MOON
Server: Apache
System: Linux nserver.cafsindia.com 4.18.0-553.104.1.lve.el8.x86_64 #1 SMP Tue Feb 10 20:07:30 UTC 2026 x86_64
User: cafsindia (1002)
PHP: 8.2.30
Disabled: NONE
Upload Files
File: //home/cafsindia/snap.cafsinfotech.in/node_modules/mapbox-gl/dist/mapbox-gl-dev.js
/* Mapbox GL JS is Copyright © 2020 Mapbox and subject to the Mapbox Terms of Service ((https://www.mapbox.com/legal/tos/). */
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.mapboxgl = factory());
})(this, (function () { 'use strict';

/* eslint-disable */

var shared, worker, mapboxgl;
// define gets called three times: one for each chunk. we rely on the order
// they're imported to know which is which
function define(_, chunk) {
if (!shared) {
    shared = chunk;
} else if (!worker) {
    worker = chunk;
} else {
    var workerBundleString = "self.onerror = function() { console.error('An error occurred while parsing the WebWorker bundle. This is most likely due to improper transpilation by Babel; please see https://docs.mapbox.com/mapbox-gl-js/guides/install/#transpiling'); }; var sharedChunk = {}; (" + shared + ")(sharedChunk); (" + worker + ")(sharedChunk); self.onerror = null;"

    var sharedChunk = {};
    shared(sharedChunk);
    mapboxgl = chunk(sharedChunk);
    if (typeof window !== 'undefined' && window && window.URL && window.URL.createObjectURL) {
        mapboxgl.workerUrl = window.URL.createObjectURL(new Blob([workerBundleString], { type: 'text/javascript' }));
    }
}
}


define(['exports'], (function (exports) { 'use strict';

//      
/* eslint-env browser */
                                                  

// shim window for the case of requiring the browser bundle in Node
var window$1 = ((typeof self !== 'undefined' ? self : ({}     ))        );

var name = "mapbox-gl";
var description = "A WebGL interactive maps library";
var version = "2.15.0";
var main = "dist/mapbox-gl.js";
var style = "dist/mapbox-gl.css";
var license = "SEE LICENSE IN LICENSE.txt";
var type = "module";
var repository = {
	type: "git",
	url: "git://github.com/mapbox/mapbox-gl-js.git"
};
var dependencies = {
	"@mapbox/geojson-rewind": "^0.5.2",
	"@mapbox/jsonlint-lines-primitives": "^2.0.2",
	"@mapbox/mapbox-gl-supported": "^2.0.1",
	"@mapbox/point-geometry": "^0.1.0",
	"@mapbox/tiny-sdf": "^2.0.6",
	"@mapbox/unitbezier": "^0.0.1",
	"@mapbox/vector-tile": "^1.3.1",
	"@mapbox/whoots-js": "^3.1.0",
	csscolorparser: "~1.0.3",
	earcut: "^2.2.4",
	"geojson-vt": "^3.2.1",
	"gl-matrix": "^3.4.3",
	"grid-index": "^1.1.0",
	kdbush: "^4.0.1",
	"murmurhash-js": "^1.0.0",
	pbf: "^3.2.1",
	potpack: "^2.0.0",
	quickselect: "^2.0.0",
	rw: "^1.3.3",
	supercluster: "^8.0.0",
	tinyqueue: "^2.0.3",
	"vt-pbf": "^3.1.3"
};
var devDependencies = {
	"@babel/core": "^7.20.5",
	"@babel/eslint-parser": "^7.18.9",
	"@mapbox/flow-remove-types": "^2.0.0",
	"@mapbox/mvt-fixtures": "^3.10.0",
	"@octokit/rest": "^19.0.4",
	"@rollup/plugin-commonjs": "^25.0.0",
	"@rollup/plugin-json": "^6.0.0",
	"@rollup/plugin-node-resolve": "^15.0.0",
	"@rollup/plugin-replace": "^5.0.0",
	"@rollup/plugin-strip": "^3.0.0",
	"@rollup/plugin-terser": "^0.4.1",
	address: "^1.2.0",
	browserify: "^17.0.0",
	chalk: "^5.0.1",
	chokidar: "^3.5.3",
	"cross-env": "^7.0.3",
	cssnano: "^6.0.0",
	d3: "^7.6.1",
	"d3-queue": "^3.0.7",
	diff: "^5.1.0",
	ejs: "^3.1.8",
	envify: "^4.1.0",
	eslint: "^7.32.0",
	"eslint-config-mourner": "^3.0.0",
	"eslint-plugin-flowtype": "^7.0.0",
	"eslint-plugin-html": "^7.1.0",
	"eslint-plugin-import": "^2.26.0",
	"eslint-plugin-jsdoc": "^39.6.4",
	"flow-bin": "0.191.0",
	gl: "6.0.2",
	glob: "^10.0.0",
	"is-builtin-module": "^3.2.0",
	jsdom: "^15.2.1",
	"json-stringify-pretty-compact": "^4.0.0",
	"lodash.template": "^4.5.0",
	"mapbox-gl-styles": "^2.0.2",
	minimist: "^1.2.6",
	"mock-geolocation": "^1.0.11",
	"node-notifier": "^10.0.1",
	"npm-font-open-sans": "^1.1.0",
	"npm-run-all": "^4.1.5",
	nyc: "^15.1.0",
	pixelmatch: "^5.3.0",
	postcss: "^8.4.16",
	"postcss-cli": "^10.1.0",
	"postcss-inline-svg": "^6.0.0",
	"pretty-bytes": "^6.0.0",
	"puppeteer-core": "^19.7.0",
	"qrcode-terminal": "^0.12.0",
	rollup: "^3.21.7",
	"rollup-plugin-sourcemaps": "^0.6.3",
	"rollup-plugin-unassert": "^0.6.0",
	"selenium-webdriver": "^4.8.0",
	"serve-static": "^1.15.0",
	"shuffle-seed": "^1.1.6",
	sinon: "^15.0.0",
	st: "^3.0.0",
	stylelint: "^14.11.0",
	"stylelint-config-standard": "^29.0.0",
	tap: "~16.3.2",
	tape: "^5.6.1",
	"tape-filter": "^1.0.4",
	testem: "^3.10.1"
};
var browser = {
	"./src/shaders/index.js": "./src/shaders/shaders.js",
	"./src/util/window.js": "./src/util/browser/window.js",
	"./src/util/web_worker.js": "./src/util/browser/web_worker.js"
};
var scripts = {
	"build-dev": "rollup -c --environment BUILD:dev",
	"watch-dev": "rollup -c --environment BUILD:dev --watch",
	"build-bench": "rollup -c --environment BUILD:bench,MINIFY:true",
	"build-prod": "rollup -c --environment BUILD:production",
	"build-prod-min": "rollup -c --environment BUILD:production,MINIFY:true",
	"build-csp": "rollup -c rollup.config.csp.js",
	"build-test-suite": "rollup -c test/integration/rollup.config.test.js",
	"build-flow-types": "mkdir -p dist && cp build/mapbox-gl.js.flow dist/mapbox-gl.js.flow && cp build/mapbox-gl.js.flow dist/mapbox-gl-dev.js.flow",
	"build-css": "postcss -o dist/mapbox-gl.css src/css/mapbox-gl.css",
	"build-style-spec": "cd src/style-spec && npm run build && cd ../.. && mkdir -p dist/style-spec && cp src/style-spec/dist/* dist/style-spec",
	"watch-css": "postcss --watch -o dist/mapbox-gl.css src/css/mapbox-gl.css",
	"build-token": "node build/generate-access-token-script.js",
	"build-benchmarks": "BENCHMARK_VERSION=${BENCHMARK_VERSION:-\"$(git rev-parse --abbrev-ref HEAD) $(git rev-parse --short=7 HEAD)\"} rollup -c bench/versions/rollup_config_benchmarks.js",
	"watch-benchmarks": "BENCHMARK_VERSION=${BENCHMARK_VERSION:-\"$(git rev-parse --abbrev-ref HEAD) $(git rev-parse --short=7 HEAD)\"} rollup -c bench/rollup_config_benchmarks.js -w",
	"start-server": "st --no-cache -H 0.0.0.0 --port 9966 --index index.html .",
	start: "run-p build-token watch-css watch-dev watch-benchmarks start-server",
	"start-debug": "run-p build-token watch-css watch-dev start-server",
	"start-bench": "run-p build-token watch-benchmarks start-server",
	"start-release": "run-s build-token build-prod-min build-css print-release-url start-server",
	lint: "eslint --cache --ignore-path .gitignore src test bench debug/*.html",
	"lint-css": "stylelint 'src/css/mapbox-gl.css'",
	test: "run-s lint lint-css test-flow test-unit",
	"test-suite": "run-s test-render test-query test-expressions",
	"test-suite-clean": "find test/integration/{render,query, expressions}-tests -mindepth 2 -type d -exec test -e \"{}/actual.png\" \\; -not \\( -exec test -e \"{}/style.json\" \\; \\) -print | xargs -t rm -r",
	"test-unit": "build/run-tap --reporter classic --no-coverage test/unit",
	"test-build": "build/run-tap --no-coverage test/build/**/*.test.js",
	"test-browser": "build/run-tap --jobs=1 --reporter spec --no-coverage -- test/browser/**/*.test.js",
	"watch-render": "cross-env SUITE_NAME=render testem -f test/integration/testem/testem.js",
	"watch-query": "SUITE_NAME=query testem -f test/integration/testem/testem.js",
	"test-render": "cross-env SUITE_NAME=render testem ci -f test/integration/testem/testem.js",
	"test-render-firefox": "cross-env BROWSER=Firefox SUITE_NAME=render testem ci -f test/integration/testem/testem.js",
	"test-render-safari": "cross-env BROWSER=Safari SUITE_NAME=render testem ci -f test/integration/testem/testem.js",
	"test-render-prod": "BUILD=production SUITE_NAME=render testem ci -f test/integration/testem/testem.js",
	"test-render-csp": "BUILD=csp SUITE_NAME=render testem ci -f test/integration/testem/testem.js",
	"test-query": "SUITE_NAME=query testem ci -f test/integration/testem/testem.js",
	"test-expressions": "build/run-node test/expression.test.js",
	"test-flow": "build/run-node build/generate-flow-typed-style-spec && flow .",
	"test-cov": "nyc --require=@mapbox/flow-remove-types/register --reporter=text-summary --reporter=lcov --cache run-s test-unit test-expressions test-query test-render",
	"test-style-spec": "cd src/style-spec && npm test",
	prepublishOnly: "run-s build-flow-types build-dev build-prod-min build-prod build-csp build-css build-style-spec",
	"print-release-url": "node build/print-release-url.js",
	"check-bundle-size": "node build/check-bundle-size.js",
	codegen: "build/run-node build/generate-style-code.js && build/run-node build/generate-struct-arrays.js"
};
var files = [
	"build/",
	"dist/mapbox-gl*",
	"dist/style-spec/",
	"dist/package.json",
	"flow-typed/*.js",
	"src/",
	".flowconfig",
	"LICENSE.txt"
];
var _package = {
	name: name,
	description: description,
	version: version,
	main: main,
	style: style,
	license: license,
	type: type,
	repository: repository,
	dependencies: dependencies,
	devDependencies: devDependencies,
	browser: browser,
	scripts: scripts,
	files: files
};

//       strict

                
                  
                        
                             
                          
                           
                          
                            
                      
                       
                       
                                
                           
                            
                        
                                     
   

let mapboxHTTPURLRegex;

const config         = {
    API_URL: 'https://api.mapbox.com',
    get API_URL_REGEX () {
        if (mapboxHTTPURLRegex == null) {
            const prodMapboxHTTPURLRegex = /^((https?:)?\/\/)?([^\/]+\.)?mapbox\.c(n|om)(\/|\?|$)/i;
            try {
                mapboxHTTPURLRegex = (process.env.API_URL_REGEX != null) ? new RegExp(process.env.API_URL_REGEX) : prodMapboxHTTPURLRegex;
            } catch (e) {
                mapboxHTTPURLRegex = prodMapboxHTTPURLRegex;
            }
        }

        return mapboxHTTPURLRegex;
    },
    get API_TILEJSON_REGEX() {
        // https://docs.mapbox.com/api/maps/mapbox-tiling-service/#retrieve-tilejson-metadata
        return /^((https?:)?\/\/)?([^\/]+\.)?mapbox\.c(n|om)(\/v[0-9]*\/.*\.json.*$)/i;
    },
    get API_SPRITE_REGEX() {
        // https://docs.mapbox.com/api/maps/styles/#retrieve-a-sprite-image-or-json
        return /^((https?:)?\/\/)?([^\/]+\.)?mapbox\.c(n|om)(\/styles\/v[0-9]*\/)(.*\/sprite.*\..*$)/i;
    },
    get API_FONTS_REGEX() {
        // https://docs.mapbox.com/api/maps/fonts/#retrieve-font-glyph-ranges
        return /^((https?:)?\/\/)?([^\/]+\.)?mapbox\.c(n|om)(\/fonts\/v[0-9]*\/)(.*\.pbf.*$)/i;
    },
    get API_STYLE_REGEX() {
        // https://docs.mapbox.com/api/maps/styles/#retrieve-a-style
        return /^((https?:)?\/\/)?([^\/]+\.)?mapbox\.c(n|om)(\/styles\/v[0-9]*\/)(.*$)/i;
    },
    get API_CDN_URL_REGEX() {
        return /^((https?:)?\/\/)?api\.mapbox\.c(n|om)(\/mapbox-gl-js\/)(.*$)/i;
    },
    get EVENTS_URL() {
        if (!config.API_URL) { return null; }
        try {
            const url = new URL(config.API_URL);
            if (url.hostname === 'api.mapbox.cn') {
                return 'https://events.mapbox.cn/events/v2';
            } else if (url.hostname === 'api.mapbox.com') {
                return 'https://events.mapbox.com/events/v2';
            } else {
                return null;
            }
        } catch (e) {
            return null;
        }
    },
    SESSION_PATH: '/map-sessions/v1',
    FEEDBACK_URL: 'https://apps.mapbox.com/feedback',
    TILE_URL_VERSION: 'v4',
    RASTER_URL_PREFIX: 'raster/v1',
    REQUIRE_ACCESS_TOKEN: true,
    ACCESS_TOKEN: null,
    MAX_PARALLEL_IMAGE_REQUESTS: 16
};

//       strict


const exported$1 = {
    supported: false,
    testSupport
};

let glForTesting;
let webpCheckComplete = false;
let webpImgTest;
let webpImgTestOnloadComplete = false;

if (window$1.document) {
    webpImgTest = window$1.document.createElement('img');
    webpImgTest.onload = function() {
        if (glForTesting) testWebpTextureUpload(glForTesting);
        glForTesting = null;
        webpImgTestOnloadComplete = true;
    };
    webpImgTest.onerror = function() {
        webpCheckComplete = true;
        glForTesting = null;
    };
    webpImgTest.src = 'data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAQAAAAfQ//73v/+BiOh/AAA=';
}

function testSupport(gl                       ) {
    if (webpCheckComplete || !webpImgTest) return;

    // HTMLImageElement.complete is set when an image is done loading it's source
    // regardless of whether the load was successful or not.
    // It's possible for an error to set HTMLImageElement.complete to true which would trigger
    // testWebpTextureUpload and mistakenly set exported.supported to true in browsers which don't support webp
    // To avoid this, we set a flag in the image's onload handler and only call testWebpTextureUpload
    // after a successful image load event.
    if (webpImgTestOnloadComplete) {
        testWebpTextureUpload(gl);
    } else {
        glForTesting = gl;

    }
}

function testWebpTextureUpload(gl                       ) {
    // Edge 18 supports WebP but not uploading a WebP image to a gl texture
    // Test support for this before allowing WebP images.
    // https://github.com/mapbox/mapbox-gl-js/issues/7671
    const texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, texture);

    try {
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, webpImgTest);

        // The error does not get triggered in Edge if the context is lost
        if (gl.isContextLost()) return;

        exported$1.supported = true;
    } catch (e) {
        // Catch "Unspecified Error." in Edge 18.
    }

    gl.deleteTexture(texture);

    webpCheckComplete = true;
}

//      

/***** START WARNING REMOVAL OR MODIFICATION OF THE
* FOLLOWING CODE VIOLATES THE MAPBOX TERMS OF SERVICE  ******
* The following code is used to access Mapbox's APIs. Removal or modification
* of this code can result in higher fees and/or
* termination of your account with Mapbox.
*
* Under the Mapbox Terms of Service, you may not use this code to access Mapbox
* Mapping APIs other than through Mapbox SDKs.
*
* The Mapping APIs documentation is available at https://docs.mapbox.com/api/maps/#maps
* and the Mapbox Terms of Service are available at https://www.mapbox.com/tos/
******************************************************************************/

                        
                  
                          
   

const SKU_ID = '01';

function createSkuToken()                 {
    // SKU_ID and TOKEN_VERSION are specified by an internal schema and should not change
    const TOKEN_VERSION = '1';
    const base62chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    // sessionRandomizer is a randomized 10-digit base-62 number
    let sessionRandomizer = '';
    for (let i = 0; i < 10; i++) {
        sessionRandomizer += base62chars[Math.floor(Math.random() * 62)];
    }
    const expiration = 12 * 60 * 60 * 1000; // 12 hours
    const token = [TOKEN_VERSION, SKU_ID, sessionRandomizer].join('');
    const tokenExpiresAt = Date.now() + expiration;

    return {token, tokenExpiresAt};
}

/***** END WARNING - REMOVAL OR MODIFICATION OF THE
PRECEDING CODE VIOLATES THE MAPBOX TERMS OF SERVICE  ******/

var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};

function getDefaultExportFromCjs (x) {
	return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}

function getDefaultExportFromNamespaceIfPresent (n) {
	return n && Object.prototype.hasOwnProperty.call(n, 'default') ? n['default'] : n;
}

function getDefaultExportFromNamespaceIfNotNamed (n) {
	return n && Object.prototype.hasOwnProperty.call(n, 'default') && Object.keys(n).length === 1 ? n['default'] : n;
}

function getAugmentedNamespace(n) {
  if (n.__esModule) return n;
  var f = n.default;
	if (typeof f == "function") {
		var a = function a () {
			if (this instanceof a) {
				var args = [null];
				args.push.apply(args, arguments);
				var Ctor = Function.bind.apply(f, args);
				return new Ctor();
			}
			return f.apply(this, arguments);
		};
		a.prototype = f.prototype;
  } else a = {};
  Object.defineProperty(a, '__esModule', {value: true});
	Object.keys(n).forEach(function (k) {
		var d = Object.getOwnPropertyDescriptor(n, k);
		Object.defineProperty(a, k, d.get ? d : {
			enumerable: true,
			get: function () {
				return n[k];
			}
		});
	});
	return a;
}

'use strict';

var unitbezier = UnitBezier;

function UnitBezier(p1x, p1y, p2x, p2y) {
    // Calculate the polynomial coefficients, implicit first and last control points are (0,0) and (1,1).
    this.cx = 3.0 * p1x;
    this.bx = 3.0 * (p2x - p1x) - this.cx;
    this.ax = 1.0 - this.cx - this.bx;

    this.cy = 3.0 * p1y;
    this.by = 3.0 * (p2y - p1y) - this.cy;
    this.ay = 1.0 - this.cy - this.by;

    this.p1x = p1x;
    this.p1y = p1y;
    this.p2x = p2x;
    this.p2y = p2y;
}

UnitBezier.prototype = {
    sampleCurveX: function (t) {
        // `ax t^3 + bx t^2 + cx t' expanded using Horner's rule.
        return ((this.ax * t + this.bx) * t + this.cx) * t;
    },

    sampleCurveY: function (t) {
        return ((this.ay * t + this.by) * t + this.cy) * t;
    },

    sampleCurveDerivativeX: function (t) {
        return (3.0 * this.ax * t + 2.0 * this.bx) * t + this.cx;
    },

    solveCurveX: function (x, epsilon) {
        if (epsilon === undefined) epsilon = 1e-6;

        if (x < 0.0) return 0.0;
        if (x > 1.0) return 1.0;

        var t = x;

        // First try a few iterations of Newton's method - normally very fast.
        for (var i = 0; i < 8; i++) {
            var x2 = this.sampleCurveX(t) - x;
            if (Math.abs(x2) < epsilon) return t;

            var d2 = this.sampleCurveDerivativeX(t);
            if (Math.abs(d2) < 1e-6) break;

            t = t - x2 / d2;
        }

        // Fall back to the bisection method for reliability.
        var t0 = 0.0;
        var t1 = 1.0;
        t = x;

        for (i = 0; i < 20; i++) {
            x2 = this.sampleCurveX(t);
            if (Math.abs(x2 - x) < epsilon) break;

            if (x > x2) {
                t0 = t;
            } else {
                t1 = t;
            }

            t = (t1 - t0) * 0.5 + t0;
        }

        return t;
    },

    solve: function (x, epsilon) {
        return this.sampleCurveY(this.solveCurveX(x, epsilon));
    }
};

var UnitBezier$1 = /*@__PURE__*/getDefaultExportFromCjs(unitbezier);

'use strict';

var pointGeometry = Point$1;

/**
 * A standalone point geometry with useful accessor, comparison, and
 * modification methods.
 *
 * @class Point
 * @param {Number} x the x-coordinate. this could be longitude or screen
 * pixels, or any other sort of unit.
 * @param {Number} y the y-coordinate. this could be latitude or screen
 * pixels, or any other sort of unit.
 * @example
 * var point = new Point(-77, 38);
 */
function Point$1(x, y) {
    this.x = x;
    this.y = y;
}

Point$1.prototype = {

    /**
     * Clone this point, returning a new point that can be modified
     * without affecting the old one.
     * @return {Point} the clone
     */
    clone: function() { return new Point$1(this.x, this.y); },

    /**
     * Add this point's x & y coordinates to another point,
     * yielding a new point.
     * @param {Point} p the other point
     * @return {Point} output point
     */
    add:     function(p) { return this.clone()._add(p); },

    /**
     * Subtract this point's x & y coordinates to from point,
     * yielding a new point.
     * @param {Point} p the other point
     * @return {Point} output point
     */
    sub:     function(p) { return this.clone()._sub(p); },

    /**
     * Multiply this point's x & y coordinates by point,
     * yielding a new point.
     * @param {Point} p the other point
     * @return {Point} output point
     */
    multByPoint:    function(p) { return this.clone()._multByPoint(p); },

    /**
     * Divide this point's x & y coordinates by point,
     * yielding a new point.
     * @param {Point} p the other point
     * @return {Point} output point
     */
    divByPoint:     function(p) { return this.clone()._divByPoint(p); },

    /**
     * Multiply this point's x & y coordinates by a factor,
     * yielding a new point.
     * @param {Point} k factor
     * @return {Point} output point
     */
    mult:    function(k) { return this.clone()._mult(k); },

    /**
     * Divide this point's x & y coordinates by a factor,
     * yielding a new point.
     * @param {Point} k factor
     * @return {Point} output point
     */
    div:     function(k) { return this.clone()._div(k); },

    /**
     * Rotate this point around the 0, 0 origin by an angle a,
     * given in radians
     * @param {Number} a angle to rotate around, in radians
     * @return {Point} output point
     */
    rotate:  function(a) { return this.clone()._rotate(a); },

    /**
     * Rotate this point around p point by an angle a,
     * given in radians
     * @param {Number} a angle to rotate around, in radians
     * @param {Point} p Point to rotate around
     * @return {Point} output point
     */
    rotateAround:  function(a,p) { return this.clone()._rotateAround(a,p); },

    /**
     * Multiply this point by a 4x1 transformation matrix
     * @param {Array<Number>} m transformation matrix
     * @return {Point} output point
     */
    matMult: function(m) { return this.clone()._matMult(m); },

    /**
     * Calculate this point but as a unit vector from 0, 0, meaning
     * that the distance from the resulting point to the 0, 0
     * coordinate will be equal to 1 and the angle from the resulting
     * point to the 0, 0 coordinate will be the same as before.
     * @return {Point} unit vector point
     */
    unit:    function() { return this.clone()._unit(); },

    /**
     * Compute a perpendicular point, where the new y coordinate
     * is the old x coordinate and the new x coordinate is the old y
     * coordinate multiplied by -1
     * @return {Point} perpendicular point
     */
    perp:    function() { return this.clone()._perp(); },

    /**
     * Return a version of this point with the x & y coordinates
     * rounded to integers.
     * @return {Point} rounded point
     */
    round:   function() { return this.clone()._round(); },

    /**
     * Return the magitude of this point: this is the Euclidean
     * distance from the 0, 0 coordinate to this point's x and y
     * coordinates.
     * @return {Number} magnitude
     */
    mag: function() {
        return Math.sqrt(this.x * this.x + this.y * this.y);
    },

    /**
     * Judge whether this point is equal to another point, returning
     * true or false.
     * @param {Point} other the other point
     * @return {boolean} whether the points are equal
     */
    equals: function(other) {
        return this.x === other.x &&
               this.y === other.y;
    },

    /**
     * Calculate the distance from this point to another point
     * @param {Point} p the other point
     * @return {Number} distance
     */
    dist: function(p) {
        return Math.sqrt(this.distSqr(p));
    },

    /**
     * Calculate the distance from this point to another point,
     * without the square root step. Useful if you're comparing
     * relative distances.
     * @param {Point} p the other point
     * @return {Number} distance
     */
    distSqr: function(p) {
        var dx = p.x - this.x,
            dy = p.y - this.y;
        return dx * dx + dy * dy;
    },

    /**
     * Get the angle from the 0, 0 coordinate to this point, in radians
     * coordinates.
     * @return {Number} angle
     */
    angle: function() {
        return Math.atan2(this.y, this.x);
    },

    /**
     * Get the angle from this point to another point, in radians
     * @param {Point} b the other point
     * @return {Number} angle
     */
    angleTo: function(b) {
        return Math.atan2(this.y - b.y, this.x - b.x);
    },

    /**
     * Get the angle between this point and another point, in radians
     * @param {Point} b the other point
     * @return {Number} angle
     */
    angleWith: function(b) {
        return this.angleWithSep(b.x, b.y);
    },

    /*
     * Find the angle of the two vectors, solving the formula for
     * the cross product a x b = |a||b|sin(θ) for θ.
     * @param {Number} x the x-coordinate
     * @param {Number} y the y-coordinate
     * @return {Number} the angle in radians
     */
    angleWithSep: function(x, y) {
        return Math.atan2(
            this.x * y - this.y * x,
            this.x * x + this.y * y);
    },

    _matMult: function(m) {
        var x = m[0] * this.x + m[1] * this.y,
            y = m[2] * this.x + m[3] * this.y;
        this.x = x;
        this.y = y;
        return this;
    },

    _add: function(p) {
        this.x += p.x;
        this.y += p.y;
        return this;
    },

    _sub: function(p) {
        this.x -= p.x;
        this.y -= p.y;
        return this;
    },

    _mult: function(k) {
        this.x *= k;
        this.y *= k;
        return this;
    },

    _div: function(k) {
        this.x /= k;
        this.y /= k;
        return this;
    },

    _multByPoint: function(p) {
        this.x *= p.x;
        this.y *= p.y;
        return this;
    },

    _divByPoint: function(p) {
        this.x /= p.x;
        this.y /= p.y;
        return this;
    },

    _unit: function() {
        this._div(this.mag());
        return this;
    },

    _perp: function() {
        var y = this.y;
        this.y = this.x;
        this.x = -y;
        return this;
    },

    _rotate: function(angle) {
        var cos = Math.cos(angle),
            sin = Math.sin(angle),
            x = cos * this.x - sin * this.y,
            y = sin * this.x + cos * this.y;
        this.x = x;
        this.y = y;
        return this;
    },

    _rotateAround: function(angle, p) {
        var cos = Math.cos(angle),
            sin = Math.sin(angle),
            x = p.x + cos * (this.x - p.x) - sin * (this.y - p.y),
            y = p.y + sin * (this.x - p.x) + cos * (this.y - p.y);
        this.x = x;
        this.y = y;
        return this;
    },

    _round: function() {
        this.x = Math.round(this.x);
        this.y = Math.round(this.y);
        return this;
    }
};

/**
 * Construct a point from an array if necessary, otherwise if the input
 * is already a Point, or an unknown type, return it unchanged
 * @param {Array<Number>|Point|*} a any kind of input value
 * @return {Point} constructed point, or passed-through value.
 * @example
 * // this
 * var point = Point.convert([0, 1]);
 * // is equivalent to
 * var point = new Point(0, 1);
 */
Point$1.convert = function (a) {
    if (a instanceof Point$1) {
        return a;
    }
    if (Array.isArray(a)) {
        return new Point$1(a[0], a[1]);
    }
    return a;
};

var Point$2 = /*@__PURE__*/getDefaultExportFromCjs(pointGeometry);

var assert$2 = {exports: {}};

/*
object-assign
(c) Sindre Sorhus
@license MIT
*/

'use strict';
/* eslint-disable no-unused-vars */
var getOwnPropertySymbols = Object.getOwnPropertySymbols;
var hasOwnProperty = Object.prototype.hasOwnProperty;
var propIsEnumerable = Object.prototype.propertyIsEnumerable;

function toObject(val) {
	if (val === null || val === undefined) {
		throw new TypeError('Object.assign cannot be called with null or undefined');
	}

	return Object(val);
}

function shouldUseNative() {
	try {
		if (!Object.assign) {
			return false;
		}

		// Detect buggy property enumeration order in older V8 versions.

		// https://bugs.chromium.org/p/v8/issues/detail?id=4118
		var test1 = new String('abc');  // eslint-disable-line no-new-wrappers
		test1[5] = 'de';
		if (Object.getOwnPropertyNames(test1)[0] === '5') {
			return false;
		}

		// https://bugs.chromium.org/p/v8/issues/detail?id=3056
		var test2 = {};
		for (var i = 0; i < 10; i++) {
			test2['_' + String.fromCharCode(i)] = i;
		}
		var order2 = Object.getOwnPropertyNames(test2).map(function (n) {
			return test2[n];
		});
		if (order2.join('') !== '0123456789') {
			return false;
		}

		// https://bugs.chromium.org/p/v8/issues/detail?id=3056
		var test3 = {};
		'abcdefghijklmnopqrst'.split('').forEach(function (letter) {
			test3[letter] = letter;
		});
		if (Object.keys(Object.assign({}, test3)).join('') !==
				'abcdefghijklmnopqrst') {
			return false;
		}

		return true;
	} catch (err) {
		// We don't expect any of the above to throw, but better to be safe.
		return false;
	}
}

var objectAssign$1 = shouldUseNative() ? Object.assign : function (target, source) {
	var from;
	var to = toObject(target);
	var symbols;

	for (var s = 1; s < arguments.length; s++) {
		from = Object(arguments[s]);

		for (var key in from) {
			if (hasOwnProperty.call(from, key)) {
				to[key] = from[key];
			}
		}

		if (getOwnPropertySymbols) {
			symbols = getOwnPropertySymbols(from);
			for (var i = 0; i < symbols.length; i++) {
				if (propIsEnumerable.call(from, symbols[i])) {
					to[symbols[i]] = from[symbols[i]];
				}
			}
		}
	}

	return to;
};

var index = /*@__PURE__*/getDefaultExportFromCjs(objectAssign$1);

var util$2 = {};

var isBufferBrowser = function isBuffer(arg) {
  return arg && typeof arg === 'object'
    && typeof arg.copy === 'function'
    && typeof arg.fill === 'function'
    && typeof arg.readUInt8 === 'function';
};

var isBufferBrowser$1 = /*@__PURE__*/getDefaultExportFromCjs(isBufferBrowser);

var inherits_browser$2 = {exports: {}};

var inherits_browser = inherits_browser$2.exports;

if (typeof Object.create === 'function') {
  // implementation from standard node.js 'util' module
  inherits_browser$2.exports = function inherits(ctor, superCtor) {
    ctor.super_ = superCtor;
    ctor.prototype = Object.create(superCtor.prototype, {
      constructor: {
        value: ctor,
        enumerable: false,
        writable: true,
        configurable: true
      }
    });
  };
} else {
  // old school shim for old browsers
  inherits_browser$2.exports = function inherits(ctor, superCtor) {
    ctor.super_ = superCtor;
    var TempCtor = function () {};
    TempCtor.prototype = superCtor.prototype;
    ctor.prototype = new TempCtor();
    ctor.prototype.constructor = ctor;
  };
}

var inherits_browserExports = inherits_browser$2.exports;
var inherits_browser$1 = /*@__PURE__*/getDefaultExportFromCjs(inherits_browserExports);

(function (exports) {
	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.

	var formatRegExp = /%[sdj%]/g;
	exports.format = function(f) {
	  if (!isString(f)) {
	    var objects = [];
	    for (var i = 0; i < arguments.length; i++) {
	      objects.push(inspect(arguments[i]));
	    }
	    return objects.join(' ');
	  }

	  var i = 1;
	  var args = arguments;
	  var len = args.length;
	  var str = String(f).replace(formatRegExp, function(x) {
	    if (x === '%%') return '%';
	    if (i >= len) return x;
	    switch (x) {
	      case '%s': return String(args[i++]);
	      case '%d': return Number(args[i++]);
	      case '%j':
	        try {
	          return JSON.stringify(args[i++]);
	        } catch (_) {
	          return '[Circular]';
	        }
	      default:
	        return x;
	    }
	  });
	  for (var x = args[i]; i < len; x = args[++i]) {
	    if (isNull(x) || !isObject(x)) {
	      str += ' ' + x;
	    } else {
	      str += ' ' + inspect(x);
	    }
	  }
	  return str;
	};


	// Mark that a method should not be used.
	// Returns a modified function which warns once by default.
	// If --no-deprecation is set, then it is a no-op.
	exports.deprecate = function(fn, msg) {
	  // Allow for deprecating things in the process of starting up.
	  if (isUndefined(global.process)) {
	    return function() {
	      return exports.deprecate(fn, msg).apply(this, arguments);
	    };
	  }

	  if (process.noDeprecation === true) {
	    return fn;
	  }

	  var warned = false;
	  function deprecated() {
	    if (!warned) {
	      if (process.throwDeprecation) {
	        throw new Error(msg);
	      } else if (process.traceDeprecation) {
	        console.trace(msg);
	      } else {
	        console.error(msg);
	      }
	      warned = true;
	    }
	    return fn.apply(this, arguments);
	  }

	  return deprecated;
	};


	var debugs = {};
	var debugEnviron;
	exports.debuglog = function(set) {
	  if (isUndefined(debugEnviron))
	    debugEnviron = process.env.NODE_DEBUG || '';
	  set = set.toUpperCase();
	  if (!debugs[set]) {
	    if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
	      var pid = process.pid;
	      debugs[set] = function() {
	        var msg = exports.format.apply(exports, arguments);
	        console.error('%s %d: %s', set, pid, msg);
	      };
	    } else {
	      debugs[set] = function() {};
	    }
	  }
	  return debugs[set];
	};


	/**
	 * Echos the value of a value. Trys to print the value out
	 * in the best way possible given the different types.
	 *
	 * @param {Object} obj The object to print out.
	 * @param {Object} opts Optional options object that alters the output.
	 */
	/* legacy: obj, showHidden, depth, colors*/
	function inspect(obj, opts) {
	  // default options
	  var ctx = {
	    seen: [],
	    stylize: stylizeNoColor
	  };
	  // legacy...
	  if (arguments.length >= 3) ctx.depth = arguments[2];
	  if (arguments.length >= 4) ctx.colors = arguments[3];
	  if (isBoolean(opts)) {
	    // legacy...
	    ctx.showHidden = opts;
	  } else if (opts) {
	    // got an "options" object
	    exports._extend(ctx, opts);
	  }
	  // set default options
	  if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
	  if (isUndefined(ctx.depth)) ctx.depth = 2;
	  if (isUndefined(ctx.colors)) ctx.colors = false;
	  if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
	  if (ctx.colors) ctx.stylize = stylizeWithColor;
	  return formatValue(ctx, obj, ctx.depth);
	}
	exports.inspect = inspect;


	// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
	inspect.colors = {
	  'bold' : [1, 22],
	  'italic' : [3, 23],
	  'underline' : [4, 24],
	  'inverse' : [7, 27],
	  'white' : [37, 39],
	  'grey' : [90, 39],
	  'black' : [30, 39],
	  'blue' : [34, 39],
	  'cyan' : [36, 39],
	  'green' : [32, 39],
	  'magenta' : [35, 39],
	  'red' : [31, 39],
	  'yellow' : [33, 39]
	};

	// Don't use 'blue' not visible on cmd.exe
	inspect.styles = {
	  'special': 'cyan',
	  'number': 'yellow',
	  'boolean': 'yellow',
	  'undefined': 'grey',
	  'null': 'bold',
	  'string': 'green',
	  'date': 'magenta',
	  // "name": intentionally not styling
	  'regexp': 'red'
	};


	function stylizeWithColor(str, styleType) {
	  var style = inspect.styles[styleType];

	  if (style) {
	    return '\u001b[' + inspect.colors[style][0] + 'm' + str +
	           '\u001b[' + inspect.colors[style][1] + 'm';
	  } else {
	    return str;
	  }
	}


	function stylizeNoColor(str, styleType) {
	  return str;
	}


	function arrayToHash(array) {
	  var hash = {};

	  array.forEach(function(val, idx) {
	    hash[val] = true;
	  });

	  return hash;
	}


	function formatValue(ctx, value, recurseTimes) {
	  // Provide a hook for user-specified inspect functions.
	  // Check that value is an object with an inspect function on it
	  if (ctx.customInspect &&
	      value &&
	      isFunction(value.inspect) &&
	      // Filter out the util module, it's inspect function is special
	      value.inspect !== exports.inspect &&
	      // Also filter out any prototype objects using the circular check.
	      !(value.constructor && value.constructor.prototype === value)) {
	    var ret = value.inspect(recurseTimes, ctx);
	    if (!isString(ret)) {
	      ret = formatValue(ctx, ret, recurseTimes);
	    }
	    return ret;
	  }

	  // Primitive types cannot have properties
	  var primitive = formatPrimitive(ctx, value);
	  if (primitive) {
	    return primitive;
	  }

	  // Look up the keys of the object.
	  var keys = Object.keys(value);
	  var visibleKeys = arrayToHash(keys);

	  if (ctx.showHidden) {
	    keys = Object.getOwnPropertyNames(value);
	  }

	  // IE doesn't make error fields non-enumerable
	  // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
	  if (isError(value)
	      && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
	    return formatError(value);
	  }

	  // Some type of object without properties can be shortcutted.
	  if (keys.length === 0) {
	    if (isFunction(value)) {
	      var name = value.name ? ': ' + value.name : '';
	      return ctx.stylize('[Function' + name + ']', 'special');
	    }
	    if (isRegExp(value)) {
	      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
	    }
	    if (isDate(value)) {
	      return ctx.stylize(Date.prototype.toString.call(value), 'date');
	    }
	    if (isError(value)) {
	      return formatError(value);
	    }
	  }

	  var base = '', array = false, braces = ['{', '}'];

	  // Make Array say that they are Array
	  if (isArray(value)) {
	    array = true;
	    braces = ['[', ']'];
	  }

	  // Make functions say that they are functions
	  if (isFunction(value)) {
	    var n = value.name ? ': ' + value.name : '';
	    base = ' [Function' + n + ']';
	  }

	  // Make RegExps say that they are RegExps
	  if (isRegExp(value)) {
	    base = ' ' + RegExp.prototype.toString.call(value);
	  }

	  // Make dates with properties first say the date
	  if (isDate(value)) {
	    base = ' ' + Date.prototype.toUTCString.call(value);
	  }

	  // Make error with message first say the error
	  if (isError(value)) {
	    base = ' ' + formatError(value);
	  }

	  if (keys.length === 0 && (!array || value.length == 0)) {
	    return braces[0] + base + braces[1];
	  }

	  if (recurseTimes < 0) {
	    if (isRegExp(value)) {
	      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
	    } else {
	      return ctx.stylize('[Object]', 'special');
	    }
	  }

	  ctx.seen.push(value);

	  var output;
	  if (array) {
	    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
	  } else {
	    output = keys.map(function(key) {
	      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
	    });
	  }

	  ctx.seen.pop();

	  return reduceToSingleString(output, base, braces);
	}


	function formatPrimitive(ctx, value) {
	  if (isUndefined(value))
	    return ctx.stylize('undefined', 'undefined');
	  if (isString(value)) {
	    var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
	                                             .replace(/'/g, "\\'")
	                                             .replace(/\\"/g, '"') + '\'';
	    return ctx.stylize(simple, 'string');
	  }
	  if (isNumber(value))
	    return ctx.stylize('' + value, 'number');
	  if (isBoolean(value))
	    return ctx.stylize('' + value, 'boolean');
	  // For some reason typeof null is "object", so special case here.
	  if (isNull(value))
	    return ctx.stylize('null', 'null');
	}


	function formatError(value) {
	  return '[' + Error.prototype.toString.call(value) + ']';
	}


	function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
	  var output = [];
	  for (var i = 0, l = value.length; i < l; ++i) {
	    if (hasOwnProperty(value, String(i))) {
	      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
	          String(i), true));
	    } else {
	      output.push('');
	    }
	  }
	  keys.forEach(function(key) {
	    if (!key.match(/^\d+$/)) {
	      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
	          key, true));
	    }
	  });
	  return output;
	}


	function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
	  var name, str, desc;
	  desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
	  if (desc.get) {
	    if (desc.set) {
	      str = ctx.stylize('[Getter/Setter]', 'special');
	    } else {
	      str = ctx.stylize('[Getter]', 'special');
	    }
	  } else {
	    if (desc.set) {
	      str = ctx.stylize('[Setter]', 'special');
	    }
	  }
	  if (!hasOwnProperty(visibleKeys, key)) {
	    name = '[' + key + ']';
	  }
	  if (!str) {
	    if (ctx.seen.indexOf(desc.value) < 0) {
	      if (isNull(recurseTimes)) {
	        str = formatValue(ctx, desc.value, null);
	      } else {
	        str = formatValue(ctx, desc.value, recurseTimes - 1);
	      }
	      if (str.indexOf('\n') > -1) {
	        if (array) {
	          str = str.split('\n').map(function(line) {
	            return '  ' + line;
	          }).join('\n').substr(2);
	        } else {
	          str = '\n' + str.split('\n').map(function(line) {
	            return '   ' + line;
	          }).join('\n');
	        }
	      }
	    } else {
	      str = ctx.stylize('[Circular]', 'special');
	    }
	  }
	  if (isUndefined(name)) {
	    if (array && key.match(/^\d+$/)) {
	      return str;
	    }
	    name = JSON.stringify('' + key);
	    if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
	      name = name.substr(1, name.length - 2);
	      name = ctx.stylize(name, 'name');
	    } else {
	      name = name.replace(/'/g, "\\'")
	                 .replace(/\\"/g, '"')
	                 .replace(/(^"|"$)/g, "'");
	      name = ctx.stylize(name, 'string');
	    }
	  }

	  return name + ': ' + str;
	}


	function reduceToSingleString(output, base, braces) {
	  var numLinesEst = 0;
	  var length = output.reduce(function(prev, cur) {
	    numLinesEst++;
	    if (cur.indexOf('\n') >= 0) numLinesEst++;
	    return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
	  }, 0);

	  if (length > 60) {
	    return braces[0] +
	           (base === '' ? '' : base + '\n ') +
	           ' ' +
	           output.join(',\n  ') +
	           ' ' +
	           braces[1];
	  }

	  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
	}


	// NOTE: These type checking functions intentionally don't use `instanceof`
	// because it is fragile and can be easily faked with `Object.create()`.
	function isArray(ar) {
	  return Array.isArray(ar);
	}
	exports.isArray = isArray;

	function isBoolean(arg) {
	  return typeof arg === 'boolean';
	}
	exports.isBoolean = isBoolean;

	function isNull(arg) {
	  return arg === null;
	}
	exports.isNull = isNull;

	function isNullOrUndefined(arg) {
	  return arg == null;
	}
	exports.isNullOrUndefined = isNullOrUndefined;

	function isNumber(arg) {
	  return typeof arg === 'number';
	}
	exports.isNumber = isNumber;

	function isString(arg) {
	  return typeof arg === 'string';
	}
	exports.isString = isString;

	function isSymbol(arg) {
	  return typeof arg === 'symbol';
	}
	exports.isSymbol = isSymbol;

	function isUndefined(arg) {
	  return arg === void 0;
	}
	exports.isUndefined = isUndefined;

	function isRegExp(re) {
	  return isObject(re) && objectToString(re) === '[object RegExp]';
	}
	exports.isRegExp = isRegExp;

	function isObject(arg) {
	  return typeof arg === 'object' && arg !== null;
	}
	exports.isObject = isObject;

	function isDate(d) {
	  return isObject(d) && objectToString(d) === '[object Date]';
	}
	exports.isDate = isDate;

	function isError(e) {
	  return isObject(e) &&
	      (objectToString(e) === '[object Error]' || e instanceof Error);
	}
	exports.isError = isError;

	function isFunction(arg) {
	  return typeof arg === 'function';
	}
	exports.isFunction = isFunction;

	function isPrimitive(arg) {
	  return arg === null ||
	         typeof arg === 'boolean' ||
	         typeof arg === 'number' ||
	         typeof arg === 'string' ||
	         typeof arg === 'symbol' ||  // ES6 symbol
	         typeof arg === 'undefined';
	}
	exports.isPrimitive = isPrimitive;

	exports.isBuffer = isBufferBrowser;

	function objectToString(o) {
	  return Object.prototype.toString.call(o);
	}


	function pad(n) {
	  return n < 10 ? '0' + n.toString(10) : n.toString(10);
	}


	var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
	              'Oct', 'Nov', 'Dec'];

	// 26 Feb 16:19:34
	function timestamp() {
	  var d = new Date();
	  var time = [pad(d.getHours()),
	              pad(d.getMinutes()),
	              pad(d.getSeconds())].join(':');
	  return [d.getDate(), months[d.getMonth()], time].join(' ');
	}


	// log is just a thin wrapper to console.log that prepends a timestamp
	exports.log = function() {
	  console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
	};


	/**
	 * Inherit the prototype methods from one constructor into another.
	 *
	 * The Function.prototype.inherits from lang.js rewritten as a standalone
	 * function (not on Function.prototype). NOTE: If this file is to be loaded
	 * during bootstrapping this function needs to be rewritten using some native
	 * functions as prototype setup using normal JavaScript does not work as
	 * expected during bootstrapping (see mirror.js in r114903).
	 *
	 * @param {function} ctor Constructor function which needs to inherit the
	 *     prototype.
	 * @param {function} superCtor Constructor function to inherit prototype from.
	 */
	exports.inherits = inherits_browserExports;

	exports._extend = function(origin, add) {
	  // Don't do anything if add isn't an object
	  if (!add || !isObject(add)) return origin;

	  var keys = Object.keys(add);
	  var i = keys.length;
	  while (i--) {
	    origin[keys[i]] = add[keys[i]];
	  }
	  return origin;
	};

	function hasOwnProperty(obj, prop) {
	  return Object.prototype.hasOwnProperty.call(obj, prop);
	} 
} (util$2));

var util$1 = /*@__PURE__*/getDefaultExportFromCjs(util$2);

var assert_1 = assert$2.exports;

'use strict';

var objectAssign = objectAssign$1;

// compare and isBuffer taken from https://github.com/feross/buffer/blob/680e9e5e488f22aac27599a57dc844a6315928dd/index.js
// original notice:

/*!
 * The buffer module from node.js, for the browser.
 *
 * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
 * @license  MIT
 */
function compare$1(a, b) {
  if (a === b) {
    return 0;
  }

  var x = a.length;
  var y = b.length;

  for (var i = 0, len = Math.min(x, y); i < len; ++i) {
    if (a[i] !== b[i]) {
      x = a[i];
      y = b[i];
      break;
    }
  }

  if (x < y) {
    return -1;
  }
  if (y < x) {
    return 1;
  }
  return 0;
}
function isBuffer(b) {
  if (global.Buffer && typeof global.Buffer.isBuffer === 'function') {
    return global.Buffer.isBuffer(b);
  }
  return !!(b != null && b._isBuffer);
}

// based on node assert, original notice:
// NB: The URL to the CommonJS spec is kept just for tradition.
//     node-assert has evolved a lot since then, both in API and behavior.

// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
//
// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
//
// Originally from narwhal.js (http://narwhaljs.org)
// Copyright (c) 2009 Thomas Robinson <280north.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the 'Software'), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

var util = util$2;
var hasOwn = Object.prototype.hasOwnProperty;
var pSlice = Array.prototype.slice;
var functionsHaveNames = (function () {
  return function foo() {}.name === 'foo';
}());
function pToString (obj) {
  return Object.prototype.toString.call(obj);
}
function isView(arrbuf) {
  if (isBuffer(arrbuf)) {
    return false;
  }
  if (typeof global.ArrayBuffer !== 'function') {
    return false;
  }
  if (typeof ArrayBuffer.isView === 'function') {
    return ArrayBuffer.isView(arrbuf);
  }
  if (!arrbuf) {
    return false;
  }
  if (arrbuf instanceof DataView) {
    return true;
  }
  if (arrbuf.buffer && arrbuf.buffer instanceof ArrayBuffer) {
    return true;
  }
  return false;
}
// 1. The assert module provides functions that throw
// AssertionError's when particular conditions are not met. The
// assert module must conform to the following interface.

var assert = assert$2.exports = ok;

// 2. The AssertionError is defined in assert.
// new assert.AssertionError({ message: message,
//                             actual: actual,
//                             expected: expected })

var regex = /\s*function\s+([^\(\s]*)\s*/;
// based on https://github.com/ljharb/function.prototype.name/blob/adeeeec8bfcc6068b187d7d9fb3d5bb1d3a30899/implementation.js
function getName(func) {
  if (!util.isFunction(func)) {
    return;
  }
  if (functionsHaveNames) {
    return func.name;
  }
  var str = func.toString();
  var match = str.match(regex);
  return match && match[1];
}
assert.AssertionError = function AssertionError(options) {
  this.name = 'AssertionError';
  this.actual = options.actual;
  this.expected = options.expected;
  this.operator = options.operator;
  if (options.message) {
    this.message = options.message;
    this.generatedMessage = false;
  } else {
    this.message = getMessage(this);
    this.generatedMessage = true;
  }
  var stackStartFunction = options.stackStartFunction || fail;
  if (Error.captureStackTrace) {
    Error.captureStackTrace(this, stackStartFunction);
  } else {
    // non v8 browsers so we can have a stacktrace
    var err = new Error();
    if (err.stack) {
      var out = err.stack;

      // try to strip useless frames
      var fn_name = getName(stackStartFunction);
      var idx = out.indexOf('\n' + fn_name);
      if (idx >= 0) {
        // once we have located the function frame
        // we need to strip out everything before it (and its line)
        var next_line = out.indexOf('\n', idx + 1);
        out = out.substring(next_line + 1);
      }

      this.stack = out;
    }
  }
};

// assert.AssertionError instanceof Error
util.inherits(assert.AssertionError, Error);

function truncate(s, n) {
  if (typeof s === 'string') {
    return s.length < n ? s : s.slice(0, n);
  } else {
    return s;
  }
}
function inspect(something) {
  if (functionsHaveNames || !util.isFunction(something)) {
    return util.inspect(something);
  }
  var rawname = getName(something);
  var name = rawname ? ': ' + rawname : '';
  return '[Function' +  name + ']';
}
function getMessage(self) {
  return truncate(inspect(self.actual), 128) + ' ' +
         self.operator + ' ' +
         truncate(inspect(self.expected), 128);
}

// At present only the three keys mentioned above are used and
// understood by the spec. Implementations or sub modules can pass
// other keys to the AssertionError's constructor - they will be
// ignored.

// 3. All of the following functions must throw an AssertionError
// when a corresponding condition is not met, with a message that
// may be undefined if not provided.  All assertion methods provide
// both the actual and expected values to the assertion error for
// display purposes.

function fail(actual, expected, message, operator, stackStartFunction) {
  throw new assert.AssertionError({
    message: message,
    actual: actual,
    expected: expected,
    operator: operator,
    stackStartFunction: stackStartFunction
  });
}

// EXTENSION! allows for well behaved errors defined elsewhere.
assert.fail = fail;

// 4. Pure assertion tests whether a value is truthy, as determined
// by !!guard.
// assert.ok(guard, message_opt);
// This statement is equivalent to assert.equal(true, !!guard,
// message_opt);. To test strictly for the value true, use
// assert.strictEqual(true, guard, message_opt);.

function ok(value, message) {
  if (!value) fail(value, true, message, '==', assert.ok);
}
assert.ok = ok;

// 5. The equality assertion tests shallow, coercive equality with
// ==.
// assert.equal(actual, expected, message_opt);

assert.equal = function equal(actual, expected, message) {
  if (actual != expected) fail(actual, expected, message, '==', assert.equal);
};

// 6. The non-equality assertion tests for whether two objects are not equal
// with != assert.notEqual(actual, expected, message_opt);

assert.notEqual = function notEqual(actual, expected, message) {
  if (actual == expected) {
    fail(actual, expected, message, '!=', assert.notEqual);
  }
};

// 7. The equivalence assertion tests a deep equality relation.
// assert.deepEqual(actual, expected, message_opt);

assert.deepEqual = function deepEqual(actual, expected, message) {
  if (!_deepEqual(actual, expected, false)) {
    fail(actual, expected, message, 'deepEqual', assert.deepEqual);
  }
};

assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) {
  if (!_deepEqual(actual, expected, true)) {
    fail(actual, expected, message, 'deepStrictEqual', assert.deepStrictEqual);
  }
};

function _deepEqual(actual, expected, strict, memos) {
  // 7.1. All identical values are equivalent, as determined by ===.
  if (actual === expected) {
    return true;
  } else if (isBuffer(actual) && isBuffer(expected)) {
    return compare$1(actual, expected) === 0;

  // 7.2. If the expected value is a Date object, the actual value is
  // equivalent if it is also a Date object that refers to the same time.
  } else if (util.isDate(actual) && util.isDate(expected)) {
    return actual.getTime() === expected.getTime();

  // 7.3 If the expected value is a RegExp object, the actual value is
  // equivalent if it is also a RegExp object with the same source and
  // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).
  } else if (util.isRegExp(actual) && util.isRegExp(expected)) {
    return actual.source === expected.source &&
           actual.global === expected.global &&
           actual.multiline === expected.multiline &&
           actual.lastIndex === expected.lastIndex &&
           actual.ignoreCase === expected.ignoreCase;

  // 7.4. Other pairs that do not both pass typeof value == 'object',
  // equivalence is determined by ==.
  } else if ((actual === null || typeof actual !== 'object') &&
             (expected === null || typeof expected !== 'object')) {
    return strict ? actual === expected : actual == expected;

  // If both values are instances of typed arrays, wrap their underlying
  // ArrayBuffers in a Buffer each to increase performance
  // This optimization requires the arrays to have the same type as checked by
  // Object.prototype.toString (aka pToString). Never perform binary
  // comparisons for Float*Arrays, though, since e.g. +0 === -0 but their
  // bit patterns are not identical.
  } else if (isView(actual) && isView(expected) &&
             pToString(actual) === pToString(expected) &&
             !(actual instanceof Float32Array ||
               actual instanceof Float64Array)) {
    return compare$1(new Uint8Array(actual.buffer),
                   new Uint8Array(expected.buffer)) === 0;

  // 7.5 For all other Object pairs, including Array objects, equivalence is
  // determined by having the same number of owned properties (as verified
  // with Object.prototype.hasOwnProperty.call), the same set of keys
  // (although not necessarily the same order), equivalent values for every
  // corresponding key, and an identical 'prototype' property. Note: this
  // accounts for both named and indexed properties on Arrays.
  } else if (isBuffer(actual) !== isBuffer(expected)) {
    return false;
  } else {
    memos = memos || {actual: [], expected: []};

    var actualIndex = memos.actual.indexOf(actual);
    if (actualIndex !== -1) {
      if (actualIndex === memos.expected.indexOf(expected)) {
        return true;
      }
    }

    memos.actual.push(actual);
    memos.expected.push(expected);

    return objEquiv(actual, expected, strict, memos);
  }
}

function isArguments(object) {
  return Object.prototype.toString.call(object) == '[object Arguments]';
}

function objEquiv(a, b, strict, actualVisitedObjects) {
  if (a === null || a === undefined || b === null || b === undefined)
    return false;
  // if one is a primitive, the other must be same
  if (util.isPrimitive(a) || util.isPrimitive(b))
    return a === b;
  if (strict && Object.getPrototypeOf(a) !== Object.getPrototypeOf(b))
    return false;
  var aIsArgs = isArguments(a);
  var bIsArgs = isArguments(b);
  if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs))
    return false;
  if (aIsArgs) {
    a = pSlice.call(a);
    b = pSlice.call(b);
    return _deepEqual(a, b, strict);
  }
  var ka = objectKeys(a);
  var kb = objectKeys(b);
  var key, i;
  // having the same number of owned properties (keys incorporates
  // hasOwnProperty)
  if (ka.length !== kb.length)
    return false;
  //the same set of keys (although not necessarily the same order),
  ka.sort();
  kb.sort();
  //~~~cheap key test
  for (i = ka.length - 1; i >= 0; i--) {
    if (ka[i] !== kb[i])
      return false;
  }
  //equivalent values for every corresponding key, and
  //~~~possibly expensive deep test
  for (i = ka.length - 1; i >= 0; i--) {
    key = ka[i];
    if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects))
      return false;
  }
  return true;
}

// 8. The non-equivalence assertion tests for any deep inequality.
// assert.notDeepEqual(actual, expected, message_opt);

assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
  if (_deepEqual(actual, expected, false)) {
    fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
  }
};

assert.notDeepStrictEqual = notDeepStrictEqual;
function notDeepStrictEqual(actual, expected, message) {
  if (_deepEqual(actual, expected, true)) {
    fail(actual, expected, message, 'notDeepStrictEqual', notDeepStrictEqual);
  }
}


// 9. The strict equality assertion tests strict equality, as determined by ===.
// assert.strictEqual(actual, expected, message_opt);

assert.strictEqual = function strictEqual(actual, expected, message) {
  if (actual !== expected) {
    fail(actual, expected, message, '===', assert.strictEqual);
  }
};

// 10. The strict non-equality assertion tests for strict inequality, as
// determined by !==.  assert.notStrictEqual(actual, expected, message_opt);

assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
  if (actual === expected) {
    fail(actual, expected, message, '!==', assert.notStrictEqual);
  }
};

function expectedException(actual, expected) {
  if (!actual || !expected) {
    return false;
  }

  if (Object.prototype.toString.call(expected) == '[object RegExp]') {
    return expected.test(actual);
  }

  try {
    if (actual instanceof expected) {
      return true;
    }
  } catch (e) {
    // Ignore.  The instanceof check doesn't work for arrow functions.
  }

  if (Error.isPrototypeOf(expected)) {
    return false;
  }

  return expected.call({}, actual) === true;
}

function _tryBlock(block) {
  var error;
  try {
    block();
  } catch (e) {
    error = e;
  }
  return error;
}

function _throws(shouldThrow, block, expected, message) {
  var actual;

  if (typeof block !== 'function') {
    throw new TypeError('"block" argument must be a function');
  }

  if (typeof expected === 'string') {
    message = expected;
    expected = null;
  }

  actual = _tryBlock(block);

  message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
            (message ? ' ' + message : '.');

  if (shouldThrow && !actual) {
    fail(actual, expected, 'Missing expected exception' + message);
  }

  var userProvidedMessage = typeof message === 'string';
  var isUnwantedException = !shouldThrow && util.isError(actual);
  var isUnexpectedException = !shouldThrow && actual && !expected;

  if ((isUnwantedException &&
      userProvidedMessage &&
      expectedException(actual, expected)) ||
      isUnexpectedException) {
    fail(actual, expected, 'Got unwanted exception' + message);
  }

  if ((shouldThrow && actual && expected &&
      !expectedException(actual, expected)) || (!shouldThrow && actual)) {
    throw actual;
  }
}

// 11. Expected to throw an error:
// assert.throws(block, Error_opt, message_opt);

assert.throws = function(block, /*optional*/error, /*optional*/message) {
  _throws(true, block, error, message);
};

// EXTENSION! This is annoying to write outside this module.
assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
  _throws(false, block, error, message);
};

assert.ifError = function(err) { if (err) throw err; };

// Expose a strict only variant of assert
function strict(value, message) {
  if (!value) fail(value, true, message, '==', strict);
}
assert.strict = objectAssign(strict, assert, {
  equal: assert.strictEqual,
  deepEqual: assert.deepStrictEqual,
  notEqual: assert.notStrictEqual,
  notDeepEqual: assert.notDeepStrictEqual
});
assert.strict.strict = assert.strict;

var objectKeys = Object.keys || function (obj) {
  var keys = [];
  for (var key in obj) {
    if (hasOwn.call(obj, key)) keys.push(key);
  }
  return keys;
};

var assertExports = assert$2.exports;
var assert$1 = /*@__PURE__*/getDefaultExportFromCjs(assertExports);

//      

/**
 * Deeply compares two object literals.
 *
 * @private
 */
function deepEqual(a        , b        )          {
    if (Array.isArray(a)) {
        if (!Array.isArray(b) || a.length !== b.length) return false;
        for (let i = 0; i < a.length; i++) {
            if (!deepEqual(a[i], b[i])) return false;
        }
        return true;
    }
    if (typeof a === 'object' && a !== null && b !== null) {
        if (!(typeof b === 'object')) return false;
        const keys = Object.keys(a);
        if (keys.length !== Object.keys(b).length) return false;
        for (const key in a) {
            if (!deepEqual(a[key], b[key])) return false;
        }
        return true;
    }
    return a === b;
}

//      


                                                   
                                          

const DEG_TO_RAD = Math.PI / 180;
const RAD_TO_DEG = 180 / Math.PI;

/**
 * Converts an angle in degrees to radians
 * copy all properties from the source objects into the destination.
 * The last source object given overrides properties from previous
 * source objects.
 *
 * @param a angle to convert
 * @returns the angle in radians
 * @private
 */
function degToRad(a        )         {
    return a * DEG_TO_RAD;
}

/**
 * Converts an angle in radians to degrees
 * copy all properties from the source objects into the destination.
 * The last source object given overrides properties from previous
 * source objects.
 *
 * @param a angle to convert
 * @returns the angle in degrees
 * @private
 */
function radToDeg(a        )         {
    return a * RAD_TO_DEG;
}

const TILE_CORNERS = [[0, 0], [1, 0], [1, 1], [0, 1]];

/**
 * Given a particular bearing, returns the corner of the tile thats farthest
 * along the bearing.
 *
 * @param {number} bearing angle in degrees (-180, 180]
 * @returns {QuadCorner}
 * @private
 */
function furthestTileCorner(bearing        )                   {
    const alignedBearing = ((bearing + 45) + 360) % 360;
    const cornerIdx = Math.round(alignedBearing / 90) % 4;
    return TILE_CORNERS[cornerIdx];
}

/**
 * @module util
 * @private
 */

/**
 * Given a value `t` that varies between 0 and 1, return
 * an interpolation function that eases between 0 and 1 in a pleasing
 * cubic in-out fashion.
 *
 * @private
 */
function easeCubicInOut(t        )         {
    if (t <= 0) return 0;
    if (t >= 1) return 1;
    const t2 = t * t,
        t3 = t2 * t;
    return 4 * (t < 0.5 ? t3 : 3 * (t - t2) + t3 - 0.75);
}

/**
 * Computes an AABB for a set of points.
 *
 * @param {Point[]} points
 * @returns {{ min: Point, max: Point}}
 * @private
 */
function getBounds(points         )                            {
    let minX = Infinity;
    let minY = Infinity;
    let maxX = -Infinity;
    let maxY = -Infinity;
    for (const p of points) {
        minX = Math.min(minX, p.x);
        minY = Math.min(minY, p.y);
        maxX = Math.max(maxX, p.x);
        maxY = Math.max(maxY, p.y);
    }

    return {
        min: new Point$2(minX, minY),
        max: new Point$2(maxX, maxY),
    };
}

/**
 * Returns the square of the 2D distance between an AABB defined by min and max and a point.
 * If point is null or undefined, the AABB distance from the origin (0,0) is returned.
 *
 * @param {Array<number>} min The minimum extent of the AABB.
 * @param {Array<number>} max The maximum extent of the AABB.
 * @param {Array<number>} [point] The point to compute the distance from, may be undefined.
 * @returns {number} The square distance from the AABB, 0.0 if the AABB contains the point.
 */
function getAABBPointSquareDist(min               , max               , point                )         {
    let sqDist = 0.0;

    for (let i = 0; i < 2; ++i) {
        const v = point ? point[i] : 0.0;
        assert$1(min[i] < max[i], 'Invalid aabb min and max inputs, min[i] must be < max[i].');
        if (min[i] > v) sqDist += (min[i] - v) * (min[i] - v);
        if (max[i] < v) sqDist += (v - max[i]) * (v - max[i]);
    }

    return sqDist;
}

/**
 * Converts a AABB into a polygon with clockwise winding order.
 *
 * @param {Point} min The top left point.
 * @param {Point} max The bottom right point.
 * @param {number} [buffer=0] The buffer width.
 * @param {boolean} [close=true] Whether to close the polygon or not.
 * @returns {Point[]} The polygon.
 */
function polygonizeBounds(min       , max       , buffer         = 0, close          = true)          {
    const offset = new Point$2(buffer, buffer);
    const minBuf = min.sub(offset);
    const maxBuf = max.add(offset);
    const polygon = [minBuf, new Point$2(maxBuf.x, minBuf.y), maxBuf, new Point$2(minBuf.x, maxBuf.y)];

    if (close) {
        polygon.push(minBuf.clone());
    }
    return polygon;
}

/**
 * Takes a convex ring and expands it outward by applying a buffer around it.
 * This function assumes that the ring is in clockwise winding order.
 *
 * @param {Point[]} ring The input ring.
 * @param {number} buffer The buffer width.
 * @returns {Point[]} The expanded ring.
 */
function bufferConvexPolygon(ring         , buffer        )          {
    assert$1(ring.length > 2, 'bufferConvexPolygon requires the ring to have atleast 3 points');
    const output = [];
    for (let currIdx = 0; currIdx < ring.length; currIdx++) {
        const prevIdx = wrap(currIdx - 1, -1, ring.length - 1);
        const nextIdx = wrap(currIdx + 1, -1, ring.length - 1);
        const prev = ring[prevIdx];
        const curr = ring[currIdx];
        const next = ring[nextIdx];
        const p1 = prev.sub(curr).unit();
        const p2 = next.sub(curr).unit();
        const interiorAngle = p2.angleWithSep(p1.x, p1.y);
        // Calcuate a vector that points in the direction of the angle bisector between two sides.
        // Scale it based on a right angled triangle constructed at that corner.
        const offset = p1.add(p2).unit().mult(-1 * buffer / Math.sin(interiorAngle / 2));
        output.push(curr.add(offset));
    }
    return output;
}

                                          

/**
 * Given given (x, y), (x1, y1) control points for a bezier curve,
 * return a function that interpolates along that curve.
 *
 * @param p1x control point 1 x coordinate
 * @param p1y control point 1 y coordinate
 * @param p2x control point 2 x coordinate
 * @param p2y control point 2 y coordinate
 * @private
 */
function bezier$1(p1x        , p1y        , p2x        , p2y        )               {
    const bezier = new UnitBezier$1(p1x, p1y, p2x, p2y);
    return function(t        ) {
        return bezier.solve(t);
    };
}

/**
 * A default bezier-curve powered easing function with
 * control points (0.25, 0.1) and (0.25, 1)
 *
 * @private
 */
const ease               = bezier$1(0.25, 0.1, 0.25, 1);

/**
 * constrain n to the given range via min + max
 *
 * @param n value
 * @param min the minimum value to be returned
 * @param max the maximum value to be returned
 * @returns the clamped value
 * @private
 */
function clamp(n        , min        , max        )         {
    return Math.min(max, Math.max(min, n));
}

/**
 * Equivalent to GLSL smoothstep.
 *
 * @param {number} e0 The lower edge of the sigmoid
 * @param {number} e1 The upper edge of the sigmoid
 * @param {number} x the value to be interpolated
 * @returns {number} in the range [0, 1]
 * @private
 */
function smoothstep(e0        , e1        , x        )         {
    x = clamp((x - e0) / (e1 - e0), 0, 1);
    return x * x * (3 - 2 * x);
}

/**
 * constrain n to the given range, excluding the minimum, via modular arithmetic
 *
 * @param n value
 * @param min the minimum value to be returned, exclusive
 * @param max the maximum value to be returned, inclusive
 * @returns constrained number
 * @private
 */
function wrap(n        , min        , max        )         {
    const d = max - min;
    const w = ((n - min) % d + d) % d + min;
    return (w === min) ? max : w;
}

/**
 * Computes shortest angle in range [-180, 180) between two angles.
 *
 * @param {*} a First angle in degrees
 * @param {*} b Second angle in degrees
 * @returns Shortest angle
 * @private
 */
function shortestAngle(a        , b        )         {
    const diff = (b - a + 180) % 360 - 180;
    return diff < -180 ? diff + 360 : diff;
}

/*
 * Call an asynchronous function on an array of arguments,
 * calling `callback` with the completed results of all calls.
 *
 * @param array input to each call of the async function.
 * @param fn an async function with signature (data, callback)
 * @param callback a callback run after all async work is done.
 * called with an array, containing the results of each async call.
 * @private
 */
function asyncAll              (
    array             ,
    fn                                                    ,
    callback                         
)       {
    if (!array.length) { return callback(null, []); }
    let remaining = array.length;
    const results = new Array(array.length);
    let error = null;
    array.forEach((item, i) => {
        fn(item, (err, result) => {
            if (err) error = err;
            results[i] = ((result     )        ); // https://github.com/facebook/flow/issues/2123
            if (--remaining === 0) callback(error, results);
        });
    });
}

/*
 * Polyfill for Object.values. Not fully spec compliant, but we don't
 * need it to be.
 *
 * @private
 */
function values   (obj                    )           {
    const result = [];
    for (const k in obj) {
        result.push(obj[k]);
    }
    return result;
}

/*
 * Compute the difference between the keys in one object and the keys
 * in another object.
 *
 * @returns keys difference
 * @private
 */
function keysDifference      (obj                    , other                    )                {
    const difference = [];
    for (const i in obj) {
        if (!(i in other)) {
            difference.push(i);
        }
    }
    return difference;
}

/**
 * Given a destination object and optionally many source objects,
 * copy all properties from the source objects into the destination.
 * The last source object given overrides properties from previous
 * source objects.
 *
 * @param dest destination object
 * @param sources sources from which properties are pulled
 * @private
 */
function extend$1(dest        , ...sources                )         {
    for (const src of sources) {
        for (const k in src) {
            dest[k] = src[k];
        }
    }
    return dest;
}

/**
 * Given an object and a number of properties as strings, return version
 * of that object with only those properties.
 *
 * @param src the object
 * @param properties an array of property names chosen
 * to appear on the resulting object.
 * @returns object with limited properties.
 * @example
 * var foo = { name: 'Charlie', age: 10 };
 * var justName = pick(foo, ['name']);
 * // justName = { name: 'Charlie' }
 * @private
 */
function pick(src        , properties               )         {
    const result = {};
    for (let i = 0; i < properties.length; i++) {
        const k = properties[i];
        if (k in src) {
            result[k] = src[k];
        }
    }
    return result;
}

let id = 1;

/**
 * Return a unique numeric id, starting at 1 and incrementing with
 * each call.
 *
 * @returns unique numeric id.
 * @private
 */
function uniqueId()         {
    return id++;
}

/**
 * Return a random UUID (v4). Taken from: https://gist.github.com/jed/982883
 * @private
 */
function uuid()         {
    function b(a      ) {
        return a ? (a ^ Math.random() * (16 >> a / 4)).toString(16) :
        //$FlowFixMe: Flow doesn't like the implied array literal conversion here
            ([1e7] + -[1e3] + -4e3 + -8e3 + -1e11).replace(/[018]/g, b);
    }
    return b();
}

/**
 * Return whether a given value is a power of two
 * @private
 */
function isPowerOfTwo(value        )          {
    return (Math.log(value) / Math.LN2) % 1 === 0;
}

/**
 * Return the next power of two, or the input value if already a power of two
 * @private
 */
function nextPowerOfTwo(value        )         {
    if (value <= 1) return 1;
    return Math.pow(2, Math.ceil(Math.log(value) / Math.LN2));
}

/**
 * Return the previous power of two, or the input value if already a power of two
 * @private
 */
function prevPowerOfTwo(value        )         {
    if (value <= 1) return 1;
    return Math.pow(2, Math.floor(Math.log(value) / Math.LN2));
}

/**
 * Validate a string to match UUID(v4) of the
 * form: xxxxxxxx-xxxx-4xxx-[89ab]xxx-xxxxxxxxxxxx
 * @param str string to validate.
 * @private
 */
function validateUuid(str         )          {
    return str ? /^[0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(str) : false;
}

/**
 * Given an array of member function names as strings, replace all of them
 * with bound versions that will always refer to `context` as `this`. This
 * is useful for classes where otherwise event bindings would reassign
 * `this` to the evented object or some other value: this lets you ensure
 * the `this` value always.
 *
 * @param fns list of member function names
 * @param context the context value
 * @example
 * function MyClass() {
 *   bindAll(['ontimer'], this);
 *   this.name = 'Tom';
 * }
 * MyClass.prototype.ontimer = function() {
 *   alert(this.name);
 * };
 * var myClass = new MyClass();
 * setTimeout(myClass.ontimer, 100);
 * @private
 */
function bindAll(fns               , context        )       {
    fns.forEach((fn) => {
        if (!context[fn]) { return; }
        context[fn] = context[fn].bind(context);
    });
}

/**
 * Determine if a string ends with a particular substring
 *
 * @private
 */
function endsWith(string        , suffix        )          {
    return string.indexOf(suffix, string.length - suffix.length) !== -1;
}

/**
 * Create an object by mapping all the values of an existing object while
 * preserving their keys.
 *
 * @private
 */
// $FlowFixMe[missing-this-annot]
function mapObject(input        , iterator          , context         )         {
    const output = {};
    for (const key in input) {
        output[key] = iterator.call(context || this, input[key], key, input);
    }
    return output;
}

/**
 * Create an object by filtering out values of an existing object.
 *
 * @private
 */
// $FlowFixMe[missing-this-annot]
function filterObject(input        , iterator          , context         )         {
    const output = {};
    for (const key in input) {
        if (iterator.call(context || this, input[key], key, input)) {
            output[key] = input[key];
        }
    }
    return output;
}

/**
 * Deeply clones two objects.
 *
 * @private
 */
function clone$9   (input   )    {
    if (Array.isArray(input)) {
        return ((input.map(clone$9)     )   );
    } else if (typeof input === 'object' && input) {
        return ((mapObject(input, clone$9)     )   );
    } else {
        return input;
    }
}

/**
 * Maps a value from a range between [min, max] to the range [outMin, outMax]
 *
 * @private
 */
function mapValue(value        , min        , max        , outMin        , outMax        )         {
    return clamp((value - min) / (max - min) * (outMax - outMin) + outMin, outMin, outMax);
}

/**
 * Check if two arrays have at least one common element.
 *
 * @private
 */
function arraysIntersect   (a          , b          )          {
    for (let l = 0; l < a.length; l++) {
        if (b.indexOf(a[l]) >= 0) return true;
    }
    return false;
}

/**
 * Print a warning message to the console and ensure duplicate warning messages
 * are not printed.
 *
 * @private
 */
const warnOnceHistory                           = {};

function warnOnce(message        )       {
    if (!warnOnceHistory[message]) {
        // console isn't defined in some WebWorkers, see #2558
        if (typeof console !== "undefined") console.warn(message);
        warnOnceHistory[message] = true;
    }
}

/**
 * Indicates if the provided Points are in a counter clockwise (true) or clockwise (false) order
 *
 * @private
 * @returns true for a counter clockwise set of points
 */
// http://bryceboe.com/2006/10/23/line-segment-intersection-algorithm/
function isCounterClockwise(a       , b       , c       )          {
    return (c.y - a.y) * (b.x - a.x) > (b.y - a.y) * (c.x - a.x);
}

/**
 * Returns the signed area for the polygon ring.  Postive areas are exterior rings and
 * have a clockwise winding.  Negative areas are interior rings and have a counter clockwise
 * ordering.
 *
 * @private
 * @param ring Exterior or interior ring
 */
function calculateSignedArea(ring              )         {
    let sum = 0;
    for (let i = 0, len = ring.length, j = len - 1, p1, p2; i < len; j = i++) {
        p1 = ring[i];
        p2 = ring[j];
        sum += (p2.x - p1.x) * (p1.y + p2.y);
    }
    return sum;
}

/* global self, WorkerGlobalScope */
/**
 *  Returns true if run in the web-worker context.
 *
 * @private
 * @returns {boolean}
 */
function isWorker()          {
    return typeof WorkerGlobalScope !== 'undefined' && typeof self !== 'undefined' &&
           self instanceof WorkerGlobalScope;
}

/**
 * Parses data from 'Cache-Control' headers.
 *
 * @private
 * @param cacheControl Value of 'Cache-Control' header
 * @return object containing parsed header info.
 */

function parseCacheControl(cacheControl        )         {
    // Taken from [Wreck](https://github.com/hapijs/wreck)
    const re = /(?:^|(?:\s*\,\s*))([^\x00-\x20\(\)<>@\,;\:\\"\/\[\]\?\=\{\}\x7F]+)(?:\=(?:([^\x00-\x20\(\)<>@\,;\:\\"\/\[\]\?\=\{\}\x7F]+)|(?:\"((?:[^"\\]|\\.)*)\")))?/g;

    const header = {};
    cacheControl.replace(re, ($0, $1, $2, $3) => {
        const value = $2 || $3;
        header[$1] = value ? value.toLowerCase() : true;
        return '';
    });

    if (header['max-age']) {
        const maxAge = parseInt(header['max-age'], 10);
        if (isNaN(maxAge)) delete header['max-age'];
        else header['max-age'] = maxAge;
    }

    return header;
}

let _isSafari = null;

function _resetSafariCheckForTest() {
    _isSafari = null;
}

/**
 * Returns true when run in WebKit derived browsers.
 * This is used as a workaround for a memory leak in Safari caused by using Transferable objects to
 * transfer data between WebWorkers and the main thread.
 * https://github.com/mapbox/mapbox-gl-js/issues/8771
 *
 * This should be removed once the underlying Safari issue is fixed.
 *
 * @private
 * @param scope {WindowOrWorkerGlobalScope} Since this function is used both on the main thread and WebWorker context,
 *      let the calling scope pass in the global scope object.
 * @returns {boolean}
 */
function isSafari(scope     )          {
    if (_isSafari == null) {
        const userAgent = scope.navigator ? scope.navigator.userAgent : null;
        _isSafari = !!scope.safari ||
        !!(userAgent && (/\b(iPad|iPhone|iPod)\b/.test(userAgent) || (!!userAgent.match('Safari') && !userAgent.match('Chrome'))));
    }
    return _isSafari;
}

function isSafariWithAntialiasingBug(scope     )           {
    const userAgent = scope.navigator ? scope.navigator.userAgent : null;
    if (!isSafari(scope)) return false;
    // 15.4 is known to be buggy.
    // 15.5 may or may not include the fix. Mark it as buggy to be on the safe side.
    return userAgent && (userAgent.match('Version/15.4') || userAgent.match('Version/15.5') || userAgent.match(/CPU (OS|iPhone OS) (15_4|15_5) like Mac OS X/));
}

function isFullscreen()          {
    return !!window$1.document.fullscreenElement || !!window$1.document.webkitFullscreenElement;
}

function storageAvailable(type        )          {
    try {
        const storage = window$1[type];
        storage.setItem('_mapbox_test_', 1);
        storage.removeItem('_mapbox_test_');
        return true;
    } catch (e) {
        return false;
    }
}

// The following methods are from https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#The_Unicode_Problem
//Unicode compliant base64 encoder for strings
function b64EncodeUnicode(str        )         {
    return window$1.btoa(
        encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
            (match, p1) => {
                return String.fromCharCode(Number('0x' + p1)); //eslint-disable-line
            }
        )
    );
}

// Unicode compliant decoder for base64-encoded strings
function b64DecodeUnicode(str        )         {
    return decodeURIComponent(window$1.atob(str).split('').map((c) => {
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); //eslint-disable-line
    }).join(''));
}

function getColumn(matrix      , col        )       {
    return [matrix[col * 4], matrix[col * 4 + 1], matrix[col * 4 + 2], matrix[col * 4 + 3]];
}

function setColumn(matrix      , col        , values      ) {
    matrix[col * 4 + 0] = values[0];
    matrix[col * 4 + 1] = values[1];
    matrix[col * 4 + 2] = values[2];
    matrix[col * 4 + 3] = values[3];
}

//      


                                              

const CACHE_NAME = 'mapbox-tiles';
let cacheLimit = 500; // 50MB / (100KB/tile) ~= 500 tiles
let cacheCheckThreshold = 50;

const MIN_TIME_UNTIL_EXPIRY = 1000 * 60 * 7; // 7 minutes. Skip caching tiles with a short enough max age.

                               
                   
                       
                    
  

// We're using a global shared cache object. Normally, requesting ad-hoc Cache objects is fine, but
// Safari has a memory leak in which it fails to release memory when requesting keys() from a Cache
// object. See https://bugs.webkit.org/show_bug.cgi?id=203991 for more information.
let sharedCache                 ;

function getCaches() {
    try {
        return window$1.caches;
    } catch (e) {
        // <iframe sandbox> triggers exceptions when trying to access window.caches
        // Chrome: DOMException, Safari: SecurityError, Firefox: NS_ERROR_FAILURE
        // Seems more robust to catch all exceptions instead of trying to match only these.
    }
}

function cacheOpen() {
    const caches = getCaches();
    if (caches && !sharedCache) {
        sharedCache = window$1.caches.open(CACHE_NAME);
    }
}

// We're never closing the cache, but our unit tests rely on changing out the global window.caches
// object, so we have a function specifically for unit tests that allows resetting the shared cache.
function cacheClose() {
    sharedCache = undefined;
}

let responseConstructorSupportsReadableStream;
function prepareBody(response          , callback                                            ) {
    if (responseConstructorSupportsReadableStream === undefined) {
        try {
            new Response(new ReadableStream()); // eslint-disable-line no-undef
            responseConstructorSupportsReadableStream = true;
        } catch (e) {
            // Edge
            responseConstructorSupportsReadableStream = false;
        }
    }

    if (responseConstructorSupportsReadableStream) {
        callback(response.body);
    } else {
        response.blob().then(callback);
    }
}

function cachePut(request         , response          , requestTime        ) {
    cacheOpen();
    if (!sharedCache) return;

    const options                  = {
        status: response.status,
        statusText: response.statusText,
        headers: new window$1.Headers()
    };
    response.headers.forEach((v, k) => options.headers.set(k, v));

    const cacheControl = parseCacheControl(response.headers.get('Cache-Control') || '');
    if (cacheControl['no-store']) {
        return;
    }
    if (cacheControl['max-age']) {
        options.headers.set('Expires', new Date(requestTime + cacheControl['max-age'] * 1000).toUTCString());
    }

    const expires = options.headers.get('Expires');
    if (!expires) return;
    const timeUntilExpiry = new Date(expires).getTime() - requestTime;
    if (timeUntilExpiry < MIN_TIME_UNTIL_EXPIRY) return;

    prepareBody(response, body => {
        const clonedResponse = new window$1.Response(body, options);

        cacheOpen();
        if (!sharedCache) return;
        sharedCache
            .then(cache => cache.put(stripQueryParameters(request.url), clonedResponse))
            .catch(e => warnOnce(e.message));
    });
}

function getQueryParameters(url        ) {
    const paramStart = url.indexOf('?');
    return paramStart > 0 ? url.slice(paramStart + 1).split('&') : [];
}

function stripQueryParameters(url        ) {
    const start = url.indexOf('?');
    if (start < 0) return url;

    // preserve `language` and `worldview` params if any
    const params = getQueryParameters(url);
    const filteredParams = params.filter(param => {
        const entry = param.split('=');
        return entry[0] === 'language' || entry[0] === 'worldview';
    });

    if (filteredParams.length) {
        return `${url.slice(0, start)}?${filteredParams.join('&')}`;
    }

    return url.slice(0, start);
}

function cacheGet(request         , callback                                                             )       {
    cacheOpen();
    if (!sharedCache) return callback(null);

    const strippedURL = stripQueryParameters(request.url);

    ((sharedCache     )                )
        .then(cache => {
            // manually strip URL instead of `ignoreSearch: true` because of a known
            // performance issue in Chrome https://github.com/mapbox/mapbox-gl-js/issues/8431
            cache.match(strippedURL)
                .then(response => {
                    const fresh = isFresh(response);

                    // Reinsert into cache so that order of keys in the cache is the order of access.
                    // This line makes the cache a LRU instead of a FIFO cache.
                    cache.delete(strippedURL);
                    if (fresh) {
                        cache.put(strippedURL, response.clone());
                    }

                    callback(null, response, fresh);
                })
                .catch(callback);
        })
        .catch(callback);

}

function isFresh(response          ) {
    if (!response) return false;
    const expires = new Date(response.headers.get('Expires') || 0);
    const cacheControl = parseCacheControl(response.headers.get('Cache-Control') || '');
    return expires > Date.now() && !cacheControl['no-cache'];
}

// `Infinity` triggers a cache check after the first tile is loaded
// so that a check is run at least once on each page load.
let globalEntryCounter = Infinity;

// The cache check gets run on a worker. The reason for this is that
// profiling sometimes shows this as taking up significant time on the
// thread it gets called from. And sometimes it doesn't. It *may* be
// fine to run this on the main thread but out of caution this is being
// dispatched on a worker. This can be investigated further in the future.
function cacheEntryPossiblyAdded(dispatcher            ) {
    globalEntryCounter++;
    if (globalEntryCounter > cacheCheckThreshold) {
        dispatcher.getActor().send('enforceCacheSizeLimit', cacheLimit);
        globalEntryCounter = 0;
    }
}

// runs on worker, see above comment
function enforceCacheSizeLimit(limit        ) {
    cacheOpen();
    if (!sharedCache) return;

    sharedCache
        .then(cache => {
            cache.keys().then(keys => {
                for (let i = 0; i < keys.length - limit; i++) {
                    cache.delete(keys[i]);
                }
            });
        });
}

function clearTileCache(callback                        ) {
    const caches = getCaches();
    if (!caches) return;

    const promise = window$1.caches.delete(CACHE_NAME);
    if (callback) {
        promise.catch(callback).then(() => callback());
    }
}

function setCacheLimits(limit        , checkThreshold        ) {
    cacheLimit = limit;
    cacheCheckThreshold = checkThreshold;
}

//      


                                                   
                                                       

/**
 * The type of a resource.
 * @private
 * @readonly
 * @enum {string}
 */
const ResourceType = {
    Unknown: 'Unknown',
    Style: 'Style',
    Source: 'Source',
    Tile: 'Tile',
    Glyphs: 'Glyphs',
    SpriteImage: 'SpriteImage',
    SpriteJSON: 'SpriteJSON',
    Image: 'Image'
};

if (typeof Object.freeze == 'function') {
    Object.freeze(ResourceType);
}

/**
 * A `RequestParameters` object to be returned from Map.options.transformRequest callbacks.
 * @typedef {Object} RequestParameters
 * @property {string} url The URL to be requested.
 * @property {Object} headers The headers to be sent with the request.
 * @property {string} method Request method `'GET' | 'POST' | 'PUT'`.
 * @property {string} body Request body.
 * @property {string} type Response body type to be returned `'string' | 'json' | 'arrayBuffer'`.
 * @property {string} credentials `'same-origin'|'include'` Use 'include' to send cookies with cross-origin requests.
 * @property {boolean} collectResourceTiming If true, Resource Timing API information will be collected for these transformed requests and returned in a resourceTiming property of relevant data events.
 * @property {string} referrerPolicy A string representing the request's referrerPolicy. For more information and possible values, see the [Referrer-Policy HTTP header page](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy).
 * @example
 * // use transformRequest to modify requests that begin with `http://myHost`
 * const map = new Map({
 *     container: 'map',
 *     style: 'mapbox://styles/mapbox/streets-v11',
 *     transformRequest: (url, resourceType) => {
 *         if (resourceType === 'Source' && url.indexOf('http://myHost') > -1) {
 *             return {
 *                 url: url.replace('http', 'https'),
 *                 headers: {'my-custom-header': true},
 *                 credentials: 'include'  // Include cookies for cross-origin requests
 *             };
 *         }
 *     }
 * });
 *
 */
                                 
                
                     
                                    
                  
                                             
                                            
                                    
                                       
 

                                                                                                             

class AJAXError extends Error {
                   
                
    constructor(message        , status        , url        ) {
        if (status === 401 && isMapboxHTTPURL(url)) {
            message += ': you may have provided an invalid Mapbox access token. See https://docs.mapbox.com/api/overview/#access-tokens-and-token-scopes';
        }
        super(message);
        this.status = status;
        this.url = url;
    }

    toString()         {
        return `${this.name}: ${this.message} (${this.status}): ${this.url}`;
    }
}

// Ensure that we're sending the correct referrer from blob URL worker bundles.
// For files loaded from the local file system, `location.origin` will be set
// to the string(!) "null" (Firefox), or "file://" (Chrome, Safari, Edge, IE),
// and we will set an empty referrer. Otherwise, we're using the document's URL.
/* global self */
const getReferrer                 = isWorker() ?
    () => self.worker && self.worker.referrer :
    () => (window$1.location.protocol === 'blob:' ? window$1.parent : window$1).location.href;

// Determines whether a URL is a file:// URL. This is obviously the case if it begins
// with file://. Relative URLs are also file:// URLs iff the original document was loaded
// via a file:// URL.
const isFileURL = (url        ) => /^file:/.test(url) || (/^file:/.test(getReferrer()) && !/^\w+:/.test(url));

function makeFetchRequest(requestParameters                   , callback                       )             {
    const controller = new window$1.AbortController();
    const request = new window$1.Request(requestParameters.url, {
        method: requestParameters.method || 'GET',
        body: requestParameters.body,
        credentials: requestParameters.credentials,
        headers: requestParameters.headers,
        referrer: getReferrer(),
        referrerPolicy: requestParameters.referrerPolicy,
        signal: controller.signal
    });
    let complete = false;
    let aborted = false;

    const cacheIgnoringSearch = hasCacheDefeatingSku(request.url);

    if (requestParameters.type === 'json') {
        request.headers.set('Accept', 'application/json');
    }

    const validateOrFetch = (err        , cachedResponse           , responseIsFresh          ) => {
        if (aborted) return;

        if (err) {
            // Do fetch in case of cache error.
            // HTTP pages in Edge trigger a security error that can be ignored.
            if (err.message !== 'SecurityError') {
                warnOnce(err.toString());
            }
        }

        if (cachedResponse && responseIsFresh) {
            return finishRequest(cachedResponse);
        }

        if (cachedResponse) {
            // We can't do revalidation with 'If-None-Match' because then the
            // request doesn't have simple cors headers.
        }

        const requestTime = Date.now();

        window$1.fetch(request).then(response => {
            if (response.ok) {
                const cacheableResponse = cacheIgnoringSearch ? response.clone() : null;
                return finishRequest(response, cacheableResponse, requestTime);
            } else {
                return callback(new AJAXError(response.statusText, response.status, requestParameters.url));
            }
        }).catch(error => {
            if (error.name === 'AbortError') {
                // silence expected AbortError
                return;
            }
            callback(new Error(`${error.message} ${requestParameters.url}`));
        });
    };

    const finishRequest = (response          , cacheableResponse           , requestTime         ) => {
        (
            requestParameters.type === 'arrayBuffer' ? response.arrayBuffer() :
            requestParameters.type === 'json' ? response.json() :
            response.text()
        ).then(result => {
            if (aborted) return;
            if (cacheableResponse && requestTime) {
                // The response needs to be inserted into the cache after it has completely loaded.
                // Until it is fully loaded there is a chance it will be aborted. Aborting while
                // reading the body can cause the cache insertion to error. We could catch this error
                // in most browsers but in Firefox it seems to sometimes crash the tab. Adding
                // it to the cache here avoids that error.
                cachePut(request, cacheableResponse, requestTime);
            }
            complete = true;
            callback(null, result, response.headers.get('Cache-Control'), response.headers.get('Expires'));
        }).catch(err => {
            if (!aborted) callback(new Error(err.message));
        });
    };

    if (cacheIgnoringSearch) {
        cacheGet(request, validateOrFetch);
    } else {
        validateOrFetch(null, null);
    }

    return {cancel: () => {
        aborted = true;
        if (!complete) controller.abort();
    }};
}

function makeXMLHttpRequest(requestParameters                   , callback                       )             {
    const xhr                 = new window$1.XMLHttpRequest();

    xhr.open(requestParameters.method || 'GET', requestParameters.url, true);
    if (requestParameters.type === 'arrayBuffer') {
        xhr.responseType = 'arraybuffer';
    }
    for (const k in requestParameters.headers) {
        xhr.setRequestHeader(k, requestParameters.headers[k]);
    }
    if (requestParameters.type === 'json') {
        xhr.responseType = 'text';
        xhr.setRequestHeader('Accept', 'application/json');
    }
    xhr.withCredentials = requestParameters.credentials === 'include';
    xhr.onerror = () => {
        callback(new Error(xhr.statusText));
    };
    xhr.onload = () => {
        if (((xhr.status >= 200 && xhr.status < 300) || xhr.status === 0) && xhr.response !== null) {
            let data        = xhr.response;
            if (requestParameters.type === 'json') {
                // We're manually parsing JSON here to get better error messages.
                try {
                    data = JSON.parse(xhr.response);
                } catch (err) {
                    return callback(err);
                }
            }
            callback(null, data, xhr.getResponseHeader('Cache-Control'), xhr.getResponseHeader('Expires'));
        } else {
            callback(new AJAXError(xhr.statusText, xhr.status, requestParameters.url));
        }
    };
    xhr.send(requestParameters.body);
    return {cancel: () => xhr.abort()};
}

const makeRequest = function(requestParameters                   , callback                       )             {
    // We're trying to use the Fetch API if possible. However, in some situations we can't use it:
    // - Safari exposes window.AbortController, but it doesn't work actually abort any requests in
    //   older versions (see https://bugs.webkit.org/show_bug.cgi?id=174980#c2). In this case,
    //   we dispatch the request to the main thread so that we can get an accurate referrer header.
    // - Requests for resources with the file:// URI scheme don't work with the Fetch API either. In
    //   this case we unconditionally use XHR on the current thread since referrers don't matter.
    if (!isFileURL(requestParameters.url)) {
        if (window$1.fetch && window$1.Request && window$1.AbortController && window$1.Request.prototype.hasOwnProperty('signal')) {
            return makeFetchRequest(requestParameters, callback);
        }
        if (isWorker() && self.worker && self.worker.actor) {
            const queueOnMainThread = true;
            return self.worker.actor.send('getResource', requestParameters, callback, undefined, queueOnMainThread);
        }
    }
    return makeXMLHttpRequest(requestParameters, callback);
};

const getJSON = function(requestParameters                   , callback                          )             {
    return makeRequest(extend$1(requestParameters, {type: 'json'}), callback);
};

const getArrayBuffer = function(requestParameters                   , callback                               )             {
    return makeRequest(extend$1(requestParameters, {type: 'arrayBuffer'}), callback);
};

const postData = function(requestParameters                   , callback                          )             {
    return makeRequest(extend$1(requestParameters, {method: 'POST'}), callback);
};

const getData = function(requestParameters                   , callback                          )             {
    return makeRequest(extend$1(requestParameters, {method: 'GET'}), callback);
};

function sameOrigin(url        ) {
    const a                    = window$1.document.createElement('a');
    a.href = url;
    return a.protocol === window$1.document.location.protocol && a.host === window$1.document.location.host;
}

const transparentPngUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYV2NgAAIAAAUAAarVyFEAAAAASUVORK5CYII=';

function arrayBufferToImage(data             , callback                            ) {
    const img                   = new window$1.Image();
    const URL = window$1.URL;
    img.onload = () => {
        callback(null, img);
        URL.revokeObjectURL(img.src);
        // prevent image dataURI memory leak in Safari;
        // but don't free the image immediately because it might be uploaded in the next frame
        // https://github.com/mapbox/mapbox-gl-js/issues/10226
        img.onload = null;
        window$1.requestAnimationFrame(() => { img.src = transparentPngUrl; });
    };
    img.onerror = () => callback(new Error('Could not load image. Please make sure to use a supported image type such as PNG or JPEG. Note that SVGs are not supported.'));
    const blob       = new window$1.Blob([new Uint8Array(data)], {type: 'image/png'});
    img.src = data.byteLength ? URL.createObjectURL(blob) : transparentPngUrl;
}

function arrayBufferToImageBitmap(data             , callback                       ) {
    const blob       = new window$1.Blob([new Uint8Array(data)], {type: 'image/png'});
    window$1.createImageBitmap(blob).then((imgBitmap) => {
        callback(null, imgBitmap);
    }).catch((e) => {
        callback(new Error(`Could not load image because of ${e.message}. Please make sure to use a supported image type such as PNG or JPEG. Note that SVGs are not supported.`));
    });
}

let imageQueue, numImageRequests;
const resetImageRequestQueue = () => {
    imageQueue = [];
    numImageRequests = 0;
};
resetImageRequestQueue();

const getImage = function(requestParameters                   , callback                                                  )             {
    if (exported$1.supported) {
        if (!requestParameters.headers) {
            requestParameters.headers = {};
        }
        requestParameters.headers.accept = 'image/webp,*/*';
    }

    // limit concurrent image loads to help with raster sources performance on big screens
    if (numImageRequests >= config.MAX_PARALLEL_IMAGE_REQUESTS) {
        const queued = {
            requestParameters,
            callback,
            cancelled: false,
            // $FlowFixMe[object-this-reference]
            cancel() { this.cancelled = true; }
        };
        imageQueue.push(queued);
        return queued;
    }
    numImageRequests++;

    let advanced = false;
    const advanceImageRequestQueue = () => {
        if (advanced) return;
        advanced = true;
        numImageRequests--;
        assert$1(numImageRequests >= 0);
        while (imageQueue.length && numImageRequests < config.MAX_PARALLEL_IMAGE_REQUESTS) { // eslint-disable-line
            const request = imageQueue.shift();
            const {requestParameters, callback, cancelled} = request;
            if (!cancelled) {
                // $FlowFixMe[cannot-write] - Flow can't infer that cancel is a writable property
                request.cancel = getImage(requestParameters, callback).cancel;
            }
        }
    };

    // request the image with XHR to work around caching issues
    // see https://github.com/mapbox/mapbox-gl-js/issues/1470
    const request = getArrayBuffer(requestParameters, (err        , data              , cacheControl         , expires         ) => {

        advanceImageRequestQueue();

        if (err) {
            callback(err);
        } else if (data) {
            if (window$1.createImageBitmap) {
                arrayBufferToImageBitmap(data, (err, imgBitmap) => callback(err, imgBitmap, cacheControl, expires));
            } else {
                arrayBufferToImage(data, (err, img) => callback(err, img, cacheControl, expires));
            }
        }
    });

    return {
        cancel: () => {
            request.cancel();
            advanceImageRequestQueue();
        }
    };
};

const getVideo = function(urls               , callback                            )             {
    const video                   = window$1.document.createElement('video');
    video.muted = true;
    video.onloadstart = function() {
        callback(null, video);
    };
    for (let i = 0; i < urls.length; i++) {
        const s                    = window$1.document.createElement('source');
        if (!sameOrigin(urls[i])) {
            video.crossOrigin = 'Anonymous';
        }
        s.src = urls[i];
        video.appendChild(s);
    }
    return {cancel: () => {}};
};

//      


                                                   
                                                                                                           

                   
                     
                      
                 
                         
   

                                           

const AUTH_ERR_MSG         = 'NO_ACCESS_TOKEN';

class RequestManager {
                      
                               
                                                   
                                
                                

    constructor(transformRequestFn                           , customAccessToken         , silenceAuthErrors          ) {
        this._transformRequestFn = transformRequestFn;
        this._customAccessToken = customAccessToken;
        this._silenceAuthErrors = !!silenceAuthErrors;
        this._createSkuToken();
    }

    _createSkuToken() {
        const skuToken = createSkuToken();
        this._skuToken = skuToken.token;
        this._skuTokenExpiresAt = skuToken.tokenExpiresAt;
    }

    _isSkuTokenExpired()          {
        return Date.now() > this._skuTokenExpiresAt;
    }

    transformRequest(url        , type                  )                    {
        if (this._transformRequestFn) {
            return this._transformRequestFn(url, type) || {url};
        }

        return {url};
    }

    normalizeStyleURL(url        , accessToken         )         {
        if (!isMapboxURL(url)) return url;
        const urlObject = parseUrl(url);
        urlObject.path = `/styles/v1${urlObject.path}`;
        return this._makeAPIURL(urlObject, this._customAccessToken || accessToken);
    }

    normalizeGlyphsURL(url        , accessToken         )         {
        if (!isMapboxURL(url)) return url;
        const urlObject = parseUrl(url);
        urlObject.path = `/fonts/v1${urlObject.path}`;
        return this._makeAPIURL(urlObject, this._customAccessToken || accessToken);
    }

    normalizeSourceURL(url        , accessToken          , language          , worldview          )         {
        if (!isMapboxURL(url)) return url;
        const urlObject = parseUrl(url);
        urlObject.path = `/v4/${urlObject.authority}.json`;
        // TileJSON requests need a secure flag appended to their URLs so
        // that the server knows to send SSL-ified resource references.
        urlObject.params.push('secure');
        if (language) {
            urlObject.params.push(`language=${language}`);
        }
        if (worldview) {
            urlObject.params.push(`worldview=${worldview}`);
        }

        return this._makeAPIURL(urlObject, this._customAccessToken || accessToken);
    }

    normalizeSpriteURL(url        , format        , extension        , accessToken         )         {
        const urlObject = parseUrl(url);
        if (!isMapboxURL(url)) {
            urlObject.path += `${format}${extension}`;
            return formatUrl(urlObject);
        }
        urlObject.path = `/styles/v1${urlObject.path}/sprite${format}${extension}`;
        return this._makeAPIURL(urlObject, this._customAccessToken || accessToken);
    }

    normalizeTileURL(tileURL        , use2x          , rasterTileSize         )         {
        if (this._isSkuTokenExpired()) {
            this._createSkuToken();
        }

        if (tileURL && !isMapboxURL(tileURL)) return tileURL;

        const urlObject = parseUrl(tileURL);
        const imageExtensionRe = /(\.(png|jpg)\d*)(?=$)/;
        const extension = exported$1.supported ? '.webp' : '$1';

        // The v4 mapbox tile API supports 512x512 image tiles but they must be requested as '@2x' tiles.
        const use2xAs512 = rasterTileSize && urlObject.authority !== 'raster' && rasterTileSize === 512;

        const suffix = use2x || use2xAs512 ? '@2x' : '';
        urlObject.path = urlObject.path.replace(imageExtensionRe, `${suffix}${extension}`);

        if (urlObject.authority === 'raster') {
            urlObject.path = `/${config.RASTER_URL_PREFIX}${urlObject.path}`;
        } else {
            const tileURLAPIPrefixRe = /^.+\/v4\//;
            urlObject.path = urlObject.path.replace(tileURLAPIPrefixRe, '/');
            urlObject.path = `/${config.TILE_URL_VERSION}${urlObject.path}`;
        }

        const accessToken = this._customAccessToken || getAccessToken(urlObject.params) || config.ACCESS_TOKEN;
        if (config.REQUIRE_ACCESS_TOKEN && accessToken && this._skuToken) {
            urlObject.params.push(`sku=${this._skuToken}`);
        }

        return this._makeAPIURL(urlObject, accessToken);
    }

    canonicalizeTileURL(url        , removeAccessToken         )         {
        // matches any file extension specified by a dot and one or more alphanumeric characters
        const extensionRe = /\.[\w]+$/;

        const urlObject = parseUrl(url);
        // Make sure that we are dealing with a valid Mapbox tile URL.
        // Has to begin with /v4/ or /raster/v1, with a valid filename + extension
        if (!urlObject.path.match(/^(\/v4\/|\/raster\/v1\/)/) || !urlObject.path.match(extensionRe)) {
            // Not a proper Mapbox tile URL.
            return url;
        }
        // Reassemble the canonical URL from the parts we've parsed before.
        let result = "mapbox://";
        if (urlObject.path.match(/^\/raster\/v1\//)) {
            // If the tile url has /raster/v1/, make the final URL mapbox://raster/....
            const rasterPrefix = `/${config.RASTER_URL_PREFIX}/`;
            result += `raster/${urlObject.path.replace(rasterPrefix, '')}`;
        } else {
            const tilesPrefix = `/${config.TILE_URL_VERSION}/`;
            result += `tiles/${urlObject.path.replace(tilesPrefix, '')}`;
        }

        // Append the query string, minus the access token parameter.
        let params = urlObject.params;
        if (removeAccessToken) {
            params = params.filter(p => !p.match(/^access_token=/));
        }
        if (params.length) result += `?${params.join('&')}`;
        return result;
    }

    canonicalizeTileset(tileJSON          , sourceURL         )                {
        const removeAccessToken = sourceURL ? isMapboxURL(sourceURL) : false;
        const canonical = [];
        for (const url of tileJSON.tiles || []) {
            if (isMapboxHTTPURL(url)) {
                canonical.push(this.canonicalizeTileURL(url, removeAccessToken));
            } else {
                canonical.push(url);
            }
        }
        return canonical;
    }

    _makeAPIURL(urlObject           , accessToken                      )         {
        const help = 'See https://docs.mapbox.com/api/overview/#access-tokens-and-token-scopes';
        const apiUrlObject = parseUrl(config.API_URL);
        urlObject.protocol = apiUrlObject.protocol;
        urlObject.authority = apiUrlObject.authority;

        if (urlObject.protocol === 'http') {
            const i = urlObject.params.indexOf('secure');
            if (i >= 0) urlObject.params.splice(i, 1);
        }

        if (apiUrlObject.path !== '/') {
            urlObject.path = `${apiUrlObject.path}${urlObject.path}`;
        }

        if (!config.REQUIRE_ACCESS_TOKEN) return formatUrl(urlObject);

        accessToken = accessToken || config.ACCESS_TOKEN;
        if (!this._silenceAuthErrors) {
            if (!accessToken)
                throw new Error(`An API access token is required to use Mapbox GL. ${help}`);
            if (accessToken[0] === 's')
                throw new Error(`Use a public access token (pk.*) with Mapbox GL, not a secret access token (sk.*). ${help}`);
        }

        urlObject.params = urlObject.params.filter((d) => d.indexOf('access_token') === -1);
        urlObject.params.push(`access_token=${accessToken || ''}`);
        return formatUrl(urlObject);
    }
}

function isMapboxURL(url        )          {
    return url.indexOf('mapbox:') === 0;
}

function isMapboxHTTPURL(url        )          {
    return config.API_URL_REGEX.test(url);
}

function isMapboxHTTPCDNURL(url        )          {
    return config.API_CDN_URL_REGEX.test(url);
}

function isMapboxHTTPStyleURL(url        )          {
    return config.API_STYLE_REGEX.test(url) && !isMapboxHTTPSpriteURL(url);
}

function isMapboxHTTPTileJSONURL(url        )          {
    return config.API_TILEJSON_REGEX.test(url);
}

function isMapboxHTTPSpriteURL(url        )          {
    return config.API_SPRITE_REGEX.test(url);
}

function isMapboxHTTPFontsURL(url        )          {
    return config.API_FONTS_REGEX.test(url);
}

function hasCacheDefeatingSku(url        )          {
    return url.indexOf('sku=') > 0 && isMapboxHTTPURL(url);
}

function getAccessToken(params               )                {
    for (const param of params) {
        const match = param.match(/^access_token=(.*)$/);
        if (match) {
            return match[1];
        }
    }
    return null;
}

const urlRe = /^(\w+):\/\/([^/?]*)(\/[^?]+)?\??(.+)?/;

function parseUrl(url        )            {
    const parts = url.match(urlRe);
    if (!parts) {
        throw new Error('Unable to parse URL object');
    }
    return {
        protocol: parts[1],
        authority: parts[2],
        path: parts[3] || '/',
        params: parts[4] ? parts[4].split('&') : []
    };
}

function formatUrl(obj           )         {
    const params = obj.params.length ? `?${obj.params.join('&')}` : '';
    return `${obj.protocol}://${obj.authority}${obj.path}${params}`;
}

const telemEventKey = 'mapbox.eventData';

function parseAccessToken(accessToken         ) {
    if (!accessToken) {
        return null;
    }

    const parts = accessToken.split('.');
    if (!parts || parts.length !== 3) {
        return null;
    }

    try {
        const jsonData = JSON.parse(b64DecodeUnicode(parts[1]));
        return jsonData;
    } catch (e) {
        return null;
    }
}

                                                                                            

class TelemetryEvent {
                   
                    
                      
                             
                                
                                

    constructor(type                    ) {
        this.type = type;
        this.anonId = null;
        this.eventData = {};
        this.queue = [];
        this.pendingRequest = null;
    }

    getStorageKey(domain         )         {
        const tokenData = parseAccessToken(config.ACCESS_TOKEN);
        let u = '';
        if (tokenData && tokenData['u']) {
            u = b64EncodeUnicode(tokenData['u']);
        } else {
            u = config.ACCESS_TOKEN || '';
        }
        return domain ?
            `${telemEventKey}.${domain}:${u}` :
            `${telemEventKey}:${u}`;
    }

    fetchEventData() {
        const isLocalStorageAvailable = storageAvailable('localStorage');
        const storageKey = this.getStorageKey();
        const uuidKey = this.getStorageKey('uuid');

        if (isLocalStorageAvailable) {
            //Retrieve cached data
            try {
                const data = window$1.localStorage.getItem(storageKey);
                if (data) {
                    this.eventData = JSON.parse(data);
                }

                const uuid = window$1.localStorage.getItem(uuidKey);
                if (uuid) this.anonId = uuid;
            } catch (e) {
                warnOnce('Unable to read from LocalStorage');
            }
        }
    }

    saveEventData() {
        const isLocalStorageAvailable = storageAvailable('localStorage');
        const storageKey =  this.getStorageKey();
        const uuidKey = this.getStorageKey('uuid');
        if (isLocalStorageAvailable) {
            try {
                window$1.localStorage.setItem(uuidKey, this.anonId);
                if (Object.keys(this.eventData).length >= 1) {
                    window$1.localStorage.setItem(storageKey, JSON.stringify(this.eventData));
                }
            } catch (e) {
                warnOnce('Unable to write to LocalStorage');
            }
        }

    }

    processRequests(_         ) {}

    /*
    * If any event data should be persisted after the POST request, the callback should modify eventData`
    * to the values that should be saved. For this reason, the callback should be invoked prior to the call
    * to TelemetryEvent#saveData
    */
    postEvent(timestamp        , additionalPayload                    , callback               , customAccessToken          ) {
        if (!config.EVENTS_URL) return;
        const eventsUrlObject            = parseUrl(config.EVENTS_URL);
        eventsUrlObject.params.push(`access_token=${customAccessToken || config.ACCESS_TOKEN || ''}`);

        const payload         = {
            event: this.type,
            created: new Date(timestamp).toISOString()
        };

        const finalPayload = additionalPayload ? extend$1(payload, additionalPayload) : payload;
        const request                    = {
            url: formatUrl(eventsUrlObject),
            headers: {
                'Content-Type': 'text/plain' //Skip the pre-flight OPTIONS request
            },
            body: JSON.stringify([finalPayload])
        };

        this.pendingRequest = postData(request, (error) => {
            this.pendingRequest = null;
            callback(error);
            this.saveEventData();
            this.processRequests(customAccessToken);
        });
    }

    queueRequest(event     , customAccessToken          ) {
        this.queue.push(event);
        this.processRequests(customAccessToken);
    }
}

class PerformanceEvent extends TelemetryEvent {
    constructor() {
        super('gljs.performance');
    }

    postPerformanceEvent(customAccessToken         , performanceData                     ) {
        if (config.EVENTS_URL) {
            if (customAccessToken || config.ACCESS_TOKEN) {
                this.queueRequest({timestamp: Date.now(), performanceData}, customAccessToken);
            }
        }
    }

    processRequests(customAccessToken          ) {
        if (this.pendingRequest || this.queue.length === 0) {
            return;
        }

        const {timestamp, performanceData} = this.queue.shift();

        const additionalPayload = getLivePerformanceMetrics(performanceData);

        // Server will only process string for these entries
        for (const metadata of additionalPayload.metadata) {
            assert$1(typeof metadata.value === 'string');
        }
        for (const counter of additionalPayload.counters) {
            assert$1(typeof counter.value === 'string');
        }
        for (const attribute of additionalPayload.attributes) {
            assert$1(typeof attribute.value === 'string');
        }

        this.postEvent(timestamp, additionalPayload, () => {}, customAccessToken);
    }
}

class MapLoadEvent extends TelemetryEvent {
                                     
                     
                           

    constructor() {
        super('map.load');
        this.success = {};
        this.skuToken = '';
    }

    postMapLoadEvent(mapId        , skuToken        , customAccessToken         , callback               ) {
        this.skuToken = skuToken;
        this.errorCb = callback;

        if (config.EVENTS_URL) {
            if (customAccessToken || config.ACCESS_TOKEN) {
                this.queueRequest({id: mapId, timestamp: Date.now()}, customAccessToken);
            } else {
                this.errorCb(new Error(AUTH_ERR_MSG));
            }
        }
    }

    processRequests(customAccessToken          ) {
        if (this.pendingRequest || this.queue.length === 0) return;
        const {id, timestamp} = this.queue.shift();

        // Only one load event should fire per map
        if (id && this.success[id]) return;

        if (!this.anonId) {
            this.fetchEventData();
        }

        if (!validateUuid(this.anonId)) {
            this.anonId = uuid();
        }

        const additionalPayload = {
            sdkIdentifier: 'mapbox-gl-js',
            sdkVersion: version,
            skuId: SKU_ID,
            skuToken: this.skuToken,
            userId: this.anonId
        };

        this.postEvent(timestamp, additionalPayload, (err) => {
            if (err) {
                this.errorCb(err);
            } else {
                if (id) this.success[id] = true;
            }

        }, customAccessToken);
    }
}

class MapSessionAPI extends TelemetryEvent {
                                     
                     
                           

    constructor() {
        super('map.auth');
        this.success = {};
        this.skuToken = '';
    }

    getSession(timestamp        , token        , callback               , customAccessToken          ) {
        if (!config.API_URL || !config.SESSION_PATH) return;
        const authUrlObject            = parseUrl(config.API_URL + config.SESSION_PATH);
        authUrlObject.params.push(`sku=${token || ''}`);
        authUrlObject.params.push(`access_token=${customAccessToken || config.ACCESS_TOKEN || ''}`);

        const request                    = {
            url: formatUrl(authUrlObject),
            headers: {
                'Content-Type': 'text/plain', //Skip the pre-flight OPTIONS request
            }
        };

        this.pendingRequest = getData(request, (error) => {
            this.pendingRequest = null;
            callback(error);
            this.saveEventData();
            this.processRequests(customAccessToken);
        });
    }

    getSessionAPI(mapId        , skuToken        , customAccessToken         , callback               ) {
        this.skuToken = skuToken;
        this.errorCb = callback;

        if (config.SESSION_PATH && config.API_URL) {
            if (customAccessToken || config.ACCESS_TOKEN) {
                this.queueRequest({id: mapId, timestamp: Date.now()}, customAccessToken);
            } else {
                this.errorCb(new Error(AUTH_ERR_MSG));
            }
        }
    }

    processRequests(customAccessToken          ) {
        if (this.pendingRequest || this.queue.length === 0) return;
        const {id, timestamp} = this.queue.shift();

        // Only one load event should fire per map
        if (id && this.success[id]) return;

        this.getSession(timestamp, this.skuToken, (err) => {
            if (err) {
                this.errorCb(err);
            } else {
                if (id) this.success[id] = true;
            }
        }, customAccessToken);
    }
}

class TurnstileEvent extends TelemetryEvent {
    constructor(customAccessToken          ) {
        super('appUserTurnstile');
        this._customAccessToken = customAccessToken;
    }

    postTurnstileEvent(tileUrls               , customAccessToken          ) {
        //Enabled only when Mapbox Access Token is set and a source uses
        // mapbox tiles.
        if (config.EVENTS_URL &&
            config.ACCESS_TOKEN &&
            Array.isArray(tileUrls) &&
            tileUrls.some(url => isMapboxURL(url) || isMapboxHTTPURL(url))) {
            this.queueRequest(Date.now(), customAccessToken);
        }
    }

    processRequests(customAccessToken          ) {
        if (this.pendingRequest || this.queue.length === 0) {
            return;
        }

        if (!this.anonId || !this.eventData.lastSuccess || !this.eventData.tokenU) {
            //Retrieve cached data
            this.fetchEventData();
        }

        const tokenData = parseAccessToken(config.ACCESS_TOKEN);
        const tokenU = tokenData ? tokenData['u'] : config.ACCESS_TOKEN;
        //Reset event data cache if the access token owner changed.
        let dueForEvent = tokenU !== this.eventData.tokenU;

        if (!validateUuid(this.anonId)) {
            this.anonId = uuid();
            dueForEvent = true;
        }

        const nextUpdate = this.queue.shift();
        // Record turnstile event once per calendar day.
        if (this.eventData.lastSuccess) {
            const lastUpdate = new Date(this.eventData.lastSuccess);
            const nextDate = new Date(nextUpdate);
            const daysElapsed = (nextUpdate - this.eventData.lastSuccess) / (24 * 60 * 60 * 1000);
            dueForEvent = dueForEvent || daysElapsed >= 1 || daysElapsed < -1 || lastUpdate.getDate() !== nextDate.getDate();
        } else {
            dueForEvent = true;
        }

        if (!dueForEvent) {
            this.processRequests();
            return;
        }

        const additionalPayload = {
            sdkIdentifier: 'mapbox-gl-js',
            sdkVersion: version,
            skuId: SKU_ID,
            "enabled.telemetry": false,
            userId: this.anonId
        };

        this.postEvent(nextUpdate, additionalPayload, (err) => {
            if (!err) {
                this.eventData.lastSuccess = nextUpdate;
                this.eventData.tokenU = tokenU;
            }
        }, customAccessToken);
    }
}

const turnstileEvent_ = new TurnstileEvent();
// $FlowFixMe[method-unbinding]
const postTurnstileEvent                                                                 = turnstileEvent_.postTurnstileEvent.bind(turnstileEvent_);

const mapLoadEvent_ = new MapLoadEvent();
// $FlowFixMe[method-unbinding]
const postMapLoadEvent                                                   = mapLoadEvent_.postMapLoadEvent.bind(mapLoadEvent_);

const performanceEvent_                   = new PerformanceEvent();
// $FlowFixMe[method-unbinding]
const postPerformanceEvent                                         = performanceEvent_.postPerformanceEvent.bind(performanceEvent_);

const mapSessionAPI_ = new MapSessionAPI();
// $FlowFixMe[method-unbinding]
const getMapSessionAPI                                                   = mapSessionAPI_.getSessionAPI.bind(mapSessionAPI_);

const authenticatedMaps = new Set();
function storeAuthState(gl                       , state         ) {
    if (state) {
        authenticatedMaps.add(gl);
    } else {
        authenticatedMaps.delete(gl);
    }
}

function isMapAuthenticated(gl                       )          {
    return authenticatedMaps.has(gl);
}

function removeAuthState(gl                       ) {
    authenticatedMaps.delete(gl);
}

/***** END WARNING - REMOVAL OR MODIFICATION OF THE
PRECEDING CODE VIOLATES THE MAPBOX TERMS OF SERVICE  ******/

//      


                               
                            
                            
                             
  

                                   
                                       
                             
                  
                   
                            
                        
                       
                 
                      
                   
  

const PerformanceMarkers = {
    create: 'create',
    load: 'load',
    fullLoad: 'fullLoad'
};

const LivePerformanceUtils = {
    mark(marker                                  ) {
        window$1.performance.mark(marker);
    },
    measure(name        , begin         , end         ) {
        window$1.performance.measure(name, begin, end);
    }
};

function categorize(arr                                  , fn                                              )                                               {
    const obj = {};
    if (arr) {
        for (const item of arr) {
            const category = fn(item);
            if (obj[category] === undefined) {
                obj[category] = [];
            }
            obj[category].push(item);
        }
    }
    return obj;
}

function getCountersPerResourceType(resourceTimers                                                ) {
    const obj = {};
    if (resourceTimers) {
        for (const category in resourceTimers) {
            if (category !== 'other') {
                for (const timer of resourceTimers[category]) {
                    const min = `${category}ResolveRangeMin`;
                    const max = `${category}ResolveRangeMax`;
                    const reqCount = `${category}RequestCount`;
                    const reqCachedCount = `${category}RequestCachedCount`;

                    // Resource -TransferStart and -TransferEnd represent the wall time
                    // between the start of a request to when the data is available
                    obj[min] = Math.min(obj[min] || +Infinity, timer.startTime);
                    obj[max] = Math.max(obj[max] || -Infinity, timer.responseEnd);

                    const increment = (key        ) => {
                        if (obj[key] === undefined) {
                            obj[key] = 0;
                        }
                        ++obj[key];
                    };

                    const transferSizeSupported = timer.transferSize !== undefined;
                    if (transferSizeSupported) {
                        const resourceFetchedFromCache = (timer.transferSize === 0);
                        if (resourceFetchedFromCache) {
                            increment(reqCachedCount);
                        }
                    }
                    increment(reqCount);
                }
            }
        }
    }
    return obj;
}

function getResourceCategory(entry                           )         {
    const url = entry.name.split('?')[0];

    if (isMapboxHTTPCDNURL(url) && url.includes('mapbox-gl.js')) return 'javascript';
    if (isMapboxHTTPCDNURL(url) && url.includes('mapbox-gl.css')) return 'css';
    if (isMapboxHTTPFontsURL(url)) return 'fontRange';
    if (isMapboxHTTPSpriteURL(url)) return 'sprite';
    if (isMapboxHTTPStyleURL(url)) return 'style';
    if (isMapboxHTTPTileJSONURL(url)) return 'tilejson';

    return 'other';
}

function getStyle(resourceTimers                         )          {
    if (resourceTimers) {
        for (const timer of resourceTimers) {
            const url = timer.name.split('?')[0];
            if (isMapboxHTTPStyleURL(url)) {
                const split = url.split('/').slice(-2);
                if (split.length === 2) {
                    return `mapbox://styles/${split[0]}/${split[1]}`;
                }
            }
        }
    }
}

function getLivePerformanceMetrics(data                     )                         {
    const resourceTimers = window$1.performance.getEntriesByType('resource');
    const markerTimers = window$1.performance.getEntriesByType('mark');
    const resourcesByType = categorize(resourceTimers, getResourceCategory);
    const counters = getCountersPerResourceType(resourcesByType);
    const devicePixelRatio = window$1.devicePixelRatio;
    const connection = window$1.navigator.connection || window$1.navigator.mozConnection || window$1.navigator.webkitConnection;
    const metrics = {counters: [], metadata: [], attributes: []};

    // Please read carefully before adding or modifying the following metrics:
    // https://github.com/mapbox/gl-js-team/blob/main/docs/live_performance_metrics.md
    const addMetric = (arr                                          , name        , value                    ) => {
        if (value !== undefined && value !== null) {
            arr.push({name, value: value.toString()});
        }
    };

    for (const counter in counters) {
        addMetric(metrics.counters, counter, counters[counter]);
    }
    if (data.interactionRange[0] !== +Infinity && data.interactionRange[1] !== -Infinity) {
        addMetric(metrics.counters, "interactionRangeMin", data.interactionRange[0]);
        addMetric(metrics.counters, "interactionRangeMax", data.interactionRange[1]);
    }
    if (markerTimers) {
        for (const marker of Object.keys(PerformanceMarkers)) {
            const markerName = PerformanceMarkers[marker];
            const markerTimer = markerTimers.find((entry) => entry.name === markerName);
            if (markerTimer) {
                addMetric(metrics.counters, markerName, markerTimer.startTime);
            }
        }
    }
    addMetric(metrics.counters, "visibilityHidden", data.visibilityHidden);

    addMetric(metrics.attributes, "style", getStyle(resourceTimers));
    addMetric(metrics.attributes, "terrainEnabled", data.terrainEnabled ? "true" : "false");
    addMetric(metrics.attributes, "fogEnabled", data.fogEnabled ? "true" : "false");
    addMetric(metrics.attributes, "projection", data.projection);
    addMetric(metrics.attributes, "zoom", data.zoom);

    addMetric(metrics.metadata, "devicePixelRatio", devicePixelRatio);
    addMetric(metrics.metadata, "connectionEffectiveType", connection ? connection.effectiveType : undefined);
    addMetric(metrics.metadata, "navigatorUserAgent", window$1.navigator.userAgent);
    addMetric(metrics.metadata, "screenWidth", window$1.screen.width);
    addMetric(metrics.metadata, "screenHeight", window$1.screen.height);
    addMetric(metrics.metadata, "windowWidth", window$1.innerWidth);
    addMetric(metrics.metadata, "windowHeight", window$1.innerHeight);
    addMetric(metrics.metadata, "mapWidth", data.width / devicePixelRatio);
    addMetric(metrics.metadata, "mapHeight", data.height / devicePixelRatio);
    addMetric(metrics.metadata, "webglRenderer", data.renderer);
    addMetric(metrics.metadata, "webglVendor", data.vendor);
    addMetric(metrics.metadata, "sdkVersion", version);
    addMetric(metrics.metadata, "sdkIdentifier", "mapbox-gl-js");

    return metrics;
}

//      

const performance = window$1.performance;

performance.mark('library-evaluate');
                                                       

                                  
                     
                         
                                 
                      
                       
                       
                       
                                 
                                 
                       
                              
                          
                            
  

                                                           

let fullLoadFinished = false;
let placementTime = 0;

const PerformanceUtils = {
    mark(marker                                  ) {
        LivePerformanceUtils.mark(marker);

        if (marker === PerformanceMarkers.fullLoad) {
            fullLoadFinished = true;
        }
    },
    measure(name        , begin         , end         ) {
        LivePerformanceUtils.measure(name, begin, end);
    },
    beginMeasure(name        )                  {
        const mark = name;
        performance.mark(mark);
        return {
            mark,
            name
        };
    },
    endMeasure(m                 ) {
        performance.measure(m.name, m.mark);
    },
    recordPlacementTime(time        ) {
        // Ignore placementTimes during loading
        if (!fullLoadFinished) {
            return;
        }

        placementTime += time;
    },
    frame(timestamp        , isRenderFrame         ) {
        performance.mark('frame', {
            detail: {
                timestamp,
                isRenderFrame
            }
        });
    },
    clearMetrics() {
        placementTime = 0;
        fullLoadFinished = false;

        performance.clearMeasures('loadTime');
        performance.clearMeasures('fullLoadTime');

        for (const marker in PerformanceMarkers) {
            performance.clearMarks(PerformanceMarkers[marker]);
        }
    },

    getPerformanceMetrics()                     {
        const metrics = {};

        performance.measure('loadTime', PerformanceMarkers.create, PerformanceMarkers.load);
        performance.measure('fullLoadTime', PerformanceMarkers.create, PerformanceMarkers.fullLoad);

        const measures = performance.getEntriesByType('measure');
        for (const measure of measures) {
            metrics[measure.name] = (metrics[measure.name] || 0) + measure.duration;
        }

        metrics.placementTime = placementTime;

        return metrics;
    },

    getWorkerPerformanceMetrics()                                                                {
        const entries = performance.getEntries().map(entry => {
            const result = entry.toJSON();
            if (entry.detail) {
                Object.assign(result, {
                    detail: entry.detail
                });
            }
            return result;
        });
        return {
            scope: isWorker() ? 'Worker' : 'Window',
            timeOrigin: performance.timeOrigin,
            entries
        };
    }
};

function getPerformanceMeasurement(request                    )                          {
    const url = request ? request.url.toString() : undefined;
    return performance.getEntriesByName(url);
}

//       strict

                                                       

let linkEl;

let reducedMotionQuery                ;

let stubTime               ;

let canvas;

/**
 * @private
 */
const exported = {
    /**
     * Returns either performance.now() or a value set by setNow.
     * @returns {number} Time value in milliseconds.
     */
    now()         {
        if (stubTime !== undefined) {
            return stubTime;
        }
        return window$1.performance.now();
    },
    setNow(time        ) {
        stubTime = time;
    },

    restoreNow() {
        stubTime = undefined;
    },

    frame(fn                                       )             {
        const frame = window$1.requestAnimationFrame(fn);
        return {cancel: () => window$1.cancelAnimationFrame(frame)};
    },

    getImageData(img                   , padding          = 0)            {
        const {width, height} = img;

        if (!canvas) {
            canvas = window$1.document.createElement('canvas');
        }

        const context = canvas.getContext('2d', {willReadFrequently: true});
        if (!context) {
            throw new Error('failed to create canvas 2d context');
        }

        if (width > canvas.width || height > canvas.height) {
            canvas.width = width;
            canvas.height = height;
        }

        context.clearRect(-padding, -padding, width + 2 * padding, height + 2 * padding);
        context.drawImage(img, 0, 0, width, height);
        return context.getImageData(-padding, -padding, width + 2 * padding, height + 2 * padding);
    },

    resolveURL(path        )         {
        if (!linkEl) linkEl = window$1.document.createElement('a');
        linkEl.href = path;
        return linkEl.href;
    },

    get devicePixelRatio()         { return window$1.devicePixelRatio; },
    get prefersReducedMotion()          {
        if (!window$1.matchMedia) return false;
        // Lazily initialize media query.
        if (reducedMotionQuery == null) {
            reducedMotionQuery = window$1.matchMedia('(prefers-reduced-motion: reduce)');
        }
        return reducedMotionQuery.matches;
    },
};

//      

                                              

                                
                                                 

function _addEventListener(type        , listener          , listenerList           ) {
    const listenerExists = listenerList[type] && listenerList[type].indexOf(listener) !== -1;
    if (!listenerExists) {
        listenerList[type] = listenerList[type] || [];
        listenerList[type].push(listener);
    }
}

function _removeEventListener(type        , listener          , listenerList           ) {
    if (listenerList && listenerList[type]) {
        const index = listenerList[type].indexOf(listener);
        if (index !== -1) {
            listenerList[type].splice(index, 1);
        }
    }
}

class Event {
                  

    constructor(type        , data         = {}) {
        extend$1(this, data);
        this.type = type;
    }
}

                     
                    
 

class ErrorEvent extends Event {
                     

    constructor(error           , data         = {}) {
        super('error', extend$1({error}, data));
    }
}

/**
 * `Evented` mixes methods into other classes for event capabilities.
 *
 * Unless you are developing a plugin you will most likely use these methods through classes like `Map` or `Popup`.
 *
 * For lists of events you can listen for, see API documentation for specific classes: [`Map`](https://docs.mapbox.com/mapbox-gl-js/api/map/#map-events), [`Marker`](https://docs.mapbox.com/mapbox-gl-js/api/map/#map-events), [`Popup`](https://docs.mapbox.com/mapbox-gl-js/api/map/#map-events), and [`GeolocationControl`](https://docs.mapbox.com/mapbox-gl-js/api/map/#map-events).
 *
 * @mixin Evented
 */
class Evented {
                          
                                 
                             
                                                 

    /**
     * Adds a listener to a specified event type.
     *
     * @param {string} type The event type to add a listen for.
     * @param {Function} listener The function to be called when the event is fired.
     *   The listener function is called with the data object passed to `fire`,
     *   extended with `target` and `type` properties.
     * @returns {Object} Returns itself to allow for method chaining.
     */
    on(type          , listener          )       {
        this._listeners = this._listeners || {};
        _addEventListener(type, listener, this._listeners);

        return this;
    }

    /**
     * Removes a previously registered event listener.
     *
     * @param {string} type The event type to remove listeners for.
     * @param {Function} listener The listener function to remove.
     * @returns {Object} Returns itself to allow for method chaining.
     */
    off(type          , listener          )       {
        _removeEventListener(type, listener, this._listeners);
        _removeEventListener(type, listener, this._oneTimeListeners);

        return this;
    }

    /**
     * Adds a listener that will be called only once to a specified event type.
     *
     * The listener will be called first time the event fires after the listener is registered.
     *
     * @param {string} type The event type to listen for.
     * @param {Function} listener (Optional) The function to be called when the event is fired once.
     *   If not provided, returns a Promise that will be resolved when the event is fired once.
     * @returns {Object} Returns `this` | Promise.
     */
    once(type          , listener           )                        {
        if (!listener) {
            return new Promise(resolve => this.once(type, resolve));
        }

        this._oneTimeListeners = this._oneTimeListeners || {};
        _addEventListener(type, listener, this._oneTimeListeners);

        return this;
    }

    fire(event       , properties         )       {
        // Compatibility with (type: string, properties: Object) signature from previous versions.
        // See https://github.com/mapbox/mapbox-gl-js/issues/6522,
        //     https://github.com/mapbox/mapbox-gl-draw/issues/766
        if (typeof event === 'string') {
            event = new Event(event, properties || {});
        }

        const type = event.type;

        if (this.listens(type)) {
            (event     ).target = this;

            // make sure adding or removing listeners inside other listeners won't cause an infinite loop
            const listeners = this._listeners && this._listeners[type] ? this._listeners[type].slice() : [];

            for (const listener of listeners) {
                listener.call(this, event);
            }

            const oneTimeListeners = this._oneTimeListeners && this._oneTimeListeners[type] ? this._oneTimeListeners[type].slice() : [];
            for (const listener of oneTimeListeners) {
                _removeEventListener(type, listener, this._oneTimeListeners);
                listener.call(this, event);
            }

            const parent = this._eventedParent;
            if (parent) {
                extend$1(
                    event,
                    typeof this._eventedParentData === 'function' ? this._eventedParentData() : this._eventedParentData
                );
                parent.fire(event);
            }

        // To ensure that no error events are dropped, print them to the
        // console if they have no listeners.
        } else if (event instanceof ErrorEvent) {
            console.error(event.error);
        }

        return this;
    }

    /**
     * Returns true if this instance of Evented or any forwarded instances of Evented have a listener for the specified type.
     *
     * @param {string} type The event type.
     * @returns {boolean} Returns `true` if there is at least one registered listener for specified event type, `false` otherwise.
     * @private
     */
    listens(type        )          {
        return !!(
            (this._listeners && this._listeners[type] && this._listeners[type].length > 0) ||
            (this._oneTimeListeners && this._oneTimeListeners[type] && this._oneTimeListeners[type].length > 0) ||
            (this._eventedParent && this._eventedParent.listens(type))
        );
    }

    /**
     * Bubble all events fired by this instance of Evented to this parent instance of Evented.
     *
     * @returns {Object} `this`
     * @private
     */
    setEventedParent(parent          , data                        )       {
        this._eventedParent = parent;
        this._eventedParentData = data;

        return this;
    }
}

var spec = JSON.parse('{"$version":8,"$root":{"version":{"required":true,"type":"enum","values":[8]},"name":{"type":"string"},"metadata":{"type":"*"},"center":{"type":"array","value":"number"},"zoom":{"type":"number"},"bearing":{"type":"number","default":0,"period":360,"units":"degrees"},"pitch":{"type":"number","default":0,"units":"degrees"},"light":{"type":"light"},"terrain":{"type":"terrain"},"fog":{"type":"fog"},"sources":{"required":true,"type":"sources"},"sprite":{"type":"string"},"glyphs":{"type":"string"},"transition":{"type":"transition"},"projection":{"type":"projection"},"layers":{"required":true,"type":"array","value":"layer"}},"sources":{"*":{"type":"source"}},"source":["source_vector","source_raster","source_raster_dem","source_geojson","source_video","source_image"],"source_vector":{"type":{"required":true,"type":"enum","values":{"vector":{}}},"url":{"type":"string"},"tiles":{"type":"array","value":"string"},"bounds":{"type":"array","value":"number","length":4,"default":[-180,-85.051129,180,85.051129]},"scheme":{"type":"enum","values":{"xyz":{},"tms":{}},"default":"xyz"},"minzoom":{"type":"number","default":0},"maxzoom":{"type":"number","default":22},"attribution":{"type":"string"},"promoteId":{"type":"promoteId"},"volatile":{"type":"boolean","default":false},"*":{"type":"*"}},"source_raster":{"type":{"required":true,"type":"enum","values":{"raster":{}}},"url":{"type":"string"},"tiles":{"type":"array","value":"string"},"bounds":{"type":"array","value":"number","length":4,"default":[-180,-85.051129,180,85.051129]},"minzoom":{"type":"number","default":0},"maxzoom":{"type":"number","default":22},"tileSize":{"type":"number","default":512,"units":"pixels"},"scheme":{"type":"enum","values":{"xyz":{},"tms":{}},"default":"xyz"},"attribution":{"type":"string"},"volatile":{"type":"boolean","default":false},"*":{"type":"*"}},"source_raster_dem":{"type":{"required":true,"type":"enum","values":{"raster-dem":{}}},"url":{"type":"string"},"tiles":{"type":"array","value":"string"},"bounds":{"type":"array","value":"number","length":4,"default":[-180,-85.051129,180,85.051129]},"minzoom":{"type":"number","default":0},"maxzoom":{"type":"number","default":22},"tileSize":{"type":"number","default":512,"units":"pixels"},"attribution":{"type":"string"},"encoding":{"type":"enum","values":{"terrarium":{},"mapbox":{}},"default":"mapbox"},"volatile":{"type":"boolean","default":false},"*":{"type":"*"}},"source_geojson":{"type":{"required":true,"type":"enum","values":{"geojson":{}}},"data":{"type":"*"},"maxzoom":{"type":"number","default":18},"attribution":{"type":"string"},"buffer":{"type":"number","default":128,"maximum":512,"minimum":0},"filter":{"type":"*"},"tolerance":{"type":"number","default":0.375},"cluster":{"type":"boolean","default":false},"clusterRadius":{"type":"number","default":50,"minimum":0},"clusterMaxZoom":{"type":"number"},"clusterMinPoints":{"type":"number"},"clusterProperties":{"type":"*"},"lineMetrics":{"type":"boolean","default":false},"generateId":{"type":"boolean","default":false},"promoteId":{"type":"promoteId"}},"source_video":{"type":{"required":true,"type":"enum","values":{"video":{}}},"urls":{"required":true,"type":"array","value":"string"},"coordinates":{"required":true,"type":"array","length":4,"value":{"type":"array","length":2,"value":"number"}}},"source_image":{"type":{"required":true,"type":"enum","values":{"image":{}}},"url":{"required":true,"type":"string"},"coordinates":{"required":true,"type":"array","length":4,"value":{"type":"array","length":2,"value":"number"}}},"layer":{"id":{"type":"string","required":true},"type":{"type":"enum","values":{"fill":{},"line":{},"symbol":{},"circle":{},"heatmap":{},"fill-extrusion":{},"raster":{},"hillshade":{},"background":{},"sky":{}},"required":true},"metadata":{"type":"*"},"source":{"type":"string"},"source-layer":{"type":"string"},"minzoom":{"type":"number","minimum":0,"maximum":24},"maxzoom":{"type":"number","minimum":0,"maximum":24},"filter":{"type":"filter"},"layout":{"type":"layout"},"paint":{"type":"paint"}},"layout":["layout_fill","layout_line","layout_circle","layout_heatmap","layout_fill-extrusion","layout_symbol","layout_raster","layout_hillshade","layout_background","layout_sky"],"layout_background":{"visibility":{"type":"enum","values":{"visible":{},"none":{}},"default":"visible","property-type":"constant"}},"layout_sky":{"visibility":{"type":"enum","values":{"visible":{},"none":{}},"default":"visible","property-type":"constant"}},"layout_fill":{"fill-sort-key":{"type":"number","expression":{"interpolated":false,"parameters":["zoom","feature"]},"property-type":"data-driven"},"visibility":{"type":"enum","values":{"visible":{},"none":{}},"default":"visible","property-type":"constant"}},"layout_circle":{"circle-sort-key":{"type":"number","expression":{"interpolated":false,"parameters":["zoom","feature"]},"property-type":"data-driven"},"visibility":{"type":"enum","values":{"visible":{},"none":{}},"default":"visible","property-type":"constant"}},"layout_heatmap":{"visibility":{"type":"enum","values":{"visible":{},"none":{}},"default":"visible","property-type":"constant"}},"layout_fill-extrusion":{"visibility":{"type":"enum","values":{"visible":{},"none":{}},"default":"visible","property-type":"constant"},"fill-extrusion-edge-radius":{"type":"number","private":true,"default":0,"minimum":0,"maximum":1,"property-type":"constant"}},"layout_line":{"line-cap":{"type":"enum","values":{"butt":{},"round":{},"square":{}},"default":"butt","expression":{"interpolated":false,"parameters":["zoom","feature"]},"property-type":"data-driven"},"line-join":{"type":"enum","values":{"bevel":{},"round":{},"miter":{}},"default":"miter","expression":{"interpolated":false,"parameters":["zoom","feature"]},"property-type":"data-driven"},"line-miter-limit":{"type":"number","default":2,"requires":[{"line-join":"miter"}],"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"line-round-limit":{"type":"number","default":1.05,"requires":[{"line-join":"round"}],"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"line-sort-key":{"type":"number","expression":{"interpolated":false,"parameters":["zoom","feature"]},"property-type":"data-driven"},"visibility":{"type":"enum","values":{"visible":{},"none":{}},"default":"visible","property-type":"constant"}},"layout_symbol":{"symbol-placement":{"type":"enum","values":{"point":{},"line":{},"line-center":{}},"default":"point","expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"symbol-spacing":{"type":"number","default":250,"minimum":1,"units":"pixels","requires":[{"symbol-placement":"line"}],"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"symbol-avoid-edges":{"type":"boolean","default":false,"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"symbol-sort-key":{"type":"number","expression":{"interpolated":false,"parameters":["zoom","feature"]},"property-type":"data-driven"},"symbol-z-order":{"type":"enum","values":{"auto":{},"viewport-y":{},"source":{}},"default":"auto","expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"icon-allow-overlap":{"type":"boolean","default":false,"requires":["icon-image"],"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"icon-ignore-placement":{"type":"boolean","default":false,"requires":["icon-image"],"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"icon-optional":{"type":"boolean","default":false,"requires":["icon-image","text-field"],"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"icon-rotation-alignment":{"type":"enum","values":{"map":{},"viewport":{},"auto":{}},"default":"auto","requires":["icon-image"],"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"icon-size":{"type":"number","default":1,"minimum":0,"units":"factor of the original icon size","requires":["icon-image"],"expression":{"interpolated":true,"parameters":["zoom","feature"]},"property-type":"data-driven"},"icon-text-fit":{"type":"enum","values":{"none":{},"width":{},"height":{},"both":{}},"default":"none","requires":["icon-image","text-field"],"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"icon-text-fit-padding":{"type":"array","value":"number","length":4,"default":[0,0,0,0],"units":"pixels","requires":["icon-image","text-field",{"icon-text-fit":["both","width","height"]}],"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"icon-image":{"type":"resolvedImage","tokens":true,"expression":{"interpolated":false,"parameters":["zoom","feature"]},"property-type":"data-driven"},"icon-rotate":{"type":"number","default":0,"period":360,"units":"degrees","requires":["icon-image"],"expression":{"interpolated":true,"parameters":["zoom","feature"]},"property-type":"data-driven"},"icon-padding":{"type":"number","default":2,"minimum":0,"units":"pixels","requires":["icon-image"],"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"icon-keep-upright":{"type":"boolean","default":false,"requires":["icon-image",{"icon-rotation-alignment":"map"},{"symbol-placement":["line","line-center"]}],"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"icon-offset":{"type":"array","value":"number","length":2,"default":[0,0],"requires":["icon-image"],"expression":{"interpolated":true,"parameters":["zoom","feature"]},"property-type":"data-driven"},"icon-anchor":{"type":"enum","values":{"center":{},"left":{},"right":{},"top":{},"bottom":{},"top-left":{},"top-right":{},"bottom-left":{},"bottom-right":{}},"default":"center","requires":["icon-image"],"expression":{"interpolated":false,"parameters":["zoom","feature"]},"property-type":"data-driven"},"icon-pitch-alignment":{"type":"enum","values":{"map":{},"viewport":{},"auto":{}},"default":"auto","requires":["icon-image"],"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"text-pitch-alignment":{"type":"enum","values":{"map":{},"viewport":{},"auto":{}},"default":"auto","requires":["text-field"],"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"text-rotation-alignment":{"type":"enum","values":{"map":{},"viewport":{},"auto":{}},"default":"auto","requires":["text-field"],"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"text-field":{"type":"formatted","default":"","tokens":true,"expression":{"interpolated":false,"parameters":["zoom","feature"]},"property-type":"data-driven"},"text-font":{"type":"array","value":"string","default":["Open Sans Regular","Arial Unicode MS Regular"],"requires":["text-field"],"expression":{"interpolated":false,"parameters":["zoom","feature"]},"property-type":"data-driven"},"text-size":{"type":"number","default":16,"minimum":0,"units":"pixels","requires":["text-field"],"expression":{"interpolated":true,"parameters":["zoom","feature"]},"property-type":"data-driven"},"text-max-width":{"type":"number","default":10,"minimum":0,"units":"ems","requires":["text-field",{"symbol-placement":["point"]}],"expression":{"interpolated":true,"parameters":["zoom","feature"]},"property-type":"data-driven"},"text-line-height":{"type":"number","default":1.2,"units":"ems","requires":["text-field"],"expression":{"interpolated":true,"parameters":["zoom","feature"]},"property-type":"data-driven"},"text-letter-spacing":{"type":"number","default":0,"units":"ems","requires":["text-field"],"expression":{"interpolated":true,"parameters":["zoom","feature"]},"property-type":"data-driven"},"text-justify":{"type":"enum","values":{"auto":{},"left":{},"center":{},"right":{}},"default":"center","requires":["text-field"],"expression":{"interpolated":false,"parameters":["zoom","feature"]},"property-type":"data-driven"},"text-radial-offset":{"type":"number","units":"ems","default":0,"requires":["text-field"],"property-type":"data-driven","expression":{"interpolated":true,"parameters":["zoom","feature"]}},"text-variable-anchor":{"type":"array","value":"enum","values":{"center":{},"left":{},"right":{},"top":{},"bottom":{},"top-left":{},"top-right":{},"bottom-left":{},"bottom-right":{}},"requires":["text-field",{"symbol-placement":["point"]}],"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"text-anchor":{"type":"enum","values":{"center":{},"left":{},"right":{},"top":{},"bottom":{},"top-left":{},"top-right":{},"bottom-left":{},"bottom-right":{}},"default":"center","requires":["text-field",{"!":"text-variable-anchor"}],"expression":{"interpolated":false,"parameters":["zoom","feature"]},"property-type":"data-driven"},"text-max-angle":{"type":"number","default":45,"units":"degrees","requires":["text-field",{"symbol-placement":["line","line-center"]}],"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"text-writing-mode":{"type":"array","value":"enum","values":{"horizontal":{},"vertical":{}},"requires":["text-field"],"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"text-rotate":{"type":"number","default":0,"period":360,"units":"degrees","requires":["text-field"],"expression":{"interpolated":true,"parameters":["zoom","feature"]},"property-type":"data-driven"},"text-padding":{"type":"number","default":2,"minimum":0,"units":"pixels","requires":["text-field"],"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"text-keep-upright":{"type":"boolean","default":true,"requires":["text-field",{"text-rotation-alignment":"map"},{"symbol-placement":["line","line-center"]}],"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"text-transform":{"type":"enum","values":{"none":{},"uppercase":{},"lowercase":{}},"default":"none","requires":["text-field"],"expression":{"interpolated":false,"parameters":["zoom","feature"]},"property-type":"data-driven"},"text-offset":{"type":"array","value":"number","units":"ems","length":2,"default":[0,0],"requires":["text-field",{"!":"text-radial-offset"}],"expression":{"interpolated":true,"parameters":["zoom","feature"]},"property-type":"data-driven"},"text-allow-overlap":{"type":"boolean","default":false,"requires":["text-field"],"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"text-ignore-placement":{"type":"boolean","default":false,"requires":["text-field"],"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"text-optional":{"type":"boolean","default":false,"requires":["text-field","icon-image"],"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"visibility":{"type":"enum","values":{"visible":{},"none":{}},"default":"visible","property-type":"constant"}},"layout_raster":{"visibility":{"type":"enum","values":{"visible":{},"none":{}},"default":"visible","property-type":"constant"}},"layout_hillshade":{"visibility":{"type":"enum","values":{"visible":{},"none":{}},"default":"visible","property-type":"constant"}},"filter":{"type":"array","value":"*"},"filter_symbol":{"type":"boolean","default":false,"transition":false,"property-type":"data-driven","expression":{"interpolated":false,"parameters":["zoom","feature","pitch","distance-from-center"]}},"filter_fill":{"type":"boolean","default":false,"transition":false,"property-type":"data-driven","expression":{"interpolated":false,"parameters":["zoom","feature"]}},"filter_line":{"type":"boolean","default":false,"transition":false,"property-type":"data-driven","expression":{"interpolated":false,"parameters":["zoom","feature"]}},"filter_circle":{"type":"boolean","default":false,"transition":false,"property-type":"data-driven","expression":{"interpolated":false,"parameters":["zoom","feature"]}},"filter_fill-extrusion":{"type":"boolean","default":false,"transition":false,"property-type":"data-driven","expression":{"interpolated":false,"parameters":["zoom","feature"]}},"filter_heatmap":{"type":"boolean","default":false,"transition":false,"property-type":"data-driven","expression":{"interpolated":false,"parameters":["zoom","feature"]}},"filter_operator":{"type":"enum","values":{"==":{},"!=":{},">":{},">=":{},"<":{},"<=":{},"in":{},"!in":{},"all":{},"any":{},"none":{},"has":{},"!has":{},"within":{}}},"geometry_type":{"type":"enum","values":{"Point":{},"LineString":{},"Polygon":{}}},"function":{"expression":{"type":"expression"},"stops":{"type":"array","value":"function_stop"},"base":{"type":"number","default":1,"minimum":0},"property":{"type":"string","default":"$zoom"},"type":{"type":"enum","values":{"identity":{},"exponential":{},"interval":{},"categorical":{}},"default":"exponential"},"colorSpace":{"type":"enum","values":{"rgb":{},"lab":{},"hcl":{}},"default":"rgb"},"default":{"type":"*","required":false}},"function_stop":{"type":"array","minimum":0,"maximum":24,"value":["number","color"],"length":2},"expression":{"type":"array","value":"*","minimum":1},"fog":{"range":{"type":"array","default":[0.5,10],"minimum":-20,"maximum":20,"length":2,"value":"number","property-type":"data-constant","transition":true,"expression":{"interpolated":true,"parameters":["zoom"]}},"color":{"type":"color","property-type":"data-constant","default":"#ffffff","expression":{"interpolated":true,"parameters":["zoom"]},"transition":true},"high-color":{"type":"color","property-type":"data-constant","default":"#245cdf","expression":{"interpolated":true,"parameters":["zoom"]},"transition":true},"space-color":{"type":"color","property-type":"data-constant","default":["interpolate",["linear"],["zoom"],4,"#010b19",7,"#367ab9"],"expression":{"interpolated":true,"parameters":["zoom"]},"transition":true},"horizon-blend":{"type":"number","property-type":"data-constant","default":["interpolate",["linear"],["zoom"],4,0.2,7,0.1],"minimum":0,"maximum":1,"expression":{"interpolated":true,"parameters":["zoom"]},"transition":true},"star-intensity":{"type":"number","property-type":"data-constant","default":["interpolate",["linear"],["zoom"],5,0.35,6,0],"minimum":0,"maximum":1,"expression":{"interpolated":true,"parameters":["zoom"]},"transition":true}},"light":{"anchor":{"type":"enum","default":"viewport","values":{"map":{},"viewport":{}},"property-type":"data-constant","transition":false,"expression":{"interpolated":false,"parameters":["zoom"]}},"position":{"type":"array","default":[1.15,210,30],"length":3,"value":"number","property-type":"data-constant","transition":true,"expression":{"interpolated":true,"parameters":["zoom"]}},"color":{"type":"color","property-type":"data-constant","default":"#ffffff","expression":{"interpolated":true,"parameters":["zoom"]},"transition":true},"intensity":{"type":"number","property-type":"data-constant","default":0.5,"minimum":0,"maximum":1,"expression":{"interpolated":true,"parameters":["zoom"]},"transition":true}},"projection":{"name":{"type":"enum","values":{"albers":{},"equalEarth":{},"equirectangular":{},"lambertConformalConic":{},"mercator":{},"naturalEarth":{},"winkelTripel":{},"globe":{}},"default":"mercator","required":true},"center":{"type":"array","length":2,"value":"number","property-type":"data-constant","minimum":[-180,-90],"maximum":[180,90],"transition":false,"requires":[{"name":["albers","lambertConformalConic"]}]},"parallels":{"type":"array","length":2,"value":"number","property-type":"data-constant","minimum":[-90,-90],"maximum":[90,90],"transition":false,"requires":[{"name":["albers","lambertConformalConic"]}]}},"terrain":{"source":{"type":"string","required":true},"exaggeration":{"type":"number","property-type":"data-constant","default":1,"minimum":0,"maximum":1000,"expression":{"interpolated":true,"parameters":["zoom"]},"transition":true,"requires":["source"]}},"paint":["paint_fill","paint_line","paint_circle","paint_heatmap","paint_fill-extrusion","paint_symbol","paint_raster","paint_hillshade","paint_background","paint_sky"],"paint_fill":{"fill-antialias":{"type":"boolean","default":true,"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"fill-opacity":{"type":"number","default":1,"minimum":0,"maximum":1,"transition":true,"expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"fill-color":{"type":"color","default":"#000000","transition":true,"requires":[{"!":"fill-pattern"}],"expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"fill-outline-color":{"type":"color","transition":true,"requires":[{"!":"fill-pattern"},{"fill-antialias":true}],"expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"fill-translate":{"type":"array","value":"number","length":2,"default":[0,0],"transition":true,"units":"pixels","expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"fill-translate-anchor":{"type":"enum","values":{"map":{},"viewport":{}},"default":"map","requires":["fill-translate"],"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"fill-pattern":{"type":"resolvedImage","transition":false,"expression":{"interpolated":false,"parameters":["zoom","feature"]},"property-type":"data-driven"}},"paint_fill-extrusion":{"fill-extrusion-opacity":{"type":"number","default":1,"minimum":0,"maximum":1,"transition":true,"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"fill-extrusion-color":{"type":"color","default":"#000000","transition":true,"requires":[{"!":"fill-extrusion-pattern"}],"expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"fill-extrusion-translate":{"type":"array","value":"number","length":2,"default":[0,0],"transition":true,"units":"pixels","expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"fill-extrusion-translate-anchor":{"type":"enum","values":{"map":{},"viewport":{}},"default":"map","requires":["fill-extrusion-translate"],"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"fill-extrusion-pattern":{"type":"resolvedImage","transition":false,"expression":{"interpolated":false,"parameters":["zoom","feature"]},"property-type":"data-driven"},"fill-extrusion-height":{"type":"number","default":0,"minimum":0,"units":"meters","transition":true,"expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"fill-extrusion-base":{"type":"number","default":0,"minimum":0,"units":"meters","transition":true,"requires":["fill-extrusion-height"],"expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"fill-extrusion-vertical-gradient":{"type":"boolean","default":true,"transition":false,"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"fill-extrusion-ambient-occlusion-intensity":{"property-type":"data-constant","type":"number","private":true,"default":0,"minimum":0,"maximum":1,"expression":{"interpolated":true,"parameters":["zoom"]},"transition":true},"fill-extrusion-ambient-occlusion-radius":{"property-type":"data-constant","type":"number","private":true,"default":3,"minimum":0,"expression":{"interpolated":true,"parameters":["zoom"]},"transition":true,"requires":["fill-extrusion-edge-radius"]},"fill-extrusion-rounded-roof":{"type":"boolean","default":true,"requires":["fill-extrusion-edge-radius"],"transition":false,"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"}},"paint_line":{"line-opacity":{"type":"number","default":1,"minimum":0,"maximum":1,"transition":true,"expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"line-color":{"type":"color","default":"#000000","transition":true,"requires":[{"!":"line-pattern"}],"expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"line-translate":{"type":"array","value":"number","length":2,"default":[0,0],"transition":true,"units":"pixels","expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"line-translate-anchor":{"type":"enum","values":{"map":{},"viewport":{}},"default":"map","requires":["line-translate"],"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"line-width":{"type":"number","default":1,"minimum":0,"transition":true,"units":"pixels","expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"line-gap-width":{"type":"number","default":0,"minimum":0,"transition":true,"units":"pixels","expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"line-offset":{"type":"number","default":0,"transition":true,"units":"pixels","expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"line-blur":{"type":"number","default":0,"minimum":0,"transition":true,"units":"pixels","expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"line-dasharray":{"type":"array","value":"number","minimum":0,"transition":false,"units":"line widths","requires":[{"!":"line-pattern"}],"expression":{"interpolated":false,"parameters":["zoom","feature"]},"property-type":"data-driven"},"line-pattern":{"type":"resolvedImage","transition":false,"expression":{"interpolated":false,"parameters":["zoom","feature"]},"property-type":"data-driven"},"line-gradient":{"type":"color","transition":false,"requires":[{"!":"line-pattern"},{"source":"geojson","has":{"lineMetrics":true}}],"expression":{"interpolated":true,"parameters":["line-progress"]},"property-type":"color-ramp"},"line-trim-offset":{"type":"array","value":"number","length":2,"default":[0,0],"minimum":[0,0],"maximum":[1,1],"transition":false,"requires":[{"source":"geojson","has":{"lineMetrics":true}}],"property-type":"constant"}},"paint_circle":{"circle-radius":{"type":"number","default":5,"minimum":0,"transition":true,"units":"pixels","expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"circle-color":{"type":"color","default":"#000000","transition":true,"expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"circle-blur":{"type":"number","default":0,"transition":true,"expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"circle-opacity":{"type":"number","default":1,"minimum":0,"maximum":1,"transition":true,"expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"circle-translate":{"type":"array","value":"number","length":2,"default":[0,0],"transition":true,"units":"pixels","expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"circle-translate-anchor":{"type":"enum","values":{"map":{},"viewport":{}},"default":"map","requires":["circle-translate"],"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"circle-pitch-scale":{"type":"enum","values":{"map":{},"viewport":{}},"default":"map","expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"circle-pitch-alignment":{"type":"enum","values":{"map":{},"viewport":{}},"default":"viewport","expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"circle-stroke-width":{"type":"number","default":0,"minimum":0,"transition":true,"units":"pixels","expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"circle-stroke-color":{"type":"color","default":"#000000","transition":true,"expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"circle-stroke-opacity":{"type":"number","default":1,"minimum":0,"maximum":1,"transition":true,"expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"}},"paint_heatmap":{"heatmap-radius":{"type":"number","default":30,"minimum":1,"transition":true,"units":"pixels","expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"heatmap-weight":{"type":"number","default":1,"minimum":0,"transition":false,"expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"heatmap-intensity":{"type":"number","default":1,"minimum":0,"transition":true,"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"heatmap-color":{"type":"color","default":["interpolate",["linear"],["heatmap-density"],0,"rgba(0, 0, 255, 0)",0.1,"royalblue",0.3,"cyan",0.5,"lime",0.7,"yellow",1,"red"],"transition":false,"expression":{"interpolated":true,"parameters":["heatmap-density"]},"property-type":"color-ramp"},"heatmap-opacity":{"type":"number","default":1,"minimum":0,"maximum":1,"transition":true,"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"}},"paint_symbol":{"icon-opacity":{"type":"number","default":1,"minimum":0,"maximum":1,"transition":true,"requires":["icon-image"],"expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"icon-color":{"type":"color","default":"#000000","transition":true,"requires":["icon-image"],"expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"icon-halo-color":{"type":"color","default":"rgba(0, 0, 0, 0)","transition":true,"requires":["icon-image"],"expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"icon-halo-width":{"type":"number","default":0,"minimum":0,"transition":true,"units":"pixels","requires":["icon-image"],"expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"icon-halo-blur":{"type":"number","default":0,"minimum":0,"transition":true,"units":"pixels","requires":["icon-image"],"expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"icon-translate":{"type":"array","value":"number","length":2,"default":[0,0],"transition":true,"units":"pixels","requires":["icon-image"],"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"icon-translate-anchor":{"type":"enum","values":{"map":{},"viewport":{}},"default":"map","requires":["icon-image","icon-translate"],"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"text-opacity":{"type":"number","default":1,"minimum":0,"maximum":1,"transition":true,"requires":["text-field"],"expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"text-color":{"type":"color","default":"#000000","transition":true,"overridable":true,"requires":["text-field"],"expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"text-halo-color":{"type":"color","default":"rgba(0, 0, 0, 0)","transition":true,"requires":["text-field"],"expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"text-halo-width":{"type":"number","default":0,"minimum":0,"transition":true,"units":"pixels","requires":["text-field"],"expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"text-halo-blur":{"type":"number","default":0,"minimum":0,"transition":true,"units":"pixels","requires":["text-field"],"expression":{"interpolated":true,"parameters":["zoom","feature","feature-state"]},"property-type":"data-driven"},"text-translate":{"type":"array","value":"number","length":2,"default":[0,0],"transition":true,"units":"pixels","requires":["text-field"],"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"text-translate-anchor":{"type":"enum","values":{"map":{},"viewport":{}},"default":"map","requires":["text-field","text-translate"],"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"}},"paint_raster":{"raster-opacity":{"type":"number","default":1,"minimum":0,"maximum":1,"transition":true,"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"raster-hue-rotate":{"type":"number","default":0,"period":360,"transition":true,"units":"degrees","expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"raster-brightness-min":{"type":"number","default":0,"minimum":0,"maximum":1,"transition":true,"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"raster-brightness-max":{"type":"number","default":1,"minimum":0,"maximum":1,"transition":true,"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"raster-saturation":{"type":"number","default":0,"minimum":-1,"maximum":1,"transition":true,"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"raster-contrast":{"type":"number","default":0,"minimum":-1,"maximum":1,"transition":true,"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"raster-resampling":{"type":"enum","values":{"linear":{},"nearest":{}},"default":"linear","expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"raster-fade-duration":{"type":"number","default":300,"minimum":0,"transition":false,"units":"milliseconds","expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"}},"paint_hillshade":{"hillshade-illumination-direction":{"type":"number","default":335,"minimum":0,"maximum":359,"transition":false,"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"hillshade-illumination-anchor":{"type":"enum","values":{"map":{},"viewport":{}},"default":"viewport","expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"hillshade-exaggeration":{"type":"number","default":0.5,"minimum":0,"maximum":1,"transition":true,"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"hillshade-shadow-color":{"type":"color","default":"#000000","transition":true,"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"hillshade-highlight-color":{"type":"color","default":"#FFFFFF","transition":true,"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"hillshade-accent-color":{"type":"color","default":"#000000","transition":true,"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"}},"paint_background":{"background-color":{"type":"color","default":"#000000","transition":true,"requires":[{"!":"background-pattern"}],"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"},"background-pattern":{"type":"resolvedImage","transition":false,"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"background-opacity":{"type":"number","default":1,"minimum":0,"maximum":1,"transition":true,"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"}},"paint_sky":{"sky-type":{"type":"enum","values":{"gradient":{},"atmosphere":{}},"default":"atmosphere","expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"sky-atmosphere-sun":{"type":"array","value":"number","length":2,"units":"degrees","minimum":[0,0],"maximum":[360,180],"transition":false,"requires":[{"sky-type":"atmosphere"}],"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"sky-atmosphere-sun-intensity":{"type":"number","requires":[{"sky-type":"atmosphere"}],"default":10,"minimum":0,"maximum":100,"transition":false,"property-type":"data-constant"},"sky-gradient-center":{"type":"array","requires":[{"sky-type":"gradient"}],"value":"number","default":[0,0],"length":2,"units":"degrees","minimum":[0,0],"maximum":[360,180],"transition":false,"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"sky-gradient-radius":{"type":"number","requires":[{"sky-type":"gradient"}],"default":90,"minimum":0,"maximum":180,"transition":false,"expression":{"interpolated":false,"parameters":["zoom"]},"property-type":"data-constant"},"sky-gradient":{"type":"color","default":["interpolate",["linear"],["sky-radial-progress"],0.8,"#87ceeb",1,"white"],"transition":false,"requires":[{"sky-type":"gradient"}],"expression":{"interpolated":true,"parameters":["sky-radial-progress"]},"property-type":"color-ramp"},"sky-atmosphere-halo-color":{"type":"color","default":"white","transition":false,"requires":[{"sky-type":"atmosphere"}],"property-type":"data-constant"},"sky-atmosphere-color":{"type":"color","default":"white","transition":false,"requires":[{"sky-type":"atmosphere"}],"property-type":"data-constant"},"sky-opacity":{"type":"number","default":1,"minimum":0,"maximum":1,"transition":true,"expression":{"interpolated":true,"parameters":["zoom"]},"property-type":"data-constant"}},"transition":{"duration":{"type":"number","default":300,"minimum":0,"units":"milliseconds"},"delay":{"type":"number","default":0,"minimum":0,"units":"milliseconds"}},"property-type":{"data-driven":{"type":"property-type"},"color-ramp":{"type":"property-type"},"data-constant":{"type":"property-type"},"constant":{"type":"property-type"}},"promoteId":{"*":{"type":"string"}}}');

//

//      

function extend (output     , ...inputs            )      {
    for (const input of inputs) {
        for (const k in input) {
            output[k] = input[k];
        }
    }
    return output;
}

//      

// Turn jsonlint-lines-primitives objects into primitive objects
function unbundle(value       )        {
    if (value instanceof Number || value instanceof String || value instanceof Boolean) {
        return value.valueOf();
    } else {
        return value;
    }
}

function deepUnbundle(value       )        {
    if (Array.isArray(value)) {
        return value.map(deepUnbundle);
    } else if (value instanceof Object && !(value instanceof Number || value instanceof String || value instanceof Boolean)) {
        const unbundledValue                           = {};
        for (const key in value) {
            unbundledValue[key] = deepUnbundle(value[key]);
        }
        return unbundledValue;
    }

    return unbundle(value);
}

//      

class ParsingError extends Error {
                
                    
    constructor(key        , message        ) {
        super(message);
        this.message = message;
        this.key = key;
    }
}

//      

                                                

/**
 * Tracks `let` bindings during expression parsing.
 * @private
 */
class Scope {
                   
                                        
    constructor(parent        , bindings                              = []) {
        this.parent = parent;
        this.bindings = {};
        for (const [name, expression] of bindings) {
            this.bindings[name] = expression;
        }
    }

    concat(bindings                             )        {
        return new Scope(this, bindings);
    }

    get(name        )             {
        if (this.bindings[name]) { return this.bindings[name]; }
        if (this.parent) { return this.parent.get(name); }
        throw new Error(`${name} not found in scope.`);
    }

    has(name        )          {
        if (this.bindings[name]) return true;
        return this.parent ? this.parent.has(name) : false;
    }
}

//      

                                         
                                             
                                             
                                               
                                           
                                             
                                           
                                           
                                                 
                                                   
                                                           

                                                                            

                  
               
                 
                 
                  
                
                 
                
                                                           
                
                   
                    
                      

                         
                  
                   
              
 

                                                                                      

const NullType = {kind: 'null'};
const NumberType = {kind: 'number'};
const StringType = {kind: 'string'};
const BooleanType = {kind: 'boolean'};
const ColorType = {kind: 'color'};
const ObjectType = {kind: 'object'};
const ValueType = {kind: 'value'};
const ErrorType = {kind: 'error'};
const CollatorType = {kind: 'collator'};
const FormattedType = {kind: 'formatted'};
const ResolvedImageType = {kind: 'resolvedImage'};

function array$1(itemType      , N         )            {
    return {
        kind: 'array',
        itemType,
        N
    };
}

function toString$1(type      )         {
    if (type.kind === 'array') {
        const itemType = toString$1(type.itemType);
        return typeof type.N === 'number' ?
            `array<${itemType}, ${type.N}>` :
            type.itemType.kind === 'value' ? 'array' : `array<${itemType}>`;
    } else {
        return type.kind;
    }
}

const valueMemberTypes = [
    NullType,
    NumberType,
    StringType,
    BooleanType,
    ColorType,
    FormattedType,
    ObjectType,
    array$1(ValueType),
    ResolvedImageType
];

/**
 * Returns null if `t` is a subtype of `expected`; otherwise returns an
 * error message.
 * @private
 */
function checkSubtype(expected      , t      )          {
    if (t.kind === 'error') {
        // Error is a subtype of every type
        return null;
    } else if (expected.kind === 'array') {
        if (t.kind === 'array' &&
            ((t.N === 0 && t.itemType.kind === 'value') || !checkSubtype(expected.itemType, t.itemType)) &&
            (typeof expected.N !== 'number' || expected.N === t.N)) {
            return null;
        }
    } else if (expected.kind === t.kind) {
        return null;
    } else if (expected.kind === 'value') {
        for (const memberType of valueMemberTypes) {
            if (!checkSubtype(memberType, t)) {
                return null;
            }
        }
    }

    return `Expected ${toString$1(expected)} but found ${toString$1(t)} instead.`;
}

function isValidType(provided      , allowedTypes             )          {
    return allowedTypes.some(t => t.kind === provided.kind);
}

function isValidNativeType(provided     , allowedTypes                   )          {
    return allowedTypes.some(t => {
        if (t === 'null') {
            return provided === null;
        } else if (t === 'array') {
            return Array.isArray(provided);
        } else if (t === 'object') {
            return provided && !Array.isArray(provided) && typeof provided === 'object';
        } else {
            return t === typeof provided;
        }
    });
}

var csscolorparser = {};

var parseCSSColor_1;
// (c) Dean McNamee <dean@gmail.com>, 2012.
//
// https://github.com/deanm/css-color-parser-js
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.

// http://www.w3.org/TR/css3-color/
var kCSSColorTable = {
  "transparent": [0,0,0,0], "aliceblue": [240,248,255,1],
  "antiquewhite": [250,235,215,1], "aqua": [0,255,255,1],
  "aquamarine": [127,255,212,1], "azure": [240,255,255,1],
  "beige": [245,245,220,1], "bisque": [255,228,196,1],
  "black": [0,0,0,1], "blanchedalmond": [255,235,205,1],
  "blue": [0,0,255,1], "blueviolet": [138,43,226,1],
  "brown": [165,42,42,1], "burlywood": [222,184,135,1],
  "cadetblue": [95,158,160,1], "chartreuse": [127,255,0,1],
  "chocolate": [210,105,30,1], "coral": [255,127,80,1],
  "cornflowerblue": [100,149,237,1], "cornsilk": [255,248,220,1],
  "crimson": [220,20,60,1], "cyan": [0,255,255,1],
  "darkblue": [0,0,139,1], "darkcyan": [0,139,139,1],
  "darkgoldenrod": [184,134,11,1], "darkgray": [169,169,169,1],
  "darkgreen": [0,100,0,1], "darkgrey": [169,169,169,1],
  "darkkhaki": [189,183,107,1], "darkmagenta": [139,0,139,1],
  "darkolivegreen": [85,107,47,1], "darkorange": [255,140,0,1],
  "darkorchid": [153,50,204,1], "darkred": [139,0,0,1],
  "darksalmon": [233,150,122,1], "darkseagreen": [143,188,143,1],
  "darkslateblue": [72,61,139,1], "darkslategray": [47,79,79,1],
  "darkslategrey": [47,79,79,1], "darkturquoise": [0,206,209,1],
  "darkviolet": [148,0,211,1], "deeppink": [255,20,147,1],
  "deepskyblue": [0,191,255,1], "dimgray": [105,105,105,1],
  "dimgrey": [105,105,105,1], "dodgerblue": [30,144,255,1],
  "firebrick": [178,34,34,1], "floralwhite": [255,250,240,1],
  "forestgreen": [34,139,34,1], "fuchsia": [255,0,255,1],
  "gainsboro": [220,220,220,1], "ghostwhite": [248,248,255,1],
  "gold": [255,215,0,1], "goldenrod": [218,165,32,1],
  "gray": [128,128,128,1], "green": [0,128,0,1],
  "greenyellow": [173,255,47,1], "grey": [128,128,128,1],
  "honeydew": [240,255,240,1], "hotpink": [255,105,180,1],
  "indianred": [205,92,92,1], "indigo": [75,0,130,1],
  "ivory": [255,255,240,1], "khaki": [240,230,140,1],
  "lavender": [230,230,250,1], "lavenderblush": [255,240,245,1],
  "lawngreen": [124,252,0,1], "lemonchiffon": [255,250,205,1],
  "lightblue": [173,216,230,1], "lightcoral": [240,128,128,1],
  "lightcyan": [224,255,255,1], "lightgoldenrodyellow": [250,250,210,1],
  "lightgray": [211,211,211,1], "lightgreen": [144,238,144,1],
  "lightgrey": [211,211,211,1], "lightpink": [255,182,193,1],
  "lightsalmon": [255,160,122,1], "lightseagreen": [32,178,170,1],
  "lightskyblue": [135,206,250,1], "lightslategray": [119,136,153,1],
  "lightslategrey": [119,136,153,1], "lightsteelblue": [176,196,222,1],
  "lightyellow": [255,255,224,1], "lime": [0,255,0,1],
  "limegreen": [50,205,50,1], "linen": [250,240,230,1],
  "magenta": [255,0,255,1], "maroon": [128,0,0,1],
  "mediumaquamarine": [102,205,170,1], "mediumblue": [0,0,205,1],
  "mediumorchid": [186,85,211,1], "mediumpurple": [147,112,219,1],
  "mediumseagreen": [60,179,113,1], "mediumslateblue": [123,104,238,1],
  "mediumspringgreen": [0,250,154,1], "mediumturquoise": [72,209,204,1],
  "mediumvioletred": [199,21,133,1], "midnightblue": [25,25,112,1],
  "mintcream": [245,255,250,1], "mistyrose": [255,228,225,1],
  "moccasin": [255,228,181,1], "navajowhite": [255,222,173,1],
  "navy": [0,0,128,1], "oldlace": [253,245,230,1],
  "olive": [128,128,0,1], "olivedrab": [107,142,35,1],
  "orange": [255,165,0,1], "orangered": [255,69,0,1],
  "orchid": [218,112,214,1], "palegoldenrod": [238,232,170,1],
  "palegreen": [152,251,152,1], "paleturquoise": [175,238,238,1],
  "palevioletred": [219,112,147,1], "papayawhip": [255,239,213,1],
  "peachpuff": [255,218,185,1], "peru": [205,133,63,1],
  "pink": [255,192,203,1], "plum": [221,160,221,1],
  "powderblue": [176,224,230,1], "purple": [128,0,128,1],
  "rebeccapurple": [102,51,153,1],
  "red": [255,0,0,1], "rosybrown": [188,143,143,1],
  "royalblue": [65,105,225,1], "saddlebrown": [139,69,19,1],
  "salmon": [250,128,114,1], "sandybrown": [244,164,96,1],
  "seagreen": [46,139,87,1], "seashell": [255,245,238,1],
  "sienna": [160,82,45,1], "silver": [192,192,192,1],
  "skyblue": [135,206,235,1], "slateblue": [106,90,205,1],
  "slategray": [112,128,144,1], "slategrey": [112,128,144,1],
  "snow": [255,250,250,1], "springgreen": [0,255,127,1],
  "steelblue": [70,130,180,1], "tan": [210,180,140,1],
  "teal": [0,128,128,1], "thistle": [216,191,216,1],
  "tomato": [255,99,71,1], "turquoise": [64,224,208,1],
  "violet": [238,130,238,1], "wheat": [245,222,179,1],
  "white": [255,255,255,1], "whitesmoke": [245,245,245,1],
  "yellow": [255,255,0,1], "yellowgreen": [154,205,50,1]};

function clamp_css_byte(i) {  // Clamp to integer 0 .. 255.
  i = Math.round(i);  // Seems to be what Chrome does (vs truncation).
  return i < 0 ? 0 : i > 255 ? 255 : i;
}

function clamp_css_float(f) {  // Clamp to float 0.0 .. 1.0.
  return f < 0 ? 0 : f > 1 ? 1 : f;
}

function parse_css_int(str) {  // int or percentage.
  if (str[str.length - 1] === '%')
    return clamp_css_byte(parseFloat(str) / 100 * 255);
  return clamp_css_byte(parseInt(str));
}

function parse_css_float(str) {  // float or percentage.
  if (str[str.length - 1] === '%')
    return clamp_css_float(parseFloat(str) / 100);
  return clamp_css_float(parseFloat(str));
}

function css_hue_to_rgb(m1, m2, h) {
  if (h < 0) h += 1;
  else if (h > 1) h -= 1;

  if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
  if (h * 2 < 1) return m2;
  if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
  return m1;
}

function parseCSSColor(css_str) {
  // Remove all whitespace, not compliant, but should just be more accepting.
  var str = css_str.replace(/ /g, '').toLowerCase();

  // Color keywords (and transparent) lookup.
  if (str in kCSSColorTable) return kCSSColorTable[str].slice();  // dup.

  // #abc and #abc123 syntax.
  if (str[0] === '#') {
    if (str.length === 4) {
      var iv = parseInt(str.substr(1), 16);  // TODO(deanm): Stricter parsing.
      if (!(iv >= 0 && iv <= 0xfff)) return null;  // Covers NaN.
      return [((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8),
              (iv & 0xf0) | ((iv & 0xf0) >> 4),
              (iv & 0xf) | ((iv & 0xf) << 4),
              1];
    } else if (str.length === 7) {
      var iv = parseInt(str.substr(1), 16);  // TODO(deanm): Stricter parsing.
      if (!(iv >= 0 && iv <= 0xffffff)) return null;  // Covers NaN.
      return [(iv & 0xff0000) >> 16,
              (iv & 0xff00) >> 8,
              iv & 0xff,
              1];
    }

    return null;
  }

  var op = str.indexOf('('), ep = str.indexOf(')');
  if (op !== -1 && ep + 1 === str.length) {
    var fname = str.substr(0, op);
    var params = str.substr(op+1, ep-(op+1)).split(',');
    var alpha = 1;  // To allow case fallthrough.
    switch (fname) {
      case 'rgba':
        if (params.length !== 4) return null;
        alpha = parse_css_float(params.pop());
        // Fall through.
      case 'rgb':
        if (params.length !== 3) return null;
        return [parse_css_int(params[0]),
                parse_css_int(params[1]),
                parse_css_int(params[2]),
                alpha];
      case 'hsla':
        if (params.length !== 4) return null;
        alpha = parse_css_float(params.pop());
        // Fall through.
      case 'hsl':
        if (params.length !== 3) return null;
        var h = (((parseFloat(params[0]) % 360) + 360) % 360) / 360;  // 0 .. 1
        // NOTE(deanm): According to the CSS spec s/l should only be
        // percentages, but we don't bother and let float or percentage.
        var s = parse_css_float(params[1]);
        var l = parse_css_float(params[2]);
        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
        var m1 = l * 2 - m2;
        return [clamp_css_byte(css_hue_to_rgb(m1, m2, h+1/3) * 255),
                clamp_css_byte(css_hue_to_rgb(m1, m2, h) * 255),
                clamp_css_byte(css_hue_to_rgb(m1, m2, h-1/3) * 255),
                alpha];
      default:
        return null;
    }
  }

  return null;
}

try { parseCSSColor_1 = csscolorparser.parseCSSColor = parseCSSColor; } catch(e) { }

//      


/**
 * An RGBA color value. Create instances from color strings using the static
 * method `Color.parse`. The constructor accepts RGB channel values in the range
 * `[0, 1]`, premultiplied by A.
 *
 * @param {number} r The red channel.
 * @param {number} g The green channel.
 * @param {number} b The blue channel.
 * @param {number} a The alpha channel.
 * @private
 */
class Color {
              
              
              
              

    constructor(r        , g        , b        , a         = 1) {
        this.r = r;
        this.g = g;
        this.b = b;
        this.a = a;
    }

                        
                        
                              
                      
                       

    /**
     * Parses valid CSS color strings and returns a `Color` instance.
     * @returns A `Color` instance, or `undefined` if the input is not a valid color string.
     */
    static parse(input                        )               {
        if (!input) {
            return undefined;
        }

        if (input instanceof Color) {
            return input;
        }

        if (typeof input !== 'string') {
            return undefined;
        }

        const rgba = parseCSSColor_1(input);
        if (!rgba) {
            return undefined;
        }

        return new Color(
            rgba[0] / 255 * rgba[3],
            rgba[1] / 255 * rgba[3],
            rgba[2] / 255 * rgba[3],
            rgba[3]
        );
    }

    /**
     * Returns an RGBA string representing the color value.
     *
     * @returns An RGBA string.
     * @example
     * var purple = new Color.parse('purple');
     * purple.toString; // = "rgba(128,0,128,1)"
     * var translucentGreen = new Color.parse('rgba(26, 207, 26, .73)');
     * translucentGreen.toString(); // = "rgba(26,207,26,0.73)"
     */
    toString()         {
        const [r, g, b, a] = this.toArray();
        return `rgba(${Math.round(r)},${Math.round(g)},${Math.round(b)},${a})`;
    }

    /**
     * Returns an RGBA array of values representing the color, unpremultiplied by A.
     *
     * @returns An array of RGBA color values in the range [0, 255].
     */
    toArray()                                   {
        const {r, g, b, a} = this;
        return a === 0 ? [0, 0, 0, 0] : [
            r * 255 / a,
            g * 255 / a,
            b * 255 / a,
            a
        ];
    }

    /**
     * Returns a RGBA array of float values representing the color, unpremultiplied by A.
     *
     * @returns An array of RGBA color values in the range [0, 1].
     */
    toArray01()                                   {
        const {r, g, b, a} = this;
        return a === 0 ? [0, 0, 0, 0] : [
            r / a,
            g / a,
            b / a,
            a
        ];
    }

    /**
     * Returns an RGBA array of values representing the color, premultiplied by A.
     *
     * @returns An array of RGBA color values in the range [0, 1].
     */
    toArray01PremultipliedAlpha()                                   {
        const {r, g, b, a} = this;
        return [
            r,
            g,
            b,
            a
        ];
    }
}

Color.black = new Color(0, 0, 0, 1);
Color.white = new Color(1, 1, 1, 1);
Color.transparent = new Color(0, 0, 0, 0);
Color.red = new Color(1, 0, 0, 1);
Color.blue = new Color(0, 0, 1, 1);

//      

// Flow type declarations for Intl cribbed from
// https://github.com/facebook/flow/issues/1270

                   
                                  
  

                             
                 
                                    
                                 
                     

            
                                    
                                 
                     

                                           

                           
 

                        
                                          
                              
                                                         
                                
                      
                                           
 

class Collator {
                          
                                                        
                            

    constructor(caseSensitive         , diacriticSensitive         , locale               ) {
        if (caseSensitive)
            this.sensitivity = diacriticSensitive ? 'variant' : 'case';
        else
            this.sensitivity = diacriticSensitive ? 'accent' : 'base';

        this.locale = locale;
        this.collator = new Intl.Collator(this.locale ? this.locale : [],
            {sensitivity: this.sensitivity, usage: 'search'});
    }

    compare(lhs        , rhs        )         {
        return this.collator.compare(lhs, rhs);
    }

    resolvedLocale()         {
        // We create a Collator without "usage: search" because we don't want
        // the search options encoded in our result (e.g. "en-u-co-search")
        return new Intl.Collator(this.locale ? this.locale : [])
            .resolvedOptions().locale;
    }
}

//      
                                             
                                                            

class FormattedSection {
                 
                                
                         
                             
                            

    constructor(text        , image                      , scale               , fontStack               , textColor              ) {
        // combine characters so that diacritic marks are not separate code points
        this.text = text.normalize ? text.normalize() : text;
        this.image = image;
        this.scale = scale;
        this.fontStack = fontStack;
        this.textColor = textColor;
    }
}

class Formatted {
                                      

    constructor(sections                         ) {
        this.sections = sections;
    }

    static fromString(unformatted        )            {
        return new Formatted([new FormattedSection(unformatted, null, null, null, null)]);
    }

    isEmpty()          {
        if (this.sections.length === 0) return true;
        return !this.sections.some(section => section.text.length !== 0 ||
                                             (section.image && section.image.name.length !== 0));
    }

    static factory(text                    )            {
        if (text instanceof Formatted) {
            return text;
        } else {
            return Formatted.fromString(text);
        }
    }

    toString()         {
        if (this.sections.length === 0) return '';
        return this.sections.map(section => section.text).join('');
    }

    serialize()               {
        const serialized               = ["format"];
        for (const section of this.sections) {
            if (section.image) {
                serialized.push(["image", section.image.name]);
                continue;
            }
            serialized.push(section.text);
            const options                           = {};
            if (section.fontStack) {
                options["text-font"] = ["literal", section.fontStack.split(',')];
            }
            if (section.scale) {
                options["font-scale"] = section.scale;
            }
            if (section.textColor) {
                options["text-color"] = (["rgba"]              ).concat(section.textColor.toArray());
            }
            serialized.push(options);
        }
        return serialized;
    }
}

//      

                                    
                 
                      
  

class ResolvedImage {
                 
                       

    constructor(options                      ) {
        this.name = options.name;
        this.available = options.available;
    }

    toString()         {
        return this.name;
    }

    static fromString(name        )                       {
        if (!name) return null; // treat empty values as no image
        return new ResolvedImage({name, available: false});
    }

    serialize()                {
        return ["image", this.name];
    }
}

//      


                                     

function validateRGBA(r       , g       , b       , a        )                {
    if (!(
        typeof r === 'number' && r >= 0 && r <= 255 &&
        typeof g === 'number' && g >= 0 && g <= 255 &&
        typeof b === 'number' && b >= 0 && b <= 255
    )) {
        const value = typeof a === 'number' ? [r, g, b, a] : [r, g, b];
        return `Invalid rgba value [${value.join(', ')}]: 'r', 'g', and 'b' must be between 0 and 255.`;
    }

    if (!(
        typeof a === 'undefined' || (typeof a === 'number' && a >= 0 && a <= 1)
    )) {
        return `Invalid rgba value [${[r, g, b, a].join(', ')}]: 'a' must be between 0 and 1.`;
    }

    return null;
}

                                                                                                                                                  

function isValue(mixed       )          {
    if (mixed === null) {
        return true;
    } else if (typeof mixed === 'string') {
        return true;
    } else if (typeof mixed === 'boolean') {
        return true;
    } else if (typeof mixed === 'number') {
        return true;
    } else if (mixed instanceof Color) {
        return true;
    } else if (mixed instanceof Collator) {
        return true;
    } else if (mixed instanceof Formatted) {
        return true;
    } else if (mixed instanceof ResolvedImage) {
        return true;
    } else if (Array.isArray(mixed)) {
        for (const item of mixed) {
            if (!isValue(item)) {
                return false;
            }
        }
        return true;
    } else if (typeof mixed === 'object') {
        for (const key in mixed) {
            if (!isValue(mixed[key])) {
                return false;
            }
        }
        return true;
    } else {
        return false;
    }
}

function typeOf(value       )       {
    if (value === null) {
        return NullType;
    } else if (typeof value === 'string') {
        return StringType;
    } else if (typeof value === 'boolean') {
        return BooleanType;
    } else if (typeof value === 'number') {
        return NumberType;
    } else if (value instanceof Color) {
        return ColorType;
    } else if (value instanceof Collator) {
        return CollatorType;
    } else if (value instanceof Formatted) {
        return FormattedType;
    } else if (value instanceof ResolvedImage) {
        return ResolvedImageType;
    } else if (Array.isArray(value)) {
        const length = value.length;
        let itemType                         ;

        for (const item of value) {
            const t = typeOf(item);
            if (!itemType) {
                itemType = t;
            } else if (itemType === t) {
                continue;
            } else {
                itemType = ValueType;
                break;
            }
        }

        return array$1(itemType || ValueType, length);
    } else {
        assert$1(typeof value === 'object');
        return ObjectType;
    }
}

function toString(value       )         {
    const type = typeof value;
    if (value === null) {
        return '';
    } else if (type === 'string' || type === 'number' || type === 'boolean') {
        return String(value);
    } else if (value instanceof Color || value instanceof Formatted || value instanceof ResolvedImage) {
        return value.toString();
    } else {
        return JSON.stringify(value);
    }
}

//      


                                      
                                         
                                                                       
                                                        

class Literal                       {
               
                 

    constructor(type      , value       ) {
        this.type = type;
        this.value = value;
    }

    static parse(args                       , context                )                 {
        if (args.length !== 2)
            return context.error(`'literal' expression requires exactly one argument, but found ${args.length - 1} instead.`);

        if (!isValue(args[1]))
            return context.error(`invalid value`);

        const value = (args[1]     );
        let type = typeOf(value);

        // special case: infer the item type if possible for zero-length arrays
        const expected = context.expectedType;
        if (
            type.kind === 'array' &&
            type.N === 0 &&
            expected &&
            expected.kind === 'array' &&
            (typeof expected.N !== 'number' || expected.N === 0)
        ) {
            type = expected;
        }

        return new Literal(type, value);
    }

    evaluate()        {
        return this.value;
    }

    eachChild() {}

    outputDefined()          {
        return true;
    }

    serialize()                       {
        if (this.type.kind === 'array' || this.type.kind === 'object') {
            return ["literal", this.value];
        } else if (this.value instanceof Color) {
            // Constant-folding can generate Literal expressions that you
            // couldn't actually generate with a "literal" expression,
            // so we have to implement an equivalent serialization here
            return ["rgba"].concat(this.value.toArray());
        } else if (this.value instanceof Formatted) {
            // Same as Color
            return this.value.serialize();
        } else {
            assert$1(this.value === null ||
                typeof this.value === 'string' ||
                typeof this.value === 'number' ||
                typeof this.value === 'boolean');
            return (this.value     );
        }
    }
}

//      

class RuntimeError {
                 
                    

    constructor(message        ) {
        this.name = 'ExpressionEvaluationError';
        this.message = message;
    }

    toJSON()         {
        return this.message;
    }
}

//      


                                                                       
                                                        
                                                              
                                      

const types$1 = {
    string: StringType,
    number: NumberType,
    boolean: BooleanType,
    object: ObjectType
};

class Assertion                       {
               
                            

    constructor(type      , args                   ) {
        this.type = type;
        this.args = args;
    }

    static parse(args                       , context                )              {
        if (args.length < 2)
            return context.error(`Expected at least one argument.`);

        let i = 1;
        let type;

        const name         = (args[0]     );
        if (name === 'array') {
            let itemType;
            if (args.length > 2) {
                const type = args[1];
                if (typeof type !== 'string' || !(type in types$1) || type === 'object')
                    return context.error('The item type argument of "array" must be one of string, number, boolean', 1);
                itemType = types$1[type];
                i++;
            } else {
                itemType = ValueType;
            }

            let N         ;
            if (args.length > 3) {
                if (args[2] !== null &&
                    (typeof args[2] !== 'number' ||
                        args[2] < 0 ||
                        args[2] !== Math.floor(args[2]))
                ) {
                    return context.error('The length argument to "array" must be a positive integer literal', 2);
                }
                N = ((args[2]     )        );
                i++;
            }

            type = array$1(itemType, N);
        } else {
            assert$1(types$1[name], name);
            type = types$1[name];
        }

        const parsed = [];
        for (; i < args.length; i++) {
            const input = context.parse(args[i], i, ValueType);
            if (!input) return null;
            parsed.push(input);
        }

        return new Assertion(type, parsed);
    }

    evaluate(ctx                   )             {
        for (let i = 0; i < this.args.length; i++) {
            const value = this.args[i].evaluate(ctx);
            const error = checkSubtype(this.type, typeOf(value));
            if (!error) {
                return value;
            } else if (i === this.args.length - 1) {
                throw new RuntimeError(`Expected value to be of type ${toString$1(this.type)}, but found ${toString$1(typeOf(value))} instead.`);
            }
        }

        assert$1(false);
        return null;
    }

    eachChild(fn                         ) {
        this.args.forEach(fn);
    }

    outputDefined()          {
        return this.args.every(arg => arg.outputDefined());
    }

    serialize()                       {
        const type = this.type;
        const serialized = [type.kind];
        if (type.kind === 'array') {
            const itemType = type.itemType;
            if (itemType.kind === 'string' ||
                itemType.kind === 'number' ||
                itemType.kind === 'boolean') {
                serialized.push(itemType.kind);
                const N = type.N;
                if (typeof N === 'number' || this.args.length > 1) {
                    serialized.push(N);
                }
            }
        }
        return serialized.concat(this.args.map(arg => arg.serialize()));
    }
}

//      


                                                                       
                                                              
                                                        
                                      

                                          
                                                            
                                                        
                        
                             
                            
                                 
 

class FormatExpression                       {
               
                                                

    constructor(sections                                   ) {
        this.type = FormattedType;
        this.sections = sections;
    }

    static parse(args                       , context                )              {
        if (args.length < 2) {
            return context.error(`Expected at least one argument.`);
        }

        const firstArg = args[1];
        if (!Array.isArray(firstArg) && typeof firstArg === 'object')  {
            return context.error(`First argument must be an image or text section.`);
        }

        const sections                                    = [];
        let nextTokenMayBeObject = false;
        for (let i = 1; i <= args.length - 1; ++i) {
            const arg = (args[i]     );

            if (nextTokenMayBeObject && typeof arg === "object" && !Array.isArray(arg)) {
                nextTokenMayBeObject = false;

                let scale = null;
                if (arg['font-scale']) {
                    scale = context.parse(arg['font-scale'], 1, NumberType);
                    if (!scale) return null;
                }

                let font = null;
                if (arg['text-font']) {
                    font = context.parse(arg['text-font'], 1, array$1(StringType));
                    if (!font) return null;
                }

                let textColor = null;
                if (arg['text-color']) {
                    textColor = context.parse(arg['text-color'], 1, ColorType);
                    if (!textColor) return null;
                }

                const lastExpression = sections[sections.length - 1];
                lastExpression.scale = scale;
                lastExpression.font = font;
                lastExpression.textColor = textColor;
            } else {
                const content = context.parse(args[i], 1, ValueType);
                if (!content) return null;

                const kind = content.type.kind;
                if (kind !== 'string' && kind !== 'value' && kind !== 'null' && kind !== 'resolvedImage')
                    return context.error(`Formatted text type must be 'string', 'value', 'image' or 'null'.`);

                nextTokenMayBeObject = true;
                sections.push({content, scale: null, font: null, textColor: null});
            }
        }

        return new FormatExpression(sections);
    }

    evaluate(ctx                   )            {
        const evaluateSection = (section                            ) => {
            const evaluatedContent = section.content.evaluate(ctx);
            if (typeOf(evaluatedContent) === ResolvedImageType) {
                return new FormattedSection('', evaluatedContent, null, null, null);
            }

            return new FormattedSection(
                    toString(evaluatedContent),
                    null,
                    section.scale ? section.scale.evaluate(ctx) : null,
                    section.font ? section.font.evaluate(ctx).join(',') : null,
                    section.textColor ? section.textColor.evaluate(ctx) : null
            );
        };

        return new Formatted(this.sections.map(evaluateSection));
    }

    eachChild(fn                         ) {
        for (const section of this.sections) {
            fn(section.content);
            if (section.scale) {
                fn(section.scale);
            }
            if (section.font) {
                fn(section.font);
            }
            if (section.textColor) {
                fn(section.textColor);
            }
        }
    }

    outputDefined()          {
        // Technically the combinatoric set of all children
        // Usually, this.text will be undefined anyway
        return false;
    }

    serialize()                       {
        const serialized = ["format"];
        for (const section of this.sections) {
            serialized.push(section.content.serialize());
            const options = {};
            if (section.scale) {
                options['font-scale'] = section.scale.serialize();
            }
            if (section.font) {
                options['text-font'] = section.font.serialize();
            }
            if (section.textColor) {
                options['text-color'] = section.textColor.serialize();
            }
            serialized.push(options);
        }
        return serialized;
    }
}

//      


                                                                       
                                                              
                                                        
                                      

class ImageExpression                       {
               
                      

    constructor(input            ) {
        this.type = ResolvedImageType;
        this.input = input;
    }

    static parse(args                       , context                )              {
        if (args.length !== 2) {
            return context.error(`Expected two arguments.`);
        }

        const name = context.parse(args[1], 1, StringType);
        if (!name) return context.error(`No image name provided.`);

        return new ImageExpression(name);
    }

    evaluate(ctx                   )                       {
        const evaluatedImageName = this.input.evaluate(ctx);

        const value = ResolvedImage.fromString(evaluatedImageName);
        if (value && ctx.availableImages) value.available = ctx.availableImages.indexOf(evaluatedImageName) > -1;

        return value;
    }

    eachChild(fn                         ) {
        fn(this.input);
    }

    outputDefined()          {
        // The output of image is determined by the list of available images in the evaluation context
        return false;
    }

    serialize()                       {
        return ["image", this.input.serialize()];
    }
}

//      


                                                                       
                                                        
                                                              
                                      

const types = {
    'to-boolean': BooleanType,
    'to-color': ColorType,
    'to-number': NumberType,
    'to-string': StringType
};

/**
 * Special form for error-coalescing coercion expressions "to-number",
 * "to-color".  Since these coercions can fail at runtime, they accept multiple
 * arguments, only evaluating one at a time until one succeeds.
 *
 * @private
 */
class Coercion                       {
               
                            

    constructor(type      , args                   ) {
        this.type = type;
        this.args = args;
    }

    static parse(args                       , context                )              {
        if (args.length < 2)
            return context.error(`Expected at least one argument.`);

        const name         = (args[0]     );
        assert$1(types[name], name);

        if ((name === 'to-boolean' || name === 'to-string') && args.length !== 2)
            return context.error(`Expected one argument.`);

        const type = types[name];

        const parsed = [];
        for (let i = 1; i < args.length; i++) {
            const input = context.parse(args[i], i, ValueType);
            if (!input) return null;
            parsed.push(input);
        }

        return new Coercion(type, parsed);
    }

    evaluate(ctx                   )                                                                       {
        if (this.type.kind === 'boolean') {
            return Boolean(this.args[0].evaluate(ctx));
        } else if (this.type.kind === 'color') {
            let input;
            let error;
            for (const arg of this.args) {
                input = arg.evaluate(ctx);
                error = null;
                if (input instanceof Color) {
                    return input;
                } else if (typeof input === 'string') {
                    const c = ctx.parseColor(input);
                    if (c) return c;
                } else if (Array.isArray(input)) {
                    if (input.length < 3 || input.length > 4) {
                        error = `Invalid rbga value ${JSON.stringify(input)}: expected an array containing either three or four numeric values.`;
                    } else {
                        error = validateRGBA(input[0], input[1], input[2], input[3]);
                    }
                    if (!error) {
                        return new Color((input[0]     ) / 255, (input[1]     ) / 255, (input[2]     ) / 255, (input[3]     ));
                    }
                }
            }
            throw new RuntimeError(error || `Could not parse color from value '${typeof input === 'string' ? input : String(JSON.stringify(input))}'`);
        } else if (this.type.kind === 'number') {
            let value = null;
            for (const arg of this.args) {
                value = arg.evaluate(ctx);
                if (value === null) return 0;
                const num = Number(value);
                if (isNaN(num)) continue;
                return num;
            }
            throw new RuntimeError(`Could not convert ${JSON.stringify(value)} to number.`);
        } else if (this.type.kind === 'formatted') {
            // There is no explicit 'to-formatted' but this coercion can be implicitly
            // created by properties that expect the 'formatted' type.
            return Formatted.fromString(toString(this.args[0].evaluate(ctx)));
        } else if (this.type.kind === 'resolvedImage') {
            return ResolvedImage.fromString(toString(this.args[0].evaluate(ctx)));
        } else {
            return toString(this.args[0].evaluate(ctx));
        }
    }

    eachChild(fn                         ) {
        this.args.forEach(fn);
    }

    outputDefined()          {
        return this.args.every(arg => arg.outputDefined());
    }

    serialize()                       {
        if (this.type.kind === 'formatted') {
            return new FormatExpression([{content: this.args[0], scale: null, font: null, textColor: null}]).serialize();
        }

        if (this.type.kind === 'resolvedImage') {
            return new ImageExpression(this.args[0]).serialize();
        }

        const serialized = [`to-${this.type.kind}`];
        this.eachChild(child => { serialized.push(child.serialize()); });
        return serialized;
    }
}

//      


                                                
                                                           
                                                                        
                                                             
                                                                    

const geometryTypes = ['Unknown', 'Point', 'LineString', 'Polygon'];

class EvaluationContext {
                              
                      
                                
                                        
                                    
                                      
                             
                                              

                                            

    constructor() {
        this.globals = (null     );
        this.feature = null;
        this.featureState = null;
        this.formattedSection = null;
        this._parseColorCache = {};
        this.availableImages = null;
        this.canonical = null;
        this.featureTileCoord = null;
        this.featureDistanceData = null;
    }

    id()                {
        return this.feature && this.feature.id !== undefined ? this.feature.id : null;
    }

    geometryType()                {
        return this.feature ? typeof this.feature.type === 'number' ? geometryTypes[this.feature.type] : this.feature.type : null;
    }

    geometry()                       {
        return this.feature && 'geometry' in this.feature ? this.feature.geometry : null;
    }

    canonicalID()                         {
        return this.canonical;
    }

    properties()                  {
        return (this.feature && this.feature.properties) || {};
    }

    distanceFromCenter()         {
        if (this.featureTileCoord && this.featureDistanceData) {

            const c = this.featureDistanceData.center;
            const scale = this.featureDistanceData.scale;
            const {x, y} = this.featureTileCoord;

            // Calculate the distance vector `d` (left handed)
            const dX = x * scale - c[0];
            const dY = y * scale - c[1];

            // The bearing vector `b` (left handed)
            const bX = this.featureDistanceData.bearing[0];
            const bY = this.featureDistanceData.bearing[1];

            // Distance is calculated as `dot(d, v)`
            const dist = (bX * dX + bY * dY);
            return dist;
        }

        return 0;
    }

    parseColor(input        )         {
        let cached = this._parseColorCache[input];
        if (!cached) {
            cached = this._parseColorCache[input] = Color.parse(input);
        }
        return cached;
    }
}

//      


                                                                    
                                     
                                       

                                       
                                       
                                                                
                                               
                                                            

class CompoundExpression                       {
                 
               
                        
                            

                                                   

    constructor(name        , type      , evaluate          , args                   ) {
        this.name = name;
        this.type = type;
        this._evaluate = evaluate;
        this.args = args;
    }

    evaluate(ctx                   )        {
        return this._evaluate(ctx, this.args);
    }

    eachChild(fn                         ) {
        this.args.forEach(fn);
    }

    outputDefined()          {
        return false;
    }

    serialize()               {
        return [this.name].concat(this.args.map(arg => arg.serialize()));
    }

    static parse(args                       , context                )              {
        const op         = (args[0]     );
        const definition = CompoundExpression.definitions[op];
        if (!definition) {
            return context.error(`Unknown expression "${op}". If you wanted a literal array, use ["literal", [...]].`, 0);
        }

        // Now check argument types against each signature
        const type = Array.isArray(definition) ?
            definition[0] : definition.type;

        const availableOverloads = Array.isArray(definition) ?
            [[definition[1], definition[2]]] :
            definition.overloads;

        const overloads = availableOverloads.filter(([signature]) => (
            !Array.isArray(signature) || // varags
            signature.length === args.length - 1 // correct param count
        ));

        let signatureContext                 = (null     );

        for (const [params, evaluate] of overloads) {
            // Use a fresh context for each attempted signature so that, if
            // we eventually succeed, we haven't polluted `context.errors`.
            signatureContext = new ParsingContext$1(context.registry, context.path, null, context.scope);

            // First parse all the args, potentially coercing to the
            // types expected by this overload.
            const parsedArgs                    = [];
            let argParseFailed = false;
            for (let i = 1; i < args.length; i++) {
                const arg = args[i];
                const expectedType = Array.isArray(params) ?
                    params[i - 1] :
                    params.type;

                const parsed = signatureContext.parse(arg, 1 + parsedArgs.length, expectedType);
                if (!parsed) {
                    argParseFailed = true;
                    break;
                }
                parsedArgs.push(parsed);
            }
            if (argParseFailed) {
                // Couldn't coerce args of this overload to expected type, move
                // on to next one.
                continue;
            }

            if (Array.isArray(params)) {
                if (params.length !== parsedArgs.length) {
                    signatureContext.error(`Expected ${params.length} arguments, but found ${parsedArgs.length} instead.`);
                    continue;
                }
            }

            for (let i = 0; i < parsedArgs.length; i++) {
                const expected = Array.isArray(params) ? params[i] : params.type;
                const arg = parsedArgs[i];
                signatureContext.concat(i + 1).checkSubtype(expected, arg.type);
            }

            if (signatureContext.errors.length === 0) {
                return new CompoundExpression(op, type, evaluate, parsedArgs);
            }
        }

        assert$1(!signatureContext || signatureContext.errors.length > 0);

        if (overloads.length === 1) {
            context.errors.push(...signatureContext.errors);
        } else {
            const expected = overloads.length ? overloads : availableOverloads;
            const signatures = expected
                .map(([params]) => stringifySignature(params))
                .join(' | ');

            const actualTypes = [];
            // For error message, re-parse arguments without trying to
            // apply any coercions
            for (let i = 1; i < args.length; i++) {
                const parsed = context.parse(args[i], 1 + actualTypes.length);
                if (!parsed) return null;
                actualTypes.push(toString$1(parsed.type));
            }
            context.error(`Expected arguments of type ${signatures}, but found (${actualTypes.join(', ')}) instead.`);
        }

        return null;
    }

    static register(
        registry                    ,
        definitions                            
    ) {
        assert$1(!CompoundExpression.definitions);
        CompoundExpression.definitions = definitions;
        for (const name in definitions) {
            // $FlowFixMe[method-unbinding]
            registry[name] = CompoundExpression;
        }
    }
}

function stringifySignature(signature           )         {
    if (Array.isArray(signature)) {
        return `(${signature.map(toString$1).join(', ')})`;
    } else {
        return `(${toString$1(signature.type)}...)`;
    }
}

//      


                                                                       
                                                              
                                                        
                                      

class CollatorExpression                       {
               
                              
                                   
                              

    constructor(caseSensitive            , diacriticSensitive            , locale                   ) {
        this.type = CollatorType;
        this.locale = locale;
        this.caseSensitive = caseSensitive;
        this.diacriticSensitive = diacriticSensitive;
    }

    static parse(args                       , context                )              {
        if (args.length !== 2)
            return context.error(`Expected one argument.`);

        const options = (args[1]     );
        if (typeof options !== "object" || Array.isArray(options))
            return context.error(`Collator options argument must be an object.`);

        const caseSensitive = context.parse(
            options['case-sensitive'] === undefined ? false : options['case-sensitive'], 1, BooleanType);
        if (!caseSensitive) return null;

        const diacriticSensitive = context.parse(
            options['diacritic-sensitive'] === undefined ? false : options['diacritic-sensitive'], 1, BooleanType);
        if (!diacriticSensitive) return null;

        let locale = null;
        if (options['locale']) {
            locale = context.parse(options['locale'], 1, StringType);
            if (!locale) return null;
        }

        return new CollatorExpression(caseSensitive, diacriticSensitive, locale);
    }

    evaluate(ctx                   )           {
        return new Collator(this.caseSensitive.evaluate(ctx), this.diacriticSensitive.evaluate(ctx), this.locale ? this.locale.evaluate(ctx) : null);
    }

    eachChild(fn                         ) {
        fn(this.caseSensitive);
        fn(this.diacriticSensitive);
        if (this.locale) {
            fn(this.locale);
        }
    }

    outputDefined()          {
        // Technically the set of possible outputs is the combinatoric set of Collators produced
        // by all possible outputs of locale/caseSensitive/diacriticSensitive
        // But for the primary use of Collators in comparison operators, we ignore the Collator's
        // possible outputs anyway, so we can get away with leaving this false for now.
        return false;
    }

    serialize()                       {
        const options = {};
        options['case-sensitive'] = this.caseSensitive.serialize();
        options['diacritic-sensitive'] = this.diacriticSensitive.serialize();
        if (this.locale) {
            options['locale'] = this.locale.serialize();
        }
        return ["collator", options];
    }
}

//      

                                                                       
                                                        
                                                              
                                                
                                                                                                         
                                                                

                                                             

// minX, minY, maxX, maxY
                                             
const EXTENT$1 = 8192;

function updateBBox(bbox      , coord                 ) {
    bbox[0] = Math.min(bbox[0], coord[0]);
    bbox[1] = Math.min(bbox[1], coord[1]);
    bbox[2] = Math.max(bbox[2], coord[0]);
    bbox[3] = Math.max(bbox[3], coord[1]);
}

function mercatorXfromLng$1(lng        ) {
    return (180 + lng) / 360;
}

function mercatorYfromLat$1(lat        ) {
    return (180 - (180 / Math.PI * Math.log(Math.tan(Math.PI / 4 + lat * Math.PI / 360)))) / 360;
}

function boxWithinBox(bbox1      , bbox2      ) {
    if (bbox1[0] <= bbox2[0]) return false;
    if (bbox1[2] >= bbox2[2]) return false;
    if (bbox1[1] <= bbox2[1]) return false;
    if (bbox1[3] >= bbox2[3]) return false;
    return true;
}

function getTileCoordinates(p                 , canonical                 ) {
    const x = mercatorXfromLng$1(p[0]);
    const y = mercatorYfromLat$1(p[1]);
    const tilesAtZoom = Math.pow(2, canonical.z);
    return [Math.round(x * tilesAtZoom * EXTENT$1), Math.round(y * tilesAtZoom * EXTENT$1)];
}

function onBoundary(p                 , p1                 , p2                 ) {
    const x1 = p[0] - p1[0];
    const y1 = p[1] - p1[1];
    const x2 = p[0] - p2[0];
    const y2 = p[1] - p2[1];
    return (x1 * y2 - x2 * y1 === 0) && (x1 * x2 <= 0) && (y1 * y2 <= 0);
}

function rayIntersect(p                 , p1                 , p2                 ) {
    return ((p1[1] > p[1]) !== (p2[1] > p[1])) && (p[0] < (p2[0] - p1[0]) * (p[1] - p1[1]) / (p2[1] - p1[1]) + p1[0]);
}

// ray casting algorithm for detecting if point is in polygon
function pointWithinPolygon(point                 , rings                               ) {
    let inside = false;
    for (let i = 0, len = rings.length; i < len; i++) {
        const ring = rings[i];
        for (let j = 0, len2 = ring.length; j < len2 - 1; j++) {
            if (onBoundary(point, ring[j], ring[j + 1])) return false;
            if (rayIntersect(point, ring[j], ring[j + 1])) inside = !inside;
        }
    }
    return inside;
}

function pointWithinPolygons(point                 , polygons                                      ) {
    for (let i = 0; i < polygons.length; i++) {
        if (pointWithinPolygon(point, polygons[i])) return true;
    }
    return false;
}

function perp(v1                 , v2                 ) {
    return (v1[0] * v2[1] - v1[1] * v2[0]);
}

// check if p1 and p2 are in different sides of line segment q1->q2
function  twoSided(p1                 , p2                 , q1                 , q2                 ) {
    // q1->p1 (x1, y1), q1->p2 (x2, y2), q1->q2 (x3, y3)
    const x1 = p1[0] - q1[0];
    const y1 = p1[1] - q1[1];
    const x2 = p2[0] - q1[0];
    const y2 = p2[1] - q1[1];
    const x3 = q2[0] - q1[0];
    const y3 = q2[1] - q1[1];
    const det1 = (x1 * y3 - x3 * y1);
    const det2 =  (x2 * y3 - x3 * y2);
    if ((det1 > 0 && det2 < 0) || (det1 < 0 && det2 > 0)) return true;
    return false;
}
// a, b are end points for line segment1, c and d are end points for line segment2
function lineIntersectLine(a                 , b                 , c                 , d                 ) {
    // check if two segments are parallel or not
    // precondition is end point a, b is inside polygon, if line a->b is
    // parallel to polygon edge c->d, then a->b won't intersect with c->d
    const vectorP = [b[0] - a[0], b[1] - a[1]];
    const vectorQ = [d[0] - c[0], d[1] - c[1]];
    if (perp(vectorQ, vectorP) === 0) return false;

    // If lines are intersecting with each other, the relative location should be:
    // a and b lie in different sides of segment c->d
    // c and d lie in different sides of segment a->b
    if (twoSided(a, b, c, d) && twoSided(c, d, a, b)) return true;
    return false;
}

function lineIntersectPolygon(p1                 , p2                 , polygon                               ) {
    for (const ring of polygon) {
        // loop through every edge of the ring
        for (let j = 0; j < ring.length - 1; ++j) {
            if (lineIntersectLine(p1, p2, ring[j], ring[j + 1])) {
                return true;
            }
        }
    }
    return false;
}

function lineStringWithinPolygon(line                        , polygon                               ) {
    // First, check if geometry points of line segments are all inside polygon
    for (let i = 0; i < line.length; ++i) {
        if (!pointWithinPolygon(line[i], polygon)) {
            return false;
        }
    }

    // Second, check if there is line segment intersecting polygon edge
    for (let i = 0; i < line.length - 1; ++i) {
        if (lineIntersectPolygon(line[i], line[i + 1], polygon)) {
            return false;
        }
    }
    return true;
}

function lineStringWithinPolygons(line                        , polygons                                      ) {
    for (let i = 0; i < polygons.length; i++) {
        if (lineStringWithinPolygon(line, polygons[i])) return true;
    }
    return false;
}

function getTilePolygon(coordinates                               , bbox      , canonical                 ) {
    const polygon = [];
    for (let i = 0; i < coordinates.length; i++) {
        const ring = [];
        for (let j = 0; j < coordinates[i].length; j++) {
            const coord = getTileCoordinates(coordinates[i][j], canonical);
            updateBBox(bbox, coord);
            ring.push(coord);
        }
        polygon.push(ring);
    }
    return polygon;
}

function getTilePolygons(coordinates                                      , bbox      , canonical                 ) {
    const polygons = [];
    for (let i = 0; i < coordinates.length; i++) {
        const polygon = getTilePolygon(coordinates[i], bbox, canonical);
        polygons.push(polygon);
    }
    return polygons;
}

function updatePoint(p                 , bbox      , polyBBox               , worldSize        ) {
    if (p[0] < polyBBox[0] || p[0] > polyBBox[2]) {
        const halfWorldSize = worldSize * 0.5;
        let shift = (p[0] - polyBBox[0] > halfWorldSize) ? -worldSize : (polyBBox[0] - p[0] > halfWorldSize) ? worldSize : 0;
        if (shift === 0) {
            shift = (p[0] - polyBBox[2] > halfWorldSize) ? -worldSize : (polyBBox[2] - p[0] > halfWorldSize) ? worldSize : 0;
        }
        p[0] += shift;
    }
    updateBBox(bbox, p);
}

function resetBBox(bbox      ) {
    bbox[0] = bbox[1] = Infinity;
    bbox[2] = bbox[3] = -Infinity;
}

function getTilePoints(geometry                      , pointBBox      , polyBBox               , canonical                 ) {
    const worldSize = Math.pow(2, canonical.z) * EXTENT$1;
    const shifts = [canonical.x * EXTENT$1, canonical.y * EXTENT$1];
    const tilePoints = [];
    if (!geometry) return tilePoints;
    for (const points of geometry) {
        for (const point of points) {
            const p = [point.x + shifts[0], point.y + shifts[1]];
            updatePoint(p, pointBBox, polyBBox, worldSize);
            tilePoints.push(p);
        }
    }
    return tilePoints;
}

function getTileLines(geometry                      , lineBBox      , polyBBox               , canonical                 ) {
    const worldSize = Math.pow(2, canonical.z) * EXTENT$1;
    const shifts = [canonical.x * EXTENT$1, canonical.y * EXTENT$1];
    const tileLines                                = [];
    if (!geometry) return tileLines;
    for (const line of geometry) {
        const tileLine = [];
        for (const point of line) {
            const p                  = [point.x + shifts[0], point.y + shifts[1]];
            updateBBox(lineBBox, p);
            tileLine.push(p);
        }
        tileLines.push(tileLine);
    }
    if (lineBBox[2] - lineBBox[0] <= worldSize / 2) {
        resetBBox(lineBBox);
        for (const line of tileLines) {
            for (const p of line) {
                updatePoint(p, lineBBox, polyBBox, worldSize);
            }
        }
    }
    return tileLines;
}

function pointsWithinPolygons(ctx                   , polygonGeometry                 ) {
    const pointBBox = [Infinity, Infinity, -Infinity, -Infinity];
    const polyBBox = [Infinity, Infinity, -Infinity, -Infinity];

    const canonical = ctx.canonicalID();
    if (!canonical) {
        return false;
    }

    if (polygonGeometry.type === 'Polygon') {
        const tilePolygon = getTilePolygon(polygonGeometry.coordinates, polyBBox, canonical);
        const tilePoints = getTilePoints(ctx.geometry(), pointBBox, polyBBox, canonical);
        if (!boxWithinBox(pointBBox, polyBBox)) return false;

        for (const point of tilePoints) {
            if (!pointWithinPolygon(point, tilePolygon)) return false;
        }
    }
    if (polygonGeometry.type === 'MultiPolygon') {
        const tilePolygons = getTilePolygons(polygonGeometry.coordinates, polyBBox, canonical);
        const tilePoints = getTilePoints(ctx.geometry(), pointBBox, polyBBox, canonical);
        if (!boxWithinBox(pointBBox, polyBBox)) return false;

        for (const point of tilePoints) {
            if (!pointWithinPolygons(point, tilePolygons)) return false;
        }
    }

    return true;
}

function linesWithinPolygons(ctx                   , polygonGeometry                 ) {
    const lineBBox = [Infinity, Infinity, -Infinity, -Infinity];
    const polyBBox = [Infinity, Infinity, -Infinity, -Infinity];

    const canonical = ctx.canonicalID();
    if (!canonical) {
        return false;
    }

    if (polygonGeometry.type === 'Polygon') {
        const tilePolygon = getTilePolygon(polygonGeometry.coordinates, polyBBox, canonical);
        const tileLines = getTileLines(ctx.geometry(), lineBBox, polyBBox, canonical);
        if (!boxWithinBox(lineBBox, polyBBox)) return false;

        for (const line of tileLines) {
            if (!lineStringWithinPolygon(line, tilePolygon)) return false;
        }
    }
    if (polygonGeometry.type === 'MultiPolygon') {
        const tilePolygons = getTilePolygons(polygonGeometry.coordinates, polyBBox, canonical);
        const tileLines = getTileLines(ctx.geometry(), lineBBox, polyBBox, canonical);
        if (!boxWithinBox(lineBBox, polyBBox)) return false;

        for (const line of tileLines) {
            if (!lineStringWithinPolygons(line, tilePolygons)) return false;
        }
    }
    return true;
}

class Within                       {
               
                    
                                

    constructor(geojson         , geometries                 ) {
        this.type = BooleanType;
        this.geojson = geojson;
        this.geometries = geometries;
    }

    static parse(args                       , context                )          {
        if (args.length !== 2)
            return context.error(`'within' expression requires exactly one argument, but found ${args.length - 1} instead.`);
        if (isValue(args[1])) {
            const geojson = (args[1]        );
            if (geojson.type === 'FeatureCollection') {
                for (let i = 0; i < geojson.features.length; ++i) {
                    const type = geojson.features[i].geometry.type;
                    if (type === 'Polygon' || type === 'MultiPolygon') {
                        return new Within(geojson, geojson.features[i].geometry);
                    }
                }
            } else if (geojson.type === 'Feature') {
                const type = geojson.geometry.type;
                if (type === 'Polygon' || type === 'MultiPolygon') {
                    return new Within(geojson, geojson.geometry);
                }
            } else if (geojson.type  === 'Polygon' || geojson.type === 'MultiPolygon') {
                return new Within(geojson, geojson);
            }
        }
        return context.error(`'within' expression requires valid geojson object that contains polygon geometry type.`);
    }

    evaluate(ctx                   )          {
        if (ctx.geometry() != null && ctx.canonicalID() != null) {
            if (ctx.geometryType() === 'Point') {
                return pointsWithinPolygons(ctx, this.geometries);
            } else if (ctx.geometryType() === 'LineString') {
                return linesWithinPolygons(ctx, this.geometries);
            }
        }
        return false;
    }

    eachChild() {}

    outputDefined()          {
        return true;
    }

    serialize()                       {
        return ["within", this.geojson];
    }

}

//      

                                                

function isFeatureConstant(e            )          {
    if (e instanceof CompoundExpression) {
        if (e.name === 'get' && e.args.length === 1) {
            return false;
        } else if (e.name === 'feature-state') {
            return false;
        } else if (e.name === 'has' && e.args.length === 1) {
            return false;
        } else if (
            e.name === 'properties' ||
            e.name === 'geometry-type' ||
            e.name === 'id'
        ) {
            return false;
        } else if (/^filter-/.test(e.name)) {
            return false;
        }
    }

    if (e instanceof Within) {
        return false;
    }

    let result = true;
    e.eachChild(arg => {
        if (result && !isFeatureConstant(arg)) { result = false; }
    });
    return result;
}

function isStateConstant(e            )          {
    if (e instanceof CompoundExpression) {
        if (e.name === 'feature-state') {
            return false;
        }
    }
    let result = true;
    e.eachChild(arg => {
        if (result && !isStateConstant(arg)) { result = false; }
    });
    return result;
}

function isGlobalPropertyConstant(e            , properties               )          {
    if (e instanceof CompoundExpression && properties.indexOf(e.name) >= 0) { return false; }
    let result = true;
    e.eachChild((arg) => {
        if (result && !isGlobalPropertyConstant(arg, properties)) { result = false; }
    });
    return result;
}

//      

                                      
                                                 
                                                        
                                                               

class Var                       {
               
                 
                                

    constructor(name        , boundExpression            ) {
        this.type = boundExpression.type;
        this.name = name;
        this.boundExpression = boundExpression;
    }

    static parse(args                       , context                )             {
        if (args.length !== 2 || typeof args[1] !== 'string')
            return context.error(`'var' expression requires exactly one string literal argument.`);

        const name = args[1];
        if (!context.scope.has(name)) {
            return context.error(`Unknown variable "${name}". Make sure "${name}" has been bound in an enclosing "let" expression before using it.`, 1);
        }

        return new Var(name, context.scope.get(name));
    }

    evaluate(ctx                   )      {
        return this.boundExpression.evaluate(ctx);
    }

    eachChild() {}

    outputDefined()          {
        return false;
    }

    serialize()                {
        return ["var", this.name];
    }
}

//      


                                                                    
                                     

/**
 * State associated parsing at a given point in an expression tree.
 * @private
 */
class ParsingContext {
                                 
                        
                
                 
                                

    // The expected type of this expression. Provided only to allow Expression
    // implementations to infer argument types: Expression#parse() need not
    // check that the output type of the parsed expression matches
    // `expectedType`.
                        

    constructor(
        registry                    ,
        path                = [],
        expectedType       ,
        scope        = new Scope(),
        errors                      = []
    ) {
        this.registry = registry;
        this.path = path;
        this.key = path.map(part => `[${part}]`).join('');
        this.scope = scope;
        this.errors = errors;
        this.expectedType = expectedType;
    }

    /**
     * @param expr the JSON expression to parse
     * @param index the optional argument index if this expression is an argument of a parent expression that's being parsed
     * @param options
     * @param options.omitTypeAnnotations set true to omit inferred type annotations.  Caller beware: with this option set, the parsed expression's type will NOT satisfy `expectedType` if it would normally be wrapped in an inferred annotation.
     * @private
     */
    parse(
        expr       ,
        index         ,
        expectedType        ,
        bindings                              ,
        options                                                  = {}
    )              {
        if (index) {
            return this.concat(index, expectedType, bindings)._parse(expr, options);
        }
        return this._parse(expr, options);
    }

    _parse(expr       , options                                                 )              {
        if (expr === null || typeof expr === 'string' || typeof expr === 'boolean' || typeof expr === 'number') {
            expr = ['literal', expr];
        }

        function annotate(parsed            , type      , typeAnnotation                              ) {
            if (typeAnnotation === 'assert') {
                return new Assertion(type, [parsed]);
            } else if (typeAnnotation === 'coerce') {
                return new Coercion(type, [parsed]);
            } else {
                return parsed;
            }
        }

        if (Array.isArray(expr)) {
            if (expr.length === 0) {
                return this.error(`Expected an array with at least one element. If you wanted a literal array, use ["literal", []].`);
            }

            const op = expr[0];
            if (typeof op !== 'string') {
                this.error(`Expression name must be a string, but found ${typeof op} instead. If you wanted a literal array, use ["literal", [...]].`, 0);
                return null;
            }

            const Expr = this.registry[op];
            if (Expr) {
                let parsed = Expr.parse(expr, this);
                if (!parsed) return null;

                if (this.expectedType) {
                    const expected = this.expectedType;
                    const actual = parsed.type;

                    // When we expect a number, string, boolean, or array but have a value, wrap it in an assertion.
                    // When we expect a color or formatted string, but have a string or value, wrap it in a coercion.
                    // Otherwise, we do static type-checking.
                    //
                    // These behaviors are overridable for:
                    //   * The "coalesce" operator, which needs to omit type annotations.
                    //   * String-valued properties (e.g. `text-field`), where coercion is more convenient than assertion.
                    //
                    if ((expected.kind === 'string' || expected.kind === 'number' || expected.kind === 'boolean' || expected.kind === 'object' || expected.kind === 'array') && actual.kind === 'value') {
                        parsed = annotate(parsed, expected, options.typeAnnotation || 'assert');
                    } else if ((expected.kind === 'color' || expected.kind === 'formatted' || expected.kind === 'resolvedImage') && (actual.kind === 'value' || actual.kind === 'string')) {
                        parsed = annotate(parsed, expected, options.typeAnnotation || 'coerce');
                    } else if (this.checkSubtype(expected, actual)) {
                        return null;
                    }
                }

                // If an expression's arguments are all literals, we can evaluate
                // it immediately and replace it with a literal value in the
                // parsed/compiled result. Expressions that expect an image should
                // not be resolved here so we can later get the available images.
                if (!(parsed instanceof Literal) && (parsed.type.kind !== 'resolvedImage') && isConstant(parsed)) {
                    const ec = new EvaluationContext();
                    try {
                        parsed = new Literal(parsed.type, parsed.evaluate(ec));
                    } catch (e) {
                        this.error(e.message);
                        return null;
                    }
                }

                return parsed;
            }

            return this.error(`Unknown expression "${op}". If you wanted a literal array, use ["literal", [...]].`, 0);
        } else if (typeof expr === 'undefined') {
            return this.error(`'undefined' value invalid. Use null instead.`);
        } else if (typeof expr === 'object') {
            return this.error(`Bare objects invalid. Use ["literal", {...}] instead.`);
        } else {
            return this.error(`Expected an array, but found ${typeof expr} instead.`);
        }
    }

    /**
     * Returns a copy of this context suitable for parsing the subexpression at
     * index `index`, optionally appending to 'let' binding map.
     *
     * Note that `errors` property, intended for collecting errors while
     * parsing, is copied by reference rather than cloned.
     * @private
     */
    concat(index        , expectedType        , bindings                              )                 {
        const path = typeof index === 'number' ? this.path.concat(index) : this.path;
        const scope = bindings ? this.scope.concat(bindings) : this.scope;
        return new ParsingContext(
            this.registry,
            path,
            expectedType || null,
            scope,
            this.errors
        );
    }

    /**
     * Push a parsing (or type checking) error into the `this.errors`
     * @param error The message
     * @param keys Optionally specify the source of the error at a child
     * of the current expression at `this.key`.
     * @private
     */
    error(error        , ...keys               ) {
        const key = `${this.key}${keys.map(k => `[${k}]`).join('')}`;
        this.errors.push(new ParsingError(key, error));
    }

    /**
     * Returns null if `t` is a subtype of `expected`; otherwise returns an
     * error message and also pushes it to `this.errors`.
     */
    checkSubtype(expected      , t      )          {
        const error = checkSubtype(expected, t);
        if (error) this.error(error);
        return error;
    }
}

var ParsingContext$1 = ParsingContext;

function isConstant(expression            ) {
    if (expression instanceof Var) {
        return isConstant(expression.boundExpression);
    } else if (expression instanceof CompoundExpression && expression.name === 'error') {
        return false;
    } else if (expression instanceof CollatorExpression) {
        // Although the results of a Collator expression with fixed arguments
        // generally shouldn't change between executions, we can't serialize them
        // as constant expressions because results change based on environment.
        return false;
    } else if (expression instanceof Within) {
        return false;
    }

    const isTypeAnnotation = expression instanceof Coercion ||
        expression instanceof Assertion;

    let childrenConstant = true;
    expression.eachChild(child => {
        // We can _almost_ assume that if `expressions` children are constant,
        // they would already have been evaluated to Literal values when they
        // were parsed.  Type annotations are the exception, because they might
        // have been inferred and added after a child was parsed.

        // So we recurse into isConstant() for the children of type annotations,
        // but otherwise simply check whether they are Literals.
        if (isTypeAnnotation) {
            childrenConstant = childrenConstant && isConstant(child);
        } else {
            childrenConstant = childrenConstant && child instanceof Literal;
        }
    });
    if (!childrenConstant) {
        return false;
    }

    return isFeatureConstant(expression) &&
        isGlobalPropertyConstant(expression, ['zoom', 'heatmap-density', 'line-progress', 'sky-radial-progress', 'accumulated', 'is-supported-script', 'pitch', 'distance-from-center']);
}

//      


                                                

                                                

/**
 * Returns the index of the last stop <= input, or 0 if it doesn't exist.
 * @private
 */
function findStopLessThanOrEqualTo(stops               , input        )         {
    const lastIndex = stops.length - 1;
    let lowerIndex = 0;
    let upperIndex = lastIndex;
    let currentIndex = 0;
    let currentValue, nextValue;

    while (lowerIndex <= upperIndex) {
        currentIndex = Math.floor((lowerIndex + upperIndex) / 2);
        currentValue = stops[currentIndex];
        nextValue = stops[currentIndex + 1];

        if (currentValue <= input) {
            if (currentIndex === lastIndex || input < nextValue) { // Search complete
                return currentIndex;
            }

            lowerIndex = currentIndex + 1;
        } else if (currentValue > input) {
            upperIndex = currentIndex - 1;
        } else {
            throw new RuntimeError('Input is not a number.');
        }
    }

    return 0;
}

//      


                                       
                                                                       
                                                        
                                                              
                                      

class Step                       {
               

                      
                          
                               

    constructor(type      , input            , stops       ) {
        this.type = type;
        this.input = input;

        this.labels = [];
        this.outputs = [];
        for (const [label, expression] of stops) {
            this.labels.push(label);
            this.outputs.push(expression);
        }
    }

    static parse(args                       , context                )        {
        if (args.length - 1 < 4) {
            return context.error(`Expected at least 4 arguments, but found only ${args.length - 1}.`);
        }

        if ((args.length - 1) % 2 !== 0) {
            return context.error(`Expected an even number of arguments.`);
        }

        const input = context.parse(args[1], 1, NumberType);
        if (!input) return null;

        const stops        = [];

        let outputType       = (null     );
        if (context.expectedType && context.expectedType.kind !== 'value') {
            outputType = context.expectedType;
        }

        for (let i = 1; i < args.length; i += 2) {
            const label = i === 1 ? -Infinity : args[i];
            const value = args[i + 1];

            const labelKey = i;
            const valueKey = i + 1;

            if (typeof label !== 'number') {
                return context.error('Input/output pairs for "step" expressions must be defined using literal numeric values (not computed expressions) for the input values.', labelKey);
            }

            if (stops.length && stops[stops.length - 1][0] >= label) {
                return context.error('Input/output pairs for "step" expressions must be arranged with input values in strictly ascending order.', labelKey);
            }

            const parsed = context.parse(value, valueKey, outputType);
            if (!parsed) return null;
            outputType = outputType || parsed.type;
            stops.push([label, parsed]);
        }

        return new Step(outputType, input, stops);
    }

    evaluate(ctx                   )      {
        const labels = this.labels;
        const outputs = this.outputs;

        if (labels.length === 1) {
            return outputs[0].evaluate(ctx);
        }

        const value = ((this.input.evaluate(ctx)     )        );
        if (value <= labels[0]) {
            return outputs[0].evaluate(ctx);
        }

        const stopCount = labels.length;
        if (value >= labels[stopCount - 1]) {
            return outputs[stopCount - 1].evaluate(ctx);
        }

        const index = findStopLessThanOrEqualTo(labels, value);
        return outputs[index].evaluate(ctx);
    }

    eachChild(fn                         ) {
        fn(this.input);
        for (const expression of this.outputs) {
            fn(expression);
        }
    }

    outputDefined()          {
        return this.outputs.every(out => out.outputDefined());
    }

    serialize()                       {
        const serialized = ["step", this.input.serialize()];
        for (let i = 0; i < this.labels.length; i++) {
            if (i > 0) {
                serialized.push(this.labels[i]);
            }
            serialized.push(this.outputs[i].serialize());
        }
        return serialized;
    }
}

//      


function number(a        , b        , t        )         {
    return (a * (1 - t)) + (b * t);
}

function color(from       , to       , t        )        {
    return new Color(
        number(from.r, to.r, t),
        number(from.g, to.g, t),
        number(from.b, to.b, t),
        number(from.a, to.a, t)
    );
}

function array(from               , to               , t        )                {
    return from.map((d, i) => {
        return number(d, to[i], t);
    });
}

var interpolate = /*#__PURE__*/Object.freeze({
__proto__: null,
array: array,
color: color,
number: number
});

//      


                 
              
              
              
                 
  

                 
              
              
              
                 
  

// Constants
const Xn = 0.950470, // D65 standard referent
    Yn = 1,
    Zn = 1.088830,
    t0 = 4 / 29,
    t1 = 6 / 29,
    t2 = 3 * t1 * t1,
    t3 = t1 * t1 * t1,
    deg2rad = Math.PI / 180,
    rad2deg = 180 / Math.PI;

// Utilities
function xyz2lab(t        ) {
    return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0;
}

function lab2xyz(t        ) {
    return t > t1 ? t * t * t : t2 * (t - t0);
}

function xyz2rgb(x        ) {
    return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055);
}

function rgb2xyz(x        ) {
    x /= 255;
    return x <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);
}

// LAB
function rgbToLab(rgbColor       )           {
    const b = rgb2xyz(rgbColor.r),
        a = rgb2xyz(rgbColor.g),
        l = rgb2xyz(rgbColor.b),
        x = xyz2lab((0.4124564 * b + 0.3575761 * a + 0.1804375 * l) / Xn),
        y = xyz2lab((0.2126729 * b + 0.7151522 * a + 0.0721750 * l) / Yn),
        z = xyz2lab((0.0193339 * b + 0.1191920 * a + 0.9503041 * l) / Zn);

    return {
        l: 116 * y - 16,
        a: 500 * (x - y),
        b: 200 * (y - z),
        alpha: rgbColor.a
    };
}

function labToRgb(labColor          )        {
    let y = (labColor.l + 16) / 116,
        x = isNaN(labColor.a) ? y : y + labColor.a / 500,
        z = isNaN(labColor.b) ? y : y - labColor.b / 200;
    y = Yn * lab2xyz(y);
    x = Xn * lab2xyz(x);
    z = Zn * lab2xyz(z);
    return new Color(
        xyz2rgb(3.2404542 * x - 1.5371385 * y - 0.4985314 * z), // D65 -> sRGB
        xyz2rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z),
        xyz2rgb(0.0556434 * x - 0.2040259 * y + 1.0572252 * z),
        labColor.alpha
    );
}

function interpolateLab(from          , to          , t        )           {
    return {
        l: number(from.l, to.l, t),
        a: number(from.a, to.a, t),
        b: number(from.b, to.b, t),
        alpha: number(from.alpha, to.alpha, t)
    };
}

// HCL
function rgbToHcl(rgbColor       )           {
    const {l, a, b} = rgbToLab(rgbColor);
    const h = Math.atan2(b, a) * rad2deg;
    return {
        h: h < 0 ? h + 360 : h,
        c: Math.sqrt(a * a + b * b),
        l,
        alpha: rgbColor.a
    };
}

function hclToRgb(hclColor          )        {
    const h = hclColor.h * deg2rad,
        c = hclColor.c,
        l = hclColor.l;
    return labToRgb({
        l,
        a: Math.cos(h) * c,
        b: Math.sin(h) * c,
        alpha: hclColor.alpha
    });
}

function interpolateHue(a        , b        , t        ) {
    const d = b - a;
    return a + t * (d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d);
}

function interpolateHcl(from          , to          , t        )           {
    return {
        h: interpolateHue(from.h, to.h, t),
        c: number(from.c, to.c, t),
        l: number(from.l, to.l, t),
        alpha: number(from.alpha, to.alpha, t)
    };
}

const lab = {
    forward: rgbToLab,
    reverse: labToRgb,
    interpolate: interpolateLab
};

const hcl = {
    forward: rgbToHcl,
    reverse: hclToRgb,
    interpolate: interpolateHcl
};

var colorSpaces = /*#__PURE__*/Object.freeze({
__proto__: null,
hcl: hcl,
lab: lab
});

//      


                                       
                                                                       
                                                        
                                                              
                                      

                               
                        
                                           
                                                                              

class Interpolate                       {
               

                                                                    
                                     
                      
                          
                               

    constructor(type      , operator                                                       , interpolation                   , input            , stops       ) {
        this.type = type;
        this.operator = operator;
        this.interpolation = interpolation;
        this.input = input;

        this.labels = [];
        this.outputs = [];
        for (const [label, expression] of stops) {
            this.labels.push(label);
            this.outputs.push(expression);
        }
    }

    static interpolationFactor(interpolation                   , input        , lower        , upper        )         {
        let t = 0;
        if (interpolation.name === 'exponential') {
            t = exponentialInterpolation(input, interpolation.base, lower, upper);
        } else if (interpolation.name === 'linear') {
            t = exponentialInterpolation(input, 1, lower, upper);
        } else if (interpolation.name === 'cubic-bezier') {
            const c = interpolation.controlPoints;
            const ub = new UnitBezier$1(c[0], c[1], c[2], c[3]);
            t = ub.solve(exponentialInterpolation(input, 1, lower, upper));
        }
        return t;
    }

    static parse(args                       , context                )               {
        let [operator, interpolation, input, ...rest] = args;

        if (!Array.isArray(interpolation) || interpolation.length === 0) {
            return context.error(`Expected an interpolation type expression.`, 1);
        }

        if (interpolation[0] === 'linear') {
            interpolation = {name: 'linear'};
        } else if (interpolation[0] === 'exponential') {
            const base = interpolation[1];
            if (typeof base !== 'number')
                return context.error(`Exponential interpolation requires a numeric base.`, 1, 1);
            interpolation = {
                name: 'exponential',
                base
            };
        } else if (interpolation[0] === 'cubic-bezier') {
            const controlPoints = interpolation.slice(1);
            if (
                controlPoints.length !== 4 ||
                controlPoints.some(t => typeof t !== 'number' || t < 0 || t > 1)
            ) {
                return context.error('Cubic bezier interpolation requires four numeric arguments with values between 0 and 1.', 1);
            }

            interpolation = {
                name: 'cubic-bezier',
                controlPoints: (controlPoints     )
            };
        } else {
            return context.error(`Unknown interpolation type ${String(interpolation[0])}`, 1, 0);
        }

        if (args.length - 1 < 4) {
            return context.error(`Expected at least 4 arguments, but found only ${args.length - 1}.`);
        }

        if ((args.length - 1) % 2 !== 0) {
            return context.error(`Expected an even number of arguments.`);
        }

        input = context.parse(input, 2, NumberType);
        if (!input) return null;

        const stops        = [];

        let outputType       = (null     );
        if (operator === 'interpolate-hcl' || operator === 'interpolate-lab') {
            outputType = ColorType;
        } else if (context.expectedType && context.expectedType.kind !== 'value') {
            outputType = context.expectedType;
        }

        for (let i = 0; i < rest.length; i += 2) {
            const label = rest[i];
            const value = rest[i + 1];

            const labelKey = i + 3;
            const valueKey = i + 4;

            if (typeof label !== 'number') {
                return context.error('Input/output pairs for "interpolate" expressions must be defined using literal numeric values (not computed expressions) for the input values.', labelKey);
            }

            if (stops.length && stops[stops.length - 1][0] >= label) {
                return context.error('Input/output pairs for "interpolate" expressions must be arranged with input values in strictly ascending order.', labelKey);
            }

            const parsed = context.parse(value, valueKey, outputType);
            if (!parsed) return null;
            outputType = outputType || parsed.type;
            stops.push([label, parsed]);
        }

        if (outputType.kind !== 'number' &&
            outputType.kind !== 'color' &&
            !(
                outputType.kind === 'array' &&
                outputType.itemType.kind === 'number' &&
                typeof outputType.N === 'number'
            )
        ) {
            return context.error(`Type ${toString$1(outputType)} is not interpolatable.`);
        }

        return new Interpolate(outputType, (operator     ), interpolation, input, stops);
    }

    evaluate(ctx                   )        {
        const labels = this.labels;
        const outputs = this.outputs;

        if (labels.length === 1) {
            return outputs[0].evaluate(ctx);
        }

        const value = ((this.input.evaluate(ctx)     )        );
        if (value <= labels[0]) {
            return outputs[0].evaluate(ctx);
        }

        const stopCount = labels.length;
        if (value >= labels[stopCount - 1]) {
            return outputs[stopCount - 1].evaluate(ctx);
        }

        const index = findStopLessThanOrEqualTo(labels, value);
        const lower = labels[index];
        const upper = labels[index + 1];
        const t = Interpolate.interpolationFactor(this.interpolation, value, lower, upper);

        const outputLower = outputs[index].evaluate(ctx);
        const outputUpper = outputs[index + 1].evaluate(ctx);

        if (this.operator === 'interpolate') {
            return (interpolate[this.type.kind.toLowerCase()]     )(outputLower, outputUpper, t); // eslint-disable-line import/namespace
        } else if (this.operator === 'interpolate-hcl') {
            return hcl.reverse(hcl.interpolate(hcl.forward(outputLower), hcl.forward(outputUpper), t));
        } else {
            return lab.reverse(lab.interpolate(lab.forward(outputLower), lab.forward(outputUpper), t));
        }
    }

    eachChild(fn                         ) {
        fn(this.input);
        for (const expression of this.outputs) {
            fn(expression);
        }
    }

    outputDefined()          {
        return this.outputs.every(out => out.outputDefined());
    }

    serialize()                       {
        let interpolation;
        if (this.interpolation.name === 'linear') {
            interpolation = ["linear"];
        } else if (this.interpolation.name === 'exponential') {
            if  (this.interpolation.base === 1) {
                interpolation = ["linear"];
            } else {
                interpolation = ["exponential", this.interpolation.base];
            }
        } else {
            interpolation = ["cubic-bezier" ].concat(this.interpolation.controlPoints);
        }

        const serialized = [this.operator, interpolation, this.input.serialize()];

        for (let i = 0; i < this.labels.length; i++) {
            serialized.push(
                this.labels[i],
                this.outputs[i].serialize()
            );
        }
        return serialized;
    }
}

/**
 * Returns a ratio that can be used to interpolate between exponential function
 * stops.
 * How it works: Two consecutive stop values define a (scaled and shifted) exponential function `f(x) = a * base^x + b`, where `base` is the user-specified base,
 * and `a` and `b` are constants affording sufficient degrees of freedom to fit
 * the function to the given stops.
 *
 * Here's a bit of algebra that lets us compute `f(x)` directly from the stop
 * values without explicitly solving for `a` and `b`:
 *
 * First stop value: `f(x0) = y0 = a * base^x0 + b`
 * Second stop value: `f(x1) = y1 = a * base^x1 + b`
 * => `y1 - y0 = a(base^x1 - base^x0)`
 * => `a = (y1 - y0)/(base^x1 - base^x0)`
 *
 * Desired value: `f(x) = y = a * base^x + b`
 * => `f(x) = y0 + a * (base^x - base^x0)`
 *
 * From the above, we can replace the `a` in `a * (base^x - base^x0)` and do a
 * little algebra:
 * ```
 * a * (base^x - base^x0) = (y1 - y0)/(base^x1 - base^x0) * (base^x - base^x0)
 *                     = (y1 - y0) * (base^x - base^x0) / (base^x1 - base^x0)
 * ```
 *
 * If we let `(base^x - base^x0) / (base^x1 base^x0)`, then we have
 * `f(x) = y0 + (y1 - y0) * ratio`.  In other words, `ratio` may be treated as
 * an interpolation factor between the two stops' output values.
 *
 * (Note: a slightly different form for `ratio`,
 * `(base^(x-x0) - 1) / (base^(x1-x0) - 1) `, is equivalent, but requires fewer
 * expensive `Math.pow()` operations.)
 *
 * @private
*/
function exponentialInterpolation(input        , base        , lowerValue        , upperValue        ) {
    const difference = upperValue - lowerValue;
    const progress = input - lowerValue;

    if (difference === 0) {
        return 0;
    } else if (base === 1) {
        return progress / difference;
    } else {
        return (Math.pow(base, progress) - 1) / (Math.pow(base, difference) - 1);
    }
}

//      


                                                                       
                                                        
                                                              
                                      

class Coalesce                       {
               
                            

    constructor(type      , args                   ) {
        this.type = type;
        this.args = args;
    }

    static parse(args                       , context                )            {
        if (args.length < 2) {
            return context.error("Expectected at least one argument.");
        }
        let outputType       = (null     );
        const expectedType = context.expectedType;
        if (expectedType && expectedType.kind !== 'value') {
            outputType = expectedType;
        }
        const parsedArgs = [];

        for (const arg of args.slice(1)) {
            const parsed = context.parse(arg, 1 + parsedArgs.length, outputType, undefined, {typeAnnotation: 'omit'});
            if (!parsed) return null;
            outputType = outputType || parsed.type;
            parsedArgs.push(parsed);
        }
        assert$1(outputType);

        // Above, we parse arguments without inferred type annotation so that
        // they don't produce a runtime error for `null` input, which would
        // preempt the desired null-coalescing behavior.
        // Thus, if any of our arguments would have needed an annotation, we
        // need to wrap the enclosing coalesce expression with it instead.
        const needsAnnotation = expectedType &&
            parsedArgs.some(arg => checkSubtype(expectedType, arg.type));

        return needsAnnotation ?
            new Coalesce(ValueType, parsedArgs) :
            new Coalesce((outputType     ), parsedArgs);
    }

    evaluate(ctx                   )             {
        let result = null;
        let argCount = 0;
        let firstImage;
        for (const arg of this.args) {
            argCount++;
            result = arg.evaluate(ctx);
            // we need to keep track of the first requested image in a coalesce statement
            // if coalesce can't find a valid image, we return the first image so styleimagemissing can fire
            if (result && result instanceof ResolvedImage && !result.available) {
                // set to first image
                if (!firstImage) {
                    firstImage = result;
                }
                result = null;
                // if we reach the end, return the first image
                if (argCount === this.args.length) {
                    return firstImage;
                }
            }

            if (result !== null) break;
        }
        return result;
    }

    eachChild(fn                         ) {
        this.args.forEach(fn);
    }

    outputDefined()          {
        return this.args.every(arg => arg.outputDefined());
    }

    serialize()                       {
        const serialized = ["coalesce"];
        this.eachChild(child => { serialized.push(child.serialize()); });
        return serialized;
    }
}

//      

                                      
                                                                       
                                                        
                                                               

class Let                       {
               
                                          
                       

    constructor(bindings                             , result            ) {
        this.type = result.type;
        this.bindings = [].concat(bindings);
        this.result = result;
    }

    evaluate(ctx                   )      {
        return this.result.evaluate(ctx);
    }

    eachChild(fn                         ) {
        for (const binding of this.bindings) {
            fn(binding[1]);
        }
        fn(this.result);
    }

    static parse(args                       , context                )       {
        if (args.length < 4)
            return context.error(`Expected at least 3 arguments, but found ${args.length - 1} instead.`);

        const bindings                              = [];
        for (let i = 1; i < args.length - 1; i += 2) {
            const name = args[i];

            if (typeof name !== 'string') {
                return context.error(`Expected string, but found ${typeof name} instead.`, i);
            }

            if (/[^a-zA-Z0-9_]/.test(name)) {
                return context.error(`Variable names must contain only alphanumeric characters or '_'.`, i);
            }

            const value = context.parse(args[i + 1], i + 1);
            if (!value) return null;

            bindings.push([name, value]);
        }

        const result = context.parse(args[args.length - 1], args.length - 1, context.expectedType, bindings);
        if (!result) return null;

        return new Let(bindings, result);
    }

    outputDefined()          {
        return this.result.outputDefined();
    }

    serialize()                       {
        const serialized = ["let"];
        for (const [name, expr] of this.bindings) {
            serialized.push(name, expr.serialize());
        }
        serialized.push(this.result.serialize());
        return serialized;
    }
}

//      


                                                                       
                                                        
                                                              
                                                 
                                        

class At                       {
               
                      
                      

    constructor(type      , index            , input            ) {
        this.type = type;
        this.index = index;
        this.input = input;
    }

    static parse(args                       , context                )      {
        if (args.length !== 3)
            return context.error(`Expected 2 arguments, but found ${args.length - 1} instead.`);

        const index = context.parse(args[1], 1, NumberType);
        const input = context.parse(args[2], 2, array$1(context.expectedType || ValueType));

        if (!index || !input) return null;

        const t            = (input.type     );
        return new At(t.itemType, index, input);
    }

    evaluate(ctx                   )        {
        const index = ((this.index.evaluate(ctx)     )        );
        const array = ((this.input.evaluate(ctx)     )              );

        if (index < 0) {
            throw new RuntimeError(`Array index out of bounds: ${index} < 0.`);
        }

        if (index >= array.length) {
            throw new RuntimeError(`Array index out of bounds: ${index} > ${array.length - 1}.`);
        }

        if (index !== Math.floor(index)) {
            throw new RuntimeError(`Array index must be an integer, but found ${index} instead.`);
        }

        return array[index];
    }

    eachChild(fn                         ) {
        fn(this.index);
        fn(this.input);
    }

    outputDefined()          {
        return false;
    }

    serialize()                       {
        return ["at", this.index.serialize(), this.input.serialize()];
    }
}

//      


                                                                       
                                                        
                                                              
                                      

class In                       {
               
                       
                         

    constructor(needle            , haystack            ) {
        this.type = BooleanType;
        this.needle = needle;
        this.haystack = haystack;
    }

    static parse(args                       , context                )      {
        if (args.length !== 3) {
            return context.error(`Expected 2 arguments, but found ${args.length - 1} instead.`);
        }

        const needle = context.parse(args[1], 1, ValueType);

        const haystack = context.parse(args[2], 2, ValueType);

        if (!needle || !haystack) return null;

        if (!isValidType(needle.type, [BooleanType, StringType, NumberType, NullType, ValueType])) {
            return context.error(`Expected first argument to be of type boolean, string, number or null, but found ${toString$1(needle.type)} instead`);
        }

        return new In(needle, haystack);
    }

    evaluate(ctx                   )          {
        const needle = (this.needle.evaluate(ctx)     );
        const haystack = (this.haystack.evaluate(ctx)     );

        if (haystack == null) return false;

        if (!isValidNativeType(needle, ['boolean', 'string', 'number', 'null'])) {
            throw new RuntimeError(`Expected first argument to be of type boolean, string, number or null, but found ${toString$1(typeOf(needle))} instead.`);
        }

        if (!isValidNativeType(haystack, ['string', 'array'])) {
            throw new RuntimeError(`Expected second argument to be of type array or string, but found ${toString$1(typeOf(haystack))} instead.`);
        }

        return haystack.indexOf(needle) >= 0;
    }

    eachChild(fn                         ) {
        fn(this.needle);
        fn(this.haystack);
    }

    outputDefined()          {
        return true;
    }

    serialize()                       {
        return ["in", this.needle.serialize(), this.haystack.serialize()];
    }
}

//      


                                                                       
                                                        
                                                              
                                      

class IndexOf                       {
               
                       
                         
                           

    constructor(needle            , haystack            , fromIndex             ) {
        this.type = NumberType;
        this.needle = needle;
        this.haystack = haystack;
        this.fromIndex = fromIndex;
    }

    static parse(args                       , context                )           {
        if (args.length <= 2 ||  args.length >= 5) {
            return context.error(`Expected 3 or 4 arguments, but found ${args.length - 1} instead.`);
        }

        const needle = context.parse(args[1], 1, ValueType);

        const haystack = context.parse(args[2], 2, ValueType);

        if (!needle || !haystack) return null;
        if (!isValidType(needle.type, [BooleanType, StringType, NumberType, NullType, ValueType])) {
            return context.error(`Expected first argument to be of type boolean, string, number or null, but found ${toString$1(needle.type)} instead`);
        }

        if (args.length === 4) {
            const fromIndex = context.parse(args[3], 3, NumberType);
            if (!fromIndex) return null;
            return new IndexOf(needle, haystack, fromIndex);
        } else {
            return new IndexOf(needle, haystack);
        }
    }

    evaluate(ctx                   )      {
        const needle = (this.needle.evaluate(ctx)     );
        const haystack = (this.haystack.evaluate(ctx)     );

        if (!isValidNativeType(needle, ['boolean', 'string', 'number', 'null'])) {
            throw new RuntimeError(`Expected first argument to be of type boolean, string, number or null, but found ${toString$1(typeOf(needle))} instead.`);
        }

        if (!isValidNativeType(haystack, ['string', 'array'])) {
            throw new RuntimeError(`Expected second argument to be of type array or string, but found ${toString$1(typeOf(haystack))} instead.`);
        }

        if (this.fromIndex) {
            const fromIndex = (this.fromIndex.evaluate(ctx)        );
            return haystack.indexOf(needle, fromIndex);
        }

        return haystack.indexOf(needle);
    }

    eachChild(fn                         ) {
        fn(this.needle);
        fn(this.haystack);
        if (this.fromIndex) {
            fn(this.fromIndex);
        }
    }

    outputDefined()          {
        return false;
    }

    serialize()                       {
        if (this.fromIndex != null && this.fromIndex !== undefined) {
            const fromIndex = this.fromIndex.serialize();
            return ["index-of", this.needle.serialize(), this.haystack.serialize(), fromIndex];
        }
        return ["index-of", this.needle.serialize(), this.haystack.serialize()];
    }
}

//      


                                                                       
                                                        
                                                              

// Map input label values to output expression index
                                         

class Match                       {
               
                    

                      
                 
                               
                          

    constructor(inputType      , outputType      , input            , cases       , outputs                   , otherwise            ) {
        this.inputType = inputType;
        this.type = outputType;
        this.input = input;
        this.cases = cases;
        this.outputs = outputs;
        this.otherwise = otherwise;
    }

    static parse(args                       , context                )         {
        if (args.length < 5)
            return context.error(`Expected at least 4 arguments, but found only ${args.length - 1}.`);
        if (args.length % 2 !== 1)
            return context.error(`Expected an even number of arguments.`);

        let inputType;
        let outputType       ;
        if (context.expectedType && context.expectedType.kind !== 'value') {
            outputType = context.expectedType;
        }
        const cases = {};
        const outputs = [];
        for (let i = 2; i < args.length - 1; i += 2) {
            let labels = args[i];
            const value = args[i + 1];

            if (!Array.isArray(labels)) {
                labels = [labels];
            }

            const labelContext = context.concat(i);
            if (labels.length === 0) {
                return labelContext.error('Expected at least one branch label.');
            }

            for (const label of labels) {
                if (typeof label !== 'number' && typeof label !== 'string') {
                    return labelContext.error(`Branch labels must be numbers or strings.`);
                } else if (typeof label === 'number' && Math.abs(label) > Number.MAX_SAFE_INTEGER) {
                    return labelContext.error(`Branch labels must be integers no larger than ${Number.MAX_SAFE_INTEGER}.`);

                } else if (typeof label === 'number' && Math.floor(label) !== label) {
                    return labelContext.error(`Numeric branch labels must be integer values.`);

                } else if (!inputType) {
                    inputType = typeOf(label);
                } else if (labelContext.checkSubtype(inputType, typeOf(label))) {
                    return null;
                }

                if (typeof cases[String(label)] !== 'undefined') {
                    return labelContext.error('Branch labels must be unique.');
                }

                cases[String(label)] = outputs.length;
            }

            const result = context.parse(value, i, outputType);
            if (!result) return null;
            outputType = outputType || result.type;
            outputs.push(result);
        }

        const input = context.parse(args[1], 1, ValueType);
        if (!input) return null;

        const otherwise = context.parse(args[args.length - 1], args.length - 1, outputType);
        if (!otherwise) return null;

        assert$1(inputType && outputType);

        if (input.type.kind !== 'value' && context.concat(1).checkSubtype((inputType     ), input.type)) {
            return null;
        }

        return new Match((inputType     ), (outputType     ), input, cases, outputs, otherwise);
    }

    evaluate(ctx                   )      {
        const input = (this.input.evaluate(ctx)     );
        const output = (typeOf(input) === this.inputType && this.outputs[this.cases[input]]) || this.otherwise;
        return output.evaluate(ctx);
    }

    eachChild(fn                         ) {
        fn(this.input);
        this.outputs.forEach(fn);
        fn(this.otherwise);
    }

    outputDefined()          {
        return this.outputs.every(out => out.outputDefined()) && this.otherwise.outputDefined();
    }

    serialize()                       {
        const serialized = ["match", this.input.serialize()];

        // Sort so serialization has an arbitrary defined order, even though
        // branch order doesn't affect evaluation
        const sortedLabels = Object.keys(this.cases).sort();

        // Group branches by unique match expression to support condensed
        // serializations of the form [case1, case2, ...] -> matchExpression
        const groupedByOutput                                          = [];
        const outputLookup                            = {}; // lookup index into groupedByOutput for a given output expression
        for (const label of sortedLabels) {
            const outputIndex = outputLookup[this.cases[label]];
            if (outputIndex === undefined) {
                // First time seeing this output, add it to the end of the grouped list
                outputLookup[this.cases[label]] = groupedByOutput.length;
                groupedByOutput.push([this.cases[label], [label]]);
            } else {
                // We've seen this expression before, add the label to that output's group
                groupedByOutput[outputIndex][1].push(label);
            }
        }

        const coerceLabel = (label                 ) => this.inputType.kind === 'number' ? Number(label) : label;

        for (const [outputIndex, labels] of groupedByOutput) {
            if (labels.length === 1) {
                // Only a single label matches this output expression
                serialized.push(coerceLabel(labels[0]));
            } else {
                // Array of literal labels pointing to this output expression
                serialized.push(labels.map(coerceLabel));
            }
            serialized.push(this.outputs[outputIndex].serialize());
        }
        serialized.push(this.otherwise.serialize());
        return serialized;
    }
}

//      


                                                                       
                                                        
                                                              
                                      

                                                

class Case                       {
               

                       
                          

    constructor(type      , branches          , otherwise            ) {
        this.type = type;
        this.branches = branches;
        this.otherwise = otherwise;
    }

    static parse(args                       , context                )        {
        if (args.length < 4)
            return context.error(`Expected at least 3 arguments, but found only ${args.length - 1}.`);
        if (args.length % 2 !== 0)
            return context.error(`Expected an odd number of arguments.`);

        let outputType       ;
        if (context.expectedType && context.expectedType.kind !== 'value') {
            outputType = context.expectedType;
        }

        const branches = [];
        for (let i = 1; i < args.length - 1; i += 2) {
            const test = context.parse(args[i], i, BooleanType);
            if (!test) return null;

            const result = context.parse(args[i + 1], i + 1, outputType);
            if (!result) return null;

            branches.push([test, result]);

            outputType = outputType || result.type;
        }

        const otherwise = context.parse(args[args.length - 1], args.length - 1, outputType);
        if (!otherwise) return null;

        assert$1(outputType);
        return new Case((outputType     ), branches, otherwise);
    }

    evaluate(ctx                   )      {
        for (const [test, expression] of this.branches) {
            if (test.evaluate(ctx)) {
                return expression.evaluate(ctx);
            }
        }
        return this.otherwise.evaluate(ctx);
    }

    eachChild(fn                         ) {
        for (const [test, expression] of this.branches) {
            fn(test);
            fn(expression);
        }
        fn(this.otherwise);
    }

    outputDefined()          {
        return this.branches.every(([_, out]) => out.outputDefined()) && this.otherwise.outputDefined();
    }

    serialize()                       {
        const serialized = ["case"];
        this.eachChild(child => { serialized.push(child.serialize()); });
        return serialized;
    }
}

//      


                                                                       
                                                        
                                                              
                                      

class Slice                       {
               
                      
                           
                          

    constructor(type      , input            , beginIndex            , endIndex             ) {
        this.type = type;
        this.input = input;
        this.beginIndex = beginIndex;
        this.endIndex = endIndex;

    }

    static parse(args                       , context                )         {
        if (args.length <= 2 ||  args.length >= 5) {
            return context.error(`Expected 3 or 4 arguments, but found ${args.length - 1} instead.`);
        }

        const input = context.parse(args[1], 1, ValueType);
        const beginIndex = context.parse(args[2], 2, NumberType);

        if (!input || !beginIndex) return null;

        if (!isValidType(input.type, [array$1(ValueType), StringType, ValueType])) {
            return context.error(`Expected first argument to be of type array or string, but found ${toString$1(input.type)} instead`);
        }

        if (args.length === 4) {
            const endIndex = context.parse(args[3], 3, NumberType);
            if (!endIndex) return null;
            return new Slice(input.type, input, beginIndex, endIndex);
        } else {
            return new Slice(input.type, input, beginIndex);
        }
    }

    evaluate(ctx                   )      {
        const input = (this.input.evaluate(ctx)     );
        const beginIndex = (this.beginIndex.evaluate(ctx)        );

        if (!isValidNativeType(input, ['string', 'array'])) {
            throw new RuntimeError(`Expected first argument to be of type array or string, but found ${toString$1(typeOf(input))} instead.`);
        }

        if (this.endIndex) {
            const endIndex = (this.endIndex.evaluate(ctx)        );
            return input.slice(beginIndex, endIndex);
        }

        return input.slice(beginIndex);
    }

    eachChild(fn                         ) {
        fn(this.input);
        fn(this.beginIndex);
        if (this.endIndex) {
            fn(this.endIndex);
        }
    }

    outputDefined()          {
        return false;
    }

    serialize()                       {
        if (this.endIndex != null && this.endIndex !== undefined) {
            const endIndex = this.endIndex.serialize();
            return ["slice", this.input.serialize(), this.beginIndex.serialize(), endIndex];
        }
        return ["slice", this.input.serialize(), this.beginIndex.serialize()];
    }
}

//      


                                                                                               
                                                              
                                                        
                                      

                                                                 

function isComparableType(op                    , type      ) {
    if (op === '==' || op === '!=') {
        // equality operator
        return type.kind === 'boolean' ||
            type.kind === 'string' ||
            type.kind === 'number' ||
            type.kind === 'null' ||
            type.kind === 'value';
    } else {
        // ordering operator
        return type.kind === 'string' ||
            type.kind === 'number' ||
            type.kind === 'value';
    }
}

function eq(ctx                   , a     , b     )          { return a === b; }
function neq(ctx                   , a     , b     )          { return a !== b; }
function lt(ctx                   , a     , b     )          { return a < b; }
function gt(ctx                   , a     , b     )          { return a > b; }
function lteq(ctx                   , a     , b     )          { return a <= b; }
function gteq(ctx                   , a     , b     )          { return a >= b; }

function eqCollate(ctx                   , a     , b     , c     )          { return c.compare(a, b) === 0; }
function neqCollate(ctx                   , a     , b     , c     )          { return !eqCollate(ctx, a, b, c); }
function ltCollate(ctx                   , a     , b     , c     )          { return c.compare(a, b) < 0; }
function gtCollate(ctx                   , a     , b     , c     )          { return c.compare(a, b) > 0; }
function lteqCollate(ctx                   , a     , b     , c     )          { return c.compare(a, b) <= 0; }
function gteqCollate(ctx                   , a     , b     , c     )          { return c.compare(a, b) >= 0; }

/**
 * Special form for comparison operators, implementing the signatures:
 * - (T, T, ?Collator) => boolean
 * - (T, value, ?Collator) => boolean
 * - (value, T, ?Collator) => boolean
 *
 * For inequalities, T must be either value, string, or number. For ==/!=, it
 * can also be boolean or null.
 *
 * Equality semantics are equivalent to Javascript's strict equality (===/!==)
 * -- i.e., when the arguments' types don't match, == evaluates to false, != to
 * true.
 *
 * When types don't match in an ordering comparison, a runtime error is thrown.
 *
 * @private
 */
function makeComparison(op                    , compareBasic                                          , compareWithCollator                                               )                         {
    const isOrderComparison = op !== '==' && op !== '!=';

    // $FlowFixMe[method-unbinding]
    return class Comparison                       {
                   
                        
                        
                              
                                    

        constructor(lhs            , rhs            , collator             ) {
            this.type = BooleanType;
            this.lhs = lhs;
            this.rhs = rhs;
            this.collator = collator;
            this.hasUntypedArgument = lhs.type.kind === 'value' || rhs.type.kind === 'value';
        }

        // $FlowFixMe[method-unbinding]
        static parse(args                       , context                )              {
            if (args.length !== 3 && args.length !== 4)
                return context.error(`Expected two or three arguments.`);

            const op                     = (args[0]     );

            let lhs = context.parse(args[1], 1, ValueType);
            if (!lhs) return null;
            if (!isComparableType(op, lhs.type)) {
                return context.concat(1).error(`"${op}" comparisons are not supported for type '${toString$1(lhs.type)}'.`);
            }
            let rhs = context.parse(args[2], 2, ValueType);
            if (!rhs) return null;
            if (!isComparableType(op, rhs.type)) {
                return context.concat(2).error(`"${op}" comparisons are not supported for type '${toString$1(rhs.type)}'.`);
            }

            if (
                lhs.type.kind !== rhs.type.kind &&
                lhs.type.kind !== 'value' &&
                rhs.type.kind !== 'value'
            ) {
                return context.error(`Cannot compare types '${toString$1(lhs.type)}' and '${toString$1(rhs.type)}'.`);
            }

            if (isOrderComparison) {
                // typing rules specific to less/greater than operators
                if (lhs.type.kind === 'value' && rhs.type.kind !== 'value') {
                    // (value, T)
                    lhs = new Assertion(rhs.type, [lhs]);
                } else if (lhs.type.kind !== 'value' && rhs.type.kind === 'value') {
                    // (T, value)
                    rhs = new Assertion(lhs.type, [rhs]);
                }
            }

            let collator = null;
            if (args.length === 4) {
                if (
                    lhs.type.kind !== 'string' &&
                    rhs.type.kind !== 'string' &&
                    lhs.type.kind !== 'value' &&
                    rhs.type.kind !== 'value'
                ) {
                    return context.error(`Cannot use collator to compare non-string types.`);
                }
                collator = context.parse(args[3], 3, CollatorType);
                if (!collator) return null;
            }

            return new Comparison(lhs, rhs, collator);
        }

        evaluate(ctx                   )          {
            const lhs = this.lhs.evaluate(ctx);
            const rhs = this.rhs.evaluate(ctx);

            if (isOrderComparison && this.hasUntypedArgument) {
                const lt = typeOf(lhs);
                const rt = typeOf(rhs);
                // check that type is string or number, and equal
                if (lt.kind !== rt.kind || !(lt.kind === 'string' || lt.kind === 'number')) {
                    throw new RuntimeError(`Expected arguments for "${op}" to be (string, string) or (number, number), but found (${lt.kind}, ${rt.kind}) instead.`);
                }
            }

            if (this.collator && !isOrderComparison && this.hasUntypedArgument) {
                const lt = typeOf(lhs);
                const rt = typeOf(rhs);
                if (lt.kind !== 'string' || rt.kind !== 'string') {
                    return compareBasic(ctx, lhs, rhs);
                }
            }

            return this.collator ?
                compareWithCollator(ctx, lhs, rhs, this.collator.evaluate(ctx)) :
                compareBasic(ctx, lhs, rhs);
        }

        eachChild(fn                         ) {
            fn(this.lhs);
            fn(this.rhs);
            if (this.collator) {
                fn(this.collator);
            }
        }

        outputDefined()          {
            return true;
        }

        serialize()                       {
            const serialized = [op];
            this.eachChild(child => { serialized.push(child.serialize()); });
            return serialized;
        }
    };
}

const Equals                                                                  = makeComparison('==', eq, eqCollate);
const NotEquals                                                                    = makeComparison('!=', neq, neqCollate);
const LessThan                                                                 = makeComparison('<', lt, ltCollate);
const GreaterThan                                                                 = makeComparison('>', gt, gtCollate);
const LessThanOrEqual                                                                      = makeComparison('<=', lteq, lteqCollate);
const GreaterThanOrEqual                                                                      = makeComparison('>=', gteq, gteqCollate);

//      


                                                                       
                                                              
                                                        
                                      

                   
                                          
  

                                 
                 
                                    
                                     
                         

            
                                    
                                     
                         

                              

                           
 

                            
                                                        
                             
                         
                                          
                                          
  

class NumberFormat                       {
               
                       
                                 // BCP 47 language tag
                                 // ISO 4217 currency code, required if style=currency
                                 // Simple units sanctioned for use in ECMAScript, required if style=unit. https://tc39.es/proposal-unified-intl-numberformat/section6/locales-currencies-tz_proposed_out.html#sec-issanctionedsimpleunitidentifier
                                          // Default 0
                                          // Default 3

    constructor(number            ,
                locale                   ,
                currency                   ,
                unit                   ,
                minFractionDigits                   ,
                maxFractionDigits                   ) {
        this.type = StringType;
        this.number = number;
        this.locale = locale;
        this.currency = currency;
        this.unit = unit;
        this.minFractionDigits = minFractionDigits;
        this.maxFractionDigits = maxFractionDigits;
    }

    static parse(args                       , context                )              {
        if (args.length !== 3)
            return context.error(`Expected two arguments.`);

        const number = context.parse(args[1], 1, NumberType);
        if (!number) return null;

        const options = (args[2]     );
        if (typeof options !== "object" || Array.isArray(options))
            return context.error(`NumberFormat options argument must be an object.`);

        let locale = null;
        if (options['locale']) {
            locale = context.parse(options['locale'], 1, StringType);
            if (!locale) return null;
        }

        let currency = null;
        if (options['currency']) {
            currency = context.parse(options['currency'], 1, StringType);
            if (!currency) return null;
        }

        let unit = null;
        if (options['unit']) {
            unit = context.parse(options['unit'], 1, StringType);
            if (!unit) return null;
        }

        let minFractionDigits = null;
        if (options['min-fraction-digits']) {
            minFractionDigits = context.parse(options['min-fraction-digits'], 1, NumberType);
            if (!minFractionDigits) return null;
        }

        let maxFractionDigits = null;
        if (options['max-fraction-digits']) {
            maxFractionDigits = context.parse(options['max-fraction-digits'], 1, NumberType);
            if (!maxFractionDigits) return null;
        }

        return new NumberFormat(number, locale, currency, unit, minFractionDigits, maxFractionDigits);
    }

    evaluate(ctx                   )         {
        return new Intl.NumberFormat(this.locale ? this.locale.evaluate(ctx) : [],
            {
                style:
                    (this.currency && "currency") ||
                    (this.unit && "unit") ||
                    "decimal",
                currency: this.currency ? this.currency.evaluate(ctx) : undefined,
                unit: this.unit ? this.unit.evaluate(ctx) : undefined,
                minimumFractionDigits: this.minFractionDigits ? this.minFractionDigits.evaluate(ctx) : undefined,
                maximumFractionDigits: this.maxFractionDigits ? this.maxFractionDigits.evaluate(ctx) : undefined,
            }).format(this.number.evaluate(ctx));
    }

    eachChild(fn                         ) {
        fn(this.number);
        if (this.locale) {
            fn(this.locale);
        }
        if (this.currency) {
            fn(this.currency);
        }
        if (this.unit) {
            fn(this.unit);
        }
        if (this.minFractionDigits) {
            fn(this.minFractionDigits);
        }
        if (this.maxFractionDigits) {
            fn(this.maxFractionDigits);
        }
    }

    outputDefined()          {
        return false;
    }

    serialize()                       {
        const options = {};
        if (this.locale) {
            options['locale'] = this.locale.serialize();
        }
        if (this.currency) {
            options['currency'] = this.currency.serialize();
        }
        if (this.unit) {
            options['unit'] = this.unit.serialize();
        }
        if (this.minFractionDigits) {
            options['min-fraction-digits'] = this.minFractionDigits.serialize();
        }
        if (this.maxFractionDigits) {
            options['max-fraction-digits'] = this.maxFractionDigits.serialize();
        }
        return ["number-format", this.number.serialize(), options];
    }
}

//      


                                                                       
                                                        
                                                              
                                      

class Length                       {
               
                      

    constructor(input            ) {
        this.type = NumberType;
        this.input = input;
    }

    static parse(args                       , context                )          {
        if (args.length !== 2)
            return context.error(`Expected 1 argument, but found ${args.length - 1} instead.`);

        const input = context.parse(args[1], 1);
        if (!input) return null;

        if (input.type.kind !== 'array' && input.type.kind !== 'string' && input.type.kind !== 'value')
            return context.error(`Expected argument of type string or array, but found ${toString$1(input.type)} instead.`);

        return new Length(input);
    }

    evaluate(ctx                   )               {
        const input = this.input.evaluate(ctx);
        if (typeof input === 'string') {
            return input.length;
        } else if (Array.isArray(input)) {
            return input.length;
        } else {
            throw new RuntimeError(`Expected value to be of type string or array, but found ${toString$1(typeOf(input))} instead.`);
        }
    }

    eachChild(fn                         ) {
        fn(this.input);
    }

    outputDefined()          {
        return false;
    }

    serialize()                       {
        const serialized = ["length"];
        this.eachChild(child => { serialized.push(child.serialize()); });
        return serialized;
    }
}

//      


                                                              
                                                       
                                                                     

const expressions                     = {
    // special forms
    '==': Equals,
    '!=': NotEquals,
    '>': GreaterThan,
    '<': LessThan,
    '>=': GreaterThanOrEqual,
    '<=': LessThanOrEqual,
    // $FlowFixMe[method-unbinding]
    'array': Assertion,
    // $FlowFixMe[method-unbinding]
    'at': At,
    'boolean': Assertion,
    // $FlowFixMe[method-unbinding]
    'case': Case,
    // $FlowFixMe[method-unbinding]
    'coalesce': Coalesce,
    // $FlowFixMe[method-unbinding]
    'collator': CollatorExpression,
    // $FlowFixMe[method-unbinding]
    'format': FormatExpression,
    // $FlowFixMe[method-unbinding]
    'image': ImageExpression,
    // $FlowFixMe[method-unbinding]
    'in': In,
    // $FlowFixMe[method-unbinding]
    'index-of': IndexOf,
    // $FlowFixMe[method-unbinding]
    'interpolate': Interpolate,
    'interpolate-hcl': Interpolate,
    'interpolate-lab': Interpolate,
    // $FlowFixMe[method-unbinding]
    'length': Length,
    // $FlowFixMe[method-unbinding]
    'let': Let,
    // $FlowFixMe[method-unbinding]
    'literal': Literal,
    // $FlowFixMe[method-unbinding]
    'match': Match,
    'number': Assertion,
    // $FlowFixMe[method-unbinding]
    'number-format': NumberFormat,
    'object': Assertion,
    // $FlowFixMe[method-unbinding]
    'slice': Slice,
    // $FlowFixMe[method-unbinding]
    'step': Step,
    'string': Assertion,
    // $FlowFixMe[method-unbinding]
    'to-boolean': Coercion,
    'to-color': Coercion,
    'to-number': Coercion,
    'to-string': Coercion,
    // $FlowFixMe[method-unbinding]
    'var': Var,
    // $FlowFixMe[method-unbinding]
    'within': Within
};

function rgba(ctx                   , [r, g, b, a]                   ) {
    r = r.evaluate(ctx);
    g = g.evaluate(ctx);
    b = b.evaluate(ctx);
    const alpha = a ? a.evaluate(ctx) : 1;
    const error = validateRGBA(r, g, b, alpha);
    if (error) throw new RuntimeError(error);
    return new Color(r / 255 * alpha, g / 255 * alpha, b / 255 * alpha, alpha);
}

function has(key        , obj                 )          {
    return key in obj;
}

function get(key        , obj                 ) {
    const v = obj[key];
    return typeof v === 'undefined' ? null : v;
}

function binarySearch(v     , a                 , i        , j        ) {
    while (i <= j) {
        const m = (i + j) >> 1;
        if (a[m] === v)
            return true;
        if (a[m] > v)
            j = m - 1;
        else
            i = m + 1;
    }
    return false;
}

function varargs(type      )          {
    return {type};
}

CompoundExpression.register(expressions, {
    'error': [
        ErrorType,
        [StringType],
        (ctx, [v]) => { throw new RuntimeError(v.evaluate(ctx)); }
    ],
    'typeof': [
        StringType,
        [ValueType],
        (ctx, [v]) => toString$1(typeOf(v.evaluate(ctx)))
    ],
    'to-rgba': [
        array$1(NumberType, 4),
        [ColorType],
        (ctx, [v]) => {
            return v.evaluate(ctx).toArray();
        }
    ],
    'rgb': [
        ColorType,
        [NumberType, NumberType, NumberType],
        rgba
    ],
    'rgba': [
        ColorType,
        [NumberType, NumberType, NumberType, NumberType],
        rgba
    ],
    'has': {
        type: BooleanType,
        overloads: [
            [
                [StringType],
                (ctx, [key]) => has(key.evaluate(ctx), ctx.properties())
            ], [
                [StringType, ObjectType],
                (ctx, [key, obj]) => has(key.evaluate(ctx), obj.evaluate(ctx))
            ]
        ]
    },
    'get': {
        type: ValueType,
        overloads: [
            [
                [StringType],
                (ctx, [key]) => get(key.evaluate(ctx), ctx.properties())
            ], [
                [StringType, ObjectType],
                (ctx, [key, obj]) => get(key.evaluate(ctx), obj.evaluate(ctx))
            ]
        ]
    },
    'feature-state': [
        ValueType,
        [StringType],
        (ctx, [key]) => get(key.evaluate(ctx), ctx.featureState || {})
    ],
    'properties': [
        ObjectType,
        [],
        (ctx) => ctx.properties()
    ],
    'geometry-type': [
        StringType,
        [],
        (ctx) => ctx.geometryType()
    ],
    'id': [
        ValueType,
        [],
        (ctx) => ctx.id()
    ],
    'zoom': [
        NumberType,
        [],
        (ctx) => ctx.globals.zoom
    ],
    'pitch': [
        NumberType,
        [],
        (ctx) => ctx.globals.pitch || 0
    ],
    'distance-from-center': [
        NumberType,
        [],
        (ctx) => ctx.distanceFromCenter()
    ],
    'heatmap-density': [
        NumberType,
        [],
        (ctx) => ctx.globals.heatmapDensity || 0
    ],
    'line-progress': [
        NumberType,
        [],
        (ctx) => ctx.globals.lineProgress || 0
    ],
    'sky-radial-progress': [
        NumberType,
        [],
        (ctx) => ctx.globals.skyRadialProgress || 0
    ],
    'accumulated': [
        ValueType,
        [],
        (ctx) => ctx.globals.accumulated === undefined ? null : ctx.globals.accumulated
    ],
    '+': [
        NumberType,
        varargs(NumberType),
        (ctx, args) => {
            let result = 0;
            for (const arg of args) {
                result += arg.evaluate(ctx);
            }
            return result;
        }
    ],
    '*': [
        NumberType,
        varargs(NumberType),
        (ctx, args) => {
            let result = 1;
            for (const arg of args) {
                result *= arg.evaluate(ctx);
            }
            return result;
        }
    ],
    '-': {
        type: NumberType,
        overloads: [
            [
                [NumberType, NumberType],
                (ctx, [a, b]) => a.evaluate(ctx) - b.evaluate(ctx)
            ], [
                [NumberType],
                (ctx, [a]) => -a.evaluate(ctx)
            ]
        ]
    },
    '/': [
        NumberType,
        [NumberType, NumberType],
        (ctx, [a, b]) => a.evaluate(ctx) / b.evaluate(ctx)
    ],
    '%': [
        NumberType,
        [NumberType, NumberType],
        (ctx, [a, b]) => a.evaluate(ctx) % b.evaluate(ctx)
    ],
    'ln2': [
        NumberType,
        [],
        () => Math.LN2
    ],
    'pi': [
        NumberType,
        [],
        () => Math.PI
    ],
    'e': [
        NumberType,
        [],
        () => Math.E
    ],
    '^': [
        NumberType,
        [NumberType, NumberType],
        (ctx, [b, e]) => Math.pow(b.evaluate(ctx), e.evaluate(ctx))
    ],
    'sqrt': [
        NumberType,
        [NumberType],
        (ctx, [x]) => Math.sqrt(x.evaluate(ctx))
    ],
    'log10': [
        NumberType,
        [NumberType],
        (ctx, [n]) => Math.log(n.evaluate(ctx)) / Math.LN10
    ],
    'ln': [
        NumberType,
        [NumberType],
        (ctx, [n]) => Math.log(n.evaluate(ctx))
    ],
    'log2': [
        NumberType,
        [NumberType],
        (ctx, [n]) => Math.log(n.evaluate(ctx)) / Math.LN2
    ],
    'sin': [
        NumberType,
        [NumberType],
        (ctx, [n]) => Math.sin(n.evaluate(ctx))
    ],
    'cos': [
        NumberType,
        [NumberType],
        (ctx, [n]) => Math.cos(n.evaluate(ctx))
    ],
    'tan': [
        NumberType,
        [NumberType],
        (ctx, [n]) => Math.tan(n.evaluate(ctx))
    ],
    'asin': [
        NumberType,
        [NumberType],
        (ctx, [n]) => Math.asin(n.evaluate(ctx))
    ],
    'acos': [
        NumberType,
        [NumberType],
        (ctx, [n]) => Math.acos(n.evaluate(ctx))
    ],
    'atan': [
        NumberType,
        [NumberType],
        (ctx, [n]) => Math.atan(n.evaluate(ctx))
    ],
    'min': [
        NumberType,
        varargs(NumberType),
        (ctx, args) => Math.min(...args.map(arg => arg.evaluate(ctx)))
    ],
    'max': [
        NumberType,
        varargs(NumberType),
        (ctx, args) => Math.max(...args.map(arg => arg.evaluate(ctx)))
    ],
    'abs': [
        NumberType,
        [NumberType],
        (ctx, [n]) => Math.abs(n.evaluate(ctx))
    ],
    'round': [
        NumberType,
        [NumberType],
        (ctx, [n]) => {
            const v = n.evaluate(ctx);
            // Javascript's Math.round() rounds towards +Infinity for halfway
            // values, even when they're negative. It's more common to round
            // away from 0 (e.g., this is what python and C++ do)
            return v < 0 ? -Math.round(-v) : Math.round(v);
        }
    ],
    'floor': [
        NumberType,
        [NumberType],
        (ctx, [n]) => Math.floor(n.evaluate(ctx))
    ],
    'ceil': [
        NumberType,
        [NumberType],
        (ctx, [n]) => Math.ceil(n.evaluate(ctx))
    ],
    'filter-==': [
        BooleanType,
        [StringType, ValueType],
        (ctx, [k, v]) => ctx.properties()[(k     ).value] === (v     ).value
    ],
    'filter-id-==': [
        BooleanType,
        [ValueType],
        (ctx, [v]) => ctx.id() === (v     ).value
    ],
    'filter-type-==': [
        BooleanType,
        [StringType],
        (ctx, [v]) => ctx.geometryType() === (v     ).value
    ],
    'filter-<': [
        BooleanType,
        [StringType, ValueType],
        (ctx, [k, v]) => {
            const a = ctx.properties()[(k     ).value];
            const b = (v     ).value;
            return typeof a === typeof b && a < b;
        }
    ],
    'filter-id-<': [
        BooleanType,
        [ValueType],
        (ctx, [v]) => {
            const a = ctx.id();
            const b = (v     ).value;
            return typeof a === typeof b && a < b;
        }
    ],
    'filter->': [
        BooleanType,
        [StringType, ValueType],
        (ctx, [k, v]) => {
            const a = ctx.properties()[(k     ).value];
            const b = (v     ).value;
            return typeof a === typeof b && a > b;
        }
    ],
    'filter-id->': [
        BooleanType,
        [ValueType],
        (ctx, [v]) => {
            const a = ctx.id();
            const b = (v     ).value;
            return typeof a === typeof b && a > b;
        }
    ],
    'filter-<=': [
        BooleanType,
        [StringType, ValueType],
        (ctx, [k, v]) => {
            const a = ctx.properties()[(k     ).value];
            const b = (v     ).value;
            return typeof a === typeof b && a <= b;
        }
    ],
    'filter-id-<=': [
        BooleanType,
        [ValueType],
        (ctx, [v]) => {
            const a = ctx.id();
            const b = (v     ).value;
            return typeof a === typeof b && a <= b;
        }
    ],
    'filter->=': [
        BooleanType,
        [StringType, ValueType],
        (ctx, [k, v]) => {
            const a = ctx.properties()[(k     ).value];
            const b = (v     ).value;
            return typeof a === typeof b && a >= b;
        }
    ],
    'filter-id->=': [
        BooleanType,
        [ValueType],
        (ctx, [v]) => {
            const a = ctx.id();
            const b = (v     ).value;
            return typeof a === typeof b && a >= b;
        }
    ],
    'filter-has': [
        BooleanType,
        [ValueType],
        (ctx, [k]) => (k     ).value in ctx.properties()
    ],
    'filter-has-id': [
        BooleanType,
        [],
        (ctx) => (ctx.id() !== null && ctx.id() !== undefined)
    ],
    'filter-type-in': [
        BooleanType,
        [array$1(StringType)],
        (ctx, [v]) => (v     ).value.indexOf(ctx.geometryType()) >= 0
    ],
    'filter-id-in': [
        BooleanType,
        [array$1(ValueType)],
        (ctx, [v]) => (v     ).value.indexOf(ctx.id()) >= 0
    ],
    'filter-in-small': [
        BooleanType,
        [StringType, array$1(ValueType)],
        // assumes v is an array literal
        (ctx, [k, v]) => (v     ).value.indexOf(ctx.properties()[(k     ).value]) >= 0
    ],
    'filter-in-large': [
        BooleanType,
        [StringType, array$1(ValueType)],
        // assumes v is a array literal with values sorted in ascending order and of a single type
        (ctx, [k, v]) => binarySearch(ctx.properties()[(k     ).value], (v     ).value, 0, (v     ).value.length - 1)
    ],
    'all': {
        type: BooleanType,
        overloads: [
            [
                [BooleanType, BooleanType],
                (ctx, [a, b]) => a.evaluate(ctx) && b.evaluate(ctx)
            ],
            [
                varargs(BooleanType),
                (ctx, args) => {
                    for (const arg of args) {
                        if (!arg.evaluate(ctx))
                            return false;
                    }
                    return true;
                }
            ]
        ]
    },
    'any': {
        type: BooleanType,
        overloads: [
            [
                [BooleanType, BooleanType],
                (ctx, [a, b]) => a.evaluate(ctx) || b.evaluate(ctx)
            ],
            [
                varargs(BooleanType),
                (ctx, args) => {
                    for (const arg of args) {
                        if (arg.evaluate(ctx))
                            return true;
                    }
                    return false;
                }
            ]
        ]
    },
    '!': [
        BooleanType,
        [BooleanType],
        (ctx, [b]) => !b.evaluate(ctx)
    ],
    'is-supported-script': [
        BooleanType,
        [StringType],
        // At parse time this will always return true, so we need to exclude this expression with isGlobalPropertyConstant
        (ctx, [s]) => {
            const isSupportedScript = ctx.globals && ctx.globals.isSupportedScript;
            if (isSupportedScript) {
                return isSupportedScript(s.evaluate(ctx));
            }
            return true;
        }
    ],
    'upcase': [
        StringType,
        [StringType],
        (ctx, [s]) => s.evaluate(ctx).toUpperCase()
    ],
    'downcase': [
        StringType,
        [StringType],
        (ctx, [s]) => s.evaluate(ctx).toLowerCase()
    ],
    'concat': [
        StringType,
        varargs(ValueType),
        (ctx, args) => args.map(arg => toString(arg.evaluate(ctx))).join('')
    ],
    'resolved-locale': [
        StringType,
        [CollatorType],
        (ctx, [collator]) => collator.evaluate(ctx).resolvedLocale()
    ]
});

//      

/**
 * A type used for returning and propagating errors. The first element of the union
 * represents success and contains a value, and the second represents an error and
 * contains an error value.
 * @private
 */
                          
                                       
                                      

function success      (value   )               {
    return {result: 'success', value};
}

function error      (value   )               {
    return {result: 'error', value};
}

//      

                                                                 

function supportsPropertyExpression(spec                            )          {
    return spec['property-type'] === 'data-driven';
}

function supportsZoomExpression(spec                            )          {
    return !!spec.expression && spec.expression.parameters.indexOf('zoom') > -1;
}

function supportsInterpolation(spec                            )          {
    return !!spec.expression && spec.expression.interpolated;
}

//      

function getType(val       )         {
    if (val instanceof Number) {
        return 'number';
    } else if (val instanceof String) {
        return 'string';
    } else if (val instanceof Boolean) {
        return 'boolean';
    } else if (Array.isArray(val)) {
        return 'array';
    } else if (val === null) {
        return 'null';
    } else {
        return typeof val;
    }
}

function isFunction(value) {
    return typeof value === 'object' && value !== null && !Array.isArray(value);
}

function identityFunction(x) {
    return x;
}

function createFunction(parameters, propertySpec) {
    const isColor = propertySpec.type === 'color';
    const zoomAndFeatureDependent = parameters.stops && typeof parameters.stops[0][0] === 'object';
    const featureDependent = zoomAndFeatureDependent || parameters.property !== undefined;
    const zoomDependent = zoomAndFeatureDependent || !featureDependent;
    const type = parameters.type || (supportsInterpolation(propertySpec) ? 'exponential' : 'interval');

    if (isColor) {
        parameters = extend({}, parameters);

        if (parameters.stops) {
            parameters.stops = parameters.stops.map((stop) => {
                return [stop[0], Color.parse(stop[1])];
            });
        }

        if (parameters.default) {
            parameters.default = Color.parse(parameters.default);
        } else {
            parameters.default = Color.parse(propertySpec.default);
        }
    }

    if (parameters.colorSpace && parameters.colorSpace !== 'rgb' && !colorSpaces[parameters.colorSpace]) { // eslint-disable-line import/namespace
        throw new Error(`Unknown color space: ${parameters.colorSpace}`);
    }

    let innerFun;
    let hashedStops;
    let categoricalKeyType;
    if (type === 'exponential') {
        innerFun = evaluateExponentialFunction;
    } else if (type === 'interval') {
        innerFun = evaluateIntervalFunction;
    } else if (type === 'categorical') {
        innerFun = evaluateCategoricalFunction;

        // For categorical functions, generate an Object as a hashmap of the stops for fast searching
        hashedStops = Object.create(null);
        for (const stop of parameters.stops) {
            hashedStops[stop[0]] = stop[1];
        }

        // Infer key type based on first stop key-- used to encforce strict type checking later
        categoricalKeyType = typeof parameters.stops[0][0];

    } else if (type === 'identity') {
        innerFun = evaluateIdentityFunction;
    } else {
        throw new Error(`Unknown function type "${type}"`);
    }

    if (zoomAndFeatureDependent) {
        const featureFunctions = {};
        const zoomStops = [];
        for (let s = 0; s < parameters.stops.length; s++) {
            const stop = parameters.stops[s];
            const zoom = stop[0].zoom;
            if (featureFunctions[zoom] === undefined) {
                featureFunctions[zoom] = {
                    zoom,
                    type: parameters.type,
                    property: parameters.property,
                    default: parameters.default,
                    stops: []
                };
                zoomStops.push(zoom);
            }
            featureFunctions[zoom].stops.push([stop[0].value, stop[1]]);
        }

        const featureFunctionStops = [];
        for (const z of zoomStops) {
            featureFunctionStops.push([featureFunctions[z].zoom, createFunction(featureFunctions[z], propertySpec)]);
        }

        const interpolationType = {name: 'linear'};
        return {
            kind: 'composite',
            interpolationType,
            interpolationFactor: Interpolate.interpolationFactor.bind(undefined, interpolationType),
            zoomStops: featureFunctionStops.map(s => s[0]),
            evaluate({zoom}, properties) {
                return evaluateExponentialFunction({
                    stops: featureFunctionStops,
                    base: parameters.base
                }, propertySpec, zoom).evaluate(zoom, properties);
            }
        };
    } else if (zoomDependent) {
        const interpolationType = type === 'exponential' ?
            {name: 'exponential', base: parameters.base !== undefined ? parameters.base : 1} : null;
        return {
            kind: 'camera',
            interpolationType,
            interpolationFactor: Interpolate.interpolationFactor.bind(undefined, interpolationType),
            zoomStops: parameters.stops.map(s => s[0]),
            evaluate: ({zoom}) => innerFun(parameters, propertySpec, zoom, hashedStops, categoricalKeyType)
        };
    } else {
        return {
            kind: 'source',
            evaluate(_, feature) {
                const value = feature && feature.properties ? feature.properties[parameters.property] : undefined;
                if (value === undefined) {
                    return coalesce(parameters.default, propertySpec.default);
                }
                return innerFun(parameters, propertySpec, value, hashedStops, categoricalKeyType);
            }
        };
    }
}

function coalesce(a, b, c) {
    if (a !== undefined) return a;
    if (b !== undefined) return b;
    if (c !== undefined) return c;
}

function evaluateCategoricalFunction(parameters, propertySpec, input, hashedStops, keyType) {
    const evaluated = typeof input === keyType ? hashedStops[input] : undefined; // Enforce strict typing on input
    return coalesce(evaluated, parameters.default, propertySpec.default);
}

function evaluateIntervalFunction(parameters, propertySpec, input) {
    // Edge cases
    if (getType(input) !== 'number') return coalesce(parameters.default, propertySpec.default);
    const n = parameters.stops.length;
    if (n === 1) return parameters.stops[0][1];
    if (input <= parameters.stops[0][0]) return parameters.stops[0][1];
    if (input >= parameters.stops[n - 1][0]) return parameters.stops[n - 1][1];

    const index = findStopLessThanOrEqualTo(parameters.stops.map((stop) => stop[0]), input);

    return parameters.stops[index][1];
}

function evaluateExponentialFunction(parameters, propertySpec, input) {
    const base = parameters.base !== undefined ? parameters.base : 1;

    // Edge cases
    if (getType(input) !== 'number') return coalesce(parameters.default, propertySpec.default);
    const n = parameters.stops.length;
    if (n === 1) return parameters.stops[0][1];
    if (input <= parameters.stops[0][0]) return parameters.stops[0][1];
    if (input >= parameters.stops[n - 1][0]) return parameters.stops[n - 1][1];

    const index = findStopLessThanOrEqualTo(parameters.stops.map((stop) => stop[0]), input);
    const t = interpolationFactor(
        input, base,
        parameters.stops[index][0],
        parameters.stops[index + 1][0]);

    const outputLower = parameters.stops[index][1];
    const outputUpper = parameters.stops[index + 1][1];
    let interp = interpolate[propertySpec.type] || identityFunction; // eslint-disable-line import/namespace

    if (parameters.colorSpace && parameters.colorSpace !== 'rgb') {
        const colorspace = colorSpaces[parameters.colorSpace]; // eslint-disable-line import/namespace
        interp = (a, b) => colorspace.reverse(colorspace.interpolate(colorspace.forward(a), colorspace.forward(b), t));
    }

    if (typeof outputLower.evaluate === 'function') {
        return {
            evaluate(...args) {
                const evaluatedLower = outputLower.evaluate.apply(undefined, args);
                const evaluatedUpper = outputUpper.evaluate.apply(undefined, args);
                // Special case for fill-outline-color, which has no spec default.
                if (evaluatedLower === undefined || evaluatedUpper === undefined) {
                    return undefined;
                }
                return interp(evaluatedLower, evaluatedUpper, t);
            }
        };
    }

    return interp(outputLower, outputUpper, t);
}

function evaluateIdentityFunction(parameters, propertySpec, input) {
    if (propertySpec.type === 'color') {
        input = Color.parse(input);
    } else if (propertySpec.type === 'formatted') {
        input = Formatted.fromString(input.toString());
    } else if (propertySpec.type === 'resolvedImage') {
        input = ResolvedImage.fromString(input.toString());
    } else if (getType(input) !== propertySpec.type && (propertySpec.type !== 'enum' || !propertySpec.values[input])) {
        input = undefined;
    }
    return coalesce(input, parameters.default, propertySpec.default);
}

/**
 * Returns a ratio that can be used to interpolate between exponential function
 * stops.
 *
 * How it works:
 * Two consecutive stop values define a (scaled and shifted) exponential
 * function `f(x) = a * base^x + b`, where `base` is the user-specified base,
 * and `a` and `b` are constants affording sufficient degrees of freedom to fit
 * the function to the given stops.
 *
 * Here's a bit of algebra that lets us compute `f(x)` directly from the stop
 * values without explicitly solving for `a` and `b`:
 *
 * First stop value: `f(x0) = y0 = a * base^x0 + b`
 * Second stop value: `f(x1) = y1 = a * base^x1 + b`
 * => `y1 - y0 = a(base^x1 - base^x0)`
 * => `a = (y1 - y0)/(base^x1 - base^x0)`
 *
 * Desired value: `f(x) = y = a * base^x + b`
 * => `f(x) = y0 + a * (base^x - base^x0)`
 *
 * From the above, we can replace the `a` in `a * (base^x - base^x0)` and do a
 * little algebra:
 * ```
 * a * (base^x - base^x0) = (y1 - y0)/(base^x1 - base^x0) * (base^x - base^x0)
 *                     = (y1 - y0) * (base^x - base^x0) / (base^x1 - base^x0)
 * ```
 *
 * If we let `(base^x - base^x0) / (base^x1 base^x0)`, then we have
 * `f(x) = y0 + (y1 - y0) * ratio`.  In other words, `ratio` may be treated as
 * an interpolation factor between the two stops' output values.
 *
 * (Note: a slightly different form for `ratio`,
 * `(base^(x-x0) - 1) / (base^(x1-x0) - 1) `, is equivalent, but requires fewer
 * expensive `Math.pow()` operations.)
 *
 * @private
 */
function interpolationFactor(input, base, lowerValue, upperValue) {
    const difference = upperValue - lowerValue;
    const progress = input - lowerValue;

    if (difference === 0) {
        return 0;
    } else if (base === 1) {
        return progress / difference;
    } else {
        return (Math.pow(base, progress) - 1) / (Math.pow(base, difference) - 1);
    }
}

//      


                                                     
                                       
                                                
                                                                 
                                              
                                                                    
                                                            
                                                           
                                                
                                                             
                                                                    

                          
                                                                      
                        
                                    
                                      
                                    
 

                                              

                                   
                  
                    
                             
                           
                                
                                                
                         
 

class StyleExpression {
                           

                                  
                         
                                              
                                     

    constructor(expression            , propertySpec                             ) {
        this.expression = expression;
        this._warningHistory = {};
        this._evaluator = new EvaluationContext();
        this._defaultValue = propertySpec ? getDefaultValue(propertySpec) : null;
        this._enumValues = propertySpec && propertySpec.type === 'enum' ? propertySpec.values : null;
    }

    evaluateWithoutErrorHandling(globals                  , feature          , featureState               , canonical                  , availableImages                , formattedSection                   , featureTileCoord        , featureDistanceData                      )      {
        this._evaluator.globals = globals;
        this._evaluator.feature = feature;
        this._evaluator.featureState = featureState;
        this._evaluator.canonical = canonical || null;
        this._evaluator.availableImages = availableImages || null;
        this._evaluator.formattedSection = formattedSection;
        this._evaluator.featureTileCoord = featureTileCoord || null;
        this._evaluator.featureDistanceData = featureDistanceData || null;

        return this.expression.evaluate(this._evaluator);
    }

    evaluate(globals                  , feature          , featureState               , canonical                  , availableImages                , formattedSection                   , featureTileCoord        , featureDistanceData                      )      {
        this._evaluator.globals = globals;
        this._evaluator.feature = feature || null;
        this._evaluator.featureState = featureState || null;
        this._evaluator.canonical = canonical || null;
        this._evaluator.availableImages = availableImages || null;
        this._evaluator.formattedSection = formattedSection || null;
        this._evaluator.featureTileCoord = featureTileCoord || null;
        this._evaluator.featureDistanceData = featureDistanceData || null;

        try {
            const val = this.expression.evaluate(this._evaluator);
            // eslint-disable-next-line no-self-compare
            if (val === null || val === undefined || (typeof val === 'number' && val !== val)) {
                return this._defaultValue;
            }
            if (this._enumValues && !(val in this._enumValues)) {
                throw new RuntimeError(`Expected value to be one of ${Object.keys(this._enumValues).map(v => JSON.stringify(v)).join(', ')}, but found ${JSON.stringify(val)} instead.`);
            }
            return val;
        } catch (e) {
            if (!this._warningHistory[e.message]) {
                this._warningHistory[e.message] = true;
                if (typeof console !== 'undefined') {
                    console.warn(e.message);
                }
            }
            return this._defaultValue;
        }
    }
}

function isExpression(expression       )          {
    return Array.isArray(expression) && expression.length > 0 &&
        typeof expression[0] === 'string' && expression[0] in expressions;
}

/**
 * Parse and typecheck the given style spec JSON expression.  If
 * options.defaultValue is provided, then the resulting StyleExpression's
 * `evaluate()` method will handle errors by logging a warning (once per
 * message) and returning the default value.  Otherwise, it will throw
 * evaluation errors.
 *
 * @private
 */
function createExpression(expression       , propertySpec                             )                                               {
    const parser = new ParsingContext$1(expressions, [], propertySpec ? getExpectedType(propertySpec) : undefined);

    // For string-valued properties, coerce to string at the top level rather than asserting.
    const parsed = parser.parse(expression, undefined, undefined, undefined,
        propertySpec && propertySpec.type === 'string' ? {typeAnnotation: 'coerce'} : undefined);

    if (!parsed) {
        assert$1(parser.errors.length > 0);
        return error(parser.errors);
    }

    return success(new StyleExpression(parsed, propertySpec));
}

class ZoomConstantExpression                       {
               
                              
                                      

    constructor(kind      , expression                 ) {
        this.kind = kind;
        this._styleExpression = expression;
        this.isStateDependent = kind !== ('constant'                ) && !isStateConstant(expression.expression);
    }

    evaluateWithoutErrorHandling(globals                  , feature          , featureState               , canonical                  , availableImages                , formattedSection                   )      {
        return this._styleExpression.evaluateWithoutErrorHandling(globals, feature, featureState, canonical, availableImages, formattedSection);
    }

    evaluate(globals                  , feature          , featureState               , canonical                  , availableImages                , formattedSection                   )      {
        return this._styleExpression.evaluate(globals, feature, featureState, canonical, availableImages, formattedSection);
    }
}

class ZoomDependentExpression                       {
               
                             
                              

                                      
                                          

    constructor(kind      , expression                 , zoomStops               , interpolationType                    ) {
        this.kind = kind;
        this.zoomStops = zoomStops;
        this._styleExpression = expression;
        this.isStateDependent = kind !== ('camera'                ) && !isStateConstant(expression.expression);
        this.interpolationType = interpolationType;
    }

    evaluateWithoutErrorHandling(globals                  , feature          , featureState               , canonical                  , availableImages                , formattedSection                   )      {
        return this._styleExpression.evaluateWithoutErrorHandling(globals, feature, featureState, canonical, availableImages, formattedSection);
    }

    evaluate(globals                  , feature          , featureState               , canonical                  , availableImages                , formattedSection                   )      {
        return this._styleExpression.evaluate(globals, feature, featureState, canonical, availableImages, formattedSection);
    }

    interpolationFactor(input        , lower        , upper        )         {
        if (this.interpolationType) {
            return Interpolate.interpolationFactor(this.interpolationType, input, lower, upper);
        } else {
            return 0;
        }
    }
}

                                            
                     
                                                                                                                                                                
 

                                          
                   
                              
                                                                                                                                                                                                     
  

                                          
                   
                                                                                                                                                                
                                                                                  
                             
                                         
  

                                      
                      
                              
                                                                                                                                                                                                     
                                                                                  
                             
                                          
 

                                     
                        
                      
                      
                          

function createPropertyExpression(expression       , propertySpec                            )                                                       {
    expression = createExpression(expression, propertySpec);
    if (expression.result === 'error') {
        return expression;
    }

    const parsed = expression.value.expression;

    const isFeatureConstant$1 = isFeatureConstant(parsed);
    if (!isFeatureConstant$1 && !supportsPropertyExpression(propertySpec)) {
        return error([new ParsingError('', 'data expressions not supported')]);
    }

    const isZoomConstant = isGlobalPropertyConstant(parsed, ['zoom', 'pitch', 'distance-from-center']);
    if (!isZoomConstant && !supportsZoomExpression(propertySpec)) {
        return error([new ParsingError('', 'zoom expressions not supported')]);
    }

    const zoomCurve = findZoomCurve(parsed);
    if (!zoomCurve && !isZoomConstant) {
        return error([new ParsingError('', '"zoom" expression may only be used as input to a top-level "step" or "interpolate" expression.')]);
    } else if (zoomCurve instanceof ParsingError) {
        return error([zoomCurve]);
    } else if (zoomCurve instanceof Interpolate && !supportsInterpolation(propertySpec)) {
        return error([new ParsingError('', '"interpolate" expressions cannot be used with this property')]);
    }

    if (!zoomCurve) {
        return success(isFeatureConstant$1 ?
            // $FlowFixMe[method-unbinding]
            (new ZoomConstantExpression('constant', expression.value)                    ) :
            // $FlowFixMe[method-unbinding]
            (new ZoomConstantExpression('source', expression.value)                  ));
    }

    const interpolationType = zoomCurve instanceof Interpolate ? zoomCurve.interpolation : undefined;

    return success(isFeatureConstant$1 ?
        // $FlowFixMe[method-unbinding]
        (new ZoomDependentExpression('camera', expression.value, zoomCurve.labels, interpolationType)                  ) :
        // $FlowFixMe[method-unbinding]
        (new ZoomDependentExpression('composite', expression.value, zoomCurve.labels, interpolationType)                     ));
}

// serialization wrapper for old-style stop functions normalized to the
// expression interface
class StylePropertyFunction    {
                                               
                                               

                         
                                                                    
                                                                                  
                              

    constructor(parameters                               , specification                            ) {
        this._parameters = parameters;
        this._specification = specification;
        extend(this, createFunction(this._parameters, this._specification));
    }

    static deserialize(serialized                                                                                          )                           {
        return new StylePropertyFunction(serialized._parameters, serialized._specification);
    }

    static serialize(input                          )                                                                                           {
        return {
            _parameters: input._parameters,
            _specification: input._specification
        };
    }
}

function normalizePropertyExpression   (value                               , specification                            )                          {
    if (isFunction(value)) {
        return (new StylePropertyFunction(value, specification)     );

    } else if (isExpression(value)) {
        const expression = createPropertyExpression(value, specification);
        if (expression.result === 'error') {
            // this should have been caught in validation
            throw new Error(expression.value.map(err => `${err.key}: ${err.message}`).join(', '));
        }
        return expression.value;

    } else {
        let constant      = value;
        if (typeof value === 'string' && specification.type === 'color') {
            constant = Color.parse(value);
        }
        return {
            kind: 'constant',
            evaluate: () => constant
        };
    }
}

// Zoom-dependent expressions may only use ["zoom"] as the input to a top-level "step" or "interpolate"
// expression (collectively referred to as a "curve"). The curve may be wrapped in one or more "let" or
// "coalesce" expressions.
function findZoomCurve(expression            )                                           {
    let result = null;
    if (expression instanceof Let) {
        result = findZoomCurve(expression.result);

    } else if (expression instanceof Coalesce) {
        for (const arg of expression.args) {
            result = findZoomCurve(arg);
            if (result) {
                break;
            }
        }

    } else if ((expression instanceof Step || expression instanceof Interpolate) &&
        expression.input instanceof CompoundExpression &&
        expression.input.name === 'zoom') {

        result = expression;
    }

    if (result instanceof ParsingError) {
        return result;
    }

    expression.eachChild((child) => {
        const childResult = findZoomCurve(child);
        if (childResult instanceof ParsingError) {
            result = childResult;
        } else if (!result && childResult) {
            result = new ParsingError('', '"zoom" expression may only be used as input to a top-level "step" or "interpolate" expression.');
        } else if (result && childResult && result !== childResult) {
            result = new ParsingError('', 'Only one zoom-based "step" or "interpolate" subexpression may be used in an expression.');
        }
    });

    return result;
}

function getExpectedType(spec                            )       {
    const types = {
        color: ColorType,
        string: StringType,
        number: NumberType,
        enum: StringType,
        boolean: BooleanType,
        formatted: FormattedType,
        resolvedImage: ResolvedImageType
    };

    if (spec.type === 'array') {
        return array$1(types[spec.value] || ValueType, spec.length);
    }

    return types[spec.type];
}

function getDefaultValue(spec                            )        {
    if (spec.type === 'color' && (isFunction(spec.default) || Array.isArray(spec.default))) {
        // Special case for heatmap-color: it uses the 'default:' to define a
        // default color ramp, but createExpression expects a simple value to fall
        // back to in case of runtime errors
        return new Color(0, 0, 0, 0);
    } else if (spec.type === 'color') {
        return Color.parse(spec.default) || null;
    } else if (spec.default === undefined) {
        return null;
    } else {
        return spec.default;
    }
}

//      

// Note: Do not inherit from Error. It breaks when transpiling to ES5.

class ValidationError {
                    
                        
                  

    constructor(key         , value                       , message        , identifier         ) {
        this.message = (key ? `${key}: ` : '') + message;
        if (identifier) this.identifier = identifier;

        if (value !== null && value !== undefined && value.__line__) {
            this.line = value.__line__;
        }
    }
}

//      


                                                     

                                    
                                       
  

function validateObject(options         )                         {
    const key = options.key;
    const object = options.value;
    const elementSpecs = options.valueSpec || {};
    const elementValidators = options.objectElementValidators || {};
    const style = options.style;
    const styleSpec = options.styleSpec;
    let errors = [];

    const type = getType(object);
    if (type !== 'object') {
        return [new ValidationError(key, object, `object expected, ${type} found`)];
    }

    for (const objectKey in object) {
        const elementSpecKey = objectKey.split('.')[0]; // treat 'paint.*' as 'paint'
        const elementSpec = elementSpecs[elementSpecKey] || elementSpecs['*'];

        let validateElement;
        if (elementValidators[elementSpecKey]) {
            validateElement = elementValidators[elementSpecKey];
        } else if (elementSpecs[elementSpecKey]) {
            validateElement = validate;
        } else if (elementValidators['*']) {
            validateElement = elementValidators['*'];
        } else if (elementSpecs['*']) {
            validateElement = validate;
        }

        if (!validateElement) {
            errors.push(new ValidationError(key, object[objectKey], `unknown property "${objectKey}"`));
            continue;
        }

        errors = errors.concat(validateElement({
            key: (key ? `${key}.` : key) + objectKey,
            value: object[objectKey],
            valueSpec: elementSpec,
            style,
            styleSpec,
            object,
            objectKey
        // $FlowFixMe[extra-arg]
        }, object));
    }

    for (const elementSpecKey in elementSpecs) {
        // Don't check `required` when there's a custom validator for that property.
        if (elementValidators[elementSpecKey]) {
            continue;
        }

        if (elementSpecs[elementSpecKey].required && elementSpecs[elementSpecKey]['default'] === undefined && object[elementSpecKey] === undefined) {
            errors.push(new ValidationError(key, object, `missing required property "${elementSpecKey}"`));
        }
    }

    return errors;
}

//      


                                                     

                                    
                                    
  

function validateArray(options         )                         {
    const array = options.value;
    const arraySpec = options.valueSpec;
    const style = options.style;
    const styleSpec = options.styleSpec;
    const key = options.key;
    const validateArrayElement = options.arrayElementValidator || validate;

    if (getType(array) !== 'array') {
        return [new ValidationError(key, array, `array expected, ${getType(array)} found`)];
    }

    if (arraySpec.length && array.length !== arraySpec.length) {
        return [new ValidationError(key, array, `array length ${arraySpec.length} expected, length ${array.length} found`)];
    }

    if (arraySpec['min-length'] && array.length < arraySpec['min-length']) {
        return [new ValidationError(key, array, `array length at least ${arraySpec['min-length']} expected, length ${array.length} found`)];
    }

    let arrayElementSpec = {
        "type": arraySpec.value,
        "values": arraySpec.values,
        "minimum": arraySpec.minimum,
        "maximum": arraySpec.maximum,
        function: undefined
    };

    if (styleSpec.$version < 7) {
        arrayElementSpec.function = arraySpec.function;
    }

    if (getType(arraySpec.value) === 'object') {
        arrayElementSpec = arraySpec.value;
    }

    let errors = [];
    for (let i = 0; i < array.length; i++) {
        errors = errors.concat(validateArrayElement({
            array,
            arrayIndex: i,
            value: array[i],
            valueSpec: arrayElementSpec,
            style,
            styleSpec,
            key: `${key}[${i}]`
        }));
    }
    return errors;
}

//      


                                                     

                                    
                       
 

function validateNumber(options         )                         {
    const key = options.key;
    const value = options.value;
    const valueSpec = options.valueSpec;
    let type = getType(value);

    // eslint-disable-next-line no-self-compare
    if (type === 'number' && value !== value) {
        type = 'NaN';
    }

    if (type !== 'number') {
        return [new ValidationError(key, value, `number expected, ${type} found`)];
    }

    if ('minimum' in valueSpec) {
        let specMin = valueSpec.minimum;
        if (getType(valueSpec.minimum) === 'array') {
            const i = options.arrayIndex;
            specMin = valueSpec.minimum[i];
        }
        if (value < specMin) {
            return [new ValidationError(key, value, `${value} is less than the minimum value ${specMin}`)];
        }
    }

    if ('maximum' in valueSpec) {
        let specMax = valueSpec.maximum;
        if (getType(valueSpec.maximum) === 'array') {
            const i = options.arrayIndex;
            specMax = valueSpec.maximum[i];
        }
        if (value > specMax) {
            return [new ValidationError(key, value, `${value} is greater than the maximum value ${specMax}`)];
        }
    }

    return [];
}

//      


                                                     

function validateFunction(options                   )      {
    const functionValueSpec = options.valueSpec;
    const functionType = unbundle(options.value.type);
    let stopKeyType;
    let stopDomainValues                               = {};
    let previousStopDomainValue        ;
    let previousStopDomainZoom;

    const isZoomFunction = functionType !== 'categorical' && options.value.property === undefined;
    const isPropertyFunction = !isZoomFunction;
    const isZoomAndPropertyFunction =
        getType(options.value.stops) === 'array' &&
        getType(options.value.stops[0]) === 'array' &&
        getType(options.value.stops[0][0]) === 'object';

    const errors = validateObject({
        key: options.key,
        value: options.value,
        valueSpec: options.styleSpec.function,
        style: options.style,
        styleSpec: options.styleSpec,
        objectElementValidators: {
            stops: validateFunctionStops,
            default: validateFunctionDefault
        }
    });

    if (functionType === 'identity' && isZoomFunction) {
        errors.push(new ValidationError(options.key, options.value, 'missing required property "property"'));
    }

    if (functionType !== 'identity' && !options.value.stops) {
        errors.push(new ValidationError(options.key, options.value, 'missing required property "stops"'));
    }

    if (functionType === 'exponential' && options.valueSpec.expression && !supportsInterpolation(options.valueSpec)) {
        errors.push(new ValidationError(options.key, options.value, 'exponential functions not supported'));
    }

    if (options.styleSpec.$version >= 8) {
        if (isPropertyFunction && !supportsPropertyExpression(options.valueSpec)) {
            errors.push(new ValidationError(options.key, options.value, 'property functions not supported'));
        } else if (isZoomFunction && !supportsZoomExpression(options.valueSpec)) {
            errors.push(new ValidationError(options.key, options.value, 'zoom functions not supported'));
        }
    }

    if ((functionType === 'categorical' || isZoomAndPropertyFunction) && options.value.property === undefined) {
        errors.push(new ValidationError(options.key, options.value, '"property" property is required'));
    }

    return errors;

    function validateFunctionStops(options                   ) {
        if (functionType === 'identity') {
            return [new ValidationError(options.key, options.value, 'identity function may not have a "stops" property')];
        }

        let errors = [];
        const value = options.value;

        errors = errors.concat(validateArray({
            key: options.key,
            value,
            valueSpec: options.valueSpec,
            style: options.style,
            styleSpec: options.styleSpec,
            arrayElementValidator: validateFunctionStop
        }));

        if (getType(value) === 'array' && value.length === 0) {
            errors.push(new ValidationError(options.key, value, 'array must have at least one stop'));
        }

        return errors;
    }

    function validateFunctionStop(options                   ) {
        let errors = [];
        const value = options.value;
        const key = options.key;

        if (getType(value) !== 'array') {
            return [new ValidationError(key, value, `array expected, ${getType(value)} found`)];
        }

        if (value.length !== 2) {
            return [new ValidationError(key, value, `array length 2 expected, length ${value.length} found`)];
        }

        if (isZoomAndPropertyFunction) {
            if (getType(value[0]) !== 'object') {
                return [new ValidationError(key, value, `object expected, ${getType(value[0])} found`)];
            }
            if (value[0].zoom === undefined) {
                return [new ValidationError(key, value, 'object stop key must have zoom')];
            }
            if (value[0].value === undefined) {
                return [new ValidationError(key, value, 'object stop key must have value')];
            }

            const nextStopDomainZoom = unbundle(value[0].zoom);
            if (typeof nextStopDomainZoom !== 'number') {
                return [new ValidationError(key, value[0].zoom, 'stop zoom values must be numbers')];
            }

            if (previousStopDomainZoom && previousStopDomainZoom > nextStopDomainZoom) {
                return [new ValidationError(key, value[0].zoom, 'stop zoom values must appear in ascending order')];
            }
            if (nextStopDomainZoom !== previousStopDomainZoom) {
                previousStopDomainZoom = nextStopDomainZoom;
                previousStopDomainValue = undefined;
                stopDomainValues = {};
            }
            errors = errors.concat(validateObject({
                key: `${key}[0]`,
                value: value[0],
                valueSpec: {zoom: {}},
                style: options.style,
                styleSpec: options.styleSpec,
                objectElementValidators: {zoom: validateNumber, value: validateStopDomainValue}
            }));
        } else {
            errors = errors.concat(validateStopDomainValue({
                key: `${key}[0]`,
                value: value[0],
                valueSpec: {},
                style: options.style,
                styleSpec: options.styleSpec
            }, value));
        }

        if (isExpression(deepUnbundle(value[1]))) {
            return errors.concat([new ValidationError(`${key}[1]`, value[1], 'expressions are not allowed in function stops.')]);
        }

        return errors.concat(validate({
            key: `${key}[1]`,
            value: value[1],
            valueSpec: functionValueSpec,
            style: options.style,
            styleSpec: options.styleSpec
        }));
    }

    function validateStopDomainValue(options                   , stop     ) {
        const type = getType(options.value);
        const value = unbundle(options.value);

        const reportValue = options.value !== null ? options.value : stop;

        if (!stopKeyType) {
            stopKeyType = type;
        } else if (type !== stopKeyType) {
            return [new ValidationError(options.key, reportValue, `${type} stop domain type must match previous stop domain type ${stopKeyType}`)];
        }

        if (type !== 'number' && type !== 'string' && type !== 'boolean' && typeof value !== 'number' && typeof value !== 'string' && typeof value !== 'boolean') {
            return [new ValidationError(options.key, reportValue, 'stop domain value must be a number, string, or boolean')];
        }

        if (type !== 'number' && functionType !== 'categorical') {
            let message = `number expected, ${type} found`;
            if (supportsPropertyExpression(functionValueSpec) && functionType === undefined) {
                message += '\nIf you intended to use a categorical function, specify `"type": "categorical"`.';
            }
            return [new ValidationError(options.key, reportValue, message)];
        }

        if (functionType === 'categorical' && type === 'number' && (typeof value !== 'number' || !isFinite(value) || Math.floor(value) !== value)) {
            return [new ValidationError(options.key, reportValue, `integer expected, found ${String(value)}`)];
        }

        if (functionType !== 'categorical' && type === 'number' && typeof value === 'number' && typeof previousStopDomainValue === 'number' && previousStopDomainValue !== undefined && value < previousStopDomainValue) {
            return [new ValidationError(options.key, reportValue, 'stop domain values must appear in ascending order')];
        } else {
            previousStopDomainValue = value;
        }

        if (functionType === 'categorical' && (value     ) in stopDomainValues) {
            return [new ValidationError(options.key, reportValue, 'stop domain values must be unique')];
        } else {
            stopDomainValues[(value     )] = true;
        }

        return [];
    }

    function validateFunctionDefault(options                   ) {
        return validate({
            key: options.key,
            value: options.value,
            valueSpec: functionValueSpec,
            style: options.style,
            styleSpec: options.styleSpec
        });
    }
}

//      


                                                            

function validateExpression(options     )                         {
    const expression = (options.expressionContext === 'property' ? createPropertyExpression : createExpression)(deepUnbundle(options.value), options.valueSpec);
    if (expression.result === 'error') {
        return expression.value.map((error) => {
            return new ValidationError(`${options.key}${error.key}`, options.value, error.message);
        });
    }

    const expressionObj = (expression.value     ).expression || (expression.value     )._styleExpression.expression;

    if (options.expressionContext === 'property' && (options.propertyKey === 'text-font') &&
        !expressionObj.outputDefined()) {
        return [new ValidationError(options.key, options.value, `Invalid data expression for "${options.propertyKey}". Output values must be contained as literals within the expression.`)];
    }

    if (options.expressionContext === 'property' && options.propertyType === 'layout' &&
        (!isStateConstant(expressionObj))) {
        return [new ValidationError(options.key, options.value, '"feature-state" data expressions are not supported with layout properties.')];
    }

    if (options.expressionContext === 'filter') {
        return disallowedFilterParameters(expressionObj, options);
    }

    if (options.expressionContext && options.expressionContext.indexOf('cluster') === 0) {
        if (!isGlobalPropertyConstant(expressionObj, ['zoom', 'feature-state'])) {
            return [new ValidationError(options.key, options.value, '"zoom" and "feature-state" expressions are not supported with cluster properties.')];
        }
        if (options.expressionContext === 'cluster-initial' && !isFeatureConstant(expressionObj)) {
            return [new ValidationError(options.key, options.value, 'Feature data expressions are not supported with initial expression part of cluster properties.')];
        }
    }

    return [];
}

function disallowedFilterParameters(e            , options     )                         {
    const disallowedParameters = new Set([
        'zoom',
        'feature-state',
        'pitch',
        'distance-from-center'
    ]);

    if (options.valueSpec && options.valueSpec.expression) {
        for (const param of options.valueSpec.expression.parameters) {
            disallowedParameters.delete(param);
        }
    }

    if (disallowedParameters.size === 0) {
        return [];
    }
    const errors = [];

    if (e instanceof CompoundExpression) {
        if (disallowedParameters.has(e.name)) {
            return [new ValidationError(options.key, options.value, `["${e.name}"] expression is not supported in a filter for a ${options.object.type} layer with id: ${options.object.id}`)];
        }
    }
    e.eachChild((arg) => {
        errors.push(...disallowedFilterParameters(arg, options));
    });

    return errors;
}

//      


                                                     

function validateBoolean(options                   )                         {
    const value = options.value;
    const key = options.key;
    const type = getType(value);

    if (type !== 'boolean') {
        return [new ValidationError(key, value, `boolean expected, ${type} found`)];
    }

    return [];
}

//      


                                                     

function validateColor(options                   )                         {
    const key = options.key;
    const value = options.value;
    const type = getType(value);

    if (type !== 'string') {
        return [new ValidationError(key, value, `color expected, ${type} found`)];
    }

    if (parseCSSColor_1(value) === null) {
        return [new ValidationError(key, value, `color expected, "${value}" found`)];
    }

    return [];
}

//      


                                                     

function validateEnum(options                   )                         {
    const key = options.key;
    const value = options.value;
    const valueSpec = options.valueSpec;
    const errors = [];

    if (Array.isArray(valueSpec.values)) { // <=v7
        if (valueSpec.values.indexOf(unbundle(value)) === -1) {
            errors.push(new ValidationError(key, value, `expected one of [${valueSpec.values.join(', ')}], ${JSON.stringify(value)} found`));
        }
    } else { // >=v8
        if (Object.keys(valueSpec.values).indexOf(unbundle(value)) === -1) {
            errors.push(new ValidationError(key, value, `expected one of [${Object.keys(valueSpec.values).join(', ')}], ${JSON.stringify(value)} found`));
        }
    }
    return errors;
}

//      


function isExpressionFilter(filter     )          {
    if (filter === true || filter === false) {
        return true;
    }

    if (!Array.isArray(filter) || filter.length === 0) {
        return false;
    }
    switch (filter[0]) {
    case 'has':
        return filter.length >= 2 && filter[1] !== '$id' && filter[1] !== '$type';

    case 'in':
        return filter.length >= 3 && (typeof filter[1] !== 'string' || Array.isArray(filter[2]));

    case '!in':
    case '!has':
    case 'none':
        return false;

    case '==':
    case '!=':
    case '>':
    case '>=':
    case '<':
    case '<=':
        return filter.length !== 3 || (Array.isArray(filter[1]) || Array.isArray(filter[2]));

    case 'any':
    case 'all':
        for (const f of filter.slice(1)) {
            if (!isExpressionFilter(f) && typeof f !== 'boolean') {
                return false;
            }
        }
        return true;

    default:
        return true;
    }
}

/**
 * Given a filter expressed as nested arrays, return a new function
 * that evaluates whether a given feature (with a .properties or .tags property)
 * passes its test.
 *
 * @private
 * @param {Array} filter mapbox gl filter
 * @param {string} layerType the type of the layer this filter will be applied to.
 * @returns {Function} filter-evaluating function
 */
function createFilter(filter     , layerType          = 'fill')                {
    if (filter === null || filter === undefined) {
        return {filter: () => true, needGeometry: false, needFeature: false};
    }

    if (!isExpressionFilter(filter)) {
        // $FlowFixMe[incompatible-call]
        filter = convertFilter(filter);
    }
    const filterExp = ((filter     )                             );

    let staticFilter = true;
    try {
        staticFilter = extractStaticFilter(filterExp);
    } catch (e) {
        console.warn(
`Failed to extract static filter. Filter will continue working, but at higher memory usage and slower framerate.
This is most likely a bug, please report this via https://github.com/mapbox/mapbox-gl-js/issues/new?assignees=&labels=&template=Bug_report.md
and paste the contents of this message in the report.
Thank you!
Filter Expression:
${JSON.stringify(filterExp, null, 2)}
        `);
    }

    // Compile the static component of the filter
    const filterSpec = spec[`filter_${layerType}`];
    const compiledStaticFilter = createExpression(staticFilter, filterSpec);

    let filterFunc = null;
    if (compiledStaticFilter.result === 'error') {
        throw new Error(compiledStaticFilter.value.map(err => `${err.key}: ${err.message}`).join(', '));
    } else {
        filterFunc = (globalProperties                  , feature         , canonical                  ) => compiledStaticFilter.value.evaluate(globalProperties, feature, {}, canonical);
    }

    // If the static component is not equal to the entire filter then we have a dynamic component
    // Compile the dynamic component separately
    let dynamicFilterFunc = null;
    let needFeature = null;
    if (staticFilter !== filterExp) {
        const compiledDynamicFilter = createExpression(filterExp, filterSpec);

        if (compiledDynamicFilter.result === 'error') {
            throw new Error(compiledDynamicFilter.value.map(err => `${err.key}: ${err.message}`).join(', '));
        } else {
            dynamicFilterFunc = (globalProperties                  , feature         , canonical                  , featureTileCoord        , featureDistanceData                      ) => compiledDynamicFilter.value.evaluate(globalProperties, feature, {}, canonical, undefined, undefined, featureTileCoord, featureDistanceData);
            needFeature = !isFeatureConstant(compiledDynamicFilter.value.expression);
        }
    }

    filterFunc = ((filterFunc     )                  );
    const needGeometry = geometryNeeded(staticFilter);

    return {
        filter: filterFunc,
        dynamicFilter: dynamicFilterFunc ? dynamicFilterFunc : undefined,
        needGeometry,
        needFeature: !!needFeature
    };
}

function extractStaticFilter(filter     )      {
    if (!isDynamicFilter(filter)) {
        return filter;
    }

    // Shallow copy so we can replace expressions in-place
    let result = deepUnbundle(filter);

    // 1. Union branches
    unionDynamicBranches(result);

    // 2. Collapse dynamic conditions to  `true`
    result = collapseDynamicBooleanExpressions(result);

    return result;
}

function collapseDynamicBooleanExpressions(expression     )      {
    if (!Array.isArray(expression)) {
        return expression;
    }

    const collapsed = collapsedExpression(expression);
    if (collapsed === true) {
        return collapsed;
    } else {
        return collapsed.map((subExpression) => collapseDynamicBooleanExpressions(subExpression));
    }
}

/**
 * Traverses the expression and replaces all instances of branching on a
 * `dynamic` conditional (such as `['pitch']` or `['distance-from-center']`)
 * into an `any` expression.
 * This ensures that all possible outcomes of a `dynamic` branch are considered
 * when evaluating the expression upfront during filtering.
 *
 * @param {Array<any>} filter the filter expression mutated in-place.
 */
function unionDynamicBranches(filter     ) {
    let isBranchingDynamically = false;
    const branches = [];

    if (filter[0] === 'case') {
        for (let i = 1; i < filter.length - 1; i += 2) {
            isBranchingDynamically = isBranchingDynamically || isDynamicFilter(filter[i]);
            branches.push(filter[i + 1]);
        }

        branches.push(filter[filter.length - 1]);
    } else if (filter[0] === 'match') {
        isBranchingDynamically = isBranchingDynamically || isDynamicFilter(filter[1]);

        for (let i = 2; i < filter.length - 1; i += 2) {
            branches.push(filter[i + 1]);
        }
        branches.push(filter[filter.length - 1]);
    } else if (filter[0] === 'step') {
        isBranchingDynamically = isBranchingDynamically || isDynamicFilter(filter[1]);

        for (let i = 1; i < filter.length - 1; i += 2) {
            branches.push(filter[i + 1]);
        }
    }

    if (isBranchingDynamically) {
        filter.length = 0;
        filter.push('any', ...branches);
    }

    // traverse and recurse into children
    for (let i = 1; i < filter.length; i++) {
        unionDynamicBranches(filter[i]);
    }
}

function isDynamicFilter(filter     )          {
    // Base Cases
    if (!Array.isArray(filter)) {
        return false;
    }
    if (isRootExpressionDynamic(filter[0])) {
        return true;
    }

    for (let i = 1; i < filter.length; i++) {
        const child = filter[i];
        if (isDynamicFilter(child)) {
            return true;
        }
    }

    return false;
}

function isRootExpressionDynamic(expression        )          {
    return expression === 'pitch' ||
        expression === 'distance-from-center';
}

const dynamicConditionExpressions = new Set([
    'in',
    '==',
    '!=',
    '>',
    '>=',
    '<',
    '<=',
    'to-boolean'
]);

function collapsedExpression(expression     )      {
    if (dynamicConditionExpressions.has(expression[0])) {

        for (let i = 1; i < expression.length; i++) {
            const param = expression[i];
            if (isDynamicFilter(param)) {
                return true;
            }
        }
    }
    return expression;
}

// Comparison function to sort numbers and strings
function compare(a        , b        ) {
    return a < b ? -1 : a > b ? 1 : 0;
}

function geometryNeeded(filter                      ) {
    if (!Array.isArray(filter)) return false;
    if (filter[0] === 'within') return true;
    for (let index = 1; index < filter.length; index++) {
        if (geometryNeeded(filter[index])) return true;
    }
    return false;
}

function convertFilter(filter             )        {
    if (!filter) return true;
    const op = filter[0];
    if (filter.length <= 1) return (op !== 'any');
    const converted =
        op === '==' ? convertComparisonOp(filter[1], filter[2], '==') :
        op === '!=' ? convertNegation(convertComparisonOp(filter[1], filter[2], '==')) :
        op === '<' ||
        op === '>' ||
        op === '<=' ||
        op === '>=' ? convertComparisonOp(filter[1], filter[2], op) :
        op === 'any' ? convertDisjunctionOp(filter.slice(1)) :
        op === 'all' ? ['all'].concat(filter.slice(1).map(convertFilter)) :
        op === 'none' ? ['all'].concat(filter.slice(1).map(convertFilter).map(convertNegation)) :
        op === 'in' ? convertInOp(filter[1], filter.slice(2)) :
        op === '!in' ? convertNegation(convertInOp(filter[1], filter.slice(2))) :
        op === 'has' ? convertHasOp(filter[1]) :
        op === '!has' ? convertNegation(convertHasOp(filter[1])) :
        op === 'within' ? filter :
        true;
    return converted;
}

function convertComparisonOp(property        , value     , op        ) {
    switch (property) {
    case '$type':
        return [`filter-type-${op}`, value];
    case '$id':
        return [`filter-id-${op}`, value];
    default:
        return [`filter-${op}`, property, value];
    }
}

function convertDisjunctionOp(filters                   ) {
    return ['any'].concat(filters.map(convertFilter));
}

function convertInOp(property        , values            ) {
    if (values.length === 0) { return false; }
    switch (property) {
    case '$type':
        return [`filter-type-in`, ['literal', values]];
    case '$id':
        return [`filter-id-in`, ['literal', values]];
    default:
        if (values.length > 200 && !values.some(v => typeof v !== typeof values[0])) {
            return ['filter-in-large', property, ['literal', values.sort(compare)]];
        } else {
            return ['filter-in-small', property, ['literal', values]];
        }
    }
}

function convertHasOp(property        ) {
    switch (property) {
    case '$type':
        return true;
    case '$id':
        return [`filter-has-id`];
    default:
        return [`filter-has`, property];
    }
}

function convertNegation(filter       ) {
    return ['!', filter];
}

//      


                                                     

                                    
                       
 

function validateFilter$1(options         )                         {
    if (isExpressionFilter(deepUnbundle(options.value))) {
        // We default to a layerType of `fill` because that points to a non-dynamic filter definition within the style-spec.
        const layerType = options.layerType || 'fill';

        return validateExpression(extend({}, options, {
            expressionContext: 'filter',
            valueSpec: options.styleSpec[`filter_${layerType}`]
        }));
    } else {
        return validateNonExpressionFilter(options);
    }
}

function validateNonExpressionFilter(options         ) {
    const value = options.value;
    const key = options.key;

    if (getType(value) !== 'array') {
        return [new ValidationError(key, value, `array expected, ${getType(value)} found`)];
    }

    const styleSpec = options.styleSpec;
    let type;

    let errors = [];

    if (value.length < 1) {
        return [new ValidationError(key, value, 'filter array must have at least 1 element')];
    }

    errors = errors.concat(validateEnum({
        key: `${key}[0]`,
        value: value[0],
        valueSpec: styleSpec.filter_operator,
        style: options.style,
        styleSpec: options.styleSpec
    }));

    switch (unbundle(value[0])) {
    case '<':
    case '<=':
    case '>':
    case '>=':
        if (value.length >= 2 && unbundle(value[1]) === '$type') {
            errors.push(new ValidationError(key, value, `"$type" cannot be use with operator "${value[0]}"`));
        }
        /* falls through */
    case '==':
    case '!=':
        if (value.length !== 3) {
            errors.push(new ValidationError(key, value, `filter array for operator "${value[0]}" must have 3 elements`));
        }
        /* falls through */
    case 'in':
    case '!in':
        if (value.length >= 2) {
            type = getType(value[1]);
            if (type !== 'string') {
                errors.push(new ValidationError(`${key}[1]`, value[1], `string expected, ${type} found`));
            }
        }
        for (let i = 2; i < value.length; i++) {
            type = getType(value[i]);
            if (unbundle(value[1]) === '$type') {
                errors = errors.concat(validateEnum({
                    key: `${key}[${i}]`,
                    value: value[i],
                    valueSpec: styleSpec.geometry_type,
                    style: options.style,
                    styleSpec: options.styleSpec
                }));
            } else if (type !== 'string' && type !== 'number' && type !== 'boolean') {
                errors.push(new ValidationError(`${key}[${i}]`, value[i], `string, number, or boolean expected, ${type} found`));
            }
        }
        break;

    case 'any':
    case 'all':
    case 'none':
        for (let i = 1; i < value.length; i++) {
            errors = errors.concat(validateNonExpressionFilter(({
                key: `${key}[${i}]`,
                value: value[i],
                style: options.style,
                styleSpec: options.styleSpec
            }     )));
        }
        break;

    case 'has':
    case '!has':
        type = getType(value[1]);
        if (value.length !== 2) {
            errors.push(new ValidationError(key, value, `filter array for "${value[0]}" operator must have 2 elements`));
        } else if (type !== 'string') {
            errors.push(new ValidationError(`${key}[1]`, value[1], `string expected, ${type} found`));
        }
        break;
    case 'within':
        type = getType(value[1]);
        if (value.length !== 2) {
            errors.push(new ValidationError(key, value, `filter array for "${value[0]}" operator must have 2 elements`));
        } else if (type !== 'object') {
            errors.push(new ValidationError(`${key}[1]`, value[1], `object expected, ${type} found`));
        }
        break;
    }
    return errors;
}

//      


                                                     

                                                             
                      
                      
 

function validateProperty(options                           , propertyType        )                         {
    const key = options.key;
    const style = options.style;
    const styleSpec = options.styleSpec;
    const value = options.value;
    const propertyKey = options.objectKey;
    const layerSpec = styleSpec[`${propertyType}_${options.layerType}`];

    if (!layerSpec) return [];

    const transitionMatch = propertyKey.match(/^(.*)-transition$/);
    if (propertyType === 'paint' && transitionMatch && layerSpec[transitionMatch[1]] && layerSpec[transitionMatch[1]].transition) {
        return validate({
            key,
            value,
            valueSpec: styleSpec.transition,
            style,
            styleSpec
        });
    }

    const valueSpec = options.valueSpec || layerSpec[propertyKey];
    if (!valueSpec) {
        return [new ValidationError(key, value, `unknown property "${propertyKey}"`)];
    }

    let tokenMatch                     ;
    if (getType(value) === 'string' && supportsPropertyExpression(valueSpec) && !valueSpec.tokens && (tokenMatch = /^{([^}]+)}$/.exec(value))) {
        const example = `\`{ "type": "identity", "property": ${tokenMatch ? JSON.stringify(tokenMatch[1]) : '"_"'} }\``;
        return [new ValidationError(
            key, value,
            `"${propertyKey}" does not support interpolation syntax\n` +
                `Use an identity property function instead: ${example}.`)];
    }

    const errors = [];

    if (options.layerType === 'symbol') {
        if (propertyKey === 'text-field' && style && !style.glyphs) {
            errors.push(new ValidationError(key, value, 'use of "text-field" requires a style "glyphs" property'));
        }
        if (propertyKey === 'text-font' && isFunction(deepUnbundle(value)) && unbundle(value.type) === 'identity') {
            errors.push(new ValidationError(key, value, '"text-font" does not support identity functions'));
        }
    }

    return errors.concat(validate({
        key: options.key,
        value,
        valueSpec,
        style,
        styleSpec,
        expressionContext: 'property',
        propertyType,
        propertyKey
    }));
}

//      


                                                                
                                                                      

function validatePaintProperty$1(options                           )                         {
    return validateProperty(options, 'paint');
}

//      


                                                                
                                                                      

function validateLayoutProperty$1(options                           )                         {
    return validateProperty(options, 'layout');
}

//      


                                                     
                                                    

                                    
                              
                       
 

function validateLayer$1(options         )                         {
    let errors = [];

    const layer = options.value;
    const key = options.key;
    const style = options.style;
    const styleSpec = options.styleSpec;

    if (!layer.type && !layer.ref) {
        errors.push(new ValidationError(key, layer, 'either "type" or "ref" is required'));
    }
    let type = unbundle(layer.type);
    const ref = unbundle(layer.ref);

    if (layer.id) {
        const layerId = unbundle(layer.id);
        for (let i = 0; i < options.arrayIndex; i++) {
            const otherLayer = style.layers[i];
            if (unbundle(otherLayer.id) === layerId) {
                // $FlowFixMe[prop-missing] - id.__line__ is added dynamically during the readStyle step
                errors.push(new ValidationError(key, layer.id, `duplicate layer id "${layer.id}", previously used at line ${otherLayer.id.__line__}`));
            }
        }
    }

    if ('ref' in layer) {
        ['type', 'source', 'source-layer', 'filter', 'layout'].forEach((p) => {
            if (p in layer) {
                errors.push(new ValidationError(key, layer[p], `"${p}" is prohibited for ref layers`));
            }
        });

        let parent;

        style.layers.forEach((layer) => {
            if (unbundle(layer.id) === ref) parent = layer;
        });

        if (!parent) {
            if (typeof ref === 'string')
                errors.push(new ValidationError(key, layer.ref, `ref layer "${ref}" not found`));
        // $FlowFixMe[prop-missing] - ref is not defined on the LayerSpecification subtypes
        } else if (parent.ref) {
            errors.push(new ValidationError(key, layer.ref, 'ref cannot reference another ref layer'));
        } else {
            type = unbundle(parent.type);
        }
    } else if (!(type === 'background' || type === 'sky')) {
        if (!layer.source) {
            errors.push(new ValidationError(key, layer, 'missing required property "source"'));
        } else {
            const source = style.sources && style.sources[layer.source];
            const sourceType = source && unbundle(source.type);
            if (!source) {
                errors.push(new ValidationError(key, layer.source, `source "${layer.source}" not found`));
            } else if (sourceType === 'vector' && type === 'raster') {
                errors.push(new ValidationError(key, layer.source, `layer "${layer.id}" requires a raster source`));
            } else if (sourceType === 'raster' && type !== 'raster') {
                errors.push(new ValidationError(key, layer.source, `layer "${layer.id}" requires a vector source`));
            } else if (sourceType === 'vector' && !layer['source-layer']) {
                errors.push(new ValidationError(key, layer, `layer "${layer.id}" must specify a "source-layer"`));
            } else if (sourceType === 'raster-dem' && type !== 'hillshade') {
                errors.push(new ValidationError(key, layer.source, 'raster-dem source can only be used with layer type \'hillshade\'.'));
            } else if (type === 'line' && layer.paint && (layer.paint['line-gradient'] || layer.paint['line-trim-offset']) &&
                       (sourceType !== 'geojson' || !source.lineMetrics)) {
                errors.push(new ValidationError(key, layer, `layer "${layer.id}" specifies a line-gradient, which requires a GeoJSON source with \`lineMetrics\` enabled.`));
            }
        }
    }

    errors = errors.concat(validateObject({
        key,
        value: layer,
        valueSpec: styleSpec.layer,
        style: options.style,
        styleSpec: options.styleSpec,
        objectElementValidators: {
            '*'() {
                return [];
            },
            // We don't want to enforce the spec's `"requires": true` for backward compatibility with refs;
            // the actual requirement is validated above. See https://github.com/mapbox/mapbox-gl-js/issues/5772.
            type() {
                return validate({
                    key: `${key}.type`,
                    value: layer.type,
                    valueSpec: styleSpec.layer.type,
                    style: options.style,
                    styleSpec: options.styleSpec,
                    object: layer,
                    objectKey: 'type'
                });
            },
            filter(options) {
                return validateFilter$1(extend({layerType: type}, options));
            },
            layout(options) {
                return validateObject({
                    layer,
                    key: options.key,
                    value: options.value,
                    valueSpec: {},
                    style: options.style,
                    styleSpec: options.styleSpec,
                    objectElementValidators: {
                        '*'(options) {
                            return validateLayoutProperty$1(extend({layerType: type}, options));
                        }
                    }
                });
            },
            paint(options) {
                return validateObject({
                    layer,
                    key: options.key,
                    value: options.value,
                    valueSpec: {},
                    style: options.style,
                    styleSpec: options.styleSpec,
                    objectElementValidators: {
                        '*'(options) {
                            return validatePaintProperty$1(extend({layerType: type}, options));
                        }
                    }
                });
            }
        }
    }));

    return errors;
}

//      


                                                     

function validateString(options                           )                         {
    const value = options.value;
    const key = options.key;
    const type = getType(value);

    if (type !== 'string') {
        return [new ValidationError(key, value, `string expected, ${type} found`)];
    }

    return [];
}

//      


                                                           
                                                     

const objectElementValidators = {
    promoteId: validatePromoteId
};

function validateSource$1(options                   )                         {
    const value = options.value;
    const key = options.key;
    const styleSpec = options.styleSpec;
    const style = options.style;

    if (!value.type) {
        return [new ValidationError(key, value, '"type" is required')];
    }

    const type = unbundle(value.type);
    let errors;

    switch (type) {
    case 'vector':
    case 'raster':
    case 'raster-dem':
        errors = validateObject({
            key,
            value,
            valueSpec: styleSpec[`source_${type.replace('-', '_')}`],
            style: options.style,
            styleSpec,
            objectElementValidators
        });
        return errors;

    case 'geojson':
        errors = validateObject({
            key,
            value,
            valueSpec: styleSpec.source_geojson,
            style,
            styleSpec,
            objectElementValidators
        });
        if (value.cluster) {
            for (const prop in value.clusterProperties) {
                const [operator, mapExpr] = value.clusterProperties[prop];
                const reduceExpr = typeof operator === 'string' ? [operator, ['accumulated'], ['get', prop]] : operator;

                errors.push(...validateExpression({
                    key: `${key}.${prop}.map`,
                    value: mapExpr,
                    expressionContext: 'cluster-map'
                }));
                errors.push(...validateExpression({
                    key: `${key}.${prop}.reduce`,
                    value: reduceExpr,
                    expressionContext: 'cluster-reduce'
                }));
            }
        }
        return errors;

    case 'video':
        return validateObject({
            key,
            value,
            valueSpec: styleSpec.source_video,
            style,
            styleSpec
        });

    case 'image':
        return validateObject({
            key,
            value,
            valueSpec: styleSpec.source_image,
            style,
            styleSpec
        });

    case 'canvas':
        return [new ValidationError(key, null, `Please use runtime APIs to add canvas sources, rather than including them in stylesheets.`, 'source.canvas')];

    default:
        return validateEnum({
            key: `${key}.type`,
            value: value.type,
            valueSpec: {values: getSourceTypeValues(styleSpec)},
            style,
            styleSpec
        });
    }
}

function getSourceTypeValues(styleSpec                ) {
    return styleSpec.source.reduce((memo, source) => {
        const sourceType = styleSpec[source];
        if (sourceType.type.type === 'enum') {
            memo = memo.concat(Object.keys(sourceType.type.values));
        }
        return memo;
    }, []);
}

function validatePromoteId({key, value}                           ) {
    if (getType(value) === 'string') {
        return validateString({key, value});
    } else {
        const errors = [];
        for (const prop in value) {
            errors.push(...validateString({key: `${key}.${prop}`, value: value[prop]}));
        }
        return errors;
    }
}

//      


                                                     

function validateLight$1(options                   )                         {
    const light = options.value;
    const styleSpec = options.styleSpec;
    const lightSpec = styleSpec.light;
    const style = options.style;

    let errors = [];

    const rootType = getType(light);
    if (light === undefined) {
        return errors;
    } else if (rootType !== 'object') {
        errors = errors.concat([new ValidationError('light', light, `object expected, ${rootType} found`)]);
        return errors;
    }

    for (const key in light) {
        const transitionMatch = key.match(/^(.*)-transition$/);

        if (transitionMatch && lightSpec[transitionMatch[1]] && lightSpec[transitionMatch[1]].transition) {
            errors = errors.concat(validate({
                key,
                value: light[key],
                valueSpec: styleSpec.transition,
                style,
                styleSpec
            }));
        } else if (lightSpec[key]) {
            errors = errors.concat(validate({
                key,
                value: light[key],
                valueSpec: lightSpec[key],
                style,
                styleSpec
            }));
        } else {
            errors = errors.concat([new ValidationError(key, light[key], `unknown property "${key}"`)]);
        }
    }

    return errors;
}

//      


                                                     

function validateTerrain$1(options                   )                         {
    const terrain = options.value;
    const key = options.key;
    const style = options.style;
    const styleSpec = options.styleSpec;
    const terrainSpec = styleSpec.terrain;
    let errors = [];

    const rootType = getType(terrain);
    if (terrain === undefined) {
        return errors;
    } else if (rootType !== 'object') {
        errors = errors.concat([new ValidationError('terrain', terrain, `object expected, ${rootType} found`)]);
        return errors;
    }

    for (const key in terrain) {
        const transitionMatch = key.match(/^(.*)-transition$/);

        if (transitionMatch && terrainSpec[transitionMatch[1]] && terrainSpec[transitionMatch[1]].transition) {
            errors = errors.concat(validate({
                key,
                value: terrain[key],
                valueSpec: styleSpec.transition,
                style,
                styleSpec
            }));
        } else if (terrainSpec[key]) {
            errors = errors.concat(validate({
                key,
                value: terrain[key],
                valueSpec: terrainSpec[key],
                style,
                styleSpec
            }));
        } else {
            errors = errors.concat([new ValidationError(key, terrain[key], `unknown property "${key}"`)]);
        }
    }

    if (!terrain.source) {
        errors.push(new ValidationError(key, terrain, `terrain is missing required property "source"`));
    } else {
        const source = style.sources && style.sources[terrain.source];
        const sourceType = source && unbundle(source.type);
        if (!source) {
            errors.push(new ValidationError(key, terrain.source, `source "${terrain.source}" not found`));
        } else if (sourceType !== 'raster-dem') {
            errors.push(new ValidationError(key, terrain.source, `terrain cannot be used with a source of type ${String(sourceType)}, it only be used with a "raster-dem" source type`));
        }
    }

    return errors;
}

//      


                                                     

function validateFog$1(options                   )                         {
    const fog = options.value;
    const style = options.style;
    const styleSpec = options.styleSpec;
    const fogSpec = styleSpec.fog;
    let errors = [];

    const rootType = getType(fog);
    if (fog === undefined) {
        return errors;
    } else if (rootType !== 'object') {
        errors = errors.concat([new ValidationError('fog', fog, `object expected, ${rootType} found`)]);
        return errors;
    }

    for (const key in fog) {
        const transitionMatch = key.match(/^(.*)-transition$/);

        if (transitionMatch && fogSpec[transitionMatch[1]] && fogSpec[transitionMatch[1]].transition) {
            errors = errors.concat(validate({
                key,
                value: fog[key],
                valueSpec: styleSpec.transition,
                style,
                styleSpec
            }));
        } else if (fogSpec[key]) {
            errors = errors.concat(validate({
                key,
                value: fog[key],
                valueSpec: fogSpec[key],
                style,
                styleSpec
            }));
        } else {
            errors = errors.concat([new ValidationError(key, fog[key], `unknown property "${key}"`)]);
        }
    }

    return errors;
}

//      


                                                     
                                                                

function validateFormatted(options                   )                         {
    if (validateString(options).length === 0) {
        return [];
    }

    return validateExpression(options);
}

//      


                                                     
                                                                

function validateImage(options                   )                         {
    if (validateString(options).length === 0) {
        return [];
    }

    return validateExpression(options);
}

//      


                                                     

function validateProjection(options                   )                         {
    const projection = options.value;
    const styleSpec = options.styleSpec;
    const projectionSpec = styleSpec.projection;
    const style = options.style;

    let errors = [];

    const rootType = getType(projection);

    if (rootType === 'object') {
        for (const key in projection) {
            errors = errors.concat(validate({
                key,
                value: projection[key],
                valueSpec: projectionSpec[key],
                style,
                styleSpec
            }));
        }
    } else if (rootType !== 'string') {
        errors = errors.concat([new ValidationError('projection', projection, `object or string expected, ${rootType} found`)]);
    }

    return errors;
}

//      


                                                           
                                                    
                                                                

const VALIDATORS = {
    '*'() {
        return [];
    },
    'array': validateArray,
    'boolean': validateBoolean,
    'number': validateNumber,
    'color': validateColor,
    'enum': validateEnum,
    'filter': validateFilter$1,
    'function': validateFunction,
    'layer': validateLayer$1,
    'object': validateObject,
    'source': validateSource$1,
    'light': validateLight$1,
    'terrain': validateTerrain$1,
    'fog': validateFog$1,
    'string': validateString,
    'formatted': validateFormatted,
    'resolvedImage': validateImage,
    'projection': validateProjection
};

// Main recursive validation function. Tracks:
//
// - key: string representing location of validation in style tree. Used only
//   for more informative error reporting.
// - value: current value from style being evaluated. May be anything from a
//   high level object that needs to be descended into deeper or a simple
//   scalar value.
// - valueSpec: current spec being evaluated. Tracks value.
// - styleSpec: current full spec being evaluated.
                                 
                
                  
                      
                                      
                              
 

function validate(options                   )                         {
    const value = options.value;
    const valueSpec = options.valueSpec;
    const styleSpec = options.styleSpec;

    if (valueSpec.expression && isFunction(unbundle(value))) {
        return validateFunction(options);

    } else if (valueSpec.expression && isExpression(deepUnbundle(value))) {
        return validateExpression(options);

    } else if (valueSpec.type && VALIDATORS[valueSpec.type]) {
        return VALIDATORS[valueSpec.type](options);

    } else {
        const valid = validateObject(extend({}, options, {
            valueSpec: valueSpec.type ? styleSpec[valueSpec.type] : valueSpec
        }));
        return valid;
    }
}

//      


                                                     

function validateGlyphsURL(options                   )                         {
    const value = options.value;
    const key = options.key;

    const errors = validateString(options);
    if (errors.length) return errors;

    if (value.indexOf('{fontstack}') === -1) {
        errors.push(new ValidationError(key, value, '"glyphs" url must include a "{fontstack}" token'));
    }

    if (value.indexOf('{range}') === -1) {
        errors.push(new ValidationError(key, value, '"glyphs" url must include a "{range}" token'));
    }

    return errors;
}

//      

                                                   

                                         
                    
                         
                   
  
                                                               
                                                     

/**
 * Validate a Mapbox GL style against the style specification. This entrypoint,
 * `mapbox-gl-style-spec/lib/validate_style.min`, is designed to produce as
 * small a browserify bundle as possible by omitting unnecessary functionality
 * and legacy style specifications.
 *
 * @private
 * @param {Object} style The style to be validated.
 * @param {Object} [styleSpec] The style specification to validate against.
 *     If omitted, the latest style spec is used.
 * @returns {Array<ValidationError>}
 * @example
 *   var validate = require('mapbox-gl-style-spec/lib/validate_style.min');
 *   var errors = validate(style);
 */
function validateStyle(style                    , styleSpec         = spec)                   {

    const errors = validate({
        key: '',
        value: style,
        valueSpec: styleSpec.$root,
        styleSpec,
        style,
        objectElementValidators: {
            glyphs: validateGlyphsURL,
            '*': () => []
        }
    });
    return sortErrors(errors);
}

const validateSource            = opts => sortErrors(validateSource$1(opts));
const validateLight            = opts => sortErrors(validateLight$1(opts));
const validateTerrain            = opts => sortErrors(validateTerrain$1(opts));
const validateFog            = opts => sortErrors(validateFog$1(opts));
const validateLayer            = opts => sortErrors(validateLayer$1(opts));
const validateFilter            = opts => sortErrors(validateFilter$1(opts));
const validatePaintProperty            = opts => sortErrors(validatePaintProperty$1(opts));
const validateLayoutProperty            = opts => sortErrors(validateLayoutProperty$1(opts));

function sortErrors(errors                  ) {
    return errors.slice().sort((a, b) => a.line && b.line ? a.line - b.line : 0);
}

//      

                                                
                                                                                               

                                                                                     

function emitValidationErrors(emitter         , errors                    )          {
    let hasErrors = false;
    if (errors && errors.length) {
        for (const error of errors) {
            emitter.fire(new ErrorEvent(new Error(error.message)));
            hasErrors = true;
        }
    }
    return hasErrors;
}

'use strict';

var gridIndex = GridIndex;

var NUM_PARAMS = 3;

function GridIndex(extent, n, padding) {
    var cells = this.cells = [];

    if (extent instanceof ArrayBuffer) {
        this.arrayBuffer = extent;
        var array = new Int32Array(this.arrayBuffer);
        extent = array[0];
        n = array[1];
        padding = array[2];

        this.d = n + 2 * padding;
        for (var k = 0; k < this.d * this.d; k++) {
            var start = array[NUM_PARAMS + k];
            var end = array[NUM_PARAMS + k + 1];
            cells.push(start === end ?
                    null :
                    array.subarray(start, end));
        }
        var keysOffset = array[NUM_PARAMS + cells.length];
        var bboxesOffset = array[NUM_PARAMS + cells.length + 1];
        this.keys = array.subarray(keysOffset, bboxesOffset);
        this.bboxes = array.subarray(bboxesOffset);

        this.insert = this._insertReadonly;

    } else {
        this.d = n + 2 * padding;
        for (var i = 0; i < this.d * this.d; i++) {
            cells.push([]);
        }
        this.keys = [];
        this.bboxes = [];
    }

    this.n = n;
    this.extent = extent;
    this.padding = padding;
    this.scale = n / extent;
    this.uid = 0;

    var p = (padding / n) * extent;
    this.min = -p;
    this.max = extent + p;
}


GridIndex.prototype.insert = function(key, x1, y1, x2, y2) {
    this._forEachCell(x1, y1, x2, y2, this._insertCell, this.uid++);
    this.keys.push(key);
    this.bboxes.push(x1);
    this.bboxes.push(y1);
    this.bboxes.push(x2);
    this.bboxes.push(y2);
};

GridIndex.prototype._insertReadonly = function() {
    throw 'Cannot insert into a GridIndex created from an ArrayBuffer.';
};

GridIndex.prototype._insertCell = function(x1, y1, x2, y2, cellIndex, uid) {
    this.cells[cellIndex].push(uid);
};

GridIndex.prototype.query = function(x1, y1, x2, y2, intersectionTest) {
    var min = this.min;
    var max = this.max;
    if (x1 <= min && y1 <= min && max <= x2 && max <= y2 && !intersectionTest) {
        // We use `Array#slice` because `this.keys` may be a `Int32Array` and
        // some browsers (Safari and IE) do not support `TypedArray#slice`
        // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice#Browser_compatibility
        return Array.prototype.slice.call(this.keys);

    } else {
        var result = [];
        var seenUids = {};
        this._forEachCell(x1, y1, x2, y2, this._queryCell, result, seenUids, intersectionTest);
        return result;
    }
};

GridIndex.prototype._queryCell = function(x1, y1, x2, y2, cellIndex, result, seenUids, intersectionTest) {
    var cell = this.cells[cellIndex];
    if (cell !== null) {
        var keys = this.keys;
        var bboxes = this.bboxes;
        for (var u = 0; u < cell.length; u++) {
            var uid = cell[u];
            if (seenUids[uid] === undefined) {
                var offset = uid * 4;
                if (intersectionTest ?
                    intersectionTest(bboxes[offset + 0], bboxes[offset + 1], bboxes[offset + 2], bboxes[offset + 3]) :
                    ((x1 <= bboxes[offset + 2]) &&
                    (y1 <= bboxes[offset + 3]) &&
                    (x2 >= bboxes[offset + 0]) &&
                    (y2 >= bboxes[offset + 1]))) {
                    seenUids[uid] = true;
                    result.push(keys[uid]);
                } else {
                    seenUids[uid] = false;
                }
            }
        }
    }
};

GridIndex.prototype._forEachCell = function(x1, y1, x2, y2, fn, arg1, arg2, intersectionTest) {
    var cx1 = this._convertToCellCoord(x1);
    var cy1 = this._convertToCellCoord(y1);
    var cx2 = this._convertToCellCoord(x2);
    var cy2 = this._convertToCellCoord(y2);
    for (var x = cx1; x <= cx2; x++) {
        for (var y = cy1; y <= cy2; y++) {
            var cellIndex = this.d * y + x;
            if (intersectionTest && !intersectionTest(
                        this._convertFromCellCoord(x),
                        this._convertFromCellCoord(y),
                        this._convertFromCellCoord(x + 1),
                        this._convertFromCellCoord(y + 1))) continue;
            if (fn.call(this, x1, y1, x2, y2, cellIndex, arg1, arg2, intersectionTest)) return;
        }
    }
};

GridIndex.prototype._convertFromCellCoord = function(x) {
    return (x - this.padding) / this.scale;
};

GridIndex.prototype._convertToCellCoord = function(x) {
    return Math.max(0, Math.min(this.d - 1, Math.floor(x * this.scale) + this.padding));
};

GridIndex.prototype.toArrayBuffer = function() {
    if (this.arrayBuffer) return this.arrayBuffer;

    var cells = this.cells;

    var metadataLength = NUM_PARAMS + this.cells.length + 1 + 1;
    var totalCellLength = 0;
    for (var i = 0; i < this.cells.length; i++) {
        totalCellLength += this.cells[i].length;
    }

    var array = new Int32Array(metadataLength + totalCellLength + this.keys.length + this.bboxes.length);
    array[0] = this.extent;
    array[1] = this.n;
    array[2] = this.padding;

    var offset = metadataLength;
    for (var k = 0; k < cells.length; k++) {
        var cell = cells[k];
        array[NUM_PARAMS + k] = offset;
        array.set(cell, offset);
        offset += cell.length;
    }

    array[NUM_PARAMS + cells.length] = offset;
    array.set(this.keys, offset);
    offset += this.keys.length;

    array[NUM_PARAMS + cells.length + 1] = offset;
    array.set(this.bboxes, offset);
    offset += this.bboxes.length;

    return array.buffer;
};

var Grid = /*@__PURE__*/getDefaultExportFromCjs(gridIndex);

//      


                                                           

                                                              
                        
          
          
             
            
            
             
            
            
          
            
                 
                      
               
                       
                       

                 
                  
                          
                                    
     
  

                           
                                   
 

const registry           = {};

/**
 * Register the given class as serializable.
 *
 * @param options
 * @param options.omit List of properties to omit from serialization (e.g., cached/computed properties)
 *
 * @private
 */
function register        (klass          , name        , options                     = {}) {
    assert$1(name, 'Can\'t register a class without a name.');
    assert$1(!registry[name], `${name} is already registered.`);
    (Object.defineProperty     )(klass, '_classRegistryKey', {
        value: name,
        writeable: false
    });
    registry[name] = {
        klass,
        omit: options.omit || []
    };
}

register(Object, 'Object');

                                              

(Grid     ).serialize = function serialize(grid      , transferables                      )                 {
    const buffer = grid.toArrayBuffer();
    if (transferables) {
        transferables.push(buffer);
    }
    return {buffer};
};

(Grid     ).deserialize = function deserialize(serialized                )       {
    return new Grid(serialized.buffer);
};

Object.defineProperty(Grid, 'name', {value: 'Grid'});

register(Grid, 'Grid');

register(Color, 'Color');
register(Error, 'Error');
register(AJAXError, 'AJAXError');
register(ResolvedImage, 'ResolvedImage');
register(StylePropertyFunction, 'StylePropertyFunction');
register(StyleExpression, 'StyleExpression', {omit: ['_evaluator']});

register(ZoomDependentExpression, 'ZoomDependentExpression');
register(ZoomConstantExpression, 'ZoomConstantExpression');
register(CompoundExpression, 'CompoundExpression', {omit: ['_evaluate']});
for (const name in expressions) {
    if (!registry[(expressions[name]     )._classRegistryKey]) register(expressions[name], `Expression${name}`);
}

function isArrayBuffer(val     )          {
    return val && typeof ArrayBuffer !== 'undefined' &&
           (val instanceof ArrayBuffer || (val.constructor && val.constructor.name === 'ArrayBuffer'));
}

function isImageBitmap(val     )          {
    return window$1.ImageBitmap &&
        val instanceof window$1.ImageBitmap;
}

/**
 * Serialize the given object for transfer to or from a web worker.
 *
 * For non-builtin types, recursively serialize each property (possibly
 * omitting certain properties - see register()), and package the result along
 * with the constructor's `name` so that the appropriate constructor can be
 * looked up in `deserialize()`.
 *
 * If a `transferables` array is provided, add any transferable objects (i.e.,
 * any ArrayBuffers or ArrayBuffer views) to the list. (If a copy is needed,
 * this should happen in the client code, before using serialize().)
 *
 * @private
 */
function serialize(input       , transferables                      )             {
    if (input === null ||
        input === undefined ||
        typeof input === 'boolean' ||
        typeof input === 'number' ||
        typeof input === 'string' ||
        input instanceof Boolean ||
        input instanceof Number ||
        input instanceof String ||
        input instanceof Date ||
        input instanceof RegExp) {
        return input;
    }

    if (isArrayBuffer(input) || isImageBitmap(input)) {
        if (transferables) {
            transferables.push(((input     )             ));
        }
        return (input     );
    }

    if (ArrayBuffer.isView(input)) {
        const view                   = (input     );
        if (transferables) {
            transferables.push(view.buffer);
        }
        return view;
    }

    if (input instanceof window$1.ImageData) {
        if (transferables) {
            transferables.push(input.data.buffer);
        }
        return input;
    }

    if (Array.isArray(input)) {
        const serialized                    = [];
        for (const item of input) {
            serialized.push(serialize(item, transferables));
        }
        return serialized;
    }

    if (typeof input === 'object') {
        const klass = (input.constructor     );
        const name = klass._classRegistryKey;
        if (!name) {
            throw new Error(`can't serialize object of unregistered class ${name}`);
        }
        assert$1(registry[name]);

        const properties                   = klass.serialize ?
            // (Temporary workaround) allow a class to provide static
            // `serialize()` and `deserialize()` methods to bypass the generic
            // approach.
            // This temporary workaround lets us use the generic serialization
            // approach for objects whose members include instances of dynamic
            // StructArray types. Once we refactor StructArray to be static,
            // we can remove this complexity.
            (klass.serialize(input, transferables)                  ) : {};

        if (!klass.serialize) {
            for (const key in input) {
                // any cast due to https://github.com/facebook/flow/issues/5393
                if (!(input     ).hasOwnProperty(key)) continue;
                if (registry[name].omit.indexOf(key) >= 0) continue;
                const property = (input     )[key];
                properties[key] = serialize(property, transferables);
            }
            if (input instanceof Error) {
                properties['message'] = input.message;
            }
        } else {
            // make sure statically serialized object survives transfer of $name property
            assert$1(!transferables || properties !== transferables[transferables.length - 1]);
        }

        if (properties['$name']) {
            throw new Error('$name property is reserved for worker serialization logic.');
        }
        if (name !== 'Object') {
            properties['$name'] = name;
        }

        return properties;
    }

    throw new Error(`can't serialize object of type ${typeof input}`);
}

function deserialize$1(input            )        {
    if (input === null ||
        input === undefined ||
        typeof input === 'boolean' ||
        typeof input === 'number' ||
        typeof input === 'string' ||
        input instanceof Boolean ||
        input instanceof Number ||
        input instanceof String ||
        input instanceof Date ||
        input instanceof RegExp ||
        isArrayBuffer(input) ||
        isImageBitmap(input) ||
        ArrayBuffer.isView(input) ||
        input instanceof window$1.ImageData) {
        return input;
    }

    if (Array.isArray(input)) {
        return input.map(deserialize$1);
    }

    if (typeof input === 'object') {
        const name = (input     ).$name || 'Object';

        const {klass} = registry[name];
        if (!klass) {
            throw new Error(`can't deserialize unregistered class ${name}`);
        }

        if (klass.deserialize) {
            return (klass.deserialize                    )(input);
        }

        const result                     = Object.create(klass.prototype);

        for (const key of Object.keys(input)) {
            // $FlowFixMe[incompatible-type]
            if (key === '$name') continue;
            const value = (input                  )[key];
            result[key] = deserialize$1(value);
        }

        return result;
    }

    throw new Error(`can't deserialize object of type ${typeof input}`);
}

//      

// The following table comes from <http://www.unicode.org/Public/12.0.0/ucd/Blocks.txt>.
// Keep it synchronized with <http://www.unicode.org/Public/UCD/latest/ucd/Blocks.txt>.

                                                                     

const unicodeBlockLookup                     = {
    // 'Basic Latin': (char) => char >= 0x0000 && char <= 0x007F,
    'Latin-1 Supplement': (char) => char >= 0x0080 && char <= 0x00FF,
    // 'Latin Extended-A': (char) => char >= 0x0100 && char <= 0x017F,
    // 'Latin Extended-B': (char) => char >= 0x0180 && char <= 0x024F,
    // 'IPA Extensions': (char) => char >= 0x0250 && char <= 0x02AF,
    // 'Spacing Modifier Letters': (char) => char >= 0x02B0 && char <= 0x02FF,
    // 'Combining Diacritical Marks': (char) => char >= 0x0300 && char <= 0x036F,
    // 'Greek and Coptic': (char) => char >= 0x0370 && char <= 0x03FF,
    // 'Cyrillic': (char) => char >= 0x0400 && char <= 0x04FF,
    // 'Cyrillic Supplement': (char) => char >= 0x0500 && char <= 0x052F,
    // 'Armenian': (char) => char >= 0x0530 && char <= 0x058F,
    //'Hebrew': (char) => char >= 0x0590 && char <= 0x05FF,
    'Arabic': (char) => char >= 0x0600 && char <= 0x06FF,
    //'Syriac': (char) => char >= 0x0700 && char <= 0x074F,
    'Arabic Supplement': (char) => char >= 0x0750 && char <= 0x077F,
    // 'Thaana': (char) => char >= 0x0780 && char <= 0x07BF,
    // 'NKo': (char) => char >= 0x07C0 && char <= 0x07FF,
    // 'Samaritan': (char) => char >= 0x0800 && char <= 0x083F,
    // 'Mandaic': (char) => char >= 0x0840 && char <= 0x085F,
    // 'Syriac Supplement': (char) => char >= 0x0860 && char <= 0x086F,
    'Arabic Extended-A': (char) => char >= 0x08A0 && char <= 0x08FF,
    // 'Devanagari': (char) => char >= 0x0900 && char <= 0x097F,
    // 'Bengali': (char) => char >= 0x0980 && char <= 0x09FF,
    // 'Gurmukhi': (char) => char >= 0x0A00 && char <= 0x0A7F,
    // 'Gujarati': (char) => char >= 0x0A80 && char <= 0x0AFF,
    // 'Oriya': (char) => char >= 0x0B00 && char <= 0x0B7F,
    // 'Tamil': (char) => char >= 0x0B80 && char <= 0x0BFF,
    // 'Telugu': (char) => char >= 0x0C00 && char <= 0x0C7F,
    // 'Kannada': (char) => char >= 0x0C80 && char <= 0x0CFF,
    // 'Malayalam': (char) => char >= 0x0D00 && char <= 0x0D7F,
    // 'Sinhala': (char) => char >= 0x0D80 && char <= 0x0DFF,
    // 'Thai': (char) => char >= 0x0E00 && char <= 0x0E7F,
    // 'Lao': (char) => char >= 0x0E80 && char <= 0x0EFF,
    // 'Tibetan': (char) => char >= 0x0F00 && char <= 0x0FFF,
    // 'Myanmar': (char) => char >= 0x1000 && char <= 0x109F,
    // 'Georgian': (char) => char >= 0x10A0 && char <= 0x10FF,
    'Hangul Jamo': (char) => char >= 0x1100 && char <= 0x11FF,
    // 'Ethiopic': (char) => char >= 0x1200 && char <= 0x137F,
    // 'Ethiopic Supplement': (char) => char >= 0x1380 && char <= 0x139F,
    // 'Cherokee': (char) => char >= 0x13A0 && char <= 0x13FF,
    'Unified Canadian Aboriginal Syllabics': (char) => char >= 0x1400 && char <= 0x167F,
    // 'Ogham': (char) => char >= 0x1680 && char <= 0x169F,
    // 'Runic': (char) => char >= 0x16A0 && char <= 0x16FF,
    // 'Tagalog': (char) => char >= 0x1700 && char <= 0x171F,
    // 'Hanunoo': (char) => char >= 0x1720 && char <= 0x173F,
    // 'Buhid': (char) => char >= 0x1740 && char <= 0x175F,
    // 'Tagbanwa': (char) => char >= 0x1760 && char <= 0x177F,
    'Khmer': (char) => char >= 0x1780 && char <= 0x17FF,
    // 'Mongolian': (char) => char >= 0x1800 && char <= 0x18AF,
    'Unified Canadian Aboriginal Syllabics Extended': (char) => char >= 0x18B0 && char <= 0x18FF,
    // 'Limbu': (char) => char >= 0x1900 && char <= 0x194F,
    // 'Tai Le': (char) => char >= 0x1950 && char <= 0x197F,
    // 'New Tai Lue': (char) => char >= 0x1980 && char <= 0x19DF,
    // 'Khmer Symbols': (char) => char >= 0x19E0 && char <= 0x19FF,
    // 'Buginese': (char) => char >= 0x1A00 && char <= 0x1A1F,
    // 'Tai Tham': (char) => char >= 0x1A20 && char <= 0x1AAF,
    // 'Combining Diacritical Marks Extended': (char) => char >= 0x1AB0 && char <= 0x1AFF,
    // 'Balinese': (char) => char >= 0x1B00 && char <= 0x1B7F,
    // 'Sundanese': (char) => char >= 0x1B80 && char <= 0x1BBF,
    // 'Batak': (char) => char >= 0x1BC0 && char <= 0x1BFF,
    // 'Lepcha': (char) => char >= 0x1C00 && char <= 0x1C4F,
    // 'Ol Chiki': (char) => char >= 0x1C50 && char <= 0x1C7F,
    // 'Cyrillic Extended-C': (char) => char >= 0x1C80 && char <= 0x1C8F,
    // 'Georgian Extended': (char) => char >= 0x1C90 && char <= 0x1CBF,
    // 'Sundanese Supplement': (char) => char >= 0x1CC0 && char <= 0x1CCF,
    // 'Vedic Extensions': (char) => char >= 0x1CD0 && char <= 0x1CFF,
    // 'Phonetic Extensions': (char) => char >= 0x1D00 && char <= 0x1D7F,
    // 'Phonetic Extensions Supplement': (char) => char >= 0x1D80 && char <= 0x1DBF,
    // 'Combining Diacritical Marks Supplement': (char) => char >= 0x1DC0 && char <= 0x1DFF,
    // 'Latin Extended Additional': (char) => char >= 0x1E00 && char <= 0x1EFF,
    // 'Greek Extended': (char) => char >= 0x1F00 && char <= 0x1FFF,
    'General Punctuation': (char) => char >= 0x2000 && char <= 0x206F,
    // 'Superscripts and Subscripts': (char) => char >= 0x2070 && char <= 0x209F,
    // 'Currency Symbols': (char) => char >= 0x20A0 && char <= 0x20CF,
    // 'Combining Diacritical Marks for Symbols': (char) => char >= 0x20D0 && char <= 0x20FF,
    'Letterlike Symbols': (char) => char >= 0x2100 && char <= 0x214F,
    'Number Forms': (char) => char >= 0x2150 && char <= 0x218F,
    // 'Arrows': (char) => char >= 0x2190 && char <= 0x21FF,
    // 'Mathematical Operators': (char) => char >= 0x2200 && char <= 0x22FF,
    'Miscellaneous Technical': (char) => char >= 0x2300 && char <= 0x23FF,
    'Control Pictures': (char) => char >= 0x2400 && char <= 0x243F,
    'Optical Character Recognition': (char) => char >= 0x2440 && char <= 0x245F,
    'Enclosed Alphanumerics': (char) => char >= 0x2460 && char <= 0x24FF,
    // 'Box Drawing': (char) => char >= 0x2500 && char <= 0x257F,
    // 'Block Elements': (char) => char >= 0x2580 && char <= 0x259F,
    'Geometric Shapes': (char) => char >= 0x25A0 && char <= 0x25FF,
    'Miscellaneous Symbols': (char) => char >= 0x2600 && char <= 0x26FF,
    // 'Dingbats': (char) => char >= 0x2700 && char <= 0x27BF,
    // 'Miscellaneous Mathematical Symbols-A': (char) => char >= 0x27C0 && char <= 0x27EF,
    // 'Supplemental Arrows-A': (char) => char >= 0x27F0 && char <= 0x27FF,
    // 'Braille Patterns': (char) => char >= 0x2800 && char <= 0x28FF,
    // 'Supplemental Arrows-B': (char) => char >= 0x2900 && char <= 0x297F,
    // 'Miscellaneous Mathematical Symbols-B': (char) => char >= 0x2980 && char <= 0x29FF,
    // 'Supplemental Mathematical Operators': (char) => char >= 0x2A00 && char <= 0x2AFF,
    'Miscellaneous Symbols and Arrows': (char) => char >= 0x2B00 && char <= 0x2BFF,
    // 'Glagolitic': (char) => char >= 0x2C00 && char <= 0x2C5F,
    // 'Latin Extended-C': (char) => char >= 0x2C60 && char <= 0x2C7F,
    // 'Coptic': (char) => char >= 0x2C80 && char <= 0x2CFF,
    // 'Georgian Supplement': (char) => char >= 0x2D00 && char <= 0x2D2F,
    // 'Tifinagh': (char) => char >= 0x2D30 && char <= 0x2D7F,
    // 'Ethiopic Extended': (char) => char >= 0x2D80 && char <= 0x2DDF,
    // 'Cyrillic Extended-A': (char) => char >= 0x2DE0 && char <= 0x2DFF,
    // 'Supplemental Punctuation': (char) => char >= 0x2E00 && char <= 0x2E7F,
    'CJK Radicals Supplement': (char) => char >= 0x2E80 && char <= 0x2EFF,
    'Kangxi Radicals': (char) => char >= 0x2F00 && char <= 0x2FDF,
    'Ideographic Description Characters': (char) => char >= 0x2FF0 && char <= 0x2FFF,
    'CJK Symbols and Punctuation': (char) => char >= 0x3000 && char <= 0x303F,
    'Hiragana': (char) => char >= 0x3040 && char <= 0x309F,
    'Katakana': (char) => char >= 0x30A0 && char <= 0x30FF,
    'Bopomofo': (char) => char >= 0x3100 && char <= 0x312F,
    'Hangul Compatibility Jamo': (char) => char >= 0x3130 && char <= 0x318F,
    'Kanbun': (char) => char >= 0x3190 && char <= 0x319F,
    'Bopomofo Extended': (char) => char >= 0x31A0 && char <= 0x31BF,
    'CJK Strokes': (char) => char >= 0x31C0 && char <= 0x31EF,
    'Katakana Phonetic Extensions': (char) => char >= 0x31F0 && char <= 0x31FF,
    'Enclosed CJK Letters and Months': (char) => char >= 0x3200 && char <= 0x32FF,
    'CJK Compatibility': (char) => char >= 0x3300 && char <= 0x33FF,
    'CJK Unified Ideographs Extension A': (char) => char >= 0x3400 && char <= 0x4DBF,
    'Yijing Hexagram Symbols': (char) => char >= 0x4DC0 && char <= 0x4DFF,
    'CJK Unified Ideographs': (char) => char >= 0x4E00 && char <= 0x9FFF,
    'Yi Syllables': (char) => char >= 0xA000 && char <= 0xA48F,
    'Yi Radicals': (char) => char >= 0xA490 && char <= 0xA4CF,
    // 'Lisu': (char) => char >= 0xA4D0 && char <= 0xA4FF,
    // 'Vai': (char) => char >= 0xA500 && char <= 0xA63F,
    // 'Cyrillic Extended-B': (char) => char >= 0xA640 && char <= 0xA69F,
    // 'Bamum': (char) => char >= 0xA6A0 && char <= 0xA6FF,
    // 'Modifier Tone Letters': (char) => char >= 0xA700 && char <= 0xA71F,
    // 'Latin Extended-D': (char) => char >= 0xA720 && char <= 0xA7FF,
    // 'Syloti Nagri': (char) => char >= 0xA800 && char <= 0xA82F,
    // 'Common Indic Number Forms': (char) => char >= 0xA830 && char <= 0xA83F,
    // 'Phags-pa': (char) => char >= 0xA840 && char <= 0xA87F,
    // 'Saurashtra': (char) => char >= 0xA880 && char <= 0xA8DF,
    // 'Devanagari Extended': (char) => char >= 0xA8E0 && char <= 0xA8FF,
    // 'Kayah Li': (char) => char >= 0xA900 && char <= 0xA92F,
    // 'Rejang': (char) => char >= 0xA930 && char <= 0xA95F,
    'Hangul Jamo Extended-A': (char) => char >= 0xA960 && char <= 0xA97F,
    // 'Javanese': (char) => char >= 0xA980 && char <= 0xA9DF,
    // 'Myanmar Extended-B': (char) => char >= 0xA9E0 && char <= 0xA9FF,
    // 'Cham': (char) => char >= 0xAA00 && char <= 0xAA5F,
    // 'Myanmar Extended-A': (char) => char >= 0xAA60 && char <= 0xAA7F,
    // 'Tai Viet': (char) => char >= 0xAA80 && char <= 0xAADF,
    // 'Meetei Mayek Extensions': (char) => char >= 0xAAE0 && char <= 0xAAFF,
    // 'Ethiopic Extended-A': (char) => char >= 0xAB00 && char <= 0xAB2F,
    // 'Latin Extended-E': (char) => char >= 0xAB30 && char <= 0xAB6F,
    // 'Cherokee Supplement': (char) => char >= 0xAB70 && char <= 0xABBF,
    // 'Meetei Mayek': (char) => char >= 0xABC0 && char <= 0xABFF,
    'Hangul Syllables': (char) => char >= 0xAC00 && char <= 0xD7AF,
    'Hangul Jamo Extended-B': (char) => char >= 0xD7B0 && char <= 0xD7FF,
    // 'High Surrogates': (char) => char >= 0xD800 && char <= 0xDB7F,
    // 'High Private Use Surrogates': (char) => char >= 0xDB80 && char <= 0xDBFF,
    // 'Low Surrogates': (char) => char >= 0xDC00 && char <= 0xDFFF,
    'Private Use Area': (char) => char >= 0xE000 && char <= 0xF8FF,
    'CJK Compatibility Ideographs': (char) => char >= 0xF900 && char <= 0xFAFF,
    // 'Alphabetic Presentation Forms': (char) => char >= 0xFB00 && char <= 0xFB4F,
    'Arabic Presentation Forms-A': (char) => char >= 0xFB50 && char <= 0xFDFF,
    // 'Variation Selectors': (char) => char >= 0xFE00 && char <= 0xFE0F,
    'Vertical Forms': (char) => char >= 0xFE10 && char <= 0xFE1F,
    // 'Combining Half Marks': (char) => char >= 0xFE20 && char <= 0xFE2F,
    'CJK Compatibility Forms': (char) => char >= 0xFE30 && char <= 0xFE4F,
    'Small Form Variants': (char) => char >= 0xFE50 && char <= 0xFE6F,
    'Arabic Presentation Forms-B': (char) => char >= 0xFE70 && char <= 0xFEFF,
    'Halfwidth and Fullwidth Forms': (char) => char >= 0xFF00 && char <= 0xFFEF
    // 'Specials': (char) => char >= 0xFFF0 && char <= 0xFFFF,
    // 'Linear B Syllabary': (char) => char >= 0x10000 && char <= 0x1007F,
    // 'Linear B Ideograms': (char) => char >= 0x10080 && char <= 0x100FF,
    // 'Aegean Numbers': (char) => char >= 0x10100 && char <= 0x1013F,
    // 'Ancient Greek Numbers': (char) => char >= 0x10140 && char <= 0x1018F,
    // 'Ancient Symbols': (char) => char >= 0x10190 && char <= 0x101CF,
    // 'Phaistos Disc': (char) => char >= 0x101D0 && char <= 0x101FF,
    // 'Lycian': (char) => char >= 0x10280 && char <= 0x1029F,
    // 'Carian': (char) => char >= 0x102A0 && char <= 0x102DF,
    // 'Coptic Epact Numbers': (char) => char >= 0x102E0 && char <= 0x102FF,
    // 'Old Italic': (char) => char >= 0x10300 && char <= 0x1032F,
    // 'Gothic': (char) => char >= 0x10330 && char <= 0x1034F,
    // 'Old Permic': (char) => char >= 0x10350 && char <= 0x1037F,
    // 'Ugaritic': (char) => char >= 0x10380 && char <= 0x1039F,
    // 'Old Persian': (char) => char >= 0x103A0 && char <= 0x103DF,
    // 'Deseret': (char) => char >= 0x10400 && char <= 0x1044F,
    // 'Shavian': (char) => char >= 0x10450 && char <= 0x1047F,
    // 'Osmanya': (char) => char >= 0x10480 && char <= 0x104AF,
    // 'Osage': (char) => char >= 0x104B0 && char <= 0x104FF,
    // 'Elbasan': (char) => char >= 0x10500 && char <= 0x1052F,
    // 'Caucasian Albanian': (char) => char >= 0x10530 && char <= 0x1056F,
    // 'Linear A': (char) => char >= 0x10600 && char <= 0x1077F,
    // 'Cypriot Syllabary': (char) => char >= 0x10800 && char <= 0x1083F,
    // 'Imperial Aramaic': (char) => char >= 0x10840 && char <= 0x1085F,
    // 'Palmyrene': (char) => char >= 0x10860 && char <= 0x1087F,
    // 'Nabataean': (char) => char >= 0x10880 && char <= 0x108AF,
    // 'Hatran': (char) => char >= 0x108E0 && char <= 0x108FF,
    // 'Phoenician': (char) => char >= 0x10900 && char <= 0x1091F,
    // 'Lydian': (char) => char >= 0x10920 && char <= 0x1093F,
    // 'Meroitic Hieroglyphs': (char) => char >= 0x10980 && char <= 0x1099F,
    // 'Meroitic Cursive': (char) => char >= 0x109A0 && char <= 0x109FF,
    // 'Kharoshthi': (char) => char >= 0x10A00 && char <= 0x10A5F,
    // 'Old South Arabian': (char) => char >= 0x10A60 && char <= 0x10A7F,
    // 'Old North Arabian': (char) => char >= 0x10A80 && char <= 0x10A9F,
    // 'Manichaean': (char) => char >= 0x10AC0 && char <= 0x10AFF,
    // 'Avestan': (char) => char >= 0x10B00 && char <= 0x10B3F,
    // 'Inscriptional Parthian': (char) => char >= 0x10B40 && char <= 0x10B5F,
    // 'Inscriptional Pahlavi': (char) => char >= 0x10B60 && char <= 0x10B7F,
    // 'Psalter Pahlavi': (char) => char >= 0x10B80 && char <= 0x10BAF,
    // 'Old Turkic': (char) => char >= 0x10C00 && char <= 0x10C4F,
    // 'Old Hungarian': (char) => char >= 0x10C80 && char <= 0x10CFF,
    // 'Hanifi Rohingya': (char) => char >= 0x10D00 && char <= 0x10D3F,
    // 'Rumi Numeral Symbols': (char) => char >= 0x10E60 && char <= 0x10E7F,
    // 'Old Sogdian': (char) => char >= 0x10F00 && char <= 0x10F2F,
    // 'Sogdian': (char) => char >= 0x10F30 && char <= 0x10F6F,
    // 'Elymaic': (char) => char >= 0x10FE0 && char <= 0x10FFF,
    // 'Brahmi': (char) => char >= 0x11000 && char <= 0x1107F,
    // 'Kaithi': (char) => char >= 0x11080 && char <= 0x110CF,
    // 'Sora Sompeng': (char) => char >= 0x110D0 && char <= 0x110FF,
    // 'Chakma': (char) => char >= 0x11100 && char <= 0x1114F,
    // 'Mahajani': (char) => char >= 0x11150 && char <= 0x1117F,
    // 'Sharada': (char) => char >= 0x11180 && char <= 0x111DF,
    // 'Sinhala Archaic Numbers': (char) => char >= 0x111E0 && char <= 0x111FF,
    // 'Khojki': (char) => char >= 0x11200 && char <= 0x1124F,
    // 'Multani': (char) => char >= 0x11280 && char <= 0x112AF,
    // 'Khudawadi': (char) => char >= 0x112B0 && char <= 0x112FF,
    // 'Grantha': (char) => char >= 0x11300 && char <= 0x1137F,
    // 'Newa': (char) => char >= 0x11400 && char <= 0x1147F,
    // 'Tirhuta': (char) => char >= 0x11480 && char <= 0x114DF,
    // 'Siddham': (char) => char >= 0x11580 && char <= 0x115FF,
    // 'Modi': (char) => char >= 0x11600 && char <= 0x1165F,
    // 'Mongolian Supplement': (char) => char >= 0x11660 && char <= 0x1167F,
    // 'Takri': (char) => char >= 0x11680 && char <= 0x116CF,
    // 'Ahom': (char) => char >= 0x11700 && char <= 0x1173F,
    // 'Dogra': (char) => char >= 0x11800 && char <= 0x1184F,
    // 'Warang Citi': (char) => char >= 0x118A0 && char <= 0x118FF,
    // 'Nandinagari': (char) => char >= 0x119A0 && char <= 0x119FF,
    // 'Zanabazar Square': (char) => char >= 0x11A00 && char <= 0x11A4F,
    // 'Soyombo': (char) => char >= 0x11A50 && char <= 0x11AAF,
    // 'Pau Cin Hau': (char) => char >= 0x11AC0 && char <= 0x11AFF,
    // 'Bhaiksuki': (char) => char >= 0x11C00 && char <= 0x11C6F,
    // 'Marchen': (char) => char >= 0x11C70 && char <= 0x11CBF,
    // 'Masaram Gondi': (char) => char >= 0x11D00 && char <= 0x11D5F,
    // 'Gunjala Gondi': (char) => char >= 0x11D60 && char <= 0x11DAF,
    // 'Makasar': (char) => char >= 0x11EE0 && char <= 0x11EFF,
    // 'Tamil Supplement': (char) => char >= 0x11FC0 && char <= 0x11FFF,
    // 'Cuneiform': (char) => char >= 0x12000 && char <= 0x123FF,
    // 'Cuneiform Numbers and Punctuation': (char) => char >= 0x12400 && char <= 0x1247F,
    // 'Early Dynastic Cuneiform': (char) => char >= 0x12480 && char <= 0x1254F,
    // 'Egyptian Hieroglyphs': (char) => char >= 0x13000 && char <= 0x1342F,
    // 'Egyptian Hieroglyph Format Controls': (char) => char >= 0x13430 && char <= 0x1343F,
    // 'Anatolian Hieroglyphs': (char) => char >= 0x14400 && char <= 0x1467F,
    // 'Bamum Supplement': (char) => char >= 0x16800 && char <= 0x16A3F,
    // 'Mro': (char) => char >= 0x16A40 && char <= 0x16A6F,
    // 'Bassa Vah': (char) => char >= 0x16AD0 && char <= 0x16AFF,
    // 'Pahawh Hmong': (char) => char >= 0x16B00 && char <= 0x16B8F,
    // 'Medefaidrin': (char) => char >= 0x16E40 && char <= 0x16E9F,
    // 'Miao': (char) => char >= 0x16F00 && char <= 0x16F9F,
    // 'Ideographic Symbols and Punctuation': (char) => char >= 0x16FE0 && char <= 0x16FFF,
    // 'Tangut': (char) => char >= 0x17000 && char <= 0x187FF,
    // 'Tangut Components': (char) => char >= 0x18800 && char <= 0x18AFF,
    // 'Kana Supplement': (char) => char >= 0x1B000 && char <= 0x1B0FF,
    // 'Kana Extended-A': (char) => char >= 0x1B100 && char <= 0x1B12F,
    // 'Small Kana Extension': (char) => char >= 0x1B130 && char <= 0x1B16F,
    // 'Nushu': (char) => char >= 0x1B170 && char <= 0x1B2FF,
    // 'Duployan': (char) => char >= 0x1BC00 && char <= 0x1BC9F,
    // 'Shorthand Format Controls': (char) => char >= 0x1BCA0 && char <= 0x1BCAF,
    // 'Byzantine Musical Symbols': (char) => char >= 0x1D000 && char <= 0x1D0FF,
    // 'Musical Symbols': (char) => char >= 0x1D100 && char <= 0x1D1FF,
    // 'Ancient Greek Musical Notation': (char) => char >= 0x1D200 && char <= 0x1D24F,
    // 'Mayan Numerals': (char) => char >= 0x1D2E0 && char <= 0x1D2FF,
    // 'Tai Xuan Jing Symbols': (char) => char >= 0x1D300 && char <= 0x1D35F,
    // 'Counting Rod Numerals': (char) => char >= 0x1D360 && char <= 0x1D37F,
    // 'Mathematical Alphanumeric Symbols': (char) => char >= 0x1D400 && char <= 0x1D7FF,
    // 'Sutton SignWriting': (char) => char >= 0x1D800 && char <= 0x1DAAF,
    // 'Glagolitic Supplement': (char) => char >= 0x1E000 && char <= 0x1E02F,
    // 'Nyiakeng Puachue Hmong': (char) => char >= 0x1E100 && char <= 0x1E14F,
    // 'Wancho': (char) => char >= 0x1E2C0 && char <= 0x1E2FF,
    // 'Mende Kikakui': (char) => char >= 0x1E800 && char <= 0x1E8DF,
    // 'Adlam': (char) => char >= 0x1E900 && char <= 0x1E95F,
    // 'Indic Siyaq Numbers': (char) => char >= 0x1EC70 && char <= 0x1ECBF,
    // 'Ottoman Siyaq Numbers': (char) => char >= 0x1ED00 && char <= 0x1ED4F,
    // 'Arabic Mathematical Alphabetic Symbols': (char) => char >= 0x1EE00 && char <= 0x1EEFF,
    // 'Mahjong Tiles': (char) => char >= 0x1F000 && char <= 0x1F02F,
    // 'Domino Tiles': (char) => char >= 0x1F030 && char <= 0x1F09F,
    // 'Playing Cards': (char) => char >= 0x1F0A0 && char <= 0x1F0FF,
    // 'Enclosed Alphanumeric Supplement': (char) => char >= 0x1F100 && char <= 0x1F1FF,
    // 'Enclosed Ideographic Supplement': (char) => char >= 0x1F200 && char <= 0x1F2FF,
    // 'Miscellaneous Symbols and Pictographs': (char) => char >= 0x1F300 && char <= 0x1F5FF,
    // 'Emoticons': (char) => char >= 0x1F600 && char <= 0x1F64F,
    // 'Ornamental Dingbats': (char) => char >= 0x1F650 && char <= 0x1F67F,
    // 'Transport and Map Symbols': (char) => char >= 0x1F680 && char <= 0x1F6FF,
    // 'Alchemical Symbols': (char) => char >= 0x1F700 && char <= 0x1F77F,
    // 'Geometric Shapes Extended': (char) => char >= 0x1F780 && char <= 0x1F7FF,
    // 'Supplemental Arrows-C': (char) => char >= 0x1F800 && char <= 0x1F8FF,
    // 'Supplemental Symbols and Pictographs': (char) => char >= 0x1F900 && char <= 0x1F9FF,
    // 'Chess Symbols': (char) => char >= 0x1FA00 && char <= 0x1FA6F,
    // 'Symbols and Pictographs Extended-A': (char) => char >= 0x1FA70 && char <= 0x1FAFF,
    // 'CJK Unified Ideographs Extension B': (char) => char >= 0x20000 && char <= 0x2A6DF,
    // 'CJK Unified Ideographs Extension C': (char) => char >= 0x2A700 && char <= 0x2B73F,
    // 'CJK Unified Ideographs Extension D': (char) => char >= 0x2B740 && char <= 0x2B81F,
    // 'CJK Unified Ideographs Extension E': (char) => char >= 0x2B820 && char <= 0x2CEAF,
    // 'CJK Unified Ideographs Extension F': (char) => char >= 0x2CEB0 && char <= 0x2EBEF,
    // 'CJK Compatibility Ideographs Supplement': (char) => char >= 0x2F800 && char <= 0x2FA1F,
    // 'Tags': (char) => char >= 0xE0000 && char <= 0xE007F,
    // 'Variation Selectors Supplement': (char) => char >= 0xE0100 && char <= 0xE01EF,
    // 'Supplementary Private Use Area-A': (char) => char >= 0xF0000 && char <= 0xFFFFF,
    // 'Supplementary Private Use Area-B': (char) => char >= 0x100000 && char <= 0x10FFFF,
};

//      


function allowsIdeographicBreaking(chars        )          {
    for (const char of chars) {
        if (!charAllowsIdeographicBreaking(char.charCodeAt(0))) return false;
    }
    return true;
}

function allowsVerticalWritingMode(chars        )          {
    for (const char of chars) {
        if (charHasUprightVerticalOrientation(char.charCodeAt(0))) return true;
    }
    return false;
}

function allowsLetterSpacing(chars        )          {
    for (const char of chars) {
        if (!charAllowsLetterSpacing(char.charCodeAt(0))) return false;
    }
    return true;
}

function charAllowsLetterSpacing(char        )          {
    if (unicodeBlockLookup['Arabic'](char)) return false;
    if (unicodeBlockLookup['Arabic Supplement'](char)) return false;
    if (unicodeBlockLookup['Arabic Extended-A'](char)) return false;
    if (unicodeBlockLookup['Arabic Presentation Forms-A'](char)) return false;
    if (unicodeBlockLookup['Arabic Presentation Forms-B'](char)) return false;

    return true;
}

function charAllowsIdeographicBreaking(char        )          {
    // Return early for characters outside all ideographic ranges.
    if (char < 0x2E80) return false;

    if (unicodeBlockLookup['Bopomofo Extended'](char)) return true;
    if (unicodeBlockLookup['Bopomofo'](char)) return true;
    if (unicodeBlockLookup['CJK Compatibility Forms'](char)) return true;
    if (unicodeBlockLookup['CJK Compatibility Ideographs'](char)) return true;
    if (unicodeBlockLookup['CJK Compatibility'](char)) return true;
    if (unicodeBlockLookup['CJK Radicals Supplement'](char)) return true;
    if (unicodeBlockLookup['CJK Strokes'](char)) return true;
    if (unicodeBlockLookup['CJK Symbols and Punctuation'](char)) return true;
    if (unicodeBlockLookup['CJK Unified Ideographs Extension A'](char)) return true;
    if (unicodeBlockLookup['CJK Unified Ideographs'](char)) return true;
    if (unicodeBlockLookup['Enclosed CJK Letters and Months'](char)) return true;
    if (unicodeBlockLookup['Halfwidth and Fullwidth Forms'](char)) return true;
    if (unicodeBlockLookup['Hiragana'](char)) return true;
    if (unicodeBlockLookup['Ideographic Description Characters'](char)) return true;
    if (unicodeBlockLookup['Kangxi Radicals'](char)) return true;
    if (unicodeBlockLookup['Katakana Phonetic Extensions'](char)) return true;
    if (unicodeBlockLookup['Katakana'](char)) return true;
    if (unicodeBlockLookup['Vertical Forms'](char)) return true;
    if (unicodeBlockLookup['Yi Radicals'](char)) return true;
    if (unicodeBlockLookup['Yi Syllables'](char)) return true;

    return false;
}

// The following logic comes from
// <http://www.unicode.org/Public/12.0.0/ucd/VerticalOrientation.txt>.
// Keep it synchronized with
// <http://www.unicode.org/Public/UCD/latest/ucd/VerticalOrientation.txt>.
// The data file denotes with “U” or “Tu” any codepoint that may be drawn
// upright in vertical text but does not distinguish between upright and
// “neutral” characters.

// Blocks in the Unicode supplementary planes are excluded from this module due
// to <https://github.com/mapbox/mapbox-gl/issues/29>.

/**
 * Returns true if the given Unicode codepoint identifies a character with
 * upright orientation.
 *
 * A character has upright orientation if it is drawn upright (unrotated)
 * whether the line is oriented horizontally or vertically, even if both
 * adjacent characters can be rotated. For example, a Chinese character is
 * always drawn upright. An uprightly oriented character causes an adjacent
 * “neutral” character to be drawn upright as well.
 * @private
 */
function charHasUprightVerticalOrientation(char        )          {
    if (char === 0x02EA /* modifier letter yin departing tone mark */ ||
        char === 0x02EB /* modifier letter yang departing tone mark */) {
        return true;
    }

    // Return early for characters outside all ranges whose characters remain
    // upright in vertical writing mode.
    if (char < 0x1100) return false;

    if (unicodeBlockLookup['Bopomofo Extended'](char)) return true;
    if (unicodeBlockLookup['Bopomofo'](char)) return true;
    if (unicodeBlockLookup['CJK Compatibility Forms'](char)) {
        if (!((char >= 0xFE49 /* dashed overline */ && char <= 0xFE4F) /* wavy low line */)) {
            return true;
        }
    }
    if (unicodeBlockLookup['CJK Compatibility Ideographs'](char)) return true;
    if (unicodeBlockLookup['CJK Compatibility'](char)) return true;
    if (unicodeBlockLookup['CJK Radicals Supplement'](char)) return true;
    if (unicodeBlockLookup['CJK Strokes'](char)) return true;
    if (unicodeBlockLookup['CJK Symbols and Punctuation'](char)) {
        if (!((char >= 0x3008 /* left angle bracket */ && char <= 0x3011) /* right black lenticular bracket */) &&
            !((char >= 0x3014 /* left tortoise shell bracket */ && char <= 0x301F) /* low double prime quotation mark */) &&
            char !== 0x3030 /* wavy dash */) {
            return true;
        }
    }
    if (unicodeBlockLookup['CJK Unified Ideographs Extension A'](char)) return true;
    if (unicodeBlockLookup['CJK Unified Ideographs'](char)) return true;
    if (unicodeBlockLookup['Enclosed CJK Letters and Months'](char)) return true;
    if (unicodeBlockLookup['Hangul Compatibility Jamo'](char)) return true;
    if (unicodeBlockLookup['Hangul Jamo Extended-A'](char)) return true;
    if (unicodeBlockLookup['Hangul Jamo Extended-B'](char)) return true;
    if (unicodeBlockLookup['Hangul Jamo'](char)) return true;
    if (unicodeBlockLookup['Hangul Syllables'](char)) return true;
    if (unicodeBlockLookup['Hiragana'](char)) return true;
    if (unicodeBlockLookup['Ideographic Description Characters'](char)) return true;
    if (unicodeBlockLookup['Kanbun'](char)) return true;
    if (unicodeBlockLookup['Kangxi Radicals'](char)) return true;
    if (unicodeBlockLookup['Katakana Phonetic Extensions'](char)) return true;
    if (unicodeBlockLookup['Katakana'](char)) {
        if (char !== 0x30FC /* katakana-hiragana prolonged sound mark */) {
            return true;
        }
    }
    if (unicodeBlockLookup['Halfwidth and Fullwidth Forms'](char)) {
        if (char !== 0xFF08 /* fullwidth left parenthesis */ &&
            char !== 0xFF09 /* fullwidth right parenthesis */ &&
            char !== 0xFF0D /* fullwidth hyphen-minus */ &&
            !((char >= 0xFF1A /* fullwidth colon */ && char <= 0xFF1E) /* fullwidth greater-than sign */) &&
            char !== 0xFF3B /* fullwidth left square bracket */ &&
            char !== 0xFF3D /* fullwidth right square bracket */ &&
            char !== 0xFF3F /* fullwidth low line */ &&
            !(char >= 0xFF5B /* fullwidth left curly bracket */ && char <= 0xFFDF) &&
            char !== 0xFFE3 /* fullwidth macron */ &&
            !(char >= 0xFFE8 /* halfwidth forms light vertical */ && char <= 0xFFEF)) {
            return true;
        }
    }
    if (unicodeBlockLookup['Small Form Variants'](char)) {
        if (!((char >= 0xFE58 /* small em dash */ && char <= 0xFE5E) /* small right tortoise shell bracket */) &&
            !((char >= 0xFE63 /* small hyphen-minus */ && char <= 0xFE66) /* small equals sign */)) {
            return true;
        }
    }
    if (unicodeBlockLookup['Unified Canadian Aboriginal Syllabics'](char)) return true;
    if (unicodeBlockLookup['Unified Canadian Aboriginal Syllabics Extended'](char)) return true;
    if (unicodeBlockLookup['Vertical Forms'](char)) return true;
    if (unicodeBlockLookup['Yijing Hexagram Symbols'](char)) return true;
    if (unicodeBlockLookup['Yi Syllables'](char)) return true;
    if (unicodeBlockLookup['Yi Radicals'](char)) return true;

    return false;
}

/**
 * Returns true if the given Unicode codepoint identifies a character with
 * neutral orientation.
 *
 * A character has neutral orientation if it may be drawn rotated or unrotated
 * when the line is oriented vertically, depending on the orientation of the
 * adjacent characters. For example, along a verticlly oriented line, the vulgar
 * fraction ½ is drawn upright among Chinese characters but rotated among Latin
 * letters. A neutrally oriented character does not influence whether an
 * adjacent character is drawn upright or rotated.
 * @private
 */
function charHasNeutralVerticalOrientation(char        )          {
    if (unicodeBlockLookup['Latin-1 Supplement'](char)) {
        if (char === 0x00A7 /* section sign */ ||
            char === 0x00A9 /* copyright sign */ ||
            char === 0x00AE /* registered sign */ ||
            char === 0x00B1 /* plus-minus sign */ ||
            char === 0x00BC /* vulgar fraction one quarter */ ||
            char === 0x00BD /* vulgar fraction one half */ ||
            char === 0x00BE /* vulgar fraction three quarters */ ||
            char === 0x00D7 /* multiplication sign */ ||
            char === 0x00F7 /* division sign */) {
            return true;
        }
    }
    if (unicodeBlockLookup['General Punctuation'](char)) {
        if (char === 0x2016 /* double vertical line */ ||
            char === 0x2020 /* dagger */ ||
            char === 0x2021 /* double dagger */ ||
            char === 0x2030 /* per mille sign */ ||
            char === 0x2031 /* per ten thousand sign */ ||
            char === 0x203B /* reference mark */ ||
            char === 0x203C /* double exclamation mark */ ||
            char === 0x2042 /* asterism */ ||
            char === 0x2047 /* double question mark */ ||
            char === 0x2048 /* question exclamation mark */ ||
            char === 0x2049 /* exclamation question mark */ ||
            char === 0x2051 /* two asterisks aligned vertically */) {
            return true;
        }
    }
    if (unicodeBlockLookup['Letterlike Symbols'](char)) return true;
    if (unicodeBlockLookup['Number Forms'](char)) return true;
    if (unicodeBlockLookup['Miscellaneous Technical'](char)) {
        if ((char >= 0x2300 /* diameter sign */ && char <= 0x2307 /* wavy line */) ||
            (char >= 0x230C /* bottom right crop */ && char <= 0x231F /* bottom right corner */) ||
            (char >= 0x2324 /* up arrowhead between two horizontal bars */ && char <= 0x2328 /* keyboard */) ||
            char === 0x232B /* erase to the left */ ||
            (char >= 0x237D /* shouldered open box */ && char <= 0x239A /* clear screen symbol */) ||
            (char >= 0x23BE /* dentistry symbol light vertical and top right */ && char <= 0x23CD /* square foot */) ||
            char === 0x23CF /* eject symbol */ ||
            (char >= 0x23D1 /* metrical breve */ && char <= 0x23DB /* fuse */) ||
            (char >= 0x23E2 /* white trapezium */ && char <= 0x23FF)) {
            return true;
        }
    }
    if (unicodeBlockLookup['Control Pictures'](char) && char !== 0x2423 /* open box */) return true;
    if (unicodeBlockLookup['Optical Character Recognition'](char)) return true;
    if (unicodeBlockLookup['Enclosed Alphanumerics'](char)) return true;
    if (unicodeBlockLookup['Geometric Shapes'](char)) return true;
    if (unicodeBlockLookup['Miscellaneous Symbols'](char)) {
        if (!((char >= 0x261A /* black left pointing index */ && char <= 0x261F) /* white down pointing index */)) {
            return true;
        }
    }
    if (unicodeBlockLookup['Miscellaneous Symbols and Arrows'](char)) {
        if ((char >= 0x2B12 /* square with top half black */ && char <= 0x2B2F /* white vertical ellipse */) ||
            (char >= 0x2B50 /* white medium star */ && char <= 0x2B59 /* heavy circled saltire */) ||
            (char >= 0x2BB8 /* upwards white arrow from bar with horizontal bar */ && char <= 0x2BEB)) {
            return true;
        }
    }
    if (unicodeBlockLookup['CJK Symbols and Punctuation'](char)) return true;
    if (unicodeBlockLookup['Katakana'](char)) return true;
    if (unicodeBlockLookup['Private Use Area'](char)) return true;
    if (unicodeBlockLookup['CJK Compatibility Forms'](char)) return true;
    if (unicodeBlockLookup['Small Form Variants'](char)) return true;
    if (unicodeBlockLookup['Halfwidth and Fullwidth Forms'](char)) return true;

    if (char === 0x221E /* infinity */ ||
        char === 0x2234 /* therefore */ ||
        char === 0x2235 /* because */ ||
        (char >= 0x2700 /* black safety scissors */ && char <= 0x2767 /* rotated floral heart bullet */) ||
        (char >= 0x2776 /* dingbat negative circled digit one */ && char <= 0x2793 /* dingbat negative circled sans-serif number ten */) ||
        char === 0xFFFC /* object replacement character */ ||
        char === 0xFFFD /* replacement character */) {
        return true;
    }

    return false;
}

/**
 * Returns true if the given Unicode codepoint identifies a character with
 * rotated orientation.
 *
 * A character has rotated orientation if it is drawn rotated when the line is
 * oriented vertically, even if both adjacent characters are upright. For
 * example, a Latin letter is drawn rotated along a vertical line. A rotated
 * character causes an adjacent “neutral” character to be drawn rotated as well.
 * @private
 */
function charHasRotatedVerticalOrientation(char        )          {
    return !(charHasUprightVerticalOrientation(char) ||
             charHasNeutralVerticalOrientation(char));
}

function charInComplexShapingScript(char        )          {
    return unicodeBlockLookup['Arabic'](char) ||
           unicodeBlockLookup['Arabic Supplement'](char) ||
           unicodeBlockLookup['Arabic Extended-A'](char) ||
           unicodeBlockLookup['Arabic Presentation Forms-A'](char) ||
           unicodeBlockLookup['Arabic Presentation Forms-B'](char);
}

function charInRTLScript(char        )          {
    // Main blocks for Hebrew, Arabic, Thaana and other RTL scripts
    return (char >= 0x0590 && char <= 0x08FF) ||
        unicodeBlockLookup['Arabic Presentation Forms-A'](char) ||
        unicodeBlockLookup['Arabic Presentation Forms-B'](char);
}

function charInSupportedScript(char        , canRenderRTL         )          {
    // This is a rough heuristic: whether we "can render" a script
    // actually depends on the properties of the font being used
    // and whether differences from the ideal rendering are considered
    // semantically significant.

    // Even in Latin script, we "can't render" combinations such as the fi
    // ligature, but we don't consider that semantically significant.
    if (!canRenderRTL && charInRTLScript(char)) {
        return false;
    }
    if ((char >= 0x0900 && char <= 0x0DFF) ||
        // Main blocks for Indic scripts and Sinhala
        (char >= 0x0F00 && char <= 0x109F) ||
        // Main blocks for Tibetan and Myanmar
        unicodeBlockLookup['Khmer'](char)) {
        // These blocks cover common scripts that require
        // complex text shaping, based on unicode script metadata:
        // http://www.unicode.org/repos/cldr/trunk/common/properties/scriptMetadata.txt
        // where "Web Rank <= 32" "Shaping Required = YES"
        return false;
    }
    return true;
}

function stringContainsRTLText(chars        )          {
    for (const char of chars) {
        if (charInRTLScript(char.charCodeAt(0))) {
            return true;
        }
    }
    return false;
}

function isStringInSupportedScript(chars        , canRenderRTL         )          {
    for (const char of chars) {
        if (!charInSupportedScript(char.charCodeAt(0), canRenderRTL)) {
            return false;
        }
    }
    return true;
}

//      

                                                   

const status = {
    unavailable: 'unavailable', // Not loaded
    deferred: 'deferred', // The plugin URL has been specified, but loading has been deferred
    loading: 'loading', // request in-flight
    loaded: 'loaded',
    error: 'error'
};

                           
                                         
                      
  

                                                            
let _completionCallback = null;

//Variables defining the current state of the plugin
let pluginStatus = status.unavailable;
let pluginURL          = null;

const triggerPluginCompletionEvent = function(error        ) {
    // NetworkError's are not correctly reflected by the plugin status which prevents reloading plugin
    if (error && typeof error === 'string' && error.indexOf('NetworkError') > -1) {
        pluginStatus = status.error;
    }

    if (_completionCallback) {
        _completionCallback(error);
    }
};

function sendPluginStateToWorker() {
    evented.fire(new Event('pluginStateChange', {pluginStatus, pluginURL}));
}

const evented          = new Evented();

const getRTLTextPluginStatus = function ()         {
    return pluginStatus;
};

const registerForPluginStateChange = function(callback                         )                          {
    // Do an initial sync of the state
    callback({pluginStatus, pluginURL});
    // Listen for all future state changes
    evented.on('pluginStateChange', callback);
    return callback;
};

const clearRTLTextPlugin = function() {
    pluginStatus = status.unavailable;
    pluginURL = null;
};

const setRTLTextPlugin = function(url        , callback                          , deferred          = false) {
    if (pluginStatus === status.deferred || pluginStatus === status.loading || pluginStatus === status.loaded) {
        throw new Error('setRTLTextPlugin cannot be called multiple times.');
    }
    pluginURL = exported.resolveURL(url);
    pluginStatus = status.deferred;
    _completionCallback = callback;
    sendPluginStateToWorker();

    //Start downloading the plugin immediately if not intending to lazy-load
    if (!deferred) {
        downloadRTLTextPlugin();
    }
};

const downloadRTLTextPlugin = function() {
    if (pluginStatus !== status.deferred || !pluginURL) {
        throw new Error('rtl-text-plugin cannot be downloaded unless a pluginURL is specified');
    }
    pluginStatus = status.loading;
    sendPluginStateToWorker();
    if (pluginURL) {
        getArrayBuffer({url: pluginURL}, (error) => {
            if (error) {
                triggerPluginCompletionEvent(error);
            } else {
                pluginStatus = status.loaded;
                sendPluginStateToWorker();
            }
        });
    }
};

const plugin   
                                  
                                                                        
                                                                                                              
                            
                             
                                           
                            
                               
  = {
    applyArabicShaping: null,
    processBidirectionalText: null,
    processStyledBidirectionalText: null,
    isLoaded() {
        return pluginStatus === status.loaded || // Main Thread: loaded if the completion callback returned successfully
            plugin.applyArabicShaping != null; // Web-worker: loaded if the plugin functions have been compiled
    },
    isLoading() { // Main Thread Only: query the loading status, this function does not return the correct value in the worker context.
        return pluginStatus === status.loading;
    },
    setState(state             ) { // Worker thread only: this tells the worker threads that the plugin is available on the Main thread
        assert$1(isWorker(), 'Cannot set the state of the rtl-text-plugin when not in the web-worker context');

        pluginStatus = state.pluginStatus;
        pluginURL = state.pluginURL;
    },
    isParsed()          {
        assert$1(isWorker(), 'rtl-text-plugin is only parsed on the worker-threads');

        return plugin.applyArabicShaping != null &&
            plugin.processBidirectionalText != null &&
            plugin.processStyledBidirectionalText != null;
    },
    getPluginURL()          {
        assert$1(isWorker(), 'rtl-text-plugin url can only be queried from the worker threads');
        return pluginURL;
    }
};

const lazyLoadRTLTextPlugin = function() {
    if (!plugin.isLoading() &&
        !plugin.isLoaded() &&
        getRTLTextPluginStatus() === 'deferred'
    ) {
        downloadRTLTextPlugin();
    }
};

//      


                                                                    

class EvaluationParameters {
                 
                  
                
                         
                                        

    // "options" may also be another EvaluationParameters to copy
    constructor(zoom        , options      ) {
        this.zoom = zoom;

        if (options) {
            this.now = options.now;
            this.fadeDuration = options.fadeDuration;
            this.transition = options.transition;
            this.pitch = options.pitch;
        } else {
            this.now = 0;
            this.fadeDuration = 0;
            this.transition = {};
            this.pitch = 0;
        }
    }

    isSupportedScript(str        )          {
        return isStringInSupportedScript(str, plugin.isLoaded());
    }
}

//      


                                                          
                                                                            
             
                            
                              
                                

             
            
                 
                            
                     
                       
                                           

                        

/**
 * Implements a number of classes that define state and behavior for paint and layout properties, most
 * importantly their respective evaluation chains:
 *
 *       Transitionable paint property value
 *     → Transitioning paint property value
 *     → Possibly evaluated paint property value
 *     → Fully evaluated paint property value
 *
 *       Layout property value
 *     → Possibly evaluated layout property value
 *     → Fully evaluated layout property value
 *
 * @module
 * @private
 */

/**
 *  Implementations of the `Property` interface:
 *
 *  * Hold metadata about a property that's independent of any specific value: stuff like the type of the value,
 *    the default value, etc. This comes from the style specification JSON.
 *  * Define behavior that needs to be polymorphic across different properties: "possibly evaluating"
 *    an input value (see below), and interpolating between two possibly-evaluted values.
 *
 *  The type `T` is the fully-evaluated value type (e.g. `number`, `string`, `Color`).
 *  The type `R` is the intermediate "possibly evaluated" value type. See below.
 *
 *  There are two main implementations of the interface -- one for properties that allow data-driven values,
 *  and one for properties that don't. There are a few "special case" implementations as well:
 *  one for `heatmap-color` and `line-gradient`, and one for `light-position`.
 *
 * @private
 */
                                 
                                              
                                                                                                                                                    
                                          
 

/**
 *  `PropertyValue` represents the value part of a property key-value unit. It's used to represent both
 *  paint and layout property values, and regardless of whether or not their property supports data-driven
 *  expressions.
 *
 *  `PropertyValue` stores the raw input value as seen in a style or a runtime styling API call, i.e. one of the
 *  following:
 *
 *    * A constant value of the type appropriate for the property
 *    * A function which produces a value of that type (but functions are quasi-deprecated in favor of expressions)
 *    * An expression which produces a value of that type
 *    * "undefined"/"not present", in which case the property is assumed to take on its default value.
 *
 *  In addition to storing the original input value, `PropertyValue` also stores a normalized representation,
 *  effectively treating functions as if they are expressions, and constant or default values as if they are
 *  (constant) expressions.
 *
 *  @private
 */
class PropertyValue       {
                             
                                                
                                        

    constructor(property                , value                                      ) {
        this.property = property;
        this.value = value;
        this.expression = normalizePropertyExpression(value === undefined ? property.specification.default : value, property.specification);
    }

    isDataDriven()          {
        return this.expression.kind === 'source' || this.expression.kind === 'composite';
    }

    possiblyEvaluate(parameters                      , canonical                  , availableImages                )    {
        return this.property.possiblyEvaluate(this, parameters, canonical, availableImages);
    }
}

// ------- Transitionable -------

                                              
                   
                                        
  

/**
 * Paint properties are _transitionable_: they can change in a fluid manner, interpolating or cross-fading between
 * old and new value. The duration of the transition, and the delay before it begins, is configurable.
 *
 * `TransitionablePropertyValue` is a compositional class that stores both the property value and that transition
 * configuration.
 *
 * A `TransitionablePropertyValue` can calculate the next step in the evaluation chain for paint property values:
 * `TransitioningPropertyValue`.
 *
 * @private
 */
class TransitionablePropertyValue       {
                             
                               
                                               

    constructor(property                ) {
        this.property = property;
        this.value = new PropertyValue(property, undefined);
    }

    transitioned(parameters                      ,
                 prior                                  )                                   {
        return new TransitioningPropertyValue(this.property, this.value, prior, // eslint-disable-line no-use-before-define
            extend$1({}, parameters.transition, this.transition), parameters.now);
    }

    untransitioned()                                   {
        return new TransitioningPropertyValue(this.property, this.value, null, {}, 0); // eslint-disable-line no-use-before-define
    }
}

/**
 * A helper type: given an object type `Properties` whose values are each of type `Property<T, R>`, it calculates
 * an object type with the same keys and values of type `TransitionablePropertyValue<T, R>`.
 *
 * @private
 */
                                                
                                                                                            

/**
 * `Transitionable` stores a map of all (property name, `TransitionablePropertyValue`) pairs for paint properties of a
 * given layer type. It can calculate the `TransitioningPropertyValue`s for all of them at once, producing a
 * `Transitioning` instance for the same set of properties.
 *
 * @private
 */
class Transitionable                {
                                   
                                                 

    constructor(properties                   ) {
        this._properties = properties;
        this._values = (Object.create(properties.defaultTransitionablePropertyValues)     );
    }

    getValue              (name   )                                       {
        return clone$9(this._values[name].value.value);
    }

    setValue              (name   , value                                      ) {
        if (!this._values.hasOwnProperty(name)) {
            this._values[name] = new TransitionablePropertyValue(this._values[name].property);
        }
        // Note that we do not _remove_ an own property in the case where a value is being reset
        // to the default: the transition might still be non-default.
        this._values[name].value = new PropertyValue(this._values[name].property, value === null ? undefined : clone$9(value));
    }

    getTransition           (name   )                                 {
        return clone$9(this._values[name].transition);
    }

    setTransition           (name   , value                                ) {
        if (!this._values.hasOwnProperty(name)) {
            this._values[name] = new TransitionablePropertyValue(this._values[name].property);
        }
        this._values[name].transition = clone$9(value) || undefined;
    }

    serialize()                                     {
        const result         = {};
        for (const property of Object.keys(this._values)) {
            const value = this.getValue(property);
            if (value !== undefined) {
                result[property] = value;
            }

            const transition = this.getTransition(property);
            if (transition !== undefined) {
                result[`${property}-transition`] = transition;
            }
        }
        return result;
    }

    transitioned(parameters                      , prior                      )                       {
        const result = new Transitioning(this._properties); // eslint-disable-line no-use-before-define
        for (const property of Object.keys(this._values)) {
            result._values[property] = this._values[property].transitioned(parameters, prior._values[property]);
        }
        return result;
    }

    untransitioned()                       {
        const result = new Transitioning(this._properties); // eslint-disable-line no-use-before-define
        for (const property of Object.keys(this._values)) {
            result._values[property] = this._values[property].untransitioned();
        }
        return result;
    }
}

// ------- Transitioning -------

/**
 * `TransitioningPropertyValue` implements the first of two intermediate steps in the evaluation chain of a paint
 * property value. In this step, transitions between old and new values are handled: as long as the transition is in
 * progress, `TransitioningPropertyValue` maintains a reference to the prior value, and interpolates between it and
 * the new value based on the current time and the configured transition duration and delay. The product is the next
 * step in the evaluation chain: the "possibly evaluated" result type `R`. See below for more on this concept.
 *
 * @private
 */
class TransitioningPropertyValue       {
                             
                               
                                             
                     
                   

    constructor(property                ,
                value                     ,
                prior                                   ,
                transition                         ,
                now           ) {
        const delay = transition.delay || 0;
        const duration = transition.duration || 0;
        now = now || 0;
        this.property = property;
        this.value = value;
        this.begin = now + delay;
        this.end = this.begin + duration;
        if (property.specification.transition && (transition.delay || transition.duration)) {
            this.prior = prior;
        }
    }

    possiblyEvaluate(parameters                      , canonical                 , availableImages               )    {
        const now = parameters.now || 0;
        const finalValue = this.value.possiblyEvaluate(parameters, canonical, availableImages);
        const prior = this.prior;
        if (!prior) {
            // No prior value.
            return finalValue;
        } else if (now > this.end) {
            // Transition from prior value is now complete.
            this.prior = null;
            return finalValue;
        } else if (this.value.isDataDriven()) {
            // Transitions to data-driven properties are not supported.
            // We snap immediately to the data-driven value so that, when we perform layout,
            // we see the data-driven function and can use it to populate vertex buffers.
            this.prior = null;
            return finalValue;
        } else if (now < this.begin) {
            // Transition hasn't started yet.
            return prior.possiblyEvaluate(parameters, canonical, availableImages);
        } else {
            // Interpolate between recursively-calculated prior value and final.
            const t = (now - this.begin) / (this.end - this.begin);
            return this.property.interpolate(prior.possiblyEvaluate(parameters, canonical, availableImages), finalValue, easeCubicInOut(t));
        }
    }
}

/**
 * A helper type: given an object type `Properties` whose values are each of type `Property<T, R>`, it calculates
 * an object type with the same keys and values of type `TransitioningPropertyValue<T, R>`.
 *
 * @private
 */
                                               
                                                                                           

/**
 * `Transitioning` stores a map of all (property name, `TransitioningPropertyValue`) pairs for paint properties of a
 * given layer type. It can calculate the possibly-evaluated values for all of them at once, producing a
 * `PossiblyEvaluated` instance for the same set of properties.
 *
 * @private
 */
class Transitioning                {
                                   
                                                

    constructor(properties                   ) {
        this._properties = properties;
        this._values = (Object.create(properties.defaultTransitioningPropertyValues)     );
    }

    possiblyEvaluate(parameters                      , canonical                  , availableImages                )                           {
        const result = new PossiblyEvaluated(this._properties); // eslint-disable-line no-use-before-define
        for (const property of Object.keys(this._values)) {
            result._values[property] = this._values[property].possiblyEvaluate(parameters, canonical, availableImages);
        }
        return result;
    }

    hasTransition()          {
        for (const property of Object.keys(this._values)) {
            if (this._values[property].prior) {
                return true;
            }
        }
        return false;
    }
}

// ------- Layout -------

/**
 * A helper type: given an object type `Properties` whose values are each of type `Property<T, R>`, it calculates
 * an object type with the same keys and values of type `PropertyValue<T, R>`.
 *
 * @private
 */
                                  
                                                                              

/**
 * A helper type: given an object type `Properties` whose values are each of type `Property<T, R>`, it calculates
 * an object type with the same keys and values of type `PropertyValueSpecification<T>`.
 *
 * @private
 */
                                               
                                                                                        

/**
 * Because layout properties are not transitionable, they have a simpler representation and evaluation chain than
 * paint properties: `PropertyValue`s are possibly evaluated, producing possibly evaluated values, which are then
 * fully evaluated.
 *
 * `Layout` stores a map of all (property name, `PropertyValue`) pairs for layout properties of a
 * given layer type. It can calculate the possibly-evaluated values for all of them at once, producing a
 * `PossiblyEvaluated` instance for the same set of properties.
 *
 * @private
 */
class Layout                {
                                   
                                   

    constructor(properties                   ) {
        this._properties = properties;
        this._values = (Object.create(properties.defaultPropertyValues)     );
    }

    getValue              (name   )                                       {
        return clone$9(this._values[name].value);
    }

    setValue           (name   , value     ) {
        this._values[name] = new PropertyValue(this._values[name].property, value === null ? undefined : clone$9(value));
    }

    serialize()                                     {
        const result         = {};
        for (const property of Object.keys(this._values)) {
            const value = this.getValue(property);
            if (value !== undefined) {
                result[property] = value;
            }
        }
        return result;
    }

    possiblyEvaluate(parameters                      , canonical                  , availableImages                )                           {
        const result = new PossiblyEvaluated(this._properties); // eslint-disable-line no-use-before-define
        for (const property of Object.keys(this._values)) {
            result._values[property] = this._values[property].possiblyEvaluate(parameters, canonical, availableImages);
        }
        return result;
    }
}

// ------- PossiblyEvaluated -------

/**
 * "Possibly evaluated value" is an intermediate stage in the evaluation chain for both paint and layout property
 * values. The purpose of this stage is to optimize away unnecessary recalculations for data-driven properties. Code
 * which uses data-driven property values must assume that the value is dependent on feature data, and request that it
 * be evaluated for each feature. But when that property value is in fact a constant or camera function, the calculation
 * will not actually depend on the feature, and we can benefit from returning the prior result of having done the
 * evaluation once, ahead of time, in an intermediate step whose inputs are just the value and "global" parameters
 * such as current zoom level.
 *
 * `PossiblyEvaluatedValue` represents the three possible outcomes of this step: if the input value was a constant or
 * camera expression, then the "possibly evaluated" result is a constant value. Otherwise, the input value was either
 * a source or composite expression, and we must defer final evaluation until supplied a feature. We separate
 * the source and composite cases because they are handled differently when generating GL attributes, buffers, and
 * uniforms.
 *
 * Note that `PossiblyEvaluatedValue` (and `PossiblyEvaluatedPropertyValue`, below) are _not_ used for properties that
 * do not allow data-driven values. For such properties, we know that the "possibly evaluated" result is always a constant
 * scalar value. See below.
 *
 * @private
 */
                                       
                                  
                      
                          

/**
 * `PossiblyEvaluatedPropertyValue` is used for data-driven paint and layout property values. It holds a
 * `PossiblyEvaluatedValue` and the `GlobalProperties` that were used to generate it. You're not allowed to supply
 * a different set of `GlobalProperties` when performing the final evaluation because they would be ignored in the
 * case where the input value was a constant or camera function.
 *
 * @private
 */
class PossiblyEvaluatedPropertyValue    {
                                    
                                     
                                     

    constructor(property                       , value                           , parameters                      ) {
        this.property = property;
        this.value = value;
        this.parameters = parameters;
    }

    isConstant()          {
        return this.value.kind === 'constant';
    }

    constantOr(value   )    {
        if (this.value.kind === 'constant') {
            return this.value.value;
        } else {
            return value;
        }
    }

    evaluate(feature         , featureState              , canonical                  , availableImages                )    {
        return this.property.evaluate(this.value, this.parameters, feature, featureState, canonical, availableImages);
    }
}

/**
 * A helper type: given an object type `Properties` whose values are each of type `Property<T, R>`, it calculates
 * an object type with the same keys, and values of type `R`.
 *
 * For properties that don't allow data-driven values, `R` is a scalar type such as `number`, `string`, or `Color`.
 * For data-driven properties, it is `PossiblyEvaluatedPropertyValue`. Critically, the type definitions are set up
 * in a way that allows flow to know which of these two cases applies for any given property name, and if you attempt
 * to use a `PossiblyEvaluatedPropertyValue` as if it was a scalar, or vice versa, you will get a type error. (However,
 * there's at least one case in which flow fails to produce a type error that you should be aware of: in a context such
 * as `layer.paint.get('foo-opacity') === 0`, if `foo-opacity` is data-driven, than the left-hand side is of type
 * `PossiblyEvaluatedPropertyValue<number>`, but flow will not complain about comparing this to a number using `===`.
 * See https://github.com/facebook/flow/issues/2359.)
 *
 * @private
 */
                                                   
                                                            

/**
 * `PossiblyEvaluated` stores a map of all (property name, `R`) pairs for paint or layout properties of a
 * given layer type.
 * @private
 */
class PossiblyEvaluated                {
                                   
                                                    

    constructor(properties                   ) {
        this._properties = properties;
        this._values = (Object.create(properties.defaultPossiblyEvaluatedValues)     );
    }

    get           (name   )                                                          {
        return this._values[name];
    }
}

/**
 * An implementation of `Property` for properties that do not permit data-driven (source or composite) expressions.
 * This restriction allows us to declare statically that the result of possibly evaluating this kind of property
 * is in fact always the scalar type `T`, and can be used without further evaluating the value on a per-feature basis.
 *
 * @private
 */
class DataConstantProperty                              {
                                              

    constructor(specification                            ) {
        this.specification = specification;
    }

    possiblyEvaluate(value                     , parameters                      )    {
        assert$1(!value.isDataDriven());
        // $FlowFixMe[method-unbinding]
        return value.expression.evaluate(parameters);
    }

    interpolate(a   , b   , t        )    {
        const interp                                = (interpolate     )[this.specification.type];
        if (interp) {
            return interp(a, b, t);
        } else {
            return a;
        }
    }
}

/**
 * An implementation of `Property` for properties that permit data-driven (source or composite) expressions.
 * The result of possibly evaluating this kind of property is `PossiblyEvaluatedPropertyValue<T>`; obtaining
 * a scalar value `T` requires further evaluation on a per-feature basis.
 *
 * @private
 */
class DataDrivenProperty                                                              {
                                              
                       
                             

    constructor(specification                            , overrides         ) {
        this.specification = specification;
        this.overrides = overrides;
    }

    possiblyEvaluate(value                                                     , parameters                      , canonical                  , availableImages                )                                    {
        if (value.expression.kind === 'constant' || value.expression.kind === 'camera') {
            // $FlowFixMe[method-unbinding]
            return new PossiblyEvaluatedPropertyValue(this, {kind: 'constant', value: value.expression.evaluate(parameters, (null     ), {}, canonical, availableImages)}, parameters);
        } else {
            return new PossiblyEvaluatedPropertyValue(this, value.expression, parameters);
        }
    }

    interpolate(a                                   ,
                b                                   ,
                t        )                                    {
        // If either possibly-evaluated value is non-constant, give up: we aren't able to interpolate data-driven values.
        if (a.value.kind !== 'constant' || b.value.kind !== 'constant') {
            return a;
        }

        // Special case hack solely for fill-outline-color. The undefined value is subsequently handled in
        // FillStyleLayer#recalculate, which sets fill-outline-color to the fill-color value if the former
        // is a PossiblyEvaluatedPropertyValue containing a constant undefined value. In addition to the
        // return value here, the other source of a PossiblyEvaluatedPropertyValue containing a constant
        // undefined value is the "default value" for fill-outline-color held in
        // `Properties#defaultPossiblyEvaluatedValues`, which serves as the prototype of
        // `PossiblyEvaluated#_values`.
        if (a.value.value === undefined || b.value.value === undefined) {
            return new PossiblyEvaluatedPropertyValue(this, {kind: 'constant', value: (undefined     )}, a.parameters);
        }

        const interp                                = (interpolate     )[this.specification.type];
        if (interp) {
            return new PossiblyEvaluatedPropertyValue(this, {kind: 'constant', value: interp(a.value.value, b.value.value, t)}, a.parameters);
        } else {
            return a;
        }
    }

    evaluate(value                           , parameters                      , feature         , featureState              , canonical                  , availableImages                )    {
        if (value.kind === 'constant') {
            return value.value;
        } else {
            // $FlowFixMe[method-unbinding]
            return value.evaluate(parameters, feature, featureState, canonical, availableImages);
        }
    }
}

/**
 * An implementation of `Property` for `heatmap-color` and `line-gradient`. Interpolation is a no-op, and
 * evaluation returns a boolean value in order to indicate its presence, but the real
 * evaluation happens in StyleLayer classes.
 *
 * @private
 */
class ColorRampProperty                                     {
                                              

    constructor(specification                            ) {
        this.specification = specification;
    }

    possiblyEvaluate(value                               , parameters                      , canonical                  , availableImages                )          {
        // $FlowFixMe[method-unbinding]
        return !!value.expression.evaluate(parameters, (null     ), {}, canonical, availableImages);
    }

    interpolate()          { return false; }
}

/**
 * `Properties` holds objects containing default values for the layout or paint property set of a given
 * layer type. These objects are immutable, and they are used as the prototypes for the `_values` members of
 * `Transitionable`, `Transitioning`, `Layout`, and `PossiblyEvaluated`. This allows these classes to avoid
 * doing work in the common case where a property has no explicit value set and should be considered to take
 * on the default value: using `for (const property of Object.keys(this._values))`, they can iterate over
 * only the _own_ properties of `_values`, skipping repeated calculation of transitions and possible/final
 * evaluations for defaults, the result of which will always be the same.
 *
 * @private
 */
class Properties                {
                      
                                                 
                                                                             
                                                                           
                                                                           
                                         

    constructor(properties       ) {
        this.properties = properties;
        this.defaultPropertyValues = ({}     );
        this.defaultTransitionablePropertyValues = ({}     );
        this.defaultTransitioningPropertyValues = ({}     );
        this.defaultPossiblyEvaluatedValues = ({}     );
        this.overridableProperties = ([]     );

        const defaultParameters = new EvaluationParameters(0, {});
        for (const property in properties) {
            const prop = properties[property];
            if (prop.specification.overridable) {
                this.overridableProperties.push(property);
            }
            const defaultPropertyValue = this.defaultPropertyValues[property] =
                new PropertyValue(prop, undefined);
            const defaultTransitionablePropertyValue = this.defaultTransitionablePropertyValues[property] =
                new TransitionablePropertyValue(prop);
            this.defaultTransitioningPropertyValues[property] =
                defaultTransitionablePropertyValue.untransitioned();
            this.defaultPossiblyEvaluatedValues[property] =
                defaultPropertyValue.possiblyEvaluate(defaultParameters);
        }
    }
}

register(DataDrivenProperty, 'DataDrivenProperty');
register(DataConstantProperty, 'DataConstantProperty');
register(ColorRampProperty, 'ColorRampProperty');

//      


/**
 * Packs two numbers, interpreted as 8-bit unsigned integers, into a single
 * float.  Unpack them in the shader using the `unpack_float()` function,
 * defined in _prelude.vertex.glsl
 *
 * @private
 */
function packUint8ToFloat(a        , b        )         {
    // coerce a and b to 8-bit ints
    a = clamp(Math.floor(a), 0, 255);
    b = clamp(Math.floor(b), 0, 255);
    return 256 * a + b;
}

//      


                                                           

const viewTypes = {
    'Int8': Int8Array,
    'Uint8': Uint8Array,
    'Int16': Int16Array,
    'Uint16': Uint16Array,
    'Int32': Int32Array,
    'Uint32': Uint32Array,
    'Float32': Float32Array
};

                                               

/**
 * @private
 */
class Struct {
    // When reading the ArrayBuffer as an array of different data types, arrays have different length
    // depending on data type size. So to acess the same position,
    // we need to read different indexes depending on array data size.
    // _pos1 is the index reading an array with 1 byte data,
    // _pos2 is reading 2 byte data, and so forth.
                  
                  
                  
                  
                               

    // The following properties are defined on the prototype of sub classes.
                 

    /**
     * @param {StructArray} structArray The StructArray the struct is stored in
     * @param {number} index The index of the struct in the StructArray.
     * @private
     */
    constructor(structArray             , index        ) {
        (this     )._structArray = structArray;
        this._pos1 = index * this.size;
        this._pos2 = this._pos1 / 2;
        this._pos4 = this._pos1 / 4;
        this._pos8 = this._pos1 / 8;
    }
}

const DEFAULT_CAPACITY = 128;
const RESIZE_MULTIPLIER = 5;

                                 
                 
                   
                       
                  
  

                                 
                                      
                 
                      
 

                                     
                   
                            
  

/**
 * `StructArray` provides an abstraction over `ArrayBuffer` and `TypedArray`
 * making it behave like an array of typed structs.
 *
 * Conceptually, a StructArray is comprised of elements, i.e., instances of its
 * associated struct type. Each particular struct type, together with an
 * alignment size, determines the memory layout of a StructArray whose elements
 * are of that type.  Thus, for each such layout that we need, we have
 * a corrseponding StructArrayLayout class, inheriting from StructArray and
 * implementing `emplaceBack()` and `_refreshViews()`.
 *
 * In some cases, where we need to access particular elements of a StructArray,
 * we implement a more specific subclass that inherits from one of the
 * StructArrayLayouts and adds a `get(i): T` accessor that returns a structured
 * object whose properties are proxies into the underlying memory space for the
 * i-th element.  This affords the convience of working with (seemingly) plain
 * Javascript objects without the overhead of serializing/deserializing them
 * into ArrayBuffers for efficient web worker transfer.
 *
 * @private
 */
class StructArray {
                     
                   
                           
                             
                      

    // The following properties are defined on the prototype.
                                      
                            
                           
                       

    constructor() {
        this.isTransferred = false;
        this.capacity = -1;
        this.resize(0);
    }

    /**
     * Serialize a StructArray instance.  Serializes both the raw data and the
     * metadata needed to reconstruct the StructArray base class during
     * deserialization.
     * @private
     */
    static serialize(array             , transferables                      )                        {
        assert$1(!array.isTransferred);

        array._trim();

        if (transferables) {
            array.isTransferred = true;
            transferables.push(array.arrayBuffer);
        }

        return {
            length: array.length,
            arrayBuffer: array.arrayBuffer,
        };
    }

    static deserialize(input                       )              {
        // $FlowFixMe not-an-object - newer Flow doesn't understand this pattern, silence for now
        const structArray                     = Object.create(this.prototype);
        structArray.arrayBuffer = input.arrayBuffer;
        structArray.length = input.length;
        structArray.capacity = input.arrayBuffer.byteLength / structArray.bytesPerElement;
        structArray._refreshViews();
        return ((structArray     )             );
    }

    /**
     * Resize the array to discard unused capacity.
     */
    _trim() {
        if (this.length !== this.capacity) {
            this.capacity = this.length;
            this.arrayBuffer = this.arrayBuffer.slice(0, this.length * this.bytesPerElement);
            this._refreshViews();
        }
    }

    /**
     * Resets the the length of the array to 0 without de-allocating capcacity.
     */
    clear() {
        this.length = 0;
    }

    /**
     * Resize the array.
     * If `n` is greater than the current length then additional elements with undefined values are added.
     * If `n` is less than the current length then the array will be reduced to the first `n` elements.
     * @param {number} n The new size of the array.
     */
    resize(n        ) {
        assert$1(!this.isTransferred);
        this.reserve(n);
        this.length = n;
    }

    /**
     * Indicate a planned increase in size, so that any necessary allocation may
     * be done once, ahead of time.
     * @param {number} n The expected size of the array.
     */
    reserve(n        ) {
        if (n > this.capacity) {
            this.capacity = Math.max(n, Math.floor(this.capacity * RESIZE_MULTIPLIER), DEFAULT_CAPACITY);
            this.arrayBuffer = new ArrayBuffer(this.capacity * this.bytesPerElement);

            const oldUint8Array = this.uint8;
            this._refreshViews();
            if (oldUint8Array) this.uint8.set(oldUint8Array);
        }
    }

    /**
     * Create TypedArray views for the current ArrayBuffer.
     */
    _refreshViews()       {
        throw new Error('_refreshViews() must be implemented by each concrete StructArray layout');
    }

    destroy() {
        // $FlowFixMe
        this.int8 = this.uint8 = this.int16 = this.uint16 = this.int32 = this.uint32 = this.float32 = null;
        this.arrayBuffer = (null     );
    }
}

/**
 * Given a list of member fields, create a full StructArrayLayout, in
 * particular calculating the correct byte offset for each field.  This data
 * is used at build time to generate StructArrayLayout_*#emplaceBack() and
 * other accessors, and at runtime for binding vertex buffer attributes.
 *
 * @private
 */
function createLayout(
    members                                                                ,
    alignment         = 1
)                    {

    let offset = 0;
    let maxSize = 0;
    const layoutMembers = members.map((member) => {
        assert$1(member.name.length);
        const typeSize = sizeOf(member.type);
        const memberOffset = offset = align$1(offset, Math.max(alignment, typeSize));
        const components = member.components || 1;

        maxSize = Math.max(maxSize, typeSize);
        offset += typeSize * components;

        return {
            name: member.name,
            type: member.type,
            components,
            offset: memberOffset,
        };
    });

    const size = align$1(offset, Math.max(maxSize, alignment));

    return {
        members: layoutMembers,
        size,
        alignment
    };
}

function sizeOf(type          )         {
    return viewTypes[type].BYTES_PER_ELEMENT;
}

function align$1(offset        , size        )         {
    return Math.ceil(offset / size) * size;
}

// This file is generated. Edit build/generate-struct-arrays.js, then run `yarn run codegen`.
/* eslint-disable camelcase */
//      


/**
 * Implementation of the StructArray layout:
 * [0]: Int16[2]
 *
 * @private
 */
class StructArrayLayout2i4 extends StructArray {
                      
                      

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.int16 = new Int16Array(this.arrayBuffer);
    }

    emplaceBack(v0        , v1        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0, v1);
    }

    emplace(i        , v0        , v1        )         {
        const o2 = i * 2;
        this.int16[o2 + 0] = v0;
        this.int16[o2 + 1] = v1;
        return i;
    }
}

StructArrayLayout2i4.prototype.bytesPerElement = 4;
register(StructArrayLayout2i4, 'StructArrayLayout2i4');

/**
 * Implementation of the StructArray layout:
 * [0]: Int16[3]
 *
 * @private
 */
class StructArrayLayout3i6 extends StructArray {
                      
                      

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.int16 = new Int16Array(this.arrayBuffer);
    }

    emplaceBack(v0        , v1        , v2        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0, v1, v2);
    }

    emplace(i        , v0        , v1        , v2        )         {
        const o2 = i * 3;
        this.int16[o2 + 0] = v0;
        this.int16[o2 + 1] = v1;
        this.int16[o2 + 2] = v2;
        return i;
    }
}

StructArrayLayout3i6.prototype.bytesPerElement = 6;
register(StructArrayLayout3i6, 'StructArrayLayout3i6');

/**
 * Implementation of the StructArray layout:
 * [0]: Int16[4]
 *
 * @private
 */
class StructArrayLayout4i8 extends StructArray {
                      
                      

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.int16 = new Int16Array(this.arrayBuffer);
    }

    emplaceBack(v0        , v1        , v2        , v3        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0, v1, v2, v3);
    }

    emplace(i        , v0        , v1        , v2        , v3        )         {
        const o2 = i * 4;
        this.int16[o2 + 0] = v0;
        this.int16[o2 + 1] = v1;
        this.int16[o2 + 2] = v2;
        this.int16[o2 + 3] = v3;
        return i;
    }
}

StructArrayLayout4i8.prototype.bytesPerElement = 8;
register(StructArrayLayout4i8, 'StructArrayLayout4i8');

/**
 * Implementation of the StructArray layout:
 * [0]: Int16[2]
 * [4]: Uint8[4]
 * [8]: Float32[1]
 *
 * @private
 */
class StructArrayLayout2i4ub1f12 extends StructArray {
                      
                      
                          

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.int16 = new Int16Array(this.arrayBuffer);
        this.float32 = new Float32Array(this.arrayBuffer);
    }

    emplaceBack(v0        , v1        , v2        , v3        , v4        , v5        , v6        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0, v1, v2, v3, v4, v5, v6);
    }

    emplace(i        , v0        , v1        , v2        , v3        , v4        , v5        , v6        )         {
        const o2 = i * 6;
        const o1 = i * 12;
        const o4 = i * 3;
        this.int16[o2 + 0] = v0;
        this.int16[o2 + 1] = v1;
        this.uint8[o1 + 4] = v2;
        this.uint8[o1 + 5] = v3;
        this.uint8[o1 + 6] = v4;
        this.uint8[o1 + 7] = v5;
        this.float32[o4 + 2] = v6;
        return i;
    }
}

StructArrayLayout2i4ub1f12.prototype.bytesPerElement = 12;
register(StructArrayLayout2i4ub1f12, 'StructArrayLayout2i4ub1f12');

/**
 * Implementation of the StructArray layout:
 * [0]: Float32[4]
 *
 * @private
 */
class StructArrayLayout4f16 extends StructArray {
                      
                          

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.float32 = new Float32Array(this.arrayBuffer);
    }

    emplaceBack(v0        , v1        , v2        , v3        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0, v1, v2, v3);
    }

    emplace(i        , v0        , v1        , v2        , v3        )         {
        const o4 = i * 4;
        this.float32[o4 + 0] = v0;
        this.float32[o4 + 1] = v1;
        this.float32[o4 + 2] = v2;
        this.float32[o4 + 3] = v3;
        return i;
    }
}

StructArrayLayout4f16.prototype.bytesPerElement = 16;
register(StructArrayLayout4f16, 'StructArrayLayout4f16');

/**
 * Implementation of the StructArray layout:
 * [0]: Uint16[4]
 * [8]: Float32[1]
 *
 * @private
 */
class StructArrayLayout4ui1f12 extends StructArray {
                      
                        
                          

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.uint16 = new Uint16Array(this.arrayBuffer);
        this.float32 = new Float32Array(this.arrayBuffer);
    }

    emplaceBack(v0        , v1        , v2        , v3        , v4        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0, v1, v2, v3, v4);
    }

    emplace(i        , v0        , v1        , v2        , v3        , v4        )         {
        const o2 = i * 6;
        const o4 = i * 3;
        this.uint16[o2 + 0] = v0;
        this.uint16[o2 + 1] = v1;
        this.uint16[o2 + 2] = v2;
        this.uint16[o2 + 3] = v3;
        this.float32[o4 + 2] = v4;
        return i;
    }
}

StructArrayLayout4ui1f12.prototype.bytesPerElement = 12;
register(StructArrayLayout4ui1f12, 'StructArrayLayout4ui1f12');

/**
 * Implementation of the StructArray layout:
 * [0]: Uint16[4]
 *
 * @private
 */
class StructArrayLayout4ui8 extends StructArray {
                      
                        

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.uint16 = new Uint16Array(this.arrayBuffer);
    }

    emplaceBack(v0        , v1        , v2        , v3        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0, v1, v2, v3);
    }

    emplace(i        , v0        , v1        , v2        , v3        )         {
        const o2 = i * 4;
        this.uint16[o2 + 0] = v0;
        this.uint16[o2 + 1] = v1;
        this.uint16[o2 + 2] = v2;
        this.uint16[o2 + 3] = v3;
        return i;
    }
}

StructArrayLayout4ui8.prototype.bytesPerElement = 8;
register(StructArrayLayout4ui8, 'StructArrayLayout4ui8');

/**
 * Implementation of the StructArray layout:
 * [0]: Int16[6]
 *
 * @private
 */
class StructArrayLayout6i12 extends StructArray {
                      
                      

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.int16 = new Int16Array(this.arrayBuffer);
    }

    emplaceBack(v0        , v1        , v2        , v3        , v4        , v5        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0, v1, v2, v3, v4, v5);
    }

    emplace(i        , v0        , v1        , v2        , v3        , v4        , v5        )         {
        const o2 = i * 6;
        this.int16[o2 + 0] = v0;
        this.int16[o2 + 1] = v1;
        this.int16[o2 + 2] = v2;
        this.int16[o2 + 3] = v3;
        this.int16[o2 + 4] = v4;
        this.int16[o2 + 5] = v5;
        return i;
    }
}

StructArrayLayout6i12.prototype.bytesPerElement = 12;
register(StructArrayLayout6i12, 'StructArrayLayout6i12');

/**
 * Implementation of the StructArray layout:
 * [0]: Int16[4]
 * [8]: Uint16[4]
 * [16]: Int16[4]
 *
 * @private
 */
class StructArrayLayout4i4ui4i24 extends StructArray {
                      
                      
                        

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.int16 = new Int16Array(this.arrayBuffer);
        this.uint16 = new Uint16Array(this.arrayBuffer);
    }

    emplaceBack(v0        , v1        , v2        , v3        , v4        , v5        , v6        , v7        , v8        , v9        , v10        , v11        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
    }

    emplace(i        , v0        , v1        , v2        , v3        , v4        , v5        , v6        , v7        , v8        , v9        , v10        , v11        )         {
        const o2 = i * 12;
        this.int16[o2 + 0] = v0;
        this.int16[o2 + 1] = v1;
        this.int16[o2 + 2] = v2;
        this.int16[o2 + 3] = v3;
        this.uint16[o2 + 4] = v4;
        this.uint16[o2 + 5] = v5;
        this.uint16[o2 + 6] = v6;
        this.uint16[o2 + 7] = v7;
        this.int16[o2 + 8] = v8;
        this.int16[o2 + 9] = v9;
        this.int16[o2 + 10] = v10;
        this.int16[o2 + 11] = v11;
        return i;
    }
}

StructArrayLayout4i4ui4i24.prototype.bytesPerElement = 24;
register(StructArrayLayout4i4ui4i24, 'StructArrayLayout4i4ui4i24');

/**
 * Implementation of the StructArray layout:
 * [0]: Int16[3]
 * [8]: Float32[3]
 *
 * @private
 */
class StructArrayLayout3i3f20 extends StructArray {
                      
                      
                          

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.int16 = new Int16Array(this.arrayBuffer);
        this.float32 = new Float32Array(this.arrayBuffer);
    }

    emplaceBack(v0        , v1        , v2        , v3        , v4        , v5        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0, v1, v2, v3, v4, v5);
    }

    emplace(i        , v0        , v1        , v2        , v3        , v4        , v5        )         {
        const o2 = i * 10;
        const o4 = i * 5;
        this.int16[o2 + 0] = v0;
        this.int16[o2 + 1] = v1;
        this.int16[o2 + 2] = v2;
        this.float32[o4 + 2] = v3;
        this.float32[o4 + 3] = v4;
        this.float32[o4 + 4] = v5;
        return i;
    }
}

StructArrayLayout3i3f20.prototype.bytesPerElement = 20;
register(StructArrayLayout3i3f20, 'StructArrayLayout3i3f20');

/**
 * Implementation of the StructArray layout:
 * [0]: Uint32[1]
 *
 * @private
 */
class StructArrayLayout1ul4 extends StructArray {
                      
                        

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.uint32 = new Uint32Array(this.arrayBuffer);
    }

    emplaceBack(v0        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0);
    }

    emplace(i        , v0        )         {
        const o4 = i * 1;
        this.uint32[o4 + 0] = v0;
        return i;
    }
}

StructArrayLayout1ul4.prototype.bytesPerElement = 4;
register(StructArrayLayout1ul4, 'StructArrayLayout1ul4');

/**
 * Implementation of the StructArray layout:
 * [0]: Int16[5]
 * [12]: Float32[4]
 * [28]: Int16[1]
 * [32]: Uint32[1]
 * [36]: Uint16[2]
 *
 * @private
 */
class StructArrayLayout5i4f1i1ul2ui40 extends StructArray {
                      
                      
                          
                        
                        

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.int16 = new Int16Array(this.arrayBuffer);
        this.float32 = new Float32Array(this.arrayBuffer);
        this.uint32 = new Uint32Array(this.arrayBuffer);
        this.uint16 = new Uint16Array(this.arrayBuffer);
    }

    emplaceBack(v0        , v1        , v2        , v3        , v4        , v5        , v6        , v7        , v8        , v9        , v10        , v11        , v12        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
    }

    emplace(i        , v0        , v1        , v2        , v3        , v4        , v5        , v6        , v7        , v8        , v9        , v10        , v11        , v12        )         {
        const o2 = i * 20;
        const o4 = i * 10;
        this.int16[o2 + 0] = v0;
        this.int16[o2 + 1] = v1;
        this.int16[o2 + 2] = v2;
        this.int16[o2 + 3] = v3;
        this.int16[o2 + 4] = v4;
        this.float32[o4 + 3] = v5;
        this.float32[o4 + 4] = v6;
        this.float32[o4 + 5] = v7;
        this.float32[o4 + 6] = v8;
        this.int16[o2 + 14] = v9;
        this.uint32[o4 + 8] = v10;
        this.uint16[o2 + 18] = v11;
        this.uint16[o2 + 19] = v12;
        return i;
    }
}

StructArrayLayout5i4f1i1ul2ui40.prototype.bytesPerElement = 40;
register(StructArrayLayout5i4f1i1ul2ui40, 'StructArrayLayout5i4f1i1ul2ui40');

/**
 * Implementation of the StructArray layout:
 * [0]: Int16[3]
 * [8]: Int16[2]
 * [12]: Int16[2]
 *
 * @private
 */
class StructArrayLayout3i2i2i16 extends StructArray {
                      
                      

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.int16 = new Int16Array(this.arrayBuffer);
    }

    emplaceBack(v0        , v1        , v2        , v3        , v4        , v5        , v6        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0, v1, v2, v3, v4, v5, v6);
    }

    emplace(i        , v0        , v1        , v2        , v3        , v4        , v5        , v6        )         {
        const o2 = i * 8;
        this.int16[o2 + 0] = v0;
        this.int16[o2 + 1] = v1;
        this.int16[o2 + 2] = v2;
        this.int16[o2 + 4] = v3;
        this.int16[o2 + 5] = v4;
        this.int16[o2 + 6] = v5;
        this.int16[o2 + 7] = v6;
        return i;
    }
}

StructArrayLayout3i2i2i16.prototype.bytesPerElement = 16;
register(StructArrayLayout3i2i2i16, 'StructArrayLayout3i2i2i16');

/**
 * Implementation of the StructArray layout:
 * [0]: Float32[2]
 * [8]: Float32[1]
 * [12]: Int16[2]
 *
 * @private
 */
class StructArrayLayout2f1f2i16 extends StructArray {
                      
                          
                      

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.float32 = new Float32Array(this.arrayBuffer);
        this.int16 = new Int16Array(this.arrayBuffer);
    }

    emplaceBack(v0        , v1        , v2        , v3        , v4        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0, v1, v2, v3, v4);
    }

    emplace(i        , v0        , v1        , v2        , v3        , v4        )         {
        const o4 = i * 4;
        const o2 = i * 8;
        this.float32[o4 + 0] = v0;
        this.float32[o4 + 1] = v1;
        this.float32[o4 + 2] = v2;
        this.int16[o2 + 6] = v3;
        this.int16[o2 + 7] = v4;
        return i;
    }
}

StructArrayLayout2f1f2i16.prototype.bytesPerElement = 16;
register(StructArrayLayout2f1f2i16, 'StructArrayLayout2f1f2i16');

/**
 * Implementation of the StructArray layout:
 * [0]: Uint8[2]
 * [4]: Float32[2]
 *
 * @private
 */
class StructArrayLayout2ub2f12 extends StructArray {
                      
                          

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.float32 = new Float32Array(this.arrayBuffer);
    }

    emplaceBack(v0        , v1        , v2        , v3        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0, v1, v2, v3);
    }

    emplace(i        , v0        , v1        , v2        , v3        )         {
        const o1 = i * 12;
        const o4 = i * 3;
        this.uint8[o1 + 0] = v0;
        this.uint8[o1 + 1] = v1;
        this.float32[o4 + 1] = v2;
        this.float32[o4 + 2] = v3;
        return i;
    }
}

StructArrayLayout2ub2f12.prototype.bytesPerElement = 12;
register(StructArrayLayout2ub2f12, 'StructArrayLayout2ub2f12');

/**
 * Implementation of the StructArray layout:
 * [0]: Float32[3]
 *
 * @private
 */
class StructArrayLayout3f12 extends StructArray {
                      
                          

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.float32 = new Float32Array(this.arrayBuffer);
    }

    emplaceBack(v0        , v1        , v2        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0, v1, v2);
    }

    emplace(i        , v0        , v1        , v2        )         {
        const o4 = i * 3;
        this.float32[o4 + 0] = v0;
        this.float32[o4 + 1] = v1;
        this.float32[o4 + 2] = v2;
        return i;
    }
}

StructArrayLayout3f12.prototype.bytesPerElement = 12;
register(StructArrayLayout3f12, 'StructArrayLayout3f12');

/**
 * Implementation of the StructArray layout:
 * [0]: Uint16[3]
 *
 * @private
 */
class StructArrayLayout3ui6 extends StructArray {
                      
                        

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.uint16 = new Uint16Array(this.arrayBuffer);
    }

    emplaceBack(v0        , v1        , v2        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0, v1, v2);
    }

    emplace(i        , v0        , v1        , v2        )         {
        const o2 = i * 3;
        this.uint16[o2 + 0] = v0;
        this.uint16[o2 + 1] = v1;
        this.uint16[o2 + 2] = v2;
        return i;
    }
}

StructArrayLayout3ui6.prototype.bytesPerElement = 6;
register(StructArrayLayout3ui6, 'StructArrayLayout3ui6');

/**
 * Implementation of the StructArray layout:
 * [0]: Int16[3]
 * [8]: Float32[2]
 * [16]: Uint16[2]
 * [20]: Uint32[3]
 * [32]: Uint16[3]
 * [40]: Float32[2]
 * [48]: Uint8[3]
 * [52]: Uint32[1]
 * [56]: Int16[1]
 * [58]: Uint8[1]
 *
 * @private
 */
class StructArrayLayout3i2f2ui3ul3ui2f3ub1ul1i1ub60 extends StructArray {
                      
                      
                          
                        
                        

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.int16 = new Int16Array(this.arrayBuffer);
        this.float32 = new Float32Array(this.arrayBuffer);
        this.uint16 = new Uint16Array(this.arrayBuffer);
        this.uint32 = new Uint32Array(this.arrayBuffer);
    }

    emplaceBack(v0        , v1        , v2        , v3        , v4        , v5        , v6        , v7        , v8        , v9        , v10        , v11        , v12        , v13        , v14        , v15        , v16        , v17        , v18        , v19        , v20        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20);
    }

    emplace(i        , v0        , v1        , v2        , v3        , v4        , v5        , v6        , v7        , v8        , v9        , v10        , v11        , v12        , v13        , v14        , v15        , v16        , v17        , v18        , v19        , v20        )         {
        const o2 = i * 30;
        const o4 = i * 15;
        const o1 = i * 60;
        this.int16[o2 + 0] = v0;
        this.int16[o2 + 1] = v1;
        this.int16[o2 + 2] = v2;
        this.float32[o4 + 2] = v3;
        this.float32[o4 + 3] = v4;
        this.uint16[o2 + 8] = v5;
        this.uint16[o2 + 9] = v6;
        this.uint32[o4 + 5] = v7;
        this.uint32[o4 + 6] = v8;
        this.uint32[o4 + 7] = v9;
        this.uint16[o2 + 16] = v10;
        this.uint16[o2 + 17] = v11;
        this.uint16[o2 + 18] = v12;
        this.float32[o4 + 10] = v13;
        this.float32[o4 + 11] = v14;
        this.uint8[o1 + 48] = v15;
        this.uint8[o1 + 49] = v16;
        this.uint8[o1 + 50] = v17;
        this.uint32[o4 + 13] = v18;
        this.int16[o2 + 28] = v19;
        this.uint8[o1 + 58] = v20;
        return i;
    }
}

StructArrayLayout3i2f2ui3ul3ui2f3ub1ul1i1ub60.prototype.bytesPerElement = 60;
register(StructArrayLayout3i2f2ui3ul3ui2f3ub1ul1i1ub60, 'StructArrayLayout3i2f2ui3ul3ui2f3ub1ul1i1ub60');

/**
 * Implementation of the StructArray layout:
 * [0]: Int16[3]
 * [8]: Float32[2]
 * [16]: Int16[6]
 * [28]: Uint16[15]
 * [60]: Uint32[1]
 * [64]: Float32[3]
 *
 * @private
 */
class StructArrayLayout3i2f6i15ui1ul3f76 extends StructArray {
                      
                      
                          
                        
                        

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.int16 = new Int16Array(this.arrayBuffer);
        this.float32 = new Float32Array(this.arrayBuffer);
        this.uint16 = new Uint16Array(this.arrayBuffer);
        this.uint32 = new Uint32Array(this.arrayBuffer);
    }

    emplaceBack(v0        , v1        , v2        , v3        , v4        , v5        , v6        , v7        , v8        , v9        , v10        , v11        , v12        , v13        , v14        , v15        , v16        , v17        , v18        , v19        , v20        , v21        , v22        , v23        , v24        , v25        , v26        , v27        , v28        , v29        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29);
    }

    emplace(i        , v0        , v1        , v2        , v3        , v4        , v5        , v6        , v7        , v8        , v9        , v10        , v11        , v12        , v13        , v14        , v15        , v16        , v17        , v18        , v19        , v20        , v21        , v22        , v23        , v24        , v25        , v26        , v27        , v28        , v29        )         {
        const o2 = i * 38;
        const o4 = i * 19;
        this.int16[o2 + 0] = v0;
        this.int16[o2 + 1] = v1;
        this.int16[o2 + 2] = v2;
        this.float32[o4 + 2] = v3;
        this.float32[o4 + 3] = v4;
        this.int16[o2 + 8] = v5;
        this.int16[o2 + 9] = v6;
        this.int16[o2 + 10] = v7;
        this.int16[o2 + 11] = v8;
        this.int16[o2 + 12] = v9;
        this.int16[o2 + 13] = v10;
        this.uint16[o2 + 14] = v11;
        this.uint16[o2 + 15] = v12;
        this.uint16[o2 + 16] = v13;
        this.uint16[o2 + 17] = v14;
        this.uint16[o2 + 18] = v15;
        this.uint16[o2 + 19] = v16;
        this.uint16[o2 + 20] = v17;
        this.uint16[o2 + 21] = v18;
        this.uint16[o2 + 22] = v19;
        this.uint16[o2 + 23] = v20;
        this.uint16[o2 + 24] = v21;
        this.uint16[o2 + 25] = v22;
        this.uint16[o2 + 26] = v23;
        this.uint16[o2 + 27] = v24;
        this.uint16[o2 + 28] = v25;
        this.uint32[o4 + 15] = v26;
        this.float32[o4 + 16] = v27;
        this.float32[o4 + 17] = v28;
        this.float32[o4 + 18] = v29;
        return i;
    }
}

StructArrayLayout3i2f6i15ui1ul3f76.prototype.bytesPerElement = 76;
register(StructArrayLayout3i2f6i15ui1ul3f76, 'StructArrayLayout3i2f6i15ui1ul3f76');

/**
 * Implementation of the StructArray layout:
 * [0]: Float32[1]
 *
 * @private
 */
class StructArrayLayout1f4 extends StructArray {
                      
                          

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.float32 = new Float32Array(this.arrayBuffer);
    }

    emplaceBack(v0        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0);
    }

    emplace(i        , v0        )         {
        const o4 = i * 1;
        this.float32[o4 + 0] = v0;
        return i;
    }
}

StructArrayLayout1f4.prototype.bytesPerElement = 4;
register(StructArrayLayout1f4, 'StructArrayLayout1f4');

/**
 * Implementation of the StructArray layout:
 * [0]: Float32[5]
 *
 * @private
 */
class StructArrayLayout5f20 extends StructArray {
                      
                          

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.float32 = new Float32Array(this.arrayBuffer);
    }

    emplaceBack(v0        , v1        , v2        , v3        , v4        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0, v1, v2, v3, v4);
    }

    emplace(i        , v0        , v1        , v2        , v3        , v4        )         {
        const o4 = i * 5;
        this.float32[o4 + 0] = v0;
        this.float32[o4 + 1] = v1;
        this.float32[o4 + 2] = v2;
        this.float32[o4 + 3] = v3;
        this.float32[o4 + 4] = v4;
        return i;
    }
}

StructArrayLayout5f20.prototype.bytesPerElement = 20;
register(StructArrayLayout5f20, 'StructArrayLayout5f20');

/**
 * Implementation of the StructArray layout:
 * [0]: Uint32[1]
 * [4]: Uint16[3]
 *
 * @private
 */
class StructArrayLayout1ul3ui12 extends StructArray {
                      
                        
                        

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.uint32 = new Uint32Array(this.arrayBuffer);
        this.uint16 = new Uint16Array(this.arrayBuffer);
    }

    emplaceBack(v0        , v1        , v2        , v3        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0, v1, v2, v3);
    }

    emplace(i        , v0        , v1        , v2        , v3        )         {
        const o4 = i * 3;
        const o2 = i * 6;
        this.uint32[o4 + 0] = v0;
        this.uint16[o2 + 2] = v1;
        this.uint16[o2 + 3] = v2;
        this.uint16[o2 + 4] = v3;
        return i;
    }
}

StructArrayLayout1ul3ui12.prototype.bytesPerElement = 12;
register(StructArrayLayout1ul3ui12, 'StructArrayLayout1ul3ui12');

/**
 * Implementation of the StructArray layout:
 * [0]: Uint16[2]
 *
 * @private
 */
class StructArrayLayout2ui4 extends StructArray {
                      
                        

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.uint16 = new Uint16Array(this.arrayBuffer);
    }

    emplaceBack(v0        , v1        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0, v1);
    }

    emplace(i        , v0        , v1        )         {
        const o2 = i * 2;
        this.uint16[o2 + 0] = v0;
        this.uint16[o2 + 1] = v1;
        return i;
    }
}

StructArrayLayout2ui4.prototype.bytesPerElement = 4;
register(StructArrayLayout2ui4, 'StructArrayLayout2ui4');

/**
 * Implementation of the StructArray layout:
 * [0]: Uint16[1]
 *
 * @private
 */
class StructArrayLayout1ui2 extends StructArray {
                      
                        

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.uint16 = new Uint16Array(this.arrayBuffer);
    }

    emplaceBack(v0        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0);
    }

    emplace(i        , v0        )         {
        const o2 = i * 1;
        this.uint16[o2 + 0] = v0;
        return i;
    }
}

StructArrayLayout1ui2.prototype.bytesPerElement = 2;
register(StructArrayLayout1ui2, 'StructArrayLayout1ui2');

/**
 * Implementation of the StructArray layout:
 * [0]: Float32[2]
 *
 * @private
 */
class StructArrayLayout2f8 extends StructArray {
                      
                          

    _refreshViews() {
        this.uint8 = new Uint8Array(this.arrayBuffer);
        this.float32 = new Float32Array(this.arrayBuffer);
    }

    emplaceBack(v0        , v1        )         {
        const i = this.length;
        this.resize(i + 1);
        return this.emplace(i, v0, v1);
    }

    emplace(i        , v0        , v1        )         {
        const o4 = i * 2;
        this.float32[o4 + 0] = v0;
        this.float32[o4 + 1] = v1;
        return i;
    }
}

StructArrayLayout2f8.prototype.bytesPerElement = 8;
register(StructArrayLayout2f8, 'StructArrayLayout2f8');

class CollisionBoxStruct extends Struct {
                                    
    get projectedAnchorX()         { return this._structArray.int16[this._pos2 + 0]; }
    get projectedAnchorY()         { return this._structArray.int16[this._pos2 + 1]; }
    get projectedAnchorZ()         { return this._structArray.int16[this._pos2 + 2]; }
    get tileAnchorX()         { return this._structArray.int16[this._pos2 + 3]; }
    get tileAnchorY()         { return this._structArray.int16[this._pos2 + 4]; }
    get x1()         { return this._structArray.float32[this._pos4 + 3]; }
    get y1()         { return this._structArray.float32[this._pos4 + 4]; }
    get x2()         { return this._structArray.float32[this._pos4 + 5]; }
    get y2()         { return this._structArray.float32[this._pos4 + 6]; }
    get padding()         { return this._structArray.int16[this._pos2 + 14]; }
    get featureIndex()         { return this._structArray.uint32[this._pos4 + 8]; }
    get sourceLayerIndex()         { return this._structArray.uint16[this._pos2 + 18]; }
    get bucketIndex()         { return this._structArray.uint16[this._pos2 + 19]; }
}

CollisionBoxStruct.prototype.size = 40;

                                              

/**
 * @private
 */
class CollisionBoxArray extends StructArrayLayout5i4f1i1ul2ui40 {
    /**
     * Return the CollisionBoxStruct at the given location in the array.
     * @param {number} index The index of the element.
     * @private
     */
    get(index        )                     {
        assert$1(!this.isTransferred);
        assert$1(index >= 0);
        assert$1(index < this.length);
        return new CollisionBoxStruct(this, index);
    }
}

register(CollisionBoxArray, 'CollisionBoxArray');

class PlacedSymbolStruct extends Struct {
                                    
    get projectedAnchorX()         { return this._structArray.int16[this._pos2 + 0]; }
    get projectedAnchorY()         { return this._structArray.int16[this._pos2 + 1]; }
    get projectedAnchorZ()         { return this._structArray.int16[this._pos2 + 2]; }
    get tileAnchorX()         { return this._structArray.float32[this._pos4 + 2]; }
    get tileAnchorY()         { return this._structArray.float32[this._pos4 + 3]; }
    get glyphStartIndex()         { return this._structArray.uint16[this._pos2 + 8]; }
    get numGlyphs()         { return this._structArray.uint16[this._pos2 + 9]; }
    get vertexStartIndex()         { return this._structArray.uint32[this._pos4 + 5]; }
    get lineStartIndex()         { return this._structArray.uint32[this._pos4 + 6]; }
    get lineLength()         { return this._structArray.uint32[this._pos4 + 7]; }
    get segment()         { return this._structArray.uint16[this._pos2 + 16]; }
    get lowerSize()         { return this._structArray.uint16[this._pos2 + 17]; }
    get upperSize()         { return this._structArray.uint16[this._pos2 + 18]; }
    get lineOffsetX()         { return this._structArray.float32[this._pos4 + 10]; }
    get lineOffsetY()         { return this._structArray.float32[this._pos4 + 11]; }
    get writingMode()         { return this._structArray.uint8[this._pos1 + 48]; }
    get placedOrientation()         { return this._structArray.uint8[this._pos1 + 49]; }
    set placedOrientation(x        ) { this._structArray.uint8[this._pos1 + 49] = x; }
    get hidden()         { return this._structArray.uint8[this._pos1 + 50]; }
    set hidden(x        ) { this._structArray.uint8[this._pos1 + 50] = x; }
    get crossTileID()         { return this._structArray.uint32[this._pos4 + 13]; }
    set crossTileID(x        ) { this._structArray.uint32[this._pos4 + 13] = x; }
    get associatedIconIndex()         { return this._structArray.int16[this._pos2 + 28]; }
    get flipState()         { return this._structArray.uint8[this._pos1 + 58]; }
    set flipState(x        ) { this._structArray.uint8[this._pos1 + 58] = x; }
}

PlacedSymbolStruct.prototype.size = 60;

                                              

/**
 * @private
 */
class PlacedSymbolArray extends StructArrayLayout3i2f2ui3ul3ui2f3ub1ul1i1ub60 {
    /**
     * Return the PlacedSymbolStruct at the given location in the array.
     * @param {number} index The index of the element.
     * @private
     */
    get(index        )                     {
        assert$1(!this.isTransferred);
        assert$1(index >= 0);
        assert$1(index < this.length);
        return new PlacedSymbolStruct(this, index);
    }
}

register(PlacedSymbolArray, 'PlacedSymbolArray');

class SymbolInstanceStruct extends Struct {
                                      
    get projectedAnchorX()         { return this._structArray.int16[this._pos2 + 0]; }
    get projectedAnchorY()         { return this._structArray.int16[this._pos2 + 1]; }
    get projectedAnchorZ()         { return this._structArray.int16[this._pos2 + 2]; }
    get tileAnchorX()         { return this._structArray.float32[this._pos4 + 2]; }
    get tileAnchorY()         { return this._structArray.float32[this._pos4 + 3]; }
    get rightJustifiedTextSymbolIndex()         { return this._structArray.int16[this._pos2 + 8]; }
    get centerJustifiedTextSymbolIndex()         { return this._structArray.int16[this._pos2 + 9]; }
    get leftJustifiedTextSymbolIndex()         { return this._structArray.int16[this._pos2 + 10]; }
    get verticalPlacedTextSymbolIndex()         { return this._structArray.int16[this._pos2 + 11]; }
    get placedIconSymbolIndex()         { return this._structArray.int16[this._pos2 + 12]; }
    get verticalPlacedIconSymbolIndex()         { return this._structArray.int16[this._pos2 + 13]; }
    get key()         { return this._structArray.uint16[this._pos2 + 14]; }
    get textBoxStartIndex()         { return this._structArray.uint16[this._pos2 + 15]; }
    get textBoxEndIndex()         { return this._structArray.uint16[this._pos2 + 16]; }
    get verticalTextBoxStartIndex()         { return this._structArray.uint16[this._pos2 + 17]; }
    get verticalTextBoxEndIndex()         { return this._structArray.uint16[this._pos2 + 18]; }
    get iconBoxStartIndex()         { return this._structArray.uint16[this._pos2 + 19]; }
    get iconBoxEndIndex()         { return this._structArray.uint16[this._pos2 + 20]; }
    get verticalIconBoxStartIndex()         { return this._structArray.uint16[this._pos2 + 21]; }
    get verticalIconBoxEndIndex()         { return this._structArray.uint16[this._pos2 + 22]; }
    get featureIndex()         { return this._structArray.uint16[this._pos2 + 23]; }
    get numHorizontalGlyphVertices()         { return this._structArray.uint16[this._pos2 + 24]; }
    get numVerticalGlyphVertices()         { return this._structArray.uint16[this._pos2 + 25]; }
    get numIconVertices()         { return this._structArray.uint16[this._pos2 + 26]; }
    get numVerticalIconVertices()         { return this._structArray.uint16[this._pos2 + 27]; }
    get useRuntimeCollisionCircles()         { return this._structArray.uint16[this._pos2 + 28]; }
    get crossTileID()         { return this._structArray.uint32[this._pos4 + 15]; }
    set crossTileID(x        ) { this._structArray.uint32[this._pos4 + 15] = x; }
    get textOffset0()         { return this._structArray.float32[this._pos4 + 16]; }
    get textOffset1()         { return this._structArray.float32[this._pos4 + 17]; }
    get collisionCircleDiameter()         { return this._structArray.float32[this._pos4 + 18]; }
}

SymbolInstanceStruct.prototype.size = 76;

                                                  

/**
 * @private
 */
class SymbolInstanceArray extends StructArrayLayout3i2f6i15ui1ul3f76 {
    /**
     * Return the SymbolInstanceStruct at the given location in the array.
     * @param {number} index The index of the element.
     * @private
     */
    get(index        )                       {
        assert$1(!this.isTransferred);
        assert$1(index >= 0);
        assert$1(index < this.length);
        return new SymbolInstanceStruct(this, index);
    }
}

register(SymbolInstanceArray, 'SymbolInstanceArray');

/**
 * @private
 */
class GlyphOffsetArray extends StructArrayLayout1f4 {
    getoffsetX(index        )         { return this.float32[index * 1 + 0]; }
}

register(GlyphOffsetArray, 'GlyphOffsetArray');

/**
 * @private
 */
class SymbolLineVertexArray extends StructArrayLayout2i4 {
    getx(index        )         { return this.int16[index * 2 + 0]; }
    gety(index        )         { return this.int16[index * 2 + 1]; }
}

register(SymbolLineVertexArray, 'SymbolLineVertexArray');

class FeatureIndexStruct extends Struct {
                                    
    get featureIndex()         { return this._structArray.uint32[this._pos4 + 0]; }
    get sourceLayerIndex()         { return this._structArray.uint16[this._pos2 + 2]; }
    get bucketIndex()         { return this._structArray.uint16[this._pos2 + 3]; }
    get layoutVertexArrayOffset()         { return this._structArray.uint16[this._pos2 + 4]; }
}

FeatureIndexStruct.prototype.size = 12;

                                              

/**
 * @private
 */
class FeatureIndexArray extends StructArrayLayout1ul3ui12 {
    /**
     * Return the FeatureIndexStruct at the given location in the array.
     * @param {number} index The index of the element.
     * @private
     */
    get(index        )                     {
        assert$1(!this.isTransferred);
        assert$1(index >= 0);
        assert$1(index < this.length);
        return new FeatureIndexStruct(this, index);
    }
}

register(FeatureIndexArray, 'FeatureIndexArray');

/**
 * @private
 */
class FillExtrusionCentroidArray extends StructArrayLayout2ui4 {
    geta_centroid_pos0(index        )         { return this.uint16[index * 2 + 0]; }
    geta_centroid_pos1(index        )         { return this.uint16[index * 2 + 1]; }
}

register(FillExtrusionCentroidArray, 'FillExtrusionCentroidArray');

//      

                                                                  

const patternAttributes                    = createLayout([
    // [tl.x, tl.y, br.x, br.y]
    {name: 'a_pattern', components: 4, type: 'Uint16'},
    {name: 'a_pixel_ratio', components: 1, type: 'Float32'}
]);

//      

                                                                  

const dashAttributes                    = createLayout([
    {name: 'a_dash', components: 4, type: 'Uint16'} // [x, y, width, unused]
]);

var murmurhashJs$1 = {exports: {}};

var murmurhash3_gc$2 = {exports: {}};

/**
 * JS Implementation of MurmurHash3 (r136) (as of May 20, 2011)
 * 
 * @author <a href="mailto:gary.court@gmail.com">Gary Court</a>
 * @see http://github.com/garycourt/murmurhash-js
 * @author <a href="mailto:aappleby@gmail.com">Austin Appleby</a>
 * @see http://sites.google.com/site/murmurhash/
 * 
 * @param {string} key ASCII only
 * @param {number} seed Positive integer only
 * @return {number} 32-bit positive integer hash 
 */
var murmurhash3_gc = murmurhash3_gc$2.exports;

(function (module) {
	function murmurhash3_32_gc(key, seed) {
		var remainder, bytes, h1, h1b, c1, c1b, c2, c2b, k1, i;
		
		remainder = key.length & 3; // key.length % 4
		bytes = key.length - remainder;
		h1 = seed;
		c1 = 0xcc9e2d51;
		c2 = 0x1b873593;
		i = 0;
		
		while (i < bytes) {
		  	k1 = 
		  	  ((key.charCodeAt(i) & 0xff)) |
		  	  ((key.charCodeAt(++i) & 0xff) << 8) |
		  	  ((key.charCodeAt(++i) & 0xff) << 16) |
		  	  ((key.charCodeAt(++i) & 0xff) << 24);
			++i;
			
			k1 = ((((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16))) & 0xffffffff;
			k1 = (k1 << 15) | (k1 >>> 17);
			k1 = ((((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16))) & 0xffffffff;

			h1 ^= k1;
	        h1 = (h1 << 13) | (h1 >>> 19);
			h1b = ((((h1 & 0xffff) * 5) + ((((h1 >>> 16) * 5) & 0xffff) << 16))) & 0xffffffff;
			h1 = (((h1b & 0xffff) + 0x6b64) + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16));
		}
		
		k1 = 0;
		
		switch (remainder) {
			case 3: k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;
			case 2: k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;
			case 1: k1 ^= (key.charCodeAt(i) & 0xff);
			
			k1 = (((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
			k1 = (k1 << 15) | (k1 >>> 17);
			k1 = (((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
			h1 ^= k1;
		}
		
		h1 ^= key.length;

		h1 ^= h1 >>> 16;
		h1 = (((h1 & 0xffff) * 0x85ebca6b) + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff;
		h1 ^= h1 >>> 13;
		h1 = ((((h1 & 0xffff) * 0xc2b2ae35) + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16))) & 0xffffffff;
		h1 ^= h1 >>> 16;

		return h1 >>> 0;
	}

	if('object' !== "undefined") {
	  module.exports = murmurhash3_32_gc;
	} 
} (murmurhash3_gc$2));

var murmurhash3_gcExports = murmurhash3_gc$2.exports;
var murmurhash3_gc$1 = /*@__PURE__*/getDefaultExportFromCjs(murmurhash3_gcExports);

var murmurhash2_gc$2 = {exports: {}};

/**
 * JS Implementation of MurmurHash2
 * 
 * @author <a href="mailto:gary.court@gmail.com">Gary Court</a>
 * @see http://github.com/garycourt/murmurhash-js
 * @author <a href="mailto:aappleby@gmail.com">Austin Appleby</a>
 * @see http://sites.google.com/site/murmurhash/
 * 
 * @param {string} str ASCII only
 * @param {number} seed Positive integer only
 * @return {number} 32-bit positive integer hash
 */
var murmurhash2_gc = murmurhash2_gc$2.exports;

(function (module) {
	function murmurhash2_32_gc(str, seed) {
	  var
	    l = str.length,
	    h = seed ^ l,
	    i = 0,
	    k;
	  
	  while (l >= 4) {
	  	k = 
	  	  ((str.charCodeAt(i) & 0xff)) |
	  	  ((str.charCodeAt(++i) & 0xff) << 8) |
	  	  ((str.charCodeAt(++i) & 0xff) << 16) |
	  	  ((str.charCodeAt(++i) & 0xff) << 24);
	    
	    k = (((k & 0xffff) * 0x5bd1e995) + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16));
	    k ^= k >>> 24;
	    k = (((k & 0xffff) * 0x5bd1e995) + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16));

		h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16)) ^ k;

	    l -= 4;
	    ++i;
	  }
	  
	  switch (l) {
	  case 3: h ^= (str.charCodeAt(i + 2) & 0xff) << 16;
	  case 2: h ^= (str.charCodeAt(i + 1) & 0xff) << 8;
	  case 1: h ^= (str.charCodeAt(i) & 0xff);
	          h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16));
	  }

	  h ^= h >>> 13;
	  h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16));
	  h ^= h >>> 15;

	  return h >>> 0;
	}

	if('object' !== undefined) {
	  module.exports = murmurhash2_32_gc;
	} 
} (murmurhash2_gc$2));

var murmurhash2_gcExports = murmurhash2_gc$2.exports;
var murmurhash2_gc$1 = /*@__PURE__*/getDefaultExportFromCjs(murmurhash2_gcExports);

var murmurhashJs = murmurhashJs$1.exports;

var murmur3 = murmurhash3_gcExports;
var murmur2 = murmurhash2_gcExports;

murmurhashJs$1.exports = murmur3;
var murmur3_1 = murmurhashJs$1.exports.murmur3 = murmur3;
var murmur2_1 = murmurhashJs$1.exports.murmur2 = murmur2;

var murmurhashJsExports = murmurhashJs$1.exports;
var murmur3$1 = /*@__PURE__*/getDefaultExportFromCjs(murmurhashJsExports);

//      


                                     
                      
                           
  

                        
                  
                  
                
  

// A transferable data structure that maps feature ids to their indices and buffer offsets
class FeaturePositionMap {
                       
                             
                     

    constructor() {
        this.ids = [];
        this.positions = [];
        this.indexed = false;
    }

    add(id       , index        , start        , end        ) {
        this.ids.push(getNumericId(id));
        this.positions.push(index, start, end);
    }

    getPositions(id       )                         {
        assert$1(this.indexed);

        const intId = getNumericId(id);

        // binary search for the first occurrence of id in this.ids;
        // relies on ids/positions being sorted by id, which happens in serialization
        let i = 0;
        let j = this.ids.length - 1;
        while (i < j) {
            const m = (i + j) >> 1;
            if (this.ids[m] >= intId) {
                j = m;
            } else {
                i = m + 1;
            }
        }
        const positions = [];
        while (this.ids[i] === intId) {
            const index = this.positions[3 * i];
            const start = this.positions[3 * i + 1];
            const end = this.positions[3 * i + 2];
            positions.push({index, start, end});
            i++;
        }
        return positions;
    }

    static serialize(map                    , transferables                    )                               {
        const ids = new Float64Array(map.ids);
        const positions = new Uint32Array(map.positions);

        sort$1(ids, positions, 0, ids.length - 1);

        if (transferables) {
            transferables.push(ids.buffer, positions.buffer);
        }

        return {ids, positions};
    }

    static deserialize(obj                              )                     {
        const map = new FeaturePositionMap();
        // after transferring, we only use these arrays statically (no pushes),
        // so TypedArray vs Array distinction that flow points out doesn't matter
        map.ids = (obj.ids     );
        map.positions = (obj.positions     );
        map.indexed = true;
        return map;
    }
}

function getNumericId(value       ) {
    const numValue = +value;
    if (!isNaN(numValue) && Number.MIN_SAFE_INTEGER <= numValue && numValue <= Number.MAX_SAFE_INTEGER) {
        return numValue;
    }
    return murmur3$1(String(value));
}

// custom quicksort that sorts ids, indices and offsets together (by ids)
// uses Hoare partitioning & manual tail call optimization to avoid worst case scenarios
function sort$1(ids              , positions             , left        , right        ) {
    while (left < right) {
        const pivot = ids[(left + right) >> 1];
        let i = left - 1;
        let j = right + 1;

        while (true) {
            do i++; while (ids[i] < pivot);
            do j--; while (ids[j] > pivot);
            if (i >= j) break;
            swap$2(ids, i, j);
            swap$2(positions, 3 * i, 3 * j);
            swap$2(positions, 3 * i + 1, 3 * j + 1);
            swap$2(positions, 3 * i + 2, 3 * j + 2);
        }

        if (j - left < right - j) {
            sort$1(ids, positions, left, j);
            left = j + 1;
        } else {
            sort$1(ids, positions, j + 1, right);
            right = j;
        }
    }
}

function swap$2(arr                            , i        , j        ) {
    const tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}

register(FeaturePositionMap, 'FeaturePositionMap');

//      

                                            

                                     
                                                   

class Uniform    {
                              
                                    
               
                         

    constructor(context         ) {
        this.gl = context.gl;
        this.initialized = false;
    }

    fetchUniformLocation(program              , name        )          {
        if (!this.location && !this.initialized) {
            this.location = this.gl.getUniformLocation(program, name);
            this.initialized = true;
        }
        return !!this.location;
    }

                                                              
}

class Uniform1i extends Uniform         {
    constructor(context         ) {
        super(context);
        this.current = 0;
    }

    // $FlowFixMe[method-unbinding]
    set(program              , name        , v        )       {
        if (!this.fetchUniformLocation(program, name)) return;
        if (this.current !== v) {
            this.current = v;
            this.gl.uniform1i(this.location, v);
        }
    }
}

class Uniform1f extends Uniform         {
    constructor(context         ) {
        super(context);
        this.current = 0;
    }

    // $FlowFixMe[method-unbinding]
    set(program              , name        , v        )       {
        if (!this.fetchUniformLocation(program, name)) return;
        if (this.current !== v) {
            this.current = v;
            this.gl.uniform1f(this.location, v);
        }
    }
}

class Uniform2f extends Uniform                   {
    constructor(context         ) {
        super(context);
        this.current = [0, 0];
    }

    // $FlowFixMe[method-unbinding]
    set(program              , name        , v                  )       {
        if (!this.fetchUniformLocation(program, name)) return;
        if (v[0] !== this.current[0] || v[1] !== this.current[1]) {
            this.current = v;
            this.gl.uniform2f(this.location, v[0], v[1]);
        }
    }
}

class Uniform3f extends Uniform                           {
    constructor(context         ) {
        super(context);
        this.current = [0, 0, 0];
    }

    // $FlowFixMe[method-unbinding]
    set(program              , name        , v                          )       {
        if (!this.fetchUniformLocation(program, name)) return;
        if (v[0] !== this.current[0] || v[1] !== this.current[1] || v[2] !== this.current[2]) {
            this.current = v;
            this.gl.uniform3f(this.location, v[0], v[1], v[2]);
        }
    }
}

class Uniform4f extends Uniform                                   {
    constructor(context         ) {
        super(context);
        this.current = [0, 0, 0, 0];
    }

    // $FlowFixMe[method-unbinding]
    set(program              , name        , v                                  )       {
        if (!this.fetchUniformLocation(program, name)) return;
        if (v[0] !== this.current[0] || v[1] !== this.current[1] ||
            v[2] !== this.current[2] || v[3] !== this.current[3]) {
            this.current = v;
            this.gl.uniform4f(this.location, v[0], v[1], v[2], v[3]);
        }
    }
}

class UniformColor extends Uniform        {
    constructor(context         ) {
        super(context);
        this.current = Color.transparent;
    }

    // $FlowFixMe[method-unbinding]
    set(program              , name        , v       )       {
        if (!this.fetchUniformLocation(program, name)) return;
        if (v.r !== this.current.r || v.g !== this.current.g ||
            v.b !== this.current.b || v.a !== this.current.a) {
            this.current = v;
            this.gl.uniform4f(this.location, v.r, v.g, v.b, v.a);
        }
    }
}

const emptyMat4 = new Float32Array(16);
class UniformMatrix4f extends Uniform               {
    constructor(context         ) {
        super(context);
        this.current = emptyMat4;
    }

    // $FlowFixMe[method-unbinding]
    set(program              , name        , v              )       {
        if (!this.fetchUniformLocation(program, name)) return;
        // The vast majority of matrix comparisons that will trip this set
        // happen at i=12 or i=0, so we check those first to avoid lots of
        // unnecessary iteration:
        if (v[12] !== this.current[12] || v[0] !== this.current[0]) {
            this.current = v;
            this.gl.uniformMatrix4fv(this.location, false, v);
            return;
        }
        for (let i = 1; i < 16; i++) {
            if (v[i] !== this.current[i]) {
                this.current = v;
                this.gl.uniformMatrix4fv(this.location, false, v);
                break;
            }
        }
    }
}

const emptyMat3 = new Float32Array(9);
class UniformMatrix3f extends Uniform               {
    constructor(context         ) {
        super(context);
        this.current = emptyMat3;
    }

    // $FlowFixMe[method-unbinding]
    set(program              , name        , v              )       {
        if (!this.fetchUniformLocation(program, name)) return;
        for (let i = 0; i < 9; i++) {
            if (v[i] !== this.current[i]) {
                this.current = v;
                this.gl.uniformMatrix3fv(this.location, false, v);
                break;
            }
        }
    }
}

const emptyMat2 = new Float32Array(4);
class UniformMatrix2f extends Uniform               {
    constructor(context         ) {
        super(context);
        this.current = emptyMat2;
    }

    // $FlowFixMe[method-unbinding]
    set(program              , name        , v              )       {
        if (!this.fetchUniformLocation(program, name)) return;
        for (let i = 0; i < 4; i++) {
            if (v[i] !== this.current[i]) {
                this.current = v;
                this.gl.uniformMatrix2fv(this.location, false, v);
                break;
            }
        }
    }
}

//      


                                                          
                                            
                                                                               
                                                                            
                                                       
                                                                      
             
            
                 
                     
                     
                       
                                           
                                                              
                                                             
                                                                                  
                                                          

                             
                 
                     
                         
  

function packColor(color       )                   {
    return [
        packUint8ToFloat(255 * color.r, 255 * color.g),
        packUint8ToFloat(255 * color.b, 255 * color.a)
    ];
}

/**
 *  `Binder` is the interface definition for the strategies for constructing,
 *  uploading, and binding paint property data as GLSL attributes. Most style-
 *  spec properties have a 1:1 relationship to shader attribute/uniforms, but
 *  some require multiple values per feature to be passed to the GPU, and in
 *  those cases we bind multiple attributes/uniforms.
 *
 *  It has three implementations, one for each of the three strategies we use:
 *
 *  * For _constant_ properties -- those whose value is a constant, or the constant
 *    result of evaluating a camera expression at a particular camera position -- we
 *    don't need a vertex attribute buffer, and instead use a uniform.
 *  * For data expressions, we use a vertex buffer with a single attribute value,
 *    the evaluated result of the source function for the given feature.
 *  * For composite expressions, we use a vertex buffer with two attributes: min and
 *    max values covering the range of zooms at which we expect the tile to be
 *    displayed. These values are calculated by evaluating the composite expression for
 *    the given feature at strategically chosen zoom levels. In addition to this
 *    attribute data, we also use a uniform value which the shader uses to interpolate
 *    between the min and max value at the final displayed zoom level. The use of a
 *    uniform allows us to cheaply update the value on every frame.
 *
 *  Note that the shader source varies depending on whether we're using a uniform or
 *  attribute. We dynamically compile shaders at runtime to accommodate this.
 *
 * @private
 */

                           
                                                                                                                                                                                                  
                                                                                                                                                                         
                          
                    
 

                         
                                
                                                                                                                                                                  
                                                                   
 

class ConstantBinder                          {
                 
                 
                                

    constructor(value       , names               , type        ) {
        this.value = value;
        this.uniformNames = names.map(name => `u_${name}`);
        this.type = type;
    }

    setUniform(program              , uniform            , globals                  , currentValue                                       , uniformName        )       {
        uniform.set(program, uniformName, currentValue.constantOr(this.value));
    }

    // $FlowFixMe[method-unbinding]
    getBinding(context         , _        )                       {
        // $FlowFixMe[method-unbinding]
        return (this.type === 'color') ?
            new UniformColor(context) :
            new Uniform1f(context);
    }
}

class PatternConstantBinder                          {
                                
                            
                       

    constructor(value       , names               ) {
        this.uniformNames = names.map(name => `u_${name}`);
        this.pattern = null;
        this.pixelRatio = 1;
    }

    setConstantPatternPositions(posTo                ) {
        this.pixelRatio = posTo.pixelRatio || 1;
        this.pattern = posTo.tl.concat(posTo.br);
    }

    setUniform(program              , uniform            , globals                  , currentValue                                       , uniformName        ) {
        const pos =
            uniformName === 'u_pattern' || uniformName === 'u_dash' ? this.pattern :
            uniformName === 'u_pixel_ratio' ? this.pixelRatio : null;
        if (pos) uniform.set(program, uniformName, pos);
    }

    // $FlowFixMe[method-unbinding]
    getBinding(context         , name        )                       {
        // $FlowFixMe[method-unbinding]
        return name === 'u_pattern' || name === 'u_dash' ?
            new Uniform4f(context) :
            new Uniform1f(context);
    }
}

class SourceExpressionBinder                            {
                                 
                 
                     

                                  
                                                    
                                     

    constructor(expression                  , names               , type        , PaintVertexArray                    ) {
        this.expression = expression;
        this.type = type;
        this.maxValue = 0;
        this.paintVertexAttributes = names.map((name) => ({
            name: `a_${name}`,
            type: 'Float32',
            components: type === 'color' ? 2 : 1,
            offset: 0
        }));
        this.paintVertexArray = new PaintVertexArray();
    }

    populatePaintArray(newLength        , feature         , imagePositions                 , availableImages               , canonical                  , formattedSection                   ) {
        const start = this.paintVertexArray.length;
        assert$1(Array.isArray(availableImages));
        // $FlowFixMe[method-unbinding]
        const value = this.expression.evaluate(new EvaluationParameters(0), feature, {}, canonical, availableImages, formattedSection);
        this.paintVertexArray.resize(newLength);
        this._setPaintValue(start, newLength, value);
    }

    updatePaintArray(start        , end        , feature         , featureState              , availableImages               ) {
        const value = this.expression.evaluate({zoom: 0}, feature, featureState, undefined, availableImages);
        this._setPaintValue(start, end, value);
    }

    _setPaintValue(start        , end        , value     ) {
        if (this.type === 'color') {
            const color = packColor(value);
            for (let i = start; i < end; i++) {
                this.paintVertexArray.emplace(i, color[0], color[1]);
            }
        } else {
            for (let i = start; i < end; i++) {
                this.paintVertexArray.emplace(i, value);
            }
            this.maxValue = Math.max(this.maxValue, Math.abs(value));
        }
    }

    upload(context         ) {
        if (this.paintVertexArray && this.paintVertexArray.arrayBuffer) {
            if (this.paintVertexBuffer && this.paintVertexBuffer.buffer) {
                this.paintVertexBuffer.updateData(this.paintVertexArray);
            } else {
                this.paintVertexBuffer = context.createVertexBuffer(this.paintVertexArray, this.paintVertexAttributes, this.expression.isStateDependent);
            }
        }
    }

    destroy() {
        if (this.paintVertexBuffer) {
            this.paintVertexBuffer.destroy();
        }
    }
}

class CompositeExpressionBinder                                           {
                                    
                                
                 
                            
                 
                     

                                  
                                                    
                                     

    constructor(expression                     , names               , type        , useIntegerZoom         , zoom        , PaintVertexArray                    ) {
        this.expression = expression;
        this.uniformNames = names.map(name => `u_${name}_t`);
        this.type = type;
        this.useIntegerZoom = useIntegerZoom;
        this.zoom = zoom;
        this.maxValue = 0;
        this.paintVertexAttributes = names.map((name) => ({
            name: `a_${name}`,
            type: 'Float32',
            components: type === 'color' ? 4 : 2,
            offset: 0
        }));
        this.paintVertexArray = new PaintVertexArray();
    }

    populatePaintArray(newLength        , feature         , imagePositions                 , availableImages               , canonical                  , formattedSection                   ) {
        // $FlowFixMe[method-unbinding]
        const min = this.expression.evaluate(new EvaluationParameters(this.zoom), feature, {}, canonical, availableImages, formattedSection);
        // $FlowFixMe[method-unbinding]
        const max = this.expression.evaluate(new EvaluationParameters(this.zoom + 1), feature, {}, canonical, availableImages, formattedSection);
        const start = this.paintVertexArray.length;
        this.paintVertexArray.resize(newLength);
        this._setPaintValue(start, newLength, min, max);
    }

    updatePaintArray(start        , end        , feature         , featureState              , availableImages               ) {
        const min = this.expression.evaluate({zoom: this.zoom}, feature, featureState, undefined, availableImages);
        const max = this.expression.evaluate({zoom: this.zoom + 1}, feature, featureState, undefined, availableImages);
        this._setPaintValue(start, end, min, max);
    }

    _setPaintValue(start        , end        , min     , max     ) {
        if (this.type === 'color') {
            const minColor = packColor(min);
            const maxColor = packColor(max);
            for (let i = start; i < end; i++) {
                this.paintVertexArray.emplace(i, minColor[0], minColor[1], maxColor[0], maxColor[1]);
            }
        } else {
            for (let i = start; i < end; i++) {
                this.paintVertexArray.emplace(i, min, max);
            }
            this.maxValue = Math.max(this.maxValue, Math.abs(min), Math.abs(max));
        }
    }

    upload(context         ) {
        if (this.paintVertexArray && this.paintVertexArray.arrayBuffer) {
            if (this.paintVertexBuffer && this.paintVertexBuffer.buffer) {
                this.paintVertexBuffer.updateData(this.paintVertexArray);
            } else {
                this.paintVertexBuffer = context.createVertexBuffer(this.paintVertexArray, this.paintVertexAttributes, this.expression.isStateDependent);
            }
        }
    }

    destroy() {
        if (this.paintVertexBuffer) {
            this.paintVertexBuffer.destroy();
        }
    }

    setUniform(program              , uniform            , globals                  , _                                   , uniformName        )       {
        const currentZoom = this.useIntegerZoom ? Math.floor(globals.zoom) : globals.zoom;
        const factor = clamp(this.expression.interpolationFactor(currentZoom, this.zoom, this.zoom + 1), 0, 1);
        uniform.set(program, uniformName, factor);
    }

    // $FlowFixMe[method-unbinding]
    getBinding(context         , _        )            {
        return new Uniform1f(context);
    }
}

class PatternCompositeBinder                            {
                                    
                    

                                  
                                     
                                                    

    constructor(expression                     , names               , type        , PaintVertexArray                    , layerId        ) {
        this.expression = expression;
        this.layerId = layerId;

        this.paintVertexAttributes = (type === 'array' ? dashAttributes : patternAttributes).members;
        for (let i = 0; i < names.length; ++i) {
            assert$1(`a_${names[i]}` === this.paintVertexAttributes[i].name);
        }

        this.paintVertexArray = new PaintVertexArray();
    }

    populatePaintArray(length        , feature         , imagePositions                 ) {
        const start = this.paintVertexArray.length;
        this.paintVertexArray.resize(length);
        this._setPaintValues(start, length, feature.patterns && feature.patterns[this.layerId], imagePositions);
    }

    updatePaintArray(start        , end        , feature         , featureState              , availableImages               , imagePositions                 ) {
        this._setPaintValues(start, end, feature.patterns && feature.patterns[this.layerId], imagePositions);
    }

    _setPaintValues(start        , end        , patterns         , positions                 ) {
        if (!positions || !patterns) return;

        const pos = positions[patterns];
        if (!pos) return;

        const {tl, br, pixelRatio} = pos;
        for (let i = start; i < end; i++) {
            this.paintVertexArray.emplace(i, tl[0], tl[1], br[0], br[1], pixelRatio);
        }
    }

    upload(context         ) {
        if (this.paintVertexArray && this.paintVertexArray.arrayBuffer) {
            this.paintVertexBuffer = context.createVertexBuffer(this.paintVertexArray, this.paintVertexAttributes, this.expression.isStateDependent);
        }
    }

    destroy() {
        if (this.paintVertexBuffer) this.paintVertexBuffer.destroy();
    }
}

/**
 * ProgramConfiguration contains the logic for binding style layer properties and tile
 * layer feature data into GL program uniforms and vertex attributes.
 *
 * Non-data-driven property values are bound to shader uniforms. Data-driven property
 * values are bound to vertex attributes. In order to support a uniform GLSL syntax over
 * both, [Mapbox GL Shaders](https://github.com/mapbox/mapbox-gl-shaders) defines a `#pragma`
 * abstraction, which ProgramConfiguration is responsible for implementing. At runtime,
 * it examines the attributes of a particular layer, combines this with fixed knowledge
 * about how layers of the particular type are implemented, and determines which uniforms
 * and vertex attributes will be required. It can then substitute the appropriate text
 * into the shader source code, create and link a program, and bind the uniforms and
 * vertex attributes in preparation for drawing.
 *
 * When a vector tile is parsed, this same configuration information is used to
 * populate the attribute buffers needed for data-driven styling using the zoom
 * level and feature property data.
 *
 * @private
 */
class ProgramConfiguration {
                                                               
                     

                                  

    constructor(layer                 , zoom        , filterProperties                         = () => true) {
        this.binders = {};
        this._buffers = [];

        const keys = [];

        for (const property in layer.paint._values) {
            if (!filterProperties(property)) continue;
            const value = layer.paint.get(property);
            if (!(value instanceof PossiblyEvaluatedPropertyValue) || !supportsPropertyExpression(value.property.specification)) {
                continue;
            }
            const names = paintAttributeNames(property, layer.type);
            const expression = value.value;
            const type = value.property.specification.type;
            const useIntegerZoom = !!value.property.useIntegerZoom;
            const isPattern = property === 'line-dasharray' || property.endsWith('pattern');
            const sourceException = property === 'line-dasharray' && (layer.layout     ).get('line-cap').value.kind !== 'constant';

            if (expression.kind === 'constant' && !sourceException) {
                this.binders[property] = isPattern ?
                    new PatternConstantBinder(expression.value, names) :
                    new ConstantBinder(expression.value, names, type);
                keys.push(`/u_${property}`);

            } else if (expression.kind === 'source' || sourceException || isPattern) {
                const StructArrayLayout = layoutType(property, type, 'source');
                this.binders[property] = isPattern ?
                    // $FlowFixMe[prop-missing]
                    // $FlowFixMe[incompatible-call] - expression can be a `composite` or `constant` kind expression
                    new PatternCompositeBinder(expression, names, type, StructArrayLayout, layer.id) :
                    // $FlowFixMe[prop-missing]
                    // $FlowFixMe[incompatible-call] - expression can be a `composite` or `constant` kind expression
                    new SourceExpressionBinder(expression, names, type, StructArrayLayout);

                keys.push(`/a_${property}`);

            } else {
                const StructArrayLayout = layoutType(property, type, 'composite');
                // $FlowFixMe[prop-missing]
                // $FlowFixMe[incompatible-call] — expression can be a `constant` kind expression
                this.binders[property] = new CompositeExpressionBinder(expression, names, type, useIntegerZoom, zoom, StructArrayLayout);
                keys.push(`/z_${property}`);
            }
        }

        this.cacheKey = keys.sort().join('');
    }

    getMaxValue(property        )         {
        const binder = this.binders[property];
        return binder instanceof SourceExpressionBinder || binder instanceof CompositeExpressionBinder ? binder.maxValue : 0;
    }

    populatePaintArrays(newLength        , feature         , imagePositions                 , availableImages               , canonical                  , formattedSection                   ) {
        for (const property in this.binders) {
            const binder = this.binders[property];
            if (binder instanceof SourceExpressionBinder || binder instanceof CompositeExpressionBinder || binder instanceof PatternCompositeBinder)
                (binder                 ).populatePaintArray(newLength, feature, imagePositions, availableImages, canonical, formattedSection);
        }
    }
    setConstantPatternPositions(posTo                ) {
        for (const property in this.binders) {
            const binder = this.binders[property];
            if (binder instanceof PatternConstantBinder)
                binder.setConstantPatternPositions(posTo);
        }
    }

    updatePaintArrays(featureStates               , featureMap                    , vtLayer                  , layer                 , availableImages               , imagePositions                 )          {
        let dirty          = false;
        for (const id in featureStates) {
            const positions = featureMap.getPositions(id);

            for (const pos of positions) {
                const feature = vtLayer.feature(pos.index);

                for (const property in this.binders) {
                    const binder = this.binders[property];
                    if ((binder instanceof SourceExpressionBinder || binder instanceof CompositeExpressionBinder ||
                         binder instanceof PatternCompositeBinder) && (binder     ).expression.isStateDependent === true) {
                        //AHM: Remove after https://github.com/mapbox/mapbox-gl-js/issues/6255
                        const value = layer.paint.get(property);
                        (binder     ).expression = value.value;
                        (binder                 ).updatePaintArray(pos.start, pos.end, feature, featureStates[id], availableImages, imagePositions);
                        dirty = true;
                    }
                }
            }
        }
        return dirty;
    }

    defines()                {
        const result = [];
        for (const property in this.binders) {
            const binder = this.binders[property];
            if (binder instanceof ConstantBinder || binder instanceof PatternConstantBinder) {
                result.push(...binder.uniformNames.map(name => `#define HAS_UNIFORM_${name}`));
            }
        }
        return result;
    }

    getBinderAttributes()                {
        const result = [];
        for (const property in this.binders) {
            const binder = this.binders[property];
            if (binder instanceof SourceExpressionBinder || binder instanceof CompositeExpressionBinder || binder instanceof PatternCompositeBinder) {
                for (let i = 0; i < binder.paintVertexAttributes.length; i++) {
                    result.push(binder.paintVertexAttributes[i].name);
                }
            }
        }
        return result;
    }

    getBinderUniforms()                {
        const uniforms = [];
        for (const property in this.binders) {
            const binder = this.binders[property];
            if (binder instanceof ConstantBinder || binder instanceof PatternConstantBinder || binder instanceof CompositeExpressionBinder) {
                for (const uniformName of binder.uniformNames) {
                    uniforms.push(uniformName);
                }
            }
        }
        return uniforms;
    }

    getPaintVertexBuffers()                      {
        return this._buffers;
    }

    getUniforms(context         )                       {
        const uniforms = [];
        for (const property in this.binders) {
            const binder = this.binders[property];
            if (binder instanceof ConstantBinder || binder instanceof PatternConstantBinder || binder instanceof CompositeExpressionBinder) {
                for (const name of binder.uniformNames) {
                    uniforms.push({name, property, binding: binder.getBinding(context, name)});
                }
            }
        }
        return uniforms;
    }

    setUniforms                    (program              , context         , binderUniforms                      , properties                               , globals                  ) {
        // Uniform state bindings are owned by the Program, but we set them
        // from within the ProgramConfiguration's binder members.
        for (const {name, property, binding} of binderUniforms) {
            (this.binders[property]     ).setUniform(program, binding, globals, properties.get(property), name);
        }
    }

    updatePaintBuffers() {
        this._buffers = [];

        for (const property in this.binders) {
            const binder = this.binders[property];
            if ((
                binder instanceof SourceExpressionBinder ||
                binder instanceof CompositeExpressionBinder ||
                binder instanceof PatternCompositeBinder) && binder.paintVertexBuffer) {
                this._buffers.push(binder.paintVertexBuffer);
            }
        }
    }

    upload(context         ) {
        for (const property in this.binders) {
            const binder = this.binders[property];
            if (binder instanceof SourceExpressionBinder || binder instanceof CompositeExpressionBinder || binder instanceof PatternCompositeBinder)
                binder.upload(context);
        }
        this.updatePaintBuffers();
    }

    destroy() {
        for (const property in this.binders) {
            const binder = this.binders[property];
            if (binder instanceof SourceExpressionBinder || binder instanceof CompositeExpressionBinder || binder instanceof PatternCompositeBinder)
                binder.destroy();
        }
    }
}

class ProgramConfigurationSet                         {
                                                               
                         
                                    
                          

    constructor(layers                       , zoom        , filterProperties                         = () => true) {
        this.programConfigurations = {};
        for (const layer of layers) {
            this.programConfigurations[layer.id] = new ProgramConfiguration(layer, zoom, filterProperties);
        }
        this.needsUpload = false;
        this._featureMap = new FeaturePositionMap();
        this._bufferOffset = 0;
    }

    populatePaintArrays(length        , feature         , index        , imagePositions                 , availableImages               , canonical                 , formattedSection                   ) {
        for (const key in this.programConfigurations) {
            this.programConfigurations[key].populatePaintArrays(length, feature, imagePositions, availableImages, canonical, formattedSection);
        }

        if (feature.id !== undefined) {
            this._featureMap.add(feature.id, index, this._bufferOffset, length);
        }
        this._bufferOffset = length;

        this.needsUpload = true;
    }

    updatePaintArrays(featureStates               , vtLayer                  , layers                                 , availableImages               , imagePositions                 ) {
        for (const layer of layers) {
            this.needsUpload = this.programConfigurations[layer.id].updatePaintArrays(featureStates, this._featureMap, vtLayer, layer, availableImages, imagePositions) || this.needsUpload;
        }
    }

    get(layerId        )                       {
        return this.programConfigurations[layerId];
    }

    upload(context         ) {
        if (!this.needsUpload) return;
        for (const layerId in this.programConfigurations) {
            this.programConfigurations[layerId].upload(context);
        }
        this.needsUpload = false;
    }

    destroy() {
        for (const layerId in this.programConfigurations) {
            this.programConfigurations[layerId].destroy();
        }
    }
}

const attributeNameExceptions = {
    'text-opacity': ['opacity'],
    'icon-opacity': ['opacity'],
    'text-color': ['fill_color'],
    'icon-color': ['fill_color'],
    'text-halo-color': ['halo_color'],
    'icon-halo-color': ['halo_color'],
    'text-halo-blur': ['halo_blur'],
    'icon-halo-blur': ['halo_blur'],
    'text-halo-width': ['halo_width'],
    'icon-halo-width': ['halo_width'],
    'line-gap-width': ['gapwidth'],
    'line-pattern': ['pattern', 'pixel_ratio'],
    'fill-pattern': ['pattern', 'pixel_ratio'],
    'fill-extrusion-pattern': ['pattern', 'pixel_ratio'],
    'line-dasharray': ['dash']
};

function paintAttributeNames(property        , type        ) {
    return attributeNameExceptions[property] || [property.replace(`${type}-`, '').replace(/-/g, '_')];
}

const propertyExceptions = {
    'line-pattern': {
        'source': StructArrayLayout4ui1f12,
        'composite': StructArrayLayout4ui1f12
    },
    'fill-pattern': {
        'source': StructArrayLayout4ui1f12,
        'composite': StructArrayLayout4ui1f12
    },
    'fill-extrusion-pattern':{
        'source': StructArrayLayout4ui1f12,
        'composite': StructArrayLayout4ui1f12
    },
    'line-dasharray': { // temporary layout
        'source': StructArrayLayout4ui8,
        'composite': StructArrayLayout4ui8
    }
};

const defaultLayouts = {
    'color': {
        'source': StructArrayLayout2f8,
        'composite': StructArrayLayout4f16
    },
    'number': {
        'source': StructArrayLayout1f4,
        'composite': StructArrayLayout2f8
    }
};

                                                                                                 

function layoutType(property        , type            , binderType        ) {
    const layoutException = propertyExceptions[property];
    // $FlowFixMe[prop-missing] - we don't cover all types in defaultLayouts for some reason
    return (layoutException && layoutException[binderType]) || defaultLayouts[type][binderType];
}

register(ConstantBinder, 'ConstantBinder');
register(PatternConstantBinder, 'PatternConstantBinder');
register(SourceExpressionBinder, 'SourceExpressionBinder');
register(PatternCompositeBinder, 'PatternCompositeBinder');
register(CompositeExpressionBinder, 'CompositeExpressionBinder');
register(ProgramConfiguration, 'ProgramConfiguration', {omit: ['_buffers']});
register(ProgramConfigurationSet, 'ProgramConfigurationSet');

//      


                                                                    
                                              
                                                
                                                                                           
                                                                         
                                                                   
                                                 
             
                       
                        
                            
                              
                                
                                                                              
                                    
                                                   
                                                                
                                                        
                                                            

const TRANSITION_SUFFIX = '-transition';

class StyleLayer extends Evented {
               
                    
                 
                   
                         
                     
                     
                                       
                                          

                                    
                   

                                              
                                            
                  

                                  
                             

                                             
                                                                    
                                                          
                                                         
                                                            
                                           
                                                   
                                                           
                                                           
                                                                                   

                                
                                   

    constructor(layer                                           , properties                                                            ) {
        super();

        this.id = layer.id;
        this.type = layer.type;
        this._featureFilter = {filter: () => true, needGeometry: false, needFeature: false};
        this._filterCompiled = false;

        if (layer.type === 'custom') return;

        layer = ((layer     )                    );

        this.metadata = layer.metadata;
        this.minzoom = layer.minzoom;
        this.maxzoom = layer.maxzoom;

        if (layer.type !== 'background' && layer.type !== 'sky') {
            this.source = layer.source;
            this.sourceLayer = layer['source-layer'];
            this.filter = layer.filter;
        }

        if (properties.layout) {
            this._unevaluatedLayout = new Layout(properties.layout);
        }

        if (properties.paint) {
            this._transitionablePaint = new Transitionable(properties.paint);

            for (const property in layer.paint) {
                this.setPaintProperty(property, layer.paint[property], {validate: false});
            }
            for (const property in layer.layout) {
                this.setLayoutProperty(property, layer.layout[property], {validate: false});
            }

            this._transitioningPaint = this._transitionablePaint.untransitioned();
            //$FlowFixMe
            this.paint = new PossiblyEvaluated(properties.paint);
        }
    }

    getLayoutProperty(name        )                                    {
        if (name === 'visibility') {
            return this.visibility;
        }

        return this._unevaluatedLayout.getValue(name);
    }

    setLayoutProperty(name        , value     , options                     = {}) {
        if (value !== null && value !== undefined) {
            const key = `layers.${this.id}.layout.${name}`;
            if (this._validate(validateLayoutProperty, key, name, value, options)) {
                return;
            }
        }

        if (name === 'visibility') {
            this.visibility = value;
            return;
        }

        this._unevaluatedLayout.setValue(name, value);
    }

    getPaintProperty(name        )                                                                     {
        if (endsWith(name, TRANSITION_SUFFIX)) {
            return this._transitionablePaint.getTransition(name.slice(0, -TRANSITION_SUFFIX.length));
        } else {
            return this._transitionablePaint.getValue(name);
        }
    }

    setPaintProperty(name        , value       , options                     = {})          {
        if (value !== null && value !== undefined) {
            const key = `layers.${this.id}.paint.${name}`;
            if (this._validate(validatePaintProperty, key, name, value, options)) {
                return false;
            }
        }

        if (endsWith(name, TRANSITION_SUFFIX)) {
            this._transitionablePaint.setTransition(name.slice(0, -TRANSITION_SUFFIX.length), (value     ) || undefined);
            return false;
        } else {
            const transitionable = this._transitionablePaint._values[name];
            const wasDataDriven = transitionable.value.isDataDriven();
            const oldValue = transitionable.value;

            this._transitionablePaint.setValue(name, value);
            this._handleSpecialPaintPropertyUpdate(name);

            const newValue = this._transitionablePaint._values[name].value;
            const isDataDriven = newValue.isDataDriven();
            const isPattern = endsWith(name, 'pattern') || name === 'line-dasharray';

            // if a pattern value is changed, we need to make sure the new icons get added to each tile's iconAtlas
            // so a call to _updateLayer is necessary, and we return true from this function so it gets called in
            // Style#setPaintProperty
            return isDataDriven || wasDataDriven || isPattern || this._handleOverridablePaintPropertyUpdate(name, oldValue, newValue);
        }
    }

    _handleSpecialPaintPropertyUpdate(_        ) {
        // No-op; can be overridden by derived classes.
    }

    getProgramIds()                  {
        // No-op; can be overridden by derived classes.
        return null;
    }

    getProgramConfiguration(_        )                              {
        // No-op; can be overridden by derived classes.
        return null;
    }

    // eslint-disable-next-line no-unused-vars
    _handleOverridablePaintPropertyUpdate      (name        , oldValue                     , newValue                     )          {
        // No-op; can be overridden by derived classes.
        return false;
    }

    isHidden(zoom        )          {
        if (this.minzoom && zoom < this.minzoom) return true;
        if (this.maxzoom && zoom >= this.maxzoom) return true;
        return this.visibility === 'none';
    }

    updateTransitions(parameters                      ) {
        this._transitioningPaint = this._transitionablePaint.transitioned(parameters, this._transitioningPaint);
    }

    hasTransition()          {
        return this._transitioningPaint.hasTransition();
    }

    recalculate(parameters                      , availableImages               ) {
        if (this._unevaluatedLayout) {
            (this     ).layout = this._unevaluatedLayout.possiblyEvaluate(parameters, undefined, availableImages);
        }

        (this     ).paint = this._transitioningPaint.possiblyEvaluate(parameters, undefined, availableImages);
    }

    serialize()                     {
        const output      = {
            'id': this.id,
            'type': this.type,
            'source': this.source,
            'source-layer': this.sourceLayer,
            'metadata': this.metadata,
            'minzoom': this.minzoom,
            'maxzoom': this.maxzoom,
            'filter': this.filter,
            'layout': this._unevaluatedLayout && this._unevaluatedLayout.serialize(),
            'paint': this._transitionablePaint && this._transitionablePaint.serialize()
        };

        if (this.visibility) {
            output.layout = output.layout || {};
            output.layout.visibility = this.visibility;
        }

        return filterObject(output, (value, key) => {
            return value !== undefined &&
                !(key === 'layout' && !Object.keys(value).length) &&
                !(key === 'paint' && !Object.keys(value).length);
        });
    }

    _validate(validate          , key        , name        , value       , options                     = {})          {
        if (options && options.validate === false) {
            return false;
        }
        return emitValidationErrors(this, validate.call(validateStyle, {
            key,
            layerType: this.type,
            objectKey: name,
            value,
            styleSpec: spec,
            // Workaround for https://github.com/mapbox/mapbox-gl-js/issues/2407
            style: {glyphs: true, sprite: true}
        }));
    }

    is3D()          {
        return false;
    }

    isSky()          {
        return false;
    }

    isTileClipped()          {
        return false;
    }

    hasOffscreenPass()          {
        return false;
    }

    resize() {
        // noop
    }

    isStateDependent()          {
        for (const property in (this     ).paint._values) {
            const value = (this     ).paint.get(property);
            if (!(value instanceof PossiblyEvaluatedPropertyValue) || !supportsPropertyExpression(value.property.specification)) {
                continue;
            }

            if ((value.value.kind === 'source' || value.value.kind === 'composite') &&
                value.value.isStateDependent) {
                return true;
            }
        }
        return false;
    }

    compileFilter() {
        if (!this._filterCompiled) {
            this._featureFilter = createFilter(this.filter);
            this._filterCompiled = true;
        }
    }

    invalidateCompiledFilter() {
        this._filterCompiled = false;
    }

    dynamicFilter()                    {
        return this._featureFilter.dynamicFilter;
    }

    dynamicFilterNeedsFeature()          {
        return this._featureFilter.needFeature;
    }
}

//      

                                                                  

const circleAttributes                    = createLayout([
    {name: 'a_pos', components: 2, type: 'Int16'}
], 4);

const circleGlobeAttributesExt                    = createLayout([
    {name: 'a_pos_3', components: 3, type: 'Int16'},
    {name: 'a_pos_normal_3', components: 3, type: 'Int16'}
]);

const {members: members$5, size: size$5, alignment: alignment$5} = circleAttributes;

//      


                                                                      
                                                         

                       
                           
                         
                            
                         
                            
                                          
 

class SegmentVector {
                                           
                             

    constructor(segments                  = []) {
        this.segments = segments;
    }

    prepareSegment(numVertices        , layoutVertexArray             , indexArray             , sortKey         )          {
        let segment          = this.segments[this.segments.length - 1];
        if (numVertices > SegmentVector.MAX_VERTEX_ARRAY_LENGTH) warnOnce(`Max vertices per segment is ${SegmentVector.MAX_VERTEX_ARRAY_LENGTH}: bucket requested ${numVertices}`);
        if (!segment || segment.vertexLength + numVertices > SegmentVector.MAX_VERTEX_ARRAY_LENGTH || segment.sortKey !== sortKey) {
            segment = ({
                vertexOffset: layoutVertexArray.length,
                primitiveOffset: indexArray.length,
                vertexLength: 0,
                primitiveLength: 0
            }     );
            if (sortKey !== undefined) segment.sortKey = sortKey;
            this.segments.push(segment);
        }
        return segment;
    }

    get()                 {
        return this.segments;
    }

    destroy() {
        for (const segment of this.segments) {
            for (const k in segment.vaos) {
                segment.vaos[k].destroy();
            }
        }
    }

    static simpleSegment(vertexOffset        , primitiveOffset        , vertexLength        , primitiveLength        )                {
        return new SegmentVector([{
            vertexOffset,
            primitiveOffset,
            vertexLength,
            primitiveLength,
            vaos: {},
            sortKey: 0
        }]);
    }
}

/*
 * The maximum size of a vertex array. This limit is imposed by WebGL's 16 bit
 * addressing of vertex buffers.
 * @private
 * @readonly
 */
SegmentVector.MAX_VERTEX_ARRAY_LENGTH = Math.pow(2, 16) - 1;

register(SegmentVector, 'SegmentVector');

//

//      

/**
 * The maximum value of a coordinate in the internal tile coordinate system. Coordinates of
 * all source features normalized to this extent upon load.
 *
 * The value is a consequence of the following:
 *
 * * Vertex buffer store positions as signed 16 bit integers.
 * * One bit is lost for signedness to support tile buffers.
 * * One bit is lost because the line vertex buffer used to pack 1 bit of other data into the int.
 * * One bit is lost to support features extending past the extent on the right edge of the tile.
 * * This leaves us with 2^13 = 8192
 *
 * @private
 * @readonly
 */
var EXTENT = 8192;

//      


                                             

/**
 * A `LngLatBounds` object represents a geographical bounding box,
 * defined by its southwest and northeast points in longitude and latitude.
 *
 * If no arguments are provided to the constructor, a `null` bounding box is created.
 *
 * Note that any Mapbox GL method that accepts a `LngLatBounds` object as an argument or option
 * can also accept an `Array` of two {@link LngLatLike} constructs and will perform an implicit conversion.
 * This flexible type is documented as {@link LngLatBoundsLike}.
 *
 * @param {LngLatLike} [sw] The southwest corner of the bounding box.
 * @param {LngLatLike} [ne] The northeast corner of the bounding box.
 * @example
 * const sw = new mapboxgl.LngLat(-73.9876, 40.7661);
 * const ne = new mapboxgl.LngLat(-73.9397, 40.8002);
 * const llb = new mapboxgl.LngLatBounds(sw, ne);
 */
class LngLatBounds {
                
                

    // This constructor is too flexible to type. It should not be so flexible.
    constructor(sw     , ne     ) {
        if (!sw) {
            // noop
        } else if (ne) {
            this.setSouthWest(sw).setNorthEast(ne);
        } else if (sw.length === 4) {
            this.setSouthWest([sw[0], sw[1]]).setNorthEast([sw[2], sw[3]]);
        } else {
            this.setSouthWest(sw[0]).setNorthEast(sw[1]);
        }
    }

    /**
     * Set the northeast corner of the bounding box.
     *
     * @param {LngLatLike} ne A {@link LngLatLike} object describing the northeast corner of the bounding box.
     * @returns {LngLatBounds} Returns itself to allow for method chaining.
     * @example
     * const sw = new mapboxgl.LngLat(-73.9876, 40.7661);
     * const ne = new mapboxgl.LngLat(-73.9397, 40.8002);
     * const llb = new mapboxgl.LngLatBounds(sw, ne);
     * llb.setNorthEast([-73.9397, 42.8002]);
     */
    setNorthEast(ne            )       {
        this._ne = ne instanceof LngLat$1 ? new LngLat$1(ne.lng, ne.lat) : LngLat$1.convert(ne);
        return this;
    }

    /**
     * Set the southwest corner of the bounding box.
     *
     * @param {LngLatLike} sw A {@link LngLatLike} object describing the southwest corner of the bounding box.
     * @returns {LngLatBounds} Returns itself to allow for method chaining.
     * @example
     * const sw = new mapboxgl.LngLat(-73.9876, 40.7661);
     * const ne = new mapboxgl.LngLat(-73.9397, 40.8002);
     * const llb = new mapboxgl.LngLatBounds(sw, ne);
     * llb.setSouthWest([-73.9876, 40.2661]);
     */
    setSouthWest(sw            )       {
        this._sw = sw instanceof LngLat$1 ? new LngLat$1(sw.lng, sw.lat) : LngLat$1.convert(sw);
        return this;
    }

    /**
     * Extend the bounds to include a given LngLatLike or LngLatBoundsLike.
     *
     * @param {LngLatLike|LngLatBoundsLike} obj Object to extend to.
     * @returns {LngLatBounds} Returns itself to allow for method chaining.
     * @example
     * const sw = new mapboxgl.LngLat(-73.9876, 40.7661);
     * const ne = new mapboxgl.LngLat(-73.9397, 40.8002);
     * const llb = new mapboxgl.LngLatBounds(sw, ne);
     * llb.extend([-72.9876, 42.2661]);
     */
    extend(obj                               )       {
        const sw = this._sw,
            ne = this._ne;
        let sw2, ne2;

        if (obj instanceof LngLat$1) {
            sw2 = obj;
            ne2 = obj;

        } else if (obj instanceof LngLatBounds) {
            sw2 = obj._sw;
            ne2 = obj._ne;

            if (!sw2 || !ne2) return this;

        } else if (Array.isArray(obj)) {
            // $FlowFixMe[method-unbinding]
            if (obj.length === 4 || obj.every(Array.isArray)) {
                const lngLatBoundsObj = ((obj     )                  );
                return this.extend(LngLatBounds.convert(lngLatBoundsObj));
            } else {
                const lngLatObj = ((obj     )            );
                return this.extend(LngLat$1.convert(lngLatObj));
            }
        } else if (typeof obj === 'object' && obj !== null && obj.hasOwnProperty("lat") && (obj.hasOwnProperty("lon") || obj.hasOwnProperty("lng"))) {
            return this.extend(LngLat$1.convert(obj));
        } else {
            return this;
        }

        if (!sw && !ne) {
            this._sw = new LngLat$1(sw2.lng, sw2.lat);
            this._ne = new LngLat$1(ne2.lng, ne2.lat);

        } else {
            sw.lng = Math.min(sw2.lng, sw.lng);
            sw.lat = Math.min(sw2.lat, sw.lat);
            ne.lng = Math.max(ne2.lng, ne.lng);
            ne.lat = Math.max(ne2.lat, ne.lat);
        }

        return this;
    }

    /**
     * Returns the geographical coordinate equidistant from the bounding box's corners.
     *
     * @returns {LngLat} The bounding box's center.
     * @example
     * const llb = new mapboxgl.LngLatBounds([-73.9876, 40.7661], [-73.9397, 40.8002]);
     * llb.getCenter(); // = LngLat {lng: -73.96365, lat: 40.78315}
     */
    getCenter()         {
        return new LngLat$1((this._sw.lng + this._ne.lng) / 2, (this._sw.lat + this._ne.lat) / 2);
    }

    /**
     * Returns the southwest corner of the bounding box.
     *
     * @returns {LngLat} The southwest corner of the bounding box.
     * @example
     * const llb = new mapboxgl.LngLatBounds([-73.9876, 40.7661], [-73.9397, 40.8002]);
     * llb.getSouthWest(); // LngLat {lng: -73.9876, lat: 40.7661}
     */
    getSouthWest()         { return this._sw; }

    /**
     * Returns the northeast corner of the bounding box.
     *
     * @returns {LngLat} The northeast corner of the bounding box.
     * @example
     * const llb = new mapboxgl.LngLatBounds([-73.9876, 40.7661], [-73.9397, 40.8002]);
     * llb.getNorthEast(); // LngLat {lng: -73.9397, lat: 40.8002}
     */
    getNorthEast()         { return this._ne; }

    /**
     * Returns the northwest corner of the bounding box.
     *
     * @returns {LngLat} The northwest corner of the bounding box.
     * @example
     * const llb = new mapboxgl.LngLatBounds([-73.9876, 40.7661], [-73.9397, 40.8002]);
     * llb.getNorthWest(); // LngLat {lng: -73.9876, lat: 40.8002}
     */
    getNorthWest()         { return new LngLat$1(this.getWest(), this.getNorth()); }

    /**
     * Returns the southeast corner of the bounding box.
     *
     * @returns {LngLat} The southeast corner of the bounding box.
     * @example
     * const llb = new mapboxgl.LngLatBounds([-73.9876, 40.7661], [-73.9397, 40.8002]);
     * llb.getSouthEast(); // LngLat {lng: -73.9397, lat: 40.7661}
     */
    getSouthEast()         { return new LngLat$1(this.getEast(), this.getSouth()); }

    /**
     * Returns the west edge of the bounding box.
     *
     * @returns {number} The west edge of the bounding box.
     * @example
     * const llb = new mapboxgl.LngLatBounds([-73.9876, 40.7661], [-73.9397, 40.8002]);
     * llb.getWest(); // -73.9876
     */
    getWest()         { return this._sw.lng; }

    /**
     * Returns the south edge of the bounding box.
     *
     * @returns {number} The south edge of the bounding box.
     * @example
     * const llb = new mapboxgl.LngLatBounds([-73.9876, 40.7661], [-73.9397, 40.8002]);
     * llb.getSouth(); // 40.7661
     */
    getSouth()         { return this._sw.lat; }

    /**
     * Returns the east edge of the bounding box.
     *
     * @returns {number} The east edge of the bounding box.
     * @example
     * const llb = new mapboxgl.LngLatBounds([-73.9876, 40.7661], [-73.9397, 40.8002]);
     * llb.getEast(); // -73.9397
     */
    getEast()         { return this._ne.lng; }

    /**
     * Returns the north edge of the bounding box.
     *
     * @returns {number} The north edge of the bounding box.
     * @example
     * const llb = new mapboxgl.LngLatBounds([-73.9876, 40.7661], [-73.9397, 40.8002]);
     * llb.getNorth(); // 40.8002
     */
    getNorth()         { return this._ne.lat; }

    /**
     * Returns the bounding box represented as an array.
     *
     * @returns {Array<Array<number>>} The bounding box represented as an array, consisting of the
     *   southwest and northeast coordinates of the bounding represented as arrays of numbers.
     * @example
     * const llb = new mapboxgl.LngLatBounds([-73.9876, 40.7661], [-73.9397, 40.8002]);
     * llb.toArray(); // = [[-73.9876, 40.7661], [-73.9397, 40.8002]]
     */
    toArray()                                       {
        return [this._sw.toArray(), this._ne.toArray()];
    }

    /**
     * Return the bounding box represented as a string.
     *
     * @returns {string} The bounding box represents as a string of the format
     *   `'LngLatBounds(LngLat(lng, lat), LngLat(lng, lat))'`.
     * @example
     * const llb = new mapboxgl.LngLatBounds([-73.9876, 40.7661], [-73.9397, 40.8002]);
     * llb.toString(); // = "LngLatBounds(LngLat(-73.9876, 40.7661), LngLat(-73.9397, 40.8002))"
     */
    toString()         {
        return `LngLatBounds(${this._sw.toString()}, ${this._ne.toString()})`;
    }

    /**
     * Check if the bounding box is an empty/`null`-type box.
     *
     * @returns {boolean} True if bounds have been defined, otherwise false.
     * @example
     * const llb = new mapboxgl.LngLatBounds();
     * llb.isEmpty(); // true
     * llb.setNorthEast([-73.9876, 40.7661]);
     * llb.setSouthWest([-73.9397, 40.8002]);
     * llb.isEmpty(); // false
     */
    isEmpty()          {
        return !(this._sw && this._ne);
    }

    /**
    * Check if the point is within the bounding box.
    *
    * @param {LngLatLike} lnglat Geographic point to check against.
    * @returns {boolean} True if the point is within the bounding box.
    * @example
    * const llb = new mapboxgl.LngLatBounds(
    *   new mapboxgl.LngLat(-73.9876, 40.7661),
    *   new mapboxgl.LngLat(-73.9397, 40.8002)
    * );
    *
    * const ll = new mapboxgl.LngLat(-73.9567, 40.7789);
    *
    * console.log(llb.contains(ll)); // = true
    */
    contains(lnglat            )          {
        const {lng, lat} = LngLat$1.convert(lnglat);

        const containsLatitude = this._sw.lat <= lat && lat <= this._ne.lat;
        let containsLongitude = this._sw.lng <= lng && lng <= this._ne.lng;
        if (this._sw.lng > this._ne.lng) { // wrapped coordinates
            containsLongitude = this._sw.lng >= lng && lng >= this._ne.lng;
        }

        return containsLatitude && containsLongitude;
    }

    /**
     * Converts an array to a `LngLatBounds` object.
     *
     * If a `LngLatBounds` object is passed in, the function returns it unchanged.
     *
     * Internally, the function calls `LngLat#convert` to convert arrays to `LngLat` values.
     *
     * @param {LngLatBoundsLike} input An array of two coordinates to convert, or a `LngLatBounds` object to return.
     * @returns {LngLatBounds} A new `LngLatBounds` object, if a conversion occurred, or the original `LngLatBounds` object.
     * @example
     * const arr = [[-73.9876, 40.7661], [-73.9397, 40.8002]];
     * const llb = mapboxgl.LngLatBounds.convert(arr);
     * console.log(llb);   // = LngLatBounds {_sw: LngLat {lng: -73.9876, lat: 40.7661}, _ne: LngLat {lng: -73.9397, lat: 40.8002}}
     */
    static convert(input                  )               {
        if (!input || input instanceof LngLatBounds) return input;
        return new LngLatBounds(input);
    }
}

/**
 * Common utilities
 * @module glMatrix
 */
// Configuration Constants
var EPSILON = 0.000001;
var ARRAY_TYPE = typeof Float32Array !== 'undefined' ? Float32Array : Array;
var RANDOM = Math.random;
/**
 * Sets the type of array used when creating new vectors and matrices
 *
 * @param {Float32ArrayConstructor | ArrayConstructor} type Array type, such as Float32Array or Array
 */

function setMatrixArrayType(type) {
  ARRAY_TYPE = type;
}
var degree = Math.PI / 180;
/**
 * Convert Degree To Radian
 *
 * @param {Number} a Angle in Degrees
 */

function toRadian(a) {
  return a * degree;
}
/**
 * Tests whether or not the arguments have approximately the same value, within an absolute
 * or relative tolerance of glMatrix.EPSILON (an absolute tolerance is used for values less
 * than or equal to 1.0, and a relative tolerance is used for larger values)
 *
 * @param {Number} a The first number to test.
 * @param {Number} b The second number to test.
 * @returns {Boolean} True if the numbers are approximately equal, false otherwise.
 */

function equals$a(a, b) {
  return Math.abs(a - b) <= EPSILON * Math.max(1.0, Math.abs(a), Math.abs(b));
}
if (!Math.hypot) Math.hypot = function () {
  var y = 0,
      i = arguments.length;

  while (i--) {
    y += arguments[i] * arguments[i];
  }

  return Math.sqrt(y);
};

var common = /*#__PURE__*/Object.freeze({
__proto__: null,
get ARRAY_TYPE () { return ARRAY_TYPE; },
EPSILON: EPSILON,
RANDOM: RANDOM,
equals: equals$a,
setMatrixArrayType: setMatrixArrayType,
toRadian: toRadian
});

/**
 * 2x2 Matrix
 * @module mat2
 */

/**
 * Creates a new identity mat2
 *
 * @returns {mat2} a new 2x2 matrix
 */

function create$8() {
  var out = new ARRAY_TYPE(4);

  if (ARRAY_TYPE != Float32Array) {
    out[1] = 0;
    out[2] = 0;
  }

  out[0] = 1;
  out[3] = 1;
  return out;
}
/**
 * Creates a new mat2 initialized with values from an existing matrix
 *
 * @param {ReadonlyMat2} a matrix to clone
 * @returns {mat2} a new 2x2 matrix
 */

function clone$8(a) {
  var out = new ARRAY_TYPE(4);
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[3];
  return out;
}
/**
 * Copy the values from one mat2 to another
 *
 * @param {mat2} out the receiving matrix
 * @param {ReadonlyMat2} a the source matrix
 * @returns {mat2} out
 */

function copy$8(out, a) {
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[3];
  return out;
}
/**
 * Set a mat2 to the identity matrix
 *
 * @param {mat2} out the receiving matrix
 * @returns {mat2} out
 */

function identity$6(out) {
  out[0] = 1;
  out[1] = 0;
  out[2] = 0;
  out[3] = 1;
  return out;
}
/**
 * Create a new mat2 with the given values
 *
 * @param {Number} m00 Component in column 0, row 0 position (index 0)
 * @param {Number} m01 Component in column 0, row 1 position (index 1)
 * @param {Number} m10 Component in column 1, row 0 position (index 2)
 * @param {Number} m11 Component in column 1, row 1 position (index 3)
 * @returns {mat2} out A new 2x2 matrix
 */

function fromValues$8(m00, m01, m10, m11) {
  var out = new ARRAY_TYPE(4);
  out[0] = m00;
  out[1] = m01;
  out[2] = m10;
  out[3] = m11;
  return out;
}
/**
 * Set the components of a mat2 to the given values
 *
 * @param {mat2} out the receiving matrix
 * @param {Number} m00 Component in column 0, row 0 position (index 0)
 * @param {Number} m01 Component in column 0, row 1 position (index 1)
 * @param {Number} m10 Component in column 1, row 0 position (index 2)
 * @param {Number} m11 Component in column 1, row 1 position (index 3)
 * @returns {mat2} out
 */

function set$8(out, m00, m01, m10, m11) {
  out[0] = m00;
  out[1] = m01;
  out[2] = m10;
  out[3] = m11;
  return out;
}
/**
 * Transpose the values of a mat2
 *
 * @param {mat2} out the receiving matrix
 * @param {ReadonlyMat2} a the source matrix
 * @returns {mat2} out
 */

function transpose$2(out, a) {
  // If we are transposing ourselves we can skip a few steps but have to cache
  // some values
  if (out === a) {
    var a1 = a[1];
    out[1] = a[2];
    out[2] = a1;
  } else {
    out[0] = a[0];
    out[1] = a[2];
    out[2] = a[1];
    out[3] = a[3];
  }

  return out;
}
/**
 * Inverts a mat2
 *
 * @param {mat2} out the receiving matrix
 * @param {ReadonlyMat2} a the source matrix
 * @returns {mat2} out
 */

function invert$5(out, a) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3]; // Calculate the determinant

  var det = a0 * a3 - a2 * a1;

  if (!det) {
    return null;
  }

  det = 1.0 / det;
  out[0] = a3 * det;
  out[1] = -a1 * det;
  out[2] = -a2 * det;
  out[3] = a0 * det;
  return out;
}
/**
 * Calculates the adjugate of a mat2
 *
 * @param {mat2} out the receiving matrix
 * @param {ReadonlyMat2} a the source matrix
 * @returns {mat2} out
 */

function adjoint$2(out, a) {
  // Caching this value is nessecary if out == a
  var a0 = a[0];
  out[0] = a[3];
  out[1] = -a[1];
  out[2] = -a[2];
  out[3] = a0;
  return out;
}
/**
 * Calculates the determinant of a mat2
 *
 * @param {ReadonlyMat2} a the source matrix
 * @returns {Number} determinant of a
 */

function determinant$3(a) {
  return a[0] * a[3] - a[2] * a[1];
}
/**
 * Multiplies two mat2's
 *
 * @param {mat2} out the receiving matrix
 * @param {ReadonlyMat2} a the first operand
 * @param {ReadonlyMat2} b the second operand
 * @returns {mat2} out
 */

function multiply$8(out, a, b) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3];
  var b0 = b[0],
      b1 = b[1],
      b2 = b[2],
      b3 = b[3];
  out[0] = a0 * b0 + a2 * b1;
  out[1] = a1 * b0 + a3 * b1;
  out[2] = a0 * b2 + a2 * b3;
  out[3] = a1 * b2 + a3 * b3;
  return out;
}
/**
 * Rotates a mat2 by the given angle
 *
 * @param {mat2} out the receiving matrix
 * @param {ReadonlyMat2} a the matrix to rotate
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat2} out
 */

function rotate$4(out, a, rad) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3];
  var s = Math.sin(rad);
  var c = Math.cos(rad);
  out[0] = a0 * c + a2 * s;
  out[1] = a1 * c + a3 * s;
  out[2] = a0 * -s + a2 * c;
  out[3] = a1 * -s + a3 * c;
  return out;
}
/**
 * Scales the mat2 by the dimensions in the given vec2
 *
 * @param {mat2} out the receiving matrix
 * @param {ReadonlyMat2} a the matrix to rotate
 * @param {ReadonlyVec2} v the vec2 to scale the matrix by
 * @returns {mat2} out
 **/

function scale$8(out, a, v) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3];
  var v0 = v[0],
      v1 = v[1];
  out[0] = a0 * v0;
  out[1] = a1 * v0;
  out[2] = a2 * v1;
  out[3] = a3 * v1;
  return out;
}
/**
 * Creates a matrix from a given angle
 * This is equivalent to (but much faster than):
 *
 *     mat2.identity(dest);
 *     mat2.rotate(dest, dest, rad);
 *
 * @param {mat2} out mat2 receiving operation result
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat2} out
 */

function fromRotation$4(out, rad) {
  var s = Math.sin(rad);
  var c = Math.cos(rad);
  out[0] = c;
  out[1] = s;
  out[2] = -s;
  out[3] = c;
  return out;
}
/**
 * Creates a matrix from a vector scaling
 * This is equivalent to (but much faster than):
 *
 *     mat2.identity(dest);
 *     mat2.scale(dest, dest, vec);
 *
 * @param {mat2} out mat2 receiving operation result
 * @param {ReadonlyVec2} v Scaling vector
 * @returns {mat2} out
 */

function fromScaling$3(out, v) {
  out[0] = v[0];
  out[1] = 0;
  out[2] = 0;
  out[3] = v[1];
  return out;
}
/**
 * Returns a string representation of a mat2
 *
 * @param {ReadonlyMat2} a matrix to represent as a string
 * @returns {String} string representation of the matrix
 */

function str$8(a) {
  return "mat2(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")";
}
/**
 * Returns Frobenius norm of a mat2
 *
 * @param {ReadonlyMat2} a the matrix to calculate Frobenius norm of
 * @returns {Number} Frobenius norm
 */

function frob$3(a) {
  return Math.hypot(a[0], a[1], a[2], a[3]);
}
/**
 * Returns L, D and U matrices (Lower triangular, Diagonal and Upper triangular) by factorizing the input matrix
 * @param {ReadonlyMat2} L the lower triangular matrix
 * @param {ReadonlyMat2} D the diagonal matrix
 * @param {ReadonlyMat2} U the upper triangular matrix
 * @param {ReadonlyMat2} a the input matrix to factorize
 */

function LDU(L, D, U, a) {
  L[2] = a[2] / a[0];
  U[0] = a[0];
  U[1] = a[1];
  U[3] = a[3] - L[2] * U[1];
  return [L, D, U];
}
/**
 * Adds two mat2's
 *
 * @param {mat2} out the receiving matrix
 * @param {ReadonlyMat2} a the first operand
 * @param {ReadonlyMat2} b the second operand
 * @returns {mat2} out
 */

function add$8(out, a, b) {
  out[0] = a[0] + b[0];
  out[1] = a[1] + b[1];
  out[2] = a[2] + b[2];
  out[3] = a[3] + b[3];
  return out;
}
/**
 * Subtracts matrix b from matrix a
 *
 * @param {mat2} out the receiving matrix
 * @param {ReadonlyMat2} a the first operand
 * @param {ReadonlyMat2} b the second operand
 * @returns {mat2} out
 */

function subtract$6(out, a, b) {
  out[0] = a[0] - b[0];
  out[1] = a[1] - b[1];
  out[2] = a[2] - b[2];
  out[3] = a[3] - b[3];
  return out;
}
/**
 * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===)
 *
 * @param {ReadonlyMat2} a The first matrix.
 * @param {ReadonlyMat2} b The second matrix.
 * @returns {Boolean} True if the matrices are equal, false otherwise.
 */

function exactEquals$8(a, b) {
  return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3];
}
/**
 * Returns whether or not the matrices have approximately the same elements in the same position.
 *
 * @param {ReadonlyMat2} a The first matrix.
 * @param {ReadonlyMat2} b The second matrix.
 * @returns {Boolean} True if the matrices are equal, false otherwise.
 */

function equals$9(a, b) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3];
  var b0 = b[0],
      b1 = b[1],
      b2 = b[2],
      b3 = b[3];
  return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3));
}
/**
 * Multiply each element of the matrix by a scalar.
 *
 * @param {mat2} out the receiving matrix
 * @param {ReadonlyMat2} a the matrix to scale
 * @param {Number} b amount to scale the matrix's elements by
 * @returns {mat2} out
 */

function multiplyScalar$3(out, a, b) {
  out[0] = a[0] * b;
  out[1] = a[1] * b;
  out[2] = a[2] * b;
  out[3] = a[3] * b;
  return out;
}
/**
 * Adds two mat2's after multiplying each element of the second operand by a scalar value.
 *
 * @param {mat2} out the receiving vector
 * @param {ReadonlyMat2} a the first operand
 * @param {ReadonlyMat2} b the second operand
 * @param {Number} scale the amount to scale b's elements by before adding
 * @returns {mat2} out
 */

function multiplyScalarAndAdd$3(out, a, b, scale) {
  out[0] = a[0] + b[0] * scale;
  out[1] = a[1] + b[1] * scale;
  out[2] = a[2] + b[2] * scale;
  out[3] = a[3] + b[3] * scale;
  return out;
}
/**
 * Alias for {@link mat2.multiply}
 * @function
 */

var mul$8 = multiply$8;
/**
 * Alias for {@link mat2.subtract}
 * @function
 */

var sub$6 = subtract$6;

var mat2 = /*#__PURE__*/Object.freeze({
__proto__: null,
LDU: LDU,
add: add$8,
adjoint: adjoint$2,
clone: clone$8,
copy: copy$8,
create: create$8,
determinant: determinant$3,
equals: equals$9,
exactEquals: exactEquals$8,
frob: frob$3,
fromRotation: fromRotation$4,
fromScaling: fromScaling$3,
fromValues: fromValues$8,
identity: identity$6,
invert: invert$5,
mul: mul$8,
multiply: multiply$8,
multiplyScalar: multiplyScalar$3,
multiplyScalarAndAdd: multiplyScalarAndAdd$3,
rotate: rotate$4,
scale: scale$8,
set: set$8,
str: str$8,
sub: sub$6,
subtract: subtract$6,
transpose: transpose$2
});

/**
 * 2x3 Matrix
 * @module mat2d
 * @description
 * A mat2d contains six elements defined as:
 * <pre>
 * [a, b,
 *  c, d,
 *  tx, ty]
 * </pre>
 * This is a short form for the 3x3 matrix:
 * <pre>
 * [a, b, 0,
 *  c, d, 0,
 *  tx, ty, 1]
 * </pre>
 * The last column is ignored so the array is shorter and operations are faster.
 */

/**
 * Creates a new identity mat2d
 *
 * @returns {mat2d} a new 2x3 matrix
 */

function create$7() {
  var out = new ARRAY_TYPE(6);

  if (ARRAY_TYPE != Float32Array) {
    out[1] = 0;
    out[2] = 0;
    out[4] = 0;
    out[5] = 0;
  }

  out[0] = 1;
  out[3] = 1;
  return out;
}
/**
 * Creates a new mat2d initialized with values from an existing matrix
 *
 * @param {ReadonlyMat2d} a matrix to clone
 * @returns {mat2d} a new 2x3 matrix
 */

function clone$7(a) {
  var out = new ARRAY_TYPE(6);
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[3];
  out[4] = a[4];
  out[5] = a[5];
  return out;
}
/**
 * Copy the values from one mat2d to another
 *
 * @param {mat2d} out the receiving matrix
 * @param {ReadonlyMat2d} a the source matrix
 * @returns {mat2d} out
 */

function copy$7(out, a) {
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[3];
  out[4] = a[4];
  out[5] = a[5];
  return out;
}
/**
 * Set a mat2d to the identity matrix
 *
 * @param {mat2d} out the receiving matrix
 * @returns {mat2d} out
 */

function identity$5(out) {
  out[0] = 1;
  out[1] = 0;
  out[2] = 0;
  out[3] = 1;
  out[4] = 0;
  out[5] = 0;
  return out;
}
/**
 * Create a new mat2d with the given values
 *
 * @param {Number} a Component A (index 0)
 * @param {Number} b Component B (index 1)
 * @param {Number} c Component C (index 2)
 * @param {Number} d Component D (index 3)
 * @param {Number} tx Component TX (index 4)
 * @param {Number} ty Component TY (index 5)
 * @returns {mat2d} A new mat2d
 */

function fromValues$7(a, b, c, d, tx, ty) {
  var out = new ARRAY_TYPE(6);
  out[0] = a;
  out[1] = b;
  out[2] = c;
  out[3] = d;
  out[4] = tx;
  out[5] = ty;
  return out;
}
/**
 * Set the components of a mat2d to the given values
 *
 * @param {mat2d} out the receiving matrix
 * @param {Number} a Component A (index 0)
 * @param {Number} b Component B (index 1)
 * @param {Number} c Component C (index 2)
 * @param {Number} d Component D (index 3)
 * @param {Number} tx Component TX (index 4)
 * @param {Number} ty Component TY (index 5)
 * @returns {mat2d} out
 */

function set$7(out, a, b, c, d, tx, ty) {
  out[0] = a;
  out[1] = b;
  out[2] = c;
  out[3] = d;
  out[4] = tx;
  out[5] = ty;
  return out;
}
/**
 * Inverts a mat2d
 *
 * @param {mat2d} out the receiving matrix
 * @param {ReadonlyMat2d} a the source matrix
 * @returns {mat2d} out
 */

function invert$4(out, a) {
  var aa = a[0],
      ab = a[1],
      ac = a[2],
      ad = a[3];
  var atx = a[4],
      aty = a[5];
  var det = aa * ad - ab * ac;

  if (!det) {
    return null;
  }

  det = 1.0 / det;
  out[0] = ad * det;
  out[1] = -ab * det;
  out[2] = -ac * det;
  out[3] = aa * det;
  out[4] = (ac * aty - ad * atx) * det;
  out[5] = (ab * atx - aa * aty) * det;
  return out;
}
/**
 * Calculates the determinant of a mat2d
 *
 * @param {ReadonlyMat2d} a the source matrix
 * @returns {Number} determinant of a
 */

function determinant$2(a) {
  return a[0] * a[3] - a[1] * a[2];
}
/**
 * Multiplies two mat2d's
 *
 * @param {mat2d} out the receiving matrix
 * @param {ReadonlyMat2d} a the first operand
 * @param {ReadonlyMat2d} b the second operand
 * @returns {mat2d} out
 */

function multiply$7(out, a, b) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3],
      a4 = a[4],
      a5 = a[5];
  var b0 = b[0],
      b1 = b[1],
      b2 = b[2],
      b3 = b[3],
      b4 = b[4],
      b5 = b[5];
  out[0] = a0 * b0 + a2 * b1;
  out[1] = a1 * b0 + a3 * b1;
  out[2] = a0 * b2 + a2 * b3;
  out[3] = a1 * b2 + a3 * b3;
  out[4] = a0 * b4 + a2 * b5 + a4;
  out[5] = a1 * b4 + a3 * b5 + a5;
  return out;
}
/**
 * Rotates a mat2d by the given angle
 *
 * @param {mat2d} out the receiving matrix
 * @param {ReadonlyMat2d} a the matrix to rotate
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat2d} out
 */

function rotate$3(out, a, rad) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3],
      a4 = a[4],
      a5 = a[5];
  var s = Math.sin(rad);
  var c = Math.cos(rad);
  out[0] = a0 * c + a2 * s;
  out[1] = a1 * c + a3 * s;
  out[2] = a0 * -s + a2 * c;
  out[3] = a1 * -s + a3 * c;
  out[4] = a4;
  out[5] = a5;
  return out;
}
/**
 * Scales the mat2d by the dimensions in the given vec2
 *
 * @param {mat2d} out the receiving matrix
 * @param {ReadonlyMat2d} a the matrix to translate
 * @param {ReadonlyVec2} v the vec2 to scale the matrix by
 * @returns {mat2d} out
 **/

function scale$7(out, a, v) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3],
      a4 = a[4],
      a5 = a[5];
  var v0 = v[0],
      v1 = v[1];
  out[0] = a0 * v0;
  out[1] = a1 * v0;
  out[2] = a2 * v1;
  out[3] = a3 * v1;
  out[4] = a4;
  out[5] = a5;
  return out;
}
/**
 * Translates the mat2d by the dimensions in the given vec2
 *
 * @param {mat2d} out the receiving matrix
 * @param {ReadonlyMat2d} a the matrix to translate
 * @param {ReadonlyVec2} v the vec2 to translate the matrix by
 * @returns {mat2d} out
 **/

function translate$4(out, a, v) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3],
      a4 = a[4],
      a5 = a[5];
  var v0 = v[0],
      v1 = v[1];
  out[0] = a0;
  out[1] = a1;
  out[2] = a2;
  out[3] = a3;
  out[4] = a0 * v0 + a2 * v1 + a4;
  out[5] = a1 * v0 + a3 * v1 + a5;
  return out;
}
/**
 * Creates a matrix from a given angle
 * This is equivalent to (but much faster than):
 *
 *     mat2d.identity(dest);
 *     mat2d.rotate(dest, dest, rad);
 *
 * @param {mat2d} out mat2d receiving operation result
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat2d} out
 */

function fromRotation$3(out, rad) {
  var s = Math.sin(rad),
      c = Math.cos(rad);
  out[0] = c;
  out[1] = s;
  out[2] = -s;
  out[3] = c;
  out[4] = 0;
  out[5] = 0;
  return out;
}
/**
 * Creates a matrix from a vector scaling
 * This is equivalent to (but much faster than):
 *
 *     mat2d.identity(dest);
 *     mat2d.scale(dest, dest, vec);
 *
 * @param {mat2d} out mat2d receiving operation result
 * @param {ReadonlyVec2} v Scaling vector
 * @returns {mat2d} out
 */

function fromScaling$2(out, v) {
  out[0] = v[0];
  out[1] = 0;
  out[2] = 0;
  out[3] = v[1];
  out[4] = 0;
  out[5] = 0;
  return out;
}
/**
 * Creates a matrix from a vector translation
 * This is equivalent to (but much faster than):
 *
 *     mat2d.identity(dest);
 *     mat2d.translate(dest, dest, vec);
 *
 * @param {mat2d} out mat2d receiving operation result
 * @param {ReadonlyVec2} v Translation vector
 * @returns {mat2d} out
 */

function fromTranslation$3(out, v) {
  out[0] = 1;
  out[1] = 0;
  out[2] = 0;
  out[3] = 1;
  out[4] = v[0];
  out[5] = v[1];
  return out;
}
/**
 * Returns a string representation of a mat2d
 *
 * @param {ReadonlyMat2d} a matrix to represent as a string
 * @returns {String} string representation of the matrix
 */

function str$7(a) {
  return "mat2d(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ")";
}
/**
 * Returns Frobenius norm of a mat2d
 *
 * @param {ReadonlyMat2d} a the matrix to calculate Frobenius norm of
 * @returns {Number} Frobenius norm
 */

function frob$2(a) {
  return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], 1);
}
/**
 * Adds two mat2d's
 *
 * @param {mat2d} out the receiving matrix
 * @param {ReadonlyMat2d} a the first operand
 * @param {ReadonlyMat2d} b the second operand
 * @returns {mat2d} out
 */

function add$7(out, a, b) {
  out[0] = a[0] + b[0];
  out[1] = a[1] + b[1];
  out[2] = a[2] + b[2];
  out[3] = a[3] + b[3];
  out[4] = a[4] + b[4];
  out[5] = a[5] + b[5];
  return out;
}
/**
 * Subtracts matrix b from matrix a
 *
 * @param {mat2d} out the receiving matrix
 * @param {ReadonlyMat2d} a the first operand
 * @param {ReadonlyMat2d} b the second operand
 * @returns {mat2d} out
 */

function subtract$5(out, a, b) {
  out[0] = a[0] - b[0];
  out[1] = a[1] - b[1];
  out[2] = a[2] - b[2];
  out[3] = a[3] - b[3];
  out[4] = a[4] - b[4];
  out[5] = a[5] - b[5];
  return out;
}
/**
 * Multiply each element of the matrix by a scalar.
 *
 * @param {mat2d} out the receiving matrix
 * @param {ReadonlyMat2d} a the matrix to scale
 * @param {Number} b amount to scale the matrix's elements by
 * @returns {mat2d} out
 */

function multiplyScalar$2(out, a, b) {
  out[0] = a[0] * b;
  out[1] = a[1] * b;
  out[2] = a[2] * b;
  out[3] = a[3] * b;
  out[4] = a[4] * b;
  out[5] = a[5] * b;
  return out;
}
/**
 * Adds two mat2d's after multiplying each element of the second operand by a scalar value.
 *
 * @param {mat2d} out the receiving vector
 * @param {ReadonlyMat2d} a the first operand
 * @param {ReadonlyMat2d} b the second operand
 * @param {Number} scale the amount to scale b's elements by before adding
 * @returns {mat2d} out
 */

function multiplyScalarAndAdd$2(out, a, b, scale) {
  out[0] = a[0] + b[0] * scale;
  out[1] = a[1] + b[1] * scale;
  out[2] = a[2] + b[2] * scale;
  out[3] = a[3] + b[3] * scale;
  out[4] = a[4] + b[4] * scale;
  out[5] = a[5] + b[5] * scale;
  return out;
}
/**
 * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===)
 *
 * @param {ReadonlyMat2d} a The first matrix.
 * @param {ReadonlyMat2d} b The second matrix.
 * @returns {Boolean} True if the matrices are equal, false otherwise.
 */

function exactEquals$7(a, b) {
  return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5];
}
/**
 * Returns whether or not the matrices have approximately the same elements in the same position.
 *
 * @param {ReadonlyMat2d} a The first matrix.
 * @param {ReadonlyMat2d} b The second matrix.
 * @returns {Boolean} True if the matrices are equal, false otherwise.
 */

function equals$8(a, b) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3],
      a4 = a[4],
      a5 = a[5];
  var b0 = b[0],
      b1 = b[1],
      b2 = b[2],
      b3 = b[3],
      b4 = b[4],
      b5 = b[5];
  return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5));
}
/**
 * Alias for {@link mat2d.multiply}
 * @function
 */

var mul$7 = multiply$7;
/**
 * Alias for {@link mat2d.subtract}
 * @function
 */

var sub$5 = subtract$5;

var mat2d = /*#__PURE__*/Object.freeze({
__proto__: null,
add: add$7,
clone: clone$7,
copy: copy$7,
create: create$7,
determinant: determinant$2,
equals: equals$8,
exactEquals: exactEquals$7,
frob: frob$2,
fromRotation: fromRotation$3,
fromScaling: fromScaling$2,
fromTranslation: fromTranslation$3,
fromValues: fromValues$7,
identity: identity$5,
invert: invert$4,
mul: mul$7,
multiply: multiply$7,
multiplyScalar: multiplyScalar$2,
multiplyScalarAndAdd: multiplyScalarAndAdd$2,
rotate: rotate$3,
scale: scale$7,
set: set$7,
str: str$7,
sub: sub$5,
subtract: subtract$5,
translate: translate$4
});

/**
 * 3x3 Matrix
 * @module mat3
 */

/**
 * Creates a new identity mat3
 *
 * @returns {mat3} a new 3x3 matrix
 */

function create$6() {
  var out = new ARRAY_TYPE(9);

  if (ARRAY_TYPE != Float32Array) {
    out[1] = 0;
    out[2] = 0;
    out[3] = 0;
    out[5] = 0;
    out[6] = 0;
    out[7] = 0;
  }

  out[0] = 1;
  out[4] = 1;
  out[8] = 1;
  return out;
}
/**
 * Copies the upper-left 3x3 values into the given mat3.
 *
 * @param {mat3} out the receiving 3x3 matrix
 * @param {ReadonlyMat4} a   the source 4x4 matrix
 * @returns {mat3} out
 */

function fromMat4$1(out, a) {
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[4];
  out[4] = a[5];
  out[5] = a[6];
  out[6] = a[8];
  out[7] = a[9];
  out[8] = a[10];
  return out;
}
/**
 * Creates a new mat3 initialized with values from an existing matrix
 *
 * @param {ReadonlyMat3} a matrix to clone
 * @returns {mat3} a new 3x3 matrix
 */

function clone$6(a) {
  var out = new ARRAY_TYPE(9);
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[3];
  out[4] = a[4];
  out[5] = a[5];
  out[6] = a[6];
  out[7] = a[7];
  out[8] = a[8];
  return out;
}
/**
 * Copy the values from one mat3 to another
 *
 * @param {mat3} out the receiving matrix
 * @param {ReadonlyMat3} a the source matrix
 * @returns {mat3} out
 */

function copy$6(out, a) {
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[3];
  out[4] = a[4];
  out[5] = a[5];
  out[6] = a[6];
  out[7] = a[7];
  out[8] = a[8];
  return out;
}
/**
 * Create a new mat3 with the given values
 *
 * @param {Number} m00 Component in column 0, row 0 position (index 0)
 * @param {Number} m01 Component in column 0, row 1 position (index 1)
 * @param {Number} m02 Component in column 0, row 2 position (index 2)
 * @param {Number} m10 Component in column 1, row 0 position (index 3)
 * @param {Number} m11 Component in column 1, row 1 position (index 4)
 * @param {Number} m12 Component in column 1, row 2 position (index 5)
 * @param {Number} m20 Component in column 2, row 0 position (index 6)
 * @param {Number} m21 Component in column 2, row 1 position (index 7)
 * @param {Number} m22 Component in column 2, row 2 position (index 8)
 * @returns {mat3} A new mat3
 */

function fromValues$6(m00, m01, m02, m10, m11, m12, m20, m21, m22) {
  var out = new ARRAY_TYPE(9);
  out[0] = m00;
  out[1] = m01;
  out[2] = m02;
  out[3] = m10;
  out[4] = m11;
  out[5] = m12;
  out[6] = m20;
  out[7] = m21;
  out[8] = m22;
  return out;
}
/**
 * Set the components of a mat3 to the given values
 *
 * @param {mat3} out the receiving matrix
 * @param {Number} m00 Component in column 0, row 0 position (index 0)
 * @param {Number} m01 Component in column 0, row 1 position (index 1)
 * @param {Number} m02 Component in column 0, row 2 position (index 2)
 * @param {Number} m10 Component in column 1, row 0 position (index 3)
 * @param {Number} m11 Component in column 1, row 1 position (index 4)
 * @param {Number} m12 Component in column 1, row 2 position (index 5)
 * @param {Number} m20 Component in column 2, row 0 position (index 6)
 * @param {Number} m21 Component in column 2, row 1 position (index 7)
 * @param {Number} m22 Component in column 2, row 2 position (index 8)
 * @returns {mat3} out
 */

function set$6(out, m00, m01, m02, m10, m11, m12, m20, m21, m22) {
  out[0] = m00;
  out[1] = m01;
  out[2] = m02;
  out[3] = m10;
  out[4] = m11;
  out[5] = m12;
  out[6] = m20;
  out[7] = m21;
  out[8] = m22;
  return out;
}
/**
 * Set a mat3 to the identity matrix
 *
 * @param {mat3} out the receiving matrix
 * @returns {mat3} out
 */

function identity$4(out) {
  out[0] = 1;
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = 1;
  out[5] = 0;
  out[6] = 0;
  out[7] = 0;
  out[8] = 1;
  return out;
}
/**
 * Transpose the values of a mat3
 *
 * @param {mat3} out the receiving matrix
 * @param {ReadonlyMat3} a the source matrix
 * @returns {mat3} out
 */

function transpose$1(out, a) {
  // If we are transposing ourselves we can skip a few steps but have to cache some values
  if (out === a) {
    var a01 = a[1],
        a02 = a[2],
        a12 = a[5];
    out[1] = a[3];
    out[2] = a[6];
    out[3] = a01;
    out[5] = a[7];
    out[6] = a02;
    out[7] = a12;
  } else {
    out[0] = a[0];
    out[1] = a[3];
    out[2] = a[6];
    out[3] = a[1];
    out[4] = a[4];
    out[5] = a[7];
    out[6] = a[2];
    out[7] = a[5];
    out[8] = a[8];
  }

  return out;
}
/**
 * Inverts a mat3
 *
 * @param {mat3} out the receiving matrix
 * @param {ReadonlyMat3} a the source matrix
 * @returns {mat3} out
 */

function invert$3(out, a) {
  var a00 = a[0],
      a01 = a[1],
      a02 = a[2];
  var a10 = a[3],
      a11 = a[4],
      a12 = a[5];
  var a20 = a[6],
      a21 = a[7],
      a22 = a[8];
  var b01 = a22 * a11 - a12 * a21;
  var b11 = -a22 * a10 + a12 * a20;
  var b21 = a21 * a10 - a11 * a20; // Calculate the determinant

  var det = a00 * b01 + a01 * b11 + a02 * b21;

  if (!det) {
    return null;
  }

  det = 1.0 / det;
  out[0] = b01 * det;
  out[1] = (-a22 * a01 + a02 * a21) * det;
  out[2] = (a12 * a01 - a02 * a11) * det;
  out[3] = b11 * det;
  out[4] = (a22 * a00 - a02 * a20) * det;
  out[5] = (-a12 * a00 + a02 * a10) * det;
  out[6] = b21 * det;
  out[7] = (-a21 * a00 + a01 * a20) * det;
  out[8] = (a11 * a00 - a01 * a10) * det;
  return out;
}
/**
 * Calculates the adjugate of a mat3
 *
 * @param {mat3} out the receiving matrix
 * @param {ReadonlyMat3} a the source matrix
 * @returns {mat3} out
 */

function adjoint$1(out, a) {
  var a00 = a[0],
      a01 = a[1],
      a02 = a[2];
  var a10 = a[3],
      a11 = a[4],
      a12 = a[5];
  var a20 = a[6],
      a21 = a[7],
      a22 = a[8];
  out[0] = a11 * a22 - a12 * a21;
  out[1] = a02 * a21 - a01 * a22;
  out[2] = a01 * a12 - a02 * a11;
  out[3] = a12 * a20 - a10 * a22;
  out[4] = a00 * a22 - a02 * a20;
  out[5] = a02 * a10 - a00 * a12;
  out[6] = a10 * a21 - a11 * a20;
  out[7] = a01 * a20 - a00 * a21;
  out[8] = a00 * a11 - a01 * a10;
  return out;
}
/**
 * Calculates the determinant of a mat3
 *
 * @param {ReadonlyMat3} a the source matrix
 * @returns {Number} determinant of a
 */

function determinant$1(a) {
  var a00 = a[0],
      a01 = a[1],
      a02 = a[2];
  var a10 = a[3],
      a11 = a[4],
      a12 = a[5];
  var a20 = a[6],
      a21 = a[7],
      a22 = a[8];
  return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20);
}
/**
 * Multiplies two mat3's
 *
 * @param {mat3} out the receiving matrix
 * @param {ReadonlyMat3} a the first operand
 * @param {ReadonlyMat3} b the second operand
 * @returns {mat3} out
 */

function multiply$6(out, a, b) {
  var a00 = a[0],
      a01 = a[1],
      a02 = a[2];
  var a10 = a[3],
      a11 = a[4],
      a12 = a[5];
  var a20 = a[6],
      a21 = a[7],
      a22 = a[8];
  var b00 = b[0],
      b01 = b[1],
      b02 = b[2];
  var b10 = b[3],
      b11 = b[4],
      b12 = b[5];
  var b20 = b[6],
      b21 = b[7],
      b22 = b[8];
  out[0] = b00 * a00 + b01 * a10 + b02 * a20;
  out[1] = b00 * a01 + b01 * a11 + b02 * a21;
  out[2] = b00 * a02 + b01 * a12 + b02 * a22;
  out[3] = b10 * a00 + b11 * a10 + b12 * a20;
  out[4] = b10 * a01 + b11 * a11 + b12 * a21;
  out[5] = b10 * a02 + b11 * a12 + b12 * a22;
  out[6] = b20 * a00 + b21 * a10 + b22 * a20;
  out[7] = b20 * a01 + b21 * a11 + b22 * a21;
  out[8] = b20 * a02 + b21 * a12 + b22 * a22;
  return out;
}
/**
 * Translate a mat3 by the given vector
 *
 * @param {mat3} out the receiving matrix
 * @param {ReadonlyMat3} a the matrix to translate
 * @param {ReadonlyVec2} v vector to translate by
 * @returns {mat3} out
 */

function translate$3(out, a, v) {
  var a00 = a[0],
      a01 = a[1],
      a02 = a[2],
      a10 = a[3],
      a11 = a[4],
      a12 = a[5],
      a20 = a[6],
      a21 = a[7],
      a22 = a[8],
      x = v[0],
      y = v[1];
  out[0] = a00;
  out[1] = a01;
  out[2] = a02;
  out[3] = a10;
  out[4] = a11;
  out[5] = a12;
  out[6] = x * a00 + y * a10 + a20;
  out[7] = x * a01 + y * a11 + a21;
  out[8] = x * a02 + y * a12 + a22;
  return out;
}
/**
 * Rotates a mat3 by the given angle
 *
 * @param {mat3} out the receiving matrix
 * @param {ReadonlyMat3} a the matrix to rotate
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat3} out
 */

function rotate$2(out, a, rad) {
  var a00 = a[0],
      a01 = a[1],
      a02 = a[2],
      a10 = a[3],
      a11 = a[4],
      a12 = a[5],
      a20 = a[6],
      a21 = a[7],
      a22 = a[8],
      s = Math.sin(rad),
      c = Math.cos(rad);
  out[0] = c * a00 + s * a10;
  out[1] = c * a01 + s * a11;
  out[2] = c * a02 + s * a12;
  out[3] = c * a10 - s * a00;
  out[4] = c * a11 - s * a01;
  out[5] = c * a12 - s * a02;
  out[6] = a20;
  out[7] = a21;
  out[8] = a22;
  return out;
}
/**
 * Scales the mat3 by the dimensions in the given vec2
 *
 * @param {mat3} out the receiving matrix
 * @param {ReadonlyMat3} a the matrix to rotate
 * @param {ReadonlyVec2} v the vec2 to scale the matrix by
 * @returns {mat3} out
 **/

function scale$6(out, a, v) {
  var x = v[0],
      y = v[1];
  out[0] = x * a[0];
  out[1] = x * a[1];
  out[2] = x * a[2];
  out[3] = y * a[3];
  out[4] = y * a[4];
  out[5] = y * a[5];
  out[6] = a[6];
  out[7] = a[7];
  out[8] = a[8];
  return out;
}
/**
 * Creates a matrix from a vector translation
 * This is equivalent to (but much faster than):
 *
 *     mat3.identity(dest);
 *     mat3.translate(dest, dest, vec);
 *
 * @param {mat3} out mat3 receiving operation result
 * @param {ReadonlyVec2} v Translation vector
 * @returns {mat3} out
 */

function fromTranslation$2(out, v) {
  out[0] = 1;
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = 1;
  out[5] = 0;
  out[6] = v[0];
  out[7] = v[1];
  out[8] = 1;
  return out;
}
/**
 * Creates a matrix from a given angle
 * This is equivalent to (but much faster than):
 *
 *     mat3.identity(dest);
 *     mat3.rotate(dest, dest, rad);
 *
 * @param {mat3} out mat3 receiving operation result
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat3} out
 */

function fromRotation$2(out, rad) {
  var s = Math.sin(rad),
      c = Math.cos(rad);
  out[0] = c;
  out[1] = s;
  out[2] = 0;
  out[3] = -s;
  out[4] = c;
  out[5] = 0;
  out[6] = 0;
  out[7] = 0;
  out[8] = 1;
  return out;
}
/**
 * Creates a matrix from a vector scaling
 * This is equivalent to (but much faster than):
 *
 *     mat3.identity(dest);
 *     mat3.scale(dest, dest, vec);
 *
 * @param {mat3} out mat3 receiving operation result
 * @param {ReadonlyVec2} v Scaling vector
 * @returns {mat3} out
 */

function fromScaling$1(out, v) {
  out[0] = v[0];
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = v[1];
  out[5] = 0;
  out[6] = 0;
  out[7] = 0;
  out[8] = 1;
  return out;
}
/**
 * Copies the values from a mat2d into a mat3
 *
 * @param {mat3} out the receiving matrix
 * @param {ReadonlyMat2d} a the matrix to copy
 * @returns {mat3} out
 **/

function fromMat2d(out, a) {
  out[0] = a[0];
  out[1] = a[1];
  out[2] = 0;
  out[3] = a[2];
  out[4] = a[3];
  out[5] = 0;
  out[6] = a[4];
  out[7] = a[5];
  out[8] = 1;
  return out;
}
/**
 * Calculates a 3x3 matrix from the given quaternion
 *
 * @param {mat3} out mat3 receiving operation result
 * @param {ReadonlyQuat} q Quaternion to create matrix from
 *
 * @returns {mat3} out
 */

function fromQuat$1(out, q) {
  var x = q[0],
      y = q[1],
      z = q[2],
      w = q[3];
  var x2 = x + x;
  var y2 = y + y;
  var z2 = z + z;
  var xx = x * x2;
  var yx = y * x2;
  var yy = y * y2;
  var zx = z * x2;
  var zy = z * y2;
  var zz = z * z2;
  var wx = w * x2;
  var wy = w * y2;
  var wz = w * z2;
  out[0] = 1 - yy - zz;
  out[3] = yx - wz;
  out[6] = zx + wy;
  out[1] = yx + wz;
  out[4] = 1 - xx - zz;
  out[7] = zy - wx;
  out[2] = zx - wy;
  out[5] = zy + wx;
  out[8] = 1 - xx - yy;
  return out;
}
/**
 * Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix
 *
 * @param {mat3} out mat3 receiving operation result
 * @param {ReadonlyMat4} a Mat4 to derive the normal matrix from
 *
 * @returns {mat3} out
 */

function normalFromMat4(out, a) {
  var a00 = a[0],
      a01 = a[1],
      a02 = a[2],
      a03 = a[3];
  var a10 = a[4],
      a11 = a[5],
      a12 = a[6],
      a13 = a[7];
  var a20 = a[8],
      a21 = a[9],
      a22 = a[10],
      a23 = a[11];
  var a30 = a[12],
      a31 = a[13],
      a32 = a[14],
      a33 = a[15];
  var b00 = a00 * a11 - a01 * a10;
  var b01 = a00 * a12 - a02 * a10;
  var b02 = a00 * a13 - a03 * a10;
  var b03 = a01 * a12 - a02 * a11;
  var b04 = a01 * a13 - a03 * a11;
  var b05 = a02 * a13 - a03 * a12;
  var b06 = a20 * a31 - a21 * a30;
  var b07 = a20 * a32 - a22 * a30;
  var b08 = a20 * a33 - a23 * a30;
  var b09 = a21 * a32 - a22 * a31;
  var b10 = a21 * a33 - a23 * a31;
  var b11 = a22 * a33 - a23 * a32; // Calculate the determinant

  var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;

  if (!det) {
    return null;
  }

  det = 1.0 / det;
  out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
  out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
  out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
  out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
  out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
  out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
  out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
  out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
  out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
  return out;
}
/**
 * Generates a 2D projection matrix with the given bounds
 *
 * @param {mat3} out mat3 frustum matrix will be written into
 * @param {number} width Width of your gl context
 * @param {number} height Height of gl context
 * @returns {mat3} out
 */

function projection(out, width, height) {
  out[0] = 2 / width;
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = -2 / height;
  out[5] = 0;
  out[6] = -1;
  out[7] = 1;
  out[8] = 1;
  return out;
}
/**
 * Returns a string representation of a mat3
 *
 * @param {ReadonlyMat3} a matrix to represent as a string
 * @returns {String} string representation of the matrix
 */

function str$6(a) {
  return "mat3(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ", " + a[8] + ")";
}
/**
 * Returns Frobenius norm of a mat3
 *
 * @param {ReadonlyMat3} a the matrix to calculate Frobenius norm of
 * @returns {Number} Frobenius norm
 */

function frob$1(a) {
  return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]);
}
/**
 * Adds two mat3's
 *
 * @param {mat3} out the receiving matrix
 * @param {ReadonlyMat3} a the first operand
 * @param {ReadonlyMat3} b the second operand
 * @returns {mat3} out
 */

function add$6(out, a, b) {
  out[0] = a[0] + b[0];
  out[1] = a[1] + b[1];
  out[2] = a[2] + b[2];
  out[3] = a[3] + b[3];
  out[4] = a[4] + b[4];
  out[5] = a[5] + b[5];
  out[6] = a[6] + b[6];
  out[7] = a[7] + b[7];
  out[8] = a[8] + b[8];
  return out;
}
/**
 * Subtracts matrix b from matrix a
 *
 * @param {mat3} out the receiving matrix
 * @param {ReadonlyMat3} a the first operand
 * @param {ReadonlyMat3} b the second operand
 * @returns {mat3} out
 */

function subtract$4(out, a, b) {
  out[0] = a[0] - b[0];
  out[1] = a[1] - b[1];
  out[2] = a[2] - b[2];
  out[3] = a[3] - b[3];
  out[4] = a[4] - b[4];
  out[5] = a[5] - b[5];
  out[6] = a[6] - b[6];
  out[7] = a[7] - b[7];
  out[8] = a[8] - b[8];
  return out;
}
/**
 * Multiply each element of the matrix by a scalar.
 *
 * @param {mat3} out the receiving matrix
 * @param {ReadonlyMat3} a the matrix to scale
 * @param {Number} b amount to scale the matrix's elements by
 * @returns {mat3} out
 */

function multiplyScalar$1(out, a, b) {
  out[0] = a[0] * b;
  out[1] = a[1] * b;
  out[2] = a[2] * b;
  out[3] = a[3] * b;
  out[4] = a[4] * b;
  out[5] = a[5] * b;
  out[6] = a[6] * b;
  out[7] = a[7] * b;
  out[8] = a[8] * b;
  return out;
}
/**
 * Adds two mat3's after multiplying each element of the second operand by a scalar value.
 *
 * @param {mat3} out the receiving vector
 * @param {ReadonlyMat3} a the first operand
 * @param {ReadonlyMat3} b the second operand
 * @param {Number} scale the amount to scale b's elements by before adding
 * @returns {mat3} out
 */

function multiplyScalarAndAdd$1(out, a, b, scale) {
  out[0] = a[0] + b[0] * scale;
  out[1] = a[1] + b[1] * scale;
  out[2] = a[2] + b[2] * scale;
  out[3] = a[3] + b[3] * scale;
  out[4] = a[4] + b[4] * scale;
  out[5] = a[5] + b[5] * scale;
  out[6] = a[6] + b[6] * scale;
  out[7] = a[7] + b[7] * scale;
  out[8] = a[8] + b[8] * scale;
  return out;
}
/**
 * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===)
 *
 * @param {ReadonlyMat3} a The first matrix.
 * @param {ReadonlyMat3} b The second matrix.
 * @returns {Boolean} True if the matrices are equal, false otherwise.
 */

function exactEquals$6(a, b) {
  return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8];
}
/**
 * Returns whether or not the matrices have approximately the same elements in the same position.
 *
 * @param {ReadonlyMat3} a The first matrix.
 * @param {ReadonlyMat3} b The second matrix.
 * @returns {Boolean} True if the matrices are equal, false otherwise.
 */

function equals$7(a, b) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3],
      a4 = a[4],
      a5 = a[5],
      a6 = a[6],
      a7 = a[7],
      a8 = a[8];
  var b0 = b[0],
      b1 = b[1],
      b2 = b[2],
      b3 = b[3],
      b4 = b[4],
      b5 = b[5],
      b6 = b[6],
      b7 = b[7],
      b8 = b[8];
  return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= EPSILON * Math.max(1.0, Math.abs(a8), Math.abs(b8));
}
/**
 * Alias for {@link mat3.multiply}
 * @function
 */

var mul$6 = multiply$6;
/**
 * Alias for {@link mat3.subtract}
 * @function
 */

var sub$4 = subtract$4;

var mat3 = /*#__PURE__*/Object.freeze({
__proto__: null,
add: add$6,
adjoint: adjoint$1,
clone: clone$6,
copy: copy$6,
create: create$6,
determinant: determinant$1,
equals: equals$7,
exactEquals: exactEquals$6,
frob: frob$1,
fromMat2d: fromMat2d,
fromMat4: fromMat4$1,
fromQuat: fromQuat$1,
fromRotation: fromRotation$2,
fromScaling: fromScaling$1,
fromTranslation: fromTranslation$2,
fromValues: fromValues$6,
identity: identity$4,
invert: invert$3,
mul: mul$6,
multiply: multiply$6,
multiplyScalar: multiplyScalar$1,
multiplyScalarAndAdd: multiplyScalarAndAdd$1,
normalFromMat4: normalFromMat4,
projection: projection,
rotate: rotate$2,
scale: scale$6,
set: set$6,
str: str$6,
sub: sub$4,
subtract: subtract$4,
translate: translate$3,
transpose: transpose$1
});

/**
 * 4x4 Matrix<br>Format: column-major, when typed out it looks like row-major<br>The matrices are being post multiplied.
 * @module mat4
 */

/**
 * Creates a new identity mat4
 *
 * @returns {mat4} a new 4x4 matrix
 */

function create$5() {
  var out = new ARRAY_TYPE(16);

  if (ARRAY_TYPE != Float32Array) {
    out[1] = 0;
    out[2] = 0;
    out[3] = 0;
    out[4] = 0;
    out[6] = 0;
    out[7] = 0;
    out[8] = 0;
    out[9] = 0;
    out[11] = 0;
    out[12] = 0;
    out[13] = 0;
    out[14] = 0;
  }

  out[0] = 1;
  out[5] = 1;
  out[10] = 1;
  out[15] = 1;
  return out;
}
/**
 * Creates a new mat4 initialized with values from an existing matrix
 *
 * @param {ReadonlyMat4} a matrix to clone
 * @returns {mat4} a new 4x4 matrix
 */

function clone$5(a) {
  var out = new ARRAY_TYPE(16);
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[3];
  out[4] = a[4];
  out[5] = a[5];
  out[6] = a[6];
  out[7] = a[7];
  out[8] = a[8];
  out[9] = a[9];
  out[10] = a[10];
  out[11] = a[11];
  out[12] = a[12];
  out[13] = a[13];
  out[14] = a[14];
  out[15] = a[15];
  return out;
}
/**
 * Copy the values from one mat4 to another
 *
 * @param {mat4} out the receiving matrix
 * @param {ReadonlyMat4} a the source matrix
 * @returns {mat4} out
 */

function copy$5(out, a) {
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[3];
  out[4] = a[4];
  out[5] = a[5];
  out[6] = a[6];
  out[7] = a[7];
  out[8] = a[8];
  out[9] = a[9];
  out[10] = a[10];
  out[11] = a[11];
  out[12] = a[12];
  out[13] = a[13];
  out[14] = a[14];
  out[15] = a[15];
  return out;
}
/**
 * Create a new mat4 with the given values
 *
 * @param {Number} m00 Component in column 0, row 0 position (index 0)
 * @param {Number} m01 Component in column 0, row 1 position (index 1)
 * @param {Number} m02 Component in column 0, row 2 position (index 2)
 * @param {Number} m03 Component in column 0, row 3 position (index 3)
 * @param {Number} m10 Component in column 1, row 0 position (index 4)
 * @param {Number} m11 Component in column 1, row 1 position (index 5)
 * @param {Number} m12 Component in column 1, row 2 position (index 6)
 * @param {Number} m13 Component in column 1, row 3 position (index 7)
 * @param {Number} m20 Component in column 2, row 0 position (index 8)
 * @param {Number} m21 Component in column 2, row 1 position (index 9)
 * @param {Number} m22 Component in column 2, row 2 position (index 10)
 * @param {Number} m23 Component in column 2, row 3 position (index 11)
 * @param {Number} m30 Component in column 3, row 0 position (index 12)
 * @param {Number} m31 Component in column 3, row 1 position (index 13)
 * @param {Number} m32 Component in column 3, row 2 position (index 14)
 * @param {Number} m33 Component in column 3, row 3 position (index 15)
 * @returns {mat4} A new mat4
 */

function fromValues$5(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {
  var out = new ARRAY_TYPE(16);
  out[0] = m00;
  out[1] = m01;
  out[2] = m02;
  out[3] = m03;
  out[4] = m10;
  out[5] = m11;
  out[6] = m12;
  out[7] = m13;
  out[8] = m20;
  out[9] = m21;
  out[10] = m22;
  out[11] = m23;
  out[12] = m30;
  out[13] = m31;
  out[14] = m32;
  out[15] = m33;
  return out;
}
/**
 * Set the components of a mat4 to the given values
 *
 * @param {mat4} out the receiving matrix
 * @param {Number} m00 Component in column 0, row 0 position (index 0)
 * @param {Number} m01 Component in column 0, row 1 position (index 1)
 * @param {Number} m02 Component in column 0, row 2 position (index 2)
 * @param {Number} m03 Component in column 0, row 3 position (index 3)
 * @param {Number} m10 Component in column 1, row 0 position (index 4)
 * @param {Number} m11 Component in column 1, row 1 position (index 5)
 * @param {Number} m12 Component in column 1, row 2 position (index 6)
 * @param {Number} m13 Component in column 1, row 3 position (index 7)
 * @param {Number} m20 Component in column 2, row 0 position (index 8)
 * @param {Number} m21 Component in column 2, row 1 position (index 9)
 * @param {Number} m22 Component in column 2, row 2 position (index 10)
 * @param {Number} m23 Component in column 2, row 3 position (index 11)
 * @param {Number} m30 Component in column 3, row 0 position (index 12)
 * @param {Number} m31 Component in column 3, row 1 position (index 13)
 * @param {Number} m32 Component in column 3, row 2 position (index 14)
 * @param {Number} m33 Component in column 3, row 3 position (index 15)
 * @returns {mat4} out
 */

function set$5(out, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {
  out[0] = m00;
  out[1] = m01;
  out[2] = m02;
  out[3] = m03;
  out[4] = m10;
  out[5] = m11;
  out[6] = m12;
  out[7] = m13;
  out[8] = m20;
  out[9] = m21;
  out[10] = m22;
  out[11] = m23;
  out[12] = m30;
  out[13] = m31;
  out[14] = m32;
  out[15] = m33;
  return out;
}
/**
 * Set a mat4 to the identity matrix
 *
 * @param {mat4} out the receiving matrix
 * @returns {mat4} out
 */

function identity$3(out) {
  out[0] = 1;
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = 0;
  out[5] = 1;
  out[6] = 0;
  out[7] = 0;
  out[8] = 0;
  out[9] = 0;
  out[10] = 1;
  out[11] = 0;
  out[12] = 0;
  out[13] = 0;
  out[14] = 0;
  out[15] = 1;
  return out;
}
/**
 * Transpose the values of a mat4
 *
 * @param {mat4} out the receiving matrix
 * @param {ReadonlyMat4} a the source matrix
 * @returns {mat4} out
 */

function transpose(out, a) {
  // If we are transposing ourselves we can skip a few steps but have to cache some values
  if (out === a) {
    var a01 = a[1],
        a02 = a[2],
        a03 = a[3];
    var a12 = a[6],
        a13 = a[7];
    var a23 = a[11];
    out[1] = a[4];
    out[2] = a[8];
    out[3] = a[12];
    out[4] = a01;
    out[6] = a[9];
    out[7] = a[13];
    out[8] = a02;
    out[9] = a12;
    out[11] = a[14];
    out[12] = a03;
    out[13] = a13;
    out[14] = a23;
  } else {
    out[0] = a[0];
    out[1] = a[4];
    out[2] = a[8];
    out[3] = a[12];
    out[4] = a[1];
    out[5] = a[5];
    out[6] = a[9];
    out[7] = a[13];
    out[8] = a[2];
    out[9] = a[6];
    out[10] = a[10];
    out[11] = a[14];
    out[12] = a[3];
    out[13] = a[7];
    out[14] = a[11];
    out[15] = a[15];
  }

  return out;
}
/**
 * Inverts a mat4
 *
 * @param {mat4} out the receiving matrix
 * @param {ReadonlyMat4} a the source matrix
 * @returns {mat4} out
 */

function invert$2(out, a) {
  var a00 = a[0],
      a01 = a[1],
      a02 = a[2],
      a03 = a[3];
  var a10 = a[4],
      a11 = a[5],
      a12 = a[6],
      a13 = a[7];
  var a20 = a[8],
      a21 = a[9],
      a22 = a[10],
      a23 = a[11];
  var a30 = a[12],
      a31 = a[13],
      a32 = a[14],
      a33 = a[15];
  var b00 = a00 * a11 - a01 * a10;
  var b01 = a00 * a12 - a02 * a10;
  var b02 = a00 * a13 - a03 * a10;
  var b03 = a01 * a12 - a02 * a11;
  var b04 = a01 * a13 - a03 * a11;
  var b05 = a02 * a13 - a03 * a12;
  var b06 = a20 * a31 - a21 * a30;
  var b07 = a20 * a32 - a22 * a30;
  var b08 = a20 * a33 - a23 * a30;
  var b09 = a21 * a32 - a22 * a31;
  var b10 = a21 * a33 - a23 * a31;
  var b11 = a22 * a33 - a23 * a32; // Calculate the determinant

  var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;

  if (!det) {
    return null;
  }

  det = 1.0 / det;
  out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
  out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
  out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
  out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
  out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
  out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
  out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
  out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
  out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
  out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
  out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
  out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
  out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
  out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
  out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
  out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
  return out;
}
/**
 * Calculates the adjugate of a mat4
 *
 * @param {mat4} out the receiving matrix
 * @param {ReadonlyMat4} a the source matrix
 * @returns {mat4} out
 */

function adjoint(out, a) {
  var a00 = a[0],
      a01 = a[1],
      a02 = a[2],
      a03 = a[3];
  var a10 = a[4],
      a11 = a[5],
      a12 = a[6],
      a13 = a[7];
  var a20 = a[8],
      a21 = a[9],
      a22 = a[10],
      a23 = a[11];
  var a30 = a[12],
      a31 = a[13],
      a32 = a[14],
      a33 = a[15];
  out[0] = a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22);
  out[1] = -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22));
  out[2] = a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12);
  out[3] = -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12));
  out[4] = -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22));
  out[5] = a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22);
  out[6] = -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12));
  out[7] = a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12);
  out[8] = a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21);
  out[9] = -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21));
  out[10] = a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11);
  out[11] = -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11));
  out[12] = -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21));
  out[13] = a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21);
  out[14] = -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11));
  out[15] = a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11);
  return out;
}
/**
 * Calculates the determinant of a mat4
 *
 * @param {ReadonlyMat4} a the source matrix
 * @returns {Number} determinant of a
 */

function determinant(a) {
  var a00 = a[0],
      a01 = a[1],
      a02 = a[2],
      a03 = a[3];
  var a10 = a[4],
      a11 = a[5],
      a12 = a[6],
      a13 = a[7];
  var a20 = a[8],
      a21 = a[9],
      a22 = a[10],
      a23 = a[11];
  var a30 = a[12],
      a31 = a[13],
      a32 = a[14],
      a33 = a[15];
  var b00 = a00 * a11 - a01 * a10;
  var b01 = a00 * a12 - a02 * a10;
  var b02 = a00 * a13 - a03 * a10;
  var b03 = a01 * a12 - a02 * a11;
  var b04 = a01 * a13 - a03 * a11;
  var b05 = a02 * a13 - a03 * a12;
  var b06 = a20 * a31 - a21 * a30;
  var b07 = a20 * a32 - a22 * a30;
  var b08 = a20 * a33 - a23 * a30;
  var b09 = a21 * a32 - a22 * a31;
  var b10 = a21 * a33 - a23 * a31;
  var b11 = a22 * a33 - a23 * a32; // Calculate the determinant

  return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
}
/**
 * Multiplies two mat4s
 *
 * @param {mat4} out the receiving matrix
 * @param {ReadonlyMat4} a the first operand
 * @param {ReadonlyMat4} b the second operand
 * @returns {mat4} out
 */

function multiply$5(out, a, b) {
  var a00 = a[0],
      a01 = a[1],
      a02 = a[2],
      a03 = a[3];
  var a10 = a[4],
      a11 = a[5],
      a12 = a[6],
      a13 = a[7];
  var a20 = a[8],
      a21 = a[9],
      a22 = a[10],
      a23 = a[11];
  var a30 = a[12],
      a31 = a[13],
      a32 = a[14],
      a33 = a[15]; // Cache only the current line of the second matrix

  var b0 = b[0],
      b1 = b[1],
      b2 = b[2],
      b3 = b[3];
  out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  b0 = b[4];
  b1 = b[5];
  b2 = b[6];
  b3 = b[7];
  out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  b0 = b[8];
  b1 = b[9];
  b2 = b[10];
  b3 = b[11];
  out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  b0 = b[12];
  b1 = b[13];
  b2 = b[14];
  b3 = b[15];
  out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  return out;
}
/**
 * Translate a mat4 by the given vector
 *
 * @param {mat4} out the receiving matrix
 * @param {ReadonlyMat4} a the matrix to translate
 * @param {ReadonlyVec3} v vector to translate by
 * @returns {mat4} out
 */

function translate$2(out, a, v) {
  var x = v[0],
      y = v[1],
      z = v[2];
  var a00, a01, a02, a03;
  var a10, a11, a12, a13;
  var a20, a21, a22, a23;

  if (a === out) {
    out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];
    out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];
    out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];
    out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];
  } else {
    a00 = a[0];
    a01 = a[1];
    a02 = a[2];
    a03 = a[3];
    a10 = a[4];
    a11 = a[5];
    a12 = a[6];
    a13 = a[7];
    a20 = a[8];
    a21 = a[9];
    a22 = a[10];
    a23 = a[11];
    out[0] = a00;
    out[1] = a01;
    out[2] = a02;
    out[3] = a03;
    out[4] = a10;
    out[5] = a11;
    out[6] = a12;
    out[7] = a13;
    out[8] = a20;
    out[9] = a21;
    out[10] = a22;
    out[11] = a23;
    out[12] = a00 * x + a10 * y + a20 * z + a[12];
    out[13] = a01 * x + a11 * y + a21 * z + a[13];
    out[14] = a02 * x + a12 * y + a22 * z + a[14];
    out[15] = a03 * x + a13 * y + a23 * z + a[15];
  }

  return out;
}
/**
 * Scales the mat4 by the dimensions in the given vec3 not using vectorization
 *
 * @param {mat4} out the receiving matrix
 * @param {ReadonlyMat4} a the matrix to scale
 * @param {ReadonlyVec3} v the vec3 to scale the matrix by
 * @returns {mat4} out
 **/

function scale$5(out, a, v) {
  var x = v[0],
      y = v[1],
      z = v[2];
  out[0] = a[0] * x;
  out[1] = a[1] * x;
  out[2] = a[2] * x;
  out[3] = a[3] * x;
  out[4] = a[4] * y;
  out[5] = a[5] * y;
  out[6] = a[6] * y;
  out[7] = a[7] * y;
  out[8] = a[8] * z;
  out[9] = a[9] * z;
  out[10] = a[10] * z;
  out[11] = a[11] * z;
  out[12] = a[12];
  out[13] = a[13];
  out[14] = a[14];
  out[15] = a[15];
  return out;
}
/**
 * Rotates a mat4 by the given angle around the given axis
 *
 * @param {mat4} out the receiving matrix
 * @param {ReadonlyMat4} a the matrix to rotate
 * @param {Number} rad the angle to rotate the matrix by
 * @param {ReadonlyVec3} axis the axis to rotate around
 * @returns {mat4} out
 */

function rotate$1(out, a, rad, axis) {
  var x = axis[0],
      y = axis[1],
      z = axis[2];
  var len = Math.hypot(x, y, z);
  var s, c, t;
  var a00, a01, a02, a03;
  var a10, a11, a12, a13;
  var a20, a21, a22, a23;
  var b00, b01, b02;
  var b10, b11, b12;
  var b20, b21, b22;

  if (len < EPSILON) {
    return null;
  }

  len = 1 / len;
  x *= len;
  y *= len;
  z *= len;
  s = Math.sin(rad);
  c = Math.cos(rad);
  t = 1 - c;
  a00 = a[0];
  a01 = a[1];
  a02 = a[2];
  a03 = a[3];
  a10 = a[4];
  a11 = a[5];
  a12 = a[6];
  a13 = a[7];
  a20 = a[8];
  a21 = a[9];
  a22 = a[10];
  a23 = a[11]; // Construct the elements of the rotation matrix

  b00 = x * x * t + c;
  b01 = y * x * t + z * s;
  b02 = z * x * t - y * s;
  b10 = x * y * t - z * s;
  b11 = y * y * t + c;
  b12 = z * y * t + x * s;
  b20 = x * z * t + y * s;
  b21 = y * z * t - x * s;
  b22 = z * z * t + c; // Perform rotation-specific matrix multiplication

  out[0] = a00 * b00 + a10 * b01 + a20 * b02;
  out[1] = a01 * b00 + a11 * b01 + a21 * b02;
  out[2] = a02 * b00 + a12 * b01 + a22 * b02;
  out[3] = a03 * b00 + a13 * b01 + a23 * b02;
  out[4] = a00 * b10 + a10 * b11 + a20 * b12;
  out[5] = a01 * b10 + a11 * b11 + a21 * b12;
  out[6] = a02 * b10 + a12 * b11 + a22 * b12;
  out[7] = a03 * b10 + a13 * b11 + a23 * b12;
  out[8] = a00 * b20 + a10 * b21 + a20 * b22;
  out[9] = a01 * b20 + a11 * b21 + a21 * b22;
  out[10] = a02 * b20 + a12 * b21 + a22 * b22;
  out[11] = a03 * b20 + a13 * b21 + a23 * b22;

  if (a !== out) {
    // If the source and destination differ, copy the unchanged last row
    out[12] = a[12];
    out[13] = a[13];
    out[14] = a[14];
    out[15] = a[15];
  }

  return out;
}
/**
 * Rotates a matrix by the given angle around the X axis
 *
 * @param {mat4} out the receiving matrix
 * @param {ReadonlyMat4} a the matrix to rotate
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat4} out
 */

function rotateX$3(out, a, rad) {
  var s = Math.sin(rad);
  var c = Math.cos(rad);
  var a10 = a[4];
  var a11 = a[5];
  var a12 = a[6];
  var a13 = a[7];
  var a20 = a[8];
  var a21 = a[9];
  var a22 = a[10];
  var a23 = a[11];

  if (a !== out) {
    // If the source and destination differ, copy the unchanged rows
    out[0] = a[0];
    out[1] = a[1];
    out[2] = a[2];
    out[3] = a[3];
    out[12] = a[12];
    out[13] = a[13];
    out[14] = a[14];
    out[15] = a[15];
  } // Perform axis-specific matrix multiplication


  out[4] = a10 * c + a20 * s;
  out[5] = a11 * c + a21 * s;
  out[6] = a12 * c + a22 * s;
  out[7] = a13 * c + a23 * s;
  out[8] = a20 * c - a10 * s;
  out[9] = a21 * c - a11 * s;
  out[10] = a22 * c - a12 * s;
  out[11] = a23 * c - a13 * s;
  return out;
}
/**
 * Rotates a matrix by the given angle around the Y axis
 *
 * @param {mat4} out the receiving matrix
 * @param {ReadonlyMat4} a the matrix to rotate
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat4} out
 */

function rotateY$3(out, a, rad) {
  var s = Math.sin(rad);
  var c = Math.cos(rad);
  var a00 = a[0];
  var a01 = a[1];
  var a02 = a[2];
  var a03 = a[3];
  var a20 = a[8];
  var a21 = a[9];
  var a22 = a[10];
  var a23 = a[11];

  if (a !== out) {
    // If the source and destination differ, copy the unchanged rows
    out[4] = a[4];
    out[5] = a[5];
    out[6] = a[6];
    out[7] = a[7];
    out[12] = a[12];
    out[13] = a[13];
    out[14] = a[14];
    out[15] = a[15];
  } // Perform axis-specific matrix multiplication


  out[0] = a00 * c - a20 * s;
  out[1] = a01 * c - a21 * s;
  out[2] = a02 * c - a22 * s;
  out[3] = a03 * c - a23 * s;
  out[8] = a00 * s + a20 * c;
  out[9] = a01 * s + a21 * c;
  out[10] = a02 * s + a22 * c;
  out[11] = a03 * s + a23 * c;
  return out;
}
/**
 * Rotates a matrix by the given angle around the Z axis
 *
 * @param {mat4} out the receiving matrix
 * @param {ReadonlyMat4} a the matrix to rotate
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat4} out
 */

function rotateZ$3(out, a, rad) {
  var s = Math.sin(rad);
  var c = Math.cos(rad);
  var a00 = a[0];
  var a01 = a[1];
  var a02 = a[2];
  var a03 = a[3];
  var a10 = a[4];
  var a11 = a[5];
  var a12 = a[6];
  var a13 = a[7];

  if (a !== out) {
    // If the source and destination differ, copy the unchanged last row
    out[8] = a[8];
    out[9] = a[9];
    out[10] = a[10];
    out[11] = a[11];
    out[12] = a[12];
    out[13] = a[13];
    out[14] = a[14];
    out[15] = a[15];
  } // Perform axis-specific matrix multiplication


  out[0] = a00 * c + a10 * s;
  out[1] = a01 * c + a11 * s;
  out[2] = a02 * c + a12 * s;
  out[3] = a03 * c + a13 * s;
  out[4] = a10 * c - a00 * s;
  out[5] = a11 * c - a01 * s;
  out[6] = a12 * c - a02 * s;
  out[7] = a13 * c - a03 * s;
  return out;
}
/**
 * Creates a matrix from a vector translation
 * This is equivalent to (but much faster than):
 *
 *     mat4.identity(dest);
 *     mat4.translate(dest, dest, vec);
 *
 * @param {mat4} out mat4 receiving operation result
 * @param {ReadonlyVec3} v Translation vector
 * @returns {mat4} out
 */

function fromTranslation$1(out, v) {
  out[0] = 1;
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = 0;
  out[5] = 1;
  out[6] = 0;
  out[7] = 0;
  out[8] = 0;
  out[9] = 0;
  out[10] = 1;
  out[11] = 0;
  out[12] = v[0];
  out[13] = v[1];
  out[14] = v[2];
  out[15] = 1;
  return out;
}
/**
 * Creates a matrix from a vector scaling
 * This is equivalent to (but much faster than):
 *
 *     mat4.identity(dest);
 *     mat4.scale(dest, dest, vec);
 *
 * @param {mat4} out mat4 receiving operation result
 * @param {ReadonlyVec3} v Scaling vector
 * @returns {mat4} out
 */

function fromScaling(out, v) {
  out[0] = v[0];
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = 0;
  out[5] = v[1];
  out[6] = 0;
  out[7] = 0;
  out[8] = 0;
  out[9] = 0;
  out[10] = v[2];
  out[11] = 0;
  out[12] = 0;
  out[13] = 0;
  out[14] = 0;
  out[15] = 1;
  return out;
}
/**
 * Creates a matrix from a given angle around a given axis
 * This is equivalent to (but much faster than):
 *
 *     mat4.identity(dest);
 *     mat4.rotate(dest, dest, rad, axis);
 *
 * @param {mat4} out mat4 receiving operation result
 * @param {Number} rad the angle to rotate the matrix by
 * @param {ReadonlyVec3} axis the axis to rotate around
 * @returns {mat4} out
 */

function fromRotation$1(out, rad, axis) {
  var x = axis[0],
      y = axis[1],
      z = axis[2];
  var len = Math.hypot(x, y, z);
  var s, c, t;

  if (len < EPSILON) {
    return null;
  }

  len = 1 / len;
  x *= len;
  y *= len;
  z *= len;
  s = Math.sin(rad);
  c = Math.cos(rad);
  t = 1 - c; // Perform rotation-specific matrix multiplication

  out[0] = x * x * t + c;
  out[1] = y * x * t + z * s;
  out[2] = z * x * t - y * s;
  out[3] = 0;
  out[4] = x * y * t - z * s;
  out[5] = y * y * t + c;
  out[6] = z * y * t + x * s;
  out[7] = 0;
  out[8] = x * z * t + y * s;
  out[9] = y * z * t - x * s;
  out[10] = z * z * t + c;
  out[11] = 0;
  out[12] = 0;
  out[13] = 0;
  out[14] = 0;
  out[15] = 1;
  return out;
}
/**
 * Creates a matrix from the given angle around the X axis
 * This is equivalent to (but much faster than):
 *
 *     mat4.identity(dest);
 *     mat4.rotateX(dest, dest, rad);
 *
 * @param {mat4} out mat4 receiving operation result
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat4} out
 */

function fromXRotation(out, rad) {
  var s = Math.sin(rad);
  var c = Math.cos(rad); // Perform axis-specific matrix multiplication

  out[0] = 1;
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = 0;
  out[5] = c;
  out[6] = s;
  out[7] = 0;
  out[8] = 0;
  out[9] = -s;
  out[10] = c;
  out[11] = 0;
  out[12] = 0;
  out[13] = 0;
  out[14] = 0;
  out[15] = 1;
  return out;
}
/**
 * Creates a matrix from the given angle around the Y axis
 * This is equivalent to (but much faster than):
 *
 *     mat4.identity(dest);
 *     mat4.rotateY(dest, dest, rad);
 *
 * @param {mat4} out mat4 receiving operation result
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat4} out
 */

function fromYRotation(out, rad) {
  var s = Math.sin(rad);
  var c = Math.cos(rad); // Perform axis-specific matrix multiplication

  out[0] = c;
  out[1] = 0;
  out[2] = -s;
  out[3] = 0;
  out[4] = 0;
  out[5] = 1;
  out[6] = 0;
  out[7] = 0;
  out[8] = s;
  out[9] = 0;
  out[10] = c;
  out[11] = 0;
  out[12] = 0;
  out[13] = 0;
  out[14] = 0;
  out[15] = 1;
  return out;
}
/**
 * Creates a matrix from the given angle around the Z axis
 * This is equivalent to (but much faster than):
 *
 *     mat4.identity(dest);
 *     mat4.rotateZ(dest, dest, rad);
 *
 * @param {mat4} out mat4 receiving operation result
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat4} out
 */

function fromZRotation(out, rad) {
  var s = Math.sin(rad);
  var c = Math.cos(rad); // Perform axis-specific matrix multiplication

  out[0] = c;
  out[1] = s;
  out[2] = 0;
  out[3] = 0;
  out[4] = -s;
  out[5] = c;
  out[6] = 0;
  out[7] = 0;
  out[8] = 0;
  out[9] = 0;
  out[10] = 1;
  out[11] = 0;
  out[12] = 0;
  out[13] = 0;
  out[14] = 0;
  out[15] = 1;
  return out;
}
/**
 * Creates a matrix from a quaternion rotation and vector translation
 * This is equivalent to (but much faster than):
 *
 *     mat4.identity(dest);
 *     mat4.translate(dest, vec);
 *     let quatMat = mat4.create();
 *     quat4.toMat4(quat, quatMat);
 *     mat4.multiply(dest, quatMat);
 *
 * @param {mat4} out mat4 receiving operation result
 * @param {quat4} q Rotation quaternion
 * @param {ReadonlyVec3} v Translation vector
 * @returns {mat4} out
 */

function fromRotationTranslation$1(out, q, v) {
  // Quaternion math
  var x = q[0],
      y = q[1],
      z = q[2],
      w = q[3];
  var x2 = x + x;
  var y2 = y + y;
  var z2 = z + z;
  var xx = x * x2;
  var xy = x * y2;
  var xz = x * z2;
  var yy = y * y2;
  var yz = y * z2;
  var zz = z * z2;
  var wx = w * x2;
  var wy = w * y2;
  var wz = w * z2;
  out[0] = 1 - (yy + zz);
  out[1] = xy + wz;
  out[2] = xz - wy;
  out[3] = 0;
  out[4] = xy - wz;
  out[5] = 1 - (xx + zz);
  out[6] = yz + wx;
  out[7] = 0;
  out[8] = xz + wy;
  out[9] = yz - wx;
  out[10] = 1 - (xx + yy);
  out[11] = 0;
  out[12] = v[0];
  out[13] = v[1];
  out[14] = v[2];
  out[15] = 1;
  return out;
}
/**
 * Creates a new mat4 from a dual quat.
 *
 * @param {mat4} out Matrix
 * @param {ReadonlyQuat2} a Dual Quaternion
 * @returns {mat4} mat4 receiving operation result
 */

function fromQuat2(out, a) {
  var translation = new ARRAY_TYPE(3);
  var bx = -a[0],
      by = -a[1],
      bz = -a[2],
      bw = a[3],
      ax = a[4],
      ay = a[5],
      az = a[6],
      aw = a[7];
  var magnitude = bx * bx + by * by + bz * bz + bw * bw; //Only scale if it makes sense

  if (magnitude > 0) {
    translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2 / magnitude;
    translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2 / magnitude;
    translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2 / magnitude;
  } else {
    translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2;
    translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2;
    translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2;
  }

  fromRotationTranslation$1(out, a, translation);
  return out;
}
/**
 * Returns the translation vector component of a transformation
 *  matrix. If a matrix is built with fromRotationTranslation,
 *  the returned vector will be the same as the translation vector
 *  originally supplied.
 * @param  {vec3} out Vector to receive translation component
 * @param  {ReadonlyMat4} mat Matrix to be decomposed (input)
 * @return {vec3} out
 */

function getTranslation$1(out, mat) {
  out[0] = mat[12];
  out[1] = mat[13];
  out[2] = mat[14];
  return out;
}
/**
 * Returns the scaling factor component of a transformation
 *  matrix. If a matrix is built with fromRotationTranslationScale
 *  with a normalized Quaternion paramter, the returned vector will be
 *  the same as the scaling vector
 *  originally supplied.
 * @param  {vec3} out Vector to receive scaling factor component
 * @param  {ReadonlyMat4} mat Matrix to be decomposed (input)
 * @return {vec3} out
 */

function getScaling(out, mat) {
  var m11 = mat[0];
  var m12 = mat[1];
  var m13 = mat[2];
  var m21 = mat[4];
  var m22 = mat[5];
  var m23 = mat[6];
  var m31 = mat[8];
  var m32 = mat[9];
  var m33 = mat[10];
  out[0] = Math.hypot(m11, m12, m13);
  out[1] = Math.hypot(m21, m22, m23);
  out[2] = Math.hypot(m31, m32, m33);
  return out;
}
/**
 * Returns a quaternion representing the rotational component
 *  of a transformation matrix. If a matrix is built with
 *  fromRotationTranslation, the returned quaternion will be the
 *  same as the quaternion originally supplied.
 * @param {quat} out Quaternion to receive the rotation component
 * @param {ReadonlyMat4} mat Matrix to be decomposed (input)
 * @return {quat} out
 */

function getRotation(out, mat) {
  var scaling = new ARRAY_TYPE(3);
  getScaling(scaling, mat);
  var is1 = 1 / scaling[0];
  var is2 = 1 / scaling[1];
  var is3 = 1 / scaling[2];
  var sm11 = mat[0] * is1;
  var sm12 = mat[1] * is2;
  var sm13 = mat[2] * is3;
  var sm21 = mat[4] * is1;
  var sm22 = mat[5] * is2;
  var sm23 = mat[6] * is3;
  var sm31 = mat[8] * is1;
  var sm32 = mat[9] * is2;
  var sm33 = mat[10] * is3;
  var trace = sm11 + sm22 + sm33;
  var S = 0;

  if (trace > 0) {
    S = Math.sqrt(trace + 1.0) * 2;
    out[3] = 0.25 * S;
    out[0] = (sm23 - sm32) / S;
    out[1] = (sm31 - sm13) / S;
    out[2] = (sm12 - sm21) / S;
  } else if (sm11 > sm22 && sm11 > sm33) {
    S = Math.sqrt(1.0 + sm11 - sm22 - sm33) * 2;
    out[3] = (sm23 - sm32) / S;
    out[0] = 0.25 * S;
    out[1] = (sm12 + sm21) / S;
    out[2] = (sm31 + sm13) / S;
  } else if (sm22 > sm33) {
    S = Math.sqrt(1.0 + sm22 - sm11 - sm33) * 2;
    out[3] = (sm31 - sm13) / S;
    out[0] = (sm12 + sm21) / S;
    out[1] = 0.25 * S;
    out[2] = (sm23 + sm32) / S;
  } else {
    S = Math.sqrt(1.0 + sm33 - sm11 - sm22) * 2;
    out[3] = (sm12 - sm21) / S;
    out[0] = (sm31 + sm13) / S;
    out[1] = (sm23 + sm32) / S;
    out[2] = 0.25 * S;
  }

  return out;
}
/**
 * Creates a matrix from a quaternion rotation, vector translation and vector scale
 * This is equivalent to (but much faster than):
 *
 *     mat4.identity(dest);
 *     mat4.translate(dest, vec);
 *     let quatMat = mat4.create();
 *     quat4.toMat4(quat, quatMat);
 *     mat4.multiply(dest, quatMat);
 *     mat4.scale(dest, scale)
 *
 * @param {mat4} out mat4 receiving operation result
 * @param {quat4} q Rotation quaternion
 * @param {ReadonlyVec3} v Translation vector
 * @param {ReadonlyVec3} s Scaling vector
 * @returns {mat4} out
 */

function fromRotationTranslationScale(out, q, v, s) {
  // Quaternion math
  var x = q[0],
      y = q[1],
      z = q[2],
      w = q[3];
  var x2 = x + x;
  var y2 = y + y;
  var z2 = z + z;
  var xx = x * x2;
  var xy = x * y2;
  var xz = x * z2;
  var yy = y * y2;
  var yz = y * z2;
  var zz = z * z2;
  var wx = w * x2;
  var wy = w * y2;
  var wz = w * z2;
  var sx = s[0];
  var sy = s[1];
  var sz = s[2];
  out[0] = (1 - (yy + zz)) * sx;
  out[1] = (xy + wz) * sx;
  out[2] = (xz - wy) * sx;
  out[3] = 0;
  out[4] = (xy - wz) * sy;
  out[5] = (1 - (xx + zz)) * sy;
  out[6] = (yz + wx) * sy;
  out[7] = 0;
  out[8] = (xz + wy) * sz;
  out[9] = (yz - wx) * sz;
  out[10] = (1 - (xx + yy)) * sz;
  out[11] = 0;
  out[12] = v[0];
  out[13] = v[1];
  out[14] = v[2];
  out[15] = 1;
  return out;
}
/**
 * Creates a matrix from a quaternion rotation, vector translation and vector scale, rotating and scaling around the given origin
 * This is equivalent to (but much faster than):
 *
 *     mat4.identity(dest);
 *     mat4.translate(dest, vec);
 *     mat4.translate(dest, origin);
 *     let quatMat = mat4.create();
 *     quat4.toMat4(quat, quatMat);
 *     mat4.multiply(dest, quatMat);
 *     mat4.scale(dest, scale)
 *     mat4.translate(dest, negativeOrigin);
 *
 * @param {mat4} out mat4 receiving operation result
 * @param {quat4} q Rotation quaternion
 * @param {ReadonlyVec3} v Translation vector
 * @param {ReadonlyVec3} s Scaling vector
 * @param {ReadonlyVec3} o The origin vector around which to scale and rotate
 * @returns {mat4} out
 */

function fromRotationTranslationScaleOrigin(out, q, v, s, o) {
  // Quaternion math
  var x = q[0],
      y = q[1],
      z = q[2],
      w = q[3];
  var x2 = x + x;
  var y2 = y + y;
  var z2 = z + z;
  var xx = x * x2;
  var xy = x * y2;
  var xz = x * z2;
  var yy = y * y2;
  var yz = y * z2;
  var zz = z * z2;
  var wx = w * x2;
  var wy = w * y2;
  var wz = w * z2;
  var sx = s[0];
  var sy = s[1];
  var sz = s[2];
  var ox = o[0];
  var oy = o[1];
  var oz = o[2];
  var out0 = (1 - (yy + zz)) * sx;
  var out1 = (xy + wz) * sx;
  var out2 = (xz - wy) * sx;
  var out4 = (xy - wz) * sy;
  var out5 = (1 - (xx + zz)) * sy;
  var out6 = (yz + wx) * sy;
  var out8 = (xz + wy) * sz;
  var out9 = (yz - wx) * sz;
  var out10 = (1 - (xx + yy)) * sz;
  out[0] = out0;
  out[1] = out1;
  out[2] = out2;
  out[3] = 0;
  out[4] = out4;
  out[5] = out5;
  out[6] = out6;
  out[7] = 0;
  out[8] = out8;
  out[9] = out9;
  out[10] = out10;
  out[11] = 0;
  out[12] = v[0] + ox - (out0 * ox + out4 * oy + out8 * oz);
  out[13] = v[1] + oy - (out1 * ox + out5 * oy + out9 * oz);
  out[14] = v[2] + oz - (out2 * ox + out6 * oy + out10 * oz);
  out[15] = 1;
  return out;
}
/**
 * Calculates a 4x4 matrix from the given quaternion
 *
 * @param {mat4} out mat4 receiving operation result
 * @param {ReadonlyQuat} q Quaternion to create matrix from
 *
 * @returns {mat4} out
 */

function fromQuat(out, q) {
  var x = q[0],
      y = q[1],
      z = q[2],
      w = q[3];
  var x2 = x + x;
  var y2 = y + y;
  var z2 = z + z;
  var xx = x * x2;
  var yx = y * x2;
  var yy = y * y2;
  var zx = z * x2;
  var zy = z * y2;
  var zz = z * z2;
  var wx = w * x2;
  var wy = w * y2;
  var wz = w * z2;
  out[0] = 1 - yy - zz;
  out[1] = yx + wz;
  out[2] = zx - wy;
  out[3] = 0;
  out[4] = yx - wz;
  out[5] = 1 - xx - zz;
  out[6] = zy + wx;
  out[7] = 0;
  out[8] = zx + wy;
  out[9] = zy - wx;
  out[10] = 1 - xx - yy;
  out[11] = 0;
  out[12] = 0;
  out[13] = 0;
  out[14] = 0;
  out[15] = 1;
  return out;
}
/**
 * Generates a frustum matrix with the given bounds
 *
 * @param {mat4} out mat4 frustum matrix will be written into
 * @param {Number} left Left bound of the frustum
 * @param {Number} right Right bound of the frustum
 * @param {Number} bottom Bottom bound of the frustum
 * @param {Number} top Top bound of the frustum
 * @param {Number} near Near bound of the frustum
 * @param {Number} far Far bound of the frustum
 * @returns {mat4} out
 */

function frustum(out, left, right, bottom, top, near, far) {
  var rl = 1 / (right - left);
  var tb = 1 / (top - bottom);
  var nf = 1 / (near - far);
  out[0] = near * 2 * rl;
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = 0;
  out[5] = near * 2 * tb;
  out[6] = 0;
  out[7] = 0;
  out[8] = (right + left) * rl;
  out[9] = (top + bottom) * tb;
  out[10] = (far + near) * nf;
  out[11] = -1;
  out[12] = 0;
  out[13] = 0;
  out[14] = far * near * 2 * nf;
  out[15] = 0;
  return out;
}
/**
 * Generates a perspective projection matrix with the given bounds.
 * The near/far clip planes correspond to a normalized device coordinate Z range of [-1, 1],
 * which matches WebGL/OpenGL's clip volume.
 * Passing null/undefined/no value for far will generate infinite projection matrix.
 *
 * @param {mat4} out mat4 frustum matrix will be written into
 * @param {number} fovy Vertical field of view in radians
 * @param {number} aspect Aspect ratio. typically viewport width/height
 * @param {number} near Near bound of the frustum
 * @param {number} far Far bound of the frustum, can be null or Infinity
 * @returns {mat4} out
 */

function perspectiveNO(out, fovy, aspect, near, far) {
  var f = 1.0 / Math.tan(fovy / 2),
      nf;
  out[0] = f / aspect;
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = 0;
  out[5] = f;
  out[6] = 0;
  out[7] = 0;
  out[8] = 0;
  out[9] = 0;
  out[11] = -1;
  out[12] = 0;
  out[13] = 0;
  out[15] = 0;

  if (far != null && far !== Infinity) {
    nf = 1 / (near - far);
    out[10] = (far + near) * nf;
    out[14] = 2 * far * near * nf;
  } else {
    out[10] = -1;
    out[14] = -2 * near;
  }

  return out;
}
/**
 * Alias for {@link mat4.perspectiveNO}
 * @function
 */

var perspective = perspectiveNO;
/**
 * Generates a perspective projection matrix suitable for WebGPU with the given bounds.
 * The near/far clip planes correspond to a normalized device coordinate Z range of [0, 1],
 * which matches WebGPU/Vulkan/DirectX/Metal's clip volume.
 * Passing null/undefined/no value for far will generate infinite projection matrix.
 *
 * @param {mat4} out mat4 frustum matrix will be written into
 * @param {number} fovy Vertical field of view in radians
 * @param {number} aspect Aspect ratio. typically viewport width/height
 * @param {number} near Near bound of the frustum
 * @param {number} far Far bound of the frustum, can be null or Infinity
 * @returns {mat4} out
 */

function perspectiveZO(out, fovy, aspect, near, far) {
  var f = 1.0 / Math.tan(fovy / 2),
      nf;
  out[0] = f / aspect;
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = 0;
  out[5] = f;
  out[6] = 0;
  out[7] = 0;
  out[8] = 0;
  out[9] = 0;
  out[11] = -1;
  out[12] = 0;
  out[13] = 0;
  out[15] = 0;

  if (far != null && far !== Infinity) {
    nf = 1 / (near - far);
    out[10] = far * nf;
    out[14] = far * near * nf;
  } else {
    out[10] = -1;
    out[14] = -near;
  }

  return out;
}
/**
 * Generates a perspective projection matrix with the given field of view.
 * This is primarily useful for generating projection matrices to be used
 * with the still experiemental WebVR API.
 *
 * @param {mat4} out mat4 frustum matrix will be written into
 * @param {Object} fov Object containing the following values: upDegrees, downDegrees, leftDegrees, rightDegrees
 * @param {number} near Near bound of the frustum
 * @param {number} far Far bound of the frustum
 * @returns {mat4} out
 */

function perspectiveFromFieldOfView(out, fov, near, far) {
  var upTan = Math.tan(fov.upDegrees * Math.PI / 180.0);
  var downTan = Math.tan(fov.downDegrees * Math.PI / 180.0);
  var leftTan = Math.tan(fov.leftDegrees * Math.PI / 180.0);
  var rightTan = Math.tan(fov.rightDegrees * Math.PI / 180.0);
  var xScale = 2.0 / (leftTan + rightTan);
  var yScale = 2.0 / (upTan + downTan);
  out[0] = xScale;
  out[1] = 0.0;
  out[2] = 0.0;
  out[3] = 0.0;
  out[4] = 0.0;
  out[5] = yScale;
  out[6] = 0.0;
  out[7] = 0.0;
  out[8] = -((leftTan - rightTan) * xScale * 0.5);
  out[9] = (upTan - downTan) * yScale * 0.5;
  out[10] = far / (near - far);
  out[11] = -1.0;
  out[12] = 0.0;
  out[13] = 0.0;
  out[14] = far * near / (near - far);
  out[15] = 0.0;
  return out;
}
/**
 * Generates a orthogonal projection matrix with the given bounds.
 * The near/far clip planes correspond to a normalized device coordinate Z range of [-1, 1],
 * which matches WebGL/OpenGL's clip volume.
 *
 * @param {mat4} out mat4 frustum matrix will be written into
 * @param {number} left Left bound of the frustum
 * @param {number} right Right bound of the frustum
 * @param {number} bottom Bottom bound of the frustum
 * @param {number} top Top bound of the frustum
 * @param {number} near Near bound of the frustum
 * @param {number} far Far bound of the frustum
 * @returns {mat4} out
 */

function orthoNO(out, left, right, bottom, top, near, far) {
  var lr = 1 / (left - right);
  var bt = 1 / (bottom - top);
  var nf = 1 / (near - far);
  out[0] = -2 * lr;
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = 0;
  out[5] = -2 * bt;
  out[6] = 0;
  out[7] = 0;
  out[8] = 0;
  out[9] = 0;
  out[10] = 2 * nf;
  out[11] = 0;
  out[12] = (left + right) * lr;
  out[13] = (top + bottom) * bt;
  out[14] = (far + near) * nf;
  out[15] = 1;
  return out;
}
/**
 * Alias for {@link mat4.orthoNO}
 * @function
 */

var ortho = orthoNO;
/**
 * Generates a orthogonal projection matrix with the given bounds.
 * The near/far clip planes correspond to a normalized device coordinate Z range of [0, 1],
 * which matches WebGPU/Vulkan/DirectX/Metal's clip volume.
 *
 * @param {mat4} out mat4 frustum matrix will be written into
 * @param {number} left Left bound of the frustum
 * @param {number} right Right bound of the frustum
 * @param {number} bottom Bottom bound of the frustum
 * @param {number} top Top bound of the frustum
 * @param {number} near Near bound of the frustum
 * @param {number} far Far bound of the frustum
 * @returns {mat4} out
 */

function orthoZO(out, left, right, bottom, top, near, far) {
  var lr = 1 / (left - right);
  var bt = 1 / (bottom - top);
  var nf = 1 / (near - far);
  out[0] = -2 * lr;
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = 0;
  out[5] = -2 * bt;
  out[6] = 0;
  out[7] = 0;
  out[8] = 0;
  out[9] = 0;
  out[10] = nf;
  out[11] = 0;
  out[12] = (left + right) * lr;
  out[13] = (top + bottom) * bt;
  out[14] = near * nf;
  out[15] = 1;
  return out;
}
/**
 * Generates a look-at matrix with the given eye position, focal point, and up axis.
 * If you want a matrix that actually makes an object look at another object, you should use targetTo instead.
 *
 * @param {mat4} out mat4 frustum matrix will be written into
 * @param {ReadonlyVec3} eye Position of the viewer
 * @param {ReadonlyVec3} center Point the viewer is looking at
 * @param {ReadonlyVec3} up vec3 pointing up
 * @returns {mat4} out
 */

function lookAt(out, eye, center, up) {
  var x0, x1, x2, y0, y1, y2, z0, z1, z2, len;
  var eyex = eye[0];
  var eyey = eye[1];
  var eyez = eye[2];
  var upx = up[0];
  var upy = up[1];
  var upz = up[2];
  var centerx = center[0];
  var centery = center[1];
  var centerz = center[2];

  if (Math.abs(eyex - centerx) < EPSILON && Math.abs(eyey - centery) < EPSILON && Math.abs(eyez - centerz) < EPSILON) {
    return identity$3(out);
  }

  z0 = eyex - centerx;
  z1 = eyey - centery;
  z2 = eyez - centerz;
  len = 1 / Math.hypot(z0, z1, z2);
  z0 *= len;
  z1 *= len;
  z2 *= len;
  x0 = upy * z2 - upz * z1;
  x1 = upz * z0 - upx * z2;
  x2 = upx * z1 - upy * z0;
  len = Math.hypot(x0, x1, x2);

  if (!len) {
    x0 = 0;
    x1 = 0;
    x2 = 0;
  } else {
    len = 1 / len;
    x0 *= len;
    x1 *= len;
    x2 *= len;
  }

  y0 = z1 * x2 - z2 * x1;
  y1 = z2 * x0 - z0 * x2;
  y2 = z0 * x1 - z1 * x0;
  len = Math.hypot(y0, y1, y2);

  if (!len) {
    y0 = 0;
    y1 = 0;
    y2 = 0;
  } else {
    len = 1 / len;
    y0 *= len;
    y1 *= len;
    y2 *= len;
  }

  out[0] = x0;
  out[1] = y0;
  out[2] = z0;
  out[3] = 0;
  out[4] = x1;
  out[5] = y1;
  out[6] = z1;
  out[7] = 0;
  out[8] = x2;
  out[9] = y2;
  out[10] = z2;
  out[11] = 0;
  out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez);
  out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez);
  out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez);
  out[15] = 1;
  return out;
}
/**
 * Generates a matrix that makes something look at something else.
 *
 * @param {mat4} out mat4 frustum matrix will be written into
 * @param {ReadonlyVec3} eye Position of the viewer
 * @param {ReadonlyVec3} center Point the viewer is looking at
 * @param {ReadonlyVec3} up vec3 pointing up
 * @returns {mat4} out
 */

function targetTo(out, eye, target, up) {
  var eyex = eye[0],
      eyey = eye[1],
      eyez = eye[2],
      upx = up[0],
      upy = up[1],
      upz = up[2];
  var z0 = eyex - target[0],
      z1 = eyey - target[1],
      z2 = eyez - target[2];
  var len = z0 * z0 + z1 * z1 + z2 * z2;

  if (len > 0) {
    len = 1 / Math.sqrt(len);
    z0 *= len;
    z1 *= len;
    z2 *= len;
  }

  var x0 = upy * z2 - upz * z1,
      x1 = upz * z0 - upx * z2,
      x2 = upx * z1 - upy * z0;
  len = x0 * x0 + x1 * x1 + x2 * x2;

  if (len > 0) {
    len = 1 / Math.sqrt(len);
    x0 *= len;
    x1 *= len;
    x2 *= len;
  }

  out[0] = x0;
  out[1] = x1;
  out[2] = x2;
  out[3] = 0;
  out[4] = z1 * x2 - z2 * x1;
  out[5] = z2 * x0 - z0 * x2;
  out[6] = z0 * x1 - z1 * x0;
  out[7] = 0;
  out[8] = z0;
  out[9] = z1;
  out[10] = z2;
  out[11] = 0;
  out[12] = eyex;
  out[13] = eyey;
  out[14] = eyez;
  out[15] = 1;
  return out;
}
/**
 * Returns a string representation of a mat4
 *
 * @param {ReadonlyMat4} a matrix to represent as a string
 * @returns {String} string representation of the matrix
 */

function str$5(a) {
  return "mat4(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ", " + a[8] + ", " + a[9] + ", " + a[10] + ", " + a[11] + ", " + a[12] + ", " + a[13] + ", " + a[14] + ", " + a[15] + ")";
}
/**
 * Returns Frobenius norm of a mat4
 *
 * @param {ReadonlyMat4} a the matrix to calculate Frobenius norm of
 * @returns {Number} Frobenius norm
 */

function frob(a) {
  return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]);
}
/**
 * Adds two mat4's
 *
 * @param {mat4} out the receiving matrix
 * @param {ReadonlyMat4} a the first operand
 * @param {ReadonlyMat4} b the second operand
 * @returns {mat4} out
 */

function add$5(out, a, b) {
  out[0] = a[0] + b[0];
  out[1] = a[1] + b[1];
  out[2] = a[2] + b[2];
  out[3] = a[3] + b[3];
  out[4] = a[4] + b[4];
  out[5] = a[5] + b[5];
  out[6] = a[6] + b[6];
  out[7] = a[7] + b[7];
  out[8] = a[8] + b[8];
  out[9] = a[9] + b[9];
  out[10] = a[10] + b[10];
  out[11] = a[11] + b[11];
  out[12] = a[12] + b[12];
  out[13] = a[13] + b[13];
  out[14] = a[14] + b[14];
  out[15] = a[15] + b[15];
  return out;
}
/**
 * Subtracts matrix b from matrix a
 *
 * @param {mat4} out the receiving matrix
 * @param {ReadonlyMat4} a the first operand
 * @param {ReadonlyMat4} b the second operand
 * @returns {mat4} out
 */

function subtract$3(out, a, b) {
  out[0] = a[0] - b[0];
  out[1] = a[1] - b[1];
  out[2] = a[2] - b[2];
  out[3] = a[3] - b[3];
  out[4] = a[4] - b[4];
  out[5] = a[5] - b[5];
  out[6] = a[6] - b[6];
  out[7] = a[7] - b[7];
  out[8] = a[8] - b[8];
  out[9] = a[9] - b[9];
  out[10] = a[10] - b[10];
  out[11] = a[11] - b[11];
  out[12] = a[12] - b[12];
  out[13] = a[13] - b[13];
  out[14] = a[14] - b[14];
  out[15] = a[15] - b[15];
  return out;
}
/**
 * Multiply each element of the matrix by a scalar.
 *
 * @param {mat4} out the receiving matrix
 * @param {ReadonlyMat4} a the matrix to scale
 * @param {Number} b amount to scale the matrix's elements by
 * @returns {mat4} out
 */

function multiplyScalar(out, a, b) {
  out[0] = a[0] * b;
  out[1] = a[1] * b;
  out[2] = a[2] * b;
  out[3] = a[3] * b;
  out[4] = a[4] * b;
  out[5] = a[5] * b;
  out[6] = a[6] * b;
  out[7] = a[7] * b;
  out[8] = a[8] * b;
  out[9] = a[9] * b;
  out[10] = a[10] * b;
  out[11] = a[11] * b;
  out[12] = a[12] * b;
  out[13] = a[13] * b;
  out[14] = a[14] * b;
  out[15] = a[15] * b;
  return out;
}
/**
 * Adds two mat4's after multiplying each element of the second operand by a scalar value.
 *
 * @param {mat4} out the receiving vector
 * @param {ReadonlyMat4} a the first operand
 * @param {ReadonlyMat4} b the second operand
 * @param {Number} scale the amount to scale b's elements by before adding
 * @returns {mat4} out
 */

function multiplyScalarAndAdd(out, a, b, scale) {
  out[0] = a[0] + b[0] * scale;
  out[1] = a[1] + b[1] * scale;
  out[2] = a[2] + b[2] * scale;
  out[3] = a[3] + b[3] * scale;
  out[4] = a[4] + b[4] * scale;
  out[5] = a[5] + b[5] * scale;
  out[6] = a[6] + b[6] * scale;
  out[7] = a[7] + b[7] * scale;
  out[8] = a[8] + b[8] * scale;
  out[9] = a[9] + b[9] * scale;
  out[10] = a[10] + b[10] * scale;
  out[11] = a[11] + b[11] * scale;
  out[12] = a[12] + b[12] * scale;
  out[13] = a[13] + b[13] * scale;
  out[14] = a[14] + b[14] * scale;
  out[15] = a[15] + b[15] * scale;
  return out;
}
/**
 * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===)
 *
 * @param {ReadonlyMat4} a The first matrix.
 * @param {ReadonlyMat4} b The second matrix.
 * @returns {Boolean} True if the matrices are equal, false otherwise.
 */

function exactEquals$5(a, b) {
  return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8] && a[9] === b[9] && a[10] === b[10] && a[11] === b[11] && a[12] === b[12] && a[13] === b[13] && a[14] === b[14] && a[15] === b[15];
}
/**
 * Returns whether or not the matrices have approximately the same elements in the same position.
 *
 * @param {ReadonlyMat4} a The first matrix.
 * @param {ReadonlyMat4} b The second matrix.
 * @returns {Boolean} True if the matrices are equal, false otherwise.
 */

function equals$6(a, b) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3];
  var a4 = a[4],
      a5 = a[5],
      a6 = a[6],
      a7 = a[7];
  var a8 = a[8],
      a9 = a[9],
      a10 = a[10],
      a11 = a[11];
  var a12 = a[12],
      a13 = a[13],
      a14 = a[14],
      a15 = a[15];
  var b0 = b[0],
      b1 = b[1],
      b2 = b[2],
      b3 = b[3];
  var b4 = b[4],
      b5 = b[5],
      b6 = b[6],
      b7 = b[7];
  var b8 = b[8],
      b9 = b[9],
      b10 = b[10],
      b11 = b[11];
  var b12 = b[12],
      b13 = b[13],
      b14 = b[14],
      b15 = b[15];
  return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= EPSILON * Math.max(1.0, Math.abs(a8), Math.abs(b8)) && Math.abs(a9 - b9) <= EPSILON * Math.max(1.0, Math.abs(a9), Math.abs(b9)) && Math.abs(a10 - b10) <= EPSILON * Math.max(1.0, Math.abs(a10), Math.abs(b10)) && Math.abs(a11 - b11) <= EPSILON * Math.max(1.0, Math.abs(a11), Math.abs(b11)) && Math.abs(a12 - b12) <= EPSILON * Math.max(1.0, Math.abs(a12), Math.abs(b12)) && Math.abs(a13 - b13) <= EPSILON * Math.max(1.0, Math.abs(a13), Math.abs(b13)) && Math.abs(a14 - b14) <= EPSILON * Math.max(1.0, Math.abs(a14), Math.abs(b14)) && Math.abs(a15 - b15) <= EPSILON * Math.max(1.0, Math.abs(a15), Math.abs(b15));
}
/**
 * Alias for {@link mat4.multiply}
 * @function
 */

var mul$5 = multiply$5;
/**
 * Alias for {@link mat4.subtract}
 * @function
 */

var sub$3 = subtract$3;

var mat4 = /*#__PURE__*/Object.freeze({
__proto__: null,
add: add$5,
adjoint: adjoint,
clone: clone$5,
copy: copy$5,
create: create$5,
determinant: determinant,
equals: equals$6,
exactEquals: exactEquals$5,
frob: frob,
fromQuat: fromQuat,
fromQuat2: fromQuat2,
fromRotation: fromRotation$1,
fromRotationTranslation: fromRotationTranslation$1,
fromRotationTranslationScale: fromRotationTranslationScale,
fromRotationTranslationScaleOrigin: fromRotationTranslationScaleOrigin,
fromScaling: fromScaling,
fromTranslation: fromTranslation$1,
fromValues: fromValues$5,
fromXRotation: fromXRotation,
fromYRotation: fromYRotation,
fromZRotation: fromZRotation,
frustum: frustum,
getRotation: getRotation,
getScaling: getScaling,
getTranslation: getTranslation$1,
identity: identity$3,
invert: invert$2,
lookAt: lookAt,
mul: mul$5,
multiply: multiply$5,
multiplyScalar: multiplyScalar,
multiplyScalarAndAdd: multiplyScalarAndAdd,
ortho: ortho,
orthoNO: orthoNO,
orthoZO: orthoZO,
perspective: perspective,
perspectiveFromFieldOfView: perspectiveFromFieldOfView,
perspectiveNO: perspectiveNO,
perspectiveZO: perspectiveZO,
rotate: rotate$1,
rotateX: rotateX$3,
rotateY: rotateY$3,
rotateZ: rotateZ$3,
scale: scale$5,
set: set$5,
str: str$5,
sub: sub$3,
subtract: subtract$3,
targetTo: targetTo,
translate: translate$2,
transpose: transpose
});

/**
 * 3 Dimensional Vector
 * @module vec3
 */

/**
 * Creates a new, empty vec3
 *
 * @returns {vec3} a new 3D vector
 */

function create$4() {
  var out = new ARRAY_TYPE(3);

  if (ARRAY_TYPE != Float32Array) {
    out[0] = 0;
    out[1] = 0;
    out[2] = 0;
  }

  return out;
}
/**
 * Creates a new vec3 initialized with values from an existing vector
 *
 * @param {ReadonlyVec3} a vector to clone
 * @returns {vec3} a new 3D vector
 */

function clone$4(a) {
  var out = new ARRAY_TYPE(3);
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  return out;
}
/**
 * Calculates the length of a vec3
 *
 * @param {ReadonlyVec3} a vector to calculate length of
 * @returns {Number} length of a
 */

function length$4(a) {
  var x = a[0];
  var y = a[1];
  var z = a[2];
  return Math.hypot(x, y, z);
}
/**
 * Creates a new vec3 initialized with the given values
 *
 * @param {Number} x X component
 * @param {Number} y Y component
 * @param {Number} z Z component
 * @returns {vec3} a new 3D vector
 */

function fromValues$4(x, y, z) {
  var out = new ARRAY_TYPE(3);
  out[0] = x;
  out[1] = y;
  out[2] = z;
  return out;
}
/**
 * Copy the values from one vec3 to another
 *
 * @param {vec3} out the receiving vector
 * @param {ReadonlyVec3} a the source vector
 * @returns {vec3} out
 */

function copy$4(out, a) {
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  return out;
}
/**
 * Set the components of a vec3 to the given values
 *
 * @param {vec3} out the receiving vector
 * @param {Number} x X component
 * @param {Number} y Y component
 * @param {Number} z Z component
 * @returns {vec3} out
 */

function set$4(out, x, y, z) {
  out[0] = x;
  out[1] = y;
  out[2] = z;
  return out;
}
/**
 * Adds two vec3's
 *
 * @param {vec3} out the receiving vector
 * @param {ReadonlyVec3} a the first operand
 * @param {ReadonlyVec3} b the second operand
 * @returns {vec3} out
 */

function add$4(out, a, b) {
  out[0] = a[0] + b[0];
  out[1] = a[1] + b[1];
  out[2] = a[2] + b[2];
  return out;
}
/**
 * Subtracts vector b from vector a
 *
 * @param {vec3} out the receiving vector
 * @param {ReadonlyVec3} a the first operand
 * @param {ReadonlyVec3} b the second operand
 * @returns {vec3} out
 */

function subtract$2(out, a, b) {
  out[0] = a[0] - b[0];
  out[1] = a[1] - b[1];
  out[2] = a[2] - b[2];
  return out;
}
/**
 * Multiplies two vec3's
 *
 * @param {vec3} out the receiving vector
 * @param {ReadonlyVec3} a the first operand
 * @param {ReadonlyVec3} b the second operand
 * @returns {vec3} out
 */

function multiply$4(out, a, b) {
  out[0] = a[0] * b[0];
  out[1] = a[1] * b[1];
  out[2] = a[2] * b[2];
  return out;
}
/**
 * Divides two vec3's
 *
 * @param {vec3} out the receiving vector
 * @param {ReadonlyVec3} a the first operand
 * @param {ReadonlyVec3} b the second operand
 * @returns {vec3} out
 */

function divide$2(out, a, b) {
  out[0] = a[0] / b[0];
  out[1] = a[1] / b[1];
  out[2] = a[2] / b[2];
  return out;
}
/**
 * Math.ceil the components of a vec3
 *
 * @param {vec3} out the receiving vector
 * @param {ReadonlyVec3} a vector to ceil
 * @returns {vec3} out
 */

function ceil$2(out, a) {
  out[0] = Math.ceil(a[0]);
  out[1] = Math.ceil(a[1]);
  out[2] = Math.ceil(a[2]);
  return out;
}
/**
 * Math.floor the components of a vec3
 *
 * @param {vec3} out the receiving vector
 * @param {ReadonlyVec3} a vector to floor
 * @returns {vec3} out
 */

function floor$2(out, a) {
  out[0] = Math.floor(a[0]);
  out[1] = Math.floor(a[1]);
  out[2] = Math.floor(a[2]);
  return out;
}
/**
 * Returns the minimum of two vec3's
 *
 * @param {vec3} out the receiving vector
 * @param {ReadonlyVec3} a the first operand
 * @param {ReadonlyVec3} b the second operand
 * @returns {vec3} out
 */

function min$2(out, a, b) {
  out[0] = Math.min(a[0], b[0]);
  out[1] = Math.min(a[1], b[1]);
  out[2] = Math.min(a[2], b[2]);
  return out;
}
/**
 * Returns the maximum of two vec3's
 *
 * @param {vec3} out the receiving vector
 * @param {ReadonlyVec3} a the first operand
 * @param {ReadonlyVec3} b the second operand
 * @returns {vec3} out
 */

function max$2(out, a, b) {
  out[0] = Math.max(a[0], b[0]);
  out[1] = Math.max(a[1], b[1]);
  out[2] = Math.max(a[2], b[2]);
  return out;
}
/**
 * Math.round the components of a vec3
 *
 * @param {vec3} out the receiving vector
 * @param {ReadonlyVec3} a vector to round
 * @returns {vec3} out
 */

function round$2(out, a) {
  out[0] = Math.round(a[0]);
  out[1] = Math.round(a[1]);
  out[2] = Math.round(a[2]);
  return out;
}
/**
 * Scales a vec3 by a scalar number
 *
 * @param {vec3} out the receiving vector
 * @param {ReadonlyVec3} a the vector to scale
 * @param {Number} b amount to scale the vector by
 * @returns {vec3} out
 */

function scale$4(out, a, b) {
  out[0] = a[0] * b;
  out[1] = a[1] * b;
  out[2] = a[2] * b;
  return out;
}
/**
 * Adds two vec3's after scaling the second operand by a scalar value
 *
 * @param {vec3} out the receiving vector
 * @param {ReadonlyVec3} a the first operand
 * @param {ReadonlyVec3} b the second operand
 * @param {Number} scale the amount to scale b by before adding
 * @returns {vec3} out
 */

function scaleAndAdd$2(out, a, b, scale) {
  out[0] = a[0] + b[0] * scale;
  out[1] = a[1] + b[1] * scale;
  out[2] = a[2] + b[2] * scale;
  return out;
}
/**
 * Calculates the euclidian distance between two vec3's
 *
 * @param {ReadonlyVec3} a the first operand
 * @param {ReadonlyVec3} b the second operand
 * @returns {Number} distance between a and b
 */

function distance$2(a, b) {
  var x = b[0] - a[0];
  var y = b[1] - a[1];
  var z = b[2] - a[2];
  return Math.hypot(x, y, z);
}
/**
 * Calculates the squared euclidian distance between two vec3's
 *
 * @param {ReadonlyVec3} a the first operand
 * @param {ReadonlyVec3} b the second operand
 * @returns {Number} squared distance between a and b
 */

function squaredDistance$2(a, b) {
  var x = b[0] - a[0];
  var y = b[1] - a[1];
  var z = b[2] - a[2];
  return x * x + y * y + z * z;
}
/**
 * Calculates the squared length of a vec3
 *
 * @param {ReadonlyVec3} a vector to calculate squared length of
 * @returns {Number} squared length of a
 */

function squaredLength$4(a) {
  var x = a[0];
  var y = a[1];
  var z = a[2];
  return x * x + y * y + z * z;
}
/**
 * Negates the components of a vec3
 *
 * @param {vec3} out the receiving vector
 * @param {ReadonlyVec3} a vector to negate
 * @returns {vec3} out
 */

function negate$2(out, a) {
  out[0] = -a[0];
  out[1] = -a[1];
  out[2] = -a[2];
  return out;
}
/**
 * Returns the inverse of the components of a vec3
 *
 * @param {vec3} out the receiving vector
 * @param {ReadonlyVec3} a vector to invert
 * @returns {vec3} out
 */

function inverse$2(out, a) {
  out[0] = 1.0 / a[0];
  out[1] = 1.0 / a[1];
  out[2] = 1.0 / a[2];
  return out;
}
/**
 * Normalize a vec3
 *
 * @param {vec3} out the receiving vector
 * @param {ReadonlyVec3} a vector to normalize
 * @returns {vec3} out
 */

function normalize$4(out, a) {
  var x = a[0];
  var y = a[1];
  var z = a[2];
  var len = x * x + y * y + z * z;

  if (len > 0) {
    //TODO: evaluate use of glm_invsqrt here?
    len = 1 / Math.sqrt(len);
  }

  out[0] = a[0] * len;
  out[1] = a[1] * len;
  out[2] = a[2] * len;
  return out;
}
/**
 * Calculates the dot product of two vec3's
 *
 * @param {ReadonlyVec3} a the first operand
 * @param {ReadonlyVec3} b the second operand
 * @returns {Number} dot product of a and b
 */

function dot$5(a, b) {
  return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
}
/**
 * Computes the cross product of two vec3's
 *
 * @param {vec3} out the receiving vector
 * @param {ReadonlyVec3} a the first operand
 * @param {ReadonlyVec3} b the second operand
 * @returns {vec3} out
 */

function cross$2(out, a, b) {
  var ax = a[0],
      ay = a[1],
      az = a[2];
  var bx = b[0],
      by = b[1],
      bz = b[2];
  out[0] = ay * bz - az * by;
  out[1] = az * bx - ax * bz;
  out[2] = ax * by - ay * bx;
  return out;
}
/**
 * Performs a linear interpolation between two vec3's
 *
 * @param {vec3} out the receiving vector
 * @param {ReadonlyVec3} a the first operand
 * @param {ReadonlyVec3} b the second operand
 * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
 * @returns {vec3} out
 */

function lerp$4(out, a, b, t) {
  var ax = a[0];
  var ay = a[1];
  var az = a[2];
  out[0] = ax + t * (b[0] - ax);
  out[1] = ay + t * (b[1] - ay);
  out[2] = az + t * (b[2] - az);
  return out;
}
/**
 * Performs a hermite interpolation with two control points
 *
 * @param {vec3} out the receiving vector
 * @param {ReadonlyVec3} a the first operand
 * @param {ReadonlyVec3} b the second operand
 * @param {ReadonlyVec3} c the third operand
 * @param {ReadonlyVec3} d the fourth operand
 * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
 * @returns {vec3} out
 */

function hermite(out, a, b, c, d, t) {
  var factorTimes2 = t * t;
  var factor1 = factorTimes2 * (2 * t - 3) + 1;
  var factor2 = factorTimes2 * (t - 2) + t;
  var factor3 = factorTimes2 * (t - 1);
  var factor4 = factorTimes2 * (3 - 2 * t);
  out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4;
  out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4;
  out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4;
  return out;
}
/**
 * Performs a bezier interpolation with two control points
 *
 * @param {vec3} out the receiving vector
 * @param {ReadonlyVec3} a the first operand
 * @param {ReadonlyVec3} b the second operand
 * @param {ReadonlyVec3} c the third operand
 * @param {ReadonlyVec3} d the fourth operand
 * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
 * @returns {vec3} out
 */

function bezier(out, a, b, c, d, t) {
  var inverseFactor = 1 - t;
  var inverseFactorTimesTwo = inverseFactor * inverseFactor;
  var factorTimes2 = t * t;
  var factor1 = inverseFactorTimesTwo * inverseFactor;
  var factor2 = 3 * t * inverseFactorTimesTwo;
  var factor3 = 3 * factorTimes2 * inverseFactor;
  var factor4 = factorTimes2 * t;
  out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4;
  out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4;
  out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4;
  return out;
}
/**
 * Generates a random vector with the given scale
 *
 * @param {vec3} out the receiving vector
 * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
 * @returns {vec3} out
 */

function random$3(out, scale) {
  scale = scale || 1.0;
  var r = RANDOM() * 2.0 * Math.PI;
  var z = RANDOM() * 2.0 - 1.0;
  var zScale = Math.sqrt(1.0 - z * z) * scale;
  out[0] = Math.cos(r) * zScale;
  out[1] = Math.sin(r) * zScale;
  out[2] = z * scale;
  return out;
}
/**
 * Transforms the vec3 with a mat4.
 * 4th vector component is implicitly '1'
 *
 * @param {vec3} out the receiving vector
 * @param {ReadonlyVec3} a the vector to transform
 * @param {ReadonlyMat4} m matrix to transform with
 * @returns {vec3} out
 */

function transformMat4$2(out, a, m) {
  var x = a[0],
      y = a[1],
      z = a[2];
  var w = m[3] * x + m[7] * y + m[11] * z + m[15];
  w = w || 1.0;
  out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w;
  out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w;
  out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w;
  return out;
}
/**
 * Transforms the vec3 with a mat3.
 *
 * @param {vec3} out the receiving vector
 * @param {ReadonlyVec3} a the vector to transform
 * @param {ReadonlyMat3} m the 3x3 matrix to transform with
 * @returns {vec3} out
 */

function transformMat3$1(out, a, m) {
  var x = a[0],
      y = a[1],
      z = a[2];
  out[0] = x * m[0] + y * m[3] + z * m[6];
  out[1] = x * m[1] + y * m[4] + z * m[7];
  out[2] = x * m[2] + y * m[5] + z * m[8];
  return out;
}
/**
 * Transforms the vec3 with a quat
 * Can also be used for dual quaternions. (Multiply it with the real part)
 *
 * @param {vec3} out the receiving vector
 * @param {ReadonlyVec3} a the vector to transform
 * @param {ReadonlyQuat} q quaternion to transform with
 * @returns {vec3} out
 */

function transformQuat$1(out, a, q) {
  // benchmarks: https://jsperf.com/quaternion-transform-vec3-implementations-fixed
  var qx = q[0],
      qy = q[1],
      qz = q[2],
      qw = q[3];
  var x = a[0],
      y = a[1],
      z = a[2]; // var qvec = [qx, qy, qz];
  // var uv = vec3.cross([], qvec, a);

  var uvx = qy * z - qz * y,
      uvy = qz * x - qx * z,
      uvz = qx * y - qy * x; // var uuv = vec3.cross([], qvec, uv);

  var uuvx = qy * uvz - qz * uvy,
      uuvy = qz * uvx - qx * uvz,
      uuvz = qx * uvy - qy * uvx; // vec3.scale(uv, uv, 2 * w);

  var w2 = qw * 2;
  uvx *= w2;
  uvy *= w2;
  uvz *= w2; // vec3.scale(uuv, uuv, 2);

  uuvx *= 2;
  uuvy *= 2;
  uuvz *= 2; // return vec3.add(out, a, vec3.add(out, uv, uuv));

  out[0] = x + uvx + uuvx;
  out[1] = y + uvy + uuvy;
  out[2] = z + uvz + uuvz;
  return out;
}
/**
 * Rotate a 3D vector around the x-axis
 * @param {vec3} out The receiving vec3
 * @param {ReadonlyVec3} a The vec3 point to rotate
 * @param {ReadonlyVec3} b The origin of the rotation
 * @param {Number} rad The angle of rotation in radians
 * @returns {vec3} out
 */

function rotateX$2(out, a, b, rad) {
  var p = [],
      r = []; //Translate point to the origin

  p[0] = a[0] - b[0];
  p[1] = a[1] - b[1];
  p[2] = a[2] - b[2]; //perform rotation

  r[0] = p[0];
  r[1] = p[1] * Math.cos(rad) - p[2] * Math.sin(rad);
  r[2] = p[1] * Math.sin(rad) + p[2] * Math.cos(rad); //translate to correct position

  out[0] = r[0] + b[0];
  out[1] = r[1] + b[1];
  out[2] = r[2] + b[2];
  return out;
}
/**
 * Rotate a 3D vector around the y-axis
 * @param {vec3} out The receiving vec3
 * @param {ReadonlyVec3} a The vec3 point to rotate
 * @param {ReadonlyVec3} b The origin of the rotation
 * @param {Number} rad The angle of rotation in radians
 * @returns {vec3} out
 */

function rotateY$2(out, a, b, rad) {
  var p = [],
      r = []; //Translate point to the origin

  p[0] = a[0] - b[0];
  p[1] = a[1] - b[1];
  p[2] = a[2] - b[2]; //perform rotation

  r[0] = p[2] * Math.sin(rad) + p[0] * Math.cos(rad);
  r[1] = p[1];
  r[2] = p[2] * Math.cos(rad) - p[0] * Math.sin(rad); //translate to correct position

  out[0] = r[0] + b[0];
  out[1] = r[1] + b[1];
  out[2] = r[2] + b[2];
  return out;
}
/**
 * Rotate a 3D vector around the z-axis
 * @param {vec3} out The receiving vec3
 * @param {ReadonlyVec3} a The vec3 point to rotate
 * @param {ReadonlyVec3} b The origin of the rotation
 * @param {Number} rad The angle of rotation in radians
 * @returns {vec3} out
 */

function rotateZ$2(out, a, b, rad) {
  var p = [],
      r = []; //Translate point to the origin

  p[0] = a[0] - b[0];
  p[1] = a[1] - b[1];
  p[2] = a[2] - b[2]; //perform rotation

  r[0] = p[0] * Math.cos(rad) - p[1] * Math.sin(rad);
  r[1] = p[0] * Math.sin(rad) + p[1] * Math.cos(rad);
  r[2] = p[2]; //translate to correct position

  out[0] = r[0] + b[0];
  out[1] = r[1] + b[1];
  out[2] = r[2] + b[2];
  return out;
}
/**
 * Get the angle between two 3D vectors
 * @param {ReadonlyVec3} a The first operand
 * @param {ReadonlyVec3} b The second operand
 * @returns {Number} The angle in radians
 */

function angle$1(a, b) {
  var ax = a[0],
      ay = a[1],
      az = a[2],
      bx = b[0],
      by = b[1],
      bz = b[2],
      mag1 = Math.sqrt(ax * ax + ay * ay + az * az),
      mag2 = Math.sqrt(bx * bx + by * by + bz * bz),
      mag = mag1 * mag2,
      cosine = mag && dot$5(a, b) / mag;
  return Math.acos(Math.min(Math.max(cosine, -1), 1));
}
/**
 * Set the components of a vec3 to zero
 *
 * @param {vec3} out the receiving vector
 * @returns {vec3} out
 */

function zero$2(out) {
  out[0] = 0.0;
  out[1] = 0.0;
  out[2] = 0.0;
  return out;
}
/**
 * Returns a string representation of a vector
 *
 * @param {ReadonlyVec3} a vector to represent as a string
 * @returns {String} string representation of the vector
 */

function str$4(a) {
  return "vec3(" + a[0] + ", " + a[1] + ", " + a[2] + ")";
}
/**
 * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===)
 *
 * @param {ReadonlyVec3} a The first vector.
 * @param {ReadonlyVec3} b The second vector.
 * @returns {Boolean} True if the vectors are equal, false otherwise.
 */

function exactEquals$4(a, b) {
  return a[0] === b[0] && a[1] === b[1] && a[2] === b[2];
}
/**
 * Returns whether or not the vectors have approximately the same elements in the same position.
 *
 * @param {ReadonlyVec3} a The first vector.
 * @param {ReadonlyVec3} b The second vector.
 * @returns {Boolean} True if the vectors are equal, false otherwise.
 */

function equals$5(a, b) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2];
  var b0 = b[0],
      b1 = b[1],
      b2 = b[2];
  return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2));
}
/**
 * Alias for {@link vec3.subtract}
 * @function
 */

var sub$2 = subtract$2;
/**
 * Alias for {@link vec3.multiply}
 * @function
 */

var mul$4 = multiply$4;
/**
 * Alias for {@link vec3.divide}
 * @function
 */

var div$2 = divide$2;
/**
 * Alias for {@link vec3.distance}
 * @function
 */

var dist$2 = distance$2;
/**
 * Alias for {@link vec3.squaredDistance}
 * @function
 */

var sqrDist$2 = squaredDistance$2;
/**
 * Alias for {@link vec3.length}
 * @function
 */

var len$4 = length$4;
/**
 * Alias for {@link vec3.squaredLength}
 * @function
 */

var sqrLen$4 = squaredLength$4;
/**
 * Perform some operation over an array of vec3s.
 *
 * @param {Array} a the array of vectors to iterate over
 * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed
 * @param {Number} offset Number of elements to skip at the beginning of the array
 * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array
 * @param {Function} fn Function to call for each vector in the array
 * @param {Object} [arg] additional argument to pass to fn
 * @returns {Array} a
 * @function
 */

var forEach$2 = function () {
  var vec = create$4();
  return function (a, stride, offset, count, fn, arg) {
    var i, l;

    if (!stride) {
      stride = 3;
    }

    if (!offset) {
      offset = 0;
    }

    if (count) {
      l = Math.min(count * stride + offset, a.length);
    } else {
      l = a.length;
    }

    for (i = offset; i < l; i += stride) {
      vec[0] = a[i];
      vec[1] = a[i + 1];
      vec[2] = a[i + 2];
      fn(vec, vec, arg);
      a[i] = vec[0];
      a[i + 1] = vec[1];
      a[i + 2] = vec[2];
    }

    return a;
  };
}();

var vec3 = /*#__PURE__*/Object.freeze({
__proto__: null,
add: add$4,
angle: angle$1,
bezier: bezier,
ceil: ceil$2,
clone: clone$4,
copy: copy$4,
create: create$4,
cross: cross$2,
dist: dist$2,
distance: distance$2,
div: div$2,
divide: divide$2,
dot: dot$5,
equals: equals$5,
exactEquals: exactEquals$4,
floor: floor$2,
forEach: forEach$2,
fromValues: fromValues$4,
hermite: hermite,
inverse: inverse$2,
len: len$4,
length: length$4,
lerp: lerp$4,
max: max$2,
min: min$2,
mul: mul$4,
multiply: multiply$4,
negate: negate$2,
normalize: normalize$4,
random: random$3,
rotateX: rotateX$2,
rotateY: rotateY$2,
rotateZ: rotateZ$2,
round: round$2,
scale: scale$4,
scaleAndAdd: scaleAndAdd$2,
set: set$4,
sqrDist: sqrDist$2,
sqrLen: sqrLen$4,
squaredDistance: squaredDistance$2,
squaredLength: squaredLength$4,
str: str$4,
sub: sub$2,
subtract: subtract$2,
transformMat3: transformMat3$1,
transformMat4: transformMat4$2,
transformQuat: transformQuat$1,
zero: zero$2
});

/**
 * 4 Dimensional Vector
 * @module vec4
 */

/**
 * Creates a new, empty vec4
 *
 * @returns {vec4} a new 4D vector
 */

function create$3() {
  var out = new ARRAY_TYPE(4);

  if (ARRAY_TYPE != Float32Array) {
    out[0] = 0;
    out[1] = 0;
    out[2] = 0;
    out[3] = 0;
  }

  return out;
}
/**
 * Creates a new vec4 initialized with values from an existing vector
 *
 * @param {ReadonlyVec4} a vector to clone
 * @returns {vec4} a new 4D vector
 */

function clone$3(a) {
  var out = new ARRAY_TYPE(4);
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[3];
  return out;
}
/**
 * Creates a new vec4 initialized with the given values
 *
 * @param {Number} x X component
 * @param {Number} y Y component
 * @param {Number} z Z component
 * @param {Number} w W component
 * @returns {vec4} a new 4D vector
 */

function fromValues$3(x, y, z, w) {
  var out = new ARRAY_TYPE(4);
  out[0] = x;
  out[1] = y;
  out[2] = z;
  out[3] = w;
  return out;
}
/**
 * Copy the values from one vec4 to another
 *
 * @param {vec4} out the receiving vector
 * @param {ReadonlyVec4} a the source vector
 * @returns {vec4} out
 */

function copy$3(out, a) {
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[3];
  return out;
}
/**
 * Set the components of a vec4 to the given values
 *
 * @param {vec4} out the receiving vector
 * @param {Number} x X component
 * @param {Number} y Y component
 * @param {Number} z Z component
 * @param {Number} w W component
 * @returns {vec4} out
 */

function set$3(out, x, y, z, w) {
  out[0] = x;
  out[1] = y;
  out[2] = z;
  out[3] = w;
  return out;
}
/**
 * Adds two vec4's
 *
 * @param {vec4} out the receiving vector
 * @param {ReadonlyVec4} a the first operand
 * @param {ReadonlyVec4} b the second operand
 * @returns {vec4} out
 */

function add$3(out, a, b) {
  out[0] = a[0] + b[0];
  out[1] = a[1] + b[1];
  out[2] = a[2] + b[2];
  out[3] = a[3] + b[3];
  return out;
}
/**
 * Subtracts vector b from vector a
 *
 * @param {vec4} out the receiving vector
 * @param {ReadonlyVec4} a the first operand
 * @param {ReadonlyVec4} b the second operand
 * @returns {vec4} out
 */

function subtract$1(out, a, b) {
  out[0] = a[0] - b[0];
  out[1] = a[1] - b[1];
  out[2] = a[2] - b[2];
  out[3] = a[3] - b[3];
  return out;
}
/**
 * Multiplies two vec4's
 *
 * @param {vec4} out the receiving vector
 * @param {ReadonlyVec4} a the first operand
 * @param {ReadonlyVec4} b the second operand
 * @returns {vec4} out
 */

function multiply$3(out, a, b) {
  out[0] = a[0] * b[0];
  out[1] = a[1] * b[1];
  out[2] = a[2] * b[2];
  out[3] = a[3] * b[3];
  return out;
}
/**
 * Divides two vec4's
 *
 * @param {vec4} out the receiving vector
 * @param {ReadonlyVec4} a the first operand
 * @param {ReadonlyVec4} b the second operand
 * @returns {vec4} out
 */

function divide$1(out, a, b) {
  out[0] = a[0] / b[0];
  out[1] = a[1] / b[1];
  out[2] = a[2] / b[2];
  out[3] = a[3] / b[3];
  return out;
}
/**
 * Math.ceil the components of a vec4
 *
 * @param {vec4} out the receiving vector
 * @param {ReadonlyVec4} a vector to ceil
 * @returns {vec4} out
 */

function ceil$1(out, a) {
  out[0] = Math.ceil(a[0]);
  out[1] = Math.ceil(a[1]);
  out[2] = Math.ceil(a[2]);
  out[3] = Math.ceil(a[3]);
  return out;
}
/**
 * Math.floor the components of a vec4
 *
 * @param {vec4} out the receiving vector
 * @param {ReadonlyVec4} a vector to floor
 * @returns {vec4} out
 */

function floor$1(out, a) {
  out[0] = Math.floor(a[0]);
  out[1] = Math.floor(a[1]);
  out[2] = Math.floor(a[2]);
  out[3] = Math.floor(a[3]);
  return out;
}
/**
 * Returns the minimum of two vec4's
 *
 * @param {vec4} out the receiving vector
 * @param {ReadonlyVec4} a the first operand
 * @param {ReadonlyVec4} b the second operand
 * @returns {vec4} out
 */

function min$1(out, a, b) {
  out[0] = Math.min(a[0], b[0]);
  out[1] = Math.min(a[1], b[1]);
  out[2] = Math.min(a[2], b[2]);
  out[3] = Math.min(a[3], b[3]);
  return out;
}
/**
 * Returns the maximum of two vec4's
 *
 * @param {vec4} out the receiving vector
 * @param {ReadonlyVec4} a the first operand
 * @param {ReadonlyVec4} b the second operand
 * @returns {vec4} out
 */

function max$1(out, a, b) {
  out[0] = Math.max(a[0], b[0]);
  out[1] = Math.max(a[1], b[1]);
  out[2] = Math.max(a[2], b[2]);
  out[3] = Math.max(a[3], b[3]);
  return out;
}
/**
 * Math.round the components of a vec4
 *
 * @param {vec4} out the receiving vector
 * @param {ReadonlyVec4} a vector to round
 * @returns {vec4} out
 */

function round$1(out, a) {
  out[0] = Math.round(a[0]);
  out[1] = Math.round(a[1]);
  out[2] = Math.round(a[2]);
  out[3] = Math.round(a[3]);
  return out;
}
/**
 * Scales a vec4 by a scalar number
 *
 * @param {vec4} out the receiving vector
 * @param {ReadonlyVec4} a the vector to scale
 * @param {Number} b amount to scale the vector by
 * @returns {vec4} out
 */

function scale$3(out, a, b) {
  out[0] = a[0] * b;
  out[1] = a[1] * b;
  out[2] = a[2] * b;
  out[3] = a[3] * b;
  return out;
}
/**
 * Adds two vec4's after scaling the second operand by a scalar value
 *
 * @param {vec4} out the receiving vector
 * @param {ReadonlyVec4} a the first operand
 * @param {ReadonlyVec4} b the second operand
 * @param {Number} scale the amount to scale b by before adding
 * @returns {vec4} out
 */

function scaleAndAdd$1(out, a, b, scale) {
  out[0] = a[0] + b[0] * scale;
  out[1] = a[1] + b[1] * scale;
  out[2] = a[2] + b[2] * scale;
  out[3] = a[3] + b[3] * scale;
  return out;
}
/**
 * Calculates the euclidian distance between two vec4's
 *
 * @param {ReadonlyVec4} a the first operand
 * @param {ReadonlyVec4} b the second operand
 * @returns {Number} distance between a and b
 */

function distance$1(a, b) {
  var x = b[0] - a[0];
  var y = b[1] - a[1];
  var z = b[2] - a[2];
  var w = b[3] - a[3];
  return Math.hypot(x, y, z, w);
}
/**
 * Calculates the squared euclidian distance between two vec4's
 *
 * @param {ReadonlyVec4} a the first operand
 * @param {ReadonlyVec4} b the second operand
 * @returns {Number} squared distance between a and b
 */

function squaredDistance$1(a, b) {
  var x = b[0] - a[0];
  var y = b[1] - a[1];
  var z = b[2] - a[2];
  var w = b[3] - a[3];
  return x * x + y * y + z * z + w * w;
}
/**
 * Calculates the length of a vec4
 *
 * @param {ReadonlyVec4} a vector to calculate length of
 * @returns {Number} length of a
 */

function length$3(a) {
  var x = a[0];
  var y = a[1];
  var z = a[2];
  var w = a[3];
  return Math.hypot(x, y, z, w);
}
/**
 * Calculates the squared length of a vec4
 *
 * @param {ReadonlyVec4} a vector to calculate squared length of
 * @returns {Number} squared length of a
 */

function squaredLength$3(a) {
  var x = a[0];
  var y = a[1];
  var z = a[2];
  var w = a[3];
  return x * x + y * y + z * z + w * w;
}
/**
 * Negates the components of a vec4
 *
 * @param {vec4} out the receiving vector
 * @param {ReadonlyVec4} a vector to negate
 * @returns {vec4} out
 */

function negate$1(out, a) {
  out[0] = -a[0];
  out[1] = -a[1];
  out[2] = -a[2];
  out[3] = -a[3];
  return out;
}
/**
 * Returns the inverse of the components of a vec4
 *
 * @param {vec4} out the receiving vector
 * @param {ReadonlyVec4} a vector to invert
 * @returns {vec4} out
 */

function inverse$1(out, a) {
  out[0] = 1.0 / a[0];
  out[1] = 1.0 / a[1];
  out[2] = 1.0 / a[2];
  out[3] = 1.0 / a[3];
  return out;
}
/**
 * Normalize a vec4
 *
 * @param {vec4} out the receiving vector
 * @param {ReadonlyVec4} a vector to normalize
 * @returns {vec4} out
 */

function normalize$3(out, a) {
  var x = a[0];
  var y = a[1];
  var z = a[2];
  var w = a[3];
  var len = x * x + y * y + z * z + w * w;

  if (len > 0) {
    len = 1 / Math.sqrt(len);
  }

  out[0] = x * len;
  out[1] = y * len;
  out[2] = z * len;
  out[3] = w * len;
  return out;
}
/**
 * Calculates the dot product of two vec4's
 *
 * @param {ReadonlyVec4} a the first operand
 * @param {ReadonlyVec4} b the second operand
 * @returns {Number} dot product of a and b
 */

function dot$4(a, b) {
  return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
}
/**
 * Returns the cross-product of three vectors in a 4-dimensional space
 *
 * @param {ReadonlyVec4} result the receiving vector
 * @param {ReadonlyVec4} U the first vector
 * @param {ReadonlyVec4} V the second vector
 * @param {ReadonlyVec4} W the third vector
 * @returns {vec4} result
 */

function cross$1(out, u, v, w) {
  var A = v[0] * w[1] - v[1] * w[0],
      B = v[0] * w[2] - v[2] * w[0],
      C = v[0] * w[3] - v[3] * w[0],
      D = v[1] * w[2] - v[2] * w[1],
      E = v[1] * w[3] - v[3] * w[1],
      F = v[2] * w[3] - v[3] * w[2];
  var G = u[0];
  var H = u[1];
  var I = u[2];
  var J = u[3];
  out[0] = H * F - I * E + J * D;
  out[1] = -(G * F) + I * C - J * B;
  out[2] = G * E - H * C + J * A;
  out[3] = -(G * D) + H * B - I * A;
  return out;
}
/**
 * Performs a linear interpolation between two vec4's
 *
 * @param {vec4} out the receiving vector
 * @param {ReadonlyVec4} a the first operand
 * @param {ReadonlyVec4} b the second operand
 * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
 * @returns {vec4} out
 */

function lerp$3(out, a, b, t) {
  var ax = a[0];
  var ay = a[1];
  var az = a[2];
  var aw = a[3];
  out[0] = ax + t * (b[0] - ax);
  out[1] = ay + t * (b[1] - ay);
  out[2] = az + t * (b[2] - az);
  out[3] = aw + t * (b[3] - aw);
  return out;
}
/**
 * Generates a random vector with the given scale
 *
 * @param {vec4} out the receiving vector
 * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
 * @returns {vec4} out
 */

function random$2(out, scale) {
  scale = scale || 1.0; // Marsaglia, George. Choosing a Point from the Surface of a
  // Sphere. Ann. Math. Statist. 43 (1972), no. 2, 645--646.
  // http://projecteuclid.org/euclid.aoms/1177692644;

  var v1, v2, v3, v4;
  var s1, s2;

  do {
    v1 = RANDOM() * 2 - 1;
    v2 = RANDOM() * 2 - 1;
    s1 = v1 * v1 + v2 * v2;
  } while (s1 >= 1);

  do {
    v3 = RANDOM() * 2 - 1;
    v4 = RANDOM() * 2 - 1;
    s2 = v3 * v3 + v4 * v4;
  } while (s2 >= 1);

  var d = Math.sqrt((1 - s1) / s2);
  out[0] = scale * v1;
  out[1] = scale * v2;
  out[2] = scale * v3 * d;
  out[3] = scale * v4 * d;
  return out;
}
/**
 * Transforms the vec4 with a mat4.
 *
 * @param {vec4} out the receiving vector
 * @param {ReadonlyVec4} a the vector to transform
 * @param {ReadonlyMat4} m matrix to transform with
 * @returns {vec4} out
 */

function transformMat4$1(out, a, m) {
  var x = a[0],
      y = a[1],
      z = a[2],
      w = a[3];
  out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w;
  out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w;
  out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w;
  out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w;
  return out;
}
/**
 * Transforms the vec4 with a quat
 *
 * @param {vec4} out the receiving vector
 * @param {ReadonlyVec4} a the vector to transform
 * @param {ReadonlyQuat} q quaternion to transform with
 * @returns {vec4} out
 */

function transformQuat(out, a, q) {
  var x = a[0],
      y = a[1],
      z = a[2];
  var qx = q[0],
      qy = q[1],
      qz = q[2],
      qw = q[3]; // calculate quat * vec

  var ix = qw * x + qy * z - qz * y;
  var iy = qw * y + qz * x - qx * z;
  var iz = qw * z + qx * y - qy * x;
  var iw = -qx * x - qy * y - qz * z; // calculate result * inverse quat

  out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;
  out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;
  out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;
  out[3] = a[3];
  return out;
}
/**
 * Set the components of a vec4 to zero
 *
 * @param {vec4} out the receiving vector
 * @returns {vec4} out
 */

function zero$1(out) {
  out[0] = 0.0;
  out[1] = 0.0;
  out[2] = 0.0;
  out[3] = 0.0;
  return out;
}
/**
 * Returns a string representation of a vector
 *
 * @param {ReadonlyVec4} a vector to represent as a string
 * @returns {String} string representation of the vector
 */

function str$3(a) {
  return "vec4(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")";
}
/**
 * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===)
 *
 * @param {ReadonlyVec4} a The first vector.
 * @param {ReadonlyVec4} b The second vector.
 * @returns {Boolean} True if the vectors are equal, false otherwise.
 */

function exactEquals$3(a, b) {
  return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3];
}
/**
 * Returns whether or not the vectors have approximately the same elements in the same position.
 *
 * @param {ReadonlyVec4} a The first vector.
 * @param {ReadonlyVec4} b The second vector.
 * @returns {Boolean} True if the vectors are equal, false otherwise.
 */

function equals$4(a, b) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3];
  var b0 = b[0],
      b1 = b[1],
      b2 = b[2],
      b3 = b[3];
  return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3));
}
/**
 * Alias for {@link vec4.subtract}
 * @function
 */

var sub$1 = subtract$1;
/**
 * Alias for {@link vec4.multiply}
 * @function
 */

var mul$3 = multiply$3;
/**
 * Alias for {@link vec4.divide}
 * @function
 */

var div$1 = divide$1;
/**
 * Alias for {@link vec4.distance}
 * @function
 */

var dist$1 = distance$1;
/**
 * Alias for {@link vec4.squaredDistance}
 * @function
 */

var sqrDist$1 = squaredDistance$1;
/**
 * Alias for {@link vec4.length}
 * @function
 */

var len$3 = length$3;
/**
 * Alias for {@link vec4.squaredLength}
 * @function
 */

var sqrLen$3 = squaredLength$3;
/**
 * Perform some operation over an array of vec4s.
 *
 * @param {Array} a the array of vectors to iterate over
 * @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed
 * @param {Number} offset Number of elements to skip at the beginning of the array
 * @param {Number} count Number of vec4s to iterate over. If 0 iterates over entire array
 * @param {Function} fn Function to call for each vector in the array
 * @param {Object} [arg] additional argument to pass to fn
 * @returns {Array} a
 * @function
 */

var forEach$1 = function () {
  var vec = create$3();
  return function (a, stride, offset, count, fn, arg) {
    var i, l;

    if (!stride) {
      stride = 4;
    }

    if (!offset) {
      offset = 0;
    }

    if (count) {
      l = Math.min(count * stride + offset, a.length);
    } else {
      l = a.length;
    }

    for (i = offset; i < l; i += stride) {
      vec[0] = a[i];
      vec[1] = a[i + 1];
      vec[2] = a[i + 2];
      vec[3] = a[i + 3];
      fn(vec, vec, arg);
      a[i] = vec[0];
      a[i + 1] = vec[1];
      a[i + 2] = vec[2];
      a[i + 3] = vec[3];
    }

    return a;
  };
}();

var vec4 = /*#__PURE__*/Object.freeze({
__proto__: null,
add: add$3,
ceil: ceil$1,
clone: clone$3,
copy: copy$3,
create: create$3,
cross: cross$1,
dist: dist$1,
distance: distance$1,
div: div$1,
divide: divide$1,
dot: dot$4,
equals: equals$4,
exactEquals: exactEquals$3,
floor: floor$1,
forEach: forEach$1,
fromValues: fromValues$3,
inverse: inverse$1,
len: len$3,
length: length$3,
lerp: lerp$3,
max: max$1,
min: min$1,
mul: mul$3,
multiply: multiply$3,
negate: negate$1,
normalize: normalize$3,
random: random$2,
round: round$1,
scale: scale$3,
scaleAndAdd: scaleAndAdd$1,
set: set$3,
sqrDist: sqrDist$1,
sqrLen: sqrLen$3,
squaredDistance: squaredDistance$1,
squaredLength: squaredLength$3,
str: str$3,
sub: sub$1,
subtract: subtract$1,
transformMat4: transformMat4$1,
transformQuat: transformQuat,
zero: zero$1
});

/**
 * Quaternion
 * @module quat
 */

/**
 * Creates a new identity quat
 *
 * @returns {quat} a new quaternion
 */

function create$2() {
  var out = new ARRAY_TYPE(4);

  if (ARRAY_TYPE != Float32Array) {
    out[0] = 0;
    out[1] = 0;
    out[2] = 0;
  }

  out[3] = 1;
  return out;
}
/**
 * Set a quat to the identity quaternion
 *
 * @param {quat} out the receiving quaternion
 * @returns {quat} out
 */

function identity$2(out) {
  out[0] = 0;
  out[1] = 0;
  out[2] = 0;
  out[3] = 1;
  return out;
}
/**
 * Sets a quat from the given angle and rotation axis,
 * then returns it.
 *
 * @param {quat} out the receiving quaternion
 * @param {ReadonlyVec3} axis the axis around which to rotate
 * @param {Number} rad the angle in radians
 * @returns {quat} out
 **/

function setAxisAngle(out, axis, rad) {
  rad = rad * 0.5;
  var s = Math.sin(rad);
  out[0] = s * axis[0];
  out[1] = s * axis[1];
  out[2] = s * axis[2];
  out[3] = Math.cos(rad);
  return out;
}
/**
 * Gets the rotation axis and angle for a given
 *  quaternion. If a quaternion is created with
 *  setAxisAngle, this method will return the same
 *  values as providied in the original parameter list
 *  OR functionally equivalent values.
 * Example: The quaternion formed by axis [0, 0, 1] and
 *  angle -90 is the same as the quaternion formed by
 *  [0, 0, 1] and 270. This method favors the latter.
 * @param  {vec3} out_axis  Vector receiving the axis of rotation
 * @param  {ReadonlyQuat} q     Quaternion to be decomposed
 * @return {Number}     Angle, in radians, of the rotation
 */

function getAxisAngle(out_axis, q) {
  var rad = Math.acos(q[3]) * 2.0;
  var s = Math.sin(rad / 2.0);

  if (s > EPSILON) {
    out_axis[0] = q[0] / s;
    out_axis[1] = q[1] / s;
    out_axis[2] = q[2] / s;
  } else {
    // If s is zero, return any axis (no rotation - axis does not matter)
    out_axis[0] = 1;
    out_axis[1] = 0;
    out_axis[2] = 0;
  }

  return rad;
}
/**
 * Gets the angular distance between two unit quaternions
 *
 * @param  {ReadonlyQuat} a     Origin unit quaternion
 * @param  {ReadonlyQuat} b     Destination unit quaternion
 * @return {Number}     Angle, in radians, between the two quaternions
 */

function getAngle(a, b) {
  var dotproduct = dot$3(a, b);
  return Math.acos(2 * dotproduct * dotproduct - 1);
}
/**
 * Multiplies two quat's
 *
 * @param {quat} out the receiving quaternion
 * @param {ReadonlyQuat} a the first operand
 * @param {ReadonlyQuat} b the second operand
 * @returns {quat} out
 */

function multiply$2(out, a, b) {
  var ax = a[0],
      ay = a[1],
      az = a[2],
      aw = a[3];
  var bx = b[0],
      by = b[1],
      bz = b[2],
      bw = b[3];
  out[0] = ax * bw + aw * bx + ay * bz - az * by;
  out[1] = ay * bw + aw * by + az * bx - ax * bz;
  out[2] = az * bw + aw * bz + ax * by - ay * bx;
  out[3] = aw * bw - ax * bx - ay * by - az * bz;
  return out;
}
/**
 * Rotates a quaternion by the given angle about the X axis
 *
 * @param {quat} out quat receiving operation result
 * @param {ReadonlyQuat} a quat to rotate
 * @param {number} rad angle (in radians) to rotate
 * @returns {quat} out
 */

function rotateX$1(out, a, rad) {
  rad *= 0.5;
  var ax = a[0],
      ay = a[1],
      az = a[2],
      aw = a[3];
  var bx = Math.sin(rad),
      bw = Math.cos(rad);
  out[0] = ax * bw + aw * bx;
  out[1] = ay * bw + az * bx;
  out[2] = az * bw - ay * bx;
  out[3] = aw * bw - ax * bx;
  return out;
}
/**
 * Rotates a quaternion by the given angle about the Y axis
 *
 * @param {quat} out quat receiving operation result
 * @param {ReadonlyQuat} a quat to rotate
 * @param {number} rad angle (in radians) to rotate
 * @returns {quat} out
 */

function rotateY$1(out, a, rad) {
  rad *= 0.5;
  var ax = a[0],
      ay = a[1],
      az = a[2],
      aw = a[3];
  var by = Math.sin(rad),
      bw = Math.cos(rad);
  out[0] = ax * bw - az * by;
  out[1] = ay * bw + aw * by;
  out[2] = az * bw + ax * by;
  out[3] = aw * bw - ay * by;
  return out;
}
/**
 * Rotates a quaternion by the given angle about the Z axis
 *
 * @param {quat} out quat receiving operation result
 * @param {ReadonlyQuat} a quat to rotate
 * @param {number} rad angle (in radians) to rotate
 * @returns {quat} out
 */

function rotateZ$1(out, a, rad) {
  rad *= 0.5;
  var ax = a[0],
      ay = a[1],
      az = a[2],
      aw = a[3];
  var bz = Math.sin(rad),
      bw = Math.cos(rad);
  out[0] = ax * bw + ay * bz;
  out[1] = ay * bw - ax * bz;
  out[2] = az * bw + aw * bz;
  out[3] = aw * bw - az * bz;
  return out;
}
/**
 * Calculates the W component of a quat from the X, Y, and Z components.
 * Assumes that quaternion is 1 unit in length.
 * Any existing W component will be ignored.
 *
 * @param {quat} out the receiving quaternion
 * @param {ReadonlyQuat} a quat to calculate W component of
 * @returns {quat} out
 */

function calculateW(out, a) {
  var x = a[0],
      y = a[1],
      z = a[2];
  out[0] = x;
  out[1] = y;
  out[2] = z;
  out[3] = Math.sqrt(Math.abs(1.0 - x * x - y * y - z * z));
  return out;
}
/**
 * Calculate the exponential of a unit quaternion.
 *
 * @param {quat} out the receiving quaternion
 * @param {ReadonlyQuat} a quat to calculate the exponential of
 * @returns {quat} out
 */

function exp(out, a) {
  var x = a[0],
      y = a[1],
      z = a[2],
      w = a[3];
  var r = Math.sqrt(x * x + y * y + z * z);
  var et = Math.exp(w);
  var s = r > 0 ? et * Math.sin(r) / r : 0;
  out[0] = x * s;
  out[1] = y * s;
  out[2] = z * s;
  out[3] = et * Math.cos(r);
  return out;
}
/**
 * Calculate the natural logarithm of a unit quaternion.
 *
 * @param {quat} out the receiving quaternion
 * @param {ReadonlyQuat} a quat to calculate the exponential of
 * @returns {quat} out
 */

function ln(out, a) {
  var x = a[0],
      y = a[1],
      z = a[2],
      w = a[3];
  var r = Math.sqrt(x * x + y * y + z * z);
  var t = r > 0 ? Math.atan2(r, w) / r : 0;
  out[0] = x * t;
  out[1] = y * t;
  out[2] = z * t;
  out[3] = 0.5 * Math.log(x * x + y * y + z * z + w * w);
  return out;
}
/**
 * Calculate the scalar power of a unit quaternion.
 *
 * @param {quat} out the receiving quaternion
 * @param {ReadonlyQuat} a quat to calculate the exponential of
 * @param {Number} b amount to scale the quaternion by
 * @returns {quat} out
 */

function pow(out, a, b) {
  ln(out, a);
  scale$2(out, out, b);
  exp(out, out);
  return out;
}
/**
 * Performs a spherical linear interpolation between two quat
 *
 * @param {quat} out the receiving quaternion
 * @param {ReadonlyQuat} a the first operand
 * @param {ReadonlyQuat} b the second operand
 * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
 * @returns {quat} out
 */

function slerp$1(out, a, b, t) {
  // benchmarks:
  //    http://jsperf.com/quaternion-slerp-implementations
  var ax = a[0],
      ay = a[1],
      az = a[2],
      aw = a[3];
  var bx = b[0],
      by = b[1],
      bz = b[2],
      bw = b[3];
  var omega, cosom, sinom, scale0, scale1; // calc cosine

  cosom = ax * bx + ay * by + az * bz + aw * bw; // adjust signs (if necessary)

  if (cosom < 0.0) {
    cosom = -cosom;
    bx = -bx;
    by = -by;
    bz = -bz;
    bw = -bw;
  } // calculate coefficients


  if (1.0 - cosom > EPSILON) {
    // standard case (slerp)
    omega = Math.acos(cosom);
    sinom = Math.sin(omega);
    scale0 = Math.sin((1.0 - t) * omega) / sinom;
    scale1 = Math.sin(t * omega) / sinom;
  } else {
    // "from" and "to" quaternions are very close
    //  ... so we can do a linear interpolation
    scale0 = 1.0 - t;
    scale1 = t;
  } // calculate final values


  out[0] = scale0 * ax + scale1 * bx;
  out[1] = scale0 * ay + scale1 * by;
  out[2] = scale0 * az + scale1 * bz;
  out[3] = scale0 * aw + scale1 * bw;
  return out;
}
/**
 * Generates a random unit quaternion
 *
 * @param {quat} out the receiving quaternion
 * @returns {quat} out
 */

function random$1(out) {
  // Implementation of http://planning.cs.uiuc.edu/node198.html
  // TODO: Calling random 3 times is probably not the fastest solution
  var u1 = RANDOM();
  var u2 = RANDOM();
  var u3 = RANDOM();
  var sqrt1MinusU1 = Math.sqrt(1 - u1);
  var sqrtU1 = Math.sqrt(u1);
  out[0] = sqrt1MinusU1 * Math.sin(2.0 * Math.PI * u2);
  out[1] = sqrt1MinusU1 * Math.cos(2.0 * Math.PI * u2);
  out[2] = sqrtU1 * Math.sin(2.0 * Math.PI * u3);
  out[3] = sqrtU1 * Math.cos(2.0 * Math.PI * u3);
  return out;
}
/**
 * Calculates the inverse of a quat
 *
 * @param {quat} out the receiving quaternion
 * @param {ReadonlyQuat} a quat to calculate inverse of
 * @returns {quat} out
 */

function invert$1(out, a) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3];
  var dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3;
  var invDot = dot ? 1.0 / dot : 0; // TODO: Would be faster to return [0,0,0,0] immediately if dot == 0

  out[0] = -a0 * invDot;
  out[1] = -a1 * invDot;
  out[2] = -a2 * invDot;
  out[3] = a3 * invDot;
  return out;
}
/**
 * Calculates the conjugate of a quat
 * If the quaternion is normalized, this function is faster than quat.inverse and produces the same result.
 *
 * @param {quat} out the receiving quaternion
 * @param {ReadonlyQuat} a quat to calculate conjugate of
 * @returns {quat} out
 */

function conjugate$1(out, a) {
  out[0] = -a[0];
  out[1] = -a[1];
  out[2] = -a[2];
  out[3] = a[3];
  return out;
}
/**
 * Creates a quaternion from the given 3x3 rotation matrix.
 *
 * NOTE: The resultant quaternion is not normalized, so you should be sure
 * to renormalize the quaternion yourself where necessary.
 *
 * @param {quat} out the receiving quaternion
 * @param {ReadonlyMat3} m rotation matrix
 * @returns {quat} out
 * @function
 */

function fromMat3(out, m) {
  // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
  // article "Quaternion Calculus and Fast Animation".
  var fTrace = m[0] + m[4] + m[8];
  var fRoot;

  if (fTrace > 0.0) {
    // |w| > 1/2, may as well choose w > 1/2
    fRoot = Math.sqrt(fTrace + 1.0); // 2w

    out[3] = 0.5 * fRoot;
    fRoot = 0.5 / fRoot; // 1/(4w)

    out[0] = (m[5] - m[7]) * fRoot;
    out[1] = (m[6] - m[2]) * fRoot;
    out[2] = (m[1] - m[3]) * fRoot;
  } else {
    // |w| <= 1/2
    var i = 0;
    if (m[4] > m[0]) i = 1;
    if (m[8] > m[i * 3 + i]) i = 2;
    var j = (i + 1) % 3;
    var k = (i + 2) % 3;
    fRoot = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1.0);
    out[i] = 0.5 * fRoot;
    fRoot = 0.5 / fRoot;
    out[3] = (m[j * 3 + k] - m[k * 3 + j]) * fRoot;
    out[j] = (m[j * 3 + i] + m[i * 3 + j]) * fRoot;
    out[k] = (m[k * 3 + i] + m[i * 3 + k]) * fRoot;
  }

  return out;
}
/**
 * Creates a quaternion from the given euler angle x, y, z.
 *
 * @param {quat} out the receiving quaternion
 * @param {x} Angle to rotate around X axis in degrees.
 * @param {y} Angle to rotate around Y axis in degrees.
 * @param {z} Angle to rotate around Z axis in degrees.
 * @returns {quat} out
 * @function
 */

function fromEuler(out, x, y, z) {
  var halfToRad = 0.5 * Math.PI / 180.0;
  x *= halfToRad;
  y *= halfToRad;
  z *= halfToRad;
  var sx = Math.sin(x);
  var cx = Math.cos(x);
  var sy = Math.sin(y);
  var cy = Math.cos(y);
  var sz = Math.sin(z);
  var cz = Math.cos(z);
  out[0] = sx * cy * cz - cx * sy * sz;
  out[1] = cx * sy * cz + sx * cy * sz;
  out[2] = cx * cy * sz - sx * sy * cz;
  out[3] = cx * cy * cz + sx * sy * sz;
  return out;
}
/**
 * Returns a string representation of a quatenion
 *
 * @param {ReadonlyQuat} a vector to represent as a string
 * @returns {String} string representation of the vector
 */

function str$2(a) {
  return "quat(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")";
}
/**
 * Creates a new quat initialized with values from an existing quaternion
 *
 * @param {ReadonlyQuat} a quaternion to clone
 * @returns {quat} a new quaternion
 * @function
 */

var clone$2 = clone$3;
/**
 * Creates a new quat initialized with the given values
 *
 * @param {Number} x X component
 * @param {Number} y Y component
 * @param {Number} z Z component
 * @param {Number} w W component
 * @returns {quat} a new quaternion
 * @function
 */

var fromValues$2 = fromValues$3;
/**
 * Copy the values from one quat to another
 *
 * @param {quat} out the receiving quaternion
 * @param {ReadonlyQuat} a the source quaternion
 * @returns {quat} out
 * @function
 */

var copy$2 = copy$3;
/**
 * Set the components of a quat to the given values
 *
 * @param {quat} out the receiving quaternion
 * @param {Number} x X component
 * @param {Number} y Y component
 * @param {Number} z Z component
 * @param {Number} w W component
 * @returns {quat} out
 * @function
 */

var set$2 = set$3;
/**
 * Adds two quat's
 *
 * @param {quat} out the receiving quaternion
 * @param {ReadonlyQuat} a the first operand
 * @param {ReadonlyQuat} b the second operand
 * @returns {quat} out
 * @function
 */

var add$2 = add$3;
/**
 * Alias for {@link quat.multiply}
 * @function
 */

var mul$2 = multiply$2;
/**
 * Scales a quat by a scalar number
 *
 * @param {quat} out the receiving vector
 * @param {ReadonlyQuat} a the vector to scale
 * @param {Number} b amount to scale the vector by
 * @returns {quat} out
 * @function
 */

var scale$2 = scale$3;
/**
 * Calculates the dot product of two quat's
 *
 * @param {ReadonlyQuat} a the first operand
 * @param {ReadonlyQuat} b the second operand
 * @returns {Number} dot product of a and b
 * @function
 */

var dot$3 = dot$4;
/**
 * Performs a linear interpolation between two quat's
 *
 * @param {quat} out the receiving quaternion
 * @param {ReadonlyQuat} a the first operand
 * @param {ReadonlyQuat} b the second operand
 * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
 * @returns {quat} out
 * @function
 */

var lerp$2 = lerp$3;
/**
 * Calculates the length of a quat
 *
 * @param {ReadonlyQuat} a vector to calculate length of
 * @returns {Number} length of a
 */

var length$2 = length$3;
/**
 * Alias for {@link quat.length}
 * @function
 */

var len$2 = length$2;
/**
 * Calculates the squared length of a quat
 *
 * @param {ReadonlyQuat} a vector to calculate squared length of
 * @returns {Number} squared length of a
 * @function
 */

var squaredLength$2 = squaredLength$3;
/**
 * Alias for {@link quat.squaredLength}
 * @function
 */

var sqrLen$2 = squaredLength$2;
/**
 * Normalize a quat
 *
 * @param {quat} out the receiving quaternion
 * @param {ReadonlyQuat} a quaternion to normalize
 * @returns {quat} out
 * @function
 */

var normalize$2 = normalize$3;
/**
 * Returns whether or not the quaternions have exactly the same elements in the same position (when compared with ===)
 *
 * @param {ReadonlyQuat} a The first quaternion.
 * @param {ReadonlyQuat} b The second quaternion.
 * @returns {Boolean} True if the vectors are equal, false otherwise.
 */

var exactEquals$2 = exactEquals$3;
/**
 * Returns whether or not the quaternions have approximately the same elements in the same position.
 *
 * @param {ReadonlyQuat} a The first vector.
 * @param {ReadonlyQuat} b The second vector.
 * @returns {Boolean} True if the vectors are equal, false otherwise.
 */

var equals$3 = equals$4;
/**
 * Sets a quaternion to represent the shortest rotation from one
 * vector to another.
 *
 * Both vectors are assumed to be unit length.
 *
 * @param {quat} out the receiving quaternion.
 * @param {ReadonlyVec3} a the initial vector
 * @param {ReadonlyVec3} b the destination vector
 * @returns {quat} out
 */

var rotationTo = function () {
  var tmpvec3 = create$4();
  var xUnitVec3 = fromValues$4(1, 0, 0);
  var yUnitVec3 = fromValues$4(0, 1, 0);
  return function (out, a, b) {
    var dot = dot$5(a, b);

    if (dot < -0.999999) {
      cross$2(tmpvec3, xUnitVec3, a);
      if (len$4(tmpvec3) < 0.000001) cross$2(tmpvec3, yUnitVec3, a);
      normalize$4(tmpvec3, tmpvec3);
      setAxisAngle(out, tmpvec3, Math.PI);
      return out;
    } else if (dot > 0.999999) {
      out[0] = 0;
      out[1] = 0;
      out[2] = 0;
      out[3] = 1;
      return out;
    } else {
      cross$2(tmpvec3, a, b);
      out[0] = tmpvec3[0];
      out[1] = tmpvec3[1];
      out[2] = tmpvec3[2];
      out[3] = 1 + dot;
      return normalize$2(out, out);
    }
  };
}();
/**
 * Performs a spherical linear interpolation with two control points
 *
 * @param {quat} out the receiving quaternion
 * @param {ReadonlyQuat} a the first operand
 * @param {ReadonlyQuat} b the second operand
 * @param {ReadonlyQuat} c the third operand
 * @param {ReadonlyQuat} d the fourth operand
 * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
 * @returns {quat} out
 */

var sqlerp = function () {
  var temp1 = create$2();
  var temp2 = create$2();
  return function (out, a, b, c, d, t) {
    slerp$1(temp1, a, d, t);
    slerp$1(temp2, b, c, t);
    slerp$1(out, temp1, temp2, 2 * t * (1 - t));
    return out;
  };
}();
/**
 * Sets the specified quaternion with values corresponding to the given
 * axes. Each axis is a vec3 and is expected to be unit length and
 * perpendicular to all other specified axes.
 *
 * @param {ReadonlyVec3} view  the vector representing the viewing direction
 * @param {ReadonlyVec3} right the vector representing the local "right" direction
 * @param {ReadonlyVec3} up    the vector representing the local "up" direction
 * @returns {quat} out
 */

var setAxes = function () {
  var matr = create$6();
  return function (out, view, right, up) {
    matr[0] = right[0];
    matr[3] = right[1];
    matr[6] = right[2];
    matr[1] = up[0];
    matr[4] = up[1];
    matr[7] = up[2];
    matr[2] = -view[0];
    matr[5] = -view[1];
    matr[8] = -view[2];
    return normalize$2(out, fromMat3(out, matr));
  };
}();

var quat = /*#__PURE__*/Object.freeze({
__proto__: null,
add: add$2,
calculateW: calculateW,
clone: clone$2,
conjugate: conjugate$1,
copy: copy$2,
create: create$2,
dot: dot$3,
equals: equals$3,
exactEquals: exactEquals$2,
exp: exp,
fromEuler: fromEuler,
fromMat3: fromMat3,
fromValues: fromValues$2,
getAngle: getAngle,
getAxisAngle: getAxisAngle,
identity: identity$2,
invert: invert$1,
len: len$2,
length: length$2,
lerp: lerp$2,
ln: ln,
mul: mul$2,
multiply: multiply$2,
normalize: normalize$2,
pow: pow,
random: random$1,
rotateX: rotateX$1,
rotateY: rotateY$1,
rotateZ: rotateZ$1,
rotationTo: rotationTo,
scale: scale$2,
set: set$2,
setAxes: setAxes,
setAxisAngle: setAxisAngle,
slerp: slerp$1,
sqlerp: sqlerp,
sqrLen: sqrLen$2,
squaredLength: squaredLength$2,
str: str$2
});

/**
 * Dual Quaternion<br>
 * Format: [real, dual]<br>
 * Quaternion format: XYZW<br>
 * Make sure to have normalized dual quaternions, otherwise the functions may not work as intended.<br>
 * @module quat2
 */

/**
 * Creates a new identity dual quat
 *
 * @returns {quat2} a new dual quaternion [real -> rotation, dual -> translation]
 */

function create$1() {
  var dq = new ARRAY_TYPE(8);

  if (ARRAY_TYPE != Float32Array) {
    dq[0] = 0;
    dq[1] = 0;
    dq[2] = 0;
    dq[4] = 0;
    dq[5] = 0;
    dq[6] = 0;
    dq[7] = 0;
  }

  dq[3] = 1;
  return dq;
}
/**
 * Creates a new quat initialized with values from an existing quaternion
 *
 * @param {ReadonlyQuat2} a dual quaternion to clone
 * @returns {quat2} new dual quaternion
 * @function
 */

function clone$1(a) {
  var dq = new ARRAY_TYPE(8);
  dq[0] = a[0];
  dq[1] = a[1];
  dq[2] = a[2];
  dq[3] = a[3];
  dq[4] = a[4];
  dq[5] = a[5];
  dq[6] = a[6];
  dq[7] = a[7];
  return dq;
}
/**
 * Creates a new dual quat initialized with the given values
 *
 * @param {Number} x1 X component
 * @param {Number} y1 Y component
 * @param {Number} z1 Z component
 * @param {Number} w1 W component
 * @param {Number} x2 X component
 * @param {Number} y2 Y component
 * @param {Number} z2 Z component
 * @param {Number} w2 W component
 * @returns {quat2} new dual quaternion
 * @function
 */

function fromValues$1(x1, y1, z1, w1, x2, y2, z2, w2) {
  var dq = new ARRAY_TYPE(8);
  dq[0] = x1;
  dq[1] = y1;
  dq[2] = z1;
  dq[3] = w1;
  dq[4] = x2;
  dq[5] = y2;
  dq[6] = z2;
  dq[7] = w2;
  return dq;
}
/**
 * Creates a new dual quat from the given values (quat and translation)
 *
 * @param {Number} x1 X component
 * @param {Number} y1 Y component
 * @param {Number} z1 Z component
 * @param {Number} w1 W component
 * @param {Number} x2 X component (translation)
 * @param {Number} y2 Y component (translation)
 * @param {Number} z2 Z component (translation)
 * @returns {quat2} new dual quaternion
 * @function
 */

function fromRotationTranslationValues(x1, y1, z1, w1, x2, y2, z2) {
  var dq = new ARRAY_TYPE(8);
  dq[0] = x1;
  dq[1] = y1;
  dq[2] = z1;
  dq[3] = w1;
  var ax = x2 * 0.5,
      ay = y2 * 0.5,
      az = z2 * 0.5;
  dq[4] = ax * w1 + ay * z1 - az * y1;
  dq[5] = ay * w1 + az * x1 - ax * z1;
  dq[6] = az * w1 + ax * y1 - ay * x1;
  dq[7] = -ax * x1 - ay * y1 - az * z1;
  return dq;
}
/**
 * Creates a dual quat from a quaternion and a translation
 *
 * @param {ReadonlyQuat2} dual quaternion receiving operation result
 * @param {ReadonlyQuat} q a normalized quaternion
 * @param {ReadonlyVec3} t tranlation vector
 * @returns {quat2} dual quaternion receiving operation result
 * @function
 */

function fromRotationTranslation(out, q, t) {
  var ax = t[0] * 0.5,
      ay = t[1] * 0.5,
      az = t[2] * 0.5,
      bx = q[0],
      by = q[1],
      bz = q[2],
      bw = q[3];
  out[0] = bx;
  out[1] = by;
  out[2] = bz;
  out[3] = bw;
  out[4] = ax * bw + ay * bz - az * by;
  out[5] = ay * bw + az * bx - ax * bz;
  out[6] = az * bw + ax * by - ay * bx;
  out[7] = -ax * bx - ay * by - az * bz;
  return out;
}
/**
 * Creates a dual quat from a translation
 *
 * @param {ReadonlyQuat2} dual quaternion receiving operation result
 * @param {ReadonlyVec3} t translation vector
 * @returns {quat2} dual quaternion receiving operation result
 * @function
 */

function fromTranslation(out, t) {
  out[0] = 0;
  out[1] = 0;
  out[2] = 0;
  out[3] = 1;
  out[4] = t[0] * 0.5;
  out[5] = t[1] * 0.5;
  out[6] = t[2] * 0.5;
  out[7] = 0;
  return out;
}
/**
 * Creates a dual quat from a quaternion
 *
 * @param {ReadonlyQuat2} dual quaternion receiving operation result
 * @param {ReadonlyQuat} q the quaternion
 * @returns {quat2} dual quaternion receiving operation result
 * @function
 */

function fromRotation(out, q) {
  out[0] = q[0];
  out[1] = q[1];
  out[2] = q[2];
  out[3] = q[3];
  out[4] = 0;
  out[5] = 0;
  out[6] = 0;
  out[7] = 0;
  return out;
}
/**
 * Creates a new dual quat from a matrix (4x4)
 *
 * @param {quat2} out the dual quaternion
 * @param {ReadonlyMat4} a the matrix
 * @returns {quat2} dual quat receiving operation result
 * @function
 */

function fromMat4(out, a) {
  //TODO Optimize this
  var outer = create$2();
  getRotation(outer, a);
  var t = new ARRAY_TYPE(3);
  getTranslation$1(t, a);
  fromRotationTranslation(out, outer, t);
  return out;
}
/**
 * Copy the values from one dual quat to another
 *
 * @param {quat2} out the receiving dual quaternion
 * @param {ReadonlyQuat2} a the source dual quaternion
 * @returns {quat2} out
 * @function
 */

function copy$1(out, a) {
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[3];
  out[4] = a[4];
  out[5] = a[5];
  out[6] = a[6];
  out[7] = a[7];
  return out;
}
/**
 * Set a dual quat to the identity dual quaternion
 *
 * @param {quat2} out the receiving quaternion
 * @returns {quat2} out
 */

function identity$1(out) {
  out[0] = 0;
  out[1] = 0;
  out[2] = 0;
  out[3] = 1;
  out[4] = 0;
  out[5] = 0;
  out[6] = 0;
  out[7] = 0;
  return out;
}
/**
 * Set the components of a dual quat to the given values
 *
 * @param {quat2} out the receiving quaternion
 * @param {Number} x1 X component
 * @param {Number} y1 Y component
 * @param {Number} z1 Z component
 * @param {Number} w1 W component
 * @param {Number} x2 X component
 * @param {Number} y2 Y component
 * @param {Number} z2 Z component
 * @param {Number} w2 W component
 * @returns {quat2} out
 * @function
 */

function set$1(out, x1, y1, z1, w1, x2, y2, z2, w2) {
  out[0] = x1;
  out[1] = y1;
  out[2] = z1;
  out[3] = w1;
  out[4] = x2;
  out[5] = y2;
  out[6] = z2;
  out[7] = w2;
  return out;
}
/**
 * Gets the real part of a dual quat
 * @param  {quat} out real part
 * @param  {ReadonlyQuat2} a Dual Quaternion
 * @return {quat} real part
 */

var getReal = copy$2;
/**
 * Gets the dual part of a dual quat
 * @param  {quat} out dual part
 * @param  {ReadonlyQuat2} a Dual Quaternion
 * @return {quat} dual part
 */

function getDual(out, a) {
  out[0] = a[4];
  out[1] = a[5];
  out[2] = a[6];
  out[3] = a[7];
  return out;
}
/**
 * Set the real component of a dual quat to the given quaternion
 *
 * @param {quat2} out the receiving quaternion
 * @param {ReadonlyQuat} q a quaternion representing the real part
 * @returns {quat2} out
 * @function
 */

var setReal = copy$2;
/**
 * Set the dual component of a dual quat to the given quaternion
 *
 * @param {quat2} out the receiving quaternion
 * @param {ReadonlyQuat} q a quaternion representing the dual part
 * @returns {quat2} out
 * @function
 */

function setDual(out, q) {
  out[4] = q[0];
  out[5] = q[1];
  out[6] = q[2];
  out[7] = q[3];
  return out;
}
/**
 * Gets the translation of a normalized dual quat
 * @param  {vec3} out translation
 * @param  {ReadonlyQuat2} a Dual Quaternion to be decomposed
 * @return {vec3} translation
 */

function getTranslation(out, a) {
  var ax = a[4],
      ay = a[5],
      az = a[6],
      aw = a[7],
      bx = -a[0],
      by = -a[1],
      bz = -a[2],
      bw = a[3];
  out[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2;
  out[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2;
  out[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2;
  return out;
}
/**
 * Translates a dual quat by the given vector
 *
 * @param {quat2} out the receiving dual quaternion
 * @param {ReadonlyQuat2} a the dual quaternion to translate
 * @param {ReadonlyVec3} v vector to translate by
 * @returns {quat2} out
 */

function translate$1(out, a, v) {
  var ax1 = a[0],
      ay1 = a[1],
      az1 = a[2],
      aw1 = a[3],
      bx1 = v[0] * 0.5,
      by1 = v[1] * 0.5,
      bz1 = v[2] * 0.5,
      ax2 = a[4],
      ay2 = a[5],
      az2 = a[6],
      aw2 = a[7];
  out[0] = ax1;
  out[1] = ay1;
  out[2] = az1;
  out[3] = aw1;
  out[4] = aw1 * bx1 + ay1 * bz1 - az1 * by1 + ax2;
  out[5] = aw1 * by1 + az1 * bx1 - ax1 * bz1 + ay2;
  out[6] = aw1 * bz1 + ax1 * by1 - ay1 * bx1 + az2;
  out[7] = -ax1 * bx1 - ay1 * by1 - az1 * bz1 + aw2;
  return out;
}
/**
 * Rotates a dual quat around the X axis
 *
 * @param {quat2} out the receiving dual quaternion
 * @param {ReadonlyQuat2} a the dual quaternion to rotate
 * @param {number} rad how far should the rotation be
 * @returns {quat2} out
 */

function rotateX(out, a, rad) {
  var bx = -a[0],
      by = -a[1],
      bz = -a[2],
      bw = a[3],
      ax = a[4],
      ay = a[5],
      az = a[6],
      aw = a[7],
      ax1 = ax * bw + aw * bx + ay * bz - az * by,
      ay1 = ay * bw + aw * by + az * bx - ax * bz,
      az1 = az * bw + aw * bz + ax * by - ay * bx,
      aw1 = aw * bw - ax * bx - ay * by - az * bz;
  rotateX$1(out, a, rad);
  bx = out[0];
  by = out[1];
  bz = out[2];
  bw = out[3];
  out[4] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by;
  out[5] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz;
  out[6] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx;
  out[7] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz;
  return out;
}
/**
 * Rotates a dual quat around the Y axis
 *
 * @param {quat2} out the receiving dual quaternion
 * @param {ReadonlyQuat2} a the dual quaternion to rotate
 * @param {number} rad how far should the rotation be
 * @returns {quat2} out
 */

function rotateY(out, a, rad) {
  var bx = -a[0],
      by = -a[1],
      bz = -a[2],
      bw = a[3],
      ax = a[4],
      ay = a[5],
      az = a[6],
      aw = a[7],
      ax1 = ax * bw + aw * bx + ay * bz - az * by,
      ay1 = ay * bw + aw * by + az * bx - ax * bz,
      az1 = az * bw + aw * bz + ax * by - ay * bx,
      aw1 = aw * bw - ax * bx - ay * by - az * bz;
  rotateY$1(out, a, rad);
  bx = out[0];
  by = out[1];
  bz = out[2];
  bw = out[3];
  out[4] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by;
  out[5] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz;
  out[6] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx;
  out[7] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz;
  return out;
}
/**
 * Rotates a dual quat around the Z axis
 *
 * @param {quat2} out the receiving dual quaternion
 * @param {ReadonlyQuat2} a the dual quaternion to rotate
 * @param {number} rad how far should the rotation be
 * @returns {quat2} out
 */

function rotateZ(out, a, rad) {
  var bx = -a[0],
      by = -a[1],
      bz = -a[2],
      bw = a[3],
      ax = a[4],
      ay = a[5],
      az = a[6],
      aw = a[7],
      ax1 = ax * bw + aw * bx + ay * bz - az * by,
      ay1 = ay * bw + aw * by + az * bx - ax * bz,
      az1 = az * bw + aw * bz + ax * by - ay * bx,
      aw1 = aw * bw - ax * bx - ay * by - az * bz;
  rotateZ$1(out, a, rad);
  bx = out[0];
  by = out[1];
  bz = out[2];
  bw = out[3];
  out[4] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by;
  out[5] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz;
  out[6] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx;
  out[7] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz;
  return out;
}
/**
 * Rotates a dual quat by a given quaternion (a * q)
 *
 * @param {quat2} out the receiving dual quaternion
 * @param {ReadonlyQuat2} a the dual quaternion to rotate
 * @param {ReadonlyQuat} q quaternion to rotate by
 * @returns {quat2} out
 */

function rotateByQuatAppend(out, a, q) {
  var qx = q[0],
      qy = q[1],
      qz = q[2],
      qw = q[3],
      ax = a[0],
      ay = a[1],
      az = a[2],
      aw = a[3];
  out[0] = ax * qw + aw * qx + ay * qz - az * qy;
  out[1] = ay * qw + aw * qy + az * qx - ax * qz;
  out[2] = az * qw + aw * qz + ax * qy - ay * qx;
  out[3] = aw * qw - ax * qx - ay * qy - az * qz;
  ax = a[4];
  ay = a[5];
  az = a[6];
  aw = a[7];
  out[4] = ax * qw + aw * qx + ay * qz - az * qy;
  out[5] = ay * qw + aw * qy + az * qx - ax * qz;
  out[6] = az * qw + aw * qz + ax * qy - ay * qx;
  out[7] = aw * qw - ax * qx - ay * qy - az * qz;
  return out;
}
/**
 * Rotates a dual quat by a given quaternion (q * a)
 *
 * @param {quat2} out the receiving dual quaternion
 * @param {ReadonlyQuat} q quaternion to rotate by
 * @param {ReadonlyQuat2} a the dual quaternion to rotate
 * @returns {quat2} out
 */

function rotateByQuatPrepend(out, q, a) {
  var qx = q[0],
      qy = q[1],
      qz = q[2],
      qw = q[3],
      bx = a[0],
      by = a[1],
      bz = a[2],
      bw = a[3];
  out[0] = qx * bw + qw * bx + qy * bz - qz * by;
  out[1] = qy * bw + qw * by + qz * bx - qx * bz;
  out[2] = qz * bw + qw * bz + qx * by - qy * bx;
  out[3] = qw * bw - qx * bx - qy * by - qz * bz;
  bx = a[4];
  by = a[5];
  bz = a[6];
  bw = a[7];
  out[4] = qx * bw + qw * bx + qy * bz - qz * by;
  out[5] = qy * bw + qw * by + qz * bx - qx * bz;
  out[6] = qz * bw + qw * bz + qx * by - qy * bx;
  out[7] = qw * bw - qx * bx - qy * by - qz * bz;
  return out;
}
/**
 * Rotates a dual quat around a given axis. Does the normalisation automatically
 *
 * @param {quat2} out the receiving dual quaternion
 * @param {ReadonlyQuat2} a the dual quaternion to rotate
 * @param {ReadonlyVec3} axis the axis to rotate around
 * @param {Number} rad how far the rotation should be
 * @returns {quat2} out
 */

function rotateAroundAxis(out, a, axis, rad) {
  //Special case for rad = 0
  if (Math.abs(rad) < EPSILON) {
    return copy$1(out, a);
  }

  var axisLength = Math.hypot(axis[0], axis[1], axis[2]);
  rad = rad * 0.5;
  var s = Math.sin(rad);
  var bx = s * axis[0] / axisLength;
  var by = s * axis[1] / axisLength;
  var bz = s * axis[2] / axisLength;
  var bw = Math.cos(rad);
  var ax1 = a[0],
      ay1 = a[1],
      az1 = a[2],
      aw1 = a[3];
  out[0] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by;
  out[1] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz;
  out[2] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx;
  out[3] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz;
  var ax = a[4],
      ay = a[5],
      az = a[6],
      aw = a[7];
  out[4] = ax * bw + aw * bx + ay * bz - az * by;
  out[5] = ay * bw + aw * by + az * bx - ax * bz;
  out[6] = az * bw + aw * bz + ax * by - ay * bx;
  out[7] = aw * bw - ax * bx - ay * by - az * bz;
  return out;
}
/**
 * Adds two dual quat's
 *
 * @param {quat2} out the receiving dual quaternion
 * @param {ReadonlyQuat2} a the first operand
 * @param {ReadonlyQuat2} b the second operand
 * @returns {quat2} out
 * @function
 */

function add$1(out, a, b) {
  out[0] = a[0] + b[0];
  out[1] = a[1] + b[1];
  out[2] = a[2] + b[2];
  out[3] = a[3] + b[3];
  out[4] = a[4] + b[4];
  out[5] = a[5] + b[5];
  out[6] = a[6] + b[6];
  out[7] = a[7] + b[7];
  return out;
}
/**
 * Multiplies two dual quat's
 *
 * @param {quat2} out the receiving dual quaternion
 * @param {ReadonlyQuat2} a the first operand
 * @param {ReadonlyQuat2} b the second operand
 * @returns {quat2} out
 */

function multiply$1(out, a, b) {
  var ax0 = a[0],
      ay0 = a[1],
      az0 = a[2],
      aw0 = a[3],
      bx1 = b[4],
      by1 = b[5],
      bz1 = b[6],
      bw1 = b[7],
      ax1 = a[4],
      ay1 = a[5],
      az1 = a[6],
      aw1 = a[7],
      bx0 = b[0],
      by0 = b[1],
      bz0 = b[2],
      bw0 = b[3];
  out[0] = ax0 * bw0 + aw0 * bx0 + ay0 * bz0 - az0 * by0;
  out[1] = ay0 * bw0 + aw0 * by0 + az0 * bx0 - ax0 * bz0;
  out[2] = az0 * bw0 + aw0 * bz0 + ax0 * by0 - ay0 * bx0;
  out[3] = aw0 * bw0 - ax0 * bx0 - ay0 * by0 - az0 * bz0;
  out[4] = ax0 * bw1 + aw0 * bx1 + ay0 * bz1 - az0 * by1 + ax1 * bw0 + aw1 * bx0 + ay1 * bz0 - az1 * by0;
  out[5] = ay0 * bw1 + aw0 * by1 + az0 * bx1 - ax0 * bz1 + ay1 * bw0 + aw1 * by0 + az1 * bx0 - ax1 * bz0;
  out[6] = az0 * bw1 + aw0 * bz1 + ax0 * by1 - ay0 * bx1 + az1 * bw0 + aw1 * bz0 + ax1 * by0 - ay1 * bx0;
  out[7] = aw0 * bw1 - ax0 * bx1 - ay0 * by1 - az0 * bz1 + aw1 * bw0 - ax1 * bx0 - ay1 * by0 - az1 * bz0;
  return out;
}
/**
 * Alias for {@link quat2.multiply}
 * @function
 */

var mul$1 = multiply$1;
/**
 * Scales a dual quat by a scalar number
 *
 * @param {quat2} out the receiving dual quat
 * @param {ReadonlyQuat2} a the dual quat to scale
 * @param {Number} b amount to scale the dual quat by
 * @returns {quat2} out
 * @function
 */

function scale$1(out, a, b) {
  out[0] = a[0] * b;
  out[1] = a[1] * b;
  out[2] = a[2] * b;
  out[3] = a[3] * b;
  out[4] = a[4] * b;
  out[5] = a[5] * b;
  out[6] = a[6] * b;
  out[7] = a[7] * b;
  return out;
}
/**
 * Calculates the dot product of two dual quat's (The dot product of the real parts)
 *
 * @param {ReadonlyQuat2} a the first operand
 * @param {ReadonlyQuat2} b the second operand
 * @returns {Number} dot product of a and b
 * @function
 */

var dot$2 = dot$3;
/**
 * Performs a linear interpolation between two dual quats's
 * NOTE: The resulting dual quaternions won't always be normalized (The error is most noticeable when t = 0.5)
 *
 * @param {quat2} out the receiving dual quat
 * @param {ReadonlyQuat2} a the first operand
 * @param {ReadonlyQuat2} b the second operand
 * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
 * @returns {quat2} out
 */

function lerp$1(out, a, b, t) {
  var mt = 1 - t;
  if (dot$2(a, b) < 0) t = -t;
  out[0] = a[0] * mt + b[0] * t;
  out[1] = a[1] * mt + b[1] * t;
  out[2] = a[2] * mt + b[2] * t;
  out[3] = a[3] * mt + b[3] * t;
  out[4] = a[4] * mt + b[4] * t;
  out[5] = a[5] * mt + b[5] * t;
  out[6] = a[6] * mt + b[6] * t;
  out[7] = a[7] * mt + b[7] * t;
  return out;
}
/**
 * Calculates the inverse of a dual quat. If they are normalized, conjugate is cheaper
 *
 * @param {quat2} out the receiving dual quaternion
 * @param {ReadonlyQuat2} a dual quat to calculate inverse of
 * @returns {quat2} out
 */

function invert(out, a) {
  var sqlen = squaredLength$1(a);
  out[0] = -a[0] / sqlen;
  out[1] = -a[1] / sqlen;
  out[2] = -a[2] / sqlen;
  out[3] = a[3] / sqlen;
  out[4] = -a[4] / sqlen;
  out[5] = -a[5] / sqlen;
  out[6] = -a[6] / sqlen;
  out[7] = a[7] / sqlen;
  return out;
}
/**
 * Calculates the conjugate of a dual quat
 * If the dual quaternion is normalized, this function is faster than quat2.inverse and produces the same result.
 *
 * @param {quat2} out the receiving quaternion
 * @param {ReadonlyQuat2} a quat to calculate conjugate of
 * @returns {quat2} out
 */

function conjugate(out, a) {
  out[0] = -a[0];
  out[1] = -a[1];
  out[2] = -a[2];
  out[3] = a[3];
  out[4] = -a[4];
  out[5] = -a[5];
  out[6] = -a[6];
  out[7] = a[7];
  return out;
}
/**
 * Calculates the length of a dual quat
 *
 * @param {ReadonlyQuat2} a dual quat to calculate length of
 * @returns {Number} length of a
 * @function
 */

var length$1 = length$2;
/**
 * Alias for {@link quat2.length}
 * @function
 */

var len$1 = length$1;
/**
 * Calculates the squared length of a dual quat
 *
 * @param {ReadonlyQuat2} a dual quat to calculate squared length of
 * @returns {Number} squared length of a
 * @function
 */

var squaredLength$1 = squaredLength$2;
/**
 * Alias for {@link quat2.squaredLength}
 * @function
 */

var sqrLen$1 = squaredLength$1;
/**
 * Normalize a dual quat
 *
 * @param {quat2} out the receiving dual quaternion
 * @param {ReadonlyQuat2} a dual quaternion to normalize
 * @returns {quat2} out
 * @function
 */

function normalize$1(out, a) {
  var magnitude = squaredLength$1(a);

  if (magnitude > 0) {
    magnitude = Math.sqrt(magnitude);
    var a0 = a[0] / magnitude;
    var a1 = a[1] / magnitude;
    var a2 = a[2] / magnitude;
    var a3 = a[3] / magnitude;
    var b0 = a[4];
    var b1 = a[5];
    var b2 = a[6];
    var b3 = a[7];
    var a_dot_b = a0 * b0 + a1 * b1 + a2 * b2 + a3 * b3;
    out[0] = a0;
    out[1] = a1;
    out[2] = a2;
    out[3] = a3;
    out[4] = (b0 - a0 * a_dot_b) / magnitude;
    out[5] = (b1 - a1 * a_dot_b) / magnitude;
    out[6] = (b2 - a2 * a_dot_b) / magnitude;
    out[7] = (b3 - a3 * a_dot_b) / magnitude;
  }

  return out;
}
/**
 * Returns a string representation of a dual quatenion
 *
 * @param {ReadonlyQuat2} a dual quaternion to represent as a string
 * @returns {String} string representation of the dual quat
 */

function str$1(a) {
  return "quat2(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ")";
}
/**
 * Returns whether or not the dual quaternions have exactly the same elements in the same position (when compared with ===)
 *
 * @param {ReadonlyQuat2} a the first dual quaternion.
 * @param {ReadonlyQuat2} b the second dual quaternion.
 * @returns {Boolean} true if the dual quaternions are equal, false otherwise.
 */

function exactEquals$1(a, b) {
  return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7];
}
/**
 * Returns whether or not the dual quaternions have approximately the same elements in the same position.
 *
 * @param {ReadonlyQuat2} a the first dual quat.
 * @param {ReadonlyQuat2} b the second dual quat.
 * @returns {Boolean} true if the dual quats are equal, false otherwise.
 */

function equals$2(a, b) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3],
      a4 = a[4],
      a5 = a[5],
      a6 = a[6],
      a7 = a[7];
  var b0 = b[0],
      b1 = b[1],
      b2 = b[2],
      b3 = b[3],
      b4 = b[4],
      b5 = b[5],
      b6 = b[6],
      b7 = b[7];
  return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7));
}

var quat2 = /*#__PURE__*/Object.freeze({
__proto__: null,
add: add$1,
clone: clone$1,
conjugate: conjugate,
copy: copy$1,
create: create$1,
dot: dot$2,
equals: equals$2,
exactEquals: exactEquals$1,
fromMat4: fromMat4,
fromRotation: fromRotation,
fromRotationTranslation: fromRotationTranslation,
fromRotationTranslationValues: fromRotationTranslationValues,
fromTranslation: fromTranslation,
fromValues: fromValues$1,
getDual: getDual,
getReal: getReal,
getTranslation: getTranslation,
identity: identity$1,
invert: invert,
len: len$1,
length: length$1,
lerp: lerp$1,
mul: mul$1,
multiply: multiply$1,
normalize: normalize$1,
rotateAroundAxis: rotateAroundAxis,
rotateByQuatAppend: rotateByQuatAppend,
rotateByQuatPrepend: rotateByQuatPrepend,
rotateX: rotateX,
rotateY: rotateY,
rotateZ: rotateZ,
scale: scale$1,
set: set$1,
setDual: setDual,
setReal: setReal,
sqrLen: sqrLen$1,
squaredLength: squaredLength$1,
str: str$1,
translate: translate$1
});

/**
 * 2 Dimensional Vector
 * @module vec2
 */

/**
 * Creates a new, empty vec2
 *
 * @returns {vec2} a new 2D vector
 */

function create() {
  var out = new ARRAY_TYPE(2);

  if (ARRAY_TYPE != Float32Array) {
    out[0] = 0;
    out[1] = 0;
  }

  return out;
}
/**
 * Creates a new vec2 initialized with values from an existing vector
 *
 * @param {ReadonlyVec2} a vector to clone
 * @returns {vec2} a new 2D vector
 */

function clone(a) {
  var out = new ARRAY_TYPE(2);
  out[0] = a[0];
  out[1] = a[1];
  return out;
}
/**
 * Creates a new vec2 initialized with the given values
 *
 * @param {Number} x X component
 * @param {Number} y Y component
 * @returns {vec2} a new 2D vector
 */

function fromValues(x, y) {
  var out = new ARRAY_TYPE(2);
  out[0] = x;
  out[1] = y;
  return out;
}
/**
 * Copy the values from one vec2 to another
 *
 * @param {vec2} out the receiving vector
 * @param {ReadonlyVec2} a the source vector
 * @returns {vec2} out
 */

function copy(out, a) {
  out[0] = a[0];
  out[1] = a[1];
  return out;
}
/**
 * Set the components of a vec2 to the given values
 *
 * @param {vec2} out the receiving vector
 * @param {Number} x X component
 * @param {Number} y Y component
 * @returns {vec2} out
 */

function set(out, x, y) {
  out[0] = x;
  out[1] = y;
  return out;
}
/**
 * Adds two vec2's
 *
 * @param {vec2} out the receiving vector
 * @param {ReadonlyVec2} a the first operand
 * @param {ReadonlyVec2} b the second operand
 * @returns {vec2} out
 */

function add(out, a, b) {
  out[0] = a[0] + b[0];
  out[1] = a[1] + b[1];
  return out;
}
/**
 * Subtracts vector b from vector a
 *
 * @param {vec2} out the receiving vector
 * @param {ReadonlyVec2} a the first operand
 * @param {ReadonlyVec2} b the second operand
 * @returns {vec2} out
 */

function subtract(out, a, b) {
  out[0] = a[0] - b[0];
  out[1] = a[1] - b[1];
  return out;
}
/**
 * Multiplies two vec2's
 *
 * @param {vec2} out the receiving vector
 * @param {ReadonlyVec2} a the first operand
 * @param {ReadonlyVec2} b the second operand
 * @returns {vec2} out
 */

function multiply(out, a, b) {
  out[0] = a[0] * b[0];
  out[1] = a[1] * b[1];
  return out;
}
/**
 * Divides two vec2's
 *
 * @param {vec2} out the receiving vector
 * @param {ReadonlyVec2} a the first operand
 * @param {ReadonlyVec2} b the second operand
 * @returns {vec2} out
 */

function divide(out, a, b) {
  out[0] = a[0] / b[0];
  out[1] = a[1] / b[1];
  return out;
}
/**
 * Math.ceil the components of a vec2
 *
 * @param {vec2} out the receiving vector
 * @param {ReadonlyVec2} a vector to ceil
 * @returns {vec2} out
 */

function ceil(out, a) {
  out[0] = Math.ceil(a[0]);
  out[1] = Math.ceil(a[1]);
  return out;
}
/**
 * Math.floor the components of a vec2
 *
 * @param {vec2} out the receiving vector
 * @param {ReadonlyVec2} a vector to floor
 * @returns {vec2} out
 */

function floor(out, a) {
  out[0] = Math.floor(a[0]);
  out[1] = Math.floor(a[1]);
  return out;
}
/**
 * Returns the minimum of two vec2's
 *
 * @param {vec2} out the receiving vector
 * @param {ReadonlyVec2} a the first operand
 * @param {ReadonlyVec2} b the second operand
 * @returns {vec2} out
 */

function min(out, a, b) {
  out[0] = Math.min(a[0], b[0]);
  out[1] = Math.min(a[1], b[1]);
  return out;
}
/**
 * Returns the maximum of two vec2's
 *
 * @param {vec2} out the receiving vector
 * @param {ReadonlyVec2} a the first operand
 * @param {ReadonlyVec2} b the second operand
 * @returns {vec2} out
 */

function max(out, a, b) {
  out[0] = Math.max(a[0], b[0]);
  out[1] = Math.max(a[1], b[1]);
  return out;
}
/**
 * Math.round the components of a vec2
 *
 * @param {vec2} out the receiving vector
 * @param {ReadonlyVec2} a vector to round
 * @returns {vec2} out
 */

function round(out, a) {
  out[0] = Math.round(a[0]);
  out[1] = Math.round(a[1]);
  return out;
}
/**
 * Scales a vec2 by a scalar number
 *
 * @param {vec2} out the receiving vector
 * @param {ReadonlyVec2} a the vector to scale
 * @param {Number} b amount to scale the vector by
 * @returns {vec2} out
 */

function scale(out, a, b) {
  out[0] = a[0] * b;
  out[1] = a[1] * b;
  return out;
}
/**
 * Adds two vec2's after scaling the second operand by a scalar value
 *
 * @param {vec2} out the receiving vector
 * @param {ReadonlyVec2} a the first operand
 * @param {ReadonlyVec2} b the second operand
 * @param {Number} scale the amount to scale b by before adding
 * @returns {vec2} out
 */

function scaleAndAdd(out, a, b, scale) {
  out[0] = a[0] + b[0] * scale;
  out[1] = a[1] + b[1] * scale;
  return out;
}
/**
 * Calculates the euclidian distance between two vec2's
 *
 * @param {ReadonlyVec2} a the first operand
 * @param {ReadonlyVec2} b the second operand
 * @returns {Number} distance between a and b
 */

function distance(a, b) {
  var x = b[0] - a[0],
      y = b[1] - a[1];
  return Math.hypot(x, y);
}
/**
 * Calculates the squared euclidian distance between two vec2's
 *
 * @param {ReadonlyVec2} a the first operand
 * @param {ReadonlyVec2} b the second operand
 * @returns {Number} squared distance between a and b
 */

function squaredDistance(a, b) {
  var x = b[0] - a[0],
      y = b[1] - a[1];
  return x * x + y * y;
}
/**
 * Calculates the length of a vec2
 *
 * @param {ReadonlyVec2} a vector to calculate length of
 * @returns {Number} length of a
 */

function length(a) {
  var x = a[0],
      y = a[1];
  return Math.hypot(x, y);
}
/**
 * Calculates the squared length of a vec2
 *
 * @param {ReadonlyVec2} a vector to calculate squared length of
 * @returns {Number} squared length of a
 */

function squaredLength(a) {
  var x = a[0],
      y = a[1];
  return x * x + y * y;
}
/**
 * Negates the components of a vec2
 *
 * @param {vec2} out the receiving vector
 * @param {ReadonlyVec2} a vector to negate
 * @returns {vec2} out
 */

function negate(out, a) {
  out[0] = -a[0];
  out[1] = -a[1];
  return out;
}
/**
 * Returns the inverse of the components of a vec2
 *
 * @param {vec2} out the receiving vector
 * @param {ReadonlyVec2} a vector to invert
 * @returns {vec2} out
 */

function inverse(out, a) {
  out[0] = 1.0 / a[0];
  out[1] = 1.0 / a[1];
  return out;
}
/**
 * Normalize a vec2
 *
 * @param {vec2} out the receiving vector
 * @param {ReadonlyVec2} a vector to normalize
 * @returns {vec2} out
 */

function normalize(out, a) {
  var x = a[0],
      y = a[1];
  var len = x * x + y * y;

  if (len > 0) {
    //TODO: evaluate use of glm_invsqrt here?
    len = 1 / Math.sqrt(len);
  }

  out[0] = a[0] * len;
  out[1] = a[1] * len;
  return out;
}
/**
 * Calculates the dot product of two vec2's
 *
 * @param {ReadonlyVec2} a the first operand
 * @param {ReadonlyVec2} b the second operand
 * @returns {Number} dot product of a and b
 */

function dot$1(a, b) {
  return a[0] * b[0] + a[1] * b[1];
}
/**
 * Computes the cross product of two vec2's
 * Note that the cross product must by definition produce a 3D vector
 *
 * @param {vec3} out the receiving vector
 * @param {ReadonlyVec2} a the first operand
 * @param {ReadonlyVec2} b the second operand
 * @returns {vec3} out
 */

function cross(out, a, b) {
  var z = a[0] * b[1] - a[1] * b[0];
  out[0] = out[1] = 0;
  out[2] = z;
  return out;
}
/**
 * Performs a linear interpolation between two vec2's
 *
 * @param {vec2} out the receiving vector
 * @param {ReadonlyVec2} a the first operand
 * @param {ReadonlyVec2} b the second operand
 * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
 * @returns {vec2} out
 */

function lerp(out, a, b, t) {
  var ax = a[0],
      ay = a[1];
  out[0] = ax + t * (b[0] - ax);
  out[1] = ay + t * (b[1] - ay);
  return out;
}
/**
 * Generates a random vector with the given scale
 *
 * @param {vec2} out the receiving vector
 * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
 * @returns {vec2} out
 */

function random(out, scale) {
  scale = scale || 1.0;
  var r = RANDOM() * 2.0 * Math.PI;
  out[0] = Math.cos(r) * scale;
  out[1] = Math.sin(r) * scale;
  return out;
}
/**
 * Transforms the vec2 with a mat2
 *
 * @param {vec2} out the receiving vector
 * @param {ReadonlyVec2} a the vector to transform
 * @param {ReadonlyMat2} m matrix to transform with
 * @returns {vec2} out
 */

function transformMat2(out, a, m) {
  var x = a[0],
      y = a[1];
  out[0] = m[0] * x + m[2] * y;
  out[1] = m[1] * x + m[3] * y;
  return out;
}
/**
 * Transforms the vec2 with a mat2d
 *
 * @param {vec2} out the receiving vector
 * @param {ReadonlyVec2} a the vector to transform
 * @param {ReadonlyMat2d} m matrix to transform with
 * @returns {vec2} out
 */

function transformMat2d(out, a, m) {
  var x = a[0],
      y = a[1];
  out[0] = m[0] * x + m[2] * y + m[4];
  out[1] = m[1] * x + m[3] * y + m[5];
  return out;
}
/**
 * Transforms the vec2 with a mat3
 * 3rd vector component is implicitly '1'
 *
 * @param {vec2} out the receiving vector
 * @param {ReadonlyVec2} a the vector to transform
 * @param {ReadonlyMat3} m matrix to transform with
 * @returns {vec2} out
 */

function transformMat3(out, a, m) {
  var x = a[0],
      y = a[1];
  out[0] = m[0] * x + m[3] * y + m[6];
  out[1] = m[1] * x + m[4] * y + m[7];
  return out;
}
/**
 * Transforms the vec2 with a mat4
 * 3rd vector component is implicitly '0'
 * 4th vector component is implicitly '1'
 *
 * @param {vec2} out the receiving vector
 * @param {ReadonlyVec2} a the vector to transform
 * @param {ReadonlyMat4} m matrix to transform with
 * @returns {vec2} out
 */

function transformMat4(out, a, m) {
  var x = a[0];
  var y = a[1];
  out[0] = m[0] * x + m[4] * y + m[12];
  out[1] = m[1] * x + m[5] * y + m[13];
  return out;
}
/**
 * Rotate a 2D vector
 * @param {vec2} out The receiving vec2
 * @param {ReadonlyVec2} a The vec2 point to rotate
 * @param {ReadonlyVec2} b The origin of the rotation
 * @param {Number} rad The angle of rotation in radians
 * @returns {vec2} out
 */

function rotate(out, a, b, rad) {
  //Translate point to the origin
  var p0 = a[0] - b[0],
      p1 = a[1] - b[1],
      sinC = Math.sin(rad),
      cosC = Math.cos(rad); //perform rotation and translate to correct position

  out[0] = p0 * cosC - p1 * sinC + b[0];
  out[1] = p0 * sinC + p1 * cosC + b[1];
  return out;
}
/**
 * Get the angle between two 2D vectors
 * @param {ReadonlyVec2} a The first operand
 * @param {ReadonlyVec2} b The second operand
 * @returns {Number} The angle in radians
 */

function angle(a, b) {
  var x1 = a[0],
      y1 = a[1],
      x2 = b[0],
      y2 = b[1],
      // mag is the product of the magnitudes of a and b
  mag = Math.sqrt(x1 * x1 + y1 * y1) * Math.sqrt(x2 * x2 + y2 * y2),
      // mag &&.. short circuits if mag == 0
  cosine = mag && (x1 * x2 + y1 * y2) / mag; // Math.min(Math.max(cosine, -1), 1) clamps the cosine between -1 and 1

  return Math.acos(Math.min(Math.max(cosine, -1), 1));
}
/**
 * Set the components of a vec2 to zero
 *
 * @param {vec2} out the receiving vector
 * @returns {vec2} out
 */

function zero(out) {
  out[0] = 0.0;
  out[1] = 0.0;
  return out;
}
/**
 * Returns a string representation of a vector
 *
 * @param {ReadonlyVec2} a vector to represent as a string
 * @returns {String} string representation of the vector
 */

function str(a) {
  return "vec2(" + a[0] + ", " + a[1] + ")";
}
/**
 * Returns whether or not the vectors exactly have the same elements in the same position (when compared with ===)
 *
 * @param {ReadonlyVec2} a The first vector.
 * @param {ReadonlyVec2} b The second vector.
 * @returns {Boolean} True if the vectors are equal, false otherwise.
 */

function exactEquals(a, b) {
  return a[0] === b[0] && a[1] === b[1];
}
/**
 * Returns whether or not the vectors have approximately the same elements in the same position.
 *
 * @param {ReadonlyVec2} a The first vector.
 * @param {ReadonlyVec2} b The second vector.
 * @returns {Boolean} True if the vectors are equal, false otherwise.
 */

function equals$1(a, b) {
  var a0 = a[0],
      a1 = a[1];
  var b0 = b[0],
      b1 = b[1];
  return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1));
}
/**
 * Alias for {@link vec2.length}
 * @function
 */

var len = length;
/**
 * Alias for {@link vec2.subtract}
 * @function
 */

var sub = subtract;
/**
 * Alias for {@link vec2.multiply}
 * @function
 */

var mul = multiply;
/**
 * Alias for {@link vec2.divide}
 * @function
 */

var div = divide;
/**
 * Alias for {@link vec2.distance}
 * @function
 */

var dist = distance;
/**
 * Alias for {@link vec2.squaredDistance}
 * @function
 */

var sqrDist = squaredDistance;
/**
 * Alias for {@link vec2.squaredLength}
 * @function
 */

var sqrLen = squaredLength;
/**
 * Perform some operation over an array of vec2s.
 *
 * @param {Array} a the array of vectors to iterate over
 * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed
 * @param {Number} offset Number of elements to skip at the beginning of the array
 * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array
 * @param {Function} fn Function to call for each vector in the array
 * @param {Object} [arg] additional argument to pass to fn
 * @returns {Array} a
 * @function
 */

var forEach = function () {
  var vec = create();
  return function (a, stride, offset, count, fn, arg) {
    var i, l;

    if (!stride) {
      stride = 2;
    }

    if (!offset) {
      offset = 0;
    }

    if (count) {
      l = Math.min(count * stride + offset, a.length);
    } else {
      l = a.length;
    }

    for (i = offset; i < l; i += stride) {
      vec[0] = a[i];
      vec[1] = a[i + 1];
      fn(vec, vec, arg);
      a[i] = vec[0];
      a[i + 1] = vec[1];
    }

    return a;
  };
}();

var vec2 = /*#__PURE__*/Object.freeze({
__proto__: null,
add: add,
angle: angle,
ceil: ceil,
clone: clone,
copy: copy,
create: create,
cross: cross,
dist: dist,
distance: distance,
div: div,
divide: divide,
dot: dot$1,
equals: equals$1,
exactEquals: exactEquals,
floor: floor,
forEach: forEach,
fromValues: fromValues,
inverse: inverse,
len: len,
length: length,
lerp: lerp,
max: max,
min: min,
mul: mul,
multiply: multiply,
negate: negate,
normalize: normalize,
random: random,
rotate: rotate,
round: round,
scale: scale,
scaleAndAdd: scaleAndAdd,
set: set,
sqrDist: sqrDist,
sqrLen: sqrLen,
squaredDistance: squaredDistance,
squaredLength: squaredLength,
str: str,
sub: sub,
subtract: subtract,
transformMat2: transformMat2,
transformMat2d: transformMat2d,
transformMat3: transformMat3,
transformMat4: transformMat4,
zero: zero
});

//      

                                                               

const layout$6                    = createLayout([
    {type: 'Float32', name: 'a_globe_pos', components: 3},
    {type: 'Float32', name: 'a_uv', components: 2}
]);
const {members: members$4, size: size$4, alignment: alignment$4} = layout$6;

//      

                                                               

const posAttributesGlobeExt                    = createLayout([
    {name: 'a_pos_3', components: 3, type: 'Int16'},
]);

var posAttributes = (createLayout([
    {name: 'a_pos', type: 'Int16', components: 2}
])                   );

//      


                                          

class Ray {
              
              

    constructor(pos_      , dir_      ) {
        this.pos = pos_;
        this.dir = dir_;
    }

    intersectsPlane(pt      , normal      , out      )          {
        const D = dot$5(normal, this.dir);

        // ray is parallel to plane, so it misses
        if (Math.abs(D) < 1e-6) { return false; }

        const t = (
            (pt[0] - this.pos[0]) * normal[0] +
            (pt[1] - this.pos[1]) * normal[1] +
            (pt[2] - this.pos[2]) * normal[2]) / D;

        out[0] = this.pos[0] + this.dir[0] * t;
        out[1] = this.pos[1] + this.dir[1] * t;
        out[2] = this.pos[2] + this.dir[2] * t;

        return true;
    }

    closestPointOnSphere(center      , r        , out      )          {
        assert$1(squaredLength$4(this.dir) > 0.0 && r >= 0.0);

        if (equals$5(this.pos, center) || r === 0.0) {
            out[0] = out[1] = out[2] = 0;
            return false;
        }

        const [dx, dy, dz] = this.dir;

        const px = this.pos[0] - center[0];
        const py = this.pos[1] - center[1];
        const pz = this.pos[2] - center[2];

        const a = dx * dx + dy * dy + dz * dz;
        const b = 2.0 * (px * dx + py * dy + pz * dz);
        const c = (px * px + py * py + pz * pz) - r * r;
        const d = b * b - 4 * a * c;

        if (d < 0.0) {
            // No intersection, find distance between closest points
            const t = Math.max(-b / 2, 0.0);
            const gx = px + dx * t; // point to globe
            const gy = py + dy * t;
            const gz = pz + dz * t;
            const glen = Math.hypot(gx, gy, gz);
            out[0] = gx * r / glen;
            out[1] = gy * r / glen;
            out[2] = gz * r / glen;
            return false;

        } else {
            assert$1(a > 0.0);
            const t = (-b - Math.sqrt(d)) / (2.0 * a);

            if (t < 0.0) {
                // Ray is pointing away from the sphere
                const plen = Math.hypot(px, py, pz);
                out[0] = px * r / plen;
                out[1] = py * r / plen;
                out[2] = pz * r / plen;
                return false;

            } else {
                out[0] = px + dx * t;
                out[1] = py + dy * t;
                out[2] = pz + dz * t;
                return true;
            }
        }
    }
}

class FrustumCorners {
                                 
                                 
                                 
                                 
                    

    constructor(TL_                          , TR_                          , BR_                          , BL_                          , horizon_        ) {
        this.TL = TL_;
        this.TR = TR_;
        this.BR = BR_;
        this.BL = BL_;
        this.horizon = horizon_;
    }

    static fromInvProjectionMatrix(invProj               , horizonFromTop        , viewportHeight        )                 {
        const TLClip = [-1, 1, 1];
        const TRClip = [1, 1, 1];
        const BRClip = [1, -1, 1];
        const BLClip = [-1, -1, 1];

        const TL = transformMat4$2(TLClip, TLClip, invProj);
        const TR = transformMat4$2(TRClip, TRClip, invProj);
        const BR = transformMat4$2(BRClip, BRClip, invProj);
        const BL = transformMat4$2(BLClip, BLClip, invProj);

        return new FrustumCorners(TL, TR, BR, BL, horizonFromTop / viewportHeight);
    }
}

class Frustum {
                                 
                                 

    constructor(points_                      , planes_                      ) {
        this.points = points_;
        this.planes = planes_;
    }

    static fromInvProjectionMatrix(invProj              , worldSize        , zoom        , zInMeters         )          {
        const clipSpaceCorners = [
            [-1, 1, -1, 1],
            [ 1, 1, -1, 1],
            [ 1, -1, -1, 1],
            [-1, -1, -1, 1],
            [-1, 1, 1, 1],
            [ 1, 1, 1, 1],
            [ 1, -1, 1, 1],
            [-1, -1, 1, 1]
        ];

        const scale = Math.pow(2, zoom);

        // Transform frustum corner points from clip space to tile space
        const frustumCoords = clipSpaceCorners
            .map(v => {
                const s = transformMat4$1([], v, invProj);
                const k = 1.0 / s[3] / worldSize * scale;
                // Z scale in meters.
                return mul$3(s, s, [k, k, zInMeters ? 1.0 / s[3] : k, k]);
            });

        const frustumPlanePointIndices = [
            [0, 1, 2],  // near
            [6, 5, 4],  // far
            [0, 3, 7],  // left
            [2, 1, 5],  // right
            [3, 2, 6],  // bottom
            [0, 4, 5]   // top
        ];

        const frustumPlanes = frustumPlanePointIndices.map((p               ) => {
            const a = sub$2([], frustumCoords[p[0]], frustumCoords[p[1]]);
            const b = sub$2([], frustumCoords[p[2]], frustumCoords[p[1]]);
            const n = normalize$4([], cross$2([], a, b));
            const d = -dot$5(n, frustumCoords[p[1]]);
            return n.concat(d);
        });

        return new Frustum(frustumCoords, frustumPlanes);
    }
}

class Aabb {
              
              
                 

    static fromPoints(points             )       {
        const min = [Infinity, Infinity, Infinity];
        const max = [-Infinity, -Infinity, -Infinity];

        for (const p of points) {
            min$2(min, min, p);
            max$2(max, max, p);
        }

        return new Aabb(min, max);
    }

    static applyTransform(aabb      , transform      )       {
        const corners = aabb.getCorners();

        for (let i = 0; i < corners.length; ++i) {
            transformMat4$2(corners[i], corners[i], transform);
        }
        return Aabb.fromPoints(corners);
    }

    constructor(min_      , max_      ) {
        this.min = min_;
        this.max = max_;
        this.center = scale$4([], add$4([], this.min, this.max), 0.5);
    }

    quadrant(index        )       {
        const split = [(index % 2) === 0, index < 2];
        const qMin = clone$4(this.min);
        const qMax = clone$4(this.max);
        for (let axis = 0; axis < split.length; axis++) {
            qMin[axis] = split[axis] ? this.min[axis] : this.center[axis];
            qMax[axis] = split[axis] ? this.center[axis] : this.max[axis];
        }
        // Temporarily, elevation is constant, hence quadrant.max.z = this.max.z
        qMax[2] = this.max[2];
        return new Aabb(qMin, qMax);
    }

    distanceX(point               )         {
        const pointOnAabb = Math.max(Math.min(this.max[0], point[0]), this.min[0]);
        return pointOnAabb - point[0];
    }

    distanceY(point               )         {
        const pointOnAabb = Math.max(Math.min(this.max[1], point[1]), this.min[1]);
        return pointOnAabb - point[1];
    }

    distanceZ(point               )         {
        const pointOnAabb = Math.max(Math.min(this.max[2], point[2]), this.min[2]);
        return pointOnAabb - point[2];
    }

    getCorners()              {
        const mn = this.min;
        const mx = this.max;
        return [
            [mn[0], mn[1], mn[2]],
            [mx[0], mn[1], mn[2]],
            [mx[0], mx[1], mn[2]],
            [mn[0], mx[1], mn[2]],
            [mn[0], mn[1], mx[2]],
            [mx[0], mn[1], mx[2]],
            [mx[0], mx[1], mx[2]],
            [mn[0], mx[1], mx[2]],
        ];
    }

    // Performs a frustum-aabb intersection test. Returns 0 if there's no intersection,
    // 1 if shapes are intersecting and 2 if the aabb if fully inside the frustum.
    intersects(frustum         )         {
        // Execute separating axis test between two convex objects to find intersections
        // Each frustum plane together with 3 major axes define the separating axes

        const aabbPoints = this.getCorners();
        let fullyInside = true;

        for (let p = 0; p < frustum.planes.length; p++) {
            const plane = frustum.planes[p];
            let pointsInside = 0;

            for (let i = 0; i < aabbPoints.length; i++) {
                pointsInside += dot$5(plane, aabbPoints[i]) + plane[3] >= 0;
            }

            if (pointsInside === 0)
                return 0;

            if (pointsInside !== aabbPoints.length)
                fullyInside = false;
        }

        if (fullyInside)
            return 2;

        for (let axis = 0; axis < 3; axis++) {
            let projMin = Number.MAX_VALUE;
            let projMax = -Number.MAX_VALUE;

            for (let p = 0; p < frustum.points.length; p++) {
                const projectedPoint = frustum.points[p][axis] - this.min[axis];

                projMin = Math.min(projMin, projectedPoint);
                projMax = Math.max(projMax, projectedPoint);
            }

            if (projMax < 0 || projMin > this.max[axis] - this.min[axis])
                return 0;
        }

        return 1;
    }
}

//      

const GLOBE_ZOOM_THRESHOLD_MIN = 5;
const GLOBE_ZOOM_THRESHOLD_MAX = 6;

// At low zoom levels the globe gets rendered so that the scale at this
// latitude matches it's scale in a mercator map. The choice of latitude is
// a bit arbitrary. Different choices will match mercator more closely in different
// views. 45 is a good enough choice because:
// - it's half way from the pole to the equator
// - matches most middle latitudes reasonably well
// - biases towards increasing size rather than decreasing
// - makes the globe slightly larger at very low zoom levels, where it already
//   covers less pixels than mercator (due to the curved surface)
//
//   Changing this value will change how large a globe is rendered and could affect
//   end users. This should only be done of the tradeoffs between change and improvement
//   are carefully considered.
const GLOBE_SCALE_MATCH_LATITUDE = 45;

const GLOBE_RADIUS = EXTENT / Math.PI / 2.0;
const GLOBE_NORMALIZATION_BIT_RANGE = 15;
const GLOBE_NORMALIZATION_MASK = (1 << (GLOBE_NORMALIZATION_BIT_RANGE - 1)) - 1;
const GLOBE_VERTEX_GRID_SIZE = 64;
const GLOBE_LATITUDINAL_GRID_LOD_TABLE = [GLOBE_VERTEX_GRID_SIZE, GLOBE_VERTEX_GRID_SIZE / 2, GLOBE_VERTEX_GRID_SIZE / 4];
const TILE_SIZE = 512;

const GLOBE_MIN = -GLOBE_RADIUS;
const GLOBE_MAX = GLOBE_RADIUS;

const GLOBE_LOW_ZOOM_TILE_AABBS = [
    // z == 0
    new Aabb([GLOBE_MIN, GLOBE_MIN, GLOBE_MIN], [GLOBE_MAX, GLOBE_MAX, GLOBE_MAX]),
    // z == 1
    new Aabb([GLOBE_MIN, GLOBE_MIN, GLOBE_MIN], [0, 0, GLOBE_MAX]), // x=0, y=0
    new Aabb([0, GLOBE_MIN, GLOBE_MIN], [GLOBE_MAX, 0, GLOBE_MAX]), // x=1, y=0
    new Aabb([GLOBE_MIN, 0, GLOBE_MIN], [0, GLOBE_MAX, GLOBE_MAX]), // x=0, y=1
    new Aabb([0, 0, GLOBE_MIN], [GLOBE_MAX, GLOBE_MAX, GLOBE_MAX])  // x=1, y=1
];

function globeMetersToEcef(d        )         {
    return d * GLOBE_RADIUS / earthRadius;
}

function globePointCoordinate(tr           , x        , y        , clampToHorizon          = true)                      {
    const point0 = scale$4([], tr._camera.position, tr.worldSize);
    const point1 = [x, y, 1, 1];

    transformMat4$1(point1, point1, tr.pixelMatrixInverse);
    scale$3(point1, point1, 1 / point1[3]);

    const p0p1 = sub$2([], point1, point0);
    const dir = normalize$4([], p0p1);

    // Find closest point on the sphere to the ray. This is a bit more involving operation
    // if the ray is not intersecting with the sphere, in which case we "clamp" the ray
    // to the surface of the sphere, i.e. find a tangent vector that originates from the camera position
    const m = tr.globeMatrix;
    const globeCenter = [m[12], m[13], m[14]];
    const p0toCenter = sub$2([], globeCenter, point0);
    const p0toCenterDist = length$4(p0toCenter);
    const centerDir = normalize$4([], p0toCenter);
    const radius = tr.worldSize / (2.0 * Math.PI);
    const cosAngle = dot$5(centerDir, dir);

    const origoTangentAngle = Math.asin(radius / p0toCenterDist);
    const origoDirAngle = Math.acos(cosAngle);

    if (origoTangentAngle < origoDirAngle) {
        if (!clampToHorizon) return null;

        // Find the tangent vector by interpolating between camera-to-globe and camera-to-click vectors.
        // First we'll find a point P1 on the clicked ray that forms a right-angled triangle with the camera position
        // and the center of the globe. Angle of the tanget vector is then used as the interpolation factor
        const clampedP1 = [], origoToP1 = [];

        scale$4(clampedP1, dir, p0toCenterDist / cosAngle);
        normalize$4(origoToP1, sub$2(origoToP1, clampedP1, p0toCenter));
        normalize$4(dir, add$4(dir, p0toCenter, scale$4(dir, origoToP1, Math.tan(origoTangentAngle) * p0toCenterDist)));
    }

    const pointOnGlobe = [];
    const ray = new Ray(point0, dir);

    ray.closestPointOnSphere(globeCenter, radius, pointOnGlobe);

    // Transform coordinate axes to find lat & lng of the position
    const xa = normalize$4([], getColumn(m, 0));
    const ya = normalize$4([], getColumn(m, 1));
    const za = normalize$4([], getColumn(m, 2));

    const xp = dot$5(xa, pointOnGlobe);
    const yp = dot$5(ya, pointOnGlobe);
    const zp = dot$5(za, pointOnGlobe);

    const lat = radToDeg(Math.asin(-yp / radius));
    let lng = radToDeg(Math.atan2(xp, zp));

    // Check that the returned longitude angle is not wrapped
    lng = tr.center.lng + shortestAngle(tr.center.lng, lng);

    const mx = mercatorXfromLng(lng);
    const my = clamp(mercatorYfromLat(lat), 0, 1);

    return new MercatorCoordinate$1(mx, my);
}

class Arc {
    constructor(p0      , p1      , center      ) {
        this.a = sub$2([], p0, center);
        this.b = sub$2([], p1, center);
        this.center = center;
        const an = normalize$4([], this.a);
        const bn = normalize$4([], this.b);
        this.angle = Math.acos(dot$5(an, bn));
    }

            
            
                 
                  
}

function slerp(a        , b        , angle        , t        )         {
    const sina = Math.sin(angle);
    return a * (Math.sin((1.0 - t) * angle) / sina) + b * (Math.sin(t * angle) / sina);
}

// Computes local extremum point of an arc on one of the dimensions (x, y or z),
// i.e. value of a point where d/dt*f(x,y,t) == 0
function localExtremum(arc     , dim        )          {
    // d/dt*slerp(x,y,t) = 0
    // => t = (1/a)*atan(y/(x*sin(a))-1/tan(a)), x > 0
    // => t = (1/a)*(pi/2), x == 0
    if (arc.angle === 0) {
        return null;
    }

    let t        ;
    if (arc.a[dim] === 0) {
        t = (1.0 / arc.angle) * 0.5 * Math.PI;
    } else {
        t = 1.0 / arc.angle * Math.atan(arc.b[dim] / arc.a[dim] / Math.sin(arc.angle) - 1.0 / Math.tan(arc.angle));
    }

    if (t < 0 || t > 1) {
        return null;
    }

    return slerp(arc.a[dim], arc.b[dim], arc.angle, clamp(t, 0.0, 1.0)) + arc.center[dim];
}

function globeTileBounds(id                 )       {
    if (id.z <= 1) {
        return GLOBE_LOW_ZOOM_TILE_AABBS[id.z + id.y * 2 + id.x];
    }

    // After zoom 1 surface function is monotonic for all tile patches
    // => it is enough to project corner points
    const bounds = tileCornersToBounds(id);
    const corners = boundsToECEF(bounds);

    return Aabb.fromPoints(corners);
}

function interpolateVec3(from      , to      , phase        )       {
    scale$4(from, from, 1 - phase);
    return scaleAndAdd$2(from, from, to, phase);
}

// Similar to globeTileBounds() but accounts for globe to Mercator transition.
function transitionTileAABBinECEF(id                 , tr           )       {
    const phase = globeToMercatorTransition(tr.zoom);
    if (phase === 0) {
        return globeTileBounds(id);
    }

    const bounds = tileCornersToBounds(id);
    const corners = boundsToECEF(bounds);

    const w = mercatorXfromLng(bounds.getWest()) * tr.worldSize;
    const e = mercatorXfromLng(bounds.getEast()) * tr.worldSize;
    const n = mercatorYfromLat(bounds.getNorth()) * tr.worldSize;
    const s = mercatorYfromLat(bounds.getSouth()) * tr.worldSize;
    // Mercator bounds globeCorners in world/pixel space
    const nw = [w, n, 0];
    const ne = [e, n, 0];
    const sw = [w, s, 0];
    const se = [e, s, 0];
    // Transform Mercator globeCorners to ECEF
    const worldToECEFMatrix = invert$2([], tr.globeMatrix);
    transformMat4$2(nw, nw, worldToECEFMatrix);
    transformMat4$2(ne, ne, worldToECEFMatrix);
    transformMat4$2(sw, sw, worldToECEFMatrix);
    transformMat4$2(se, se, worldToECEFMatrix);
    // Interpolate Mercator corners and globe corners
    corners[0] = interpolateVec3(corners[0], sw, phase);
    corners[1] = interpolateVec3(corners[1], se, phase);
    corners[2] = interpolateVec3(corners[2], ne, phase);
    corners[3] = interpolateVec3(corners[3], nw, phase);

    return Aabb.fromPoints(corners);
}

function transformPoints(corners             , globeMatrix      , scale        ) {
    for (const corner of corners) {
        transformMat4$2(corner, corner, globeMatrix);
        scale$4(corner, corner, scale);
    }
}

// Returns AABB in world/camera space scaled by numTiles / tr.worldSize
function aabbForTileOnGlobe(tr           , numTiles        , tileId                 )       {
    const scale = numTiles / tr.worldSize;
    const m = tr.globeMatrix;

    if (tileId.z <= 1) {
        // Compute world/pixel space AABB that fully encapsulates
        // transformed corners of the ECEF AABB
        const corners = globeTileBounds(tileId).getCorners();
        transformPoints(corners, m, scale);
        return Aabb.fromPoints(corners);
    }

    // Find minimal aabb for a tile. Correct solution would be to compute bounding box that
    // fully encapsulates the curved patch that represents the tile on globes surface.
    // This can be simplified a bit as the globe transformation is constrained:
    //  1. Camera always faces the center point on the map
    //  2. Camera is always above (z-coordinate) all of the tiles
    //  3. Up direction of the coordinate space (pixel space) is always +z. This means that
    //     the "highest" point of the map is at the center.
    //  4. z-coordinate of any point in any tile descends as a function of the distance from the center

    // Simplified aabb is computed by first encapsulating 4 transformed corner points of the tile.
    // The resulting aabb is not complete yet as curved edges of the tile might span outside of the boundaries.
    // It is enough to extend the aabb to contain only the edge that's closest to the center point.
    const bounds = tileCornersToBounds(tileId);
    const corners = boundsToECEF(bounds);

    // Transform the corners to world space
    transformPoints(corners, m, scale);

    const mx = Number.MAX_VALUE;
    const cornerMax = [-mx, -mx, -mx];
    const cornerMin = [mx, mx, mx];

    // Extend the aabb by including the center point. There are some corner cases where center point is inside the
    // tile but due to curvature aabb computed from corner points does not cover the curved area.
    if (bounds.contains(tr.center)) {

        for (const corner of corners) {
            min$2(cornerMin, cornerMin, corner);
            max$2(cornerMax, cornerMax, corner);
        }
        cornerMax[2] = 0.0;
        const point = tr.point;
        const center = [point.x * scale, point.y * scale, 0];
        min$2(cornerMin, cornerMin, center);
        max$2(cornerMax, cornerMax, center);

        return new Aabb(cornerMin, cornerMax);
    }

    // Compute arcs describing edges of the tile on the globe surface.
    // Vertical edges revolves around the globe origin whereas horizontal edges revolves around the y-axis.
    const arcCenter = [m[12] * scale, m[13] * scale, m[14] * scale];

    const tileCenter = bounds.getCenter();
    const centerLat = clamp(tr.center.lat, -MAX_MERCATOR_LATITUDE, MAX_MERCATOR_LATITUDE);
    const tileCenterLat = clamp(tileCenter.lat, -MAX_MERCATOR_LATITUDE, MAX_MERCATOR_LATITUDE);
    const camX = mercatorXfromLng(tr.center.lng);
    const camY = mercatorYfromLat(centerLat);

    let dx = camX - mercatorXfromLng(tileCenter.lng);
    const dy = camY - mercatorYfromLat(tileCenterLat);

    // Shortest distance might be across the antimeridian
    if (dx > .5) {
        dx -= 1;
    } else if (dx < -.5) {
        dx += 1;
    }

    // Here we determine the arc which is closest to the map center point.
    // Horizontal arcs origin = globe center
    // Vertical arcs origin = globe center + yAxis * shift.
    // Where `shift` is determined by latitude.
    let closestArcIdx = 0;
    if (Math.abs(dx) > Math.abs(dy)) {
        closestArcIdx = dx >= 0 ? 1 : 3;
    } else {
        closestArcIdx = dy >= 0 ? 0 : 2;
        const yAxis = [m[4] * scale, m[5] * scale, m[6] * scale];
        const shift = -Math.sin(degToRad(dy >= 0 ? bounds.getSouth() : bounds.getNorth())) * GLOBE_RADIUS;
        scaleAndAdd$2(arcCenter, arcCenter, yAxis, shift);
    }

    const arcStart = corners[closestArcIdx];
    const arcEnd = corners[(closestArcIdx + 1) % 4];

    const closestArc = new Arc(arcStart, arcEnd, arcCenter);
    const arcExtremum = [
        (localExtremum(closestArc, 0) || arcStart[0]),
        (localExtremum(closestArc, 1) || arcStart[1]),
        (localExtremum(closestArc, 2) || arcStart[2])];

    const phase = globeToMercatorTransition(tr.zoom);
    if (phase > 0.0) {
        const mercatorCorners = mercatorTileCornersInCameraSpace(tileId, numTiles, tr._pixelsPerMercatorPixel, camX, camY);
        // Interpolate the four corners towards their world space location in mercator projection during transition.
        for (let i = 0; i < corners.length; i++) {
            interpolateVec3(corners[i], mercatorCorners[i], phase);
        }
        // Calculate the midpoint of the closest edge midpoint in Mercator
        const mercatorMidpoint = add$4([], mercatorCorners[closestArcIdx], mercatorCorners[(closestArcIdx + 1) % 4]);
        scale$4(mercatorMidpoint, mercatorMidpoint, .5);
        // Interpolate globe extremum toward Mercator midpoint
        interpolateVec3(arcExtremum, mercatorMidpoint, phase);
    }

    for (const corner of corners) {
        min$2(cornerMin, cornerMin, corner);
        max$2(cornerMax, cornerMax, corner);
    }

    // Reduce height of the aabb to match height of the closest arc. This reduces false positives
    // of tiles farther away from the center as they would otherwise intersect with far end
    // of the view frustum
    cornerMin[2] = Math.min(arcStart[2], arcEnd[2]);

    min$2(cornerMin, cornerMin, arcExtremum);
    max$2(cornerMax, cornerMax, arcExtremum);

    return new Aabb(cornerMin, cornerMax);
}

function tileCornersToBounds({x, y, z}                 )               {
    const s = 1.0 / (1 << z);
    const sw = new LngLat$1(lngFromMercatorX(x * s), latFromMercatorY((y + 1) * s));
    const ne = new LngLat$1(lngFromMercatorX((x + 1) * s), latFromMercatorY(y * s));
    return new LngLatBounds(sw, ne);
}

function mercatorTileCornersInCameraSpace({x, y, z}                 , numTiles        , mercatorScale        , camX        , camY        )              {

    const tileScale = 1.0 / (1 << z);
    // Values in Mercator coordinates (0 - 1)
    let w = x * tileScale;
    let e = w + tileScale;
    let n = y * tileScale;
    let s = n + tileScale;

    // // Ensure that the tile viewed is the nearest when across the antimeridian
    let wrap = 0;
    const tileCenterXFromCamera = (w + e) / 2 - camX;
    if (tileCenterXFromCamera > .5) {
        wrap = -1;
    } else if (tileCenterXFromCamera < -.5) {
        wrap = 1;
    }

    camX *= numTiles;
    camY *= numTiles;

    //  Transform Mercator coordinates to points on the plane tangent to the globe at cameraCenter.
    w = ((w + wrap) * numTiles - camX) * mercatorScale + camX;
    e = ((e + wrap) * numTiles - camX) * mercatorScale + camX;
    n = (n * numTiles - camY) * mercatorScale + camY;
    s = (s * numTiles - camY) * mercatorScale + camY;

    return [[w, s, 0],
        [e, s, 0],
        [e, n, 0],
        [w, n, 0]];
}

function boundsToECEF(bounds              )              {
    const ny = degToRad(bounds.getNorth());
    const sy = degToRad(bounds.getSouth());
    const cosN = Math.cos(ny);
    const cosS = Math.cos(sy);
    const sinN = Math.sin(ny);
    const sinS = Math.sin(sy);
    const w = bounds.getWest();
    const e = bounds.getEast();
    return [
        csLatLngToECEF(cosS, sinS, w),
        csLatLngToECEF(cosS, sinS, e),
        csLatLngToECEF(cosN, sinN, e),
        csLatLngToECEF(cosN, sinN, w)
    ];
}

function csLatLngToECEF(cosLat        , sinLat        , lng        , radius         = GLOBE_RADIUS)       {
    lng = degToRad(lng);

    // Convert lat & lng to spherical representation. Use zoom=0 as a reference
    const sx = cosLat * Math.sin(lng) * radius;
    const sy = -sinLat * radius;
    const sz = cosLat * Math.cos(lng) * radius;

    return [sx, sy, sz];
}

function ecefToLatLng([x, y, z]               )         {
    const radius = Math.hypot(x, y, z);
    const lng = Math.atan2(x, z);
    const lat = Math.PI * 0.5 - Math.acos(-y / radius);

    return new LngLat$1(radToDeg(lng), radToDeg(lat));
}

function latLngToECEF(lat        , lng        , radius         )       {
    assert$1(lat <= 90 && lat >= -90, 'Lattitude must be between -90 and 90');
    return csLatLngToECEF(Math.cos(degToRad(lat)), Math.sin(degToRad(lat)), lng, radius);
}

function tileCoordToECEF(x        , y        , id                 , radius         )       {
    const tileCount = 1 << id.z;
    const mercatorX = (x / EXTENT + id.x) / tileCount;
    const mercatorY = (y / EXTENT + id.y) / tileCount;
    const lat = latFromMercatorY(mercatorY);
    const lng = lngFromMercatorX(mercatorX);
    const pos = latLngToECEF(lat, lng, radius);
    return pos;
}

function globeECEFOrigin(tileMatrix      , id                 )                           {
    const origin = [0, 0, 0];
    const bounds = globeTileBounds(id.canonical);
    const normalizationMatrix = globeNormalizeECEF(bounds);
    transformMat4$2(origin, origin, normalizationMatrix);
    transformMat4$2(origin, origin, tileMatrix);
    return origin;
}

function globeECEFNormalizationScale({min, max}      )         {
    return GLOBE_NORMALIZATION_MASK / Math.max(max[0] - min[0], max[1] - min[1], max[2] - min[2]);
}

// avoid redundant allocations by sharing the same typed array for normalization/denormalization matrices;
// we never use multiple instances of these at the same time, but this might change, so let's be careful here!
const tempMatrix = new Float64Array(16);

function globeNormalizeECEF(bounds      )               {
    const scale = globeECEFNormalizationScale(bounds);
    const m = fromScaling(tempMatrix, [scale, scale, scale]);
    return translate$2(m, m, negate$2([], bounds.min));
}

function globeDenormalizeECEF(bounds      )               {
    const m = fromTranslation$1(tempMatrix, bounds.min);
    const scale = 1.0 / globeECEFNormalizationScale(bounds);
    return scale$5(m, m, [scale, scale, scale]);
}

function globeECEFUnitsToPixelScale(worldSize        )         {
    const localRadius = EXTENT / (2.0 * Math.PI);
    const wsRadius = worldSize / (2.0 * Math.PI);
    return wsRadius / localRadius;
}

function globePixelsToTileUnits(zoom        , id                 )         {
    const ecefPerPixel = EXTENT / (TILE_SIZE * Math.pow(2, zoom));
    const normCoeff = globeECEFNormalizationScale(globeTileBounds(id));

    return ecefPerPixel * normCoeff;
}

function calculateGlobePosMatrix(x        , y        , worldSize        , lng        , lat        )               {
    // transform the globe from reference coordinate space to world space
    const scale = globeECEFUnitsToPixelScale(worldSize);
    const offset = [x, y, -worldSize / (2.0 * Math.PI)];
    const m = identity$3(new Float64Array(16));
    translate$2(m, m, offset);
    scale$5(m, m, [scale, scale, scale]);
    rotateX$3(m, m, degToRad(-lat));
    rotateY$3(m, m, degToRad(-lng));
    return m;
}

function calculateGlobeMatrix(tr           )               {
    const {x, y} = tr.point;
    const {lng, lat} = tr._center;
    return calculateGlobePosMatrix(x, y, tr.worldSize, lng, lat);
}

function calculateGlobeLabelMatrix(tr           , id                 )               {
    const {x, y} = tr.point;

    // Map aligned label space for globe view is the non-rotated globe itself in pixel coordinates.

    // Camera is moved closer towards the ground near poles as part of
    // compesanting the reprojection. This has to be compensated for the
    // map aligned label space. Whithout this logic map aligned symbols
    // would appear larger than intended.
    const m = calculateGlobePosMatrix(x, y, tr.worldSize / tr._pixelsPerMercatorPixel, 0, 0);
    return multiply$5(m, m, globeDenormalizeECEF(globeTileBounds(id)));
}

function calculateGlobeMercatorMatrix(tr           )               {
    const zScale = tr.pixelsPerMeter;
    const ws = zScale / mercatorZfromAltitude(1, tr.center.lat);

    const posMatrix = identity$3(new Float64Array(16));
    translate$2(posMatrix, posMatrix, [tr.point.x, tr.point.y, 0.0]);
    scale$5(posMatrix, posMatrix, [ws, ws, zScale]);

    return Float32Array.from(posMatrix);
}

function globeToMercatorTransition(zoom        )         {
    return smoothstep(GLOBE_ZOOM_THRESHOLD_MIN, GLOBE_ZOOM_THRESHOLD_MAX, zoom);
}

function globeMatrixForTile(id                 , globeMatrix              )               {
    const decode = globeDenormalizeECEF(globeTileBounds(id));
    return mul$5(create$5(), globeMatrix, decode);
}

function globePoleMatrixForTile(z        , x        , tr           )               {
    const poleMatrix = identity$3(new Float64Array(16));

    // Rotate the pole triangle fan to the correct location
    const numTiles = 1 << z;
    const xOffsetAngle = (x / numTiles - 0.5) * Math.PI * 2.0;
    rotateY$3(poleMatrix, tr.globeMatrix, xOffsetAngle);

    return Float32Array.from(poleMatrix);
}

function globeUseCustomAntiAliasing(painter         , context         , transform           )          {
    const transitionT = globeToMercatorTransition(transform.zoom);
    const useContextAA = painter.style.map._antialias;
    const hasStandardDerivatives = !!context.extStandardDerivatives;
    const disabled = context.extStandardDerivativesForceOff || (painter.terrain && painter.terrain.exaggeration() > 0.0);
    return transitionT === 0.0 && !useContextAA && !disabled && hasStandardDerivatives;
}

function getGridMatrix(id                 , bounds              , latitudinalLod        , worldSize        )       {
    const n = bounds.getNorth();
    const s = bounds.getSouth();
    const w = bounds.getWest();
    const e = bounds.getEast();

    // Construct transformation matrix for converting tile coordinates into LatLngs
    const tiles = 1 << id.z;
    const tileWidth = e - w;
    const tileHeight = n - s;
    const tileToLng = tileWidth / GLOBE_VERTEX_GRID_SIZE;
    const tileToLat = -tileHeight / GLOBE_LATITUDINAL_GRID_LOD_TABLE[latitudinalLod];

    const matrix = [0, tileToLng, 0, tileToLat, 0, 0, n, w, 0];

    if (id.z > 0) {
        // Add slight padding to patch seams between tiles.
        // This is done by extruding vertices by a fixed amount. Pixel padding
        // is first converted to degrees and then to tile units before being
        // applied to the final transformation matrix.
        const pixelPadding = 0.5;
        const padding = pixelPadding * 360.0 / worldSize;

        const xScale = padding / tileWidth + 1;
        const yScale = padding / tileHeight + 1;
        const padMatrix = [xScale, 0, 0, 0, yScale, 0, -0.5 * padding / tileToLng, 0.5 * padding / tileToLat, 1];

        multiply$6(matrix, matrix, padMatrix);
    }

    // Embed additional variables to the last row of the matrix
    matrix[2] = tiles;
    matrix[5] = id.x;
    matrix[8] = id.y;

    return matrix;
}

function getLatitudinalLod(lat        )         {
    const UPPER_LATITUDE = MAX_MERCATOR_LATITUDE - 5.0;
    lat = clamp(lat, -UPPER_LATITUDE, UPPER_LATITUDE) / UPPER_LATITUDE * 90.0;
    // const t = Math.pow(1.0 - Math.cos(degToRad(lat)), 2);
    const t = Math.pow(Math.abs(Math.sin(degToRad(lat))), 3);
    const lod = Math.round(t * (GLOBE_LATITUDINAL_GRID_LOD_TABLE.length - 1));
    return lod;
}

function globeCenterToScreenPoint(tr           )        {
    const pos = [0, 0, 0];
    const matrix = identity$3(new Float64Array(16));
    multiply$5(matrix, tr.pixelMatrix, tr.globeMatrix);
    transformMat4$2(pos, pos, matrix);
    return new Point$2(pos[0], pos[1]);
}

function cameraPositionInECEF(tr           )                {
    // Here "center" is the center of the globe. We refer to transform._center
    // (the surface of the map on the center of the screen) as "pivot" to avoid confusion.
    const centerToPivot = latLngToECEF(tr._center.lat, tr._center.lng);

    // Set axis to East-West line tangent to sphere at pivot
    const south = fromValues$4(0, 1, 0);
    let axis = cross$2([], south, centerToPivot);

    // Rotate axis around pivot by bearing
    const rotation = fromRotation$1([], -tr.angle, centerToPivot);
    axis = transformMat4$2(axis, axis, rotation);

    // Rotate camera around axis by pitch
    fromRotation$1(rotation, -tr._pitch, axis);

    const pivotToCamera = normalize$4([], centerToPivot);
    scale$4(pivotToCamera, pivotToCamera, globeMetersToEcef(tr.cameraToCenterDistance / tr.pixelsPerMeter));
    transformMat4$2(pivotToCamera, pivotToCamera, rotation);

    return add$4([], centerToPivot, pivotToCamera);
}

// Return the angle of the normal vector at a point on the globe relative to the camera.
// i.e. how much to tilt map-aligned markers.
function globeTiltAtLngLat(tr           , lngLat        )         {
    const centerToPoint = latLngToECEF(lngLat.lat, lngLat.lng);
    const centerToCamera = cameraPositionInECEF(tr);
    const pointToCamera = subtract$2([], centerToCamera, centerToPoint);
    return angle$1(pointToCamera, centerToPoint);
}

function isLngLatBehindGlobe(tr           , lngLat        )          {
    // We consider 1% past the horizon not occluded, this allows popups to be dragged around the globe edge without fading.
    return (globeTiltAtLngLat(tr, lngLat) > Math.PI / 2 * 1.01);
}

/**
 * Check if poles are visible inside the current viewport
 *
 * @param {Transform} transform The current map transform.
 * @returns {[boolean, boolean]} A tuple of booleans [northInViewport, southInViewport]
 */
function polesInViewport(tr           )                     {
    // Create matrix from ECEF to screen coordinates
    const ecefToScreenMatrix = identity$3(new Float64Array(16));
    multiply$5(ecefToScreenMatrix, tr.pixelMatrix, tr.globeMatrix);

    const north = [0, GLOBE_MIN, 0];
    const south = [0, GLOBE_MAX, 0];

    // Translate the poles from ECEF to screen coordinates
    transformMat4$2(north, north, ecefToScreenMatrix);
    transformMat4$2(south, south, ecefToScreenMatrix);

    // Check if the poles are inside the viewport and not behind the globe surface
    const northInViewport =
        north[0] > 0 && north[0] <= tr.width &&
        north[1] > 0 && north[1] <= tr.height &&
        !isLngLatBehindGlobe(tr, new LngLat$1(tr.center.lat, 90));

    const southInViewport =
        south[0] > 0 && south[0] <= tr.width &&
        south[1] > 0 && south[1] <= tr.height &&
        !isLngLatBehindGlobe(tr, new LngLat$1(tr.center.lat, -90));

    return [northInViewport, southInViewport];
}

const POLE_RAD = degToRad(85.0);
const POLE_COS = Math.cos(POLE_RAD);
const POLE_SIN = Math.sin(POLE_RAD);

// Generate terrain grid with embedded skirts
const EMBED_SKIRTS = true;

                        
                                 
                             
  

                     
                       
                                
                                    
  

class GlobeSharedBuffers {
                                         
                                         
                                  
                                        

                              
                                  
                                          

                                       
                                             

    constructor(context         ) {
        this._createGrid(context);
        this._createPoles(context);
    }

    destroy() {
        this._poleIndexBuffer.destroy();
        this._gridBuffer.destroy();
        this._gridIndexBuffer.destroy();
        this._poleNorthVertexBuffer.destroy();
        this._poleSouthVertexBuffer.destroy();
        for (const segments of this._poleSegments) segments.destroy();
        for (const segments of this._gridSegments) {
            segments.withSkirts.destroy();
            segments.withoutSkirts.destroy();
        }

        if (this._wireframeIndexBuffer) {
            this._wireframeIndexBuffer.destroy();
            for (const segments of this._wireframeSegments) segments.destroy();
        }
    }

    // Generate terrain grid vertices and indices for all LOD's
    //
    // Grid vertices memory layout:
    //
    //          First line Skirt
    //          ┌───────────────┐
    //          │┌─────────────┐│
    // Left     ││┼┼┼┼┼┼┼┼┼┼┼┼┼││ Right
    // Border   ││┼┼┼┼┼┼┼┼┼┼┼┼┼││ Border
    // Skirt    │├─────────────┤│ Skirt
    //          ││  Main Grid  ││
    //          │├─────────────┤│
    //          ││┼┼┼┼┼┼┼┼┼┼┼┼┼││
    //          ││┼┼┼┼┼┼┼┼┼┼┼┼┼││
    //          │└─────────────┘│
    //          ├───────────────┤
    //          ├───────────────┤
    //          └───────────────┘
    //      Bottom Skirt = Number of LOD's
    //
    _fillGridMeshWithLods(longitudinalCellsCount        , latitudinalLods          )               {
        const vertices = new StructArrayLayout2i4();
        const indices = new StructArrayLayout3ui6();
        const segments                         = [];

        const xVertices = longitudinalCellsCount + 1 + 2 * (EMBED_SKIRTS ? 1 : 0);
        const yVerticesHighLodNoStrip = latitudinalLods[0] + 1;
        const yVerticesHighLodWithStrip = latitudinalLods[0] + 1 + (EMBED_SKIRTS ? 1 + latitudinalLods.length : 0);

        // Index adjustment, used to make strip (x, y) vertex input attribute data
        // to match same data on ordinary grid edges
        const prepareVertex = (x        , y        , isSkirt         ) => {
            if (!EMBED_SKIRTS) return [x, y];

            let adjustedX = (() => {
                if (x === xVertices - 1) {
                    return x - 2;
                } else if (x === 0) {
                    return x;
                } else {
                    return x - 1;
                }
            })();

            // Skirt factor is introduces as an offset to the .x coordinate, similar to how it's done for mercator grids
            const skirtOffset = 24575;
            adjustedX += isSkirt ? skirtOffset : 0;

            return [adjustedX, y];
        };

        // Add first horizontal strip if present
        if (EMBED_SKIRTS) {
            for (let x = 0; x < xVertices; ++x) {
                vertices.emplaceBack(...prepareVertex(x, 0, true));
            }
        }

        // Add main grid part with vertices strips embedded
        for (let y = 0; y < yVerticesHighLodNoStrip; ++y) {
            for (let x = 0; x < xVertices; ++x) {
                const isSideBorder = (x === 0 || x === xVertices - 1);

                vertices.emplaceBack(...prepareVertex(x, y, isSideBorder && EMBED_SKIRTS));
            }
        }

        // Add bottom strips for each LOD
        if (EMBED_SKIRTS) {
            for (let lodIdx = 0; lodIdx < latitudinalLods.length; ++lodIdx) {
                const lastYRowForLod = latitudinalLods[lodIdx];
                for (let x = 0; x < xVertices; ++x) {
                    vertices.emplaceBack(...prepareVertex(x, lastYRowForLod, true));
                }
            }
        }

        // Fill triangles
        for (let lodIdx = 0; lodIdx < latitudinalLods.length; ++lodIdx) {
            const indexOffset = indices.length;

            const yVerticesLod = latitudinalLods[lodIdx] + 1 + 2 * (EMBED_SKIRTS ? 1 : 0);

            const skirtsOnlyIndices = new StructArrayLayout3ui6();

            for (let y = 0; y < yVerticesLod - 1; y++) {
                const isLastLine = (y === yVerticesLod - 2);
                const offsetToNextRow =
                    (isLastLine && EMBED_SKIRTS ?
                        (xVertices * (yVerticesHighLodWithStrip - latitudinalLods.length + lodIdx - y)) :
                        xVertices);

                for (let x = 0; x < xVertices - 1; x++) {
                    const idx = y * xVertices + x;

                    const isSkirt = EMBED_SKIRTS && (y === 0 || isLastLine || x === 0 || x === xVertices - 2);

                    if (isSkirt) {
                        skirtsOnlyIndices.emplaceBack(idx + 1, idx, idx + offsetToNextRow);
                        skirtsOnlyIndices.emplaceBack(idx + offsetToNextRow, idx + offsetToNextRow + 1, idx + 1);
                    } else {
                        indices.emplaceBack(idx + 1, idx, idx + offsetToNextRow);
                        indices.emplaceBack(idx + offsetToNextRow, idx + offsetToNextRow + 1, idx + 1);
                    }
                }
            }

            // Segments grid only
            const withoutSkirts = SegmentVector.simpleSegment(0, indexOffset, vertices.length, indices.length - indexOffset);

            for (let i = 0; i < skirtsOnlyIndices.uint16.length; i += 3) {
                indices.emplaceBack(skirtsOnlyIndices.uint16[i], skirtsOnlyIndices.uint16[i + 1], skirtsOnlyIndices.uint16[i + 2]);
            }

            // Segments grid + skirts only
            const withSkirts = SegmentVector.simpleSegment(0, indexOffset, vertices.length, indices.length - indexOffset);
            segments.push({withoutSkirts, withSkirts});
        }

        return {vertices, indices, segments};
    }

    _createGrid(context         ) {
        const gridWithLods = this._fillGridMeshWithLods(GLOBE_VERTEX_GRID_SIZE, GLOBE_LATITUDINAL_GRID_LOD_TABLE);
        this._gridSegments = gridWithLods.segments;

        this._gridBuffer = context.createVertexBuffer(gridWithLods.vertices, posAttributes.members);
        this._gridIndexBuffer = context.createIndexBuffer(gridWithLods.indices, true);
    }

    _createPoles(context         ) {
        const poleIndices = new StructArrayLayout3ui6();
        for (let i = 0; i <= GLOBE_VERTEX_GRID_SIZE; i++) {
            poleIndices.emplaceBack(0, i + 1, i + 2);
        }
        this._poleIndexBuffer = context.createIndexBuffer(poleIndices, true);

        const northVertices = new StructArrayLayout5f20();
        const southVertices = new StructArrayLayout5f20();
        const polePrimitives = GLOBE_VERTEX_GRID_SIZE;
        const poleVertices = GLOBE_VERTEX_GRID_SIZE + 2;
        this._poleSegments = [];

        for (let zoom = 0, offset = 0; zoom < GLOBE_ZOOM_THRESHOLD_MIN; zoom++) {
            const tiles = 1 << zoom;
            const endAngle = 360.0 / tiles;

            northVertices.emplaceBack(0, -GLOBE_RADIUS, 0, 0.5, 0); // place the tip
            southVertices.emplaceBack(0, -GLOBE_RADIUS, 0, 0.5, 1);

            for (let i = 0; i <= GLOBE_VERTEX_GRID_SIZE; i++) {
                const uvX = i / GLOBE_VERTEX_GRID_SIZE;
                const angle = number(0, endAngle, uvX);
                const [gx, gy, gz] = csLatLngToECEF(POLE_COS, POLE_SIN, angle, GLOBE_RADIUS);
                northVertices.emplaceBack(gx, gy, gz, uvX, 0);
                southVertices.emplaceBack(gx, gy, gz, uvX, 1);
            }

            this._poleSegments.push(SegmentVector.simpleSegment(offset, 0, poleVertices, polePrimitives));

            offset += poleVertices;
        }

        this._poleNorthVertexBuffer = context.createVertexBuffer(northVertices, members$4, false);
        this._poleSouthVertexBuffer = context.createVertexBuffer(southVertices, members$4, false);
    }

    getGridBuffers(latitudinalLod        , withSkirts         )                                             {
        return [this._gridBuffer, this._gridIndexBuffer, withSkirts ? this._gridSegments[latitudinalLod].withSkirts : this._gridSegments[latitudinalLod].withoutSkirts];
    }

    getPoleBuffers(z        )                                                           {
        return [this._poleNorthVertexBuffer, this._poleSouthVertexBuffer, this._poleIndexBuffer, this._poleSegments[z]];
    }

    getWirefameBuffers(context         , lod        )                                             {
        if (!this._wireframeSegments) {
            const wireframeIndices = new StructArrayLayout2ui4();
            const quadExt = GLOBE_VERTEX_GRID_SIZE;
            const vertexExt = quadExt + 1 + (EMBED_SKIRTS ? 2 : 0);

            const iterOffset = EMBED_SKIRTS ? 1 : 0;

            this._wireframeSegments = [];
            for (let k = 0, primitiveOffset = 0; k < GLOBE_LATITUDINAL_GRID_LOD_TABLE.length; k++) {
                const latitudinalLod = GLOBE_LATITUDINAL_GRID_LOD_TABLE[k];
                for (let j = iterOffset; j < latitudinalLod + iterOffset; j++) {
                    for (let i = iterOffset; i < quadExt + iterOffset; i++) {
                        const index = j * vertexExt + i;
                        wireframeIndices.emplaceBack(index, index + 1);
                        wireframeIndices.emplaceBack(index, index + vertexExt);
                        wireframeIndices.emplaceBack(index, index + vertexExt + 1);
                    }
                }

                const numVertices = (latitudinalLod + 1) * vertexExt;
                const numPrimitives = latitudinalLod * quadExt * 3;

                this._wireframeSegments.push(SegmentVector.simpleSegment(0, primitiveOffset, numVertices, numPrimitives));
                primitiveOffset += numPrimitives;
            }

            this._wireframeIndexBuffer = context.createIndexBuffer(wireframeIndices);
        }
        return [this._gridBuffer, this._wireframeIndexBuffer, this._wireframeSegments[lod]];
    }
}

//      


/*
* Approximate radius of the earth in meters.
* Uses the WGS-84 approximation. The radius at the equator is ~6378137 and at the poles is ~6356752. https://en.wikipedia.org/wiki/World_Geodetic_System#WGS84
* 6371008.8 is one published "average radius" see https://en.wikipedia.org/wiki/Earth_radius#Mean_radius, or ftp://athena.fsv.cvut.cz/ZFG/grs80-Moritz.pdf p.4
*/
const earthRadius = 6371008.8;

/*
 * The average circumference of the earth in meters.
 */
const earthCircumference = 2 * Math.PI * earthRadius;

/**
 * A `LngLat` object represents a given longitude and latitude coordinate, measured in degrees.
 * These coordinates use longitude, latitude coordinate order (as opposed to latitude, longitude)
 * to match the [GeoJSON specification](https://datatracker.ietf.org/doc/html/rfc7946#section-4),
 * which is equivalent to the OGC:CRS84 coordinate reference system.
 *
 * Note that any Mapbox GL method that accepts a `LngLat` object as an argument or option
 * can also accept an `Array` of two numbers and will perform an implicit conversion.
 * This flexible type is documented as {@link LngLatLike}.
 *
 * @param {number} lng Longitude, measured in degrees.
 * @param {number} lat Latitude, measured in degrees.
 * @example
 * const ll = new mapboxgl.LngLat(-123.9749, 40.7736);
 * console.log(ll.lng); // = -123.9749
 * @see [Example: Get coordinates of the mouse pointer](https://www.mapbox.com/mapbox-gl-js/example/mouse-position/)
 * @see [Example: Display a popup](https://www.mapbox.com/mapbox-gl-js/example/popup/)
 * @see [Example: Highlight features within a bounding box](https://www.mapbox.com/mapbox-gl-js/example/using-box-queryrenderedfeatures/)
 * @see [Example: Create a timeline animation](https://www.mapbox.com/mapbox-gl-js/example/timeline-animation/)
 */
class LngLat {
                
                

    constructor(lng        , lat        ) {
        if (isNaN(lng) || isNaN(lat)) {
            throw new Error(`Invalid LngLat object: (${lng}, ${lat})`);
        }
        this.lng = +lng;
        this.lat = +lat;
        if (this.lat > 90 || this.lat < -90) {
            throw new Error('Invalid LngLat latitude value: must be between -90 and 90');
        }
    }

    /**
     * Returns a new `LngLat` object whose longitude is wrapped to the range (-180, 180).
     *
     * @returns {LngLat} The wrapped `LngLat` object.
     * @example
     * const ll = new mapboxgl.LngLat(286.0251, 40.7736);
     * const wrapped = ll.wrap();
     * console.log(wrapped.lng); // = -73.9749
     */
    wrap()         {
        return new LngLat(wrap(this.lng, -180, 180), this.lat);
    }

    /**
     * Returns the coordinates represented as an array of two numbers.
     *
     * @returns {Array<number>} The coordinates represeted as an array of longitude and latitude.
     * @example
     * const ll = new mapboxgl.LngLat(-73.9749, 40.7736);
     * ll.toArray(); // = [-73.9749, 40.7736]
     */
    toArray()                   {
        return [this.lng, this.lat];
    }

    /**
     * Returns the coordinates represent as a string.
     *
     * @returns {string} The coordinates represented as a string of the format `'LngLat(lng, lat)'`.
     * @example
     * const ll = new mapboxgl.LngLat(-73.9749, 40.7736);
     * ll.toString(); // = "LngLat(-73.9749, 40.7736)"
     */
    toString()         {
        return `LngLat(${this.lng}, ${this.lat})`;
    }

    /**
     * Returns the approximate distance between a pair of coordinates in meters.
     * Uses the Haversine Formula (from R.W. Sinnott, "Virtues of the Haversine", Sky and Telescope, vol. 68, no. 2, 1984, p. 159).
     *
     * @param {LngLat} lngLat Coordinates to compute the distance to.
     * @returns {number} Distance in meters between the two coordinates.
     * @example
     * const newYork = new mapboxgl.LngLat(-74.0060, 40.7128);
     * const losAngeles = new mapboxgl.LngLat(-118.2437, 34.0522);
     * newYork.distanceTo(losAngeles); // = 3935751.690893987, "true distance" using a non-spherical approximation is ~3966km
     */
    distanceTo(lngLat        )         {
        const rad = Math.PI / 180;
        const lat1 = this.lat * rad;
        const lat2 = lngLat.lat * rad;
        const a = Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos((lngLat.lng - this.lng) * rad);

        const maxMeters = earthRadius * Math.acos(Math.min(a, 1));
        return maxMeters;
    }

    /**
     * Returns a `LngLatBounds` from the coordinates extended by a given `radius`. The returned `LngLatBounds` completely contains the `radius`.
     *
     * @param {number} [radius=0] Distance in meters from the coordinates to extend the bounds.
     * @returns {LngLatBounds} A new `LngLatBounds` object representing the coordinates extended by the `radius`.
     * @example
     * const ll = new mapboxgl.LngLat(-73.9749, 40.7736);
     * ll.toBounds(100).toArray(); // = [[-73.97501862141328, 40.77351016847229], [-73.97478137858673, 40.77368983152771]]
     */
    toBounds(radius          = 0)               {
        const earthCircumferenceInMetersAtEquator = 40075017;
        const latAccuracy = 360 * radius / earthCircumferenceInMetersAtEquator,
            lngAccuracy = latAccuracy / Math.cos((Math.PI / 180) * this.lat);

        return new LngLatBounds(new LngLat(this.lng - lngAccuracy, this.lat - latAccuracy),
            new LngLat(this.lng + lngAccuracy, this.lat + latAccuracy));
    }

    toEcef(altitude        )                           {
        const altInEcef = globeMetersToEcef(altitude);
        const radius = GLOBE_RADIUS + altInEcef;
        return (latLngToECEF(this.lat, this.lng, radius)     );
    }

    /**
     * Converts an array of two numbers or an object with `lng` and `lat` or `lon` and `lat` properties
     * to a `LngLat` object.
     *
     * If a `LngLat` object is passed in, the function returns it unchanged.
     *
     * @param {LngLatLike} input An array of two numbers or object to convert, or a `LngLat` object to return.
     * @returns {LngLat} A new `LngLat` object, if a conversion occurred, or the original `LngLat` object.
     * @example
     * const arr = [-73.9749, 40.7736];
     * const ll = mapboxgl.LngLat.convert(arr);
     * console.log(ll);   // = LngLat {lng: -73.9749, lat: 40.7736}
     */
    static convert(input            )         {
        if (input instanceof LngLat) {
            return input;
        }
        if (Array.isArray(input) && (input.length === 2 || input.length === 3)) {
            return new LngLat(Number(input[0]), Number(input[1]));
        }
        if (!Array.isArray(input) && typeof input === 'object' && input !== null) {
            return new LngLat(
                // flow can't refine this to have one of lng or lat, so we have to cast to any
                Number('lng' in input ? (input     ).lng : (input     ).lon),
                Number(input.lat)
            );
        }
        throw new Error("`LngLatLike` argument must be specified as a LngLat instance, an object {lng: <lng>, lat: <lat>}, an object {lon: <lng>, lat: <lat>}, or an array of [<lng>, <lat>]");
    }
}

/**
 * A {@link LngLat} object, an array of two numbers representing longitude and latitude,
 * or an object with `lng` and `lat` or `lon` and `lat` properties.
 *
 * @typedef {LngLat | {lng: number, lat: number} | {lon: number, lat: number} | [number, number]} LngLatLike
 * @example
 * const v1 = new mapboxgl.LngLat(-122.420679, 37.772537);
 * const v2 = [-122.420679, 37.772537];
 * const v3 = {lon: -122.420679, lat: 37.772537};
 */
                                                                                                             

var LngLat$1 = LngLat;

//      

                                                  

/*
 * The circumference at a line of latitude in meters.
 */
function circumferenceAtLatitude(latitude        )         {
    return earthCircumference * Math.cos(latitude * Math.PI / 180);
}

function mercatorXfromLng(lng        )         {
    return (180 + lng) / 360;
}

function mercatorYfromLat(lat        )         {
    return (180 - (180 / Math.PI * Math.log(Math.tan(Math.PI / 4 + lat * Math.PI / 360)))) / 360;
}

function mercatorZfromAltitude(altitude        , lat        )         {
    return altitude / circumferenceAtLatitude(lat);
}

function lngFromMercatorX(x        )         {
    return x * 360 - 180;
}

function latFromMercatorY(y        )         {
    const y2 = 180 - y * 360;
    return 360 / Math.PI * Math.atan(Math.exp(y2 * Math.PI / 180)) - 90;
}

function altitudeFromMercatorZ(z        , y        )         {
    return z * circumferenceAtLatitude(latFromMercatorY(y));
}

const MAX_MERCATOR_LATITUDE = 85.051129;

/**
 * Determine the Mercator scale factor for a given latitude, see
 * https://en.wikipedia.org/wiki/Mercator_projection#Scale_factor
 *
 * At the equator the scale factor will be 1, which increases at higher latitudes.
 *
 * @param {number} lat Latitude
 * @returns {number} scale factor
 * @private
 */
function mercatorScale(lat        )         {
    return 1 / Math.cos(lat * Math.PI / 180);
}

/**
 * A `MercatorCoordinate` object represents a projected three dimensional position.
 *
 * `MercatorCoordinate` uses the web mercator projection ([EPSG:3857](https://epsg.io/3857)) with slightly different units:
 * - the size of 1 unit is the width of the projected world instead of the "mercator meter"
 * - the origin of the coordinate space is at the north-west corner instead of the middle.
 *
 * For example, `MercatorCoordinate(0, 0, 0)` is the north-west corner of the mercator world and
 * `MercatorCoordinate(1, 1, 0)` is the south-east corner. If you are familiar with
 * [vector tiles](https://github.com/mapbox/vector-tile-spec) it may be helpful to think
 * of the coordinate space as the `0/0/0` tile with an extent of `1`.
 *
 * The `z` dimension of `MercatorCoordinate` is conformal. A cube in the mercator coordinate space would be rendered as a cube.
 *
 * @param {number} x The x component of the position.
 * @param {number} y The y component of the position.
 * @param {number} z The z component of the position.
 * @example
 * const nullIsland = new mapboxgl.MercatorCoordinate(0.5, 0.5, 0);
 *
 * @see [Example: Add a custom style layer](https://www.mapbox.com/mapbox-gl-js/example/custom-style-layer/)
 */
class MercatorCoordinate {
              
              
              

    constructor(x        , y        , z         = 0) {
        this.x = +x;
        this.y = +y;
        this.z = +z;
    }

    /**
     * Project a `LngLat` to a `MercatorCoordinate`.
     *
     * @param {LngLatLike} lngLatLike The location to project.
     * @param {number} altitude The altitude in meters of the position.
     * @returns {MercatorCoordinate} The projected mercator coordinate.
     * @example
     * const coord = mapboxgl.MercatorCoordinate.fromLngLat({lng: 0, lat: 0}, 0);
     * console.log(coord); // MercatorCoordinate(0.5, 0.5, 0)
     */
    static fromLngLat(lngLatLike            , altitude         = 0)                     {
        const lngLat = LngLat$1.convert(lngLatLike);

        return new MercatorCoordinate(
                mercatorXfromLng(lngLat.lng),
                mercatorYfromLat(lngLat.lat),
                mercatorZfromAltitude(altitude, lngLat.lat));
    }

    /**
     * Returns the `LngLat` for the coordinate.
     *
     * @returns {LngLat} The `LngLat` object.
     * @example
     * const coord = new mapboxgl.MercatorCoordinate(0.5, 0.5, 0);
     * const lngLat = coord.toLngLat(); // LngLat(0, 0)
     */
    toLngLat()         {
        return new LngLat$1(
                lngFromMercatorX(this.x),
                latFromMercatorY(this.y));
    }

    /**
     * Returns the altitude in meters of the coordinate.
     *
     * @returns {number} The altitude in meters.
     * @example
     * const coord = new mapboxgl.MercatorCoordinate(0, 0, 0.02);
     * coord.toAltitude(); // 6914.281956295339
     */
    toAltitude()         {
        return altitudeFromMercatorZ(this.z, this.y);
    }

    /**
     * Returns the distance of 1 meter in `MercatorCoordinate` units at this latitude.
     *
     * For coordinates in real world units using meters, this naturally provides the scale
     * to transform into `MercatorCoordinate`s.
     *
     * @returns {number} Distance of 1 meter in `MercatorCoordinate` units.
     * @example
     * // Calculate a new MercatorCoordinate that is 150 meters west of the other coord.
     * const coord = new mapboxgl.MercatorCoordinate(0.5, 0.25, 0);
     * const offsetInMeters = 150;
     * const offsetInMercatorCoordinateUnits = offsetInMeters * coord.meterInMercatorCoordinateUnits();
     * const westCoord = new mapboxgl.MercatorCoordinate(coord.x - offsetInMercatorCoordinateUnits, coord.y, coord.z);
     */
    meterInMercatorCoordinateUnits()         {
        // 1 meter / circumference at equator in meters * Mercator projection scale factor at this latitude
        return 1 / earthCircumference * mercatorScale(latFromMercatorY(this.y));
    }

}

var MercatorCoordinate$1 = MercatorCoordinate;

//      


function pointToLineDist(px        , py        , ax        , ay        , bx        , by        ) {
    const dx = ax - bx;
    const dy = ay - by;
    return Math.abs((ay - py) * dx - (ax - px) * dy) / Math.hypot(dx, dy);
}

function addResampled(resampled              , mx0        , my0        , mx2        , my2        , start       , end       , reproject                   , tolerance        ) {
    const mx1 = (mx0 + mx2) / 2;
    const my1 = (my0 + my2) / 2;
    const mid = new Point$2(mx1, my1);
    reproject(mid);
    const err = pointToLineDist(mid.x, mid.y, start.x, start.y, end.x, end.y);

    // if reprojected midPoint is too far from geometric midpoint, recurse into two halves
    if (err >= tolerance) {
        // we're very unlikely to hit max call stack exceeded here,
        // but we might want to safeguard against it in the future
        addResampled(resampled, mx0, my0, mx1, my1, start, mid, reproject, tolerance);
        addResampled(resampled, mx1, my1, mx2, my2, mid, end, reproject, tolerance);

    } else { // otherwise, just add the point
        resampled.push(end);
    }
}

// reproject and resample a line, adding point where necessary for lines that become curves;
// note that this operation is mutable (modifying original points) for performance
function resample$1(line              , reproject                 , tolerance        )               {
    let prev = line[0];
    let mx0 = prev.x;
    let my0 = prev.y;
    reproject(prev);
    const resampled = [prev];

    for (let i = 1; i < line.length; i++) {
        const point = line[i];
        const {x, y} = point;
        reproject(point);
        addResampled(resampled, mx0, my0, x, y, prev, point, reproject, tolerance);
        mx0 = x;
        my0 = y;
        prev = point;
    }

    return resampled;
}

function addResampledPred(resampled         , a       , b       , pred                             ) {
    const split = pred(a, b);

    // if the predicate condition is met, recurse into two halves
    if (split) {
        const mid = a.add(b)._mult(0.5);
        addResampledPred(resampled, a, mid, pred);
        addResampledPred(resampled, mid, b, pred);

    } else {
        resampled.push(b);
    }
}

function resamplePred(line         , predicate                           )          {
    let prev = line[0];
    const resampled = [prev];

    for (let i = 1; i < line.length; i++) {
        const point = line[i];
        addResampledPred(resampled, prev, point, predicate);
        prev = point;
    }

    return resampled;
}

//      


                                                          
                                                                       

// These bounds define the minimum and maximum supported coordinate values.
// While visible coordinates are within [0, EXTENT], tiles may theoretically
// contain coordinates within [-Infinity, Infinity]. Our range is limited by the
// number of bits used to represent the coordinate.
const BITS = 15;
const MAX = Math.pow(2, BITS - 1) - 1;
const MIN = -MAX - 1;

function preparePoint(point       , scale        ) {
    const x = Math.round(point.x * scale);
    const y = Math.round(point.y * scale);
    point.x = clamp(x, MIN, MAX);
    point.y = clamp(y, MIN, MAX);
    if (x < point.x || x > point.x + 1 || y < point.y || y > point.y + 1) {
        // warn when exceeding allowed extent except for the 1-px-off case
        // https://github.com/mapbox/mapbox-gl-js/issues/8992
        warnOnce('Geometry exceeds allowed extent, reduce your vector tile buffer size');
    }
    return point;
}

// a subset of VectorTileGeometry
                               
                   
                    
                                        
 

/**
 * Loads a geometry from a VectorTileFeature and scales it to the common extent
 * used internally.
 * @param {VectorTileFeature} feature
 * @private
 */
function loadGeometry(feature                     , canonical                  , tileTransform                )                      {
    const geometry = feature.loadGeometry();
    const extent = feature.extent;
    const extentScale = EXTENT / extent;

    if (canonical && tileTransform && tileTransform.projection.isReprojectedInTileSpace) {
        const z2 = 1 << canonical.z;
        const {scale, x, y, projection} = tileTransform;

        const reproject = (p       ) => {
            const lng = lngFromMercatorX((canonical.x + p.x / extent) / z2);
            const lat = latFromMercatorY((canonical.y + p.y / extent) / z2);
            const p2 = projection.project(lng, lat);
            p.x = (p2.x * scale - x) * extent;
            p.y = (p2.y * scale - y) * extent;
        };

        for (let i = 0; i < geometry.length; i++) {
            if (feature.type !== 1) {
                geometry[i] = resample$1(geometry[i], reproject, 1); // resample lines and polygons

            } else { // points
                const line = [];
                for (const p of geometry[i]) {
                    // filter out point features outside tile boundaries now; it'd be harder to do later
                    // when the coords are reprojected and no longer axis-aligned; ideally this would happen
                    // or not depending on how the geometry is used, but we forego the complexity for now
                    if (p.x < 0 || p.x >= extent || p.y < 0 || p.y >= extent) continue;
                    reproject(p);
                    line.push(p);
                }
                geometry[i] = line;
            }
        }
    }

    for (const line of geometry) {
        for (const p of line) {
            preparePoint(p, extentScale);
        }
    }

    return geometry;
}

//      


                                                
                                                            

                          
                                                                      
              
                                    
                                      
                                 
  

/**
 * Construct a new feature based on a VectorTileFeature for expression evaluation, the geometry of which
 * will be loaded based on necessity.
 * @param {VectorTileFeature} feature
 * @param {boolean} needGeometry
 * @private
 */
function toEvaluationFeature(feature                    , needGeometry         )                    {
    return {type: feature.type,
        id: feature.id,
        properties:feature.properties,
        geometry: needGeometry ? loadGeometry(feature) : []};
}

//      


                                                             
             
           
                     
                  
                   
                      
                      
                                                                                  
                                                                                    
                                               
                                                        
                                                          
                                                
                                                                
                                                         
                                                                          
                                                                       
                                                                 
                                    
                                                          

function addCircleVertex(layoutVertexArray                   , x        , y        , extrudeX        , extrudeY        ) {
    layoutVertexArray.emplaceBack(
        (x * 2) + ((extrudeX + 1) / 2),
        (y * 2) + ((extrudeY + 1) / 2));
}

function addGlobeExtVertex$1(vertexArray                     , pos                                   , normal      ) {
    const encode = 1 << 14;
    vertexArray.emplaceBack(
        pos.x, pos.y, pos.z,
        normal[0] * encode, normal[1] * encode, normal[2] * encode);
}

/**
 * Circles are represented by two triangles.
 *
 * Each corner has a pos that is the center of the circle and an extrusion
 * vector that is where it points.
 * @private
 */
class CircleBucket                                                                {
                  
                 
                        
                            
                         
                                       
                                          

                                         
                                     
                                              
                                        

                                   
                             

                        
                                                          
                            
                      
                                        

    constructor(options                         ) {
        this.zoom = options.zoom;
        this.overscaling = options.overscaling;
        this.layers = options.layers;
        this.layerIds = this.layers.map(layer => layer.id);
        this.index = options.index;
        this.hasPattern = false;
        this.projection = options.projection;

        this.layoutVertexArray = new StructArrayLayout2i4();
        this.indexArray = new StructArrayLayout3ui6();
        this.segments = new SegmentVector();
        this.programConfigurations = new ProgramConfigurationSet(options.layers, options.zoom);
        this.stateDependentLayerIds = this.layers.filter((l) => l.isStateDependent()).map((l) => l.id);
    }

    populate(features                       , options                    , canonical                 , tileTransform               ) {
        const styleLayer = this.layers[0];
        const bucketFeatures = [];
        let circleSortKey = null;

        // Heatmap layers are handled in this bucket and have no evaluated properties, so we check our access
        if (styleLayer.type === 'circle') {
            circleSortKey = ((styleLayer     )                  ).layout.get('circle-sort-key');
        }

        for (const {feature, id, index, sourceLayerIndex} of features) {
            const needGeometry = this.layers[0]._featureFilter.needGeometry;
            const evaluationFeature = toEvaluationFeature(feature, needGeometry);

            // $FlowFixMe[method-unbinding]
            if (!this.layers[0]._featureFilter.filter(new EvaluationParameters(this.zoom), evaluationFeature, canonical)) continue;

            const sortKey = circleSortKey ?
                circleSortKey.evaluate(evaluationFeature, {}, canonical) :
                undefined;

            const bucketFeature                = {
                id,
                properties: feature.properties,
                type: feature.type,
                sourceLayerIndex,
                index,
                geometry: needGeometry ? evaluationFeature.geometry : loadGeometry(feature, canonical, tileTransform),
                patterns: {},
                sortKey
            };

            bucketFeatures.push(bucketFeature);

        }

        if (circleSortKey) {
            bucketFeatures.sort((a, b) => {
                // a.sortKey is always a number when in use
                return ((a.sortKey     )        ) - ((b.sortKey     )        );
            });
        }

        let globeProjection              = null;

        if (tileTransform.projection.name === 'globe') {
            // Extend vertex attributes if the globe projection is enabled
            this.globeExtVertexArray = new StructArrayLayout6i12();
            globeProjection = tileTransform.projection;
        }

        for (const bucketFeature of bucketFeatures) {
            const {geometry, index, sourceLayerIndex} = bucketFeature;
            const feature = features[index].feature;

            this.addFeature(bucketFeature, geometry, index, options.availableImages, canonical, globeProjection);
            options.featureIndex.insert(feature, geometry, index, sourceLayerIndex, this.index);
        }
    }

    update(states               , vtLayer                  , availableImages               , imagePositions                 ) {
        if (!this.stateDependentLayers.length) return;
        this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers, availableImages, imagePositions);
    }

    isEmpty()          {
        return this.layoutVertexArray.length === 0;
    }

    uploadPending()          {
        return !this.uploaded || this.programConfigurations.needsUpload;
    }

    upload(context         ) {
        if (!this.uploaded) {
            this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray, circleAttributes.members);
            this.indexBuffer = context.createIndexBuffer(this.indexArray);

            if (this.globeExtVertexArray) {
                this.globeExtVertexBuffer = context.createVertexBuffer(this.globeExtVertexArray, circleGlobeAttributesExt.members);
            }
        }
        this.programConfigurations.upload(context);
        this.uploaded = true;
    }

    destroy() {
        if (!this.layoutVertexBuffer) return;
        this.layoutVertexBuffer.destroy();
        this.indexBuffer.destroy();
        this.programConfigurations.destroy();
        this.segments.destroy();
        if (this.globeExtVertexBuffer) {
            this.globeExtVertexBuffer.destroy();
        }
    }

    addFeature(feature               , geometry                     , index        , availableImages               , canonical                 , projection              ) {
        for (const ring of geometry) {
            for (const point of ring) {
                const x = point.x;
                const y = point.y;

                // Do not include points that are outside the tile boundaries.
                if (x < 0 || x >= EXTENT || y < 0 || y >= EXTENT) continue;

                // this geometry will be of the Point type, and we'll derive
                // two triangles from it.
                //
                // ┌─────────┐
                // │ 3     2 │
                // │         │
                // │ 0     1 │
                // └─────────┘

                if (projection) {
                    const projectedPoint = projection.projectTilePoint(x, y, canonical);
                    const normal = projection.upVector(canonical, x, y);
                    const array      = this.globeExtVertexArray;

                    addGlobeExtVertex$1(array, projectedPoint, normal);
                    addGlobeExtVertex$1(array, projectedPoint, normal);
                    addGlobeExtVertex$1(array, projectedPoint, normal);
                    addGlobeExtVertex$1(array, projectedPoint, normal);
                }
                const segment = this.segments.prepareSegment(4, this.layoutVertexArray, this.indexArray, feature.sortKey);
                const index = segment.vertexLength;

                addCircleVertex(this.layoutVertexArray, x, y, -1, -1);
                addCircleVertex(this.layoutVertexArray, x, y, 1, -1);
                addCircleVertex(this.layoutVertexArray, x, y, 1, 1);
                addCircleVertex(this.layoutVertexArray, x, y, -1, 1);

                this.indexArray.emplaceBack(index, index + 1, index + 2);
                this.indexArray.emplaceBack(index, index + 2, index + 3);

                segment.vertexLength += 4;
                segment.primitiveLength += 2;
            }
        }

        this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index, {}, availableImages, canonical);
    }
}

register(CircleBucket, 'CircleBucket', {omit: ['layers']});

//      


                                  
                                      
                                  
                                     
                                            

function polygonIntersectsPolygon(polygonA         , polygonB         )          {
    for (let i = 0; i < polygonA.length; i++) {
        if (polygonContainsPoint(polygonB, polygonA[i])) return true;
    }

    for (let i = 0; i < polygonB.length; i++) {
        if (polygonContainsPoint(polygonA, polygonB[i])) return true;
    }

    if (lineIntersectsLine(polygonA, polygonB)) return true;

    return false;
}

function polygonIntersectsBufferedPoint(polygon         , point       , radius        )          {
    if (polygonContainsPoint(polygon, point)) return true;
    if (pointIntersectsBufferedLine(point, polygon, radius)) return true;
    return false;
}

function polygonIntersectsMultiPolygon(polygon         , multiPolygon              )          {

    if (polygon.length === 1) {
        return multiPolygonContainsPoint(multiPolygon, polygon[0]);
    }

    for (let m = 0; m < multiPolygon.length; m++) {
        const ring = multiPolygon[m];
        for (let n = 0; n < ring.length; n++) {
            if (polygonContainsPoint(polygon, ring[n])) return true;
        }
    }

    for (let i = 0; i < polygon.length; i++) {
        if (multiPolygonContainsPoint(multiPolygon, polygon[i])) return true;
    }

    for (let k = 0; k < multiPolygon.length; k++) {
        if (lineIntersectsLine(polygon, multiPolygon[k])) return true;
    }

    return false;
}

function polygonIntersectsBufferedMultiLine(polygon         , multiLine           , radius        )          {
    for (let i = 0; i < multiLine.length; i++) {
        const line = multiLine[i];

        if (polygon.length >= 3) {
            for (let k = 0; k < line.length; k++) {
                if (polygonContainsPoint(polygon, line[k])) return true;
            }
        }

        if (lineIntersectsBufferedLine(polygon, line, radius)) return true;
    }
    return false;
}

function lineIntersectsBufferedLine(lineA      , lineB      , radius        ) {

    if (lineA.length > 1) {
        if (lineIntersectsLine(lineA, lineB)) return true;

        // Check whether any point in either line is within radius of the other line
        for (let j = 0; j < lineB.length; j++) {
            if (pointIntersectsBufferedLine(lineB[j], lineA, radius)) return true;
        }
    }

    for (let k = 0; k < lineA.length; k++) {
        if (pointIntersectsBufferedLine(lineA[k], lineB, radius)) return true;
    }

    return false;
}

function lineIntersectsLine(lineA      , lineB      ) {
    if (lineA.length === 0 || lineB.length === 0) return false;
    for (let i = 0; i < lineA.length - 1; i++) {
        const a0 = lineA[i];
        const a1 = lineA[i + 1];
        for (let j = 0; j < lineB.length - 1; j++) {
            const b0 = lineB[j];
            const b1 = lineB[j + 1];
            if (lineSegmentIntersectsLineSegment(a0, a1, b0, b1)) return true;
        }
    }
    return false;
}

function lineSegmentIntersectsLineSegment(a0       , a1       , b0       , b1       ) {
    return isCounterClockwise(a0, b0, b1) !== isCounterClockwise(a1, b0, b1) &&
        isCounterClockwise(a0, a1, b0) !== isCounterClockwise(a0, a1, b1);
}

function pointIntersectsBufferedLine(p       , line      , radius        ) {
    const radiusSquared = radius * radius;

    if (line.length === 1) return p.distSqr(line[0]) < radiusSquared;

    for (let i = 1; i < line.length; i++) {
        // Find line segments that have a distance <= radius^2 to p
        // In that case, we treat the line as "containing point p".
        const v = line[i - 1], w = line[i];
        if (distToSegmentSquared(p, v, w) < radiusSquared) return true;
    }
    return false;
}

// Code from http://stackoverflow.com/a/1501725/331379.
function distToSegmentSquared(p       , v       , w       )         {
    const l2 = v.distSqr(w);
    if (l2 === 0) return p.distSqr(v);
    const t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2;
    if (t < 0) return p.distSqr(v);
    if (t > 1) return p.distSqr(w);
    return p.distSqr(w.sub(v)._mult(t)._add(v));
}

// point in polygon ray casting algorithm
function multiPolygonContainsPoint(rings              , p       ) {
    let c = false,
        ring, p1, p2;

    for (let k = 0; k < rings.length; k++) {
        ring = rings[k];
        for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {
            p1 = ring[i];
            p2 = ring[j];
            if (((p1.y > p.y) !== (p2.y > p.y)) && (p.x < (p2.x - p1.x) * (p.y - p1.y) / (p2.y - p1.y) + p1.x)) {
                c = !c;
            }
        }
    }
    return c;
}

function polygonContainsPoint(ring      , p       )          {
    let c = false;
    for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {
        const p1 = ring[i];
        const p2 = ring[j];
        if (((p1.y > p.y) !== (p2.y > p.y)) && (p.x < (p2.x - p1.x) * (p.y - p1.y) / (p2.y - p1.y) + p1.x)) {
            c = !c;
        }
    }
    return c;
}

function polygonIntersectsBox(ring      , boxX1        , boxY1        , boxX2        , boxY2        )          {
    for (const p of ring) {
        if (boxX1 <= p.x &&
            boxY1 <= p.y &&
            boxX2 >= p.x &&
            boxY2 >= p.y) return true;
    }

    const corners = [
        new Point$2(boxX1, boxY1),
        new Point$2(boxX1, boxY2),
        new Point$2(boxX2, boxY2),
        new Point$2(boxX2, boxY1)];

    if (ring.length > 2) {
        for (const corner of corners) {
            if (polygonContainsPoint(ring, corner)) return true;
        }
    }

    for (let i = 0; i < ring.length - 1; i++) {
        const p1 = ring[i];
        const p2 = ring[i + 1];
        if (edgeIntersectsBox(p1, p2, corners)) return true;
    }

    return false;
}

function edgeIntersectsBox(e1       , e2       , corners              ) {
    const tl = corners[0];
    const br = corners[2];
    // the edge and box do not intersect in either the x or y dimensions
    if (((e1.x < tl.x) && (e2.x < tl.x)) ||
        ((e1.x > br.x) && (e2.x > br.x)) ||
        ((e1.y < tl.y) && (e2.y < tl.y)) ||
        ((e1.y > br.y) && (e2.y > br.y))) return false;

    // check if all corners of the box are on the same side of the edge
    const dir = isCounterClockwise(e1, e2, corners[0]);
    return dir !== isCounterClockwise(e1, e2, corners[1]) ||
        dir !== isCounterClockwise(e1, e2, corners[2]) ||
        dir !== isCounterClockwise(e1, e2, corners[3]);
}

//      


                                                                    
                                                      
                                                                
                                                            

function getMaximumPaintValue(property        , layer            , bucket                              )         {
    const value = ((layer.paint     ).get(property)                                     ).value;
    if (value.kind === 'constant') {
        return value.value;
    } else {
        return bucket.programConfigurations.get(layer.id).getMaxValue(property);
    }
}

function translateDistance(translate                  )         {
    return Math.sqrt(translate[0] * translate[0] + translate[1] * translate[1]);
}

function translate(queryGeometry              ,
                   translate                  ,
                   translateAnchor                    ,
                   bearing        ,
                   pixelsToTileUnits        )               {
    if (!translate[0] && !translate[1]) {
        return queryGeometry;
    }
    const pt = Point$2.convert(translate)._mult(pixelsToTileUnits);

    if (translateAnchor === "viewport") {
        pt._rotate(-bearing);
    }

    const translated = [];
    for (let i = 0; i < queryGeometry.length; i++) {
        const point = queryGeometry[i];
        translated.push(point.sub(pt));
    }
    return translated;
}

function tilespaceTranslate(translate                  ,
                    translateAnchor                    ,
                    bearing        ,
                    pixelsToTileUnits        )        {
    const pt = Point$2.convert(translate)._mult(pixelsToTileUnits);

    if (translateAnchor === "viewport") {
        pt._rotate(-bearing);
    }

    return pt;
}

// This file is generated. Edit build/generate-style-code.js, then run `yarn run codegen`.
//      
/* eslint-disable */


                                                        

                                                                            

                                                                                     

                            
                                                  
   

const layout$5                          = new Properties({
    "circle-sort-key": new DataDrivenProperty(spec["layout_circle"]["circle-sort-key"]),
});

                           
                                                
                                              
                                              
                                                 
                                                               
                                                                        
                                                                   
                                                                       
                                                      
                                                     
                                                        
   

const paint$9                         = new Properties({
    "circle-radius": new DataDrivenProperty(spec["paint_circle"]["circle-radius"]),
    "circle-color": new DataDrivenProperty(spec["paint_circle"]["circle-color"]),
    "circle-blur": new DataDrivenProperty(spec["paint_circle"]["circle-blur"]),
    "circle-opacity": new DataDrivenProperty(spec["paint_circle"]["circle-opacity"]),
    "circle-translate": new DataConstantProperty(spec["paint_circle"]["circle-translate"]),
    "circle-translate-anchor": new DataConstantProperty(spec["paint_circle"]["circle-translate-anchor"]),
    "circle-pitch-scale": new DataConstantProperty(spec["paint_circle"]["circle-pitch-scale"]),
    "circle-pitch-alignment": new DataConstantProperty(spec["paint_circle"]["circle-pitch-alignment"]),
    "circle-stroke-width": new DataDrivenProperty(spec["paint_circle"]["circle-stroke-width"]),
    "circle-stroke-color": new DataDrivenProperty(spec["paint_circle"]["circle-stroke-color"]),
    "circle-stroke-opacity": new DataDrivenProperty(spec["paint_circle"]["circle-stroke-opacity"]),
});

// Note: without adding the explicit type annotation, Flow infers weaker types
// for these objects from their use in the constructor to StyleLayer, as
// {layout?: Properties<...>, paint: Properties<...>}
var properties$9 = ({ paint: paint$9, layout: layout$5 }          
                                                                
  );

//      


                                                                       
                                                    
                                                                   
                                                                                
                                                                  
                                                                 
                                                           
                                                            

class CircleStyleLayer extends StyleLayer {
                                            
                                           

                                                     
                                                   
                                         

    constructor(layer                    ) {
        super(layer, properties$9);
    }

    createBucket(parameters                                    )                                 {
        return new CircleBucket(parameters);
    }

    // $FlowFixMe[method-unbinding]
    queryRadius(bucket        )         {
        const circleBucket                                 = (bucket     );
        return getMaximumPaintValue('circle-radius', this, circleBucket) +
            getMaximumPaintValue('circle-stroke-width', this, circleBucket) +
            translateDistance(this.paint.get('circle-translate'));
    }

    // $FlowFixMe[method-unbinding]
    queryIntersectsFeature(queryGeometry                        ,
                           feature                    ,
                           featureState              ,
                           geometry                     ,
                           zoom        ,
                           transform           ,
                           pixelPosMatrix              ,
                           elevationHelper             )          {

        const translation = tilespaceTranslate(
            this.paint.get('circle-translate'),
            this.paint.get('circle-translate-anchor'),
            transform.angle, queryGeometry.pixelToTileUnitsFactor);

        const size = this.paint.get('circle-radius').evaluate(feature, featureState) +
            this.paint.get('circle-stroke-width').evaluate(feature, featureState);

        return queryIntersectsCircle(queryGeometry, geometry, transform, pixelPosMatrix, elevationHelper,
            this.paint.get('circle-pitch-alignment') === 'map',
            this.paint.get('circle-pitch-scale') === 'map', translation, size);
    }

    getProgramIds()                {
        return ['circle'];
    }

    getProgramConfiguration(zoom        )                       {
        return new ProgramConfiguration(this, zoom);
    }
}

function queryIntersectsCircle(queryGeometry                        ,
                       geometry                     ,
                       transform           ,
                       pixelPosMatrix              ,
                       elevationHelper             ,
                       alignWithMap         ,
                       scaleWithMap         ,
                       translation       ,
                       size        )          {
    if (alignWithMap && queryGeometry.queryGeometry.isAboveHorizon) return false;

    // For pitch-alignment: map, compare feature geometry to query geometry in the plane of the tile
    // // Otherwise, compare geometry in the plane of the viewport
    // // A circle with fixed scaling relative to the viewport gets larger in tile space as it moves into the distance
    // // A circle with fixed scaling relative to the map gets smaller in viewport space as it moves into the distance
    if (alignWithMap) size *= queryGeometry.pixelToTileUnitsFactor;

    const tileId = queryGeometry.tileID.canonical;
    const elevationScale = transform.projection.upVectorScale(tileId, transform.center.lat, transform.worldSize).metersToTile;

    for (const ring of geometry) {
        for (const point of ring) {
            const translatedPoint = point.add(translation);
            const z = (elevationHelper && transform.elevation) ?
                transform.elevation.exaggeration() * elevationHelper.getElevationAt(translatedPoint.x, translatedPoint.y, true) :
                0;

            // Reproject tile coordinate to the local coordinate space used by the projection
            const reproj = transform.projection.projectTilePoint(translatedPoint.x, translatedPoint.y, tileId);

            if (z > 0) {
                const dir = transform.projection.upVector(tileId, translatedPoint.x, translatedPoint.y);
                reproj.x += dir[0] * elevationScale * z;
                reproj.y += dir[1] * elevationScale * z;
                reproj.z += dir[2] * elevationScale * z;
            }

            const transformedPoint = alignWithMap ? translatedPoint : projectPoint(reproj.x, reproj.y, reproj.z, pixelPosMatrix);
            const transformedPolygon = alignWithMap ?
                queryGeometry.tilespaceRays.map((r) => intersectAtHeight(r, z)) :
                queryGeometry.queryGeometry.screenGeometry;

            const projectedCenter = transformMat4$1([], [reproj.x, reproj.y, reproj.z, 1], pixelPosMatrix);
            if (!scaleWithMap && alignWithMap) {
                size *= projectedCenter[3] / transform.cameraToCenterDistance;
            } else if (scaleWithMap && !alignWithMap) {
                size *= transform.cameraToCenterDistance / projectedCenter[3];
            }

            if (alignWithMap) {
                // Apply extra scaling to cover different pixelPerMeter ratios at different latitudes
                const lat = latFromMercatorY((point.y / EXTENT + tileId.y) / (1 << tileId.z));
                const scale = transform.projection.pixelsPerMeter(lat, 1) / mercatorZfromAltitude(1, lat);

                size /= scale;
            }

            if (polygonIntersectsBufferedPoint(transformedPolygon, transformedPoint, size)) return true;
        }
    }

    return false;
}

function projectPoint(x        , y        , z        , pixelPosMatrix              ) {
    const point = transformMat4$1([], [x, y, z, 1], pixelPosMatrix);
    return new Point$2(point[0] / point[3], point[1] / point[3]);
}

const origin = fromValues$4(0, 0, 0);
const up = fromValues$4(0, 0, 1);

function intersectAtHeight(r     , z        )        {
    const intersectionPt = create$4();
    origin[2] = z;
    const intersects = r.intersectsPlane(origin, up, intersectionPt);
    assert$1(intersects, 'tilespacePoint should always be below horizon, and since camera cannot have pitch >90, ray should always intersect');

    return new Point$2(intersectionPt[0], intersectionPt[1]);
}

//      


                                                                                    

class HeatmapBucket extends CircleBucket                    {
    // Needed for flow to accept omit: ['layers'] below, due to
    // https://github.com/facebook/flow/issues/4262
                                     
}

register(HeatmapBucket, 'HeatmapBucket', {omit: ['layers']});

//      


                              
                  
                   
  

                                 
                          
                          
                        
 
                                                            

              
              
             
  

function createImage                           (image   , {width, height}      , channels        , data                                 )    {
    if (!data) {
        data = new Uint8Array(width * height * channels);
    } else if (data instanceof Uint8ClampedArray) {
        data = new Uint8Array(data.buffer);
    } else if (data.length !== width * height * channels) {
        throw new RangeError('mismatched image size');
    }
    image.width = width;
    image.height = height;
    image.data = data;
    return image;
}

function resizeImage                           (image   , newImage   , channels        ) {
    const {width, height} = newImage;
    if (width === image.width && height === image.height) {
        return;
    }

    copyImage(image, newImage, {x: 0, y: 0}, {x: 0, y: 0}, {
        width: Math.min(image.width, width),
        height: Math.min(image.height, height)
    }, channels);

    image.width = width;
    image.height = height;
    image.data = newImage.data;
}

function copyImage                           (srcImg               , dstImg   , srcPt       , dstPt       , size      , channels        )    {
    if (size.width === 0 || size.height === 0) {
        return dstImg;
    }

    if (size.width > srcImg.width ||
        size.height > srcImg.height ||
        srcPt.x > srcImg.width - size.width ||
        srcPt.y > srcImg.height - size.height) {
        throw new RangeError('out of range source coordinates for image copy');
    }

    if (size.width > dstImg.width ||
        size.height > dstImg.height ||
        dstPt.x > dstImg.width - size.width ||
        dstPt.y > dstImg.height - size.height) {
        throw new RangeError('out of range destination coordinates for image copy');
    }

    const srcData = srcImg.data;
    const dstData = dstImg.data;

    assert$1(srcData !== dstData);

    for (let y = 0; y < size.height; y++) {
        const srcOffset = ((srcPt.y + y) * srcImg.width + srcPt.x) * channels;
        const dstOffset = ((dstPt.y + y) * dstImg.width + dstPt.x) * channels;
        for (let i = 0; i < size.width * channels; i++) {
            dstData[dstOffset + i] = srcData[srcOffset + i];
        }
    }
    return dstImg;
}

class AlphaImage {
                  
                   
                     

    constructor(size      , data                                 ) {
        createImage(this, size, 1, data);
    }

    resize(size      ) {
        resizeImage(this, new AlphaImage(size), 1);
    }

    clone()             {
        return new AlphaImage({width: this.width, height: this.height}, new Uint8Array(this.data));
    }

    static copy(srcImg            , dstImg            , srcPt       , dstPt       , size      ) {
        copyImage(srcImg, dstImg, srcPt, dstPt, size, 1);
    }
}

// Not premultiplied, because ImageData is not premultiplied.
// UNPACK_PREMULTIPLY_ALPHA_WEBGL must be used when uploading to a texture.
class RGBAImage {
                  
                   

    // data must be a Uint8Array instead of Uint8ClampedArray because texImage2D does not
    // support Uint8ClampedArray in all browsers
                     

    constructor(size      , data                                 ) {
        createImage(this, size, 4, data);
    }

    resize(size      ) {
        resizeImage(this, new RGBAImage(size), 4);
    }

    replace(data                                , copy          ) {
        if (copy) {
            this.data.set(data);
        } else if (data instanceof Uint8ClampedArray) {
            this.data = new Uint8Array(data.buffer);
        } else {
            this.data = data;
        }
    }

    clone()            {
        return new RGBAImage({width: this.width, height: this.height}, new Uint8Array(this.data));
    }

    static copy(srcImg                       , dstImg           , srcPt       , dstPt       , size      ) {
        copyImage(srcImg, dstImg, srcPt, dstPt, size, 4);
    }
}

register(AlphaImage, 'AlphaImage');
register(RGBAImage, 'RGBAImage');

// This file is generated. Edit build/generate-style-code.js, then run `yarn run codegen`.
//      
/* eslint-disable */


                                                        

                                                                            

                                                                                     


                           
                                                 
                                                 
                                                      
                                       
                                                    
   

const paint$8                         = new Properties({
    "heatmap-radius": new DataDrivenProperty(spec["paint_heatmap"]["heatmap-radius"]),
    "heatmap-weight": new DataDrivenProperty(spec["paint_heatmap"]["heatmap-weight"]),
    "heatmap-intensity": new DataConstantProperty(spec["paint_heatmap"]["heatmap-intensity"]),
    "heatmap-color": new ColorRampProperty(spec["paint_heatmap"]["heatmap-color"]),
    "heatmap-opacity": new DataConstantProperty(spec["paint_heatmap"]["heatmap-opacity"]),
});

// Note: without adding the explicit type annotation, Flow infers weaker types
// for these objects from their use in the constructor to StyleLayer, as
// {layout?: Properties<...>, paint: Properties<...>}
var properties$8 = ({ paint: paint$8 }          
                               
  );

//      


                                                                               

                               
                                        
                          
                        
                      
                          
 

/**
 * Given an expression that should evaluate to a color ramp,
 * return a RGBA image representing that ramp expression.
 *
 * @private
 */
function renderColorRamp(params                 )            {
    const evaluationGlobals = {};
    const width = params.resolution || 256;
    const height = params.clips ? params.clips.length : 1;
    const image = params.image || new RGBAImage({width, height});

    assert$1(isPowerOfTwo(width));

    const renderPixel = (stride        , index        , progress        ) => {
        evaluationGlobals[params.evaluationKey] = progress;
        const pxColor = params.expression.evaluate((evaluationGlobals     ));
        // the colors are being unpremultiplied because Color uses
        // premultiplied values, and the Texture class expects unpremultiplied ones
        image.data[stride + index + 0] = Math.floor(pxColor.r * 255 / pxColor.a);
        image.data[stride + index + 1] = Math.floor(pxColor.g * 255 / pxColor.a);
        image.data[stride + index + 2] = Math.floor(pxColor.b * 255 / pxColor.a);
        image.data[stride + index + 3] = Math.floor(pxColor.a * 255);
    };

    if (!params.clips) {
        for (let i = 0, j = 0; i < width; i++, j += 4) {
            const progress = i / (width - 1);

            renderPixel(0, j, progress);
        }
    } else {
        for (let clip = 0, stride = 0; clip < height; ++clip, stride += width * 4) {
            for (let i = 0, j = 0; i < width; i++, j += 4) {
                // Remap progress between clips
                const progress = i / (width - 1);
                const {start, end} = params.clips[clip];
                const evaluationProgress = start * (1 - progress) + end * progress;
                renderPixel(stride, j, evaluationProgress);
            }
        }
    }

    return image;
}

//      

                                                                 
                                                           
                                                                       
                                                    
                                                                   
                                                            

class HeatmapStyleLayer extends StyleLayer {

                             
                         
                               

                                                     
                                                   
                                         

    createBucket(parameters                                     )                {
        return new HeatmapBucket(parameters);
    }

    constructor(layer                    ) {
        super(layer, properties$8);

        // make sure color ramp texture is generated for default heatmap color too
        this._updateColorRamp();
    }

    _handleSpecialPaintPropertyUpdate(name        ) {
        if (name === 'heatmap-color') {
            this._updateColorRamp();
        }
    }

    _updateColorRamp() {
        const expression = this._transitionablePaint._values['heatmap-color'].value.expression;
        this.colorRamp = renderColorRamp({
            expression,
            evaluationKey: 'heatmapDensity',
            image: this.colorRamp
        });
        this.colorRampTexture = null;
    }

    resize() {
        if (this.heatmapFbo) {
            this.heatmapFbo.destroy();
            this.heatmapFbo = null;
        }
    }

    // $FlowFixMe[method-unbinding]
    queryRadius(bucket        )         {
        return getMaximumPaintValue('heatmap-radius', this, ((bucket     )                 ));
    }

    // $FlowFixMe[method-unbinding]
    queryIntersectsFeature(queryGeometry                        ,
                           feature                    ,
                           featureState              ,
                           geometry                     ,
                           zoom        ,
                           transform           ,
                           pixelPosMatrix              ,
                           elevationHelper             )          {

        const size = this.paint.get('heatmap-radius').evaluate(feature, featureState);
        return queryIntersectsCircle(
            queryGeometry, geometry, transform, pixelPosMatrix, elevationHelper,
            true, true, new Point$2(0, 0), size);
    }

    hasOffscreenPass()          {
        return this.paint.get('heatmap-opacity') !== 0 && this.visibility !== 'none';
    }

    getProgramIds()                {
        return ['heatmap', 'heatmapTexture'];
    }

    getProgramConfiguration(zoom        )                       {
        return new ProgramConfiguration(this, zoom);
    }
}

// This file is generated. Edit build/generate-style-code.js, then run `yarn run codegen`.
//      
/* eslint-disable */


                                                        

                                                                            

                                                                                     


                           
                                                                     
                                                                              
                                                           
                                                          
                                                             
                                                          
   

const paint$7                         = new Properties({
    "hillshade-illumination-direction": new DataConstantProperty(spec["paint_hillshade"]["hillshade-illumination-direction"]),
    "hillshade-illumination-anchor": new DataConstantProperty(spec["paint_hillshade"]["hillshade-illumination-anchor"]),
    "hillshade-exaggeration": new DataConstantProperty(spec["paint_hillshade"]["hillshade-exaggeration"]),
    "hillshade-shadow-color": new DataConstantProperty(spec["paint_hillshade"]["hillshade-shadow-color"]),
    "hillshade-highlight-color": new DataConstantProperty(spec["paint_hillshade"]["hillshade-highlight-color"]),
    "hillshade-accent-color": new DataConstantProperty(spec["paint_hillshade"]["hillshade-accent-color"]),
});

// Note: without adding the explicit type annotation, Flow infers weaker types
// for these objects from their use in the constructor to StyleLayer, as
// {layout?: Properties<...>, paint: Properties<...>}
var properties$7 = ({ paint: paint$7 }          
                               
  );

//      


                                                                      
                                                                  

class HillshadeStyleLayer extends StyleLayer {
                                                     
                                                   
                                         

    constructor(layer                    ) {
        super(layer, properties$7);
    }

    hasOffscreenPass()          {
        return this.paint.get('hillshade-exaggeration') !== 0 && this.visibility !== 'none';
    }

    getProgramIds()                {
        return ['hillshade', 'hillshadePrepare'];
    }
}

//      

                                                                  

const layout$4                    = createLayout([
    {name: 'a_pos', components: 2, type: 'Int16'}
], 4);
const {members: members$3, size: size$3, alignment: alignment$3} = layout$4;

var earcut$2 = {exports: {}};

var earcut_1 = earcut$2.exports;

'use strict';

earcut$2.exports = earcut;
var _default = earcut$2.exports.default = earcut;

function earcut(data, holeIndices, dim) {

    dim = dim || 2;

    var hasHoles = holeIndices && holeIndices.length,
        outerLen = hasHoles ? holeIndices[0] * dim : data.length,
        outerNode = linkedList(data, 0, outerLen, dim, true),
        triangles = [];

    if (!outerNode || outerNode.next === outerNode.prev) return triangles;

    var minX, minY, maxX, maxY, x, y, invSize;

    if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);

    // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox
    if (data.length > 80 * dim) {
        minX = maxX = data[0];
        minY = maxY = data[1];

        for (var i = dim; i < outerLen; i += dim) {
            x = data[i];
            y = data[i + 1];
            if (x < minX) minX = x;
            if (y < minY) minY = y;
            if (x > maxX) maxX = x;
            if (y > maxY) maxY = y;
        }

        // minX, minY and invSize are later used to transform coords into integers for z-order calculation
        invSize = Math.max(maxX - minX, maxY - minY);
        invSize = invSize !== 0 ? 32767 / invSize : 0;
    }

    earcutLinked(outerNode, triangles, dim, minX, minY, invSize, 0);

    return triangles;
}

// create a circular doubly linked list from polygon points in the specified winding order
function linkedList(data, start, end, dim, clockwise) {
    var i, last;

    if (clockwise === (signedArea$1(data, start, end, dim) > 0)) {
        for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);
    } else {
        for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);
    }

    if (last && equals(last, last.next)) {
        removeNode(last);
        last = last.next;
    }

    return last;
}

// eliminate colinear or duplicate points
function filterPoints(start, end) {
    if (!start) return start;
    if (!end) end = start;

    var p = start,
        again;
    do {
        again = false;

        if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {
            removeNode(p);
            p = end = p.prev;
            if (p === p.next) break;
            again = true;

        } else {
            p = p.next;
        }
    } while (again || p !== end);

    return end;
}

// main ear slicing loop which triangulates a polygon (given as a linked list)
function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {
    if (!ear) return;

    // interlink polygon nodes in z-order
    if (!pass && invSize) indexCurve(ear, minX, minY, invSize);

    var stop = ear,
        prev, next;

    // iterate through ears, slicing them one by one
    while (ear.prev !== ear.next) {
        prev = ear.prev;
        next = ear.next;

        if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) {
            // cut off the triangle
            triangles.push(prev.i / dim | 0);
            triangles.push(ear.i / dim | 0);
            triangles.push(next.i / dim | 0);

            removeNode(ear);

            // skipping the next vertex leads to less sliver triangles
            ear = next.next;
            stop = next.next;

            continue;
        }

        ear = next;

        // if we looped through the whole remaining polygon and can't find any more ears
        if (ear === stop) {
            // try filtering points and slicing again
            if (!pass) {
                earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1);

            // if this didn't work, try curing all small self-intersections locally
            } else if (pass === 1) {
                ear = cureLocalIntersections(filterPoints(ear), triangles, dim);
                earcutLinked(ear, triangles, dim, minX, minY, invSize, 2);

            // as a last resort, try splitting the remaining polygon into two
            } else if (pass === 2) {
                splitEarcut(ear, triangles, dim, minX, minY, invSize);
            }

            break;
        }
    }
}

// check whether a polygon node forms a valid ear with adjacent nodes
function isEar(ear) {
    var a = ear.prev,
        b = ear,
        c = ear.next;

    if (area(a, b, c) >= 0) return false; // reflex, can't be an ear

    // now make sure we don't have other points inside the potential ear
    var ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;

    // triangle bbox; min & max are calculated like this for speed
    var x0 = ax < bx ? (ax < cx ? ax : cx) : (bx < cx ? bx : cx),
        y0 = ay < by ? (ay < cy ? ay : cy) : (by < cy ? by : cy),
        x1 = ax > bx ? (ax > cx ? ax : cx) : (bx > cx ? bx : cx),
        y1 = ay > by ? (ay > cy ? ay : cy) : (by > cy ? by : cy);

    var p = c.next;
    while (p !== a) {
        if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 &&
            pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) &&
            area(p.prev, p, p.next) >= 0) return false;
        p = p.next;
    }

    return true;
}

function isEarHashed(ear, minX, minY, invSize) {
    var a = ear.prev,
        b = ear,
        c = ear.next;

    if (area(a, b, c) >= 0) return false; // reflex, can't be an ear

    var ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;

    // triangle bbox; min & max are calculated like this for speed
    var x0 = ax < bx ? (ax < cx ? ax : cx) : (bx < cx ? bx : cx),
        y0 = ay < by ? (ay < cy ? ay : cy) : (by < cy ? by : cy),
        x1 = ax > bx ? (ax > cx ? ax : cx) : (bx > cx ? bx : cx),
        y1 = ay > by ? (ay > cy ? ay : cy) : (by > cy ? by : cy);

    // z-order range for the current triangle bbox;
    var minZ = zOrder(x0, y0, minX, minY, invSize),
        maxZ = zOrder(x1, y1, minX, minY, invSize);

    var p = ear.prevZ,
        n = ear.nextZ;

    // look for points inside the triangle in both directions
    while (p && p.z >= minZ && n && n.z <= maxZ) {
        if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c &&
            pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
        p = p.prevZ;

        if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c &&
            pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;
        n = n.nextZ;
    }

    // look for remaining points in decreasing z-order
    while (p && p.z >= minZ) {
        if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c &&
            pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
        p = p.prevZ;
    }

    // look for remaining points in increasing z-order
    while (n && n.z <= maxZ) {
        if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c &&
            pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;
        n = n.nextZ;
    }

    return true;
}

// go through all polygon nodes and cure small local self-intersections
function cureLocalIntersections(start, triangles, dim) {
    var p = start;
    do {
        var a = p.prev,
            b = p.next.next;

        if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {

            triangles.push(a.i / dim | 0);
            triangles.push(p.i / dim | 0);
            triangles.push(b.i / dim | 0);

            // remove two nodes involved
            removeNode(p);
            removeNode(p.next);

            p = start = b;
        }
        p = p.next;
    } while (p !== start);

    return filterPoints(p);
}

// try splitting polygon into two and triangulate them independently
function splitEarcut(start, triangles, dim, minX, minY, invSize) {
    // look for a valid diagonal that divides the polygon into two
    var a = start;
    do {
        var b = a.next.next;
        while (b !== a.prev) {
            if (a.i !== b.i && isValidDiagonal(a, b)) {
                // split the polygon in two by the diagonal
                var c = splitPolygon(a, b);

                // filter colinear points around the cuts
                a = filterPoints(a, a.next);
                c = filterPoints(c, c.next);

                // run earcut on each half
                earcutLinked(a, triangles, dim, minX, minY, invSize, 0);
                earcutLinked(c, triangles, dim, minX, minY, invSize, 0);
                return;
            }
            b = b.next;
        }
        a = a.next;
    } while (a !== start);
}

// link every hole into the outer loop, producing a single-ring polygon without holes
function eliminateHoles(data, holeIndices, outerNode, dim) {
    var queue = [],
        i, len, start, end, list;

    for (i = 0, len = holeIndices.length; i < len; i++) {
        start = holeIndices[i] * dim;
        end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
        list = linkedList(data, start, end, dim, false);
        if (list === list.next) list.steiner = true;
        queue.push(getLeftmost(list));
    }

    queue.sort(compareX);

    // process holes from left to right
    for (i = 0; i < queue.length; i++) {
        outerNode = eliminateHole(queue[i], outerNode);
    }

    return outerNode;
}

function compareX(a, b) {
    return a.x - b.x;
}

// find a bridge between vertices that connects hole with an outer ring and and link it
function eliminateHole(hole, outerNode) {
    var bridge = findHoleBridge(hole, outerNode);
    if (!bridge) {
        return outerNode;
    }

    var bridgeReverse = splitPolygon(bridge, hole);

    // filter collinear points around the cuts
    filterPoints(bridgeReverse, bridgeReverse.next);
    return filterPoints(bridge, bridge.next);
}

// David Eberly's algorithm for finding a bridge between hole and outer polygon
function findHoleBridge(hole, outerNode) {
    var p = outerNode,
        hx = hole.x,
        hy = hole.y,
        qx = -Infinity,
        m;

    // find a segment intersected by a ray from the hole's leftmost point to the left;
    // segment's endpoint with lesser x will be potential connection point
    do {
        if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {
            var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
            if (x <= hx && x > qx) {
                qx = x;
                m = p.x < p.next.x ? p : p.next;
                if (x === hx) return m; // hole touches outer segment; pick leftmost endpoint
            }
        }
        p = p.next;
    } while (p !== outerNode);

    if (!m) return null;

    // look for points inside the triangle of hole point, segment intersection and endpoint;
    // if there are no points found, we have a valid connection;
    // otherwise choose the point of the minimum angle with the ray as connection point

    var stop = m,
        mx = m.x,
        my = m.y,
        tanMin = Infinity,
        tan;

    p = m;

    do {
        if (hx >= p.x && p.x >= mx && hx !== p.x &&
                pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {

            tan = Math.abs(hy - p.y) / (hx - p.x); // tangential

            if (locallyInside(p, hole) &&
                (tan < tanMin || (tan === tanMin && (p.x > m.x || (p.x === m.x && sectorContainsSector(m, p)))))) {
                m = p;
                tanMin = tan;
            }
        }

        p = p.next;
    } while (p !== stop);

    return m;
}

// whether sector in vertex m contains sector in vertex p in the same coordinates
function sectorContainsSector(m, p) {
    return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0;
}

// interlink polygon nodes in z-order
function indexCurve(start, minX, minY, invSize) {
    var p = start;
    do {
        if (p.z === 0) p.z = zOrder(p.x, p.y, minX, minY, invSize);
        p.prevZ = p.prev;
        p.nextZ = p.next;
        p = p.next;
    } while (p !== start);

    p.prevZ.nextZ = null;
    p.prevZ = null;

    sortLinked(p);
}

// Simon Tatham's linked list merge sort algorithm
// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
function sortLinked(list) {
    var i, p, q, e, tail, numMerges, pSize, qSize,
        inSize = 1;

    do {
        p = list;
        list = null;
        tail = null;
        numMerges = 0;

        while (p) {
            numMerges++;
            q = p;
            pSize = 0;
            for (i = 0; i < inSize; i++) {
                pSize++;
                q = q.nextZ;
                if (!q) break;
            }
            qSize = inSize;

            while (pSize > 0 || (qSize > 0 && q)) {

                if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) {
                    e = p;
                    p = p.nextZ;
                    pSize--;
                } else {
                    e = q;
                    q = q.nextZ;
                    qSize--;
                }

                if (tail) tail.nextZ = e;
                else list = e;

                e.prevZ = tail;
                tail = e;
            }

            p = q;
        }

        tail.nextZ = null;
        inSize *= 2;

    } while (numMerges > 1);

    return list;
}

// z-order of a point given coords and inverse of the longer side of data bbox
function zOrder(x, y, minX, minY, invSize) {
    // coords are transformed into non-negative 15-bit integer range
    x = (x - minX) * invSize | 0;
    y = (y - minY) * invSize | 0;

    x = (x | (x << 8)) & 0x00FF00FF;
    x = (x | (x << 4)) & 0x0F0F0F0F;
    x = (x | (x << 2)) & 0x33333333;
    x = (x | (x << 1)) & 0x55555555;

    y = (y | (y << 8)) & 0x00FF00FF;
    y = (y | (y << 4)) & 0x0F0F0F0F;
    y = (y | (y << 2)) & 0x33333333;
    y = (y | (y << 1)) & 0x55555555;

    return x | (y << 1);
}

// find the leftmost node of a polygon ring
function getLeftmost(start) {
    var p = start,
        leftmost = start;
    do {
        if (p.x < leftmost.x || (p.x === leftmost.x && p.y < leftmost.y)) leftmost = p;
        p = p.next;
    } while (p !== start);

    return leftmost;
}

// check if a point lies within a convex triangle
function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
    return (cx - px) * (ay - py) >= (ax - px) * (cy - py) &&
           (ax - px) * (by - py) >= (bx - px) * (ay - py) &&
           (bx - px) * (cy - py) >= (cx - px) * (by - py);
}

// check if a diagonal between two polygon nodes is valid (lies in polygon interior)
function isValidDiagonal(a, b) {
    return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && // dones't intersect other edges
           (locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible
            (area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors
            equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0); // special zero-length case
}

// signed area of a triangle
function area(p, q, r) {
    return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
}

// check if two points are equal
function equals(p1, p2) {
    return p1.x === p2.x && p1.y === p2.y;
}

// check if two segments intersect
function intersects(p1, q1, p2, q2) {
    var o1 = sign(area(p1, q1, p2));
    var o2 = sign(area(p1, q1, q2));
    var o3 = sign(area(p2, q2, p1));
    var o4 = sign(area(p2, q2, q1));

    if (o1 !== o2 && o3 !== o4) return true; // general case

    if (o1 === 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1
    if (o2 === 0 && onSegment(p1, q2, q1)) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1
    if (o3 === 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2
    if (o4 === 0 && onSegment(p2, q1, q2)) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2

    return false;
}

// for collinear points p, q, r, check if point q lies on segment pr
function onSegment(p, q, r) {
    return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);
}

function sign(num) {
    return num > 0 ? 1 : num < 0 ? -1 : 0;
}

// check if a polygon diagonal intersects any polygon segments
function intersectsPolygon(a, b) {
    var p = a;
    do {
        if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&
                intersects(p, p.next, a, b)) return true;
        p = p.next;
    } while (p !== a);

    return false;
}

// check if a polygon diagonal is locally inside the polygon
function locallyInside(a, b) {
    return area(a.prev, a, a.next) < 0 ?
        area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 :
        area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;
}

// check if the middle point of a polygon diagonal is inside the polygon
function middleInside(a, b) {
    var p = a,
        inside = false,
        px = (a.x + b.x) / 2,
        py = (a.y + b.y) / 2;
    do {
        if (((p.y > py) !== (p.next.y > py)) && p.next.y !== p.y &&
                (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x))
            inside = !inside;
        p = p.next;
    } while (p !== a);

    return inside;
}

// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;
// if one belongs to the outer ring and another to a hole, it merges it into a single ring
function splitPolygon(a, b) {
    var a2 = new Node(a.i, a.x, a.y),
        b2 = new Node(b.i, b.x, b.y),
        an = a.next,
        bp = b.prev;

    a.next = b;
    b.prev = a;

    a2.next = an;
    an.prev = a2;

    b2.next = a2;
    a2.prev = b2;

    bp.next = b2;
    b2.prev = bp;

    return b2;
}

// create a node and optionally link it with previous one (in a circular doubly linked list)
function insertNode(i, x, y, last) {
    var p = new Node(i, x, y);

    if (!last) {
        p.prev = p;
        p.next = p;

    } else {
        p.next = last.next;
        p.prev = last;
        last.next.prev = p;
        last.next = p;
    }
    return p;
}

function removeNode(p) {
    p.next.prev = p.prev;
    p.prev.next = p.next;

    if (p.prevZ) p.prevZ.nextZ = p.nextZ;
    if (p.nextZ) p.nextZ.prevZ = p.prevZ;
}

function Node(i, x, y) {
    // vertex index in coordinates array
    this.i = i;

    // vertex coordinates
    this.x = x;
    this.y = y;

    // previous and next vertex nodes in a polygon ring
    this.prev = null;
    this.next = null;

    // z-order curve value
    this.z = 0;

    // previous and next nodes in z-order
    this.prevZ = null;
    this.nextZ = null;

    // indicates whether this is a steiner point
    this.steiner = false;
}

// return a percentage difference between the polygon area and its triangulation area;
// used to verify correctness of triangulation
earcut.deviation = function (data, holeIndices, dim, triangles) {
    var hasHoles = holeIndices && holeIndices.length;
    var outerLen = hasHoles ? holeIndices[0] * dim : data.length;

    var polygonArea = Math.abs(signedArea$1(data, 0, outerLen, dim));
    if (hasHoles) {
        for (var i = 0, len = holeIndices.length; i < len; i++) {
            var start = holeIndices[i] * dim;
            var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
            polygonArea -= Math.abs(signedArea$1(data, start, end, dim));
        }
    }

    var trianglesArea = 0;
    for (i = 0; i < triangles.length; i += 3) {
        var a = triangles[i] * dim;
        var b = triangles[i + 1] * dim;
        var c = triangles[i + 2] * dim;
        trianglesArea += Math.abs(
            (data[a] - data[c]) * (data[b + 1] - data[a + 1]) -
            (data[a] - data[b]) * (data[c + 1] - data[a + 1]));
    }

    return polygonArea === 0 && trianglesArea === 0 ? 0 :
        Math.abs((trianglesArea - polygonArea) / polygonArea);
};

function signedArea$1(data, start, end, dim) {
    var sum = 0;
    for (var i = start, j = end - dim; i < end; i += dim) {
        sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);
        j = i;
    }
    return sum;
}

// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts
earcut.flatten = function (data) {
    var dim = data[0][0].length,
        result = {vertices: [], holes: [], dimensions: dim},
        holeIndex = 0;

    for (var i = 0; i < data.length; i++) {
        for (var j = 0; j < data[i].length; j++) {
            for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]);
        }
        if (i > 0) {
            holeIndex += data[i - 1].length;
            result.holes.push(holeIndex);
        }
    }
    return result;
};

var earcutExports = earcut$2.exports;
var earcut$1 = /*@__PURE__*/getDefaultExportFromCjs(earcutExports);

function quickselect(arr, k, left, right, compare) {
    quickselectStep(arr, k, left || 0, right || (arr.length - 1), compare || defaultCompare$1);
}

function quickselectStep(arr, k, left, right, compare) {

    while (right > left) {
        if (right - left > 600) {
            var n = right - left + 1;
            var m = k - left + 1;
            var z = Math.log(n);
            var s = 0.5 * Math.exp(2 * z / 3);
            var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);
            var newLeft = Math.max(left, Math.floor(k - m * s / n + sd));
            var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));
            quickselectStep(arr, k, newLeft, newRight, compare);
        }

        var t = arr[k];
        var i = left;
        var j = right;

        swap$1(arr, left, k);
        if (compare(arr[right], t) > 0) swap$1(arr, left, right);

        while (i < j) {
            swap$1(arr, i, j);
            i++;
            j--;
            while (compare(arr[i], t) < 0) i++;
            while (compare(arr[j], t) > 0) j--;
        }

        if (compare(arr[left], t) === 0) swap$1(arr, left, j);
        else {
            j++;
            swap$1(arr, j, right);
        }

        if (j <= k) left = j + 1;
        if (k <= j) right = j - 1;
    }
}

function swap$1(arr, i, j) {
    var tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}

function defaultCompare$1(a, b) {
    return a < b ? -1 : a > b ? 1 : 0;
}

//      


                                                

// classifies an array of rings into polygons with outer rings and holes
function classifyRings$1(rings                     , maxRings        )                             {
    const len = rings.length;

    if (len <= 1) return [rings];

    const polygons = [];
    let polygon,
        ccw;

    for (let i = 0; i < len; i++) {
        const area = calculateSignedArea(rings[i]);
        if (area === 0) continue;

        (rings[i]     ).area = Math.abs(area);

        if (ccw === undefined) ccw = area < 0;

        if (ccw === area < 0) {
            if (polygon) polygons.push(polygon);
            polygon = [rings[i]];

        } else {
            (polygon     ).push(rings[i]);
        }
    }
    if (polygon) polygons.push(polygon);

    // Earcut performance degrades with the # of rings in a polygon. For this
    // reason, we limit strip out all but the `maxRings` largest rings.
    if (maxRings > 1) {
        for (let j = 0; j < polygons.length; j++) {
            if (polygons[j].length <= maxRings) continue;
            quickselect(polygons[j], maxRings, 1, polygons[j].length - 1, compareAreas);
            polygons[j] = polygons[j].slice(0, maxRings);
        }
    }

    return polygons;
}

function compareAreas(a                , b                ) {
    return b.area - a.area;
}

//      
                                                                              
                                                                                                 
                                                                              

             
                  
                      
                      

                         
                           
                           
                                   

function hasPattern(type        , layers                    , options                    )          {
    const patterns = options.patternDependencies;
    let hasPattern = false;

    for (const layer of layers) {
        const patternProperty = layer.paint.get(`${type}-pattern`);
        if (!patternProperty.isConstant()) {
            hasPattern = true;
        }

        const constantPattern = patternProperty.constantOr(null);
        if (constantPattern) {
            hasPattern = true;
            patterns[constantPattern] =  true;
        }
    }

    return hasPattern;
}

function addPatternDependencies(type        , layers                    , patternFeature               , zoom        , options                    )                {
    const patterns = options.patternDependencies;
    for (const layer of layers) {
        const patternProperty = layer.paint.get(`${type}-pattern`);

        const patternPropertyValue = patternProperty.value;
        if (patternPropertyValue.kind !== "constant") {
            let pattern = patternPropertyValue.evaluate({zoom}, patternFeature, {}, options.availableImages);
            pattern = pattern && pattern.name ? pattern.name : pattern;

            // add to patternDependencies
            patterns[pattern] = true;

            // save for layout
            patternFeature.patterns[layer.id] = pattern;
        }
    }
    return patternFeature;
}

//      

const EARCUT_MAX_RINGS$1 = 500;

                                                             
             
           
                     
                  
                   
                      
                      
                                                                              
                                               
                                                        
                                                          
                                                
                                                                
                                                         
                                                                       
                                                                          
                                                          

class FillBucket                   {
                  
                 
                        
                                  
                            
                                                
                                          
                                          

                                       
                                     

                                   
                             

                                
                              

                        
                                                                   
                            
                             
                      
                                        

    constructor(options                                  ) {
        this.zoom = options.zoom;
        this.overscaling = options.overscaling;
        this.layers = options.layers;
        this.layerIds = this.layers.map(layer => layer.id);
        this.index = options.index;
        this.hasPattern = false;
        this.patternFeatures = [];

        this.layoutVertexArray = new StructArrayLayout2i4();
        this.indexArray = new StructArrayLayout3ui6();
        this.indexArray2 = new StructArrayLayout2ui4();
        this.programConfigurations = new ProgramConfigurationSet(options.layers, options.zoom);
        this.segments = new SegmentVector();
        this.segments2 = new SegmentVector();
        this.stateDependentLayerIds = this.layers.filter((l) => l.isStateDependent()).map((l) => l.id);
        this.projection = options.projection;
    }

    populate(features                       , options                    , canonical                 , tileTransform               ) {
        this.hasPattern = hasPattern('fill', this.layers, options);
        const fillSortKey = this.layers[0].layout.get('fill-sort-key');
        const bucketFeatures = [];

        for (const {feature, id, index, sourceLayerIndex} of features) {
            const needGeometry = this.layers[0]._featureFilter.needGeometry;
            const evaluationFeature = toEvaluationFeature(feature, needGeometry);

            // $FlowFixMe[method-unbinding]
            if (!this.layers[0]._featureFilter.filter(new EvaluationParameters(this.zoom), evaluationFeature, canonical)) continue;

            const sortKey = fillSortKey ?
                fillSortKey.evaluate(evaluationFeature, {}, canonical, options.availableImages) :
                undefined;

            const bucketFeature                = {
                id,
                properties: feature.properties,
                type: feature.type,
                sourceLayerIndex,
                index,
                geometry: needGeometry ? evaluationFeature.geometry : loadGeometry(feature, canonical, tileTransform),
                patterns: {},
                sortKey
            };

            bucketFeatures.push(bucketFeature);
        }

        if (fillSortKey) {
            bucketFeatures.sort((a, b) => {
                // a.sortKey is always a number when in use
                return ((a.sortKey     )        ) - ((b.sortKey     )        );
            });
        }

        for (const bucketFeature of bucketFeatures) {
            const {geometry, index, sourceLayerIndex} = bucketFeature;

            if (this.hasPattern) {
                const patternFeature = addPatternDependencies('fill', this.layers, bucketFeature, this.zoom, options);
                // pattern features are added only once the pattern is loaded into the image atlas
                // so are stored during populate until later updated with positions by tile worker in addFeatures
                this.patternFeatures.push(patternFeature);
            } else {
                this.addFeature(bucketFeature, geometry, index, canonical, {}, options.availableImages);
            }

            const feature = features[index].feature;
            options.featureIndex.insert(feature, geometry, index, sourceLayerIndex, this.index);
        }
    }

    update(states               , vtLayer                  , availableImages               , imagePositions                 ) {
        if (!this.stateDependentLayers.length) return;
        this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers, availableImages, imagePositions);
    }

    addFeatures(options                    , canonical                 , imagePositions                 , availableImages               , _               ) {
        for (const feature of this.patternFeatures) {
            this.addFeature(feature, feature.geometry, feature.index, canonical, imagePositions, availableImages);
        }
    }

    isEmpty()          {
        return this.layoutVertexArray.length === 0;
    }

    uploadPending()          {
        return !this.uploaded || this.programConfigurations.needsUpload;
    }
    upload(context         ) {
        if (!this.uploaded) {
            this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray, members$3);
            this.indexBuffer = context.createIndexBuffer(this.indexArray);
            this.indexBuffer2 = context.createIndexBuffer(this.indexArray2);
        }
        this.programConfigurations.upload(context);
        this.uploaded = true;
    }

    destroy() {
        if (!this.layoutVertexBuffer) return;
        this.layoutVertexBuffer.destroy();
        this.indexBuffer.destroy();
        this.indexBuffer2.destroy();
        this.programConfigurations.destroy();
        this.segments.destroy();
        this.segments2.destroy();
    }

    addFeature(feature               , geometry                     , index        , canonical                 , imagePositions                 , availableImages                = []) {
        for (const polygon of classifyRings$1(geometry, EARCUT_MAX_RINGS$1)) {
            let numVertices = 0;
            for (const ring of polygon) {
                numVertices += ring.length;
            }

            const triangleSegment = this.segments.prepareSegment(numVertices, this.layoutVertexArray, this.indexArray);
            const triangleIndex = triangleSegment.vertexLength;

            const flattened = [];
            const holeIndices = [];

            for (const ring of polygon) {
                if (ring.length === 0) {
                    continue;
                }

                if (ring !== polygon[0]) {
                    holeIndices.push(flattened.length / 2);
                }

                const lineSegment = this.segments2.prepareSegment(ring.length, this.layoutVertexArray, this.indexArray2);
                const lineIndex = lineSegment.vertexLength;

                this.layoutVertexArray.emplaceBack(ring[0].x, ring[0].y);
                this.indexArray2.emplaceBack(lineIndex + ring.length - 1, lineIndex);
                flattened.push(ring[0].x);
                flattened.push(ring[0].y);

                for (let i = 1; i < ring.length; i++) {
                    this.layoutVertexArray.emplaceBack(ring[i].x, ring[i].y);
                    this.indexArray2.emplaceBack(lineIndex + i - 1, lineIndex + i);
                    flattened.push(ring[i].x);
                    flattened.push(ring[i].y);
                }

                lineSegment.vertexLength += ring.length;
                lineSegment.primitiveLength += ring.length;
            }

            const indices = earcut$1(flattened, holeIndices);
            assert$1(indices.length % 3 === 0);

            for (let i = 0; i < indices.length; i += 3) {
                this.indexArray.emplaceBack(
                    triangleIndex + indices[i],
                    triangleIndex + indices[i + 1],
                    triangleIndex + indices[i + 2]);
            }

            triangleSegment.vertexLength += numVertices;
            triangleSegment.primitiveLength += indices.length / 3;
        }
        this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index, imagePositions, availableImages, canonical);
    }
}

register(FillBucket, 'FillBucket', {omit: ['layers', 'patternFeatures']});

// This file is generated. Edit build/generate-style-code.js, then run `yarn run codegen`.
//      
/* eslint-disable */


                                                        

                                                                            

                                                                                     

                            
                                                
   

const layout$3                          = new Properties({
    "fill-sort-key": new DataDrivenProperty(spec["layout_fill"]["fill-sort-key"]),
});

                           
                                                    
                                               
                                            
                                                    
                                                             
                                                                      
                                                       
   

const paint$6                         = new Properties({
    "fill-antialias": new DataConstantProperty(spec["paint_fill"]["fill-antialias"]),
    "fill-opacity": new DataDrivenProperty(spec["paint_fill"]["fill-opacity"]),
    "fill-color": new DataDrivenProperty(spec["paint_fill"]["fill-color"]),
    "fill-outline-color": new DataDrivenProperty(spec["paint_fill"]["fill-outline-color"]),
    "fill-translate": new DataConstantProperty(spec["paint_fill"]["fill-translate"]),
    "fill-translate-anchor": new DataConstantProperty(spec["paint_fill"]["fill-translate-anchor"]),
    "fill-pattern": new DataDrivenProperty(spec["paint_fill"]["fill-pattern"]),
});

// Note: without adding the explicit type annotation, Flow infers weaker types
// for these objects from their use in the constructor to StyleLayer, as
// {layout?: Properties<...>, paint: Properties<...>}
var properties$6 = ({ paint: paint$6, layout: layout$3 }          
                                                                
  );

//      


                                                                       
                                                           
                                                
                                                                              
                                                                    
                                                    
                                                                  
                                                                 
                                                            

class FillStyleLayer extends StyleLayer {
                                            
                                           

                                                     
                                                   
                                         

    constructor(layer                    ) {
        super(layer, properties$6);
    }

    getProgramIds()           {
        const pattern = this.paint.get('fill-pattern');
        const image = pattern && pattern.constantOr((1     ));

        const ids = [image ? 'fillPattern' : 'fill'];

        if (this.paint.get('fill-antialias')) {
            ids.push(image && !this.getPaintProperty('fill-outline-color') ? 'fillOutlinePattern' : 'fillOutline');
        }

        return ids;
    }

    getProgramConfiguration(zoom        )                       {
        return new ProgramConfiguration(this, zoom);
    }

    recalculate(parameters                      , availableImages               ) {
        super.recalculate(parameters, availableImages);

        const outlineColor = this.paint._values['fill-outline-color'];
        if (outlineColor.value.kind === 'constant' && outlineColor.value.value === undefined) {
            this.paint._values['fill-outline-color'] = this.paint._values['fill-color'];
        }
    }

    createBucket(parameters                                  )             {
        return new FillBucket(parameters);
    }

    // $FlowFixMe[method-unbinding]
    queryRadius()         {
        return translateDistance(this.paint.get('fill-translate'));
    }

    // $FlowFixMe[method-unbinding]
    queryIntersectsFeature(queryGeometry                        ,
                           feature                    ,
                           featureState              ,
                           geometry                     ,
                           zoom        ,
                           transform           )          {
        if (queryGeometry.queryGeometry.isAboveHorizon) return false;

        const translatedPolygon = translate(queryGeometry.tilespaceGeometry,
            this.paint.get('fill-translate'),
            this.paint.get('fill-translate-anchor'),
            transform.angle, queryGeometry.pixelToTileUnitsFactor);
        return polygonIntersectsMultiPolygon(translatedPolygon, geometry);
    }

    isTileClipped()          {
        return true;
    }
}

//      

                                                                  

const fillExtrusionAttributes                    = createLayout([
    {name: 'a_pos_normal_ed', components: 4, type: 'Int16'}
]);

const centroidAttributes                    = createLayout([
    {name: 'a_centroid_pos',  components: 2, type: 'Uint16'}
]);

const fillExtrusionAttributesExt                    = createLayout([
    {name: 'a_pos_3', components: 3, type: 'Int16'},
    {name: 'a_pos_normal_3', components: 3, type: 'Int16'}
]);

const {members: members$2, size: size$2, alignment: alignment$2} = fillExtrusionAttributes;

var vectorTile = {};

'use strict';

var Point = pointGeometry;

var vectortilefeature = VectorTileFeature$2;

function VectorTileFeature$2(pbf, end, extent, keys, values) {
    // Public
    this.properties = {};
    this.extent = extent;
    this.type = 0;

    // Private
    this._pbf = pbf;
    this._geometry = -1;
    this._keys = keys;
    this._values = values;

    pbf.readFields(readFeature, this, end);
}

function readFeature(tag, feature, pbf) {
    if (tag == 1) feature.id = pbf.readVarint();
    else if (tag == 2) readTag(pbf, feature);
    else if (tag == 3) feature.type = pbf.readVarint();
    else if (tag == 4) feature._geometry = pbf.pos;
}

function readTag(pbf, feature) {
    var end = pbf.readVarint() + pbf.pos;

    while (pbf.pos < end) {
        var key = feature._keys[pbf.readVarint()],
            value = feature._values[pbf.readVarint()];
        feature.properties[key] = value;
    }
}

VectorTileFeature$2.types = ['Unknown', 'Point', 'LineString', 'Polygon'];

VectorTileFeature$2.prototype.loadGeometry = function() {
    var pbf = this._pbf;
    pbf.pos = this._geometry;

    var end = pbf.readVarint() + pbf.pos,
        cmd = 1,
        length = 0,
        x = 0,
        y = 0,
        lines = [],
        line;

    while (pbf.pos < end) {
        if (length <= 0) {
            var cmdLen = pbf.readVarint();
            cmd = cmdLen & 0x7;
            length = cmdLen >> 3;
        }

        length--;

        if (cmd === 1 || cmd === 2) {
            x += pbf.readSVarint();
            y += pbf.readSVarint();

            if (cmd === 1) { // moveTo
                if (line) lines.push(line);
                line = [];
            }

            line.push(new Point(x, y));

        } else if (cmd === 7) {

            // Workaround for https://github.com/mapbox/mapnik-vector-tile/issues/90
            if (line) {
                line.push(line[0].clone()); // closePolygon
            }

        } else {
            throw new Error('unknown command ' + cmd);
        }
    }

    if (line) lines.push(line);

    return lines;
};

VectorTileFeature$2.prototype.bbox = function() {
    var pbf = this._pbf;
    pbf.pos = this._geometry;

    var end = pbf.readVarint() + pbf.pos,
        cmd = 1,
        length = 0,
        x = 0,
        y = 0,
        x1 = Infinity,
        x2 = -Infinity,
        y1 = Infinity,
        y2 = -Infinity;

    while (pbf.pos < end) {
        if (length <= 0) {
            var cmdLen = pbf.readVarint();
            cmd = cmdLen & 0x7;
            length = cmdLen >> 3;
        }

        length--;

        if (cmd === 1 || cmd === 2) {
            x += pbf.readSVarint();
            y += pbf.readSVarint();
            if (x < x1) x1 = x;
            if (x > x2) x2 = x;
            if (y < y1) y1 = y;
            if (y > y2) y2 = y;

        } else if (cmd !== 7) {
            throw new Error('unknown command ' + cmd);
        }
    }

    return [x1, y1, x2, y2];
};

VectorTileFeature$2.prototype.toGeoJSON = function(x, y, z) {
    var size = this.extent * Math.pow(2, z),
        x0 = this.extent * x,
        y0 = this.extent * y,
        coords = this.loadGeometry(),
        type = VectorTileFeature$2.types[this.type],
        i, j;

    function project(line) {
        for (var j = 0; j < line.length; j++) {
            var p = line[j], y2 = 180 - (p.y + y0) * 360 / size;
            line[j] = [
                (p.x + x0) * 360 / size - 180,
                360 / Math.PI * Math.atan(Math.exp(y2 * Math.PI / 180)) - 90
            ];
        }
    }

    switch (this.type) {
    case 1:
        var points = [];
        for (i = 0; i < coords.length; i++) {
            points[i] = coords[i][0];
        }
        coords = points;
        project(coords);
        break;

    case 2:
        for (i = 0; i < coords.length; i++) {
            project(coords[i]);
        }
        break;

    case 3:
        coords = classifyRings(coords);
        for (i = 0; i < coords.length; i++) {
            for (j = 0; j < coords[i].length; j++) {
                project(coords[i][j]);
            }
        }
        break;
    }

    if (coords.length === 1) {
        coords = coords[0];
    } else {
        type = 'Multi' + type;
    }

    var result = {
        type: "Feature",
        geometry: {
            type: type,
            coordinates: coords
        },
        properties: this.properties
    };

    if ('id' in this) {
        result.id = this.id;
    }

    return result;
};

// classifies an array of rings into polygons with outer rings and holes

function classifyRings(rings) {
    var len = rings.length;

    if (len <= 1) return [rings];

    var polygons = [],
        polygon,
        ccw;

    for (var i = 0; i < len; i++) {
        var area = signedArea(rings[i]);
        if (area === 0) continue;

        if (ccw === undefined) ccw = area < 0;

        if (ccw === area < 0) {
            if (polygon) polygons.push(polygon);
            polygon = [rings[i]];

        } else {
            polygon.push(rings[i]);
        }
    }
    if (polygon) polygons.push(polygon);

    return polygons;
}

function signedArea(ring) {
    var sum = 0;
    for (var i = 0, len = ring.length, j = len - 1, p1, p2; i < len; j = i++) {
        p1 = ring[i];
        p2 = ring[j];
        sum += (p2.x - p1.x) * (p1.y + p2.y);
    }
    return sum;
}

var vectortilefeature$1 = /*@__PURE__*/getDefaultExportFromCjs(vectortilefeature);

'use strict';

var VectorTileFeature$1 = vectortilefeature;

var vectortilelayer = VectorTileLayer$2;

function VectorTileLayer$2(pbf, end) {
    // Public
    this.version = 1;
    this.name = null;
    this.extent = 4096;
    this.length = 0;

    // Private
    this._pbf = pbf;
    this._keys = [];
    this._values = [];
    this._features = [];

    pbf.readFields(readLayer, this, end);

    this.length = this._features.length;
}

function readLayer(tag, layer, pbf) {
    if (tag === 15) layer.version = pbf.readVarint();
    else if (tag === 1) layer.name = pbf.readString();
    else if (tag === 5) layer.extent = pbf.readVarint();
    else if (tag === 2) layer._features.push(pbf.pos);
    else if (tag === 3) layer._keys.push(pbf.readString());
    else if (tag === 4) layer._values.push(readValueMessage(pbf));
}

function readValueMessage(pbf) {
    var value = null,
        end = pbf.readVarint() + pbf.pos;

    while (pbf.pos < end) {
        var tag = pbf.readVarint() >> 3;

        value = tag === 1 ? pbf.readString() :
            tag === 2 ? pbf.readFloat() :
            tag === 3 ? pbf.readDouble() :
            tag === 4 ? pbf.readVarint64() :
            tag === 5 ? pbf.readVarint() :
            tag === 6 ? pbf.readSVarint() :
            tag === 7 ? pbf.readBoolean() : null;
    }

    return value;
}

// return feature `i` from this layer as a `VectorTileFeature`
VectorTileLayer$2.prototype.feature = function(i) {
    if (i < 0 || i >= this._features.length) throw new Error('feature index out of bounds');

    this._pbf.pos = this._features[i];

    var end = this._pbf.readVarint() + this._pbf.pos;
    return new VectorTileFeature$1(this._pbf, end, this.extent, this._keys, this._values);
};

var vectortilelayer$1 = /*@__PURE__*/getDefaultExportFromCjs(vectortilelayer);

'use strict';

var VectorTileLayer$1 = vectortilelayer;

var vectortile = VectorTile$1;

function VectorTile$1(pbf, end) {
    this.layers = pbf.readFields(readTile, {}, end);
}

function readTile(tag, layers, pbf) {
    if (tag === 3) {
        var layer = new VectorTileLayer$1(pbf, pbf.readVarint() + pbf.pos);
        if (layer.length) layers[layer.name] = layer;
    }
}

var vectortile$1 = /*@__PURE__*/getDefaultExportFromCjs(vectortile);

var VectorTile = vectorTile.VectorTile = vectortile;
var VectorTileFeature = vectorTile.VectorTileFeature = vectortilefeature;
var VectorTileLayer = vectorTile.VectorTileLayer = vectortilelayer;

//      


                              
                                 
                          
  

                                               

function clipPolygon(polygons              , clipAxis1        , clipAxis2        , axis        )               {
    const intersectX = (ring              , ax        , ay        , bx        , by        , x        ) => {
        ring.push(new Point$2(x, ay + (by - ay) * ((x - ax) / (bx - ax))));
    };
    const intersectY = (ring              , ax        , ay        , bx        , by        , y        ) => {
        ring.push(new Point$2(ax + (bx - ax) * ((y - ay) / (by - ay)), y));
    };

    const polygonsClipped = [];
    const intersect = axis === 0 ? intersectX : intersectY;
    for (const polygon of polygons) {
        const polygonClipped = [];
        for (const ring of polygon) {
            if (ring.length <= 2) {
                continue;
            }

            const clipped = [];
            for (let i = 0; i < ring.length - 1; i++) {
                const ax = ring[i].x;
                const ay = ring[i].y;
                const bx = ring[i + 1].x;
                const by = ring[i + 1].y;
                const a = axis === 0 ? ax : ay;
                const b = axis === 0 ? bx : by;
                if (a < clipAxis1) {
                    if (b > clipAxis1) {
                        intersect(clipped, ax, ay, bx, by, clipAxis1);
                    }
                } else if (a > clipAxis2) {
                    if (b < clipAxis2) {
                        intersect(clipped, ax, ay, bx, by, clipAxis2);
                    }
                } else {
                    clipped.push(ring[i]);
                }
                if (b < clipAxis1 && a >= clipAxis1) {
                    intersect(clipped, ax, ay, bx, by, clipAxis1);
                }
                if (b > clipAxis2 && a <= clipAxis2) {
                    intersect(clipped, ax, ay, bx, by, clipAxis2);
                }
            }

            let last = ring[ring.length - 1];
            const a = axis === 0 ? last.x : last.y;
            if (a >= clipAxis1 && a <= clipAxis2) {
                clipped.push(last);
            }
            if (clipped.length) {
                last = clipped[clipped.length - 1];
                if (clipped[0].x !== last.x || clipped[0].y !== last.y) {
                    clipped.push(clipped[0]);
                }
                polygonClipped.push(clipped);
            }
        }
        if (polygonClipped.length) {
            polygonsClipped.push(polygonClipped);
        }
    }

    return polygonsClipped;
}

function subdividePolygons(polygons              , bounds                , gridSizeX        , gridSizeY        , padding         = 0.0, splitFn          )                        {
    const outPolygons = [];

    if (!polygons.length || !gridSizeX || !gridSizeY) {
        return outPolygons;
    }

    const addResult = (clipped              , bounds                ) => {
        for (const polygon of clipped) {
            outPolygons.push({polygon, bounds});
        }
    };

    const hSplits = Math.ceil(Math.log2(gridSizeX));
    const vSplits = Math.ceil(Math.log2(gridSizeY));

    const initialSplits = hSplits - vSplits;

    const splits = [];
    for (let i = 0; i < Math.abs(initialSplits); i++) {
        splits.push(initialSplits > 0 ? 0 : 1);
    }

    for (let i = 0; i < Math.min(hSplits, vSplits); i++) {
        splits.push(0); // x
        splits.push(1); // y
    }

    let split = polygons;

    split = clipPolygon(split, bounds[0].y - padding, bounds[1].y + padding, 1);
    split = clipPolygon(split, bounds[0].x - padding, bounds[1].x + padding, 0);

    if (!split.length) {
        return outPolygons;
    }

    const stack = [];
    if (splits.length) {
        stack.push({polygons: split, bounds, depth: 0});
    } else {
        addResult(split, bounds);
    }

    while (stack.length) {
        const frame = stack.pop();

        assert$1(frame.polygons.length > 0);

        const depth = frame.depth;
        const axis = splits[depth];

        const bboxMin = frame.bounds[0];
        const bboxMax = frame.bounds[1];

        const splitMin = axis === 0 ? bboxMin.x : bboxMin.y;
        const splitMax = axis === 0 ? bboxMax.x : bboxMax.y;

        const splitMid = splitFn ? splitFn(axis, splitMin, splitMax) : 0.5 * (splitMin + splitMax);

        const lclip = clipPolygon(frame.polygons, splitMin - padding, splitMid + padding, axis);
        const rclip = clipPolygon(frame.polygons, splitMid - padding, splitMax + padding, axis);

        if (lclip.length) {
            const bbMaxX = axis === 0 ? splitMid : bboxMax.x;
            const bbMaxY = axis === 1 ? splitMid : bboxMax.y;

            const bbMax = new Point$2(bbMaxX, bbMaxY);

            const lclipBounds = [bboxMin, bbMax];

            if (splits.length > depth + 1) {
                stack.push({polygons: lclip, bounds: lclipBounds, depth: depth + 1});
            } else {
                addResult(lclip, lclipBounds);
            }
        }

        if (rclip.length) {
            const bbMinX = axis === 0 ? splitMid : bboxMin.x;
            const bbMinY = axis === 1 ? splitMid : bboxMin.y;

            const bbMin = new Point$2(bbMinX, bbMinY);

            const rclipBounds = [bbMin, bboxMax];

            if (splits.length > depth + 1) {
                stack.push({polygons: rclip, bounds: rclipBounds, depth: depth + 1});
            } else {
                addResult(rclip, rclipBounds);
            }
        }
    }

    return outPolygons;
}

//      

const vectorTileFeatureTypes$2 = VectorTileFeature.types;
const EARCUT_MAX_RINGS = 500;

                                                                                                 
                                               
                                                        
                                                          
                                                                
                                                         
                                                                       
                                                                          
                                                          

const FACTOR = Math.pow(2, 13);

// Also declared in _prelude_terrain.vertex.glsl
// Used to scale most likely elevation values to fit well in an uint16
// (Elevation of Dead Sea + ELEVATION_OFFSET) * ELEVATION_SCALE is roughly 0
// (Height of mt everest + ELEVATION_OFFSET) * ELEVATION_SCALE is roughly 64k
const ELEVATION_SCALE = 7.0;
const ELEVATION_OFFSET = 450;

function addVertex$1(vertexArray                          , x        , y        , nxRatio        , nySign        , normalUp        , top        , e        ) {
    vertexArray.emplaceBack(
        // a_pos_normal_ed:
        // Encode top and side/up normal using the least significant bits
        (x << 1) + top,
        (y << 1) + normalUp,
        // dxdy is signed, encode quadrant info using the least significant bit
        (Math.floor(nxRatio * FACTOR) << 1) + nySign,
        // edgedistance (used for wrapping patterns around extrusion sides)
        Math.round(e)
    );
}

function addGlobeExtVertex(vertexArray                       , pos                                   , normal      ) {
    const encode = 1 << 14;
    vertexArray.emplaceBack(
        pos.x, pos.y, pos.z,
        normal[0] * encode, normal[1] * encode, normal[2] * encode);
}

class PartMetadata {
               
               
               
                                                   
                                                   
                                      // Array<[min, max]>
                              

    constructor() {
        this.acc = new Point$2(0, 0);
        this.polyCount = [];
    }

    startRing(p       ) {
        this.currentPolyCount = {edges: 0, top: 0};
        this.polyCount.push(this.currentPolyCount);
        if (this.min) return;
        this.min = new Point$2(p.x, p.y);
        this.max = new Point$2(p.x, p.y);
    }

    append(p       , prev       ) {
        this.currentPolyCount.edges++;

        this.acc._add(p);
        const min = this.min, max = this.max;
        if (p.x < min.x) {
            min.x = p.x;
        } else if (p.x > max.x) {
            max.x = p.x;
        }
        if (p.y < min.y) {
            min.y = p.y;
        } else if (p.y > max.y) {
            max.y = p.y;
        }
        if (((p.x === 0 || p.x === EXTENT) && p.x === prev.x) !== ((p.y === 0 || p.y === EXTENT) && p.y === prev.y)) {
            // Custom defined geojson buildings are cut on borders. Points are
            // repeated when edge cuts tile corner (reason for using xor).
            this.processBorderOverlap(p, prev);
        }
        // check border intersection
        if ((prev.x < 0) !== (p.x < 0)) {
            this.addBorderIntersection(0, number(prev.y, p.y, (0 - prev.x) / (p.x - prev.x)));
        }
        if ((prev.x > EXTENT) !== (p.x > EXTENT)) {
            this.addBorderIntersection(1, number(prev.y, p.y, (EXTENT - prev.x) / (p.x - prev.x)));
        }
        if ((prev.y < 0) !== (p.y < 0)) {
            this.addBorderIntersection(2, number(prev.x, p.x, (0 - prev.y) / (p.y - prev.y)));
        }
        if ((prev.y > EXTENT) !== (p.y > EXTENT)) {
            this.addBorderIntersection(3, number(prev.x, p.x, (EXTENT - prev.y) / (p.y - prev.y)));
        }
    }

    addBorderIntersection(index               , i        ) {
        if (!this.borders) {
            this.borders = [
                [Number.MAX_VALUE, -Number.MAX_VALUE],
                [Number.MAX_VALUE, -Number.MAX_VALUE],
                [Number.MAX_VALUE, -Number.MAX_VALUE],
                [Number.MAX_VALUE, -Number.MAX_VALUE]
            ];
        }
        const b = this.borders[index];
        if (i < b[0]) b[0] = i;
        if (i > b[1]) b[1] = i;
    }

    processBorderOverlap(p       , prev       ) {
        if (p.x === prev.x) {
            if (p.y === prev.y) return; // custom defined geojson could have points repeated.
            const index = p.x === 0 ? 0 : 1;
            this.addBorderIntersection(index, prev.y);
            this.addBorderIntersection(index, p.y);
        } else {
            assert$1(p.y === prev.y);
            const index = p.y === 0 ? 2 : 3;
            this.addBorderIntersection(index, prev.x);
            this.addBorderIntersection(index, p.x);
        }
    }

    centroid()        {
        const count = this.polyCount.reduce((acc, p) => acc + p.edges, 0);
        return count !== 0 ? this.acc.div(count)._round() : new Point$2(0, 0);
    }

    span()        {
        return new Point$2(this.max.x - this.min.x, this.max.y - this.min.y);
    }

    intersectsCount()         {
        return this.borders.reduce((acc, p) => acc + +(p[0] !== Number.MAX_VALUE), 0);
    }
}

class FillExtrusionBucket                   {
                  
                 
                               
                        
                           
                                           
                            
                                                         
                                          

                                                
                                     

                                                    
                                       

                                                 
                                         

                                   
                             

                        
                       
                                                                            
                            
                      
                                   

                                          
    // borders / borderDoneWithNeighborZ: 0 - left, 1, right, 2 - top, 3 - bottom
                                   // For each side, indices into featuresOnBorder array.
                                           
                                 
                         // cache conversion.
                                        

    constructor(options                                           ) {
        this.zoom = options.zoom;
        this.canonical = options.canonical;
        this.overscaling = options.overscaling;
        this.layers = options.layers;
        this.layerIds = this.layers.map(layer => layer.id);
        this.index = options.index;
        this.hasPattern = false;
        this.edgeRadius = 0;
        this.projection = options.projection;

        this.layoutVertexArray = new StructArrayLayout4i8();
        this.centroidVertexArray = new FillExtrusionCentroidArray();
        this.indexArray = new StructArrayLayout3ui6();
        this.programConfigurations = new ProgramConfigurationSet(options.layers, options.zoom);
        this.segments = new SegmentVector();
        this.stateDependentLayerIds = this.layers.filter((l) => l.isStateDependent()).map((l) => l.id);
        this.enableTerrain = options.enableTerrain;
    }

    populate(features                       , options                    , canonical                 , tileTransform               ) {
        this.features = [];
        this.hasPattern = hasPattern('fill-extrusion', this.layers, options);
        this.featuresOnBorder = [];
        this.borders = [[], [], [], []];
        this.borderDoneWithNeighborZ = [-1, -1, -1, -1];
        this.tileToMeter = tileToMeter(canonical);
        this.edgeRadius = this.layers[0].layout.get('fill-extrusion-edge-radius') / this.tileToMeter;

        for (const {feature, id, index, sourceLayerIndex} of features) {
            const needGeometry = this.layers[0]._featureFilter.needGeometry;
            const evaluationFeature = toEvaluationFeature(feature, needGeometry);

            // $FlowFixMe[method-unbinding]
            if (!this.layers[0]._featureFilter.filter(new EvaluationParameters(this.zoom), evaluationFeature, canonical)) continue;

            const bucketFeature                = {
                id,
                sourceLayerIndex,
                index,
                geometry: needGeometry ? evaluationFeature.geometry : loadGeometry(feature, canonical, tileTransform),
                properties: feature.properties,
                type: feature.type,
                patterns: {}
            };

            const vertexArrayOffset = this.layoutVertexArray.length;
            if (this.hasPattern) {
                this.features.push(addPatternDependencies('fill-extrusion', this.layers, bucketFeature, this.zoom, options));
            } else {
                this.addFeature(bucketFeature, bucketFeature.geometry, index, canonical, {}, options.availableImages, tileTransform);
            }

            options.featureIndex.insert(feature, bucketFeature.geometry, index, sourceLayerIndex, this.index, vertexArrayOffset);
        }
        this.sortBorders();
    }

    addFeatures(options                    , canonical                 , imagePositions                 , availableImages               , tileTransform               ) {
        for (const feature of this.features) {
            const {geometry} = feature;
            this.addFeature(feature, geometry, feature.index, canonical, imagePositions, availableImages, tileTransform);
        }
        this.sortBorders();
    }

    update(states               , vtLayer                  , availableImages               , imagePositions                 ) {
        if (!this.stateDependentLayers.length) return;
        this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers, availableImages, imagePositions);
    }

    isEmpty()          {
        return this.layoutVertexArray.length === 0;
    }

    uploadPending()          {
        return !this.uploaded || this.programConfigurations.needsUpload;
    }

    upload(context         ) {
        if (!this.uploaded) {
            this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray, members$2);
            this.indexBuffer = context.createIndexBuffer(this.indexArray);

            if (this.layoutVertexExtArray) {
                this.layoutVertexExtBuffer = context.createVertexBuffer(this.layoutVertexExtArray, fillExtrusionAttributesExt.members, true);
            }
        }
        this.programConfigurations.upload(context);
        this.uploaded = true;
    }

    uploadCentroid(context         ) {
        if (this.centroidVertexArray.length === 0) return;
        if (!this.centroidVertexBuffer) {
            this.centroidVertexBuffer = context.createVertexBuffer(this.centroidVertexArray, centroidAttributes.members, true);
        } else if (this.needsCentroidUpdate) {
            this.centroidVertexBuffer.updateData(this.centroidVertexArray);
        }
        this.needsCentroidUpdate = false;
    }

    destroy() {
        if (!this.layoutVertexBuffer) return;
        this.layoutVertexBuffer.destroy();
        if (this.centroidVertexBuffer) {
            this.centroidVertexBuffer.destroy();
        }
        if (this.layoutVertexExtBuffer) {
            this.layoutVertexExtBuffer.destroy();
        }
        this.indexBuffer.destroy();
        this.programConfigurations.destroy();
        this.segments.destroy();
    }

    addFeature(feature               , geometry                     , index        , canonical                 , imagePositions                 , availableImages               , tileTransform               ) {
        const tileBounds = [new Point$2(0, 0), new Point$2(EXTENT, EXTENT)];
        const projection = tileTransform.projection;
        const isGlobe = projection.name === 'globe';
        const metadata = this.enableTerrain && !isGlobe ? new PartMetadata() : null;
        const isPolygon = vectorTileFeatureTypes$2[feature.type] === 'Polygon';

        if (isGlobe && !this.layoutVertexExtArray) {
            this.layoutVertexExtArray = new StructArrayLayout6i12();
        }

        const polygons = classifyRings$1(geometry, EARCUT_MAX_RINGS);

        for (let i = polygons.length - 1; i >= 0; i--) {
            const polygon = polygons[i];
            if (polygon.length === 0 || isEntirelyOutside(polygon[0])) {
                polygons.splice(i, 1);
            }
        }

        let clippedPolygons                  ;
        if (isGlobe) {
            // Perform tesselation for polygons of tiles in order to support long planar
            // triangles on the curved surface of the globe. This is done for all polygons
            // regardless of their size in order guarantee identical results on all sides of
            // tile boundaries.
            //
            // The globe is subdivided into a 32x16 grid. The number of subdivisions done
            // for a tile depends on the zoom level. For example tile with z=0 requires 2⁴
            // subdivisions, tile with z=1 2³ etc. The subdivision is done in polar coordinates
            // instead of tile coordinates.
            clippedPolygons = resampleFillExtrusionPolygonsForGlobe(polygons, tileBounds, canonical);
        } else {
            clippedPolygons = [];
            for (const polygon of polygons) {
                clippedPolygons.push({polygon, bounds: tileBounds});
            }
        }

        const edgeRadius = isPolygon ? this.edgeRadius : 0;

        for (const {polygon, bounds} of clippedPolygons) {
            // Only triangulate and draw the area of the feature if it is a polygon
            // Other feature types (e.g. LineString) do not have area, so triangulation is pointless / undefined
            let topIndex = 0;
            let numVertices = 0;
            for (const ring of polygon) {
                // make sure the ring closes
                if (isPolygon && !ring[0].equals(ring[ring.length - 1])) ring.push(ring[0]);
                numVertices += (isPolygon ? (ring.length - 1) : ring.length);
            }
            // We use "(isPolygon ? 5 : 4) * numVertices" as an estimate to ensure whether additional segments are needed or not (see SegmentVector.MAX_VERTEX_ARRAY_LENGTH).
            const segment = this.segments.prepareSegment((isPolygon ? 5 : 4) * numVertices, this.layoutVertexArray, this.indexArray);
            if (isPolygon) {
                const flattened = [];
                const holeIndices = [];
                topIndex = segment.vertexLength;

                // First we offset (inset) the top vertices (i.e the vertices that make up the roof).
                for (const ring of polygon) {
                    if (ring.length && ring !== polygon[0]) {
                        holeIndices.push(flattened.length / 2);
                    }

                    // The following vectors are used to avoid duplicate normal calculations when going over the vertices.
                    let na, nb;
                    {
                        const p0 = ring[0];
                        const p1 = ring[1];
                        na = p1.sub(p0)._perp()._unit();
                    }
                    for (let i = 1; i < ring.length; i++) {
                        const p1 = ring[i];
                        const p2 = ring[i === ring.length - 1 ? 1 : i + 1];

                        let {x, y} = p1;
                        if (edgeRadius) {
                            nb = p2.sub(p1)._perp()._unit();
                            const nm = na.add(nb)._unit();

                            const cosHalfAngle = na.x * nm.x + na.y * nm.y;
                            const offset = edgeRadius * Math.min(4, 1 / cosHalfAngle);

                            x += offset * nm.x;
                            y += offset * nm.y;

                            na = nb;
                        }

                        addVertex$1(this.layoutVertexArray, x, y, 0, 0, 1, 1, 0);
                        segment.vertexLength++;

                        // triangulate as if vertices were not offset to ensure correct triangulation
                        flattened.push(p1.x, p1.y);

                        if (isGlobe) {
                            const array      = this.layoutVertexExtArray;
                            const projectedP = projection.projectTilePoint(x, y, canonical);
                            const n = projection.upVector(canonical, x, y);
                            addGlobeExtVertex(array, projectedP, n);
                        }
                    }
                }

                const indices = earcut$1(flattened, holeIndices);
                assert$1(indices.length % 3 === 0);

                for (let j = 0; j < indices.length; j += 3) {
                    // clockwise winding order.
                    this.indexArray.emplaceBack(
                        topIndex + indices[j],
                        topIndex + indices[j + 2],
                        topIndex + indices[j + 1]);
                    segment.primitiveLength++;
                }
            }

            for (const ring of polygon) {
                if (metadata && ring.length) metadata.startRing(ring[0]);
                let isPrevCornerConcave = ring.length > 4 && isAOConcaveAngle(ring[ring.length - 2], ring[0], ring[1]);
                let offsetPrev = edgeRadius ? getRoundedEdgeOffset(ring[ring.length - 2], ring[0], ring[1], edgeRadius) : 0;

                let kFirst;

                // The following vectors are used to avoid duplicate normal calculations when going over the vertices.
                let na, nb;
                {
                    const p0 = ring[0];
                    const p1 = ring[1];
                    na = p1.sub(p0)._perp()._unit();
                }
                let cap = true;
                for (let i = 1, edgeDistance = 0; i < ring.length; i++) {
                    let p0 = ring[i - 1];
                    let p1 = ring[i];
                    const p2 = ring[i === ring.length - 1 ? 1 : i + 1];

                    if (metadata && isPolygon) metadata.currentPolyCount.top++;
                    if (isEdgeOutsideBounds(p1, p0, bounds)) {
                        if (edgeRadius) {
                            na = p2.sub(p1)._perp()._unit();
                            cap = !cap;
                        }
                        continue;
                    }
                    if (metadata) metadata.append(p1, p0);

                    const d = p1.sub(p0)._perp();
                    // Given that nz === 0, encode nx / (abs(nx) + abs(ny)) and signs.
                    // This information is sufficient to reconstruct normal vector in vertex shader.
                    const nxRatio = d.x / (Math.abs(d.x) + Math.abs(d.y));
                    const nySign = d.y > 0 ? 1 : 0;

                    const dist = p0.dist(p1);
                    if (edgeDistance + dist > 32768) edgeDistance = 0;

                    // Next offset the vertices along the edges and create a chamfer space between them:
                    // So if we have the following (where 'x' denotes a vertex)
                    // x──────x
                    // |      |
                    // |      |
                    // |      |
                    // |      |
                    // x──────x
                    // we end up with:
                    //  x────x
                    // x      x
                    // |      |
                    // |      |
                    // x      x
                    //  x────x
                    // (drawing isn't exact but hopefully gets the point across).

                    if (edgeRadius) {
                        nb = p2.sub(p1)._perp()._unit();

                        const cosHalfAngle = getCosHalfAngle(na, nb);
                        let offsetNext = _getRoundedEdgeOffset(p0, p1, p2, cosHalfAngle, edgeRadius);

                        if (isNaN(offsetNext)) offsetNext = 0;
                        const nEdge = p1.sub(p0)._unit();
                        p0 = p0.add(nEdge.mult(offsetPrev))._round();
                        p1 = p1.add(nEdge.mult(-offsetNext))._round();
                        offsetPrev = offsetNext;

                        na = nb;
                    }

                    const k = segment.vertexLength;

                    const isConcaveCorner = ring.length > 4 && isAOConcaveAngle(p0, p1, p2);
                    let encodedEdgeDistance = encodeAOToEdgeDistance(edgeDistance, isPrevCornerConcave, cap);

                    addVertex$1(this.layoutVertexArray, p0.x, p0.y, nxRatio, nySign, 0, 0, encodedEdgeDistance);
                    addVertex$1(this.layoutVertexArray, p0.x, p0.y, nxRatio, nySign, 0, 1, encodedEdgeDistance);

                    edgeDistance += dist;
                    encodedEdgeDistance = encodeAOToEdgeDistance(edgeDistance, isConcaveCorner, !cap);
                    isPrevCornerConcave = isConcaveCorner;

                    addVertex$1(this.layoutVertexArray, p1.x, p1.y, nxRatio, nySign, 0, 0, encodedEdgeDistance);
                    addVertex$1(this.layoutVertexArray, p1.x, p1.y, nxRatio, nySign, 0, 1, encodedEdgeDistance);

                    segment.vertexLength += 4;

                    // ┌──────┐
                    // │ 1  3 │ clockwise winding order.
                    // │      │ Triangle 1: 0 => 1 => 2
                    // │ 0  2 │ Triangle 2: 1 => 3 => 2
                    // └──────┘
                    this.indexArray.emplaceBack(k + 0, k + 1, k + 2);
                    this.indexArray.emplaceBack(k + 1, k + 3, k + 2);
                    segment.primitiveLength += 2;

                    if (edgeRadius) {
                        // Note that in the previous for-loop we start from index 1 to add the top vertices which explains the next line.
                        const t0 = topIndex + (i === 1 ? ring.length - 2 : i - 2);
                        const t1 = i === 1 ? topIndex : t0 + 1;

                        // top chamfer along the side (i.e. the space between the wall and the roof).
                        this.indexArray.emplaceBack(k + 1, t0, k + 3);
                        this.indexArray.emplaceBack(t0, t1, k + 3);
                        segment.primitiveLength += 2;

                        if (kFirst === undefined) {
                            kFirst = k;
                        }

                        // Make sure to fill in the gap in the corner only when both corresponding edges are in tile bounds.
                        if (!isEdgeOutsideBounds(p2, ring[i], bounds)) {
                            const l = i === ring.length - 1 ? kFirst : segment.vertexLength;

                            // vertical side chamfer i.e. the space between consecutive walls.
                            this.indexArray.emplaceBack(k + 2, k + 3, l);
                            this.indexArray.emplaceBack(k + 3, l + 1, l);

                            // top corner where the top(roof) and two sides(walls) meet.
                            this.indexArray.emplaceBack(k + 3, t1, l + 1);

                            segment.primitiveLength += 3;
                        }
                        cap = !cap;
                    }

                    if (isGlobe) {
                        const array      = this.layoutVertexExtArray;

                        const projectedP0 = projection.projectTilePoint(p0.x, p0.y, canonical);
                        const projectedP1 = projection.projectTilePoint(p1.x, p1.y, canonical);

                        const n0 = projection.upVector(canonical, p0.x, p0.y);
                        const n1 = projection.upVector(canonical, p1.x, p1.y);

                        addGlobeExtVertex(array, projectedP0, n0);
                        addGlobeExtVertex(array, projectedP0, n0);
                        addGlobeExtVertex(array, projectedP1, n1);
                        addGlobeExtVertex(array, projectedP1, n1);
                    }
                }
                if (isPolygon) topIndex += (ring.length - 1);
            }
        }

        assert$1(!isGlobe || (this.layoutVertexExtArray && this.layoutVertexExtArray.length === this.layoutVertexArray.length));

        if (metadata && metadata.polyCount.length > 0) {
            // When building is split between tiles, don't handle flat roofs here.
            if (metadata.borders) {
                // Store to the bucket. Flat roofs are handled in flatRoofsUpdate,
                // after joining parts that lay in different buckets.
                metadata.vertexArrayOffset = this.centroidVertexArray.length;
                const borders = metadata.borders;
                const index = this.featuresOnBorder.push(metadata) - 1;
                for (let i = 0; i < 4; i++) {
                    if (borders[i][0] !== Number.MAX_VALUE) { this.borders[i].push(index); }
                }
            }
            this.encodeCentroid(metadata.borders ? undefined : metadata.centroid(), metadata);
            assert$1(!this.centroidVertexArray.length || this.centroidVertexArray.length === this.layoutVertexArray.length);
        }

        this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index, imagePositions, availableImages, canonical);
    }

    sortBorders() {
        for (let i = 0; i < 4; i++) {
            // Sort by border intersection area minimums, ascending.
            this.borders[i].sort((a, b) => this.featuresOnBorder[a].borders[i][0] - this.featuresOnBorder[b].borders[i][0]);
        }
    }

    encodeCentroid(c        , metadata              , append          = true) {
        let x, y;
        // Encoded centroid x and y:
        //     x     y
        // ---------------------------------------------
        //     0     0    Default, no flat roof.
        //     0     1    Hide, used to hide parts of buildings on border while expecting the other side to get loaded
        //    >0     0    Elevation encoded to uint16 word
        //    >0    >0    Encoded centroid position and x & y span
        if (c) {
            if (c.y !== 0) {
                const span = metadata.span()._mult(this.tileToMeter);
                x = (Math.max(c.x, 1) << 3) + Math.min(7, Math.round(span.x / 10));
                y = (Math.max(c.y, 1) << 3) + Math.min(7, Math.round(span.y / 10));
            } else { // encode height:
                x = Math.ceil((c.x + ELEVATION_OFFSET) * ELEVATION_SCALE);
                y = 0;
            }
        } else {
            // Use the impossible situation (building that has width and doesn't cross border cannot have centroid
            // at border) to encode unprocessed border building: it is initially (append === true) hidden until
            // computing centroid for joined building parts in rendering thread (flatRoofsUpdate). If it intersects more than
            // two borders, flat roof approach is not applied.
            x = 0;
            y = +append; // Hide (1) initially when creating - visibility is changed in draw_fill_extrusion as soon as neighbor tile gets loaded.
        }

        assert$1(append || metadata.vertexArrayOffset !== undefined);
        let offset = append ? this.centroidVertexArray.length : metadata.vertexArrayOffset;
        for (const polyInfo of metadata.polyCount) {
            if (append) {
                this.centroidVertexArray.resize(this.centroidVertexArray.length + polyInfo.edges * 4 + polyInfo.top);
            }
            for (let i = 0; i < polyInfo.top; i++) {
                this.centroidVertexArray.emplace(offset++, x, y);
            }
            for (let i = 0; i < polyInfo.edges * 2; i++) {
                this.centroidVertexArray.emplace(offset++, 0, y);
                this.centroidVertexArray.emplace(offset++, x, y);
            }
        }
    }
}

function getCosHalfAngle(na       , nb       ) {
    const nm = na.add(nb)._unit();
    const cosHalfAngle = na.x * nm.x + na.y * nm.y;
    return cosHalfAngle;
}

function getRoundedEdgeOffset(p0       , p1       , p2       , edgeRadius        ) {
    const na = p1.sub(p0)._perp()._unit();
    const nb = p2.sub(p1)._perp()._unit();
    const cosHalfAngle = getCosHalfAngle(na, nb);
    return _getRoundedEdgeOffset(p0, p1, p2, cosHalfAngle, edgeRadius);
}

function _getRoundedEdgeOffset(p0       , p1       , p2       , cosHalfAngle        , edgeRadius        ) {
    const sinHalfAngle = Math.sqrt(1 - cosHalfAngle * cosHalfAngle);
    return Math.min(p0.dist(p1) / 3, p1.dist(p2) / 3, edgeRadius * sinHalfAngle / cosHalfAngle);
}

register(FillExtrusionBucket, 'FillExtrusionBucket', {omit: ['layers', 'features']});
register(PartMetadata, 'PartMetadata');

// Edges that are outside tile bounds are defined in tile across the border.
// Rendering them twice often results with Z-fighting.
// In case of globe and axis aligned bounds, it is also useful to
// discard edges that have the both endpoints outside the same bound.
function isEdgeOutsideBounds(p1       , p2       , bounds                ) {
    return (p1.x < bounds[0].x && p2.x < bounds[0].x) ||
           (p1.x > bounds[1].x && p2.x > bounds[1].x) ||
           (p1.y < bounds[0].y && p2.y < bounds[0].y) ||
           (p1.y > bounds[1].y && p2.y > bounds[1].y);
}

function isEntirelyOutside(ring              ) {
    // Discard rings with corners on border if all other vertices are outside: they get defined
    // also in the tile across the border. Eventual zero area rings at border are discarded by classifyRings
    // and there is no need to handle that case here.
    return ring.every(p => p.x <= 0) ||
        ring.every(p => p.x >= EXTENT) ||
        ring.every(p => p.y <= 0) ||
        ring.every(p => p.y >= EXTENT);
}

function tileToMeter(canonical                 ) {
    const circumferenceAtEquator = 40075017;
    const mercatorY = canonical.y / (1 << canonical.z);
    const exp = Math.exp(Math.PI * (1 - 2 * mercatorY));
    // simplify cos(2 * atan(e) - PI/2) from mercator_coordinate.js, remove trigonometrics.
    return circumferenceAtEquator * 2 * exp / (exp * exp + 1) / EXTENT / (1 << canonical.z);
}

function isAOConcaveAngle(p2       , p1       , p3       ) {
    if (p2.x < 0 || p2.x >= EXTENT || p1.x < 0 || p1.x >= EXTENT || p3.x < 0 || p3.x >= EXTENT) {
        return false; // angles are not processed for edges that extend over tile borders
    }
    const a = p3.sub(p1);
    const an = a.perp();
    const b = p2.sub(p1);
    const ab = a.x * b.x + a.y * b.y;
    const cosAB = ab / Math.sqrt(((a.x * a.x + a.y * a.y) * (b.x * b.x + b.y * b.y)));
    const dotProductWithNormal = an.x * b.x + an.y * b.y;

    // Heuristics: don't shade concave angles above 150° (arccos(-0.866)).
    return cosAB > -0.866 && dotProductWithNormal < 0;
}

function encodeAOToEdgeDistance(edgeDistance        , isConcaveCorner         , edgeStart         ) {
    // Encode concavity and edge start/end using the least significant bits.
    // Second least significant bit 1 encodes concavity.
    // The least significant bit 1 marks the edge start, 0 for edge end.
    const encodedEdgeDistance = isConcaveCorner ? (edgeDistance | 2) : (edgeDistance & ~2);
    return edgeStart ? (encodedEdgeDistance | 1) : (encodedEdgeDistance & ~1);
}

function fillExtrusionHeightLift()         {
    // A rectangle covering globe is subdivided into a grid of 32 cells
    // This information can be used to deduce a minimum lift value so that
    // fill extrusions with 0 height will never go below the ground.
    const angle = Math.PI / 32.0;
    const tanAngle = Math.tan(angle);
    const r = earthRadius;
    return r * Math.sqrt(1.0 + 2.0 * tanAngle * tanAngle) - r;
}

// Resamples fill extrusion polygons by subdividing them into 32x16 cells in mercator space.
// The idea is to allow reprojection of large continuous planar shapes on the surface of the globe
function resampleFillExtrusionPolygonsForGlobe(polygons             , tileBounds                , tileID                 )                   {
    const cellCount = 360.0 / 32.0;
    const tiles = 1 << tileID.z;
    const leftLng = lngFromMercatorX(tileID.x / tiles);
    const rightLng = lngFromMercatorX((tileID.x + 1) / tiles);
    const topLat = latFromMercatorY(tileID.y / tiles);
    const bottomLat = latFromMercatorY((tileID.y + 1) / tiles);
    const cellCountOnXAxis = Math.ceil((rightLng - leftLng) / cellCount);
    const cellCountOnYAxis = Math.ceil((topLat - bottomLat) / cellCount);

    const splitFn = (axis        , min        , max        ) => {
        if (axis === 0) {
            return 0.5 * (min + max);
        } else {
            const maxLat = latFromMercatorY((tileID.y + min / EXTENT) / tiles);
            const minLat = latFromMercatorY((tileID.y + max / EXTENT) / tiles);
            const midLat = 0.5 * (minLat + maxLat);
            return (mercatorYfromLat(midLat) * tiles - tileID.y) * EXTENT;
        }
    };

    return subdividePolygons(polygons, tileBounds, cellCountOnXAxis, cellCountOnYAxis, 1.0, splitFn);
}

// This file is generated. Edit build/generate-style-code.js, then run `yarn run codegen`.
//      
/* eslint-disable */


                                                        

                                                                            

                                                                                     

                            
                                                               
   

const layout$2                          = new Properties({
    "fill-extrusion-edge-radius": new DataConstantProperty(spec["layout_fill-extrusion"]["fill-extrusion-edge-radius"]),
});

                           
                                                           
                                                      
                                                                       
                                                                                
                                                                 
                                                        
                                                      
                                                                      
                                                                               
                                                                            
                                                                 
   

const paint$5                         = new Properties({
    "fill-extrusion-opacity": new DataConstantProperty(spec["paint_fill-extrusion"]["fill-extrusion-opacity"]),
    "fill-extrusion-color": new DataDrivenProperty(spec["paint_fill-extrusion"]["fill-extrusion-color"]),
    "fill-extrusion-translate": new DataConstantProperty(spec["paint_fill-extrusion"]["fill-extrusion-translate"]),
    "fill-extrusion-translate-anchor": new DataConstantProperty(spec["paint_fill-extrusion"]["fill-extrusion-translate-anchor"]),
    "fill-extrusion-pattern": new DataDrivenProperty(spec["paint_fill-extrusion"]["fill-extrusion-pattern"]),
    "fill-extrusion-height": new DataDrivenProperty(spec["paint_fill-extrusion"]["fill-extrusion-height"]),
    "fill-extrusion-base": new DataDrivenProperty(spec["paint_fill-extrusion"]["fill-extrusion-base"]),
    "fill-extrusion-vertical-gradient": new DataConstantProperty(spec["paint_fill-extrusion"]["fill-extrusion-vertical-gradient"]),
    "fill-extrusion-ambient-occlusion-intensity": new DataConstantProperty(spec["paint_fill-extrusion"]["fill-extrusion-ambient-occlusion-intensity"]),
    "fill-extrusion-ambient-occlusion-radius": new DataConstantProperty(spec["paint_fill-extrusion"]["fill-extrusion-ambient-occlusion-radius"]),
    "fill-extrusion-rounded-roof": new DataConstantProperty(spec["paint_fill-extrusion"]["fill-extrusion-rounded-roof"]),
});

// Note: without adding the explicit type annotation, Flow infers weaker types
// for these objects from their use in the constructor to StyleLayer, as
// {layout?: Properties<...>, paint: Properties<...>}
var properties$5 = ({ paint: paint$5, layout: layout$2 }          
                                                                
  );

/**
 * getURL
 *
 * @param    {String}  baseUrl  Base url of the WMS server
 * @param    {String}  layer    Layer name
 * @param    {Number}  x        Tile coordinate x
 * @param    {Number}  y        Tile coordinate y
 * @param    {Number}  z        Tile zoom
 * @param    {Object}  [options]
 * @param    {String}  [options.format='image/png']
 * @param    {String}  [options.service='WMS']
 * @param    {String}  [options.version='1.1.1']
 * @param    {String}  [options.request='GetMap']
 * @param    {String}  [options.srs='EPSG:3857']
 * @param    {Number}  [options.width='256']
 * @param    {Number}  [options.height='256']
 * @returns  {String}  url
 * @example
 * var baseUrl = 'http://geodata.state.nj.us/imagerywms/Natural2015';
 * var layer = 'Natural2015';
 * var url = whoots.getURL(baseUrl, layer, 154308, 197167, 19);
 */
function getURL(baseUrl, layer, x, y, z, options) {
    options = options || {};

    var url = baseUrl + '?' + [
        'bbox='    + getTileBBox(x, y, z),
        'format='  + (options.format || 'image/png'),
        'service=' + (options.service || 'WMS'),
        'version=' + (options.version || '1.1.1'),
        'request=' + (options.request || 'GetMap'),
        'srs='     + (options.srs || 'EPSG:3857'),
        'width='   + (options.width || 256),
        'height='  + (options.height || 256),
        'layers='  + layer
    ].join('&');

    return url;
}


/**
 * getTileBBox
 *
 * @param    {Number}  x  Tile coordinate x
 * @param    {Number}  y  Tile coordinate y
 * @param    {Number}  z  Tile zoom
 * @returns  {String}  String of the bounding box
 */
function getTileBBox(x, y, z) {
    // for Google/OSM tile scheme we need to alter the y
    y = (Math.pow(2, z) - y - 1);

    var min = getMercCoords(x * 256, y * 256, z),
        max = getMercCoords((x + 1) * 256, (y + 1) * 256, z);

    return min[0] + ',' + min[1] + ',' + max[0] + ',' + max[1];
}


/**
 * getMercCoords
 *
 * @param    {Number}  x  Pixel coordinate x
 * @param    {Number}  y  Pixel coordinate y
 * @param    {Number}  z  Tile zoom
 * @returns  {Array}   [x, y]
 */
function getMercCoords(x, y, z) {
    var resolution = (2 * Math.PI * 6378137 / 256) / Math.pow(2, z),
        merc_x = (x * resolution - 2 * Math.PI  * 6378137 / 2.0),
        merc_y = (y * resolution - 2 * Math.PI  * 6378137 / 2.0);

    return [merc_x, merc_y];
}

//      


class CanonicalTileID {
              
              
              
                

    constructor(z        , x        , y        ) {
        assert$1(z >= 0 && z <= 25);
        assert$1(x >= 0 && x < Math.pow(2, z));
        assert$1(y >= 0 && y < Math.pow(2, z));
        this.z = z;
        this.x = x;
        this.y = y;
        this.key = calculateKey(0, z, z, x, y);
    }

    equals(id                 )          {
        return this.z === id.z && this.x === id.x && this.y === id.y;
    }

    // given a list of urls, choose a url template and return a tile URL
    url(urls               , scheme         )         {
        const bbox = getTileBBox(this.x, this.y, this.z);
        const quadkey = getQuadkey(this.z, this.x, this.y);

        return urls[(this.x + this.y) % urls.length]
            .replace('{prefix}', (this.x % 16).toString(16) + (this.y % 16).toString(16))
            .replace(/{z}/g, String(this.z))
            .replace(/{x}/g, String(this.x))
            .replace(/{y}/g, String(scheme === 'tms' ? (Math.pow(2, this.z) - this.y - 1) : this.y))
            .replace('{quadkey}', quadkey)
            .replace('{bbox-epsg-3857}', bbox);
    }

    toString()         {
        return `${this.z}/${this.x}/${this.y}`;
    }
}

class UnwrappedTileID {
                 
                               
                

    constructor(wrap        , canonical                 ) {
        this.wrap = wrap;
        this.canonical = canonical;
        this.key = calculateKey(wrap, canonical.z, canonical.z, canonical.x, canonical.y);
    }
}

class OverscaledTileID {
                        
                 
                               
                
                             

    constructor(overscaledZ        , wrap        , z        , x        , y        ) {
        assert$1(overscaledZ >= z);
        this.overscaledZ = overscaledZ;
        this.wrap = wrap;
        this.canonical = new CanonicalTileID(z, +x, +y);
        this.key = wrap === 0 && overscaledZ === z ? this.canonical.key : calculateKey(wrap, overscaledZ, z, x, y);
    }

    equals(id                  )          {
        return this.overscaledZ === id.overscaledZ && this.wrap === id.wrap && this.canonical.equals(id.canonical);
    }

    scaledTo(targetZ        )                   {
        assert$1(targetZ <= this.overscaledZ);
        const zDifference = this.canonical.z - targetZ;
        if (targetZ > this.canonical.z) {
            return new OverscaledTileID(targetZ, this.wrap, this.canonical.z, this.canonical.x, this.canonical.y);
        } else {
            return new OverscaledTileID(targetZ, this.wrap, targetZ, this.canonical.x >> zDifference, this.canonical.y >> zDifference);
        }
    }

    /*
     * calculateScaledKey is an optimization:
     * when withWrap == true, implements the same as this.scaledTo(z).key,
     * when withWrap == false, implements the same as this.scaledTo(z).wrapped().key.
     */
    calculateScaledKey(targetZ        , withWrap          = true)         {
        if (this.overscaledZ === targetZ && withWrap) return this.key;
        if (targetZ > this.canonical.z) {
            return calculateKey(this.wrap * +withWrap, targetZ, this.canonical.z, this.canonical.x, this.canonical.y);
        } else {
            const zDifference = this.canonical.z - targetZ;
            return calculateKey(this.wrap * +withWrap, targetZ, targetZ, this.canonical.x >> zDifference, this.canonical.y >> zDifference);
        }
    }

    isChildOf(parent                  )          {
        if (parent.wrap !== this.wrap) {
            // We can't be a child if we're in a different world copy
            return false;
        }
        const zDifference = this.canonical.z - parent.canonical.z;
        // We're first testing for z == 0, to avoid a 32 bit shift, which is undefined.
        return parent.overscaledZ === 0 || (
            parent.overscaledZ < this.overscaledZ &&
                parent.canonical.x === (this.canonical.x >> zDifference) &&
                parent.canonical.y === (this.canonical.y >> zDifference));
    }

    children(sourceMaxZoom        )                          {
        if (this.overscaledZ >= sourceMaxZoom) {
            // return a single tile coord representing a an overscaled tile
            return [new OverscaledTileID(this.overscaledZ + 1, this.wrap, this.canonical.z, this.canonical.x, this.canonical.y)];
        }

        const z = this.canonical.z + 1;
        const x = this.canonical.x * 2;
        const y = this.canonical.y * 2;
        return [
            new OverscaledTileID(z, this.wrap, z, x, y),
            new OverscaledTileID(z, this.wrap, z, x + 1, y),
            new OverscaledTileID(z, this.wrap, z, x, y + 1),
            new OverscaledTileID(z, this.wrap, z, x + 1, y + 1)
        ];
    }

    isLessThan(rhs                  )          {
        if (this.wrap < rhs.wrap) return true;
        if (this.wrap > rhs.wrap) return false;

        if (this.overscaledZ < rhs.overscaledZ) return true;
        if (this.overscaledZ > rhs.overscaledZ) return false;

        if (this.canonical.x < rhs.canonical.x) return true;
        if (this.canonical.x > rhs.canonical.x) return false;

        if (this.canonical.y < rhs.canonical.y) return true;
        return false;
    }

    wrapped()                   {
        return new OverscaledTileID(this.overscaledZ, 0, this.canonical.z, this.canonical.x, this.canonical.y);
    }

    unwrapTo(wrap        )                   {
        return new OverscaledTileID(this.overscaledZ, wrap, this.canonical.z, this.canonical.x, this.canonical.y);
    }

    overscaleFactor()         {
        return Math.pow(2, this.overscaledZ - this.canonical.z);
    }

    toUnwrapped()                  {
        return new UnwrappedTileID(this.wrap, this.canonical);
    }

    toString()         {
        return `${this.overscaledZ}/${this.canonical.x}/${this.canonical.y}`;
    }
}

function calculateKey(wrap        , overscaledZ        , z        , x        , y        )         {
    // only use 22 bits for x & y so that the key fits into MAX_SAFE_INTEGER
    const dim = 1 << Math.min(z, 22);
    let xy = dim * (y % dim) + (x % dim);

    // zigzag-encode wrap if we have the room for it
    if (wrap && z < 22) {
        const bitsAvailable = 2 * (22 - z);
        xy += dim * dim * ((wrap < 0 ? -2 * wrap - 1 : 2 * wrap) % (1 << bitsAvailable));
    }

    // encode z into 5 bits (24 max) and overscaledZ into 4 bits (10 max)
    const key = ((xy * 32) + z) * 16 + (overscaledZ - z);
    assert$1(key >= 0 && key <= Number.MAX_SAFE_INTEGER);

    return key;
}

function getQuadkey(z        , x        , y        ) {
    let quadkey = '', mask;
    for (let i = z; i > 0; i--) {
        mask = 1 << (i - 1);
        quadkey += ((x & mask ? 1 : 0) + (y & mask ? 2 : 0));
    }
    return quadkey;
}

register(CanonicalTileID, 'CanonicalTileID');
register(OverscaledTileID, 'OverscaledTileID', {omit: ['projMatrix']});

//      


                                                                       
                                                           
                                                                                        
                                                    
                                                                  
                                                                 
                                                           
                                          
                                                            

class Point3D extends Point$2 {
              

    constructor(x        , y        , z        ) {
        super(x, y);
        this.z = z;
    }
}

class FillExtrusionStyleLayer extends StyleLayer {
                                                     
                                                   
                                         
                                           

    constructor(layer                    ) {
        super(layer, properties$5);
    }

    createBucket(parameters                                           )                      {
        return new FillExtrusionBucket(parameters);
    }

    // $FlowFixMe[method-unbinding]
    queryRadius()         {
        return translateDistance(this.paint.get('fill-extrusion-translate'));
    }

    is3D()          {
        return true;
    }

    getProgramIds()           {
        const patternProperty = this.paint.get('fill-extrusion-pattern');
        const image = patternProperty.constantOr((1     ));
        return [image ? 'fillExtrusionPattern' : 'fillExtrusion'];
    }

    getProgramConfiguration(zoom        )                       {
        return new ProgramConfiguration(this, zoom);
    }

    // $FlowFixMe[method-unbinding]
    queryIntersectsFeature(queryGeometry                        ,
                           feature                    ,
                           featureState              ,
                           geometry                     ,
                           zoom        ,
                           transform           ,
                           pixelPosMatrix              ,
                           elevationHelper             ,
                           layoutVertexArrayOffset        )                   {

        const translation = tilespaceTranslate(this.paint.get('fill-extrusion-translate'),
                                this.paint.get('fill-extrusion-translate-anchor'),
                                transform.angle,
                                queryGeometry.pixelToTileUnitsFactor);
        const height = this.paint.get('fill-extrusion-height').evaluate(feature, featureState);
        const base = this.paint.get('fill-extrusion-base').evaluate(feature, featureState);

        const centroid = [0, 0];
        const terrainVisible = elevationHelper && transform.elevation;
        const exaggeration = transform.elevation ? transform.elevation.exaggeration() : 1;
        const bucket = queryGeometry.tile.getBucket(this);
        if (terrainVisible && bucket instanceof FillExtrusionBucket) {
            const centroidVertexArray = bucket.centroidVertexArray;

            // See FillExtrusionBucket#encodeCentroid(), centroid is inserted at vertexOffset + 1
            const centroidOffset = layoutVertexArrayOffset + 1;
            if (centroidOffset < centroidVertexArray.length) {
                centroid[0] = centroidVertexArray.geta_centroid_pos0(centroidOffset);
                centroid[1] = centroidVertexArray.geta_centroid_pos1(centroidOffset);
            }
        }

        // Early exit if fill extrusion is still hidden while waiting for backfill
        const isHidden = centroid[0] === 0 && centroid[1] === 1;
        if (isHidden) return false;

        if (transform.projection.name === 'globe') {
            // Fill extrusion geometry has to be resampled so that large planar polygons
            // can be rendered on the curved surface
            const bounds = [new Point$2(0, 0), new Point$2(EXTENT, EXTENT)];
            const resampledGeometry = resampleFillExtrusionPolygonsForGlobe([geometry], bounds, queryGeometry.tileID.canonical);
            geometry = resampledGeometry.map(clipped => clipped.polygon).flat();
        }

        const demSampler = terrainVisible ? elevationHelper : null;
        const [projectedBase, projectedTop] = projectExtrusion(transform, geometry, base, height, translation, pixelPosMatrix, demSampler, centroid, exaggeration, transform.center.lat, queryGeometry.tileID.canonical);

        const screenQuery = queryGeometry.queryGeometry;
        const projectedQueryGeometry = screenQuery.isPointQuery() ? screenQuery.screenBounds : screenQuery.screenGeometry;
        return checkIntersection(projectedBase, projectedTop, projectedQueryGeometry);
    }
}

function dot(a       , b       ) {
    return a.x * b.x + a.y * b.y;
}

function getIntersectionDistance(projectedQueryGeometry              , projectedFace                )         {

    if (projectedQueryGeometry.length === 1) {
        // For point queries calculate the z at which the point intersects the face
        // using barycentric coordinates.

        // Find the barycentric coordinates of the projected point within the first
        // triangle of the face, using only the xy plane. It doesn't matter if the
        // point is outside the first triangle because all the triangles in the face
        // are in the same plane.
        //
        // Check whether points are coincident and use other points if they are.
        let i = 0;
        const a = projectedFace[i++];
        let b;
        while (!b || a.equals(b)) {
            b = projectedFace[i++];
            if (!b) return Infinity;
        }

        // Loop until point `c` is not colinear with points `a` and `b`.
        for (; i < projectedFace.length; i++) {
            const c = projectedFace[i];

            const p = projectedQueryGeometry[0];

            const ab = b.sub(a);
            const ac = c.sub(a);
            const ap = p.sub(a);

            const dotABAB = dot(ab, ab);
            const dotABAC = dot(ab, ac);
            const dotACAC = dot(ac, ac);
            const dotAPAB = dot(ap, ab);
            const dotAPAC = dot(ap, ac);
            const denom = dotABAB * dotACAC - dotABAC * dotABAC;

            const v = (dotACAC * dotAPAB - dotABAC * dotAPAC) / denom;
            const w = (dotABAB * dotAPAC - dotABAC * dotAPAB) / denom;
            const u = 1 - v - w;

            // Use the barycentric weighting along with the original triangle z coordinates to get the point of intersection.
            const distance = a.z * u + b.z * v + c.z * w;

            if (isFinite(distance)) return distance;
        }

        return Infinity;

    } else {
        // The counts as closest is less clear when the query is a box. This
        // returns the distance to the nearest point on the face, whether it is
        // within the query or not. It could be more correct to return the
        // distance to the closest point within the query box but this would be
        // more complicated and expensive to calculate with little benefit.
        let closestDistance = Infinity;
        for (const p of projectedFace) {
            closestDistance = Math.min(closestDistance, p.z);
        }
        return closestDistance;
    }
}

function checkIntersection(projectedBase                       , projectedTop                       , projectedQueryGeometry              ) {
    let closestDistance = Infinity;

    if (polygonIntersectsMultiPolygon(projectedQueryGeometry, projectedTop)) {
        closestDistance = getIntersectionDistance(projectedQueryGeometry, projectedTop[0]);
    }

    for (let r = 0; r < projectedTop.length; r++) {
        const ringTop = projectedTop[r];
        const ringBase = projectedBase[r];
        for (let p = 0; p < ringTop.length - 1; p++) {
            const topA = ringTop[p];
            const topB = ringTop[p + 1];
            const baseA = ringBase[p];
            const baseB = ringBase[p + 1];
            const face = [topA, topB, baseB, baseA, topA];
            if (polygonIntersectsPolygon(projectedQueryGeometry, face)) {
                closestDistance = Math.min(closestDistance, getIntersectionDistance(projectedQueryGeometry, face));
            }
        }
    }

    return closestDistance === Infinity ? false : closestDistance;
}

function projectExtrusion(tr           , geometry                     , zBase        , zTop        , translation       , m              , demSampler             , centroid      , exaggeration        , lat        , tileID                 ) {
    if (tr.projection.name === 'globe') {
        return projectExtrusionGlobe(tr, geometry, zBase, zTop, translation, m, demSampler, centroid, exaggeration, lat, tileID);
    } else {
        if (demSampler) {
            return projectExtrusion3D(geometry, zBase, zTop, translation, m, demSampler, centroid, exaggeration, lat);
        } else {
            return projectExtrusion2D(geometry, zBase, zTop, translation, m);
        }
    }
}

function projectExtrusionGlobe(tr           , geometry                     , zBase        , zTop        , translation       , m              , demSampler             , centroid      , exaggeration        , lat        , tileID                 ) {
    const projectedBase = [];
    const projectedTop = [];
    const elevationScale = tr.projection.upVectorScale(tileID, tr.center.lat, tr.worldSize).metersToTile;
    const basePoint = [0, 0, 0, 1];
    const topPoint = [0, 0, 0, 1];

    const setPoint = (point               , x        , y        , z        ) => {
        point[0] = x;
        point[1] = y;
        point[2] = z;
        point[3] = 1;
    };

    // Fixed "lift" value is added to height so that 0-height fill extrusions wont clip with globe's surface
    const lift = fillExtrusionHeightLift();

    if (zBase > 0) {
        zBase += lift;
    }
    zTop += lift;

    for (const r of geometry) {
        const ringBase = [];
        const ringTop = [];
        for (const p of r) {
            const x = p.x + translation.x;
            const y = p.y + translation.y;

            // Reproject tile coordinate into ecef and apply elevation to correct direction
            const reproj = tr.projection.projectTilePoint(x, y, tileID);
            const dir = tr.projection.upVector(tileID, p.x, p.y);

            let zBasePoint = zBase;
            let zTopPoint = zTop;

            if (demSampler) {
                const offset = getTerrainHeightOffset(x, y, zBase, zTop, demSampler, centroid, exaggeration, lat);

                zBasePoint += offset.base;
                zTopPoint += offset.top;
            }

            if (zBase !== 0) {
                setPoint(
                    basePoint,
                    reproj.x + dir[0] * elevationScale * zBasePoint,
                    reproj.y + dir[1] * elevationScale * zBasePoint,
                    reproj.z + dir[2] * elevationScale * zBasePoint);
            } else {
                setPoint(basePoint, reproj.x, reproj.y, reproj.z);
            }

            setPoint(
                topPoint,
                reproj.x + dir[0] * elevationScale * zTopPoint,
                reproj.y + dir[1] * elevationScale * zTopPoint,
                reproj.z + dir[2] * elevationScale * zTopPoint);

            transformMat4$2(basePoint, basePoint, m);
            transformMat4$2(topPoint, topPoint, m);

            ringBase.push(new Point3D(basePoint[0], basePoint[1], basePoint[2]));
            ringTop.push(new Point3D(topPoint[0], topPoint[1], topPoint[2]));
        }
        projectedBase.push(ringBase);
        projectedTop.push(ringTop);
    }

    return [projectedBase, projectedTop];
}

/*
 * Project the geometry using matrix `m`. This is essentially doing
 * `vec4.transformMat4([], [p.x, p.y, z, 1], m)` but the multiplication
 * is inlined so that parts of the projection that are the same across
 * different points can only be done once. This produced a measurable
 * performance improvement.
 */
function projectExtrusion2D(geometry                     , zBase        , zTop        , translation       , m              ) {
    const projectedBase = [];
    const projectedTop = [];

    const baseXZ = m[8] * zBase;
    const baseYZ = m[9] * zBase;
    const baseZZ = m[10] * zBase;
    const baseWZ = m[11] * zBase;
    const topXZ = m[8] * zTop;
    const topYZ = m[9] * zTop;
    const topZZ = m[10] * zTop;
    const topWZ = m[11] * zTop;

    for (const r of geometry) {
        const ringBase = [];
        const ringTop = [];
        for (const p of r) {
            const x = p.x + translation.x;
            const y = p.y + translation.y;

            const sX = m[0] * x + m[4] * y + m[12];
            const sY = m[1] * x + m[5] * y + m[13];
            const sZ = m[2] * x + m[6] * y + m[14];
            const sW = m[3] * x + m[7] * y + m[15];

            const baseX = sX + baseXZ;
            const baseY = sY + baseYZ;
            const baseZ = sZ + baseZZ;
            const baseW = Math.max(sW + baseWZ, 0.00001);

            const topX = sX + topXZ;
            const topY = sY + topYZ;
            const topZ = sZ + topZZ;
            const topW = Math.max(sW + topWZ, 0.00001);

            ringBase.push(new Point3D(baseX / baseW, baseY / baseW, baseZ / baseW));
            ringTop.push(new Point3D(topX / topW, topY / topW, topZ / topW));
        }
        projectedBase.push(ringBase);
        projectedTop.push(ringTop);
    }
    return [projectedBase, projectedTop];
}

/*
 * Projects a fill extrusion vertices to screen while accounting for terrain.
 * This and its dependent functions are ported directly from `fill_extrusion.vertex.glsl`
 * with a few co-ordinate space differences.
 *
 * - Matrix `m` projects to screen-pixel space instead of to gl-coordinates (NDC)
 * - Texture querying is performed in texture pixel coordinates instead of  normalized uv coordinates.
 * - Height offset calculation for fill-extrusion-base is offset with -1 instead of -5 to prevent underground picking.
 */
function projectExtrusion3D(geometry                     , zBase        , zTop        , translation       , m              , demSampler            , centroid      , exaggeration        , lat        ) {
    const projectedBase = [];
    const projectedTop = [];
    const v = [0, 0, 0, 1];

    for (const r of geometry) {
        const ringBase = [];
        const ringTop = [];
        for (const p of r) {
            const x = p.x + translation.x;
            const y = p.y + translation.y;
            const heightOffset = getTerrainHeightOffset(x, y, zBase, zTop, demSampler, centroid, exaggeration, lat);

            v[0] = x;
            v[1] = y;
            v[2] = heightOffset.base;
            v[3] = 1;
            transformMat4$1(v, v, m);
            v[3] = Math.max(v[3], 0.00001);
            const base = new Point3D(v[0] / v[3], v[1] / v[3], v[2] / v[3]);

            v[0] = x;
            v[1] = y;
            v[2] = heightOffset.top;
            v[3] = 1;
            transformMat4$1(v, v, m);
            v[3] = Math.max(v[3], 0.00001);
            const top = new Point3D(v[0] / v[3], v[1] / v[3], v[2] / v[3]);

            ringBase.push(base);
            ringTop.push(top);
        }
        projectedBase.push(ringBase);
        projectedTop.push(ringTop);
    }
    return [projectedBase, projectedTop];
}

function getTerrainHeightOffset(x        , y        , zBase        , zTop        , demSampler            , centroid      , exaggeration        , lat        )                               {
    const ele = exaggeration * demSampler.getElevationAt(x, y, true, true);
    const flatRoof = centroid[0] !== 0;
    const centroidElevation = flatRoof ? centroid[1] === 0 ? exaggeration * elevationFromUint16(centroid[0]) : exaggeration * flatElevation(demSampler, centroid, lat) : ele;
    return {
        base: ele + (zBase === 0) ? -1 : zBase, // Use -1 instead of -5 in shader to prevent picking underground
        top: flatRoof ? Math.max(centroidElevation + zTop, ele + zBase + 2) : ele + zTop
    };
}

// Elevation is encoded into unit16 in fill_extrusion_bucket.js FillExtrusionBucket#encodeCentroid
function elevationFromUint16(n        )         {
    return n / ELEVATION_SCALE - ELEVATION_OFFSET;
}

// Equivalent GPU side function is in _prelude_terrain.vertex.glsl
function flatElevation(demSampler            , centroid      , lat        )         {
    // Span and pos are packed two 16 bit uint16 values in fill_extrusion_bucket.js FillExtrusionBucket#encodeCentroid
    // pos is encoded by << by 3 bits thus dividing by 8 performs equivalent of right shifting it back.
    const posX = Math.floor(centroid[0] / 8);
    const posY = Math.floor(centroid[1] / 8);

    // Span is stored in the lower three bits in multiples of 10
    const spanX = 10 * (centroid[0] - posX * 8);
    const spanY = 10 * (centroid[1] - posY * 8);

    // Get height at centroid
    const z = demSampler.getElevationAt(posX, posY, true, true);
    const meterToDEM = demSampler.getMeterToDEM(lat);

    const wX = Math.floor(0.5 * (spanX * meterToDEM - 1));
    const wY = Math.floor(0.5 * (spanY * meterToDEM - 1));

    const posPx = demSampler.tileCoordToPixel(posX, posY);

    const offsetX = 2 * wX + 1;
    const offsetY = 2 * wY + 1;
    const corners = fourSample(demSampler, posPx.x - wX, posPx.y - wY, offsetX, offsetY);

    const diffX = Math.abs(corners[0] - corners[1]);
    const diffY = Math.abs(corners[2] - corners[3]);
    const diffZ = Math.abs(corners[0] - corners[2]);
    const diffW = Math.abs(corners[1] - corners[3]);

    const diffSumX = diffX + diffY;
    const diffSumY = diffZ + diffW;

    const slopeX = Math.min(0.25, meterToDEM * 0.5 * diffSumX / offsetX);
    const slopeY = Math.min(0.25, meterToDEM * 0.5 * diffSumY / offsetY);

    return z + Math.max(slopeX * spanX, slopeY * spanY);
}

function fourSample(demSampler            , posX        , posY        , offsetX        , offsetY        )       {
    return [
        demSampler.getElevationAtPixel(posX, posY, true),
        demSampler.getElevationAtPixel(posX + offsetY, posY, true),
        demSampler.getElevationAtPixel(posX, posY + offsetY, true),
        demSampler.getElevationAtPixel(posX + offsetX, posY + offsetY, true)
    ];
}

//      

                                                                  

const lineLayoutAttributes                    = createLayout([
    {name: 'a_pos_normal', components: 2, type: 'Int16'},
    {name: 'a_data', components: 4, type: 'Uint8'},
    {name: 'a_linesofar', components: 1, type: 'Float32'}
], 4);
const {members: members$1, size: size$1, alignment: alignment$1} = lineLayoutAttributes;

//      

                                                                  

const lineLayoutAttributesExt                    = createLayout([
    {name: 'a_packed', components: 4, type: 'Float32'}
]);
const {members, size, alignment} = lineLayoutAttributesExt;

//      

const vectorTileFeatureTypes$1 = VectorTileFeature.types;
                                                                       
                                                             
             
           
                     
                  
                   
                      
                      
                                                                              
                                                
                                           
                                                                    
                                               
                                                   
                                                        
                                                          
                                                                
                                                        
                                                                          
                                                          

// NOTE ON EXTRUDE SCALE:
// scale the extrusion vector so that the normal length is this value.
// contains the "texture" normals (-1..1). this is distinct from the extrude
// normals for line joins, because the x-value remains 0 for the texture
// normal array, while the extrude normal actually moves the vertex to create
// the acute/bevelled line join.
const EXTRUDE_SCALE = 63;

/*
 * Sharp corners cause dashed lines to tilt because the distance along the line
 * is the same at both the inner and outer corners. To improve the appearance of
 * dashed lines we add extra points near sharp corners so that a smaller part
 * of the line is tilted.
 *
 * COS_HALF_SHARP_CORNER controls how sharp a corner has to be for us to add an
 * extra vertex. The default is 75 degrees.
 *
 * The newly created vertices are placed SHARP_CORNER_OFFSET pixels from the corner.
 */
const COS_HALF_SHARP_CORNER = Math.cos(75 / 2 * (Math.PI / 180));
const SHARP_CORNER_OFFSET = 15;

// Angle per triangle for approximating round line joins.
const DEG_PER_TRIANGLE = 20;

                  
                  
                
 

                        
                     
                         
                    
 

/**
 * @private
 */
class LineBucket                   {
                     
                          
                          
                           
                      
                          

               
               

                  
                 
                        
                                  
                            
                                           
                                     
                                          
                                          
                                     

                                       
                                     
                                           
                                      

                                   
                             

                        
                                                                   
                            
                      
                                        

    constructor(options                                  ) {
        this.zoom = options.zoom;
        this.overscaling = options.overscaling;
        this.layers = options.layers;
        this.layerIds = this.layers.map(layer => layer.id);
        this.index = options.index;
        this.projection = options.projection;
        this.hasPattern = false;
        this.patternFeatures = [];
        this.lineClipsArray = [];
        this.gradients = {};
        this.layers.forEach(layer => {
            this.gradients[layer.id] = {};
        });

        this.layoutVertexArray = new StructArrayLayout2i4ub1f12();
        this.layoutVertexArray2 = new StructArrayLayout4f16();
        this.indexArray = new StructArrayLayout3ui6();
        this.programConfigurations = new ProgramConfigurationSet(options.layers, options.zoom);
        this.segments = new SegmentVector();
        this.maxLineLength = 0;

        this.stateDependentLayerIds = this.layers.filter((l) => l.isStateDependent()).map((l) => l.id);
    }

    populate(features                       , options                    , canonical                 , tileTransform               ) {
        this.hasPattern = hasPattern('line', this.layers, options);
        const lineSortKey = this.layers[0].layout.get('line-sort-key');
        const bucketFeatures = [];

        for (const {feature, id, index, sourceLayerIndex} of features) {
            const needGeometry = this.layers[0]._featureFilter.needGeometry;
            const evaluationFeature = toEvaluationFeature(feature, needGeometry);

            // $FlowFixMe[method-unbinding]
            if (!this.layers[0]._featureFilter.filter(new EvaluationParameters(this.zoom), evaluationFeature, canonical)) continue;

            const sortKey = lineSortKey ?
                lineSortKey.evaluate(evaluationFeature, {}, canonical) :
                undefined;

            const bucketFeature                = {
                id,
                properties: feature.properties,
                type: feature.type,
                sourceLayerIndex,
                index,
                geometry: needGeometry ? evaluationFeature.geometry : loadGeometry(feature, canonical, tileTransform),
                patterns: {},
                sortKey
            };

            bucketFeatures.push(bucketFeature);
        }

        if (lineSortKey) {
            bucketFeatures.sort((a, b) => {
                // a.sortKey is always a number when in use
                return ((a.sortKey     )        ) - ((b.sortKey     )        );
            });
        }

        const {lineAtlas, featureIndex} = options;
        const hasFeatureDashes = this.addConstantDashes(lineAtlas);

        for (const bucketFeature of bucketFeatures) {
            const {geometry, index, sourceLayerIndex} = bucketFeature;

            if (hasFeatureDashes) {
                this.addFeatureDashes(bucketFeature, lineAtlas);
            }

            if (this.hasPattern) {
                const patternBucketFeature = addPatternDependencies('line', this.layers, bucketFeature, this.zoom, options);
                // pattern features are added only once the pattern is loaded into the image atlas
                // so are stored during populate until later updated with positions by tile worker in addFeatures
                this.patternFeatures.push(patternBucketFeature);

            } else {
                this.addFeature(bucketFeature, geometry, index, canonical, lineAtlas.positions, options.availableImages);
            }

            const feature = features[index].feature;
            featureIndex.insert(feature, geometry, index, sourceLayerIndex, this.index);
        }
    }

    addConstantDashes(lineAtlas           )          {
        let hasFeatureDashes = false;

        for (const layer of this.layers) {
            const dashPropertyValue = layer.paint.get('line-dasharray').value;
            const capPropertyValue = layer.layout.get('line-cap').value;

            if (dashPropertyValue.kind !== 'constant' || capPropertyValue.kind !== 'constant') {
                hasFeatureDashes = true;

            } else {
                const constCap = capPropertyValue.value;
                const constDash = dashPropertyValue.value;
                if (!constDash) continue;
                lineAtlas.addDash(constDash, constCap);
            }
        }

        return hasFeatureDashes;
    }

    addFeatureDashes(feature               , lineAtlas           ) {

        const zoom = this.zoom;

        for (const layer of this.layers) {
            const dashPropertyValue = layer.paint.get('line-dasharray').value;
            const capPropertyValue = layer.layout.get('line-cap').value;

            if (dashPropertyValue.kind === 'constant' && capPropertyValue.kind === 'constant') continue;

            let dashArray, cap;

            if (dashPropertyValue.kind === 'constant') {
                dashArray = dashPropertyValue.value;
                if (!dashArray) continue;

            } else {
                dashArray = dashPropertyValue.evaluate({zoom}, feature);
            }

            if (capPropertyValue.kind === 'constant') {
                cap = capPropertyValue.value;

            } else {
                cap = capPropertyValue.evaluate({zoom}, feature);
            }

            lineAtlas.addDash(dashArray, cap);

            // save positions for paint array
            feature.patterns[layer.id] = lineAtlas.getKey(dashArray, cap);
        }

    }

    update(states               , vtLayer                  , availableImages               , imagePositions                 ) {
        if (!this.stateDependentLayers.length) return;
        this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers, availableImages, imagePositions);
    }

    addFeatures(options                    , canonical                 , imagePositions                 , availableImages               , _               ) {
        for (const feature of this.patternFeatures) {
            this.addFeature(feature, feature.geometry, feature.index, canonical, imagePositions, availableImages);
        }
    }

    isEmpty()          {
        return this.layoutVertexArray.length === 0;
    }

    uploadPending()          {
        return !this.uploaded || this.programConfigurations.needsUpload;
    }

    upload(context         ) {
        if (!this.uploaded) {
            if (this.layoutVertexArray2.length !== 0) {
                this.layoutVertexBuffer2 = context.createVertexBuffer(this.layoutVertexArray2, members);
            }
            this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray, members$1);
            this.indexBuffer = context.createIndexBuffer(this.indexArray);
        }
        this.programConfigurations.upload(context);
        this.uploaded = true;
    }

    destroy() {
        if (!this.layoutVertexBuffer) return;
        this.layoutVertexBuffer.destroy();
        this.indexBuffer.destroy();
        this.programConfigurations.destroy();
        this.segments.destroy();
    }

    lineFeatureClips(feature               )             {
        if (!!feature.properties && feature.properties.hasOwnProperty('mapbox_clip_start') && feature.properties.hasOwnProperty('mapbox_clip_end')) {
            const start = +feature.properties['mapbox_clip_start'];
            const end = +feature.properties['mapbox_clip_end'];
            return {start, end};
        }
    }

    addFeature(feature               , geometry                     , index        , canonical                 , imagePositions                 , availableImages               ) {
        const layout = this.layers[0].layout;
        const join = layout.get('line-join').evaluate(feature, {});
        const cap = layout.get('line-cap').evaluate(feature, {});
        const miterLimit = layout.get('line-miter-limit');
        const roundLimit = layout.get('line-round-limit');
        this.lineClips = this.lineFeatureClips(feature);

        for (const line of geometry) {
            this.addLine(line, feature, join, cap, miterLimit, roundLimit);
        }

        this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index, imagePositions, availableImages, canonical);
    }

    addLine(vertices              , feature               , join        , cap        , miterLimit        , roundLimit        ) {
        this.distance = 0;
        this.scaledDistance = 0;
        this.totalDistance = 0;
        this.lineSoFar = 0;

        if (this.lineClips) {
            this.lineClipsArray.push(this.lineClips);
            // Calculate the total distance, in tile units, of this tiled line feature
            for (let i = 0; i < vertices.length - 1; i++) {
                this.totalDistance += vertices[i].dist(vertices[i + 1]);
            }
            this.updateScaledDistance();
            this.maxLineLength = Math.max(this.maxLineLength, this.totalDistance);
        }

        const isPolygon = vectorTileFeatureTypes$1[feature.type] === 'Polygon';

        // If the line has duplicate vertices at the ends, adjust start/length to remove them.
        let len = vertices.length;
        while (len >= 2 && vertices[len - 1].equals(vertices[len - 2])) {
            len--;
        }
        let first = 0;
        while (first < len - 1 && vertices[first].equals(vertices[first + 1])) {
            first++;
        }

        // Ignore invalid geometry.
        if (len < (isPolygon ? 3 : 2)) return;

        if (join === 'bevel') miterLimit = 1.05;

        const sharpCornerOffset = this.overscaling <= 16 ?
            SHARP_CORNER_OFFSET * EXTENT / (512 * this.overscaling) :
            0;

        // we could be more precise, but it would only save a negligible amount of space
        const segment = this.segments.prepareSegment(len * 10, this.layoutVertexArray, this.indexArray);

        let currentVertex;
        let prevVertex = ((undefined     )       );
        let nextVertex = ((undefined     )       );
        let prevNormal = ((undefined     )       );
        let nextNormal = ((undefined     )       );

        // the last two vertices added
        this.e1 = this.e2 = -1;

        if (isPolygon) {
            currentVertex = vertices[len - 2];
            nextNormal = vertices[first].sub(currentVertex)._unit()._perp();
        }

        for (let i = first; i < len; i++) {

            nextVertex = i === len - 1 ?
                (isPolygon ? vertices[first + 1] : (undefined     )) : // if it's a polygon, treat the last vertex like the first
                vertices[i + 1]; // just the next vertex

            // if two consecutive vertices exist, skip the current one
            if (nextVertex && vertices[i].equals(nextVertex)) continue;

            if (nextNormal) prevNormal = nextNormal;
            if (currentVertex) prevVertex = currentVertex;

            currentVertex = vertices[i];

            // Calculate the normal towards the next vertex in this line. In case
            // there is no next vertex, pretend that the line is continuing straight,
            // meaning that we are just using the previous normal.
            nextNormal = nextVertex ? nextVertex.sub(currentVertex)._unit()._perp() : prevNormal;

            // If we still don't have a previous normal, this is the beginning of a
            // non-closed line, so we're doing a straight "join".
            prevNormal = prevNormal || nextNormal;

            // Determine the normal of the join extrusion. It is the angle bisector
            // of the segments between the previous line and the next line.
            // In the case of 180° angles, the prev and next normals cancel each other out:
            // prevNormal + nextNormal = (0, 0), its magnitude is 0, so the unit vector would be
            // undefined. In that case, we're keeping the joinNormal at (0, 0), so that the cosHalfAngle
            // below will also become 0 and miterLength will become Infinity.
            let joinNormal = prevNormal.add(nextNormal);
            if (joinNormal.x !== 0 || joinNormal.y !== 0) {
                joinNormal._unit();
            }
            /*  joinNormal     prevNormal
             *             ↖      ↑
             *                .________. prevVertex
             *                |
             * nextNormal  ←  |  currentVertex
             *                |
             *     nextVertex !
             *
             */

            // calculate cosines of the angle (and its half) using dot product
            const cosAngle = prevNormal.x * nextNormal.x + prevNormal.y * nextNormal.y;
            const cosHalfAngle = joinNormal.x * nextNormal.x + joinNormal.y * nextNormal.y;

            // Calculate the length of the miter (the ratio of the miter to the width)
            // as the inverse of cosine of the angle between next and join normals
            const miterLength = cosHalfAngle !== 0 ? 1 / cosHalfAngle : Infinity;

            // approximate angle from cosine
            const approxAngle = 2 * Math.sqrt(2 - 2 * cosHalfAngle);

            const isSharpCorner = cosHalfAngle < COS_HALF_SHARP_CORNER && prevVertex && nextVertex;
            const lineTurnsLeft = prevNormal.x * nextNormal.y - prevNormal.y * nextNormal.x > 0;

            if (isSharpCorner && i > first) {
                const prevSegmentLength = currentVertex.dist(prevVertex);
                if (prevSegmentLength > 2 * sharpCornerOffset) {
                    const newPrevVertex = currentVertex.sub(currentVertex.sub(prevVertex)._mult(sharpCornerOffset / prevSegmentLength)._round());
                    this.updateDistance(prevVertex, newPrevVertex);
                    this.addCurrentVertex(newPrevVertex, prevNormal, 0, 0, segment);
                    prevVertex = newPrevVertex;
                }
            }

            // The join if a middle vertex, otherwise the cap.
            const middleVertex = prevVertex && nextVertex;
            let currentJoin = middleVertex ? join : isPolygon ? 'butt' : cap;

            if (middleVertex && currentJoin === 'round') {
                if (miterLength < roundLimit) {
                    currentJoin = 'miter';
                } else if (miterLength <= 2) {
                    currentJoin = 'fakeround';
                }
            }

            if (currentJoin === 'miter' && miterLength > miterLimit) {
                currentJoin = 'bevel';
            }

            if (currentJoin === 'bevel') {
                // The maximum extrude length is 128 / 63 = 2 times the width of the line
                // so if miterLength >= 2 we need to draw a different type of bevel here.
                if (miterLength > 2) currentJoin = 'flipbevel';

                // If the miterLength is really small and the line bevel wouldn't be visible,
                // just draw a miter join to save a triangle.
                if (miterLength < miterLimit) currentJoin = 'miter';
            }

            // Calculate how far along the line the currentVertex is
            if (prevVertex) this.updateDistance(prevVertex, currentVertex);

            if (currentJoin === 'miter') {

                joinNormal._mult(miterLength);
                this.addCurrentVertex(currentVertex, joinNormal, 0, 0, segment);

            } else if (currentJoin === 'flipbevel') {
                // miter is too big, flip the direction to make a beveled join

                if (miterLength > 100) {
                    // Almost parallel lines
                    joinNormal = nextNormal.mult(-1);

                } else {
                    const bevelLength = miterLength * prevNormal.add(nextNormal).mag() / prevNormal.sub(nextNormal).mag();
                    joinNormal._perp()._mult(bevelLength * (lineTurnsLeft ? -1 : 1));
                }
                this.addCurrentVertex(currentVertex, joinNormal, 0, 0, segment);
                this.addCurrentVertex(currentVertex, joinNormal.mult(-1), 0, 0, segment);

            } else if (currentJoin === 'bevel' || currentJoin === 'fakeround') {
                const offset = -Math.sqrt(miterLength * miterLength - 1);
                const offsetA = lineTurnsLeft ? offset : 0;
                const offsetB = lineTurnsLeft ? 0 : offset;

                // Close previous segment with a bevel
                if (prevVertex) {
                    this.addCurrentVertex(currentVertex, prevNormal, offsetA, offsetB, segment);
                }

                if (currentJoin === 'fakeround') {
                    // The join angle is sharp enough that a round join would be visible.
                    // Bevel joins fill the gap between segments with a single pie slice triangle.
                    // Create a round join by adding multiple pie slices. The join isn't actually round, but
                    // it looks like it is at the sizes we render lines at.

                    // pick the number of triangles for approximating round join by based on the angle between normals
                    const n = Math.round((approxAngle * 180 / Math.PI) / DEG_PER_TRIANGLE);

                    for (let m = 1; m < n; m++) {
                        let t = m / n;
                        if (t !== 0.5) {
                            // approximate spherical interpolation https://observablehq.com/@mourner/approximating-geometric-slerp
                            const t2 = t - 0.5;
                            const A = 1.0904 + cosAngle * (-3.2452 + cosAngle * (3.55645 - cosAngle * 1.43519));
                            const B = 0.848013 + cosAngle * (-1.06021 + cosAngle * 0.215638);
                            t = t + t * t2 * (t - 1) * (A * t2 * t2 + B);
                        }
                        const extrude = nextNormal.sub(prevNormal)._mult(t)._add(prevNormal)._unit()._mult(lineTurnsLeft ? -1 : 1);
                        this.addHalfVertex(currentVertex, extrude.x, extrude.y, false, lineTurnsLeft, 0, segment);
                    }
                }

                if (nextVertex) {
                    // Start next segment
                    this.addCurrentVertex(currentVertex, nextNormal, -offsetA, -offsetB, segment);
                }

            } else if (currentJoin === 'butt') {
                this.addCurrentVertex(currentVertex, joinNormal, 0, 0, segment); // butt cap

            } else if (currentJoin === 'square') {
                const offset = prevVertex ? 1 : -1; // closing or starting square cap

                if (!prevVertex) {
                    this.addCurrentVertex(currentVertex, joinNormal, offset, offset, segment);
                }

                // make the cap it's own quad to avoid the cap affecting the line distance
                this.addCurrentVertex(currentVertex, joinNormal, 0, 0, segment);

                if (prevVertex) {
                    this.addCurrentVertex(currentVertex, joinNormal, offset, offset, segment);
                }

            } else if (currentJoin === 'round') {

                if (prevVertex) {
                    // Close previous segment with butt
                    this.addCurrentVertex(currentVertex, prevNormal, 0, 0, segment);

                    // Add round cap or linejoin at end of segment
                    this.addCurrentVertex(currentVertex, prevNormal, 1, 1, segment, true);
                }
                if (nextVertex) {
                    // Add round cap before first segment
                    this.addCurrentVertex(currentVertex, nextNormal, -1, -1, segment, true);

                    // Start next segment with a butt
                    this.addCurrentVertex(currentVertex, nextNormal, 0, 0, segment);
                }
            }

            if (isSharpCorner && i < len - 1) {
                const nextSegmentLength = currentVertex.dist(nextVertex);
                if (nextSegmentLength > 2 * sharpCornerOffset) {
                    const newCurrentVertex = currentVertex.add(nextVertex.sub(currentVertex)._mult(sharpCornerOffset / nextSegmentLength)._round());
                    this.updateDistance(currentVertex, newCurrentVertex);
                    this.addCurrentVertex(newCurrentVertex, nextNormal, 0, 0, segment);
                    currentVertex = newCurrentVertex;
                }
            }
        }
    }

    /**
     * Add two vertices to the buffers.
     *
     * @param p the line vertex to add buffer vertices for
     * @param normal vertex normal
     * @param endLeft extrude to shift the left vertex along the line
     * @param endRight extrude to shift the left vertex along the line
     * @param segment the segment object to add the vertex to
     * @param round whether this is a round cap
     * @private
     */
    addCurrentVertex(p       , normal       , endLeft        , endRight        , segment         , round          = false) {
        // left and right extrude vectors, perpendicularly shifted by endLeft/endRight
        const leftX = normal.x + normal.y * endLeft;
        const leftY = normal.y - normal.x * endLeft;
        const rightX = -normal.x + normal.y * endRight;
        const rightY = -normal.y - normal.x * endRight;

        this.addHalfVertex(p, leftX, leftY, round, false, endLeft, segment);
        this.addHalfVertex(p, rightX, rightY, round, true, -endRight, segment);
    }

    addHalfVertex({x, y}       , extrudeX        , extrudeY        , round         , up         , dir        , segment         ) {
        this.layoutVertexArray.emplaceBack(
            // a_pos_normal
            // Encode round/up the least significant bits
            (x << 1) + (round ? 1 : 0),
            (y << 1) + (up ? 1 : 0),
            // a_data
            // add 128 to store a byte in an unsigned byte
            Math.round(EXTRUDE_SCALE * extrudeX) + 128,
            Math.round(EXTRUDE_SCALE * extrudeY) + 128,
            ((dir === 0 ? 0 : (dir < 0 ? -1 : 1)) + 1),
            0, // unused
            // a_linesofar
            this.lineSoFar);

        // Constructs a second vertex buffer with higher precision line progress
        if (this.lineClips) {
            this.layoutVertexArray2.emplaceBack(this.scaledDistance, this.lineClipsArray.length, this.lineClips.start, this.lineClips.end);
        }

        const e = segment.vertexLength++;
        if (this.e1 >= 0 && this.e2 >= 0) {
            this.indexArray.emplaceBack(this.e1, this.e2, e);
            segment.primitiveLength++;
        }
        if (up) {
            this.e2 = e;
        } else {
            this.e1 = e;
        }
    }

    updateScaledDistance() {
        // Knowing the ratio of the full linestring covered by this tiled feature, as well
        // as the total distance (in tile units) of this tiled feature, and the distance
        // (in tile units) of the current vertex, we can determine the relative distance
        // of this vertex along the full linestring feature.
        if (this.lineClips) {
            const featureShare = this.lineClips.end - this.lineClips.start;
            const totalFeatureLength = this.totalDistance / featureShare;
            this.scaledDistance = this.distance / this.totalDistance;
            this.lineSoFar = totalFeatureLength * this.lineClips.start + this.distance;
        } else {
            this.lineSoFar = this.distance;
        }
    }

    updateDistance(prev       , next       ) {
        this.distance += prev.dist(next);
        this.updateScaledDistance();
    }
}

register(LineBucket, 'LineBucket', {omit: ['layers', 'patternFeatures']});

// This file is generated. Edit build/generate-style-code.js, then run `yarn run codegen`.
//      
/* eslint-disable */


                                                        

                                                                            

                                                                                     

                            
                                                                
                                                                 
                                                     
                                                     
                                                
   

const layout$1                          = new Properties({
    "line-cap": new DataDrivenProperty(spec["layout_line"]["line-cap"]),
    "line-join": new DataDrivenProperty(spec["layout_line"]["line-join"]),
    "line-miter-limit": new DataConstantProperty(spec["layout_line"]["line-miter-limit"]),
    "line-round-limit": new DataConstantProperty(spec["layout_line"]["line-round-limit"]),
    "line-sort-key": new DataDrivenProperty(spec["layout_line"]["line-sort-key"]),
});

                           
                                               
                                            
                                                             
                                                                      
                                             
                                                 
                                              
                                            
                                                         
                                                       
                                       
                                                               
   

const paint$4                         = new Properties({
    "line-opacity": new DataDrivenProperty(spec["paint_line"]["line-opacity"]),
    "line-color": new DataDrivenProperty(spec["paint_line"]["line-color"]),
    "line-translate": new DataConstantProperty(spec["paint_line"]["line-translate"]),
    "line-translate-anchor": new DataConstantProperty(spec["paint_line"]["line-translate-anchor"]),
    "line-width": new DataDrivenProperty(spec["paint_line"]["line-width"]),
    "line-gap-width": new DataDrivenProperty(spec["paint_line"]["line-gap-width"]),
    "line-offset": new DataDrivenProperty(spec["paint_line"]["line-offset"]),
    "line-blur": new DataDrivenProperty(spec["paint_line"]["line-blur"]),
    "line-dasharray": new DataDrivenProperty(spec["paint_line"]["line-dasharray"]),
    "line-pattern": new DataDrivenProperty(spec["paint_line"]["line-pattern"]),
    "line-gradient": new ColorRampProperty(spec["paint_line"]["line-gradient"]),
    "line-trim-offset": new DataConstantProperty(spec["paint_line"]["line-trim-offset"]),
});

// Note: without adding the explicit type annotation, Flow infers weaker types
// for these objects from their use in the constructor to StyleLayer, as
// {layout?: Properties<...>, paint: Properties<...>}
var properties$4 = ({ paint: paint$4, layout: layout$1 }          
                                                                
  );

//      

                                                                                                            
                                                                                                                                 
                                                                   
                                                                              
                                                    
                                                                  
                                                                 
                                                            

class LineFloorwidthProperty extends DataDrivenProperty         {
                             

    possiblyEvaluate(value                                                               , parameters                      )                                         {
        parameters = new EvaluationParameters(Math.floor(parameters.zoom), {
            now: parameters.now,
            fadeDuration: parameters.fadeDuration,
            transition: parameters.transition
        });
        return super.possiblyEvaluate(value, parameters);
    }

    evaluate(value                                , globals                      , feature         , featureState              )         {
        globals = extend$1({}, globals, {zoom: Math.floor(globals.zoom)});
        return super.evaluate(value, globals, feature, featureState);
    }
}

const lineFloorwidthProperty = new LineFloorwidthProperty(properties$4.paint.properties['line-width'].specification);
lineFloorwidthProperty.useIntegerZoom = true;

class LineStyleLayer extends StyleLayer {
                                            
                                           

                            
                             

                                                     
                                                   
                                         

    constructor(layer                    ) {
        super(layer, properties$4);
        this.gradientVersion = 0;
    }

    _handleSpecialPaintPropertyUpdate(name        ) {
        if (name === 'line-gradient') {
            const expression                                   = ((this._transitionablePaint._values['line-gradient'].value.expression)     );
            this.stepInterpolant = expression._styleExpression && expression._styleExpression.expression instanceof Step;
            this.gradientVersion = (this.gradientVersion + 1) % Number.MAX_SAFE_INTEGER;
        }
    }

    gradientExpression()                          {
        return this._transitionablePaint._values['line-gradient'].value.expression;
    }

    widthExpression()                          {
        return this._transitionablePaint._values['line-width'].value.expression;
    }

    recalculate(parameters                      , availableImages               ) {
        super.recalculate(parameters, availableImages);

        (this.paint._values     )['line-floorwidth'] =
            lineFloorwidthProperty.possiblyEvaluate(this._transitioningPaint._values['line-width'].value, parameters);
    }

    createBucket(parameters                                  )             {
        return new LineBucket(parameters);
    }

    getProgramIds()           {
        const patternProperty = this.paint.get('line-pattern');
        const image = patternProperty.constantOr((1     ));
        const programId = image ? 'linePattern' : 'line';
        return [programId];
    }

    getProgramConfiguration(zoom        )                       {
        return new ProgramConfiguration(this, zoom);
    }

    // $FlowFixMe[method-unbinding]
    queryRadius(bucket        )         {
        const lineBucket             = (bucket     );
        const width = getLineWidth(
            getMaximumPaintValue('line-width', this, lineBucket),
            getMaximumPaintValue('line-gap-width', this, lineBucket));
        const offset = getMaximumPaintValue('line-offset', this, lineBucket);
        return width / 2 + Math.abs(offset) + translateDistance(this.paint.get('line-translate'));
    }

    // $FlowFixMe[method-unbinding]
    queryIntersectsFeature(queryGeometry                        ,
                           feature                    ,
                           featureState              ,
                           geometry                     ,
                           zoom        ,
                           transform           )          {
        if (queryGeometry.queryGeometry.isAboveHorizon) return false;

        const translatedPolygon = translate(queryGeometry.tilespaceGeometry,
            this.paint.get('line-translate'),
            this.paint.get('line-translate-anchor'),
            transform.angle, queryGeometry.pixelToTileUnitsFactor);
        const halfWidth = queryGeometry.pixelToTileUnitsFactor / 2 * getLineWidth(
            this.paint.get('line-width').evaluate(feature, featureState),
            this.paint.get('line-gap-width').evaluate(feature, featureState));
        const lineOffset = this.paint.get('line-offset').evaluate(feature, featureState);
        if (lineOffset) {
            geometry = offsetLine(geometry, lineOffset * queryGeometry.pixelToTileUnitsFactor);
        }

        return polygonIntersectsBufferedMultiLine(translatedPolygon, geometry, halfWidth);
    }

    isTileClipped()          {
        return true;
    }
}

function getLineWidth(lineWidth        , lineGapWidth        ) {
    if (lineGapWidth > 0) {
        return lineGapWidth + 2 * lineWidth;
    } else {
        return lineWidth;
    }
}

function offsetLine(rings                     , offset        ) {
    const newRings = [];
    const zero = new Point$2(0, 0);
    for (let k = 0; k < rings.length; k++) {
        const ring = rings[k];
        const newRing = [];
        for (let i = 0; i < ring.length; i++) {
            const a = ring[i - 1];
            const b = ring[i];
            const c = ring[i + 1];
            const aToB = i === 0 ? zero : b.sub(a)._unit()._perp();
            const bToC = i === ring.length - 1 ? zero : c.sub(b)._unit()._perp();
            const extrude = aToB._add(bToC)._unit();

            const cosHalfAngle = extrude.x * bToC.x + extrude.y * bToC.y;
            extrude._mult(1 / cosHalfAngle);

            newRing.push(extrude._mult(offset)._add(b));
        }
        newRings.push(newRing);
    }
    return newRings;
}

//      

                                                                  

const symbolLayoutAttributes                    = createLayout([
    {name: 'a_pos_offset',   components: 4, type: 'Int16'},
    {name: 'a_tex_size',     components: 4, type: 'Uint16'},
    {name: 'a_pixeloffset',  components: 4, type: 'Int16'}
], 4);

const symbolGlobeExtAttributes                    = createLayout([
    {name: 'a_globe_anchor', components: 3, type: 'Int16'},
    {name: 'a_globe_normal', components: 3, type: 'Float32'},
], 4);

const dynamicLayoutAttributes                    = createLayout([
    {name: 'a_projected_pos', components: 4, type: 'Float32'}
], 4);

const placementOpacityAttributes                    = createLayout([
    {name: 'a_fade_opacity', components: 1, type: 'Uint32'}
], 4);

const collisionVertexAttributes                    = createLayout([
    {name: 'a_placed', components: 2, type: 'Uint8'},
    {name: 'a_shift', components: 2, type: 'Float32'},
]);

const collisionVertexAttributesExt                    = createLayout([
    {name: 'a_size_scale', components: 1, type: 'Float32'},
    {name: 'a_padding', components: 2, type: 'Float32'},
]);

const collisionBox                    = createLayout([
    // the box is centered around the anchor point
    {type: 'Int16', name: 'projectedAnchorX'},
    {type: 'Int16', name: 'projectedAnchorY'},
    {type: 'Int16', name: 'projectedAnchorZ'},

    {type: 'Int16', name: 'tileAnchorX'},
    {type: 'Int16', name: 'tileAnchorY'},

    // distances to the edges from the anchor
    {type: 'Float32', name: 'x1'},
    {type: 'Float32', name: 'y1'},
    {type: 'Float32', name: 'x2'},
    {type: 'Float32', name: 'y2'},

    {type: 'Int16', name: 'padding'},

    // the index of the feature in the original vectortile
    {type: 'Uint32', name: 'featureIndex'},
    // the source layer the feature appears in
    {type: 'Uint16', name: 'sourceLayerIndex'},
    // the bucket the feature appears in
    {type: 'Uint16', name: 'bucketIndex'},
]);

const collisionBoxLayout                    = createLayout([ // used to render collision boxes for debugging purposes
    {name: 'a_pos',             components: 3, type: 'Int16'},
    {name: 'a_anchor_pos',      components: 2, type: 'Int16'},
    {name: 'a_extrude',         components: 2, type: 'Int16'}
], 4);

const collisionCircleLayout                    = createLayout([ // used to render collision circles for debugging purposes
    {name: 'a_pos_2f',     components: 2, type: 'Float32'},
    {name: 'a_radius',     components: 1, type: 'Float32'},
    {name: 'a_flags',      components: 2, type: 'Int16'}
], 4);

const quadTriangle                    = createLayout([
    {name: 'triangle', components: 3, type: 'Uint16'},
]);

const placement                    = createLayout([
    {type: 'Int16', name: 'projectedAnchorX'},
    {type: 'Int16', name: 'projectedAnchorY'},
    {type: 'Int16', name: 'projectedAnchorZ'},
    {type: 'Float32', name: 'tileAnchorX'},
    {type: 'Float32', name: 'tileAnchorY'},
    {type: 'Uint16', name: 'glyphStartIndex'},
    {type: 'Uint16', name: 'numGlyphs'},
    {type: 'Uint32', name: 'vertexStartIndex'},
    {type: 'Uint32', name: 'lineStartIndex'},
    {type: 'Uint32', name: 'lineLength'},
    {type: 'Uint16', name: 'segment'},
    {type: 'Uint16', name: 'lowerSize'},
    {type: 'Uint16', name: 'upperSize'},
    {type: 'Float32', name: 'lineOffsetX'},
    {type: 'Float32', name: 'lineOffsetY'},
    {type: 'Uint8', name: 'writingMode'},
    {type: 'Uint8', name: 'placedOrientation'},
    {type: 'Uint8', name: 'hidden'},
    {type: 'Uint32', name: 'crossTileID'},
    {type: 'Int16', name: 'associatedIconIndex'},
    {type: 'Uint8', name: 'flipState'}
]);

const symbolInstance                    = createLayout([
    {type: 'Int16', name: 'projectedAnchorX'},
    {type: 'Int16', name: 'projectedAnchorY'},
    {type: 'Int16', name: 'projectedAnchorZ'},
    {type: 'Float32', name: 'tileAnchorX'},
    {type: 'Float32', name: 'tileAnchorY'},
    {type: 'Int16', name: 'rightJustifiedTextSymbolIndex'},
    {type: 'Int16', name: 'centerJustifiedTextSymbolIndex'},
    {type: 'Int16', name: 'leftJustifiedTextSymbolIndex'},
    {type: 'Int16', name: 'verticalPlacedTextSymbolIndex'},
    {type: 'Int16', name: 'placedIconSymbolIndex'},
    {type: 'Int16', name: 'verticalPlacedIconSymbolIndex'},
    {type: 'Uint16', name: 'key'},
    {type: 'Uint16', name: 'textBoxStartIndex'},
    {type: 'Uint16', name: 'textBoxEndIndex'},
    {type: 'Uint16', name: 'verticalTextBoxStartIndex'},
    {type: 'Uint16', name: 'verticalTextBoxEndIndex'},
    {type: 'Uint16', name: 'iconBoxStartIndex'},
    {type: 'Uint16', name: 'iconBoxEndIndex'},
    {type: 'Uint16', name: 'verticalIconBoxStartIndex'},
    {type: 'Uint16', name: 'verticalIconBoxEndIndex'},
    {type: 'Uint16', name: 'featureIndex'},
    {type: 'Uint16', name: 'numHorizontalGlyphVertices'},
    {type: 'Uint16', name: 'numVerticalGlyphVertices'},
    {type: 'Uint16', name: 'numIconVertices'},
    {type: 'Uint16', name: 'numVerticalIconVertices'},
    {type: 'Uint16', name: 'useRuntimeCollisionCircles'},
    {type: 'Uint32', name: 'crossTileID'},
    {type: 'Float32', components: 2, name: 'textOffset'},
    {type: 'Float32', name: 'collisionCircleDiameter'},
]);

const glyphOffset                    = createLayout([
    {type: 'Float32', name: 'offsetX'}
]);

const lineVertex                    = createLayout([
    {type: 'Int16', name: 'x'},
    {type: 'Int16', name: 'y'}
]);

//      
// ONE_EM constant used to go between "em" units used in style spec and "points" used internally for layout

var ONE_EM = 24;

//      


                                                                                          
                                                                                           

const SIZE_PACK_FACTOR = 128;

                        
                     
                      
     
                  
     
                   
                    
                    
                    
                    
                                         
     
                      
                    
                    
                                         
  

                                 
                  
                  
   

// For {text,icon}-size, get the bucket-level data that will be needed by
// the painter to set symbol-size-related uniforms
function getSizeData(tileZoom        , value                                                               )           {
    const {expression} = value;

    if (expression.kind === 'constant') {
        // $FlowFixMe[method-unbinding]
        const layoutSize = expression.evaluate(new EvaluationParameters(tileZoom + 1));
        return {kind: 'constant', layoutSize};

    } else if (expression.kind === 'source') {
        return {kind: 'source'};

    } else {
        const {zoomStops, interpolationType} = expression;

        // calculate covering zoom stops for zoom-dependent values
        let lower = 0;
        while (lower < zoomStops.length && zoomStops[lower] <= tileZoom) lower++;
        lower = Math.max(0, lower - 1);
        let upper = lower;
        while (upper < zoomStops.length && zoomStops[upper] < tileZoom + 1) upper++;
        upper = Math.min(zoomStops.length - 1, upper);

        const minZoom = zoomStops[lower];
        const maxZoom = zoomStops[upper];

        // We'd like to be able to use CameraExpression or CompositeExpression in these
        // return types rather than ExpressionSpecification, but the former are not
        // transferrable across Web Worker boundaries.
        if (expression.kind === 'composite') {
            return {kind: 'composite', minZoom, maxZoom, interpolationType};
        }

        // for camera functions, also save off the function values
        // evaluated at the covering zoom levels
        // $FlowFixMe[method-unbinding]
        const minSize = expression.evaluate(new EvaluationParameters(minZoom));
        // $FlowFixMe[method-unbinding]
        const maxSize = expression.evaluate(new EvaluationParameters(maxZoom));

        return {kind: 'camera', minZoom, maxZoom, minSize, maxSize, interpolationType};
    }
}

function evaluateSizeForFeature(sizeData          ,
                                {uSize, uSizeT}                  ,
                                {lowerSize, upperSize}                                                    )         {
    if (sizeData.kind === 'source') {
        return lowerSize / SIZE_PACK_FACTOR;
    } else if (sizeData.kind === 'composite') {
        return number(lowerSize / SIZE_PACK_FACTOR, upperSize / SIZE_PACK_FACTOR, uSizeT);
    }
    return uSize;
}

function evaluateSizeForZoom(sizeData          , zoom        )                   {
    let uSizeT = 0;
    let uSize = 0;

    if (sizeData.kind === 'constant') {
        uSize = sizeData.layoutSize;

    } else if (sizeData.kind !== 'source') {
        const {interpolationType, minZoom, maxZoom} = sizeData;

        // Even though we could get the exact value of the camera function
        // at z = tr.zoom, we intentionally do not: instead, we interpolate
        // between the camera function values at a pair of zoom stops covering
        // [tileZoom, tileZoom + 1] in order to be consistent with this
        // restriction on composite functions
        const t = !interpolationType ? 0 : clamp(
            Interpolate.interpolationFactor(interpolationType, zoom, minZoom, maxZoom), 0, 1);

        if (sizeData.kind === 'camera') {
            uSize = number(sizeData.minSize, sizeData.maxSize, t);
        } else {
            uSizeT = t;
        }
    }

    return {uSizeT, uSize};
}

var symbolSize = /*#__PURE__*/Object.freeze({
__proto__: null,
SIZE_PACK_FACTOR: SIZE_PACK_FACTOR,
evaluateSizeForFeature: evaluateSizeForFeature,
evaluateSizeForZoom: evaluateSizeForZoom,
getSizeData: getSizeData
});

//      


function transformText(text        , layer                  , feature         ) {
    const transform = layer.layout.get('text-transform').evaluate(feature, {});
    if (transform === 'uppercase') {
        text = text.toLocaleUpperCase();
    } else if (transform === 'lowercase') {
        text = text.toLocaleLowerCase();
    }

    if (plugin.applyArabicShaping) {
        text = plugin.applyArabicShaping(text);
    }

    return text;
}

function transformText$1(text           , layer                  , feature         )            {
    text.sections.forEach(section => {
        section.text = transformText(section.text, layer, feature);
    });
    return text;
}

//      

                                                
                                                                   

function mergeLines (features                      )                       {
    const leftIndex                        = {};
    const rightIndex                        = {};
    const mergedFeatures = [];
    let mergedIndex = 0;

    function add(k        ) {
        mergedFeatures.push(features[k]);
        mergedIndex++;
    }

    function mergeFromRight(leftKey        , rightKey        , geom                     ) {
        const i = rightIndex[leftKey];
        delete rightIndex[leftKey];
        rightIndex[rightKey] = i;

        mergedFeatures[i].geometry[0].pop();
        mergedFeatures[i].geometry[0] = mergedFeatures[i].geometry[0].concat(geom[0]);
        return i;
    }

    function mergeFromLeft(leftKey        , rightKey        , geom                     ) {
        const i = leftIndex[rightKey];
        delete leftIndex[rightKey];
        leftIndex[leftKey] = i;

        mergedFeatures[i].geometry[0].shift();
        mergedFeatures[i].geometry[0] = geom[0].concat(mergedFeatures[i].geometry[0]);
        return i;
    }

    function getKey(text        , geom                     , onRight          ) {
        const point = onRight ? geom[0][geom[0].length - 1] : geom[0][0];
        return `${text}:${point.x}:${point.y}`;
    }

    for (let k = 0; k < features.length; k++) {
        const feature = features[k];
        const geom = feature.geometry;
        const text = feature.text ? feature.text.toString() : null;

        if (!text) {
            add(k);
            continue;
        }

        const leftKey = getKey(text, geom),
            rightKey = getKey(text, geom, true);

        if ((leftKey in rightIndex) && (rightKey in leftIndex) && (rightIndex[leftKey] !== leftIndex[rightKey])) {
            // found lines with the same text adjacent to both ends of the current line, merge all three
            const j = mergeFromLeft(leftKey, rightKey, geom);
            const i = mergeFromRight(leftKey, rightKey, mergedFeatures[j].geometry);

            delete leftIndex[leftKey];
            delete rightIndex[rightKey];

            rightIndex[getKey(text, mergedFeatures[i].geometry, true)] = i;
            mergedFeatures[j].geometry = (null     );

        } else if (leftKey in rightIndex) {
            // found mergeable line adjacent to the start of the current line, merge
            mergeFromRight(leftKey, rightKey, geom);

        } else if (rightKey in leftIndex) {
            // found mergeable line adjacent to the end of the current line, merge
            mergeFromLeft(leftKey, rightKey, geom);

        } else {
            // no adjacent lines, add as a new item
            add(k);
            leftIndex[leftKey] = mergedIndex - 1;
            rightIndex[rightKey] = mergedIndex - 1;
        }
    }

    return mergedFeatures.filter((f) => f.geometry);
}

//      


const verticalizedCharacterMap = {
    '!': '︕',
    '#': '#',
    '$': '$',
    '%': '%',
    '&': '&',
    '(': '︵',
    ')': '︶',
    '*': '*',
    '+': '+',
    ',': '︐',
    '-': '︲',
    '.': '・',
    '/': '/',
    ':': '︓',
    ';': '︔',
    '<': '︿',
    '=': '=',
    '>': '﹀',
    '?': '︖',
    '@': '@',
    '[': '﹇',
    '\\': '\',
    ']': '﹈',
    '^': '^',
    '_': '︳',
    '`': '`',
    '{': '︷',
    '|': '―',
    '}': '︸',
    '~': '~',
    '¢': '¢',
    '£': '£',
    '¥': '¥',
    '¦': '¦',
    '¬': '¬',
    '¯': ' ̄',
    '–': '︲',
    '—': '︱',
    '‘': '﹃',
    '’': '﹄',
    '“': '﹁',
    '”': '﹂',
    '…': '︙',
    '‧': '・',
    '₩': '₩',
    '、': '︑',
    '。': '︒',
    '〈': '︿',
    '〉': '﹀',
    '《': '︽',
    '》': '︾',
    '「': '﹁',
    '」': '﹂',
    '『': '﹃',
    '』': '﹄',
    '【': '︻',
    '】': '︼',
    '〔': '︹',
    '〕': '︺',
    '〖': '︗',
    '〗': '︘',
    '!': '︕',
    '(': '︵',
    ')': '︶',
    ',': '︐',
    '-': '︲',
    '.': '・',
    ':': '︓',
    ';': '︔',
    '<': '︿',
    '>': '﹀',
    '?': '︖',
    '[': '﹇',
    ']': '﹈',
    '_': '︳',
    '{': '︷',
    '|': '―',
    '}': '︸',
    '⦅': '︵',
    '⦆': '︶',
    '。': '︒',
    '「': '﹁',
    '」': '﹂',
    '←': '↑',
    '→': '↓'
};

function verticalizePunctuation(input        , skipContextChecking         )         {
    let output = '';

    for (let i = 0; i < input.length; i++) {
        const nextCharCode = input.charCodeAt(i + 1) || null;
        const prevCharCode = input.charCodeAt(i - 1) || null;

        const canReplacePunctuation = skipContextChecking || (
            (!nextCharCode || !charHasRotatedVerticalOrientation(nextCharCode) || verticalizedCharacterMap[input[i + 1]]) &&
            (!prevCharCode || !charHasRotatedVerticalOrientation(prevCharCode) || verticalizedCharacterMap[input[i - 1]])
        );

        if (canReplacePunctuation && verticalizedCharacterMap[input[i]]) {
            output += verticalizedCharacterMap[input[i]];
        } else {
            output += input[i];
        }
    }

    return output;
}

function isVerticalClosePunctuation(chr        )          {
    return chr === '︶' || chr === '﹈' || chr === '︸' || chr === '﹄' || chr === '﹂' || chr === '︾' ||
           chr === '︼' || chr === '︺' || chr === '︘' || chr === '﹀' || chr === '︐' || chr === '︓' ||
           chr === '︔' || chr === '`' || chr === ' ̄' || chr === '︑' || chr === '︒';
}

function isVerticalOpenPunctuation(chr        )          {
    return chr === '︵' || chr === '﹇' || chr === '︷' || chr === '﹃' || chr === '﹁' || chr === '︽' ||
           chr === '︻' || chr === '︹' || chr === '︗' || chr === '︿';
}

var ieee754$1 = {};

/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */

var read = ieee754$1.read = function (buffer, offset, isLE, mLen, nBytes) {
  var e, m;
  var eLen = (nBytes * 8) - mLen - 1;
  var eMax = (1 << eLen) - 1;
  var eBias = eMax >> 1;
  var nBits = -7;
  var i = isLE ? (nBytes - 1) : 0;
  var d = isLE ? -1 : 1;
  var s = buffer[offset + i];

  i += d;

  e = s & ((1 << (-nBits)) - 1);
  s >>= (-nBits);
  nBits += eLen;
  for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}

  m = e & ((1 << (-nBits)) - 1);
  e >>= (-nBits);
  nBits += mLen;
  for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}

  if (e === 0) {
    e = 1 - eBias;
  } else if (e === eMax) {
    return m ? NaN : ((s ? -1 : 1) * Infinity)
  } else {
    m = m + Math.pow(2, mLen);
    e = e - eBias;
  }
  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
};

var write = ieee754$1.write = function (buffer, value, offset, isLE, mLen, nBytes) {
  var e, m, c;
  var eLen = (nBytes * 8) - mLen - 1;
  var eMax = (1 << eLen) - 1;
  var eBias = eMax >> 1;
  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0);
  var i = isLE ? 0 : (nBytes - 1);
  var d = isLE ? 1 : -1;
  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;

  value = Math.abs(value);

  if (isNaN(value) || value === Infinity) {
    m = isNaN(value) ? 1 : 0;
    e = eMax;
  } else {
    e = Math.floor(Math.log(value) / Math.LN2);
    if (value * (c = Math.pow(2, -e)) < 1) {
      e--;
      c *= 2;
    }
    if (e + eBias >= 1) {
      value += rt / c;
    } else {
      value += rt * Math.pow(2, 1 - eBias);
    }
    if (value * c >= 2) {
      e++;
      c /= 2;
    }

    if (e + eBias >= eMax) {
      m = 0;
      e = eMax;
    } else if (e + eBias >= 1) {
      m = ((value * c) - 1) * Math.pow(2, mLen);
      e = e + eBias;
    } else {
      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
      e = 0;
    }
  }

  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}

  e = (e << mLen) | m;
  eLen += mLen;
  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}

  buffer[offset + i - d] |= s * 128;
};

'use strict';

var pbf = Pbf;

var ieee754 = ieee754$1;

function Pbf(buf) {
    this.buf = ArrayBuffer.isView && ArrayBuffer.isView(buf) ? buf : new Uint8Array(buf || 0);
    this.pos = 0;
    this.type = 0;
    this.length = this.buf.length;
}

Pbf.Varint  = 0; // varint: int32, int64, uint32, uint64, sint32, sint64, bool, enum
Pbf.Fixed64 = 1; // 64-bit: double, fixed64, sfixed64
Pbf.Bytes   = 2; // length-delimited: string, bytes, embedded messages, packed repeated fields
Pbf.Fixed32 = 5; // 32-bit: float, fixed32, sfixed32

var SHIFT_LEFT_32 = (1 << 16) * (1 << 16),
    SHIFT_RIGHT_32 = 1 / SHIFT_LEFT_32;

// Threshold chosen based on both benchmarking and knowledge about browser string
// data structures (which currently switch structure types at 12 bytes or more)
var TEXT_DECODER_MIN_LENGTH = 12;
var utf8TextDecoder = typeof TextDecoder === 'undefined' ? null : new TextDecoder('utf8');

Pbf.prototype = {

    destroy: function() {
        this.buf = null;
    },

    // === READING =================================================================

    readFields: function(readField, result, end) {
        end = end || this.length;

        while (this.pos < end) {
            var val = this.readVarint(),
                tag = val >> 3,
                startPos = this.pos;

            this.type = val & 0x7;
            readField(tag, result, this);

            if (this.pos === startPos) this.skip(val);
        }
        return result;
    },

    readMessage: function(readField, result) {
        return this.readFields(readField, result, this.readVarint() + this.pos);
    },

    readFixed32: function() {
        var val = readUInt32(this.buf, this.pos);
        this.pos += 4;
        return val;
    },

    readSFixed32: function() {
        var val = readInt32(this.buf, this.pos);
        this.pos += 4;
        return val;
    },

    // 64-bit int handling is based on github.com/dpw/node-buffer-more-ints (MIT-licensed)

    readFixed64: function() {
        var val = readUInt32(this.buf, this.pos) + readUInt32(this.buf, this.pos + 4) * SHIFT_LEFT_32;
        this.pos += 8;
        return val;
    },

    readSFixed64: function() {
        var val = readUInt32(this.buf, this.pos) + readInt32(this.buf, this.pos + 4) * SHIFT_LEFT_32;
        this.pos += 8;
        return val;
    },

    readFloat: function() {
        var val = ieee754.read(this.buf, this.pos, true, 23, 4);
        this.pos += 4;
        return val;
    },

    readDouble: function() {
        var val = ieee754.read(this.buf, this.pos, true, 52, 8);
        this.pos += 8;
        return val;
    },

    readVarint: function(isSigned) {
        var buf = this.buf,
            val, b;

        b = buf[this.pos++]; val  =  b & 0x7f;        if (b < 0x80) return val;
        b = buf[this.pos++]; val |= (b & 0x7f) << 7;  if (b < 0x80) return val;
        b = buf[this.pos++]; val |= (b & 0x7f) << 14; if (b < 0x80) return val;
        b = buf[this.pos++]; val |= (b & 0x7f) << 21; if (b < 0x80) return val;
        b = buf[this.pos];   val |= (b & 0x0f) << 28;

        return readVarintRemainder(val, isSigned, this);
    },

    readVarint64: function() { // for compatibility with v2.0.1
        return this.readVarint(true);
    },

    readSVarint: function() {
        var num = this.readVarint();
        return num % 2 === 1 ? (num + 1) / -2 : num / 2; // zigzag encoding
    },

    readBoolean: function() {
        return Boolean(this.readVarint());
    },

    readString: function() {
        var end = this.readVarint() + this.pos;
        var pos = this.pos;
        this.pos = end;

        if (end - pos >= TEXT_DECODER_MIN_LENGTH && utf8TextDecoder) {
            // longer strings are fast with the built-in browser TextDecoder API
            return readUtf8TextDecoder(this.buf, pos, end);
        }
        // short strings are fast with our custom implementation
        return readUtf8(this.buf, pos, end);
    },

    readBytes: function() {
        var end = this.readVarint() + this.pos,
            buffer = this.buf.subarray(this.pos, end);
        this.pos = end;
        return buffer;
    },

    // verbose for performance reasons; doesn't affect gzipped size

    readPackedVarint: function(arr, isSigned) {
        if (this.type !== Pbf.Bytes) return arr.push(this.readVarint(isSigned));
        var end = readPackedEnd(this);
        arr = arr || [];
        while (this.pos < end) arr.push(this.readVarint(isSigned));
        return arr;
    },
    readPackedSVarint: function(arr) {
        if (this.type !== Pbf.Bytes) return arr.push(this.readSVarint());
        var end = readPackedEnd(this);
        arr = arr || [];
        while (this.pos < end) arr.push(this.readSVarint());
        return arr;
    },
    readPackedBoolean: function(arr) {
        if (this.type !== Pbf.Bytes) return arr.push(this.readBoolean());
        var end = readPackedEnd(this);
        arr = arr || [];
        while (this.pos < end) arr.push(this.readBoolean());
        return arr;
    },
    readPackedFloat: function(arr) {
        if (this.type !== Pbf.Bytes) return arr.push(this.readFloat());
        var end = readPackedEnd(this);
        arr = arr || [];
        while (this.pos < end) arr.push(this.readFloat());
        return arr;
    },
    readPackedDouble: function(arr) {
        if (this.type !== Pbf.Bytes) return arr.push(this.readDouble());
        var end = readPackedEnd(this);
        arr = arr || [];
        while (this.pos < end) arr.push(this.readDouble());
        return arr;
    },
    readPackedFixed32: function(arr) {
        if (this.type !== Pbf.Bytes) return arr.push(this.readFixed32());
        var end = readPackedEnd(this);
        arr = arr || [];
        while (this.pos < end) arr.push(this.readFixed32());
        return arr;
    },
    readPackedSFixed32: function(arr) {
        if (this.type !== Pbf.Bytes) return arr.push(this.readSFixed32());
        var end = readPackedEnd(this);
        arr = arr || [];
        while (this.pos < end) arr.push(this.readSFixed32());
        return arr;
    },
    readPackedFixed64: function(arr) {
        if (this.type !== Pbf.Bytes) return arr.push(this.readFixed64());
        var end = readPackedEnd(this);
        arr = arr || [];
        while (this.pos < end) arr.push(this.readFixed64());
        return arr;
    },
    readPackedSFixed64: function(arr) {
        if (this.type !== Pbf.Bytes) return arr.push(this.readSFixed64());
        var end = readPackedEnd(this);
        arr = arr || [];
        while (this.pos < end) arr.push(this.readSFixed64());
        return arr;
    },

    skip: function(val) {
        var type = val & 0x7;
        if (type === Pbf.Varint) while (this.buf[this.pos++] > 0x7f) {}
        else if (type === Pbf.Bytes) this.pos = this.readVarint() + this.pos;
        else if (type === Pbf.Fixed32) this.pos += 4;
        else if (type === Pbf.Fixed64) this.pos += 8;
        else throw new Error('Unimplemented type: ' + type);
    },

    // === WRITING =================================================================

    writeTag: function(tag, type) {
        this.writeVarint((tag << 3) | type);
    },

    realloc: function(min) {
        var length = this.length || 16;

        while (length < this.pos + min) length *= 2;

        if (length !== this.length) {
            var buf = new Uint8Array(length);
            buf.set(this.buf);
            this.buf = buf;
            this.length = length;
        }
    },

    finish: function() {
        this.length = this.pos;
        this.pos = 0;
        return this.buf.subarray(0, this.length);
    },

    writeFixed32: function(val) {
        this.realloc(4);
        writeInt32(this.buf, val, this.pos);
        this.pos += 4;
    },

    writeSFixed32: function(val) {
        this.realloc(4);
        writeInt32(this.buf, val, this.pos);
        this.pos += 4;
    },

    writeFixed64: function(val) {
        this.realloc(8);
        writeInt32(this.buf, val & -1, this.pos);
        writeInt32(this.buf, Math.floor(val * SHIFT_RIGHT_32), this.pos + 4);
        this.pos += 8;
    },

    writeSFixed64: function(val) {
        this.realloc(8);
        writeInt32(this.buf, val & -1, this.pos);
        writeInt32(this.buf, Math.floor(val * SHIFT_RIGHT_32), this.pos + 4);
        this.pos += 8;
    },

    writeVarint: function(val) {
        val = +val || 0;

        if (val > 0xfffffff || val < 0) {
            writeBigVarint(val, this);
            return;
        }

        this.realloc(4);

        this.buf[this.pos++] =           val & 0x7f  | (val > 0x7f ? 0x80 : 0); if (val <= 0x7f) return;
        this.buf[this.pos++] = ((val >>>= 7) & 0x7f) | (val > 0x7f ? 0x80 : 0); if (val <= 0x7f) return;
        this.buf[this.pos++] = ((val >>>= 7) & 0x7f) | (val > 0x7f ? 0x80 : 0); if (val <= 0x7f) return;
        this.buf[this.pos++] =   (val >>> 7) & 0x7f;
    },

    writeSVarint: function(val) {
        this.writeVarint(val < 0 ? -val * 2 - 1 : val * 2);
    },

    writeBoolean: function(val) {
        this.writeVarint(Boolean(val));
    },

    writeString: function(str) {
        str = String(str);
        this.realloc(str.length * 4);

        this.pos++; // reserve 1 byte for short string length

        var startPos = this.pos;
        // write the string directly to the buffer and see how much was written
        this.pos = writeUtf8(this.buf, str, this.pos);
        var len = this.pos - startPos;

        if (len >= 0x80) makeRoomForExtraLength(startPos, len, this);

        // finally, write the message length in the reserved place and restore the position
        this.pos = startPos - 1;
        this.writeVarint(len);
        this.pos += len;
    },

    writeFloat: function(val) {
        this.realloc(4);
        ieee754.write(this.buf, val, this.pos, true, 23, 4);
        this.pos += 4;
    },

    writeDouble: function(val) {
        this.realloc(8);
        ieee754.write(this.buf, val, this.pos, true, 52, 8);
        this.pos += 8;
    },

    writeBytes: function(buffer) {
        var len = buffer.length;
        this.writeVarint(len);
        this.realloc(len);
        for (var i = 0; i < len; i++) this.buf[this.pos++] = buffer[i];
    },

    writeRawMessage: function(fn, obj) {
        this.pos++; // reserve 1 byte for short message length

        // write the message directly to the buffer and see how much was written
        var startPos = this.pos;
        fn(obj, this);
        var len = this.pos - startPos;

        if (len >= 0x80) makeRoomForExtraLength(startPos, len, this);

        // finally, write the message length in the reserved place and restore the position
        this.pos = startPos - 1;
        this.writeVarint(len);
        this.pos += len;
    },

    writeMessage: function(tag, fn, obj) {
        this.writeTag(tag, Pbf.Bytes);
        this.writeRawMessage(fn, obj);
    },

    writePackedVarint:   function(tag, arr) { if (arr.length) this.writeMessage(tag, writePackedVarint, arr);   },
    writePackedSVarint:  function(tag, arr) { if (arr.length) this.writeMessage(tag, writePackedSVarint, arr);  },
    writePackedBoolean:  function(tag, arr) { if (arr.length) this.writeMessage(tag, writePackedBoolean, arr);  },
    writePackedFloat:    function(tag, arr) { if (arr.length) this.writeMessage(tag, writePackedFloat, arr);    },
    writePackedDouble:   function(tag, arr) { if (arr.length) this.writeMessage(tag, writePackedDouble, arr);   },
    writePackedFixed32:  function(tag, arr) { if (arr.length) this.writeMessage(tag, writePackedFixed32, arr);  },
    writePackedSFixed32: function(tag, arr) { if (arr.length) this.writeMessage(tag, writePackedSFixed32, arr); },
    writePackedFixed64:  function(tag, arr) { if (arr.length) this.writeMessage(tag, writePackedFixed64, arr);  },
    writePackedSFixed64: function(tag, arr) { if (arr.length) this.writeMessage(tag, writePackedSFixed64, arr); },

    writeBytesField: function(tag, buffer) {
        this.writeTag(tag, Pbf.Bytes);
        this.writeBytes(buffer);
    },
    writeFixed32Field: function(tag, val) {
        this.writeTag(tag, Pbf.Fixed32);
        this.writeFixed32(val);
    },
    writeSFixed32Field: function(tag, val) {
        this.writeTag(tag, Pbf.Fixed32);
        this.writeSFixed32(val);
    },
    writeFixed64Field: function(tag, val) {
        this.writeTag(tag, Pbf.Fixed64);
        this.writeFixed64(val);
    },
    writeSFixed64Field: function(tag, val) {
        this.writeTag(tag, Pbf.Fixed64);
        this.writeSFixed64(val);
    },
    writeVarintField: function(tag, val) {
        this.writeTag(tag, Pbf.Varint);
        this.writeVarint(val);
    },
    writeSVarintField: function(tag, val) {
        this.writeTag(tag, Pbf.Varint);
        this.writeSVarint(val);
    },
    writeStringField: function(tag, str) {
        this.writeTag(tag, Pbf.Bytes);
        this.writeString(str);
    },
    writeFloatField: function(tag, val) {
        this.writeTag(tag, Pbf.Fixed32);
        this.writeFloat(val);
    },
    writeDoubleField: function(tag, val) {
        this.writeTag(tag, Pbf.Fixed64);
        this.writeDouble(val);
    },
    writeBooleanField: function(tag, val) {
        this.writeVarintField(tag, Boolean(val));
    }
};

function readVarintRemainder(l, s, p) {
    var buf = p.buf,
        h, b;

    b = buf[p.pos++]; h  = (b & 0x70) >> 4;  if (b < 0x80) return toNum(l, h, s);
    b = buf[p.pos++]; h |= (b & 0x7f) << 3;  if (b < 0x80) return toNum(l, h, s);
    b = buf[p.pos++]; h |= (b & 0x7f) << 10; if (b < 0x80) return toNum(l, h, s);
    b = buf[p.pos++]; h |= (b & 0x7f) << 17; if (b < 0x80) return toNum(l, h, s);
    b = buf[p.pos++]; h |= (b & 0x7f) << 24; if (b < 0x80) return toNum(l, h, s);
    b = buf[p.pos++]; h |= (b & 0x01) << 31; if (b < 0x80) return toNum(l, h, s);

    throw new Error('Expected varint not more than 10 bytes');
}

function readPackedEnd(pbf) {
    return pbf.type === Pbf.Bytes ?
        pbf.readVarint() + pbf.pos : pbf.pos + 1;
}

function toNum(low, high, isSigned) {
    if (isSigned) {
        return high * 0x100000000 + (low >>> 0);
    }

    return ((high >>> 0) * 0x100000000) + (low >>> 0);
}

function writeBigVarint(val, pbf) {
    var low, high;

    if (val >= 0) {
        low  = (val % 0x100000000) | 0;
        high = (val / 0x100000000) | 0;
    } else {
        low  = ~(-val % 0x100000000);
        high = ~(-val / 0x100000000);

        if (low ^ 0xffffffff) {
            low = (low + 1) | 0;
        } else {
            low = 0;
            high = (high + 1) | 0;
        }
    }

    if (val >= 0x10000000000000000 || val < -0x10000000000000000) {
        throw new Error('Given varint doesn\'t fit into 10 bytes');
    }

    pbf.realloc(10);

    writeBigVarintLow(low, high, pbf);
    writeBigVarintHigh(high, pbf);
}

function writeBigVarintLow(low, high, pbf) {
    pbf.buf[pbf.pos++] = low & 0x7f | 0x80; low >>>= 7;
    pbf.buf[pbf.pos++] = low & 0x7f | 0x80; low >>>= 7;
    pbf.buf[pbf.pos++] = low & 0x7f | 0x80; low >>>= 7;
    pbf.buf[pbf.pos++] = low & 0x7f | 0x80; low >>>= 7;
    pbf.buf[pbf.pos]   = low & 0x7f;
}

function writeBigVarintHigh(high, pbf) {
    var lsb = (high & 0x07) << 4;

    pbf.buf[pbf.pos++] |= lsb         | ((high >>>= 3) ? 0x80 : 0); if (!high) return;
    pbf.buf[pbf.pos++]  = high & 0x7f | ((high >>>= 7) ? 0x80 : 0); if (!high) return;
    pbf.buf[pbf.pos++]  = high & 0x7f | ((high >>>= 7) ? 0x80 : 0); if (!high) return;
    pbf.buf[pbf.pos++]  = high & 0x7f | ((high >>>= 7) ? 0x80 : 0); if (!high) return;
    pbf.buf[pbf.pos++]  = high & 0x7f | ((high >>>= 7) ? 0x80 : 0); if (!high) return;
    pbf.buf[pbf.pos++]  = high & 0x7f;
}

function makeRoomForExtraLength(startPos, len, pbf) {
    var extraLen =
        len <= 0x3fff ? 1 :
        len <= 0x1fffff ? 2 :
        len <= 0xfffffff ? 3 : Math.floor(Math.log(len) / (Math.LN2 * 7));

    // if 1 byte isn't enough for encoding message length, shift the data to the right
    pbf.realloc(extraLen);
    for (var i = pbf.pos - 1; i >= startPos; i--) pbf.buf[i + extraLen] = pbf.buf[i];
}

function writePackedVarint(arr, pbf)   { for (var i = 0; i < arr.length; i++) pbf.writeVarint(arr[i]);   }
function writePackedSVarint(arr, pbf)  { for (var i = 0; i < arr.length; i++) pbf.writeSVarint(arr[i]);  }
function writePackedFloat(arr, pbf)    { for (var i = 0; i < arr.length; i++) pbf.writeFloat(arr[i]);    }
function writePackedDouble(arr, pbf)   { for (var i = 0; i < arr.length; i++) pbf.writeDouble(arr[i]);   }
function writePackedBoolean(arr, pbf)  { for (var i = 0; i < arr.length; i++) pbf.writeBoolean(arr[i]);  }
function writePackedFixed32(arr, pbf)  { for (var i = 0; i < arr.length; i++) pbf.writeFixed32(arr[i]);  }
function writePackedSFixed32(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeSFixed32(arr[i]); }
function writePackedFixed64(arr, pbf)  { for (var i = 0; i < arr.length; i++) pbf.writeFixed64(arr[i]);  }
function writePackedSFixed64(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeSFixed64(arr[i]); }

// Buffer code below from https://github.com/feross/buffer, MIT-licensed

function readUInt32(buf, pos) {
    return ((buf[pos]) |
        (buf[pos + 1] << 8) |
        (buf[pos + 2] << 16)) +
        (buf[pos + 3] * 0x1000000);
}

function writeInt32(buf, val, pos) {
    buf[pos] = val;
    buf[pos + 1] = (val >>> 8);
    buf[pos + 2] = (val >>> 16);
    buf[pos + 3] = (val >>> 24);
}

function readInt32(buf, pos) {
    return ((buf[pos]) |
        (buf[pos + 1] << 8) |
        (buf[pos + 2] << 16)) +
        (buf[pos + 3] << 24);
}

function readUtf8(buf, pos, end) {
    var str = '';
    var i = pos;

    while (i < end) {
        var b0 = buf[i];
        var c = null; // codepoint
        var bytesPerSequence =
            b0 > 0xEF ? 4 :
            b0 > 0xDF ? 3 :
            b0 > 0xBF ? 2 : 1;

        if (i + bytesPerSequence > end) break;

        var b1, b2, b3;

        if (bytesPerSequence === 1) {
            if (b0 < 0x80) {
                c = b0;
            }
        } else if (bytesPerSequence === 2) {
            b1 = buf[i + 1];
            if ((b1 & 0xC0) === 0x80) {
                c = (b0 & 0x1F) << 0x6 | (b1 & 0x3F);
                if (c <= 0x7F) {
                    c = null;
                }
            }
        } else if (bytesPerSequence === 3) {
            b1 = buf[i + 1];
            b2 = buf[i + 2];
            if ((b1 & 0xC0) === 0x80 && (b2 & 0xC0) === 0x80) {
                c = (b0 & 0xF) << 0xC | (b1 & 0x3F) << 0x6 | (b2 & 0x3F);
                if (c <= 0x7FF || (c >= 0xD800 && c <= 0xDFFF)) {
                    c = null;
                }
            }
        } else if (bytesPerSequence === 4) {
            b1 = buf[i + 1];
            b2 = buf[i + 2];
            b3 = buf[i + 3];
            if ((b1 & 0xC0) === 0x80 && (b2 & 0xC0) === 0x80 && (b3 & 0xC0) === 0x80) {
                c = (b0 & 0xF) << 0x12 | (b1 & 0x3F) << 0xC | (b2 & 0x3F) << 0x6 | (b3 & 0x3F);
                if (c <= 0xFFFF || c >= 0x110000) {
                    c = null;
                }
            }
        }

        if (c === null) {
            c = 0xFFFD;
            bytesPerSequence = 1;

        } else if (c > 0xFFFF) {
            c -= 0x10000;
            str += String.fromCharCode(c >>> 10 & 0x3FF | 0xD800);
            c = 0xDC00 | c & 0x3FF;
        }

        str += String.fromCharCode(c);
        i += bytesPerSequence;
    }

    return str;
}

function readUtf8TextDecoder(buf, pos, end) {
    return utf8TextDecoder.decode(buf.subarray(pos, end));
}

function writeUtf8(buf, str, pos) {
    for (var i = 0, c, lead; i < str.length; i++) {
        c = str.charCodeAt(i); // code point

        if (c > 0xD7FF && c < 0xE000) {
            if (lead) {
                if (c < 0xDC00) {
                    buf[pos++] = 0xEF;
                    buf[pos++] = 0xBF;
                    buf[pos++] = 0xBD;
                    lead = c;
                    continue;
                } else {
                    c = lead - 0xD800 << 10 | c - 0xDC00 | 0x10000;
                    lead = null;
                }
            } else {
                if (c > 0xDBFF || (i + 1 === str.length)) {
                    buf[pos++] = 0xEF;
                    buf[pos++] = 0xBF;
                    buf[pos++] = 0xBD;
                } else {
                    lead = c;
                }
                continue;
            }
        } else if (lead) {
            buf[pos++] = 0xEF;
            buf[pos++] = 0xBF;
            buf[pos++] = 0xBD;
            lead = null;
        }

        if (c < 0x80) {
            buf[pos++] = c;
        } else {
            if (c < 0x800) {
                buf[pos++] = c >> 0x6 | 0xC0;
            } else {
                if (c < 0x10000) {
                    buf[pos++] = c >> 0xC | 0xE0;
                } else {
                    buf[pos++] = c >> 0x12 | 0xF0;
                    buf[pos++] = c >> 0xC & 0x3F | 0x80;
                }
                buf[pos++] = c >> 0x6 & 0x3F | 0x80;
            }
            buf[pos++] = c & 0x3F | 0x80;
        }
    }
    return pos;
}

var Protobuf = /*@__PURE__*/getDefaultExportFromCjs(pbf);

//      

const border$1 = 3;

                                                 

function readFontstacks(tag        , glyphData                                                                    , pbf          ) {
    glyphData.glyphs = [];
    if (tag === 1) {
        pbf.readMessage(readFontstack, glyphData);
    }
}

function readFontstack(tag        ,  glyphData                                                                    , pbf          ) {
    if (tag === 3) {
        const {id, bitmap, width, height, left, top, advance} = pbf.readMessage(readGlyph, {});
        glyphData.glyphs.push({
            id,
            bitmap: new AlphaImage({
                width: width + 2 * border$1,
                height: height + 2 * border$1
            }, bitmap),
            metrics: {width, height, left, top, advance}
        });
    } else if (tag === 4) {
        glyphData.ascender = pbf.readSVarint();
    } else if (tag === 5) {
        glyphData.descender = pbf.readSVarint();
    }
}

function readGlyph(tag        , glyph        , pbf          ) {
    if (tag === 1) glyph.id = pbf.readVarint();
    else if (tag === 2) glyph.bitmap = pbf.readBytes();
    else if (tag === 3) glyph.width = pbf.readVarint();
    else if (tag === 4) glyph.height = pbf.readVarint();
    else if (tag === 5) glyph.left = pbf.readSVarint();
    else if (tag === 6) glyph.top = pbf.readSVarint();
    else if (tag === 7) glyph.advance = pbf.readVarint();
}

function parseGlyphPBF (data                          )                                                                     {
    return new Protobuf(data).readFields(readFontstacks, {});
}

const GLYPH_PBF_BORDER = border$1;

function potpack(boxes) {

    // calculate total box area and maximum box width
    let area = 0;
    let maxWidth = 0;

    for (const box of boxes) {
        area += box.w * box.h;
        maxWidth = Math.max(maxWidth, box.w);
    }

    // sort the boxes for insertion by height, descending
    boxes.sort((a, b) => b.h - a.h);

    // aim for a squarish resulting container,
    // slightly adjusted for sub-100% space utilization
    const startWidth = Math.max(Math.ceil(Math.sqrt(area / 0.95)), maxWidth);

    // start with a single empty space, unbounded at the bottom
    const spaces = [{x: 0, y: 0, w: startWidth, h: Infinity}];

    let width = 0;
    let height = 0;

    for (const box of boxes) {
        // look through spaces backwards so that we check smaller spaces first
        for (let i = spaces.length - 1; i >= 0; i--) {
            const space = spaces[i];

            // look for empty spaces that can accommodate the current box
            if (box.w > space.w || box.h > space.h) continue;

            // found the space; add the box to its top-left corner
            // |-------|-------|
            // |  box  |       |
            // |_______|       |
            // |         space |
            // |_______________|
            box.x = space.x;
            box.y = space.y;

            height = Math.max(height, box.y + box.h);
            width = Math.max(width, box.x + box.w);

            if (box.w === space.w && box.h === space.h) {
                // space matches the box exactly; remove it
                const last = spaces.pop();
                if (i < spaces.length) spaces[i] = last;

            } else if (box.h === space.h) {
                // space matches the box height; update it accordingly
                // |-------|---------------|
                // |  box  | updated space |
                // |_______|_______________|
                space.x += box.w;
                space.w -= box.w;

            } else if (box.w === space.w) {
                // space matches the box width; update it accordingly
                // |---------------|
                // |      box      |
                // |_______________|
                // | updated space |
                // |_______________|
                space.y += box.h;
                space.h -= box.h;

            } else {
                // otherwise the box splits the space into two spaces
                // |-------|-----------|
                // |  box  | new space |
                // |_______|___________|
                // | updated space     |
                // |___________________|
                spaces.push({
                    x: space.x + box.w,
                    y: space.y,
                    w: space.w - box.w,
                    h: box.h
                });
                space.y += box.h;
                space.h -= box.h;
            }
            break;
        }
    }

    return {
        w: width, // container width
        h: height, // container height
        fill: (area / (width * height)) || 0 // space utilization
    };
}

//      


                                                        
                                                   
                                        
                                                     

const IMAGE_PADDING         = 1;

             
              
              
              
             
  

class ImagePosition                           {
                     
                       
                    
                                       
                                       
                                               

    constructor(paddedRect      , {pixelRatio, version, stretchX, stretchY, content}            ) {
        this.paddedRect = paddedRect;
        this.pixelRatio = pixelRatio;
        this.stretchX = stretchX;
        this.stretchY = stretchY;
        this.content = content;
        this.version = version;
    }

    get tl()                   {
        return [
            this.paddedRect.x + IMAGE_PADDING,
            this.paddedRect.y + IMAGE_PADDING
        ];
    }

    get br()                   {
        return [
            this.paddedRect.x + this.paddedRect.w - IMAGE_PADDING,
            this.paddedRect.y + this.paddedRect.h - IMAGE_PADDING
        ];
    }

    get displaySize()                   {
        return [
            (this.paddedRect.w - IMAGE_PADDING * 2) / this.pixelRatio,
            (this.paddedRect.h - IMAGE_PADDING * 2) / this.pixelRatio
        ];
    }
}

class ImageAtlas {
                     
                                                
                                                   
                                       
                       

    constructor(icons                           , patterns                           ) {
        const iconPositions = {}, patternPositions = {};
        this.haveRenderCallbacks = [];

        const bins = [];

        this.addImages(icons, iconPositions, bins);
        this.addImages(patterns, patternPositions, bins);

        const {w, h} = potpack(bins);
        const image = new RGBAImage({width: w || 1, height: h || 1});

        for (const id in icons) {
            const src = icons[id];
            const bin = iconPositions[id].paddedRect;
            RGBAImage.copy(src.data, image, {x: 0, y: 0}, {x: bin.x + IMAGE_PADDING, y: bin.y + IMAGE_PADDING}, src.data);
        }

        for (const id in patterns) {
            const src = patterns[id];
            const bin = patternPositions[id].paddedRect;
            const x = bin.x + IMAGE_PADDING,
                y = bin.y + IMAGE_PADDING,
                w = src.data.width,
                h = src.data.height;

            RGBAImage.copy(src.data, image, {x: 0, y: 0}, {x, y}, src.data);
            // Add 1 pixel wrapped padding on each side of the image.
            RGBAImage.copy(src.data, image, {x: 0, y: h - 1}, {x, y: y - 1}, {width: w, height: 1}); // T
            RGBAImage.copy(src.data, image, {x: 0, y:     0}, {x, y: y + h}, {width: w, height: 1}); // B
            RGBAImage.copy(src.data, image, {x: w - 1, y: 0}, {x: x - 1, y}, {width: 1, height: h}); // L
            RGBAImage.copy(src.data, image, {x: 0,     y: 0}, {x: x + w, y}, {width: 1, height: h}); // R
        }

        this.image = image;
        this.iconPositions = iconPositions;
        this.patternPositions = patternPositions;
    }

    addImages(images                           , positions                              , bins             ) {
        for (const id in images) {
            const src = images[id];
            const bin = {
                x: 0,
                y: 0,
                w: src.data.width + 2 * IMAGE_PADDING,
                h: src.data.height + 2 * IMAGE_PADDING,
            };
            bins.push(bin);
            positions[id] = new ImagePosition(bin, src);

            if (src.hasRenderCallback) {
                this.haveRenderCallbacks.push(id);
            }
        }
    }

    patchUpdatedImages(imageManager              , texture         ) {
        this.haveRenderCallbacks = this.haveRenderCallbacks.filter(id => imageManager.hasImage(id));
        imageManager.dispatchRenderCallbacks(this.haveRenderCallbacks);
        for (const name in imageManager.updatedImages) {
            this.patchUpdatedImage(this.iconPositions[name], imageManager.getImage(name), texture);
            this.patchUpdatedImage(this.patternPositions[name], imageManager.getImage(name), texture);
        }
    }

    patchUpdatedImage(position                , image             , texture         ) {
        if (!position || !image) return;

        if (position.version === image.version) return;

        position.version = image.version;
        const [x, y] = position.tl;
        texture.update(image.data, undefined, {x, y});
    }

}

register(ImagePosition, 'ImagePosition');
register(ImageAtlas, 'ImageAtlas');

//      


const WritingMode = {
    horizontal: 1,
    vertical: 2,
    horizontalOnly: 3
};

const SHAPING_DEFAULT_OFFSET = -17;

// The position of a glyph relative to the text's anchor point.
                               
                  
                             
              
              
                      
                  
                      
                         
                          
                           
                        
  

                              
                                             
                      
  

// A collection of positioned glyphs and some metadata
                       
                                           
                
                   
                 
                  
                       
                 
                         
                            
                        
  

                         
                            
                         
   

function isEmpty(positionedLines                       ) {
    for (const line of positionedLines) {
        if (line.positionedGlyphs.length !== 0) {
            return false;
        }
    }
    return true;
}

                                                                                                                                      
                                                      

// Max number of images in label is 6401 U+E000–U+F8FF that covers
// Basic Multilingual Plane Unicode Private Use Area (PUA).
const PUAbegin = 0xE000;
const PUAend = 0xF8FF;

class SectionOptions {
    // Text options
                  
                      
    // Image options
                             

    constructor() {
        this.scale = 1.0;
        this.fontStack = "";
        this.imageName = null;
    }

    static forText(scale         , fontStack        )                 {
        const textOptions = new SectionOptions();
        textOptions.scale = scale || 1;
        textOptions.fontStack = fontStack;
        return textOptions;
    }

    static forImage(imageName        )                 {
        const imageOptions = new SectionOptions();
        imageOptions.imageName = imageName;
        return imageOptions;
    }

}

class TaggedString {
                 
                                // maps each character in 'text' to its corresponding entry in 'sections'
                                   
                                  

    constructor() {
        this.text = "";
        this.sectionIndex = [];
        this.sections = [];
        this.imageSectionID = null;
    }

    static fromFeature(text           , defaultFontStack        )               {
        const result = new TaggedString();
        for (let i = 0; i < text.sections.length; i++) {
            const section = text.sections[i];
            if (!section.image) {
                result.addTextSection(section, defaultFontStack);
            } else {
                result.addImageSection(section);
            }
        }
        return result;
    }

    length()         {
        return this.text.length;
    }

    getSection(index        )                 {
        return this.sections[this.sectionIndex[index]];
    }

    getSections()                        {
        return this.sections;
    }

    getSectionIndex(index        )         {
        return this.sectionIndex[index];
    }

    getCharCode(index        )         {
        return this.text.charCodeAt(index);
    }

    verticalizePunctuation(skipContextChecking         ) {
        this.text = verticalizePunctuation(this.text, skipContextChecking);
    }

    trim() {
        let beginningWhitespace = 0;
        for (let i = 0;
            i < this.text.length && whitespace[this.text.charCodeAt(i)];
            i++) {
            beginningWhitespace++;
        }
        let trailingWhitespace = this.text.length;
        for (let i = this.text.length - 1;
            i >= 0 && i >= beginningWhitespace && whitespace[this.text.charCodeAt(i)];
            i--) {
            trailingWhitespace--;
        }
        this.text = this.text.substring(beginningWhitespace, trailingWhitespace);
        this.sectionIndex = this.sectionIndex.slice(beginningWhitespace, trailingWhitespace);
    }

    substring(start        , end        )               {
        const substring = new TaggedString();
        substring.text = this.text.substring(start, end);
        substring.sectionIndex = this.sectionIndex.slice(start, end);
        substring.sections = this.sections;
        return substring;
    }

    toString()         {
        return this.text;
    }

    getMaxScale()         {
        return this.sectionIndex.reduce((max, index) => Math.max(max, this.sections[index].scale), 0);
    }

    addTextSection(section                  , defaultFontStack        ) {
        this.text += section.text;
        this.sections.push(SectionOptions.forText(section.scale, section.fontStack || defaultFontStack));
        const index = this.sections.length - 1;
        for (let i = 0; i < section.text.length; ++i) {
            this.sectionIndex.push(index);
        }
    }

    addImageSection(section                  ) {
        const imageName = section.image ? section.image.name : '';
        if (imageName.length === 0) {
            warnOnce(`Can't add FormattedSection with an empty image.`);
            return;
        }

        const nextImageSectionCharCode = this.getNextImageSectionCharCode();
        if (!nextImageSectionCharCode) {
            warnOnce(`Reached maximum number of images ${PUAend - PUAbegin + 2}`);
            return;
        }

        this.text += String.fromCharCode(nextImageSectionCharCode);
        this.sections.push(SectionOptions.forImage(imageName));
        this.sectionIndex.push(this.sections.length - 1);
    }

    getNextImageSectionCharCode()                {
        if (!this.imageSectionID) {
            this.imageSectionID = PUAbegin;
            return this.imageSectionID;
        }

        if (this.imageSectionID >= PUAend) return null;
        return ++this.imageSectionID;
    }
}

function breakLines(input              , lineBreakPoints               )                      {
    const lines = [];
    const text = input.text;
    let start = 0;
    for (const lineBreak of lineBreakPoints) {
        lines.push(input.substring(start, lineBreak));
        start = lineBreak;
    }

    if (start < text.length) {
        lines.push(input.substring(start, text.length));
    }
    return lines;
}

function shapeText(text           ,
                   glyphMap                                                                                            ,
                   glyphPositions                ,
                   imagePositions                              ,
                   defaultFontStack        ,
                   maxWidth        ,
                   lineHeight        ,
                   textAnchor              ,
                   textJustify             ,
                   spacing        ,
                   translate                  ,
                   writingMode       ,
                   allowVerticalPlacement         ,
                   layoutTextSize        ,
                   layoutTextSizeThisZoom        )                  {
    const logicalInput = TaggedString.fromFeature(text, defaultFontStack);

    if (writingMode === WritingMode.vertical) {
        logicalInput.verticalizePunctuation(allowVerticalPlacement);
    }

    let lines                      = [];

    const lineBreaks = determineLineBreaks(logicalInput, spacing, maxWidth, glyphMap, imagePositions, layoutTextSize);

    const {processBidirectionalText, processStyledBidirectionalText} = plugin;
    if (processBidirectionalText && logicalInput.sections.length === 1) {
        // Bidi doesn't have to be style-aware
        const untaggedLines = processBidirectionalText(logicalInput.toString(), lineBreaks);
        for (const line of untaggedLines) {
            const taggedLine = new TaggedString();
            taggedLine.text = line;
            taggedLine.sections = logicalInput.sections;
            for (let i = 0; i < line.length; i++) {
                taggedLine.sectionIndex.push(0);
            }
            lines.push(taggedLine);
        }
    } else if (processStyledBidirectionalText) {
        // Need version of mapbox-gl-rtl-text with style support for combining RTL text with formatting
        const processedLines = processStyledBidirectionalText(logicalInput.text, logicalInput.sectionIndex, lineBreaks);
        for (const line of processedLines) {
            const taggedLine = new TaggedString();
            taggedLine.text = line[0];
            taggedLine.sectionIndex = line[1];
            taggedLine.sections = logicalInput.sections;
            lines.push(taggedLine);
        }
    } else {
        lines = breakLines(logicalInput, lineBreaks);
    }

    const positionedLines = [];
    const shaping = {
        positionedLines,
        text: logicalInput.toString(),
        top: translate[1],
        bottom: translate[1],
        left: translate[0],
        right: translate[0],
        writingMode,
        iconsInText: false,
        verticalizable: false,
        hasBaseline: false
    };

    shapeLines(shaping, glyphMap, glyphPositions, imagePositions, lines, lineHeight, textAnchor, textJustify, writingMode, spacing, allowVerticalPlacement, layoutTextSizeThisZoom);
    if (isEmpty(positionedLines)) return false;

    return shaping;
}

// using computed properties due to https://github.com/facebook/flow/issues/380
/* eslint no-useless-computed-key: 0 */

const whitespace                         = {
    [0x09]: true, // tab
    [0x0a]: true, // newline
    [0x0b]: true, // vertical tab
    [0x0c]: true, // form feed
    [0x0d]: true, // carriage return
    [0x20]: true, // space
};

const breakable                         = {
    [0x0a]:   true, // newline
    [0x20]:   true, // space
    [0x26]:   true, // ampersand
    [0x28]:   true, // left parenthesis
    [0x29]:   true, // right parenthesis
    [0x2b]:   true, // plus sign
    [0x2d]:   true, // hyphen-minus
    [0x2f]:   true, // solidus
    [0xad]:   true, // soft hyphen
    [0xb7]:   true, // middle dot
    [0x200b]: true, // zero-width space
    [0x2010]: true, // hyphen
    [0x2013]: true, // en dash
    [0x2027]: true  // interpunct
    // Many other characters may be reasonable breakpoints
    // Consider "neutral orientation" characters at scriptDetection.charHasNeutralVerticalOrientation
    // See https://github.com/mapbox/mapbox-gl-js/issues/3658
};

function getGlyphAdvance(codePoint        ,
                         section                ,
                         glyphMap                                                                                            ,
                         imagePositions                              ,
                         spacing        ,
                         layoutTextSize        )         {
    if (!section.imageName) {
        const positions = glyphMap[section.fontStack];
        const glyph = positions && positions.glyphs[codePoint];
        if (!glyph) return 0;
        return glyph.metrics.advance * section.scale + spacing;
    } else {
        const imagePosition = imagePositions[section.imageName];
        if (!imagePosition) return 0;
        return imagePosition.displaySize[0] * section.scale * ONE_EM / layoutTextSize + spacing;
    }
}

function determineAverageLineWidth(logicalInput              ,
                                   spacing        ,
                                   maxWidth        ,
                                   glyphMap                                                                                            ,
                                   imagePositions                              ,
                                   layoutTextSize        ) {
    let totalWidth = 0;

    for (let index = 0; index < logicalInput.length(); index++) {
        const section = logicalInput.getSection(index);
        totalWidth += getGlyphAdvance(logicalInput.getCharCode(index), section, glyphMap, imagePositions, spacing, layoutTextSize);
    }

    const lineCount = Math.max(1, Math.ceil(totalWidth / maxWidth));
    return totalWidth / lineCount;
}

function calculateBadness(lineWidth        ,
                          targetWidth        ,
                          penalty        ,
                          isLastBreak         ) {
    const raggedness = Math.pow(lineWidth - targetWidth, 2);
    if (isLastBreak) {
        // Favor finals lines shorter than average over longer than average
        if (lineWidth < targetWidth) {
            return raggedness / 2;
        } else {
            return raggedness * 2;
        }
    }

    return raggedness + Math.abs(penalty) * penalty;
}

function calculatePenalty(codePoint        , nextCodePoint        , penalizableIdeographicBreak         ) {
    let penalty = 0;
    // Force break on newline
    if (codePoint === 0x0a) {
        penalty -= 10000;
    }
    // Penalize breaks between characters that allow ideographic breaking because
    // they are less preferable than breaks at spaces (or zero width spaces).
    if (penalizableIdeographicBreak) {
        penalty += 150;
    }

    // Penalize open parenthesis at end of line
    if (codePoint === 0x28 || codePoint === 0xff08) {
        penalty += 50;
    }

    // Penalize close parenthesis at beginning of line
    if (nextCodePoint === 0x29 || nextCodePoint === 0xff09) {
        penalty += 50;
    }
    return penalty;
}

              
                  
              
                       
                   
  

function evaluateBreak(breakIndex        ,
                       breakX        ,
                       targetWidth        ,
                       potentialBreaks              ,
                       penalty        ,
                       isLastBreak         )        {
    // We could skip evaluating breaks where the line length (breakX - priorBreak.x) > maxWidth
    //  ...but in fact we allow lines longer than maxWidth (if there's no break points)
    //  ...and when targetWidth and maxWidth are close, strictly enforcing maxWidth can give
    //     more lopsided results.

    let bestPriorBreak         = null;
    let bestBreakBadness = calculateBadness(breakX, targetWidth, penalty, isLastBreak);

    for (const potentialBreak of potentialBreaks) {
        const lineWidth = breakX - potentialBreak.x;
        const breakBadness =
            calculateBadness(lineWidth, targetWidth, penalty, isLastBreak) + potentialBreak.badness;
        if (breakBadness <= bestBreakBadness) {
            bestPriorBreak = potentialBreak;
            bestBreakBadness = breakBadness;
        }
    }

    return {
        index: breakIndex,
        x: breakX,
        priorBreak: bestPriorBreak,
        badness: bestBreakBadness
    };
}

function leastBadBreaks(lastLineBreak        )                {
    if (!lastLineBreak) {
        return [];
    }
    return leastBadBreaks(lastLineBreak.priorBreak).concat(lastLineBreak.index);
}

function determineLineBreaks(logicalInput              ,
                             spacing        ,
                             maxWidth        ,
                             glyphMap                                                                                            ,
                             imagePositions                              ,
                             layoutTextSize        )                {
    if (!logicalInput)
        return [];

    const potentialLineBreaks = [];
    const targetWidth = determineAverageLineWidth(logicalInput, spacing, maxWidth, glyphMap, imagePositions, layoutTextSize);

    const hasServerSuggestedBreakpoints = logicalInput.text.indexOf("\u200b") >= 0;

    let currentX = 0;

    for (let i = 0; i < logicalInput.length(); i++) {
        const section = logicalInput.getSection(i);
        const codePoint = logicalInput.getCharCode(i);
        if (!whitespace[codePoint]) currentX += getGlyphAdvance(codePoint, section, glyphMap, imagePositions, spacing, layoutTextSize);

        // Ideographic characters, spaces, and word-breaking punctuation that often appear without
        // surrounding spaces.
        if ((i < logicalInput.length() - 1)) {
            const ideographicBreak = charAllowsIdeographicBreaking(codePoint);
            if (breakable[codePoint] || ideographicBreak || section.imageName) {

                potentialLineBreaks.push(
                    evaluateBreak(
                        i + 1,
                        currentX,
                        targetWidth,
                        potentialLineBreaks,
                        calculatePenalty(codePoint, logicalInput.getCharCode(i + 1), ideographicBreak && hasServerSuggestedBreakpoints),
                        false));
            }
        }
    }

    return leastBadBreaks(
        evaluateBreak(
            logicalInput.length(),
            currentX,
            targetWidth,
            potentialLineBreaks,
            0,
            true));
}

function getAnchorAlignment(anchor              )                  {
    let horizontalAlign = 0.5, verticalAlign = 0.5;

    switch (anchor) {
    case 'right':
    case 'top-right':
    case 'bottom-right':
        horizontalAlign = 1;
        break;
    case 'left':
    case 'top-left':
    case 'bottom-left':
        horizontalAlign = 0;
        break;
    }

    switch (anchor) {
    case 'bottom':
    case 'bottom-right':
    case 'bottom-left':
        verticalAlign = 1;
        break;
    case 'top':
    case 'top-right':
    case 'top-left':
        verticalAlign = 0;
        break;
    }

    return {horizontalAlign, verticalAlign};
}

function shapeLines(shaping         ,
                    glyphMap                                                                                            ,
                    glyphPositions                ,
                    imagePositions                              ,
                    lines                     ,
                    lineHeight        ,
                    textAnchor              ,
                    textJustify             ,
                    writingMode       ,
                    spacing        ,
                    allowVerticalPlacement         ,
                    layoutTextSizeThisZoom        ) {

    let x = 0;
    let y = 0;

    let maxLineLength = 0;
    let maxLineHeight = 0;

    const justify =
        textJustify === 'right' ? 1 :
        textJustify === 'left' ? 0 : 0.5;

    let hasBaseline = false;
    for (const line of lines) {
        const sections = line.getSections();
        for (const section of sections) {
            if (section.imageName) continue;

            const glyphData = glyphMap[section.fontStack];
            if (!glyphData) continue;

            hasBaseline = glyphData.ascender !== undefined && glyphData.descender !== undefined;
            if (!hasBaseline) break;
        }
        if (!hasBaseline) break;
    }

    let lineIndex = 0;
    for (const line of lines) {
        line.trim();

        const lineMaxScale = line.getMaxScale();
        const maxLineOffset = (lineMaxScale - 1) * ONE_EM;
        const positionedLine = {positionedGlyphs: [], lineOffset: 0};
        shaping.positionedLines[lineIndex] = positionedLine;
        const positionedGlyphs = positionedLine.positionedGlyphs;
        let lineOffset = 0.0;

        if (!line.length()) {
            y += lineHeight; // Still need a line feed after empty line
            ++lineIndex;
            continue;
        }

        let biggestHeight = 0;
        let baselineOffset = 0;
        for (let i = 0; i < line.length(); i++) {
            const section = line.getSection(i);
            const sectionIndex = line.getSectionIndex(i);
            const codePoint = line.getCharCode(i);

            let sectionScale = section.scale;
            let metrics = null;
            let rect = null;
            let imageName = null;
            let verticalAdvance = ONE_EM;
            let glyphOffset = 0;

            const vertical = !(writingMode === WritingMode.horizontal ||
                // Don't verticalize glyphs that have no upright orientation if vertical placement is disabled.
                (!allowVerticalPlacement && !charHasUprightVerticalOrientation(codePoint)) ||
                // If vertical placement is enabled, don't verticalize glyphs that
                // are from complex text layout script, or whitespaces.
                (allowVerticalPlacement && (whitespace[codePoint] || charInComplexShapingScript(codePoint))));

            if (!section.imageName) {
                // Find glyph position in the glyph atlas, if bitmap is null,
                // glyphPosition will not exit in the glyphPosition map
                const glyphPositionData = glyphPositions[section.fontStack];
                if (!glyphPositionData) continue;
                if (glyphPositionData[codePoint]) {
                    rect = glyphPositionData[codePoint];
                }
                const glyphData = glyphMap[section.fontStack];
                if (!glyphData) continue;
                const glyph = glyphData.glyphs[codePoint];
                if (!glyph) continue;

                metrics = glyph.metrics;
                verticalAdvance = codePoint !== 0x200b ? ONE_EM : 0;

                // In order to make different fonts aligned, they must share a general baseline that aligns with every
                // font's real baseline. Glyph's offset is counted from the top left corner, where the ascender line
                // starts.
                // First of all, each glyph's baseline lies on the center line of the shaping line. Since ascender
                // is above the baseline, the glyphOffset is the negative shift. Then, in order to make glyphs fit in
                // the shaping box, for each line, we shift the glyph with biggest height(with scale) to make its center
                // lie on the center line of the line, which will lead to a baseline shift. Then adjust the whole line
                // with the baseline offset we calculated from the shift.
                if (hasBaseline) {
                    const ascender = glyphData.ascender !== undefined ? Math.abs(glyphData.ascender) : 0;
                    const descender = glyphData.descender !== undefined ? Math.abs(glyphData.descender) : 0;
                    const value = (ascender + descender) * sectionScale;
                    if (biggestHeight < value) {
                        biggestHeight = value;
                        baselineOffset = (ascender - descender) / 2 * sectionScale;
                    }
                    glyphOffset = -ascender * sectionScale;
                } else {
                    // If font's baseline is not applicable, fall back to use a default baseline offset, see
                    // Shaping::yOffset. Since we're laying out at 24 points, we need also calculate how much it will
                    // move when we scale up or down.
                    glyphOffset = SHAPING_DEFAULT_OFFSET + (lineMaxScale - sectionScale) * ONE_EM;
                }
            } else {
                const imagePosition = imagePositions[section.imageName];
                if (!imagePosition) continue;
                imageName = section.imageName;
                shaping.iconsInText = shaping.iconsInText || true;
                rect = imagePosition.paddedRect;
                const size = imagePosition.displaySize;
                // If needed, allow to set scale factor for an image using
                // alias "image-scale" that could be alias for "font-scale"
                // when FormattedSection is an image section.
                sectionScale = sectionScale * ONE_EM / layoutTextSizeThisZoom;

                metrics = {width: size[0],
                    height: size[1],
                    left: IMAGE_PADDING,
                    top: -GLYPH_PBF_BORDER,
                    advance: vertical ? size[1] : size[0],
                    localGlyph: false};

                if (!hasBaseline) {
                    glyphOffset = SHAPING_DEFAULT_OFFSET + lineMaxScale * ONE_EM - size[1] * sectionScale;
                } else {
                    // Based on node-fontnik: 'top = heightAboveBaseline - Ascender'(it is not valid for locally
                    // generated glyph). Since the top is a constant: glyph's borderSize. So if we set image glyph with
                    // 'ascender = height', it means we pull down the glyph under baseline with a distance of glyph's borderSize.
                    const imageAscender = metrics.height;
                    glyphOffset = -imageAscender * sectionScale;

                }
                verticalAdvance = metrics.advance;

                // Difference between height of an image and one EM at max line scale.
                // Pushes current line down if an image size is over 1 EM at max line scale.
                const offset = (vertical ? size[0] : size[1]) * sectionScale - ONE_EM * lineMaxScale;
                if (offset > 0 && offset > lineOffset) {
                    lineOffset = offset;
                }
            }

            if (!vertical) {
                positionedGlyphs.push({glyph: codePoint, imageName, x, y: y + glyphOffset, vertical, scale: sectionScale, localGlyph: metrics.localGlyph, fontStack: section.fontStack, sectionIndex, metrics, rect});
                x += metrics.advance * sectionScale + spacing;
            } else {
                shaping.verticalizable = true;
                positionedGlyphs.push({glyph: codePoint, imageName, x, y: y + glyphOffset, vertical, scale: sectionScale, localGlyph: metrics.localGlyph, fontStack: section.fontStack, sectionIndex, metrics, rect});
                x += verticalAdvance * sectionScale + spacing;
            }
        }

        // Only justify if we placed at least one glyph
        if (positionedGlyphs.length !== 0) {
            const lineLength = x - spacing;
            maxLineLength = Math.max(lineLength, maxLineLength);
            // Justify the line so that its top is aligned with the current height of y, and its horizontal coordinates
            // are justified according to the TextJustifyType
            if (hasBaseline) {
                justifyLine(positionedGlyphs, justify, lineOffset, baselineOffset, lineHeight * lineMaxScale / 2);
            } else {
                // Scaled line height offset is counted in glyphOffset, so here just use an unscaled line height
                justifyLine(positionedGlyphs, justify, lineOffset, 0, lineHeight / 2);
            }
        }

        x = 0;
        const currentLineHeight = lineHeight * lineMaxScale + lineOffset;
        positionedLine.lineOffset = Math.max(lineOffset, maxLineOffset);
        y += currentLineHeight;
        maxLineHeight = Math.max(currentLineHeight, maxLineHeight);
        ++lineIndex;
    }

    const height = y;
    const {horizontalAlign, verticalAlign} = getAnchorAlignment(textAnchor);
    align(shaping.positionedLines, justify, horizontalAlign, verticalAlign, maxLineLength, height);
    // Calculate the bounding box
    shaping.top += -verticalAlign * height;
    shaping.bottom = shaping.top + height;
    shaping.left += -horizontalAlign * maxLineLength;
    shaping.right = shaping.left + maxLineLength;
    shaping.hasBaseline = hasBaseline;
}

// justify right = 1, left = 0, center = 0.5
function justifyLine(positionedGlyphs                        ,
                     justify             ,
                     lineOffset        ,
                     baselineOffset        ,
                     halfLineHeight        ) {
    if (!justify && !lineOffset && !baselineOffset && !halfLineHeight) {
        return;
    }
    const end = positionedGlyphs.length - 1;
    const lastGlyph = positionedGlyphs[end];
    const lastAdvance = lastGlyph.metrics.advance * lastGlyph.scale;
    const lineIndent = (lastGlyph.x + lastAdvance) * justify;

    for (let j = 0; j <= end; j++) {
        positionedGlyphs[j].x -= lineIndent;
        positionedGlyphs[j].y += lineOffset + baselineOffset + halfLineHeight;
    }
}

function align(positionedLines                       ,
               justify        ,
               horizontalAlign        ,
               verticalAlign        ,
               maxLineLength        ,
               blockHeight        ) {
    const shiftX = (justify - horizontalAlign) * maxLineLength;

    const shiftY = -blockHeight * verticalAlign;
    for (const line of positionedLines) {
        for (const positionedGlyph of line.positionedGlyphs) {
            positionedGlyph.x += shiftX;
            positionedGlyph.y += shiftY;
        }
    }
}

                              
                         
                
                   
                 
                  
                                                       
  

function shapeIcon(image               , iconOffset                  , iconAnchor              )                 {
    const {horizontalAlign, verticalAlign} = getAnchorAlignment(iconAnchor);
    const dx = iconOffset[0];
    const dy = iconOffset[1];
    const x1 = dx - image.displaySize[0] * horizontalAlign;
    const x2 = x1 + image.displaySize[0];
    const y1 = dy - image.displaySize[1] * verticalAlign;
    const y2 = y1 + image.displaySize[1];
    return {image, top: y1, bottom: y2, left: x1, right: x2};
}

function fitIconToText(shapedIcon                , shapedText         ,
                       textFit        ,
                       padding                                    ,
                       iconOffset                    , fontScale        )                 {
    assert$1(textFit !== 'none');
    assert$1(Array.isArray(padding) && padding.length === 4);
    assert$1(Array.isArray(iconOffset) && iconOffset.length === 2);

    const image = shapedIcon.image;

    let collisionPadding;
    if (image.content) {
        const content = image.content;
        const pixelRatio = image.pixelRatio || 1;
        collisionPadding = [
            content[0] / pixelRatio,
            content[1] / pixelRatio,
            image.displaySize[0] - content[2] / pixelRatio,
            image.displaySize[1] - content[3] / pixelRatio
        ];
    }

    // We don't respect the icon-anchor, because icon-text-fit is set. Instead,
    // the icon will be centered on the text, then stretched in the given
    // dimensions.

    const textLeft = shapedText.left * fontScale;
    const textRight = shapedText.right * fontScale;

    let top, right, bottom, left;
    if (textFit === 'width' || textFit === 'both') {
        // Stretched horizontally to the text width
        left = iconOffset[0] + textLeft - padding[3];
        right = iconOffset[0] + textRight + padding[1];
    } else {
        // Centered on the text
        left = iconOffset[0] + (textLeft + textRight - image.displaySize[0]) / 2;
        right = left + image.displaySize[0];
    }

    const textTop = shapedText.top * fontScale;
    const textBottom = shapedText.bottom * fontScale;
    if (textFit === 'height' || textFit === 'both') {
        // Stretched vertically to the text height
        top = iconOffset[1] + textTop - padding[0];
        bottom = iconOffset[1] + textBottom + padding[2];
    } else {
        // Centered on the text
        top = iconOffset[1] + (textTop + textBottom - image.displaySize[1]) / 2;
        bottom = top + image.displaySize[1];
    }

    return {image, top, right, bottom, left, collisionPadding};
}

//      


class Anchor extends Point$2 {
               
              
                           

    constructor(x        , y        , z        , angle        , segment         ) {
        super(x, y);
        this.angle = angle;
        this.z = z;
        if (segment !== undefined) {
            this.segment = segment;
        }
    }

    clone()         {
        return new Anchor(this.x, this.y, this.z, this.angle, this.segment);
    }
}

register(Anchor, 'Anchor');

//      


                                                
                                      

/**
 * Labels placed around really sharp angles aren't readable. Check if any
 * part of the potential label has a combined angle that is too big.
 *
 * @param line
 * @param anchor The point on the line around which the label is anchored.
 * @param labelLength The length of the label in geometry units.
 * @param windowSize The check fails if the combined angles within a part of the line that is `windowSize` long is too big.
 * @param maxAngle The maximum combined angle that any window along the label is allowed to have.
 *
 * @returns {boolean} whether the label should be placed
 * @private
 */
function checkMaxAngle(line              , anchor        , labelLength        , windowSize        , maxAngle        )          {

    // horizontal labels always pass
    if (anchor.segment === undefined) return true;

    let p        = anchor;
    let index = anchor.segment + 1;
    let anchorDistance = 0;

    // move backwards along the line to the first segment the label appears on
    while (anchorDistance > -labelLength / 2) {
        index--;

        // there isn't enough room for the label after the beginning of the line
        if (index < 0) return false;

        anchorDistance -= line[index].dist(p);
        p = line[index];
    }

    anchorDistance += line[index].dist(line[index + 1]);
    index++;

    // store recent corners and their total angle difference
    const recentCorners = [];
    let recentAngleDelta = 0;

    // move forwards by the length of the label and check angles along the way
    while (anchorDistance < labelLength / 2) {
        const prev = line[index - 1];
        const current = line[index];
        const next = line[index + 1];

        // there isn't enough room for the label before the end of the line
        if (!next) return false;

        let angleDelta = prev.angleTo(current) - current.angleTo(next);
        // restrict angle to -pi..pi range
        angleDelta = Math.abs(((angleDelta + 3 * Math.PI) % (Math.PI * 2)) - Math.PI);

        recentCorners.push({
            distance: anchorDistance,
            angleDelta
        });
        recentAngleDelta += angleDelta;

        // remove corners that are far enough away from the list of recent anchors
        while (anchorDistance - recentCorners[0].distance > windowSize) {
            recentAngleDelta -= recentCorners.shift().angleDelta;
        }

        // the sum of angles within the window area exceeds the maximum allowed value. check fails.
        if (recentAngleDelta > maxAngle) return false;

        index++;
        anchorDistance += current.dist(next);
    }

    // no part of the line had an angle greater than the maximum allowed. check passes.
    return true;
}

//      


function getLineLength(line              )         {
    let lineLength = 0;
    for (let k = 0; k < line.length - 1; k++) {
        lineLength += line[k].dist(line[k + 1]);
    }
    return lineLength;
}

function getAngleWindowSize(shapedText          ,
                            glyphSize        ,
                            boxScale        )         {
    return shapedText ?
        3 / 5 * glyphSize * boxScale :
        0;
}

function getShapedLabelLength(shapedText          , shapedIcon                 )         {
    return Math.max(
        shapedText ? shapedText.right - shapedText.left : 0,
        shapedIcon ? shapedIcon.right - shapedIcon.left : 0);
}

function getCenterAnchor(line              ,
                         maxAngle        ,
                         shapedText          ,
                         shapedIcon                 ,
                         glyphSize        ,
                         boxScale        )          {
    const angleWindowSize = getAngleWindowSize(shapedText, glyphSize, boxScale);
    const labelLength = getShapedLabelLength(shapedText, shapedIcon) * boxScale;

    let prevDistance = 0;
    const centerDistance = getLineLength(line) / 2;

    for (let i = 0; i < line.length - 1; i++) {

        const a = line[i],
            b = line[i + 1];

        const segmentDistance = a.dist(b);

        if (prevDistance + segmentDistance > centerDistance) {
            // The center is on this segment
            const t = (centerDistance - prevDistance) / segmentDistance,
                x = number(a.x, b.x, t),
                y = number(a.y, b.y, t);

            const anchor = new Anchor(x, y, 0, b.angleTo(a), i);
            if (!angleWindowSize || checkMaxAngle(line, anchor, labelLength, angleWindowSize, maxAngle)) {
                return anchor;
            } else {
                return;
            }
        }

        prevDistance += segmentDistance;
    }
}

function getAnchors(line              ,
                    spacing        ,
                    maxAngle        ,
                    shapedText          ,
                    shapedIcon                 ,
                    glyphSize        ,
                    boxScale        ,
                    overscaling        ,
                    tileExtent        )                {

    // Resample a line to get anchor points for labels and check that each
    // potential label passes text-max-angle check and has enough froom to fit
    // on the line.

    const angleWindowSize = getAngleWindowSize(shapedText, glyphSize, boxScale);
    const shapedLabelLength = getShapedLabelLength(shapedText, shapedIcon);
    const labelLength = shapedLabelLength * boxScale;

    // Is the line continued from outside the tile boundary?
    const isLineContinued = line[0].x === 0 || line[0].x === tileExtent || line[0].y === 0 || line[0].y === tileExtent;

    // Is the label long, relative to the spacing?
    // If so, adjust the spacing so there is always a minimum space of `spacing / 4` between label edges.
    if (spacing - labelLength < spacing / 4) {
        spacing = labelLength + spacing / 4;
    }

    // Offset the first anchor by:
    // Either half the label length plus a fixed extra offset if the line is not continued
    // Or half the spacing if the line is continued.

    // For non-continued lines, add a bit of fixed extra offset to avoid collisions at T intersections.
    const fixedExtraOffset = glyphSize * 2;

    const offset = !isLineContinued ?
        ((shapedLabelLength / 2 + fixedExtraOffset) * boxScale * overscaling) % spacing :
        (spacing / 2 * overscaling) % spacing;

    return resample(line, offset, spacing, angleWindowSize, maxAngle, labelLength, isLineContinued, false, tileExtent);
}

function resample(line              , offset        , spacing        , angleWindowSize        , maxAngle        , labelLength        , isLineContinued         , placeAtMiddle         , tileExtent        ) {

    const halfLabelLength = labelLength / 2;
    const lineLength = getLineLength(line);

    let distance = 0,
        markedDistance = offset - spacing;

    let anchors = [];

    for (let i = 0; i < line.length - 1; i++) {

        const a = line[i],
            b = line[i + 1];

        const segmentDist = a.dist(b),
            angle = b.angleTo(a);

        while (markedDistance + spacing < distance + segmentDist) {
            markedDistance += spacing;

            const t = (markedDistance - distance) / segmentDist,
                x = number(a.x, b.x, t),
                y = number(a.y, b.y, t);

            // Check that the point is within the tile boundaries and that
            // the label would fit before the beginning and end of the line
            // if placed at this point.
            if (x >= 0 && x < tileExtent && y >= 0 && y < tileExtent &&
                    markedDistance - halfLabelLength >= 0 &&
                    markedDistance + halfLabelLength <= lineLength) {
                const anchor = new Anchor(x, y, 0, angle, i);
                anchor._round();

                if (!angleWindowSize || checkMaxAngle(line, anchor, labelLength, angleWindowSize, maxAngle)) {
                    anchors.push(anchor);
                }
            }
        }

        distance += segmentDist;
    }

    if (!placeAtMiddle && !anchors.length && !isLineContinued) {
        // The first attempt at finding anchors at which labels can be placed failed.
        // Try again, but this time just try placing one anchor at the middle of the line.
        // This has the most effect for short lines in overscaled tiles, since the
        // initial offset used in overscaled tiles is calculated to align labels with positions in
        // parent tiles instead of placing the label as close to the beginning as possible.
        anchors = resample(line, distance / 2, spacing, angleWindowSize, maxAngle, labelLength, isLineContinued, true, tileExtent);
    }

    return anchors;
}

//      


/**
 * Returns the part of a multiline that intersects with the provided rectangular box.
 *
 * @param lines
 * @param x1 the left edge of the box
 * @param y1 the top edge of the box
 * @param x2 the right edge of the box
 * @param y2 the bottom edge of the box
 * @returns lines
 * @private
 */
function clipLine(lines                     , x1        , y1        , x2        , y2        )                      {
    const clippedLines = [];

    for (let l = 0; l < lines.length; l++) {
        const line = lines[l];
        let clippedLine;

        for (let i = 0; i < line.length - 1; i++) {
            let p0 = line[i];
            let p1 = line[i + 1];

            if (p0.x < x1 && p1.x < x1) {
                continue;
            } else if (p0.x < x1) {
                p0 = new Point$2(x1, p0.y + (p1.y - p0.y) * ((x1 - p0.x) / (p1.x - p0.x)))._round();
            } else if (p1.x < x1) {
                p1 = new Point$2(x1, p0.y + (p1.y - p0.y) * ((x1 - p0.x) / (p1.x - p0.x)))._round();
            }

            if (p0.y < y1 && p1.y < y1) {
                continue;
            } else if (p0.y < y1) {
                p0 = new Point$2(p0.x + (p1.x - p0.x) * ((y1 - p0.y) / (p1.y - p0.y)), y1)._round();
            } else if (p1.y < y1) {
                p1 = new Point$2(p0.x + (p1.x - p0.x) * ((y1 - p0.y) / (p1.y - p0.y)), y1)._round();
            }

            if (p0.x >= x2 && p1.x >= x2) {
                continue;
            } else if (p0.x >= x2) {
                p0 = new Point$2(x2, p0.y + (p1.y - p0.y) * ((x2 - p0.x) / (p1.x - p0.x)))._round();
            } else if (p1.x >= x2) {
                p1 = new Point$2(x2, p0.y + (p1.y - p0.y) * ((x2 - p0.x) / (p1.x - p0.x)))._round();
            }

            if (p0.y >= y2 && p1.y >= y2) {
                continue;
            } else if (p0.y >= y2) {
                p0 = new Point$2(p0.x + (p1.x - p0.x) * ((y2 - p0.y) / (p1.y - p0.y)), y2)._round();
            } else if (p1.y >= y2) {
                p1 = new Point$2(p0.x + (p1.x - p0.x) * ((y2 - p0.y) / (p1.y - p0.y)), y2)._round();
            }

            if (!clippedLine || !p0.equals(clippedLine[clippedLine.length - 1])) {
                clippedLine = [p0];
                clippedLines.push(clippedLine);
            }

            clippedLine.push(p1);
        }
    }

    return clippedLines;
}

//      


                                                 
                                                      
                                                   

function loadGlyphRange (fontstack        ,
                           range        ,
                           urlTemplate        ,
                           requestManager                ,
                           callback                                                                                          ) {
    const begin = range * 256;
    const end = begin + 255;

    const request = requestManager.transformRequest(
        requestManager.normalizeGlyphsURL(urlTemplate)
            .replace('{fontstack}', fontstack)
            .replace('{range}', `${begin}-${end}`),
        ResourceType.Glyphs);

    getArrayBuffer(request, (err        , data              ) => {
        if (err) {
            callback(err);
        } else if (data) {
            const glyphs = {};
            const glyphData = parseGlyphPBF(data);
            for (const glyph of glyphData.glyphs) {
                glyphs[glyph.id] = glyph;
            }
            callback(null, {glyphs, ascender: glyphData.ascender, descender: glyphData.descender});
        }
    });
}

const INF = 1e20;

class TinySDF {
    constructor({
        fontSize = 24,
        buffer = 3,
        radius = 8,
        cutoff = 0.25,
        fontFamily = 'sans-serif',
        fontWeight = 'normal',
        fontStyle = 'normal'
    } = {}) {
        this.buffer = buffer;
        this.cutoff = cutoff;
        this.radius = radius;

        // make the canvas size big enough to both have the specified buffer around the glyph
        // for "halo", and account for some glyphs possibly being larger than their font size
        const size = this.size = fontSize + buffer * 4;

        const canvas = this._createCanvas(size);
        const ctx = this.ctx = canvas.getContext('2d', {willReadFrequently: true});
        ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily}`;

        ctx.textBaseline = 'alphabetic';
        ctx.textAlign = 'left'; // Necessary so that RTL text doesn't have different alignment
        ctx.fillStyle = 'black';

        // temporary arrays for the distance transform
        this.gridOuter = new Float64Array(size * size);
        this.gridInner = new Float64Array(size * size);
        this.f = new Float64Array(size);
        this.z = new Float64Array(size + 1);
        this.v = new Uint16Array(size);
    }

    _createCanvas(size) {
        const canvas = document.createElement('canvas');
        canvas.width = canvas.height = size;
        return canvas;
    }

    draw(char) {
        const {
            width: glyphAdvance,
            actualBoundingBoxAscent,
            actualBoundingBoxDescent,
            actualBoundingBoxLeft,
            actualBoundingBoxRight
        } = this.ctx.measureText(char);

        // The integer/pixel part of the top alignment is encoded in metrics.glyphTop
        // The remainder is implicitly encoded in the rasterization
        const glyphTop = Math.ceil(actualBoundingBoxAscent);
        const glyphLeft = 0;

        // If the glyph overflows the canvas size, it will be clipped at the bottom/right
        const glyphWidth = Math.max(0, Math.min(this.size - this.buffer, Math.ceil(actualBoundingBoxRight - actualBoundingBoxLeft)));
        const glyphHeight = Math.min(this.size - this.buffer, glyphTop + Math.ceil(actualBoundingBoxDescent));

        const width = glyphWidth + 2 * this.buffer;
        const height = glyphHeight + 2 * this.buffer;

        const len = Math.max(width * height, 0);
        const data = new Uint8ClampedArray(len);
        const glyph = {data, width, height, glyphWidth, glyphHeight, glyphTop, glyphLeft, glyphAdvance};
        if (glyphWidth === 0 || glyphHeight === 0) return glyph;

        const {ctx, buffer, gridInner, gridOuter} = this;
        ctx.clearRect(buffer, buffer, glyphWidth, glyphHeight);
        ctx.fillText(char, buffer, buffer + glyphTop);
        const imgData = ctx.getImageData(buffer, buffer, glyphWidth, glyphHeight);

        // Initialize grids outside the glyph range to alpha 0
        gridOuter.fill(INF, 0, len);
        gridInner.fill(0, 0, len);

        for (let y = 0; y < glyphHeight; y++) {
            for (let x = 0; x < glyphWidth; x++) {
                const a = imgData.data[4 * (y * glyphWidth + x) + 3] / 255; // alpha value
                if (a === 0) continue; // empty pixels

                const j = (y + buffer) * width + x + buffer;

                if (a === 1) { // fully drawn pixels
                    gridOuter[j] = 0;
                    gridInner[j] = INF;

                } else { // aliased pixels
                    const d = 0.5 - a;
                    gridOuter[j] = d > 0 ? d * d : 0;
                    gridInner[j] = d < 0 ? d * d : 0;
                }
            }
        }

        edt(gridOuter, 0, 0, width, height, width, this.f, this.v, this.z);
        edt(gridInner, buffer, buffer, glyphWidth, glyphHeight, width, this.f, this.v, this.z);

        for (let i = 0; i < len; i++) {
            const d = Math.sqrt(gridOuter[i]) - Math.sqrt(gridInner[i]);
            data[i] = Math.round(255 - 255 * (d / this.radius + this.cutoff));
        }

        return glyph;
    }
}

// 2D Euclidean squared distance transform by Felzenszwalb & Huttenlocher https://cs.brown.edu/~pff/papers/dt-final.pdf
function edt(data, x0, y0, width, height, gridSize, f, v, z) {
    for (let x = x0; x < x0 + width; x++) edt1d(data, y0 * gridSize + x, gridSize, height, f, v, z);
    for (let y = y0; y < y0 + height; y++) edt1d(data, y * gridSize + x0, 1, width, f, v, z);
}

// 1D squared distance transform
function edt1d(grid, offset, stride, length, f, v, z) {
    v[0] = 0;
    z[0] = -INF;
    z[1] = INF;
    f[0] = grid[offset];

    for (let q = 1, k = 0, s = 0; q < length; q++) {
        f[q] = grid[offset + q * stride];
        const q2 = q * q;
        do {
            const r = v[k];
            s = (f[q] - f[r] + q2 - r * r) / (q - r) / 2;
        } while (s <= z[k] && --k > -1);

        k++;
        v[k] = q;
        z[k] = s;
        z[k + 1] = INF;
    }

    for (let q = 0, k = 0; q < length; q++) {
        while (z[k + 1] < q) k++;
        const r = v[k];
        const qr = q - r;
        grid[offset + q * stride] = f[r] + qr * qr;
    }
}

//      


                                                        
                                                      
                                                   

/*
  SDF_SCALE controls the pixel density of locally generated glyphs relative
  to "normal" SDFs which are generated at 24pt font and a "pixel ratio" of 1.
  The GlyphManager will generate glyphs SDF_SCALE times as large,
  but with the same glyph metrics, and the quad generation code will scale them
  back down so they display at the same size.

  The choice of SDF_SCALE is a trade-off between performance and quality.
  Glyph generation time grows quadratically with the the scale, while quality
  improvements drop off rapidly when the scale is higher than the pixel ratio
  of the device. The scale of 2 buys noticeable improvements on HDPI screens
  at acceptable cost.

  The scale can be any value, but in order to avoid small distortions, these
  pixel-based values must come out to integers:
   - "localGlyphPadding" in GlyphAtlas
   - Font/Canvas/Buffer size for TinySDF
  localGlyphPadding + buffer should equal 4 * SDF_SCALE. So if you wanted to
  use an SDF_SCALE of 1.75, you could manually set localGlyphAdding to 2 and
  buffer to 5.
*/
const SDF_SCALE = 2;

              
                                                                                         
                                              
                                                                                                                                 
                                              
                      
                      
                      
  

const LocalGlyphMode = {
    none: 0,
    ideographs: 1,
    all: 2
};

class GlyphManager {
                                   
                             
                           
                                  
    // Multiple fontstacks may share the same local glyphs, so keep an index
    // into the glyphs based soley on font weight
                                                                                                                   
                 

    // exposed as statics to enable stubbing in unit tests
                                                 
                                   

    constructor(requestManager                , localGlyphMode        , localFontFamily         ) {
        this.requestManager = requestManager;
        this.localGlyphMode = localGlyphMode;
        this.localFontFamily = localFontFamily;
        this.entries = {};
        this.localGlyphs = {
            // Only these four font weights are supported
            '200': {},
            '400': {},
            '500': {},
            '900': {}
        };
    }

    setURL(url         ) {
        this.url = url;
    }

    getGlyphs(glyphs                                  , callback                                                                                                          ) {
        const all = [];

        for (const stack in glyphs) {
            for (const id of glyphs[stack]) {
                all.push({stack, id});
            }
        }

        asyncAll(all, ({stack, id}, fnCallback                                                           ) => {
            let entry = this.entries[stack];
            if (!entry) {
                entry = this.entries[stack] = {
                    glyphs: {},
                    requests: {},
                    ranges: {},
                    ascender: undefined,
                    descender: undefined
                };
            }

            let glyph = entry.glyphs[id];
            if (glyph !== undefined) {
                fnCallback(null, {stack, id, glyph});
                return;
            }

            glyph = this._tinySDF(entry, stack, id);
            if (glyph) {
                entry.glyphs[id] = glyph;
                fnCallback(null, {stack, id, glyph});
                return;
            }

            const range = Math.floor(id / 256);
            if (range * 256 > 65535) {
                fnCallback(new Error('glyphs > 65535 not supported'));
                return;
            }

            if (entry.ranges[range]) {
                fnCallback(null, {stack, id, glyph});
                return;
            }

            let requests = entry.requests[range];
            if (!requests) {
                requests = entry.requests[range] = [];
                GlyphManager.loadGlyphRange(stack, range, (this.url     ), this.requestManager,
                    (err, response                                                                                    ) => {
                        if (response) {
                            entry.ascender = response.ascender;
                            entry.descender = response.descender;
                            for (const id in response.glyphs) {
                                if (!this._doesCharSupportLocalGlyph(+id)) {
                                    entry.glyphs[+id] = response.glyphs[+id];
                                }
                            }
                            entry.ranges[range] = true;
                        }
                        for (const cb of requests) {
                            cb(err, response);
                        }
                        delete entry.requests[range];
                    });
            }

            requests.push((err, result                                                                                    ) => {
                if (err) {
                    fnCallback(err);
                } else if (result) {
                    fnCallback(null, {stack, id, glyph: result.glyphs[id] || null});
                }
            });
        }, (err, glyphs                                                         ) => {
            if (err) {
                callback(err);
            } else if (glyphs) {
                const result = {};

                for (const {stack, id, glyph} of glyphs) {
                    // Clone the glyph so that our own copy of its ArrayBuffer doesn't get transferred.
                    if (result[stack] === undefined) result[stack] = {};
                    if (result[stack].glyphs === undefined) result[stack].glyphs = {};
                    result[stack].glyphs[id] = glyph && {
                        id: glyph.id,
                        bitmap: glyph.bitmap.clone(),
                        metrics: glyph.metrics
                    };
                    result[stack].ascender = this.entries[stack].ascender;
                    result[stack].descender = this.entries[stack].descender;
                }

                callback(null, result);
            }
        });
    }

    _doesCharSupportLocalGlyph(id        )          {
        if (this.localGlyphMode === LocalGlyphMode.none) {
            return false;
        } else if (this.localGlyphMode === LocalGlyphMode.all) {
            return !!this.localFontFamily;
        } else {
            /* eslint-disable new-cap */
            return !!this.localFontFamily &&
            ((unicodeBlockLookup['CJK Unified Ideographs'](id) ||
                unicodeBlockLookup['Hangul Syllables'](id) ||
                unicodeBlockLookup['Hiragana'](id) ||
                unicodeBlockLookup['Katakana'](id)) ||
                // gl-native parity: Extend Ideographs rasterization range to include CJK symbols and punctuations
                unicodeBlockLookup['CJK Symbols and Punctuation'](id));
            /* eslint-enable new-cap */
        }
    }

    _tinySDF(entry       , stack        , id        )              {
        const fontFamily = this.localFontFamily;
        if (!fontFamily || !this._doesCharSupportLocalGlyph(id)) return;

        let tinySDF = entry.tinySDF;
        if (!tinySDF) {
            let fontWeight = '400';
            if (/bold/i.test(stack)) {
                fontWeight = '900';
            } else if (/medium/i.test(stack)) {
                fontWeight = '500';
            } else if (/light/i.test(stack)) {
                fontWeight = '200';
            }

            const fontSize = 24 * SDF_SCALE;
            const buffer = 3 * SDF_SCALE;
            const radius = 8 * SDF_SCALE;
            tinySDF = entry.tinySDF = new GlyphManager.TinySDF({fontFamily, fontWeight, fontSize, buffer, radius});
            tinySDF.fontWeight = fontWeight;
        }

        if (this.localGlyphs[tinySDF.fontWeight][id]) {
            return this.localGlyphs[tinySDF.fontWeight][id];
        }

        const char = String.fromCharCode(id);
        const {data, width, height, glyphWidth, glyphHeight, glyphLeft, glyphTop, glyphAdvance} = tinySDF.draw(char);
        /*
        TinySDF's "top" is the distance from the alphabetic baseline to the
         top of the glyph.

        Server-generated fonts specify "top" relative to an origin above the
         em box (the origin comes from FreeType, but I'm unclear on exactly
         how it's derived)
          ref: https://github.com/mapbox/sdf-glyph-foundry

        Server fonts don't yet include baseline information, so we can't line
        up exactly with them (and they don't line up with each other)
          ref: https://github.com/mapbox/node-fontnik/pull/160

        To approximately align TinySDF glyphs with server-provided glyphs, we
        use this baseline adjustment factor calibrated to be in between DIN Pro
        and Arial Unicode (but closer to Arial Unicode)
        */
        const baselineAdjustment = 27;

        const glyph = this.localGlyphs[tinySDF.fontWeight][id] = {
            id,
            bitmap: new AlphaImage({width, height}, data),
            metrics: {
                width: glyphWidth / SDF_SCALE,
                height: glyphHeight / SDF_SCALE,
                left: glyphLeft / SDF_SCALE,
                top: glyphTop / SDF_SCALE - baselineAdjustment,
                advance: glyphAdvance / SDF_SCALE,
                localGlyph: true
            }
        };
        return glyph;
    }
}

GlyphManager.loadGlyphRange = loadGlyphRange;
GlyphManager.TinySDF = TinySDF;

//      


                                                 

/**
 * A textured quad for rendering a single icon or glyph.
 *
 * The zoom range the glyph can be shown is defined by minScale and maxScale.
 *
 * @param tl The offset of the top left corner from the anchor.
 * @param tr The offset of the top right corner from the anchor.
 * @param bl The offset of the bottom left corner from the anchor.
 * @param br The offset of the bottom right corner from the anchor.
 * @param tex The texture coordinates.
 *
 * @private
 */
                          
              
              
              
              
          
                  
                  
                  
                 
      
                         
                         
                            
                                  
                         
                   
                          
                         
  

// If you have a 10px icon that isn't perfectly aligned to the pixel grid it will cover 11 actual
// pixels. The quad needs to be padded to account for this, otherwise they'll look slightly clipped
// on one edge in some cases.
const border = IMAGE_PADDING;

/**
 * Create the quads used for rendering an icon.
 * @private
 */
function getIconQuads(
                      shapedIcon                ,
                      iconRotate        ,
                      isSDFIcon         ,
                      hasIconTextFit         )                    {
    const quads = [];

    const image = shapedIcon.image;
    const pixelRatio = image.pixelRatio;
    const imageWidth = image.paddedRect.w - 2 * border;
    const imageHeight = image.paddedRect.h - 2 * border;

    const iconWidth = shapedIcon.right - shapedIcon.left;
    const iconHeight = shapedIcon.bottom - shapedIcon.top;

    const stretchX = image.stretchX || [[0, imageWidth]];
    const stretchY = image.stretchY || [[0, imageHeight]];

    const reduceRanges = (sum        , range                  ) => sum + range[1] - range[0];
    const stretchWidth = stretchX.reduce(reduceRanges, 0);
    const stretchHeight = stretchY.reduce(reduceRanges, 0);
    const fixedWidth = imageWidth - stretchWidth;
    const fixedHeight = imageHeight - stretchHeight;

    let stretchOffsetX = 0;
    let stretchContentWidth = stretchWidth;
    let stretchOffsetY = 0;
    let stretchContentHeight = stretchHeight;
    let fixedOffsetX = 0;
    let fixedContentWidth = fixedWidth;
    let fixedOffsetY = 0;
    let fixedContentHeight = fixedHeight;

    if (image.content && hasIconTextFit) {
        const content = image.content;
        stretchOffsetX = sumWithinRange(stretchX, 0, content[0]);
        stretchOffsetY = sumWithinRange(stretchY, 0, content[1]);
        stretchContentWidth = sumWithinRange(stretchX, content[0], content[2]);
        stretchContentHeight = sumWithinRange(stretchY, content[1], content[3]);
        fixedOffsetX = content[0] - stretchOffsetX;
        fixedOffsetY = content[1] - stretchOffsetY;
        fixedContentWidth = content[2] - content[0] - stretchContentWidth;
        fixedContentHeight = content[3] - content[1] - stretchContentHeight;
    }

    const makeBox = (left      , top      , right      , bottom      ) => {

        const leftEm = getEmOffset(left.stretch - stretchOffsetX, stretchContentWidth, iconWidth, shapedIcon.left);
        const leftPx = getPxOffset(left.fixed - fixedOffsetX, fixedContentWidth, left.stretch, stretchWidth);

        const topEm = getEmOffset(top.stretch - stretchOffsetY, stretchContentHeight, iconHeight, shapedIcon.top);
        const topPx = getPxOffset(top.fixed - fixedOffsetY, fixedContentHeight, top.stretch, stretchHeight);

        const rightEm = getEmOffset(right.stretch - stretchOffsetX, stretchContentWidth, iconWidth, shapedIcon.left);
        const rightPx = getPxOffset(right.fixed - fixedOffsetX, fixedContentWidth, right.stretch, stretchWidth);

        const bottomEm = getEmOffset(bottom.stretch - stretchOffsetY, stretchContentHeight, iconHeight, shapedIcon.top);
        const bottomPx = getPxOffset(bottom.fixed - fixedOffsetY, fixedContentHeight, bottom.stretch, stretchHeight);

        const tl = new Point$2(leftEm, topEm);
        const tr = new Point$2(rightEm, topEm);
        const br = new Point$2(rightEm, bottomEm);
        const bl = new Point$2(leftEm, bottomEm);
        const pixelOffsetTL = new Point$2(leftPx / pixelRatio, topPx / pixelRatio);
        const pixelOffsetBR = new Point$2(rightPx / pixelRatio, bottomPx / pixelRatio);

        const angle = iconRotate * Math.PI / 180;

        if (angle) {
            const sin = Math.sin(angle),
                cos = Math.cos(angle),
                matrix = [cos, -sin, sin, cos];

            tl._matMult(matrix);
            tr._matMult(matrix);
            bl._matMult(matrix);
            br._matMult(matrix);
        }

        const x1 = left.stretch + left.fixed;
        const x2 = right.stretch + right.fixed;
        const y1 = top.stretch + top.fixed;
        const y2 = bottom.stretch + bottom.fixed;

        const subRect = {
            x: image.paddedRect.x + border + x1,
            y: image.paddedRect.y + border + y1,
            w: x2 - x1,
            h: y2 - y1
        };

        const minFontScaleX = fixedContentWidth / pixelRatio / iconWidth;
        const minFontScaleY = fixedContentHeight / pixelRatio / iconHeight;

        // Icon quad is padded, so texture coordinates also need to be padded.
        return {tl, tr, bl, br, tex: subRect, writingMode: undefined, glyphOffset: [0, 0], sectionIndex: 0, pixelOffsetTL, pixelOffsetBR, minFontScaleX, minFontScaleY, isSDF: isSDFIcon};
    };

    if (!hasIconTextFit || (!image.stretchX && !image.stretchY)) {
        quads.push(makeBox(
            {fixed: 0, stretch: -1},
            {fixed: 0, stretch: -1},
            {fixed: 0, stretch: imageWidth + 1},
            {fixed: 0, stretch: imageHeight + 1}));
    } else {
        const xCuts = stretchZonesToCuts(stretchX, fixedWidth, stretchWidth);
        const yCuts = stretchZonesToCuts(stretchY, fixedHeight, stretchHeight);

        for (let xi = 0; xi < xCuts.length - 1; xi++) {
            const x1 = xCuts[xi];
            const x2 = xCuts[xi + 1];
            for (let yi = 0; yi < yCuts.length - 1; yi++) {
                const y1 = yCuts[yi];
                const y2 = yCuts[yi + 1];
                quads.push(makeBox(x1, y1, x2, y2));
            }
        }
    }

    return quads;
}

function sumWithinRange(ranges                         , min        , max        ) {
    let sum = 0;
    for (const range of ranges) {
        sum += Math.max(min, Math.min(max, range[1])) - Math.max(min, Math.min(max, range[0]));
    }
    return sum;
}

function stretchZonesToCuts(stretchZones                         , fixedSize        , stretchSize        ) {
    const cuts = [{fixed: -border, stretch: 0}];

    for (const [c1, c2] of stretchZones) {
        const last = cuts[cuts.length - 1];
        cuts.push({
            fixed: c1 - last.stretch,
            stretch: last.stretch
        });
        cuts.push({
            fixed: c1 - last.stretch,
            stretch: last.stretch + (c2 - c1)
        });
    }
    cuts.push({
        fixed: fixedSize + border,
        stretch: stretchSize
    });
    return cuts;
}

function getEmOffset(stretchOffset        , stretchSize        , iconSize        , iconOffset        ) {
    return stretchOffset / stretchSize * iconSize + iconOffset;
}

function getPxOffset(fixedOffset        , fixedSize        , stretchOffset        , stretchSize        ) {
    return fixedOffset - fixedSize * stretchOffset / stretchSize;
}

function getRotateOffset(textOffset                  ) {
    const x = textOffset[0], y = textOffset[1];
    const product = x * y;
    if (product > 0) {
        return [x, -y];
    } else if (product < 0) {
        return [-x, y];
    } else if (x === 0) {
        return [y, x];
    } else {
        return [y, -x];
    }
}

function getMidlineOffset(shaping         , lineHeight        , previousOffset        , lineIndex        ) {
    const currentLineHeight = (lineHeight + shaping.positionedLines[lineIndex].lineOffset);
    if (lineIndex === 0) {
        return previousOffset + currentLineHeight / 2.0;
    }
    const aboveLineHeight = (lineHeight + shaping.positionedLines[lineIndex - 1].lineOffset);
    return previousOffset + (currentLineHeight + aboveLineHeight) / 2.0;
}

/**
 * Create the quads used for rendering a text label.
 * @private
 */
function getGlyphQuads(anchor        ,
                       shaping         ,
                       textOffset                  ,
                       layer                  ,
                       alongLine         ,
                       feature         ,
                       imageMap                           ,
                       allowVerticalPlacement         )                    {
    const quads = [];
    if (shaping.positionedLines.length === 0) return quads;

    const textRotate = layer.layout.get('text-rotate').evaluate(feature, {}) * Math.PI / 180;
    const rotateOffset = getRotateOffset(textOffset);

    let shapingHeight = Math.abs(shaping.top - shaping.bottom);
    for (const line of shaping.positionedLines) {
        shapingHeight -= line.lineOffset;
    }
    const lineCounts = shaping.positionedLines.length;
    const lineHeight = shapingHeight / lineCounts;
    let currentOffset = shaping.top - textOffset[1];
    for (let lineIndex = 0; lineIndex < lineCounts; ++lineIndex) {
        const line = shaping.positionedLines[lineIndex];
        currentOffset = getMidlineOffset(shaping, lineHeight, currentOffset, lineIndex);
        for (const positionedGlyph of line.positionedGlyphs) {
            if (!positionedGlyph.rect) continue;
            const textureRect = positionedGlyph.rect || {};

            // The rects have an additional buffer that is not included in their size.
            const glyphPadding = 1.0;
            let rectBuffer = GLYPH_PBF_BORDER + glyphPadding;
            let isSDF = true;
            let pixelRatio = 1.0;
            let lineOffset = 0.0;
            if (positionedGlyph.imageName) {
                const image = imageMap[positionedGlyph.imageName];
                if (!image) continue;
                if (image.sdf) {
                    warnOnce("SDF images are not supported in formatted text and will be ignored.");
                    continue;
                }
                isSDF = false;
                pixelRatio = image.pixelRatio;
                rectBuffer = IMAGE_PADDING / pixelRatio;
            }

            const rotateVerticalGlyph = (alongLine || allowVerticalPlacement) && positionedGlyph.vertical;
            const halfAdvance = positionedGlyph.metrics.advance * positionedGlyph.scale / 2;
            const metrics = positionedGlyph.metrics;
            const rect = positionedGlyph.rect;
            if (rect === null) continue;

            // Align images and scaled glyphs in the middle of a vertical line.
            if (allowVerticalPlacement && shaping.verticalizable) {
                // image's advance for vertical shaping is its height, so that we have to take the difference into
                // account after image glyph is rotated
                lineOffset = positionedGlyph.imageName ? halfAdvance - positionedGlyph.metrics.width * positionedGlyph.scale / 2.0 : 0;
            }

            const glyphOffset = alongLine ?
                [positionedGlyph.x + halfAdvance, positionedGlyph.y] :
                [0, 0];

            let builtInOffset = [0, 0];
            let verticalizedLabelOffset = [0, 0];
            let useRotateOffset = false;
            if (!alongLine) {
                if (rotateVerticalGlyph) {
                // Vertical POI labels that are rotated 90deg CW and whose glyphs must preserve upright orientation
                // need to be rotated 90deg CCW. After a quad is rotated, it is translated to the original built-in offset.
                    verticalizedLabelOffset =
                        [positionedGlyph.x + halfAdvance + rotateOffset[0], positionedGlyph.y + rotateOffset[1] - lineOffset];
                    useRotateOffset = true;
                } else {
                    builtInOffset =  [positionedGlyph.x + halfAdvance + textOffset[0], positionedGlyph.y + textOffset[1] - lineOffset];
                }
            }

            const paddedWidth =
                rect.w * positionedGlyph.scale / (pixelRatio * (positionedGlyph.localGlyph ? SDF_SCALE : 1));
            const  paddedHeight =
                rect.h * positionedGlyph.scale / (pixelRatio * (positionedGlyph.localGlyph ? SDF_SCALE : 1));

            let tl, tr, bl, br;
            if (!rotateVerticalGlyph) {
                const x1 = (metrics.left - rectBuffer) * positionedGlyph.scale - halfAdvance + builtInOffset[0];
                const y1 = (-metrics.top - rectBuffer) * positionedGlyph.scale + builtInOffset[1];
                const x2 = x1 + paddedWidth;
                const y2 = y1 + paddedHeight;

                tl = new Point$2(x1, y1);
                tr = new Point$2(x2, y1);
                bl = new Point$2(x1, y2);
                br = new Point$2(x2, y2);
            } else {
                // For vertical glyph placement, follow the steps to put the glyph bitmap in right coordinates:
                // 1. Rotate the glyph by using original glyph coordinates instead of padded coordinates, since the
                // rotation center and xOffsetCorrection are all based on original glyph's size.
                // 2. Do x offset correction so that 'tl' is shifted to the same x coordinate before rotation.
                // 3. Adjust glyph positon for 'tl' by applying vertial padding and horizontal shift, now 'tl' is the
                // coordinate where we draw the glyph bitmap.
                // 4. Calculate other three bitmap coordinates.

                // Vertical-supporting glyphs are laid out in 24x24 point boxes (1 square em)
                // In horizontal orientation, the "yShift" is the negative value of the height that
                // the glyph is above the horizontal midline.
                // By rotating counter-clockwise around the point at the center of the left
                // edge of a 24x24 layout box centered below the midline, we align the midline
                // of the rotated glyphs with the horizontal midline, so the yShift is no longer
                // necessary, but we also pull the glyph to the left along the x axis.
                const yShift = (positionedGlyph.y - currentOffset);
                const center = new Point$2(-halfAdvance, halfAdvance - yShift);
                const verticalRotation = -Math.PI / 2;
                const verticalOffsetCorrection = new Point$2(...verticalizedLabelOffset);
                // Relative position before rotation
                // tl ----- tr
                //   |     |
                //   |     |
                // bl ----- br
                tl = new Point$2(-halfAdvance + builtInOffset[0], builtInOffset[1]);
                tl._rotateAround(verticalRotation, center)._add(verticalOffsetCorrection);

                // Relative position after rotating
                // tr ----- br
                //   |     |
                //   |     |
                // tl ----- bl
                // After rotation, glyph lies on the horizontal midline.
                // Shift back to tl's original x coordinate before rotation by applying 'xOffsetCorrection'.
                tl.x += -yShift + halfAdvance;

                // Add padding for y coordinate's justification
                tl.y -= (metrics.left - rectBuffer) * positionedGlyph.scale;

                // Adjust x coordinate according to glyph bitmap's height and the vectical advance
                const verticalAdvance = positionedGlyph.imageName ? metrics.advance * positionedGlyph.scale :
                    ONE_EM * positionedGlyph.scale;
                // Check wether the glyph is generated from server side or locally
                const chr = String.fromCharCode(positionedGlyph.glyph);
                if (isVerticalClosePunctuation(chr)) {
                    // Place vertical punctuation in right place, pull down 1 pixel's space for close punctuations
                    tl.x += (-rectBuffer + 1) * positionedGlyph.scale;
                } else if (isVerticalOpenPunctuation(chr)) {
                    const xOffset = verticalAdvance - metrics.height * positionedGlyph.scale;
                    // Place vertical punctuation in right place, pull up 1 pixel's space for open punctuations
                    tl.x += xOffset + (-rectBuffer - 1) * positionedGlyph.scale;
                } else if (!positionedGlyph.imageName &&
                           ((metrics.width + rectBuffer * 2) !== rect.w || metrics.height + rectBuffer * 2 !== rect.h)) {
                    // Locally generated glyphs' bitmap do not have exact 'rectBuffer' padded around the glyphs,
                    // but the original tl do have distance of rectBuffer padded to the top of the glyph.
                    const perfectPaddedHeight = (metrics.height + rectBuffer * 2) * positionedGlyph.scale;
                    const delta = verticalAdvance - perfectPaddedHeight;
                    tl.x += delta / 2;
                } else {
                    // Place the glyph bitmap right in the center of the 24x24 point boxes
                    const delta = verticalAdvance - paddedHeight;
                    tl.x += delta / 2;
                }
                // Calculate other three points
                tr = new Point$2(tl.x, tl.y - paddedWidth);
                bl = new Point$2(tl.x + paddedHeight, tl.y);
                br = new Point$2(tl.x + paddedHeight, tl.y - paddedWidth);
            }

            if (textRotate) {
                let center;
                if (!alongLine) {
                    if (useRotateOffset) {
                        center = new Point$2(rotateOffset[0], rotateOffset[1]);
                    } else {
                        center = new Point$2(textOffset[0], textOffset[1]);
                    }
                } else {
                    center = new Point$2(0, 0);
                }
                tl._rotateAround(textRotate, center);
                tr._rotateAround(textRotate, center);
                bl._rotateAround(textRotate, center);
                br._rotateAround(textRotate, center);
            }

            const pixelOffsetTL = new Point$2(0, 0);
            const pixelOffsetBR = new Point$2(0, 0);
            const minFontScaleX = 0;
            const minFontScaleY = 0;
            quads.push({tl, tr, bl, br, tex: textureRect, writingMode: shaping.writingMode, glyphOffset, sectionIndex: positionedGlyph.sectionIndex, isSDF, pixelOffsetTL, pixelOffsetBR, minFontScaleX, minFontScaleY});
        }
    }

    return quads;
}

class TinyQueue {
    constructor(data = [], compare = defaultCompare) {
        this.data = data;
        this.length = this.data.length;
        this.compare = compare;

        if (this.length > 0) {
            for (let i = (this.length >> 1) - 1; i >= 0; i--) this._down(i);
        }
    }

    push(item) {
        this.data.push(item);
        this.length++;
        this._up(this.length - 1);
    }

    pop() {
        if (this.length === 0) return undefined;

        const top = this.data[0];
        const bottom = this.data.pop();
        this.length--;

        if (this.length > 0) {
            this.data[0] = bottom;
            this._down(0);
        }

        return top;
    }

    peek() {
        return this.data[0];
    }

    _up(pos) {
        const {data, compare} = this;
        const item = data[pos];

        while (pos > 0) {
            const parent = (pos - 1) >> 1;
            const current = data[parent];
            if (compare(item, current) >= 0) break;
            data[pos] = current;
            pos = parent;
        }

        data[pos] = item;
    }

    _down(pos) {
        const {data, compare} = this;
        const halfLength = this.length >> 1;
        const item = data[pos];

        while (pos < halfLength) {
            let left = (pos << 1) + 1;
            let best = data[left];
            const right = left + 1;

            if (right < this.length && compare(data[right], best) < 0) {
                left = right;
                best = data[right];
            }
            if (compare(best, item) >= 0) break;

            data[pos] = best;
            pos = left;
        }

        data[pos] = item;
    }
}

function defaultCompare(a, b) {
    return a < b ? -1 : a > b ? 1 : 0;
}

//      


/**
 * Finds an approximation of a polygon's Pole Of Inaccessibility https://en.wikipedia.org/wiki/Pole_of_inaccessibility
 * This is a copy of http://github.com/mapbox/polylabel adapted to use Points
 *
 * @param polygonRings first item in array is the outer ring followed optionally by the list of holes, should be an element of the result of util/classify_rings
 * @param precision Specified in input coordinate units. If 0 returns after first run, if > 0 repeatedly narrows the search space until the radius of the area searched for the best pole is less than precision
 * @param debug Print some statistics to the console during execution
 * @returns Pole of Inaccessibility.
 * @private
 */
function findPoleOfInaccessibility (polygonRings                     , precision          = 1, debug           = false)        {
    // find the bounding box of the outer ring
    let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
    const outerRing = polygonRings[0];
    for (let i = 0; i < outerRing.length; i++) {
        const p = outerRing[i];
        if (!i || p.x < minX) minX = p.x;
        if (!i || p.y < minY) minY = p.y;
        if (!i || p.x > maxX) maxX = p.x;
        if (!i || p.y > maxY) maxY = p.y;
    }

    const width = maxX - minX;
    const height = maxY - minY;
    const cellSize = Math.min(width, height);
    let h = cellSize / 2;

    // a priority queue of cells in order of their "potential" (max distance to polygon)
    const cellQueue = new TinyQueue([], compareMax);

    if (cellSize === 0) return new Point$2(minX, minY);

    // cover polygon with initial cells
    for (let x = minX; x < maxX; x += cellSize) {
        for (let y = minY; y < maxY; y += cellSize) {
            cellQueue.push(new Cell(x + h, y + h, h, polygonRings));
        }
    }

    // take centroid as the first best guess
    let bestCell = getCentroidCell(polygonRings);
    let numProbes = cellQueue.length;

    while (cellQueue.length) {
        // pick the most promising cell from the queue
        const cell = cellQueue.pop();

        // update the best cell if we found a better one
        if (cell.d > bestCell.d || !bestCell.d) {
            bestCell = cell;
            if (debug) console.log('found best %d after %d probes', Math.round(1e4 * cell.d) / 1e4, numProbes);
        }

        // do not drill down further if there's no chance of a better solution
        if (cell.max - bestCell.d <= precision) continue;

        // split the cell into four cells
        h = cell.h / 2;
        cellQueue.push(new Cell(cell.p.x - h, cell.p.y - h, h, polygonRings));
        cellQueue.push(new Cell(cell.p.x + h, cell.p.y - h, h, polygonRings));
        cellQueue.push(new Cell(cell.p.x - h, cell.p.y + h, h, polygonRings));
        cellQueue.push(new Cell(cell.p.x + h, cell.p.y + h, h, polygonRings));
        numProbes += 4;
    }

    if (debug) {
        console.log(`num probes: ${numProbes}`);
        console.log(`best distance: ${bestCell.d}`);
    }

    return bestCell.p;
}

function compareMax(a      , b      ) {
    return b.max - a.max;
}

class Cell {
             
              
              
                

    constructor(x        , y        , h        , polygon                     ) {
        this.p = new Point$2(x, y);
        this.h = h; // half the cell size
        this.d = pointToPolygonDist(this.p, polygon); // distance from cell center to polygon
        this.max = this.d + this.h * Math.SQRT2; // max distance to polygon within a cell
    }
}

// signed distance from point to polygon outline (negative if point is outside)
function pointToPolygonDist(p       , polygon                     ) {
    let inside = false;
    let minDistSq = Infinity;

    for (let k = 0; k < polygon.length; k++) {
        const ring = polygon[k];

        for (let i = 0, len = ring.length, j = len - 1; i < len; j = i++) {
            const a = ring[i];
            const b = ring[j];

            if ((a.y > p.y !== b.y > p.y) &&
                (p.x < (b.x - a.x) * (p.y - a.y) / (b.y - a.y) + a.x)) inside = !inside;

            minDistSq = Math.min(minDistSq, distToSegmentSquared(p, a, b));
        }
    }

    return (inside ? 1 : -1) * Math.sqrt(minDistSq);
}

// get polygon centroid
function getCentroidCell(polygon                     ) {
    let area = 0;
    let x = 0;
    let y = 0;
    const points = polygon[0];
    for (let i = 0, len = points.length, j = len - 1; i < len; j = i++) {
        const a = points[i];
        const b = points[j];
        const f = a.x * b.y - b.x * a.y;
        x += (a.x + b.x) * f;
        y += (a.y + b.y) * f;
        area += f * 3;
    }
    return new Cell(x / area, y / area, 0, polygon);
}

//      


// The symbol layout process needs `text-size` evaluated at up to five different zoom levels, and
// `icon-size` at up to three:
//
//   1. `text-size` at the zoom level of the bucket. Used to calculate a per-feature size for source `text-size`
//       expressions, and to calculate the box dimensions for icon-text-fit.
//   2. `icon-size` at the zoom level of the bucket. Used to calculate a per-feature size for source `icon-size`
//       expressions.
//   3. `text-size` and `icon-size` at the zoom level of the bucket, plus one. Used to calculate collision boxes.
//   4. `text-size` at zoom level 18. Used for something line-symbol-placement-related.
//   5.  For composite `*-size` expressions: two zoom levels of curve stops that "cover" the zoom level of the
//       bucket. These go into a vertex buffer and are used by the shader to interpolate the size at render time.
//
// (1) and (2) are stored in `bucket.layers[0].layout`. The remainder are below.
//
              
                                                                  
                                                                  
                                                                  
                                                                                                                
                                                                                                                
  

                                                                                                                                    

// The radial offset is to the edge of the text box
// In the horizontal direction, the edge of the text box is where glyphs start
// But in the vertical direction, the glyphs appear to "start" at the baseline
// We don't actually load baseline data, but we assume an offset of ONE_EM - 17
// (see "yOffset" in shaping.js)
const baselineOffset = 7;
const INVALID_TEXT_OFFSET = Number.POSITIVE_INFINITY;
const sqrt2 = Math.sqrt(2);

function evaluateVariableOffset(anchor            , [offsetX, offsetY]                  )                   {
    let x = 0, y = 0;

    if (offsetY === INVALID_TEXT_OFFSET) { // radial offset
        if (offsetX < 0) offsetX = 0; // Ignore negative offset.
        // solve for r where r^2 + r^2 = offsetX^2
        const hypotenuse = offsetX / sqrt2;
        switch (anchor) {
        case 'top-right':
        case 'top-left':
            y = hypotenuse - baselineOffset;
            break;
        case 'bottom-right':
        case 'bottom-left':
            y = -hypotenuse + baselineOffset;
            break;
        case 'bottom':
            y = -offsetX + baselineOffset;
            break;
        case 'top':
            y = offsetX - baselineOffset;
            break;
        }

        switch (anchor) {
        case 'top-right':
        case 'bottom-right':
            x = -hypotenuse;
            break;
        case 'top-left':
        case 'bottom-left':
            x = hypotenuse;
            break;
        case 'left':
            x = offsetX;
            break;
        case 'right':
            x = -offsetX;
            break;
        }

    } else { // text offset
        // Use absolute offset values.
        offsetX = Math.abs(offsetX);
        offsetY = Math.abs(offsetY);

        switch (anchor) {
        case 'top-right':
        case 'top-left':
        case 'top':
            y = offsetY - baselineOffset;
            break;
        case 'bottom-right':
        case 'bottom-left':
        case 'bottom':
            y = -offsetY + baselineOffset;
            break;
        }

        switch (anchor) {
        case 'top-right':
        case 'bottom-right':
        case 'right':
            x = -offsetX;
            break;
        case 'top-left':
        case 'bottom-left':
        case 'left':
            x = offsetX;
            break;
        }
    }

    return [x, y];
}

function performSymbolLayout(bucket              ,
                             glyphMap                                                                                            ,
                             glyphPositions                ,
                             imageMap                           ,
                             imagePositions                              ,
                             showCollisionBoxes         ,
                             availableImages               ,
                             canonical                 ,
                             tileZoom        ,
                             projection            ) {
    bucket.createArrays();

    const tileSize = 512 * bucket.overscaling;
    bucket.tilePixelRatio = EXTENT / tileSize;
    bucket.compareText = {};
    bucket.iconsNeedLinear = false;

    const layout = bucket.layers[0].layout;
    const unevaluatedLayoutValues = bucket.layers[0]._unevaluatedLayout._values;

    const sizes = {};

    if (bucket.textSizeData.kind === 'composite') {
        const {minZoom, maxZoom} = bucket.textSizeData;
        sizes.compositeTextSizes = [
            unevaluatedLayoutValues['text-size'].possiblyEvaluate(new EvaluationParameters(minZoom), canonical),
            unevaluatedLayoutValues['text-size'].possiblyEvaluate(new EvaluationParameters(maxZoom), canonical)
        ];
    }

    if (bucket.iconSizeData.kind === 'composite') {
        const {minZoom, maxZoom} = bucket.iconSizeData;
        sizes.compositeIconSizes = [
            unevaluatedLayoutValues['icon-size'].possiblyEvaluate(new EvaluationParameters(minZoom), canonical),
            unevaluatedLayoutValues['icon-size'].possiblyEvaluate(new EvaluationParameters(maxZoom), canonical)
        ];
    }

    sizes.layoutTextSize = unevaluatedLayoutValues['text-size'].possiblyEvaluate(new EvaluationParameters(tileZoom + 1), canonical);
    sizes.layoutIconSize = unevaluatedLayoutValues['icon-size'].possiblyEvaluate(new EvaluationParameters(tileZoom + 1), canonical);
    sizes.textMaxSize = unevaluatedLayoutValues['text-size'].possiblyEvaluate(new EvaluationParameters(18), canonical);

    const textAlongLine = layout.get('text-rotation-alignment') === 'map' && layout.get('symbol-placement') !== 'point';
    const textSize = layout.get('text-size');

    for (const feature of bucket.features) {
        const fontstack = layout.get('text-font').evaluate(feature, {}, canonical).join(',');
        const layoutTextSizeThisZoom = textSize.evaluate(feature, {}, canonical);
        const layoutTextSize = sizes.layoutTextSize.evaluate(feature, {}, canonical);
        const layoutIconSize = sizes.layoutIconSize.evaluate(feature, {}, canonical);

        const shapedTextOrientations = {
            horizontal: {},
            vertical: undefined
        };
        const text = feature.text;
        let textOffset                   = [0, 0];
        if (text) {
            const unformattedText = text.toString();
            const spacing = layout.get('text-letter-spacing').evaluate(feature, {}, canonical) * ONE_EM;
            const lineHeight = layout.get('text-line-height').evaluate(feature, {}, canonical) * ONE_EM;
            const spacingIfAllowed = allowsLetterSpacing(unformattedText) ? spacing : 0;

            const textAnchor = layout.get('text-anchor').evaluate(feature, {}, canonical);
            const variableTextAnchor = layout.get('text-variable-anchor');

            if (!variableTextAnchor) {
                const radialOffset = layout.get('text-radial-offset').evaluate(feature, {}, canonical);
                // Layers with variable anchors use the `text-radial-offset` property and the [x, y] offset vector
                // is calculated at placement time instead of layout time
                if (radialOffset) {
                    // The style spec says don't use `text-offset` and `text-radial-offset` together
                    // but doesn't actually specify what happens if you use both. We go with the radial offset.
                    textOffset = evaluateVariableOffset(textAnchor, [radialOffset * ONE_EM, INVALID_TEXT_OFFSET]);
                } else {
                    textOffset = (layout.get('text-offset').evaluate(feature, {}, canonical).map(t => t * ONE_EM)     );
                }
            }

            let textJustify = textAlongLine ?
                "center" :
                layout.get('text-justify').evaluate(feature, {}, canonical);

            const isPointPlacement = layout.get('symbol-placement') === 'point';
            const maxWidth = isPointPlacement ?
                layout.get('text-max-width').evaluate(feature, {}, canonical) * ONE_EM :
                Infinity;

            const addVerticalShapingIfNeeded = (textJustify             ) => {
                if (bucket.allowVerticalPlacement && allowsVerticalWritingMode(unformattedText)) {
                    // Vertical POI label placement is meant to be used for scripts that support vertical
                    // writing mode, thus, default left justification is used. If Latin
                    // scripts would need to be supported, this should take into account other justifications.
                    shapedTextOrientations.vertical = shapeText(text, glyphMap, glyphPositions, imagePositions, fontstack, maxWidth, lineHeight, textAnchor,
                                                                textJustify, spacingIfAllowed, textOffset, WritingMode.vertical, true, layoutTextSize, layoutTextSizeThisZoom);
                }
            };

            // If this layer uses text-variable-anchor, generate shapings for all justification possibilities.
            if (!textAlongLine && variableTextAnchor) {
                const justifications = textJustify === "auto" ?
                    variableTextAnchor.map(a => getAnchorJustification(a)) :
                    [textJustify];

                let singleLine = false;
                for (let i = 0; i < justifications.length; i++) {
                    const justification              = justifications[i];
                    if (shapedTextOrientations.horizontal[justification]) continue;
                    if (singleLine) {
                        // If the shaping for the first justification was only a single line, we
                        // can re-use it for the other justifications
                        shapedTextOrientations.horizontal[justification] = shapedTextOrientations.horizontal[0];
                    } else {
                        // If using text-variable-anchor for the layer, we use a center anchor for all shapings and apply
                        // the offsets for the anchor in the placement step.
                        const shaping = shapeText(text, glyphMap, glyphPositions, imagePositions, fontstack, maxWidth, lineHeight, 'center',
                                                  justification, spacingIfAllowed, textOffset, WritingMode.horizontal, false, layoutTextSize, layoutTextSizeThisZoom);
                        if (shaping) {
                            shapedTextOrientations.horizontal[justification] = shaping;
                            singleLine = shaping.positionedLines.length === 1;
                        }
                    }
                }

                addVerticalShapingIfNeeded('left');
            } else {
                if (textJustify === "auto") {
                    textJustify = getAnchorJustification(textAnchor);
                }
                // Add horizontal shaping for all point labels and line labels that need horizontal writing mode.
                if (isPointPlacement || ((layout.get("text-writing-mode").indexOf('horizontal') >= 0) || !allowsVerticalWritingMode(unformattedText))) {
                    const shaping = shapeText(text, glyphMap, glyphPositions, imagePositions, fontstack, maxWidth, lineHeight, textAnchor, textJustify, spacingIfAllowed,
                                            textOffset, WritingMode.horizontal, false, layoutTextSize, layoutTextSizeThisZoom);
                    if (shaping) shapedTextOrientations.horizontal[textJustify] = shaping;
                }

                // Vertical point label (if allowVerticalPlacement is enabled).
                addVerticalShapingIfNeeded(isPointPlacement ? 'left' : textJustify);
            }
        }

        let shapedIcon;
        let isSDFIcon = false;
        if (feature.icon && feature.icon.name) {
            const image = imageMap[feature.icon.name];
            if (image) {
                shapedIcon = shapeIcon(
                    imagePositions[feature.icon.name],
                    layout.get('icon-offset').evaluate(feature, {}, canonical),
                    layout.get('icon-anchor').evaluate(feature, {}, canonical));
                isSDFIcon = image.sdf;
                if (bucket.sdfIcons === undefined) {
                    bucket.sdfIcons = image.sdf;
                } else if (bucket.sdfIcons !== image.sdf) {
                    warnOnce('Style sheet warning: Cannot mix SDF and non-SDF icons in one buffer');
                }
                if (image.pixelRatio !== bucket.pixelRatio) {
                    bucket.iconsNeedLinear = true;
                } else if (layout.get('icon-rotate').constantOr(1) !== 0) {
                    bucket.iconsNeedLinear = true;
                }
            }
        }

        const shapedText = getDefaultHorizontalShaping(shapedTextOrientations.horizontal) || shapedTextOrientations.vertical;
        if (!bucket.iconsInText) {
            bucket.iconsInText = shapedText ? shapedText.iconsInText : false;
        }
        if (shapedText || shapedIcon) {
            addFeature(bucket, feature, shapedTextOrientations, shapedIcon, imageMap, sizes, layoutTextSize, layoutIconSize, textOffset, isSDFIcon, availableImages, canonical, projection);
        }
    }

    if (showCollisionBoxes) {
        bucket.generateCollisionDebugBuffers(tileZoom, bucket.collisionBoxArray);
    }
}

// Choose the justification that matches the direction of the TextAnchor
function getAnchorJustification(anchor            )               {
    switch (anchor) {
    case 'right':
    case 'top-right':
    case 'bottom-right':
        return 'right';
    case 'left':
    case 'top-left':
    case 'bottom-left':
        return 'left';
    }
    return 'center';
}

/**
 * for "very" overscaled tiles (overscaleFactor > 2) on high zoom levels (z > 18)
 * we use the tile pixel ratio from the previous zoom level and clamp it to 1
 * in order to thin out labels density and save memory and CPU .
 * @private
 */
function tilePixelRatioForSymbolSpacing(overscaleFactor        , overscaledZ        ) {
    if (overscaledZ > 18 && overscaleFactor > 2) {
        overscaleFactor >>= 1;
    }
    const tilePixelRatio = EXTENT / (512 * overscaleFactor);
    return Math.max(tilePixelRatio, 1);
}

/**
 * Given a feature and its shaped text and icon data, add a 'symbol
 * instance' for each _possible_ placement of the symbol feature.
 * (At render time Placement.updateBucketOpacities() selects which of these
 * instances to show or hide based on collisions with symbols in other layers.)
 * @private
 */
function addFeature(bucket              ,
                    feature               ,
                    shapedTextOrientations     ,
                    shapedIcon                       ,
                    imageMap                           ,
                    sizes       ,
                    layoutTextSize        ,
                    layoutIconSize        ,
                    textOffset                  ,
                    isSDFIcon         ,
                    availableImages               ,
                    canonical                 ,
                    projection            ) {
    // To reduce the number of labels that jump around when zooming we need
    // to use a text-size value that is the same for all zoom levels.
    // bucket calculates text-size at a high zoom level so that all tiles can
    // use the same value when calculating anchor positions.
    let textMaxSize = sizes.textMaxSize.evaluate(feature, {}, canonical);
    if (textMaxSize === undefined) {
        textMaxSize = layoutTextSize;
    }
    const layout = bucket.layers[0].layout;
    const iconOffset = layout.get('icon-offset').evaluate(feature, {}, canonical);
    const defaultShaping = getDefaultHorizontalShaping(shapedTextOrientations.horizontal) || shapedTextOrientations.vertical;
    const isGlobe = projection.name === 'globe';

    const glyphSize = ONE_EM,
        fontScale = layoutTextSize / glyphSize,
        textMaxBoxScale = bucket.tilePixelRatio * textMaxSize / glyphSize,
        iconBoxScale = bucket.tilePixelRatio * layoutIconSize,
        symbolMinDistance = tilePixelRatioForSymbolSpacing(bucket.overscaling, bucket.zoom) * layout.get('symbol-spacing'),
        textPadding = layout.get('text-padding') * bucket.tilePixelRatio,
        iconPadding = layout.get('icon-padding') * bucket.tilePixelRatio,
        textMaxAngle = degToRad(layout.get('text-max-angle')),
        textAlongLine = layout.get('text-rotation-alignment') === 'map' && layout.get('symbol-placement') !== 'point',
        iconAlongLine = layout.get('icon-rotation-alignment') === 'map' && layout.get('symbol-placement') !== 'point',
        symbolPlacement = layout.get('symbol-placement'),
        textRepeatDistance = symbolMinDistance / 2;

    const iconTextFit = layout.get('icon-text-fit');
    let verticallyShapedIcon;

    // Adjust shaped icon size when icon-text-fit is used.
    if (shapedIcon && iconTextFit !== 'none') {
        if (bucket.allowVerticalPlacement && shapedTextOrientations.vertical) {
            verticallyShapedIcon = fitIconToText(shapedIcon, shapedTextOrientations.vertical, iconTextFit,
                layout.get('icon-text-fit-padding'), iconOffset, fontScale);
        }
        if (defaultShaping) {
            shapedIcon = fitIconToText(shapedIcon, defaultShaping, iconTextFit,
                                       layout.get('icon-text-fit-padding'), iconOffset, fontScale);
        }
    }

    const addSymbolAtAnchor = (line              , anchor        , canonicalId                 ) => {
        if (anchor.x < 0 || anchor.x >= EXTENT || anchor.y < 0 || anchor.y >= EXTENT) {
            // Symbol layers are drawn across tile boundaries, We filter out symbols
            // outside our tile boundaries (which may be included in vector tile buffers)
            // to prevent double-drawing symbols.
            return;
        }

        let globe                              = null;
        if (isGlobe) {
            const {x, y, z} = projection.projectTilePoint(anchor.x, anchor.y, canonicalId);
            globe = {
                anchor: new Anchor(x, y, z, 0, undefined),
                up: projection.upVector(canonicalId, anchor.x, anchor.y)
            };
        }

        addSymbol(bucket, anchor, globe, line, shapedTextOrientations, shapedIcon, imageMap, verticallyShapedIcon, bucket.layers[0],
            bucket.collisionBoxArray, feature.index, feature.sourceLayerIndex,
            bucket.index, textPadding, textAlongLine, textOffset,
            iconBoxScale, iconPadding, iconAlongLine, iconOffset,
            feature, sizes, isSDFIcon, availableImages, canonical);
    };

    if (symbolPlacement === 'line') {
        for (const line of clipLine(feature.geometry, 0, 0, EXTENT, EXTENT)) {
            const anchors = getAnchors(
                line,
                symbolMinDistance,
                textMaxAngle,
                shapedTextOrientations.vertical || defaultShaping,
                shapedIcon,
                glyphSize,
                textMaxBoxScale,
                bucket.overscaling,
                EXTENT
            );
            for (const anchor of anchors) {
                const shapedText = defaultShaping;
                if (!shapedText || !anchorIsTooClose(bucket, shapedText.text, textRepeatDistance, anchor)) {
                    addSymbolAtAnchor(line, anchor, canonical);
                }
            }
        }
    } else if (symbolPlacement === 'line-center') {
        // No clipping, multiple lines per feature are allowed
        // "lines" with only one point are ignored as in clipLines
        for (const line of feature.geometry) {
            if (line.length > 1) {
                const anchor = getCenterAnchor(
                    line,
                    textMaxAngle,
                    shapedTextOrientations.vertical || defaultShaping,
                    shapedIcon,
                    glyphSize,
                    textMaxBoxScale);
                if (anchor) {
                    addSymbolAtAnchor(line, anchor, canonical);
                }
            }
        }
    } else if (feature.type === 'Polygon') {
        for (const polygon of classifyRings$1(feature.geometry, 0)) {
            // 16 here represents 2 pixels
            const poi = findPoleOfInaccessibility(polygon, 16);
            addSymbolAtAnchor(polygon[0], new Anchor(poi.x, poi.y, 0, 0, undefined), canonical);
        }
    } else if (feature.type === 'LineString') {
        // https://github.com/mapbox/mapbox-gl-js/issues/3808
        for (const line of feature.geometry) {
            addSymbolAtAnchor(line, new Anchor(line[0].x, line[0].y, 0, 0, undefined), canonical);
        }
    } else if (feature.type === 'Point') {
        for (const points of feature.geometry) {
            for (const point of points) {
                addSymbolAtAnchor([point], new Anchor(point.x, point.y, 0, 0, undefined), canonical);
            }
        }
    }
}

const MAX_GLYPH_ICON_SIZE = 255;
const MAX_PACKED_SIZE = MAX_GLYPH_ICON_SIZE * SIZE_PACK_FACTOR;

function addTextVertices(bucket              ,
                         globe                               ,
                         tileAnchor        ,
                         shapedText         ,
                         imageMap                           ,
                         layer                  ,
                         textAlongLine         ,
                         feature               ,
                         textOffset                  ,
                         lineArray                                              ,
                         writingMode        ,
                         placementTypes                                                 ,
                         placedTextSymbolIndices                       ,
                         placedIconIndex        ,
                         sizes       ,
                         availableImages               ,
                         canonical                 ) {
    const glyphQuads = getGlyphQuads(tileAnchor, shapedText, textOffset,
                            layer, textAlongLine, feature, imageMap, bucket.allowVerticalPlacement);

    const sizeData = bucket.textSizeData;
    let textSizeData = null;

    if (sizeData.kind === 'source') {
        textSizeData = [
            SIZE_PACK_FACTOR * layer.layout.get('text-size').evaluate(feature, {}, canonical)
        ];
        if (textSizeData[0] > MAX_PACKED_SIZE) {
            warnOnce(`${bucket.layerIds[0]}: Value for "text-size" is >= ${MAX_GLYPH_ICON_SIZE}. Reduce your "text-size".`);
        }
    } else if (sizeData.kind === 'composite') {
        textSizeData = [
            SIZE_PACK_FACTOR * sizes.compositeTextSizes[0].evaluate(feature, {}, canonical),
            SIZE_PACK_FACTOR * sizes.compositeTextSizes[1].evaluate(feature, {}, canonical)
        ];
        if (textSizeData[0] > MAX_PACKED_SIZE || textSizeData[1] > MAX_PACKED_SIZE) {
            warnOnce(`${bucket.layerIds[0]}: Value for "text-size" is >= ${MAX_GLYPH_ICON_SIZE}. Reduce your "text-size".`);
        }
    }

    bucket.addSymbols(
        bucket.text,
        glyphQuads,
        textSizeData,
        textOffset,
        textAlongLine,
        feature,
        writingMode,
        globe,
        tileAnchor,
        lineArray.lineStartIndex,
        lineArray.lineLength,
        placedIconIndex,
        availableImages,
        canonical);

    // The placedSymbolArray is used at render time in drawTileSymbols
    // These indices allow access to the array at collision detection time
    for (const placementType of placementTypes) {
        placedTextSymbolIndices[placementType] = bucket.text.placedSymbolArray.length - 1;
    }

    return glyphQuads.length * 4;
}

function getDefaultHorizontalShaping(horizontalShaping                             )                 {
    // We don't care which shaping we get because this is used for collision purposes
    // and all the justifications have the same collision box
    for (const justification      in horizontalShaping) {
        return horizontalShaping[justification];
    }
    return null;
}

function evaluateBoxCollisionFeature(collisionBoxArray                   ,
                                     projectedAnchor        ,
                                     tileAnchor        ,
                                     featureIndex        ,
                                     sourceLayerIndex        ,
                                     bucketIndex        ,
                                     shaped        ,
                                     padding        ,
                                     rotate        ,
                                     textOffset                   )         {
    let y1 = shaped.top;
    let y2 = shaped.bottom;
    let x1 = shaped.left;
    let x2 = shaped.right;

    const collisionPadding = shaped.collisionPadding;
    if (collisionPadding) {
        x1 -= collisionPadding[0];
        y1 -= collisionPadding[1];
        x2 += collisionPadding[2];
        y2 += collisionPadding[3];
    }

    if (rotate) {
        // Account for *-rotate in point collision boxes
        // See https://github.com/mapbox/mapbox-gl-js/issues/6075
        // Doesn't account for icon-text-fit

        const tl = new Point$2(x1, y1);
        const tr = new Point$2(x2, y1);
        const bl = new Point$2(x1, y2);
        const br = new Point$2(x2, y2);

        const rotateRadians = degToRad(rotate);
        let rotateCenter = new Point$2(0, 0);

        if (textOffset) {
            rotateCenter = new Point$2(textOffset[0], textOffset[1]);
        }

        tl._rotateAround(rotateRadians, rotateCenter);
        tr._rotateAround(rotateRadians, rotateCenter);
        bl._rotateAround(rotateRadians, rotateCenter);
        br._rotateAround(rotateRadians, rotateCenter);

        // Collision features require an "on-axis" geometry,
        // so take the envelope of the rotated geometry
        // (may be quite large for wide labels rotated 45 degrees)
        x1 = Math.min(tl.x, tr.x, bl.x, br.x);
        x2 = Math.max(tl.x, tr.x, bl.x, br.x);
        y1 = Math.min(tl.y, tr.y, bl.y, br.y);
        y2 = Math.max(tl.y, tr.y, bl.y, br.y);
    }

    collisionBoxArray.emplaceBack(projectedAnchor.x, projectedAnchor.y, projectedAnchor.z, tileAnchor.x, tileAnchor.y, x1, y1, x2, y2, padding, featureIndex, sourceLayerIndex, bucketIndex);

    return collisionBoxArray.length - 1;
}

function evaluateCircleCollisionFeature(shaped        )                {
    if (shaped.collisionPadding) {
        // Compute height of the shape in glyph metrics and apply padding.
        // Note that the pixel based 'text-padding' is applied at runtime
        shaped.top -= shaped.collisionPadding[1];
        shaped.bottom += shaped.collisionPadding[3];
    }

    // Set minimum box height to avoid very many small labels
    const height = shaped.bottom - shaped.top;
    return height > 0 ? Math.max(10, height) : null;
}

/**
 * Add a single label & icon placement.
 *
 * @private
 */
function addSymbol(bucket              ,
                   anchor        ,
                   globe                               ,
                   line              ,
                   shapedTextOrientations     ,
                   shapedIcon                       ,
                   imageMap                           ,
                   verticallyShapedIcon                       ,
                   layer                  ,
                   collisionBoxArray                   ,
                   featureIndex        ,
                   sourceLayerIndex        ,
                   bucketIndex        ,
                   textPadding        ,
                   textAlongLine         ,
                   textOffset                  ,
                   iconBoxScale        ,
                   iconPadding        ,
                   iconAlongLine         ,
                   iconOffset                  ,
                   feature               ,
                   sizes       ,
                   isSDFIcon         ,
                   availableImages               ,
                   canonical                 ) {
    const lineArray = bucket.addToLineVertexArray(anchor, line);
    let textBoxIndex, iconBoxIndex, verticalTextBoxIndex, verticalIconBoxIndex;
    let textCircle, verticalTextCircle, verticalIconCircle;

    let numIconVertices = 0;
    let numVerticalIconVertices = 0;
    let numHorizontalGlyphVertices = 0;
    let numVerticalGlyphVertices = 0;
    let placedIconSymbolIndex = -1;
    let verticalPlacedIconSymbolIndex = -1;
    const placedTextSymbolIndices = {};
    let key = murmur3$1('');
    const collisionFeatureAnchor         = globe ? globe.anchor : anchor;

    let textOffset0 = 0;
    let textOffset1 = 0;
    if (layer._unevaluatedLayout.getValue('text-radial-offset') === undefined) {
        [textOffset0, textOffset1] = (layer.layout.get('text-offset').evaluate(feature, {}, canonical).map(t => t * ONE_EM)     );
    } else {
        textOffset0 = layer.layout.get('text-radial-offset').evaluate(feature, {}, canonical) * ONE_EM;
        textOffset1 = INVALID_TEXT_OFFSET;
    }

    if (bucket.allowVerticalPlacement && shapedTextOrientations.vertical) {
        const verticalShaping = shapedTextOrientations.vertical;
        if (textAlongLine) {
            verticalTextCircle = evaluateCircleCollisionFeature(verticalShaping);
            if (verticallyShapedIcon) {
                verticalIconCircle = evaluateCircleCollisionFeature(verticallyShapedIcon);
            }
        } else {
            const textRotation = layer.layout.get('text-rotate').evaluate(feature, {}, canonical);
            const verticalTextRotation = textRotation + 90.0;
            verticalTextBoxIndex = evaluateBoxCollisionFeature(collisionBoxArray, collisionFeatureAnchor, anchor, featureIndex, sourceLayerIndex, bucketIndex, verticalShaping, textPadding, verticalTextRotation, textOffset);
            if (verticallyShapedIcon) {
                verticalIconBoxIndex = evaluateBoxCollisionFeature(collisionBoxArray, collisionFeatureAnchor, anchor, featureIndex, sourceLayerIndex, bucketIndex, verticallyShapedIcon, iconPadding, verticalTextRotation);
            }
        }
    }

    // Place icon first, so text can have a reference to its index in the placed symbol array.
    // Text symbols can lazily shift at render-time because of variable anchor placement.
    // If the style specifies an `icon-text-fit` then the icon would have to shift along with it.
    // For more info check `updateVariableAnchors` in `draw_symbol.js` .

    if (shapedIcon) {
        const iconRotate = layer.layout.get('icon-rotate').evaluate(feature, {}, canonical);
        const hasIconTextFit = layer.layout.get('icon-text-fit') !== 'none';
        const iconQuads = getIconQuads(shapedIcon, iconRotate, isSDFIcon, hasIconTextFit);
        const verticalIconQuads = verticallyShapedIcon ? getIconQuads(verticallyShapedIcon, iconRotate, isSDFIcon, hasIconTextFit) : undefined;
        iconBoxIndex = evaluateBoxCollisionFeature(collisionBoxArray, collisionFeatureAnchor, anchor, featureIndex, sourceLayerIndex, bucketIndex, shapedIcon, iconPadding, iconRotate);
        numIconVertices = iconQuads.length * 4;

        const sizeData = bucket.iconSizeData;
        let iconSizeData = null;

        if (sizeData.kind === 'source') {
            iconSizeData = [
                SIZE_PACK_FACTOR * layer.layout.get('icon-size').evaluate(feature, {}, canonical)
            ];
            if (iconSizeData[0] > MAX_PACKED_SIZE) {
                warnOnce(`${bucket.layerIds[0]}: Value for "icon-size" is >= ${MAX_GLYPH_ICON_SIZE}. Reduce your "icon-size".`);
            }
        } else if (sizeData.kind === 'composite') {
            iconSizeData = [
                SIZE_PACK_FACTOR * sizes.compositeIconSizes[0].evaluate(feature, {}, canonical),
                SIZE_PACK_FACTOR * sizes.compositeIconSizes[1].evaluate(feature, {}, canonical)
            ];
            if (iconSizeData[0] > MAX_PACKED_SIZE || iconSizeData[1] > MAX_PACKED_SIZE) {
                warnOnce(`${bucket.layerIds[0]}: Value for "icon-size" is >= ${MAX_GLYPH_ICON_SIZE}. Reduce your "icon-size".`);
            }
        }

        bucket.addSymbols(
            bucket.icon,
            iconQuads,
            iconSizeData,
            iconOffset,
            iconAlongLine,
            feature,
            false,
            globe,
            anchor,
            lineArray.lineStartIndex,
            lineArray.lineLength,
            // The icon itself does not have an associated symbol since the text isnt placed yet
            -1,
            availableImages,
            canonical);

        placedIconSymbolIndex = bucket.icon.placedSymbolArray.length - 1;

        if (verticalIconQuads) {
            numVerticalIconVertices = verticalIconQuads.length * 4;

            bucket.addSymbols(
                bucket.icon,
                verticalIconQuads,
                iconSizeData,
                iconOffset,
                iconAlongLine,
                feature,
                WritingMode.vertical,
                globe,
                anchor,
                lineArray.lineStartIndex,
                lineArray.lineLength,
                // The icon itself does not have an associated symbol since the text isnt placed yet
                -1,
                availableImages,
                canonical);

            verticalPlacedIconSymbolIndex = bucket.icon.placedSymbolArray.length - 1;
        }
    }

    for (const justification      in shapedTextOrientations.horizontal) {
        const shaping = shapedTextOrientations.horizontal[justification];

        if (!textBoxIndex) {
            key = murmur3$1(shaping.text);
            // As a collision approximation, we can use either the vertical or any of the horizontal versions of the feature
            // We're counting on all versions having similar dimensions
            if (textAlongLine) {
                textCircle = evaluateCircleCollisionFeature(shaping);
            } else {
                const textRotate = layer.layout.get('text-rotate').evaluate(feature, {}, canonical);
                textBoxIndex = evaluateBoxCollisionFeature(collisionBoxArray, collisionFeatureAnchor, anchor, featureIndex, sourceLayerIndex, bucketIndex, shaping, textPadding, textRotate, textOffset);
            }
        }

        const singleLine = shaping.positionedLines.length === 1;
        numHorizontalGlyphVertices += addTextVertices(
            bucket, globe, anchor, shaping, imageMap, layer, textAlongLine, feature, textOffset, lineArray,
            shapedTextOrientations.vertical ? WritingMode.horizontal : WritingMode.horizontalOnly,
            singleLine ? (Object.keys(shapedTextOrientations.horizontal)     ) : [justification],
            placedTextSymbolIndices, placedIconSymbolIndex, sizes, availableImages, canonical);

        if (singleLine) {
            break;
        }
    }

    if (shapedTextOrientations.vertical) {
        numVerticalGlyphVertices += addTextVertices(
            bucket, globe, anchor, shapedTextOrientations.vertical, imageMap, layer, textAlongLine, feature,
            textOffset, lineArray, WritingMode.vertical, ['vertical'], placedTextSymbolIndices, verticalPlacedIconSymbolIndex, sizes, availableImages, canonical);
    }

    // Check if runtime collision circles should be used for any of the collision features.
    // It is enough to choose the tallest feature shape as circles are always placed on a line.
    // All measurements are in glyph metrics and later converted into pixels using proper font size "layoutTextSize"
    let collisionCircleDiameter = -1;

    const getCollisionCircleHeight = (diameter         , prevHeight        )         => {
        return diameter ? Math.max(diameter, prevHeight) : prevHeight;
    };

    collisionCircleDiameter = getCollisionCircleHeight(textCircle, collisionCircleDiameter);
    collisionCircleDiameter = getCollisionCircleHeight(verticalTextCircle, collisionCircleDiameter);
    collisionCircleDiameter = getCollisionCircleHeight(verticalIconCircle, collisionCircleDiameter);
    const useRuntimeCollisionCircles = (collisionCircleDiameter > -1) ? 1 : 0;

    if (bucket.glyphOffsetArray.length >= SymbolBucket$1.MAX_GLYPHS) warnOnce(
        "Too many glyphs being rendered in a tile. See https://github.com/mapbox/mapbox-gl-js/issues/2907"
    );

    if (feature.sortKey !== undefined) {
        bucket.addToSortKeyRanges(bucket.symbolInstances.length, feature.sortKey);
    }

    const projectedAnchor = collisionFeatureAnchor;

    bucket.symbolInstances.emplaceBack(
        projectedAnchor.x,
        projectedAnchor.y,
        projectedAnchor.z,
        anchor.x,
        anchor.y,
        placedTextSymbolIndices.right >= 0 ? placedTextSymbolIndices.right : -1,
        placedTextSymbolIndices.center >= 0 ? placedTextSymbolIndices.center : -1,
        placedTextSymbolIndices.left >= 0 ? placedTextSymbolIndices.left : -1,
        placedTextSymbolIndices.vertical  >= 0 ? placedTextSymbolIndices.vertical : -1,
        placedIconSymbolIndex,
        verticalPlacedIconSymbolIndex,
        key,
        textBoxIndex !== undefined ? textBoxIndex : bucket.collisionBoxArray.length,
        textBoxIndex !== undefined ? textBoxIndex + 1 : bucket.collisionBoxArray.length,
        verticalTextBoxIndex !== undefined ? verticalTextBoxIndex : bucket.collisionBoxArray.length,
        verticalTextBoxIndex !== undefined ? verticalTextBoxIndex + 1 : bucket.collisionBoxArray.length,
        iconBoxIndex !== undefined ? iconBoxIndex : bucket.collisionBoxArray.length,
        iconBoxIndex !== undefined ? iconBoxIndex + 1 : bucket.collisionBoxArray.length,
        verticalIconBoxIndex ? verticalIconBoxIndex : bucket.collisionBoxArray.length,
        verticalIconBoxIndex ? verticalIconBoxIndex + 1 : bucket.collisionBoxArray.length,
        featureIndex,
        numHorizontalGlyphVertices,
        numVerticalGlyphVertices,
        numIconVertices,
        numVerticalIconVertices,
        useRuntimeCollisionCircles,
        0,
        textOffset0,
        textOffset1,
        collisionCircleDiameter);
}

function anchorIsTooClose(bucket     , text        , repeatDistance        , anchor       ) {
    const compareText = bucket.compareText;
    if (!(text in compareText)) {
        compareText[text] = [];
    } else {
        const otherAnchors = compareText[text];
        for (let k = otherAnchors.length - 1; k >= 0; k--) {
            if (anchor.dist(otherAnchors[k]) < repeatDistance) {
                // If it's within repeatDistance of one anchor, stop looking
                return true;
            }
        }
    }
    // If anchor is not within repeatDistance of any other anchor, add to array
    compareText[text].push(anchor);
    return false;
}

//      
                                             

function farthestPixelDistanceOnPlane(tr           , pixelsPerMeter        )         {
    // Find the distance from the center point [width/2 + offset.x, height/2 + offset.y] to the
    // center top point [width/2 + offset.x, 0] in Z units, using the law of sines.
    // 1 Z unit is equivalent to 1 horizontal px at the center of the map
    // (the distance between[width/2, height/2] and [width/2 + 1, height/2])
    const fovAboveCenter = tr.fovAboveCenter;

    // Adjust distance to MSL by the minimum possible elevation visible on screen,
    // this way the far plane is pushed further in the case of negative elevation.
    const minElevationInPixels = tr.elevation ?
        tr.elevation.getMinElevationBelowMSL() * pixelsPerMeter :
        0;
    const cameraToSeaLevelDistance = ((tr._camera.position[2] * tr.worldSize) - minElevationInPixels) / Math.cos(tr._pitch);
    const topHalfSurfaceDistance = Math.sin(fovAboveCenter) * cameraToSeaLevelDistance / Math.sin(Math.max(Math.PI / 2.0 - tr._pitch - fovAboveCenter, 0.01));

    // Calculate z distance of the farthest fragment that should be rendered.
    const furthestDistance = Math.sin(tr._pitch) * topHalfSurfaceDistance + cameraToSeaLevelDistance;
    const horizonDistance = cameraToSeaLevelDistance * (1 / tr._horizonShift);

    // Add a bit extra to avoid precision problems when a fragment's distance is exactly `furthestDistance`
    return Math.min(furthestDistance * 1.01, horizonDistance);
}

function farthestPixelDistanceOnSphere(tr           , pixelsPerMeter        )         {
    // Find farthest distance of the globe that is potentially visible to the camera.
    // First check if the view frustum is fully covered by the map by casting a ray
    // from the top left/right corner and see if it intersects with the globe. In case
    // of no intersection we need to find distance to the horizon point where the
    // surface normal is perpendicular to the camera forward direction.
    const cameraDistance = tr.cameraToCenterDistance;
    const centerPixelAltitude = tr._centerAltitude * pixelsPerMeter;

    const camera = tr._camera;
    const forward = tr._camera.forward();
    const cameraPosition = add$4([], scale$4([], forward, -cameraDistance), [0, 0, centerPixelAltitude]);

    const globeRadius = tr.worldSize / (2.0 * Math.PI);
    const globeCenter = [0, 0, -globeRadius];

    const aspectRatio = tr.width / tr.height;
    const tanFovAboveCenter = Math.tan(tr.fovAboveCenter);

    const up = scale$4([], camera.up(), tanFovAboveCenter);
    const right = scale$4([], camera.right(), tanFovAboveCenter * aspectRatio);
    const dir = normalize$4([], add$4([], add$4([], forward, up), right));

    const pointOnGlobe = [];
    const ray = new Ray(cameraPosition, dir);

    let pixelDistance;
    if (ray.closestPointOnSphere(globeCenter, globeRadius, pointOnGlobe)) {
        const p0 = add$4([], pointOnGlobe, globeCenter);
        const p1 = sub$2([], p0, cameraPosition);
        // Globe is fully covering the view frustum. Project the intersection
        // point to the camera view vector in order to find the pixel distance
        pixelDistance = Math.cos(tr.fovAboveCenter) * length$4(p1);
    } else {
        // Background space is visible. Find distance to the point of the
        // globe where surface normal is parallel to the view vector
        const globeCenterToCamera = sub$2([], cameraPosition, globeCenter);
        const cameraToGlobe = sub$2([], globeCenter, cameraPosition);
        normalize$4(cameraToGlobe, cameraToGlobe);

        const cameraHeight = length$4(globeCenterToCamera) - globeRadius;
        pixelDistance = Math.sqrt(cameraHeight * (cameraHeight + 2 * globeRadius));
        const angle = Math.acos(pixelDistance / (globeRadius + cameraHeight)) - Math.acos(dot$5(forward, cameraToGlobe));
        pixelDistance *= Math.cos(angle);
    }

    return pixelDistance * 1.01;
}

//      

                                    
                                                                
                                             

                             
                  
              
              
               
               
                          
  

function tileTransform(id        , projection            )                {
    if (!projection.isReprojectedInTileSpace) {
        return {scale: 1 << id.z, x: id.x, y: id.y, x2: id.x + 1, y2: id.y + 1, projection};
    }

    const s = Math.pow(2, -id.z);

    const x1 = (id.x) * s;
    const x2 = (id.x + 1) * s;
    const y1 = (id.y) * s;
    const y2 = (id.y + 1) * s;

    const lng1 = lngFromMercatorX(x1);
    const lng2 = lngFromMercatorX(x2);
    const lat1 = latFromMercatorY(y1);
    const lat2 = latFromMercatorY(y2);

    const p0 = projection.project(lng1, lat1);
    const p1 = projection.project(lng2, lat1);
    const p2 = projection.project(lng2, lat2);
    const p3 = projection.project(lng1, lat2);

    let minX = Math.min(p0.x, p1.x, p2.x, p3.x);
    let minY = Math.min(p0.y, p1.y, p2.y, p3.y);
    let maxX = Math.max(p0.x, p1.x, p2.x, p3.x);
    let maxY = Math.max(p0.y, p1.y, p2.y, p3.y);

    // we pick an error threshold for calculating the bbox that balances between performance and precision
    const maxErr = s / 16;

    function processSegment(pa                , pb                , ax        , ay        , bx        , by        ) {
        const mx = (ax + bx) / 2;
        const my = (ay + by) / 2;

        const pm = projection.project(lngFromMercatorX(mx), latFromMercatorY(my));
        const err = Math.max(0, minX - pm.x, minY - pm.y, pm.x - maxX, pm.y - maxY);

        minX = Math.min(minX, pm.x);
        maxX = Math.max(maxX, pm.x);
        minY = Math.min(minY, pm.y);
        maxY = Math.max(maxY, pm.y);

        if (err > maxErr) {
            processSegment(pa, pm, ax, ay, mx, my);
            processSegment(pm, pb, mx, my, bx, by);
        }
    }

    processSegment(p0, p1, x1, y1, x2, y1);
    processSegment(p1, p2, x2, y1, x2, y2);
    processSegment(p2, p3, x2, y2, x1, y2);
    processSegment(p3, p0, x1, y2, x1, y1);

    // extend the bbox by max error to make sure coords don't go past tile extent
    minX -= maxErr;
    minY -= maxErr;
    maxX += maxErr;
    maxY += maxErr;

    const max = Math.max(maxX - minX, maxY - minY);
    const scale = 1 / max;

    return {
        scale,
        x: minX * scale,
        y: minY * scale,
        x2: maxX * scale,
        y2: maxY * scale,
        projection
    };
}

function tileAABB(tr           , numTiles        , z        , x        , y        , wrap        , min        , max        , projection            )       {
    if (projection.name === 'globe') {
        const tileId = new CanonicalTileID(z, x, y);
        return aabbForTileOnGlobe(tr, numTiles, tileId);
    }

    const tt = tileTransform({z, x, y}, projection);
    const tx = tt.x / tt.scale;
    const ty = tt.y / tt.scale;
    const tx2 = tt.x2 / tt.scale;
    const ty2 = tt.y2 / tt.scale;

    if (isNaN(tx) || isNaN(tx2) || isNaN(ty) || isNaN(ty2)) {
        assert$1(false);
    }

    return new Aabb(
        [(wrap + tx) * numTiles, numTiles * ty, min],
        [(wrap  + tx2) * numTiles, numTiles * ty2, max]);
}

function getTilePoint(tileTransform               , {x, y}                                    , wrap         = 0)        {
    return new Point$2(
        ((x - wrap) * tileTransform.scale - tileTransform.x) * EXTENT,
        (y * tileTransform.scale - tileTransform.y) * EXTENT);
}

function getTileVec3(tileTransform               , coord                    , wrap         = 0)       {
    const x = ((coord.x - wrap) * tileTransform.scale - tileTransform.x) * EXTENT;
    const y = (coord.y * tileTransform.scale - tileTransform.y) * EXTENT;
    return fromValues$4(x, y, altitudeFromMercatorZ(coord.z, coord.y));
}

//      

                                                    
                                    
                                                                
                                                                       
                                                                              

                              
              
              
              
  

                              
                                                                                        
                                                                         
                        
 

const identity = identity$3(new Float32Array(16));

class Projection {
                 
                  
                   
                             
                                 
                             
                         
                                
                                   
                                      
                             
                             
                                 
                                     
                                  

    constructor(options                         ) {
        this.spec = options;
        this.name = options.name;
        this.wrap = false;
        this.requiresDraping = false;
        this.supportsWorldCopies = false;
        this.supportsTerrain = false;
        this.supportsFog = false;
        this.supportsFreeCamera = false;
        this.zAxisUnit = 'meters';
        this.isReprojectedInTileSpace = true;
        this.unsupportedLayers = ['custom'];
        this.center = [0, 0];
        this.range = [3.5, 7];
    }

    project(lng        , lat        )                 { // eslint-disable-line
        return {x: 0, y: 0, z: 0}; // overriden in subclasses
    }

    unproject(x        , y        )         { // eslint-disable-line
        return new LngLat$1(0, 0); // overriden in subclasses
    }

    projectTilePoint(x        , y        , _                 )                 {
        return {x, y, z: 0};
    }

    locationPoint(tr           , lngLat        , terrain          = true)        {
        return tr._coordinatePoint(tr.locationCoordinate(lngLat), terrain);
    }

    pixelsPerMeter(lat        , worldSize        )         {
        return mercatorZfromAltitude(1, lat) * worldSize;
    }

    // pixels-per-meter is used to describe relation between real world and pixel distances.
    // `pixelSpaceConversion` can be used to convert the ratio from mercator projection to
    // the currently active projection.
    //
    // `pixelSpaceConversion` is useful for converting between pixel spaces where some logic
    // expects mercator pixels, such as raycasting where the scale is expected to be in
    // mercator pixels.
    pixelSpaceConversion(lat        , worldSize        , interpolationT        )         { // eslint-disable-line
        return 1.0;
    }

    farthestPixelDistance(tr           )         {
        return farthestPixelDistanceOnPlane(tr, tr.pixelsPerMeter);
    }

    pointCoordinate(tr           , x        , y        , z        )                     {
        const horizonOffset = tr.horizonLineFromTop(false);
        const clamped = new Point$2(x, Math.max(horizonOffset, y));
        return tr.rayIntersectionCoordinate(tr.pointRayIntersection(clamped, z));
    }

    pointCoordinate3D(tr           , x        , y        )        {
        const p = new Point$2(x, y);
        if (tr.elevation) {
            return tr.elevation.pointCoordinate(p);
        } else {
            const mc = this.pointCoordinate(tr, p.x, p.y, 0);
            return [mc.x, mc.y, mc.z];
        }
    }

    isPointAboveHorizon(tr           , p       )          {
        if (tr.elevation) {
            const raycastOnTerrain = this.pointCoordinate3D(tr, p.x, p.y);
            return !raycastOnTerrain;
        }
        const horizon = tr.horizonLineFromTop();
        return p.y < horizon;
    }

    createInversionMatrix(tr           , id                 )               { // eslint-disable-line
        return identity;
    }

    createTileMatrix(tr           , worldSize        , id                 )               {
        let scale, scaledX, scaledY;
        const canonical = id.canonical;
        const posMatrix = identity$3(new Float64Array(16));

        if (this.isReprojectedInTileSpace) {
            const cs = tileTransform(canonical, this);
            scale = 1;
            scaledX = cs.x + id.wrap * cs.scale;
            scaledY = cs.y;
            scale$5(posMatrix, posMatrix, [scale / cs.scale, scale / cs.scale, tr.pixelsPerMeter / worldSize]);
        } else {
            scale = worldSize / tr.zoomScale(canonical.z);
            const unwrappedX = canonical.x + Math.pow(2, canonical.z) * id.wrap;
            scaledX = unwrappedX * scale;
            scaledY = canonical.y * scale;
        }

        translate$2(posMatrix, posMatrix, [scaledX, scaledY, 0]);
        scale$5(posMatrix, posMatrix, [scale / EXTENT, scale / EXTENT, 1]);

        return posMatrix;
    }

    upVector(id                 , x        , y        )       { // eslint-disable-line
        return [0, 0, 1];
    }

    upVectorScale(id                 , latitude        , worldSize        )                 { // eslint-disable-line
        return {metersToTile: 1};
    }
}

//      

                                                                       
                                                    

// based on https://github.com/d3/d3-geo-projection, MIT-licensed
class Albers extends Projection {
              
              
               

    constructor(options                         ) {
        super(options);
        this.range = [4, 7];
        this.center = options.center || [-96, 37.5];
        const [lat0, lat1] = this.parallels = options.parallels || [29.5, 45.5];

        const sy0 = Math.sin(degToRad(lat0));
        this.n = (sy0 + Math.sin(degToRad(lat1))) / 2;
        this.c = 1 + sy0 * (2 * this.n - sy0);
        this.r0 = Math.sqrt(this.c) / this.n;
    }

    project(lng        , lat        )                 {
        const {n, c, r0} = this;
        const lambda = degToRad(lng - this.center[0]);
        const phi = degToRad(lat);

        const r = Math.sqrt(c - 2 * n * Math.sin(phi)) / n;
        const x = r * Math.sin(lambda * n);
        const y = r * Math.cos(lambda * n) - r0;
        return {x, y, z: 0};
    }

    unproject(x        , y        )         {
        const {n, c, r0} = this;
        const r0y = r0 + y;
        let l = Math.atan2(x, Math.abs(r0y)) * Math.sign(r0y);
        if (r0y * n < 0) {
            l -= Math.PI * Math.sign(x) * Math.sign(r0y);
        }
        const dt = degToRad(this.center[0]) * n;
        l = wrap(l, -Math.PI - dt, Math.PI - dt);

        const lng = clamp(radToDeg(l / n) + this.center[0], -180, 180);
        const phi = Math.asin(clamp((c - (x * x + r0y * r0y) * n * n) / (2 * n), -1, 1));
        const lat = clamp(radToDeg(phi), -MAX_MERCATOR_LATITUDE, MAX_MERCATOR_LATITUDE);

        return new LngLat$1(lng, lat);
    }
}

//      

                                                    

const a1 = 1.340264;
const a2 = -0.081106;
const a3 = 0.000893;
const a4 = 0.003796;
const M = Math.sqrt(3) / 2;

class EqualEarth extends Projection {

    project(lng        , lat        )                 {
        // based on https://github.com/d3/d3-geo, MIT-licensed
        lat = lat / 180 * Math.PI;
        lng = lng / 180 * Math.PI;
        const theta = Math.asin(M * Math.sin(lat));
        const theta2 = theta * theta;
        const theta6 = theta2 * theta2 * theta2;
        const x = lng * Math.cos(theta) / (M * (a1 + 3 * a2 * theta2 + theta6 * (7 * a3 + 9 * a4 * theta2)));
        const y = theta * (a1 + a2 * theta2 + theta6 * (a3 + a4 * theta2));

        return {
            x: (x / Math.PI + 0.5) * 0.5,
            y: 1 - (y / Math.PI + 1) * 0.5,
            z: 0
        };
    }

    unproject(x        , y        )         {
        // based on https://github.com/d3/d3-geo, MIT-licensed
        x = (2 * x - 0.5) * Math.PI;
        y = (2 * (1 - y) - 1) * Math.PI;
        let theta = y;
        let theta2 = theta * theta;
        let theta6 = theta2 * theta2 * theta2;

        for (let i = 0, delta, fy, fpy; i < 12; ++i) {
            fy = theta * (a1 + a2 * theta2 + theta6 * (a3 + a4 * theta2)) - y;
            fpy = a1 + 3 * a2 * theta2 + theta6 * (7 * a3 + 9 * a4 * theta2);
            delta = fy / fpy;
            theta = clamp(theta - delta, -Math.PI / 3, Math.PI / 3);
            theta2 = theta * theta;
            theta6 = theta2 * theta2 * theta2;
            if (Math.abs(delta) < 1e-12) break;
        }

        const lambda = M * x * (a1 + 3 * a2 * theta2 + theta6 * (7 * a3 + 9 * a4 * theta2)) / Math.cos(theta);
        const phi = Math.asin(Math.sin(theta) / M);
        const lng = clamp(lambda * 180 / Math.PI, -180, 180);
        const lat = clamp(phi * 180 / Math.PI, -MAX_MERCATOR_LATITUDE, MAX_MERCATOR_LATITUDE);

        return new LngLat$1(lng, lat);
    }
}

//      

                                                                       
                                                    

class Equirectangular extends Projection {

    constructor(options                         ) {
        super(options);
        this.wrap = true;
        this.supportsWorldCopies = true;
    }

    project(lng        , lat        )                 {
        const x = 0.5 + lng / 360;
        const y = 0.5 - lat / 360;
        return {x, y, z: 0};
    }

    unproject(x        , y        )         {
        const lng = (x - 0.5) * 360;
        const lat = clamp((0.5 - y) * 360, -MAX_MERCATOR_LATITUDE, MAX_MERCATOR_LATITUDE);
        return new LngLat$1(lng, lat);
    }
}

//      

                                                                       
                                                    

const halfPi = Math.PI / 2;

function tany(y        ) {
    return Math.tan((halfPi + y) / 2);
}

// based on https://github.com/d3/d3-geo, MIT-licensed
class LambertConformalConic extends Projection {
              
              
                            

    constructor(options                         ) {
        super(options);
        this.center = options.center || [0, 30];
        const [lat0, lat1] = this.parallels = options.parallels || [30, 30];

        let y0 = degToRad(lat0);
        let y1 = degToRad(lat1);
        // Run projection math on inverted lattitudes if the paralell lines are south of the equator
        // This fixes divide by zero errors with a South polar projection
        this.southernCenter = (y0 + y1) < 0;
        if (this.southernCenter) {
            y0 = -y0;
            y1 = -y1;
        }
        const cy0 = Math.cos(y0);
        const tany0 = tany(y0);

        this.n = y0 === y1 ? Math.sin(y0) : Math.log(cy0 / Math.cos(y1)) / Math.log(tany(y1) / tany0);
        this.f = cy0 * Math.pow(tany(y0), this.n) / this.n;
    }

    project(lng        , lat        )                 {
        lat = degToRad(lat);
        if (this.southernCenter) lat = -lat;
        lng = degToRad(lng - this.center[0]);

        const epsilon = 1e-6;
        const {n, f} = this;

        if (f > 0) {
            if (lat < -halfPi + epsilon) lat = -halfPi + epsilon;
        } else {
            if (lat > halfPi - epsilon) lat = halfPi - epsilon;
        }

        const r = f / Math.pow(tany(lat), n);
        let x = r * Math.sin(n * lng);
        let y = f - r * Math.cos(n * lng);
        x = (x / Math.PI + 0.5) * 0.5;
        y = (y / Math.PI + 0.5) * 0.5;

        return {
            x,
            y: this.southernCenter ? y : 1 - y,
            z: 0
        };
    }

    unproject(x        , y        )         {
        x = (2 * x - 0.5) * Math.PI;
        if (this.southernCenter) y = 1 - y;
        y = (2 * (1 - y) - 0.5) * Math.PI;
        const {n, f} = this;
        const fy = f - y;
        const signFy = Math.sign(fy);
        const r = Math.sign(n) * Math.sqrt(x * x + fy * fy);
        let l = Math.atan2(x, Math.abs(fy)) * signFy;

        if (fy * n < 0) l -= Math.PI * Math.sign(x) * signFy;

        const lng = clamp(radToDeg(l / n) + this.center[0], -180, 180);
        const phi = 2 * Math.atan(Math.pow(f / r, 1 / n)) - halfPi;
        const lat = clamp(radToDeg(phi), -MAX_MERCATOR_LATITUDE, MAX_MERCATOR_LATITUDE);

        return new LngLat$1(lng, this.southernCenter ? -lat : lat);
    }
}

//      

                                                                       
                                                    

class Mercator extends Projection {

    constructor(options                         ) {
        super(options);
        this.wrap = true;
        this.supportsWorldCopies = true;
        this.supportsTerrain = true;
        this.supportsFog = true;
        this.supportsFreeCamera = true;
        this.isReprojectedInTileSpace = false;
        this.unsupportedLayers = [];
        this.range = null;
    }

    project(lng        , lat        )                 {
        const x = mercatorXfromLng(lng);
        const y = mercatorYfromLat(lat);
        return {x, y, z: 0};
    }

    unproject(x        , y        )         {
        const lng = lngFromMercatorX(x);
        const lat = latFromMercatorY(y);
        return new LngLat$1(lng, lat);
    }
}

//      

                                                    

const maxPhi$1 = degToRad(MAX_MERCATOR_LATITUDE);

class NaturalEarth extends Projection {

    project(lng        , lat        )                 {
        // based on https://github.com/d3/d3-geo, MIT-licensed
        lat = degToRad(lat);
        lng = degToRad(lng);

        const phi2 = lat * lat;
        const phi4 = phi2 * phi2;
        const x = lng * (0.8707 - 0.131979 * phi2 + phi4 * (-0.013791 + phi4 * (0.003971 * phi2 - 0.001529 * phi4)));
        const y = lat * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4)));

        return {
            x: (x / Math.PI + 0.5) * 0.5,
            y: 1 - (y / Math.PI + 1) * 0.5,
            z: 0
        };
    }

    unproject(x        , y        )         {
        // based on https://github.com/d3/d3-geo, MIT-licensed
        x = (2 * x - 0.5) * Math.PI;
        y = (2 * (1 - y) - 1) * Math.PI;
        const epsilon = 1e-6;
        let phi = y;
        let i = 25;
        let delta = 0;
        let phi2 = phi * phi;

        do {
            phi2 = phi * phi;
            const phi4 = phi2 * phi2;
            delta = (phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4))) - y) /
                (1.007226 + phi2 * (0.015085 * 3 + phi4 * (-0.044475 * 7 + 0.028874 * 9 * phi2 - 0.005916 * 11 * phi4)));
            phi = clamp(phi - delta, -maxPhi$1, maxPhi$1);
        } while (Math.abs(delta) > epsilon && --i > 0);

        phi2 = phi * phi;
        const lambda = x / (0.8707 + phi2 * (-0.131979 + phi2 * (-0.013791 + phi2 * phi2 * phi2 * (0.003971 - 0.001529 * phi2))));

        const lng = clamp(radToDeg(lambda), -180, 180);
        const lat = radToDeg(phi);

        return new LngLat$1(lng, lat);
    }
}

//      

                                                    

const maxPhi = degToRad(MAX_MERCATOR_LATITUDE);

class WinkelTripel extends Projection {

    project(lng        , lat        )                 {
        lat = degToRad(lat);
        lng = degToRad(lng);
        const cosLat = Math.cos(lat);
        const twoOverPi = 2 / Math.PI;
        const alpha = Math.acos(cosLat * Math.cos(lng / 2));
        const sinAlphaOverAlpha = Math.sin(alpha) / alpha;
        const x = 0.5 * (lng * twoOverPi + (2 * cosLat * Math.sin(lng / 2)) / sinAlphaOverAlpha) || 0;
        const y = 0.5 * (lat + Math.sin(lat) / sinAlphaOverAlpha) || 0;
        return {
            x: (x / Math.PI + 0.5) * 0.5,
            y: 1 - (y / Math.PI + 1) * 0.5,
            z: 0
        };
    }

    unproject(x        , y        )         {
        // based on https://github.com/d3/d3-geo-projection, MIT-licensed
        x = (2 * x - 0.5) * Math.PI;
        y = (2 * (1 - y) - 1) * Math.PI;
        let lambda = x;
        let phi = y;
        let i = 25;
        const epsilon = 1e-6;
        let dlambda = 0, dphi = 0;
        do {
            const cosphi = Math.cos(phi),
                sinphi = Math.sin(phi),
                sinphi2 = 2 * sinphi * cosphi,
                sin2phi = sinphi * sinphi,
                cos2phi = cosphi * cosphi,
                coslambda2 = Math.cos(lambda / 2),
                sinlambda2 = Math.sin(lambda / 2),
                sinlambda = 2 * coslambda2 * sinlambda2,
                sin2lambda2 = sinlambda2 * sinlambda2,
                C = 1 - cos2phi * coslambda2 * coslambda2,
                F = C ? 1 / C : 0,
                E = C ? Math.acos(cosphi * coslambda2) * Math.sqrt(1 / C) : 0,
                fx = 0.5 * (2 * E * cosphi * sinlambda2 + lambda * 2 / Math.PI) - x,
                fy = 0.5 * (E * sinphi + phi) - y,
                dxdlambda = 0.5 * F * (cos2phi * sin2lambda2 + E * cosphi * coslambda2 * sin2phi) + 1 / Math.PI,
                dxdphi = F * (sinlambda * sinphi2 / 4 - E * sinphi * sinlambda2),
                dydlambda = 0.125 * F * (sinphi2 * sinlambda2 - E * sinphi * cos2phi * sinlambda),
                dydphi = 0.5 * F * (sin2phi * coslambda2 + E * sin2lambda2 * cosphi) + 0.5,
                denominator = dxdphi * dydlambda - dydphi * dxdlambda;

            dlambda = (fy * dxdphi - fx * dydphi) / denominator;
            dphi = (fx * dydlambda - fy * dxdlambda) / denominator;
            lambda = clamp(lambda - dlambda, -Math.PI, Math.PI);
            phi = clamp(phi - dphi, -maxPhi, maxPhi);

        } while ((Math.abs(dlambda) > epsilon || Math.abs(dphi) > epsilon) && --i > 0);

        return new LngLat$1(radToDeg(lambda), radToDeg(phi));
    }
}

//      

                                                                       
                                                    

class CylindricalEqualArea extends Projection {
                   
                  

    constructor(options                         ) {
        super(options);
        this.center = options.center || [0, 0];
        this.parallels = options.parallels || [0, 0];
        this.cosPhi = Math.max(0.01, Math.cos(degToRad(this.parallels[0])));
        // scale coordinates between 0 and 1 to avoid constraint issues
        this.scale = 1 / (2 * Math.max(Math.PI * this.cosPhi, 1 / this.cosPhi));
        this.wrap = true;
        this.supportsWorldCopies = true;
    }

    project(lng        , lat        )                 {
        const {scale, cosPhi} = this;
        const x = degToRad(lng) * cosPhi;
        const y = Math.sin(degToRad(lat)) / cosPhi;

        return {
            x: (x * scale) + 0.5,
            y: (-y * scale) + 0.5,
            z: 0
        };
    }

    unproject(x        , y        )         {
        const {scale, cosPhi} = this;
        const x_ = (x - 0.5) / scale;
        const y_ = -(y - 0.5) / scale;
        const lng = clamp(radToDeg(x_) / cosPhi, -180, 180);
        const y2 = y_ * cosPhi;
        const y3 = Math.asin(clamp(y2, -1, 1));
        const lat = clamp(radToDeg(y3), -MAX_MERCATOR_LATITUDE, MAX_MERCATOR_LATITUDE);

        return new LngLat$1(lng, lat);
    }
}

//      

                                             
                                                    
                                    
                                                                       
                                                                              

class Globe extends Mercator {

    constructor(options                         ) {
        super(options);
        this.requiresDraping = true;
        this.supportsWorldCopies = false;
        this.supportsFog = true;
        this.zAxisUnit = "pixels";
        this.unsupportedLayers = ['debug'];
        this.range = [3, 5];
    }

    projectTilePoint(x        , y        , id                 )                                    {
        const pos = tileCoordToECEF(x, y, id);
        const bounds = globeTileBounds(id);
        const normalizationMatrix = globeNormalizeECEF(bounds);
        transformMat4$2(pos, pos, normalizationMatrix);

        return {x: pos[0], y: pos[1], z: pos[2]};
    }

    locationPoint(tr           , lngLat        )        {
        const pos = latLngToECEF(lngLat.lat, lngLat.lng);
        const up = normalize$4([], pos);

        const elevation = tr.elevation ?
            tr.elevation.getAtPointOrZero(tr.locationCoordinate(lngLat), tr._centerAltitude) :
            tr._centerAltitude;

        const upScale = mercatorZfromAltitude(1, 0) * EXTENT * elevation;
        scaleAndAdd$2(pos, pos, up, upScale);
        const matrix = identity$3(new Float64Array(16));
        multiply$5(matrix, tr.pixelMatrix, tr.globeMatrix);
        transformMat4$2(pos, pos, matrix);

        return new Point$2(pos[0], pos[1]);
    }

    pixelsPerMeter(lat        , worldSize        )         {
        return mercatorZfromAltitude(1, 0) * worldSize;
    }

    pixelSpaceConversion(lat        , worldSize        , interpolationT        )         {
        // Using only the center latitude to determine scale causes the globe to rapidly change
        // size as you pan up and down. As you approach the pole, the globe's size approaches infinity.
        // This is because zoom levels are based on mercator.
        //
        // Instead, use a fixed reference latitude at lower zoom levels. And transition between
        // this latitude and the center's latitude as you zoom in. This is a compromise that
        // makes globe view more usable with existing camera parameters, styles and data.
        const centerScale = mercatorZfromAltitude(1, lat) * worldSize;
        const referenceScale = mercatorZfromAltitude(1, GLOBE_SCALE_MATCH_LATITUDE) * worldSize;
        const combinedScale = number(referenceScale, centerScale, interpolationT);
        return this.pixelsPerMeter(lat, worldSize) / combinedScale;
    }

    createTileMatrix(tr           , worldSize        , id                 )               {
        const decode = globeDenormalizeECEF(globeTileBounds(id.canonical));
        return multiply$5(new Float64Array(16), tr.globeMatrix, decode);
    }

    createInversionMatrix(tr           , id                 )               {
        const {center} = tr;
        const matrix = globeNormalizeECEF(globeTileBounds(id));
        rotateY$3(matrix, matrix, degToRad(center.lng));
        rotateX$3(matrix, matrix, degToRad(center.lat));
        scale$5(matrix, matrix, [tr._pixelsPerMercatorPixel, tr._pixelsPerMercatorPixel, 1.0]);
        return Float32Array.from(matrix);
    }

    pointCoordinate(tr           , x        , y        , _        )                     {
        const coord = globePointCoordinate(tr, x, y, true);
        if (!coord) { return new MercatorCoordinate$1(0, 0); } // This won't happen, is here for Flow
        return coord;
    }

    pointCoordinate3D(tr           , x        , y        )        {
        const coord = this.pointCoordinate(tr, x, y, 0);
        return [coord.x, coord.y, coord.z];
    }

    isPointAboveHorizon(tr           , p       )          {
        const raycastOnGlobe = globePointCoordinate(tr, p.x, p.y, false);
        return !raycastOnGlobe;
    }

    farthestPixelDistance(tr           )         {
        const pixelsPerMeter = this.pixelsPerMeter(tr.center.lat, tr.worldSize);
        const globePixelDistance = farthestPixelDistanceOnSphere(tr, pixelsPerMeter);
        const t = globeToMercatorTransition(tr.zoom);
        if (t > 0.0) {
            const mercatorPixelsPerMeter = mercatorZfromAltitude(1, tr.center.lat) * tr.worldSize;
            const mercatorPixelDistance = farthestPixelDistanceOnPlane(tr, mercatorPixelsPerMeter);
            const pixelRadius = tr.worldSize / (2.0 * Math.PI);
            const approxTileArcHalfAngle = Math.max(tr.width, tr.height) / tr.worldSize * Math.PI;
            const padding = pixelRadius * (1.0 - Math.cos(approxTileArcHalfAngle));

            // During transition to mercator we would like to keep
            // the far plane lower to ensure that geometries (e.g. circles) that are far away and are not supposed
            // to be rendered get culled out correctly. see https://github.com/mapbox/mapbox-gl-js/issues/11476
            // To achieve this we dampen the interpolation.
            return number(globePixelDistance, mercatorPixelDistance + padding, Math.pow(t, 10.0));
        }
        return globePixelDistance;
    }

    upVector(id                 , x        , y        )       {
        return tileCoordToECEF(x, y, id, 1);
    }

    upVectorScale(id                 )                 {
        return {metersToTile: globeMetersToEcef(globeECEFNormalizationScale(globeTileBounds(id)))};
    }
}

//      

                                                                       
                                              

function getProjection(config                         )             {

    const parallels = config.parallels;
    const isDegenerateConic = parallels ? Math.abs(parallels[0] + parallels[1]) < 0.01 : false;

    switch (config.name) {
    case 'mercator':
        return new Mercator(config);
    case 'equirectangular':
        return new Equirectangular(config);
    case 'naturalEarth':
        return new NaturalEarth(config);
    case 'equalEarth':
        return new EqualEarth(config);
    case 'winkelTripel':
        return new WinkelTripel(config);
    case 'albers':
        return isDegenerateConic ? new CylindricalEqualArea(config) : new Albers(config);
    case 'lambertConformalConic':
        return isDegenerateConic ? new CylindricalEqualArea(config) : new LambertConformalConic(config);
    case 'globe':
        return new Globe(config);
    }

    throw new Error(`Invalid projection name: ${config.name}`);
}

//      

const vectorTileFeatureTypes = VectorTileFeature.types;
                                               
                                                        
                                                          
                                                      
                                                          
                                                                
                                                                          
                                  
               
               
               
               
                    
                             
                             
                             
                        
                        
                       
                              
  
                                          
                                                         
                                                          

                               
                                 
                                         
                                 
                                         
                              
                                      
                              
                                      
  

                              
                           
                           
                         
                  
                             
                                  
                       
                                             
            
   

                            
                    
                                
                             
  

                         
                       
                          
   

// Opacity arrays are frequently updated but don't contain a lot of information, so we pack them
// tight. Each Uint32 is actually four duplicate Uint8s for the four corners of a glyph
// 7 bits are for the current opacity, and the lowest bit is the target opacity

// actually defined in symbol_attributes.js
// const placementOpacityAttributes = [
//     { name: 'a_fade_opacity', components: 1, type: 'Uint32' }
// ];
const shaderOpacityAttributes = [
    {name: 'a_fade_opacity', components: 1, type: 'Uint8', offset: 0}
];

function addVertex(array                   , tileAnchorX        , tileAnchorY        , ox        , oy        , tx        , ty        , sizeVertex     , isSDF         , pixelOffsetX        , pixelOffsetY        , minFontScaleX        , minFontScaleY        ) {
    const aSizeX = sizeVertex ? Math.min(MAX_PACKED_SIZE, Math.round(sizeVertex[0])) : 0;
    const aSizeY = sizeVertex ? Math.min(MAX_PACKED_SIZE, Math.round(sizeVertex[1])) : 0;

    array.emplaceBack(
        // a_pos_offset
        tileAnchorX,
        tileAnchorY,
        Math.round(ox * 32),
        Math.round(oy * 32),

        // a_data
        tx, // x coordinate of symbol on glyph atlas texture
        ty, // y coordinate of symbol on glyph atlas texture
        (aSizeX << 1) + (isSDF ? 1 : 0),
        aSizeY,
        pixelOffsetX * 16,
        pixelOffsetY * 16,
        minFontScaleX * 256,
        minFontScaleY * 256
    );
}

function addGlobeVertex(array                     , projAnchorX        , projAnchorY        , projAnchorZ        , normX        , normY        , normZ        ) {
    array.emplaceBack(
        // a_globe_anchor
        projAnchorX,
        projAnchorY,
        projAnchorZ,

        // a_globe_normal
        normX,
        normY,
        normZ
    );
}

function updateGlobeVertexNormal(array                     , vertexIdx        , normX        , normY        , normZ        ) {
    // Modify float32 array directly. 20 bytes per entry, 3xInt16 for position, 3xfloat32 for normal
    const offset = vertexIdx * 5 + 2;
    array.float32[offset + 0] = normX;
    array.float32[offset + 1] = normY;
    array.float32[offset + 2] = normZ;
}

function addDynamicAttributes(dynamicLayoutVertexArray             , x        , y        , z        , angle        ) {
    dynamicLayoutVertexArray.emplaceBack(x, y, z, angle);
    dynamicLayoutVertexArray.emplaceBack(x, y, z, angle);
    dynamicLayoutVertexArray.emplaceBack(x, y, z, angle);
    dynamicLayoutVertexArray.emplaceBack(x, y, z, angle);
}

function containsRTLText(formattedText           )          {
    for (const section of formattedText.sections) {
        if (stringContainsRTLText(section.text)) {
            return true;
        }
    }
    return false;
}

class SymbolBuffers {
                                         
                                     

                                   
                             

                                                                     
                            

                                                       
                                            

                                           
                                      

                                             
                                       

                                         

    constructor(programConfigurations                                           ) {
        this.layoutVertexArray = new StructArrayLayout4i4ui4i24();
        this.indexArray = new StructArrayLayout3ui6();
        this.programConfigurations = programConfigurations;
        this.segments = new SegmentVector();
        this.dynamicLayoutVertexArray = new StructArrayLayout4f16();
        this.opacityVertexArray = new StructArrayLayout1ul4();
        this.placedSymbolArray = new PlacedSymbolArray();
        this.globeExtVertexArray = new StructArrayLayout3i3f20();
    }

    isEmpty()          {
        return this.layoutVertexArray.length === 0 &&
            this.indexArray.length === 0 &&
            this.dynamicLayoutVertexArray.length === 0 &&
            this.opacityVertexArray.length === 0;
    }

    upload(context         , dynamicIndexBuffer         , upload          , update          ) {
        if (this.isEmpty()) {
            return;
        }

        if (upload) {
            this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray, symbolLayoutAttributes.members);
            this.indexBuffer = context.createIndexBuffer(this.indexArray, dynamicIndexBuffer);
            this.dynamicLayoutVertexBuffer = context.createVertexBuffer(this.dynamicLayoutVertexArray, dynamicLayoutAttributes.members, true);
            this.opacityVertexBuffer = context.createVertexBuffer(this.opacityVertexArray, shaderOpacityAttributes, true);
            if (this.globeExtVertexArray.length > 0) {
                this.globeExtVertexBuffer = context.createVertexBuffer(this.globeExtVertexArray, symbolGlobeExtAttributes.members, true);
            }
            // This is a performance hack so that we can write to opacityVertexArray with uint32s
            // even though the shaders read uint8s
            this.opacityVertexBuffer.itemSize = 1;
        }
        if (upload || update) {
            this.programConfigurations.upload(context);
        }
    }

    destroy() {
        if (!this.layoutVertexBuffer) return;
        this.layoutVertexBuffer.destroy();
        this.indexBuffer.destroy();
        this.programConfigurations.destroy();
        this.segments.destroy();
        this.dynamicLayoutVertexBuffer.destroy();
        this.opacityVertexBuffer.destroy();
        if (this.globeExtVertexBuffer) {
            this.globeExtVertexBuffer.destroy();
        }
    }
}

register(SymbolBuffers, 'SymbolBuffers');

class CollisionBuffers {
                                   
                                               
                                     

                                                    
                             

                            

                                               
                                        

                                                     
                                           

    constructor(LayoutArray                    ,
                layoutAttributes                          ,
                IndexArray                                            ) {
        this.layoutVertexArray = new LayoutArray();
        this.layoutAttributes = layoutAttributes;
        this.indexArray = new IndexArray();
        this.segments = new SegmentVector();
        this.collisionVertexArray = new StructArrayLayout2ub2f12();
        this.collisionVertexArrayExt = new StructArrayLayout3f12();
    }

    upload(context         ) {
        this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray, this.layoutAttributes);
        this.indexBuffer = context.createIndexBuffer(this.indexArray);
        this.collisionVertexBuffer = context.createVertexBuffer(this.collisionVertexArray, collisionVertexAttributes.members, true);
        this.collisionVertexBufferExt = context.createVertexBuffer(this.collisionVertexArrayExt, collisionVertexAttributesExt.members, true);
    }

    destroy() {
        if (!this.layoutVertexBuffer) return;
        this.layoutVertexBuffer.destroy();
        this.indexBuffer.destroy();
        this.segments.destroy();
        this.collisionVertexBuffer.destroy();
        this.collisionVertexBufferExt.destroy();
    }
}

register(CollisionBuffers, 'CollisionBuffers');

/**
 * Unlike other buckets, which simply implement #addFeature with type-specific
 * logic for (essentially) triangulating feature geometries, SymbolBucket
 * requires specialized behavior:
 *
 * 1. WorkerTile#parse(), the logical owner of the bucket creation process,
 *    calls SymbolBucket#populate(), which resolves text and icon tokens on
 *    each feature, adds each glyphs and symbols needed to the passed-in
 *    collections options.glyphDependencies and options.iconDependencies, and
 *    stores the feature data for use in subsequent step (this.features).
 *
 * 2. WorkerTile asynchronously requests from the main thread all of the glyphs
 *    and icons needed (by this bucket and any others). When glyphs and icons
 *    have been received, the WorkerTile creates a CollisionIndex and invokes:
 *
 * 3. performSymbolLayout(bucket, stacks, icons) perform texts shaping and
 *    layout on a Symbol Bucket. This step populates:
 *      `this.symbolInstances`: metadata on generated symbols
 *      `collisionBoxArray`: collision data for use by foreground
 *      `this.text`: SymbolBuffers for text symbols
 *      `this.icons`: SymbolBuffers for icons
 *      `this.iconCollisionBox`: Debug SymbolBuffers for icon collision boxes
 *      `this.textCollisionBox`: Debug SymbolBuffers for text collision boxes
 *    The results are sent to the foreground for rendering
 *
 * 4. Placement.updateBucketOpacities() is run on the foreground,
 *    and uses the CollisionIndex along with current camera settings to determine
 *    which symbols can actually show on the map. Collided symbols are hidden
 *    using a dynamic "OpacityVertexArray".
 *
 * @private
 */
class SymbolBucket                   {
                              
                                                             

                                         
                 
                        
                                    
                            
                                                  
                                          

                  
                      
                         
                             
                             
                          
                        
                          

                           
                           

                                       
                                           
                                   
                                         
                                            
                                       
                       
                           
                                             
                          
                               
                             
                        
                        
                                    

                                        
                                 
                                  

                        
                        
                                       
                                       
                      
                             
                     
                                         
                                
                                    
                        
                                        
                                    

    constructor(options                                    ) {
        this.collisionBoxArray = options.collisionBoxArray;
        this.zoom = options.zoom;
        this.overscaling = options.overscaling;
        this.layers = options.layers;
        this.layerIds = this.layers.map(layer => layer.id);
        this.index = options.index;
        this.pixelRatio = options.pixelRatio;
        this.sourceLayerIndex = options.sourceLayerIndex;
        this.hasPattern = false;
        this.hasRTLText = false;
        this.fullyClipped = false;
        this.sortKeyRanges = [];

        this.collisionCircleArray = [];
        this.placementInvProjMatrix = identity$3([]);
        this.placementViewportMatrix = identity$3([]);

        const layer = this.layers[0];
        const unevaluatedLayoutValues = layer._unevaluatedLayout._values;

        this.textSizeData = getSizeData(this.zoom, unevaluatedLayoutValues['text-size']);
        this.iconSizeData = getSizeData(this.zoom, unevaluatedLayoutValues['icon-size']);

        const layout = this.layers[0].layout;
        const sortKey = layout.get('symbol-sort-key');
        const zOrder = layout.get('symbol-z-order');
        this.canOverlap =
            layout.get('text-allow-overlap') ||
            layout.get('icon-allow-overlap') ||
            layout.get('text-ignore-placement') ||
            layout.get('icon-ignore-placement');
        this.sortFeaturesByKey = zOrder !== 'viewport-y' && sortKey.constantOr(1) !== undefined;
        const zOrderByViewportY = zOrder === 'viewport-y' || (zOrder === 'auto' && !this.sortFeaturesByKey);
        this.sortFeaturesByY = zOrderByViewportY && this.canOverlap;

        this.writingModes = layout.get('text-writing-mode').map(wm => WritingMode[wm]);

        this.stateDependentLayerIds = this.layers.filter((l) => l.isStateDependent()).map((l) => l.id);

        this.sourceID = options.sourceID;
        this.projection = options.projection;
    }

    createArrays() {
        this.text = new SymbolBuffers(new ProgramConfigurationSet(this.layers, this.zoom, property => /^text/.test(property)));
        this.icon = new SymbolBuffers(new ProgramConfigurationSet(this.layers, this.zoom, property => /^icon/.test(property)));

        this.glyphOffsetArray = new GlyphOffsetArray();
        this.lineVertexArray = new SymbolLineVertexArray();
        this.symbolInstances = new SymbolInstanceArray();
    }

    calculateGlyphDependencies(text        , stack                        , textAlongLine         , allowVerticalPlacement         , doesAllowVerticalWritingMode         ) {
        for (let i = 0; i < text.length; i++) {
            stack[text.charCodeAt(i)] = true;
            if (allowVerticalPlacement && doesAllowVerticalWritingMode) {
                const verticalChar = verticalizedCharacterMap[text.charAt(i)];
                if (verticalChar) {
                    stack[verticalChar.charCodeAt(0)] = true;
                }
            }
        }
    }

    populate(features                       , options                    , canonical                 , tileTransform               ) {
        const layer = this.layers[0];
        const layout = layer.layout;
        const isGlobe = this.projection.name === 'globe';

        const textFont = layout.get('text-font');
        const textField = layout.get('text-field');
        const iconImage = layout.get('icon-image');
        const hasText =
            (textField.value.kind !== 'constant' ||
                (textField.value.value instanceof Formatted && !textField.value.value.isEmpty()) ||
                textField.value.value.toString().length > 0) &&
            (textFont.value.kind !== 'constant' || textFont.value.value.length > 0);
        // we should always resolve the icon-image value if the property was defined in the style
        // this allows us to fire the styleimagemissing event if image evaluation returns null
        // the only way to distinguish between null returned from a coalesce statement with no valid images
        // and null returned because icon-image wasn't defined is to check whether or not iconImage.parameters is an empty object
        const hasIcon = iconImage.value.kind !== 'constant' || !!iconImage.value.value || Object.keys(iconImage.parameters).length > 0;
        const symbolSortKey = layout.get('symbol-sort-key');

        this.features = [];

        if (!hasText && !hasIcon) {
            return;
        }

        const icons = options.iconDependencies;
        const stacks = options.glyphDependencies;
        const availableImages = options.availableImages;
        const globalProperties = new EvaluationParameters(this.zoom);

        for (const {feature, id, index, sourceLayerIndex} of features) {

            const needGeometry = layer._featureFilter.needGeometry;
            const evaluationFeature = toEvaluationFeature(feature, needGeometry);
            // $FlowFixMe[method-unbinding]
            if (!layer._featureFilter.filter(globalProperties, evaluationFeature, canonical)) {
                continue;
            }

            if (!needGeometry) evaluationFeature.geometry = loadGeometry(feature, canonical, tileTransform);

            if (isGlobe && feature.type !== 1 && canonical.z <= 5) {
                // Resample long lines and polygons in globe view so that their length wont exceed ~0.19 radians (360/32 degrees).
                // Otherwise lines could clip through the globe as the resolution is not enough to represent curved paths.
                // The threshold value follows subdivision size used with fill extrusions
                const geom = evaluationFeature.geometry;

                // cos(11.25 degrees) = 0.98078528056
                const cosAngleThreshold = 0.98078528056;
                const predicate = (a       , b       ) => {
                    const v0 = tileCoordToECEF(a.x, a.y, canonical, 1);
                    const v1 = tileCoordToECEF(b.x, b.y, canonical, 1);
                    return dot$5(v0, v1) < cosAngleThreshold;
                };

                for (let i = 0; i < geom.length; i++) {
                    geom[i] = resamplePred(geom[i], predicate);
                }
            }

            let text                  ;
            if (hasText) {
                // Expression evaluation will automatically coerce to Formatted
                // but plain string token evaluation skips that pathway so do the
                // conversion here.
                const resolvedTokens = layer.getValueAndResolveTokens('text-field', evaluationFeature, canonical, availableImages);
                const formattedText = Formatted.factory(resolvedTokens);
                if (containsRTLText(formattedText)) {
                    this.hasRTLText = true;
                }
                if (
                    !this.hasRTLText || // non-rtl text so can proceed safely
                    getRTLTextPluginStatus() === 'unavailable' || // We don't intend to lazy-load the rtl text plugin, so proceed with incorrect shaping
                    (this.hasRTLText && plugin.isParsed()) // Use the rtlText plugin to shape text
                ) {
                    text = transformText$1(formattedText, layer, evaluationFeature);
                }
            }

            let icon                ;
            if (hasIcon) {
                // Expression evaluation will automatically coerce to Image
                // but plain string token evaluation skips that pathway so do the
                // conversion here.
                const resolvedTokens = layer.getValueAndResolveTokens('icon-image', evaluationFeature, canonical, availableImages);
                if (resolvedTokens instanceof ResolvedImage) {
                    icon = resolvedTokens;
                } else {
                    icon = ResolvedImage.fromString(resolvedTokens);
                }
            }

            if (!text && !icon) {
                continue;
            }
            const sortKey = this.sortFeaturesByKey ?
                symbolSortKey.evaluate(evaluationFeature, {}, canonical) :
                undefined;

            const symbolFeature                = {
                id,
                text,
                icon,
                index,
                sourceLayerIndex,
                geometry: evaluationFeature.geometry,
                properties: feature.properties,
                type: vectorTileFeatureTypes[feature.type],
                sortKey
            };
            this.features.push(symbolFeature);

            if (icon) {
                icons[icon.name] = true;
            }

            if (text) {
                const fontStack = textFont.evaluate(evaluationFeature, {}, canonical).join(',');
                const textAlongLine = layout.get('text-rotation-alignment') === 'map' && layout.get('symbol-placement') !== 'point';
                this.allowVerticalPlacement = this.writingModes && this.writingModes.indexOf(WritingMode.vertical) >= 0;
                for (const section of text.sections) {
                    if (!section.image) {
                        const doesAllowVerticalWritingMode = allowsVerticalWritingMode(text.toString());
                        const sectionFont = section.fontStack || fontStack;
                        const sectionStack = stacks[sectionFont] = stacks[sectionFont] || {};
                        this.calculateGlyphDependencies(section.text, sectionStack, textAlongLine, this.allowVerticalPlacement, doesAllowVerticalWritingMode);
                    } else {
                        // Add section image to the list of dependencies.
                        icons[section.image.name] = true;
                    }
                }
            }
        }

        if (layout.get('symbol-placement') === 'line') {
            // Merge adjacent lines with the same text to improve labelling.
            // It's better to place labels on one long line than on many short segments.
            this.features = mergeLines(this.features);
        }

        if (this.sortFeaturesByKey) {
            this.features.sort((a, b) => {
                // a.sortKey is always a number when sortFeaturesByKey is true
                return ((a.sortKey     )        ) - ((b.sortKey     )        );
            });
        }
    }

    update(states               , vtLayer                  , availableImages               , imagePositions                 ) {
        if (!this.stateDependentLayers.length) return;
        this.text.programConfigurations.updatePaintArrays(states, vtLayer, this.layers, availableImages, imagePositions);
        this.icon.programConfigurations.updatePaintArrays(states, vtLayer, this.layers, availableImages, imagePositions);
    }

    isEmpty()          {
        // When the bucket encounters only rtl-text but the plugin isn't loaded, no symbol instances will be created.
        // In order for the bucket to be serialized, and not discarded as an empty bucket both checks are necessary.
        return this.symbolInstances.length === 0 && !this.hasRTLText;
    }

    uploadPending()          {
        return !this.uploaded || this.text.programConfigurations.needsUpload || this.icon.programConfigurations.needsUpload;
    }

    upload(context         ) {
        if (!this.uploaded && this.hasDebugData()) {
            this.textCollisionBox.upload(context);
            this.iconCollisionBox.upload(context);
        }
        this.text.upload(context, this.sortFeaturesByY, !this.uploaded, this.text.programConfigurations.needsUpload);
        this.icon.upload(context, this.sortFeaturesByY, !this.uploaded, this.icon.programConfigurations.needsUpload);
        this.uploaded = true;
    }

    destroyDebugData() {
        this.textCollisionBox.destroy();
        this.iconCollisionBox.destroy();
    }

    getProjection()             {
        if (!this.projectionInstance) {
            this.projectionInstance = getProjection(this.projection);
        }
        return this.projectionInstance;
    }

    destroy() {
        this.text.destroy();
        this.icon.destroy();

        if (this.hasDebugData()) {
            this.destroyDebugData();
        }
    }

    addToLineVertexArray(anchor        , line              )                  {
        const lineStartIndex = this.lineVertexArray.length;
        if (anchor.segment !== undefined) {
            for (const {x, y} of line) {
                this.lineVertexArray.emplaceBack(x, y);
            }
        }
        return {
            lineStartIndex,
            lineLength: this.lineVertexArray.length - lineStartIndex
        };
    }

    addSymbols(arrays               ,
               quads                   ,
               sizeVertex     ,
               lineOffset                  ,
               alongLine         ,
               feature               ,
               writingMode     ,
               globe                               ,
               tileAnchor        ,
               lineStartIndex        ,
               lineLength        ,
               associatedIconIndex        ,
               availableImages               ,
               canonical                 ) {
        const indexArray = arrays.indexArray;
        const layoutVertexArray = arrays.layoutVertexArray;
        const globeExtVertexArray = arrays.globeExtVertexArray;

        const segment = arrays.segments.prepareSegment(4 * quads.length, layoutVertexArray, indexArray, this.canOverlap ? feature.sortKey : undefined);
        const glyphOffsetArrayStart = this.glyphOffsetArray.length;
        const vertexStartIndex = segment.vertexLength;

        const angle = (this.allowVerticalPlacement && writingMode === WritingMode.vertical) ? Math.PI / 2 : 0;

        const sections = feature.text && feature.text.sections;

        for (let i = 0; i < quads.length; i++) {
            const {tl, tr, bl, br, tex, pixelOffsetTL, pixelOffsetBR, minFontScaleX, minFontScaleY, glyphOffset, isSDF, sectionIndex} = quads[i];
            const index = segment.vertexLength;

            const y = glyphOffset[1];
            addVertex(layoutVertexArray, tileAnchor.x, tileAnchor.y, tl.x, y + tl.y, tex.x, tex.y, sizeVertex, isSDF, pixelOffsetTL.x, pixelOffsetTL.y, minFontScaleX, minFontScaleY);
            addVertex(layoutVertexArray, tileAnchor.x, tileAnchor.y, tr.x, y + tr.y, tex.x + tex.w, tex.y, sizeVertex, isSDF, pixelOffsetBR.x, pixelOffsetTL.y, minFontScaleX, minFontScaleY);
            addVertex(layoutVertexArray, tileAnchor.x, tileAnchor.y, bl.x, y + bl.y, tex.x, tex.y + tex.h, sizeVertex, isSDF, pixelOffsetTL.x, pixelOffsetBR.y, minFontScaleX, minFontScaleY);
            addVertex(layoutVertexArray, tileAnchor.x, tileAnchor.y, br.x, y + br.y, tex.x + tex.w, tex.y + tex.h, sizeVertex, isSDF, pixelOffsetBR.x, pixelOffsetBR.y, minFontScaleX, minFontScaleY);

            if (globe) {
                const {x, y, z} = globe.anchor;
                const [ux, uy, uz] = globe.up;
                addGlobeVertex(globeExtVertexArray, x, y, z, ux, uy, uz);
                addGlobeVertex(globeExtVertexArray, x, y, z, ux, uy, uz);
                addGlobeVertex(globeExtVertexArray, x, y, z, ux, uy, uz);
                addGlobeVertex(globeExtVertexArray, x, y, z, ux, uy, uz);

                addDynamicAttributes(arrays.dynamicLayoutVertexArray, x, y, z, angle);
            } else {
                addDynamicAttributes(arrays.dynamicLayoutVertexArray, tileAnchor.x, tileAnchor.y, tileAnchor.z, angle);
            }

            indexArray.emplaceBack(index, index + 1, index + 2);
            indexArray.emplaceBack(index + 1, index + 2, index + 3);

            segment.vertexLength += 4;
            segment.primitiveLength += 2;

            this.glyphOffsetArray.emplaceBack(glyphOffset[0]);

            if (i === quads.length - 1 || sectionIndex !== quads[i + 1].sectionIndex) {
                arrays.programConfigurations.populatePaintArrays(layoutVertexArray.length, feature, feature.index, {}, availableImages, canonical, sections && sections[sectionIndex]);
            }
        }

        const projectedAnchor = globe ? globe.anchor : tileAnchor;

        arrays.placedSymbolArray.emplaceBack(projectedAnchor.x, projectedAnchor.y, projectedAnchor.z, tileAnchor.x, tileAnchor.y,
            glyphOffsetArrayStart, this.glyphOffsetArray.length - glyphOffsetArrayStart, vertexStartIndex,
            lineStartIndex, lineLength, (tileAnchor.segment     ),
            sizeVertex ? sizeVertex[0] : 0, sizeVertex ? sizeVertex[1] : 0,
            lineOffset[0], lineOffset[1],
            writingMode,
            // placedOrientation is null initially; will be updated to horizontal(1)/vertical(2) if placed
            0,
            (false     ),
            // The crossTileID is only filled/used on the foreground for dynamic text anchors
            0,
            associatedIconIndex,
            // flipState is unknown initially; will be updated to flipRequired(1)/flipNotRequired(2) during line label reprojection
            0
        );
    }

    _commitLayoutVertex(array             , boxTileAnchorX        , boxTileAnchorY        , boxTileAnchorZ        , tileAnchorX        , tileAnchorY        , extrude       ) {
        array.emplaceBack(
            // pos
            boxTileAnchorX,
            boxTileAnchorY,
            boxTileAnchorZ,
            // a_anchor_pos
            tileAnchorX,
            tileAnchorY,
            // extrude
            Math.round(extrude.x),
            Math.round(extrude.y));
    }

    _addCollisionDebugVertices(box              , scale        , arrays                  , boxTileAnchorX        , boxTileAnchorY        , boxTileAnchorZ        , symbolInstance                ) {
        const segment = arrays.segments.prepareSegment(4, arrays.layoutVertexArray, arrays.indexArray);
        const index = segment.vertexLength;
        const symbolTileAnchorX = symbolInstance.tileAnchorX;
        const symbolTileAnchorY = symbolInstance.tileAnchorY;

        for (let i = 0; i < 4; i++) {
            arrays.collisionVertexArray.emplaceBack(0, 0, 0, 0);
        }

        arrays.collisionVertexArrayExt.emplaceBack(scale, -box.padding, -box.padding);
        arrays.collisionVertexArrayExt.emplaceBack(scale,  box.padding, -box.padding);
        arrays.collisionVertexArrayExt.emplaceBack(scale,  box.padding,  box.padding);
        arrays.collisionVertexArrayExt.emplaceBack(scale, -box.padding,  box.padding);

        this._commitLayoutVertex(arrays.layoutVertexArray, boxTileAnchorX, boxTileAnchorY, boxTileAnchorZ, symbolTileAnchorX, symbolTileAnchorY, new Point$2(box.x1, box.y1));
        this._commitLayoutVertex(arrays.layoutVertexArray, boxTileAnchorX, boxTileAnchorY, boxTileAnchorZ, symbolTileAnchorX, symbolTileAnchorY, new Point$2(box.x2, box.y1));
        this._commitLayoutVertex(arrays.layoutVertexArray, boxTileAnchorX, boxTileAnchorY, boxTileAnchorZ, symbolTileAnchorX, symbolTileAnchorY, new Point$2(box.x2, box.y2));
        this._commitLayoutVertex(arrays.layoutVertexArray, boxTileAnchorX, boxTileAnchorY, boxTileAnchorZ, symbolTileAnchorX, symbolTileAnchorY, new Point$2(box.x1, box.y2));

        segment.vertexLength += 4;

        const indexArray                 = (arrays.indexArray     );
        indexArray.emplaceBack(index, index + 1);
        indexArray.emplaceBack(index + 1, index + 2);
        indexArray.emplaceBack(index + 2, index + 3);
        indexArray.emplaceBack(index + 3, index);

        segment.primitiveLength += 4;
    }

    _addTextDebugCollisionBoxes(size     , zoom        , collisionBoxArray                   , startIndex        , endIndex        , instance                ) {
        for (let b = startIndex; b < endIndex; b++) {
            const box               = (collisionBoxArray.get(b)     );
            const scale = this.getSymbolInstanceTextSize(size, instance, zoom, b);

            this._addCollisionDebugVertices(box, scale, this.textCollisionBox, box.projectedAnchorX, box.projectedAnchorY, box.projectedAnchorZ, instance);
        }
    }

    _addIconDebugCollisionBoxes(size     , zoom        , collisionBoxArray                   , startIndex        , endIndex        , instance                ) {
        for (let b = startIndex; b < endIndex; b++) {
            const box               = (collisionBoxArray.get(b)     );
            const scale = this.getSymbolInstanceIconSize(size, zoom, instance.placedIconSymbolIndex);

            this._addCollisionDebugVertices(box, scale, this.iconCollisionBox, box.projectedAnchorX, box.projectedAnchorY, box.projectedAnchorZ, instance);
        }
    }

    generateCollisionDebugBuffers(zoom        , collisionBoxArray                   ) {
        if (this.hasDebugData()) {
            this.destroyDebugData();
        }

        this.textCollisionBox = new CollisionBuffers(StructArrayLayout3i2i2i16, collisionBoxLayout.members, StructArrayLayout2ui4);
        this.iconCollisionBox = new CollisionBuffers(StructArrayLayout3i2i2i16, collisionBoxLayout.members, StructArrayLayout2ui4);

        const iconSize = evaluateSizeForZoom(this.iconSizeData, zoom);
        const textSize = evaluateSizeForZoom(this.textSizeData, zoom);

        for (let i = 0; i < this.symbolInstances.length; i++) {
            const symbolInstance = this.symbolInstances.get(i);
            this._addTextDebugCollisionBoxes(textSize, zoom, collisionBoxArray, symbolInstance.textBoxStartIndex, symbolInstance.textBoxEndIndex, symbolInstance);
            this._addTextDebugCollisionBoxes(textSize, zoom, collisionBoxArray, symbolInstance.verticalTextBoxStartIndex, symbolInstance.verticalTextBoxEndIndex, symbolInstance);
            this._addIconDebugCollisionBoxes(iconSize, zoom, collisionBoxArray, symbolInstance.iconBoxStartIndex, symbolInstance.iconBoxEndIndex, symbolInstance);
            this._addIconDebugCollisionBoxes(iconSize, zoom, collisionBoxArray, symbolInstance.verticalIconBoxStartIndex, symbolInstance.verticalIconBoxEndIndex, symbolInstance);
        }
    }

    getSymbolInstanceTextSize(textSize     , instance                , zoom        , boxIndex        )         {
        const symbolIndex = instance.rightJustifiedTextSymbolIndex >= 0 ?
            instance.rightJustifiedTextSymbolIndex : instance.centerJustifiedTextSymbolIndex >= 0 ?
                instance.centerJustifiedTextSymbolIndex : instance.leftJustifiedTextSymbolIndex >= 0 ?
                    instance.leftJustifiedTextSymbolIndex : instance.verticalPlacedTextSymbolIndex >= 0 ?
                        instance.verticalPlacedTextSymbolIndex : boxIndex;

        const symbol = this.text.placedSymbolArray.get(symbolIndex);
        const featureSize = evaluateSizeForFeature(this.textSizeData, textSize, symbol) / ONE_EM;

        return this.tilePixelRatio * featureSize;
    }

    getSymbolInstanceIconSize(iconSize     , zoom        , iconIndex        )         {
        const symbol = this.icon.placedSymbolArray.get(iconIndex);
        const featureSize = evaluateSizeForFeature(this.iconSizeData, iconSize, symbol);

        return this.tilePixelRatio * featureSize;
    }

    _commitDebugCollisionVertexUpdate(array             , scale        , padding        ) {
        array.emplaceBack(scale, -padding, -padding);
        array.emplaceBack(scale,  padding, -padding);
        array.emplaceBack(scale,  padding,  padding);
        array.emplaceBack(scale, -padding,  padding);
    }

    _updateTextDebugCollisionBoxes(size     , zoom        , collisionBoxArray                   , startIndex        , endIndex        , instance                ) {
        for (let b = startIndex; b < endIndex; b++) {
            const box               = (collisionBoxArray.get(b)     );
            const scale = this.getSymbolInstanceTextSize(size, instance, zoom, b);
            const array = this.textCollisionBox.collisionVertexArrayExt;
            this._commitDebugCollisionVertexUpdate(array, scale, box.padding);
        }
    }

    _updateIconDebugCollisionBoxes(size     , zoom        , collisionBoxArray                   , startIndex        , endIndex        , symbolIndex        ) {
        for (let b = startIndex; b < endIndex; b++) {
            const box = (collisionBoxArray.get(b));
            const scale = this.getSymbolInstanceIconSize(size, zoom, symbolIndex);
            const array = this.iconCollisionBox.collisionVertexArrayExt;
            this._commitDebugCollisionVertexUpdate(array, scale, box.padding);
        }
    }

    updateCollisionDebugBuffers(zoom        , collisionBoxArray                   ) {
        if (!this.hasDebugData()) {
            return;
        }

        if (this.hasTextCollisionBoxData()) this.textCollisionBox.collisionVertexArrayExt.clear();
        if (this.hasIconCollisionBoxData()) this.iconCollisionBox.collisionVertexArrayExt.clear();

        const iconSize = evaluateSizeForZoom(this.iconSizeData, zoom);
        const textSize = evaluateSizeForZoom(this.textSizeData, zoom);

        for (let i = 0; i < this.symbolInstances.length; i++) {
            const symbolInstance = this.symbolInstances.get(i);
            this._updateTextDebugCollisionBoxes(textSize, zoom, collisionBoxArray, symbolInstance.textBoxStartIndex, symbolInstance.textBoxEndIndex, symbolInstance);
            this._updateTextDebugCollisionBoxes(textSize, zoom, collisionBoxArray, symbolInstance.verticalTextBoxStartIndex, symbolInstance.verticalTextBoxEndIndex, symbolInstance);
            this._updateIconDebugCollisionBoxes(iconSize, zoom, collisionBoxArray, symbolInstance.iconBoxStartIndex, symbolInstance.iconBoxEndIndex, symbolInstance.placedIconSymbolIndex);
            this._updateIconDebugCollisionBoxes(iconSize, zoom, collisionBoxArray, symbolInstance.verticalIconBoxStartIndex, symbolInstance.verticalIconBoxEndIndex, symbolInstance.placedIconSymbolIndex);
        }

        if (this.hasTextCollisionBoxData() && this.textCollisionBox.collisionVertexBufferExt) {
            this.textCollisionBox.collisionVertexBufferExt.updateData(this.textCollisionBox.collisionVertexArrayExt);
        }
        if (this.hasIconCollisionBoxData() && this.iconCollisionBox.collisionVertexBufferExt) {
            this.iconCollisionBox.collisionVertexBufferExt.updateData(this.iconCollisionBox.collisionVertexArrayExt);
        }
    }

    // These flat arrays are meant to be quicker to iterate over than the source
    // CollisionBoxArray
    _deserializeCollisionBoxesForSymbol(collisionBoxArray                   ,
        textStartIndex        , textEndIndex        ,
        verticalTextStartIndex        , verticalTextEndIndex        ,
        iconStartIndex        , iconEndIndex        ,
        verticalIconStartIndex        , verticalIconEndIndex        )                  {

        // Only one box allowed per instance
        const collisionArrays = {};
        if (textStartIndex < textEndIndex) {
            const {x1, y1, x2, y2, padding, projectedAnchorX, projectedAnchorY, projectedAnchorZ, tileAnchorX, tileAnchorY, featureIndex} = collisionBoxArray.get(textStartIndex);
            collisionArrays.textBox = {x1, y1, x2, y2, padding, projectedAnchorX, projectedAnchorY, projectedAnchorZ, tileAnchorX, tileAnchorY};
            collisionArrays.textFeatureIndex = featureIndex;
        }
        if (verticalTextStartIndex < verticalTextEndIndex) {
            const {x1, y1, x2, y2, padding, projectedAnchorX, projectedAnchorY, projectedAnchorZ, tileAnchorX, tileAnchorY, featureIndex} = collisionBoxArray.get(verticalTextStartIndex);
            collisionArrays.verticalTextBox = {x1, y1, x2, y2, padding, projectedAnchorX, projectedAnchorY, projectedAnchorZ, tileAnchorX, tileAnchorY};
            collisionArrays.verticalTextFeatureIndex = featureIndex;
        }
        if (iconStartIndex < iconEndIndex) {
            const {x1, y1, x2, y2, padding, projectedAnchorX, projectedAnchorY, projectedAnchorZ, tileAnchorX, tileAnchorY, featureIndex} = collisionBoxArray.get(iconStartIndex);
            collisionArrays.iconBox = {x1, y1, x2, y2, padding, projectedAnchorX, projectedAnchorY, projectedAnchorZ, tileAnchorX, tileAnchorY};
            collisionArrays.iconFeatureIndex = featureIndex;
        }
        if (verticalIconStartIndex < verticalIconEndIndex) {
            const {x1, y1, x2, y2, padding, projectedAnchorX, projectedAnchorY, projectedAnchorZ, tileAnchorX, tileAnchorY, featureIndex} = collisionBoxArray.get(verticalIconStartIndex);
            collisionArrays.verticalIconBox = {x1, y1, x2, y2, padding, projectedAnchorX, projectedAnchorY, projectedAnchorZ, tileAnchorX, tileAnchorY};
            collisionArrays.verticalIconFeatureIndex = featureIndex;
        }
        return collisionArrays;
    }

    deserializeCollisionBoxes(collisionBoxArray                   ) {
        this.collisionArrays = [];
        for (let i = 0; i < this.symbolInstances.length; i++) {
            const symbolInstance = this.symbolInstances.get(i);
            this.collisionArrays.push(this._deserializeCollisionBoxesForSymbol(
                collisionBoxArray,
                symbolInstance.textBoxStartIndex,
                symbolInstance.textBoxEndIndex,
                symbolInstance.verticalTextBoxStartIndex,
                symbolInstance.verticalTextBoxEndIndex,
                symbolInstance.iconBoxStartIndex,
                symbolInstance.iconBoxEndIndex,
                symbolInstance.verticalIconBoxStartIndex,
                symbolInstance.verticalIconBoxEndIndex
            ));
        }
    }

    hasTextData()          {
        return this.text.segments.get().length > 0;
    }

    hasIconData()          {
        return this.icon.segments.get().length > 0;
    }

    hasDebugData()                   {
        return this.textCollisionBox && this.iconCollisionBox;
    }

    hasTextCollisionBoxData()          {
        return this.hasDebugData() && this.textCollisionBox.segments.get().length > 0;
    }

    hasIconCollisionBoxData()          {
        return this.hasDebugData() && this.iconCollisionBox.segments.get().length > 0;
    }

    addIndicesForPlacedSymbol(iconOrText               , placedSymbolIndex        ) {
        const placedSymbol = iconOrText.placedSymbolArray.get(placedSymbolIndex);

        const endIndex = placedSymbol.vertexStartIndex + placedSymbol.numGlyphs * 4;
        for (let vertexIndex = placedSymbol.vertexStartIndex; vertexIndex < endIndex; vertexIndex += 4) {
            iconOrText.indexArray.emplaceBack(vertexIndex, vertexIndex + 1, vertexIndex + 2);
            iconOrText.indexArray.emplaceBack(vertexIndex + 1, vertexIndex + 2, vertexIndex + 3);
        }
    }

    getSortedSymbolIndexes(angle        )                {
        if (this.sortedAngle === angle && this.symbolInstanceIndexes !== undefined) {
            return this.symbolInstanceIndexes;
        }
        const sin = Math.sin(angle);
        const cos = Math.cos(angle);
        const rotatedYs = [];
        const featureIndexes = [];
        const result = [];

        for (let i = 0; i < this.symbolInstances.length; ++i) {
            result.push(i);
            const symbolInstance = this.symbolInstances.get(i);
            rotatedYs.push(Math.round(sin * symbolInstance.tileAnchorX + cos * symbolInstance.tileAnchorY) | 0);
            featureIndexes.push(symbolInstance.featureIndex);
        }

        result.sort((aIndex, bIndex) => (rotatedYs[aIndex] - rotatedYs[bIndex]) || (featureIndexes[bIndex] - featureIndexes[aIndex]));

        return result;
    }

    addToSortKeyRanges(symbolInstanceIndex        , sortKey        ) {
        const last = this.sortKeyRanges[this.sortKeyRanges.length - 1];
        if (last && last.sortKey === sortKey) {
            last.symbolInstanceEnd = symbolInstanceIndex + 1;
        } else {
            this.sortKeyRanges.push({
                sortKey,
                symbolInstanceStart: symbolInstanceIndex,
                symbolInstanceEnd: symbolInstanceIndex + 1
            });
        }
    }

    sortFeatures(angle        ) {
        if (!this.sortFeaturesByY) return;
        if (this.sortedAngle === angle) return;

        // The current approach to sorting doesn't sort across segments so don't try.
        // Sorting within segments separately seemed not to be worth the complexity.
        if (this.text.segments.get().length > 1 || this.icon.segments.get().length > 1) return;

        // If the symbols are allowed to overlap sort them by their vertical screen position.
        // The index array buffer is rewritten to reference the (unchanged) vertices in the
        // sorted order.

        // To avoid sorting the actual symbolInstance array we sort an array of indexes.
        this.symbolInstanceIndexes = this.getSortedSymbolIndexes(angle);
        this.sortedAngle = angle;

        this.text.indexArray.clear();
        this.icon.indexArray.clear();

        this.featureSortOrder = [];

        for (const i of this.symbolInstanceIndexes) {
            const symbol = this.symbolInstances.get(i);
            this.featureSortOrder.push(symbol.featureIndex);
            const {
                rightJustifiedTextSymbolIndex: right, centerJustifiedTextSymbolIndex: center,
                leftJustifiedTextSymbolIndex: left, verticalPlacedTextSymbolIndex: vertical,
                placedIconSymbolIndex: icon, verticalPlacedIconSymbolIndex: iconVertical
            } = symbol;

            // Only add a given index the first time it shows up, to avoid duplicate
            // opacity entries when multiple justifications share the same glyphs.
            if (right >= 0) this.addIndicesForPlacedSymbol(this.text, right);
            if (center >= 0 && center !== right) this.addIndicesForPlacedSymbol(this.text, center);
            if (left >= 0 && left !== center && left !== right) this.addIndicesForPlacedSymbol(this.text, left);

            if (vertical >= 0) this.addIndicesForPlacedSymbol(this.text, vertical);
            if (icon >= 0) this.addIndicesForPlacedSymbol(this.icon, icon);
            if (iconVertical >= 0) this.addIndicesForPlacedSymbol(this.icon, iconVertical);
        }

        if (this.text.indexBuffer) this.text.indexBuffer.updateData(this.text.indexArray);
        if (this.icon.indexBuffer) this.icon.indexBuffer.updateData(this.icon.indexArray);
    }
}

register(SymbolBucket, 'SymbolBucket', {
    omit: ['layers', 'collisionBoxArray', 'features', 'compareText']
});

// this constant is based on the size of StructArray indexes used in a symbol
// bucket--namely, glyphOffsetArrayStart
// eg the max valid UInt16 is 65,535
// See https://github.com/mapbox/mapbox-gl-js/issues/2907 for motivation
// lineStartIndex and textBoxStartIndex could potentially be concerns
// but we expect there to be many fewer boxes/lines than glyphs
SymbolBucket.MAX_GLYPHS = 65535;

SymbolBucket.addDynamicAttributes = addDynamicAttributes;

var SymbolBucket$1 = SymbolBucket;

//      

/**
 * Replace tokens in a string template with values in an object
 *
 * @param properties a key/value relationship between tokens and replacements
 * @param text the template string
 * @returns the template with tokens replaced
 * @private
 */
function resolveTokens(properties                    , text        )         {
    return text.replace(/{([^{}]+)}/g, (match, key        ) => {
        return key in properties ? String(properties[key]) : '';
    });
}

// This file is generated. Edit build/generate-style-code.js, then run `yarn run codegen`.
//      
/* eslint-disable */


                            
                                                                               
                                                   
                                                        
                                                  
                                                                             
                                                        
                                                           
                                                   
                                                                                 
                                            
                                                                                
                                                                                    
                                                    
                                              
                                                 
                                                       
                                                        
                                                                                                                                                  
                                                                              
                                                                              
                                                                                 
                                                
                                                   
                                            
                                                 
                                                   
                                                      
                                                                             
                                                     
                                                                                                                                                                    
                                                                                                                                                  
                                                   
                                                                                
                                              
                                                 
                                                       
                                                                             
                                                        
                                                        
                                                           
                                                   
   

const layout                          = new Properties({
    "symbol-placement": new DataConstantProperty(spec["layout_symbol"]["symbol-placement"]),
    "symbol-spacing": new DataConstantProperty(spec["layout_symbol"]["symbol-spacing"]),
    "symbol-avoid-edges": new DataConstantProperty(spec["layout_symbol"]["symbol-avoid-edges"]),
    "symbol-sort-key": new DataDrivenProperty(spec["layout_symbol"]["symbol-sort-key"]),
    "symbol-z-order": new DataConstantProperty(spec["layout_symbol"]["symbol-z-order"]),
    "icon-allow-overlap": new DataConstantProperty(spec["layout_symbol"]["icon-allow-overlap"]),
    "icon-ignore-placement": new DataConstantProperty(spec["layout_symbol"]["icon-ignore-placement"]),
    "icon-optional": new DataConstantProperty(spec["layout_symbol"]["icon-optional"]),
    "icon-rotation-alignment": new DataConstantProperty(spec["layout_symbol"]["icon-rotation-alignment"]),
    "icon-size": new DataDrivenProperty(spec["layout_symbol"]["icon-size"]),
    "icon-text-fit": new DataConstantProperty(spec["layout_symbol"]["icon-text-fit"]),
    "icon-text-fit-padding": new DataConstantProperty(spec["layout_symbol"]["icon-text-fit-padding"]),
    "icon-image": new DataDrivenProperty(spec["layout_symbol"]["icon-image"]),
    "icon-rotate": new DataDrivenProperty(spec["layout_symbol"]["icon-rotate"]),
    "icon-padding": new DataConstantProperty(spec["layout_symbol"]["icon-padding"]),
    "icon-keep-upright": new DataConstantProperty(spec["layout_symbol"]["icon-keep-upright"]),
    "icon-offset": new DataDrivenProperty(spec["layout_symbol"]["icon-offset"]),
    "icon-anchor": new DataDrivenProperty(spec["layout_symbol"]["icon-anchor"]),
    "icon-pitch-alignment": new DataConstantProperty(spec["layout_symbol"]["icon-pitch-alignment"]),
    "text-pitch-alignment": new DataConstantProperty(spec["layout_symbol"]["text-pitch-alignment"]),
    "text-rotation-alignment": new DataConstantProperty(spec["layout_symbol"]["text-rotation-alignment"]),
    "text-field": new DataDrivenProperty(spec["layout_symbol"]["text-field"]),
    "text-font": new DataDrivenProperty(spec["layout_symbol"]["text-font"]),
    "text-size": new DataDrivenProperty(spec["layout_symbol"]["text-size"]),
    "text-max-width": new DataDrivenProperty(spec["layout_symbol"]["text-max-width"]),
    "text-line-height": new DataDrivenProperty(spec["layout_symbol"]["text-line-height"]),
    "text-letter-spacing": new DataDrivenProperty(spec["layout_symbol"]["text-letter-spacing"]),
    "text-justify": new DataDrivenProperty(spec["layout_symbol"]["text-justify"]),
    "text-radial-offset": new DataDrivenProperty(spec["layout_symbol"]["text-radial-offset"]),
    "text-variable-anchor": new DataConstantProperty(spec["layout_symbol"]["text-variable-anchor"]),
    "text-anchor": new DataDrivenProperty(spec["layout_symbol"]["text-anchor"]),
    "text-max-angle": new DataConstantProperty(spec["layout_symbol"]["text-max-angle"]),
    "text-writing-mode": new DataConstantProperty(spec["layout_symbol"]["text-writing-mode"]),
    "text-rotate": new DataDrivenProperty(spec["layout_symbol"]["text-rotate"]),
    "text-padding": new DataConstantProperty(spec["layout_symbol"]["text-padding"]),
    "text-keep-upright": new DataConstantProperty(spec["layout_symbol"]["text-keep-upright"]),
    "text-transform": new DataDrivenProperty(spec["layout_symbol"]["text-transform"]),
    "text-offset": new DataDrivenProperty(spec["layout_symbol"]["text-offset"]),
    "text-allow-overlap": new DataConstantProperty(spec["layout_symbol"]["text-allow-overlap"]),
    "text-ignore-placement": new DataConstantProperty(spec["layout_symbol"]["text-ignore-placement"]),
    "text-optional": new DataConstantProperty(spec["layout_symbol"]["text-optional"]),
});

                           
                                               
                                            
                                                 
                                                  
                                                 
                                                             
                                                                      
                                               
                                            
                                                 
                                                  
                                                 
                                                             
                                                                      
   

const paint$3                         = new Properties({
    "icon-opacity": new DataDrivenProperty(spec["paint_symbol"]["icon-opacity"]),
    "icon-color": new DataDrivenProperty(spec["paint_symbol"]["icon-color"]),
    "icon-halo-color": new DataDrivenProperty(spec["paint_symbol"]["icon-halo-color"]),
    "icon-halo-width": new DataDrivenProperty(spec["paint_symbol"]["icon-halo-width"]),
    "icon-halo-blur": new DataDrivenProperty(spec["paint_symbol"]["icon-halo-blur"]),
    "icon-translate": new DataConstantProperty(spec["paint_symbol"]["icon-translate"]),
    "icon-translate-anchor": new DataConstantProperty(spec["paint_symbol"]["icon-translate-anchor"]),
    "text-opacity": new DataDrivenProperty(spec["paint_symbol"]["text-opacity"]),
    "text-color": new DataDrivenProperty(spec["paint_symbol"]["text-color"], { runtimeType: ColorType, getOverride: (o) => o.textColor, hasOverride: (o) => !!o.textColor }),
    "text-halo-color": new DataDrivenProperty(spec["paint_symbol"]["text-halo-color"]),
    "text-halo-width": new DataDrivenProperty(spec["paint_symbol"]["text-halo-width"]),
    "text-halo-blur": new DataDrivenProperty(spec["paint_symbol"]["text-halo-blur"]),
    "text-translate": new DataConstantProperty(spec["paint_symbol"]["text-translate"]),
    "text-translate-anchor": new DataConstantProperty(spec["paint_symbol"]["text-translate-anchor"]),
});

// Note: without adding the explicit type annotation, Flow infers weaker types
// for these objects from their use in the constructor to StyleLayer, as
// {layout?: Properties<...>, paint: Properties<...>}
var properties$3 = ({ paint: paint$3, layout }          
                                                                
  );

//      


// This is an internal expression class. It is only used in GL JS and
// has GL JS dependencies which can break the standalone style-spec module
class FormatSectionOverride                          {
               
                                                    

    constructor(defaultValue                                   ) {
        assert$1(defaultValue.property.overrides !== undefined);
        this.type = defaultValue.property.overrides ? defaultValue.property.overrides.runtimeType : NullType;
        this.defaultValue = defaultValue;
    }

    evaluate(ctx                   )    {
        if (ctx.formattedSection) {
            const overrides = this.defaultValue.property.overrides;
            if (overrides && overrides.hasOverride(ctx.formattedSection)) {
                return overrides.getOverride(ctx.formattedSection);
            }
        }

        if (ctx.feature && ctx.featureState) {
            return this.defaultValue.evaluate(ctx.feature, ctx.featureState);
        }

        // not sure how to make Flow refine the type properly here — will need investigation
        return ((this.defaultValue.property.specification.default     )   );
    }

    eachChild(fn                         ) {
        if (!this.defaultValue.isConstant()) {
            const expr                                   = ((this.defaultValue.value)     );
            fn(expr._styleExpression.expression);
        }
    }

    // Cannot be statically evaluated, as the output depends on the evaluation context.
    outputDefined()          {
        return false;
    }

    serialize()       {
        return null;
    }
}

register(FormatSectionOverride, 'FormatSectionOverride', {omit: ['defaultValue']});

//      


class SymbolStyleLayer extends StyleLayer {
                                            
                                           

                                                     
                                                   
                                         

    constructor(layer                    ) {
        super(layer, properties$3);
    }

    recalculate(parameters                      , availableImages               ) {
        super.recalculate(parameters, availableImages);

        if (this.layout.get('icon-rotation-alignment') === 'auto') {
            if (this.layout.get('symbol-placement') !== 'point') {
                this.layout._values['icon-rotation-alignment'] = 'map';
            } else {
                this.layout._values['icon-rotation-alignment'] = 'viewport';
            }
        }

        if (this.layout.get('text-rotation-alignment') === 'auto') {
            if (this.layout.get('symbol-placement') !== 'point') {
                this.layout._values['text-rotation-alignment'] = 'map';
            } else {
                this.layout._values['text-rotation-alignment'] = 'viewport';
            }
        }

        // If unspecified, `*-pitch-alignment` inherits `*-rotation-alignment`
        if (this.layout.get('text-pitch-alignment') === 'auto') {
            this.layout._values['text-pitch-alignment'] = this.layout.get('text-rotation-alignment');
        }
        if (this.layout.get('icon-pitch-alignment') === 'auto') {
            this.layout._values['icon-pitch-alignment'] = this.layout.get('icon-rotation-alignment');
        }

        const writingModes = this.layout.get('text-writing-mode');
        if (writingModes) {
            // remove duplicates, preserving order
            const deduped = [];
            for (const m of writingModes) {
                if (deduped.indexOf(m) < 0) deduped.push(m);
            }
            this.layout._values['text-writing-mode'] = deduped;
        } else if (this.layout.get('symbol-placement') === 'point') {
            // default value for 'point' placement symbols
            this.layout._values['text-writing-mode'] = ['horizontal'];
        } else {
            // default value for 'line' placement symbols
            this.layout._values['text-writing-mode'] = ['horizontal', 'vertical'];
        }

        this._setPaintOverrides();
    }

    getValueAndResolveTokens(name     , feature         , canonical                 , availableImages               )         {
        const value = this.layout.get(name).evaluate(feature, {}, canonical, availableImages);
        const unevaluated = this._unevaluatedLayout._values[name];
        if (!unevaluated.isDataDriven() && !isExpression(unevaluated.value) && value) {
            return resolveTokens(feature.properties, value);
        }

        return value;
    }

    createBucket(parameters                                    )               {
        return new SymbolBucket$1(parameters);
    }

    // $FlowFixMe[method-unbinding]
    queryRadius()         {
        return 0;
    }

    // $FlowFixMe[method-unbinding]
    queryIntersectsFeature()          {
        assert$1(false); // Should take a different path in FeatureIndex
        return false;
    }

    _setPaintOverrides() {
        for (const overridable of properties$3.paint.overridableProperties) {
            if (!SymbolStyleLayer.hasPaintOverride(this.layout, overridable)) {
                continue;
            }
            const overriden = this.paint.get(overridable);
            const override = new FormatSectionOverride(overriden);
            const styleExpression = new StyleExpression(override, overriden.property.specification);
            let expression = null;
            if (overriden.value.kind === 'constant' || overriden.value.kind === 'source') {
                // $FlowFixMe[method-unbinding]
                expression = (new ZoomConstantExpression('source', styleExpression)                  );
            } else {
                // $FlowFixMe[method-unbinding]
                expression = (new ZoomDependentExpression('composite',
                                                          styleExpression,
                                                          overriden.value.zoomStops,
                                                          overriden.value._interpolationType)                     );
            }
            // $FlowFixMe[prop-missing]
            this.paint._values[overridable] = new PossiblyEvaluatedPropertyValue(overriden.property,
                                                                                 expression,
                                                                                 overriden.parameters);
        }
    }

    _handleOverridablePaintPropertyUpdate      (name        , oldValue                     , newValue                     )          {
        if (!this.layout || oldValue.isDataDriven() || newValue.isDataDriven()) {
            return false;
        }
        return SymbolStyleLayer.hasPaintOverride(this.layout, name);
    }

    static hasPaintOverride(layout                                , propertyName        )          {
        const textField = layout.get('text-field');
        const property = properties$3.paint.properties[propertyName];
        let hasOverrides = false;

        const checkSections = (sections                                                             ) => {
            for (const section of sections) {
                if (property.overrides && property.overrides.hasOverride(section)) {
                    hasOverrides = true;
                    return;
                }
            }
        };

        if (textField.value.kind === 'constant' && textField.value.value instanceof Formatted) {
            checkSections(textField.value.value.sections);
        } else if (textField.value.kind === 'source') {

            const checkExpression = (expression            ) => {
                if (hasOverrides) return;

                if (expression instanceof Literal && typeOf(expression.value) === FormattedType) {
                    const formatted            = ((expression.value)     );
                    checkSections(formatted.sections);
                } else if (expression instanceof FormatExpression) {
                    checkSections(expression.sections);
                } else {
                    expression.eachChild(checkExpression);
                }
            };

            const expr                                   = ((textField.value)     );
            if (expr._styleExpression) {
                checkExpression(expr._styleExpression.expression);
            }
        }

        return hasOverrides;
    }

    getProgramConfiguration(zoom        )                       {
        return new ProgramConfiguration(this, zoom);
    }
}

// This file is generated. Edit build/generate-style-code.js, then run `yarn run codegen`.
//      
/* eslint-disable */


                                                        

                                                                            

                                                                                     


                           
                                                    
                                                               
                                                       
   

const paint$2                         = new Properties({
    "background-color": new DataConstantProperty(spec["paint_background"]["background-color"]),
    "background-pattern": new DataConstantProperty(spec["paint_background"]["background-pattern"]),
    "background-opacity": new DataConstantProperty(spec["paint_background"]["background-opacity"]),
});

// Note: without adding the explicit type annotation, Flow infers weaker types
// for these objects from their use in the constructor to StyleLayer, as
// {layout?: Properties<...>, paint: Properties<...>}
var properties$2 = ({ paint: paint$2 }          
                               
  );

//      


                                                                       
                                                                  

class BackgroundStyleLayer extends StyleLayer {
                                                     
                                                   
                                         

    constructor(layer                    ) {
        super(layer, properties$2);
    }

    getProgramIds()                {
        const image = this.paint.get('background-pattern');
        return [image ? 'backgroundPattern' : 'background'];
    }
}

// This file is generated. Edit build/generate-style-code.js, then run `yarn run codegen`.
//      
/* eslint-disable */


                                                        

                                                                            

                                                                                     


                           
                                                   
                                                      
                                                          
                                                          
                                                      
                                                    
                                                                    
                                                         
   

const paint$1                         = new Properties({
    "raster-opacity": new DataConstantProperty(spec["paint_raster"]["raster-opacity"]),
    "raster-hue-rotate": new DataConstantProperty(spec["paint_raster"]["raster-hue-rotate"]),
    "raster-brightness-min": new DataConstantProperty(spec["paint_raster"]["raster-brightness-min"]),
    "raster-brightness-max": new DataConstantProperty(spec["paint_raster"]["raster-brightness-max"]),
    "raster-saturation": new DataConstantProperty(spec["paint_raster"]["raster-saturation"]),
    "raster-contrast": new DataConstantProperty(spec["paint_raster"]["raster-contrast"]),
    "raster-resampling": new DataConstantProperty(spec["paint_raster"]["raster-resampling"]),
    "raster-fade-duration": new DataConstantProperty(spec["paint_raster"]["raster-fade-duration"]),
});

// Note: without adding the explicit type annotation, Flow infers weaker types
// for these objects from their use in the constructor to StyleLayer, as
// {layout?: Properties<...>, paint: Properties<...>}
var properties$1 = ({ paint: paint$1 }          
                               
  );

//      


                                                                   
                                                                  

class RasterStyleLayer extends StyleLayer {
                                                     
                                                   
                                         

    constructor(layer                    ) {
        super(layer, properties$1);
    }

    getProgramIds()                {
        return ['raster'];
    }
}

//      

                                                           
                                                                       

                                                                                                                                                                                                                                                                                

/**
 * Interface for custom style layers. This is a specification for
 * implementers to model: it is not an exported method or class.
 *
 * Custom layers allow a user to render directly into the map's GL context using the map's camera.
 * These layers can be added between any regular layers using {@link Map#addLayer}.
 *
 * Custom layers must have a unique `id` and must have the `type` of `"custom"`.
 * They must implement `render` and may implement `prerender`, `onAdd` and `onRemove`.
 * They can trigger rendering using {@link Map#triggerRepaint}
 * and they should appropriately handle {@link Map.event:webglcontextlost} and
 * {@link Map.event:webglcontextrestored}.
 *
 * The `renderingMode` property controls whether the layer is treated as a `"2d"` or `"3d"` map layer. Use:
 * - `"renderingMode": "3d"` to use the depth buffer and share it with other layers
 * - `"renderingMode": "2d"` to add a layer with no depth. If you need to use the depth buffer for a `"2d"` layer you must use an offscreen
 *   framebuffer and {@link CustomLayerInterface#prerender}.
 *
 * @interface CustomLayerInterface
 * @property {string} id A unique layer id.
 * @property {string} type The layer's type. Must be `"custom"`.
 * @property {string} renderingMode Either `"2d"` or `"3d"`. Defaults to `"2d"`.
 * @example
 * // Custom layer implemented as ES6 class
 * class NullIslandLayer {
 *     constructor() {
 *         this.id = 'null-island';
 *         this.type = 'custom';
 *         this.renderingMode = '2d';
 *     }
 *
 *     onAdd(map, gl) {
 *         const vertexSource = `
 *         uniform mat4 u_matrix;
 *         void main() {
 *             gl_Position = u_matrix * vec4(0.5, 0.5, 0.0, 1.0);
 *             gl_PointSize = 20.0;
 *         }`;
 *
 *         const fragmentSource = `
 *         void main() {
 *             gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
 *         }`;
 *
 *         const vertexShader = gl.createShader(gl.VERTEX_SHADER);
 *         gl.shaderSource(vertexShader, vertexSource);
 *         gl.compileShader(vertexShader);
 *         const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
 *         gl.shaderSource(fragmentShader, fragmentSource);
 *         gl.compileShader(fragmentShader);
 *
 *         this.program = gl.createProgram();
 *         gl.attachShader(this.program, vertexShader);
 *         gl.attachShader(this.program, fragmentShader);
 *         gl.linkProgram(this.program);
 *     }
 *
 *     render(gl, matrix) {
 *         gl.useProgram(this.program);
 *         gl.uniformMatrix4fv(gl.getUniformLocation(this.program, "u_matrix"), false, matrix);
 *         gl.drawArrays(gl.POINTS, 0, 1);
 *     }
 * }
 *
 * map.on('load', () => {
 *     map.addLayer(new NullIslandLayer());
 * });
 * @see [Example: Add a custom style layer](https://docs.mapbox.com/mapbox-gl-js/example/custom-style-layer/)
 * @see [Example: Add a 3D model](https://docs.mapbox.com/mapbox-gl-js/example/add-3d-model/)
 */

/**
 * Optional method called when the layer has been added to the Map with {@link Map#addLayer}. This
 * gives the layer a chance to initialize gl resources and register event listeners.
 *
 * @function
 * @memberof CustomLayerInterface
 * @instance
 * @name onAdd
 * @param {Map} map The Map this custom layer was just added to.
 * @param {WebGLRenderingContext} gl The gl context for the map.
 */

/**
 * Optional method called when the layer has been removed from the Map with {@link Map#removeLayer}. This
 * gives the layer a chance to clean up gl resources and event listeners.
 *
 * @function
 * @memberof CustomLayerInterface
 * @instance
 * @name onRemove
 * @param {Map} map The Map this custom layer was just added to.
 * @param {WebGLRenderingContext} gl The gl context for the map.
 */

/**
 * Optional method called during a render frame to allow a layer to prepare resources or render into a texture.
 *
 * The layer cannot make any assumptions about the current GL state and must bind a framebuffer before rendering.
 *
 * @function
 * @memberof CustomLayerInterface
 * @instance
 * @name prerender
 * @param {WebGLRenderingContext} gl The map's gl context.
 * @param {Array<number>} matrix The map's camera matrix. It projects spherical mercator
 * coordinates to gl coordinates. The mercator coordinate `[0, 0]` represents the
 * top left corner of the mercator world and `[1, 1]` represents the bottom right corner. When
 * the `renderingMode` is `"3d"`, the z coordinate is conformal. A box with identical x, y, and z
 * lengths in mercator units would be rendered as a cube. {@link MercatorCoordinate}.fromLngLat
 * can be used to project a `LngLat` to a mercator coordinate.
 */

/**
 * Called during a render frame allowing the layer to draw into the GL context.
 *
 * The layer can assume blending and depth state is set to allow the layer to properly
 * blend and clip other layers. The layer cannot make any other assumptions about the
 * current GL state.
 *
 * If the layer needs to render to a texture, it should implement the `prerender` method
 * to do this and only use the `render` method for drawing directly into the main framebuffer.
 *
 * The blend function is set to `gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)`. This expects
 * colors to be provided in premultiplied alpha form where the `r`, `g` and `b` values are already
 * multiplied by the `a` value. If you are unable to provide colors in premultiplied form you
 * may want to change the blend function to
 * `gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA)`.
 *
 * @function
 * @memberof CustomLayerInterface
 * @instance
 * @name render
 * @param {WebGLRenderingContext} gl The map's gl context.
 * @param {Array<number>} matrix The map's camera matrix. It projects spherical mercator
 * coordinates to gl coordinates. The spherical mercator coordinate `[0, 0]` represents the
 * top left corner of the mercator world and `[1, 1]` represents the bottom right corner. When
 * the `renderingMode` is `"3d"`, the z coordinate is conformal. A box with identical x, y, and z
 * lengths in mercator units would be rendered as a cube. {@link MercatorCoordinate}.fromLngLat
 * can be used to project a `LngLat` to a mercator coordinate.
 */
                                    
               
                   
                               
                               
                                   
                                                                                   
                                        
                                                          
                                                            
 

function validateCustomStyleLayer(layerObject                      )                   {
    const errors = [];
    const id = layerObject.id;

    if (id === undefined) {
        errors.push({
            message: `layers.${id}: missing required property "id"`
        });
    }

    if (layerObject.render === undefined) {
        errors.push({
            message: `layers.${id}: missing required method "render"`
        });
    }

    if (layerObject.renderingMode &&
        layerObject.renderingMode !== '2d' &&
        layerObject.renderingMode !== '3d') {
        errors.push({
            message: `layers.${id}: property "renderingMode" must be either "2d" or "3d"`
        });
    }

    return errors;
}

class CustomStyleLayer extends StyleLayer {

                                         

    constructor(implementation                      ) {
        super(implementation, {});
        this.implementation = implementation;
    }

    is3D()          {
        return this.implementation.renderingMode === '3d';
    }

    hasOffscreenPass()          {
        return this.implementation.prerender !== undefined;
    }

    isLayerDraped()          {
        return this.implementation.renderToTile !== undefined;
    }

    shouldRedrape()          {
        return !!this.implementation.shouldRerenderTiles && this.implementation.shouldRerenderTiles();
    }

    recalculate() {}
    updateTransitions() {}
    hasTransition()          {
        return false;
    }

    // $FlowFixMe[incompatible-extend] - CustomStyleLayer is not serializable
    serialize() {
        assert$1(false, "Custom layers cannot be serialized");
    }

    // $FlowFixMe[method-unbinding]
    onAdd(map     ) {
        if (this.implementation.onAdd) {
            this.implementation.onAdd(map, map.painter.context.gl);
        }
    }

    // $FlowFixMe[method-unbinding]
    onRemove(map     ) {
        if (this.implementation.onRemove) {
            this.implementation.onRemove(map, map.painter.context.gl);
        }
    }
}

// This file is generated. Edit build/generate-style-code.js, then run `yarn run codegen`.
//      
/* eslint-disable */


                                                        

                                                                            

                                                                                     


                           
                                                                
                                                                 
                                                                 
                                                                  
                                                        
                                      
                                                             
                                                        
                                                
   

const paint                         = new Properties({
    "sky-type": new DataConstantProperty(spec["paint_sky"]["sky-type"]),
    "sky-atmosphere-sun": new DataConstantProperty(spec["paint_sky"]["sky-atmosphere-sun"]),
    "sky-atmosphere-sun-intensity": new DataConstantProperty(spec["paint_sky"]["sky-atmosphere-sun-intensity"]),
    "sky-gradient-center": new DataConstantProperty(spec["paint_sky"]["sky-gradient-center"]),
    "sky-gradient-radius": new DataConstantProperty(spec["paint_sky"]["sky-gradient-radius"]),
    "sky-gradient": new ColorRampProperty(spec["paint_sky"]["sky-gradient"]),
    "sky-atmosphere-halo-color": new DataConstantProperty(spec["paint_sky"]["sky-atmosphere-halo-color"]),
    "sky-atmosphere-color": new DataConstantProperty(spec["paint_sky"]["sky-atmosphere-color"]),
    "sky-opacity": new DataConstantProperty(spec["paint_sky"]["sky-opacity"]),
});

// Note: without adding the explicit type annotation, Flow infers weaker types
// for these objects from their use in the constructor to StyleLayer, as
// {layout?: Properties<...>, paint: Properties<...>}
var properties = ({ paint }          
                               
  );

//      


function getCelestialDirection(azimuth        , altitude        , leftHanded         ) {
    const up = [0, 0, 1];
    const rotation = identity$2([]);

    rotateY$1(rotation, rotation, leftHanded ? -degToRad(azimuth) + Math.PI : degToRad(azimuth));
    rotateX$1(rotation, rotation, -degToRad(altitude));
    transformQuat$1(up, up, rotation);

    return normalize$4(up, up);
}

class SkyLayer extends StyleLayer {
                                                     
                                                   
                                         
                                  

                            
                                 
                                 

                         
                               

                                   

    constructor(layer                    ) {
        super(layer, properties);
        this._updateColorRamp();
    }

    _handleSpecialPaintPropertyUpdate(name        ) {
        if (name === 'sky-gradient') {
            this._updateColorRamp();
        } else if (name === 'sky-atmosphere-sun' ||
                   name === 'sky-atmosphere-halo-color' ||
                   name === 'sky-atmosphere-color' ||
                   name === 'sky-atmosphere-sun-intensity') {
            this._skyboxInvalidated = true;
        }
    }

    _updateColorRamp() {
        const expression = this._transitionablePaint._values['sky-gradient'].value.expression;
        this.colorRamp = renderColorRamp({
            expression,
            evaluationKey: 'skyRadialProgress'
        });
        if (this.colorRampTexture) {
            this.colorRampTexture.destroy();
            this.colorRampTexture = null;
        }
    }

    needsSkyboxCapture(painter         )          {
        if (!!this._skyboxInvalidated || !this.skyboxTexture || !this.skyboxGeometry) {
            return true;
        }
        if (!this.paint.get('sky-atmosphere-sun')) {
            const lightPosition = painter.style.light.properties.get('position');
            return this._lightPosition.azimuthal !== lightPosition.azimuthal ||
                   this._lightPosition.polar !== lightPosition.polar;
        }
        return false;
    }

    getCenter(painter         , leftHanded         )                           {
        const type = this.paint.get('sky-type');
        if (type === 'atmosphere') {
            const sunPosition = this.paint.get('sky-atmosphere-sun');
            const useLightPosition = !sunPosition;
            const light = painter.style.light;
            const lightPosition = light.properties.get('position');

            if (useLightPosition && light.properties.get('anchor') === 'viewport') {
                warnOnce('The sun direction is attached to a light with viewport anchor, lighting may behave unexpectedly.');
            }

            return useLightPosition ?
                getCelestialDirection(lightPosition.azimuthal, -lightPosition.polar + 90, leftHanded) :
                getCelestialDirection(sunPosition[0], -sunPosition[1] + 90, leftHanded);
        }
        assert$1(type === 'gradient');
        const direction = this.paint.get('sky-gradient-center');
        return getCelestialDirection(direction[0], -direction[1] + 90, leftHanded);
    }

    is3D()          {
        return false;
    }

    isSky()          {
        return true;
    }

    markSkyboxValid(painter         ) {
        this._skyboxInvalidated = false;
        this._lightPosition = painter.style.light.properties.get('position');
    }

    hasOffscreenPass()          {
        return true;
    }

    getProgramIds()                  {
        const type = this.paint.get('sky-type');
        if (type === 'atmosphere') {
            return ['skyboxCapture', 'skybox'];
        } else if (type === 'gradient') {
            return ['skyboxGradient'];
        }
        return null;
    }
}

//      

                                                                              

                                                               

const subclasses = {
    circle: CircleStyleLayer,
    heatmap: HeatmapStyleLayer,
    hillshade: HillshadeStyleLayer,
    fill: FillStyleLayer,
    'fill-extrusion': FillExtrusionStyleLayer,
    line: LineStyleLayer,
    symbol: SymbolStyleLayer,
    background: BackgroundStyleLayer,
    raster: RasterStyleLayer,
    sky: SkyLayer
};

function createStyleLayer(layer                                           )                                {
    if (layer.type === 'custom') {
        return new CustomStyleLayer(layer);
    } else {
        return new subclasses[layer.type](layer);
    }
}

//      


                                            
                                                            

                           
                                                  
                                                    
                           
                                                    
                                                                   
                                                      
                         
                                                    
                                                           
                                                              

                   
                  
                   
              
 

                          
               
                
                      
                       
                      
               
                
                  

class Texture {
                     
                           
                          
                          
                           
                       
                       

    constructor(context         , image              , format               , options                                                 ) {
        this.context = context;
        this.format = format;
        this.texture = ((context.gl.createTexture()     )              );
        this.update(image, options);
    }

    update(image              , options                                               , position                           ) {
        const {width, height} = image;
        const {context} = this;
        const {gl} = context;
        const {HTMLImageElement, HTMLCanvasElement, HTMLVideoElement, ImageData, ImageBitmap} = window$1;

        gl.bindTexture(gl.TEXTURE_2D, this.texture);

        context.pixelStoreUnpackFlipY.set(false);
        context.pixelStoreUnpack.set(1);
        context.pixelStoreUnpackPremultiplyAlpha.set(this.format === gl.RGBA && (!options || options.premultiply !== false));

        if (!position && (!this.size || this.size[0] !== width || this.size[1] !== height)) {
            this.size = [width, height];

            if (image instanceof HTMLImageElement || image instanceof HTMLCanvasElement || image instanceof HTMLVideoElement || image instanceof ImageData || (ImageBitmap && image instanceof ImageBitmap)) {
                gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.format, gl.UNSIGNED_BYTE, image);
            } else {
                // $FlowFixMe prop-missing - Flow can't refine image type here
                gl.texImage2D(gl.TEXTURE_2D, 0, this.format, width, height, 0, this.format, gl.UNSIGNED_BYTE, image.data);
            }

        } else {
            const {x, y} = position || {x: 0, y: 0};
            if (image instanceof HTMLImageElement || image instanceof HTMLCanvasElement || image instanceof HTMLVideoElement || image instanceof ImageData || (ImageBitmap && image instanceof ImageBitmap)) {
                gl.texSubImage2D(gl.TEXTURE_2D, 0, x, y, gl.RGBA, gl.UNSIGNED_BYTE, image);
            } else {
                // $FlowFixMe prop-missing - Flow can't refine image type here
                gl.texSubImage2D(gl.TEXTURE_2D, 0, x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, image.data);
            }
        }

        this.useMipmap = Boolean(options && options.useMipmap && this.isSizePowerOfTwo());
        if (this.useMipmap) {
            gl.generateMipmap(gl.TEXTURE_2D);
        }
    }

    bind(filter               , wrap             ) {
        const {context} = this;
        const {gl} = context;
        gl.bindTexture(gl.TEXTURE_2D, this.texture);

        if (filter !== this.filter) {
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,
                this.useMipmap ? (filter === gl.NEAREST ? gl.NEAREST_MIPMAP_NEAREST : gl.LINEAR_MIPMAP_NEAREST) : filter
            );
            this.filter = filter;
        }

        if (wrap !== this.wrap) {
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap);
            this.wrap = wrap;
        }
    }

    isSizePowerOfTwo()          {
        return this.size[0] === this.size[1] && (Math.log(this.size[0]) / Math.LN2) % 1 === 0;
    }

    destroy() {
        const {gl} = this.context;
        gl.deleteTexture(this.texture);
        this.texture = (null     );
    }
}

//      

/**
 * Invokes the wrapped function in a non-blocking way when trigger() is called. Invocation requests
 * are ignored until the function was actually invoked.
 *
 * @private
 */
class ThrottledInvoker {
                              
                        
                       

    constructor(callback          ) {
        this._callback = callback;
        this._triggered = false;
        if (typeof MessageChannel !== 'undefined') {
            this._channel = new MessageChannel();
            this._channel.port2.onmessage = () => {
                this._triggered = false;
                this._callback();
            };
        }
    }

    trigger() {
        if (!this._triggered) {
            this._triggered = true;
            if (this._channel) {
                this._channel.port1.postMessage(true);
            } else {
                setTimeout(() => {
                    this._triggered = false;
                    this._callback();
                }, 0);
            }
        }
    }

    remove() {
        this._channel = undefined;
        this._callback = () => {};
    }
}

//      


                                                       

                     
                                                   
                           
                 
  

                               

             
                     
                           
                     
              
  

class Scheduler {

                              
                             
                              
                   

    constructor() {
        this.tasks = {};
        this.taskQueue = [];
        bindAll(['process'], this);
        // $FlowFixMe[method-unbinding]
        this.invoker = new ThrottledInvoker(this.process);

        this.nextId = 0;
    }

    add(fn              , metadata              )             {
        const id = this.nextId++;
        const priority = getPriority(metadata);

        if (priority === 0) {
            // Process tasks with priority 0 immediately. Do not yield to the event loop.
            const m = isWorker() ? PerformanceUtils.beginMeasure('workerTask') : undefined;
            try {
                fn();
            } finally {
                if (m) PerformanceUtils.endMeasure(m);
            }
            return {
                cancel: () => {}
            };
        }

        this.tasks[id] = {fn, metadata, priority, id};
        this.taskQueue.push(id);
        this.invoker.trigger();
        return {
            cancel: () => {
                delete this.tasks[id];
            }
        };
    }

    process() {
        const m = isWorker() ? PerformanceUtils.beginMeasure('workerTask') : undefined;
        try {
            this.taskQueue = this.taskQueue.filter(id => !!this.tasks[id]);

            if (!this.taskQueue.length) {
                return;
            }
            const id = this.pick();
            if (id === null) return;

            const task = this.tasks[id];
            delete this.tasks[id];
            // Schedule another process call if we know there's more to process _before_ invoking the
            // current task. This is necessary so that processing continues even if the current task
            // doesn't execute successfully.
            if (this.taskQueue.length) {
                this.invoker.trigger();
            }
            if (!task) {
                // If the task ID doesn't have associated task data anymore, it was canceled.
                return;
            }

            task.fn();
        } finally {
            if (m) PerformanceUtils.endMeasure(m);
        }
    }

    pick()                {
        let minIndex = null;
        let minPriority = Infinity;
        for (let i = 0; i < this.taskQueue.length; i++) {
            const id = this.taskQueue[i];
            const task = this.tasks[id];
            if (task.priority < minPriority) {
                minPriority = task.priority;
                minIndex = i;
            }
        }
        if (minIndex === null) return null;
        const id = this.taskQueue[minIndex];
        this.taskQueue.splice(minIndex, 1);
        return id;
    }

    remove() {
        this.invoker.remove();
    }
}

function getPriority({type, isSymbolTile, zoom}              )         {
    zoom = zoom || 0;
    if (type === 'message') return 0;
    if (type === 'maybePrepare' && !isSymbolTile) return 100 - zoom;
    if (type === 'parseTile' && !isSymbolTile) return 200 - zoom;
    if (type === 'parseTile' && isSymbolTile) return 300 - zoom;
    if (type === 'maybePrepare' && isSymbolTile) return 400 - zoom;
    return 500;
}

//      


                                                           
                                                       

/**
 * An implementation of the [Actor design pattern](http://en.wikipedia.org/wiki/Actor_model)
 * that maintains the relationship between asynchronous tasks and the objects
 * that spin them off - in this case, tasks like parsing parts of styles,
 * owned by the styles
 *
 * @param {WebWorker} target
 * @param {WebWorker} parent
 * @param {string|number} mapId A unique identifier for the Map instance using this Actor.
 * @private
 */
class Actor {
                
                
                   
                               
                 
                                            
                     
                         

    constructor(target     , parent     , mapId         ) {
        this.target = target;
        this.parent = parent;
        this.mapId = mapId;
        this.callbacks = {};
        this.cancelCallbacks = {};
        bindAll(['receive'], this);
        // $FlowFixMe[method-unbinding]
        this.target.addEventListener('message', this.receive, false);
        this.globalScope = isWorker() ? target : window$1;
        this.scheduler = new Scheduler();
    }

    /**
     * Sends a message from a main-thread map to a Worker or from a Worker back to
     * a main-thread map instance.
     *
     * @param type The name of the target method to invoke or '[source-type].[source-name].name' for a method on a WorkerSource.
     * @param targetMapId A particular mapId to which to send this message.
     * @private
     */
    send(type        , data       , callback           , targetMapId         , mustQueue          = false, callbackMetadata         )              {
        // We're using a string ID instead of numbers because they are being used as object keys
        // anyway, and thus stringified implicitly. We use random IDs because an actor may receive
        // message from multiple other actors which could run in different execution context. A
        // linearly increasing ID could produce collisions.
        const id = Math.round((Math.random() * 1e18)).toString(36).substring(0, 10);
        if (callback) {
            callback.metadata = callbackMetadata;
            this.callbacks[id] = callback;
        }
        const buffers                       = isSafari(this.globalScope) ? undefined : [];
        this.target.postMessage({
            id,
            type,
            hasCallback: !!callback,
            targetMapId,
            mustQueue,
            sourceMapId: this.mapId,
            data: serialize(data, buffers)
        }, buffers);
        return {
            cancel: () => {
                if (callback) {
                    // Set the callback to null so that it never fires after the request is aborted.
                    delete this.callbacks[id];
                }
                this.target.postMessage({
                    id,
                    type: '<cancel>',
                    targetMapId,
                    sourceMapId: this.mapId
                });
            }
        };
    }

    receive(message        ) {
        const data = message.data,
            id = data.id;

        if (!id) {
            return;
        }

        if (data.targetMapId && this.mapId !== data.targetMapId) {
            return;
        }

        if (data.type === '<cancel>') {
            // Remove the original request from the queue. This is only possible if it
            // hasn't been kicked off yet. The id will remain in the queue, but because
            // there is no associated task, it will be dropped once it's time to execute it.
            const cancel = this.cancelCallbacks[id];
            delete this.cancelCallbacks[id];
            if (cancel) {
                cancel.cancel();
            }
        } else {
            if (data.mustQueue || isWorker()) {
                // for worker tasks that are often cancelled, such as loadTile, store them before actually
                // processing them. This is necessary because we want to keep receiving <cancel> messages.
                // Some tasks may take a while in the worker thread, so before executing the next task
                // in our queue, postMessage preempts this and <cancel> messages can be processed.
                // We're using a MessageChannel object to get throttle the process() flow to one at a time.
                const callback = this.callbacks[id];
                const metadata = (callback && callback.metadata) || {type: "message"};
                this.cancelCallbacks[id] = this.scheduler.add(() => this.processTask(id, data), metadata);
            } else {
                // In the main thread, process messages immediately so that other work does not slip in
                // between getting partial data back from workers.
                this.processTask(id, data);
            }
        }
    }

    processTask(id        , task     ) {
        if (task.type === '<response>') {
            // The done() function in the counterpart has been called, and we are now
            // firing the callback in the originating actor, if there is one.
            const callback = this.callbacks[id];
            delete this.callbacks[id];
            if (callback) {
                // If we get a response, but don't have a callback, the request was canceled.
                if (task.error) {
                    callback(deserialize$1(task.error));
                } else {
                    callback(null, deserialize$1(task.data));
                }
            }
        } else {
            const buffers                       = isSafari(this.globalScope) ? undefined : [];
            const done = task.hasCallback ? (err        , data       ) => {
                delete this.cancelCallbacks[id];
                this.target.postMessage({
                    id,
                    type: '<response>',
                    sourceMapId: this.mapId,
                    error: err ? serialize(err) : null,
                    data: serialize(data, buffers)
                }, buffers);
            } : (_) => {
            };

            const params = (deserialize$1(task.data)     );
            if (this.parent[task.type]) {
                // task.type == 'loadTile', 'removeTile', etc.
                this.parent[task.type](task.sourceMapId, params, done);
            } else if (this.parent.getWorkerSource) {
                // task.type == sourcetype.method
                const keys = task.type.split('.');
                const scope = (this.parent     ).getWorkerSource(task.sourceMapId, keys[0], params.source);
                scope[keys[1]](params, done);
            } else {
                // No function was found.
                done(new Error(`Could not find function ${task.type}`));
            }
        }
    }

    remove() {
        this.scheduler.remove();
        // $FlowFixMe[method-unbinding]
        this.target.removeEventListener('message', this.receive, false);
    }
}

//       strict


class DictionaryCoder {
                                            
                                   

    constructor(strings               ) {
        this._stringToNumber = {};
        this._numberToString = [];
        for (let i = 0; i < strings.length; i++) {
            const string = strings[i];
            this._stringToNumber[string] = i;
            this._numberToString[i] = string;
        }
    }

    encode(string        )         {
        assert$1(string in this._stringToNumber);
        return this._stringToNumber[string];
    }

    decode(n        )         {
        assert$1(n < this._numberToString.length);
        return this._numberToString[n];
    }
}

//      
                                                                                    
                                                                           
                                                            

// we augment GeoJSON with custom properties in query*Features results
                                                      
                                
                                           
                                   
                  
                         
 

const customProps = ['tile', 'layer', 'source', 'sourceLayer', 'state'];

class Feature {
                    
                                
                    
                               
                                           
               
               
               

                 
                               
                   
                        
                  

    constructor(vectorTileFeature                    , z        , x        , y        , id                        ) {
        this.type = 'Feature';

        this._vectorTileFeature = vectorTileFeature;
        this._z = z;
        this._x = x;
        this._y = y;

        this.properties = vectorTileFeature.properties;
        this.id = id;
    }

    get geometry()                   {
        if (this._geometry === undefined) {
            this._geometry = this._vectorTileFeature.toGeoJSON(this._x, this._y, this._z).geometry;
        }
        return this._geometry;
    }

    set geometry(g                  ) {
        this._geometry = g;
    }

    toJSON()               {
        const json               = {
            type: 'Feature',
            state: undefined,
            geometry: this.geometry,
            properties: this.properties
        };
        if (this.id !== undefined) json.id = this.id;
        for (const key of customProps) {
            // Flow doesn't support indexed access for classes https://github.com/facebook/flow/issues/1323
            if ((this     )[key] !== undefined) json[key] = (this     )[key];
        }
        return json;
    }
}

//      

                                                        
                                           
                                                                               
                                                   
                                            
                                                             
                                                      
                                                     
                                                          
                                                                       
                                                
                                                                    
                                                                              

                                                        
                  
                         
                 
                               
                       
                        
                                         
                             
                     
                           
                                       
 

                                  
                               
                         
                            
                          
                                   
                        
 

                              
                                
                               
                  
                             
 

                              
                  
                             
                                  
                       
                    
             
                                     
                    
   

/**
 * The `Bucket` interface is the single point of knowledge about turning vector
 * tiles into WebGL buffers.
 *
 * `Bucket` is an abstract interface. An implementation exists for each style layer type.
 * Create a bucket via the `StyleLayer#createBucket` method.
 *
 * The concrete bucket types, using layout options from the style layer,
 * transform feature geometries into vertex and index data for use by the
 * vertex shader.  They also (via `ProgramConfiguration`) use feature
 * properties and the zoom level to populate the attributes needed for
 * data-driven styling.
 *
 * Buckets are designed to be built on a worker thread and then serialized and
 * transferred back to the main thread for rendering.  On the worker side, a
 * bucket's vertex, index, and attribute data is stored in `bucket.arrays:
 * ArrayGroup`.  When a bucket's data is serialized and sent back to the main
 * thread, is gets deserialized (using `new Bucket(serializedBucketData)`, with
 * the array data now stored in `bucket.buffers: BufferGroup`.  BufferGroups
 * hold the same data as ArrayGroups, but are tuned for consumption by WebGL.
 *
 * @private
 */
                         
                            
                        
                        
                                      
                                           
                                                                                                                                           
                                                                                                                                    
                       

                                   
                             

       
                                                                                 
                                                                                
                                                                                   
      
               
       
                    
 

function deserialize(input               , style       )                        {
    const output = {};

    // Guard against the case where the map's style has been set to null while
    // this bucket has been parsing.
    if (!style) return output;

    for (const bucket of input) {
        const layers = bucket.layerIds
            .map((id) => style.getLayer(id))
            .filter(Boolean);

        if (layers.length === 0) {
            continue;
        }

        // look up StyleLayer objects from layer ids (since we don't
        // want to waste time serializing/copying them from the worker)
        (bucket     ).layers = layers;
        if ((bucket     ).stateDependentLayerIds) {
            (bucket     ).stateDependentLayers = (bucket     ).stateDependentLayerIds.map((lId) => layers.filter((l) => l.id === lId)[0]);
        }
        for (const layer of layers) {
            output[layer.id] = bucket;
        }
    }

    return output;
}

//      

                                          
                                                 
                                                
                                                         
                                                           
/**
 * This is a private namespace for utility functions that will get automatically stripped
 * out in production builds.
 *
 * @private
 */
const Debug   
                                    
                             
                     
                  
                           
                        
                         
                       
                        
                        
                                
  =
{
    extend(dest        , ...sources                )         {
        return extend$1(dest, ...sources);
    },

    run(fn           ) {
        fn();
    },

    logToElement(message        , overwrite          = false, id         = "log") {
        const el = window$1.document.getElementById(id);
        if (el) {
            if (overwrite) el.innerHTML = '';
            el.innerHTML += `<br>${message}`;
        }

    },

    debugCanvas: null,
    aabbCorners: [],

    _initializeCanvas(tr           ) {
        if (!Debug.debugCanvas) {
            Debug.debugCanvas = window$1.document.createElement('canvas');
            window$1.document.body.appendChild(Debug.debugCanvas);
            // Supress Flow check because we're checking for null above
            if (!Debug.debugCanvas) return;

            Debug.debugCanvas.style.position = 'absolute';
            Debug.debugCanvas.style.left = '0';
            Debug.debugCanvas.style.top = '0';
            Debug.debugCanvas.style.pointerEvents = 'none';

            const resize = () => {
                if (!Debug.debugCanvas) { return; }
                Debug.debugCanvas.width = tr.width;
                Debug.debugCanvas.height = tr.height;
            };
            resize();

            window$1.addEventListener("resize", resize);
        }
        return Debug.debugCanvas;
    },

    _drawLine(ctx                          , start       , end       ) {
        if (!start || !end) { return; }
        ctx.moveTo(...start);
        ctx.lineTo(...end);
    },

    _drawQuad(ctx                          , corners              ) {
        Debug._drawLine(ctx, corners[0], corners[1]);
        Debug._drawLine(ctx, corners[1], corners[2]);
        Debug._drawLine(ctx, corners[2], corners[3]);
        Debug._drawLine(ctx, corners[3], corners[0]);
    },

    _drawBox(ctx                          , corners              ) {
        assert$1(corners.length === 8, `AABB needs 8 corners, found ${corners.length}`);
        ctx.beginPath();
        Debug._drawQuad(ctx, corners.slice(0, 4));
        Debug._drawQuad(ctx, corners.slice(4));
        Debug._drawLine(ctx, corners[0], corners[4]);
        Debug._drawLine(ctx, corners[1], corners[5]);
        Debug._drawLine(ctx, corners[2], corners[6]);
        Debug._drawLine(ctx, corners[3], corners[7]);
        ctx.stroke();
    },

    drawAabbs(painter         , sourceCache             , coords                         ) {
        const tr = painter.transform;

        const worldToECEFMatrix = invert$2(new Float64Array(16), tr.globeMatrix);
        const ecefToPixelMatrix = multiply$5([], tr.pixelMatrix, tr.globeMatrix);
        const ecefToCameraMatrix = multiply$5([],  tr._camera.getWorldToCamera(tr.worldSize, 1), tr.globeMatrix);

        if (!tr.freezeTileCoverage) {
            Debug.aabbCorners = coords.map(coord => {
                // Get tile AABBs in world/pixel space scaled by worldSize
                const aabb = aabbForTileOnGlobe(tr, tr.worldSize, coord.canonical);
                const corners = aabb.getCorners();
                // Store AABBs as rectangular prisms in ECEF, this allows viewing them from other angles
                // when transform.freezeTileCoverage is enabled.
                for (const pos of corners) {
                    transformMat4$2(pos, pos, worldToECEFMatrix);
                }
                // $FlowFixMe[incompatible-type]
                return corners;
            });
        }

        const canvas = Debug._initializeCanvas(tr);
        const ctx = canvas.getContext('2d');
        ctx.clearRect(0, 0, canvas.width, canvas.height);

        const tileCount = Debug.aabbCorners.length;
        ctx.shadowColor = '#000';
        ctx.shadowBlur = 2;
        ctx.lineWidth = 1.5;

        for (let i = 0; i <  tileCount; i++) {
            const pixelCorners = Debug.aabbCorners[i].map(ecef => {
                // Clipping to prevent visual artifacts.
                // We don't draw any lines if one of their points is behind the camera.
                // This means that AABBs close to the camera may appear to be missing.
                // (A more correct algorithm would shorten the line segments instead of removing them entirely.)
                // Full AABBs can be viewed by enabling `map.transform.freezeTileCoverage` and panning.
                // $FlowFixMe[incompatible-call]
                const cameraPos = transformMat4$2([], ecef, ecefToCameraMatrix);

                // $FlowFixMe[incompatible-call]
                if (cameraPos[2] > 0) { return null; }

                // $FlowFixMe[incompatible-call]
                return transformMat4$2([], ecef, ecefToPixelMatrix);
            });
            ctx.strokeStyle = `hsl(${360 * i / tileCount}, 100%, 50%)`;
            Debug._drawBox(ctx, pixelCorners);
        }
    },

    clearAabbs() {
        if (!Debug.debugCanvas) return;
        // $FlowFixMe[incompatible-use] - Flow doesn't know that debugCanvas is non-null here
        Debug.debugCanvas.getContext('2d').clearRect(0, 0, Debug.debugCanvas.width, Debug.debugCanvas.height);
        Debug.aabbCorners = [];
    }
};

//      

                                                       
                                                     
                                                
                                            

/**
 * Helper class that can be used to draw debug geometry in tile-space
 *
 * @class TileSpaceDebugBuffer
 * @private
 */
class TileSpaceDebugBuffer {
                       
                                 
                     
                         
                 

                                
                              
                             

    constructor(tileSize        , color        = Color.red) {
        this.vertices = new StructArrayLayout2i4();
        this.indices = new StructArrayLayout1ui2();
        this.tileSize = tileSize;
        this.needsUpload = true;
        this.color = color;
    }

    addPoints(points         ) {
        this.clearPoints();
        for (const point of points) {
            this.addPoint(point);
        }
        this.addPoint(points[0]);
    }

    addPoint(p       ) {
        // Add a bowtie shape
        const crosshairSize = 80;
        const currLineLineLength = this.vertices.length;
        this.vertices.emplaceBack(p.x, p.y);
        this.vertices.emplaceBack(p.x + crosshairSize / 2, p.y);
        this.vertices.emplaceBack(p.x, p.y - crosshairSize / 2);
        this.vertices.emplaceBack(p.x, p.y + crosshairSize / 2);
        this.vertices.emplaceBack(p.x - crosshairSize / 2, p.y);
        this.indices.emplaceBack(currLineLineLength);
        this.indices.emplaceBack(currLineLineLength + 1);
        this.indices.emplaceBack(currLineLineLength + 2);
        this.indices.emplaceBack(currLineLineLength + 3);
        this.indices.emplaceBack(currLineLineLength + 4);
        this.indices.emplaceBack(currLineLineLength);

        this.needsUpload = true;
    }

    clearPoints() {
        this.vertices.clear();
        this.indices.clear();
        this.needsUpload = true;
    }

    lazyUpload(context         ) {
        if (this.needsUpload && this.hasVertices()) {
            this.unload();

            this.vertexBuffer = context.createVertexBuffer(this.vertices, posAttributes.members, true);
            this.indexBuffer = context.createIndexBuffer(this.indices, true);
            this.segments = SegmentVector.simpleSegment(0, 0, this.vertices.length, this.indices.length);
            this.needsUpload = false;
        }
    }

    hasVertices()          {
        return this.vertices.length > 1;
    }

    unload() {
        if (this.vertexBuffer) {
            this.vertexBuffer.destroy();
            delete this.vertexBuffer;
        }
        if (this.indexBuffer) {
            this.indexBuffer.destroy();
            delete this.indexBuffer;
        }
        if (this.segments) {
            this.segments.destroy();
            delete this.segments;
        }
    }
}

//      
// logic for generating non-Mercator adaptive raster tile reprojection meshes with MARTINI


                                                  
                                                              

const meshSize = 32;
const gridSize = meshSize + 1;

const numTriangles = meshSize * meshSize * 2 - 2;
const numParentTriangles = numTriangles - meshSize * meshSize;

const coords = new Uint16Array(numTriangles * 4);

// precalculate RTIN triangle coordinates
for (let i = 0; i < numTriangles; i++) {
    let id = i + 2;
    let ax = 0, ay = 0, bx = 0, by = 0, cx = 0, cy = 0;

    if (id & 1) {
        bx = by = cx = meshSize; // bottom-left triangle

    } else {
        ax = ay = cy = meshSize; // top-right triangle
    }

    while ((id >>= 1) > 1) {
        const mx = (ax + bx) >> 1;
        const my = (ay + by) >> 1;

        if (id & 1) { // left half
            bx = ax; by = ay;
            ax = cx; ay = cy;

        } else { // right half
            ax = bx; ay = by;
            bx = cx; by = cy;
        }

        cx = mx; cy = my;
    }

    const k = i * 4;
    coords[k + 0] = ax;
    coords[k + 1] = ay;
    coords[k + 2] = bx;
    coords[k + 3] = by;
}

// temporary arrays we'll reuse for MARTINI mesh code
const reprojectedCoords = new Uint16Array(gridSize * gridSize * 2);
const used = new Uint8Array(gridSize * gridSize);
const indexMap = new Uint16Array(gridSize * gridSize);

                 
                              
                               
  

// There can be visible seams between neighbouring tiles because of precision issues
// and resampling differences. Adding a bit of padding around the edges of tiles hides
// most of these issues.
const commonRasterTileSize = 256;
const paddingSize = meshSize / commonRasterTileSize / 4;
function seamPadding(n        ) {
    if (n === 0) return -paddingSize;
    else if (n === gridSize - 1) return paddingSize;
    else return 0;
}

function getTileMesh(canonical                 , projection            )           {
    const cs = tileTransform(canonical, projection);
    const z2 = Math.pow(2, canonical.z);

    for (let y = 0; y < gridSize; y++) {
        for (let x = 0; x < gridSize; x++) {
            const lng = lngFromMercatorX((canonical.x + (x + seamPadding(x)) / meshSize) / z2);
            const lat = latFromMercatorY((canonical.y + (y + seamPadding(y)) / meshSize) / z2);
            const p = projection.project(lng, lat);
            const k = y * gridSize + x;
            reprojectedCoords[2 * k + 0] = Math.round((p.x * cs.scale - cs.x) * EXTENT);
            reprojectedCoords[2 * k + 1] = Math.round((p.y * cs.scale - cs.y) * EXTENT);
        }
    }

    used.fill(0);
    indexMap.fill(0);

    // iterate over all possible triangles, starting from the smallest level
    for (let i = numTriangles - 1; i >= 0; i--) {
        const k = i * 4;
        const ax = coords[k + 0];
        const ay = coords[k + 1];
        const bx = coords[k + 2];
        const by = coords[k + 3];
        const mx = (ax + bx) >> 1;
        const my = (ay + by) >> 1;
        const cx = mx + my - ay;
        const cy = my + ax - mx;

        const aIndex = ay * gridSize + ax;
        const bIndex = by * gridSize + bx;
        const mIndex = my * gridSize + mx;

        // calculate error in the middle of the long edge of the triangle
        const rax = reprojectedCoords[2 * aIndex + 0];
        const ray = reprojectedCoords[2 * aIndex + 1];
        const rbx = reprojectedCoords[2 * bIndex + 0];
        const rby = reprojectedCoords[2 * bIndex + 1];
        const rmx = reprojectedCoords[2 * mIndex + 0];
        const rmy = reprojectedCoords[2 * mIndex + 1];

        // raster tiles are typically 512px, and we use 1px as an error threshold; 8192 / 512 = 16
        const isUsed = Math.hypot((rax + rbx) / 2 - rmx, (ray + rby) / 2 - rmy) >= 16;

        used[mIndex] = used[mIndex] || (isUsed ? 1 : 0);

        if (i < numParentTriangles) { // bigger triangles; accumulate error with children
            const leftChildIndex = ((ay + cy) >> 1) * gridSize + ((ax + cx) >> 1);
            const rightChildIndex = ((by + cy) >> 1) * gridSize + ((bx + cx) >> 1);
            used[mIndex] = used[mIndex] || used[leftChildIndex] || used[rightChildIndex];
        }
    }

    const vertices = new StructArrayLayout4i8();
    const indices = new StructArrayLayout3ui6();

    let numVertices = 0;

    function addVertex(x        , y        ) {
        const k = y * gridSize + x;

        if (indexMap[k] === 0) {
            vertices.emplaceBack(
                reprojectedCoords[2 * k + 0],
                reprojectedCoords[2 * k + 1],
                x * EXTENT / meshSize,
                y * EXTENT / meshSize);

            // save new vertex index so that we can reuse it
            indexMap[k] = ++numVertices;
        }

        return indexMap[k] - 1;
    }

    function addTriangles(ax        , ay        , bx        , by        , cx        , cy        ) {
        const mx = (ax + bx) >> 1;
        const my = (ay + by) >> 1;

        if (Math.abs(ax - cx) + Math.abs(ay - cy) > 1 && used[my * gridSize + mx]) {
            // triangle doesn't approximate the surface well enough; drill down further
            addTriangles(cx, cy, ax, ay, mx, my);
            addTriangles(bx, by, cx, cy, mx, my);

        } else {
            const ai = addVertex(ax, ay);
            const bi = addVertex(bx, by);
            const ci = addVertex(cx, cy);
            indices.emplaceBack(ai, bi, ci);
        }
    }

    addTriangles(0, 0, meshSize, meshSize, meshSize, 0);
    addTriangles(meshSize, meshSize, 0, 0, 0, meshSize);

    return {vertices, indices};
}

//      

                                                               

var boundsAttributes = (createLayout([
    {name: 'a_pos', type: 'Int16', components: 2},
    {name: 'a_texture_pos', type: 'Int16', components: 2}
])                   );

//      


                                              
                                                      
                                                         
                                          
                                               
                                                                  
                                                       
                                                     
                                                           
                                            
                                                                    
                                                    
                                                 
                                                          
                                                       
                                                                
                                                                       
                                                       
                                                     
                                                              
                                                                       
                                                          
                                                
                                                                   
                                    
                                                       
                                                         

const CLOCK_SKEW_RETRY_TIMEOUT = 30000;
                       
                                                            
                                                                     
                                                                                          
                                                
                                                                  
                  /* Tile data was previously loaded, but has expired per its
                   * HTTP headers and is in the process of refreshing. */

// a tile bounds outline used for getting reprojected tile geometry in non-mercator projections
const BOUNDS_FEATURE = (() => {
    return {
        type: 2,
        extent: EXTENT,
        loadGeometry() {
            return [[
                new Point$2(0, 0),
                new Point$2(EXTENT + 1, 0),
                new Point$2(EXTENT + 1, EXTENT + 1),
                new Point$2(0, EXTENT + 1),
                new Point$2(0, 0)
            ]];
        }
    };
})();

/**
 * A tile object is the combination of a Coordinate, which defines
 * its place, as well as a unique ID and data tracking for its content
 *
 * @private
 */
class Tile {
                             
                
                 
                     
                     
                                   
                                      
                                    
                            
                               
                          
                              
                                 
                               
                        
                                
                     
                   
                     
                                          
                          
                                
                         
                  
                                             
                           
                       
                                  

                              
                  
                      
                                    
                                    
                         
                 
                      
                         
                                     
                        
                                                      
                         

                                 
                              
                        
                         
                           

                                                 
                                               

                                    
                                     
                                        
                                        
                                      
                                       
                                               
                                        
                                          
                                           
                                             

    /**
     * @param {OverscaledTileID} tileID
     * @param size
     * @private
     */
    constructor(tileID                  , size        , tileZoom        , painter     , isRaster          ) {
        this.tileID = tileID;
        this.uid = uniqueId();
        this.uses = 0;
        this.tileSize = size;
        this.tileZoom = tileZoom;
        this.buckets = {};
        this.expirationTime = null;
        this.queryPadding = 0;
        this.hasSymbolBuckets = false;
        this.hasRTLText = false;
        this.dependencies = {};
        this.isRaster = isRaster;

        // Counts the number of times a response was already expired when
        // received. We're using this to add a delay when making a new request
        // so we don't have to keep retrying immediately in case of a server
        // serving expired tiles.
        this.expiredRequestCount = 0;

        this.state = 'loading';

        if (painter && painter.transform) {
            this.projection = painter.transform.projection;
        }
    }

    registerFadeDuration(duration        ) {
        const fadeEndTime = duration + this.timeAdded;
        if (fadeEndTime < exported.now()) return;
        if (this.fadeEndTime && fadeEndTime < this.fadeEndTime) return;

        this.fadeEndTime = fadeEndTime;
    }

    wasRequested()          {
        return this.state === 'errored' || this.state === 'loaded' || this.state === 'reloading';
    }

    get tileTransform()                {
        if (!this._tileTransform) {
            this._tileTransform = tileTransform(this.tileID.canonical, this.projection);
        }
        return this._tileTransform;
    }

    /**
     * Given a data object with a 'buffers' property, load it into
     * this tile's elementGroups and buffers properties and set loaded
     * to true. If the data is null, like in the case of an empty
     * GeoJSON tile, no-op but still set loaded to true.
     * @param {Object} data
     * @param painter
     * @returns {undefined}
     * @private
     */
    loadVectorData(data                   , painter     , justReloaded          ) {
        this.unloadVectorData();

        this.state = 'loaded';

        // empty GeoJSON tile
        if (!data) {
            this.collisionBoxArray = new CollisionBoxArray();
            return;
        }

        if (data.featureIndex) {
            this.latestFeatureIndex = data.featureIndex;
            if (data.rawTileData) {
                // Only vector tiles have rawTileData, and they won't update it for
                // 'reloadTile'
                this.latestRawTileData = data.rawTileData;
                this.latestFeatureIndex.rawTileData = data.rawTileData;
            } else if (this.latestRawTileData) {
                // If rawTileData hasn't updated, hold onto a pointer to the last
                // one we received
                this.latestFeatureIndex.rawTileData = this.latestRawTileData;
            }
        }
        this.collisionBoxArray = data.collisionBoxArray;
        this.buckets = deserialize(data.buckets, painter.style);

        this.hasSymbolBuckets = false;
        for (const id in this.buckets) {
            const bucket = this.buckets[id];
            if (bucket instanceof SymbolBucket$1) {
                this.hasSymbolBuckets = true;
                if (justReloaded) {
                    bucket.justReloaded = true;
                } else {
                    break;
                }
            }
        }

        this.hasRTLText = false;
        if (this.hasSymbolBuckets) {
            for (const id in this.buckets) {
                const bucket = this.buckets[id];
                if (bucket instanceof SymbolBucket$1) {
                    if (bucket.hasRTLText) {
                        this.hasRTLText = true;
                        lazyLoadRTLTextPlugin();
                        break;
                    }
                }
            }
        }

        this.queryPadding = 0;
        for (const id in this.buckets) {
            const bucket = this.buckets[id];
            this.queryPadding = Math.max(this.queryPadding, painter.style.getLayer(id).queryRadius(bucket));
        }

        if (data.imageAtlas) {
            this.imageAtlas = data.imageAtlas;
        }
        if (data.glyphAtlasImage) {
            this.glyphAtlasImage = data.glyphAtlasImage;
        }
        if (data.lineAtlas) {
            this.lineAtlas = data.lineAtlas;
        }
    }

    /**
     * Release any data or WebGL resources referenced by this tile.
     * @returns {undefined}
     * @private
     */
    unloadVectorData() {
        if (!this.hasData()) return;

        for (const id in this.buckets) {
            this.buckets[id].destroy();
        }
        this.buckets = {};

        if (this.imageAtlas) {
            this.imageAtlas = null;
        }

        if (this.lineAtlas) {
            this.lineAtlas = null;
        }

        if (this.imageAtlasTexture) {
            this.imageAtlasTexture.destroy();
        }

        if (this.glyphAtlasTexture) {
            this.glyphAtlasTexture.destroy();
        }

        if (this.lineAtlasTexture) {
            this.lineAtlasTexture.destroy();
        }

        if (this._tileBoundsBuffer) {
            this._tileBoundsBuffer.destroy();
            this._tileBoundsIndexBuffer.destroy();
            this._tileBoundsSegments.destroy();
            this._tileBoundsBuffer = null;
        }

        if (this._tileDebugBuffer) {
            this._tileDebugBuffer.destroy();
            this._tileDebugSegments.destroy();
            this._tileDebugBuffer = null;
        }

        if (this._tileDebugIndexBuffer) {
            this._tileDebugIndexBuffer.destroy();
            this._tileDebugIndexBuffer = null;
        }

        if (this._globeTileDebugBorderBuffer) {
            this._globeTileDebugBorderBuffer.destroy();
            this._globeTileDebugBorderBuffer = null;
        }

        if (this._tileDebugTextBuffer) {
            this._tileDebugTextBuffer.destroy();
            this._tileDebugTextSegments.destroy();
            this._tileDebugTextIndexBuffer.destroy();
            this._tileDebugTextBuffer = null;
        }

        if (this._globeTileDebugTextBuffer) {
            this._globeTileDebugTextBuffer.destroy();
            this._globeTileDebugTextBuffer = null;
        }

        Debug.run(() => {
            if (this.queryGeometryDebugViz) {
                this.queryGeometryDebugViz.unload();
                delete this.queryGeometryDebugViz;
            }
            if (this.queryBoundsDebugViz) {
                this.queryBoundsDebugViz.unload();
                delete this.queryBoundsDebugViz;
            }
        });
        this.latestFeatureIndex = null;
        this.state = 'unloaded';
    }

    getBucket(layer            )         {
        return this.buckets[layer.id];
    }

    upload(context         ) {
        for (const id in this.buckets) {
            const bucket = this.buckets[id];
            if (bucket.uploadPending()) {
                bucket.upload(context);
            }
        }

        const gl = context.gl;
        if (this.imageAtlas && !this.imageAtlas.uploaded) {
            this.imageAtlasTexture = new Texture(context, this.imageAtlas.image, gl.RGBA);
            ((this.imageAtlas     )            ).uploaded = true;
        }

        if (this.glyphAtlasImage) {
            this.glyphAtlasTexture = new Texture(context, this.glyphAtlasImage, gl.ALPHA);
            this.glyphAtlasImage = null;
        }

        if (this.lineAtlas && !this.lineAtlas.uploaded) {
            this.lineAtlasTexture = new Texture(context, this.lineAtlas.image, gl.ALPHA);
            ((this.lineAtlas     )           ).uploaded = true;
        }
    }

    prepare(imageManager              ) {
        if (this.imageAtlas) {
            this.imageAtlas.patchUpdatedImages(imageManager, this.imageAtlasTexture);
        }
    }

    // Queries non-symbol features rendered for this tile.
    // Symbol features are queried globally
    queryRenderedFeatures(layers                           ,
                          serializedLayers                    ,
                          sourceFeatureState                    ,
                          tileResult                        ,
                          params                                                                                        ,
                          transform           ,
                          pixelPosMatrix              ,
                          visualizeQueryGeometry         )              {
        Debug.run(() => {
            if (visualizeQueryGeometry) {
                let geometryViz = this.queryGeometryDebugViz;
                let boundsViz = this.queryBoundsDebugViz;
                if (!geometryViz) {
                    geometryViz = this.queryGeometryDebugViz = new TileSpaceDebugBuffer(this.tileSize);
                }
                if (!boundsViz) {
                    boundsViz = this.queryBoundsDebugViz = new TileSpaceDebugBuffer(this.tileSize, Color.blue);
                }

                geometryViz.addPoints(tileResult.tilespaceGeometry);
                boundsViz.addPoints(tileResult.bufferedTilespaceGeometry);
            }
        });

        if (!this.latestFeatureIndex || !this.latestFeatureIndex.rawTileData)
            return {};

        return this.latestFeatureIndex.query({
            tileResult,
            pixelPosMatrix,
            transform,
            params,
            tileTransform: this.tileTransform
        }, layers, serializedLayers, sourceFeatureState);
    }

    querySourceFeatures(result                     , params     ) {
        const featureIndex = this.latestFeatureIndex;
        if (!featureIndex || !featureIndex.rawTileData) return;

        const vtLayers = featureIndex.loadVTLayers();

        const sourceLayer = params ? params.sourceLayer : '';
        const layer = vtLayers._geojsonTileLayer || vtLayers[sourceLayer];

        if (!layer) return;

        const filter = createFilter(params && params.filter);
        const {z, x, y} = this.tileID.canonical;
        const coord = {z, x, y};

        for (let i = 0; i < layer.length; i++) {
            const feature = layer.feature(i);
            if (filter.needGeometry) {
                const evaluationFeature = toEvaluationFeature(feature, true);
                // $FlowFixMe[method-unbinding]
                if (!filter.filter(new EvaluationParameters(this.tileID.overscaledZ), evaluationFeature, this.tileID.canonical)) continue;
            // $FlowFixMe[method-unbinding]
            } else if (!filter.filter(new EvaluationParameters(this.tileID.overscaledZ), feature)) {
                continue;
            }
            const id = featureIndex.getId(feature, sourceLayer);
            const geojsonFeature = new Feature(feature, z, x, y, id);
            geojsonFeature.tile = coord;

            result.push(geojsonFeature);
        }
    }

    hasData()          {
        return this.state === 'loaded' || this.state === 'reloading' || this.state === 'expired';
    }

    patternsLoaded()          {
        return !!this.imageAtlas && !!Object.keys(this.imageAtlas.patternPositions).length;
    }

    setExpiryData(data     ) {
        const prior = this.expirationTime;

        if (data.cacheControl) {
            const parsedCC = parseCacheControl(data.cacheControl);
            if (parsedCC['max-age']) this.expirationTime = Date.now() + parsedCC['max-age'] * 1000;
        } else if (data.expires) {
            this.expirationTime = new Date(data.expires).getTime();
        }

        if (this.expirationTime) {
            const now = Date.now();
            let isExpired = false;

            if (this.expirationTime > now) {
                isExpired = false;
            } else if (!prior) {
                isExpired = true;
            } else if (this.expirationTime < prior) {
                // Expiring date is going backwards:
                // fall back to exponential backoff
                isExpired = true;

            } else {
                const delta = this.expirationTime - prior;

                if (!delta) {
                    // Server is serving the same expired resource over and over: fall
                    // back to exponential backoff.
                    isExpired = true;

                } else {
                    // Assume that either the client or the server clock is wrong and
                    // try to interpolate a valid expiration date (from the client POV)
                    // observing a minimum timeout.
                    this.expirationTime = now + Math.max(delta, CLOCK_SKEW_RETRY_TIMEOUT);

                }
            }

            if (isExpired) {
                this.expiredRequestCount++;
                this.state = 'expired';
            } else {
                this.expiredRequestCount = 0;
            }
        }
    }

    getExpiryTimeout()                {
        if (this.expirationTime) {
            if (this.expiredRequestCount) {
                return 1000 * (1 << Math.min(this.expiredRequestCount - 1, 31));
            } else {
                // Max value for `setTimeout` implementations is a 32 bit integer; cap this accordingly
                return Math.min(this.expirationTime - new Date().getTime(), Math.pow(2, 31) - 1);
            }
        }
    }

    setFeatureState(states                    , painter          ) {
        if (!this.latestFeatureIndex ||
            !this.latestFeatureIndex.rawTileData ||
            Object.keys(states).length === 0 ||
            !painter) {
            return;
        }

        const vtLayers = this.latestFeatureIndex.loadVTLayers();
        const availableImages = painter.style.listImages();

        for (const id in this.buckets) {
            if (!painter.style.hasLayer(id)) continue;

            const bucket = this.buckets[id];
            // Buckets are grouped by common source-layer
            const sourceLayerId = bucket.layers[0]['sourceLayer'] || '_geojsonTileLayer';
            const sourceLayer = vtLayers[sourceLayerId];
            const sourceLayerStates = states[sourceLayerId];
            if (!sourceLayer || !sourceLayerStates || Object.keys(sourceLayerStates).length === 0) continue;

            // $FlowFixMe[incompatible-type] Flow can't interpret ImagePosition as SpritePosition for some reason here
            const imagePositions                  = (this.imageAtlas && this.imageAtlas.patternPositions) || {};
            bucket.update(sourceLayerStates, sourceLayer, availableImages, imagePositions);
            if (bucket instanceof LineBucket || bucket instanceof FillBucket) {
                const sourceCache = painter.style._getSourceCache(bucket.layers[0].source);
                if (painter._terrain && painter._terrain.enabled && sourceCache && bucket.programConfigurations.needsUpload) {
                    painter._terrain._clearRenderCacheForTile(sourceCache.id, this.tileID);
                }
            }
            const layer = painter && painter.style && painter.style.getLayer(id);
            if (layer) {
                this.queryPadding = Math.max(this.queryPadding, layer.queryRadius(bucket));
            }
        }
    }

    holdingForFade()          {
        return this.symbolFadeHoldUntil !== undefined;
    }

    symbolFadeFinished()          {
        return !this.symbolFadeHoldUntil || this.symbolFadeHoldUntil < exported.now();
    }

    clearFadeHold() {
        this.symbolFadeHoldUntil = undefined;
    }

    setHoldDuration(duration        ) {
        this.symbolFadeHoldUntil = exported.now() + duration;
    }

    setTexture(img              , painter         ) {
        const context = painter.context;
        const gl = context.gl;
        this.texture = this.texture || painter.getTileTexture(img.width);
        if (this.texture) {
            this.texture.update(img, {useMipmap: true});
        } else {
            this.texture = new Texture(context, img, gl.RGBA, {useMipmap: true});
            this.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);
        }
    }

    setDependencies(namespace        , dependencies               ) {
        const index = {};
        for (const dep of dependencies) {
            index[dep] = true;
        }
        this.dependencies[namespace] = index;
    }

    hasDependency(namespaces               , keys               )          {
        for (const namespace of namespaces) {
            const dependencies = this.dependencies[namespace];
            if (dependencies) {
                for (const key of keys) {
                    if (dependencies[key]) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    clearQueryDebugViz() {
        Debug.run(() => {
            if (this.queryGeometryDebugViz) {
                this.queryGeometryDebugViz.clearPoints();
            }
            if (this.queryBoundsDebugViz) {
                this.queryBoundsDebugViz.clearPoints();
            }
        });
    }

    _makeDebugTileBoundsBuffers(context         , projection            ) {
        if (!projection || projection.name === 'mercator' || this._tileDebugBuffer) return;

        // reproject tile outline with adaptive resampling
        const boundsLine = loadGeometry(BOUNDS_FEATURE, this.tileID.canonical, this.tileTransform)[0];

        // generate vertices for debugging tile boundaries
        const debugVertices = new StructArrayLayout2i4();
        const debugIndices = new StructArrayLayout1ui2();

        for (let i = 0; i < boundsLine.length; i++) {
            const {x, y} = boundsLine[i];
            debugVertices.emplaceBack(x, y);
            debugIndices.emplaceBack(i);
        }
        debugIndices.emplaceBack(0);

        this._tileDebugIndexBuffer = context.createIndexBuffer(debugIndices);
        this._tileDebugBuffer = context.createVertexBuffer(debugVertices, posAttributes.members);
        this._tileDebugSegments = SegmentVector.simpleSegment(0, 0, debugVertices.length, debugIndices.length);
    }

    _makeTileBoundsBuffers(context         , projection            ) {
        if (this._tileBoundsBuffer || !projection || projection.name === 'mercator') return;

        // reproject tile outline with adaptive resampling
        const boundsLine = loadGeometry(BOUNDS_FEATURE, this.tileID.canonical, this.tileTransform)[0];

        let boundsVertices, boundsIndices;
        if (this.isRaster) {
            // for raster tiles, generate an adaptive MARTINI mesh
            const mesh = getTileMesh(this.tileID.canonical, projection);
            boundsVertices = mesh.vertices;
            boundsIndices = mesh.indices;

        } else {
            // for vector tiles, generate an Earcut triangulation of the outline
            boundsVertices = new StructArrayLayout4i8();
            boundsIndices = new StructArrayLayout3ui6();

            for (const {x, y} of boundsLine) {
                boundsVertices.emplaceBack(x, y, 0, 0);
            }
            const indices = earcut$1(boundsVertices.int16, undefined, 4);
            for (let i = 0; i < indices.length; i += 3) {
                boundsIndices.emplaceBack(indices[i], indices[i + 1], indices[i + 2]);
            }
        }
        this._tileBoundsBuffer = context.createVertexBuffer(boundsVertices, boundsAttributes.members);
        this._tileBoundsIndexBuffer = context.createIndexBuffer(boundsIndices);
        this._tileBoundsSegments = SegmentVector.simpleSegment(0, 0, boundsVertices.length, boundsIndices.length);
    }

    _makeGlobeTileDebugBuffers(context         , transform           ) {
        const projection = transform.projection;
        if (!projection || projection.name !== 'globe' || transform.freezeTileCoverage) return;

        const id = this.tileID.canonical;
        const bounds = transitionTileAABBinECEF(id, transform);
        const normalizationMatrix = globeNormalizeECEF(bounds);

        const phase = globeToMercatorTransition(transform.zoom);
        let worldToECEFMatrix;
        if (phase > 0.0) {
            worldToECEFMatrix = invert$2(new Float64Array(16), transform.globeMatrix);
        }

        this._makeGlobeTileDebugBorderBuffer(context, id, transform, normalizationMatrix, worldToECEFMatrix, phase);
        this._makeGlobeTileDebugTextBuffer(context, id, transform, normalizationMatrix, worldToECEFMatrix, phase);
    }

    _globePoint(x        , y        , id                 , tr           , normalizationMatrix              , worldToECEFMatrix               , phase        )       {
        // The following is equivalent to doing globe.projectTilePoint.
        // This way we don't recompute the normalization matrix everytime since it remains the same for all points.
        let ecef = tileCoordToECEF(x, y, id);
        if (worldToECEFMatrix) {
            // When in globe-to-Mercator transition, interpolate between globe and Mercator positions in ECEF
            const tileCount = 1 << id.z;

            // Wrap tiles to ensure that that Mercator interpolation is in the right direction
            const camX = mercatorXfromLng(tr.center.lng);
            const camY = mercatorYfromLat(tr.center.lat);

            const tileCenterX = (id.x + .5) / tileCount;
            const dx = tileCenterX - camX;
            let wrap = 0;
            if (dx > .5) {
                wrap = -1;
            } else if (dx < -.5) {
                wrap = 1;
            }

            let mercatorX = (x / EXTENT + id.x) / tileCount + wrap;
            let mercatorY = (y / EXTENT + id.y) / tileCount;
            mercatorX = (mercatorX - camX) * tr._pixelsPerMercatorPixel + camX;
            mercatorY = (mercatorY - camY) * tr._pixelsPerMercatorPixel + camY;
            const mercatorPos = [mercatorX * tr.worldSize, mercatorY * tr.worldSize, 0];
            transformMat4$2(mercatorPos, mercatorPos, worldToECEFMatrix);
            ecef = interpolateVec3(ecef, mercatorPos, phase);
        }
        const gp = transformMat4$2(ecef, ecef, normalizationMatrix);
        return gp;
    }

    _makeGlobeTileDebugBorderBuffer(context         , id                 , tr           , normalizationMatrix              , worldToECEFMatrix               , phase        ) {
        const vertices = new StructArrayLayout2i4();
        const indices = new StructArrayLayout1ui2();
        const extraGlobe = new StructArrayLayout3i6();

        const addLine = (sx        , sy        , ex        , ey        , pointCount        ) => {
            const stepX = (ex - sx) / (pointCount - 1);
            const stepY = (ey - sy) / (pointCount - 1);

            const vOffset = vertices.length;

            for (let i = 0; i < pointCount; i++) {
                const x = sx + i * stepX;
                const y = sy + i * stepY;
                vertices.emplaceBack(x, y);

                const gp = this._globePoint(x, y, id, tr, normalizationMatrix, worldToECEFMatrix, phase);

                extraGlobe.emplaceBack(gp[0], gp[1], gp[2]);
                indices.emplaceBack(vOffset + i);
            }
        };

        const e = EXTENT;
        addLine(0, 0, e, 0, 16);
        addLine(e, 0, e, e, 16);
        addLine(e, e, 0, e, 16);
        addLine(0, e, 0, 0, 16);

        this._tileDebugIndexBuffer = context.createIndexBuffer(indices);
        this._tileDebugBuffer = context.createVertexBuffer(vertices, posAttributes.members);
        this._globeTileDebugBorderBuffer = context.createVertexBuffer(extraGlobe, posAttributesGlobeExt.members);
        this._tileDebugSegments = SegmentVector.simpleSegment(0, 0, vertices.length, indices.length);
    }

    _makeGlobeTileDebugTextBuffer(context         , id                 , tr           , normalizationMatrix              , worldToECEFMatrix               , phase        ) {
        const SEGMENTS = 4;
        const numVertices = SEGMENTS + 1;
        const step = EXTENT / SEGMENTS;

        const vertices = new StructArrayLayout2i4();
        const indices = new StructArrayLayout3ui6();
        const extraGlobe = new StructArrayLayout3i6();

        const totalVertices = numVertices * numVertices;
        const totalTriangles = SEGMENTS * SEGMENTS * 2;
        indices.reserve(totalTriangles);
        vertices.reserve(totalVertices);
        extraGlobe.reserve(totalVertices);

        const toIndex = (j        , i        )         => {
            return totalVertices * j + i;
        };

        // add vertices.
        for (let j = 0; j < totalVertices; j++) {
            const y = j * step;
            for (let i = 0; i < totalVertices; i++) {
                const x = i * step;
                vertices.emplaceBack(x, y);

                const gp = this._globePoint(x, y, id, tr, normalizationMatrix, worldToECEFMatrix, phase);
                extraGlobe.emplaceBack(gp[0], gp[1], gp[2]);
            }
        }

        // add indices.
        for (let j = 0; j < SEGMENTS; j++) {
            for (let i = 0; i < SEGMENTS; i++) {
                const tl = toIndex(j, i);
                const tr = toIndex(j, i + 1);
                const bl = toIndex(j + 1, i);
                const br = toIndex(j + 1, i + 1);

                // first triangle of the sub-patch.
                indices.emplaceBack(tl, tr, bl);

                // second triangle of the sub-patch.
                indices.emplaceBack(bl, tr, br);
            }
        }

        this._tileDebugTextIndexBuffer = context.createIndexBuffer(indices);
        this._tileDebugTextBuffer = context.createVertexBuffer(vertices, posAttributes.members);
        this._globeTileDebugTextBuffer = context.createVertexBuffer(extraGlobe, posAttributesGlobeExt.members);
        this._tileDebugTextSegments = SegmentVector.simpleSegment(0, 0, totalVertices, totalTriangles);
    }
}

//      

                                                                    
                                                

                                                                 
                                                                  

/**
 * SourceFeatureState manages the state and pending changes
 * to features in a source, separated by source layer.
 * stateChanges and deletedStates batch all changes to the tile (updates and removes, respectively)
 * between coalesce() events. addFeatureState() and removeFeatureState() also update their counterpart's
 * list of changes, such that coalesce() can apply the proper state changes while agnostic to the order of operations.
 * In deletedStates, all null's denote complete removal of state at that scope
 * @private
*/
class SourceFeatureState {
                              
                                     
                      

    constructor() {
        this.state = {};
        this.stateChanges = {};
        this.deletedStates = {};
    }

    updateState(sourceLayer        , featureId                 , newState        ) {
        const feature = String(featureId);
        this.stateChanges[sourceLayer] = this.stateChanges[sourceLayer] || {};
        this.stateChanges[sourceLayer][feature] = this.stateChanges[sourceLayer][feature] || {};
        extend$1(this.stateChanges[sourceLayer][feature], newState);

        if (this.deletedStates[sourceLayer] === null) {
            this.deletedStates[sourceLayer] = {};
            for (const ft in this.state[sourceLayer]) {
                if (ft !== feature) this.deletedStates[sourceLayer][ft] = null;
            }
        } else {
            const featureDeletionQueued = this.deletedStates[sourceLayer] && this.deletedStates[sourceLayer][feature] === null;
            if (featureDeletionQueued) {
                this.deletedStates[sourceLayer][feature] = {};
                for (const prop in this.state[sourceLayer][feature]) {
                    if (!newState[prop]) this.deletedStates[sourceLayer][feature][prop] = null;
                }
            } else {
                for (const key in newState) {
                    const deletionInQueue = this.deletedStates[sourceLayer] && this.deletedStates[sourceLayer][feature] && this.deletedStates[sourceLayer][feature][key] === null;
                    if (deletionInQueue) delete this.deletedStates[sourceLayer][feature][key];
                }
            }
        }
    }

    removeFeatureState(sourceLayer        , featureId                  , key         ) {
        const sourceLayerDeleted = this.deletedStates[sourceLayer] === null;
        if (sourceLayerDeleted) return;

        const feature = String(featureId);

        this.deletedStates[sourceLayer] = this.deletedStates[sourceLayer] || {};

        if (key && featureId !== undefined) {
            if (this.deletedStates[sourceLayer][feature] !== null) {
                this.deletedStates[sourceLayer][feature] = this.deletedStates[sourceLayer][feature] || {};
                this.deletedStates[sourceLayer][feature][key] = null;
            }
        } else if (featureId !== undefined) {
            const updateInQueue = this.stateChanges[sourceLayer] && this.stateChanges[sourceLayer][feature];
            if (updateInQueue) {
                this.deletedStates[sourceLayer][feature] = {};
                for (key in this.stateChanges[sourceLayer][feature]) this.deletedStates[sourceLayer][feature][key] = null;

            } else {
                this.deletedStates[sourceLayer][feature] = null;
            }
        } else {
            this.deletedStates[sourceLayer] = null;
        }
    }

    getState(sourceLayer        , featureId                 )                {
        const feature = String(featureId);
        const base = this.state[sourceLayer] || {};
        const changes = this.stateChanges[sourceLayer] || {};

        const reconciledState = extend$1({}, base[feature], changes[feature]);

        //return empty object if the whole source layer is awaiting deletion
        if (this.deletedStates[sourceLayer] === null) return {};
        else if (this.deletedStates[sourceLayer]) {
            const featureDeletions = this.deletedStates[sourceLayer][featureId];
            if (featureDeletions === null) return {};
            for (const prop in featureDeletions) delete reconciledState[prop];
        }
        return reconciledState;
    }

    initializeTileState(tile      , painter          ) {
        tile.setFeatureState(this.state, painter);
    }

    coalesceChanges(tiles                  , painter     ) {
        //track changes with full state objects, but only for features that got modified
        const featuresChanged                     = {};

        for (const sourceLayer in this.stateChanges) {
            this.state[sourceLayer]  = this.state[sourceLayer] || {};
            const layerStates = {};
            for (const feature in this.stateChanges[sourceLayer]) {
                if (!this.state[sourceLayer][feature]) this.state[sourceLayer][feature] = {};
                extend$1(this.state[sourceLayer][feature], this.stateChanges[sourceLayer][feature]);
                layerStates[feature] = this.state[sourceLayer][feature];
            }
            featuresChanged[sourceLayer] = layerStates;
        }

        for (const sourceLayer in this.deletedStates) {
            this.state[sourceLayer]  = this.state[sourceLayer] || {};
            const layerStates = {};

            if (this.deletedStates[sourceLayer] === null) {
                for (const ft in this.state[sourceLayer]) {
                    layerStates[ft] = {};
                    this.state[sourceLayer][ft] = {};
                }
            } else {
                for (const feature in this.deletedStates[sourceLayer]) {
                    const deleteWholeFeatureState = this.deletedStates[sourceLayer][feature] === null;
                    if (deleteWholeFeatureState) this.state[sourceLayer][feature] = {};
                    else if (this.state[sourceLayer][feature]) {
                        for (const key of Object.keys(this.deletedStates[sourceLayer][feature])) {
                            delete this.state[sourceLayer][feature][key];
                        }
                    }
                    layerStates[feature] = this.state[sourceLayer][feature];
                }
            }

            featuresChanged[sourceLayer] = featuresChanged[sourceLayer] || {};
            extend$1(featuresChanged[sourceLayer], layerStates);
        }

        this.stateChanges = {};
        this.deletedStates = {};

        if (Object.keys(featuresChanged).length === 0) return;

        for (const id in tiles) {
            const tile = tiles[id];
            tile.setFeatureState(featuresChanged, painter);
        }
    }
}

//      


                                    

class MipLevel {
                 
                            
                            
                          

    constructor(size_        ) {
        this.size = size_;
        this.minimums = [];
        this.maximums = [];
        this.leaves = [];
    }

    getElevation(x        , y        )                              {
        const idx = this.toIdx(x, y);
        return {
            min: this.minimums[idx],
            max: this.maximums[idx]
        };
    }

    isLeaf(x        , y        )         {
        return this.leaves[this.toIdx(x, y)];
    }

    toIdx(x        , y        )         {
        return y * this.size + x;
    }
}

function aabbRayIntersect(min      , max      , pos      , dir      )          {
    let tMin = 0;
    let tMax = Number.MAX_VALUE;

    const epsilon = 1e-15;

    for (let i = 0; i < 3; i++) {
        if (Math.abs(dir[i]) < epsilon) {
            // Parallel ray
            if (pos[i] < min[i] || pos[i] > max[i])
                return null;
        } else {
            const ood = 1.0 / dir[i];
            let t1 = (min[i] - pos[i]) * ood;
            let t2 = (max[i] - pos[i]) * ood;
            if (t1 > t2) {
                const temp = t1;
                t1 = t2;
                t2 = temp;
            }
            if (t1 > tMin)
                tMin = t1;
            if (t2 < tMax)
                tMax = t2;
            if (tMin > tMax)
                return null;
        }
    }

    return tMin;
}

function triangleRayIntersect(ax        , ay        , az        , bx        , by        , bz        , cx        , cy        , cz        , pos      , dir      )          {
    // Compute barycentric coordinates u and v to find the intersection
    const abX = bx - ax;
    const abY = by - ay;
    const abZ = bz - az;

    const acX = cx - ax;
    const acY = cy - ay;
    const acZ = cz - az;

    // pvec = cross(dir, a), det = dot(ab, pvec)
    const pvecX = dir[1] * acZ - dir[2] * acY;
    const pvecY = dir[2] * acX - dir[0] * acZ;
    const pvecZ = dir[0] * acY - dir[1] * acX;
    const det = abX * pvecX + abY * pvecY + abZ * pvecZ;

    if (Math.abs(det) < 1e-15)
        return null;

    const invDet = 1.0 / det;
    const tvecX = pos[0] - ax;
    const tvecY = pos[1] - ay;
    const tvecZ = pos[2] - az;
    const u = (tvecX * pvecX + tvecY * pvecY + tvecZ * pvecZ) * invDet;

    if (u < 0.0 || u > 1.0)
        return null;

    // qvec = cross(tvec, ab)
    const qvecX = tvecY * abZ - tvecZ * abY;
    const qvecY = tvecZ * abX - tvecX * abZ;
    const qvecZ = tvecX * abY - tvecY * abX;
    const v = (dir[0] * qvecX + dir[1] * qvecY + dir[2] * qvecZ) * invDet;

    if (v < 0.0 || u + v > 1.0)
        return null;

    return (acX * qvecX + acY * qvecY + acZ * qvecZ) * invDet;
}

function frac(v        , lo        , hi        ) {
    return (v - lo) / (hi - lo);
}

function decodeBounds(x        , y        , depth        , boundsMinx        , boundsMiny        , boundsMaxx        , boundsMaxy        , outMin               , outMax               ) {
    const scale = 1 << depth;
    const rangex = boundsMaxx - boundsMinx;
    const rangey = boundsMaxy - boundsMiny;

    const minX = (x + 0) / scale * rangex + boundsMinx;
    const maxX = (x + 1) / scale * rangex + boundsMinx;
    const minY = (y + 0) / scale * rangey + boundsMiny;
    const maxY = (y + 1) / scale * rangey + boundsMiny;

    outMin[0] = minX;
    outMin[1] = minY;
    outMax[0] = maxX;
    outMax[1] = maxY;
}

// A small padding value is used with bounding boxes to extend the bottom below sea level
const aabbSkirtPadding = 100;

// A sparse min max quad tree for performing accelerated queries against dem elevation data.
// Each tree node stores the minimum and maximum elevation of its children nodes and a flag whether the node is a leaf.
// Node data is stored in non-interleaved arrays where the root is at index 0.
class DemMinMaxQuadTree {
                            
                            
                          
                                
                      
                 
                                         

    constructor(dem_         ) {
        this.maximums = [];
        this.minimums = [];
        this.leaves = [];
        this.childOffsets = [];
        this.nodeCount = 0;
        this.dem = dem_;

        // Precompute the order of 4 sibling nodes in the memory. Top-left, top-right, bottom-left, bottom-right
        this._siblingOffset = [
            [0, 0],
            [1, 0],
            [0, 1],
            [1, 1]
        ];

        if (!this.dem)
            return;

        const mips = buildDemMipmap(this.dem);
        const maxLvl = mips.length - 1;

        // Create the root node
        const rootMip = mips[maxLvl];
        const min = rootMip.minimums;
        const max = rootMip.maximums;
        const leaves = rootMip.leaves;
        this._addNode(min[0], max[0], leaves[0]);

        // Construct the rest of the tree recursively
        this._construct(mips, 0, 0, maxLvl, 0);
    }

    // Performs raycast against the tree root only. Min and max coordinates defines the size of the root node
    raycastRoot(minx        , miny        , maxx        , maxy        , p      , d      , exaggeration         = 1)          {
        const min = [minx, miny, -aabbSkirtPadding];
        const max = [maxx, maxy, this.maximums[0] * exaggeration];
        return aabbRayIntersect(min, max, p, d);
    }

    raycast(rootMinx        , rootMiny        , rootMaxx        , rootMaxy        , p      , d      , exaggeration         = 1)          {
        if (!this.nodeCount)
            return null;

        const t = this.raycastRoot(rootMinx, rootMiny, rootMaxx, rootMaxy, p, d, exaggeration);
        if (t == null)
            return null;

        const tHits = [];
        const sortedHits = [];
        const boundsMin = [];
        const boundsMax = [];

        const stack = [{
            idx: 0,
            t,
            nodex: 0,
            nodey: 0,
            depth: 0
        }];

        // Traverse the tree until something is hit or the ray escapes
        while (stack.length > 0) {
            const {idx, t, nodex, nodey, depth} = stack.pop();

            if (this.leaves[idx]) {
                // Create 2 triangles to approximate the surface plane for more precise tests
                decodeBounds(nodex, nodey, depth, rootMinx, rootMiny, rootMaxx, rootMaxy, boundsMin, boundsMax);

                const scale = 1 << depth;
                const minxUv = (nodex + 0) / scale;
                const maxxUv = (nodex + 1) / scale;
                const minyUv = (nodey + 0) / scale;
                const maxyUv = (nodey + 1) / scale;

                // 4 corner points A, B, C and D defines the (quad) area covered by this node
                const az = sampleElevation(minxUv, minyUv, this.dem) * exaggeration;
                const bz = sampleElevation(maxxUv, minyUv, this.dem) * exaggeration;
                const cz = sampleElevation(maxxUv, maxyUv, this.dem) * exaggeration;
                const dz = sampleElevation(minxUv, maxyUv, this.dem) * exaggeration;

                const t0      = triangleRayIntersect(
                    boundsMin[0], boundsMin[1], az,     // A
                    boundsMax[0], boundsMin[1], bz,     // B
                    boundsMax[0], boundsMax[1], cz,     // C
                    p, d);

                const t1      = triangleRayIntersect(
                    boundsMax[0], boundsMax[1], cz,
                    boundsMin[0], boundsMax[1], dz,
                    boundsMin[0], boundsMin[1], az,
                    p, d);

                const tMin = Math.min(
                    t0 !== null ? t0 : Number.MAX_VALUE,
                    t1 !== null ? t1 : Number.MAX_VALUE);

                // The ray might go below the two surface triangles but hit one of the sides.
                // This covers the case of skirt geometry between two dem tiles of different zoom level
                if (tMin === Number.MAX_VALUE) {
                    const hitPos = scaleAndAdd$2([], p, d, t);
                    const fracx = frac(hitPos[0], boundsMin[0], boundsMax[0]);
                    const fracy = frac(hitPos[1], boundsMin[1], boundsMax[1]);

                    if (bilinearLerp(az, bz, dz, cz, fracx, fracy) >= hitPos[2])
                        return t;
                } else {
                    return tMin;
                }

                continue;
            }

            // Perform intersection tests agains each of the 4 child nodes and store results from closest to furthest.
            let hitCount = 0;

            for (let i = 0; i < this._siblingOffset.length; i++) {

                const childNodeX = (nodex << 1) + this._siblingOffset[i][0];
                const childNodeY = (nodey << 1) + this._siblingOffset[i][1];

                // Decode node aabb from the morton code
                decodeBounds(childNodeX, childNodeY, depth + 1, rootMinx, rootMiny, rootMaxx, rootMaxy, boundsMin, boundsMax);

                boundsMin[2] = -aabbSkirtPadding;
                boundsMax[2] = this.maximums[this.childOffsets[idx] + i] * exaggeration;

                const result = aabbRayIntersect(boundsMin, boundsMax, p, d);
                if (result != null) {
                    // Build the result list from furthest to closest hit.
                    // The order will be inversed when building the stack
                    const tHit         = result;
                    tHits[i] = tHit;

                    let added = false;
                    for (let j = 0; j < hitCount && !added; j++) {
                        if (tHit >= tHits[sortedHits[j]]) {
                            sortedHits.splice(j, 0, i);
                            added = true;
                        }
                    }
                    if (!added)
                        sortedHits[hitCount] = i;
                    hitCount++;
                }
            }

            // Continue recursion from closest to furthest
            for (let i = 0; i < hitCount; i++) {
                const hitIdx = sortedHits[i];
                stack.push({
                    idx: this.childOffsets[idx] + hitIdx,
                    t: tHits[hitIdx],
                    nodex: (nodex << 1) + this._siblingOffset[hitIdx][0],
                    nodey: (nodey << 1) + this._siblingOffset[hitIdx][1],
                    depth: depth + 1
                });
            }
        }

        return null;
    }

    _addNode(min        , max        , leaf        )         {
        this.minimums.push(min);
        this.maximums.push(max);
        this.leaves.push(leaf);
        this.childOffsets.push(0);
        return this.nodeCount++;
    }

    _construct(mips                 , x        , y        , lvl        , parentIdx        ) {
        if (mips[lvl].isLeaf(x, y) === 1) {
            return;
        }

        // Update parent offset
        if (!this.childOffsets[parentIdx])
            this.childOffsets[parentIdx] = this.nodeCount;

        // Construct all 4 children and place them next to each other in memory
        const childLvl = lvl - 1;
        const childMip = mips[childLvl];

        let leafMask = 0;
        let firstNodeIdx = 0;

        for (let i = 0; i < this._siblingOffset.length; i++) {
            const childX = x * 2 + this._siblingOffset[i][0];
            const childY = y * 2 + this._siblingOffset[i][1];

            const elevation = childMip.getElevation(childX, childY);
            const leaf = childMip.isLeaf(childX, childY);
            const nodeIdx = this._addNode(elevation.min, elevation.max, leaf);

            if (leaf)
                leafMask |= 1 << i;
            if (!firstNodeIdx)
                firstNodeIdx = nodeIdx;
        }

        // Continue construction of the tree recursively to non-leaf nodes.
        for (let i = 0; i < this._siblingOffset.length; i++) {
            if (!(leafMask & (1 << i))) {
                this._construct(mips, x * 2 + this._siblingOffset[i][0], y * 2 + this._siblingOffset[i][1], childLvl, firstNodeIdx + i);
            }
        }
    }
}

function bilinearLerp(p00     , p10     , p01     , p11     , x        , y        )      {
    return number(
        number(p00, p01, y),
        number(p10, p11, y),
        x);
}

// Sample elevation in normalized uv-space ([0, 0] is the top left)
// This function does not account for exaggeration
function sampleElevation(fx        , fy        , dem         )         {
    // Sample position in texels
    const demSize = dem.dim;
    const x = clamp(fx * demSize - 0.5, 0, demSize - 1);
    const y = clamp(fy * demSize - 0.5, 0, demSize - 1);

    // Compute 4 corner points for bilinear interpolation
    const ixMin = Math.floor(x);
    const iyMin = Math.floor(y);
    const ixMax = Math.min(ixMin + 1, demSize - 1);
    const iyMax = Math.min(iyMin + 1, demSize - 1);

    const e00 = dem.get(ixMin, iyMin);
    const e10 = dem.get(ixMax, iyMin);
    const e01 = dem.get(ixMin, iyMax);
    const e11 = dem.get(ixMax, iyMax);

    return bilinearLerp(e00, e10, e01, e11, x - ixMin, y - iyMin);
}

function buildDemMipmap(dem         )                  {
    const demSize = dem.dim;

    const elevationDiffThreshold = 5;
    const texelSizeOfMip0 = 8;
    const levelCount = Math.ceil(Math.log2(demSize / texelSizeOfMip0));
    const mips                  = [];

    let blockCount = Math.ceil(Math.pow(2, levelCount));
    const blockSize = 1 / blockCount;

    const blockSamples = (x        , y        , size        , exclusive         , outBounds               ) => {
        const padding = exclusive ? 1 : 0;
        const minx = x * size;
        const maxx = (x + 1) * size - padding;
        const miny = y * size;
        const maxy = (y + 1) * size - padding;

        outBounds[0] = minx;
        outBounds[1] = miny;
        outBounds[2] = maxx;
        outBounds[3] = maxy;
    };

    // The first mip (0) is built by sampling 4 corner points of each 8x8 texel block
    let mip = new MipLevel(blockCount);
    const blockBounds = [];

    for (let idx = 0; idx < blockCount * blockCount; idx++) {
        const y = Math.floor(idx / blockCount);
        const x = idx % blockCount;

        blockSamples(x, y, blockSize, false, blockBounds);

        const e0 = sampleElevation(blockBounds[0], blockBounds[1], dem);    // minx, miny
        const e1 = sampleElevation(blockBounds[2], blockBounds[1], dem);    // maxx, miny
        const e2 = sampleElevation(blockBounds[2], blockBounds[3], dem);    // maxx, maxy
        const e3 = sampleElevation(blockBounds[0], blockBounds[3], dem);    // minx, maxy

        mip.minimums.push(Math.min(e0, e1, e2, e3));
        mip.maximums.push(Math.max(e0, e1, e2, e3));
        mip.leaves.push(1);
    }

    mips.push(mip);

    // Construct the rest of the mip levels from bottom to up
    for (blockCount /= 2; blockCount >= 1; blockCount /= 2) {
        const prevMip = mips[mips.length - 1];

        mip = new MipLevel(blockCount);

        for (let idx = 0; idx < blockCount * blockCount; idx++) {
            const y = Math.floor(idx / blockCount);
            const x = idx % blockCount;

            // Sample elevation of all 4 children mip texels. 4 leaf nodes can be concatenated into a single
            // leaf if the total elevation difference is below the threshold value
            blockSamples(x, y, 2, true, blockBounds);

            const e0 = prevMip.getElevation(blockBounds[0], blockBounds[1]);
            const e1 = prevMip.getElevation(blockBounds[2], blockBounds[1]);
            const e2 = prevMip.getElevation(blockBounds[2], blockBounds[3]);
            const e3 = prevMip.getElevation(blockBounds[0], blockBounds[3]);

            const l0 = prevMip.isLeaf(blockBounds[0], blockBounds[1]);
            const l1 = prevMip.isLeaf(blockBounds[2], blockBounds[1]);
            const l2 = prevMip.isLeaf(blockBounds[2], blockBounds[3]);
            const l3 = prevMip.isLeaf(blockBounds[0], blockBounds[3]);

            const minElevation = Math.min(e0.min, e1.min, e2.min, e3.min);
            const maxElevation = Math.max(e0.max, e1.max, e2.max, e3.max);
            const canConcatenate = l0 && l1 && l2 && l3;

            mip.maximums.push(maxElevation);
            mip.minimums.push(minElevation);

            if (maxElevation - minElevation <= elevationDiffThreshold && canConcatenate) {
                // All samples have uniform elevation. Mark this as a leaf
                mip.leaves.push(1);
            } else {
                mip.leaves.push(0);
            }
        }

        mips.push(mip);
    }

    return mips;
}

//      

// DEMData is a data structure for decoding, backfilling, and storing elevation data for processing in the hillshade shaders
// data can be populated either from a pngraw image tile or from serliazed data sent back from a worker. When data is initially
// loaded from a image tile, we decode the pixel values using the appropriate decoding formula, but we store the
// elevation data as an Int32 value. we add 65536 (2^16) to eliminate negative values and enable the use of
// integer overflow when creating the texture used in the hillshadePrepare step.

// DEMData also handles the backfilling of data from a tile's neighboring tiles. This is necessary because we use a pixel's 8
// surrounding pixel values to compute the slope at that pixel, and we cannot accurately calculate the slope at pixels on a
// tile's edge without backfilling from neighboring tiles.

                                                 

const unpackVectors = {
    mapbox: [6553.6, 25.6, 0.1, 10000.0],
    terrarium: [256.0, 1.0, 1.0 / 256.0, 32768.0]
};

function unpackMapbox(r        , g        , b        )         {
    // unpacking formula for mapbox.terrain-rgb:
    // https://www.mapbox.com/help/access-elevation-data/#mapbox-terrain-rgb
    return ((r * 256 * 256 + g * 256.0 + b) / 10.0 - 10000.0);
}

function unpackTerrarium(r        , g        , b        )         {
    // unpacking formula for mapzen terrarium:
    // https://aws.amazon.com/public-datasets/terrain/
    return ((r * 256 + g + b / 256) - 32768.0);
}

class DEMData {
                
                       
                   
                
                          
                         
                             
    get tree()                    {
        if (!this._tree) this._buildQuadTree();
        return this._tree;
    }

    // RGBAImage data has uniform 1px padding on all sides: square tile edge size defines stride
    // and dim is calculated as stride - 2.
    constructor(uid        , data           , encoding             , borderReady          = false, buildQuadTree          = false)       {
        this.uid = uid;
        if (data.height !== data.width) throw new RangeError('DEM tiles must be square');
        if (encoding && encoding !== "mapbox" && encoding !== "terrarium") return warnOnce(
            `"${encoding}" is not a valid encoding type. Valid types include "mapbox" and "terrarium".`
        );
        this.stride = data.height;
        const dim = this.dim = data.height - 2;
        const values = new Uint32Array(data.data.buffer);
        this.pixels = new Uint8Array(data.data.buffer);
        this.encoding = encoding || 'mapbox';
        this.borderReady = borderReady;

        if (borderReady) return;

        // in order to avoid flashing seams between tiles, here we are initially populating a 1px border of pixels around the image
        // with the data of the nearest pixel from the image. this data is eventually replaced when the tile's neighboring
        // tiles are loaded and the accurate data can be backfilled using DEMData#backfillBorder
        for (let x = 0; x < dim; x++) {
            // left vertical border
            values[this._idx(-1, x)] = values[this._idx(0, x)];
            // right vertical border
            values[this._idx(dim, x)] = values[this._idx(dim - 1, x)];
            // left horizontal border
            values[this._idx(x, -1)] = values[this._idx(x, 0)];
            // right horizontal border
            values[this._idx(x, dim)] = values[this._idx(x, dim - 1)];
        }
        // corners
        values[this._idx(-1, -1)] = values[this._idx(0, 0)];
        values[this._idx(dim, -1)] = values[this._idx(dim - 1, 0)];
        values[this._idx(-1, dim)] = values[this._idx(0, dim - 1)];
        values[this._idx(dim, dim)] = values[this._idx(dim - 1, dim - 1)];
        if (buildQuadTree) this._buildQuadTree();
    }

    _buildQuadTree() {
        assert$1(!this._tree);
        // Construct the implicit sparse quad tree by traversing mips from top to down
        this._tree = new DemMinMaxQuadTree(this);
    }

    get(x        , y        , clampToEdge          = false)         {
        if (clampToEdge) {
            x = clamp(x, -1, this.dim);
            y = clamp(y, -1, this.dim);
        }
        const index = this._idx(x, y) * 4;
        const unpack = this.encoding === "terrarium" ? unpackTerrarium : unpackMapbox;
        return unpack(this.pixels[index], this.pixels[index + 1], this.pixels[index + 2]);
    }

    static getUnpackVector(encoding             )                                   {
        return unpackVectors[encoding];
    }

    get unpackVector()                                   {
        return unpackVectors[this.encoding];
    }

    _idx(x        , y        )         {
        if (x < -1 || x >= this.dim + 1 ||  y < -1 || y >= this.dim + 1) throw new RangeError('out of range source coordinates for DEM data');
        return (y + 1) * this.stride + (x + 1);
    }

    static pack(altitude        , encoding             )                                   {
        const color = [0, 0, 0, 0];
        const vector = DEMData.getUnpackVector(encoding);
        let v = Math.floor((altitude + vector[3]) / vector[2]);
        color[2] = v % 256;
        v = Math.floor(v / 256);
        color[1] = v % 256;
        v = Math.floor(v / 256);
        color[0] = v;
        return color;
    }

    getPixels()            {
        return new RGBAImage({width: this.stride, height: this.stride}, this.pixels);
    }

    backfillBorder(borderTile         , dx        , dy        )       {
        if (this.dim !== borderTile.dim) throw new Error('dem dimension mismatch');

        let xMin = dx * this.dim,
            xMax = dx * this.dim + this.dim,
            yMin = dy * this.dim,
            yMax = dy * this.dim + this.dim;

        switch (dx) {
        case -1:
            xMin = xMax - 1;
            break;
        case 1:
            xMax = xMin + 1;
            break;
        }

        switch (dy) {
        case -1:
            yMin = yMax - 1;
            break;
        case 1:
            yMax = yMin + 1;
            break;
        }

        const ox = -dx * this.dim;
        const oy = -dy * this.dim;
        for (let y = yMin; y < yMax; y++) {
            for (let x = xMin; x < xMax; x++) {
                const i = 4 * this._idx(x, y);
                const j = 4 * this._idx(x + ox, y + oy);
                this.pixels[i + 0] = borderTile.pixels[j + 0];
                this.pixels[i + 1] = borderTile.pixels[j + 1];
                this.pixels[i + 2] = borderTile.pixels[j + 2];
                this.pixels[i + 3] = borderTile.pixels[j + 3];
            }
        }
    }

    onDeserialize() {
        if (this._tree) this._tree.dem = this;
    }
}

register(DEMData, 'DEMData');
register(DemMinMaxQuadTree, 'DemMinMaxQuadTree', {omit: ['dem']});

//      

                                  

/**
 * A [least-recently-used cache](http://en.wikipedia.org/wiki/Cache_algorithms)
 * with hash lookup made possible by keeping a list of keys in parallel to
 * an array of dictionary of values
 *
 * @private
 */
class TileCache {
                
                                                                               
                         
                                      
    /**
     * @param {number} max The max number of permitted values.
     * @private
     * @param {Function} onRemove The callback called with items when they expire.
     */
    constructor(max        , onRemove                         ) {
        this.max = max;
        this.onRemove = onRemove;
        this.reset();
    }

    /**
     * Clear the cache.
     *
     * @returns {TileCache} Returns itself to allow for method chaining.
     * @private
     */
    reset()       {
        for (const key in this.data) {
            for (const removedData of this.data[key]) {
                if (removedData.timeout) clearTimeout(removedData.timeout);
                this.onRemove(removedData.value);
            }
        }

        this.data = {};
        this.order = [];

        return this;
    }

    /**
     * Add a key, value combination to the cache, trimming its size if this pushes
     * it over max length.
     *
     * @param {OverscaledTileID} tileID lookup key for the item
     * @param {*} data any value
     *
     * @returns {TileCache} Returns itself to allow for method chaining.
     * @private
     */
    add(tileID                  , data      , expiryTimeout               )       {
        const key = tileID.wrapped().key;
        if (this.data[key] === undefined) {
            this.data[key] = [];
        }

        const dataWrapper = {
            value: data,
            timeout: undefined
        };

        if (expiryTimeout !== undefined) {
            dataWrapper.timeout = setTimeout(() => {
                this.remove(tileID, dataWrapper);
            }, expiryTimeout);
        }

        this.data[key].push(dataWrapper);
        this.order.push(key);

        if (this.order.length > this.max) {
            const removedData = this._getAndRemoveByKey(this.order[0]);
            if (removedData) this.onRemove(removedData);
        }

        return this;
    }

    /**
     * Determine whether the value attached to `key` is present
     *
     * @param {OverscaledTileID} tileID the key to be looked-up
     * @returns {boolean} whether the cache has this value
     * @private
     */
    has(tileID                  )          {
        return tileID.wrapped().key in this.data;
    }

    /**
     * Get the value attached to a specific key and remove data from cache.
     * If the key is not found, returns `null`
     *
     * @param {OverscaledTileID} tileID the key to look up
     * @returns {*} the data, or null if it isn't found
     * @private
     */
    getAndRemove(tileID                  )        {
        if (!this.has(tileID)) { return null; }
        return this._getAndRemoveByKey(tileID.wrapped().key);
    }

    /*
     * Get and remove the value with the specified key.
     */
    _getAndRemoveByKey(key        )        {
        const data = this.data[key].shift();
        if (data.timeout) clearTimeout(data.timeout);

        if (this.data[key].length === 0) {
            delete this.data[key];
        }
        this.order.splice(this.order.indexOf(key), 1);

        return data.value;
    }

    /*
     * Get the value with the specified (wrapped tile) key.
     */
    getByKey(key        )        {
        const data = this.data[key];
        return data ? data[0].value : null;
    }

    /**
     * Get the value attached to a specific key without removing data
     * from the cache. If the key is not found, returns `null`
     *
     * @param {OverscaledTileID} tileID the key to look up
     * @returns {*} the data, or null if it isn't found
     * @private
     */
    get(tileID                  )        {
        if (!this.has(tileID)) { return null; }

        const data = this.data[tileID.wrapped().key][0];
        return data.value;
    }

    /**
     * Remove a key/value combination from the cache.
     *
     * @param {OverscaledTileID} tileID the key for the pair to delete
     * @param {Tile} value If a value is provided, remove that exact version of the value.
     * @returns {TileCache} this cache
     * @private
     */
    remove(tileID                  , value                                      )       {
        if (!this.has(tileID)) { return this; }
        const key = tileID.wrapped().key;

        const dataIndex = value === undefined ? 0 : this.data[key].indexOf(value);
        const data = this.data[key][dataIndex];
        this.data[key].splice(dataIndex, 1);
        if (data.timeout) clearTimeout(data.timeout);
        if (this.data[key].length === 0) {
            delete this.data[key];
        }
        this.onRemove(data.value);
        this.order.splice(this.order.indexOf(key), 1);

        return this;
    }

    /**
     * Change the max size of the cache.
     *
     * @param {number} max the max size of the cache
     * @returns {TileCache} this cache
     * @private
     */
    setMaxSize(max        )            {
        this.max = max;

        while (this.order.length > this.max) {
            const removedData = this._getAndRemoveByKey(this.order[0]);
            if (removedData) this.onRemove(removedData);
        }

        return this;
    }

    /**
     * Remove entries that do not pass a filter function. Used for removing
     * stale tiles from the cache.
     *
     * @private
     * @param {function} filterFn Determines whether the tile is filtered. If the supplied function returns false, the tile will be filtered out.
     */
    filter(filterFn                         ) {
        const removed = [];
        for (const key in this.data) {
            for (const entry of this.data[key]) {
                if (!filterFn(entry.value)) {
                    removed.push(entry);
                }
            }
        }
        for (const r of removed) {
            this.remove(r.value.tileID, r);
        }
    }
}

//      

                                                         
                                                                                                         
                                            

class IndexBuffer {
                     
                         
                         

    constructor(context         , array                                                           , dynamicDraw          ) {
        this.context = context;
        const gl = context.gl;
        this.buffer = gl.createBuffer();
        this.dynamicDraw = Boolean(dynamicDraw);

        // The bound index buffer is part of vertex array object state. We don't want to
        // modify whatever VAO happens to be currently bound, so make sure the default
        // vertex array provided by the context is bound instead.
        this.context.unbindVAO();

        context.bindElementBuffer.set(this.buffer);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, array.arrayBuffer, this.dynamicDraw ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW);

        if (!this.dynamicDraw) {
            array.destroy();
        }
    }

    bind() {
        this.context.bindElementBuffer.set(this.buffer);
    }

    updateData(array             ) {
        const gl = this.context.gl;
        assert$1(this.dynamicDraw);
        // The right VAO will get this buffer re-bound later in VertexArrayObject#bind
        // See https://github.com/mapbox/mapbox-gl-js/issues/5620
        this.context.unbindVAO();
        this.bind();
        gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, array.arrayBuffer);
    }

    destroy() {
        const gl = this.context.gl;
        if (this.buffer) {
            gl.deleteBuffer(this.buffer);
            delete this.buffer;
        }
    }
}

//      


             
                
                     
                                 

                                                
                                            

/**
 * @enum {string} AttributeType
 * @private
 * @readonly
 */
const AttributeType = {
    Int8:   'BYTE',
    Uint8:  'UNSIGNED_BYTE',
    Int16:  'SHORT',
    Uint16: 'UNSIGNED_SHORT',
    Int32:  'INT',
    Uint32: 'UNSIGNED_INT',
    Float32: 'FLOAT'
};

/**
 * The `VertexBuffer` class turns a `StructArray` into a WebGL buffer. Each member of the StructArray's
 * Struct type is converted to a WebGL atribute.
 * @private
 */
class VertexBuffer {
                   
                                                  
                     
                          
                     
                         

    /**
     * @param dynamicDraw Whether this buffer will be repeatedly updated.
     * @private
     */
    constructor(context         , array             , attributes                                   , dynamicDraw          ) {
        this.length = array.length;
        this.attributes = attributes;
        this.itemSize = array.bytesPerElement;
        this.dynamicDraw = dynamicDraw;

        this.context = context;
        const gl = context.gl;
        this.buffer = gl.createBuffer();
        context.bindVertexBuffer.set(this.buffer);
        gl.bufferData(gl.ARRAY_BUFFER, array.arrayBuffer, this.dynamicDraw ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW);

        if (!this.dynamicDraw) {
            array.destroy();
        }
    }

    bind() {
        this.context.bindVertexBuffer.set(this.buffer);
    }

    updateData(array             ) {
        assert$1(array.length === this.length);
        const gl = this.context.gl;
        this.bind();
        gl.bufferSubData(gl.ARRAY_BUFFER, 0, array.arrayBuffer);
    }

    enableAttributes(gl                       , program            ) {
        for (let j = 0; j < this.attributes.length; j++) {
            const member = this.attributes[j];
            const attribIndex                = program.attributes[member.name];
            if (attribIndex !== undefined) {
                gl.enableVertexAttribArray(attribIndex);
            }
        }
    }

    /**
     * Set the attribute pointers in a WebGL context.
     * @param gl The WebGL context.
     * @param program The active WebGL program.
     * @param vertexOffset Index of the starting vertex of the segment.
     */
    setVertexAttribPointers(gl                       , program            , vertexOffset         ) {
        for (let j = 0; j < this.attributes.length; j++) {
            const member = this.attributes[j];
            const attribIndex                = program.attributes[member.name];

            if (attribIndex !== undefined) {
                gl.vertexAttribPointer(
                    attribIndex,
                    member.components,
                    (gl     )[AttributeType[member.type]],
                    false,
                    this.itemSize,
                    member.offset + (this.itemSize * (vertexOffset || 0))
                );
            }
        }
    }

    /**
     * Destroy the GL buffer bound to the given WebGL context.
     */
    destroy() {
        const gl = this.context.gl;
        if (this.buffer) {
            gl.deleteBuffer(this.buffer);
            delete this.buffer;
        }
    }
}

//      


                                        
             
                  
                      
                  
                   
                  
                    
                  
                  
                    
                 
                     
                  
                    

                           
               
               
                   
             
                       
                        
 

class BaseValue                        {
                              
               
               
                   

    constructor(context         ) {
        this.gl = context.gl;
        this.default = this.getDefault();
        this.current = this.default;
        this.dirty = false;
    }

    get()    {
        return this.current;
    }
    set(value   ) { // eslint-disable-line
        // overridden in child classes;
    }

    getDefault()    {
        return this.default; // overriden in child classes
    }
    setDefault() {
        this.set(this.default);
    }
}

class ClearColor extends BaseValue        {
    getDefault()        {
        return Color.transparent;
    }
    set(v       ) {
        const c = this.current;
        if (v.r === c.r && v.g === c.g && v.b === c.b && v.a === c.a && !this.dirty) return;
        this.gl.clearColor(v.r, v.g, v.b, v.a);
        this.current = v;
        this.dirty = false;
    }
}

class ClearDepth extends BaseValue         {
    getDefault()         {
        return 1;
    }
    set(v        ) {
        if (v === this.current && !this.dirty) return;
        this.gl.clearDepth(v);
        this.current = v;
        this.dirty = false;
    }
}

class ClearStencil extends BaseValue         {
    getDefault()         {
        return 0;
    }
    set(v        ) {
        if (v === this.current && !this.dirty) return;
        this.gl.clearStencil(v);
        this.current = v;
        this.dirty = false;
    }
}

class ColorMask extends BaseValue                {
    getDefault()                {
        return [true, true, true, true];
    }
    set(v               ) {
        const c = this.current;
        if (v[0] === c[0] && v[1] === c[1] && v[2] === c[2] && v[3] === c[3] && !this.dirty) return;
        this.gl.colorMask(v[0], v[1], v[2], v[3]);
        this.current = v;
        this.dirty = false;
    }
}

class DepthMask extends BaseValue                {
    getDefault()                {
        return true;
    }
    set(v               )       {
        if (v === this.current && !this.dirty) return;
        this.gl.depthMask(v);
        this.current = v;
        this.dirty = false;
    }
}

class StencilMask extends BaseValue         {
    getDefault()         {
        return 0xFF;
    }
    set(v        )       {
        if (v === this.current && !this.dirty) return;
        this.gl.stencilMask(v);
        this.current = v;
        this.dirty = false;
    }
}

class StencilFunc extends BaseValue                  {
    getDefault()                  {
        return {
            func: this.gl.ALWAYS,
            ref: 0,
            mask: 0xFF
        };
    }
    set(v                 )       {
        const c = this.current;
        if (v.func === c.func && v.ref === c.ref && v.mask === c.mask && !this.dirty) return;
        // Assume UNSIGNED_INT_24_8 storage, with 8 bits dedicated to stencil.
        // Please revise your stencil values if this threshold is triggered.
        assert$1(v.ref >= 0 && v.ref <= 255);
        this.gl.stencilFunc(v.func, v.ref, v.mask);
        this.current = v;
        this.dirty = false;
    }
}

class StencilOp extends BaseValue                {
    getDefault()                {
        const gl = this.gl;
        return [gl.KEEP, gl.KEEP, gl.KEEP];
    }
    set(v               ) {
        const c = this.current;
        if (v[0] === c[0] && v[1] === c[1] && v[2] === c[2] && !this.dirty) return;
        this.gl.stencilOp(v[0], v[1], v[2]);
        this.current = v;
        this.dirty = false;
    }
}

class StencilTest extends BaseValue          {
    getDefault()          {
        return false;
    }
    set(v         ) {
        if (v === this.current && !this.dirty) return;
        const gl = this.gl;
        if (v) {
            gl.enable(gl.STENCIL_TEST);
        } else {
            gl.disable(gl.STENCIL_TEST);
        }
        this.current = v;
        this.dirty = false;
    }
}

class DepthRange extends BaseValue                 {
    getDefault()                 {
        return [0, 1];
    }
    set(v                ) {
        const c = this.current;
        if (v[0] === c[0] && v[1] === c[1] && !this.dirty) return;
        this.gl.depthRange(v[0], v[1]);
        this.current = v;
        this.dirty = false;
    }
}

class DepthTest extends BaseValue          {
    getDefault()          {
        return false;
    }
    set(v         ) {
        if (v === this.current && !this.dirty) return;
        const gl = this.gl;
        if (v) {
            gl.enable(gl.DEPTH_TEST);
        } else {
            gl.disable(gl.DEPTH_TEST);
        }
        this.current = v;
        this.dirty = false;
    }
}

class DepthFunc extends BaseValue                {
    getDefault()                {
        return this.gl.LESS;
    }
    set(v               ) {
        if (v === this.current && !this.dirty) return;
        this.gl.depthFunc(v);
        this.current = v;
        this.dirty = false;
    }
}

class Blend extends BaseValue          {
    getDefault()          {
        return false;
    }
    set(v         ) {
        if (v === this.current && !this.dirty) return;
        const gl = this.gl;
        if (v) {
            gl.enable(gl.BLEND);
        } else {
            gl.disable(gl.BLEND);
        }
        this.current = v;
        this.dirty = false;
    }
}

class BlendFunc extends BaseValue                {
    getDefault()                {
        const gl = this.gl;
        return [gl.ONE, gl.ZERO];
    }
    set(v               ) {
        const c = this.current;
        if (v[0] === c[0] && v[1] === c[1] && !this.dirty) return;
        this.gl.blendFunc(v[0], v[1]);
        this.current = v;
        this.dirty = false;
    }
}

class BlendColor extends BaseValue        {
    getDefault()        {
        return Color.transparent;
    }
    set(v       ) {
        const c = this.current;
        if (v.r === c.r && v.g === c.g && v.b === c.b && v.a === c.a && !this.dirty) return;
        this.gl.blendColor(v.r, v.g, v.b, v.a);
        this.current = v;
        this.dirty = false;
    }
}

class BlendEquation extends BaseValue                    {
    getDefault()                    {
        return this.gl.FUNC_ADD;
    }
    set(v                   ) {
        if (v === this.current && !this.dirty) return;
        this.gl.blendEquation(v);
        this.current = v;
        this.dirty = false;
    }
}

class CullFace extends BaseValue          {
    getDefault()          {
        return false;
    }
    set(v         ) {
        if (v === this.current && !this.dirty) return;
        const gl = this.gl;
        if (v) {
            gl.enable(gl.CULL_FACE);
        } else {
            gl.disable(gl.CULL_FACE);
        }
        this.current = v;
        this.dirty = false;
    }
}

class CullFaceSide extends BaseValue                   {
    getDefault()                   {
        return this.gl.BACK;
    }
    set(v                  ) {
        if (v === this.current && !this.dirty) return;
        this.gl.cullFace(v);
        this.current = v;
        this.dirty = false;
    }
}

class FrontFace extends BaseValue                {
    getDefault()                {
        return this.gl.CCW;
    }
    set(v               ) {
        if (v === this.current && !this.dirty) return;
        this.gl.frontFace(v);
        this.current = v;
        this.dirty = false;
    }
}

class Program extends BaseValue                {
    getDefault()                      {
        return null;
    }
    set(v               ) {
        if (v === this.current && !this.dirty) return;
        this.gl.useProgram(v);
        this.current = v;
        this.dirty = false;
    }
}

class ActiveTextureUnit extends BaseValue                  {
    getDefault()                  {
        return this.gl.TEXTURE0;
    }
    set(v                 ) {
        if (v === this.current && !this.dirty) return;
        this.gl.activeTexture(v);
        this.current = v;
        this.dirty = false;
    }
}

class Viewport extends BaseValue               {
    getDefault()               {
        const gl = this.gl;
        return [0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight];
    }
    set(v              ) {
        const c = this.current;
        if (v[0] === c[0] && v[1] === c[1] && v[2] === c[2] && v[3] === c[3] && !this.dirty) return;
        this.gl.viewport(v[0], v[1], v[2], v[3]);
        this.current = v;
        this.dirty = false;
    }
}

class BindFramebuffer extends BaseValue                    {
    getDefault()                          {
        return null;
    }
    set(v                   ) {
        if (v === this.current && !this.dirty) return;
        const gl = this.gl;
        gl.bindFramebuffer(gl.FRAMEBUFFER, v);
        this.current = v;
        this.dirty = false;
    }
}

class BindRenderbuffer extends BaseValue                     {
    getDefault()                           {
        return null;
    }
    set(v                    ) {
        if (v === this.current && !this.dirty) return;
        const gl = this.gl;
        gl.bindRenderbuffer(gl.RENDERBUFFER, v);
        this.current = v;
        this.dirty = false;
    }
}

class BindTexture extends BaseValue                {
    getDefault()                      {
        return null;
    }
    set(v               ) {
        if (v === this.current && !this.dirty) return;
        const gl = this.gl;
        gl.bindTexture(gl.TEXTURE_2D, v);
        this.current = v;
        this.dirty = false;
    }
}

class BindVertexBuffer extends BaseValue               {
    getDefault()                     {
        return null;
    }
    set(v              ) {
        if (v === this.current && !this.dirty) return;
        const gl = this.gl;
        gl.bindBuffer(gl.ARRAY_BUFFER, v);
        this.current = v;
        this.dirty = false;
    }
}

class BindElementBuffer extends BaseValue               {
    getDefault()                     {
        return null;
    }
    set(v              ) {
        // Always rebind
        const gl = this.gl;
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, v);
        this.current = v;
        this.dirty = false;
    }
}

class BindVertexArrayOES extends BaseValue      {
             

    constructor(context         ) {
        super(context);
        this.vao = context.extVertexArrayObject;
    }
    getDefault()      {
        return null;
    }
    set(v     ) {
        if (!this.vao || (v === this.current && !this.dirty)) return;
        this.vao.bindVertexArrayOES(v);
        this.current = v;
        this.dirty = false;
    }
}

class PixelStoreUnpack extends BaseValue         {
    getDefault()         {
        return 4;
    }
    set(v        ) {
        if (v === this.current && !this.dirty) return;
        const gl = this.gl;
        gl.pixelStorei(gl.UNPACK_ALIGNMENT, v);
        this.current = v;
        this.dirty = false;
    }
}

class PixelStoreUnpackPremultiplyAlpha extends BaseValue          {
    getDefault()          {
        return false;
    }
    set(v         )       {
        if (v === this.current && !this.dirty) return;
        const gl = this.gl;
        gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, (v     ));
        this.current = v;
        this.dirty = false;
    }
}

class PixelStoreUnpackFlipY extends BaseValue          {
    getDefault()          {
        return false;
    }
    set(v         )       {
        if (v === this.current && !this.dirty) return;
        const gl = this.gl;
        gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, (v     ));
        this.current = v;
        this.dirty = false;
    }
}

class FramebufferAttachment    extends BaseValue     {
                             
                     

    constructor(context         , parent                  ) {
        super(context);
        this.context = context;
        this.parent = parent;
    }
    getDefault()       {
        return null;
    }
}

class ColorAttachment extends FramebufferAttachment               {
    setDirty() {
        this.dirty = true;
    }
    set(v               )       {
        if (v === this.current && !this.dirty) return;
        this.context.bindFramebuffer.set(this.parent);
        // note: it's possible to attach a renderbuffer to the color
        // attachment point, but thus far MBGL only uses textures for color
        const gl = this.gl;
        gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, v, 0);
        this.current = v;
        this.dirty = false;
    }
}

class DepthAttachment extends FramebufferAttachment                    {
    attachment()         { return this.gl.DEPTH_ATTACHMENT; }
    set(v                    )       {
        if (v === this.current && !this.dirty) return;
        this.context.bindFramebuffer.set(this.parent);
        // note: it's possible to attach a texture to the depth attachment
        // point, but thus far MBGL only uses renderbuffers for depth
        const gl = this.gl;
        gl.framebufferRenderbuffer(gl.FRAMEBUFFER, this.attachment(), gl.RENDERBUFFER, v);
        this.current = v;
        this.dirty = false;
    }
}

class DepthStencilAttachment extends DepthAttachment {
    attachment()         { return this.gl.DEPTH_STENCIL_ATTACHMENT; }
}

//      

class Framebuffer {
                     
                  
                   
                                  
                                     
                                     

    constructor(context         , width        , height        , hasDepth         ) {
        this.context = context;
        this.width = width;
        this.height = height;
        const gl = context.gl;
        const fbo = this.framebuffer = ((gl.createFramebuffer()     )                  );

        this.colorAttachment = new ColorAttachment(context, fbo);
        if (hasDepth) {
            this.depthAttachment = new DepthAttachment(context, fbo);
        }
        assert$1(gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE);
    }

    destroy() {
        const gl = this.context.gl;

        const texture = this.colorAttachment.get();
        if (texture) gl.deleteTexture(texture);

        if (this.depthAttachment) {
            const renderbuffer = this.depthAttachment.get();
            if (renderbuffer) gl.deleteRenderbuffer(renderbuffer);
        }

        gl.deleteFramebuffer(this.framebuffer);
    }
}

//      
                                                                             

const ALWAYS$1 = 0x0207;

class DepthMode {
                        
                        
                          

    // DepthMask enums
                             
                              

    constructor(depthFunc               , depthMask               , depthRange                ) {
        this.func = depthFunc;
        this.mask = depthMask;
        this.range = depthRange;
    }

                                          
}

DepthMode.ReadOnly = false;
DepthMode.ReadWrite = true;

DepthMode.disabled = new DepthMode(ALWAYS$1, DepthMode.ReadOnly, [0, 1]);

//      
                                                               

const ALWAYS = 0x0207;
const KEEP = 0x1E00;

class StencilMode {
                      
                
                 
                            
                                 
                            

    constructor(test             , ref        , mask        , fail                   ,
        depthFail                   , pass                   ) {
        this.test = test;
        this.ref = ref;
        this.mask = mask;
        this.fail = fail;
        this.depthFail = depthFail;
        this.pass = pass;
    }

                                            
}

StencilMode.disabled = new StencilMode({func: ALWAYS, mask: 0}, 0, 0, KEEP, KEEP, KEEP);

//      

                                                             

const ZERO = 0x0000;
const ONE = 0x0001;
const ONE_MINUS_SRC_ALPHA = 0x0303;

class ColorMode {
                                 
                      
                        

    constructor(blendFunction               , blendColor       , mask               ) {
        this.blendFunction = blendFunction;
        this.blendColor = blendColor;
        this.mask = mask;
    }

                                  

                                          
                                           
                                              
}

ColorMode.Replace = [ONE, ZERO];

ColorMode.disabled = new ColorMode(ColorMode.Replace, Color.transparent, [false, false, false, false]);
ColorMode.unblended = new ColorMode(ColorMode.Replace, Color.transparent, [true, true, true, true]);
ColorMode.alphaBlended = new ColorMode([ONE, ONE_MINUS_SRC_ALPHA], Color.transparent, [true, true, true, true]);

//      

                                                                

const BACK = 0x0405;
const FRONT = 0x0404;
const CCW = 0x0901;
const CW = 0x0900;

class CullFaceMode {
                    
                           
                             

    constructor(enable         , mode                  , frontFace               ) {
        this.enable = enable;
        this.mode = mode;
        this.frontFace = frontFace;
    }

                                             
                                            
                                           
                                            
                                             
}

CullFaceMode.disabled = new CullFaceMode(false, BACK, CCW);
CullFaceMode.backCCW = new CullFaceMode(true, BACK, CCW);
CullFaceMode.backCW = new CullFaceMode(true, BACK, CW);
CullFaceMode.frontCW = new CullFaceMode(true, FRONT, CW);
CullFaceMode.frontCCW = new CullFaceMode(true, FRONT, CCW);

//      

                                                                                                         
             
                
                     
                                 
                                                     

                  
                  
                   
                    
  

class Context {
                              
                      
                              
                                  
                           

                           
                           
                               
                         
                         
                             
                             
                         
                             
                           
                         
                         
                 
                         
                           
                                 
                       
                               
                         
                     
                                     
                       
                                     
                                       
                             
                                       
                                         
                                           
                                       
                                                                       
                                                 
                      
                    

                                     
                                        
                             
                                     
                                
                              
                       

                                                 
                                            

    constructor(gl                       , isWebGL2          = false) {
        this.gl = gl;
        this.isWebGL2 = isWebGL2;
        this.extVertexArrayObject = this.gl.getExtension('OES_vertex_array_object');

        if (isWebGL2) {
            /* $FlowFixMe[cannot-resolve-name] */ // Not adding dependency to webgl2 yet.
            const gl2 = (gl                        );
            this.extVertexArrayObject = {
                createVertexArrayOES: gl2.createVertexArray.bind(gl),
                deleteVertexArrayOES: gl2.deleteVertexArray.bind(gl),
                bindVertexArrayOES: gl2.bindVertexArray.bind(gl)
            };
        }

        this.clearColor = new ClearColor(this);
        this.clearDepth = new ClearDepth(this);
        this.clearStencil = new ClearStencil(this);
        this.colorMask = new ColorMask(this);
        this.depthMask = new DepthMask(this);
        this.stencilMask = new StencilMask(this);
        this.stencilFunc = new StencilFunc(this);
        this.stencilOp = new StencilOp(this);
        this.stencilTest = new StencilTest(this);
        this.depthRange = new DepthRange(this);
        this.depthTest = new DepthTest(this);
        this.depthFunc = new DepthFunc(this);
        this.blend = new Blend(this);
        this.blendFunc = new BlendFunc(this);
        this.blendColor = new BlendColor(this);
        this.blendEquation = new BlendEquation(this);
        this.cullFace = new CullFace(this);
        this.cullFaceSide = new CullFaceSide(this);
        this.frontFace = new FrontFace(this);
        this.program = new Program(this);
        this.activeTexture = new ActiveTextureUnit(this);
        this.viewport = new Viewport(this);
        this.bindFramebuffer = new BindFramebuffer(this);
        this.bindRenderbuffer = new BindRenderbuffer(this);
        this.bindTexture = new BindTexture(this);
        this.bindVertexBuffer = new BindVertexBuffer(this);
        this.bindElementBuffer = new BindElementBuffer(this);
        this.bindVertexArrayOES = this.extVertexArrayObject && new BindVertexArrayOES(this);
        this.pixelStoreUnpack = new PixelStoreUnpack(this);
        this.pixelStoreUnpackPremultiplyAlpha = new PixelStoreUnpackPremultiplyAlpha(this);
        this.pixelStoreUnpackFlipY = new PixelStoreUnpackFlipY(this);

        this.extTextureFilterAnisotropic = (
            gl.getExtension('EXT_texture_filter_anisotropic') ||
            gl.getExtension('MOZ_EXT_texture_filter_anisotropic') ||
            gl.getExtension('WEBKIT_EXT_texture_filter_anisotropic')
        );
        if (this.extTextureFilterAnisotropic) {
            this.extTextureFilterAnisotropicMax = gl.getParameter(this.extTextureFilterAnisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
        }
        this.extTextureFilterAnisotropicForceOff = false;
        this.extStandardDerivativesForceOff = false;

        this.extDebugRendererInfo = gl.getExtension('WEBGL_debug_renderer_info');
        if (this.extDebugRendererInfo) {
            this.renderer = gl.getParameter(this.extDebugRendererInfo.UNMASKED_RENDERER_WEBGL);
            this.vendor = gl.getParameter(this.extDebugRendererInfo.UNMASKED_VENDOR_WEBGL);
        }

        if (!isWebGL2) this.extTextureHalfFloat = gl.getExtension('OES_texture_half_float');
        if (isWebGL2 || (this.extTextureHalfFloat && gl.getExtension('OES_texture_half_float_linear'))) {
            this.extRenderToTextureHalfFloat = gl.getExtension('EXT_color_buffer_half_float');
        }
        this.extStandardDerivatives = isWebGL2 || gl.getExtension('OES_standard_derivatives');

        this.extTimerQuery = gl.getExtension('EXT_disjoint_timer_query');
        this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
    }

    setDefault() {
        this.unbindVAO();

        this.clearColor.setDefault();
        this.clearDepth.setDefault();
        this.clearStencil.setDefault();
        this.colorMask.setDefault();
        this.depthMask.setDefault();
        this.stencilMask.setDefault();
        this.stencilFunc.setDefault();
        this.stencilOp.setDefault();
        this.stencilTest.setDefault();
        this.depthRange.setDefault();
        this.depthTest.setDefault();
        this.depthFunc.setDefault();
        this.blend.setDefault();
        this.blendFunc.setDefault();
        this.blendColor.setDefault();
        this.blendEquation.setDefault();
        this.cullFace.setDefault();
        this.cullFaceSide.setDefault();
        this.frontFace.setDefault();
        this.program.setDefault();
        this.activeTexture.setDefault();
        this.bindFramebuffer.setDefault();
        this.pixelStoreUnpack.setDefault();
        this.pixelStoreUnpackPremultiplyAlpha.setDefault();
        this.pixelStoreUnpackFlipY.setDefault();
    }

    setDirty() {
        this.clearColor.dirty = true;
        this.clearDepth.dirty = true;
        this.clearStencil.dirty = true;
        this.colorMask.dirty = true;
        this.depthMask.dirty = true;
        this.stencilMask.dirty = true;
        this.stencilFunc.dirty = true;
        this.stencilOp.dirty = true;
        this.stencilTest.dirty = true;
        this.depthRange.dirty = true;
        this.depthTest.dirty = true;
        this.depthFunc.dirty = true;
        this.blend.dirty = true;
        this.blendFunc.dirty = true;
        this.blendColor.dirty = true;
        this.blendEquation.dirty = true;
        this.cullFace.dirty = true;
        this.cullFaceSide.dirty = true;
        this.frontFace.dirty = true;
        this.program.dirty = true;
        this.activeTexture.dirty = true;
        this.viewport.dirty = true;
        this.bindFramebuffer.dirty = true;
        this.bindRenderbuffer.dirty = true;
        this.bindTexture.dirty = true;
        this.bindVertexBuffer.dirty = true;
        this.bindElementBuffer.dirty = true;
        if (this.extVertexArrayObject) {
            this.bindVertexArrayOES.dirty = true;
        }
        this.pixelStoreUnpack.dirty = true;
        this.pixelStoreUnpackPremultiplyAlpha.dirty = true;
        this.pixelStoreUnpackFlipY.dirty = true;
    }

    createIndexBuffer(array                                                           , dynamicDraw          )              {
        return new IndexBuffer(this, array, dynamicDraw);
    }

    createVertexBuffer(array             , attributes                                   , dynamicDraw          )               {
        return new VertexBuffer(this, array, attributes, dynamicDraw);
    }

    createRenderbuffer(storageFormat        , width        , height        )                     {
        const gl = this.gl;

        const rbo = gl.createRenderbuffer();
        this.bindRenderbuffer.set(rbo);
        gl.renderbufferStorage(gl.RENDERBUFFER, storageFormat, width, height);
        this.bindRenderbuffer.set(null);

        return rbo;
    }

    createFramebuffer(width        , height        , hasDepth         )              {
        return new Framebuffer(this, width, height, hasDepth);
    }

    clear({color, depth, stencil}           ) {
        const gl = this.gl;
        let mask = 0;

        if (color) {
            mask |= gl.COLOR_BUFFER_BIT;
            this.clearColor.set(color);
            this.colorMask.set([true, true, true, true]);
        }

        if (typeof depth !== 'undefined') {
            mask |= gl.DEPTH_BUFFER_BIT;

            // Workaround for platforms where clearDepth doesn't seem to work
            // without reseting the depthRange. See https://github.com/mapbox/mapbox-gl-js/issues/3437
            this.depthRange.set([0, 1]);

            this.clearDepth.set(depth);
            this.depthMask.set(true);
        }

        if (typeof stencil !== 'undefined') {
            mask |= gl.STENCIL_BUFFER_BIT;
            this.clearStencil.set(stencil);
            this.stencilMask.set(0xFF);
        }

        gl.clear(mask);
    }

    setCullFace(cullFaceMode                         ) {
        if (cullFaceMode.enable === false) {
            this.cullFace.set(false);
        } else {
            this.cullFace.set(true);
            this.cullFaceSide.set(cullFaceMode.mode);
            this.frontFace.set(cullFaceMode.frontFace);
        }
    }

    setDepthMode(depthMode                      ) {
        if (depthMode.func === this.gl.ALWAYS && !depthMode.mask) {
            this.depthTest.set(false);
        } else {
            this.depthTest.set(true);
            this.depthFunc.set(depthMode.func);
            this.depthMask.set(depthMode.mask);
            this.depthRange.set(depthMode.range);
        }
    }

    setStencilMode(stencilMode                        ) {
        if (stencilMode.test.func === this.gl.ALWAYS && !stencilMode.mask) {
            this.stencilTest.set(false);
        } else {
            this.stencilTest.set(true);
            this.stencilMask.set(stencilMode.mask);
            this.stencilOp.set([stencilMode.fail, stencilMode.depthFail, stencilMode.pass]);
            this.stencilFunc.set({
                func: stencilMode.test.func,
                ref: stencilMode.ref,
                mask: stencilMode.test.mask
            });
        }
    }

    setColorMode(colorMode                      ) {
        if (deepEqual(colorMode.blendFunction, ColorMode.Replace)) {
            this.blend.set(false);
        } else {
            this.blend.set(true);
            this.blendFunc.set(colorMode.blendFunction);
            this.blendColor.set(colorMode.blendColor);
        }

        this.colorMask.set(colorMode.mask);
    }

    unbindVAO() {
        // Unbinding the VAO prevents other things (custom layers, new buffer creation) from
        // unintentionally changing the state of the last VAO used.
        if (this.extVertexArrayObject) {
            this.bindVertexArrayOES.set(null);
        }
    }
}

//      


                                        
                                                                
                                                       
                                           
                                                 
                                         
                                                   
                                                     
                                                                                      

/**
 * `SourceCache` is responsible for
 *
 *  - creating an instance of `Source`
 *  - forwarding events from `Source`
 *  - caching tiles loaded from an instance of `Source`
 *  - loading the tiles needed to render a given viewport
 *  - unloading the cached tiles not needed to render a given viewport
 *
 * @private
 */
class SourceCache extends Evented {
               
                   
                 

                    
                           
                            
                                         
                            
                      
                                   
                                        
                               
                               
                     
                       
                                   
                                                   
                         
                  
                            
                               
                                                      
                           

                                   
                                  

    constructor(id        , source        , onlySymbols          ) {
        super();
        this.id = id;
        this._onlySymbols = onlySymbols;

        source.on('data', (e) => {
            // this._sourceLoaded signifies that the TileJSON is loaded if applicable.
            // if the source type does not come with a TileJSON, the flag signifies the
            // source data has loaded (in other words, GeoJSON has been tiled on the worker and is ready)
            if (e.dataType === 'source' && e.sourceDataType === 'metadata') this._sourceLoaded = true;

            // for sources with mutable data, this event fires when the underlying data
            // to a source is changed (for example, using [GeoJSONSource#setData](https://docs.mapbox.com/mapbox-gl-js/api/sources/#geojsonsource#setdata) or [ImageSource#setCoordinates](https://docs.mapbox.com/mapbox-gl-js/api/sources/#imagesource#setcoordinates))
            if (this._sourceLoaded && !this._paused && e.dataType === "source" && e.sourceDataType === 'content') {
                this.reload();
                if (this.transform) {
                    this.update(this.transform);
                }
            }
        });

        source.on('error', () => {
            this._sourceErrored = true;
        });

        this._source = source;
        this._tiles = {};
        // $FlowFixMe[method-unbinding]
        this._cache = new TileCache(0, this._unloadTile.bind(this));
        this._timers = {};
        this._cacheTimers = {};
        this._minTileCacheSize = source.minTileCacheSize;
        this._maxTileCacheSize = source.maxTileCacheSize;
        this._loadedParentTiles = {};

        this._coveredTiles = {};
        this._state = new SourceFeatureState();
        this._isRaster =
            this._source.type === 'raster' ||
            this._source.type === 'raster-dem' ||
            // $FlowFixMe[prop-missing]
            (this._source.type === 'custom' && this._source._dataType === 'raster');
    }

    onAdd(map           ) {
        this.map = map;
        this._minTileCacheSize = this._minTileCacheSize === undefined && map ? map._minTileCacheSize : this._minTileCacheSize;
        this._maxTileCacheSize = this._maxTileCacheSize === undefined && map ? map._maxTileCacheSize : this._maxTileCacheSize;
    }

    /**
     * Return true if no tile data is pending, tiles will not change unless
     * an additional API call is received.
     * @private
     */
    loaded()          {
        if (this._sourceErrored) { return true; }
        if (!this._sourceLoaded) { return false; }
        if (!this._source.loaded()) { return false; }
        for (const t in this._tiles) {
            const tile = this._tiles[t];
            if (tile.state !== 'loaded' && tile.state !== 'errored')
                return false;
        }
        return true;
    }

    getSource()         {
        return this._source;
    }

    pause() {
        this._paused = true;
    }

    resume() {
        if (!this._paused) return;
        const shouldReload = this._shouldReloadOnResume;
        this._paused = false;
        this._shouldReloadOnResume = false;
        if (shouldReload) this.reload();
        if (this.transform) this.update(this.transform);
    }

    _loadTile(tile      , callback                )       {
        tile.isSymbolTile = this._onlySymbols;
        return this._source.loadTile(tile, callback);
    }

    _unloadTile(tile      )       {
        if (this._source.unloadTile)
            return this._source.unloadTile(tile, () => {});
    }

    _abortTile(tile      )       {
        if (this._source.abortTile)
            return this._source.abortTile(tile, () => {});
    }

    serialize()                      {
        return this._source.serialize();
    }

    prepare(context         ) {
        if  (this._source.prepare) {
            this._source.prepare();
        }

        this._state.coalesceChanges(this._tiles, this.map ? this.map.painter : null);

        for (const i in this._tiles) {
            const tile = this._tiles[i];
            tile.upload(context);
            tile.prepare(this.map.style.imageManager);
        }
    }

    /**
     * Return all tile ids ordered with z-order, and cast to numbers
     * @private
     */
    getIds()                {
        return values((this._tiles     )).map((tile      ) => tile.tileID).sort(compareTileId).map(id => id.key);
    }

    getRenderableIds(symbolLayer          )                {
        const renderables              = [];
        for (const id in this._tiles) {
            if (this._isIdRenderable(+id, symbolLayer)) renderables.push(this._tiles[id]);
        }
        if (symbolLayer) {
            return renderables.sort((a_      , b_      ) => {
                const a = a_.tileID;
                const b = b_.tileID;
                const rotatedA = (new Point$2(a.canonical.x, a.canonical.y))._rotate(this.transform.angle);
                const rotatedB = (new Point$2(b.canonical.x, b.canonical.y))._rotate(this.transform.angle);
                return a.overscaledZ - b.overscaledZ || rotatedB.y - rotatedA.y || rotatedB.x - rotatedA.x;
            }).map(tile => tile.tileID.key);
        }
        return renderables.map(tile => tile.tileID).sort(compareTileId).map(id => id.key);
    }

    hasRenderableParent(tileID                  )          {
        const parentTile = this.findLoadedParent(tileID, 0);
        if (parentTile) {
            return this._isIdRenderable(parentTile.tileID.key);
        }
        return false;
    }

    _isIdRenderable(id        , symbolLayer          )          {
        return this._tiles[id] && this._tiles[id].hasData() &&
            !this._coveredTiles[id] && (symbolLayer || !this._tiles[id].holdingForFade());
    }

    reload() {
        if (this._paused) {
            this._shouldReloadOnResume = true;
            return;
        }

        this._cache.reset();

        for (const i in this._tiles) {
            if (this._tiles[i].state !== "errored") this._reloadTile(+i, 'reloading');
        }
    }

    _reloadTile(id        , state           ) {
        const tile = this._tiles[id];

        // this potentially does not address all underlying
        // issues https://github.com/mapbox/mapbox-gl-js/issues/4252
        // - hard to tell without repro steps
        if (!tile) return;

        // The difference between "loading" tiles and "reloading" or "expired"
        // tiles is that "reloading"/"expired" tiles are "renderable".
        // Therefore, a "loading" tile cannot become a "reloading" tile without
        // first becoming a "loaded" tile.
        if (tile.state !== 'loading') {
            tile.state = state;
        }

        // $FlowFixMe[method-unbinding]
        this._loadTile(tile, this._tileLoaded.bind(this, tile, id, state));
    }

    _tileLoaded(tile      , id        , previousState           , err        ) {
        if (err) {
            tile.state = 'errored';
            if ((err     ).status !== 404) this._source.fire(new ErrorEvent(err, {tile}));
            else {
                // continue to try loading parent/children tiles if a tile doesn't exist (404)
                const updateForTerrain = this._source.type === 'raster-dem' && this.usedForTerrain;
                if (updateForTerrain && this.map.painter.terrain) {
                    const terrain = this.map.painter.terrain;
                    this.update(this.transform, terrain.getScaledDemTileSize(), true);
                    terrain.resetTileLookupCache(this.id);
                } else {
                    this.update(this.transform);
                }
            }
            return;
        }

        tile.timeAdded = exported.now();
        if (previousState === 'expired') tile.refreshedUponExpiration = true;
        this._setTileReloadTimer(id, tile);
        if (this._source.type === 'raster-dem' && tile.dem) this._backfillDEM(tile);
        this._state.initializeTileState(tile, this.map ? this.map.painter : null);

        this._source.fire(new Event('data', {dataType: 'source', tile, coord: tile.tileID, 'sourceCacheId': this.id}));
    }

    /**
    * For raster terrain source, backfill DEM to eliminate visible tile boundaries
    * @private
    */
    _backfillDEM(tile      ) {
        const renderables = this.getRenderableIds();
        for (let i = 0; i < renderables.length; i++) {
            const borderId = renderables[i];
            if (tile.neighboringTiles && tile.neighboringTiles[borderId]) {
                const borderTile = this.getTileByID(borderId);
                fillBorder(tile, borderTile);
                fillBorder(borderTile, tile);
            }
        }

        function fillBorder(tile      , borderTile      ) {
            if (!tile.dem || tile.dem.borderReady) return;
            tile.needsHillshadePrepare = true;
            tile.needsDEMTextureUpload = true;
            let dx = borderTile.tileID.canonical.x - tile.tileID.canonical.x;
            const dy = borderTile.tileID.canonical.y - tile.tileID.canonical.y;
            const dim = Math.pow(2, tile.tileID.canonical.z);
            const borderId = borderTile.tileID.key;
            if (dx === 0 && dy === 0) return;

            if (Math.abs(dy) > 1) {
                return;
            }
            if (Math.abs(dx) > 1) {
                // Adjust the delta coordinate for world wraparound.
                if (Math.abs(dx + dim) === 1) {
                    dx += dim;
                } else if (Math.abs(dx - dim) === 1) {
                    dx -= dim;
                }
            }
            if (!borderTile.dem || !tile.dem) return;
            tile.dem.backfillBorder(borderTile.dem, dx, dy);
            if (tile.neighboringTiles && tile.neighboringTiles[borderId])
                tile.neighboringTiles[borderId].backfilled = true;
        }
    }
    /**
     * Get a specific tile by TileID
     * @private
     */
    getTile(tileID                  )       {
        return this.getTileByID(tileID.key);
    }

    /**
     * Get a specific tile by id
     * @private
     */
    getTileByID(id        )       {
        return this._tiles[id];
    }

    /**
     * For a given set of tiles, retain children that are loaded and have a zoom
     * between `zoom` (exclusive) and `maxCoveringZoom` (inclusive)
     * @private
     */
    _retainLoadedChildren(
        idealTiles                                       ,
        zoom        ,
        maxCoveringZoom        ,
        retain                                       
    ) {
        for (const id in this._tiles) {
            let tile = this._tiles[id];

            // only consider renderable tiles up to maxCoveringZoom
            if (retain[id] ||
                !tile.hasData() ||
                tile.tileID.overscaledZ <= zoom ||
                tile.tileID.overscaledZ > maxCoveringZoom
            ) continue;

            // loop through parents and retain the topmost loaded one if found
            let topmostLoadedID = tile.tileID;
            while (tile && tile.tileID.overscaledZ > zoom + 1) {
                const parentID = tile.tileID.scaledTo(tile.tileID.overscaledZ - 1);

                tile = this._tiles[parentID.key];

                if (tile && tile.hasData()) {
                    topmostLoadedID = parentID;
                }
            }

            // loop through ancestors of the topmost loaded child to see if there's one that needed it
            let tileID = topmostLoadedID;
            while (tileID.overscaledZ > zoom) {
                tileID = tileID.scaledTo(tileID.overscaledZ - 1);

                if (idealTiles[tileID.key]) {
                    // found a parent that needed a loaded child; retain that child
                    retain[topmostLoadedID.key] = topmostLoadedID;
                    break;
                }
            }
        }
    }

    /**
     * Find a loaded parent of the given tile (up to minCoveringZoom)
     * @private
     */
    findLoadedParent(tileID                  , minCoveringZoom        )        {
        if (tileID.key in this._loadedParentTiles) {
            const parent = this._loadedParentTiles[tileID.key];
            if (parent && parent.tileID.overscaledZ >= minCoveringZoom) {
                return parent;
            } else {
                return null;
            }
        }
        for (let z = tileID.overscaledZ - 1; z >= minCoveringZoom; z--) {
            const parentTileID = tileID.scaledTo(z);
            const tile = this._getLoadedTile(parentTileID);
            if (tile) {
                return tile;
            }
        }
    }

    _getLoadedTile(tileID                  )        {
        const tile = this._tiles[tileID.key];
        if (tile && tile.hasData()) {
            return tile;
        }
        // TileCache ignores wrap in lookup.
        const cachedTile = this._cache.getByKey(this._source.reparseOverscaled ? tileID.wrapped().key : tileID.canonical.key);
        return cachedTile;
    }

    /**
     * Resizes the tile cache based on the current viewport's size
     * or the minTileCacheSize and maxTileCacheSize options passed during map creation
     *
     * Larger viewports use more tiles and need larger caches. Larger viewports
     * are more likely to be found on devices with more memory and on pages where
     * the map is more important.
     * @private
     */
    updateCacheSize(transform           , tileSize         ) {
        tileSize = tileSize || this._source.tileSize;
        const widthInTiles = Math.ceil(transform.width / tileSize) + 1;
        const heightInTiles = Math.ceil(transform.height / tileSize) + 1;
        const approxTilesInView = widthInTiles * heightInTiles;
        const commonZoomRange = 5;

        const viewDependentMaxSize = Math.floor(approxTilesInView * commonZoomRange);
        const minSize = typeof this._minTileCacheSize === 'number' ? Math.max(this._minTileCacheSize, viewDependentMaxSize) : viewDependentMaxSize;
        const maxSize = typeof this._maxTileCacheSize === 'number' ? Math.min(this._maxTileCacheSize, minSize) : minSize;

        this._cache.setMaxSize(maxSize);
    }

    handleWrapJump(lng        ) {
        // On top of the regular z/x/y values, TileIDs have a `wrap` value that specify
        // which copy of the world the tile belongs to. For example, at `lng: 10` you
        // might render z/x/y/0 while at `lng: 370` you would render z/x/y/1.
        //
        // When lng values get wrapped (going from `lng: 370` to `long: 10`) you expect
        // to see the same thing on the screen (370 degrees and 10 degrees is the same
        // place in the world) but all the TileIDs will have different wrap values.
        //
        // In order to make this transition seamless, we calculate the rounded difference of
        // "worlds" between the last frame and the current frame. If the map panned by
        // a world, then we can assign all the tiles new TileIDs with updated wrap values.
        // For example, assign z/x/y/1 a new id: z/x/y/0. It is the same tile, just rendered
        // in a different position.
        //
        // This enables us to reuse the tiles at more ideal locations and prevent flickering.
        const prevLng = this._prevLng === undefined ? lng : this._prevLng;
        const lngDifference = lng - prevLng;
        const worldDifference = lngDifference / 360;
        const wrapDelta = Math.round(worldDifference);
        this._prevLng = lng;

        if (wrapDelta) {
            const tiles                               = {};
            for (const key in this._tiles) {
                const tile = this._tiles[key];
                tile.tileID = tile.tileID.unwrapTo(tile.tileID.wrap + wrapDelta);
                tiles[tile.tileID.key] = tile;
            }
            this._tiles = tiles;

            // Reset tile reload timers
            for (const id in this._timers) {
                clearTimeout(this._timers[id]);
                delete this._timers[id];
            }
            for (const id in this._tiles) {
                const tile = this._tiles[id];
                this._setTileReloadTimer(+id, tile);
            }
        }
    }

    /**
     * Removes tiles that are outside the viewport and adds new tiles that
     * are inside the viewport.
     * @private
     * @param {boolean} updateForTerrain Signals to update tiles even if the
     * source is not used (this.used) by layers: it is used for terrain.
     * @param {tileSize} tileSize If needed to get lower resolution ideal cover,
     * override source.tileSize used in tile cover calculation.
     */
    update(transform           , tileSize         , updateForTerrain          ) {
        this.transform = transform;
        if (!this._sourceLoaded || this._paused || this.transform.freezeTileCoverage) { return; }
        assert$1(!(updateForTerrain && !this.usedForTerrain));
        if (this.usedForTerrain && !updateForTerrain) {
            // If source is used for both terrain and hillshade, don't update it twice.
            return;
        }

        this.updateCacheSize(transform, tileSize);
        if (this.transform.projection.name !== 'globe') {
            this.handleWrapJump(this.transform.center.lng);
        }

        // Covered is a list of retained tiles who's areas are fully covered by other,
        // better, retained tiles. They are not drawn separately.
        this._coveredTiles = {};

        let idealTileIDs;
        if (!this.used && !this.usedForTerrain) {
            idealTileIDs = [];
        } else if (this._source.tileID) {
            idealTileIDs = transform.getVisibleUnwrappedCoordinates(this._source.tileID)
                .map((unwrapped) => new OverscaledTileID(unwrapped.canonical.z, unwrapped.wrap, unwrapped.canonical.z, unwrapped.canonical.x, unwrapped.canonical.y));
        } else {
            idealTileIDs = transform.coveringTiles({
                tileSize: tileSize || this._source.tileSize,
                minzoom: this._source.minzoom,
                maxzoom: this._source.maxzoom,
                roundZoom: this._source.roundZoom && !updateForTerrain,
                reparseOverscaled: this._source.reparseOverscaled,
                isTerrainDEM: this.usedForTerrain
            });

            if (this._source.hasTile) {
                idealTileIDs = idealTileIDs.filter((coord) => (this._source.hasTile     )(coord));
            }
        }

        // Retain is a list of tiles that we shouldn't delete, even if they are not
        // the most ideal tile for the current viewport. This may include tiles like
        // parent or child tiles that are *already* loaded.
        const retain = this._updateRetainedTiles(idealTileIDs);

        if (isRasterType(this._source.type) && idealTileIDs.length !== 0) {
            const parentsForFading                                           = {};
            const fadingTiles = {};
            const ids = Object.keys(retain);
            for (const id of ids) {
                const tileID = retain[id];
                assert$1(tileID.key === +id);

                const tile = this._tiles[id];
                if (!tile || (tile.fadeEndTime && tile.fadeEndTime <= exported.now())) continue;

                // if the tile is loaded but still fading in, find parents to cross-fade with it
                const parentTile = this.findLoadedParent(tileID, Math.max(tileID.overscaledZ - SourceCache.maxOverzooming, this._source.minzoom));
                if (parentTile) {
                    this._addTile(parentTile.tileID);
                    parentsForFading[parentTile.tileID.key] = parentTile.tileID;
                }

                fadingTiles[id] = tileID;
            }

            // for children tiles with parent tiles still fading in,
            // retain the children so the parent can fade on top
            const minZoom = idealTileIDs[idealTileIDs.length - 1].overscaledZ;
            for (const id in this._tiles) {
                const childTile = this._tiles[id];
                if (retain[id] || !childTile.hasData()) {
                    continue;
                }

                let parentID = childTile.tileID;
                while (parentID.overscaledZ > minZoom) {
                    parentID = parentID.scaledTo(parentID.overscaledZ - 1);
                    const tile = this._tiles[parentID.key];
                    if (tile && tile.hasData() && fadingTiles[parentID.key]) {
                        retain[id] = childTile.tileID;
                        break;
                    }
                }
            }

            for (const id in parentsForFading) {
                if (!retain[id]) {
                    // If a tile is only needed for fading, mark it as covered so that it isn't rendered on it's own.
                    this._coveredTiles[id] = true;
                    retain[id] = parentsForFading[id];
                }
            }
        }

        for (const retainedId in retain) {
            // Make sure retained tiles always clear any existing fade holds
            // so that if they're removed again their fade timer starts fresh.
            this._tiles[retainedId].clearFadeHold();
        }

        // Remove the tiles we don't need anymore.
        const remove = keysDifference((this._tiles     ), (retain     ));
        for (const tileID of remove) {
            const tile = this._tiles[tileID];
            if (tile.hasSymbolBuckets && !tile.holdingForFade()) {
                tile.setHoldDuration(this.map._fadeDuration);
            } else if (!tile.hasSymbolBuckets || tile.symbolFadeFinished()) {
                this._removeTile(+tileID);
            }
        }

        // Construct a cache of loaded parents
        this._updateLoadedParentTileCache();

        if (this._onlySymbols && this._source.afterUpdate) {
            this._source.afterUpdate();
        }
    }

    releaseSymbolFadeTiles() {
        for (const id in this._tiles) {
            if (this._tiles[id].holdingForFade()) {
                this._removeTile(+id);
            }
        }
    }

    _updateRetainedTiles(idealTileIDs                         )                                           {
        const retain                                           = {};
        if (idealTileIDs.length === 0) { return retain; }

        const checked                                   = {};
        const minZoom = idealTileIDs.reduce((min, id) => Math.min(min, id.overscaledZ), Infinity);
        const maxZoom = idealTileIDs[0].overscaledZ;
        assert$1(minZoom <= maxZoom);
        const minCoveringZoom = Math.max(maxZoom - SourceCache.maxOverzooming, this._source.minzoom);
        const maxCoveringZoom = Math.max(maxZoom + SourceCache.maxUnderzooming,  this._source.minzoom);

        const missingTiles = {};
        for (const tileID of idealTileIDs) {
            const tile = this._addTile(tileID);

            // retain the tile even if it's not loaded because it's an ideal tile.
            retain[tileID.key] = tileID;

            if (tile.hasData()) continue;

            if (minZoom < this._source.maxzoom) {
                // save missing tiles that potentially have loaded children
                missingTiles[tileID.key] = tileID;
            }
        }

        // retain any loaded children of ideal tiles up to maxCoveringZoom
        this._retainLoadedChildren(missingTiles, minZoom, maxCoveringZoom, retain);

        for (const tileID of idealTileIDs) {
            let tile = this._tiles[tileID.key];

            if (tile.hasData()) continue;

            // The tile we require is not yet loaded or does not exist;
            // Attempt to find children that fully cover it.

            if (tileID.canonical.z >= this._source.maxzoom) {
                // We're looking for an overzoomed child tile.
                const childCoord = tileID.children(this._source.maxzoom)[0];
                const childTile = this.getTile(childCoord);
                if (!!childTile && childTile.hasData()) {
                    retain[childCoord.key] = childCoord;
                    continue; // tile is covered by overzoomed child
                }
            } else {
                // Check if all 4 immediate children are loaded (in other words, the missing ideal tile is covered)
                const children = tileID.children(this._source.maxzoom);

                if (retain[children[0].key] &&
                    retain[children[1].key] &&
                    retain[children[2].key] &&
                    retain[children[3].key]) continue; // tile is covered by children
            }

            // We couldn't find child tiles that entirely cover the ideal tile; look for parents now.

            // As we ascend up the tile pyramid of the ideal tile, we check whether the parent
            // tile has been previously requested (and errored because we only loop over tiles with no data)
            // in order to determine if we need to request its parent.
            let parentWasRequested = tile.wasRequested();

            for (let overscaledZ = tileID.overscaledZ - 1; overscaledZ >= minCoveringZoom; --overscaledZ) {
                const parentId = tileID.scaledTo(overscaledZ);

                // Break parent tile ascent if this route has been previously checked by another child.
                if (checked[parentId.key]) break;
                checked[parentId.key] = true;

                tile = this.getTile(parentId);
                if (!tile && parentWasRequested) {
                    tile = this._addTile(parentId);
                }
                if (tile) {
                    retain[parentId.key] = parentId;
                    // Save the current values, since they're the parent of the next iteration
                    // of the parent tile ascent loop.
                    parentWasRequested = tile.wasRequested();
                    if (tile.hasData()) break;
                }
            }
        }

        return retain;
    }

    _updateLoadedParentTileCache() {
        this._loadedParentTiles = {};

        for (const tileKey in this._tiles) {
            const path = [];
            let parentTile       ;
            let currentId = this._tiles[tileKey].tileID;

            // Find the closest loaded ancestor by traversing the tile tree towards the root and
            // caching results along the way
            while (currentId.overscaledZ > 0) {

                // Do we have a cached result from previous traversals?
                if (currentId.key in this._loadedParentTiles) {
                    parentTile = this._loadedParentTiles[currentId.key];
                    break;
                }

                path.push(currentId.key);

                // Is the parent loaded?
                const parentId = currentId.scaledTo(currentId.overscaledZ - 1);
                parentTile = this._getLoadedTile(parentId);
                if (parentTile) {
                    break;
                }

                currentId = parentId;
            }

            // Cache the result of this traversal to all newly visited tiles
            for (const key of path) {
                this._loadedParentTiles[key] = parentTile;
            }
        }
    }

    /**
     * Add a tile, given its coordinate, to the pyramid.
     * @private
     */
    _addTile(tileID                  )       {
        let tile        = this._tiles[tileID.key];
        if (tile) return tile;

        tile = this._cache.getAndRemove(tileID);
        if (tile) {
            this._setTileReloadTimer(tileID.key, tile);
            // set the tileID because the cached tile could have had a different wrap value
            tile.tileID = tileID;
            this._state.initializeTileState(tile, this.map ? this.map.painter : null);
            if (this._cacheTimers[tileID.key]) {
                clearTimeout(this._cacheTimers[tileID.key]);
                delete this._cacheTimers[tileID.key];
                this._setTileReloadTimer(tileID.key, tile);
            }
        }

        const cached = Boolean(tile);
        if (!cached) {
            const painter = this.map ? this.map.painter : null;
            tile = new Tile(tileID, this._source.tileSize * tileID.overscaleFactor(), this.transform.tileZoom, painter, this._isRaster);
            // $FlowFixMe[method-unbinding]
            this._loadTile(tile, this._tileLoaded.bind(this, tile, tileID.key, tile.state));
        }

        // Impossible, but silence flow.
        if (!tile) return (null     );

        tile.uses++;
        this._tiles[tileID.key] = tile;
        if (!cached) this._source.fire(new Event('dataloading', {tile, coord: tile.tileID, dataType: 'source'}));

        return tile;
    }

    _setTileReloadTimer(id        , tile      ) {
        if (id in this._timers) {
            clearTimeout(this._timers[id]);
            delete this._timers[id];
        }

        const expiryTimeout = tile.getExpiryTimeout();
        if (expiryTimeout) {
            this._timers[id] = setTimeout(() => {
                this._reloadTile(id, 'expired');
                delete this._timers[id];
            }, expiryTimeout);
        }
    }

    /**
     * Remove a tile, given its id, from the pyramid
     * @private
     */
    _removeTile(id        ) {
        const tile = this._tiles[id];
        if (!tile)
            return;

        tile.uses--;
        delete this._tiles[id];
        if (this._timers[id]) {
            clearTimeout(this._timers[id]);
            delete this._timers[id];
        }

        if (tile.uses > 0)
            return;

        if (tile.hasData() && tile.state !== 'reloading') {
            this._cache.add(tile.tileID, tile, tile.getExpiryTimeout());
        } else {
            tile.aborted = true;
            this._abortTile(tile);
            this._unloadTile(tile);
        }
    }

    /**
     * Remove all tiles from this pyramid.
     * @private
     */
    clearTiles() {
        this._shouldReloadOnResume = false;
        this._paused = false;

        for (const id in this._tiles)
            this._removeTile(+id);

        if (this._source._clear) this._source._clear();

        this._cache.reset();

        if (this.map && this.usedForTerrain && this.map.painter.terrain) {
            this.map.painter.terrain.resetTileLookupCache(this.id);
        }
    }

    /**
     * Search through our current tiles and attempt to find the tiles that cover the given `queryGeometry`.
     *
     * @param {QueryGeometry} queryGeometry
     * @param {boolean} [visualizeQueryGeometry=false]
     * @param {boolean} use3DQuery
     * @returns
     * @private
     */
    tilesIn(queryGeometry               , use3DQuery         , visualizeQueryGeometry         )                           {
        const tileResults = [];

        const transform = this.transform;
        if (!transform) return tileResults;

        const isGlobe = transform.projection.name === 'globe';
        const centerX = mercatorXfromLng(transform.center.lng);

        for (const tileID in this._tiles) {
            const tile = this._tiles[tileID];
            if (visualizeQueryGeometry) {
                tile.clearQueryDebugViz();
            }
            if (tile.holdingForFade()) {
                // Tiles held for fading are covered by tiles that are closer to ideal
                continue;
            }

            // An array of wrap values for the tile [-1, 0, 1]. The default value is 0 but -1 or 1 wrapping
            // might be required in globe view due to globe's surface being continuous.
            let tilesToCheck;

            if (isGlobe) {
                // Compare distances to copies of the tile to see if a wrapped one should be used.
                const id = tile.tileID.canonical;
                assert$1(tile.tileID.wrap === 0);

                if (id.z === 0) {
                    // Render the zoom level 0 tile twice as the query polygon might span over the antimeridian
                    const distances = [
                        Math.abs(clamp(centerX, ...tileBoundsX(id, -1)) - centerX),
                        Math.abs(clamp(centerX, ...tileBoundsX(id, 1)) - centerX)
                    ];

                    tilesToCheck = [0, distances.indexOf(Math.min(...distances)) * 2 - 1];
                } else {
                    const distances = [
                        Math.abs(clamp(centerX, ...tileBoundsX(id, -1)) - centerX),
                        Math.abs(clamp(centerX, ...tileBoundsX(id, 0)) - centerX),
                        Math.abs(clamp(centerX, ...tileBoundsX(id, 1)) - centerX)
                    ];

                    tilesToCheck = [distances.indexOf(Math.min(...distances)) - 1];
                }
            } else {
                tilesToCheck = [0];
            }

            for (const wrap of tilesToCheck) {
                const tileResult = queryGeometry.containsTile(tile, transform, use3DQuery, wrap);
                if (tileResult) {
                    tileResults.push(tileResult);
                }
            }
        }
        return tileResults;
    }

    getVisibleCoordinates(symbolLayer          )                          {
        const coords = this.getRenderableIds(symbolLayer).map((id) => this._tiles[id].tileID);
        for (const coord of coords) {
            coord.projMatrix = this.transform.calculateProjMatrix(coord.toUnwrapped());
        }
        return coords;
    }

    hasTransition()          {
        if (this._source.hasTransition()) {
            return true;
        }

        if (isRasterType(this._source.type)) {
            for (const id in this._tiles) {
                const tile = this._tiles[id];
                if (tile.fadeEndTime !== undefined && tile.fadeEndTime >= exported.now()) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * Set the value of a particular state for a feature
     * @private
     */
    setFeatureState(sourceLayer         , featureId                 , state        ) {
        sourceLayer = sourceLayer || '_geojsonTileLayer';
        this._state.updateState(sourceLayer, featureId, state);
    }

    /**
     * Resets the value of a particular state key for a feature
     * @private
     */
    removeFeatureState(sourceLayer         , featureId                  , key         ) {
        sourceLayer = sourceLayer || '_geojsonTileLayer';
        this._state.removeFeatureState(sourceLayer, featureId, key);
    }

    /**
     * Get the entire state object for a feature
     * @private
     */
    getFeatureState(sourceLayer         , featureId                 )                {
        sourceLayer = sourceLayer || '_geojsonTileLayer';
        return this._state.getState(sourceLayer, featureId);
    }

    /**
     * Sets the set of keys that the tile depends on. This allows tiles to
     * be reloaded when their dependencies change.
     * @private
     */
    setDependencies(tileKey        , namespace        , dependencies               ) {
        const tile = this._tiles[tileKey];
        if (tile) {
            tile.setDependencies(namespace, dependencies);
        }
    }

    /**
     * Reloads all tiles that depend on the given keys.
     * @private
     */
    reloadTilesForDependencies(namespaces               , keys               ) {
        for (const id in this._tiles) {
            const tile = this._tiles[id];
            if (tile.hasDependency(namespaces, keys)) {
                this._reloadTile(+id, 'reloading');
            }
        }
        this._cache.filter(tile => !tile.hasDependency(namespaces, keys));
    }

    /**
     * Preloads all tiles that will be requested for one or a series of transformations
     *
     * @private
     * @returns {Object} Returns `this` | Promise.
     */
    _preloadTiles(transform                              , callback               ) {
        if (!this._sourceLoaded) {
            const waitUntilSourceLoaded = () => {
                if (!this._sourceLoaded) return;
                this._source.off('data', waitUntilSourceLoaded);
                this._preloadTiles(transform, callback);
            };

            this._source.on('data', waitUntilSourceLoaded);
            return;
        }

        const coveringTilesIDs                                = new Map();
        const transforms = Array.isArray(transform) ? transform : [transform];

        const terrain = this.map.painter.terrain;
        const tileSize = this.usedForTerrain && terrain ? terrain.getScaledDemTileSize() : this._source.tileSize;

        for (const tr of transforms) {
            const tileIDs = tr.coveringTiles({
                tileSize,
                minzoom: this._source.minzoom,
                maxzoom: this._source.maxzoom,
                roundZoom: this._source.roundZoom && !this.usedForTerrain,
                reparseOverscaled: this._source.reparseOverscaled,
                isTerrainDEM: this.usedForTerrain
            });

            for (const tileID of tileIDs) {
                coveringTilesIDs.set(tileID.key, tileID);
            }

            if (this.usedForTerrain) {
                tr.updateElevation(false);
            }
        }

        const tileIDs = Array.from(coveringTilesIDs.values());

        asyncAll(tileIDs, (tileID, done) => {
            const tile = new Tile(tileID, this._source.tileSize * tileID.overscaleFactor(), this.transform.tileZoom, this.map.painter, this._isRaster);
            this._loadTile(tile, (err) => {
                if (this._source.type === 'raster-dem' && tile.dem) this._backfillDEM(tile);
                done(err, tile);
            });
        }, callback);
    }
}

SourceCache.maxOverzooming = 10;
SourceCache.maxUnderzooming = 3;

function compareTileId(a                  , b                  )         {
    // Different copies of the world are sorted based on their distance to the center.
    // Wrap values are converted to unsigned distances by reserving odd number for copies
    // with negative wrap and even numbers for copies with positive wrap.
    const aWrap = Math.abs(a.wrap * 2) - +(a.wrap < 0);
    const bWrap = Math.abs(b.wrap * 2) - +(b.wrap < 0);
    return a.overscaledZ - b.overscaledZ || bWrap - aWrap || b.canonical.y - a.canonical.y || b.canonical.x - a.canonical.x;
}

function isRasterType(type        )          {
    return type === 'raster' || type === 'image' || type === 'video' || type === 'custom';
}

function tileBoundsX(id                 , wrap        )                   {
    const tiles = 1 << id.z;
    return [id.x / tiles + wrap, (id.x + 1) / tiles + wrap];
}

//      


                                                              
                                          
                                    

/**
 * Options common to {@link Map#queryTerrainElevation} and {@link Map#unproject3d}, used to control how elevation
 * data is returned.
 *
 * @typedef {Object} ElevationQueryOptions
 * @property {boolean} exaggerated When set to `true` returns the value of the elevation with the terrains `exaggeration` on the style already applied,
 * when`false` it returns the raw value of the underlying data without styling applied.
 */
                                     
                        
  

/**
 * Provides access to elevation data from raster-dem source cache.
 */
class Elevation {

    /**
     * Helper that checks whether DEM data is available at a given mercator coordinate.
     * @param {MercatorCoordinate} point Mercator coordinate of the point to check against.
     * @returns {boolean} `true` indicating whether the data is available at `point`, and `false` otherwise.
     */
    isDataAvailableAtPoint(point                    )          {
        const sourceCache = this._source();
        if (this.isUsingMockSource() || !sourceCache || point.y < 0.0 || point.y > 1.0) {
            return false;
        }

        const cache              = sourceCache;
        const z = cache.getSource().maxzoom;
        const tiles = 1 << z;
        const wrap = Math.floor(point.x);
        const px = point.x - wrap;
        const x = Math.floor(px * tiles);
        const y = Math.floor(point.y * tiles);
        const demTile = this.findDEMTileFor(new OverscaledTileID(z, wrap, z, x, y));

        return !!(demTile && demTile.dem);
    }

    /**
     * Helper around `getAtPoint` that guarantees that a numeric value is returned.
     * @param {MercatorCoordinate} point Mercator coordinate of the point.
     * @param {number} defaultIfNotLoaded Value that is returned if the dem tile of the provided point is not loaded.
     * @returns {number} Altitude in meters.
     */
    getAtPointOrZero(point                    , defaultIfNotLoaded         = 0)         {
        return this.getAtPoint(point, defaultIfNotLoaded) || 0;
    }

    /**
     * Altitude above sea level in meters at specified point.
     * @param {MercatorCoordinate} point Mercator coordinate of the point.
     * @param {number} defaultIfNotLoaded Value that is returned if the DEM tile of the provided point is not loaded.
     * @param {boolean} exaggerated `true` if styling exaggeration should be applied to the resulting elevation.
     * @returns {number} Altitude in meters.
     * If there is no loaded tile that carries information for the requested
     * point elevation, returns `defaultIfNotLoaded`.
     * Doesn't invoke network request to fetch the data.
     */
    getAtPoint(point                    , defaultIfNotLoaded         , exaggerated          = true)          {
        if (this.isUsingMockSource()) {
            return null;
        }

        // Force a cast to null for both null and undefined
        if (defaultIfNotLoaded == null) defaultIfNotLoaded = null;

        const src = this._source();
        if (!src) return defaultIfNotLoaded;
        if (point.y < 0.0 || point.y > 1.0) {
            return defaultIfNotLoaded;
        }
        const cache              = src;
        const z = cache.getSource().maxzoom;
        const tiles = 1 << z;
        const wrap = Math.floor(point.x);
        const px = point.x - wrap;
        const tileID = new OverscaledTileID(z, wrap, z, Math.floor(px * tiles), Math.floor(point.y * tiles));
        const demTile = this.findDEMTileFor(tileID);
        if (!(demTile && demTile.dem)) { return defaultIfNotLoaded; }
        const dem          = demTile.dem;
        const tilesAtTileZoom = 1 << demTile.tileID.canonical.z;
        const x = (px * tilesAtTileZoom - demTile.tileID.canonical.x) * dem.dim;
        const y = (point.y * tilesAtTileZoom - demTile.tileID.canonical.y) * dem.dim;
        const i = Math.floor(x);
        const j = Math.floor(y);
        const exaggeration = exaggerated ? this.exaggeration() : 1;

        return exaggeration * number(
            number(dem.get(i, j), dem.get(i, j + 1), y - j),
            number(dem.get(i + 1, j), dem.get(i + 1, j + 1), y - j),
            x - i);
    }

    /*
     * x and y are offset within tile, in 0 .. EXTENT coordinate space.
     */
    getAtTileOffset(tileID                  , x        , y        )         {
        const tilesAtTileZoom = 1 << tileID.canonical.z;
        return this.getAtPointOrZero(new MercatorCoordinate$1(
            tileID.wrap + (tileID.canonical.x + x / EXTENT) / tilesAtTileZoom,
            (tileID.canonical.y + y / EXTENT) / tilesAtTileZoom));
    }

    getAtTileOffsetFunc(tileID                  , lat        , worldSize        , projection            )           {
        return (p => {
            const elevation = this.getAtTileOffset(tileID, p.x, p.y);
            const upVector = projection.upVector(tileID.canonical, p.x, p.y);
            const upVectorScale = projection.upVectorScale(tileID.canonical, lat, worldSize).metersToTile;
            // $FlowFixMe can't yet resolve tuple vs array incompatibilities
            scale$4(upVector, upVector, elevation * upVectorScale);
            return upVector;
        });
    }

    /*
     * Batch fetch for multiple tile points: points holds input and return value:
     * vec3's items on index 0 and 1 define x and y offset within tile, in [0 .. EXTENT]
     * range, respectively. vec3 item at index 2 is output value, in meters.
     * If a DEM tile that covers tileID is loaded, true is returned, otherwise false.
     * Nearest filter sampling on dem data is done (no interpolation).
     */
    getForTilePoints(tileID                  , points             , interpolated          , useDemTile       )          {
        if (this.isUsingMockSource()) {
            return false;
        }

        const helper = DEMSampler.create(this, tileID, useDemTile);
        if (!helper) { return false; }

        points.forEach(p => {
            p[2] = this.exaggeration() * helper.getElevationAt(p[0], p[1], interpolated);
        });
        return true;
    }

    /**
     * Get elevation minimum and maximum for tile identified by `tileID`.
     * @param {OverscaledTileID} tileID The `tileId` is a sub tile (or covers the same space) of the DEM tile we read the information from.
     * @returns {?{min: number, max: number}} The min and max elevation.
     */
    getMinMaxForTile(tileID                  )                              {
        if (this.isUsingMockSource()) {
            return null;
        }

        const demTile = this.findDEMTileFor(tileID);

        if (!(demTile && demTile.dem)) {
            return null;
        }

        const dem          = demTile.dem;
        const tree = dem.tree;
        const demTileID = demTile.tileID;
        const scale = 1 << tileID.canonical.z - demTileID.canonical.z;
        let xOffset = tileID.canonical.x / scale - demTileID.canonical.x;
        let yOffset = tileID.canonical.y / scale - demTileID.canonical.y;
        let index = 0; // Start from DEM tree root.
        for (let i = 0; i < tileID.canonical.z - demTileID.canonical.z; i++) {
            if (tree.leaves[index]) break;
            xOffset *= 2;
            yOffset *= 2;
            const childOffset = 2 * Math.floor(yOffset) + Math.floor(xOffset);
            index = tree.childOffsets[index] + childOffset;
            xOffset = xOffset % 1;
            yOffset = yOffset % 1;
        }
        return {min: this.exaggeration() * tree.minimums[index], max: this.exaggeration() * tree.maximums[index]};
    }

    /**
     * Get elevation minimum below MSL for the visible tiles. This function accounts
     * for terrain exaggeration and is conservative based on the maximum DEM error,
     * do not expect accurate values from this function.
     * If no negative elevation is visible, this function returns 0.
     * @returns {number} The min elevation below sea level of all visible tiles.
     */
    getMinElevationBelowMSL()         {
        throw new Error('Pure virtual method called.');
    }

    /**
     * Performs raycast against visible DEM tiles on the screen and returns the distance travelled along the ray.
     * `x` & `y` components of the position are expected to be in normalized mercator coordinates [0, 1] and z in meters.
     * @param {vec3} position The ray origin.
     * @param {vec3} dir The ray direction.
     * @param {number} exaggeration The terrain exaggeration.
    */
    raycast(position      , dir      , exaggeration        )          {
        throw new Error('Pure virtual method called.');
    }

    /**
     * Given a point on screen, returns 3D MercatorCoordinate on terrain.
     * Helper function that wraps `raycast`.
     *
     * @param {Point} screenPoint Screen point in pixels in top-left origin coordinate system.
     * @returns {vec3} If there is intersection with terrain, returns 3D MercatorCoordinate's of
     * intersection, as vec3(x, y, z), otherwise null.
     */ /* eslint no-unused-vars: ["error", { "args": "none" }] */
    pointCoordinate(screenPoint       )        {
        throw new Error('Pure virtual method called.');
    }

    /*
     * Implementation provides SourceCache of raster-dem source type cache, in
     * order to access already loaded cached tiles.
     */
    _source()               {
        throw new Error('Pure virtual method called.');
    }

    /*
     * Whether the SourceCache instance is a mock source cache.
     * This mock source cache is used solely for the Globe projection and with terrain disabled,
     * where we only want to leverage the draping rendering pipeline without incurring DEM-tile
     * download overhead. This function is useful to skip DEM processing as the mock data source
     * placeholder contains only 0 height.
     */
    isUsingMockSource()          {
        throw new Error('Pure virtual method called.');
    }

    /*
     * A multiplier defined by style as terrain exaggeration. Elevation provided
     * by getXXXX methods is multiplied by this.
     */
    exaggeration()         {
        throw new Error('Pure virtual method called.');
    }

    /**
     * Lookup DEM tile that corresponds to (covers) tileID.
     * @private
     */
    findDEMTileFor(_                  )        {
        throw new Error('Pure virtual method called.');
    }

    /**
     * Get list of DEM tiles used to render current frame.
     * @private
     */
    get visibleDemTiles()              {
        throw new Error('Getter must be implemented in subclass.');
    }
}

/**
 * Helper class computes and caches data required to lookup elevation offsets at the tile level.
 */
class DEMSampler {
                   
                  
                   
                              

    constructor(demTile      , scale        , offset                  ) {
        this._demTile = demTile;
        // demTile.dem will always exist because the factory method `create` does the check
        // Make flow happy with a cast through any
        this._dem = (((this._demTile.dem)     )         );
        this._scale = scale;
        this._offset = offset;
    }

    static create(elevation           , tileID                  , useDemTile       )              {
        const demTile = useDemTile || elevation.findDEMTileFor(tileID);
        if (!(demTile && demTile.dem)) { return; }
        const dem          = demTile.dem;
        const demTileID = demTile.tileID;
        const scale = 1 << tileID.canonical.z - demTileID.canonical.z;
        const xOffset = (tileID.canonical.x / scale - demTileID.canonical.x) * dem.dim;
        const yOffset = (tileID.canonical.y / scale - demTileID.canonical.y) * dem.dim;
        const k = demTile.tileSize / EXTENT / scale;

        return new DEMSampler(demTile, k, [xOffset, yOffset]);
    }

    tileCoordToPixel(x        , y        )        {
        const px = x * this._scale + this._offset[0];
        const py = y * this._scale + this._offset[1];
        const i = Math.floor(px);
        const j = Math.floor(py);
        return new Point$2(i, j);
    }

    getElevationAt(x        , y        , interpolated          , clampToEdge          )         {
        const px = x * this._scale + this._offset[0];
        const py = y * this._scale + this._offset[1];
        const i = Math.floor(px);
        const j = Math.floor(py);
        const dem = this._dem;

        clampToEdge = !!clampToEdge;

        return interpolated ? number(
            number(dem.get(i, j, clampToEdge), dem.get(i, j + 1, clampToEdge), py - j),
            number(dem.get(i + 1, j, clampToEdge), dem.get(i + 1, j + 1, clampToEdge), py - j),
            px - i) :
            dem.get(i, j, clampToEdge);
    }

    getElevationAtPixel(x        , y        , clampToEdge          )         {
        return this._dem.get(x, y, !!clampToEdge);
    }

    getMeterToDEM(lat        )         {
        return (1 << this._demTile.tileID.canonical.z) * mercatorZfromAltitude(1, lat) * this._dem.stride;
    }
}

//      


                                                      
                                                                   
                                                          
                                                                         
                                                 
                                                                                        
                                                                       
                                                                         
                                                                       
                                                                              

                        
                                 
                         
                                       
                                 
             
                                    
                              
                                      
     
 

                                                                                                

                       
                        
                             
                         
                                   
                       

class FeatureIndex {
                             
              
              
              
               
                                         
                                       

                             
                                         

                                              
                                                    
                                      

    constructor(tileID                  , promoteId                          ) {
        this.tileID = tileID;
        this.x = tileID.canonical.x;
        this.y = tileID.canonical.y;
        this.z = tileID.canonical.z;
        this.grid = new Grid(EXTENT, 16, 0);
        this.featureIndexArray = new FeatureIndexArray();
        this.promoteId = promoteId;
    }

    insert(feature                    , geometry                     , featureIndex        , sourceLayerIndex        , bucketIndex        , layoutVertexArrayOffset         = 0) {
        const key = this.featureIndexArray.length;
        this.featureIndexArray.emplaceBack(featureIndex, sourceLayerIndex, bucketIndex, layoutVertexArrayOffset);

        const grid = this.grid;

        for (let r = 0; r < geometry.length; r++) {
            const ring = geometry[r];

            const bbox = [Infinity, Infinity, -Infinity, -Infinity];
            for (let i = 0; i < ring.length; i++) {
                const p = ring[i];
                bbox[0] = Math.min(bbox[0], p.x);
                bbox[1] = Math.min(bbox[1], p.y);
                bbox[2] = Math.max(bbox[2], p.x);
                bbox[3] = Math.max(bbox[3], p.y);
            }

            if (bbox[0] < EXTENT &&
                bbox[1] < EXTENT &&
                bbox[2] >= 0 &&
                bbox[3] >= 0) {
                grid.insert(key, bbox[0], bbox[1], bbox[2], bbox[3]);
            }
        }
    }

    loadVTLayers()                                  {
        if (!this.vtLayers) {
            this.vtLayers = new VectorTile(new Protobuf(this.rawTileData)).layers;
            this.sourceLayerCoder = new DictionaryCoder(this.vtLayers ? Object.keys(this.vtLayers).sort() : ['_geojsonTileLayer']);
            this.vtFeatures = {};
            for (const layer in this.vtLayers) {
                this.vtFeatures[layer] = [];
            }
        }
        return this.vtLayers;
    }

    // Finds non-symbol features in this tile at a particular position.
    query(args                 , styleLayers                           , serializedLayers                       , sourceFeatureState                    )              {
        this.loadVTLayers();
        const params = args.params || {},
            filter = createFilter(params.filter);
        const tilespaceGeometry = args.tileResult;
        const transform = args.transform;

        const bounds = tilespaceGeometry.bufferedTilespaceBounds;
        const queryPredicate = (bx1        , by1        , bx2        , by2        ) => {
            return polygonIntersectsBox(tilespaceGeometry.bufferedTilespaceGeometry, bx1, by1, bx2, by2);
        };
        const matching = this.grid.query(bounds.min.x, bounds.min.y, bounds.max.x, bounds.max.y, queryPredicate);
        matching.sort(topDownFeatureComparator);

        let elevationHelper = null;
        if (transform.elevation && matching.length > 0) {
            elevationHelper = DEMSampler.create(transform.elevation, this.tileID);
        }

        const result = {};
        let previousIndex;
        for (let k = 0; k < matching.length; k++) {
            const index = matching[k];

            // don't check the same feature more than once
            if (index === previousIndex) continue;
            previousIndex = index;

            const match = this.featureIndexArray.get(index);
            let featureGeometry = null;
            this.loadMatchingFeature(
                result,
                match,
                filter,
                params.layers,
                params.availableImages,
                styleLayers,
                serializedLayers,
                sourceFeatureState,
                (feature                    , styleLayer            , featureState        , layoutVertexArrayOffset         = 0) => {
                    if (!featureGeometry) {
                        featureGeometry = loadGeometry(feature, this.tileID.canonical, args.tileTransform);
                    }

                    return styleLayer.queryIntersectsFeature(tilespaceGeometry, feature, featureState, featureGeometry, this.z, args.transform, args.pixelPosMatrix, elevationHelper, layoutVertexArrayOffset);
                }
            );
        }

        return result;
    }

    loadMatchingFeature(
        result             ,
        featureIndexData                ,
        filter               ,
        filterLayerIDs               ,
        availableImages               ,
        styleLayers                           ,
        serializedLayers                       ,
        sourceFeatureState                     ,
        intersectionTest                                                                                                                                   ) {

        const {featureIndex, bucketIndex, sourceLayerIndex, layoutVertexArrayOffset} = featureIndexData;
        const layerIDs = this.bucketLayerIDs[bucketIndex];
        if (filterLayerIDs && !arraysIntersect(filterLayerIDs, layerIDs))
            return;

        const sourceLayerName = this.sourceLayerCoder.decode(sourceLayerIndex);
        const sourceLayer = this.vtLayers[sourceLayerName];
        const feature = sourceLayer.feature(featureIndex);

        if (filter.needGeometry) {
            const evaluationFeature = toEvaluationFeature(feature, true);
            // $FlowFixMe[method-unbinding]
            if (!filter.filter(new EvaluationParameters(this.tileID.overscaledZ), evaluationFeature, this.tileID.canonical)) {
                return;
            }
        // $FlowFixMe[method-unbinding]
        } else if (!filter.filter(new EvaluationParameters(this.tileID.overscaledZ), feature)) {
            return;
        }

        const id = this.getId(feature, sourceLayerName);

        for (let l = 0; l < layerIDs.length; l++) {
            const layerID = layerIDs[l];

            if (filterLayerIDs && filterLayerIDs.indexOf(layerID) < 0) {
                continue;
            }

            const styleLayer = styleLayers[layerID];

            if (!styleLayer) continue;

            let featureState = {};
            if (id !== undefined && sourceFeatureState) {
                // `feature-state` expression evaluation requires feature state to be available
                featureState = sourceFeatureState.getState(styleLayer.sourceLayer || '_geojsonTileLayer', id);
            }

            const serializedLayer = extend$1({}, serializedLayers[layerID]);

            serializedLayer.paint = evaluateProperties(serializedLayer.paint, styleLayer.paint, feature, featureState, availableImages);
            serializedLayer.layout = evaluateProperties(serializedLayer.layout, styleLayer.layout, feature, featureState, availableImages);

            const intersectionZ = !intersectionTest || intersectionTest(feature, styleLayer, featureState, layoutVertexArrayOffset);
            if (!intersectionZ) {
                // Only applied for non-symbol features
                continue;
            }

            const geojsonFeature = new Feature(feature, this.z, this.x, this.y, id);
            geojsonFeature.layer = serializedLayer;
            let layerResult = result[layerID];
            if (layerResult === undefined) {
                layerResult = result[layerID] = [];
            }

            layerResult.push({featureIndex, feature: geojsonFeature, intersectionZ});
        }
    }

    // Given a set of symbol indexes that have already been looked up,
    // return a matching set of GeoJSONFeatures
    lookupSymbolFeatures(symbolFeatureIndexes               ,
                         serializedLayers                        ,
                         bucketIndex        ,
                         sourceLayerIndex        ,
                         filterSpec                     ,
                         filterLayerIDs               ,
                         availableImages               ,
                         styleLayers                           )              {
        const result = {};
        this.loadVTLayers();

        const filter = createFilter(filterSpec);

        for (const symbolFeatureIndex of symbolFeatureIndexes) {
            this.loadMatchingFeature(
                result, {
                    bucketIndex,
                    sourceLayerIndex,
                    featureIndex: symbolFeatureIndex,
                    layoutVertexArrayOffset: 0
                },
                filter,
                filterLayerIDs,
                availableImages,
                styleLayers,
                serializedLayers
            );

        }
        return result;
    }

    loadFeature(featureIndexData                )                     {
        const {featureIndex, sourceLayerIndex} = featureIndexData;

        this.loadVTLayers();
        const sourceLayerName = this.sourceLayerCoder.decode(sourceLayerIndex);

        const featureCache = this.vtFeatures[sourceLayerName];
        if (featureCache[featureIndex]) {
            return featureCache[featureIndex];
        }
        const sourceLayer = this.vtLayers[sourceLayerName];
        const feature = sourceLayer.feature(featureIndex);
        featureCache[featureIndex] = feature;

        return feature;
    }

    hasLayer(id        )          {
        for (const layerIDs of this.bucketLayerIDs) {
            for (const layerID of layerIDs) {
                if (id === layerID) return true;
            }
        }

        return false;
    }

    getId(feature                    , sourceLayerId        )                         {
        let id = feature.id;
        if (this.promoteId) {
            const propName = typeof this.promoteId === 'string' ? this.promoteId : this.promoteId[sourceLayerId];
            // $FlowFixMe[incompatible-type] - Flow can't narrow the id type from IVectorTileFeature.id
            if (propName != null) id = feature.properties[propName];
            if (typeof id === 'boolean') id = Number(id);
        }
        return id;
    }
}

register(FeatureIndex, 'FeatureIndex', {omit: ['rawTileData', 'sourceLayerCoder']});

function evaluateProperties(serializedProperties       , styleLayerProperties       , feature                    , featureState               , availableImages               ) {
    return mapObject(serializedProperties, (property, key) => {
        const prop = styleLayerProperties instanceof PossiblyEvaluated ? styleLayerProperties.get(key) : null;
        return prop && prop.evaluate ? prop.evaluate(feature, featureState, availableImages) : prop;
    });
}

function topDownFeatureComparator(a        , b        ) {
    return b - a;
}

//      


                                                                      

                   
                    
                 
                  
                       
   

/**
 * A LineAtlas lets us reuse rendered dashed lines
 * by writing many of them to a texture and then fetching their positions
 * using .getDash.
 *
 * @param {number} width
 * @param {number} height
 * @private
 */
class LineAtlas {
                  
                   
                    
                      
                               
                      

    constructor(width        , height        ) {
        this.width = width;
        this.height = height;
        this.nextRow = 0;
        this.image = new AlphaImage({width, height});
        this.positions = {};
        this.uploaded = false;
    }

    /**
     * Get a dash line pattern.
     *
     * @param {Array<number>} dasharray
     * @param {string} lineCap the type of line caps to be added to dashes
     * @returns {Object} position of dash texture in { y, height, width }
     * @private
     */
    getDash(dasharray               , lineCap        )                 {
        const key = this.getKey(dasharray, lineCap);
        return this.positions[key];
    }

    trim() {
        const width = this.width;
        const height = this.height = nextPowerOfTwo(this.nextRow);
        this.image.resize({width, height});
    }

    getKey(dasharray               , lineCap        )         {
        return dasharray.join(',') + lineCap;
    }

    getDashRanges(dasharray               , lineAtlasWidth        , stretch        )                   {
        // If dasharray has an odd length, both the first and last parts
        // are dashes and should be joined seamlessly.
        const oddDashArray = dasharray.length % 2 === 1;

        const ranges = [];

        let left = oddDashArray ? -dasharray[dasharray.length - 1] * stretch : 0;
        let right = dasharray[0] * stretch;
        let isDash = true;

        ranges.push({left, right, isDash, zeroLength: dasharray[0] === 0});

        let currentDashLength = dasharray[0];
        for (let i = 1; i < dasharray.length; i++) {
            isDash = !isDash;

            const dashLength = dasharray[i];
            left = currentDashLength * stretch;
            currentDashLength += dashLength;
            right = currentDashLength * stretch;

            ranges.push({left, right, isDash, zeroLength: dashLength === 0});
        }

        return ranges;
    }

    addRoundDash(ranges                  , stretch        , n        ) {
        const halfStretch = stretch / 2;

        for (let y = -n; y <= n; y++) {
            const row = this.nextRow + n + y;
            const index = this.width * row;
            let currIndex = 0;
            let range = ranges[currIndex];

            for (let x = 0; x < this.width; x++) {
                if (x / range.right > 1) { range = ranges[++currIndex]; }

                const distLeft = Math.abs(x - range.left);
                const distRight = Math.abs(x - range.right);
                const minDist = Math.min(distLeft, distRight);
                let signedDistance;

                const distMiddle =  y / n * (halfStretch + 1);
                if (range.isDash) {
                    const distEdge = halfStretch - Math.abs(distMiddle);
                    signedDistance = Math.sqrt(minDist * minDist + distEdge * distEdge);
                } else {
                    signedDistance = halfStretch - Math.sqrt(minDist * minDist + distMiddle * distMiddle);
                }

                this.image.data[index + x] = Math.max(0, Math.min(255, signedDistance + 128));
            }
        }
    }

    addRegularDash(ranges                  , capLength        ) {

        // Collapse any zero-length range
        // Collapse neighbouring same-type parts into a single part
        for (let i = ranges.length - 1; i >= 0; --i) {
            const part = ranges[i];
            const next = ranges[i + 1];
            if (part.zeroLength) {
                ranges.splice(i, 1);
            } else if (next && next.isDash === part.isDash) {
                next.left = part.left;
                ranges.splice(i, 1);
            }
        }

        // Combine the first and last parts if possible
        const first = ranges[0];
        const last = ranges[ranges.length - 1];
        if (first.isDash === last.isDash) {
            first.left = last.left - this.width;
            last.right = first.right + this.width;
        }

        const index = this.width * this.nextRow;
        let currIndex = 0;
        let range = ranges[currIndex];

        for (let x = 0; x < this.width; x++) {
            if (x / range.right > 1) {
                range = ranges[++currIndex];
            }

            const distLeft = Math.abs(x - range.left);
            const distRight = Math.abs(x - range.right);

            const minDist = Math.min(distLeft, distRight);
            const signedDistance = (range.isDash ? minDist : -minDist) + capLength;

            this.image.data[index + x] = Math.max(0, Math.min(255, signedDistance + 128));
        }
    }

    addDash(dasharray               , lineCap        )                        {
        const key = this.getKey(dasharray, lineCap);
        if (this.positions[key]) return this.positions[key];

        const round = lineCap === 'round';
        const n = round ? 7 : 0;
        const height = 2 * n + 1;

        if (this.nextRow + height > this.height) {
            warnOnce('LineAtlas out of space');
            return null;
        }

        // dasharray is empty, draws a full line (no dash or no gap length represented, default behavior)
        if (dasharray.length === 0) {
            // insert a single dash range in order to draw a full line
            dasharray.push(1);
        }

        let length = 0;
        for (let i = 0; i < dasharray.length; i++) {
            if (dasharray[i] < 0) {
                warnOnce('Negative value is found in line dasharray, replacing values with 0');
                dasharray[i] = 0;
            }
            length += dasharray[i];
        }

        if (length !== 0) {
            const stretch = this.width / length;
            const ranges = this.getDashRanges(dasharray, this.width, stretch);

            if (round) {
                this.addRoundDash(ranges, stretch, n);
            } else {
                const capLength = lineCap === 'square' ? 0.5 * stretch : 0;
                this.addRegularDash(ranges, capLength);
            }
        }

        const y = this.nextRow + n;

        this.nextRow += height;

        const pos = {
            tl: [y, n],
            br: [length, 0]
        };
        this.positions[key] = pos;
        return pos;
    }
}

register(LineAtlas, 'LineAtlas');

//      


                                                        

const glyphPadding = 1;
/*
    The glyph padding is just to prevent sampling errors at the boundaries between
    glyphs in the atlas texture, and for that purpose there's no need to make it
    bigger with high-res SDFs. However, layout is done based on the glyph size
    including this padding, so scaling this padding is the easiest way to keep
    layout exactly the same as the SDF_SCALE changes.
*/
const localGlyphPadding = glyphPadding * SDF_SCALE;

                         
              
              
              
             
  
// {glyphID: glyphRect}
                                                          

// {fontStack: glyphPoistionMap}
                                                               

class GlyphAtlas {
                      
                              
    constructor(stacks                                                                                              ) {
        const positions = {};
        const bins = [];

        for (const stack in stacks) {
            const glyphData = stacks[stack];
            const glyphPositionMap = positions[stack] = {};

            for (const id in glyphData.glyphs) {
                const src = glyphData.glyphs[+id];
                if (!src || src.bitmap.width === 0 || src.bitmap.height === 0) continue;

                const padding = src.metrics.localGlyph ? localGlyphPadding : glyphPadding;
                const bin = {
                    x: 0,
                    y: 0,
                    w: src.bitmap.width + 2 * padding,
                    h: src.bitmap.height + 2 * padding
                };
                bins.push(bin);
                glyphPositionMap[id] = bin;
            }
        }

        const {w, h} = potpack(bins);
        const image = new AlphaImage({width: w || 1, height: h || 1});

        for (const stack in stacks) {
            const glyphData = stacks[stack];

            for (const id in glyphData.glyphs) {
                const src = glyphData.glyphs[+id];
                if (!src || src.bitmap.width === 0 || src.bitmap.height === 0) continue;
                const bin = positions[stack][id];
                const padding = src.metrics.localGlyph ? localGlyphPadding : glyphPadding;
                AlphaImage.copy(src.bitmap, image, {x: 0, y: 0}, {x: bin.x + padding, y: bin.y + padding}, src.bitmap);
            }
        }

        this.image = image;
        this.positions = positions;
    }
}

register(GlyphAtlas, 'GlyphAtlas');

//      

                                                              
                                              
                                          
                                                      
                                                                 
                                                        
                                                        
                                                      
             
                         
                       
                                    
                                                                   
                                                                       
                                                     

class WorkerTile {
                             
                
                 
                     
                               
                       
                     
                   
                                       
                        
                                
                                   
                                
                           
                           
                           
                                 

                               
                      
                                         

                       
                                        
                            

    constructor(params                      ) {
        this.tileID = new OverscaledTileID(params.tileID.overscaledZ, params.tileID.wrap, params.tileID.canonical.z, params.tileID.canonical.x, params.tileID.canonical.y);
        this.tileZoom = params.tileZoom;
        this.uid = params.uid;
        this.zoom = params.zoom;
        this.canonical = params.tileID.canonical;
        this.pixelRatio = params.pixelRatio;
        this.tileSize = params.tileSize;
        this.source = params.source;
        this.overscaling = this.tileID.overscaleFactor();
        this.showCollisionBoxes = params.showCollisionBoxes;
        this.collectResourceTiming = !!params.collectResourceTiming;
        this.returnDependencies = !!params.returnDependencies;
        this.promoteId = params.promoteId;
        this.enableTerrain = !!params.enableTerrain;
        this.isSymbolTile = params.isSymbolTile;
        this.tileTransform = tileTransform(params.tileID.canonical, params.projection);
        this.projection = params.projection;
    }

    parse(data             , layerIndex                 , availableImages               , actor       , callback                    ) {
        const m = PerformanceUtils.beginMeasure('parseTile1');
        this.status = 'parsing';
        this.data = data;

        this.collisionBoxArray = new CollisionBoxArray();
        const sourceLayerCoder = new DictionaryCoder(Object.keys(data.layers).sort());

        const featureIndex = new FeatureIndex(this.tileID, this.promoteId);
        featureIndex.bucketLayerIDs = [];

        const buckets                        = {};

        // we initially reserve space for a 256x256 atlas, but trim it after processing all line features
        const lineAtlas = new LineAtlas(256, 256);

        const options = {
            featureIndex,
            iconDependencies: {},
            patternDependencies: {},
            glyphDependencies: {},
            lineAtlas,
            availableImages
        };

        const layerFamilies = layerIndex.familiesBySource[this.source];
        for (const sourceLayerId in layerFamilies) {
            const sourceLayer = data.layers[sourceLayerId];
            if (!sourceLayer) {
                continue;
            }

            let anySymbolLayers = false;
            let anyOtherLayers = false;
            for (const family of layerFamilies[sourceLayerId]) {
                if (family[0].type === 'symbol') {
                    anySymbolLayers = true;
                } else {
                    anyOtherLayers = true;
                }
            }

            if (this.isSymbolTile === true && !anySymbolLayers) {
                continue;
            } else if (this.isSymbolTile === false && !anyOtherLayers) {
                continue;
            }

            if (sourceLayer.version === 1) {
                warnOnce(`Vector tile source "${this.source}" layer "${sourceLayerId}" ` +
                    `does not use vector tile spec v2 and therefore may have some rendering errors.`);
            }

            const sourceLayerIndex = sourceLayerCoder.encode(sourceLayerId);
            const features = [];
            for (let index = 0; index < sourceLayer.length; index++) {
                const feature = sourceLayer.feature(index);
                const id = featureIndex.getId(feature, sourceLayerId);
                features.push({feature, id, index, sourceLayerIndex});
            }

            for (const family of layerFamilies[sourceLayerId]) {
                const layer = family[0];
                if (this.isSymbolTile !== undefined && (layer.type === 'symbol') !== this.isSymbolTile) continue;

                assert$1(layer.source === this.source);
                if (layer.minzoom && this.zoom < Math.floor(layer.minzoom)) continue;
                if (layer.maxzoom && this.zoom >= layer.maxzoom) continue;
                if (layer.visibility === 'none') continue;

                recalculateLayers(family, this.zoom, availableImages);

                const bucket = buckets[layer.id] = layer.createBucket({
                    index: featureIndex.bucketLayerIDs.length,
                    // $FlowFixMe[incompatible-call] - Flow can't infer proper `family` type from `layer` above
                    layers: family,
                    zoom: this.zoom,
                    canonical: this.canonical,
                    pixelRatio: this.pixelRatio,
                    overscaling: this.overscaling,
                    collisionBoxArray: this.collisionBoxArray,
                    sourceLayerIndex,
                    sourceID: this.source,
                    enableTerrain: this.enableTerrain,
                    projection: this.projection.spec,
                    availableImages
                });

                assert$1(this.tileTransform.projection.name === this.projection.name);
                bucket.populate(features, options, this.tileID.canonical, this.tileTransform);
                featureIndex.bucketLayerIDs.push(family.map((l) => l.id));
            }
        }

        lineAtlas.trim();

        let error        ;
        let glyphMap                                                                                            ;
        let iconMap                           ;
        let patternMap                           ;
        const taskMetadata = {type: 'maybePrepare', isSymbolTile: this.isSymbolTile, zoom: this.zoom};

        const maybePrepare = () => {
            if (error) {
                return callback(error);
            } else if (glyphMap && iconMap && patternMap) {
                const m = PerformanceUtils.beginMeasure('parseTile2');
                const glyphAtlas = new GlyphAtlas(glyphMap);
                const imageAtlas = new ImageAtlas(iconMap, patternMap);

                for (const key in buckets) {
                    const bucket = buckets[key];
                    if (bucket instanceof SymbolBucket$1) {
                        recalculateLayers(bucket.layers, this.zoom, availableImages);
                        performSymbolLayout(bucket,
                            glyphMap,
                            glyphAtlas.positions,
                            iconMap,
                            imageAtlas.iconPositions,
                            this.showCollisionBoxes,
                            availableImages,
                            this.tileID.canonical,
                            this.tileZoom,
                            this.projection);
                    } else if (bucket.hasPattern &&
                        (bucket instanceof LineBucket ||
                         bucket instanceof FillBucket ||
                         bucket instanceof FillExtrusionBucket)) {
                        recalculateLayers(bucket.layers, this.zoom, availableImages);
                        // $FlowFixMe[incompatible-type] Flow can't interpret ImagePosition as SpritePosition for some reason here
                        const imagePositions                  = imageAtlas.patternPositions;
                        bucket.addFeatures(options, this.tileID.canonical, imagePositions, availableImages, this.tileTransform);
                    }
                }

                this.status = 'done';
                callback(null, {
                    buckets: values(buckets).filter(b => !b.isEmpty()),
                    featureIndex,
                    collisionBoxArray: this.collisionBoxArray,
                    glyphAtlasImage: glyphAtlas.image,
                    lineAtlas,
                    imageAtlas,
                    // Only used for benchmarking:
                    glyphMap: this.returnDependencies ? glyphMap : null,
                    iconMap: this.returnDependencies ? iconMap : null,
                    glyphPositions: this.returnDependencies ? glyphAtlas.positions : null
                });
                PerformanceUtils.endMeasure(m);
            }
        };

        const stacks = mapObject(options.glyphDependencies, (glyphs) => Object.keys(glyphs).map(Number));
        if (Object.keys(stacks).length) {
            actor.send('getGlyphs', {uid: this.uid, stacks}, (err, result) => {
                if (!error) {
                    error = err;
                    glyphMap = result;
                    maybePrepare();
                }
            }, undefined, false, taskMetadata);
        } else {
            glyphMap = {};
        }

        const icons = Object.keys(options.iconDependencies);
        if (icons.length) {
            actor.send('getImages', {icons, source: this.source, tileID: this.tileID, type: 'icons'}, (err, result) => {
                if (!error) {
                    error = err;
                    iconMap = result;
                    maybePrepare();
                }
            }, undefined, false, taskMetadata);
        } else {
            iconMap = {};
        }

        const patterns = Object.keys(options.patternDependencies);
        if (patterns.length) {
            actor.send('getImages', {icons: patterns, source: this.source, tileID: this.tileID, type: 'patterns'}, (err, result) => {
                if (!error) {
                    error = err;
                    patternMap = result;
                    maybePrepare();
                }
            }, undefined, false, taskMetadata);
        } else {
            patternMap = {};
        }

        PerformanceUtils.endMeasure(m);

        maybePrepare();
    }
}

function recalculateLayers(layers                            , zoom        , availableImages               ) {
    // Layers are shared and may have been used by a WorkerTile with a different zoom.
    const parameters = new EvaluationParameters(zoom);
    for (const layer of layers) {
        layer.recalculate(parameters, availableImages);
    }
}

//      


             
                 
                     
                         
                            
                       
                  
                                    

                                          
                                                                 
                                                   
                                                  
                                                     

                                    
                         
                             
                  
                       
                                                      
  

/**
 * @callback LoadVectorDataCallback
 * @param error
 * @param vectorTile
 * @private
 */
                                                                     

                                         
                                                                                                                     
class DedupedRequest {
                                  
                          

    constructor(scheduler            ) {
        this.entries = {};
        this.scheduler = scheduler;
    }

    request(key        , metadata        , request     , callback                        )               {
        const entry = this.entries[key] = this.entries[key] || {callbacks: []};

        if (entry.result) {
            const [err, result] = entry.result;
            if (this.scheduler) {
                this.scheduler.add(() => {
                    callback(err, result);
                }, metadata);
            } else {
                callback(err, result);
            }
            return () => {};
        }

        entry.callbacks.push(callback);

        if (!entry.cancel) {
            entry.cancel = request((err, result) => {
                entry.result = [err, result];
                for (const cb of entry.callbacks) {
                    if (this.scheduler) {
                        this.scheduler.add(() => {
                            cb(err, result);
                        }, metadata);
                    } else {
                        cb(err, result);
                    }
                }
                setTimeout(() => delete this.entries[key], 1000 * 3);
            });
        }

        return () => {
            if (entry.result) return;
            entry.callbacks = entry.callbacks.filter(cb => cb !== callback);
            if (!entry.callbacks.length) {
                entry.cancel();
                delete this.entries[key];
            }
        };
    }
}

/**
 * @private
 */
// $FlowFixMe[missing-this-annot]
function loadVectorTile(params                         , callback                        , skipParse          )               {
    const key = JSON.stringify(params.request);

    const makeRequest = (callback                        ) => {
        const request = getArrayBuffer(params.request, (err        , data              , cacheControl         , expires         ) => {
            if (err) {
                callback(err);
            } else if (data) {
                callback(null, {
                    vectorTile: skipParse ? undefined : new VectorTile(new Protobuf(data)),
                    rawData: data,
                    cacheControl,
                    expires
                });
            }
        });
        return () => {
            request.cancel();
            callback();
        };
    };

    if (params.data) {
        // if we already got the result earlier (on the main thread), return it directly
        (this.deduped                ).entries[key] = {result: [null, params.data]};
    }

    const callbackMetadata = {type: 'parseTile', isSymbolTile: params.isSymbolTile, zoom: params.tileZoom};
    return (this.deduped                ).request(key, callbackMetadata, makeRequest, callback);
}

/**
 * The {@link WorkerSource} implementation that supports {@link VectorTileSource}.
 * This class is designed to be easily reused to support custom source types
 * for data formats that can be parsed/converted into an in-memory VectorTile
 * representation.  To do so, create it with
 * `new VectorTileWorkerSource(actor, styleLayers, customLoadVectorDataFunction)`.
 *
 * @private
 */
class VectorTileWorkerSource extends Evented                         {
                 
                                
                                   
                                   
                                        
                                       
                            
                            
                          

    /**
     * @param [loadVectorData] Optional method for custom loading of a VectorTile
     * object based on parameters passed from the main-thread Source. See
     * {@link VectorTileWorkerSource#loadTile}. The default implementation simply
     * loads the pbf at `params.url`.
     * @private
     */
    constructor(actor       , layerIndex                 , availableImages               , isSpriteLoaded         , loadVectorData                 ) {
        super();
        this.actor = actor;
        this.layerIndex = layerIndex;
        this.availableImages = availableImages;
        this.loadVectorData = loadVectorData || loadVectorTile;
        this.loading = {};
        this.loaded = {};
        this.deduped = new DedupedRequest(actor.scheduler);
        this.isSpriteLoaded = isSpriteLoaded;
        this.scheduler = actor.scheduler;
    }

    /**
     * Implements {@link WorkerSource#loadTile}. Delegates to
     * {@link VectorTileWorkerSource#loadVectorData} (which by default expects
     * a `params.url` property) for fetching and producing a VectorTile object.
     * @private
     */
    loadTile(params                      , callback                    ) {
        const uid = params.uid;

        const requestParam = params && params.request;
        const perf = requestParam && requestParam.collectResourceTiming;

        const workerTile = this.loading[uid] = new WorkerTile(params);
        workerTile.abort = this.loadVectorData(params, (err, response) => {

            const aborted = !this.loading[uid];

            delete this.loading[uid];

            if (aborted || err || !response) {
                workerTile.status = 'done';
                if (!aborted) this.loaded[uid] = workerTile;
                return callback(err);
            }

            const rawTileData = response.rawData;
            const cacheControl = {};
            if (response.expires) cacheControl.expires = response.expires;
            if (response.cacheControl) cacheControl.cacheControl = response.cacheControl;

            // response.vectorTile will be present in the GeoJSON worker case (which inherits from this class)
            // because we stub the vector tile interface around JSON data instead of parsing it directly
            workerTile.vectorTile = response.vectorTile || new VectorTile(new Protobuf(rawTileData));
            const parseTile = () => {
                workerTile.parse(workerTile.vectorTile, this.layerIndex, this.availableImages, this.actor, (err, result) => {
                    if (err || !result) return callback(err);

                    const resourceTiming = {};
                    if (perf) {
                        // Transferring a copy of rawTileData because the worker needs to retain its copy.
                        const resourceTimingData = getPerformanceMeasurement(requestParam);
                        // it's necessary to eval the result of getEntriesByName() here via parse/stringify
                        // late evaluation in the main thread causes TypeError: illegal invocation
                        if (resourceTimingData.length > 0) {
                            resourceTiming.resourceTiming = JSON.parse(JSON.stringify(resourceTimingData));
                        }
                    }
                    callback(null, extend$1({rawTileData: rawTileData.slice(0)}, result, cacheControl, resourceTiming));
                });
            };

            if (this.isSpriteLoaded) {
                parseTile();
            } else {
                this.once('isSpriteLoaded', () => {
                    if (this.scheduler) {
                        const metadata = {type: 'parseTile', isSymbolTile: params.isSymbolTile, zoom: params.tileZoom};
                        this.scheduler.add(parseTile, metadata);
                    } else {
                        parseTile();
                    }
                });
            }

            this.loaded = this.loaded || {};
            this.loaded[uid] = workerTile;
        });
    }

    /**
     * Implements {@link WorkerSource#reloadTile}.
     * @private
     */
    reloadTile(params                      , callback                    ) {
        const loaded = this.loaded,
            uid = params.uid,
            vtSource = this;
        if (loaded && loaded[uid]) {
            const workerTile = loaded[uid];
            workerTile.showCollisionBoxes = params.showCollisionBoxes;
            workerTile.enableTerrain = !!params.enableTerrain;
            workerTile.projection = params.projection;
            workerTile.tileTransform = tileTransform(params.tileID.canonical, params.projection);

            const done = (err        , data                   ) => {
                const reloadCallback = workerTile.reloadCallback;
                if (reloadCallback) {
                    delete workerTile.reloadCallback;
                    workerTile.parse(workerTile.vectorTile, vtSource.layerIndex, this.availableImages, vtSource.actor, reloadCallback);
                }
                callback(err, data);
            };

            if (workerTile.status === 'parsing') {
                workerTile.reloadCallback = done;
            } else if (workerTile.status === 'done') {
                // if there was no vector tile data on the initial load, don't try and re-parse tile
                if (workerTile.vectorTile) {
                    workerTile.parse(workerTile.vectorTile, this.layerIndex, this.availableImages, this.actor, done);
                } else {
                    done();
                }
            }
        }
    }

    /**
     * Implements {@link WorkerSource#abortTile}.
     *
     * @param params
     * @param params.uid The UID for this tile.
     * @private
     */
    abortTile(params                , callback                    ) {
        const uid = params.uid;
        const tile = this.loading[uid];
        if (tile) {
            if (tile.abort) tile.abort();
            delete this.loading[uid];
        }
        callback();
    }

    /**
     * Implements {@link WorkerSource#removeTile}.
     *
     * @param params
     * @param params.uid The UID for this tile.
     * @private
     */
    removeTile(params                , callback                    ) {
        const loaded = this.loaded,
            uid = params.uid;
        if (loaded && loaded[uid]) {
            delete loaded[uid];
        }
        callback();
    }
}

//      
var refProperties = ['type', 'source', 'source-layer', 'minzoom', 'maxzoom', 'filter', 'layout'];

const ARRAY_TYPES = [
    Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array,
    Int32Array, Uint32Array, Float32Array, Float64Array
];

/** @typedef {Int8ArrayConstructor | Uint8ArrayConstructor | Uint8ClampedArrayConstructor | Int16ArrayConstructor | Uint16ArrayConstructor | Int32ArrayConstructor | Uint32ArrayConstructor | Float32ArrayConstructor | Float64ArrayConstructor} TypedArrayConstructor */

const VERSION = 1; // serialized format version
const HEADER_SIZE = 8;

class KDBush {

    /**
     * Creates an index from raw `ArrayBuffer` data.
     * @param {ArrayBuffer} data
     */
    static from(data) {
        if (!(data instanceof ArrayBuffer)) {
            throw new Error('Data must be an instance of ArrayBuffer.');
        }
        const [magic, versionAndType] = new Uint8Array(data, 0, 2);
        if (magic !== 0xdb) {
            throw new Error('Data does not appear to be in a KDBush format.');
        }
        const version = versionAndType >> 4;
        if (version !== VERSION) {
            throw new Error(`Got v${version} data when expected v${VERSION}.`);
        }
        const ArrayType = ARRAY_TYPES[versionAndType & 0x0f];
        if (!ArrayType) {
            throw new Error('Unrecognized array type.');
        }
        const [nodeSize] = new Uint16Array(data, 2, 1);
        const [numItems] = new Uint32Array(data, 4, 1);

        return new KDBush(numItems, nodeSize, ArrayType, data);
    }

    /**
     * Creates an index that will hold a given number of items.
     * @param {number} numItems
     * @param {number} [nodeSize=64] Size of the KD-tree node (64 by default).
     * @param {TypedArrayConstructor} [ArrayType=Float64Array] The array type used for coordinates storage (`Float64Array` by default).
     * @param {ArrayBuffer} [data] (For internal use only)
     */
    constructor(numItems, nodeSize = 64, ArrayType = Float64Array, data) {
        if (isNaN(numItems) || numItems < 0) throw new Error(`Unpexpected numItems value: ${numItems}.`);

        this.numItems = +numItems;
        this.nodeSize = Math.min(Math.max(+nodeSize, 2), 65535);
        this.ArrayType = ArrayType;
        this.IndexArrayType = numItems < 65536 ? Uint16Array : Uint32Array;

        const arrayTypeIndex = ARRAY_TYPES.indexOf(this.ArrayType);
        const coordsByteSize = numItems * 2 * this.ArrayType.BYTES_PER_ELEMENT;
        const idsByteSize = numItems * this.IndexArrayType.BYTES_PER_ELEMENT;
        const padCoords = (8 - idsByteSize % 8) % 8;

        if (arrayTypeIndex < 0) {
            throw new Error(`Unexpected typed array class: ${ArrayType}.`);
        }

        if (data && (data instanceof ArrayBuffer)) { // reconstruct an index from a buffer
            this.data = data;
            this.ids = new this.IndexArrayType(this.data, HEADER_SIZE, numItems);
            this.coords = new this.ArrayType(this.data, HEADER_SIZE + idsByteSize + padCoords, numItems * 2);
            this._pos = numItems * 2;
            this._finished = true;
        } else { // initialize a new index
            this.data = new ArrayBuffer(HEADER_SIZE + coordsByteSize + idsByteSize + padCoords);
            this.ids = new this.IndexArrayType(this.data, HEADER_SIZE, numItems);
            this.coords = new this.ArrayType(this.data, HEADER_SIZE + idsByteSize + padCoords, numItems * 2);
            this._pos = 0;
            this._finished = false;

            // set header
            new Uint8Array(this.data, 0, 2).set([0xdb, (VERSION << 4) + arrayTypeIndex]);
            new Uint16Array(this.data, 2, 1)[0] = nodeSize;
            new Uint32Array(this.data, 4, 1)[0] = numItems;
        }
    }

    /**
     * Add a point to the index.
     * @param {number} x
     * @param {number} y
     * @returns {number} An incremental index associated with the added item (starting from `0`).
     */
    add(x, y) {
        const index = this._pos >> 1;
        this.ids[index] = index;
        this.coords[this._pos++] = x;
        this.coords[this._pos++] = y;
        return index;
    }

    /**
     * Perform indexing of the added points.
     */
    finish() {
        const numAdded = this._pos >> 1;
        if (numAdded !== this.numItems) {
            throw new Error(`Added ${numAdded} items when expected ${this.numItems}.`);
        }
        // kd-sort both arrays for efficient search
        sort(this.ids, this.coords, this.nodeSize, 0, this.numItems - 1, 0);

        this._finished = true;
        return this;
    }

    /**
     * Search the index for items within a given bounding box.
     * @param {number} minX
     * @param {number} minY
     * @param {number} maxX
     * @param {number} maxY
     * @returns {number[]} An array of indices correponding to the found items.
     */
    range(minX, minY, maxX, maxY) {
        if (!this._finished) throw new Error('Data not yet indexed - call index.finish().');

        const {ids, coords, nodeSize} = this;
        const stack = [0, ids.length - 1, 0];
        const result = [];

        // recursively search for items in range in the kd-sorted arrays
        while (stack.length) {
            const axis = stack.pop() || 0;
            const right = stack.pop() || 0;
            const left = stack.pop() || 0;

            // if we reached "tree node", search linearly
            if (right - left <= nodeSize) {
                for (let i = left; i <= right; i++) {
                    const x = coords[2 * i];
                    const y = coords[2 * i + 1];
                    if (x >= minX && x <= maxX && y >= minY && y <= maxY) result.push(ids[i]);
                }
                continue;
            }

            // otherwise find the middle index
            const m = (left + right) >> 1;

            // include the middle item if it's in range
            const x = coords[2 * m];
            const y = coords[2 * m + 1];
            if (x >= minX && x <= maxX && y >= minY && y <= maxY) result.push(ids[m]);

            // queue search in halves that intersect the query
            if (axis === 0 ? minX <= x : minY <= y) {
                stack.push(left);
                stack.push(m - 1);
                stack.push(1 - axis);
            }
            if (axis === 0 ? maxX >= x : maxY >= y) {
                stack.push(m + 1);
                stack.push(right);
                stack.push(1 - axis);
            }
        }

        return result;
    }

    /**
     * Search the index for items within a given radius.
     * @param {number} qx
     * @param {number} qy
     * @param {number} r Query radius.
     * @returns {number[]} An array of indices correponding to the found items.
     */
    within(qx, qy, r) {
        if (!this._finished) throw new Error('Data not yet indexed - call index.finish().');

        const {ids, coords, nodeSize} = this;
        const stack = [0, ids.length - 1, 0];
        const result = [];
        const r2 = r * r;

        // recursively search for items within radius in the kd-sorted arrays
        while (stack.length) {
            const axis = stack.pop() || 0;
            const right = stack.pop() || 0;
            const left = stack.pop() || 0;

            // if we reached "tree node", search linearly
            if (right - left <= nodeSize) {
                for (let i = left; i <= right; i++) {
                    if (sqDist(coords[2 * i], coords[2 * i + 1], qx, qy) <= r2) result.push(ids[i]);
                }
                continue;
            }

            // otherwise find the middle index
            const m = (left + right) >> 1;

            // include the middle item if it's in range
            const x = coords[2 * m];
            const y = coords[2 * m + 1];
            if (sqDist(x, y, qx, qy) <= r2) result.push(ids[m]);

            // queue search in halves that intersect the query
            if (axis === 0 ? qx - r <= x : qy - r <= y) {
                stack.push(left);
                stack.push(m - 1);
                stack.push(1 - axis);
            }
            if (axis === 0 ? qx + r >= x : qy + r >= y) {
                stack.push(m + 1);
                stack.push(right);
                stack.push(1 - axis);
            }
        }

        return result;
    }
}

/**
 * @param {Uint16Array | Uint32Array} ids
 * @param {InstanceType<TypedArrayConstructor>} coords
 * @param {number} nodeSize
 * @param {number} left
 * @param {number} right
 * @param {number} axis
 */
function sort(ids, coords, nodeSize, left, right, axis) {
    if (right - left <= nodeSize) return;

    const m = (left + right) >> 1; // middle index

    // sort ids and coords around the middle index so that the halves lie
    // either left/right or top/bottom correspondingly (taking turns)
    select(ids, coords, m, left, right, axis);

    // recursively kd-sort first half and second half on the opposite axis
    sort(ids, coords, nodeSize, left, m - 1, 1 - axis);
    sort(ids, coords, nodeSize, m + 1, right, 1 - axis);
}

/**
 * Custom Floyd-Rivest selection algorithm: sort ids and coords so that
 * [left..k-1] items are smaller than k-th item (on either x or y axis)
 * @param {Uint16Array | Uint32Array} ids
 * @param {InstanceType<TypedArrayConstructor>} coords
 * @param {number} k
 * @param {number} left
 * @param {number} right
 * @param {number} axis
 */
function select(ids, coords, k, left, right, axis) {

    while (right > left) {
        if (right - left > 600) {
            const n = right - left + 1;
            const m = k - left + 1;
            const z = Math.log(n);
            const s = 0.5 * Math.exp(2 * z / 3);
            const sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);
            const newLeft = Math.max(left, Math.floor(k - m * s / n + sd));
            const newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));
            select(ids, coords, k, newLeft, newRight, axis);
        }

        const t = coords[2 * k + axis];
        let i = left;
        let j = right;

        swapItem(ids, coords, left, k);
        if (coords[2 * right + axis] > t) swapItem(ids, coords, left, right);

        while (i < j) {
            swapItem(ids, coords, i, j);
            i++;
            j--;
            while (coords[2 * i + axis] < t) i++;
            while (coords[2 * j + axis] > t) j--;
        }

        if (coords[2 * left + axis] === t) swapItem(ids, coords, left, j);
        else {
            j++;
            swapItem(ids, coords, j, right);
        }

        if (j <= k) left = j + 1;
        if (k <= j) right = j - 1;
    }
}

/**
 * @param {Uint16Array | Uint32Array} ids
 * @param {InstanceType<TypedArrayConstructor>} coords
 * @param {number} i
 * @param {number} j
 */
function swapItem(ids, coords, i, j) {
    swap(ids, i, j);
    swap(coords, 2 * i, 2 * j);
    swap(coords, 2 * i + 1, 2 * j + 1);
}

/**
 * @param {InstanceType<TypedArrayConstructor>} arr
 * @param {number} i
 * @param {number} j
 */
function swap(arr, i, j) {
    const tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}

/**
 * @param {number} ax
 * @param {number} ay
 * @param {number} bx
 * @param {number} by
 */
function sqDist(ax, ay, bx, by) {
    const dx = ax - bx;
    const dy = ay - by;
    return dx * dx + dy * dy;
}

exports.AUTH_ERR_MSG = AUTH_ERR_MSG;
exports.Aabb = Aabb;
exports.Actor = Actor;
exports.CanonicalTileID = CanonicalTileID;
exports.Color = Color;
exports.ColorMode = ColorMode;
exports.Context = Context;
exports.CullFaceMode = CullFaceMode;
exports.DEMData = DEMData;
exports.DataConstantProperty = DataConstantProperty;
exports.Debug = Debug;
exports.DedupedRequest = DedupedRequest;
exports.DepthMode = DepthMode;
exports.DepthStencilAttachment = DepthStencilAttachment;
exports.EXTENT = EXTENT;
exports.Elevation = Elevation;
exports.ErrorEvent = ErrorEvent;
exports.EvaluationParameters = EvaluationParameters;
exports.Event = Event;
exports.Evented = Evented;
exports.FillExtrusionBucket = FillExtrusionBucket;
exports.Frustum = Frustum;
exports.FrustumCorners = FrustumCorners;
exports.GLOBE_RADIUS = GLOBE_RADIUS;
exports.GLOBE_SCALE_MATCH_LATITUDE = GLOBE_SCALE_MATCH_LATITUDE;
exports.GLOBE_ZOOM_THRESHOLD_MAX = GLOBE_ZOOM_THRESHOLD_MAX;
exports.GLOBE_ZOOM_THRESHOLD_MIN = GLOBE_ZOOM_THRESHOLD_MIN;
exports.GlobeSharedBuffers = GlobeSharedBuffers;
exports.GlyphManager = GlyphManager;
exports.ImagePosition = ImagePosition;
exports.KDBush = KDBush;
exports.LivePerformanceUtils = LivePerformanceUtils;
exports.LngLat = LngLat$1;
exports.LngLatBounds = LngLatBounds;
exports.LocalGlyphMode = LocalGlyphMode;
exports.MAX_MERCATOR_LATITUDE = MAX_MERCATOR_LATITUDE;
exports.MercatorCoordinate = MercatorCoordinate$1;
exports.ONE_EM = ONE_EM;
exports.OverscaledTileID = OverscaledTileID;
exports.PerformanceMarkers = PerformanceMarkers;
exports.PerformanceUtils = PerformanceUtils;
exports.Point = Point$2;
exports.Properties = Properties;
exports.RGBAImage = RGBAImage;
exports.Ray = Ray;
exports.RequestManager = RequestManager;
exports.ResourceType = ResourceType;
exports.SegmentVector = SegmentVector;
exports.SourceCache = SourceCache;
exports.StencilMode = StencilMode;
exports.StructArrayLayout1ui2 = StructArrayLayout1ui2;
exports.StructArrayLayout2f1f2i16 = StructArrayLayout2f1f2i16;
exports.StructArrayLayout2i4 = StructArrayLayout2i4;
exports.StructArrayLayout2ui4 = StructArrayLayout2ui4;
exports.StructArrayLayout3f12 = StructArrayLayout3f12;
exports.StructArrayLayout3ui6 = StructArrayLayout3ui6;
exports.StructArrayLayout4i8 = StructArrayLayout4i8;
exports.StructArrayLayout5f20 = StructArrayLayout5f20;
exports.Texture = Texture;
exports.Tile = Tile;
exports.Transitionable = Transitionable;
exports.Uniform1f = Uniform1f;
exports.Uniform1i = Uniform1i;
exports.Uniform2f = Uniform2f;
exports.Uniform3f = Uniform3f;
exports.Uniform4f = Uniform4f;
exports.UniformColor = UniformColor;
exports.UniformMatrix2f = UniformMatrix2f;
exports.UniformMatrix3f = UniformMatrix3f;
exports.UniformMatrix4f = UniformMatrix4f;
exports.UnwrappedTileID = UnwrappedTileID;
exports.ValidationError = ValidationError;
exports.VectorTileFeature = VectorTileFeature;
exports.VectorTileWorkerSource = VectorTileWorkerSource;
exports.WritingMode = WritingMode;
exports.ZoomDependentExpression = ZoomDependentExpression;
exports.add = add$4;
exports.addDynamicAttributes = addDynamicAttributes;
exports.adjoint = adjoint$1;
exports.assert = assert$1;
exports.asyncAll = asyncAll;
exports.bezier = bezier$1;
exports.bindAll = bindAll;
exports.boundsAttributes = boundsAttributes;
exports.bufferConvexPolygon = bufferConvexPolygon;
exports.cacheEntryPossiblyAdded = cacheEntryPossiblyAdded;
exports.calculateGlobeLabelMatrix = calculateGlobeLabelMatrix;
exports.calculateGlobeMatrix = calculateGlobeMatrix;
exports.calculateGlobeMercatorMatrix = calculateGlobeMercatorMatrix;
exports.circumferenceAtLatitude = circumferenceAtLatitude;
exports.clamp = clamp;
exports.clearTileCache = clearTileCache;
exports.clipLine = clipLine;
exports.clone = clone$5;
exports.clone$1 = clone$9;
exports.collisionCircleLayout = collisionCircleLayout;
exports.config = config;
exports.conjugate = conjugate$1;
exports.create = create$5;
exports.create$1 = create$6;
exports.create$2 = create$8;
exports.createExpression = createExpression;
exports.createLayout = createLayout;
exports.createStyleLayer = createStyleLayer;
exports.cross = cross$2;
exports.deepEqual = deepEqual;
exports.degToRad = degToRad;
exports.distance = distance$2;
exports.div = div$2;
exports.dot = dot$5;
exports.earthRadius = earthRadius;
exports.ease = ease;
exports.easeCubicInOut = easeCubicInOut;
exports.ecefToLatLng = ecefToLatLng;
exports.emitValidationErrors = emitValidationErrors;
exports.endsWith = endsWith;
exports.enforceCacheSizeLimit = enforceCacheSizeLimit;
exports.evaluateSizeForFeature = evaluateSizeForFeature;
exports.evaluateSizeForZoom = evaluateSizeForZoom;
exports.evaluateVariableOffset = evaluateVariableOffset;
exports.evented = evented;
exports.exactEquals = exactEquals$2;
exports.exactEquals$1 = exactEquals$4;
exports.exported = exported;
exports.exported$1 = exported$1;
exports.extend = extend$1;
exports.extend$1 = extend;
exports.fillExtrusionHeightLift = fillExtrusionHeightLift;
exports.filterObject = filterObject;
exports.fromMat4 = fromMat4$1;
exports.fromQuat = fromQuat;
exports.fromRotation = fromRotation$2;
exports.fromScaling = fromScaling;
exports.furthestTileCorner = furthestTileCorner;
exports.getAABBPointSquareDist = getAABBPointSquareDist;
exports.getAnchorAlignment = getAnchorAlignment;
exports.getAnchorJustification = getAnchorJustification;
exports.getBounds = getBounds;
exports.getColumn = getColumn;
exports.getDefaultExportFromCjs = getDefaultExportFromCjs;
exports.getGridMatrix = getGridMatrix;
exports.getImage = getImage;
exports.getJSON = getJSON;
exports.getLatitudinalLod = getLatitudinalLod;
exports.getMapSessionAPI = getMapSessionAPI;
exports.getPerformanceMeasurement = getPerformanceMeasurement;
exports.getProjection = getProjection;
exports.getRTLTextPluginStatus = getRTLTextPluginStatus;
exports.getReferrer = getReferrer;
exports.getTilePoint = getTilePoint;
exports.getTileVec3 = getTileVec3;
exports.getVideo = getVideo;
exports.globeCenterToScreenPoint = globeCenterToScreenPoint;
exports.globeDenormalizeECEF = globeDenormalizeECEF;
exports.globeECEFOrigin = globeECEFOrigin;
exports.globeMetersToEcef = globeMetersToEcef;
exports.globeNormalizeECEF = globeNormalizeECEF;
exports.globePixelsToTileUnits = globePixelsToTileUnits;
exports.globePoleMatrixForTile = globePoleMatrixForTile;
exports.globeTileBounds = globeTileBounds;
exports.globeTiltAtLngLat = globeTiltAtLngLat;
exports.globeToMercatorTransition = globeToMercatorTransition;
exports.globeUseCustomAntiAliasing = globeUseCustomAntiAliasing;
exports.identity = identity$3;
exports.identity$1 = identity$2;
exports.invert = invert$5;
exports.invert$1 = invert$2;
exports.isFullscreen = isFullscreen;
exports.isLngLatBehindGlobe = isLngLatBehindGlobe;
exports.isMapAuthenticated = isMapAuthenticated;
exports.isMapboxURL = isMapboxURL;
exports.isSafari = isSafari;
exports.isSafariWithAntialiasingBug = isSafariWithAntialiasingBug;
exports.latFromMercatorY = latFromMercatorY;
exports.latLngToECEF = latLngToECEF;
exports.len = len$4;
exports.length = length$4;
exports.length$1 = length$2;
exports.lngFromMercatorX = lngFromMercatorX;
exports.loadVectorTile = loadVectorTile;
exports.makeRequest = makeRequest;
exports.mapValue = mapValue;
exports.mercatorScale = mercatorScale;
exports.mercatorXfromLng = mercatorXfromLng;
exports.mercatorYfromLat = mercatorYfromLat;
exports.mercatorZfromAltitude = mercatorZfromAltitude;
exports.mul = mul$5;
exports.mul$1 = mul$4;
exports.multiply = multiply$5;
exports.multiply$1 = multiply$6;
exports.multiply$2 = multiply$4;
exports.nextPowerOfTwo = nextPowerOfTwo;
exports.normalize = normalize$4;
exports.normalize$1 = normalize$2;
exports.normalize$2 = normalize$3;
exports.number = number;
exports.ortho = ortho;
exports.pbf = pbf;
exports.perspective = perspective;
exports.pick = pick;
exports.plugin = plugin;
exports.pointGeometry = pointGeometry;
exports.polesInViewport = polesInViewport;
exports.polygonContainsPoint = polygonContainsPoint;
exports.polygonIntersectsBox = polygonIntersectsBox;
exports.polygonIntersectsPolygon = polygonIntersectsPolygon;
exports.polygonizeBounds = polygonizeBounds;
exports.posAttributes = posAttributes;
exports.postMapLoadEvent = postMapLoadEvent;
exports.postPerformanceEvent = postPerformanceEvent;
exports.postTurnstileEvent = postTurnstileEvent;
exports.potpack = potpack;
exports.prevPowerOfTwo = prevPowerOfTwo;
exports.radToDeg = radToDeg;
exports.refProperties = refProperties;
exports.registerForPluginStateChange = registerForPluginStateChange;
exports.removeAuthState = removeAuthState;
exports.renderColorRamp = renderColorRamp;
exports.resample = resample$1;
exports.rotate = rotate$4;
exports.rotateX = rotateX$3;
exports.rotateX$1 = rotateX$1;
exports.rotateY = rotateY$3;
exports.rotateY$1 = rotateY$1;
exports.rotateZ = rotateZ$3;
exports.rotateZ$1 = rotateZ$1;
exports.scale = scale$8;
exports.scale$1 = scale$5;
exports.scale$2 = scale$3;
exports.scale$3 = scale$4;
exports.scaleAndAdd = scaleAndAdd$2;
exports.set = set$4;
exports.setCacheLimits = setCacheLimits;
exports.setColumn = setColumn;
exports.setRTLTextPlugin = setRTLTextPlugin;
exports.smoothstep = smoothstep;
exports.spec = spec;
exports.squaredLength = squaredLength$4;
exports.storeAuthState = storeAuthState;
exports.sub = sub$2;
exports.subtract = subtract$2;
exports.symbolSize = symbolSize;
exports.tileAABB = tileAABB;
exports.tileCornersToBounds = tileCornersToBounds;
exports.tileTransform = tileTransform;
exports.transformMat3 = transformMat3$1;
exports.transformMat4 = transformMat4$2;
exports.transformMat4$1 = transformMat4$1;
exports.transformQuat = transformQuat$1;
exports.transitionTileAABBinECEF = transitionTileAABBinECEF;
exports.translate = translate$2;
exports.transpose = transpose$1;
exports.triggerPluginCompletionEvent = triggerPluginCompletionEvent;
exports.uniqueId = uniqueId;
exports.updateGlobeVertexNormal = updateGlobeVertexNormal;
exports.validateCustomStyleLayer = validateCustomStyleLayer;
exports.validateFilter = validateFilter;
exports.validateFog = validateFog;
exports.validateLayer = validateLayer;
exports.validateLight = validateLight;
exports.validateSource = validateSource;
exports.validateStyle = validateStyle;
exports.validateTerrain = validateTerrain;
exports.values = values;
exports.vectorTile = vectorTile;
exports.version = version;
exports.warnOnce = warnOnce;
exports.window = window$1;
exports.wrap = wrap;

}));

define(['./shared'], (function (index) { 'use strict';

//      


function stringify(obj     ) {
    if (typeof obj === 'number' || typeof obj === 'boolean' || typeof obj === 'string' || obj === undefined || obj === null)
        return JSON.stringify(obj);

    if (Array.isArray(obj)) {
        let str = '[';
        for (const val of obj) {
            str += `${stringify(val)},`;
        }
        return `${str}]`;
    }

    let str = '{';
    for (const key of Object.keys(obj).sort()) {
        str += `${key}:${stringify((obj     )[key])},`;
    }
    return `${str}}`;
}

function getKey(layer                    ) {
    let key = '';
    for (const k of index.refProperties) {
        key += `/${stringify((layer     )[k])}`;
    }
    return key;
}

/**
 * Given an array of layers, return an array of arrays of layers where all
 * layers in each group have identical layout-affecting properties. These
 * are the properties that were formerly used by explicit `ref` mechanism
 * for layers: 'type', 'source', 'source-layer', 'minzoom', 'maxzoom',
 * 'filter', and 'layout'.
 *
 * The input is not modified. The output layers are references to the
 * input layers.
 *
 * @private
 * @param {Array<Layer>} layers
 * @param {Object} [cachedKeys] - an object to keep already calculated keys.
 * @returns {Array<Array<Layer>>}
 */
function groupByLayout(layers                           , cachedKeys                        )                                   {
    const groups = {};

    for (let i = 0; i < layers.length; i++) {

        const k = (cachedKeys && cachedKeys[layers[i].id]) || getKey(layers[i]);
        // update the cache if there is one
        if (cachedKeys)
            cachedKeys[layers[i].id] = k;

        let group = groups[k];
        if (!group) {
            group = groups[k] = [];
        }
        group.push(layers[i]);
    }

    const result = [];

    for (const k in groups) {
        result.push(groups[k]);
    }

    return result;
}

//      


                                                                        
                                                               

                                                              
                                                          

class StyleLayerIndex {
                                                                                                      
                                           

                                
                                             

    constructor(layerConfigs                            ) {
        this.keyCache = {};
        if (layerConfigs) {
            this.replace(layerConfigs);
        }
    }

    replace(layerConfigs                           ) {
        this._layerConfigs = {};
        this._layers = {};
        this.update(layerConfigs, []);
    }

    update(layerConfigs                           , removedIds               ) {
        for (const layerConfig of layerConfigs) {
            this._layerConfigs[layerConfig.id] = layerConfig;

            const layer = this._layers[layerConfig.id] = ((index.createStyleLayer(layerConfig)     )                 );
            layer.compileFilter();
            if (this.keyCache[layerConfig.id])
                delete this.keyCache[layerConfig.id];
        }
        for (const id of removedIds) {
            delete this.keyCache[id];
            delete this._layerConfigs[id];
            delete this._layers[id];
        }

        this.familiesBySource = {};

        const groups = groupByLayout(index.values(this._layerConfigs), this.keyCache);

        for (const layerConfigs of groups) {
            const layers = layerConfigs.map((layerConfig) => this._layers[layerConfig.id]);

            const layer = layers[0];
            if (layer.visibility === 'none') {
                continue;
            }

            const sourceId = layer.source || '';
            let sourceGroup = this.familiesBySource[sourceId];
            if (!sourceGroup) {
                sourceGroup = this.familiesBySource[sourceId] = {};
            }

            const sourceLayerId = layer.sourceLayer || '_geojsonTileLayer';
            let sourceLayerFamilies = sourceGroup[sourceLayerId];
            if (!sourceLayerFamilies) {
                sourceLayerFamilies = sourceGroup[sourceLayerId] = [];
            }

            sourceLayerFamilies.push(layers);
        }
    }
}

//      


                                          
                                                                                       

class RasterDEMTileWorkerSource {
                 
                                     
                                                     

    loadTile(params                         , callback                       ) {
        const {uid, encoding, rawImageData, padding, buildQuadTree} = params;
        // Main thread will transfer ImageBitmap if offscreen decode with OffscreenCanvas is supported, else it will transfer an already decoded image.
        // Flow struggles to refine ImageBitmap type, likely due to the JSDom shim
        const imagePixels = index.window.ImageBitmap && rawImageData instanceof index.window.ImageBitmap ? this.getImageData(rawImageData, padding) : ((rawImageData     )           );
        const dem = new index.DEMData(uid, imagePixels, encoding, padding < 1, buildQuadTree);
        callback(null, dem);
    }

    getImageData(imgBitmap             , padding        )            {
        // Lazily initialize OffscreenCanvas
        if (!this.offscreenCanvas || !this.offscreenCanvasContext) {
            // Dem tiles are typically 256x256
            this.offscreenCanvas = new OffscreenCanvas(imgBitmap.width, imgBitmap.height);
            // $FlowIssue[extra-arg]: internal Flow types don't yet know about willReadFrequently
            this.offscreenCanvasContext = this.offscreenCanvas.getContext('2d', {willReadFrequently: true});
        }

        this.offscreenCanvas.width = imgBitmap.width;
        this.offscreenCanvas.height = imgBitmap.height;

        this.offscreenCanvasContext.drawImage(imgBitmap, 0, 0, imgBitmap.width, imgBitmap.height);
        // Insert or remove defined padding around the image to allow backfilling for neighboring data.
        const imgData = this.offscreenCanvasContext.getImageData(-padding, -padding, imgBitmap.width + 2 * padding, imgBitmap.height + 2 * padding);
        this.offscreenCanvasContext.clearRect(0, 0, this.offscreenCanvas.width, this.offscreenCanvas.height);
        return imgData;
    }
}

var geojsonRewind = rewind$1;

function rewind$1(gj, outer) {
    var type = gj && gj.type, i;

    if (type === 'FeatureCollection') {
        for (i = 0; i < gj.features.length; i++) rewind$1(gj.features[i], outer);

    } else if (type === 'GeometryCollection') {
        for (i = 0; i < gj.geometries.length; i++) rewind$1(gj.geometries[i], outer);

    } else if (type === 'Feature') {
        rewind$1(gj.geometry, outer);

    } else if (type === 'Polygon') {
        rewindRings(gj.coordinates, outer);

    } else if (type === 'MultiPolygon') {
        for (i = 0; i < gj.coordinates.length; i++) rewindRings(gj.coordinates[i], outer);
    }

    return gj;
}

function rewindRings(rings, outer) {
    if (rings.length === 0) return;

    rewindRing(rings[0], outer);
    for (var i = 1; i < rings.length; i++) {
        rewindRing(rings[i], !outer);
    }
}

function rewindRing(ring, dir) {
    var area = 0, err = 0;
    for (var i = 0, len = ring.length, j = len - 1; i < len; j = i++) {
        var k = (ring[i][0] - ring[j][0]) * (ring[j][1] + ring[i][1]);
        var m = area + k;
        err += Math.abs(area) >= Math.abs(k) ? area - m + k : k - m + area;
        area = m;
    }
    if (area + err >= 0 !== !!dir) ring.reverse();
}

var rewind$2 = /*@__PURE__*/index.getDefaultExportFromCjs(geojsonRewind);

//      

// $FlowFixMe[method-unbinding]
const toGeoJSON = index.VectorTileFeature.prototype.toGeoJSON;

                                                          
                                                                                           

// The feature type used by geojson-vt and supercluster. Should be extracted to
// global type and used in module definitions for those two modules.
                
            
              
                                                   
                                      
     
                
              
                                                   
                                             
 

let FeatureWrapper$1 = class FeatureWrapper                               {
                      

                   
                    
               
                                                         

    constructor(feature         ) {
        this._feature = feature;

        this.extent = index.EXTENT;
        this.type = feature.type;
        this.properties = feature.tags;

        // If the feature has a top-level `id` property, copy it over, but only
        // if it can be coerced to an integer, because this wrapper is used for
        // serializing geojson feature data into vector tile PBF data, and the
        // vector tile spec only supports integer values for feature ids --
        // allowing non-integer values here results in a non-compliant PBF
        // that causes an exception when it is parsed with vector-tile-js
        if ('id' in feature && !isNaN(feature.id)) {
            this.id = parseInt(feature.id, 10);
        }
    }

    loadGeometry()                      {
        if (this._feature.type === 1) {
            const geometry = [];
            for (const point of this._feature.geometry) {
                geometry.push([new index.Point(point[0], point[1])]);
            }
            return geometry;
        } else {
            const geometry = [];
            for (const ring of this._feature.geometry) {
                const newRing = [];
                for (const point of ring) {
                    newRing.push(new index.Point(point[0], point[1]));
                }
                geometry.push(newRing);
            }
            return geometry;
        }
    }

    toGeoJSON(x        , y        , z        )                 {
        return toGeoJSON.call(this, x, y, z);
    }
};

let GeoJSONWrapper$2 = class GeoJSONWrapper                                          {
                                            
                 
                   
                   
                              

    constructor(features                ) {
        this.layers = {'_geojsonTileLayer': this};
        this.name = '_geojsonTileLayer';
        this.extent = index.EXTENT;
        this.length = features.length;
        this._features = features;
    }

    feature(i        )                     {
        return new FeatureWrapper$1(this._features[i]);
    }
};

var vtPbf$1 = {exports: {}};

'use strict';

var Point = index.pointGeometry;
var VectorTileFeature = index.vectorTile.VectorTileFeature;

var geojson_wrapper = GeoJSONWrapper$1;

// conform to vectortile api
function GeoJSONWrapper$1 (features, options) {
  this.options = options || {};
  this.features = features;
  this.length = features.length;
}

GeoJSONWrapper$1.prototype.feature = function (i) {
  return new FeatureWrapper(this.features[i], this.options.extent)
};

function FeatureWrapper (feature, extent) {
  this.id = typeof feature.id === 'number' ? feature.id : undefined;
  this.type = feature.type;
  this.rawGeometry = feature.type === 1 ? [feature.geometry] : feature.geometry;
  this.properties = feature.tags;
  this.extent = extent || 4096;
}

FeatureWrapper.prototype.loadGeometry = function () {
  var rings = this.rawGeometry;
  this.geometry = [];

  for (var i = 0; i < rings.length; i++) {
    var ring = rings[i];
    var newRing = [];
    for (var j = 0; j < ring.length; j++) {
      newRing.push(new Point(ring[j][0], ring[j][1]));
    }
    this.geometry.push(newRing);
  }
  return this.geometry
};

FeatureWrapper.prototype.bbox = function () {
  if (!this.geometry) this.loadGeometry();

  var rings = this.geometry;
  var x1 = Infinity;
  var x2 = -Infinity;
  var y1 = Infinity;
  var y2 = -Infinity;

  for (var i = 0; i < rings.length; i++) {
    var ring = rings[i];

    for (var j = 0; j < ring.length; j++) {
      var coord = ring[j];

      x1 = Math.min(x1, coord.x);
      x2 = Math.max(x2, coord.x);
      y1 = Math.min(y1, coord.y);
      y2 = Math.max(y2, coord.y);
    }
  }

  return [x1, y1, x2, y2]
};

FeatureWrapper.prototype.toGeoJSON = VectorTileFeature.prototype.toGeoJSON;

var geojson_wrapper$1 = /*@__PURE__*/index.getDefaultExportFromCjs(geojson_wrapper);

var vtPbf = vtPbf$1.exports;

var Pbf = index.pbf;
var GeoJSONWrapper = geojson_wrapper;

vtPbf$1.exports = fromVectorTileJs;
var fromVectorTileJs_1 = vtPbf$1.exports.fromVectorTileJs = fromVectorTileJs;
var fromGeojsonVt_1 = vtPbf$1.exports.fromGeojsonVt = fromGeojsonVt;
var GeoJSONWrapper_1 = vtPbf$1.exports.GeoJSONWrapper = GeoJSONWrapper;

/**
 * Serialize a vector-tile-js-created tile to pbf
 *
 * @param {Object} tile
 * @return {Buffer} uncompressed, pbf-serialized tile data
 */
function fromVectorTileJs (tile) {
  var out = new Pbf();
  writeTile(tile, out);
  return out.finish()
}

/**
 * Serialized a geojson-vt-created tile to pbf.
 *
 * @param {Object} layers - An object mapping layer names to geojson-vt-created vector tile objects
 * @param {Object} [options] - An object specifying the vector-tile specification version and extent that were used to create `layers`.
 * @param {Number} [options.version=1] - Version of vector-tile spec used
 * @param {Number} [options.extent=4096] - Extent of the vector tile
 * @return {Buffer} uncompressed, pbf-serialized tile data
 */
function fromGeojsonVt (layers, options) {
  options = options || {};
  var l = {};
  for (var k in layers) {
    l[k] = new GeoJSONWrapper(layers[k].features, options);
    l[k].name = k;
    l[k].version = options.version;
    l[k].extent = options.extent;
  }
  return fromVectorTileJs({ layers: l })
}

function writeTile (tile, pbf) {
  for (var key in tile.layers) {
    pbf.writeMessage(3, writeLayer, tile.layers[key]);
  }
}

function writeLayer (layer, pbf) {
  pbf.writeVarintField(15, layer.version || 1);
  pbf.writeStringField(1, layer.name || '');
  pbf.writeVarintField(5, layer.extent || 4096);

  var i;
  var context = {
    keys: [],
    values: [],
    keycache: {},
    valuecache: {}
  };

  for (i = 0; i < layer.length; i++) {
    context.feature = layer.feature(i);
    pbf.writeMessage(2, writeFeature, context);
  }

  var keys = context.keys;
  for (i = 0; i < keys.length; i++) {
    pbf.writeStringField(3, keys[i]);
  }

  var values = context.values;
  for (i = 0; i < values.length; i++) {
    pbf.writeMessage(4, writeValue, values[i]);
  }
}

function writeFeature (context, pbf) {
  var feature = context.feature;

  if (feature.id !== undefined) {
    pbf.writeVarintField(1, feature.id);
  }

  pbf.writeMessage(2, writeProperties, context);
  pbf.writeVarintField(3, feature.type);
  pbf.writeMessage(4, writeGeometry, feature);
}

function writeProperties (context, pbf) {
  var feature = context.feature;
  var keys = context.keys;
  var values = context.values;
  var keycache = context.keycache;
  var valuecache = context.valuecache;

  for (var key in feature.properties) {
    var value = feature.properties[key];

    var keyIndex = keycache[key];
    if (value === null) continue // don't encode null value properties

    if (typeof keyIndex === 'undefined') {
      keys.push(key);
      keyIndex = keys.length - 1;
      keycache[key] = keyIndex;
    }
    pbf.writeVarint(keyIndex);

    var type = typeof value;
    if (type !== 'string' && type !== 'boolean' && type !== 'number') {
      value = JSON.stringify(value);
    }
    var valueKey = type + ':' + value;
    var valueIndex = valuecache[valueKey];
    if (typeof valueIndex === 'undefined') {
      values.push(value);
      valueIndex = values.length - 1;
      valuecache[valueKey] = valueIndex;
    }
    pbf.writeVarint(valueIndex);
  }
}

function command (cmd, length) {
  return (length << 3) + (cmd & 0x7)
}

function zigzag (num) {
  return (num << 1) ^ (num >> 31)
}

function writeGeometry (feature, pbf) {
  var geometry = feature.loadGeometry();
  var type = feature.type;
  var x = 0;
  var y = 0;
  var rings = geometry.length;
  for (var r = 0; r < rings; r++) {
    var ring = geometry[r];
    var count = 1;
    if (type === 1) {
      count = ring.length;
    }
    pbf.writeVarint(command(1, count)); // moveto
    // do not write polygon closing path as lineto
    var lineCount = type === 3 ? ring.length - 1 : ring.length;
    for (var i = 0; i < lineCount; i++) {
      if (i === 1 && type !== 1) {
        pbf.writeVarint(command(2, lineCount - 1)); // lineto
      }
      var dx = ring[i].x - x;
      var dy = ring[i].y - y;
      pbf.writeVarint(zigzag(dx));
      pbf.writeVarint(zigzag(dy));
      x += dx;
      y += dy;
    }
    if (type === 3) {
      pbf.writeVarint(command(7, 1)); // closepath
    }
  }
}

function writeValue (value, pbf) {
  var type = typeof value;
  if (type === 'string') {
    pbf.writeStringField(1, value);
  } else if (type === 'boolean') {
    pbf.writeBooleanField(7, value);
  } else if (type === 'number') {
    if (value % 1 !== 0) {
      pbf.writeDoubleField(3, value);
    } else if (value < 0) {
      pbf.writeSVarintField(6, value);
    } else {
      pbf.writeVarintField(5, value);
    }
  }
}

var vtPbfExports = vtPbf$1.exports;
var vtpbf = /*@__PURE__*/index.getDefaultExportFromCjs(vtPbfExports);

const defaultOptions = {
    minZoom: 0,   // min zoom to generate clusters on
    maxZoom: 16,  // max zoom level to cluster the points on
    minPoints: 2, // minimum points to form a cluster
    radius: 40,   // cluster radius in pixels
    extent: 512,  // tile extent (radius is calculated relative to it)
    nodeSize: 64, // size of the KD-tree leaf node, affects performance
    log: false,   // whether to log timing info

    // whether to generate numeric ids for input features (in vector tiles)
    generateId: false,

    // a reduce function for calculating custom cluster properties
    reduce: null, // (accumulated, props) => { accumulated.sum += props.sum; }

    // properties to use for individual points when running the reducer
    map: props => props // props => ({sum: props.my_value})
};

const fround = Math.fround || (tmp => ((x) => { tmp[0] = +x; return tmp[0]; }))(new Float32Array(1));

const OFFSET_ZOOM = 2;
const OFFSET_ID = 3;
const OFFSET_PARENT = 4;
const OFFSET_NUM = 5;
const OFFSET_PROP = 6;

class Supercluster {
    constructor(options) {
        this.options = Object.assign(Object.create(defaultOptions), options);
        this.trees = new Array(this.options.maxZoom + 1);
        this.stride = this.options.reduce ? 7 : 6;
        this.clusterProps = [];
    }

    load(points) {
        const {log, minZoom, maxZoom} = this.options;

        if (log) console.time('total time');

        const timerId = `prepare ${  points.length  } points`;
        if (log) console.time(timerId);

        this.points = points;

        // generate a cluster object for each point and index input points into a KD-tree
        const data = [];

        for (let i = 0; i < points.length; i++) {
            const p = points[i];
            if (!p.geometry) continue;

            const [lng, lat] = p.geometry.coordinates;
            const x = fround(lngX(lng));
            const y = fround(latY(lat));
            // store internal point/cluster data in flat numeric arrays for performance
            data.push(
                x, y, // projected point coordinates
                Infinity, // the last zoom the point was processed at
                i, // index of the source feature in the original input array
                -1, // parent cluster id
                1 // number of points in a cluster
            );
            if (this.options.reduce) data.push(0); // noop
        }
        let tree = this.trees[maxZoom + 1] = this._createTree(data);

        if (log) console.timeEnd(timerId);

        // cluster points on max zoom, then cluster the results on previous zoom, etc.;
        // results in a cluster hierarchy across zoom levels
        for (let z = maxZoom; z >= minZoom; z--) {
            const now = +Date.now();

            // create a new set of clusters for the zoom and index them with a KD-tree
            tree = this.trees[z] = this._createTree(this._cluster(tree, z));

            if (log) console.log('z%d: %d clusters in %dms', z, tree.numItems, +Date.now() - now);
        }

        if (log) console.timeEnd('total time');

        return this;
    }

    getClusters(bbox, zoom) {
        let minLng = ((bbox[0] + 180) % 360 + 360) % 360 - 180;
        const minLat = Math.max(-90, Math.min(90, bbox[1]));
        let maxLng = bbox[2] === 180 ? 180 : ((bbox[2] + 180) % 360 + 360) % 360 - 180;
        const maxLat = Math.max(-90, Math.min(90, bbox[3]));

        if (bbox[2] - bbox[0] >= 360) {
            minLng = -180;
            maxLng = 180;
        } else if (minLng > maxLng) {
            const easternHem = this.getClusters([minLng, minLat, 180, maxLat], zoom);
            const westernHem = this.getClusters([-180, minLat, maxLng, maxLat], zoom);
            return easternHem.concat(westernHem);
        }

        const tree = this.trees[this._limitZoom(zoom)];
        const ids = tree.range(lngX(minLng), latY(maxLat), lngX(maxLng), latY(minLat));
        const data = tree.data;
        const clusters = [];
        for (const id of ids) {
            const k = this.stride * id;
            clusters.push(data[k + OFFSET_NUM] > 1 ? getClusterJSON(data, k, this.clusterProps) : this.points[data[k + OFFSET_ID]]);
        }
        return clusters;
    }

    getChildren(clusterId) {
        const originId = this._getOriginId(clusterId);
        const originZoom = this._getOriginZoom(clusterId);
        const errorMsg = 'No cluster with the specified id.';

        const tree = this.trees[originZoom];
        if (!tree) throw new Error(errorMsg);

        const data = tree.data;
        if (originId * this.stride >= data.length) throw new Error(errorMsg);

        const r = this.options.radius / (this.options.extent * Math.pow(2, originZoom - 1));
        const x = data[originId * this.stride];
        const y = data[originId * this.stride + 1];
        const ids = tree.within(x, y, r);
        const children = [];
        for (const id of ids) {
            const k = id * this.stride;
            if (data[k + OFFSET_PARENT] === clusterId) {
                children.push(data[k + OFFSET_NUM] > 1 ? getClusterJSON(data, k, this.clusterProps) : this.points[data[k + OFFSET_ID]]);
            }
        }

        if (children.length === 0) throw new Error(errorMsg);

        return children;
    }

    getLeaves(clusterId, limit, offset) {
        limit = limit || 10;
        offset = offset || 0;

        const leaves = [];
        this._appendLeaves(leaves, clusterId, limit, offset, 0);

        return leaves;
    }

    getTile(z, x, y) {
        const tree = this.trees[this._limitZoom(z)];
        const z2 = Math.pow(2, z);
        const {extent, radius} = this.options;
        const p = radius / extent;
        const top = (y - p) / z2;
        const bottom = (y + 1 + p) / z2;

        const tile = {
            features: []
        };

        this._addTileFeatures(
            tree.range((x - p) / z2, top, (x + 1 + p) / z2, bottom),
            tree.data, x, y, z2, tile);

        if (x === 0) {
            this._addTileFeatures(
                tree.range(1 - p / z2, top, 1, bottom),
                tree.data, z2, y, z2, tile);
        }
        if (x === z2 - 1) {
            this._addTileFeatures(
                tree.range(0, top, p / z2, bottom),
                tree.data, -1, y, z2, tile);
        }

        return tile.features.length ? tile : null;
    }

    getClusterExpansionZoom(clusterId) {
        let expansionZoom = this._getOriginZoom(clusterId) - 1;
        while (expansionZoom <= this.options.maxZoom) {
            const children = this.getChildren(clusterId);
            expansionZoom++;
            if (children.length !== 1) break;
            clusterId = children[0].properties.cluster_id;
        }
        return expansionZoom;
    }

    _appendLeaves(result, clusterId, limit, offset, skipped) {
        const children = this.getChildren(clusterId);

        for (const child of children) {
            const props = child.properties;

            if (props && props.cluster) {
                if (skipped + props.point_count <= offset) {
                    // skip the whole cluster
                    skipped += props.point_count;
                } else {
                    // enter the cluster
                    skipped = this._appendLeaves(result, props.cluster_id, limit, offset, skipped);
                    // exit the cluster
                }
            } else if (skipped < offset) {
                // skip a single point
                skipped++;
            } else {
                // add a single point
                result.push(child);
            }
            if (result.length === limit) break;
        }

        return skipped;
    }

    _createTree(data) {
        const tree = new index.KDBush(data.length / this.stride | 0, this.options.nodeSize, Float32Array);
        for (let i = 0; i < data.length; i += this.stride) tree.add(data[i], data[i + 1]);
        tree.finish();
        tree.data = data;
        return tree;
    }

    _addTileFeatures(ids, data, x, y, z2, tile) {
        for (const i of ids) {
            const k = i * this.stride;
            const isCluster = data[k + OFFSET_NUM] > 1;

            let tags, px, py;
            if (isCluster) {
                tags = getClusterProperties(data, k, this.clusterProps);
                px = data[k];
                py = data[k + 1];
            } else {
                const p = this.points[data[k + OFFSET_ID]];
                tags = p.properties;
                const [lng, lat] = p.geometry.coordinates;
                px = lngX(lng);
                py = latY(lat);
            }

            const f = {
                type: 1,
                geometry: [[
                    Math.round(this.options.extent * (px * z2 - x)),
                    Math.round(this.options.extent * (py * z2 - y))
                ]],
                tags
            };

            // assign id
            let id;
            if (isCluster || this.options.generateId) {
                // optionally generate id for points
                id = data[k + OFFSET_ID];
            } else {
                // keep id if already assigned
                id = this.points[data[k + OFFSET_ID]].id;
            }

            if (id !== undefined) f.id = id;

            tile.features.push(f);
        }
    }

    _limitZoom(z) {
        return Math.max(this.options.minZoom, Math.min(Math.floor(+z), this.options.maxZoom + 1));
    }

    _cluster(tree, zoom) {
        const {radius, extent, reduce, minPoints} = this.options;
        const r = radius / (extent * Math.pow(2, zoom));
        const data = tree.data;
        const nextData = [];
        const stride = this.stride;

        // loop through each point
        for (let i = 0; i < data.length; i += stride) {
            // if we've already visited the point at this zoom level, skip it
            if (data[i + OFFSET_ZOOM] <= zoom) continue;
            data[i + OFFSET_ZOOM] = zoom;

            // find all nearby points
            const x = data[i];
            const y = data[i + 1];
            const neighborIds = tree.within(data[i], data[i + 1], r);

            const numPointsOrigin = data[i + OFFSET_NUM];
            let numPoints = numPointsOrigin;

            // count the number of points in a potential cluster
            for (const neighborId of neighborIds) {
                const k = neighborId * stride;
                // filter out neighbors that are already processed
                if (data[k + OFFSET_ZOOM] > zoom) numPoints += data[k + OFFSET_NUM];
            }

            // if there were neighbors to merge, and there are enough points to form a cluster
            if (numPoints > numPointsOrigin && numPoints >= minPoints) {
                let wx = x * numPointsOrigin;
                let wy = y * numPointsOrigin;

                let clusterProperties;
                let clusterPropIndex = -1;

                // encode both zoom and point index on which the cluster originated -- offset by total length of features
                const id = ((i / stride | 0) << 5) + (zoom + 1) + this.points.length;

                for (const neighborId of neighborIds) {
                    const k = neighborId * stride;

                    if (data[k + OFFSET_ZOOM] <= zoom) continue;
                    data[k + OFFSET_ZOOM] = zoom; // save the zoom (so it doesn't get processed twice)

                    const numPoints2 = data[k + OFFSET_NUM];
                    wx += data[k] * numPoints2; // accumulate coordinates for calculating weighted center
                    wy += data[k + 1] * numPoints2;

                    data[k + OFFSET_PARENT] = id;

                    if (reduce) {
                        if (!clusterProperties) {
                            clusterProperties = this._map(data, i, true);
                            clusterPropIndex = this.clusterProps.length;
                            this.clusterProps.push(clusterProperties);
                        }
                        reduce(clusterProperties, this._map(data, k));
                    }
                }

                data[i + OFFSET_PARENT] = id;
                nextData.push(wx / numPoints, wy / numPoints, Infinity, id, -1, numPoints);
                if (reduce) nextData.push(clusterPropIndex);

            } else { // left points as unclustered
                for (let j = 0; j < stride; j++) nextData.push(data[i + j]);

                if (numPoints > 1) {
                    for (const neighborId of neighborIds) {
                        const k = neighborId * stride;
                        if (data[k + OFFSET_ZOOM] <= zoom) continue;
                        data[k + OFFSET_ZOOM] = zoom;
                        for (let j = 0; j < stride; j++) nextData.push(data[k + j]);
                    }
                }
            }
        }

        return nextData;
    }

    // get index of the point from which the cluster originated
    _getOriginId(clusterId) {
        return (clusterId - this.points.length) >> 5;
    }

    // get zoom of the point from which the cluster originated
    _getOriginZoom(clusterId) {
        return (clusterId - this.points.length) % 32;
    }

    _map(data, i, clone) {
        if (data[i + OFFSET_NUM] > 1) {
            const props = this.clusterProps[data[i + OFFSET_PROP]];
            return clone ? Object.assign({}, props) : props;
        }
        const original = this.points[data[i + OFFSET_ID]].properties;
        const result = this.options.map(original);
        return clone && result === original ? Object.assign({}, result) : result;
    }
}

function getClusterJSON(data, i, clusterProps) {
    return {
        type: 'Feature',
        id: data[i + OFFSET_ID],
        properties: getClusterProperties(data, i, clusterProps),
        geometry: {
            type: 'Point',
            coordinates: [xLng(data[i]), yLat(data[i + 1])]
        }
    };
}

function getClusterProperties(data, i, clusterProps) {
    const count = data[i + OFFSET_NUM];
    const abbrev =
        count >= 10000 ? `${Math.round(count / 1000)  }k` :
        count >= 1000 ? `${Math.round(count / 100) / 10  }k` : count;
    const propIndex = data[i + OFFSET_PROP];
    const properties = propIndex === -1 ? {} : Object.assign({}, clusterProps[propIndex]);
    return Object.assign(properties, {
        cluster: true,
        cluster_id: data[i + OFFSET_ID],
        point_count: count,
        point_count_abbreviated: abbrev
    });
}

// longitude/latitude to spherical mercator in [0..1] range
function lngX(lng) {
    return lng / 360 + 0.5;
}
function latY(lat) {
    const sin = Math.sin(lat * Math.PI / 180);
    const y = (0.5 - 0.25 * Math.log((1 + sin) / (1 - sin)) / Math.PI);
    return y < 0 ? 0 : y > 1 ? 1 : y;
}

// spherical mercator to longitude/latitude
function xLng(x) {
    return (x - 0.5) * 360;
}
function yLat(y) {
    const y2 = (180 - y * 360) * Math.PI / 180;
    return 360 * Math.atan(Math.exp(y2)) / Math.PI - 90;
}

// calculate simplification data using optimized Douglas-Peucker algorithm

function simplify(coords, first, last, sqTolerance) {
    var maxSqDist = sqTolerance;
    var mid = (last - first) >> 1;
    var minPosToMid = last - first;
    var index;

    var ax = coords[first];
    var ay = coords[first + 1];
    var bx = coords[last];
    var by = coords[last + 1];

    for (var i = first + 3; i < last; i += 3) {
        var d = getSqSegDist(coords[i], coords[i + 1], ax, ay, bx, by);

        if (d > maxSqDist) {
            index = i;
            maxSqDist = d;

        } else if (d === maxSqDist) {
            // a workaround to ensure we choose a pivot close to the middle of the list,
            // reducing recursion depth, for certain degenerate inputs
            // https://github.com/mapbox/geojson-vt/issues/104
            var posToMid = Math.abs(i - mid);
            if (posToMid < minPosToMid) {
                index = i;
                minPosToMid = posToMid;
            }
        }
    }

    if (maxSqDist > sqTolerance) {
        if (index - first > 3) simplify(coords, first, index, sqTolerance);
        coords[index + 2] = maxSqDist;
        if (last - index > 3) simplify(coords, index, last, sqTolerance);
    }
}

// square distance from a point to a segment
function getSqSegDist(px, py, x, y, bx, by) {

    var dx = bx - x;
    var dy = by - y;

    if (dx !== 0 || dy !== 0) {

        var t = ((px - x) * dx + (py - y) * dy) / (dx * dx + dy * dy);

        if (t > 1) {
            x = bx;
            y = by;

        } else if (t > 0) {
            x += dx * t;
            y += dy * t;
        }
    }

    dx = px - x;
    dy = py - y;

    return dx * dx + dy * dy;
}

function createFeature(id, type, geom, tags) {
    var feature = {
        id: typeof id === 'undefined' ? null : id,
        type: type,
        geometry: geom,
        tags: tags,
        minX: Infinity,
        minY: Infinity,
        maxX: -Infinity,
        maxY: -Infinity
    };
    calcBBox(feature);
    return feature;
}

function calcBBox(feature) {
    var geom = feature.geometry;
    var type = feature.type;

    if (type === 'Point' || type === 'MultiPoint' || type === 'LineString') {
        calcLineBBox(feature, geom);

    } else if (type === 'Polygon' || type === 'MultiLineString') {
        for (var i = 0; i < geom.length; i++) {
            calcLineBBox(feature, geom[i]);
        }

    } else if (type === 'MultiPolygon') {
        for (i = 0; i < geom.length; i++) {
            for (var j = 0; j < geom[i].length; j++) {
                calcLineBBox(feature, geom[i][j]);
            }
        }
    }
}

function calcLineBBox(feature, geom) {
    for (var i = 0; i < geom.length; i += 3) {
        feature.minX = Math.min(feature.minX, geom[i]);
        feature.minY = Math.min(feature.minY, geom[i + 1]);
        feature.maxX = Math.max(feature.maxX, geom[i]);
        feature.maxY = Math.max(feature.maxY, geom[i + 1]);
    }
}

// converts GeoJSON feature into an intermediate projected JSON vector format with simplification data

function convert(data, options) {
    var features = [];
    if (data.type === 'FeatureCollection') {
        for (var i = 0; i < data.features.length; i++) {
            convertFeature(features, data.features[i], options, i);
        }

    } else if (data.type === 'Feature') {
        convertFeature(features, data, options);

    } else {
        // single geometry or a geometry collection
        convertFeature(features, {geometry: data}, options);
    }

    return features;
}

function convertFeature(features, geojson, options, index) {
    if (!geojson.geometry) return;

    var coords = geojson.geometry.coordinates;
    var type = geojson.geometry.type;
    var tolerance = Math.pow(options.tolerance / ((1 << options.maxZoom) * options.extent), 2);
    var geometry = [];
    var id = geojson.id;
    if (options.promoteId) {
        id = geojson.properties[options.promoteId];
    } else if (options.generateId) {
        id = index || 0;
    }
    if (type === 'Point') {
        convertPoint(coords, geometry);

    } else if (type === 'MultiPoint') {
        for (var i = 0; i < coords.length; i++) {
            convertPoint(coords[i], geometry);
        }

    } else if (type === 'LineString') {
        convertLine(coords, geometry, tolerance, false);

    } else if (type === 'MultiLineString') {
        if (options.lineMetrics) {
            // explode into linestrings to be able to track metrics
            for (i = 0; i < coords.length; i++) {
                geometry = [];
                convertLine(coords[i], geometry, tolerance, false);
                features.push(createFeature(id, 'LineString', geometry, geojson.properties));
            }
            return;
        } else {
            convertLines(coords, geometry, tolerance, false);
        }

    } else if (type === 'Polygon') {
        convertLines(coords, geometry, tolerance, true);

    } else if (type === 'MultiPolygon') {
        for (i = 0; i < coords.length; i++) {
            var polygon = [];
            convertLines(coords[i], polygon, tolerance, true);
            geometry.push(polygon);
        }
    } else if (type === 'GeometryCollection') {
        for (i = 0; i < geojson.geometry.geometries.length; i++) {
            convertFeature(features, {
                id: id,
                geometry: geojson.geometry.geometries[i],
                properties: geojson.properties
            }, options, index);
        }
        return;
    } else {
        throw new Error('Input data is not a valid GeoJSON object.');
    }

    features.push(createFeature(id, type, geometry, geojson.properties));
}

function convertPoint(coords, out) {
    out.push(projectX(coords[0]));
    out.push(projectY(coords[1]));
    out.push(0);
}

function convertLine(ring, out, tolerance, isPolygon) {
    var x0, y0;
    var size = 0;

    for (var j = 0; j < ring.length; j++) {
        var x = projectX(ring[j][0]);
        var y = projectY(ring[j][1]);

        out.push(x);
        out.push(y);
        out.push(0);

        if (j > 0) {
            if (isPolygon) {
                size += (x0 * y - x * y0) / 2; // area
            } else {
                size += Math.sqrt(Math.pow(x - x0, 2) + Math.pow(y - y0, 2)); // length
            }
        }
        x0 = x;
        y0 = y;
    }

    var last = out.length - 3;
    out[2] = 1;
    simplify(out, 0, last, tolerance);
    out[last + 2] = 1;

    out.size = Math.abs(size);
    out.start = 0;
    out.end = out.size;
}

function convertLines(rings, out, tolerance, isPolygon) {
    for (var i = 0; i < rings.length; i++) {
        var geom = [];
        convertLine(rings[i], geom, tolerance, isPolygon);
        out.push(geom);
    }
}

function projectX(x) {
    return x / 360 + 0.5;
}

function projectY(y) {
    var sin = Math.sin(y * Math.PI / 180);
    var y2 = 0.5 - 0.25 * Math.log((1 + sin) / (1 - sin)) / Math.PI;
    return y2 < 0 ? 0 : y2 > 1 ? 1 : y2;
}

/* clip features between two axis-parallel lines:
 *     |        |
 *  ___|___     |     /
 * /   |   \____|____/
 *     |        |
 */

function clip(features, scale, k1, k2, axis, minAll, maxAll, options) {

    k1 /= scale;
    k2 /= scale;

    if (minAll >= k1 && maxAll < k2) return features; // trivial accept
    else if (maxAll < k1 || minAll >= k2) return null; // trivial reject

    var clipped = [];

    for (var i = 0; i < features.length; i++) {

        var feature = features[i];
        var geometry = feature.geometry;
        var type = feature.type;

        var min = axis === 0 ? feature.minX : feature.minY;
        var max = axis === 0 ? feature.maxX : feature.maxY;

        if (min >= k1 && max < k2) { // trivial accept
            clipped.push(feature);
            continue;
        } else if (max < k1 || min >= k2) { // trivial reject
            continue;
        }

        var newGeometry = [];

        if (type === 'Point' || type === 'MultiPoint') {
            clipPoints(geometry, newGeometry, k1, k2, axis);

        } else if (type === 'LineString') {
            clipLine(geometry, newGeometry, k1, k2, axis, false, options.lineMetrics);

        } else if (type === 'MultiLineString') {
            clipLines(geometry, newGeometry, k1, k2, axis, false);

        } else if (type === 'Polygon') {
            clipLines(geometry, newGeometry, k1, k2, axis, true);

        } else if (type === 'MultiPolygon') {
            for (var j = 0; j < geometry.length; j++) {
                var polygon = [];
                clipLines(geometry[j], polygon, k1, k2, axis, true);
                if (polygon.length) {
                    newGeometry.push(polygon);
                }
            }
        }

        if (newGeometry.length) {
            if (options.lineMetrics && type === 'LineString') {
                for (j = 0; j < newGeometry.length; j++) {
                    clipped.push(createFeature(feature.id, type, newGeometry[j], feature.tags));
                }
                continue;
            }

            if (type === 'LineString' || type === 'MultiLineString') {
                if (newGeometry.length === 1) {
                    type = 'LineString';
                    newGeometry = newGeometry[0];
                } else {
                    type = 'MultiLineString';
                }
            }
            if (type === 'Point' || type === 'MultiPoint') {
                type = newGeometry.length === 3 ? 'Point' : 'MultiPoint';
            }

            clipped.push(createFeature(feature.id, type, newGeometry, feature.tags));
        }
    }

    return clipped.length ? clipped : null;
}

function clipPoints(geom, newGeom, k1, k2, axis) {
    for (var i = 0; i < geom.length; i += 3) {
        var a = geom[i + axis];

        if (a >= k1 && a <= k2) {
            newGeom.push(geom[i]);
            newGeom.push(geom[i + 1]);
            newGeom.push(geom[i + 2]);
        }
    }
}

function clipLine(geom, newGeom, k1, k2, axis, isPolygon, trackMetrics) {

    var slice = newSlice(geom);
    var intersect = axis === 0 ? intersectX : intersectY;
    var len = geom.start;
    var segLen, t;

    for (var i = 0; i < geom.length - 3; i += 3) {
        var ax = geom[i];
        var ay = geom[i + 1];
        var az = geom[i + 2];
        var bx = geom[i + 3];
        var by = geom[i + 4];
        var a = axis === 0 ? ax : ay;
        var b = axis === 0 ? bx : by;
        var exited = false;

        if (trackMetrics) segLen = Math.sqrt(Math.pow(ax - bx, 2) + Math.pow(ay - by, 2));

        if (a < k1) {
            // ---|-->  | (line enters the clip region from the left)
            if (b > k1) {
                t = intersect(slice, ax, ay, bx, by, k1);
                if (trackMetrics) slice.start = len + segLen * t;
            }
        } else if (a > k2) {
            // |  <--|--- (line enters the clip region from the right)
            if (b < k2) {
                t = intersect(slice, ax, ay, bx, by, k2);
                if (trackMetrics) slice.start = len + segLen * t;
            }
        } else {
            addPoint(slice, ax, ay, az);
        }
        if (b < k1 && a >= k1) {
            // <--|---  | or <--|-----|--- (line exits the clip region on the left)
            t = intersect(slice, ax, ay, bx, by, k1);
            exited = true;
        }
        if (b > k2 && a <= k2) {
            // |  ---|--> or ---|-----|--> (line exits the clip region on the right)
            t = intersect(slice, ax, ay, bx, by, k2);
            exited = true;
        }

        if (!isPolygon && exited) {
            if (trackMetrics) slice.end = len + segLen * t;
            newGeom.push(slice);
            slice = newSlice(geom);
        }

        if (trackMetrics) len += segLen;
    }

    // add the last point
    var last = geom.length - 3;
    ax = geom[last];
    ay = geom[last + 1];
    az = geom[last + 2];
    a = axis === 0 ? ax : ay;
    if (a >= k1 && a <= k2) addPoint(slice, ax, ay, az);

    // close the polygon if its endpoints are not the same after clipping
    last = slice.length - 3;
    if (isPolygon && last >= 3 && (slice[last] !== slice[0] || slice[last + 1] !== slice[1])) {
        addPoint(slice, slice[0], slice[1], slice[2]);
    }

    // add the final slice
    if (slice.length) {
        newGeom.push(slice);
    }
}

function newSlice(line) {
    var slice = [];
    slice.size = line.size;
    slice.start = line.start;
    slice.end = line.end;
    return slice;
}

function clipLines(geom, newGeom, k1, k2, axis, isPolygon) {
    for (var i = 0; i < geom.length; i++) {
        clipLine(geom[i], newGeom, k1, k2, axis, isPolygon, false);
    }
}

function addPoint(out, x, y, z) {
    out.push(x);
    out.push(y);
    out.push(z);
}

function intersectX(out, ax, ay, bx, by, x) {
    var t = (x - ax) / (bx - ax);
    out.push(x);
    out.push(ay + (by - ay) * t);
    out.push(1);
    return t;
}

function intersectY(out, ax, ay, bx, by, y) {
    var t = (y - ay) / (by - ay);
    out.push(ax + (bx - ax) * t);
    out.push(y);
    out.push(1);
    return t;
}

function wrap(features, options) {
    var buffer = options.buffer / options.extent;
    var merged = features;
    var left  = clip(features, 1, -1 - buffer, buffer,     0, -1, 2, options); // left world copy
    var right = clip(features, 1,  1 - buffer, 2 + buffer, 0, -1, 2, options); // right world copy

    if (left || right) {
        merged = clip(features, 1, -buffer, 1 + buffer, 0, -1, 2, options) || []; // center world copy

        if (left) merged = shiftFeatureCoords(left, 1).concat(merged); // merge left into center
        if (right) merged = merged.concat(shiftFeatureCoords(right, -1)); // merge right into center
    }

    return merged;
}

function shiftFeatureCoords(features, offset) {
    var newFeatures = [];

    for (var i = 0; i < features.length; i++) {
        var feature = features[i],
            type = feature.type;

        var newGeometry;

        if (type === 'Point' || type === 'MultiPoint' || type === 'LineString') {
            newGeometry = shiftCoords(feature.geometry, offset);

        } else if (type === 'MultiLineString' || type === 'Polygon') {
            newGeometry = [];
            for (var j = 0; j < feature.geometry.length; j++) {
                newGeometry.push(shiftCoords(feature.geometry[j], offset));
            }
        } else if (type === 'MultiPolygon') {
            newGeometry = [];
            for (j = 0; j < feature.geometry.length; j++) {
                var newPolygon = [];
                for (var k = 0; k < feature.geometry[j].length; k++) {
                    newPolygon.push(shiftCoords(feature.geometry[j][k], offset));
                }
                newGeometry.push(newPolygon);
            }
        }

        newFeatures.push(createFeature(feature.id, type, newGeometry, feature.tags));
    }

    return newFeatures;
}

function shiftCoords(points, offset) {
    var newPoints = [];
    newPoints.size = points.size;

    if (points.start !== undefined) {
        newPoints.start = points.start;
        newPoints.end = points.end;
    }

    for (var i = 0; i < points.length; i += 3) {
        newPoints.push(points[i] + offset, points[i + 1], points[i + 2]);
    }
    return newPoints;
}

// Transforms the coordinates of each feature in the given tile from
// mercator-projected space into (extent x extent) tile space.
function transformTile(tile, extent) {
    if (tile.transformed) return tile;

    var z2 = 1 << tile.z,
        tx = tile.x,
        ty = tile.y,
        i, j, k;

    for (i = 0; i < tile.features.length; i++) {
        var feature = tile.features[i],
            geom = feature.geometry,
            type = feature.type;

        feature.geometry = [];

        if (type === 1) {
            for (j = 0; j < geom.length; j += 2) {
                feature.geometry.push(transformPoint(geom[j], geom[j + 1], extent, z2, tx, ty));
            }
        } else {
            for (j = 0; j < geom.length; j++) {
                var ring = [];
                for (k = 0; k < geom[j].length; k += 2) {
                    ring.push(transformPoint(geom[j][k], geom[j][k + 1], extent, z2, tx, ty));
                }
                feature.geometry.push(ring);
            }
        }
    }

    tile.transformed = true;

    return tile;
}

function transformPoint(x, y, extent, z2, tx, ty) {
    return [
        Math.round(extent * (x * z2 - tx)),
        Math.round(extent * (y * z2 - ty))];
}

function createTile(features, z, tx, ty, options) {
    var tolerance = z === options.maxZoom ? 0 : options.tolerance / ((1 << z) * options.extent);
    var tile = {
        features: [],
        numPoints: 0,
        numSimplified: 0,
        numFeatures: 0,
        source: null,
        x: tx,
        y: ty,
        z: z,
        transformed: false,
        minX: 2,
        minY: 1,
        maxX: -1,
        maxY: 0
    };
    for (var i = 0; i < features.length; i++) {
        tile.numFeatures++;
        addFeature(tile, features[i], tolerance, options);

        var minX = features[i].minX;
        var minY = features[i].minY;
        var maxX = features[i].maxX;
        var maxY = features[i].maxY;

        if (minX < tile.minX) tile.minX = minX;
        if (minY < tile.minY) tile.minY = minY;
        if (maxX > tile.maxX) tile.maxX = maxX;
        if (maxY > tile.maxY) tile.maxY = maxY;
    }
    return tile;
}

function addFeature(tile, feature, tolerance, options) {

    var geom = feature.geometry,
        type = feature.type,
        simplified = [];

    if (type === 'Point' || type === 'MultiPoint') {
        for (var i = 0; i < geom.length; i += 3) {
            simplified.push(geom[i]);
            simplified.push(geom[i + 1]);
            tile.numPoints++;
            tile.numSimplified++;
        }

    } else if (type === 'LineString') {
        addLine(simplified, geom, tile, tolerance, false, false);

    } else if (type === 'MultiLineString' || type === 'Polygon') {
        for (i = 0; i < geom.length; i++) {
            addLine(simplified, geom[i], tile, tolerance, type === 'Polygon', i === 0);
        }

    } else if (type === 'MultiPolygon') {

        for (var k = 0; k < geom.length; k++) {
            var polygon = geom[k];
            for (i = 0; i < polygon.length; i++) {
                addLine(simplified, polygon[i], tile, tolerance, true, i === 0);
            }
        }
    }

    if (simplified.length) {
        var tags = feature.tags || null;
        if (type === 'LineString' && options.lineMetrics) {
            tags = {};
            for (var key in feature.tags) tags[key] = feature.tags[key];
            tags['mapbox_clip_start'] = geom.start / geom.size;
            tags['mapbox_clip_end'] = geom.end / geom.size;
        }
        var tileFeature = {
            geometry: simplified,
            type: type === 'Polygon' || type === 'MultiPolygon' ? 3 :
                type === 'LineString' || type === 'MultiLineString' ? 2 : 1,
            tags: tags
        };
        if (feature.id !== null) {
            tileFeature.id = feature.id;
        }
        tile.features.push(tileFeature);
    }
}

function addLine(result, geom, tile, tolerance, isPolygon, isOuter) {
    var sqTolerance = tolerance * tolerance;

    if (tolerance > 0 && (geom.size < (isPolygon ? sqTolerance : tolerance))) {
        tile.numPoints += geom.length / 3;
        return;
    }

    var ring = [];

    for (var i = 0; i < geom.length; i += 3) {
        if (tolerance === 0 || geom[i + 2] > sqTolerance) {
            tile.numSimplified++;
            ring.push(geom[i]);
            ring.push(geom[i + 1]);
        }
        tile.numPoints++;
    }

    if (isPolygon) rewind(ring, isOuter);

    result.push(ring);
}

function rewind(ring, clockwise) {
    var area = 0;
    for (var i = 0, len = ring.length, j = len - 2; i < len; j = i, i += 2) {
        area += (ring[i] - ring[j]) * (ring[i + 1] + ring[j + 1]);
    }
    if (area > 0 === clockwise) {
        for (i = 0, len = ring.length; i < len / 2; i += 2) {
            var x = ring[i];
            var y = ring[i + 1];
            ring[i] = ring[len - 2 - i];
            ring[i + 1] = ring[len - 1 - i];
            ring[len - 2 - i] = x;
            ring[len - 1 - i] = y;
        }
    }
}

function geojsonvt(data, options) {
    return new GeoJSONVT(data, options);
}

function GeoJSONVT(data, options) {
    options = this.options = extend(Object.create(this.options), options);

    var debug = options.debug;

    if (debug) console.time('preprocess data');

    if (options.maxZoom < 0 || options.maxZoom > 24) throw new Error('maxZoom should be in the 0-24 range');
    if (options.promoteId && options.generateId) throw new Error('promoteId and generateId cannot be used together.');

    var features = convert(data, options);

    this.tiles = {};
    this.tileCoords = [];

    if (debug) {
        console.timeEnd('preprocess data');
        console.log('index: maxZoom: %d, maxPoints: %d', options.indexMaxZoom, options.indexMaxPoints);
        console.time('generate tiles');
        this.stats = {};
        this.total = 0;
    }

    features = wrap(features, options);

    // start slicing from the top tile down
    if (features.length) this.splitTile(features, 0, 0, 0);

    if (debug) {
        if (features.length) console.log('features: %d, points: %d', this.tiles[0].numFeatures, this.tiles[0].numPoints);
        console.timeEnd('generate tiles');
        console.log('tiles generated:', this.total, JSON.stringify(this.stats));
    }
}

GeoJSONVT.prototype.options = {
    maxZoom: 14,            // max zoom to preserve detail on
    indexMaxZoom: 5,        // max zoom in the tile index
    indexMaxPoints: 100000, // max number of points per tile in the tile index
    tolerance: 3,           // simplification tolerance (higher means simpler)
    extent: 4096,           // tile extent
    buffer: 64,             // tile buffer on each side
    lineMetrics: false,     // whether to calculate line metrics
    promoteId: null,        // name of a feature property to be promoted to feature.id
    generateId: false,      // whether to generate feature ids. Cannot be used with promoteId
    debug: 0                // logging level (0, 1 or 2)
};

GeoJSONVT.prototype.splitTile = function (features, z, x, y, cz, cx, cy) {

    var stack = [features, z, x, y],
        options = this.options,
        debug = options.debug;

    // avoid recursion by using a processing queue
    while (stack.length) {
        y = stack.pop();
        x = stack.pop();
        z = stack.pop();
        features = stack.pop();

        var z2 = 1 << z,
            id = toID(z, x, y),
            tile = this.tiles[id];

        if (!tile) {
            if (debug > 1) console.time('creation');

            tile = this.tiles[id] = createTile(features, z, x, y, options);
            this.tileCoords.push({z: z, x: x, y: y});

            if (debug) {
                if (debug > 1) {
                    console.log('tile z%d-%d-%d (features: %d, points: %d, simplified: %d)',
                        z, x, y, tile.numFeatures, tile.numPoints, tile.numSimplified);
                    console.timeEnd('creation');
                }
                var key = 'z' + z;
                this.stats[key] = (this.stats[key] || 0) + 1;
                this.total++;
            }
        }

        // save reference to original geometry in tile so that we can drill down later if we stop now
        tile.source = features;

        // if it's the first-pass tiling
        if (!cz) {
            // stop tiling if we reached max zoom, or if the tile is too simple
            if (z === options.indexMaxZoom || tile.numPoints <= options.indexMaxPoints) continue;

        // if a drilldown to a specific tile
        } else {
            // stop tiling if we reached base zoom or our target tile zoom
            if (z === options.maxZoom || z === cz) continue;

            // stop tiling if it's not an ancestor of the target tile
            var m = 1 << (cz - z);
            if (x !== Math.floor(cx / m) || y !== Math.floor(cy / m)) continue;
        }

        // if we slice further down, no need to keep source geometry
        tile.source = null;

        if (features.length === 0) continue;

        if (debug > 1) console.time('clipping');

        // values we'll use for clipping
        var k1 = 0.5 * options.buffer / options.extent,
            k2 = 0.5 - k1,
            k3 = 0.5 + k1,
            k4 = 1 + k1,
            tl, bl, tr, br, left, right;

        tl = bl = tr = br = null;

        left  = clip(features, z2, x - k1, x + k3, 0, tile.minX, tile.maxX, options);
        right = clip(features, z2, x + k2, x + k4, 0, tile.minX, tile.maxX, options);
        features = null;

        if (left) {
            tl = clip(left, z2, y - k1, y + k3, 1, tile.minY, tile.maxY, options);
            bl = clip(left, z2, y + k2, y + k4, 1, tile.minY, tile.maxY, options);
            left = null;
        }

        if (right) {
            tr = clip(right, z2, y - k1, y + k3, 1, tile.minY, tile.maxY, options);
            br = clip(right, z2, y + k2, y + k4, 1, tile.minY, tile.maxY, options);
            right = null;
        }

        if (debug > 1) console.timeEnd('clipping');

        stack.push(tl || [], z + 1, x * 2,     y * 2);
        stack.push(bl || [], z + 1, x * 2,     y * 2 + 1);
        stack.push(tr || [], z + 1, x * 2 + 1, y * 2);
        stack.push(br || [], z + 1, x * 2 + 1, y * 2 + 1);
    }
};

GeoJSONVT.prototype.getTile = function (z, x, y) {
    var options = this.options,
        extent = options.extent,
        debug = options.debug;

    if (z < 0 || z > 24) return null;

    var z2 = 1 << z;
    x = ((x % z2) + z2) % z2; // wrap tile x coordinate

    var id = toID(z, x, y);
    if (this.tiles[id]) return transformTile(this.tiles[id], extent);

    if (debug > 1) console.log('drilling down to z%d-%d-%d', z, x, y);

    var z0 = z,
        x0 = x,
        y0 = y,
        parent;

    while (!parent && z0 > 0) {
        z0--;
        x0 = Math.floor(x0 / 2);
        y0 = Math.floor(y0 / 2);
        parent = this.tiles[toID(z0, x0, y0)];
    }

    if (!parent || !parent.source) return null;

    // if we found a parent tile containing the original geometry, we can drill down from it
    if (debug > 1) console.log('found parent tile z%d-%d-%d', z0, x0, y0);

    if (debug > 1) console.time('drilling down');
    this.splitTile(parent.source, z0, x0, y0, z, x, y);
    if (debug > 1) console.timeEnd('drilling down');

    return this.tiles[id] ? transformTile(this.tiles[id], extent) : null;
};

function toID(z, x, y) {
    return (((1 << z) * y + x) * 32) + z;
}

function extend(dest, src) {
    for (var i in src) dest[i] = src[i];
    return dest;
}

//      


             
                            
                         
                       
                                    

                                          
                                                                 

                                                                           
                                                                         
                                                   
                                                          

                                    
                   
                     
                                 
                              
                               
                         
  

                                                            
                                
                 
  

                                                                                                      

                               
                                                     

                           
                                                       
                                                          
                                                                                       
 

// $FlowFixMe[missing-this-annot]
function loadGeoJSONTile(params                         , callback                        ) {
    const canonical = params.tileID.canonical;

    if (!this._geoJSONIndex) {
        return callback(null, null);  // we couldn't load the file
    }

    const geoJSONTile = this._geoJSONIndex.getTile(canonical.z, canonical.x, canonical.y);
    if (!geoJSONTile) {
        return callback(null, null); // nothing in the given tile
    }

    const geojsonWrapper = new GeoJSONWrapper$2(geoJSONTile.features);

    // Encode the geojson-vt tile into binary vector tile form.  This
    // is a convenience that allows `FeatureIndex` to operate the same way
    // across `VectorTileSource` and `GeoJSONSource` data.
    let pbf = vtpbf(geojsonWrapper);
    if (pbf.byteOffset !== 0 || pbf.byteLength !== pbf.buffer.byteLength) {
        // Compatibility with node Buffer (https://github.com/mapbox/pbf/issues/35)
        pbf = new Uint8Array(pbf);
    }

    callback(null, {
        vectorTile: geojsonWrapper,
        rawData: pbf.buffer
    });
}

/**
 * The {@link WorkerSource} implementation that supports {@link GeoJSONSource}.
 * This class is designed to be easily reused to support custom source types
 * for data formats that can be parsed/converted into an in-memory GeoJSON
 * representation.  To do so, create it with
 * `new GeoJSONWorkerSource(actor, layerIndex, customLoadGeoJSONFunction)`.
 * For a full example, see [mapbox-gl-topojson](https://github.com/developmentseed/mapbox-gl-topojson).
 *
 * @private
 */
class GeoJSONWorkerSource extends index.VectorTileWorkerSource {
                             
                               

    /**
     * @param [loadGeoJSON] Optional method for custom loading/parsing of
     * GeoJSON based on parameters passed from the main-thread Source.
     * See {@link GeoJSONWorkerSource#loadGeoJSON}.
     * @private
     */
    constructor(actor       , layerIndex                 , availableImages               , isSpriteLoaded         , loadGeoJSON              ) {
        super(actor, layerIndex, availableImages, isSpriteLoaded, loadGeoJSONTile);
        if (loadGeoJSON) {
            this.loadGeoJSON = loadGeoJSON;
        }
    }

    /**
     * Fetches (if appropriate), parses, and index geojson data into tiles. This
     * preparatory method must be called before {@link GeoJSONWorkerSource#loadTile}
     * can correctly serve up tiles.
     *
     * Defers to {@link GeoJSONWorkerSource#loadGeoJSON} for the fetching/parsing,
     * expecting `callback(error, data)` to be called with either an error or a
     * parsed GeoJSON object.
     *
     * When `loadData` requests come in faster than they can be processed,
     * they are coalesced into a single request using the latest data.
     * See {@link GeoJSONWorkerSource#coalesce}
     *
     * @param params
     * @param callback
     * @private
     */
    loadData(params                       , callback                                                                              ) {
        const requestParam = params && params.request;
        const perf = requestParam && requestParam.collectResourceTiming;

        this.loadGeoJSON(params, (err        , data         ) => {
            if (err || !data) {
                return callback(err);
            } else if (typeof data !== 'object') {
                return callback(new Error(`Input data given to '${params.source}' is not a valid GeoJSON object.`));
            } else {
                rewind$2(data, true);

                try {
                    if (params.filter) {
                        const compiled = index.createExpression(params.filter, {type: 'boolean', 'property-type': 'data-driven', overridable: false, transition: false});
                        if (compiled.result === 'error')
                            throw new Error(compiled.value.map(err => `${err.key}: ${err.message}`).join(', '));

                        const features = data.features.filter(feature => compiled.value.evaluate({zoom: 0}, feature));
                        data = {type: 'FeatureCollection', features};
                    }

                    this._geoJSONIndex = params.cluster ?
                        new Supercluster(getSuperclusterOptions(params)).load(data.features) :
                        geojsonvt(data, params.geojsonVtOptions);
                } catch (err) {
                    return callback(err);
                }

                this.loaded = {};

                const result = {};
                if (perf) {
                    const resourceTimingData = index.getPerformanceMeasurement(requestParam);
                    // it's necessary to eval the result of getEntriesByName() here via parse/stringify
                    // late evaluation in the main thread causes TypeError: illegal invocation
                    if (resourceTimingData) {
                        result.resourceTiming = {};
                        result.resourceTiming[params.source] = JSON.parse(JSON.stringify(resourceTimingData));
                    }
                }
                callback(null, result);
            }
        });
    }

    /**
    * Implements {@link WorkerSource#reloadTile}.
    *
    * If the tile is loaded, uses the implementation in VectorTileWorkerSource.
    * Otherwise, such as after a setData() call, we load the tile fresh.
    *
    * @param params
    * @param params.uid The UID for this tile.
    * @private
    */
    reloadTile(params                      , callback                    )       {
        const loaded = this.loaded,
            uid = params.uid;

        if (loaded && loaded[uid]) {
            return super.reloadTile(params, callback);
        } else {
            return this.loadTile(params, callback);
        }
    }

    /**
     * Fetch and parse GeoJSON according to the given params.  Calls `callback`
     * with `(err, data)`, where `data` is a parsed GeoJSON object.
     *
     * GeoJSON is loaded and parsed from `params.url` if it exists, or else
     * expected as a literal (string or object) `params.data`.
     *
     * @param params
     * @param [params.url] A URL to the remote GeoJSON data.
     * @param [params.data] Literal GeoJSON data. Must be provided if `params.url` is not.
     * @private
     */
    // $FlowFixMe[duplicate-class-member]
    loadGeoJSON(params                       , callback                          )       {
        // Because of same origin issues, urls must either include an explicit
        // origin or absolute path.
        // ie: /foo/bar.json or http://example.com/bar.json
        // but not ../foo/bar.json
        if (params.request) {
            index.getJSON(params.request, callback);
        } else if (typeof params.data === 'string') {
            try {
                return callback(null, JSON.parse(params.data));
            } catch (e) {
                return callback(new Error(`Input data given to '${params.source}' is not a valid GeoJSON object.`));
            }
        } else {
            return callback(new Error(`Input data given to '${params.source}' is not a valid GeoJSON object.`));
        }
    }

    getClusterExpansionZoom(params                     , callback                  ) {
        try {
            callback(null, this._geoJSONIndex.getClusterExpansionZoom(params.clusterId));
        } catch (e) {
            callback(e);
        }
    }

    getClusterChildren(params                     , callback                                 ) {
        try {
            callback(null, this._geoJSONIndex.getChildren(params.clusterId));
        } catch (e) {
            callback(e);
        }
    }

    getClusterLeaves(params                                                    , callback                                 ) {
        try {
            callback(null, this._geoJSONIndex.getLeaves(params.clusterId, params.limit, params.offset));
        } catch (e) {
            callback(e);
        }
    }
}

function getSuperclusterOptions({superclusterOptions, clusterProperties}                       ) {
    if (!clusterProperties || !superclusterOptions) return superclusterOptions;

    const mapExpressions = {};
    const reduceExpressions = {};
    const globals = {accumulated: null, zoom: 0};
    const feature = {properties: null};
    const propertyNames = Object.keys(clusterProperties);

    for (const key of propertyNames) {
        const [operator, mapExpression] = clusterProperties[key];

        const mapExpressionParsed = index.createExpression(mapExpression);
        const reduceExpressionParsed = index.createExpression(
            typeof operator === 'string' ? [operator, ['accumulated'], ['get', key]] : operator);

        index.assert(mapExpressionParsed.result === 'success');
        index.assert(reduceExpressionParsed.result === 'success');

        mapExpressions[key] = mapExpressionParsed.value;
        reduceExpressions[key] = reduceExpressionParsed.value;
    }

    superclusterOptions.map = (pointProperties) => {
        feature.properties = pointProperties;
        const properties = {};
        for (const key of propertyNames) {
            properties[key] = mapExpressions[key].evaluate(globals, feature);
        }
        return properties;
    };
    superclusterOptions.reduce = (accumulated, clusterProperties) => {
        feature.properties = clusterProperties;
        for (const key of propertyNames) {
            globals.accumulated = accumulated[key];
            accumulated[key] = reduceExpressions[key].evaluate(globals, feature);
        }
    };

    return superclusterOptions;
}

//      


             
                 
                         
                            
                       
                          
                  
                                    

                                                                      
                                                   
                                                                                        
                                                      
                                                              

/**
 * @private
 */
class Worker {
                                     
                 
                                                  
                                                   
                                                           
                                                                                
                                                                                
                                            
                                  
                                            
                      
                      

    constructor(self                            ) {
        index.PerformanceUtils.measure('workerEvaluateScript');
        this.self = self;
        this.actor = new index.Actor(self, this);

        this.layerIndexes = {};
        this.availableImages = {};
        this.isSpriteLoaded = {};

        this.projections = {};
        this.defaultProjection = index.getProjection({name: 'mercator'});

        this.workerSourceTypes = {
            vector: index.VectorTileWorkerSource,
            geojson: GeoJSONWorkerSource
        };

        // [mapId][sourceType][sourceName] => worker source instance
        this.workerSources = {};
        this.demWorkerSources = {};

        this.self.registerWorkerSource = (name        , WorkerSource                     ) => {
            if (this.workerSourceTypes[name]) {
                throw new Error(`Worker source with name "${name}" already registered.`);
            }
            this.workerSourceTypes[name] = WorkerSource;
        };

        // This is invoked by the RTL text plugin when the download via the `importScripts` call has finished, and the code has been parsed.
        this.self.registerRTLTextPlugin = (rtlTextPlugin                                                                                                               ) => {
            if (index.plugin.isParsed()) {
                throw new Error('RTL text plugin already registered.');
            }
            index.plugin['applyArabicShaping'] = rtlTextPlugin.applyArabicShaping;
            index.plugin['processBidirectionalText'] = rtlTextPlugin.processBidirectionalText;
            index.plugin['processStyledBidirectionalText'] = rtlTextPlugin.processStyledBidirectionalText;
        };
    }

    clearCaches(mapId        , unused       , callback                    ) {
        delete this.layerIndexes[mapId];
        delete this.availableImages[mapId];
        delete this.workerSources[mapId];
        delete this.demWorkerSources[mapId];
        callback();
    }

    checkIfReady(mapID        , unused       , callback                    ) {
        // noop, used to check if a worker is fully set up and ready to receive messages
        callback();
    }

    setReferrer(mapID        , referrer        ) {
        this.referrer = referrer;
    }

    spriteLoaded(mapId        , bool         ) {
        this.isSpriteLoaded[mapId] = bool;
        for (const workerSource in this.workerSources[mapId]) {
            const ws = this.workerSources[mapId][workerSource];
            for (const source in ws) {
                if (ws[source] instanceof index.VectorTileWorkerSource) {
                    ws[source].isSpriteLoaded = bool;
                    ws[source].fire(new index.Event('isSpriteLoaded'));
                }
            }
        }
    }

    setImages(mapId        , images               , callback                    ) {
        this.availableImages[mapId] = images;
        for (const workerSource in this.workerSources[mapId]) {
            const ws = this.workerSources[mapId][workerSource];
            for (const source in ws) {
                ws[source].availableImages = images;
            }
        }
        callback();
    }

    enableTerrain(mapId        , enable         , callback                    ) {
        this.terrain = enable;
        callback();
    }

    setProjection(mapId        , config                         ) {
        this.projections[mapId] = index.getProjection(config);
    }

    setLayers(mapId        , layers                           , callback                    ) {
        this.getLayerIndex(mapId).replace(layers);
        callback();
    }

    updateLayers(mapId        , params                                                                , callback                    ) {
        this.getLayerIndex(mapId).update(params.layers, params.removedIds);
        callback();
    }

    loadTile(mapId        , params                                       , callback                    ) {
        index.assert(params.type);
        // $FlowFixMe[method-unbinding]
        const p = this.enableTerrain ? index.extend({enableTerrain: this.terrain}, params) : params;
        p.projection = this.projections[mapId] || this.defaultProjection;
        this.getWorkerSource(mapId, params.type, params.source).loadTile(p, callback);
    }

    loadDEMTile(mapId        , params                         , callback                       ) {
        // $FlowFixMe[method-unbinding]
        const p = this.enableTerrain ? index.extend({buildQuadTree: this.terrain}, params) : params;
        this.getDEMWorkerSource(mapId, params.source).loadTile(p, callback);
    }

    reloadTile(mapId        , params                                       , callback                    ) {
        index.assert(params.type);
        // $FlowFixMe[method-unbinding]
        const p = this.enableTerrain ? index.extend({enableTerrain: this.terrain}, params) : params;
        p.projection = this.projections[mapId] || this.defaultProjection;
        this.getWorkerSource(mapId, params.type, params.source).reloadTile(p, callback);
    }

    abortTile(mapId        , params                                 , callback                    ) {
        index.assert(params.type);
        this.getWorkerSource(mapId, params.type, params.source).abortTile(params, callback);
    }

    removeTile(mapId        , params                                 , callback                    ) {
        index.assert(params.type);
        this.getWorkerSource(mapId, params.type, params.source).removeTile(params, callback);
    }

    removeSource(mapId        , params                                   , callback                    ) {
        index.assert(params.type);
        index.assert(params.source);

        if (!this.workerSources[mapId] ||
            !this.workerSources[mapId][params.type] ||
            !this.workerSources[mapId][params.type][params.source]) {
            return;
        }

        const worker = this.workerSources[mapId][params.type][params.source];
        delete this.workerSources[mapId][params.type][params.source];

        if (worker.removeSource !== undefined) {
            worker.removeSource(params, callback);
        } else {
            callback();
        }
    }

    /**
     * Load a {@link WorkerSource} script at params.url.  The script is run
     * (using importScripts) with `registerWorkerSource` in scope, which is a
     * function taking `(name, workerSourceObject)`.
     *  @private
     */
    loadWorkerSource(map        , params                 , callback                ) {
        try {
            this.self.importScripts(params.url);
            callback();
        } catch (e) {
            callback(e.toString());
        }
    }

    syncRTLPluginState(map        , state             , callback                   ) {
        try {
            index.plugin.setState(state);
            const pluginURL = index.plugin.getPluginURL();
            if (
                index.plugin.isLoaded() &&
                !index.plugin.isParsed() &&
                pluginURL != null // Not possible when `isLoaded` is true, but keeps flow happy
            ) {
                this.self.importScripts(pluginURL);
                const complete = index.plugin.isParsed();
                const error = complete ? undefined : new Error(`RTL Text Plugin failed to import scripts from ${pluginURL}`);
                callback(error, complete);
            }
        } catch (e) {
            callback(e.toString());
        }
    }

    getAvailableImages(mapId        )                {
        let availableImages = this.availableImages[mapId];

        if (!availableImages) {
            availableImages = [];
        }

        return availableImages;
    }

    getLayerIndex(mapId        )                  {
        let layerIndexes = this.layerIndexes[mapId];
        if (!layerIndexes) {
            layerIndexes = this.layerIndexes[mapId] = new StyleLayerIndex();
        }
        return layerIndexes;
    }

    getWorkerSource(mapId        , type        , source        )               {
        if (!this.workerSources[mapId])
            this.workerSources[mapId] = {};
        if (!this.workerSources[mapId][type])
            this.workerSources[mapId][type] = {};

        if (!this.workerSources[mapId][type][source]) {
            // use a wrapped actor so that we can attach a target mapId param
            // to any messages invoked by the WorkerSource
            const actor = {
                send: (type        , data       , callback     , _     , mustQueue         , metadata     ) => {
                    this.actor.send(type, data, callback, mapId, mustQueue, metadata);
                },
                scheduler: this.actor.scheduler
            };
            this.workerSources[mapId][type][source] = new (this.workerSourceTypes[type]     )((actor     ), this.getLayerIndex(mapId), this.getAvailableImages(mapId), this.isSpriteLoaded[mapId]);
        }

        return this.workerSources[mapId][type][source];
    }

    getDEMWorkerSource(mapId        , source        )                            {
        if (!this.demWorkerSources[mapId])
            this.demWorkerSources[mapId] = {};

        if (!this.demWorkerSources[mapId][source]) {
            this.demWorkerSources[mapId][source] = new RasterDEMTileWorkerSource();
        }

        return this.demWorkerSources[mapId][source];
    }

    enforceCacheSizeLimit(mapId        , limit        ) {
        index.enforceCacheSizeLimit(limit);
    }

    getWorkerPerformanceMetrics(mapId        , params     , callback                                          ) {
        callback(undefined, index.PerformanceUtils.getWorkerPerformanceMetrics());
    }
}

/* global self, WorkerGlobalScope */
if (typeof WorkerGlobalScope !== 'undefined' &&
    typeof self !== 'undefined' &&
    self instanceof WorkerGlobalScope) {
    // $FlowFixMe[prop-missing]
    self.worker = new Worker(self);
}

return Worker;

}));

define(['./shared'], (function (index) { 'use strict';

var mapboxGlSupported = {};

'use strict';

var supported = mapboxGlSupported.supported = isSupported;
var notSupportedReason_1 = mapboxGlSupported.notSupportedReason = notSupportedReason;

/**
 * Test whether the current browser supports Mapbox GL JS
 * @param {Object} options
 * @param {boolean} [options.failIfMajorPerformanceCaveat=false] Return `false`
 *   if the performance of Mapbox GL JS would be dramatically worse than
 *   expected (i.e. a software renderer is would be used)
 * @return {boolean}
 */
function isSupported(options) {
    return !notSupportedReason(options);
}

function notSupportedReason(options) {
    if (!isBrowser()) return 'not a browser';
    if (!isArraySupported()) return 'insufficent Array support';
    if (!isFunctionSupported()) return 'insufficient Function support';
    if (!isObjectSupported()) return 'insufficient Object support';
    if (!isJSONSupported()) return 'insufficient JSON support';
    if (!isWorkerSupported()) return 'insufficient worker support';
    if (!isUint8ClampedArraySupported()) return 'insufficient Uint8ClampedArray support';
    if (!isArrayBufferSupported()) return 'insufficient ArrayBuffer support';
    if (!isCanvasGetImageDataSupported()) return 'insufficient Canvas/getImageData support';
    if (!isWebGLSupportedCached(options && options.failIfMajorPerformanceCaveat)) return 'insufficient WebGL support';
    if (!isNotIE()) return 'insufficient ECMAScript 6 support';
}

function isBrowser() {
    return typeof window !== 'undefined' && typeof document !== 'undefined';
}

function isArraySupported() {
    return (
        Array.prototype &&
        Array.prototype.every &&
        Array.prototype.filter &&
        Array.prototype.forEach &&
        Array.prototype.indexOf &&
        Array.prototype.lastIndexOf &&
        Array.prototype.map &&
        Array.prototype.some &&
        Array.prototype.reduce &&
        Array.prototype.reduceRight &&
        Array.isArray
    );
}

function isFunctionSupported() {
    return Function.prototype && Function.prototype.bind;
}

function isObjectSupported() {
    return (
        Object.keys &&
        Object.create &&
        Object.getPrototypeOf &&
        Object.getOwnPropertyNames &&
        Object.isSealed &&
        Object.isFrozen &&
        Object.isExtensible &&
        Object.getOwnPropertyDescriptor &&
        Object.defineProperty &&
        Object.defineProperties &&
        Object.seal &&
        Object.freeze &&
        Object.preventExtensions
    );
}

function isJSONSupported() {
    return 'JSON' in window && 'parse' in JSON && 'stringify' in JSON;
}

function isWorkerSupported() {
    if (!('Worker' in window && 'Blob' in window && 'URL' in window)) {
        return false;
    }

    var blob = new Blob([''], { type: 'text/javascript' });
    var workerURL = URL.createObjectURL(blob);
    var supported;
    var worker;

    try {
        worker = new Worker(workerURL);
        supported = true;
    } catch (e) {
        supported = false;
    }

    if (worker) {
        worker.terminate();
    }
    URL.revokeObjectURL(workerURL);

    return supported;
}

// IE11 only supports `Uint8ClampedArray` as of version
// [KB2929437](https://support.microsoft.com/en-us/kb/2929437)
function isUint8ClampedArraySupported() {
    return 'Uint8ClampedArray' in window;
}

// https://github.com/mapbox/mapbox-gl-supported/issues/19
function isArrayBufferSupported() {
    return ArrayBuffer.isView;
}

// Some browsers or browser extensions block access to canvas data to prevent fingerprinting.
// Mapbox GL uses this API to load sprites and images in general.
function isCanvasGetImageDataSupported() {
    var canvas = document.createElement('canvas');
    canvas.width = canvas.height = 1;
    var context = canvas.getContext('2d');
    if (!context) {
        return false;
    }
    var imageData = context.getImageData(0, 0, 1, 1);
    return imageData && imageData.width === canvas.width;
}

var isWebGLSupportedCache = {};
function isWebGLSupportedCached(failIfMajorPerformanceCaveat) {

    if (isWebGLSupportedCache[failIfMajorPerformanceCaveat] === undefined) {
        isWebGLSupportedCache[failIfMajorPerformanceCaveat] = isWebGLSupported(failIfMajorPerformanceCaveat);
    }

    return isWebGLSupportedCache[failIfMajorPerformanceCaveat];
}

isSupported.webGLContextAttributes = {
    antialias: false,
    alpha: true,
    stencil: true,
    depth: true
};

function getWebGLContext(failIfMajorPerformanceCaveat) {
    var canvas = document.createElement('canvas');

    var attributes = Object.create(isSupported.webGLContextAttributes);
    attributes.failIfMajorPerformanceCaveat = failIfMajorPerformanceCaveat;

    return (
        canvas.getContext('webgl', attributes) ||
        canvas.getContext('experimental-webgl', attributes)
    );
}

function isWebGLSupported(failIfMajorPerformanceCaveat) {
    var gl = getWebGLContext(failIfMajorPerformanceCaveat);
    if (!gl) {
        return false;
    }

    // Try compiling a shader and get its compile status. Some browsers like Brave block this API
    // to prevent fingerprinting. Unfortunately, this also means that Mapbox GL won't work.
    var shader;
    try {
        shader = gl.createShader(gl.VERTEX_SHADER);
    } catch (e) {
        // some older browsers throw an exception that `createShader` is not defined
        // so handle this separately from the case where browsers block `createShader`
        // for security reasons
        return false;
    }

    if (!shader || gl.isContextLost()) {
        return false;
    }
    gl.shaderSource(shader, 'void main() {}');
    gl.compileShader(shader);
    return gl.getShaderParameter(shader, gl.COMPILE_STATUS) === true;
}

function isNotIE() {
    return !document.documentMode;
}

//       strict


// refine the return type based on tagName, e.g. 'button' -> HTMLButtonElement
// $FlowFixMe[method-unbinding]
function create$1           (tagName   , className         , container              )                                          {
    const el = index.window.document.createElement(tagName);
    if (className !== undefined) el.className = className;
    if (container) container.appendChild(el);
    return el;
}

function createSVG(tagName        , attributes                             , container          )          {
    const el = index.window.document.createElementNS('http://www.w3.org/2000/svg', tagName);
    for (const name of Object.keys(attributes)) {
        el.setAttributeNS(null, name, attributes[name]);
    }
    if (container) container.appendChild(el);
    return el;
}

const docStyle = index.window.document && index.window.document.documentElement.style;
const selectProp = docStyle && docStyle.userSelect !== undefined ? 'userSelect' : 'WebkitUserSelect';
let userSelect;

function disableDrag() {
    if (docStyle && selectProp) {
        userSelect = docStyle[selectProp];
        docStyle[selectProp] = 'none';
    }
}

function enableDrag() {
    if (docStyle && selectProp) {
        docStyle[selectProp] = userSelect;
    }
}

// Suppress the next click, but only if it's immediate.
function suppressClickListener(e       ) {
    e.preventDefault();
    e.stopPropagation();
    index.window.removeEventListener('click', suppressClickListener, true);
}

function suppressClick() {
    index.window.addEventListener('click', suppressClickListener, true);
    index.window.setTimeout(() => {
        index.window.removeEventListener('click', suppressClickListener, true);
    }, 0);
}

function mousePos(el             , e                         )        {
    const rect = el.getBoundingClientRect();
    return getScaledPoint(el, rect, e);
}

function touchPos(el             , touches           )               {
    const rect = el.getBoundingClientRect(),
        points = [];

    for (let i = 0; i < touches.length; i++) {
        points.push(getScaledPoint(el, rect, touches[i]));
    }
    return points;
}

function mouseButton(e            )         {
    index.assert(e.type === 'mousedown' || e.type === 'mouseup');
    if (typeof index.window.InstallTrigger !== 'undefined' && e.button === 2 && e.ctrlKey &&
        index.window.navigator.platform.toUpperCase().indexOf('MAC') >= 0) {
        // Fix for https://github.com/mapbox/mapbox-gl-js/issues/3131:
        // Firefox (detected by InstallTrigger) on Mac determines e.button = 2 when
        // using Control + left click
        return 0;
    }
    return e.button;
}

function getScaledPoint(el             , rect            , e                                 ) {
    // Until we get support for pointer events (https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent)
    // we use this dirty trick which would not work for the case of rotated transforms, but works well for
    // the case of simple scaling.
    // Note: `el.offsetWidth === rect.width` eliminates the `0/0` case.
    const scaling = el.offsetWidth === rect.width ? 1 : el.offsetWidth / rect.width;
    return new index.Point(
        (e.clientX - rect.left) * scaling,
        (e.clientY - rect.top) * scaling
    );
}

//      


                                                 
                                                      
                                                   
                                                       

function loadSprite(baseURL        ,
                          requestManager                ,
                          callback                                     )             {
    let json     , image, error;
    const format = index.exported.devicePixelRatio > 1 ? '@2x' : '';

    let jsonRequest              = index.getJSON(requestManager.transformRequest(requestManager.normalizeSpriteURL(baseURL, format, '.json'), index.ResourceType.SpriteJSON), (err        , data         ) => {
        jsonRequest = null;
        if (!error) {
            error = err;
            json = data;
            maybeComplete();
        }
    });

    let imageRequest              = index.getImage(requestManager.transformRequest(requestManager.normalizeSpriteURL(baseURL, format, '.png'), index.ResourceType.SpriteImage), (err, img) => {
        imageRequest = null;
        if (!error) {
            error = err;
            image = img;
            maybeComplete();
        }
    });

    function maybeComplete() {
        if (error) {
            callback(error);
        } else if (json && image) {
            const imageData = index.exported.getImageData(image);
            const result = {};

            for (const id in json) {
                const {width, height, x, y, sdf, pixelRatio, stretchX, stretchY, content} = json[id];
                const data = new index.RGBAImage({width, height});
                index.RGBAImage.copy(imageData, data, {x, y}, {x: 0, y: 0}, {width, height});
                result[id] = {data, pixelRatio, sdf, stretchX, stretchY, content};
            }

            callback(null, result);
        }
    }

    return {
        cancel() {
            if (jsonRequest) {
                jsonRequest.cancel();
                jsonRequest = null;
            }
            if (imageRequest) {
                imageRequest.cancel();
                imageRequest = null;
            }
        }
    };
}

//      


                                    

                              
                    
                    
                                
                                   
  

                                  
                       
                 
                                       
                                       
                                              
  

                                                             

                                   
                  
                   
                                         
                           
                                           
                         
  

function renderStyleImage(image            )          {
    const {userImage} = image;
    if (userImage && userImage.render) {
        const updated = userImage.render();
        if (updated) {
            image.data.replace(new Uint8Array(userImage.data.buffer));
            return true;
        }
    }
    return false;
}

/**
 * Interface for dynamically generated style images. This is a specification for
 * implementers to model: it is not an exported method or class.
 *
 * Images implementing this interface can be redrawn for every frame. They can be used to animate
 * icons and patterns or make them respond to user input. Style images can implement a
 * {@link StyleImageInterface#render} method. The method is called every frame and
 * can be used to update the image.
 *
 * @interface StyleImageInterface
 * @property {number} width Width in pixels.
 * @property {number} height Height in pixels.
 * @property {Uint8Array | Uint8ClampedArray} data Byte array representing the image. To ensure space for all four channels in an RGBA color, size must be width × height × 4.
 *
 * @see [Example: Add an animated icon to the map.](https://docs.mapbox.com/mapbox-gl-js/example/add-image-animated/)
 *
 * @example
 * const flashingSquare = {
 *     width: 64,
 *     height: 64,
 *     data: new Uint8Array(64 * 64 * 4),
 *
 *     onAdd(map) {
 *         this.map = map;
 *     },
 *
 *     render() {
 *         // keep repainting while the icon is on the map
 *         this.map.triggerRepaint();
 *
 *         // alternate between black and white based on the time
 *         const value = Math.round(Date.now() / 1000) % 2 === 0  ? 255 : 0;
 *
 *         // check if image needs to be changed
 *         if (value !== this.previousValue) {
 *             this.previousValue = value;
 *
 *             const bytesPerPixel = 4;
 *             for (let x = 0; x < this.width; x++) {
 *                 for (let y = 0; y < this.height; y++) {
 *                     const offset = (y * this.width + x) * bytesPerPixel;
 *                     this.data[offset + 0] = value;
 *                     this.data[offset + 1] = value;
 *                     this.data[offset + 2] = value;
 *                     this.data[offset + 3] = 255;
 *                 }
 *             }
 *
 *             // return true to indicate that the image changed
 *             return true;
 *         }
 *     }
 * };
 *
 * map.addImage('flashing_square', flashingSquare);
 */

/**
 * This method is called once before every frame where the icon will be used.
 * The method can optionally update the image's `data` member with a new image.
 *
 * If the method updates the image it must return `true` to commit the change.
 * If the method returns `false` or nothing the image is assumed to not have changed.
 *
 * If updates are infrequent it maybe easier to use {@link Map#updateImage} to update
 * the image instead of implementing this method.
 *
 * @function
 * @memberof StyleImageInterface
 * @instance
 * @name render
 * @return {boolean} `true` if this method updated the image. `false` if the image was not changed.
 */

/**
 * Optional method called when the layer has been added to the Map with {@link Map#addImage}.
 *
 * @function
 * @memberof StyleImageInterface
 * @instance
 * @name onAdd
 * @param {Map} map The Map this custom layer was just added to.
 */

/**
 * Optional method called when the icon is removed from the map with {@link Map#removeImage}.
 * This gives the image a chance to clean up resources and event listeners.
 *
 * @function
 * @memberof StyleImageInterface
 * @instance
 * @name onRemove
 */

//      


                                                        
                                            
                                 
                                                   
                                           

                
             
                           
  

// When copied into the atlas texture, image data is padded by one pixel on each side. Icon
// images are padded with fully transparent pixels, while pattern images are padded with a
// copy of the image data wrapped from the opposite side. In both cases, this ensures the
// correct behavior of GL_LINEAR texture sampling mode.
const padding = 1;

/*
    ImageManager does three things:

        1. Tracks requests for icon images from tile workers and sends responses when the requests are fulfilled.
        2. Builds a texture atlas for pattern images.
        3. Rerenders renderable images once per frame

    These are disparate responsibilities and should eventually be handled by different classes. When we implement
    data-driven support for `*-pattern`, we'll likely use per-bucket pattern atlases, and that would be a good time
    to refactor this.
*/
class ImageManager extends index.Evented {
                                      
                                          
                                                        
                    
                                                                                           

                                     
                          
                           
                   

    constructor() {
        super();
        this.images = {};
        this.updatedImages = {};
        this.callbackDispatchedThisFrame = {};
        this.loaded = false;
        this.requestors = [];

        this.patterns = {};
        this.atlasImage = new index.RGBAImage({width: 1, height: 1});
        this.dirty = true;
    }

    isLoaded()          {
        return this.loaded;
    }

    setLoaded(loaded         ) {
        if (this.loaded === loaded) {
            return;
        }

        this.loaded = loaded;

        if (loaded) {
            for (const {ids, callback} of this.requestors) {
                this._notify(ids, callback);
            }
            this.requestors = [];
        }
    }

    hasImage(id        )          {
        return !!this.getImage(id);
    }

    getImage(id        )              {
        return this.images[id];
    }

    addImage(id        , image            ) {
        index.assert(!this.images[id]);
        if (this._validate(id, image)) {
            this.images[id] = image;
        }
    }

    _validate(id        , image            )          {
        let valid = true;
        if (!this._validateStretch(image.stretchX, image.data && image.data.width)) {
            this.fire(new index.ErrorEvent(new Error(`Image "${id}" has invalid "stretchX" value`)));
            valid = false;
        }
        if (!this._validateStretch(image.stretchY, image.data && image.data.height)) {
            this.fire(new index.ErrorEvent(new Error(`Image "${id}" has invalid "stretchY" value`)));
            valid = false;
        }
        if (!this._validateContent(image.content, image)) {
            this.fire(new index.ErrorEvent(new Error(`Image "${id}" has invalid "content" value`)));
            valid = false;
        }
        return valid;
    }

    _validateStretch(stretch                                 , size        )          {
        if (!stretch) return true;
        let last = 0;
        for (const part of stretch) {
            if (part[0] < last || part[1] < part[0] || size < part[1]) return false;
            last = part[1];
        }
        return true;
    }

    _validateContent(content                                          , image            )          {
        if (!content) return true;
        if (content.length !== 4) return false;
        if (content[0] < 0 || image.data.width < content[0]) return false;
        if (content[1] < 0 || image.data.height < content[1]) return false;
        if (content[2] < 0 || image.data.width < content[2]) return false;
        if (content[3] < 0 || image.data.height < content[3]) return false;
        if (content[2] < content[0]) return false;
        if (content[3] < content[1]) return false;
        return true;
    }

    updateImage(id        , image            ) {
        const oldImage = this.images[id];
        index.assert(oldImage);
        index.assert(oldImage.data.width === image.data.width);
        index.assert(oldImage.data.height === image.data.height);
        image.version = oldImage.version + 1;
        this.images[id] = image;
        this.updatedImages[id] = true;
    }

    removeImage(id        ) {
        index.assert(this.images[id]);
        const image = this.images[id];
        delete this.images[id];
        delete this.patterns[id];

        if (image.userImage && image.userImage.onRemove) {
            image.userImage.onRemove();
        }
    }

    listImages()                {
        return Object.keys(this.images);
    }

    getImages(ids               , callback                                     ) {
        // If the sprite has been loaded, or if all the icon dependencies are already present
        // (i.e. if they've been added via runtime styling), then notify the requestor immediately.
        // Otherwise, delay notification until the sprite is loaded. At that point, if any of the
        // dependencies are still unavailable, we'll just assume they are permanently missing.
        let hasAllDependencies = true;
        if (!this.isLoaded()) {
            for (const id of ids) {
                if (!this.images[id]) {
                    hasAllDependencies = false;
                }
            }
        }
        if (this.isLoaded() || hasAllDependencies) {
            this._notify(ids, callback);
        } else {
            this.requestors.push({ids, callback});
        }
    }

    _notify(ids               , callback                                     ) {
        const response = {};

        for (const id of ids) {
            if (!this.images[id]) {
                this.fire(new index.Event('styleimagemissing', {id}));
            }
            const image = this.images[id];
            if (image) {
                // Clone the image so that our own copy of its ArrayBuffer doesn't get transferred.
                response[id] = {
                    data: image.data.clone(),
                    pixelRatio: image.pixelRatio,
                    sdf: image.sdf,
                    version: image.version,
                    stretchX: image.stretchX,
                    stretchY: image.stretchY,
                    content: image.content,
                    hasRenderCallback: Boolean(image.userImage && image.userImage.render)
                };
            } else {
                index.warnOnce(`Image "${id}" could not be loaded. Please make sure you have added the image with map.addImage() or a "sprite" property in your style. You can provide missing images by listening for the "styleimagemissing" map event.`);
            }
        }

        callback(null, response);
    }

    // Pattern stuff

    getPixelSize()       {
        const {width, height} = this.atlasImage;
        return {width, height};
    }

    getPattern(id        )                 {
        const pattern = this.patterns[id];

        const image = this.getImage(id);
        if (!image) {
            return null;
        }

        if (pattern && pattern.position.version === image.version) {
            return pattern.position;
        }

        if (!pattern) {
            const w = image.data.width + padding * 2;
            const h = image.data.height + padding * 2;
            const bin = {w, h, x: 0, y: 0};
            const position = new index.ImagePosition(bin, image);
            this.patterns[id] = {bin, position};
        } else {
            pattern.position.version = image.version;
        }

        this._updatePatternAtlas();

        return this.patterns[id].position;
    }

    bind(context         ) {
        const gl = context.gl;
        if (!this.atlasTexture) {
            this.atlasTexture = new index.Texture(context, this.atlasImage, gl.RGBA);
        } else if (this.dirty) {
            this.atlasTexture.update(this.atlasImage);
            this.dirty = false;
        }

        if (!this.atlasTexture) return; // Flow can't infer that atlasTexture is defined here
        this.atlasTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);
    }

    _updatePatternAtlas() {
        const bins = [];
        for (const id in this.patterns) {
            bins.push(this.patterns[id].bin);
        }

        const {w, h} = index.potpack(bins);

        const dst = this.atlasImage;
        dst.resize({width: w || 1, height: h || 1});

        for (const id in this.patterns) {
            const {bin} = this.patterns[id];
            const x = bin.x + padding;
            const y = bin.y + padding;
            const src = this.images[id].data;
            const w = src.width;
            const h = src.height;

            index.RGBAImage.copy(src, dst, {x: 0, y: 0}, {x, y}, {width: w, height: h});

            // Add 1 pixel wrapped padding on each side of the image.
            index.RGBAImage.copy(src, dst, {x: 0, y: h - 1}, {x, y: y - 1}, {width: w, height: 1}); // T
            index.RGBAImage.copy(src, dst, {x: 0, y:     0}, {x, y: y + h}, {width: w, height: 1}); // B
            index.RGBAImage.copy(src, dst, {x: w - 1, y: 0}, {x: x - 1, y}, {width: 1, height: h}); // L
            index.RGBAImage.copy(src, dst, {x: 0,     y: 0}, {x: x + w, y}, {width: 1, height: h}); // R
        }

        this.dirty = true;
    }

    beginFrame() {
        this.callbackDispatchedThisFrame = {};
    }

    dispatchRenderCallbacks(ids               ) {
        for (const id of ids) {

            // the callback for the image was already dispatched for a different frame
            if (this.callbackDispatchedThisFrame[id]) continue;
            this.callbackDispatchedThisFrame[id] = true;

            const image = this.images[id];
            index.assert(image);

            const updated = renderStyleImage(image);
            if (updated) {
                this.updateImage(id, image);
            }
        }
    }
}

//      


                                                                            
                                                                   
                                                          
             
             
                  
                        
                         

                                                               

                             
              
              
              
                      
                  
  

/**
 * Converts spherical coordinates to cartesian LightPosition coordinates.
 *
 * @private
 * @param spherical Spherical coordinates, in [radial, azimuthal, polar]
 * @return LightPosition cartesian coordinates
 */
function sphericalToCartesian([r, azimuthal, polar]                          )                {
    // We abstract "north"/"up" (compass-wise) to be 0° when really this is 90° (π/2):
    // correct for that here
    const a = index.degToRad(azimuthal + 90), p = index.degToRad(polar);

    return {
        x: r * Math.cos(a) * Math.sin(p),
        y: r * Math.sin(a) * Math.sin(p),
        z: r * Math.cos(p),
        azimuthal, polar
    };
}

class LightPositionProperty                                                              {
                                              

    constructor() {
        this.specification = index.spec.light.position;
    }

    possiblyEvaluate(value                                                        , parameters                      )                {
        // $FlowFixMe[method-unbinding]
        return sphericalToCartesian(value.expression.evaluate(parameters));
    }

    interpolate(a               , b               , t        )                {
        return {
            x: index.number(a.x, b.x, t),
            y: index.number(a.y, b.y, t),
            z: index.number(a.z, b.z, t),
            azimuthal: index.number(a.azimuthal, b.azimuthal, t),
            polar: index.number(a.polar, b.polar, t),
        };
    }
}

               
                                                       
                                      
                                         
                                              
   

const properties$1                    = new index.Properties({
    "anchor": new index.DataConstantProperty(index.spec.light.anchor),
    "position": new LightPositionProperty(),
    "color": new index.DataConstantProperty(index.spec.light.color),
    "intensity": new index.DataConstantProperty(index.spec.light.intensity),
});

const TRANSITION_SUFFIX$2 = '-transition';

/*
 * Represents the light used to light extruded features.
 */
class Light extends index.Evented {
                                           
                                         
                                         

    constructor(lightOptions                     ) {
        super();
        this._transitionable = new index.Transitionable(properties$1);
        this.setLight(lightOptions);
        this._transitioning = this._transitionable.untransitioned();
    }

    getLight()                     {
        return (this._transitionable.serialize()     );
    }

    setLight(light                     , options                     = {}) {
        if (this._validate(index.validateLight, light, options)) {
            return;
        }

        for (const name in light) {
            const value = light[name];
            if (index.endsWith(name, TRANSITION_SUFFIX$2)) {
                this._transitionable.setTransition(name.slice(0, -TRANSITION_SUFFIX$2.length), value);
            } else {
                this._transitionable.setValue(name, value);
            }
        }
    }

    updateTransitions(parameters                      ) {
        this._transitioning = this._transitionable.transitioned(parameters, this._transitioning);
    }

    hasTransition()          {
        return this._transitioning.hasTransition();
    }

    recalculate(parameters                      ) {
        this.properties = this._transitioning.possiblyEvaluate(parameters);
    }

    _validate(validate          , value       , options                       )          {
        if (options && options.validate === false) {
            return false;
        }

        return index.emitValidationErrors(this, validate.call(index.validateStyle, index.extend({
            value,
            // Workaround for https://github.com/mapbox/mapbox-gl-js/issues/2407
            style: {glyphs: true, sprite: true},
            styleSpec: index.spec
        })));
    }
}

//      


                                                                   
                                                          
                                                                 

               
                                           
                                                 
   

const DrapeRenderMode = {
    deferred: 0,
    elevated: 1
};

const properties                    = new index.Properties({
    "source": new index.DataConstantProperty(index.spec.terrain.source),
    "exaggeration": new index.DataConstantProperty(index.spec.terrain.exaggeration),
});

const TRANSITION_SUFFIX$1 = '-transition';

let Terrain$1 = class Terrain extends index.Evented {
                                           
                                         
                                         
                            

    constructor(terrainOptions                      , drapeRenderMode        ) {
        super();
        this._transitionable = new index.Transitionable(properties);
        this.set(terrainOptions);
        this._transitioning = this._transitionable.untransitioned();
        this.drapeRenderMode = drapeRenderMode;
    }

    get()                       {
        return (this._transitionable.serialize()     );
    }

    set(terrain                      ) {
        for (const name in terrain) {
            const value = terrain[name];
            if (index.endsWith(name, TRANSITION_SUFFIX$1)) {
                this._transitionable.setTransition(name.slice(0, -TRANSITION_SUFFIX$1.length), value);
            } else {
                this._transitionable.setValue(name, value);
            }
        }
    }

    updateTransitions(parameters                      ) {
        this._transitioning = this._transitionable.transitioned(parameters, this._transitioning);
    }

    hasTransition()          {
        return this._transitioning.hasTransition();
    }

    recalculate(parameters                      ) {
        this.properties = this._transitioning.possiblyEvaluate(parameters);
    }
};

//      
                                            
                                                          
                                                 

const FOG_PITCH_START = 45;
const FOG_PITCH_END = 65;
const FOG_SYMBOL_CLIPPING_THRESHOLD = 0.9;

                        
                            
                         
                 
  

// As defined in _prelude_fog.fragment.glsl#fog_opacity
function getFogOpacity(state          , pos               , pitch        , fov        )         {
    const fogPitchOpacity = index.smoothstep(FOG_PITCH_START, FOG_PITCH_END, pitch);
    const [start, end] = getFovAdjustedFogRange(state, fov);

    // The output of this function must match _prelude_fog.fragment.glsl
    // For further details, refer to the implementation in the shader code
    const decay = 6;
    const depth = index.length(pos);
    const fogRange = (depth - start) / (end - start);
    let falloff = 1.0 - Math.min(1, Math.exp(-decay * fogRange));

    falloff *= falloff * falloff;
    falloff = Math.min(1.0, 1.00747 * falloff);

    return falloff * fogPitchOpacity * state.alpha;
}

function getFovAdjustedFogRange(state          , fov        )                   {
    // This function computes a shifted fog range so that the appearance is unchanged
    // when the fov changes. We define range=0 starting at the camera position given
    // the default fov. We avoid starting the fog range at the camera center so that
    // ranges aren't generally negative unless the FOV is modified.
    const shift = 0.5 / Math.tan(fov * 0.5);
    return [state.range[0] + shift, state.range[1] + shift];
}

function getFogOpacityAtTileCoord(state          , x        , y        , z        , tileId                 , transform           )         {
    const mat = transform.calculateFogTileMatrix(tileId);
    const pos = [x, y, z];
    index.transformMat4(pos, pos, mat);

    return getFogOpacity(state, pos, transform.pitch, transform._fov);
}

function getFogOpacityAtLngLat(state          , lngLat        , transform           )         {
    const meters = index.MercatorCoordinate.fromLngLat(lngLat);
    const elevation = transform.elevation ? transform.elevation.getAtPointOrZero(meters) : 0;
    const pos = [meters.x, meters.y, elevation];
    index.transformMat4(pos, pos, transform.mercatorFogMatrix);

    return getFogOpacity(state, pos, transform.pitch, transform._fov);
}

//      


               
                                                    
                                         
                                              
                                               
                                                  
                                                   
   

const fogProperties                    = new index.Properties({
    "range": new index.DataConstantProperty(index.spec.fog.range),
    "color": new index.DataConstantProperty(index.spec.fog.color),
    "high-color": new index.DataConstantProperty(index.spec.fog["high-color"]),
    "space-color": new index.DataConstantProperty(index.spec.fog["space-color"]),
    "horizon-blend": new index.DataConstantProperty(index.spec.fog["horizon-blend"]),
    "star-intensity": new index.DataConstantProperty(index.spec.fog["star-intensity"]),
});

const TRANSITION_SUFFIX = '-transition';

class Fog extends index.Evented {
                                           
                                         
                                         

    // Alternate projections do not yet support fog.
    // Hold on to transform so that we know whether a projection is set.
                          

    constructor(fogOptions                   , transform           ) {
        super();
        this._transitionable = new index.Transitionable(fogProperties);
        this.set(fogOptions);
        this._transitioning = this._transitionable.untransitioned();
        this._transform = transform;
    }

    get state()           {
        const tr = this._transform;
        const isGlobe = tr.projection.name === 'globe';
        const transitionT = index.globeToMercatorTransition(tr.zoom);
        const range = this.properties.get('range');
        const globeFixedFogRange = [0.5, 3];
        return {
            range: isGlobe ? [
                index.number(globeFixedFogRange[0], range[0], transitionT),
                index.number(globeFixedFogRange[1], range[1], transitionT)
            ] : range,
            horizonBlend: this.properties.get('horizon-blend'),
            alpha: this.properties.get('color').a
        };
    }

    get()                   {
        return (this._transitionable.serialize()     );
    }

    set(fog                   , options                     = {}) {
        if (this._validate(index.validateFog, fog, options)) {
            return;
        }

        for (const name of Object.keys(index.spec.fog)) {
            // Fallback to use default style specification when the properties wasn't set
            if (fog && fog[name] === undefined) {
                // $FlowFixMe[prop-missing]
                fog[name] = index.spec.fog[name].default;
            }
        }

        for (const name in fog) {
            const value = fog[name];
            if (index.endsWith(name, TRANSITION_SUFFIX)) {
                this._transitionable.setTransition(name.slice(0, -TRANSITION_SUFFIX.length), value);
            } else {
                this._transitionable.setValue(name, value);
            }
        }
    }

    getOpacity(pitch        )         {
        if (!this._transform.projection.supportsFog) return 0;

        const fogColor = (this.properties && this.properties.get('color')) || 1.0;
        const isGlobe = this._transform.projection.name === 'globe';
        const pitchFactor = isGlobe ? 1.0 : index.smoothstep(FOG_PITCH_START, FOG_PITCH_END, pitch);
        return pitchFactor * fogColor.a;
    }

    getOpacityAtLatLng(lngLat        , transform           )         {
        if (!this._transform.projection.supportsFog) return 0;

        return getFogOpacityAtLngLat(this.state, lngLat, transform);
    }

    getFovAdjustedRange(fov        )                   {
        // We can return any arbitrary range because we expect opacity=0 to clean it up
        if (!this._transform.projection.supportsFog) return [0, 1];

        return getFovAdjustedFogRange(this.state, fov);
    }

    updateTransitions(parameters                      ) {
        this._transitioning = this._transitionable.transitioned(parameters, this._transitioning);
    }

    hasTransition()          {
        return this._transitioning.hasTransition();
    }

    recalculate(parameters                      ) {
        this.properties = this._transitioning.possiblyEvaluate(parameters);
    }

    _validate(validate          , value       , options                       )          {
        if (options && options.validate === false) {
            return false;
        }

        return index.emitValidationErrors(this, validate.call(index.validateStyle, index.extend({
            value,
            style: {glyphs: true, sprite: true},
            styleSpec: index.spec
        })));
    }
}

//      


                                               

/**
 * Responsible for sending messages from a {@link Source} to an associated
 * {@link WorkerSource}.
 *
 * @private
 */
class Dispatcher {
                           
                         
                         
               
                   

    // exposed to allow stubbing in unit tests
                               

    constructor(workerPool            , parent     ) {
        this.workerPool = workerPool;
        this.actors = [];
        this.currentActor = 0;
        this.id = index.uniqueId();
        const workers = this.workerPool.acquire(this.id);
        for (let i = 0; i < workers.length; i++) {
            const worker = workers[i];
            const actor = new Dispatcher.Actor(worker, parent, this.id);
            actor.name = `Worker ${i}`;
            this.actors.push(actor);
        }
        index.assert(this.actors.length);

        // track whether all workers are instantiated and ready to receive messages;
        // used for optimizations on initial map load
        this.ready = false;
        this.broadcast('checkIfReady', null, () => { this.ready = true; });
    }

    /**
     * Broadcast a message to all Workers.
     * @private
     */
    broadcast(type        , data       , cb           ) {
        index.assert(this.actors.length);
        cb = cb || function () {};
        index.asyncAll(this.actors, (actor, done) => {
            actor.send(type, data, done);
        }, cb);
    }

    /**
     * Acquires an actor to dispatch messages to. The actors are distributed in round-robin fashion.
     * @returns {Actor} An actor object backed by a web worker for processing messages.
     */
    getActor()        {
        index.assert(this.actors.length);
        this.currentActor = (this.currentActor + 1) % this.actors.length;
        return this.actors[this.currentActor];
    }

    remove() {
        this.actors.forEach((actor) => { actor.remove(); });
        this.actors = [];
        this.workerPool.release(this.id);
    }
}

Dispatcher.Actor = index.Actor;

//      


                                                   
                                                 
                                                                       

/**
 * Converts a pixel value at a the given zoom level to tile units.
 *
 * The shaders mostly calculate everything in tile units so style
 * properties need to be converted from pixels to tile units using this.
 *
 * For example, a translation by 30 pixels at zoom 6.5 will be a
 * translation by pixelsToTileUnits(30, 6.5) tile units.
 *
 * @returns value in tile units
 * @private
 */
function pixelsToTileUnits(tile                                                        , pixelValue        , z        )         {
    return pixelValue * (index.EXTENT / (tile.tileSize * Math.pow(2, z - tile.tileID.overscaledZ)));
}

function getPixelsToTileUnitsMatrix(tile                                                                                       , transform           )               {
    const {scale} = tile.tileTransform;
    const s = scale * index.EXTENT / (tile.tileSize * Math.pow(2, transform.zoom - tile.tileID.overscaledZ + tile.tileID.canonical.z));
    return index.scale(new Float32Array(4), transform.inverseAdjustmentMatrix, [s, s]);
}

//      


                      
                                                 
                                  

                                                                                           
                       
  

/**
 * A data-class that represents a screenspace query from `Map#queryRenderedFeatures`.
 * All the internal geometries and data are intented to be immutable and read-only.
 * Its lifetime is only for the duration of the query and fixed state of the map while the query is being processed.
 *
 * @class QueryGeometry
 */
class QueryGeometry {
                          
                       
                            
                                          

                                                       
                                                       

                            

    constructor(screenBounds         , cameraPoint       , aboveHorizon         , transform           ) {
        this.screenBounds = screenBounds;
        this.cameraPoint = cameraPoint;
        this._screenRaycastCache = {};
        this._cameraRaycastCache = {};
        this.isAboveHorizon = aboveHorizon;

        this.screenGeometry = this.bufferedScreenGeometry(0);
        this.screenGeometryMercator = this._bufferedScreenMercator(0, transform);
    }

    /**
     * Factory method to help contruct an instance  while accounting for current map state.
     *
     * @static
     * @param {(PointLike | [PointLike, PointLike])} geometry The query geometry.
     * @param {Transform} transform The current map transform.
     * @returns {QueryGeometry} An instance of the QueryGeometry class.
     */
    static createFromScreenPoints(geometry                                    , transform           )                {
        let screenGeometry;
        let aboveHorizon;

        // $FlowFixMe: Flow can't refine that this will be PointLike but we can
        if (geometry instanceof index.Point || typeof geometry[0] === 'number') {
            // $FlowFixMe
            const pt = index.Point.convert(geometry);
            screenGeometry = [pt];
            aboveHorizon = transform.isPointAboveHorizon(pt);
        } else {
            // $FlowFixMe
            const tl = index.Point.convert(geometry[0]);
            // $FlowFixMe
            const br = index.Point.convert(geometry[1]);
            screenGeometry = [tl, br];
            aboveHorizon = index.polygonizeBounds(tl, br).every((p) => transform.isPointAboveHorizon(p));
        }

        return new QueryGeometry(screenGeometry, transform.getCameraPoint(), aboveHorizon, transform);
    }

    /**
     * Returns true if the initial query by the user was a single point.
     *
     * @returns {boolean} Returns `true` if the initial query geometry was a single point.
     */
    isPointQuery()          {
        return this.screenBounds.length === 1;
    }

    /**
     * Due to data-driven styling features do not uniform size(eg `circle-radius`) and can be offset differntly
     * from their original location(for example with `*-translate`). This means we have to expand our query region for
     * each tile to account for variation in these properties.
     * Each tile calculates a tile level max padding value (in screenspace pixels) when its parsed, this function
     * lets us calculate a buffered version of the screenspace query geometry for each tile.
     *
     * @param {number} buffer The tile padding in screenspace pixels.
     * @returns {Point[]} The buffered query geometry.
     */
    bufferedScreenGeometry(buffer        )          {
        return index.polygonizeBounds(
            this.screenBounds[0],
            this.screenBounds.length === 1 ? this.screenBounds[0] : this.screenBounds[1],
            buffer
        );
    }

    /**
     * When the map is pitched, some of the 3D features that intersect a query will not intersect
     * the query at the surface of the earth. Instead the feature may be closer and only intersect
     * the query because it extrudes into the air.
     *
     * This returns a geometry that is a convex polygon that encompasses the query frustum and the point underneath the camera.
     * Similar to `bufferedScreenGeometry`, buffering is added to account for variation in paint properties.
     *
     * Case 1: point underneath camera is exactly behind query volume
     *              +----------+
     *              |          |
     *              |          |
     *              |          |
     *              +          +
     *               X        X
     *                X      X
     *                 X    X
     *                  X  X
     *                   XX.
     *
     * Case 2: point is behind and to the right
     *              +----------+
     *              |          X
     *              |           X
     *              |           XX
     *              +            X
     *              XXX          XX
     *                 XXXX       X
     *                    XXX     XX
     *                        XX   X
     *                           XXX.
     *
     * Case 3: point is behind and to the left
     *              +----------+
     *             X           |
     *             X           |
     *            XX           |
     *            X            +
     *           X          XXXX
     *          XX       XXX
     *          X    XXXX
     *         X XXXX
     *         XXX.
     *
     * @param {number} buffer The tile padding in screenspace pixels.
     * @returns {Point[]} The buffered query geometry.
     */
    bufferedCameraGeometry(buffer        )          {
        const min = this.screenBounds[0];
        const max = this.screenBounds.length === 1 ? this.screenBounds[0].add(new index.Point(1, 1)) : this.screenBounds[1];
        const cameraPolygon = index.polygonizeBounds(min, max, 0, false);

        // Only need to account for point underneath camera if its behind query volume
        if (this.cameraPoint.y > max.y) {
            //case 1: insert point in the middle
            if (this.cameraPoint.x > min.x && this.cameraPoint.x < max.x) {
                cameraPolygon.splice(3, 0, this.cameraPoint);
            //case 2: replace btm right point
            } else if (this.cameraPoint.x >= max.x) {
                cameraPolygon[2] = this.cameraPoint;
            //case 3: replace btm left point
            } else if (this.cameraPoint.x <= min.x) {
                cameraPolygon[3] = this.cameraPoint;
            }
        }

        return index.bufferConvexPolygon(cameraPolygon, buffer);
    }

    // Creates a convex polygon in screen coordinates that encompasses the query frustum and
    // the camera location at globe's surface. Camera point can be at any side of the query polygon as
    // opposed to `bufferedCameraGeometry` which restricts the location to underneath the polygon.
    bufferedCameraGeometryGlobe(buffer        )          {
        const min = this.screenBounds[0];
        const max = this.screenBounds.length === 1 ? this.screenBounds[0].add(new index.Point(1, 1)) : this.screenBounds[1];

        // Padding is added to the query polygon before inclusion of the camera location.
        // Otherwise the buffered (narrow) polygon could penetrate the globe creating a lot of false positives
        const cameraPolygon = index.polygonizeBounds(min, max, buffer);

        const camPos = this.cameraPoint.clone();
        const column = (camPos.x > min.x) + (camPos.x > max.x);
        const row = (camPos.y > min.y) + (camPos.y > max.y);
        const sector = row * 3 + column;

        switch (sector) {
        case 0:     // replace top-left point (closed polygon)
            cameraPolygon[0] = camPos;
            cameraPolygon[4] = camPos.clone();
            break;
        case 1:     // insert point in the middle of top-left and top-right
            cameraPolygon.splice(1, 0, camPos);
            break;
        case 2:     // replace top-right point
            cameraPolygon[1] = camPos;
            break;
        case 3:     // insert point in the middle of top-left and bottom-left
            cameraPolygon.splice(4, 0, camPos);
            break;
        case 5:     // insert point in the middle of top-right and bottom-right
            cameraPolygon.splice(2, 0, camPos);
            break;
        case 6:     // replace bottom-left point
            cameraPolygon[3] = camPos;
            break;
        case 7:     // insert point in the middle of bottom-left and bottom-right
            cameraPolygon.splice(3, 0, camPos);
            break;
        case 8:     // replace bottom-right point
            cameraPolygon[2] = camPos;
            break;
        }

        return cameraPolygon;
    }

    /**
     * Checks if a tile is contained within this query geometry.
     *
     * @param {Tile} tile The tile to check.
     * @param {Transform} transform The current map transform.
     * @param {boolean} use3D A boolean indicating whether to query 3D features.
     * @param {number} cameraWrap A wrap value for offsetting the camera position.
     * @returns {?TilespaceQueryGeometry} Returns `undefined` if the tile does not intersect.
     */
    containsTile(tile      , transform           , use3D         , cameraWrap         = 0)                          {
        // The buffer around the query geometry is applied in screen-space.
        // transform._pixelsPerMercatorPixel is used to compensate any extra scaling applied from the currently active projection.
        // Floating point errors when projecting into tilespace could leave a feature
        // outside the query volume even if it looks like it overlaps visually, a 1px bias value overcomes that.
        const bias = 1;
        const padding = tile.queryPadding / transform._pixelsPerMercatorPixel + bias;

        const cachedQuery = use3D ?
            this._bufferedCameraMercator(padding, transform) :
            this._bufferedScreenMercator(padding, transform);

        let wrap = tile.tileID.wrap + (cachedQuery.unwrapped ? cameraWrap : 0);
        const geometryForTileCheck = cachedQuery.polygon.map((p) => index.getTilePoint(tile.tileTransform, p, wrap));

        if (!index.polygonIntersectsBox(geometryForTileCheck, 0, 0, index.EXTENT, index.EXTENT)) {
            return undefined;
        }

        wrap = tile.tileID.wrap + (this.screenGeometryMercator.unwrapped ? cameraWrap : 0);
        const tilespaceVec3s = this.screenGeometryMercator.polygon.map((p) => index.getTileVec3(tile.tileTransform, p, wrap));
        const tilespaceGeometry = tilespaceVec3s.map((v) => new index.Point(v[0], v[1]));

        const cameraMercator = transform.getFreeCameraOptions().position || new index.MercatorCoordinate(0, 0, 0);
        const tilespaceCameraPosition = index.getTileVec3(tile.tileTransform, cameraMercator, wrap);
        const tilespaceRays = tilespaceVec3s.map((tileVec) => {
            const dir = index.sub(tileVec, tileVec, tilespaceCameraPosition);
            index.normalize(dir, dir);
            return new index.Ray(tilespaceCameraPosition, dir);
        });
        const pixelToTileUnitsFactor = pixelsToTileUnits(tile, 1, transform.zoom) * transform._pixelsPerMercatorPixel;

        return {
            queryGeometry: this,
            tilespaceGeometry,
            tilespaceRays,
            bufferedTilespaceGeometry: geometryForTileCheck,
            bufferedTilespaceBounds: clampBoundsToTileExtents(index.getBounds(geometryForTileCheck)),
            tile,
            tileID: tile.tileID,
            pixelToTileUnitsFactor
        };
    }

    /**
     * These methods add caching on top of the terrain raycasting provided by `Transform#pointCoordinate3d`.
     * Tiles come with different values of padding, however its very likely that multiple tiles share the same value of padding
     * based on the style. In that case we want to reuse the result from a previously computed terrain raycast.
     */

    _bufferedScreenMercator(padding        , transform           )                {
        const key = cacheKey(padding);
        if (this._screenRaycastCache[key]) {
            return this._screenRaycastCache[key];
        } else {
            let poly               ;

            if (transform.projection.name === 'globe') {
                poly = this._projectAndResample(this.bufferedScreenGeometry(padding), transform);
            } else {
                poly = {
                    polygon: this.bufferedScreenGeometry(padding).map((p) => transform.pointCoordinate3D(p)),
                    unwrapped: true
                };
            }

            this._screenRaycastCache[key] = poly;
            return poly;
        }
    }

    _bufferedCameraMercator(padding        , transform           )                {
        const key = cacheKey(padding);
        if (this._cameraRaycastCache[key]) {
            return this._cameraRaycastCache[key];
        } else {
            let poly               ;

            if (transform.projection.name === 'globe') {
                poly = this._projectAndResample(this.bufferedCameraGeometryGlobe(padding), transform);
            } else {
                poly = {
                    polygon: this.bufferedCameraGeometry(padding).map((p) => transform.pointCoordinate3D(p)),
                    unwrapped: true
                };
            }

            this._cameraRaycastCache[key] = poly;
            return poly;
        }
    }

    _projectAndResample(polygon         , transform           )                {
        // Handle a special case where either north or south pole is inside the query polygon
        const polePolygon                 = projectPolygonCoveringPoles(polygon, transform);

        if (polePolygon) {
            return polePolygon;
        }

        // Resample the polygon by adding intermediate points so that straight lines of the shape
        // are correctly projected on the surface of the globe.
        const resampled = unwrapQueryPolygon(resamplePolygon(polygon, transform).map(p => new index.Point(wrap(p.x), p.y)), transform);

        return {
            polygon: resampled.polygon.map(p => new index.MercatorCoordinate(p.x, p.y)),
            unwrapped: resampled.unwrapped
        };
    }
}

// Checks whether the provided polygon is crossing the antimeridian line and unwraps it if necessary.
// The resulting polygon is continuous
function unwrapQueryPolygon(polygon         , tr           )                                         {
    let unwrapped = false;

    // Traverse edges of the polygon and unwrap vertices that are crossing the antimeridian.
    let maxX = -Infinity;
    let startEdge = 0;

    for (let e = 0; e < polygon.length - 1; e++) {
        if (polygon[e].x > maxX) {
            maxX = polygon[e].x;
            startEdge = e;
        }
    }

    for (let i = 0; i < polygon.length - 1; i++) {
        const edge = (startEdge + i) % (polygon.length - 1);
        const a = polygon[edge];
        const b = polygon[edge + 1];

        if (Math.abs(a.x - b.x) > 0.5) {
            // A straight line drawn on the globe can't have longer length than 0.5 on the x-axis
            // without crossing the antimeridian
            if (a.x < b.x) {
                a.x += 1;

                if (edge === 0) {
                    // First and last points are duplicate for closed polygons
                    polygon[polygon.length - 1].x += 1;
                }
            } else {
                b.x += 1;

                if (edge + 1 === polygon.length - 1) {
                    polygon[0].x += 1;
                }
            }

            unwrapped = true;
        }
    }

    const cameraX = index.mercatorXfromLng(tr.center.lng);
    if (unwrapped && cameraX < Math.abs(cameraX - 1)) {
        polygon.forEach(p => { p.x -= 1; });
    }

    return {
        polygon,
        unwrapped
    };
}

// Special function for handling scenarios where one of the poles is inside the query polygon.
// Finding projection of these kind of polygons is more involving as projecting just the corners will
// produce a degenerate (self-intersecting, non-continuous, etc.) polygon in mercator coordinates
function projectPolygonCoveringPoles(polygon         , tr           )                 {
    const matrix = index.multiply([], tr.pixelMatrix, tr.globeMatrix);

    // Transform north and south pole coordinates to the screen to see if they're
    // inside the query polygon
    const northPole = [0, -index.GLOBE_RADIUS, 0, 1];
    const southPole = [0, index.GLOBE_RADIUS, 0, 1];
    const center = [0, 0, 0, 1];

    index.transformMat4$1(northPole, northPole, matrix);
    index.transformMat4$1(southPole, southPole, matrix);
    index.transformMat4$1(center, center, matrix);

    const screenNp = new index.Point(northPole[0] / northPole[3], northPole[1] / northPole[3]);
    const screenSp = new index.Point(southPole[0] / southPole[3], southPole[1] / southPole[3]);
    const containsNp = index.polygonContainsPoint(polygon, screenNp) && northPole[3] < center[3];
    const containsSp = index.polygonContainsPoint(polygon, screenSp) && southPole[3] < center[3];

    if (!containsNp && !containsSp) {
        return null;
    }

    // Project corner points of the polygon and traverse the ring to find the edge that's
    // crossing the zero longitude border.
    const result = findEdgeCrossingAntimeridian(polygon, tr, containsNp ? -1 : 1);

    if (!result) {
        return null;
    }

    // Start constructing the new polygon by resampling edges until the crossing edge
    const {idx, t} = result;
    let partA = idx > 1 ? resamplePolygon(polygon.slice(0, idx), tr) : [];
    let partB = idx < polygon.length ? resamplePolygon(polygon.slice(idx), tr) : [];

    partA = partA.map(p => new index.Point(wrap(p.x), p.y));
    partB = partB.map(p => new index.Point(wrap(p.x), p.y));

    // Resample first section of the ring (up to the edge that crosses the 0-line)
    const resampled = [...partA];

    if (resampled.length === 0) {
        resampled.push(partB[partB.length - 1]);
    }

    // Find location of the crossing by interpolating mercator coordinates.
    // This will produce slightly off result as the crossing edge is not actually
    // linear on the globe.
    const a = resampled[resampled.length - 1];
    const b = partB.length === 0 ? partA[0] : partB[0];
    const intersectionY = index.number(a.y, b.y, t);

    let mid;

    if (containsNp) {
        mid = [
            new index.Point(0, intersectionY),
            new index.Point(0, 0),
            new index.Point(1, 0),
            new index.Point(1, intersectionY)
        ];
    } else {
        mid = [
            new index.Point(1, intersectionY),
            new index.Point(1, 1),
            new index.Point(0, 1),
            new index.Point(0, intersectionY)
        ];
    }

    resampled.push(...mid);

    // Resample to the second section of the ring
    if (partB.length === 0) {
        resampled.push(partA[0]);
    } else {
        resampled.push(...partB);
    }

    return {
        polygon: resampled.map(p => new index.MercatorCoordinate(p.x, p.y)),
        unwrapped: false
    };
}

function resamplePolygon(polygon         , transform           )          {
    // Choose a tolerance value for the resampling logic that produces sufficiently
    // accurate polygons without creating too many points. The value 1 / 256 was chosen
    // based on empirical testing
    const tolerance = 1.0 / 256.0;
    return index.resample(
        polygon,
        p => {
            const mc = transform.pointCoordinate3D(p);
            p.x = mc.x;
            p.y = mc.y;
        },
        tolerance);
}

function wrap(mercatorX        )         {
    return mercatorX < 0 ? 1 + (mercatorX % 1) : mercatorX % 1;
}

function findEdgeCrossingAntimeridian(polygon         , tr           , direction        )                            {
    for (let i = 1; i < polygon.length; i++) {
        const a = wrap(tr.pointCoordinate3D(polygon[i - 1]).x);
        const b = wrap(tr.pointCoordinate3D(polygon[i]).x);

        // direction < 0: mercator coordinate 0 will be crossed from left
        // direction > 0: mercator coordinate 1 will be crossed from right
        if (direction < 0) {
            if (a < b) {
                return {idx: i, t: -a / (b - 1 - a)};
            }
        } else {
            if (b < a) {
                return {idx: i, t: (1 - a) / (b + 1 - a)};
            }
        }
    }

    return null;
}

//Padding is in screen pixels and is only used as a coarse check, so 2 decimal places of precision should be good enough for a cache.
function cacheKey(padding        )          {
    return (padding * 100) | 0;
}

                                      
                                 
                               
                         
                                       
                                                       
               
                             
                                  
  

function clampBoundsToTileExtents(bounds                          )                           {
    bounds.min.x = index.clamp(bounds.min.x, 0, index.EXTENT);
    bounds.min.y = index.clamp(bounds.min.y, 0, index.EXTENT);

    bounds.max.x = index.clamp(bounds.max.x, 0, index.EXTENT);
    bounds.max.y = index.clamp(bounds.max.y, 0, index.EXTENT);
    return bounds;
}

//      


                                                      
                                                   
                                                   
                                                       

function loadTileJSON(options     , requestManager                , language         , worldview         , callback                    )             {
    const loaded = function(err        , tileJSON         ) {
        if (err) {
            return callback(err);
        } else if (tileJSON) {
            // Prefer TileJSON tiles, if both URL and tiles options are set
            if (options.url && tileJSON.tiles && options.tiles) delete options.tiles;

            const result      = index.pick(
                // explicit source options take precedence over TileJSON
                index.extend(tileJSON, options),
                ['tiles', 'minzoom', 'maxzoom', 'attribution', 'mapbox_logo', 'bounds', 'scheme', 'tileSize', 'encoding']
            );

            if (tileJSON.vector_layers) {
                result.vectorLayers = tileJSON.vector_layers;
                result.vectorLayerIds = result.vectorLayers.map((layer) => { return layer.id; });
            }

            result.tiles = requestManager.canonicalizeTileset(result, options.url);
            callback(null, result);
        }
    };

    if (options.url) {
        return index.getJSON(requestManager.transformRequest(requestManager.normalizeSourceURL(options.url, null, language, worldview), index.ResourceType.Source), loaded);
    } else {
        return index.exported.frame(() => loaded(null, options));
    }
}

//      


                                                  

class TileBounds {
                         
                    
                    

    constructor(bounds                                  , minzoom         , maxzoom         ) {
        this.bounds = index.LngLatBounds.convert(this.validateBounds(bounds));
        this.minzoom = minzoom || 0;
        this.maxzoom = maxzoom || 24;
    }

    validateBounds(bounds                                  )                                   {
        // make sure the bounds property contains valid longitude and latitudes
        if (!Array.isArray(bounds) || bounds.length !== 4) return [-180, -90, 180, 90];
        return [Math.max(-180, bounds[0]), Math.max(-90, bounds[1]), Math.min(180, bounds[2]), Math.min(90, bounds[3])];
    }

    contains(tileID                 )          {
        const worldSize = Math.pow(2, tileID.z);
        const level = {
            minX: Math.floor(index.mercatorXfromLng(this.bounds.getWest()) * worldSize),
            minY: Math.floor(index.mercatorYfromLat(this.bounds.getNorth()) * worldSize),
            maxX: Math.ceil(index.mercatorXfromLng(this.bounds.getEast()) * worldSize),
            maxY: Math.ceil(index.mercatorYfromLat(this.bounds.getSouth()) * worldSize)
        };
        const hit = tileID.x >= level.minX && tileID.x < level.maxX && tileID.y >= level.minY && tileID.y < level.maxY;
        return hit;
    }
}

//      


                                        
                                                   
                                    
                                                    
                                  
                                                   
                                                       
                                                                                              
                                          
                                                                         
                                                         

/**
 * A source containing vector tiles in [Mapbox Vector Tile format](https://docs.mapbox.com/vector-tiles/reference/).
 * See the [Style Specification](https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/#vector) for detailed documentation of options.
 *
 * @example
 * map.addSource('some id', {
 *     type: 'vector',
 *     url: 'mapbox://mapbox.mapbox-streets-v8'
 * });
 *
 * @example
 * map.addSource('some id', {
 *     type: 'vector',
 *     tiles: ['https://d25uarhxywzl1j.cloudfront.net/v0.1/{z}/{x}/{y}.mvt'],
 *     minzoom: 6,
 *     maxzoom: 14
 * });
 *
 * @example
 * map.getSource('some id').setUrl("mapbox://mapbox.mapbox-streets-v8");
 *
 * @example
 * map.getSource('some id').setTiles(['https://d25uarhxywzl1j.cloudfront.net/v0.1/{z}/{x}/{y}.mvt']);
 * @see [Example: Add a vector tile source](https://docs.mapbox.com/mapbox-gl-js/example/vector-source/)
 * @see [Example: Add a third party vector tile source](https://docs.mapbox.com/mapbox-gl-js/example/third-party/)
 */
class VectorTileSource extends index.Evented                   {
                   
               
                    
                    
                
                   
                     
                                       

                                        
                                    
                           
             
                                              
                         
                           
                                      
                                  
                                  
                     
                                    
                             

    constructor(id        , options                                                              , dispatcher            , eventedParent         ) {
        super();
        this.id = id;
        this.dispatcher = dispatcher;

        this.type = 'vector';
        this.minzoom = 0;
        this.maxzoom = 22;
        this.scheme = 'xyz';
        this.tileSize = 512;
        this.reparseOverscaled = true;
        this.isTileClipped = true;
        this._loaded = false;

        index.extend(this, index.pick(options, ['url', 'scheme', 'tileSize', 'promoteId']));
        this._options = index.extend({type: 'vector'}, options);

        this._collectResourceTiming = options.collectResourceTiming;

        if (this.tileSize !== 512) {
            throw new Error('vector tile sources must have a tileSize of 512');
        }

        this.setEventedParent(eventedParent);

        this._tileWorkers = {};
        this._deduped = new index.DedupedRequest();
    }

    load(callback                 ) {
        this._loaded = false;
        this.fire(new index.Event('dataloading', {dataType: 'source'}));
        const language = Array.isArray(this.map._language) ? this.map._language.join() : this.map._language;
        const worldview = this.map._worldview;
        this._tileJSONRequest = loadTileJSON(this._options, this.map._requestManager, language, worldview, (err, tileJSON) => {
            this._tileJSONRequest = null;
            this._loaded = true;
            if (err) {
                if (language) console.warn(`Ensure that your requested language string is a valid BCP-47 code or list of codes. Found: ${language}`);
                if (worldview && worldview.length !== 2) console.warn(`Requested worldview strings must be a valid ISO alpha-2 code. Found: ${worldview}`);

                this.fire(new index.ErrorEvent(err));
            } else if (tileJSON) {
                index.extend(this, tileJSON);
                if (tileJSON.bounds) this.tileBounds = new TileBounds(tileJSON.bounds, this.minzoom, this.maxzoom);
                index.postTurnstileEvent(tileJSON.tiles, this.map._requestManager._customAccessToken);

                // `content` is included here to prevent a race condition where `Style#_updateSources` is called
                // before the TileJSON arrives. this makes sure the tiles needed are loaded once TileJSON arrives
                // ref: https://github.com/mapbox/mapbox-gl-js/pull/4347#discussion_r104418088
                this.fire(new index.Event('data', {dataType: 'source', sourceDataType: 'metadata'}));
                this.fire(new index.Event('data', {dataType: 'source', sourceDataType: 'content'}));
            }

            if (callback) callback(err);
        });
    }

    loaded()          {
        return this._loaded;
    }

    // $FlowFixMe[method-unbinding]
    hasTile(tileID                  )          {
        return !this.tileBounds || this.tileBounds.contains(tileID.canonical);
    }

    // $FlowFixMe[method-unbinding]
    onAdd(map     ) {
        this.map = map;
        this.load();
    }

    /**
     * Reloads the source data and re-renders the map.
     *
     * @example
     * map.getSource('source-id').reload();
     */
    // $FlowFixMe[method-unbinding]
    reload() {
        this.cancelTileJSONRequest();
        this.load(() => this.map.style._clearSource(this.id));
    }

    /**
     * Sets the source `tiles` property and re-renders the map.
     *
     * @param {string[]} tiles An array of one or more tile source URLs, as in the TileJSON spec.
     * @returns {VectorTileSource} Returns itself to allow for method chaining.
     * @example
     * map.addSource('source-id', {
     *     type: 'vector',
     *     tiles: ['https://some_end_point.net/{z}/{x}/{y}.mvt'],
     *     minzoom: 6,
     *     maxzoom: 14
     * });
     *
     * // Set the endpoint associated with a vector tile source.
     * map.getSource('source-id').setTiles(['https://another_end_point.net/{z}/{x}/{y}.mvt']);
     */
    setTiles(tiles               )       {
        this._options.tiles = tiles;
        this.reload();

        return this;
    }

    /**
     * Sets the source `url` property and re-renders the map.
     *
     * @param {string} url A URL to a TileJSON resource. Supported protocols are `http:`, `https:`, and `mapbox://<Tileset ID>`.
     * @returns {VectorTileSource} Returns itself to allow for method chaining.
     * @example
     * map.addSource('source-id', {
     *     type: 'vector',
     *     url: 'mapbox://mapbox.mapbox-streets-v7'
     * });
     *
     * // Update vector tile source to a new URL endpoint
     * map.getSource('source-id').setUrl("mapbox://mapbox.mapbox-streets-v8");
     */
    setUrl(url        )       {
        this.url = url;
        this._options.url = url;
        this.reload();

        return this;
    }

    // $FlowFixMe[method-unbinding]
    onRemove() {
        this.cancelTileJSONRequest();
    }

    serialize()                            {
        return index.extend({}, this._options);
    }

    loadTile(tile      , callback                ) {
        const url = this.map._requestManager.normalizeTileURL(tile.tileID.canonical.url(this.tiles, this.scheme));
        const request = this.map._requestManager.transformRequest(url, index.ResourceType.Tile);

        const params = {
            request,
            data: undefined,
            uid: tile.uid,
            tileID: tile.tileID,
            tileZoom: tile.tileZoom,
            zoom: tile.tileID.overscaledZ,
            tileSize: this.tileSize * tile.tileID.overscaleFactor(),
            type: this.type,
            source: this.id,
            pixelRatio: index.exported.devicePixelRatio,
            showCollisionBoxes: this.map.showCollisionBoxes,
            promoteId: this.promoteId,
            isSymbolTile: tile.isSymbolTile
        };
        params.request.collectResourceTiming = this._collectResourceTiming;

        if (!tile.actor || tile.state === 'expired') {
            tile.actor = this._tileWorkers[url] = this._tileWorkers[url] || this.dispatcher.getActor();

            // if workers are not ready to receive messages yet, use the idle time to preemptively
            // load tiles on the main thread and pass the result instead of requesting a worker to do so
            if (!this.dispatcher.ready) {
                const cancel = index.loadVectorTile.call({deduped: this._deduped}, params, (err        , data                       ) => {
                    if (err || !data) {
                        done.call(this, err);
                    } else {
                        // the worker will skip the network request if the data is already there
                        params.data = {
                            cacheControl: data.cacheControl,
                            expires: data.expires,
                            rawData: data.rawData.slice(0)
                        };
                        if (tile.actor) tile.actor.send('loadTile', params, done.bind(this), undefined, true);
                    }
                }, true);
                tile.request = {cancel};

            } else {
                tile.request = tile.actor.send('loadTile', params, done.bind(this), undefined, true);
            }

        } else if (tile.state === 'loading') {
            // schedule tile reloading after it has been loaded
            tile.reloadCallback = callback;

        } else {
            tile.request = tile.actor.send('reloadTile', params, done.bind(this));
        }

        // $FlowFixMe[missing-this-annot]
        function done(err        , data                   ) {
            delete tile.request;

            if (tile.aborted)
                return callback(null);

            // $FlowFixMe[prop-missing] - generic Error type doesn't have status
            if (err && err.status !== 404) {
                return callback(err);
            }

            if (data && data.resourceTiming)
                tile.resourceTiming = data.resourceTiming;

            if (this.map._refreshExpiredTiles && data) tile.setExpiryData(data);
            tile.loadVectorData(data, this.map.painter);

            index.cacheEntryPossiblyAdded(this.dispatcher);

            callback(null);

            if (tile.reloadCallback) {
                this.loadTile(tile, tile.reloadCallback);
                tile.reloadCallback = null;
            }
        }
    }

    // $FlowFixMe[method-unbinding]
    abortTile(tile      ) {
        if (tile.request) {
            tile.request.cancel();
            delete tile.request;
        }
        if (tile.actor) {
            tile.actor.send('abortTile', {uid: tile.uid, type: this.type, source: this.id});
        }
    }

    // $FlowFixMe[method-unbinding]
    unloadTile(tile      ) {
        tile.unloadVectorData();
        if (tile.actor) {
            tile.actor.send('removeTile', {uid: tile.uid, type: this.type, source: this.id});
        }
    }

    hasTransition()          {
        return false;
    }

    // $FlowFixMe[method-unbinding]
    afterUpdate() {
        this._tileWorkers = {};
    }

    cancelTileJSONRequest() {
        if (!this._tileJSONRequest) return;
        this._tileJSONRequest.cancel();
        this._tileJSONRequest = null;
    }
}

//      


                                        
                                                   
                                    
                                                
                                                    
                                  
                                                   
                                                       
                                                       
             
                              
                                
                                

/**
 * A source containing raster tiles.
 * See the [Style Specification](https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/#raster) for detailed documentation of options.
 *
 * @example
 * map.addSource('some id', {
 *     type: 'raster',
 *     url: 'mapbox://mapbox.satellite',
 *     tileSize: 256
 * });
 *
 * @example
 * map.addSource('some id', {
 *     type: 'raster',
 *     tiles: ['https://img.nj.gov/imagerywms/Natural2015?bbox={bbox-epsg-3857}&format=image/png&service=WMS&version=1.1.1&request=GetMap&srs=EPSG:3857&transparent=true&width=256&height=256&layers=Natural2015'],
 *     tileSize: 256
 * });
 *
 * @see [Example: Add a raster tile source](https://docs.mapbox.com/mapbox-gl-js/example/map-tiles/)
 * @see [Example: Add a WMS source](https://docs.mapbox.com/mapbox-gl-js/example/wms/)
 */
class RasterTileSource extends index.Evented                   {
                                  
               
                    
                    
                
                   
                     

                                              
                           
                              
                           
             
                         

                     
                                                                       
                                  

    constructor(id        , options                                                          , dispatcher            , eventedParent         ) {
        super();
        this.id = id;
        this.dispatcher = dispatcher;
        this.setEventedParent(eventedParent);

        this.type = 'raster';
        this.minzoom = 0;
        this.maxzoom = 22;
        this.roundZoom = true;
        this.scheme = 'xyz';
        this.tileSize = 512;
        this._loaded = false;

        this._options = index.extend({type: 'raster'}, options);
        index.extend(this, index.pick(options, ['url', 'scheme', 'tileSize']));
    }

    load(callback                 ) {
        this._loaded = false;
        this.fire(new index.Event('dataloading', {dataType: 'source'}));
        this._tileJSONRequest = loadTileJSON(this._options, this.map._requestManager, null, null, (err, tileJSON) => {
            this._tileJSONRequest = null;
            this._loaded = true;
            if (err) {
                this.fire(new index.ErrorEvent(err));
            } else if (tileJSON) {
                index.extend(this, tileJSON);
                if (tileJSON.bounds) this.tileBounds = new TileBounds(tileJSON.bounds, this.minzoom, this.maxzoom);

                index.postTurnstileEvent(tileJSON.tiles);

                // `content` is included here to prevent a race condition where `Style#_updateSources` is called
                // before the TileJSON arrives. this makes sure the tiles needed are loaded once TileJSON arrives
                // ref: https://github.com/mapbox/mapbox-gl-js/pull/4347#discussion_r104418088
                this.fire(new index.Event('data', {dataType: 'source', sourceDataType: 'metadata'}));
                this.fire(new index.Event('data', {dataType: 'source', sourceDataType: 'content'}));
            }

            if (callback) callback(err);
        });
    }

    loaded()          {
        return this._loaded;
    }

    // $FlowFixMe[method-unbinding]
    onAdd(map     ) {
        this.map = map;
        this.load();
    }

    /**
     * Reloads the source data and re-renders the map.
     *
     * @example
     * map.getSource('source-id').reload();
     */
    // $FlowFixMe[method-unbinding]
    reload() {
        this.cancelTileJSONRequest();
        this.load(() => this.map.style._clearSource(this.id));
    }

    /**
     * Sets the source `tiles` property and re-renders the map.
     *
     * @param {string[]} tiles An array of one or more tile source URLs, as in the TileJSON spec.
     * @returns {RasterTileSource} Returns itself to allow for method chaining.
     * @example
     * map.addSource('source-id', {
     *     type: 'raster',
     *     tiles: ['https://some_end_point.net/{z}/{x}/{y}.png'],
     *     tileSize: 256
     * });
     *
     * // Set the endpoint associated with a raster tile source.
     * map.getSource('source-id').setTiles(['https://another_end_point.net/{z}/{x}/{y}.png']);
     */
    setTiles(tiles               )       {
        this._options.tiles = tiles;
        this.reload();

        return this;
    }

    /**
     * Sets the source `url` property and re-renders the map.
     *
     * @param {string} url A URL to a TileJSON resource. Supported protocols are `http:`, `https:`, and `mapbox://<Tileset ID>`.
     * @returns {RasterTileSource} Returns itself to allow for method chaining.
     * @example
     * map.addSource('source-id', {
     *     type: 'raster',
     *     url: 'mapbox://mapbox.satellite'
     * });
     *
     * // Update raster tile source to a new URL endpoint
     * map.getSource('source-id').setUrl('mapbox://mapbox.satellite');
     */
    setUrl(url        )       {
        this.url = url;
        this._options.url = url;
        this.reload();

        return this;
    }

    // $FlowFixMe[method-unbinding]
    onRemove() {
        this.cancelTileJSONRequest();
    }

    serialize()                                                           {
        return index.extend({}, this._options);
    }

    // $FlowFixMe[method-unbinding]
    hasTile(tileID                  )          {
        return !this.tileBounds || this.tileBounds.contains(tileID.canonical);
    }

    loadTile(tile      , callback                ) {
        const use2x = index.exported.devicePixelRatio >= 2;
        const url = this.map._requestManager.normalizeTileURL(tile.tileID.canonical.url(this.tiles, this.scheme), use2x, this.tileSize);
        tile.request = index.getImage(this.map._requestManager.transformRequest(url, index.ResourceType.Tile), (error, data, cacheControl, expires) => {
            delete tile.request;

            if (tile.aborted) {
                tile.state = 'unloaded';
                return callback(null);
            }

            if (error) {
                tile.state = 'errored';
                return callback(error);
            }

            if (!data) return callback(null);

            if (this.map._refreshExpiredTiles) tile.setExpiryData({cacheControl, expires});
            tile.setTexture(data, this.map.painter);
            tile.state = 'loaded';

            index.cacheEntryPossiblyAdded(this.dispatcher);
            callback(null);
        });
    }

    static loadTileData(tile      , data              , painter         ) {
        tile.setTexture(data, painter);
    }

    static unloadTileData(tile      , painter         ) {
        if (tile.texture) {
            painter.saveTileTexture(tile.texture);
        }
    }

    // $FlowFixMe[method-unbinding]
    abortTile(tile      , callback                ) {
        if (tile.request) {
            tile.request.cancel();
            delete tile.request;
        }
        callback();
    }

    // $FlowFixMe[method-unbinding]
    unloadTile(tile      , callback                ) {
        if (tile.texture) this.map.painter.saveTileTexture(tile.texture);
        callback();
    }

    hasTransition()          {
        return false;
    }

    cancelTileJSONRequest() {
        if (!this._tileJSONRequest) return;
        this._tileJSONRequest.cancel();
        this._tileJSONRequest = null;
    }
}

//      

let supportsOffscreenCanvas          ;

function offscreenCanvasSupported()          {
    if (supportsOffscreenCanvas == null) {
        supportsOffscreenCanvas = index.window.OffscreenCanvas &&
            new index.window.OffscreenCanvas(1, 1).getContext('2d') &&
            typeof index.window.createImageBitmap === 'function';
    }

    return supportsOffscreenCanvas;
}

//      


                                        
                                                    
                                  
                                                   
                                                       
                                                                         

// $FlowFixMe[method-unbinding]
class RasterDEMTileSource extends RasterTileSource                   {
                                     

    constructor(id        , options                              , dispatcher            , eventedParent         ) {
        super(id, options, dispatcher, eventedParent);
        this.type = 'raster-dem';
        this.maxzoom = 22;
        this._options = index.extend({type: 'raster-dem'}, options);
        this.encoding = options.encoding || "mapbox";
    }

    loadTile(tile      , callback                ) {
        const url = this.map._requestManager.normalizeTileURL(tile.tileID.canonical.url(this.tiles, this.scheme), false, this.tileSize);
        tile.request = index.getImage(this.map._requestManager.transformRequest(url, index.ResourceType.Tile), imageLoaded.bind(this));

        // $FlowFixMe[missing-this-annot]
        function imageLoaded(err        , img               , cacheControl         , expires         ) {
            delete tile.request;
            if (tile.aborted) {
                tile.state = 'unloaded';
                callback(null);
            } else if (err) {
                tile.state = 'errored';
                callback(err);
            } else if (img) {
                if (this.map._refreshExpiredTiles) tile.setExpiryData({cacheControl, expires});
                const transfer = index.window.ImageBitmap && img instanceof index.window.ImageBitmap && offscreenCanvasSupported();
                // DEMData uses 1px padding. Handle cases with image buffer of 1 and 2 pxs, the rest assume default buffer 0
                // in order to keep the previous implementation working (no validation against tileSize).
                const buffer = (img.width - index.prevPowerOfTwo(img.width)) / 2;
                // padding is used in getImageData. As DEMData has 1px padding, if DEM tile buffer is 2px, discard outermost pixels.
                const padding = 1 - buffer;
                const borderReady = padding < 1;
                if (!borderReady && !tile.neighboringTiles) {
                    tile.neighboringTiles = this._getNeighboringTiles(tile.tileID);
                }

                // $FlowFixMe[incompatible-call]
                const rawImageData = transfer ? img : index.exported.getImageData(img, padding);
                const params = {
                    uid: tile.uid,
                    coord: tile.tileID,
                    source: this.id,
                    rawImageData,
                    encoding: this.encoding,
                    padding
                };

                if (!tile.actor || tile.state === 'expired') {
                    tile.actor = this.dispatcher.getActor();
                    tile.actor.send('loadDEMTile', params, done.bind(this), undefined, true);
                }
            }
        }

        // $FlowFixMe[missing-this-annot]
        function done(err        , dem          ) {
            if (err) {
                tile.state = 'errored';
                callback(err);
            }

            if (dem) {
                tile.dem = dem;
                tile.dem.onDeserialize();
                tile.needsHillshadePrepare = true;
                tile.needsDEMTextureUpload = true;
                tile.state = 'loaded';
                callback(null);
            }
        }
    }

    _getNeighboringTiles(tileID                  )                                    {
        const canonical = tileID.canonical;
        const dim = Math.pow(2, canonical.z);

        const px = (canonical.x - 1 + dim) % dim;
        const pxw = canonical.x === 0 ? tileID.wrap - 1 : tileID.wrap;
        const nx = (canonical.x + 1 + dim) % dim;
        const nxw = canonical.x + 1 === dim ? tileID.wrap + 1 : tileID.wrap;

        const neighboringTiles = {};
        // add adjacent tiles
        neighboringTiles[new index.OverscaledTileID(tileID.overscaledZ, pxw, canonical.z, px, canonical.y).key] = {backfilled: false};
        neighboringTiles[new index.OverscaledTileID(tileID.overscaledZ, nxw, canonical.z, nx, canonical.y).key] = {backfilled: false};

        // Add upper neighboringTiles
        if (canonical.y > 0) {
            neighboringTiles[new index.OverscaledTileID(tileID.overscaledZ, pxw, canonical.z, px, canonical.y - 1).key] = {backfilled: false};
            neighboringTiles[new index.OverscaledTileID(tileID.overscaledZ, tileID.wrap, canonical.z, canonical.x, canonical.y - 1).key] = {backfilled: false};
            neighboringTiles[new index.OverscaledTileID(tileID.overscaledZ, nxw, canonical.z, nx, canonical.y - 1).key] = {backfilled: false};
        }
        // Add lower neighboringTiles
        if (canonical.y + 1 < dim) {
            neighboringTiles[new index.OverscaledTileID(tileID.overscaledZ, pxw, canonical.z, px, canonical.y + 1).key] = {backfilled: false};
            neighboringTiles[new index.OverscaledTileID(tileID.overscaledZ, tileID.wrap, canonical.z, canonical.x, canonical.y + 1).key] = {backfilled: false};
            neighboringTiles[new index.OverscaledTileID(tileID.overscaledZ, nxw, canonical.z, nx, canonical.y + 1).key] = {backfilled: false};
        }

        return neighboringTiles;
    }

    // $FlowFixMe[method-unbinding]
    unloadTile(tile      ) {
        if (tile.demTexture) this.map.painter.saveTileTexture(tile.demTexture);
        if (tile.fbo) {
            tile.fbo.destroy();
            delete tile.fbo;
        }
        if (tile.dem) delete tile.dem;
        delete tile.neighboringTiles;

        tile.state = 'unloaded';
    }

}

//      


                                        
                                    
                                                    
                                  
                                          
                                                   
                                                                     
                                                                   
                                                                                               
                                                       

/**
 * A source containing GeoJSON.
 * See the [Style Specification](https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson) for detailed documentation of options.
 *
 * @example
 * map.addSource('some id', {
 *     type: 'geojson',
 *     data: 'https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_10m_ports.geojson'
 * });
 *
 * @example
 * map.addSource('some id', {
 *     type: 'geojson',
 *     data: {
 *         "type": "FeatureCollection",
 *         "features": [{
 *             "type": "Feature",
 *             "properties": {},
 *             "geometry": {
 *                 "type": "Point",
 *                 "coordinates": [
 *                     -76.53063297271729,
 *                     39.18174077994108
 *                 ]
 *             }
 *         }]
 *     }
 * });
 *
 * @example
 * map.getSource('some id').setData({
 *     "type": "FeatureCollection",
 *     "features": [{
 *         "type": "Feature",
 *         "properties": {"name": "Null Island"},
 *         "geometry": {
 *             "type": "Point",
 *             "coordinates": [ 0, 0 ]
 *         }
 *     }]
 * });
 * @see [Example: Draw GeoJSON points](https://www.mapbox.com/mapbox-gl-js/example/geojson-markers/)
 * @see [Example: Add a GeoJSON line](https://www.mapbox.com/mapbox-gl-js/example/geojson-line/)
 * @see [Example: Create a heatmap from points](https://www.mapbox.com/mapbox-gl-js/example/heatmap/)
 * @see [Example: Create and style clusters](https://www.mapbox.com/mapbox-gl-js/example/cluster/)
 */
class GeoJSONSource extends index.Evented                   {
                    
               
                    
                    
                     
                               
                                       

                                  
                                      
                            
                                         
                                        
             
                 
                     
                        
                             
                                    
                              

    /**
     * @private
     */
    constructor(id        , options                                                                                                     , dispatcher            , eventedParent         ) {
        super();

        this.id = id;

        // `type` is a property rather than a constant to make it easy for 3rd
        // parties to use GeoJSONSource to build their own source types.
        this.type = 'geojson';

        this.minzoom = 0;
        this.maxzoom = 18;
        this.tileSize = 512;
        this.isTileClipped = true;
        this.reparseOverscaled = true;
        this._loaded = false;

        this.actor = dispatcher.getActor();
        this.setEventedParent(eventedParent);

        this._data = (options.data     );
        this._options = index.extend({}, options);

        this._collectResourceTiming = options.collectResourceTiming;

        if (options.maxzoom !== undefined) this.maxzoom = options.maxzoom;
        if (options.type) this.type = options.type;
        if (options.attribution) this.attribution = options.attribution;
        this.promoteId = options.promoteId;

        const scale = index.EXTENT / this.tileSize;

        // sent to the worker, along with `url: ...` or `data: literal geojson`,
        // so that it can load/parse/index the geojson data
        // extending with `options.workerOptions` helps to make it easy for
        // third-party sources to hack/reuse GeoJSONSource.
        this.workerOptions = index.extend({
            source: this.id,
            cluster: options.cluster || false,
            geojsonVtOptions: {
                buffer: (options.buffer !== undefined ? options.buffer : 128) * scale,
                tolerance: (options.tolerance !== undefined ? options.tolerance : 0.375) * scale,
                extent: index.EXTENT,
                maxZoom: this.maxzoom,
                lineMetrics: options.lineMetrics || false,
                generateId: options.generateId || false
            },
            superclusterOptions: {
                maxZoom: options.clusterMaxZoom !== undefined ? options.clusterMaxZoom : this.maxzoom - 1,
                minPoints: Math.max(2, options.clusterMinPoints || 2),
                extent: index.EXTENT,
                radius: (options.clusterRadius !== undefined ? options.clusterRadius : 50) * scale,
                log: false,
                generateId: options.generateId || false
            },
            clusterProperties: options.clusterProperties,
            filter: options.filter
        }, options.workerOptions);
    }

    // $FlowFixMe[method-unbinding]
    onAdd(map     ) {
        this.map = map;
        this.setData(this._data);
    }

    /**
     * Sets the GeoJSON data and re-renders the map.
     *
     * @param {Object | string} data A GeoJSON data object or a URL to one. The latter is preferable in the case of large GeoJSON files.
     * @returns {GeoJSONSource} Returns itself to allow for method chaining.
     * @example
     * map.addSource('source_id', {
     *     type: 'geojson',
     *     data: {
     *         type: 'FeatureCollection',
     *         features: []
     *     }
     * });
     * const geojsonSource = map.getSource('source_id');
     * // Update the data after the GeoJSON source was created
     * geojsonSource.setData({
     *     "type": "FeatureCollection",
     *     "features": [{
     *         "type": "Feature",
     *         "properties": {"name": "Null Island"},
     *         "geometry": {
     *             "type": "Point",
     *             "coordinates": [ 0, 0 ]
     *         }
     *     }]
     * });
     */
    setData(data                  )       {
        this._data = data;
        this._updateWorkerData();
        return this;
    }

    /**
     * For clustered sources, fetches the zoom at which the given cluster expands.
     *
     * @param {number} clusterId The value of the cluster's `cluster_id` property.
     * @param {Function} callback A callback to be called when the zoom value is retrieved (`(error, zoom) => { ... }`).
     * @returns {GeoJSONSource} Returns itself to allow for method chaining.
     * @example
     * // Assuming the map has a layer named 'clusters' and a source 'earthquakes'
     * // The following creates a camera animation on cluster feature click
     * // the clicked layer should be filtered to only include clusters, e.g. `filter: ['has', 'point_count']`
     * map.on('click', 'clusters', (e) => {
     *     const features = map.queryRenderedFeatures(e.point, {
     *         layers: ['clusters']
     *     });
     *
     *     const clusterId = features[0].properties.cluster_id;
     *
     *     // Ease the camera to the next cluster expansion
     *     map.getSource('earthquakes').getClusterExpansionZoom(
     *         clusterId,
     *         (err, zoom) => {
     *             if (!err) {
     *                 map.easeTo({
     *                     center: features[0].geometry.coordinates,
     *                     zoom
     *                 });
     *             }
     *         }
     *     );
     * });
     */
    getClusterExpansionZoom(clusterId        , callback                  )       {
        this.actor.send('geojson.getClusterExpansionZoom', {clusterId, source: this.id}, callback);
        return this;
    }

    /**
     * For clustered sources, fetches the children of the given cluster on the next zoom level (as an array of GeoJSON features).
     *
     * @param {number} clusterId The value of the cluster's `cluster_id` property.
     * @param {Function} callback A callback to be called when the features are retrieved (`(error, features) => { ... }`).
     * @returns {GeoJSONSource} Returns itself to allow for method chaining.
     * @example
     * // Retrieve cluster children on click
     * // the clicked layer should be filtered to only include clusters, e.g. `filter: ['has', 'point_count']`
     * map.on('click', 'clusters', (e) => {
     *     const features = map.queryRenderedFeatures(e.point, {
     *         layers: ['clusters']
     *     });
     *
     *     const clusterId = features[0].properties.cluster_id;
     *
     *     clusterSource.getClusterChildren(clusterId, (error, features) => {
     *         if (!error) {
     *             console.log('Cluster children:', features);
     *         }
     *     });
     * });
     *
     */
    getClusterChildren(clusterId        , callback                                 )       {
        this.actor.send('geojson.getClusterChildren', {clusterId, source: this.id}, callback);
        return this;
    }

    /**
     * For clustered sources, fetches the original points that belong to the cluster (as an array of GeoJSON features).
     *
     * @param {number} clusterId The value of the cluster's `cluster_id` property.
     * @param {number} limit The maximum number of features to return. Defaults to `10` if a falsy value is given.
     * @param {number} offset The number of features to skip (for example, for pagination). Defaults to `0` if a falsy value is given.
     * @param {Function} callback A callback to be called when the features are retrieved (`(error, features) => { ... }`).
     * @returns {GeoJSONSource} Returns itself to allow for method chaining.
     * @example
     * // Retrieve cluster leaves on click
     * // the clicked layer should be filtered to only include clusters, e.g. `filter: ['has', 'point_count']`
     * map.on('click', 'clusters', (e) => {
     *     const features = map.queryRenderedFeatures(e.point, {
     *         layers: ['clusters']
     *     });
     *
     *     const clusterId = features[0].properties.cluster_id;
     *     const pointCount = features[0].properties.point_count;
     *     const clusterSource = map.getSource('clusters');
     *
     *     clusterSource.getClusterLeaves(clusterId, pointCount, 0, (error, features) => {
     *     // Print cluster leaves in the console
     *         console.log('Cluster leaves:', error, features);
     *     });
     * });
     */
    getClusterLeaves(clusterId        , limit        , offset        , callback                                 )       {
        this.actor.send('geojson.getClusterLeaves', {
            source: this.id,
            clusterId,
            limit,
            offset
        }, callback);
        return this;
    }

    /*
     * Responsible for invoking WorkerSource's geojson.loadData target, which
     * handles loading the geojson data and preparing to serve it up as tiles,
     * using geojson-vt or supercluster as appropriate.
     */
    _updateWorkerData() {
        // if there's an earlier loadData to finish, wait until it finishes and then do another update
        if (this._pendingLoad) {
            this._coalesce = true;
            return;
        }

        this.fire(new index.Event('dataloading', {dataType: 'source'}));

        this._loaded = false;
        const options = index.extend({}, this.workerOptions);
        const data = this._data;
        if (typeof data === 'string') {
            options.request = this.map._requestManager.transformRequest(index.exported.resolveURL(data), index.ResourceType.Source);
            options.request.collectResourceTiming = this._collectResourceTiming;
        } else {
            options.data = JSON.stringify(data);
        }

        // target {this.type}.loadData rather than literally geojson.loadData,
        // so that other geojson-like source types can easily reuse this
        // implementation
        this._pendingLoad = this.actor.send(`${this.type}.loadData`, options, (err, result) => {
            this._loaded = true;
            this._pendingLoad = null;

            if (err) {
                this.fire(new index.ErrorEvent(err));

            } else {
                // although GeoJSON sources contain no metadata, we fire this event at first
                // to let the SourceCache know its ok to start requesting tiles.
                const data         = {dataType: 'source', sourceDataType: this._metadataFired ? 'content' : 'metadata'};
                if (this._collectResourceTiming && result && result.resourceTiming && result.resourceTiming[this.id]) {
                    data.resourceTiming = result.resourceTiming[this.id];
                }
                this.fire(new index.Event('data', data));
                this._metadataFired = true;
            }

            if (this._coalesce) {
                this._updateWorkerData();
                this._coalesce = false;
            }
        });
    }

    loaded()          {
        return this._loaded;
    }

    loadTile(tile      , callback                ) {
        const message = !tile.actor ? 'loadTile' : 'reloadTile';
        tile.actor = this.actor;
        const params = {
            type: this.type,
            uid: tile.uid,
            tileID: tile.tileID,
            tileZoom: tile.tileZoom,
            zoom: tile.tileID.overscaledZ,
            maxZoom: this.maxzoom,
            tileSize: this.tileSize,
            source: this.id,
            pixelRatio: index.exported.devicePixelRatio,
            showCollisionBoxes: this.map.showCollisionBoxes,
            promoteId: this.promoteId
        };

        tile.request = this.actor.send(message, params, (err, data) => {
            delete tile.request;
            tile.unloadVectorData();

            if (tile.aborted) {
                return callback(null);
            }

            if (err) {
                return callback(err);
            }

            tile.loadVectorData(data, this.map.painter, message === 'reloadTile');

            return callback(null);
        }, undefined, message === 'loadTile');
    }

    // $FlowFixMe[method-unbinding]
    abortTile(tile      ) {
        if (tile.request) {
            tile.request.cancel();
            delete tile.request;
        }
        tile.aborted = true;
    }

    // $FlowFixMe[method-unbinding]
    unloadTile(tile      ) {
        tile.unloadVectorData();
        this.actor.send('removeTile', {uid: tile.uid, type: this.type, source: this.id});
    }

    // $FlowFixMe[method-unbinding]
    onRemove() {
        if (this._pendingLoad) {
            this._pendingLoad.cancel();
        }
    }

    serialize()                             {
        return index.extend({}, this._options, {
            type: this.type,
            data: this._data
        });
    }

    hasTransition()          {
        return false;
    }
}

//      


                                        
                                                                  
                                    
                                                    
                                  
                                                   
                                                       
                                                       
             
                             
                            
                                
                                            

                                                                                            

// perspective correction for texture mapping, see https://github.com/mapbox/mapbox-gl-js/issues/9158
// adapted from https://math.stackexchange.com/a/339033/48653

function basisToPoints(x1        , y1        , x2        , y2        , x3        , y3        , x4        , y4        ) {
    const m = [x1, x2, x3, y1, y2, y3, 1, 1, 1];
    const s = [x4, y4, 1];
    const ma = index.adjoint([], m);
    const [sx, sy, sz] = index.transformMat3(s, s, index.transpose(ma, ma));
    return index.multiply$1(m, [sx, 0, 0, 0, sy, 0, 0, 0, sz], m);
}

function getPerspectiveTransform(w        , h        , x1        , y1        , x2        , y2        , x3        , y3        , x4        , y4        ) {
    const s = basisToPoints(0, 0, w, 0, 0, h, w, h);
    const m = basisToPoints(x1, y1, x2, y2, x3, y3, x4, y4);
    index.multiply$1(m, index.adjoint(s, s), m);
    return [
        m[6] / m[8] * w / index.EXTENT,
        m[7] / m[8] * h / index.EXTENT
    ];
}

/**
 * A data source containing an image.
 * See the [Style Specification](https://www.mapbox.com/mapbox-gl-style-spec/#sources-image) for detailed documentation of options.
 *
 * @example
 * // add to map
 * map.addSource('some id', {
 *     type: 'image',
 *     url: 'https://www.mapbox.com/images/foo.png',
 *     coordinates: [
 *         [-76.54, 39.18],
 *         [-76.52, 39.18],
 *         [-76.52, 39.17],
 *         [-76.54, 39.17]
 *     ]
 * });
 *
 * // update coordinates
 * const mySource = map.getSource('some id');
 * mySource.setCoordinates([
 *     [-76.54335737228394, 39.18579907229748],
 *     [-76.52803659439087, 39.1838364847587],
 *     [-76.5295386314392, 39.17683392507606],
 *     [-76.54520273208618, 39.17876344106642]
 * ]);
 *
 * // update url and coordinates simultaneously
 * mySource.updateImage({
 *     url: 'https://www.mapbox.com/images/bar.png',
 *     coordinates: [
 *         [-76.54335737228394, 39.18579907229748],
 *         [-76.52803659439087, 39.1838364847587],
 *         [-76.5295386314392, 39.17683392507606],
 *         [-76.54520273208618, 39.17876344106642]
 *     ]
 * });
 *
 * map.removeSource('some id');  // remove
 * @see [Example: Add an image](https://www.mapbox.com/mapbox-gl-js/example/image-on-a-map/)
 * @see [Example: Animate a series of images](https://www.mapbox.com/mapbox-gl-js/example/animate-images/)
 */
class ImageSource extends index.Evented                   {
                 
               
                    
                    
                     
                
                  
                   

                             
                               
                 
                           
             
                            
                                                      
    // $FlowFixMe
                            
                                     
                                
                                   
                     
                    
                               
                                           

    /**
     * @private
     */
    constructor(id        , options                                                                                 , dispatcher            , eventedParent         ) {
        super();
        this.id = id;
        this.dispatcher = dispatcher;
        this.coordinates = options.coordinates;

        this.type = 'image';
        this.minzoom = 0;
        this.maxzoom = 22;
        this.tileSize = 512;
        this.tiles = {};
        this._loaded = false;

        this.setEventedParent(eventedParent);

        this.options = options;
        this._dirty = false;
    }

    load(newCoordinates              , loaded          ) {
        this._loaded = loaded || false;
        this.fire(new index.Event('dataloading', {dataType: 'source'}));

        this.url = this.options.url;

        this._imageRequest = index.getImage(this.map._requestManager.transformRequest(this.url, index.ResourceType.Image), (err, image) => {
            this._imageRequest = null;
            this._loaded = true;
            if (err) {
                this.fire(new index.ErrorEvent(err));
            } else if (image) {
                const {HTMLImageElement} = index.window;
                if (image instanceof HTMLImageElement) {
                    this.image = index.exported.getImageData(image);
                } else {
                    this.image = image;
                }
                this._dirty = true;
                this.width = this.image.width;
                this.height = this.image.height;
                if (newCoordinates) {
                    this.coordinates = newCoordinates;
                }
                this._finishLoading();
            }
        });
    }

    loaded()          {
        return this._loaded;
    }

    /**
     * Updates the image URL and, optionally, the coordinates. To avoid having the image flash after changing,
     * set the `raster-fade-duration` paint property on the raster layer to 0.
     *
     * @param {Object} options Options object.
     * @param {string} [options.url] Required image URL.
     * @param {Array<Array<number>>} [options.coordinates] Four geographical coordinates,
     *   represented as arrays of longitude and latitude numbers, which define the corners of the image.
     *   The coordinates start at the top left corner of the image and proceed in clockwise order.
     *   They do not have to represent a rectangle.
     * @returns {ImageSource} Returns itself to allow for method chaining.
     * @example
     * // Add to an image source to the map with some initial URL and coordinates
     * map.addSource('image_source_id', {
     *     type: 'image',
     *     url: 'https://www.mapbox.com/images/foo.png',
     *     coordinates: [
     *         [-76.54, 39.18],
     *         [-76.52, 39.18],
     *         [-76.52, 39.17],
     *         [-76.54, 39.17]
     *     ]
     * });
     * // Then update the image URL and coordinates
     * imageSource.updateImage({
     *     url: 'https://www.mapbox.com/images/bar.png',
     *     coordinates: [
     *         [-76.5433, 39.1857],
     *         [-76.5280, 39.1838],
     *         [-76.5295, 39.1768],
     *         [-76.5452, 39.1787]
     *     ]
     * });
     */
    updateImage(options                                          )       {
        if (!this.image || !options.url) {
            return this;
        }
        if (this._imageRequest && options.url !== this.options.url) {
            this._imageRequest.cancel();
            this._imageRequest = null;
        }
        this.options.url = options.url;
        this.load(options.coordinates, this._loaded);
        return this;
    }

    _finishLoading() {
        if (this.map) {
            this.setCoordinates(this.coordinates);
            this.fire(new index.Event('data', {dataType: 'source', sourceDataType: 'metadata'}));
        }
    }

    // $FlowFixMe[method-unbinding]
    onAdd(map     ) {
        this.map = map;
        this.load();
    }

    // $FlowFixMe[method-unbinding]
    onRemove() {
        if (this._imageRequest) {
            this._imageRequest.cancel();
            this._imageRequest = null;
        }
        if (this.texture) this.texture.destroy();
    }

    /**
     * Sets the image's coordinates and re-renders the map.
     *
     * @param {Array<Array<number>>} coordinates Four geographical coordinates,
     *   represented as arrays of longitude and latitude numbers, which define the corners of the image.
     *   The coordinates start at the top left corner of the image and proceed in clockwise order.
     *   They do not have to represent a rectangle.
     * @returns {ImageSource} Returns itself to allow for method chaining.
     * @example
     * // Add an image source to the map with some initial coordinates
     * map.addSource('image_source_id', {
     *     type: 'image',
     *     url: 'https://www.mapbox.com/images/foo.png',
     *     coordinates: [
     *         [-76.54, 39.18],
     *         [-76.52, 39.18],
     *         [-76.52, 39.17],
     *         [-76.54, 39.17]
     *     ]
     * });
     * // Then update the image coordinates
     * imageSource.setCoordinates([
     *     [-76.5433, 39.1857],
     *     [-76.5280, 39.1838],
     *     [-76.5295, 39.1768],
     *     [-76.5452, 39.1787]
     * ]);
     */
    setCoordinates(coordinates             )       {
        this.coordinates = coordinates;
        this._boundsArray = undefined;

        // Calculate which mercator tile is suitable for rendering the video in
        // and create a buffer with the corner coordinates. These coordinates
        // may be outside the tile, because raster tiles aren't clipped when rendering.

        // transform the geo coordinates into (zoom 0) tile space coordinates
        // $FlowFixMe[method-unbinding]
        const cornerCoords = coordinates.map(index.MercatorCoordinate.fromLngLat);

        // Compute the coordinates of the tile we'll use to hold this image's
        // render data
        this.tileID = getCoordinatesCenterTileID(cornerCoords);

        // Constrain min/max zoom to our tile's zoom level in order to force
        // SourceCache to request this tile (no matter what the map's zoom
        // level)
        this.minzoom = this.maxzoom = this.tileID.z;

        this.fire(new index.Event('data', {dataType:'source', sourceDataType: 'content'}));
        return this;
    }

    // $FlowFixMe[method-unbinding]
    _clear() {
        this._boundsArray = undefined;
    }

    _prepareData(context         ) {
        for (const w in this.tiles) {
            const tile = this.tiles[w];
            if (tile.state !== 'loaded') {
                tile.state = 'loaded';
                tile.texture = this.texture;
            }
        }

        if (this._boundsArray) return;

        const tileTr = index.tileTransform(this.tileID, this.map.transform.projection);

        // Transform the corner coordinates into the coordinate space of our tile.
        const [tl, tr, br, bl] = this.coordinates.map((coord) => {
            const projectedCoord = tileTr.projection.project(coord[0], coord[1]);
            return index.getTilePoint(tileTr, projectedCoord)._round();
        });

        this.perspectiveTransform = getPerspectiveTransform(
            this.width, this.height, tl.x, tl.y, tr.x, tr.y, bl.x, bl.y, br.x, br.y);

        const boundsArray = this._boundsArray = new index.StructArrayLayout4i8();
        boundsArray.emplaceBack(tl.x, tl.y, 0, 0);
        boundsArray.emplaceBack(tr.x, tr.y, index.EXTENT, 0);
        boundsArray.emplaceBack(bl.x, bl.y, 0, index.EXTENT);
        boundsArray.emplaceBack(br.x, br.y, index.EXTENT, index.EXTENT);

        if (this.boundsBuffer) {
            this.boundsBuffer.destroy();
        }
        this.boundsBuffer = context.createVertexBuffer(boundsArray, index.boundsAttributes.members);
        this.boundsSegments = index.SegmentVector.simpleSegment(0, 0, 4, 2);
    }

    // $FlowFixMe[method-unbinding]
    prepare() {
        if (Object.keys(this.tiles).length === 0 || !this.image) return;

        const context = this.map.painter.context;
        const gl = context.gl;

        if (this._dirty) {
            if (!this.texture) {
                this.texture = new index.Texture(context, this.image, gl.RGBA);
                this.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);
            } else {
                this.texture.update(this.image);
            }
            this._dirty = false;
        }

        this._prepareData(context);
    }

    loadTile(tile      , callback                ) {
        // We have a single tile -- whoose coordinates are this.tileID -- that
        // covers the image we want to render.  If that's the one being
        // requested, set it up with the image; otherwise, mark the tile as
        // `errored` to indicate that we have no data for it.
        // If the world wraps, we may have multiple "wrapped" copies of the
        // single tile.
        if (this.tileID && this.tileID.equals(tile.tileID.canonical)) {
            this.tiles[String(tile.tileID.wrap)] = tile;
            tile.buckets = {};
            callback(null);
        } else {
            tile.state = 'errored';
            callback(null);
        }
    }

    serialize()         {
        return {
            type: 'image',
            url: this.options.url,
            coordinates: this.coordinates
        };
    }

    hasTransition()          {
        return false;
    }
}

/**
 * Given a list of coordinates, get their center as a coordinate.
 *
 * @returns centerpoint
 * @private
 */
function getCoordinatesCenterTileID(coords                           )                  {
    let minX = Infinity;
    let minY = Infinity;
    let maxX = -Infinity;
    let maxY = -Infinity;

    for (const coord of coords) {
        minX = Math.min(minX, coord.x);
        minY = Math.min(minY, coord.y);
        maxX = Math.max(maxX, coord.x);
        maxY = Math.max(maxY, coord.y);
    }

    const dx = maxX - minX;
    const dy = maxY - minY;
    const dMax = Math.max(dx, dy);
    const zoom = Math.max(0, Math.floor(-Math.log(dMax) / Math.LN2));
    const tilesAtZoom = Math.pow(2, zoom);

    return new index.CanonicalTileID(
            zoom,
            Math.floor((minX + maxX) / 2 * tilesAtZoom),
            Math.floor((minY + maxY) / 2 * tilesAtZoom));
}

//      


                                    
                                                    
                                                
                                                                     

/**
 * A data source containing video.
 * See the [Style Specification](https://www.mapbox.com/mapbox-gl-style-spec/#sources-video) for detailed documentation of options.
 *
 * @example
 * // add to map
 * map.addSource('some id', {
 *     type: 'video',
 *     url: [
 *         'https://www.mapbox.com/blog/assets/baltimore-smoke.mp4',
 *         'https://www.mapbox.com/blog/assets/baltimore-smoke.webm'
 *     ],
 *     coordinates: [
 *         [-76.54, 39.18],
 *         [-76.52, 39.18],
 *         [-76.52, 39.17],
 *         [-76.54, 39.17]
 *     ]
 * });
 *
 * // update
 * const mySource = map.getSource('some id');
 * mySource.setCoordinates([
 *     [-76.54335737228394, 39.18579907229748],
 *     [-76.52803659439087, 39.1838364847587],
 *     [-76.5295386314392, 39.17683392507606],
 *     [-76.54520273208618, 39.17876344106642]
 * ]);
 *
 * map.removeSource('some id');  // remove
 * @see [Example: Add a video](https://www.mapbox.com/mapbox-gl-js/example/video-on-a-map/)
 */
class VideoSource extends ImageSource {
                                      
                        
                            
                       

    /**
     * @private
     */
    constructor(id        , options                          , dispatcher            , eventedParent         ) {
        super(id, options, dispatcher, eventedParent);
        this.roundZoom = true;
        this.type = 'video';
        this.options = options;
    }

    load() {
        this._loaded = false;
        const options = this.options;

        this.urls = [];
        for (const url of options.urls) {
            this.urls.push(this.map._requestManager.transformRequest(url, index.ResourceType.Source).url);
        }

        index.getVideo(this.urls, (err, video) => {
            this._loaded = true;
            if (err) {
                this.fire(new index.ErrorEvent(err));
            } else if (video) {
                this.video = video;
                this.video.loop = true;

                // Prevent the video from taking over the screen in iOS
                this.video.setAttribute('playsinline', '');

                // Start repainting when video starts playing. hasTransition() will then return
                // true to trigger additional frames as long as the videos continues playing.
                this.video.addEventListener('playing', () => {
                    this.map.triggerRepaint();
                });

                if (this.map) {
                    this.video.play();
                }

                this._finishLoading();
            }
        });
    }

    /**
     * Pauses the video.
     *
     * @example
     * // Assuming a video source identified by video_source_id was added to the map
     * const videoSource = map.getSource('video_source_id');
     *
     * // Pauses the video
     * videoSource.pause();
     */
    pause() {
        if (this.video) {
            this.video.pause();
        }
    }

    /**
     * Plays the video.
     *
     * @example
     * // Assuming a video source identified by video_source_id was added to the map
     * const videoSource = map.getSource('video_source_id');
     *
     * // Starts the video
     * videoSource.play();
     */
    play() {
        if (this.video) {
            this.video.play();
        }
    }

    /**
     * Sets playback to a timestamp, in seconds.
     * @private
     */
    seek(seconds        ) {
        if (this.video) {
            const seekableRange = this.video.seekable;
            if (seconds < seekableRange.start(0) || seconds > seekableRange.end(0)) {
                this.fire(new index.ErrorEvent(new index.ValidationError(`sources.${this.id}`, null, `Playback for this video can be set only between the ${seekableRange.start(0)} and ${seekableRange.end(0)}-second mark.`)));
            } else this.video.currentTime = seconds;
        }
    }

    /**
     * Returns the HTML `video` element.
     *
     * @returns {HTMLVideoElement} The HTML `video` element.
     * @example
     * // Assuming a video source identified by video_source_id was added to the map
     * const videoSource = map.getSource('video_source_id');
     *
     * videoSource.getVideo(); // <video crossorigin="Anonymous" loop="">...</video>
     */
    getVideo()                   {
        return this.video;
    }

    onAdd(map     ) {
        if (this.map) return;
        this.map = map;
        this.load();
        if (this.video) {
            this.video.play();
            this.setCoordinates(this.coordinates);
        }
    }

    /**
     * Sets the video's coordinates and re-renders the map.
     *
     * @method setCoordinates
     * @instance
     * @memberof VideoSource
     * @returns {VideoSource} Returns itself to allow for method chaining.
     * @example
     * // Add a video source to the map to map
     * map.addSource('video_source_id', {
     *     type: 'video',
     *     url: [
     *         'https://www.mapbox.com/blog/assets/baltimore-smoke.mp4',
     *         'https://www.mapbox.com/blog/assets/baltimore-smoke.webm'
     *     ],
     *     coordinates: [
     *         [-76.54, 39.18],
     *         [-76.52, 39.18],
     *         [-76.52, 39.17],
     *         [-76.54, 39.17]
     *     ]
     * });
     *
     * // Then update the video source coordinates by new coordinates
     * const videoSource = map.getSource('video_source_id');
     * videoSource.setCoordinates([
     *     [-76.5433, 39.1857],
     *     [-76.5280, 39.1838],
     *     [-76.5295, 39.1768],
     *     [-76.5452, 39.1787]
     * ]);
     */
    // setCoordinates inherited from ImageSource

    prepare() {
        if (Object.keys(this.tiles).length === 0 || this.video.readyState < 2) {
            return; // not enough data for current position
        }

        const context = this.map.painter.context;
        const gl = context.gl;

        if (!this.texture) {
            this.texture = new index.Texture(context, this.video, gl.RGBA);
            this.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);
            this.width = this.video.videoWidth;
            this.height = this.video.videoHeight;

        } else if (!this.video.paused) {
            this.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);
            gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, this.video);
        }

        this._prepareData(context);
    }

    serialize()                           {
        return {
            type: 'video',
            urls: this.urls,
            coordinates: this.coordinates
        };
    }

    hasTransition()          {
        return this.video && !this.video.paused;
    }
}

//      


                                    
                                                    
                                                

                                          
                     
                                                                                            
                        
                                        
   

/**
 * Options to add a canvas source type to the map.
 *
 * @typedef {Object} CanvasSourceOptions
 * @property {string} type Source type. Must be `"canvas"`.
 * @property {string|HTMLCanvasElement} canvas Canvas source from which to read pixels. Can be a string representing the ID of the canvas element, or the `HTMLCanvasElement` itself.
 * @property {Array<Array<number>>} coordinates Four geographical coordinates denoting where to place the corners of the canvas, specified in `[longitude, latitude]` pairs.
 * @property {boolean} [animate=true] Whether the canvas source is animated. If the canvas is static (pixels do not need to be re-read on every frame), `animate` should be set to `false` to improve performance.
 */

/**
 * A data source containing the contents of an HTML canvas. See {@link CanvasSourceOptions} for detailed documentation of options.
 *
 * @example
 * // add to map
 * map.addSource('some id', {
 *     type: 'canvas',
 *     canvas: 'idOfMyHTMLCanvas',
 *     animate: true,
 *     coordinates: [
 *         [-76.54, 39.18],
 *         [-76.52, 39.18],
 *         [-76.52, 39.17],
 *         [-76.54, 39.17]
 *     ]
 * });
 *
 * // update
 * const mySource = map.getSource('some id');
 * mySource.setCoordinates([
 *     [-76.54335737228394, 39.18579907229748],
 *     [-76.52803659439087, 39.1838364847587],
 *     [-76.5295386314392, 39.17683392507606],
 *     [-76.54520273208618, 39.17876344106642]
 * ]);
 *
 * map.removeSource('some id');  // remove
 * @see [Example: Add a canvas source](https://docs.mapbox.com/mapbox-gl-js/example/canvas-source/)
 */
class CanvasSource extends ImageSource {
                                       
                     
                              
                     
                      
                      

    /**
     * @private
     */
    constructor(id        , options                           , dispatcher            , eventedParent         ) {
        super(id, options, dispatcher, eventedParent);

        // We build in some validation here, since canvas sources aren't included in the style spec:
        if (!options.coordinates) {
            this.fire(new index.ErrorEvent(new index.ValidationError(`sources.${id}`, null, 'missing required property "coordinates"')));
        } else if (!Array.isArray(options.coordinates) || options.coordinates.length !== 4 ||
                options.coordinates.some(c => !Array.isArray(c) || c.length !== 2 || c.some(l => typeof l !== 'number'))) {
            this.fire(new index.ErrorEvent(new index.ValidationError(`sources.${id}`, null, '"coordinates" property must be an array of 4 longitude/latitude array pairs')));
        }

        if (options.animate && typeof options.animate !== 'boolean') {
            this.fire(new index.ErrorEvent(new index.ValidationError(`sources.${id}`, null, 'optional "animate" property must be a boolean value')));
        }

        if (!options.canvas) {
            this.fire(new index.ErrorEvent(new index.ValidationError(`sources.${id}`, null, 'missing required property "canvas"')));
        } else if (typeof options.canvas !== 'string' && !(options.canvas instanceof index.window.HTMLCanvasElement)) {
            this.fire(new index.ErrorEvent(new index.ValidationError(`sources.${id}`, null, '"canvas" must be either a string representing the ID of the canvas element from which to read, or an HTMLCanvasElement instance')));
        }

        this.options = options;
        this.animate = options.animate !== undefined ? options.animate : true;
    }

    /**
     * Enables animation. The image will be copied from the canvas to the map on each frame.
     *
     * @method play
     * @instance
     * @memberof CanvasSource
     */

    /**
     * Disables animation. The map will display a static copy of the canvas image.
     *
     * @method pause
     * @instance
     * @memberof CanvasSource
     */

    load() {
        this._loaded = true;
        if (!this.canvas) {
            this.canvas = (this.options.canvas instanceof index.window.HTMLCanvasElement) ?
                this.options.canvas :
                index.window.document.getElementById(this.options.canvas);
        }
        this.width = this.canvas.width;
        this.height = this.canvas.height;

        if (this._hasInvalidDimensions()) {
            this.fire(new index.ErrorEvent(new Error('Canvas dimensions cannot be less than or equal to zero.')));
            return;
        }

        // $FlowFixMe[missing-this-annot]
        this.play = function() {
            this._playing = true;
            this.map.triggerRepaint();
        };

        // $FlowFixMe[missing-this-annot]
        this.pause = function() {
            if (this._playing) {
                this.prepare();
                this._playing = false;
            }
        };

        this._finishLoading();
    }

    /**
     * Returns the HTML `canvas` element.
     *
     * @returns {HTMLCanvasElement} The HTML `canvas` element.
     * @example
     * // Assuming the following canvas is added to your page
     * // <canvas id="canvasID" width="400" height="400"></canvas>
     * map.addSource('canvas-source', {
     *     type: 'canvas',
     *     canvas: 'canvasID',
     *     coordinates: [
     *         [91.4461, 21.5006],
     *         [100.3541, 21.5006],
     *         [100.3541, 13.9706],
     *         [91.4461, 13.9706]
     *     ]
     * });
     * map.getSource('canvas-source').getCanvas(); // <canvas id="canvasID" width="400" height="400"></canvas>
     */
    getCanvas()                    {
        return this.canvas;
    }

    // $FlowFixMe[method-unbinding]
    onAdd(map     ) {
        this.map = map;
        this.load();
        if (this.canvas) {
            if (this.animate) this.play();
        }
    }

    // $FlowFixMe[method-unbinding]
    onRemove() {
        this.pause();
    }

    /**
     * Sets the canvas's coordinates and re-renders the map.
     *
     * @method setCoordinates
     * @instance
     * @memberof CanvasSource
     * @param {Array<Array<number>>} coordinates Four geographical coordinates,
     *   represented as arrays of longitude and latitude numbers, which define the corners of the canvas.
     *   The coordinates start at the top left corner of the canvas and proceed in clockwise order.
     *   They do not have to represent a rectangle.
     * @returns {CanvasSource} Returns itself to allow for method chaining.
     */

    // setCoordinates inherited from ImageSource

    // $FlowFixMe[method-unbinding]
    prepare() {
        let resize = false;
        if (this.canvas.width !== this.width) {
            this.width = this.canvas.width;
            resize = true;
        }
        if (this.canvas.height !== this.height) {
            this.height = this.canvas.height;
            resize = true;
        }

        if (this._hasInvalidDimensions()) return;

        if (Object.keys(this.tiles).length === 0) return; // not enough data for current position

        const context = this.map.painter.context;

        if (!this.texture) {
            this.texture = new index.Texture(context, this.canvas, context.gl.RGBA, {premultiply: true});
        } else if (resize || this._playing) {
            this.texture.update(this.canvas, {premultiply: true});
        }

        this._prepareData(context);
    }

    serialize()         {
        return {
            type: 'canvas',
            coordinates: this.coordinates
        };
    }

    hasTransition()          {
        return this._playing;
    }

    _hasInvalidDimensions()          {
        for (const x of [this.canvas.width, this.canvas.height]) {
            if (isNaN(x) || x <= 0) return true;
        }
        return false;
    }
}

//      


                                    
                                                    
                                        
                                                   
                                                   

                         

function isRaster(data     )          {
    return data instanceof index.window.ImageData ||
        data instanceof index.window.HTMLCanvasElement ||
        data instanceof index.window.ImageBitmap ||
        data instanceof index.window.HTMLImageElement;
}

/**
 * Interface for custom sources. This is a specification for
 * implementers to model: it is not an exported method or class.
 *
 * Custom sources allow a user to load and modify their own tiles.
 * These sources can be added between any regular sources using {@link Map#addSource}.
 *
 * Custom sources must have a unique `id` and must have the `type` of `"custom"`.
 * They must implement `loadTile` and may implement `unloadTile`, `onAdd` and `onRemove`.
 * They can trigger rendering using {@link Map#triggerRepaint}.
 *
 * @interface CustomSourceInterface
 * @property {string} id A unique source id.
 * @property {string} type The source's type. Must be `"custom"`.
 * @example
 * // Custom source implemented as ES6 class
 * class CustomSource {
 *     constructor() {
 *         this.id = 'custom-source';
 *         this.type = 'custom';
 *         this.tileSize = 256;
 *         this.tilesUrl = 'https://stamen-tiles.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.jpg';
 *         this.attribution = 'Map tiles by Stamen Design, under CC BY 3.0';
 *     }
 *
 *     async loadTile(tile, {signal}) {
 *         const url = this.tilesUrl
 *             .replace('{z}', String(tile.z))
 *             .replace('{x}', String(tile.x))
 *             .replace('{y}', String(tile.y));
 *
 *         const response = await fetch(url, {signal});
 *         const data = await response.arrayBuffer();
 *
 *         const blob = new window.Blob([new Uint8Array(data)], {type: 'image/png'});
 *         const imageBitmap = await window.createImageBitmap(blob);
 *
 *         return imageBitmap;
 *     }
 * }
 *
 * map.on('load', () => {
 *     map.addSource('custom-source', new CustomSource());
 *     map.addLayer({
 *         id: 'layer',
 *         type: 'raster',
 *         source: 'custom-source'
 *     });
 * });
 */

/**
 * Optional method called when the source has been added to the Map with {@link Map#addSource}.
 * This gives the source a chance to initialize resources and register event listeners.
 *
 * @function
 * @memberof CustomSourceInterface
 * @instance
 * @name onAdd
 * @param {Map} map The Map this custom source was just added to.
 */

/**
 * Optional method called when the source has been removed from the Map with {@link Map#removeSource}.
 * This gives the source a chance to clean up resources and event listeners.
 *
 * @function
 * @memberof CustomSourceInterface
 * @instance
 * @name onRemove
 * @param {Map} map The Map this custom source was added to.
 */

/**
 * Optional method called after the tile is unloaded from the map viewport. This
 * gives the source a chance to clean up resources and event listeners.
 *
 * @function
 * @memberof CustomSourceInterface
 * @instance
 * @name unloadTile
 * @param {{ z: number, x: number, y: number }} tile Tile name to unload in the XYZ scheme format.
 */

/**
 * Optional method called during a render frame to check if there is a tile to render.
 *
 * @function
 * @memberof CustomSourceInterface
 * @instance
 * @name hasTile
 * @param {{ z: number, x: number, y: number }} tile Tile name to prepare in the XYZ scheme format.
 * @returns {boolean} True if tile exists, otherwise false.
 */

/**
 * Called when the map starts loading tile for the current animation frame.
 *
 * @function
 * @memberof CustomSourceInterface
 * @instance
 * @name loadTile
 * @param {{ z: number, x: number, y: number }} tile Tile name to load in the XYZ scheme format.
 * @param {Object} options Options.
 * @param {AbortSignal} options.signal A signal object that communicates when the map cancels the tile loading request.
 * @returns {Promise<TextureImage | undefined | null>} The promise that resolves to the tile image data as an `HTMLCanvasElement`, `HTMLImageElement`, `ImageData`, `ImageBitmap` or object with `width`, `height`, and `data`.
 *  If `loadTile` resolves to `undefined`, a map will render an overscaled parent tile in the tile’s space. If `loadTile` resolves to `null`, a map will render nothing in the tile’s space.
 */
                                        
               
                   
                        
                     
                     
                    
                      
                         
                                              
                                                                       
                                                                                                             
                                                                       
                               
                                  
 

class CustomSource    extends index.Evented                   {

               
                   
                   
                    
                    
                     
                               

                              
                            
                              
                              

              
                     
                            
                         
                                              

    constructor(id        , implementation                          , dispatcher            , eventedParent         ) {
        super();
        this.id = id;
        this.type = 'custom';
        this._dataType = 'raster';
        this._dispatcher = dispatcher;
        this._implementation = implementation;
        this.setEventedParent(eventedParent);

        this.scheme = 'xyz';
        this.minzoom = 0;
        this.maxzoom = 22;
        this.tileSize = 512;

        this._loaded = false;
        this.roundZoom = true;

        if (!this._implementation) {
            this.fire(new index.ErrorEvent(new Error(`Missing implementation for ${this.id} custom source`)));
        }

        if (!this._implementation.loadTile) {
            this.fire(new index.ErrorEvent(new Error(`Missing loadTile implementation for ${this.id} custom source`)));
        }

        if (this._implementation.bounds) {
            this.tileBounds = new TileBounds(this._implementation.bounds, this.minzoom, this.maxzoom);
        }

        // $FlowFixMe[prop-missing]
        // $FlowFixMe[method-unbinding]
        implementation.update = this._update.bind(this);

        // $FlowFixMe[prop-missing]
        // $FlowFixMe[method-unbinding]
        implementation.clearTiles = this._clearTiles.bind(this);

        // $FlowFixMe[prop-missing]
        // $FlowFixMe[method-unbinding]
        implementation.coveringTiles = this._coveringTiles.bind(this);

        index.extend(this, index.pick(implementation, ['dataType', 'scheme', 'minzoom', 'maxzoom', 'tileSize', 'attribution', 'minTileCacheSize', 'maxTileCacheSize']));
    }

    serialize()         {
        return index.pick(this, ['type', 'scheme', 'minzoom', 'maxzoom', 'tileSize', 'attribution']);
    }

    load() {
        this._loaded = true;
        this.fire(new index.Event('data', {dataType: 'source', sourceDataType: 'metadata'}));
        this.fire(new index.Event('data', {dataType: 'source', sourceDataType: 'content'}));
    }

    loaded()          {
        return this._loaded;
    }

    // $FlowFixMe[method-unbinding]
    onAdd(map     )       {
        this._map = map;
        this._loaded = false;
        this.fire(new index.Event('dataloading', {dataType: 'source'}));
        if (this._implementation.onAdd) this._implementation.onAdd(map);
        this.load();
    }

    // $FlowFixMe[method-unbinding]
    onRemove(map     )       {
        if (this._implementation.onRemove) {
            this._implementation.onRemove(map);
        }
    }

    // $FlowFixMe[method-unbinding]
    hasTile(tileID                  )          {
        if (this._implementation.hasTile) {
            const {x, y, z} = tileID.canonical;
            return this._implementation.hasTile({x, y, z});
        }

        return !this.tileBounds || this.tileBounds.contains(tileID.canonical);
    }

    loadTile(tile      , callback                )       {
        const {x, y, z} = tile.tileID.canonical;
        const controller = new index.window.AbortController();
        const signal = controller.signal;

        // $FlowFixMe[prop-missing]
        tile.request = Promise
            .resolve(this._implementation.loadTile({x, y, z}, {signal}))
            .then(tileLoaded.bind(this))
            .catch(error => {
                // silence AbortError
                if (error.code === 20) return;
                tile.state = 'errored';
                callback(error);
            });

        // $FlowFixMe[prop-missing]
        tile.request.cancel = () => controller.abort();

        // $FlowFixMe[missing-this-annot]
        function tileLoaded(data    ) {
            delete tile.request;

            if (tile.aborted) {
                tile.state = 'unloaded';
                return callback(null);
            }

            // If the implementation returned `undefined` as tile data,
            // mark the tile as `errored` to indicate that we have no data for it.
            // A map will render an overscaled parent tile in the tile’s space.
            if (data === undefined) {
                tile.state = 'errored';
                return callback(null);
            }

            // If the implementation returned `null` as tile data,
            // mark the tile as `loaded` and use an an empty image as tile data.
            // A map will render nothing in the tile’s space.
            if (data === null) {
                const emptyImage = {width: this.tileSize, height: this.tileSize, data: null};
                this.loadTileData(tile, (emptyImage     ));
                tile.state = 'loaded';
                return callback(null);
            }

            if (!isRaster(data)) {
                tile.state = 'errored';
                return callback(new Error(`Can't infer data type for ${this.id}, only raster data supported at the moment`));
            }

            this.loadTileData(tile, data);
            tile.state = 'loaded';
            callback(null);
        }
    }

    loadTileData(tile      , data   )       {
        // Only raster data supported at the moment
        RasterTileSource.loadTileData(tile, (data     ), this._map.painter);
    }

    unloadTileData(tile      )       {
        // Only raster data supported at the moment
        RasterTileSource.unloadTileData(tile, this._map.painter);
    }

    // $FlowFixMe[method-unbinding]
    unloadTile(tile      , callback                )       {
        this.unloadTileData(tile);
        if (this._implementation.unloadTile) {
            const {x, y, z} = tile.tileID.canonical;
            this._implementation.unloadTile({x, y, z});
        }

        callback();
    }

    // $FlowFixMe[method-unbinding]
    abortTile(tile      , callback                )       {
        if (tile.request && tile.request.cancel) {
            tile.request.cancel();
            delete tile.request;
        }

        callback();
    }

    hasTransition()          {
        return false;
    }

    _coveringTiles()                                        {
        const tileIDs = this._map.transform.coveringTiles({
            tileSize: this.tileSize,
            minzoom: this.minzoom,
            maxzoom: this.maxzoom,
            roundZoom: this.roundZoom
        });

        return tileIDs.map(tileID => ({x: tileID.canonical.x, y: tileID.canonical.y, z: tileID.canonical.z}));
    }

    _clearTiles() {
        this._map.style._clearSource(this.id);
    }

    _update() {
        this.fire(new index.Event('data', {dataType: 'source', sourceDataType: 'content'}));
    }
}

//      


                                                                

const sourceTypes                            = {
    vector: VectorTileSource,
    raster: RasterTileSource,
    'raster-dem': RasterDEMTileSource,
    geojson: GeoJSONSource,
    video: VideoSource,
    image: ImageSource,
    canvas: CanvasSource,
    custom: CustomSource
};

/*
 * Creates a tiled data source instance given an options object.
 *
 * @param id
 * @param {Object} source A source definition object compliant with
 * [`mapbox-gl-style-spec`](https://www.mapbox.com/mapbox-gl-style-spec/#sources) or, for a third-party source type,
  * with that type's requirements.
 * @param {Dispatcher} dispatcher
 * @returns {Source}
 */
const create = function(id        , specification                     , dispatcher            , eventedParent         )         {
    // $FlowFixMe[prop-missing]
    const source = new sourceTypes[specification.type](id, (specification     ), dispatcher, eventedParent);

    if (source.id !== id) {
        throw new Error(`Expected Source id to be ${id} instead of ${source.id}`);
    }

    index.bindAll(['load', 'abort', 'unload', 'serialize', 'prepare'], source);
    return source;
};

const getType = function (name        )                {
    return sourceTypes[name];
};

const setType = function (name        , type               ) {
    sourceTypes[name] = type;
};

//      


                                                
                                                          
                                                                   

                                           
                          
                             
   

/*
 * Returns a matrix that can be used to convert from tile coordinates to viewport pixel coordinates.
 */
function getPixelPosMatrix(transform           , tileID                  ) {
    const t = index.identity([]);
    index.scale$1(t, t, [transform.width * 0.5, -transform.height * 0.5, 1]);
    index.translate(t, t, [1, -1, 0]);
    index.multiply(t, t, transform.calculateProjMatrix(tileID.toUnwrapped()));
    return Float32Array.from(t);
}

function queryRenderedFeatures(sourceCache             ,
                            styleLayers                           ,
                            serializedLayers                       ,
                            queryGeometry               ,
                            params                                                                                        ,
                            transform           ,
                            use3DQuery         ,
                            visualizeQueryGeometry          = false)              {
    const tileResults = sourceCache.tilesIn(queryGeometry, use3DQuery, visualizeQueryGeometry);
    tileResults.sort(sortTilesIn);
    const renderedFeatureLayers = [];
    for (const tileResult of tileResults) {
        renderedFeatureLayers.push({
            wrappedTileID: tileResult.tile.tileID.wrapped().key,
            queryResults: tileResult.tile.queryRenderedFeatures(
                styleLayers,
                serializedLayers,
                sourceCache._state,
                tileResult,
                params,
                transform,
                getPixelPosMatrix(sourceCache.transform, tileResult.tile.tileID),
                visualizeQueryGeometry)
        });
    }

    const result = mergeRenderedFeatureLayers(renderedFeatureLayers);

    // Merge state from SourceCache into the results
    for (const layerID in result) {
        result[layerID].forEach((featureWrapper) => {
            const feature = featureWrapper.feature;
            const layer = feature.layer;

            if (!layer || layer.type === 'background' || layer.type === 'sky') return;

            feature.source = layer.source;
            if (layer['source-layer']) {
                feature.sourceLayer = layer['source-layer'];
            }
            feature.state = feature.id !== undefined ? sourceCache.getFeatureState(layer['source-layer'], feature.id) : {};
        });
    }
    return result;
}

function queryRenderedSymbols(styleLayers                           ,
                            serializedLayers                           ,
                            getLayerSourceCache                                           ,
                            queryGeometry              ,
                            params                                                                                        ,
                            collisionIndex                ,
                            retainedQueryData                                  )              {
    const result = {};
    const renderedSymbols = collisionIndex.queryRenderedSymbols(queryGeometry);
    const bucketQueryData = [];
    for (const bucketInstanceId of Object.keys(renderedSymbols).map(Number)) {
        bucketQueryData.push(retainedQueryData[bucketInstanceId]);
    }
    bucketQueryData.sort(sortTilesIn);

    for (const queryData of bucketQueryData) {
        const bucketSymbols = queryData.featureIndex.lookupSymbolFeatures(
                renderedSymbols[queryData.bucketInstanceId],
                serializedLayers,
                queryData.bucketIndex,
                queryData.sourceLayerIndex,
                params.filter,
                params.layers,
                params.availableImages,
                styleLayers);

        for (const layerID in bucketSymbols) {
            const resultFeatures = result[layerID] = result[layerID] || [];
            const layerSymbols = bucketSymbols[layerID];
            layerSymbols.sort((a, b) => {
                // Match topDownFeatureComparator from FeatureIndex, but using
                // most recent sorting of features from bucket.sortFeatures
                const featureSortOrder = queryData.featureSortOrder;
                if (featureSortOrder) {
                    // queryRenderedSymbols documentation says we'll return features in
                    // "top-to-bottom" rendering order (aka last-to-first).
                    // Actually there can be multiple symbol instances per feature, so
                    // we sort each feature based on the first matching symbol instance.
                    const sortedA = featureSortOrder.indexOf(a.featureIndex);
                    const sortedB = featureSortOrder.indexOf(b.featureIndex);
                    index.assert(sortedA >= 0);
                    index.assert(sortedB >= 0);
                    return sortedB - sortedA;
                } else {
                    // Bucket hasn't been re-sorted based on angle, so use the
                    // reverse of the order the features appeared in the data.
                    return b.featureIndex - a.featureIndex;
                }
            });
            for (const symbolFeature of layerSymbols) {
                resultFeatures.push(symbolFeature);
            }
        }
    }

    // Merge state from SourceCache into the results
    for (const layerName in result) {
        result[layerName].forEach((featureWrapper) => {
            const feature = featureWrapper.feature;
            const layer = styleLayers[layerName];
            const sourceCache = getLayerSourceCache(layer);
            if (!sourceCache) return;

            const state = sourceCache.getFeatureState(feature.layer['source-layer'], feature.id);
            feature.source = feature.layer.source;
            if (feature.layer['source-layer']) {
                feature.sourceLayer = feature.layer['source-layer'];
            }
            feature.state = state;
        });
    }
    return result;
}

function querySourceFeatures(sourceCache             , params     )                      {
    const tiles = sourceCache.getRenderableIds().map((id) => {
        return sourceCache.getTileByID(id);
    });

    const result = [];

    const dataTiles = {};
    for (let i = 0; i < tiles.length; i++) {
        const tile = tiles[i];
        const dataID = tile.tileID.canonical.key;
        if (!dataTiles[dataID]) {
            dataTiles[dataID] = true;
            tile.querySourceFeatures(result, params);
        }
    }

    return result;
}

function sortTilesIn(a                                            , b                                            ) {
    const idA = a.tileID;
    const idB = b.tileID;
    return (idA.overscaledZ - idB.overscaledZ) || (idA.canonical.y - idB.canonical.y) || (idA.wrap - idB.wrap) || (idA.canonical.x - idB.canonical.x);
}

function mergeRenderedFeatureLayers(tiles                       )              {
    // Merge results from all tiles, but if two tiles share the same
    // wrapped ID, don't duplicate features between the two tiles
    const result = {};
    const wrappedIDLayerMap = {};
    for (const tile of tiles) {
        const queryResults = tile.queryResults;
        const wrappedID = tile.wrappedTileID;
        const wrappedIDLayers = wrappedIDLayerMap[wrappedID] = wrappedIDLayerMap[wrappedID] || {};
        for (const layerID in queryResults) {
            const tileFeatures = queryResults[layerID];
            const wrappedIDFeatures = wrappedIDLayers[layerID] = wrappedIDLayers[layerID] || {};
            const resultFeatures = result[layerID] = result[layerID] || [];
            for (const tileFeature of tileFeatures) {
                if (!wrappedIDFeatures[tileFeature.featureIndex]) {
                    wrappedIDFeatures[tileFeature.featureIndex] = true;
                    resultFeatures.push(tileFeature);
                }
            }
        }
    }
    return result;
}

//      


                                                      

function WebWorker ()                  {
    return (mapboxgl.workerClass != null) ? new mapboxgl.workerClass() : (new index.window.Worker(mapboxgl.workerUrl)     ); // eslint-disable-line new-cap
}

//      

                                                     

const PRELOAD_POOL_ID = 'mapboxgl_preloaded_worker_pool';

/**
 * Constructs a worker pool.
 * @private
 */
class WorkerPool {
                               

                                            
                                    

    constructor() {
        this.active = {};
    }

    acquire(mapId                 )                         {
        if (!this.workers) {
            // Lazily look up the value of mapboxgl.workerCount so that
            // client code has had a chance to set it.
            this.workers = [];
            while (this.workers.length < WorkerPool.workerCount) {
                // $FlowFixMe[invalid-constructor]
                this.workers.push(new WebWorker());
            }
        }

        this.active[mapId] = true;
        return this.workers.slice();
    }

    release(mapId                 ) {
        delete this.active[mapId];
        if (this.numActive() === 0) {
            this.workers.forEach((w) => {
                w.terminate();
            });
            this.workers = (null     );
        }
    }

    isPreloaded()          {
        return !!this.active[PRELOAD_POOL_ID];
    }

    numActive()         {
        return Object.keys(this.active).length;
    }
}

// extensive benchmarking showed 2 to be the best default for both desktop and mobile devices;
// we can't rely on hardwareConcurrency because of wild inconsistency of reported numbers between browsers
WorkerPool.workerCount = 2;

//      


let globalWorkerPool             ;

/**
 * Creates (if necessary) and returns the single, global WorkerPool instance
 * to be shared across each Map
 * @private
 */
function getGlobalWorkerPool ()             {
    if (!globalWorkerPool) {
        globalWorkerPool = new WorkerPool();
    }
    return globalWorkerPool;
}

function prewarm() {
    const workerPool = getGlobalWorkerPool();
    workerPool.acquire(PRELOAD_POOL_ID);
}

function clearPrewarmedResources() {
    const pool = globalWorkerPool;
    if (pool) {
        // Remove the pool only if all maps that referenced the preloaded global worker pool have been removed.
        if (pool.isPreloaded() && pool.numActive() === 1) {
            pool.release(PRELOAD_POOL_ID);
            globalWorkerPool = null;
        } else {
            console.warn('Could not clear WebWorkers since there are active Map instances that still reference it. The pre-warmed WebWorker pool can only be cleared when all map instances have been removed with map.remove()');
        }
    }
}

//      


                                                   

function deref(layer                    , parent                    )                     {
    const result = {};

    for (const k in layer) {
        if (k !== 'ref') {
            result[k] = layer[k];
        }
    }

    index.refProperties.forEach((k) => {
        if (k in parent) {
            result[k] = (parent     )[k];
        }
    });

    return ((result     )                    );
}

/**
 * Given an array of layers, some of which may contain `ref` properties
 * whose value is the `id` of another property, return a new array where
 * such layers have been augmented with the 'type', 'source', etc. properties
 * from the parent layer, and the `ref` property has been removed.
 *
 * The input is not modified. The output may contain references to portions
 * of the input.
 *
 * @private
 * @param {Array<Layer>} layers
 * @returns {Array<Layer>}
 */
function derefLayers(layers                           )                            {
    layers = layers.slice();

    const map         = Object.create(null);
    for (let i = 0; i < layers.length; i++) {
        map[layers[i].id] = layers[i];
    }

    for (let i = 0; i < layers.length; i++) {
        if ('ref' in layers[i]) {
            layers[i] = deref(layers[i], map[(layers[i]     ).ref]);
        }
    }

    return layers;
}

//      
                                                   

function emptyStyle()                     {
    return {
        version: 8,
        layers: [],
        sources: {}
    };
}

//      


                                                                                            

                                                 

                
                    
                     
  

const operations                        = {

    /*
     * { command: 'setStyle', args: [stylesheet] }
     */
    setStyle: 'setStyle',

    /*
     * { command: 'addLayer', args: [layer, 'beforeLayerId'] }
     */
    addLayer: 'addLayer',

    /*
     * { command: 'removeLayer', args: ['layerId'] }
     */
    removeLayer: 'removeLayer',

    /*
     * { command: 'setPaintProperty', args: ['layerId', 'prop', value] }
     */
    setPaintProperty: 'setPaintProperty',

    /*
     * { command: 'setLayoutProperty', args: ['layerId', 'prop', value] }
     */
    setLayoutProperty: 'setLayoutProperty',

    /*
     * { command: 'setFilter', args: ['layerId', filter] }
     */
    setFilter: 'setFilter',

    /*
     * { command: 'addSource', args: ['sourceId', source] }
     */
    addSource: 'addSource',

    /*
     * { command: 'removeSource', args: ['sourceId'] }
     */
    removeSource: 'removeSource',

    /*
     * { command: 'setGeoJSONSourceData', args: ['sourceId', data] }
     */
    setGeoJSONSourceData: 'setGeoJSONSourceData',

    /*
     * { command: 'setLayerZoomRange', args: ['layerId', 0, 22] }
     */
    setLayerZoomRange: 'setLayerZoomRange',

    /*
     * { command: 'setLayerProperty', args: ['layerId', 'prop', value] }
     */
    setLayerProperty: 'setLayerProperty',

    /*
     * { command: 'setCenter', args: [[lon, lat]] }
     */
    setCenter: 'setCenter',

    /*
     * { command: 'setZoom', args: [zoom] }
     */
    setZoom: 'setZoom',

    /*
     * { command: 'setBearing', args: [bearing] }
     */
    setBearing: 'setBearing',

    /*
     * { command: 'setPitch', args: [pitch] }
     */
    setPitch: 'setPitch',

    /*
     * { command: 'setSprite', args: ['spriteUrl'] }
     */
    setSprite: 'setSprite',

    /*
     * { command: 'setGlyphs', args: ['glyphsUrl'] }
     */
    setGlyphs: 'setGlyphs',

    /*
     * { command: 'setTransition', args: [transition] }
     */
    setTransition: 'setTransition',

    /*
     * { command: 'setLighting', args: [lightProperties] }
     */
    setLight: 'setLight',

    /*
     * { command: 'setTerrain', args: [terrainProperties] }
     */
    setTerrain: 'setTerrain',

    /*
     *  { command: 'setFog', args: [fogProperties] }
     */
    setFog: 'setFog',

    /*
     *  { command: 'setProjection', args: [projectionProperties] }
     */
    setProjection: 'setProjection'
};

function addSource(sourceId        , after         , commands                ) {
    commands.push({command: operations.addSource, args: [sourceId, after[sourceId]]});
}

function removeSource(sourceId        , commands                , sourcesRemoved                  ) {
    commands.push({command: operations.removeSource, args: [sourceId]});
    sourcesRemoved[sourceId] = true;
}

function updateSource(sourceId        , after         , commands                , sourcesRemoved                  ) {
    removeSource(sourceId, commands, sourcesRemoved);
    addSource(sourceId, after, commands);
}

function canUpdateGeoJSON(before         , after         , sourceId        ) {
    let prop;
    for (prop in before[sourceId]) {
        if (!before[sourceId].hasOwnProperty(prop)) continue;
        if (prop !== 'data' && !index.deepEqual(before[sourceId][prop], after[sourceId][prop])) {
            return false;
        }
    }
    for (prop in after[sourceId]) {
        if (!after[sourceId].hasOwnProperty(prop)) continue;
        if (prop !== 'data' && !index.deepEqual(before[sourceId][prop], after[sourceId][prop])) {
            return false;
        }
    }
    return true;
}

function diffSources(before         , after         , commands                , sourcesRemoved                  ) {
    before = before || {};
    after = after || {};

    let sourceId;

    // look for sources to remove
    for (sourceId in before) {
        if (!before.hasOwnProperty(sourceId)) continue;
        if (!after.hasOwnProperty(sourceId)) {
            removeSource(sourceId, commands, sourcesRemoved);
        }
    }

    // look for sources to add/update
    for (sourceId in after) {
        if (!after.hasOwnProperty(sourceId)) continue;
        const source = after[sourceId];
        if (!before.hasOwnProperty(sourceId)) {
            addSource(sourceId, after, commands);
        } else if (!index.deepEqual(before[sourceId], source)) {
            if (before[sourceId].type === 'geojson' && source.type === 'geojson' && canUpdateGeoJSON(before, after, sourceId)) {
                commands.push({command: operations.setGeoJSONSourceData, args: [sourceId, source.data]});
            } else {
                // no update command, must remove then add
                updateSource(sourceId, after, commands, sourcesRemoved);
            }
        }
    }
}

function diffLayerPropertyChanges(before     , after     , commands                , layerId        , klass         , command        ) {
    before = before || {};
    after = after || {};

    let prop;

    for (prop in before) {
        if (!before.hasOwnProperty(prop)) continue;
        if (!index.deepEqual(before[prop], after[prop])) {
            commands.push({command, args: [layerId, prop, after[prop], klass]});
        }
    }
    for (prop in after) {
        if (!after.hasOwnProperty(prop) || before.hasOwnProperty(prop)) continue;
        if (!index.deepEqual(before[prop], after[prop])) {
            commands.push({command, args: [layerId, prop, after[prop], klass]});
        }
    }
}

function pluckId(layer                    ) {
    return layer.id;
}

function indexById(group                                , layer                    ) {
    group[layer.id] = layer;
    return group;
}

function diffLayers(before                           , after                           , commands                ) {
    before = before || [];
    after = after || [];

    // order of layers by id
    const beforeOrder = before.map(pluckId);
    const afterOrder = after.map(pluckId);

    // index of layer by id
    const beforeIndex = before.reduce(indexById, {});
    const afterIndex = after.reduce(indexById, {});

    // track order of layers as if they have been mutated
    const tracker = beforeOrder.slice();

    // layers that have been added do not need to be diffed
    const clean         = Object.create(null);

    let i, d, layerId, beforeLayer                    , afterLayer                    , insertBeforeLayerId, prop;

    // remove layers
    for (i = 0, d = 0; i < beforeOrder.length; i++) {
        layerId = beforeOrder[i];
        if (!afterIndex.hasOwnProperty(layerId)) {
            commands.push({command: operations.removeLayer, args: [layerId]});
            tracker.splice(tracker.indexOf(layerId, d), 1);
        } else {
            // limit where in tracker we need to look for a match
            d++;
        }
    }

    // add/reorder layers
    for (i = 0, d = 0; i < afterOrder.length; i++) {
        // work backwards as insert is before an existing layer
        layerId = afterOrder[afterOrder.length - 1 - i];

        if (tracker[tracker.length - 1 - i] === layerId) continue;

        if (beforeIndex.hasOwnProperty(layerId)) {
            // remove the layer before we insert at the correct position
            commands.push({command: operations.removeLayer, args: [layerId]});
            tracker.splice(tracker.lastIndexOf(layerId, tracker.length - d), 1);
        } else {
            // limit where in tracker we need to look for a match
            d++;
        }

        // add layer at correct position
        insertBeforeLayerId = tracker[tracker.length - i];
        commands.push({command: operations.addLayer, args: [afterIndex[layerId], insertBeforeLayerId]});
        tracker.splice(tracker.length - i, 0, layerId);
        clean[layerId] = true;
    }

    // update layers
    for (i = 0; i < afterOrder.length; i++) {
        layerId = afterOrder[i];
        beforeLayer = beforeIndex[layerId];
        afterLayer = afterIndex[layerId];

        // no need to update if previously added (new or moved)
        if (clean[layerId] || index.deepEqual(beforeLayer, afterLayer)) continue;

        // If source, source-layer, or type have changes, then remove the layer
        // and add it back 'from scratch'.
        // $FlowFixMe[prop-missing] - there is no `source-layer` in background and sky layers
        if (!index.deepEqual(beforeLayer.source, afterLayer.source) || !index.deepEqual(beforeLayer['source-layer'], afterLayer['source-layer']) || !index.deepEqual(beforeLayer.type, afterLayer.type)) {
            commands.push({command: operations.removeLayer, args: [layerId]});
            // we add the layer back at the same position it was already in, so
            // there's no need to update the `tracker`
            insertBeforeLayerId = tracker[tracker.lastIndexOf(layerId) + 1];
            commands.push({command: operations.addLayer, args: [afterLayer, insertBeforeLayerId]});
            continue;
        }

        // layout, paint, filter, minzoom, maxzoom
        diffLayerPropertyChanges(beforeLayer.layout, afterLayer.layout, commands, layerId, null, operations.setLayoutProperty);
        diffLayerPropertyChanges(beforeLayer.paint, afterLayer.paint, commands, layerId, null, operations.setPaintProperty);
        if (!index.deepEqual(beforeLayer.filter, afterLayer.filter)) {
            commands.push({command: operations.setFilter, args: [layerId, afterLayer.filter]});
        }
        if (!index.deepEqual(beforeLayer.minzoom, afterLayer.minzoom) || !index.deepEqual(beforeLayer.maxzoom, afterLayer.maxzoom)) {
            commands.push({command: operations.setLayerZoomRange, args: [layerId, afterLayer.minzoom, afterLayer.maxzoom]});
        }

        // handle all other layer props, including paint.*
        for (prop in beforeLayer) {
            if (!beforeLayer.hasOwnProperty(prop)) continue;
            if (prop === 'layout' || prop === 'paint' || prop === 'filter' ||
                prop === 'metadata' || prop === 'minzoom' || prop === 'maxzoom') continue;
            if (prop.indexOf('paint.') === 0) {
                diffLayerPropertyChanges(beforeLayer[prop], afterLayer[prop], commands, layerId, prop.slice(6), operations.setPaintProperty);
            } else if (!index.deepEqual(beforeLayer[prop], afterLayer[prop])) {
                commands.push({command: operations.setLayerProperty, args: [layerId, prop, afterLayer[prop]]});
            }
        }
        for (prop in afterLayer) {
            if (!afterLayer.hasOwnProperty(prop) || beforeLayer.hasOwnProperty(prop)) continue;
            if (prop === 'layout' || prop === 'paint' || prop === 'filter' ||
                prop === 'metadata' || prop === 'minzoom' || prop === 'maxzoom') continue;
            if (prop.indexOf('paint.') === 0) {
                diffLayerPropertyChanges(beforeLayer[prop], afterLayer[prop], commands, layerId, prop.slice(6), operations.setPaintProperty);
            } else if (!index.deepEqual(beforeLayer[prop], afterLayer[prop])) {
                commands.push({command: operations.setLayerProperty, args: [layerId, prop, afterLayer[prop]]});
            }
        }
    }
}

/**
 * Diff two stylesheet
 *
 * Creates semanticly aware diffs that can easily be applied at runtime.
 * Operations produced by the diff closely resemble the mapbox-gl-js API. Any
 * error creating the diff will fall back to the 'setStyle' operation.
 *
 * Example diff:
 * [
 *     { command: 'setConstant', args: ['@water', '#0000FF'] },
 *     { command: 'setPaintProperty', args: ['background', 'background-color', 'black'] }
 * ]
 *
 * @private
 * @param {*} [before] stylesheet to compare from
 * @param {*} after stylesheet to compare to
 * @returns Array list of changes
 */
function diffStyles(before                    , after                    )                 {
    if (!before) return [{command: operations.setStyle, args: [after]}];

    let commands = [];

    try {
        // Handle changes to top-level properties
        if (!index.deepEqual(before.version, after.version)) {
            return [{command: operations.setStyle, args: [after]}];
        }
        if (!index.deepEqual(before.center, after.center)) {
            commands.push({command: operations.setCenter, args: [after.center]});
        }
        if (!index.deepEqual(before.zoom, after.zoom)) {
            commands.push({command: operations.setZoom, args: [after.zoom]});
        }
        if (!index.deepEqual(before.bearing, after.bearing)) {
            commands.push({command: operations.setBearing, args: [after.bearing]});
        }
        if (!index.deepEqual(before.pitch, after.pitch)) {
            commands.push({command: operations.setPitch, args: [after.pitch]});
        }
        if (!index.deepEqual(before.sprite, after.sprite)) {
            commands.push({command: operations.setSprite, args: [after.sprite]});
        }
        if (!index.deepEqual(before.glyphs, after.glyphs)) {
            commands.push({command: operations.setGlyphs, args: [after.glyphs]});
        }
        if (!index.deepEqual(before.transition, after.transition)) {
            commands.push({command: operations.setTransition, args: [after.transition]});
        }
        if (!index.deepEqual(before.light, after.light)) {
            commands.push({command: operations.setLight, args: [after.light]});
        }
        if (!index.deepEqual(before.fog, after.fog)) {
            commands.push({command: operations.setFog, args: [after.fog]});
        }
        if (!index.deepEqual(before.projection, after.projection)) {
            commands.push({command: operations.setProjection, args: [after.projection]});
        }

        // Handle changes to `sources`
        // If a source is to be removed, we also--before the removeSource
        // command--need to remove all the style layers that depend on it.
        const sourcesRemoved = {};

        // First collect the {add,remove}Source commands
        const removeOrAddSourceCommands = [];
        diffSources(before.sources, after.sources, removeOrAddSourceCommands, sourcesRemoved);

        // Push a removeLayer command for each style layer that depends on a
        // source that's being removed.
        // Also, exclude any such layers them from the input to `diffLayers`
        // below, so that diffLayers produces the appropriate `addLayers`
        // command
        const beforeLayers = [];
        if (before.layers) {
            before.layers.forEach((layer) => {
                if (layer.source && sourcesRemoved[layer.source]) {
                    commands.push({command: operations.removeLayer, args: [layer.id]});
                } else {
                    beforeLayers.push(layer);
                }
            });
        }

        // Remove the terrain if the source for that terrain is being removed
        let beforeTerrain = before.terrain;
        if (beforeTerrain) {
            if (sourcesRemoved[beforeTerrain.source]) {
                commands.push({command: operations.setTerrain, args: [undefined]});
                beforeTerrain = undefined;
            }
        }

        commands = commands.concat(removeOrAddSourceCommands);

        // Even though terrain is a top-level property
        // Its like a layer in the sense that it depends on a source being present.
        if (!index.deepEqual(beforeTerrain, after.terrain)) {
            commands.push({command: operations.setTerrain, args: [after.terrain]});
        }

        // Handle changes to `layers`
        diffLayers(beforeLayers, after.layers, commands);

    } catch (e) {
        // fall back to setStyle
        console.warn('Unable to compute style diff:', e);
        commands = [{command: operations.setStyle, args: [after]}];
    }

    return commands;
}

//      


class PathInterpolator {
                         
                   
                         
                    
                              

    constructor(points_               , padding_         ) {
        this.reset(points_, padding_);
    }

    reset(points_               , padding_         ) {
        this.points = points_ || [];

        // Compute cumulative distance from first point to every other point in the segment.
        // Last entry in the array is total length of the path
        this._distances = [0.0];

        for (let i = 1; i < this.points.length; i++) {
            this._distances[i] = this._distances[i - 1] + this.points[i].dist(this.points[i - 1]);
        }

        this.length = this._distances[this._distances.length - 1];
        this.padding = Math.min(padding_ || 0, this.length * 0.5);
        this.paddedLength = this.length - this.padding * 2.0;
    }

    lerp(t        )        {
        index.assert(this.points.length > 0);
        if (this.points.length === 1) {
            return this.points[0];
        }

        t = index.clamp(t, 0, 1);

        // Find the correct segment [p0, p1] where p0 <= x < p1
        let currentIndex = 1;
        let distOfCurrentIdx = this._distances[currentIndex];
        const distToTarget = t * this.paddedLength + this.padding;

        while (distOfCurrentIdx < distToTarget && currentIndex < this._distances.length) {
            distOfCurrentIdx = this._distances[++currentIndex];
        }

        // Interpolate between the two points of the segment
        const idxOfPrevPoint = currentIndex - 1;
        const distOfPrevIdx = this._distances[idxOfPrevPoint];
        const segmentLength = distOfCurrentIdx - distOfPrevIdx;
        const segmentT = segmentLength > 0 ? (distToTarget - distOfPrevIdx) / segmentLength : 0;

        return this.points[idxOfPrevPoint].mult(1.0 - segmentT).add(this.points[currentIndex].mult(segmentT));
    }
}

//      

                 
             
               
               
               
              
  

/**
 * GridIndex is a data structure for testing the intersection of
 * circles and rectangles in a 2d plane.
 * It is optimized for rapid insertion and querying.
 * GridIndex splits the plane into a set of "cells" and keeps track
 * of which geometries intersect with each cell. At query time,
 * full geometry comparisons are only done for items that share
 * at least one cell. As long as the geometries are relatively
 * uniformly distributed across the plane, this greatly reduces
 * the number of comparisons necessary.
 *
 * @private
 */
class GridIndex {
                           
                        
                                   
                                      
                          
                           
                       
                       
                  
                   
                   
                   
                   
                      

    constructor (width        , height        , cellSize        ) {
        const boxCells = this.boxCells = [];
        const circleCells = this.circleCells = [];

        // More cells -> fewer geometries to check per cell, but items tend
        // to be split across more cells.
        // Sweet spot allows most small items to fit in one cell
        this.xCellCount = Math.ceil(width / cellSize);
        this.yCellCount = Math.ceil(height / cellSize);

        for (let i = 0; i < this.xCellCount * this.yCellCount; i++) {
            boxCells.push([]);
            circleCells.push([]);
        }
        this.circleKeys = [];
        this.boxKeys = [];
        this.bboxes = [];
        this.circles = [];

        this.width = width;
        this.height = height;
        this.xScale = this.xCellCount / width;
        this.yScale = this.yCellCount / height;
        this.boxUid = 0;
        this.circleUid = 0;
    }

    keysLength()         {
        return this.boxKeys.length + this.circleKeys.length;
    }

    insert(key     , x1        , y1        , x2        , y2        ) {
        // $FlowFixMe[method-unbinding]
        this._forEachCell(x1, y1, x2, y2, this._insertBoxCell, this.boxUid++);
        this.boxKeys.push(key);
        this.bboxes.push(x1);
        this.bboxes.push(y1);
        this.bboxes.push(x2);
        this.bboxes.push(y2);
    }

    insertCircle(key     , x        , y        , radius        ) {
        // Insert circle into grid for all cells in the circumscribing square
        // It's more than necessary (by a factor of 4/PI), but fast to insert
        // $FlowFixMe[method-unbinding]
        this._forEachCell(x - radius, y - radius, x + radius, y + radius, this._insertCircleCell, this.circleUid++);
        this.circleKeys.push(key);
        this.circles.push(x);
        this.circles.push(y);
        this.circles.push(radius);
    }

    _insertBoxCell(x1        , y1        , x2        , y2        , cellIndex        , uid        ) {
        this.boxCells[cellIndex].push(uid);
    }

    _insertCircleCell(x1        , y1        , x2        , y2        , cellIndex        , uid        )  {
        this.circleCells[cellIndex].push(uid);
    }

    _query(x1        , y1        , x2        , y2        , hitTest         , predicate      )                            {
        if (x2 < 0 || x1 > this.width || y2 < 0 || y1 > this.height) {
            return hitTest ? false : [];
        }
        const result = [];
        if (x1 <= 0 && y1 <= 0 && this.width <= x2 && this.height <= y2) {
            if (hitTest) {
                return true;
            }
            for (let boxUid = 0; boxUid < this.boxKeys.length; boxUid++) {
                result.push({
                    key: this.boxKeys[boxUid],
                    x1: this.bboxes[boxUid * 4],
                    y1: this.bboxes[boxUid * 4 + 1],
                    x2: this.bboxes[boxUid * 4 + 2],
                    y2: this.bboxes[boxUid * 4 + 3]
                });
            }
            for (let circleUid = 0; circleUid < this.circleKeys.length; circleUid++) {
                const x = this.circles[circleUid * 3];
                const y = this.circles[circleUid * 3 + 1];
                const radius = this.circles[circleUid * 3 + 2];
                result.push({
                    key: this.circleKeys[circleUid],
                    x1: x - radius,
                    y1: y - radius,
                    x2: x + radius,
                    y2: y + radius
                });
            }
            return predicate ? result.filter(predicate) : result;
        } else {
            const queryArgs = {
                hitTest,
                seenUids: {box: {}, circle: {}}
            };
            // $FlowFixMe[method-unbinding]
            this._forEachCell(x1, y1, x2, y2, this._queryCell, result, queryArgs, predicate);
            return hitTest ? result.length > 0 : result;
        }
    }

    _queryCircle(x        , y        , radius        , hitTest         , predicate      )                            {
        // Insert circle into grid for all cells in the circumscribing square
        // It's more than necessary (by a factor of 4/PI), but fast to insert
        const x1 = x - radius;
        const x2 = x + radius;
        const y1 = y - radius;
        const y2 = y + radius;
        if (x2 < 0 || x1 > this.width || y2 < 0 || y1 > this.height) {
            return hitTest ? false : [];
        }

        // Box query early exits if the bounding box is larger than the grid, but we don't do
        // the equivalent calculation for circle queries because early exit is less likely
        // and the calculation is more expensive
        const result = [];
        const queryArgs = {
            hitTest,
            circle: {x, y, radius},
            seenUids: {box: {}, circle: {}}
        };
        // $FlowFixMe[method-unbinding]
        this._forEachCell(x1, y1, x2, y2, this._queryCellCircle, result, queryArgs, predicate);
        return hitTest ? result.length > 0 : result;
    }

    query(x1        , y1        , x2        , y2        , predicate      )                  {
        return (this._query(x1, y1, x2, y2, false, predicate)     );
    }

    hitTest(x1        , y1        , x2        , y2        , predicate      )           {
        return (this._query(x1, y1, x2, y2, true, predicate)     );
    }

    hitTestCircle(x        , y        , radius        , predicate      )          {
        return (this._queryCircle(x, y, radius, true, predicate)     );
    }

    _queryCell(x1        , y1        , x2        , y2        , cellIndex        , result     , queryArgs     , predicate      )                 {
        const seenUids = queryArgs.seenUids;
        const boxCell = this.boxCells[cellIndex];
        if (boxCell !== null) {
            const bboxes = this.bboxes;
            for (const boxUid of boxCell) {
                if (!seenUids.box[boxUid]) {
                    seenUids.box[boxUid] = true;
                    const offset = boxUid * 4;
                    if ((x1 <= bboxes[offset + 2]) &&
                        (y1 <= bboxes[offset + 3]) &&
                        (x2 >= bboxes[offset + 0]) &&
                        (y2 >= bboxes[offset + 1]) &&
                        (!predicate || predicate(this.boxKeys[boxUid]))) {
                        if (queryArgs.hitTest) {
                            result.push(true);
                            return true;
                        } else {
                            result.push({
                                key: this.boxKeys[boxUid],
                                x1: bboxes[offset],
                                y1: bboxes[offset + 1],
                                x2: bboxes[offset + 2],
                                y2: bboxes[offset + 3]
                            });
                        }
                    }
                }
            }
        }
        const circleCell = this.circleCells[cellIndex];
        if (circleCell !== null) {
            const circles = this.circles;
            for (const circleUid of circleCell) {
                if (!seenUids.circle[circleUid]) {
                    seenUids.circle[circleUid] = true;
                    const offset = circleUid * 3;
                    if (this._circleAndRectCollide(
                        circles[offset],
                        circles[offset + 1],
                        circles[offset + 2],
                        x1,
                        y1,
                        x2,
                        y2) &&
                        (!predicate || predicate(this.circleKeys[circleUid]))) {
                        if (queryArgs.hitTest) {
                            result.push(true);
                            return true;
                        } else {
                            const x = circles[offset];
                            const y = circles[offset + 1];
                            const radius = circles[offset + 2];
                            result.push({
                                key: this.circleKeys[circleUid],
                                x1: x - radius,
                                y1: y - radius,
                                x2: x + radius,
                                y2: y + radius
                            });
                        }
                    }
                }
            }
        }
    }

    _queryCellCircle(x1        , y1        , x2        , y2        , cellIndex        , result     , queryArgs     , predicate      )                 {
        const circle = queryArgs.circle;
        const seenUids = queryArgs.seenUids;
        const boxCell = this.boxCells[cellIndex];
        if (boxCell !== null) {
            const bboxes = this.bboxes;
            for (const boxUid of boxCell) {
                if (!seenUids.box[boxUid]) {
                    seenUids.box[boxUid] = true;
                    const offset = boxUid * 4;
                    if (this._circleAndRectCollide(
                        circle.x,
                        circle.y,
                        circle.radius,
                        bboxes[offset + 0],
                        bboxes[offset + 1],
                        bboxes[offset + 2],
                        bboxes[offset + 3]) &&
                        (!predicate || predicate(this.boxKeys[boxUid]))) {
                        result.push(true);
                        return true;
                    }
                }
            }
        }

        const circleCell = this.circleCells[cellIndex];
        if (circleCell !== null) {
            const circles = this.circles;
            for (const circleUid of circleCell) {
                if (!seenUids.circle[circleUid]) {
                    seenUids.circle[circleUid] = true;
                    const offset = circleUid * 3;
                    if (this._circlesCollide(
                        circles[offset],
                        circles[offset + 1],
                        circles[offset + 2],
                        circle.x,
                        circle.y,
                        circle.radius) &&
                        (!predicate || predicate(this.circleKeys[circleUid]))) {
                        result.push(true);
                        return true;
                    }
                }
            }
        }
    }

    _forEachCell(x1        , y1        , x2        , y2        , fn     , arg1     , arg2      , predicate      ) {
        const cx1 = this._convertToXCellCoord(x1);
        const cy1 = this._convertToYCellCoord(y1);
        const cx2 = this._convertToXCellCoord(x2);
        const cy2 = this._convertToYCellCoord(y2);

        for (let x = cx1; x <= cx2; x++) {
            for (let y = cy1; y <= cy2; y++) {
                const cellIndex = this.xCellCount * y + x;
                if (fn.call(this, x1, y1, x2, y2, cellIndex, arg1, arg2, predicate)) return;
            }
        }
    }

    _convertToXCellCoord(x        )         {
        return Math.max(0, Math.min(this.xCellCount - 1, Math.floor(x * this.xScale)));
    }

    _convertToYCellCoord(y        )         {
        return Math.max(0, Math.min(this.yCellCount - 1, Math.floor(y * this.yScale)));
    }

    _circlesCollide(x1        , y1        , r1        , x2        , y2        , r2        )          {
        const dx = x2 - x1;
        const dy = y2 - y1;
        const bothRadii = r1 + r2;
        return (bothRadii * bothRadii) > (dx * dx + dy * dy);
    }

    _circleAndRectCollide(circleX        , circleY        , radius        , x1        , y1        , x2        , y2        )          {
        const halfRectWidth = (x2 - x1) / 2;
        const distX = Math.abs(circleX - (x1 + halfRectWidth));
        if (distX > (halfRectWidth + radius)) {
            return false;
        }

        const halfRectHeight = (y2 - y1) / 2;
        const distY = Math.abs(circleY - (y1 + halfRectHeight));
        if (distY > (halfRectHeight + radius)) {
            return false;
        }

        if (distX <= halfRectWidth || distY <= halfRectHeight) {
            return true;
        }

        const dx = distX - halfRectWidth;
        const dy = distY - halfRectHeight;
        return (dx * dx + dy * dy <= (radius * radius));
    }
}

//      


                     
                  
                      
                
                           
            
   
                                           

                        
                            
                            
                         
  

const FlipState = {
    unknown: 0,
    flipRequired: 1,
    flipNotRequired: 2
};

const maxTangent = Math.tan(85 * Math.PI / 180);

/*
 * # Overview of coordinate spaces
 *
 * ## Tile coordinate spaces
 * Each label has an anchor. Some labels have corresponding line geometries.
 * The points for both anchors and lines are stored in tile units. Each tile has it's own
 * coordinate space going from (0, 0) at the top left to (EXTENT, EXTENT) at the bottom right.
 *
 * ## GL coordinate space
 * At the end of everything, the vertex shader needs to produce a position in GL coordinate space,
 * which is (-1, 1) at the top left and (1, -1) in the bottom right.
 *
 * ## Map pixel coordinate spaces
 * Each tile has a pixel coordinate space. It's just the tile units scaled so that one unit is
 * whatever counts as 1 pixel at the current zoom.
 * This space is used for pitch-alignment=map, rotation-alignment=map
 *
 * ## Rotated map pixel coordinate spaces
 * Like the above, but rotated so axis of the space are aligned with the viewport instead of the tile.
 * This space is used for pitch-alignment=map, rotation-alignment=viewport
 *
 * ## Viewport pixel coordinate space
 * (0, 0) is at the top left of the canvas and (pixelWidth, pixelHeight) is at the bottom right corner
 * of the canvas. This space is used for pitch-alignment=viewport
 *
 *
 * # Vertex projection
 * It goes roughly like this:
 * 1. project the anchor and line from tile units into the correct label coordinate space
 *      - map pixel space           pitch-alignment=map         rotation-alignment=map
 *      - rotated map pixel space   pitch-alignment=map         rotation-alignment=viewport
 *      - viewport pixel space      pitch-alignment=viewport    rotation-alignment=*
 * 2. if the label follows a line, find the point along the line that is the correct distance from the anchor.
 * 3. add the glyph's corner offset to the point from step 3
 * 4. convert from the label coordinate space to gl coordinates
 *
 * For horizontal labels we want to do step 1 in the shader for performance reasons (no cpu work).
 *      This is what `u_label_plane_matrix` is used for.
 * For labels aligned with lines we have to steps 1 and 2 on the cpu since we need access to the line geometry.
 *      This is what `updateLineLabels(...)` does.
 *      Since the conversion is handled on the cpu we just set `u_label_plane_matrix` to an identity matrix.
 *
 * Steps 3 and 4 are done in the shaders for all labels.
 */

/*
 * Returns a matrix for converting from tile units to the correct label coordinate space.
 * This variation of the function returns a label space matrix specialized for rendering.
 * It transforms coordinates as-is to whatever the target space is (either 2D or 3D).
 * See also `getLabelPlaneMatrixForPlacement`
 */
function getLabelPlaneMatrixForRendering(posMatrix              ,
                             tileID                 ,
                             pitchWithMap         ,
                             rotateWithMap         ,
                             transform           ,
                             projection            ,
                             pixelsToTileUnits              )               {
    const m = index.create();

    if (pitchWithMap) {
        if (projection.name === 'globe') {
            const lm = index.calculateGlobeLabelMatrix(transform, tileID);
            index.multiply(m, m, lm);
        } else {
            const s = index.invert([], pixelsToTileUnits);
            m[0] = s[0];
            m[1] = s[1];
            m[4] = s[2];
            m[5] = s[3];
            if (!rotateWithMap) {
                index.rotateZ(m, m, transform.angle);
            }
        }
    } else {
        index.multiply(m, transform.labelPlaneMatrix, posMatrix);
    }

    return m;
}

/*
 * Returns a matrix for converting from tile units to the correct label coordinate space.
 * This variation of the function returns a matrix specialized for placement logic.
 * Coordinates will be clamped to x&y 2D plane which is used with viewport and map aligned placement
 * logic in most cases. Certain projections such as globe view will use 3D space for map aligned
 * label placement.
 */
function getLabelPlaneMatrixForPlacement(posMatrix              ,
                             tileID                 ,
                             pitchWithMap         ,
                             rotateWithMap         ,
                             transform           ,
                             projection            ,
                             pixelsToTileUnits              )               {
    const m = getLabelPlaneMatrixForRendering(posMatrix, tileID, pitchWithMap, rotateWithMap, transform, projection, pixelsToTileUnits);

    // Symbol placement logic is performed in 2D in most scenarios.
    // For this reason project all coordinates to the xy-plane by discarding the z-component
    if (projection.name !== 'globe' || !pitchWithMap) {
        // Pre-multiply by scaling z to 0
        m[2] = m[6] = m[10] = m[14] = 0;
    }

    return m;
}

/*
 * Returns a matrix for converting from the correct label coordinate space to gl coords.
 */
function getGlCoordMatrix(posMatrix              ,
                          tileID                 ,
                          pitchWithMap         ,
                          rotateWithMap         ,
                          transform           ,
                          projection            ,
                          pixelsToTileUnits              )               {
    if (pitchWithMap) {
        if (projection.name === 'globe') {
            const m = getLabelPlaneMatrixForRendering(posMatrix, tileID, pitchWithMap, rotateWithMap, transform, projection, pixelsToTileUnits);
            index.invert$1(m, m);
            index.multiply(m, posMatrix, m);
            return m;
        } else {
            const m = index.clone(posMatrix);
            const s = index.identity([]);
            s[0] = pixelsToTileUnits[0];
            s[1] = pixelsToTileUnits[1];
            s[4] = pixelsToTileUnits[2];
            s[5] = pixelsToTileUnits[3];
            index.multiply(m, m, s);
            if (!rotateWithMap) {
                index.rotateZ(m, m, -transform.angle);
            }
            return m;
        }
    } else {
        return transform.glCoordMatrix;
    }
}

function project(x        , y        , z        , matrix      )       {
    const pos = [x, y, z, 1];
    if (z) {
        index.transformMat4$1(pos, pos, matrix);
    } else {
        xyTransformMat4(pos, pos, matrix);
    }
    const w = pos[3];
    pos[0] /= w;
    pos[1] /= w;
    pos[2] /= w;
    return pos;
}

function projectClamped([x, y, z]      , matrix      )       {
    const pos = [x, y, z, 1];
    index.transformMat4$1(pos, pos, matrix);

    // Clamp distance to a positive value so we can avoid screen coordinate
    // being flipped possibly due to perspective projection
    const w = pos[3] = Math.max(pos[3], 0.000001);
    pos[0] /= w;
    pos[1] /= w;
    pos[2] /= w;
    return pos;
}

function getPerspectiveRatio(cameraToCenterDistance        , signedDistanceFromCamera        )         {
    return Math.min(0.5 + 0.5 * (cameraToCenterDistance / signedDistanceFromCamera), 1.5);
}

function isVisible(anchorPos                                  ,
                   clippingBuffer                  ) {
    const x = anchorPos[0] / anchorPos[3];
    const y = anchorPos[1] / anchorPos[3];
    const inPaddedViewport = (
        x >= -clippingBuffer[0] &&
        x <= clippingBuffer[0] &&
        y >= -clippingBuffer[1] &&
        y <= clippingBuffer[1]);
    return inPaddedViewport;
}

/*
 *  Update the `dynamicLayoutVertexBuffer` for the buffer with the correct glyph positions for the current map view.
 *  This is only run on labels that are aligned with lines. Horizontal labels are handled entirely in the shader.
 */
function updateLineLabels(bucket              ,
                          posMatrix              ,
                          painter         ,
                          isText         ,
                          labelPlaneMatrix              ,
                          glCoordMatrix              ,
                          pitchWithMap         ,
                          keepUpright         ,
                          getElevation                                ,
                          tileID                  ) {

    const tr = painter.transform;
    const sizeData = isText ? bucket.textSizeData : bucket.iconSizeData;
    const partiallyEvaluatedSize = index.evaluateSizeForZoom(sizeData, painter.transform.zoom);
    const isGlobe = tr.projection.name === 'globe';

    const clippingBuffer = [256 / painter.width * 2 + 1, 256 / painter.height * 2 + 1];

    const dynamicLayoutVertexArray = isText ?
        bucket.text.dynamicLayoutVertexArray :
        bucket.icon.dynamicLayoutVertexArray;
    dynamicLayoutVertexArray.clear();

    let globeExtVertexArray                       = null;
    if (isGlobe) {
        globeExtVertexArray = isText ?
            bucket.text.globeExtVertexArray :
            bucket.icon.globeExtVertexArray;
    }

    const lineVertexArray = bucket.lineVertexArray;
    const placedSymbols = isText ? bucket.text.placedSymbolArray : bucket.icon.placedSymbolArray;

    const aspectRatio = painter.transform.width / painter.transform.height;

    let useVertical           = false;
    let prevWritingMode;

    for (let s = 0; s < placedSymbols.length; s++) {
        const symbol = placedSymbols.get(s);
        const {numGlyphs, writingMode} = symbol;

        // Normally, the 'Horizontal|Vertical' writing mode is followed by a 'Vertical' counterpart, this
        // is not true for 'Vertical' only line labels. For this case, we'll have to overwrite the 'useVertical'
        // status before further checks.
        if (writingMode === index.WritingMode.vertical && !useVertical && prevWritingMode !== index.WritingMode.horizontal) {
            useVertical = true;
        }
        prevWritingMode = writingMode;

        // Don't do calculations for vertical glyphs unless the previous symbol was horizontal
        // and we determined that vertical glyphs were necessary.
        // Also don't do calculations for symbols that are collided and fully faded out
        if ((symbol.hidden || writingMode === index.WritingMode.vertical) && !useVertical) {
            hideGlyphs(numGlyphs, dynamicLayoutVertexArray);
            continue;
        }
        // Awkward... but we're counting on the paired "vertical" symbol coming immediately after its horizontal counterpart
        useVertical = false;

        // Project tile anchor to globe anchor
        const tileAnchorPoint = new index.Point(symbol.tileAnchorX, symbol.tileAnchorY);
        let {x, y, z} = tr.projection.projectTilePoint(tileAnchorPoint.x, tileAnchorPoint.y, tileID.canonical);
        if (getElevation) {
            const [dx, dy, dz] = getElevation(tileAnchorPoint);
            x += dx;
            y += dy;
            z += dz;
        }
        const anchorPos = [x, y, z, 1.0];
        index.transformMat4$1(anchorPos, anchorPos, posMatrix);

        // Don't bother calculating the correct point for invisible labels.
        if (!isVisible(anchorPos, clippingBuffer)) {
            hideGlyphs(numGlyphs, dynamicLayoutVertexArray);
            continue;
        }
        const cameraToAnchorDistance = anchorPos[3];
        const perspectiveRatio = getPerspectiveRatio(painter.transform.cameraToCenterDistance, cameraToAnchorDistance);

        const fontSize = index.evaluateSizeForFeature(sizeData, partiallyEvaluatedSize, symbol);
        const pitchScaledFontSize = pitchWithMap ? fontSize / perspectiveRatio : fontSize * perspectiveRatio;

        const labelPlaneAnchorPoint = project(x, y, z, labelPlaneMatrix);

        // Skip labels behind the camera
        if (labelPlaneAnchorPoint[3] <= 0.0) {
            hideGlyphs(numGlyphs, dynamicLayoutVertexArray);
            continue;
        }

        let projectionCache                  = {};

        const getElevationForPlacement = pitchWithMap ? null : getElevation; // When pitchWithMap, we're projecting to scaled tile coordinate space: there is no need to get elevation as it doesn't affect projection.
        const placeUnflipped = placeGlyphsAlongLine(symbol, pitchScaledFontSize, false /*unflipped*/, keepUpright, posMatrix, labelPlaneMatrix, glCoordMatrix,
            bucket.glyphOffsetArray, lineVertexArray, dynamicLayoutVertexArray, globeExtVertexArray, labelPlaneAnchorPoint, tileAnchorPoint, projectionCache, aspectRatio, getElevationForPlacement, tr.projection, tileID, pitchWithMap);

        useVertical = placeUnflipped.useVertical;

        if (getElevationForPlacement && placeUnflipped.needsFlipping) projectionCache = {}; // Truncated points should be recalculated.
        if (placeUnflipped.notEnoughRoom || useVertical ||
            (placeUnflipped.needsFlipping &&
             placeGlyphsAlongLine(symbol, pitchScaledFontSize, true /*flipped*/, keepUpright, posMatrix, labelPlaneMatrix, glCoordMatrix,
                 bucket.glyphOffsetArray, lineVertexArray, dynamicLayoutVertexArray, globeExtVertexArray, labelPlaneAnchorPoint, tileAnchorPoint, projectionCache, aspectRatio, getElevationForPlacement, tr.projection, tileID, pitchWithMap).notEnoughRoom)) {
            hideGlyphs(numGlyphs, dynamicLayoutVertexArray);
        }
    }

    if (isText) {
        bucket.text.dynamicLayoutVertexBuffer.updateData(dynamicLayoutVertexArray);
        if (globeExtVertexArray) {
            bucket.text.globeExtVertexBuffer.updateData(globeExtVertexArray);
        }
    } else {
        bucket.icon.dynamicLayoutVertexBuffer.updateData(dynamicLayoutVertexArray);
        if (globeExtVertexArray) {
            bucket.icon.globeExtVertexBuffer.updateData(globeExtVertexArray);
        }
    }
}

function placeFirstAndLastGlyph(
    fontScale        ,
    glyphOffsetArray                  ,
    lineOffsetX        ,
    lineOffsetY        ,
    flip         ,
    anchorPoint      ,
    tileAnchorPoint       ,
    symbol              ,
    lineVertexArray                       ,
    labelPlaneMatrix              ,
    projectionCache                 ,
    getElevation                                ,
    returnPathInTileCoords          ,
    projection            ,
    tileID                  ,
    pitchWithMap         )                                                   {

    const {lineStartIndex, glyphStartIndex, segment} = symbol;
    const glyphEndIndex = glyphStartIndex + symbol.numGlyphs;
    const lineEndIndex = lineStartIndex + symbol.lineLength;

    const firstGlyphOffset = glyphOffsetArray.getoffsetX(glyphStartIndex);
    const lastGlyphOffset = glyphOffsetArray.getoffsetX(glyphEndIndex - 1);

    const firstPlacedGlyph = placeGlyphAlongLine(fontScale * firstGlyphOffset, lineOffsetX, lineOffsetY, flip, anchorPoint, tileAnchorPoint, segment,
        lineStartIndex, lineEndIndex, lineVertexArray, labelPlaneMatrix, projectionCache, getElevation, returnPathInTileCoords, true, projection, tileID, pitchWithMap);
    if (!firstPlacedGlyph)
        return null;

    const lastPlacedGlyph = placeGlyphAlongLine(fontScale * lastGlyphOffset, lineOffsetX, lineOffsetY, flip, anchorPoint, tileAnchorPoint, segment,
        lineStartIndex, lineEndIndex, lineVertexArray, labelPlaneMatrix, projectionCache, getElevation, returnPathInTileCoords, true, projection, tileID, pitchWithMap);
    if (!lastPlacedGlyph)
        return null;

    return {first: firstPlacedGlyph, last: lastPlacedGlyph};
}

// Check in the glCoordinate space, the rough estimation of angle between the text line and the Y axis.
// If the angle if less or equal to 5 degree, then keep the text glyphs unflipped even if it is required.
function isInFlipRetainRange(dx        , dy        ) {
    return dx === 0 || Math.abs(dy / dx) > maxTangent;
}

function requiresOrientationChange(writingMode        , flipState        , dx        , dy        ) {
    if (writingMode === index.WritingMode.horizontal && Math.abs(dy) > Math.abs(dx)) {
        // On top of choosing whether to flip, choose whether to render this version of the glyphs or the alternate
        // vertical glyphs. We can't just filter out vertical glyphs in the horizontal range because the horizontal
        // and vertical versions can have slightly different projections which could lead to angles where both or
        // neither showed.
        return {useVertical: true};
    }
    // Check if flipping is required for "verticalOnly" case.
    if (writingMode === index.WritingMode.vertical) {
        return dy > 0 ? {needsFlipping: true} : null;
    }

    // symbol's flipState stores the flip decision from the previous frame, and that
    // decision is reused when the symbol is in the retain range.
    if (flipState !== FlipState.unknown && isInFlipRetainRange(dx, dy)) {
        return (flipState === FlipState.flipRequired) ? {needsFlipping: true} : null;
    }

    // Check if flipping is required for "horizontal" case.
    return dx < 0 ? {needsFlipping: true} : null;
}

function placeGlyphsAlongLine(symbol              , fontSize        , flip         , keepUpright         , posMatrix              , labelPlaneMatrix              , glCoordMatrix              , glyphOffsetArray                  , lineVertexArray                       , dynamicLayoutVertexArray                          , globeExtVertexArray                      , anchorPoint         , tileAnchorPoint       , projectionCache                 , aspectRatio        , getElevation                                , projection            , tileID                  , pitchWithMap         )                  {
    const fontScale = fontSize / 24;
    const lineOffsetX = symbol.lineOffsetX * fontScale;
    const lineOffsetY = symbol.lineOffsetY * fontScale;
    const {lineStartIndex, glyphStartIndex, numGlyphs, segment, writingMode, flipState} = symbol;
    const lineEndIndex = lineStartIndex + symbol.lineLength;

    const addGlyph = (glyph             ) => {
        if (globeExtVertexArray) {
            const [ux, uy, uz] = glyph.up;
            const offset = dynamicLayoutVertexArray.length;
            index.updateGlobeVertexNormal(globeExtVertexArray, offset + 0, ux, uy, uz);
            index.updateGlobeVertexNormal(globeExtVertexArray, offset + 1, ux, uy, uz);
            index.updateGlobeVertexNormal(globeExtVertexArray, offset + 2, ux, uy, uz);
            index.updateGlobeVertexNormal(globeExtVertexArray, offset + 3, ux, uy, uz);
        }
        const [x, y, z] = glyph.point;
        index.addDynamicAttributes(dynamicLayoutVertexArray, x, y, z, glyph.angle);
    };

    if (numGlyphs > 1) {
        // Place the first and the last glyph in the label first, so we can figure out
        // the overall orientation of the label and determine whether it needs to be flipped in keepUpright mode
        const firstAndLastGlyph = placeFirstAndLastGlyph(fontScale, glyphOffsetArray, lineOffsetX, lineOffsetY, flip, anchorPoint, tileAnchorPoint, symbol, lineVertexArray, labelPlaneMatrix, projectionCache, getElevation, false, projection, tileID, pitchWithMap);
        if (!firstAndLastGlyph) {
            return {notEnoughRoom: true};
        }

        if (keepUpright && !flip) {
            let [x0, y0, z0] = firstAndLastGlyph.first.point;
            let [x1, y1, z1] = firstAndLastGlyph.last.point;
            [x0, y0] = project(x0, y0, z0, glCoordMatrix);
            [x1, y1] = project(x1, y1, z1, glCoordMatrix);
            const orientationChange = requiresOrientationChange(writingMode, flipState, (x1 - x0) * aspectRatio, y1 - y0);
            symbol.flipState = orientationChange && orientationChange.needsFlipping ? FlipState.flipRequired : FlipState.flipNotRequired;
            if (orientationChange) {
                return orientationChange;
            }
        }

        addGlyph(firstAndLastGlyph.first);
        for (let glyphIndex = glyphStartIndex + 1; glyphIndex < glyphStartIndex + numGlyphs - 1; glyphIndex++) {
            // Since first and last glyph fit on the line, the rest of the glyphs can be placed too, but check to make sure
            const glyph = placeGlyphAlongLine(fontScale * glyphOffsetArray.getoffsetX(glyphIndex), lineOffsetX, lineOffsetY, flip, anchorPoint, tileAnchorPoint, segment,
                lineStartIndex, lineEndIndex, lineVertexArray, labelPlaneMatrix, projectionCache, getElevation, false, false, projection, tileID, pitchWithMap);
            if (!glyph) {
                // undo previous glyphs of the symbol if it doesn't fit; it will be filled with hideGlyphs instead
                dynamicLayoutVertexArray.length -= 4 * (glyphIndex - glyphStartIndex);
                return {notEnoughRoom: true};
            }
            addGlyph(glyph);
        }
        addGlyph(firstAndLastGlyph.last);
    } else {
        // Only a single glyph to place
        // So, determine whether to flip based on projected angle of the line segment it's on
        if (keepUpright && !flip) {
            const a = project(tileAnchorPoint.x, tileAnchorPoint.y, 0, posMatrix);
            const tileVertexIndex = lineStartIndex + segment + 1;
            const tileSegmentEnd = new index.Point(lineVertexArray.getx(tileVertexIndex), lineVertexArray.gety(tileVertexIndex));
            const projectedVertex = project(tileSegmentEnd.x, tileSegmentEnd.y, 0, posMatrix);
            // We know the anchor will be in the viewport, but the end of the line segment may be
            // behind the plane of the camera, in which case we can use a point at any arbitrary (closer)
            // point on the segment.
            const b = (projectedVertex[3] > 0) ?
                projectedVertex :
                projectTruncatedLineSegment(tileAnchorPoint, tileSegmentEnd, a, 1, posMatrix, undefined, projection, tileID.canonical);

            const orientationChange = requiresOrientationChange(writingMode, flipState, (b[0] - a[0]) * aspectRatio, b[1] - a[1]);
            symbol.flipState = orientationChange && orientationChange.needsFlipping ? FlipState.flipRequired : FlipState.flipNotRequired;
            if (orientationChange) {
                return orientationChange;
            }
        }
        const singleGlyph = placeGlyphAlongLine(fontScale * glyphOffsetArray.getoffsetX(glyphStartIndex), lineOffsetX, lineOffsetY, flip, anchorPoint, tileAnchorPoint, segment,
            lineStartIndex, lineEndIndex, lineVertexArray, labelPlaneMatrix, projectionCache, getElevation, false, false, projection, tileID, pitchWithMap);
        if (!singleGlyph) {
            return {notEnoughRoom: true};
        }

        addGlyph(singleGlyph);
    }
    return {};
}

function elevatePointAndProject(p       , tileID                 , posMatrix              , projection            , getElevation                                ) {
    const {x, y, z} = projection.projectTilePoint(p.x, p.y, tileID);
    if (!getElevation) {
        return project(x, y, z, posMatrix);
    }
    const [dx, dy, dz] = getElevation(p);
    return project(x + dx, y + dy, z + dz, posMatrix);
}

function projectTruncatedLineSegment(previousTilePoint       , currentTilePoint       , previousProjectedPoint      , minimumLength        , projectionMatrix              , getElevation                                , projection            , tileID                 )       {
    // We are assuming "previousTilePoint" won't project to a point within one unit of the camera plane
    // If it did, that would mean our label extended all the way out from within the viewport to a (very distant)
    // point near the plane of the camera. We wouldn't be able to render the label anyway once it crossed the
    // plane of the camera.
    const unitVertex = previousTilePoint.sub(currentTilePoint)._unit()._add(previousTilePoint);
    const projectedUnit = elevatePointAndProject(unitVertex, tileID, projectionMatrix, projection, getElevation);
    index.sub(projectedUnit, previousProjectedPoint, projectedUnit);
    index.normalize(projectedUnit, projectedUnit);

    return index.scaleAndAdd(projectedUnit, previousProjectedPoint, projectedUnit, minimumLength);
}

function placeGlyphAlongLine(
    offsetX        ,
    lineOffsetX        ,
    lineOffsetY        ,
    flip         ,
    anchorPoint      ,
    tileAnchorPoint       ,
    anchorSegment        ,
    lineStartIndex        ,
    lineEndIndex        ,
    lineVertexArray                       ,
    labelPlaneMatrix              ,
    projectionCache                 ,
    getElevation                                ,
    returnPathInTileCoords          ,
    endGlyph          ,
    reprojection            ,
    tileID                  ,
    pitchWithMap         )                     {

    const combinedOffsetX = flip ?
        offsetX - lineOffsetX :
        offsetX + lineOffsetX;

    let dir = combinedOffsetX > 0 ? 1 : -1;

    let angle = 0;
    if (flip) {
        // The label needs to be flipped to keep text upright.
        // Iterate in the reverse direction.
        dir *= -1;
        angle = Math.PI;
    }

    if (dir < 0) angle += Math.PI;

    let currentIndex = lineStartIndex + anchorSegment + (dir > 0 ? 0 : 1) | 0;
    let current = anchorPoint;
    let prev = anchorPoint;
    let distanceToPrev = 0;
    let currentSegmentDistance = 0;
    const absOffsetX = Math.abs(combinedOffsetX);
    const pathVertices = [];
    const tilePath = [];
    let currentVertex = tileAnchorPoint;
    let prevVertex = currentVertex;

    const getTruncatedLineSegment = () => {
        return projectTruncatedLineSegment(prevVertex, currentVertex, prev, absOffsetX - distanceToPrev + 1, labelPlaneMatrix, getElevation, reprojection, tileID.canonical);
    };

    while (distanceToPrev + currentSegmentDistance <= absOffsetX) {
        currentIndex += dir;

        // offset does not fit on the projected line
        if (currentIndex < lineStartIndex || currentIndex >= lineEndIndex)
            return null;

        prev = current;
        prevVertex = currentVertex;

        pathVertices.push(prev);
        if (returnPathInTileCoords) tilePath.push(prevVertex);

        currentVertex = new index.Point(lineVertexArray.getx(currentIndex), lineVertexArray.gety(currentIndex));
        current = projectionCache[currentIndex];
        if (!current) {
            const projection = elevatePointAndProject(currentVertex, tileID.canonical, labelPlaneMatrix, reprojection, getElevation);
            if (projection[3] > 0) {
                current = projectionCache[currentIndex] = projection;
            } else {
                // The vertex is behind the plane of the camera, so we can't project it
                // Instead, we'll create a vertex along the line that's far enough to include the glyph
                // Don't cache because the new vertex might not be far enough out for future glyphs on the same segment
                current = getTruncatedLineSegment();
            }
        }

        distanceToPrev += currentSegmentDistance;
        currentSegmentDistance = index.distance(prev, current);
    }

    if (endGlyph && getElevation) {
        // For terrain, always truncate end points in order to handle terrain curvature.
        // If previously truncated, on signedDistanceFromCamera < 0, don't do it.
        // Cache as end point. The cache is cleared if there is need for flipping in updateLineLabels.
        if (projectionCache[currentIndex]) {
            current = getTruncatedLineSegment();
            currentSegmentDistance = index.distance(prev, current);
        }
        projectionCache[currentIndex] = current;
    }

    // The point is on the current segment. Interpolate to find it. Compute points on both label plane and tile space
    const segmentInterpolationT = (absOffsetX - distanceToPrev) / currentSegmentDistance;
    const tilePoint = currentVertex.sub(prevVertex)._mult(segmentInterpolationT)._add(prevVertex);
    const prevToCurrent = index.sub([], current, prev);
    const labelPlanePoint = index.scaleAndAdd([], prev, prevToCurrent, segmentInterpolationT);

    let axisZ       = [0, 0, 1];
    let diffX = prevToCurrent[0];
    let diffY = prevToCurrent[1];

    if (pitchWithMap) {
        axisZ = reprojection.upVector(tileID.canonical, tilePoint.x, tilePoint.y);

        if (axisZ[0] !== 0 || axisZ[1] !== 0 || axisZ[2] !== 1) {
            // Compute coordinate frame that is aligned to the tangent of the surface
            const axisX = [axisZ[2], 0, -axisZ[0]];
            const axisY = index.cross([], axisZ, axisX);
            index.normalize(axisX, axisX);
            index.normalize(axisY, axisY);
            diffX = index.dot(prevToCurrent, axisX);
            diffY = index.dot(prevToCurrent, axisY);
        }
    }

    // offset the point from the line to text-offset and icon-offset
    if (lineOffsetY) {
        // Find a coordinate frame for the vertical offset
        const offsetDir = index.cross([], axisZ, prevToCurrent);
        index.normalize(offsetDir, offsetDir);
        index.scaleAndAdd(labelPlanePoint, labelPlanePoint, offsetDir, lineOffsetY * dir);
    }

    const segmentAngle = angle + Math.atan2(diffY, diffX);

    pathVertices.push(labelPlanePoint);
    if (returnPathInTileCoords) {
        tilePath.push(tilePoint);
    }

    return {
        point: labelPlanePoint,
        angle: segmentAngle,
        path: pathVertices,
        tilePath,
        up: axisZ
    };
}

// Hide them by moving them offscreen. We still need to add them to the buffer
// because the dynamic buffer is paired with a static buffer that doesn't get updated.
function hideGlyphs(num        , dynamicLayoutVertexArray                          ) {
    const offset = dynamicLayoutVertexArray.length;
    const end = offset + 4 * num;
    dynamicLayoutVertexArray.resize(end);
    // Since all hidden glyphs have the same attributes, we can build up the array faster with a single call to
    // Float32Array.fill for all vertices, instead of calling addDynamicAttributes for each vertex.
    dynamicLayoutVertexArray.float32.fill(-Infinity, offset * 4, end * 4);
}

// For line label layout, we're not using z output and our w input is always 1
// This custom matrix transformation ignores those components to make projection faster
function xyTransformMat4(out      , a      , m      )       {
    const x = a[0], y = a[1];
    out[0] = m[0] * x + m[4] * y + m[12];
    out[1] = m[1] * x + m[5] * y + m[13];
    out[3] = m[3] * x + m[7] * y + m[15];
    return out;
}

//      


                                                 
                                                              
                                                                                      
                                                                                                  
                                                      
                                          

                                   
                       
                       
                     
   
                                
                           
                       
                               
                     
   
                           
                    
                           
               
                                   
   

// When a symbol crosses the edge that causes it to be included in
// collision detection, it will cause changes in the symbols around
// it. This constant specifies how many pixels to pad the edge of
// the viewport for collision detection so that the bulk of the changes
// occur offscreen. Making this constant greater increases label
// stability, but it's expensive.
const viewportPadding = 100;

/**
 * A collision index used to prevent symbols from overlapping. It keep tracks of
 * where previous symbols have been placed and is used to check if a new
 * symbol overlaps with any previously added symbols.
 *
 * There are two steps to insertion: first placeCollisionBox/Circles checks if
 * there's room for a symbol, then insertCollisionBox/Circles actually puts the
 * symbol in the index. The two step process allows paired symbols to be inserted
 * together even if they overlap.
 *
 * @private
 */
class CollisionIndex {
               
                      
                         
                        
                                
                                 
                              
                               
                        

    constructor(
        transform           ,
        fogState           ,
        grid       = new GridIndex(transform.width + 2 * viewportPadding, transform.height + 2 * viewportPadding, 25),
        ignoredGrid       = new GridIndex(transform.width + 2 * viewportPadding, transform.height + 2 * viewportPadding, 25)
    ) {
        this.transform = transform;

        this.grid = grid;
        this.ignoredGrid = ignoredGrid;
        this.pitchfactor = Math.cos(transform._pitch) * transform.cameraToCenterDistance;

        this.screenRightBoundary = transform.width + viewportPadding;
        this.screenBottomBoundary = transform.height + viewportPadding;
        this.gridRightBoundary = transform.width + 2 * viewportPadding;
        this.gridBottomBoundary = transform.height + 2 * viewportPadding;
        this.fogState = fogState;
    }

    placeCollisionBox(bucket              , scale        , collisionBox                    , shift       , allowOverlap         , textPixelRatio        , posMatrix      , collisionGroupPredicate      )                     {
        index.assert(!this.transform.elevation || collisionBox.elevation !== undefined);

        let anchorX = collisionBox.projectedAnchorX;
        let anchorY = collisionBox.projectedAnchorY;
        let anchorZ = collisionBox.projectedAnchorZ;

        // Apply elevation vector to the anchor point
        const elevation = collisionBox.elevation;
        const tileID = collisionBox.tileID;
        const projection = bucket.getProjection();
        if (elevation && tileID) {
            const [ux, uy, uz] = projection.upVector(tileID.canonical, collisionBox.tileAnchorX, collisionBox.tileAnchorY);
            const upScale = projection.upVectorScale(tileID.canonical, this.transform.center.lat, this.transform.worldSize).metersToTile;

            anchorX += ux * elevation * upScale;
            anchorY += uy * elevation * upScale;
            anchorZ += uz * elevation * upScale;
        }

        const checkOcclusion = projection.name === 'globe' || !!elevation || this.transform.pitch > 0;
        const projectedPoint = this.projectAndGetPerspectiveRatio(posMatrix, anchorX, anchorY, anchorZ, collisionBox.tileID, checkOcclusion, projection);

        const tileToViewport = textPixelRatio * projectedPoint.perspectiveRatio;
        const tlX = (collisionBox.x1 * scale + shift.x - collisionBox.padding) * tileToViewport + projectedPoint.point.x;
        const tlY = (collisionBox.y1 * scale + shift.y - collisionBox.padding) * tileToViewport + projectedPoint.point.y;
        const brX = (collisionBox.x2 * scale + shift.x + collisionBox.padding) * tileToViewport + projectedPoint.point.x;
        const brY = (collisionBox.y2 * scale + shift.y + collisionBox.padding) * tileToViewport + projectedPoint.point.y;
        // Clip at 10 times the distance of the map center or, said otherwise, when the label
        // would be drawn at 10% the size of the features around it without scaling. Refer:
        // https://github.com/mapbox/mapbox-gl-native/wiki/Text-Rendering#perspective-scaling
        // 0.55 === projection.getPerspectiveRatio(camera_to_center, camera_to_center * 10)
        const minPerspectiveRatio = 0.55;
        const isClipped = projectedPoint.perspectiveRatio <= minPerspectiveRatio || projectedPoint.occluded;

        if (!this.isInsideGrid(tlX, tlY, brX, brY) ||
            (!allowOverlap && this.grid.hitTest(tlX, tlY, brX, brY, collisionGroupPredicate)) ||
            isClipped) {
            return {
                box: [],
                offscreen: false,
                occluded: projectedPoint.occluded
            };
        }

        return {
            box: [tlX, tlY, brX, brY],
            offscreen: this.isOffscreen(tlX, tlY, brX, brY),
            occluded: false
        };
    }

    placeCollisionCircles(bucket              ,
                          allowOverlap         ,
                          symbol              ,
                          lineVertexArray                       ,
                          glyphOffsetArray                  ,
                          fontSize        ,
                          posMatrix              ,
                          labelPlaneMatrix              ,
                          labelToScreenMatrix       ,
                          showCollisionCircles         ,
                          pitchWithMap         ,
                          collisionGroupPredicate      ,
                          circlePixelDiameter        ,
                          textPixelPadding        ,
                          tileID                  )                         {
        const placedCollisionCircles = [];
        const elevation = this.transform.elevation;
        const projection = bucket.getProjection();
        const getElevation = elevation ? elevation.getAtTileOffsetFunc(tileID, this.transform.center.lat, this.transform.worldSize, projection) : null;

        const tileUnitAnchorPoint = new index.Point(symbol.tileAnchorX, symbol.tileAnchorY);
        let {x: anchorX, y: anchorY, z: anchorZ} = projection.projectTilePoint(tileUnitAnchorPoint.x, tileUnitAnchorPoint.y, tileID.canonical);
        if (getElevation) {
            const [dx, dy, dz] = getElevation(tileUnitAnchorPoint);
            anchorX += dx;
            anchorY += dy;
            anchorZ += dz;
        }
        const isGlobe = projection.name === 'globe';
        const checkOcclusion = isGlobe || !!elevation || this.transform.pitch > 0;
        const screenAnchorPoint = this.projectAndGetPerspectiveRatio(posMatrix, anchorX, anchorY, anchorZ, tileID, checkOcclusion, projection);
        const {perspectiveRatio} = screenAnchorPoint;
        const labelPlaneFontScale = (pitchWithMap ? fontSize / perspectiveRatio : fontSize * perspectiveRatio) / index.ONE_EM;
        const labelPlaneAnchorPoint = project(anchorX, anchorY, anchorZ, labelPlaneMatrix);

        const projectionCache = {};
        const lineOffsetX = symbol.lineOffsetX * labelPlaneFontScale;
        const lineOffsetY = symbol.lineOffsetY * labelPlaneFontScale;

        const firstAndLastGlyph = screenAnchorPoint.signedDistanceFromCamera > 0 ? placeFirstAndLastGlyph(
            labelPlaneFontScale,
            glyphOffsetArray,
            lineOffsetX,
            lineOffsetY,
            /*flip*/ false,
            labelPlaneAnchorPoint,
            tileUnitAnchorPoint,
            symbol,
            lineVertexArray,
            labelPlaneMatrix,
            projectionCache,
            elevation && !pitchWithMap ? getElevation : null, // pitchWithMap: no need to sample elevation as it has no effect when projecting using scale/rotate to tile space labelPlaneMatrix.
            pitchWithMap && !!elevation,
            projection,
            tileID,
            pitchWithMap
        ) : null;

        let collisionDetected = false;
        let inGrid = false;
        let entirelyOffscreen = true;

        if (firstAndLastGlyph && !screenAnchorPoint.occluded) {
            const radius = circlePixelDiameter * 0.5 * perspectiveRatio + textPixelPadding;
            const screenPlaneMin = new index.Point(-viewportPadding, -viewportPadding);
            const screenPlaneMax = new index.Point(this.screenRightBoundary, this.screenBottomBoundary);
            const interpolator = new PathInterpolator();

            // Construct a projected path from projected line vertices. Anchor points are ignored and removed
            const {first, last} = firstAndLastGlyph;
            const firstLen = first.path.length;

            let projectedPath         = [];
            for (let i = firstLen - 1; i >= 1; i--) {
                projectedPath.push(first.path[i]);
            }
            for (let i = 1; i < last.path.length; i++) {
                projectedPath.push(last.path[i]);
            }
            index.assert(projectedPath.length >= 2);

            // Tolerate a slightly longer distance than one diameter between two adjacent circles
            const circleDist = radius * 2.5;

            // The path might need to be converted into screen space if a pitched map is used as the label space
            if (labelToScreenMatrix) {
                index.assert(pitchWithMap);
                projectedPath = projectedPath.map(([x, y, z], index) => {
                    if (getElevation && !isGlobe) {
                        z = getElevation(index < firstLen - 1 ? first.tilePath[firstLen - 1 - index] : last.tilePath[index - firstLen + 2])[2];
                    }
                    return project(x, y, z, labelToScreenMatrix);
                });

                // Do not try to place collision circles if even of the points is behind the camera.
                // This is a plausible scenario with big camera pitch angles
                if (projectedPath.some(point => point[3] <= 0)) {
                    projectedPath = [];
                }
            }

            let segments = [];

            if (projectedPath.length > 0) {
                // Quickly check if the path is fully inside or outside of the padded collision region.
                // For overlapping paths we'll only create collision circles for the visible segments
                let minx = Infinity;
                let maxx = -Infinity;
                let miny = Infinity;
                let maxy = -Infinity;

                for (const p of projectedPath) {
                    minx = Math.min(minx, p[0]);
                    miny = Math.min(miny, p[1]);
                    maxx = Math.max(maxx, p[0]);
                    maxy = Math.max(maxy, p[1]);
                }

                // Path visible
                if (maxx >= screenPlaneMin.x && minx <= screenPlaneMax.x &&
                    maxy >= screenPlaneMin.y && miny <= screenPlaneMax.y) {

                    segments = [projectedPath.map(p => new index.Point(p[0], p[1]))];

                    if (minx < screenPlaneMin.x || maxx > screenPlaneMax.x ||
                        miny < screenPlaneMin.y || maxy > screenPlaneMax.y) {
                        // Path partially visible, clip
                        segments = index.clipLine(segments, screenPlaneMin.x, screenPlaneMin.y, screenPlaneMax.x, screenPlaneMax.y);
                    }
                }
            }

            for (const seg of segments) {
                // interpolate positions for collision circles. Add a small padding to both ends of the segment
                index.assert(seg.length > 0);
                interpolator.reset(seg, radius * 0.25);

                let numCircles = 0;

                if (interpolator.length <= 0.5 * radius) {
                    numCircles = 1;
                } else {
                    numCircles = Math.ceil(interpolator.paddedLength / circleDist) + 1;
                }

                for (let i = 0; i < numCircles; i++) {
                    const t = i / Math.max(numCircles - 1, 1);
                    const circlePosition = interpolator.lerp(t);

                    // add viewport padding to the position and perform initial collision check
                    const centerX = circlePosition.x + viewportPadding;
                    const centerY = circlePosition.y + viewportPadding;

                    placedCollisionCircles.push(centerX, centerY, radius, 0);

                    const x1 = centerX - radius;
                    const y1 = centerY - radius;
                    const x2 = centerX + radius;
                    const y2 = centerY + radius;

                    entirelyOffscreen = entirelyOffscreen && this.isOffscreen(x1, y1, x2, y2);
                    inGrid = inGrid || this.isInsideGrid(x1, y1, x2, y2);

                    if (!allowOverlap) {
                        if (this.grid.hitTestCircle(centerX, centerY, radius, collisionGroupPredicate)) {
                            // Don't early exit if we're showing the debug circles because we still want to calculate
                            // which circles are in use
                            collisionDetected = true;
                            if (!showCollisionCircles) {
                                return {
                                    circles: [],
                                    offscreen: false,
                                    collisionDetected,
                                    occluded: false
                                };
                            }
                        }
                    }
                }
            }
        }

        return {
            circles: ((!showCollisionCircles && collisionDetected) || !inGrid) ? [] : placedCollisionCircles,
            offscreen: entirelyOffscreen,
            collisionDetected,
            occluded: screenAnchorPoint.occluded
        };
    }

    /**
     * Because the geometries in the CollisionIndex are an approximation of the shape of
     * symbols on the map, we use the CollisionIndex to look up the symbol part of
     * `queryRenderedFeatures`.
     *
     * @private
     */
    queryRenderedSymbols(viewportQueryGeometry              )                                {
        if (viewportQueryGeometry.length === 0 || (this.grid.keysLength() === 0 && this.ignoredGrid.keysLength() === 0)) {
            return {};
        }

        const query = [];
        let minX = Infinity;
        let minY = Infinity;
        let maxX = -Infinity;
        let maxY = -Infinity;
        for (const point of viewportQueryGeometry) {
            const gridPoint = new index.Point(point.x + viewportPadding, point.y + viewportPadding);
            minX = Math.min(minX, gridPoint.x);
            minY = Math.min(minY, gridPoint.y);
            maxX = Math.max(maxX, gridPoint.x);
            maxY = Math.max(maxY, gridPoint.y);
            query.push(gridPoint);
        }

        const features = this.grid.query(minX, minY, maxX, maxY)
            .concat(this.ignoredGrid.query(minX, minY, maxX, maxY));

        const seenFeatures = {};
        const result = {};

        for (const feature of features) {
            const featureKey = feature.key;
            // Skip already seen features.
            if (seenFeatures[featureKey.bucketInstanceId] === undefined) {
                seenFeatures[featureKey.bucketInstanceId] = {};
            }
            if (seenFeatures[featureKey.bucketInstanceId][featureKey.featureIndex]) {
                continue;
            }

            // Check if query intersects with the feature box
            // "Collision Circles" for line labels are treated as boxes here
            // Since there's no actual collision taking place, the circle vs. square
            // distinction doesn't matter as much, and box geometry is easier
            // to work with.
            const bbox = [
                new index.Point(feature.x1, feature.y1),
                new index.Point(feature.x2, feature.y1),
                new index.Point(feature.x2, feature.y2),
                new index.Point(feature.x1, feature.y2)
            ];
            if (!index.polygonIntersectsPolygon(query, bbox)) {
                continue;
            }

            seenFeatures[featureKey.bucketInstanceId][featureKey.featureIndex] = true;
            if (result[featureKey.bucketInstanceId] === undefined) {
                result[featureKey.bucketInstanceId] = [];
            }
            result[featureKey.bucketInstanceId].push(featureKey.featureIndex);
        }

        return result;
    }

    insertCollisionBox(collisionBox               , ignorePlacement         , bucketInstanceId        , featureIndex        , collisionGroupID        ) {
        const grid = ignorePlacement ? this.ignoredGrid : this.grid;

        const key = {bucketInstanceId, featureIndex, collisionGroupID};
        grid.insert(key, collisionBox[0], collisionBox[1], collisionBox[2], collisionBox[3]);
    }

    insertCollisionCircles(collisionCircles               , ignorePlacement         , bucketInstanceId        , featureIndex        , collisionGroupID        ) {
        const grid = ignorePlacement ? this.ignoredGrid : this.grid;

        const key = {bucketInstanceId, featureIndex, collisionGroupID};
        for (let k = 0; k < collisionCircles.length; k += 4) {
            grid.insertCircle(key, collisionCircles[k], collisionCircles[k + 1], collisionCircles[k + 2]);
        }
    }

    projectAndGetPerspectiveRatio(posMatrix      , x        , y        , z        , tileID                   , checkOcclusion         , bucketProjection            )                    {
        const p = [x, y, z, 1];
        let behindFog = false;
        if (z || this.transform.pitch > 0) {
            index.transformMat4$1(p, p, posMatrix);
            // Do not perform symbol occlusion on globe due to fog fixed range
            const isGlobe = bucketProjection.name === 'globe';
            if (this.fogState && tileID && !isGlobe) {
                const fogOpacity = getFogOpacityAtTileCoord(this.fogState, x, y, z, tileID.toUnwrapped(), this.transform);
                behindFog = fogOpacity > FOG_SYMBOL_CLIPPING_THRESHOLD;
            }
        } else {
            xyTransformMat4(p, p, posMatrix);
        }
        const w = p[3];
        const a = new index.Point(
            (((p[0] / w + 1) / 2) * this.transform.width) + viewportPadding,
            (((-p[1] / w + 1) / 2) * this.transform.height) + viewportPadding
        );
        return {
            point: a,
            // See perspective ratio comment in symbol_sdf.vertex
            // We're doing collision detection in viewport space so we need
            // to scale down boxes in the distance
            perspectiveRatio: Math.min(0.5 + 0.5 * (this.transform.getCameraToCenterDistance(bucketProjection) / w), 1.5),
            signedDistanceFromCamera: w,
            occluded: (checkOcclusion && p[2] > w) || behindFog // Occluded by the far plane
        };
    }

    isOffscreen(x1        , y1        , x2        , y2        )          {
        return x2 < viewportPadding || x1 >= this.screenRightBoundary || y2 < viewportPadding || y1 > this.screenBottomBoundary;
    }

    isInsideGrid(x1        , y1        , x2        , y2        )          {
        return x2 >= 0 && x1 < this.gridRightBoundary && y2 >= 0 && y1 < this.gridBottomBoundary;
    }

    /*
    * Returns a matrix for transforming collision shapes to viewport coordinate space.
    * Use this function to render e.g. collision circles on the screen.
    *   example transformation: clipPos = glCoordMatrix * viewportMatrix * circle_pos
    */
    getViewportMatrix()       {
        const m = index.identity([]);
        index.translate(m, m, [-viewportPadding, -viewportPadding, 0.0]);
        return m;
    }
}

//      
                                                              

function reconstructTileMatrix(transform           , projection            , coord                  ) {
    // Bucket being rendered is built for different map projection
    // than is currently being used. Reconstruct correct matrices.
    // This code path may happen during a Globe - Mercator transition
    const tileMatrix = projection.createTileMatrix(transform, transform.worldSize, coord.toUnwrapped());
    return index.multiply(new Float32Array(16), transform.projMatrix, tileMatrix);
}

function getCollisionDebugTileProjectionMatrix(coord                  , bucket              , transform           )               {
    if (bucket.projection.name === transform.projection.name) {
        index.assert(coord.projMatrix);
        return coord.projMatrix;
    }
    const tr = transform.clone();
    tr.setProjection(bucket.projection);
    return reconstructTileMatrix(tr, bucket.getProjection(), coord);
}

function getSymbolTileProjectionMatrix(coord                  , bucketProjection            , transform           )               {
    if (bucketProjection.name === transform.projection.name) {
        index.assert(coord.projMatrix);
        return coord.projMatrix;
    }
    return reconstructTileMatrix(transform, bucketProjection, coord);
}

function getSymbolPlacementTileProjectionMatrix(coord                  , bucketProjection            , transform           , runtimeProjection        )               {
    if (bucketProjection.name === runtimeProjection) {
        return transform.calculateProjMatrix(coord.toUnwrapped());
    }
    index.assert(transform.projection.name === bucketProjection.name);
    return reconstructTileMatrix(transform, bucketProjection, coord);
}

//      

                                                           
                                                   
                                                      
                                    
                                                             

// PlacedCollisionBox with all fields optional
                                                                          

class OpacityState {
                    
                    
    constructor(prevState               , increment        , placed         , skipFade          ) {
        if (prevState) {
            this.opacity = Math.max(0, Math.min(1, prevState.opacity + (prevState.placed ? increment : -increment)));
        } else {
            this.opacity = (skipFade && placed) ? 1 : 0;
        }
        this.placed = placed;
    }
    isHidden()          {
        return this.opacity === 0 && !this.placed;
    }
}

class JointOpacityState {
                       
                       
                     
    constructor(prevState                    , increment        , placedText         , placedIcon         , skipFade          , clipped          = false) {
        this.text = new OpacityState(prevState ? prevState.text : null, increment, placedText, skipFade);
        this.icon = new OpacityState(prevState ? prevState.icon : null, increment, placedIcon, skipFade);

        this.clipped = clipped;
    }
    isHidden()          {
        return this.text.isHidden() && this.icon.isHidden();
    }
}

class JointPlacement {
                  
                  
    // skipFade = outside viewport, but within CollisionIndex::viewportPadding px of the edge
    // Because these symbols aren't onscreen yet, we can skip the "fade in" animation,
    // and if a subsequent viewport change brings them into view, they'll be fully
    // visible right away.
                      

                    
    constructor(text         , icon         , skipFade         , clipped          = false) {
        this.text = text;
        this.icon = icon;
        this.skipFade = skipFade;
        this.clipped = clipped;
    }
}

class CollisionCircleArray {
    // Stores collision circles and placement matrices of a bucket for debug rendering.
                        
                         
                           

    constructor() {
        this.invProjMatrix = index.create();
        this.viewportMatrix = index.create();
        this.circles = [];
    }
}

class RetainedQueryData {
                             
                               
                             
                        
                             
                                    
    constructor(bucketInstanceId        ,
                featureIndex              ,
                sourceLayerIndex        ,
                bucketIndex        ,
                tileID                  ) {
        this.bucketInstanceId = bucketInstanceId;
        this.featureIndex = featureIndex;
        this.sourceLayerIndex = sourceLayerIndex;
        this.bucketIndex = bucketIndex;
        this.tileID = tileID;
    }
}

                                                      

class CollisionGroups {
                                                           
                       
                                   

    constructor(crossSourceCollisions         ) {
        this.crossSourceCollisions = crossSourceCollisions;
        this.maxGroupID = 0;
        this.collisionGroups = {};
    }

    get(sourceID        )                 {
        // The predicate/groupID mechanism allows for arbitrary grouping,
        // but the current interface defines one source == one group when
        // crossSourceCollisions == true.
        if (!this.crossSourceCollisions) {
            if (!this.collisionGroups[sourceID]) {
                const nextGroupID = ++this.maxGroupID;
                this.collisionGroups[sourceID] = {
                    ID: nextGroupID,
                    predicate: (key) => {
                        return key.collisionGroupID === nextGroupID;
                    }
                };
            }
            return this.collisionGroups[sourceID];
        } else {
            return {ID: 0, predicate: null};
        }
    }
}

function calculateVariableLayoutShift(anchor            , width        , height        , textOffset                  , textScale        )        {
    const {horizontalAlign, verticalAlign} = index.getAnchorAlignment(anchor);
    const shiftX = -(horizontalAlign - 0.5) * width;
    const shiftY = -(verticalAlign - 0.5) * height;
    const offset = index.evaluateVariableOffset(anchor, textOffset);
    return new index.Point(
        shiftX + offset[0] * textScale,
        shiftY + offset[1] * textScale
    );
}

function offsetShift(shiftX        , shiftY        , rotateWithMap         , pitchWithMap         , angle        )        {
    const shift = new index.Point(shiftX, shiftY);
    if (rotateWithMap) {
        shift._rotate(pitchWithMap ? angle : -angle);
    }
    return shift;
}

                              
                                 
                  
                   
                       
                      
                           
  

                            
                         
                
                    
                               
                               
                  
                           
                            
                                          
                                    
                       
  

                          
                            
                                
                              
                                   
  

                                          

class Placement {
                       
                         
                                   
                                                     
                                                       
                                                         
                                                    
                       
                               
                                    
                   
                         
                                                        
                                     
                              
                                   
                                                         

    constructor(transform           , fadeDuration        , crossSourceCollisions         , prevPlacement            , fogState           ) {
        this.transform = transform.clone();
        this.projection = transform.projection.name;
        this.collisionIndex = new CollisionIndex(this.transform, fogState);
        this.placements = {};
        this.opacities = {};
        this.variableOffsets = {};
        this.stale = false;
        this.commitTime = 0;
        this.fadeDuration = fadeDuration;
        this.retainedQueryData = {};
        this.collisionGroups = new CollisionGroups(crossSourceCollisions);
        this.collisionCircleArrays = {};

        this.prevPlacement = prevPlacement;
        if (prevPlacement) {
            prevPlacement.prevPlacement = undefined; // Only hold on to one placement back
        }

        this.placedOrientations = {};
    }

    getBucketParts(results                   , styleLayer            , tile      , sortAcrossTiles         ) {
        const symbolBucket = ((tile.getBucket(styleLayer)     )              );
        const bucketFeatureIndex = tile.latestFeatureIndex;

        if (!symbolBucket || !bucketFeatureIndex || styleLayer.id !== symbolBucket.layerIds[0])
            return;

        const layout = symbolBucket.layers[0].layout;

        const collisionBoxArray = tile.collisionBoxArray;
        const scale = Math.pow(2, this.transform.zoom - tile.tileID.overscaledZ);
        const textPixelRatio = tile.tileSize / index.EXTENT;
        const unwrappedTileID = tile.tileID.toUnwrapped();

        this.transform.setProjection(symbolBucket.projection);

        const posMatrix = getSymbolPlacementTileProjectionMatrix(tile.tileID, symbolBucket.getProjection(), this.transform, this.projection);

        const pitchWithMap = layout.get('text-pitch-alignment') === 'map';
        const rotateWithMap = layout.get('text-rotation-alignment') === 'map';

        styleLayer.compileFilter();

        const dynamicFilter = styleLayer.dynamicFilter();
        const dynamicFilterNeedsFeature = styleLayer.dynamicFilterNeedsFeature();
        const pixelsToTiles = this.transform.calculatePixelsToTileUnitsMatrix(tile);

        const textLabelPlaneMatrix = getLabelPlaneMatrixForPlacement(posMatrix,
                tile.tileID.canonical,
                pitchWithMap,
                rotateWithMap,
                this.transform,
                symbolBucket.getProjection(),
                pixelsToTiles);

        let labelToScreenMatrix = null;

        if (pitchWithMap) {
            const glMatrix = getGlCoordMatrix(
                posMatrix,
                tile.tileID.canonical,
                pitchWithMap,
                rotateWithMap,
                this.transform,
                symbolBucket.getProjection(),
                pixelsToTiles);

            labelToScreenMatrix = index.multiply([], this.transform.labelPlaneMatrix, glMatrix);
        }

        let clippingData = null;
        index.assert(!!tile.latestFeatureIndex);
        if (!!dynamicFilter && tile.latestFeatureIndex) {

            clippingData = {
                unwrappedTileID,
                dynamicFilter,
                dynamicFilterNeedsFeature,
                featureIndex: tile.latestFeatureIndex
            };
        }

        // As long as this placement lives, we have to hold onto this bucket's
        // matching FeatureIndex/data for querying purposes
        this.retainedQueryData[symbolBucket.bucketInstanceId] = new RetainedQueryData(
            symbolBucket.bucketInstanceId,
            bucketFeatureIndex,
            symbolBucket.sourceLayerIndex,
            symbolBucket.index,
            tile.tileID
        );

        const parameters = {
            bucket: symbolBucket,
            layout,
            posMatrix,
            textLabelPlaneMatrix,
            labelToScreenMatrix,
            clippingData,
            scale,
            textPixelRatio,
            holdingForFade: tile.holdingForFade(),
            collisionBoxArray,
            partiallyEvaluatedTextSize: index.evaluateSizeForZoom(symbolBucket.textSizeData, this.transform.zoom),
            partiallyEvaluatedIconSize: index.evaluateSizeForZoom(symbolBucket.iconSizeData, this.transform.zoom),
            collisionGroup: this.collisionGroups.get(symbolBucket.sourceID)
        };

        if (sortAcrossTiles) {
            for (const range of symbolBucket.sortKeyRanges) {
                const {sortKey, symbolInstanceStart, symbolInstanceEnd} = range;
                results.push({sortKey, symbolInstanceStart, symbolInstanceEnd, parameters});
            }
        } else {
            results.push({
                symbolInstanceStart: 0,
                symbolInstanceEnd: symbolBucket.symbolInstances.length,
                parameters
            });
        }
    }

    attemptAnchorPlacement(anchor            , textBox                    , width        , height        ,
                           textScale        , rotateWithMap         , pitchWithMap         , textPixelRatio        ,
                           posMatrix      , collisionGroup                , textAllowOverlap         ,
                           symbolInstance                , boxIndex        , bucket              ,
                           orientation        , iconBox                     , textSize     , iconSize     )                                                           {

        const {textOffset0, textOffset1, crossTileID} = symbolInstance;
        const textOffset = [textOffset0, textOffset1];
        const shift = calculateVariableLayoutShift(anchor, width, height, textOffset, textScale);

        const placedGlyphBoxes = this.collisionIndex.placeCollisionBox(
            bucket, textScale, textBox, offsetShift(shift.x, shift.y, rotateWithMap, pitchWithMap, this.transform.angle),
            textAllowOverlap, textPixelRatio, posMatrix, collisionGroup.predicate);
        if (iconBox) {
            const size = bucket.getSymbolInstanceIconSize(iconSize, this.transform.zoom, symbolInstance.placedIconSymbolIndex);
            const placedIconBoxes = this.collisionIndex.placeCollisionBox(
                bucket, size,
                iconBox, offsetShift(shift.x, shift.y, rotateWithMap, pitchWithMap, this.transform.angle),
                textAllowOverlap, textPixelRatio, posMatrix, collisionGroup.predicate);
            if (placedIconBoxes.box.length === 0) return;
        }

        if (placedGlyphBoxes.box.length > 0) {
            let prevAnchor;
            // If this label was placed in the previous placement, record the anchor position
            // to allow us to animate the transition
            if (this.prevPlacement &&
                this.prevPlacement.variableOffsets[crossTileID] &&
                this.prevPlacement.placements[crossTileID] &&
                this.prevPlacement.placements[crossTileID].text) {
                prevAnchor = this.prevPlacement.variableOffsets[crossTileID].anchor;
            }
            index.assert(crossTileID !== 0);
            this.variableOffsets[crossTileID] = {
                textOffset,
                width,
                height,
                anchor,
                textScale,
                prevAnchor
            };
            this.markUsedJustification(bucket, anchor, symbolInstance, orientation);

            if (bucket.allowVerticalPlacement) {
                this.markUsedOrientation(bucket, orientation, symbolInstance);
                this.placedOrientations[crossTileID] = orientation;
            }

            return {shift, placedGlyphBoxes};
        }
    }

    placeLayerBucketPart(bucketPart        , seenCrossTileIDs             , showCollisionBoxes         , updateCollisionBoxIfNecessary         ) {

        const {
            bucket,
            layout,
            posMatrix,
            textLabelPlaneMatrix,
            labelToScreenMatrix,
            clippingData,
            textPixelRatio,
            holdingForFade,
            collisionBoxArray,
            partiallyEvaluatedTextSize,
            partiallyEvaluatedIconSize,
            collisionGroup
        } = bucketPart.parameters;

        const textOptional = layout.get('text-optional');
        const iconOptional = layout.get('icon-optional');
        const textAllowOverlap = layout.get('text-allow-overlap');
        const iconAllowOverlap = layout.get('icon-allow-overlap');
        const rotateWithMap = layout.get('text-rotation-alignment') === 'map';
        const pitchWithMap = layout.get('text-pitch-alignment') === 'map';
        const hasIconTextFit = layout.get('icon-text-fit') !== 'none';
        const zOrderByViewportY = layout.get('symbol-z-order') === 'viewport-y';

        this.transform.setProjection(bucket.projection);

        // This logic is similar to the "defaultOpacityState" logic below in updateBucketOpacities
        // If we know a symbol is always supposed to show, force it to be marked visible even if
        // it wasn't placed into the collision index (because some or all of it was outside the range
        // of the collision grid).
        // There is a subtle edge case here we're accepting:
        //  Symbol A has text-allow-overlap: true, icon-allow-overlap: true, icon-optional: false
        //  A's icon is outside the grid, so doesn't get placed
        //  A's text would be inside grid, but doesn't get placed because of icon-optional: false
        //  We still show A because of the allow-overlap settings.
        //  Symbol B has allow-overlap: false, and gets placed where A's text would be
        //  On panning in, there is a short period when Symbol B and Symbol A will overlap
        //  This is the reverse of our normal policy of "fade in on pan", but should look like any other
        //  collision and hopefully not be too noticeable.
        // See https://github.com/mapbox/mapbox-gl-js/issues/7172
        let alwaysShowText = textAllowOverlap && (iconAllowOverlap || !bucket.hasIconData() || iconOptional);
        let alwaysShowIcon = iconAllowOverlap && (textAllowOverlap || !bucket.hasTextData() || textOptional);

        if (!bucket.collisionArrays && collisionBoxArray) {
            bucket.deserializeCollisionBoxes(collisionBoxArray);
        }

        if (showCollisionBoxes && updateCollisionBoxIfNecessary) {
            bucket.updateCollisionDebugBuffers(this.transform.zoom, collisionBoxArray);
        }

        const placeSymbol = (symbolInstance                , boxIndex        , collisionArrays                 ) => {
            const {crossTileID, numVerticalGlyphVertices} = symbolInstance;

            if (clippingData) {
                // Setup globals
                const globals = {
                    zoom: this.transform.zoom,
                    pitch: this.transform.pitch,
                };

                // Deserialize feature only if necessary
                let feature = null;
                if (clippingData.dynamicFilterNeedsFeature) {
                    const featureIndex = clippingData.featureIndex;
                    const retainedQueryData = this.retainedQueryData[bucket.bucketInstanceId];
                    feature = featureIndex.loadFeature({
                        featureIndex: symbolInstance.featureIndex,
                        bucketIndex: retainedQueryData.bucketIndex,
                        sourceLayerIndex: retainedQueryData.sourceLayerIndex,
                        layoutVertexArrayOffset: 0
                    });
                }
                const canonicalTileId = this.retainedQueryData[bucket.bucketInstanceId].tileID.canonical;

                const filterFunc = clippingData.dynamicFilter;
                const shouldClip = !filterFunc(globals, feature, canonicalTileId, new index.Point(symbolInstance.tileAnchorX, symbolInstance.tileAnchorY), this.transform.calculateDistanceTileData(clippingData.unwrappedTileID));

                if (shouldClip) {
                    this.placements[crossTileID] = new JointPlacement(false, false, false, true);
                    seenCrossTileIDs.add(crossTileID);
                    return;
                }
            }

            if (seenCrossTileIDs.has(crossTileID)) return;
            if (holdingForFade) {
                // Mark all symbols from this tile as "not placed", but don't add to seenCrossTileIDs, because we don't
                // know yet if we have a duplicate in a parent tile that _should_ be placed.
                this.placements[crossTileID] = new JointPlacement(false, false, false);
                return;
            }
            let placeText           = false;
            let placeIcon           = false;
            let offscreen           = true;
            let textOccluded           = false;
            let iconOccluded = false;
            let shift = null;

            let placed                            = {box: null, offscreen: null, occluded: null};
            let placedVerticalText                            = {box: null, offscreen: null, occluded: null};

            let placedGlyphBoxes = null;
            let placedGlyphCircles = null;
            let placedIconBoxes = null;
            let textFeatureIndex = 0;
            let verticalTextFeatureIndex = 0;
            let iconFeatureIndex = 0;

            if (collisionArrays.textFeatureIndex) {
                textFeatureIndex = collisionArrays.textFeatureIndex;
            } else if (symbolInstance.useRuntimeCollisionCircles) {
                textFeatureIndex = symbolInstance.featureIndex;
            }
            if (collisionArrays.verticalTextFeatureIndex) {
                verticalTextFeatureIndex = collisionArrays.verticalTextFeatureIndex;
            }

            const updateBoxData = (box                    ) => {
                box.tileID = this.retainedQueryData[bucket.bucketInstanceId].tileID;
                const elevation = this.transform.elevation;
                if (!elevation && !box.elevation) return;
                box.elevation = elevation ? elevation.getAtTileOffset(box.tileID, box.tileAnchorX, box.tileAnchorY) : 0;
            };

            const textBox = collisionArrays.textBox;
            if (textBox) {
                updateBoxData(textBox);
                const updatePreviousOrientationIfNotPlaced = (isPlaced         ) => {
                    let previousOrientation = index.WritingMode.horizontal;
                    if (bucket.allowVerticalPlacement && !isPlaced && this.prevPlacement) {
                        const prevPlacedOrientation = this.prevPlacement.placedOrientations[crossTileID];
                        if (prevPlacedOrientation) {
                            this.placedOrientations[crossTileID] = prevPlacedOrientation;
                            previousOrientation = prevPlacedOrientation;
                            this.markUsedOrientation(bucket, previousOrientation, symbolInstance);
                        }
                    }
                    return previousOrientation;
                };

                const placeTextForPlacementModes = (placeHorizontalFn                                 , placeVerticalFn                                 ) => {
                    if (bucket.allowVerticalPlacement && numVerticalGlyphVertices > 0 && collisionArrays.verticalTextBox) {
                        for (const placementMode of bucket.writingModes) {
                            if (placementMode === index.WritingMode.vertical) {
                                placed = placeVerticalFn();
                                placedVerticalText = placed;
                            } else {
                                placed = placeHorizontalFn();
                            }
                            if (placed && placed.box && placed.box.length) break;
                        }
                    } else {
                        placed = placeHorizontalFn();
                    }
                };

                if (!layout.get('text-variable-anchor')) {
                    const placeBox = (collisionTextBox                    , orientation        ) => {
                        const textScale = bucket.getSymbolInstanceTextSize(partiallyEvaluatedTextSize, symbolInstance, this.transform.zoom, boxIndex);
                        const placedFeature = this.collisionIndex.placeCollisionBox(bucket, textScale, collisionTextBox,
                            new index.Point(0, 0), textAllowOverlap, textPixelRatio, posMatrix, collisionGroup.predicate);
                        if (placedFeature && placedFeature.box && placedFeature.box.length) {
                            this.markUsedOrientation(bucket, orientation, symbolInstance);
                            this.placedOrientations[crossTileID] = orientation;
                        }
                        return placedFeature;
                    };

                    const placeHorizontal                           = () => {
                        return placeBox(textBox, index.WritingMode.horizontal);
                    };

                    const placeVertical                                                       = () => {
                        const verticalTextBox = collisionArrays.verticalTextBox;
                        if (bucket.allowVerticalPlacement && numVerticalGlyphVertices > 0 && verticalTextBox) {
                            updateBoxData(verticalTextBox);
                            return placeBox(verticalTextBox, index.WritingMode.vertical);
                        }
                        return {box: null, offscreen: null, occluded: null};
                    };

                    placeTextForPlacementModes(
                        ((placeHorizontal     )                                 ),
                        ((placeVertical     )                                 ),
                    );

                    const isPlaced = placed && placed.box && placed.box.length;
                    updatePreviousOrientationIfNotPlaced(!!isPlaced);

                } else {
                    let anchors = layout.get('text-variable-anchor');

                    // If this symbol was in the last placement, shift the previously used
                    // anchor to the front of the anchor list, only if the previous anchor
                    // is still in the anchor list
                    if (this.prevPlacement && this.prevPlacement.variableOffsets[crossTileID]) {
                        const prevOffsets = this.prevPlacement.variableOffsets[crossTileID];
                        if (anchors.indexOf(prevOffsets.anchor) > 0) {
                            anchors = anchors.filter(anchor => anchor !== prevOffsets.anchor);
                            anchors.unshift(prevOffsets.anchor);
                        }
                    }

                    const placeBoxForVariableAnchors = (collisionTextBox                    , collisionIconBox                     , orientation        ) => {
                        const textScale = bucket.getSymbolInstanceTextSize(partiallyEvaluatedTextSize, symbolInstance, this.transform.zoom, boxIndex);
                        const width = (collisionTextBox.x2 - collisionTextBox.x1) * textScale + 2.0 * collisionTextBox.padding;
                        const height = (collisionTextBox.y2 - collisionTextBox.y1) * textScale + 2.0 * collisionTextBox.padding;

                        const variableIconBox = hasIconTextFit && !iconAllowOverlap ? collisionIconBox : null;
                        if (variableIconBox) updateBoxData(variableIconBox);

                        let placedBox                            = {box: [], offscreen: false, occluded: false};
                        const placementAttempts = textAllowOverlap ? anchors.length * 2 : anchors.length;
                        for (let i = 0; i < placementAttempts; ++i) {
                            const anchor = anchors[i % anchors.length];
                            const allowOverlap = (i >= anchors.length);
                            const result = this.attemptAnchorPlacement(
                                anchor, collisionTextBox, width, height, textScale, rotateWithMap,
                                pitchWithMap, textPixelRatio, posMatrix, collisionGroup, allowOverlap,
                                symbolInstance, boxIndex, bucket, orientation, variableIconBox,
                                partiallyEvaluatedTextSize, partiallyEvaluatedIconSize);

                            if (result) {
                                placedBox = ((result.placedGlyphBoxes     )                           );
                                if (placedBox && placedBox.box && placedBox.box.length) {
                                    placeText = true;
                                    shift = result.shift;
                                    break;
                                }
                            }
                        }

                        return placedBox;
                    };

                    const placeHorizontal = () => {
                        return placeBoxForVariableAnchors(textBox, collisionArrays.iconBox, index.WritingMode.horizontal);
                    };

                    const placeVertical = () => {
                        const verticalTextBox = collisionArrays.verticalTextBox;
                        if (verticalTextBox) updateBoxData(verticalTextBox);
                        const wasPlaced = placed && placed.box && placed.box.length;
                        if (bucket.allowVerticalPlacement && !wasPlaced && numVerticalGlyphVertices > 0 && verticalTextBox) {
                            return placeBoxForVariableAnchors(verticalTextBox, collisionArrays.verticalIconBox, index.WritingMode.vertical);
                        }
                        return {box: null, offscreen: null, occluded: null};
                    };

                    placeTextForPlacementModes(placeHorizontal, placeVertical);

                    if (placed) {
                        placeText = placed.box;
                        offscreen = placed.offscreen;
                        textOccluded = placed.occluded;
                    }

                    const isPlaced = placed && placed.box;
                    const prevOrientation = updatePreviousOrientationIfNotPlaced(!!isPlaced);

                    // If we didn't get placed, we still need to copy our position from the last placement for
                    // fade animations
                    if (!placeText && this.prevPlacement) {
                        const prevOffset = this.prevPlacement.variableOffsets[crossTileID];
                        if (prevOffset) {
                            this.variableOffsets[crossTileID] = prevOffset;
                            this.markUsedJustification(bucket, prevOffset.anchor, symbolInstance, prevOrientation);
                        }
                    }

                }
            }

            placedGlyphBoxes = placed;

            placeText = placedGlyphBoxes && placedGlyphBoxes.box && placedGlyphBoxes.box.length > 0;
            offscreen = placedGlyphBoxes && placedGlyphBoxes.offscreen;
            textOccluded = placedGlyphBoxes && placedGlyphBoxes.occluded;

            if (symbolInstance.useRuntimeCollisionCircles) {
                const placedSymbolIndex = symbolInstance.centerJustifiedTextSymbolIndex >= 0 ? symbolInstance.centerJustifiedTextSymbolIndex : symbolInstance.verticalPlacedTextSymbolIndex;
                const placedSymbol = bucket.text.placedSymbolArray.get(placedSymbolIndex);
                const fontSize = index.evaluateSizeForFeature(bucket.textSizeData, partiallyEvaluatedTextSize, placedSymbol);

                const textPixelPadding = layout.get('text-padding');
                // Convert circle collision height into pixels
                const circlePixelDiameter = symbolInstance.collisionCircleDiameter * fontSize / index.ONE_EM;

                placedGlyphCircles = this.collisionIndex.placeCollisionCircles(
                        bucket,
                        textAllowOverlap,
                        placedSymbol,
                        bucket.lineVertexArray,
                        bucket.glyphOffsetArray,
                        fontSize,
                        posMatrix,
                        textLabelPlaneMatrix,
                        labelToScreenMatrix,
                        showCollisionBoxes,
                        pitchWithMap,
                        collisionGroup.predicate,
                        circlePixelDiameter,
                        textPixelPadding,
                        this.retainedQueryData[bucket.bucketInstanceId].tileID);

                index.assert(!placedGlyphCircles.circles.length || (!placedGlyphCircles.collisionDetected || showCollisionBoxes));
                // If text-allow-overlap is set, force "placedCircles" to true
                // In theory there should always be at least one circle placed
                // in this case, but for now quirks in text-anchor
                // and text-offset may prevent that from being true.
                placeText = textAllowOverlap || (placedGlyphCircles.circles.length > 0 && !placedGlyphCircles.collisionDetected);
                offscreen = offscreen && placedGlyphCircles.offscreen;
                textOccluded = placedGlyphCircles.occluded;
            }

            if (collisionArrays.iconFeatureIndex) {
                iconFeatureIndex = collisionArrays.iconFeatureIndex;
            }

            if (collisionArrays.iconBox) {

                const placeIconFeature = (iconBox                    ) => {
                    updateBoxData(iconBox);
                    const shiftPoint        = hasIconTextFit && shift ?
                        offsetShift(shift.x, shift.y, rotateWithMap, pitchWithMap, this.transform.angle) :
                        new index.Point(0, 0);
                    const iconScale = bucket.getSymbolInstanceIconSize(partiallyEvaluatedIconSize, this.transform.zoom, symbolInstance.placedIconSymbolIndex);
                    return this.collisionIndex.placeCollisionBox(bucket, iconScale, iconBox, shiftPoint,
                        iconAllowOverlap, textPixelRatio, posMatrix, collisionGroup.predicate);
                };

                if (placedVerticalText && placedVerticalText.box && placedVerticalText.box.length && collisionArrays.verticalIconBox) {
                    placedIconBoxes = placeIconFeature(collisionArrays.verticalIconBox);
                    placeIcon = placedIconBoxes.box.length > 0;
                } else {
                    placedIconBoxes = placeIconFeature(collisionArrays.iconBox);
                    placeIcon = placedIconBoxes.box.length > 0;
                }
                offscreen = offscreen && placedIconBoxes.offscreen;
                iconOccluded = placedIconBoxes.occluded;
            }

            const iconWithoutText = textOptional ||
                (symbolInstance.numHorizontalGlyphVertices === 0 && numVerticalGlyphVertices === 0);
            const textWithoutIcon = iconOptional || symbolInstance.numIconVertices === 0;

            // Combine the scales for icons and text.
            if (!iconWithoutText && !textWithoutIcon) {
                placeIcon = placeText = placeIcon && placeText;
            } else if (!textWithoutIcon) {
                placeText = placeIcon && placeText;
            } else if (!iconWithoutText) {
                placeIcon = placeIcon && placeText;
            }

            if (placeText && placedGlyphBoxes && placedGlyphBoxes.box) {
                if (placedVerticalText && placedVerticalText.box && verticalTextFeatureIndex) {
                    this.collisionIndex.insertCollisionBox(placedGlyphBoxes.box, layout.get('text-ignore-placement'),
                        bucket.bucketInstanceId, verticalTextFeatureIndex, collisionGroup.ID);
                } else {
                    this.collisionIndex.insertCollisionBox(placedGlyphBoxes.box, layout.get('text-ignore-placement'),
                        bucket.bucketInstanceId, textFeatureIndex, collisionGroup.ID);
                }

            }
            if (placeIcon && placedIconBoxes) {
                this.collisionIndex.insertCollisionBox(placedIconBoxes.box, layout.get('icon-ignore-placement'),
                        bucket.bucketInstanceId, iconFeatureIndex, collisionGroup.ID);
            }
            if (placedGlyphCircles) {
                if (placeText) {
                    this.collisionIndex.insertCollisionCircles(placedGlyphCircles.circles, layout.get('text-ignore-placement'),
                        bucket.bucketInstanceId, textFeatureIndex, collisionGroup.ID);
                }

                if (showCollisionBoxes) {
                    const id = bucket.bucketInstanceId;
                    let circleArray = this.collisionCircleArrays[id];

                    // Group collision circles together by bucket. Circles can't be pushed forward for rendering yet as the symbol placement
                    // for a bucket is not guaranteed to be complete before the commit-function has been called
                    if (circleArray === undefined)
                        circleArray = this.collisionCircleArrays[id] = new CollisionCircleArray();

                    for (let i = 0; i < placedGlyphCircles.circles.length; i += 4) {
                        circleArray.circles.push(placedGlyphCircles.circles[i + 0]);              // x
                        circleArray.circles.push(placedGlyphCircles.circles[i + 1]);              // y
                        circleArray.circles.push(placedGlyphCircles.circles[i + 2]);              // radius
                        circleArray.circles.push(placedGlyphCircles.collisionDetected ? 1 : 0);   // collisionDetected-flag
                    }
                }
            }

            index.assert(crossTileID !== 0);
            index.assert(bucket.bucketInstanceId !== 0);

            const notGlobe = bucket.projection.name !== 'globe';
            alwaysShowText = alwaysShowText && (notGlobe || !textOccluded);
            alwaysShowIcon = alwaysShowIcon && (notGlobe || !iconOccluded);

            this.placements[crossTileID] = new JointPlacement(placeText || alwaysShowText, placeIcon || alwaysShowIcon, offscreen || bucket.justReloaded);
            seenCrossTileIDs.add(crossTileID);
        };

        if (zOrderByViewportY) {
            index.assert(bucketPart.symbolInstanceStart === 0);
            const symbolIndexes = bucket.getSortedSymbolIndexes(this.transform.angle);
            for (let i = symbolIndexes.length - 1; i >= 0; --i) {
                const symbolIndex = symbolIndexes[i];
                placeSymbol(bucket.symbolInstances.get(symbolIndex), symbolIndex, bucket.collisionArrays[symbolIndex]);
            }
        } else {
            for (let i = bucketPart.symbolInstanceStart; i < bucketPart.symbolInstanceEnd; i++) {
                placeSymbol(bucket.symbolInstances.get(i), i, bucket.collisionArrays[i]);
            }
        }

        if (showCollisionBoxes && bucket.bucketInstanceId in this.collisionCircleArrays) {
            const circleArray = this.collisionCircleArrays[bucket.bucketInstanceId];

            // Store viewport and inverse projection matrices per bucket
            index.invert$1(circleArray.invProjMatrix, posMatrix);
            circleArray.viewportMatrix = this.collisionIndex.getViewportMatrix();
        }

        bucket.justReloaded = false;
    }

    markUsedJustification(bucket              , placedAnchor            , symbolInstance                , orientation        ) {
        const {
            leftJustifiedTextSymbolIndex: left, centerJustifiedTextSymbolIndex: center,
            rightJustifiedTextSymbolIndex: right, verticalPlacedTextSymbolIndex: vertical, crossTileID
        } = symbolInstance;

        const justification = index.getAnchorJustification(placedAnchor);
        const autoIndex =
            orientation === index.WritingMode.vertical ? vertical :
            justification === 'left' ? left :
            justification === 'center' ? center :
            justification === 'right' ? right : -1;

        // If there are multiple justifications and this one isn't it: shift offscreen
        // If either this is the chosen justification or the justification is hardwired: use it
        if (left >= 0) bucket.text.placedSymbolArray.get(left).crossTileID = autoIndex >= 0 && left !== autoIndex ? 0 : crossTileID;
        if (center >= 0) bucket.text.placedSymbolArray.get(center).crossTileID = autoIndex >= 0 && center !== autoIndex ? 0 : crossTileID;
        if (right >= 0) bucket.text.placedSymbolArray.get(right).crossTileID = autoIndex >= 0 && right !== autoIndex ? 0 : crossTileID;
        if (vertical >= 0) bucket.text.placedSymbolArray.get(vertical).crossTileID = autoIndex >= 0 && vertical !== autoIndex ? 0 : crossTileID;
    }

    markUsedOrientation(bucket              , orientation        , symbolInstance                ) {
        const horizontalOrientation = (orientation === index.WritingMode.horizontal || orientation === index.WritingMode.horizontalOnly) ? orientation : 0;
        const verticalOrientation = orientation === index.WritingMode.vertical ? orientation : 0;
        const {
            leftJustifiedTextSymbolIndex: left, centerJustifiedTextSymbolIndex: center,
            rightJustifiedTextSymbolIndex: right, verticalPlacedTextSymbolIndex: vertical
        } = symbolInstance;
        const array = bucket.text.placedSymbolArray;

        if (left >= 0) array.get(left).placedOrientation = horizontalOrientation;
        if (center >= 0) array.get(center).placedOrientation = horizontalOrientation;
        if (right >= 0) array.get(right).placedOrientation = horizontalOrientation;
        if (vertical >= 0) array.get(vertical).placedOrientation = verticalOrientation;
    }

    commit(now        )       {
        this.commitTime = now;
        this.zoomAtLastRecencyCheck = this.transform.zoom;

        const prevPlacement = this.prevPlacement;
        let placementChanged = false;

        this.prevZoomAdjustment = prevPlacement ? prevPlacement.zoomAdjustment(this.transform.zoom) : 0;
        const increment = prevPlacement ? prevPlacement.symbolFadeChange(now) : 1;

        const prevOpacities = prevPlacement ? prevPlacement.opacities : {};
        const prevOffsets = prevPlacement ? prevPlacement.variableOffsets : {};
        const prevOrientations = prevPlacement ? prevPlacement.placedOrientations : {};

        // add the opacities from the current placement, and copy their current values from the previous placement
        for (const crossTileID in this.placements) {
            const jointPlacement = this.placements[crossTileID];
            const prevOpacity = prevOpacities[crossTileID];
            if (prevOpacity) {
                this.opacities[crossTileID] = new JointOpacityState(prevOpacity, increment, jointPlacement.text, jointPlacement.icon, null, jointPlacement.clipped);
                placementChanged = placementChanged ||
                    jointPlacement.text !== prevOpacity.text.placed ||
                    jointPlacement.icon !== prevOpacity.icon.placed;
            } else {
                this.opacities[crossTileID] = new JointOpacityState(null, increment, jointPlacement.text, jointPlacement.icon, jointPlacement.skipFade, jointPlacement.clipped);
                placementChanged = placementChanged || jointPlacement.text || jointPlacement.icon;
            }
        }

        // copy and update values from the previous placement that aren't in the current placement but haven't finished fading
        for (const crossTileID in prevOpacities) {
            const prevOpacity = prevOpacities[crossTileID];
            if (!this.opacities[crossTileID]) {
                const jointOpacity = new JointOpacityState(prevOpacity, increment, false, false);
                if (!jointOpacity.isHidden()) {
                    this.opacities[crossTileID] = jointOpacity;
                    placementChanged = placementChanged || prevOpacity.text.placed || prevOpacity.icon.placed;
                }
            }
        }
        for (const crossTileID in prevOffsets) {
            if (!this.variableOffsets[crossTileID] && this.opacities[crossTileID] && !this.opacities[crossTileID].isHidden()) {
                this.variableOffsets[crossTileID] = prevOffsets[crossTileID];
            }
        }

        for (const crossTileID in prevOrientations) {
            if (!this.placedOrientations[crossTileID] && this.opacities[crossTileID] && !this.opacities[crossTileID].isHidden()) {
                this.placedOrientations[crossTileID] = prevOrientations[crossTileID];
            }
        }

        // this.lastPlacementChangeTime is the time of the last commit() that
        // resulted in a placement change -- in other words, the start time of
        // the last symbol fade animation
        index.assert(!prevPlacement || prevPlacement.lastPlacementChangeTime !== undefined);
        if (placementChanged) {
            this.lastPlacementChangeTime = now;
        } else if (typeof this.lastPlacementChangeTime !== 'number') {
            this.lastPlacementChangeTime = prevPlacement ? prevPlacement.lastPlacementChangeTime : now;
        }
    }

    updateLayerOpacities(styleLayer            , tiles             ) {
        const seenCrossTileIDs = new Set();
        for (const tile of tiles) {
            const symbolBucket = ((tile.getBucket(styleLayer)     )              );
            if (symbolBucket && tile.latestFeatureIndex && styleLayer.id === symbolBucket.layerIds[0]) {
                this.updateBucketOpacities(symbolBucket, seenCrossTileIDs, tile.collisionBoxArray);
            }
        }
    }

    updateBucketOpacities(bucket              , seenCrossTileIDs             , collisionBoxArray                    ) {
        if (bucket.hasTextData()) bucket.text.opacityVertexArray.clear();
        if (bucket.hasIconData()) bucket.icon.opacityVertexArray.clear();
        if (bucket.hasIconCollisionBoxData()) bucket.iconCollisionBox.collisionVertexArray.clear();
        if (bucket.hasTextCollisionBoxData()) bucket.textCollisionBox.collisionVertexArray.clear();

        const layout = bucket.layers[0].layout;
        const hasClipping = !!bucket.layers[0].dynamicFilter();
        const duplicateOpacityState = new JointOpacityState(null, 0, false, false, true);
        const textAllowOverlap = layout.get('text-allow-overlap');
        const iconAllowOverlap = layout.get('icon-allow-overlap');
        const variablePlacement = layout.get('text-variable-anchor');
        const rotateWithMap = layout.get('text-rotation-alignment') === 'map';
        const pitchWithMap = layout.get('text-pitch-alignment') === 'map';
        const hasIconTextFit = layout.get('icon-text-fit') !== 'none';
        // If allow-overlap is true, we can show symbols before placement runs on them
        // But we have to wait for placement if we potentially depend on a paired icon/text
        // with allow-overlap: false.
        // See https://github.com/mapbox/mapbox-gl-js/issues/7032
        const defaultOpacityState = new JointOpacityState(null, 0,
                textAllowOverlap && (iconAllowOverlap || !bucket.hasIconData() || layout.get('icon-optional')),
                iconAllowOverlap && (textAllowOverlap || !bucket.hasTextData() || layout.get('text-optional')),
                true);

        if (!bucket.collisionArrays && collisionBoxArray && ((bucket.hasIconCollisionBoxData() || bucket.hasTextCollisionBoxData()))) {
            bucket.deserializeCollisionBoxes(collisionBoxArray);
        }

        const addOpacities = (iconOrText               , numVertices        , opacity        ) => {
            for (let i = 0; i < numVertices / 4; i++) {
                iconOrText.opacityVertexArray.emplaceBack(opacity);
            }
        };

        let visibleInstanceCount = 0;

        for (let s = 0; s < bucket.symbolInstances.length; s++) {
            const symbolInstance = bucket.symbolInstances.get(s);
            const {
                numHorizontalGlyphVertices,
                numVerticalGlyphVertices,
                crossTileID,
                numIconVertices
            } = symbolInstance;

            const isDuplicate = seenCrossTileIDs.has(crossTileID);

            let opacityState = this.opacities[crossTileID];
            if (isDuplicate) {
                opacityState = duplicateOpacityState;
            } else if (!opacityState) {
                opacityState = defaultOpacityState;
                // store the state so that future placements use it as a starting point
                this.opacities[crossTileID] = opacityState;
            }

            seenCrossTileIDs.add(crossTileID);

            const hasText = numHorizontalGlyphVertices > 0 || numVerticalGlyphVertices > 0;
            const hasIcon = numIconVertices > 0;

            const placedOrientation = this.placedOrientations[crossTileID];
            const horizontalHidden = placedOrientation === index.WritingMode.vertical;
            const verticalHidden = placedOrientation === index.WritingMode.horizontal || placedOrientation === index.WritingMode.horizontalOnly;
            if ((hasText || hasIcon) && !opacityState.isHidden()) visibleInstanceCount++;

            if (hasText) {
                const packedOpacity = packOpacity(opacityState.text);
                // Vertical text fades in/out on collision the same way as corresponding
                // horizontal text. Switch between vertical/horizontal should be instantaneous
                const horizontalOpacity = horizontalHidden ? PACKED_HIDDEN_OPACITY : packedOpacity;
                addOpacities(bucket.text, numHorizontalGlyphVertices, horizontalOpacity);
                const verticalOpacity = verticalHidden ? PACKED_HIDDEN_OPACITY : packedOpacity;
                addOpacities(bucket.text, numVerticalGlyphVertices, verticalOpacity);

                // If this label is completely faded, mark it so that we don't have to calculate
                // its position at render time. If this layer has variable placement, shift the various
                // symbol instances appropriately so that symbols from buckets that have yet to be placed
                // offset appropriately.
                const symbolHidden = opacityState.text.isHidden();
                const {
                    leftJustifiedTextSymbolIndex: left, centerJustifiedTextSymbolIndex: center,
                    rightJustifiedTextSymbolIndex: right, verticalPlacedTextSymbolIndex: vertical
                } = symbolInstance;
                const array = bucket.text.placedSymbolArray;
                const horizontalHiddenValue = symbolHidden || horizontalHidden ? 1 : 0;

                if (left >= 0) array.get(left).hidden = horizontalHiddenValue;
                if (center >= 0) array.get(center).hidden = horizontalHiddenValue;
                if (right >= 0) array.get(right).hidden = horizontalHiddenValue;
                if (vertical >= 0) array.get(vertical).hidden = symbolHidden || verticalHidden ? 1 : 0;

                const prevOffset = this.variableOffsets[crossTileID];
                if (prevOffset) {
                    this.markUsedJustification(bucket, prevOffset.anchor, symbolInstance, placedOrientation);
                }

                const prevOrientation = this.placedOrientations[crossTileID];
                if (prevOrientation) {
                    this.markUsedJustification(bucket, 'left', symbolInstance, prevOrientation);
                    this.markUsedOrientation(bucket, prevOrientation, symbolInstance);
                }
            }

            if (hasIcon) {
                const packedOpacity = packOpacity(opacityState.icon);
                const {placedIconSymbolIndex, verticalPlacedIconSymbolIndex} = symbolInstance;
                const array = bucket.icon.placedSymbolArray;
                const iconHidden = opacityState.icon.isHidden() ? 1 : 0;

                if (placedIconSymbolIndex >= 0) {
                    const horizontalOpacity = !horizontalHidden ? packedOpacity : PACKED_HIDDEN_OPACITY;
                    addOpacities(bucket.icon, numIconVertices, horizontalOpacity);
                    array.get(placedIconSymbolIndex).hidden = iconHidden;
                }

                if (verticalPlacedIconSymbolIndex >= 0) {
                    const verticalOpacity = !verticalHidden ? packedOpacity : PACKED_HIDDEN_OPACITY;
                    addOpacities(bucket.icon, symbolInstance.numVerticalIconVertices, verticalOpacity);
                    array.get(verticalPlacedIconSymbolIndex).hidden = iconHidden;
                }
            }

            if (bucket.hasIconCollisionBoxData() || bucket.hasTextCollisionBoxData()) {
                const collisionArrays = bucket.collisionArrays[s];
                if (collisionArrays) {
                    let shift = new index.Point(0, 0);
                    let used = true;
                    if (collisionArrays.textBox || collisionArrays.verticalTextBox) {
                        if (variablePlacement) {
                            const variableOffset = this.variableOffsets[crossTileID];
                            if (variableOffset) {
                                // This will show either the currently placed position or the last
                                // successfully placed position (so you can visualize what collision
                                // just made the symbol disappear, and the most likely place for the
                                // symbol to come back)
                                shift = calculateVariableLayoutShift(variableOffset.anchor,
                                   variableOffset.width,
                                   variableOffset.height,
                                   variableOffset.textOffset,
                                   variableOffset.textScale);
                                if (rotateWithMap) {
                                    shift._rotate(pitchWithMap ? this.transform.angle : -this.transform.angle);
                                }
                            } else {
                                // No offset -> this symbol hasn't been placed since coming on-screen
                                // No single box is particularly meaningful and all of them would be too noisy
                                // Use the center box just to show something's there, but mark it "not used"
                                used = false;
                            }
                        }

                        if (hasClipping) {
                            used = !opacityState.clipped;
                        }

                        if (collisionArrays.textBox) {
                            updateCollisionVertices(bucket.textCollisionBox.collisionVertexArray, opacityState.text.placed, !used || horizontalHidden, shift.x, shift.y);
                        }
                        if (collisionArrays.verticalTextBox) {
                            updateCollisionVertices(bucket.textCollisionBox.collisionVertexArray, opacityState.text.placed, !used || verticalHidden, shift.x, shift.y);
                        }
                    }

                    const verticalIconUsed = used && Boolean(!verticalHidden && collisionArrays.verticalIconBox);

                    if (collisionArrays.iconBox) {
                        updateCollisionVertices(bucket.iconCollisionBox.collisionVertexArray, opacityState.icon.placed, verticalIconUsed,
                            hasIconTextFit ? shift.x : 0,
                            hasIconTextFit ? shift.y : 0);
                    }

                    if (collisionArrays.verticalIconBox) {
                        updateCollisionVertices(bucket.iconCollisionBox.collisionVertexArray, opacityState.icon.placed, !verticalIconUsed,
                            hasIconTextFit ? shift.x : 0,
                            hasIconTextFit ? shift.y : 0);
                    }
                }
            }
        }
        bucket.fullyClipped = visibleInstanceCount === 0;
        bucket.sortFeatures(this.transform.angle);
        if (this.retainedQueryData[bucket.bucketInstanceId]) {
            this.retainedQueryData[bucket.bucketInstanceId].featureSortOrder = bucket.featureSortOrder;
        }

        if (bucket.hasTextData() && bucket.text.opacityVertexBuffer) {
            bucket.text.opacityVertexBuffer.updateData(bucket.text.opacityVertexArray);
        }
        if (bucket.hasIconData() && bucket.icon.opacityVertexBuffer) {
            bucket.icon.opacityVertexBuffer.updateData(bucket.icon.opacityVertexArray);
        }
        if (bucket.hasIconCollisionBoxData() && bucket.iconCollisionBox.collisionVertexBuffer) {
            bucket.iconCollisionBox.collisionVertexBuffer.updateData(bucket.iconCollisionBox.collisionVertexArray);
        }
        if (bucket.hasTextCollisionBoxData() && bucket.textCollisionBox.collisionVertexBuffer) {
            bucket.textCollisionBox.collisionVertexBuffer.updateData(bucket.textCollisionBox.collisionVertexArray);
        }

        index.assert(bucket.text.opacityVertexArray.length === bucket.text.layoutVertexArray.length / 4);
        index.assert(bucket.icon.opacityVertexArray.length === bucket.icon.layoutVertexArray.length / 4);

        // Push generated collision circles to the bucket for debug rendering
        if (bucket.bucketInstanceId in this.collisionCircleArrays) {
            const instance = this.collisionCircleArrays[bucket.bucketInstanceId];

            bucket.placementInvProjMatrix = instance.invProjMatrix;
            bucket.placementViewportMatrix = instance.viewportMatrix;
            bucket.collisionCircleArray = instance.circles;

            delete this.collisionCircleArrays[bucket.bucketInstanceId];
        }
    }

    symbolFadeChange(now        )         {
        return this.fadeDuration === 0 ?
            1 :
            ((now - this.commitTime) / this.fadeDuration + this.prevZoomAdjustment);
    }

    zoomAdjustment(zoom        )         {
        // When zooming out quickly, labels can overlap each other. This
        // adjustment is used to reduce the interval between placement calculations
        // and to reduce the fade duration when zooming out quickly. Discovering the
        // collisions more quickly and fading them more quickly reduces the unwanted effect.
        return Math.max(0, (this.transform.zoom - zoom) / 1.5);
    }

    hasTransitions(now        )          {
        return this.stale ||
            now - this.lastPlacementChangeTime < this.fadeDuration;
    }

    stillRecent(now        , zoom        )          {
        // The adjustment makes placement more frequent when zooming.
        // This condition applies the adjustment only after the map has
        // stopped zooming. This avoids adding extra jank while zooming.
        const durationAdjustment = this.zoomAtLastRecencyCheck === zoom ?
            (1 - this.zoomAdjustment(zoom)) :
            1;
        this.zoomAtLastRecencyCheck = zoom;

        return this.commitTime + this.fadeDuration * durationAdjustment > now;
    }

    setStale() {
        this.stale = true;
    }
}

function updateCollisionVertices(collisionVertexArray                      , placed         , notUsed                  , shiftX         , shiftY         ) {
    collisionVertexArray.emplaceBack(placed ? 1 : 0, notUsed ? 1 : 0, shiftX || 0, shiftY || 0);
    collisionVertexArray.emplaceBack(placed ? 1 : 0, notUsed ? 1 : 0, shiftX || 0, shiftY || 0);
    collisionVertexArray.emplaceBack(placed ? 1 : 0, notUsed ? 1 : 0, shiftX || 0, shiftY || 0);
    collisionVertexArray.emplaceBack(placed ? 1 : 0, notUsed ? 1 : 0, shiftX || 0, shiftY || 0);
}

// All four vertices for a glyph will have the same opacity state
// So we pack the opacity into a uint8, and then repeat it four times
// to make a single uint32 that we can upload for each glyph in the
// label.
const shift25 = Math.pow(2, 25);
const shift24 = Math.pow(2, 24);
const shift17 = Math.pow(2, 17);
const shift16 = Math.pow(2, 16);
const shift9 = Math.pow(2, 9);
const shift8 = Math.pow(2, 8);
const shift1 = Math.pow(2, 1);
function packOpacity(opacityState              )         {
    if (opacityState.opacity === 0 && !opacityState.placed) {
        return 0;
    } else if (opacityState.opacity === 1 && opacityState.placed) {
        return 4294967295;
    }
    const targetBit = opacityState.placed ? 1 : 0;
    const opacityBits = Math.floor(opacityState.opacity * 127);
    return opacityBits * shift25 + targetBit * shift24 +
        opacityBits * shift17 + targetBit * shift16 +
        opacityBits * shift9 + targetBit * shift8 +
        opacityBits * shift1 + targetBit;
}

const PACKED_HIDDEN_OPACITY = 0;

//      


                                                 
                                               
                                                                        
                                          
                                                       
                                               

class LayerPlacement {
                              
                              
                              
                                   
                                    

    constructor(styleLayer                  ) {
        this._sortAcrossTiles = styleLayer.layout.get('symbol-z-order') !== 'viewport-y' &&
            styleLayer.layout.get('symbol-sort-key').constantOr(1) !== undefined;

        this._currentTileIndex = 0;
        this._currentPartIndex = 0;
        this._seenCrossTileIDs = new Set();
        this._bucketParts = [];
    }

    continuePlacement(tiles             , placement           , showCollisionBoxes         , styleLayer            , shouldPausePlacement               )          {
        const bucketParts = this._bucketParts;

        while (this._currentTileIndex < tiles.length) {
            const tile = tiles[this._currentTileIndex];
            placement.getBucketParts(bucketParts, styleLayer, tile, this._sortAcrossTiles);

            this._currentTileIndex++;
            if (shouldPausePlacement()) {
                return true;
            }
        }

        if (this._sortAcrossTiles) {
            this._sortAcrossTiles = false;
            bucketParts.sort((a, b) => ((a.sortKey     )        ) - ((b.sortKey     )        ));
        }

        while (this._currentPartIndex < bucketParts.length) {
            const bucketPart = bucketParts[this._currentPartIndex];
            placement.placeLayerBucketPart(bucketPart, this._seenCrossTileIDs, showCollisionBoxes, bucketPart.symbolInstanceStart === 0);
            this._currentPartIndex++;
            if (shouldPausePlacement()) {
                return true;
            }
        }
        return false;
    }
}

class PauseablePlacement {
                         
                   
                                   
                                 
                                 
                                      

    constructor(transform           , order               ,
                forceFullPlacement         ,
                showCollisionBoxes         ,
                fadeDuration        ,
                crossSourceCollisions         ,
                prevPlacement            ,
                fogState           ) {

        this.placement = new Placement(transform, fadeDuration, crossSourceCollisions, prevPlacement, fogState);
        this._currentPlacementIndex = order.length - 1;
        this._forceFullPlacement = forceFullPlacement;
        this._showCollisionBoxes = showCollisionBoxes;
        this._done = false;
    }

    isDone()          {
        return this._done;
    }

    continuePlacement(order               , layers                           , layerTiles                            ) {
        const startTime = index.exported.now();

        const shouldPausePlacement = () => {
            const elapsedTime = index.exported.now() - startTime;
            return this._forceFullPlacement ? false : elapsedTime > 2;
        };

        while (this._currentPlacementIndex >= 0) {
            const layerId = order[this._currentPlacementIndex];
            const layer = layers[layerId];
            const placementZoom = this.placement.collisionIndex.transform.zoom;
            if (layer.type === 'symbol' &&
                (!layer.minzoom || layer.minzoom <= placementZoom) &&
                (!layer.maxzoom || layer.maxzoom > placementZoom)) {

                if (!this._inProgressLayer) {
                    this._inProgressLayer = new LayerPlacement(((layer     )                  ));
                }

                const pausePlacement = this._inProgressLayer.continuePlacement(layerTiles[layer.source], this.placement, this._showCollisionBoxes, layer, shouldPausePlacement);

                if (pausePlacement) {
                    index.PerformanceUtils.recordPlacementTime(index.exported.now() - startTime);
                    // We didn't finish placing all layers within 2ms,
                    // but we can keep rendering with a partial placement
                    // We'll resume here on the next frame
                    return;
                }

                delete this._inProgressLayer;
            }

            this._currentPlacementIndex--;
        }
        index.PerformanceUtils.recordPlacementTime(index.exported.now() - startTime);
        this._done = true;
    }

    commit(now        )            {
        this.placement.commit(now);
        return this.placement;
    }
}

//      


                                                              
                                                           
                                                                
                                                      
                                          

/*
    The CrossTileSymbolIndex generally works on the assumption that
    a conceptual "unique symbol" can be identified by the text of
    the label combined with the anchor point. The goal is to assign
    these conceptual "unique symbols" a shared crossTileID that can be
    used by Placement to keep fading opacity states consistent and to
    deduplicate labels.

    The CrossTileSymbolIndex indexes all the current symbol instances and
    their crossTileIDs. When a symbol bucket gets added or updated, the
    index assigns a crossTileID to each of it's symbol instances by either
    matching it with an existing id or assigning a new one.
*/

// Round anchor positions to roughly 4 pixel grid
const roundingFactor = 512 / index.EXTENT / 2;

class TileLayerIndex {
                             
                             
                  
                        
                                

    constructor(tileID                  , symbolInstances                     , bucketInstanceId        ) {
        this.tileID = tileID;
        this.bucketInstanceId = bucketInstanceId;

        // create a spatial index for deduplicating symbol instances;
        // use a low nodeSize because we're optimizing for search performance, not indexing
        this.index = new index.KDBush(symbolInstances.length, 16, Int32Array);
        this.keys = [];
        this.crossTileIDs = [];
        const tx = tileID.canonical.x * index.EXTENT;
        const ty = tileID.canonical.y * index.EXTENT;

        for (let i = 0; i < symbolInstances.length; i++) {
            const {key, crossTileID, tileAnchorX, tileAnchorY} = symbolInstances.get(i);

            // Converts the coordinates of the input symbol instance into coordinates that be can compared
            // against other symbols in this index. Coordinates are:
            // (1) world-based (so after conversion the source tile is irrelevant)
            // (2) converted to the z-scale of this TileLayerIndex
            // (3) down-sampled by "roundingFactor" from tile coordinate precision in order to be
            //     more tolerant of small differences between tiles.
            const x = Math.floor((tx + tileAnchorX) * roundingFactor);
            const y = Math.floor((ty + tileAnchorY) * roundingFactor);

            this.index.add(x, y);
            this.keys.push(key);
            this.crossTileIDs.push(crossTileID);
        }
        this.index.finish();
    }

    findMatches(symbolInstances                     , newTileID                  , zoomCrossTileIDs             ) {
        const tolerance = this.tileID.canonical.z < newTileID.canonical.z ? 1 : Math.pow(2, this.tileID.canonical.z - newTileID.canonical.z);
        const scale = roundingFactor / Math.pow(2, newTileID.canonical.z - this.tileID.canonical.z);
        const tx = newTileID.canonical.x * index.EXTENT;
        const ty = newTileID.canonical.y * index.EXTENT;

        for (let i = 0; i < symbolInstances.length; i++) {
            const symbolInstance = symbolInstances.get(i);
            if (symbolInstance.crossTileID) {
                // already has a match, skip
                continue;
            }
            const {key, tileAnchorX, tileAnchorY} = symbolInstance;
            const x = Math.floor((tx + tileAnchorX) * scale);
            const y = Math.floor((ty + tileAnchorY) * scale);

            // Return any symbol with the same keys whose coordinates are within 1
            // grid unit. (with a 4px grid, this covers a 12px by 12px area)
            const matchedIds = this.index.range(x - tolerance, y - tolerance, x + tolerance, y + tolerance);
            for (const id of matchedIds) {
                const crossTileID = this.crossTileIDs[id];
                if (this.keys[id] === key && !zoomCrossTileIDs.has(crossTileID)) {
                    // Once we've marked ourselves duplicate against this parent symbol,
                    // don't let any other symbols at the same zoom level duplicate against
                    // the same parent (see issue #5993)
                    zoomCrossTileIDs.add(crossTileID);
                    symbolInstance.crossTileID = crossTileID;
                    break;
                }
            }
        }
    }
}

class CrossTileIDs {
                           
    constructor() {
        this.maxCrossTileID = 0;
    }
    generate()         {
        return ++this.maxCrossTileID;
    }
}

class CrossTileSymbolLayerIndex {
                                                                                    
                                                             
                

    constructor() {
        this.indexes = {};
        this.usedCrossTileIDs = {};
        this.lng = 0;
    }

    /*
     * Sometimes when a user pans across the antimeridian the longitude value gets wrapped.
     * To prevent labels from flashing out and in we adjust the tileID values in the indexes
     * so that they match the new wrapped version of the map.
     */
    handleWrapJump(lng        ) {
        const wrapDelta = Math.round((lng - this.lng) / 360);
        if (wrapDelta !== 0) {
            for (const zoom in this.indexes) {
                const zoomIndexes = this.indexes[zoom];
                const newZoomIndex = {};
                for (const key in zoomIndexes) {
                    // change the tileID's wrap and add it to a new index
                    const index = zoomIndexes[key];
                    index.tileID = index.tileID.unwrapTo(index.tileID.wrap + wrapDelta);
                    newZoomIndex[index.tileID.key] = index;
                }
                this.indexes[zoom] = newZoomIndex;
            }
        }
        this.lng = lng;
    }

    addBucket(tileID                  , bucket              , crossTileIDs              )          {
        if (this.indexes[tileID.overscaledZ] &&
            this.indexes[tileID.overscaledZ][tileID.key]) {
            if (this.indexes[tileID.overscaledZ][tileID.key].bucketInstanceId ===
                bucket.bucketInstanceId) {
                return false;
            } else {
                // We're replacing this bucket with an updated version
                // Remove the old bucket's "used crossTileIDs" now so that
                // the new bucket can claim them.
                // The old index entries themselves stick around until
                // 'removeStaleBuckets' is called.
                this.removeBucketCrossTileIDs(tileID.overscaledZ,
                    this.indexes[tileID.overscaledZ][tileID.key]);
            }
        }

        for (let i = 0; i < bucket.symbolInstances.length; i++) {
            const symbolInstance = bucket.symbolInstances.get(i);
            symbolInstance.crossTileID = 0;
        }

        if (!this.usedCrossTileIDs[tileID.overscaledZ]) {
            this.usedCrossTileIDs[tileID.overscaledZ] = new Set();
        }
        const zoomCrossTileIDs = this.usedCrossTileIDs[tileID.overscaledZ];

        for (const zoom in this.indexes) {
            const zoomIndexes = this.indexes[zoom];
            if (Number(zoom) > tileID.overscaledZ) {
                for (const id in zoomIndexes) {
                    const childIndex = zoomIndexes[id];
                    if (childIndex.tileID.isChildOf(tileID)) {
                        childIndex.findMatches(bucket.symbolInstances, tileID, zoomCrossTileIDs);
                    }
                }
            } else {
                const parentCoord = tileID.scaledTo(Number(zoom));
                const parentIndex = zoomIndexes[parentCoord.key];
                if (parentIndex) {
                    parentIndex.findMatches(bucket.symbolInstances, tileID, zoomCrossTileIDs);
                }
            }
        }

        for (let i = 0; i < bucket.symbolInstances.length; i++) {
            const symbolInstance = bucket.symbolInstances.get(i);
            if (!symbolInstance.crossTileID) {
                // symbol did not match any known symbol, assign a new id
                symbolInstance.crossTileID = crossTileIDs.generate();
                zoomCrossTileIDs.add(symbolInstance.crossTileID);
            }
        }

        if (this.indexes[tileID.overscaledZ] === undefined) {
            this.indexes[tileID.overscaledZ] = {};
        }
        this.indexes[tileID.overscaledZ][tileID.key] = new TileLayerIndex(tileID, bucket.symbolInstances, bucket.bucketInstanceId);

        return true;
    }

    removeBucketCrossTileIDs(zoom                 , removedBucket                ) {
        for (const crossTileID of removedBucket.crossTileIDs) {
            this.usedCrossTileIDs[zoom].delete(crossTileID);
        }
    }

    removeStaleBuckets(currentIDs                                )          {
        let tilesChanged = false;
        for (const z in this.indexes) {
            const zoomIndexes = this.indexes[z];
            for (const tileKey in zoomIndexes) {
                if (!currentIDs[zoomIndexes[tileKey].bucketInstanceId]) {
                    this.removeBucketCrossTileIDs(z, zoomIndexes[tileKey]);
                    delete zoomIndexes[tileKey];
                    tilesChanged = true;
                }
            }
        }
        return tilesChanged;
    }
}

class CrossTileSymbolIndex {
                                                                 
                               
                                
                                                      

    constructor() {
        this.layerIndexes = {};
        this.crossTileIDs = new CrossTileIDs();
        this.maxBucketInstanceId = 0;
        this.bucketsInCurrentPlacement = {};
    }

    addLayer(styleLayer            , tiles             , lng        , projection            )          {
        let layerIndex = this.layerIndexes[styleLayer.id];
        if (layerIndex === undefined) {
            layerIndex = this.layerIndexes[styleLayer.id] = new CrossTileSymbolLayerIndex();
        }

        let symbolBucketsChanged = false;
        const currentBucketIDs = {};

        if (projection.name !== 'globe') {
            layerIndex.handleWrapJump(lng);
        }

        for (const tile of tiles) {
            const symbolBucket = ((tile.getBucket(styleLayer)     )              );
            if (!symbolBucket || styleLayer.id !== symbolBucket.layerIds[0])
                continue;

            if (!symbolBucket.bucketInstanceId) {
                symbolBucket.bucketInstanceId = ++this.maxBucketInstanceId;
            }

            if (layerIndex.addBucket(tile.tileID, symbolBucket, this.crossTileIDs)) {
                symbolBucketsChanged = true;
            }
            currentBucketIDs[symbolBucket.bucketInstanceId] = true;
        }

        if (layerIndex.removeStaleBuckets(currentBucketIDs)) {
            symbolBucketsChanged = true;
        }

        return symbolBucketsChanged;
    }

    pruneUnusedLayers(usedLayers               ) {
        const usedLayerMap = {};
        usedLayers.forEach((usedLayer) => {
            usedLayerMap[usedLayer] = true;
        });
        for (const layerId in this.layerIndexes) {
            if (!usedLayerMap[layerId]) {
                delete this.layerIndexes[layerId];
            }
        }
    }
}

//      


// We're skipping validation errors with the `source.canvas` identifier in order
// to continue to allow canvas sources to be added at runtime/updated in
// smart setStyle (see https://github.com/mapbox/mapbox-gl-js/pull/6424):
const emitValidationErrors = (evented         , errors                   ) =>
    index.emitValidationErrors(evented, errors && errors.filter(error => error.identifier !== 'source.canvas'));

                                    
                                                 
                                                 
                                                 
                                                   
                                                                   
                                                      
                                                       
                                                                         
                                                   
             
                       
                        
                       
                       
                        
                         
                     
                            
                            
                              
                                
                                                                              
                                                                     
                                                           
                                                          
                                                                   
                                                             
                                                      
                                                
                                                          

const supportedDiffOperations = index.pick(operations, [
    'addLayer',
    'removeLayer',
    'setPaintProperty',
    'setLayoutProperty',
    'setFilter',
    'addSource',
    'removeSource',
    'setLayerZoomRange',
    'setLight',
    'setTransition',
    'setGeoJSONSourceData',
    'setTerrain',
    'setFog',
    'setProjection'
    // 'setGlyphs',
    // 'setSprite',
]);

const ignoredDiffOperations = index.pick(operations, [
    'setCenter',
    'setZoom',
    'setBearing',
    'setPitch'
]);

const empty = emptyStyle();

                            
                       
                             
                                     
  

                                  
                      
  

// Symbols are draped only for specific cases: see isLayerDraped
const drapedLayers = {'fill': true, 'line': true, 'background': true, "hillshade": true, "raster": true};

/**
 * @private
 */
class Style extends index.Evented {
             
                                   
                           
                               
                               
                 
                      
              

                          
                                
                                       
                         
                             
                             
                                             
                          
                                     
                                              
                                                   
                                                    
                     
                                     
                      
                                                       
                                        
                                              
                                        
                                                
                                
                                    
                                

                                               
                                           
                         
              

    // exposed to allow stubbing by unit tests
                                               
                                               
                                                                             

    constructor(map     , options               = {}) {
        super();

        this.map = map;
        this.dispatcher = new Dispatcher(getGlobalWorkerPool(), this);
        this.imageManager = new ImageManager();
        this.imageManager.setEventedParent(this);
        this.glyphManager = new index.GlyphManager(map._requestManager,
            options.localFontFamily ?
                index.LocalGlyphMode.all :
                (options.localIdeographFontFamily ? index.LocalGlyphMode.ideographs : index.LocalGlyphMode.none),
            options.localFontFamily || options.localIdeographFontFamily);
        this.crossTileSymbolIndex = new CrossTileSymbolIndex();

        this._layers = {};
        this._num3DLayers = 0;
        this._numSymbolLayers = 0;
        this._numCircleLayers = 0;
        this._serializedLayers = {};
        this._sourceCaches = {};
        this._otherSourceCaches = {};
        this._symbolSourceCaches = {};
        this._loaded = false;
        this._availableImages = [];
        this._order  = [];
        this._drapedFirstOrder = [];
        this._markersNeedUpdate = false;

        this._resetUpdates();

        this.dispatcher.broadcast('setReferrer', index.getReferrer());

        const self = this;
        this._rtlTextPluginCallback = Style.registerForPluginStateChange((event) => {
            const state = {
                pluginStatus: event.pluginStatus,
                pluginURL: event.pluginURL
            };
            self.dispatcher.broadcast('syncRTLPluginState', state, (err, results) => {
                index.triggerPluginCompletionEvent(err);
                if (results) {
                    const allComplete = results.every((elem) => elem);
                    if (allComplete) {
                        for (const id in self._sourceCaches) {
                            const sourceCache = self._sourceCaches[id];
                            const sourceCacheType = sourceCache.getSource().type;
                            if (sourceCacheType === 'vector' || sourceCacheType === 'geojson') {
                                sourceCache.reload(); // Should be a no-op if the plugin loads before any tiles load
                            }
                        }
                    }
                }

            });
        });

        this.on('data', (event) => {
            if (event.dataType !== 'source' || event.sourceDataType !== 'metadata') {
                return;
            }

            const source = this.getSource(event.sourceId);
            if (!source || !source.vectorLayerIds) {
                return;
            }

            for (const layerId in this._layers) {
                const layer = this._layers[layerId];
                if (layer.source === source.id) {
                    this._validateLayer(layer);
                }
            }
        });
    }

    loadURL(url        , options   
                           
                            
      = {}) {
        this.fire(new index.Event('dataloading', {dataType: 'style'}));

        const validate = typeof options.validate === 'boolean' ?
            options.validate : !index.isMapboxURL(url);

        url = this.map._requestManager.normalizeStyleURL(url, options.accessToken);
        const request = this.map._requestManager.transformRequest(url, index.ResourceType.Style);
        this._request = index.getJSON(request, (error        , json         ) => {
            this._request = null;
            if (error) {
                this.fire(new index.ErrorEvent(error));
            } else if (json) {
                this._load(json, validate);
            }
        });
    }

    loadJSON(json                    , options                     = {}) {
        this.fire(new index.Event('dataloading', {dataType: 'style'}));

        this._request = index.exported.frame(() => {
            this._request = null;
            this._load(json, options.validate !== false);
        });
    }

    loadEmpty() {
        this.fire(new index.Event('dataloading', {dataType: 'style'}));
        this._load(empty, false);
    }

    _updateLayerCount(layer            , add         ) {
        // Typed layer bookkeeping
        const count = add ? 1 : -1;
        if (layer.is3D()) {
            this._num3DLayers += count;
        }
        if (layer.type === 'circle') {
            this._numCircleLayers += count;
        }
        if (layer.type === 'symbol') {
            this._numSymbolLayers += count;
        }
    }

    _load(json                    , validate         ) {
        if (validate && emitValidationErrors(this, index.validateStyle(json))) {
            return;
        }

        this._loaded = true;
        this.stylesheet = index.clone$1(json);
        this._updateMapProjection();

        for (const id in json.sources) {
            this.addSource(id, json.sources[id], {validate: false});
        }
        this._changed = false; // avoid triggering redundant style update after adding initial sources
        if (json.sprite) {
            this._loadSprite(json.sprite);
        } else {
            this.imageManager.setLoaded(true);
            this.dispatcher.broadcast('spriteLoaded', true);
        }

        this.glyphManager.setURL(json.glyphs);

        const layers                            = derefLayers(this.stylesheet.layers);

        this._order = layers.map((layer) => layer.id);

        this._layers = {};
        this._serializedLayers = {};
        for (const layer of layers) {
            const styleLayer = index.createStyleLayer(layer);
            styleLayer.setEventedParent(this, {layer: {id: styleLayer.id}});
            this._layers[styleLayer.id] = styleLayer;
            this._serializedLayers[styleLayer.id] = styleLayer.serialize();
            this._updateLayerCount(styleLayer, true);
        }

        this.dispatcher.broadcast('setLayers', this._serializeLayers(this._order));

        this.light = new Light(this.stylesheet.light);
        if (this.stylesheet.terrain && !this.terrainSetForDrapingOnly()) {
            // $FlowFixMe[incompatible-call] - Flow can't infer that terrain is not undefined
            this._createTerrain(this.stylesheet.terrain, DrapeRenderMode.elevated);
        }
        if (this.stylesheet.fog) {
            this._createFog(this.stylesheet.fog);
        }
        this._updateDrapeFirstLayers();

        this.fire(new index.Event('data', {dataType: 'style'}));
        this.fire(new index.Event('style.load'));
    }

    terrainSetForDrapingOnly()          {
        return !!this.terrain && this.terrain.drapeRenderMode === DrapeRenderMode.deferred;
    }

    setProjection(projection                           ) {
        if (projection) {
            this.stylesheet.projection = projection;
        } else {
            delete this.stylesheet.projection;
        }
        this._updateMapProjection();
    }

    applyProjectionUpdate() {
        if (!this._loaded) return;
        this.dispatcher.broadcast('setProjection', this.map.transform.projectionOptions);

        if (this.map.transform.projection.requiresDraping) {
            const hasTerrain = this.getTerrain() || this.stylesheet.terrain;
            if (!hasTerrain) {
                this.setTerrainForDraping();
            }
        } else if (this.terrainSetForDrapingOnly()) {
            this.setTerrain(null);
        }
    }

    _updateMapProjection() {
        if (!this.map._useExplicitProjection) { // Update the visible projection if map's is null
            this.map._prioritizeAndUpdateProjection(null, this.stylesheet.projection);
        } else { // Ensure that style is consistent with current projection on style load
            this.applyProjectionUpdate();
        }
    }

    _loadSprite(url        ) {
        this._spriteRequest = loadSprite(url, this.map._requestManager, (err, images) => {
            this._spriteRequest = null;
            if (err) {
                this.fire(new index.ErrorEvent(err));
            } else if (images) {
                for (const id in images) {
                    this.imageManager.addImage(id, images[id]);
                }
            }

            this.imageManager.setLoaded(true);
            this._availableImages = this.imageManager.listImages();
            this.dispatcher.broadcast('setImages', this._availableImages);
            this.dispatcher.broadcast('spriteLoaded', true);
            this.fire(new index.Event('data', {dataType: 'style'}));
        });
    }

    _validateLayer(layer            ) {
        const source = this.getSource(layer.source);
        if (!source) {
            return;
        }

        const sourceLayer = layer.sourceLayer;
        if (!sourceLayer) {
            return;
        }

        if (source.type === 'geojson' || (source.vectorLayerIds && source.vectorLayerIds.indexOf(sourceLayer) === -1)) {
            this.fire(new index.ErrorEvent(new Error(
                `Source layer "${sourceLayer}" ` +
                `does not exist on source "${source.id}" ` +
                `as specified by style layer "${layer.id}"`
            )));
        }
    }

    loaded()          {
        if (!this._loaded)
            return false;

        if (Object.keys(this._updatedSources).length)
            return false;

        for (const id in this._sourceCaches)
            if (!this._sourceCaches[id].loaded())
                return false;

        if (!this.imageManager.isLoaded())
            return false;

        return true;
    }

    _serializeLayers(ids               )                {
        const serializedLayers = [];
        for (const id of ids) {
            const layer = this._layers[id];
            if (layer.type !== 'custom') {
                serializedLayers.push(layer.serialize());
            }
        }
        return serializedLayers;
    }

    hasTransitions()          {
        if (this.light && this.light.hasTransition()) {
            return true;
        }

        if (this.fog && this.fog.hasTransition()) {
            return true;
        }

        for (const id in this._sourceCaches) {
            if (this._sourceCaches[id].hasTransition()) {
                return true;
            }
        }

        for (const id in this._layers) {
            if (this._layers[id].hasTransition()) {
                return true;
            }
        }

        return false;
    }

    get order()                {
        if (this.map._optimizeForTerrain && this.terrain) {
            index.assert(this._drapedFirstOrder.length === this._order.length);
            return this._drapedFirstOrder;
        }
        return this._order;
    }

    isLayerDraped(layer            )          {
        if (!this.terrain) return false;
        // $FlowFixMe[prop-missing]
        // $FlowFixMe[incompatible-use]
        if (typeof layer.isLayerDraped === 'function') return layer.isLayerDraped();
        return drapedLayers[layer.type];
    }

    _checkLoaded()       {
        if (!this._loaded) {
            throw new Error('Style is not done loading');
        }
    }

    /**
     * Apply queued style updates in a batch and recalculate zoom-dependent paint properties.
     * @private
     */
    update(parameters                      ) {
        if (!this._loaded) {
            return;
        }

        const changed = this._changed;
        if (this._changed) {
            const updatedIds = Object.keys(this._updatedLayers);
            const removedIds = Object.keys(this._removedLayers);

            if (updatedIds.length || removedIds.length) {
                this._updateWorkerLayers(updatedIds, removedIds);
            }
            for (const id in this._updatedSources) {
                const action = this._updatedSources[id];
                index.assert(action === 'reload' || action === 'clear');
                if (action === 'reload') {
                    this._reloadSource(id);
                } else if (action === 'clear') {
                    this._clearSource(id);
                }
            }

            this._updateTilesForChangedImages();

            for (const id in this._updatedPaintProps) {
                this._layers[id].updateTransitions(parameters);
            }

            this.light.updateTransitions(parameters);
            if (this.fog) {
                this.fog.updateTransitions(parameters);
            }

            this._resetUpdates();
        }

        const sourcesUsedBefore = {};

        for (const sourceId in this._sourceCaches) {
            const sourceCache = this._sourceCaches[sourceId];
            sourcesUsedBefore[sourceId] = sourceCache.used;
            sourceCache.used = false;
        }

        for (const layerId of this._order) {
            const layer = this._layers[layerId];

            layer.recalculate(parameters, this._availableImages);
            if (!layer.isHidden(parameters.zoom)) {
                const sourceCache = this._getLayerSourceCache(layer);
                if (sourceCache) sourceCache.used = true;
            }

            const painter = this.map.painter;
            if (painter) {
                const programIds = layer.getProgramIds();
                if (!programIds) continue;

                const programConfiguration = layer.getProgramConfiguration(parameters.zoom);

                for (const programId of programIds) {
                    painter.useProgram(programId, programConfiguration);
                }
            }
        }

        for (const sourceId in sourcesUsedBefore) {
            const sourceCache = this._sourceCaches[sourceId];
            if (sourcesUsedBefore[sourceId] !== sourceCache.used) {
                sourceCache.getSource().fire(new index.Event('data', {sourceDataType: 'visibility', dataType:'source', sourceId: sourceCache.getSource().id}));
            }
        }

        this.light.recalculate(parameters);
        if (this.terrain) {
            this.terrain.recalculate(parameters);
        }
        if (this.fog) {
            this.fog.recalculate(parameters);
        }
        this.z = parameters.zoom;

        if (this._markersNeedUpdate) {
            this._updateMarkersOpacity();
            this._markersNeedUpdate = false;
        }

        if (changed) {
            this.fire(new index.Event('data', {dataType: 'style'}));
        }
    }

    /*
     * Apply any queued image changes.
     */
    _updateTilesForChangedImages() {
        const changedImages = Object.keys(this._changedImages);
        if (changedImages.length) {
            for (const name in this._sourceCaches) {
                this._sourceCaches[name].reloadTilesForDependencies(['icons', 'patterns'], changedImages);
            }
            this._changedImages = {};
        }
    }

    _updateWorkerLayers(updatedIds               , removedIds               ) {
        this.dispatcher.broadcast('updateLayers', {
            layers: this._serializeLayers(updatedIds),
            removedIds
        });
    }

    _resetUpdates() {
        this._changed = false;

        this._updatedLayers = {};
        this._removedLayers = {};

        this._updatedSources = {};
        this._updatedPaintProps = {};

        this._changedImages = {};
    }

    /**
     * Update this style's state to match the given style JSON, performing only
     * the necessary mutations.
     *
     * May throw an Error ('Unimplemented: METHOD') if the mapbox-gl-style-spec
     * diff algorithm produces an operation that is not supported.
     *
     * @returns {boolean} true if any changes were made; false otherwise
     * @private
     */
    setState(nextState                    )          {
        this._checkLoaded();

        if (emitValidationErrors(this, index.validateStyle(nextState))) return false;

        nextState = index.clone$1(nextState);
        nextState.layers = derefLayers(nextState.layers);

        const changes = diffStyles(this.serialize(), nextState)
            .filter(op => !(op.command in ignoredDiffOperations));

        if (changes.length === 0) {
            return false;
        }

        const unimplementedOps = changes.filter(op => !(op.command in supportedDiffOperations));
        if (unimplementedOps.length > 0) {
            throw new Error(`Unimplemented: ${unimplementedOps.map(op => op.command).join(', ')}.`);
        }

        changes.forEach((op) => {
            if (op.command === 'setTransition' || op.command === 'setProjection') {
                // `transition` and `projection` are always read directly from
                // `this.stylesheet`, which we update below
                return;
            }
            (this     )[op.command].apply(this, op.args);
        });

        this.stylesheet = nextState;
        this._updateMapProjection();

        return true;
    }

    addImage(id        , image            )       {
        if (this.getImage(id)) {
            return this.fire(new index.ErrorEvent(new Error('An image with this name already exists.')));
        }
        this.imageManager.addImage(id, image);
        this._afterImageUpdated(id);
        return this;
    }

    updateImage(id        , image            ) {
        this.imageManager.updateImage(id, image);
    }

    getImage(id        )              {
        return this.imageManager.getImage(id);
    }

    removeImage(id        )       {
        if (!this.getImage(id)) {
            return this.fire(new index.ErrorEvent(new Error('No image with this name exists.')));
        }
        this.imageManager.removeImage(id);
        this._afterImageUpdated(id);
        return this;
    }

    _afterImageUpdated(id        ) {
        this._availableImages = this.imageManager.listImages();
        this._changedImages[id] = true;
        this._changed = true;
        this.dispatcher.broadcast('setImages', this._availableImages);
        this.fire(new index.Event('data', {dataType: 'style'}));
    }

    listImages()                {
        this._checkLoaded();
        return this._availableImages.slice();
    }

    addSource(id        , source                     , options                     = {})       {
        this._checkLoaded();

        if (this.getSource(id) !== undefined) {
            throw new Error('There is already a source with this ID');
        }

        if (!source.type) {
            throw new Error(`The type property must be defined, but only the following properties were given: ${Object.keys(source).join(', ')}.`);
        }

        const builtIns = ['vector', 'raster', 'geojson', 'video', 'image'];
        const shouldValidate = builtIns.indexOf(source.type) >= 0;
        if (shouldValidate && this._validate(index.validateSource, `sources.${id}`, source, null, options)) return;

        if (this.map && this.map._collectResourceTiming) (source     ).collectResourceTiming = true;

        const sourceInstance = create(id, source, this.dispatcher, this);

        sourceInstance.setEventedParent(this, () => ({
            isSourceLoaded: this._isSourceCacheLoaded(id),
            source: sourceInstance.serialize(),
            sourceId: id
        }));

        const addSourceCache = (onlySymbols         ) => {
            const sourceCacheId = (onlySymbols ? 'symbol:' : 'other:') + id;
            const sourceCache = this._sourceCaches[sourceCacheId] = new index.SourceCache(sourceCacheId, sourceInstance, onlySymbols);
            (onlySymbols ? this._symbolSourceCaches : this._otherSourceCaches)[id] = sourceCache;
            sourceCache.style = this;

            sourceCache.onAdd(this.map);
        };

        addSourceCache(false);
        if (source.type === 'vector' || source.type === 'geojson') {
            addSourceCache(true);
        }

        if (sourceInstance.onAdd) sourceInstance.onAdd(this.map);

        this._changed = true;
    }

    /**
     * Remove a source from this stylesheet, given its ID.
     * @param {string} id ID of the source to remove.
     * @throws {Error} If no source is found with the given ID.
     * @returns {Map} The {@link Map} object.
     */
    removeSource(id        )       {
        this._checkLoaded();

        const source = this.getSource(id);
        if (!source) {
            throw new Error('There is no source with this ID');
        }
        for (const layerId in this._layers) {
            if (this._layers[layerId].source === id) {
                return this.fire(new index.ErrorEvent(new Error(`Source "${id}" cannot be removed while layer "${layerId}" is using it.`)));
            }
        }
        if (this.terrain && this.terrain.get().source === id) {
            return this.fire(new index.ErrorEvent(new Error(`Source "${id}" cannot be removed while terrain is using it.`)));
        }

        const sourceCaches = this._getSourceCaches(id);
        for (const sourceCache of sourceCaches) {
            delete this._sourceCaches[sourceCache.id];
            delete this._updatedSources[sourceCache.id];
            sourceCache.fire(new index.Event('data', {sourceDataType: 'metadata', dataType:'source', sourceId: sourceCache.getSource().id}));
            sourceCache.setEventedParent(null);
            sourceCache.clearTiles();
        }
        delete this._otherSourceCaches[id];
        delete this._symbolSourceCaches[id];

        source.setEventedParent(null);
        if (source.onRemove) {
            source.onRemove(this.map);
        }
        this._changed = true;
        return this;
    }

    /**
    * Set the data of a GeoJSON source, given its ID.
    * @param {string} id ID of the source.
    * @param {GeoJSON|string} data GeoJSON source.
    */
    setGeoJSONSourceData(id        , data                  ) {
        this._checkLoaded();

        index.assert(this.getSource(id) !== undefined, 'There is no source with this ID');
        const geojsonSource                = (this.getSource(id)     );
        index.assert(geojsonSource.type === 'geojson');

        geojsonSource.setData(data);
        this._changed = true;
    }

    /**
     * Get a source by ID.
     * @param {string} id ID of the desired source.
     * @returns {?Source} The source object.
     */
    getSource(id        )          {
        const sourceCache = this._getSourceCache(id);
        return sourceCache && sourceCache.getSource();
    }

    _getSources()           {
        const sources = [];
        for (const id in this._otherSourceCaches) {
            const sourceCache = this._getSourceCache(id);
            if (sourceCache) sources.push(sourceCache.getSource());
        }

        return sources;
    }

    /**
     * Add a layer to the map style. The layer will be inserted before the layer with
     * ID `before`, or appended if `before` is omitted.
     * @param {Object | CustomLayerInterface} layerObject The style layer to add.
     * @param {string} [before] ID of an existing layer to insert before.
     * @param {Object} options Style setter options.
     * @returns {Map} The {@link Map} object.
     */
    addLayer(layerObject                                           , before         , options                     = {}) {
        this._checkLoaded();

        const id = layerObject.id;

        if (this.getLayer(id)) {
            this.fire(new index.ErrorEvent(new Error(`Layer with id "${id}" already exists on this map`)));
            return;
        }

        let layer;
        if (layerObject.type === 'custom') {

            if (emitValidationErrors(this, index.validateCustomStyleLayer(layerObject))) return;

            layer = index.createStyleLayer(layerObject);

        } else {
            if (typeof layerObject.source === 'object') {
                this.addSource(id, layerObject.source);
                layerObject = index.clone$1(layerObject);
                layerObject = (index.extend(layerObject, {source: id})     );
            }

            // this layer is not in the style.layers array, so we pass an impossible array index
            if (this._validate(index.validateLayer,
                `layers.${id}`, layerObject, {arrayIndex: -1}, options)) return;

            layer = index.createStyleLayer(layerObject);
            this._validateLayer(layer);

            layer.setEventedParent(this, {layer: {id}});
            this._serializedLayers[layer.id] = layer.serialize();
            this._updateLayerCount(layer, true);
        }

        const index$1 = before ? this._order.indexOf(before) : this._order.length;
        if (before && index$1 === -1) {
            this.fire(new index.ErrorEvent(new Error(`Layer with id "${before}" does not exist on this map.`)));
            return;
        }

        this._order.splice(index$1, 0, id);
        this._layerOrderChanged = true;

        this._layers[id] = layer;

        const sourceCache = this._getLayerSourceCache(layer);
        if (this._removedLayers[id] && layer.source && sourceCache && layer.type !== 'custom') {
            // If, in the current batch, we have already removed this layer
            // and we are now re-adding it with a different `type`, then we
            // need to clear (rather than just reload) the underyling source's
            // tiles.  Otherwise, tiles marked 'reloading' will have buckets /
            // buffers that are set up for the _previous_ version of this
            // layer, causing, e.g.:
            // https://github.com/mapbox/mapbox-gl-js/issues/3633
            const removed = this._removedLayers[id];
            delete this._removedLayers[id];
            if (removed.type !== layer.type) {
                this._updatedSources[layer.source] = 'clear';
            } else {
                this._updatedSources[layer.source] = 'reload';
                sourceCache.pause();
            }
        }
        this._updateLayer(layer);

        // $FlowFixMe[method-unbinding]
        if (layer.onAdd) {
            layer.onAdd(this.map);
        }

        this._updateDrapeFirstLayers();
    }

    /**
     * Moves a layer to a different z-position. The layer will be inserted before the layer with
     * ID `before`, or appended if `before` is omitted.
     * @param {string} id  ID of the layer to move.
     * @param {string} [before] ID of an existing layer to insert before.
     */
    moveLayer(id        , before         ) {
        this._checkLoaded();
        this._changed = true;

        const layer = this._layers[id];
        if (!layer) {
            this.fire(new index.ErrorEvent(new Error(`The layer '${id}' does not exist in the map's style and cannot be moved.`)));
            return;
        }

        if (id === before) {
            return;
        }

        const index$1 = this._order.indexOf(id);
        this._order.splice(index$1, 1);

        const newIndex = before ? this._order.indexOf(before) : this._order.length;
        if (before && newIndex === -1) {
            this.fire(new index.ErrorEvent(new Error(`Layer with id "${before}" does not exist on this map.`)));
            return;
        }
        this._order.splice(newIndex, 0, id);

        this._layerOrderChanged = true;

        this._updateDrapeFirstLayers();
    }

    /**
     * Remove the layer with the given id from the style.
     *
     * If no such layer exists, an `error` event is fired.
     *
     * @param {string} id ID of the layer to remove.
     * @fires Map.event:error
     */
    removeLayer(id        ) {
        this._checkLoaded();

        const layer = this._layers[id];
        if (!layer) {
            this.fire(new index.ErrorEvent(new Error(`The layer '${id}' does not exist in the map's style and cannot be removed.`)));
            return;
        }

        layer.setEventedParent(null);

        this._updateLayerCount(layer, false);

        const index$1 = this._order.indexOf(id);
        this._order.splice(index$1, 1);

        this._layerOrderChanged = true;
        this._changed = true;
        this._removedLayers[id] = layer;
        delete this._layers[id];
        delete this._serializedLayers[id];
        delete this._updatedLayers[id];
        delete this._updatedPaintProps[id];

        if (layer.onRemove) {
            layer.onRemove(this.map);
        }

        this._updateDrapeFirstLayers();
    }

    /**
     * Return the style layer object with the given `id`.
     *
     * @param {string} id ID of the desired layer.
     * @returns {?StyleLayer} A layer, if one with the given `id` exists.
     */
    getLayer(id        )              {
        return this._layers[id];
    }

    /**
     * Checks if a specific layer is present within the style.
     *
     * @param {string} id ID of the desired layer.
     * @returns {boolean} A boolean specifying if the given layer is present.
     */
    hasLayer(id        )          {
        return id in this._layers;
    }

    /**
     * Checks if a specific layer type is present within the style.
     *
     * @param {string} type Type of the desired layer.
     * @returns {boolean} A boolean specifying if the given layer type is present.
     */
    hasLayerType(type        )          {
        for (const layerId in this._layers) {
            const layer = this._layers[layerId];
            if (layer.type === type) {
                return true;
            }
        }
        return false;
    }

    setLayerZoomRange(layerId        , minzoom         , maxzoom         ) {
        this._checkLoaded();

        const layer = this.getLayer(layerId);
        if (!layer) {
            this.fire(new index.ErrorEvent(new Error(`The layer '${layerId}' does not exist in the map's style and cannot have zoom extent.`)));
            return;
        }

        if (layer.minzoom === minzoom && layer.maxzoom === maxzoom) return;

        if (minzoom != null) {
            layer.minzoom = minzoom;
        }
        if (maxzoom != null) {
            layer.maxzoom = maxzoom;
        }
        this._updateLayer(layer);
    }

    setFilter(layerId        , filter                      ,  options                     = {}) {
        this._checkLoaded();

        const layer = this.getLayer(layerId);
        if (!layer) {
            this.fire(new index.ErrorEvent(new Error(`The layer '${layerId}' does not exist in the map's style and cannot be filtered.`)));
            return;
        }

        if (index.deepEqual(layer.filter, filter)) {
            return;
        }

        if (filter === null || filter === undefined) {
            layer.filter = undefined;
            this._updateLayer(layer);
            return;
        }

        if (this._validate(index.validateFilter, `layers.${layer.id}.filter`, filter, {layerType: layer.type}, options)) {
            return;
        }

        layer.filter = index.clone$1(filter);
        this._updateLayer(layer);
    }

    /**
     * Get a layer's filter object.
     * @param {string} layerId The layer to inspect.
     * @returns {*} The layer's filter, if any.
     */
    getFilter(layerId        )                       {
        const layer = this.getLayer(layerId);
        return layer && index.clone$1(layer.filter);
    }

    setLayoutProperty(layerId        , name        , value     ,  options                     = {}) {
        this._checkLoaded();

        const layer = this.getLayer(layerId);
        if (!layer) {
            this.fire(new index.ErrorEvent(new Error(`The layer '${layerId}' does not exist in the map's style and cannot be styled.`)));
            return;
        }

        if (index.deepEqual(layer.getLayoutProperty(name), value)) return;

        layer.setLayoutProperty(name, value, options);
        this._updateLayer(layer);
    }

    /**
     * Get a layout property's value from a given layer.
     * @param {string} layerId The layer to inspect.
     * @param {string} name The name of the layout property.
     * @returns {*} The property value.
     */
    getLayoutProperty(layerId        , name        )                                     {
        const layer = this.getLayer(layerId);
        if (!layer) {
            this.fire(new index.ErrorEvent(new Error(`The layer '${layerId}' does not exist in the map's style.`)));
            return;
        }

        return layer.getLayoutProperty(name);
    }

    setPaintProperty(layerId        , name        , value     , options                     = {}) {
        this._checkLoaded();

        const layer = this.getLayer(layerId);
        if (!layer) {
            this.fire(new index.ErrorEvent(new Error(`The layer '${layerId}' does not exist in the map's style and cannot be styled.`)));
            return;
        }

        if (index.deepEqual(layer.getPaintProperty(name), value)) return;

        const requiresRelayout = layer.setPaintProperty(name, value, options);
        if (requiresRelayout) {
            this._updateLayer(layer);
        }

        this._changed = true;
        this._updatedPaintProps[layerId] = true;
    }

    getPaintProperty(layerId        , name        )                                                                     {
        const layer = this.getLayer(layerId);
        return layer && layer.getPaintProperty(name);
    }

    setFeatureState(target                                                                , state        ) {
        this._checkLoaded();
        const sourceId = target.source;
        const sourceLayer = target.sourceLayer;
        const source = this.getSource(sourceId);

        if (!source) {
            this.fire(new index.ErrorEvent(new Error(`The source '${sourceId}' does not exist in the map's style.`)));
            return;
        }
        const sourceType = source.type;
        if (sourceType === 'geojson' && sourceLayer) {
            this.fire(new index.ErrorEvent(new Error(`GeoJSON sources cannot have a sourceLayer parameter.`)));
            return;
        }
        if (sourceType === 'vector' && !sourceLayer) {
            this.fire(new index.ErrorEvent(new Error(`The sourceLayer parameter must be provided for vector source types.`)));
            return;
        }
        if (target.id === undefined) {
            this.fire(new index.ErrorEvent(new Error(`The feature id parameter must be provided.`)));
        }

        const sourceCaches = this._getSourceCaches(sourceId);
        for (const sourceCache of sourceCaches) {
            sourceCache.setFeatureState(sourceLayer, target.id, state);
        }
    }

    removeFeatureState(target                                                                 , key         ) {
        this._checkLoaded();
        const sourceId = target.source;
        const source = this.getSource(sourceId);

        if (!source) {
            this.fire(new index.ErrorEvent(new Error(`The source '${sourceId}' does not exist in the map's style.`)));
            return;
        }

        const sourceType = source.type;
        const sourceLayer = sourceType === 'vector' ? target.sourceLayer : undefined;

        if (sourceType === 'vector' && !sourceLayer) {
            this.fire(new index.ErrorEvent(new Error(`The sourceLayer parameter must be provided for vector source types.`)));
            return;
        }

        if (key && (typeof target.id !== 'string' && typeof target.id !== 'number')) {
            this.fire(new index.ErrorEvent(new Error(`A feature id is required to remove its specific state property.`)));
            return;
        }

        const sourceCaches = this._getSourceCaches(sourceId);
        for (const sourceCache of sourceCaches) {
            sourceCache.removeFeatureState(sourceLayer, target.id, key);
        }
    }

    getFeatureState(target                                                                )                 {
        this._checkLoaded();
        const sourceId = target.source;
        const sourceLayer = target.sourceLayer;
        const source = this.getSource(sourceId);

        if (!source) {
            this.fire(new index.ErrorEvent(new Error(`The source '${sourceId}' does not exist in the map's style.`)));
            return;
        }
        const sourceType = source.type;
        if (sourceType === 'vector' && !sourceLayer) {
            this.fire(new index.ErrorEvent(new Error(`The sourceLayer parameter must be provided for vector source types.`)));
            return;
        }
        if (target.id === undefined) {
            this.fire(new index.ErrorEvent(new Error(`The feature id parameter must be provided.`)));
        }

        const sourceCaches = this._getSourceCaches(sourceId);
        return sourceCaches[0].getFeatureState(sourceLayer, target.id);
    }

    getTransition()                          {
        return index.extend({duration: 300, delay: 0}, this.stylesheet && this.stylesheet.transition);
    }

    serialize()                     {
        const sources = {};
        for (const cacheId in this._sourceCaches) {
            const source = this._sourceCaches[cacheId].getSource();
            if (!sources[source.id]) {
                sources[source.id] = source.serialize();
            }
        }

        return index.filterObject({
            version: this.stylesheet.version,
            name: this.stylesheet.name,
            metadata: this.stylesheet.metadata,
            light: this.stylesheet.light,
            terrain: this.getTerrain() || undefined,
            fog: this.stylesheet.fog,
            center: this.stylesheet.center,
            zoom: this.stylesheet.zoom,
            bearing: this.stylesheet.bearing,
            pitch: this.stylesheet.pitch,
            sprite: this.stylesheet.sprite,
            glyphs: this.stylesheet.glyphs,
            transition: this.stylesheet.transition,
            projection: this.stylesheet.projection,
            sources,
            layers: this._serializeLayers(this._order)
        }, (value) => { return value !== undefined; });
    }

    _updateLayer(layer            ) {
        this._updatedLayers[layer.id] = true;
        const sourceCache = this._getLayerSourceCache(layer);
        if (layer.source && !this._updatedSources[layer.source] &&
            //Skip for raster layers (https://github.com/mapbox/mapbox-gl-js/issues/7865)
            sourceCache &&
            sourceCache.getSource().type !== 'raster') {
            this._updatedSources[layer.source] = 'reload';
            sourceCache.pause();
        }
        this._changed = true;
        layer.invalidateCompiledFilter();

    }

    _flattenAndSortRenderedFeatures(sourceResults            )               {
        // Feature order is complicated.
        // The order between features in two 2D layers is always determined by layer order.
        // The order between features in two 3D layers is always determined by depth.
        // The order between a feature in a 2D layer and a 3D layer is tricky:
        //      Most often layer order determines the feature order in this case. If
        //      a line layer is above a extrusion layer the line feature will be rendered
        //      above the extrusion. If the line layer is below the extrusion layer,
        //      it will be rendered below it.
        //
        //      There is a weird case though.
        //      You have layers in this order: extrusion_layer_a, line_layer, extrusion_layer_b
        //      Each layer has a feature that overlaps the other features.
        //      The feature in extrusion_layer_a is closer than the feature in extrusion_layer_b so it is rendered above.
        //      The feature in line_layer is rendered above extrusion_layer_a.
        //      This means that that the line_layer feature is above the extrusion_layer_b feature despite
        //      it being in an earlier layer.

        const isLayer3D = (layerId        ) => this._layers[layerId].type === 'fill-extrusion';

        const layerIndex = {};
        const features3D = [];
        for (let l = this._order.length - 1; l >= 0; l--) {
            const layerId = this._order[l];
            if (isLayer3D(layerId)) {
                layerIndex[layerId] = l;
                for (const sourceResult of sourceResults) {
                    const layerFeatures = sourceResult[layerId];
                    if (layerFeatures) {
                        for (const featureWrapper of layerFeatures) {
                            features3D.push(featureWrapper);
                        }
                    }
                }
            }
        }

        features3D.sort((a, b) => {
            return b.intersectionZ - a.intersectionZ;
        });

        const features = [];
        for (let l = this._order.length - 1; l >= 0; l--) {
            const layerId = this._order[l];

            if (isLayer3D(layerId)) {
                // add all 3D features that are in or above the current layer
                for (let i = features3D.length - 1; i >= 0; i--) {
                    const topmost3D = features3D[i].feature;
                    if (layerIndex[topmost3D.layer.id] < l) break;
                    features.push(topmost3D);
                    features3D.pop();
                }
            } else {
                for (const sourceResult of sourceResults) {
                    const layerFeatures = sourceResult[layerId];
                    if (layerFeatures) {
                        for (const featureWrapper of layerFeatures) {
                            features.push(featureWrapper.feature);
                        }
                    }
                }
            }
        }

        return features;
    }

    queryRenderedFeatures(queryGeometry                                    , params     , transform           )                     {
        if (params && params.filter) {
            this._validate(index.validateFilter, 'queryRenderedFeatures.filter', params.filter, null, params);
        }

        const includedSources = {};
        if (params && params.layers) {
            if (!Array.isArray(params.layers)) {
                this.fire(new index.ErrorEvent(new Error('parameters.layers must be an Array.')));
                return [];
            }
            for (const layerId of params.layers) {
                const layer = this._layers[layerId];
                if (!layer) {
                    // this layer is not in the style.layers array
                    this.fire(new index.ErrorEvent(new Error(`The layer '${layerId}' does not exist in the map's style and cannot be queried for features.`)));
                    return [];
                }
                includedSources[layer.source] = true;
            }
        }

        const sourceResults                     = [];

        params.availableImages = this._availableImages;

        const has3DLayer = (params && params.layers) ?
            params.layers.some((layerId) => {
                const layer = this.getLayer(layerId);
                return layer && layer.is3D();
            }) :
            this.has3DLayers();
        const queryGeometryStruct = QueryGeometry.createFromScreenPoints(queryGeometry, transform);

        for (const id in this._sourceCaches) {
            const sourceId = this._sourceCaches[id].getSource().id;
            if (params.layers && !includedSources[sourceId]) continue;
            sourceResults.push(
                queryRenderedFeatures(
                    this._sourceCaches[id],
                    this._layers,
                    this._serializedLayers,
                    queryGeometryStruct,
                    params,
                    transform,
                    has3DLayer,
                    !!this.map._showQueryGeometry)
            );
        }

        if (this.placement) {
            // If a placement has run, query against its CollisionIndex
            // for symbol results, and treat it as an extra source to merge
            sourceResults.push(
                queryRenderedSymbols(
                    this._layers,
                    this._serializedLayers,
                    // $FlowFixMe[method-unbinding]
                    this._getLayerSourceCache.bind(this),
                    queryGeometryStruct.screenGeometry,
                    params,
                    this.placement.collisionIndex,
                    this.placement.retainedQueryData)
            );
        }

        return (this._flattenAndSortRenderedFeatures(sourceResults)     );
    }

    querySourceFeatures(sourceID        , params                                                                  )                      {
        if (params && params.filter) {
            this._validate(index.validateFilter, 'querySourceFeatures.filter', params.filter, null, params);
        }
        const sourceCaches = this._getSourceCaches(sourceID);
        let results = [];
        for (const sourceCache of sourceCaches) {
            results = results.concat(querySourceFeatures(sourceCache, params));
        }
        return results;
    }

    addSourceType(name        , SourceType             , callback                )       {
        if (Style.getSourceType(name)) {
            return callback(new Error(`A source type called "${name}" already exists.`));
        }

        Style.setSourceType(name, SourceType);

        if (!SourceType.workerSourceURL) {
            return callback(null, null);
        }

        this.dispatcher.broadcast('loadWorkerSource', {
            name,
            url: SourceType.workerSourceURL
        }, callback);
    }

    getLight()                     {
        return this.light.getLight();
    }

    setLight(lightOptions                    , options                     = {}) {
        this._checkLoaded();

        const light = this.light.getLight();
        let _update = false;
        for (const key in lightOptions) {
            if (!index.deepEqual(lightOptions[key], light[key])) {
                _update = true;
                break;
            }
        }
        if (!_update) return;

        const parameters = this._setTransitionParameters({duration: 300, delay: 0});

        this.light.setLight(lightOptions, options);
        this.light.updateTransitions(parameters);
    }

    getTerrain()                        {
        return this.terrain && this.terrain.drapeRenderMode === DrapeRenderMode.elevated ? this.terrain.get() : null;
    }

    setTerrainForDraping() {
        const mockTerrainOptions = {source: '', exaggeration: 0};
        this.setTerrain(mockTerrainOptions, DrapeRenderMode.deferred);
    }

    // eslint-disable-next-line no-warning-comments
    // TODO: generic approach for root level property: light, terrain, skybox.
    // It is not done here to prevent rebasing issues.
    setTerrain(terrainOptions                       , drapeRenderMode         = DrapeRenderMode.elevated) {
        this._checkLoaded();

        // Disabling
        if (!terrainOptions) {
            delete this.terrain;
            delete this.stylesheet.terrain;
            this.dispatcher.broadcast('enableTerrain', false);
            this._force3DLayerUpdate();
            this._markersNeedUpdate = true;
            return;
        }

        let options                       = terrainOptions;
        if (drapeRenderMode === DrapeRenderMode.elevated) {
            // Input validation and source object unrolling
            if (typeof options.source === 'object') {
                const id = 'terrain-dem-src';
                this.addSource(id, options.source);
                options = index.clone$1(options);
                options = index.extend(options, {source: id});
            }

            if (this._validate(index.validateTerrain, 'terrain', options)) {
                return;
            }
        }

        // Enabling
        if (!this.terrain || (this.terrain && drapeRenderMode !== this.terrain.drapeRenderMode)) {
            if (!options) return;
            this._createTerrain(options, drapeRenderMode);
        } else { // Updating
            const terrain = this.terrain;
            const currSpec = terrain.get();

            for (const name of Object.keys(index.spec.terrain)) {
                // Fallback to use default style specification when the properties wasn't set
                if (!options.hasOwnProperty(name) && !!index.spec.terrain[name].default) {
                    // $FlowFixMe[prop-missing]
                    options[name] = index.spec.terrain[name].default;
                }
            }
            for (const key in options) {
                if (!index.deepEqual(options[key], currSpec[key])) {
                    terrain.set(options);
                    this.stylesheet.terrain = options;
                    const parameters = this._setTransitionParameters({duration: 0});
                    terrain.updateTransitions(parameters);
                    break;
                }
            }
        }

        this._updateDrapeFirstLayers();
        this._markersNeedUpdate = true;
    }

    _createFog(fogOptions                  ) {
        const fog = this.fog = new Fog(fogOptions, this.map.transform);
        this.stylesheet.fog = fogOptions;
        const parameters = this._setTransitionParameters({duration: 0});
        fog.updateTransitions(parameters);
    }

    _updateMarkersOpacity() {
        if (this.map._markers.length === 0) {
            return;
        }
        this.map._requestDomTask(() => {
            for (const marker of this.map._markers) {
                marker._evaluateOpacity();
            }
        });
    }

    getFog()                    {
        return this.fog ? this.fog.get() : null;
    }

    setFog(fogOptions                  ) {
        this._checkLoaded();

        if (!fogOptions) {
            // Remove fog
            delete this.fog;
            delete this.stylesheet.fog;
            this._markersNeedUpdate = true;
            return;
        }

        if (!this.fog) {
            // Initialize Fog
            this._createFog(fogOptions);
        } else {
            // Updating fog
            const fog = this.fog;
            const currSpec = fog.get();

            // empty object should pass through to set default values
            if (Object.keys(fogOptions).length === 0) fog.set(fogOptions);

            for (const key in fogOptions) {
                if (!index.deepEqual(fogOptions[key], currSpec[key])) {
                    fog.set(fogOptions);
                    this.stylesheet.fog = fogOptions;
                    const parameters = this._setTransitionParameters({duration: 0});
                    fog.updateTransitions(parameters);
                    break;
                }
            }
        }

        this._markersNeedUpdate = true;
    }

    _setTransitionParameters(transitionOptions        )                       {
        return {
            now: index.exported.now(),
            transition: index.extend(
                transitionOptions,
                this.stylesheet.transition)
        };
    }

    _updateDrapeFirstLayers() {
        if (!this.map._optimizeForTerrain || !this.terrain) {
            return;
        }

        const draped = this._order.filter((id) => {
            return this.isLayerDraped(this._layers[id]);
        });

        const nonDraped = this._order.filter((id) => {
            return !this.isLayerDraped(this._layers[id]);
        });
        this._drapedFirstOrder = [];
        this._drapedFirstOrder.push(...draped);
        this._drapedFirstOrder.push(...nonDraped);
    }

    _createTerrain(terrainOptions                      , drapeRenderMode        ) {
        const terrain = this.terrain = new Terrain$1(terrainOptions, drapeRenderMode);
        this.stylesheet.terrain = terrainOptions;
        this.dispatcher.broadcast('enableTerrain', !this.terrainSetForDrapingOnly());
        this._force3DLayerUpdate();
        const parameters = this._setTransitionParameters({duration: 0});
        terrain.updateTransitions(parameters);
    }

    _force3DLayerUpdate() {
        for (const layerId in this._layers) {
            const layer = this._layers[layerId];
            if (layer.type === 'fill-extrusion') {
                this._updateLayer(layer);
            }
        }
    }

    _forceSymbolLayerUpdate() {
        for (const layerId in this._layers) {
            const layer = this._layers[layerId];
            if (layer.type === 'symbol') {
                this._updateLayer(layer);
            }
        }
    }

    _validate(validate           , key        , value     , props     , options                         = {})          {
        if (options && options.validate === false) {
            return false;
        }
        return emitValidationErrors(this, validate.call(index.validateStyle, index.extend({
            key,
            style: this.serialize(),
            value,
            styleSpec: index.spec
        }, props)));
    }

    _remove() {
        if (this._request) {
            this._request.cancel();
            this._request = null;
        }
        if (this._spriteRequest) {
            this._spriteRequest.cancel();
            this._spriteRequest = null;
        }
        index.evented.off('pluginStateChange', this._rtlTextPluginCallback);
        for (const layerId in this._layers) {
            const layer             = this._layers[layerId];
            layer.setEventedParent(null);
        }
        for (const id in this._sourceCaches) {
            this._sourceCaches[id].clearTiles();
            this._sourceCaches[id].setEventedParent(null);
        }
        this.imageManager.setEventedParent(null);
        this.setEventedParent(null);
        this.dispatcher.remove();
    }

    _clearSource(id        ) {
        const sourceCaches = this._getSourceCaches(id);
        for (const sourceCache of sourceCaches) {
            sourceCache.clearTiles();
        }
    }

    _reloadSource(id        ) {
        const sourceCaches = this._getSourceCaches(id);
        for (const sourceCache of sourceCaches) {
            sourceCache.resume();
            sourceCache.reload();
        }
    }

    _reloadSources() {
        for (const source of this._getSources()) {
            if (source.reload) {
                source.reload();
            }
        }
    }

    _updateSources(transform           ) {
        for (const id in this._sourceCaches) {
            this._sourceCaches[id].update(transform);
        }
    }

    _generateCollisionBoxes() {
        for (const id in this._sourceCaches) {
            const sourceCache = this._sourceCaches[id];
            sourceCache.resume();
            sourceCache.reload();
        }
    }

    _updatePlacement(transform           , showCollisionBoxes         , fadeDuration        , crossSourceCollisions         , forceFullPlacement          = false)          {
        let symbolBucketsChanged = false;
        let placementCommitted = false;

        const layerTiles = {};

        for (const layerID of this._order) {
            const styleLayer = this._layers[layerID];
            if (styleLayer.type !== 'symbol') continue;

            if (!layerTiles[styleLayer.source]) {
                const sourceCache = this._getLayerSourceCache(styleLayer);
                if (!sourceCache) continue;
                layerTiles[styleLayer.source] = sourceCache.getRenderableIds(true)
                    .map((id) => sourceCache.getTileByID(id))
                    .sort((a, b) => (b.tileID.overscaledZ - a.tileID.overscaledZ) || (a.tileID.isLessThan(b.tileID) ? -1 : 1));
            }

            const layerBucketsChanged = this.crossTileSymbolIndex.addLayer(styleLayer, layerTiles[styleLayer.source], transform.center.lng, transform.projection);
            symbolBucketsChanged = symbolBucketsChanged || layerBucketsChanged;
        }
        this.crossTileSymbolIndex.pruneUnusedLayers(this._order);

        // Anything that changes our "in progress" layer and tile indices requires us
        // to start over. When we start over, we do a full placement instead of incremental
        // to prevent starvation.
        // We need to restart placement to keep layer indices in sync.
        // Also force full placement when fadeDuration === 0 to ensure that newly loaded
        // tiles will fully display symbols in their first frame
        forceFullPlacement = forceFullPlacement || this._layerOrderChanged || fadeDuration === 0;

        if (this._layerOrderChanged) {
            this.fire(new index.Event('neworder'));
        }

        if (forceFullPlacement || !this.pauseablePlacement || (this.pauseablePlacement.isDone() && !this.placement.stillRecent(index.exported.now(), transform.zoom))) {
            const fogState = this.fog && transform.projection.supportsFog ? this.fog.state : null;
            this.pauseablePlacement = new PauseablePlacement(transform, this._order, forceFullPlacement, showCollisionBoxes, fadeDuration, crossSourceCollisions, this.placement, fogState);
            this._layerOrderChanged = false;
        }

        if (this.pauseablePlacement.isDone()) {
            // the last placement finished running, but the next one hasn’t
            // started yet because of the `stillRecent` check immediately
            // above, so mark it stale to ensure that we request another
            // render frame
            this.placement.setStale();
        } else {
            this.pauseablePlacement.continuePlacement(this._order, this._layers, layerTiles);

            if (this.pauseablePlacement.isDone()) {
                this.placement = this.pauseablePlacement.commit(index.exported.now());
                placementCommitted = true;
            }

            if (symbolBucketsChanged) {
                // since the placement gets split over multiple frames it is possible
                // these buckets were processed before they were changed and so the
                // placement is already stale while it is in progress
                this.pauseablePlacement.placement.setStale();
            }
        }

        if (placementCommitted || symbolBucketsChanged) {
            for (const layerID of this._order) {
                const styleLayer = this._layers[layerID];
                if (styleLayer.type !== 'symbol') continue;
                this.placement.updateLayerOpacities(styleLayer, layerTiles[styleLayer.source]);
            }
        }

        // needsRender is false when we have just finished a placement that didn't change the visibility of any symbols
        const needsRerender = !this.pauseablePlacement.isDone() || this.placement.hasTransitions(index.exported.now());
        return needsRerender;
    }

    _releaseSymbolFadeTiles() {
        for (const id in this._sourceCaches) {
            this._sourceCaches[id].releaseSymbolFadeTiles();
        }
    }

    // Callbacks from web workers

    getImages(mapId        , params                                                                                , callback                                     ) {

        this.imageManager.getImages(params.icons, callback);

        // Apply queued image changes before setting the tile's dependencies so that the tile
        // is not reloaded unecessarily. Without this forced update the reload could happen in cases
        // like this one:
        // - icons contains "my-image"
        // - imageManager.getImages(...) triggers `onstyleimagemissing`
        // - the user adds "my-image" within the callback
        // - addImage adds "my-image" to this._changedImages
        // - the next frame triggers a reload of this tile even though it already has the latest version
        this._updateTilesForChangedImages();

        const setDependencies = (sourceCache             ) => {
            if (sourceCache) {
                sourceCache.setDependencies(params.tileID.key, params.type, params.icons);
            }
        };
        setDependencies(this._otherSourceCaches[params.source]);
        setDependencies(this._symbolSourceCaches[params.source]);
    }

    getGlyphs(mapId        , params                                        , callback                                                                                                      ) {
        this.glyphManager.getGlyphs(params.stacks, callback);
    }

    getResource(mapId        , params                   , callback                       )             {
        return index.makeRequest(params, callback);
    }

    _getSourceCache(source        )                     {
        return this._otherSourceCaches[source];
    }

    _getLayerSourceCache(layer            )                     {
        return layer.type === 'symbol' ?
            this._symbolSourceCaches[layer.source] :
            this._otherSourceCaches[layer.source];
    }

    _getSourceCaches(source        )                     {
        const sourceCaches = [];
        if (this._otherSourceCaches[source]) {
            sourceCaches.push(this._otherSourceCaches[source]);
        }
        if (this._symbolSourceCaches[source]) {
            sourceCaches.push(this._symbolSourceCaches[source]);
        }
        return sourceCaches;
    }

    _isSourceCacheLoaded(source        )          {
        const sourceCaches = this._getSourceCaches(source);
        if (sourceCaches.length === 0) {
            this.fire(new index.ErrorEvent(new Error(`There is no source with ID '${source}'`)));
            return false;
        }
        return sourceCaches.every(sc => sc.loaded());
    }

    has3DLayers()          {
        return this._num3DLayers > 0;
    }

    hasSymbolLayers()          {
        return this._numSymbolLayers > 0;
    }

    hasCircleLayers()          {
        return this._numCircleLayers > 0;
    }

    _clearWorkerCaches() {
        this.dispatcher.broadcast('clearCaches');
    }

    destroy() {
        this._clearWorkerCaches();
        if (this.terrainSetForDrapingOnly()) {
            delete this.terrain;
            delete this.stylesheet.terrain;
        }
    }
}

Style.getSourceType = getType;
Style.setSourceType = setType;
Style.registerForPluginStateChange = index.registerForPluginStateChange;

var preludeCommon = "// IMPORTANT:\n// This prelude is injected in both vertex and fragment shader be wary\n// of precision qualifiers as vertex and fragment precision may differ\n\n#define EPSILON 0.0000001\n#define PI 3.141592653589793\n#define EXTENT 8192.0\n#define HALF_PI PI / 2.0\n#define QUARTER_PI PI / 4.0\n#define RAD_TO_DEG 180.0 / PI\n#define DEG_TO_RAD PI / 180.0\n#define GLOBE_RADIUS EXTENT / PI / 2.0";

var preludeFrag = "// NOTE: This prelude is injected in the fragment shader only\n\n#if __VERSION__ >= 300\n#define varying in\n#define gl_FragColor glFragColor\n#define texture2D texture\n#define textureCube texture\nout vec4 glFragColor;\n#endif\n\nhighp vec3 hash(highp vec2 p) {\n    highp vec3 p3 = fract(p.xyx * vec3(443.8975, 397.2973, 491.1871));\n    p3 += dot(p3, p3.yxz + 19.19);\n    return fract((p3.xxy + p3.yzz) * p3.zyx);\n}\n\nvec3 dither(vec3 color, highp vec2 seed) {\n    vec3 rnd = hash(seed) + hash(seed + 0.59374) - 0.5;\n    return color + rnd / 255.0;\n}\n\nhighp float unpack_depth(highp vec4 rgba_depth)\n{\n    const highp vec4 bit_shift = vec4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0);\n    return dot(rgba_depth, bit_shift) * 2.0 - 1.0;\n}\n\n// Pack depth to RGBA. A piece of code copied in various libraries and WebGL\n// shadow mapping examples.\n// https://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/\nhighp vec4 pack_depth(highp float ndc_z) {\n    highp float depth = ndc_z * 0.5 + 0.5;\n    const highp vec4 bit_shift = vec4(255.0 * 255.0 * 255.0, 255.0 * 255.0, 255.0, 1.0);\n    const highp vec4 bit_mask  = vec4(0.0, 1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0);\n    highp vec4 res = fract(depth * bit_shift);\n    res -= res.xxyz * bit_mask;\n    return res;\n}\n";

var preludeVert = "// NOTE: This prelude is injected in the vertex shader only\n\n#if __VERSION__ >= 300\n#define attribute in\n#define varying out\n#define texture2D texture\n#endif\n\nfloat wrap(float n, float min, float max) {\n    float d = max - min;\n    float w = mod(mod(n - min, d) + d, d) + min;\n    return (w == min) ? max : w;\n}\n\n#ifdef PROJECTION_GLOBE_VIEW\nvec3 mercator_tile_position(mat4 matrix, vec2 tile_anchor, vec3 tile_id, vec2 mercator_center) {\n#ifndef PROJECTED_POS_ON_VIEWPORT\n    // tile_id.z contains pow(2.0, coord.canonical.z)\n    float tiles = tile_id.z;\n\n    vec2 mercator = (tile_anchor / EXTENT + tile_id.xy) / tiles;\n    mercator -= mercator_center;\n    mercator.x = wrap(mercator.x, -0.5, 0.5);\n\n    vec4 mercator_tile = vec4(mercator.xy * EXTENT, EXTENT / (2.0 * PI), 1.0);\n    mercator_tile = matrix * mercator_tile;\n\n    return mercator_tile.xyz;\n#else\n    return vec3(0.0);\n#endif\n}\n\nvec3 mix_globe_mercator(vec3 globe, vec3 mercator, float t) {\n    return mix(globe, mercator, t);\n}\n\nmat3 globe_mercator_surface_vectors(vec3 pos_normal, vec3 up_dir, float zoom_transition) {\n    vec3 normal = zoom_transition == 0.0 ? pos_normal : normalize(mix(pos_normal, up_dir, zoom_transition));\n    vec3 xAxis = normalize(vec3(normal.z, 0.0, -normal.x));\n    vec3 yAxis = normalize(cross(normal, xAxis));\n    return mat3(xAxis, yAxis, normal);\n}\n#endif // GLOBE_VIEW_PROJECTION\n\n// Unpack a pair of values that have been packed into a single float.\n// The packed values are assumed to be 8-bit unsigned integers, and are\n// packed like so:\n// packedValue = floor(input[0]) * 256 + input[1],\nvec2 unpack_float(const float packedValue) {\n    int packedIntValue = int(packedValue);\n    int v0 = packedIntValue / 256;\n    return vec2(v0, packedIntValue - v0 * 256);\n}\n\nvec2 unpack_opacity(const float packedOpacity) {\n    int intOpacity = int(packedOpacity) / 2;\n    return vec2(float(intOpacity) / 127.0, mod(packedOpacity, 2.0));\n}\n\n// To minimize the number of attributes needed, we encode a 4-component\n// color into a pair of floats (i.e. a vec2) as follows:\n// [ floor(color.r * 255) * 256 + color.g * 255,\n//   floor(color.b * 255) * 256 + color.g * 255 ]\nvec4 decode_color(const vec2 encodedColor) {\n    return vec4(\n        unpack_float(encodedColor[0]) / 255.0,\n        unpack_float(encodedColor[1]) / 255.0\n    );\n}\n\n// Unpack a pair of paint values and interpolate between them.\nfloat unpack_mix_vec2(const vec2 packedValue, const float t) {\n    return mix(packedValue[0], packedValue[1], t);\n}\n\n// Unpack a pair of paint values and interpolate between them.\nvec4 unpack_mix_color(const vec4 packedColors, const float t) {\n    vec4 minColor = decode_color(vec2(packedColors[0], packedColors[1]));\n    vec4 maxColor = decode_color(vec2(packedColors[2], packedColors[3]));\n    return mix(minColor, maxColor, t);\n}\n\n// The offset depends on how many pixels are between the world origin and the edge of the tile:\n// vec2 offset = mod(pixel_coord, size)\n//\n// At high zoom levels there are a ton of pixels between the world origin and the edge of the tile.\n// The glsl spec only guarantees 16 bits of precision for highp floats. We need more than that.\n//\n// The pixel_coord is passed in as two 16 bit values:\n// pixel_coord_upper = floor(pixel_coord / 2^16)\n// pixel_coord_lower = mod(pixel_coord, 2^16)\n//\n// The offset is calculated in a series of steps that should preserve this precision:\nvec2 get_pattern_pos(const vec2 pixel_coord_upper, const vec2 pixel_coord_lower,\n    const vec2 pattern_size, const float tile_units_to_pixels, const vec2 pos) {\n\n    vec2 offset = mod(mod(mod(pixel_coord_upper, pattern_size) * 256.0, pattern_size) * 256.0 + pixel_coord_lower, pattern_size);\n    return (tile_units_to_pixels * pos + offset) / pattern_size;\n}\n\nconst vec4 AWAY = vec4(-1000.0, -1000.0, -1000.0, 1); // Normalized device coordinate that is not rendered.\n";

var backgroundFrag = "uniform vec4 u_color;\nuniform float u_opacity;\n\n#ifdef LIGHTING_3D_MODE\nvarying vec4 v_color;\n#endif\n\nvoid main() {\n    vec4 out_color;\n#ifdef LIGHTING_3D_MODE\n    out_color = v_color;\n#else\n    out_color = u_color;\n#endif\n#ifdef FOG\n    out_color = fog_dither(fog_apply_premultiplied(out_color, v_fog_pos));\n#endif\n\n    gl_FragColor = out_color * u_opacity;\n\n#ifdef OVERDRAW_INSPECTOR\n    gl_FragColor = vec4(1.0);\n#endif\n}\n";

var backgroundVert = "attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\n\n#ifdef LIGHTING_3D_MODE\nuniform vec4 u_color;\nvarying vec4 v_color;\n#endif\n\nvoid main() {\n    gl_Position = u_matrix * vec4(a_pos, 0, 1);\n\n#ifdef LIGHTING_3D_MODE\n    v_color = apply_lighting(u_color);\n#endif\n#ifdef FOG\n    v_fog_pos = fog_position(a_pos);\n#endif\n}\n";

var backgroundPatternFrag = "uniform vec2 u_pattern_tl;\nuniform vec2 u_pattern_br;\nuniform vec2 u_texsize;\nuniform float u_opacity;\n\nuniform sampler2D u_image;\n\nvarying vec2 v_pos;\n\nvoid main() {\n    vec2 imagecoord = mod(v_pos, 1.0);\n    vec2 pos = mix(u_pattern_tl / u_texsize, u_pattern_br / u_texsize, imagecoord);\n    vec4 out_color = texture2D(u_image, pos);\n\n#ifdef LIGHTING_3D_MODE\n    out_color = apply_lighting(out_color);\n#endif\n#ifdef FOG\n    out_color = fog_dither(fog_apply_premultiplied(out_color, v_fog_pos));\n#endif\n\n    gl_FragColor = out_color * u_opacity;\n\n#ifdef OVERDRAW_INSPECTOR\n    gl_FragColor = vec4(1.0);\n#endif\n}\n";

var backgroundPatternVert = "uniform mat4 u_matrix;\nuniform vec2 u_pattern_size;\nuniform vec2 u_pixel_coord_upper;\nuniform vec2 u_pixel_coord_lower;\nuniform float u_tile_units_to_pixels;\n\nattribute vec2 a_pos;\n\nvarying vec2 v_pos;\n\nvoid main() {\n    gl_Position = u_matrix * vec4(a_pos, 0, 1);\n\n    v_pos = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, u_pattern_size, u_tile_units_to_pixels, a_pos);\n\n#ifdef FOG\n    v_fog_pos = fog_position(a_pos);\n#endif\n}\n";

var circleFrag = "varying vec3 v_data;\nvarying float v_visibility;\n\n#pragma mapbox: define highp vec4 color\n#pragma mapbox: define mediump float radius\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define highp vec4 stroke_color\n#pragma mapbox: define mediump float stroke_width\n#pragma mapbox: define lowp float stroke_opacity\n\nvoid main() {\n    #pragma mapbox: initialize highp vec4 color\n    #pragma mapbox: initialize mediump float radius\n    #pragma mapbox: initialize lowp float blur\n    #pragma mapbox: initialize lowp float opacity\n    #pragma mapbox: initialize highp vec4 stroke_color\n    #pragma mapbox: initialize mediump float stroke_width\n    #pragma mapbox: initialize lowp float stroke_opacity\n\n    vec2 extrude = v_data.xy;\n    float extrude_length = length(extrude);\n\n    lowp float antialiasblur = v_data.z;\n    float antialiased_blur = -max(blur, antialiasblur);\n\n    float opacity_t = smoothstep(0.0, antialiased_blur, extrude_length - 1.0);\n\n    float color_t = stroke_width < 0.01 ? 0.0 : smoothstep(\n        antialiased_blur,\n        0.0,\n        extrude_length - radius / (radius + stroke_width)\n    );\n\n    vec4 out_color = mix(color * opacity, stroke_color * stroke_opacity, color_t);\n\n#ifdef LIGHTING_3D_MODE\n    out_color = apply_lighting(out_color);\n#endif\n#ifdef FOG\n    out_color = fog_apply_premultiplied(out_color, v_fog_pos);\n#endif\n\n    gl_FragColor = out_color * (v_visibility * opacity_t);\n\n#ifdef OVERDRAW_INSPECTOR\n    gl_FragColor = vec4(1.0);\n#endif\n}\n";

var circleVert = "#define NUM_VISIBILITY_RINGS 2\n#define INV_SQRT2 0.70710678\n#define ELEVATION_BIAS 0.0001\n\n#define NUM_SAMPLES_PER_RING 16\n\nuniform mat4 u_matrix;\nuniform mat2 u_extrude_scale;\nuniform lowp float u_device_pixel_ratio;\nuniform highp float u_camera_to_center_distance;\n\nattribute vec2 a_pos;\n\n#ifdef PROJECTION_GLOBE_VIEW\nattribute vec3 a_pos_3;         // Projected position on the globe\nattribute vec3 a_pos_normal_3;  // Surface normal at the position\n\n// Uniforms required for transition between globe and mercator\nuniform mat4 u_inv_rot_matrix;\nuniform vec2 u_merc_center;\nuniform vec3 u_tile_id;\nuniform float u_zoom_transition;\nuniform vec3 u_up_dir;\n#endif\n\nvarying vec3 v_data;\nvarying float v_visibility;\n\n#pragma mapbox: define highp vec4 color\n#pragma mapbox: define mediump float radius\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define highp vec4 stroke_color\n#pragma mapbox: define mediump float stroke_width\n#pragma mapbox: define lowp float stroke_opacity\n\nvec2 calc_offset(vec2 extrusion, float radius, float stroke_width,  float view_scale) {\n    return extrusion * (radius + stroke_width) * u_extrude_scale * view_scale;\n}\n\nfloat cantilevered_elevation(vec2 pos, float radius, float stroke_width, float view_scale) {\n    vec2 c1 = pos + calc_offset(vec2(-1,-1), radius, stroke_width, view_scale);\n    vec2 c2 = pos + calc_offset(vec2(1,-1), radius, stroke_width, view_scale);\n    vec2 c3 = pos + calc_offset(vec2(1,1), radius, stroke_width, view_scale);\n    vec2 c4 = pos + calc_offset(vec2(-1,1), radius, stroke_width, view_scale);\n    float h1 = elevation(c1) + ELEVATION_BIAS;\n    float h2 = elevation(c2) + ELEVATION_BIAS;\n    float h3 = elevation(c3) + ELEVATION_BIAS;\n    float h4 = elevation(c4) + ELEVATION_BIAS;\n    return max(h4, max(h3, max(h1,h2)));\n}\n\nfloat circle_elevation(vec2 pos) {\n#if defined(TERRAIN)\n    return elevation(pos) + ELEVATION_BIAS;\n#else\n    return 0.0;\n#endif\n}\n\nvec4 project_vertex(vec2 extrusion, vec4 world_center, vec4 projected_center, float radius, float stroke_width,  float view_scale, mat3 surface_vectors) {\n    vec2 sample_offset = calc_offset(extrusion, radius, stroke_width, view_scale);\n#ifdef PITCH_WITH_MAP\n    #ifdef PROJECTION_GLOBE_VIEW\n        return u_matrix * ( world_center + vec4(sample_offset.x * surface_vectors[0] + sample_offset.y * surface_vectors[1], 0) );\n    #else\n        return u_matrix * ( world_center + vec4(sample_offset, 0, 0) );\n    #endif\n#else\n    return projected_center + vec4(sample_offset, 0, 0);\n#endif\n}\n\nfloat get_sample_step() {\n#ifdef PITCH_WITH_MAP\n    return 2.0 * PI / float(NUM_SAMPLES_PER_RING);\n#else\n    // We want to only sample the top half of the circle when it is viewport-aligned.\n    // This is to prevent the circle from intersecting with the ground plane below it at high pitch.\n    return PI / float(NUM_SAMPLES_PER_RING);\n#endif\n}\n\nvoid main(void) {\n    #pragma mapbox: initialize highp vec4 color\n    #pragma mapbox: initialize mediump float radius\n    #pragma mapbox: initialize lowp float blur\n    #pragma mapbox: initialize lowp float opacity\n    #pragma mapbox: initialize highp vec4 stroke_color\n    #pragma mapbox: initialize mediump float stroke_width\n    #pragma mapbox: initialize lowp float stroke_opacity\n\n    // unencode the extrusion vector that we snuck into the a_pos vector\n    vec2 extrude = vec2(mod(a_pos, 2.0) * 2.0 - 1.0);\n\n    // multiply a_pos by 0.5, since we had it * 2 in order to sneak\n    // in extrusion data\n    vec2 circle_center = floor(a_pos * 0.5);\n\n    vec4 world_center;\n    mat3 surface_vectors;\n#ifdef PROJECTION_GLOBE_VIEW\n    // Compute positions on both globe and mercator plane to support transition between the two modes\n    // Apply extra scaling to extrusion to cover different pixel space ratios (which is dependant on the latitude)\n    vec3 pos_normal_3 = a_pos_normal_3 / 16384.0;\n    surface_vectors = globe_mercator_surface_vectors(pos_normal_3, u_up_dir, u_zoom_transition);\n\n    vec3 surface_extrusion = extrude.x * surface_vectors[0] + extrude.y * surface_vectors[1];\n    vec3 globe_elevation = elevationVector(circle_center) * circle_elevation(circle_center);\n    vec3 globe_pos = a_pos_3 + surface_extrusion + globe_elevation;\n    vec3 mercator_elevation = u_up_dir * u_tile_up_scale * circle_elevation(circle_center);\n    vec3 merc_pos = mercator_tile_position(u_inv_rot_matrix, circle_center, u_tile_id, u_merc_center) + surface_extrusion + mercator_elevation;\n    vec3 pos = mix_globe_mercator(globe_pos, merc_pos, u_zoom_transition);\n    world_center = vec4(pos, 1);\n#else \n    surface_vectors = mat3(1.0);\n    // extract height offset for terrain, this returns 0 if terrain is not active\n    float height = circle_elevation(circle_center);\n    world_center = vec4(circle_center, height, 1);\n#endif\n\n    vec4 projected_center = u_matrix * world_center;\n\n    float view_scale = 0.0;\n    #ifdef PITCH_WITH_MAP\n        #ifdef SCALE_WITH_MAP\n            view_scale = 1.0;\n        #else\n            // Pitching the circle with the map effectively scales it with the map\n            // To counteract the effect for pitch-scale: viewport, we rescale the\n            // whole circle based on the pitch scaling effect at its central point\n            view_scale = projected_center.w / u_camera_to_center_distance;\n        #endif\n    #else\n        #ifdef SCALE_WITH_MAP\n            view_scale = u_camera_to_center_distance;\n        #else\n            view_scale = projected_center.w;\n        #endif\n    #endif\n    gl_Position = project_vertex(extrude, world_center, projected_center, radius, stroke_width, view_scale, surface_vectors);\n\n    float visibility = 0.0;\n    #ifdef TERRAIN\n        float step = get_sample_step();\n        vec4 occlusion_world_center;\n        vec4 occlusion_projected_center;\n        #ifdef PITCH_WITH_MAP\n            // to prevent the circle from self-intersecting with the terrain underneath on a sloped hill,\n            // we calculate the elevation at each corner and pick the highest one when computing visibility.\n            float cantilevered_height = cantilevered_elevation(circle_center, radius, stroke_width, view_scale);\n            occlusion_world_center = vec4(circle_center, cantilevered_height, 1);\n            occlusion_projected_center = u_matrix * occlusion_world_center;\n        #else\n            occlusion_world_center = world_center;\n            occlusion_projected_center = projected_center;\n        #endif\n        for(int ring = 0; ring < NUM_VISIBILITY_RINGS; ring++) {\n            float scale = (float(ring) + 1.0)/float(NUM_VISIBILITY_RINGS);\n            for(int i = 0; i < NUM_SAMPLES_PER_RING; i++) {\n                vec2 extrusion = vec2(cos(step * float(i)), -sin(step * float(i))) * scale;\n                vec4 frag_pos = project_vertex(extrusion, occlusion_world_center, occlusion_projected_center, radius, stroke_width, view_scale, surface_vectors);\n                visibility += float(!isOccluded(frag_pos));\n            }\n        }\n        visibility /= float(NUM_VISIBILITY_RINGS) * float(NUM_SAMPLES_PER_RING);\n    #else\n        visibility = 1.0;\n    #endif\n    // This is a temporary overwrite until we add support for terrain occlusion for the globe view\n    // Having a separate overwrite here makes the metal shader generation simpler for the default case\n    #ifdef PROJECTION_GLOBE_VIEW\n        visibility = 1.0;\n    #endif\n    v_visibility = visibility;\n\n    // This is a minimum blur distance that serves as a faux-antialiasing for\n    // the circle. since blur is a ratio of the circle's size and the intent is\n    // to keep the blur at roughly 1px, the two are inversely related.\n    lowp float antialiasblur = 1.0 / u_device_pixel_ratio / (radius + stroke_width);\n\n    v_data = vec3(extrude.x, extrude.y, antialiasblur);\n\n#ifdef FOG\n    v_fog_pos = fog_position(world_center.xyz);\n#endif\n}\n";

var clippingMaskFrag = "void main() {\n    gl_FragColor = vec4(1.0);\n}\n";

var clippingMaskVert = "attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\n\nvoid main() {\n    gl_Position = u_matrix * vec4(a_pos, 0, 1);\n}\n";

var heatmapFrag = "uniform highp float u_intensity;\n\nvarying vec2 v_extrude;\n\n#pragma mapbox: define highp float weight\n\n// Gaussian kernel coefficient: 1 / sqrt(2 * PI)\n#define GAUSS_COEF 0.3989422804014327\n\nvoid main() {\n    #pragma mapbox: initialize highp float weight\n\n    // Kernel density estimation with a Gaussian kernel of size 5x5\n    float d = -0.5 * 3.0 * 3.0 * dot(v_extrude, v_extrude);\n    float val = weight * u_intensity * GAUSS_COEF * exp(d);\n\n    gl_FragColor = vec4(val, 1.0, 1.0, 1.0);\n\n#ifdef FOG\n    // Globe uses a fixed range and heatmaps preserve\n    // their color with this thin atmosphere layer to\n    // prevent this layer from overly flickering\n    if (u_is_globe == 0) {\n        // Heatmaps work differently than other layers, so we operate on the accumulated\n        // density rather than a final color. The power is chosen so that the density\n        // fades into the fog at a reasonable rate.\n        gl_FragColor.r *= pow(1.0 - fog_opacity(v_fog_pos), 2.0);\n    }\n#endif\n\n#ifdef OVERDRAW_INSPECTOR\n    gl_FragColor = vec4(1.0);\n#endif\n}\n";

var heatmapVert = "\nuniform mat4 u_matrix;\nuniform float u_extrude_scale;\nuniform float u_opacity;\nuniform float u_intensity;\n\nattribute vec2 a_pos;\n\n#ifdef PROJECTION_GLOBE_VIEW\nattribute vec3 a_pos_3;         // Projected position on the globe\nattribute vec3 a_pos_normal_3;  // Surface normal at the position\n\n// Uniforms required for transition between globe and mercator\nuniform mat4 u_inv_rot_matrix;\nuniform vec2 u_merc_center;\nuniform vec3 u_tile_id;\nuniform float u_zoom_transition;\nuniform vec3 u_up_dir;\n#endif\n\nvarying vec2 v_extrude;\n\n#pragma mapbox: define highp float weight\n#pragma mapbox: define mediump float radius\n\n// Effective \"0\" in the kernel density texture to adjust the kernel size to;\n// this empirically chosen number minimizes artifacts on overlapping kernels\n// for typical heatmap cases (assuming clustered source)\nconst highp float ZERO = 1.0 / 255.0 / 16.0;\n\n// Gaussian kernel coefficient: 1 / sqrt(2 * PI)\n#define GAUSS_COEF 0.3989422804014327\n\nvoid main(void) {\n    #pragma mapbox: initialize highp float weight\n    #pragma mapbox: initialize mediump float radius\n\n    // unencode the extrusion vector that we snuck into the a_pos vector\n    vec2 unscaled_extrude = vec2(mod(a_pos, 2.0) * 2.0 - 1.0);\n\n    // This 'extrude' comes in ranging from [-1, -1], to [1, 1].  We'll use\n    // it to produce the vertices of a square mesh framing the point feature\n    // we're adding to the kernel density texture.  We'll also pass it as\n    // a varying, so that the fragment shader can determine the distance of\n    // each fragment from the point feature.\n    // Before we do so, we need to scale it up sufficiently so that the\n    // kernel falls effectively to zero at the edge of the mesh.\n    // That is, we want to know S such that\n    // weight * u_intensity * GAUSS_COEF * exp(-0.5 * 3.0^2 * S^2) == ZERO\n    // Which solves to:\n    // S = sqrt(-2.0 * log(ZERO / (weight * u_intensity * GAUSS_COEF))) / 3.0\n    float S = sqrt(-2.0 * log(ZERO / weight / u_intensity / GAUSS_COEF)) / 3.0;\n\n    // Pass the varying in units of radius\n    v_extrude = S * unscaled_extrude;\n\n    // Scale by radius and the zoom-based scale factor to produce actual\n    // mesh position\n    vec2 extrude = v_extrude * radius * u_extrude_scale;\n\n    // multiply a_pos by 0.5, since we had it * 2 in order to sneak\n    // in extrusion data\n    vec2 tilePos = floor(a_pos * 0.5);\n\n    vec3 pos;\n#ifdef PROJECTION_GLOBE_VIEW\n    // Compute positions on both globe and mercator plane to support transition between the two modes\n    // Apply extra scaling to extrusion to cover different pixel space ratios (which is dependant on the latitude)\n    vec3 pos_normal_3 = a_pos_normal_3 / 16384.0;\n    mat3 surface_vectors = globe_mercator_surface_vectors(pos_normal_3, u_up_dir, u_zoom_transition);\n    vec3 surface_extrusion = extrude.x * surface_vectors[0] + extrude.y * surface_vectors[1];\n    vec3 globe_elevation = elevationVector(tilePos) * elevation(tilePos);\n    vec3 globe_pos = a_pos_3 + surface_extrusion + globe_elevation;\n    vec3 mercator_elevation = u_up_dir * u_tile_up_scale * elevation(tilePos);\n    vec3 merc_pos = mercator_tile_position(u_inv_rot_matrix, tilePos, u_tile_id, u_merc_center) + surface_extrusion + mercator_elevation;\n    pos = mix_globe_mercator(globe_pos, merc_pos, u_zoom_transition);\n#else\n    pos = vec3(tilePos + extrude, elevation(tilePos));\n#endif\n\n    gl_Position = u_matrix * vec4(pos, 1);\n\n#ifdef FOG\n    v_fog_pos = fog_position(pos);\n#endif\n}\n";

var heatmapTextureFrag = "uniform sampler2D u_image;\nuniform sampler2D u_color_ramp;\nuniform float u_opacity;\nvarying vec2 v_pos;\n\nvoid main() {\n    float t = texture2D(u_image, v_pos).r;\n    vec4 color = texture2D(u_color_ramp, vec2(t, 0.5));\n\n    gl_FragColor = color * u_opacity;\n\n#ifdef OVERDRAW_INSPECTOR\n    gl_FragColor = vec4(0.0);\n#endif\n}\n";

var heatmapTextureVert = "attribute vec2 a_pos;\nvarying vec2 v_pos;\n\nvoid main() {\n    gl_Position = vec4(a_pos, 0, 1);\n\n    v_pos = a_pos * 0.5 + 0.5;\n}\n";

var collisionBoxFrag = "varying float v_placed;\nvarying float v_notUsed;\n\nvoid main() {\n    vec4 red  = vec4(1.0, 0.0, 0.0, 1.0); // Red = collision, hide label\n    vec4 blue = vec4(0.0, 0.0, 1.0, 0.5); // Blue = no collision, label is showing\n\n    gl_FragColor  = mix(red, blue, step(0.5, v_placed)) * 0.5;\n    gl_FragColor *= mix(1.0, 0.1, step(0.5, v_notUsed));\n}";

var collisionBoxVert = "attribute vec3 a_pos;\nattribute vec2 a_anchor_pos;\nattribute vec2 a_extrude;\nattribute vec2 a_placed;\nattribute vec2 a_shift;\nattribute float a_size_scale;\nattribute vec2 a_padding;\n\nuniform mat4 u_matrix;\nuniform vec2 u_extrude_scale;\nuniform float u_camera_to_center_distance;\n\nvarying float v_placed;\nvarying float v_notUsed;\n\nvoid main() {\n    vec4 projectedPoint = u_matrix * vec4(a_pos + elevationVector(a_anchor_pos) * elevation(a_anchor_pos), 1);\n\n    highp float camera_to_anchor_distance = projectedPoint.w;\n    highp float collision_perspective_ratio = clamp(\n        0.5 + 0.5 * (u_camera_to_center_distance / camera_to_anchor_distance),\n        0.0, // Prevents oversized near-field boxes in pitched/overzoomed tiles\n        1.5);\n\n    gl_Position = projectedPoint;\n    gl_Position.xy += (a_extrude * a_size_scale + a_shift + a_padding) * u_extrude_scale * gl_Position.w * collision_perspective_ratio;\n\n    v_placed = a_placed.x;\n    v_notUsed = a_placed.y;\n}\n";

var collisionCircleFrag = "varying float v_radius;\nvarying vec2 v_extrude;\nvarying float v_perspective_ratio;\nvarying float v_collision;\n\nvoid main() {\n    float alpha = 0.5 * min(v_perspective_ratio, 1.0);\n    float stroke_radius = 0.9 * max(v_perspective_ratio, 1.0);\n\n    float distance_to_center = length(v_extrude);\n    float distance_to_edge = abs(distance_to_center - v_radius);\n    float opacity_t = smoothstep(-stroke_radius, 0.0, -distance_to_edge);\n\n    vec4 color = mix(vec4(0.0, 0.0, 1.0, 0.5), vec4(1.0, 0.0, 0.0, 1.0), v_collision);\n\n    gl_FragColor = color * alpha * opacity_t;\n}\n";

var collisionCircleVert = "attribute vec2 a_pos_2f;\nattribute float a_radius;\nattribute vec2 a_flags;\n\nuniform mat4 u_matrix;\nuniform mat4 u_inv_matrix;\nuniform vec2 u_viewport_size;\nuniform float u_camera_to_center_distance;\n\nvarying float v_radius;\nvarying vec2 v_extrude;\nvarying float v_perspective_ratio;\nvarying float v_collision;\n\nvec3 toTilePosition(vec2 screenPos) {\n    // Shoot a ray towards the ground to reconstruct the depth-value\n    vec4 rayStart = u_inv_matrix * vec4(screenPos, -1.0, 1.0);\n    vec4 rayEnd   = u_inv_matrix * vec4(screenPos,  1.0, 1.0);\n\n    rayStart.xyz /= rayStart.w;\n    rayEnd.xyz   /= rayEnd.w;\n\n    highp float t = (0.0 - rayStart.z) / (rayEnd.z - rayStart.z);\n    return mix(rayStart.xyz, rayEnd.xyz, t);\n}\n\nvoid main() {\n    vec2 quadCenterPos = a_pos_2f;\n    float radius = a_radius;\n    float collision = a_flags.x;\n    float vertexIdx = a_flags.y;\n\n    vec2 quadVertexOffset = vec2(\n        mix(-1.0, 1.0, float(vertexIdx >= 2.0)),\n        mix(-1.0, 1.0, float(vertexIdx >= 1.0 && vertexIdx <= 2.0)));\n\n    vec2 quadVertexExtent = quadVertexOffset * radius;\n\n    // Screen position of the quad might have been computed with different camera parameters.\n    // Transform the point to a proper position on the current viewport\n    vec3 tilePos = toTilePosition(quadCenterPos);\n    vec4 clipPos = u_matrix * vec4(tilePos, 1.0);\n\n    highp float camera_to_anchor_distance = clipPos.w;\n    highp float collision_perspective_ratio = clamp(\n        0.5 + 0.5 * (u_camera_to_center_distance / camera_to_anchor_distance),\n        0.0, // Prevents oversized near-field circles in pitched/overzoomed tiles\n        4.0);\n\n    // Apply small padding for the anti-aliasing effect to fit the quad\n    // Note that v_radius and v_extrude are in screen coordinates already\n    float padding_factor = 1.2;\n    v_radius = radius;\n    v_extrude = quadVertexExtent * padding_factor;\n    v_perspective_ratio = collision_perspective_ratio;\n    v_collision = collision;\n\n    gl_Position = vec4(clipPos.xyz / clipPos.w, 1.0) + vec4(quadVertexExtent * padding_factor / u_viewport_size * 2.0, 0.0, 0.0);\n}\n";

var debugFrag = "uniform highp vec4 u_color;\nuniform sampler2D u_overlay;\n\nvarying vec2 v_uv;\n\nvoid main() {\n    vec4 overlay_color = texture2D(u_overlay, v_uv);\n    gl_FragColor = mix(u_color, overlay_color, overlay_color.a);\n}\n";

var debugVert = "attribute vec2 a_pos;\n#ifdef PROJECTION_GLOBE_VIEW\nattribute vec3 a_pos_3;\n#endif\nvarying vec2 v_uv;\n\nuniform mat4 u_matrix;\nuniform float u_overlay_scale;\n\nvoid main() {\n    // This vertex shader expects a EXTENT x EXTENT quad,\n    // The UV co-ordinates for the overlay texture can be calculated using that knowledge\n    float h = elevation(a_pos);\n    v_uv = a_pos / 8192.0;\n#ifdef PROJECTION_GLOBE_VIEW\n    gl_Position = u_matrix * vec4(a_pos_3 + elevationVector(a_pos) * h, 1);\n#else\n    gl_Position = u_matrix * vec4(a_pos * u_overlay_scale, h, 1);\n#endif\n}\n";

var fillFrag = "#pragma mapbox: define highp vec4 color\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n    #pragma mapbox: initialize highp vec4 color\n    #pragma mapbox: initialize lowp float opacity\n\n    vec4 out_color = color;\n\n#ifdef LIGHTING_3D_MODE\n    out_color = apply_lighting(out_color);\n#endif\n#ifdef FOG\n    out_color = fog_dither(fog_apply_premultiplied(out_color, v_fog_pos));\n#endif\n\n    gl_FragColor = out_color * opacity;\n\n#ifdef OVERDRAW_INSPECTOR\n    gl_FragColor = vec4(1.0);\n#endif\n}\n";

var fillVert = "attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\n\n#pragma mapbox: define highp vec4 color\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n    #pragma mapbox: initialize highp vec4 color\n    #pragma mapbox: initialize lowp float opacity\n\n    gl_Position = u_matrix * vec4(a_pos, 0, 1);\n\n#ifdef FOG\n    v_fog_pos = fog_position(a_pos);\n#endif\n}\n";

var fillOutlineFrag = "varying vec2 v_pos;\n\n#pragma mapbox: define highp vec4 outline_color\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n    #pragma mapbox: initialize highp vec4 outline_color\n    #pragma mapbox: initialize lowp float opacity\n\n    float dist = length(v_pos - gl_FragCoord.xy);\n    float alpha = 1.0 - smoothstep(0.0, 1.0, dist);\n    vec4 out_color = outline_color;\n\n#ifdef LIGHTING_3D_MODE\n    out_color = apply_lighting(out_color);\n#endif\n#ifdef FOG\n    out_color = fog_dither(fog_apply_premultiplied(out_color, v_fog_pos));\n#endif\n\n    gl_FragColor = out_color * (alpha * opacity);\n\n#ifdef OVERDRAW_INSPECTOR\n    gl_FragColor = vec4(1.0);\n#endif\n}\n";

var fillOutlineVert = "attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\nuniform vec2 u_world;\n\nvarying vec2 v_pos;\n\n#pragma mapbox: define highp vec4 outline_color\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n    #pragma mapbox: initialize highp vec4 outline_color\n    #pragma mapbox: initialize lowp float opacity\n\n    gl_Position = u_matrix * vec4(a_pos, 0, 1);\n    v_pos = (gl_Position.xy / gl_Position.w + 1.0) / 2.0 * u_world;\n\n#ifdef FOG\n    v_fog_pos = fog_position(a_pos);\n#endif\n}\n";

var fillOutlinePatternFrag = "\nuniform vec2 u_texsize;\nuniform sampler2D u_image;\n\nvarying vec2 v_pos;\nvarying vec2 v_pos_world;\n\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define lowp vec4 pattern\n\nvoid main() {\n    #pragma mapbox: initialize lowp float opacity\n    #pragma mapbox: initialize mediump vec4 pattern\n\n    vec2 pattern_tl = pattern.xy;\n    vec2 pattern_br = pattern.zw;\n\n    vec2 imagecoord = mod(v_pos, 1.0);\n    vec2 pos = mix(pattern_tl / u_texsize, pattern_br / u_texsize, imagecoord);\n\n    // find distance to outline for alpha interpolation\n\n    float dist = length(v_pos_world - gl_FragCoord.xy);\n    float alpha = 1.0 - smoothstep(0.0, 1.0, dist);\n\n    vec4 out_color = texture2D(u_image, pos);\n\n#ifdef LIGHTING_3D_MODE\n    out_color = apply_lighting(out_color);\n#endif\n#ifdef FOG\n    out_color = fog_dither(fog_apply_premultiplied(out_color, v_fog_pos));\n#endif\n\n    gl_FragColor = out_color * (alpha * opacity);\n\n#ifdef OVERDRAW_INSPECTOR\n    gl_FragColor = vec4(1.0);\n#endif\n}\n";

var fillOutlinePatternVert = "uniform mat4 u_matrix;\nuniform vec2 u_world;\nuniform vec2 u_pixel_coord_upper;\nuniform vec2 u_pixel_coord_lower;\nuniform float u_tile_units_to_pixels;\n\nattribute vec2 a_pos;\n\nvarying vec2 v_pos;\nvarying vec2 v_pos_world;\n\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define lowp vec4 pattern\n#pragma mapbox: define lowp float pixel_ratio\n\nvoid main() {\n    #pragma mapbox: initialize lowp float opacity\n    #pragma mapbox: initialize mediump vec4 pattern\n    #pragma mapbox: initialize lowp float pixel_ratio\n\n    vec2 pattern_tl = pattern.xy;\n    vec2 pattern_br = pattern.zw;\n\n    gl_Position = u_matrix * vec4(a_pos, 0, 1);\n\n    vec2 display_size = (pattern_br - pattern_tl) / pixel_ratio;\n\n    v_pos = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, display_size, u_tile_units_to_pixels, a_pos);\n\n    v_pos_world = (gl_Position.xy / gl_Position.w + 1.0) / 2.0 * u_world;\n\n#ifdef FOG\n    v_fog_pos = fog_position(a_pos);\n#endif\n}\n";

var fillPatternFrag = "uniform vec2 u_texsize;\n\nuniform sampler2D u_image;\n\nvarying vec2 v_pos;\n\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define lowp vec4 pattern\n\nvoid main() {\n    #pragma mapbox: initialize lowp float opacity\n    #pragma mapbox: initialize mediump vec4 pattern\n\n    vec2 pattern_tl = pattern.xy;\n    vec2 pattern_br = pattern.zw;\n\n    vec2 imagecoord = mod(v_pos, 1.0);\n    vec2 pos = mix(pattern_tl / u_texsize, pattern_br / u_texsize, imagecoord);\n    vec4 out_color = texture2D(u_image, pos);\n\n#ifdef LIGHTING_3D_MODE\n    out_color = apply_lighting(out_color);\n#endif\n#ifdef FOG\n    out_color = fog_dither(fog_apply_premultiplied(out_color, v_fog_pos));\n#endif\n\n    gl_FragColor = out_color * opacity;\n\n#ifdef OVERDRAW_INSPECTOR\n    gl_FragColor = vec4(1.0);\n#endif\n}\n";

var fillPatternVert = "uniform mat4 u_matrix;\nuniform vec2 u_pixel_coord_upper;\nuniform vec2 u_pixel_coord_lower;\nuniform float u_tile_units_to_pixels;\n\nattribute vec2 a_pos;\n\nvarying vec2 v_pos;\n\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define lowp vec4 pattern\n#pragma mapbox: define lowp float pixel_ratio\n\nvoid main() {\n    #pragma mapbox: initialize lowp float opacity\n    #pragma mapbox: initialize mediump vec4 pattern\n    #pragma mapbox: initialize lowp float pixel_ratio\n\n    vec2 pattern_tl = pattern.xy;\n    vec2 pattern_br = pattern.zw;\n\n    vec2 display_size = (pattern_br - pattern_tl) / pixel_ratio;\n    gl_Position = u_matrix * vec4(a_pos, 0, 1);\n\n    v_pos = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, display_size, u_tile_units_to_pixels, a_pos);\n\n#ifdef FOG\n    v_fog_pos = fog_position(a_pos);\n#endif\n}\n";

var fillExtrusionFrag = "varying vec4 v_color;\n\n#ifdef RENDER_SHADOWS\nvarying highp vec4 v_pos_light_view_0;\nvarying highp vec4 v_pos_light_view_1;\nvarying float v_depth;\n#endif\n\n#ifdef FAUX_AO\nuniform lowp vec2 u_ao;\nvarying vec3 v_ao;\n#endif\n\n#ifdef ZERO_ROOF_RADIUS\nvarying vec4 v_roof_color;\n#endif\n\n#if defined(ZERO_ROOF_RADIUS) || defined(RENDER_SHADOWS)\nvarying highp vec3 v_normal;\n#endif\n\nvoid main() {\n\n#if defined(ZERO_ROOF_RADIUS) || defined(RENDER_SHADOWS)\n    vec3 normal = v_normal;\n#endif\n\nfloat z;\nvec4 color;\n#ifdef ZERO_ROOF_RADIUS\n    z = float(normal.z > 0.00001);\n    color = mix(v_color, v_roof_color, z);\n#else\n    color = v_color;\n#endif\n#ifdef FAUX_AO\n    float intensity = u_ao[0];\n    float h = max(0.0, v_ao.z);\n    float h_floors = h / u_ao[1];\n    float y_shade = 1.0 - 0.9 * intensity * min(v_ao.y, 1.0);\n    float shade = (1.0 - 0.08 * intensity) * (y_shade + (1.0 - y_shade) * (1.0 - pow(1.0 - min(h_floors / 16.0, 1.0), 16.0))) + 0.08 * intensity * min(h_floors / 160.0, 1.0);\n    // concave angle\n    float concave = v_ao.x * v_ao.x;\n#ifdef ZERO_ROOF_RADIUS\n    concave *= (1.0 - z);\n#endif\n    float x_shade = mix(1.0, mix(0.6, 0.75, min(h_floors / 30.0, 1.0)), intensity) + 0.1 * intensity * min(h, 1.0);\n    shade *= mix(1.0, x_shade * x_shade * x_shade, concave);\n    color.rgb = color.rgb * shade;\n#endif\n\n#ifdef RENDER_SHADOWS\n#ifdef ZERO_ROOF_RADIUS\n    normal = mix(normal, vec3(0.0, 0.0, 1.0), z);\n#endif\n    color.xyz = shadowed_color_normal(color.xyz, normalize(normal), v_pos_light_view_0, v_pos_light_view_1, v_depth);\n#endif\n\n#ifdef FOG\n    color = fog_dither(fog_apply_premultiplied(color, v_fog_pos));\n#endif\n    gl_FragColor = color;\n\n#ifdef OVERDRAW_INSPECTOR\n    gl_FragColor = vec4(1.0);\n#endif\n}\n";

var fillExtrusionVert = "\nuniform mat4 u_matrix;\nuniform vec3 u_lightcolor;\nuniform lowp vec3 u_lightpos;\nuniform lowp float u_lightintensity;\nuniform float u_vertical_gradient;\nuniform lowp float u_opacity;\nuniform float u_edge_radius;\n\nattribute vec4 a_pos_normal_ed;\nattribute vec2 a_centroid_pos;\n\n#ifdef PROJECTION_GLOBE_VIEW\nattribute vec3 a_pos_3;         // Projected position on the globe\nattribute vec3 a_pos_normal_3;  // Surface normal at the position\n\nuniform mat4 u_inv_rot_matrix;\nuniform vec2 u_merc_center;\nuniform vec3 u_tile_id;\nuniform float u_zoom_transition;\nuniform vec3 u_up_dir;\nuniform float u_height_lift;\n#endif\n\nvarying vec4 v_color;\n\n#ifdef RENDER_SHADOWS\nuniform mat4 u_light_matrix_0;\nuniform mat4 u_light_matrix_1;\n\nvarying highp vec4 v_pos_light_view_0;\nvarying highp vec4 v_pos_light_view_1;\nvarying float v_depth;\n#endif\n\n#ifdef ZERO_ROOF_RADIUS\nvarying vec4 v_roof_color;\n#endif\n\n#if defined(ZERO_ROOF_RADIUS) || defined(RENDER_SHADOWS)\nvarying highp vec3 v_normal;\n#endif\n\n#ifdef FAUX_AO\nuniform lowp vec2 u_ao;\nvarying vec3 v_ao;\n#endif\n\n#pragma mapbox: define highp float base\n#pragma mapbox: define highp float height\n\n#pragma mapbox: define highp vec4 color\n\nvoid main() {\n    #pragma mapbox: initialize highp float base\n    #pragma mapbox: initialize highp float height\n    #pragma mapbox: initialize highp vec4 color\n\n    vec4 pos_nx = floor(a_pos_normal_ed * 0.5);\n    // The least significant bits of a_pos_normal_ed hold:\n    // x is 1 if it's on top, 0 for ground.\n    // y is 1 if the normal points up, and 0 if it points to side.\n    // z is sign of ny: 1 for positive, 0 for values <= 0.\n    // w marks edge's start, 0 is for edge end, edgeDistance increases from start to end.\n    vec4 top_up_ny_start = a_pos_normal_ed - 2.0 * pos_nx;\n    vec3 top_up_ny = top_up_ny_start.xyz;\n\n    float x_normal = pos_nx.z / 8192.0;\n    vec3 normal = top_up_ny.y == 1.0 ? vec3(0.0, 0.0, 1.0) : normalize(vec3(x_normal, (2.0 * top_up_ny.z - 1.0) * (1.0 - abs(x_normal)), 0.0));\n#if defined(ZERO_ROOF_RADIUS) || defined(RENDER_SHADOWS)\n    v_normal = normal;\n#endif\n\n    base = max(0.0, base);\n\n    height = max(0.0, top_up_ny.y == 0.0 && top_up_ny.x == 1.0 ? height - u_edge_radius : height);\n\n    float t = top_up_ny.x;\n\n    vec2 centroid_pos = vec2(0.0);\n#if defined(HAS_CENTROID) || defined(TERRAIN)\n    centroid_pos = a_centroid_pos;\n#endif\n\n    float ele = 0.0;\n    float h = 0.0;\n    float c_ele;\n    vec3 pos;\n#ifdef TERRAIN\n    bool flat_roof = centroid_pos.x != 0.0 && t > 0.0;\n    ele = elevation(pos_nx.xy);\n    c_ele = flat_roof ? centroid_pos.y == 0.0 ? elevationFromUint16(centroid_pos.x) : flatElevation(centroid_pos) : ele;\n    // If centroid elevation lower than vertex elevation, roof at least 2 meters height above base.\n    h = flat_roof ? max(c_ele + height, ele + base + 2.0) : ele + (t > 0.0 ? height : base == 0.0 ? -5.0 : base);\n    pos = vec3(pos_nx.xy, h);\n#else\n    h = t > 0.0 ? height : base;\n    pos = vec3(pos_nx.xy, h);\n#endif\n\n#ifdef PROJECTION_GLOBE_VIEW\n    // If t > 0 (top) we always add the lift, otherwise (ground) we only add it if base height is > 0\n    float lift = float((t + base) > 0.0) * u_height_lift;\n    h += lift;\n    vec3 globe_normal = normalize(mix(a_pos_normal_3 / 16384.0, u_up_dir, u_zoom_transition));\n    vec3 globe_pos = a_pos_3 + globe_normal * (u_tile_up_scale * h);\n    vec3 merc_pos = mercator_tile_position(u_inv_rot_matrix, pos.xy, u_tile_id, u_merc_center) + u_up_dir * u_tile_up_scale * pos.z;\n    pos = mix_globe_mercator(globe_pos, merc_pos, u_zoom_transition);\n#endif\n\n    float hidden = float(centroid_pos.x == 0.0 && centroid_pos.y == 1.0);\n    gl_Position = mix(u_matrix * vec4(pos, 1), AWAY, hidden);\n\n#ifdef RENDER_SHADOWS\n    v_pos_light_view_0 = u_light_matrix_0 * vec4(pos, 1);\n    v_pos_light_view_1 = u_light_matrix_1 * vec4(pos, 1);\n    v_depth = gl_Position.w;\n#endif\n\n    float NdotL = 0.0;\n    float colorvalue = 0.0;\n#ifdef LIGHTING_3D_MODE\n    NdotL = calculate_NdotL(normal);\n#else\n    // Relative luminance (how dark/bright is the surface color?)\n    colorvalue = color.r * 0.2126 + color.g * 0.7152 + color.b * 0.0722;\n\n    // Add slight ambient lighting so no extrusions are totally black\n    vec4 ambientlight = vec4(0.03, 0.03, 0.03, 1.0);\n    color += ambientlight;\n\n    // Calculate cos(theta), where theta is the angle between surface normal and diffuse light ray\n    NdotL = clamp(dot(normal, u_lightpos), 0.0, 1.0);\n\n    // Adjust NdotL so that\n    // the range of values for highlight/shading is narrower\n    // with lower light intensity\n    // and with lighter/brighter surface colors\n    NdotL = mix((1.0 - u_lightintensity), max((1.0 - colorvalue + u_lightintensity), 1.0), NdotL);\n#endif\n\n    // Add gradient along z axis of side surfaces\n    if (normal.y != 0.0) {\n        float r = 0.84;\n#ifndef LIGHTING_3D_MODE\n        r = mix(0.7, 0.98, 1.0 - u_lightintensity);\n#endif\n        // This avoids another branching statement, but multiplies by a constant of 0.84 if no vertical gradient,\n        // and otherwise calculates the gradient based on base + height\n        NdotL *= (\n            (1.0 - u_vertical_gradient) +\n            (u_vertical_gradient * clamp((t + base) * pow(height / 150.0, 0.5), r, 1.0)));\n    }\n\n    v_color = vec4(0.0, 0.0, 0.0, 1.0);\n\n#ifdef FAUX_AO\n    // Documented at https://github.com/mapbox/mapbox-gl-js/pull/11926#discussion_r898496259\n    float concave = pos_nx.w - floor(pos_nx.w * 0.5) * 2.0;\n    float start = top_up_ny_start.w;\n    float y_ground = 1.0 - clamp(t + base, 0.0, 1.0);\n    float top_height = height;\n#ifdef TERRAIN\n    top_height = mix(max(c_ele + height, ele + base + 2.0), ele + height, float(centroid_pos.x == 0.0)) - ele;\n    y_ground += y_ground * 5.0 / max(3.0, top_height);\n#endif\n    v_ao = vec3(mix(concave, -concave, start), y_ground, h - ele);\n    NdotL *= (1.0 + 0.05 * (1.0 - top_up_ny.y) * u_ao[0]); // compensate sides faux ao shading contribution\n\n#ifdef PROJECTION_GLOBE_VIEW\n    top_height += u_height_lift;\n#endif\n    gl_Position.z -= (0.0000006 * (min(top_height, 500.) + 2.0 * min(base, 500.0) + 60.0 * concave + 3.0 * start)) * gl_Position.w;\n#endif\n\n#ifdef LIGHTING_3D_MODE\n    v_color = apply_lighting(color, NdotL);\n#else\n    // Assign final color based on surface + ambient light color, diffuse light NdotL, and light color\n    // with lower bounds adjusted to hue of light\n    // so that shading is tinted with the complementary (opposite) color to the light color\n    v_color.rgb += clamp(color.rgb * NdotL * u_lightcolor, mix(vec3(0.0), vec3(0.3), 1.0 - u_lightcolor), vec3(1.0));\n#endif\n    \n    v_color *= u_opacity;\n\n#ifdef ZERO_ROOF_RADIUS\n    v_roof_color = vec4(0.0, 0.0, 0.0, 1.0);\n\n#ifdef LIGHTING_3D_MODE\n    v_roof_color = apply_lighting(color, calculate_NdotL(vec3(0.0, 0.0, 1.0)));\n#else\n    float roofNdotL = clamp(u_lightpos.z, 0.0, 1.0);\n    roofNdotL = mix((1.0 - u_lightintensity), max((1.0 - colorvalue + u_lightintensity), 1.0), roofNdotL);\n    v_roof_color.rgb += clamp(color.rgb * roofNdotL * u_lightcolor, mix(vec3(0.0), vec3(0.3), 1.0 - u_lightcolor), vec3(1.0));\n#endif\n\n    v_roof_color *= u_opacity;\n#endif\n\n#ifdef FOG\n    v_fog_pos = fog_position(pos);\n#endif\n}\n";

var fillExtrusionPatternFrag = "uniform vec2 u_texsize;\n\nuniform sampler2D u_image;\n\n#ifdef FAUX_AO\nuniform lowp vec2 u_ao;\nvarying vec3 v_ao;\n#endif\n\n#ifdef LIGHTING_3D_MODE\nvarying float v_NdotL;\n#endif\n\nvarying vec2 v_pos;\nvarying vec4 v_lighting;\n\nuniform lowp float u_opacity;\n\n#pragma mapbox: define lowp float base\n#pragma mapbox: define lowp float height\n#pragma mapbox: define lowp vec4 pattern\n#pragma mapbox: define lowp float pixel_ratio\n\nvoid main() {\n    #pragma mapbox: initialize lowp float base\n    #pragma mapbox: initialize lowp float height\n    #pragma mapbox: initialize mediump vec4 pattern\n    #pragma mapbox: initialize lowp float pixel_ratio\n\n    vec2 pattern_tl = pattern.xy;\n    vec2 pattern_br = pattern.zw;\n\n    vec2 imagecoord = mod(v_pos, 1.0);\n    vec2 pos = mix(pattern_tl / u_texsize, pattern_br / u_texsize, imagecoord);\n    vec4 out_color = texture2D(u_image, pos);\n\n#ifdef LIGHTING_3D_MODE\n    out_color = apply_lighting(out_color, v_NdotL) * u_opacity;\n#else\n    out_color = out_color * v_lighting;\n#endif\n\n#ifdef FAUX_AO\n    float intensity = u_ao[0];\n    float h = max(0.0, v_ao.z);\n    float h_floors = h / u_ao[1];\n    float y_shade = 1.0 - 0.9 * intensity * min(v_ao.y, 1.0);\n    float shade = (1.0 - 0.08 * intensity) * (y_shade + (1.0 - y_shade) * (1.0 - pow(1.0 - min(h_floors / 16.0, 1.0), 16.0))) + 0.08 * intensity * min(h_floors / 160.0, 1.0);\n    // concave angle\n    float concave = v_ao.x * v_ao.x;\n    float x_shade = mix(1.0, mix(0.6, 0.75, min(h_floors / 30.0, 1.0)), intensity) + 0.1 * intensity * min(h, 1.0);\n    shade *= mix(1.0, x_shade * x_shade * x_shade, concave);\n    out_color.rgb = out_color.rgb * shade;\n#endif\n#ifdef FOG\n    out_color = fog_dither(fog_apply_premultiplied(out_color, v_fog_pos));\n#endif\n\n    gl_FragColor = out_color;\n\n#ifdef OVERDRAW_INSPECTOR\n    gl_FragColor = vec4(1.0);\n#endif\n}\n";

var fillExtrusionPatternVert = "uniform mat4 u_matrix;\nuniform vec2 u_pixel_coord_upper;\nuniform vec2 u_pixel_coord_lower;\nuniform float u_height_factor;\nuniform float u_tile_units_to_pixels;\nuniform float u_vertical_gradient;\nuniform lowp float u_opacity;\n\nuniform vec3 u_lightcolor;\nuniform lowp vec3 u_lightpos;\nuniform lowp float u_lightintensity;\n\nattribute vec4 a_pos_normal_ed;\nattribute vec2 a_centroid_pos;\n\n#ifdef PROJECTION_GLOBE_VIEW\nattribute vec3 a_pos_3;         // Projected position on the globe\nattribute vec3 a_pos_normal_3;  // Surface normal at the position\n\nuniform mat4 u_inv_rot_matrix;\nuniform vec2 u_merc_center;\nuniform vec3 u_tile_id;\nuniform float u_zoom_transition;\nuniform vec3 u_up_dir;\nuniform float u_height_lift;\n#endif\n\nvarying vec2 v_pos;\nvarying vec4 v_lighting;\n\n#ifdef FAUX_AO\nuniform lowp vec2 u_ao;\nvarying vec3 v_ao;\n#endif\n\n#ifdef LIGHTING_3D_MODE\nvarying float v_NdotL;\n#endif\n\n#pragma mapbox: define lowp float base\n#pragma mapbox: define lowp float height\n#pragma mapbox: define lowp vec4 pattern\n#pragma mapbox: define lowp float pixel_ratio\n\nvoid main() {\n    #pragma mapbox: initialize lowp float base\n    #pragma mapbox: initialize lowp float height\n    #pragma mapbox: initialize mediump vec4 pattern\n    #pragma mapbox: initialize lowp float pixel_ratio\n\n    vec2 pattern_tl = pattern.xy;\n    vec2 pattern_br = pattern.zw;\n\n    vec4 pos_nx = floor(a_pos_normal_ed * 0.5);\n    // The least significant bits of a_pos_normal_ed.xy hold:\n    // x is 1 if it's on top, 0 for ground.\n    // y is 1 if the normal points up, and 0 if it points to side.\n    // z is sign of ny: 1 for positive, 0 for values <= 0.\n    // w marks edge's start, 0 is for edge end, edgeDistance increases from start to end.\n    mediump vec4 top_up_ny_start = a_pos_normal_ed - 2.0 * pos_nx;\n    mediump vec3 top_up_ny = top_up_ny_start.xyz;\n\n    float x_normal = pos_nx.z / 8192.0;\n    vec3 normal = top_up_ny.y == 1.0 ? vec3(0.0, 0.0, 1.0) : normalize(vec3(x_normal, (2.0 * top_up_ny.z - 1.0) * (1.0 - abs(x_normal)), 0.0));\n    float edgedistance = a_pos_normal_ed.w;\n\n    vec2 display_size = (pattern_br - pattern_tl) / pixel_ratio;\n\n    base = max(0.0, base);\n    height = max(0.0, height);\n\n    float t = top_up_ny.x;\n    float z = t > 0.0 ? height : base;\n\n    vec2 centroid_pos = vec2(0.0);\n#if defined(HAS_CENTROID) || defined(TERRAIN)\n    centroid_pos = a_centroid_pos;\n#endif\n\n    float ele = 0.0;\n    float h = z;\n    vec3 p;\n    float c_ele;\n#ifdef TERRAIN\n    bool flat_roof = centroid_pos.x != 0.0 && t > 0.0;\n    ele = elevation(pos_nx.xy);\n    c_ele = flat_roof ? centroid_pos.y == 0.0 ? elevationFromUint16(centroid_pos.x) : flatElevation(centroid_pos) : ele;\n    // If centroid elevation lower than vertex elevation, roof at least 2 meters height above base.\n    h = flat_roof ? max(c_ele + height, ele + base + 2.0) : ele + (t > 0.0 ? height : base == 0.0 ? -5.0 : base);\n    p = vec3(pos_nx.xy, h);\n#else\n    p = vec3(pos_nx.xy, z);\n#endif\n\n#ifdef PROJECTION_GLOBE_VIEW\n    // If t > 0 (top) we always add the lift, otherwise (ground) we only add it if base height is > 0\n    float lift = float((t + base) > 0.0) * u_height_lift;\n    h += lift;\n    vec3 globe_normal = normalize(mix(a_pos_normal_3 / 16384.0, u_up_dir, u_zoom_transition));\n    vec3 globe_pos = a_pos_3 + globe_normal * (u_tile_up_scale * (p.z + lift));\n    vec3 merc_pos = mercator_tile_position(u_inv_rot_matrix, p.xy, u_tile_id, u_merc_center) + u_up_dir * u_tile_up_scale * p.z;\n    p = mix_globe_mercator(globe_pos, merc_pos, u_zoom_transition);\n#endif\n\n    float hidden = float(centroid_pos.x == 0.0 && centroid_pos.y == 1.0);\n    gl_Position = mix(u_matrix * vec4(p, 1), AWAY, hidden);\n\n    vec2 pos = normal.z == 1.0\n        ? pos_nx.xy // extrusion top\n        : vec2(edgedistance, z * u_height_factor); // extrusion side\n\n    v_pos = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, display_size, u_tile_units_to_pixels, pos);\n\n    v_lighting = vec4(0.0, 0.0, 0.0, 1.0);\n    float NdotL = 0.0;\n#ifdef LIGHTING_3D_MODE\n    NdotL = calculate_NdotL(normal);\n#else\n    NdotL = clamp(dot(normal, u_lightpos), 0.0, 1.0);\n    NdotL = mix((1.0 - u_lightintensity), max((0.5 + u_lightintensity), 1.0), NdotL);\n#endif\n\n    if (normal.y != 0.0) {\n        float r = 0.84;\n#ifndef LIGHTING_3D_MODE\n        r = mix(0.7, 0.98, 1.0 - u_lightintensity);\n#endif\n        // This avoids another branching statement, but multiplies by a constant of 0.84 if no vertical gradient,\n        // and otherwise calculates the gradient based on base + height\n        NdotL *= (\n            (1.0 - u_vertical_gradient) +\n            (u_vertical_gradient * clamp((t + base) * pow(height / 150.0, 0.5), r, 1.0)));\n    }\n\n#ifdef FAUX_AO\n    // Documented at https://github.com/mapbox/mapbox-gl-js/pull/11926#discussion_r898496259\n    float concave = pos_nx.w - floor(pos_nx.w * 0.5) * 2.0;\n    float start = top_up_ny_start.w;\n    float y_ground = 1.0 - clamp(t + base, 0.0, 1.0);\n    float top_height = height;\n#ifdef TERRAIN\n    top_height = mix(max(c_ele + height, ele + base + 2.0), ele + height, float(centroid_pos.x == 0.0)) - ele;\n    y_ground += y_ground * 5.0 / max(3.0, top_height);\n#endif\n    v_ao = vec3(mix(concave, -concave, start), y_ground, h - ele);\n    NdotL *= (1.0 + 0.05 * (1.0 - top_up_ny.y) * u_ao[0]); // compensate sides faux ao shading contribution\n\n#ifdef PROJECTION_GLOBE_VIEW\n    top_height += u_height_lift;\n#endif\n    gl_Position.z -= (0.0000006 * (min(top_height, 500.) + 2.0 * min(base, 500.0) + 60.0 * concave + 3.0 * start)) * gl_Position.w;\n#endif\n\n#ifdef LIGHTING_3D_MODE\n    v_NdotL = NdotL;\n#else\n    v_lighting.rgb += clamp(NdotL * u_lightcolor, mix(vec3(0.0), vec3(0.3), 1.0 - u_lightcolor), vec3(1.0));\n    v_lighting *= u_opacity;\n#endif \n\n#ifdef FOG\n    v_fog_pos = fog_position(p);\n#endif\n}\n";

var hillshadePrepareFrag = "#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform sampler2D u_image;\nvarying vec2 v_pos;\nuniform vec2 u_dimension;\nuniform float u_zoom;\nuniform vec4 u_unpack;\n\nfloat getElevation(vec2 coord) {\n#ifdef TERRAIN_DEM_FLOAT_FORMAT\n    return texture2D(u_image, coord).a / 4.0;\n#else\n    // Convert encoded elevation value to meters\n    vec4 data = texture2D(u_image, coord) * 255.0;\n    data.a = -1.0;\n    return dot(data, u_unpack) / 4.0;\n#endif\n}\n\nvoid main() {\n    vec2 epsilon = 1.0 / u_dimension;\n\n    // queried pixels:\n    // +-----------+\n    // |   |   |   |\n    // | a | b | c |\n    // |   |   |   |\n    // +-----------+\n    // |   |   |   |\n    // | d |   | e |\n    // |   |   |   |\n    // +-----------+\n    // |   |   |   |\n    // | f | g | h |\n    // |   |   |   |\n    // +-----------+\n\n    float a = getElevation(v_pos + vec2(-epsilon.x, -epsilon.y));\n    float b = getElevation(v_pos + vec2(0, -epsilon.y));\n    float c = getElevation(v_pos + vec2(epsilon.x, -epsilon.y));\n    float d = getElevation(v_pos + vec2(-epsilon.x, 0));\n    float e = getElevation(v_pos + vec2(epsilon.x, 0));\n    float f = getElevation(v_pos + vec2(-epsilon.x, epsilon.y));\n    float g = getElevation(v_pos + vec2(0, epsilon.y));\n    float h = getElevation(v_pos + vec2(epsilon.x, epsilon.y));\n\n    // Here we divide the x and y slopes by 8 * pixel size\n    // where pixel size (aka meters/pixel) is:\n    // circumference of the world / (pixels per tile * number of tiles)\n    // which is equivalent to: 8 * 40075016.6855785 / (512 * pow(2, u_zoom))\n    // which can be reduced to: pow(2, 19.25619978527 - u_zoom).\n    // We want to vertically exaggerate the hillshading because otherwise\n    // it is barely noticeable at low zooms. To do this, we multiply this by\n    // a scale factor that is a function of zooms below 15, which is an arbitrary\n    // that corresponds to the max zoom level of Mapbox terrain-RGB tiles.\n    // See nickidlugash's awesome breakdown for more info:\n    // https://github.com/mapbox/mapbox-gl-js/pull/5286#discussion_r148419556\n\n    float exaggerationFactor = u_zoom < 2.0 ? 0.4 : u_zoom < 4.5 ? 0.35 : 0.3;\n    float exaggeration = u_zoom < 15.0 ? (u_zoom - 15.0) * exaggerationFactor : 0.0;\n\n    vec2 deriv = vec2(\n        (c + e + e + h) - (a + d + d + f),\n        (f + g + g + h) - (a + b + b + c)\n    ) / pow(2.0, exaggeration + (19.2562 - u_zoom));\n\n    gl_FragColor = clamp(vec4(\n        deriv.x / 2.0 + 0.5,\n        deriv.y / 2.0 + 0.5,\n        1.0,\n        1.0), 0.0, 1.0);\n\n#ifdef OVERDRAW_INSPECTOR\n    gl_FragColor = vec4(1.0);\n#endif\n}\n";

var hillshadePrepareVert = "uniform mat4 u_matrix;\nuniform vec2 u_dimension;\n\nattribute vec2 a_pos;\nattribute vec2 a_texture_pos;\n\nvarying vec2 v_pos;\n\nvoid main() {\n    gl_Position = u_matrix * vec4(a_pos, 0, 1);\n\n    highp vec2 epsilon = 1.0 / u_dimension;\n    float scale = (u_dimension.x - 2.0) / u_dimension.x;\n    v_pos = (a_texture_pos / 8192.0) * scale + epsilon;\n}\n";

var hillshadeFrag = "uniform sampler2D u_image;\nvarying vec2 v_pos;\n\nuniform vec2 u_latrange;\nuniform vec2 u_light;\nuniform vec4 u_shadow;\nuniform vec4 u_highlight;\nuniform vec4 u_accent;\n\nvoid main() {\n    vec4 pixel = texture2D(u_image, v_pos);\n\n    vec2 deriv = ((pixel.rg * 2.0) - 1.0);\n\n    // We divide the slope by a scale factor based on the cosin of the pixel's approximate latitude\n    // to account for mercator projection distortion. see #4807 for details\n    float scaleFactor = cos(radians((u_latrange[0] - u_latrange[1]) * (1.0 - v_pos.y) + u_latrange[1]));\n    // We also multiply the slope by an arbitrary z-factor of 1.25\n    float slope = atan(1.25 * length(deriv) / scaleFactor);\n    float aspect = deriv.x != 0.0 ? atan(deriv.y, -deriv.x) : PI / 2.0 * (deriv.y > 0.0 ? 1.0 : -1.0);\n\n    float intensity = u_light.x;\n    // We add PI to make this property match the global light object, which adds PI/2 to the light's azimuthal\n    // position property to account for 0deg corresponding to north/the top of the viewport in the style spec\n    // and the original shader was written to accept (-illuminationDirection - 90) as the azimuthal.\n    float azimuth = u_light.y + PI;\n\n    // We scale the slope exponentially based on intensity, using a calculation similar to\n    // the exponential interpolation function in the style spec:\n    // src/style-spec/expression/definitions/interpolate.js#L217-L228\n    // so that higher intensity values create more opaque hillshading.\n    float base = 1.875 - intensity * 1.75;\n    float maxValue = 0.5 * PI;\n    float scaledSlope = intensity != 0.5 ? ((pow(base, slope) - 1.0) / (pow(base, maxValue) - 1.0)) * maxValue : slope;\n\n    // The accent color is calculated with the cosine of the slope while the shade color is calculated with the sine\n    // so that the accent color's rate of change eases in while the shade color's eases out.\n    float accent = cos(scaledSlope);\n    // We multiply both the accent and shade color by a clamped intensity value\n    // so that intensities >= 0.5 do not additionally affect the color values\n    // while intensity values < 0.5 make the overall color more transparent.\n    vec4 accent_color = (1.0 - accent) * u_accent * clamp(intensity * 2.0, 0.0, 1.0);\n    float shade = abs(mod((aspect + azimuth) / PI + 0.5, 2.0) - 1.0);\n    vec4 shade_color = mix(u_shadow, u_highlight, shade) * sin(scaledSlope) * clamp(intensity * 2.0, 0.0, 1.0);\n    gl_FragColor = accent_color * (1.0 - shade_color.a) + shade_color;\n\n#ifdef LIGHTING_3D_MODE\n    gl_FragColor = apply_lighting(gl_FragColor);\n#endif\n#ifdef FOG\n    gl_FragColor = fog_dither(fog_apply_premultiplied(gl_FragColor, v_fog_pos));\n#endif\n\n#ifdef OVERDRAW_INSPECTOR\n    gl_FragColor = vec4(1.0);\n#endif\n}\n";

var hillshadeVert = "uniform mat4 u_matrix;\n\nattribute vec2 a_pos;\nattribute vec2 a_texture_pos;\n\nvarying vec2 v_pos;\n\nvoid main() {\n    gl_Position = u_matrix * vec4(a_pos, 0, 1);\n    v_pos = a_texture_pos / 8192.0;\n\n#ifdef FOG\n    v_fog_pos = fog_position(a_pos);\n#endif\n}\n";

var lineFrag = "uniform lowp float u_device_pixel_ratio;\nuniform float u_alpha_discard_threshold;\nuniform highp vec2 u_trim_offset;\n\nvarying vec2 v_width2;\nvarying vec2 v_normal;\nvarying float v_gamma_scale;\nvarying highp vec4 v_uv;\n#ifdef RENDER_LINE_DASH\nuniform sampler2D u_dash_image;\n\nvarying vec2 v_tex;\n#endif\n\n#ifdef RENDER_LINE_GRADIENT\nuniform sampler2D u_gradient_image;\n#endif\n\nuniform float u_border_width;\nuniform vec4 u_border_color;\nfloat luminance(vec3 c) {\n    // Digital ITU BT.601 (Y = 0.299 R + 0.587 G + 0.114 B) approximation\n    return (c.r + c.r + c.b + c.g + c.g + c.g) * 0.1667;\n}\n\n#pragma mapbox: define highp vec4 color\n#pragma mapbox: define lowp float floorwidth\n#pragma mapbox: define lowp vec4 dash\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n\nfloat linearstep(float edge0, float edge1, float x) {\n    return  clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n}\n\nvoid main() {\n    #pragma mapbox: initialize highp vec4 color\n    #pragma mapbox: initialize lowp float floorwidth\n    #pragma mapbox: initialize lowp vec4 dash\n    #pragma mapbox: initialize lowp float blur\n    #pragma mapbox: initialize lowp float opacity\n\n    // Calculate the distance of the pixel from the line in pixels.\n    float dist = length(v_normal) * v_width2.s;\n\n    // Calculate the antialiasing fade factor. This is either when fading in\n    // the line in case of an offset line (v_width2.t) or when fading out\n    // (v_width2.s)\n    float blur2 = (blur + 1.0 / u_device_pixel_ratio) * v_gamma_scale;\n    float alpha = clamp(min(dist - (v_width2.t - blur2), v_width2.s - dist) / blur2, 0.0, 1.0);\n#ifdef RENDER_LINE_DASH\n    float sdfdist = texture2D(u_dash_image, v_tex).a;\n    float sdfgamma = 1.0 / (2.0 * u_device_pixel_ratio) / dash.z;\n    alpha *= linearstep(0.5 - sdfgamma / floorwidth, 0.5 + sdfgamma / floorwidth, sdfdist);\n#endif\n\n    highp vec4 out_color;\n#ifdef RENDER_LINE_GRADIENT\n    // For gradient lines, v_uv.xy are the coord specify where the texture will be simpled.\n    out_color = texture2D(u_gradient_image, v_uv.xy);\n#else\n    out_color = color;\n#endif\n\n    float trimmed = 1.0;\n#ifdef RENDER_LINE_TRIM_OFFSET\n    // v_uv[2] and v_uv[3] are specifying the original clip range that the vertex is located in.\n    highp float start = v_uv[2];\n    highp float end = v_uv[3];\n    highp float trim_start = u_trim_offset[0];\n    highp float trim_end = u_trim_offset[1];\n    // v_uv.x is the relative prorgress based on each clip. Calculate the absolute progress based on\n    // the whole line by combining the clip start and end value.\n    highp float line_progress = (start + (v_uv.x) * (end - start));\n    // Mark the pixel to be transparent when:\n    // 1. trim_offset range is valid\n    // 2. line_progress is within trim_offset range\n\n    // Nested conditionals fixes the issue\n    // https://github.com/mapbox/mapbox-gl-js/issues/12013\n    if (trim_end > trim_start) {\n        if (line_progress <= trim_end && line_progress >= trim_start) {\n            out_color = vec4(0, 0, 0, 0);\n            trimmed = 0.0;\n        }\n    }\n#endif\n\n#ifdef LIGHTING_3D_MODE\n    out_color = apply_lighting(out_color);\n#endif\n#ifdef FOG\n    out_color = fog_dither(fog_apply_premultiplied(out_color, v_fog_pos));\n#endif\n\n#ifdef RENDER_LINE_ALPHA_DISCARD\n    if (alpha < u_alpha_discard_threshold) {\n        discard;\n    }\n#endif\n\n#ifdef RENDER_LINE_BORDER\n    float edgeBlur = (u_border_width + 1.0 / u_device_pixel_ratio);\n    float alpha2 = clamp(min(dist - (v_width2.t - edgeBlur), v_width2.s - dist) / edgeBlur, 0.0, 1.0);\n    if (alpha2 < 1.) {\n        float smoothAlpha = smoothstep(0.6, 1.0, alpha2);\n#ifdef RENDER_LINE_BORDER_AUTO\n        float Y = (out_color.a > 0.01) ? luminance(out_color.rgb / out_color.a) : 1.; // out_color is premultiplied\n        float adjustment = (Y > 0.) ? 0.5 / Y : 0.45;\n        if (out_color.a > 0.25 && Y < 0.25) {\n            vec3 borderColor = (Y > 0.) ? out_color.rgb : vec3(1, 1, 1) * out_color.a;\n            out_color.rgb = out_color.rgb + borderColor * (adjustment * (1.0 - smoothAlpha));\n        } else {\n            out_color.rgb *= (0.6  + 0.4 * smoothAlpha);\n        }\n#else  // use user-provided border color\n        out_color.rgb = mix(u_border_color.rgb * u_border_color.a * trimmed, out_color.rgb, smoothAlpha);\n#endif // RENDER_LINE_BORDER_AUTO\n    }\n#endif\n    gl_FragColor = out_color * (alpha * opacity);\n\n\n#ifdef OVERDRAW_INSPECTOR\n    gl_FragColor = vec4(1.0);\n#endif\n}\n";

var lineVert = "// floor(127 / 2) == 63.0\n// the maximum allowed miter limit is 2.0 at the moment. the extrude normal is\n// stored in a byte (-128..127). we scale regular normals up to length 63, but\n// there are also \"special\" normals that have a bigger length (of up to 126 in\n// this case).\n// #define scale 63.0\n#define EXTRUDE_SCALE 0.015873016\n\nattribute vec2 a_pos_normal;\nattribute vec4 a_data;\n// Includes in order: a_uv_x, a_split_index, a_clip_start, a_clip_end\n// to reduce attribute count on older devices.\n// Only line-gradient and line-trim-offset will requires a_packed info.\n#if defined(RENDER_LINE_GRADIENT) || defined(RENDER_LINE_TRIM_OFFSET)\nattribute highp vec4 a_packed;\n#endif\n\n#ifdef RENDER_LINE_DASH\nattribute float a_linesofar;\n#endif\n\nuniform mat4 u_matrix;\nuniform mat2 u_pixels_to_tile_units;\nuniform vec2 u_units_to_pixels;\nuniform lowp float u_device_pixel_ratio;\n\nvarying vec2 v_normal;\nvarying vec2 v_width2;\nvarying float v_gamma_scale;\nvarying highp vec4 v_uv;\n\n#ifdef RENDER_LINE_DASH\nuniform vec2 u_texsize;\nuniform float u_tile_units_to_pixels;\nvarying vec2 v_tex;\n#endif\n\n#ifdef RENDER_LINE_GRADIENT\nuniform float u_image_height;\n#endif\n\n#pragma mapbox: define highp vec4 color\n#pragma mapbox: define lowp float floorwidth\n#pragma mapbox: define lowp vec4 dash\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define mediump float gapwidth\n#pragma mapbox: define lowp float offset\n#pragma mapbox: define mediump float width\n\nvoid main() {\n    #pragma mapbox: initialize highp vec4 color\n    #pragma mapbox: initialize lowp float floorwidth\n    #pragma mapbox: initialize lowp vec4 dash\n    #pragma mapbox: initialize lowp float blur\n    #pragma mapbox: initialize lowp float opacity\n    #pragma mapbox: initialize mediump float gapwidth\n    #pragma mapbox: initialize lowp float offset\n    #pragma mapbox: initialize mediump float width\n\n    // the distance over which the line edge fades out.\n    // Retina devices need a smaller distance to avoid aliasing.\n    float ANTIALIASING = 1.0 / u_device_pixel_ratio / 2.0;\n\n    vec2 a_extrude = a_data.xy - 128.0;\n    float a_direction = mod(a_data.z, 4.0) - 1.0;\n    vec2 pos = floor(a_pos_normal * 0.5);\n\n    // x is 1 if it's a round cap, 0 otherwise\n    // y is 1 if the normal points up, and -1 if it points down\n    // We store these in the least significant bit of a_pos_normal\n    mediump vec2 normal = a_pos_normal - 2.0 * pos;\n    normal.y = normal.y * 2.0 - 1.0;\n    v_normal = normal;\n\n    // these transformations used to be applied in the JS and native code bases.\n    // moved them into the shader for clarity and simplicity.\n    gapwidth = gapwidth / 2.0;\n    float halfwidth = width / 2.0;\n    offset = -1.0 * offset;\n\n    float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0);\n    float outset = gapwidth + halfwidth * (gapwidth > 0.0 ? 2.0 : 1.0) + (halfwidth == 0.0 ? 0.0 : ANTIALIASING);\n\n    // Scale the extrusion vector down to a normal and then up by the line width\n    // of this vertex.\n    mediump vec2 dist = outset * a_extrude * EXTRUDE_SCALE;\n\n    // Calculate the offset when drawing a line that is to the side of the actual line.\n    // We do this by creating a vector that points towards the extrude, but rotate\n    // it when we're drawing round end points (a_direction = -1 or 1) since their\n    // extrude vector points in another direction.\n    mediump float u = 0.5 * a_direction;\n    mediump float t = 1.0 - abs(u);\n    mediump vec2 offset2 = offset * a_extrude * EXTRUDE_SCALE * normal.y * mat2(t, -u, u, t);\n\n    vec4 projected_extrude = u_matrix * vec4(dist * u_pixels_to_tile_units, 0.0, 0.0);\n    gl_Position = u_matrix * vec4(pos + offset2 * u_pixels_to_tile_units, 0.0, 1.0) + projected_extrude;\n\n#ifndef RENDER_TO_TEXTURE\n    // calculate how much the perspective view squishes or stretches the extrude\n    float extrude_length_without_perspective = length(dist);\n    float extrude_length_with_perspective = length(projected_extrude.xy / gl_Position.w * u_units_to_pixels);\n    v_gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective;\n#else\n    v_gamma_scale = 1.0;\n#endif\n\n#if defined(RENDER_LINE_GRADIENT) || defined(RENDER_LINE_TRIM_OFFSET)\n    float a_uv_x = a_packed[0];\n    float a_split_index = a_packed[1];\n    highp float a_clip_start = a_packed[2];\n    highp float a_clip_end = a_packed[3];\n#ifdef RENDER_LINE_GRADIENT\n    highp float texel_height = 1.0 / u_image_height;\n    highp float half_texel_height = 0.5 * texel_height;\n\n    v_uv = vec4(a_uv_x, a_split_index * texel_height - half_texel_height, a_clip_start, a_clip_end);\n#else\n    v_uv = vec4(a_uv_x, 0.0, a_clip_start, a_clip_end);\n#endif\n#endif\n\n#ifdef RENDER_LINE_DASH\n    float scale = dash.z == 0.0 ? 0.0 : u_tile_units_to_pixels / dash.z;\n    float height = dash.y;\n\n    v_tex = vec2(a_linesofar * scale / floorwidth, (-normal.y * height + dash.x + 0.5) / u_texsize.y);\n#endif\n\n    v_width2 = vec2(outset, inset);\n\n#ifdef FOG\n    v_fog_pos = fog_position(pos);\n#endif\n}\n";

var linePatternFrag = "uniform lowp float u_device_pixel_ratio;\nuniform vec2 u_texsize;\nuniform float u_tile_units_to_pixels;\n\nuniform sampler2D u_image;\n\nvarying vec2 v_normal;\nvarying vec2 v_width2;\nvarying float v_linesofar;\nvarying float v_gamma_scale;\nvarying float v_width;\n\n#pragma mapbox: define lowp vec4 pattern\n#pragma mapbox: define lowp float pixel_ratio\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n    #pragma mapbox: initialize mediump vec4 pattern\n    #pragma mapbox: initialize lowp float pixel_ratio\n\n    #pragma mapbox: initialize lowp float blur\n    #pragma mapbox: initialize lowp float opacity\n\n    vec2 pattern_tl = pattern.xy;\n    vec2 pattern_br = pattern.zw;\n\n    vec2 display_size = (pattern_br - pattern_tl) / pixel_ratio;\n\n    vec2 pattern_size = vec2(display_size.x / u_tile_units_to_pixels, display_size.y);\n\n    float aspect = display_size.y / v_width;\n\n    // Calculate the distance of the pixel from the line in pixels.\n    float dist = length(v_normal) * v_width2.s;\n\n    // Calculate the antialiasing fade factor. This is either when fading in\n    // the line in case of an offset line (v_width2.t) or when fading out\n    // (v_width2.s)\n    float blur2 = (blur + 1.0 / u_device_pixel_ratio) * v_gamma_scale;\n    float alpha = clamp(min(dist - (v_width2.t - blur2), v_width2.s - dist) / blur2, 0.0, 1.0);\n\n    float x = mod(v_linesofar / pattern_size.x * aspect, 1.0);\n\n    float y = 0.5 * v_normal.y + 0.5;\n\n    vec2 texel_size = 1.0 / u_texsize;\n\n    vec2 pos = mix(pattern_tl * texel_size - texel_size, pattern_br * texel_size + texel_size, vec2(x, y));\n    vec4 color = texture2D(u_image, pos);\n\n#ifdef LIGHTING_3D_MODE\n    color = apply_lighting(color);\n#endif\n#ifdef FOG\n    color = fog_dither(fog_apply_premultiplied(color, v_fog_pos));\n#endif\n\n    gl_FragColor = color * (alpha * opacity);\n\n#ifdef OVERDRAW_INSPECTOR\n    gl_FragColor = vec4(1.0);\n#endif\n}\n";

var linePatternVert = "// floor(127 / 2) == 63.0\n// the maximum allowed miter limit is 2.0 at the moment. the extrude normal is\n// stored in a byte (-128..127). we scale regular normals up to length 63, but\n// there are also \"special\" normals that have a bigger length (of up to 126 in\n// this case).\n// #define scale 63.0\n#define scale 0.015873016\n\nattribute vec2 a_pos_normal;\nattribute vec4 a_data;\nattribute float a_linesofar;\n\nuniform mat4 u_matrix;\nuniform vec2 u_units_to_pixels;\nuniform mat2 u_pixels_to_tile_units;\nuniform lowp float u_device_pixel_ratio;\n\nvarying vec2 v_normal;\nvarying vec2 v_width2;\nvarying float v_linesofar;\nvarying float v_gamma_scale;\nvarying float v_width;\n\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define lowp float offset\n#pragma mapbox: define mediump float gapwidth\n#pragma mapbox: define mediump float width\n#pragma mapbox: define lowp float floorwidth\n#pragma mapbox: define lowp vec4 pattern\n#pragma mapbox: define lowp float pixel_ratio\n\nvoid main() {\n    #pragma mapbox: initialize lowp float blur\n    #pragma mapbox: initialize lowp float opacity\n    #pragma mapbox: initialize lowp float offset\n    #pragma mapbox: initialize mediump float gapwidth\n    #pragma mapbox: initialize mediump float width\n    #pragma mapbox: initialize lowp float floorwidth\n    #pragma mapbox: initialize mediump vec4 pattern\n    #pragma mapbox: initialize lowp float pixel_ratio\n\n    // the distance over which the line edge fades out.\n    // Retina devices need a smaller distance to avoid aliasing.\n    float ANTIALIASING = 1.0 / u_device_pixel_ratio / 2.0;\n\n    vec2 a_extrude = a_data.xy - 128.0;\n    float a_direction = mod(a_data.z, 4.0) - 1.0;\n\n    vec2 pos = floor(a_pos_normal * 0.5);\n\n    // x is 1 if it's a round cap, 0 otherwise\n    // y is 1 if the normal points up, and -1 if it points down\n    // We store these in the least significant bit of a_pos_normal\n    mediump vec2 normal = a_pos_normal - 2.0 * pos;\n    normal.y = normal.y * 2.0 - 1.0;\n    v_normal = normal;\n\n    // these transformations used to be applied in the JS and native code bases.\n    // moved them into the shader for clarity and simplicity.\n    gapwidth = gapwidth / 2.0;\n    float halfwidth = width / 2.0;\n    offset = -1.0 * offset;\n\n    float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0);\n    float outset = gapwidth + halfwidth * (gapwidth > 0.0 ? 2.0 : 1.0) + (halfwidth == 0.0 ? 0.0 : ANTIALIASING);\n\n    // Scale the extrusion vector down to a normal and then up by the line width\n    // of this vertex.\n    mediump vec2 dist = outset * a_extrude * scale;\n\n    // Calculate the offset when drawing a line that is to the side of the actual line.\n    // We do this by creating a vector that points towards the extrude, but rotate\n    // it when we're drawing round end points (a_direction = -1 or 1) since their\n    // extrude vector points in another direction.\n    mediump float u = 0.5 * a_direction;\n    mediump float t = 1.0 - abs(u);\n    mediump vec2 offset2 = offset * a_extrude * scale * normal.y * mat2(t, -u, u, t);\n\n    vec4 projected_extrude = u_matrix * vec4(dist * u_pixels_to_tile_units, 0.0, 0.0);\n    gl_Position = u_matrix * vec4(pos + offset2 * u_pixels_to_tile_units, 0.0, 1.0) + projected_extrude;\n\n#ifndef RENDER_TO_TEXTURE\n    // calculate how much the perspective view squishes or stretches the extrude\n    float extrude_length_without_perspective = length(dist);\n    float extrude_length_with_perspective = length(projected_extrude.xy / gl_Position.w * u_units_to_pixels);\n    v_gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective;\n#else\n    v_gamma_scale = 1.0;\n#endif\n    v_linesofar = a_linesofar;\n    v_width2 = vec2(outset, inset);\n    v_width = floorwidth;\n\n#ifdef FOG\n    v_fog_pos = fog_position(pos);\n#endif\n}\n";

var rasterFrag = "uniform float u_fade_t;\nuniform float u_opacity;\nuniform sampler2D u_image0;\nuniform sampler2D u_image1;\nvarying vec2 v_pos0;\nvarying vec2 v_pos1;\n\nuniform float u_brightness_low;\nuniform float u_brightness_high;\n\nuniform float u_saturation_factor;\nuniform float u_contrast_factor;\nuniform vec3 u_spin_weights;\n\nvoid main() {\n\n    // read and cross-fade colors from the main and parent tiles\n    vec4 color0 = texture2D(u_image0, v_pos0);\n    vec4 color1 = texture2D(u_image1, v_pos1);\n    if (color0.a > 0.0) {\n        color0.rgb = color0.rgb / color0.a;\n    }\n    if (color1.a > 0.0) {\n        color1.rgb = color1.rgb / color1.a;\n    }\n    vec4 color = mix(color0, color1, u_fade_t);\n    color.a *= u_opacity;\n    vec3 rgb = color.rgb;\n\n    // spin\n    rgb = vec3(\n        dot(rgb, u_spin_weights.xyz),\n        dot(rgb, u_spin_weights.zxy),\n        dot(rgb, u_spin_weights.yzx));\n\n    // saturation\n    float average = (color.r + color.g + color.b) / 3.0;\n    rgb += (average - rgb) * u_saturation_factor;\n\n    // contrast\n    rgb = (rgb - 0.5) * u_contrast_factor + 0.5;\n\n    // brightness\n    vec3 u_high_vec = vec3(u_brightness_low, u_brightness_low, u_brightness_low);\n    vec3 u_low_vec = vec3(u_brightness_high, u_brightness_high, u_brightness_high);\n\n    vec3 out_color = mix(u_high_vec, u_low_vec, rgb);\n\n#ifdef LIGHTING_3D_MODE\n    out_color = apply_lighting(out_color);\n#endif\n#ifdef FOG\n    out_color = fog_dither(fog_apply(out_color, v_fog_pos));\n#endif\n\n    gl_FragColor = vec4(out_color * color.a, color.a);\n\n#ifdef OVERDRAW_INSPECTOR\n    gl_FragColor = vec4(1.0);\n#endif\n}\n";

var rasterVert = "uniform mat4 u_matrix;\nuniform vec2 u_tl_parent;\nuniform float u_scale_parent;\nuniform vec2 u_perspective_transform;\n\nattribute vec2 a_pos;\nattribute vec2 a_texture_pos;\n\nvarying vec2 v_pos0;\nvarying vec2 v_pos1;\n\nvoid main() {\n    float w = 1.0 + dot(a_texture_pos, u_perspective_transform);\n    gl_Position = u_matrix * vec4(a_pos * w, 0, w);\n    // We are using Int16 for texture position coordinates to give us enough precision for\n    // fractional coordinates. We use 8192 to scale the texture coordinates in the buffer\n    // as an arbitrarily high number to preserve adequate precision when rendering.\n    // This is also the same value as the EXTENT we are using for our tile buffer pos coordinates,\n    // so math for modifying either is consistent.\n    v_pos0 = a_texture_pos / 8192.0;\n    v_pos1 = (v_pos0 * u_scale_parent) + u_tl_parent;\n\n#ifdef FOG\n    v_fog_pos = fog_position(a_pos);\n#endif\n}\n";

var symbolIconFrag = "uniform sampler2D u_texture;\n\nvarying vec2 v_tex;\nvarying float v_fade_opacity;\n\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n    #pragma mapbox: initialize lowp float opacity\n\n    lowp float alpha = opacity * v_fade_opacity;\n    gl_FragColor = texture2D(u_texture, v_tex) * alpha;\n\n#ifdef OVERDRAW_INSPECTOR\n    gl_FragColor = vec4(1.0);\n#endif\n}\n";

var symbolIconVert = "attribute vec4 a_pos_offset;\nattribute vec4 a_tex_size;\nattribute vec4 a_pixeloffset;\nattribute vec4 a_projected_pos;\nattribute float a_fade_opacity;\n#ifdef PROJECTION_GLOBE_VIEW\nattribute vec3 a_globe_anchor;\nattribute vec3 a_globe_normal;\n#endif\n\nuniform bool u_is_size_zoom_constant;\nuniform bool u_is_size_feature_constant;\nuniform highp float u_size_t; // used to interpolate between zoom stops when size is a composite function\nuniform highp float u_size; // used when size is both zoom and feature constant\nuniform highp float u_camera_to_center_distance;\nuniform bool u_rotate_symbol;\nuniform highp float u_aspect_ratio;\nuniform float u_fade_change;\n\nuniform mat4 u_matrix;\nuniform mat4 u_label_plane_matrix;\nuniform mat4 u_coord_matrix;\n\nuniform bool u_is_text;\nuniform bool u_pitch_with_map;\n\nuniform vec2 u_texsize;\nuniform vec3 u_up_vector;\n\n#ifdef PROJECTION_GLOBE_VIEW\nuniform vec3 u_tile_id;\nuniform mat4 u_inv_rot_matrix;\nuniform vec2 u_merc_center;\nuniform vec3 u_camera_forward;\nuniform float u_zoom_transition;\nuniform vec3 u_ecef_origin;\nuniform mat4 u_tile_matrix;\n#endif\n\nvarying vec2 v_tex;\nvarying float v_fade_opacity;\n\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n    #pragma mapbox: initialize lowp float opacity\n\n    vec2 a_pos = a_pos_offset.xy;\n    vec2 a_offset = a_pos_offset.zw;\n\n    vec2 a_tex = a_tex_size.xy;\n    vec2 a_size = a_tex_size.zw;\n\n    float a_size_min = floor(a_size[0] * 0.5);\n    vec2 a_pxoffset = a_pixeloffset.xy;\n    vec2 a_min_font_scale = a_pixeloffset.zw / 256.0;\n\n    highp float segment_angle = -a_projected_pos[3];\n    float size;\n\n    if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {\n        size = mix(a_size_min, a_size[1], u_size_t) / 128.0;\n    } else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {\n        size = a_size_min / 128.0;\n    } else {\n        size = u_size;\n    }\n\n    vec2 tile_anchor = a_pos;\n    vec3 h = elevationVector(tile_anchor) * elevation(tile_anchor);\n\n    float globe_occlusion_fade;\n    vec3 world_pos;\n    vec3 mercator_pos;\n#ifdef PROJECTION_GLOBE_VIEW\n    mercator_pos = mercator_tile_position(u_inv_rot_matrix, tile_anchor, u_tile_id, u_merc_center);\n    world_pos = mix_globe_mercator(a_globe_anchor + h, mercator_pos, u_zoom_transition);\n\n    vec4 ecef_point = u_tile_matrix * vec4(world_pos, 1.0);\n    vec3 origin_to_point = ecef_point.xyz - u_ecef_origin;\n\n    // Occlude symbols that are on the non-visible side of the globe sphere\n    globe_occlusion_fade = dot(origin_to_point, u_camera_forward) >= 0.0 ? 0.0 : 1.0;\n#else\n    world_pos = vec3(tile_anchor, 0) + h;\n    globe_occlusion_fade = 1.0;\n#endif\n\n    vec4 projected_point = u_matrix * vec4(world_pos, 1);\n\n    highp float camera_to_anchor_distance = projected_point.w;\n    // See comments in symbol_sdf.vertex\n    highp float distance_ratio = u_pitch_with_map ?\n        camera_to_anchor_distance / u_camera_to_center_distance :\n        u_camera_to_center_distance / camera_to_anchor_distance;\n    highp float perspective_ratio = clamp(\n            0.5 + 0.5 * distance_ratio,\n            0.0, // Prevents oversized near-field symbols in pitched/overzoomed tiles\n            1.5);\n\n    size *= perspective_ratio;\n\n    float font_scale = u_is_text ? size / 24.0 : size;\n\n    highp float symbol_rotation = 0.0;\n    if (u_rotate_symbol) {\n        // See comments in symbol_sdf.vertex\n        vec4 offsetProjected_point;\n#ifdef PROJECTION_GLOBE_VIEW\n        vec3 displacement = vec3(a_globe_normal.z, 0, -a_globe_normal.x);\n        offsetProjected_point = u_matrix * vec4(a_globe_anchor + displacement, 1);\n#else\n        offsetProjected_point = u_matrix * vec4(tile_anchor + vec2(1, 0), 0, 1);\n#endif\n        vec2 a = projected_point.xy / projected_point.w;\n        vec2 b = offsetProjected_point.xy / offsetProjected_point.w;\n\n        symbol_rotation = atan((b.y - a.y) / u_aspect_ratio, b.x - a.x);\n    }\n\n    vec4 projected_pos;\n#ifdef PROJECTION_GLOBE_VIEW\n    vec3 proj_pos = mix_globe_mercator(a_projected_pos.xyz + h, mercator_pos, u_zoom_transition);\n    projected_pos = u_label_plane_matrix * vec4(proj_pos, 1.0);\n#else\n    projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, h.z, 1.0);\n#endif\n\n    highp float angle_sin = sin(segment_angle + symbol_rotation);\n    highp float angle_cos = cos(segment_angle + symbol_rotation);\n    mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos);\n\n    float z = 0.0;\n    vec2 offset = rotation_matrix * (a_offset / 32.0 * max(a_min_font_scale, font_scale) + a_pxoffset / 16.0);\n#ifdef TERRAIN\n#ifdef PITCH_WITH_MAP_TERRAIN\n    vec4 tile_pos = u_label_plane_matrix_inv * vec4(a_projected_pos.xy + offset, 0.0, 1.0);\n    z = elevation(tile_pos.xy);\n#endif\n#endif\n    // Symbols might end up being behind the camera. Move them AWAY.\n    float occlusion_fade = occlusionFade(projected_point) * globe_occlusion_fade;\n#ifdef PROJECTION_GLOBE_VIEW\n    // Map aligned labels in globe view are aligned to the surface of the globe\n    vec3 xAxis = u_pitch_with_map ? normalize(cross(a_globe_normal, u_up_vector)) : vec3(1, 0, 0);\n    vec3 yAxis = u_pitch_with_map ? normalize(cross(a_globe_normal, xAxis)) : vec3(0, 1, 0);\n\n    gl_Position = mix(u_coord_matrix * vec4(projected_pos.xyz / projected_pos.w + xAxis * offset.x + yAxis * offset.y, 1.0), AWAY, float(projected_point.w <= 0.0 || occlusion_fade == 0.0));\n#else\n    gl_Position = mix(u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + offset, z, 1.0), AWAY, float(projected_point.w <= 0.0 || occlusion_fade == 0.0));\n#endif\n\n    float projection_transition_fade = 1.0;\n#if defined(PROJECTED_POS_ON_VIEWPORT) && defined(PROJECTION_GLOBE_VIEW)\n    projection_transition_fade = 1.0 - step(EPSILON, u_zoom_transition);\n#endif\n\n    v_tex = a_tex / u_texsize;\n    vec2 fade_opacity = unpack_opacity(a_fade_opacity);\n    float fade_change = fade_opacity[1] > 0.5 ? u_fade_change : -u_fade_change;\n    v_fade_opacity = max(0.0, min(occlusion_fade, fade_opacity[0] + fade_change)) * projection_transition_fade;\n}\n";

var symbolSDFFrag = "#define SDF_PX 8.0\n\nuniform bool u_is_halo;\nuniform sampler2D u_texture;\nuniform highp float u_gamma_scale;\nuniform lowp float u_device_pixel_ratio;\nuniform bool u_is_text;\n\nvarying vec2 v_data0;\nvarying vec3 v_data1;\n\n#pragma mapbox: define highp vec4 fill_color\n#pragma mapbox: define highp vec4 halo_color\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define lowp float halo_width\n#pragma mapbox: define lowp float halo_blur\n\nvoid main() {\n    #pragma mapbox: initialize highp vec4 fill_color\n    #pragma mapbox: initialize highp vec4 halo_color\n    #pragma mapbox: initialize lowp float opacity\n    #pragma mapbox: initialize lowp float halo_width\n    #pragma mapbox: initialize lowp float halo_blur\n\n    float EDGE_GAMMA = 0.105 / u_device_pixel_ratio;\n\n    vec2 tex = v_data0.xy;\n    float gamma_scale = v_data1.x;\n    float size = v_data1.y;\n    float fade_opacity = v_data1[2];\n\n    float fontScale = u_is_text ? size / 24.0 : size;\n\n    lowp vec4 color = fill_color;\n    highp float gamma = EDGE_GAMMA / (fontScale * u_gamma_scale);\n    lowp float buff = (256.0 - 64.0) / 256.0;\n    if (u_is_halo) {\n        color = halo_color;\n        gamma = (halo_blur * 1.19 / SDF_PX + EDGE_GAMMA) / (fontScale * u_gamma_scale);\n        buff = (6.0 - halo_width / fontScale) / SDF_PX;\n    }\n\n    lowp float dist = texture2D(u_texture, tex).a;\n    highp float gamma_scaled = gamma * gamma_scale;\n    highp float alpha = smoothstep(buff - gamma_scaled, buff + gamma_scaled, dist);\n\n    gl_FragColor = color * (alpha * opacity * fade_opacity);\n\n#ifdef OVERDRAW_INSPECTOR\n    gl_FragColor = vec4(1.0);\n#endif\n}\n";

var symbolSDFVert = "attribute vec4 a_pos_offset;\nattribute vec4 a_tex_size;\nattribute vec4 a_pixeloffset;\nattribute vec4 a_projected_pos;\nattribute float a_fade_opacity;\n#ifdef PROJECTION_GLOBE_VIEW\nattribute vec3 a_globe_anchor;\nattribute vec3 a_globe_normal;\n#endif\n\n// contents of a_size vary based on the type of property value\n// used for {text,icon}-size.\n// For constants, a_size is disabled.\n// For source functions, we bind only one value per vertex: the value of {text,icon}-size evaluated for the current feature.\n// For composite functions:\n// [ text-size(lowerZoomStop, feature),\n//   text-size(upperZoomStop, feature) ]\nuniform bool u_is_size_zoom_constant;\nuniform bool u_is_size_feature_constant;\nuniform highp float u_size_t; // used to interpolate between zoom stops when size is a composite function\nuniform highp float u_size; // used when size is both zoom and feature constant\nuniform mat4 u_matrix;\nuniform mat4 u_label_plane_matrix;\nuniform mat4 u_coord_matrix;\nuniform bool u_is_text;\nuniform bool u_pitch_with_map;\nuniform bool u_rotate_symbol;\nuniform highp float u_aspect_ratio;\nuniform highp float u_camera_to_center_distance;\nuniform float u_fade_change;\nuniform vec2 u_texsize;\nuniform vec3 u_up_vector;\n\n#ifdef PROJECTION_GLOBE_VIEW\nuniform vec3 u_tile_id;\nuniform mat4 u_inv_rot_matrix;\nuniform vec2 u_merc_center;\nuniform vec3 u_camera_forward;\nuniform float u_zoom_transition;\nuniform vec3 u_ecef_origin;\nuniform mat4 u_tile_matrix;\n#endif\n\nvarying vec2 v_data0;\nvarying vec3 v_data1;\n\n#pragma mapbox: define highp vec4 fill_color\n#pragma mapbox: define highp vec4 halo_color\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define lowp float halo_width\n#pragma mapbox: define lowp float halo_blur\n\nvoid main() {\n    #pragma mapbox: initialize highp vec4 fill_color\n    #pragma mapbox: initialize highp vec4 halo_color\n    #pragma mapbox: initialize lowp float opacity\n    #pragma mapbox: initialize lowp float halo_width\n    #pragma mapbox: initialize lowp float halo_blur\n\n    vec2 a_pos = a_pos_offset.xy;\n    vec2 a_offset = a_pos_offset.zw;\n\n    vec2 a_tex = a_tex_size.xy;\n    vec2 a_size = a_tex_size.zw;\n\n    float a_size_min = floor(a_size[0] * 0.5);\n    vec2 a_pxoffset = a_pixeloffset.xy;\n\n    highp float segment_angle = -a_projected_pos[3];\n    float size;\n\n    if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {\n        size = mix(a_size_min, a_size[1], u_size_t) / 128.0;\n    } else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {\n        size = a_size_min / 128.0;\n    } else {\n        size = u_size;\n    }\n\n    vec2 tile_anchor = a_pos;\n    vec3 h = elevationVector(tile_anchor) * elevation(tile_anchor);\n\n    float globe_occlusion_fade;\n    vec3 world_pos;\n    vec3 mercator_pos;\n#ifdef PROJECTION_GLOBE_VIEW\n    mercator_pos = mercator_tile_position(u_inv_rot_matrix, tile_anchor, u_tile_id, u_merc_center);\n    world_pos = mix_globe_mercator(a_globe_anchor + h, mercator_pos, u_zoom_transition);\n\n    vec4 ecef_point = u_tile_matrix * vec4(world_pos, 1.0);\n    vec3 origin_to_point = ecef_point.xyz - u_ecef_origin;\n\n    // Occlude symbols that are on the non-visible side of the globe sphere\n    globe_occlusion_fade = dot(origin_to_point, u_camera_forward) >= 0.0 ? 0.0 : 1.0;\n#else\n    world_pos = vec3(tile_anchor, 0) + h;\n    globe_occlusion_fade = 1.0;\n#endif\n\n    vec4 projected_point = u_matrix * vec4(world_pos, 1);\n\n    highp float camera_to_anchor_distance = projected_point.w;\n    // If the label is pitched with the map, layout is done in pitched space,\n    // which makes labels in the distance smaller relative to viewport space.\n    // We counteract part of that effect by multiplying by the perspective ratio.\n    // If the label isn't pitched with the map, we do layout in viewport space,\n    // which makes labels in the distance larger relative to the features around\n    // them. We counteract part of that effect by dividing by the perspective ratio.\n    highp float distance_ratio = u_pitch_with_map ?\n        camera_to_anchor_distance / u_camera_to_center_distance :\n        u_camera_to_center_distance / camera_to_anchor_distance;\n    highp float perspective_ratio = clamp(\n        0.5 + 0.5 * distance_ratio,\n        0.0, // Prevents oversized near-field symbols in pitched/overzoomed tiles\n        1.5);\n\n    size *= perspective_ratio;\n\n    float fontScale = u_is_text ? size / 24.0 : size;\n\n    highp float symbol_rotation = 0.0;\n    if (u_rotate_symbol) {\n        // Point labels with 'rotation-alignment: map' are horizontal with respect to tile units\n        // To figure out that angle in projected space, we draw a short horizontal line in tile\n        // space, project it, and measure its angle in projected space.\n        vec4 offsetprojected_point;\n#ifdef PROJECTION_GLOBE_VIEW\n        // Use x-axis of the label plane for displacement (x_axis = cross(normal, vec3(0, -1, 0)))\n        vec3 displacement = vec3(a_globe_normal.z, 0, -a_globe_normal.x);\n        offsetprojected_point = u_matrix * vec4(a_globe_anchor + displacement, 1);\n#else\n        offsetprojected_point = u_matrix * vec4(tile_anchor + vec2(1, 0), 0, 1);\n#endif\n        vec2 a = projected_point.xy / projected_point.w;\n        vec2 b = offsetprojected_point.xy / offsetprojected_point.w;\n\n        symbol_rotation = atan((b.y - a.y) / u_aspect_ratio, b.x - a.x);\n    }\n\n    vec4 projected_pos;\n#ifdef PROJECTION_GLOBE_VIEW\n    vec3 proj_pos = mix_globe_mercator(a_projected_pos.xyz + h, mercator_pos, u_zoom_transition);\n    projected_pos = u_label_plane_matrix * vec4(proj_pos, 1.0);\n#else\n    projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, h.z, 1.0);\n#endif\n\n    highp float angle_sin = sin(segment_angle + symbol_rotation);\n    highp float angle_cos = cos(segment_angle + symbol_rotation);\n    mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos);\n\n    float z = 0.0;\n    vec2 offset = rotation_matrix * (a_offset / 32.0 * fontScale + a_pxoffset);\n#ifdef TERRAIN\n#ifdef PITCH_WITH_MAP_TERRAIN\n    vec4 tile_pos = u_label_plane_matrix_inv * vec4(a_projected_pos.xy + offset, 0.0, 1.0);\n    z = elevation(tile_pos.xy);\n#endif\n#endif\n    // Symbols might end up being behind the camera. Move them AWAY.\n    float occlusion_fade = occlusionFade(projected_point) * globe_occlusion_fade;\n#ifdef PROJECTION_GLOBE_VIEW\n    // Map aligned labels in globe view are aligned to the surface of the globe\n    vec3 xAxis = u_pitch_with_map ? normalize(cross(a_globe_normal, u_up_vector)) : vec3(1, 0, 0);\n    vec3 yAxis = u_pitch_with_map ? normalize(cross(a_globe_normal, xAxis)) : vec3(0, 1, 0);\n\n    gl_Position = mix(u_coord_matrix * vec4(projected_pos.xyz / projected_pos.w + xAxis * offset.x + yAxis * offset.y, 1.0), AWAY, float(projected_point.w <= 0.0 || occlusion_fade == 0.0));\n#else\n    gl_Position = mix(u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + offset, z, 1.0), AWAY, float(projected_point.w <= 0.0 || occlusion_fade == 0.0));\n#endif\n    float gamma_scale = gl_Position.w;\n\n    float projection_transition_fade = 1.0;\n#if defined(PROJECTED_POS_ON_VIEWPORT) && defined(PROJECTION_GLOBE_VIEW)\n    projection_transition_fade = 1.0 - step(EPSILON, u_zoom_transition);\n#endif\n\n    vec2 fade_opacity = unpack_opacity(a_fade_opacity);\n    float fade_change = fade_opacity[1] > 0.5 ? u_fade_change : -u_fade_change;\n    float interpolated_fade_opacity = max(0.0, min(occlusion_fade, fade_opacity[0] + fade_change));\n\n    v_data0 = a_tex / u_texsize;\n    v_data1 = vec3(gamma_scale, size, interpolated_fade_opacity * projection_transition_fade);\n}\n";

var symbolTextAndIconFrag = "#define SDF_PX 8.0\n\n#define SDF 1.0\n#define ICON 0.0\n\nuniform bool u_is_halo;\nuniform sampler2D u_texture;\nuniform sampler2D u_texture_icon;\nuniform highp float u_gamma_scale;\nuniform lowp float u_device_pixel_ratio;\n\nvarying vec4 v_data0;\nvarying vec4 v_data1;\n\n#pragma mapbox: define highp vec4 fill_color\n#pragma mapbox: define highp vec4 halo_color\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define lowp float halo_width\n#pragma mapbox: define lowp float halo_blur\n\nvoid main() {\n    #pragma mapbox: initialize highp vec4 fill_color\n    #pragma mapbox: initialize highp vec4 halo_color\n    #pragma mapbox: initialize lowp float opacity\n    #pragma mapbox: initialize lowp float halo_width\n    #pragma mapbox: initialize lowp float halo_blur\n\n    float fade_opacity = v_data1[2];\n\n    if (v_data1.w == ICON) {\n        vec2 tex_icon = v_data0.zw;\n        lowp float alpha = opacity * fade_opacity;\n        gl_FragColor = texture2D(u_texture_icon, tex_icon) * alpha;\n\n#ifdef OVERDRAW_INSPECTOR\n        gl_FragColor = vec4(1.0);\n#endif\n        return;\n    }\n\n    vec2 tex = v_data0.xy;\n\n    float EDGE_GAMMA = 0.105 / u_device_pixel_ratio;\n\n    float gamma_scale = v_data1.x;\n    float size = v_data1.y;\n\n    float fontScale = size / 24.0;\n\n    lowp vec4 color = fill_color;\n    highp float gamma = EDGE_GAMMA / (fontScale * u_gamma_scale);\n    lowp float buff = (256.0 - 64.0) / 256.0;\n    if (u_is_halo) {\n        color = halo_color;\n        gamma = (halo_blur * 1.19 / SDF_PX + EDGE_GAMMA) / (fontScale * u_gamma_scale);\n        buff = (6.0 - halo_width / fontScale) / SDF_PX;\n    }\n\n    lowp float dist = texture2D(u_texture, tex).a;\n    highp float gamma_scaled = gamma * gamma_scale;\n    highp float alpha = smoothstep(buff - gamma_scaled, buff + gamma_scaled, dist);\n\n    gl_FragColor = color * (alpha * opacity * fade_opacity);\n\n#ifdef OVERDRAW_INSPECTOR\n    gl_FragColor = vec4(1.0);\n#endif\n}\n";

var symbolTextAndIconVert = "attribute vec4 a_pos_offset;\nattribute vec4 a_tex_size;\nattribute vec4 a_projected_pos;\nattribute float a_fade_opacity;\n#ifdef PROJECTION_GLOBE_VIEW\nattribute vec3 a_globe_anchor;\nattribute vec3 a_globe_normal;\n#endif\n\n// contents of a_size vary based on the type of property value\n// used for {text,icon}-size.\n// For constants, a_size is disabled.\n// For source functions, we bind only one value per vertex: the value of {text,icon}-size evaluated for the current feature.\n// For composite functions:\n// [ text-size(lowerZoomStop, feature),\n//   text-size(upperZoomStop, feature) ]\nuniform bool u_is_size_zoom_constant;\nuniform bool u_is_size_feature_constant;\nuniform highp float u_size_t; // used to interpolate between zoom stops when size is a composite function\nuniform highp float u_size; // used when size is both zoom and feature constant\nuniform mat4 u_matrix;\nuniform mat4 u_label_plane_matrix;\nuniform mat4 u_coord_matrix;\nuniform bool u_is_text;\nuniform bool u_pitch_with_map;\nuniform bool u_rotate_symbol;\nuniform highp float u_aspect_ratio;\nuniform highp float u_camera_to_center_distance;\nuniform float u_fade_change;\nuniform vec2 u_texsize;\nuniform vec3 u_up_vector;\nuniform vec2 u_texsize_icon;\n\n#ifdef PROJECTION_GLOBE_VIEW\nuniform vec3 u_tile_id;\nuniform mat4 u_inv_rot_matrix;\nuniform vec2 u_merc_center;\nuniform vec3 u_camera_forward;\nuniform float u_zoom_transition;\nuniform vec3 u_ecef_origin;\nuniform mat4 u_tile_matrix;\n#endif\n\nvarying vec4 v_data0;\nvarying vec4 v_data1;\n\n#pragma mapbox: define highp vec4 fill_color\n#pragma mapbox: define highp vec4 halo_color\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define lowp float halo_width\n#pragma mapbox: define lowp float halo_blur\n\nvoid main() {\n    #pragma mapbox: initialize highp vec4 fill_color\n    #pragma mapbox: initialize highp vec4 halo_color\n    #pragma mapbox: initialize lowp float opacity\n    #pragma mapbox: initialize lowp float halo_width\n    #pragma mapbox: initialize lowp float halo_blur\n\n    vec2 a_pos = a_pos_offset.xy;\n    vec2 a_offset = a_pos_offset.zw;\n\n    vec2 a_tex = a_tex_size.xy;\n    vec2 a_size = a_tex_size.zw;\n\n    float a_size_min = floor(a_size[0] * 0.5);\n    float is_sdf = a_size[0] - 2.0 * a_size_min;\n\n    highp float segment_angle = -a_projected_pos[3];\n    float size;\n\n    if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {\n        size = mix(a_size_min, a_size[1], u_size_t) / 128.0;\n    } else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {\n        size = a_size_min / 128.0;\n    } else {\n        size = u_size;\n    }\n\n    vec2 tile_anchor = a_pos;\n    vec3 h = elevationVector(tile_anchor) * elevation(tile_anchor);\n\n    float globe_occlusion_fade;\n    vec3 world_pos;\n    vec3 mercator_pos;\n#ifdef PROJECTION_GLOBE_VIEW\n    mercator_pos = mercator_tile_position(u_inv_rot_matrix, tile_anchor, u_tile_id, u_merc_center);\n    world_pos = mix_globe_mercator(a_globe_anchor + h, mercator_pos, u_zoom_transition);\n\n    vec4 ecef_point = u_tile_matrix * vec4(world_pos, 1.0);\n    vec3 origin_to_point = ecef_point.xyz - u_ecef_origin;\n\n    // Occlude symbols that are on the non-visible side of the globe sphere\n    globe_occlusion_fade = dot(origin_to_point, u_camera_forward) >= 0.0 ? 0.0 : 1.0;\n#else\n    world_pos = vec3(tile_anchor, 0) + h;\n    globe_occlusion_fade = 1.0;\n#endif\n\n    vec4 projected_point = u_matrix * vec4(world_pos, 1);\n\n    highp float camera_to_anchor_distance = projected_point.w;\n    // If the label is pitched with the map, layout is done in pitched space,\n    // which makes labels in the distance smaller relative to viewport space.\n    // We counteract part of that effect by multiplying by the perspective ratio.\n    // If the label isn't pitched with the map, we do layout in viewport space,\n    // which makes labels in the distance larger relative to the features around\n    // them. We counteract part of that effect by dividing by the perspective ratio.\n    highp float distance_ratio = u_pitch_with_map ?\n        camera_to_anchor_distance / u_camera_to_center_distance :\n        u_camera_to_center_distance / camera_to_anchor_distance;\n    highp float perspective_ratio = clamp(\n        0.5 + 0.5 * distance_ratio,\n        0.0, // Prevents oversized near-field symbols in pitched/overzoomed tiles\n        1.5);\n\n    size *= perspective_ratio;\n\n    float font_scale = size / 24.0;\n\n    highp float symbol_rotation = 0.0;\n    if (u_rotate_symbol) {\n        // Point labels with 'rotation-alignment: map' are horizontal with respect to tile units\n        // To figure out that angle in projected space, we draw a short horizontal line in tile\n        // space, project it, and measure its angle in projected space.\n        vec4 offset_projected_point = u_matrix * vec4(a_pos + vec2(1, 0), 0, 1);\n\n        vec2 a = projected_point.xy / projected_point.w;\n        vec2 b = offset_projected_point.xy / offset_projected_point.w;\n\n        symbol_rotation = atan((b.y - a.y) / u_aspect_ratio, b.x - a.x);\n    }\n\n    vec4 projected_pos;\n#ifdef PROJECTION_GLOBE_VIEW\n    vec3 proj_pos = mix_globe_mercator(a_projected_pos.xyz + h, mercator_pos, u_zoom_transition);\n    projected_pos = u_label_plane_matrix * vec4(proj_pos, 1.0);\n#else\n    projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, h.z, 1.0);\n#endif\n\n    highp float angle_sin = sin(segment_angle + symbol_rotation);\n    highp float angle_cos = cos(segment_angle + symbol_rotation);\n    mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos);\n\n    float z = 0.0;\n    vec2 offset = rotation_matrix * (a_offset / 32.0 * font_scale);\n#ifdef TERRAIN\n#ifdef PITCH_WITH_MAP_TERRAIN\n    vec4 tile_pos = u_label_plane_matrix_inv * vec4(a_projected_pos.xy + offset, 0.0, 1.0);\n    z = elevation(tile_pos.xy);\n#endif\n#endif\n    float occlusion_fade = occlusionFade(projected_point) * globe_occlusion_fade;\n#ifdef PROJECTION_GLOBE_VIEW\n    // Map aligned labels in globe view are aligned to the surface of the globe\n    vec3 xAxis = u_pitch_with_map ? normalize(cross(a_globe_normal, u_up_vector)) : vec3(1, 0, 0);\n    vec3 yAxis = u_pitch_with_map ? normalize(cross(a_globe_normal, xAxis)) : vec3(0, 1, 0);\n\n    gl_Position = mix(u_coord_matrix * vec4(projected_pos.xyz / projected_pos.w + xAxis * offset.x + yAxis * offset.y, 1.0), AWAY, float(projected_point.w <= 0.0 || occlusion_fade == 0.0));\n#else\n    gl_Position = mix(u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + offset, z, 1.0), AWAY, float(projected_point.w <= 0.0 || occlusion_fade == 0.0));\n#endif\n    float gamma_scale = gl_Position.w;\n\n    vec2 fade_opacity = unpack_opacity(a_fade_opacity);\n    float fade_change = fade_opacity[1] > 0.5 ? u_fade_change : -u_fade_change;\n    float interpolated_fade_opacity = max(0.0, min(occlusion_fade, fade_opacity[0] + fade_change));\n\n    float projection_transition_fade = 1.0;\n#if defined(PROJECTED_POS_ON_VIEWPORT) && defined(PROJECTION_GLOBE_VIEW)\n    projection_transition_fade = 1.0 - step(EPSILON, u_zoom_transition);\n#endif\n\n    v_data0.xy = a_tex / u_texsize;\n    v_data0.zw = a_tex / u_texsize_icon;\n    v_data1 = vec4(gamma_scale, size, interpolated_fade_opacity * projection_transition_fade, is_sdf);\n}\n";

var skyboxFrag = "// [1] Banding in games http://loopit.dk/banding_in_games.pdf\n\nvarying lowp vec3 v_uv;\n\nuniform lowp samplerCube u_cubemap;\nuniform lowp float u_opacity;\nuniform highp float u_temporal_offset;\nuniform highp vec3 u_sun_direction;\n\nfloat sun_disk(highp vec3 ray_direction, highp vec3 sun_direction) {\n    highp float cos_angle = dot(normalize(ray_direction), sun_direction);\n\n    // Sun angular angle is ~0.5°\n    const highp float cos_sun_angular_diameter = 0.99996192306;\n    const highp float smoothstep_delta = 1e-5;\n\n    return smoothstep(\n        cos_sun_angular_diameter - smoothstep_delta,\n        cos_sun_angular_diameter + smoothstep_delta,\n        cos_angle);\n}\n\nfloat map(float value, float start, float end, float new_start, float new_end) {\n    return ((value - start) * (new_end - new_start)) / (end - start) + new_start;\n}\n\nvoid main() {\n    vec3 uv = v_uv;\n\n    // Add a small offset to prevent black bands around areas where\n    // the scattering algorithm does not manage to gather lighting\n    const float y_bias = 0.015;\n    uv.y += y_bias;\n\n    // Inverse of the operation applied for non-linear UV parameterization\n    uv.y = pow(abs(uv.y), 1.0 / 5.0);\n\n    // To make better utilization of the visible range (e.g. over the horizon, UVs\n    // from 0.0 to 1.0 on the Y-axis in cubemap space), the UV range is remapped from\n    // (0.0,1.0) to (-1.0,1.0) on y. The inverse operation is applied when generating.\n    uv.y = map(uv.y, 0.0, 1.0, -1.0, 1.0);\n\n    vec3 sky_color = textureCube(u_cubemap, uv).rgb;\n\n#ifdef FOG\n    // Apply fog contribution if enabled\n    // Swizzle to put z-up (ignoring x-y mirror since fog does not depend on azimuth)\n    sky_color = fog_apply_sky_gradient(v_uv.xzy, sky_color);\n#endif\n\n    // Dither [1]\n    sky_color.rgb = dither(sky_color.rgb, gl_FragCoord.xy + u_temporal_offset);\n    // Add sun disk\n    sky_color += 0.1 * sun_disk(v_uv, u_sun_direction);\n\n    gl_FragColor = vec4(sky_color * u_opacity, u_opacity);\n\n#ifdef OVERDRAW_INSPECTOR\n    gl_FragColor = vec4(1.0);\n#endif\n}\n";

var skyboxGradientFrag = "varying highp vec3 v_uv;\n\nuniform lowp sampler2D u_color_ramp;\nuniform highp vec3 u_center_direction;\nuniform lowp float u_radius;\nuniform lowp float u_opacity;\nuniform highp float u_temporal_offset;\n\nvoid main() {\n    float progress = acos(dot(normalize(v_uv), u_center_direction)) / u_radius;\n    vec4 color = texture2D(u_color_ramp, vec2(progress, 0.5));\n\n#ifdef FOG\n    // Apply fog contribution if enabled, make sure to un/post multiply alpha before/after\n    // applying sky gradient contribution, as color ramps are premultiplied-alpha colors.\n    // Swizzle to put z-up (ignoring x-y mirror since fog does not depend on azimuth)\n    color.rgb = fog_apply_sky_gradient(v_uv.xzy, color.rgb / color.a) * color.a;\n#endif\n\n    color *= u_opacity;\n\n    // Dither\n    color.rgb = dither(color.rgb, gl_FragCoord.xy + u_temporal_offset);\n\n    gl_FragColor = color;\n\n#ifdef OVERDRAW_INSPECTOR\n    gl_FragColor = vec4(1.0);\n#endif\n}\n";

var skyboxVert = "attribute highp vec3 a_pos_3f;\n\nuniform lowp mat4 u_matrix;\n\nvarying highp vec3 v_uv;\n\nvoid main() {\n    const mat3 half_neg_pi_around_x = mat3(1.0, 0.0,  0.0,\n                                           0.0, 0.0, -1.0,\n                                           0.0, 1.0,  0.0);\n\n    v_uv = half_neg_pi_around_x * a_pos_3f;\n    vec4 pos = u_matrix * vec4(a_pos_3f, 1.0);\n\n    // Enforce depth to be 1.0\n    gl_Position = pos.xyww;\n}\n";

var terrainRasterFrag = "uniform sampler2D u_image0;\nvarying vec2 v_pos0;\n\n#ifdef FOG\nvarying float v_fog_opacity;\n#endif\n\n#ifdef RENDER_SHADOWS\nvarying vec4 v_pos_light_view_0;\nvarying vec4 v_pos_light_view_1;\nvarying float v_depth;\n#endif\n\nvoid main() {\n    vec4 color = texture2D(u_image0, v_pos0);\n\n#ifdef RENDER_SHADOWS\n    color.xyz = shadowed_color(color.xyz, v_pos_light_view_0, v_pos_light_view_1, v_depth);\n#endif\n\n#ifdef FOG\n#ifdef ZERO_EXAGGERATION\n    color = fog_dither(fog_apply_premultiplied(color, v_fog_pos));\n#else\n    color = fog_dither(fog_apply_from_vert(color, v_fog_opacity));\n#endif\n#endif\n    gl_FragColor = color;\n#ifdef TERRAIN_WIREFRAME\n    gl_FragColor = vec4(1.0, 0.0, 0.0, 0.8);\n#endif\n#ifdef OVERDRAW_INSPECTOR\n    gl_FragColor = vec4(1.0);\n#endif\n}\n";

var terrainRasterVert = "uniform mat4 u_matrix;\nuniform float u_skirt_height;\n\nattribute vec2 a_pos;\n\nvarying vec2 v_pos0;\n\n#ifdef FOG\nvarying float v_fog_opacity;\n#endif\n\n#ifdef RENDER_SHADOWS\nuniform mat4 u_light_matrix_0;\nuniform mat4 u_light_matrix_1;\nvarying vec4 v_pos_light_view_0;\nvarying vec4 v_pos_light_view_1;\nvarying float v_depth;\n#endif\n\nconst float wireframeOffset = 0.00015;\n\nvoid main() {\n    vec3 decomposedPosAndSkirt = decomposeToPosAndSkirt(a_pos);\n    float skirt = decomposedPosAndSkirt.z;\n    vec2 decodedPos = decomposedPosAndSkirt.xy;\n    float elevation = elevation(decodedPos) - skirt * u_skirt_height;\n#ifdef TERRAIN_WIREFRAME\n    elevation += wireframeOffset;\n#endif\n    v_pos0 = decodedPos / 8192.0;\n    gl_Position = u_matrix * vec4(decodedPos, elevation, 1.0);\n\n#ifdef FOG\n#ifdef ZERO_EXAGGERATION\n    v_fog_pos = fog_position(decodedPos);\n#else\n    v_fog_opacity = fog(fog_position(vec3(decodedPos, elevation)));\n#endif\n#endif\n\n#ifdef RENDER_SHADOWS\n    vec3 pos = vec3(decodedPos, elevation);\n    v_pos_light_view_0 = u_light_matrix_0 * vec4(pos, 1.);\n    v_pos_light_view_1 = u_light_matrix_1 * vec4(pos, 1.);\n    v_depth = gl_Position.w;\n#endif\n}\n";

var terrainDepthFrag = "#ifdef GL_ES\nprecision highp float;\n#endif\n\nvarying float v_depth;\n\nvoid main() {\n    gl_FragColor = pack_depth(v_depth);\n}\n";

var terrainDepthVert = "uniform mat4 u_matrix;\nattribute vec2 a_pos;\n\nvarying float v_depth;\n\nvoid main() {\n    float elevation = elevation(a_pos);\n    gl_Position = u_matrix * vec4(a_pos, elevation, 1.0);\n    v_depth = gl_Position.z / gl_Position.w;\n}";

var preludeTerrainVert = "// Also declared in data/bucket/fill_extrusion_bucket.js\n#define ELEVATION_SCALE 7.0\n#define ELEVATION_OFFSET 450.0\n\n#ifdef PROJECTION_GLOBE_VIEW\n\nuniform vec3 u_tile_tl_up;\nuniform vec3 u_tile_tr_up;\nuniform vec3 u_tile_br_up;\nuniform vec3 u_tile_bl_up;\nuniform float u_tile_up_scale;\nvec3 elevationVector(vec2 pos) {\n    vec2 uv = pos / EXTENT;\n    vec3 up = normalize(mix(\n        mix(u_tile_tl_up, u_tile_tr_up, uv.xxx),\n        mix(u_tile_bl_up, u_tile_br_up, uv.xxx),\n        uv.yyy));\n    return up * u_tile_up_scale;\n}\n\n#else\n\nvec3 elevationVector(vec2 pos) { return vec3(0, 0, 1); }\n\n#endif\n\n// Handle skirt flag for terrain & globe shaders\n\nconst float skirtOffset = 24575.0;\nvec3 decomposeToPosAndSkirt(vec2 posWithComposedSkirt)\n{\n    float skirt = float(posWithComposedSkirt.x >= skirtOffset);\n    vec2 pos = posWithComposedSkirt - vec2(skirt * skirtOffset, 0.0);\n\n    return vec3(pos, skirt);\n}\n\n\n#ifdef TERRAIN\n\n#ifdef TERRAIN_DEM_FLOAT_FORMAT\nuniform highp sampler2D u_dem;\nuniform highp sampler2D u_dem_prev;\n#else\nuniform sampler2D u_dem;\nuniform sampler2D u_dem_prev;\n#endif\nuniform vec4 u_dem_unpack;\nuniform vec2 u_dem_tl;\nuniform vec2 u_dem_tl_prev;\nuniform float u_dem_scale;\nuniform float u_dem_scale_prev;\nuniform float u_dem_size;\nuniform float u_dem_lerp;\nuniform float u_exaggeration;\nuniform float u_meter_to_dem;\nuniform mat4 u_label_plane_matrix_inv;\n\nuniform sampler2D u_depth;\nuniform vec2 u_depth_size_inv;\n\nvec4 tileUvToDemSample(vec2 uv, float dem_size, float dem_scale, vec2 dem_tl) {\n    vec2 pos = dem_size * (uv * dem_scale + dem_tl) + 1.0;\n    vec2 f = fract(pos);\n    return vec4((pos - f + 0.5) / (dem_size + 2.0), f);\n}\n\nfloat decodeElevation(vec4 v) {\n    return dot(vec4(v.xyz * 255.0, -1.0), u_dem_unpack);\n}\n\nfloat currentElevation(vec2 apos) {\n#ifdef TERRAIN_DEM_FLOAT_FORMAT\n    vec2 pos = (u_dem_size * (apos / 8192.0 * u_dem_scale + u_dem_tl) + 1.5) / (u_dem_size + 2.0);\n    return u_exaggeration * texture2D(u_dem, pos).a;\n#else\n    float dd = 1.0 / (u_dem_size + 2.0);\n    vec4 r = tileUvToDemSample(apos / 8192.0, u_dem_size, u_dem_scale, u_dem_tl);\n    vec2 pos = r.xy;\n    vec2 f = r.zw;\n\n    float tl = decodeElevation(texture2D(u_dem, pos));\n#ifdef TERRAIN_DEM_NEAREST_FILTER\n    return u_exaggeration * tl;\n#endif\n    float tr = decodeElevation(texture2D(u_dem, pos + vec2(dd, 0.0)));\n    float bl = decodeElevation(texture2D(u_dem, pos + vec2(0.0, dd)));\n    float br = decodeElevation(texture2D(u_dem, pos + vec2(dd, dd)));\n\n    return u_exaggeration * mix(mix(tl, tr, f.x), mix(bl, br, f.x), f.y);\n#endif\n}\n\nfloat prevElevation(vec2 apos) {\n#ifdef TERRAIN_DEM_FLOAT_FORMAT\n    vec2 pos = (u_dem_size * (apos / 8192.0 * u_dem_scale_prev + u_dem_tl_prev) + 1.5) / (u_dem_size + 2.0);\n    return u_exaggeration * texture2D(u_dem_prev, pos).a;\n#else\n    float dd = 1.0 / (u_dem_size + 2.0);\n    vec4 r = tileUvToDemSample(apos / 8192.0, u_dem_size, u_dem_scale_prev, u_dem_tl_prev);\n    vec2 pos = r.xy;\n    vec2 f = r.zw;\n\n    float tl = decodeElevation(texture2D(u_dem_prev, pos));\n    float tr = decodeElevation(texture2D(u_dem_prev, pos + vec2(dd, 0.0)));\n    float bl = decodeElevation(texture2D(u_dem_prev, pos + vec2(0.0, dd)));\n    float br = decodeElevation(texture2D(u_dem_prev, pos + vec2(dd, dd)));\n\n    return u_exaggeration * mix(mix(tl, tr, f.x), mix(bl, br, f.x), f.y);\n#endif\n}\n\n#ifdef TERRAIN_VERTEX_MORPHING\nfloat elevation(vec2 apos) {\n    #ifdef ZERO_EXAGGERATION\n        return 0.0;\n    #endif\n    float nextElevation = currentElevation(apos);\n    float prevElevation = prevElevation(apos);\n    return mix(prevElevation, nextElevation, u_dem_lerp);\n}\n#else\nfloat elevation(vec2 apos) {\n    #ifdef ZERO_EXAGGERATION\n        return 0.0;\n    #endif\n    return currentElevation(apos);\n}\n#endif\n\n// Unpack depth from RGBA. A piece of code copied in various libraries and WebGL\n// shadow mapping examples.\n// https://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/\nhighp float unpack_depth(highp vec4 rgba_depth)\n{\n    const highp vec4 bit_shift = vec4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0);\n    return dot(rgba_depth, bit_shift) * 2.0 - 1.0;\n}\n\nbool isOccluded(vec4 frag) {\n    vec3 coord = frag.xyz / frag.w;\n    float depth = unpack_depth(texture2D(u_depth, (coord.xy + 1.0) * 0.5));\n    return coord.z > depth + 0.0005;\n}\n\nfloat occlusionFade(vec4 frag) {\n    vec3 coord = frag.xyz / frag.w;\n\n    vec3 df = vec3(5.0 * u_depth_size_inv, 0.0);\n    vec2 uv = 0.5 * coord.xy + 0.5;\n    vec4 depth = vec4(\n        unpack_depth(texture2D(u_depth, uv - df.xz)),\n        unpack_depth(texture2D(u_depth, uv + df.xz)),\n        unpack_depth(texture2D(u_depth, uv - df.zy)),\n        unpack_depth(texture2D(u_depth, uv + df.zy))\n    );\n    return dot(vec4(0.25), vec4(1.0) - clamp(300.0 * (vec4(coord.z - 0.001) - depth), 0.0, 1.0));\n}\n\n // BEGIN: code for fill-extrusion height offseting\n // When making changes here please also update associated JS ports in src/style/style_layer/fill-extrusion-style-layer.js\n // This is so that rendering changes are reflected on CPU side for feature querying.\n\nvec4 fourSample(vec2 pos, vec2 off) {\n#ifdef TERRAIN_DEM_FLOAT_FORMAT\n    float tl = texture2D(u_dem, pos).a;\n    float tr = texture2D(u_dem, pos + vec2(off.x, 0.0)).a;\n    float bl = texture2D(u_dem, pos + vec2(0.0, off.y)).a;\n    float br = texture2D(u_dem, pos + off).a;\n#else\n    vec4 demtl = vec4(texture2D(u_dem, pos).xyz * 255.0, -1.0);\n    float tl = dot(demtl, u_dem_unpack);\n    vec4 demtr = vec4(texture2D(u_dem, pos + vec2(off.x, 0.0)).xyz * 255.0, -1.0);\n    float tr = dot(demtr, u_dem_unpack);\n    vec4 dembl = vec4(texture2D(u_dem, pos + vec2(0.0, off.y)).xyz * 255.0, -1.0);\n    float bl = dot(dembl, u_dem_unpack);\n    vec4 dembr = vec4(texture2D(u_dem, pos + off).xyz * 255.0, -1.0);\n    float br = dot(dembr, u_dem_unpack);\n#endif\n    return vec4(tl, tr, bl, br);\n}\n\nfloat flatElevation(vec2 pack) {\n    vec2 apos = floor(pack / 8.0);\n    vec2 span = 10.0 * (pack - apos * 8.0);\n\n    vec2 uvTex = (apos - vec2(1.0, 1.0)) / 8190.0;\n    float size = u_dem_size + 2.0;\n    float dd = 1.0 / size;\n\n    vec2 pos = u_dem_size * (uvTex * u_dem_scale + u_dem_tl) + 1.0;\n    vec2 f = fract(pos);\n    pos = (pos - f + 0.5) * dd;\n\n    // Get elevation of centroid.\n    vec4 h = fourSample(pos, vec2(dd));\n    float z = mix(mix(h.x, h.y, f.x), mix(h.z, h.w, f.x), f.y);\n\n    vec2 w = floor(0.5 * (span * u_meter_to_dem - 1.0));\n    vec2 d = dd * w;\n\n    // Get building wide sample, to get better slope estimate.\n    h = fourSample(pos - d, 2.0 * d + vec2(dd));\n\n    vec4 diff = abs(h.xzxy - h.ywzw);\n    vec2 slope = min(vec2(0.25), u_meter_to_dem * 0.5 * (diff.xz + diff.yw) / (2.0 * w + vec2(1.0)));\n    vec2 fix = slope * span;\n    float base = z + max(fix.x, fix.y);\n    return u_exaggeration * base;\n}\n\nfloat elevationFromUint16(float word) {\n    return u_exaggeration * (word / ELEVATION_SCALE - ELEVATION_OFFSET);\n}\n\n// END: code for fill-extrusion height offseting\n\n#else\n\nfloat elevation(vec2 pos) { return 0.0; }\nbool isOccluded(vec4 frag) { return false; }\nfloat occlusionFade(vec4 frag) { return 1.0; }\n\n#endif\n";

var preludeFogVert = "#ifdef FOG\n\nuniform mediump vec4 u_fog_color;\nuniform mediump vec2 u_fog_range;\nuniform mediump float u_fog_horizon_blend;\nuniform mediump mat4 u_fog_matrix;\nvarying vec3 v_fog_pos;\n\nfloat fog_range(float depth) {\n    // Map [near, far] to [0, 1] without clamping\n    return (depth - u_fog_range[0]) / (u_fog_range[1] - u_fog_range[0]);\n}\n\n// Assumes z up and camera_dir *normalized* (to avoid computing\n// its length multiple times for different functions).\nfloat fog_horizon_blending(vec3 camera_dir) {\n    float t = max(0.0, camera_dir.z / u_fog_horizon_blend);\n    // Factor of 3 chosen to roughly match smoothstep.\n    // See: https://www.desmos.com/calculator/pub31lvshf\n    return u_fog_color.a * exp(-3.0 * t * t);\n}\n\n// Compute a ramp for fog opacity\n//   - t: depth, rescaled to 0 at fogStart and 1 at fogEnd\n// See: https://www.desmos.com/calculator/3taufutxid\nfloat fog_opacity(float t) {\n    const float decay = 6.0;\n    float falloff = 1.0 - min(1.0, exp(-decay * t));\n\n    // Cube without pow() to smooth the onset\n    falloff *= falloff * falloff;\n\n    // Scale and clip to 1 at the far limit\n    return u_fog_color.a * min(1.0, 1.00747 * falloff);\n}\n\nvec3 fog_position(vec3 pos) {\n    // The following function requires that u_fog_matrix be affine and\n    // results in a vector with w = 1. Otherwise we must divide by w.\n    return (u_fog_matrix * vec4(pos, 1.0)).xyz;\n}\n\nvec3 fog_position(vec2 pos) {\n    return fog_position(vec3(pos, 0.0));\n}\n\nfloat fog(vec3 pos) {\n    float depth = length(pos);\n    float opacity = fog_opacity(fog_range(depth));\n    return opacity * fog_horizon_blending(pos / depth);\n}\n\n#endif\n";

var preludeFogFrag = "#ifdef FOG\n\nuniform mediump vec4 u_fog_color;\nuniform mediump vec2 u_fog_range;\nuniform mediump float u_fog_horizon_blend;\nuniform mediump float u_fog_temporal_offset;\nvarying vec3 v_fog_pos;\n\nuniform highp vec3 u_frustum_tl;\nuniform highp vec3 u_frustum_tr;\nuniform highp vec3 u_frustum_br;\nuniform highp vec3 u_frustum_bl;\nuniform highp vec3 u_globe_pos;\nuniform highp float u_globe_radius;\nuniform highp vec2 u_viewport;\nuniform float u_globe_transition;\nuniform int u_is_globe;\n\nfloat fog_range(float depth) {\n    // Map [near, far] to [0, 1] without clamping\n    return (depth - u_fog_range[0]) / (u_fog_range[1] - u_fog_range[0]);\n}\n\n// Assumes z up and camera_dir *normalized* (to avoid computing\n// its length multiple times for different functions).\nfloat fog_horizon_blending(vec3 camera_dir) {\n    float t = max(0.0, camera_dir.z / u_fog_horizon_blend);\n    // Factor of 3 chosen to roughly match smoothstep.\n    // See: https://www.desmos.com/calculator/pub31lvshf\n    return u_fog_color.a * exp(-3.0 * t * t);\n}\n\n// Compute a ramp for fog opacity\n//   - t: depth, rescaled to 0 at fogStart and 1 at fogEnd\n// See: https://www.desmos.com/calculator/3taufutxid\nfloat fog_opacity(float t) {\n    const float decay = 6.0;\n    float falloff = 1.0 - min(1.0, exp(-decay * t));\n\n    // Cube without pow() to smooth the onset\n    falloff *= falloff * falloff;\n\n    // Scale and clip to 1 at the far limit\n    return u_fog_color.a * min(1.0, 1.00747 * falloff);\n}\n\nfloat globe_glow_progress() {\n    highp vec2 uv = gl_FragCoord.xy / u_viewport;\n    highp vec3 ray_dir = mix(\n        mix(u_frustum_tl, u_frustum_tr, uv.x),\n        mix(u_frustum_bl, u_frustum_br, uv.x),\n        1.0 - uv.y);\n    highp vec3 dir = normalize(ray_dir);\n    highp vec3 closest_point = dot(u_globe_pos, dir) * dir;\n    highp float sdf = length(closest_point - u_globe_pos) / u_globe_radius;\n    return sdf + PI * 0.5;\n}\n\n// This function is only used in rare places like heatmap where opacity is used\n// directly, outside the normal fog_apply method.\nfloat fog_opacity(vec3 pos) {\n    float depth = length(pos);\n    return fog_opacity(fog_range(depth));\n}\n\nvec3 fog_apply(vec3 color, vec3 pos) {\n    float depth = length(pos);\n    float opacity;\n    if (u_is_globe == 1) {\n        float glow_progress = globe_glow_progress();\n        float t = mix(glow_progress, depth, u_globe_transition);\n        opacity = fog_opacity(fog_range(t));\n    } else {\n        opacity = fog_opacity(fog_range(depth));\n        opacity *= fog_horizon_blending(pos / depth);\n    }\n    return mix(color, u_fog_color.rgb, opacity);\n}\n\n// Apply fog computed in the vertex shader\nvec4 fog_apply_from_vert(vec4 color, float fog_opac) {\n    float alpha = EPSILON + color.a;\n    color.rgb = mix(color.rgb / alpha, u_fog_color.rgb, fog_opac) * alpha;\n    return color;\n}\n\n// Assumes z up\nvec3 fog_apply_sky_gradient(vec3 camera_ray, vec3 sky_color) {\n    float horizon_blend = fog_horizon_blending(normalize(camera_ray));\n    return mix(sky_color, u_fog_color.rgb, horizon_blend);\n}\n\n// Un-premultiply the alpha, then blend fog, then re-premultiply alpha.\n// For use with colors using premultiplied alpha\nvec4 fog_apply_premultiplied(vec4 color, vec3 pos) {\n    float alpha = EPSILON + color.a;\n    color.rgb = fog_apply(color.rgb / alpha, pos) * alpha;\n    return color;\n}\n\nvec3 fog_dither(vec3 color) {\n    vec2 dither_seed = gl_FragCoord.xy + u_fog_temporal_offset;\n    return dither(color, dither_seed);\n}\n\nvec4 fog_dither(vec4 color) {\n    return vec4(fog_dither(color.rgb), color.a);\n}\n\n#endif\n";

var skyboxCaptureFrag = "// [1] Precomputed Atmospheric Scattering: https://hal.inria.fr/inria-00288758/document\n// [2] Earth Fact Sheet https://nssdc.gsfc.nasa.gov/planetary/factsheet/earthfact.html\n// [3] Tonemapping Operators http://filmicworlds.com/blog/filmic-tonemapping-operators\n\nvarying highp vec3 v_position;\n\nuniform highp float u_sun_intensity;\nuniform highp float u_luminance;\nuniform lowp vec3 u_sun_direction;\nuniform highp vec4 u_color_tint_r;\nuniform highp vec4 u_color_tint_m;\n\n#ifdef GL_ES\nprecision highp float;\n#endif\n\n// [1] equation (1) section 2.1. for λ = (680, 550, 440) nm,\n// which corresponds to scattering coefficients at sea level\n#define BETA_R                  vec3(5.5e-6, 13.0e-6, 22.4e-6)\n// The following constants are from [1] Figure 6 and section 2.1\n#define BETA_M                  vec3(21e-6, 21e-6, 21e-6)\n#define MIE_G                   0.76\n#define DENSITY_HEIGHT_SCALE_R  8000.0 // m\n#define DENSITY_HEIGHT_SCALE_M  1200.0 // m\n// [1] and [2] section 2.1\n#define PLANET_RADIUS           6360e3 // m\n#define ATMOSPHERE_RADIUS       6420e3 // m\n#define SAMPLE_STEPS            10\n#define DENSITY_STEPS           4\n\nfloat ray_sphere_exit(vec3 orig, vec3 dir, float radius) {\n    float a = dot(dir, dir);\n    float b = 2.0 * dot(dir, orig);\n    float c = dot(orig, orig) - radius * radius;\n    float d = sqrt(b * b - 4.0 * a * c);\n    return (-b + d) / (2.0 * a);\n}\n\nvec3 extinction(vec2 density) {\n    return exp(-vec3(BETA_R * u_color_tint_r.a * density.x + BETA_M * u_color_tint_m.a * density.y));\n}\n\nvec2 local_density(vec3 point) {\n    float height = max(length(point) - PLANET_RADIUS, 0.0);\n    // Explicitly split in two shader statements, exp(vec2)\n    // did not behave correctly on specific arm mali arch.\n    float exp_r = exp(-height / DENSITY_HEIGHT_SCALE_R);\n    float exp_m = exp(-height / DENSITY_HEIGHT_SCALE_M);\n    return vec2(exp_r, exp_m);\n}\n\nfloat phase_ray(float cos_angle) {\n    return (3.0 / (16.0 * PI)) * (1.0 + cos_angle * cos_angle);\n}\n\nfloat phase_mie(float cos_angle) {\n    return (3.0 / (8.0 * PI)) * ((1.0 - MIE_G * MIE_G) * (1.0 + cos_angle * cos_angle)) /\n        ((2.0 + MIE_G * MIE_G) * pow(1.0 + MIE_G * MIE_G - 2.0 * MIE_G * cos_angle, 1.5));\n}\n\nvec2 density_to_atmosphere(vec3 point, vec3 light_dir) {\n    float ray_len = ray_sphere_exit(point, light_dir, ATMOSPHERE_RADIUS);\n    float step_len = ray_len / float(DENSITY_STEPS);\n\n    vec2 density_point_to_atmosphere = vec2(0.0);\n    for (int i = 0; i < DENSITY_STEPS; ++i) {\n        vec3 point_on_ray = point + light_dir * ((float(i) + 0.5) * step_len);\n        density_point_to_atmosphere += local_density(point_on_ray) * step_len;;\n    }\n\n    return density_point_to_atmosphere;\n}\n\nvec3 atmosphere(vec3 ray_dir, vec3 sun_direction, float sun_intensity) {\n    vec2 density_orig_to_point = vec2(0.0);\n    vec3 scatter_r = vec3(0.0);\n    vec3 scatter_m = vec3(0.0);\n    vec3 origin = vec3(0.0, PLANET_RADIUS, 0.0);\n\n    float ray_len = ray_sphere_exit(origin, ray_dir, ATMOSPHERE_RADIUS);\n    float step_len = ray_len / float(SAMPLE_STEPS);\n    for (int i = 0; i < SAMPLE_STEPS; ++i) {\n        vec3 point_on_ray = origin + ray_dir * ((float(i) + 0.5) * step_len);\n\n        // Local density\n        vec2 density = local_density(point_on_ray) * step_len;\n        density_orig_to_point += density;\n\n        // Density from point to atmosphere\n        vec2 density_point_to_atmosphere = density_to_atmosphere(point_on_ray, sun_direction);\n\n        // Scattering contribution\n        vec2 density_orig_to_atmosphere = density_orig_to_point + density_point_to_atmosphere;\n        vec3 extinction = extinction(density_orig_to_atmosphere);\n        scatter_r += density.x * extinction;\n        scatter_m += density.y * extinction;\n    }\n\n    // The mie and rayleigh phase functions describe how much light\n    // is scattered towards the eye when colliding with particles\n    float cos_angle = dot(ray_dir, sun_direction);\n    float phase_r = phase_ray(cos_angle);\n    float phase_m = phase_mie(cos_angle);\n\n    // Apply light color adjustments\n    vec3 beta_r = BETA_R * u_color_tint_r.rgb * u_color_tint_r.a;\n    vec3 beta_m = BETA_M * u_color_tint_m.rgb * u_color_tint_m.a;\n\n    return (scatter_r * phase_r * beta_r + scatter_m * phase_m * beta_m) * sun_intensity;\n}\n\nconst float A = 0.15;\nconst float B = 0.50;\nconst float C = 0.10;\nconst float D = 0.20;\nconst float E = 0.02;\nconst float F = 0.30;\n\nvec3 uncharted2_tonemap(vec3 x) {\n   return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F;\n}\n\nvoid main() {\n    vec3 ray_direction = v_position;\n\n    // Non-linear UV parameterization to increase horizon events\n    ray_direction.y = pow(ray_direction.y, 5.0);\n\n    // Add a small offset to prevent black bands around areas where\n    // the scattering algorithm does not manage to gather lighting\n    const float y_bias = 0.015;\n    ray_direction.y += y_bias;\n\n    vec3 color = atmosphere(normalize(ray_direction), u_sun_direction, u_sun_intensity);\n\n    // Apply exposure [3]\n    float white_scale = 1.0748724675633854; // 1.0 / uncharted2_tonemap(1000.0)\n    color = uncharted2_tonemap((log2(2.0 / pow(u_luminance, 4.0))) * color) * white_scale;\n\n    gl_FragColor = vec4(color, 1.0);\n}\n";

var skyboxCaptureVert = "attribute highp vec3 a_pos_3f;\n\nuniform mat3 u_matrix_3f;\n\nvarying highp vec3 v_position;\n\nfloat map(float value, float start, float end, float new_start, float new_end) {\n    return ((value - start) * (new_end - new_start)) / (end - start) + new_start;\n}\n\nvoid main() {\n    vec4 pos = vec4(u_matrix_3f * a_pos_3f, 1.0);\n\n    v_position = pos.xyz;\n    v_position.y *= -1.0;\n\n    // To make better utilization of the visible range (e.g. over the horizon, UVs\n    // from 0.0 to 1.0 on the Y-axis in cubemap space), the UV range is remapped from\n    // (-1.0,1.0) to (0.0,1.0) on y. The inverse operation is applied when sampling.\n    v_position.y = map(v_position.y, -1.0, 1.0, 0.0, 1.0);\n\n    gl_Position = vec4(a_pos_3f.xy, 0.0, 1.0);\n}\n";

var globeFrag = "uniform sampler2D u_image0;\nvarying vec2 v_pos0;\n\n#ifndef FOG\nuniform highp vec3 u_frustum_tl;\nuniform highp vec3 u_frustum_tr;\nuniform highp vec3 u_frustum_br;\nuniform highp vec3 u_frustum_bl;\nuniform highp vec3 u_globe_pos;\nuniform highp float u_globe_radius;\nuniform vec2 u_viewport;\n#endif\n\nvoid main() {\n    vec4 color;\n#ifdef CUSTOM_ANTIALIASING\n    vec2 uv = gl_FragCoord.xy / u_viewport;\n\n    highp vec3 ray_dir = mix(\n        mix(u_frustum_tl, u_frustum_tr, uv.x),\n        mix(u_frustum_bl, u_frustum_br, uv.x),\n        1.0 - uv.y);\n        \n    vec3 dir = normalize(ray_dir);\n\n    vec3 closest_point = dot(u_globe_pos, dir) * dir;\n    float norm_dist_from_center = 1.0 - length(closest_point - u_globe_pos) / u_globe_radius;\n\n    const float antialias_pixel = 2.0;\n    float antialias_factor = antialias_pixel * fwidth(norm_dist_from_center);\n    float antialias = smoothstep(0.0, antialias_factor, norm_dist_from_center);\n\n    vec4 raster = texture2D(u_image0, v_pos0);\n    color = vec4(raster.rgb * antialias, raster.a * antialias);\n#else\n    color = texture2D(u_image0, v_pos0);\n#endif\n#ifdef FOG\n    color = fog_dither(fog_apply_premultiplied(color, v_fog_pos));\n#endif\n    gl_FragColor = color;\n#ifdef TERRAIN_WIREFRAME\n    gl_FragColor = vec4(1.0, 0.0, 0.0, 0.8);\n#endif\n#ifdef OVERDRAW_INSPECTOR\n    gl_FragColor = vec4(1.0);\n#endif\n}\n";

var globeVert = "uniform mat4 u_proj_matrix;\nuniform mat4 u_normalize_matrix;\nuniform mat4 u_globe_matrix;\nuniform mat4 u_merc_matrix;\nuniform float u_zoom_transition;\nuniform vec2 u_merc_center;\nuniform mat3 u_grid_matrix;\nuniform float u_skirt_height;\n\n#ifdef GLOBE_POLES\nattribute vec3 a_globe_pos;\nattribute vec2 a_uv;\n#else\nattribute vec2 a_pos; // .xy - grid coords, .z - 1 - skirt, 0 - grid\n#endif\n\nvarying vec2 v_pos0;\n\nconst float wireframeOffset = 1e3;\n\nfloat mercatorXfromLng(float lng) {\n    return (180.0 + lng) / 360.0;\n}\n\nfloat mercatorYfromLat(float lat) {\n    return (180.0 - (RAD_TO_DEG* log(tan(QUARTER_PI + lat / 2.0 * DEG_TO_RAD)))) / 360.0;\n}\n\nvec3 latLngToECEF(vec2 latLng) {\n    latLng = DEG_TO_RAD * latLng;\n    \n    float cosLat = cos(latLng[0]);\n    float sinLat = sin(latLng[0]);\n    float cosLng = cos(latLng[1]);\n    float sinLng = sin(latLng[1]);\n\n    // Convert lat & lng to spherical representation. Use zoom=0 as a reference\n    float sx = cosLat * sinLng * GLOBE_RADIUS;\n    float sy = -sinLat * GLOBE_RADIUS;\n    float sz = cosLat * cosLng * GLOBE_RADIUS;\n\n    return vec3(sx, sy, sz);\n}\n\nvoid main() {\n#ifdef GLOBE_POLES\n    vec3 globe_pos = a_globe_pos;\n    vec2 uv = a_uv;\n#else\n    // The 3rd row of u_grid_matrix is only used as a spare space to \n    // pass the following 3 uniforms to avoid explicitly introducing new ones.\n    float tiles = u_grid_matrix[0][2];\n    float idx = u_grid_matrix[1][2];\n    float idy = u_grid_matrix[2][2];\n\n    vec3 decomposed_pos_and_skirt = decomposeToPosAndSkirt(a_pos);\n\n    vec3 latLng = u_grid_matrix * vec3(decomposed_pos_and_skirt.xy, 1.0);\n\n    float mercatorY = mercatorYfromLat(latLng[0]);\n    float uvY = mercatorY * tiles - idy;\n    \n    float mercatorX = mercatorXfromLng(latLng[1]);\n    float uvX = mercatorX * tiles - idx;\n\n    vec3 globe_pos = latLngToECEF(latLng.xy);\n    vec2 merc_pos = vec2(mercatorX, mercatorY);\n    vec2 uv = vec2(uvX, uvY);\n#endif\n\n    v_pos0 = uv;\n    vec2 tile_pos = uv * EXTENT;\n\n    // Used for poles and skirts\n    vec3 globe_derived_up_vector = normalize(globe_pos) * u_tile_up_scale;\n#ifdef GLOBE_POLES\n    // Normal vector can be derived from the ecef position\n    // as \"elevationVector\" can't be queried outside of the tile\n    vec3 up_vector = globe_derived_up_vector;\n#else\n    vec3 up_vector = elevationVector(tile_pos);\n#endif\n\n    float height = elevation(tile_pos);\n\n#ifdef TERRAIN_WIREFRAME\n    height += wireframeOffset;\n#endif\n\n    globe_pos += up_vector * height;\n\n#ifndef GLOBE_POLES\n    // Apply skirts for grid and only by offsetting via globe_pos derived normal\n    globe_pos -= globe_derived_up_vector * u_skirt_height * decomposed_pos_and_skirt.z;\n#endif\n\n#ifdef GLOBE_POLES\n    vec4 interpolated_pos = u_globe_matrix * vec4(globe_pos, 1.0);\n#else\n    vec4 globe_world_pos = u_globe_matrix * vec4(globe_pos, 1.0);\n    vec4 merc_world_pos = vec4(0.0);\n    if (u_zoom_transition > 0.0) {\n        merc_world_pos = vec4(merc_pos, height - u_skirt_height * decomposed_pos_and_skirt.z, 1.0);\n        merc_world_pos.xy -= u_merc_center;\n        merc_world_pos.x = wrap(merc_world_pos.x, -0.5, 0.5);\n        merc_world_pos = u_merc_matrix * merc_world_pos;\n    }\n\n    vec4 interpolated_pos = vec4(mix(globe_world_pos.xyz, merc_world_pos.xyz, u_zoom_transition), 1.0);\n#endif\n\n    gl_Position = u_proj_matrix * interpolated_pos;\n\n#ifdef FOG\n    v_fog_pos = fog_position((u_normalize_matrix * vec4(globe_pos, 1.0)).xyz);\n#endif\n}\n";

var atmosphereFrag = "uniform float u_transition;\nuniform highp float u_fadeout_range;\nuniform highp float u_temporal_offset;\nuniform vec3 u_start_color;\nuniform vec4 u_color;\nuniform vec4 u_space_color;\nuniform vec4 u_high_color;\nuniform float u_star_intensity;\nuniform float u_star_size;\nuniform float u_star_density;\nuniform float u_horizon_angle;\nuniform mat4 u_rotation_matrix;\n\nvarying highp vec3 v_ray_dir;\nvarying highp vec3 v_horizon_dir;\n\nhighp float random(highp vec3 p) {\n    p = fract(p * vec3(23.2342, 97.1231, 91.2342));\n    p += dot(p.zxy, p.yxz + 123.1234);\n    return fract(p.x * p.y);\n}\n\nfloat stars(vec3 p, float scale, vec2 offset) {\n    vec2 uv_scale = (u_viewport / u_star_size) * scale;\n    vec3 position = vec3(p.xy * uv_scale + offset * u_viewport, p.z);\n\n    vec3 q = fract(position) - 0.5;\n    vec3 id = floor(position);\n\n    float random_visibility = step(random(id), u_star_density);\n    float circle = smoothstep(0.5 + u_star_intensity, 0.5, length(q));\n\n    return circle * random_visibility;\n}\n\nvoid main() {\n    highp vec3 dir = normalize(v_ray_dir);\n\n    float globe_pos_dot_dir;\n#ifdef PROJECTION_GLOBE_VIEW\n    globe_pos_dot_dir = dot(u_globe_pos, dir);\n    highp vec3 closest_point_forward = abs(globe_pos_dot_dir) * dir;\n    float norm_dist_from_center = length(closest_point_forward - u_globe_pos) / u_globe_radius;\n\n    // Compare against 0.98 instead of 1.0 to give enough room for the custom\n    // antialiasing that might be applied from globe_raster.fragment.glsl\n    if (norm_dist_from_center < 0.98) {\n        discard;\n        return;\n    }\n#endif\n\n    highp vec3 horizon_dir = normalize(v_horizon_dir);\n    float horizon_angle_mercator = dir.y < horizon_dir.y ?\n        0.0 : max(acos(dot(dir, horizon_dir)), 0.0);\n\n    float horizon_angle;\n#ifdef PROJECTION_GLOBE_VIEW\n    // Angle between dir and globe center\n    highp vec3 closest_point = globe_pos_dot_dir * dir;\n    float closest_point_to_center = length(closest_point - u_globe_pos);\n    float theta = asin(clamp(closest_point_to_center / length(u_globe_pos), -1.0, 1.0));\n\n    // Backward facing closest point rays should be treated separately\n    horizon_angle = globe_pos_dot_dir < 0.0 ?\n        PI - theta - u_horizon_angle : theta - u_horizon_angle;\n\n    // Increase speed of change of the angle interpolation for\n    // a smoother visual transition between horizon angle mixing\n    float angle_t = pow(u_transition, 10.0);\n\n    horizon_angle = mix(horizon_angle, horizon_angle_mercator, angle_t);\n#else\n    horizon_angle = horizon_angle_mercator;\n#endif\n\n    // Normalize in [0, 1]\n    horizon_angle /= PI;\n\n    // exponential curve\n    // [0.0, 1.0] == inside the globe, > 1.0 == outside of the globe\n    // https://www.desmos.com/calculator/l5v8lw9zby\n    float t = exp(-horizon_angle / u_fadeout_range);\n\n    float alpha_0 = u_color.a;\n    float alpha_1 = u_high_color.a;\n    float alpha_2 = u_space_color.a;\n\n    vec3 color_stop_0 = u_color.rgb;\n    vec3 color_stop_1 = u_high_color.rgb;\n    vec3 color_stop_2 = u_space_color.rgb;\n\n    vec3 c0 = mix(color_stop_2, color_stop_1, alpha_1);\n    vec3 c1 = mix(c0, color_stop_0, alpha_0);\n    vec3 c2 = mix(c0, c1, t);\n    vec3 c  = mix(color_stop_2, c2, t);\n\n    // Blend alphas\n    float a0 = mix(alpha_2, 1.0, alpha_1);\n    float a1 = mix(a0, 1.0, alpha_0);\n    float a2 = mix(a0, a1, t);\n    float a  = mix(alpha_2, a2, t);\n\n    vec2 uv = gl_FragCoord.xy / u_viewport - 0.5;\n    float aspect_ratio = u_viewport.x / u_viewport.y;\n\n    vec4 uv_dir = vec4(normalize(vec3(uv.x * aspect_ratio, uv.y, 1.0)), 1.0);\n\n    uv_dir = u_rotation_matrix * uv_dir;\n\n    vec3 n = abs(uv_dir.xyz);\n    vec2 uv_remap = (n.x > n.y && n.x > n.z) ? uv_dir.yz / uv_dir.x:\n                    (n.y > n.x && n.y > n.z) ? uv_dir.zx / uv_dir.y:\n                                               uv_dir.xy / uv_dir.z;\n\n    uv_remap.x /= aspect_ratio;\n\n    vec3 D = vec3(uv_remap, 1.0);\n\n    // Accumulate star field\n    highp float star_field = 0.0;\n\n    if (u_star_intensity > 0.0) {\n        // Create stars of various scales and offset to improve randomness\n        star_field += stars(D, 1.2, vec2(0.0, 0.0));\n        star_field += stars(D, 1.0, vec2(1.0, 0.0));\n        star_field += stars(D, 0.8, vec2(0.0, 1.0));\n        star_field += stars(D, 0.6, vec2(1.0, 1.0));\n\n        // Fade stars as they get closer to horizon to\n        // give the feeling of an atmosphere with thickness\n        star_field *= (1.0 - pow(t, 0.25 + (1.0 - u_high_color.a) * 0.75));\n\n        // Additive star field\n        c += star_field * alpha_2;\n    }\n\n    // Dither\n    c = dither(c, gl_FragCoord.xy + u_temporal_offset);\n\n\n    gl_FragColor = vec4(c, a);\n}\n";

var atmosphereVert = "attribute vec3 a_pos;\nattribute vec2 a_uv;\n\n// View frustum direction vectors pointing from the camera position to of each the corner points\nuniform vec3 u_frustum_tl;\nuniform vec3 u_frustum_tr;\nuniform vec3 u_frustum_br;\nuniform vec3 u_frustum_bl;\nuniform float u_horizon;\n\nvarying highp vec3 v_ray_dir;\nvarying highp vec3 v_horizon_dir;\n\nvoid main() {\n    v_ray_dir = mix(\n        mix(u_frustum_tl, u_frustum_tr, a_uv.x),\n        mix(u_frustum_bl, u_frustum_br, a_uv.x),\n        a_uv.y);\n\n    v_horizon_dir = mix(\n        mix(u_frustum_tl, u_frustum_bl, u_horizon),\n        mix(u_frustum_tr, u_frustum_br, u_horizon),\n        a_uv.x);\n\n    gl_Position = vec4(a_pos, 1.0);\n}\n";

let preludeTerrain = {};
let preludeFog = {};

const commonDefines = [];
parseUsedPreprocessorDefines(preludeCommon, commonDefines);
parseUsedPreprocessorDefines(preludeTerrainVert, commonDefines);
parseUsedPreprocessorDefines(preludeFogVert, commonDefines);
parseUsedPreprocessorDefines(preludeFogFrag, commonDefines);

preludeTerrain = compile('', preludeTerrainVert);
preludeFog = compile(preludeFogFrag, preludeFogVert);
// Shadow prelude is not compiled until GL-JS implements shadows

const prelude = compile(preludeFrag, preludeVert);
const preludeCommonSource = preludeCommon;

const preludeVertPrecisionQualifiers = `
#ifdef GL_ES
precision highp float;
#else

#if !defined(lowp)
#define lowp
#endif

#if !defined(mediump)
#define mediump
#endif

#if !defined(highp)
#define highp
#endif

#endif`;
const preludeFragPrecisionQualifiers = `
#ifdef GL_ES
precision mediump float;
#else

#if !defined(lowp)
#define lowp
#endif

#if !defined(mediump)
#define mediump
#endif

#if !defined(highp)
#define highp
#endif

#endif`;

const standardDerivativesExt = '#extension GL_OES_standard_derivatives : enable\n';

var shaders = {
    background: compile(backgroundFrag, backgroundVert),
    backgroundPattern: compile(backgroundPatternFrag, backgroundPatternVert),
    circle: compile(circleFrag, circleVert),
    clippingMask: compile(clippingMaskFrag, clippingMaskVert),
    heatmap: compile(heatmapFrag, heatmapVert),
    heatmapTexture: compile(heatmapTextureFrag, heatmapTextureVert),
    collisionBox: compile(collisionBoxFrag, collisionBoxVert),
    collisionCircle: compile(collisionCircleFrag, collisionCircleVert),
    debug: compile(debugFrag, debugVert),
    fill: compile(fillFrag, fillVert),
    fillOutline: compile(fillOutlineFrag, fillOutlineVert),
    fillOutlinePattern: compile(fillOutlinePatternFrag, fillOutlinePatternVert),
    fillPattern: compile(fillPatternFrag, fillPatternVert),
    fillExtrusion: compile(fillExtrusionFrag, fillExtrusionVert),
    fillExtrusionPattern: compile(fillExtrusionPatternFrag, fillExtrusionPatternVert),
    hillshadePrepare: compile(hillshadePrepareFrag, hillshadePrepareVert),
    hillshade: compile(hillshadeFrag, hillshadeVert),
    line: compile(lineFrag, lineVert),
    linePattern: compile(linePatternFrag, linePatternVert),
    raster: compile(rasterFrag, rasterVert),
    symbolIcon: compile(symbolIconFrag, symbolIconVert),
    symbolSDF: compile(symbolSDFFrag, symbolSDFVert),
    symbolTextAndIcon: compile(symbolTextAndIconFrag, symbolTextAndIconVert),
    terrainRaster: compile(terrainRasterFrag, terrainRasterVert),
    terrainDepth: compile(terrainDepthFrag, terrainDepthVert),
    skybox: compile(skyboxFrag, skyboxVert),
    skyboxGradient: compile(skyboxGradientFrag, skyboxVert),
    skyboxCapture: compile(skyboxCaptureFrag, skyboxCaptureVert),
    globeRaster: compile(globeFrag, globeVert),
    globeAtmosphere: compile(atmosphereFrag, atmosphereVert)
};

function parseUsedPreprocessorDefines(source, defines) {
    const lines = source.replace(/\s*\/\/[^\n]*\n/g, '\n').split('\n');
    for (let line of lines) {
        line = line.trim();
        if (line[0] === '#') {
            if (line.includes('if') && !line.includes('endif')) {
                line = line.replace('#', '')
                    .replace(/ifdef|ifndef|elif|if/g, '')
                    .replace(/!|defined|\(|\)|\|\||&&/g, '')
                    .replace(/\s+/g, ' ').trim();

                const newDefines = line.split(' ');
                for (const define of newDefines) {
                    if (!defines.includes(define)) {
                        defines.push(define);
                    }
                }
            }
        }
    }
}

// Expand #pragmas to #ifdefs.
function compile(fragmentSource, vertexSource) {
    const pragmaRegex = /#pragma mapbox: ([\w]+) ([\w]+) ([\w]+) ([\w]+)/g;
    const attributeRegex = /attribute (highp |mediump |lowp )?([\w]+) ([\w]+)/g;

    const staticAttributes = vertexSource.match(attributeRegex);
    const fragmentPragmas = {};

    const usedDefines = [...commonDefines];
    parseUsedPreprocessorDefines(fragmentSource, usedDefines);
    parseUsedPreprocessorDefines(vertexSource, usedDefines);

    fragmentSource = fragmentSource.replace(pragmaRegex, (match, operation, precision, type, name) => {
        fragmentPragmas[name] = true;
        if (operation === 'define') {
            return `
#ifndef HAS_UNIFORM_u_${name}
varying ${precision} ${type} ${name};
#else
uniform ${precision} ${type} u_${name};
#endif
`;
        } else /* if (operation === 'initialize') */ {
            return `
#ifdef HAS_UNIFORM_u_${name}
    ${precision} ${type} ${name} = u_${name};
#endif
`;
        }
    });

    vertexSource = vertexSource.replace(pragmaRegex, (match, operation, precision, type, name) => {
        const attrType = type === 'float' ? 'vec2' : 'vec4';
        const unpackType = name.match(/color/) ? 'color' : attrType;

        if (fragmentPragmas[name]) {
            if (operation === 'define') {
                return `
#ifndef HAS_UNIFORM_u_${name}
uniform lowp float u_${name}_t;
attribute ${precision} ${attrType} a_${name};
varying ${precision} ${type} ${name};
#else
uniform ${precision} ${type} u_${name};
#endif
`;
            } else /* if (operation === 'initialize') */ {
                if (unpackType === 'vec4') {
                    // vec4 attributes are only used for cross-faded properties, and are not packed
                    return `
#ifndef HAS_UNIFORM_u_${name}
    ${name} = a_${name};
#else
    ${precision} ${type} ${name} = u_${name};
#endif
`;
                } else {
                    return `
#ifndef HAS_UNIFORM_u_${name}
    ${name} = unpack_mix_${unpackType}(a_${name}, u_${name}_t);
#else
    ${precision} ${type} ${name} = u_${name};
#endif
`;
                }
            }
        } else {
            if (operation === 'define') {
                return `
#ifndef HAS_UNIFORM_u_${name}
uniform lowp float u_${name}_t;
attribute ${precision} ${attrType} a_${name};
#else
uniform ${precision} ${type} u_${name};
#endif
`;
            } else /* if (operation === 'initialize') */ {
                if (unpackType === 'vec4') {
                    // vec4 attributes are only used for cross-faded properties, and are not packed
                    return `
#ifndef HAS_UNIFORM_u_${name}
    ${precision} ${type} ${name} = a_${name};
#else
    ${precision} ${type} ${name} = u_${name};
#endif
`;
                } else /* */{
                    return `
#ifndef HAS_UNIFORM_u_${name}
    ${precision} ${type} ${name} = unpack_mix_${unpackType}(a_${name}, u_${name}_t);
#else
    ${precision} ${type} ${name} = u_${name};
#endif
`;
                }
            }
        }
    });

    return {fragmentSource, vertexSource, staticAttributes, usedDefines};
}

//      


                                        
                                                       
                                                     
                                            

class VertexArrayObject {
                     
                              
                                           
                                                 
                                   
                               
                                                    
             

    constructor() {
        this.boundProgram = null;
        this.boundLayoutVertexBuffer = null;
        this.boundPaintVertexBuffers = [];
        this.boundIndexBuffer = null;
        this.boundVertexOffset = null;
        this.boundDynamicVertexBuffers = [];
        this.vao = null;
    }

    bind(context         ,
         program            ,
         layoutVertexBuffer              ,
         paintVertexBuffers                     ,
         indexBuffer              ,
         vertexOffset         ,
         dynamicVertexBuffers                      ) {

        this.context = context;

        let paintBuffersDiffer = this.boundPaintVertexBuffers.length !== paintVertexBuffers.length;
        for (let i = 0; !paintBuffersDiffer && i < paintVertexBuffers.length; i++) {
            if (this.boundPaintVertexBuffers[i] !== paintVertexBuffers[i]) {
                paintBuffersDiffer = true;
            }
        }
        let dynamicBuffersDiffer = this.boundDynamicVertexBuffers.length !== dynamicVertexBuffers.length;
        for (let i = 0; !dynamicBuffersDiffer && i < dynamicVertexBuffers.length; i++) {
            if (this.boundDynamicVertexBuffers[i] !== dynamicVertexBuffers[i]) {
                dynamicBuffersDiffer = true;
            }
        }

        const isFreshBindRequired = (
            !this.vao ||
            this.boundProgram !== program ||
            this.boundLayoutVertexBuffer !== layoutVertexBuffer ||
            paintBuffersDiffer ||
            dynamicBuffersDiffer ||
            this.boundIndexBuffer !== indexBuffer ||
            this.boundVertexOffset !== vertexOffset
        );

        if (!context.extVertexArrayObject || isFreshBindRequired) {
            this.freshBind(program, layoutVertexBuffer, paintVertexBuffers, indexBuffer, vertexOffset, dynamicVertexBuffers);
        } else {
            context.bindVertexArrayOES.set(this.vao);
            for (const dynamicBuffer of dynamicVertexBuffers) {
                if (dynamicBuffer) {
                    dynamicBuffer.bind();
                }
            }
            if (indexBuffer && indexBuffer.dynamicDraw) {
                indexBuffer.bind();
            }
        }
    }

    freshBind(program            ,
              layoutVertexBuffer              ,
              paintVertexBuffers                     ,
              indexBuffer              ,
              vertexOffset         ,
              dynamicVertexBuffers                      ) {
        let numPrevAttributes;
        const numNextAttributes = program.numAttributes;

        const context = this.context;
        const gl = context.gl;

        if (context.extVertexArrayObject) {
            if (this.vao) this.destroy();
            this.vao = context.extVertexArrayObject.createVertexArrayOES();
            context.bindVertexArrayOES.set(this.vao);
            numPrevAttributes = 0;

            // store the arguments so that we can verify them when the vao is bound again
            this.boundProgram = program;
            this.boundLayoutVertexBuffer = layoutVertexBuffer;
            this.boundPaintVertexBuffers = paintVertexBuffers;
            this.boundIndexBuffer = indexBuffer;
            this.boundVertexOffset = vertexOffset;
            this.boundDynamicVertexBuffers = dynamicVertexBuffers;

        } else {
            numPrevAttributes = context.currentNumAttributes || 0;

            // Disable all attributes from the previous program that aren't used in
            // the new program. Note: attribute indices are *not* program specific!
            for (let i = numNextAttributes; i < numPrevAttributes; i++) {
                // WebGL breaks if you disable attribute 0.
                // http://stackoverflow.com/questions/20305231
                index.assert(i !== 0);
                gl.disableVertexAttribArray(i);
            }
        }

        layoutVertexBuffer.enableAttributes(gl, program);
        layoutVertexBuffer.bind();
        layoutVertexBuffer.setVertexAttribPointers(gl, program, vertexOffset);

        for (const vertexBuffer of paintVertexBuffers) {
            vertexBuffer.enableAttributes(gl, program);
            vertexBuffer.bind();
            vertexBuffer.setVertexAttribPointers(gl, program, vertexOffset);
        }

        for (const dynamicBuffer of dynamicVertexBuffers) {
            if (dynamicBuffer) {
                dynamicBuffer.enableAttributes(gl, program);
                dynamicBuffer.bind();
                dynamicBuffer.setVertexAttribPointers(gl, program, vertexOffset);
            }
        }

        if (indexBuffer) {
            indexBuffer.bind();
        }

        context.currentNumAttributes = numNextAttributes;
    }

    destroy() {
        if (this.vao) {
            this.context.extVertexArrayObject.deleteVertexArrayOES(this.vao);
            this.vao = null;
        }
    }
}

//      


                                               
                                                         
                                             
                                         
                                                                                        
                                                  
                                                              

                                      
                                
                         
                            
                         
                             
                                
                            
   

                                             
                                
                         
                             
                        
                         
   

const hillshadeUniforms = (context         )                        => ({
    'u_matrix': new index.UniformMatrix4f(context),
    'u_image': new index.Uniform1i(context),
    'u_latrange': new index.Uniform2f(context),
    'u_light': new index.Uniform2f(context),
    'u_shadow': new index.UniformColor(context),
    'u_highlight': new index.UniformColor(context),
    'u_accent': new index.UniformColor(context)
});

const hillshadePrepareUniforms = (context         )                               => ({
    'u_matrix': new index.UniformMatrix4f(context),
    'u_image': new index.Uniform1i(context),
    'u_dimension': new index.Uniform2f(context),
    'u_zoom': new index.Uniform1f(context),
    'u_unpack': new index.Uniform4f(context)
});

const hillshadeUniformValues = (
    painter         ,
    tile      ,
    layer                     ,
    matrix               
)                                       => {
    const shadow = layer.paint.get("hillshade-shadow-color");
    const highlight = layer.paint.get("hillshade-highlight-color");
    const accent = layer.paint.get("hillshade-accent-color");

    let azimuthal = layer.paint.get('hillshade-illumination-direction') * (Math.PI / 180);
    // modify azimuthal angle by map rotation if light is anchored at the viewport
    if (layer.paint.get('hillshade-illumination-anchor') === 'viewport') {
        azimuthal -= painter.transform.angle;
    }
    const align = !painter.options.moving;
    return {
        'u_matrix': matrix ? matrix : painter.transform.calculateProjMatrix(tile.tileID.toUnwrapped(), align),
        'u_image': 0,
        'u_latrange': getTileLatRange(painter, tile.tileID),
        'u_light': [layer.paint.get('hillshade-exaggeration'), azimuthal],
        'u_shadow': shadow,
        'u_highlight': highlight,
        'u_accent': accent
    };
};

const hillshadeUniformPrepareValues = (
    tileID                  , dem         
)                                              => {

    const stride = dem.stride;
    const matrix = index.create();
    // Flip rendering at y axis.
    index.ortho(matrix, 0, index.EXTENT, -index.EXTENT, 0, 0, 1);
    index.translate(matrix, matrix, [0, -index.EXTENT, 0]);

    return {
        'u_matrix': matrix,
        'u_image': 1,
        'u_dimension': [stride, stride],
        'u_zoom': tileID.overscaledZ,
        'u_unpack': dem.unpackVector
    };
};

function getTileLatRange(painter         , tileID                  ) {
    // for scaling the magnitude of a points slope by its latitude
    const tilesAtZoom = Math.pow(2, tileID.canonical.z);
    const y = tileID.canonical.y;
    return [
        new index.MercatorCoordinate(0, y / tilesAtZoom).toLngLat().lat,
        new index.MercatorCoordinate(0, (y + 1) / tilesAtZoom).toLngLat().lat];
}

//      


function drawHillshade(painter         , sourceCache             , layer                     , tileIDs                         ) {
    if (painter.renderPass !== 'offscreen' && painter.renderPass !== 'translucent') return;

    const context = painter.context;

    const depthMode = painter.depthModeForSublayer(0, index.DepthMode.ReadOnly);
    const colorMode = painter.colorModeForRenderPass();

    // When rendering to texture, coordinates are already sorted: primary by
    // proxy id and secondary sort is by Z.
    const renderingToTexture = painter.terrain && painter.terrain.renderingToTexture;
    const [stencilModes, coords] = painter.renderPass === 'translucent' && !renderingToTexture ?
        painter.stencilConfigForOverlap(tileIDs) : [{}, tileIDs];

    for (const coord of coords) {
        const tile = sourceCache.getTile(coord);
        if (tile.needsHillshadePrepare && painter.renderPass === 'offscreen') {
            prepareHillshade(painter, tile, layer, depthMode, index.StencilMode.disabled, colorMode);
        } else if (painter.renderPass === 'translucent') {
            const stencilMode = renderingToTexture && painter.terrain ?
                painter.terrain.stencilModeForRTTOverlap(coord) : stencilModes[coord.overscaledZ];
            renderHillshade(painter, coord, tile, layer, depthMode, stencilMode, colorMode);
        }
    }

    context.viewport.set([0, 0, painter.width, painter.height]);

    painter.resetStencilClippingMasks();
}

function renderHillshade(painter         , coord                  , tile      , layer                     , depthMode           , stencilMode             , colorMode           ) {
    const context = painter.context;
    const gl = context.gl;
    const fbo = tile.fbo;
    if (!fbo) return;
    painter.prepareDrawTile();

    const program = painter.useProgram('hillshade');

    context.activeTexture.set(gl.TEXTURE0);
    gl.bindTexture(gl.TEXTURE_2D, fbo.colorAttachment.get());

    const uniformValues = hillshadeUniformValues(painter, tile, layer, painter.terrain ? coord.projMatrix : null);

    painter.prepareDrawProgram(context, program, coord.toUnwrapped());

    const {tileBoundsBuffer, tileBoundsIndexBuffer, tileBoundsSegments} = painter.getTileBoundsBuffers(tile);

    program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, index.CullFaceMode.disabled,
        uniformValues, layer.id, tileBoundsBuffer,
        tileBoundsIndexBuffer, tileBoundsSegments);
}

function prepareDEMTexture(painter         , tile      , dem         ) {
    if (!tile.needsDEMTextureUpload) return;

    const context = painter.context;
    const gl = context.gl;

    context.pixelStoreUnpackPremultiplyAlpha.set(false);
    const textureStride = dem.stride;
    tile.demTexture = tile.demTexture || painter.getTileTexture(textureStride);
    const pixelData = dem.getPixels();
    if (tile.demTexture) {
        tile.demTexture.update(pixelData, {premultiply: false});
    } else {
        tile.demTexture = new index.Texture(context, pixelData, gl.RGBA, {premultiply: false});
    }
    tile.needsDEMTextureUpload = false;
}

// hillshade rendering is done in two steps. the prepare step first calculates the slope of the terrain in the x and y
// directions for each pixel, and saves those values to a framebuffer texture in the r and g channels.
function prepareHillshade(painter         , tile      , layer                     , depthMode           , stencilMode             , colorMode           ) {
    const context = painter.context;
    const gl = context.gl;
    if (!tile.dem) return;
    const dem          = tile.dem;

    context.activeTexture.set(gl.TEXTURE1);
    prepareDEMTexture(painter, tile, dem);
    index.assert(tile.demTexture);
    if (!tile.demTexture) return; // Silence flow.
    tile.demTexture.bind(gl.NEAREST, gl.CLAMP_TO_EDGE);
    const tileSize = dem.dim;

    context.activeTexture.set(gl.TEXTURE0);
    let fbo = tile.fbo;
    if (!fbo) {
        const renderTexture = new index.Texture(context, {width: tileSize, height: tileSize, data: null}, gl.RGBA);
        renderTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);

        fbo = tile.fbo = context.createFramebuffer(tileSize, tileSize, true);
        fbo.colorAttachment.set(renderTexture.texture);
    }

    context.bindFramebuffer.set(fbo.framebuffer);
    context.viewport.set([0, 0, tileSize, tileSize]);

    const {tileBoundsBuffer, tileBoundsIndexBuffer, tileBoundsSegments} = painter.getMercatorTileBoundsBuffers();

    painter.useProgram('hillshadePrepare').draw(context, gl.TRIANGLES,
        depthMode, stencilMode, colorMode, index.CullFaceMode.disabled,
        hillshadeUniformPrepareValues(tile.tileID, dem),
        layer.id, tileBoundsBuffer,
        tileBoundsIndexBuffer, tileBoundsSegments);

    tile.needsHillshadePrepare = false;
}

//      


                                            
                                                                

                                          
                                
                          
                               
   

const terrainRasterUniforms = (context         )                            => ({
    'u_matrix': new index.UniformMatrix4f(context),
    'u_image0': new index.Uniform1i(context),
    'u_skirt_height': new index.Uniform1f(context)
});

const terrainRasterUniformValues = (
    matrix              ,
    skirtHeight        
)                                           => ({
    'u_matrix': matrix,
    'u_image0': 0,
    'u_skirt_height': skirtHeight
});

//      


                                            
                                                                
                                    

                                        
                                     
                                      
                                          
                                     
                                   
                               
                          
                                     
                                
                              
                              
                              
                              
                             
                                
                           
   

                                       
                              
                              
                              
                              
                           
                              
                                 
                         
                              
                               
                                  
                             
                                
                                   
                                 
                                        
   

const globeRasterUniforms = (context         )                          => ({
    'u_proj_matrix': new index.UniformMatrix4f(context),
    'u_globe_matrix': new index.UniformMatrix4f(context),
    'u_normalize_matrix': new index.UniformMatrix4f(context),
    'u_merc_matrix': new index.UniformMatrix4f(context),
    'u_zoom_transition': new index.Uniform1f(context),
    'u_merc_center': new index.Uniform2f(context),
    'u_image0': new index.Uniform1i(context),
    'u_grid_matrix': new index.UniformMatrix3f(context),
    'u_skirt_height': new index.Uniform1f(context),
    'u_frustum_tl': new index.Uniform3f(context),
    'u_frustum_tr': new index.Uniform3f(context),
    'u_frustum_br': new index.Uniform3f(context),
    'u_frustum_bl': new index.Uniform3f(context),
    'u_globe_pos': new index.Uniform3f(context),
    'u_globe_radius': new index.Uniform1f(context),
    'u_viewport': new index.Uniform2f(context)
});

const atmosphereUniforms = (context         )                         => ({
    'u_frustum_tl': new index.Uniform3f(context),
    'u_frustum_tr': new index.Uniform3f(context),
    'u_frustum_br': new index.Uniform3f(context),
    'u_frustum_bl': new index.Uniform3f(context),
    'u_horizon': new index.Uniform1f(context),
    'u_transition': new index.Uniform1f(context),
    'u_fadeout_range': new index.Uniform1f(context),
    'u_color': new index.Uniform4f(context),
    'u_high_color': new index.Uniform4f(context),
    'u_space_color': new index.Uniform4f(context),
    'u_star_intensity': new index.Uniform1f(context),
    'u_star_density': new index.Uniform1f(context),
    'u_star_size': new index.Uniform1f(context),
    'u_temporal_offset': new index.Uniform1f(context),
    'u_horizon_angle': new index.Uniform1f(context),
    'u_rotation_matrix': new index.UniformMatrix4f(context)
});

const globeRasterUniformValues = (
    projMatrix      ,
    globeMatrix              ,
    globeMercatorMatrix              ,
    normalizeMatrix              ,
    zoomTransition        ,
    mercCenter                  ,
    frustumDirTl                          ,
    frustumDirTr                          ,
    frustumDirBr                          ,
    frustumDirBl                          ,
    globePosition                          ,
    globeRadius        ,
    viewport                  ,
    skirtHeight        ,
    gridMatrix       
)                                         => ({
    'u_proj_matrix': Float32Array.from(projMatrix),
    'u_globe_matrix': globeMatrix,
    'u_normalize_matrix': Float32Array.from(normalizeMatrix),
    'u_merc_matrix': globeMercatorMatrix,
    'u_zoom_transition': zoomTransition,
    'u_merc_center': mercCenter,
    'u_image0': 0,
    'u_frustum_tl': frustumDirTl,
    'u_frustum_tr': frustumDirTr,
    'u_frustum_br': frustumDirBr,
    'u_frustum_bl': frustumDirBl,
    'u_globe_pos': globePosition,
    'u_globe_radius': globeRadius,
    'u_viewport': viewport,
    'u_grid_matrix': gridMatrix ? Float32Array.from(gridMatrix) : new Float32Array(9),
    'u_skirt_height': skirtHeight
});

const atmosphereUniformValues = (
    frustumDirTl                          ,
    frustumDirTr                          ,
    frustumDirBr                          ,
    frustumDirBl                          ,
    horizon        ,
    transitionT        ,
    fadeoutRange        ,
    color                                  ,
    highColor                                  ,
    spaceColor                                  ,
    starIntensity        ,
    temporalOffset        ,
    horizonAngle        ,
    rotationMatrix              
)                                        => ({
    'u_frustum_tl': frustumDirTl,
    'u_frustum_tr': frustumDirTr,
    'u_frustum_br': frustumDirBr,
    'u_frustum_bl': frustumDirBl,
    'u_horizon': horizon,
    'u_transition': transitionT,
    'u_fadeout_range': fadeoutRange,
    'u_color': color,
    'u_high_color': highColor,
    'u_space_color': spaceColor,
    'u_star_intensity': starIntensity,
    'u_star_size': 5.0 * index.exported.devicePixelRatio,
    'u_star_density': 0.0,
    'u_temporal_offset': temporalOffset,
    'u_horizon_angle': horizonAngle,
    'u_rotation_matrix': rotationMatrix
});

//      


                 
                      
                  
                                                                 
               
             
                 
  

class VertexMorphing {
                                               

    constructor() {
        this.operations = {};
    }

    newMorphing(key        , from      , to      , now        , duration        ) {
        index.assert(from.demTexture && to.demTexture);
        index.assert(from.tileID.key !== to.tileID.key);

        if (key in this.operations) {
            const op = this.operations[key];
            index.assert(op.from && op.to);
            // Queue the target tile unless it's being morphed to already
            if (op.to.tileID.key !== to.tileID.key)
                op.queued = to;
        } else {
            this.operations[key] = {
                startTime: now,
                phase: 0.0,
                duration,
                from,
                to,
                queued: null
            };
        }
    }

    getMorphValuesForProxy(key        )                                         {
        if (!(key in this.operations))
            return null;

        const op = this.operations[key];
        const from = op.from;
        const to = op.to;
        index.assert(from && to);

        return {from, to, phase: op.phase};
    }

    update(now        ) {
        for (const key in this.operations) {
            const op = this.operations[key];
            index.assert(op.from && op.to);

            op.phase = (now - op.startTime) / op.duration;

            // Start the queued operation if the current one is finished or the data has expired
            while (op.phase >= 1.0 || !this._validOp(op)) {
                if (!this._nextOp(op, now)) {
                    delete this.operations[key];
                    break;
                }
            }
        }
    }

    _nextOp(op          , now        )          {
        if (!op.queued)
            return false;
        op.from = op.to;
        op.to = op.queued;
        op.queued = null;
        op.phase = 0.0;
        op.startTime = now;
        return true;
    }

    _validOp(op          )          {
        return op.from.hasData() && op.to.hasData();
    }
}

function demTileChanged(prev       , next       )          {
    if (prev == null || next == null)
        return false;
    if (!prev.hasData() || !next.hasData())
        return false;
    if (prev.demTexture == null || next.demTexture == null)
        return false;
    return prev.tileID.key !== next.tileID.key;
}

const vertexMorphing = new VertexMorphing();
const SHADER_DEFAULT = 0;
const SHADER_MORPHING = 1;
const SHADER_TERRAIN_WIREFRAME = 2;
const defaultDuration = 250;

const shaderDefines = {
    "0": null,
    "1": 'TERRAIN_VERTEX_MORPHING',
    "2": 'TERRAIN_WIREFRAME'
};

function drawTerrainForGlobe(painter         , terrain         , sourceCache             , tileIDs                         , now        ) {
    const context = painter.context;
    const gl = context.gl;

    let program, programMode;
    const showWireframe = painter.options.showTerrainWireframe ? SHADER_TERRAIN_WIREFRAME : SHADER_DEFAULT;
    const tr = painter.transform;
    const useCustomAntialiasing = index.globeUseCustomAntiAliasing(painter, context, tr);

    const setShaderMode = (mode        , isWireframe         ) => {
        if (programMode === mode) return;
        const defines = [shaderDefines[mode], 'PROJECTION_GLOBE_VIEW'];

        if (useCustomAntialiasing) defines.push('CUSTOM_ANTIALIASING');
        if (isWireframe) defines.push(shaderDefines[showWireframe]);

        program = painter.useProgram('globeRaster', null, defines);
        programMode = mode;
    };

    const colorMode = painter.colorModeForRenderPass();
    const depthMode = new index.DepthMode(gl.LEQUAL, index.DepthMode.ReadWrite, painter.depthRangeFor3D);
    vertexMorphing.update(now);
    const globeMercatorMatrix = index.calculateGlobeMercatorMatrix(tr);
    const mercatorCenter = [index.mercatorXfromLng(tr.center.lng), index.mercatorYfromLat(tr.center.lat)];
    const batches = showWireframe ? [false, true] : [false];
    const sharedBuffers = painter.globeSharedBuffers;
    const viewport = [tr.width * index.exported.devicePixelRatio, tr.height * index.exported.devicePixelRatio];
    const globeMatrix = Float32Array.from(tr.globeMatrix);
    const elevationOptions = {useDenormalizedUpVectorScale: true};

    batches.forEach(isWireframe => {
        const tr = painter.transform;
        const skirtHeightValue = skirtHeight(tr.zoom) * terrain.exaggeration();

        // This code assumes the rendering is batched into mesh terrain and then wireframe
        // terrain (if applicable) so that this is enough to ensure the correct program is
        // set when we switch from one to the other.
        programMode = -1;

        const primitive = isWireframe ? gl.LINES : gl.TRIANGLES;

        for (const coord of tileIDs) {
            const tile = sourceCache.getTile(coord);
            const stencilMode = index.StencilMode.disabled;

            const prevDemTile = terrain.prevTerrainTileForTile[coord.key];
            const nextDemTile = terrain.terrainTileForTile[coord.key];

            if (demTileChanged(prevDemTile, nextDemTile)) {
                vertexMorphing.newMorphing(coord.key, prevDemTile, nextDemTile, now, defaultDuration);
            }

            // Bind the main draped texture
            context.activeTexture.set(gl.TEXTURE0);
            tile.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);

            const morph = vertexMorphing.getMorphValuesForProxy(coord.key);
            const shaderMode = morph ? SHADER_MORPHING : SHADER_DEFAULT;

            if (morph) {
                index.extend$1(elevationOptions, {morphing: {srcDemTile: morph.from, dstDemTile: morph.to, phase: index.easeCubicInOut(morph.phase)}});
            }

            const tileBounds = index.tileCornersToBounds(coord.canonical);
            const latitudinalLod = index.getLatitudinalLod(tileBounds.getCenter().lat);
            const gridMatrix = index.getGridMatrix(coord.canonical, tileBounds, latitudinalLod, tr.worldSize / tr._pixelsPerMercatorPixel);
            const normalizeMatrix = index.globeNormalizeECEF(index.globeTileBounds(coord.canonical));
            const uniformValues = globeRasterUniformValues(
                tr.projMatrix, globeMatrix, globeMercatorMatrix, normalizeMatrix, index.globeToMercatorTransition(tr.zoom),
                mercatorCenter, tr.frustumCorners.TL, tr.frustumCorners.TR, tr.frustumCorners.BR,
                tr.frustumCorners.BL, tr.globeCenterInViewSpace, tr.globeRadius, viewport, skirtHeightValue, gridMatrix);

            setShaderMode(shaderMode, isWireframe);

            terrain.setupElevationDraw(tile, program, elevationOptions);

            painter.prepareDrawProgram(context, program, coord.toUnwrapped());

            if (sharedBuffers) {
                const [buffer, indexBuffer, segments] = isWireframe ?
                    sharedBuffers.getWirefameBuffers(painter.context, latitudinalLod) :
                    sharedBuffers.getGridBuffers(latitudinalLod, skirtHeightValue !== 0);

                program.draw(context, primitive, depthMode, stencilMode, colorMode, index.CullFaceMode.backCCW,
                    uniformValues, "globe_raster", buffer, indexBuffer, segments);
            }
        }
    });

    // Render the poles.
    if (sharedBuffers) {
        const defines = ['GLOBE_POLES', 'PROJECTION_GLOBE_VIEW'];
        if (useCustomAntialiasing) defines.push('CUSTOM_ANTIALIASING');

        program = painter.useProgram('globeRaster', null, defines);
        for (const coord of tileIDs) {
            // Fill poles by extrapolating adjacent border tiles
            const {x, y, z} = coord.canonical;
            const topCap = y === 0;
            const bottomCap = y === (1 << z) - 1;

            const [northPoleBuffer, southPoleBuffer, indexBuffer, segment] = sharedBuffers.getPoleBuffers(z);

            if (segment && (topCap || bottomCap)) {
                const tile = sourceCache.getTile(coord);

                // Bind the main draped texture
                context.activeTexture.set(gl.TEXTURE0);
                tile.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);

                let poleMatrix = index.globePoleMatrixForTile(z, x, tr);
                const normalizeMatrix = index.globeNormalizeECEF(index.globeTileBounds(coord.canonical));

                const drawPole = (program              , vertexBuffer              ) => program.draw(
                    context, gl.TRIANGLES, depthMode, index.StencilMode.disabled, colorMode, index.CullFaceMode.disabled,
                    globeRasterUniformValues(tr.projMatrix, poleMatrix, poleMatrix, normalizeMatrix, 0.0, mercatorCenter,
                    tr.frustumCorners.TL, tr.frustumCorners.TR, tr.frustumCorners.BR, tr.frustumCorners.BL,
                    tr.globeCenterInViewSpace, tr.globeRadius, viewport, 0), "globe_pole_raster", vertexBuffer,
                    indexBuffer, segment);

                terrain.setupElevationDraw(tile, program, elevationOptions);

                painter.prepareDrawProgram(context, program, coord.toUnwrapped());

                if (topCap) {
                    drawPole(program, northPoleBuffer);
                }
                if (bottomCap) {
                    poleMatrix = index.scale$1(index.create(), poleMatrix, [1, -1, 1]);
                    drawPole(program, southPoleBuffer);
                }
            }
        }
    }
}

function drawTerrainRaster(painter         , terrain         , sourceCache             , tileIDs                         , now        ) {
    if (painter.transform.projection.name === 'globe') {
        drawTerrainForGlobe(painter, terrain, sourceCache, tileIDs, now);
    } else {
        const context = painter.context;
        const gl = context.gl;

        let program, programMode;
        const showWireframe = painter.options.showTerrainWireframe ? SHADER_TERRAIN_WIREFRAME : SHADER_DEFAULT;

        const setShaderMode = (mode        , isWireframe         ) => {
            if (programMode === mode)
                return;
            const modes = [shaderDefines[mode]];
            if (isWireframe) modes.push(shaderDefines[showWireframe]);
            program = painter.useProgram('terrainRaster', null, modes);
            programMode = mode;
        };

        const colorMode = painter.colorModeForRenderPass();
        const depthMode = new index.DepthMode(gl.LEQUAL, index.DepthMode.ReadWrite, painter.depthRangeFor3D);
        vertexMorphing.update(now);
        const tr = painter.transform;
        const skirt = skirtHeight(tr.zoom) * terrain.exaggeration();

        const batches = showWireframe ? [false, true] : [false];

        batches.forEach(isWireframe => {
            // This code assumes the rendering is batched into mesh terrain and then wireframe
            // terrain (if applicable) so that this is enough to ensure the correct program is
            // set when we switch from one to the other.
            programMode = -1;

            const primitive = isWireframe ? gl.LINES : gl.TRIANGLES;
            const [buffer, segments] = isWireframe ? terrain.getWirefameBuffer() : [terrain.gridIndexBuffer, terrain.gridSegments];

            for (const coord of tileIDs) {
                const tile = sourceCache.getTile(coord);
                const stencilMode = index.StencilMode.disabled;

                const prevDemTile = terrain.prevTerrainTileForTile[coord.key];
                const nextDemTile = terrain.terrainTileForTile[coord.key];

                if (demTileChanged(prevDemTile, nextDemTile)) {
                    vertexMorphing.newMorphing(coord.key, prevDemTile, nextDemTile, now, defaultDuration);
                }

                // Bind the main draped texture
                context.activeTexture.set(gl.TEXTURE0);
                tile.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST);

                const morph = vertexMorphing.getMorphValuesForProxy(coord.key);
                const shaderMode = morph ? SHADER_MORPHING : SHADER_DEFAULT;
                let elevationOptions;

                if (morph) {
                    elevationOptions = {morphing: {srcDemTile: morph.from, dstDemTile: morph.to, phase: index.easeCubicInOut(morph.phase)}};
                }

                const uniformValues = terrainRasterUniformValues(coord.projMatrix, isEdgeTile(coord.canonical, tr.renderWorldCopies) ? skirt / 10 : skirt);
                setShaderMode(shaderMode, isWireframe);

                terrain.setupElevationDraw(tile, program, elevationOptions);

                painter.prepareDrawProgram(context, program, coord.toUnwrapped());

                program.draw(context, primitive, depthMode, stencilMode, colorMode, index.CullFaceMode.backCCW,
                    uniformValues, "terrain_raster", terrain.gridBuffer, buffer, segments);
            }
        });
    }
}

function drawTerrainDepth(painter         , terrain         , sourceCache             , tileIDs                         ) {
    if (painter.transform.projection.name === 'globe') {
        return;
    }

    index.assert(painter.renderPass === 'offscreen');

    const context = painter.context;
    const gl = context.gl;

    context.clear({depth: 1});
    const program = painter.useProgram('terrainDepth');
    const depthMode = new index.DepthMode(gl.LESS, index.DepthMode.ReadWrite, painter.depthRangeFor3D);

    for (const coord of tileIDs) {
        const tile = sourceCache.getTile(coord);
        const uniformValues = terrainRasterUniformValues(coord.projMatrix, 0);
        terrain.setupElevationDraw(tile, program);

        program.draw(context, gl.TRIANGLES, depthMode, index.StencilMode.disabled, index.ColorMode.unblended, index.CullFaceMode.backCCW,
            uniformValues, "terrain_depth", terrain.gridBuffer, terrain.gridIndexBuffer, terrain.gridNoSkirtSegments);
    }
}

function skirtHeight(zoom        ) {
    // Skirt height calculation is heuristic: provided value hides
    // seams between tiles and it is not too large: 9 at zoom 22, ~20000m at zoom 0.
    return 6 * Math.pow(1.5, 22 - zoom);
}

function isEdgeTile(cid                 , renderWorldCopies         )          {
    const numTiles = 1 << cid.z;
    return (!renderWorldCopies && (cid.x === 0 || cid.x === numTiles - 1)) || cid.y === 0 || cid.y === numTiles - 1;
}

//      


                                               
                                                         

                                         
                               
   

const clippingMaskUniforms = (context         )                           => ({
    'u_matrix': new index.UniformMatrix4f(context)
});

const clippingMaskUniformValues = (matrix              )                                          => ({
    'u_matrix': matrix
});

//      

                                                 

                           
                    
                
   

function rasterFade(tile      , parentTile       , sourceCache             , transform           , fadeDuration        )             {
    if (fadeDuration > 0) {
        const now = index.exported.now();
        const sinceTile = (now - tile.timeAdded) / fadeDuration;
        const sinceParent = parentTile ? (now - parentTile.timeAdded) / fadeDuration : -1;

        const source = sourceCache.getSource();
        const idealZ = transform.coveringZoomLevel({
            tileSize: source.tileSize,
            roundZoom: source.roundZoom
        });

        // if no parent or parent is older, fade in; if parent is younger, fade out
        const fadeIn = !parentTile || Math.abs(parentTile.tileID.overscaledZ - idealZ) > Math.abs(tile.tileID.overscaledZ - idealZ);

        const childOpacity = (fadeIn && tile.refreshedUponExpiration) ? 1 : index.clamp(fadeIn ? sinceTile : 1 - sinceParent, 0, 1);

        // we don't crossfade tiles that were just refreshed upon expiring:
        // once they're old enough to pass the crossfading threshold
        // (fadeDuration), unset the `refreshedUponExpiration` flag so we don't
        // incorrectly fail to crossfade them when zooming
        if (tile.refreshedUponExpiration && sinceTile >= 1) tile.refreshedUponExpiration = false;

        if (parentTile) {
            return {
                opacity: 1,
                mix: 1 - childOpacity
            };
        } else {
            return {
                opacity: childOpacity,
                mix: 0
            };
        }
    } else {
        return {
            opacity: 1,
            mix: 0
        };
    }
}

//      


                                    
                                                
                                           
                                                      
                                                       
                                                     
                                            
                                                                
                                                 
                                                     
                                          
                                                          

const GRID_DIM = 128;

const FBO_POOL_SIZE = 5;
const RENDER_CACHE_MAX_SIZE = 50;

                    
                  
                
 

class MockSourceCache extends index.SourceCache {
    constructor(map     ) {
        const sourceSpec = {type: 'raster-dem', maxzoom: map.transform.maxZoom};
        const sourceDispatcher = new Dispatcher(getGlobalWorkerPool(), null);
        const source = create('mock-dem', sourceSpec, sourceDispatcher, map.style);

        super('mock-dem', source, false);

        source.setEventedParent(this);

        this._sourceLoaded = true;
    }

    _loadTile(tile      , callback                ) {
        tile.state = 'loaded';
        callback(null);
    }
}

/**
 * Proxy source cache gets ideal screen tile cover coordinates. All the other
 * source caches's coordinates get mapped to subrects of proxy coordinates (or
 * vice versa, subrects of larger tiles from all source caches get mapped to
 * full proxy tile). This happens on every draw call in Terrain.updateTileBinding.
 * Approach is used here for terrain : all the visible source tiles of all the
 * source caches get rendered to proxy source cache textures and then draped over
 * terrain. It is in future reusable for handling overscalling as buckets could be
 * constructed only for proxy tile content, not for full overscalled vector tile.
 */
class ProxySourceCache extends index.SourceCache {
                            
                                   
                                                                     

    constructor(map     ) {

        const source = create('proxy', {
            type: 'geojson',
            maxzoom: map.transform.maxZoom
        }, new Dispatcher(getGlobalWorkerPool(), null), map.style);

        super('proxy', source, false);

        source.setEventedParent(this);

        // This source is not to be added as a map source: we use it's tile management.
        // For that, initialize internal structures used for tile cover update.
        this.map = ((this.getSource()     )               ).map = map;
        this.used = this._sourceLoaded = true;
        this.renderCache = [];
        this.renderCachePool = [];
        this.proxyCachedFBO = {};
    }

    // Override for transient nature of cover here: don't cache and retain.
    update(transform           , tileSize         , updateForTerrain          ) { // eslint-disable-line no-unused-vars
        if (transform.freezeTileCoverage) { return; }
        this.transform = transform;
        const idealTileIDs = transform.coveringTiles({
            tileSize: this._source.tileSize,
            minzoom: this._source.minzoom,
            maxzoom: this._source.maxzoom,
            roundZoom: this._source.roundZoom,
            reparseOverscaled: this._source.reparseOverscaled
        });

        const incoming                     = idealTileIDs.reduce((acc, tileID) => {
            acc[tileID.key] = '';
            if (!this._tiles[tileID.key]) {
                const tile = new index.Tile(tileID, this._source.tileSize * tileID.overscaleFactor(), transform.tileZoom);
                tile.state = 'loaded';
                this._tiles[tileID.key] = tile;
            }
            return acc;
        }, {});

        for (const id in this._tiles) {
            if (!(id in incoming)) {
                this.freeFBO(id);
                this._tiles[id].unloadVectorData();
                delete this._tiles[id];
            }
        }
    }

    freeFBO(id        ) {
        const fbos = this.proxyCachedFBO[id];
        if (fbos !== undefined) {
            const fboIds = ((Object.values(fbos)     )               );
            this.renderCachePool.push(...fboIds);
            delete this.proxyCachedFBO[id];
        }
    }

    deallocRenderCache() {
        this.renderCache.forEach(fbo => fbo.fb.destroy());
        this.renderCache = [];
        this.renderCachePool = [];
        this.proxyCachedFBO = {};
    }
}

/**
 * Canonical, wrap and overscaledZ contain information of original source cache tile.
 * This tile gets ortho-rendered to proxy tile (defined by proxyTileKey).
 * `posMatrix` holds orthographic, scaling and translation information that is used
 * for rendering original tile content to a proxy tile. Proxy tile covers whole
 * or sub-rectangle of the original tile.
 */
class ProxiedTileID extends index.OverscaledTileID {
                         

    constructor(tileID                  , proxyTileKey        , projMatrix              ) {
        super(tileID.overscaledZ, tileID.wrap, tileID.canonical.z, tileID.canonical.x, tileID.canonical.y);
        this.proxyTileKey = proxyTileKey;
        this.projMatrix = projMatrix;
    }
}

                                                  
                                                           

class Terrain extends index.Elevation {
                                                  
                                                      
                     
                             
                             
                                 
                                
                                       
                                     
                                      
                                                    
                                         
                                                                
                                       
                                
                  
                                      
                              
                     
                       

                                  
                                             
                                     
                                            
                        

                          
                            
                            
                          
                             
                                
                     
                            
                                             
                                            

                                                            

                                                 
                                    

                                       
                               
                            
                                    

    constructor(painter         , style       ) {
        super();
        this.painter = painter;
        this.terrainTileForTile = {};
        this.prevTerrainTileForTile = {};

        // Terrain rendering grid is 129x129 cell grid, made by 130x130 points.
        // 130 vertices map to 128 DEM data + 1px padding on both sides.
        // DEM texture is padded (1, 1, 1, 1) and padding pixels are backfilled
        // by neighboring tile edges. This way we achieve tile stitching as
        // edge vertices from neighboring tiles evaluate to the same 3D point.
        const [triangleGridArray, triangleGridIndices, skirtIndicesOffset] = createGrid(GRID_DIM + 1);
        const context = painter.context;
        this.gridBuffer = context.createVertexBuffer(triangleGridArray, index.posAttributes.members);
        this.gridIndexBuffer = context.createIndexBuffer(triangleGridIndices);
        this.gridSegments = index.SegmentVector.simpleSegment(0, 0, triangleGridArray.length, triangleGridIndices.length);
        this.gridNoSkirtSegments = index.SegmentVector.simpleSegment(0, 0, triangleGridArray.length, skirtIndicesOffset);
        this.proxyCoords = [];
        this.proxiedCoords = {};
        this._visibleDemTiles = [];
        this._drapedRenderBatches = [];
        this._sourceTilesOverlap = {};
        this.proxySourceCache = new ProxySourceCache(style.map);
        this.orthoMatrix = index.create();
        const epsilon = this.painter.transform.projection.name === 'globe' ?  .015 : 0; // Experimentally the smallest value to avoid rendering artifacts (https://github.com/mapbox/mapbox-gl-js/issues/11975)
        index.ortho(this.orthoMatrix, epsilon, index.EXTENT, 0, index.EXTENT, 0, 1);
        const gl = context.gl;
        this._overlapStencilMode = new index.StencilMode({func: gl.GEQUAL, mask: 0xFF}, 0, 0xFF, gl.KEEP, gl.KEEP, gl.REPLACE);
        this._previousZoom = painter.transform.zoom;
        this.pool = [];
        this._findCoveringTileCache = {};
        this._tilesDirty = {};
        this.style = style;
        this._useVertexMorphing = true;
        this._exaggeration = 1;
        this._mockSourceCache = new MockSourceCache(style.map);
    }

    set style(style       ) {
        // $FlowFixMe[method-unbinding]
        style.on('data', this._onStyleDataEvent.bind(this));
        // $FlowFixMe[method-unbinding]
        style.on('neworder', this._checkRenderCacheEfficiency.bind(this));
        this._style = style;
        this._checkRenderCacheEfficiency();
        this._style.map.on('moveend', () => {
            this._clearLineLayersFromRenderCache();
        });
    }

    /*
     * Validate terrain and update source cache used for elevation.
     * Explicitly pass transform to update elevation (Transform.updateElevation)
     * before using transform for source cache update.
     */
    update(style       , transform           , adaptCameraAltitude         ) {
        if (style && style.terrain) {
            if (this._style !== style) {
                this.style = style;
            }
            this.enabled = true;
            const terrainProps = style.terrain.properties;
            const isDrapeModeDeferred = style.terrain.drapeRenderMode === DrapeRenderMode.deferred;
            this.sourceCache = isDrapeModeDeferred ? this._mockSourceCache :
                ((style._getSourceCache(terrainProps.get('source'))     )             );
            this._exaggeration = terrainProps.get('exaggeration');

            const updateSourceCache = () => {
                if (this.sourceCache.used) {
                    index.warnOnce(`Raster DEM source '${this.sourceCache.id}' is used both for terrain and as layer source.\n` +
                        'This leads to lower resolution of hillshade. For full hillshade resolution but higher memory consumption, define another raster DEM source.');
                }
                // Lower tile zoom is sufficient for terrain, given the size of terrain grid.
                const scaledDemTileSize = this.getScaledDemTileSize();
                // Dem tile needs to be parent or at least of the same zoom level as proxy tile.
                // Tile cover roundZoom behavior is set to the same as for proxy (false) in SourceCache.update().
                this.sourceCache.update(transform, scaledDemTileSize, true);
                // As a result of update, we get new set of tiles: reset lookup cache.
                this.resetTileLookupCache(this.sourceCache.id);
            };

            if (!this.sourceCache.usedForTerrain) {
                // Init cache entry.
                this.resetTileLookupCache(this.sourceCache.id);
                // When toggling terrain on/off load available terrain tiles from cache
                // before reading elevation at center.
                this.sourceCache.usedForTerrain = true;
                updateSourceCache();
                this._initializing = true;
            }

            updateSourceCache();
            // Camera gets constrained over terrain. Issue constrainCameraOverTerrain = true
            // here to cover potential under terrain situation on data, style, or other camera changes.
            transform.updateElevation(true, adaptCameraAltitude);

            // Reset tile lookup cache and update draped tiles coordinates.
            this.resetTileLookupCache(this.proxySourceCache.id);
            this.proxySourceCache.update(transform);

            this._emptyDEMTextureDirty = true;
        } else {
            this._disable();
        }
    }

    resetTileLookupCache(sourceCacheID        ) {
        this._findCoveringTileCache[sourceCacheID] = {};
    }

    getScaledDemTileSize()         {
        const demScale = this.sourceCache.getSource().tileSize / GRID_DIM;
        const proxyTileSize = this.proxySourceCache.getSource().tileSize;
        return demScale * proxyTileSize;
    }

    _checkRenderCacheEfficiency() {
        const renderCacheInfo = this.renderCacheEfficiency(this._style);
        if (this._style.map._optimizeForTerrain) {
            index.assert(renderCacheInfo.efficiency === 100);
        } else if (renderCacheInfo.efficiency !== 100) {
            index.warnOnce(`Terrain render cache efficiency is not optimal (${renderCacheInfo.efficiency}%) and performance
                may be affected negatively, consider placing all background, fill and line layers before layer
                with id '${renderCacheInfo.firstUndrapedLayer}' or create a map using optimizeForTerrain: true option.`);
        }
    }

    _onStyleDataEvent(event     ) {
        if (event.coord && event.dataType === 'source') {
            this._clearRenderCacheForTile(event.sourceCacheId, event.coord);
        } else if (event.dataType === 'style') {
            this._invalidateRenderCache = true;
        }
    }

    // Terrain
    _disable() {
        if (!this.enabled) return;
        this.enabled = false;
        this._sharedDepthStencil = undefined;
        this.proxySourceCache.deallocRenderCache();
        if (this._style) {
            for (const id in this._style._sourceCaches) {
                this._style._sourceCaches[id].usedForTerrain = false;
            }
        }
    }

    destroy() {
        this._disable();
        if (this._emptyDEMTexture) this._emptyDEMTexture.destroy();
        if (this._emptyDepthBufferTexture) this._emptyDepthBufferTexture.destroy();
        this.pool.forEach(fbo => fbo.fb.destroy());
        this.pool = [];
        if (this._depthFBO) {
            this._depthFBO.destroy();
            this._depthFBO = undefined;
            this._depthTexture = undefined;
        }
    }

    // Implements Elevation::_source.
    _source()               {
        return this.enabled ? this.sourceCache : null;
    }

    isUsingMockSource()          {
        return this.sourceCache === this._mockSourceCache;
    }

    // Implements Elevation::exaggeration.
    exaggeration()         {
        return this._exaggeration;
    }

    get visibleDemTiles()              {
        return this._visibleDemTiles;
    }

    get drapeBufferSize()                   {
        const extent = this.proxySourceCache.getSource().tileSize * 2; // *2 is to avoid upscaling bitmap on zoom.
        return [extent, extent];
    }

    set useVertexMorphing(enable         ) {
        this._useVertexMorphing = enable;
    }

    // For every renderable coordinate in every source cache, assign one proxy
    // tile (see _setupProxiedCoordsForOrtho). Mapping of source tile to proxy
    // tile is modeled by ProxiedTileID. In general case, source and proxy tile
    // are of different zoom: ProxiedTileID.projMatrix models ortho, scale and
    // translate from source to proxy. This matrix is used when rendering source
    // tile to proxy tile's texture.
    // One proxy tile can have multiple source tiles, or pieces of source tiles,
    // that get rendered to it.
    // For each proxy tile we assign one terrain tile (_assignTerrainTiles). The
    // terrain tile provides elevation data when rendering (draping) proxy tile
    // texture over terrain grid.
    updateTileBinding(sourcesCoords                                     ) {
        if (!this.enabled) return;
        this.prevTerrainTileForTile = this.terrainTileForTile;

        const psc = this.proxySourceCache;
        const tr = this.painter.transform;
        if (this._initializing) {
            // Don't activate terrain until center tile gets loaded.
            this._initializing = tr._centerAltitude === 0 && this.getAtPointOrZero(index.MercatorCoordinate.fromLngLat(tr.center), -1) === -1;
            this._emptyDEMTextureDirty = !this._initializing;
        }

        const coords = this.proxyCoords = psc.getIds().map((id) => {
            const tileID = psc.getTileByID(id).tileID;
            tileID.projMatrix = tr.calculateProjMatrix(tileID.toUnwrapped());
            return tileID;
        });
        sortByDistanceToCamera(coords, this.painter);
        this._previousZoom = tr.zoom;

        const previousProxyToSource = this.proxyToSource || {};
        this.proxyToSource = {};
        coords.forEach((tileID) => {
            this.proxyToSource[tileID.key] = {};
        });

        this.terrainTileForTile = {};
        const sourceCaches = this._style._sourceCaches;
        for (const id in sourceCaches) {
            const sourceCache = sourceCaches[id];
            if (!sourceCache.used) continue;
            if (sourceCache !== this.sourceCache) this.resetTileLookupCache(sourceCache.id);
            this._setupProxiedCoordsForOrtho(sourceCache, sourcesCoords[id], previousProxyToSource);
            if (sourceCache.usedForTerrain) continue;
            const coordinates = sourcesCoords[id];
            if (sourceCache.getSource().reparseOverscaled) {
                // Do this for layers that are not rasterized to proxy tile.
                this._assignTerrainTiles(coordinates);
            }
        }

        // Background has no source. Using proxy coords with 1-1 ortho (this.proxiedCoords[psc.id])
        // when rendering background to proxy tiles.
        this.proxiedCoords[psc.id] = coords.map(tileID => new ProxiedTileID(tileID, tileID.key, this.orthoMatrix));
        this._assignTerrainTiles(coords);
        this._prepareDEMTextures();
        this._setupDrapedRenderBatches();
        this._initFBOPool();
        this._setupRenderCache(previousProxyToSource);

        this.renderingToTexture = false;
        this._updateTimestamp = index.exported.now();

        // Gather all dem tiles that are assigned to proxy tiles
        const visibleKeys = {};
        this._visibleDemTiles = [];

        for (const id of this.proxyCoords) {
            const demTile = this.terrainTileForTile[id.key];
            if (!demTile)
                continue;
            const key = demTile.tileID.key;
            if (key in visibleKeys)
                continue;
            this._visibleDemTiles.push(demTile);
            visibleKeys[key] = key;
        }

    }

    _assignTerrainTiles(coords                         ) {
        if (this._initializing) return;
        coords.forEach((tileID) => {
            if (this.terrainTileForTile[tileID.key]) return;
            const demTile = this._findTileCoveringTileID(tileID, this.sourceCache);
            if (demTile) this.terrainTileForTile[tileID.key] = demTile;
        });
    }

    _prepareDEMTextures() {
        const context = this.painter.context;
        const gl = context.gl;
        for (const key in this.terrainTileForTile) {
            const tile = this.terrainTileForTile[key];
            const dem = tile.dem;
            if (dem && (!tile.demTexture || tile.needsDEMTextureUpload)) {
                context.activeTexture.set(gl.TEXTURE1);
                prepareDEMTexture(this.painter, tile, dem);
            }
        }
    }

    _prepareDemTileUniforms(proxyTile      , demTile       , uniforms                                    , uniformSuffix         )          {
        if (!demTile || demTile.demTexture == null)
            return false;

        index.assert(demTile.dem);
        const proxyId = proxyTile.tileID.canonical;
        const demId = demTile.tileID.canonical;
        const demScaleBy = Math.pow(2, demId.z - proxyId.z);
        const suffix = uniformSuffix || "";
        // $FlowFixMe[prop-missing]
        uniforms[`u_dem_tl${suffix}`] = [proxyId.x * demScaleBy % 1, proxyId.y * demScaleBy % 1];
        // $FlowFixMe[prop-missing]
        uniforms[`u_dem_scale${suffix}`] = demScaleBy;
        return true;
    }

    get emptyDEMTexture()          {
        return !this._emptyDEMTextureDirty && this._emptyDEMTexture ?
            this._emptyDEMTexture : this._updateEmptyDEMTexture();
    }

    get emptyDepthBufferTexture()          {
        const context = this.painter.context;
        const gl = context.gl;
        if (!this._emptyDepthBufferTexture) {
            const image = new index.RGBAImage({width: 1, height: 1}, Uint8Array.of(255, 255, 255, 255));
            this._emptyDepthBufferTexture = new index.Texture(context, image, gl.RGBA, {premultiply: false});
        }
        return this._emptyDepthBufferTexture;
    }

    _getLoadedAreaMinimum()         {
        let nonzero = 0;
        const min = this._visibleDemTiles.reduce((acc, tile) => {
            if (!tile.dem) return acc;
            const m = tile.dem.tree.minimums[0];
            acc += m;
            if (m > 0) nonzero++;
            return acc;
        }, 0);
        return nonzero ? min / nonzero : 0;
    }

    _updateEmptyDEMTexture()          {
        const context = this.painter.context;
        const gl = context.gl;
        context.activeTexture.set(gl.TEXTURE2);

        const min = this._getLoadedAreaMinimum();
        const image = new index.RGBAImage(
            {width: 1, height: 1},
            new Uint8Array(index.DEMData.pack(min, ((this.sourceCache.getSource()     )                     ).encoding))
        );

        this._emptyDEMTextureDirty = false;
        let texture = this._emptyDEMTexture;
        if (!texture) {
            texture = this._emptyDEMTexture = new index.Texture(context, image, gl.RGBA, {premultiply: false});
        } else {
            texture.update(image, {premultiply: false});
        }
        return texture;
    }

    // useDepthForOcclusion: Pre-rendered depth to texture (this._depthTexture) is
    // used to hide (actually moves all object's vertices out of viewport).
    // useMeterToDem: u_meter_to_dem uniform is not used for all terrain programs,
    // optimization to avoid unnecessary computation and upload.
    setupElevationDraw(tile      , program            ,
        options    
                                           
                                    
                                                
                                                                             
                                                  
         ) {
        const context = this.painter.context;
        const gl = context.gl;
        const uniforms = defaultTerrainUniforms(((this.sourceCache.getSource()     )                     ).encoding);
        uniforms['u_dem_size'] = this.sourceCache.getSource().tileSize;
        uniforms['u_exaggeration'] = this.exaggeration();

        let demTile = null;
        let prevDemTile = null;
        let morphingPhase = 1.0;

        if (options && options.morphing && this._useVertexMorphing) {
            const srcTile = options.morphing.srcDemTile;
            const dstTile = options.morphing.dstDemTile;
            morphingPhase = options.morphing.phase;

            if (srcTile && dstTile) {
                if (this._prepareDemTileUniforms(tile, srcTile, uniforms, "_prev"))
                    prevDemTile = srcTile;
                if (this._prepareDemTileUniforms(tile, dstTile, uniforms))
                    demTile = dstTile;
            }
        }

        if (prevDemTile && demTile) {
            // Both DEM textures are expected to be correctly set if geomorphing is enabled
            context.activeTexture.set(gl.TEXTURE2);
            (demTile.demTexture     ).bind(gl.NEAREST, gl.CLAMP_TO_EDGE, gl.NEAREST);
            context.activeTexture.set(gl.TEXTURE4);
            (prevDemTile.demTexture     ).bind(gl.NEAREST, gl.CLAMP_TO_EDGE, gl.NEAREST);

            uniforms["u_dem_lerp"] = morphingPhase;
        } else {
            demTile = this.terrainTileForTile[tile.tileID.key];
            context.activeTexture.set(gl.TEXTURE2);
            const demTexture = this._prepareDemTileUniforms(tile, demTile, uniforms) ?
                (demTile.demTexture     ) : this.emptyDEMTexture;
            demTexture.bind(gl.NEAREST, gl.CLAMP_TO_EDGE);
        }

        context.activeTexture.set(gl.TEXTURE3);
        if (options && options.useDepthForOcclusion) {
            if (this._depthTexture) this._depthTexture.bind(gl.NEAREST, gl.CLAMP_TO_EDGE);
            if (this._depthFBO) uniforms['u_depth_size_inv'] = [1 / this._depthFBO.width, 1 / this._depthFBO.height];
        } else {
            this.emptyDepthBufferTexture.bind(gl.NEAREST, gl.CLAMP_TO_EDGE);
            uniforms['u_depth_size_inv'] = [1, 1];
        }

        if (options && options.useMeterToDem && demTile) {
            const meterToDEM = (1 << demTile.tileID.canonical.z) * index.mercatorZfromAltitude(1, this.painter.transform.center.lat) * this.sourceCache.getSource().tileSize;
            uniforms['u_meter_to_dem'] = meterToDEM;
        }
        if (options && options.labelPlaneMatrixInv) {
            uniforms['u_label_plane_matrix_inv'] = options.labelPlaneMatrixInv;
        }
        program.setTerrainUniformValues(context, uniforms);

        if (this.painter.transform.projection.name === 'globe') {
            const globeUniforms = this.globeUniformValues(this.painter.transform, tile.tileID.canonical, options && options.useDenormalizedUpVectorScale);
            program.setGlobeUniformValues(context, globeUniforms);
        }
    }

    globeUniformValues(tr           , id                 , useDenormalizedUpVectorScale          )                                   {
        const projection = tr.projection;
        return {
            'u_tile_tl_up': (projection.upVector(id, 0, 0)     ),
            'u_tile_tr_up': (projection.upVector(id, index.EXTENT, 0)     ),
            'u_tile_br_up': (projection.upVector(id, index.EXTENT, index.EXTENT)     ),
            'u_tile_bl_up': (projection.upVector(id, 0, index.EXTENT)     ),
            'u_tile_up_scale': (useDenormalizedUpVectorScale ? index.globeMetersToEcef(1) : projection.upVectorScale(id, tr.center.lat, tr.worldSize).metersToTile     )
        };
    }

    renderToBackBuffer(accumulatedDrapes                         ) {
        const painter = this.painter;
        const context = this.painter.context;

        if (accumulatedDrapes.length === 0) {
            return;
        }

        context.bindFramebuffer.set(null);
        context.viewport.set([0, 0, painter.width, painter.height]);

        painter.gpuTimingDeferredRenderStart();

        this.renderingToTexture = false;
        drawTerrainRaster(painter, this, this.proxySourceCache, accumulatedDrapes, this._updateTimestamp);
        this.renderingToTexture = true;

        painter.gpuTimingDeferredRenderEnd();

        accumulatedDrapes.splice(0, accumulatedDrapes.length);
    }

    // For each proxy tile, render all layers until the non-draped layer (and
    // render the tile to the screen) before advancing to the next proxy tile.
    // Returns the last drawn index that is used as a start
    // layer for interleaved draped rendering.
    // Apart to layer-by-layer rendering used in 2D, here we have proxy-tile-by-proxy-tile
    // rendering.
    renderBatch(startLayerIndex        )         {
        if (this._drapedRenderBatches.length === 0) {
            return startLayerIndex + 1;
        }

        this.renderingToTexture = true;
        const painter = this.painter;
        const context = this.painter.context;
        const psc = this.proxySourceCache;
        const proxies = this.proxiedCoords[psc.id];

        // Consume batch of sequential drape layers and move next
        const drapedLayerBatch = this._drapedRenderBatches.shift();
        index.assert(drapedLayerBatch.start === startLayerIndex);

        const accumulatedDrapes = [];
        const layerIds = painter.style.order;

        let poolIndex = 0;
        for (const proxy of proxies) {
            // bind framebuffer and assign texture to the tile (texture used in drawTerrainRaster).
            const tile = psc.getTileByID(proxy.proxyTileKey);
            const renderCacheIndex = psc.proxyCachedFBO[proxy.key] ? psc.proxyCachedFBO[proxy.key][startLayerIndex] : undefined;
            const fbo = renderCacheIndex !== undefined ? psc.renderCache[renderCacheIndex] : this.pool[poolIndex++];
            const useRenderCache = renderCacheIndex !== undefined;

            tile.texture = fbo.tex;

            if (useRenderCache && !fbo.dirty) {
                // Use cached render from previous pass, no need to render again.
                accumulatedDrapes.push(tile.tileID);
                continue;
            }

            context.bindFramebuffer.set(fbo.fb.framebuffer);
            this.renderedToTile = false; // reset flag.
            if (fbo.dirty) {
                // Clear on start.
                context.clear({color: index.Color.transparent, stencil: 0});
                fbo.dirty = false;
            }

            let currentStencilSource; // There is no need to setup stencil for the same source for consecutive layers.
            for (let j = drapedLayerBatch.start; j <= drapedLayerBatch.end; ++j) {
                const layer = painter.style._layers[layerIds[j]];
                const hidden = layer.isHidden(painter.transform.zoom);
                index.assert(this._style.isLayerDraped(layer) || hidden);
                if (hidden) continue;

                const sourceCache = painter.style._getLayerSourceCache(layer);
                const proxiedCoords = sourceCache ? this.proxyToSource[proxy.key][sourceCache.id] : [proxy];
                if (!proxiedCoords) continue; // when tile is not loaded yet for the source cache.

                const coords = ((proxiedCoords     )                         );
                context.viewport.set([0, 0, fbo.fb.width, fbo.fb.height]);
                if (currentStencilSource !== (sourceCache ? sourceCache.id : null)) {
                    this._setupStencil(fbo, proxiedCoords, layer, sourceCache);
                    currentStencilSource = sourceCache ? sourceCache.id : null;
                }
                painter.renderLayer(painter, sourceCache, layer, coords);
            }

            if (this.renderedToTile) {
                fbo.dirty = true;
                accumulatedDrapes.push(tile.tileID);
            } else if (!useRenderCache) {
                --poolIndex;
                index.assert(poolIndex >= 0);
            }
            if (poolIndex === FBO_POOL_SIZE) {
                poolIndex = 0;
                this.renderToBackBuffer(accumulatedDrapes);
            }
        }

        // Reset states and render last drapes
        this.renderToBackBuffer(accumulatedDrapes);
        this.renderingToTexture = false;

        context.bindFramebuffer.set(null);
        context.viewport.set([0, 0, painter.width, painter.height]);

        return drapedLayerBatch.end + 1;
    }

    postRender() {
        // Make sure we consumed all the draped terrain batches at this point
        index.assert(this._drapedRenderBatches.length === 0);
    }

    renderCacheEfficiency(style       )         {
        const layerCount = style.order.length;

        if (layerCount === 0) {
            return {efficiency: 100.0};
        }

        let uncacheableLayerCount = 0;
        let drapedLayerCount = 0;
        let reachedUndrapedLayer = false;
        let firstUndrapedLayer;

        for (let i = 0; i < layerCount; ++i) {
            const layer = style._layers[style.order[i]];
            if (!this._style.isLayerDraped(layer)) {
                if (!reachedUndrapedLayer) {
                    reachedUndrapedLayer = true;
                    firstUndrapedLayer = layer.id;
                }
            } else {
                if (reachedUndrapedLayer) {
                    ++uncacheableLayerCount;
                }
                ++drapedLayerCount;
            }
        }

        if (drapedLayerCount === 0) {
            return {efficiency: 100.0};
        }

        return {efficiency: (1.0 - uncacheableLayerCount / drapedLayerCount) * 100.0, firstUndrapedLayer};
    }

    getMinElevationBelowMSL()         {
        let min = 0.0;
        // The maximum DEM error in meters to be conservative (SRTM).
        const maxDEMError = 30.0;
        this._visibleDemTiles.filter(tile => tile.dem).forEach(tile => {
            const minMaxTree = (tile.dem     ).tree;
            min = Math.min(min, minMaxTree.minimums[0]);
        });
        return min === 0.0 ? min : (min - maxDEMError) * this._exaggeration;
    }

    // Performs raycast against visible DEM tiles on the screen and returns the distance travelled along the ray.
    // x & y components of the position are expected to be in normalized mercator coordinates [0, 1] and z in meters.
    raycast(pos      , dir      , exaggeration        )          {
        if (!this._visibleDemTiles)
            return null;

        // Perform initial raycasts against root nodes of the available dem tiles
        // and use this information to sort them from closest to furthest.
        const preparedTiles = this._visibleDemTiles.filter(tile => tile.dem).map(tile => {
            const id = tile.tileID;
            const tiles = 1 << id.overscaledZ;
            const {x, y} = id.canonical;

            // Compute tile boundaries in mercator coordinates
            const minx = x / tiles;
            const maxx = (x + 1) / tiles;
            const miny = y / tiles;
            const maxy = (y + 1) / tiles;
            const tree = (tile.dem     ).tree;

            return {
                minx, miny, maxx, maxy,
                t: tree.raycastRoot(minx, miny, maxx, maxy, pos, dir, exaggeration),
                tile
            };
        });

        preparedTiles.sort((a, b) => {
            const at = a.t !== null ? a.t : Number.MAX_VALUE;
            const bt = b.t !== null ? b.t : Number.MAX_VALUE;
            return at - bt;
        });

        for (const obj of preparedTiles) {
            if (obj.t == null)
                return null;

            // Perform more accurate raycast against the dem tree. First intersection is the closest on
            // as all tiles are sorted from closest to furthest
            const tree = (obj.tile.dem     ).tree;
            const t = tree.raycast(obj.minx, obj.miny, obj.maxx, obj.maxy, pos, dir, exaggeration);

            if (t != null)
                return t;
        }

        return null;
    }

    _createFBO()      {
        const painter = this.painter;
        const context = painter.context;
        const gl = context.gl;
        const bufferSize = this.drapeBufferSize;
        context.activeTexture.set(gl.TEXTURE0);
        const tex = new index.Texture(context, {width: bufferSize[0], height: bufferSize[1], data: null}, gl.RGBA);
        tex.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);
        const fb = context.createFramebuffer(bufferSize[0], bufferSize[1], false);
        fb.colorAttachment.set(tex.texture);
        fb.depthAttachment = new index.DepthStencilAttachment(context, fb.framebuffer);

        if (this._sharedDepthStencil === undefined) {
            this._sharedDepthStencil = context.createRenderbuffer(context.gl.DEPTH_STENCIL, bufferSize[0], bufferSize[1]);
            this._stencilRef = 0;
            fb.depthAttachment.set(this._sharedDepthStencil);
            context.clear({stencil: 0});
        } else {
            fb.depthAttachment.set(this._sharedDepthStencil);
        }

        if (context.extTextureFilterAnisotropic && !context.extTextureFilterAnisotropicForceOff) {
            gl.texParameterf(gl.TEXTURE_2D,
                context.extTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT,
                context.extTextureFilterAnisotropicMax);
        }

        return {fb, tex, dirty: false};
    }

    _initFBOPool() {
        while (this.pool.length < Math.min(FBO_POOL_SIZE, this.proxyCoords.length)) {
            this.pool.push(this._createFBO());
        }
    }

    _shouldDisableRenderCache()          {
        // Disable render caches on dynamic events due to fading or transitioning.
        if (this._style.light && this._style.light.hasTransition()) {
            return true;
        }

        for (const id in this._style._sourceCaches) {
            if (this._style._sourceCaches[id].hasTransition()) {
                return true;
            }
        }

        const isTransitioning = (id        ) => {
            const layer = this._style._layers[id];
            const isHidden = layer.isHidden(this.painter.transform.zoom);
            if (layer.type === 'custom') {
                return !isHidden && ((layer     )                  ).shouldRedrape();
            }
            return !isHidden && layer.hasTransition();
        };
        return this._style.order.some(isTransitioning);
    }

    _clearLineLayersFromRenderCache() {
        let hasVectorSource = false;
        for (const source of this._style._getSources()) {
            if (source instanceof VectorTileSource) {
                hasVectorSource = true;
                break;
            }
        }

        if (!hasVectorSource) return;

        const clearSourceCaches = {};
        for (let i = 0; i < this._style.order.length; ++i) {
            const layer = this._style._layers[this._style.order[i]];
            const sourceCache = this._style._getLayerSourceCache(layer);
            if (!sourceCache || clearSourceCaches[sourceCache.id]) continue;

            const isHidden = layer.isHidden(this.painter.transform.zoom);
            if (isHidden || layer.type !== 'line') continue;

            // Check if layer has a zoom dependent "line-width" expression
            const widthExpression = ((layer     )                ).widthExpression();
            if (!(widthExpression instanceof index.ZoomDependentExpression)) continue;

            // Mark sourceCache as cleared
            clearSourceCaches[sourceCache.id] = true;
            for (const proxy of this.proxyCoords) {
                const proxiedCoords = this.proxyToSource[proxy.key][sourceCache.id];
                const coords = ((proxiedCoords     )                         );
                if (!coords) continue;

                for (const coord of coords) {
                    this._clearRenderCacheForTile(sourceCache.id, coord);
                }
            }
        }
    }

    _clearRasterLayersFromRenderCache() {
        let hasRasterSource = false;
        for (const id in this._style._sourceCaches) {
            if (this._style._sourceCaches[id]._source instanceof RasterTileSource) {
                hasRasterSource = true;
                break;
            }
        }

        if (!hasRasterSource) return;

        const clearSourceCaches = {};
        for (let i = 0; i < this._style.order.length; ++i) {
            const layer = this._style._layers[this._style.order[i]];
            const sourceCache = this._style._getLayerSourceCache(layer);
            if (!sourceCache || clearSourceCaches[sourceCache.id]) continue;

            const isHidden = layer.isHidden(this.painter.transform.zoom);
            if (isHidden || layer.type !== 'raster') continue;

            // Check if any raster tile is in a fading state
            const fadeDuration = ((layer     )                  ).paint.get('raster-fade-duration');
            for (const proxy of this.proxyCoords) {
                const proxiedCoords = this.proxyToSource[proxy.key][sourceCache.id];
                const coords = ((proxiedCoords     )                         );
                if (!coords) continue;

                for (const coord of coords) {
                    const tile = sourceCache.getTile(coord);
                    const parent = sourceCache.findLoadedParent(coord, 0);
                    const fade = rasterFade(tile, parent, sourceCache, this.painter.transform, fadeDuration);
                    const isFading = fade.opacity !== 1 || fade.mix !== 0;
                    if (isFading) {
                        this._clearRenderCacheForTile(sourceCache.id, coord);
                    }
                }
            }
        }
    }

    _setupDrapedRenderBatches() {
        const layerIds = this._style.order;
        const layerCount = layerIds.length;
        if (layerCount === 0) {
            return;
        }

        const batches                     = [];

        let currentLayer = 0;
        let layer = this._style._layers[layerIds[currentLayer]];
        while (!this._style.isLayerDraped(layer) && layer.isHidden(this.painter.transform.zoom) && ++currentLayer < layerCount) {
            layer = this._style._layers[layerIds[currentLayer]];
        }

        let batchStart               ;
        for (; currentLayer < layerCount; ++currentLayer) {
            const layer = this._style._layers[layerIds[currentLayer]];
            if (layer.isHidden(this.painter.transform.zoom)) {
                continue;
            }
            if (!this._style.isLayerDraped(layer)) {
                if (batchStart !== undefined) {
                    batches.push({start: batchStart, end: currentLayer - 1});
                    batchStart = undefined;
                }
                continue;
            }
            if (batchStart === undefined) {
                batchStart = currentLayer;
            }
        }

        if (batchStart !== undefined) {
            batches.push({start: batchStart, end: currentLayer - 1});
        }

        if (this._style.map._optimizeForTerrain) {
            // Draped first approach should result in a single or no batch
            index.assert(batches.length === 1 || batches.length === 0);
        }

        this._drapedRenderBatches = batches;
    }

    _setupRenderCache(previousProxyToSource                                              ) {
        const psc = this.proxySourceCache;
        if (this._shouldDisableRenderCache() || this._invalidateRenderCache) {
            this._invalidateRenderCache = false;
            if (psc.renderCache.length > psc.renderCachePool.length) {
                const used = ((Object.values(psc.proxyCachedFBO)     )                                    );
                psc.proxyCachedFBO = {};
                for (let i = 0; i < used.length; ++i) {
                    const fbos = ((Object.values(used[i])     )               );
                    psc.renderCachePool.push(...fbos);
                }
                index.assert(psc.renderCache.length === psc.renderCachePool.length);
            }
            return;
        }

        this._clearRasterLayersFromRenderCache();

        const coords = this.proxyCoords;
        const dirty = this._tilesDirty;
        for (let i = coords.length - 1; i >= 0; i--) {
            const proxy = coords[i];
            const tile = psc.getTileByID(proxy.key);

            if (psc.proxyCachedFBO[proxy.key] !== undefined) {
                index.assert(tile.texture);
                const prev = previousProxyToSource[proxy.key];
                index.assert(prev);
                // Reuse previous render from cache if there was no change of
                // content that was used to render proxy tile.
                const current = this.proxyToSource[proxy.key];
                let equal = 0;
                for (const source in current) {
                    const tiles = current[source];
                    const prevTiles = prev[source];
                    if (!prevTiles || prevTiles.length !== tiles.length ||
                        tiles.some((t, index) =>
                            (t !== prevTiles[index] ||
                            (dirty[source] && dirty[source].hasOwnProperty(t.key)
                            )))
                    ) {
                        equal = -1;
                        break;
                    }
                    ++equal;
                }
                // dirty === false: doesn't need to be rendered to, just use cached render.
                for (const proxyFBO in psc.proxyCachedFBO[proxy.key]) {
                    psc.renderCache[psc.proxyCachedFBO[proxy.key][proxyFBO]].dirty = equal < 0 || equal !== Object.values(prev).length;
                }
            }
        }

        const sortedRenderBatches = [...this._drapedRenderBatches];
        sortedRenderBatches.sort((batchA, batchB) => {
            const batchASize = batchA.end - batchA.start;
            const batchBSize = batchB.end - batchB.start;
            return batchBSize - batchASize;
        });

        for (const batch of sortedRenderBatches) {
            for (const id of coords) {
                if (psc.proxyCachedFBO[id.key]) {
                    continue;
                }

                // Assign renderCache FBO if there are available FBOs in pool.
                let index = psc.renderCachePool.pop();
                if (index === undefined && psc.renderCache.length < RENDER_CACHE_MAX_SIZE) {
                    index = psc.renderCache.length;
                    psc.renderCache.push(this._createFBO());
                }
                if (index !== undefined) {
                    psc.proxyCachedFBO[id.key] = {};
                    psc.proxyCachedFBO[id.key][batch.start] = index;
                    psc.renderCache[index].dirty = true; // needs to be rendered to.
                }
            }
        }
        this._tilesDirty = {};
    }

    _setupStencil(fbo     , proxiedCoords                      , layer            , sourceCache              ) {
        if (!sourceCache || !this._sourceTilesOverlap[sourceCache.id]) {
            if (this._overlapStencilType) this._overlapStencilType = false;
            return;
        }
        const context = this.painter.context;
        const gl = context.gl;

        // If needed, setup stencilling. Don't bother to remove when there is no
        // more need: in such case, if there is no overlap, stencilling is disabled.
        if (proxiedCoords.length <= 1) { this._overlapStencilType = false; return; }

        let stencilRange;
        if (layer.isTileClipped()) {
            stencilRange = proxiedCoords.length;
            this._overlapStencilMode.test = {func: gl.EQUAL, mask: 0xFF};
            this._overlapStencilType = 'Clip';
        } else if (proxiedCoords[0].overscaledZ > proxiedCoords[proxiedCoords.length - 1].overscaledZ) {
            stencilRange = 1;
            this._overlapStencilMode.test = {func: gl.GREATER, mask: 0xFF};
            this._overlapStencilType = 'Mask';
        } else {
            this._overlapStencilType = false;
            return;
        }
        if (this._stencilRef + stencilRange > 255) {
            context.clear({stencil: 0});
            this._stencilRef = 0;
        }
        this._stencilRef += stencilRange;
        this._overlapStencilMode.ref = this._stencilRef;
        if (layer.isTileClipped()) {
            this._renderTileClippingMasks(proxiedCoords, this._overlapStencilMode.ref);
        }
    }

    clipOrMaskOverlapStencilType()          {
        return this._overlapStencilType === 'Clip' || this._overlapStencilType === 'Mask';
    }

    stencilModeForRTTOverlap(id                  )                         {
        if (!this.renderingToTexture || !this._overlapStencilType) {
            return index.StencilMode.disabled;
        }
        // All source tiles contributing to the same proxy are processed in sequence, in zoom descending order.
        // For raster / hillshade overlap masking, ref is based on zoom dif.
        // For vector layer clipping, every tile gets dedicated stencil ref.
        if (this._overlapStencilType === 'Clip') {
            // In immediate 2D mode, we render rects to mark clipping area and handle behavior on tile borders.
            // Here, there is no need for now for this:
            // 1. overlap is handled by proxy render to texture tiles (there is no overlap there)
            // 2. here we handle only brief zoom out semi-transparent color intensity flickering
            //    and that is avoided fine by stenciling primitives as part of drawing (instead of additional tile quad step).
            this._overlapStencilMode.ref = this.painter._tileClippingMaskIDs[id.key];
        } // else this._overlapStencilMode.ref is set to a single value used per proxy tile, in _setupStencil.
        return this._overlapStencilMode;
    }

    _renderTileClippingMasks(proxiedCoords                      , ref        ) {
        const painter = this.painter;
        const context = this.painter.context;
        const gl = context.gl;
        painter._tileClippingMaskIDs = {};
        context.setColorMode(index.ColorMode.disabled);
        context.setDepthMode(index.DepthMode.disabled);

        const program = painter.useProgram('clippingMask');

        for (const tileID of proxiedCoords) {
            const id = painter._tileClippingMaskIDs[tileID.key] = --ref;
            program.draw(context, gl.TRIANGLES, index.DepthMode.disabled,
                // Tests will always pass, and ref value will be written to stencil buffer.
                new index.StencilMode({func: gl.ALWAYS, mask: 0}, id, 0xFF, gl.KEEP, gl.KEEP, gl.REPLACE),
                index.ColorMode.disabled, index.CullFaceMode.disabled, clippingMaskUniformValues(tileID.projMatrix),
                '$clipping', painter.tileExtentBuffer,
                painter.quadTriangleIndexBuffer, painter.tileExtentSegments);
        }
    }

    // Casts a ray from a point on screen and returns the intersection point with the terrain.
    // The returned point contains the mercator coordinates in its first 3 components, and elevation
    // in meter in its 4th coordinate.
    pointCoordinate(screenPoint       )        {
        const transform = this.painter.transform;
        if (screenPoint.x < 0 || screenPoint.x > transform.width ||
            screenPoint.y < 0 || screenPoint.y > transform.height) {
            return null;
        }

        const far = [screenPoint.x, screenPoint.y, 1, 1];
        index.transformMat4$1(far, far, transform.pixelMatrixInverse);
        index.scale$2(far, far, 1.0 / far[3]);
        // x & y in pixel coordinates, z is altitude in meters
        far[0] /= transform.worldSize;
        far[1] /= transform.worldSize;
        const camera = transform._camera.position;
        const mercatorZScale = index.mercatorZfromAltitude(1, transform.center.lat);
        const p = [camera[0], camera[1], camera[2] / mercatorZScale, 0.0];
        const dir = index.subtract([], far.slice(0, 3), p);
        index.normalize(dir, dir);

        const exaggeration = this._exaggeration;
        const distanceAlongRay = this.raycast(p, dir, exaggeration);

        if (distanceAlongRay === null || !distanceAlongRay) return null;
        index.scaleAndAdd(p, p, dir, distanceAlongRay);
        p[3] = p[2];
        p[2] *= mercatorZScale;
        return p;
    }

    drawDepth() {
        const painter = this.painter;
        const context = painter.context;
        const psc = this.proxySourceCache;

        const width = Math.ceil(painter.width), height = Math.ceil(painter.height);
        if (this._depthFBO && (this._depthFBO.width !== width || this._depthFBO.height !== height)) {
            this._depthFBO.destroy();
            this._depthFBO = undefined;
            this._depthTexture = undefined;
        }
        if (!this._depthFBO) {
            const gl = context.gl;
            const fbo = context.createFramebuffer(width, height, true);
            context.activeTexture.set(gl.TEXTURE0);
            const texture = new index.Texture(context, {width, height, data: null}, gl.RGBA);
            texture.bind(gl.NEAREST, gl.CLAMP_TO_EDGE);
            fbo.colorAttachment.set(texture.texture);
            const renderbuffer = context.createRenderbuffer(context.gl.DEPTH_COMPONENT16, width, height);
            fbo.depthAttachment.set(renderbuffer);
            this._depthFBO = fbo;
            this._depthTexture = texture;
        }
        context.bindFramebuffer.set(this._depthFBO.framebuffer);
        context.viewport.set([0, 0, width, height]);

        drawTerrainDepth(painter, this, psc, this.proxyCoords);
    }

    _setupProxiedCoordsForOrtho(sourceCache             , sourceCoords                         , previousProxyToSource                                              )       {
        if (sourceCache.getSource() instanceof ImageSource) {
            return this._setupProxiedCoordsForImageSource(sourceCache, sourceCoords, previousProxyToSource);
        }
        this._findCoveringTileCache[sourceCache.id] = this._findCoveringTileCache[sourceCache.id] || {};
        const coords = this.proxiedCoords[sourceCache.id] = [];
        const proxys = this.proxyCoords;
        for (let i = 0; i < proxys.length; i++) {
            const proxyTileID = proxys[i];
            const proxied = this._findTileCoveringTileID(proxyTileID, sourceCache);
            if (proxied) {
                index.assert(proxied.hasData());
                const id = this._createProxiedId(proxyTileID, proxied, previousProxyToSource[proxyTileID.key] && previousProxyToSource[proxyTileID.key][sourceCache.id]);
                coords.push(id);
                this.proxyToSource[proxyTileID.key][sourceCache.id] = [id];
            }
        }
        let hasOverlap = false;
        for (let i = 0; i < sourceCoords.length; i++) {
            const tile = sourceCache.getTile(sourceCoords[i]);
            if (!tile || !tile.hasData()) continue;
            const proxy = this._findTileCoveringTileID(tile.tileID, this.proxySourceCache);
            // Don't add the tile if already added in loop above.
            if (proxy && proxy.tileID.canonical.z !== tile.tileID.canonical.z) {
                const array = this.proxyToSource[proxy.tileID.key][sourceCache.id];
                const id = this._createProxiedId(proxy.tileID, tile, previousProxyToSource[proxy.tileID.key] && previousProxyToSource[proxy.tileID.key][sourceCache.id]);
                if (!array) {
                    this.proxyToSource[proxy.tileID.key][sourceCache.id] = [id];
                } else {
                    // The last element is parent added in loop above. This way we get
                    // a list in Z descending order which is needed for stencil masking.
                    array.splice(array.length - 1, 0, id);
                }
                coords.push(id);
                hasOverlap = true;
            }
        }
        this._sourceTilesOverlap[sourceCache.id] = hasOverlap;
    }

    _setupProxiedCoordsForImageSource(sourceCache             , sourceCoords                         , previousProxyToSource                                              ) {
        if (!sourceCache.getSource().loaded()) return;

        const coords = this.proxiedCoords[sourceCache.id] = [];
        const proxys = this.proxyCoords;
        const imageSource              = ((sourceCache.getSource()     )             );

        const anchor = new index.Point(imageSource.tileID.x, imageSource.tileID.y)._div(1 << imageSource.tileID.z);
        // $FlowFixMe[method-unbinding]
        const aabb = imageSource.coordinates.map(index.MercatorCoordinate.fromLngLat).reduce((acc, coord) => {
            acc.min.x = Math.min(acc.min.x, coord.x - anchor.x);
            acc.min.y = Math.min(acc.min.y, coord.y - anchor.y);
            acc.max.x = Math.max(acc.max.x, coord.x - anchor.x);
            acc.max.y = Math.max(acc.max.y, coord.y - anchor.y);
            return acc;
        }, {min: new index.Point(Number.MAX_VALUE, Number.MAX_VALUE), max: new index.Point(-Number.MAX_VALUE, -Number.MAX_VALUE)});

        // Fast conservative check using aabb: content outside proxy tile gets clipped out by on render, anyway.
        const tileOutsideImage = (tileID                  , imageTileID                  ) => {
            const x = tileID.wrap + tileID.canonical.x / (1 << tileID.canonical.z);
            const y = tileID.canonical.y / (1 << tileID.canonical.z);
            const d = index.EXTENT / (1 << tileID.canonical.z);

            const ix = imageTileID.wrap + imageTileID.canonical.x / (1 << imageTileID.canonical.z);
            const iy = imageTileID.canonical.y / (1 << imageTileID.canonical.z);

            return x + d < ix + aabb.min.x || x > ix + aabb.max.x || y + d < iy + aabb.min.y || y > iy + aabb.max.y;
        };

        for (let i = 0; i < proxys.length; i++) {
            const proxyTileID = proxys[i];
            for (let j = 0; j < sourceCoords.length; j++) {
                const tile = sourceCache.getTile(sourceCoords[j]);
                if (!tile || !tile.hasData()) continue;

                // Setup proxied -> proxy mapping only if image on given tile wrap intersects the proxy tile.
                if (tileOutsideImage(proxyTileID, tile.tileID)) continue;

                const id = this._createProxiedId(proxyTileID, tile, previousProxyToSource[proxyTileID.key] && previousProxyToSource[proxyTileID.key][sourceCache.id]);
                const array = this.proxyToSource[proxyTileID.key][sourceCache.id];
                if (!array) {
                    this.proxyToSource[proxyTileID.key][sourceCache.id] = [id];
                } else {
                    array.push(id);
                }
                coords.push(id);
            }
        }
    }

    // recycle is previous pass content that likely contains proxied ID combining proxy and source tile.
    _createProxiedId(proxyTileID                  , tile      , recycle                      )                {
        let matrix = this.orthoMatrix;
        if (recycle) {
            const recycled = recycle.find(proxied => (proxied.key === tile.tileID.key));
            if (recycled) return recycled;
        }
        if (tile.tileID.key !== proxyTileID.key) {
            const scale = proxyTileID.canonical.z - tile.tileID.canonical.z;
            matrix = index.create();
            let size, xOffset, yOffset;
            const wrap = (tile.tileID.wrap - proxyTileID.wrap) << proxyTileID.overscaledZ;
            if (scale > 0) {
                size = index.EXTENT >> scale;
                xOffset = size * ((tile.tileID.canonical.x << scale) - proxyTileID.canonical.x + wrap);
                yOffset = size * ((tile.tileID.canonical.y << scale) - proxyTileID.canonical.y);
            } else {
                size = index.EXTENT << -scale;
                xOffset = index.EXTENT * (tile.tileID.canonical.x - ((proxyTileID.canonical.x + wrap) << -scale));
                yOffset = index.EXTENT * (tile.tileID.canonical.y - (proxyTileID.canonical.y << -scale));
            }
            index.ortho(matrix, 0, size, 0, size, 0, 1);
            index.translate(matrix, matrix, [xOffset, yOffset, 0]);
        }
        return new ProxiedTileID(tile.tileID, proxyTileID.key, matrix);
    }

    // A variant of SourceCache.findLoadedParent that considers only visible
    // tiles (and doesn't check SourceCache._cache). Another difference is in
    // caching "not found" results along the lookup, to leave the lookup early.
    // Not found is cached by this._findCoveringTileCache[key] = null;
    _findTileCoveringTileID(tileID                  , sourceCache             )        {
        let tile        = sourceCache.getTile(tileID);
        if (tile && tile.hasData()) return tile;

        const lookup = this._findCoveringTileCache[sourceCache.id];
        const key = lookup[tileID.key];
        tile = key ? sourceCache.getTileByID(key) : null;
        if ((tile && tile.hasData()) || key === null) return tile;

        index.assert(!key || tile);

        let sourceTileID = tile ? tile.tileID : tileID;
        let z = sourceTileID.overscaledZ;
        const minzoom = sourceCache.getSource().minzoom;
        const path = [];
        if (!key) {
            const maxzoom = sourceCache.getSource().maxzoom;
            if (tileID.canonical.z >= maxzoom) {
                const downscale = tileID.canonical.z - maxzoom;
                if (sourceCache.getSource().reparseOverscaled) {
                    z = Math.max(tileID.canonical.z + 2, sourceCache.transform.tileZoom);
                    sourceTileID = new index.OverscaledTileID(z, tileID.wrap, maxzoom,
                        tileID.canonical.x >> downscale, tileID.canonical.y >> downscale);
                } else if (downscale !== 0) {
                    z = maxzoom;
                    sourceTileID = new index.OverscaledTileID(z, tileID.wrap, maxzoom,
                        tileID.canonical.x >> downscale, tileID.canonical.y >> downscale);
                }
            }
            if (sourceTileID.key !== tileID.key) {
                path.push(sourceTileID.key);
                tile = sourceCache.getTile(sourceTileID);
            }
        }

        const pathToLookup = (key         ) => {
            path.forEach(id => { lookup[id] = key; });
            path.length = 0;
        };

        for (z = z - 1; z >= minzoom && !(tile && tile.hasData()); z--) {
            if (tile) {
                pathToLookup(tile.tileID.key); // Store lookup to parents not loaded (yet).
            }
            const id = sourceTileID.calculateScaledKey(z);
            tile = sourceCache.getTileByID(id);
            if (tile && tile.hasData()) break;
            const key = lookup[id];
            if (key === null) {
                break; // There's no tile loaded and no point searching further.
            } else if (key !== undefined) {
                tile = sourceCache.getTileByID(key);
                index.assert(tile);
                continue;
            }
            path.push(id);
        }

        pathToLookup(tile ? tile.tileID.key : null);
        return tile && tile.hasData() ? tile : null;
    }

    findDEMTileFor(tileID                  )        {
        return this.enabled ? this._findTileCoveringTileID(tileID, this.sourceCache) : null;
    }

    /*
     * Bookkeeping if something gets rendered to the tile.
     */
    prepareDrawTile() {
        this.renderedToTile = true;
    }

    _clearRenderCacheForTile(source        , coord                  ) {
        let sourceTiles = this._tilesDirty[source];
        if (!sourceTiles) sourceTiles = this._tilesDirty[source] = {};
        sourceTiles[coord.key] = true;
    }

    /*
     * Lazily instantiate the wireframe index buffer and segment vector so that we don't
     * allocate the geometry for rendering a debug wireframe until it's needed.
     */
    getWirefameBuffer()                               {
        if (!this.wireframeSegments) {
            const wireframeGridIndices = createWireframeGrid(GRID_DIM + 1);
            this.wireframeIndexBuffer = this.painter.context.createIndexBuffer(wireframeGridIndices);
            this.wireframeSegments = index.SegmentVector.simpleSegment(0, 0, this.gridBuffer.length, wireframeGridIndices.length);
        }
        return [this.wireframeIndexBuffer, this.wireframeSegments];
    }

}

function sortByDistanceToCamera(tileIDs                         , painter         ) {
    const cameraCoordinate = painter.transform.pointCoordinate(painter.transform.getCameraPoint());
    const cameraPoint = new index.Point(cameraCoordinate.x, cameraCoordinate.y);
    tileIDs.sort((a, b) => {
        if (b.overscaledZ - a.overscaledZ) return b.overscaledZ - a.overscaledZ;
        const aPoint = new index.Point(a.canonical.x + (1 << a.canonical.z) * a.wrap, a.canonical.y);
        const bPoint = new index.Point(b.canonical.x + (1 << b.canonical.z) * b.wrap, b.canonical.y);
        const cameraScaled = cameraPoint.mult(1 << a.canonical.z);
        cameraScaled.x -= 0.5;
        cameraScaled.y -= 0.5;
        return cameraScaled.distSqr(aPoint) - cameraScaled.distSqr(bPoint);
    });
}

/**
 * Creates uniform grid of triangles, covering EXTENT x EXTENT square, with two
 * adjustent traigles forming a quad, so that there are |count| columns and rows
 * of these quads in EXTENT x EXTENT square.
 * e.g. for count of 2:
 *  -------------
 *  |    /|    /|
 *  |  /  |  /  |
 *  |/    |/    |
 *  -------------
 *  |    /|    /|
 *  |  /  |  /  |
 *  |/    |/    |
 *  -------------
 * @param {number} count Count of rows and columns
 * @private
 */
function createGrid(count        )                                         {
    const boundsArray = new index.StructArrayLayout2i4();
    // Around the grid, add one more row/column padding for "skirt".
    const indexArray = new index.StructArrayLayout3ui6();
    const size = count + 2;
    boundsArray.reserve(size * size);
    indexArray.reserve((size - 1) * (size - 1) * 2);
    const step = index.EXTENT / (count - 1);
    const gridBound = index.EXTENT + step / 2;
    const bound = gridBound + step;

    // Skirt offset of 0x5FFF is chosen randomly to encode boolean value (skirt
    // on/off) with x position (max value EXTENT = 4096) to 16-bit signed integer.
    const skirtOffset = 24575; // 0x5FFF
    for (let y = -step; y < bound; y += step) {
        for (let x = -step; x < bound; x += step) {
            const offset = (x < 0 || x > gridBound || y < 0 || y > gridBound) ? skirtOffset : 0;
            const xi = index.clamp(Math.round(x), 0, index.EXTENT);
            const yi = index.clamp(Math.round(y), 0, index.EXTENT);
            boundsArray.emplaceBack(xi + offset, yi);
        }
    }

    // For cases when there's no need to render "skirt", the "inner" grid indices
    // are followed by skirt indices.
    const skirtIndicesOffset = (size - 3) * (size - 3) * 2;
    const quad = (i        , j        ) => {
        const index = j * size + i;
        indexArray.emplaceBack(index + 1, index, index + size);
        indexArray.emplaceBack(index + size, index + size + 1, index + 1);
    };
    for (let j = 1; j < size - 2; j++) {
        for (let i = 1; i < size - 2; i++) {
            quad(i, j);
        }
    }
    // Padding (skirt) indices:
    [0, size - 2].forEach(j => {
        for (let i = 0; i < size - 1; i++) {
            quad(i, j);
            quad(j, i);
        }
    });
    return [boundsArray, indexArray, skirtIndicesOffset];
}

/**
 * Creates a grid of indices corresponding to the grid constructed by createGrid
 * in order to render that grid as a wireframe rather than a solid  mesh. It does
 * not create a skirt and so only goes from 1 to count + 1, e.g. for count of 2:
 *  -------------
 *  |    /|    /|
 *  |  /  |  /  |
 *  |/    |/    |
 *  -------------
 *  |    /|    /|
 *  |  /  |  /  |
 *  |/    |/    |
 *  -------------
 * @param {number} count Count of rows and columns
 * @private
 */
function createWireframeGrid(count        )                 {
    let index$1 = 0;
    const indexArray = new index.StructArrayLayout2ui4();
    const size = count + 2;
    // Draw two edges of a quad and its diagonal. The very last row and column have
    // an additional line to close off the grid.
    for (let j = 1; j < count; j++) {
        for (let i = 1; i < count; i++) {
            index$1 = j * size + i;
            indexArray.emplaceBack(index$1, index$1 + 1);
            indexArray.emplaceBack(index$1, index$1 + size);
            indexArray.emplaceBack(index$1 + 1, index$1 + size);

            // Place an extra line at the end of each row
            if (j === count - 1) indexArray.emplaceBack(index$1 + size, index$1 + size + 1);
        }
        // Place an extra line at the end of each col
        indexArray.emplaceBack(index$1 + 1, index$1 + 1 + size);
    }
    return indexArray;
}

                                    
                       
                            
                              
                          
                             
                               
                                  
                            
                            
                                
                         
                                  
                                 
                                                 
   

const terrainUniforms = (context         )                      => ({
    'u_dem': new index.Uniform1i(context),
    'u_dem_prev': new index.Uniform1i(context),
    'u_dem_unpack': new index.Uniform4f(context),
    'u_dem_tl': new index.Uniform2f(context),
    'u_dem_scale': new index.Uniform1f(context),
    'u_dem_tl_prev': new index.Uniform2f(context),
    'u_dem_scale_prev': new index.Uniform1f(context),
    'u_dem_size': new index.Uniform1f(context),
    'u_dem_lerp': new index.Uniform1f(context),
    'u_exaggeration': new index.Uniform1f(context),
    'u_depth': new index.Uniform1i(context),
    'u_depth_size_inv': new index.Uniform2f(context),
    'u_meter_to_dem': new index.Uniform1f(context),
    'u_label_plane_matrix_inv': new index.UniformMatrix4f(context),
});

function defaultTerrainUniforms(encoding             )                                     {
    return {
        'u_dem': 2,
        'u_dem_prev': 4,
        'u_dem_unpack': index.DEMData.getUnpackVector(encoding),
        'u_dem_tl': [0, 0],
        'u_dem_tl_prev': [0, 0],
        'u_dem_scale': 0,
        'u_dem_scale_prev': 0,
        'u_dem_size': 0,
        'u_dem_lerp': 1.0,
        'u_depth': 3,
        'u_depth_size_inv': [0, 0],
        'u_exaggeration': 0,
    };
}

                                  
                              
                              
                              
                              
                                
   

const globeUniforms = (context         )                    => ({
    'u_tile_tl_up': new index.Uniform3f(context),
    'u_tile_tr_up': new index.Uniform3f(context),
    'u_tile_br_up': new index.Uniform3f(context),
    'u_tile_bl_up': new index.Uniform3f(context),
    'u_tile_up_scale': new index.Uniform1f(context)
});

//      


                                
                                    
                             
                             
                                     
                                       
                              
                              
                              
                              
                             
                                
                                    
                            
                            
   

const fogUniforms = (context         )                  => ({
    'u_fog_matrix': new index.UniformMatrix4f(context),
    'u_fog_range': new index.Uniform2f(context),
    'u_fog_color': new index.Uniform4f(context),
    'u_fog_horizon_blend': new index.Uniform1f(context),
    'u_fog_temporal_offset': new index.Uniform1f(context),
    'u_frustum_tl': new index.Uniform3f(context),
    'u_frustum_tr': new index.Uniform3f(context),
    'u_frustum_br': new index.Uniform3f(context),
    'u_frustum_bl': new index.Uniform3f(context),
    'u_globe_pos': new index.Uniform3f(context),
    'u_globe_radius': new index.Uniform1f(context),
    'u_globe_transition': new index.Uniform1f(context),
    'u_is_globe': new index.Uniform1i(context),
    'u_viewport': new index.Uniform2f(context)
});

const fogUniformValues = (
    painter         ,
    fog     ,
    tileID                  ,
    fogOpacity        ,
    frustumDirTl                          ,
    frustumDirTr                          ,
    frustumDirBr                          ,
    frustumDirBl                          ,
    globePosition                          ,
    globeRadius        ,
    viewport                  
)                                 => {
    const tr = painter.transform;
    const fogColor = fog.properties.get('color').toArray01();
    fogColor[3] = fogOpacity; // Update Alpha
    const temporalOffset = (painter.frameCounter / 1000.0) % 1;
    return {
        'u_fog_matrix': tileID ? tr.calculateFogTileMatrix(tileID) : painter.identityMat,
        'u_fog_range': fog.getFovAdjustedRange(tr._fov),
        'u_fog_color': fogColor,
        'u_fog_horizon_blend': fog.properties.get('horizon-blend'),
        'u_fog_temporal_offset': temporalOffset,
        'u_frustum_tl': frustumDirTl,
        'u_frustum_tr': frustumDirTr,
        'u_frustum_br': frustumDirBr,
        'u_frustum_bl': frustumDirBl,
        'u_globe_pos': globePosition,
        'u_globe_radius': globeRadius,
        'u_viewport': viewport,
        'u_globe_transition': index.globeToMercatorTransition(tr.zoom),
        'u_is_globe': +(tr.projection.name === 'globe')
    };
};

//      

                                              

                                                    
                                                       
                                                     
                                                 
                                                     
                                                 
                                                        
                                                                         
                                                                    

                      
                                                   
                                                       
                                                         

                     
                           
                         
                                    
                              
  

function getTokenizedAttributes(array               )                {
    const result = [];

    for (let i = 0; i < array.length; i++) {
        if (array[i] === null) continue;
        const token = array[i].split(' ');
        result.push(token.pop());
    }
    return result;
}

class Program                      {
                          
                                      
                          
                      
                                         
                            
                                          
                                  
                                      

    static cacheKey(source              , name        , defines          , programConfiguration                       )         {
        let key = `${name}${programConfiguration ? programConfiguration.cacheKey : ''}`;
        for (const define of defines) {
            if (source.usedDefines.includes(define)) {
                key += `/${define}`;
            }
        }
        return key;
    }

    constructor(context         ,
                name        ,
                source              ,
                configuration                       ,
                fixedUniforms                 ,
                fixedDefines          ) {
        const gl = context.gl;
        this.program = ((gl.createProgram()     )              );

        const staticAttrInfo = getTokenizedAttributes(source.staticAttributes);
        const dynamicAttrInfo = configuration ? configuration.getBinderAttributes() : [];
        const allAttrInfo = staticAttrInfo.concat(dynamicAttrInfo);

        let defines = configuration ? configuration.defines() : [];
        defines = defines.concat(fixedDefines.map((define) => `#define ${define}`));
        const version = context.isWebGL2 ? '#version 300 es\n' : '';

        const fragmentSource = version + defines.concat(
            context.extStandardDerivatives && version.length === 0 ? standardDerivativesExt.concat(preludeFragPrecisionQualifiers) : preludeFragPrecisionQualifiers,
            preludeFragPrecisionQualifiers,
            preludeCommonSource,
            prelude.fragmentSource,
            preludeFog.fragmentSource,
            source.fragmentSource).join('\n');
        const vertexSource = version + defines.concat(
            preludeVertPrecisionQualifiers,
            preludeCommonSource,
            prelude.vertexSource,
            preludeFog.vertexSource,
            preludeTerrain.vertexSource,
            source.vertexSource).join('\n');

        const fragmentShader = ((gl.createShader(gl.FRAGMENT_SHADER)     )             );
        if (gl.isContextLost()) {
            this.failedToCreate = true;
            return;
        }
        gl.shaderSource(fragmentShader, fragmentSource);
        gl.compileShader(fragmentShader);
        index.assert(gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS), (gl.getShaderInfoLog(fragmentShader)     ));
        gl.attachShader(this.program, fragmentShader);

        const vertexShader = ((gl.createShader(gl.VERTEX_SHADER)     )             );
        if (gl.isContextLost()) {
            this.failedToCreate = true;
            return;
        }
        gl.shaderSource(vertexShader, vertexSource);
        gl.compileShader(vertexShader);
        index.assert(gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS), (gl.getShaderInfoLog(vertexShader)     ));
        gl.attachShader(this.program, vertexShader);

        this.attributes = {};

        this.numAttributes = allAttrInfo.length;

        for (let i = 0; i < this.numAttributes; i++) {
            if (allAttrInfo[i]) {
                gl.bindAttribLocation(this.program, i, allAttrInfo[i]);
                this.attributes[allAttrInfo[i]] = i;
            }
        }

        gl.linkProgram(this.program);
        index.assert(gl.getProgramParameter(this.program, gl.LINK_STATUS), (gl.getProgramInfoLog(this.program)     ));

        gl.deleteShader(vertexShader);
        gl.deleteShader(fragmentShader);

        this.fixedUniforms = fixedUniforms(context);
        this.binderUniforms = configuration ? configuration.getUniforms(context) : [];
        if (fixedDefines.includes('TERRAIN')) {
            this.terrainUniforms = terrainUniforms(context);
        }
        if (fixedDefines.includes('GLOBE')) {
            this.globeUniforms = globeUniforms(context);
        }
        if (fixedDefines.includes('FOG')) {
            this.fogUniforms = fogUniforms(context);
        }
    }

    setTerrainUniformValues(context         , terrainUniformValues                                    ) {
        if (!this.terrainUniforms) return;
        const uniforms                      = this.terrainUniforms;

        if (this.failedToCreate) return;
        context.program.set(this.program);

        for (const name in terrainUniformValues) {
            if (uniforms[name]) {
                uniforms[name].set(this.program, name, terrainUniformValues[name]);
            }
        }
    }

    setGlobeUniformValues(context         , globeUniformValues                                  ) {
        if (!this.globeUniforms) return;
        const uniforms                    = this.globeUniforms;

        if (this.failedToCreate) return;
        context.program.set(this.program);

        for (const name in globeUniformValues) {
            if (uniforms[name]) {
                uniforms[name].set(this.program, name, globeUniformValues[name]);
            }
        }
    }

    setFogUniformValues(context         , fogUniformsValues                                ) {
        if (!this.fogUniforms) return;
        const uniforms                  = this.fogUniforms;

        if (this.failedToCreate) return;
        context.program.set(this.program);

        for (const name in fogUniformsValues) {
            uniforms[name].set(this.program, name, fogUniformsValues[name]);
        }
    }

    draw(
         context         ,
         drawMode          ,
         depthMode                      ,
         stencilMode                        ,
         colorMode                      ,
         cullFaceMode                         ,
         uniformValues                   ,
         layerID        ,
         layoutVertexBuffer              ,
         indexBuffer             ,
         segments               ,
         currentProperties     ,
         zoom         ,
         configuration                       ,
         dynamicLayoutBuffers                       ) {

        const gl = context.gl;

        if (this.failedToCreate) return;

        context.program.set(this.program);
        context.setDepthMode(depthMode);
        context.setStencilMode(stencilMode);
        context.setColorMode(colorMode);
        context.setCullFace(cullFaceMode);

        for (const name of Object.keys(this.fixedUniforms)) {
            this.fixedUniforms[name].set(this.program, name, uniformValues[name]);
        }

        if (configuration) {
            configuration.setUniforms(this.program, context, this.binderUniforms, currentProperties, {zoom: (zoom     )});
        }

        const primitiveSize = {
            [gl.LINES]: 2,
            [gl.TRIANGLES]: 3,
            [gl.LINE_STRIP]: 1
        }[drawMode];

        for (const segment of segments.get()) {
            const vaos = segment.vaos || (segment.vaos = {});
            const vao                    = vaos[layerID] || (vaos[layerID] = new VertexArrayObject());

            vao.bind(
                context,
                this,
                layoutVertexBuffer,
                configuration ? configuration.getPaintVertexBuffers() : [],
                indexBuffer,
                segment.vertexOffset,
                dynamicLayoutBuffers ? dynamicLayoutBuffers : []
            );

            gl.drawElements(
                drawMode,
                segment.primitiveLength * primitiveSize,
                gl.UNSIGNED_SHORT,
                segment.primitiveOffset * primitiveSize * 2);
        }
    }
}

//      


                                         
                                                              
                                                         
                                             
                                                                                     

                                       
                         
                              
                              
                           
                                
                                     
                                     
                                       
   

                                    
                         
                           
                                        
                                     
                                    
   

function patternUniformValues(painter         , tile      )                                     {

    const numTiles = Math.pow(2, tile.tileID.overscaledZ);
    const tileSizeAtNearestZoom = tile.tileSize * Math.pow(2, painter.transform.tileZoom) / numTiles;

    const pixelX = tileSizeAtNearestZoom * (tile.tileID.canonical.x + tile.tileID.wrap * numTiles);
    const pixelY = tileSizeAtNearestZoom * tile.tileID.canonical.y;

    return {
        'u_image': 0,
        'u_texsize': tile.imageAtlasTexture.size,
        'u_tile_units_to_pixels': 1 / pixelsToTileUnits(tile, 1, painter.transform.tileZoom),
        // split the pixel coord into two pairs of 16 bit numbers. The glsl spec only guarantees 16 bits of precision.
        'u_pixel_coord_upper': [pixelX >> 16, pixelY >> 16],
        'u_pixel_coord_lower': [pixelX & 0xFFFF, pixelY & 0xFFFF]
    };
}

function bgPatternUniformValues(image               , painter         ,
        tile                                              
)                                               {

    const imagePos = painter.imageManager.getPattern(image.toString());
    index.assert(imagePos);
    const {width, height} = painter.imageManager.getPixelSize();

    const numTiles = Math.pow(2, tile.tileID.overscaledZ);
    const tileSizeAtNearestZoom = tile.tileSize * Math.pow(2, painter.transform.tileZoom) / numTiles;

    const pixelX = tileSizeAtNearestZoom * (tile.tileID.canonical.x + tile.tileID.wrap * numTiles);
    const pixelY = tileSizeAtNearestZoom * tile.tileID.canonical.y;

    return {
        'u_image': 0,
        'u_pattern_tl': (imagePos     ).tl,
        'u_pattern_br': (imagePos     ).br,
        'u_texsize': [width, height],
        'u_pattern_size': (imagePos     ).displaySize,
        'u_tile_units_to_pixels': 1 / pixelsToTileUnits(tile, 1, painter.transform.tileZoom),
        // split the pixel coord into two pairs of 16 bit numbers. The glsl spec only guarantees 16 bits of precision.
        'u_pixel_coord_upper': [pixelX >> 16, pixelY >> 16],
        'u_pixel_coord_lower': [pixelX & 0xFFFF, pixelY & 0xFFFF]
    };
}

//      


                                          
                                
                            
                                  
                              
                                     
                           
                      
                           
                                   
                                        
                               
                          
                               
                      
                              
   

                                                 
                                
                            
                                  
                              
                                 
                                     
                      
                               
                      
                           
                                   
                                        
                               
                          
                               
                        
                           
                         
                                     
                                     
                                        
                          
   

const fillExtrusionUniforms = (context         )                            => ({
    'u_matrix': new index.UniformMatrix4f(context),
    'u_lightpos': new index.Uniform3f(context),
    'u_lightintensity': new index.Uniform1f(context),
    'u_lightcolor': new index.Uniform3f(context),
    'u_vertical_gradient': new index.Uniform1f(context),
    'u_opacity': new index.Uniform1f(context),
    'u_edge_radius': new index.Uniform1f(context),
    'u_ao': new index.Uniform2f(context),
    // globe uniforms:
    'u_tile_id': new index.Uniform3f(context),
    'u_zoom_transition': new index.Uniform1f(context),
    'u_inv_rot_matrix': new index.UniformMatrix4f(context),
    'u_merc_center': new index.Uniform2f(context),
    'u_up_dir': new index.Uniform3f(context),
    'u_height_lift': new index.Uniform1f(context)
});

const fillExtrusionPatternUniforms = (context         )                                   => ({
    'u_matrix': new index.UniformMatrix4f(context),
    'u_lightpos': new index.Uniform3f(context),
    'u_lightintensity': new index.Uniform1f(context),
    'u_lightcolor': new index.Uniform3f(context),
    'u_vertical_gradient': new index.Uniform1f(context),
    'u_height_factor': new index.Uniform1f(context),
    'u_edge_radius': new index.Uniform1f(context),
    'u_ao': new index.Uniform2f(context),
    // globe uniforms:
    'u_tile_id': new index.Uniform3f(context),
    'u_zoom_transition': new index.Uniform1f(context),
    'u_inv_rot_matrix': new index.UniformMatrix4f(context),
    'u_merc_center': new index.Uniform2f(context),
    'u_up_dir': new index.Uniform3f(context),
    'u_height_lift': new index.Uniform1f(context),
    // pattern uniforms
    'u_image': new index.Uniform1i(context),
    'u_texsize': new index.Uniform2f(context),
    'u_pixel_coord_upper': new index.Uniform2f(context),
    'u_pixel_coord_lower': new index.Uniform2f(context),
    'u_tile_units_to_pixels': new index.Uniform1f(context),
    'u_opacity': new index.Uniform1f(context)
});

const identityMatrix$3 = index.create();

const fillExtrusionUniformValues = (
    matrix              ,
    painter         ,
    shouldUseVerticalGradient         ,
    opacity        ,
    aoIntensityRadius                  ,
    edgeRadius        ,
    coord                  ,
    heightLift        ,
    zoomTransition        ,
    mercatorCenter                  ,
    invMatrix              
)                                           => {
    const light = painter.style.light;
    const _lp = light.properties.get('position');
    const lightPos = [_lp.x, _lp.y, _lp.z];
    const lightMat = index.create$1();
    const anchor = light.properties.get('anchor');
    if (anchor === 'viewport') {
        index.fromRotation(lightMat, -painter.transform.angle);
        index.transformMat3(lightPos, lightPos, lightMat);
    }

    const lightColor = light.properties.get('color');
    const tr = painter.transform;

    const uniformValues = {
        'u_matrix': matrix,
        'u_lightpos': lightPos,
        'u_lightintensity': light.properties.get('intensity'),
        'u_lightcolor': [lightColor.r, lightColor.g, lightColor.b],
        'u_vertical_gradient': +shouldUseVerticalGradient,
        'u_opacity': opacity,
        'u_tile_id': [0, 0, 0],
        'u_zoom_transition': 0,
        'u_inv_rot_matrix': identityMatrix$3,
        'u_merc_center': [0, 0],
        'u_up_dir': [0, 0, 0],
        'u_height_lift': 0,
        'u_ao': aoIntensityRadius,
        'u_edge_radius': edgeRadius
    };

    if (tr.projection.name === 'globe') {
        uniformValues['u_tile_id'] = [coord.canonical.x, coord.canonical.y, 1 << coord.canonical.z];
        uniformValues['u_zoom_transition'] = zoomTransition;
        uniformValues['u_inv_rot_matrix'] = invMatrix;
        uniformValues['u_merc_center'] = mercatorCenter;
        uniformValues['u_up_dir'] = (tr.projection.upVector(new index.CanonicalTileID(0, 0, 0), mercatorCenter[0] * index.EXTENT, mercatorCenter[1] * index.EXTENT)     );
        uniformValues['u_height_lift'] = heightLift;
    }

    return uniformValues;
};

const fillExtrusionPatternUniformValues = (
    matrix              ,
    painter         ,
    shouldUseVerticalGradient         ,
    opacity        ,
    aoIntensityRadius                  ,
    edgeRadius        ,
    coord                  ,
    tile      ,
    heightLift        ,
    zoomTransition        ,
    mercatorCenter                  ,
    invMatrix              
)                                                  => {
    const uniformValues = fillExtrusionUniformValues(
        matrix, painter, shouldUseVerticalGradient, opacity, aoIntensityRadius, edgeRadius, coord,
        heightLift, zoomTransition, mercatorCenter, invMatrix);
    const heightFactorUniform = {
        'u_height_factor': -Math.pow(2, coord.overscaledZ) / tile.tileSize / 8
    };
    return index.extend(uniformValues, patternUniformValues(painter, tile), heightFactorUniform);
};

//      


                                         
                                                         
                                               
                                             

                                 
                               
   

                                        
                                
                        
   

                                        
                                
                        
                           
                         
                                     
                                     
                                       
   

                                               
                                
                         
                        
                           
                         
                                     
                                     
                                       
   

const fillUniforms = (context         )                   => ({
    'u_matrix': new index.UniformMatrix4f(context)
});

const fillPatternUniforms = (context         )                          => ({
    'u_matrix': new index.UniformMatrix4f(context),
    'u_image': new index.Uniform1i(context),
    'u_texsize': new index.Uniform2f(context),
    'u_pixel_coord_upper': new index.Uniform2f(context),
    'u_pixel_coord_lower': new index.Uniform2f(context),
    'u_tile_units_to_pixels': new index.Uniform1f(context)

});

const fillOutlineUniforms = (context         )                          => ({
    'u_matrix': new index.UniformMatrix4f(context),
    'u_world': new index.Uniform2f(context)
});

const fillOutlinePatternUniforms = (context         )                                 => ({
    'u_matrix': new index.UniformMatrix4f(context),
    'u_world': new index.Uniform2f(context),
    'u_image': new index.Uniform1i(context),
    'u_texsize': new index.Uniform2f(context),
    'u_pixel_coord_upper': new index.Uniform2f(context),
    'u_pixel_coord_lower': new index.Uniform2f(context),
    'u_tile_units_to_pixels': new index.Uniform1f(context)
});

const fillUniformValues = (matrix              )                                  => ({
    'u_matrix': matrix
});

const fillPatternUniformValues = (
    matrix              ,
    painter         ,
    tile      
)                                         => index.extend(
    fillUniformValues(matrix),
    patternUniformValues(painter, tile)
);

const fillOutlineUniformValues = (
    matrix              ,
    drawingBufferSize                  
)                                         => ({
    'u_matrix': matrix,
    'u_world': drawingBufferSize
});

const fillOutlinePatternUniformValues = (
    matrix              ,
    painter         ,
    tile      ,
    drawingBufferSize                  
)                                                => index.extend(
    fillPatternUniformValues(matrix, painter, tile),
    {
        'u_world': drawingBufferSize
    }
);

//      


                                   
                                             
                                       
                                      
                                
                                        
                               
                           
                                   
                          
   

                                                                                              

const circleUniforms = (context         )                     => ({
    'u_camera_to_center_distance': new index.Uniform1f(context),
    'u_extrude_scale': new index.UniformMatrix2f(context),
    'u_device_pixel_ratio': new index.Uniform1f(context),
    'u_matrix': new index.UniformMatrix4f(context),
    'u_inv_rot_matrix': new index.UniformMatrix4f(context),
    'u_merc_center': new index.Uniform2f(context),
    'u_tile_id': new index.Uniform3f(context),
    'u_zoom_transition': new index.Uniform1f(context),
    'u_up_dir': new index.Uniform3f(context),
});

const identityMatrix$2 = index.create();

const circleUniformValues = (
    painter         ,
    coord                  ,
    tile      ,
    invMatrix              ,
    mercatorCenter                  ,
    layer                  
)                                    => {
    const transform = painter.transform;
    const isGlobe = transform.projection.name === 'globe';

    let extrudeScale;
    if (layer.paint.get('circle-pitch-alignment') === 'map') {
        if (isGlobe) {
            const s = index.globePixelsToTileUnits(transform.zoom, coord.canonical) * transform._pixelsPerMercatorPixel;
            extrudeScale = Float32Array.from([s, 0, 0, s]);
        } else {
            extrudeScale = transform.calculatePixelsToTileUnitsMatrix(tile);
        }
    } else {
        extrudeScale = new Float32Array([
            transform.pixelsToGLUnits[0],
            0,
            0,
            transform.pixelsToGLUnits[1]]);
    }

    const values = {
        'u_camera_to_center_distance': transform.cameraToCenterDistance,
        'u_matrix': painter.translatePosMatrix(
            coord.projMatrix,
            tile,
            layer.paint.get('circle-translate'),
            layer.paint.get('circle-translate-anchor')),
        'u_device_pixel_ratio': index.exported.devicePixelRatio,
        'u_extrude_scale': extrudeScale,
        'u_inv_rot_matrix': identityMatrix$2,
        'u_merc_center': [0, 0],
        'u_tile_id': [0, 0, 0],
        'u_zoom_transition': 0,
        'u_up_dir': [0, 0, 0]
    };

    if (isGlobe) {
        values['u_inv_rot_matrix'] = invMatrix;
        values['u_merc_center'] = mercatorCenter;
        values['u_tile_id'] = [coord.canonical.x, coord.canonical.y, 1 << coord.canonical.z];
        values['u_zoom_transition'] = index.globeToMercatorTransition(transform.zoom);
        const x = mercatorCenter[0] * index.EXTENT;
        const y = mercatorCenter[1] * index.EXTENT;
        values['u_up_dir'] = (transform.projection.upVector(new index.CanonicalTileID(0, 0, 0), x, y)     );
    }

    return values;
};

const circleDefinesValues = (layer                  )                      => {
    const values = [];
    if (layer.paint.get('circle-pitch-alignment') === 'map') values.push('PITCH_WITH_MAP');
    if (layer.paint.get('circle-pitch-scale') === 'map') values.push('SCALE_WITH_MAP');

    return values;
};

//      

                                               
                                                         
                                                    
                                             
                                                                 

                                      
                                
                                             
                                
   

                                            
                                
                                    
                                             
                                
   

const collisionUniforms = (context         )                        => ({
    'u_matrix': new index.UniformMatrix4f(context),
    'u_camera_to_center_distance': new index.Uniform1f(context),
    'u_extrude_scale': new index.Uniform2f(context)
});

const collisionCircleUniforms = (context         )                              => ({
    'u_matrix': new index.UniformMatrix4f(context),
    'u_inv_matrix': new index.UniformMatrix4f(context),
    'u_camera_to_center_distance': new index.Uniform1f(context),
    'u_viewport_size': new index.Uniform2f(context)
});

const collisionUniformValues = (
    matrix              ,
    transform           ,
    tile      ,
    projection            
)                                       => {
    const pixelRatio = index.EXTENT / tile.tileSize;

    return {
        'u_matrix': matrix,
        'u_camera_to_center_distance': transform.getCameraToCenterDistance(projection),
        'u_extrude_scale': [transform.pixelsToGLUnits[0] / pixelRatio,
            transform.pixelsToGLUnits[1] / pixelRatio]
    };
};

const collisionCircleUniformValues = (
    matrix              ,
    invMatrix              ,
    transform           ,
    projection            
)                                             => {
    return {
        'u_matrix': matrix,
        'u_inv_matrix': invMatrix,
        'u_camera_to_center_distance': transform.getCameraToCenterDistance(projection),
        'u_viewport_size': [transform.width, transform.height]
    };
};

//      


                                               
                                                         
                                                        

                                  
                            
                                
                           
                                
   

const debugUniforms = (context         )                    => ({
    'u_color': new index.UniformColor(context),
    'u_matrix': new index.UniformMatrix4f(context),
    'u_overlay': new index.Uniform1i(context),
    'u_overlay_scale':  new index.Uniform1f(context),
});

const debugUniformValues = (matrix              , color       , scaleRatio         = 1)                                   => ({
    'u_matrix': matrix,
    'u_color': color,
    'u_overlay': 0,
    'u_overlay_scale': scaleRatio
});

//      


                                    
                                 
                             
                                
                                        
                               
                           
                                   
                          
   

                                           
                         
                              
                          
   

const heatmapUniforms = (context         )                      => ({
    'u_extrude_scale': new index.Uniform1f(context),
    'u_intensity': new index.Uniform1f(context),
    'u_matrix': new index.UniformMatrix4f(context),
    'u_inv_rot_matrix': new index.UniformMatrix4f(context),
    'u_merc_center': new index.Uniform2f(context),
    'u_tile_id': new index.Uniform3f(context),
    'u_zoom_transition': new index.Uniform1f(context),
    'u_up_dir': new index.Uniform3f(context)
});

const heatmapTextureUniforms = (context         )                             => ({
    'u_image': new index.Uniform1i(context),
    'u_color_ramp': new index.Uniform1i(context),
    'u_opacity': new index.Uniform1f(context)
});

const identityMatrix$1 = index.create();

const heatmapUniformValues = (
    painter         ,
    coord                  ,
    tile      ,
    invMatrix              ,
    mercatorCenter                  ,
    zoom        ,
    intensity        
)                                     => {
    const transform = painter.transform;
    const isGlobe = transform.projection.name === 'globe';
    const extrudeScale = isGlobe ? index.globePixelsToTileUnits(transform.zoom, coord.canonical) * transform._pixelsPerMercatorPixel : pixelsToTileUnits(tile, 1, zoom);

    const values = {
        'u_matrix': coord.projMatrix,
        'u_extrude_scale': extrudeScale,
        'u_intensity': intensity,
        'u_inv_rot_matrix': identityMatrix$1,
        'u_merc_center': [0, 0],
        'u_tile_id': [0, 0, 0],
        'u_zoom_transition': 0,
        'u_up_dir': [0, 0, 0],
    };

    if (isGlobe) {
        values['u_inv_rot_matrix'] = invMatrix;
        values['u_merc_center'] = mercatorCenter;
        values['u_tile_id'] = [coord.canonical.x, coord.canonical.y, 1 << coord.canonical.z];
        values['u_zoom_transition'] = index.globeToMercatorTransition(transform.zoom);
        const x = mercatorCenter[0] * index.EXTENT;
        const y = mercatorCenter[1] * index.EXTENT;
        values['u_up_dir'] = (transform.projection.upVector(new index.CanonicalTileID(0, 0, 0), x, y)     );
    }

    return values;
};

const heatmapTextureUniformValues = (
    painter         ,
    layer                   ,
    textureUnit        ,
    colorRampUnit        
)                                            => {
    return {
        'u_image': textureUnit,
        'u_color_ramp': colorRampUnit,
        'u_opacity': layer.paint.get('heatmap-opacity')
    };
};

//      


                                               
                                                         
                                                    
                                             
                                                                              
                                         

                                 
                                
                                              
                                      
                                   
                              
                                  
                                
                           
                                        
                                           
                              
   

                                        
                                
                           
                                              
                                      
                                   
                         
                                        
                                          
   

                                                                                                                                    

const lineUniforms = (context         )                   => ({
    'u_matrix': new index.UniformMatrix4f(context),
    'u_pixels_to_tile_units': new index.UniformMatrix2f(context),
    'u_device_pixel_ratio': new index.Uniform1f(context),
    'u_units_to_pixels': new index.Uniform2f(context),
    'u_dash_image': new index.Uniform1i(context),
    'u_gradient_image': new index.Uniform1i(context),
    'u_image_height': new index.Uniform1f(context),
    'u_texsize': new index.Uniform2f(context),
    'u_tile_units_to_pixels': new index.Uniform1f(context),
    'u_alpha_discard_threshold': new index.Uniform1f(context),
    'u_trim_offset': new index.Uniform2f(context)
});

const linePatternUniforms = (context         )                          => ({
    'u_matrix': new index.UniformMatrix4f(context),
    'u_texsize': new index.Uniform2f(context),
    'u_pixels_to_tile_units': new index.UniformMatrix2f(context),
    'u_device_pixel_ratio': new index.Uniform1f(context),
    'u_image': new index.Uniform1i(context),
    'u_units_to_pixels': new index.Uniform2f(context),
    'u_tile_units_to_pixels': new index.Uniform1f(context),
    'u_alpha_discard_threshold': new index.Uniform1f(context)
});

const lineUniformValues = (
    painter         ,
    tile      ,
    layer                ,
    matrix               ,
    imageHeight        ,
    pixelRatio        ,
    trimOffset                  ,
)                                  => {
    const transform = painter.transform;
    const pixelsToTileUnits = transform.calculatePixelsToTileUnitsMatrix(tile);
    return {
        'u_matrix': calculateMatrix(painter, tile, layer, matrix),
        'u_pixels_to_tile_units': pixelsToTileUnits,
        'u_device_pixel_ratio': pixelRatio,
        'u_units_to_pixels': [
            1 / transform.pixelsToGLUnits[0],
            1 / transform.pixelsToGLUnits[1]
        ],
        'u_dash_image': 0,
        'u_gradient_image': 1,
        'u_image_height': imageHeight,
        'u_texsize': hasDash(layer) ? tile.lineAtlasTexture.size : [0, 0],
        'u_tile_units_to_pixels': calculateTileRatio(tile, painter.transform),
        'u_alpha_discard_threshold': 0.0,
        'u_trim_offset': trimOffset
    };
};

const linePatternUniformValues = (
    painter         ,
    tile      ,
    layer                ,
    matrix               ,
    pixelRatio        
)                                         => {
    const transform = painter.transform;
    return {
        'u_matrix': calculateMatrix(painter, tile, layer, matrix),
        'u_texsize': tile.imageAtlasTexture.size,
        // camera zoom ratio
        'u_pixels_to_tile_units': transform.calculatePixelsToTileUnitsMatrix(tile),
        'u_device_pixel_ratio': pixelRatio,
        'u_image': 0,
        'u_tile_units_to_pixels': calculateTileRatio(tile, transform),
        'u_units_to_pixels': [
            1 / transform.pixelsToGLUnits[0],
            1 / transform.pixelsToGLUnits[1]
        ],
        'u_alpha_discard_threshold': 0.0
    };
};

function calculateTileRatio(tile      , transform           ) {
    return 1 / pixelsToTileUnits(tile, 1, transform.tileZoom);
}

function calculateMatrix(painter         , tile      , layer                , matrix               ) {
    return painter.translatePosMatrix(
        matrix ? matrix : tile.tileID.projMatrix,
        tile,
        layer.paint.get('line-translate'),
        layer.paint.get('line-translate-anchor')
    );
}

const lineDefinesValues = (layer                )                    => {
    const values = [];
    if (hasDash(layer)) values.push('RENDER_LINE_DASH');
    if (layer.paint.get('line-gradient')) values.push('RENDER_LINE_GRADIENT');

    const trimOffset = layer.paint.get('line-trim-offset');
    if (trimOffset[0] !== 0 || trimOffset[1] !== 0) {
        values.push('RENDER_LINE_TRIM_OFFSET');
    }

    const hasPattern = layer.paint.get('line-pattern').constantOr((1     ));
    const hasOpacity = layer.paint.get('line-opacity').constantOr(1.0) !== 1.0;
    if (!hasPattern && hasOpacity) {
        values.push('RENDER_LINE_ALPHA_DISCARD');
    }
    return values;
};

function hasDash(layer                ) {
    const dashPropertyValue = layer.paint.get('line-dasharray').value;
    return dashPropertyValue.value || dashPropertyValue.kind !== "constant";
}

//      


                                               
                                                         
                                                                                  

                                   
                                
                             
                                
                          
                           
                          
                          
                                  
                                   
                                     
                                   
                                
                                        
   

const rasterUniforms = (context         )                     => ({
    'u_matrix': new index.UniformMatrix4f(context),
    'u_tl_parent': new index.Uniform2f(context),
    'u_scale_parent': new index.Uniform1f(context),
    'u_fade_t': new index.Uniform1f(context),
    'u_opacity': new index.Uniform1f(context),
    'u_image0': new index.Uniform1i(context),
    'u_image1': new index.Uniform1i(context),
    'u_brightness_low': new index.Uniform1f(context),
    'u_brightness_high': new index.Uniform1f(context),
    'u_saturation_factor': new index.Uniform1f(context),
    'u_contrast_factor': new index.Uniform1f(context),
    'u_spin_weights': new index.Uniform3f(context),
    'u_perspective_transform': new index.Uniform2f(context)
});

const rasterUniformValues = (
    matrix              ,
    parentTL                  ,
    parentScaleBy        ,
    fade                                ,
    layer                  ,
    perspectiveTransform                  
)                                    => ({
    'u_matrix': matrix,
    'u_tl_parent': parentTL,
    'u_scale_parent': parentScaleBy,
    'u_fade_t': fade.mix,
    'u_opacity': fade.opacity * layer.paint.get('raster-opacity'),
    'u_image0': 0,
    'u_image1': 1,
    'u_brightness_low': layer.paint.get('raster-brightness-min'),
    'u_brightness_high': layer.paint.get('raster-brightness-max'),
    'u_saturation_factor': saturationFactor(layer.paint.get('raster-saturation')),
    'u_contrast_factor': contrastFactor(layer.paint.get('raster-contrast')),
    'u_spin_weights': spinWeights(layer.paint.get('raster-hue-rotate')),
    'u_perspective_transform': perspectiveTransform
});

function spinWeights(angle        ) {
    angle *= Math.PI / 180;
    const s = Math.sin(angle);
    const c = Math.cos(angle);
    return [
        (2 * c + 1) / 3,
        (-Math.sqrt(3) * s - c + 1) / 3,
        (Math.sqrt(3) * s - c + 1) / 3
    ];
}

function contrastFactor(contrast        ) {
    return contrast > 0 ?
        1 / (1 - contrast) :
        1 + contrast;
}

function saturationFactor(saturation        ) {
    return saturation > 0 ?
        1 - 1 / (1.001 - saturation) :
        -saturation;
}

//      

                                                                 

                                                                  

                                       
                                         
                                            
                          
                        
                                             
                                 
                                
                               
                                
                                            
                                      
                           
                                  
                           
                           
                                   
                                        
                               
                                  
                                     
                             
                               
                          
   

                                      
                                         
                                            
                          
                        
                                             
                                 
                                
                               
                                
                                            
                                      
                           
                                  
                           
                           
                               
                                      
                           
                                   
                                        
                               
                                  
                                     
                             
                               
                          
   

                                              
                                         
                                            
                          
                        
                                             
                                 
                                
                               
                                
                                            
                                      
                           
                                  
                           
                                
                           
                                
                               
                                      
                          
   

                                                         

const symbolIconUniforms = (context         )                         => ({
    'u_is_size_zoom_constant': new index.Uniform1i(context),
    'u_is_size_feature_constant': new index.Uniform1i(context),
    'u_size_t': new index.Uniform1f(context),
    'u_size': new index.Uniform1f(context),
    'u_camera_to_center_distance': new index.Uniform1f(context),
    'u_rotate_symbol': new index.Uniform1i(context),
    'u_aspect_ratio': new index.Uniform1f(context),
    'u_fade_change': new index.Uniform1f(context),
    'u_matrix': new index.UniformMatrix4f(context),
    'u_label_plane_matrix': new index.UniformMatrix4f(context),
    'u_coord_matrix': new index.UniformMatrix4f(context),
    'u_is_text': new index.Uniform1i(context),
    'u_pitch_with_map': new index.Uniform1i(context),
    'u_texsize': new index.Uniform2f(context),
    'u_tile_id': new index.Uniform3f(context),
    'u_zoom_transition': new index.Uniform1f(context),
    'u_inv_rot_matrix': new index.UniformMatrix4f(context),
    'u_merc_center': new index.Uniform2f(context),
    'u_camera_forward': new index.Uniform3f(context),
    'u_tile_matrix': new index.UniformMatrix4f(context),
    'u_up_vector': new index.Uniform3f(context),
    'u_ecef_origin': new index.Uniform3f(context),
    'u_texture': new index.Uniform1i(context)
});

const symbolSDFUniforms = (context         )                        => ({
    'u_is_size_zoom_constant': new index.Uniform1i(context),
    'u_is_size_feature_constant': new index.Uniform1i(context),
    'u_size_t': new index.Uniform1f(context),
    'u_size': new index.Uniform1f(context),
    'u_camera_to_center_distance': new index.Uniform1f(context),
    'u_rotate_symbol': new index.Uniform1i(context),
    'u_aspect_ratio': new index.Uniform1f(context),
    'u_fade_change': new index.Uniform1f(context),
    'u_matrix': new index.UniformMatrix4f(context),
    'u_label_plane_matrix': new index.UniformMatrix4f(context),
    'u_coord_matrix': new index.UniformMatrix4f(context),
    'u_is_text': new index.Uniform1i(context),
    'u_pitch_with_map': new index.Uniform1i(context),
    'u_texsize': new index.Uniform2f(context),
    'u_texture': new index.Uniform1i(context),
    'u_gamma_scale': new index.Uniform1f(context),
    'u_device_pixel_ratio': new index.Uniform1f(context),
    'u_tile_id': new index.Uniform3f(context),
    'u_zoom_transition': new index.Uniform1f(context),
    'u_inv_rot_matrix': new index.UniformMatrix4f(context),
    'u_merc_center': new index.Uniform2f(context),
    'u_camera_forward': new index.Uniform3f(context),
    'u_tile_matrix': new index.UniformMatrix4f(context),
    'u_up_vector': new index.Uniform3f(context),
    'u_ecef_origin': new index.Uniform3f(context),
    'u_is_halo': new index.Uniform1i(context)
});

const symbolTextAndIconUniforms = (context         )                                => ({
    'u_is_size_zoom_constant': new index.Uniform1i(context),
    'u_is_size_feature_constant': new index.Uniform1i(context),
    'u_size_t': new index.Uniform1f(context),
    'u_size': new index.Uniform1f(context),
    'u_camera_to_center_distance': new index.Uniform1f(context),
    'u_rotate_symbol': new index.Uniform1i(context),
    'u_aspect_ratio': new index.Uniform1f(context),
    'u_fade_change': new index.Uniform1f(context),
    'u_matrix': new index.UniformMatrix4f(context),
    'u_label_plane_matrix': new index.UniformMatrix4f(context),
    'u_coord_matrix': new index.UniformMatrix4f(context),
    'u_is_text': new index.Uniform1i(context),
    'u_pitch_with_map': new index.Uniform1i(context),
    'u_texsize': new index.Uniform2f(context),
    'u_texsize_icon': new index.Uniform2f(context),
    'u_texture': new index.Uniform1i(context),
    'u_texture_icon': new index.Uniform1i(context),
    'u_gamma_scale': new index.Uniform1f(context),
    'u_device_pixel_ratio': new index.Uniform1f(context),
    'u_is_halo': new index.Uniform1i(context)
});

const identityMatrix = index.create();

const symbolIconUniformValues = (
    functionType        ,
    size                   ,
    rotateInShader         ,
    pitchWithMap         ,
    painter         ,
    matrix              ,
    labelPlaneMatrix              ,
    glCoordMatrix              ,
    isText         ,
    texSize                  ,
    coord                  ,
    zoomTransition        ,
    mercatorCenter                  ,
    invMatrix              ,
    upVector                          ,
    projection            
)                                        => {
    const transform = painter.transform;

    const values = {
        'u_is_size_zoom_constant': +(functionType === 'constant' || functionType === 'source'),
        'u_is_size_feature_constant': +(functionType === 'constant' || functionType === 'camera'),
        'u_size_t': size ? size.uSizeT : 0,
        'u_size': size ? size.uSize : 0,
        'u_camera_to_center_distance': transform.cameraToCenterDistance,
        'u_rotate_symbol': +rotateInShader,
        'u_aspect_ratio': transform.width / transform.height,
        'u_fade_change': painter.options.fadeDuration ? painter.symbolFadeChange : 1,
        'u_matrix': matrix,
        'u_label_plane_matrix': labelPlaneMatrix,
        'u_coord_matrix': glCoordMatrix,
        'u_is_text': +isText,
        'u_pitch_with_map': +pitchWithMap,
        'u_texsize': texSize,
        'u_texture': 0,
        'u_tile_id': [0, 0, 0],
        'u_zoom_transition': 0,
        'u_inv_rot_matrix': identityMatrix,
        'u_merc_center': [0, 0],
        'u_camera_forward': [0, 0, 0],
        'u_ecef_origin': [0, 0, 0],
        'u_tile_matrix': identityMatrix,
        'u_up_vector': [0, -1, 0]
    };

    if (projection.name === 'globe') {
        values['u_tile_id'] = [coord.canonical.x, coord.canonical.y, 1 << coord.canonical.z];
        values['u_zoom_transition'] = zoomTransition;
        values['u_inv_rot_matrix'] = invMatrix;
        values['u_merc_center'] = mercatorCenter;
        values['u_camera_forward'] = ((transform._camera.forward()     )                          );
        values['u_ecef_origin'] = index.globeECEFOrigin(transform.globeMatrix, coord.toUnwrapped());
        values['u_tile_matrix'] = Float32Array.from(transform.globeMatrix);
        values['u_up_vector'] = upVector;
    }

    return values;
};

const symbolSDFUniformValues = (
    functionType        ,
    size                   ,
    rotateInShader         ,
    pitchWithMap         ,
    painter         ,
    matrix              ,
    labelPlaneMatrix              ,
    glCoordMatrix              ,
    isText         ,
    texSize                  ,
    isHalo         ,
    coord                  ,
    zoomTransition        ,
    mercatorCenter                  ,
    invMatrix              ,
    upVector                          ,
    projection            
)                                       => {
    return index.extend(symbolIconUniformValues(functionType, size, rotateInShader,
        pitchWithMap, painter, matrix, labelPlaneMatrix, glCoordMatrix, isText,
        texSize, coord, zoomTransition, mercatorCenter, invMatrix, upVector, projection), {
        'u_gamma_scale': pitchWithMap ? painter.transform.cameraToCenterDistance * Math.cos(painter.terrain ? 0 : painter.transform._pitch) : 1,
        'u_device_pixel_ratio': index.exported.devicePixelRatio,
        'u_is_halo': +isHalo
    });
};

const symbolTextAndIconUniformValues = (
    functionType        ,
    size                   ,
    rotateInShader         ,
    pitchWithMap         ,
    painter         ,
    matrix              ,
    labelPlaneMatrix              ,
    glCoordMatrix              ,
    texSizeSDF                  ,
    texSizeIcon                  ,
    coord                  ,
    zoomTransition        ,
    mercatorCenter                  ,
    invMatrix              ,
    upVector                          ,
    projection            
)                                        => {
    return index.extend(symbolSDFUniformValues(functionType, size, rotateInShader,
        pitchWithMap, painter, matrix, labelPlaneMatrix, glCoordMatrix, true, texSizeSDF,
        true, coord, zoomTransition, mercatorCenter, invMatrix, upVector, projection), {
        'u_texsize_icon': texSizeIcon,
        'u_texture_icon': 1
    });
};

//      


                                         
                                                         
                                               
                                                        
                                                              
                                                                                     

                                       
                                
                           
                           
   

                                              
                                
                           
                        
                         
                              
                              
                           
                                
                                     
                                     
                                       
   

const backgroundUniforms = (context         )                         => ({
    'u_matrix': new index.UniformMatrix4f(context),
    'u_opacity': new index.Uniform1f(context),
    'u_color': new index.UniformColor(context)
});

const backgroundPatternUniforms = (context         )                                => ({
    'u_matrix': new index.UniformMatrix4f(context),
    'u_opacity': new index.Uniform1f(context),
    'u_image': new index.Uniform1i(context),
    'u_pattern_tl': new index.Uniform2f(context),
    'u_pattern_br': new index.Uniform2f(context),
    'u_texsize': new index.Uniform2f(context),
    'u_pattern_size': new index.Uniform2f(context),
    'u_pixel_coord_upper': new index.Uniform2f(context),
    'u_pixel_coord_lower': new index.Uniform2f(context),
    'u_tile_units_to_pixels': new index.Uniform1f(context)
});

const backgroundUniformValues = (
    matrix              ,
    opacity        ,
    color       
)                                        => ({
    'u_matrix': matrix,
    'u_opacity': opacity,
    'u_color': color
});

const backgroundPatternUniformValues = (
    matrix              ,
    opacity        ,
    painter         ,
    image               ,
    tile                                              
)                                               => index.extend(
    bgPatternUniformValues(image, painter, tile),
    {
        'u_matrix': matrix,
        'u_opacity': opacity
    }
);

//      


                                                         
                                               

                                   
                                
                                 
                           
                           
                                  
   

                                            
                                
                              
                                    
                          
                           
                                   
   

const skyboxUniforms = (context         )                     => ({
    'u_matrix': new index.UniformMatrix4f(context),
    'u_sun_direction': new index.Uniform3f(context),
    'u_cubemap': new index.Uniform1i(context),
    'u_opacity': new index.Uniform1f(context),
    'u_temporal_offset': new index.Uniform1f(context)

});

const skyboxUniformValues = (
    matrix              ,
    sunDirection                          ,
    cubemap        ,
    opacity        ,
    temporalOffset        
)                                    => ({
    'u_matrix': matrix,
    'u_sun_direction': sunDirection,
    'u_cubemap': cubemap,
    'u_opacity': opacity,
    'u_temporal_offset': temporalOffset
});

const skyboxGradientUniforms = (context         )                              => ({
    'u_matrix': new index.UniformMatrix4f(context),
    'u_color_ramp': new index.Uniform1i(context),
    // radial gradient uniforms
    'u_center_direction': new index.Uniform3f(context),
    'u_radius': new index.Uniform1f(context),
    'u_opacity': new index.Uniform1f(context),
    'u_temporal_offset': new index.Uniform1f(context)
});

const skyboxGradientUniformValues = (
    matrix              ,
    centerDirection                          ,
    radius        , //degrees
    opacity        ,
    temporalOffset        
)                                             => {
    return {
        'u_matrix': matrix,
        'u_color_ramp': 0,
        'u_center_direction': centerDirection,
        'u_radius': index.degToRad(radius),
        'u_opacity': opacity,
        'u_temporal_offset': temporalOffset
    };
};

//      

                                                         
                                               

                                          
                                   
                                 
                                 
                                
                                
                             
   

const skyboxCaptureUniforms = (context         )                            => ({
    'u_matrix_3f': new index.UniformMatrix3f(context),
    'u_sun_direction': new index.Uniform3f(context),
    'u_sun_intensity': new index.Uniform1f(context),
    'u_color_tint_r': new index.Uniform4f(context),
    'u_color_tint_m': new index.Uniform4f(context),
    'u_luminance': new index.Uniform1f(context),
});

const skyboxCaptureUniformValues = (
    matrix              ,
    sunDirection                          ,
    sunIntensity        ,
    atmosphereColor       ,
    atmosphereHaloColor       
)                                           => ({
    'u_matrix_3f': matrix,
    'u_sun_direction': sunDirection,
    'u_sun_intensity': sunIntensity,
    'u_color_tint_r': [
        atmosphereColor.r,
        atmosphereColor.g,
        atmosphereColor.b,
        atmosphereColor.a
    ],
    'u_color_tint_m': [
        atmosphereHaloColor.r,
        atmosphereHaloColor.g,
        atmosphereHaloColor.b,
        atmosphereHaloColor.a
    ],
    'u_luminance': 5e-5,
});

//      

                                                             
                                                         
                                                                            

                                                                                                                                                    

const programUniforms = {
    fillExtrusion: fillExtrusionUniforms,
    fillExtrusionPattern: fillExtrusionPatternUniforms,
    fill: fillUniforms,
    fillPattern: fillPatternUniforms,
    fillOutline: fillOutlineUniforms,
    fillOutlinePattern: fillOutlinePatternUniforms,
    circle: circleUniforms,
    collisionBox: collisionUniforms,
    collisionCircle: collisionCircleUniforms,
    debug: debugUniforms,
    clippingMask: clippingMaskUniforms,
    heatmap: heatmapUniforms,
    heatmapTexture: heatmapTextureUniforms,
    hillshade: hillshadeUniforms,
    hillshadePrepare: hillshadePrepareUniforms,
    line: lineUniforms,
    linePattern: linePatternUniforms,
    raster: rasterUniforms,
    symbolIcon: symbolIconUniforms,
    symbolSDF: symbolSDFUniforms,
    symbolTextAndIcon: symbolTextAndIconUniforms,
    background: backgroundUniforms,
    backgroundPattern: backgroundPatternUniforms,
    terrainRaster: terrainRasterUniforms,
    terrainDepth: terrainRasterUniforms,
    skybox: skyboxUniforms,
    skyboxGradient: skyboxGradientUniforms,
    skyboxCapture: skyboxCaptureUniforms,
    globeRaster: globeRasterUniforms,
    globeAtmosphere: atmosphereUniforms,
};

//      


                  
                               
                         
                            
                               
                          
  

let quadTriangles                    ;

function drawCollisionDebug(painter         , sourceCache             , layer            , coords                         , translate                  , translateAnchor                    , isText         ) {
    const context = painter.context;
    const gl = context.gl;
    const tr = painter.transform;
    const program = painter.useProgram('collisionBox');
    const tileBatches                   = [];
    let circleCount = 0;
    let circleOffset = 0;

    for (let i = 0; i < coords.length; i++) {
        const coord = coords[i];
        const tile = sourceCache.getTile(coord);
        const bucket                = (tile.getBucket(layer)     );
        if (!bucket) continue;

        const tileMatrix = getCollisionDebugTileProjectionMatrix(coord, bucket, tr);

        let posMatrix = tileMatrix;
        if (translate[0] !== 0 || translate[1] !== 0) {
            posMatrix = painter.translatePosMatrix(tileMatrix, tile, translate, translateAnchor);
        }
        const buffers = isText ? bucket.textCollisionBox : bucket.iconCollisionBox;
        // Get collision circle data of this bucket
        const circleArray                = bucket.collisionCircleArray;
        if (circleArray.length > 0) {
            // We need to know the projection matrix that was used for projecting collision circles to the screen.
            // This might vary between buckets as the symbol placement is a continous process. This matrix is
            // required for transforming points from previous screen space to the current one
            const invTransform = index.create();
            const transform = posMatrix;

            index.mul(invTransform, bucket.placementInvProjMatrix, tr.glCoordMatrix);
            index.mul(invTransform, invTransform, bucket.placementViewportMatrix);

            tileBatches.push({
                circleArray,
                circleOffset,
                transform,
                invTransform,
                projection: bucket.getProjection()
            });

            circleCount += circleArray.length / 4;  // 4 values per circle
            circleOffset = circleCount;
        }
        if (!buffers) continue;
        if (painter.terrain) painter.terrain.setupElevationDraw(tile, program);
        program.draw(context, gl.LINES,
            index.DepthMode.disabled, index.StencilMode.disabled,
            painter.colorModeForRenderPass(),
            index.CullFaceMode.disabled,
            collisionUniformValues(posMatrix, tr, tile, bucket.getProjection()),
            layer.id, buffers.layoutVertexBuffer, buffers.indexBuffer,
            buffers.segments, null, tr.zoom, null,
            [buffers.collisionVertexBuffer, buffers.collisionVertexBufferExt]);
    }

    if (!isText || !tileBatches.length) {
        return;
    }

    // Render collision circles
    const circleProgram = painter.useProgram('collisionCircle');

    // Construct vertex data
    const vertexData = new index.StructArrayLayout2f1f2i16();
    vertexData.resize(circleCount * 4);
    vertexData._trim();

    let vertexOffset = 0;

    for (const batch of tileBatches) {
        for (let i = 0; i < batch.circleArray.length / 4; i++) {
            const circleIdx = i * 4;
            const x = batch.circleArray[circleIdx + 0];
            const y = batch.circleArray[circleIdx + 1];
            const radius = batch.circleArray[circleIdx + 2];
            const collision = batch.circleArray[circleIdx + 3];

            // 4 floats per vertex, 4 vertices per quad
            vertexData.emplace(vertexOffset++, x, y, radius, collision, 0);
            vertexData.emplace(vertexOffset++, x, y, radius, collision, 1);
            vertexData.emplace(vertexOffset++, x, y, radius, collision, 2);
            vertexData.emplace(vertexOffset++, x, y, radius, collision, 3);
        }
    }
    if (!quadTriangles || quadTriangles.length < circleCount * 2) {
        quadTriangles = createQuadTriangles(circleCount);
    }

    const indexBuffer              = context.createIndexBuffer(quadTriangles, true);
    const vertexBuffer               = context.createVertexBuffer(vertexData, index.collisionCircleLayout.members, true);

    // Render batches
    for (const batch of tileBatches) {
        const uniforms = collisionCircleUniformValues(batch.transform, batch.invTransform, tr, batch.projection);

        circleProgram.draw(
            context,
            gl.TRIANGLES,
            index.DepthMode.disabled,
            index.StencilMode.disabled,
            painter.colorModeForRenderPass(),
            index.CullFaceMode.disabled,
            uniforms,
            layer.id,
            vertexBuffer,
            indexBuffer,
            index.SegmentVector.simpleSegment(0, batch.circleOffset * 2, batch.circleArray.length, batch.circleArray.length / 2),
            null,
            tr.zoom);
    }

    vertexBuffer.destroy();
    indexBuffer.destroy();
}

function createQuadTriangles(quadCount        )                    {
    const triCount = quadCount * 2;
    const array = new index.StructArrayLayout3ui6();

    array.resize(triCount);
    array._trim();

    // Two triangles and 4 vertices per quad.
    for (let i = 0; i < triCount; i++) {
        const idx = i * 6;

        array.uint16[idx + 0] = i * 4 + 0;
        array.uint16[idx + 1] = i * 4 + 1;
        array.uint16[idx + 2] = i * 4 + 2;
        array.uint16[idx + 3] = i * 4 + 2;
        array.uint16[idx + 4] = i * 4 + 3;
        array.uint16[idx + 5] = i * 4 + 0;
    }

    return array;
}

//      

const identityMat4 = index.create();

                              
                            
                    
            
                     
                               
                           
                              
                                         
                                
                                    
                       
                         
                   
                                          
     
  

                                             

function drawSymbols(painter         , sourceCache             , layer                  , coords                         , variableOffsets                                    ) {
    if (painter.renderPass !== 'translucent') return;

    // Disable the stencil test so that labels aren't clipped to tile boundaries.
    const stencilMode = index.StencilMode.disabled;
    const colorMode = painter.colorModeForRenderPass();
    const variablePlacement = layer.layout.get('text-variable-anchor');

    //Compute variable-offsets before painting since icons and text data positioning
    //depend on each other in this case.
    if (variablePlacement) {
        updateVariableAnchors(coords, painter, layer, sourceCache,
            layer.layout.get('text-rotation-alignment'),
            layer.layout.get('text-pitch-alignment'),
            variableOffsets
        );
    }

    if (layer.paint.get('icon-opacity').constantOr(1) !== 0) {
        drawLayerSymbols(painter, sourceCache, layer, coords, false,
            layer.paint.get('icon-translate'),
            layer.paint.get('icon-translate-anchor'),
            layer.layout.get('icon-rotation-alignment'),
            layer.layout.get('icon-pitch-alignment'),
            layer.layout.get('icon-keep-upright'),
            stencilMode, colorMode
        );
    }

    if (layer.paint.get('text-opacity').constantOr(1) !== 0) {
        drawLayerSymbols(painter, sourceCache, layer, coords, true,
            layer.paint.get('text-translate'),
            layer.paint.get('text-translate-anchor'),
            layer.layout.get('text-rotation-alignment'),
            layer.layout.get('text-pitch-alignment'),
            layer.layout.get('text-keep-upright'),
            stencilMode, colorMode
        );
    }

    if (sourceCache.map.showCollisionBoxes) {
        drawCollisionDebug(painter, sourceCache, layer, coords, layer.paint.get('text-translate'),
            layer.paint.get('text-translate-anchor'), true);
        drawCollisionDebug(painter, sourceCache, layer, coords, layer.paint.get('icon-translate'),
            layer.paint.get('icon-translate-anchor'), false);
    }
}

function computeGlobeCameraUp(transform           )                           {
    const viewMatrix = transform._camera.getWorldToCamera(transform.worldSize, 1);
    const viewToEcef = index.multiply([], viewMatrix, transform.globeMatrix);
    index.invert$1(viewToEcef, viewToEcef);

    const cameraUpVector = [0, 0, 0];
    const up = [0, 1, 0, 0];
    index.transformMat4$1(up, up,  viewToEcef);
    cameraUpVector[0] = up[0];
    cameraUpVector[1] = up[1];
    cameraUpVector[2] = up[2];
    index.normalize(cameraUpVector, cameraUpVector);

    return cameraUpVector;
}

function calculateVariableRenderShift({width, height, anchor, textOffset, textScale}                , renderTextSize        )        {
    const {horizontalAlign, verticalAlign} = index.getAnchorAlignment(anchor);
    const shiftX = -(horizontalAlign - 0.5) * width;
    const shiftY = -(verticalAlign - 0.5) * height;
    const variableOffset = index.evaluateVariableOffset(anchor, textOffset);
    return new index.Point(
        (shiftX / textScale + variableOffset[0]) * renderTextSize,
        (shiftY / textScale + variableOffset[1]) * renderTextSize
    );
}

function updateVariableAnchors(coords                         , painter         , layer                  , sourceCache             , rotationAlignment           , pitchAlignment           , variableOffsets                                      ) {
    const tr = painter.transform;
    const rotateWithMap = rotationAlignment === 'map';
    const pitchWithMap = pitchAlignment === 'map';

    for (const coord of coords) {
        const tile = sourceCache.getTile(coord);
        const bucket               = (tile.getBucket(layer)     );
        if (!bucket || !bucket.text || !bucket.text.segments.get().length) {
            continue;
        }

        const sizeData = bucket.textSizeData;
        const size = index.evaluateSizeForZoom(sizeData, tr.zoom);
        const tileMatrix = getSymbolTileProjectionMatrix(coord, bucket.getProjection(), tr);

        const pixelsToTileUnits = tr.calculatePixelsToTileUnitsMatrix(tile);
        const labelPlaneMatrix = getLabelPlaneMatrixForRendering(tileMatrix, tile.tileID.canonical, pitchWithMap, rotateWithMap, tr, bucket.getProjection(), pixelsToTileUnits);
        const updateTextFitIcon = layer.layout.get('icon-text-fit') !== 'none' &&  bucket.hasIconData();

        if (size) {
            const tileScale = Math.pow(2, tr.zoom - tile.tileID.overscaledZ);
            updateVariableAnchorsForBucket(bucket, rotateWithMap, pitchWithMap, variableOffsets, index.symbolSize,
                                  tr, labelPlaneMatrix, coord, tileScale, size, updateTextFitIcon);
        }
    }
}

function updateVariableAnchorsForBucket(bucket              , rotateWithMap         , pitchWithMap         , variableOffsets                                      , symbolSize                   , transform           , labelPlaneMatrix              , coord                  , tileScale        , size                  , updateTextFitIcon         ) {
    const placedSymbols = bucket.text.placedSymbolArray;
    const dynamicTextLayoutVertexArray = bucket.text.dynamicLayoutVertexArray;
    const dynamicIconLayoutVertexArray = bucket.icon.dynamicLayoutVertexArray;
    const placedTextShifts = {};
    const projection = bucket.getProjection();
    const tileMatrix = getSymbolTileProjectionMatrix(coord, projection, transform);
    const elevation = transform.elevation;
    const metersToTile = projection.upVectorScale(coord.canonical, transform.center.lat, transform.worldSize).metersToTile;

    dynamicTextLayoutVertexArray.clear();
    for (let s = 0; s < placedSymbols.length; s++) {
        const symbol = placedSymbols.get(s);
        const {tileAnchorX, tileAnchorY, numGlyphs} = symbol;
        const skipOrientation = bucket.allowVerticalPlacement && !symbol.placedOrientation;
        const variableOffset = (!symbol.hidden && symbol.crossTileID && !skipOrientation) ? variableOffsets[symbol.crossTileID] : null;

        if (!variableOffset) {
            // These symbols are from a justification that is not being used, or a label that wasn't placed
            // so we don't need to do the extra math to figure out what incremental shift to apply.
            hideGlyphs(numGlyphs, dynamicTextLayoutVertexArray);

        } else  {
            let dx = 0, dy = 0, dz = 0;
            if (elevation) {
                const h = elevation ? elevation.getAtTileOffset(coord, tileAnchorX, tileAnchorY) : 0.0;
                const [ux, uy, uz] = projection.upVector(coord.canonical, tileAnchorX, tileAnchorY);
                dx = h * ux * metersToTile;
                dy = h * uy * metersToTile;
                dz = h * uz * metersToTile;
            }
            let [x, y, z, w] = project(
                symbol.projectedAnchorX + dx,
                symbol.projectedAnchorY + dy,
                symbol.projectedAnchorZ + dz,
                pitchWithMap ? tileMatrix : labelPlaneMatrix);

            const perspectiveRatio = getPerspectiveRatio(transform.getCameraToCenterDistance(projection), w);
            let renderTextSize = symbolSize.evaluateSizeForFeature(bucket.textSizeData, size, symbol) * perspectiveRatio / index.ONE_EM;
            if (pitchWithMap) {
                // Go from size in pixels to equivalent size in tile units
                renderTextSize *= bucket.tilePixelRatio / tileScale;
            }

            const shift = calculateVariableRenderShift(variableOffset, renderTextSize);

            // Usual case is that we take the projected anchor and add the pixel-based shift
            // calculated above. In the (somewhat weird) case of pitch-aligned text, we add an equivalent
            // tile-unit based shift to the anchor before projecting to the label plane.
            if (pitchWithMap) {
                ({x, y, z} = projection.projectTilePoint(tileAnchorX + shift.x, tileAnchorY + shift.y, coord.canonical));
                [x, y, z] = project(x + dx, y + dy, z + dz, labelPlaneMatrix);

            } else {
                if (rotateWithMap) shift._rotate(-transform.angle);
                x += shift.x;
                y += shift.y;
                z = 0;
            }

            const angle = (bucket.allowVerticalPlacement && symbol.placedOrientation === index.WritingMode.vertical) ? Math.PI / 2 : 0;
            for (let g = 0; g < numGlyphs; g++) {
                index.addDynamicAttributes(dynamicTextLayoutVertexArray, x, y, z, angle);
            }
            //Only offset horizontal text icons
            if (updateTextFitIcon && symbol.associatedIconIndex >= 0) {
                placedTextShifts[symbol.associatedIconIndex] = {x, y, z, angle};
            }
        }
    }

    if (updateTextFitIcon) {
        dynamicIconLayoutVertexArray.clear();
        const placedIcons = bucket.icon.placedSymbolArray;
        for (let i = 0; i < placedIcons.length; i++) {
            const placedIcon = placedIcons.get(i);
            const {numGlyphs} = placedIcon;
            const shift = placedTextShifts[i];

            if (placedIcon.hidden || !shift) {
                hideGlyphs(numGlyphs, dynamicIconLayoutVertexArray);
            } else {
                const {x, y, z, angle} = shift;
                for (let g = 0; g < numGlyphs; g++) {
                    index.addDynamicAttributes(dynamicIconLayoutVertexArray, x, y, z, angle);
                }
            }
        }
        bucket.icon.dynamicLayoutVertexBuffer.updateData(dynamicIconLayoutVertexArray);
    }
    bucket.text.dynamicLayoutVertexBuffer.updateData(dynamicTextLayoutVertexArray);
}

function getSymbolProgramName(isSDF         , isText         , bucket              ) {
    if (bucket.iconsInText && isText) {
        return 'symbolTextAndIcon';
    } else if (isSDF) {
        return 'symbolSDF';
    } else {
        return 'symbolIcon';
    }
}

function drawLayerSymbols(painter         , sourceCache             , layer                  , coords                         , isText         , translate                  , translateAnchor                    , rotationAlignment           , pitchAlignment           , keepUpright         , stencilMode             , colorMode           ) {
    const context = painter.context;
    const gl = context.gl;
    const tr = painter.transform;

    const rotateWithMap = rotationAlignment === 'map';
    const pitchWithMap = pitchAlignment === 'map';
    const alongLine = rotateWithMap && layer.layout.get('symbol-placement') !== 'point';

    // Line label rotation happens in `updateLineLabels`
    // Pitched point labels are automatically rotated by the labelPlaneMatrix projection
    // Unpitched point labels need to have their rotation applied after projection
    const rotateInShader = rotateWithMap && !pitchWithMap && !alongLine;

    const hasSortKey = layer.layout.get('symbol-sort-key').constantOr(1) !== undefined;
    let sortFeaturesByKey = false;

    const depthMode = painter.depthModeForSublayer(0, index.DepthMode.ReadOnly);
    const mercatorCenter = [
        index.mercatorXfromLng(tr.center.lng),
        index.mercatorYfromLat(tr.center.lat)
    ];
    const variablePlacement = layer.layout.get('text-variable-anchor');
    const isGlobeProjection = tr.projection.name === 'globe';
    const tileRenderState                               = [];

    const mercatorCameraUp = [0, -1, 0];

    let globeCameraUp                           = mercatorCameraUp;
    if ((isGlobeProjection || tr.mercatorFromTransition) && !rotateWithMap) {
        // Each symbol rotating with the viewport requires per-instance information about
        // how to align with the viewport. In 2D case rotation is shared between all of the symbols and
        // hence embedded in the label plane matrix but in globe view this needs to be computed at runtime.
        // Camera up vector together with surface normals can be used to find the correct orientation for each symbol.
        globeCameraUp = computeGlobeCameraUp(tr);
    }

    for (const coord of coords) {
        const tile = sourceCache.getTile(coord);
        const bucket               = (tile.getBucket(layer)     );
        if (!bucket) continue;
        // Allow rendering of buckets built for globe projection in mercator mode
        // until the substitute tile has been loaded
        if (bucket.projection.name === 'mercator' && isGlobeProjection) {
            continue;
        }
        const buffers = isText ? bucket.text : bucket.icon;
        if (!buffers || bucket.fullyClipped || !buffers.segments.get().length) continue;
        const programConfiguration = buffers.programConfigurations.get(layer.id);

        const isSDF = isText || bucket.sdfIcons;

        const sizeData = isText ? bucket.textSizeData : bucket.iconSizeData;
        const transformed = pitchWithMap || tr.pitch !== 0;

        const size = index.evaluateSizeForZoom(sizeData, tr.zoom);

        let texSize                  ;
        let texSizeIcon                   = [0, 0];
        let atlasTexture;
        let atlasInterpolation;
        let atlasTextureIcon = null;
        let atlasInterpolationIcon;
        if (isText) {
            atlasTexture = tile.glyphAtlasTexture;
            atlasInterpolation = gl.LINEAR;
            texSize = tile.glyphAtlasTexture.size;
            if (bucket.iconsInText) {
                texSizeIcon = tile.imageAtlasTexture.size;
                atlasTextureIcon = tile.imageAtlasTexture;
                const zoomDependentSize = sizeData.kind === 'composite' || sizeData.kind === 'camera';
                atlasInterpolationIcon = transformed || painter.options.rotating || painter.options.zooming || zoomDependentSize ? gl.LINEAR : gl.NEAREST;
            }
        } else {
            const iconScaled = layer.layout.get('icon-size').constantOr(0) !== 1 || bucket.iconsNeedLinear;
            atlasTexture = tile.imageAtlasTexture;
            atlasInterpolation = isSDF || painter.options.rotating || painter.options.zooming || iconScaled || transformed ?
                gl.LINEAR :
                gl.NEAREST;
            texSize = tile.imageAtlasTexture.size;
        }

        const bucketIsGlobeProjection = bucket.projection.name === 'globe';
        const cameraUpVector = bucketIsGlobeProjection ? globeCameraUp : mercatorCameraUp;
        const globeToMercator =  bucketIsGlobeProjection ? index.globeToMercatorTransition(tr.zoom) : 0.0;
        const tileMatrix = getSymbolTileProjectionMatrix(coord, bucket.getProjection(), tr);

        const s = tr.calculatePixelsToTileUnitsMatrix(tile);
        const labelPlaneMatrixRendering = getLabelPlaneMatrixForRendering(tileMatrix, tile.tileID.canonical, pitchWithMap, rotateWithMap, tr, bucket.getProjection(), s);
        // labelPlaneMatrixInv is used for converting vertex pos to tile coordinates needed for sampling elevation.
        const labelPlaneMatrixInv = painter.terrain && pitchWithMap && alongLine ? index.invert$1(index.create(), labelPlaneMatrixRendering) : identityMat4;
        const glCoordMatrix = getGlCoordMatrix(tileMatrix, tile.tileID.canonical, pitchWithMap, rotateWithMap, tr, bucket.getProjection(), s);

        const hasVariableAnchors = variablePlacement && bucket.hasTextData();
        const updateTextFitIcon = layer.layout.get('icon-text-fit') !== 'none' &&
            hasVariableAnchors &&
            bucket.hasIconData();

        if (alongLine) {
            const elevation = tr.elevation;
            const getElevation = elevation ? elevation.getAtTileOffsetFunc(coord, tr.center.lat, tr.worldSize, bucket.getProjection()) : null;
            const labelPlaneMatrixPlacement = getLabelPlaneMatrixForPlacement(tileMatrix, tile.tileID.canonical, pitchWithMap, rotateWithMap, tr, bucket.getProjection(), s);

            updateLineLabels(bucket, tileMatrix, painter, isText, labelPlaneMatrixPlacement, glCoordMatrix, pitchWithMap, keepUpright, getElevation, coord);
        }

        const projectedPosOnLabelSpace = alongLine || (isText && variablePlacement) || updateTextFitIcon;
        const matrix = painter.translatePosMatrix(tileMatrix, tile, translate, translateAnchor);
        const uLabelPlaneMatrix = projectedPosOnLabelSpace ? identityMat4 : labelPlaneMatrixRendering;
        const uglCoordMatrix = painter.translatePosMatrix(glCoordMatrix, tile, translate, translateAnchor, true);
        const invMatrix = bucket.getProjection().createInversionMatrix(tr, coord.canonical);

        const baseDefines = ([]     );
        if (painter.terrainRenderModeElevated() && pitchWithMap) {
            baseDefines.push('PITCH_WITH_MAP_TERRAIN');
        }
        if (bucketIsGlobeProjection) {
            baseDefines.push('PROJECTION_GLOBE_VIEW');
        }
        if (projectedPosOnLabelSpace) {
            baseDefines.push('PROJECTED_POS_ON_VIEWPORT');
        }

        const hasHalo = isSDF && layer.paint.get(isText ? 'text-halo-width' : 'icon-halo-width').constantOr(1) !== 0;

        let uniformValues;
        if (isSDF) {
            if (!bucket.iconsInText) {
                uniformValues = symbolSDFUniformValues(sizeData.kind, size, rotateInShader, pitchWithMap, painter,
                    matrix, uLabelPlaneMatrix, uglCoordMatrix, isText, texSize, true, coord, globeToMercator, mercatorCenter, invMatrix, cameraUpVector, bucket.getProjection());
            } else {
                uniformValues = symbolTextAndIconUniformValues(sizeData.kind, size, rotateInShader, pitchWithMap, painter,
                    matrix, uLabelPlaneMatrix, uglCoordMatrix, texSize, texSizeIcon, coord, globeToMercator, mercatorCenter, invMatrix, cameraUpVector, bucket.getProjection());
            }
        } else {
            uniformValues = symbolIconUniformValues(sizeData.kind, size, rotateInShader, pitchWithMap, painter, matrix,
                uLabelPlaneMatrix, uglCoordMatrix, isText, texSize, coord, globeToMercator, mercatorCenter, invMatrix, cameraUpVector, bucket.getProjection());
        }

        const program = painter.useProgram(getSymbolProgramName(isSDF, isText, bucket), programConfiguration, baseDefines);

        const state = {
            program,
            buffers,
            uniformValues,
            atlasTexture,
            atlasTextureIcon,
            atlasInterpolation,
            atlasInterpolationIcon,
            isSDF,
            hasHalo,
            tile,
            labelPlaneMatrixInv
        };

        if (hasSortKey && bucket.canOverlap) {
            sortFeaturesByKey = true;
            const oldSegments = buffers.segments.get();
            for (const segment of oldSegments) {
                tileRenderState.push({
                    segments: new index.SegmentVector([segment]),
                    sortKey: ((segment.sortKey     )        ),
                    state
                });
            }
        } else {
            tileRenderState.push({
                segments: buffers.segments,
                sortKey: 0,
                state
            });
        }
    }

    if (sortFeaturesByKey) {
        tileRenderState.sort((a, b) => a.sortKey - b.sortKey);
    }

    for (const segmentState of tileRenderState) {
        const state = segmentState.state;
        if (painter.terrain) {
            const options = {
                useDepthForOcclusion: !isGlobeProjection,
                labelPlaneMatrixInv: state.labelPlaneMatrixInv
            };
            painter.terrain.setupElevationDraw(state.tile, state.program, options);
        }
        context.activeTexture.set(gl.TEXTURE0);
        state.atlasTexture.bind(state.atlasInterpolation, gl.CLAMP_TO_EDGE);
        if (state.atlasTextureIcon) {
            context.activeTexture.set(gl.TEXTURE1);
            if (state.atlasTextureIcon) {
                state.atlasTextureIcon.bind(state.atlasInterpolationIcon, gl.CLAMP_TO_EDGE);
            }
        }

        if (state.isSDF) {
            const uniformValues = ((state.uniformValues     )                                      );
            if (state.hasHalo) {
                uniformValues['u_is_halo'] = 1;
                drawSymbolElements(state.buffers, segmentState.segments, layer, painter, state.program, depthMode, stencilMode, colorMode, uniformValues);
            }
            uniformValues['u_is_halo'] = 0;
        }
        drawSymbolElements(state.buffers, segmentState.segments, layer, painter, state.program, depthMode, stencilMode, colorMode, state.uniformValues);
    }
}

function drawSymbolElements(buffers               , segments               , layer                  , painter         , program     , depthMode           , stencilMode             , colorMode           , uniformValues                                      ) {
    const context = painter.context;
    const gl = context.gl;
    const dynamicBuffers = [buffers.dynamicLayoutVertexBuffer, buffers.opacityVertexBuffer, buffers.globeExtVertexBuffer];
    program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, index.CullFaceMode.disabled,
        uniformValues, layer.id, buffers.layoutVertexBuffer,
        buffers.indexBuffer, segments, layer.paint,
        painter.transform.zoom, buffers.programConfigurations.get(layer.id), dynamicBuffers);
}

//      


                        
                                               
                        
                                     
                                        
                             
                                                     
              
  

                                
                            
                    
                          
  

function drawCircles(painter         , sourceCache             , layer                  , coords                         ) {
    if (painter.renderPass !== 'translucent') return;

    const opacity = layer.paint.get('circle-opacity');
    const strokeWidth = layer.paint.get('circle-stroke-width');
    const strokeOpacity = layer.paint.get('circle-stroke-opacity');
    const sortFeaturesByKey = layer.layout.get('circle-sort-key').constantOr(1) !== undefined;

    if (opacity.constantOr(1) === 0 && (strokeWidth.constantOr(1) === 0 || strokeOpacity.constantOr(1) === 0)) {
        return;
    }

    const context = painter.context;
    const gl = context.gl;
    const tr = painter.transform;

    const depthMode = painter.depthModeForSublayer(0, index.DepthMode.ReadOnly);
    // Turn off stencil testing to allow circles to be drawn across boundaries,
    // so that large circles are not clipped to tiles
    const stencilMode = index.StencilMode.disabled;
    const colorMode = painter.colorModeForRenderPass();
    const isGlobeProjection = tr.projection.name === 'globe';
    const mercatorCenter = [index.mercatorXfromLng(tr.center.lng), index.mercatorYfromLat(tr.center.lat)];

    const segmentsRenderStates                                 = [];

    for (let i = 0; i < coords.length; i++) {
        const coord = coords[i];

        const tile = sourceCache.getTile(coord);
        const bucket                   = (tile.getBucket(layer)     );
        if (!bucket || bucket.projection.name !== tr.projection.name) continue;

        const programConfiguration = bucket.programConfigurations.get(layer.id);
        const definesValues = circleDefinesValues(layer);
        if (isGlobeProjection) {
            definesValues.push('PROJECTION_GLOBE_VIEW');
        }
        const program = painter.useProgram('circle', programConfiguration, ((definesValues     )                      ));
        const layoutVertexBuffer = bucket.layoutVertexBuffer;
        const globeExtVertexBuffer = bucket.globeExtVertexBuffer;
        const indexBuffer = bucket.indexBuffer;
        const invMatrix = tr.projection.createInversionMatrix(tr, coord.canonical);
        const uniformValues = circleUniformValues(painter, coord, tile, invMatrix, mercatorCenter, layer);

        const state                  = {
            programConfiguration,
            program,
            layoutVertexBuffer,
            globeExtVertexBuffer,
            indexBuffer,
            uniformValues,
            tile
        };

        if (sortFeaturesByKey) {
            const oldSegments = bucket.segments.get();
            for (const segment of oldSegments) {
                segmentsRenderStates.push({
                    segments: new index.SegmentVector([segment]),
                    sortKey: ((segment.sortKey     )        ),
                    state
                });
            }
        } else {
            segmentsRenderStates.push({
                segments: bucket.segments,
                sortKey: 0,
                state
            });
        }

    }

    if (sortFeaturesByKey) {
        segmentsRenderStates.sort((a, b) => a.sortKey - b.sortKey);
    }

    const terrainOptions = {useDepthForOcclusion: !isGlobeProjection};

    for (const segmentsState of segmentsRenderStates) {
        const {programConfiguration, program, layoutVertexBuffer, globeExtVertexBuffer, indexBuffer, uniformValues, tile} = segmentsState.state;
        const segments = segmentsState.segments;

        if (painter.terrain) painter.terrain.setupElevationDraw(tile, program, terrainOptions);

        painter.prepareDrawProgram(context, program, tile.tileID.toUnwrapped());

        program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, index.CullFaceMode.disabled,
            uniformValues, layer.id, layoutVertexBuffer, indexBuffer, segments,
            layer.paint, tr.zoom, programConfiguration, [globeExtVertexBuffer]);
    }
}

//      


function drawHeatmap(painter         , sourceCache             , layer                   , coords                         ) {
    if (layer.paint.get('heatmap-opacity') === 0) {
        return;
    }

    if (painter.renderPass === 'offscreen') {
        const context = painter.context;
        const gl = context.gl;

        // Allow kernels to be drawn across boundaries, so that
        // large kernels are not clipped to tiles
        const stencilMode = index.StencilMode.disabled;
        // Turn on additive blending for kernels, which is a key aspect of kernel density estimation formula
        const colorMode = new index.ColorMode([gl.ONE, gl.ONE], index.Color.transparent, [true, true, true, true]);
        const resolutionScaling = painter.transform.projection.name === 'globe' ? 0.5 : 0.25;

        bindFramebuffer(context, painter, layer, resolutionScaling);

        context.clear({color: index.Color.transparent});

        const tr = painter.transform;

        const isGlobeProjection = tr.projection.name === 'globe';

        const definesValues = isGlobeProjection ? ['PROJECTION_GLOBE_VIEW'] : null;
        const cullMode = isGlobeProjection ? index.CullFaceMode.frontCCW : index.CullFaceMode.disabled;

        const mercatorCenter = [index.mercatorXfromLng(tr.center.lng), index.mercatorYfromLat(tr.center.lat)];

        for (let i = 0; i < coords.length; i++) {
            const coord = coords[i];

            // Skip tiles that have uncovered parents to avoid flickering; we don't need
            // to use complex tile masking here because the change between zoom levels is subtle,
            // so it's fine to simply render the parent until all its 4 children are loaded
            if (sourceCache.hasRenderableParent(coord)) continue;

            const tile = sourceCache.getTile(coord);
            const bucket                 = (tile.getBucket(layer)     );
            if (!bucket || bucket.projection.name !== tr.projection.name) continue;

            const programConfiguration = bucket.programConfigurations.get(layer.id);
            const program = painter.useProgram('heatmap', programConfiguration, definesValues);
            const {zoom} = painter.transform;
            if (painter.terrain) painter.terrain.setupElevationDraw(tile, program);

            painter.prepareDrawProgram(context, program, coord.toUnwrapped());

            const invMatrix = tr.projection.createInversionMatrix(tr, coord.canonical);

            program.draw(context, gl.TRIANGLES, index.DepthMode.disabled, stencilMode, colorMode, cullMode,
                heatmapUniformValues(painter, coord,
                    tile, invMatrix, mercatorCenter, zoom, layer.paint.get('heatmap-intensity')),
                layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer,
                bucket.segments, layer.paint, painter.transform.zoom,
                programConfiguration, isGlobeProjection ? [bucket.globeExtVertexBuffer] : null);
        }

        context.viewport.set([0, 0, painter.width, painter.height]);

    } else if (painter.renderPass === 'translucent') {
        painter.context.setColorMode(painter.colorModeForRenderPass());
        renderTextureToMap(painter, layer);
    }
}

function bindFramebuffer(context         , painter         , layer                   , scaling        ) {
    const gl = context.gl;
    const width = painter.width * scaling;
    const height = painter.height * scaling;

    context.activeTexture.set(gl.TEXTURE1);
    context.viewport.set([0, 0, width, height]);

    let fbo = layer.heatmapFbo;

    if (!fbo || (fbo && (fbo.width !== width || fbo.height !== height))) {
        if (fbo) { fbo.destroy(); }

        const texture = gl.createTexture();
        gl.bindTexture(gl.TEXTURE_2D, texture);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);

        fbo = layer.heatmapFbo = context.createFramebuffer(width, height, false);

        bindTextureToFramebuffer(context, painter, texture, fbo, width, height);

    } else {
        gl.bindTexture(gl.TEXTURE_2D, fbo.colorAttachment.get());
        context.bindFramebuffer.set(fbo.framebuffer);
    }
}

function bindTextureToFramebuffer(context         , painter         , texture               , fbo             , width        , height        ) {
    const gl = context.gl;
    // Use the higher precision half-float texture where available (producing much smoother looking heatmaps);
    // Otherwise, fall back to a low precision texture
    /* $FlowFixMe[prop-missing] WebGL2 */
    const type = context.extRenderToTextureHalfFloat ? (context.isWebGL2 ? gl.HALF_FLOAT : context.extTextureHalfFloat.HALF_FLOAT_OES) : gl.UNSIGNED_BYTE;
    /* $FlowFixMe[prop-missing] WebGL2 */
    gl.texImage2D(gl.TEXTURE_2D, 0, (context.isWebGL2 && context.extRenderToTextureHalfFloat) ? gl.RGBA16F : gl.RGBA, width, height, 0, gl.RGBA, type, null);
    fbo.colorAttachment.set(texture);
}

function renderTextureToMap(painter         , layer                   ) {
    const context = painter.context;
    const gl = context.gl;

    // Here we bind two different textures from which we'll sample in drawing
    // heatmaps: the kernel texture, prepared in the offscreen pass, and a
    // color ramp texture.
    const fbo = layer.heatmapFbo;
    if (!fbo) return;
    context.activeTexture.set(gl.TEXTURE0);
    gl.bindTexture(gl.TEXTURE_2D, fbo.colorAttachment.get());

    context.activeTexture.set(gl.TEXTURE1);
    let colorRampTexture = layer.colorRampTexture;
    if (!colorRampTexture) {
        colorRampTexture = layer.colorRampTexture = new index.Texture(context, layer.colorRamp, gl.RGBA);
    }
    colorRampTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);

    painter.useProgram('heatmapTexture').draw(context, gl.TRIANGLES,
        index.DepthMode.disabled, index.StencilMode.disabled, painter.colorModeForRenderPass(), index.CullFaceMode.disabled,
        heatmapTextureUniformValues(painter, layer, 0, 1),
        layer.id, painter.viewportBuffer, painter.quadTriangleIndexBuffer,
        painter.viewportSegments, layer.paint, painter.transform.zoom);
}

//      


function drawLine(painter         , sourceCache             , layer                , coords                         ) {
    if (painter.renderPass !== 'translucent') return;

    const opacity = layer.paint.get('line-opacity');
    const width = layer.paint.get('line-width');
    if (opacity.constantOr(1) === 0 || width.constantOr(1) === 0) return;

    const depthMode = painter.depthModeForSublayer(0, index.DepthMode.ReadOnly);
    const colorMode = painter.colorModeForRenderPass();
    const pixelRatio = (painter.terrain && painter.terrain.renderingToTexture) ? 1.0 : index.exported.devicePixelRatio;

    const dasharrayProperty = layer.paint.get('line-dasharray');
    const dasharray = dasharrayProperty.constantOr((1     ));
    const capProperty = layer.layout.get('line-cap');
    const patternProperty = layer.paint.get('line-pattern');
    const image = patternProperty.constantOr((1     ));

    const gradient = layer.paint.get('line-gradient');

    const programId = image ? 'linePattern' : 'line';

    const context = painter.context;
    const gl = context.gl;

    const definesValues = lineDefinesValues(layer);
    let useStencilMaskRenderPass = definesValues.includes('RENDER_LINE_ALPHA_DISCARD');
    if (painter.terrain && painter.terrain.clipOrMaskOverlapStencilType()) {
        useStencilMaskRenderPass = false;
    }

    for (const coord of coords) {
        const tile = sourceCache.getTile(coord);
        if (image && !tile.patternsLoaded()) continue;

        const bucket              = (tile.getBucket(layer)     );
        if (!bucket) continue;
        painter.prepareDrawTile();

        const programConfiguration = bucket.programConfigurations.get(layer.id);
        const program = painter.useProgram(programId, programConfiguration, ((definesValues     )                      ));

        const constantPattern = patternProperty.constantOr(null);
        if (constantPattern && tile.imageAtlas) {
            const posTo = tile.imageAtlas.patternPositions[constantPattern.toString()];
            if (posTo) programConfiguration.setConstantPatternPositions(posTo);
        }

        const constantDash = dasharrayProperty.constantOr(null);
        const constantCap = capProperty.constantOr((null     ));

        if (!image && constantDash && constantCap && tile.lineAtlas) {
            const posTo = tile.lineAtlas.getDash(constantDash, constantCap);
            if (posTo) programConfiguration.setConstantPatternPositions(posTo);
        }

        let [trimStart, trimEnd] = layer.paint.get('line-trim-offset');
        // When line cap is 'round' or 'square', the whole line progress will beyond 1.0 or less than 0.0.
        // If trim_offset begin is line begin (0.0), or trim_offset end is line end (1.0), adjust the trim
        // offset with fake offset shift so that the line_progress < 0.0 or line_progress > 1.0 part will be
        // correctly covered.
        if (constantCap === 'round' || constantCap === 'square') {
            // Fake the percentage so that it will cover the round/square cap that is beyond whole line
            const fakeOffsetShift = 1.0;
            // To make sure that the trim offset range is effecive
            if (trimStart !== trimEnd) {
                if (trimStart === 0.0) {
                    trimStart -= fakeOffsetShift;
                }
                if (trimEnd === 1.0) {
                    trimEnd += fakeOffsetShift;
                }
            }
        }

        const matrix = painter.terrain ? coord.projMatrix : null;
        const uniformValues = image ?
            linePatternUniformValues(painter, tile, layer, matrix, pixelRatio) :
            lineUniformValues(painter, tile, layer, matrix, bucket.lineClipsArray.length, pixelRatio, [trimStart, trimEnd]);

        if (gradient) {
            const layerGradient = bucket.gradients[layer.id];
            let gradientTexture = layerGradient.texture;
            if (layer.gradientVersion !== layerGradient.version) {
                let textureResolution = 256;
                if (layer.stepInterpolant) {
                    const sourceMaxZoom = sourceCache.getSource().maxzoom;
                    const potentialOverzoom = coord.canonical.z === sourceMaxZoom ?
                        Math.ceil(1 << (painter.transform.maxZoom - coord.canonical.z)) : 1;
                    const lineLength = bucket.maxLineLength / index.EXTENT;
                    // Logical pixel tile size is 512px, and 1024px right before current zoom + 1
                    const maxTilePixelSize = 1024;
                    // Maximum possible texture coverage heuristic, bound by hardware max texture size
                    const maxTextureCoverage = lineLength * maxTilePixelSize * potentialOverzoom;
                    textureResolution = index.clamp(index.nextPowerOfTwo(maxTextureCoverage), 256, context.maxTextureSize);
                }
                layerGradient.gradient = index.renderColorRamp({
                    expression: layer.gradientExpression(),
                    evaluationKey: 'lineProgress',
                    resolution: textureResolution,
                    image: layerGradient.gradient || undefined,
                    clips: bucket.lineClipsArray
                });
                if (layerGradient.texture) {
                    layerGradient.texture.update(layerGradient.gradient);
                } else {
                    layerGradient.texture = new index.Texture(context, layerGradient.gradient, gl.RGBA);
                }
                layerGradient.version = layer.gradientVersion;
                gradientTexture = layerGradient.texture;
            }
            context.activeTexture.set(gl.TEXTURE1);
            gradientTexture.bind(layer.stepInterpolant ? gl.NEAREST : gl.LINEAR, gl.CLAMP_TO_EDGE);
        }
        if (dasharray) {
            context.activeTexture.set(gl.TEXTURE0);
            tile.lineAtlasTexture.bind(gl.LINEAR, gl.REPEAT);
            programConfiguration.updatePaintBuffers();
        }
        if (image) {
            context.activeTexture.set(gl.TEXTURE0);
            tile.imageAtlasTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);
            programConfiguration.updatePaintBuffers();
        }

        painter.prepareDrawProgram(context, program, coord.toUnwrapped());

        const renderLine = (stencilMode             ) => {
            program.draw(context, gl.TRIANGLES, depthMode,
                stencilMode, colorMode, index.CullFaceMode.disabled, uniformValues,
                layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer, bucket.segments,
                layer.paint, painter.transform.zoom, programConfiguration, [bucket.layoutVertexBuffer2]);
        };

        if (useStencilMaskRenderPass) {
            const stencilId = painter.stencilModeForClipping(coord).ref;
            // When terrain is on, ensure that the stencil buffer has 0 values.
            // As stencil may be disabled when it is not in overlapping stencil
            // mode. Refer to stencilModeForRTTOverlap logic.
            if (stencilId === 0 && painter.terrain) {
                context.clear({stencil: 0});
            }
            const stencilFunc = {func: gl.EQUAL, mask: 0xFF};

            // Allow line geometry fragment to be drawn only once:
            // - Invert the stencil identifier left by stencil clipping, this
            // ensures that we are not conflicting with neighborhing tiles.
            // - Draw Anti-Aliased pixels with a threshold set to 0.8, this
            // may draw Anti-Aliased pixels more than once, but due to their
            // low opacity, these pixels are usually invisible and potential
            // overlapping pixel artifacts locally minimized.
            uniformValues['u_alpha_discard_threshold'] = 0.8;
            renderLine(new index.StencilMode(stencilFunc, stencilId, 0xFF, gl.KEEP, gl.KEEP, gl.INVERT));
            uniformValues['u_alpha_discard_threshold'] = 0.0;
            renderLine(new index.StencilMode(stencilFunc, stencilId, 0xFF, gl.KEEP, gl.KEEP, gl.KEEP));
        } else {
            renderLine(painter.stencilModeForClipping(coord));
        }
    }

    // When rendering to stencil, reset the mask to make sure that the tile
    // clipping reverts the stencil mask we may have drawn in the buffer.
    // The stamp could be reverted by an extra draw call of line geometry,
    // but tile clipping drawing is usually faster to draw than lines.
    if (useStencilMaskRenderPass) {
        painter.resetStencilClippingMasks();
        if (painter.terrain) { context.clear({stencil: 0}); }
    }
}

//      


function drawFill(painter         , sourceCache             , layer                , coords                         ) {
    const color = layer.paint.get('fill-color');
    const opacity = layer.paint.get('fill-opacity');

    if (opacity.constantOr(1) === 0) {
        return;
    }

    const colorMode = painter.colorModeForRenderPass();

    const pattern = layer.paint.get('fill-pattern');
    const pass = painter.opaquePassEnabledForLayer() &&
        (!pattern.constantOr((1     )) &&
        color.constantOr(index.Color.transparent).a === 1 &&
        opacity.constantOr(0) === 1) ? 'opaque' : 'translucent';

    // Draw fill
    if (painter.renderPass === pass) {
        const depthMode = painter.depthModeForSublayer(
            1, painter.renderPass === 'opaque' ? index.DepthMode.ReadWrite : index.DepthMode.ReadOnly);
        drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode, false);
    }

    // Draw stroke
    if (painter.renderPass === 'translucent' && layer.paint.get('fill-antialias')) {

        // If we defined a different color for the fill outline, we are
        // going to ignore the bits in 0x07 and just care about the global
        // clipping mask.
        // Otherwise, we only want to drawFill the antialiased parts that are
        // *outside* the current shape. This is important in case the fill
        // or stroke color is translucent. If we wouldn't clip to outside
        // the current shape, some pixels from the outline stroke overlapped
        // the (non-antialiased) fill.
        const depthMode = painter.depthModeForSublayer(
            layer.getPaintProperty('fill-outline-color') ? 2 : 0, index.DepthMode.ReadOnly);
        drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode, true);
    }
}

function drawFillTiles(painter         , sourceCache             , layer                , coords                         , depthMode           , colorMode           , isOutline         ) {
    const gl = painter.context.gl;

    const patternProperty = layer.paint.get('fill-pattern');
    const image = patternProperty && patternProperty.constantOr((1     ));
    let drawMode, programName, uniformValues, indexBuffer, segments;

    if (!isOutline) {
        programName = image ? 'fillPattern' : 'fill';
        drawMode = gl.TRIANGLES;
    } else {
        programName = image && !layer.getPaintProperty('fill-outline-color') ? 'fillOutlinePattern' : 'fillOutline';
        drawMode = gl.LINES;
    }

    for (const coord of coords) {
        const tile = sourceCache.getTile(coord);
        if (image && !tile.patternsLoaded()) continue;

        const bucket              = (tile.getBucket(layer)     );
        if (!bucket) continue;
        painter.prepareDrawTile();

        const programConfiguration = bucket.programConfigurations.get(layer.id);
        const program = painter.useProgram(programName, programConfiguration);

        if (image) {
            painter.context.activeTexture.set(gl.TEXTURE0);
            tile.imageAtlasTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);
            programConfiguration.updatePaintBuffers();
        }

        const constantPattern = patternProperty.constantOr(null);
        if (constantPattern && tile.imageAtlas) {
            const atlas = tile.imageAtlas;
            const posTo = atlas.patternPositions[constantPattern.toString()];
            if (posTo) programConfiguration.setConstantPatternPositions(posTo);
        }

        const tileMatrix = painter.translatePosMatrix(coord.projMatrix, tile,
            layer.paint.get('fill-translate'), layer.paint.get('fill-translate-anchor'));

        if (!isOutline) {
            indexBuffer = bucket.indexBuffer;
            segments = bucket.segments;
            uniformValues = image ?
                fillPatternUniformValues(tileMatrix, painter, tile) :
                fillUniformValues(tileMatrix);
        } else {
            indexBuffer = bucket.indexBuffer2;
            segments = bucket.segments2;
            const drawingBufferSize = (painter.terrain && painter.terrain.renderingToTexture) ? painter.terrain.drapeBufferSize : [gl.drawingBufferWidth, gl.drawingBufferHeight];
            uniformValues = (programName === 'fillOutlinePattern' && image) ?
                fillOutlinePatternUniformValues(tileMatrix, painter, tile, drawingBufferSize) :
                fillOutlineUniformValues(tileMatrix, drawingBufferSize);
        }

        painter.prepareDrawProgram(painter.context, program, coord.toUnwrapped());

        program.draw(painter.context, drawMode, depthMode,
            painter.stencilModeForClipping(coord), colorMode, index.CullFaceMode.disabled, uniformValues,
            layer.id, bucket.layoutVertexBuffer, indexBuffer, segments,
            layer.paint, painter.transform.zoom, programConfiguration);
    }
}

//      


function draw$1(painter         , source             , layer                         , coords                         ) {
    const opacity = layer.paint.get('fill-extrusion-opacity');
    if (opacity === 0) {
        return;
    }

    if (painter.renderPass === 'translucent') {
        const depthMode = new index.DepthMode(painter.context.gl.LEQUAL, index.DepthMode.ReadWrite, painter.depthRangeFor3D);

        if (opacity === 1 && !layer.paint.get('fill-extrusion-pattern').constantOr((1     ))) {
            const colorMode = painter.colorModeForRenderPass();
            drawExtrusionTiles(painter, source, layer, coords, depthMode, index.StencilMode.disabled, colorMode);

        } else {
            // Draw transparent buildings in two passes so that only the closest surface is drawn.
            // First draw all the extrusions into only the depth buffer. No colors are drawn.
            drawExtrusionTiles(painter, source, layer, coords, depthMode,
                index.StencilMode.disabled,
                index.ColorMode.disabled);

            // Then draw all the extrusions a second type, only coloring fragments if they have the
            // same depth value as the closest fragment in the previous pass. Use the stencil buffer
            // to prevent the second draw in cases where we have coincident polygons.
            drawExtrusionTiles(painter, source, layer, coords, depthMode,
                painter.stencilModeFor3D(),
                painter.colorModeForRenderPass());

            painter.resetStencilClippingMasks();
        }
    }
}

function drawExtrusionTiles(painter         , source             , layer                         , coords                         , depthMode           , stencilMode             , colorMode           ) {
    const context = painter.context;
    const gl = context.gl;
    const tr = painter.transform;
    const patternProperty = layer.paint.get('fill-extrusion-pattern');
    const image = patternProperty.constantOr((1     ));
    const opacity = layer.paint.get('fill-extrusion-opacity');
    const ao = [layer.paint.get('fill-extrusion-ambient-occlusion-intensity'), layer.paint.get('fill-extrusion-ambient-occlusion-radius')];
    const edgeRadius = layer.layout.get('fill-extrusion-edge-radius');
    const zeroRoofRadius = edgeRadius > 0 && !layer.paint.get('fill-extrusion-rounded-roof');
    const roofEdgeRadius = zeroRoofRadius ? 0.0 : edgeRadius;
    const heightLift = tr.projection.name === 'globe' ? index.fillExtrusionHeightLift() : 0;
    const isGlobeProjection = tr.projection.name === 'globe';
    const globeToMercator = isGlobeProjection ? index.globeToMercatorTransition(tr.zoom) : 0.0;
    const mercatorCenter = [index.mercatorXfromLng(tr.center.lng), index.mercatorYfromLat(tr.center.lat)];
    const baseDefines = ([]     );
    if (isGlobeProjection) {
        baseDefines.push('PROJECTION_GLOBE_VIEW');
    }
    if (ao[0] > 0) { // intensity
        baseDefines.push('FAUX_AO');
    }
    if (zeroRoofRadius) {
        baseDefines.push('ZERO_ROOF_RADIUS');
    }

    for (const coord of coords) {
        const tile = source.getTile(coord);
        const bucket                       = (tile.getBucket(layer)     );
        if (!bucket || bucket.projection.name !== tr.projection.name) continue;

        const programConfiguration = bucket.programConfigurations.get(layer.id);
        const program = painter.useProgram(image ? 'fillExtrusionPattern' : 'fillExtrusion', programConfiguration, baseDefines);

        if (painter.terrain) {
            const terrain = painter.terrain;
            if (painter.style.terrainSetForDrapingOnly()) {
                terrain.setupElevationDraw(tile, program, {useMeterToDem: true});
            } else {
                if (!bucket.enableTerrain) continue;
                terrain.setupElevationDraw(tile, program, {useMeterToDem: true});
                flatRoofsUpdate(context, source, coord, bucket, layer, terrain);
                if (!bucket.centroidVertexBuffer) {
                    const attrIndex                = program.attributes['a_centroid_pos'];
                    if (attrIndex !== undefined) gl.vertexAttrib2f(attrIndex, 0, 0);
                }
            }
        }

        if (image) {
            painter.context.activeTexture.set(gl.TEXTURE0);
            tile.imageAtlasTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);
            programConfiguration.updatePaintBuffers();
        }
        const constantPattern = patternProperty.constantOr(null);
        if (constantPattern && tile.imageAtlas) {
            const atlas = tile.imageAtlas;
            const posTo = atlas.patternPositions[constantPattern.toString()];
            if (posTo) programConfiguration.setConstantPatternPositions(posTo);
        }

        const matrix = painter.translatePosMatrix(
            coord.projMatrix,
            tile,
            layer.paint.get('fill-extrusion-translate'),
            layer.paint.get('fill-extrusion-translate-anchor'));

        const invMatrix = tr.projection.createInversionMatrix(tr, coord.canonical);

        const shouldUseVerticalGradient = layer.paint.get('fill-extrusion-vertical-gradient');
        const uniformValues = image ?
            fillExtrusionPatternUniformValues(matrix, painter, shouldUseVerticalGradient, opacity, ao, roofEdgeRadius, coord,
                tile, heightLift, globeToMercator, mercatorCenter, invMatrix) :
            fillExtrusionUniformValues(matrix, painter, shouldUseVerticalGradient, opacity, ao, roofEdgeRadius, coord,
                heightLift, globeToMercator, mercatorCenter, invMatrix);

        painter.prepareDrawProgram(context, program, coord.toUnwrapped());

        index.assert(!isGlobeProjection || bucket.layoutVertexExtBuffer);

        const dynamicBuffers = [];
        if (painter.terrain) dynamicBuffers.push(bucket.centroidVertexBuffer);
        if (isGlobeProjection) dynamicBuffers.push(bucket.layoutVertexExtBuffer);

        program.draw(context, context.gl.TRIANGLES, depthMode, stencilMode, colorMode, index.CullFaceMode.backCCW,
            uniformValues, layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer,
            bucket.segments, layer.paint, painter.transform.zoom,
            programConfiguration, dynamicBuffers);
    }
}

// Flat roofs array is prepared in the bucket, except for buildings that are on tile borders.
// For them, join pieces, calculate joined size here, and then upload data.
function flatRoofsUpdate(context         , source             , coord                  , bucket                     , layer                         , terrain         ) {
    // For all four borders: 0 - left, 1, right, 2 - top, 3 - bottom
    const neighborCoord = [
        (coord                  ) => {
            let x = coord.canonical.x - 1;
            let w = coord.wrap;
            if (x < 0) {
                x = (1 << coord.canonical.z) - 1;
                w--;
            }
            return new index.OverscaledTileID(coord.overscaledZ, w, coord.canonical.z, x, coord.canonical.y);
        },
        (coord                  ) => {
            let x = coord.canonical.x + 1;
            let w = coord.wrap;
            if (x === 1 << coord.canonical.z) {
                x = 0;
                w++;
            }
            return new index.OverscaledTileID(coord.overscaledZ, w, coord.canonical.z, x, coord.canonical.y);
        },
        (coord                  ) => new index.OverscaledTileID(coord.overscaledZ, coord.wrap, coord.canonical.z, coord.canonical.x,
            (coord.canonical.y === 0 ? 1 << coord.canonical.z : coord.canonical.y) - 1),
        (coord                  ) => new index.OverscaledTileID(coord.overscaledZ, coord.wrap, coord.canonical.z, coord.canonical.x,
            coord.canonical.y === (1 << coord.canonical.z) - 1 ? 0 : coord.canonical.y + 1)
    ];

    const getLoadedBucket = (nid                  ) => {
        const minzoom = source.getSource().minzoom;
        const getBucket = (key        ) => {
            const n = source.getTileByID(key);
            if (n && n.hasData()) {
                return n.getBucket(layer);
            }
        };
        // Look one tile zoom above and under. We do this to avoid flickering and
        // use the content in Z-1 and Z+1 buckets until Z bucket is loaded or handle
        // behavior on borders between different zooms.
        const zoomLevels = [0, -1, 1];
        for (const i of zoomLevels) {
            const z = nid.overscaledZ + i;
            if (z < minzoom) continue;
            const key = nid.calculateScaledKey(nid.overscaledZ + i);
            const b = getBucket(key);
            if (b) {
                return b;
            }
        }
    };

    const projectedToBorder = [0, 0, 0]; // [min, max, maxOffsetFromBorder]
    const xjoin = (a              , b              ) => {
        projectedToBorder[0] = Math.min(a.min.y, b.min.y);
        projectedToBorder[1] = Math.max(a.max.y, b.max.y);
        projectedToBorder[2] = index.EXTENT - b.min.x > a.max.x ? b.min.x - index.EXTENT : a.max.x;
        return projectedToBorder;
    };
    const yjoin = (a              , b              ) => {
        projectedToBorder[0] = Math.min(a.min.x, b.min.x);
        projectedToBorder[1] = Math.max(a.max.x, b.max.x);
        projectedToBorder[2] = index.EXTENT - b.min.y > a.max.y ? b.min.y - index.EXTENT : a.max.y;
        return projectedToBorder;
    };
    const projectCombinedSpanToBorder = [
        (a              , b              ) => xjoin(a, b),
        (a              , b              ) => xjoin(b, a),
        (a              , b              ) => yjoin(a, b),
        (a              , b              ) => yjoin(b, a)
    ];

    const centroid = new index.Point(0, 0);
    const error = 3; // Allow intrusion of a building to the building with adjacent wall.

    let demTile, neighborDEMTile, neighborTileID;

    const flatBase = (min        , max        , edge        , verticalEdge         , maxOffsetFromBorder        ) => {
        const points = [[verticalEdge ? edge : min, verticalEdge ? min : edge, 0], [verticalEdge ? edge : max, verticalEdge ? max : edge, 0]];

        const coord3 = maxOffsetFromBorder < 0 ? index.EXTENT + maxOffsetFromBorder : maxOffsetFromBorder;
        const thirdPoint = [verticalEdge ? coord3 : (min + max) / 2, verticalEdge ? (min + max) / 2 : coord3, 0];
        if ((edge === 0 && maxOffsetFromBorder < 0) || (edge !== 0 && maxOffsetFromBorder > 0)) {
            // Third point is inside neighbor tile, not in the |coord| tile.
            terrain.getForTilePoints(neighborTileID, [thirdPoint], true, neighborDEMTile);
        } else {
            points.push(thirdPoint);
        }
        terrain.getForTilePoints(coord, points, true, demTile);
        return Math.max(points[0][2], points[1][2], thirdPoint[2]) / terrain.exaggeration();
    };

    // Process all four borders: get neighboring tile
    for (let i = 0; i < 4; i++) {
        // borders / borderDoneWithNeighborZ: 0 - left, 1, right, 2 - top, 3 - bottom
        // bucket's border i is neighboring bucket's border j:
        const j = (i < 2 ? 1 : 5) - i;
        // Sort by border intersection area minimums, ascending.
        const a = bucket.borders[i];
        if (a.length === 0) continue;
        const nid = neighborTileID = neighborCoord[i](coord);
        const nBucket = getLoadedBucket(nid);
        if (!nBucket || !(nBucket instanceof index.FillExtrusionBucket) || !nBucket.enableTerrain) continue;
        if (bucket.borderDoneWithNeighborZ[i] === nBucket.canonical.z &&
            nBucket.borderDoneWithNeighborZ[j] === bucket.canonical.z) {
            continue;
        }

        neighborDEMTile = terrain.findDEMTileFor(nid);
        if (!neighborDEMTile || !neighborDEMTile.dem) continue;
        if (!demTile) {
            const dem = terrain.findDEMTileFor(coord);
            if (!(dem && dem.dem)) return; // defer update until an elevation tile is available.
            demTile = dem;
        }
        const b = nBucket.borders[j];
        let ib = 0;

        const updateNeighbor = nBucket.borderDoneWithNeighborZ[j] !== bucket.canonical.z;
        // If neighbors are of different canonical z, we cannot join parts but show
        // all without flat roofs.
        if (bucket.canonical.z !== nBucket.canonical.z) {
            for (const index of a) {
                bucket.encodeCentroid(undefined, bucket.featuresOnBorder[index], false);
            }
            if (updateNeighbor) {
                for (const index of b) {
                    nBucket.encodeCentroid(undefined, nBucket.featuresOnBorder[index], false);
                }
                nBucket.borderDoneWithNeighborZ[j] = bucket.canonical.z;
                nBucket.needsCentroidUpdate = true;
            }
            bucket.borderDoneWithNeighborZ[i] = nBucket.canonical.z;
            bucket.needsCentroidUpdate = true;
            continue;
        }

        for (let ia = 0; ia < a.length; ia++) {
            const parta = bucket.featuresOnBorder[a[ia]];
            const partABorderRange = parta.borders[i];
            // Find all nBucket parts that share the border overlap.
            let partb;
            while (ib < b.length) {
                // Pass all that are before the overlap.
                partb = nBucket.featuresOnBorder[b[ib]];
                const partBBorderRange = partb.borders[j];
                if (partBBorderRange[1] > partABorderRange[0] + error) break;
                if (updateNeighbor) nBucket.encodeCentroid(undefined, partb, false);
                ib++;
            }
            if (partb && ib < b.length) {
                const saveIb = ib;
                let count = 0;
                while (true) {
                    // Collect all parts overlapping parta on the edge, to make sure it is only one.
                    const partBBorderRange = partb.borders[j];
                    if (partBBorderRange[0] > partABorderRange[1] - error) break;
                    count++;
                    if (++ib === b.length) break;
                    partb = nBucket.featuresOnBorder[b[ib]];
                }
                partb = nBucket.featuresOnBorder[b[saveIb]];

                // If any of a or b crosses more than one tile edge, don't support flat roof.
                if (parta.intersectsCount() > 1 || partb.intersectsCount() > 1 || count !== 1) {
                    if (count !== 1) {
                        ib = saveIb; // rewind unprocessed ib so that it is processed again for the next ia.
                    }

                    bucket.encodeCentroid(undefined, parta, false);
                    if (updateNeighbor) nBucket.encodeCentroid(undefined, partb, false);
                    continue;
                }

                // Now we have 1-1 matching of parts in both tiles that share the edge. Calculate flat base elevation
                // as average of three points: 2 are edge points (combined span projected to border) and one is point of
                // span that has maximum offset to border.
                const span = projectCombinedSpanToBorder[i](parta, partb);
                const edge = (i % 2) ? index.EXTENT - 1 : 0;
                centroid.x = flatBase(span[0], Math.min(index.EXTENT - 1, span[1]), edge, i < 2, span[2]);
                centroid.y = 0;
                index.assert(parta.vertexArrayOffset !== undefined && parta.vertexArrayOffset < bucket.layoutVertexArray.length);
                bucket.encodeCentroid(centroid, parta, false);

                index.assert(partb.vertexArrayOffset !== undefined && partb.vertexArrayOffset < nBucket.layoutVertexArray.length);
                if (updateNeighbor) nBucket.encodeCentroid(centroid, partb, false);
            } else {
                index.assert(parta.intersectsCount() > 1 || (partb && partb.intersectsCount() > 1)); // expected at the end of border, when buildings cover corner (show building w/o flat roof).
                bucket.encodeCentroid(undefined, parta, false);
            }
        }

        bucket.borderDoneWithNeighborZ[i] = nBucket.canonical.z;
        bucket.needsCentroidUpdate = true;
        if (updateNeighbor) {
            nBucket.borderDoneWithNeighborZ[j] = bucket.canonical.z;
            nBucket.needsCentroidUpdate = true;
        }
    }

    if (bucket.needsCentroidUpdate || (!bucket.centroidVertexBuffer && bucket.centroidVertexArray.length !== 0)) {
        bucket.uploadCentroid(context);
    }
}

//      


function drawRaster(painter         , sourceCache             , layer                  , tileIDs                         , variableOffsets     , isInitialLoad         ) {
    if (painter.renderPass !== 'translucent') return;
    if (layer.paint.get('raster-opacity') === 0) return;
    if (!tileIDs.length) return;

    const context = painter.context;
    const gl = context.gl;
    const source = sourceCache.getSource();
    const program = painter.useProgram('raster');

    const colorMode = painter.colorModeForRenderPass();

    // When rendering to texture, coordinates are already sorted: primary by
    // proxy id and secondary sort is by Z.
    const renderingToTexture = painter.terrain && painter.terrain.renderingToTexture;

    const [stencilModes, coords] = source instanceof ImageSource || renderingToTexture ? [{}, tileIDs] :
        painter.stencilConfigForOverlap(tileIDs);

    const minTileZ = coords[coords.length - 1].overscaledZ;

    const align = !painter.options.moving;
    for (const coord of coords) {
        // Set the lower zoom level to sublayer 0, and higher zoom levels to higher sublayers
        // Use gl.LESS to prevent double drawing in areas where tiles overlap.
        const depthMode = renderingToTexture ? index.DepthMode.disabled : painter.depthModeForSublayer(coord.overscaledZ - minTileZ,
            layer.paint.get('raster-opacity') === 1 ? index.DepthMode.ReadWrite : index.DepthMode.ReadOnly, gl.LESS);

        const unwrappedTileID = coord.toUnwrapped();
        const tile = sourceCache.getTile(coord);
        if (renderingToTexture && !(tile && tile.hasData())) continue;

        const projMatrix = (renderingToTexture) ? coord.projMatrix :
            painter.transform.calculateProjMatrix(unwrappedTileID, align);

        const stencilMode = painter.terrain && renderingToTexture ?
            painter.terrain.stencilModeForRTTOverlap(coord) :
            stencilModes[coord.overscaledZ];

        const rasterFadeDuration = isInitialLoad ? 0 : layer.paint.get('raster-fade-duration');
        tile.registerFadeDuration(rasterFadeDuration);

        const parentTile = sourceCache.findLoadedParent(coord, 0);
        const fade = rasterFade(tile, parentTile, sourceCache, painter.transform, rasterFadeDuration);
        if (painter.terrain) painter.terrain.prepareDrawTile();

        let parentScaleBy, parentTL;

        const textureFilter = layer.paint.get('raster-resampling') === 'nearest' ? gl.NEAREST : gl.LINEAR;

        context.activeTexture.set(gl.TEXTURE0);
        tile.texture.bind(textureFilter, gl.CLAMP_TO_EDGE);

        context.activeTexture.set(gl.TEXTURE1);

        if (parentTile) {
            parentTile.texture.bind(textureFilter, gl.CLAMP_TO_EDGE);
            parentScaleBy = Math.pow(2, parentTile.tileID.overscaledZ - tile.tileID.overscaledZ);
            parentTL = [tile.tileID.canonical.x * parentScaleBy % 1, tile.tileID.canonical.y * parentScaleBy % 1];

        } else {
            tile.texture.bind(textureFilter, gl.CLAMP_TO_EDGE);
        }

        // Enable trilinear filtering on tiles only beyond 20 degrees pitch,
        // to prevent it from compromising image crispness on flat or low tilted maps.
        if (tile.texture.useMipmap && context.extTextureFilterAnisotropic && painter.transform.pitch > 20) {
            gl.texParameterf(gl.TEXTURE_2D, context.extTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT, context.extTextureFilterAnisotropicMax);
        }

        const perspectiveTransform = source instanceof ImageSource ? source.perspectiveTransform : [0, 0];
        const uniformValues = rasterUniformValues(projMatrix, parentTL || [0, 0], parentScaleBy || 1, fade, layer, perspectiveTransform);

        painter.prepareDrawProgram(context, program, unwrappedTileID);

        if (source instanceof ImageSource) {
            if (source.boundsBuffer && source.boundsSegments) program.draw(
                context, gl.TRIANGLES, depthMode, index.StencilMode.disabled, colorMode, index.CullFaceMode.disabled,
                uniformValues, layer.id, source.boundsBuffer,
                painter.quadTriangleIndexBuffer, source.boundsSegments);
        } else {
            const {tileBoundsBuffer, tileBoundsIndexBuffer, tileBoundsSegments} = painter.getTileBoundsBuffers(tile);

            program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, index.CullFaceMode.disabled,
                uniformValues, layer.id, tileBoundsBuffer,
                tileBoundsIndexBuffer, tileBoundsSegments);
        }
    }

    painter.resetStencilClippingMasks();
}

//      


function drawBackground(painter         , sourceCache             , layer                      , coords                         ) {
    const color = layer.paint.get('background-color');
    const opacity = layer.paint.get('background-opacity');

    if (opacity === 0) return;

    const context = painter.context;
    const gl = context.gl;
    const transform = painter.transform;
    const tileSize = transform.tileSize;
    const image = layer.paint.get('background-pattern');
    if (painter.isPatternMissing(image)) return;

    const pass = (!image && color.a === 1 && opacity === 1 && painter.opaquePassEnabledForLayer()) ? 'opaque' : 'translucent';
    if (painter.renderPass !== pass) return;

    const stencilMode = index.StencilMode.disabled;
    const depthMode = painter.depthModeForSublayer(0, pass === 'opaque' ? index.DepthMode.ReadWrite : index.DepthMode.ReadOnly);
    const colorMode = painter.colorModeForRenderPass();

    const program = painter.useProgram(image ? 'backgroundPattern' : 'background');

    let tileIDs = coords;
    let backgroundTiles;
    if (!tileIDs) {
        backgroundTiles = painter.getBackgroundTiles();
        tileIDs = Object.values(backgroundTiles).map(tile => (tile     ).tileID);
    }

    if (image) {
        context.activeTexture.set(gl.TEXTURE0);
        painter.imageManager.bind(painter.context);
    }

    for (const tileID of tileIDs) {
        const unwrappedTileID = tileID.toUnwrapped();
        const matrix = coords ? tileID.projMatrix : painter.transform.calculateProjMatrix(unwrappedTileID);
        painter.prepareDrawTile();

        const tile = sourceCache ? sourceCache.getTile(tileID) :
            backgroundTiles ? backgroundTiles[tileID.key] : new index.Tile(tileID, tileSize, transform.zoom, painter);

        const uniformValues = image ?
            backgroundPatternUniformValues(matrix, opacity, painter, image, {tileID, tileSize}) :
            backgroundUniformValues(matrix, opacity, color);

        painter.prepareDrawProgram(context, program, unwrappedTileID);

        const {tileBoundsBuffer, tileBoundsIndexBuffer, tileBoundsSegments} = painter.getTileBoundsBuffers(tile);

        program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, index.CullFaceMode.disabled,
            uniformValues, layer.id, tileBoundsBuffer,
                tileBoundsIndexBuffer, tileBoundsSegments);
    }
}

//      


                                        
                                                         
                                                           

const topColor = new index.Color(1, 0, 0, 1);
const btmColor = new index.Color(0, 1, 0, 1);
const leftColor = new index.Color(0, 0, 1, 1);
const rightColor = new index.Color(1, 0, 1, 1);
const centerColor = new index.Color(0, 1, 1, 1);

function drawDebug(painter         , sourceCache             , coords                         ) {
    for (let i = 0; i < coords.length; i++) {
        drawDebugTile(painter, sourceCache, coords[i]);
    }
}

function drawDebugPadding(painter         ) {
    const padding = painter.transform.padding;
    const lineWidth = 3;
    // Top
    drawHorizontalLine(painter, painter.transform.height - (padding.top || 0), lineWidth, topColor);
    // Bottom
    drawHorizontalLine(painter, padding.bottom || 0, lineWidth, btmColor);
    // Left
    drawVerticalLine(painter, padding.left || 0, lineWidth, leftColor);
    // Right
    drawVerticalLine(painter, painter.transform.width - (padding.right || 0), lineWidth, rightColor);
    // Center
    const center = painter.transform.centerPoint;
    drawCrosshair(painter, center.x, painter.transform.height - center.y, centerColor);
}

function drawDebugQueryGeometry(painter         , sourceCache             , coords                         ) {
    for (let i = 0; i < coords.length; i++) {
        drawTileQueryGeometry(painter, sourceCache, coords[i]);
    }
}

function drawDebugTile(painter         , sourceCache             , coord                  ) {
    const context = painter.context;
    const tr = painter.transform;
    const gl = context.gl;

    const isGlobeProjection = tr.projection.name === 'globe';
    const definesValues = isGlobeProjection ? ['PROJECTION_GLOBE_VIEW'] : null;

    let posMatrix = coord.projMatrix;

    if (isGlobeProjection && index.globeToMercatorTransition(tr.zoom) > 0) {
        // We use a custom tile matrix here in order to handle the globe-to-mercator transition
        // the following is equivalent to transform.calculatePosMatrix,
        // except we use transitionTileAABBinECEF instead of globeTileBounds to account for the transition.
        const bounds = index.transitionTileAABBinECEF(coord.canonical, tr);
        const decode = index.globeDenormalizeECEF(bounds);
        posMatrix = index.multiply(new Float32Array(16), tr.globeMatrix, decode);
        index.multiply(posMatrix, tr.projMatrix, posMatrix);
    }

    const program = painter.useProgram('debug', null, definesValues);
    const tile = sourceCache.getTileByID(coord.key);
    if (painter.terrain) painter.terrain.setupElevationDraw(tile, program);

    const depthMode = index.DepthMode.disabled;
    const stencilMode = index.StencilMode.disabled;
    const colorMode = painter.colorModeForRenderPass();
    const id = '$debug';

    context.activeTexture.set(gl.TEXTURE0);
    // Bind the empty texture for drawing outlines
    painter.emptyTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);

    if (isGlobeProjection) {
        tile._makeGlobeTileDebugBuffers(painter.context, tr);
    } else {
        tile._makeDebugTileBoundsBuffers(painter.context, tr.projection);
    }

    const debugBuffer = tile._tileDebugBuffer || painter.debugBuffer;
    const debugIndexBuffer = tile._tileDebugIndexBuffer || painter.debugIndexBuffer;
    const debugSegments = tile._tileDebugSegments || painter.debugSegments;

    program.draw(context, gl.LINE_STRIP, depthMode, stencilMode, colorMode, index.CullFaceMode.disabled,
        debugUniformValues(posMatrix, index.Color.red), id,
        debugBuffer, debugIndexBuffer, debugSegments,
        null, null, null, [tile._globeTileDebugBorderBuffer]);

    const tileRawData = tile.latestRawTileData;
    const tileByteLength = (tileRawData && tileRawData.byteLength) || 0;
    const tileSizeKb = Math.floor(tileByteLength / 1024);
    const tileSize = sourceCache.getTile(coord).tileSize;
    const scaleRatio = (512 / Math.min(tileSize, 512) * (coord.overscaledZ / tr.zoom)) * 0.5;
    let tileLabel = coord.canonical.toString();
    if (coord.overscaledZ !== coord.canonical.z) {
        tileLabel += ` => ${coord.overscaledZ}`;
    }
    tileLabel += ` ${tileSizeKb}kb`;
    drawTextToOverlay(painter, tileLabel);

    const debugTextBuffer = tile._tileDebugTextBuffer || painter.debugBuffer;
    const debugTextIndexBuffer = tile._tileDebugTextIndexBuffer || painter.quadTriangleIndexBuffer;
    const debugTextSegments = tile._tileDebugTextSegments || painter.debugSegments;

    program.draw(context, gl.TRIANGLES, depthMode, stencilMode, index.ColorMode.alphaBlended, index.CullFaceMode.disabled,
        debugUniformValues(posMatrix, index.Color.transparent, scaleRatio), id,
        debugTextBuffer, debugTextIndexBuffer, debugTextSegments,
        null, null, null, [tile._globeTileDebugTextBuffer]);
}

function drawCrosshair(painter         , x        , y        , color       ) {
    const size = 20;
    const lineWidth = 2;
    //Vertical line
    drawDebugSSRect(painter, x - lineWidth / 2, y - size / 2, lineWidth, size, color);
    //Horizontal line
    drawDebugSSRect(painter, x - size / 2, y - lineWidth / 2, size, lineWidth, color);
}

function drawHorizontalLine(painter         , y        , lineWidth        , color       ) {
    drawDebugSSRect(painter, 0, y  + lineWidth / 2, painter.transform.width,  lineWidth, color);
}

function drawVerticalLine(painter         , x        , lineWidth        , color       ) {
    drawDebugSSRect(painter, x - lineWidth / 2, 0, lineWidth,  painter.transform.height, color);
}

function drawDebugSSRect(painter         , x        , y        , width        , height        , color       ) {
    const context = painter.context;
    const gl = context.gl;

    gl.enable(gl.SCISSOR_TEST);
    gl.scissor(x * index.exported.devicePixelRatio, y * index.exported.devicePixelRatio, width * index.exported.devicePixelRatio, height * index.exported.devicePixelRatio);
    context.clear({color});
    gl.disable(gl.SCISSOR_TEST);
}

function drawTileQueryGeometry(painter         , sourceCache             , coord                  ) {
    const context = painter.context;
    const gl = context.gl;

    const posMatrix = coord.projMatrix;
    const program = painter.useProgram('debug');
    const tile = sourceCache.getTileByID(coord.key);
    if (painter.terrain) painter.terrain.setupElevationDraw(tile, program);

    const depthMode = index.DepthMode.disabled;
    const stencilMode = index.StencilMode.disabled;
    const colorMode = painter.colorModeForRenderPass();
    const id = '$debug';

    context.activeTexture.set(gl.TEXTURE0);
    // Bind the empty texture for drawing outlines
    painter.emptyTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);

    const queryViz = tile.queryGeometryDebugViz;
    const boundsViz = tile.queryBoundsDebugViz;

    if (queryViz && queryViz.vertices.length > 0) {
        queryViz.lazyUpload(context);
        const vertexBuffer = queryViz.vertexBuffer;
        const indexBuffer = queryViz.indexBuffer;
        const segments = queryViz.segments;
        if (vertexBuffer != null && indexBuffer != null && segments != null) {
            program.draw(context, gl.LINE_STRIP, depthMode, stencilMode, colorMode, index.CullFaceMode.disabled,
                debugUniformValues(posMatrix, queryViz.color), id,
                vertexBuffer, indexBuffer, segments);
        }
    }

    if (boundsViz && boundsViz.vertices.length > 0) {
        boundsViz.lazyUpload(context);
        const vertexBuffer = boundsViz.vertexBuffer;
        const indexBuffer = boundsViz.indexBuffer;
        const segments = boundsViz.segments;
        if (vertexBuffer != null && indexBuffer != null && segments != null) {
            program.draw(context, gl.LINE_STRIP, depthMode, stencilMode, colorMode, index.CullFaceMode.disabled,
                debugUniformValues(posMatrix, boundsViz.color), id,
                vertexBuffer, indexBuffer, segments);
        }
    }
}

function drawTextToOverlay(painter         , text        ) {
    painter.initDebugOverlayCanvas();
    const canvas = painter.debugOverlayCanvas;
    const gl = painter.context.gl;
    const ctx2d = painter.debugOverlayCanvas.getContext('2d');
    ctx2d.clearRect(0, 0, canvas.width, canvas.height);

    ctx2d.shadowColor = 'white';
    ctx2d.shadowBlur = 2;
    ctx2d.lineWidth = 1.5;
    ctx2d.strokeStyle = 'white';
    ctx2d.textBaseline = 'top';
    ctx2d.font = `bold ${36}px Open Sans, sans-serif`;
    ctx2d.fillText(text, 5, 5);
    ctx2d.strokeText(text, 5, 5);

    painter.debugOverlayTexture.update(canvas);
    painter.debugOverlayTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);
}

//      


function drawCustom(painter         , sourceCache             , layer                  , coords                         ) {

    const context = painter.context;
    const implementation = layer.implementation;

    if (painter.transform.projection.unsupportedLayers && painter.transform.projection.unsupportedLayers.includes("custom") &&
        !(painter.terrain && (painter.terrain.renderingToTexture || painter.renderPass === 'offscreen') && layer.isLayerDraped())) {
        index.warnOnce('Custom layers are not yet supported with this projection. Use mercator or globe to enable usage of custom layers.');
        return;
    }

    if (painter.renderPass === 'offscreen') {

        const prerender = implementation.prerender;
        if (prerender) {
            painter.setCustomLayerDefaults();
            context.setColorMode(painter.colorModeForRenderPass());

            if (painter.transform.projection.name === "globe") {
                const center = painter.transform.pointMerc;
                prerender.call(implementation, context.gl, painter.transform.customLayerMatrix(), painter.transform.getProjection(), painter.transform.globeToMercatorMatrix(),  index.globeToMercatorTransition(painter.transform.zoom), [center.x, center.y], painter.transform.pixelsPerMeterRatio);
            } else {
                prerender.call(implementation, context.gl, painter.transform.customLayerMatrix());
            }

            context.setDirty();
            painter.setBaseState();
        }

    } else if (painter.renderPass === 'translucent') {

        if (painter.terrain && painter.terrain.renderingToTexture) {
            index.assert(implementation.renderToTile);
            index.assert(coords.length === 1);
            const renderToTile = implementation.renderToTile;
            if (renderToTile) {
                const c = coords[0].canonical;
                const unwrapped = new index.MercatorCoordinate(c.x + coords[0].wrap * (1 << c.z), c.y, c.z);

                context.setDepthMode(index.DepthMode.disabled);
                context.setStencilMode(index.StencilMode.disabled);
                context.setColorMode(painter.colorModeForRenderPass());
                painter.setCustomLayerDefaults();

                renderToTile.call(implementation, context.gl, unwrapped);
                context.setDirty();
                painter.setBaseState();
            }
            return;
        }

        painter.setCustomLayerDefaults();

        context.setColorMode(painter.colorModeForRenderPass());
        context.setStencilMode(index.StencilMode.disabled);

        const depthMode = implementation.renderingMode === '3d' ?
            new index.DepthMode(painter.context.gl.LEQUAL, index.DepthMode.ReadWrite, painter.depthRangeFor3D) :
            painter.depthModeForSublayer(0, index.DepthMode.ReadOnly);

        context.setDepthMode(depthMode);

        if (painter.transform.projection.name === "globe") {
            const center = painter.transform.pointMerc;
            implementation.render(context.gl, painter.transform.customLayerMatrix(), painter.transform.getProjection(), painter.transform.globeToMercatorMatrix(), index.globeToMercatorTransition(painter.transform.zoom), [center.x, center.y], painter.transform.pixelsPerMeterRatio);
        } else {
            implementation.render(context.gl, painter.transform.customLayerMatrix());
        }

        context.setDirty();
        painter.setBaseState();
        context.bindFramebuffer.set(null);
    }
}

//      

                                                               

const skyboxAttributes                    = index.createLayout([
    {name: 'a_pos_3f',  components: 3, type: 'Float32'}
]);
const {members, size, alignment} = skyboxAttributes;

//      

                                                     
                                                       
                                            

function addVertex(vertexArray                   , x        , y        , z        ) {
    vertexArray.emplaceBack(
        // a_pos
        x,
        y,
        z
    );
}

class SkyboxGeometry {
                                   
                               
                                
                             
                           

    constructor(context         ) {
        this.vertexArray = new index.StructArrayLayout3f12();
        this.indices = new index.StructArrayLayout3ui6();

        addVertex(this.vertexArray, -1.0, -1.0,  1.0);
        addVertex(this.vertexArray,  1.0, -1.0,  1.0);
        addVertex(this.vertexArray, -1.0,  1.0,  1.0);
        addVertex(this.vertexArray,  1.0,  1.0,  1.0);
        addVertex(this.vertexArray, -1.0, -1.0, -1.0);
        addVertex(this.vertexArray,  1.0, -1.0, -1.0);
        addVertex(this.vertexArray, -1.0,  1.0, -1.0);
        addVertex(this.vertexArray,  1.0,  1.0, -1.0);

        // +x
        this.indices.emplaceBack(5, 1, 3);
        this.indices.emplaceBack(3, 7, 5);
        // -x
        this.indices.emplaceBack(6, 2, 0);
        this.indices.emplaceBack(0, 4, 6);
        // +y
        this.indices.emplaceBack(2, 6, 7);
        this.indices.emplaceBack(7, 3, 2);
        // -y
        this.indices.emplaceBack(5, 4, 0);
        this.indices.emplaceBack(0, 1, 5);
        // +z
        this.indices.emplaceBack(0, 2, 3);
        this.indices.emplaceBack(3, 1, 0);
        // -z
        this.indices.emplaceBack(7, 6, 4);
        this.indices.emplaceBack(4, 5, 7);

        this.vertexBuffer = context.createVertexBuffer(this.vertexArray, members);
        this.indexBuffer = context.createIndexBuffer(this.indices);

        this.segment = index.SegmentVector.simpleSegment(0, 0, 36, 12);
    }
}

//      


const TRANSITION_OPACITY_ZOOM_START = 7;
const TRANSITION_OPACITY_ZOOM_END = 8;

function drawSky(painter         , sourceCache             , layer          ) {
    const tr = painter.transform;
    const globeOrMercator = (tr.projection.name === 'mercator' || tr.projection.name === 'globe');
    // For non-mercator projection, use a forced opacity transition. This transition is set to be
    // 1.0 after the sheer adjustment upper bound which ensures to be in the mercator projection.
    // Note: we only render sky for globe projection during the transition to mercator.
    const transitionOpacity = globeOrMercator ? 1.0 : index.smoothstep(TRANSITION_OPACITY_ZOOM_START, TRANSITION_OPACITY_ZOOM_END, tr.zoom);
    const opacity = layer.paint.get('sky-opacity') * transitionOpacity;
    if (opacity === 0) {
        return;
    }

    const context = painter.context;
    const type = layer.paint.get('sky-type');
    const depthMode = new index.DepthMode(context.gl.LEQUAL, index.DepthMode.ReadOnly, [0, 1]);
    const temporalOffset = (painter.frameCounter / 1000.0) % 1;

    if (type === 'atmosphere') {
        if (painter.renderPass === 'offscreen') {
            if (layer.needsSkyboxCapture(painter)) {
                captureSkybox(painter, layer, 32, 32);
                layer.markSkyboxValid(painter);
            }
        } else if (painter.renderPass === 'sky') {
            drawSkyboxFromCapture(painter, layer, depthMode, opacity, temporalOffset);
        }
    } else if (type === 'gradient') {
        if (painter.renderPass === 'sky') {
            drawSkyboxGradient(painter, layer, depthMode, opacity, temporalOffset);
        }
    } else {
        index.assert(false, `${type} is unsupported sky-type`);
    }
}

function drawSkyboxGradient(painter         , layer          , depthMode           , opacity        , temporalOffset        ) {
    const context = painter.context;
    const gl = context.gl;
    const transform = painter.transform;
    const program = painter.useProgram('skyboxGradient');

    // Lazily initialize geometry and texture if they havent been created yet.
    if (!layer.skyboxGeometry) {
        layer.skyboxGeometry = new SkyboxGeometry(context);
    }
    context.activeTexture.set(gl.TEXTURE0);
    let colorRampTexture = layer.colorRampTexture;
    if (!colorRampTexture) {
        colorRampTexture = layer.colorRampTexture = new index.Texture(context, layer.colorRamp, gl.RGBA);
    }
    colorRampTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);
    const uniformValues = skyboxGradientUniformValues(
        transform.skyboxMatrix,
        layer.getCenter(painter, false),
        layer.paint.get('sky-gradient-radius'),
        opacity,
        temporalOffset
    );

    painter.prepareDrawProgram(context, program);

    program.draw(context, gl.TRIANGLES, depthMode, index.StencilMode.disabled,
        painter.colorModeForRenderPass(), index.CullFaceMode.backCW,
        uniformValues, 'skyboxGradient', layer.skyboxGeometry.vertexBuffer,
        layer.skyboxGeometry.indexBuffer, layer.skyboxGeometry.segment);
}

function drawSkyboxFromCapture(painter         , layer          , depthMode           , opacity        , temporalOffset        ) {
    const context = painter.context;
    const gl = context.gl;
    const transform = painter.transform;
    const program = painter.useProgram('skybox');

    context.activeTexture.set(gl.TEXTURE0);

    gl.bindTexture(gl.TEXTURE_CUBE_MAP, layer.skyboxTexture);

    const uniformValues = skyboxUniformValues(transform.skyboxMatrix, layer.getCenter(painter, false), 0, opacity, temporalOffset);

    painter.prepareDrawProgram(context, program);

    program.draw(context, gl.TRIANGLES, depthMode, index.StencilMode.disabled,
        painter.colorModeForRenderPass(), index.CullFaceMode.backCW,
        uniformValues, 'skybox', layer.skyboxGeometry.vertexBuffer,
        layer.skyboxGeometry.indexBuffer, layer.skyboxGeometry.segment);
}

function drawSkyboxFace(context         , layer          , program              , faceRotate      , sunDirection                          , i        ) {
    const gl = context.gl;

    const atmosphereColor = layer.paint.get('sky-atmosphere-color');
    const atmosphereHaloColor = layer.paint.get('sky-atmosphere-halo-color');
    const sunIntensity = layer.paint.get('sky-atmosphere-sun-intensity');

    const uniformValues = skyboxCaptureUniformValues(
        index.fromMat4(index.create$1(), faceRotate),
        sunDirection,
        sunIntensity,
        atmosphereColor,
        atmosphereHaloColor);

    const glFace = gl.TEXTURE_CUBE_MAP_POSITIVE_X + i;
    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, glFace, layer.skyboxTexture, 0);

    program.draw(context, gl.TRIANGLES, index.DepthMode.disabled, index.StencilMode.disabled, index.ColorMode.unblended, index.CullFaceMode.frontCW,
        uniformValues, 'skyboxCapture', layer.skyboxGeometry.vertexBuffer,
        layer.skyboxGeometry.indexBuffer, layer.skyboxGeometry.segment);
}

function captureSkybox(painter         , layer          , width        , height        ) {
    const context = painter.context;
    const gl = context.gl;
    let fbo = layer.skyboxFbo;

    // Using absence of fbo as a signal for lazy initialization of all resources, cache resources in layer object
    if (!fbo) {
        fbo = layer.skyboxFbo = context.createFramebuffer(width, height, false);
        layer.skyboxGeometry = new SkyboxGeometry(context);
        layer.skyboxTexture = context.gl.createTexture();

        gl.bindTexture(gl.TEXTURE_CUBE_MAP, layer.skyboxTexture);
        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);

        for (let i = 0; i < 6; ++i) {
            const glFace = gl.TEXTURE_CUBE_MAP_POSITIVE_X + i;

            // The format here could be RGB, but render tests are not happy with rendering to such a format
            gl.texImage2D(glFace, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
        }
    }

    context.bindFramebuffer.set(fbo.framebuffer);
    context.viewport.set([0, 0, width, height]);

    const sunDirection = layer.getCenter(painter, true);
    const program = painter.useProgram('skyboxCapture');
    const faceRotate = new Float64Array(16);

    // +x;
    index.identity(faceRotate);
    index.rotateY(faceRotate, faceRotate, -Math.PI * 0.5);
    drawSkyboxFace(context, layer, program, faceRotate, sunDirection, 0);
    // -x
    index.identity(faceRotate);
    index.rotateY(faceRotate, faceRotate, Math.PI * 0.5);
    drawSkyboxFace(context, layer, program, faceRotate, sunDirection, 1);
    // +y
    index.identity(faceRotate);
    index.rotateX(faceRotate, faceRotate, -Math.PI * 0.5);
    drawSkyboxFace(context, layer, program, faceRotate, sunDirection, 2);
    // -y
    index.identity(faceRotate);
    index.rotateX(faceRotate, faceRotate, Math.PI * 0.5);
    drawSkyboxFace(context, layer, program, faceRotate, sunDirection, 3);
    // +z
    index.identity(faceRotate);
    drawSkyboxFace(context, layer, program, faceRotate, sunDirection, 4);
    // -z
    index.identity(faceRotate);
    index.rotateY(faceRotate, faceRotate, Math.PI);
    drawSkyboxFace(context, layer, program, faceRotate, sunDirection, 5);

    context.viewport.set([0, 0, painter.width, painter.height]);
}

//      


function drawAtmosphere(painter         , fog     ) {
    const context = painter.context;
    const gl = context.gl;
    const tr = painter.transform;
    const depthMode = new index.DepthMode(gl.LEQUAL, index.DepthMode.ReadOnly, [0, 1]);
    const defines = tr.projection.name === 'globe' ? ['PROJECTION_GLOBE_VIEW', 'FOG'] : ['FOG'];
    const program = painter.useProgram('globeAtmosphere', null, ((defines     )                      ));

    const transitionT = index.globeToMercatorTransition(tr.zoom);

    const fogColor = fog.properties.get('color').toArray01();
    const highColor = fog.properties.get('high-color').toArray01();
    const spaceColor = fog.properties.get('space-color').toArray01PremultipliedAlpha();

    const orientation = index.identity$1([]);

    index.rotateY$1(orientation, orientation, -index.degToRad(tr._center.lng));
    index.rotateX$1(orientation, orientation, index.degToRad(tr._center.lat));

    index.rotateZ$1(orientation, orientation, tr.angle);
    index.rotateX$1(orientation, orientation, -tr._pitch);

    const rotationMatrix = index.fromQuat(new Float32Array(16), orientation);

    const starIntensity = index.mapValue(fog.properties.get('star-intensity'), 0.0, 1.0, 0.0, 0.25);
    // https://www.desmos.com/calculator/oanvvpr36d
    // Ensure horizon blend is 0-exclusive to prevent division by 0 in the shader
    const minHorizonBlend = 0.0005;
    const horizonBlend = index.mapValue(fog.properties.get('horizon-blend'), 0.0, 1.0, minHorizonBlend, 0.25);

    // Use a slightly smaller size of the globe to account for custom
    // antialiasing that reduces the size of the globe of two pixels
    // https://www.desmos.com/calculator/xpgmzghc37
    const globeRadius = index.globeUseCustomAntiAliasing(painter, context, tr) && horizonBlend === minHorizonBlend ?
        tr.worldSize / (2.0 * Math.PI * 1.025) - 1.0 : tr.globeRadius;

    const temporalOffset = (painter.frameCounter / 1000.0) % 1;
    const globeCenterInViewSpace = (((tr.globeCenterInViewSpace)     )               );
    const globeCenterDistance = index.length(globeCenterInViewSpace);
    const distanceToHorizon = Math.sqrt(Math.pow(globeCenterDistance, 2.0) - Math.pow(globeRadius, 2.0));
    const horizonAngle = Math.acos(distanceToHorizon / globeCenterDistance);

    const uniforms = atmosphereUniformValues(
        tr.frustumCorners.TL,
        tr.frustumCorners.TR,
        tr.frustumCorners.BR,
        tr.frustumCorners.BL,
        tr.frustumCorners.horizon,
        transitionT,
        horizonBlend,
        fogColor,
        highColor,
        spaceColor,
        starIntensity,
        temporalOffset,
        horizonAngle,
        rotationMatrix);

    painter.prepareDrawProgram(context, program);

    const buffer = painter.atmosphereBuffer;
    if (buffer) {
        program.draw(context, gl.TRIANGLES, depthMode, index.StencilMode.disabled,
            index.ColorMode.alphaBlended, index.CullFaceMode.backCW, uniforms, "skybox",
            buffer.vertexBuffer, buffer.indexBuffer, buffer.segments);
    }
}

//      

                                                               

const atmosphereLayout                    = index.createLayout([
    {type: 'Float32', name: 'a_pos', components: 3},
    {type: 'Float32', name: 'a_uv', components: 2}
]);

//      
                                                     

class AtmosphereBuffer {
                               
                             
                            

    constructor(context         ) {
        const vertices = new index.StructArrayLayout5f20();
        vertices.emplaceBack(-1, 1, 1, 0, 0);
        vertices.emplaceBack(1, 1, 1, 1, 0);
        vertices.emplaceBack(1, -1, 1, 1, 1);
        vertices.emplaceBack(-1, -1, 1, 0, 1);

        const triangles = new index.StructArrayLayout3ui6();
        triangles.emplaceBack(0, 1, 2);
        triangles.emplaceBack(2, 3, 0);

        this.vertexBuffer = context.createVertexBuffer(vertices, atmosphereLayout.members);
        this.indexBuffer = context.createIndexBuffer(triangles);
        this.segments = index.SegmentVector.simpleSegment(0, 0, 4, 2);
    }

    destroy() {
        this.vertexBuffer.destroy();
        this.indexBuffer.destroy();
        this.segments.destroy();
    }
}

//      


const draw = {
    symbol: drawSymbols,
    circle: drawCircles,
    heatmap: drawHeatmap,
    line: drawLine,
    fill: drawFill,
    'fill-extrusion': draw$1,
    hillshade: drawHillshade,
    raster: drawRaster,
    background: drawBackground,
    sky: drawSky,
    debug: drawDebug,
    custom: drawCustom
};

                                                 
                                                                            
                                           
                                                      
                                                   
                                                   
                                                       
                                                     
                                                                                 
                                                                                  
                                                                      

                                                                        
                                   
                                 
                        
 

                       
                                   
                                
                                  
                               
                           
                         
                      
                     
                    
                       
                                     
                         
                           
                             
 

                           
                                 
                                     
                                    
   

                                          

/**
 * Initialize a new painter object.
 *
 * @param {Canvas} gl an experimental-webgl drawing context
 * @private
 */
class Painter {
                     
                         
                                                  
                         
                         
                                                    
                  
                   
                                   
                                      
                              
                                  
                                 
                                 
                                    
                                         
                                       
                                          
                                                 
                                  
                 
                            
                               
                               
                                    
                             
                         
                           
                         
                                  
                          
               
                                    
                                      
                             
                         
                                             
                          
                              
                                 
                                          
                       
                                            
                                       
                        
                                     
                                  
                                            

    constructor(gl                       , transform           , isWebGL2          = false) {
        this.context = new index.Context(gl, isWebGL2);
        this.transform = transform;
        this._tileTextures = {};
        this.frameCopies = [];
        this.loadTimeStamps = [];

        this.setup();

        // Within each layer there are multiple distinct z-planes that can be drawn to.
        // This is implemented using the WebGL depth buffer.
        this.numSublayers = index.SourceCache.maxUnderzooming + index.SourceCache.maxOverzooming + 1;
        this.depthEpsilon = 1 / Math.pow(2, 16);

        this.deferredRenderGpuTimeQueries = [];
        this.gpuTimers = {};
        this.frameCounter = 0;
        this._backgroundTiles = {};
    }

    updateTerrain(style       , adaptCameraAltitude         ) {
        const enabled = !!style && !!style.terrain && this.transform.projection.supportsTerrain;
        if (!enabled && (!this._terrain || !this._terrain.enabled)) return;
        if (!this._terrain) {
            this._terrain = new Terrain(this, style);
        }
        const terrain          = this._terrain;
        this.transform.elevation = enabled ? terrain : null;
        terrain.update(style, this.transform, adaptCameraAltitude);
    }

    _updateFog(style       ) {
        // Globe makes use of thin fog overlay with a fixed fog range,
        // so we can skip updating fog tile culling for this projection
        const isGlobe = this.transform.projection.name === 'globe';

        const fog = style.fog;
        if (!fog || isGlobe || fog.getOpacity(this.transform.pitch) < 1 || fog.properties.get('horizon-blend') < 0.03) {
            this.transform.fogCullDistSq = null;
            return;
        }

        // We start culling where the fog opacity function hits
        // 98% which leaves a non-noticeable change threshold.
        const [start, end] = fog.getFovAdjustedRange(this.transform._fov);

        if (start > end) {
            this.transform.fogCullDistSq = null;
            return;
        }

        const fogBoundFraction = 0.78;
        const fogCullDist = start + (end - start) * fogBoundFraction;

        this.transform.fogCullDistSq = fogCullDist * fogCullDist;
    }

    get terrain()           {
        return this.transform._terrainEnabled() && this._terrain && this._terrain.enabled ? this._terrain : null;
    }

    /*
     * Update the GL viewport, projection matrix, and transforms to compensate
     * for a new width and height value.
     */
    resize(width        , height        ) {
        this.width = width * index.exported.devicePixelRatio;
        this.height = height * index.exported.devicePixelRatio;
        this.context.viewport.set([0, 0, this.width, this.height]);

        if (this.style) {
            for (const layerId of this.style.order) {
                this.style._layers[layerId].resize();
            }
        }
    }

    setup() {
        const context = this.context;

        const tileExtentArray = new index.StructArrayLayout2i4();
        tileExtentArray.emplaceBack(0, 0);
        tileExtentArray.emplaceBack(index.EXTENT, 0);
        tileExtentArray.emplaceBack(0, index.EXTENT);
        tileExtentArray.emplaceBack(index.EXTENT, index.EXTENT);
        this.tileExtentBuffer = context.createVertexBuffer(tileExtentArray, index.posAttributes.members);
        this.tileExtentSegments = index.SegmentVector.simpleSegment(0, 0, 4, 2);

        const debugArray = new index.StructArrayLayout2i4();
        debugArray.emplaceBack(0, 0);
        debugArray.emplaceBack(index.EXTENT, 0);
        debugArray.emplaceBack(0, index.EXTENT);
        debugArray.emplaceBack(index.EXTENT, index.EXTENT);
        this.debugBuffer = context.createVertexBuffer(debugArray, index.posAttributes.members);
        this.debugSegments = index.SegmentVector.simpleSegment(0, 0, 4, 5);

        const viewportArray = new index.StructArrayLayout2i4();
        viewportArray.emplaceBack(-1, -1);
        viewportArray.emplaceBack(1, -1);
        viewportArray.emplaceBack(-1, 1);
        viewportArray.emplaceBack(1, 1);
        this.viewportBuffer = context.createVertexBuffer(viewportArray, index.posAttributes.members);
        this.viewportSegments = index.SegmentVector.simpleSegment(0, 0, 4, 2);

        const tileBoundsArray = new index.StructArrayLayout4i8();
        tileBoundsArray.emplaceBack(0, 0, 0, 0);
        tileBoundsArray.emplaceBack(index.EXTENT, 0, index.EXTENT, 0);
        tileBoundsArray.emplaceBack(0, index.EXTENT, 0, index.EXTENT);
        tileBoundsArray.emplaceBack(index.EXTENT, index.EXTENT, index.EXTENT, index.EXTENT);
        this.mercatorBoundsBuffer = context.createVertexBuffer(tileBoundsArray, index.boundsAttributes.members);
        this.mercatorBoundsSegments = index.SegmentVector.simpleSegment(0, 0, 4, 2);

        const quadTriangleIndices = new index.StructArrayLayout3ui6();
        quadTriangleIndices.emplaceBack(0, 1, 2);
        quadTriangleIndices.emplaceBack(2, 1, 3);
        this.quadTriangleIndexBuffer = context.createIndexBuffer(quadTriangleIndices);

        const tileLineStripIndices = new index.StructArrayLayout1ui2();
        for (const i of [0, 1, 3, 2, 0]) tileLineStripIndices.emplaceBack(i);
        this.debugIndexBuffer = context.createIndexBuffer(tileLineStripIndices);

        this.emptyTexture = new index.Texture(context,
            new index.RGBAImage({width: 1, height: 1}, Uint8Array.of(0, 0, 0, 0)), context.gl.RGBA);

        this.identityMat = index.create();

        const gl = this.context.gl;
        this.stencilClearMode = new index.StencilMode({func: gl.ALWAYS, mask: 0}, 0x0, 0xFF, gl.ZERO, gl.ZERO, gl.ZERO);
        this.loadTimeStamps.push(index.window.performance.now());

        this.atmosphereBuffer = new AtmosphereBuffer(this.context);
    }

    getMercatorTileBoundsBuffers()                    {
        return {
            tileBoundsBuffer: this.mercatorBoundsBuffer,
            tileBoundsIndexBuffer: this.quadTriangleIndexBuffer,
            tileBoundsSegments: this.mercatorBoundsSegments
        };
    }

    getTileBoundsBuffers(tile      )                    {
        tile._makeTileBoundsBuffers(this.context, this.transform.projection);
        if (tile._tileBoundsBuffer) {
            const tileBoundsBuffer = tile._tileBoundsBuffer;
            const tileBoundsIndexBuffer = tile._tileBoundsIndexBuffer;
            const tileBoundsSegments = tile._tileBoundsSegments;
            return {tileBoundsBuffer, tileBoundsIndexBuffer, tileBoundsSegments};
        } else {
            return this.getMercatorTileBoundsBuffers();
        }
    }

    /*
     * Reset the drawing canvas by clearing the stencil buffer so that we can draw
     * new tiles at the same location, while retaining previously drawn pixels.
     */
    clearStencil() {
        const context = this.context;
        const gl = context.gl;

        this.nextStencilID = 1;
        this.currentStencilSource = undefined;
        this._tileClippingMaskIDs = {};

        // As a temporary workaround for https://github.com/mapbox/mapbox-gl-js/issues/5490,
        // pending an upstream fix, we draw a fullscreen stencil=0 clipping mask here,
        // effectively clearing the stencil buffer: once an upstream patch lands, remove
        // this function in favor of context.clear({ stencil: 0x0 })
        this.useProgram('clippingMask').draw(context, gl.TRIANGLES,
            index.DepthMode.disabled, this.stencilClearMode, index.ColorMode.disabled, index.CullFaceMode.disabled,
            clippingMaskUniformValues(this.identityMat),
            '$clipping', this.viewportBuffer,
            this.quadTriangleIndexBuffer, this.viewportSegments);
    }

    resetStencilClippingMasks() {
        if (!this.terrain) {
            this.currentStencilSource = undefined;
            this._tileClippingMaskIDs = {};
        }
    }

    _renderTileClippingMasks(layer            , sourceCache              , tileIDs                          ) {
        if (!sourceCache || this.currentStencilSource === sourceCache.id || !layer.isTileClipped() || !tileIDs || tileIDs.length === 0) {
            return;
        }

        if (this._tileClippingMaskIDs && !this.terrain) {
            let dirtyStencilClippingMasks = false;
            // Equivalent tile set is already rendered in stencil
            for (const coord of tileIDs) {
                if (this._tileClippingMaskIDs[coord.key] === undefined) {
                    dirtyStencilClippingMasks = true;
                    break;
                }
            }
            if (!dirtyStencilClippingMasks) {
                return;
            }
        }

        this.currentStencilSource = sourceCache.id;

        const context = this.context;
        const gl = context.gl;

        if (this.nextStencilID + tileIDs.length > 256) {
            // we'll run out of fresh IDs so we need to clear and start from scratch
            this.clearStencil();
        }

        context.setColorMode(index.ColorMode.disabled);
        context.setDepthMode(index.DepthMode.disabled);

        const program = this.useProgram('clippingMask');

        this._tileClippingMaskIDs = {};

        for (const tileID of tileIDs) {
            const tile = sourceCache.getTile(tileID);
            const id = this._tileClippingMaskIDs[tileID.key] = this.nextStencilID++;
            const {tileBoundsBuffer, tileBoundsIndexBuffer, tileBoundsSegments} = this.getTileBoundsBuffers(tile);

            program.draw(context, gl.TRIANGLES, index.DepthMode.disabled,
            // Tests will always pass, and ref value will be written to stencil buffer.
            new index.StencilMode({func: gl.ALWAYS, mask: 0}, id, 0xFF, gl.KEEP, gl.KEEP, gl.REPLACE),
            index.ColorMode.disabled, index.CullFaceMode.disabled, clippingMaskUniformValues(tileID.projMatrix),
            '$clipping', tileBoundsBuffer,
            tileBoundsIndexBuffer, tileBoundsSegments);
        }
    }

    stencilModeFor3D()              {
        this.currentStencilSource = undefined;

        if (this.nextStencilID + 1 > 256) {
            this.clearStencil();
        }

        const id = this.nextStencilID++;
        const gl = this.context.gl;
        return new index.StencilMode({func: gl.NOTEQUAL, mask: 0xFF}, id, 0xFF, gl.KEEP, gl.KEEP, gl.REPLACE);
    }

    stencilModeForClipping(tileID                  )                          {
        if (this.terrain) return this.terrain.stencilModeForRTTOverlap(tileID);
        const gl = this.context.gl;
        return new index.StencilMode({func: gl.EQUAL, mask: 0xFF}, this._tileClippingMaskIDs[tileID.key], 0x00, gl.KEEP, gl.KEEP, gl.REPLACE);
    }

    /*
     * Sort coordinates by Z as drawing tiles is done in Z-descending order.
     * All children with the same Z write the same stencil value.  Children
     * stencil values are greater than parent's.  This is used only for raster
     * and raster-dem tiles, which are already clipped to tile boundaries, to
     * mask area of tile overlapped by children tiles.
     * Stencil ref values continue range used in _tileClippingMaskIDs.
     *
     * Returns [StencilMode for tile overscaleZ map, sortedCoords].
     */
    stencilConfigForOverlap(tileIDs                         )                                                                   {
        const gl = this.context.gl;
        const coords = tileIDs.sort((a, b) => b.overscaledZ - a.overscaledZ);
        const minTileZ = coords[coords.length - 1].overscaledZ;
        const stencilValues = coords[0].overscaledZ - minTileZ + 1;
        if (stencilValues > 1) {
            this.currentStencilSource = undefined;
            if (this.nextStencilID + stencilValues > 256) {
                this.clearStencil();
            }
            const zToStencilMode = {};
            for (let i = 0; i < stencilValues; i++) {
                zToStencilMode[i + minTileZ] = new index.StencilMode({func: gl.GEQUAL, mask: 0xFF}, i + this.nextStencilID, 0xFF, gl.KEEP, gl.KEEP, gl.REPLACE);
            }
            this.nextStencilID += stencilValues;
            return [zToStencilMode, coords];
        }
        return [{[minTileZ]: index.StencilMode.disabled}, coords];
    }

    colorModeForRenderPass()                       {
        const gl = this.context.gl;
        if (this._showOverdrawInspector) {
            const numOverdrawSteps = 8;
            const a = 1 / numOverdrawSteps;

            return new index.ColorMode([gl.CONSTANT_COLOR, gl.ONE], new index.Color(a, a, a, 0), [true, true, true, true]);
        } else if (this.renderPass === 'opaque') {
            return index.ColorMode.unblended;
        } else {
            return index.ColorMode.alphaBlended;
        }
    }

    depthModeForSublayer(n        , mask               , func                )                       {
        if (!this.opaquePassEnabledForLayer()) return index.DepthMode.disabled;
        const depth = 1 - ((1 + this.currentLayer) * this.numSublayers + n) * this.depthEpsilon;
        return new index.DepthMode(func || this.context.gl.LEQUAL, mask, [depth, depth]);
    }

    /*
     * The opaque pass and 3D layers both use the depth buffer.
     * Layers drawn above 3D layers need to be drawn using the
     * painter's algorithm so that they appear above 3D features.
     * This returns true for layers that can be drawn using the
     * opaque pass.
     */
    opaquePassEnabledForLayer()          {
        return this.currentLayer < this.opaquePassCutoff;
    }

    render(style       , options                ) {
        this.style = style;
        this.options = options;

        this.imageManager = style.imageManager;
        this.glyphManager = style.glyphManager;

        this.symbolFadeChange = style.placement.symbolFadeChange(index.exported.now());

        this.imageManager.beginFrame();

        const layerIds = this.style.order;
        const sourceCaches = this.style._sourceCaches;

        for (const id in sourceCaches) {
            const sourceCache = sourceCaches[id];
            if (sourceCache.used) {
                sourceCache.prepare(this.context);
            }
        }

        const coordsAscending                                         = {};
        const coordsDescending                                         = {};
        const coordsDescendingSymbol                                         = {};

        for (const id in sourceCaches) {
            const sourceCache = sourceCaches[id];
            coordsAscending[id] = sourceCache.getVisibleCoordinates();
            coordsDescending[id] = coordsAscending[id].slice().reverse();
            coordsDescendingSymbol[id] = sourceCache.getVisibleCoordinates(true).reverse();
        }

        this.opaquePassCutoff = Infinity;
        for (let i = 0; i < layerIds.length; i++) {
            const layerId = layerIds[i];
            if (this.style._layers[layerId].is3D()) {
                this.opaquePassCutoff = i;
                break;
            }
        }

        if (this.terrain) {
            this.terrain.updateTileBinding(coordsDescendingSymbol);
            // All render to texture is done in translucent pass to remove need
            // for depth buffer allocation per tile.
            this.opaquePassCutoff = 0;
        }

        if (this.transform.projection.name === 'globe' && !this.globeSharedBuffers) {
            this.globeSharedBuffers = new index.GlobeSharedBuffers(this.context);
        }

        // Following line is billing related code. Do not change. See LICENSE.txt
        if (!index.isMapAuthenticated(this.context.gl)) return;

        // Offscreen pass ===============================================
        // We first do all rendering that requires rendering to a separate
        // framebuffer, and then save those for rendering back to the map
        // later: in doing this we avoid doing expensive framebuffer restores.
        this.renderPass = 'offscreen';

        for (const layerId of layerIds) {
            const layer = this.style._layers[layerId];
            const sourceCache = style._getLayerSourceCache(layer);
            if (!layer.hasOffscreenPass() || layer.isHidden(this.transform.zoom)) continue;

            const coords = sourceCache ? coordsDescending[sourceCache.id] : undefined;
            if (!(layer.type === 'custom' || layer.isSky()) && !(coords && coords.length)) continue;

            this.renderLayer(this, sourceCache, layer, coords);
        }

        this.depthRangeFor3D = [0, 1 - ((style.order.length + 2) * this.numSublayers * this.depthEpsilon)];

        // Terrain depth offscreen render pass ==========================
        // With terrain on, renders the depth buffer into a texture.
        // This texture is used for occlusion testing (labels)
        const terrain = this.terrain;
        if (terrain && (this.style.hasSymbolLayers() || this.style.hasCircleLayers())) {
            terrain.drawDepth();
        }

        // Rebind the main framebuffer now that all offscreen layers have been rendered:
        this.context.bindFramebuffer.set(null);
        this.context.viewport.set([0, 0, this.width, this.height]);

        // Clear buffers in preparation for drawing to the main framebuffer
        this.context.clear({color: options.showOverdrawInspector ? index.Color.black : index.Color.transparent, depth: 1});
        this.clearStencil();

        this._showOverdrawInspector = options.showOverdrawInspector;

        // Opaque pass ===============================================
        // Draw opaque layers top-to-bottom first.
        this.renderPass = 'opaque';

        if (!this.terrain) {
            for (this.currentLayer = layerIds.length - 1; this.currentLayer >= 0; this.currentLayer--) {
                const layer = this.style._layers[layerIds[this.currentLayer]];
                const sourceCache = style._getLayerSourceCache(layer);
                if (layer.isSky()) continue;
                const coords = sourceCache ? coordsDescending[sourceCache.id] : undefined;

                this._renderTileClippingMasks(layer, sourceCache, coords);
                this.renderLayer(this, sourceCache, layer, coords);
            }
        }

        if (this.style.fog && this.transform.projection.supportsFog) {
            drawAtmosphere(this, this.style.fog);
        }

        // Sky pass ======================================================
        // Draw all sky layers bottom to top.
        // They are drawn at max depth, they are drawn after opaque and before
        // translucent to fail depth testing and mix with translucent objects.
        this.renderPass = 'sky';
        const isTransitioning = index.globeToMercatorTransition(this.transform.zoom) > 0.0;
        if ((isTransitioning || this.transform.projection.name !== 'globe') && this.transform.isHorizonVisible()) {
            for (this.currentLayer = 0; this.currentLayer < layerIds.length; this.currentLayer++) {
                const layer = this.style._layers[layerIds[this.currentLayer]];
                const sourceCache = style._getLayerSourceCache(layer);
                if (!layer.isSky()) continue;
                const coords = sourceCache ? coordsDescending[sourceCache.id] : undefined;

                this.renderLayer(this, sourceCache, layer, coords);
            }
        }

        // Translucent pass ===============================================
        // Draw all other layers bottom-to-top.
        this.renderPass = 'translucent';

        this.currentLayer = 0;
        while (this.currentLayer < layerIds.length) {
            const layer = this.style._layers[layerIds[this.currentLayer]];
            const sourceCache = style._getLayerSourceCache(layer);

            // Nothing to draw in translucent pass for sky layers, advance
            if (layer.isSky()) {
                ++this.currentLayer;
                continue;
            }

            // With terrain on and for draped layers only, issue rendering and progress
            // this.currentLayer until the next non-draped layer.
            // Otherwise we interleave terrain draped render with non-draped layers on top
            if (this.terrain && this.style.isLayerDraped(layer)) {
                if (layer.isHidden(this.transform.zoom)) {
                    ++this.currentLayer;
                    continue;
                }
                const terrain = (((this.terrain)     )         );
                const prevLayer = this.currentLayer;
                this.currentLayer = terrain.renderBatch(this.currentLayer);
                index.assert(this.context.bindFramebuffer.current === null);
                index.assert(this.currentLayer > prevLayer);
                continue;
            }

            // For symbol layers in the translucent pass, we add extra tiles to the renderable set
            // for cross-tile symbol fading. Symbol layers don't use tile clipping, so no need to render
            // separate clipping masks
            const coords = sourceCache ?
                (layer.type === 'symbol' ? coordsDescendingSymbol : coordsDescending)[sourceCache.id] :
                undefined;

            this._renderTileClippingMasks(layer, sourceCache, sourceCache ? coordsAscending[sourceCache.id] : undefined);
            this.renderLayer(this, sourceCache, layer, coords);

            ++this.currentLayer;
        }

        if (this.terrain) {
            this.terrain.postRender();
        }

        if (this.options.showTileBoundaries || this.options.showQueryGeometry || this.options.showTileAABBs) {
            //Use source with highest maxzoom
            let selectedSource = null;
            const layers = index.values(this.style._layers);
            layers.forEach((layer) => {
                const sourceCache = style._getLayerSourceCache(layer);
                if (sourceCache && !layer.isHidden(this.transform.zoom)) {
                    if (!selectedSource || (selectedSource.getSource().maxzoom < sourceCache.getSource().maxzoom)) {
                        selectedSource = sourceCache;
                    }
                }
            });
            if (selectedSource) {
                if (this.options.showTileBoundaries) {
                    draw.debug(this, selectedSource, selectedSource.getVisibleCoordinates());
                }

                index.Debug.run(() => {
                    if (!selectedSource) return;
                    if (this.options.showQueryGeometry) {
                        drawDebugQueryGeometry(this, selectedSource, selectedSource.getVisibleCoordinates());
                    }
                    if (this.options.showTileAABBs) {
                        index.Debug.drawAabbs(this, selectedSource, selectedSource.getVisibleCoordinates());
                    }
                });
            }
        }

        if (this.options.showPadding) {
            drawDebugPadding(this);
        }

        // Set defaults for most GL values so that anyone using the state after the render
        // encounters more expected values.
        this.context.setDefault();
        this.frameCounter = (this.frameCounter + 1) % Number.MAX_SAFE_INTEGER;

        if (this.tileLoaded && this.options.speedIndexTiming) {
            this.loadTimeStamps.push(index.window.performance.now());
            this.saveCanvasCopy();
        }
    }

    renderLayer(painter         , sourceCache              , layer            , coords                          ) {
        if (layer.isHidden(this.transform.zoom)) return;
        if (layer.type !== 'background' && layer.type !== 'sky' && layer.type !== 'custom' && !(coords && coords.length)) return;
        this.id = layer.id;

        this.gpuTimingStart(layer);
        if (!painter.transform.projection.unsupportedLayers || !painter.transform.projection.unsupportedLayers.includes(layer.type) ||
            (painter.terrain && layer.type === 'custom')) {
            draw[layer.type](painter, sourceCache, layer, coords, this.style.placement.variableOffsets, this.options.isInitialLoad);
        }
        this.gpuTimingEnd();
    }

    gpuTimingStart(layer            ) {
        if (!this.options.gpuTiming) return;
        const ext = this.context.extTimerQuery;
        // This tries to time the draw call itself, but note that the cost for drawing a layer
        // may be dominated by the cost of uploading vertices to the GPU.
        // To instrument that, we'd need to pass the layerTimers object down into the bucket
        // uploading logic.
        let layerTimer = this.gpuTimers[layer.id];
        if (!layerTimer) {
            layerTimer = this.gpuTimers[layer.id] = {
                calls: 0,
                cpuTime: 0,
                query: ext.createQueryEXT()
            };
        }
        layerTimer.calls++;
        ext.beginQueryEXT(ext.TIME_ELAPSED_EXT, layerTimer.query);
    }

    gpuTimingDeferredRenderStart() {
        if (this.options.gpuTimingDeferredRender) {
            const ext = this.context.extTimerQuery;
            const query = ext.createQueryEXT();
            this.deferredRenderGpuTimeQueries.push(query);
            ext.beginQueryEXT(ext.TIME_ELAPSED_EXT, query);
        }
    }

    gpuTimingDeferredRenderEnd() {
        if (!this.options.gpuTimingDeferredRender) return;
        const ext = this.context.extTimerQuery;
        ext.endQueryEXT(ext.TIME_ELAPSED_EXT);
    }

    gpuTimingEnd() {
        if (!this.options.gpuTiming) return;
        const ext = this.context.extTimerQuery;
        ext.endQueryEXT(ext.TIME_ELAPSED_EXT);
    }

    collectGpuTimers()            {
        const currentLayerTimers = this.gpuTimers;
        this.gpuTimers = {};
        return currentLayerTimers;
    }

    collectDeferredRenderGpuQueries()             {
        const currentQueries = this.deferredRenderGpuTimeQueries;
        this.deferredRenderGpuTimeQueries = [];
        return currentQueries;
    }

    queryGpuTimers(gpuTimers           )                              {
        const layers = {};
        for (const layerId in gpuTimers) {
            const gpuTimer = gpuTimers[layerId];
            const ext = this.context.extTimerQuery;
            const gpuTime = ext.getQueryObjectEXT(gpuTimer.query, ext.QUERY_RESULT_EXT) / (1000 * 1000);
            ext.deleteQueryEXT(gpuTimer.query);
            layers[layerId] = (gpuTime        );
        }
        return layers;
    }

    queryGpuTimeDeferredRender(gpuQueries            )         {
        if (!this.options.gpuTimingDeferredRender) return 0;
        const ext = this.context.extTimerQuery;

        let gpuTime = 0;
        for (const query of gpuQueries) {
            gpuTime += ext.getQueryObjectEXT(query, ext.QUERY_RESULT_EXT) / (1000 * 1000);
            ext.deleteQueryEXT(query);
        }

        return gpuTime;
    }

    /**
     * Transform a matrix to incorporate the *-translate and *-translate-anchor properties into it.
     * @param inViewportPixelUnitsUnits True when the units accepted by the matrix are in viewport pixels instead of tile units.
     * @returns {Float32Array} matrix
     * @private
     */
    translatePosMatrix(matrix              , tile      , translate                  , translateAnchor                    , inViewportPixelUnitsUnits          )               {
        if (!translate[0] && !translate[1]) return matrix;

        const angle = inViewportPixelUnitsUnits ?
            (translateAnchor === 'map' ? this.transform.angle : 0) :
            (translateAnchor === 'viewport' ? -this.transform.angle : 0);

        if (angle) {
            const sinA = Math.sin(angle);
            const cosA = Math.cos(angle);
            translate = [
                translate[0] * cosA - translate[1] * sinA,
                translate[0] * sinA + translate[1] * cosA
            ];
        }

        const translation = [
            inViewportPixelUnitsUnits ? translate[0] : pixelsToTileUnits(tile, translate[0], this.transform.zoom),
            inViewportPixelUnitsUnits ? translate[1] : pixelsToTileUnits(tile, translate[1], this.transform.zoom),
            0
        ];

        const translatedMatrix = new Float32Array(16);
        index.translate(translatedMatrix, matrix, translation);
        return translatedMatrix;
    }

    saveTileTexture(texture         ) {
        const textures = this._tileTextures[texture.size[0]];
        if (!textures) {
            this._tileTextures[texture.size[0]] = [texture];
        } else {
            textures.push(texture);
        }
    }

    getTileTexture(size        )                 {
        const textures = this._tileTextures[size];
        return textures && textures.length > 0 ? textures.pop() : null;
    }

    /**
     * Checks whether a pattern image is needed, and if it is, whether it is not loaded.
     *
     * @returns true if a needed image is missing and rendering needs to be skipped.
     * @private
     */
    isPatternMissing(image                )          {
        if (image === null) return true;
        if (image === undefined) return false;
        return !this.imageManager.getPattern(image.toString());
    }

    terrainRenderModeElevated()          {
        // Whether elevation sampling should be enabled in the vertex shader.
        return this.style && !!this.style.getTerrain() && !!this.terrain && !this.terrain.renderingToTexture;
    }

    /**
     * Returns #defines that would need to be injected into every Program
     * based on the current state of Painter.
     *
     * @returns {string[]}
     * @private
     */
    currentGlobalDefines()           {
        const rtt = this.terrain && this.terrain.renderingToTexture;
        const zeroExaggeration = this.terrain && this.terrain.exaggeration() === 0.0;
        const fog = this.style && this.style.fog;
        const defines = [];

        if (this.terrainRenderModeElevated()) defines.push('TERRAIN');
        if (this.transform.projection.name === 'globe') defines.push('GLOBE');
        if (zeroExaggeration) defines.push('ZERO_EXAGGERATION');
        // When terrain is active, fog is rendered as part of draping, not as part of tile
        // rendering. Removing the fog flag during tile rendering avoids additional defines.
        if (fog && !rtt && fog.getOpacity(this.transform.pitch) !== 0.0) {
            defines.push('FOG');
        }
        if (rtt) defines.push('RENDER_TO_TEXTURE');
        if (this._showOverdrawInspector) defines.push('OVERDRAW_INSPECTOR');
        return defines;
    }

    useProgram(name        , programConfiguration                       , fixedDefines                       )               {
        this.cache = this.cache || {};
        const defines = (((fixedDefines || [])     )          );

        const globalDefines = this.currentGlobalDefines();
        const allDefines = globalDefines.concat(defines);
        const key = Program.cacheKey(shaders[name], name, allDefines, programConfiguration);

        if (!this.cache[key]) {
            this.cache[key] = new Program(this.context, name, shaders[name], programConfiguration, programUniforms[name], allDefines);
        }
        return this.cache[key];
    }

    /*
     * Reset some GL state to default values to avoid hard-to-debug bugs
     * in custom layers.
     */
    setCustomLayerDefaults() {
        // Prevent custom layers from unintentionally modify the last VAO used.
        // All other state is state is restored on it's own, but for VAOs it's
        // simpler to unbind so that we don't have to track the state of VAOs.
        this.context.unbindVAO();

        // The default values for this state is meaningful and often expected.
        // Leaving this state dirty could cause a lot of confusion for users.
        this.context.cullFace.setDefault();
        this.context.frontFace.setDefault();
        this.context.cullFaceSide.setDefault();
        this.context.activeTexture.setDefault();
        this.context.pixelStoreUnpack.setDefault();
        this.context.pixelStoreUnpackPremultiplyAlpha.setDefault();
        this.context.pixelStoreUnpackFlipY.setDefault();
    }

    /*
     * Set GL state that is shared by all layers.
     */
    setBaseState() {
        const gl = this.context.gl;
        this.context.cullFace.set(false);
        this.context.viewport.set([0, 0, this.width, this.height]);
        this.context.blendEquation.set(gl.FUNC_ADD);
    }

    initDebugOverlayCanvas() {
        if (this.debugOverlayCanvas == null) {
            this.debugOverlayCanvas = index.window.document.createElement('canvas');
            this.debugOverlayCanvas.width = 512;
            this.debugOverlayCanvas.height = 512;
            const gl = this.context.gl;
            this.debugOverlayTexture = new index.Texture(this.context, this.debugOverlayCanvas, gl.RGBA);
        }
    }

    destroy() {
        if (this._terrain) {
            this._terrain.destroy();
        }
        if (this.globeSharedBuffers) {
            this.globeSharedBuffers.destroy();
        }
        this.emptyTexture.destroy();
        if (this.debugOverlayTexture) {
            this.debugOverlayTexture.destroy();
        }
        if (this.atmosphereBuffer) {
            this.atmosphereBuffer.destroy();
        }
    }

    prepareDrawTile() {
        if (this.terrain) {
            this.terrain.prepareDrawTile();
        }
    }

    prepareDrawProgram(context         , program            , tileID                  ) {

        // Fog is not enabled when rendering to texture so we
        // can safely skip uploading uniforms in that case
        if (this.terrain && this.terrain.renderingToTexture) {
            return;
        }

        const fog = this.style.fog;

        if (fog) {
            const fogOpacity = fog.getOpacity(this.transform.pitch);
            const fogUniforms = fogUniformValues(
                this, fog, tileID, fogOpacity,
                this.transform.frustumCorners.TL,
                this.transform.frustumCorners.TR,
                this.transform.frustumCorners.BR,
                this.transform.frustumCorners.BL,
                this.transform.globeCenterInViewSpace,
                this.transform.globeRadius,
                [
                    this.transform.width * index.exported.devicePixelRatio,
                    this.transform.height * index.exported.devicePixelRatio
                ]);

            program.setFogUniformValues(context, fogUniforms);
        }
    }

    setTileLoadedFlag(flag         ) {
        this.tileLoaded = flag;
    }

    saveCanvasCopy() {
        const canvas = this.canvasCopy();
        if (!canvas) return;
        this.frameCopies.push(canvas);
        this.tileLoaded = false;
    }

    canvasCopy()                {
        const gl = this.context.gl;
        const texture = gl.createTexture();
        gl.bindTexture(gl.TEXTURE_2D, texture);
        gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight, 0);
        return texture;
    }

    getCanvasCopiesAndTimestamps()                      {
        return {
            canvasCopies: this.frameCopies,
            timeStamps: this.loadTimeStamps
        };
    }

    averageElevationNeedsEasing()          {
        if (!this.transform._elevation) return false;

        const fog = this.style && this.style.fog;
        if (!fog) return false;

        const fogOpacity = fog.getOpacity(this.transform.pitch);
        if (fogOpacity === 0) return false;

        return true;
    }

    getBackgroundTiles()                        {
        const oldTiles = this._backgroundTiles;
        const newTiles = this._backgroundTiles = {};

        const tileSize = 512;
        const tileIDs = this.transform.coveringTiles({tileSize});
        for (const tileID of tileIDs) {
            newTiles[tileID.key] = oldTiles[tileID.key] || new index.Tile(tileID, tileSize, this.transform.tileZoom, this);
        }
        return newTiles;
    }

    clearBackgroundTiles() {
        this._backgroundTiles = {};
    }
}

//      

/**
 * @private
 * An `EdgeInset` object represents screen space padding applied to the edges of the viewport.
 * This shifts the apparent center or the vanishing point of the map. This is useful for adding floating UI elements
 * on top of the map and having the vanishing point shift as UI elements resize.
 *
 * @param {number} [top=0]
 * @param {number} [bottom=0]
 * @param {number} [left=0]
 * @param {number} [right=0]
 */
class EdgeInsets {
                
                   
                 
                  

    constructor(top         = 0, bottom         = 0, left         = 0, right         = 0) {
        if (isNaN(top) || top < 0 ||
            isNaN(bottom) || bottom < 0 ||
            isNaN(left) || left < 0 ||
            isNaN(right) || right < 0
        ) {
            throw new Error('Invalid value for edge-insets, top, bottom, left and right must all be numbers');
        }

        this.top = top;
        this.bottom = bottom;
        this.left = left;
        this.right = right;
    }

    /**
     * Interpolates the inset in-place.
     * This maintains the current inset value for any inset not present in `target`.
     *
     * @private
     * @param {PaddingOptions | EdgeInsets} start The initial padding options.
     * @param {PaddingOptions} target The target padding options.
     * @param {number} t The interpolation variable.
     * @returns {EdgeInsets} The interpolated edge insets.
     * @memberof EdgeInsets
     */
    interpolate(start                             , target                , t        )             {
        if (target.top != null && start.top != null) this.top = index.number(start.top, target.top, t);
        if (target.bottom != null && start.bottom != null) this.bottom = index.number(start.bottom, target.bottom, t);
        if (target.left != null && start.left != null) this.left = index.number(start.left, target.left, t);
        if (target.right != null && start.right != null) this.right = index.number(start.right, target.right, t);

        return this;
    }

    /**
     * Utility method that computes the new apprent center or vanishing point after applying insets.
     * This is in pixels and with the top left being (0.0) and +y being downwards.
     *
     * @private
     * @param {number} width The width of the map in pixels.
     * @param {number} height The height of the map in pixels.
     * @returns {Point} The apparent center or vanishing point of the map.
     * @memberof EdgeInsets
     */
    getCenter(width        , height        )        {
        // Clamp insets so they never overflow width/height and always calculate a valid center
        const x = index.clamp((this.left + width - this.right) / 2, 0, width);
        const y = index.clamp((this.top + height - this.bottom) / 2, 0, height);

        return new index.Point(x, y);
    }

    equals(other                )          {
        return this.top === other.top &&
            this.bottom === other.bottom &&
            this.left === other.left &&
            this.right === other.right;
    }

    clone()             {
        return new EdgeInsets(this.top, this.bottom, this.left, this.right);
    }

    /**
     * Returns the current state as json, useful when you want to have a
     * read-only representation of the inset.
     *
     * @private
     * @returns {PaddingOptions} The current padding options.
     * @memberof EdgeInsets
     */
    toJSON()                 {
        return {
            top: this.top,
            bottom: this.bottom,
            left: this.left,
            right: this.right
        };
    }
}

//      


                                                       
                                                  
                                                      

function updateTransformOrientation(matrix      , orientation      ) {
    // Take temporary copy of position to prevent it from being overwritten
    const position       = index.getColumn(matrix, 3);

    // Convert quaternion to rotation matrix
    index.fromQuat(matrix, orientation);
    index.setColumn(matrix, 3, position);
}

function updateTransformPosition(matrix      , position      ) {
    index.setColumn(matrix, 3, [position[0], position[1], position[2], 1.0]);
}

function orientationFromPitchBearing(pitch        , bearing        )       {
    // Both angles are considered to define CW rotation around their respective axes.
    // Values have to be negated to achieve the proper quaternion in left handed coordinate space
    const orientation = index.identity$1([]);
    index.rotateZ$1(orientation, orientation, -bearing);
    index.rotateX$1(orientation, orientation, -pitch);
    return orientation;
}

function orientationFromFrame(forward      , up      )        {
    // Find right-vector of the resulting coordinate frame. Up-vector has to be
    // sanitized first in order to remove the roll component from the orientation
    const xyForward = [forward[0], forward[1], 0];
    const xyUp = [up[0], up[1], 0];

    const epsilon = 1e-15;

    if (index.length(xyForward) >= epsilon) {
        // Roll rotation can be seen as the right vector not being on the xy-plane, ie. right[2] != 0.0.
        // It can be negated by projecting the up vector on top of the forward vector.
        const xyDir = index.normalize([], xyForward);
        index.scale$3(xyUp, xyDir, index.dot(xyUp, xyDir));

        up[0] = xyUp[0];
        up[1] = xyUp[1];
    }

    const right = index.cross([], up, forward);
    if (index.len(right) < epsilon) {
        return null;
    }

    const bearing = Math.atan2(-right[1], right[0]);
    const pitch = Math.atan2(Math.sqrt(forward[0] * forward[0] + forward[1] * forward[1]), -forward[2]);

    return orientationFromPitchBearing(pitch, bearing);
}

/**
 * Options for accessing physical properties of the underlying camera entity.
 * Direct access to these properties allows more flexible and precise controlling of the camera.
 * These options are also fully compatible and interchangeable with CameraOptions. All fields are optional.
 * See {@link Map#setFreeCameraOptions} and {@link Map#getFreeCameraOptions}.
 *
 * @param {MercatorCoordinate} position Position of the camera in slightly modified web mercator coordinates.
        - The size of 1 unit is the width of the projected world instead of the "mercator meter".
          Coordinate [0, 0, 0] is the north-west corner and [1, 1, 0] is the south-east corner.
        - Z coordinate is conformal and must respect minimum and maximum zoom values.
        - Zoom is automatically computed from the altitude (z).
 * @param {quat} orientation Orientation of the camera represented as a unit quaternion [x, y, z, w] in a left-handed coordinate space.
        Direction of the rotation is clockwise around the respective axis.
        The default pose of the camera is such that the forward vector is looking up the -Z axis.
        The up vector is aligned with north orientation of the map:
          forward: [0, 0, -1]
          up:      [0, -1, 0]
          right    [1, 0, 0]
        Orientation can be set freely but certain constraints still apply:
         - Orientation must be representable with only pitch and bearing.
         - Pitch has an upper limit
 * @example
 * const camera = map.getFreeCameraOptions();
 *
 * const position = [138.72649, 35.33974];
 * const altitude = 3000;
 *
 * camera.position = mapboxgl.MercatorCoordinate.fromLngLat(position, altitude);
 * camera.lookAtPoint([138.73036, 35.36197]);
 *
 * map.setFreeCameraOptions(camera);
 * @see [Example: Animate the camera around a point in 3D terrain](https://docs.mapbox.com/mapbox-gl-js/example/free-camera-point/)
 * @see [Example: Animate the camera along a path](https://docs.mapbox.com/mapbox-gl-js/example/free-camera-path/)
*/
class FreeCameraOptions {
                       
                                   
                           
                                

    constructor(position                     , orientation       ) {
        this.position = position;
        this.orientation = orientation;
    }

    get position()                      {
        return this._position;
    }

    set position(position                            ) {
        if (!position) {
            this._position = null;
        } else {
            const mercatorCoordinate = position instanceof index.MercatorCoordinate ? position : new index.MercatorCoordinate(position[0], position[1], position[2]);
            if (this._renderWorldCopies) {
                mercatorCoordinate.x = index.wrap(mercatorCoordinate.x, 0, 1);
            }
            this._position = mercatorCoordinate;
        }
    }

    /**
     * Helper function for setting orientation of the camera by defining a focus point
     * on the map.
     *
     * @param {LngLatLike} location Location of the focus point on the map.
     * @param {vec3?} up Up vector of the camera is necessary in certain scenarios where bearing can't be deduced
     *      from the viewing direction.
     * @example
     * const camera = map.getFreeCameraOptions();
     *
     * const position = [138.72649, 35.33974];
     * const altitude = 3000;
     *
     * camera.position = mapboxgl.MercatorCoordinate.fromLngLat(position, altitude);
     * camera.lookAtPoint([138.73036, 35.36197]);
     * // Apply camera changes
     * map.setFreeCameraOptions(camera);
     */
    lookAtPoint(location            , up       ) {
        this.orientation = null;
        if (!this.position) {
            return;
        }

        const pos                     = this.position;
        const altitude = this._elevation ? this._elevation.getAtPointOrZero(index.MercatorCoordinate.fromLngLat(location)) : 0;
        const target = index.MercatorCoordinate.fromLngLat(location, altitude);
        const forward = [target.x - pos.x, target.y - pos.y, target.z - pos.z];
        if (!up)
            up = [0, 0, 1];

        // flip z-component if the up vector is pointing downwards
        up[2] = Math.abs(up[2]);

        this.orientation = orientationFromFrame(forward, up);
    }

    /**
     * Helper function for setting the orientation of the camera as a pitch and a bearing.
     *
     * @param {number} pitch Pitch angle in degrees.
     * @param {number} bearing Bearing angle in degrees.
     * @example
     * const camera = map.getFreeCameraOptions();
     *
     * // Update camera pitch and bearing
     * camera.setPitchBearing(80, 90);
     * // Apply changes
     * map.setFreeCameraOptions(camera);
     */
    setPitchBearing(pitch        , bearing        ) {
        this.orientation = orientationFromPitchBearing(index.degToRad(pitch), index.degToRad(-bearing));
    }
}

/**
 * While using the free camera API the outcome value of isZooming, isMoving and isRotating
 * is not a result of the free camera API.
 * If the user sets the map.interactive to true, there will be conflicting behaviors while
 * interacting with map via zooming or moving using mouse or/and keyboard which will result
 * in isZooming, isMoving and isRotating to return true while using free camera API. In order
 * to prevent the confilicting behavior please set map.interactive to false which will result
 * in muting the following events: zoom, zoomend, zoomstart, rotate, rotateend, rotatestart,
 * move, moveend, movestart, pitch, pitchend, pitchstart.
 */

class FreeCamera {
                     
                       

    constructor(position       , orientation       ) {
        this._transform = index.identity([]);
        this.orientation = orientation;
        this.position = position;
    }

    get mercatorPosition()                     {
        const pos = this.position;
        return new index.MercatorCoordinate(pos[0], pos[1], pos[2]);
    }

    get position()       {
        const col       = index.getColumn(this._transform, 3);
        return [col[0], col[1], col[2]];
    }

    set position(value       ) {
        if (value) {
            updateTransformPosition(this._transform, value);
        }
    }

    get orientation()       {
        return this._orientation;
    }

    set orientation(value       ) {
        this._orientation = value || index.identity$1([]);
        if (value) {
            updateTransformOrientation(this._transform, this._orientation);
        }
    }

    getPitchBearing()                                   {
        const f = this.forward();
        const r = this.right();

        return {
            bearing: Math.atan2(-r[1], r[0]),
            pitch: Math.atan2(Math.sqrt(f[0] * f[0] + f[1] * f[1]), -f[2])
        };
    }

    setPitchBearing(pitch        , bearing        ) {
        this._orientation = orientationFromPitchBearing(pitch, bearing);
        updateTransformOrientation(this._transform, this._orientation);
    }

    forward()       {
        const col       = index.getColumn(this._transform, 2);
        // Forward direction is towards the negative Z-axis
        return [-col[0], -col[1], -col[2]];
    }

    up()       {
        const col       = index.getColumn(this._transform, 1);
        // Up direction has to be flipped to point towards north
        return [-col[0], -col[1], -col[2]];
    }

    right()       {
        const col       = index.getColumn(this._transform, 0);
        return [col[0], col[1], col[2]];
    }

    getCameraToWorld(worldSize        , pixelsPerMeter        )               {
        const cameraToWorld = new Float64Array(16);
        index.invert$1(cameraToWorld, this.getWorldToCamera(worldSize, pixelsPerMeter));
        return cameraToWorld;
    }

    getWorldToCameraPosition(worldSize        , pixelsPerMeter        , uniformScale        )               {
        const invPosition = this.position;

        index.scale$3(invPosition, invPosition, -worldSize);
        const matrix = new Float64Array(16);
        index.fromScaling(matrix, [uniformScale, uniformScale, uniformScale]);
        index.translate(matrix, matrix, invPosition);

        // Adjust scale on z (3rd column 3rd row)
        matrix[10] *= pixelsPerMeter;

        return matrix;
    }

    getWorldToCamera(worldSize        , pixelsPerMeter        )               {
        // transformation chain from world space to camera space:
        // 1. Height value (z) of renderables is in meters. Scale z coordinate by pixelsPerMeter
        // 2. Transform from pixel coordinates to camera space with cameraMatrix^-1
        // 3. flip Y if required

        // worldToCamera: flip * cam^-1 * zScale
        // cameraToWorld: (flip * cam^-1 * zScale)^-1 => (zScale^-1 * cam * flip^-1)
        const matrix = new Float64Array(16);

        // Compute inverse of camera matrix and post-multiply negated translation
        const invOrientation = new Float64Array(4);
        const invPosition = this.position;

        index.conjugate(invOrientation, this._orientation);
        index.scale$3(invPosition, invPosition, -worldSize);

        index.fromQuat(matrix, invOrientation);

        index.translate(matrix, matrix, invPosition);

        // Pre-multiply y (2nd row)
        matrix[1] *= -1.0;
        matrix[5] *= -1.0;
        matrix[9] *= -1.0;
        matrix[13] *= -1.0;

        // Post-multiply z (3rd column)
        matrix[8] *= pixelsPerMeter;
        matrix[9] *= pixelsPerMeter;
        matrix[10] *= pixelsPerMeter;
        matrix[11] *= pixelsPerMeter;

        return matrix;
    }

    getCameraToClipPerspective(fovy        , aspectRatio        , nearZ        , farZ        )               {
        const matrix = new Float64Array(16);
        index.perspective(matrix, fovy, aspectRatio, nearZ, farZ);
        return matrix;
    }

    // The additional parameter needs to be removed. This was introduced because originally
    // the value returned by this function was incorrect. Fixing it would break the fog visuals and needs to be
    // communicated carefully first. Also see transform.cameraWorldSizeForFog.
    getDistanceToElevation(elevationMeters        , convert          = false)         {
        const z0 = elevationMeters === 0 ? 0 : index.mercatorZfromAltitude(elevationMeters, convert ? index.latFromMercatorY(this.position[1]) : this.position[1]);
        const f = this.forward();
        return (z0 - this.position[2]) / f[2];
    }

    clone()             {
        return new FreeCamera([...this.position], [...this.orientation]);
    }
}

//      


                                              
                                             

function getProjectionAdjustments(transform           , withoutRotation          )                {
    const interpT = getProjectionInterpolationT(transform.projection, transform.zoom, transform.width, transform.height);
    const matrix = getShearAdjustment(transform.projection, transform.zoom, transform.center, interpT, withoutRotation);

    const scaleAdjustment = getScaleAdjustment(transform);
    index.scale$1(matrix, matrix, [scaleAdjustment, scaleAdjustment, 1]);

    return matrix;
}

function getScaleAdjustment(transform           )         {
    const projection = transform.projection;
    const interpT = getProjectionInterpolationT(transform.projection, transform.zoom, transform.width, transform.height);
    const zoomAdjustment = getZoomAdjustment(projection, transform.center);
    const zoomAdjustmentOrigin = getZoomAdjustment(projection, index.LngLat.convert(projection.center));
    const scaleAdjustment = Math.pow(2, zoomAdjustment * interpT + (1 - interpT) * zoomAdjustmentOrigin);
    return scaleAdjustment;
}

function getProjectionAdjustmentInverted(transform           )                {
    const m = getProjectionAdjustments(transform, true);
    return index.invert([], [
        m[0], m[1],
        m[4], m[5]]);
}

function getProjectionInterpolationT(projection            , zoom        , width        , height        , maxSize         = Infinity)         {
    const range = projection.range;
    if (!range) return 0;

    const size = Math.min(maxSize, Math.max(width, height));
    // The interpolation ranges are manually defined based on what makes
    // sense in a 1024px wide map. Adjust the ranges to the current size
    // of the map. The smaller the map, the earlier you can start unskewing.
    const rangeAdjustment = Math.log(size / 1024) / Math.LN2;
    const zoomA = range[0] + rangeAdjustment;
    const zoomB = range[1] + rangeAdjustment;
    const t = index.smoothstep(zoomA, zoomB, zoom);
    return t;
}

// approx. kilometers per longitude degree at equator
const offset = 1 / 40000;

/*
 * Calculates the scale difference between Mercator and the given projection at a certain location.
 */
function getZoomAdjustment(projection            , loc        ) {
    // make sure we operate within mercator space for adjustments (they can go over for other projections)
    const lat = index.clamp(loc.lat, -index.MAX_MERCATOR_LATITUDE, index.MAX_MERCATOR_LATITUDE);

    const loc1 = new index.LngLat(loc.lng - 180 * offset, lat);
    const loc2 = new index.LngLat(loc.lng + 180 * offset, lat);

    const p1 = projection.project(loc1.lng, lat);
    const p2 = projection.project(loc2.lng, lat);

    const m1 = index.MercatorCoordinate.fromLngLat(loc1);
    const m2 = index.MercatorCoordinate.fromLngLat(loc2);

    const pdx = p2.x - p1.x;
    const pdy = p2.y - p1.y;
    const mdx = m2.x - m1.x;
    const mdy = m2.y - m1.y;

    const scale = Math.sqrt((mdx * mdx + mdy * mdy) / (pdx * pdx + pdy * pdy));

    return Math.log(scale) / Math.LN2;
}

function getShearAdjustment(projection            , zoom        , loc        , interpT        , withoutRotation          ) {

    // create two locations a tiny amount (~1km) east and west of the given location
    const locw = new index.LngLat(loc.lng - 180 * offset, loc.lat);
    const loce = new index.LngLat(loc.lng + 180 * offset, loc.lat);

    const pw = projection.project(locw.lng, locw.lat);
    const pe = projection.project(loce.lng, loce.lat);

    const pdx = pe.x - pw.x;
    const pdy = pe.y - pw.y;

    // Calculate how much the map would need to be rotated to make east-west in
    // projected coordinates be left-right
    const angleAdjust = -Math.atan2(pdy, pdx);

    // Pick a location identical to the original one except for poles to make sure we're within mercator bounds
    const mc2 = index.MercatorCoordinate.fromLngLat(loc);
    mc2.y = index.clamp(mc2.y, -1 + offset, 1 - offset);
    const loc2 = mc2.toLngLat();
    const p2 = projection.project(loc2.lng, loc2.lat);

    // Find the projected coordinates of two locations, one slightly south and one slightly east.
    // Then calculate the transform that would make the projected coordinates of the two locations be:
    // - equal distances from the original location
    // - perpendicular to one another
    //
    // Only the position of the coordinate to the north is adjusted.
    // The coordinate to the east stays where it is.
    const mc3 = index.MercatorCoordinate.fromLngLat(loc2);
    mc3.x += offset;
    const loc3 = mc3.toLngLat();
    const p3 = projection.project(loc3.lng, loc3.lat);
    const pdx3 = p3.x - p2.x;
    const pdy3 = p3.y - p2.y;
    const delta3 = rotate(pdx3, pdy3, angleAdjust);

    const mc4 = index.MercatorCoordinate.fromLngLat(loc2);
    mc4.y += offset;
    const loc4 = mc4.toLngLat();
    const p4 = projection.project(loc4.lng, loc4.lat);
    const pdx4 = p4.x - p2.x;
    const pdy4 = p4.y - p2.y;
    const delta4 = rotate(pdx4, pdy4, angleAdjust);

    const scale = Math.abs(delta3.x) / Math.abs(delta4.y);

    const unrotate = index.identity([]);
    index.rotateZ(unrotate, unrotate, (-angleAdjust) * (1 - (withoutRotation ? 0 : interpT)));

    // unskew
    const shear = index.identity([]);
    index.scale$1(shear, shear, [1, 1 - (1 - scale) * interpT, 1]);
    shear[4] = -delta4.x / delta4.y * interpT;

    // unrotate
    index.rotateZ(shear, shear, angleAdjust);

    index.multiply(shear, unrotate, shear);

    return shear;
}

function rotate(x        , y        , angle        ) {
    const cos = Math.cos(angle);
    const sin = Math.sin(angle);
    return {
        x: x * cos - y * sin,
        y: x * sin + y * cos
    };
}

//      


                                                              
                                                       
                                                     
                                          
                                                                    
                                                                               
                                                      
                                             

const NUM_WORLD_COPIES = 3;
const DEFAULT_MIN_ZOOM = 0;

                                                              
                                           
                 
               
                          
                 
                 
                          
                              
                 
              
              
                 
  

/**
 * A single transform, generally used for a single tile to be
 * scaled, rotated, and zoomed.
 * @private
 */
class Transform {
                     
                     
                             

    // 2^zoom (worldSize = tileSize * scale)
                  

    // Map viewport size (not including the pixel ratio)
                  
                   

    // Bearing, radians, in [-pi, pi]
                  

    // 2D rotation matrix in the horizontal plane, as a function of bearing
                                 

    // Zoom, modulo 1
                         

    // The scale factor component of the conversion from pixels ([0, w] x [h, 0]) to GL
    // NDC ([1, -1] x [1, -1]) (note flipped y)
                                      

    // Distance from camera to the center, in screen pixel units, independent of zoom
                                   

    // Projection from mercator coordinates ([0, 0] nw, [1, 1] se) to GL clip coordinates
                                  

    // Translate points in mercator coordinates to be centered about the camera, with units chosen
    // for screen-height-independent scaling of fog. Not affected by orientation of camera.
                                    

    // Projection from world coordinates (mercator scaled by worldSize) to clip coordinates
                                                            
                                

    // Same as projMatrix, pixel-aligned to avoid fractional pixels for raster tiles
                                    

    // From world coordinates to screen pixel coordinates (projMatrix premultiplied by labelPlaneMatrix)
                              
                                     

                                   
                               

    // Transform from screen coordinates to GL NDC, [0, w] x [h, 0] --> [-1, 1] x [-1, 1]
    // Roughly speaking, applies pixelsToGLUnits scaling with a translation
                                

    // Inverse of glCoordMatrix, from NDC to screen coordinates, [-1, 1] x [-1, 1] --> [0, w] x [h, 0]
                                   

    // globe coordinate transformation matrix
                              

                                                     
                        

                                           

                                    

                   
                   
                   
                   
                      
                      
                      
                      

                                   

                                
                                                 
                           
                              
                                               
                           
                           
                 
                   
                  
                           
                         
                                
                     
                     
                      
                      
                    
                            
                           
                                                  
                                                         
                                                         
                                                     
                                                               
                        
                            
                                                 
                          
                                    
                   
                  
                                
                                  

    constructor(minZoom         , maxZoom         , minPitch         , maxPitch         , renderWorldCopies                , projection                           , bounds               ) {
        this.tileSize = 512; // constant

        this._renderWorldCopies = renderWorldCopies === undefined ? true : renderWorldCopies;
        this._minZoom = minZoom || DEFAULT_MIN_ZOOM;
        this._maxZoom = maxZoom || 22;

        this._minPitch = (minPitch === undefined || minPitch === null) ? 0 : minPitch;
        this._maxPitch = (maxPitch === undefined || maxPitch === null) ? 60 : maxPitch;

        this.setProjection(projection);
        this.setMaxBounds(bounds);

        this.width = 0;
        this.height = 0;
        this._center = new index.LngLat(0, 0);
        this.zoom = 0;
        this.angle = 0;
        this._fov = 0.6435011087932844;
        this._pitch = 0;
        this._nearZ = 0;
        this._farZ = 0;
        this._unmodified = true;
        this._edgeInsets = new EdgeInsets();
        this._projMatrixCache = {};
        this._alignedProjMatrixCache = {};
        this._fogTileMatrixCache = {};
        this._distanceTileDataCache = {};
        this._camera = new FreeCamera();
        this._centerAltitude = 0;
        this._averageElevation = 0;
        this.cameraElevationReference = "ground";
        this._pixelsPerMercatorPixel = 1.0;
        this.globeRadius = 0;
        this.globeCenterInViewSpace = [0, 0, 0];

        // Move the horizon closer to the center. 0 would not shift the horizon. 1 would put the horizon at the center.
        this._horizonShift = 0.1;
    }

    clone()            {
        const clone = new Transform(this._minZoom, this._maxZoom, this._minPitch, this.maxPitch, this._renderWorldCopies, this.getProjection());
        clone._elevation = this._elevation;
        clone._centerAltitude = this._centerAltitude;
        clone._centerAltitudeValidForExaggeration = this._centerAltitudeValidForExaggeration;
        clone.tileSize = this.tileSize;
        clone.mercatorFromTransition = this.mercatorFromTransition;
        clone.width = this.width;
        clone.height = this.height;
        clone.cameraElevationReference = this.cameraElevationReference;
        clone._center = this._center;
        clone._setZoom(this.zoom);
        clone._seaLevelZoom = this._seaLevelZoom;
        clone.angle = this.angle;
        clone._fov = this._fov;
        clone._pitch = this._pitch;
        clone._nearZ = this._nearZ;
        clone._farZ = this._farZ;
        clone._averageElevation = this._averageElevation;
        clone._unmodified = this._unmodified;
        clone._edgeInsets = this._edgeInsets.clone();
        clone._camera = this._camera.clone();
        clone._calcMatrices();
        clone.freezeTileCoverage = this.freezeTileCoverage;
        clone.frustumCorners = this.frustumCorners;
        return clone;
    }

    get elevation()             { return this._elevation; }
    set elevation(elevation            ) {
        if (this._elevation === elevation) return;
        this._elevation = elevation;
        this._updateCameraOnTerrain();
        this._calcMatrices();
    }

    updateElevation(constrainCameraOverTerrain         , adaptCameraAltitude          = false) {
        const centerAltitudeChanged = this._elevation && this._elevation.exaggeration() !== this._centerAltitudeValidForExaggeration;
        if (this._seaLevelZoom == null || centerAltitudeChanged) {
            this._updateCameraOnTerrain();
        }
        if (constrainCameraOverTerrain || centerAltitudeChanged) {
            this._constrainCamera(adaptCameraAltitude);
        }
        this._calcMatrices();
    }

    getProjection()                          {
        return (index.pick(this.projection, ['name', 'center', 'parallels'])                         );
    }

    // Returns whether the projection changes
    setProjection(projection                           )          {
        this.projectionOptions = projection || {name: 'mercator'};

        const oldProjection = this.projection ? this.getProjection() : undefined;
        this.projection = index.getProjection(this.projectionOptions);
        const newProjection = this.getProjection();

        const projectionHasChanged = !index.deepEqual(oldProjection, newProjection);
        if (projectionHasChanged) {
            this._calcMatrices();
        }
        this.mercatorFromTransition = false;

        return projectionHasChanged;
    }

    setMercatorFromTransition()          {
        const oldProjection = this.projection.name;
        this.mercatorFromTransition = true;
        this.projectionOptions = {name: 'mercator'};
        this.projection = index.getProjection({name: 'mercator'});
        const projectionHasChanged = oldProjection !== this.projection.name;
        if (projectionHasChanged) {
            this._calcMatrices();
        }
        return projectionHasChanged;
    }

    get minZoom()         { return this._minZoom; }
    set minZoom(zoom        ) {
        if (this._minZoom === zoom) return;
        this._minZoom = zoom;
        this.zoom = Math.max(this.zoom, zoom);
    }

    get maxZoom()         { return this._maxZoom; }
    set maxZoom(zoom        ) {
        if (this._maxZoom === zoom) return;
        this._maxZoom = zoom;
        this.zoom = Math.min(this.zoom, zoom);
    }

    get minPitch()         { return this._minPitch; }
    set minPitch(pitch        ) {
        if (this._minPitch === pitch) return;
        this._minPitch = pitch;
        this.pitch = Math.max(this.pitch, pitch);
    }

    get maxPitch()         { return this._maxPitch; }
    set maxPitch(pitch        ) {
        if (this._maxPitch === pitch) return;
        this._maxPitch = pitch;
        this.pitch = Math.min(this.pitch, pitch);
    }

    get renderWorldCopies()          {
        return this._renderWorldCopies && this.projection.supportsWorldCopies === true;
    }
    set renderWorldCopies(renderWorldCopies           ) {
        if (renderWorldCopies === undefined) {
            renderWorldCopies = true;
        } else if (renderWorldCopies === null) {
            renderWorldCopies = false;
        }

        this._renderWorldCopies = renderWorldCopies;
    }

    get worldSize()         {
        return this.tileSize * this.scale;
    }

    // This getter returns an incorrect value.
    // It should eventually be removed and cameraWorldSize be used instead.
    // See free_camera.getDistanceToElevation for the rationale.
    get cameraWorldSizeForFog()         {
        const distance = Math.max(this._camera.getDistanceToElevation(this._averageElevation), Number.EPSILON);
        return this._worldSizeFromZoom(this._zoomFromMercatorZ(distance));
    }

    get cameraWorldSize()         {
        const distance = Math.max(this._camera.getDistanceToElevation(this._averageElevation, true), Number.EPSILON);
        return this._worldSizeFromZoom(this._zoomFromMercatorZ(distance));
    }

    // `pixelsPerMeter` is used to describe relation between real world and pixel distances.
    // In mercator projection it is dependant on latitude value meaning that one meter covers
    // less pixels at the equator than near polar regions. Globe projection in other hand uses
    // fixed ratio everywhere.

    get pixelsPerMeter()         {
        return this.projection.pixelsPerMeter(this.center.lat, this.worldSize);
    }

    get cameraPixelsPerMeter()         {
        return index.mercatorZfromAltitude(this.center.lat, this.cameraWorldSizeForFog);
    }

    get centerOffset()        {
        return this.centerPoint._sub(this.size._div(2));
    }

    get size()        {
        return new index.Point(this.width, this.height);
    }

    get bearing()         {
        return index.wrap(this.rotation, -180, 180);
    }

    set bearing(bearing        ) {
        this.rotation = bearing;
    }

    get rotation()         {
        return -this.angle / Math.PI * 180;
    }

    set rotation(rotation        ) {
        const b = -rotation * Math.PI / 180;
        if (this.angle === b) return;
        this._unmodified = false;
        this.angle = b;
        this._calcMatrices();

        // 2x2 matrix for rotating points
        this.rotationMatrix = index.create$2();
        index.rotate(this.rotationMatrix, this.rotationMatrix, this.angle);
    }

    get pitch()         {
        return this._pitch / Math.PI * 180;
    }
    set pitch(pitch        ) {
        const p = index.clamp(pitch, this.minPitch, this.maxPitch) / 180 * Math.PI;
        if (this._pitch === p) return;
        this._unmodified = false;
        this._pitch = p;
        this._calcMatrices();
    }

    get aspect()         {
        return this.width / this.height;
    }

    get fov()         {
        return this._fov / Math.PI * 180;
    }

    get fovX()         {
        return this._fov;
    }

    get fovY()         {
        const focalLength = 1.0 / Math.tan(this.fovX * 0.5);
        return 2 * Math.atan((1.0 / this.aspect) / focalLength);
    }

    set fov(fov        ) {
        fov = Math.max(0.01, Math.min(60, fov));
        if (this._fov === fov) return;
        this._unmodified = false;
        this._fov = index.degToRad(fov);
        this._calcMatrices();
    }

    get averageElevation()         {
        return this._averageElevation;
    }
    set averageElevation(averageElevation        ) {
        this._averageElevation = averageElevation;
        this._calcFogMatrices();
        this._distanceTileDataCache = {};
    }

    get zoom()         { return this._zoom; }
    set zoom(zoom        ) {
        const z = Math.min(Math.max(zoom, this.minZoom), this.maxZoom);
        if (this._zoom === z) return;
        this._unmodified = false;
        this._setZoom(z);
        this._updateSeaLevelZoom();
        this._constrain();
        this._calcMatrices();
    }
    _setZoom(z        ) {
        this._zoom = z;
        this.scale = this.zoomScale(z);
        this.tileZoom = Math.floor(z);
        this.zoomFraction = z - this.tileZoom;
    }

    _updateCameraOnTerrain() {
        if (!this._elevation || !this._elevation.isDataAvailableAtPoint(this.locationCoordinate(this.center))) {
            // Elevation data not loaded yet, reset
            this._centerAltitude = 0;
            this._seaLevelZoom = null;
            this._centerAltitudeValidForExaggeration = undefined;
            return;
        }
        const elevation            = this._elevation;
        this._centerAltitude = elevation.getAtPointOrZero(this.locationCoordinate(this.center));
        this._centerAltitudeValidForExaggeration = elevation.exaggeration();
        this._updateSeaLevelZoom();
    }

    _updateSeaLevelZoom() {
        if (this._centerAltitudeValidForExaggeration === undefined) {
            return;
        }
        const height = this.cameraToCenterDistance;
        const terrainElevation = this.pixelsPerMeter * this._centerAltitude;
        const mercatorZ = (terrainElevation + height) / this.worldSize;

        // MSL (Mean Sea Level) zoom describes the distance of the camera to the sea level (altitude).
        // It is used only for manipulating the camera location. The standard zoom (this._zoom)
        // defines the camera distance to the terrain (height). Its behavior and conceptual
        // meaning in determining which tiles to stream is same with or without the terrain.
        this._seaLevelZoom = this._zoomFromMercatorZ(mercatorZ);
    }

    sampleAverageElevation()         {
        if (!this._elevation) return 0;
        const elevation            = this._elevation;

        const elevationSamplePoints = [
            [0.5, 0.2],
            [0.3, 0.5],
            [0.5, 0.5],
            [0.7, 0.5],
            [0.5, 0.8]
        ];

        const horizon = this.horizonLineFromTop();

        let elevationSum = 0.0;
        let weightSum = 0.0;
        for (let i = 0; i < elevationSamplePoints.length; i++) {
            const pt = new index.Point(
                elevationSamplePoints[i][0] * this.width,
                horizon + elevationSamplePoints[i][1] * (this.height - horizon)
            );
            const hit = elevation.pointCoordinate(pt);
            if (!hit) continue;

            const distanceToHit = Math.hypot(hit[0] - this._camera.position[0], hit[1] - this._camera.position[1]);
            const weight = 1 / distanceToHit;
            elevationSum += hit[3] * weight;
            weightSum += weight;
        }

        if (weightSum === 0) return NaN;
        return elevationSum / weightSum;
    }

    get center()         { return this._center; }
    set center(center        ) {
        if (center.lat === this._center.lat && center.lng === this._center.lng) return;

        this._unmodified = false;
        this._center = center;
        if (this._terrainEnabled()) {
            if (this.cameraElevationReference === "ground") {
                this._updateCameraOnTerrain();
            } else {
                this._updateZoomFromElevation();
            }
        }
        this._constrain();
        this._calcMatrices();
    }

    _updateZoomFromElevation() {
        if (this._seaLevelZoom == null || !this._elevation)
            return;

        // Compute zoom level from the height of the camera relative to the terrain
        const seaLevelZoom         = this._seaLevelZoom;
        const elevationAtCenter = this._elevation.getAtPointOrZero(this.locationCoordinate(this.center));
        const mercatorElevation = this.pixelsPerMeter / this.worldSize * elevationAtCenter;
        const altitude  = this._mercatorZfromZoom(seaLevelZoom);
        const minHeight = this._mercatorZfromZoom(this._maxZoom);
        const height = Math.max(altitude - mercatorElevation, minHeight);

        this._setZoom(this._zoomFromMercatorZ(height));
    }

    get padding()                 { return this._edgeInsets.toJSON(); }
    set padding(padding                ) {
        if (this._edgeInsets.equals(padding)) return;
        this._unmodified = false;
        //Update edge-insets inplace
        this._edgeInsets.interpolate(this._edgeInsets, padding, 1);
        this._calcMatrices();
    }

    /**
     * Computes a zoom value relative to a map plane that goes through the provided mercator position.
     *
     * @param {MercatorCoordinate} position A position defining the altitude of the the map plane.
     * @returns {number} The zoom value.
     */
    computeZoomRelativeTo(position                    )         {
        // Find map center position on the target plane by casting a ray from screen center towards the plane.
        // Direct distance to the target position is used if the target position is above camera position.
        const centerOnTargetAltitude = this.rayIntersectionCoordinate(this.pointRayIntersection(this.centerPoint, position.toAltitude()));

        let targetPosition       ;
        if (position.z < this._camera.position[2]) {
            targetPosition = [centerOnTargetAltitude.x, centerOnTargetAltitude.y, centerOnTargetAltitude.z];
        } else {
            targetPosition = [position.x, position.y, position.z];
        }

        const distToTarget = index.length(index.sub([], this._camera.position, targetPosition));
        return index.clamp(this._zoomFromMercatorZ(distToTarget), this._minZoom, this._maxZoom);
    }

    setFreeCameraOptions(options                   ) {
        if (!this.height)
            return;

        if (!options.position && !options.orientation)
            return;

        // Camera state must be up-to-date before accessing its getters
        this._updateCameraState();

        let changed = false;
        if (options.orientation && !index.exactEquals(options.orientation, this._camera.orientation)) {
            // $FlowFixMe[incompatible-call] - Flow can't infer that orientation is not null
            changed = this._setCameraOrientation(options.orientation);
        }

        if (options.position) {
            const newPosition = [options.position.x, options.position.y, options.position.z];
            if (!index.exactEquals$1(newPosition, this._camera.position)) {
                this._setCameraPosition(newPosition);
                changed = true;
            }
        }

        if (changed) {
            this._updateStateFromCamera();
            this.recenterOnTerrain();
        }
    }

    getFreeCameraOptions()                    {
        this._updateCameraState();
        const pos = this._camera.position;
        const options = new FreeCameraOptions();
        options.position = new index.MercatorCoordinate(pos[0], pos[1], pos[2]);
        options.orientation = this._camera.orientation;
        options._elevation = this.elevation;
        options._renderWorldCopies = this.renderWorldCopies;

        return options;
    }

    _setCameraOrientation(orientation      )          {
        // zero-length quaternions are not valid
        if (!index.length$1(orientation))
            return false;

        index.normalize$1(orientation, orientation);

        // The new orientation must be sanitized by making sure it can be represented
        // with a pitch and bearing. Roll-component must be removed and the camera can't be upside down
        const forward = index.transformQuat([], [0, 0, -1], orientation);
        const up = index.transformQuat([], [0, -1, 0], orientation);

        if (up[2] < 0.0)
            return false;

        const updatedOrientation = orientationFromFrame(forward, up);
        if (!updatedOrientation)
            return false;

        this._camera.orientation = updatedOrientation;
        return true;
    }

    _setCameraPosition(position      ) {
        // Altitude must be clamped to respect min and max zoom
        const minWorldSize = this.zoomScale(this.minZoom) * this.tileSize;
        const maxWorldSize = this.zoomScale(this.maxZoom) * this.tileSize;
        const distToCenter = this.cameraToCenterDistance;

        position[2] = index.clamp(position[2], distToCenter / maxWorldSize, distToCenter / minWorldSize);
        this._camera.position = position;
    }

    /**
     * The center of the screen in pixels with the top-left corner being (0,0)
     * and +y axis pointing downwards. This accounts for padding.
     *
     * @readonly
     * @type {Point}
     * @memberof Transform
     */
    get centerPoint()        {
        return this._edgeInsets.getCenter(this.width, this.height);
    }

    /**
     * Returns the vertical half-fov, accounting for padding, in radians.
     *
     * @readonly
     * @type {number}
     * @private
     */
    get fovAboveCenter()         {
        return this._fov * (0.5 + this.centerOffset.y / this.height);
    }

    /**
     * Returns true if the padding options are equal.
     *
     * @param {PaddingOptions} padding The padding options to compare.
     * @returns {boolean} True if the padding options are equal.
     * @memberof Transform
     */
    isPaddingEqual(padding                )          {
        return this._edgeInsets.equals(padding);
    }

    /**
     * Helper method to update edge-insets inplace.
     *
     * @param {PaddingOptions} start The initial padding options.
     * @param {PaddingOptions} target The target padding options.
     * @param {number} t The interpolation variable.
     * @memberof Transform
     */
    interpolatePadding(start                , target                , t        ) {
        this._unmodified = false;
        this._edgeInsets.interpolate(start, target, t);
        this._constrain();
        this._calcMatrices();
    }

    /**
     * Return the highest zoom level that fully includes all tiles within the transform's boundaries.
     * @param {Object} options Options.
     * @param {number} options.tileSize Tile size, expressed in screen pixels.
     * @param {boolean} options.roundZoom Target zoom level. If true, the value will be rounded to the closest integer. Otherwise the value will be floored.
     * @returns {number} An integer zoom level at which all tiles will be visible.
     */
    coveringZoomLevel(options                                         )         {
        const z = (options.roundZoom ? Math.round : Math.floor)(
            this.zoom + this.scaleZoom(this.tileSize / options.tileSize)
        );
        // At negative zoom levels load tiles from z0 because negative tile zoom levels don't exist.
        return Math.max(0, z);
    }

    /**
     * Return any "wrapped" copies of a given tile coordinate that are visible
     * in the current view.
     *
     * @private
     */
    getVisibleUnwrappedCoordinates(tileID                 )                         {
        const result = [new index.UnwrappedTileID(0, tileID)];
        if (this.renderWorldCopies) {
            const utl = this.pointCoordinate(new index.Point(0, 0));
            const utr = this.pointCoordinate(new index.Point(this.width, 0));
            const ubl = this.pointCoordinate(new index.Point(this.width, this.height));
            const ubr = this.pointCoordinate(new index.Point(0, this.height));
            const w0 = Math.floor(Math.min(utl.x, utr.x, ubl.x, ubr.x));
            const w1 = Math.floor(Math.max(utl.x, utr.x, ubl.x, ubr.x));

            // Add an extra copy of the world on each side to properly render ImageSources and CanvasSources.
            // Both sources draw outside the tile boundaries of the tile that "contains them" so we need
            // to add extra copies on both sides in case offscreen tiles need to draw into on-screen ones.
            const extraWorldCopy = 1;

            for (let w = w0 - extraWorldCopy; w <= w1 + extraWorldCopy; w++) {
                if (w === 0) continue;
                result.push(new index.UnwrappedTileID(w, tileID));
            }
        }
        return result;
    }

    /**
     * Return all coordinates that could cover this transform for a covering
     * zoom level.
     * @param {Object} options
     * @param {number} options.tileSize
     * @param {number} options.minzoom
     * @param {number} options.maxzoom
     * @param {boolean} options.roundZoom
     * @param {boolean} options.reparseOverscaled
     * @returns {Array<OverscaledTileID>} OverscaledTileIDs
     * @private
     */
    coveringTiles(
        options   
                             
                             
                             
                                
                                        
                                        
                                  
         
    )                          {
        let z = this.coveringZoomLevel(options);
        const actualZ = z;

        const useElevationData = this.elevation && !options.isTerrainDEM;
        const isMercator = this.projection.name === 'mercator';

        if (options.minzoom !== undefined && z < options.minzoom) return [];
        if (options.maxzoom !== undefined && z > options.maxzoom) z = options.maxzoom;

        const centerCoord = this.locationCoordinate(this.center);
        const centerLatitude = this.center.lat;
        const numTiles = 1 << z;
        const centerPoint = [numTiles * centerCoord.x, numTiles * centerCoord.y, 0];
        const isGlobe = this.projection.name === 'globe';
        const zInMeters = !isGlobe;
        const cameraFrustum = index.Frustum.fromInvProjectionMatrix(this.invProjMatrix, this.worldSize, z, zInMeters);
        const cameraCoord = isGlobe ? this._camera.mercatorPosition : this.pointCoordinate(this.getCameraPoint());
        const meterToTile = numTiles * index.mercatorZfromAltitude(1, this.center.lat);
        const cameraAltitude = this._camera.position[2] / index.mercatorZfromAltitude(1, this.center.lat);
        const cameraPoint = [numTiles * cameraCoord.x, numTiles * cameraCoord.y, cameraAltitude * (zInMeters ? 1 : meterToTile)];
        // Let's consider an example for !roundZoom: e.g. tileZoom 16 is used from zoom 16 all the way to zoom 16.99.
        // This would mean that the minimal distance to split would be based on distance from camera to center of 16.99 zoom.
        // The same is already incorporated in logic behind roundZoom for raster (so there is no adjustment needed in following line).
        // 0.02 added to compensate for precision errors, see "coveringTiles for terrain" test in transform.test.js.
        const zoomSplitDistance = this.cameraToCenterDistance / options.tileSize * (options.roundZoom ? 1 : 0.502);

        // No change of LOD behavior for pitch lower than 60 and when there is no top padding: return only tile ids from the requested zoom level
        const minZoom = this.pitch <= 60.0 && this._edgeInsets.top <= this._edgeInsets.bottom && !this._elevation && !this.projection.isReprojectedInTileSpace ? z : 0;

        // When calculating tile cover for terrain, create deep AABB for nodes, to ensure they intersect frustum: for sources,
        // other than DEM, use minimum of visible DEM tiles and center altitude as upper bound (pitch is always less than 90°).
        const maxRange = options.isTerrainDEM && this._elevation ? this._elevation.exaggeration() * 10000 : this._centerAltitude;
        const minRange = options.isTerrainDEM ? -maxRange : this._elevation ? this._elevation.getMinElevationBelowMSL() : 0;

        const scaleAdjustment = this.projection.isReprojectedInTileSpace ? getScaleAdjustment(this) : 1.0;

        const relativeScaleAtMercatorCoord = (mc                    ) => {
            // Calculate how scale compares between projected coordinates and mercator coordinates.
            // Returns a length. The units don't matter since the result is only
            // used in a ratio with other values returned by this function.

            // Construct a small square in Mercator coordinates.
            const offset = 1 / 40000;
            const mcEast = new index.MercatorCoordinate(mc.x + offset, mc.y, mc.z);
            const mcSouth = new index.MercatorCoordinate(mc.x, mc.y + offset, mc.z);

            // Convert the square to projected coordinates.
            const ll = mc.toLngLat();
            const llEast = mcEast.toLngLat();
            const llSouth = mcSouth.toLngLat();
            const p = this.locationCoordinate(ll);
            const pEast = this.locationCoordinate(llEast);
            const pSouth = this.locationCoordinate(llSouth);

            // Calculate the size of each edge of the reprojected square
            const dx = Math.hypot(pEast.x - p.x, pEast.y - p.y);
            const dy = Math.hypot(pSouth.x - p.x, pSouth.y - p.y);

            // Calculate the size of a projected square that would have the
            // same area as the reprojected square.
            return Math.sqrt(dx * dy) * scaleAdjustment / offset;
        };

        const newRootTile = (wrap        )           => {
            const max = maxRange;
            const min = minRange;
            return {
                // With elevation, this._elevation provides z coordinate values. For 2D:
                // All tiles are on zero elevation plane => z difference is zero
                aabb: index.tileAABB(this, numTiles, 0, 0, 0, wrap, min, max, this.projection),
                zoom: 0,
                x: 0,
                y: 0,
                minZ: min,
                maxZ: max,
                wrap,
                fullyVisible: false
            };
        };

        // Do a depth-first traversal to find visible tiles and proper levels of detail
        const stack = [];
        let result = [];
        const maxZoom = z;
        const overscaledZ = options.reparseOverscaled ? actualZ : z;
        const square = (a        ) => a * a;
        const cameraHeightSqr = square((cameraAltitude - this._centerAltitude) * meterToTile); // in tile coordinates.

        const getAABBFromElevation = (it          ) => {
            index.assert(this._elevation);
            if (!this._elevation || !it.tileID || !isMercator) return; // To silence flow.
            const minmax = this._elevation.getMinMaxForTile(it.tileID);
            const aabb = it.aabb;
            if (minmax) {
                aabb.min[2] = minmax.min;
                aabb.max[2] = minmax.max;
                aabb.center[2] = (aabb.min[2] + aabb.max[2]) / 2;
            } else {
                it.shouldSplit = shouldSplit(it);
                if (!it.shouldSplit) {
                    // At final zoom level, while corresponding DEM tile is not loaded yet,
                    // assume center elevation. This covers ground to horizon and prevents
                    // loading unnecessary tiles until DEM cover is fully loaded.
                    aabb.min[2] = aabb.max[2] = aabb.center[2] = this._centerAltitude;
                }
            }
        };

        // Scale distance to split for acute angles.
        // dzSqr: z component of camera to tile distance, square.
        // dSqr: 3D distance of camera to tile, square.
        const distToSplitScale = (dzSqr        , dSqr        ) => {
            // When the angle between camera to tile ray and tile plane is smaller
            // than acuteAngleThreshold, scale the distance to split. Scaling is adaptive: smaller
            // the angle, the scale gets lower value. Although it seems early to start at 45,
            // it is not: scaling kicks in around 60 degrees pitch.
            const acuteAngleThresholdSin = 0.707; // Math.sin(45)
            const stretchTile = 1.1;
            // Distances longer than 'dz / acuteAngleThresholdSin' gets scaled
            // following geometric series sum: every next dz length in distance can be
            // 'stretchTile times' longer. It is further, the angle is sharper. Total,
            // adjusted, distance would then be:
            // = dz / acuteAngleThresholdSin + (dz * stretchTile + dz * stretchTile ^ 2 + ... + dz * stretchTile ^ k),
            // where k = (d - dz / acuteAngleThresholdSin) / dz = d / dz - 1 / acuteAngleThresholdSin;
            // = dz / acuteAngleThresholdSin + dz * ((stretchTile ^ (k + 1) - 1) / (stretchTile - 1) - 1)
            // or put differently, given that k is based on d and dz, tile on distance d could be used on distance scaled by:
            // 1 / acuteAngleThresholdSin + (stretchTile ^ (k + 1) - 1) / (stretchTile - 1) - 1
            if (dSqr * square(acuteAngleThresholdSin) < dzSqr) return 1.0; // Early return, no scale.
            const r = Math.sqrt(dSqr / dzSqr);
            const k =  r - 1 / acuteAngleThresholdSin;
            return r / (1 / acuteAngleThresholdSin + (Math.pow(stretchTile, k + 1) - 1) / (stretchTile - 1) - 1);
        };

        const shouldSplit = (it          ) => {
            if (it.zoom < minZoom) {
                return true;
            } else if (it.zoom === maxZoom) {
                return false;
            }
            if (it.shouldSplit != null) {
                return it.shouldSplit;
            }
            const dx = it.aabb.distanceX(cameraPoint);
            const dy = it.aabb.distanceY(cameraPoint);
            let dzSqr = cameraHeightSqr;

            let tileScaleAdjustment = 1;
            if (isGlobe) {
                dzSqr = square(it.aabb.distanceZ(cameraPoint));
                // Compensate physical sizes of the tiles when determining which zoom level to use.
                // In practice tiles closer to poles should use more aggressive LOD as their
                // physical size is already smaller than size of tiles near the equator.
                const tilesAtZoom = Math.pow(2, it.zoom);
                const minLat = index.latFromMercatorY((it.y + 1) / tilesAtZoom);
                const maxLat = index.latFromMercatorY((it.y) / tilesAtZoom);
                const closestLat = Math.min(Math.max(centerLatitude, minLat), maxLat);

                const relativeTileScale = index.circumferenceAtLatitude(closestLat) / index.circumferenceAtLatitude(centerLatitude);

                // With globe, the rendered scale does not exactly match the mercator scale at low zoom levels.
                // Account for this difference during LOD of loading so that you load the correct size tiles.
                // We try to compromise between two conflicting requirements:
                // - loading tiles at the camera's zoom level (for visual and styling consistency)
                // - loading correct size tiles (to reduce the number of tiles loaded)
                // These are arbitrarily balanced:
                if (closestLat === centerLatitude) {
                    // For tiles that are in the middle of the viewport, prioritize matching the camera
                    // zoom and allow divergence from the true scale.
                    const maxDivergence = 0.3;
                    tileScaleAdjustment = 1 / Math.max(1, this._mercatorScaleRatio - maxDivergence);
                } else {
                    // For other tiles, use the real scale to reduce tile counts near poles.
                    tileScaleAdjustment = Math.min(1, relativeTileScale / this._mercatorScaleRatio);
                }

                // Ensure that all tiles near the center have the same zoom level.
                // With LOD tile loading, tile zoom levels can change when scale slightly changes.
                // These differences can be pretty different in globe view. Work around this by
                // making more tiles match the center tile's zoom level. If the tiles are nearly big enough,
                // round up. Only apply this adjustment before the transition to mercator rendering has started.
                if (this.zoom <= index.GLOBE_ZOOM_THRESHOLD_MIN && it.zoom === maxZoom - 1 && relativeTileScale >= 0.9) {
                    return true;
                }
            } else {
                index.assert(zInMeters);
                if (useElevationData) {
                    dzSqr = square(it.aabb.distanceZ(cameraPoint) * meterToTile);
                }
                if (this.projection.isReprojectedInTileSpace && actualZ <= 5) {
                    // In other projections, not all tiles are the same size.
                    // Account for the tile size difference by adjusting the distToSplit.
                    // Adjust by the ratio of the area at the tile center to the area at the map center.
                    // Adjustments are only needed at lower zooms where tiles are not similarly sized.
                    const numTiles = Math.pow(2, it.zoom);
                    const relativeScale = relativeScaleAtMercatorCoord(new index.MercatorCoordinate((it.x + 0.5) / numTiles, (it.y + 0.5) / numTiles));
                    // Fudge the ratio slightly so that all tiles near the center have the same zoom level.
                    tileScaleAdjustment = relativeScale > 0.85 ? 1 : relativeScale;
                }
            }

            const distanceSqr = dx * dx + dy * dy + dzSqr;
            const distToSplit = (1 << maxZoom - it.zoom) * zoomSplitDistance * tileScaleAdjustment;
            const distToSplitSqr = square(distToSplit * distToSplitScale(Math.max(dzSqr, cameraHeightSqr), distanceSqr));

            return distanceSqr < distToSplitSqr;
        };

        if (this.renderWorldCopies) {
            // Render copy of the globe thrice on both sides
            for (let i = 1; i <= NUM_WORLD_COPIES; i++) {
                stack.push(newRootTile(-i));
                stack.push(newRootTile(i));
            }
        }

        stack.push(newRootTile(0));

        while (stack.length > 0) {
            const it = stack.pop();
            const x = it.x;
            const y = it.y;
            let fullyVisible = it.fullyVisible;

            // Visibility of a tile is not required if any of its ancestor is fully inside the frustum
            if (!fullyVisible) {
                const intersectResult = it.aabb.intersects(cameraFrustum);

                if (intersectResult === 0)
                    continue;

                fullyVisible = intersectResult === 2;
            }

            // Have we reached the target depth or is the tile too far away to be any split further?
            if (it.zoom === maxZoom || !shouldSplit(it)) {
                const tileZoom = it.zoom === maxZoom ? overscaledZ : it.zoom;
                if (!!options.minzoom && options.minzoom > tileZoom) {
                    // Not within source tile range.
                    continue;
                }

                const dx = centerPoint[0] - ((0.5 + x + (it.wrap << it.zoom)) * (1 << (z - it.zoom)));
                const dy = centerPoint[1] - 0.5 - y;
                const id = it.tileID ? it.tileID : new index.OverscaledTileID(tileZoom, it.wrap, it.zoom, x, y);
                result.push({tileID: id, distanceSq: dx * dx + dy * dy});
                continue;
            }

            for (let i = 0; i < 4; i++) {
                const childX = (x << 1) + (i % 2);
                const childY = (y << 1) + (i >> 1);

                const aabb = isMercator ? it.aabb.quadrant(i) : index.tileAABB(this, numTiles, it.zoom + 1, childX, childY, it.wrap, it.minZ, it.maxZ, this.projection);
                const child           = {aabb, zoom: it.zoom + 1, x: childX, y: childY, wrap: it.wrap, fullyVisible, tileID: undefined, shouldSplit: undefined, minZ: it.minZ, maxZ: it.maxZ};
                if (useElevationData && !isGlobe) {
                    child.tileID = new index.OverscaledTileID(it.zoom + 1 === maxZoom ? overscaledZ : it.zoom + 1, it.wrap, it.zoom + 1, childX, childY);
                    getAABBFromElevation(child);
                }
                stack.push(child);
            }
        }

        if (this.fogCullDistSq) {
            const fogCullDistSq = this.fogCullDistSq;
            const horizonLineFromTop = this.horizonLineFromTop();
            result = result.filter(entry => {
                const min = [0, 0, 0, 1];
                const max = [index.EXTENT, index.EXTENT, 0, 1];

                const fogTileMatrix = this.calculateFogTileMatrix(entry.tileID.toUnwrapped());

                index.transformMat4$1(min, min, fogTileMatrix);
                index.transformMat4$1(max, max, fogTileMatrix);

                const sqDist = index.getAABBPointSquareDist(min, max);

                if (sqDist === 0) { return true; }

                let overHorizonLine = false;

                // Terrain loads at one zoom level lower than the raster data,
                // so the following checks whether the terrain sits above the horizon and ensures that
                // when mountains stick out above the fog (due to horizon-blend),
                // we haven’t accidentally culled some of the raster tiles we need to draw on them.
                // If we don’t do this, the terrain is default black color and may flash in and out as we move toward it.

                const elevation = this._elevation;

                if (elevation && sqDist > fogCullDistSq && horizonLineFromTop !== 0) {
                    const projMatrix = this.calculateProjMatrix(entry.tileID.toUnwrapped());

                    let minmax;
                    if (!options.isTerrainDEM) {
                        minmax = elevation.getMinMaxForTile(entry.tileID);
                    }

                    if (!minmax) { minmax = {min: minRange, max: maxRange}; }

                    // ensure that we want `this.rotation` instead of `this.bearing` here
                    const cornerFar = index.furthestTileCorner(this.rotation);

                    const farX = cornerFar[0] * index.EXTENT;
                    const farY = cornerFar[1] * index.EXTENT;

                    const worldFar = [farX, farY, minmax.max];

                    // World to NDC
                    index.transformMat4(worldFar, worldFar, projMatrix);

                    // NDC to Screen
                    const screenCoordY = (1 - worldFar[1]) * this.height * 0.5;

                    // Prevent cutting tiles crossing over the horizon line to
                    // prevent pop-in and out within the fog culling range
                    overHorizonLine = screenCoordY < horizonLineFromTop;
                }

                return sqDist < fogCullDistSq || overHorizonLine;
            });
        }

        const cover = result.sort((a, b) => a.distanceSq - b.distanceSq).map(a => a.tileID);

        // Relax the assertion on terrain, on high zoom we use distance to center of tile
        // while camera might be closer to selected center of map.
        index.assert(!cover.length || this.elevation || cover[0].overscaledZ === overscaledZ || !isMercator);
        return cover;
    }

    resize(width        , height        ) {
        this.width = width;
        this.height = height;

        this.pixelsToGLUnits = [2 / width, -2 / height];
        this._constrain();
        this._calcMatrices();
    }

    get unmodified()          { return this._unmodified; }

    zoomScale(zoom        )         { return Math.pow(2, zoom); }
    scaleZoom(scale        )         { return Math.log(scale) / Math.LN2; }

    // Transform from LngLat to Point in world coordinates [-180, 180] x [90, -90] --> [0, this.worldSize] x [0, this.worldSize]
    project(lnglat        )        {
        const lat = index.clamp(lnglat.lat, -index.MAX_MERCATOR_LATITUDE, index.MAX_MERCATOR_LATITUDE);
        const projectedLngLat = this.projection.project(lnglat.lng, lat);
        return new index.Point(
                projectedLngLat.x * this.worldSize,
                projectedLngLat.y * this.worldSize);
    }

    // Transform from Point in world coordinates to LngLat [0, this.worldSize] x [0, this.worldSize] --> [-180, 180] x [90, -90]
    unproject(point       )         {
        return this.projection.unproject(point.x / this.worldSize, point.y / this.worldSize);
    }

    // Point at center in world coordinates.
    get point()        { return this.project(this.center); }

    // Point at center in Mercator coordinates.
    get pointMerc()        { return this.point._div(this.worldSize); }

    // Ratio of pixelsPerMeter in the current projection to Mercator's.
    get pixelsPerMeterRatio()         { return this.pixelsPerMeter / index.mercatorZfromAltitude(1, this.center.lat) / this.worldSize; }

    setLocationAtPoint(lnglat        , point       ) {
        let x, y;
        const centerPoint = this.centerPoint;

        if (this.projection.name === 'globe') {
            // Pixel coordinates are applied directly to the globe
            const worldSize = this.worldSize;
            x = (point.x - centerPoint.x) / worldSize;
            y = (point.y - centerPoint.y) / worldSize;
        } else {
            const a = this.pointCoordinate(point);
            const b = this.pointCoordinate(centerPoint);
            x = a.x - b.x;
            y = a.y - b.y;
        }

        const loc = this.locationCoordinate(lnglat);
        this.setLocation(new index.MercatorCoordinate(loc.x - x, loc.y - y));
    }

    setLocation(location                    ) {
        this.center = this.coordinateLocation(location);
        if (this.projection.wrap) {
            this.center = this.center.wrap();
        }
    }

    /**
     * Given a location, return the screen point that corresponds to it. In 3D mode
     * (with terrain) this behaves the same as in 2D mode.
     * This method is coupled with {@see pointLocation} in 3D mode to model map manipulation
     * using flat plane approach to keep constant elevation above ground.
     * @param {LngLat} lnglat location
     * @returns {Point} screen point
     * @private
     */
    locationPoint(lnglat        )        {
        return this.projection.locationPoint(this, lnglat);
    }

    /**
     * Given a location, return the screen point that corresponds to it
     * In 3D mode (when terrain is enabled) elevation is sampled for the point before
     * projecting it. In 2D mode, behaves the same locationPoint.
     * @param {LngLat} lnglat location
     * @returns {Point} screen point
     * @private
     */
    locationPoint3D(lnglat        )        {
        return this.projection.locationPoint(this, lnglat, true);
    }

    /**
     * Given a point on screen, return its lnglat
     * @param {Point} p screen point
     * @returns {LngLat} lnglat location
     * @private
     */
    pointLocation(p       )         {
        return this.coordinateLocation(this.pointCoordinate(p));
    }

    /**
     * Given a point on screen, return its lnglat
     * In 3D mode (map with terrain) returns location of terrain raycast point.
     * In 2D mode, behaves the same as {@see pointLocation}.
     * @param {Point} p screen point
     * @returns {LngLat} lnglat location
     * @private
     */
    pointLocation3D(p       )         {
        return this.coordinateLocation(this.pointCoordinate3D(p));
    }

    /**
     * Given a geographical lngLat, return an unrounded
     * coordinate that represents it at this transform's zoom level.
     * @param {LngLat} lngLat
     * @returns {Coordinate}
     * @private
     */
    locationCoordinate(lngLat        , altitude         )                     {
        const z = altitude ?
            index.mercatorZfromAltitude(altitude, lngLat.lat) :
            undefined;
        const projectedLngLat = this.projection.project(lngLat.lng, lngLat.lat);
        return new index.MercatorCoordinate(
            projectedLngLat.x,
            projectedLngLat.y,
            z);
    }

    /**
     * Given a Coordinate, return its geographical position.
     * @param {Coordinate} coord
     * @returns {LngLat} lngLat
     * @private
     */
    coordinateLocation(coord                    )         {
        return this.projection.unproject(coord.x, coord.y);
    }

    /**
     * Casts a ray from a point on screen and returns the Ray,
     * and the extent along it, at which it intersects the map plane.
     *
     * @param {Point} p Viewport pixel co-ordinates.
     * @param {number} z Optional altitude of the map plane, defaulting to elevation at center.
     * @returns {{ p0: Vec4, p1: Vec4, t: number }} p0,p1 are two points on the ray.
     * t is the fractional extent along the ray at which the ray intersects the map plane.
     * @private
     */
    pointRayIntersection(p       , z         )                        {
        const targetZ = (z !== undefined && z !== null) ? z : this._centerAltitude;
        // Since we don't know the correct projected z value for the point,
        // unproject two points to get a line and then find the point on that
        // line with z=0.

        const p0 = [p.x, p.y, 0, 1];
        const p1 = [p.x, p.y, 1, 1];

        index.transformMat4$1(p0, p0, this.pixelMatrixInverse);
        index.transformMat4$1(p1, p1, this.pixelMatrixInverse);

        const w0 = p0[3];
        const w1 = p1[3];
        index.scale$2(p0, p0, 1 / w0);
        index.scale$2(p1, p1, 1 / w1);

        const z0 = p0[2];
        const z1 = p1[2];

        const t = z0 === z1 ? 0 : (targetZ - z0) / (z1 - z0);

        return {p0, p1, t};
    }

    screenPointToMercatorRay(p       )      {
        const p0 = [p.x, p.y, 0, 1];
        const p1 = [p.x, p.y, 1, 1];

        index.transformMat4$1(p0, p0, this.pixelMatrixInverse);
        index.transformMat4$1(p1, p1, this.pixelMatrixInverse);

        index.scale$2(p0, p0, 1 / p0[3]);
        index.scale$2(p1, p1, 1 / p1[3]);

        // Convert altitude from meters to pixels.
        p0[2] = index.mercatorZfromAltitude(p0[2], this._center.lat) * this.worldSize;
        p1[2] = index.mercatorZfromAltitude(p1[2], this._center.lat) * this.worldSize;

        index.scale$2(p0, p0, 1 / this.worldSize);
        index.scale$2(p1, p1, 1 / this.worldSize);

        return new index.Ray([p0[0], p0[1], p0[2]], index.normalize([], index.sub([], p1, p0)));
    }

    /**
     *  Helper method to convert the ray intersection with the map plane to MercatorCoordinate.
     *
     * @param {RayIntersectionResult} rayIntersection
     * @returns {MercatorCoordinate}
     * @private
     */
    rayIntersectionCoordinate(rayIntersection                       )                     {
        const {p0, p1, t} = rayIntersection;

        const z0 = index.mercatorZfromAltitude(p0[2], this._center.lat);
        const z1 = index.mercatorZfromAltitude(p1[2], this._center.lat);

        return new index.MercatorCoordinate(
            index.number(p0[0], p1[0], t) / this.worldSize,
            index.number(p0[1], p1[1], t) / this.worldSize,
            index.number(z0, z1, t));
    }

    /**
     * Given a point on screen, returns MercatorCoordinate.
     * @param {Point} p Top left origin screen point, in pixels.
     * @param {number} z Optional altitude of the map plane, defaulting to elevation at center.
     * @private
     */
    pointCoordinate(p       , z          = this._centerAltitude)                     {
        return this.projection.pointCoordinate(this, p.x, p.y, z);
    }

    /**
     * Given a point on screen, returns MercatorCoordinate.
     * In 3D mode, raycast to terrain. In 2D mode, behaves the same as {@see pointCoordinate}.
     * For p above terrain, don't return point behind camera but clamp p.y at the top of terrain.
     * @param {Point} p top left origin screen point, in pixels.
     * @private
     */
    pointCoordinate3D(p       )                     {
        if (!this.elevation) return this.pointCoordinate(p);
        let raycast        = this.projection.pointCoordinate3D(this, p.x, p.y);
        if (raycast) return new index.MercatorCoordinate(raycast[0], raycast[1], raycast[2]);
        let start = 0, end = this.horizonLineFromTop();
        if (p.y > end) return this.pointCoordinate(p); // holes between tiles below horizon line or below bottom.
        const samples = 10;
        const threshold = 0.02 * end;
        const r = p.clone();

        for (let i = 0; i < samples && end - start > threshold; i++) {
            r.y = index.number(start, end, 0.66); // non uniform binary search favoring points closer to horizon.
            const rCast = this.projection.pointCoordinate3D(this, r.x, r.y);
            if (rCast) {
                end = r.y;
                raycast = rCast;
            } else {
                start = r.y;
            }
        }
        return raycast ? new index.MercatorCoordinate(raycast[0], raycast[1], raycast[2]) : this.pointCoordinate(p);
    }

    /**
     * Returns true if a screenspace Point p, is above the horizon.
     * In non-globe projections, this approximates the map as an infinite plane and does not account for z0-z3
     * wherein the map is small quad with whitespace above the north pole and below the south pole.
     *
     * @param {Point} p
     * @returns {boolean}
     * @private
     */
    isPointAboveHorizon(p       )          {
        return this.projection.isPointAboveHorizon(this, p);
    }

    /**
     * Determines if the given point is located on a visible map surface.
     *
     * @param {Point} p
     * @returns {boolean}
     * @private
     */
    isPointOnSurface(p       )          {
        if (p.y < 0 || p.y > this.height || p.x < 0 || p.x > this.width) return false;
        if (this.elevation || this.zoom >= index.GLOBE_ZOOM_THRESHOLD_MAX) return !this.isPointAboveHorizon(p);
        const coord = this.pointCoordinate(p);
        return coord.y >= 0 && coord.y <= 1;
    }

    /**
     * Given a coordinate, return the screen point that corresponds to it
     * @param {Coordinate} coord
     * @param {boolean} sampleTerrainIn3D in 3D mode (terrain enabled), sample elevation for the point.
     * If false, do the same as in 2D mode, assume flat camera elevation plane for all points.
     * @returns {Point} screen point
     * @private
     */
    _coordinatePoint(coord                    , sampleTerrainIn3D         )        {
        const elevation = sampleTerrainIn3D && this.elevation ? this.elevation.getAtPointOrZero(coord, this._centerAltitude) : this._centerAltitude;
        const p = [coord.x * this.worldSize, coord.y * this.worldSize, elevation + coord.toAltitude(), 1];
        index.transformMat4$1(p, p, this.pixelMatrix);
        return p[3] > 0 ?
            new index.Point(p[0] / p[3], p[1] / p[3]) :
            new index.Point(Number.MAX_VALUE, Number.MAX_VALUE);
    }

    // In Globe, conic and thematic projections, Lng/Lat extremes are not always at corners.
    // This function additionally checks each screen edge midpoint.
    // While midpoints continue to be extremes, it recursively checks midpoints of smaller segments.
    _getBoundsNonRectangular()               {
        index.assert(!this.projection.supportsWorldCopies, "Rectangular projections should use the simpler _getBoundsRectangular");
        const {top, left} = this._edgeInsets;
        const bottom = this.height - this._edgeInsets.bottom;
        const right = this.width - this._edgeInsets.right;

        const tl = this.pointLocation3D(new index.Point(left, top));
        const tr = this.pointLocation3D(new index.Point(right, top));
        const br = this.pointLocation3D(new index.Point(right, bottom));
        const bl = this.pointLocation3D(new index.Point(left, bottom));

        let west = Math.min(tl.lng, tr.lng, br.lng, bl.lng);
        let east = Math.max(tl.lng, tr.lng, br.lng, bl.lng);
        let south = Math.min(tl.lat, tr.lat, br.lat, bl.lat);
        let north = Math.max(tl.lat, tr.lat, br.lat, bl.lat);

        // we pick an error threshold for calculating the bbox that balances between performance and precision
        // Roughly emulating behavior of maxErr in tile_transform.js
        const s = Math.pow(2, -this.zoom);
        const maxErr = s / 16 * 270; // 270 = avg(180, 360) i.e. rough conversion between Mercator coords and Lat/Lng

        // We check a minimum of 15 points on each side for Albers, etc.
        // We check a minmum of one midpoint on each side per globe.
        // Globe checks require raytracing and are slower
        // and mising area near the horizon is highly compressed so not noticeable
        const minRecursions = this.projection.name === "globe" ? 1 : 4;

        const processSegment = (ax        , ay        , bx        , by        , depth        ) => {
            const mx = (ax + bx) / 2;
            const my = (ay + by) / 2;

            const p = new index.Point(mx, my);
            const {lng, lat} = this.pointLocation3D(p);

            // The error metric is the maximum change to bounds from a given point
            const err = Math.max(0, west - lng, south - lat, lng - east, lat - north);

            west = Math.min(west, lng);
            east = Math.max(east, lng);
            south = Math.min(south, lat);
            north = Math.max(north, lat);

            if (depth < minRecursions || err > maxErr) {
                processSegment(ax, ay, mx, my, depth + 1);
                processSegment(mx, my, bx, by, depth + 1);
            }
        };

        processSegment(left, top, right, top, 1);
        processSegment(right, top, right, bottom, 1);
        processSegment(right, bottom, left, bottom, 1);
        processSegment(left, bottom, left, top, 1);

        if (this.projection.name === "globe") {
            const [northPoleIsVisible, southPoleIsVisible] = index.polesInViewport(this);
            if (northPoleIsVisible) {
                north = 90;
                east = 180;
                west = -180;
            } else if (southPoleIsVisible) {
                south = -90;
                east = 180;
                west = -180;
            }
        }

        return new index.LngLatBounds(new index.LngLat(west, south), new index.LngLat(east, north));
    }

    _getBoundsRectangular(min        , max        )               {
        index.assert(this.projection.supportsWorldCopies, "_getBoundsRectangular only checks corners and works only on rectangular projections. Other projections should use _getBoundsNonRectangular");

        const {top, left} = this._edgeInsets;
        const bottom = this.height - this._edgeInsets.bottom;
        const right = this.width - this._edgeInsets.right;

        const topLeft = new index.Point(left, top);
        const topRight = new index.Point(right, top);
        const bottomRight = new index.Point(right, bottom);
        const bottomLeft = new index.Point(left, bottom);

        // Consider far points at the maximum possible elevation
        // and near points at the minimum to ensure full coverage.
        let tl = this.pointCoordinate(topLeft, min);
        let tr = this.pointCoordinate(topRight, min);
        const br = this.pointCoordinate(bottomRight, max);
        const bl = this.pointCoordinate(bottomLeft, max);

        // If map pitch places top corners off map edge (latitude > 90 or < -90),
        // place them at the intersection between the left/right screen edge and map edge.
        const slope = (p1                    , p2                    ) => (p2.y - p1.y) / (p2.x - p1.x);

        if (tl.y > 1 && tr.y >= 0) tl = new index.MercatorCoordinate((1 - bl.y) / slope(bl, tl) + bl.x, 1);
        else if (tl.y < 0 && tr.y <= 1) tl = new index.MercatorCoordinate(-bl.y / slope(bl, tl) + bl.x, 0);

        if (tr.y > 1 && tl.y >= 0) tr = new index.MercatorCoordinate((1 - br.y) / slope(br, tr) + br.x, 1);
        else if (tr.y < 0 && tl.y <= 1) tr = new index.MercatorCoordinate(-br.y / slope(br, tr) + br.x, 0);

        return new index.LngLatBounds()
            .extend(this.coordinateLocation(tl))
            .extend(this.coordinateLocation(tr))
            .extend(this.coordinateLocation(bl))
            .extend(this.coordinateLocation(br));
    }

    _getBoundsRectangularTerrain()               {
        index.assert(this.elevation);
        const elevation = ((this.elevation     )           );
        if (!elevation.visibleDemTiles.length || elevation.isUsingMockSource()) { return this._getBoundsRectangular(0, 0); }
        const minmax = elevation.visibleDemTiles.reduce((acc, t) => {
            if (t.dem) {
                const tree = t.dem.tree;
                acc.min = Math.min(acc.min, tree.minimums[0]);
                acc.max = Math.max(acc.max, tree.maximums[0]);
            }
            return acc;
        }, {min: Number.MAX_VALUE, max: 0});
        index.assert(minmax.min !== Number.MAX_VALUE);
        return this._getBoundsRectangular(minmax.min * elevation.exaggeration(), minmax.max * elevation.exaggeration());
    }

    /**
     * Returns the map's geographical bounds. When the bearing or pitch is non-zero, the visible region is not
     * an axis-aligned rectangle, and the result is the smallest bounds that encompasses the visible region.
     *
     * @returns {LngLatBounds} Returns a {@link LngLatBounds} object describing the map's geographical bounds.
     */
    getBounds()               {
        if (this.projection.name === 'mercator' || this.projection.name === 'equirectangular') {
            if (this._terrainEnabled()) return this._getBoundsRectangularTerrain();
            return this._getBoundsRectangular(0, 0);
        }
        return this._getBoundsNonRectangular();
    }

    /**
     * Returns position of horizon line from the top of the map in pixels.
     * If horizon is not visible, returns 0 by default or a negative value if called with clampToTop = false.
     * @private
     */
    horizonLineFromTop(clampToTop          = true)         {
        // h is height of space above map center to horizon.
        const h = this.height / 2 / Math.tan(this._fov / 2) / Math.tan(Math.max(this._pitch, 0.1)) + this.centerOffset.y;
        const offset = this.height / 2 - h * (1 - this._horizonShift);
        return clampToTop ? Math.max(0, offset) : offset;
    }

    /**
     * Returns the maximum geographical bounds the map is constrained to, or `null` if none set.
     * @returns {LngLatBounds} {@link LngLatBounds}.
     */
    getMaxBounds()                {
        return this.maxBounds;
    }

    /**
     * Sets or clears the map's geographical constraints.
     *
     * @param {LngLatBounds} bounds A {@link LngLatBounds} object describing the new geographic boundaries of the map.
     */
    setMaxBounds(bounds               ) {
        this.maxBounds = bounds;

        this.minLat = -index.MAX_MERCATOR_LATITUDE;
        this.maxLat = index.MAX_MERCATOR_LATITUDE;
        this.minLng = -180;
        this.maxLng = 180;

        if (bounds) {
            this.minLat = bounds.getSouth();
            this.maxLat = bounds.getNorth();
            this.minLng = bounds.getWest();
            this.maxLng = bounds.getEast();
            if (this.maxLng < this.minLng) this.maxLng += 360;
        }

        this.worldMinX = index.mercatorXfromLng(this.minLng) * this.tileSize;
        this.worldMaxX = index.mercatorXfromLng(this.maxLng) * this.tileSize;
        this.worldMinY = index.mercatorYfromLat(this.maxLat) * this.tileSize;
        this.worldMaxY = index.mercatorYfromLat(this.minLat) * this.tileSize;

        this._constrain();
    }

    calculatePosMatrix(unwrappedTileID                 , worldSize        )               {
        return this.projection.createTileMatrix(this, worldSize, unwrappedTileID);
    }

    calculateDistanceTileData(unwrappedTileID                 )                      {
        const distanceDataKey = unwrappedTileID.key;
        const cache = this._distanceTileDataCache;
        if (cache[distanceDataKey]) {
            return cache[distanceDataKey];
        }

        //Calculate the offset of the tile
        const canonical = unwrappedTileID.canonical;
        const windowScaleFactor = 1 / this.height;
        const cws = this.cameraWorldSize;
        const scale = cws / this.zoomScale(canonical.z);
        const unwrappedX = canonical.x + Math.pow(2, canonical.z) * unwrappedTileID.wrap;
        const tX = unwrappedX * scale;
        const tY = canonical.y * scale;

        const center = this.point;
        // center is in world/pixel coordinate, ensure it's in the same coordinate space as tX and tY computed earlier.
        center.x *= cws / this.worldSize;
        center.y *= cws / this.worldSize;

        // Calculate the bearing vector by rotating unit vector [0, -1] clockwise
        const angle = this.angle;
        const bX = Math.sin(-angle);
        const bY = -Math.cos(-angle);

        const cX = (center.x - tX) * windowScaleFactor;
        const cY = (center.y - tY) * windowScaleFactor;
        cache[distanceDataKey] = {
            bearing: [bX, bY],
            center: [cX, cY],
            scale: (scale / index.EXTENT) * windowScaleFactor
        };

        return cache[distanceDataKey];
    }

    /**
     * Calculate the fogTileMatrix that, given a tile coordinate, can be used to
     * calculate its position relative to the camera in units of pixels divided
     * by the map height. Used with fog for consistent computation of distance
     * from camera.
     *
     * @param {UnwrappedTileID} unwrappedTileID;
     * @private
     */
    calculateFogTileMatrix(unwrappedTileID                 )               {
        const fogTileMatrixKey = unwrappedTileID.key;
        const cache = this._fogTileMatrixCache;
        if (cache[fogTileMatrixKey]) {
            return cache[fogTileMatrixKey];
        }

        const posMatrix = this.projection.createTileMatrix(this, this.cameraWorldSizeForFog, unwrappedTileID);
        index.multiply(posMatrix, this.worldToFogMatrix, posMatrix);

        cache[fogTileMatrixKey] = new Float32Array(posMatrix);
        return cache[fogTileMatrixKey];
    }

    /**
     * Calculate the projMatrix that, given a tile coordinate, would be used to display the tile on the screen.
     * @param {UnwrappedTileID} unwrappedTileID;
     * @private
     */
    calculateProjMatrix(unwrappedTileID                 , aligned          = false)               {
        const projMatrixKey = unwrappedTileID.key;
        const cache = aligned ? this._alignedProjMatrixCache : this._projMatrixCache;
        if (cache[projMatrixKey]) {
            return cache[projMatrixKey];
        }

        const posMatrix = this.calculatePosMatrix(unwrappedTileID, this.worldSize);
        const projMatrix = this.projection.isReprojectedInTileSpace ?
            this.mercatorMatrix : (aligned ? this.alignedProjMatrix : this.projMatrix);
        index.multiply(posMatrix, projMatrix, posMatrix);

        cache[projMatrixKey] = new Float32Array(posMatrix);
        return cache[projMatrixKey];
    }

    calculatePixelsToTileUnitsMatrix(tile      )               {
        const key = tile.tileID.key;
        const cache = this._pixelsToTileUnitsCache;
        if (cache[key]) {
            return cache[key];
        }

        const matrix = getPixelsToTileUnitsMatrix(tile, this);
        cache[key] = matrix;
        return cache[key];
    }

    customLayerMatrix()                {
        return this.mercatorMatrix.slice();
    }

    globeToMercatorMatrix()                 {
        if (this.projection.name === 'globe') {
            const pixelsToMerc = 1 / this.worldSize;
            const m = index.fromScaling([], [pixelsToMerc, pixelsToMerc, pixelsToMerc]);
            index.multiply(m, m, this.globeMatrix);
            return m;
        }
        return undefined;
    }

    recenterOnTerrain() {
        if (!this._elevation || this.projection.name === 'globe')
            return;

        const elevation            = this._elevation;
        this._updateCameraState();

        // Cast a ray towards the sea level and find the intersection point with the terrain.
        // We need to use a camera position that exists in the same coordinate space as the data.
        // The default camera position might have been compensated by the active projection model.
        const mercPixelsPerMeter = index.mercatorZfromAltitude(1, this._center.lat) * this.worldSize;
        const start = this._computeCameraPosition(mercPixelsPerMeter);
        const dir = this._camera.forward();

        // The raycast function expects z-component to be in meters
        const metersToMerc = index.mercatorZfromAltitude(1.0, this._center.lat);
        start[2] /= metersToMerc;
        dir[2] /= metersToMerc;
        index.normalize(dir, dir);

        const t = elevation.raycast(start, dir, elevation.exaggeration());

        if (t) {
            const point = index.scaleAndAdd([], start, dir, t);
            const newCenter = new index.MercatorCoordinate(point[0], point[1], index.mercatorZfromAltitude(point[2], index.latFromMercatorY(point[1])));

            const camToNew = [newCenter.x - start[0], newCenter.y - start[1], newCenter.z - start[2] * metersToMerc];
            const maxAltitude = (newCenter.z + index.length(camToNew)) * this._pixelsPerMercatorPixel;
            this._seaLevelZoom = this._zoomFromMercatorZ(maxAltitude);

            // Camera zoom has to be updated as the orbit distance might have changed
            this._centerAltitude = newCenter.toAltitude();
            this._center = this.coordinateLocation(newCenter);
            this._updateZoomFromElevation();
            this._constrain();
            this._calcMatrices();
        }
    }

    _constrainCamera(adaptCameraAltitude          = false) {
        if (!this._elevation)
            return;

        const elevation            = this._elevation;

        // Find uncompensated camera position for elevation sampling.
        // The default camera position might have been compensated by the active projection model.
        const mercPixelsPerMeter = index.mercatorZfromAltitude(1, this._center.lat) * this.worldSize;
        const pos = this._computeCameraPosition(mercPixelsPerMeter);
        const elevationAtCamera = elevation.getAtPointOrZero(new index.MercatorCoordinate(...pos));
        const terrainElevation = this.pixelsPerMeter / this.worldSize * elevationAtCamera;
        const minHeight = this._minimumHeightOverTerrain();
        const cameraHeight = pos[2] - terrainElevation;

        if (cameraHeight <= minHeight) {
            if (cameraHeight < 0 || adaptCameraAltitude) {
                const center = this.locationCoordinate(this._center, this._centerAltitude);
                const cameraToCenter = [pos[0], pos[1], center.z - pos[2]];

                const prevDistToCamera = index.length(cameraToCenter);
                // Adjust the camera vector so that the camera is placed above the terrain.
                // Distance between the camera and the center point is kept constant.
                cameraToCenter[2] -= (minHeight - cameraHeight) / this._pixelsPerMercatorPixel;
                const newDistToCamera = index.length(cameraToCenter);

                if (newDistToCamera === 0)
                    return;

                index.scale$3(cameraToCenter, cameraToCenter, prevDistToCamera / newDistToCamera * this._pixelsPerMercatorPixel);
                this._camera.position = [pos[0], pos[1], center.z * this._pixelsPerMercatorPixel - cameraToCenter[2]];
                this._updateStateFromCamera();
            } else {
                this._isCameraConstrained = true;
            }
        }
    }

    _constrain() {
        if (!this.center || !this.width || !this.height || this._constraining) return;

        this._constraining = true;
        const isGlobe = this.projection.name === 'globe' || this.mercatorFromTransition;

        // alternate constraining for non-Mercator projections
        if (this.projection.isReprojectedInTileSpace || isGlobe) {
            const center = this.center;
            center.lat = index.clamp(center.lat, this.minLat, this.maxLat);
            if (this.maxBounds || !(this.renderWorldCopies || isGlobe)) center.lng = index.clamp(center.lng, this.minLng, this.maxLng);
            this.center = center;
            this._constraining = false;
            return;
        }

        const unmodified = this._unmodified;
        const {x, y} = this.point;
        let s = 0;
        let x2 = x;
        let y2 = y;
        const w2 = this.width / 2;
        const h2 = this.height / 2;

        const minY = this.worldMinY * this.scale;
        const maxY = this.worldMaxY * this.scale;
        if (y - h2 < minY) y2 = minY + h2;
        if (y + h2 > maxY) y2 = maxY - h2;
        if (maxY - minY < this.height) {
            s = Math.max(s, this.height / (maxY - minY));
            y2 = (maxY + minY) / 2;
        }

        if (this.maxBounds || !this._renderWorldCopies || !this.projection.wrap) {
            const minX = this.worldMinX * this.scale;
            const maxX = this.worldMaxX * this.scale;

            // Translate to positive positions with the map center in the center position.
            // This ensures that the map snaps to the correct edge.
            const shift = this.worldSize / 2 - (minX + maxX) / 2;
            x2 = (x + shift + this.worldSize) % this.worldSize - shift;

            if (x2 - w2 < minX) x2 = minX + w2;
            if (x2 + w2 > maxX) x2 = maxX - w2;
            if (maxX - minX < this.width) {
                s = Math.max(s, this.width / (maxX - minX));
                x2 = (maxX + minX) / 2;
            }
        }

        if (x2 !== x || y2 !== y) { // pan the map to fit the range
            this.center = this.unproject(new index.Point(x2, y2));
        }
        if (s) { // scale the map to fit the range
            this.zoom += this.scaleZoom(s);
        }

        this._constrainCamera();
        this._unmodified = unmodified;
        this._constraining = false;
    }

    /**
     * Returns the minimum zoom at which `this.width` can fit max longitude range
     * and `this.height` can fit max latitude range.
     *
     * @returns {number} The zoom value.
     */
    _minZoomForBounds()         {
        let minZoom = Math.max(0, this.scaleZoom(this.height / (this.worldMaxY - this.worldMinY)));
        if (this.maxBounds) {
            minZoom = Math.max(minZoom, this.scaleZoom(this.width / (this.worldMaxX - this.worldMinX)));
        }
        return minZoom;
    }

    /**
     * Returns the maximum distance of the camera from the center of the bounds, such that
     * `this.width` can fit max longitude range and `this.height` can fit max latitude range.
     * In mercator units.
     *
     * @returns {number} The mercator z coordinate.
     */
    _maxCameraBoundsDistance()         {
        return this._mercatorZfromZoom(this._minZoomForBounds());
    }

    _calcMatrices()       {
        if (!this.height) return;

        const offset = this.centerOffset;

        // Z-axis uses pixel coordinates when globe mode is enabled
        const pixelsPerMeter = this.pixelsPerMeter;

        if (this.projection.name === 'globe') {
            this._mercatorScaleRatio = index.mercatorZfromAltitude(1, this.center.lat) / index.mercatorZfromAltitude(1, index.GLOBE_SCALE_MATCH_LATITUDE);
        }

        const projectionT = getProjectionInterpolationT(this.projection, this.zoom, this.width, this.height, 1024);

        // 'this._pixelsPerMercatorPixel' is the ratio between pixelsPerMeter in the current projection relative to Mercator.
        // This is useful for converting e.g. camera position between pixel spaces as some logic
        // such as raycasting expects the scale to be in mercator pixels
        this._pixelsPerMercatorPixel = this.projection.pixelSpaceConversion(this.center.lat, this.worldSize, projectionT);

        this.cameraToCenterDistance = 0.5 / Math.tan(this._fov * 0.5) * this.height * this._pixelsPerMercatorPixel;

        this._updateCameraState();

        this._farZ = this.projection.farthestPixelDistance(this);

        // The larger the value of nearZ is
        // - the more depth precision is available for features (good)
        // - clipping starts appearing sooner when the camera is close to 3d features (bad)
        //
        // Smaller values worked well for mapbox-gl-js but deckgl was encountering precision issues
        // when rendering it's layers using custom layers. This value was experimentally chosen and
        // seems to solve z-fighting issues in deckgl while not clipping buildings too close to the camera.
        this._nearZ = this.height / 50;

        const zUnit = this.projection.zAxisUnit === "meters" ? pixelsPerMeter : 1.0;
        const worldToCamera = this._camera.getWorldToCamera(this.worldSize, zUnit);
        const cameraToClip = this._camera.getCameraToClipPerspective(this._fov, this.width / this.height, this._nearZ, this._farZ);

        // Apply center of perspective offset
        cameraToClip[8] = -offset.x * 2 / this.width;
        cameraToClip[9] = offset.y * 2 / this.height;

        let m                                              = index.mul([], cameraToClip, worldToCamera);

        if (this.projection.isReprojectedInTileSpace) {
            // Projections undistort as you zoom in (shear, scale, rotate).
            // Apply the undistortion around the center of the map.
            const mc = this.locationCoordinate(this.center);
            const adjustments = index.identity([]);
            index.translate(adjustments, adjustments, [mc.x * this.worldSize, mc.y * this.worldSize, 0]);
            index.multiply(adjustments, adjustments, getProjectionAdjustments(this));
            index.translate(adjustments, adjustments, [-mc.x * this.worldSize, -mc.y * this.worldSize, 0]);
            index.multiply(m, m, adjustments);
            this.inverseAdjustmentMatrix = getProjectionAdjustmentInverted(this);
        } else {
            this.inverseAdjustmentMatrix = [1, 0, 0, 1];
        }

        // The mercatorMatrix can be used to transform points from mercator coordinates
        // ([0, 0] nw, [1, 1] se) to GL coordinates. / zUnit compensates for scaling done in worldToCamera.
        this.mercatorMatrix = index.scale$1([], m, [this.worldSize, this.worldSize, this.worldSize / zUnit, 1.0]);

        this.projMatrix = m;

        // For tile cover calculation, use inverted of base (non elevated) matrix
        // as tile elevations are in tile coordinates and relative to center elevation.
        this.invProjMatrix = index.invert$1(new Float64Array(16), this.projMatrix);

        const clipToCamera = index.invert$1([], cameraToClip);
        this.frustumCorners = index.FrustumCorners.fromInvProjectionMatrix(clipToCamera, this.horizonLineFromTop(), this.height);

        const view = new Float32Array(16);
        index.identity(view);
        index.scale$1(view, view, [1, -1, 1]);
        index.rotateX(view, view, this._pitch);
        index.rotateZ(view, view, this.angle);

        const projection = index.perspective(new Float32Array(16), this._fov, this.width / this.height, this._nearZ, this._farZ);
        // The distance in pixels the skybox needs to be shifted down by to meet the shifted horizon.
        const skyboxHorizonShift = (Math.PI / 2 - this._pitch) * (this.height / this._fov) * this._horizonShift;
        // Apply center of perspective offset to skybox projection
        projection[8] = -offset.x * 2 / this.width;
        projection[9] = (offset.y + skyboxHorizonShift) * 2 / this.height;
        this.skyboxMatrix = index.multiply(view, projection, view);

        // Make a second projection matrix that is aligned to a pixel grid for rendering raster tiles.
        // We're rounding the (floating point) x/y values to achieve to avoid rendering raster images to fractional
        // coordinates. Additionally, we adjust by half a pixel in either direction in case that viewport dimension
        // is an odd integer to preserve rendering to the pixel grid. We're rotating this shift based on the angle
        // of the transformation so that 0°, 90°, 180°, and 270° rasters are crisp, and adjust the shift so that
        // it is always <= 0.5 pixels.
        const point = this.point;
        const x = point.x, y = point.y;
        const xShift = (this.width % 2) / 2, yShift = (this.height % 2) / 2,
            angleCos = Math.cos(this.angle), angleSin = Math.sin(this.angle),
            dx = x - Math.round(x) + angleCos * xShift + angleSin * yShift,
            dy = y - Math.round(y) + angleCos * yShift + angleSin * xShift;
        const alignedM = new Float64Array(m);
        index.translate(alignedM, alignedM, [ dx > 0.5 ? dx - 1 : dx, dy > 0.5 ? dy - 1 : dy, 0 ]);
        this.alignedProjMatrix = alignedM;

        m = index.create();
        index.scale$1(m, m, [this.width / 2, -this.height / 2, 1]);
        index.translate(m, m, [1, -1, 0]);
        this.labelPlaneMatrix = m;

        m = index.create();
        index.scale$1(m, m, [1, -1, 1]);
        index.translate(m, m, [-1, -1, 0]);
        index.scale$1(m, m, [2 / this.width, 2 / this.height, 1]);
        this.glCoordMatrix = m;

        // matrix for conversion from location to screen coordinates
        this.pixelMatrix = index.multiply(new Float64Array(16), this.labelPlaneMatrix, this.projMatrix);

        this._calcFogMatrices();
        this._distanceTileDataCache = {};

        // inverse matrix for conversion from screen coordinates to location
        m = index.invert$1(new Float64Array(16), this.pixelMatrix);
        if (!m) throw new Error("failed to invert matrix");
        this.pixelMatrixInverse = m;

        if (this.projection.name === 'globe' || this.mercatorFromTransition) {
            this.globeMatrix = index.calculateGlobeMatrix(this);

            const globeCenter = [this.globeMatrix[12], this.globeMatrix[13], this.globeMatrix[14]];

            this.globeCenterInViewSpace = index.transformMat4(globeCenter, globeCenter, worldToCamera);
            this.globeRadius = this.worldSize / 2.0 / Math.PI - 1.0;
        } else {
            this.globeMatrix = m;
        }

        this._projMatrixCache = {};
        this._alignedProjMatrixCache = {};
        this._pixelsToTileUnitsCache = {};
    }

    _calcFogMatrices() {
        this._fogTileMatrixCache = {};

        const cameraWorldSizeForFog = this.cameraWorldSizeForFog;
        const cameraPixelsPerMeter = this.cameraPixelsPerMeter;
        const cameraPos = this._camera.position;

        // The mercator fog matrix encodes transformation necessary to transform a position to camera fog space (in meters):
        // translates p to camera origin and transforms it from pixels to meters. The windowScaleFactor is used to have a
        // consistent transformation across different window sizes.
        // - p = p - cameraOrigin
        // - p.xy = p.xy * cameraWorldSizeForFog * windowScaleFactor
        // - p.z  = p.z  * cameraPixelsPerMeter * windowScaleFactor
        const windowScaleFactor = 1 / this.height / this._pixelsPerMercatorPixel;
        const metersToPixel = [cameraWorldSizeForFog, cameraWorldSizeForFog, cameraPixelsPerMeter];
        index.scale$3(metersToPixel, metersToPixel, windowScaleFactor);
        index.scale$3(cameraPos, cameraPos, -1);
        index.multiply$2(cameraPos, cameraPos, metersToPixel);

        const m = index.create();
        index.translate(m, m, cameraPos);
        index.scale$1(m, m, metersToPixel);
        this.mercatorFogMatrix = m;

        // The worldToFogMatrix can be used for conversion from world coordinates to relative camera position in
        // units of fractions of the map height. Later composed with tile position to construct the fog tile matrix.
        this.worldToFogMatrix = this._camera.getWorldToCameraPosition(cameraWorldSizeForFog, cameraPixelsPerMeter, windowScaleFactor);
    }

    _computeCameraPosition(targetPixelsPerMeter         )       {
        targetPixelsPerMeter = targetPixelsPerMeter || this.pixelsPerMeter;
        const pixelSpaceConversion = targetPixelsPerMeter / this.pixelsPerMeter;

        const dir = this._camera.forward();
        const center = this.point;

        // Compute camera position using the following vector math: camera.position = map.center - camera.forward * cameraToCenterDist
        // Camera distance to the center can be found in mercator units by subtracting the center elevation from
        // camera's zenith position (which can be deduced from the zoom level)
        const zoom = this._seaLevelZoom ? this._seaLevelZoom : this._zoom;
        const altitude = this._mercatorZfromZoom(zoom) * pixelSpaceConversion;
        const distance = altitude - targetPixelsPerMeter / this.worldSize * this._centerAltitude;

        return [
            center.x / this.worldSize - dir[0] * distance,
            center.y / this.worldSize - dir[1] * distance,
            targetPixelsPerMeter / this.worldSize * this._centerAltitude - dir[2] * distance
        ];
    }

    _updateCameraState() {
        if (!this.height) return;

        // Set camera orientation and move it to a proper distance from the map
        this._camera.setPitchBearing(this._pitch, this.angle);
        this._camera.position = this._computeCameraPosition();
    }

    /**
     * Apply a 3d translation to the camera position, but clamping it so that
     * it respects the maximum longitude and latitude range set.
     *
     * @param {vec3} translation The translation vector.
     */
    _translateCameraConstrained(translation      ) {
        const maxDistance = this._maxCameraBoundsDistance();
        // Define a ceiling in mercator Z
        const maxZ = maxDistance * Math.cos(this._pitch);
        const z = this._camera.position[2];
        const deltaZ = translation[2];
        let t = 1;

        if (this.projection.wrap) this.center = this.center.wrap();

        // we only need to clamp if the camera is moving upwards
        if (deltaZ > 0) {
            t = Math.min((maxZ - z) / deltaZ, 1);
        }

        this._camera.position = index.scaleAndAdd([], this._camera.position, translation, t);
        this._updateStateFromCamera();
    }

    _updateStateFromCamera() {
        const position = this._camera.position;
        const dir = this._camera.forward();
        const {pitch, bearing} = this._camera.getPitchBearing();

        // Compute zoom from the distance between camera and terrain
        const centerAltitude = index.mercatorZfromAltitude(this._centerAltitude, this.center.lat) * this._pixelsPerMercatorPixel;
        const minHeight = this._mercatorZfromZoom(this._maxZoom) * Math.cos(index.degToRad(this._maxPitch));
        const height = Math.max((position[2] - centerAltitude) / Math.cos(pitch), minHeight);
        const zoom = this._zoomFromMercatorZ(height);

        // Cast a ray towards the ground to find the center point
        index.scaleAndAdd(position, position, dir, height);

        this._pitch = index.clamp(pitch, index.degToRad(this.minPitch), index.degToRad(this.maxPitch));
        this.angle = index.wrap(bearing, -Math.PI, Math.PI);
        this._setZoom(index.clamp(zoom, this._minZoom, this._maxZoom));
        this._updateSeaLevelZoom();

        this._center = this.coordinateLocation(new index.MercatorCoordinate(position[0], position[1], position[2]));
        this._unmodified = false;
        this._constrain();
        this._calcMatrices();
    }

    _worldSizeFromZoom(zoom        )         {
        return Math.pow(2.0, zoom) * this.tileSize;
    }

    _mercatorZfromZoom(zoom        )         {
        return this.cameraToCenterDistance / this._worldSizeFromZoom(zoom);
    }

    _minimumHeightOverTerrain()         {
        // Determine minimum height for the camera over the terrain related to current zoom.
        // Values above 4 allow camera closer to e.g. top of the hill, exposing
        // drape raster overscale artifacts or cut terrain (see under it) as it gets clipped on
        // near plane. Returned value is in mercator coordinates.
        const MAX_DRAPE_OVERZOOM = 4;
        const zoom = Math.min((this._seaLevelZoom != null ? this._seaLevelZoom : this._zoom) + MAX_DRAPE_OVERZOOM, this._maxZoom);
        return this._mercatorZfromZoom(zoom);
    }

    _zoomFromMercatorZ(z        )         {
        return this.scaleZoom(this.cameraToCenterDistance / (z * this.tileSize));
    }

    // This function is helpful to approximate true zoom given a mercator height with varying ppm.
    // With Globe, since we use a fixed reference latitude at lower zoom levels and transition between this
    // latitude and the center's latitude as you zoom in, camera to center distance varies dynamically.
    // As the cameraToCenterDistance is a function of zoom, we need to approximate the true zoom
    // given a mercator meter value in order to eliminate the zoom/cameraToCenterDistance dependency.
    zoomFromMercatorZAdjusted(mercatorZ        )         {
        index.assert(this.projection.name === 'globe');
        index.assert(mercatorZ !== 0);

        let zoomLow = 0;
        let zoomHigh = index.GLOBE_ZOOM_THRESHOLD_MAX;
        let zoom = 0;
        let minZoomDiff = Infinity;

        const epsilon = 1e-6;

        while (zoomHigh - zoomLow > epsilon && zoomHigh > zoomLow) {
            const zoomMid = zoomLow + (zoomHigh - zoomLow) * 0.5;

            const worldSize = this.tileSize * Math.pow(2, zoomMid);
            const d = this.getCameraToCenterDistance(this.projection, zoomMid, worldSize);
            const newZoom = this.scaleZoom(d / (mercatorZ * this.tileSize));

            const diff = Math.abs(zoomMid - newZoom);

            if (diff < minZoomDiff) {
                minZoomDiff = diff;
                zoom = zoomMid;
            }

            if (zoomMid < newZoom) {
                zoomLow = zoomMid;
            } else {
                zoomHigh = zoomMid;
            }
        }

        return zoom;
    }

    _terrainEnabled()          {
        if (!this._elevation) return false;
        if (!this.projection.supportsTerrain) {
            index.warnOnce('Terrain is not yet supported with alternate projections. Use mercator or globe to enable terrain.');
            return false;
        }
        return true;
    }

    // Check if any of the four corners are off the edge of the rendered map
    // This function will return `false` for all non-mercator projection
    anyCornerOffEdge(p0       , p1       )          {
        const minX = Math.min(p0.x, p1.x);
        const maxX = Math.max(p0.x, p1.x);
        const minY = Math.min(p0.y, p1.y);
        const maxY = Math.max(p0.y, p1.y);

        const horizon = this.horizonLineFromTop(false);
        if (minY < horizon) return true;

        if (this.projection.name !== 'mercator') {
            return false;
        }

        const min = new index.Point(minX, minY);
        const max = new index.Point(maxX, maxY);

        const corners = [
            min, max,
            new index.Point(minX, maxY),
            new index.Point(maxX, minY),
        ];

        const minWX = (this.renderWorldCopies) ? -NUM_WORLD_COPIES : 0;
        const maxWX = (this.renderWorldCopies) ? 1 + NUM_WORLD_COPIES : 1;
        const minWY = 0;
        const maxWY = 1;

        for (const corner of corners) {
            const rayIntersection = this.pointRayIntersection(corner);
            // Point is above the horizon
            if (rayIntersection.t < 0) {
                return true;
            }
            // Point is off the bondaries of the map
            const coordinate = this.rayIntersectionCoordinate(rayIntersection);
            if (coordinate.x < minWX || coordinate.y < minWY ||
                coordinate.x > maxWX || coordinate.y > maxWY) {
                return true;
            }
        }

        return false;
    }

    // Checks the four corners of the frustum to see if they lie in the map's quad.
    //
    isHorizonVisible()          {

        // we consider the horizon as visible if the angle between
        // a the top plane of the frustum and the map plane is smaller than this threshold.
        const horizonAngleEpsilon = 2;
        if (this.pitch + index.radToDeg(this.fovAboveCenter) > (90 - horizonAngleEpsilon)) {
            return true;
        }

        return this.anyCornerOffEdge(new index.Point(0, 0), new index.Point(this.width, this.height));
    }

    /**
     * Converts a zoom delta value into a physical distance travelled in web mercator coordinates.
     *
     * @param {vec3} center Destination mercator point of the movement.
     * @param {number} zoomDelta Change in the zoom value.
     * @returns {number} The distance in mercator coordinates.
     */
    zoomDeltaToMovement(center      , zoomDelta        )         {
        const distance = index.length(index.sub([], this._camera.position, center));
        const relativeZoom = this._zoomFromMercatorZ(distance) + zoomDelta;
        return distance - this._mercatorZfromZoom(relativeZoom);
    }

    /*
     * The camera looks at the map from a 3D (lng, lat, altitude) location. Let's use `cameraLocation`
     * as the name for the location under the camera and on the surface of the earth (lng, lat, 0).
     * `cameraPoint` is the projected position of the `cameraLocation`.
     *
     * This point is useful to us because only fill-extrusions that are between `cameraPoint` and
     * the query point on the surface of the earth can extend and intersect the query.
     *
     * When the map is not pitched the `cameraPoint` is equivalent to the center of the map because
     * the camera is right above the center of the map.
     */
    getCameraPoint()        {
        if (this.projection.name === 'globe') {
            // Find precise location of the projected camera position on the curved surface
            const center = [this.globeMatrix[12], this.globeMatrix[13], this.globeMatrix[14]];
            const pos = projectClamped(center, this.pixelMatrix);
            return new index.Point(pos[0], pos[1]);
        } else {
            const pitch = this._pitch;
            const yOffset = Math.tan(pitch) * (this.cameraToCenterDistance || 1);
            return this.centerPoint.add(new index.Point(0, yOffset));
        }
    }

    getCameraToCenterDistance(projection            , zoom         = this.zoom, worldSize         = this.worldSize)         {
        const t = getProjectionInterpolationT(projection, zoom, this.width, this.height, 1024);
        const projectionScaler = projection.pixelSpaceConversion(this.center.lat, worldSize, t);
        return 0.5 / Math.tan(this._fov * 0.5) * this.height * projectionScaler;
    }

    getWorldToCameraMatrix()       {
        const zUnit = this.projection.zAxisUnit === "meters" ? this.pixelsPerMeter : 1.0;
        const worldToCamera = this._camera.getWorldToCamera(this.worldSize, zUnit);

        if (this.projection.name === 'globe') {
            index.multiply(worldToCamera, worldToCamera, this.globeMatrix);
        }

        return worldToCamera;
    }
}

//       strict

/**
 * Throttle the given function to run at most every `period` milliseconds.
 * @private
 */
function throttle(fn            , time        )                   {
    let pending = false;
    let timerId             = null;

    const later = () => {
        timerId = null;
        if (pending) {
            fn();
            timerId = setTimeout(later, time);
            pending = false;
        }
    };

    return () => {
        pending = true;
        if (!timerId) {
            later();
        }
        return timerId;
    };
}

//      


                                

/*
 * Adds the map's position to its page's location hash.
 * Passed as an option to the map object.
 *
 * @returns {Hash} `this`
 */
class Hash {
               
                                  
                       

    constructor(hashName         ) {
        this._hashName = hashName && encodeURIComponent(hashName);
        index.bindAll([
            '_getCurrentHash',
            '_onHashChange',
            '_updateHash'
        ], this);

        // Mobile Safari doesn't allow updating the hash more than 100 times per 30 seconds.
        // $FlowFixMe[method-unbinding]
        this._updateHash = throttle(this._updateHashUnthrottled.bind(this), 30 * 1000 / 100);
    }

    /*
     * Map element to listen for coordinate changes
     *
     * @param {Object} map
     * @returns {Hash} `this`
     */
    addTo(map     )       {
        this._map = map;
        // $FlowFixMe[method-unbinding]
        index.window.addEventListener('hashchange', this._onHashChange, false);
        map.on('moveend', this._updateHash);
        return this;
    }

    /*
     * Removes hash
     *
     * @returns {Popup} `this`
     */
    remove()       {
        if (!this._map) return this;

        this._map.off('moveend', this._updateHash);
        // $FlowFixMe[method-unbinding]
        index.window.removeEventListener('hashchange', this._onHashChange, false);
        clearTimeout(this._updateHash());

        this._map = undefined;
        return this;
    }

    getHashString()         {
        const map = this._map;
        if (!map) return '';

        const hash = getHashString(map);

        if (this._hashName) {
            const hashName = this._hashName;
            let found = false;
            const parts = index.window.location.hash.slice(1).split('&').map(part => {
                const key = part.split('=')[0];
                if (key === hashName) {
                    found = true;
                    return `${key}=${hash}`;
                }
                return part;
            }).filter(a => a);
            if (!found) {
                parts.push(`${hashName}=${hash}`);
            }
            return `#${parts.join('&')}`;
        }

        return `#${hash}`;
    }

    _getCurrentHash()                {
        // Get the current hash from location, stripped from its number sign
        const hash = index.window.location.hash.replace('#', '');
        if (this._hashName) {
            // Split the parameter-styled hash into parts and find the value we need
            let keyval;
            hash.split('&').map(
                part => part.split('=')
            ).forEach(part => {
                if (part[0] === this._hashName) {
                    keyval = part;
                }
            });
            return (keyval ? keyval[1] || '' : '').split('/');
        }
        return hash.split('/');
    }

    _onHashChange()          {
        const map = this._map;
        if (!map) return false;
        const loc = this._getCurrentHash();
        if (loc.length >= 3 && !loc.some(v => isNaN(v))) {
            const bearing = map.dragRotate.isEnabled() && map.touchZoomRotate.isEnabled() ? +(loc[3] || 0) : map.getBearing();
            map.jumpTo({
                center: [+loc[2], +loc[1]],
                zoom: +loc[0],
                bearing,
                pitch: +(loc[4] || 0)
            });
            return true;
        }
        return false;
    }

    _updateHashUnthrottled() {
        // Replace if already present, else append the updated hash string
        const location = index.window.location.href.replace(/(#.+)?$/, this.getHashString());
        index.window.history.replaceState(index.window.history.state, null, location);
    }
}

function getHashString(map     , mapFeedback          )         {
    const center = map.getCenter(),
        zoom = Math.round(map.getZoom() * 100) / 100,
        // derived from equation: 512px * 2^z / 360 / 10^d < 0.5px
        precision = Math.ceil((zoom * Math.LN2 + Math.log(512 / 360 / 0.5)) / Math.LN10),
        m = Math.pow(10, precision),
        lng = Math.round(center.lng * m) / m,
        lat = Math.round(center.lat * m) / m,
        bearing = map.getBearing(),
        pitch = map.getPitch();

    // new map feedback site has some constraints that don't allow
    // us to use the same hash format as we do for the Map hash option.
    let hash = mapFeedback ? `/${lng}/${lat}/${zoom}` : `${zoom}/${lat}/${lng}`;

    if (bearing || pitch) hash += (`/${Math.round(bearing * 10) / 10}`);
    if (pitch) hash += (`/${Math.round(pitch)}`);

    return hash;
}

//      


                                                               
                                                   

const defaultInertiaOptions = {
    linearity: 0.3,
    easing: index.bezier(0, 0, 0.3, 1),
};

const defaultPanInertiaOptions = index.extend({
    deceleration: 2500,
    maxSpeed: 1400
}, defaultInertiaOptions);

const defaultZoomInertiaOptions = index.extend({
    deceleration: 20,
    maxSpeed: 1400
}, defaultInertiaOptions);

const defaultBearingInertiaOptions = index.extend({
    deceleration: 1000,
    maxSpeed: 360
}, defaultInertiaOptions);

const defaultPitchInertiaOptions = index.extend({
    deceleration: 1000,
    maxSpeed: 90
}, defaultInertiaOptions);

                              
                      
                                  
                         
                     
  

                                                                              

class HandlerInertia {
              
                                                              

    constructor(map     ) {
        this._map = map;
        this.clear();
    }

    clear() {
        this._inertiaBuffer = [];
    }

    record(settings     ) {
        this._drainInertiaBuffer();
        this._inertiaBuffer.push({time: index.exported.now(), settings});
    }

    _drainInertiaBuffer() {
        const inertia = this._inertiaBuffer,
            now = index.exported.now(),
            cutoff = 160;   //msec

        while (inertia.length > 0 && now - inertia[0].time > cutoff)
            inertia.shift();
    }

    _onMoveEnd(panInertiaOptions                 )                                       {
        if (this._map._prefersReducedMotion()) {
            return;
        }

        this._drainInertiaBuffer();
        if (this._inertiaBuffer.length < 2) {
            return;
        }

        const deltas = {
            zoom: 0,
            bearing: 0,
            pitch: 0,
            pan: new index.Point(0, 0),
            pinchAround: undefined,
            around: undefined
        };

        for (const {settings} of this._inertiaBuffer) {
            deltas.zoom += settings.zoomDelta || 0;
            deltas.bearing += settings.bearingDelta || 0;
            deltas.pitch += settings.pitchDelta || 0;
            if (settings.panDelta) deltas.pan._add(settings.panDelta);
            if (settings.around) deltas.around = settings.around;
            if (settings.pinchAround) deltas.pinchAround = settings.pinchAround;
        }

        const lastEntry = this._inertiaBuffer[this._inertiaBuffer.length - 1];
        const duration = (lastEntry.time - this._inertiaBuffer[0].time);

        const easeOptions = {};

        if (deltas.pan.mag()) {
            const result = calculateEasing(deltas.pan.mag(), duration, index.extend({}, defaultPanInertiaOptions, panInertiaOptions || {}));
            easeOptions.offset = deltas.pan.mult(result.amount / deltas.pan.mag());
            easeOptions.center = this._map.transform.center;
            extendDuration(easeOptions, result);
        }

        if (deltas.zoom) {
            const result = calculateEasing(deltas.zoom, duration, defaultZoomInertiaOptions);
            easeOptions.zoom = this._map.transform.zoom + result.amount;
            extendDuration(easeOptions, result);
        }

        if (deltas.bearing) {
            const result = calculateEasing(deltas.bearing, duration, defaultBearingInertiaOptions);
            easeOptions.bearing = this._map.transform.bearing + index.clamp(result.amount, -179, 179);
            extendDuration(easeOptions, result);
        }

        if (deltas.pitch) {
            const result = calculateEasing(deltas.pitch, duration, defaultPitchInertiaOptions);
            easeOptions.pitch = this._map.transform.pitch + result.amount;
            extendDuration(easeOptions, result);
        }

        if (easeOptions.zoom || easeOptions.bearing) {
            const last = deltas.pinchAround === undefined ? deltas.around : deltas.pinchAround;
            easeOptions.around = last ? this._map.unproject(last) : this._map.getCenter();
        }

        this.clear();
        easeOptions.noMoveStart = true;
        return easeOptions;
    }
}

// Unfortunately zoom, bearing, etc can't have different durations and easings so
// we need to choose one. We use the longest duration and it's corresponding easing.
function extendDuration(easeOptions               , result                                                                       ) {
    if (!easeOptions.duration || easeOptions.duration < result.duration) {
        easeOptions.duration = result.duration;
        easeOptions.easing = result.easing;
    }
}

function calculateEasing(amount        , inertiaDuration        , inertiaOptions                ) {
    const {maxSpeed, linearity, deceleration} = inertiaOptions;
    const speed = index.clamp(
        amount * linearity / (inertiaDuration / 1000),
        -maxSpeed,
        maxSpeed);
    const duration = Math.abs(speed) / (deceleration * linearity);
    return {
        easing: inertiaOptions.easing,
        duration: duration * 1000,
        amount: speed * (duration / 2)
    };
}

//      


                                
                                            

/**
 * `MapMouseEvent` is a class used by other classes to generate
 * mouse events of specific types such as 'click' or 'hover'.
 * For a full list of available events, see [`Map` events](/mapbox-gl-js/api/map/#map-events).
 *
 * @extends {Object}
 * @example
 * // Example of a MapMouseEvent of type "click"
 * map.on('click', (e) => {
 *     console.log(e);
 *     // {
 *     //     lngLat: {
 *     //         lng: 40.203,
 *     //         lat: -74.451
 *     //     },
 *     //     originalEvent: {...},
 *     //     point: {
 *     //         x: 266,
 *     //         y: 464
 *     //     },
 *     //      target: {...},
 *     //      type: "click"
 *     // }
 * });
 * @see [Reference: `Map` events API documentation](https://docs.mapbox.com/mapbox-gl-js/api/map/#map-events)
 * @see [Example: Display popup on click](https://docs.mapbox.com/mapbox-gl-js/example/popup-on-click/)
 * @see [Example: Display popup on hover](https://www.mapbox.com/mapbox-gl-js/example/popup-on-hover/)
 */
class MapMouseEvent extends index.Event {
    /**
     * The type of originating event. For a full list of available events, see [`Map` events](/mapbox-gl-js/api/map/#map-events).
     */
                     
                   
                    
                 
                    
                     
                     
                      
                      
                    
                        

    /**
     * The `Map` object that fired the event.
     */
                

    /**
     * The DOM event which caused the map event.
     */
                              

    /**
     * The pixel coordinates of the mouse cursor, relative to the map and measured from the top left corner.
     */
                 

    /**
     * The geographic location on the map of the mouse cursor.
     */
                   

    /**
     * If a single `layerId`(as a single string) or multiple `layerIds` (as an array of strings) were specified when adding the event listener with {@link Map#on},
     * `features` will be an array of [GeoJSON](http://geojson.org/) [Feature objects](https://tools.ietf.org/html/rfc7946#section-3.2).
     * The array will contain all features from that layer that are rendered at the event's point,
     * in the order that they are rendered with the topmost feature being at the start of the array.
     * The `features` are identical to those returned by {@link Map#queryRenderedFeatures}.
     *
     * If no `layerId` was specified when adding the event listener, `features` will be `undefined`.
     * You can get the features at the point with `map.queryRenderedFeatures(e.point)`.
     *
     * @example
     * // logging features for a specific layer (with `e.features`)
     * map.on('click', 'myLayerId', (e) => {
     *     console.log(`There are ${e.features.length} features at point ${e.point}`);
     * });
     *
     * @example
     * // logging features for two layers (with `e.features`)
     * map.on('click', ['layer1', 'layer2'], (e) => {
     *     console.log(`There are ${e.features.length} features at point ${e.point}`);
     * });
     *
     * @example
     * // logging all features for all layers (without `e.features`)
     * map.on('click', (e) => {
     *     const features = map.queryRenderedFeatures(e.point);
     *     console.log(`There are ${features.length} features at point ${e.point}`);
     * });
     */
                                   

    /**
     * Prevents subsequent default processing of the event by the map.
     *
     * Calling this method will prevent the following default map behaviors:
     *
     *   * On `mousedown` events, the behavior of {@link DragPanHandler}.
     *   * On `mousedown` events, the behavior of {@link DragRotateHandler}.
     *   * On `mousedown` events, the behavior of {@link BoxZoomHandler}.
     *   * On `dblclick` events, the behavior of {@link DoubleClickZoomHandler}.
     *
     * @example
     * map.on('click', (e) => {
     *     e.preventDefault();
     * });
     */
    preventDefault() {
        this._defaultPrevented = true;
    }

    /**
     * `true` if `preventDefault` has been called.
     * @private
     */
    get defaultPrevented()          {
        return this._defaultPrevented;
    }

                               

    /**
     * @private
     */
    constructor(type        , map     , originalEvent            , data         = {}) {
        const point = mousePos(map.getCanvasContainer(), originalEvent);
        const lngLat = map.unproject(point);
        super(type, index.extend({point, lngLat, originalEvent}, data));
        this._defaultPrevented = false;
        this.target = map;
    }
}

/**
 * `MapTouchEvent` is a class used by other classes to generate
 * mouse events of specific types such as 'touchstart' or 'touchend'.
 * For a full list of available events, see [`Map` events](/mapbox-gl-js/api/map/#map-events).
 *
 * @extends {Object}
 *
 * @example
 * // Example of a MapTouchEvent of type "touch"
 * map.on('touchstart', (e) => {
 *     console.log(e);
 *     // {
 *     //   lngLat: {
 *     //      lng: 40.203,
 *     //      lat: -74.451
 *     //   },
 *     //   lngLats: [
 *     //      {
 *     //         lng: 40.203,
 *     //         lat: -74.451
 *     //      }
 *     //   ],
 *     //   originalEvent: {...},
 *     //   point: {
 *     //      x: 266,
 *     //      y: 464
 *     //   },
 *     //   points: [
 *     //      {
 *     //         x: 266,
 *     //         y: 464
 *     //      }
 *     //   ]
 *     //   preventDefault(),
 *     //   target: {...},
 *     //   type: "touchstart"
 *     // }
 * });
 * @see [Reference: `Map` events API documentation](https://docs.mapbox.com/mapbox-gl-js/api/map/#map-events)
 * @see [Example: Create a draggable point](https://docs.mapbox.com/mapbox-gl-js/example/drag-a-point/)
 */
class MapTouchEvent extends index.Event {
    /**
     * The type of originating event. For a full list of available events, see [`Map` events](/mapbox-gl-js/api/map/#map-events).
     */
                      
                    
                        

    /**
     * The `Map` object that fired the event.
     */
                

    /**
     * The DOM event which caused the map event.
     */
                              

    /**
     * The geographic location on the map of the center of the touch event points.
     */
                   

    /**
     * The pixel coordinates of the center of the touch event points, relative to the map and measured from the top left
     * corner.
     */
                 

    /**
     * The array of pixel coordinates corresponding to a
     * [touch event's `touches`](https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/touches) property.
     */
                         

    /**
     * The geographical locations on the map corresponding to a
     * [touch event's `touches`](https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/touches) property.
     */
                           

    /**
     * If a `layerId` was specified when adding the event listener with {@link Map#on}, `features` will be an array of
     * [GeoJSON](http://geojson.org/) [Feature objects](https://tools.ietf.org/html/rfc7946#section-3.2).
     * The array will contain all features from that layer that are rendered at the event's point.
     * The `features` are identical to those returned by {@link Map#queryRenderedFeatures}.
     *
     * If no `layerId` was specified when adding the event listener, `features` will be `undefined`.
     * You can get the features at the point with `map.queryRenderedFeatures(e.point)`.
     *
     * @example
     * // logging features for a specific layer (with `e.features`)
     * map.on('touchstart', 'myLayerId', (e) => {
     *     console.log(`There are ${e.features.length} features at point ${e.point}`);
     * });
     *
     * @example
     * // logging all features for all layers (without `e.features`)
     * map.on('touchstart', (e) => {
     *     const features = map.queryRenderedFeatures(e.point);
     *     console.log(`There are ${features.length} features at point ${e.point}`);
     * });
     */
                                   

    /**
     * Prevents subsequent default processing of the event by the map.
     *
     * Calling this method will prevent the following default map behaviors:
     *
     *   * On `touchstart` events, the behavior of {@link DragPanHandler}.
     *   * On `touchstart` events, the behavior of {@link TouchZoomRotateHandler}.
     *
     * @example
     * map.on('touchstart', (e) => {
     *     e.preventDefault();
     * });
     */
    preventDefault() {
        this._defaultPrevented = true;
    }

    /**
     * Returns `true` if `preventDefault` has been called.
     * @private
     */
    get defaultPrevented()          {
        return this._defaultPrevented;
    }

                               

    /**
     * @private
     */
    constructor(type        , map     , originalEvent            ) {
        const touches = type === "touchend" ? originalEvent.changedTouches : originalEvent.touches;
        const points = touchPos(map.getCanvasContainer(), touches);
        const lngLats = points.map((t) => map.unproject(t));
        const point = points.reduce((prev, curr, i, arr) => {
            return prev.add(curr.div(arr.length));
        }, new index.Point(0, 0));
        const lngLat = map.unproject(point);
        super(type, {points, point, lngLats, lngLat, originalEvent});
        this._defaultPrevented = false;
    }
}

/**
 * `MapWheelEvent` is a class used by other classes to generate
 * mouse events of specific types such as 'wheel'.
 * For a full list of available events, see [`Map` events](/mapbox-gl-js/api/map/#map-events).
 *
 * @extends {Object}
 * @example
 * // Example event trigger for a MapWheelEvent of type "wheel"
 * map.on('wheel', (e) => {
 *     console.log('event type:', e.type);
 *     // event type: wheel
 * });
 * @example
 * // Example of a MapWheelEvent of type "wheel"
 * // {
 * //   originalEvent: WheelEvent {...},
 * // 	 target: Map {...},
 * // 	 type: "wheel"
 * // }
 * @see [Reference: `Map` events API documentation](https://docs.mapbox.com/mapbox-gl-js/api/map/#map-events)
 */
class MapWheelEvent extends index.Event {
    /**
     * The type of originating event. For a full list of available events, see [`Map` events](/mapbox-gl-js/api/map/#map-events).
     */
                  

    /**
     * The `Map` object that fired the event.
     */
                

    /**
     * The DOM event which caused the map event.
     */
                              

    /**
     * Prevents subsequent default processing of the event by the map.
     * Calling this method will prevent the the behavior of {@link ScrollZoomHandler}.
     *
     * @example
     * map.on('wheel', (e) => {
     *     // Prevent the default map scroll zoom behavior.
     *     e.preventDefault();
     * });
     */
    preventDefault() {
        this._defaultPrevented = true;
    }

    /**
     * `true` if `preventDefault` has been called.
     * @private
     */
    get defaultPrevented()          {
        return this._defaultPrevented;
    }

                               

    /**
     * @private
     */
    constructor(type        , map     , originalEvent            ) {
        super(type, {originalEvent});
        this._defaultPrevented = false;
    }
}

/**
 * `MapBoxZoomEvent` is a class used to generate
 * the events 'boxzoomstart', 'boxzoomend', and 'boxzoomcancel'.
 * For a full list of available events, see [`Map` events](/mapbox-gl-js/api/map/#map-events).
 *
 * @typedef {Object} MapBoxZoomEvent
 * @property {MouseEvent} originalEvent The DOM event that triggered the boxzoom event. Can be a `MouseEvent` or `KeyboardEvent`.
 * @property {('boxzoomstart' | 'boxzoomend' | 'boxzoomcancel')} type The type of originating event. For a full list of available events, see [`Map` events](/mapbox-gl-js/api/map/#map-events).
 * @property {Map} target The `Map` instance that triggered the event.
 * @example
 * // Example trigger of a BoxZoomEvent of type "boxzoomstart"
 * map.on('boxzoomstart', (e) => {
 *     console.log('event type:', e.type);
 *     // event type: boxzoomstart
 * });
 * @example
 * // Example of a BoxZoomEvent of type "boxzoomstart"
 * // {
 * //   originalEvent: {...},
 * //   type: "boxzoomstart",
 * //   target: {...}
 * // }
 * @see [Reference: `Map` events API documentation](https://docs.mapbox.com/mapbox-gl-js/api/map/#map-events)
 * @see [Example: Highlight features within a bounding box](https://docs.mapbox.com/mapbox-gl-js/example/using-box-queryrenderedfeatures/)
 */
                               
                        
                      
                          
                
                             
  

/**
 * `MapDataEvent` is a class used to generate
 * events related to loading data, styles, and sources.
 * For a full list of available events, see [`Map` events](/mapbox-gl-js/api/map/#map-events).
 *
 * @typedef {Object} MapDataEvent
 * @property {('data' | 'dataloading' | 'styledata' | 'styledataloading' | 'sourcedata'| 'sourcedataloading')} type The type of originating event. For a full list of available events, see [`Map` events](/mapbox-gl-js/api/map/#map-events).
 * @property {('source' | 'style')} dataType The type of data that has changed. One of `'source'` or `'style'`, where `'source'` refers to the data associated with any source, and `'style'` refers to the entire [style](https://docs.mapbox.com/help/glossary/style/) used by the map.
 * @property {boolean} [isSourceLoaded] True if the event has a `dataType` of `source` and the source has no outstanding network requests.
 * @property {Object} [source] The [style spec representation of the source](https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/) if the event has a `dataType` of `source`.
 * @property {string} [sourceId] The `id` of the [`source`](https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/) that triggered the event, if the event has a `dataType` of `source`. Same as the `id` of the object in the `source` property.
 * @property {string} [sourceDataType] Included if the event has a `dataType` of `source` and the event signals
 * that internal data has been received or changed. Possible values are `metadata`, `content` and `visibility`.
 * @property {Object} [tile] The tile being loaded or changed, if the event has a `dataType` of `source` and
 * the event is related to loading of a tile.
 * @property {Coordinate} [coord] The coordinate of the tile if the event has a `dataType` of `source` and
 * the event is related to loading of a tile.
 * @example
 * // Example of a MapDataEvent of type "sourcedata"
 * map.on('sourcedata', (e) => {
 *     console.log(e);
 *     // {
 *     //   dataType: "source",
 *     //   isSourceLoaded: false,
 *     //   source: {
 *     //     type: "vector",
 *     //     url: "mapbox://mapbox.mapbox-streets-v8,mapbox.mapbox-terrain-v2"
 *     //   },
 *     //   sourceDataType: "visibility",
 *     //   sourceId: "composite",
 *     //   style: {...},
 *     //   target: {...},
 *     //   type: "sourcedata"
 *     // }
 * });
 * @see [Reference: `Map` events API documentation](https://docs.mapbox.com/mapbox-gl-js/api/map/#map-events)
 * @see [Example: Change a map's style](https://docs.mapbox.com/mapbox-gl-js/example/setstyle/)
 * @see [Example: Add a GeoJSON line](https://docs.mapbox.com/mapbox-gl-js/example/geojson-line/)
 */

//      


                                 
                                                
                                                         

class MapEventHandler {

                          
                            
              

    constructor(map     , options                            ) {
        this._map = map;
        this._clickTolerance = options.clickTolerance;
    }

    reset() {
        this._mousedownPos = undefined;
    }

    wheel(e            )                 {
        // If mapEvent.preventDefault() is called by the user, prevent handlers such as:
        // - ScrollZoom
        return this._firePreventable(new MapWheelEvent(e.type, this._map, e));
    }

    mousedown(e            , point       )                 {
        this._mousedownPos = point;
        // If mapEvent.preventDefault() is called by the user, prevent handlers such as:
        // - MousePan
        // - MouseRotate
        // - MousePitch
        // - DblclickHandler
        return this._firePreventable(new MapMouseEvent(e.type, this._map, e));
    }

    mouseup(e            ) {
        this._map.fire(new MapMouseEvent(e.type, this._map, e));
    }

    preclick(e            ) {
        const synth = index.extend({}, e);
        synth.type = 'preclick';
        this._map.fire(new MapMouseEvent(synth.type, this._map, synth));
    }

    click(e            , point       ) {
        if (this._mousedownPos && this._mousedownPos.dist(point) >= this._clickTolerance) return;
        this.preclick(e);
        this._map.fire(new MapMouseEvent(e.type, this._map, e));
    }

    dblclick(e            )                 {
        // If mapEvent.preventDefault() is called by the user, prevent handlers such as:
        // - DblClickZoom
        return this._firePreventable(new MapMouseEvent(e.type, this._map, e));
    }

    mouseover(e            ) {
        this._map.fire(new MapMouseEvent(e.type, this._map, e));
    }

    mouseout(e            ) {
        this._map.fire(new MapMouseEvent(e.type, this._map, e));
    }

    touchstart(e            )                 {
        // If mapEvent.preventDefault() is called by the user, prevent handlers such as:
        // - TouchPan
        // - TouchZoom
        // - TouchRotate
        // - TouchPitch
        // - TapZoom
        // - SwipeZoom
        return this._firePreventable(new MapTouchEvent(e.type, this._map, e));
    }

    touchmove(e            ) {
        this._map.fire(new MapTouchEvent(e.type, this._map, e));
    }

    touchend(e            ) {
        this._map.fire(new MapTouchEvent(e.type, this._map, e));
    }

    touchcancel(e            ) {
        this._map.fire(new MapTouchEvent(e.type, this._map, e));
    }

    _firePreventable(mapEvent                                               )                 {
        this._map.fire(mapEvent);
        if (mapEvent.defaultPrevented) {
            // returning an object marks the handler as active and resets other handlers
            return {};
        }
    }

    isEnabled()          {
        return true;
    }

    isActive()          {
        return false;
    }
    enable() {}
    disable() {}
}

class BlockableMapEventHandler {
              
                               
                                   

    constructor(map     ) {
        this._map = map;
    }

    reset() {
        this._delayContextMenu = false;
        this._contextMenuEvent = undefined;
    }

    mousemove(e            ) {
        // mousemove map events should not be fired when interaction handlers (pan, rotate, etc) are active
        this._map.fire(new MapMouseEvent(e.type, this._map, e));
    }

    mousedown() {
        this._delayContextMenu = true;
    }

    mouseup() {
        this._delayContextMenu = false;
        if (this._contextMenuEvent) {
            this._map.fire(new MapMouseEvent('contextmenu', this._map, this._contextMenuEvent));
            delete this._contextMenuEvent;
        }
    }
    contextmenu(e            ) {
        if (this._delayContextMenu) {
            // Mac: contextmenu fired on mousedown; we save it until mouseup for consistency's sake
            this._contextMenuEvent = e;
        } else {
            // Windows: contextmenu fired on mouseup, so fire event now
            this._map.fire(new MapMouseEvent(e.type, this._map, e));
        }

        // prevent browser context menu when necessary
        if (this._map.listens('contextmenu')) {
            e.preventDefault();
        }
    }

    isEnabled()          {
        return true;
    }

    isActive()          {
        return false;
    }
    enable() {}
    disable() {}
}

//      


                                 
                                                
                                                         

/**
 * The `BoxZoomHandler` allows the user to zoom the map to fit within a bounding box.
 * The bounding box is defined by clicking and holding `shift` while dragging the cursor.
 *
 * @see [Example: Toggle interactions](https://docs.mapbox.com/mapbox-gl-js/example/toggle-interaction-handlers/)
 * @see [Example: Highlight features within a bounding box](https://docs.mapbox.com/mapbox-gl-js/example/using-box-queryrenderedfeatures/)
 */
class BoxZoomHandler {
              
                     
                            
                      
                     
                      
                     
                      
                            

    /**
     * @private
     */
    constructor(map     , options   
                              
     ) {
        this._map = map;
        this._el = map.getCanvasContainer();
        this._container = map.getContainer();
        this._clickTolerance = options.clickTolerance || 1;
    }

    /**
     * Returns a Boolean indicating whether the "box zoom" interaction is enabled.
     *
     * @returns {boolean} Returns `true` if the "box zoom" interaction is enabled.
     * @example
     * const isBoxZoomEnabled = map.boxZoom.isEnabled();
     */
    isEnabled()          {
        return !!this._enabled;
    }

    /**
     * Returns a Boolean indicating whether the "box zoom" interaction is active (currently being used).
     *
     * @returns {boolean} Returns `true` if the "box zoom" interaction is active.
     * @example
     * const isBoxZoomActive = map.boxZoom.isActive();
     */
    isActive()          {
        return !!this._active;
    }

    /**
     * Enables the "box zoom" interaction.
     *
     * @example
     * map.boxZoom.enable();
     */
    enable() {
        if (this.isEnabled()) return;
        this._enabled = true;
    }

    /**
     * Disables the "box zoom" interaction.
     *
     * @example
     * map.boxZoom.disable();
     */
    disable() {
        if (!this.isEnabled()) return;
        this._enabled = false;
    }

    mousedown(e            , point       ) {
        if (!this.isEnabled()) return;
        if (!(e.shiftKey && e.button === 0)) return;

        disableDrag();
        this._startPos = this._lastPos = point;
        this._active = true;
    }

    mousemoveWindow(e            , point       ) {
        if (!this._active) return;

        const pos = point;
        const p0 = this._startPos;
        const p1 = this._lastPos;

        if (!p0 || !p1 || p1.equals(pos) || (!this._box && pos.dist(p0) < this._clickTolerance)) {
            return;
        }

        this._lastPos = pos;

        if (!this._box) {
            this._box = create$1('div', 'mapboxgl-boxzoom', this._container);
            this._container.classList.add('mapboxgl-crosshair');
            this._fireEvent('boxzoomstart', e);
        }

        const minX = Math.min(p0.x, pos.x),
            maxX = Math.max(p0.x, pos.x),
            minY = Math.min(p0.y, pos.y),
            maxY = Math.max(p0.y, pos.y);

        this._map._requestDomTask(() => {
            if (this._box) {
                this._box.style.transform = `translate(${minX}px,${minY}px)`;
                this._box.style.width = `${maxX - minX}px`;
                this._box.style.height = `${maxY - minY}px`;
            }
        });
    }

    mouseupWindow(e            , point       )                 {
        if (!this._active) return;

        const p0 = this._startPos,
            p1 = point;

        if (!p0 || e.button !== 0) return;

        this.reset();

        suppressClick();

        if (p0.x === p1.x && p0.y === p1.y) {
            this._fireEvent('boxzoomcancel', e);
        } else {
            this._map.fire(new index.Event('boxzoomend', {originalEvent: e}));
            return {
                cameraAnimation: (map     ) => map.fitScreenCoordinates(p0, p1, this._map.getBearing(), {linear: false})
            };
        }
    }

    keydown(e               ) {
        if (!this._active) return;

        if (e.keyCode === 27) {
            this.reset();
            this._fireEvent('boxzoomcancel', e);
        }
    }

    blur() {
        this.reset();
    }

    reset() {
        this._active = false;

        this._container.classList.remove('mapboxgl-crosshair');

        if (this._box) {
            this._box.remove();
            this._box = (null     );
        }

        enableDrag();

        delete this._startPos;
        delete this._lastPos;
    }

    _fireEvent(type        , e     )      {
        return this._map.fire(new index.Event(type, {originalEvent: e}));
    }
}

//      


                                                

function indexTouches(touches              , points              )                             {
    index.assert(touches.length === points.length);
    const obj = {};
    for (let i = 0; i < touches.length; i++) {
        obj[touches[i].identifier] = points[i];
    }
    return obj;
}

//      


function getCentroid(points              ) {
    const sum = new index.Point(0, 0);
    for (const point of points) {
        sum._add(point);
    }
    return sum.div(points.length);
}

const MAX_TAP_INTERVAL = 500;
const MAX_TOUCH_TIME = 500;
const MAX_DIST = 30;

class SingleTapRecognizer {

                       
                     
                      
                     
                                          

    constructor(options                        ) {
        this.reset();
        this.numTouches = options.numTouches;
    }

    reset() {
        this.centroid = undefined;
        this.startTime = 0;
        this.touches = {};
        this.aborted = false;
    }

    touchstart(e            , points              , mapTouches              ) {

        if (this.centroid || mapTouches.length > this.numTouches) {
            this.aborted = true;
        }
        if (this.aborted) {
            return;
        }

        if (this.startTime === 0) {
            this.startTime = e.timeStamp;
        }

        if (mapTouches.length === this.numTouches) {
            this.centroid = getCentroid(points);
            this.touches = indexTouches(mapTouches, points);
        }
    }

    touchmove(e            , points              , mapTouches              ) {
        if (this.aborted || !this.centroid) return;

        const newTouches = indexTouches(mapTouches, points);
        for (const id in this.touches) {
            const prevPos = this.touches[id];
            const pos = newTouches[id];
            if (!pos || pos.dist(prevPos) > MAX_DIST) {
                this.aborted = true;
            }
        }
    }

    touchend(e            , points              , mapTouches              )         {
        if (!this.centroid || e.timeStamp - this.startTime > MAX_TOUCH_TIME) {
            this.aborted = true;
        }

        if (mapTouches.length === 0) {
            const centroid = !this.aborted && this.centroid;
            this.reset();
            if (centroid) return centroid;
        }
    }

}

class TapRecognizer {

                                   
                    
                     
                    
                  

    constructor(options                                         ) {
        this.singleTap = new SingleTapRecognizer(options);
        this.numTaps = options.numTaps;
        this.reset();
    }

    reset() {
        this.lastTime = Infinity;
        this.lastTap = undefined;
        this.count = 0;
        this.singleTap.reset();
    }

    touchstart(e            , points              , mapTouches              ) {
        this.singleTap.touchstart(e, points, mapTouches);
    }

    touchmove(e            , points              , mapTouches              ) {
        this.singleTap.touchmove(e, points, mapTouches);
    }

    touchend(e            , points              , mapTouches              )         {
        const tap = this.singleTap.touchend(e, points, mapTouches);
        if (tap) {
            const soonEnough = e.timeStamp - this.lastTime < MAX_TAP_INTERVAL;
            const closeEnough = !this.lastTap || this.lastTap.dist(tap) < MAX_DIST;

            if (!soonEnough || !closeEnough) {
                this.reset();
            }

            this.count++;
            this.lastTime = e.timeStamp;
            this.lastTap = tap;

            if (this.count === this.numTaps) {
                this.reset();
                return tap;
            }
        }
    }
}

//      

                                                
                                 
                                                         

class TapZoomHandler {

                      
                     
                           
                            

    constructor() {
        this._zoomIn = new TapRecognizer({
            numTouches: 1,
            numTaps: 2
        });

        this._zoomOut = new TapRecognizer({
            numTouches: 2,
            numTaps: 1
        });

        this.reset();
    }

    reset() {
        this._active = false;
        this._zoomIn.reset();
        this._zoomOut.reset();
    }

    touchstart(e            , points              , mapTouches              ) {
        this._zoomIn.touchstart(e, points, mapTouches);
        this._zoomOut.touchstart(e, points, mapTouches);
    }

    touchmove(e            , points              , mapTouches              ) {
        this._zoomIn.touchmove(e, points, mapTouches);
        this._zoomOut.touchmove(e, points, mapTouches);
    }

    touchend(e            , points              , mapTouches              )                 {
        const zoomInPoint = this._zoomIn.touchend(e, points, mapTouches);
        const zoomOutPoint = this._zoomOut.touchend(e, points, mapTouches);

        if (zoomInPoint) {
            this._active = true;
            e.preventDefault();
            setTimeout(() => this.reset(), 0);
            return {
                cameraAnimation: (map     ) => map.easeTo({
                    duration: 300,
                    zoom: map.getZoom() + 1,
                    around: map.unproject(zoomInPoint)
                }, {originalEvent: e})
            };
        } else if (zoomOutPoint) {
            this._active = true;
            e.preventDefault();
            setTimeout(() => this.reset(), 0);
            return {
                cameraAnimation: (map     ) => map.easeTo({
                    duration: 300,
                    zoom: map.getZoom() - 1,
                    around: map.unproject(zoomOutPoint)
                }, {originalEvent: e})
            };
        }
    }

    touchcancel() {
        this.reset();
    }

    enable() {
        this._enabled = true;
    }

    disable() {
        this._enabled = false;
        this.reset();
    }

    isEnabled()          {
        return this._enabled;
    }

    isActive()          {
        return this._active;
    }
}

//      

                                                
                                                         

const LEFT_BUTTON = 0;
const RIGHT_BUTTON = 2;

// the values for each button in MouseEvent.buttons
const BUTTONS_FLAGS = {
    [LEFT_BUTTON]: 1,
    [RIGHT_BUTTON]: 2
};

function buttonStillPressed(e            , button        ) {
    const flag = BUTTONS_FLAGS[button];
    return e.buttons === undefined || (e.buttons & flag) !== flag;
}

class MouseHandler {

                      
                     
                       
                          
                    
                            

    constructor(options                            ) {
        this.reset();
        this._clickTolerance = options.clickTolerance || 1;
    }

    blur() {
        this.reset();
    }

    reset() {
        this._active = false;
        this._moved = false;
        this._lastPoint = undefined;
        this._eventButton = undefined;
    }

    _correctButton(e            , button        )          {  //eslint-disable-line
        return false; // implemented by child
    }

    _move(lastPoint       , point       )                 {  //eslint-disable-line
        return {}; // implemented by child
    }

    mousedown(e            , point       ) {
        if (this._lastPoint) return;

        const eventButton = mouseButton(e);
        if (!this._correctButton(e, eventButton)) return;

        this._lastPoint = point;
        this._eventButton = eventButton;
    }

    mousemoveWindow(e            , point       )                 {
        const lastPoint = this._lastPoint;
        if (!lastPoint) return;
        e.preventDefault();

        if (this._eventButton != null && buttonStillPressed(e, this._eventButton)) {
            // Some browsers don't fire a `mouseup` when the mouseup occurs outside
            // the window or iframe:
            // https://github.com/mapbox/mapbox-gl-js/issues/4622
            //
            // If the button is no longer pressed during this `mousemove` it may have
            // been released outside of the window or iframe.
            this.reset();
            return;
        }

        if (!this._moved && point.dist(lastPoint) < this._clickTolerance) return;
        this._moved = true;
        this._lastPoint = point;

        // implemented by child class
        return this._move(lastPoint, point);
    }

    mouseupWindow(e            ) {
        if (!this._lastPoint) return;
        const eventButton = mouseButton(e);
        if (eventButton !== this._eventButton) return;
        if (this._moved) suppressClick();
        this.reset();
    }

    enable() {
        this._enabled = true;
    }

    disable() {
        this._enabled = false;
        this.reset();
    }

    isEnabled()          {
        return this._enabled;
    }

    isActive()          {
        return this._active;
    }
}

class MousePanHandler extends MouseHandler {

    mousedown(e            , point       ) {
        super.mousedown(e, point);
        if (this._lastPoint) this._active = true;
    }
    _correctButton(e            , button        )          {
        return button === LEFT_BUTTON && !e.ctrlKey;
    }

    _move(lastPoint       , point       )                 {
        return {
            around: point,
            panDelta: point.sub(lastPoint)
        };
    }
}

class MouseRotateHandler extends MouseHandler {
    _correctButton(e            , button        )          {
        return (button === LEFT_BUTTON && e.ctrlKey) || (button === RIGHT_BUTTON);
    }

    _move(lastPoint       , point       )                 {
        const degreesPerPixelMoved = 0.8;
        const bearingDelta = (point.x - lastPoint.x) * degreesPerPixelMoved;
        if (bearingDelta) {
            this._active = true;
            return {bearingDelta};
        }
    }

    contextmenu(e            ) {
        // prevent browser context menu when necessary; we don't allow it with rotation
        // because we can't discern rotation gesture start from contextmenu on Mac
        e.preventDefault();
    }
}

class MousePitchHandler extends MouseHandler {
    _correctButton(e            , button        )          {
        return (button === LEFT_BUTTON && e.ctrlKey) || (button === RIGHT_BUTTON);
    }

    _move(lastPoint       , point       )                 {
        const degreesPerPixelMoved = -0.5;
        const pitchDelta = (point.y - lastPoint.y) * degreesPerPixelMoved;
        if (pitchDelta) {
            this._active = true;
            return {pitchDelta};
        }
    }

    contextmenu(e            ) {
        // prevent browser context menu when necessary; we don't allow it with rotation
        // because we can't discern rotation gesture start from contextmenu on Mac
        e.preventDefault();
    }
}

//      

                                                         

class TouchPanHandler {

              
                     
                      
                     
                                           
                        
                            
                
                                 
                           

    constructor(map     , options                            ) {
        this._map = map;
        this._el = map.getCanvasContainer();
        this._minTouches = 1;
        this._clickTolerance = options.clickTolerance || 1;
        this.reset();
        index.bindAll(['_addTouchPanBlocker', '_showTouchPanBlockerAlert'], this);
    }

    reset() {
        this._active = false;
        this._touches = {};
        this._sum = new index.Point(0, 0);
    }

    touchstart(e            , points              , mapTouches              )                 {
        return this._calculateTransform(e, points, mapTouches);
    }

    touchmove(e            , points              , mapTouches              )                 {
        if (!this._active || mapTouches.length < this._minTouches) return;

        // if cooperative gesture handling is set to true, require two fingers to touch pan
        if (this._map._cooperativeGestures && !this._map.isMoving()) {
            if (mapTouches.length === 1 && !index.isFullscreen()) {
                this._showTouchPanBlockerAlert();
                return;
            } else if (this._alertContainer.style.visibility !== 'hidden') {
                // immediately hide alert if it is visible when two fingers are used to pan.
                this._alertContainer.style.visibility = 'hidden';
                clearTimeout(this._alertTimer);
            }
        }

        if (e.cancelable) {
            e.preventDefault();
        }

        return this._calculateTransform(e, points, mapTouches);
    }

    touchend(e            , points              , mapTouches              ) {
        this._calculateTransform(e, points, mapTouches);

        if (this._active && mapTouches.length < this._minTouches) {
            this.reset();
        }
    }

    touchcancel() {
        this.reset();
    }

    _calculateTransform(e            , points              , mapTouches              )                 {
        if (mapTouches.length > 0) this._active = true;

        const touches = indexTouches(mapTouches, points);

        const touchPointSum = new index.Point(0, 0);
        const touchDeltaSum = new index.Point(0, 0);
        let touchDeltaCount = 0;

        for (const identifier in touches) {
            const point = touches[identifier];
            const prevPoint = this._touches[identifier];
            if (prevPoint) {
                touchPointSum._add(point);
                touchDeltaSum._add(point.sub(prevPoint));
                touchDeltaCount++;
                touches[identifier] = point;
            }
        }

        this._touches = touches;

        if (touchDeltaCount < this._minTouches || !touchDeltaSum.mag()) return;

        const panDelta = touchDeltaSum.div(touchDeltaCount);
        this._sum._add(panDelta);
        if (this._sum.mag() < this._clickTolerance) return;

        const around = touchPointSum.div(touchDeltaCount);

        return {
            around,
            panDelta
        };
    }

    enable() {
        this._enabled = true;
        if (this._map._cooperativeGestures) {
            this._addTouchPanBlocker();
            // override touch-action css property to enable scrolling page over map
            this._el.classList.add('mapboxgl-touch-pan-blocker-override', 'mapboxgl-scrollable-page');
        }
    }

    disable() {
        this._enabled = false;
        if (this._map._cooperativeGestures) {
            clearTimeout(this._alertTimer);
            this._alertContainer.remove();
            this._el.classList.remove('mapboxgl-touch-pan-blocker-override', 'mapboxgl-scrollable-page');
        }
        this.reset();
    }

    isEnabled()          {
        return !!this._enabled;
    }

    isActive()          {
        return !!this._active;
    }

    _addTouchPanBlocker() {
        if (this._map && !this._alertContainer) {
            this._alertContainer = create$1('div', 'mapboxgl-touch-pan-blocker', this._map._container);

            this._alertContainer.textContent = this._map._getUIString('TouchPanBlocker.Message');

            // dynamically set the font size of the touch pan blocker alert message
            this._alertContainer.style.fontSize = `${Math.max(10, Math.min(24, Math.floor(this._el.clientWidth * 0.05)))}px`;
        }
    }

    _showTouchPanBlockerAlert() {
        this._alertContainer.style.visibility = 'visible';
        this._alertContainer.classList.add('mapboxgl-touch-pan-blocker-show');
        this._alertContainer.setAttribute("role", "alert");

        clearTimeout(this._alertTimer);

        this._alertTimer = setTimeout(() => {
            this._alertContainer.classList.remove('mapboxgl-touch-pan-blocker-show');
            this._alertContainer.setAttribute("role", "null");
        }, 500);
    }

}

//      


class TwoTouchHandler {

                      
                     
                                        
                    
                         
                           

    constructor() {
        this.reset();
    }

    reset() {
        this._active = false;
        this._firstTwoTouches = undefined;
    }

    _start(points                ) {} //eslint-disable-line
    _move(points                , pinchAround        , e            )                 { return {}; } //eslint-disable-line

    touchstart(e            , points              , mapTouches              ) {
        //console.log(e.target, e.targetTouches.length ? e.targetTouches[0].target : null);
        //log('touchstart', points, e.target.innerHTML, e.targetTouches.length ? e.targetTouches[0].target.innerHTML: undefined);
        if (this._firstTwoTouches || mapTouches.length < 2) return;

        this._firstTwoTouches = [
            mapTouches[0].identifier,
            mapTouches[1].identifier
        ];

        // implemented by child classes
        this._start([points[0], points[1]]);
    }

    touchmove(e            , points              , mapTouches              )                 {
        const firstTouches = this._firstTwoTouches;
        if (!firstTouches) return;

        e.preventDefault();

        const [idA, idB] = firstTouches;
        const a = getTouchById(mapTouches, points, idA);
        const b = getTouchById(mapTouches, points, idB);
        if (!a || !b) return;
        const pinchAround = this._aroundCenter ? null : a.add(b).div(2);

        // implemented by child classes
        return this._move([a, b], pinchAround, e);

    }

    touchend(e            , points              , mapTouches              ) {
        if (!this._firstTwoTouches) return;

        const [idA, idB] = this._firstTwoTouches;
        const a = getTouchById(mapTouches, points, idA);
        const b = getTouchById(mapTouches, points, idB);
        if (a && b) return;

        if (this._active) suppressClick();

        this.reset();
    }

    touchcancel() {
        this.reset();
    }

    enable(options                      ) {
        this._enabled = true;
        this._aroundCenter = !!options && options.around === 'center';
    }

    disable() {
        this._enabled = false;
        this.reset();
    }

    isEnabled()          {
        return this._enabled;
    }

    isActive()          {
        return this._active;
    }
}

function getTouchById(mapTouches              , points              , identifier        ) {
    for (let i = 0; i < mapTouches.length; i++) {
        if (mapTouches[i].identifier === identifier) return points[i];
    }
}

/* ZOOM */

const ZOOM_THRESHOLD = 0.1;

function getZoomDelta(distance        , lastDistance        ) {
    return Math.log(distance / lastDistance) / Math.LN2;
}

class TouchZoomHandler extends TwoTouchHandler {

                      
                           

    reset() {
        super.reset();
        this._distance = 0;
        this._startDistance = 0;
    }

    _start(points                ) {
        this._startDistance = this._distance = points[0].dist(points[1]);
    }

    _move(points                , pinchAround        )                 {
        const lastDistance = this._distance;
        this._distance = points[0].dist(points[1]);
        if (!this._active && Math.abs(getZoomDelta(this._distance, this._startDistance)) < ZOOM_THRESHOLD) return;
        this._active = true;
        return {
            zoomDelta: getZoomDelta(this._distance, lastDistance),
            pinchAround
        };
    }
}

/* ROTATE */

const ROTATION_THRESHOLD = 25; // pixels along circumference of touch circle

function getBearingDelta(a       , b       ) {
    return a.angleWith(b) * 180 / Math.PI;
}

class TouchRotateHandler extends TwoTouchHandler {
                         

    reset() {
        super.reset();
        this._minDiameter = 0;
        this._startVector = undefined;
        this._vector = undefined;
    }

    _start(points                ) {
        this._startVector = this._vector = points[0].sub(points[1]);
        this._minDiameter = points[0].dist(points[1]);
    }

    _move(points                , pinchAround        )                 {
        const lastVector = this._vector;
        this._vector = points[0].sub(points[1]);

        if (!lastVector || (!this._active && this._isBelowThreshold(this._vector))) return;
        this._active = true;

        return {
            // $FlowFixMe[incompatible-call] - Flow doesn't infer that this._vectoris not null
            bearingDelta: getBearingDelta(this._vector, lastVector),
            pinchAround
        };
    }

    _isBelowThreshold(vector       )          {
        /*
         * The threshold before a rotation actually happens is configured in
         * pixels alongth circumference of the circle formed by the two fingers.
         * This makes the threshold in degrees larger when the fingers are close
         * together and smaller when the fingers are far apart.
         *
         * Use the smallest diameter from the whole gesture to reduce sensitivity
         * when pinching in and out.
         */

        this._minDiameter = Math.min(this._minDiameter, vector.mag());
        const circumference = Math.PI * this._minDiameter;
        const threshold = ROTATION_THRESHOLD / circumference * 360;

        const startVector = this._startVector;
        if (!startVector) return false;

        const bearingDeltaSinceStart = getBearingDelta(vector, startVector);
        return Math.abs(bearingDeltaSinceStart) < threshold;
    }
}

/* PITCH */

function isVertical(vector       ) {
    return Math.abs(vector.y) > Math.abs(vector.x);
}

const ALLOWED_SINGLE_TOUCH_TIME = 100;

/**
 * The `TouchPitchHandler` allows the user to pitch the map by dragging up and down with two fingers.
 *
 * @see [Example: Set pitch and bearing](https://docs.mapbox.com/mapbox-gl-js/example/set-perspective/)
*/
class TouchPitchHandler extends TwoTouchHandler {

                           
                        
                                 
              

    constructor(map     ) {
        super();
        this._map = map;
    }

    reset() {
        super.reset();
        this._valid = undefined;
        this._firstMove = undefined;
        this._lastPoints = undefined;
    }

    _start(points                ) {
        this._lastPoints = points;
        if (isVertical(points[0].sub(points[1]))) {
            // fingers are more horizontal than vertical
            this._valid = false;
        }

    }

    _move(points                , center        , e            )                 {
        const lastPoints = this._lastPoints;
        if (!lastPoints) return;
        const vectorA = points[0].sub(lastPoints[0]);
        const vectorB = points[1].sub(lastPoints[1]);

        if (this._map._cooperativeGestures && !index.isFullscreen() && e.touches.length < 3) return;

        this._valid = this.gestureBeginsVertically(vectorA, vectorB, e.timeStamp);

        if (!this._valid) return;

        this._lastPoints = points;
        this._active = true;
        const yDeltaAverage = (vectorA.y + vectorB.y) / 2;
        const degreesPerPixelMoved = -0.5;
        return {
            pitchDelta: yDeltaAverage * degreesPerPixelMoved
        };
    }

    gestureBeginsVertically(vectorA       , vectorB       , timeStamp        )                 {
        if (this._valid !== undefined) return this._valid;

        const threshold = 2;
        const movedA = vectorA.mag() >= threshold;
        const movedB = vectorB.mag() >= threshold;

        // neither finger has moved a meaningful amount, wait
        if (!movedA && !movedB) return;

        // One finger has moved and the other has not.
        // If enough time has passed, decide it is not a pitch.
        if (!movedA || !movedB) {
            if (this._firstMove == null) {
                this._firstMove = timeStamp;
            }

            if (timeStamp - this._firstMove < ALLOWED_SINGLE_TOUCH_TIME) {
                // still waiting for a movement from the second finger
                return undefined;
            } else {
                return false;
            }
        }

        const isSameDirection = vectorA.y > 0 === vectorB.y > 0;
        return isVertical(vectorA) && isVertical(vectorB) && isSameDirection;
    }
}

//      

                                 
                                                         

const defaultOptions$5 = {
    panStep: 100,
    bearingStep: 15,
    pitchStep: 10
};

/**
 * The `KeyboardHandler` allows the user to zoom, rotate, and pan the map using
 * the following keyboard shortcuts:
 *
 * - `=` / `+`: Increase the zoom level by 1.
 * - `Shift-=` / `Shift-+`: Increase the zoom level by 2.
 * - `-`: Decrease the zoom level by 1.
 * - `Shift--`: Decrease the zoom level by 2.
 * - Arrow keys: Pan by 100 pixels.
 * - `Shift+⇢`: Increase the rotation by 15 degrees.
 * - `Shift+⇠`: Decrease the rotation by 15 degrees.
 * - `Shift+⇡`: Increase the pitch by 10 degrees.
 * - `Shift+⇣`: Decrease the pitch by 10 degrees.
 *
 * @see [Example: Toggle interactions](https://docs.mapbox.com/mapbox-gl-js/example/toggle-interaction-handlers/)
 * @see [Example: Navigate the map with game-like controls](https://docs.mapbox.com/mapbox-gl-js/example/game-controls/)
 * @see [Example: Display map navigation controls](https://docs.mapbox.com/mapbox-gl-js/example/navigation/)
 */
class KeyboardHandler {
                      
                     
                     
                         
                       
                               

    /**
    * @private
    */
    constructor() {
        const stepOptions = defaultOptions$5;
        this._panStep = stepOptions.panStep;
        this._bearingStep = stepOptions.bearingStep;
        this._pitchStep = stepOptions.pitchStep;
        this._rotationDisabled = false;
    }

    blur() {
        this.reset();
    }

    reset() {
        this._active = false;
    }

    keydown(e               )                 {
        if (e.altKey || e.ctrlKey || e.metaKey) return;

        let zoomDir = 0;
        let bearingDir = 0;
        let pitchDir = 0;
        let xDir = 0;
        let yDir = 0;

        switch (e.keyCode) {
        case 61:
        case 107:
        case 171:
        case 187:
            zoomDir = 1;
            break;

        case 189:
        case 109:
        case 173:
            zoomDir = -1;
            break;

        case 37:
            if (e.shiftKey) {
                bearingDir = -1;
            } else {
                e.preventDefault();
                xDir = -1;
            }
            break;

        case 39:
            if (e.shiftKey) {
                bearingDir = 1;
            } else {
                e.preventDefault();
                xDir = 1;
            }
            break;

        case 38:
            if (e.shiftKey) {
                pitchDir = 1;
            } else {
                e.preventDefault();
                yDir = -1;
            }
            break;

        case 40:
            if (e.shiftKey) {
                pitchDir = -1;
            } else {
                e.preventDefault();
                yDir = 1;
            }
            break;

        default:
            return;
        }

        if (this._rotationDisabled) {
            bearingDir = 0;
            pitchDir = 0;
        }

        return {
            cameraAnimation: (map     ) => {
                const zoom = map.getZoom();

                map.easeTo({
                    duration: 300,
                    easeId: 'keyboardHandler',
                    easing: easeOut,
                    zoom: zoomDir ? Math.round(zoom) + zoomDir * (e.shiftKey ? 2 : 1) : zoom,
                    bearing: map.getBearing() + bearingDir * this._bearingStep,
                    pitch: map.getPitch() + pitchDir * this._pitchStep,
                    offset: [-xDir * this._panStep, -yDir * this._panStep],
                    center: map.getCenter()
                }, {originalEvent: e});
            }
        };
    }

    /**
     * Enables the "keyboard rotate and zoom" interaction.
     *
     * @example
     * map.keyboard.enable();
     */
    enable() {
        this._enabled = true;
    }

    /**
     * Disables the "keyboard rotate and zoom" interaction.
     *
     * @example
     * map.keyboard.disable();
     */
    disable() {
        this._enabled = false;
        this.reset();
    }

    /**
     * Returns a Boolean indicating whether the "keyboard rotate and zoom"
     * interaction is enabled.
     *
     * @returns {boolean} `true` if the "keyboard rotate and zoom"
     * interaction is enabled.
     * @example
     * const isKeyboardEnabled = map.keyboard.isEnabled();
     */
    isEnabled()          {
        return this._enabled;
    }

    /**
     * Returns true if the handler is enabled and has detected the start of a
     * zoom/rotate gesture.
     *
     * @returns {boolean} `true` if the handler is enabled and has detected the
     * start of a zoom/rotate gesture.
     * @example
     * const isKeyboardActive = map.keyboard.isActive();
     */
    isActive()          {
        return this._active;
    }

    /**
     * Disables the "keyboard pan/rotate" interaction, leaving the
     * "keyboard zoom" interaction enabled.
     *
     * @example
     * map.keyboard.disableRotation();
     */
    disableRotation() {
        this._rotationDisabled = true;
    }

    /**
     * Enables the "keyboard pan/rotate" interaction.
     *
     * @example
     * map.keyboard.enable();
     * map.keyboard.enableRotation();
     */
    enableRotation() {
        this._rotationDisabled = false;
    }
}

function easeOut(t        ) {
    return t * (2 - t);
}

//      


// deltaY value for mouse scroll wheel identification
const wheelZoomDelta = 4.000244140625;

// These magic numbers control the rate of zoom. Trackpad events fire at a greater
// frequency than mouse scroll wheel, so reduce the zoom rate per wheel tick
const defaultZoomRate = 1 / 100;
const wheelZoomRate = 1 / 450;

// upper bound on how much we scale the map in any single render frame; this
// is used to limit zoom rate in the case of very fast scrolling
const maxScalePerFrame = 2;

/**
 * The `ScrollZoomHandler` allows the user to zoom the map by scrolling.
 *
 * @see [Example: Toggle interactions](https://docs.mapbox.com/mapbox-gl-js/example/toggle-interaction-handlers/)
 * @see [Example: Disable scroll zoom](https://docs.mapbox.com/mapbox-gl-js/example/disable-scroll-zoom/)
 */
class ScrollZoomHandler {
              
                     
                      
                     
                      
                           
                        
                                     
                                       
                       
                          // used for delayed-handling of a single wheel movement
                                // used to delay final '{move,zoom}end' events

                         
                                

                        
                         
                   
                                   
                                                                                 

                       
                             

                             
                           

                                  // used to display the scroll zoom blocker alert
                           

    /**
     * @private
     */
    constructor(map     , handler                ) {
        this._map = map;
        this._el = map.getCanvasContainer();
        this._handler = handler;

        this._delta = 0;

        this._defaultZoomRate = defaultZoomRate;
        this._wheelZoomRate = wheelZoomRate;

        index.bindAll(['_onTimeout', '_addScrollZoomBlocker', '_showBlockerAlert'], this);

    }

    /**
     * Sets the zoom rate of a trackpad.
     *
     * @param {number} [zoomRate=1/100] The rate used to scale trackpad movement to a zoom value.
     * @example
     * // Speed up trackpad zoom
     * map.scrollZoom.setZoomRate(1 / 25);
     */
    setZoomRate(zoomRate        ) {
        this._defaultZoomRate = zoomRate;
    }

    /**
    * Sets the zoom rate of a mouse wheel.
     *
    * @param {number} [wheelZoomRate=1/450] The rate used to scale mouse wheel movement to a zoom value.
    * @example
    * // Slow down zoom of mouse wheel
    * map.scrollZoom.setWheelZoomRate(1 / 600);
    */
    setWheelZoomRate(wheelZoomRate        ) {
        this._wheelZoomRate = wheelZoomRate;
    }

    /**
     * Returns a Boolean indicating whether the "scroll to zoom" interaction is enabled.
     *
     * @returns {boolean} `true` if the "scroll to zoom" interaction is enabled.
     * @example
     * const isScrollZoomEnabled = map.scrollZoom.isEnabled();
     */
    isEnabled()          {
        return !!this._enabled;
    }

    /*
    * Active state is turned on and off with every scroll wheel event and is set back to false before the map
    * render is called, so _active is not a good candidate for determining if a scroll zoom animation is in
    * progress.
    */
    isActive()          {
        return this._active || this._finishTimeout !== undefined;
    }

    isZooming()          {
        return !!this._zooming;
    }

    /**
     * Enables the "scroll to zoom" interaction.
     *
     * @param {Object} [options] Options object.
     * @param {string} [options.around] If "center" is passed, map will zoom around center of map.
     *
     * @example
     * map.scrollZoom.enable();
     * @example
     * map.scrollZoom.enable({around: 'center'});
     */
    enable(options                      ) {
        if (this.isEnabled()) return;
        this._enabled = true;
        this._aroundCenter = !!options && options.around === 'center';
        if (this._map._cooperativeGestures) this._addScrollZoomBlocker();
    }

    /**
     * Disables the "scroll to zoom" interaction.
     *
     * @example
     * map.scrollZoom.disable();
     */
    disable() {
        if (!this.isEnabled()) return;
        this._enabled = false;
        if (this._map._cooperativeGestures) {
            clearTimeout(this._alertTimer);
            this._alertContainer.remove();
        }
    }

    wheel(e            ) {
        if (!this.isEnabled()) return;

        if (this._map._cooperativeGestures) {
            if (!e.ctrlKey && !e.metaKey && !this.isZooming() && !index.isFullscreen()) {
                this._showBlockerAlert();
                return;
            } else if (this._alertContainer.style.visibility !== 'hidden') {
                // immediately hide alert if it is visible when ctrl or ⌘ is pressed while scroll zooming.
                this._alertContainer.style.visibility = 'hidden';
                clearTimeout(this._alertTimer);
            }
        }

        // Remove `any` cast when https://github.com/facebook/flow/issues/4879 is fixed.
        let value = e.deltaMode === (index.window.WheelEvent     ).DOM_DELTA_LINE ? e.deltaY * 40 : e.deltaY;
        const now = index.exported.now(),
            timeDelta = now - (this._lastWheelEventTime || 0);

        this._lastWheelEventTime = now;

        if (value !== 0 && (value % wheelZoomDelta) === 0) {
            // This one is definitely a mouse wheel event.
            this._type = 'wheel';

        } else if (value !== 0 && Math.abs(value) < 4) {
            // This one is definitely a trackpad event because it is so small.
            this._type = 'trackpad';

        } else if (timeDelta > 400) {
            // This is likely a new scroll action.
            this._type = null;
            this._lastValue = value;

            // Start a timeout in case this was a singular event, and delay it by up to 40ms.
            // $FlowFixMe[method-unbinding]
            this._timeout = setTimeout(this._onTimeout, 40, e);

        } else if (!this._type) {
            // This is a repeating event, but we don't know the type of event just yet.
            // If the delta per time is small, we assume it's a fast trackpad; otherwise we switch into wheel mode.
            this._type = (Math.abs(timeDelta * value) < 200) ? 'trackpad' : 'wheel';

            // Make sure our delayed event isn't fired again, because we accumulate
            // the previous event (which was less than 40ms ago) into this event.
            if (this._timeout) {
                clearTimeout(this._timeout);
                this._timeout = null;
                value += this._lastValue;
            }
        }

        // Slow down zoom if shift key is held for more precise zooming
        if (e.shiftKey && value) value = value / 4;

        // Only fire the callback if we actually know what type of scrolling device the user uses.
        if (this._type) {
            this._lastWheelEvent = e;
            this._delta -= value;
            if (!this._active) {
                this._start(e);
            }
        }

        e.preventDefault();
    }

    _onTimeout(initialEvent            ) {
        this._type = 'wheel';
        this._delta -= this._lastValue;
        if (!this._active) {
            this._start(initialEvent);
        }
    }

    _start(e            ) {
        if (!this._delta) return;

        if (this._frameId) {
            this._frameId = null;
        }

        this._active = true;
        if (!this.isZooming()) {
            this._zooming = true;
        }

        if (this._finishTimeout) {
            clearTimeout(this._finishTimeout);
            delete this._finishTimeout;
        }

        const pos = mousePos(this._el, e);
        this._aroundPoint = this._aroundCenter ? this._map.transform.centerPoint : pos;
        this._aroundCoord = this._map.transform.pointCoordinate3D(this._aroundPoint);
        this._targetZoom = undefined;

        if (!this._frameId) {
            this._frameId = true;
            this._handler._triggerRenderFrame();
        }
    }

    renderFrame()                 {
        if (!this._frameId) return;
        this._frameId = null;

        if (!this.isActive()) return;

        const tr = this._map.transform;

        // If projection wraps and center crosses the antimeridian, reset previous mouse scroll easing settings to resolve https://github.com/mapbox/mapbox-gl-js/issues/11910
        if (this._type === 'wheel' && tr.projection.wrap && (tr._center.lng >= 180 || tr._center.lng <= -180)) {
            this._prevEase = null;
            this._easing = null;
            this._lastWheelEvent = null;
            this._lastWheelEventTime = 0;
        }

        const startingZoom = () => {
            return (tr._terrainEnabled() && this._aroundCoord) ? tr.computeZoomRelativeTo(this._aroundCoord) : tr.zoom;
        };

        // if we've had scroll events since the last render frame, consume the
        // accumulated delta, and update the target zoom level accordingly
        if (this._delta !== 0) {
            // For trackpad events and single mouse wheel ticks, use the default zoom rate
            const zoomRate = (this._type === 'wheel' && Math.abs(this._delta) > wheelZoomDelta) ? this._wheelZoomRate : this._defaultZoomRate;
            // Scale by sigmoid of scroll wheel delta.
            let scale = maxScalePerFrame / (1 + Math.exp(-Math.abs(this._delta * zoomRate)));

            if (this._delta < 0 && scale !== 0) {
                scale = 1 / scale;
            }

            const startZoom = startingZoom();
            const startScale = Math.pow(2.0, startZoom);

            const fromScale = typeof this._targetZoom === 'number' ? tr.zoomScale(this._targetZoom) : startScale;
            this._targetZoom = Math.min(tr.maxZoom, Math.max(tr.minZoom, tr.scaleZoom(fromScale * scale)));

            // if this is a mouse wheel, refresh the starting zoom and easing
            // function we're using to smooth out the zooming between wheel
            // events
            if (this._type === 'wheel') {
                this._startZoom = startZoom;
                this._easing = this._smoothOutEasing(200);
            }

            this._delta = 0;
        }
        const targetZoom = typeof this._targetZoom === 'number' ?
            this._targetZoom : startingZoom();
        const startZoom = this._startZoom;
        const easing = this._easing;

        let finished = false;
        let zoom;
        if (this._type === 'wheel' && startZoom && easing) {
            index.assert(easing && typeof startZoom === 'number');

            const t = Math.min((index.exported.now() - this._lastWheelEventTime) / 200, 1);
            const k = easing(t);
            zoom = index.number(startZoom, targetZoom, k);
            if (t < 1) {
                if (!this._frameId) {
                    this._frameId = true;
                }
            } else {
                finished = true;
            }
        } else {
            zoom = targetZoom;
            finished = true;
        }

        this._active = true;

        if (finished) {
            this._active = false;
            this._finishTimeout = setTimeout(() => {
                this._zooming = false;
                this._handler._triggerRenderFrame();
                delete this._targetZoom;
                delete this._finishTimeout;
            }, 200);
        }

        return {
            noInertia: true,
            needsRenderFrame: !finished,
            zoomDelta: zoom - startingZoom(),
            around: this._aroundPoint,
            aroundCoord: this._aroundCoord,
            originalEvent: this._lastWheelEvent
        };
    }

    _smoothOutEasing(duration        )                     {
        let easing = index.ease;

        if (this._prevEase) {
            const ease = this._prevEase,
                t = (index.exported.now() - ease.start) / ease.duration,
                speed = ease.easing(t + 0.01) - ease.easing(t),

                // Quick hack to make new bezier that is continuous with last
                x = 0.27 / Math.sqrt(speed * speed + 0.0001) * 0.01,
                y = Math.sqrt(0.27 * 0.27 - x * x);

            easing = index.bezier(x, y, 0.25, 1);
        }

        this._prevEase = {
            start: index.exported.now(),
            duration,
            easing
        };

        return easing;
    }

    blur() {
        this.reset();
    }

    reset() {
        this._active = false;
    }

    _addScrollZoomBlocker() {
        if (this._map && !this._alertContainer) {
            this._alertContainer = create$1('div', 'mapboxgl-scroll-zoom-blocker', this._map._container);

            if (/(Mac|iPad)/i.test(index.window.navigator.userAgent)) {
                this._alertContainer.textContent = this._map._getUIString('ScrollZoomBlocker.CmdMessage');
            } else {
                this._alertContainer.textContent = this._map._getUIString('ScrollZoomBlocker.CtrlMessage');
            }

            // dynamically set the font size of the scroll zoom blocker alert message
            this._alertContainer.style.fontSize = `${Math.max(10, Math.min(24, Math.floor(this._el.clientWidth * 0.05)))}px`;
        }
    }

    _showBlockerAlert() {
        this._alertContainer.style.visibility = 'visible';
        this._alertContainer.classList.add('mapboxgl-scroll-zoom-blocker-show');
        this._alertContainer.setAttribute("role", "alert");

        clearTimeout(this._alertTimer);

        this._alertTimer = setTimeout(() => {
            this._alertContainer.classList.remove('mapboxgl-scroll-zoom-blocker-show');
            this._alertContainer.setAttribute("role", "null");
        }, 200);
    }

}

//      

                                                     
                                                   

/**
 * The `DoubleClickZoomHandler` allows the user to zoom the map at a point by
 * double clicking or double tapping.
 *
 * @see [Example: Toggle interactions](https://docs.mapbox.com/mapbox-gl-js/example/toggle-interaction-handlers/)
 */
class DoubleClickZoomHandler {

                                 
                             

    /**
     * @private
    */
    constructor(clickZoom                  , TapZoom                ) {
        this._clickZoom = clickZoom;
        this._tapZoom = TapZoom;
    }

    /**
     * Enables the "double click to zoom" interaction.
     *
     * @example
     * map.doubleClickZoom.enable();
     */
    enable() {
        this._clickZoom.enable();
        this._tapZoom.enable();
    }

    /**
     * Disables the "double click to zoom" interaction.
     *
     * @example
     * map.doubleClickZoom.disable();
     */
    disable() {
        this._clickZoom.disable();
        this._tapZoom.disable();
    }

    /**
     * Returns a Boolean indicating whether the "double click to zoom" interaction is enabled.
     *
     * @returns {boolean} Returns `true` if the "double click to zoom" interaction is enabled.
     * @example
     * const isDoubleClickZoomEnabled = map.doubleClickZoom.isEnabled();
     */
    isEnabled()          {
        return this._clickZoom.isEnabled() && this._tapZoom.isEnabled();
    }

    /**
     * Returns a Boolean indicating whether the "double click to zoom" interaction is active (currently being used).
     *
     * @returns {boolean} Returns `true` if the "double click to zoom" interaction is active.
     * @example
     * const isDoubleClickZoomActive = map.doubleClickZoom.isActive();
     */
    isActive()          {
        return this._clickZoom.isActive() || this._tapZoom.isActive();
    }
}

//      

                                                
                                 
                                                         

class ClickZoomHandler {

                      
                     

    constructor() {
        this.reset();
    }

    reset() {
        this._active = false;
    }

    blur() {
        this.reset();
    }

    dblclick(e            , point       )                {
        e.preventDefault();
        return {
            cameraAnimation: (map     ) => {
                map.easeTo({
                    duration: 300,
                    zoom: map.getZoom() + (e.shiftKey ? -1 : 1),
                    around: map.unproject(point)
                }, {originalEvent: e});
            }
        };
    }

    enable() {
        this._enabled = true;
    }

    disable() {
        this._enabled = false;
        this.reset();
    }

    isEnabled()          {
        return this._enabled;
    }

    isActive()          {
        return this._active;
    }
}

//      

                                                
                                                         

class TapDragZoomHandler {

                      
                     
                        
                        
                     
                        

    constructor() {

        this._tap = new TapRecognizer({
            numTouches: 1,
            numTaps: 1
        });

        this.reset();
    }

    reset() {
        this._active = false;
        this._swipePoint = undefined;
        this._swipeTouch = 0;
        this._tapTime = 0;
        this._tap.reset();
    }

    touchstart(e            , points              , mapTouches              ) {
        if (this._swipePoint) return;

        if (this._tapTime && e.timeStamp - this._tapTime > MAX_TAP_INTERVAL) {
            this.reset();
        }

        if (!this._tapTime) {
            this._tap.touchstart(e, points, mapTouches);
        } else if (mapTouches.length > 0) {
            this._swipePoint = points[0];
            this._swipeTouch = mapTouches[0].identifier;
        }

    }

    touchmove(e            , points              , mapTouches              )                 {
        if (!this._tapTime) {
            this._tap.touchmove(e, points, mapTouches);
        } else if (this._swipePoint) {
            if (mapTouches[0].identifier !== this._swipeTouch) {
                return;
            }

            const newSwipePoint = points[0];
            const dist = newSwipePoint.y - this._swipePoint.y;
            this._swipePoint = newSwipePoint;

            e.preventDefault();
            this._active = true;

            return {
                zoomDelta: dist / 128
            };
        }
    }

    touchend(e            , points              , mapTouches              ) {
        if (!this._tapTime) {
            const point = this._tap.touchend(e, points, mapTouches);
            if (point) {
                this._tapTime = e.timeStamp;
            }
        } else if (this._swipePoint) {
            if (mapTouches.length === 0) {
                this.reset();
            }
        }
    }

    touchcancel() {
        this.reset();
    }

    enable() {
        this._enabled = true;
    }

    disable() {
        this._enabled = false;
        this.reset();
    }

    isEnabled()          {
        return this._enabled;
    }

    isActive()          {
        return this._active;
    }
}

//      

                                                 
                                                     

                              
                       
                                   
                          
                      
  

/**
 * The `DragPanHandler` allows the user to pan the map by clicking and dragging
 * the cursor.
 *
 * @see [Example: Toggle interactions](https://docs.mapbox.com/mapbox-gl-js/example/toggle-interaction-handlers/)
 * @see [Example: Highlight features within a bounding box](https://docs.mapbox.com/mapbox-gl-js/example/using-box-queryrenderedfeatures/)
 */
class DragPanHandler {

                     
                               
                               
                                   

    /**
     * @private
    */
    constructor(el             , mousePan                 , touchPan                 ) {
        this._el = el;
        this._mousePan = mousePan;
        this._touchPan = touchPan;
    }

    /**
     * Enables the "drag to pan" interaction and accepts options to control the behavior of the panning inertia.
     *
     * @param {Object} [options] Options object.
     * @param {number} [options.linearity=0] Factor used to scale the drag velocity.
     * @param {Function} [options.easing] Optional easing function applied to {@link Map#panTo} when applying the drag. Defaults to bezier function using [@mapbox/unitbezier](https://github.com/mapbox/unitbezier).
     * @param {number} [options.maxSpeed=1400] The maximum value of the drag velocity.
     * @param {number} [options.deceleration=2500] The rate at which the speed reduces after the pan ends.
     *
     * @example
     * map.dragPan.enable();
     * @example
     * map.dragPan.enable({
     *     linearity: 0.3,
     *     easing: t => t,
     *     maxSpeed: 1400,
     *     deceleration: 2500
     * });
     * @see [Example: Highlight features within a bounding box](https://docs.mapbox.com/mapbox-gl-js/example/using-box-queryrenderedfeatures/)
     */
    enable(options                 ) {
        this._inertiaOptions = options || {};
        this._mousePan.enable();
        this._touchPan.enable();
        this._el.classList.add('mapboxgl-touch-drag-pan');
    }

    /**
     * Disables the "drag to pan" interaction.
     *
     * @example
     * map.dragPan.disable();
     */
    disable() {
        this._mousePan.disable();
        this._touchPan.disable();
        this._el.classList.remove('mapboxgl-touch-drag-pan');
    }

    /**
     * Returns a Boolean indicating whether the "drag to pan" interaction is enabled.
     *
     * @returns {boolean} Returns `true` if the "drag to pan" interaction is enabled.
     * @example
     * const isDragPanEnabled = map.dragPan.isEnabled();
     */
    isEnabled()          {
        return this._mousePan.isEnabled() && this._touchPan.isEnabled();
    }

    /**
     * Returns a Boolean indicating whether the "drag to pan" interaction is active (currently being used).
     *
     * @returns {boolean} Returns `true` if the "drag to pan" interaction is active.
     * @example
     * const isDragPanActive = map.dragPan.isActive();
     */
    isActive()          {
        return this._mousePan.isActive() || this._touchPan.isActive();
    }
}

//      

                                                                       

/**
 * The `DragRotateHandler` allows the user to rotate the map by clicking and
 * dragging the cursor while holding the right mouse button or `ctrl` key.
 *
 * @see [Example: Toggle interactions](https://docs.mapbox.com/mapbox-gl-js/example/toggle-interaction-handlers/)
 * @see [Example: Disable map rotation](https://docs.mapbox.com/mapbox-gl-js/example/disable-rotation/)
 */
class DragRotateHandler {

                                     
                                   
                              

    /**
     * @param {Object} [options]
     * @param {number} [options.bearingSnap] The threshold, measured in degrees, that determines when the map's
     *   bearing will snap to north.
     * @param {bool} [options.pitchWithRotate=true] Control the map pitch in addition to the bearing
     * @private
     */
    constructor(options                            , mouseRotate                    , mousePitch                   ) {
        this._pitchWithRotate = options.pitchWithRotate;
        this._mouseRotate = mouseRotate;
        this._mousePitch = mousePitch;
    }

    /**
     * Enables the "drag to rotate" interaction.
     *
     * @example
     * map.dragRotate.enable();
     */
    enable() {
        this._mouseRotate.enable();
        if (this._pitchWithRotate) this._mousePitch.enable();
    }

    /**
     * Disables the "drag to rotate" interaction.
     *
     * @example
     * map.dragRotate.disable();
     */
    disable() {
        this._mouseRotate.disable();
        this._mousePitch.disable();
    }

    /**
     * Returns a Boolean indicating whether the "drag to rotate" interaction is enabled.
     *
     * @returns {boolean} `true` if the "drag to rotate" interaction is enabled.
     * @example
     * const isDragRotateEnabled = map.dragRotate.isEnabled();
     */
    isEnabled()          {
        return this._mouseRotate.isEnabled() && (!this._pitchWithRotate || this._mousePitch.isEnabled());
    }

    /**
     * Returns a Boolean indicating whether the "drag to rotate" interaction is active (currently being used).
     *
     * @returns {boolean} Returns `true` if the "drag to rotate" interaction is active.
     * @example
     * const isDragRotateActive = map.dragRotate.isActive();
     */
    isActive()          {
        return this._mouseRotate.isActive() || this._mousePitch.isActive();
    }
}

//      

                                                                                  
                                                          

/**
 * The `TouchZoomRotateHandler` allows the user to zoom and rotate the map by
 * pinching on a touchscreen.
 *
 * They can zoom with one finger by double tapping and dragging. On the second tap,
 * hold the finger down and drag up or down to zoom in or out.
 *
 * @see [Example: Toggle interactions](https://docs.mapbox.com/mapbox-gl-js/example/toggle-interaction-handlers/)
 */
class TouchZoomRotateHandler {

                     
                                 
                                     
                                     
                               
                      

    /**
     * @private
    */
    constructor(el             , touchZoom                  , touchRotate                    , tapDragZoom                    ) {
        this._el = el;
        this._touchZoom = touchZoom;
        this._touchRotate = touchRotate;
        this._tapDragZoom = tapDragZoom;
        this._rotationDisabled = false;
        this._enabled = true;
    }

    /**
     * Enables the "pinch to rotate and zoom" interaction.
     *
     * @param {Object} [options] Options object.
     * @param {string} [options.around] If "center" is passed, map will zoom around the center.
     *
     * @example
     * map.touchZoomRotate.enable();
     * @example
     * map.touchZoomRotate.enable({around: 'center'});
     */
    enable(options                      ) {
        this._touchZoom.enable(options);
        if (!this._rotationDisabled) this._touchRotate.enable(options);
        this._tapDragZoom.enable();
        this._el.classList.add('mapboxgl-touch-zoom-rotate');
    }

    /**
     * Disables the "pinch to rotate and zoom" interaction.
     *
     * @example
     * map.touchZoomRotate.disable();
     */
    disable() {
        this._touchZoom.disable();
        this._touchRotate.disable();
        this._tapDragZoom.disable();
        this._el.classList.remove('mapboxgl-touch-zoom-rotate');
    }

    /**
     * Returns a Boolean indicating whether the "pinch to rotate and zoom" interaction is enabled.
     *
     * @returns {boolean} `true` if the "pinch to rotate and zoom" interaction is enabled.
     * @example
     * const isTouchZoomRotateEnabled = map.touchZoomRotate.isEnabled();
     */
    isEnabled()          {
        return this._touchZoom.isEnabled() &&
            (this._rotationDisabled || this._touchRotate.isEnabled()) &&
            this._tapDragZoom.isEnabled();
    }

    /**
     * Returns true if the handler is enabled and has detected the start of a zoom/rotate gesture.
     *
     * @returns {boolean} `true` if enabled and a zoom/rotate gesture was detected.
     * @example
     * const isTouchZoomRotateActive = map.touchZoomRotate.isActive();
     */
    isActive()          {
        return this._touchZoom.isActive() || this._touchRotate.isActive() || this._tapDragZoom.isActive();
    }

    /**
     * Disables the "pinch to rotate" interaction, leaving the "pinch to zoom"
     * interaction enabled.
     *
     * @example
     * map.touchZoomRotate.disableRotation();
     */
    disableRotation() {
        this._rotationDisabled = true;
        this._touchRotate.disable();
    }

    /**
     * Enables the "pinch to rotate" interaction.
     *
     * @example
     * map.touchZoomRotate.enable();
     * map.touchZoomRotate.enableRotation();
     */
    enableRotation() {
        this._rotationDisabled = false;
        if (this._touchZoom.isEnabled()) this._touchRotate.enable();
    }
}

//      


                                    

                                                                              

const isMoving = (p                   ) => p.zoom || p.drag || p.pitch || p.rotate;

class RenderFrameEvent extends index.Event {
                        
                      
}

class TrackingEllipsoid {
                             
                   

    constructor() {
        // a, b, c in the equation x²/a² + y²/b² + z²/c² = 1
        this.constants = [1, 1, 0.01];
        this.radius = 0;
    }

    setup(center      , pointOnSurface      ) {
        const centerToSurface = index.sub([], pointOnSurface, center);
        if (centerToSurface[2] < 0) {
            this.radius = index.length(index.div([], centerToSurface, this.constants));
        } else {
            // The point on surface is above the center. This can happen for example when the camera is
            // below the clicked point (like a mountain) Use slightly shorter radius for less aggressive movement
            this.radius = index.length([centerToSurface[0], centerToSurface[1], 0]);
        }
    }

    // Cast a ray from the center of the ellipsoid and the intersection point.
    projectRay(dir      )       {
        // Perform the intersection test against a unit sphere
        index.div(dir, dir, this.constants);
        index.normalize(dir, dir);
        index.mul$1(dir, dir, this.constants);

        const intersection = index.scale$3([], dir, this.radius);

        if (intersection[2] > 0) {
            // The intersection point is above horizon so special handling is required.
            // Otherwise direction of the movement would be inverted due to the ellipsoid shape
            const h = index.scale$3([], [0, 0, 1], index.dot(intersection, [0, 0, 1]));
            const r = index.scale$3([], index.normalize([], [intersection[0], intersection[1], 0]), this.radius);
            const p = index.add([], intersection, index.scale$3([], index.sub([], index.add([], r, h), intersection), 2));

            intersection[0] = p[0];
            intersection[1] = p[1];
        }

        return intersection;
    }
}

// Handlers interpret dom events and return camera changes that should be
// applied to the map (`HandlerResult`s). The camera changes are all deltas.
// The handler itself should have no knowledge of the map's current state.
// This makes it easier to merge multiple results and keeps handlers simpler.
// For example, if there is a mousedown and mousemove, the mousePan handler
// would return a `panDelta` on the mousemove.
                          
                   
                    
                         
                        

                                                                                                        
                  

                                                       
                                                                             
                                                                                                    
                                                                                                   
                                                                                                  
                                                                                                     
                                                                 
                                                                 
                                                               
                                                                
                                                             
                                                    
                                                  

                                                                          
                                                                            
                                        
 

// All handler methods that are called with events can optionally return a `HandlerResult`.
                             
                     
                       
                          
                        
                                                     
                          
                                                                               
                               
                                                                             
                                            
                                                                                     
                                        

                                                                            
                                                                                   
                        
                                                                                                                     
                               
                                                                  
                       
  

function hasChange(result               ) {
    return (result.panDelta && result.panDelta.mag()) || result.zoomDelta || result.bearingDelta || result.pitchDelta;
}

class HandlerManager {
              
                     
                                                                              
                              
                      
                             
                         
                                         
                             
                                                  
                                                   
                                                                                      
                                          
                       

    constructor(map     , options                                                                                                ) {
        this._map = map;
        this._el = this._map.getCanvasContainer();
        this._handlers = [];
        this._handlersById = {};
        this._changes = [];

        this._inertia = new HandlerInertia(map);
        this._bearingSnap = options.bearingSnap;
        this._previousActiveHandlers = {};
        this._trackingEllipsoid = new TrackingEllipsoid();
        this._dragOrigin = null;

        // Track whether map is currently moving, to compute start/move/end events
        this._eventsInProgress = {};

        this._addDefaultHandlers(options);

        index.bindAll(['handleEvent', 'handleWindowEvent'], this);

        const el = this._el;

        this._listeners = [
            // This needs to be `passive: true` so that a double tap fires two
            // pairs of touchstart/end events in iOS Safari 13. If this is set to
            // `passive: false` then the second pair of events is only fired if
            // preventDefault() is called on the first touchstart. Calling preventDefault()
            // undesirably prevents click events.
            [el, 'touchstart', {passive: true}],
            // This needs to be `passive: false` so that scrolls and pinches can be
            // prevented in browsers that don't support `touch-actions: none`, for example iOS Safari 12.
            [el, 'touchmove', {passive: false}],
            [el, 'touchend', undefined],
            [el, 'touchcancel', undefined],

            [el, 'mousedown', undefined],
            [el, 'mousemove', undefined],
            [el, 'mouseup', undefined],

            // Bind window-level event listeners for move and up/end events. In the absence of
            // the pointer capture API, which is not supported by all necessary platforms,
            // window-level event listeners give us the best shot at capturing events that
            // fall outside the map canvas element. Use `{capture: true}` for the move event
            // to prevent map move events from being fired during a drag.
            [index.window.document, 'mousemove', {capture: true}],
            [index.window.document, 'mouseup', undefined],

            [el, 'mouseover', undefined],
            [el, 'mouseout', undefined],
            [el, 'dblclick', undefined],
            [el, 'click', undefined],

            [el, 'keydown', {capture: false}],
            [el, 'keyup', undefined],

            [el, 'wheel', {passive: false}],
            [el, 'contextmenu', undefined],

            [index.window, 'blur', undefined]
        ];

        for (const [target, type, listenerOptions] of this._listeners) {
            // $FlowFixMe[method-unbinding]
            const listener = target === index.window.document ? this.handleWindowEvent : this.handleEvent;
            target.addEventListener((type     ), (listener     ), listenerOptions);
        }
    }

    destroy() {
        for (const [target, type, listenerOptions] of this._listeners) {
            // $FlowFixMe[method-unbinding]
            const listener = target === index.window.document ? this.handleWindowEvent : this.handleEvent;
            target.removeEventListener((type     ), (listener     ), listenerOptions);
        }
    }

    _addDefaultHandlers(options                                                                            ) {
        const map = this._map;
        const el = map.getCanvasContainer();
        // $FlowFixMe[method-unbinding]
        this._add('mapEvent', new MapEventHandler(map, options));

        const boxZoom = map.boxZoom = new BoxZoomHandler(map, options);
        // $FlowFixMe[method-unbinding]
        this._add('boxZoom', boxZoom);

        const tapZoom = new TapZoomHandler();
        const clickZoom = new ClickZoomHandler();
        map.doubleClickZoom = new DoubleClickZoomHandler(clickZoom, tapZoom);
        // $FlowFixMe[method-unbinding]
        this._add('tapZoom', tapZoom);
        // $FlowFixMe[method-unbinding]
        this._add('clickZoom', clickZoom);

        const tapDragZoom = new TapDragZoomHandler();
        // $FlowFixMe[method-unbinding]
        this._add('tapDragZoom', tapDragZoom);

        const touchPitch = map.touchPitch = new TouchPitchHandler(map);
        // $FlowFixMe[method-unbinding]
        this._add('touchPitch', touchPitch);

        const mouseRotate = new MouseRotateHandler(options);
        const mousePitch = new MousePitchHandler(options);
        map.dragRotate = new DragRotateHandler(options, mouseRotate, mousePitch);
        // $FlowFixMe[method-unbinding]
        this._add('mouseRotate', mouseRotate, ['mousePitch']);
        // $FlowFixMe[method-unbinding]
        this._add('mousePitch', mousePitch, ['mouseRotate']);

        const mousePan = new MousePanHandler(options);
        const touchPan = new TouchPanHandler(map, options);
        map.dragPan = new DragPanHandler(el, mousePan, touchPan);
        // $FlowFixMe[method-unbinding]
        this._add('mousePan', mousePan);
        // $FlowFixMe[method-unbinding]
        this._add('touchPan', touchPan, ['touchZoom', 'touchRotate']);

        const touchRotate = new TouchRotateHandler();
        const touchZoom = new TouchZoomHandler();
        map.touchZoomRotate = new TouchZoomRotateHandler(el, touchZoom, touchRotate, tapDragZoom);
        // $FlowFixMe[method-unbinding]
        this._add('touchRotate', touchRotate, ['touchPan', 'touchZoom']);
        // $FlowFixMe[method-unbinding]
        this._add('touchZoom', touchZoom, ['touchPan', 'touchRotate']);

        // $FlowFixMe[method-unbinding]
        this._add('blockableMapEvent', new BlockableMapEventHandler(map));

        const scrollZoom = map.scrollZoom = new ScrollZoomHandler(map, this);
        // $FlowFixMe[method-unbinding]
        this._add('scrollZoom', scrollZoom, ['mousePan']);

        const keyboard = map.keyboard = new KeyboardHandler();
        // $FlowFixMe[method-unbinding]
        this._add('keyboard', keyboard);

        for (const name of ['boxZoom', 'doubleClickZoom', 'tapDragZoom', 'touchPitch', 'dragRotate', 'dragPan', 'touchZoomRotate', 'scrollZoom', 'keyboard']) {
            if (options.interactive && (options     )[name]) {
                (map     )[name].enable((options     )[name]);
            }
        }
    }

    _add(handlerName        , handler         , allowed                ) {
        this._handlers.push({handlerName, handler, allowed});
        this._handlersById[handlerName] = handler;
    }

    stop(allowEndAnimation         ) {
        // do nothing if this method was triggered by a gesture update
        if (this._updatingCamera) return;

        for (const {handler} of this._handlers) {
            handler.reset();
        }
        this._inertia.clear();
        this._fireEvents({}, {}, allowEndAnimation);
        this._changes = [];
    }

    isActive()          {
        for (const {handler} of this._handlers) {
            if (handler.isActive()) return true;
        }
        return false;
    }

    isZooming()          {
        return !!this._eventsInProgress.zoom || this._map.scrollZoom.isZooming();
    }

    isRotating()          {
        return !!this._eventsInProgress.rotate;
    }

    isMoving()          {
        return !!isMoving(this._eventsInProgress) || this.isZooming();
    }

    _isDragging()          {
        return !!this._eventsInProgress.drag;
    }

    _blockedByActive(activeHandlers                       , allowed               , myName        )          {
        for (const name in activeHandlers) {
            if (name === myName) continue;
            if (!allowed || allowed.indexOf(name) < 0) {
                return true;
            }
        }
        return false;
    }

    handleWindowEvent(e            ) {
        this.handleEvent(e, `${e.type}Window`);
    }

    _getMapTouches(touches           )            {
        const mapTouches = [];
        for (const t of touches) {
            const target = ((t.target     )      );
            if (this._el.contains(target)) {
                mapTouches.push(t);
            }
        }
        return ((mapTouches     )           );
    }

    handleEvent(e                               , eventName         ) {

        this._updatingCamera = true;
        index.assert(e.timeStamp !== undefined);

        const isRenderFrame = e.type === 'renderFrame';
        const inputEvent = isRenderFrame ? undefined : ((e     )            );

        /*
         * We don't call e.preventDefault() for any events by default.
         * Handlers are responsible for calling it where necessary.
         */

        const mergedHandlerResult                = {needsRenderFrame: false};
        const eventsInProgress = {};
        const activeHandlers = {};

        const mapTouches = e.touches ? this._getMapTouches(((e     )            ).touches) : undefined;
        const points = mapTouches ? touchPos(this._el, mapTouches) :
            isRenderFrame ? undefined : // renderFrame event doesn't have any points
            mousePos(this._el, ((e     )            ));

        for (const {handlerName, handler, allowed} of this._handlers) {
            if (!handler.isEnabled()) continue;

            let data                ;
            if (this._blockedByActive(activeHandlers, allowed, handlerName)) {
                handler.reset();

            } else {
                if ((handler     )[eventName || e.type]) {
                    data = (handler     )[eventName || e.type](e, points, mapTouches);
                    this.mergeHandlerResult(mergedHandlerResult, eventsInProgress, data, handlerName, inputEvent);
                    if (data && data.needsRenderFrame) {
                        this._triggerRenderFrame();
                    }
                }
            }

            if (data || handler.isActive()) {
                activeHandlers[handlerName] = handler;
            }
        }

        const deactivatedHandlers = {};
        for (const name in this._previousActiveHandlers) {
            if (!activeHandlers[name]) {
                deactivatedHandlers[name] = inputEvent;
            }
        }
        this._previousActiveHandlers = activeHandlers;

        if (Object.keys(deactivatedHandlers).length || hasChange(mergedHandlerResult)) {
            this._changes.push([mergedHandlerResult, eventsInProgress, deactivatedHandlers]);
            this._triggerRenderFrame();
        }

        if (Object.keys(activeHandlers).length || hasChange(mergedHandlerResult)) {
            this._map._stop(true);
        }

        this._updatingCamera = false;

        const {cameraAnimation} = mergedHandlerResult;
        if (cameraAnimation) {
            this._inertia.clear();
            this._fireEvents({}, {}, true);
            this._changes = [];
            cameraAnimation(this._map);
        }
    }

    mergeHandlerResult(mergedHandlerResult               , eventsInProgress        , handlerResult               , name        , e             ) {
        if (!handlerResult) return;

        index.extend(mergedHandlerResult, handlerResult);

        const eventData = {handlerName: name, originalEvent: handlerResult.originalEvent || e};

        // track which handler changed which camera property
        if (handlerResult.zoomDelta !== undefined) {
            eventsInProgress.zoom = eventData;
        }
        if (handlerResult.panDelta !== undefined) {
            eventsInProgress.drag = eventData;
        }
        if (handlerResult.pitchDelta !== undefined) {
            eventsInProgress.pitch = eventData;
        }
        if (handlerResult.bearingDelta !== undefined) {
            eventsInProgress.rotate = eventData;
        }
    }

    _applyChanges() {
        const combined = {};
        const combinedEventsInProgress = {};
        const combinedDeactivatedHandlers = {};

        for (const [change, eventsInProgress, deactivatedHandlers] of this._changes) {

            if (change.panDelta) combined.panDelta = (combined.panDelta || new index.Point(0, 0))._add(change.panDelta);
            if (change.zoomDelta) combined.zoomDelta = (combined.zoomDelta || 0) + change.zoomDelta;
            if (change.bearingDelta) combined.bearingDelta = (combined.bearingDelta || 0) + change.bearingDelta;
            if (change.pitchDelta) combined.pitchDelta = (combined.pitchDelta || 0) + change.pitchDelta;
            if (change.around !== undefined) combined.around = change.around;
            if (change.aroundCoord !== undefined) combined.aroundCoord = change.aroundCoord;
            if (change.pinchAround !== undefined) combined.pinchAround = change.pinchAround;
            if (change.noInertia) combined.noInertia = change.noInertia;

            index.extend(combinedEventsInProgress, eventsInProgress);
            index.extend(combinedDeactivatedHandlers, deactivatedHandlers);
        }

        this._updateMapTransform(combined, combinedEventsInProgress, combinedDeactivatedHandlers);
        this._changes = [];
    }

    _updateMapTransform(combinedResult     , combinedEventsInProgress        , deactivatedHandlers        ) {

        const map = this._map;
        const tr = map.transform;

        const eventStarted = (type        ) => {
            const newEvent = combinedEventsInProgress[type];
            return newEvent && !this._eventsInProgress[type];
        };

        const eventEnded = (type        ) => {
            const event = this._eventsInProgress[type];
            return event && !this._handlersById[event.handlerName].isActive();
        };

        const toVec3 = (p                    )       => [p.x, p.y, p.z];

        if (eventEnded("drag") && !hasChange(combinedResult)) {
            const preZoom = tr.zoom;
            tr.cameraElevationReference = "sea";
            tr.recenterOnTerrain();
            tr.cameraElevationReference = "ground";
            // Map zoom might change during the pan operation due to terrain elevation.
            if (preZoom !== tr.zoom) this._map._update(true);
        }

        // Catches double click and double tap zooms when camera is constrained over terrain
        if (tr._isCameraConstrained) map._stop(true);

        if (!hasChange(combinedResult)) {
            this._fireEvents(combinedEventsInProgress, deactivatedHandlers, true);
            return;
        }

        let {panDelta, zoomDelta, bearingDelta, pitchDelta, around, aroundCoord, pinchAround} = combinedResult;

        if (tr._isCameraConstrained) {
            // Catches wheel zoom events when camera is constrained over terrain
            if (zoomDelta > 0) zoomDelta = 0;
            tr._isCameraConstrained = false;
        }

        if (pinchAround !== undefined) {
            around = pinchAround;
        }

        if ((zoomDelta || eventStarted("drag")) && around) {
            this._dragOrigin = toVec3(tr.pointCoordinate3D(around));
            // Construct the tracking ellipsoid every time user changes the zoom or drag origin.
            // Direction of the ray will define size of the shape and hence defining the available range of movement
            this._trackingEllipsoid.setup(tr._camera.position, this._dragOrigin);
        }

        // All movement of the camera is done relative to the sea level
        tr.cameraElevationReference = "sea";

        // stop any ongoing camera animations (easeTo, flyTo)
        map._stop(true);

        around = around || map.transform.centerPoint;
        if (bearingDelta) tr.bearing += bearingDelta;
        if (pitchDelta) tr.pitch += pitchDelta;
        tr._updateCameraState();

        // Compute Mercator 3D camera offset based on screenspace panDelta
        const panVec = [0, 0, 0];
        if (panDelta) {
            if (tr.projection.name === 'mercator') {
                index.assert(this._dragOrigin, '_dragOrigin should have been setup with a previous dragstart');
                const startPoint = this._trackingEllipsoid.projectRay(tr.screenPointToMercatorRay(around).dir);
                const endPoint = this._trackingEllipsoid.projectRay(tr.screenPointToMercatorRay(around.sub(panDelta)).dir);
                panVec[0] = endPoint[0] - startPoint[0];
                panVec[1] = endPoint[1] - startPoint[1];

            } else {
                const startPoint = tr.pointCoordinate(around);
                if (tr.projection.name === 'globe') {
                    // Compute pan vector directly in pixel coordinates for the globe.
                    // Rotate the globe a bit faster when dragging near poles to compensate
                    // different pixel-per-meter ratios (ie. pixel-to-physical-rotation is lower)
                    panDelta = panDelta.rotate(-tr.angle);
                    const scale = tr._pixelsPerMercatorPixel / tr.worldSize;
                    panVec[0] = -panDelta.x * index.mercatorScale(index.latFromMercatorY(startPoint.y)) * scale;
                    panVec[1] = -panDelta.y * index.mercatorScale(tr.center.lat) * scale;

                } else {
                    const endPoint = tr.pointCoordinate(around.sub(panDelta));

                    if (startPoint && endPoint) {
                        panVec[0] = endPoint.x - startPoint.x;
                        panVec[1] = endPoint.y - startPoint.y;
                    }
                }
            }
        }

        const originalZoom = tr.zoom;
        // Compute Mercator 3D camera offset based on screenspace requested ZoomDelta
        const zoomVec = [0, 0, 0];
        if (zoomDelta) {
            // Zoom value has to be computed relative to a secondary map plane that is created from the terrain position below the cursor.
            // This way the zoom interpolation can be kept linear and independent of the (possible) terrain elevation
            const pickedPosition       = aroundCoord ? toVec3(aroundCoord) : toVec3(tr.pointCoordinate3D(around));

            const aroundRay = {dir: index.normalize([], index.sub([], pickedPosition, tr._camera.position))};
            if (aroundRay.dir[2] < 0) {
                // Special handling is required if the ray created from the cursor is heading up.
                // This scenario is possible if user is trying to zoom towards a feature like a hill or a mountain.
                // Convert zoomDelta to a movement vector as if the camera would be orbiting around the picked point
                const movement = tr.zoomDeltaToMovement(pickedPosition, zoomDelta);
                index.scale$3(zoomVec, aroundRay.dir, movement);
            }
        }

        // Mutate camera state via CameraAPI
        const translation = index.add(panVec, panVec, zoomVec);
        tr._translateCameraConstrained(translation);

        if (zoomDelta && Math.abs(tr.zoom - originalZoom) > 0.0001) {
            tr.recenterOnTerrain();
        }

        tr.cameraElevationReference = "ground";

        this._map._update();
        if (!combinedResult.noInertia) this._inertia.record(combinedResult);
        this._fireEvents(combinedEventsInProgress, deactivatedHandlers, true);
    }

    _fireEvents(newEventsInProgress                      , deactivatedHandlers        , allowEndAnimation         ) {

        const wasMoving = isMoving(this._eventsInProgress);
        const nowMoving = isMoving(newEventsInProgress);

        const startEvents = {};

        for (const eventName in newEventsInProgress) {
            const {originalEvent} = newEventsInProgress[eventName];
            if (!this._eventsInProgress[eventName]) {
                startEvents[`${eventName}start`] = originalEvent;
            }
            this._eventsInProgress[eventName] = newEventsInProgress[eventName];
        }

        // fire start events only after this._eventsInProgress has been updated
        if (!wasMoving && nowMoving) {
            this._fireEvent('movestart', nowMoving.originalEvent);
        }

        for (const name in startEvents) {
            this._fireEvent(name, startEvents[name]);
        }

        if (nowMoving) {
            this._fireEvent('move', nowMoving.originalEvent);
        }

        for (const eventName in newEventsInProgress) {
            const {originalEvent} = newEventsInProgress[eventName];
            this._fireEvent(eventName, originalEvent);
        }

        const endEvents = {};

        let originalEndEvent;
        for (const eventName in this._eventsInProgress) {
            const {handlerName, originalEvent} = this._eventsInProgress[eventName];
            if (!this._handlersById[handlerName].isActive()) {
                delete this._eventsInProgress[eventName];
                originalEndEvent = deactivatedHandlers[handlerName] || originalEvent;
                endEvents[`${eventName}end`] = originalEndEvent;
            }
        }

        for (const name in endEvents) {
            this._fireEvent(name, endEvents[name]);
        }

        const stillMoving = isMoving(this._eventsInProgress);
        if (allowEndAnimation && (wasMoving || nowMoving) && !stillMoving) {
            this._updatingCamera = true;
            const inertialEase = this._inertia._onMoveEnd(this._map.dragPan._inertiaOptions);

            const shouldSnapToNorth = (bearing        ) => bearing !== 0 && -this._bearingSnap < bearing && bearing < this._bearingSnap;

            if (inertialEase) {
                if (shouldSnapToNorth(inertialEase.bearing || this._map.getBearing())) {
                    inertialEase.bearing = 0;
                }
                this._map.easeTo(inertialEase, {originalEvent: originalEndEvent});
            } else {
                this._map.fire(new index.Event('moveend', {originalEvent: originalEndEvent}));
                if (shouldSnapToNorth(this._map.getBearing())) {
                    this._map.resetNorth();
                }
            }
            this._updatingCamera = false;
        }

    }

    _fireEvent(type        , e     ) {
        this._map.fire(new index.Event(type, e ? {originalEvent: e} : {}));
    }

    _requestFrame()         {
        this._map.triggerRepaint();
        return this._map._renderTaskQueue.add(timeStamp => {
            this._frameId = undefined;
            this.handleEvent(new RenderFrameEvent('renderFrame', {timeStamp}));
            this._applyChanges();
        });
    }

    _triggerRenderFrame() {
        if (this._frameId === undefined) {
            this._frameId = this._requestFrame();
        }
    }
}

//      

                                                          
                                          

/**
 * A helper type: converts all Object type values to non-maybe types.
 */
                                                             

/**
 * Options common to {@link Map#jumpTo}, {@link Map#easeTo}, and {@link Map#flyTo}, controlling the desired location,
 * zoom, bearing, and pitch of the camera. All properties are optional, and when a property is omitted, the current
 * camera value for that property will remain unchanged.
 *
 * @typedef {Object} CameraOptions
 * @property {LngLatLike} center The location to place at the screen center.
 * @property {number} zoom The desired zoom level.
 * @property {number} bearing The desired bearing in degrees. The bearing is the compass direction that
 * is "up". For example, `bearing: 90` orients the map so that east is up.
 * @property {number} pitch The desired pitch in degrees. The pitch is the angle towards the horizon
 * measured in degrees with a range between 0 and 85 degrees. For example, pitch: 0 provides the appearance
 * of looking straight down at the map, while pitch: 60 tilts the user's perspective towards the horizon.
 * Increasing the pitch value is often used to display 3D objects.
 * @property {LngLatLike} around The location serving as the origin for a change in `zoom`, `pitch` and/or `bearing`.
 * This location will remain at the same screen position following the transform.
 * This is useful for drawing attention to a location that is not in the screen center.
 * `center` is ignored if `around` is included.
 * @property {PaddingOptions} padding Dimensions in pixels applied on each side of the viewport for shifting the vanishing point.
 * @example
 * // set the map's initial perspective with CameraOptions
 * const map = new mapboxgl.Map({
 *     container: 'map',
 *     style: 'mapbox://styles/mapbox/streets-v11',
 *     center: [-73.5804, 45.53483],
 *     pitch: 60,
 *     bearing: -60,
 *     zoom: 10
 * });
 * @see [Example: Set pitch and bearing](https://docs.mapbox.com/mapbox-gl-js/example/set-perspective/)
 * @see [Example: Jump to a series of locations](https://docs.mapbox.com/mapbox-gl-js/example/jump-to/)
 * @see [Example: Fly to a location](https://docs.mapbox.com/mapbox-gl-js/example/flyto/)
 * @see [Example: Display buildings in 3D](https://docs.mapbox.com/mapbox-gl-js/example/3d-buildings/)
 */
                             
                        
                  
                     
                   
                        
                            
  

                                 
                    
                      
                                     
                 

/**
 * Options common to map movement methods that involve animation, such as {@link Map#panBy} and
 * {@link Map#easeTo}, controlling the duration and easing function of the animation. All properties
 * are optional.
 *
 * @typedef {Object} AnimationOptions
 * @property {number} duration The animation's duration, measured in milliseconds.
 * @property {Function} easing A function taking a time in the range 0..1 and returning a number where 0 is
 *   the initial state and 1 is the final state.
 * @property {PointLike} offset The target center's offset relative to real map container center at the end of animation.
 * @property {boolean} animate If `false`, no animation will occur.
 * @property {boolean} essential If `true`, then the animation is considered essential and will not be affected by
 *   [`prefers-reduced-motion`](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion).
 * @property {boolean} preloadOnly If `true`, it will trigger tiles loading across the animation path, but no animation will occur.
 * @property {number} curve The zooming "curve" that will occur along the
 *     flight path. A high value maximizes zooming for an exaggerated animation, while a low
 *     value minimizes zooming for an effect closer to {@link Map#easeTo}. 1.42 is the average
 *     value selected by participants in the user study discussed in
 *     [van Wijk (2003)](https://www.win.tue.nl/~vanwijk/zoompan.pdf). A value of
 *     `Math.pow(6, 0.25)` would be equivalent to the root mean squared average velocity. A
 *     value of 1 would produce a circular motion. If `minZoom` is specified, this option will be ignored.
 * @property {number} minZoom The zero-based zoom level at the peak of the flight path. If
 *     this option is specified, `curve` will be ignored.
 * @property {number} speed The average speed of the animation defined in relation to
 *     `curve`. A speed of 1.2 means that the map appears to move along the flight path
 *     by 1.2 times `curve` screenfuls every second. A _screenful_ is the map's visible span.
 *     It does not correspond to a fixed physical distance, but varies by zoom level.
 * @property {number} screenSpeed The average speed of the animation measured in screenfuls
 *     per second, assuming a linear timing curve. If `speed` is specified, this option is ignored.
 * @property {number} maxDuration The animation's maximum duration, measured in milliseconds.
 *     If duration exceeds maximum duration, it resets to 0.
 * @see [Example: Slowly fly to a location](https://docs.mapbox.com/mapbox-gl-js/example/flyto-options/)
 * @see [Example: Customize camera animations](https://docs.mapbox.com/mapbox-gl-js/example/camera-animation/)
 * @see [Example: Navigate the map with game-like controls](https://docs.mapbox.com/mapbox-gl-js/example/game-controls/)
*/
                                
                      
                                   
                       
                      
                        
                         
  

                                                             

                                   
                      
                      
                        
                       
  

const freeCameraNotSupportedWarning = 'map.setFreeCameraOptions(...) and map.getFreeCameraOptions() are not yet supported for non-mercator projections.';

/**
 * Options for setting padding on calls to methods such as {@link Map#fitBounds}, {@link Map#fitScreenCoordinates}, and {@link Map#setPadding}. Adjust these options to set the amount of padding in pixels added to the edges of the canvas. Set a uniform padding on all edges or individual values for each edge. All properties of this object must be
 * non-negative integers.
 *
 * @typedef {Object} PaddingOptions
 * @property {number} top Padding in pixels from the top of the map canvas.
 * @property {number} bottom Padding in pixels from the bottom of the map canvas.
 * @property {number} left Padding in pixels from the left of the map canvas.
 * @property {number} right Padding in pixels from the right of the map canvas.
 *
 * @example
 * const bbox = [[-79, 43], [-73, 45]];
 * map.fitBounds(bbox, {
 *     padding: {top: 10, bottom:25, left: 15, right: 5}
 * });
 *
 * @example
 * const bbox = [[-79, 43], [-73, 45]];
 * map.fitBounds(bbox, {
 *     padding: 20
 * });
 * @see [Example: Fit to the bounds of a LineString](https://docs.mapbox.com/mapbox-gl-js/example/zoomto-linestring/)
 * @see [Example: Fit a map to a bounding box](https://docs.mapbox.com/mapbox-gl-js/example/fitbounds/)
 */

class Camera extends index.Evented {
                         
                     
                      
                       
                       
                      

                         
                       
                                                                    
                           
                                          

                                                   
                                           
                          

                                                 
                                             

                                                                                               

    constructor(transform           , options                                                              ) {
        super();
        this._moving = false;
        this._zooming = false;
        this.transform = transform;
        this._bearingSnap = options.bearingSnap;
        this._respectPrefersReducedMotion = options.respectPrefersReducedMotion !== false;

        index.bindAll(['_renderFrameCallback'], this);

        //addAssertions(this);
    }

    /** @section {Camera}
     * @method
     * @instance
     * @memberof Map */

    /**
     * Returns the map's geographical centerpoint.
     *
     * @memberof Map#
     * @returns {LngLat} The map's geographical centerpoint.
     * @example
     * // Return a LngLat object such as {lng: 0, lat: 0}.
     * const center = map.getCenter();
     * // Access longitude and latitude values directly.
     * const {lng, lat} = map.getCenter();
     * @see [Tutorial: Use Mapbox GL JS in a React app](https://docs.mapbox.com/help/tutorials/use-mapbox-gl-js-with-react/#store-the-new-coordinates)
     */
    getCenter()         { return new index.LngLat(this.transform.center.lng, this.transform.center.lat); }

    /**
     * Sets the map's geographical centerpoint. Equivalent to `jumpTo({center: center})`.
     *
     * @memberof Map#
     * @param {LngLatLike} center The centerpoint to set.
     * @param {Object | null} eventData Additional properties to be added to event objects of events triggered by this method.
     * @fires Map.event:movestart
     * @fires Map.event:moveend
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * map.setCenter([-74, 38]);
     */
    setCenter(center            , eventData         )       {
        return this.jumpTo({center}, eventData);
    }

    /**
     * Pans the map by the specified offset.
     *
     * @memberof Map#
     * @param {PointLike} offset The `x` and `y` coordinates by which to pan the map.
     * @param {AnimationOptions | null} options An options object describing the destination and animation of the transition. We do not recommend using `options.offset` since this value will override the value of the `offset` parameter.
     * @param {Object | null} eventData Additional properties to be added to event objects of events triggered by this method.
     * @fires Map.event:movestart
     * @fires Map.event:moveend
     * @returns {Map} `this` Returns itself to allow for method chaining.
     * @example
     * map.panBy([-74, 38]);
     * @example
     * // panBy with an animation of 5 seconds.
     * map.panBy([-74, 38], {duration: 5000});
     * @see [Example: Navigate the map with game-like controls](https://www.mapbox.com/mapbox-gl-js/example/game-controls/)
     */
    panBy(offset           , options                   , eventData         )       {
        offset = index.Point.convert(offset).mult(-1);
        return this.panTo(this.transform.center, index.extend({offset}, options), eventData);
    }

    /**
     * Pans the map to the specified location with an animated transition.
     *
     * @memberof Map#
     * @param {LngLatLike} lnglat The location to pan the map to.
     * @param {AnimationOptions | null} options Options describing the destination and animation of the transition.
     * @param {Object | null} eventData Additional properties to be added to event objects of events triggered by this method.
     * @fires Map.event:movestart
     * @fires Map.event:moveend
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * map.panTo([-74, 38]);
     * @example
     * // Specify that the panTo animation should last 5000 milliseconds.
     * map.panTo([-74, 38], {duration: 5000});
     * @see [Example: Update a feature in realtime](https://docs.mapbox.com/mapbox-gl-js/example/live-update-feature/)
     */
    panTo(lnglat            , options                   , eventData         )       {
        return this.easeTo(index.extend({
            center: lnglat
        }, options), eventData);
    }

    /**
     * Returns the map's current zoom level.
     *
     * @memberof Map#
     * @returns {number} The map's current zoom level.
     * @example
     * map.getZoom();
     */
    getZoom()         { return this.transform.zoom; }

    /**
     * Sets the map's zoom level. Equivalent to `jumpTo({zoom: zoom})`.
     *
     * @memberof Map#
     * @param {number} zoom The zoom level to set (0-20).
     * @param {Object | null} eventData Additional properties to be added to event objects of events triggered by this method.
     * @fires Map.event:movestart
     * @fires Map.event:zoomstart
     * @fires Map.event:move
     * @fires Map.event:zoom
     * @fires Map.event:moveend
     * @fires Map.event:zoomend
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * // Zoom to the zoom level 5 without an animated transition
     * map.setZoom(5);
     */
    setZoom(zoom        , eventData         )       {
        this.jumpTo({zoom}, eventData);
        return this;
    }

    /**
     * Zooms the map to the specified zoom level, with an animated transition.
     *
     * @memberof Map#
     * @param {number} zoom The zoom level to transition to.
     * @param {AnimationOptions | null} options Options object.
     * @param {Object | null} eventData Additional properties to be added to event objects of events triggered by this method.
     * @fires Map.event:movestart
     * @fires Map.event:zoomstart
     * @fires Map.event:move
     * @fires Map.event:zoom
     * @fires Map.event:moveend
     * @fires Map.event:zoomend
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * // Zoom to the zoom level 5 without an animated transition
     * map.zoomTo(5);
     * // Zoom to the zoom level 8 with an animated transition
     * map.zoomTo(8, {
     *     duration: 2000,
     *     offset: [100, 50]
     * });
     */
    zoomTo(zoom        , options                    , eventData         )       {
        return this.easeTo(index.extend({
            zoom
        }, options), eventData);
    }

    /**
     * Increases the map's zoom level by 1.
     *
     * @memberof Map#
     * @param {AnimationOptions | null} options Options object.
     * @param {Object | null} eventData Additional properties to be added to event objects of events triggered by this method.
     * @fires Map.event:movestart
     * @fires Map.event:zoomstart
     * @fires Map.event:move
     * @fires Map.event:zoom
     * @fires Map.event:moveend
     * @fires Map.event:zoomend
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * // zoom the map in one level with a custom animation duration
     * map.zoomIn({duration: 1000});
     */
    zoomIn(options                   , eventData         )       {
        this.zoomTo(this.getZoom() + 1, options, eventData);
        return this;
    }

    /**
     * Decreases the map's zoom level by 1.
     *
     * @memberof Map#
     * @param {AnimationOptions | null} options Options object.
     * @param {Object | null} eventData Additional properties to be added to event objects of events triggered by this method.
     * @fires Map.event:movestart
     * @fires Map.event:zoomstart
     * @fires Map.event:move
     * @fires Map.event:zoom
     * @fires Map.event:moveend
     * @fires Map.event:zoomend
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * // zoom the map out one level with a custom animation offset
     * map.zoomOut({offset: [80, 60]});
     */
    zoomOut(options                   , eventData         )       {
        this.zoomTo(this.getZoom() - 1, options, eventData);
        return this;
    }

    /**
     * Returns the map's current bearing. The bearing is the compass direction that is "up"; for example, a bearing
     * of 90° orients the map so that east is up.
     *
     * @memberof Map#
     * @returns {number} The map's current bearing.
     * @example
     * const bearing = map.getBearing();
     * @see [Example: Navigate the map with game-like controls](https://www.mapbox.com/mapbox-gl-js/example/game-controls/)
     */
    getBearing()         {
        return this.transform.bearing;
    }

    /**
     * Sets the map's bearing (rotation). The bearing is the compass direction that is "up"; for example, a bearing
     * of 90° orients the map so that east is up.
     *
     * Equivalent to `jumpTo({bearing: bearing})`.
     *
     * @memberof Map#
     * @param {number} bearing The desired bearing.
     * @param {Object | null} eventData Additional properties to be added to event objects of events triggered by this method.
     * @fires Map.event:movestart
     * @fires Map.event:moveend
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * // Rotate the map to 90 degrees.
     * map.setBearing(90);
     */
    setBearing(bearing        , eventData         )       {
        this.jumpTo({bearing}, eventData);
        return this;
    }

    /**
     * Returns the current padding applied around the map viewport.
     *
     * @memberof Map#
     * @returns {PaddingOptions} The current padding around the map viewport.
     * @example
     * const padding = map.getPadding();
     */
    getPadding()                 { return this.transform.padding; }

    /**
     * Sets the padding in pixels around the viewport.
     *
     * Equivalent to `jumpTo({padding: padding})`.
     *
     * @memberof Map#
     * @param {PaddingOptions} padding The desired padding. Format: {left: number, right: number, top: number, bottom: number}.
     * @param {Object | null} eventData Additional properties to be added to event objects of events triggered by this method.
     * @fires Map.event:movestart
     * @fires Map.event:moveend
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * // Sets a left padding of 300px, and a top padding of 50px
     * map.setPadding({left: 300, top: 50});
     */
    setPadding(padding                , eventData         )       {
        this.jumpTo({padding}, eventData);
        return this;
    }

    /**
     * Rotates the map to the specified bearing, with an animated transition. The bearing is the compass direction
     * that is \"up\"; for example, a bearing of 90° orients the map so that east is up.
     *
     * @memberof Map#
     * @param {number} bearing The desired bearing.
     * @param {EasingOptions | null} options Options describing the destination and animation of the transition.
     *            Accepts {@link CameraOptions} and {@link AnimationOptions}.
     * @param {Object | null} eventData Additional properties to be added to event objects of events triggered by this method.
     * @fires Map.event:movestart
     * @fires Map.event:moveend
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * map.rotateTo(30);
     * @example
     * // rotateTo with an animation of 2 seconds.
     * map.rotateTo(30, {duration: 2000});
     */
    rotateTo(bearing        , options                , eventData         )       {
        return this.easeTo(index.extend({
            bearing
        }, options), eventData);
    }

    /**
     * Rotates the map so that north is up (0° bearing), with an animated transition.
     *
     * @memberof Map#
     * @param {EasingOptions | null} options Options describing the destination and animation of the transition.
     *            Accepts {@link CameraOptions} and {@link AnimationOptions}.
     * @param {Object | null} eventData Additional properties to be added to event objects of events triggered by this method.
     * @fires Map.event:movestart
     * @fires Map.event:moveend
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * // resetNorth with an animation of 2 seconds.
     * map.resetNorth({duration: 2000});
     */
    resetNorth(options                , eventData         )       {
        this.rotateTo(0, index.extend({duration: 1000}, options), eventData);
        return this;
    }

    /**
     * Rotates and pitches the map so that north is up (0° bearing) and pitch is 0°, with an animated transition.
     *
     * @memberof Map#
     * @param {EasingOptions | null} options Options describing the destination and animation of the transition.
     *            Accepts {@link CameraOptions} and {@link AnimationOptions}.
     * @param {Object | null} eventData Additional properties to be added to event objects of events triggered by this method.
     * @fires Map.event:movestart
     * @fires Map.event:moveend
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * // resetNorthPitch with an animation of 2 seconds.
     * map.resetNorthPitch({duration: 2000});
     */
    resetNorthPitch(options                , eventData         )       {
        this.easeTo(index.extend({
            bearing: 0,
            pitch: 0,
            duration: 1000
        }, options), eventData);
        return this;
    }

    /**
     * Snaps the map so that north is up (0° bearing), if the current bearing is
     * close enough to it (within the `bearingSnap` threshold).
     *
     * @memberof Map#
     * @param {EasingOptions | null} options Options describing the destination and animation of the transition.
     *            Accepts {@link CameraOptions} and {@link AnimationOptions}.
     * @param {Object | null} eventData Additional properties to be added to event objects of events triggered by this method.
     * @fires Map.event:movestart
     * @fires Map.event:moveend
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * // snapToNorth with an animation of 2 seconds.
     * map.snapToNorth({duration: 2000});
     */
    snapToNorth(options                , eventData         )       {
        if (Math.abs(this.getBearing()) < this._bearingSnap) {
            return this.resetNorth(options, eventData);
        }
        return this;
    }

    /**
     * Returns the map's current [pitch](https://docs.mapbox.com/help/glossary/camera/) (tilt).
     *
     * @memberof Map#
     * @returns {number} The map's current pitch, measured in degrees away from the plane of the screen.
     * @example
     * const pitch = map.getPitch();
     */
    getPitch()         { return this.transform.pitch; }

    /**
     * Sets the map's [pitch](https://docs.mapbox.com/help/glossary/camera/) (tilt). Equivalent to `jumpTo({pitch: pitch})`.
     *
     * @memberof Map#
     * @param {number} pitch The pitch to set, measured in degrees away from the plane of the screen (0-60).
     * @param {Object | null} eventData Additional properties to be added to event objects of events triggered by this method.
     * @fires Map.event:pitchstart
     * @fires Map.event:movestart
     * @fires Map.event:moveend
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * // setPitch with an animation of 2 seconds.
     * map.setPitch(80, {duration: 2000});
     */
    setPitch(pitch        , eventData         )       {
        this.jumpTo({pitch}, eventData);
        return this;
    }

    /**
     * Returns a {@link CameraOptions} object for the highest zoom level
     * up to and including `Map#getMaxZoom()` that fits the bounds
     * in the viewport at the specified bearing.
     *
     * @memberof Map#
     * @param {LngLatBoundsLike} bounds Calculate the center for these bounds in the viewport and use
     *      the highest zoom level up to and including `Map#getMaxZoom()` that fits
     *      in the viewport. LngLatBounds represent a box that is always axis-aligned with bearing 0.
     * @param {CameraOptions | null} options Options object.
     * @param {number | PaddingOptions} [options.padding] The amount of padding in pixels to add to the given bounds.
     * @param {number} [options.bearing=0] Desired map bearing at end of animation, in degrees.
     * @param {number} [options.pitch=0] Desired map pitch at end of animation, in degrees.
     * @param {PointLike} [options.offset=[0, 0]] The center of the given bounds relative to the map's center, measured in pixels.
     * @param {number} [options.maxZoom] The maximum zoom level to allow when the camera would transition to the specified bounds.
     * @returns {CameraOptions | void} If map is able to fit to provided bounds, returns `CameraOptions` with
     *      `center`, `zoom`, and `bearing`. If map is unable to fit, method will warn and return undefined.
     * @example
     * const bbox = [[-79, 43], [-73, 45]];
     * const newCameraTransform = map.cameraForBounds(bbox, {
     *     padding: {top: 10, bottom:25, left: 15, right: 5}
     * });
     */
    cameraForBounds(bounds                  , options                )                 {
        bounds = index.LngLatBounds.convert(bounds);
        const bearing = (options && options.bearing) || 0;
        const pitch = (options && options.pitch) || 0;
        const lnglat0 = bounds.getNorthWest();
        const lnglat1 = bounds.getSouthEast();
        return this._cameraForBounds(this.transform, lnglat0, lnglat1, bearing, pitch, options);
    }

    _extendCameraOptions(options                )                    {
        const defaultPadding = {
            top: 0,
            bottom: 0,
            right: 0,
            left: 0
        };
        options = index.extend({
            padding: defaultPadding,
            offset: [0, 0],
            maxZoom: this.transform.maxZoom
        }, options);

        if (typeof options.padding === 'number') {
            const p = options.padding;
            options.padding = {
                top: p,
                bottom: p,
                right: p,
                left: p
            };
        }
        options.padding = index.extend(defaultPadding, options.padding);
        return options;
    }

    _minimumAABBFrustumDistance(tr           , aabb      )         {
        const aabbW = aabb.max[0] - aabb.min[0];
        const aabbH = aabb.max[1] - aabb.min[1];
        const aabbAspectRatio = aabbW / aabbH;
        const selectXAxis = aabbAspectRatio > tr.aspect;

        const minimumDistance = selectXAxis ?
            aabbW / (2 * Math.tan(tr.fovX * 0.5) * tr.aspect) :
            aabbH / (2 * Math.tan(tr.fovY * 0.5) * tr.aspect);

        return minimumDistance;
    }

    _cameraForBoundsOnGlobe(transform           , p0            , p1            , bearing        , pitch        , options                )                 {
        const tr = transform.clone();
        const eOptions = this._extendCameraOptions(options);

        tr.bearing = bearing;
        tr.pitch = pitch;

        const coord0 = index.LngLat.convert(p0);
        const coord1 = index.LngLat.convert(p1);

        const midLat = (coord0.lat + coord1.lat) * 0.5;
        const midLng = (coord0.lng + coord1.lng) * 0.5;

        const origin = index.latLngToECEF(midLat, midLng);

        const zAxis = index.normalize([], origin);
        const xAxis = index.normalize([], index.cross([], zAxis, [0, 1, 0]));
        const yAxis = index.cross([], xAxis, zAxis);

        const aabbOrientation = [
            xAxis[0], xAxis[1], xAxis[2], 0,
            yAxis[0], yAxis[1], yAxis[2], 0,
            zAxis[0], zAxis[1], zAxis[2], 0,
            0, 0, 0, 1
        ];

        const ecefCoords = [
            origin,

            index.latLngToECEF(coord0.lat, coord0.lng),
            index.latLngToECEF(coord1.lat, coord0.lng),
            index.latLngToECEF(coord1.lat, coord1.lng),
            index.latLngToECEF(coord0.lat, coord1.lng),

            index.latLngToECEF(midLat, coord0.lng),
            index.latLngToECEF(midLat, coord1.lng),
            index.latLngToECEF(coord0.lat, midLng),
            index.latLngToECEF(coord1.lat, midLng),
        ];

        let aabb = index.Aabb.fromPoints(ecefCoords.map(p => [index.dot(xAxis, p), index.dot(yAxis, p), index.dot(zAxis, p)]));

        const center = index.transformMat4([], aabb.center, aabbOrientation);

        if (index.squaredLength(center) === 0) {
            index.set(center, 0, 0, 1);
        }

        index.normalize(center, center);
        index.scale$3(center, center, index.GLOBE_RADIUS);
        tr.center = index.ecefToLatLng(center);

        const worldToCamera = tr.getWorldToCameraMatrix();
        const cameraToWorld = index.invert$1(new Float64Array(16), worldToCamera);

        aabb = index.Aabb.applyTransform(aabb, index.multiply([], worldToCamera, aabbOrientation));

        index.transformMat4(center, center, worldToCamera);

        const aabbHalfExtentZ = (aabb.max[2] - aabb.min[2]) * 0.5;
        const frustumDistance = this._minimumAABBFrustumDistance(tr, aabb);

        const offsetZ = index.scale$3([], [0, 0, 1], aabbHalfExtentZ);
        const aabbClosestPoint = index.add(offsetZ, center, offsetZ);
        const offsetDistance = frustumDistance + (tr.pitch === 0 ? 0 : index.distance(center, aabbClosestPoint));

        const globeCenter = tr.globeCenterInViewSpace;
        const normal = index.sub([], center, [globeCenter[0], globeCenter[1], globeCenter[2]]);
        index.normalize(normal, normal);
        index.scale$3(normal, normal, offsetDistance);

        const cameraPosition = index.add([], center, normal);

        index.transformMat4(cameraPosition, cameraPosition, cameraToWorld);

        const meterPerECEF = index.earthRadius / index.GLOBE_RADIUS;
        const altitudeECEF = index.length(cameraPosition);
        const altitudeMeter = altitudeECEF * meterPerECEF - index.earthRadius;
        const mercatorZ = index.mercatorZfromAltitude(Math.max(altitudeMeter, Number.EPSILON), 0);

        const zoom = Math.min(tr.zoomFromMercatorZAdjusted(mercatorZ), eOptions.maxZoom);

        const halfZoomTransition = (index.GLOBE_ZOOM_THRESHOLD_MIN + index.GLOBE_ZOOM_THRESHOLD_MAX) * 0.5;
        if (zoom > halfZoomTransition) {
            tr.setProjection({name: 'mercator'});
            tr.zoom = zoom;
            return this._cameraForBounds(tr, p0, p1, bearing, pitch, options);
        }

        return {center: tr.center, zoom, bearing, pitch};
    }

    /** @section {Querying features} */

    /**
     * Queries the currently loaded data for elevation at a geographical location. The elevation is returned in `meters` relative to mean sea-level.
     * Returns `null` if `terrain` is disabled or if terrain data for the location hasn't been loaded yet.
     *
     * In order to guarantee that the terrain data is loaded ensure that the geographical location is visible and wait for the `idle` event to occur.
     *
     * @memberof Map#
     * @param {LngLatLike} lnglat The geographical location at which to query.
     * @param {ElevationQueryOptions} [options] Options object.
     * @param {boolean} [options.exaggerated=true] When `true` returns the terrain elevation with the value of `exaggeration` from the style already applied.
     * When `false`, returns the raw value of the underlying data without styling applied.
     * @returns {number | null} The elevation in meters.
     * @example
     * const coordinate = [-122.420679, 37.772537];
     * const elevation = map.queryTerrainElevation(coordinate);
     * @see [Example: Query terrain elevation](https://docs.mapbox.com/mapbox-gl-js/example/query-terrain-elevation/)
     */
    queryTerrainElevation(lnglat            , options                        )          {
        const elevation = this.transform.elevation;
        if (elevation) {
            options = index.extend({}, {exaggerated: true}, options);
            return elevation.getAtPoint(index.MercatorCoordinate.fromLngLat(lnglat), null, options.exaggerated);
        }
        return null;
    }

    /**
     * Calculate the center of these two points in the viewport and use
     * the highest zoom level up to and including `Map#getMaxZoom()` that fits
     * the points in the viewport at the specified bearing.
     * @memberof Map#
     * @param {LngLatLike} p0 First point
     * @param {LngLatLike} p1 Second point
     * @param {number} bearing Desired map bearing at end of animation, in degrees
     * @param {number} pitch Desired map pitch at end of animation, in degrees
     * @param {CameraOptions | null} options
     * @param {number | PaddingOptions} [options.padding] The amount of padding in pixels to add to the given bounds.
     * @param {PointLike} [options.offset=[0, 0]] The center of the given bounds relative to the map's center, measured in pixels.
     * @param {number} [options.maxZoom] The maximum zoom level to allow when the camera would transition to the specified bounds.
     * @returns {CameraOptions | void} If map is able to fit to provided bounds, returns `CameraOptions` with
     *      `center`, `zoom`, and `bearing`. If map is unable to fit, method will warn and return undefined.
     * @private
     * @example
     * var p0 = [-79, 43];
     * var p1 = [-73, 45];
     * var bearing = 90;
     * var newCameraTransform = map._cameraForBounds(p0, p1, bearing, pitch, {
     *   padding: {top: 10, bottom:25, left: 15, right: 5}
     * });
     */
    _cameraForBounds(transform           , p0            , p1            , bearing        , pitch        , options                )                 {
        if (transform.projection.name === 'globe') {
            return this._cameraForBoundsOnGlobe(transform, p0, p1, bearing, pitch, options);
        }

        const tr = transform.clone();
        const eOptions = this._extendCameraOptions(options);
        const edgePadding = tr.padding;

        tr.bearing = bearing;
        tr.pitch = pitch;

        const coord0 = index.LngLat.convert(p0);
        const coord1 = index.LngLat.convert(p1);
        const coord2 = new index.LngLat(coord0.lng, coord1.lat);
        const coord3 = new index.LngLat(coord1.lng, coord0.lat);

        const p0world = tr.project(coord0);
        const p1world = tr.project(coord1);

        const z0 = this.queryTerrainElevation(coord0);
        const z1 = this.queryTerrainElevation(coord1);
        const z2 = this.queryTerrainElevation(coord2);
        const z3 = this.queryTerrainElevation(coord3);

        const worldCoords = [
            [p0world.x, p0world.y, Math.min(z0 || 0, z1 || 0, z2 || 0, z3 || 0)],
            [p1world.x, p1world.y, Math.max(z0 || 0, z1 || 0, z2 || 0, z3 || 0)]
        ];

        let aabb = index.Aabb.fromPoints(worldCoords);

        const worldToCamera = tr.getWorldToCameraMatrix();
        const cameraToWorld = index.invert$1(new Float64Array(16), worldToCamera);

        aabb = index.Aabb.applyTransform(aabb, worldToCamera);

        const size = index.sub([], aabb.max, aabb.min);

        const screenPadL = edgePadding.left || 0;
        const screenPadR = edgePadding.right || 0;
        const screenPadB = edgePadding.bottom || 0;
        const screenPadT = edgePadding.top || 0;

        const {left: padL, right: padR, top: padT, bottom: padB} = eOptions.padding;

        const halfScreenPadX = (screenPadL + screenPadR) * 0.5;
        const halfScreenPadY = (screenPadT + screenPadB) * 0.5;

        const scaleX = (tr.width - (screenPadL + screenPadR + padL + padR)) / size[0];
        const scaleY = (tr.height - (screenPadB + screenPadT + padB + padT)) / size[1];

        const zoomRef = Math.min(tr.scaleZoom(tr.scale * Math.min(scaleX, scaleY)), eOptions.maxZoom);

        const scaleRatio = tr.scale / tr.zoomScale(zoomRef);

        aabb = new index.Aabb(
            [aabb.min[0] - (padL + halfScreenPadX) * scaleRatio, aabb.min[1] - (padB + halfScreenPadY) * scaleRatio, aabb.min[2]],
            [aabb.max[0] + (padR + halfScreenPadX) * scaleRatio, aabb.max[1] + (padT + halfScreenPadY) * scaleRatio, aabb.max[2]]);

        const aabbHalfExtentZ = size[2] * 0.5;
        const frustumDistance = this._minimumAABBFrustumDistance(tr, aabb);

        const normalZ = [0, 0, 1, 0];

        index.transformMat4$1(normalZ, normalZ, worldToCamera);
        index.normalize$2(normalZ, normalZ);

        const offset = index.scale$3([], normalZ, frustumDistance + aabbHalfExtentZ);
        const cameraPosition = index.add([], aabb.center, offset);

        const centerOffset = (typeof eOptions.offset.x === 'number' && typeof eOptions.offset.y === 'number') ?
            new index.Point(eOptions.offset.x, eOptions.offset.y) :
            index.Point.convert(eOptions.offset);

        const rotatedOffset = centerOffset.rotate(-index.degToRad(bearing));

        aabb.center[0] -= rotatedOffset.x * scaleRatio;
        aabb.center[1] += rotatedOffset.y * scaleRatio;

        index.transformMat4(aabb.center, aabb.center, cameraToWorld);
        index.transformMat4(cameraPosition, cameraPosition, cameraToWorld);

        const mercator = [aabb.center[0], aabb.center[1], cameraPosition[2] * tr.pixelsPerMeter];
        index.scale$3(mercator, mercator, 1.0 / tr.worldSize);

        const lng = index.lngFromMercatorX(mercator[0]);
        const lat = index.latFromMercatorY(mercator[1]);

        const zoom = Math.min(tr._zoomFromMercatorZ(mercator[2]), eOptions.maxZoom);
        const center = new index.LngLat(lng, lat);

        const halfZoomTransition = (index.GLOBE_ZOOM_THRESHOLD_MIN + index.GLOBE_ZOOM_THRESHOLD_MAX) * 0.5;

        if (tr.mercatorFromTransition && zoom < halfZoomTransition) {
            tr.setProjection({name: 'globe'});
            tr.zoom = zoom;
            return this._cameraForBounds(tr, p0, p1, bearing, pitch, options);
        }

        return {center, zoom, bearing, pitch};
    }

    /**
     * Pans and zooms the map to contain its visible area within the specified geographical bounds.
     * If a padding is set on the map, the bounds are fit to the inset.
     *
     * @memberof Map#
     * @param {LngLatBoundsLike} bounds Center these bounds in the viewport and use the highest
     *      zoom level up to and including `Map#getMaxZoom()` that fits them in the viewport.
     * @param {Object} [options] Options supports all properties from {@link AnimationOptions} and {@link CameraOptions} in addition to the fields below.
     * @param {number | PaddingOptions} [options.padding] The amount of padding in pixels to add to the given bounds.
     * @param {number} [options.pitch=0] Desired map pitch at end of animation, in degrees.
     * @param {number} [options.bearing=0] Desired map bearing at end of animation, in degrees.
     * @param {boolean} [options.linear=false] If `true`, the map transitions using
     *     {@link Map#easeTo}. If `false`, the map transitions using {@link Map#flyTo}. See
     *     those functions and {@link AnimationOptions} for information about options available.
     * @param {Function} [options.easing] An easing function for the animated transition. See {@link AnimationOptions}.
     * @param {PointLike} [options.offset=[0, 0]] The center of the given bounds relative to the map's center, measured in pixels.
     * @param {number} [options.maxZoom] The maximum zoom level to allow when the map view transitions to the specified bounds.
     * @param {Object} [eventData] Additional properties to be added to event objects of events triggered by this method.
     * @fires Map.event:movestart
     * @fires Map.event:moveend
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * const bbox = [[-79, 43], [-73, 45]];
     * map.fitBounds(bbox, {
     *     padding: {top: 10, bottom:25, left: 15, right: 5}
     * });
     * @see [Example: Fit a map to a bounding box](https://www.mapbox.com/mapbox-gl-js/example/fitbounds/)
     */
    fitBounds(bounds                  , options                , eventData         )       {
        const cameraPlacement = this.cameraForBounds(bounds, options);
        return this._fitInternal(cameraPlacement, options, eventData);
    }

    /**
     * Pans, rotates and zooms the map to to fit the box made by points p0 and p1
     * once the map is rotated to the specified bearing. To zoom without rotating,
     * pass in the current map bearing.
     *
     * @memberof Map#
     * @param {PointLike} p0 First point on screen, in pixel coordinates.
     * @param {PointLike} p1 Second point on screen, in pixel coordinates.
     * @param {number} bearing Desired map bearing at end of animation, in degrees.
     * @param {EasingOptions | null} options Options object.
     *     Accepts {@link CameraOptions} and {@link AnimationOptions}.
     * @param {number | PaddingOptions} [options.padding] The amount of padding in pixels to add to the given bounds.
     * @param {boolean} [options.linear=false] If `true`, the map transitions using
     *     {@link Map#easeTo}. If `false`, the map transitions using {@link Map#flyTo}. See
     *     those functions and {@link AnimationOptions} for information about options available.
     * @param {number} [options.pitch=0] Desired map pitch at end of animation, in degrees.
     * @param {Function} [options.easing] An easing function for the animated transition. See {@link AnimationOptions}.
     * @param {PointLike} [options.offset=[0, 0]] The center of the given bounds relative to the map's center, measured in pixels.
     * @param {number} [options.maxZoom] The maximum zoom level to allow when the map view transitions to the specified bounds.
     * @param {Object | null} eventData Additional properties to be added to event objects of events triggered by this method.
     * @fires Map.event:movestart
     * @fires Map.event:moveend
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * const p0 = [220, 400];
     * const p1 = [500, 900];
     * map.fitScreenCoordinates(p0, p1, map.getBearing(), {
     *     padding: {top: 10, bottom:25, left: 15, right: 5}
     * });
     * @see Used by {@link BoxZoomHandler}
     */
    fitScreenCoordinates(p0           , p1           , bearing        , options                , eventData         )       {
        const screen0 = index.Point.convert(p0);
        const screen1 = index.Point.convert(p1);

        const min = new index.Point(Math.min(screen0.x, screen1.x), Math.min(screen0.y, screen1.y));
        const max = new index.Point(Math.max(screen0.x, screen1.x), Math.max(screen0.y, screen1.y));

        if (this.transform.projection.name === 'mercator' && this.transform.anyCornerOffEdge(screen0, screen1)) {
            return this;
        }

        const lnglat0 = this.transform.pointLocation3D(min);
        const lnglat1 = this.transform.pointLocation3D(max);
        const lnglat2 = this.transform.pointLocation3D(new index.Point(min.x, max.y));
        const lnglat3 = this.transform.pointLocation3D(new index.Point(max.x, min.y));

        const p0coord = [
            Math.min(lnglat0.lng, lnglat1.lng, lnglat2.lng, lnglat3.lng),
            Math.min(lnglat0.lat, lnglat1.lat, lnglat2.lat, lnglat3.lat),
        ];
        const p1coord =  [
            Math.max(lnglat0.lng, lnglat1.lng, lnglat2.lng, lnglat3.lng),
            Math.max(lnglat0.lat, lnglat1.lat, lnglat2.lat, lnglat3.lat),
        ];

        const pitch = options && options.pitch ? options.pitch : this.getPitch();

        const cameraPlacement = this._cameraForBounds(this.transform, p0coord, p1coord, bearing, pitch, options);
        return this._fitInternal(cameraPlacement, options, eventData);
    }

    _fitInternal(calculatedOptions                 , options                , eventData         )       {
        // cameraForBounds warns + returns undefined if unable to fit:
        if (!calculatedOptions) return this;

        options = index.extend(calculatedOptions, options);
        // Explicitly remove the padding field because, calculatedOptions already accounts for padding by setting zoom and center accordingly.
        delete options.padding;

        return options.linear ?
            this.easeTo(options, eventData) :
            this.flyTo(options, eventData);
    }

    /**
     * Changes any combination of center, zoom, bearing, and pitch, without
     * an animated transition. The map will retain its current values for any
     * details not specified in `options`.
     *
     * @memberof Map#
     * @param {CameraOptions} options Options object.
     * @param {Object | null} eventData Additional properties to be added to event objects of events triggered by this method.
     * @fires Map.event:movestart
     * @fires Map.event:zoomstart
     * @fires Map.event:pitchstart
     * @fires Map.event:rotate
     * @fires Map.event:move
     * @fires Map.event:zoom
     * @fires Map.event:pitch
     * @fires Map.event:moveend
     * @fires Map.event:zoomend
     * @fires Map.event:pitchend
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * // jump to coordinates at current zoom
     * map.jumpTo({center: [0, 0]});
     * // jump with zoom, pitch, and bearing options
     * map.jumpTo({
     *     center: [0, 0],
     *     zoom: 8,
     *     pitch: 45,
     *     bearing: 90
     * });
     * @see [Example: Jump to a series of locations](https://docs.mapbox.com/mapbox-gl-js/example/jump-to/)
     * @see [Example: Update a feature in realtime](https://docs.mapbox.com/mapbox-gl-js/example/live-update-feature/)
     */
    jumpTo(options                                                                                , eventData         )       {
        this.stop();

        const tr = options.preloadOnly ? this.transform.clone() : this.transform;
        let zoomChanged = false,
            bearingChanged = false,
            pitchChanged = false;

        if ('zoom' in options && tr.zoom !== +options.zoom) {
            zoomChanged = true;
            tr.zoom = +options.zoom;
        }

        if (options.center !== undefined) {
            tr.center = index.LngLat.convert(options.center);
        }

        if ('bearing' in options && tr.bearing !== +options.bearing) {
            bearingChanged = true;
            tr.bearing = +options.bearing;
        }

        if ('pitch' in options && tr.pitch !== +options.pitch) {
            pitchChanged = true;
            tr.pitch = +options.pitch;
        }

        if (options.padding != null && !tr.isPaddingEqual(options.padding)) {
            // $FlowFixMe[incompatible-type] - Flow can't infer that padding is not null here
            tr.padding = options.padding;
        }

        if (options.preloadOnly) {
            this._preloadTiles(tr);
            return this;
        }

        this.fire(new index.Event('movestart', eventData))
            .fire(new index.Event('move', eventData));

        if (zoomChanged) {
            this.fire(new index.Event('zoomstart', eventData))
                .fire(new index.Event('zoom', eventData))
                .fire(new index.Event('zoomend', eventData));
        }

        if (bearingChanged) {
            this.fire(new index.Event('rotatestart', eventData))
                .fire(new index.Event('rotate', eventData))
                .fire(new index.Event('rotateend', eventData));
        }

        if (pitchChanged) {
            this.fire(new index.Event('pitchstart', eventData))
                .fire(new index.Event('pitch', eventData))
                .fire(new index.Event('pitchend', eventData));
        }

        return this.fire(new index.Event('moveend', eventData));
    }

    /**
     * Returns position and orientation of the camera entity.
     *
     * This method is not supported for projections other than mercator.
     *
     * @memberof Map#
     * @returns {FreeCameraOptions} The camera state.
     * @example
     * const camera = map.getFreeCameraOptions();
     *
     * const position = [138.72649, 35.33974];
     * const altitude = 3000;
     *
     * camera.position = mapboxgl.MercatorCoordinate.fromLngLat(position, altitude);
     * camera.lookAtPoint([138.73036, 35.36197]);
     *
     * map.setFreeCameraOptions(camera);
     */
    getFreeCameraOptions()                    {
        if (!this.transform.projection.supportsFreeCamera) {
            index.warnOnce(freeCameraNotSupportedWarning);
        }
        return this.transform.getFreeCameraOptions();
    }

    /**
     * `FreeCameraOptions` provides more direct access to the underlying camera entity.
     * For backwards compatibility the state set using this API must be representable with
     * `CameraOptions` as well. Parameters are clamped into a valid range or discarded as invalid
     * if the conversion to the pitch and bearing presentation is ambiguous. For example orientation
     * can be invalid if it leads to the camera being upside down, the quaternion has zero length,
     * or the pitch is over the maximum pitch limit.
     *
     * This method is not supported for projections other than mercator.
     *
     * @memberof Map#
     * @param {FreeCameraOptions} options `FreeCameraOptions` object.
     * @param {Object | null} eventData Additional properties to be added to event objects of events triggered by this method.
     * @fires Map.event:movestart
     * @fires Map.event:zoomstart
     * @fires Map.event:pitchstart
     * @fires Map.event:rotate
     * @fires Map.event:move
     * @fires Map.event:zoom
     * @fires Map.event:pitch
     * @fires Map.event:moveend
     * @fires Map.event:zoomend
     * @fires Map.event:pitchend
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * const camera = map.getFreeCameraOptions();
     *
     * const position = [138.72649, 35.33974];
     * const altitude = 3000;
     *
     * camera.position = mapboxgl.MercatorCoordinate.fromLngLat(position, altitude);
     * camera.lookAtPoint([138.73036, 35.36197]);
     *
     * map.setFreeCameraOptions(camera);
     */
    setFreeCameraOptions(options                   , eventData         )       {
        const tr = this.transform;

        if (!tr.projection.supportsFreeCamera) {
            index.warnOnce(freeCameraNotSupportedWarning);
            return this;
        }

        this.stop();

        const prevZoom = tr.zoom;
        const prevPitch = tr.pitch;
        const prevBearing = tr.bearing;

        tr.setFreeCameraOptions(options);

        const zoomChanged = prevZoom !== tr.zoom;
        const pitchChanged = prevPitch !== tr.pitch;
        const bearingChanged = prevBearing !== tr.bearing;

        this.fire(new index.Event('movestart', eventData))
            .fire(new index.Event('move', eventData));

        if (zoomChanged) {
            this.fire(new index.Event('zoomstart', eventData))
                .fire(new index.Event('zoom', eventData))
                .fire(new index.Event('zoomend', eventData));
        }

        if (bearingChanged) {
            this.fire(new index.Event('rotatestart', eventData))
                .fire(new index.Event('rotate', eventData))
                .fire(new index.Event('rotateend', eventData));
        }

        if (pitchChanged) {
            this.fire(new index.Event('pitchstart', eventData))
                .fire(new index.Event('pitch', eventData))
                .fire(new index.Event('pitchend', eventData));
        }

        this.fire(new index.Event('moveend', eventData));
        return this;
    }

    /**
     * Changes any combination of `center`, `zoom`, `bearing`, `pitch`, and `padding` with an animated transition
     * between old and new values. The map will retain its current values for any
     * details not specified in `options`.
     *
     * Note: The transition will happen instantly if the user has enabled
     * the `reduced motion` accessibility feature enabled in their operating system,
     * unless `options` includes `essential: true`.
     *
     * @memberof Map#
     * @param {EasingOptions} options Options describing the destination and animation of the transition.
     *            Accepts {@link CameraOptions} and {@link AnimationOptions}.
     * @param {Object | null} eventData Additional properties to be added to event objects of events triggered by this method.
     * @fires Map.event:movestart
     * @fires Map.event:zoomstart
     * @fires Map.event:pitchstart
     * @fires Map.event:rotate
     * @fires Map.event:move
     * @fires Map.event:zoom
     * @fires Map.event:pitch
     * @fires Map.event:moveend
     * @fires Map.event:zoomend
     * @fires Map.event:pitchend
     * @returns {Map} `this` Returns itself to allow for method chaining.
     * @example
     * // Ease with default options to null island for 5 seconds.
     * map.easeTo({center: [0, 0], zoom: 9, duration: 5000});
     * @example
     * // Using easeTo options.
     * map.easeTo({
     *     center: [0, 0],
     *     zoom: 9,
     *     speed: 0.2,
     *     curve: 1,
     *     duration: 5000,
     *     easing(t) {
     *         return t;
     *     }
     * });
     * @see [Example: Navigate the map with game-like controls](https://www.mapbox.com/mapbox-gl-js/example/game-controls/)
     */
    easeTo(options                                   , eventData         )       {
        this._stop(false, options.easeId);

        options = index.extend({
            offset: [0, 0],
            duration: 500,
            easing: index.ease
        }, options);

        if (options.animate === false || this._prefersReducedMotion(options)) options.duration = 0;

        const tr = this.transform,
            startZoom = this.getZoom(),
            startBearing = this.getBearing(),
            startPitch = this.getPitch(),
            startPadding = this.getPadding(),

            zoom = 'zoom' in options ? +options.zoom : startZoom,
            bearing = 'bearing' in options ? this._normalizeBearing(options.bearing, startBearing) : startBearing,
            pitch = 'pitch' in options ? +options.pitch : startPitch,
            padding = 'padding' in options ? options.padding : tr.padding;

        const offsetAsPoint = index.Point.convert(options.offset);

        let pointAtOffset;
        let from;
        let delta;

        if (tr.projection.name === 'globe') {
            // Pixel coordinates will be applied directly to translate the globe
            const centerCoord = index.MercatorCoordinate.fromLngLat(tr.center);

            const rotatedOffset = offsetAsPoint.rotate(-tr.angle);
            centerCoord.x += rotatedOffset.x / tr.worldSize;
            centerCoord.y += rotatedOffset.y / tr.worldSize;

            const locationAtOffset = centerCoord.toLngLat();
            const center = index.LngLat.convert(options.center || locationAtOffset);
            this._normalizeCenter(center);

            pointAtOffset = tr.centerPoint.add(rotatedOffset);
            from = new index.Point(centerCoord.x, centerCoord.y).mult(tr.worldSize);
            delta = new index.Point(index.mercatorXfromLng(center.lng), index.mercatorYfromLat(center.lat)).mult(tr.worldSize).sub(from);
        } else {
            pointAtOffset = tr.centerPoint.add(offsetAsPoint);
            const locationAtOffset = tr.pointLocation(pointAtOffset);
            const center = index.LngLat.convert(options.center || locationAtOffset);
            this._normalizeCenter(center);

            from = tr.project(locationAtOffset);
            delta = tr.project(center).sub(from);
        }
        const finalScale = tr.zoomScale(zoom - startZoom);

        let around, aroundPoint;

        if (options.around) {
            around = index.LngLat.convert(options.around);
            aroundPoint = tr.locationPoint(around);
        }

        const zoomChanged = this._zooming || (zoom !== startZoom);
        const bearingChanged = this._rotating || (startBearing !== bearing);
        const pitchChanged = this._pitching || (pitch !== startPitch);
        const paddingChanged = !tr.isPaddingEqual(padding);

        const frame = (tr           ) => (k        ) => {
            if (zoomChanged) {
                tr.zoom = index.number(startZoom, zoom, k);
            }
            if (bearingChanged) {
                tr.bearing = index.number(startBearing, bearing, k);
            }
            if (pitchChanged) {
                tr.pitch = index.number(startPitch, pitch, k);
            }
            if (paddingChanged) {
                tr.interpolatePadding(startPadding, padding, k);
                // When padding is being applied, Transform#centerPoint is changing continuously,
                // thus we need to recalculate offsetPoint every fra,e
                pointAtOffset = tr.centerPoint.add(offsetAsPoint);
            }

            if (around) {
                tr.setLocationAtPoint(around, aroundPoint);
            } else {
                const scale = tr.zoomScale(tr.zoom - startZoom);
                const base = zoom > startZoom ?
                    Math.min(2, finalScale) :
                    Math.max(0.5, finalScale);
                const speedup = Math.pow(base, 1 - k);
                const newCenter = tr.unproject(from.add(delta.mult(k * speedup)).mult(scale));
                tr.setLocationAtPoint(tr.renderWorldCopies ? newCenter.wrap() : newCenter, pointAtOffset);
            }

            if (!options.preloadOnly) {
                this._fireMoveEvents(eventData);
            }

            return tr;
        };

        if (options.preloadOnly) {
            const predictedTransforms = this._emulate(frame, options.duration, tr);
            this._preloadTiles(predictedTransforms);
            return this;
        }

        const currently = {
            moving: this._moving,
            zooming: this._zooming,
            rotating: this._rotating,
            pitching: this._pitching
        };

        this._zooming = zoomChanged;
        this._rotating = bearingChanged;
        this._pitching = pitchChanged;
        this._padding = paddingChanged;

        this._easeId = options.easeId;
        this._prepareEase(eventData, options.noMoveStart, currently);

        this._ease(frame(tr), (interruptingEaseId         ) => {
            tr.recenterOnTerrain();
            this._afterEase(eventData, interruptingEaseId);
        }, options);

        return this;
    }

    _prepareEase(eventData         , noMoveStart         , currently         = {}) {
        this._moving = true;
        this.transform.cameraElevationReference = "sea";

        if (!noMoveStart && !currently.moving) {
            this.fire(new index.Event('movestart', eventData));
        }
        if (this._zooming && !currently.zooming) {
            this.fire(new index.Event('zoomstart', eventData));
        }
        if (this._rotating && !currently.rotating) {
            this.fire(new index.Event('rotatestart', eventData));
        }
        if (this._pitching && !currently.pitching) {
            this.fire(new index.Event('pitchstart', eventData));
        }
    }

    _fireMoveEvents(eventData         ) {
        this.fire(new index.Event('move', eventData));
        if (this._zooming) {
            this.fire(new index.Event('zoom', eventData));
        }
        if (this._rotating) {
            this.fire(new index.Event('rotate', eventData));
        }
        if (this._pitching) {
            this.fire(new index.Event('pitch', eventData));
        }
    }

    _afterEase(eventData         , easeId         ) {
        // if this easing is being stopped to start another easing with
        // the same id then don't fire any events to avoid extra start/stop events
        if (this._easeId && easeId && this._easeId === easeId) {
            return;
        }
        this._easeId = undefined;
        this.transform.cameraElevationReference = "ground";

        const wasZooming = this._zooming;
        const wasRotating = this._rotating;
        const wasPitching = this._pitching;
        this._moving = false;
        this._zooming = false;
        this._rotating = false;
        this._pitching = false;
        this._padding = false;

        if (wasZooming) {
            this.fire(new index.Event('zoomend', eventData));
        }
        if (wasRotating) {
            this.fire(new index.Event('rotateend', eventData));
        }
        if (wasPitching) {
            this.fire(new index.Event('pitchend', eventData));
        }
        this.fire(new index.Event('moveend', eventData));
    }

    /**
     * Changes any combination of center, zoom, bearing, and pitch, animating the transition along a curve that
     * evokes flight. The animation seamlessly incorporates zooming and panning to help
     * the user maintain their bearings even after traversing a great distance.
     *
     * If a user has the `reduced motion` accessibility feature enabled in their
     * operating system, the animation will be skipped and this will behave
     * equivalently to `jumpTo`, unless 'options' includes `essential: true`.
     *
     * @memberof Map#
     * @param {Object} options Options describing the destination and animation of the transition.
     *     Accepts {@link CameraOptions}, {@link AnimationOptions},
     *     and the following additional options.
     * @param {number} [options.curve=1.42] The zooming "curve" that will occur along the
     *     flight path. A high value maximizes zooming for an exaggerated animation, while a low
     *     value minimizes zooming for an effect closer to {@link Map#easeTo}. 1.42 is the average
     *     value selected by participants in the user study discussed in
     *     [van Wijk (2003)](https://www.win.tue.nl/~vanwijk/zoompan.pdf). A value of
     *     `Math.pow(6, 0.25)` would be equivalent to the root mean squared average velocity. A
     *     value of 1 would produce a circular motion. If `options.minZoom` is specified, this option will be ignored.
     * @param {number} [options.minZoom] The zero-based zoom level at the peak of the flight path. If
     *     this option is specified, `options.curve` will be ignored.
     * @param {number} [options.speed=1.2] The average speed of the animation defined in relation to
     *     `options.curve`. A speed of 1.2 means that the map appears to move along the flight path
     *     by 1.2 times `options.curve` screenfuls every second. A _screenful_ is the map's visible span.
     *     It does not correspond to a fixed physical distance, but varies by zoom level.
     * @param {number} [options.screenSpeed] The average speed of the animation measured in screenfuls
     *     per second, assuming a linear timing curve. If `options.speed` is specified, this option is ignored.
     * @param {number} [options.maxDuration] The animation's maximum duration, measured in milliseconds.
     *     If duration exceeds maximum duration, it resets to 0.
     * @param {Object | null} eventData Additional properties to be added to event objects of events triggered by this method.
     * @fires Map.event:movestart
     * @fires Map.event:zoomstart
     * @fires Map.event:pitchstart
     * @fires Map.event:move
     * @fires Map.event:zoom
     * @fires Map.event:rotate
     * @fires Map.event:pitch
     * @fires Map.event:moveend
     * @fires Map.event:zoomend
     * @fires Map.event:pitchend
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * // fly with default options to null island
     * map.flyTo({center: [0, 0], zoom: 9});
     * // using flyTo options
     * map.flyTo({
     *     center: [0, 0],
     *     zoom: 9,
     *     speed: 0.2,
     *     curve: 1,
     *     easing(t) {
     *         return t;
     *     }
     * });
     * @see [Example: Fly to a location](https://www.mapbox.com/mapbox-gl-js/example/flyto/)
     * @see [Example: Slowly fly to a location](https://www.mapbox.com/mapbox-gl-js/example/flyto-options/)
     * @see [Example: Fly to a location based on scroll position](https://www.mapbox.com/mapbox-gl-js/example/scroll-fly-to/)
     */
    flyTo(options               , eventData         )       {
        // Fall through to jumpTo if user has set prefers-reduced-motion
        if (this._prefersReducedMotion(options)) {
            const coercedOptions = index.pick(options, ['center', 'zoom', 'bearing', 'pitch', 'around']);
            return this.jumpTo(coercedOptions, eventData);
        }

        // This method implements an “optimal path” animation, as detailed in:
        //
        // Van Wijk, Jarke J.; Nuij, Wim A. A. “Smooth and efficient zooming and panning.” INFOVIS
        //   ’03. pp. 15–22. <https://www.win.tue.nl/~vanwijk/zoompan.pdf#page=5>.
        //
        // Where applicable, local variable documentation begins with the associated variable or
        // function in van Wijk (2003).

        this.stop();

        options = index.extend({
            offset: [0, 0],
            speed: 1.2,
            curve: 1.42,
            easing: index.ease
        }, options);

        const tr = this.transform,
            startZoom = this.getZoom(),
            startBearing = this.getBearing(),
            startPitch = this.getPitch(),
            startPadding = this.getPadding();

        const zoom = 'zoom' in options ? index.clamp(+options.zoom, tr.minZoom, tr.maxZoom) : startZoom;
        const bearing = 'bearing' in options ? this._normalizeBearing(options.bearing, startBearing) : startBearing;
        const pitch = 'pitch' in options ? +options.pitch : startPitch;
        const padding = 'padding' in options ? options.padding : tr.padding;

        const scale = tr.zoomScale(zoom - startZoom);
        const offsetAsPoint = index.Point.convert(options.offset);
        let pointAtOffset = tr.centerPoint.add(offsetAsPoint);
        const locationAtOffset = tr.pointLocation(pointAtOffset);
        const center = index.LngLat.convert(options.center || locationAtOffset);
        this._normalizeCenter(center);

        const from = tr.project(locationAtOffset);
        const delta = tr.project(center).sub(from);

        let rho = options.curve;

        // w₀: Initial visible span, measured in pixels at the initial scale.
        const w0 = Math.max(tr.width, tr.height),
            // w₁: Final visible span, measured in pixels with respect to the initial scale.
            w1 = w0 / scale,
            // Length of the flight path as projected onto the ground plane, measured in pixels from
            // the world image origin at the initial scale.
            u1 = delta.mag();

        if ('minZoom' in options) {
            const minZoom = index.clamp(Math.min(options.minZoom, startZoom, zoom), tr.minZoom, tr.maxZoom);
            // w<sub>m</sub>: Maximum visible span, measured in pixels with respect to the initial
            // scale.
            const wMax = w0 / tr.zoomScale(minZoom - startZoom);
            rho = Math.sqrt(wMax / u1 * 2);
        }

        // ρ²
        const rho2 = rho * rho;

        /**
         * rᵢ: Returns the zoom-out factor at one end of the animation.
         *
         * @param i 0 for the ascent or 1 for the descent.
         * @private
         */
        function r(i        ) {
            const b = (w1 * w1 - w0 * w0 + (i ? -1 : 1) * rho2 * rho2 * u1 * u1) / (2 * (i ? w1 : w0) * rho2 * u1);
            return Math.log(Math.sqrt(b * b + 1) - b);
        }

        function sinh(n        ) { return (Math.exp(n) - Math.exp(-n)) / 2; }
        function cosh(n        ) { return (Math.exp(n) + Math.exp(-n)) / 2; }
        function tanh(n        ) { return sinh(n) / cosh(n); }

        // r₀: Zoom-out factor during ascent.
        const r0 = r(0);

        // w(s): Returns the visible span on the ground, measured in pixels with respect to the
        // initial scale. Assumes an angular field of view of 2 arctan ½ ≈ 53°.
        let w                        = function (s) {
            return (cosh(r0) / cosh(r0 + rho * s));
        };

        // u(s): Returns the distance along the flight path as projected onto the ground plane,
        // measured in pixels from the world image origin at the initial scale.
        let u                        = function (s) {
            return w0 * ((cosh(r0) * tanh(r0 + rho * s) - sinh(r0)) / rho2) / u1;
        };

        // S: Total length of the flight path, measured in ρ-screenfuls.
        let S = (r(1) - r0) / rho;

        // When u₀ = u₁, the optimal path doesn’t require both ascent and descent.
        if (Math.abs(u1) < 0.000001 || !isFinite(S)) {
            // Perform a more or less instantaneous transition if the path is too short.
            if (Math.abs(w0 - w1) < 0.000001) return this.easeTo(options, eventData);

            const k = w1 < w0 ? -1 : 1;
            S = Math.abs(Math.log(w1 / w0)) / rho;

            u = function() { return 0; };
            w = function(s) { return Math.exp(k * rho * s); };
        }

        if ('duration' in options) {
            options.duration = +options.duration;
        } else {
            const V = 'screenSpeed' in options ? +options.screenSpeed / rho : +options.speed;
            options.duration = 1000 * S / V;
        }

        if (options.maxDuration && options.duration > options.maxDuration) {
            options.duration = 0;
        }

        const zoomChanged = true;
        const bearingChanged = (startBearing !== bearing);
        const pitchChanged = (pitch !== startPitch);
        const paddingChanged = !tr.isPaddingEqual(padding);

        const frame = (tr           ) => (k        ) => {
            // s: The distance traveled along the flight path, measured in ρ-screenfuls.
            const s = k * S;
            const scale = 1 / w(s);
            tr.zoom = k === 1 ? zoom : startZoom + tr.scaleZoom(scale);

            if (bearingChanged) {
                tr.bearing = index.number(startBearing, bearing, k);
            }
            if (pitchChanged) {
                tr.pitch = index.number(startPitch, pitch, k);
            }
            if (paddingChanged) {
                tr.interpolatePadding(startPadding, padding, k);
                // When padding is being applied, Transform#centerPoint is changing continuously,
                // thus we need to recalculate offsetPoint every frame
                pointAtOffset = tr.centerPoint.add(offsetAsPoint);
            }

            const newCenter = k === 1 ? center : tr.unproject(from.add(delta.mult(u(s))).mult(scale));
            tr.setLocationAtPoint(tr.renderWorldCopies ? newCenter.wrap() : newCenter, pointAtOffset);
            tr._updateCameraOnTerrain();

            if (!options.preloadOnly) {
                this._fireMoveEvents(eventData);
            }

            return tr;
        };

        if (options.preloadOnly) {
            const predictedTransforms = this._emulate(frame, options.duration, tr);
            this._preloadTiles(predictedTransforms);
            return this;
        }

        this._zooming = zoomChanged;
        this._rotating = bearingChanged;
        this._pitching = pitchChanged;
        this._padding = paddingChanged;

        this._prepareEase(eventData, false);
        this._ease(frame(tr), () => this._afterEase(eventData), options);

        return this;
    }

    isEasing()          {
        return !!this._easeFrameId;
    }

    /**
     * Stops any animated transition underway.
     *
     * @memberof Map#
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * map.stop();
     */
    stop()       {
        return this._stop();
    }

    _stop(allowGestures          , easeId         )       {
        if (this._easeFrameId) {
            this._cancelRenderFrame(this._easeFrameId);
            this._easeFrameId = undefined;
            this._onEaseFrame = undefined;
        }

        if (this._onEaseEnd) {
            // The _onEaseEnd function might emit events which trigger new
            // animation, which sets a new _onEaseEnd. Ensure we don't delete
            // it unintentionally.
            const onEaseEnd = this._onEaseEnd;
            this._onEaseEnd = undefined;
            onEaseEnd.call(this, easeId);
        }
        if (!allowGestures) {
            const handlers = (this     ).handlers;
            if (handlers) handlers.stop(false);
        }
        return this;
    }

    _ease(frame                                 ,
          finish            ,
          options                                                                     ) {
        if (options.animate === false || options.duration === 0) {
            frame(1);
            finish();
        } else {
            this._easeStart = index.exported.now();
            this._easeOptions = options;
            this._onEaseFrame = frame;
            this._onEaseEnd = finish;
            // $FlowFixMe[method-unbinding]
            this._easeFrameId = this._requestRenderFrame(this._renderFrameCallback);
        }
    }

    // Callback for map._requestRenderFrame
    _renderFrameCallback() {
        const t = Math.min((index.exported.now() - this._easeStart) / this._easeOptions.duration, 1);
        const frame = this._onEaseFrame;
        if (frame) frame(this._easeOptions.easing(t));
        if (t < 1) {
            // $FlowFixMe[method-unbinding]
            this._easeFrameId = this._requestRenderFrame(this._renderFrameCallback);
        } else {
            this.stop();
        }
    }

    // convert bearing so that it's numerically close to the current one so that it interpolates properly
    _normalizeBearing(bearing        , currentBearing        )         {
        bearing = index.wrap(bearing, -180, 180);
        const diff = Math.abs(bearing - currentBearing);
        if (Math.abs(bearing - 360 - currentBearing) < diff) bearing -= 360;
        if (Math.abs(bearing + 360 - currentBearing) < diff) bearing += 360;
        return bearing;
    }

    // If a path crossing the antimeridian would be shorter, extend the final coordinate so that
    // interpolating between the two endpoints will cross it.
    _normalizeCenter(center        ) {
        const tr = this.transform;
        if (!tr.renderWorldCopies || tr.maxBounds) return;

        const delta = center.lng - tr.center.lng;
        center.lng +=
            delta > 180 ? -360 :
            delta < -180 ? 360 : 0;
    }

    _prefersReducedMotion(options                   )          {
        const essential = options && options.essential;
        const prefersReducedMotion = this._respectPrefersReducedMotion && index.exported.prefersReducedMotion;
        return prefersReducedMotion && !essential;
    }

    // emulates frame function for some transform
    _emulate(frame          , duration        , initialTransform           )                   {
        const frameRate = 15;
        const numFrames = Math.ceil(duration * frameRate / 1000);

        const transforms = [];
        const emulateFrame = frame(initialTransform.clone());
        for (let i = 0; i <= numFrames; i++) {
            const transform = emulateFrame(i / numFrames);
            transforms.push(transform.clone());
        }

        return transforms;
    }
}

// In debug builds, check that camera change events are fired in the correct order.
// - ___start events needs to be fired before ___ and ___end events
// - another ___start event can't be fired before a ___end event has been fired for the previous one
function addAssertions(camera        ) { //eslint-disable-line
    index.Debug.run(() => {
        const inProgress = {};

        ['drag', 'zoom', 'rotate', 'pitch', 'move'].forEach(name => {
            inProgress[name] = false;

            camera.on(((`${name}start`     )          ), () => {
                index.assert(!inProgress[name], `"${name}start" fired twice without a "${name}end"`);
                inProgress[name] = true;
                index.assert(inProgress.move);
            });

            camera.on(name, () => {
                index.assert(inProgress[name]);
                index.assert(inProgress.move);
            });

            camera.on(((`${name}end`     )          ), () => {
                index.assert(inProgress.move);
                index.assert(inProgress[name]);
                inProgress[name] = false;
            });
        });

        // Canary used to test whether this function is stripped in prod build
        canary = 'canary debug run'; //eslint-disable-line
    });
}

let canary; //eslint-disable-line

//      


                                                    

                
                      
                                              
  

/**
 * An `AttributionControl` control presents the map's [attribution information](https://docs.mapbox.com/help/how-mapbox-works/attribution/).
 * Add this control to a map using {@link Map#addControl}.
 *
 * @implements {IControl}
 * @param {Object} [options]
 * @param {boolean} [options.compact] If `true`, force a compact attribution that shows the full attribution on mouse hover. If `false`, force the full attribution control. The default is a responsive attribution that collapses when the map is less than 640 pixels wide. **Attribution should not be collapsed if it can comfortably fit on the map. `compact` should only be used to modify default attribution when map size makes it impossible to fit [default attribution](https://docs.mapbox.com/help/how-mapbox-works/attribution/) and when the automatic compact resizing for default settings are not sufficient**.
 * @param {string | Array<string>} [options.customAttribution] String or strings to show in addition to any other attributions. You can also set a custom attribution when initializing your map with {@link https://docs.mapbox.com/mapbox-gl-js/api/map/#map-parameters the customAttribution option}.
 * @example
 * const map = new mapboxgl.Map({attributionControl: false})
 *     .addControl(new mapboxgl.AttributionControl({
 *         customAttribution: 'Map design by me'
 *     }));
 */
class AttributionControl {
                     
              
                            
                                 
                                      
                                  
                        
                    
                       

    constructor(options          = {}) {
        this.options = options;

        index.bindAll([
            '_toggleAttribution',
            '_updateEditLink',
            '_updateData',
            '_updateCompact'
        ], this);
    }

    getDefaultPosition()                  {
        return 'bottom-right';
    }

    onAdd(map     )              {
        const compact = this.options && this.options.compact;

        this._map = map;
        this._container = create$1('div', 'mapboxgl-ctrl mapboxgl-ctrl-attrib');
        this._compactButton = create$1('button', 'mapboxgl-ctrl-attrib-button', this._container);
        create$1('span', `mapboxgl-ctrl-icon`, this._compactButton).setAttribute('aria-hidden', 'true');
        this._compactButton.type = 'button';
        // $FlowFixMe[method-unbinding]
        this._compactButton.addEventListener('click', this._toggleAttribution);
        this._setElementTitle(this._compactButton, 'ToggleAttribution');
        this._innerContainer = create$1('div', 'mapboxgl-ctrl-attrib-inner', this._container);
        this._innerContainer.setAttribute('role', 'list');

        if (compact) {
            this._container.classList.add('mapboxgl-compact');
        }

        this._updateAttributions();
        this._updateEditLink();

        // $FlowFixMe[method-unbinding]
        this._map.on('styledata', this._updateData);
        // $FlowFixMe[method-unbinding]
        this._map.on('sourcedata', this._updateData);
        // $FlowFixMe[method-unbinding]
        this._map.on('moveend', this._updateEditLink);

        if (compact === undefined) {
            // $FlowFixMe[method-unbinding]
            this._map.on('resize', this._updateCompact);
            this._updateCompact();
        }

        return this._container;
    }

    onRemove() {
        this._container.remove();

        // $FlowFixMe[method-unbinding]
        this._map.off('styledata', this._updateData);
        // $FlowFixMe[method-unbinding]
        this._map.off('sourcedata', this._updateData);
        // $FlowFixMe[method-unbinding]
        this._map.off('moveend', this._updateEditLink);
        // $FlowFixMe[method-unbinding]
        this._map.off('resize', this._updateCompact);

        this._map = (undefined     );
        this._attribHTML = (undefined     );
    }

    _setElementTitle(element             , title        ) {
        const str = this._map._getUIString(`AttributionControl.${title}`);
        element.setAttribute('aria-label', str);
        element.removeAttribute('title');
        if (element.firstElementChild) element.firstElementChild.setAttribute('title', str);
    }

    _toggleAttribution() {
        if (this._container.classList.contains('mapboxgl-compact-show')) {
            this._container.classList.remove('mapboxgl-compact-show');
            this._compactButton.setAttribute('aria-expanded', 'false');
        } else {
            this._container.classList.add('mapboxgl-compact-show');
            this._compactButton.setAttribute('aria-expanded', 'true');
        }
    }

    _updateEditLink() {
        let editLink = this._editLink;
        if (!editLink) {
            editLink = this._editLink = (this._container.querySelector('.mapbox-improve-map')     );
        }

        const params = [
            {key: 'owner', value: this.styleOwner},
            {key: 'id', value: this.styleId},
            {key: 'access_token', value: this._map._requestManager._customAccessToken || index.config.ACCESS_TOKEN}
        ];

        if (editLink) {
            const paramString = params.reduce((acc, next, i) => {
                if (next.value) {
                    acc += `${next.key}=${next.value}${i < params.length - 1 ? '&' : ''}`;
                }
                return acc;
            }, `?`);
            editLink.href = `${index.config.FEEDBACK_URL}/${paramString}#${getHashString(this._map, true)}`;
            editLink.rel = 'noopener nofollow';
            this._setElementTitle(editLink, 'MapFeedback');
        }
    }

    _updateData(e     ) {
        if (e && (e.sourceDataType === 'metadata' || e.sourceDataType === 'visibility' || e.dataType === 'style')) {
            this._updateAttributions();
            this._updateEditLink();
        }
    }

    _updateAttributions() {
        if (!this._map.style) return;
        let attributions                = [];

        if (this._map.style.stylesheet) {
            const stylesheet      = this._map.style.stylesheet;
            this.styleOwner = stylesheet.owner;
            this.styleId = stylesheet.id;
        }

        const sourceCaches = this._map.style._sourceCaches;
        for (const id in sourceCaches) {
            const sourceCache = sourceCaches[id];
            if (sourceCache.used) {
                const source = sourceCache.getSource();
                if (source.attribution && attributions.indexOf(source.attribution) < 0) {
                    // $FlowFixMe[incompatible-call] - Flow can't infer that attribution is a string
                    attributions.push(source.attribution);
                }
            }
        }

        // remove any entries that are substrings of another entry.
        // first sort by length so that substrings come first
        attributions.sort((a, b) => a.length - b.length);
        attributions = attributions.filter((attrib, i) => {
            for (let j = i + 1; j < attributions.length; j++) {
                if (attributions[j].indexOf(attrib) >= 0) { return false; }
            }
            return true;
        });

        if (this.options.customAttribution) {
            if (Array.isArray(this.options.customAttribution)) {
                attributions = [...this.options.customAttribution, ...attributions];
            } else {
                attributions.unshift(this.options.customAttribution);
            }
        }

        // check if attribution string is different to minimize DOM changes
        const attribHTML = attributions.join(' | ');
        if (attribHTML === this._attribHTML) return;

        this._attribHTML = attribHTML;

        if (attributions.length) {
            this._innerContainer.innerHTML = attribHTML;
            this._container.classList.remove('mapboxgl-attrib-empty');
        } else {
            this._container.classList.add('mapboxgl-attrib-empty');
        }
        // remove old DOM node from _editLink
        this._editLink = null;
    }

    _updateCompact() {
        if (this._map.getCanvasContainer().offsetWidth <= 640) {
            this._container.classList.add('mapboxgl-compact');
        } else {
            this._container.classList.remove('mapboxgl-compact', 'mapboxgl-compact-show');
        }
    }

}

//      


                                                    

/**
 * A `LogoControl` is a control that adds the Mapbox watermark
 * to the map as required by the [terms of service](https://www.mapbox.com/tos/) for Mapbox
 * vector tiles and core styles.
 * Add this control to a map using {@link Map#addControl}.
 *
 * @implements {IControl}
 * @private
**/

class LogoControl {
              
                            

    constructor() {
        index.bindAll(['_updateLogo', '_updateCompact'], this);
    }

    onAdd(map     )              {
        this._map = map;
        this._container = create$1('div', 'mapboxgl-ctrl');
        const anchor = create$1('a', 'mapboxgl-ctrl-logo');
        anchor.target = "_blank";
        anchor.rel = "noopener nofollow";
        anchor.href = "https://www.mapbox.com/";
        anchor.setAttribute("aria-label", this._map._getUIString('LogoControl.Title'));
        anchor.setAttribute("rel", "noopener nofollow");
        this._container.appendChild(anchor);
        this._container.style.display = 'none';

        // $FlowFixMe[method-unbinding]
        this._map.on('sourcedata', this._updateLogo);
        this._updateLogo();

        // $FlowFixMe[method-unbinding]
        this._map.on('resize', this._updateCompact);
        this._updateCompact();

        return this._container;
    }

    onRemove() {
        this._container.remove();
        // $FlowFixMe[method-unbinding]
        this._map.off('sourcedata', this._updateLogo);
        // $FlowFixMe[method-unbinding]
        this._map.off('resize', this._updateCompact);
    }

    getDefaultPosition()                  {
        return 'bottom-left';
    }

    _updateLogo(e     ) {
        if (!e || e.sourceDataType === 'metadata') {
            this._container.style.display = this._logoRequired() ? 'block' : 'none';
        }
    }

    _logoRequired()          {
        if (!this._map.style) return true;
        const sourceCaches = this._map.style._sourceCaches;
        if (Object.entries(sourceCaches).length === 0) return true;
        for (const id in sourceCaches) {
            const source = sourceCaches[id].getSource();
            if (source.hasOwnProperty('mapbox_logo') && !source.mapbox_logo) {
                return false;
            }
        }

        return true;
    }

    _updateCompact() {
        const containerChildren = this._container.children;
        if (containerChildren.length) {
            const anchor = containerChildren[0];
            if (this._map.getCanvasContainer().offsetWidth < 250) {
                anchor.classList.add('mapboxgl-compact');
            } else {
                anchor.classList.remove('mapboxgl-compact');
            }
        }
    }

}

//       strict

                             // can't mark opaque due to https://github.com/flowtype/flow-remove-types/pull/61
             
                                          
               
                       
  

class TaskQueue {
                        
                
                      
                                           

    constructor()  {
        this._queue = [];
        this._id = 0;
        this._cleared = false;
        this._currentlyRunning = false;
    }

    add(callback                             )         {
        const id = ++this._id;
        const queue = this._queue;
        queue.push({callback, id, cancelled: false});
        return id;
    }

    remove(id        ) {
        const running = this._currentlyRunning;
        const queue = running ? this._queue.concat(running) : this._queue;
        for (const task of queue) {
            if (task.id === id) {
                task.cancelled = true;
                return;
            }
        }
    }

    run(timeStamp         = 0) {
        index.assert(!this._currentlyRunning);
        const queue = this._currentlyRunning = this._queue;

        // Tasks queued by callbacks in the current queue should be executed
        // on the next run, not the current run.
        this._queue = [];

        for (const task of queue) {
            if (task.cancelled) continue;
            task.callback(timeStamp);
            if (this._cleared) break;
        }

        this._cleared = false;
        this._currentlyRunning = false;
    }

    clear() {
        if (this._currentlyRunning) {
            this._cleared = true;
        }
        this._queue = [];
    }
}

//      


                                                
                                                 

/**
 * Given a LngLat, prior projected position, and a transform, return a new LngLat shifted
 * n × 360° east or west for some n ≥ 0 such that:
 *
 * * the projected location of the result is on screen, if possible, and secondarily:
 * * the difference between the projected location of the result and the prior position
 *   is minimized.
 *
 * The object is to preserve perceived object constancy for Popups and Markers as much as
 * possible; they should avoid shifting large distances across the screen, even when the
 * map center changes by ±360° due to automatic wrapping, and when about to go off screen,
 * should wrap just enough to avoid doing so.
 *
 * @private
 */
function smartWrap(lngLat        , priorPos        , transform           )         {
    lngLat = new index.LngLat(lngLat.lng, lngLat.lat);

    // First, try shifting one world in either direction, and see if either is closer to the
    // prior position. Don't shift away if it new position is further from center.
    // This preserves object constancy when the map center is auto-wrapped during animations,
    // but don't allow it to run away on horizon (points towards horizon get closer and closer).
    if (priorPos) {
        const left  = new index.LngLat(lngLat.lng - 360, lngLat.lat);
        const right = new index.LngLat(lngLat.lng + 360, lngLat.lat);
        // Unless offscreen, keep the marker within same wrap distance to center. This is to prevent
        // running it to infinity `lng` near horizon when bearing is ~90°.
        const withinWrap =  Math.ceil(Math.abs(lngLat.lng - transform.center.lng) / 360) * 360;
        const delta = transform.locationPoint(lngLat).distSqr(priorPos);
        const offscreen = priorPos.x < 0 || priorPos.y < 0 || priorPos.x > transform.width || priorPos.y > transform.height;
        if (transform.locationPoint(left).distSqr(priorPos) < delta && (offscreen || Math.abs(left.lng - transform.center.lng) < withinWrap)) {
            lngLat = left;
        } else if (transform.locationPoint(right).distSqr(priorPos) < delta && (offscreen || Math.abs(right.lng - transform.center.lng) < withinWrap)) {
            lngLat = right;
        }
    }

    // Second, wrap toward the center until the new position is on screen, or we can't get
    // any closer.
    while (Math.abs(lngLat.lng - transform.center.lng) > 180) {
        const pos = transform.locationPoint(lngLat);
        if (pos.x >= 0 && pos.y >= 0 && pos.x <= transform.width && pos.y <= transform.height) {
            break;
        }
        if (lngLat.lng > transform.center.lng) {
            lngLat.lng -= 360;
        } else {
            lngLat.lng += 360;
        }
    }

    return lngLat;
}

//      

                    
              
           
              
            
             
                
                 
                   
                     

const anchorTranslate                        = {
    'center': 'translate(-50%,-50%)',
    'top': 'translate(-50%,0)',
    'top-left': 'translate(0,0)',
    'top-right': 'translate(-100%,0)',
    'bottom': 'translate(-50%,-100%)',
    'bottom-left': 'translate(0,-100%)',
    'bottom-right': 'translate(-100%,-100%)',
    'left': 'translate(0,-50%)',
    'right': 'translate(-100%,-50%)'
};

//      


                
                          
                       
                    
                   
                   
                        
                            
                      
                               
                            
                            
  

/**
 * Creates a marker component.
 *
 * @param {Object} [options]
 * @param {HTMLElement} [options.element] DOM element to use as a marker. The default is a light blue, droplet-shaped SVG marker.
 * @param {string} [options.anchor='center'] A string indicating the part of the Marker that should be positioned closest to the coordinate set via {@link Marker#setLngLat}.
 *   Options are `'center'`, `'top'`, `'bottom'`, `'left'`, `'right'`, `'top-left'`, `'top-right'`, `'bottom-left'`, and `'bottom-right'`.
 * @param {PointLike} [options.offset] The offset in pixels as a {@link PointLike} object to apply relative to the element's center. Negatives indicate left and up.
 * @param {string} [options.color='#3FB1CE'] The color to use for the default marker if `options.element` is not provided. The default is light blue.
 * @param {number} [options.scale=1] The scale to use for the default marker if `options.element` is not provided. The default scale corresponds to a height of `41px` and a width of `27px`.
 * @param {boolean} [options.draggable=false] A boolean indicating whether or not a marker is able to be dragged to a new position on the map.
 * @param {number} [options.clickTolerance=0] The max number of pixels a user can shift the mouse pointer during a click on the marker for it to be considered a valid click (as opposed to a marker drag). The default is to inherit map's `clickTolerance`.
 * @param {number} [options.rotation=0] The rotation angle of the marker in degrees, relative to its respective `rotationAlignment` setting. A positive value will rotate the marker clockwise.
 * @param {string} [options.pitchAlignment='auto'] `'map'` aligns the `Marker` to the plane of the map. `'viewport'` aligns the `Marker` to the plane of the viewport. `'auto'` automatically matches the value of `rotationAlignment`.
 * @param {string} [options.rotationAlignment='auto'] The alignment of the marker's rotation.`'map'` is aligned with the map plane, consistent with the cardinal directions as the map rotates. `'viewport'` is screenspace-aligned. `'horizon'` is aligned according to the nearest horizon, on non-globe projections it is equivalent to `'viewport'`. `'auto'` is equivalent to `'viewport'`.
 * @param {number} [options.occludedOpacity=0.2] The opacity of a marker that's occluded by 3D terrain.
 * @example
 * // Create a new marker.
 * const marker = new mapboxgl.Marker()
 *     .setLngLat([30.5, 50.5])
 *     .addTo(map);
 * @example
 * // Set marker options.
 * const marker = new mapboxgl.Marker({
 *     color: "#FFFFFF",
 *     draggable: true
 * }).setLngLat([30.5, 50.5])
 *     .addTo(map);
 * @see [Example: Add custom icons with Markers](https://www.mapbox.com/mapbox-gl-js/example/custom-marker-icons/)
 * @see [Example: Create a draggable Marker](https://www.mapbox.com/mapbox-gl-js/example/drag-a-marker/)
 */
class Marker extends index.Evented {
               
                    
                   
                          
                   
                    
                 
                   
                   
                            
                        
                            
                         
                                               // used for handling drag events
                           
                            
                      
                            
                               
                                // original tabindex of _element
                           
                           
                              
                             

    constructor(options          , legacyOptions          ) {
        super();
        // For backward compatibility -- the constructor used to accept the element as a
        // required first argument, before it was made optional.
        if (options instanceof index.window.HTMLElement || legacyOptions) {
            options = index.extend({element: options}, legacyOptions);
        }

        index.bindAll([
            '_update',
            '_onMove',
            '_onUp',
            '_addDragHandler',
            '_onMapClick',
            '_onKeyPress',
            '_clearFadeTimer'
        ], this);

        this._anchor = (options && options.anchor) || 'center';
        this._color = (options && options.color) || '#3FB1CE';
        this._scale = (options && options.scale) || 1;
        this._draggable = (options && options.draggable) || false;
        this._clickTolerance = (options && options.clickTolerance) || 0;
        this._isDragging = false;
        this._state = 'inactive';
        this._rotation = (options && options.rotation) || 0;
        this._rotationAlignment = (options && options.rotationAlignment) || 'auto';
        this._pitchAlignment = (options && options.pitchAlignment && options.pitchAlignment) || 'auto';
        this._updateMoving = () => this._update(true);
        this._occludedOpacity = (options && options.occludedOpacity) || 0.2;

        if (!options || !options.element) {
            this._defaultMarker = true;
            this._element = create$1('div');

            // create default map marker SVG

            const DEFAULT_HEIGHT = 41;
            const DEFAULT_WIDTH = 27;

            const svg = createSVG('svg', {
                display: 'block',
                height: `${DEFAULT_HEIGHT * this._scale}px`,
                width: `${DEFAULT_WIDTH * this._scale}px`,
                viewBox: `0 0 ${DEFAULT_WIDTH} ${DEFAULT_HEIGHT}`
            }, this._element);

            const gradient = createSVG('radialGradient', {id: 'shadowGradient'}, createSVG('defs', {}, svg));
            createSVG('stop', {offset: '10%', 'stop-opacity': 0.4}, gradient);
            createSVG('stop', {offset: '100%', 'stop-opacity': 0.05}, gradient);
            createSVG('ellipse', {cx: 13.5, cy: 34.8, rx: 10.5, ry: 5.25, fill: 'url(#shadowGradient)'}, svg); // shadow

            createSVG('path', { // marker shape
                fill: this._color,
                d: 'M27,13.5C27,19.07 20.25,27 14.75,34.5C14.02,35.5 12.98,35.5 12.25,34.5C6.75,27 0,19.22 0,13.5C0,6.04 6.04,0 13.5,0C20.96,0 27,6.04 27,13.5Z'
            }, svg);
            createSVG('path', { // border
                opacity: 0.25,
                d: 'M13.5,0C6.04,0 0,6.04 0,13.5C0,19.22 6.75,27 12.25,34.5C13,35.52 14.02,35.5 14.75,34.5C20.25,27 27,19.07 27,13.5C27,6.04 20.96,0 13.5,0ZM13.5,1C20.42,1 26,6.58 26,13.5C26,15.9 24.5,19.18 22.22,22.74C19.95,26.3 16.71,30.14 13.94,33.91C13.74,34.18 13.61,34.32 13.5,34.44C13.39,34.32 13.26,34.18 13.06,33.91C10.28,30.13 7.41,26.31 5.02,22.77C2.62,19.23 1,15.95 1,13.5C1,6.58 6.58,1 13.5,1Z'
            }, svg);

            createSVG('circle', {fill: 'white', cx: 13.5, cy: 13.5, r: 5.5}, svg); // circle

            // if no element and no offset option given apply an offset for the default marker
            // the -14 as the y value of the default marker offset was determined as follows
            //
            // the marker tip is at the center of the shadow ellipse from the default svg
            // the y value of the center of the shadow ellipse relative to the svg top left is 34.8
            // offset to the svg center "height (41 / 2)" gives 34.8 - (41 / 2) and rounded for an integer pixel offset gives 14
            // negative is used to move the marker up from the center so the tip is at the Marker lngLat
            this._offset = index.Point.convert((options && options.offset) || [0, -14]);
        } else {
            this._element = options.element;
            this._offset = index.Point.convert((options && options.offset) || [0, 0]);
        }

        if (!this._element.hasAttribute('aria-label')) this._element.setAttribute('aria-label', 'Map marker');
        this._element.classList.add('mapboxgl-marker');
        this._element.addEventListener('dragstart', (e           ) => {
            e.preventDefault();
        });
        this._element.addEventListener('mousedown', (e            ) => {
            // prevent focusing on click
            e.preventDefault();
        });
        const classList = this._element.classList;
        for (const key in anchorTranslate) {
            classList.remove(`mapboxgl-marker-anchor-${key}`);
        }
        classList.add(`mapboxgl-marker-anchor-${this._anchor}`);

        this._popup = null;
    }

    /**
     * Attaches the `Marker` to a `Map` object.
     *
     * @param {Map} map The Mapbox GL JS map to add the marker to.
     * @returns {Marker} Returns itself to allow for method chaining.
     * @example
     * const marker = new mapboxgl.Marker()
     *     .setLngLat([30.5, 50.5])
     *     .addTo(map); // add the marker to the map
     */
    addTo(map     )       {
        if (map === this._map) {
            return this;
        }
        this.remove();
        this._map = map;
        map.getCanvasContainer().appendChild(this._element);
        map.on('move', this._updateMoving);
        // $FlowFixMe[method-unbinding]
        map.on('moveend', this._update);
        // $FlowFixMe[method-unbinding]
        map.on('remove', this._clearFadeTimer);
        map._addMarker(this);
        this.setDraggable(this._draggable);
        this._update();

        // If we attached the `click` listener to the marker element, the popup
        // would close once the event propogated to `map` due to the
        // `Popup#_onClickClose` listener.
        // $FlowFixMe[method-unbinding]
        map.on('click', this._onMapClick);

        return this;
    }

    /**
     * Removes the marker from a map.
     *
     * @example
     * const marker = new mapboxgl.Marker().addTo(map);
     * marker.remove();
     * @returns {Marker} Returns itself to allow for method chaining.
     */
    remove()       {
        const map = this._map;
        if (map) {
            // $FlowFixMe[method-unbinding]
            map.off('click', this._onMapClick);
            map.off('move', this._updateMoving);
            // $FlowFixMe[method-unbinding]
            map.off('moveend', this._update);
            // $FlowFixMe[method-unbinding]
            map.off('mousedown', this._addDragHandler);
            // $FlowFixMe[method-unbinding]
            map.off('touchstart', this._addDragHandler);
            // $FlowFixMe[method-unbinding]
            map.off('mouseup', this._onUp);
            // $FlowFixMe[method-unbinding]
            map.off('touchend', this._onUp);
            // $FlowFixMe[method-unbinding]
            map.off('mousemove', this._onMove);
            // $FlowFixMe[method-unbinding]
            map.off('touchmove', this._onMove);
            // $FlowFixMe[method-unbinding]
            map.off('remove', this._clearFadeTimer);
            map._removeMarker(this);
            this._map = undefined;
        }
        this._clearFadeTimer();
        this._element.remove();
        if (this._popup) this._popup.remove();
        return this;
    }

    /**
     * Get the marker's geographical location.
     *
     * The longitude of the result may differ by a multiple of 360 degrees from the longitude previously
     * set by `setLngLat` because `Marker` wraps the anchor longitude across copies of the world to keep
     * the marker on screen.
     *
     * @returns {LngLat} A {@link LngLat} describing the marker's location.
    * @example
    * // Store the marker's longitude and latitude coordinates in a variable
    * const lngLat = marker.getLngLat();
    * // Print the marker's longitude and latitude values in the console
    * console.log(`Longitude: ${lngLat.lng}, Latitude: ${lngLat.lat}`);
    * @see [Example: Create a draggable Marker](https://docs.mapbox.com/mapbox-gl-js/example/drag-a-marker/)
    */
    getLngLat()         {
        return this._lngLat;
    }

    /**
    * Set the marker's geographical position and move it.
     *
    * @param {LngLat} lnglat A {@link LngLat} describing where the marker should be located.
    * @returns {Marker} Returns itself to allow for method chaining.
    * @example
    * // Create a new marker, set the longitude and latitude, and add it to the map.
    * new mapboxgl.Marker()
    *     .setLngLat([-65.017, -16.457])
    *     .addTo(map);
    * @see [Example: Add custom icons with Markers](https://docs.mapbox.com/mapbox-gl-js/example/custom-marker-icons/)
    * @see [Example: Create a draggable Marker](https://docs.mapbox.com/mapbox-gl-js/example/drag-a-marker/)
    * @see [Example: Add a marker using a place name](https://docs.mapbox.com/mapbox-gl-js/example/marker-from-geocode/)
    */
    setLngLat(lnglat            )       {
        this._lngLat = index.LngLat.convert(lnglat);
        this._pos = null;
        if (this._popup) this._popup.setLngLat(this._lngLat);
        this._update(true);
        return this;
    }

    /**
     * Returns the `Marker`'s HTML element.
     *
     * @returns {HTMLElement} Returns the marker element.
     * @example
     * const element = marker.getElement();
     */
    getElement()              {
        return this._element;
    }

    /**
     * Binds a {@link Popup} to the {@link Marker}.
     *
     * @param {Popup | null} popup An instance of the {@link Popup} class. If undefined or null, any popup
     * set on this {@link Marker} instance is unset.
     * @returns {Marker} Returns itself to allow for method chaining.
     * @example
     * const marker = new mapboxgl.Marker()
     *     .setLngLat([0, 0])
     *     .setPopup(new mapboxgl.Popup().setHTML("<h1>Hello World!</h1>")) // add popup
     *     .addTo(map);
     * @see [Example: Attach a popup to a marker instance](https://docs.mapbox.com/mapbox-gl-js/example/set-popup/)
     */
    setPopup(popup        )       {
        if (this._popup) {
            this._popup.remove();
            this._popup = null;
            this._element.removeAttribute('role');
            // $FlowFixMe[method-unbinding]
            this._element.removeEventListener('keypress', this._onKeyPress);

            if (!this._originalTabIndex) {
                this._element.removeAttribute('tabindex');
            }
        }

        if (popup) {
            if (!('offset' in popup.options)) {
                const markerHeight = 41 - (5.8 / 2);
                const markerRadius = 13.5;
                const linearOffset = Math.sqrt(Math.pow(markerRadius, 2) / 2);
                popup.options.offset = this._defaultMarker ? {
                    'top': [0, 0],
                    'top-left': [0, 0],
                    'top-right': [0, 0],
                    'bottom': [0, -markerHeight],
                    'bottom-left': [linearOffset, (markerHeight - markerRadius + linearOffset) * -1],
                    'bottom-right': [-linearOffset, (markerHeight - markerRadius + linearOffset) * -1],
                    'left': [markerRadius, (markerHeight - markerRadius) * -1],
                    'right': [-markerRadius, (markerHeight - markerRadius) * -1]
                } : this._offset;
            }
            this._popup = popup;
            popup._marker = this;
            if (this._lngLat) this._popup.setLngLat(this._lngLat);

            this._element.setAttribute('role', 'button');
            this._originalTabIndex = this._element.getAttribute('tabindex');
            if (!this._originalTabIndex) {
                this._element.setAttribute('tabindex', '0');
            }
            // $FlowFixMe[method-unbinding]
            this._element.addEventListener('keypress', this._onKeyPress);
            this._element.setAttribute('aria-expanded', 'false');
        }

        return this;
    }

    _onKeyPress(e               ) {
        const code = e.code;
        const legacyCode = e.charCode || e.keyCode;

        if (
            (code === 'Space') || (code === 'Enter') ||
            (legacyCode === 32) || (legacyCode === 13) // space or enter
        ) {
            this.togglePopup();
        }
    }

    _onMapClick(e               ) {
        const targetElement = e.originalEvent.target;
        const element = this._element;

        if (this._popup && (targetElement === element || element.contains((targetElement     )))) {
            this.togglePopup();
        }
    }

    /**
     * Returns the {@link Popup} instance that is bound to the {@link Marker}.
     *
     * @returns {Popup} Returns the popup.
     * @example
     * const marker = new mapboxgl.Marker()
     *     .setLngLat([0, 0])
     *     .setPopup(new mapboxgl.Popup().setHTML("<h1>Hello World!</h1>"))
     *     .addTo(map);
     *
     * console.log(marker.getPopup()); // return the popup instance
     */
    getPopup()         {
        return this._popup;
    }

    /**
     * Opens or closes the {@link Popup} instance that is bound to the {@link Marker}, depending on the current state of the {@link Popup}.
     *
     * @returns {Marker} Returns itself to allow for method chaining.
     * @example
     * const marker = new mapboxgl.Marker()
     *     .setLngLat([0, 0])
     *     .setPopup(new mapboxgl.Popup().setHTML("<h1>Hello World!</h1>"))
     *     .addTo(map);
     *
     * marker.togglePopup(); // toggle popup open or closed
     */
    togglePopup()       {
        const popup = this._popup;
        if (!popup) {
            return this;
        } else if (popup.isOpen()) {
            popup.remove();
            this._element.setAttribute('aria-expanded', 'false');
        } else if (this._map) {
            popup.addTo(this._map);
            this._element.setAttribute('aria-expanded', 'true');
        }
        return this;
    }

    _behindTerrain()          {
        const map = this._map;
        const pos = this._pos;
        if (!map || !pos) return false;
        const unprojected = map.unproject(pos);
        const camera = map.getFreeCameraOptions();
        if (!camera.position) return false;
        const cameraLngLat = camera.position.toLngLat();
        const toClosestSurface = cameraLngLat.distanceTo(unprojected);
        const toMarker = cameraLngLat.distanceTo(this._lngLat);
        return toClosestSurface < toMarker * 0.9;

    }

    _evaluateOpacity() {
        const map = this._map;
        if (!map) return;

        const pos = this._pos;

        if (!pos || pos.x < 0 || pos.x > map.transform.width || pos.y < 0 || pos.y > map.transform.height) {
            this._clearFadeTimer();
            return;
        }
        const mapLocation = map.unproject(pos);
        let opacity;
        if (map._showingGlobe() && index.isLngLatBehindGlobe(map.transform, this._lngLat)) {
            opacity = 0;
        } else {
            opacity = 1 - map._queryFogOpacity(mapLocation);
            if (map.transform._terrainEnabled() && map.getTerrain() && this._behindTerrain()) {
                opacity *= this._occludedOpacity;
            }
        }

        this._element.style.opacity = `${opacity}`;
        this._element.style.pointerEvents = opacity > 0 ? 'auto' : 'none';
        if (this._popup) {
            this._popup._setOpacity(opacity);
        }

        this._fadeTimer = null;
    }

    _clearFadeTimer() {
        if (this._fadeTimer) {
            clearTimeout(this._fadeTimer);
            this._fadeTimer = null;
        }
    }

    _updateDOM() {
        const pos = this._pos;
        const map = this._map;
        if (!pos || !map) { return; }

        const offset = this._offset.mult(this._scale);

        this._element.style.transform = `
            translate(${pos.x}px,${pos.y}px)
            ${anchorTranslate[this._anchor]}
            ${this._calculateXYTransform()} ${this._calculateZTransform()}
            translate(${offset.x}px,${offset.y}px)
        `;
    }

    _calculateXYTransform()         {
        const pos = this._pos;
        const map = this._map;
        const alignment = this.getPitchAlignment();

        // `viewport', 'auto' and invalid arugments do no pitch transformation.
        if (!map || !pos || alignment !== 'map') {
            return ``;
        }
        // 'map' alignment on a flat map
        if (!map._showingGlobe()) {
            const pitch = map.getPitch();
            return pitch ? `rotateX(${pitch}deg)` : '';
        }
        // 'map' alignment on globe
        const tilt = index.radToDeg(index.globeTiltAtLngLat(map.transform, this._lngLat));
        const posFromCenter = pos.sub(index.globeCenterToScreenPoint(map.transform));
        const manhattanDistance = (Math.abs(posFromCenter.x) + Math.abs(posFromCenter.y));
        if (manhattanDistance === 0) { return ''; }

        const tiltOverDist =  tilt / manhattanDistance;
        const yTilt = posFromCenter.x * tiltOverDist;
        const xTilt = -posFromCenter.y * tiltOverDist;
        return `rotateX(${xTilt}deg) rotateY(${yTilt}deg)`;

    }

    _calculateZTransform()         {

        const pos = this._pos;
        const map = this._map;
        if (!map || !pos) { return ''; }

        let rotation = 0;
        const alignment = this.getRotationAlignment();
        if (alignment === 'map') {
            if (map._showingGlobe()) {
                const north = map.project(new index.LngLat(this._lngLat.lng, this._lngLat.lat + .001));
                const south = map.project(new index.LngLat(this._lngLat.lng, this._lngLat.lat - .001));
                const diff = south.sub(north);
                rotation = index.radToDeg(Math.atan2(diff.y, diff.x)) - 90;
            } else {
                rotation = -map.getBearing();
            }
        } else if (alignment === 'horizon') {
            const ALIGN_TO_HORIZON_BELOW_ZOOM = 4;
            const ALIGN_TO_SCREEN_ABOVE_ZOOM = 6;
            index.assert(ALIGN_TO_SCREEN_ABOVE_ZOOM <= index.GLOBE_ZOOM_THRESHOLD_MAX, 'Horizon-oriented marker transition should be complete when globe switches to Mercator');
            index.assert(ALIGN_TO_HORIZON_BELOW_ZOOM <= ALIGN_TO_SCREEN_ABOVE_ZOOM);

            const smooth = index.smoothstep(ALIGN_TO_HORIZON_BELOW_ZOOM, ALIGN_TO_SCREEN_ABOVE_ZOOM, map.getZoom());

            const centerPoint = index.globeCenterToScreenPoint(map.transform);
            centerPoint.y += smooth * map.transform.height;
            const rel = pos.sub(centerPoint);
            const angle = index.radToDeg(Math.atan2(rel.y, rel.x));
            const up = angle > 90 ? angle - 270 : angle + 90;
            rotation = up * (1 - smooth);
        }

        rotation += this._rotation;
        return rotation ? `rotateZ(${rotation}deg)` : '';
    }

    _update(delaySnap          ) {
        index.window.cancelAnimationFrame(this._updateFrameId);
        const map = this._map;
        if (!map) return;

        if (map.transform.renderWorldCopies) {
            this._lngLat = smartWrap(this._lngLat, this._pos, map.transform);
        }

        this._pos = map.project(this._lngLat);

        // because rounding the coordinates at every `move` event causes stuttered zooming
        // we only round them when _update is called with `moveend` or when its called with
        // no arguments (when the Marker is initialized or Marker#setLngLat is invoked).
        if (delaySnap === true) {
            this._updateFrameId = index.window.requestAnimationFrame(() => {
                if (this._element && this._pos && this._anchor) {
                    this._pos = this._pos.round();
                    this._updateDOM();
                }
            });
        } else {
            this._pos = this._pos.round();
        }

        map._requestDomTask(() => {
            if (!this._map) return;

            if (this._element && this._pos && this._anchor) {
                this._updateDOM();
            }

            if ((map._showingGlobe() || map.getTerrain() || map.getFog()) && !this._fadeTimer) {
                // $FlowFixMe[method-unbinding]
                this._fadeTimer = setTimeout(this._evaluateOpacity.bind(this), 60);
            }
        });
    }

    /**
     * Get the marker's offset.
     *
     * @returns {Point} The marker's screen coordinates in pixels.
     * @example
     * const offset = marker.getOffset();
     */
    getOffset()        {
        return this._offset;
    }

    /**
     * Sets the offset of the marker.
     *
     * @param {PointLike} offset The offset in pixels as a {@link PointLike} object to apply relative to the element's center. Negatives indicate left and up.
     * @returns {Marker} Returns itself to allow for method chaining.
     * @example
     * marker.setOffset([0, 1]);
     */
    setOffset(offset           )       {
        this._offset = index.Point.convert(offset);
        this._update();
        return this;
    }

    _onMove(e                               ) {
        const map = this._map;
        if (!map) return;

        const startPos = this._pointerdownPos;
        const posDelta = this._positionDelta;
        if (!startPos || !posDelta) return;

        if (!this._isDragging) {
            const clickTolerance = this._clickTolerance || map._clickTolerance;
            if (e.point.dist(startPos) < clickTolerance) return;
            this._isDragging = true;
        }

        this._pos = e.point.sub(posDelta);
        this._lngLat = map.unproject(this._pos);
        this.setLngLat(this._lngLat);
        // suppress click event so that popups don't toggle on drag
        this._element.style.pointerEvents = 'none';

        // make sure dragstart only fires on the first move event after mousedown.
        // this can't be on mousedown because that event doesn't necessarily
        // imply that a drag is about to happen.
        if (this._state === 'pending') {
            this._state = 'active';

            /**
             * Fired when dragging starts.
             *
             * @event dragstart
             * @memberof Marker
             * @instance
             * @type {Object}
             * @property {Marker} marker The object that is being dragged.
             */
            this.fire(new index.Event('dragstart'));
        }

        /**
         * Fired while dragging.
         *
         * @event drag
         * @memberof Marker
         * @instance
         * @type {Object}
         * @property {Marker} marker The object that is being dragged.
         */
        this.fire(new index.Event('drag'));
    }

    _onUp() {
        // revert to normal pointer event handling
        this._element.style.pointerEvents = 'auto';
        this._positionDelta = null;
        this._pointerdownPos = null;
        this._isDragging = false;

        const map = this._map;
        if (map) {
            // $FlowFixMe[method-unbinding]
            map.off('mousemove', this._onMove);
            // $FlowFixMe[method-unbinding]
            map.off('touchmove', this._onMove);
        }

        // only fire dragend if it was preceded by at least one drag event
        if (this._state === 'active') {
            /**
            * Fired when the marker is finished being dragged.
            *
            * @event dragend
            * @memberof Marker
            * @instance
            * @type {Object}
            * @property {Marker} marker The object that was dragged.
            */
            this.fire(new index.Event('dragend'));
        }

        this._state = 'inactive';
    }

    _addDragHandler(e                               ) {
        const map = this._map;
        const pos = this._pos;
        if (!map || !pos) return;

        if (this._element.contains((e.originalEvent.target     ))) {
            e.preventDefault();

            // We need to calculate the pixel distance between the click point
            // and the marker position, with the offset accounted for. Then we
            // can subtract this distance from the mousemove event's position
            // to calculate the new marker position.
            // If we don't do this, the marker 'jumps' to the click position
            // creating a jarring UX effect.
            this._positionDelta = e.point.sub(pos);
            this._pointerdownPos = e.point;

            this._state = 'pending';
            // $FlowFixMe[method-unbinding]
            map.on('mousemove', this._onMove);
            // $FlowFixMe[method-unbinding]
            map.on('touchmove', this._onMove);
            // $FlowFixMe[method-unbinding]
            map.once('mouseup', this._onUp);
            // $FlowFixMe[method-unbinding]
            map.once('touchend', this._onUp);
        }
    }

    /**
     * Sets the `draggable` property and functionality of the marker.
     *
     * @param {boolean} [shouldBeDraggable=false] Turns drag functionality on/off.
     * @returns {Marker} Returns itself to allow for method chaining.
     * @example
     * marker.setDraggable(true);
     */
    setDraggable(shouldBeDraggable         )       {
        this._draggable = !!shouldBeDraggable; // convert possible undefined value to false

        // handle case where map may not exist yet
        // for example, when setDraggable is called before addTo
        const map = this._map;
        if (map) {
            if (shouldBeDraggable) {
                // $FlowFixMe[method-unbinding]
                map.on('mousedown', this._addDragHandler);
                // $FlowFixMe[method-unbinding]
                map.on('touchstart', this._addDragHandler);
            } else {
                // $FlowFixMe[method-unbinding]
                map.off('mousedown', this._addDragHandler);
                // $FlowFixMe[method-unbinding]
                map.off('touchstart', this._addDragHandler);
            }
        }

        return this;
    }

    /**
     * Returns true if the marker can be dragged.
     *
     * @returns {boolean} True if the marker is draggable.
     * @example
     * const isMarkerDraggable = marker.isDraggable();
     */
    isDraggable()          {
        return this._draggable;
    }

    /**
     * Sets the `rotation` property of the marker.
     *
     * @param {number} [rotation=0] The rotation angle of the marker (clockwise, in degrees), relative to its respective {@link Marker#setRotationAlignment} setting.
     * @returns {Marker} Returns itself to allow for method chaining.
     * @example
     * marker.setRotation(45);
     */
    setRotation(rotation        )       {
        this._rotation = rotation || 0;
        this._update();
        return this;
    }

    /**
     * Returns the current rotation angle of the marker (in degrees).
     *
     * @returns {number} The current rotation angle of the marker.
     * @example
     * const rotation = marker.getRotation();
     */
    getRotation()         {
        return this._rotation;
    }

    /**
     * Sets the `rotationAlignment` property of the marker.
     *
     * @param {string} [alignment='auto'] Sets the `rotationAlignment` property of the marker.
     * @returns {Marker} Returns itself to allow for method chaining.
     * @example
     * marker.setRotationAlignment('viewport');
     */
    setRotationAlignment(alignment        )       {
        this._rotationAlignment = alignment || 'auto';
        this._update();
        return this;
    }

    /**
     * Returns the current `rotationAlignment` property of the marker.
     *
     * @returns {string} The current rotational alignment of the marker.
     * @example
     * const alignment = marker.getRotationAlignment();
     */
    getRotationAlignment()         {
        if (this._rotationAlignment === 'auto')
            return 'viewport';
        if (this._rotationAlignment === 'horizon' && this._map && !this._map._showingGlobe())
            return 'viewport';
        return this._rotationAlignment;
    }

    /**
     * Sets the `pitchAlignment` property of the marker.
     *
     * @param {string} [alignment] Sets the `pitchAlignment` property of the marker. If alignment is 'auto', it will automatically match `rotationAlignment`.
     * @returns {Marker} Returns itself to allow for method chaining.
     * @example
     * marker.setPitchAlignment('map');
     */
    setPitchAlignment(alignment        )       {
        this._pitchAlignment = alignment || 'auto';
        this._update();
        return this;
    }

    /**
     * Returns the current `pitchAlignment` behavior of the marker.
     *
     * @returns {string} The current pitch alignment of the marker.
     * @example
     * const alignment = marker.getPitchAlignment();
     */
    getPitchAlignment()         {
        if (this._pitchAlignment === 'auto') {
            return this.getRotationAlignment();
        }
        return this._pitchAlignment;
    }

    /**
     * Sets the `occludedOpacity` property of the marker.
     * This opacity is used on the marker when the marker is occluded by terrain.
     *
     * @param {number} [opacity=0.2] Sets the `occludedOpacity` property of the marker.
     * @returns {Marker} Returns itself to allow for method chaining.
     * @example
     * marker.setOccludedOpacity(0.3);
     */
    setOccludedOpacity(opacity        )       {
        this._occludedOpacity = opacity || 0.2;
        this._update();
        return this;
    }

    /**
     * Returns the current `occludedOpacity` of the marker.
     *
     * @returns {number} The opacity of a terrain occluded marker.
     * @example
     * const opacity = marker.getOccludedOpacity();
     */
    getOccludedOpacity()         {
        return this._occludedOpacity;
    }
}

//      


                                
                                                  
                                                      
                                      

const defaultOptions$4 = {
    closeButton: true,
    closeOnClick: true,
    focusAfterOpen: true,
    className: '',
    maxWidth: "240px"
};

                                                                   

                            
                          
                           
                          
                             
                    
                    
                       
                     
  

const focusQuerySelector = [
    "a[href]",
    "[tabindex]:not([tabindex='-1'])",
    "[contenteditable]:not([contenteditable='false'])",
    "button:not([disabled])",
    "input:not([disabled])",
    "select:not([disabled])",
    "textarea:not([disabled])",
].join(", ");

/**
 * A popup component.
 *
 * @param {Object} [options]
 * @param {boolean} [options.closeButton=true] If `true`, a close button will appear in the
 *   top right corner of the popup.
 * @param {boolean} [options.closeOnClick=true] If `true`, the popup will close when the
 *   map is clicked.
 * @param {boolean} [options.closeOnMove=false] If `true`, the popup will close when the
 *   map moves.
 * @param {boolean} [options.focusAfterOpen=true] If `true`, the popup will try to focus the
 *   first focusable element inside the popup.
 * @param {string} [options.anchor] - A string indicating the part of the popup that should
 *   be positioned closest to the coordinate, set via {@link Popup#setLngLat}.
 *   Options are `'center'`, `'top'`, `'bottom'`, `'left'`, `'right'`, `'top-left'`,
 *   `'top-right'`, `'bottom-left'`, and `'bottom-right'`. If unset, the anchor will be
 *   dynamically set to ensure the popup falls within the map container with a preference
 *   for `'bottom'`.
 * @param {number | PointLike | Object} [options.offset] -
 *  A pixel offset applied to the popup's location specified as:
 *   - a single number specifying a distance from the popup's location
 *   - a {@link PointLike} specifying a constant offset
 *   - an object of {@link Point}s specifing an offset for each anchor position.
 *
 *  Negative offsets indicate left and up.
 * @param {string} [options.className] Space-separated CSS class names to add to popup container.
 * @param {string} [options.maxWidth='240px'] -
 *  A string that sets the CSS property of the popup's maximum width (for example, `'300px'`).
 *  To ensure the popup resizes to fit its content, set this property to `'none'`.
 *  See the MDN documentation for the list of [available values](https://developer.mozilla.org/en-US/docs/Web/CSS/max-width).
 * @example
 * const markerHeight = 50;
 * const markerRadius = 10;
 * const linearOffset = 25;
 * const popupOffsets = {
 *     'top': [0, 0],
 *     'top-left': [0, 0],
 *     'top-right': [0, 0],
 *     'bottom': [0, -markerHeight],
 *     'bottom-left': [linearOffset, (markerHeight - markerRadius + linearOffset) * -1],
 *     'bottom-right': [-linearOffset, (markerHeight - markerRadius + linearOffset) * -1],
 *     'left': [markerRadius, (markerHeight - markerRadius) * -1],
 *     'right': [-markerRadius, (markerHeight - markerRadius) * -1]
 * };
 * const popup = new mapboxgl.Popup({offset: popupOffsets, className: 'my-class'})
 *     .setLngLat(e.lngLat)
 *     .setHTML("<h1>Hello World!</h1>")
 *     .setMaxWidth("300px")
 *     .addTo(map);
 * @see [Example: Display a popup](https://www.mapbox.com/mapbox-gl-js/example/popup/)
 * @see [Example: Display a popup on hover](https://www.mapbox.com/mapbox-gl-js/example/popup-on-hover/)
 * @see [Example: Display a popup on click](https://www.mapbox.com/mapbox-gl-js/example/popup-on-click/)
 * @see [Example: Attach a popup to a marker instance](https://www.mapbox.com/mapbox-gl-js/example/set-popup/)
 */
class Popup extends index.Evented {
               
                          
                           
                             
                               
                       
                    
                           
                 
                    
                            
                     

    constructor(options              ) {
        super();
        this.options = index.extend(Object.create(defaultOptions$4), options);
        index.bindAll(['_update', '_onClose', 'remove', '_onMouseEvent'], this);
        this._classList = new Set(options && options.className ?
            options.className.trim().split(/\s+/) : []);
    }

    /**
     * Adds the popup to a map.
     *
     * @param {Map} map The Mapbox GL JS map to add the popup to.
     * @returns {Popup} Returns itself to allow for method chaining.
     * @example
     * new mapboxgl.Popup()
     *     .setLngLat([0, 0])
     *     .setHTML("<h1>Null Island</h1>")
     *     .addTo(map);
     * @see [Example: Display a popup](https://docs.mapbox.com/mapbox-gl-js/example/popup/)
     * @see [Example: Display a popup on hover](https://docs.mapbox.com/mapbox-gl-js/example/popup-on-hover/)
     * @see [Example: Display a popup on click](https://docs.mapbox.com/mapbox-gl-js/example/popup-on-click/)
     * @see [Example: Show polygon information on click](https://docs.mapbox.com/mapbox-gl-js/example/polygon-popup-on-click/)
     */
    addTo(map     )       {
        if (this._map) this.remove();

        this._map = map;
        if (this.options.closeOnClick) {
            // $FlowFixMe[method-unbinding]
            map.on('preclick', this._onClose);
        }

        if (this.options.closeOnMove) {
            // $FlowFixMe[method-unbinding]
            map.on('move', this._onClose);
        }

        // $FlowFixMe[method-unbinding]
        map.on('remove', this.remove);
        this._update();
        map._addPopup(this);
        this._focusFirstElement();

        if (this._trackPointer) {
            // $FlowFixMe[method-unbinding]
            map.on('mousemove', this._onMouseEvent);
            // $FlowFixMe[method-unbinding]
            map.on('mouseup', this._onMouseEvent);
            map._canvasContainer.classList.add('mapboxgl-track-pointer');
        } else {
            // $FlowFixMe[method-unbinding]
            map.on('move', this._update);
        }

        /**
         * Fired when the popup is opened manually or programatically.
         *
         * @event open
         * @memberof Popup
         * @instance
         * @type {Object}
         * @property {Popup} popup Object that was opened.
         *
         * @example
         * // Create a popup
         * const popup = new mapboxgl.Popup();
         * // Set an event listener that will fire
         * // any time the popup is opened
         * popup.on('open', () => {
         *     console.log('popup was opened');
         * });
         *
         */
        this.fire(new index.Event('open'));

        return this;
    }

    /**
     * Checks if a popup is open.
     *
     * @returns {boolean} `true` if the popup is open, `false` if it is closed.
     * @example
     * const isPopupOpen = popup.isOpen();
     */
    isOpen()          {
        return !!this._map;
    }

    /**
     * Removes the popup from the map it has been added to.
     *
     * @example
     * const popup = new mapboxgl.Popup().addTo(map);
     * popup.remove();
     * @returns {Popup} Returns itself to allow for method chaining.
     */
    remove()       {
        if (this._content) {
            this._content.remove();
        }

        if (this._container) {
            this._container.remove();
            this._container = undefined;
        }

        const map = this._map;
        if (map) {
            // $FlowFixMe[method-unbinding]
            map.off('move', this._update);
            // $FlowFixMe[method-unbinding]
            map.off('move', this._onClose);
            // $FlowFixMe[method-unbinding]
            map.off('preclick', this._onClose);
            // $FlowFixMe[method-unbinding]
            map.off('click', this._onClose);
            // $FlowFixMe[method-unbinding]
            map.off('remove', this.remove);
            // $FlowFixMe[method-unbinding]
            map.off('mousemove', this._onMouseEvent);
            // $FlowFixMe[method-unbinding]
            map.off('mouseup', this._onMouseEvent);
            // $FlowFixMe[method-unbinding]
            map.off('drag', this._onMouseEvent);
            if (map._canvasContainer) {
                map._canvasContainer.classList.remove('mapboxgl-track-pointer');
            }
            map._removePopup(this);
            this._map = undefined;
        }

        /**
         * Fired when the popup is closed manually or programatically.
         *
         * @event close
         * @memberof Popup
         * @instance
         * @type {Object}
         * @property {Popup} popup Object that was closed.
         *
         * @example
         * // Create a popup
         * const popup = new mapboxgl.Popup();
         * // Set an event listener that will fire
         * // any time the popup is closed
         * popup.on('close', () => {
         *     console.log('popup was closed');
         * });
         *
         */
        this.fire(new index.Event('close'));

        return this;
    }

    /**
     * Returns the geographical location of the popup's anchor.
     *
     * The longitude of the result may differ by a multiple of 360 degrees from the longitude previously
     * set by `setLngLat` because `Popup` wraps the anchor longitude across copies of the world to keep
     * the popup on screen.
     *
     * @returns {LngLat} The geographical location of the popup's anchor.
     * @example
     * const lngLat = popup.getLngLat();
     */
    getLngLat()         {
        return this._lngLat;
    }

    /**
     * Sets the geographical location of the popup's anchor, and moves the popup to it. Replaces trackPointer() behavior.
     *
     * @param {LngLatLike} lnglat The geographical location to set as the popup's anchor.
     * @returns {Popup} Returns itself to allow for method chaining.
     * @example
     * popup.setLngLat([-122.4194, 37.7749]);
     */
    setLngLat(lnglat            )       {
        this._lngLat = index.LngLat.convert(lnglat);
        this._pos = null;

        this._trackPointer = false;

        this._update();

        const map = this._map;
        if (map) {
            // $FlowFixMe[method-unbinding]
            map.on('move', this._update);
            // $FlowFixMe[method-unbinding]
            map.off('mousemove', this._onMouseEvent);
            map._canvasContainer.classList.remove('mapboxgl-track-pointer');
        }

        return this;
    }

    /**
     * Tracks the popup anchor to the cursor position on screens with a pointer device (it will be hidden on touchscreens). Replaces the `setLngLat` behavior.
     * For most use cases, set `closeOnClick` and `closeButton` to `false`.
     *
     * @example
     * const popup = new mapboxgl.Popup({closeOnClick: false, closeButton: false})
     *     .setHTML("<h1>Hello World!</h1>")
     *     .trackPointer()
     *     .addTo(map);
     * @returns {Popup} Returns itself to allow for method chaining.
     */
    trackPointer()       {
        this._trackPointer = true;
        this._pos = null;
        this._update();
        const map = this._map;
        if (map) {
            // $FlowFixMe[method-unbinding]
            map.off('move', this._update);
            // $FlowFixMe[method-unbinding]
            map.on('mousemove', this._onMouseEvent);
            // $FlowFixMe[method-unbinding]
            map.on('drag', this._onMouseEvent);
            map._canvasContainer.classList.add('mapboxgl-track-pointer');
        }

        return this;

    }

    /**
     * Returns the `Popup`'s HTML element.
     *
     * @example
     * // Change the `Popup` element's font size
     * const popup = new mapboxgl.Popup()
     *     .setLngLat([-96, 37.8])
     *     .setHTML("<p>Hello World!</p>")
     *     .addTo(map);
     * const popupElem = popup.getElement();
     * popupElem.style.fontSize = "25px";
     * @returns {HTMLElement} Returns container element.
     */
    getElement()               {
        return this._container;
    }

    /**
     * Sets the popup's content to a string of text.
     *
     * This function creates a [Text](https://developer.mozilla.org/en-US/docs/Web/API/Text) node in the DOM,
     * so it cannot insert raw HTML. Use this method for security against XSS
     * if the popup content is user-provided.
     *
     * @param {string} text Textual content for the popup.
     * @returns {Popup} Returns itself to allow for method chaining.
     * @example
     * const popup = new mapboxgl.Popup()
     *     .setLngLat(e.lngLat)
     *     .setText('Hello, world!')
     *     .addTo(map);
     */
    setText(text        )       {
        return this.setDOMContent(index.window.document.createTextNode(text));
    }

    /**
     * Sets the popup's content to the HTML provided as a string.
     *
     * This method does not perform HTML filtering or sanitization, and must be
     * used only with trusted content. Consider {@link Popup#setText} if
     * the content is an untrusted text string.
     *
     * @param {string} html A string representing HTML content for the popup.
     * @returns {Popup} Returns itself to allow for method chaining.
     * @example
     * const popup = new mapboxgl.Popup()
     *     .setLngLat(e.lngLat)
     *     .setHTML("<h1>Hello World!</h1>")
     *     .addTo(map);
     * @see [Example: Display a popup](https://docs.mapbox.com/mapbox-gl-js/example/popup/)
     * @see [Example: Display a popup on hover](https://docs.mapbox.com/mapbox-gl-js/example/popup-on-hover/)
     * @see [Example: Display a popup on click](https://docs.mapbox.com/mapbox-gl-js/example/popup-on-click/)
     * @see [Example: Attach a popup to a marker instance](https://docs.mapbox.com/mapbox-gl-js/example/set-popup/)
     */
    setHTML(html        )       {
        const frag = index.window.document.createDocumentFragment();
        const temp = index.window.document.createElement('body');
        let child;
        temp.innerHTML = html;
        while (true) {
            child = temp.firstChild;
            if (!child) break;
            frag.appendChild(child);
        }

        return this.setDOMContent(frag);
    }

    /**
     * Returns the popup's maximum width.
     *
     * @returns {string} The maximum width of the popup.
     * @example
     * const maxWidth = popup.getMaxWidth();
     */
    getMaxWidth()          {
        return this._container && this._container.style.maxWidth;
    }

    /**
     * Sets the popup's maximum width. This is setting the CSS property `max-width`.
     * Available values can be found here: https://developer.mozilla.org/en-US/docs/Web/CSS/max-width.
     *
     * @param {string} maxWidth A string representing the value for the maximum width.
     * @returns {Popup} Returns itself to allow for method chaining.
     * @example
     * popup.setMaxWidth('50');
     */
    setMaxWidth(maxWidth        )       {
        this.options.maxWidth = maxWidth;
        this._update();
        return this;
    }

    /**
     * Sets the popup's content to the element provided as a DOM node.
     *
     * @param {Element} htmlNode A DOM node to be used as content for the popup.
     * @returns {Popup} Returns itself to allow for method chaining.
     * @example
     * // create an element with the popup content
     * const div = window.document.createElement('div');
     * div.innerHTML = 'Hello, world!';
     * const popup = new mapboxgl.Popup()
     *     .setLngLat(e.lngLat)
     *     .setDOMContent(div)
     *     .addTo(map);
     */
    setDOMContent(htmlNode      )       {
        let content = this._content;
        if (content) {
            // Clear out children first.
            while (content.hasChildNodes()) {
                if (content.firstChild) {
                    content.removeChild(content.firstChild);
                }
            }
        } else {
            content = this._content = create$1('div', 'mapboxgl-popup-content', this._container || undefined);
        }

        // The close button should be the last tabbable element inside the popup for a good keyboard UX.
        content.appendChild(htmlNode);

        if (this.options.closeButton) {
            const button = this._closeButton = create$1('button', 'mapboxgl-popup-close-button', content);
            button.type = 'button';
            button.setAttribute('aria-label', 'Close popup');
            button.setAttribute('aria-hidden', 'true');
            button.innerHTML = '&#215;';
            // $FlowFixMe[method-unbinding]
            button.addEventListener('click', this._onClose);
        }
        this._update();
        this._focusFirstElement();
        return this;
    }

    /**
     * Adds a CSS class to the popup container element.
     *
     * @param {string} className Non-empty string with CSS class name to add to popup container.
     * @returns {Popup} Returns itself to allow for method chaining.
     *
     * @example
     * const popup = new mapboxgl.Popup();
     * popup.addClassName('some-class');
     */
    addClassName(className        )       {
        this._classList.add(className);
        this._updateClassList();
        return this;
    }

    /**
     * Removes a CSS class from the popup container element.
     *
     * @param {string} className Non-empty string with CSS class name to remove from popup container.
     *
     * @returns {Popup} Returns itself to allow for method chaining.
     * @example
     * const popup = new mapboxgl.Popup({className: 'some classes'});
     * popup.removeClassName('some');
     */
    removeClassName(className        )       {
        this._classList.delete(className);
        this._updateClassList();
        return this;
    }

    /**
     * Sets the popup's offset.
     *
     * @param {number | PointLike | Object} offset Sets the popup's offset. The `Object` is of the following structure
     * {
     *    'center': ?PointLike,
     *    'top': ?PointLike,
     *    'bottom': ?PointLike,
     *    'left': ?PointLike,
     *    'right': ?PointLike,
     *    'top-left': ?PointLike,
     *    'top-right': ?PointLike,
     *    'bottom-left': ?PointLike,
     *    'bottom-right': ?PointLike
     * }.
     *
     * @returns {Popup} `this`.
     * @example
     * popup.setOffset(10);
     */
    setOffset (offset         )       {
        this.options.offset = offset;
        this._update();
        return this;
    }

    /**
     * Add or remove the given CSS class on the popup container, depending on whether the container currently has that class.
     *
     * @param {string} className Non-empty string with CSS class name to add/remove.
     *
     * @returns {boolean} If the class was removed return `false`. If the class was added, then return `true`.
     *
     * @example
     * const popup = new mapboxgl.Popup();
     * popup.toggleClassName('highlighted');
     */
    toggleClassName(className        )          {
        let finalState         ;
        if (this._classList.delete(className)) {
            finalState = false;
        } else {
            this._classList.add(className);
            finalState = true;
        }
        this._updateClassList();
        return finalState;
    }

    _onMouseEvent(event               ) {
        this._update(event.point);
    }

    _getAnchor(bottomY        )         {
        if (this.options.anchor) { return this.options.anchor; }

        const map = this._map;
        const container = this._container;
        const pos = this._pos;

        if (!map || !container || !pos) return 'bottom';

        const width = container.offsetWidth;
        const height = container.offsetHeight;

        const isTop = pos.y + bottomY < height;
        const isBottom = pos.y > map.transform.height - height;
        const isLeft = pos.x < width / 2;
        const isRight = pos.x > map.transform.width - width / 2;

        if (isTop) {
            if (isLeft) return 'top-left';
            if (isRight) return 'top-right';
            return 'top';
        }
        if (isBottom) {
            if (isLeft) return 'bottom-left';
            if (isRight) return 'bottom-right';
        }
        if (isLeft) return 'left';
        if (isRight) return 'right';

        return 'bottom';
    }

    _updateClassList() {
        const container = this._container;
        if (!container) return;

        const classes = [...this._classList];
        classes.push('mapboxgl-popup');
        if (this._anchor) {
            classes.push(`mapboxgl-popup-anchor-${this._anchor}`);
        }
        if (this._trackPointer) {
            classes.push('mapboxgl-popup-track-pointer');
        }
        container.className = classes.join(' ');
    }

    _update(cursor        ) {
        const hasPosition = this._lngLat || this._trackPointer;
        const map = this._map;
        const content = this._content;

        if (!map || !hasPosition || !content) { return; }

        let container = this._container;

        if (!container) {
            container = this._container = create$1('div', 'mapboxgl-popup', map.getContainer());
            this._tip = create$1('div', 'mapboxgl-popup-tip', container);
            container.appendChild(content);
        }

        if (this.options.maxWidth && container.style.maxWidth !== this.options.maxWidth) {
            container.style.maxWidth = this.options.maxWidth;
        }

        if (map.transform.renderWorldCopies && !this._trackPointer) {
            this._lngLat = smartWrap(this._lngLat, this._pos, map.transform);
        }

        if (!this._trackPointer || cursor) {
            const pos = this._pos = this._trackPointer && cursor ? cursor : map.project(this._lngLat);

            const offsetBottom = normalizeOffset(this.options.offset);
            const anchor = this._anchor = this._getAnchor(offsetBottom.y);
            const offset = normalizeOffset(this.options.offset, anchor);

            const offsetedPos = pos.add(offset).round();
            map._requestDomTask(() => {
                if (this._container && anchor) {
                    this._container.style.transform = `${anchorTranslate[anchor]} translate(${offsetedPos.x}px,${offsetedPos.y}px)`;
                }
            });
        }

        if (!this._marker && map._showingGlobe()) {
            const opacity = index.isLngLatBehindGlobe(map.transform, this._lngLat) ? 0 : 1;
            this._setOpacity(opacity);
        }

        this._updateClassList();
    }

    _focusFirstElement() {
        if (!this.options.focusAfterOpen || !this._container) return;

        const firstFocusable = this._container.querySelector(focusQuerySelector);

        if (firstFocusable) firstFocusable.focus();
    }

    _onClose() {
        this.remove();
    }

    _setOpacity(opacity        ) {
        if (this._container) {
            this._container.style.opacity = `${opacity}`;
        }
        if (this._content) {
            this._content.style.pointerEvents = opacity ? 'auto' : 'none';
        }
    }
}

// returns a normalized offset for a given anchor
function normalizeOffset(offset         = new index.Point(0, 0), anchor         = 'bottom')        {
    if (typeof offset === 'number') {
        // input specifies a radius from which to calculate offsets at all positions
        const cornerOffset = Math.round(Math.sqrt(0.5 * Math.pow(offset, 2)));
        switch (anchor) {
        case 'top': return new index.Point(0, offset);
        case 'top-left': return new index.Point(cornerOffset, cornerOffset);
        case 'top-right': return new index.Point(-cornerOffset, cornerOffset);
        case 'bottom': return new index.Point(0, -offset);
        case 'bottom-left': return new index.Point(cornerOffset, -cornerOffset);
        case 'bottom-right': return new index.Point(-cornerOffset, -cornerOffset);
        case 'left': return new index.Point(offset, 0);
        case 'right': return new index.Point(-offset, 0);
        }
        return new index.Point(0, 0);
    }

    if (offset instanceof index.Point || Array.isArray(offset)) {
        // input specifies a single offset to be applied to all positions
        return index.Point.convert(offset);
    }

    // input specifies an offset per position
    // $FlowFixMe we know offset is an object at this point but Flow can't refine it for some reason
    return index.Point.convert(offset[anchor] || [0, 0]);
}

//      


/**
 * An object for maintaining just enough state to ease a variable.
 *
 * @private
 */
class EasedVariable {
                   
                 
                       
                     

    constructor(initialValue        ) {
        this.jumpTo(initialValue);
    }

    /**
     * Evaluate the current value, given a timestamp.
     *
     * @param timeStamp {number} Time at which to evaluate.
     *
     * @returns {number} Evaluated value.
     */
    getValue(timeStamp        )         {
        if (timeStamp <= this._startTime) return this._start;
        if (timeStamp >= this._endTime) return this._end;

        const t = index.easeCubicInOut((timeStamp - this._startTime) / (this._endTime - this._startTime));
        return this._start * (1 - t) + this._end * t;
    }

    /**
     * Check if an ease is in progress.
     *
     * @param timeStamp {number} Current time stamp.
     *
     * @returns {boolean} Returns `true` if ease is in progress.
     */
    isEasing(timeStamp        )          {
        return timeStamp >= this._startTime && timeStamp <= this._endTime;
    }

    /**
     * Set the value without easing and cancel any in progress ease.
     *
     * @param value {number} New value.
     */
    jumpTo(value        ) {
        this._startTime = -Infinity;
        this._endTime = -Infinity;

        this._start = value;
        this._end = value;
    }

    /**
     * Cancel any in-progress ease and begin a new ease.
     *
     * @param value {number} New value to which to ease.
     * @param timeStamp {number} Current time stamp.
     * @param duration {number} Ease duration, in same units as timeStamp.
     */
    easeTo(value        , timeStamp        , duration        ) {
        this._start = this.getValue(timeStamp);
        this._end = value;

        this._startTime = timeStamp;
        this._endTime = timeStamp + duration;
    }
}

//      

const defaultLocale = {
    'AttributionControl.ToggleAttribution': 'Toggle attribution',
    'AttributionControl.MapFeedback': 'Map feedback',
    'FullscreenControl.Enter': 'Enter fullscreen',
    'FullscreenControl.Exit': 'Exit fullscreen',
    'GeolocateControl.FindMyLocation': 'Find my location',
    'GeolocateControl.LocationNotAvailable': 'Location not available',
    'LogoControl.Title': 'Mapbox logo',
    'Map.Title': 'Map',
    'NavigationControl.ResetBearing': 'Reset bearing to north',
    'NavigationControl.ZoomIn': 'Zoom in',
    'NavigationControl.ZoomOut': 'Zoom out',
    'ScrollZoomBlocker.CtrlMessage': 'Use ctrl + scroll to zoom the map',
    'ScrollZoomBlocker.CmdMessage': 'Use ⌘ + scroll to zoom the map',
    'TouchPanBlocker.Message': 'Use two fingers to move the map'
};

//      

                                                  
                                                       
             
                       
                        
                       
                       
                         
                     
                        
                            
                               
                           
                                
                                                      
                                                
                                                                   
                                                          

                                                                                        
/* eslint-disable no-use-before-define */
                    
                                      
                                  

                                                
                                                            
 
/* eslint-enable no-use-before-define */

const AVERAGE_ELEVATION_SAMPLING_INTERVAL = 500; // ms
const AVERAGE_ELEVATION_EASE_TIME = 300; // ms
const AVERAGE_ELEVATION_EASE_THRESHOLD = 1; // meters
const AVERAGE_ELEVATION_CHANGE_THRESHOLD = 1e-4; // meters

                   
                            
                          
                                    
                         
                                 
                                               
                                   
                                           
                                    
                        
                                  
                                 
                         
                      
                      
                       
                       
                      
                         
                             
                       
                              
                              
                         
                                  
                          
                        
                  
                     
                   
                                 
                                
                              
                              
                                                
                        
                       
                    
                                                  
                      
                      
  

const defaultMinZoom = -2;
const defaultMaxZoom = 22;

// the default values, but also the valid range
const defaultMinPitch = 0;
const defaultMaxPitch = 85;

const defaultOptions$3 = {
    center: [0, 0],
    zoom: 0,
    bearing: 0,
    pitch: 0,

    minZoom: defaultMinZoom,
    maxZoom: defaultMaxZoom,

    minPitch: defaultMinPitch,
    maxPitch: defaultMaxPitch,

    interactive: true,
    scrollZoom: true,
    boxZoom: true,
    dragRotate: true,
    dragPan: true,
    keyboard: true,
    doubleClickZoom: true,
    touchZoomRotate: true,
    touchPitch: true,
    cooperativeGestures: false,
    performanceMetricsCollection: true,

    bearingSnap: 7,
    clickTolerance: 3,
    pitchWithRotate: true,

    hash: false,
    attributionControl: true,

    failIfMajorPerformanceCaveat: false,
    preserveDrawingBuffer: false,
    trackResize: true,
    optimizeForTerrain: true,
    renderWorldCopies: true,
    refreshExpiredTiles: true,
    minTileCacheSize: null,
    maxTileCacheSize: null,
    localIdeographFontFamily: 'sans-serif',
    localFontFamily: null,
    transformRequest: null,
    accessToken: null,
    fadeDuration: 300,
    respectPrefersReducedMotion: true,
    crossSourceCollisions: true
};

/**
 * The `Map` object represents the map on your page. It exposes methods
 * and properties that enable you to programmatically change the map,
 * and fires events as users interact with it.
 *
 * You create a `Map` by specifying a `container` and other options.
 * Then Mapbox GL JS initializes the map on the page and returns your `Map`
 * object.
 *
 * @extends Evented
 * @param {Object} options
 * @param {HTMLElement|string} options.container The HTML element in which Mapbox GL JS will render the map, or the element's string `id`. The specified element must have no children.
 * @param {number} [options.minZoom=0] The minimum zoom level of the map (0-24).
 * @param {number} [options.maxZoom=22] The maximum zoom level of the map (0-24).
 * @param {number} [options.minPitch=0] The minimum pitch of the map (0-85).
 * @param {number} [options.maxPitch=85] The maximum pitch of the map (0-85).
 * @param {Object | string} options.style The map's Mapbox style. This must be an a JSON object conforming to
 * the schema described in the [Mapbox Style Specification](https://mapbox.com/mapbox-gl-style-spec/), or a URL
 * to such JSON. Can accept a null value to allow adding a style manually.
 *
 * To load a style from the Mapbox API, you can use a URL of the form `mapbox://styles/:owner/:style`,
 * where `:owner` is your Mapbox account name and `:style` is the style ID. You can also use a
 * [Mapbox-owned style](https://docs.mapbox.com/api/maps/styles/#mapbox-styles):
 *
 *  * `mapbox://styles/mapbox/streets-v11`
 *  * `mapbox://styles/mapbox/outdoors-v11`
 *  * `mapbox://styles/mapbox/light-v10`
 *  * `mapbox://styles/mapbox/dark-v10`
 *  * `mapbox://styles/mapbox/satellite-v9`
 *  * `mapbox://styles/mapbox/satellite-streets-v11`
 *  * `mapbox://styles/mapbox/navigation-day-v1`
 *  * `mapbox://styles/mapbox/navigation-night-v1`.
 *
 * Tilesets hosted with Mapbox can be style-optimized if you append `?optimize=true` to the end of your style URL, like `mapbox://styles/mapbox/streets-v11?optimize=true`.
 * Learn more about style-optimized vector tiles in our [API documentation](https://www.mapbox.com/api-documentation/maps/#retrieve-tiles).
 *
 * @param {(boolean|string)} [options.hash=false] If `true`, the map's [position](https://docs.mapbox.com/help/glossary/camera) (zoom, center latitude, center longitude, bearing, and pitch) will be synced with the hash fragment of the page's URL.
 *   For example, `http://path/to/my/page.html#2.59/39.26/53.07/-24.1/60`.
 *   An additional string may optionally be provided to indicate a parameter-styled hash,
 *   for example http://path/to/my/page.html#map=2.59/39.26/53.07/-24.1/60&foo=bar, where `foo`
 *   is a custom parameter and `bar` is an arbitrary hash distinct from the map hash.
 * @param {boolean} [options.interactive=true] If `false`, no mouse, touch, or keyboard listeners will be attached to the map, so it will not respond to interaction.
 * @param {number} [options.bearingSnap=7] The threshold, measured in degrees, that determines when the map's
 *   bearing will snap to north. For example, with a `bearingSnap` of 7, if the user rotates
 *   the map within 7 degrees of north, the map will automatically snap to exact north.
 * @param {boolean} [options.pitchWithRotate=true] If `false`, the map's pitch (tilt) control with "drag to rotate" interaction will be disabled.
 * @param {number} [options.clickTolerance=3] The max number of pixels a user can shift the mouse pointer during a click for it to be considered a valid click (as opposed to a mouse drag).
 * @param {boolean} [options.attributionControl=true] If `true`, an {@link AttributionControl} will be added to the map.
 * @param {string | Array<string>} [options.customAttribution=null] String or strings to show in an {@link AttributionControl}. Only applicable if `options.attributionControl` is `true`.
 * @param {string} [options.logoPosition='bottom-left'] A string representing the position of the Mapbox wordmark on the map. Valid options are `top-left`,`top-right`, `bottom-left`, `bottom-right`.
 * @param {boolean} [options.failIfMajorPerformanceCaveat=false] If `true`, map creation will fail if the performance of Mapbox GL JS would be dramatically worse than expected (a software renderer would be used).
 * @param {boolean} [options.preserveDrawingBuffer=false] If `true`, the map's canvas can be exported to a PNG using `map.getCanvas().toDataURL()`. This is `false` by default as a performance optimization.
 * @param {boolean} [options.antialias=false] If `true`, the gl context will be created with [MSAA antialiasing](https://en.wikipedia.org/wiki/Multisample_anti-aliasing), which can be useful for antialiasing custom layers. This is `false` by default as a performance optimization.
 * @param {boolean} [options.useWebGL2=false] This is an experimental feature. If true and device's capabilities support it, WebGL 2 context will be created.
 * @param {boolean} [options.refreshExpiredTiles=true] If `false`, the map won't attempt to re-request tiles once they expire per their HTTP `cacheControl`/`expires` headers.
 * @param {LngLatBoundsLike} [options.maxBounds=null] If set, the map will be constrained to the given bounds.
 * @param {boolean|Object} [options.scrollZoom=true] If `true`, the "scroll to zoom" interaction is enabled. An `Object` value is passed as options to {@link ScrollZoomHandler#enable}.
 * @param {boolean} [options.boxZoom=true] If `true`, the "box zoom" interaction is enabled (see {@link BoxZoomHandler}).
 * @param {boolean} [options.dragRotate=true] If `true`, the "drag to rotate" interaction is enabled (see {@link DragRotateHandler}).
 * @param {boolean | Object} [options.dragPan=true] If `true`, the "drag to pan" interaction is enabled. An `Object` value is passed as options to {@link DragPanHandler#enable}.
 * @param {boolean} [options.keyboard=true] If `true`, keyboard shortcuts are enabled (see {@link KeyboardHandler}).
 * @param {boolean} [options.doubleClickZoom=true] If `true`, the "double click to zoom" interaction is enabled (see {@link DoubleClickZoomHandler}).
 * @param {boolean | Object} [options.touchZoomRotate=true] If `true`, the "pinch to rotate and zoom" interaction is enabled. An `Object` value is passed as options to {@link TouchZoomRotateHandler#enable}.
 * @param {boolean | Object} [options.touchPitch=true] If `true`, the "drag to pitch" interaction is enabled. An `Object` value is passed as options to {@link TouchPitchHandler}.
 * @param {boolean} [options.cooperativeGestures] If `true`, scroll zoom will require pressing the ctrl or ⌘ key while scrolling to zoom map, and touch pan will require using two fingers while panning to move the map. Touch pitch will require three fingers to activate if enabled.
 * @param {boolean} [options.trackResize=true] If `true`, the map will automatically resize when the browser window resizes.
 * @param {boolean} [options.performanceMetricsCollection=true] If `true`, mapbox-gl will collect and send performance metrics.
 * @param {LngLatLike} [options.center=[0, 0]] The initial geographical [centerpoint](https://docs.mapbox.com/help/glossary/camera#center) of the map. If `center` is not specified in the constructor options, Mapbox GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `[0, 0]` Note: Mapbox GL uses longitude, latitude coordinate order (as opposed to latitude, longitude) to match GeoJSON.
 * @param {number} [options.zoom=0] The initial [zoom](https://docs.mapbox.com/help/glossary/camera#zoom) level of the map. If `zoom` is not specified in the constructor options, Mapbox GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `0`.
 * @param {number} [options.bearing=0] The initial [bearing](https://docs.mapbox.com/help/glossary/camera#bearing) (rotation) of the map, measured in degrees counter-clockwise from north. If `bearing` is not specified in the constructor options, Mapbox GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `0`.
 * @param {number} [options.pitch=0] The initial [pitch](https://docs.mapbox.com/help/glossary/camera#pitch) (tilt) of the map, measured in degrees away from the plane of the screen (0-85). If `pitch` is not specified in the constructor options, Mapbox GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `0`.
 * @param {LngLatBoundsLike} [options.bounds=null] The initial bounds of the map. If `bounds` is specified, it overrides `center` and `zoom` constructor options.
 * @param {Object} [options.fitBoundsOptions] A {@link Map#fitBounds} options object to use _only_ when fitting the initial `bounds` provided above.
 * @param {'auto' | string | string[]} [options.language=null] A string with a BCP 47 language tag, or an array of such strings representing the desired languages used for the map's labels and UI components. Languages can only be set on Mapbox vector tile sources.
 *   By default, GL JS will not set a language so that the language of Mapbox tiles will be determined by the vector tile source's TileJSON.
 *   Valid language strings must be a [BCP-47 language code](https://en.wikipedia.org/wiki/IETF_language_tag#List_of_subtags). Unsupported BCP-47 codes will not include any translations. Invalid codes will result in an recoverable error.
 *   If a label has no translation for the selected language, it will display in the label's local language.
 *   If option is set to `auto`, GL JS will select a user's preferred language as determined by the browser's [`window.navigator.language`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/language) property.
 *   If the `locale` property is not set separately, this language will also be used to localize the UI for supported languages.
 * @param {string} [options.worldview=null] Sets the map's worldview. A worldview determines the way that certain disputed boundaries
     * are rendered. By default, GL JS will not set a worldview so that the worldview of Mapbox tiles will be determined by the vector tile source's TileJSON.
     * Valid worldview strings must be an [ISO alpha-2 country code](https://en.wikipedia.org/wiki/ISO_3166-1#Current_codes). Unsupported
     * ISO alpha-2 codes will fall back to the TileJSON's default worldview. Invalid codes will result in a recoverable error.
 * @param {boolean} [options.optimizeForTerrain=true] With terrain on, if `true`, the map will render for performance priority, which may lead to layer reordering allowing to maximize performance (layers that are draped over terrain will be drawn first, including fill, line, background, hillshade and raster). Otherwise, if set to `false`, the map will always be drawn for layer order priority.
 * @param {boolean} [options.renderWorldCopies=true] If `true`, multiple copies of the world will be rendered side by side beyond -180 and 180 degrees longitude. If set to `false`:
 * - When the map is zoomed out far enough that a single representation of the world does not fill the map's entire
 * container, there will be blank space beyond 180 and -180 degrees longitude.
 * - Features that cross 180 and -180 degrees longitude will be cut in two (with one portion on the right edge of the
 * map and the other on the left edge of the map) at every zoom level.
 * @param {number} [options.minTileCacheSize=null] The minimum number of tiles stored in the tile cache for a given source. Larger viewports use more tiles and need larger caches. Larger viewports are more likely to be found on devices with more memory and on pages where the map is more important. If omitted, the cache will be dynamically sized based on the current viewport.
 * @param {number} [options.maxTileCacheSize=null] The maximum number of tiles stored in the tile cache for a given source. If omitted, the cache will be dynamically sized based on the current viewport.
 * @param {string} [options.localIdeographFontFamily='sans-serif'] Defines a CSS font-family for locally overriding generation of glyphs in the 'CJK Unified Ideographs', 'Hiragana', 'Katakana', 'Hangul Syllables' and 'CJK Symbols and Punctuation' ranges.
 *   In these ranges, font settings from the map's style will be ignored, except for font-weight keywords (light/regular/medium/bold).
 *   Set to `false`, to enable font settings from the map's style for these glyph ranges. Note that [Mapbox Studio](https://studio.mapbox.com/) sets this value to `false` by default.
 *   The purpose of this option is to avoid bandwidth-intensive glyph server requests. For an example of this option in use, see [Use locally generated ideographs](https://www.mapbox.com/mapbox-gl-js/example/local-ideographs).
 * @param {string} [options.localFontFamily=false] Defines a CSS
 *   font-family for locally overriding generation of all glyphs. Font settings from the map's style will be ignored, except for font-weight keywords (light/regular/medium/bold).
 *   If set, this option overrides the setting in localIdeographFontFamily.
 * @param {RequestTransformFunction} [options.transformRequest=null] A callback run before the Map makes a request for an external URL. The callback can be used to modify the url, set headers, or set the credentials property for cross-origin requests.
 *   Expected to return a {@link RequestParameters} object with a `url` property and optionally `headers` and `credentials` properties.
 * @param {boolean} [options.collectResourceTiming=false] If `true`, Resource Timing API information will be collected for requests made by GeoJSON and Vector Tile web workers (this information is normally inaccessible from the main Javascript thread). Information will be returned in a `resourceTiming` property of relevant `data` events.
 * @param {number} [options.fadeDuration=300] Controls the duration of the fade-in/fade-out animation for label collisions, in milliseconds. This setting affects all symbol layers. This setting does not affect the duration of runtime styling transitions or raster tile cross-fading.
 * @param {boolean} [options.respectPrefersReducedMotion=true] If set to `true`, the map will respect the user's `prefers-reduced-motion` browser setting and apply a reduced motion mode, minimizing animations and transitions. When set to `false`, the map will always ignore the `prefers-reduced-motion` settings, regardless of the user's preference, making all animations essential.
 * @param {boolean} [options.crossSourceCollisions=true] If `true`, symbols from multiple sources can collide with each other during collision detection. If `false`, collision detection is run separately for the symbols in each source.
 * @param {string} [options.accessToken=null] If specified, map will use this [token](https://docs.mapbox.com/help/glossary/access-token/) instead of the one defined in `mapboxgl.accessToken`.
 * @param {Object} [options.locale=null] A patch to apply to the default localization table for UI strings such as control tooltips. The `locale` object maps namespaced UI string IDs to translated strings in the target language;
 *  see [`src/ui/default_locale.js`](https://github.com/mapbox/mapbox-gl-js/blob/main/src/ui/default_locale.js) for an example with all supported string IDs. The object may specify all UI strings (thereby adding support for a new translation) or only a subset of strings (thereby patching the default translation table).
 * @param {boolean} [options.testMode=false] Silences errors and warnings generated due to an invalid accessToken, useful when using the library to write unit tests.
 * @param {ProjectionSpecification} [options.projection='mercator'] The [projection](https://docs.mapbox.com/mapbox-gl-js/style-spec/projection/) the map should be rendered in.
 * Supported projections are:
 *  * [Albers](https://en.wikipedia.org/wiki/Albers_projection) equal-area conic projection as `albers`
 *  * [Equal Earth](https://en.wikipedia.org/wiki/Equal_Earth_projection) equal-area pseudocylindrical projection as `equalEarth`
 *  * [Equirectangular](https://en.wikipedia.org/wiki/Equirectangular_projection) (Plate Carrée/WGS84) as `equirectangular`
 *  * 3d Globe as `globe`
 *  * [Lambert Conformal Conic](https://en.wikipedia.org/wiki/Lambert_conformal_conic_projection) as `lambertConformalConic`
 *  * [Mercator](https://en.wikipedia.org/wiki/Mercator_projection) cylindrical map projection as `mercator`
 *  * [Natural Earth](https://en.wikipedia.org/wiki/Natural_Earth_projection) pseudocylindrical map projection as `naturalEarth`
 *  * [Winkel Tripel](https://en.wikipedia.org/wiki/Winkel_tripel_projection) azimuthal map projection as `winkelTripel`
 *  Conic projections such as Albers and Lambert have configurable `center` and `parallels` properties that allow developers to define the region in which the projection has minimal distortion; see the example for how to configure these properties.
 * @example
 * const map = new mapboxgl.Map({
 *     container: 'map', // container ID
 *     center: [-122.420679, 37.772537], // starting position [lng, lat]
 *     zoom: 13, // starting zoom
 *     style: 'mapbox://styles/mapbox/streets-v11', // style URL or style object
 *     hash: true, // sync `center`, `zoom`, `pitch`, and `bearing` with URL
 *     // Use `transformRequest` to modify requests that begin with `http://myHost`.
 *     transformRequest: (url, resourceType) => {
 *         if (resourceType === 'Source' && url.startsWith('http://myHost')) {
 *             return {
 *                 url: url.replace('http', 'https'),
 *                 headers: {'my-custom-header': true},
 *                 credentials: 'include'  // Include cookies for cross-origin requests
 *             };
 *         }
 *     }
 * });
 * @see [Example: Display a map on a webpage](https://docs.mapbox.com/mapbox-gl-js/example/simple-map/)
 * @see [Example: Display a map with a custom style](https://docs.mapbox.com/mapbox-gl-js/example/custom-style-id/)
 * @see [Example: Check if Mapbox GL JS is supported](https://docs.mapbox.com/mapbox-gl-js/example/check-for-support/)
 */
class Map extends Camera {
                 
                     
                              

                            
                                   
                                  
                                   
                                                  
                           
                                  
                                    
                                 
                                  
                           
                             
                                    
                       
                        
                               
                              
                              
                        
                               
                          
                            
                              
                     
                           // accounts for placement finishing as well
                          
                                    
                                           
                        
                        
                                  
                
                             
                            
                                
                          
                                    
                                    
                                 
                                
                                   
                               
                            
                          
                           
                   
                                      
                             
                                    
                    
                      
                               
                            
                                  
                                
                                           
                                          
                                     
                            
                             
                                   
                        
                                        
                              
                                           

    // `_useExplicitProjection` indicates that a projection is set by a call to map.setProjection()
                                    

    /** @section {Interaction handlers} */

    /**
     * The map's {@link ScrollZoomHandler}, which implements zooming in and out with a scroll wheel or trackpad.
     * Find more details and examples using `scrollZoom` in the {@link ScrollZoomHandler} section.
     */
                                  

    /**
     * The map's {@link BoxZoomHandler}, which implements zooming using a drag gesture with the Shift key pressed.
     * Find more details and examples using `boxZoom` in the {@link BoxZoomHandler} section.
     */
                            

    /**
     * The map's {@link DragRotateHandler}, which implements rotating the map while dragging with the right
     * mouse button or with the Control key pressed. Find more details and examples using `dragRotate`
     * in the {@link DragRotateHandler} section.
     */
                                  

    /**
     * The map's {@link DragPanHandler}, which implements dragging the map with a mouse or touch gesture.
     * Find more details and examples using `dragPan` in the {@link DragPanHandler} section.
     */
                            

    /**
     * The map's {@link KeyboardHandler}, which allows the user to zoom, rotate, and pan the map using keyboard
     * shortcuts. Find more details and examples using `keyboard` in the {@link KeyboardHandler} section.
     */
                              

    /**
     * The map's {@link DoubleClickZoomHandler}, which allows the user to zoom by double clicking.
     * Find more details and examples using `doubleClickZoom` in the {@link DoubleClickZoomHandler} section.
     */
                                            

    /**
     * The map's {@link TouchZoomRotateHandler}, which allows the user to zoom or rotate the map with touch gestures.
     * Find more details and examples using `touchZoomRotate` in the {@link TouchZoomRotateHandler} section.
     */
                                            

    /**
     * The map's {@link TouchPitchHandler}, which allows the user to pitch the map with touch gestures.
     * Find more details and examples using `touchPitch` in the {@link TouchPitchHandler} section.
     */
                                  

    constructor(options            ) {
        index.LivePerformanceUtils.mark(index.PerformanceMarkers.create);

        options = index.extend({}, defaultOptions$3, options);

        if (options.minZoom != null && options.maxZoom != null && options.minZoom > options.maxZoom) {
            throw new Error(`maxZoom must be greater than or equal to minZoom`);
        }

        if (options.minPitch != null && options.maxPitch != null && options.minPitch > options.maxPitch) {
            throw new Error(`maxPitch must be greater than or equal to minPitch`);
        }

        if (options.minPitch != null && options.minPitch < defaultMinPitch) {
            throw new Error(`minPitch must be greater than or equal to ${defaultMinPitch}`);
        }

        if (options.maxPitch != null && options.maxPitch > defaultMaxPitch) {
            throw new Error(`maxPitch must be less than or equal to ${defaultMaxPitch}`);
        }

        // disable antialias with OS/iOS 15.4 and 15.5 due to rendering bug
        if (options.antialias && index.isSafariWithAntialiasingBug(index.window)) {
            options.antialias = false;
            index.warnOnce('Antialiasing is disabled for this WebGL context to avoid browser bug: https://github.com/mapbox/mapbox-gl-js/issues/11609');
        }

        const transform = new Transform(options.minZoom, options.maxZoom, options.minPitch, options.maxPitch, options.renderWorldCopies);
        super(transform, options);

        this._interactive = options.interactive;
        this._minTileCacheSize = options.minTileCacheSize;
        this._maxTileCacheSize = options.maxTileCacheSize;
        this._failIfMajorPerformanceCaveat = options.failIfMajorPerformanceCaveat;
        this._preserveDrawingBuffer = options.preserveDrawingBuffer;
        this._antialias = options.antialias;
        this._useWebGL2 = options.useWebGL2;
        this._trackResize = options.trackResize;
        this._bearingSnap = options.bearingSnap;
        this._refreshExpiredTiles = options.refreshExpiredTiles;
        this._fadeDuration = options.fadeDuration;
        this._isInitialLoad = true;
        this._crossSourceCollisions = options.crossSourceCollisions;
        this._collectResourceTiming = options.collectResourceTiming;
        this._optimizeForTerrain = options.optimizeForTerrain;
        this._language = this._parseLanguage(options.language);
        this._worldview = options.worldview;
        this._renderTaskQueue = new TaskQueue();
        this._domRenderTaskQueue = new TaskQueue();
        this._controls = [];
        this._markers = [];
        this._popups = [];
        this._mapId = index.uniqueId();
        this._locale = index.extend({}, defaultLocale, options.locale);
        this._clickTolerance = options.clickTolerance;
        this._cooperativeGestures = options.cooperativeGestures;
        this._performanceMetricsCollection = options.performanceMetricsCollection;
        this._containerWidth = 0;
        this._containerHeight = 0;

        this._averageElevationLastSampledAt = -Infinity;
        this._averageElevationExaggeration = 0;
        this._averageElevation = new EasedVariable(0);

        this._interactionRange = [+Infinity, -Infinity];
        this._visibilityHidden = 0;

        this._useExplicitProjection = false; // Fallback to stylesheet by default

        this._requestManager = new index.RequestManager(options.transformRequest, options.accessToken, options.testMode);
        this._silenceAuthErrors = !!options.testMode;

        if (typeof options.container === 'string') {
            this._container = index.window.document.getElementById(options.container);

            if (!this._container) {
                throw new Error(`Container '${options.container}' not found.`);
            }
        } else if (options.container instanceof index.window.HTMLElement) {
            this._container = options.container;
        } else {
            throw new Error(`Invalid type: 'container' must be a String or HTMLElement.`);
        }

        if (this._container.childNodes.length > 0) {
            index.warnOnce(`The map container element should be empty, otherwise the map's interactivity will be negatively impacted. If you want to display a message when WebGL is not supported, use the Mapbox GL Supported plugin instead.`);
        }

        if (options.maxBounds) {
            this.setMaxBounds(options.maxBounds);
        }

        index.bindAll([
            '_onWindowOnline',
            '_onWindowResize',
            '_onVisibilityChange',
            '_onMapScroll',
            '_contextLost',
            '_contextRestored'
        ], this);

        this._setupContainer();
        this._setupPainter();
        if (this.painter === undefined) {
            throw new Error(`Failed to initialize WebGL.`);
        }

        this.on('move', () => this._update(false));
        this.on('moveend', () => this._update(false));
        this.on('zoom', () => this._update(true));

        if (typeof index.window !== 'undefined') {
            // $FlowFixMe[method-unbinding]
            index.window.addEventListener('online', this._onWindowOnline, false);
            // $FlowFixMe[method-unbinding]
            index.window.addEventListener('resize', this._onWindowResize, false);
            // $FlowFixMe[method-unbinding]
            index.window.addEventListener('orientationchange', this._onWindowResize, false);
            // $FlowFixMe[method-unbinding]
            index.window.addEventListener('webkitfullscreenchange', this._onWindowResize, false);
            // $FlowFixMe[method-unbinding]
            index.window.addEventListener('visibilitychange', this._onVisibilityChange, false);
        }

        this.handlers = new HandlerManager(this, options);

        this._localFontFamily = options.localFontFamily;
        this._localIdeographFontFamily = options.localIdeographFontFamily;

        if (options.style) {
            this.setStyle(options.style, {localFontFamily: this._localFontFamily, localIdeographFontFamily: this._localIdeographFontFamily});
        }

        if (options.projection) {
            this.setProjection(options.projection);
        }

        const hashName = (typeof options.hash === 'string' && options.hash) || undefined;
        this._hash = options.hash && (new Hash(hashName)).addTo(this);
        // don't set position from options if set through hash
        if (!this._hash || !this._hash._onHashChange()) {
            this.jumpTo({
                center: options.center,
                zoom: options.zoom,
                bearing: options.bearing,
                pitch: options.pitch
            });

            if (options.bounds) {
                this.resize();
                this.fitBounds(options.bounds, index.extend({}, options.fitBoundsOptions, {duration: 0}));
            }
        }

        this.resize();

        if (options.attributionControl)
            // $FlowFixMe[method-unbinding]
            this.addControl(new AttributionControl({customAttribution: options.customAttribution}));

        // $FlowFixMe[method-unbinding]
        this._logoControl = new LogoControl();
        // $FlowFixMe[method-unbinding]
        this.addControl(this._logoControl, options.logoPosition);

        this.on('style.load', () => {
            if (this.transform.unmodified) {
                this.jumpTo((this.style.stylesheet     ));
            }
        });
        this.on('data', (event              ) => {
            this._update(event.dataType === 'style');
            this.fire(new index.Event(`${event.dataType}data`, event));
        });
        this.on('dataloading', (event              ) => {
            this.fire(new index.Event(`${event.dataType}dataloading`, event));
        });
    }

    /*
    * Returns a unique number for this map instance which is used for the MapLoadEvent
    * to make sure we only fire one event per instantiated map object.
    * @private
    * @returns {number}
    */
    _getMapId()         {
        return this._mapId;
    }

    /** @section {Controls} */

    /**
     * Adds an {@link IControl} to the map, calling `control.onAdd(this)`.
     *
     * @param {IControl} control The {@link IControl} to add.
     * @param {string} [position] Position on the map to which the control will be added.
     * Valid values are `'top-left'`, `'top-right'`, `'bottom-left'`, and `'bottom-right'`. Defaults to `'top-right'`.
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * // Add zoom and rotation controls to the map.
     * map.addControl(new mapboxgl.NavigationControl());
     * @see [Example: Display map navigation controls](https://www.mapbox.com/mapbox-gl-js/example/navigation/)
     */
    addControl(control          , position                  )       {
        if (position === undefined) {
            if (control.getDefaultPosition) {
                position = control.getDefaultPosition();
            } else {
                position = 'top-right';
            }
        }
        if (!control || !control.onAdd) {
            return this.fire(new index.ErrorEvent(new Error(
                'Invalid argument to map.addControl(). Argument must be a control with onAdd and onRemove methods.')));
        }
        const controlElement = control.onAdd(this);
        this._controls.push(control);

        const positionContainer = this._controlPositions[position];
        if (position.indexOf('bottom') !== -1) {
            positionContainer.insertBefore(controlElement, positionContainer.firstChild);
        } else {
            positionContainer.appendChild(controlElement);
        }
        return this;
    }

    /**
     * Removes the control from the map.
     *
     * @param {IControl} control The {@link IControl} to remove.
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * // Define a new navigation control.
     * const navigation = new mapboxgl.NavigationControl();
     * // Add zoom and rotation controls to the map.
     * map.addControl(navigation);
     * // Remove zoom and rotation controls from the map.
     * map.removeControl(navigation);
     */
    removeControl(control          )       {
        if (!control || !control.onRemove) {
            return this.fire(new index.ErrorEvent(new Error(
                'Invalid argument to map.removeControl(). Argument must be a control with onAdd and onRemove methods.')));
        }
        const ci = this._controls.indexOf(control);
        if (ci > -1) this._controls.splice(ci, 1);
        control.onRemove(this);
        return this;
    }

    /**
     * Checks if a control is on the map.
     *
     * @param {IControl} control The {@link IControl} to check.
     * @returns {boolean} True if map contains control.
     * @example
     * // Define a new navigation control.
     * const navigation = new mapboxgl.NavigationControl();
     * // Add zoom and rotation controls to the map.
     * map.addControl(navigation);
     * // Check that the navigation control exists on the map.
     * const added = map.hasControl(navigation);
     * // added === true
     */
    hasControl(control          )          {
        return this._controls.indexOf(control) > -1;
    }

    /**
     * Returns the map's containing HTML element.
     *
     * @returns {HTMLElement} The map's container.
     * @example
     * const container = map.getContainer();
     */
    getContainer()              {
        return this._container;
    }

    /**
     * Returns the HTML element containing the map's `<canvas>` element.
     *
     * If you want to add non-GL overlays to the map, you should append them to this element.
     *
     * This is the element to which event bindings for map interactivity (such as panning and zooming) are
     * attached. It will receive bubbled events from child elements such as the `<canvas>`, but not from
     * map controls.
     *
     * @returns {HTMLElement} The container of the map's `<canvas>`.
     * @example
     * const canvasContainer = map.getCanvasContainer();
     * @see [Example: Create a draggable point](https://www.mapbox.com/mapbox-gl-js/example/drag-a-point/)
     * @see [Example: Highlight features within a bounding box](https://www.mapbox.com/mapbox-gl-js/example/using-box-queryrenderedfeatures/)
     */
    getCanvasContainer()              {
        return this._canvasContainer;
    }

    /**
     * Returns the map's `<canvas>` element.
     *
     * @returns {HTMLCanvasElement} The map's `<canvas>` element.
     * @example
     * const canvas = map.getCanvas();
     * @see [Example: Measure distances](https://www.mapbox.com/mapbox-gl-js/example/measure/)
     * @see [Example: Display a popup on hover](https://www.mapbox.com/mapbox-gl-js/example/popup-on-hover/)
     * @see [Example: Center the map on a clicked symbol](https://www.mapbox.com/mapbox-gl-js/example/center-on-symbol/)
     */
    getCanvas()                    {
        return this._canvas;
    }

    /** @section {Map constraints} */

    /**
     * Resizes the map according to the dimensions of its
     * `container` element.
     *
     * Checks if the map container size changed and updates the map if it has changed.
     * This method must be called after the map's `container` is resized programmatically
     * or when the map is shown after being initially hidden with CSS.
     *
     * @param {Object | null} eventData Additional properties to be passed to `movestart`, `move`, `resize`, and `moveend`
     *   events that get triggered as a result of resize. This can be useful for differentiating the
     *   source of an event (for example, user-initiated or programmatically-triggered events).
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * // Resize the map when the map container is shown
     * // after being initially hidden with CSS.
     * const mapDiv = document.getElementById('map');
     * if (mapDiv.style.visibility === true) map.resize();
     */
    resize(eventData         )       {
        this._updateContainerDimensions();

        // do nothing if container remained the same size
        if (this._containerWidth === this.transform.width && this._containerHeight === this.transform.height) return this;

        this._resizeCanvas(this._containerWidth, this._containerHeight);

        this.transform.resize(this._containerWidth, this._containerHeight);
        this.painter.resize(Math.ceil(this._containerWidth), Math.ceil(this._containerHeight));

        const fireMoving = !this._moving;
        if (fireMoving) {
            this.fire(new index.Event('movestart', eventData))
                .fire(new index.Event('move', eventData));
        }

        this.fire(new index.Event('resize', eventData));

        if (fireMoving) this.fire(new index.Event('moveend', eventData));

        return this;
    }

    /**
     * Returns the map's geographical bounds. When the bearing or pitch is non-zero, the visible region is not
     * an axis-aligned rectangle, and the result is the smallest bounds that encompasses the visible region.
     * If a padding is set on the map, the bounds returned are for the inset.
     * With globe projection, the smallest bounds encompassing the visible region
     * may not precisely represent the visible region due to the earth's curvature.
     *
     * @returns {LngLatBounds} The geographical bounds of the map as {@link LngLatBounds}.
     * @example
     * const bounds = map.getBounds();
     */
    getBounds()                      {
        return this.transform.getBounds();
    }

    /**
     * Returns the maximum geographical bounds the map is constrained to, or `null` if none set.
     *
     * @returns {Map} The map object.
     *
     * @example
     * const maxBounds = map.getMaxBounds();
     */
    getMaxBounds()                      {
        return this.transform.getMaxBounds() || null;
    }

    /**
     * Sets or clears the map's geographical bounds.
     *
     * Pan and zoom operations are constrained within these bounds.
     * If a pan or zoom is performed that would
     * display regions outside these bounds, the map will
     * instead display a position and zoom level
     * as close as possible to the operation's request while still
     * remaining within the bounds.
     *
     * For `mercator` projection, the viewport will be constrained to the bounds.
     * For other projections such as `globe`, only the map center will be constrained.
     *
     * @param {LngLatBoundsLike | null | undefined} bounds The maximum bounds to set. If `null` or `undefined` is provided, the function removes the map's maximum bounds.
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * // Define bounds that conform to the `LngLatBoundsLike` object.
     * const bounds = [
     *     [-74.04728, 40.68392], // [west, south]
     *     [-73.91058, 40.87764]  // [east, north]
     * ];
     * // Set the map's max bounds.
     * map.setMaxBounds(bounds);
     */
    setMaxBounds(bounds                  )       {
        this.transform.setMaxBounds(index.LngLatBounds.convert(bounds));
        return this._update();
    }

    /**
     * Sets or clears the map's minimum zoom level.
     * If the map's current zoom level is lower than the new minimum,
     * the map will zoom to the new minimum.
     *
     * It is not always possible to zoom out and reach the set `minZoom`.
     * Other factors such as map height may restrict zooming. For example,
     * if the map is 512px tall it will not be possible to zoom below zoom 0
     * no matter what the `minZoom` is set to.
     *
     * @param {number | null | undefined} minZoom The minimum zoom level to set (-2 - 24).
     *   If `null` or `undefined` is provided, the function removes the current minimum zoom and it will be reset to -2.
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * map.setMinZoom(12.25);
     */
    setMinZoom(minZoom          )       {

        minZoom = minZoom === null || minZoom === undefined ? defaultMinZoom : minZoom;

        if (minZoom >= defaultMinZoom && minZoom <= this.transform.maxZoom) {
            this.transform.minZoom = minZoom;
            this._update();

            if (this.getZoom() < minZoom) {
                this.setZoom(minZoom);
            } else {
                this.fire(new index.Event('zoomstart'))
                    .fire(new index.Event('zoom'))
                    .fire(new index.Event('zoomend'));
            }

            return this;

        } else throw new Error(`minZoom must be between ${defaultMinZoom} and the current maxZoom, inclusive`);
    }

    /**
     * Returns the map's minimum allowable zoom level.
     *
     * @returns {number} Returns `minZoom`.
     * @example
     * const minZoom = map.getMinZoom();
     */
    getMinZoom()         { return this.transform.minZoom; }

    /**
     * Sets or clears the map's maximum zoom level.
     * If the map's current zoom level is higher than the new maximum,
     * the map will zoom to the new maximum.
     *
     * @param {number | null | undefined} maxZoom The maximum zoom level to set.
     *   If `null` or `undefined` is provided, the function removes the current maximum zoom (sets it to 22).
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * map.setMaxZoom(18.75);
     */
    setMaxZoom(maxZoom          )       {

        maxZoom = maxZoom === null || maxZoom === undefined ? defaultMaxZoom : maxZoom;

        if (maxZoom >= this.transform.minZoom) {
            this.transform.maxZoom = maxZoom;
            this._update();

            if (this.getZoom() > maxZoom) {
                this.setZoom(maxZoom);
            } else {
                this.fire(new index.Event('zoomstart'))
                    .fire(new index.Event('zoom'))
                    .fire(new index.Event('zoomend'));
            }

            return this;

        } else throw new Error(`maxZoom must be greater than the current minZoom`);
    }

    /**
     * Returns the map's maximum allowable zoom level.
     *
     * @returns {number} Returns `maxZoom`.
     * @example
     * const maxZoom = map.getMaxZoom();
     */
    getMaxZoom()         { return this.transform.maxZoom; }

    /**
     * Sets or clears the map's minimum pitch.
     * If the map's current pitch is lower than the new minimum,
     * the map will pitch to the new minimum.
     *
     * @param {number | null | undefined} minPitch The minimum pitch to set (0-85). If `null` or `undefined` is provided, the function removes the current minimum pitch and resets it to 0.
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * map.setMinPitch(5);
     */
    setMinPitch(minPitch          )       {

        minPitch = minPitch === null || minPitch === undefined ? defaultMinPitch : minPitch;

        if (minPitch < defaultMinPitch) {
            throw new Error(`minPitch must be greater than or equal to ${defaultMinPitch}`);
        }

        if (minPitch >= defaultMinPitch && minPitch <= this.transform.maxPitch) {
            this.transform.minPitch = minPitch;
            this._update();

            if (this.getPitch() < minPitch) {
                this.setPitch(minPitch);
            } else {
                this.fire(new index.Event('pitchstart'))
                    .fire(new index.Event('pitch'))
                    .fire(new index.Event('pitchend'));
            }

            return this;

        } else throw new Error(`minPitch must be between ${defaultMinPitch} and the current maxPitch, inclusive`);
    }

    /**
     * Returns the map's minimum allowable pitch.
     *
     * @returns {number} Returns `minPitch`.
     * @example
     * const minPitch = map.getMinPitch();
     */
    getMinPitch()         { return this.transform.minPitch; }

    /**
     * Sets or clears the map's maximum pitch.
     * If the map's current pitch is higher than the new maximum,
     * the map will pitch to the new maximum.
     *
     * @param {number | null | undefined} maxPitch The maximum pitch to set.
     *   If `null` or `undefined` is provided, the function removes the current maximum pitch (sets it to 85).
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * map.setMaxPitch(70);
     */
    setMaxPitch(maxPitch          )       {

        maxPitch = maxPitch === null || maxPitch === undefined ? defaultMaxPitch : maxPitch;

        if (maxPitch > defaultMaxPitch) {
            throw new Error(`maxPitch must be less than or equal to ${defaultMaxPitch}`);
        }

        if (maxPitch >= this.transform.minPitch) {
            this.transform.maxPitch = maxPitch;
            this._update();

            if (this.getPitch() > maxPitch) {
                this.setPitch(maxPitch);
            } else {
                this.fire(new index.Event('pitchstart'))
                    .fire(new index.Event('pitch'))
                    .fire(new index.Event('pitchend'));
            }

            return this;

        } else throw new Error(`maxPitch must be greater than or equal to minPitch`);
    }

    /**
     * Returns the map's maximum allowable pitch.
     *
     * @returns {number} Returns `maxPitch`.
     * @example
     * const maxPitch = map.getMaxPitch();
     */
    getMaxPitch()         { return this.transform.maxPitch; }

    /**
     * Returns the state of `renderWorldCopies`. If `true`, multiple copies of the world will be rendered side by side beyond -180 and 180 degrees longitude. If set to `false`:
     * - When the map is zoomed out far enough that a single representation of the world does not fill the map's entire
     * container, there will be blank space beyond 180 and -180 degrees longitude.
     * - Features that cross 180 and -180 degrees longitude will be cut in two (with one portion on the right edge of the
     * map and the other on the left edge of the map) at every zoom level.
     *
     * @returns {boolean} Returns `renderWorldCopies` boolean.
     * @example
     * const worldCopiesRendered = map.getRenderWorldCopies();
     * @see [Example: Render world copies](https://docs.mapbox.com/mapbox-gl-js/example/render-world-copies/)
     */
    getRenderWorldCopies()          { return this.transform.renderWorldCopies; }

    /**
     * Sets the state of `renderWorldCopies`.
     *
     * @param {boolean} renderWorldCopies If `true`, multiple copies of the world will be rendered side by side beyond -180 and 180 degrees longitude. If set to `false`:
     * - When the map is zoomed out far enough that a single representation of the world does not fill the map's entire
     * container, there will be blank space beyond 180 and -180 degrees longitude.
     * - Features that cross 180 and -180 degrees longitude will be cut in two (with one portion on the right edge of the
     * map and the other on the left edge of the map) at every zoom level.
     *
     * `undefined` is treated as `true`, `null` is treated as `false`.
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * map.setRenderWorldCopies(true);
     * @see [Example: Render world copies](https://docs.mapbox.com/mapbox-gl-js/example/render-world-copies/)
     */
    setRenderWorldCopies(renderWorldCopies           )       {
        this.transform.renderWorldCopies = renderWorldCopies;
        if (!this.transform.renderWorldCopies) {
            this._forceMarkerAndPopupUpdate(true);
        }
        return this._update();
    }

    /**
     * Returns the map's language, which is used for translating map labels and UI components.
     *
     * @private
     * @returns {undefined | string | string[]} Returns the map's language code.
     * @example
     * const language = map.getLanguage();
     */
    getLanguage()                      {
        return this._language;
    }

    _parseLanguage(language                               )                      {
        if (language === 'auto') return index.window.navigator.language;
        if (Array.isArray(language)) return language.length === 0 ?
            undefined :
            language.map(l => l === 'auto' ? index.window.navigator.language : l);

        return language;
    }

    /**
     * Sets the map's language, which is used for translating map labels and UI components.
     *
     * @private
     * @param {'auto' | string | string[]} [language] A string representing the desired language used for the map's labels and UI components. Languages can only be set on Mapbox vector tile sources.
     *  Valid language strings must be a [BCP-47 language code](https://en.wikipedia.org/wiki/IETF_language_tag#List_of_subtags). Unsupported BCP-47 codes will not include any translations. Invalid codes will result in an recoverable error.
     *  If a label has no translation for the selected language, it will display in the label's local language.
     *  If param is set to `auto`, GL JS will select a user's preferred language as determined by the browser's [`window.navigator.language`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/language) property.
     *  If the `locale` property is not set separately, this language will also be used to localize the UI for supported languages.
     *  If param is set to `undefined` or `null`, it will remove the current map language and reset the language used for translating map labels and UI components.
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * map.setLanguage('es');
     *
     * @example
     * map.setLanguage(['en-GB', 'en-US']);
     *
     * @example
     * map.setLanguage('auto');
     *
     * @example
     * map.setLanguage();
     */
    setLanguage(language                               )       {
        const newLanguage = this._parseLanguage(language);
        if (!this.style || newLanguage === this._language) return this;
        this._language = newLanguage;

        this.style._reloadSources();

        for (const control of this._controls) {
            if (control._setLanguage) {
                control._setLanguage(this._language);
            }
        }

        return this;
    }

    /**
     * Returns the code for the map's worldview.
     *
     * @private
     * @returns {string} Returns the map's worldview code.
     * @example
     * const worldview = map.getWorldview();
     */
    getWorldview()          {
        return this._worldview;
    }

    /**
     * Sets the map's worldview.
     *
     * @private
     * @param {string} [worldview] A string representing the desired worldview.
     *  A worldview determines the way that certain disputed boundaries are rendered.
     *  Valid worldview strings must be an [ISO alpha-2 country code](https://en.wikipedia.org/wiki/ISO_3166-1#Current_codes).
     *  Unsupported ISO alpha-2 codes will fall back to the TileJSON's default worldview. Invalid codes will result in a recoverable error.
     *  If param is set to `undefined` or `null`, it will cause the map to fall back to the TileJSON's default worldview.
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * map.setWorldView('JP');
     *
     * @example
     * map.setWorldView();
     */
    setWorldview(worldview          )       {
        if (!this.style || worldview === this._worldview) return this;

        this._worldview = worldview;
        this.style._reloadSources();

        return this;
    }

    /** @section {Point conversion} */

    /**
     * Returns a [projection](https://docs.mapbox.com/mapbox-gl-js/style-spec/projection/) object that defines the current map projection.
     *
     * @returns {ProjectionSpecification} The [projection](https://docs.mapbox.com/mapbox-gl-js/style-spec/projection/) defining the current map projection.
     * @example
     * const projection = map.getProjection();
     */
    getProjection()                          {
        if (this.transform.mercatorFromTransition) {
            return {name: "globe", center: [0, 0]};
        }
        return this.transform.getProjection();
    }

    /**
     * Returns true if map [projection](https://docs.mapbox.com/mapbox-gl-js/style-spec/projection/) has been set to globe AND the map is at a low enough zoom level that globe view is enabled.
     * @private
     * @returns {boolean} Returns `globe-is-active` boolean.
     * @example
     * if (map._showingGlobe()) {
     *     // do globe things here
     * }
     */
    _showingGlobe()          { return this.transform.projection.name === 'globe'; }

    /**
     * Sets the map's projection. If called with `null` or `undefined`, the map will reset to Mercator.
     *
     * @param {ProjectionSpecification | string | null | undefined} projection The projection that the map should be rendered in.
     * This can be a [projection](https://docs.mapbox.com/mapbox-gl-js/style-spec/projection/) object or a string of the projection's name.
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * map.setProjection('albers');
     * map.setProjection({
     *     name: 'albers',
     *     center: [35, 55],
     *     parallels: [20, 60]
     * });
     * @see [Example: Display a web map using an alternate projection](https://docs.mapbox.com/mapbox-gl-js/example/map-projection/)
     * @see [Example: Use different map projections for web maps](https://docs.mapbox.com/mapbox-gl-js/example/projections/)
     */
    setProjection(projection                                    )       {
        this._lazyInitEmptyStyle();

        if (!projection) {
            projection = null;
        } else if (typeof projection === 'string') {
            projection = (({name: projection}     )                         );
        }

        this._useExplicitProjection = !!projection;
        const stylesheetProjection = this.style.stylesheet ? this.style.stylesheet.projection : null;
        return this._prioritizeAndUpdateProjection(projection, stylesheetProjection);
    }

    _updateProjectionTransition() {
        // The projection isn't globe, we can skip updating the transition
        if (this.getProjection().name !== 'globe') {
            return;
        }

        const tr = this.transform;
        const projection = tr.projection.name;
        let projectionHasChanged;

        if (projection === 'globe' && tr.zoom >= index.GLOBE_ZOOM_THRESHOLD_MAX) {
            tr.setMercatorFromTransition();
            projectionHasChanged = true;
        } else if (projection === 'mercator' && tr.zoom < index.GLOBE_ZOOM_THRESHOLD_MAX) {
            tr.setProjection({name: 'globe'});
            projectionHasChanged = true;
        }

        if (projectionHasChanged) {
            this.style.applyProjectionUpdate();
            this.style._forceSymbolLayerUpdate();
        }
    }

    _prioritizeAndUpdateProjection(explicitProjection                          , styleProjection                          )       {
        // Given a stylesheet and eventual runtime projection, in order of priority, we select:
        //  1. the explicit projection
        //  2. the stylesheet projection
        //  3. mercator (fallback)
        const prioritizedProjection = explicitProjection || styleProjection || {name: "mercator"};

        return this._updateProjection(prioritizedProjection);
    }

    _updateProjection(projection                         )       {
        let projectionHasChanged;

        if (projection.name === 'globe' && this.transform.zoom >= index.GLOBE_ZOOM_THRESHOLD_MAX) {
            projectionHasChanged = this.transform.setMercatorFromTransition();
        } else {
            projectionHasChanged = this.transform.setProjection(projection);
        }

        this.style.applyProjectionUpdate();

        if (projectionHasChanged) {
            this.painter.clearBackgroundTiles();
            for (const id in this.style._sourceCaches) {
                this.style._sourceCaches[id].clearTiles();
            }
            this._update(true);
            this._forceMarkerAndPopupUpdate(true);
        }

        return this;
    }

    /**
     * Returns a {@link Point} representing pixel coordinates, relative to the map's `container`,
     * that correspond to the specified geographical location.
     *
     * When the map is pitched and `lnglat` is completely behind the camera, there are no pixel
     * coordinates corresponding to that location. In that case,
     * the `x` and `y` components of the returned {@link Point} are set to Number.MAX_VALUE.
     *
     * @param {LngLatLike} lnglat The geographical location to project.
     * @returns {Point} The {@link Point} corresponding to `lnglat`, relative to the map's `container`.
     * @example
     * const coordinate = [-122.420679, 37.772537];
     * const point = map.project(coordinate);
     */
    project(lnglat            )        {
        return this.transform.locationPoint3D(index.LngLat.convert(lnglat));
    }

    /**
     * Returns a {@link LngLat} representing geographical coordinates that correspond
     * to the specified pixel coordinates. If horizon is visible, and specified pixel is
     * above horizon, returns a {@link LngLat} corresponding to point on horizon, nearest
     * to the point.
     *
     * @param {PointLike} point The pixel coordinates to unproject.
     * @returns {LngLat} The {@link LngLat} corresponding to `point`.
     * @example
     * map.on('click', (e) => {
     *     // When the map is clicked, get the geographic coordinate.
     *     const coordinate = map.unproject(e.point);
     * });
     */
    unproject(point           )         {
        return this.transform.pointLocation3D(index.Point.convert(point));
    }

    /** @section {Movement state} */

    /**
     * Returns true if the map is panning, zooming, rotating, or pitching due to a camera animation or user gesture.
     *
     * @returns {boolean} True if the map is moving.
     * @example
     * const isMoving = map.isMoving();
     */
    isMoving()          {
        return this._moving || (this.handlers && this.handlers.isMoving()) || false;
    }

    /**
     * Returns true if the map is zooming due to a camera animation or user gesture.
     *
     * @returns {boolean} True if the map is zooming.
     * @example
     * const isZooming = map.isZooming();
     */
    isZooming()          {
        return this._zooming || (this.handlers && this.handlers.isZooming()) || false;
    }

    /**
     * Returns true if the map is rotating due to a camera animation or user gesture.
     *
     * @returns {boolean} True if the map is rotating.
     * @example
     * map.isRotating();
     */
    isRotating()          {
        return this._rotating || (this.handlers && this.handlers.isRotating()) || false;
    }

    _isDragging()          {
        return (this.handlers && this.handlers._isDragging()) || false;
    }

    _createDelegatedListener(type          , layers            , listener     )      {
        if (type === 'mouseenter' || type === 'mouseover') {
            let mousein = false;
            const mousemove = (e               ) => {
                const filteredLayers = layers.filter(layerId => this.getLayer(layerId));
                const features = filteredLayers.length ? this.queryRenderedFeatures(e.point, {layers: filteredLayers}) : [];
                if (!features.length) {
                    mousein = false;
                } else if (!mousein) {
                    mousein = true;
                    listener.call(this, new MapMouseEvent(type, this, e.originalEvent, {features}));
                }
            };
            const mouseout = () => {
                mousein = false;
            };

            return {layers: new Set(layers), listener, delegates: {mousemove, mouseout}};
        } else if (type === 'mouseleave' || type === 'mouseout') {
            let mousein = false;
            const mousemove = (e               ) => {
                const filteredLayers = layers.filter(layerId => this.getLayer(layerId));
                const features = filteredLayers.length ? this.queryRenderedFeatures(e.point, {layers: filteredLayers}) : [];
                if (features.length) {
                    mousein = true;
                } else if (mousein) {
                    mousein = false;
                    listener.call(this, new MapMouseEvent(type, this, e.originalEvent));
                }
            };
            const mouseout = (e               ) => {
                if (mousein) {
                    mousein = false;
                    listener.call(this, new MapMouseEvent(type, this, e.originalEvent));
                }
            };

            return {layers: new Set(layers), listener, delegates: {mousemove, mouseout}};
        } else {
            const delegate = (e               ) => {
                const filteredLayers = layers.filter(layerId => this.getLayer(layerId));
                const features = filteredLayers.length ? this.queryRenderedFeatures(e.point, {layers: filteredLayers}) : [];
                if (features.length) {
                    // Here we need to mutate the original event, so that preventDefault works as expected.
                    e.features = features;
                    listener.call(this, e);
                    delete e.features;
                }
            };

            return {layers: new Set(layers), listener, delegates: {[(type        )]: delegate}};
        }
    }

    /** @section {Working with events} */

    /**
     * Adds a listener for events of a specified type,
     * optionally limited to features in a specified style layer.
     *
     * @param {string} type The event type to listen for. Events compatible with the optional `layerId` parameter are triggered
     * when the cursor enters a visible portion of the specified layer from outside that layer or outside the map canvas.
     *
     * | Event                                                     | Compatible with `layerId` |
     * |-----------------------------------------------------------|---------------------------|
     * | [`mousedown`](#map.event:mousedown)                       | yes                       |
     * | [`mouseup`](#map.event:mouseup)                           | yes                       |
     * | [`mouseover`](#map.event:mouseover)                       | yes                       |
     * | [`mouseout`](#map.event:mouseout)                         | yes                       |
     * | [`mousemove`](#map.event:mousemove)                       | yes                       |
     * | [`mouseenter`](#map.event:mouseenter)                     | yes (required)            |
     * | [`mouseleave`](#map.event:mouseleave)                     | yes (required)            |
     * | [`preclick`](#map.event:preclick)                         |                           |
     * | [`click`](#map.event:click)                               | yes                       |
     * | [`dblclick`](#map.event:dblclick)                         | yes                       |
     * | [`contextmenu`](#map.event:contextmenu)                   | yes                       |
     * | [`touchstart`](#map.event:touchstart)                     | yes                       |
     * | [`touchend`](#map.event:touchend)                         | yes                       |
     * | [`touchcancel`](#map.event:touchcancel)                   | yes                       |
     * | [`wheel`](#map.event:wheel)                               |                           |
     * | [`resize`](#map.event:resize)                             |                           |
     * | [`remove`](#map.event:remove)                             |                           |
     * | [`touchmove`](#map.event:touchmove)                       |                           |
     * | [`movestart`](#map.event:movestart)                       |                           |
     * | [`move`](#map.event:move)                                 |                           |
     * | [`moveend`](#map.event:moveend)                           |                           |
     * | [`dragstart`](#map.event:dragstart)                       |                           |
     * | [`drag`](#map.event:drag)                                 |                           |
     * | [`dragend`](#map.event:dragend)                           |                           |
     * | [`zoomstart`](#map.event:zoomstart)                       |                           |
     * | [`zoom`](#map.event:zoom)                                 |                           |
     * | [`zoomend`](#map.event:zoomend)                           |                           |
     * | [`rotatestart`](#map.event:rotatestart)                   |                           |
     * | [`rotate`](#map.event:rotate)                             |                           |
     * | [`rotateend`](#map.event:rotateend)                       |                           |
     * | [`pitchstart`](#map.event:pitchstart)                     |                           |
     * | [`pitch`](#map.event:pitch)                               |                           |
     * | [`pitchend`](#map.event:pitchend)                         |                           |
     * | [`boxzoomstart`](#map.event:boxzoomstart)                 |                           |
     * | [`boxzoomend`](#map.event:boxzoomend)                     |                           |
     * | [`boxzoomcancel`](#map.event:boxzoomcancel)               |                           |
     * | [`webglcontextlost`](#map.event:webglcontextlost)         |                           |
     * | [`webglcontextrestored`](#map.event:webglcontextrestored) |                           |
     * | [`load`](#map.event:load)                                 |                           |
     * | [`render`](#map.event:render)                             |                           |
     * | [`idle`](#map.event:idle)                                 |                           |
     * | [`error`](#map.event:error)                               |                           |
     * | [`data`](#map.event:data)                                 |                           |
     * | [`styledata`](#map.event:styledata)                       |                           |
     * | [`sourcedata`](#map.event:sourcedata)                     |                           |
     * | [`dataloading`](#map.event:dataloading)                   |                           |
     * | [`styledataloading`](#map.event:styledataloading)         |                           |
     * | [`sourcedataloading`](#map.event:sourcedataloading)       |                           |
     * | [`styleimagemissing`](#map.event:styleimagemissing)       |                           |
     * | [`style.load`](#map.event:style.load)                     |                           |
     *
     * @param {string | Array<string>} layerIds (optional) The ID(s) of a style layer(s). If you provide a `layerId`,
     * the listener will be triggered only if its location is within a visible feature in these layers,
     * and the event will have a `features` property containing an array of the matching features.
     * If you do not provide `layerIds`, the listener will be triggered by a corresponding event
     * happening anywhere on the map, and the event will not have a `features` property.
     * Note that many event types are not compatible with the optional `layerIds` parameter.
     * @param {Function} listener The function to be called when the event is fired.
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * // Set an event listener that will fire
     * // when the map has finished loading.
     * map.on('load', () => {
     *     // Add a new layer.
     *     map.addLayer({
     *         id: 'points-of-interest',
     *         source: {
     *             type: 'vector',
     *             url: 'mapbox://mapbox.mapbox-streets-v8'
     *         },
     *         'source-layer': 'poi_label',
     *         type: 'circle',
     *         paint: {
     *             // Mapbox Style Specification paint properties
     *         },
     *         layout: {
     *             // Mapbox Style Specification layout properties
     *         }
     *     });
     * });
     * @example
     * // Set an event listener that will fire
     * // when a feature on the countries layer of the map is clicked.
     * map.on('click', 'countries', (e) => {
     *     new mapboxgl.Popup()
     *         .setLngLat(e.lngLat)
     *         .setHTML(`Country name: ${e.features[0].properties.name}`)
     *         .addTo(map);
     * });
     * @example
     * // Set an event listener that will fire
     * // when a feature on the countries or background layers of the map is clicked.
     * map.on('click', ['countries', 'background'], (e) => {
     *     new mapboxgl.Popup()
     *         .setLngLat(e.lngLat)
     *         .setHTML(`Country name: ${e.features[0].properties.name}`)
     *         .addTo(map);
     * });
     * @see [Example: Add 3D terrain to a map](https://docs.mapbox.com/mapbox-gl-js/example/add-terrain/)
     * @see [Example: Center the map on a clicked symbol](https://docs.mapbox.com/mapbox-gl-js/example/center-on-symbol/)
     * @see [Example: Create a draggable marker](https://docs.mapbox.com/mapbox-gl-js/example/drag-a-point/)
     * @see [Example: Create a hover effect](https://docs.mapbox.com/mapbox-gl-js/example/hover-styles/)
     * @see [Example: Display popup on click](https://docs.mapbox.com/mapbox-gl-js/example/popup-on-click/)
     */
    on(type          , layerIds     , listener     )       {
        if (listener === undefined) {
            return super.on(type, layerIds);
        }

        if (!Array.isArray(layerIds)) {
            layerIds = [layerIds];
        }
        const delegatedListener = this._createDelegatedListener(type, layerIds, listener);

        this._delegatedListeners = this._delegatedListeners || {};
        this._delegatedListeners[type] = this._delegatedListeners[type] || [];
        this._delegatedListeners[type].push(delegatedListener);

        for (const event in delegatedListener.delegates) {
            this.on((event     ), delegatedListener.delegates[event]);
        }

        return this;
    }

    /**
     * Adds a listener that will be called only once to a specified event type,
     * optionally limited to events occurring on features in a specified style layer.
     *
     * @param {string} type The event type to listen for; one of `'mousedown'`, `'mouseup'`, `'preclick'`, `'click'`, `'dblclick'`,
     * `'mousemove'`, `'mouseenter'`, `'mouseleave'`, `'mouseover'`, `'mouseout'`, `'contextmenu'`, `'touchstart'`,
     * `'touchend'`, or `'touchcancel'`. `mouseenter` and `mouseover` events are triggered when the cursor enters
     * a visible portion of the specified layer from outside that layer or outside the map canvas. `mouseleave`
     * and `mouseout` events are triggered when the cursor leaves a visible portion of the specified layer, or leaves
     * the map canvas.
     * @param {string | Array<string>} layerIds (optional) The ID(s) of a style layer(s). If you provide `layerIds`,
     * the listener will be triggered only if its location is within a visible feature in these layers,
     * and the event will have a `features` property containing an array of the matching features.
     * If you do not provide `layerIds`, the listener will be triggered by a corresponding event
     * happening anywhere on the map, and the event will not have a `features` property.
     * Note that many event types are not compatible with the optional `layerIds` parameter.
     * @param {Function} listener The function to be called when the event is fired.
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * // Log the coordinates of a user's first map touch.
     * map.once('touchstart', (e) => {
     *     console.log(`The first map touch was at: ${e.lnglat}`);
     * });
     * @example
     * // Log the coordinates of a user's first map touch
     * // on a specific layer.
     * map.once('touchstart', 'my-point-layer', (e) => {
     *     console.log(`The first map touch on the point layer was at: ${e.lnglat}`);
     * });
     * @example
     * // Log the coordinates of a user's first map touch
     * // on specific layers.
     * map.once('touchstart', ['my-point-layer', 'my-point-layer-2'], (e) => {
     *     console.log(`The first map touch on the point layer was at: ${e.lnglat}`);
     * });
     * @see [Example: Create a draggable point](https://docs.mapbox.com/mapbox-gl-js/example/drag-a-point/)
     * @see [Example: Animate the camera around a point with 3D terrain](https://docs.mapbox.com/mapbox-gl-js/example/free-camera-point/)
     * @see [Example: Play map locations as a slideshow](https://docs.mapbox.com/mapbox-gl-js/example/playback-locations/)
     */
    once(type          , layerIds     , listener     )                        {

        if (listener === undefined) {
            return super.once(type, layerIds);
        }

        if (!Array.isArray(layerIds)) {
            layerIds = [layerIds];
        }
        const delegatedListener = this._createDelegatedListener(type, layerIds, listener);

        for (const event in delegatedListener.delegates) {
            this.once((event     ), delegatedListener.delegates[event]);
        }

        return this;
    }

    /**
     * Removes an event listener previously added with {@link Map#on},
     * optionally limited to layer-specific events.
     *
     * @param {string} type The event type previously used to install the listener.
     * @param {string | Array<string>} layerIds (optional) The layer ID(s) previously used to install the listener.
     * @param {Function} listener The function previously installed as a listener.
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * // Create a function to print coordinates while a mouse is moving.
     * function onMove(e) {
     *     console.log(`The mouse is moving: ${e.lngLat}`);
     * }
     * // Create a function to unbind the `mousemove` event.
     * function onUp(e) {
     *     console.log(`The final coordinates are: ${e.lngLat}`);
     *     map.off('mousemove', onMove);
     * }
     * // When a click occurs, bind both functions to mouse events.
     * map.on('mousedown', (e) => {
     *     map.on('mousemove', onMove);
     *     map.once('mouseup', onUp);
     * });
     * @see [Example: Create a draggable point](https://docs.mapbox.com/mapbox-gl-js/example/drag-a-point/)
     */
    off(type          , layerIds     , listener     )       {
        if (listener === undefined) {
            return super.off(type, layerIds);
        }

        layerIds = new Set(Array.isArray(layerIds) ? layerIds : [layerIds]);
        const areLayerArraysEqual = (hash1             , hash2             ) => {
            if (hash1.size !== hash2.size) {
                return false; // at-least 1 arr has duplicate value(s)
            }

            // comparing values
            for (const value of hash1) {
                if (!hash2.has(value)) return false;
            }
            return true;
        };

        const removeDelegatedListeners = (listeners            ) => {
            for (let i = 0; i < listeners.length; i++) {
                const delegatedListener = listeners[i];
                if (delegatedListener.listener === listener && areLayerArraysEqual(delegatedListener.layers, layerIds)) {
                    for (const event in delegatedListener.delegates) {
                        this.off((event     ), delegatedListener.delegates[event]);
                    }
                    listeners.splice(i, 1);
                    return this;
                }
            }
        };

        const delegatedListeners = this._delegatedListeners ? this._delegatedListeners[type] : undefined;
        if (delegatedListeners) {
            removeDelegatedListeners(delegatedListeners);
        }

        return this;
    }

    /** @section {Querying features} */

    /**
     * Returns an array of [GeoJSON](http://geojson.org/)
     * [Feature objects](https://tools.ietf.org/html/rfc7946#section-3.2)
     * representing visible features that satisfy the query parameters.
     *
     * @param {PointLike|Array<PointLike>} [geometry] - The geometry of the query region in pixels:
     * either a single point or bottom left and top right points describing a bounding box, where the origin is at the top left.
     * Omitting this parameter (by calling {@link Map#queryRenderedFeatures} with zero arguments,
     * or with only an `options` argument) is equivalent to passing a bounding box encompassing the entire
     * map viewport.
     * Only values within the existing viewport are supported.
     * @param {Object} [options] Options object.
     * @param {Array<string>} [options.layers] An array of [style layer IDs](https://docs.mapbox.com/mapbox-gl-js/style-spec/#layer-id) for the query to inspect.
     *   Only features within these layers will be returned. If this parameter is undefined, all layers will be checked.
     * @param {Array} [options.filter] A [filter](https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#filter)
     *   to limit query results.
     * @param {boolean} [options.validate=true] Whether to check if the [options.filter] conforms to the Mapbox GL Style Specification. Disabling validation is a performance optimization that should only be used if you have previously validated the values you will be passing to this function.
     *
     * @returns {Array<Object>} An array of [GeoJSON](http://geojson.org/)
     * [feature objects](https://tools.ietf.org/html/rfc7946#section-3.2).
     *
     * The `properties` value of each returned feature object contains the properties of its source feature. For GeoJSON sources, only
     * string and numeric property values are supported. `null`, `Array`, and `Object` values are not supported.
     *
     * Each feature includes top-level `layer`, `source`, and `sourceLayer` properties. The `layer` property is an object
     * representing the style layer to  which the feature belongs. Layout and paint properties in this object contain values
     * which are fully evaluated for the given zoom level and feature.
     *
     * Only features that are currently rendered are included. Some features will **not** be included, like:
     *
     * - Features from layers whose `visibility` property is `"none"`.
     * - Features from layers whose zoom range excludes the current zoom level.
     * - Symbol features that have been hidden due to text or icon collision.
     *
     * Features from all other layers are included, including features that may have no visible
     * contribution to the rendered result; for example, because the layer's opacity or color alpha component is set to
     * 0.
     *
     * The topmost rendered feature appears first in the returned array, and subsequent features are sorted by
     * descending z-order. Features that are rendered multiple times (due to wrapping across the antimeridian at low
     * zoom levels) are returned only once (though subject to the following caveat).
     *
     * Because features come from tiled vector data or GeoJSON data that is converted to tiles internally, feature
     * geometries may be split or duplicated across tile boundaries and, as a result, features may appear multiple
     * times in query results. For example, suppose there is a highway running through the bounding rectangle of a query.
     * The results of the query will be those parts of the highway that lie within the map tiles covering the bounding
     * rectangle, even if the highway extends into other tiles, and the portion of the highway within each map tile
     * will be returned as a separate feature. Similarly, a point feature near a tile boundary may appear in multiple
     * tiles due to tile buffering.
     *
     * @example
     * // Find all features at a point
     * const features = map.queryRenderedFeatures(
     *   [20, 35],
     *   {layers: ['my-layer-name']}
     * );
     *
     * @example
     * // Find all features within a static bounding box
     * const features = map.queryRenderedFeatures(
     *   [[10, 20], [30, 50]],
     *   {layers: ['my-layer-name']}
     * );
     *
     * @example
     * // Find all features within a bounding box around a point
     * const width = 10;
     * const height = 20;
     * const features = map.queryRenderedFeatures([
     *     [point.x - width / 2, point.y - height / 2],
     *     [point.x + width / 2, point.y + height / 2]
     * ], {layers: ['my-layer-name']});
     *
     * @example
     * // Query all rendered features from a single layer
     * const features = map.queryRenderedFeatures({layers: ['my-layer-name']});
     * @see [Example: Get features under the mouse pointer](https://www.mapbox.com/mapbox-gl-js/example/queryrenderedfeatures/)
     * @see [Example: Highlight features within a bounding box](https://www.mapbox.com/mapbox-gl-js/example/using-box-queryrenderedfeatures/)
     * @see [Example: Filter features within map view](https://www.mapbox.com/mapbox-gl-js/example/filter-features-within-map-view/)
     */
    queryRenderedFeatures(geometry                                     , options         )                     {
        // The first parameter can be omitted entirely, making this effectively an overloaded method
        // with two signatures:
        //
        //     queryRenderedFeatures(geometry: PointLike | [PointLike, PointLike], options?: Object)
        //     queryRenderedFeatures(options?: Object)
        //
        // There no way to express that in a way that's compatible with both flow and documentation.js.
        // Related: https://github.com/facebook/flow/issues/1556

        if (!this.style) {
            return [];
        }

        if (options === undefined && geometry !== undefined && !(geometry instanceof index.Point) && !Array.isArray(geometry)) {
            options = (geometry        );
            geometry = undefined;
        }

        options = options || {};
        geometry = geometry || [([0, 0]           ), ([this.transform.width, this.transform.height]           )];

        return this.style.queryRenderedFeatures(geometry, options, this.transform);
    }

    /**
     * Returns an array of [GeoJSON](http://geojson.org/)
     * [Feature objects](https://tools.ietf.org/html/rfc7946#section-3.2)
     * representing features within the specified vector tile or GeoJSON source that satisfy the query parameters.
     *
     * @param {string} sourceId The ID of the vector tile or GeoJSON source to query.
     * @param {Object} [parameters] Options object.
     * @param {string} [parameters.sourceLayer] The name of the [source layer](https://docs.mapbox.com/help/glossary/source-layer/)
     *   to query. *For vector tile sources, this parameter is required.* For GeoJSON sources, it is ignored.
     * @param {Array} [parameters.filter] A [filter](https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#filter)
     *   to limit query results.
     * @param {boolean} [parameters.validate=true] Whether to check if the [parameters.filter] conforms to the Mapbox GL Style Specification. Disabling validation is a performance optimization that should only be used if you have previously validated the values you will be passing to this function.
     *
     * @returns {Array<Object>} An array of [GeoJSON](http://geojson.org/)
     * [Feature objects](https://tools.ietf.org/html/rfc7946#section-3.2).
     *
     * In contrast to {@link Map#queryRenderedFeatures}, this function returns all features matching the query parameters,
     * whether or not they are rendered by the current style (in other words, are visible). The domain of the query includes all currently-loaded
     * vector tiles and GeoJSON source tiles: this function does not check tiles outside the currently
     * visible viewport.
     *
     * Because features come from tiled vector data or GeoJSON data that is converted to tiles internally, feature
     * geometries may be split or duplicated across tile boundaries and, as a result, features may appear multiple
     * times in query results. For example, suppose there is a highway running through the bounding rectangle of a query.
     * The results of the query will be those parts of the highway that lie within the map tiles covering the bounding
     * rectangle, even if the highway extends into other tiles, and the portion of the highway within each map tile
     * will be returned as a separate feature. Similarly, a point feature near a tile boundary may appear in multiple
     * tiles due to tile buffering.
     *
     * @example
     * // Find all features in one source layer in a vector source
     * const features = map.querySourceFeatures('your-source-id', {
     *     sourceLayer: 'your-source-layer'
     * });
     *
     * @see [Example: Highlight features containing similar data](https://www.mapbox.com/mapbox-gl-js/example/query-similar-features/)
     */
    querySourceFeatures(sourceId        , parameters                                                                  )                      {
        return this.style.querySourceFeatures(sourceId, parameters);
    }

    /**
     * Determines if the given point is located on a visible map surface.
     *
     * @param {PointLike} point - The point to be checked, specified as an array of two numbers representing the x and y coordinates, or as a {@link https://docs.mapbox.com/mapbox-gl-js/api/geography/#point|Point} object.
     * @returns {boolean} Returns `true` if the point is on the visible map surface, otherwise returns `false`.
     * @example
     * const pointOnSurface = map.isPointOnSurface([100, 200]);
     */
    isPointOnSurface(point           )          {
        const {name} = this.transform.projection;
        if (name !== 'globe' && name !== 'mercator') {
            index.warnOnce(`${name} projection does not support isPointOnSurface, this API may behave unexpectedly.`);
        }

        return this.transform.isPointOnSurface(index.Point.convert(point));
    }

    /** @section {Working with styles} */

    /**
     * Updates the map's Mapbox style object with a new value.
     *
     * If a style is already set when this is used and the `diff` option is set to `true`, the map renderer will attempt to compare the given style
     * against the map's current state and perform only the changes necessary to make the map style match the desired state. Changes in sprites
     * (images used for icons and patterns) and glyphs (fonts for label text) **cannot** be diffed. If the sprites or fonts used in the current
     * style and the given style are different in any way, the map renderer will force a full update, removing the current style and building
     * the given one from scratch.
     *
     * @param {Object | string| null} style A JSON object conforming to the schema described in the
     *   [Mapbox Style Specification](https://mapbox.com/mapbox-gl-style-spec/), or a URL to such JSON.
     * @param {Object} [options] Options object.
     * @param {boolean} [options.diff=true] If false, force a 'full' update, removing the current style
     *   and building the given one instead of attempting a diff-based update.
     * @param {string} [options.localIdeographFontFamily='sans-serif'] Defines a CSS
     *   font-family for locally overriding generation of glyphs in the 'CJK Unified Ideographs', 'Hiragana', 'Katakana' and 'Hangul Syllables' ranges.
     *   In these ranges, font settings from the map's style will be ignored, except for font-weight keywords (light/regular/medium/bold).
     *   Set to `false`, to enable font settings from the map's style for these glyph ranges.
     *   Forces a full update.
     * @returns {Map} Returns itself to allow for method chaining.
     *
     * @example
     * map.setStyle("mapbox://styles/mapbox/streets-v11");
     *
     * @see [Example: Change a map's style](https://www.mapbox.com/mapbox-gl-js/example/setstyle/)
     */
    setStyle(style                                    , options                                  )       {
        options = index.extend({}, {localIdeographFontFamily: this._localIdeographFontFamily, localFontFamily: this._localFontFamily}, options);

        if ((options.diff !== false &&
            options.localIdeographFontFamily === this._localIdeographFontFamily &&
            options.localFontFamily === this._localFontFamily) && this.style && style) {
            this._diffStyle(style, options);
            return this;
        } else {
            this._localIdeographFontFamily = options.localIdeographFontFamily;
            this._localFontFamily = options.localFontFamily;
            return this._updateStyle(style, options);
        }
    }

    _getUIString(key        )         {
        const str = this._locale[key];
        if (str == null) {
            throw new Error(`Missing UI string '${key}'`);
        }

        return str;
    }

    _updateStyle(style                                    ,  options                                  )       {
        if (this.style) {
            this.style.setEventedParent(null);
            this.style._remove();
            this.style = (undefined     ); // we lazy-init it so it's never undefined when accessed
        }

        if (style) {
            this.style = new Style(this, options || {});
            this.style.setEventedParent(this, {style: this.style});

            if (typeof style === 'string') {
                this.style.loadURL(style);
            } else {
                this.style.loadJSON(style);
            }
        }
        this._updateTerrain();
        return this;
    }

    _lazyInitEmptyStyle() {
        if (!this.style) {
            this.style = new Style(this, {});
            this.style.setEventedParent(this, {style: this.style});
            this.style.loadEmpty();
        }
    }

    _diffStyle(style                             ,  options                                  ) {
        if (typeof style === 'string') {
            const url = this._requestManager.normalizeStyleURL(style);
            const request = this._requestManager.transformRequest(url, index.ResourceType.Style);
            index.getJSON(request, (error        , json         ) => {
                if (error) {
                    this.fire(new index.ErrorEvent(error));
                } else if (json) {
                    this._updateDiff(json, options);
                }
            });
        } else if (typeof style === 'object') {
            this._updateDiff(style, options);
        }
    }

    _updateDiff(style                    ,  options                                  ) {
        try {
            if (this.style.setState(style)) {
                this._update(true);
            }
        } catch (e) {
            index.warnOnce(
                `Unable to perform style diff: ${e.message || e.error || e}.  Rebuilding the style from scratch.`
            );
            this._updateStyle(style, options);
        }
    }

    /**
     * Returns the map's Mapbox [style](https://docs.mapbox.com/help/glossary/style/) object, a JSON object which can be used to recreate the map's style.
     *
     * @returns {Object} The map's style JSON object.
     *
     * @example
     * map.on('load', () => {
     *     const styleJson = map.getStyle();
     * });
     *
     */
    getStyle()                      {
        if (this.style) {
            return this.style.serialize();
        }
    }

    /**
     * Returns a Boolean indicating whether the map's style is fully loaded.
     *
     * @returns {boolean} A Boolean indicating whether the style is fully loaded.
     *
     * @example
     * const styleLoadStatus = map.isStyleLoaded();
     */
    isStyleLoaded()          {
        if (!this.style) {
            index.warnOnce('There is no style added to the map.');
            return false;
        }
        return this.style.loaded();
    }

    /** @section {Sources} */

    /**
     * Adds a source to the map's style.
     *
     * @param {string} id The ID of the source to add. Must not conflict with existing sources.
     * @param {Object} source The source object, conforming to the
     * Mapbox Style Specification's [source definition](https://www.mapbox.com/mapbox-gl-style-spec/#sources) or
     * {@link CanvasSourceOptions}.
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * map.addSource('my-data', {
     *     type: 'vector',
     *     url: 'mapbox://myusername.tilesetid'
     * });
     * @example
     * map.addSource('my-data', {
     *     "type": "geojson",
     *     "data": {
     *         "type": "Feature",
     *         "geometry": {
     *             "type": "Point",
     *             "coordinates": [-77.0323, 38.9131]
     *         },
     *         "properties": {
     *             "title": "Mapbox DC",
     *             "marker-symbol": "monument"
     *         }
     *     }
     * });
     * @see Example: Vector source: [Show and hide layers](https://docs.mapbox.com/mapbox-gl-js/example/toggle-layers/)
     * @see Example: GeoJSON source: [Add live realtime data](https://docs.mapbox.com/mapbox-gl-js/example/live-geojson/)
     * @see Example: Raster DEM source: [Add hillshading](https://docs.mapbox.com/mapbox-gl-js/example/hillshade/)
     */
    addSource(id        , source                     )       {
        this._lazyInitEmptyStyle();
        this.style.addSource(id, source);
        return this._update(true);
    }

    /**
     * Returns a Boolean indicating whether the source is loaded. Returns `true` if the source with
     * the given ID in the map's style has no outstanding network requests, otherwise `false`.
     *
     * @param {string} id The ID of the source to be checked.
     * @returns {boolean} A Boolean indicating whether the source is loaded.
     * @example
     * const sourceLoaded = map.isSourceLoaded('bathymetry-data');
     */
    isSourceLoaded(id        )          {
        return !!this.style && this.style._isSourceCacheLoaded(id);
    }

    /**
     * Returns a Boolean indicating whether all tiles in the viewport from all sources on
     * the style are loaded.
     *
     * @returns {boolean} A Boolean indicating whether all tiles are loaded.
     * @example
     * const tilesLoaded = map.areTilesLoaded();
     */

    areTilesLoaded()          {
        const sources = this.style && this.style._sourceCaches;
        for (const id in sources) {
            const source = sources[id];
            const tiles = source._tiles;
            for (const t in tiles) {
                const tile = tiles[t];
                if (!(tile.state === 'loaded' || tile.state === 'errored')) return false;
            }
        }
        return true;
    }

    /**
     * Adds a [custom source type](#Custom Sources), making it available for use with
     * {@link Map#addSource}.
     * @private
     * @param {string} name The name of the source type; source definition objects use this name in the `{type: ...}` field.
     * @param {Function} SourceType A {@link Source} constructor.
     * @param {Function} callback Called when the source type is ready or with an error argument if there is an error.
     */
    addSourceType(name        , SourceType     , callback          ) {
        this._lazyInitEmptyStyle();
        this.style.addSourceType(name, SourceType, callback);
    }

    /**
     * Removes a source from the map's style.
     *
     * @param {string} id The ID of the source to remove.
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * map.removeSource('bathymetry-data');
     */
    removeSource(id        )       {
        this.style.removeSource(id);
        this._updateTerrain();
        return this._update(true);
    }

    /**
     * Returns the source with the specified ID in the map's style.
     *
     * This method is often used to update a source using the instance members for the relevant
     * source type as defined in [Sources](#sources).
     * For example, setting the `data` for a GeoJSON source or updating the `url` and `coordinates`
     * of an image source.
     *
     * @param {string} id The ID of the source to get.
     * @returns {?Object} The style source with the specified ID or `undefined` if the ID
     * corresponds to no existing sources.
     * The shape of the object varies by source type.
     * A list of options for each source type is available on the Mapbox Style Specification's
     * [Sources](https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/) page.
     * @example
     * const sourceObject = map.getSource('points');
     * @see [Example: Create a draggable point](https://docs.mapbox.com/mapbox-gl-js/example/drag-a-point/)
     * @see [Example: Animate a point](https://docs.mapbox.com/mapbox-gl-js/example/animate-point-along-line/)
     * @see [Example: Add live realtime data](https://docs.mapbox.com/mapbox-gl-js/example/live-geojson/)
     */
    getSource(id        )          {
        return this.style.getSource(id);
    }

    /** @section {Images} */

    // eslint-disable-next-line jsdoc/require-returns
    /**
     * Add an image to the style. This image can be displayed on the map like any other icon in the style's
     * [sprite](https://docs.mapbox.com/mapbox-gl-js/style-spec/sprite/) using the image's ID with
     * [`icon-image`](https://docs.mapbox.com/mapbox-gl-js/style-spec/#layout-symbol-icon-image),
     * [`background-pattern`](https://docs.mapbox.com/mapbox-gl-js/style-spec/#paint-background-background-pattern),
     * [`fill-pattern`](https://docs.mapbox.com/mapbox-gl-js/style-spec/#paint-fill-fill-pattern),
     * or [`line-pattern`](https://docs.mapbox.com/mapbox-gl-js/style-spec/#paint-line-line-pattern).
     * A {@link Map.event:error} event will be fired if there is not enough space in the sprite to add this image.
     *
     * @param {string} id The ID of the image.
     * @param {HTMLImageElement | ImageBitmap | ImageData | {width: number, height: number, data: (Uint8Array | Uint8ClampedArray)} | StyleImageInterface} image The image as an `HTMLImageElement`, `ImageData`, `ImageBitmap` or object with `width`, `height`, and `data`
     * properties with the same format as `ImageData`.
     * @param {Object | null} options Options object.
     * @param {number} options.pixelRatio The ratio of pixels in the image to physical pixels on the screen.
     * @param {boolean} options.sdf Whether the image should be interpreted as an SDF image.
     * @param {[number, number, number, number]} options.content `[x1, y1, x2, y2]`  If `icon-text-fit` is used in a layer with this image, this option defines the part of the image that can be covered by the content in `text-field`.
     * @param {Array<[number, number]>} options.stretchX `[[x1, x2], ...]` If `icon-text-fit` is used in a layer with this image, this option defines the part(s) of the image that can be stretched horizontally.
     * @param {Array<[number, number]>} options.stretchY `[[y1, y2], ...]` If `icon-text-fit` is used in a layer with this image, this option defines the part(s) of the image that can be stretched vertically.
     *
     * @example
     * // If the style's sprite does not already contain an image with ID 'cat',
     * // add the image 'cat-icon.png' to the style's sprite with the ID 'cat'.
     * map.loadImage('https://upload.wikimedia.org/wikipedia/commons/thumb/6/60/Cat_silhouette.svg/400px-Cat_silhouette.svg.png', (error, image) => {
     *     if (error) throw error;
     *     if (!map.hasImage('cat')) map.addImage('cat', image);
     * });
     *
     * // Add a stretchable image that can be used with `icon-text-fit`
     * // In this example, the image is 600px wide by 400px high.
     * map.loadImage('https://upload.wikimedia.org/wikipedia/commons/8/89/Black_and_White_Boxed_%28bordered%29.png', (error, image) => {
     *     if (error) throw error;
     *     if (!map.hasImage('border-image')) {
     *         map.addImage('border-image', image, {
     *             content: [16, 16, 300, 384], // place text over left half of image, avoiding the 16px border
     *             stretchX: [[16, 584]], // stretch everything horizontally except the 16px border
     *             stretchY: [[16, 384]], // stretch everything vertically except the 16px border
     *         });
     *     }
     * });
     *
     *
     * @see Example: Use `HTMLImageElement`: [Add an icon to the map](https://www.mapbox.com/mapbox-gl-js/example/add-image/)
     * @see Example: Use `ImageData`: [Add a generated icon to the map](https://www.mapbox.com/mapbox-gl-js/example/add-image-generated/)
     */
    addImage(id        ,
             image                                                                                                                                          ,
             {pixelRatio = 1, sdf = false, stretchX, stretchY, content}                             = {}) {
        this._lazyInitEmptyStyle();
        const version = 0;

        if (image instanceof index.window.HTMLImageElement || (index.window.ImageBitmap && image instanceof index.window.ImageBitmap)) {
            const {width, height, data} = index.exported.getImageData(image);
            this.style.addImage(id, {data: new index.RGBAImage({width, height}, data), pixelRatio, stretchX, stretchY, content, sdf, version});
        } else if (image.width === undefined || image.height === undefined) {
            this.fire(new index.ErrorEvent(new Error(
                'Invalid arguments to map.addImage(). The second argument must be an `HTMLImageElement`, `ImageData`, `ImageBitmap`, ' +
                'or object with `width`, `height`, and `data` properties with the same format as `ImageData`')));
        } else {
            const {width, height} = image;
            const userImage = ((image     )                     );
            const data = userImage.data;

            this.style.addImage(id, {
                data: new index.RGBAImage({width, height}, new Uint8Array(data)),
                pixelRatio,
                stretchX,
                stretchY,
                content,
                sdf,
                version,
                userImage
            });

            if (userImage.onAdd) {
                userImage.onAdd(this, id);
            }
        }
    }

    // eslint-disable-next-line jsdoc/require-returns
    /**
     * Update an existing image in a style. This image can be displayed on the map like any other icon in the style's
     * [sprite](https://docs.mapbox.com/help/glossary/sprite/) using the image's ID with
     * [`icon-image`](https://docs.mapbox.com/mapbox-gl-js/style-spec/#layout-symbol-icon-image),
     * [`background-pattern`](https://docs.mapbox.com/mapbox-gl-js/style-spec/#paint-background-background-pattern),
     * [`fill-pattern`](https://docs.mapbox.com/mapbox-gl-js/style-spec/#paint-fill-fill-pattern),
     * or [`line-pattern`](https://docs.mapbox.com/mapbox-gl-js/style-spec/#paint-line-line-pattern).
     *
     * @param {string} id The ID of the image.
     * @param {HTMLImageElement | ImageBitmap | ImageData | StyleImageInterface} image The image as an `HTMLImageElement`, [`ImageData`](https://developer.mozilla.org/en-US/docs/Web/API/ImageData), [`ImageBitmap`](https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap) or object with `width`, `height`, and `data`
     * properties with the same format as `ImageData`.
     *
     * @example
    * // Load an image from an external URL.
     * map.loadImage('http://placekitten.com/50/50', (error, image) => {
     *     if (error) throw error;
     *     // If an image with the ID 'cat' already exists in the style's sprite,
     *     // replace that image with a new image, 'other-cat-icon.png'.
     *     if (map.hasImage('cat')) map.updateImage('cat', image);
     * });
     */
    updateImage(id        ,
        image                                                                                                                                          ) {

        const existingImage = this.style.getImage(id);
        if (!existingImage) {
            this.fire(new index.ErrorEvent(new Error(
                'The map has no image with that id. If you are adding a new image use `map.addImage(...)` instead.')));
            return;
        }
        const imageData = (image instanceof index.window.HTMLImageElement || (index.window.ImageBitmap && image instanceof index.window.ImageBitmap)) ? index.exported.getImageData(image) : image;
        const {width, height} = imageData;
        // Flow can't refine the type enough to exclude ImageBitmap
        const data = ((imageData     ).data                                );

        if (width === undefined || height === undefined) {
            this.fire(new index.ErrorEvent(new Error(
                'Invalid arguments to map.updateImage(). The second argument must be an `HTMLImageElement`, `ImageData`, `ImageBitmap`, ' +
                'or object with `width`, `height`, and `data` properties with the same format as `ImageData`')));
            return;
        }

        if (width !== existingImage.data.width || height !== existingImage.data.height) {
            this.fire(new index.ErrorEvent(new Error(
                `The width and height of the updated image (${width}, ${height})
                must be that same as the previous version of the image
                (${existingImage.data.width}, ${existingImage.data.height})`)));
            return;
        }

        const copy = !(image instanceof index.window.HTMLImageElement || (index.window.ImageBitmap && image instanceof index.window.ImageBitmap));
        existingImage.data.replace(data, copy);

        this.style.updateImage(id, existingImage);
    }

    /**
     * Check whether or not an image with a specific ID exists in the style. This checks both images
     * in the style's original [sprite](https://docs.mapbox.com/help/glossary/sprite/) and any images
     * that have been added at runtime using {@link Map#addImage}.
     *
     * @param {string} id The ID of the image.
     *
     * @returns {boolean} A Boolean indicating whether the image exists.
     * @example
     * // Check if an image with the ID 'cat' exists in
     * // the style's sprite.
     * const catIconExists = map.hasImage('cat');
     */
    hasImage(id        )          {
        if (!id) {
            this.fire(new index.ErrorEvent(new Error('Missing required image id')));
            return false;
        }

        return !!this.style.getImage(id);
    }

    /**
     * Remove an image from a style. This can be an image from the style's original
     * [sprite](https://docs.mapbox.com/help/glossary/sprite/) or any images
     * that have been added at runtime using {@link Map#addImage}.
     *
     * @param {string} id The ID of the image.
     *
     * @example
     * // If an image with the ID 'cat' exists in
     * // the style's sprite, remove it.
     * if (map.hasImage('cat')) map.removeImage('cat');
     */
    removeImage(id        ) {
        this.style.removeImage(id);
    }

    /**
     * Load an image from an external URL to be used with {@link Map#addImage}. External
     * domains must support [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS).
     *
     * @param {string} url The URL of the image file. Image file must be in png, webp, or jpg format.
     * @param {Function} callback Expecting `callback(error, data)`. Called when the image has loaded or with an error argument if there is an error.
     *
     * @example
     * // Load an image from an external URL.
     * map.loadImage('http://placekitten.com/50/50', (error, image) => {
     *     if (error) throw error;
     *     // Add the loaded image to the style's sprite with the ID 'kitten'.
     *     map.addImage('kitten', image);
     * });
     *
     * @see [Example: Add an icon to the map](https://www.mapbox.com/mapbox-gl-js/example/add-image/)
     */
    loadImage(url        , callback          ) {
        index.getImage(this._requestManager.transformRequest(url, index.ResourceType.Image), (err, img) => {
            callback(err, img instanceof index.window.HTMLImageElement ? index.exported.getImageData(img) : img);
        });
    }

    /**
    * Returns an Array of strings containing the IDs of all images currently available in the map.
    * This includes both images from the style's original [sprite](https://docs.mapbox.com/help/glossary/sprite/)
    * and any images that have been added at runtime using {@link Map#addImage}.
    *
    * @returns {Array<string>} An Array of strings containing the names of all sprites/images currently available in the map.
    *
    * @example
    * const allImages = map.listImages();
    *
    */
    listImages()                {
        return this.style.listImages();
    }

    /** @section {Layers} */

    /**
     * Adds a [Mapbox style layer](https://docs.mapbox.com/mapbox-gl-js/style-spec/#layers)
     * to the map's style.
     *
     * A layer defines how data from a specified source will be styled. Read more about layer types
     * and available paint and layout properties in the [Mapbox Style Specification](https://docs.mapbox.com/mapbox-gl-js/style-spec/#layers).
     *
     * @param {Object | CustomLayerInterface} layer The layer to add, conforming to either the Mapbox Style Specification's [layer definition](https://docs.mapbox.com/mapbox-gl-js/style-spec/#layers) or, less commonly, the {@link CustomLayerInterface} specification.
     * The Mapbox Style Specification's layer definition is appropriate for most layers.
     *
     * @param {string} layer.id A unique identifier that you define.
     * @param {string} layer.type The type of layer (for example `fill` or `symbol`).
     * A list of layer types is available in the [Mapbox Style Specification](https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#type).
     *
     * This can also be `custom`. For more information, see {@link CustomLayerInterface}.
     * @param {string | Object} [layer.source] The data source for the layer.
     * Reference a source that has _already been defined_ using the source's unique id.
     * Reference a _new source_ using a source object (as defined in the [Mapbox Style Specification](https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/)) directly.
     * This is **required** for all `layer.type` options _except_ for `custom` and `background`.
     * @param {string} [layer.sourceLayer] (optional) The name of the [source layer](https://docs.mapbox.com/help/glossary/source-layer/) within the specified `layer.source` to use for this style layer.
     * This is only applicable for vector tile sources and is **required** when `layer.source` is of the type `vector`.
     * @param {Array} [layer.filter] (optional) An expression specifying conditions on source features.
     * Only features that match the filter are displayed.
     * The Mapbox Style Specification includes more information on the limitations of the [`filter`](https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#filter) parameter
     * and a complete list of available [expressions](https://docs.mapbox.com/mapbox-gl-js/style-spec/expressions/).
     * If no filter is provided, all features in the source (or source layer for vector tilesets) will be displayed.
     * @param {Object} [layer.paint] (optional) Paint properties for the layer.
     * Available paint properties vary by `layer.type`.
     * A full list of paint properties for each layer type is available in the [Mapbox Style Specification](https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/).
     * If no paint properties are specified, default values will be used.
     * @param {Object} [layer.layout] (optional) Layout properties for the layer.
     * Available layout properties vary by `layer.type`.
     * A full list of layout properties for each layer type is available in the [Mapbox Style Specification](https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/).
     * If no layout properties are specified, default values will be used.
     * @param {number} [layer.maxzoom] (optional) The maximum zoom level for the layer.
     * At zoom levels equal to or greater than the maxzoom, the layer will be hidden.
     * The value can be any number between `0` and `24` (inclusive).
     * If no maxzoom is provided, the layer will be visible at all zoom levels for which there are tiles available.
     * @param {number} [layer.minzoom] (optional) The minimum zoom level for the layer.
     * At zoom levels less than the minzoom, the layer will be hidden.
     * The value can be any number between `0` and `24` (inclusive).
     * If no minzoom is provided, the layer will be visible at all zoom levels for which there are tiles available.
     * @param {Object} [layer.metadata] (optional) Arbitrary properties useful to track with the layer, but do not influence rendering.
     * @param {string} [layer.renderingMode] This is only applicable for layers with the type `custom`.
     * See {@link CustomLayerInterface} for more information.
     * @param {string} [beforeId] The ID of an existing layer to insert the new layer before,
     * resulting in the new layer appearing visually beneath the existing layer.
     * If this argument is not specified, the layer will be appended to the end of the layers array
     * and appear visually above all other layers.
     *
     * @returns {Map} Returns itself to allow for method chaining.
     *
     * @example
     * // Add a circle layer with a vector source
     * map.addLayer({
     *     id: 'points-of-interest',
     *     source: {
     *         type: 'vector',
     *         url: 'mapbox://mapbox.mapbox-streets-v8'
     *     },
     *     'source-layer': 'poi_label',
     *     type: 'circle',
     *     paint: {
     *     // Mapbox Style Specification paint properties
     *     },
     *     layout: {
     *     // Mapbox Style Specification layout properties
     *     }
     * });
     *
     * @example
     * // Define a source before using it to create a new layer
     * map.addSource('state-data', {
     *     type: 'geojson',
     *     data: 'path/to/data.geojson'
     * });
     *
     * map.addLayer({
     *     id: 'states',
     *     // References the GeoJSON source defined above
     *     // and does not require a `source-layer`
     *     source: 'state-data',
     *     type: 'symbol',
     *     layout: {
     *         // Set the label content to the
     *         // feature's `name` property
     *         'text-field': ['get', 'name']
     *     }
     * });
     *
     * @example
     * // Add a new symbol layer before an existing layer
     * map.addLayer({
     *     id: 'states',
     *     // References a source that's already been defined
     *     source: 'state-data',
     *     type: 'symbol',
     *     layout: {
     *         // Set the label content to the
     *         // feature's `name` property
     *         'text-field': ['get', 'name']
     *     }
     * // Add the layer before the existing `cities` layer
     * }, 'cities');
     *
     * @see [Example: Select features around a clicked point](https://docs.mapbox.com/mapbox-gl-js/example/queryrenderedfeatures-around-point/) (fill layer)
     * @see [Example: Add a new layer below labels](https://docs.mapbox.com/mapbox-gl-js/example/geojson-layer-in-stack/)
     * @see [Example: Create and style clusters](https://docs.mapbox.com/mapbox-gl-js/example/cluster/) (circle layer)
     * @see [Example: Add a vector tile source](https://docs.mapbox.com/mapbox-gl-js/example/vector-source/) (line layer)
     * @see [Example: Add a WMS layer](https://docs.mapbox.com/mapbox-gl-js/example/wms/) (raster layer)
     */
    addLayer(layer                                           , beforeId         )       {
        this._lazyInitEmptyStyle();
        this.style.addLayer(layer, beforeId);
        return this._update(true);
    }

    /**
     * Moves a layer to a different z-position.
     *
     * @param {string} id The ID of the layer to move.
     * @param {string} [beforeId] The ID of an existing layer to insert the new layer before. When viewing the map, the `id` layer will appear beneath the `beforeId` layer. If `beforeId` is omitted, the layer will be appended to the end of the layers array and appear above all other layers on the map.
     * @returns {Map} Returns itself to allow for method chaining.
     *
     * @example
     * // Move a layer with ID 'polygon' before the layer with ID 'country-label'. The `polygon` layer will appear beneath the `country-label` layer on the map.
     * map.moveLayer('polygon', 'country-label');
     */
    moveLayer(id        , beforeId         )       {
        this.style.moveLayer(id, beforeId);
        return this._update(true);
    }

    /**
     * Removes the layer with the given ID from the map's style.
     *
     * If no such layer exists, an `error` event is fired.
     *
     * @param {string} id ID of the layer to remove.
     * @returns {Map} Returns itself to allow for method chaining.
     * @fires Map.event:error
     *
     * @example
     * // If a layer with ID 'state-data' exists, remove it.
     * if (map.getLayer('state-data')) map.removeLayer('state-data');
     */
    removeLayer(id        )       {
        this.style.removeLayer(id);
        return this._update(true);
    }

    /**
     * Returns the layer with the specified ID in the map's style.
     *
     * @param {string} id The ID of the layer to get.
     * @returns {?Object} The layer with the specified ID, or `undefined`
     *   if the ID corresponds to no existing layers.
     *
     * @example
     * const stateDataLayer = map.getLayer('state-data');
     *
     * @see [Example: Filter symbols by toggling a list](https://www.mapbox.com/mapbox-gl-js/example/filter-markers/)
     * @see [Example: Filter symbols by text input](https://www.mapbox.com/mapbox-gl-js/example/filter-markers-by-input/)
     */
    getLayer(id        )              {
        return this.style.getLayer(id);
    }

    /**
     * Sets the zoom extent for the specified style layer. The zoom extent includes the
     * [minimum zoom level](https://docs.mapbox.com/mapbox-gl-js/style-spec/#layer-minzoom)
     * and [maximum zoom level](https://docs.mapbox.com/mapbox-gl-js/style-spec/#layer-maxzoom))
     * at which the layer will be rendered.
     *
     * Note: For style layers using vector sources, style layers cannot be rendered at zoom levels lower than the
     * minimum zoom level of the _source layer_ because the data does not exist at those zoom levels. If the minimum
     * zoom level of the source layer is higher than the minimum zoom level defined in the style layer, the style
     * layer will not be rendered at all zoom levels in the zoom range.
     *
     * @param {string} layerId The ID of the layer to which the zoom extent will be applied.
     * @param {number} minzoom The minimum zoom to set (0-24).
     * @param {number} maxzoom The maximum zoom to set (0-24).
     * @returns {Map} Returns itself to allow for method chaining.
     *
     * @example
     * map.setLayerZoomRange('my-layer', 2, 5);
     *
     */
    setLayerZoomRange(layerId        , minzoom        , maxzoom        )       {
        this.style.setLayerZoomRange(layerId, minzoom, maxzoom);
        return this._update(true);
    }

    /**
     * Sets the filter for the specified style layer.
     *
     * Filters control which features a style layer renders from its source.
     * Any feature for which the filter expression evaluates to `true` will be
     * rendered on the map. Those that are false will be hidden.
     *
     * Use `setFilter` to show a subset of your source data.
     *
     * To clear the filter, pass `null` or `undefined` as the second parameter.
     *
     * @param {string} layerId The ID of the layer to which the filter will be applied.
     * @param {Array | null | undefined} filter The filter, conforming to the Mapbox Style Specification's
     *   [filter definition](https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#filter).  If `null` or `undefined` is provided, the function removes any existing filter from the layer.
     * @param {Object} [options] Options object.
     * @param {boolean} [options.validate=true] Whether to check if the filter conforms to the Mapbox GL Style Specification. Disabling validation is a performance optimization that should only be used if you have previously validated the values you will be passing to this function.
     * @returns {Map} Returns itself to allow for method chaining.
     *
     * @example
     * // display only features with the 'name' property 'USA'
     * map.setFilter('my-layer', ['==', ['get', 'name'], 'USA']);
     * @example
     * // display only features with five or more 'available-spots'
     * map.setFilter('bike-docks', ['>=', ['get', 'available-spots'], 5]);
     * @example
     * // remove the filter for the 'bike-docks' style layer
     * map.setFilter('bike-docks', null);
     *
     * @see [Example: Filter features within map view](https://www.mapbox.com/mapbox-gl-js/example/filter-features-within-map-view/)
     * @see [Example: Highlight features containing similar data](https://www.mapbox.com/mapbox-gl-js/example/query-similar-features/)
     * @see [Example: Create a timeline animation](https://www.mapbox.com/mapbox-gl-js/example/timeline-animation/)
     * @see [Tutorial: Show changes over time](https://docs.mapbox.com/help/tutorials/show-changes-over-time/)
     */
    setFilter(layerId        , filter                      ,  options                     = {})       {
        this.style.setFilter(layerId, filter, options);
        return this._update(true);
    }

    /**
     * Returns the filter applied to the specified style layer.
     *
     * @param {string} layerId The ID of the style layer whose filter to get.
     * @returns {Array} The layer's filter.
     * @example
     * const filter = map.getFilter('myLayer');
     */
    getFilter(layerId        )                       {
        return this.style.getFilter(layerId);
    }

    /**
     * Sets the value of a paint property in the specified style layer.
     *
     * @param {string} layerId The ID of the layer to set the paint property in.
     * @param {string} name The name of the paint property to set.
     * @param {*} value The value of the paint property to set.
     *   Must be of a type appropriate for the property, as defined in the [Mapbox Style Specification](https://www.mapbox.com/mapbox-gl-style-spec/).
     * @param {Object} [options] Options object.
     * @param {boolean} [options.validate=true] Whether to check if `value` conforms to the Mapbox GL Style Specification. Disabling validation is a performance optimization that should only be used if you have previously validated the values you will be passing to this function.
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * map.setPaintProperty('my-layer', 'fill-color', '#faafee');
     * @see [Example: Change a layer's color with buttons](https://www.mapbox.com/mapbox-gl-js/example/color-switcher/)
     * @see [Example: Adjust a layer's opacity](https://www.mapbox.com/mapbox-gl-js/example/adjust-layer-opacity/)
     * @see [Example: Create a draggable point](https://www.mapbox.com/mapbox-gl-js/example/drag-a-point/)
     */
    setPaintProperty(layerId        , name        , value     , options                     = {})       {
        this.style.setPaintProperty(layerId, name, value, options);
        return this._update(true);
    }

    /**
     * Returns the value of a paint property in the specified style layer.
     *
     * @param {string} layerId The ID of the layer to get the paint property from.
     * @param {string} name The name of a paint property to get.
     * @returns {*} The value of the specified paint property.
     * @example
     * const paintProperty = map.getPaintProperty('mySymbolLayer', 'icon-color');
     */
    getPaintProperty(layerId        , name        )                                                                     {
        return this.style.getPaintProperty(layerId, name);
    }

    /**
     * Sets the value of a layout property in the specified style layer.
     *
     * @param {string} layerId The ID of the layer to set the layout property in.
     * @param {string} name The name of the layout property to set.
     * @param {*} value The value of the layout property. Must be of a type appropriate for the property, as defined in the [Mapbox Style Specification](https://www.mapbox.com/mapbox-gl-style-spec/).
     * @param {Object} [options] Options object.
     * @param {boolean} [options.validate=true] Whether to check if `value` conforms to the Mapbox GL Style Specification. Disabling validation is a performance optimization that should only be used if you have previously validated the values you will be passing to this function.
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * map.setLayoutProperty('my-layer', 'visibility', 'none');
     * @see [Example: Show and hide layers](https://docs.mapbox.com/mapbox-gl-js/example/toggle-layers/)
     */
    setLayoutProperty(layerId        , name        , value     , options                     = {})       {
        this.style.setLayoutProperty(layerId, name, value, options);
        return this._update(true);
    }

    /**
     * Returns the value of a layout property in the specified style layer.
     *
     * @param {string} layerId The ID of the layer to get the layout property from.
     * @param {string} name The name of the layout property to get.
     * @returns {*} The value of the specified layout property.
     * @example
     * const layoutProperty = map.getLayoutProperty('mySymbolLayer', 'icon-anchor');
     */
    getLayoutProperty(layerId        , name        )                                     {
        return this.style.getLayoutProperty(layerId, name);
    }

    /** @section {Style properties} */

    /**
     * Sets the any combination of light values.
     *
     * @param {LightSpecification} light Light properties to set. Must conform to the [Light Style Specification](https://www.mapbox.com/mapbox-gl-style-spec/#light).
     * @param {Object} [options] Options object.
     * @param {boolean} [options.validate=true] Whether to check if the filter conforms to the Mapbox GL Style Specification. Disabling validation is a performance optimization that should only be used if you have previously validated the values you will be passing to this function.
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * map.setLight({
     *     "anchor": "viewport",
     *     "color": "blue",
     *     "intensity": 0.5
     * });
     */
    setLight(light                    , options                     = {})       {
        this._lazyInitEmptyStyle();
        this.style.setLight(light, options);
        return this._update(true);
    }

    /**
     * Returns the value of the light object.
     *
     * @returns {LightSpecification} Light properties of the style.
     * @example
     * const light = map.getLight();
     */
    getLight()                     {
        return this.style.getLight();
    }

    // eslint-disable-next-line jsdoc/require-returns
    /**
     * Sets the terrain property of the style.
     *
     * @param {TerrainSpecification} terrain Terrain properties to set. Must conform to the [Terrain Style Specification](https://docs.mapbox.com/mapbox-gl-js/style-spec/terrain/).
     * If `null` or `undefined` is provided, function removes terrain.
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * map.addSource('mapbox-dem', {
     *     'type': 'raster-dem',
     *     'url': 'mapbox://mapbox.mapbox-terrain-dem-v1',
     *     'tileSize': 512,
     *     'maxzoom': 14
     * });
     * // add the DEM source as a terrain layer with exaggerated height
     * map.setTerrain({'source': 'mapbox-dem', 'exaggeration': 1.5});
     */
    setTerrain(terrain                      )       {
        this._lazyInitEmptyStyle();
        if (!terrain && this.transform.projection.requiresDraping) {
            this.style.setTerrainForDraping();
        } else {
            this.style.setTerrain(terrain);
        }
        this._averageElevationLastSampledAt = -Infinity;
        return this._update(true);
    }

    /**
     * Returns the terrain specification or `null` if terrain isn't set on the map.
     *
     * @returns {TerrainSpecification | null} Terrain specification properties of the style.
     * @example
     * const terrain = map.getTerrain();
     */
    getTerrain()                        {
        return this.style ? this.style.getTerrain() : null;
    }

    /**
     * Sets the fog property of the style.
     *
     * @param {FogSpecification} fog The fog properties to set. Must conform to the [Fog Style Specification](https://docs.mapbox.com/mapbox-gl-js/style-spec/fog/).
     * If `null` or `undefined` is provided, this function call removes the fog from the map.
     * @returns {Map} Returns itself to allow for method chaining.
     * @example
     * map.setFog({
     *     "range": [0.8, 8],
     *     "color": "#dc9f9f",
     *     "horizon-blend": 0.5,
     *     "high-color": "#245bde",
     *     "space-color": "#000000",
     *     "star-intensity": 0.15
     * });
     * @see [Example: Add fog to a map](https://docs.mapbox.com/mapbox-gl-js/example/add-fog/)
     */
    setFog(fog                  )       {
        this._lazyInitEmptyStyle();
        this.style.setFog(fog);
        return this._update(true);
    }

    /**
     * Returns the fog specification or `null` if fog is not set on the map.
     *
     * @returns {FogSpecification} Fog specification properties of the style.
     * @example
     * const fog = map.getFog();
     */
    getFog()                    {
        return this.style ? this.style.getFog() : null;
    }

    /**
     * Returns the fog opacity for a given location.
     *
     * An opacity of 0 means that there is no fog contribution for the given location
     * while a fog opacity of 1.0 means the location is fully obscured by the fog effect.
     *
     * If there is no fog set on the map, this function will return 0.
     *
     * @param {LngLatLike} lnglat The geographical location to evaluate the fog on.
     * @returns {number} A value between 0 and 1 representing the fog opacity, where 1 means fully within, and 0 means not affected by the fog effect.
     * @private
     */
    _queryFogOpacity(lnglat            )         {
        if (!this.style || !this.style.fog) return 0.0;
        return this.style.fog.getOpacityAtLatLng(index.LngLat.convert(lnglat), this.transform);
    }

    /** @section {Feature state} */

    /**
     * Sets the `state` of a feature.
     * A feature's `state` is a set of user-defined key-value pairs that are assigned to a feature at runtime.
     * When using this method, the `state` object is merged with any existing key-value pairs in the feature's state.
     * Features are identified by their `id` attribute, which can be any number or string.
     *
     * This method can only be used with sources that have a `id` attribute. The `id` attribute can be defined in three ways:
     * - For vector or GeoJSON sources, including an `id` attribute in the original data file.
     * - For vector or GeoJSON sources, using the [`promoteId`](https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/#vector-promoteId) option at the time the source is defined.
     * - For GeoJSON sources, using the [`generateId`](https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/#geojson-generateId) option to auto-assign an `id` based on the feature's index in the source data. If you change feature data using `map.getSource('some id').setData(...)`, you may need to re-apply state taking into account updated `id` values.
     *
     * _Note: You can use the [`feature-state` expression](https://docs.mapbox.com/mapbox-gl-js/style-spec/expressions/#feature-state) to access the values in a feature's state object for the purposes of styling_.
     *
     * @param {Object} feature Feature identifier. Feature objects returned from
     * {@link Map#queryRenderedFeatures} or event handlers can be used as feature identifiers.
     * @param {number | string} feature.id Unique id of the feature. Can be an integer or a string, but supports string values only when the [`promoteId`](https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/#vector-promoteId) option has been applied to the source or the string can be cast to an integer.
     * @param {string} feature.source The id of the vector or GeoJSON source for the feature.
     * @param {string} [feature.sourceLayer] (optional) *For vector tile sources, `sourceLayer` is required*.
     * @param {Object} state A set of key-value pairs. The values should be valid JSON types.
     * @returns {Map} The map object.
     * @example
     * // When the mouse moves over the `my-layer` layer, update
     * // the feature state for the feature under the mouse
     * map.on('mousemove', 'my-layer', (e) => {
     *     if (e.features.length > 0) {
     *         map.setFeatureState({
     *             source: 'my-source',
     *             sourceLayer: 'my-source-layer',
     *             id: e.features[0].id,
     *         }, {
     *             hover: true
     *         });
     *     }
     * });
     *
     * @see [Example: Create a hover effect](https://docs.mapbox.com/mapbox-gl-js/example/hover-styles/)
     * @see [Tutorial: Create interactive hover effects with Mapbox GL JS](https://docs.mapbox.com/help/tutorials/create-interactive-hover-effects-with-mapbox-gl-js/)
     */
    setFeatureState(feature                                                                , state        )       {
        this.style.setFeatureState(feature, state);
        return this._update();
    }

    // eslint-disable-next-line jsdoc/require-returns
    /**
     * Removes the `state` of a feature, setting it back to the default behavior.
     * If only a `feature.source` is specified, it will remove the state for all features from that source.
     * If `feature.id` is also specified, it will remove all keys for that feature's state.
     * If `key` is also specified, it removes only that key from that feature's state.
     * Features are identified by their `feature.id` attribute, which can be any number or string.
     *
     * @param {Object} feature Identifier of where to remove state. It can be a source, a feature, or a specific key of feature.
     * Feature objects returned from {@link Map#queryRenderedFeatures} or event handlers can be used as feature identifiers.
     * @param {number | string} [feature.id] (optional) Unique id of the feature. Can be an integer or a string, but supports string values only when the [`promoteId`](https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/#vector-promoteId) option has been applied to the source or the string can be cast to an integer.
     * @param {string} feature.source The id of the vector or GeoJSON source for the feature.
     * @param {string} [feature.sourceLayer] (optional) For vector tile sources, `sourceLayer` is required.
     * @param {string} [key] (optional) The key in the feature state to reset.
     *
     * @example
     * // Reset the entire state object for all features
     * // in the `my-source` source
     * map.removeFeatureState({
     *     source: 'my-source'
     * });
     *
     * @example
     * // When the mouse leaves the `my-layer` layer,
     * // reset the entire state object for the
     * // feature under the mouse
     * map.on('mouseleave', 'my-layer', (e) => {
     *     map.removeFeatureState({
     *         source: 'my-source',
     *         sourceLayer: 'my-source-layer',
     *         id: e.features[0].id
     *     });
     * });
     *
     * @example
     * // When the mouse leaves the `my-layer` layer,
     * // reset only the `hover` key-value pair in the
     * // state for the feature under the mouse
     * map.on('mouseleave', 'my-layer', (e) => {
     *     map.removeFeatureState({
     *         source: 'my-source',
     *         sourceLayer: 'my-source-layer',
     *         id: e.features[0].id
     *     }, 'hover');
     * });
     *
     */
    removeFeatureState(feature                                                                 , key         )       {
        this.style.removeFeatureState(feature, key);
        return this._update();
    }

    /**
     * Gets the `state` of a feature.
     * A feature's `state` is a set of user-defined key-value pairs that are assigned to a feature at runtime.
     * Features are identified by their `id` attribute, which can be any number or string.
     *
     * _Note: To access the values in a feature's state object for the purposes of styling the feature, use the [`feature-state` expression](https://docs.mapbox.com/mapbox-gl-js/style-spec/expressions/#feature-state)_.
     *
     * @param {Object} feature Feature identifier. Feature objects returned from
     * {@link Map#queryRenderedFeatures} or event handlers can be used as feature identifiers.
     * @param {number | string} feature.id Unique id of the feature. Can be an integer or a string, but supports string values only when the [`promoteId`](https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/#vector-promoteId) option has been applied to the source or the string can be cast to an integer.
     * @param {string} feature.source The id of the vector or GeoJSON source for the feature.
     * @param {string} [feature.sourceLayer] (optional) *For vector tile sources, `sourceLayer` is required*.
     *
     * @returns {Object} The state of the feature: a set of key-value pairs that was assigned to the feature at runtime.
     *
     * @example
     * // When the mouse moves over the `my-layer` layer,
     * // get the feature state for the feature under the mouse
     * map.on('mousemove', 'my-layer', (e) => {
     *     if (e.features.length > 0) {
     *         map.getFeatureState({
     *             source: 'my-source',
     *             sourceLayer: 'my-source-layer',
     *             id: e.features[0].id
     *         });
     *     }
     * });
     *
     */
    getFeatureState(feature                                                                )      {
        return this.style.getFeatureState(feature);
    }

    _updateContainerDimensions() {
        if (!this._container) return;

        const width = this._container.getBoundingClientRect().width || 400;
        const height = this._container.getBoundingClientRect().height || 300;

        let transformValues;
        let transformScaleWidth;
        let transformScaleHeight;
        let el           = this._container;
        while (el && (!transformScaleWidth || !transformScaleHeight)) {
            const transformMatrix = index.window.getComputedStyle(el).transform;
            if (transformMatrix && transformMatrix !== 'none') {
                transformValues = transformMatrix.match(/matrix.*\((.+)\)/)[1].split(', ');
                if (transformValues[0] && transformValues[0] !== '0' && transformValues[0] !== '1') transformScaleWidth = transformValues[0];
                if (transformValues[3] && transformValues[3] !== '0' && transformValues[3] !== '1') transformScaleHeight = transformValues[3];
            }
            el = el.parentElement;
        }

        this._containerWidth = transformScaleWidth ? Math.abs(width / transformScaleWidth) : width;
        this._containerHeight = transformScaleHeight ? Math.abs(height / transformScaleHeight) : height;
    }

    _detectMissingCSS()       {
        const computedColor = index.window.getComputedStyle(this._missingCSSCanary).getPropertyValue('background-color');
        if (computedColor !== 'rgb(250, 128, 114)') {
            index.warnOnce('This page appears to be missing CSS declarations for ' +
                'Mapbox GL JS, which may cause the map to display incorrectly. ' +
                'Please ensure your page includes mapbox-gl.css, as described ' +
                'in https://www.mapbox.com/mapbox-gl-js/api/.');
        }
    }

    _setupContainer() {
        const container = this._container;
        container.classList.add('mapboxgl-map');

        const missingCSSCanary = this._missingCSSCanary = create$1('div', 'mapboxgl-canary', container);
        missingCSSCanary.style.visibility = 'hidden';
        this._detectMissingCSS();

        const canvasContainer = this._canvasContainer = create$1('div', 'mapboxgl-canvas-container', container);
        if (this._interactive) {
            canvasContainer.classList.add('mapboxgl-interactive');
        }

        this._canvas = create$1('canvas', 'mapboxgl-canvas', canvasContainer);
        // $FlowFixMe[method-unbinding]
        this._canvas.addEventListener('webglcontextlost', this._contextLost, false);
        // $FlowFixMe[method-unbinding]
        this._canvas.addEventListener('webglcontextrestored', this._contextRestored, false);
        this._canvas.setAttribute('tabindex', '0');
        this._canvas.setAttribute('aria-label', this._getUIString('Map.Title'));
        this._canvas.setAttribute('role', 'region');

        this._updateContainerDimensions();
        this._resizeCanvas(this._containerWidth, this._containerHeight);

        const controlContainer = this._controlContainer = create$1('div', 'mapboxgl-control-container', container);
        const positions = this._controlPositions = {};
        ['top-left', 'top-right', 'bottom-left', 'bottom-right'].forEach((positionName) => {
            positions[positionName] = create$1('div', `mapboxgl-ctrl-${positionName}`, controlContainer);
        });

        // $FlowFixMe[method-unbinding]
        this._container.addEventListener('scroll', this._onMapScroll, false);
    }

    _resizeCanvas(width        , height        ) {
        const pixelRatio = index.exported.devicePixelRatio || 1;

        // Request the required canvas size (rounded up) taking the pixelratio into account.
        this._canvas.width = pixelRatio * Math.ceil(width);
        this._canvas.height = pixelRatio * Math.ceil(height);

        // Maintain the same canvas size, potentially downscaling it for HiDPI displays
        this._canvas.style.width = `${width}px`;
        this._canvas.style.height = `${height}px`;
    }

    _addMarker(marker        ) {
        this._markers.push(marker);
    }

    _removeMarker(marker        ) {
        const index = this._markers.indexOf(marker);
        if (index !== -1) {
            this._markers.splice(index, 1);
        }
    }

    _addPopup(popup       ) {
        this._popups.push(popup);
    }

    _removePopup(popup       ) {
        const index = this._popups.indexOf(popup);
        if (index !== -1) {
            this._popups.splice(index, 1);
        }
    }

    _setupPainter() {
        const attributes = index.extend({}, supported.webGLContextAttributes, {
            failIfMajorPerformanceCaveat: this._failIfMajorPerformanceCaveat,
            preserveDrawingBuffer: this._preserveDrawingBuffer,
            antialias: this._antialias || false
        });

        const gl2 = this._useWebGL2 && ((this._canvas.getContext("webgl2", attributes)     )                       );
        const gl = gl2 ||
            this._canvas.getContext('webgl', attributes) ||
            this._canvas.getContext('experimental-webgl', attributes);

        if (!gl) {
            this.fire(new index.ErrorEvent(new Error('Failed to initialize WebGL')));
            return;
        }

        if (this._useWebGL2 && !gl2) {
            index.warnOnce('Failed to create WebGL 2 context. Using WebGL 1.');
        }
        index.storeAuthState(gl, true);

        this.painter = new Painter(gl, this.transform, !!gl2);
        this.on('data', (event              ) => {
            if (event.dataType === 'source') {
                this.painter.setTileLoadedFlag(true);
            }
        });

        index.exported$1.testSupport(gl);
    }

    _contextLost(event     ) {
        event.preventDefault();
        if (this._frame) {
            this._frame.cancel();
            this._frame = null;
        }
        this.fire(new index.Event('webglcontextlost', {originalEvent: event}));
    }

    _contextRestored(event     ) {
        this._setupPainter();
        this.resize();
        this._update();
        this.fire(new index.Event('webglcontextrestored', {originalEvent: event}));
    }

    _onMapScroll(event     )           {
        if (event.target !== this._container) return;

        // Revert any scroll which would move the canvas outside of the view
        this._container.scrollTop = 0;
        this._container.scrollLeft = 0;
        return false;
    }

    /** @section {Lifecycle} */

    /**
     * Returns a Boolean indicating whether the map is fully loaded.
     *
     * Returns `false` if the style is not yet fully loaded,
     * or if there has been a change to the sources or style that
     * has not yet fully loaded.
     *
     * @returns {boolean} A Boolean indicating whether the map is fully loaded.
     * @example
     * const isLoaded = map.loaded();
     */
    loaded()          {
        return !this._styleDirty && !this._sourcesDirty && !!this.style && this.style.loaded();
    }

    /**
     * Update this map's style and sources, and re-render the map.
     *
     * @param {boolean} updateStyle mark the map's style for reprocessing as
     * well as its sources
     * @returns {Map} this
     * @private
     */
    _update(updateStyle          )       {
        if (!this.style) return this;

        this._styleDirty = this._styleDirty || updateStyle;
        this._sourcesDirty = true;
        this.triggerRepaint();

        return this;
    }

    /**
     * Request that the given callback be executed during the next render
     * frame.  Schedule a render frame if one is not already scheduled.
     * @returns An id that can be used to cancel the callback
     * @private
     */
    // $FlowFixMe[method-unbinding]
    _requestRenderFrame(callback            )         {
        this._update();
        return this._renderTaskQueue.add(callback);
    }

    // $FlowFixMe[method-unbinding]
    _cancelRenderFrame(id        ) {
        this._renderTaskQueue.remove(id);
    }

    /**
     * Request that the given callback be executed during the next render frame if the map is not
     * idle. Otherwise it is executed immediately, to avoid triggering a new render.
     * @private
     */
    _requestDomTask(callback            ) {
        // This condition means that the map is idle: the callback needs to be called right now as
        // there won't be a triggered render to run the queue.
        if (!this.loaded() || (this.loaded() && !this.isMoving())) {
            callback();
        } else {
            this._domRenderTaskQueue.add(callback);
        }
    }

    /**
     * Call when a (re-)render of the map is required:
     * - The style has changed (`setPaintProperty()`, etc.)
     * - Source data has changed (for example, tiles have finished loading)
     * - The map has is moving (or just finished moving)
     * - A transition is in progress
     *
     * @param {number} paintStartTimeStamp  The time when the animation frame began executing.
     *
     * @returns {Map} this
     * @private
     */
    _render(paintStartTimeStamp        ) {
        const m = index.PerformanceUtils.beginMeasure('render');

        let gpuTimer;
        const extTimerQuery = this.painter.context.extTimerQuery;
        const frameStartTime = index.exported.now();
        if (this.listens('gpu-timing-frame')) {
            gpuTimer = extTimerQuery.createQueryEXT();
            extTimerQuery.beginQueryEXT(extTimerQuery.TIME_ELAPSED_EXT, gpuTimer);
        }

        // A custom layer may have used the context asynchronously. Mark the state as dirty.
        this.painter.context.setDirty();
        this.painter.setBaseState();

        if (this.isMoving() || this.isRotating() || this.isZooming()) {
            this._interactionRange[0] = Math.min(this._interactionRange[0], index.window.performance.now());
            this._interactionRange[1] = Math.max(this._interactionRange[1], index.window.performance.now());
        }

        this._renderTaskQueue.run(paintStartTimeStamp);
        this._domRenderTaskQueue.run(paintStartTimeStamp);
        // A task queue callback may have fired a user event which may have removed the map
        if (this._removed) return;

        this._updateProjectionTransition();

        const fadeDuration = this._isInitialLoad ? 0 : this._fadeDuration;

        // If the style has changed, the map is being zoomed, or a transition or fade is in progress:
        //  - Apply style changes (in a batch)
        //  - Recalculate paint properties.
        if (this.style && this._styleDirty) {
            this._styleDirty = false;

            const zoom = this.transform.zoom;
            const pitch = this.transform.pitch;
            const now = index.exported.now();

            const parameters = new index.EvaluationParameters(zoom, {
                now,
                fadeDuration,
                pitch,
                transition: this.style.getTransition()
            });

            this.style.update(parameters);
        }

        const fogIsTransitioning = this.style && this.style.fog && this.style.fog.hasTransition();

        if (fogIsTransitioning) {
            this.style._markersNeedUpdate = true;
            this._sourcesDirty = true;
        }

        // If we are in _render for any reason other than an in-progress paint
        // transition, update source caches to check for and load any tiles we
        // need for the current transform
        let averageElevationChanged = false;
        if (this.style && this._sourcesDirty) {
            this._sourcesDirty = false;
            this.painter._updateFog(this.style);
            this._updateTerrain(); // Terrain DEM source updates here and skips update in style._updateSources.
            averageElevationChanged = this._updateAverageElevation(frameStartTime);
            this.style._updateSources(this.transform);
            // Update positions of markers and popups on enabling/disabling terrain
            this._forceMarkerAndPopupUpdate();
        } else {
            averageElevationChanged = this._updateAverageElevation(frameStartTime);
        }

        this._placementDirty = this.style && this.style._updatePlacement(this.painter.transform, this.showCollisionBoxes, fadeDuration, this._crossSourceCollisions);

        // Actually draw
        if (this.style) {
            this.painter.render(this.style, {
                showTileBoundaries: this.showTileBoundaries,
                showTerrainWireframe: this.showTerrainWireframe,
                showOverdrawInspector: this._showOverdrawInspector,
                showQueryGeometry: !!this._showQueryGeometry,
                showTileAABBs: this.showTileAABBs,
                rotating: this.isRotating(),
                zooming: this.isZooming(),
                moving: this.isMoving(),
                fadeDuration,
                isInitialLoad: this._isInitialLoad,
                showPadding: this.showPadding,
                gpuTiming: !!this.listens('gpu-timing-layer'),
                gpuTimingDeferredRender: !!this.listens('gpu-timing-deferred-render'),
                speedIndexTiming: this.speedIndexTiming,
            });
        }

        this.fire(new index.Event('render'));

        if (this.loaded() && !this._loaded) {
            this._loaded = true;
            index.PerformanceUtils.mark(index.PerformanceMarkers.load);
            this.fire(new index.Event('load'));
        }

        if (this.style && (this.style.hasTransitions())) {
            this._styleDirty = true;
        }

        if (this.style && !this._placementDirty) {
            // Since no fade operations are in progress, we can release
            // all tiles held for fading. If we didn't do this, the tiles
            // would just sit in the SourceCaches until the next render
            this.style._releaseSymbolFadeTiles();
        }

        if (gpuTimer) {
            const renderCPUTime = index.exported.now() - frameStartTime;
            extTimerQuery.endQueryEXT(extTimerQuery.TIME_ELAPSED_EXT, gpuTimer);
            setTimeout(() => {
                const renderGPUTime = extTimerQuery.getQueryObjectEXT(gpuTimer, extTimerQuery.QUERY_RESULT_EXT) / (1000 * 1000);
                extTimerQuery.deleteQueryEXT(gpuTimer);
                this.fire(new index.Event('gpu-timing-frame', {
                    cpuTime: renderCPUTime,
                    gpuTime: renderGPUTime
                }));
                index.window.performance.mark('frame-gpu', {
                    startTime: frameStartTime,
                    detail: {
                        gpuTime: renderGPUTime
                    }
                });
            }, 50); // Wait 50ms to give time for all GPU calls to finish before querying
        }

        index.PerformanceUtils.endMeasure(m);

        if (this.listens('gpu-timing-layer')) {
            // Resetting the Painter's per-layer timing queries here allows us to isolate
            // the queries to individual frames.
            const frameLayerQueries = this.painter.collectGpuTimers();

            setTimeout(() => {
                const renderedLayerTimes = this.painter.queryGpuTimers(frameLayerQueries);

                this.fire(new index.Event('gpu-timing-layer', {
                    layerTimes: renderedLayerTimes
                }));
            }, 50); // Wait 50ms to give time for all GPU calls to finish before querying
        }

        if (this.listens('gpu-timing-deferred-render')) {
            const deferredRenderQueries = this.painter.collectDeferredRenderGpuQueries();

            setTimeout(() => {
                const gpuTime = this.painter.queryGpuTimeDeferredRender(deferredRenderQueries);
                this.fire(new index.Event('gpu-timing-deferred-render', {gpuTime}));
            }, 50); // Wait 50ms to give time for all GPU calls to finish before querying
        }

        // Schedule another render frame if it's needed.
        //
        // Even though `_styleDirty` and `_sourcesDirty` are reset in this
        // method, synchronous events fired during Style#update or
        // Style#_updateSources could have caused them to be set again.
        const somethingDirty = this._sourcesDirty || this._styleDirty || this._placementDirty || averageElevationChanged;
        if (somethingDirty || this._repaint) {
            this.triggerRepaint();
        } else {
            const willIdle = !this.isMoving() && this.loaded();
            if (willIdle) {
                // Before idling, we perform one last sample so that if the average elevation
                // does not exactly match the terrain, we skip idle and ease it to its final state.
                averageElevationChanged = this._updateAverageElevation(frameStartTime, true);
            }

            if (averageElevationChanged) {
                this.triggerRepaint();
            } else {
                this._triggerFrame(false);
                if (willIdle) {
                    this.fire(new index.Event('idle'));
                    this._isInitialLoad = false;
                    // check the options to see if need to calculate the speed index
                    if (this.speedIndexTiming) {
                        const speedIndexNumber = this._calculateSpeedIndex();
                        this.fire(new index.Event('speedindexcompleted', {speedIndex: speedIndexNumber}));
                        this.speedIndexTiming = false;
                    }
                }
            }
        }

        if (this._loaded && !this._fullyLoaded && !somethingDirty) {
            this._fullyLoaded = true;
            index.LivePerformanceUtils.mark(index.PerformanceMarkers.fullLoad);
            // Following lines are billing and metrics related code. Do not change. See LICENSE.txt
            if (this._performanceMetricsCollection) {
                index.postPerformanceEvent(this._requestManager._customAccessToken, {
                    width: this.painter.width,
                    height: this.painter.height,
                    interactionRange: this._interactionRange,
                    visibilityHidden: this._visibilityHidden,
                    terrainEnabled: !!this.painter.style.getTerrain(),
                    fogEnabled: !!this.painter.style.getFog(),
                    projection: this.getProjection().name,
                    zoom: this.transform.zoom,
                    renderer: this.painter.context.renderer,
                    vendor: this.painter.context.vendor
                });
            }
            this._authenticate();
        }
    }

    _forceMarkerAndPopupUpdate(shouldWrap          ) {
        for (const marker of this._markers) {
            // Wrap marker location when toggling to a projection without world copies
            if (shouldWrap && !this.getRenderWorldCopies()) {
                marker._lngLat = marker._lngLat.wrap();
            }
            marker._update();
        }
        for (const popup of this._popups) {
            // Wrap popup location when toggling to a projection without world copies and track pointer set to false
            if (shouldWrap && !this.getRenderWorldCopies() && !popup._trackPointer) {
                popup._lngLat = popup._lngLat.wrap();
            }
            popup._update();
        }
    }

    /**
     * Update the average visible elevation by sampling terrain
     *
     * @returns {boolean} true if elevation has changed from the last sampling
     * @private
     */
    _updateAverageElevation(timeStamp        , ignoreTimeout          = false)          {
        const applyUpdate = (value        ) => {
            this.transform.averageElevation = value;
            this._update(false);
            return true;
        };

        if (!this.painter.averageElevationNeedsEasing()) {
            if (this.transform.averageElevation !== 0) return applyUpdate(0);
            return false;
        }

        const timeoutElapsed = ignoreTimeout || timeStamp - this._averageElevationLastSampledAt > AVERAGE_ELEVATION_SAMPLING_INTERVAL;

        if (timeoutElapsed && !this._averageElevation.isEasing(timeStamp)) {
            const currentElevation = this.transform.averageElevation;
            let newElevation = this.transform.sampleAverageElevation();
            let exaggerationChanged = false;
            if (this.transform.elevation) {
                exaggerationChanged = this.transform.elevation.exaggeration() !== this._averageElevationExaggeration;
                // $FlowIgnore[incompatible-use]
                this._averageElevationExaggeration = this.transform.elevation.exaggeration();
            }

            // New elevation is NaN if no terrain tiles were available
            if (isNaN(newElevation)) {
                newElevation = 0;
            } else {
                // Don't activate the timeout if no data was available
                this._averageElevationLastSampledAt = timeStamp;
            }
            const elevationChange = Math.abs(currentElevation - newElevation);

            if (elevationChange > AVERAGE_ELEVATION_EASE_THRESHOLD) {
                if (this._isInitialLoad || exaggerationChanged) {
                    this._averageElevation.jumpTo(newElevation);
                    return applyUpdate(newElevation);
                } else {
                    this._averageElevation.easeTo(newElevation, timeStamp, AVERAGE_ELEVATION_EASE_TIME);
                }
            } else if (elevationChange > AVERAGE_ELEVATION_CHANGE_THRESHOLD) {
                this._averageElevation.jumpTo(newElevation);
                return applyUpdate(newElevation);
            }
        }

        if (this._averageElevation.isEasing(timeStamp)) {
            return applyUpdate(this._averageElevation.getValue(timeStamp));
        }

        return false;
    }

    /***** START WARNING - REMOVAL OR MODIFICATION OF THE
    * FOLLOWING CODE VIOLATES THE MAPBOX TERMS OF SERVICE  ******
    * The following code is used to access Mapbox's APIs. Removal or modification
    * of this code can result in higher fees and/or
    * termination of your account with Mapbox.
    *
    * Under the Mapbox Terms of Service, you may not use this code to access Mapbox
    * Mapping APIs other than through Mapbox SDKs.
    *
    * The Mapping APIs documentation is available at https://docs.mapbox.com/api/maps/#maps
    * and the Mapbox Terms of Service are available at https://www.mapbox.com/tos/
    ******************************************************************************/

    _authenticate() {
        index.getMapSessionAPI(this._getMapId(), this._requestManager._skuToken, this._requestManager._customAccessToken, (err) => {
            if (err) {
                // throwing an error here will cause the callback to be called again unnecessarily
                if (err.message === index.AUTH_ERR_MSG || (err     ).status === 401) {
                    const gl = this.painter.context.gl;
                    index.storeAuthState(gl, false);
                    if (this._logoControl instanceof LogoControl) {
                        this._logoControl._updateLogo();
                    }
                    if (gl) gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);

                    if (!this._silenceAuthErrors) {
                        this.fire(new index.ErrorEvent(new Error('A valid Mapbox access token is required to use Mapbox GL JS. To create an account or a new access token, visit https://account.mapbox.com/')));
                    }
                }
            }
        });
        index.postMapLoadEvent(this._getMapId(), this._requestManager._skuToken, this._requestManager._customAccessToken, () => {});
    }

    /***** END WARNING - REMOVAL OR MODIFICATION OF THE
    PRECEDING CODE VIOLATES THE MAPBOX TERMS OF SERVICE  ******/

    _updateTerrain() {
        // Recalculate if enabled/disabled and calculate elevation cover. As camera is using elevation tiles before
        // render (and deferred update after zoom recalculation), this needs to be called when removing terrain source.
        const adaptCameraAltitude = this._isDragging();
        this.painter.updateTerrain(this.style, adaptCameraAltitude);
    }

    _calculateSpeedIndex()         {
        const finalFrame = this.painter.canvasCopy();
        const canvasCopyInstances = this.painter.getCanvasCopiesAndTimestamps();
        canvasCopyInstances.timeStamps.push(performance.now());

        const gl = this.painter.context.gl;
        const framebuffer = gl.createFramebuffer();
        gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);

        function read(texture               ) {
            gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
            const pixels = new Uint8Array(gl.drawingBufferWidth * gl.drawingBufferHeight * 4);
            gl.readPixels(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
            return pixels;
        }

        return this._canvasPixelComparison(read(finalFrame), canvasCopyInstances.canvasCopies.map(read), canvasCopyInstances.timeStamps);
    }

    _canvasPixelComparison(finalFrame            , allFrames              , timeStamps          )         {
        let finalScore = timeStamps[1] - timeStamps[0];
        const numPixels = finalFrame.length / 4;

        for (let i = 0; i < allFrames.length; i++) {
            const frame = allFrames[i];
            let cnt = 0;
            for (let j = 0; j < frame.length; j += 4) {
                if (frame[j] === finalFrame[j] &&
                    frame[j + 1] === finalFrame[j + 1] &&
                    frame[j + 2] === finalFrame[j + 2] &&
                    frame[j + 3] === finalFrame[j + 3]) {
                    cnt = cnt + 1;
                }
            }
            //calculate the % visual completeness
            const interval = timeStamps[i + 2] - timeStamps[i + 1];
            const visualCompletness = cnt / numPixels;
            finalScore +=  interval * (1 - visualCompletness);
        }
        return finalScore;
    }

    /**
     * Clean up and release all internal resources associated with this map.
     *
     * This includes DOM elements, event bindings, web workers, and WebGL resources.
     *
     * Use this method when you are done using the map and wish to ensure that it no
     * longer consumes browser resources. Afterwards, you must not call any other
     * methods on the map.
     *
     * @example
     * map.remove();
     */
    remove() {
        if (this._hash) this._hash.remove();

        for (const control of this._controls) control.onRemove(this);
        this._controls = [];

        if (this._frame) {
            this._frame.cancel();
            this._frame = null;
        }
        this._renderTaskQueue.clear();
        this._domRenderTaskQueue.clear();
        if (this.style) {
            this.style.destroy();
        }
        this.painter.destroy();
        if (this.handlers) this.handlers.destroy();
        this.handlers = undefined;
        this.setStyle(null);

        if (typeof index.window !== 'undefined') {
            // $FlowFixMe[method-unbinding]
            index.window.removeEventListener('resize', this._onWindowResize, false);
            // $FlowFixMe[method-unbinding]
            index.window.removeEventListener('orientationchange', this._onWindowResize, false);
            // $FlowFixMe[method-unbinding]
            index.window.removeEventListener('webkitfullscreenchange', this._onWindowResize, false);
            // $FlowFixMe[method-unbinding]
            index.window.removeEventListener('online', this._onWindowOnline, false);
            // $FlowFixMe[method-unbinding]
            index.window.removeEventListener('visibilitychange', this._onVisibilityChange, false);
        }

        const extension = this.painter.context.gl.getExtension('WEBGL_lose_context');
        if (extension) extension.loseContext();

        // $FlowFixMe[method-unbinding]
        this._canvas.removeEventListener('webglcontextlost', this._contextLost, false);
        // $FlowFixMe[method-unbinding]
        this._canvas.removeEventListener('webglcontextrestored', this._contextRestored, false);

        this._canvasContainer.remove();
        this._controlContainer.remove();
        this._missingCSSCanary.remove();

        this._canvas = (undefined     );
        this._canvasContainer = (undefined     );
        this._controlContainer = (undefined     );
        this._missingCSSCanary = (undefined     );

        this._container.classList.remove('mapboxgl-map');
        // $FlowFixMe[method-unbinding]
        this._container.removeEventListener('scroll', this._onMapScroll, false);

        index.PerformanceUtils.clearMetrics();
        index.removeAuthState(this.painter.context.gl);
        this._removed = true;
        this.fire(new index.Event('remove'));
    }

    /**
     * Trigger the rendering of a single frame. Use this method with custom layers to
     * repaint the map when the layer's properties or properties associated with the
     * layer's source change. Calling this multiple times before the
     * next frame is rendered will still result in only a single frame being rendered.
     *
     * @example
     * map.triggerRepaint();
     * @see [Example: Add a 3D model](https://docs.mapbox.com/mapbox-gl-js/example/add-3d-model/)
     * @see [Example: Add an animated icon to the map](https://docs.mapbox.com/mapbox-gl-js/example/add-image-animated/)
     */
    triggerRepaint() {
        this._triggerFrame(true);
    }

    _triggerFrame(render         ) {
        this._renderNextFrame = this._renderNextFrame || render;
        if (this.style && !this._frame) {
            this._frame = index.exported.frame((paintStartTimeStamp        ) => {
                const isRenderFrame = !!this._renderNextFrame;
                index.PerformanceUtils.frame(paintStartTimeStamp, isRenderFrame);
                this._frame = null;
                this._renderNextFrame = null;
                if (isRenderFrame) {
                    this._render(paintStartTimeStamp);
                }
            });
        }
    }

    /**
     * Preloads all tiles that will be requested for one or a series of transformations
     *
     * @private
     * @returns {Object} Returns `this` | Promise.
     */
    // $FlowFixMe[method-unbinding]
    _preloadTiles(transform                              )       {
        const sources                     = this.style ? (Object.values(this.style._sourceCaches)     ) : [];
        index.asyncAll(sources, (source, done) => source._preloadTiles(transform, done), () => {
            this.triggerRepaint();
        });

        return this;
    }

    _onWindowOnline() {
        this._update();
    }

    _onWindowResize(event       ) {
        if (this._trackResize) {
            this.resize({originalEvent: event})._update();
        }
    }

    _onVisibilityChange() {
        if (index.window.document.visibilityState === 'hidden') {
            this._visibilityHidden++;
        }
    }

    /** @section {Debug features} */

    /**
     * Gets and sets a Boolean indicating whether the map will render an outline
     * around each tile and the tile ID. These tile boundaries are useful for
     * debugging.
     *
     * The uncompressed file size of the first vector source is drawn in the top left
     * corner of each tile, next to the tile ID.
     *
     * @name showTileBoundaries
     * @type {boolean}
     * @instance
     * @memberof Map
     * @example
     * map.showTileBoundaries = true;
     */
    get showTileBoundaries()          { return !!this._showTileBoundaries; }
    set showTileBoundaries(value         ) {
        if (this._showTileBoundaries === value) return;
        this._showTileBoundaries = value;
        this._update();
    }

    /**
     * Gets and sets a Boolean indicating whether the map will render a wireframe
     * on top of the displayed terrain. Useful for debugging.
     *
     * The wireframe is always red and is drawn only when terrain is active.
     *
     * @name showTerrainWireframe
     * @type {boolean}
     * @instance
     * @memberof Map
     * @example
     * map.showTerrainWireframe = true;
     */
    get showTerrainWireframe()          { return !!this._showTerrainWireframe; }
    set showTerrainWireframe(value         ) {
        if (this._showTerrainWireframe === value) return;
        this._showTerrainWireframe = value;
        this._update();
    }

    /**
     * Gets and sets a Boolean indicating whether the speedindex metric calculation is on or off
     *
     * @private
     * @name speedIndexTiming
     * @type {boolean}
     * @instance
     * @memberof Map
     * @example
     * map.speedIndexTiming = true;
     */
    get speedIndexTiming()          { return !!this._speedIndexTiming; }
    set speedIndexTiming(value         ) {
        if (this._speedIndexTiming === value) return;
        this._speedIndexTiming = value;
        this._update();
    }

    /**
     * Gets and sets a Boolean indicating whether the map will visualize
     * the padding offsets.
     *
     * @name showPadding
     * @type {boolean}
     * @instance
     * @memberof Map
     */
    get showPadding()          { return !!this._showPadding; }
    set showPadding(value         ) {
        if (this._showPadding === value) return;
        this._showPadding = value;
        this._update();
    }

    /**
     * Gets and sets a Boolean indicating whether the map will render boxes
     * around all symbols in the data source, revealing which symbols
     * were rendered or which were hidden due to collisions.
     * This information is useful for debugging.
     *
     * @name showCollisionBoxes
     * @type {boolean}
     * @instance
     * @memberof Map
     */
    get showCollisionBoxes()          { return !!this._showCollisionBoxes; }
    set showCollisionBoxes(value         ) {
        if (this._showCollisionBoxes === value) return;
        this._showCollisionBoxes = value;
        if (value) {
            // When we turn collision boxes on we have to generate them for existing tiles
            // When we turn them off, there's no cost to leaving existing boxes in place
            this.style._generateCollisionBoxes();
        } else {
            // Otherwise, call an update to remove collision boxes
            this._update();
        }
    }

    /**
     * Gets and sets a Boolean indicating whether the map should color-code
     * each fragment to show how many times it has been shaded.
     * White fragments have been shaded 8 or more times.
     * Black fragments have been shaded 0 times.
     * This information is useful for debugging.
     *
     * @name showOverdraw
     * @type {boolean}
     * @instance
     * @memberof Map
     */
    get showOverdrawInspector()          { return !!this._showOverdrawInspector; }
    set showOverdrawInspector(value         ) {
        if (this._showOverdrawInspector === value) return;
        this._showOverdrawInspector = value;
        this._update();
    }

    /**
     * Gets and sets a Boolean indicating whether the map will
     * continuously repaint. This information is useful for analyzing performance.
     *
     * @name repaint
     * @type {boolean}
     * @instance
     * @memberof Map
     */
    get repaint()          { return !!this._repaint; }
    set repaint(value         ) {
        if (this._repaint !== value) {
            this._repaint = value;
            this.triggerRepaint();
        }
    }
    // show vertices
    get vertices()          { return !!this._vertices; }
    set vertices(value         ) { this._vertices = value; this._update(); }

    /**
    * Display tile AABBs for debugging
    *
    * @private
    * @type {boolean}
    */
    get showTileAABBs()          { return !!this._showTileAABBs; }
    set showTileAABBs(value         ) {
        if (this._showTileAABBs === value) return;
        this._showTileAABBs = value;
        if (!value) { index.Debug.clearAabbs(); return; }
        this._update();
    }

    // for cache browser tests
    _setCacheLimits(limit        , checkThreshold        ) {
        index.setCacheLimits(limit, checkThreshold);
    }

    /**
     * The version of Mapbox GL JS in use as specified in package.json, CHANGELOG.md, and the GitHub release.
     *
     * @name version
     * @instance
     * @memberof Map
     * @var {string} version
     */

    get version()         { return index.version; }
}

/**
 * Interface for interactive controls added to the map. This is a
 * specification for implementers to model: it is not
 * an exported method or class.
 *
 * Controls must implement `onAdd` and `onRemove`, and must own an
 * element, which is often a `div` element. To use Mapbox GL JS's
 * default control styling, add the `mapboxgl-ctrl` class to your control's
 * node.
 *
 * @interface IControl
 * @example
 * // Control implemented as ES6 class
 * class HelloWorldControl {
 *     onAdd(map) {
 *         this._map = map;
 *         this._container = document.createElement('div');
 *         this._container.className = 'mapboxgl-ctrl';
 *         this._container.textContent = 'Hello, world';
 *         return this._container;
 *     }
 *
 *     onRemove() {
 *         this._container.parentNode.removeChild(this._container);
 *         this._map = undefined;
 *     }
 * }
 *
 * @example
 * // Control implemented as ES5 prototypical class
 * function HelloWorldControl() { }
 *
 * HelloWorldControl.prototype.onAdd = function(map) {
 *     this._map = map;
 *     this._container = document.createElement('div');
 *     this._container.className = 'mapboxgl-ctrl';
 *     this._container.textContent = 'Hello, world';
 *     return this._container;
 * };
 *
 * HelloWorldControl.prototype.onRemove = function () {
 *     this._container.parentNode.removeChild(this._container);
 *     this._map = undefined;
 * };
 */

/**
 * Register a control on the map and give it a chance to register event listeners
 * and resources. This method is called by {@link Map#addControl}
 * internally.
 *
 * @function
 * @memberof IControl
 * @instance
 * @name onAdd
 * @param {Map} map The Map this control will be added to.
 * @returns {HTMLElement} The control's container element. This should
 * be created by the control and returned by onAdd without being attached
 * to the DOM: the map will insert the control's element into the DOM
 * as necessary.
 */

/**
 * Unregister a control on the map and give it a chance to detach event listeners
 * and resources. This method is called by {@link Map#removeControl}
 * internally.
 *
 * @function
 * @memberof IControl
 * @instance
 * @name onRemove
 * @param {Map} map The Map this control will be removed from.
 * @returns {undefined} There is no required return value for this method.
 */

/**
 * Optionally provide a default position for this control. If this method
 * is implemented and {@link Map#addControl} is called without the `position`
 * parameter, the value returned by getDefaultPosition will be used as the
 * control's position.
 *
 * @function
 * @memberof IControl
 * @instance
 * @name getDefaultPosition
 * @returns {string} A control position, one of the values valid in addControl.
 */

/**
 * A [`Point` geometry](https://github.com/mapbox/point-geometry) object, which has
 * `x` and `y` properties representing screen coordinates in pixels.
 *
 * @typedef {Point} Point
 * @example
 * const point = new mapboxgl.Point(-77, 38);
 */

/**
 * A {@link Point} or an array of two numbers representing `x` and `y` screen coordinates in pixels.
 *
 * @typedef {(Point | Array<number>)} PointLike
 * @example
 * const p1 = new mapboxgl.Point(-77, 38); // a PointLike which is a Point
 * const p2 = [-77, 38]; // a PointLike which is an array of two numbers
 */

//      


                                 
                                                

                
                          
                       
                            
  

const defaultOptions$2          = {
    showCompass: true,
    showZoom: true,
    visualizePitch: false
};

/**
 * A `NavigationControl` control contains zoom buttons and a compass.
 * Add this control to a map using {@link Map#addControl}.
 *
 * @implements {IControl}
 * @param {Object} [options]
 * @param {boolean} [options.showCompass=true] If `true` the compass button is included.
 * @param {boolean} [options.showZoom=true] If `true` the zoom-in and zoom-out buttons are included.
 * @param {boolean} [options.visualizePitch=false] If `true` the pitch is visualized by rotating X-axis of compass.
 * @example
 * const nav = new mapboxgl.NavigationControl();
 * map.addControl(nav, 'top-left');
 * @example
 * const nav = new mapboxgl.NavigationControl({
 *     visualizePitch: true
 * });
 * map.addControl(nav, 'bottom-right');
 * @see [Example: Display map navigation controls](https://www.mapbox.com/mapbox-gl-js/example/navigation/)
 * @see [Example: Add a third party vector tile source](https://www.mapbox.com/mapbox-gl-js/example/third-party/)
 */
class NavigationControl {
               
                     
                            
                                     
                                      
                                
                              
                                  

    constructor(options         ) {
        this.options = index.extend({}, defaultOptions$2, options);

        this._container = create$1('div', 'mapboxgl-ctrl mapboxgl-ctrl-group');
        this._container.addEventListener('contextmenu', (e            ) => e.preventDefault());

        if (this.options.showZoom) {
            index.bindAll([
                '_setButtonTitle',
                '_updateZoomButtons'
            ], this);
            this._zoomInButton = this._createButton('mapboxgl-ctrl-zoom-in', (e) => { if (this._map) this._map.zoomIn({}, {originalEvent: e}); });
            create$1('span', `mapboxgl-ctrl-icon`, this._zoomInButton).setAttribute('aria-hidden', 'true');
            this._zoomOutButton = this._createButton('mapboxgl-ctrl-zoom-out', (e) => { if (this._map) this._map.zoomOut({}, {originalEvent: e}); });
            create$1('span', `mapboxgl-ctrl-icon`, this._zoomOutButton).setAttribute('aria-hidden', 'true');
        }
        if (this.options.showCompass) {
            index.bindAll([
                '_rotateCompassArrow'
            ], this);
            this._compass = this._createButton('mapboxgl-ctrl-compass', (e) => {
                const map = this._map;
                if (!map) return;
                if (this.options.visualizePitch) {
                    map.resetNorthPitch({}, {originalEvent: e});
                } else {
                    map.resetNorth({}, {originalEvent: e});
                }
            });
            this._compassIcon = create$1('span', 'mapboxgl-ctrl-icon', this._compass);
            this._compassIcon.setAttribute('aria-hidden', 'true');
        }
    }

    _updateZoomButtons() {
        const map = this._map;
        if (!map) return;

        const zoom = map.getZoom();
        const isMax = zoom === map.getMaxZoom();
        const isMin = zoom === map.getMinZoom();
        this._zoomInButton.disabled = isMax;
        this._zoomOutButton.disabled = isMin;
        this._zoomInButton.setAttribute('aria-disabled', isMax.toString());
        this._zoomOutButton.setAttribute('aria-disabled', isMin.toString());
    }

    _rotateCompassArrow() {
        const map = this._map;
        if (!map) return;

        const rotate = this.options.visualizePitch ?
            `scale(${1 / Math.pow(Math.cos(map.transform.pitch * (Math.PI / 180)), 0.5)}) rotateX(${map.transform.pitch}deg) rotateZ(${map.transform.angle * (180 / Math.PI)}deg)` :
            `rotate(${map.transform.angle * (180 / Math.PI)}deg)`;

        map._requestDomTask(() => {
            if (this._compassIcon) {
                this._compassIcon.style.transform = rotate;
            }
        });
    }

    onAdd(map     )              {
        this._map = map;
        if (this.options.showZoom) {
            this._setButtonTitle(this._zoomInButton, 'ZoomIn');
            this._setButtonTitle(this._zoomOutButton, 'ZoomOut');
            // $FlowFixMe[method-unbinding]
            map.on('zoom', this._updateZoomButtons);
            this._updateZoomButtons();
        }
        if (this.options.showCompass) {
            this._setButtonTitle(this._compass, 'ResetBearing');
            if (this.options.visualizePitch) {
                // $FlowFixMe[method-unbinding]
                map.on('pitch', this._rotateCompassArrow);
            }
            // $FlowFixMe[method-unbinding]
            map.on('rotate', this._rotateCompassArrow);
            this._rotateCompassArrow();
            this._handler = new MouseRotateWrapper(map, this._compass, this.options.visualizePitch);
        }
        return this._container;
    }

    onRemove() {
        const map = this._map;
        if (!map) return;
        this._container.remove();
        if (this.options.showZoom) {
            // $FlowFixMe[method-unbinding]
            map.off('zoom', this._updateZoomButtons);
        }
        if (this.options.showCompass) {
            if (this.options.visualizePitch) {
                // $FlowFixMe[method-unbinding]
                map.off('pitch', this._rotateCompassArrow);
            }
            // $FlowFixMe[method-unbinding]
            map.off('rotate', this._rotateCompassArrow);
            if (this._handler) this._handler.off();
            this._handler = undefined;
        }
        this._map = undefined;
    }

    _createButton(className        , fn             )                    {
        const a = create$1('button', className, this._container);
        a.type = 'button';
        a.addEventListener('click', fn);
        return a;
    }

    _setButtonTitle(button                   , title        ) {
        if (!this._map) return;
        const str = this._map._getUIString(`NavigationControl.${title}`);
        button.setAttribute('aria-label', str);
        if (button.firstElementChild) button.firstElementChild.setAttribute('title', str);
    }
}

class MouseRotateWrapper {

             
                            
                         
                                    
                                  
                      
                     

    constructor(map     , element             , pitch           = false) {
        this._clickTolerance = 10;
        this.element = element;
        this.mouseRotate = new MouseRotateHandler({clickTolerance: map.dragRotate._mouseRotate._clickTolerance});
        this.map = map;
        if (pitch) this.mousePitch = new MousePitchHandler({clickTolerance: map.dragRotate._mousePitch._clickTolerance});

        index.bindAll(['mousedown', 'mousemove', 'mouseup', 'touchstart', 'touchmove', 'touchend', 'reset'], this);
        // $FlowFixMe[method-unbinding]
        element.addEventListener('mousedown', this.mousedown);
        // $FlowFixMe[method-unbinding]
        element.addEventListener('touchstart', this.touchstart, {passive: false});
        // $FlowFixMe[method-unbinding]
        element.addEventListener('touchmove', this.touchmove);
        // $FlowFixMe[method-unbinding]
        element.addEventListener('touchend', this.touchend);
        // $FlowFixMe[method-unbinding]
        element.addEventListener('touchcancel', this.reset);
    }

    down(e            , point       ) {
        this.mouseRotate.mousedown(e, point);
        if (this.mousePitch) this.mousePitch.mousedown(e, point);
        disableDrag();
    }

    move(e            , point       ) {
        const map = this.map;
        const r = this.mouseRotate.mousemoveWindow(e, point);
        const delta = r && r.bearingDelta;
        if (delta) map.setBearing(map.getBearing() + delta);
        if (this.mousePitch) {
            const p = this.mousePitch.mousemoveWindow(e, point);
            const delta = p && p.pitchDelta;
            if (delta) map.setPitch(map.getPitch() + delta);
        }
    }

    off() {
        const element = this.element;
        // $FlowFixMe[method-unbinding]
        element.removeEventListener('mousedown', this.mousedown);
        // $FlowFixMe[method-unbinding]
        element.removeEventListener('touchstart', this.touchstart, {passive: false});
        // $FlowFixMe[method-unbinding]
        element.removeEventListener('touchmove', this.touchmove);
        // $FlowFixMe[method-unbinding]
        element.removeEventListener('touchend', this.touchend);
        // $FlowFixMe[method-unbinding]
        element.removeEventListener('touchcancel', this.reset);
        this.offTemp();
    }

    offTemp() {
        enableDrag();
        // $FlowFixMe[method-unbinding]
        index.window.removeEventListener('mousemove', this.mousemove);
        // $FlowFixMe[method-unbinding]
        index.window.removeEventListener('mouseup', this.mouseup);
    }

    mousedown(e            ) {
        this.down(index.extend({}, e, {ctrlKey: true, preventDefault: () => e.preventDefault()}), mousePos(this.element, e));
        // $FlowFixMe[method-unbinding]
        index.window.addEventListener('mousemove', this.mousemove);
        // $FlowFixMe[method-unbinding]
        index.window.addEventListener('mouseup', this.mouseup);
    }

    mousemove(e            ) {
        this.move(e, mousePos(this.element, e));
    }

    mouseup(e            ) {
        this.mouseRotate.mouseupWindow(e);
        if (this.mousePitch) this.mousePitch.mouseupWindow(e);
        this.offTemp();
    }

    touchstart(e            ) {
        if (e.targetTouches.length !== 1) {
            this.reset();
        } else {
            this._startPos = this._lastPos = touchPos(this.element, e.targetTouches)[0];
            this.down((({type: 'mousedown', button: 0, ctrlKey: true, preventDefault: () => e.preventDefault()}     )            ), this._startPos);
        }
    }

    touchmove(e            ) {
        if (e.targetTouches.length !== 1) {
            this.reset();
        } else {
            this._lastPos = touchPos(this.element, e.targetTouches)[0];
            this.move((({preventDefault: () => e.preventDefault()}     )            ), this._lastPos);
        }
    }

    touchend(e            ) {
        if (e.targetTouches.length === 0 &&
            this._startPos &&
            this._lastPos &&
            this._startPos.dist(this._lastPos) < this._clickTolerance) {
            this.element.click();
        }
        this.reset();
    }

    reset() {
        this.mouseRotate.reset();
        if (this.mousePitch) this.mousePitch.reset();
        delete this._startPos;
        delete this._lastPos;
        this.offTemp();
    }
}

//      


                                 
                                                                  

                
                                     
                                                       
                               
                                
                              
                             
                             
  

                               
                      
                  
                 
                  
                                       
                                  
 

const defaultOptions$1 = {
    positionOptions: {
        enableHighAccuracy: false,
        maximumAge: 0,
        timeout: 6000 /* 6 sec */
    },
    fitBoundsOptions: {
        maxZoom: 15
    },
    trackUserLocation: false,
    showAccuracyCircle: true,
    showUserLocation: true,
    showUserHeading: false
};

/**
 * A `GeolocateControl` control provides a button that uses the browser's geolocation
 * API to locate the user on the map.
 * Add this control to a map using {@link Map#addControl}.
 *
 * Not all browsers support geolocation,
 * and some users may disable the feature. Geolocation support for modern
 * browsers including Chrome requires sites to be served over HTTPS. If
 * geolocation support is not available, the GeolocateControl will show
 * as disabled.
 *
 * The [zoom level](https://docs.mapbox.com/help/glossary/zoom-level/) applied depends on the accuracy of the geolocation provided by the device.
 *
 * The GeolocateControl has two modes. If `trackUserLocation` is `false` (default) the control acts as a button, which when pressed will set the map's camera to target the user location. If the user moves, the map won't update. This is most suited for the desktop. If `trackUserLocation` is `true` the control acts as a toggle button that when active the user's location is actively monitored for changes. In this mode the GeolocateControl has three interaction states:
 * * active - The map's camera automatically updates as the user's location changes, keeping the location dot in the center. This is the initial state, and the state upon clicking the `GeolocateControl` button.
 * * passive - The user's location dot automatically updates, but the map's camera does not. Occurs upon the user initiating a map movement.
 * * disabled - Occurs if geolocation is not available, disabled, or denied.
 *
 * These interaction states can't be controlled programmatically. Instead, they are set based on user interactions.
 *
 * @implements {IControl}
 * @param {Object} [options]
 * @param {Object} [options.positionOptions={enableHighAccuracy: false, timeout: 6000}] A Geolocation API [PositionOptions](https://developer.mozilla.org/en-US/docs/Web/API/PositionOptions) object.
 * @param {Object} [options.fitBoundsOptions={maxZoom: 15}] A {@link Map#fitBounds} options object to use when the map is panned and zoomed to the user's location. The default is to use a `maxZoom` of 15 to limit how far the map will zoom in for very accurate locations.
 * @param {Object} [options.trackUserLocation=false] If `true` the GeolocateControl becomes a toggle button and when active the map will receive updates to the user's location as it changes.
 * @param {Object} [options.showAccuracyCircle=true] By default, if `showUserLocation` is `true`, a transparent circle will be drawn around the user location indicating the accuracy (95% confidence level) of the user's location. Set to `false` to disable. Always disabled when `showUserLocation` is `false`.
 * @param {Object} [options.showUserLocation=true] By default a dot will be shown on the map at the user's location. Set to `false` to disable.
 * @param {Object} [options.showUserHeading=false] If `true` an arrow will be drawn next to the user location dot indicating the device's heading. This only has affect when `trackUserLocation` is `true`.
 * @param {Object} [options.geolocation=window.navigator.geolocation] `window.navigator.geolocation` by default; you can provide an object with the same shape to customize geolocation handling.
 *
 * @example
 * map.addControl(new mapboxgl.GeolocateControl({
 *     positionOptions: {
 *         enableHighAccuracy: true
 *     },
 *     trackUserLocation: true,
 *     showUserHeading: true
 * }));
 * @see [Example: Locate the user](https://www.mapbox.com/mapbox-gl-js/example/locate-user/)
 */
class GeolocateControl extends index.Evented {
              
                     
                            
                             
                                
                                        
                                
                           
                                                                                                               
                            
                                   
                                  
                      
                     // set to true once the control has been setup
                      
                                             

                             
                        
                                  

    constructor(options                 ) {
        super();
        const geolocation = index.window.navigator.geolocation;
        this.options = index.extend({geolocation}, defaultOptions$1, options);

        index.bindAll([
            '_onSuccess',
            '_onError',
            '_onZoom',
            '_finish',
            '_setupUI',
            '_updateCamera',
            '_updateMarker',
            '_updateMarkerRotation',
            '_onDeviceOrientation'
        ], this);

        // $FlowFixMe[method-unbinding]
        this._updateMarkerRotationThrottled = throttle(this._updateMarkerRotation, 20);
        this._numberOfWatches = 0;
    }

    onAdd(map     )              {
        this._map = map;
        this._container = create$1('div', `mapboxgl-ctrl mapboxgl-ctrl-group`);
        // $FlowFixMe[method-unbinding]
        this._checkGeolocationSupport(this._setupUI);
        return this._container;
    }

    onRemove() {
        // clear the geolocation watch if exists
        if (this._geolocationWatchID !== undefined) {
            this.options.geolocation.clearWatch(this._geolocationWatchID);
            this._geolocationWatchID = (undefined     );
        }

        // clear the markers from the map
        if (this.options.showUserLocation && this._userLocationDotMarker) {
            this._userLocationDotMarker.remove();
        }
        if (this.options.showAccuracyCircle && this._accuracyCircleMarker) {
            this._accuracyCircleMarker.remove();
        }

        this._container.remove();
        // $FlowFixMe[method-unbinding]
        this._map.off('zoom', this._onZoom);
        this._map = (undefined     );
        this._numberOfWatches = 0;
        this._noTimeout = false;
    }

    _checkGeolocationSupport(callback                 ) {
        const updateSupport = (supported          = !!this.options.geolocation) => {
            this._supportsGeolocation = supported;
            callback(supported);
        };

        if (this._supportsGeolocation !== undefined) {
            callback(this._supportsGeolocation);

        } else if (index.window.navigator.permissions !== undefined) {
            // navigator.permissions has incomplete browser support http://caniuse.com/#feat=permissions-api
            // Test for the case where a browser disables Geolocation because of an insecure origin;
            // in some environments like iOS16 WebView, permissions reject queries but still support geolocation
            index.window.navigator.permissions.query({name: 'geolocation'})
                .then(p => updateSupport(p.state !== 'denied'))
                .catch(() => updateSupport());

        } else {
            updateSupport();
        }
    }

    /**
     * Check if the Geolocation API Position is outside the map's maxbounds.
     *
     * @param {Position} position the Geolocation API Position
     * @returns {boolean} Returns `true` if position is outside the map's maxbounds, otherwise returns `false`.
     * @private
     */
    _isOutOfMapMaxBounds(position          )          {
        const bounds = this._map.getMaxBounds();
        const coordinates = position.coords;

        return !!bounds && (
            coordinates.longitude < bounds.getWest() ||
            coordinates.longitude > bounds.getEast() ||
            coordinates.latitude < bounds.getSouth() ||
            coordinates.latitude > bounds.getNorth()
        );
    }

    _setErrorState() {
        switch (this._watchState) {
        case 'WAITING_ACTIVE':
            this._watchState = 'ACTIVE_ERROR';
            this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-active');
            this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-active-error');
            break;
        case 'ACTIVE_LOCK':
            this._watchState = 'ACTIVE_ERROR';
            this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-active');
            this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-active-error');
            this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-waiting');
            // turn marker grey
            break;
        case 'BACKGROUND':
            this._watchState = 'BACKGROUND_ERROR';
            this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-background');
            this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-background-error');
            this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-waiting');
            // turn marker grey
            break;
        case 'ACTIVE_ERROR':
            break;
        default:
            index.assert(false, `Unexpected watchState ${this._watchState}`);
        }
    }

    /**
     * When the Geolocation API returns a new location, update the GeolocateControl.
     *
     * @param {Position} position the Geolocation API Position
     * @private
     */
    _onSuccess(position          ) {
        if (!this._map) {
            // control has since been removed
            return;
        }

        if (this._isOutOfMapMaxBounds(position)) {
            this._setErrorState();

            this.fire(new index.Event('outofmaxbounds', position));
            this._updateMarker();
            this._finish();

            return;
        }

        if (this.options.trackUserLocation) {
            // keep a record of the position so that if the state is BACKGROUND and the user
            // clicks the button, we can move to ACTIVE_LOCK immediately without waiting for
            // watchPosition to trigger _onSuccess
            this._lastKnownPosition = position;

            switch (this._watchState) {
            case 'WAITING_ACTIVE':
            case 'ACTIVE_LOCK':
            case 'ACTIVE_ERROR':
                this._watchState = 'ACTIVE_LOCK';
                this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-waiting');
                this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-active-error');
                this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-active');
                break;
            case 'BACKGROUND':
            case 'BACKGROUND_ERROR':
                this._watchState = 'BACKGROUND';
                this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-waiting');
                this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-background-error');
                this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-background');
                break;
            default:
                index.assert(false, `Unexpected watchState ${this._watchState}`);
            }
        }

        // if showUserLocation and the watch state isn't off then update the marker location
        if (this.options.showUserLocation && this._watchState !== 'OFF') {
            this._updateMarker(position);
        }

        // if in normal mode (not watch mode), or if in watch mode and the state is active watch
        // then update the camera
        if (!this.options.trackUserLocation || this._watchState === 'ACTIVE_LOCK') {
            this._updateCamera(position);
        }

        if (this.options.showUserLocation) {
            this._dotElement.classList.remove('mapboxgl-user-location-dot-stale');
        }

        this.fire(new index.Event('geolocate', position));
        this._finish();
    }

    /**
     * Update the camera location to center on the current position
     *
     * @param {Position} position the Geolocation API Position
     * @private
     */
    _updateCamera(position          ) {
        const center = new index.LngLat(position.coords.longitude, position.coords.latitude);
        const radius = position.coords.accuracy;
        const bearing = this._map.getBearing();
        const options = index.extend({bearing}, this.options.fitBoundsOptions);

        this._map.fitBounds(center.toBounds(radius), options, {
            geolocateSource: true // tag this camera change so it won't cause the control to change to background state
        });
    }

    /**
     * Update the user location dot Marker to the current position
     *
     * @param {Position} [position] the Geolocation API Position
     * @private
     */
    _updateMarker(position           ) {
        if (position) {
            const center = new index.LngLat(position.coords.longitude, position.coords.latitude);
            this._accuracyCircleMarker.setLngLat(center).addTo(this._map);
            this._userLocationDotMarker.setLngLat(center).addTo(this._map);
            this._accuracy = position.coords.accuracy;
            if (this.options.showUserLocation && this.options.showAccuracyCircle) {
                this._updateCircleRadius();
            }
        } else {
            this._userLocationDotMarker.remove();
            this._accuracyCircleMarker.remove();
        }
    }

    _updateCircleRadius() {
        index.assert(this._circleElement);
        const map = this._map;
        const tr = map.transform;

        const pixelsPerMeter = index.mercatorZfromAltitude(1.0, tr._center.lat) * tr.worldSize;
        index.assert(pixelsPerMeter !== 0.0);
        const circleDiameter = Math.ceil(2.0 * this._accuracy * pixelsPerMeter);

        this._circleElement.style.width = `${circleDiameter}px`;
        this._circleElement.style.height = `${circleDiameter}px`;
    }

    _onZoom() {
        if (this.options.showUserLocation && this.options.showAccuracyCircle) {
            this._updateCircleRadius();
        }
    }

    /**
     * Update the user location dot Marker rotation to the current heading
     *
     * @private
     */
    _updateMarkerRotation() {
        if (this._userLocationDotMarker && typeof this._heading === 'number') {
            this._userLocationDotMarker.setRotation(this._heading);
            this._dotElement.classList.add('mapboxgl-user-location-show-heading');
        } else {
            this._dotElement.classList.remove('mapboxgl-user-location-show-heading');
            this._userLocationDotMarker.setRotation(0);
        }
    }

    _onError(error               ) {
        if (!this._map) {
            // control has since been removed
            return;
        }

        if (this.options.trackUserLocation) {
            if (error.code === 1) {
                // PERMISSION_DENIED
                this._watchState = 'OFF';
                this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-waiting');
                this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-active');
                this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-active-error');
                this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-background');
                this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-background-error');
                this._geolocateButton.disabled = true;
                const title = this._map._getUIString('GeolocateControl.LocationNotAvailable');
                this._geolocateButton.setAttribute('aria-label', title);
                if (this._geolocateButton.firstElementChild) this._geolocateButton.firstElementChild.setAttribute('title', title);

                if (this._geolocationWatchID !== undefined) {
                    this._clearWatch();
                }
            } else if (error.code === 3 && this._noTimeout) {
                // this represents a forced error state
                // this was triggered to force immediate geolocation when a watch is already present
                // see https://github.com/mapbox/mapbox-gl-js/issues/8214
                // and https://w3c.github.io/geolocation-api/#example-5-forcing-the-user-agent-to-return-a-fresh-cached-position
                return;
            } else {
                this._setErrorState();
            }
        }

        if (this._watchState !== 'OFF' && this.options.showUserLocation) {
            this._dotElement.classList.add('mapboxgl-user-location-dot-stale');
        }

        this.fire(new index.Event('error', error));

        this._finish();
    }

    _finish() {
        if (this._timeoutId) { clearTimeout(this._timeoutId); }
        this._timeoutId = undefined;
    }

    _setupUI(supported         ) {
        if (this._map === undefined) {
            // This control was removed from the map before geolocation
            // support was determined.
            return;
        }
        this._container.addEventListener('contextmenu', (e            ) => e.preventDefault());
        this._geolocateButton = create$1('button', `mapboxgl-ctrl-geolocate`, this._container);
        create$1('span', `mapboxgl-ctrl-icon`, this._geolocateButton).setAttribute('aria-hidden', 'true');

        this._geolocateButton.type = 'button';

        if (supported === false) {
            index.warnOnce('Geolocation support is not available so the GeolocateControl will be disabled.');
            const title = this._map._getUIString('GeolocateControl.LocationNotAvailable');
            this._geolocateButton.disabled = true;
            this._geolocateButton.setAttribute('aria-label', title);
            if (this._geolocateButton.firstElementChild) this._geolocateButton.firstElementChild.setAttribute('title', title);
        } else {
            const title = this._map._getUIString('GeolocateControl.FindMyLocation');
            this._geolocateButton.setAttribute('aria-label', title);
            if (this._geolocateButton.firstElementChild) this._geolocateButton.firstElementChild.setAttribute('title', title);
        }

        if (this.options.trackUserLocation) {
            this._geolocateButton.setAttribute('aria-pressed', 'false');
            this._watchState = 'OFF';
        }

        // when showUserLocation is enabled, keep the Geolocate button disabled until the device location marker is setup on the map
        if (this.options.showUserLocation) {
            this._dotElement = create$1('div', 'mapboxgl-user-location');
            this._dotElement.appendChild(create$1('div', 'mapboxgl-user-location-dot'));
            this._dotElement.appendChild(create$1('div', 'mapboxgl-user-location-heading'));

            this._userLocationDotMarker = new Marker({
                element: this._dotElement,
                rotationAlignment: 'map',
                pitchAlignment: 'map'
            });

            this._circleElement = create$1('div', 'mapboxgl-user-location-accuracy-circle');
            this._accuracyCircleMarker = new Marker({element: this._circleElement, pitchAlignment: 'map'});

            if (this.options.trackUserLocation) this._watchState = 'OFF';

            // $FlowFixMe[method-unbinding]
            this._map.on('zoom', this._onZoom);
        }

        // $FlowFixMe[method-unbinding]
        this._geolocateButton.addEventListener('click', this.trigger.bind(this));

        this._setup = true;

        // when the camera is changed (and it's not as a result of the Geolocation Control) change
        // the watch mode to background watch, so that the marker is updated but not the camera.
        if (this.options.trackUserLocation) {
            this._map.on('movestart', (event) => {
                const fromResize = event.originalEvent && event.originalEvent.type === 'resize';
                if (!event.geolocateSource && this._watchState === 'ACTIVE_LOCK' && !fromResize) {
                    this._watchState = 'BACKGROUND';
                    this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-background');
                    this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-active');

                    this.fire(new index.Event('trackuserlocationend'));
                }
            });
        }
    }

    /**
    * Programmatically request and move the map to the user's location.
    *
    * @returns {boolean} Returns `false` if called before control was added to a map, otherwise returns `true`.
    * Called on a deviceorientation event.
    *
    * @param deviceOrientationEvent {DeviceOrientationEvent}
    * @private
    * @example
    * // Initialize the GeolocateControl.
    * var geolocate = new mapboxgl.GeolocateControl({
    *  positionOptions: {
    *    enableHighAccuracy: true
    *  },
    *  trackUserLocation: true
    * });
    * // Add the control to the map.
    * map.addControl(geolocate);
    * map.on('load', function() {
    *   geolocate.trigger();
    * });
    */
    _onDeviceOrientation(deviceOrientationEvent                        ) {
        // absolute is true if the orientation data is provided as the difference between the Earth's coordinate frame and the device's coordinate frame, or false if the orientation data is being provided in reference to some arbitrary, device-determined coordinate frame.
        if (this._userLocationDotMarker) {
            if (deviceOrientationEvent.webkitCompassHeading) {
                // Safari
                this._heading = deviceOrientationEvent.webkitCompassHeading;
            } else if (deviceOrientationEvent.absolute === true) {
                // non-Safari alpha increases counter clockwise around the z axis
                this._heading = deviceOrientationEvent.alpha * -1;
            }
            this._updateMarkerRotationThrottled();
        }
    }

    /**
     * Trigger a geolocation event.
     *
     * @example
     * // Initialize the geolocate control.
     * const geolocate = new mapboxgl.GeolocateControl({
     *     positionOptions: {
     *         enableHighAccuracy: true
     *     },
     *     trackUserLocation: true
     * });
     * // Add the control to the map.
     * map.addControl(geolocate);
     * map.on('load', () => {
     *     geolocate.trigger();
     * });
     * @returns {boolean} Returns `false` if called before control was added to a map, otherwise returns `true`.
     */
    trigger()          {
        if (!this._setup) {
            index.warnOnce('Geolocate control triggered before added to a map');
            return false;
        }
        if (this.options.trackUserLocation) {
            // update watchState and do any outgoing state cleanup
            switch (this._watchState) {
            case 'OFF':
                // turn on the GeolocateControl
                this._watchState = 'WAITING_ACTIVE';

                this.fire(new index.Event('trackuserlocationstart'));
                break;
            case 'WAITING_ACTIVE':
            case 'ACTIVE_LOCK':
            case 'ACTIVE_ERROR':
            case 'BACKGROUND_ERROR':
                // turn off the Geolocate Control
                this._numberOfWatches--;
                this._noTimeout = false;
                this._watchState = 'OFF';
                this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-waiting');
                this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-active');
                this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-active-error');
                this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-background');
                this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-background-error');

                this.fire(new index.Event('trackuserlocationend'));
                break;
            case 'BACKGROUND':
                this._watchState = 'ACTIVE_LOCK';
                this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-background');
                // set camera to last known location
                if (this._lastKnownPosition) this._updateCamera(this._lastKnownPosition);

                this.fire(new index.Event('trackuserlocationstart'));
                break;
            default:
                index.assert(false, `Unexpected watchState ${this._watchState}`);
            }

            // incoming state setup
            switch (this._watchState) {
            case 'WAITING_ACTIVE':
                this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-waiting');
                this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-active');
                break;
            case 'ACTIVE_LOCK':
                this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-active');
                break;
            case 'ACTIVE_ERROR':
                this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-waiting');
                this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-active-error');
                break;
            case 'BACKGROUND':
                this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-background');
                break;
            case 'BACKGROUND_ERROR':
                this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-waiting');
                this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-background-error');
                break;
            case 'OFF':
                break;
            default:
                index.assert(false, `Unexpected watchState ${this._watchState}`);
            }

            // manage geolocation.watchPosition / geolocation.clearWatch
            if (this._watchState === 'OFF' && this._geolocationWatchID !== undefined) {
                // clear watchPosition as we've changed to an OFF state
                this._clearWatch();
            } else if (this._geolocationWatchID === undefined) {
                // enable watchPosition since watchState is not OFF and there is no watchPosition already running

                this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-waiting');
                this._geolocateButton.setAttribute('aria-pressed', 'true');

                this._numberOfWatches++;
                let positionOptions;
                if (this._numberOfWatches > 1) {
                    positionOptions = {maximumAge:600000, timeout:0};
                    this._noTimeout = true;
                } else {
                    positionOptions = this.options.positionOptions;
                    this._noTimeout = false;
                }

                this._geolocationWatchID = this.options.geolocation.watchPosition(
                    this._onSuccess, this._onError, positionOptions);

                if (this.options.showUserHeading) {
                    this._addDeviceOrientationListener();
                }
            }
        } else {
            // $FlowFixMe[method-unbinding]
            this.options.geolocation.getCurrentPosition(this._onSuccess, this._onError, this.options.positionOptions);

            // This timeout ensures that we still call finish() even if
            // the user declines to share their location in Firefox
            // $FlowFixMe[method-unbinding]
            this._timeoutId = setTimeout(this._finish, 10000 /* 10sec */);
        }

        return true;
    }

    _addDeviceOrientationListener() {
        const addListener = () => {
            if ('ondeviceorientationabsolute' in index.window) {
                // $FlowFixMe[method-unbinding]
                index.window.addEventListener('deviceorientationabsolute', this._onDeviceOrientation);
            } else {
                // $FlowFixMe[method-unbinding]
                index.window.addEventListener('deviceorientation', this._onDeviceOrientation);
            }
        };

        if (typeof index.window.DeviceMotionEvent !== "undefined" &&
            typeof index.window.DeviceMotionEvent.requestPermission === 'function') {
            // $FlowFixMe
            DeviceOrientationEvent.requestPermission()
                .then(response => {
                    if (response === 'granted') {
                        addListener();
                    }
                })
                .catch(console.error);
        } else {
            addListener();
        }
    }

    _clearWatch() {
        this.options.geolocation.clearWatch(this._geolocationWatchID);

        // $FlowFixMe[method-unbinding]
        index.window.removeEventListener('deviceorientation', this._onDeviceOrientation);
        // $FlowFixMe[method-unbinding]
        index.window.removeEventListener('deviceorientationabsolute', this._onDeviceOrientation);

        this._geolocationWatchID = (undefined     );
        this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-waiting');
        this._geolocateButton.setAttribute('aria-pressed', 'false');

        if (this.options.showUserLocation) {
            this._updateMarker(null);
        }
    }
}

/* GeolocateControl Watch States
 * This is the private state of the control.
 *
 * OFF
 *    off/inactive
 * WAITING_ACTIVE
 *    GeolocateControl was clicked but still waiting for Geolocation API response with user location
 * ACTIVE_LOCK
 *    Showing the user location as a dot AND tracking the camera to be fixed to their location. If their location changes the map moves to follow.
 * ACTIVE_ERROR
 *    There was en error from the Geolocation API while trying to show and track the user location.
 * BACKGROUND
 *    Showing the user location as a dot but the camera doesn't follow their location as it changes.
 * BACKGROUND_ERROR
 *    There was an error from the Geolocation API while trying to show (but not track) the user location.
 */

/**
 * Fired on each Geolocation API position update that returned as success.
 *
 * @event geolocate
 * @memberof GeolocateControl
 * @instance
 * @property {Position} data The returned [Position](https://developer.mozilla.org/en-US/docs/Web/API/Position) object from the callback in [Geolocation.getCurrentPosition()](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/getCurrentPosition) or [Geolocation.watchPosition()](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/watchPosition).
 * @example
 * // Initialize the GeolocateControl.
 * const geolocate = new mapboxgl.GeolocateControl({
 *     positionOptions: {
 *         enableHighAccuracy: true
 *     },
 *     trackUserLocation: true
 * });
 * // Add the control to the map.
 * map.addControl(geolocate);
 * // Set an event listener that fires
 * // when a geolocate event occurs.
 * geolocate.on('geolocate', () => {
 *     console.log('A geolocate event has occurred.');
 * });
 *
 */

/**
 * Fired on each Geolocation API position update that returned as an error.
 *
 * @event error
 * @memberof GeolocateControl
 * @instance
 * @property {PositionError} data The returned [PositionError](https://developer.mozilla.org/en-US/docs/Web/API/PositionError) object from the callback in [Geolocation.getCurrentPosition()](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/getCurrentPosition) or [Geolocation.watchPosition()](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/watchPosition).
 * @example
 * // Initialize the GeolocateControl.
 * const geolocate = new mapboxgl.GeolocateControl({
 *     positionOptions: {
 *         enableHighAccuracy: true
 *     },
 *     trackUserLocation: true
 * });
 * // Add the control to the map.
 * map.addControl(geolocate);
 * // Set an event listener that fires
 * // when an error event occurs.
 * geolocate.on('error', () => {
 *     console.log('An error event has occurred.');
 * });
 *
 */

/**
 * Fired on each Geolocation API position update that returned as success but user position is out of map `maxBounds`.
 *
 * @event outofmaxbounds
 * @memberof GeolocateControl
 * @instance
 * @property {Position} data The returned [Position](https://developer.mozilla.org/en-US/docs/Web/API/Position) object from the callback in [Geolocation.getCurrentPosition()](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/getCurrentPosition) or [Geolocation.watchPosition()](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/watchPosition).
 * @example
 * // Initialize the GeolocateControl.
 * const geolocate = new mapboxgl.GeolocateControl({
 *     positionOptions: {
 *         enableHighAccuracy: true
 *     },
 *     trackUserLocation: true
 * });
 * // Add the control to the map.
 * map.addControl(geolocate);
 * // Set an event listener that fires
 * // when an outofmaxbounds event occurs.
 * geolocate.on('outofmaxbounds', () => {
 *     console.log('An outofmaxbounds event has occurred.');
 * });
 *
 */

/**
 * Fired when the GeolocateControl changes to the active lock state, which happens either upon first obtaining a successful Geolocation API position for the user (a geolocate event will follow), or when the user clicks the geolocate button when in the background state, which uses the last known position to recenter the map and enter active lock state (no geolocate event will follow unless the users's location changes).
 *
 * @event trackuserlocationstart
 * @memberof GeolocateControl
 * @instance
 * @example
 * // Initialize the GeolocateControl.
 * const geolocate = new mapboxgl.GeolocateControl({
 *     positionOptions: {
 *         enableHighAccuracy: true
 *     },
 *     trackUserLocation: true
 * });
 * // Add the control to the map.
 * map.addControl(geolocate);
 * // Set an event listener that fires
 * // when a trackuserlocationstart event occurs.
 * geolocate.on('trackuserlocationstart', () => {
 *     console.log('A trackuserlocationstart event has occurred.');
 * });
 *
 */

/**
 * Fired when the GeolocateControl changes to the background state, which happens when a user changes the camera during an active position lock. This only applies when trackUserLocation is true. In the background state, the dot on the map will update with location updates but the camera will not.
 *
 * @event trackuserlocationend
 * @memberof GeolocateControl
 * @instance
 * @example
 * // Initialize the GeolocateControl.
 * const geolocate = new mapboxgl.GeolocateControl({
 *     positionOptions: {
 *         enableHighAccuracy: true
 *     },
 *     trackUserLocation: true
 * });
 * // Add the control to the map.
 * map.addControl(geolocate);
 * // Set an event listener that fires
 * // when a trackuserlocationend event occurs.
 * geolocate.on('trackuserlocationend', () => {
 *     console.log('A trackuserlocationend event has occurred.');
 * });
 *
 */

//      


                                                    

                                               

                
                      
                
  

const defaultOptions          = {
    maxWidth: 100,
    unit: 'metric'
};

const unitAbbr = {
    kilometer: 'km',
    meter: 'm',
    mile: 'mi',
    foot: 'ft',
    'nautical-mile': 'nm',
};

/**
 * A `ScaleControl` control displays the ratio of a distance on the map to the corresponding distance on the ground.
 * Add this control to a map using {@link Map#addControl}.
 *
 * @implements {IControl}
 * @param {Object} [options]
 * @param {number} [options.maxWidth='100'] The maximum length of the scale control in pixels.
 * @param {string} [options.unit='metric'] Unit of the distance (`'imperial'`, `'metric'` or `'nautical'`).
 * @example
 * const scale = new mapboxgl.ScaleControl({
 *     maxWidth: 80,
 *     unit: 'imperial'
 * });
 * map.addControl(scale);
 *
 * scale.setUnit('metric');
 */
class ScaleControl {
              
                            
                                   
                                      
                     

    constructor(options         ) {
        this.options = index.extend({}, defaultOptions, options);

        // Some old browsers (e.g., Safari < 14.1) don't support the "unit" style in NumberFormat.
        // This is a workaround to display the scale without proper internationalization support.
        this._isNumberFormatSupported = isNumberFormatSupported();

        index.bindAll([
            '_update',
            '_setScale',
            'setUnit'
        ], this);
    }

    getDefaultPosition()                  {
        return 'bottom-left';
    }

    _update() {
        // A horizontal scale is imagined to be present at center of the map
        // container with maximum length (Default) as 100px.
        // Using spherical law of cosines approximation, the real distance is
        // found between the two coordinates.
        const maxWidth = this.options.maxWidth || 100;

        const map = this._map;
        const y = map._containerHeight / 2;
        const x = (map._containerWidth / 2) - maxWidth / 2;
        const left = map.unproject([x, y]);
        const right = map.unproject([x + maxWidth, y]);
        const maxMeters = left.distanceTo(right);
        // The real distance corresponding to 100px scale length is rounded off to
        // near pretty number and the scale length for the same is found out.
        // Default unit of the scale is based on User's locale.
        if (this.options.unit === 'imperial') {
            const maxFeet = 3.2808 * maxMeters;
            if (maxFeet > 5280) {
                const maxMiles = maxFeet / 5280;
                this._setScale(maxWidth, maxMiles, 'mile');
            } else {
                this._setScale(maxWidth, maxFeet, 'foot');
            }
        } else if (this.options.unit === 'nautical') {
            const maxNauticals = maxMeters / 1852;
            this._setScale(maxWidth, maxNauticals, 'nautical-mile');
        } else if (maxMeters >= 1000) {
            this._setScale(maxWidth, maxMeters / 1000, 'kilometer');
        } else {
            this._setScale(maxWidth, maxMeters, 'meter');
        }
    }

    _setScale(maxWidth        , maxDistance        , unit        ) {
        this._map._requestDomTask(() => {
            const distance = getRoundNum(maxDistance);
            const ratio = distance / maxDistance;

            if (this._isNumberFormatSupported && unit !== 'nautical-mile') {
                // $FlowFixMe[incompatible-call] — flow v0.190.1 doesn't support optional `locales` argument and `unit` style option
                this._container.innerHTML = new Intl.NumberFormat(this._language, {style: 'unit', unitDisplay: 'short', unit}).format(distance);
            } else {
                this._container.innerHTML = `${distance}&nbsp;${unitAbbr[unit]}`;
            }

            this._container.style.width = `${maxWidth * ratio}px`;
        });
    }

    onAdd(map     )              {
        this._map = map;
        this._language = map.getLanguage();
        this._container = create$1('div', 'mapboxgl-ctrl mapboxgl-ctrl-scale', map.getContainer());
        this._container.dir = 'auto';

        // $FlowFixMe[method-unbinding]
        this._map.on('move', this._update);
        this._update();

        return this._container;
    }

    onRemove() {
        this._container.remove();
        // $FlowFixMe[method-unbinding]
        this._map.off('move', this._update);
        this._map = (undefined     );
    }

    _setLanguage(language        ) {
        this._language = language;
        this._update();
    }

    /**
     * Set the scale's unit of the distance.
     *
     * @param {'imperial' | 'metric' | 'nautical'} unit Unit of the distance (`'imperial'`, `'metric'` or `'nautical'`).
     */
    setUnit(unit      ) {
        this.options.unit = unit;
        this._update();
    }
}

function isNumberFormatSupported() {
    try {
        // $FlowIgnore
        new Intl.NumberFormat('en', {style: 'unit', unitDisplay: 'short', unit: 'meter'});
        return true;
    } catch (_) {
        return false;
    }
}

function getDecimalRoundNum(d        ) {
    const multiplier = Math.pow(10, Math.ceil(-Math.log(d) / Math.LN10));
    return Math.round(d * multiplier) / multiplier;
}

function getRoundNum(num        ) {
    const pow10 = Math.pow(10, (`${Math.floor(num)}`).length - 1);
    let d = num / pow10;

    d = d >= 10 ? 10 :
        d >= 5 ? 5 :
        d >= 3 ? 3 :
        d >= 2 ? 2 :
        d >= 1 ? 1 : getDecimalRoundNum(d);

    return pow10 * d;
}

//      


                                 

                
                           
  

/**
 * A `FullscreenControl` control contains a button for toggling the map in and out of fullscreen mode. See the `requestFullScreen` [compatibility table](https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullScreen#browser_compatibility) for supported browsers.
 * Add this control to a map using {@link Map#addControl}.
 *
 * @implements {IControl}
 * @param {Object} [options]
 * @param {HTMLElement} [options.container] `container` is the [compatible DOM element](https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullScreen#Compatible_elements) which should be made full screen. By default, the map container element will be made full screen.
 *
 * @example
 * map.addControl(new mapboxgl.FullscreenControl({container: document.querySelector('body')}));
 * @see [Example: View a fullscreen map](https://www.mapbox.com/mapbox-gl-js/example/fullscreen/)
 */

class FullscreenControl {
              
                                   
                         
                              
                                   
                            

    constructor(options         ) {
        this._fullscreen = false;
        if (options && options.container) {
            if (options.container instanceof index.window.HTMLElement) {
                this._container = options.container;
            } else {
                index.warnOnce('Full screen control \'container\' must be a DOM element.');
            }
        }
        index.bindAll([
            '_onClickFullscreen',
            '_changeIcon'
        ], this);
        if ('onfullscreenchange' in index.window.document) {
            this._fullscreenchange = 'fullscreenchange';
        } else if ('onwebkitfullscreenchange' in index.window.document) {
            this._fullscreenchange = 'webkitfullscreenchange';
        }
    }

    onAdd(map     )              {
        this._map = map;
        if (!this._container) this._container = this._map.getContainer();
        this._controlContainer = create$1('div', `mapboxgl-ctrl mapboxgl-ctrl-group`);
        if (this._checkFullscreenSupport()) {
            this._setupUI();
        } else {
            this._controlContainer.style.display = 'none';
            index.warnOnce('This device does not support fullscreen mode.');
        }
        return this._controlContainer;
    }

    onRemove() {
        this._controlContainer.remove();
        this._map = (null     );
        // $FlowFixMe[method-unbinding]
        index.window.document.removeEventListener(this._fullscreenchange, this._changeIcon);
    }

    _checkFullscreenSupport()          {
        return !!(
            index.window.document.fullscreenEnabled ||
            (index.window.document     ).webkitFullscreenEnabled
        );
    }

    _setupUI() {
        const button = this._fullscreenButton = create$1('button', (`mapboxgl-ctrl-fullscreen`), this._controlContainer);
        create$1('span', `mapboxgl-ctrl-icon`, button).setAttribute('aria-hidden', 'true');
        button.type = 'button';
        this._updateTitle();
        // $FlowFixMe[method-unbinding]
        this._fullscreenButton.addEventListener('click', this._onClickFullscreen);
        // $FlowFixMe[method-unbinding]
        index.window.document.addEventListener(this._fullscreenchange, this._changeIcon);
    }

    _updateTitle() {
        const title = this._getTitle();
        this._fullscreenButton.setAttribute("aria-label", title);
        if (this._fullscreenButton.firstElementChild) this._fullscreenButton.firstElementChild.setAttribute('title', title);
    }

    _getTitle()         {
        return this._map._getUIString(this._isFullscreen() ? 'FullscreenControl.Exit' : 'FullscreenControl.Enter');
    }

    _isFullscreen()          {
        return this._fullscreen;
    }

    _changeIcon() {
        const fullscreenElement =
            index.window.document.fullscreenElement ||
            (index.window.document     ).webkitFullscreenElement;

        if ((fullscreenElement === this._container) !== this._fullscreen) {
            this._fullscreen = !this._fullscreen;
            this._fullscreenButton.classList.toggle(`mapboxgl-ctrl-shrink`);
            this._fullscreenButton.classList.toggle(`mapboxgl-ctrl-fullscreen`);
            this._updateTitle();
        }
    }

    _onClickFullscreen() {
        if (this._isFullscreen()) {
            if (index.window.document.exitFullscreen) {
                (index.window.document     ).exitFullscreen();
            } else if (index.window.document.webkitCancelFullScreen) {
                (index.window.document     ).webkitCancelFullScreen();
            }
        // $FlowFixMe[method-unbinding]
        } else if (this._container.requestFullscreen) {
            this._container.requestFullscreen();
        } else if ((this._container     ).webkitRequestFullscreen) {
            (this._container     ).webkitRequestFullscreen();
        }
    }
}

//      


const performance$1 = index.window.performance;

// separate from PerformanceUtils to avoid circular dependency

const WorkerPerformanceUtils = {

    getPerformanceMetricsAsync(callback                                          ) {
        const metrics = index.PerformanceUtils.getPerformanceMetrics();
        const dispatcher = new Dispatcher(getGlobalWorkerPool(), WorkerPerformanceUtils);

        const createTime = performance$1.getEntriesByName('create', 'mark')[0].startTime;

        dispatcher.broadcast('getWorkerPerformanceMetrics', {}, (err, results) => {
            dispatcher.remove();
            if (err) return callback(err);

            const sums = {};

            for (const result of results) {
                for (const measure of result.entries) {
                    if (measure.entryType !== 'measure') continue;
                    sums[measure.name] = (sums[measure.name] || 0) + measure.duration;
                }

                sums.workerInitialization = result.timeOrigin - performance$1.timeOrigin - createTime;
            }

            for (const name in sums) {
                metrics[name] = sums[name] / results.length;
            }

            metrics.workerIdle = metrics.loadTime - metrics.workerInitialization - metrics.workerEvaluateScript - metrics.workerTask;
            metrics.workerIdlePercent = metrics.workerIdle / metrics.loadTime;

            metrics.parseTile = metrics.parseTile1 + metrics.parseTile2;

            metrics.timelines = [index.PerformanceUtils.getWorkerPerformanceMetrics(), ...results];

            return callback(undefined, metrics);
        });
    }
};

//      


const exported = {
    version: index.version,
    supported,
    setRTLTextPlugin: index.setRTLTextPlugin,
    getRTLTextPluginStatus: index.getRTLTextPluginStatus,
    Map,
    NavigationControl,
    GeolocateControl,
    AttributionControl,
    ScaleControl,
    FullscreenControl,
    Popup,
    Marker,
    Style,
    LngLat: index.LngLat,
    LngLatBounds: index.LngLatBounds,
    Point: index.Point,
    MercatorCoordinate: index.MercatorCoordinate,
    FreeCameraOptions,
    Evented: index.Evented,
    config: index.config,
    /**
     * Initializes resources like WebWorkers that can be shared across maps to lower load
     * times in some situations. [`mapboxgl.workerUrl`](https://docs.mapbox.com/mapbox-gl-js/api/properties/#workerurl)
     * and [`mapboxgl.workerCount`](https://docs.mapbox.com/mapbox-gl-js/api/properties/#workercount), if being
     * used, must be set before `prewarm()` is called to have an effect.
     *
     * By default, the lifecycle of these resources is managed automatically, and they are
     * lazily initialized when a `Map` is first created. Invoking `prewarm()` creates these
     * resources ahead of time and ensures they are not cleared when the last `Map`
     * is removed from the page. This allows them to be re-used by new `Map` instances that
     * are created later. They can be manually cleared by calling
     * [`mapboxgl.clearPrewarmedResources()`](https://docs.mapbox.com/mapbox-gl-js/api/properties/#clearprewarmedresources).
     * This is only necessary if your web page remains active but stops using maps altogether.
     * `prewarm()` is idempotent and has guards against being executed multiple times,
     * and any resources allocated by `prewarm()` are created synchronously.
     *
     * This is primarily useful when using Mapbox GL JS maps in a single page app,
     * in which a user navigates between various views, resulting in
     * constant creation and destruction of `Map` instances.
     *
     * @function prewarm
     * @example
     * mapboxgl.prewarm();
     */
    prewarm,
    /**
     * Clears up resources that have previously been created by [`mapboxgl.prewarm()](https://docs.mapbox.com/mapbox-gl-js/api/properties/#prewarm)`.
     * Note that this is typically not necessary. You should only call this function
     * if you expect the user of your app to not return to a Map view at any point
     * in your application.
     *
     * @function clearPrewarmedResources
     * @example
     * mapboxgl.clearPrewarmedResources();
     */
    clearPrewarmedResources,

    /**
     * Gets and sets the map's [access token](https://www.mapbox.com/help/define-access-token/).
     *
     * @var {string} accessToken
     * @returns {string} The currently set access token.
     * @example
     * mapboxgl.accessToken = myAccessToken;
     * @see [Example: Display a map](https://www.mapbox.com/mapbox-gl-js/example/simple-map/)
     */
    get accessToken()          {
        return index.config.ACCESS_TOKEN;
    },

    set accessToken(token        ) {
        index.config.ACCESS_TOKEN = token;
    },

    /**
     * Gets and sets the map's default API URL for requesting tiles, styles, sprites, and glyphs.
     *
     * @var {string} baseApiUrl
     * @returns {string} The current base API URL.
     * @example
     * mapboxgl.baseApiUrl = 'https://api.mapbox.com';
     */
    get baseApiUrl()          {
        return index.config.API_URL;
    },

    set baseApiUrl(url        ) {
        index.config.API_URL = url;
    },

    /**
     * Gets and sets the number of web workers instantiated on a page with Mapbox GL JS maps.
     * By default, it is set to 2.
     * Make sure to set this property before creating any map instances for it to have effect.
     *
     * @var {string} workerCount
     * @returns {number} Number of workers currently configured.
     * @example
     * mapboxgl.workerCount = 4;
     */
    get workerCount()         {
        return WorkerPool.workerCount;
    },

    set workerCount(count        ) {
        WorkerPool.workerCount = count;
    },

    /**
     * Gets and sets the maximum number of images (raster tiles, sprites, icons) to load in parallel.
     * 16 by default. There is no maximum value, but the number of images affects performance in raster-heavy maps.
     *
     * @var {string} maxParallelImageRequests
     * @returns {number} Number of parallel requests currently configured.
     * @example
     * mapboxgl.maxParallelImageRequests = 10;
     */
    get maxParallelImageRequests()         {
        return index.config.MAX_PARALLEL_IMAGE_REQUESTS;
    },

    set maxParallelImageRequests(numRequests        ) {
        index.config.MAX_PARALLEL_IMAGE_REQUESTS = numRequests;
    },

    /**
     * Clears browser storage used by this library. Using this method flushes the Mapbox tile
     * cache that is managed by this library. Tiles may still be cached by the browser
     * in some cases.
     *
     * This API is supported on browsers where the [`Cache` API](https://developer.mozilla.org/en-US/docs/Web/API/Cache)
     * is supported and enabled. This includes all major browsers when pages are served over
     * `https://`, except Internet Explorer and Edge Mobile.
     *
     * When called in unsupported browsers or environments (private or incognito mode), the
     * callback will be called with an error argument.
     *
     * @function clearStorage
     * @param {Function} callback Called with an error argument if there is an error.
     * @example
     * mapboxgl.clearStorage();
     */
    clearStorage(callback                        ) {
        index.clearTileCache(callback);
    },
    /**
     * Provides an interface for loading mapbox-gl's WebWorker bundle from a self-hosted URL.
     * This needs to be set only once, and before any call to `new mapboxgl.Map(..)` takes place.
     * This is useful if your site needs to operate in a strict CSP (Content Security Policy) environment
     * wherein you are not allowed to load JavaScript code from a [`Blob` URL](https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL), which is default behavior.
     *
     * See our documentation on [CSP Directives](https://docs.mapbox.com/mapbox-gl-js/api/#csp-directives) for more details.
     *
     * @var {string} workerUrl
     * @returns {string} A URL hosting a JavaScript bundle for mapbox-gl's WebWorker.
     * @example
     * <script src='https://api.mapbox.com/mapbox-gl-js/v2.3.1/mapbox-gl-csp.js'></script>
     * <script>
     * mapboxgl.workerUrl = "https://api.mapbox.com/mapbox-gl-js/v2.3.1/mapbox-gl-csp-worker.js";
     * ...
     * </script>
     */
    workerUrl: '',

    /**
     * Provides an interface for external module bundlers such as Webpack or Rollup to package
     * mapbox-gl's WebWorker into a separate class and integrate it with the library.
     *
     * Takes precedence over `mapboxgl.workerUrl`.
     *
     * @var {Object} workerClass
     * @returns {Object | null} A class that implements the `Worker` interface.
     * @example
     * import mapboxgl from 'mapbox-gl/dist/mapbox-gl-csp.js';
     * import MapboxGLWorker from 'mapbox-gl/dist/mapbox-gl-csp-worker.js';
     *
     * mapboxgl.workerClass = MapboxGLWorker;
     */
    workerClass: null,

    /**
     * Sets the time used by Mapbox GL JS internally for all animations. Useful for generating videos from Mapbox GL JS.
     *
     * @var {number} time
     */
    setNow: index.exported.setNow,

    /**
     * Restores the internal animation timing to follow regular computer time (`performance.now()`).
     */
    restoreNow: index.exported.restoreNow
};

//This gets automatically stripped out in production builds.
index.Debug.extend(exported, {isSafari: index.isSafari, getPerformanceMetrics: index.PerformanceUtils.getPerformanceMetrics, getPerformanceMetricsAsync: WorkerPerformanceUtils.getPerformanceMetricsAsync});

/**
 * Gets the version of Mapbox GL JS in use as specified in `package.json`,
 * `CHANGELOG.md`, and the GitHub release.
 *
 * @var {string} version
 * @example
 * console.log(`Mapbox GL JS v${mapboxgl.version}`);
 */

/**
 * Test whether the browser [supports Mapbox GL JS](https://www.mapbox.com/help/mapbox-browser-support/#mapbox-gl-js).
 *
 * @function supported
 * @param {Object} [options]
 * @param {boolean} [options.failIfMajorPerformanceCaveat=false] If `true`,
 *   the function will return `false` if the performance of Mapbox GL JS would
 *   be dramatically worse than expected (for example, a software WebGL renderer
 *   would be used).
 * @return {boolean}
 * @example
 * // Show an alert if the browser does not support Mapbox GL
 * if (!mapboxgl.supported()) {
 *     alert('Your browser does not support Mapbox GL');
 * }
 * @see [Example: Check for browser support](https://www.mapbox.com/mapbox-gl-js/example/check-for-support/)
 */

/**
 * Sets the map's [RTL text plugin](https://www.mapbox.com/mapbox-gl-js/plugins/#mapbox-gl-rtl-text).
 * Necessary for supporting the Arabic and Hebrew languages, which are written right-to-left. Mapbox Studio loads this plugin by default.
 *
 * @function setRTLTextPlugin
 * @param {string} pluginURL URL pointing to the Mapbox RTL text plugin source.
 * @param {Function} callback Called with an error argument if there is an error, or no arguments if the plugin loads successfully.
 * @param {boolean} lazy If set to `true`, MapboxGL will defer loading the plugin until right-to-left text is encountered, and
 *    right-to-left text will be rendered only after the plugin finishes loading.
 * @example
 * mapboxgl.setRTLTextPlugin('https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-rtl-text/v0.2.0/mapbox-gl-rtl-text.js');
 * @see [Example: Add support for right-to-left scripts](https://www.mapbox.com/mapbox-gl-js/example/mapbox-gl-rtl-text/)
 */

/**
  * Gets the map's [RTL text plugin](https://www.mapbox.com/mapbox-gl-js/plugins/#mapbox-gl-rtl-text) status.
  * The status can be `unavailable` (not requested or removed), `loading`, `loaded`, or `error`.
  * If the status is `loaded` and the plugin is requested again, an error will be thrown.
  *
  * @function getRTLTextPluginStatus
  * @example
  * const pluginStatus = mapboxgl.getRTLTextPluginStatus();
  */

var mapboxgl = exported;

// canary assert: used to confirm that asserts have been removed from production build
index.assert(true, 'canary assert');

return mapboxgl;

}));

//
// Our custom intro provides a specialized "define()" function, called by the
// AMD modules below, that sets up the worker blob URL and then executes the
// main module, storing its exported value as 'mapboxgl'


var mapboxgl$1 = mapboxgl;

return mapboxgl$1;

}));
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFwYm94LWdsLWRldi5qcyIsInNvdXJjZXMiOlsiLi4vc3JjL3V0aWwvYnJvd3Nlci93aW5kb3cuanMiLCIuLi9zcmMvdXRpbC9jb25maWcuanMiLCIuLi9zcmMvdXRpbC93ZWJwX3N1cHBvcnRlZC5qcyIsIi4uL3NyYy91dGlsL3NrdV90b2tlbi5qcyIsIi4uL25vZGVfbW9kdWxlcy9AbWFwYm94L3VuaXRiZXppZXIvaW5kZXguanMiLCIuLi9ub2RlX21vZHVsZXMvQG1hcGJveC9wb2ludC1nZW9tZXRyeS9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy9vYmplY3QtYXNzaWduL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL2Fzc2VydC9ub2RlX21vZHVsZXMvdXRpbC9zdXBwb3J0L2lzQnVmZmVyQnJvd3Nlci5qcyIsIi4uL25vZGVfbW9kdWxlcy9hc3NlcnQvbm9kZV9tb2R1bGVzL2luaGVyaXRzL2luaGVyaXRzX2Jyb3dzZXIuanMiLCIuLi9ub2RlX21vZHVsZXMvYXNzZXJ0L25vZGVfbW9kdWxlcy91dGlsL3V0aWwuanMiLCIuLi9ub2RlX21vZHVsZXMvYXNzZXJ0L2Fzc2VydC5qcyIsIi4uL3NyYy9zdHlsZS1zcGVjL3V0aWwvZGVlcF9lcXVhbC5qcyIsIi4uL3NyYy91dGlsL3V0aWwuanMiLCIuLi9zcmMvdXRpbC90aWxlX3JlcXVlc3RfY2FjaGUuanMiLCIuLi9zcmMvdXRpbC9hamF4LmpzIiwiLi4vc3JjL3V0aWwvbWFwYm94LmpzIiwiLi4vc3JjL3V0aWwvbGl2ZV9wZXJmb3JtYW5jZS5qcyIsIi4uL3NyYy91dGlsL3BlcmZvcm1hbmNlLmpzIiwiLi4vc3JjL3V0aWwvYnJvd3Nlci5qcyIsIi4uL3NyYy91dGlsL2V2ZW50ZWQuanMiLCIuLi9zcmMvc3R5bGUtc3BlYy9yZWZlcmVuY2UvbGF0ZXN0LmpzIiwiLi4vc3JjL3N0eWxlLXNwZWMvdXRpbC9leHRlbmQuanMiLCIuLi9zcmMvc3R5bGUtc3BlYy91dGlsL3VuYnVuZGxlX2pzb25saW50LmpzIiwiLi4vc3JjL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi9wYXJzaW5nX2Vycm9yLmpzIiwiLi4vc3JjL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi9zY29wZS5qcyIsIi4uL3NyYy9zdHlsZS1zcGVjL2V4cHJlc3Npb24vdHlwZXMuanMiLCIuLi9ub2RlX21vZHVsZXMvY3NzY29sb3JwYXJzZXIvY3NzY29sb3JwYXJzZXIuanMiLCIuLi9zcmMvc3R5bGUtc3BlYy91dGlsL2NvbG9yLmpzIiwiLi4vc3JjL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi90eXBlcy9jb2xsYXRvci5qcyIsIi4uL3NyYy9zdHlsZS1zcGVjL2V4cHJlc3Npb24vdHlwZXMvZm9ybWF0dGVkLmpzIiwiLi4vc3JjL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi90eXBlcy9yZXNvbHZlZF9pbWFnZS5qcyIsIi4uL3NyYy9zdHlsZS1zcGVjL2V4cHJlc3Npb24vdmFsdWVzLmpzIiwiLi4vc3JjL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi9kZWZpbml0aW9ucy9saXRlcmFsLmpzIiwiLi4vc3JjL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi9ydW50aW1lX2Vycm9yLmpzIiwiLi4vc3JjL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi9kZWZpbml0aW9ucy9hc3NlcnRpb24uanMiLCIuLi9zcmMvc3R5bGUtc3BlYy9leHByZXNzaW9uL2RlZmluaXRpb25zL2Zvcm1hdC5qcyIsIi4uL3NyYy9zdHlsZS1zcGVjL2V4cHJlc3Npb24vZGVmaW5pdGlvbnMvaW1hZ2UuanMiLCIuLi9zcmMvc3R5bGUtc3BlYy9leHByZXNzaW9uL2RlZmluaXRpb25zL2NvZXJjaW9uLmpzIiwiLi4vc3JjL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi9ldmFsdWF0aW9uX2NvbnRleHQuanMiLCIuLi9zcmMvc3R5bGUtc3BlYy9leHByZXNzaW9uL2NvbXBvdW5kX2V4cHJlc3Npb24uanMiLCIuLi9zcmMvc3R5bGUtc3BlYy9leHByZXNzaW9uL2RlZmluaXRpb25zL2NvbGxhdG9yLmpzIiwiLi4vc3JjL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi9kZWZpbml0aW9ucy93aXRoaW4uanMiLCIuLi9zcmMvc3R5bGUtc3BlYy9leHByZXNzaW9uL2lzX2NvbnN0YW50LmpzIiwiLi4vc3JjL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi9kZWZpbml0aW9ucy92YXIuanMiLCIuLi9zcmMvc3R5bGUtc3BlYy9leHByZXNzaW9uL3BhcnNpbmdfY29udGV4dC5qcyIsIi4uL3NyYy9zdHlsZS1zcGVjL2V4cHJlc3Npb24vc3RvcHMuanMiLCIuLi9zcmMvc3R5bGUtc3BlYy9leHByZXNzaW9uL2RlZmluaXRpb25zL3N0ZXAuanMiLCIuLi9zcmMvc3R5bGUtc3BlYy91dGlsL2ludGVycG9sYXRlLmpzIiwiLi4vc3JjL3N0eWxlLXNwZWMvdXRpbC9jb2xvcl9zcGFjZXMuanMiLCIuLi9zcmMvc3R5bGUtc3BlYy9leHByZXNzaW9uL2RlZmluaXRpb25zL2ludGVycG9sYXRlLmpzIiwiLi4vc3JjL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi9kZWZpbml0aW9ucy9jb2FsZXNjZS5qcyIsIi4uL3NyYy9zdHlsZS1zcGVjL2V4cHJlc3Npb24vZGVmaW5pdGlvbnMvbGV0LmpzIiwiLi4vc3JjL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi9kZWZpbml0aW9ucy9hdC5qcyIsIi4uL3NyYy9zdHlsZS1zcGVjL2V4cHJlc3Npb24vZGVmaW5pdGlvbnMvaW4uanMiLCIuLi9zcmMvc3R5bGUtc3BlYy9leHByZXNzaW9uL2RlZmluaXRpb25zL2luZGV4X29mLmpzIiwiLi4vc3JjL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi9kZWZpbml0aW9ucy9tYXRjaC5qcyIsIi4uL3NyYy9zdHlsZS1zcGVjL2V4cHJlc3Npb24vZGVmaW5pdGlvbnMvY2FzZS5qcyIsIi4uL3NyYy9zdHlsZS1zcGVjL2V4cHJlc3Npb24vZGVmaW5pdGlvbnMvc2xpY2UuanMiLCIuLi9zcmMvc3R5bGUtc3BlYy9leHByZXNzaW9uL2RlZmluaXRpb25zL2NvbXBhcmlzb24uanMiLCIuLi9zcmMvc3R5bGUtc3BlYy9leHByZXNzaW9uL2RlZmluaXRpb25zL251bWJlcl9mb3JtYXQuanMiLCIuLi9zcmMvc3R5bGUtc3BlYy9leHByZXNzaW9uL2RlZmluaXRpb25zL2xlbmd0aC5qcyIsIi4uL3NyYy9zdHlsZS1zcGVjL2V4cHJlc3Npb24vZGVmaW5pdGlvbnMvaW5kZXguanMiLCIuLi9zcmMvc3R5bGUtc3BlYy91dGlsL3Jlc3VsdC5qcyIsIi4uL3NyYy9zdHlsZS1zcGVjL3V0aWwvcHJvcGVydGllcy5qcyIsIi4uL3NyYy9zdHlsZS1zcGVjL3V0aWwvZ2V0X3R5cGUuanMiLCIuLi9zcmMvc3R5bGUtc3BlYy9mdW5jdGlvbi9pbmRleC5qcyIsIi4uL3NyYy9zdHlsZS1zcGVjL2V4cHJlc3Npb24vaW5kZXguanMiLCIuLi9zcmMvc3R5bGUtc3BlYy9lcnJvci92YWxpZGF0aW9uX2Vycm9yLmpzIiwiLi4vc3JjL3N0eWxlLXNwZWMvdmFsaWRhdGUvdmFsaWRhdGVfb2JqZWN0LmpzIiwiLi4vc3JjL3N0eWxlLXNwZWMvdmFsaWRhdGUvdmFsaWRhdGVfYXJyYXkuanMiLCIuLi9zcmMvc3R5bGUtc3BlYy92YWxpZGF0ZS92YWxpZGF0ZV9udW1iZXIuanMiLCIuLi9zcmMvc3R5bGUtc3BlYy92YWxpZGF0ZS92YWxpZGF0ZV9mdW5jdGlvbi5qcyIsIi4uL3NyYy9zdHlsZS1zcGVjL3ZhbGlkYXRlL3ZhbGlkYXRlX2V4cHJlc3Npb24uanMiLCIuLi9zcmMvc3R5bGUtc3BlYy92YWxpZGF0ZS92YWxpZGF0ZV9ib29sZWFuLmpzIiwiLi4vc3JjL3N0eWxlLXNwZWMvdmFsaWRhdGUvdmFsaWRhdGVfY29sb3IuanMiLCIuLi9zcmMvc3R5bGUtc3BlYy92YWxpZGF0ZS92YWxpZGF0ZV9lbnVtLmpzIiwiLi4vc3JjL3N0eWxlLXNwZWMvZmVhdHVyZV9maWx0ZXIvaW5kZXguanMiLCIuLi9zcmMvc3R5bGUtc3BlYy92YWxpZGF0ZS92YWxpZGF0ZV9maWx0ZXIuanMiLCIuLi9zcmMvc3R5bGUtc3BlYy92YWxpZGF0ZS92YWxpZGF0ZV9wcm9wZXJ0eS5qcyIsIi4uL3NyYy9zdHlsZS1zcGVjL3ZhbGlkYXRlL3ZhbGlkYXRlX3BhaW50X3Byb3BlcnR5LmpzIiwiLi4vc3JjL3N0eWxlLXNwZWMvdmFsaWRhdGUvdmFsaWRhdGVfbGF5b3V0X3Byb3BlcnR5LmpzIiwiLi4vc3JjL3N0eWxlLXNwZWMvdmFsaWRhdGUvdmFsaWRhdGVfbGF5ZXIuanMiLCIuLi9zcmMvc3R5bGUtc3BlYy92YWxpZGF0ZS92YWxpZGF0ZV9zdHJpbmcuanMiLCIuLi9zcmMvc3R5bGUtc3BlYy92YWxpZGF0ZS92YWxpZGF0ZV9zb3VyY2UuanMiLCIuLi9zcmMvc3R5bGUtc3BlYy92YWxpZGF0ZS92YWxpZGF0ZV9saWdodC5qcyIsIi4uL3NyYy9zdHlsZS1zcGVjL3ZhbGlkYXRlL3ZhbGlkYXRlX3RlcnJhaW4uanMiLCIuLi9zcmMvc3R5bGUtc3BlYy92YWxpZGF0ZS92YWxpZGF0ZV9mb2cuanMiLCIuLi9zcmMvc3R5bGUtc3BlYy92YWxpZGF0ZS92YWxpZGF0ZV9mb3JtYXR0ZWQuanMiLCIuLi9zcmMvc3R5bGUtc3BlYy92YWxpZGF0ZS92YWxpZGF0ZV9pbWFnZS5qcyIsIi4uL3NyYy9zdHlsZS1zcGVjL3ZhbGlkYXRlL3ZhbGlkYXRlX3Byb2plY3Rpb24uanMiLCIuLi9zcmMvc3R5bGUtc3BlYy92YWxpZGF0ZS92YWxpZGF0ZS5qcyIsIi4uL3NyYy9zdHlsZS1zcGVjL3ZhbGlkYXRlL3ZhbGlkYXRlX2dseXBoc191cmwuanMiLCIuLi9zcmMvc3R5bGUtc3BlYy92YWxpZGF0ZV9zdHlsZS5taW4uanMiLCIuLi9zcmMvc3R5bGUvdmFsaWRhdGVfc3R5bGUuanMiLCIuLi9ub2RlX21vZHVsZXMvZ3JpZC1pbmRleC9ncmlkLWluZGV4LmpzIiwiLi4vc3JjL3V0aWwvd2ViX3dvcmtlcl90cmFuc2Zlci5qcyIsIi4uL3NyYy91dGlsL2lzX2NoYXJfaW5fdW5pY29kZV9ibG9jay5qcyIsIi4uL3NyYy91dGlsL3NjcmlwdF9kZXRlY3Rpb24uanMiLCIuLi9zcmMvc291cmNlL3J0bF90ZXh0X3BsdWdpbi5qcyIsIi4uL3NyYy9zdHlsZS9ldmFsdWF0aW9uX3BhcmFtZXRlcnMuanMiLCIuLi9zcmMvc3R5bGUvcHJvcGVydGllcy5qcyIsIi4uL3NyYy9zaGFkZXJzL2VuY29kZV9hdHRyaWJ1dGUuanMiLCIuLi9zcmMvdXRpbC9zdHJ1Y3RfYXJyYXkuanMiLCIuLi9zcmMvZGF0YS9hcnJheV90eXBlcy5qcyIsIi4uL3NyYy9kYXRhL2J1Y2tldC9wYXR0ZXJuX2F0dHJpYnV0ZXMuanMiLCIuLi9zcmMvZGF0YS9idWNrZXQvZGFzaF9hdHRyaWJ1dGVzLmpzIiwiLi4vbm9kZV9tb2R1bGVzL211cm11cmhhc2gtanMvbXVybXVyaGFzaDNfZ2MuanMiLCIuLi9ub2RlX21vZHVsZXMvbXVybXVyaGFzaC1qcy9tdXJtdXJoYXNoMl9nYy5qcyIsIi4uL25vZGVfbW9kdWxlcy9tdXJtdXJoYXNoLWpzL2luZGV4LmpzIiwiLi4vc3JjL2RhdGEvZmVhdHVyZV9wb3NpdGlvbl9tYXAuanMiLCIuLi9zcmMvcmVuZGVyL3VuaWZvcm1fYmluZGluZy5qcyIsIi4uL3NyYy9kYXRhL3Byb2dyYW1fY29uZmlndXJhdGlvbi5qcyIsIi4uL3NyYy9zdHlsZS9zdHlsZV9sYXllci5qcyIsIi4uL3NyYy9kYXRhL2J1Y2tldC9jaXJjbGVfYXR0cmlidXRlcy5qcyIsIi4uL3NyYy9kYXRhL3NlZ21lbnQuanMiLCIuLi9zcmMvZGF0YS9pbmRleF9hcnJheV90eXBlLmpzIiwiLi4vc3JjL2RhdGEvZXh0ZW50LmpzIiwiLi4vc3JjL2dlby9sbmdfbGF0X2JvdW5kcy5qcyIsIi4uL25vZGVfbW9kdWxlcy9nbC1tYXRyaXgvZXNtL2NvbW1vbi5qcyIsIi4uL25vZGVfbW9kdWxlcy9nbC1tYXRyaXgvZXNtL21hdDIuanMiLCIuLi9ub2RlX21vZHVsZXMvZ2wtbWF0cml4L2VzbS9tYXQyZC5qcyIsIi4uL25vZGVfbW9kdWxlcy9nbC1tYXRyaXgvZXNtL21hdDMuanMiLCIuLi9ub2RlX21vZHVsZXMvZ2wtbWF0cml4L2VzbS9tYXQ0LmpzIiwiLi4vbm9kZV9tb2R1bGVzL2dsLW1hdHJpeC9lc20vdmVjMy5qcyIsIi4uL25vZGVfbW9kdWxlcy9nbC1tYXRyaXgvZXNtL3ZlYzQuanMiLCIuLi9ub2RlX21vZHVsZXMvZ2wtbWF0cml4L2VzbS9xdWF0LmpzIiwiLi4vbm9kZV9tb2R1bGVzL2dsLW1hdHJpeC9lc20vcXVhdDIuanMiLCIuLi9ub2RlX21vZHVsZXMvZ2wtbWF0cml4L2VzbS92ZWMyLmpzIiwiLi4vc3JjL3RlcnJhaW4vZ2xvYmVfYXR0cmlidXRlcy5qcyIsIi4uL3NyYy9kYXRhL3Bvc19hdHRyaWJ1dGVzLmpzIiwiLi4vc3JjL3V0aWwvcHJpbWl0aXZlcy5qcyIsIi4uL3NyYy9nZW8vcHJvamVjdGlvbi9nbG9iZV91dGlsLmpzIiwiLi4vc3JjL2dlby9sbmdfbGF0LmpzIiwiLi4vc3JjL2dlby9tZXJjYXRvcl9jb29yZGluYXRlLmpzIiwiLi4vc3JjL2dlby9wcm9qZWN0aW9uL3Jlc2FtcGxlLmpzIiwiLi4vc3JjL2RhdGEvbG9hZF9nZW9tZXRyeS5qcyIsIi4uL3NyYy9kYXRhL2V2YWx1YXRpb25fZmVhdHVyZS5qcyIsIi4uL3NyYy9kYXRhL2J1Y2tldC9jaXJjbGVfYnVja2V0LmpzIiwiLi4vc3JjL3V0aWwvaW50ZXJzZWN0aW9uX3Rlc3RzLmpzIiwiLi4vc3JjL3N0eWxlL3F1ZXJ5X3V0aWxzLmpzIiwiLi4vc3JjL3N0eWxlL3N0eWxlX2xheWVyL2NpcmNsZV9zdHlsZV9sYXllcl9wcm9wZXJ0aWVzLmpzIiwiLi4vc3JjL3N0eWxlL3N0eWxlX2xheWVyL2NpcmNsZV9zdHlsZV9sYXllci5qcyIsIi4uL3NyYy9kYXRhL2J1Y2tldC9oZWF0bWFwX2J1Y2tldC5qcyIsIi4uL3NyYy91dGlsL2ltYWdlLmpzIiwiLi4vc3JjL3N0eWxlL3N0eWxlX2xheWVyL2hlYXRtYXBfc3R5bGVfbGF5ZXJfcHJvcGVydGllcy5qcyIsIi4uL3NyYy91dGlsL2NvbG9yX3JhbXAuanMiLCIuLi9zcmMvc3R5bGUvc3R5bGVfbGF5ZXIvaGVhdG1hcF9zdHlsZV9sYXllci5qcyIsIi4uL3NyYy9zdHlsZS9zdHlsZV9sYXllci9oaWxsc2hhZGVfc3R5bGVfbGF5ZXJfcHJvcGVydGllcy5qcyIsIi4uL3NyYy9zdHlsZS9zdHlsZV9sYXllci9oaWxsc2hhZGVfc3R5bGVfbGF5ZXIuanMiLCIuLi9zcmMvZGF0YS9idWNrZXQvZmlsbF9hdHRyaWJ1dGVzLmpzIiwiLi4vbm9kZV9tb2R1bGVzL2VhcmN1dC9zcmMvZWFyY3V0LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3F1aWNrc2VsZWN0L2luZGV4LmpzIiwiLi4vc3JjL3V0aWwvY2xhc3NpZnlfcmluZ3MuanMiLCIuLi9zcmMvZGF0YS9idWNrZXQvcGF0dGVybl9idWNrZXRfZmVhdHVyZXMuanMiLCIuLi9zcmMvZGF0YS9idWNrZXQvZmlsbF9idWNrZXQuanMiLCIuLi9zcmMvc3R5bGUvc3R5bGVfbGF5ZXIvZmlsbF9zdHlsZV9sYXllcl9wcm9wZXJ0aWVzLmpzIiwiLi4vc3JjL3N0eWxlL3N0eWxlX2xheWVyL2ZpbGxfc3R5bGVfbGF5ZXIuanMiLCIuLi9zcmMvZGF0YS9idWNrZXQvZmlsbF9leHRydXNpb25fYXR0cmlidXRlcy5qcyIsIi4uL25vZGVfbW9kdWxlcy9AbWFwYm94L3ZlY3Rvci10aWxlL2xpYi92ZWN0b3J0aWxlZmVhdHVyZS5qcyIsIi4uL25vZGVfbW9kdWxlcy9AbWFwYm94L3ZlY3Rvci10aWxlL2xpYi92ZWN0b3J0aWxlbGF5ZXIuanMiLCIuLi9ub2RlX21vZHVsZXMvQG1hcGJveC92ZWN0b3ItdGlsZS9saWIvdmVjdG9ydGlsZS5qcyIsIi4uL25vZGVfbW9kdWxlcy9AbWFwYm94L3ZlY3Rvci10aWxlL2luZGV4LmpzIiwiLi4vc3JjL3V0aWwvcG9seWdvbl9jbGlwcGluZy5qcyIsIi4uL3NyYy9kYXRhL2J1Y2tldC9maWxsX2V4dHJ1c2lvbl9idWNrZXQuanMiLCIuLi9zcmMvc3R5bGUvc3R5bGVfbGF5ZXIvZmlsbF9leHRydXNpb25fc3R5bGVfbGF5ZXJfcHJvcGVydGllcy5qcyIsIi4uL25vZGVfbW9kdWxlcy9AbWFwYm94L3dob290cy1qcy9pbmRleC5tanMiLCIuLi9zcmMvc291cmNlL3RpbGVfaWQuanMiLCIuLi9zcmMvc3R5bGUvc3R5bGVfbGF5ZXIvZmlsbF9leHRydXNpb25fc3R5bGVfbGF5ZXIuanMiLCIuLi9zcmMvZGF0YS9idWNrZXQvbGluZV9hdHRyaWJ1dGVzLmpzIiwiLi4vc3JjL2RhdGEvYnVja2V0L2xpbmVfYXR0cmlidXRlc19leHQuanMiLCIuLi9zcmMvZGF0YS9idWNrZXQvbGluZV9idWNrZXQuanMiLCIuLi9zcmMvc3R5bGUvc3R5bGVfbGF5ZXIvbGluZV9zdHlsZV9sYXllcl9wcm9wZXJ0aWVzLmpzIiwiLi4vc3JjL3N0eWxlL3N0eWxlX2xheWVyL2xpbmVfc3R5bGVfbGF5ZXIuanMiLCIuLi9zcmMvZGF0YS9idWNrZXQvc3ltYm9sX2F0dHJpYnV0ZXMuanMiLCIuLi9zcmMvc3ltYm9sL29uZV9lbS5qcyIsIi4uL3NyYy9zeW1ib2wvc3ltYm9sX3NpemUuanMiLCIuLi9zcmMvc3ltYm9sL3RyYW5zZm9ybV90ZXh0LmpzIiwiLi4vc3JjL3N5bWJvbC9tZXJnZWxpbmVzLmpzIiwiLi4vc3JjL3V0aWwvdmVydGljYWxpemVfcHVuY3R1YXRpb24uanMiLCIuLi9ub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy9wYmYvaW5kZXguanMiLCIuLi9zcmMvc3R5bGUvcGFyc2VfZ2x5cGhfcGJmLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3BvdHBhY2svaW5kZXguanMiLCIuLi9zcmMvcmVuZGVyL2ltYWdlX2F0bGFzLmpzIiwiLi4vc3JjL3N5bWJvbC9zaGFwaW5nLmpzIiwiLi4vc3JjL3N5bWJvbC9hbmNob3IuanMiLCIuLi9zcmMvc3ltYm9sL2NoZWNrX21heF9hbmdsZS5qcyIsIi4uL3NyYy9zeW1ib2wvZ2V0X2FuY2hvcnMuanMiLCIuLi9zcmMvc3ltYm9sL2NsaXBfbGluZS5qcyIsIi4uL3NyYy9zdHlsZS9sb2FkX2dseXBoX3JhbmdlLmpzIiwiLi4vbm9kZV9tb2R1bGVzL0BtYXBib3gvdGlueS1zZGYvaW5kZXguanMiLCIuLi9zcmMvcmVuZGVyL2dseXBoX21hbmFnZXIuanMiLCIuLi9zcmMvc3ltYm9sL3F1YWRzLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3RpbnlxdWV1ZS9pbmRleC5qcyIsIi4uL3NyYy91dGlsL2ZpbmRfcG9sZV9vZl9pbmFjY2Vzc2liaWxpdHkuanMiLCIuLi9zcmMvc3ltYm9sL3N5bWJvbF9sYXlvdXQuanMiLCIuLi9zcmMvZ2VvL3Byb2plY3Rpb24vZmFyX3ouanMiLCIuLi9zcmMvZ2VvL3Byb2plY3Rpb24vdGlsZV90cmFuc2Zvcm0uanMiLCIuLi9zcmMvZ2VvL3Byb2plY3Rpb24vcHJvamVjdGlvbi5qcyIsIi4uL3NyYy9nZW8vcHJvamVjdGlvbi9hbGJlcnMuanMiLCIuLi9zcmMvZ2VvL3Byb2plY3Rpb24vZXF1YWxfZWFydGguanMiLCIuLi9zcmMvZ2VvL3Byb2plY3Rpb24vZXF1aXJlY3Rhbmd1bGFyLmpzIiwiLi4vc3JjL2dlby9wcm9qZWN0aW9uL2xhbWJlcnQuanMiLCIuLi9zcmMvZ2VvL3Byb2plY3Rpb24vbWVyY2F0b3IuanMiLCIuLi9zcmMvZ2VvL3Byb2plY3Rpb24vbmF0dXJhbF9lYXJ0aC5qcyIsIi4uL3NyYy9nZW8vcHJvamVjdGlvbi93aW5rZWxfdHJpcGVsLmpzIiwiLi4vc3JjL2dlby9wcm9qZWN0aW9uL2N5bGluZHJpY2FsX2VxdWFsX2FyZWEuanMiLCIuLi9zcmMvZ2VvL3Byb2plY3Rpb24vZ2xvYmUuanMiLCIuLi9zcmMvZ2VvL3Byb2plY3Rpb24vaW5kZXguanMiLCIuLi9zcmMvZGF0YS9idWNrZXQvc3ltYm9sX2J1Y2tldC5qcyIsIi4uL3NyYy91dGlsL3Jlc29sdmVfdG9rZW5zLmpzIiwiLi4vc3JjL3N0eWxlL3N0eWxlX2xheWVyL3N5bWJvbF9zdHlsZV9sYXllcl9wcm9wZXJ0aWVzLmpzIiwiLi4vc3JjL3N0eWxlL2Zvcm1hdF9zZWN0aW9uX292ZXJyaWRlLmpzIiwiLi4vc3JjL3N0eWxlL3N0eWxlX2xheWVyL3N5bWJvbF9zdHlsZV9sYXllci5qcyIsIi4uL3NyYy9zdHlsZS9zdHlsZV9sYXllci9iYWNrZ3JvdW5kX3N0eWxlX2xheWVyX3Byb3BlcnRpZXMuanMiLCIuLi9zcmMvc3R5bGUvc3R5bGVfbGF5ZXIvYmFja2dyb3VuZF9zdHlsZV9sYXllci5qcyIsIi4uL3NyYy9zdHlsZS9zdHlsZV9sYXllci9yYXN0ZXJfc3R5bGVfbGF5ZXJfcHJvcGVydGllcy5qcyIsIi4uL3NyYy9zdHlsZS9zdHlsZV9sYXllci9yYXN0ZXJfc3R5bGVfbGF5ZXIuanMiLCIuLi9zcmMvc3R5bGUvc3R5bGVfbGF5ZXIvY3VzdG9tX3N0eWxlX2xheWVyLmpzIiwiLi4vc3JjL3N0eWxlL3N0eWxlX2xheWVyL3NreV9zdHlsZV9sYXllcl9wcm9wZXJ0aWVzLmpzIiwiLi4vc3JjL3N0eWxlL3N0eWxlX2xheWVyL3NreV9zdHlsZV9sYXllci5qcyIsIi4uL3NyYy9zdHlsZS9jcmVhdGVfc3R5bGVfbGF5ZXIuanMiLCIuLi9zcmMvcmVuZGVyL3RleHR1cmUuanMiLCIuLi9zcmMvdXRpbC90aHJvdHRsZWRfaW52b2tlci5qcyIsIi4uL3NyYy91dGlsL3NjaGVkdWxlci5qcyIsIi4uL3NyYy91dGlsL2FjdG9yLmpzIiwiLi4vc3JjL3V0aWwvZGljdGlvbmFyeV9jb2Rlci5qcyIsIi4uL3NyYy91dGlsL3ZlY3RvcnRpbGVfdG9fZ2VvanNvbi5qcyIsIi4uL3NyYy9kYXRhL2J1Y2tldC5qcyIsIi4uL3NyYy91dGlsL2RlYnVnLmpzIiwiLi4vc3JjL2RhdGEvZGVidWdfdml6LmpzIiwiLi4vc3JjL3NvdXJjZS90aWxlX21lc2guanMiLCIuLi9zcmMvZGF0YS9ib3VuZHNfYXR0cmlidXRlcy5qcyIsIi4uL3NyYy9zb3VyY2UvdGlsZS5qcyIsIi4uL3NyYy9zb3VyY2Uvc291cmNlX3N0YXRlLmpzIiwiLi4vc3JjL2RhdGEvZGVtX3RyZWUuanMiLCIuLi9zcmMvZGF0YS9kZW1fZGF0YS5qcyIsIi4uL3NyYy9zb3VyY2UvdGlsZV9jYWNoZS5qcyIsIi4uL3NyYy9nbC9pbmRleF9idWZmZXIuanMiLCIuLi9zcmMvZ2wvdmVydGV4X2J1ZmZlci5qcyIsIi4uL3NyYy9nbC92YWx1ZS5qcyIsIi4uL3NyYy9nbC9mcmFtZWJ1ZmZlci5qcyIsIi4uL3NyYy9nbC9kZXB0aF9tb2RlLmpzIiwiLi4vc3JjL2dsL3N0ZW5jaWxfbW9kZS5qcyIsIi4uL3NyYy9nbC9jb2xvcl9tb2RlLmpzIiwiLi4vc3JjL2dsL2N1bGxfZmFjZV9tb2RlLmpzIiwiLi4vc3JjL2dsL2NvbnRleHQuanMiLCIuLi9zcmMvc291cmNlL3NvdXJjZV9jYWNoZS5qcyIsIi4uL3NyYy90ZXJyYWluL2VsZXZhdGlvbi5qcyIsIi4uL3NyYy9kYXRhL2ZlYXR1cmVfaW5kZXguanMiLCIuLi9zcmMvcmVuZGVyL2xpbmVfYXRsYXMuanMiLCIuLi9zcmMvcmVuZGVyL2dseXBoX2F0bGFzLmpzIiwiLi4vc3JjL3NvdXJjZS93b3JrZXJfdGlsZS5qcyIsIi4uL3NyYy9zb3VyY2UvdmVjdG9yX3RpbGVfd29ya2VyX3NvdXJjZS5qcyIsIi4uL3NyYy9zdHlsZS1zcGVjL3V0aWwvcmVmX3Byb3BlcnRpZXMuanMiLCIuLi9ub2RlX21vZHVsZXMva2RidXNoL2luZGV4LmpzIiwiLi4vc3JjL3N0eWxlLXNwZWMvZ3JvdXBfYnlfbGF5b3V0LmpzIiwiLi4vc3JjL3N0eWxlL3N0eWxlX2xheWVyX2luZGV4LmpzIiwiLi4vc3JjL3NvdXJjZS9yYXN0ZXJfZGVtX3RpbGVfd29ya2VyX3NvdXJjZS5qcyIsIi4uL25vZGVfbW9kdWxlcy9AbWFwYm94L2dlb2pzb24tcmV3aW5kL2luZGV4LmpzIiwiLi4vc3JjL3NvdXJjZS9nZW9qc29uX3dyYXBwZXIuanMiLCIuLi9ub2RlX21vZHVsZXMvdnQtcGJmL2xpYi9nZW9qc29uX3dyYXBwZXIuanMiLCIuLi9ub2RlX21vZHVsZXMvdnQtcGJmL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3N1cGVyY2x1c3Rlci9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy9nZW9qc29uLXZ0L3NyYy9zaW1wbGlmeS5qcyIsIi4uL25vZGVfbW9kdWxlcy9nZW9qc29uLXZ0L3NyYy9mZWF0dXJlLmpzIiwiLi4vbm9kZV9tb2R1bGVzL2dlb2pzb24tdnQvc3JjL2NvbnZlcnQuanMiLCIuLi9ub2RlX21vZHVsZXMvZ2VvanNvbi12dC9zcmMvY2xpcC5qcyIsIi4uL25vZGVfbW9kdWxlcy9nZW9qc29uLXZ0L3NyYy93cmFwLmpzIiwiLi4vbm9kZV9tb2R1bGVzL2dlb2pzb24tdnQvc3JjL3RyYW5zZm9ybS5qcyIsIi4uL25vZGVfbW9kdWxlcy9nZW9qc29uLXZ0L3NyYy90aWxlLmpzIiwiLi4vbm9kZV9tb2R1bGVzL2dlb2pzb24tdnQvc3JjL2luZGV4LmpzIiwiLi4vc3JjL3NvdXJjZS9nZW9qc29uX3dvcmtlcl9zb3VyY2UuanMiLCIuLi9zcmMvc291cmNlL3dvcmtlci5qcyIsIi4uL25vZGVfbW9kdWxlcy9AbWFwYm94L21hcGJveC1nbC1zdXBwb3J0ZWQvaW5kZXguanMiLCIuLi9zcmMvdXRpbC9kb20uanMiLCIuLi9zcmMvc3R5bGUvbG9hZF9zcHJpdGUuanMiLCIuLi9zcmMvc3R5bGUvc3R5bGVfaW1hZ2UuanMiLCIuLi9zcmMvcmVuZGVyL2ltYWdlX21hbmFnZXIuanMiLCIuLi9zcmMvc3R5bGUvbGlnaHQuanMiLCIuLi9zcmMvc3R5bGUvdGVycmFpbi5qcyIsIi4uL3NyYy9zdHlsZS9mb2dfaGVscGVycy5qcyIsIi4uL3NyYy9zdHlsZS9mb2cuanMiLCIuLi9zcmMvdXRpbC9kaXNwYXRjaGVyLmpzIiwiLi4vc3JjL3NvdXJjZS9waXhlbHNfdG9fdGlsZV91bml0cy5qcyIsIi4uL3NyYy9zdHlsZS9xdWVyeV9nZW9tZXRyeS5qcyIsIi4uL3NyYy9zb3VyY2UvbG9hZF90aWxlanNvbi5qcyIsIi4uL3NyYy9zb3VyY2UvdGlsZV9ib3VuZHMuanMiLCIuLi9zcmMvc291cmNlL3ZlY3Rvcl90aWxlX3NvdXJjZS5qcyIsIi4uL3NyYy9zb3VyY2UvcmFzdGVyX3RpbGVfc291cmNlLmpzIiwiLi4vc3JjL3V0aWwvb2Zmc2NyZWVuX2NhbnZhc19zdXBwb3J0ZWQuanMiLCIuLi9zcmMvc291cmNlL3Jhc3Rlcl9kZW1fdGlsZV9zb3VyY2UuanMiLCIuLi9zcmMvc291cmNlL2dlb2pzb25fc291cmNlLmpzIiwiLi4vc3JjL3NvdXJjZS9pbWFnZV9zb3VyY2UuanMiLCIuLi9zcmMvc291cmNlL3ZpZGVvX3NvdXJjZS5qcyIsIi4uL3NyYy9zb3VyY2UvY2FudmFzX3NvdXJjZS5qcyIsIi4uL3NyYy9zb3VyY2UvY3VzdG9tX3NvdXJjZS5qcyIsIi4uL3NyYy9zb3VyY2Uvc291cmNlLmpzIiwiLi4vc3JjL3NvdXJjZS9xdWVyeV9mZWF0dXJlcy5qcyIsIi4uL3NyYy91dGlsL2Jyb3dzZXIvd2ViX3dvcmtlci5qcyIsIi4uL3NyYy91dGlsL3dvcmtlcl9wb29sLmpzIiwiLi4vc3JjL3V0aWwvZ2xvYmFsX3dvcmtlcl9wb29sLmpzIiwiLi4vc3JjL3N0eWxlLXNwZWMvZGVyZWYuanMiLCIuLi9zcmMvc3R5bGUtc3BlYy9lbXB0eS5qcyIsIi4uL3NyYy9zdHlsZS1zcGVjL2RpZmYuanMiLCIuLi9zcmMvc3ltYm9sL3BhdGhfaW50ZXJwb2xhdG9yLmpzIiwiLi4vc3JjL3N5bWJvbC9ncmlkX2luZGV4LmpzIiwiLi4vc3JjL3N5bWJvbC9wcm9qZWN0aW9uLmpzIiwiLi4vc3JjL3N5bWJvbC9jb2xsaXNpb25faW5kZXguanMiLCIuLi9zcmMvZ2VvL3Byb2plY3Rpb24vcHJvamVjdGlvbl91dGlsLmpzIiwiLi4vc3JjL3N5bWJvbC9wbGFjZW1lbnQuanMiLCIuLi9zcmMvc3R5bGUvcGF1c2VhYmxlX3BsYWNlbWVudC5qcyIsIi4uL3NyYy9zeW1ib2wvY3Jvc3NfdGlsZV9zeW1ib2xfaW5kZXguanMiLCIuLi9zcmMvc3R5bGUvc3R5bGUuanMiLCIuLi9zcmMvc2hhZGVycy9zaGFkZXJzLmpzIiwiLi4vc3JjL3JlbmRlci92ZXJ0ZXhfYXJyYXlfb2JqZWN0LmpzIiwiLi4vc3JjL3JlbmRlci9wcm9ncmFtL2hpbGxzaGFkZV9wcm9ncmFtLmpzIiwiLi4vc3JjL3JlbmRlci9kcmF3X2hpbGxzaGFkZS5qcyIsIi4uL3NyYy90ZXJyYWluL3RlcnJhaW5fcmFzdGVyX3Byb2dyYW0uanMiLCIuLi9zcmMvdGVycmFpbi9nbG9iZV9yYXN0ZXJfcHJvZ3JhbS5qcyIsIi4uL3NyYy90ZXJyYWluL2RyYXdfdGVycmFpbl9yYXN0ZXIuanMiLCIuLi9zcmMvcmVuZGVyL3Byb2dyYW0vY2xpcHBpbmdfbWFza19wcm9ncmFtLmpzIiwiLi4vc3JjL3JlbmRlci9yYXN0ZXJfZmFkZS5qcyIsIi4uL3NyYy90ZXJyYWluL3RlcnJhaW4uanMiLCIuLi9zcmMvcmVuZGVyL2ZvZy5qcyIsIi4uL3NyYy9yZW5kZXIvcHJvZ3JhbS5qcyIsIi4uL3NyYy9yZW5kZXIvcHJvZ3JhbS9wYXR0ZXJuLmpzIiwiLi4vc3JjL3JlbmRlci9wcm9ncmFtL2ZpbGxfZXh0cnVzaW9uX3Byb2dyYW0uanMiLCIuLi9zcmMvcmVuZGVyL3Byb2dyYW0vZmlsbF9wcm9ncmFtLmpzIiwiLi4vc3JjL3JlbmRlci9wcm9ncmFtL2NpcmNsZV9wcm9ncmFtLmpzIiwiLi4vc3JjL3JlbmRlci9wcm9ncmFtL2NvbGxpc2lvbl9wcm9ncmFtLmpzIiwiLi4vc3JjL3JlbmRlci9wcm9ncmFtL2RlYnVnX3Byb2dyYW0uanMiLCIuLi9zcmMvcmVuZGVyL3Byb2dyYW0vaGVhdG1hcF9wcm9ncmFtLmpzIiwiLi4vc3JjL3JlbmRlci9wcm9ncmFtL2xpbmVfcHJvZ3JhbS5qcyIsIi4uL3NyYy9yZW5kZXIvcHJvZ3JhbS9yYXN0ZXJfcHJvZ3JhbS5qcyIsIi4uL3NyYy9yZW5kZXIvcHJvZ3JhbS9zeW1ib2xfcHJvZ3JhbS5qcyIsIi4uL3NyYy9yZW5kZXIvcHJvZ3JhbS9iYWNrZ3JvdW5kX3Byb2dyYW0uanMiLCIuLi9zcmMvcmVuZGVyL3Byb2dyYW0vc2t5Ym94X3Byb2dyYW0uanMiLCIuLi9zcmMvcmVuZGVyL3Byb2dyYW0vc2t5Ym94X2NhcHR1cmVfcHJvZ3JhbS5qcyIsIi4uL3NyYy9yZW5kZXIvcHJvZ3JhbS9wcm9ncmFtX3VuaWZvcm1zLmpzIiwiLi4vc3JjL3JlbmRlci9kcmF3X2NvbGxpc2lvbl9kZWJ1Zy5qcyIsIi4uL3NyYy9yZW5kZXIvZHJhd19zeW1ib2wuanMiLCIuLi9zcmMvcmVuZGVyL2RyYXdfY2lyY2xlLmpzIiwiLi4vc3JjL3JlbmRlci9kcmF3X2hlYXRtYXAuanMiLCIuLi9zcmMvcmVuZGVyL2RyYXdfbGluZS5qcyIsIi4uL3NyYy9yZW5kZXIvZHJhd19maWxsLmpzIiwiLi4vc3JjL3JlbmRlci9kcmF3X2ZpbGxfZXh0cnVzaW9uLmpzIiwiLi4vc3JjL3JlbmRlci9kcmF3X3Jhc3Rlci5qcyIsIi4uL3NyYy9yZW5kZXIvZHJhd19iYWNrZ3JvdW5kLmpzIiwiLi4vc3JjL3JlbmRlci9kcmF3X2RlYnVnLmpzIiwiLi4vc3JjL3JlbmRlci9kcmF3X2N1c3RvbS5qcyIsIi4uL3NyYy9yZW5kZXIvc2t5Ym94X2F0dHJpYnV0ZXMuanMiLCIuLi9zcmMvcmVuZGVyL3NreWJveF9nZW9tZXRyeS5qcyIsIi4uL3NyYy9yZW5kZXIvZHJhd19za3kuanMiLCIuLi9zcmMvcmVuZGVyL2RyYXdfYXRtb3NwaGVyZS5qcyIsIi4uL3NyYy9yZW5kZXIvYXRtb3NwaGVyZV9hdHRyaWJ1dGVzLmpzIiwiLi4vc3JjL3JlbmRlci9hdG1vc3BoZXJlX2J1ZmZlci5qcyIsIi4uL3NyYy9yZW5kZXIvcGFpbnRlci5qcyIsIi4uL3NyYy9nZW8vZWRnZV9pbnNldHMuanMiLCIuLi9zcmMvdWkvZnJlZV9jYW1lcmEuanMiLCIuLi9zcmMvZ2VvL3Byb2plY3Rpb24vYWRqdXN0bWVudHMuanMiLCIuLi9zcmMvZ2VvL3RyYW5zZm9ybS5qcyIsIi4uL3NyYy91dGlsL3Rocm90dGxlLmpzIiwiLi4vc3JjL3VpL2hhc2guanMiLCIuLi9zcmMvdWkvaGFuZGxlcl9pbmVydGlhLmpzIiwiLi4vc3JjL3VpL2V2ZW50cy5qcyIsIi4uL3NyYy91aS9oYW5kbGVyL21hcF9ldmVudC5qcyIsIi4uL3NyYy91aS9oYW5kbGVyL2JveF96b29tLmpzIiwiLi4vc3JjL3VpL2hhbmRsZXIvaGFuZGxlcl91dGlsLmpzIiwiLi4vc3JjL3VpL2hhbmRsZXIvdGFwX3JlY29nbml6ZXIuanMiLCIuLi9zcmMvdWkvaGFuZGxlci90YXBfem9vbS5qcyIsIi4uL3NyYy91aS9oYW5kbGVyL21vdXNlLmpzIiwiLi4vc3JjL3VpL2hhbmRsZXIvdG91Y2hfcGFuLmpzIiwiLi4vc3JjL3VpL2hhbmRsZXIvdG91Y2hfem9vbV9yb3RhdGUuanMiLCIuLi9zcmMvdWkvaGFuZGxlci9rZXlib2FyZC5qcyIsIi4uL3NyYy91aS9oYW5kbGVyL3Njcm9sbF96b29tLmpzIiwiLi4vc3JjL3VpL2hhbmRsZXIvc2hpbS9kYmxjbGlja196b29tLmpzIiwiLi4vc3JjL3VpL2hhbmRsZXIvY2xpY2tfem9vbS5qcyIsIi4uL3NyYy91aS9oYW5kbGVyL3RhcF9kcmFnX3pvb20uanMiLCIuLi9zcmMvdWkvaGFuZGxlci9zaGltL2RyYWdfcGFuLmpzIiwiLi4vc3JjL3VpL2hhbmRsZXIvc2hpbS9kcmFnX3JvdGF0ZS5qcyIsIi4uL3NyYy91aS9oYW5kbGVyL3NoaW0vdG91Y2hfem9vbV9yb3RhdGUuanMiLCIuLi9zcmMvdWkvaGFuZGxlcl9tYW5hZ2VyLmpzIiwiLi4vc3JjL3VpL2NhbWVyYS5qcyIsIi4uL3NyYy91aS9jb250cm9sL2F0dHJpYnV0aW9uX2NvbnRyb2wuanMiLCIuLi9zcmMvdWkvY29udHJvbC9sb2dvX2NvbnRyb2wuanMiLCIuLi9zcmMvdXRpbC90YXNrX3F1ZXVlLmpzIiwiLi4vc3JjL3V0aWwvc21hcnRfd3JhcC5qcyIsIi4uL3NyYy91aS9hbmNob3IuanMiLCIuLi9zcmMvdWkvbWFya2VyLmpzIiwiLi4vc3JjL3VpL3BvcHVwLmpzIiwiLi4vc3JjL3V0aWwvZWFzZWRfdmFyaWFibGUuanMiLCIuLi9zcmMvdWkvZGVmYXVsdF9sb2NhbGUuanMiLCIuLi9zcmMvdWkvbWFwLmpzIiwiLi4vc3JjL3VpL2NvbnRyb2wvbmF2aWdhdGlvbl9jb250cm9sLmpzIiwiLi4vc3JjL3VpL2NvbnRyb2wvZ2VvbG9jYXRlX2NvbnRyb2wuanMiLCIuLi9zcmMvdWkvY29udHJvbC9zY2FsZV9jb250cm9sLmpzIiwiLi4vc3JjL3VpL2NvbnRyb2wvZnVsbHNjcmVlbl9jb250cm9sLmpzIiwiLi4vc3JjL3V0aWwvd29ya2VyX3BlcmZvcm1hbmNlX3V0aWxzLmpzIiwiLi4vc3JjL2luZGV4LmpzIiwiLi4vcm9sbHVwL21hcGJveGdsLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG4vKiBlc2xpbnQtZW52IGJyb3dzZXIgKi9cbmltcG9ydCB0eXBlIHtXaW5kb3d9IGZyb20gJy4uLy4uL3R5cGVzL3dpbmRvdy5qcyc7XG5cbi8vIHNoaW0gd2luZG93IGZvciB0aGUgY2FzZSBvZiByZXF1aXJpbmcgdGhlIGJyb3dzZXIgYnVuZGxlIGluIE5vZGVcbmV4cG9ydCBkZWZhdWx0ICgodHlwZW9mIHNlbGYgIT09ICd1bmRlZmluZWQnID8gc2VsZiA6ICh7fTogYW55KSk6IFdpbmRvdyk7XG4iLCIvLyBAZmxvdyBzdHJpY3RcblxudHlwZSBDb25maWcgPSB7fFxuICBBUElfVVJMOiBzdHJpbmcsXG4gIEFQSV9VUkxfUkVHRVg6IFJlZ0V4cCxcbiAgQVBJX1RJTEVKU09OX1JFR0VYOiBSZWdFeHAsXG4gIEFQSV9GT05UU19SRUdFWDogUmVnRXhwLFxuICBBUElfU1BSSVRFX1JFR0VYOiBSZWdFeHAsXG4gIEFQSV9TVFlMRV9SRUdFWDogUmVnRXhwLFxuICBBUElfQ0ROX1VSTF9SRUdFWDogUmVnRXhwLFxuICBFVkVOVFNfVVJMOiA/c3RyaW5nLFxuICBTRVNTSU9OX1BBVEg6IHN0cmluZyxcbiAgRkVFREJBQ0tfVVJMOiBzdHJpbmcsXG4gIFJFUVVJUkVfQUNDRVNTX1RPS0VOOiBib29sZWFuLFxuICBUSUxFX1VSTF9WRVJTSU9OOiBzdHJpbmcsXG4gIFJBU1RFUl9VUkxfUFJFRklYOiBzdHJpbmcsXG4gIEFDQ0VTU19UT0tFTjogP3N0cmluZyxcbiAgTUFYX1BBUkFMTEVMX0lNQUdFX1JFUVVFU1RTOiBudW1iZXJcbnx9O1xuXG5sZXQgbWFwYm94SFRUUFVSTFJlZ2V4O1xuXG5jb25zdCBjb25maWc6IENvbmZpZyA9IHtcbiAgICBBUElfVVJMOiAnaHR0cHM6Ly9hcGkubWFwYm94LmNvbScsXG4gICAgZ2V0IEFQSV9VUkxfUkVHRVggKCkge1xuICAgICAgICBpZiAobWFwYm94SFRUUFVSTFJlZ2V4ID09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnN0IHByb2RNYXBib3hIVFRQVVJMUmVnZXggPSAvXigoaHR0cHM/Oik/XFwvXFwvKT8oW15cXC9dK1xcLik/bWFwYm94XFwuYyhufG9tKShcXC98XFw/fCQpL2k7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIG1hcGJveEhUVFBVUkxSZWdleCA9IChwcm9jZXNzLmVudi5BUElfVVJMX1JFR0VYICE9IG51bGwpID8gbmV3IFJlZ0V4cChwcm9jZXNzLmVudi5BUElfVVJMX1JFR0VYKSA6IHByb2RNYXBib3hIVFRQVVJMUmVnZXg7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgbWFwYm94SFRUUFVSTFJlZ2V4ID0gcHJvZE1hcGJveEhUVFBVUkxSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBtYXBib3hIVFRQVVJMUmVnZXg7XG4gICAgfSxcbiAgICBnZXQgQVBJX1RJTEVKU09OX1JFR0VYKCkge1xuICAgICAgICAvLyBodHRwczovL2RvY3MubWFwYm94LmNvbS9hcGkvbWFwcy9tYXBib3gtdGlsaW5nLXNlcnZpY2UvI3JldHJpZXZlLXRpbGVqc29uLW1ldGFkYXRhXG4gICAgICAgIHJldHVybiAvXigoaHR0cHM/Oik/XFwvXFwvKT8oW15cXC9dK1xcLik/bWFwYm94XFwuYyhufG9tKShcXC92WzAtOV0qXFwvLipcXC5qc29uLiokKS9pO1xuICAgIH0sXG4gICAgZ2V0IEFQSV9TUFJJVEVfUkVHRVgoKSB7XG4gICAgICAgIC8vIGh0dHBzOi8vZG9jcy5tYXBib3guY29tL2FwaS9tYXBzL3N0eWxlcy8jcmV0cmlldmUtYS1zcHJpdGUtaW1hZ2Utb3ItanNvblxuICAgICAgICByZXR1cm4gL14oKGh0dHBzPzopP1xcL1xcLyk/KFteXFwvXStcXC4pP21hcGJveFxcLmMobnxvbSkoXFwvc3R5bGVzXFwvdlswLTldKlxcLykoLipcXC9zcHJpdGUuKlxcLi4qJCkvaTtcbiAgICB9LFxuICAgIGdldCBBUElfRk9OVFNfUkVHRVgoKSB7XG4gICAgICAgIC8vIGh0dHBzOi8vZG9jcy5tYXBib3guY29tL2FwaS9tYXBzL2ZvbnRzLyNyZXRyaWV2ZS1mb250LWdseXBoLXJhbmdlc1xuICAgICAgICByZXR1cm4gL14oKGh0dHBzPzopP1xcL1xcLyk/KFteXFwvXStcXC4pP21hcGJveFxcLmMobnxvbSkoXFwvZm9udHNcXC92WzAtOV0qXFwvKSguKlxcLnBiZi4qJCkvaTtcbiAgICB9LFxuICAgIGdldCBBUElfU1RZTEVfUkVHRVgoKSB7XG4gICAgICAgIC8vIGh0dHBzOi8vZG9jcy5tYXBib3guY29tL2FwaS9tYXBzL3N0eWxlcy8jcmV0cmlldmUtYS1zdHlsZVxuICAgICAgICByZXR1cm4gL14oKGh0dHBzPzopP1xcL1xcLyk/KFteXFwvXStcXC4pP21hcGJveFxcLmMobnxvbSkoXFwvc3R5bGVzXFwvdlswLTldKlxcLykoLiokKS9pO1xuICAgIH0sXG4gICAgZ2V0IEFQSV9DRE5fVVJMX1JFR0VYKCkge1xuICAgICAgICByZXR1cm4gL14oKGh0dHBzPzopP1xcL1xcLyk/YXBpXFwubWFwYm94XFwuYyhufG9tKShcXC9tYXBib3gtZ2wtanNcXC8pKC4qJCkvaTtcbiAgICB9LFxuICAgIGdldCBFVkVOVFNfVVJMKCkge1xuICAgICAgICBpZiAoIWNvbmZpZy5BUElfVVJMKSB7IHJldHVybiBudWxsOyB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCB1cmwgPSBuZXcgVVJMKGNvbmZpZy5BUElfVVJMKTtcbiAgICAgICAgICAgIGlmICh1cmwuaG9zdG5hbWUgPT09ICdhcGkubWFwYm94LmNuJykge1xuICAgICAgICAgICAgICAgIHJldHVybiAnaHR0cHM6Ly9ldmVudHMubWFwYm94LmNuL2V2ZW50cy92Mic7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHVybC5ob3N0bmFtZSA9PT0gJ2FwaS5tYXBib3guY29tJykge1xuICAgICAgICAgICAgICAgIHJldHVybiAnaHR0cHM6Ly9ldmVudHMubWFwYm94LmNvbS9ldmVudHMvdjInO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIFNFU1NJT05fUEFUSDogJy9tYXAtc2Vzc2lvbnMvdjEnLFxuICAgIEZFRURCQUNLX1VSTDogJ2h0dHBzOi8vYXBwcy5tYXBib3guY29tL2ZlZWRiYWNrJyxcbiAgICBUSUxFX1VSTF9WRVJTSU9OOiAndjQnLFxuICAgIFJBU1RFUl9VUkxfUFJFRklYOiAncmFzdGVyL3YxJyxcbiAgICBSRVFVSVJFX0FDQ0VTU19UT0tFTjogdHJ1ZSxcbiAgICBBQ0NFU1NfVE9LRU46IG51bGwsXG4gICAgTUFYX1BBUkFMTEVMX0lNQUdFX1JFUVVFU1RTOiAxNlxufTtcblxuZXhwb3J0IGRlZmF1bHQgY29uZmlnO1xuIiwiLy8gQGZsb3cgc3RyaWN0XG5cbmltcG9ydCB3aW5kb3cgZnJvbSAnLi93aW5kb3cuanMnO1xuXG5jb25zdCBleHBvcnRlZCA9IHtcbiAgICBzdXBwb3J0ZWQ6IGZhbHNlLFxuICAgIHRlc3RTdXBwb3J0XG59O1xuXG5leHBvcnQgZGVmYXVsdCBleHBvcnRlZDtcblxubGV0IGdsRm9yVGVzdGluZztcbmxldCB3ZWJwQ2hlY2tDb21wbGV0ZSA9IGZhbHNlO1xubGV0IHdlYnBJbWdUZXN0O1xubGV0IHdlYnBJbWdUZXN0T25sb2FkQ29tcGxldGUgPSBmYWxzZTtcblxuaWYgKHdpbmRvdy5kb2N1bWVudCkge1xuICAgIHdlYnBJbWdUZXN0ID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpO1xuICAgIHdlYnBJbWdUZXN0Lm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAoZ2xGb3JUZXN0aW5nKSB0ZXN0V2VicFRleHR1cmVVcGxvYWQoZ2xGb3JUZXN0aW5nKTtcbiAgICAgICAgZ2xGb3JUZXN0aW5nID0gbnVsbDtcbiAgICAgICAgd2VicEltZ1Rlc3RPbmxvYWRDb21wbGV0ZSA9IHRydWU7XG4gICAgfTtcbiAgICB3ZWJwSW1nVGVzdC5vbmVycm9yID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHdlYnBDaGVja0NvbXBsZXRlID0gdHJ1ZTtcbiAgICAgICAgZ2xGb3JUZXN0aW5nID0gbnVsbDtcbiAgICB9O1xuICAgIHdlYnBJbWdUZXN0LnNyYyA9ICdkYXRhOmltYWdlL3dlYnA7YmFzZTY0LFVrbEdSaDRBQUFCWFJVSlFWbEE0VEJFQUFBQXZBUUFBQUFmUS8vNzN2LytCaU9oL0FBQT0nO1xufVxuXG5mdW5jdGlvbiB0ZXN0U3VwcG9ydChnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0KSB7XG4gICAgaWYgKHdlYnBDaGVja0NvbXBsZXRlIHx8ICF3ZWJwSW1nVGVzdCkgcmV0dXJuO1xuXG4gICAgLy8gSFRNTEltYWdlRWxlbWVudC5jb21wbGV0ZSBpcyBzZXQgd2hlbiBhbiBpbWFnZSBpcyBkb25lIGxvYWRpbmcgaXQncyBzb3VyY2VcbiAgICAvLyByZWdhcmRsZXNzIG9mIHdoZXRoZXIgdGhlIGxvYWQgd2FzIHN1Y2Nlc3NmdWwgb3Igbm90LlxuICAgIC8vIEl0J3MgcG9zc2libGUgZm9yIGFuIGVycm9yIHRvIHNldCBIVE1MSW1hZ2VFbGVtZW50LmNvbXBsZXRlIHRvIHRydWUgd2hpY2ggd291bGQgdHJpZ2dlclxuICAgIC8vIHRlc3RXZWJwVGV4dHVyZVVwbG9hZCBhbmQgbWlzdGFrZW5seSBzZXQgZXhwb3J0ZWQuc3VwcG9ydGVkIHRvIHRydWUgaW4gYnJvd3NlcnMgd2hpY2ggZG9uJ3Qgc3VwcG9ydCB3ZWJwXG4gICAgLy8gVG8gYXZvaWQgdGhpcywgd2Ugc2V0IGEgZmxhZyBpbiB0aGUgaW1hZ2UncyBvbmxvYWQgaGFuZGxlciBhbmQgb25seSBjYWxsIHRlc3RXZWJwVGV4dHVyZVVwbG9hZFxuICAgIC8vIGFmdGVyIGEgc3VjY2Vzc2Z1bCBpbWFnZSBsb2FkIGV2ZW50LlxuICAgIGlmICh3ZWJwSW1nVGVzdE9ubG9hZENvbXBsZXRlKSB7XG4gICAgICAgIHRlc3RXZWJwVGV4dHVyZVVwbG9hZChnbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgZ2xGb3JUZXN0aW5nID0gZ2w7XG5cbiAgICB9XG59XG5cbmZ1bmN0aW9uIHRlc3RXZWJwVGV4dHVyZVVwbG9hZChnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0KSB7XG4gICAgLy8gRWRnZSAxOCBzdXBwb3J0cyBXZWJQIGJ1dCBub3QgdXBsb2FkaW5nIGEgV2ViUCBpbWFnZSB0byBhIGdsIHRleHR1cmVcbiAgICAvLyBUZXN0IHN1cHBvcnQgZm9yIHRoaXMgYmVmb3JlIGFsbG93aW5nIFdlYlAgaW1hZ2VzLlxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXBib3gvbWFwYm94LWdsLWpzL2lzc3Vlcy83NjcxXG4gICAgY29uc3QgdGV4dHVyZSA9IGdsLmNyZWF0ZVRleHR1cmUoKTtcbiAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCB0ZXh0dXJlKTtcblxuICAgIHRyeSB7XG4gICAgICAgIGdsLnRleEltYWdlMkQoZ2wuVEVYVFVSRV8yRCwgMCwgZ2wuUkdCQSwgZ2wuUkdCQSwgZ2wuVU5TSUdORURfQllURSwgd2VicEltZ1Rlc3QpO1xuXG4gICAgICAgIC8vIFRoZSBlcnJvciBkb2VzIG5vdCBnZXQgdHJpZ2dlcmVkIGluIEVkZ2UgaWYgdGhlIGNvbnRleHQgaXMgbG9zdFxuICAgICAgICBpZiAoZ2wuaXNDb250ZXh0TG9zdCgpKSByZXR1cm47XG5cbiAgICAgICAgZXhwb3J0ZWQuc3VwcG9ydGVkID0gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIENhdGNoIFwiVW5zcGVjaWZpZWQgRXJyb3IuXCIgaW4gRWRnZSAxOC5cbiAgICB9XG5cbiAgICBnbC5kZWxldGVUZXh0dXJlKHRleHR1cmUpO1xuXG4gICAgd2VicENoZWNrQ29tcGxldGUgPSB0cnVlO1xufVxuIiwiLy8gQGZsb3dcblxuLyoqKioqIFNUQVJUIFdBUk5JTkcgUkVNT1ZBTCBPUiBNT0RJRklDQVRJT04gT0YgVEhFXG4qIEZPTExPV0lORyBDT0RFIFZJT0xBVEVTIFRIRSBNQVBCT1ggVEVSTVMgT0YgU0VSVklDRSAgKioqKioqXG4qIFRoZSBmb2xsb3dpbmcgY29kZSBpcyB1c2VkIHRvIGFjY2VzcyBNYXBib3gncyBBUElzLiBSZW1vdmFsIG9yIG1vZGlmaWNhdGlvblxuKiBvZiB0aGlzIGNvZGUgY2FuIHJlc3VsdCBpbiBoaWdoZXIgZmVlcyBhbmQvb3JcbiogdGVybWluYXRpb24gb2YgeW91ciBhY2NvdW50IHdpdGggTWFwYm94LlxuKlxuKiBVbmRlciB0aGUgTWFwYm94IFRlcm1zIG9mIFNlcnZpY2UsIHlvdSBtYXkgbm90IHVzZSB0aGlzIGNvZGUgdG8gYWNjZXNzIE1hcGJveFxuKiBNYXBwaW5nIEFQSXMgb3RoZXIgdGhhbiB0aHJvdWdoIE1hcGJveCBTREtzLlxuKlxuKiBUaGUgTWFwcGluZyBBUElzIGRvY3VtZW50YXRpb24gaXMgYXZhaWxhYmxlIGF0IGh0dHBzOi8vZG9jcy5tYXBib3guY29tL2FwaS9tYXBzLyNtYXBzXG4qIGFuZCB0aGUgTWFwYm94IFRlcm1zIG9mIFNlcnZpY2UgYXJlIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5tYXBib3guY29tL3Rvcy9cbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxudHlwZSBTa3VUb2tlbk9iamVjdCA9IHt8XG4gICAgdG9rZW46IHN0cmluZyxcbiAgICB0b2tlbkV4cGlyZXNBdDogbnVtYmVyXG58fTtcblxuY29uc3QgU0tVX0lEID0gJzAxJztcblxuZnVuY3Rpb24gY3JlYXRlU2t1VG9rZW4oKTogU2t1VG9rZW5PYmplY3Qge1xuICAgIC8vIFNLVV9JRCBhbmQgVE9LRU5fVkVSU0lPTiBhcmUgc3BlY2lmaWVkIGJ5IGFuIGludGVybmFsIHNjaGVtYSBhbmQgc2hvdWxkIG5vdCBjaGFuZ2VcbiAgICBjb25zdCBUT0tFTl9WRVJTSU9OID0gJzEnO1xuICAgIGNvbnN0IGJhc2U2MmNoYXJzID0gJzAxMjM0NTY3ODlhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaJztcbiAgICAvLyBzZXNzaW9uUmFuZG9taXplciBpcyBhIHJhbmRvbWl6ZWQgMTAtZGlnaXQgYmFzZS02MiBudW1iZXJcbiAgICBsZXQgc2Vzc2lvblJhbmRvbWl6ZXIgPSAnJztcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IDEwOyBpKyspIHtcbiAgICAgICAgc2Vzc2lvblJhbmRvbWl6ZXIgKz0gYmFzZTYyY2hhcnNbTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogNjIpXTtcbiAgICB9XG4gICAgY29uc3QgZXhwaXJhdGlvbiA9IDEyICogNjAgKiA2MCAqIDEwMDA7IC8vIDEyIGhvdXJzXG4gICAgY29uc3QgdG9rZW4gPSBbVE9LRU5fVkVSU0lPTiwgU0tVX0lELCBzZXNzaW9uUmFuZG9taXplcl0uam9pbignJyk7XG4gICAgY29uc3QgdG9rZW5FeHBpcmVzQXQgPSBEYXRlLm5vdygpICsgZXhwaXJhdGlvbjtcblxuICAgIHJldHVybiB7dG9rZW4sIHRva2VuRXhwaXJlc0F0fTtcbn1cblxuZXhwb3J0IHtjcmVhdGVTa3VUb2tlbiwgU0tVX0lEfTtcblxuLyoqKioqIEVORCBXQVJOSU5HIC0gUkVNT1ZBTCBPUiBNT0RJRklDQVRJT04gT0YgVEhFXG5QUkVDRURJTkcgQ09ERSBWSU9MQVRFUyBUSEUgTUFQQk9YIFRFUk1TIE9GIFNFUlZJQ0UgICoqKioqKi9cbiIsIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBVbml0QmV6aWVyO1xuXG5mdW5jdGlvbiBVbml0QmV6aWVyKHAxeCwgcDF5LCBwMngsIHAyeSkge1xuICAgIC8vIENhbGN1bGF0ZSB0aGUgcG9seW5vbWlhbCBjb2VmZmljaWVudHMsIGltcGxpY2l0IGZpcnN0IGFuZCBsYXN0IGNvbnRyb2wgcG9pbnRzIGFyZSAoMCwwKSBhbmQgKDEsMSkuXG4gICAgdGhpcy5jeCA9IDMuMCAqIHAxeDtcbiAgICB0aGlzLmJ4ID0gMy4wICogKHAyeCAtIHAxeCkgLSB0aGlzLmN4O1xuICAgIHRoaXMuYXggPSAxLjAgLSB0aGlzLmN4IC0gdGhpcy5ieDtcblxuICAgIHRoaXMuY3kgPSAzLjAgKiBwMXk7XG4gICAgdGhpcy5ieSA9IDMuMCAqIChwMnkgLSBwMXkpIC0gdGhpcy5jeTtcbiAgICB0aGlzLmF5ID0gMS4wIC0gdGhpcy5jeSAtIHRoaXMuYnk7XG5cbiAgICB0aGlzLnAxeCA9IHAxeDtcbiAgICB0aGlzLnAxeSA9IHAxeTtcbiAgICB0aGlzLnAyeCA9IHAyeDtcbiAgICB0aGlzLnAyeSA9IHAyeTtcbn1cblxuVW5pdEJlemllci5wcm90b3R5cGUgPSB7XG4gICAgc2FtcGxlQ3VydmVYOiBmdW5jdGlvbiAodCkge1xuICAgICAgICAvLyBgYXggdF4zICsgYnggdF4yICsgY3ggdCcgZXhwYW5kZWQgdXNpbmcgSG9ybmVyJ3MgcnVsZS5cbiAgICAgICAgcmV0dXJuICgodGhpcy5heCAqIHQgKyB0aGlzLmJ4KSAqIHQgKyB0aGlzLmN4KSAqIHQ7XG4gICAgfSxcblxuICAgIHNhbXBsZUN1cnZlWTogZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgcmV0dXJuICgodGhpcy5heSAqIHQgKyB0aGlzLmJ5KSAqIHQgKyB0aGlzLmN5KSAqIHQ7XG4gICAgfSxcblxuICAgIHNhbXBsZUN1cnZlRGVyaXZhdGl2ZVg6IGZ1bmN0aW9uICh0KSB7XG4gICAgICAgIHJldHVybiAoMy4wICogdGhpcy5heCAqIHQgKyAyLjAgKiB0aGlzLmJ4KSAqIHQgKyB0aGlzLmN4O1xuICAgIH0sXG5cbiAgICBzb2x2ZUN1cnZlWDogZnVuY3Rpb24gKHgsIGVwc2lsb24pIHtcbiAgICAgICAgaWYgKGVwc2lsb24gPT09IHVuZGVmaW5lZCkgZXBzaWxvbiA9IDFlLTY7XG5cbiAgICAgICAgaWYgKHggPCAwLjApIHJldHVybiAwLjA7XG4gICAgICAgIGlmICh4ID4gMS4wKSByZXR1cm4gMS4wO1xuXG4gICAgICAgIHZhciB0ID0geDtcblxuICAgICAgICAvLyBGaXJzdCB0cnkgYSBmZXcgaXRlcmF0aW9ucyBvZiBOZXd0b24ncyBtZXRob2QgLSBub3JtYWxseSB2ZXJ5IGZhc3QuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgODsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgeDIgPSB0aGlzLnNhbXBsZUN1cnZlWCh0KSAtIHg7XG4gICAgICAgICAgICBpZiAoTWF0aC5hYnMoeDIpIDwgZXBzaWxvbikgcmV0dXJuIHQ7XG5cbiAgICAgICAgICAgIHZhciBkMiA9IHRoaXMuc2FtcGxlQ3VydmVEZXJpdmF0aXZlWCh0KTtcbiAgICAgICAgICAgIGlmIChNYXRoLmFicyhkMikgPCAxZS02KSBicmVhaztcblxuICAgICAgICAgICAgdCA9IHQgLSB4MiAvIGQyO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRmFsbCBiYWNrIHRvIHRoZSBiaXNlY3Rpb24gbWV0aG9kIGZvciByZWxpYWJpbGl0eS5cbiAgICAgICAgdmFyIHQwID0gMC4wO1xuICAgICAgICB2YXIgdDEgPSAxLjA7XG4gICAgICAgIHQgPSB4O1xuXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCAyMDsgaSsrKSB7XG4gICAgICAgICAgICB4MiA9IHRoaXMuc2FtcGxlQ3VydmVYKHQpO1xuICAgICAgICAgICAgaWYgKE1hdGguYWJzKHgyIC0geCkgPCBlcHNpbG9uKSBicmVhaztcblxuICAgICAgICAgICAgaWYgKHggPiB4Mikge1xuICAgICAgICAgICAgICAgIHQwID0gdDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdDEgPSB0O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0ID0gKHQxIC0gdDApICogMC41ICsgdDA7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdDtcbiAgICB9LFxuXG4gICAgc29sdmU6IGZ1bmN0aW9uICh4LCBlcHNpbG9uKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNhbXBsZUN1cnZlWSh0aGlzLnNvbHZlQ3VydmVYKHgsIGVwc2lsb24pKTtcbiAgICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBvaW50O1xuXG4vKipcbiAqIEEgc3RhbmRhbG9uZSBwb2ludCBnZW9tZXRyeSB3aXRoIHVzZWZ1bCBhY2Nlc3NvciwgY29tcGFyaXNvbiwgYW5kXG4gKiBtb2RpZmljYXRpb24gbWV0aG9kcy5cbiAqXG4gKiBAY2xhc3MgUG9pbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSB4IHRoZSB4LWNvb3JkaW5hdGUuIHRoaXMgY291bGQgYmUgbG9uZ2l0dWRlIG9yIHNjcmVlblxuICogcGl4ZWxzLCBvciBhbnkgb3RoZXIgc29ydCBvZiB1bml0LlxuICogQHBhcmFtIHtOdW1iZXJ9IHkgdGhlIHktY29vcmRpbmF0ZS4gdGhpcyBjb3VsZCBiZSBsYXRpdHVkZSBvciBzY3JlZW5cbiAqIHBpeGVscywgb3IgYW55IG90aGVyIHNvcnQgb2YgdW5pdC5cbiAqIEBleGFtcGxlXG4gKiB2YXIgcG9pbnQgPSBuZXcgUG9pbnQoLTc3LCAzOCk7XG4gKi9cbmZ1bmN0aW9uIFBvaW50KHgsIHkpIHtcbiAgICB0aGlzLnggPSB4O1xuICAgIHRoaXMueSA9IHk7XG59XG5cblBvaW50LnByb3RvdHlwZSA9IHtcblxuICAgIC8qKlxuICAgICAqIENsb25lIHRoaXMgcG9pbnQsIHJldHVybmluZyBhIG5ldyBwb2ludCB0aGF0IGNhbiBiZSBtb2RpZmllZFxuICAgICAqIHdpdGhvdXQgYWZmZWN0aW5nIHRoZSBvbGQgb25lLlxuICAgICAqIEByZXR1cm4ge1BvaW50fSB0aGUgY2xvbmVcbiAgICAgKi9cbiAgICBjbG9uZTogZnVuY3Rpb24oKSB7IHJldHVybiBuZXcgUG9pbnQodGhpcy54LCB0aGlzLnkpOyB9LFxuXG4gICAgLyoqXG4gICAgICogQWRkIHRoaXMgcG9pbnQncyB4ICYgeSBjb29yZGluYXRlcyB0byBhbm90aGVyIHBvaW50LFxuICAgICAqIHlpZWxkaW5nIGEgbmV3IHBvaW50LlxuICAgICAqIEBwYXJhbSB7UG9pbnR9IHAgdGhlIG90aGVyIHBvaW50XG4gICAgICogQHJldHVybiB7UG9pbnR9IG91dHB1dCBwb2ludFxuICAgICAqL1xuICAgIGFkZDogICAgIGZ1bmN0aW9uKHApIHsgcmV0dXJuIHRoaXMuY2xvbmUoKS5fYWRkKHApOyB9LFxuXG4gICAgLyoqXG4gICAgICogU3VidHJhY3QgdGhpcyBwb2ludCdzIHggJiB5IGNvb3JkaW5hdGVzIHRvIGZyb20gcG9pbnQsXG4gICAgICogeWllbGRpbmcgYSBuZXcgcG9pbnQuXG4gICAgICogQHBhcmFtIHtQb2ludH0gcCB0aGUgb3RoZXIgcG9pbnRcbiAgICAgKiBAcmV0dXJuIHtQb2ludH0gb3V0cHV0IHBvaW50XG4gICAgICovXG4gICAgc3ViOiAgICAgZnVuY3Rpb24ocCkgeyByZXR1cm4gdGhpcy5jbG9uZSgpLl9zdWIocCk7IH0sXG5cbiAgICAvKipcbiAgICAgKiBNdWx0aXBseSB0aGlzIHBvaW50J3MgeCAmIHkgY29vcmRpbmF0ZXMgYnkgcG9pbnQsXG4gICAgICogeWllbGRpbmcgYSBuZXcgcG9pbnQuXG4gICAgICogQHBhcmFtIHtQb2ludH0gcCB0aGUgb3RoZXIgcG9pbnRcbiAgICAgKiBAcmV0dXJuIHtQb2ludH0gb3V0cHV0IHBvaW50XG4gICAgICovXG4gICAgbXVsdEJ5UG9pbnQ6ICAgIGZ1bmN0aW9uKHApIHsgcmV0dXJuIHRoaXMuY2xvbmUoKS5fbXVsdEJ5UG9pbnQocCk7IH0sXG5cbiAgICAvKipcbiAgICAgKiBEaXZpZGUgdGhpcyBwb2ludCdzIHggJiB5IGNvb3JkaW5hdGVzIGJ5IHBvaW50LFxuICAgICAqIHlpZWxkaW5nIGEgbmV3IHBvaW50LlxuICAgICAqIEBwYXJhbSB7UG9pbnR9IHAgdGhlIG90aGVyIHBvaW50XG4gICAgICogQHJldHVybiB7UG9pbnR9IG91dHB1dCBwb2ludFxuICAgICAqL1xuICAgIGRpdkJ5UG9pbnQ6ICAgICBmdW5jdGlvbihwKSB7IHJldHVybiB0aGlzLmNsb25lKCkuX2RpdkJ5UG9pbnQocCk7IH0sXG5cbiAgICAvKipcbiAgICAgKiBNdWx0aXBseSB0aGlzIHBvaW50J3MgeCAmIHkgY29vcmRpbmF0ZXMgYnkgYSBmYWN0b3IsXG4gICAgICogeWllbGRpbmcgYSBuZXcgcG9pbnQuXG4gICAgICogQHBhcmFtIHtQb2ludH0gayBmYWN0b3JcbiAgICAgKiBAcmV0dXJuIHtQb2ludH0gb3V0cHV0IHBvaW50XG4gICAgICovXG4gICAgbXVsdDogICAgZnVuY3Rpb24oaykgeyByZXR1cm4gdGhpcy5jbG9uZSgpLl9tdWx0KGspOyB9LFxuXG4gICAgLyoqXG4gICAgICogRGl2aWRlIHRoaXMgcG9pbnQncyB4ICYgeSBjb29yZGluYXRlcyBieSBhIGZhY3RvcixcbiAgICAgKiB5aWVsZGluZyBhIG5ldyBwb2ludC5cbiAgICAgKiBAcGFyYW0ge1BvaW50fSBrIGZhY3RvclxuICAgICAqIEByZXR1cm4ge1BvaW50fSBvdXRwdXQgcG9pbnRcbiAgICAgKi9cbiAgICBkaXY6ICAgICBmdW5jdGlvbihrKSB7IHJldHVybiB0aGlzLmNsb25lKCkuX2RpdihrKTsgfSxcblxuICAgIC8qKlxuICAgICAqIFJvdGF0ZSB0aGlzIHBvaW50IGFyb3VuZCB0aGUgMCwgMCBvcmlnaW4gYnkgYW4gYW5nbGUgYSxcbiAgICAgKiBnaXZlbiBpbiByYWRpYW5zXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGEgYW5nbGUgdG8gcm90YXRlIGFyb3VuZCwgaW4gcmFkaWFuc1xuICAgICAqIEByZXR1cm4ge1BvaW50fSBvdXRwdXQgcG9pbnRcbiAgICAgKi9cbiAgICByb3RhdGU6ICBmdW5jdGlvbihhKSB7IHJldHVybiB0aGlzLmNsb25lKCkuX3JvdGF0ZShhKTsgfSxcblxuICAgIC8qKlxuICAgICAqIFJvdGF0ZSB0aGlzIHBvaW50IGFyb3VuZCBwIHBvaW50IGJ5IGFuIGFuZ2xlIGEsXG4gICAgICogZ2l2ZW4gaW4gcmFkaWFuc1xuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBhIGFuZ2xlIHRvIHJvdGF0ZSBhcm91bmQsIGluIHJhZGlhbnNcbiAgICAgKiBAcGFyYW0ge1BvaW50fSBwIFBvaW50IHRvIHJvdGF0ZSBhcm91bmRcbiAgICAgKiBAcmV0dXJuIHtQb2ludH0gb3V0cHV0IHBvaW50XG4gICAgICovXG4gICAgcm90YXRlQXJvdW5kOiAgZnVuY3Rpb24oYSxwKSB7IHJldHVybiB0aGlzLmNsb25lKCkuX3JvdGF0ZUFyb3VuZChhLHApOyB9LFxuXG4gICAgLyoqXG4gICAgICogTXVsdGlwbHkgdGhpcyBwb2ludCBieSBhIDR4MSB0cmFuc2Zvcm1hdGlvbiBtYXRyaXhcbiAgICAgKiBAcGFyYW0ge0FycmF5PE51bWJlcj59IG0gdHJhbnNmb3JtYXRpb24gbWF0cml4XG4gICAgICogQHJldHVybiB7UG9pbnR9IG91dHB1dCBwb2ludFxuICAgICAqL1xuICAgIG1hdE11bHQ6IGZ1bmN0aW9uKG0pIHsgcmV0dXJuIHRoaXMuY2xvbmUoKS5fbWF0TXVsdChtKTsgfSxcblxuICAgIC8qKlxuICAgICAqIENhbGN1bGF0ZSB0aGlzIHBvaW50IGJ1dCBhcyBhIHVuaXQgdmVjdG9yIGZyb20gMCwgMCwgbWVhbmluZ1xuICAgICAqIHRoYXQgdGhlIGRpc3RhbmNlIGZyb20gdGhlIHJlc3VsdGluZyBwb2ludCB0byB0aGUgMCwgMFxuICAgICAqIGNvb3JkaW5hdGUgd2lsbCBiZSBlcXVhbCB0byAxIGFuZCB0aGUgYW5nbGUgZnJvbSB0aGUgcmVzdWx0aW5nXG4gICAgICogcG9pbnQgdG8gdGhlIDAsIDAgY29vcmRpbmF0ZSB3aWxsIGJlIHRoZSBzYW1lIGFzIGJlZm9yZS5cbiAgICAgKiBAcmV0dXJuIHtQb2ludH0gdW5pdCB2ZWN0b3IgcG9pbnRcbiAgICAgKi9cbiAgICB1bml0OiAgICBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXMuY2xvbmUoKS5fdW5pdCgpOyB9LFxuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZSBhIHBlcnBlbmRpY3VsYXIgcG9pbnQsIHdoZXJlIHRoZSBuZXcgeSBjb29yZGluYXRlXG4gICAgICogaXMgdGhlIG9sZCB4IGNvb3JkaW5hdGUgYW5kIHRoZSBuZXcgeCBjb29yZGluYXRlIGlzIHRoZSBvbGQgeVxuICAgICAqIGNvb3JkaW5hdGUgbXVsdGlwbGllZCBieSAtMVxuICAgICAqIEByZXR1cm4ge1BvaW50fSBwZXJwZW5kaWN1bGFyIHBvaW50XG4gICAgICovXG4gICAgcGVycDogICAgZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzLmNsb25lKCkuX3BlcnAoKTsgfSxcblxuICAgIC8qKlxuICAgICAqIFJldHVybiBhIHZlcnNpb24gb2YgdGhpcyBwb2ludCB3aXRoIHRoZSB4ICYgeSBjb29yZGluYXRlc1xuICAgICAqIHJvdW5kZWQgdG8gaW50ZWdlcnMuXG4gICAgICogQHJldHVybiB7UG9pbnR9IHJvdW5kZWQgcG9pbnRcbiAgICAgKi9cbiAgICByb3VuZDogICBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXMuY2xvbmUoKS5fcm91bmQoKTsgfSxcblxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgbWFnaXR1ZGUgb2YgdGhpcyBwb2ludDogdGhpcyBpcyB0aGUgRXVjbGlkZWFuXG4gICAgICogZGlzdGFuY2UgZnJvbSB0aGUgMCwgMCBjb29yZGluYXRlIHRvIHRoaXMgcG9pbnQncyB4IGFuZCB5XG4gICAgICogY29vcmRpbmF0ZXMuXG4gICAgICogQHJldHVybiB7TnVtYmVyfSBtYWduaXR1ZGVcbiAgICAgKi9cbiAgICBtYWc6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gTWF0aC5zcXJ0KHRoaXMueCAqIHRoaXMueCArIHRoaXMueSAqIHRoaXMueSk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEp1ZGdlIHdoZXRoZXIgdGhpcyBwb2ludCBpcyBlcXVhbCB0byBhbm90aGVyIHBvaW50LCByZXR1cm5pbmdcbiAgICAgKiB0cnVlIG9yIGZhbHNlLlxuICAgICAqIEBwYXJhbSB7UG9pbnR9IG90aGVyIHRoZSBvdGhlciBwb2ludFxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59IHdoZXRoZXIgdGhlIHBvaW50cyBhcmUgZXF1YWxcbiAgICAgKi9cbiAgICBlcXVhbHM6IGZ1bmN0aW9uKG90aGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnggPT09IG90aGVyLnggJiZcbiAgICAgICAgICAgICAgIHRoaXMueSA9PT0gb3RoZXIueTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlIHRoZSBkaXN0YW5jZSBmcm9tIHRoaXMgcG9pbnQgdG8gYW5vdGhlciBwb2ludFxuICAgICAqIEBwYXJhbSB7UG9pbnR9IHAgdGhlIG90aGVyIHBvaW50XG4gICAgICogQHJldHVybiB7TnVtYmVyfSBkaXN0YW5jZVxuICAgICAqL1xuICAgIGRpc3Q6IGZ1bmN0aW9uKHApIHtcbiAgICAgICAgcmV0dXJuIE1hdGguc3FydCh0aGlzLmRpc3RTcXIocCkpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDYWxjdWxhdGUgdGhlIGRpc3RhbmNlIGZyb20gdGhpcyBwb2ludCB0byBhbm90aGVyIHBvaW50LFxuICAgICAqIHdpdGhvdXQgdGhlIHNxdWFyZSByb290IHN0ZXAuIFVzZWZ1bCBpZiB5b3UncmUgY29tcGFyaW5nXG4gICAgICogcmVsYXRpdmUgZGlzdGFuY2VzLlxuICAgICAqIEBwYXJhbSB7UG9pbnR9IHAgdGhlIG90aGVyIHBvaW50XG4gICAgICogQHJldHVybiB7TnVtYmVyfSBkaXN0YW5jZVxuICAgICAqL1xuICAgIGRpc3RTcXI6IGZ1bmN0aW9uKHApIHtcbiAgICAgICAgdmFyIGR4ID0gcC54IC0gdGhpcy54LFxuICAgICAgICAgICAgZHkgPSBwLnkgLSB0aGlzLnk7XG4gICAgICAgIHJldHVybiBkeCAqIGR4ICsgZHkgKiBkeTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBhbmdsZSBmcm9tIHRoZSAwLCAwIGNvb3JkaW5hdGUgdG8gdGhpcyBwb2ludCwgaW4gcmFkaWFuc1xuICAgICAqIGNvb3JkaW5hdGVzLlxuICAgICAqIEByZXR1cm4ge051bWJlcn0gYW5nbGVcbiAgICAgKi9cbiAgICBhbmdsZTogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBNYXRoLmF0YW4yKHRoaXMueSwgdGhpcy54KTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBhbmdsZSBmcm9tIHRoaXMgcG9pbnQgdG8gYW5vdGhlciBwb2ludCwgaW4gcmFkaWFuc1xuICAgICAqIEBwYXJhbSB7UG9pbnR9IGIgdGhlIG90aGVyIHBvaW50XG4gICAgICogQHJldHVybiB7TnVtYmVyfSBhbmdsZVxuICAgICAqL1xuICAgIGFuZ2xlVG86IGZ1bmN0aW9uKGIpIHtcbiAgICAgICAgcmV0dXJuIE1hdGguYXRhbjIodGhpcy55IC0gYi55LCB0aGlzLnggLSBiLngpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGFuZ2xlIGJldHdlZW4gdGhpcyBwb2ludCBhbmQgYW5vdGhlciBwb2ludCwgaW4gcmFkaWFuc1xuICAgICAqIEBwYXJhbSB7UG9pbnR9IGIgdGhlIG90aGVyIHBvaW50XG4gICAgICogQHJldHVybiB7TnVtYmVyfSBhbmdsZVxuICAgICAqL1xuICAgIGFuZ2xlV2l0aDogZnVuY3Rpb24oYikge1xuICAgICAgICByZXR1cm4gdGhpcy5hbmdsZVdpdGhTZXAoYi54LCBiLnkpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIEZpbmQgdGhlIGFuZ2xlIG9mIHRoZSB0d28gdmVjdG9ycywgc29sdmluZyB0aGUgZm9ybXVsYSBmb3JcbiAgICAgKiB0aGUgY3Jvc3MgcHJvZHVjdCBhIHggYiA9IHxhfHxifHNpbijOuCkgZm9yIM64LlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IHRoZSB4LWNvb3JkaW5hdGVcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geSB0aGUgeS1jb29yZGluYXRlXG4gICAgICogQHJldHVybiB7TnVtYmVyfSB0aGUgYW5nbGUgaW4gcmFkaWFuc1xuICAgICAqL1xuICAgIGFuZ2xlV2l0aFNlcDogZnVuY3Rpb24oeCwgeSkge1xuICAgICAgICByZXR1cm4gTWF0aC5hdGFuMihcbiAgICAgICAgICAgIHRoaXMueCAqIHkgLSB0aGlzLnkgKiB4LFxuICAgICAgICAgICAgdGhpcy54ICogeCArIHRoaXMueSAqIHkpO1xuICAgIH0sXG5cbiAgICBfbWF0TXVsdDogZnVuY3Rpb24obSkge1xuICAgICAgICB2YXIgeCA9IG1bMF0gKiB0aGlzLnggKyBtWzFdICogdGhpcy55LFxuICAgICAgICAgICAgeSA9IG1bMl0gKiB0aGlzLnggKyBtWzNdICogdGhpcy55O1xuICAgICAgICB0aGlzLnggPSB4O1xuICAgICAgICB0aGlzLnkgPSB5O1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgX2FkZDogZnVuY3Rpb24ocCkge1xuICAgICAgICB0aGlzLnggKz0gcC54O1xuICAgICAgICB0aGlzLnkgKz0gcC55O1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgX3N1YjogZnVuY3Rpb24ocCkge1xuICAgICAgICB0aGlzLnggLT0gcC54O1xuICAgICAgICB0aGlzLnkgLT0gcC55O1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgX211bHQ6IGZ1bmN0aW9uKGspIHtcbiAgICAgICAgdGhpcy54ICo9IGs7XG4gICAgICAgIHRoaXMueSAqPSBrO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgX2RpdjogZnVuY3Rpb24oaykge1xuICAgICAgICB0aGlzLnggLz0gaztcbiAgICAgICAgdGhpcy55IC89IGs7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBfbXVsdEJ5UG9pbnQ6IGZ1bmN0aW9uKHApIHtcbiAgICAgICAgdGhpcy54ICo9IHAueDtcbiAgICAgICAgdGhpcy55ICo9IHAueTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIF9kaXZCeVBvaW50OiBmdW5jdGlvbihwKSB7XG4gICAgICAgIHRoaXMueCAvPSBwLng7XG4gICAgICAgIHRoaXMueSAvPSBwLnk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBfdW5pdDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHRoaXMuX2Rpdih0aGlzLm1hZygpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIF9wZXJwOiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIHkgPSB0aGlzLnk7XG4gICAgICAgIHRoaXMueSA9IHRoaXMueDtcbiAgICAgICAgdGhpcy54ID0gLXk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBfcm90YXRlOiBmdW5jdGlvbihhbmdsZSkge1xuICAgICAgICB2YXIgY29zID0gTWF0aC5jb3MoYW5nbGUpLFxuICAgICAgICAgICAgc2luID0gTWF0aC5zaW4oYW5nbGUpLFxuICAgICAgICAgICAgeCA9IGNvcyAqIHRoaXMueCAtIHNpbiAqIHRoaXMueSxcbiAgICAgICAgICAgIHkgPSBzaW4gKiB0aGlzLnggKyBjb3MgKiB0aGlzLnk7XG4gICAgICAgIHRoaXMueCA9IHg7XG4gICAgICAgIHRoaXMueSA9IHk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBfcm90YXRlQXJvdW5kOiBmdW5jdGlvbihhbmdsZSwgcCkge1xuICAgICAgICB2YXIgY29zID0gTWF0aC5jb3MoYW5nbGUpLFxuICAgICAgICAgICAgc2luID0gTWF0aC5zaW4oYW5nbGUpLFxuICAgICAgICAgICAgeCA9IHAueCArIGNvcyAqICh0aGlzLnggLSBwLngpIC0gc2luICogKHRoaXMueSAtIHAueSksXG4gICAgICAgICAgICB5ID0gcC55ICsgc2luICogKHRoaXMueCAtIHAueCkgKyBjb3MgKiAodGhpcy55IC0gcC55KTtcbiAgICAgICAgdGhpcy54ID0geDtcbiAgICAgICAgdGhpcy55ID0geTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIF9yb3VuZDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHRoaXMueCA9IE1hdGgucm91bmQodGhpcy54KTtcbiAgICAgICAgdGhpcy55ID0gTWF0aC5yb3VuZCh0aGlzLnkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59O1xuXG4vKipcbiAqIENvbnN0cnVjdCBhIHBvaW50IGZyb20gYW4gYXJyYXkgaWYgbmVjZXNzYXJ5LCBvdGhlcndpc2UgaWYgdGhlIGlucHV0XG4gKiBpcyBhbHJlYWR5IGEgUG9pbnQsIG9yIGFuIHVua25vd24gdHlwZSwgcmV0dXJuIGl0IHVuY2hhbmdlZFxuICogQHBhcmFtIHtBcnJheTxOdW1iZXI+fFBvaW50fCp9IGEgYW55IGtpbmQgb2YgaW5wdXQgdmFsdWVcbiAqIEByZXR1cm4ge1BvaW50fSBjb25zdHJ1Y3RlZCBwb2ludCwgb3IgcGFzc2VkLXRocm91Z2ggdmFsdWUuXG4gKiBAZXhhbXBsZVxuICogLy8gdGhpc1xuICogdmFyIHBvaW50ID0gUG9pbnQuY29udmVydChbMCwgMV0pO1xuICogLy8gaXMgZXF1aXZhbGVudCB0b1xuICogdmFyIHBvaW50ID0gbmV3IFBvaW50KDAsIDEpO1xuICovXG5Qb2ludC5jb252ZXJ0ID0gZnVuY3Rpb24gKGEpIHtcbiAgICBpZiAoYSBpbnN0YW5jZW9mIFBvaW50KSB7XG4gICAgICAgIHJldHVybiBhO1xuICAgIH1cbiAgICBpZiAoQXJyYXkuaXNBcnJheShhKSkge1xuICAgICAgICByZXR1cm4gbmV3IFBvaW50KGFbMF0sIGFbMV0pO1xuICAgIH1cbiAgICByZXR1cm4gYTtcbn07XG4iLCIvKlxub2JqZWN0LWFzc2lnblxuKGMpIFNpbmRyZSBTb3JodXNcbkBsaWNlbnNlIE1JVFxuKi9cblxuJ3VzZSBzdHJpY3QnO1xuLyogZXNsaW50LWRpc2FibGUgbm8tdW51c2VkLXZhcnMgKi9cbnZhciBnZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzO1xudmFyIGhhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciBwcm9wSXNFbnVtZXJhYmxlID0gT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcblxuZnVuY3Rpb24gdG9PYmplY3QodmFsKSB7XG5cdGlmICh2YWwgPT09IG51bGwgfHwgdmFsID09PSB1bmRlZmluZWQpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdPYmplY3QuYXNzaWduIGNhbm5vdCBiZSBjYWxsZWQgd2l0aCBudWxsIG9yIHVuZGVmaW5lZCcpO1xuXHR9XG5cblx0cmV0dXJuIE9iamVjdCh2YWwpO1xufVxuXG5mdW5jdGlvbiBzaG91bGRVc2VOYXRpdmUoKSB7XG5cdHRyeSB7XG5cdFx0aWYgKCFPYmplY3QuYXNzaWduKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gRGV0ZWN0IGJ1Z2d5IHByb3BlcnR5IGVudW1lcmF0aW9uIG9yZGVyIGluIG9sZGVyIFY4IHZlcnNpb25zLlxuXG5cdFx0Ly8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9NDExOFxuXHRcdHZhciB0ZXN0MSA9IG5ldyBTdHJpbmcoJ2FiYycpOyAgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXctd3JhcHBlcnNcblx0XHR0ZXN0MVs1XSA9ICdkZSc7XG5cdFx0aWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRlc3QxKVswXSA9PT0gJzUnKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzA1NlxuXHRcdHZhciB0ZXN0MiA9IHt9O1xuXHRcdGZvciAodmFyIGkgPSAwOyBpIDwgMTA7IGkrKykge1xuXHRcdFx0dGVzdDJbJ18nICsgU3RyaW5nLmZyb21DaGFyQ29kZShpKV0gPSBpO1xuXHRcdH1cblx0XHR2YXIgb3JkZXIyID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModGVzdDIpLm1hcChmdW5jdGlvbiAobikge1xuXHRcdFx0cmV0dXJuIHRlc3QyW25dO1xuXHRcdH0pO1xuXHRcdGlmIChvcmRlcjIuam9pbignJykgIT09ICcwMTIzNDU2Nzg5Jykge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdC8vIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTMwNTZcblx0XHR2YXIgdGVzdDMgPSB7fTtcblx0XHQnYWJjZGVmZ2hpamtsbW5vcHFyc3QnLnNwbGl0KCcnKS5mb3JFYWNoKGZ1bmN0aW9uIChsZXR0ZXIpIHtcblx0XHRcdHRlc3QzW2xldHRlcl0gPSBsZXR0ZXI7XG5cdFx0fSk7XG5cdFx0aWYgKE9iamVjdC5rZXlzKE9iamVjdC5hc3NpZ24oe30sIHRlc3QzKSkuam9pbignJykgIT09XG5cdFx0XHRcdCdhYmNkZWZnaGlqa2xtbm9wcXJzdCcpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fSBjYXRjaCAoZXJyKSB7XG5cdFx0Ly8gV2UgZG9uJ3QgZXhwZWN0IGFueSBvZiB0aGUgYWJvdmUgdG8gdGhyb3csIGJ1dCBiZXR0ZXIgdG8gYmUgc2FmZS5cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzaG91bGRVc2VOYXRpdmUoKSA/IE9iamVjdC5hc3NpZ24gOiBmdW5jdGlvbiAodGFyZ2V0LCBzb3VyY2UpIHtcblx0dmFyIGZyb207XG5cdHZhciB0byA9IHRvT2JqZWN0KHRhcmdldCk7XG5cdHZhciBzeW1ib2xzO1xuXG5cdGZvciAodmFyIHMgPSAxOyBzIDwgYXJndW1lbnRzLmxlbmd0aDsgcysrKSB7XG5cdFx0ZnJvbSA9IE9iamVjdChhcmd1bWVudHNbc10pO1xuXG5cdFx0Zm9yICh2YXIga2V5IGluIGZyb20pIHtcblx0XHRcdGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKGZyb20sIGtleSkpIHtcblx0XHRcdFx0dG9ba2V5XSA9IGZyb21ba2V5XTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoZ2V0T3duUHJvcGVydHlTeW1ib2xzKSB7XG5cdFx0XHRzeW1ib2xzID0gZ2V0T3duUHJvcGVydHlTeW1ib2xzKGZyb20pO1xuXHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBzeW1ib2xzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdGlmIChwcm9wSXNFbnVtZXJhYmxlLmNhbGwoZnJvbSwgc3ltYm9sc1tpXSkpIHtcblx0XHRcdFx0XHR0b1tzeW1ib2xzW2ldXSA9IGZyb21bc3ltYm9sc1tpXV07XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gdG87XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc0J1ZmZlcihhcmcpIHtcbiAgcmV0dXJuIGFyZyAmJiB0eXBlb2YgYXJnID09PSAnb2JqZWN0J1xuICAgICYmIHR5cGVvZiBhcmcuY29weSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICYmIHR5cGVvZiBhcmcuZmlsbCA9PT0gJ2Z1bmN0aW9uJ1xuICAgICYmIHR5cGVvZiBhcmcucmVhZFVJbnQ4ID09PSAnZnVuY3Rpb24nO1xufSIsImlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAvLyBpbXBsZW1lbnRhdGlvbiBmcm9tIHN0YW5kYXJkIG5vZGUuanMgJ3V0aWwnIG1vZHVsZVxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgY3Rvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ3Rvci5wcm90b3R5cGUsIHtcbiAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgIHZhbHVlOiBjdG9yLFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgfVxuICAgIH0pO1xuICB9O1xufSBlbHNlIHtcbiAgLy8gb2xkIHNjaG9vbCBzaGltIGZvciBvbGQgYnJvd3NlcnNcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgIHZhciBUZW1wQ3RvciA9IGZ1bmN0aW9uICgpIHt9XG4gICAgVGVtcEN0b3IucHJvdG90eXBlID0gc3VwZXJDdG9yLnByb3RvdHlwZVxuICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKClcbiAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3JcbiAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbnZhciBmb3JtYXRSZWdFeHAgPSAvJVtzZGolXS9nO1xuZXhwb3J0cy5mb3JtYXQgPSBmdW5jdGlvbihmKSB7XG4gIGlmICghaXNTdHJpbmcoZikpIHtcbiAgICB2YXIgb2JqZWN0cyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBvYmplY3RzLnB1c2goaW5zcGVjdChhcmd1bWVudHNbaV0pKTtcbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdHMuam9pbignICcpO1xuICB9XG5cbiAgdmFyIGkgPSAxO1xuICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgdmFyIGxlbiA9IGFyZ3MubGVuZ3RoO1xuICB2YXIgc3RyID0gU3RyaW5nKGYpLnJlcGxhY2UoZm9ybWF0UmVnRXhwLCBmdW5jdGlvbih4KSB7XG4gICAgaWYgKHggPT09ICclJScpIHJldHVybiAnJSc7XG4gICAgaWYgKGkgPj0gbGVuKSByZXR1cm4geDtcbiAgICBzd2l0Y2ggKHgpIHtcbiAgICAgIGNhc2UgJyVzJzogcmV0dXJuIFN0cmluZyhhcmdzW2krK10pO1xuICAgICAgY2FzZSAnJWQnOiByZXR1cm4gTnVtYmVyKGFyZ3NbaSsrXSk7XG4gICAgICBjYXNlICclaic6XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGFyZ3NbaSsrXSk7XG4gICAgICAgIH0gY2F0Y2ggKF8pIHtcbiAgICAgICAgICByZXR1cm4gJ1tDaXJjdWxhcl0nO1xuICAgICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4geDtcbiAgICB9XG4gIH0pO1xuICBmb3IgKHZhciB4ID0gYXJnc1tpXTsgaSA8IGxlbjsgeCA9IGFyZ3NbKytpXSkge1xuICAgIGlmIChpc051bGwoeCkgfHwgIWlzT2JqZWN0KHgpKSB7XG4gICAgICBzdHIgKz0gJyAnICsgeDtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RyICs9ICcgJyArIGluc3BlY3QoeCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBzdHI7XG59O1xuXG5cbi8vIE1hcmsgdGhhdCBhIG1ldGhvZCBzaG91bGQgbm90IGJlIHVzZWQuXG4vLyBSZXR1cm5zIGEgbW9kaWZpZWQgZnVuY3Rpb24gd2hpY2ggd2FybnMgb25jZSBieSBkZWZhdWx0LlxuLy8gSWYgLS1uby1kZXByZWNhdGlvbiBpcyBzZXQsIHRoZW4gaXQgaXMgYSBuby1vcC5cbmV4cG9ydHMuZGVwcmVjYXRlID0gZnVuY3Rpb24oZm4sIG1zZykge1xuICAvLyBBbGxvdyBmb3IgZGVwcmVjYXRpbmcgdGhpbmdzIGluIHRoZSBwcm9jZXNzIG9mIHN0YXJ0aW5nIHVwLlxuICBpZiAoaXNVbmRlZmluZWQoZ2xvYmFsLnByb2Nlc3MpKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGV4cG9ydHMuZGVwcmVjYXRlKGZuLCBtc2cpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfTtcbiAgfVxuXG4gIGlmIChwcm9jZXNzLm5vRGVwcmVjYXRpb24gPT09IHRydWUpIHtcbiAgICByZXR1cm4gZm47XG4gIH1cblxuICB2YXIgd2FybmVkID0gZmFsc2U7XG4gIGZ1bmN0aW9uIGRlcHJlY2F0ZWQoKSB7XG4gICAgaWYgKCF3YXJuZWQpIHtcbiAgICAgIGlmIChwcm9jZXNzLnRocm93RGVwcmVjYXRpb24pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG4gICAgICB9IGVsc2UgaWYgKHByb2Nlc3MudHJhY2VEZXByZWNhdGlvbikge1xuICAgICAgICBjb25zb2xlLnRyYWNlKG1zZyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLmVycm9yKG1zZyk7XG4gICAgICB9XG4gICAgICB3YXJuZWQgPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIHJldHVybiBkZXByZWNhdGVkO1xufTtcblxuXG52YXIgZGVidWdzID0ge307XG52YXIgZGVidWdFbnZpcm9uO1xuZXhwb3J0cy5kZWJ1Z2xvZyA9IGZ1bmN0aW9uKHNldCkge1xuICBpZiAoaXNVbmRlZmluZWQoZGVidWdFbnZpcm9uKSlcbiAgICBkZWJ1Z0Vudmlyb24gPSBwcm9jZXNzLmVudi5OT0RFX0RFQlVHIHx8ICcnO1xuICBzZXQgPSBzZXQudG9VcHBlckNhc2UoKTtcbiAgaWYgKCFkZWJ1Z3Nbc2V0XSkge1xuICAgIGlmIChuZXcgUmVnRXhwKCdcXFxcYicgKyBzZXQgKyAnXFxcXGInLCAnaScpLnRlc3QoZGVidWdFbnZpcm9uKSkge1xuICAgICAgdmFyIHBpZCA9IHByb2Nlc3MucGlkO1xuICAgICAgZGVidWdzW3NldF0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIG1zZyA9IGV4cG9ydHMuZm9ybWF0LmFwcGx5KGV4cG9ydHMsIGFyZ3VtZW50cyk7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJyVzICVkOiAlcycsIHNldCwgcGlkLCBtc2cpO1xuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGVidWdzW3NldF0gPSBmdW5jdGlvbigpIHt9O1xuICAgIH1cbiAgfVxuICByZXR1cm4gZGVidWdzW3NldF07XG59O1xuXG5cbi8qKlxuICogRWNob3MgdGhlIHZhbHVlIG9mIGEgdmFsdWUuIFRyeXMgdG8gcHJpbnQgdGhlIHZhbHVlIG91dFxuICogaW4gdGhlIGJlc3Qgd2F5IHBvc3NpYmxlIGdpdmVuIHRoZSBkaWZmZXJlbnQgdHlwZXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iaiBUaGUgb2JqZWN0IHRvIHByaW50IG91dC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIE9wdGlvbmFsIG9wdGlvbnMgb2JqZWN0IHRoYXQgYWx0ZXJzIHRoZSBvdXRwdXQuXG4gKi9cbi8qIGxlZ2FjeTogb2JqLCBzaG93SGlkZGVuLCBkZXB0aCwgY29sb3JzKi9cbmZ1bmN0aW9uIGluc3BlY3Qob2JqLCBvcHRzKSB7XG4gIC8vIGRlZmF1bHQgb3B0aW9uc1xuICB2YXIgY3R4ID0ge1xuICAgIHNlZW46IFtdLFxuICAgIHN0eWxpemU6IHN0eWxpemVOb0NvbG9yXG4gIH07XG4gIC8vIGxlZ2FjeS4uLlxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSAzKSBjdHguZGVwdGggPSBhcmd1bWVudHNbMl07XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDQpIGN0eC5jb2xvcnMgPSBhcmd1bWVudHNbM107XG4gIGlmIChpc0Jvb2xlYW4ob3B0cykpIHtcbiAgICAvLyBsZWdhY3kuLi5cbiAgICBjdHguc2hvd0hpZGRlbiA9IG9wdHM7XG4gIH0gZWxzZSBpZiAob3B0cykge1xuICAgIC8vIGdvdCBhbiBcIm9wdGlvbnNcIiBvYmplY3RcbiAgICBleHBvcnRzLl9leHRlbmQoY3R4LCBvcHRzKTtcbiAgfVxuICAvLyBzZXQgZGVmYXVsdCBvcHRpb25zXG4gIGlmIChpc1VuZGVmaW5lZChjdHguc2hvd0hpZGRlbikpIGN0eC5zaG93SGlkZGVuID0gZmFsc2U7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguZGVwdGgpKSBjdHguZGVwdGggPSAyO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmNvbG9ycykpIGN0eC5jb2xvcnMgPSBmYWxzZTtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5jdXN0b21JbnNwZWN0KSkgY3R4LmN1c3RvbUluc3BlY3QgPSB0cnVlO1xuICBpZiAoY3R4LmNvbG9ycykgY3R4LnN0eWxpemUgPSBzdHlsaXplV2l0aENvbG9yO1xuICByZXR1cm4gZm9ybWF0VmFsdWUoY3R4LCBvYmosIGN0eC5kZXB0aCk7XG59XG5leHBvcnRzLmluc3BlY3QgPSBpbnNwZWN0O1xuXG5cbi8vIGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQU5TSV9lc2NhcGVfY29kZSNncmFwaGljc1xuaW5zcGVjdC5jb2xvcnMgPSB7XG4gICdib2xkJyA6IFsxLCAyMl0sXG4gICdpdGFsaWMnIDogWzMsIDIzXSxcbiAgJ3VuZGVybGluZScgOiBbNCwgMjRdLFxuICAnaW52ZXJzZScgOiBbNywgMjddLFxuICAnd2hpdGUnIDogWzM3LCAzOV0sXG4gICdncmV5JyA6IFs5MCwgMzldLFxuICAnYmxhY2snIDogWzMwLCAzOV0sXG4gICdibHVlJyA6IFszNCwgMzldLFxuICAnY3lhbicgOiBbMzYsIDM5XSxcbiAgJ2dyZWVuJyA6IFszMiwgMzldLFxuICAnbWFnZW50YScgOiBbMzUsIDM5XSxcbiAgJ3JlZCcgOiBbMzEsIDM5XSxcbiAgJ3llbGxvdycgOiBbMzMsIDM5XVxufTtcblxuLy8gRG9uJ3QgdXNlICdibHVlJyBub3QgdmlzaWJsZSBvbiBjbWQuZXhlXG5pbnNwZWN0LnN0eWxlcyA9IHtcbiAgJ3NwZWNpYWwnOiAnY3lhbicsXG4gICdudW1iZXInOiAneWVsbG93JyxcbiAgJ2Jvb2xlYW4nOiAneWVsbG93JyxcbiAgJ3VuZGVmaW5lZCc6ICdncmV5JyxcbiAgJ251bGwnOiAnYm9sZCcsXG4gICdzdHJpbmcnOiAnZ3JlZW4nLFxuICAnZGF0ZSc6ICdtYWdlbnRhJyxcbiAgLy8gXCJuYW1lXCI6IGludGVudGlvbmFsbHkgbm90IHN0eWxpbmdcbiAgJ3JlZ2V4cCc6ICdyZWQnXG59O1xuXG5cbmZ1bmN0aW9uIHN0eWxpemVXaXRoQ29sb3Ioc3RyLCBzdHlsZVR5cGUpIHtcbiAgdmFyIHN0eWxlID0gaW5zcGVjdC5zdHlsZXNbc3R5bGVUeXBlXTtcblxuICBpZiAoc3R5bGUpIHtcbiAgICByZXR1cm4gJ1xcdTAwMWJbJyArIGluc3BlY3QuY29sb3JzW3N0eWxlXVswXSArICdtJyArIHN0ciArXG4gICAgICAgICAgICdcXHUwMDFiWycgKyBpbnNwZWN0LmNvbG9yc1tzdHlsZV1bMV0gKyAnbSc7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIHN0eWxpemVOb0NvbG9yKHN0ciwgc3R5bGVUeXBlKSB7XG4gIHJldHVybiBzdHI7XG59XG5cblxuZnVuY3Rpb24gYXJyYXlUb0hhc2goYXJyYXkpIHtcbiAgdmFyIGhhc2ggPSB7fTtcblxuICBhcnJheS5mb3JFYWNoKGZ1bmN0aW9uKHZhbCwgaWR4KSB7XG4gICAgaGFzaFt2YWxdID0gdHJ1ZTtcbiAgfSk7XG5cbiAgcmV0dXJuIGhhc2g7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0VmFsdWUoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzKSB7XG4gIC8vIFByb3ZpZGUgYSBob29rIGZvciB1c2VyLXNwZWNpZmllZCBpbnNwZWN0IGZ1bmN0aW9ucy5cbiAgLy8gQ2hlY2sgdGhhdCB2YWx1ZSBpcyBhbiBvYmplY3Qgd2l0aCBhbiBpbnNwZWN0IGZ1bmN0aW9uIG9uIGl0XG4gIGlmIChjdHguY3VzdG9tSW5zcGVjdCAmJlxuICAgICAgdmFsdWUgJiZcbiAgICAgIGlzRnVuY3Rpb24odmFsdWUuaW5zcGVjdCkgJiZcbiAgICAgIC8vIEZpbHRlciBvdXQgdGhlIHV0aWwgbW9kdWxlLCBpdCdzIGluc3BlY3QgZnVuY3Rpb24gaXMgc3BlY2lhbFxuICAgICAgdmFsdWUuaW5zcGVjdCAhPT0gZXhwb3J0cy5pbnNwZWN0ICYmXG4gICAgICAvLyBBbHNvIGZpbHRlciBvdXQgYW55IHByb3RvdHlwZSBvYmplY3RzIHVzaW5nIHRoZSBjaXJjdWxhciBjaGVjay5cbiAgICAgICEodmFsdWUuY29uc3RydWN0b3IgJiYgdmFsdWUuY29uc3RydWN0b3IucHJvdG90eXBlID09PSB2YWx1ZSkpIHtcbiAgICB2YXIgcmV0ID0gdmFsdWUuaW5zcGVjdChyZWN1cnNlVGltZXMsIGN0eCk7XG4gICAgaWYgKCFpc1N0cmluZyhyZXQpKSB7XG4gICAgICByZXQgPSBmb3JtYXRWYWx1ZShjdHgsIHJldCwgcmVjdXJzZVRpbWVzKTtcbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbiAgfVxuXG4gIC8vIFByaW1pdGl2ZSB0eXBlcyBjYW5ub3QgaGF2ZSBwcm9wZXJ0aWVzXG4gIHZhciBwcmltaXRpdmUgPSBmb3JtYXRQcmltaXRpdmUoY3R4LCB2YWx1ZSk7XG4gIGlmIChwcmltaXRpdmUpIHtcbiAgICByZXR1cm4gcHJpbWl0aXZlO1xuICB9XG5cbiAgLy8gTG9vayB1cCB0aGUga2V5cyBvZiB0aGUgb2JqZWN0LlxuICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHZhbHVlKTtcbiAgdmFyIHZpc2libGVLZXlzID0gYXJyYXlUb0hhc2goa2V5cyk7XG5cbiAgaWYgKGN0eC5zaG93SGlkZGVuKSB7XG4gICAga2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHZhbHVlKTtcbiAgfVxuXG4gIC8vIElFIGRvZXNuJ3QgbWFrZSBlcnJvciBmaWVsZHMgbm9uLWVudW1lcmFibGVcbiAgLy8gaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L2llL2R3dzUyc2J0KHY9dnMuOTQpLmFzcHhcbiAgaWYgKGlzRXJyb3IodmFsdWUpXG4gICAgICAmJiAoa2V5cy5pbmRleE9mKCdtZXNzYWdlJykgPj0gMCB8fCBrZXlzLmluZGV4T2YoJ2Rlc2NyaXB0aW9uJykgPj0gMCkpIHtcbiAgICByZXR1cm4gZm9ybWF0RXJyb3IodmFsdWUpO1xuICB9XG5cbiAgLy8gU29tZSB0eXBlIG9mIG9iamVjdCB3aXRob3V0IHByb3BlcnRpZXMgY2FuIGJlIHNob3J0Y3V0dGVkLlxuICBpZiAoa2V5cy5sZW5ndGggPT09IDApIHtcbiAgICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICAgIHZhciBuYW1lID0gdmFsdWUubmFtZSA/ICc6ICcgKyB2YWx1ZS5uYW1lIDogJyc7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJ1tGdW5jdGlvbicgKyBuYW1lICsgJ10nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ3JlZ2V4cCcpO1xuICAgIH1cbiAgICBpZiAoaXNEYXRlKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKERhdGUucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAnZGF0ZScpO1xuICAgIH1cbiAgICBpZiAoaXNFcnJvcih2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIGJhc2UgPSAnJywgYXJyYXkgPSBmYWxzZSwgYnJhY2VzID0gWyd7JywgJ30nXTtcblxuICAvLyBNYWtlIEFycmF5IHNheSB0aGF0IHRoZXkgYXJlIEFycmF5XG4gIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgIGFycmF5ID0gdHJ1ZTtcbiAgICBicmFjZXMgPSBbJ1snLCAnXSddO1xuICB9XG5cbiAgLy8gTWFrZSBmdW5jdGlvbnMgc2F5IHRoYXQgdGhleSBhcmUgZnVuY3Rpb25zXG4gIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgIHZhciBuID0gdmFsdWUubmFtZSA/ICc6ICcgKyB2YWx1ZS5uYW1lIDogJyc7XG4gICAgYmFzZSA9ICcgW0Z1bmN0aW9uJyArIG4gKyAnXSc7XG4gIH1cblxuICAvLyBNYWtlIFJlZ0V4cHMgc2F5IHRoYXQgdGhleSBhcmUgUmVnRXhwc1xuICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSk7XG4gIH1cblxuICAvLyBNYWtlIGRhdGVzIHdpdGggcHJvcGVydGllcyBmaXJzdCBzYXkgdGhlIGRhdGVcbiAgaWYgKGlzRGF0ZSh2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgRGF0ZS5wcm90b3R5cGUudG9VVENTdHJpbmcuY2FsbCh2YWx1ZSk7XG4gIH1cblxuICAvLyBNYWtlIGVycm9yIHdpdGggbWVzc2FnZSBmaXJzdCBzYXkgdGhlIGVycm9yXG4gIGlmIChpc0Vycm9yKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gIH1cblxuICBpZiAoa2V5cy5sZW5ndGggPT09IDAgJiYgKCFhcnJheSB8fCB2YWx1ZS5sZW5ndGggPT0gMCkpIHtcbiAgICByZXR1cm4gYnJhY2VzWzBdICsgYmFzZSArIGJyYWNlc1sxXTtcbiAgfVxuXG4gIGlmIChyZWN1cnNlVGltZXMgPCAwKSB7XG4gICAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdyZWdleHAnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKCdbT2JqZWN0XScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG5cbiAgY3R4LnNlZW4ucHVzaCh2YWx1ZSk7XG5cbiAgdmFyIG91dHB1dDtcbiAgaWYgKGFycmF5KSB7XG4gICAgb3V0cHV0ID0gZm9ybWF0QXJyYXkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5cyk7XG4gIH0gZWxzZSB7XG4gICAgb3V0cHV0ID0ga2V5cy5tYXAoZnVuY3Rpb24oa2V5KSB7XG4gICAgICByZXR1cm4gZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5LCBhcnJheSk7XG4gICAgfSk7XG4gIH1cblxuICBjdHguc2Vlbi5wb3AoKTtcblxuICByZXR1cm4gcmVkdWNlVG9TaW5nbGVTdHJpbmcob3V0cHV0LCBiYXNlLCBicmFjZXMpO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKSB7XG4gIGlmIChpc1VuZGVmaW5lZCh2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCd1bmRlZmluZWQnLCAndW5kZWZpbmVkJyk7XG4gIGlmIChpc1N0cmluZyh2YWx1ZSkpIHtcbiAgICB2YXIgc2ltcGxlID0gJ1xcJycgKyBKU09OLnN0cmluZ2lmeSh2YWx1ZSkucmVwbGFjZSgvXlwifFwiJC9nLCAnJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXFxcXCIvZywgJ1wiJykgKyAnXFwnJztcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoc2ltcGxlLCAnc3RyaW5nJyk7XG4gIH1cbiAgaWYgKGlzTnVtYmVyKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJycgKyB2YWx1ZSwgJ251bWJlcicpO1xuICBpZiAoaXNCb29sZWFuKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJycgKyB2YWx1ZSwgJ2Jvb2xlYW4nKTtcbiAgLy8gRm9yIHNvbWUgcmVhc29uIHR5cGVvZiBudWxsIGlzIFwib2JqZWN0XCIsIHNvIHNwZWNpYWwgY2FzZSBoZXJlLlxuICBpZiAoaXNOdWxsKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJ251bGwnLCAnbnVsbCcpO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdEVycm9yKHZhbHVlKSB7XG4gIHJldHVybiAnWycgKyBFcnJvci5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSkgKyAnXSc7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0QXJyYXkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5cykge1xuICB2YXIgb3V0cHV0ID0gW107XG4gIGZvciAodmFyIGkgPSAwLCBsID0gdmFsdWUubGVuZ3RoOyBpIDwgbDsgKytpKSB7XG4gICAgaWYgKGhhc093blByb3BlcnR5KHZhbHVlLCBTdHJpbmcoaSkpKSB7XG4gICAgICBvdXRwdXQucHVzaChmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLFxuICAgICAgICAgIFN0cmluZyhpKSwgdHJ1ZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBvdXRwdXQucHVzaCgnJyk7XG4gICAgfVxuICB9XG4gIGtleXMuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcbiAgICBpZiAoIWtleS5tYXRjaCgvXlxcZCskLykpIHtcbiAgICAgIG91dHB1dC5wdXNoKGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsXG4gICAgICAgICAga2V5LCB0cnVlKSk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIG91dHB1dDtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXksIGFycmF5KSB7XG4gIHZhciBuYW1lLCBzdHIsIGRlc2M7XG4gIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHZhbHVlLCBrZXkpIHx8IHsgdmFsdWU6IHZhbHVlW2tleV0gfTtcbiAgaWYgKGRlc2MuZ2V0KSB7XG4gICAgaWYgKGRlc2Muc2V0KSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0dldHRlci9TZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tHZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGRlc2Muc2V0KSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW1NldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuICBpZiAoIWhhc093blByb3BlcnR5KHZpc2libGVLZXlzLCBrZXkpKSB7XG4gICAgbmFtZSA9ICdbJyArIGtleSArICddJztcbiAgfVxuICBpZiAoIXN0cikge1xuICAgIGlmIChjdHguc2Vlbi5pbmRleE9mKGRlc2MudmFsdWUpIDwgMCkge1xuICAgICAgaWYgKGlzTnVsbChyZWN1cnNlVGltZXMpKSB7XG4gICAgICAgIHN0ciA9IGZvcm1hdFZhbHVlKGN0eCwgZGVzYy52YWx1ZSwgbnVsbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdHIgPSBmb3JtYXRWYWx1ZShjdHgsIGRlc2MudmFsdWUsIHJlY3Vyc2VUaW1lcyAtIDEpO1xuICAgICAgfVxuICAgICAgaWYgKHN0ci5pbmRleE9mKCdcXG4nKSA+IC0xKSB7XG4gICAgICAgIGlmIChhcnJheSkge1xuICAgICAgICAgIHN0ciA9IHN0ci5zcGxpdCgnXFxuJykubWFwKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgICAgIHJldHVybiAnICAnICsgbGluZTtcbiAgICAgICAgICB9KS5qb2luKCdcXG4nKS5zdWJzdHIoMik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3RyID0gJ1xcbicgKyBzdHIuc3BsaXQoJ1xcbicpLm1hcChmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgICAgICByZXR1cm4gJyAgICcgKyBsaW5lO1xuICAgICAgICAgIH0pLmpvaW4oJ1xcbicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbQ2lyY3VsYXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH1cbiAgaWYgKGlzVW5kZWZpbmVkKG5hbWUpKSB7XG4gICAgaWYgKGFycmF5ICYmIGtleS5tYXRjaCgvXlxcZCskLykpIHtcbiAgICAgIHJldHVybiBzdHI7XG4gICAgfVxuICAgIG5hbWUgPSBKU09OLnN0cmluZ2lmeSgnJyArIGtleSk7XG4gICAgaWYgKG5hbWUubWF0Y2goL15cIihbYS16QS1aX11bYS16QS1aXzAtOV0qKVwiJC8pKSB7XG4gICAgICBuYW1lID0gbmFtZS5zdWJzdHIoMSwgbmFtZS5sZW5ndGggLSAyKTtcbiAgICAgIG5hbWUgPSBjdHguc3R5bGl6ZShuYW1lLCAnbmFtZScpO1xuICAgIH0gZWxzZSB7XG4gICAgICBuYW1lID0gbmFtZS5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIilcbiAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcXFxcIi9nLCAnXCInKVxuICAgICAgICAgICAgICAgICAucmVwbGFjZSgvKF5cInxcIiQpL2csIFwiJ1wiKTtcbiAgICAgIG5hbWUgPSBjdHguc3R5bGl6ZShuYW1lLCAnc3RyaW5nJyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5hbWUgKyAnOiAnICsgc3RyO1xufVxuXG5cbmZ1bmN0aW9uIHJlZHVjZVRvU2luZ2xlU3RyaW5nKG91dHB1dCwgYmFzZSwgYnJhY2VzKSB7XG4gIHZhciBudW1MaW5lc0VzdCA9IDA7XG4gIHZhciBsZW5ndGggPSBvdXRwdXQucmVkdWNlKGZ1bmN0aW9uKHByZXYsIGN1cikge1xuICAgIG51bUxpbmVzRXN0Kys7XG4gICAgaWYgKGN1ci5pbmRleE9mKCdcXG4nKSA+PSAwKSBudW1MaW5lc0VzdCsrO1xuICAgIHJldHVybiBwcmV2ICsgY3VyLnJlcGxhY2UoL1xcdTAwMWJcXFtcXGRcXGQ/bS9nLCAnJykubGVuZ3RoICsgMTtcbiAgfSwgMCk7XG5cbiAgaWYgKGxlbmd0aCA+IDYwKSB7XG4gICAgcmV0dXJuIGJyYWNlc1swXSArXG4gICAgICAgICAgIChiYXNlID09PSAnJyA/ICcnIDogYmFzZSArICdcXG4gJykgK1xuICAgICAgICAgICAnICcgK1xuICAgICAgICAgICBvdXRwdXQuam9pbignLFxcbiAgJykgK1xuICAgICAgICAgICAnICcgK1xuICAgICAgICAgICBicmFjZXNbMV07XG4gIH1cblxuICByZXR1cm4gYnJhY2VzWzBdICsgYmFzZSArICcgJyArIG91dHB1dC5qb2luKCcsICcpICsgJyAnICsgYnJhY2VzWzFdO1xufVxuXG5cbi8vIE5PVEU6IFRoZXNlIHR5cGUgY2hlY2tpbmcgZnVuY3Rpb25zIGludGVudGlvbmFsbHkgZG9uJ3QgdXNlIGBpbnN0YW5jZW9mYFxuLy8gYmVjYXVzZSBpdCBpcyBmcmFnaWxlIGFuZCBjYW4gYmUgZWFzaWx5IGZha2VkIHdpdGggYE9iamVjdC5jcmVhdGUoKWAuXG5mdW5jdGlvbiBpc0FycmF5KGFyKSB7XG4gIHJldHVybiBBcnJheS5pc0FycmF5KGFyKTtcbn1cbmV4cG9ydHMuaXNBcnJheSA9IGlzQXJyYXk7XG5cbmZ1bmN0aW9uIGlzQm9vbGVhbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJztcbn1cbmV4cG9ydHMuaXNCb29sZWFuID0gaXNCb29sZWFuO1xuXG5mdW5jdGlvbiBpc051bGwoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGw7XG59XG5leHBvcnRzLmlzTnVsbCA9IGlzTnVsbDtcblxuZnVuY3Rpb24gaXNOdWxsT3JVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsT3JVbmRlZmluZWQgPSBpc051bGxPclVuZGVmaW5lZDtcblxuZnVuY3Rpb24gaXNOdW1iZXIoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnbnVtYmVyJztcbn1cbmV4cG9ydHMuaXNOdW1iZXIgPSBpc051bWJlcjtcblxuZnVuY3Rpb24gaXNTdHJpbmcoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3RyaW5nJztcbn1cbmV4cG9ydHMuaXNTdHJpbmcgPSBpc1N0cmluZztcblxuZnVuY3Rpb24gaXNTeW1ib2woYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3ltYm9sJztcbn1cbmV4cG9ydHMuaXNTeW1ib2wgPSBpc1N5bWJvbDtcblxuZnVuY3Rpb24gaXNVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IHZvaWQgMDtcbn1cbmV4cG9ydHMuaXNVbmRlZmluZWQgPSBpc1VuZGVmaW5lZDtcblxuZnVuY3Rpb24gaXNSZWdFeHAocmUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KHJlKSAmJiBvYmplY3RUb1N0cmluZyhyZSkgPT09ICdbb2JqZWN0IFJlZ0V4cF0nO1xufVxuZXhwb3J0cy5pc1JlZ0V4cCA9IGlzUmVnRXhwO1xuXG5mdW5jdGlvbiBpc09iamVjdChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnICYmIGFyZyAhPT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNPYmplY3QgPSBpc09iamVjdDtcblxuZnVuY3Rpb24gaXNEYXRlKGQpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KGQpICYmIG9iamVjdFRvU3RyaW5nKGQpID09PSAnW29iamVjdCBEYXRlXSc7XG59XG5leHBvcnRzLmlzRGF0ZSA9IGlzRGF0ZTtcblxuZnVuY3Rpb24gaXNFcnJvcihlKSB7XG4gIHJldHVybiBpc09iamVjdChlKSAmJlxuICAgICAgKG9iamVjdFRvU3RyaW5nKGUpID09PSAnW29iamVjdCBFcnJvcl0nIHx8IGUgaW5zdGFuY2VvZiBFcnJvcik7XG59XG5leHBvcnRzLmlzRXJyb3IgPSBpc0Vycm9yO1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cbmV4cG9ydHMuaXNGdW5jdGlvbiA9IGlzRnVuY3Rpb247XG5cbmZ1bmN0aW9uIGlzUHJpbWl0aXZlKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnYm9vbGVhbicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdudW1iZXInIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3RyaW5nJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N5bWJvbCcgfHwgIC8vIEVTNiBzeW1ib2xcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICd1bmRlZmluZWQnO1xufVxuZXhwb3J0cy5pc1ByaW1pdGl2ZSA9IGlzUHJpbWl0aXZlO1xuXG5leHBvcnRzLmlzQnVmZmVyID0gcmVxdWlyZSgnLi9zdXBwb3J0L2lzQnVmZmVyJyk7XG5cbmZ1bmN0aW9uIG9iamVjdFRvU3RyaW5nKG8pIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKTtcbn1cblxuXG5mdW5jdGlvbiBwYWQobikge1xuICByZXR1cm4gbiA8IDEwID8gJzAnICsgbi50b1N0cmluZygxMCkgOiBuLnRvU3RyaW5nKDEwKTtcbn1cblxuXG52YXIgbW9udGhzID0gWydKYW4nLCAnRmViJywgJ01hcicsICdBcHInLCAnTWF5JywgJ0p1bicsICdKdWwnLCAnQXVnJywgJ1NlcCcsXG4gICAgICAgICAgICAgICdPY3QnLCAnTm92JywgJ0RlYyddO1xuXG4vLyAyNiBGZWIgMTY6MTk6MzRcbmZ1bmN0aW9uIHRpbWVzdGFtcCgpIHtcbiAgdmFyIGQgPSBuZXcgRGF0ZSgpO1xuICB2YXIgdGltZSA9IFtwYWQoZC5nZXRIb3VycygpKSxcbiAgICAgICAgICAgICAgcGFkKGQuZ2V0TWludXRlcygpKSxcbiAgICAgICAgICAgICAgcGFkKGQuZ2V0U2Vjb25kcygpKV0uam9pbignOicpO1xuICByZXR1cm4gW2QuZ2V0RGF0ZSgpLCBtb250aHNbZC5nZXRNb250aCgpXSwgdGltZV0uam9pbignICcpO1xufVxuXG5cbi8vIGxvZyBpcyBqdXN0IGEgdGhpbiB3cmFwcGVyIHRvIGNvbnNvbGUubG9nIHRoYXQgcHJlcGVuZHMgYSB0aW1lc3RhbXBcbmV4cG9ydHMubG9nID0gZnVuY3Rpb24oKSB7XG4gIGNvbnNvbGUubG9nKCclcyAtICVzJywgdGltZXN0YW1wKCksIGV4cG9ydHMuZm9ybWF0LmFwcGx5KGV4cG9ydHMsIGFyZ3VtZW50cykpO1xufTtcblxuXG4vKipcbiAqIEluaGVyaXQgdGhlIHByb3RvdHlwZSBtZXRob2RzIGZyb20gb25lIGNvbnN0cnVjdG9yIGludG8gYW5vdGhlci5cbiAqXG4gKiBUaGUgRnVuY3Rpb24ucHJvdG90eXBlLmluaGVyaXRzIGZyb20gbGFuZy5qcyByZXdyaXR0ZW4gYXMgYSBzdGFuZGFsb25lXG4gKiBmdW5jdGlvbiAobm90IG9uIEZ1bmN0aW9uLnByb3RvdHlwZSkuIE5PVEU6IElmIHRoaXMgZmlsZSBpcyB0byBiZSBsb2FkZWRcbiAqIGR1cmluZyBib290c3RyYXBwaW5nIHRoaXMgZnVuY3Rpb24gbmVlZHMgdG8gYmUgcmV3cml0dGVuIHVzaW5nIHNvbWUgbmF0aXZlXG4gKiBmdW5jdGlvbnMgYXMgcHJvdG90eXBlIHNldHVwIHVzaW5nIG5vcm1hbCBKYXZhU2NyaXB0IGRvZXMgbm90IHdvcmsgYXNcbiAqIGV4cGVjdGVkIGR1cmluZyBib290c3RyYXBwaW5nIChzZWUgbWlycm9yLmpzIGluIHIxMTQ5MDMpLlxuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGN0b3IgQ29uc3RydWN0b3IgZnVuY3Rpb24gd2hpY2ggbmVlZHMgdG8gaW5oZXJpdCB0aGVcbiAqICAgICBwcm90b3R5cGUuXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBzdXBlckN0b3IgQ29uc3RydWN0b3IgZnVuY3Rpb24gdG8gaW5oZXJpdCBwcm90b3R5cGUgZnJvbS5cbiAqL1xuZXhwb3J0cy5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbmV4cG9ydHMuX2V4dGVuZCA9IGZ1bmN0aW9uKG9yaWdpbiwgYWRkKSB7XG4gIC8vIERvbid0IGRvIGFueXRoaW5nIGlmIGFkZCBpc24ndCBhbiBvYmplY3RcbiAgaWYgKCFhZGQgfHwgIWlzT2JqZWN0KGFkZCkpIHJldHVybiBvcmlnaW47XG5cbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhhZGQpO1xuICB2YXIgaSA9IGtleXMubGVuZ3RoO1xuICB3aGlsZSAoaS0tKSB7XG4gICAgb3JpZ2luW2tleXNbaV1dID0gYWRkW2tleXNbaV1dO1xuICB9XG4gIHJldHVybiBvcmlnaW47XG59O1xuXG5mdW5jdGlvbiBoYXNPd25Qcm9wZXJ0eShvYmosIHByb3ApIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgb2JqZWN0QXNzaWduID0gcmVxdWlyZSgnb2JqZWN0LWFzc2lnbicpO1xuXG4vLyBjb21wYXJlIGFuZCBpc0J1ZmZlciB0YWtlbiBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyL2Jsb2IvNjgwZTllNWU0ODhmMjJhYWMyNzU5OWE1N2RjODQ0YTYzMTU5MjhkZC9pbmRleC5qc1xuLy8gb3JpZ2luYWwgbm90aWNlOlxuXG4vKiFcbiAqIFRoZSBidWZmZXIgbW9kdWxlIGZyb20gbm9kZS5qcywgZm9yIHRoZSBicm93c2VyLlxuICpcbiAqIEBhdXRob3IgICBGZXJvc3MgQWJvdWtoYWRpamVoIDxmZXJvc3NAZmVyb3NzLm9yZz4gPGh0dHA6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG5mdW5jdGlvbiBjb21wYXJlKGEsIGIpIHtcbiAgaWYgKGEgPT09IGIpIHtcbiAgICByZXR1cm4gMDtcbiAgfVxuXG4gIHZhciB4ID0gYS5sZW5ndGg7XG4gIHZhciB5ID0gYi5sZW5ndGg7XG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IE1hdGgubWluKHgsIHkpOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAoYVtpXSAhPT0gYltpXSkge1xuICAgICAgeCA9IGFbaV07XG4gICAgICB5ID0gYltpXTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGlmICh4IDwgeSkge1xuICAgIHJldHVybiAtMTtcbiAgfVxuICBpZiAoeSA8IHgpIHtcbiAgICByZXR1cm4gMTtcbiAgfVxuICByZXR1cm4gMDtcbn1cbmZ1bmN0aW9uIGlzQnVmZmVyKGIpIHtcbiAgaWYgKGdsb2JhbC5CdWZmZXIgJiYgdHlwZW9mIGdsb2JhbC5CdWZmZXIuaXNCdWZmZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gZ2xvYmFsLkJ1ZmZlci5pc0J1ZmZlcihiKTtcbiAgfVxuICByZXR1cm4gISEoYiAhPSBudWxsICYmIGIuX2lzQnVmZmVyKTtcbn1cblxuLy8gYmFzZWQgb24gbm9kZSBhc3NlcnQsIG9yaWdpbmFsIG5vdGljZTpcbi8vIE5COiBUaGUgVVJMIHRvIHRoZSBDb21tb25KUyBzcGVjIGlzIGtlcHQganVzdCBmb3IgdHJhZGl0aW9uLlxuLy8gICAgIG5vZGUtYXNzZXJ0IGhhcyBldm9sdmVkIGEgbG90IHNpbmNlIHRoZW4sIGJvdGggaW4gQVBJIGFuZCBiZWhhdmlvci5cblxuLy8gaHR0cDovL3dpa2kuY29tbW9uanMub3JnL3dpa2kvVW5pdF9UZXN0aW5nLzEuMFxuLy9cbi8vIFRISVMgSVMgTk9UIFRFU1RFRCBOT1IgTElLRUxZIFRPIFdPUksgT1VUU0lERSBWOCFcbi8vXG4vLyBPcmlnaW5hbGx5IGZyb20gbmFyd2hhbC5qcyAoaHR0cDovL25hcndoYWxqcy5vcmcpXG4vLyBDb3B5cmlnaHQgKGMpIDIwMDkgVGhvbWFzIFJvYmluc29uIDwyODBub3J0aC5jb20+XG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgJ1NvZnR3YXJlJyksIHRvXG4vLyBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxuLy8gcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4vLyBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICdBUyBJUycsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyBBVVRIT1JTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTlxuLy8gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTlxuLy8gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbC8nKTtcbnZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xudmFyIHBTbGljZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZTtcbnZhciBmdW5jdGlvbnNIYXZlTmFtZXMgPSAoZnVuY3Rpb24gKCkge1xuICByZXR1cm4gZnVuY3Rpb24gZm9vKCkge30ubmFtZSA9PT0gJ2Zvbyc7XG59KCkpO1xuZnVuY3Rpb24gcFRvU3RyaW5nIChvYmopIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopO1xufVxuZnVuY3Rpb24gaXNWaWV3KGFycmJ1Zikge1xuICBpZiAoaXNCdWZmZXIoYXJyYnVmKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAodHlwZW9mIGdsb2JhbC5BcnJheUJ1ZmZlciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyLmlzVmlldyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBBcnJheUJ1ZmZlci5pc1ZpZXcoYXJyYnVmKTtcbiAgfVxuICBpZiAoIWFycmJ1Zikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoYXJyYnVmIGluc3RhbmNlb2YgRGF0YVZpZXcpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAoYXJyYnVmLmJ1ZmZlciAmJiBhcnJidWYuYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG4vLyAxLiBUaGUgYXNzZXJ0IG1vZHVsZSBwcm92aWRlcyBmdW5jdGlvbnMgdGhhdCB0aHJvd1xuLy8gQXNzZXJ0aW9uRXJyb3IncyB3aGVuIHBhcnRpY3VsYXIgY29uZGl0aW9ucyBhcmUgbm90IG1ldC4gVGhlXG4vLyBhc3NlcnQgbW9kdWxlIG11c3QgY29uZm9ybSB0byB0aGUgZm9sbG93aW5nIGludGVyZmFjZS5cblxudmFyIGFzc2VydCA9IG1vZHVsZS5leHBvcnRzID0gb2s7XG5cbi8vIDIuIFRoZSBBc3NlcnRpb25FcnJvciBpcyBkZWZpbmVkIGluIGFzc2VydC5cbi8vIG5ldyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3IoeyBtZXNzYWdlOiBtZXNzYWdlLFxuLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdHVhbDogYWN0dWFsLFxuLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBleHBlY3RlZCB9KVxuXG52YXIgcmVnZXggPSAvXFxzKmZ1bmN0aW9uXFxzKyhbXlxcKFxcc10qKVxccyovO1xuLy8gYmFzZWQgb24gaHR0cHM6Ly9naXRodWIuY29tL2xqaGFyYi9mdW5jdGlvbi5wcm90b3R5cGUubmFtZS9ibG9iL2FkZWVlZWM4YmZjYzYwNjhiMTg3ZDdkOWZiM2Q1YmIxZDNhMzA4OTkvaW1wbGVtZW50YXRpb24uanNcbmZ1bmN0aW9uIGdldE5hbWUoZnVuYykge1xuICBpZiAoIXV0aWwuaXNGdW5jdGlvbihmdW5jKSkge1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAoZnVuY3Rpb25zSGF2ZU5hbWVzKSB7XG4gICAgcmV0dXJuIGZ1bmMubmFtZTtcbiAgfVxuICB2YXIgc3RyID0gZnVuYy50b1N0cmluZygpO1xuICB2YXIgbWF0Y2ggPSBzdHIubWF0Y2gocmVnZXgpO1xuICByZXR1cm4gbWF0Y2ggJiYgbWF0Y2hbMV07XG59XG5hc3NlcnQuQXNzZXJ0aW9uRXJyb3IgPSBmdW5jdGlvbiBBc3NlcnRpb25FcnJvcihvcHRpb25zKSB7XG4gIHRoaXMubmFtZSA9ICdBc3NlcnRpb25FcnJvcic7XG4gIHRoaXMuYWN0dWFsID0gb3B0aW9ucy5hY3R1YWw7XG4gIHRoaXMuZXhwZWN0ZWQgPSBvcHRpb25zLmV4cGVjdGVkO1xuICB0aGlzLm9wZXJhdG9yID0gb3B0aW9ucy5vcGVyYXRvcjtcbiAgaWYgKG9wdGlvbnMubWVzc2FnZSkge1xuICAgIHRoaXMubWVzc2FnZSA9IG9wdGlvbnMubWVzc2FnZTtcbiAgICB0aGlzLmdlbmVyYXRlZE1lc3NhZ2UgPSBmYWxzZTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLm1lc3NhZ2UgPSBnZXRNZXNzYWdlKHRoaXMpO1xuICAgIHRoaXMuZ2VuZXJhdGVkTWVzc2FnZSA9IHRydWU7XG4gIH1cbiAgdmFyIHN0YWNrU3RhcnRGdW5jdGlvbiA9IG9wdGlvbnMuc3RhY2tTdGFydEZ1bmN0aW9uIHx8IGZhaWw7XG4gIGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkge1xuICAgIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIHN0YWNrU3RhcnRGdW5jdGlvbik7XG4gIH0gZWxzZSB7XG4gICAgLy8gbm9uIHY4IGJyb3dzZXJzIHNvIHdlIGNhbiBoYXZlIGEgc3RhY2t0cmFjZVxuICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoKTtcbiAgICBpZiAoZXJyLnN0YWNrKSB7XG4gICAgICB2YXIgb3V0ID0gZXJyLnN0YWNrO1xuXG4gICAgICAvLyB0cnkgdG8gc3RyaXAgdXNlbGVzcyBmcmFtZXNcbiAgICAgIHZhciBmbl9uYW1lID0gZ2V0TmFtZShzdGFja1N0YXJ0RnVuY3Rpb24pO1xuICAgICAgdmFyIGlkeCA9IG91dC5pbmRleE9mKCdcXG4nICsgZm5fbmFtZSk7XG4gICAgICBpZiAoaWR4ID49IDApIHtcbiAgICAgICAgLy8gb25jZSB3ZSBoYXZlIGxvY2F0ZWQgdGhlIGZ1bmN0aW9uIGZyYW1lXG4gICAgICAgIC8vIHdlIG5lZWQgdG8gc3RyaXAgb3V0IGV2ZXJ5dGhpbmcgYmVmb3JlIGl0IChhbmQgaXRzIGxpbmUpXG4gICAgICAgIHZhciBuZXh0X2xpbmUgPSBvdXQuaW5kZXhPZignXFxuJywgaWR4ICsgMSk7XG4gICAgICAgIG91dCA9IG91dC5zdWJzdHJpbmcobmV4dF9saW5lICsgMSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc3RhY2sgPSBvdXQ7XG4gICAgfVxuICB9XG59O1xuXG4vLyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3IgaW5zdGFuY2VvZiBFcnJvclxudXRpbC5pbmhlcml0cyhhc3NlcnQuQXNzZXJ0aW9uRXJyb3IsIEVycm9yKTtcblxuZnVuY3Rpb24gdHJ1bmNhdGUocywgbikge1xuICBpZiAodHlwZW9mIHMgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHMubGVuZ3RoIDwgbiA/IHMgOiBzLnNsaWNlKDAsIG4pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBzO1xuICB9XG59XG5mdW5jdGlvbiBpbnNwZWN0KHNvbWV0aGluZykge1xuICBpZiAoZnVuY3Rpb25zSGF2ZU5hbWVzIHx8ICF1dGlsLmlzRnVuY3Rpb24oc29tZXRoaW5nKSkge1xuICAgIHJldHVybiB1dGlsLmluc3BlY3Qoc29tZXRoaW5nKTtcbiAgfVxuICB2YXIgcmF3bmFtZSA9IGdldE5hbWUoc29tZXRoaW5nKTtcbiAgdmFyIG5hbWUgPSByYXduYW1lID8gJzogJyArIHJhd25hbWUgOiAnJztcbiAgcmV0dXJuICdbRnVuY3Rpb24nICsgIG5hbWUgKyAnXSc7XG59XG5mdW5jdGlvbiBnZXRNZXNzYWdlKHNlbGYpIHtcbiAgcmV0dXJuIHRydW5jYXRlKGluc3BlY3Qoc2VsZi5hY3R1YWwpLCAxMjgpICsgJyAnICtcbiAgICAgICAgIHNlbGYub3BlcmF0b3IgKyAnICcgK1xuICAgICAgICAgdHJ1bmNhdGUoaW5zcGVjdChzZWxmLmV4cGVjdGVkKSwgMTI4KTtcbn1cblxuLy8gQXQgcHJlc2VudCBvbmx5IHRoZSB0aHJlZSBrZXlzIG1lbnRpb25lZCBhYm92ZSBhcmUgdXNlZCBhbmRcbi8vIHVuZGVyc3Rvb2QgYnkgdGhlIHNwZWMuIEltcGxlbWVudGF0aW9ucyBvciBzdWIgbW9kdWxlcyBjYW4gcGFzc1xuLy8gb3RoZXIga2V5cyB0byB0aGUgQXNzZXJ0aW9uRXJyb3IncyBjb25zdHJ1Y3RvciAtIHRoZXkgd2lsbCBiZVxuLy8gaWdub3JlZC5cblxuLy8gMy4gQWxsIG9mIHRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zIG11c3QgdGhyb3cgYW4gQXNzZXJ0aW9uRXJyb3Jcbi8vIHdoZW4gYSBjb3JyZXNwb25kaW5nIGNvbmRpdGlvbiBpcyBub3QgbWV0LCB3aXRoIGEgbWVzc2FnZSB0aGF0XG4vLyBtYXkgYmUgdW5kZWZpbmVkIGlmIG5vdCBwcm92aWRlZC4gIEFsbCBhc3NlcnRpb24gbWV0aG9kcyBwcm92aWRlXG4vLyBib3RoIHRoZSBhY3R1YWwgYW5kIGV4cGVjdGVkIHZhbHVlcyB0byB0aGUgYXNzZXJ0aW9uIGVycm9yIGZvclxuLy8gZGlzcGxheSBwdXJwb3Nlcy5cblxuZnVuY3Rpb24gZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCBvcGVyYXRvciwgc3RhY2tTdGFydEZ1bmN0aW9uKSB7XG4gIHRocm93IG5ldyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3Ioe1xuICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgYWN0dWFsOiBhY3R1YWwsXG4gICAgZXhwZWN0ZWQ6IGV4cGVjdGVkLFxuICAgIG9wZXJhdG9yOiBvcGVyYXRvcixcbiAgICBzdGFja1N0YXJ0RnVuY3Rpb246IHN0YWNrU3RhcnRGdW5jdGlvblxuICB9KTtcbn1cblxuLy8gRVhURU5TSU9OISBhbGxvd3MgZm9yIHdlbGwgYmVoYXZlZCBlcnJvcnMgZGVmaW5lZCBlbHNld2hlcmUuXG5hc3NlcnQuZmFpbCA9IGZhaWw7XG5cbi8vIDQuIFB1cmUgYXNzZXJ0aW9uIHRlc3RzIHdoZXRoZXIgYSB2YWx1ZSBpcyB0cnV0aHksIGFzIGRldGVybWluZWRcbi8vIGJ5ICEhZ3VhcmQuXG4vLyBhc3NlcnQub2soZ3VhcmQsIG1lc3NhZ2Vfb3B0KTtcbi8vIFRoaXMgc3RhdGVtZW50IGlzIGVxdWl2YWxlbnQgdG8gYXNzZXJ0LmVxdWFsKHRydWUsICEhZ3VhcmQsXG4vLyBtZXNzYWdlX29wdCk7LiBUbyB0ZXN0IHN0cmljdGx5IGZvciB0aGUgdmFsdWUgdHJ1ZSwgdXNlXG4vLyBhc3NlcnQuc3RyaWN0RXF1YWwodHJ1ZSwgZ3VhcmQsIG1lc3NhZ2Vfb3B0KTsuXG5cbmZ1bmN0aW9uIG9rKHZhbHVlLCBtZXNzYWdlKSB7XG4gIGlmICghdmFsdWUpIGZhaWwodmFsdWUsIHRydWUsIG1lc3NhZ2UsICc9PScsIGFzc2VydC5vayk7XG59XG5hc3NlcnQub2sgPSBvaztcblxuLy8gNS4gVGhlIGVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBzaGFsbG93LCBjb2VyY2l2ZSBlcXVhbGl0eSB3aXRoXG4vLyA9PS5cbi8vIGFzc2VydC5lcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5lcXVhbCA9IGZ1bmN0aW9uIGVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKGFjdHVhbCAhPSBleHBlY3RlZCkgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnPT0nLCBhc3NlcnQuZXF1YWwpO1xufTtcblxuLy8gNi4gVGhlIG5vbi1lcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgZm9yIHdoZXRoZXIgdHdvIG9iamVjdHMgYXJlIG5vdCBlcXVhbFxuLy8gd2l0aCAhPSBhc3NlcnQubm90RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQubm90RXF1YWwgPSBmdW5jdGlvbiBub3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgPT0gZXhwZWN0ZWQpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICchPScsIGFzc2VydC5ub3RFcXVhbCk7XG4gIH1cbn07XG5cbi8vIDcuIFRoZSBlcXVpdmFsZW5jZSBhc3NlcnRpb24gdGVzdHMgYSBkZWVwIGVxdWFsaXR5IHJlbGF0aW9uLlxuLy8gYXNzZXJ0LmRlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5kZWVwRXF1YWwgPSBmdW5jdGlvbiBkZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoIV9kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgZmFsc2UpKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnZGVlcEVxdWFsJywgYXNzZXJ0LmRlZXBFcXVhbCk7XG4gIH1cbn07XG5cbmFzc2VydC5kZWVwU3RyaWN0RXF1YWwgPSBmdW5jdGlvbiBkZWVwU3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoIV9kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgdHJ1ZSkpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICdkZWVwU3RyaWN0RXF1YWwnLCBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBzdHJpY3QsIG1lbW9zKSB7XG4gIC8vIDcuMS4gQWxsIGlkZW50aWNhbCB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGFzIGRldGVybWluZWQgYnkgPT09LlxuICBpZiAoYWN0dWFsID09PSBleHBlY3RlZCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2UgaWYgKGlzQnVmZmVyKGFjdHVhbCkgJiYgaXNCdWZmZXIoZXhwZWN0ZWQpKSB7XG4gICAgcmV0dXJuIGNvbXBhcmUoYWN0dWFsLCBleHBlY3RlZCkgPT09IDA7XG5cbiAgLy8gNy4yLiBJZiB0aGUgZXhwZWN0ZWQgdmFsdWUgaXMgYSBEYXRlIG9iamVjdCwgdGhlIGFjdHVhbCB2YWx1ZSBpc1xuICAvLyBlcXVpdmFsZW50IGlmIGl0IGlzIGFsc28gYSBEYXRlIG9iamVjdCB0aGF0IHJlZmVycyB0byB0aGUgc2FtZSB0aW1lLlxuICB9IGVsc2UgaWYgKHV0aWwuaXNEYXRlKGFjdHVhbCkgJiYgdXRpbC5pc0RhdGUoZXhwZWN0ZWQpKSB7XG4gICAgcmV0dXJuIGFjdHVhbC5nZXRUaW1lKCkgPT09IGV4cGVjdGVkLmdldFRpbWUoKTtcblxuICAvLyA3LjMgSWYgdGhlIGV4cGVjdGVkIHZhbHVlIGlzIGEgUmVnRXhwIG9iamVjdCwgdGhlIGFjdHVhbCB2YWx1ZSBpc1xuICAvLyBlcXVpdmFsZW50IGlmIGl0IGlzIGFsc28gYSBSZWdFeHAgb2JqZWN0IHdpdGggdGhlIHNhbWUgc291cmNlIGFuZFxuICAvLyBwcm9wZXJ0aWVzIChgZ2xvYmFsYCwgYG11bHRpbGluZWAsIGBsYXN0SW5kZXhgLCBgaWdub3JlQ2FzZWApLlxuICB9IGVsc2UgaWYgKHV0aWwuaXNSZWdFeHAoYWN0dWFsKSAmJiB1dGlsLmlzUmVnRXhwKGV4cGVjdGVkKSkge1xuICAgIHJldHVybiBhY3R1YWwuc291cmNlID09PSBleHBlY3RlZC5zb3VyY2UgJiZcbiAgICAgICAgICAgYWN0dWFsLmdsb2JhbCA9PT0gZXhwZWN0ZWQuZ2xvYmFsICYmXG4gICAgICAgICAgIGFjdHVhbC5tdWx0aWxpbmUgPT09IGV4cGVjdGVkLm11bHRpbGluZSAmJlxuICAgICAgICAgICBhY3R1YWwubGFzdEluZGV4ID09PSBleHBlY3RlZC5sYXN0SW5kZXggJiZcbiAgICAgICAgICAgYWN0dWFsLmlnbm9yZUNhc2UgPT09IGV4cGVjdGVkLmlnbm9yZUNhc2U7XG5cbiAgLy8gNy40LiBPdGhlciBwYWlycyB0aGF0IGRvIG5vdCBib3RoIHBhc3MgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnLFxuICAvLyBlcXVpdmFsZW5jZSBpcyBkZXRlcm1pbmVkIGJ5ID09LlxuICB9IGVsc2UgaWYgKChhY3R1YWwgPT09IG51bGwgfHwgdHlwZW9mIGFjdHVhbCAhPT0gJ29iamVjdCcpICYmXG4gICAgICAgICAgICAgKGV4cGVjdGVkID09PSBudWxsIHx8IHR5cGVvZiBleHBlY3RlZCAhPT0gJ29iamVjdCcpKSB7XG4gICAgcmV0dXJuIHN0cmljdCA/IGFjdHVhbCA9PT0gZXhwZWN0ZWQgOiBhY3R1YWwgPT0gZXhwZWN0ZWQ7XG5cbiAgLy8gSWYgYm90aCB2YWx1ZXMgYXJlIGluc3RhbmNlcyBvZiB0eXBlZCBhcnJheXMsIHdyYXAgdGhlaXIgdW5kZXJseWluZ1xuICAvLyBBcnJheUJ1ZmZlcnMgaW4gYSBCdWZmZXIgZWFjaCB0byBpbmNyZWFzZSBwZXJmb3JtYW5jZVxuICAvLyBUaGlzIG9wdGltaXphdGlvbiByZXF1aXJlcyB0aGUgYXJyYXlzIHRvIGhhdmUgdGhlIHNhbWUgdHlwZSBhcyBjaGVja2VkIGJ5XG4gIC8vIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcgKGFrYSBwVG9TdHJpbmcpLiBOZXZlciBwZXJmb3JtIGJpbmFyeVxuICAvLyBjb21wYXJpc29ucyBmb3IgRmxvYXQqQXJyYXlzLCB0aG91Z2gsIHNpbmNlIGUuZy4gKzAgPT09IC0wIGJ1dCB0aGVpclxuICAvLyBiaXQgcGF0dGVybnMgYXJlIG5vdCBpZGVudGljYWwuXG4gIH0gZWxzZSBpZiAoaXNWaWV3KGFjdHVhbCkgJiYgaXNWaWV3KGV4cGVjdGVkKSAmJlxuICAgICAgICAgICAgIHBUb1N0cmluZyhhY3R1YWwpID09PSBwVG9TdHJpbmcoZXhwZWN0ZWQpICYmXG4gICAgICAgICAgICAgIShhY3R1YWwgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkgfHxcbiAgICAgICAgICAgICAgIGFjdHVhbCBpbnN0YW5jZW9mIEZsb2F0NjRBcnJheSkpIHtcbiAgICByZXR1cm4gY29tcGFyZShuZXcgVWludDhBcnJheShhY3R1YWwuYnVmZmVyKSxcbiAgICAgICAgICAgICAgICAgICBuZXcgVWludDhBcnJheShleHBlY3RlZC5idWZmZXIpKSA9PT0gMDtcblxuICAvLyA3LjUgRm9yIGFsbCBvdGhlciBPYmplY3QgcGFpcnMsIGluY2x1ZGluZyBBcnJheSBvYmplY3RzLCBlcXVpdmFsZW5jZSBpc1xuICAvLyBkZXRlcm1pbmVkIGJ5IGhhdmluZyB0aGUgc2FtZSBudW1iZXIgb2Ygb3duZWQgcHJvcGVydGllcyAoYXMgdmVyaWZpZWRcbiAgLy8gd2l0aCBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwpLCB0aGUgc2FtZSBzZXQgb2Yga2V5c1xuICAvLyAoYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IHRoZSBzYW1lIG9yZGVyKSwgZXF1aXZhbGVudCB2YWx1ZXMgZm9yIGV2ZXJ5XG4gIC8vIGNvcnJlc3BvbmRpbmcga2V5LCBhbmQgYW4gaWRlbnRpY2FsICdwcm90b3R5cGUnIHByb3BlcnR5LiBOb3RlOiB0aGlzXG4gIC8vIGFjY291bnRzIGZvciBib3RoIG5hbWVkIGFuZCBpbmRleGVkIHByb3BlcnRpZXMgb24gQXJyYXlzLlxuICB9IGVsc2UgaWYgKGlzQnVmZmVyKGFjdHVhbCkgIT09IGlzQnVmZmVyKGV4cGVjdGVkKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSBlbHNlIHtcbiAgICBtZW1vcyA9IG1lbW9zIHx8IHthY3R1YWw6IFtdLCBleHBlY3RlZDogW119O1xuXG4gICAgdmFyIGFjdHVhbEluZGV4ID0gbWVtb3MuYWN0dWFsLmluZGV4T2YoYWN0dWFsKTtcbiAgICBpZiAoYWN0dWFsSW5kZXggIT09IC0xKSB7XG4gICAgICBpZiAoYWN0dWFsSW5kZXggPT09IG1lbW9zLmV4cGVjdGVkLmluZGV4T2YoZXhwZWN0ZWQpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIG1lbW9zLmFjdHVhbC5wdXNoKGFjdHVhbCk7XG4gICAgbWVtb3MuZXhwZWN0ZWQucHVzaChleHBlY3RlZCk7XG5cbiAgICByZXR1cm4gb2JqRXF1aXYoYWN0dWFsLCBleHBlY3RlZCwgc3RyaWN0LCBtZW1vcyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNBcmd1bWVudHMob2JqZWN0KSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqZWN0KSA9PSAnW29iamVjdCBBcmd1bWVudHNdJztcbn1cblxuZnVuY3Rpb24gb2JqRXF1aXYoYSwgYiwgc3RyaWN0LCBhY3R1YWxWaXNpdGVkT2JqZWN0cykge1xuICBpZiAoYSA9PT0gbnVsbCB8fCBhID09PSB1bmRlZmluZWQgfHwgYiA9PT0gbnVsbCB8fCBiID09PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIGZhbHNlO1xuICAvLyBpZiBvbmUgaXMgYSBwcmltaXRpdmUsIHRoZSBvdGhlciBtdXN0IGJlIHNhbWVcbiAgaWYgKHV0aWwuaXNQcmltaXRpdmUoYSkgfHwgdXRpbC5pc1ByaW1pdGl2ZShiKSlcbiAgICByZXR1cm4gYSA9PT0gYjtcbiAgaWYgKHN0cmljdCAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoYSkgIT09IE9iamVjdC5nZXRQcm90b3R5cGVPZihiKSlcbiAgICByZXR1cm4gZmFsc2U7XG4gIHZhciBhSXNBcmdzID0gaXNBcmd1bWVudHMoYSk7XG4gIHZhciBiSXNBcmdzID0gaXNBcmd1bWVudHMoYik7XG4gIGlmICgoYUlzQXJncyAmJiAhYklzQXJncykgfHwgKCFhSXNBcmdzICYmIGJJc0FyZ3MpKVxuICAgIHJldHVybiBmYWxzZTtcbiAgaWYgKGFJc0FyZ3MpIHtcbiAgICBhID0gcFNsaWNlLmNhbGwoYSk7XG4gICAgYiA9IHBTbGljZS5jYWxsKGIpO1xuICAgIHJldHVybiBfZGVlcEVxdWFsKGEsIGIsIHN0cmljdCk7XG4gIH1cbiAgdmFyIGthID0gb2JqZWN0S2V5cyhhKTtcbiAgdmFyIGtiID0gb2JqZWN0S2V5cyhiKTtcbiAgdmFyIGtleSwgaTtcbiAgLy8gaGF2aW5nIHRoZSBzYW1lIG51bWJlciBvZiBvd25lZCBwcm9wZXJ0aWVzIChrZXlzIGluY29ycG9yYXRlc1xuICAvLyBoYXNPd25Qcm9wZXJ0eSlcbiAgaWYgKGthLmxlbmd0aCAhPT0ga2IubGVuZ3RoKVxuICAgIHJldHVybiBmYWxzZTtcbiAgLy90aGUgc2FtZSBzZXQgb2Yga2V5cyAoYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IHRoZSBzYW1lIG9yZGVyKSxcbiAga2Euc29ydCgpO1xuICBrYi5zb3J0KCk7XG4gIC8vfn5+Y2hlYXAga2V5IHRlc3RcbiAgZm9yIChpID0ga2EubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBpZiAoa2FbaV0gIT09IGtiW2ldKVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8vZXF1aXZhbGVudCB2YWx1ZXMgZm9yIGV2ZXJ5IGNvcnJlc3BvbmRpbmcga2V5LCBhbmRcbiAgLy9+fn5wb3NzaWJseSBleHBlbnNpdmUgZGVlcCB0ZXN0XG4gIGZvciAoaSA9IGthLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAga2V5ID0ga2FbaV07XG4gICAgaWYgKCFfZGVlcEVxdWFsKGFba2V5XSwgYltrZXldLCBzdHJpY3QsIGFjdHVhbFZpc2l0ZWRPYmplY3RzKSlcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLy8gOC4gVGhlIG5vbi1lcXVpdmFsZW5jZSBhc3NlcnRpb24gdGVzdHMgZm9yIGFueSBkZWVwIGluZXF1YWxpdHkuXG4vLyBhc3NlcnQubm90RGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0Lm5vdERlZXBFcXVhbCA9IGZ1bmN0aW9uIG5vdERlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChfZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIGZhbHNlKSkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJ25vdERlZXBFcXVhbCcsIGFzc2VydC5ub3REZWVwRXF1YWwpO1xuICB9XG59O1xuXG5hc3NlcnQubm90RGVlcFN0cmljdEVxdWFsID0gbm90RGVlcFN0cmljdEVxdWFsO1xuZnVuY3Rpb24gbm90RGVlcFN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKF9kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgdHJ1ZSkpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICdub3REZWVwU3RyaWN0RXF1YWwnLCBub3REZWVwU3RyaWN0RXF1YWwpO1xuICB9XG59XG5cblxuLy8gOS4gVGhlIHN0cmljdCBlcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgc3RyaWN0IGVxdWFsaXR5LCBhcyBkZXRlcm1pbmVkIGJ5ID09PS5cbi8vIGFzc2VydC5zdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5zdHJpY3RFcXVhbCA9IGZ1bmN0aW9uIHN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKGFjdHVhbCAhPT0gZXhwZWN0ZWQpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICc9PT0nLCBhc3NlcnQuc3RyaWN0RXF1YWwpO1xuICB9XG59O1xuXG4vLyAxMC4gVGhlIHN0cmljdCBub24tZXF1YWxpdHkgYXNzZXJ0aW9uIHRlc3RzIGZvciBzdHJpY3QgaW5lcXVhbGl0eSwgYXNcbi8vIGRldGVybWluZWQgYnkgIT09LiAgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0Lm5vdFN0cmljdEVxdWFsID0gZnVuY3Rpb24gbm90U3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoYWN0dWFsID09PSBleHBlY3RlZCkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJyE9PScsIGFzc2VydC5ub3RTdHJpY3RFcXVhbCk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGV4cGVjdGVkRXhjZXB0aW9uKGFjdHVhbCwgZXhwZWN0ZWQpIHtcbiAgaWYgKCFhY3R1YWwgfHwgIWV4cGVjdGVkKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChleHBlY3RlZCkgPT0gJ1tvYmplY3QgUmVnRXhwXScpIHtcbiAgICByZXR1cm4gZXhwZWN0ZWQudGVzdChhY3R1YWwpO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBpZiAoYWN0dWFsIGluc3RhbmNlb2YgZXhwZWN0ZWQpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vIElnbm9yZS4gIFRoZSBpbnN0YW5jZW9mIGNoZWNrIGRvZXNuJ3Qgd29yayBmb3IgYXJyb3cgZnVuY3Rpb25zLlxuICB9XG5cbiAgaWYgKEVycm9yLmlzUHJvdG90eXBlT2YoZXhwZWN0ZWQpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIGV4cGVjdGVkLmNhbGwoe30sIGFjdHVhbCkgPT09IHRydWU7XG59XG5cbmZ1bmN0aW9uIF90cnlCbG9jayhibG9jaykge1xuICB2YXIgZXJyb3I7XG4gIHRyeSB7XG4gICAgYmxvY2soKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGVycm9yID0gZTtcbiAgfVxuICByZXR1cm4gZXJyb3I7XG59XG5cbmZ1bmN0aW9uIF90aHJvd3Moc2hvdWxkVGhyb3csIGJsb2NrLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICB2YXIgYWN0dWFsO1xuXG4gIGlmICh0eXBlb2YgYmxvY2sgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImJsb2NrXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gIH1cblxuICBpZiAodHlwZW9mIGV4cGVjdGVkID09PSAnc3RyaW5nJykge1xuICAgIG1lc3NhZ2UgPSBleHBlY3RlZDtcbiAgICBleHBlY3RlZCA9IG51bGw7XG4gIH1cblxuICBhY3R1YWwgPSBfdHJ5QmxvY2soYmxvY2spO1xuXG4gIG1lc3NhZ2UgPSAoZXhwZWN0ZWQgJiYgZXhwZWN0ZWQubmFtZSA/ICcgKCcgKyBleHBlY3RlZC5uYW1lICsgJykuJyA6ICcuJykgK1xuICAgICAgICAgICAgKG1lc3NhZ2UgPyAnICcgKyBtZXNzYWdlIDogJy4nKTtcblxuICBpZiAoc2hvdWxkVGhyb3cgJiYgIWFjdHVhbCkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgJ01pc3NpbmcgZXhwZWN0ZWQgZXhjZXB0aW9uJyArIG1lc3NhZ2UpO1xuICB9XG5cbiAgdmFyIHVzZXJQcm92aWRlZE1lc3NhZ2UgPSB0eXBlb2YgbWVzc2FnZSA9PT0gJ3N0cmluZyc7XG4gIHZhciBpc1Vud2FudGVkRXhjZXB0aW9uID0gIXNob3VsZFRocm93ICYmIHV0aWwuaXNFcnJvcihhY3R1YWwpO1xuICB2YXIgaXNVbmV4cGVjdGVkRXhjZXB0aW9uID0gIXNob3VsZFRocm93ICYmIGFjdHVhbCAmJiAhZXhwZWN0ZWQ7XG5cbiAgaWYgKChpc1Vud2FudGVkRXhjZXB0aW9uICYmXG4gICAgICB1c2VyUHJvdmlkZWRNZXNzYWdlICYmXG4gICAgICBleHBlY3RlZEV4Y2VwdGlvbihhY3R1YWwsIGV4cGVjdGVkKSkgfHxcbiAgICAgIGlzVW5leHBlY3RlZEV4Y2VwdGlvbikge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgJ0dvdCB1bndhbnRlZCBleGNlcHRpb24nICsgbWVzc2FnZSk7XG4gIH1cblxuICBpZiAoKHNob3VsZFRocm93ICYmIGFjdHVhbCAmJiBleHBlY3RlZCAmJlxuICAgICAgIWV4cGVjdGVkRXhjZXB0aW9uKGFjdHVhbCwgZXhwZWN0ZWQpKSB8fCAoIXNob3VsZFRocm93ICYmIGFjdHVhbCkpIHtcbiAgICB0aHJvdyBhY3R1YWw7XG4gIH1cbn1cblxuLy8gMTEuIEV4cGVjdGVkIHRvIHRocm93IGFuIGVycm9yOlxuLy8gYXNzZXJ0LnRocm93cyhibG9jaywgRXJyb3Jfb3B0LCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC50aHJvd3MgPSBmdW5jdGlvbihibG9jaywgLypvcHRpb25hbCovZXJyb3IsIC8qb3B0aW9uYWwqL21lc3NhZ2UpIHtcbiAgX3Rocm93cyh0cnVlLCBibG9jaywgZXJyb3IsIG1lc3NhZ2UpO1xufTtcblxuLy8gRVhURU5TSU9OISBUaGlzIGlzIGFubm95aW5nIHRvIHdyaXRlIG91dHNpZGUgdGhpcyBtb2R1bGUuXG5hc3NlcnQuZG9lc05vdFRocm93ID0gZnVuY3Rpb24oYmxvY2ssIC8qb3B0aW9uYWwqL2Vycm9yLCAvKm9wdGlvbmFsKi9tZXNzYWdlKSB7XG4gIF90aHJvd3MoZmFsc2UsIGJsb2NrLCBlcnJvciwgbWVzc2FnZSk7XG59O1xuXG5hc3NlcnQuaWZFcnJvciA9IGZ1bmN0aW9uKGVycikgeyBpZiAoZXJyKSB0aHJvdyBlcnI7IH07XG5cbi8vIEV4cG9zZSBhIHN0cmljdCBvbmx5IHZhcmlhbnQgb2YgYXNzZXJ0XG5mdW5jdGlvbiBzdHJpY3QodmFsdWUsIG1lc3NhZ2UpIHtcbiAgaWYgKCF2YWx1ZSkgZmFpbCh2YWx1ZSwgdHJ1ZSwgbWVzc2FnZSwgJz09Jywgc3RyaWN0KTtcbn1cbmFzc2VydC5zdHJpY3QgPSBvYmplY3RBc3NpZ24oc3RyaWN0LCBhc3NlcnQsIHtcbiAgZXF1YWw6IGFzc2VydC5zdHJpY3RFcXVhbCxcbiAgZGVlcEVxdWFsOiBhc3NlcnQuZGVlcFN0cmljdEVxdWFsLFxuICBub3RFcXVhbDogYXNzZXJ0Lm5vdFN0cmljdEVxdWFsLFxuICBub3REZWVwRXF1YWw6IGFzc2VydC5ub3REZWVwU3RyaWN0RXF1YWxcbn0pO1xuYXNzZXJ0LnN0cmljdC5zdHJpY3QgPSBhc3NlcnQuc3RyaWN0O1xuXG52YXIgb2JqZWN0S2V5cyA9IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIChvYmopIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgIGlmIChoYXNPd24uY2FsbChvYmosIGtleSkpIGtleXMucHVzaChrZXkpO1xuICB9XG4gIHJldHVybiBrZXlzO1xufTtcbiIsIi8vIEBmbG93XG5cbi8qKlxuICogRGVlcGx5IGNvbXBhcmVzIHR3byBvYmplY3QgbGl0ZXJhbHMuXG4gKlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZGVlcEVxdWFsKGE6ID9taXhlZCwgYjogP21peGVkKTogYm9vbGVhbiB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYSkpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGIpIHx8IGEubGVuZ3RoICE9PSBiLmxlbmd0aCkgcmV0dXJuIGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICghZGVlcEVxdWFsKGFbaV0sIGJbaV0pKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgYSA9PT0gJ29iamVjdCcgJiYgYSAhPT0gbnVsbCAmJiBiICE9PSBudWxsKSB7XG4gICAgICAgIGlmICghKHR5cGVvZiBiID09PSAnb2JqZWN0JykpIHJldHVybiBmYWxzZTtcbiAgICAgICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKGEpO1xuICAgICAgICBpZiAoa2V5cy5sZW5ndGggIT09IE9iamVjdC5rZXlzKGIpLmxlbmd0aCkgcmV0dXJuIGZhbHNlO1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBhKSB7XG4gICAgICAgICAgICBpZiAoIWRlZXBFcXVhbChhW2tleV0sIGJba2V5XSkpIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGEgPT09IGI7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGRlZXBFcXVhbDtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCBVbml0QmV6aWVyIGZyb20gJ0BtYXBib3gvdW5pdGJlemllcic7XG5cbmltcG9ydCBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCB3aW5kb3cgZnJvbSAnLi93aW5kb3cuanMnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuXG5pbXBvcnQgdHlwZSB7Q2FsbGJhY2t9IGZyb20gJy4uL3R5cGVzL2NhbGxiYWNrLmpzJztcbmltcG9ydCB0eXBlIHtNYXQ0LCBWZWM0fSBmcm9tICdnbC1tYXRyaXgnO1xuXG5jb25zdCBERUdfVE9fUkFEID0gTWF0aC5QSSAvIDE4MDtcbmNvbnN0IFJBRF9UT19ERUcgPSAxODAgLyBNYXRoLlBJO1xuXG4vKipcbiAqIENvbnZlcnRzIGFuIGFuZ2xlIGluIGRlZ3JlZXMgdG8gcmFkaWFuc1xuICogY29weSBhbGwgcHJvcGVydGllcyBmcm9tIHRoZSBzb3VyY2Ugb2JqZWN0cyBpbnRvIHRoZSBkZXN0aW5hdGlvbi5cbiAqIFRoZSBsYXN0IHNvdXJjZSBvYmplY3QgZ2l2ZW4gb3ZlcnJpZGVzIHByb3BlcnRpZXMgZnJvbSBwcmV2aW91c1xuICogc291cmNlIG9iamVjdHMuXG4gKlxuICogQHBhcmFtIGEgYW5nbGUgdG8gY29udmVydFxuICogQHJldHVybnMgdGhlIGFuZ2xlIGluIHJhZGlhbnNcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWdUb1JhZChhOiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiBhICogREVHX1RPX1JBRDtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhbiBhbmdsZSBpbiByYWRpYW5zIHRvIGRlZ3JlZXNcbiAqIGNvcHkgYWxsIHByb3BlcnRpZXMgZnJvbSB0aGUgc291cmNlIG9iamVjdHMgaW50byB0aGUgZGVzdGluYXRpb24uXG4gKiBUaGUgbGFzdCBzb3VyY2Ugb2JqZWN0IGdpdmVuIG92ZXJyaWRlcyBwcm9wZXJ0aWVzIGZyb20gcHJldmlvdXNcbiAqIHNvdXJjZSBvYmplY3RzLlxuICpcbiAqIEBwYXJhbSBhIGFuZ2xlIHRvIGNvbnZlcnRcbiAqIEByZXR1cm5zIHRoZSBhbmdsZSBpbiBkZWdyZWVzXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gcmFkVG9EZWcoYTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gYSAqIFJBRF9UT19ERUc7XG59XG5cbmNvbnN0IFRJTEVfQ09STkVSUyA9IFtbMCwgMF0sIFsxLCAwXSwgWzEsIDFdLCBbMCwgMV1dO1xuXG4vKipcbiAqIEdpdmVuIGEgcGFydGljdWxhciBiZWFyaW5nLCByZXR1cm5zIHRoZSBjb3JuZXIgb2YgdGhlIHRpbGUgdGhhdHMgZmFydGhlc3RcbiAqIGFsb25nIHRoZSBiZWFyaW5nLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBiZWFyaW5nIGFuZ2xlIGluIGRlZ3JlZXMgKC0xODAsIDE4MF1cbiAqIEByZXR1cm5zIHtRdWFkQ29ybmVyfVxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZ1cnRoZXN0VGlsZUNvcm5lcihiZWFyaW5nOiBudW1iZXIpOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgICBjb25zdCBhbGlnbmVkQmVhcmluZyA9ICgoYmVhcmluZyArIDQ1KSArIDM2MCkgJSAzNjA7XG4gICAgY29uc3QgY29ybmVySWR4ID0gTWF0aC5yb3VuZChhbGlnbmVkQmVhcmluZyAvIDkwKSAlIDQ7XG4gICAgcmV0dXJuIFRJTEVfQ09STkVSU1tjb3JuZXJJZHhdO1xufVxuXG4vKipcbiAqIEBtb2R1bGUgdXRpbFxuICogQHByaXZhdGVcbiAqL1xuXG4vKipcbiAqIEdpdmVuIGEgdmFsdWUgYHRgIHRoYXQgdmFyaWVzIGJldHdlZW4gMCBhbmQgMSwgcmV0dXJuXG4gKiBhbiBpbnRlcnBvbGF0aW9uIGZ1bmN0aW9uIHRoYXQgZWFzZXMgYmV0d2VlbiAwIGFuZCAxIGluIGEgcGxlYXNpbmdcbiAqIGN1YmljIGluLW91dCBmYXNoaW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlYXNlQ3ViaWNJbk91dCh0OiBudW1iZXIpOiBudW1iZXIge1xuICAgIGlmICh0IDw9IDApIHJldHVybiAwO1xuICAgIGlmICh0ID49IDEpIHJldHVybiAxO1xuICAgIGNvbnN0IHQyID0gdCAqIHQsXG4gICAgICAgIHQzID0gdDIgKiB0O1xuICAgIHJldHVybiA0ICogKHQgPCAwLjUgPyB0MyA6IDMgKiAodCAtIHQyKSArIHQzIC0gMC43NSk7XG59XG5cbi8qKlxuICogQ29tcHV0ZXMgYW4gQUFCQiBmb3IgYSBzZXQgb2YgcG9pbnRzLlxuICpcbiAqIEBwYXJhbSB7UG9pbnRbXX0gcG9pbnRzXG4gKiBAcmV0dXJucyB7eyBtaW46IFBvaW50LCBtYXg6IFBvaW50fX1cbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRCb3VuZHMocG9pbnRzOiBQb2ludFtdKTogeyBtaW46IFBvaW50LCBtYXg6IFBvaW50fSB7XG4gICAgbGV0IG1pblggPSBJbmZpbml0eTtcbiAgICBsZXQgbWluWSA9IEluZmluaXR5O1xuICAgIGxldCBtYXhYID0gLUluZmluaXR5O1xuICAgIGxldCBtYXhZID0gLUluZmluaXR5O1xuICAgIGZvciAoY29uc3QgcCBvZiBwb2ludHMpIHtcbiAgICAgICAgbWluWCA9IE1hdGgubWluKG1pblgsIHAueCk7XG4gICAgICAgIG1pblkgPSBNYXRoLm1pbihtaW5ZLCBwLnkpO1xuICAgICAgICBtYXhYID0gTWF0aC5tYXgobWF4WCwgcC54KTtcbiAgICAgICAgbWF4WSA9IE1hdGgubWF4KG1heFksIHAueSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgbWluOiBuZXcgUG9pbnQobWluWCwgbWluWSksXG4gICAgICAgIG1heDogbmV3IFBvaW50KG1heFgsIG1heFkpLFxuICAgIH07XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgc3F1YXJlIG9mIHRoZSAyRCBkaXN0YW5jZSBiZXR3ZWVuIGFuIEFBQkIgZGVmaW5lZCBieSBtaW4gYW5kIG1heCBhbmQgYSBwb2ludC5cbiAqIElmIHBvaW50IGlzIG51bGwgb3IgdW5kZWZpbmVkLCB0aGUgQUFCQiBkaXN0YW5jZSBmcm9tIHRoZSBvcmlnaW4gKDAsMCkgaXMgcmV0dXJuZWQuXG4gKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBtaW4gVGhlIG1pbmltdW0gZXh0ZW50IG9mIHRoZSBBQUJCLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBtYXggVGhlIG1heGltdW0gZXh0ZW50IG9mIHRoZSBBQUJCLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBbcG9pbnRdIFRoZSBwb2ludCB0byBjb21wdXRlIHRoZSBkaXN0YW5jZSBmcm9tLCBtYXkgYmUgdW5kZWZpbmVkLlxuICogQHJldHVybnMge251bWJlcn0gVGhlIHNxdWFyZSBkaXN0YW5jZSBmcm9tIHRoZSBBQUJCLCAwLjAgaWYgdGhlIEFBQkIgY29udGFpbnMgdGhlIHBvaW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0QUFCQlBvaW50U3F1YXJlRGlzdChtaW46IEFycmF5PG51bWJlcj4sIG1heDogQXJyYXk8bnVtYmVyPiwgcG9pbnQ6ID9BcnJheTxudW1iZXI+KTogbnVtYmVyIHtcbiAgICBsZXQgc3FEaXN0ID0gMC4wO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCAyOyArK2kpIHtcbiAgICAgICAgY29uc3QgdiA9IHBvaW50ID8gcG9pbnRbaV0gOiAwLjA7XG4gICAgICAgIGFzc2VydChtaW5baV0gPCBtYXhbaV0sICdJbnZhbGlkIGFhYmIgbWluIGFuZCBtYXggaW5wdXRzLCBtaW5baV0gbXVzdCBiZSA8IG1heFtpXS4nKTtcbiAgICAgICAgaWYgKG1pbltpXSA+IHYpIHNxRGlzdCArPSAobWluW2ldIC0gdikgKiAobWluW2ldIC0gdik7XG4gICAgICAgIGlmIChtYXhbaV0gPCB2KSBzcURpc3QgKz0gKHYgLSBtYXhbaV0pICogKHYgLSBtYXhbaV0pO1xuICAgIH1cblxuICAgIHJldHVybiBzcURpc3Q7XG59XG5cbi8qKlxuICogQ29udmVydHMgYSBBQUJCIGludG8gYSBwb2x5Z29uIHdpdGggY2xvY2t3aXNlIHdpbmRpbmcgb3JkZXIuXG4gKlxuICogQHBhcmFtIHtQb2ludH0gbWluIFRoZSB0b3AgbGVmdCBwb2ludC5cbiAqIEBwYXJhbSB7UG9pbnR9IG1heCBUaGUgYm90dG9tIHJpZ2h0IHBvaW50LlxuICogQHBhcmFtIHtudW1iZXJ9IFtidWZmZXI9MF0gVGhlIGJ1ZmZlciB3aWR0aC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Nsb3NlPXRydWVdIFdoZXRoZXIgdG8gY2xvc2UgdGhlIHBvbHlnb24gb3Igbm90LlxuICogQHJldHVybnMge1BvaW50W119IFRoZSBwb2x5Z29uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcG9seWdvbml6ZUJvdW5kcyhtaW46IFBvaW50LCBtYXg6IFBvaW50LCBidWZmZXI6IG51bWJlciA9IDAsIGNsb3NlOiBib29sZWFuID0gdHJ1ZSk6IFBvaW50W10ge1xuICAgIGNvbnN0IG9mZnNldCA9IG5ldyBQb2ludChidWZmZXIsIGJ1ZmZlcik7XG4gICAgY29uc3QgbWluQnVmID0gbWluLnN1YihvZmZzZXQpO1xuICAgIGNvbnN0IG1heEJ1ZiA9IG1heC5hZGQob2Zmc2V0KTtcbiAgICBjb25zdCBwb2x5Z29uID0gW21pbkJ1ZiwgbmV3IFBvaW50KG1heEJ1Zi54LCBtaW5CdWYueSksIG1heEJ1ZiwgbmV3IFBvaW50KG1pbkJ1Zi54LCBtYXhCdWYueSldO1xuXG4gICAgaWYgKGNsb3NlKSB7XG4gICAgICAgIHBvbHlnb24ucHVzaChtaW5CdWYuY2xvbmUoKSk7XG4gICAgfVxuICAgIHJldHVybiBwb2x5Z29uO1xufVxuXG4vKipcbiAqIFRha2VzIGEgY29udmV4IHJpbmcgYW5kIGV4cGFuZHMgaXQgb3V0d2FyZCBieSBhcHBseWluZyBhIGJ1ZmZlciBhcm91bmQgaXQuXG4gKiBUaGlzIGZ1bmN0aW9uIGFzc3VtZXMgdGhhdCB0aGUgcmluZyBpcyBpbiBjbG9ja3dpc2Ugd2luZGluZyBvcmRlci5cbiAqXG4gKiBAcGFyYW0ge1BvaW50W119IHJpbmcgVGhlIGlucHV0IHJpbmcuXG4gKiBAcGFyYW0ge251bWJlcn0gYnVmZmVyIFRoZSBidWZmZXIgd2lkdGguXG4gKiBAcmV0dXJucyB7UG9pbnRbXX0gVGhlIGV4cGFuZGVkIHJpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWZmZXJDb252ZXhQb2x5Z29uKHJpbmc6IFBvaW50W10sIGJ1ZmZlcjogbnVtYmVyKTogUG9pbnRbXSB7XG4gICAgYXNzZXJ0KHJpbmcubGVuZ3RoID4gMiwgJ2J1ZmZlckNvbnZleFBvbHlnb24gcmVxdWlyZXMgdGhlIHJpbmcgdG8gaGF2ZSBhdGxlYXN0IDMgcG9pbnRzJyk7XG4gICAgY29uc3Qgb3V0cHV0ID0gW107XG4gICAgZm9yIChsZXQgY3VycklkeCA9IDA7IGN1cnJJZHggPCByaW5nLmxlbmd0aDsgY3VycklkeCsrKSB7XG4gICAgICAgIGNvbnN0IHByZXZJZHggPSB3cmFwKGN1cnJJZHggLSAxLCAtMSwgcmluZy5sZW5ndGggLSAxKTtcbiAgICAgICAgY29uc3QgbmV4dElkeCA9IHdyYXAoY3VycklkeCArIDEsIC0xLCByaW5nLmxlbmd0aCAtIDEpO1xuICAgICAgICBjb25zdCBwcmV2ID0gcmluZ1twcmV2SWR4XTtcbiAgICAgICAgY29uc3QgY3VyciA9IHJpbmdbY3VycklkeF07XG4gICAgICAgIGNvbnN0IG5leHQgPSByaW5nW25leHRJZHhdO1xuICAgICAgICBjb25zdCBwMSA9IHByZXYuc3ViKGN1cnIpLnVuaXQoKTtcbiAgICAgICAgY29uc3QgcDIgPSBuZXh0LnN1YihjdXJyKS51bml0KCk7XG4gICAgICAgIGNvbnN0IGludGVyaW9yQW5nbGUgPSBwMi5hbmdsZVdpdGhTZXAocDEueCwgcDEueSk7XG4gICAgICAgIC8vIENhbGN1YXRlIGEgdmVjdG9yIHRoYXQgcG9pbnRzIGluIHRoZSBkaXJlY3Rpb24gb2YgdGhlIGFuZ2xlIGJpc2VjdG9yIGJldHdlZW4gdHdvIHNpZGVzLlxuICAgICAgICAvLyBTY2FsZSBpdCBiYXNlZCBvbiBhIHJpZ2h0IGFuZ2xlZCB0cmlhbmdsZSBjb25zdHJ1Y3RlZCBhdCB0aGF0IGNvcm5lci5cbiAgICAgICAgY29uc3Qgb2Zmc2V0ID0gcDEuYWRkKHAyKS51bml0KCkubXVsdCgtMSAqIGJ1ZmZlciAvIE1hdGguc2luKGludGVyaW9yQW5nbGUgLyAyKSk7XG4gICAgICAgIG91dHB1dC5wdXNoKGN1cnIuYWRkKG9mZnNldCkpO1xuICAgIH1cbiAgICByZXR1cm4gb3V0cHV0O1xufVxuXG50eXBlIEVhc2VGdW5jdGlvbiA9ICh0OiBudW1iZXIpID0+IG51bWJlcjtcblxuLyoqXG4gKiBHaXZlbiBnaXZlbiAoeCwgeSksICh4MSwgeTEpIGNvbnRyb2wgcG9pbnRzIGZvciBhIGJlemllciBjdXJ2ZSxcbiAqIHJldHVybiBhIGZ1bmN0aW9uIHRoYXQgaW50ZXJwb2xhdGVzIGFsb25nIHRoYXQgY3VydmUuXG4gKlxuICogQHBhcmFtIHAxeCBjb250cm9sIHBvaW50IDEgeCBjb29yZGluYXRlXG4gKiBAcGFyYW0gcDF5IGNvbnRyb2wgcG9pbnQgMSB5IGNvb3JkaW5hdGVcbiAqIEBwYXJhbSBwMnggY29udHJvbCBwb2ludCAyIHggY29vcmRpbmF0ZVxuICogQHBhcmFtIHAyeSBjb250cm9sIHBvaW50IDIgeSBjb29yZGluYXRlXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gYmV6aWVyKHAxeDogbnVtYmVyLCBwMXk6IG51bWJlciwgcDJ4OiBudW1iZXIsIHAyeTogbnVtYmVyKTogRWFzZUZ1bmN0aW9uIHtcbiAgICBjb25zdCBiZXppZXIgPSBuZXcgVW5pdEJlemllcihwMXgsIHAxeSwgcDJ4LCBwMnkpO1xuICAgIHJldHVybiBmdW5jdGlvbih0OiBudW1iZXIpIHtcbiAgICAgICAgcmV0dXJuIGJlemllci5zb2x2ZSh0KTtcbiAgICB9O1xufVxuXG4vKipcbiAqIEEgZGVmYXVsdCBiZXppZXItY3VydmUgcG93ZXJlZCBlYXNpbmcgZnVuY3Rpb24gd2l0aFxuICogY29udHJvbCBwb2ludHMgKDAuMjUsIDAuMSkgYW5kICgwLjI1LCAxKVxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBjb25zdCBlYXNlOiBFYXNlRnVuY3Rpb24gPSBiZXppZXIoMC4yNSwgMC4xLCAwLjI1LCAxKTtcblxuLyoqXG4gKiBjb25zdHJhaW4gbiB0byB0aGUgZ2l2ZW4gcmFuZ2UgdmlhIG1pbiArIG1heFxuICpcbiAqIEBwYXJhbSBuIHZhbHVlXG4gKiBAcGFyYW0gbWluIHRoZSBtaW5pbXVtIHZhbHVlIHRvIGJlIHJldHVybmVkXG4gKiBAcGFyYW0gbWF4IHRoZSBtYXhpbXVtIHZhbHVlIHRvIGJlIHJldHVybmVkXG4gKiBAcmV0dXJucyB0aGUgY2xhbXBlZCB2YWx1ZVxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsYW1wKG46IG51bWJlciwgbWluOiBudW1iZXIsIG1heDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gTWF0aC5taW4obWF4LCBNYXRoLm1heChtaW4sIG4pKTtcbn1cblxuLyoqXG4gKiBFcXVpdmFsZW50IHRvIEdMU0wgc21vb3Roc3RlcC5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gZTAgVGhlIGxvd2VyIGVkZ2Ugb2YgdGhlIHNpZ21vaWRcbiAqIEBwYXJhbSB7bnVtYmVyfSBlMSBUaGUgdXBwZXIgZWRnZSBvZiB0aGUgc2lnbW9pZFxuICogQHBhcmFtIHtudW1iZXJ9IHggdGhlIHZhbHVlIHRvIGJlIGludGVycG9sYXRlZFxuICogQHJldHVybnMge251bWJlcn0gaW4gdGhlIHJhbmdlIFswLCAxXVxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNtb290aHN0ZXAoZTA6IG51bWJlciwgZTE6IG51bWJlciwgeDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICB4ID0gY2xhbXAoKHggLSBlMCkgLyAoZTEgLSBlMCksIDAsIDEpO1xuICAgIHJldHVybiB4ICogeCAqICgzIC0gMiAqIHgpO1xufVxuXG4vKipcbiAqIGNvbnN0cmFpbiBuIHRvIHRoZSBnaXZlbiByYW5nZSwgZXhjbHVkaW5nIHRoZSBtaW5pbXVtLCB2aWEgbW9kdWxhciBhcml0aG1ldGljXG4gKlxuICogQHBhcmFtIG4gdmFsdWVcbiAqIEBwYXJhbSBtaW4gdGhlIG1pbmltdW0gdmFsdWUgdG8gYmUgcmV0dXJuZWQsIGV4Y2x1c2l2ZVxuICogQHBhcmFtIG1heCB0aGUgbWF4aW11bSB2YWx1ZSB0byBiZSByZXR1cm5lZCwgaW5jbHVzaXZlXG4gKiBAcmV0dXJucyBjb25zdHJhaW5lZCBudW1iZXJcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cmFwKG46IG51bWJlciwgbWluOiBudW1iZXIsIG1heDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBjb25zdCBkID0gbWF4IC0gbWluO1xuICAgIGNvbnN0IHcgPSAoKG4gLSBtaW4pICUgZCArIGQpICUgZCArIG1pbjtcbiAgICByZXR1cm4gKHcgPT09IG1pbikgPyBtYXggOiB3O1xufVxuXG4vKipcbiAqIENvbXB1dGVzIHNob3J0ZXN0IGFuZ2xlIGluIHJhbmdlIFstMTgwLCAxODApIGJldHdlZW4gdHdvIGFuZ2xlcy5cbiAqXG4gKiBAcGFyYW0geyp9IGEgRmlyc3QgYW5nbGUgaW4gZGVncmVlc1xuICogQHBhcmFtIHsqfSBiIFNlY29uZCBhbmdsZSBpbiBkZWdyZWVzXG4gKiBAcmV0dXJucyBTaG9ydGVzdCBhbmdsZVxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNob3J0ZXN0QW5nbGUoYTogbnVtYmVyLCBiOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGNvbnN0IGRpZmYgPSAoYiAtIGEgKyAxODApICUgMzYwIC0gMTgwO1xuICAgIHJldHVybiBkaWZmIDwgLTE4MCA/IGRpZmYgKyAzNjAgOiBkaWZmO1xufVxuXG4vKlxuICogQ2FsbCBhbiBhc3luY2hyb25vdXMgZnVuY3Rpb24gb24gYW4gYXJyYXkgb2YgYXJndW1lbnRzLFxuICogY2FsbGluZyBgY2FsbGJhY2tgIHdpdGggdGhlIGNvbXBsZXRlZCByZXN1bHRzIG9mIGFsbCBjYWxscy5cbiAqXG4gKiBAcGFyYW0gYXJyYXkgaW5wdXQgdG8gZWFjaCBjYWxsIG9mIHRoZSBhc3luYyBmdW5jdGlvbi5cbiAqIEBwYXJhbSBmbiBhbiBhc3luYyBmdW5jdGlvbiB3aXRoIHNpZ25hdHVyZSAoZGF0YSwgY2FsbGJhY2spXG4gKiBAcGFyYW0gY2FsbGJhY2sgYSBjYWxsYmFjayBydW4gYWZ0ZXIgYWxsIGFzeW5jIHdvcmsgaXMgZG9uZS5cbiAqIGNhbGxlZCB3aXRoIGFuIGFycmF5LCBjb250YWluaW5nIHRoZSByZXN1bHRzIG9mIGVhY2ggYXN5bmMgY2FsbC5cbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhc3luY0FsbDxJdGVtLCBSZXN1bHQ+KFxuICAgIGFycmF5OiBBcnJheTxJdGVtPixcbiAgICBmbjogKGl0ZW06IEl0ZW0sIGZuQ2FsbGJhY2s6IENhbGxiYWNrPFJlc3VsdD4pID0+IHZvaWQsXG4gICAgY2FsbGJhY2s6IENhbGxiYWNrPEFycmF5PFJlc3VsdD4+XG4pOiB2b2lkIHtcbiAgICBpZiAoIWFycmF5Lmxlbmd0aCkgeyByZXR1cm4gY2FsbGJhY2sobnVsbCwgW10pOyB9XG4gICAgbGV0IHJlbWFpbmluZyA9IGFycmF5Lmxlbmd0aDtcbiAgICBjb25zdCByZXN1bHRzID0gbmV3IEFycmF5KGFycmF5Lmxlbmd0aCk7XG4gICAgbGV0IGVycm9yID0gbnVsbDtcbiAgICBhcnJheS5mb3JFYWNoKChpdGVtLCBpKSA9PiB7XG4gICAgICAgIGZuKGl0ZW0sIChlcnIsIHJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgaWYgKGVycikgZXJyb3IgPSBlcnI7XG4gICAgICAgICAgICByZXN1bHRzW2ldID0gKChyZXN1bHQ6IGFueSk6IFJlc3VsdCk7IC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9mbG93L2lzc3Vlcy8yMTIzXG4gICAgICAgICAgICBpZiAoLS1yZW1haW5pbmcgPT09IDApIGNhbGxiYWNrKGVycm9yLCByZXN1bHRzKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59XG5cbi8qXG4gKiBQb2x5ZmlsbCBmb3IgT2JqZWN0LnZhbHVlcy4gTm90IGZ1bGx5IHNwZWMgY29tcGxpYW50LCBidXQgd2UgZG9uJ3RcbiAqIG5lZWQgaXQgdG8gYmUuXG4gKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbHVlczxUPihvYmo6IHtba2V5OiBzdHJpbmddOiBUfSk6IEFycmF5PFQ+IHtcbiAgICBjb25zdCByZXN1bHQgPSBbXTtcbiAgICBmb3IgKGNvbnN0IGsgaW4gb2JqKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKG9ialtrXSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbi8qXG4gKiBDb21wdXRlIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIGtleXMgaW4gb25lIG9iamVjdCBhbmQgdGhlIGtleXNcbiAqIGluIGFub3RoZXIgb2JqZWN0LlxuICpcbiAqIEByZXR1cm5zIGtleXMgZGlmZmVyZW5jZVxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGtleXNEaWZmZXJlbmNlPFMsIFQ+KG9iajoge1trZXk6IHN0cmluZ106IFN9LCBvdGhlcjoge1trZXk6IHN0cmluZ106IFR9KTogQXJyYXk8c3RyaW5nPiB7XG4gICAgY29uc3QgZGlmZmVyZW5jZSA9IFtdO1xuICAgIGZvciAoY29uc3QgaSBpbiBvYmopIHtcbiAgICAgICAgaWYgKCEoaSBpbiBvdGhlcikpIHtcbiAgICAgICAgICAgIGRpZmZlcmVuY2UucHVzaChpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGlmZmVyZW5jZTtcbn1cblxuLyoqXG4gKiBHaXZlbiBhIGRlc3RpbmF0aW9uIG9iamVjdCBhbmQgb3B0aW9uYWxseSBtYW55IHNvdXJjZSBvYmplY3RzLFxuICogY29weSBhbGwgcHJvcGVydGllcyBmcm9tIHRoZSBzb3VyY2Ugb2JqZWN0cyBpbnRvIHRoZSBkZXN0aW5hdGlvbi5cbiAqIFRoZSBsYXN0IHNvdXJjZSBvYmplY3QgZ2l2ZW4gb3ZlcnJpZGVzIHByb3BlcnRpZXMgZnJvbSBwcmV2aW91c1xuICogc291cmNlIG9iamVjdHMuXG4gKlxuICogQHBhcmFtIGRlc3QgZGVzdGluYXRpb24gb2JqZWN0XG4gKiBAcGFyYW0gc291cmNlcyBzb3VyY2VzIGZyb20gd2hpY2ggcHJvcGVydGllcyBhcmUgcHVsbGVkXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZXh0ZW5kKGRlc3Q6IE9iamVjdCwgLi4uc291cmNlczogQXJyYXk8P09iamVjdD4pOiBPYmplY3Qge1xuICAgIGZvciAoY29uc3Qgc3JjIG9mIHNvdXJjZXMpIHtcbiAgICAgICAgZm9yIChjb25zdCBrIGluIHNyYykge1xuICAgICAgICAgICAgZGVzdFtrXSA9IHNyY1trXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGVzdDtcbn1cblxuLyoqXG4gKiBHaXZlbiBhbiBvYmplY3QgYW5kIGEgbnVtYmVyIG9mIHByb3BlcnRpZXMgYXMgc3RyaW5ncywgcmV0dXJuIHZlcnNpb25cbiAqIG9mIHRoYXQgb2JqZWN0IHdpdGggb25seSB0aG9zZSBwcm9wZXJ0aWVzLlxuICpcbiAqIEBwYXJhbSBzcmMgdGhlIG9iamVjdFxuICogQHBhcmFtIHByb3BlcnRpZXMgYW4gYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMgY2hvc2VuXG4gKiB0byBhcHBlYXIgb24gdGhlIHJlc3VsdGluZyBvYmplY3QuXG4gKiBAcmV0dXJucyBvYmplY3Qgd2l0aCBsaW1pdGVkIHByb3BlcnRpZXMuXG4gKiBAZXhhbXBsZVxuICogdmFyIGZvbyA9IHsgbmFtZTogJ0NoYXJsaWUnLCBhZ2U6IDEwIH07XG4gKiB2YXIganVzdE5hbWUgPSBwaWNrKGZvbywgWyduYW1lJ10pO1xuICogLy8ganVzdE5hbWUgPSB7IG5hbWU6ICdDaGFybGllJyB9XG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gcGljayhzcmM6IE9iamVjdCwgcHJvcGVydGllczogQXJyYXk8c3RyaW5nPik6IE9iamVjdCB7XG4gICAgY29uc3QgcmVzdWx0ID0ge307XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwcm9wZXJ0aWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGsgPSBwcm9wZXJ0aWVzW2ldO1xuICAgICAgICBpZiAoayBpbiBzcmMpIHtcbiAgICAgICAgICAgIHJlc3VsdFtrXSA9IHNyY1trXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG5sZXQgaWQgPSAxO1xuXG4vKipcbiAqIFJldHVybiBhIHVuaXF1ZSBudW1lcmljIGlkLCBzdGFydGluZyBhdCAxIGFuZCBpbmNyZW1lbnRpbmcgd2l0aFxuICogZWFjaCBjYWxsLlxuICpcbiAqIEByZXR1cm5zIHVuaXF1ZSBudW1lcmljIGlkLlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVuaXF1ZUlkKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIGlkKys7XG59XG5cbi8qKlxuICogUmV0dXJuIGEgcmFuZG9tIFVVSUQgKHY0KS4gVGFrZW4gZnJvbTogaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vamVkLzk4Mjg4M1xuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHV1aWQoKTogc3RyaW5nIHtcbiAgICBmdW5jdGlvbiBiKGE6IHZvaWQpIHtcbiAgICAgICAgcmV0dXJuIGEgPyAoYSBeIE1hdGgucmFuZG9tKCkgKiAoMTYgPj4gYSAvIDQpKS50b1N0cmluZygxNikgOlxuICAgICAgICAvLyRGbG93Rml4TWU6IEZsb3cgZG9lc24ndCBsaWtlIHRoZSBpbXBsaWVkIGFycmF5IGxpdGVyYWwgY29udmVyc2lvbiBoZXJlXG4gICAgICAgICAgICAoWzFlN10gKyAtWzFlM10gKyAtNGUzICsgLThlMyArIC0xZTExKS5yZXBsYWNlKC9bMDE4XS9nLCBiKTtcbiAgICB9XG4gICAgcmV0dXJuIGIoKTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gd2hldGhlciBhIGdpdmVuIHZhbHVlIGlzIGEgcG93ZXIgb2YgdHdvXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNQb3dlck9mVHdvKHZhbHVlOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKE1hdGgubG9nKHZhbHVlKSAvIE1hdGguTE4yKSAlIDEgPT09IDA7XG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSBuZXh0IHBvd2VyIG9mIHR3bywgb3IgdGhlIGlucHV0IHZhbHVlIGlmIGFscmVhZHkgYSBwb3dlciBvZiB0d29cbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBuZXh0UG93ZXJPZlR3byh2YWx1ZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBpZiAodmFsdWUgPD0gMSkgcmV0dXJuIDE7XG4gICAgcmV0dXJuIE1hdGgucG93KDIsIE1hdGguY2VpbChNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMikpO1xufVxuXG4vKipcbiAqIFJldHVybiB0aGUgcHJldmlvdXMgcG93ZXIgb2YgdHdvLCBvciB0aGUgaW5wdXQgdmFsdWUgaWYgYWxyZWFkeSBhIHBvd2VyIG9mIHR3b1xuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByZXZQb3dlck9mVHdvKHZhbHVlOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGlmICh2YWx1ZSA8PSAxKSByZXR1cm4gMTtcbiAgICByZXR1cm4gTWF0aC5wb3coMiwgTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMikpO1xufVxuXG4vKipcbiAqIFZhbGlkYXRlIGEgc3RyaW5nIHRvIG1hdGNoIFVVSUQodjQpIG9mIHRoZVxuICogZm9ybTogeHh4eHh4eHgteHh4eC00eHh4LVs4OWFiXXh4eC14eHh4eHh4eHh4eHhcbiAqIEBwYXJhbSBzdHIgc3RyaW5nIHRvIHZhbGlkYXRlLlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlVXVpZChzdHI6ID9zdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gc3RyID8gL15bMC05YS1mXXs4fS1bMC05YS1mXXs0fS1bNF1bMC05YS1mXXszfS1bODlhYl1bMC05YS1mXXszfS1bMC05YS1mXXsxMn0kL2kudGVzdChzdHIpIDogZmFsc2U7XG59XG5cbi8qKlxuICogR2l2ZW4gYW4gYXJyYXkgb2YgbWVtYmVyIGZ1bmN0aW9uIG5hbWVzIGFzIHN0cmluZ3MsIHJlcGxhY2UgYWxsIG9mIHRoZW1cbiAqIHdpdGggYm91bmQgdmVyc2lvbnMgdGhhdCB3aWxsIGFsd2F5cyByZWZlciB0byBgY29udGV4dGAgYXMgYHRoaXNgLiBUaGlzXG4gKiBpcyB1c2VmdWwgZm9yIGNsYXNzZXMgd2hlcmUgb3RoZXJ3aXNlIGV2ZW50IGJpbmRpbmdzIHdvdWxkIHJlYXNzaWduXG4gKiBgdGhpc2AgdG8gdGhlIGV2ZW50ZWQgb2JqZWN0IG9yIHNvbWUgb3RoZXIgdmFsdWU6IHRoaXMgbGV0cyB5b3UgZW5zdXJlXG4gKiB0aGUgYHRoaXNgIHZhbHVlIGFsd2F5cy5cbiAqXG4gKiBAcGFyYW0gZm5zIGxpc3Qgb2YgbWVtYmVyIGZ1bmN0aW9uIG5hbWVzXG4gKiBAcGFyYW0gY29udGV4dCB0aGUgY29udGV4dCB2YWx1ZVxuICogQGV4YW1wbGVcbiAqIGZ1bmN0aW9uIE15Q2xhc3MoKSB7XG4gKiAgIGJpbmRBbGwoWydvbnRpbWVyJ10sIHRoaXMpO1xuICogICB0aGlzLm5hbWUgPSAnVG9tJztcbiAqIH1cbiAqIE15Q2xhc3MucHJvdG90eXBlLm9udGltZXIgPSBmdW5jdGlvbigpIHtcbiAqICAgYWxlcnQodGhpcy5uYW1lKTtcbiAqIH07XG4gKiB2YXIgbXlDbGFzcyA9IG5ldyBNeUNsYXNzKCk7XG4gKiBzZXRUaW1lb3V0KG15Q2xhc3Mub250aW1lciwgMTAwKTtcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiaW5kQWxsKGZuczogQXJyYXk8c3RyaW5nPiwgY29udGV4dDogT2JqZWN0KTogdm9pZCB7XG4gICAgZm5zLmZvckVhY2goKGZuKSA9PiB7XG4gICAgICAgIGlmICghY29udGV4dFtmbl0pIHsgcmV0dXJuOyB9XG4gICAgICAgIGNvbnRleHRbZm5dID0gY29udGV4dFtmbl0uYmluZChjb250ZXh0KTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSBzdHJpbmcgZW5kcyB3aXRoIGEgcGFydGljdWxhciBzdWJzdHJpbmdcbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZW5kc1dpdGgoc3RyaW5nOiBzdHJpbmcsIHN1ZmZpeDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHN0cmluZy5pbmRleE9mKHN1ZmZpeCwgc3RyaW5nLmxlbmd0aCAtIHN1ZmZpeC5sZW5ndGgpICE9PSAtMTtcbn1cblxuLyoqXG4gKiBDcmVhdGUgYW4gb2JqZWN0IGJ5IG1hcHBpbmcgYWxsIHRoZSB2YWx1ZXMgb2YgYW4gZXhpc3Rpbmcgb2JqZWN0IHdoaWxlXG4gKiBwcmVzZXJ2aW5nIHRoZWlyIGtleXMuXG4gKlxuICogQHByaXZhdGVcbiAqL1xuLy8gJEZsb3dGaXhNZVttaXNzaW5nLXRoaXMtYW5ub3RdXG5leHBvcnQgZnVuY3Rpb24gbWFwT2JqZWN0KGlucHV0OiBPYmplY3QsIGl0ZXJhdG9yOiBGdW5jdGlvbiwgY29udGV4dD86IE9iamVjdCk6IE9iamVjdCB7XG4gICAgY29uc3Qgb3V0cHV0ID0ge307XG4gICAgZm9yIChjb25zdCBrZXkgaW4gaW5wdXQpIHtcbiAgICAgICAgb3V0cHV0W2tleV0gPSBpdGVyYXRvci5jYWxsKGNvbnRleHQgfHwgdGhpcywgaW5wdXRba2V5XSwga2V5LCBpbnB1dCk7XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXQ7XG59XG5cbi8qKlxuICogQ3JlYXRlIGFuIG9iamVjdCBieSBmaWx0ZXJpbmcgb3V0IHZhbHVlcyBvZiBhbiBleGlzdGluZyBvYmplY3QuXG4gKlxuICogQHByaXZhdGVcbiAqL1xuLy8gJEZsb3dGaXhNZVttaXNzaW5nLXRoaXMtYW5ub3RdXG5leHBvcnQgZnVuY3Rpb24gZmlsdGVyT2JqZWN0KGlucHV0OiBPYmplY3QsIGl0ZXJhdG9yOiBGdW5jdGlvbiwgY29udGV4dD86IE9iamVjdCk6IE9iamVjdCB7XG4gICAgY29uc3Qgb3V0cHV0ID0ge307XG4gICAgZm9yIChjb25zdCBrZXkgaW4gaW5wdXQpIHtcbiAgICAgICAgaWYgKGl0ZXJhdG9yLmNhbGwoY29udGV4dCB8fCB0aGlzLCBpbnB1dFtrZXldLCBrZXksIGlucHV0KSkge1xuICAgICAgICAgICAgb3V0cHV0W2tleV0gPSBpbnB1dFtrZXldO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXQ7XG59XG5cbmltcG9ydCBkZWVwRXF1YWwgZnJvbSAnLi4vc3R5bGUtc3BlYy91dGlsL2RlZXBfZXF1YWwuanMnO1xuZXhwb3J0IHtkZWVwRXF1YWx9O1xuXG4vKipcbiAqIERlZXBseSBjbG9uZXMgdHdvIG9iamVjdHMuXG4gKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsb25lPFQ+KGlucHV0OiBUKTogVCB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoaW5wdXQpKSB7XG4gICAgICAgIHJldHVybiAoKGlucHV0Lm1hcChjbG9uZSk6IGFueSk6IFQpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGlucHV0ID09PSAnb2JqZWN0JyAmJiBpbnB1dCkge1xuICAgICAgICByZXR1cm4gKChtYXBPYmplY3QoaW5wdXQsIGNsb25lKTogYW55KTogVCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGlucHV0O1xuICAgIH1cbn1cblxuLyoqXG4gKiBNYXBzIGEgdmFsdWUgZnJvbSBhIHJhbmdlIGJldHdlZW4gW21pbiwgbWF4XSB0byB0aGUgcmFuZ2UgW291dE1pbiwgb3V0TWF4XVxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXBWYWx1ZSh2YWx1ZTogbnVtYmVyLCBtaW46IG51bWJlciwgbWF4OiBudW1iZXIsIG91dE1pbjogbnVtYmVyLCBvdXRNYXg6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIGNsYW1wKCh2YWx1ZSAtIG1pbikgLyAobWF4IC0gbWluKSAqIChvdXRNYXggLSBvdXRNaW4pICsgb3V0TWluLCBvdXRNaW4sIG91dE1heCk7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgdHdvIGFycmF5cyBoYXZlIGF0IGxlYXN0IG9uZSBjb21tb24gZWxlbWVudC5cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gYXJyYXlzSW50ZXJzZWN0PFQ+KGE6IEFycmF5PFQ+LCBiOiBBcnJheTxUPik6IGJvb2xlYW4ge1xuICAgIGZvciAobGV0IGwgPSAwOyBsIDwgYS5sZW5ndGg7IGwrKykge1xuICAgICAgICBpZiAoYi5pbmRleE9mKGFbbF0pID49IDApIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogUHJpbnQgYSB3YXJuaW5nIG1lc3NhZ2UgdG8gdGhlIGNvbnNvbGUgYW5kIGVuc3VyZSBkdXBsaWNhdGUgd2FybmluZyBtZXNzYWdlc1xuICogYXJlIG5vdCBwcmludGVkLlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmNvbnN0IHdhcm5PbmNlSGlzdG9yeToge1trZXk6IHN0cmluZ106IGJvb2xlYW59ID0ge307XG5cbmV4cG9ydCBmdW5jdGlvbiB3YXJuT25jZShtZXNzYWdlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIXdhcm5PbmNlSGlzdG9yeVttZXNzYWdlXSkge1xuICAgICAgICAvLyBjb25zb2xlIGlzbid0IGRlZmluZWQgaW4gc29tZSBXZWJXb3JrZXJzLCBzZWUgIzI1NThcbiAgICAgICAgaWYgKHR5cGVvZiBjb25zb2xlICE9PSBcInVuZGVmaW5lZFwiKSBjb25zb2xlLndhcm4obWVzc2FnZSk7XG4gICAgICAgIHdhcm5PbmNlSGlzdG9yeVttZXNzYWdlXSA9IHRydWU7XG4gICAgfVxufVxuXG4vKipcbiAqIEluZGljYXRlcyBpZiB0aGUgcHJvdmlkZWQgUG9pbnRzIGFyZSBpbiBhIGNvdW50ZXIgY2xvY2t3aXNlICh0cnVlKSBvciBjbG9ja3dpc2UgKGZhbHNlKSBvcmRlclxuICpcbiAqIEBwcml2YXRlXG4gKiBAcmV0dXJucyB0cnVlIGZvciBhIGNvdW50ZXIgY2xvY2t3aXNlIHNldCBvZiBwb2ludHNcbiAqL1xuLy8gaHR0cDovL2JyeWNlYm9lLmNvbS8yMDA2LzEwLzIzL2xpbmUtc2VnbWVudC1pbnRlcnNlY3Rpb24tYWxnb3JpdGhtL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQ291bnRlckNsb2Nrd2lzZShhOiBQb2ludCwgYjogUG9pbnQsIGM6IFBvaW50KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChjLnkgLSBhLnkpICogKGIueCAtIGEueCkgPiAoYi55IC0gYS55KSAqIChjLnggLSBhLngpO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIHNpZ25lZCBhcmVhIGZvciB0aGUgcG9seWdvbiByaW5nLiAgUG9zdGl2ZSBhcmVhcyBhcmUgZXh0ZXJpb3IgcmluZ3MgYW5kXG4gKiBoYXZlIGEgY2xvY2t3aXNlIHdpbmRpbmcuICBOZWdhdGl2ZSBhcmVhcyBhcmUgaW50ZXJpb3IgcmluZ3MgYW5kIGhhdmUgYSBjb3VudGVyIGNsb2Nrd2lzZVxuICogb3JkZXJpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSByaW5nIEV4dGVyaW9yIG9yIGludGVyaW9yIHJpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZVNpZ25lZEFyZWEocmluZzogQXJyYXk8UG9pbnQ+KTogbnVtYmVyIHtcbiAgICBsZXQgc3VtID0gMDtcbiAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gcmluZy5sZW5ndGgsIGogPSBsZW4gLSAxLCBwMSwgcDI7IGkgPCBsZW47IGogPSBpKyspIHtcbiAgICAgICAgcDEgPSByaW5nW2ldO1xuICAgICAgICBwMiA9IHJpbmdbal07XG4gICAgICAgIHN1bSArPSAocDIueCAtIHAxLngpICogKHAxLnkgKyBwMi55KTtcbiAgICB9XG4gICAgcmV0dXJuIHN1bTtcbn1cblxuLyogZ2xvYmFsIHNlbGYsIFdvcmtlckdsb2JhbFNjb3BlICovXG4vKipcbiAqICBSZXR1cm5zIHRydWUgaWYgcnVuIGluIHRoZSB3ZWItd29ya2VyIGNvbnRleHQuXG4gKlxuICogQHByaXZhdGVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNXb3JrZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHR5cGVvZiBXb3JrZXJHbG9iYWxTY29wZSAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIHNlbGYgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgICAgIHNlbGYgaW5zdGFuY2VvZiBXb3JrZXJHbG9iYWxTY29wZTtcbn1cblxuLyoqXG4gKiBQYXJzZXMgZGF0YSBmcm9tICdDYWNoZS1Db250cm9sJyBoZWFkZXJzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0gY2FjaGVDb250cm9sIFZhbHVlIG9mICdDYWNoZS1Db250cm9sJyBoZWFkZXJcbiAqIEByZXR1cm4gb2JqZWN0IGNvbnRhaW5pbmcgcGFyc2VkIGhlYWRlciBpbmZvLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUNhY2hlQ29udHJvbChjYWNoZUNvbnRyb2w6IHN0cmluZyk6IE9iamVjdCB7XG4gICAgLy8gVGFrZW4gZnJvbSBbV3JlY2tdKGh0dHBzOi8vZ2l0aHViLmNvbS9oYXBpanMvd3JlY2spXG4gICAgY29uc3QgcmUgPSAvKD86XnwoPzpcXHMqXFwsXFxzKikpKFteXFx4MDAtXFx4MjBcXChcXCk8PkBcXCw7XFw6XFxcXFwiXFwvXFxbXFxdXFw/XFw9XFx7XFx9XFx4N0ZdKykoPzpcXD0oPzooW15cXHgwMC1cXHgyMFxcKFxcKTw+QFxcLDtcXDpcXFxcXCJcXC9cXFtcXF1cXD9cXD1cXHtcXH1cXHg3Rl0rKXwoPzpcXFwiKCg/OlteXCJcXFxcXXxcXFxcLikqKVxcXCIpKSk/L2c7XG5cbiAgICBjb25zdCBoZWFkZXIgPSB7fTtcbiAgICBjYWNoZUNvbnRyb2wucmVwbGFjZShyZSwgKCQwLCAkMSwgJDIsICQzKSA9PiB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gJDIgfHwgJDM7XG4gICAgICAgIGhlYWRlclskMV0gPSB2YWx1ZSA/IHZhbHVlLnRvTG93ZXJDYXNlKCkgOiB0cnVlO1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgfSk7XG5cbiAgICBpZiAoaGVhZGVyWydtYXgtYWdlJ10pIHtcbiAgICAgICAgY29uc3QgbWF4QWdlID0gcGFyc2VJbnQoaGVhZGVyWydtYXgtYWdlJ10sIDEwKTtcbiAgICAgICAgaWYgKGlzTmFOKG1heEFnZSkpIGRlbGV0ZSBoZWFkZXJbJ21heC1hZ2UnXTtcbiAgICAgICAgZWxzZSBoZWFkZXJbJ21heC1hZ2UnXSA9IG1heEFnZTtcbiAgICB9XG5cbiAgICByZXR1cm4gaGVhZGVyO1xufVxuXG5sZXQgX2lzU2FmYXJpID0gbnVsbDtcblxuZXhwb3J0IGZ1bmN0aW9uIF9yZXNldFNhZmFyaUNoZWNrRm9yVGVzdCgpIHtcbiAgICBfaXNTYWZhcmkgPSBudWxsO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSB3aGVuIHJ1biBpbiBXZWJLaXQgZGVyaXZlZCBicm93c2Vycy5cbiAqIFRoaXMgaXMgdXNlZCBhcyBhIHdvcmthcm91bmQgZm9yIGEgbWVtb3J5IGxlYWsgaW4gU2FmYXJpIGNhdXNlZCBieSB1c2luZyBUcmFuc2ZlcmFibGUgb2JqZWN0cyB0b1xuICogdHJhbnNmZXIgZGF0YSBiZXR3ZWVuIFdlYldvcmtlcnMgYW5kIHRoZSBtYWluIHRocmVhZC5cbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXBib3gvbWFwYm94LWdsLWpzL2lzc3Vlcy84NzcxXG4gKlxuICogVGhpcyBzaG91bGQgYmUgcmVtb3ZlZCBvbmNlIHRoZSB1bmRlcmx5aW5nIFNhZmFyaSBpc3N1ZSBpcyBmaXhlZC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHNjb3BlIHtXaW5kb3dPcldvcmtlckdsb2JhbFNjb3BlfSBTaW5jZSB0aGlzIGZ1bmN0aW9uIGlzIHVzZWQgYm90aCBvbiB0aGUgbWFpbiB0aHJlYWQgYW5kIFdlYldvcmtlciBjb250ZXh0LFxuICogICAgICBsZXQgdGhlIGNhbGxpbmcgc2NvcGUgcGFzcyBpbiB0aGUgZ2xvYmFsIHNjb3BlIG9iamVjdC5cbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNTYWZhcmkoc2NvcGU6IGFueSk6IGJvb2xlYW4ge1xuICAgIGlmIChfaXNTYWZhcmkgPT0gbnVsbCkge1xuICAgICAgICBjb25zdCB1c2VyQWdlbnQgPSBzY29wZS5uYXZpZ2F0b3IgPyBzY29wZS5uYXZpZ2F0b3IudXNlckFnZW50IDogbnVsbDtcbiAgICAgICAgX2lzU2FmYXJpID0gISFzY29wZS5zYWZhcmkgfHxcbiAgICAgICAgISEodXNlckFnZW50ICYmICgvXFxiKGlQYWR8aVBob25lfGlQb2QpXFxiLy50ZXN0KHVzZXJBZ2VudCkgfHwgKCEhdXNlckFnZW50Lm1hdGNoKCdTYWZhcmknKSAmJiAhdXNlckFnZW50Lm1hdGNoKCdDaHJvbWUnKSkpKTtcbiAgICB9XG4gICAgcmV0dXJuIF9pc1NhZmFyaTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzU2FmYXJpV2l0aEFudGlhbGlhc2luZ0J1ZyhzY29wZTogYW55KTogP2Jvb2xlYW4ge1xuICAgIGNvbnN0IHVzZXJBZ2VudCA9IHNjb3BlLm5hdmlnYXRvciA/IHNjb3BlLm5hdmlnYXRvci51c2VyQWdlbnQgOiBudWxsO1xuICAgIGlmICghaXNTYWZhcmkoc2NvcGUpKSByZXR1cm4gZmFsc2U7XG4gICAgLy8gMTUuNCBpcyBrbm93biB0byBiZSBidWdneS5cbiAgICAvLyAxNS41IG1heSBvciBtYXkgbm90IGluY2x1ZGUgdGhlIGZpeC4gTWFyayBpdCBhcyBidWdneSB0byBiZSBvbiB0aGUgc2FmZSBzaWRlLlxuICAgIHJldHVybiB1c2VyQWdlbnQgJiYgKHVzZXJBZ2VudC5tYXRjaCgnVmVyc2lvbi8xNS40JykgfHwgdXNlckFnZW50Lm1hdGNoKCdWZXJzaW9uLzE1LjUnKSB8fCB1c2VyQWdlbnQubWF0Y2goL0NQVSAoT1N8aVBob25lIE9TKSAoMTVfNHwxNV81KSBsaWtlIE1hYyBPUyBYLykpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNGdWxsc2NyZWVuKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXdpbmRvdy5kb2N1bWVudC5mdWxsc2NyZWVuRWxlbWVudCB8fCAhIXdpbmRvdy5kb2N1bWVudC53ZWJraXRGdWxsc2NyZWVuRWxlbWVudDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHN0b3JhZ2VBdmFpbGFibGUodHlwZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3Qgc3RvcmFnZSA9IHdpbmRvd1t0eXBlXTtcbiAgICAgICAgc3RvcmFnZS5zZXRJdGVtKCdfbWFwYm94X3Rlc3RfJywgMSk7XG4gICAgICAgIHN0b3JhZ2UucmVtb3ZlSXRlbSgnX21hcGJveF90ZXN0XycpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59XG5cbi8vIFRoZSBmb2xsb3dpbmcgbWV0aG9kcyBhcmUgZnJvbSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvV2luZG93QmFzZTY0L0Jhc2U2NF9lbmNvZGluZ19hbmRfZGVjb2RpbmcjVGhlX1VuaWNvZGVfUHJvYmxlbVxuLy9Vbmljb2RlIGNvbXBsaWFudCBiYXNlNjQgZW5jb2RlciBmb3Igc3RyaW5nc1xuZXhwb3J0IGZ1bmN0aW9uIGI2NEVuY29kZVVuaWNvZGUoc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB3aW5kb3cuYnRvYShcbiAgICAgICAgZW5jb2RlVVJJQ29tcG9uZW50KHN0cikucmVwbGFjZSgvJShbMC05QS1GXXsyfSkvZyxcbiAgICAgICAgICAgIChtYXRjaCwgcDEpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShOdW1iZXIoJzB4JyArIHAxKSk7IC8vZXNsaW50LWRpc2FibGUtbGluZVxuICAgICAgICAgICAgfVxuICAgICAgICApXG4gICAgKTtcbn1cblxuLy8gVW5pY29kZSBjb21wbGlhbnQgZGVjb2RlciBmb3IgYmFzZTY0LWVuY29kZWQgc3RyaW5nc1xuZXhwb3J0IGZ1bmN0aW9uIGI2NERlY29kZVVuaWNvZGUoc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQod2luZG93LmF0b2Ioc3RyKS5zcGxpdCgnJykubWFwKChjKSA9PiB7XG4gICAgICAgIHJldHVybiAnJScgKyAoJzAwJyArIGMuY2hhckNvZGVBdCgwKS50b1N0cmluZygxNikpLnNsaWNlKC0yKTsgLy9lc2xpbnQtZGlzYWJsZS1saW5lXG4gICAgfSkuam9pbignJykpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29sdW1uKG1hdHJpeDogTWF0NCwgY29sOiBudW1iZXIpOiBWZWM0IHtcbiAgICByZXR1cm4gW21hdHJpeFtjb2wgKiA0XSwgbWF0cml4W2NvbCAqIDQgKyAxXSwgbWF0cml4W2NvbCAqIDQgKyAyXSwgbWF0cml4W2NvbCAqIDQgKyAzXV07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRDb2x1bW4obWF0cml4OiBNYXQ0LCBjb2w6IG51bWJlciwgdmFsdWVzOiBWZWM0KSB7XG4gICAgbWF0cml4W2NvbCAqIDQgKyAwXSA9IHZhbHVlc1swXTtcbiAgICBtYXRyaXhbY29sICogNCArIDFdID0gdmFsdWVzWzFdO1xuICAgIG1hdHJpeFtjb2wgKiA0ICsgMl0gPSB2YWx1ZXNbMl07XG4gICAgbWF0cml4W2NvbCAqIDQgKyAzXSA9IHZhbHVlc1szXTtcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCB7d2Fybk9uY2UsIHBhcnNlQ2FjaGVDb250cm9sfSBmcm9tICcuL3V0aWwuanMnO1xuaW1wb3J0IHdpbmRvdyBmcm9tICcuL3dpbmRvdy5qcyc7XG5cbmltcG9ydCB0eXBlIERpc3BhdGNoZXIgZnJvbSAnLi9kaXNwYXRjaGVyLmpzJztcblxuY29uc3QgQ0FDSEVfTkFNRSA9ICdtYXBib3gtdGlsZXMnO1xubGV0IGNhY2hlTGltaXQgPSA1MDA7IC8vIDUwTUIgLyAoMTAwS0IvdGlsZSkgfj0gNTAwIHRpbGVzXG5sZXQgY2FjaGVDaGVja1RocmVzaG9sZCA9IDUwO1xuXG5jb25zdCBNSU5fVElNRV9VTlRJTF9FWFBJUlkgPSAxMDAwICogNjAgKiA3OyAvLyA3IG1pbnV0ZXMuIFNraXAgY2FjaGluZyB0aWxlcyB3aXRoIGEgc2hvcnQgZW5vdWdoIG1heCBhZ2UuXG5cbmV4cG9ydCB0eXBlIFJlc3BvbnNlT3B0aW9ucyA9IHtcbiAgICBzdGF0dXM6IG51bWJlcixcbiAgICBzdGF0dXNUZXh0OiBzdHJpbmcsXG4gICAgaGVhZGVyczogSGVhZGVyc1xufTtcblxuLy8gV2UncmUgdXNpbmcgYSBnbG9iYWwgc2hhcmVkIGNhY2hlIG9iamVjdC4gTm9ybWFsbHksIHJlcXVlc3RpbmcgYWQtaG9jIENhY2hlIG9iamVjdHMgaXMgZmluZSwgYnV0XG4vLyBTYWZhcmkgaGFzIGEgbWVtb3J5IGxlYWsgaW4gd2hpY2ggaXQgZmFpbHMgdG8gcmVsZWFzZSBtZW1vcnkgd2hlbiByZXF1ZXN0aW5nIGtleXMoKSBmcm9tIGEgQ2FjaGVcbi8vIG9iamVjdC4gU2VlIGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0yMDM5OTEgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG5sZXQgc2hhcmVkQ2FjaGU6ID9Qcm9taXNlPENhY2hlPjtcblxuZnVuY3Rpb24gZ2V0Q2FjaGVzKCkge1xuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB3aW5kb3cuY2FjaGVzO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gPGlmcmFtZSBzYW5kYm94PiB0cmlnZ2VycyBleGNlcHRpb25zIHdoZW4gdHJ5aW5nIHRvIGFjY2VzcyB3aW5kb3cuY2FjaGVzXG4gICAgICAgIC8vIENocm9tZTogRE9NRXhjZXB0aW9uLCBTYWZhcmk6IFNlY3VyaXR5RXJyb3IsIEZpcmVmb3g6IE5TX0VSUk9SX0ZBSUxVUkVcbiAgICAgICAgLy8gU2VlbXMgbW9yZSByb2J1c3QgdG8gY2F0Y2ggYWxsIGV4Y2VwdGlvbnMgaW5zdGVhZCBvZiB0cnlpbmcgdG8gbWF0Y2ggb25seSB0aGVzZS5cbiAgICB9XG59XG5cbmZ1bmN0aW9uIGNhY2hlT3BlbigpIHtcbiAgICBjb25zdCBjYWNoZXMgPSBnZXRDYWNoZXMoKTtcbiAgICBpZiAoY2FjaGVzICYmICFzaGFyZWRDYWNoZSkge1xuICAgICAgICBzaGFyZWRDYWNoZSA9IHdpbmRvdy5jYWNoZXMub3BlbihDQUNIRV9OQU1FKTtcbiAgICB9XG59XG5cbi8vIFdlJ3JlIG5ldmVyIGNsb3NpbmcgdGhlIGNhY2hlLCBidXQgb3VyIHVuaXQgdGVzdHMgcmVseSBvbiBjaGFuZ2luZyBvdXQgdGhlIGdsb2JhbCB3aW5kb3cuY2FjaGVzXG4vLyBvYmplY3QsIHNvIHdlIGhhdmUgYSBmdW5jdGlvbiBzcGVjaWZpY2FsbHkgZm9yIHVuaXQgdGVzdHMgdGhhdCBhbGxvd3MgcmVzZXR0aW5nIHRoZSBzaGFyZWQgY2FjaGUuXG5leHBvcnQgZnVuY3Rpb24gY2FjaGVDbG9zZSgpIHtcbiAgICBzaGFyZWRDYWNoZSA9IHVuZGVmaW5lZDtcbn1cblxubGV0IHJlc3BvbnNlQ29uc3RydWN0b3JTdXBwb3J0c1JlYWRhYmxlU3RyZWFtO1xuZnVuY3Rpb24gcHJlcGFyZUJvZHkocmVzcG9uc2U6IFJlc3BvbnNlLCBjYWxsYmFjazogKChib2R5OiA/KEJsb2IgfCBSZWFkYWJsZVN0cmVhbSkpID0+IHZvaWQpKSB7XG4gICAgaWYgKHJlc3BvbnNlQ29uc3RydWN0b3JTdXBwb3J0c1JlYWRhYmxlU3RyZWFtID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIG5ldyBSZXNwb25zZShuZXcgUmVhZGFibGVTdHJlYW0oKSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW5kZWZcbiAgICAgICAgICAgIHJlc3BvbnNlQ29uc3RydWN0b3JTdXBwb3J0c1JlYWRhYmxlU3RyZWFtID0gdHJ1ZTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgLy8gRWRnZVxuICAgICAgICAgICAgcmVzcG9uc2VDb25zdHJ1Y3RvclN1cHBvcnRzUmVhZGFibGVTdHJlYW0gPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmIChyZXNwb25zZUNvbnN0cnVjdG9yU3VwcG9ydHNSZWFkYWJsZVN0cmVhbSkge1xuICAgICAgICBjYWxsYmFjayhyZXNwb25zZS5ib2R5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXNwb25zZS5ibG9iKCkudGhlbihjYWxsYmFjayk7XG4gICAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gY2FjaGVQdXQocmVxdWVzdDogUmVxdWVzdCwgcmVzcG9uc2U6IFJlc3BvbnNlLCByZXF1ZXN0VGltZTogbnVtYmVyKSB7XG4gICAgY2FjaGVPcGVuKCk7XG4gICAgaWYgKCFzaGFyZWRDYWNoZSkgcmV0dXJuO1xuXG4gICAgY29uc3Qgb3B0aW9uczogUmVzcG9uc2VPcHRpb25zID0ge1xuICAgICAgICBzdGF0dXM6IHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgICAgc3RhdHVzVGV4dDogcmVzcG9uc2Uuc3RhdHVzVGV4dCxcbiAgICAgICAgaGVhZGVyczogbmV3IHdpbmRvdy5IZWFkZXJzKClcbiAgICB9O1xuICAgIHJlc3BvbnNlLmhlYWRlcnMuZm9yRWFjaCgodiwgaykgPT4gb3B0aW9ucy5oZWFkZXJzLnNldChrLCB2KSk7XG5cbiAgICBjb25zdCBjYWNoZUNvbnRyb2wgPSBwYXJzZUNhY2hlQ29udHJvbChyZXNwb25zZS5oZWFkZXJzLmdldCgnQ2FjaGUtQ29udHJvbCcpIHx8ICcnKTtcbiAgICBpZiAoY2FjaGVDb250cm9sWyduby1zdG9yZSddKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGNhY2hlQ29udHJvbFsnbWF4LWFnZSddKSB7XG4gICAgICAgIG9wdGlvbnMuaGVhZGVycy5zZXQoJ0V4cGlyZXMnLCBuZXcgRGF0ZShyZXF1ZXN0VGltZSArIGNhY2hlQ29udHJvbFsnbWF4LWFnZSddICogMTAwMCkudG9VVENTdHJpbmcoKSk7XG4gICAgfVxuXG4gICAgY29uc3QgZXhwaXJlcyA9IG9wdGlvbnMuaGVhZGVycy5nZXQoJ0V4cGlyZXMnKTtcbiAgICBpZiAoIWV4cGlyZXMpIHJldHVybjtcbiAgICBjb25zdCB0aW1lVW50aWxFeHBpcnkgPSBuZXcgRGF0ZShleHBpcmVzKS5nZXRUaW1lKCkgLSByZXF1ZXN0VGltZTtcbiAgICBpZiAodGltZVVudGlsRXhwaXJ5IDwgTUlOX1RJTUVfVU5USUxfRVhQSVJZKSByZXR1cm47XG5cbiAgICBwcmVwYXJlQm9keShyZXNwb25zZSwgYm9keSA9PiB7XG4gICAgICAgIGNvbnN0IGNsb25lZFJlc3BvbnNlID0gbmV3IHdpbmRvdy5SZXNwb25zZShib2R5LCBvcHRpb25zKTtcblxuICAgICAgICBjYWNoZU9wZW4oKTtcbiAgICAgICAgaWYgKCFzaGFyZWRDYWNoZSkgcmV0dXJuO1xuICAgICAgICBzaGFyZWRDYWNoZVxuICAgICAgICAgICAgLnRoZW4oY2FjaGUgPT4gY2FjaGUucHV0KHN0cmlwUXVlcnlQYXJhbWV0ZXJzKHJlcXVlc3QudXJsKSwgY2xvbmVkUmVzcG9uc2UpKVxuICAgICAgICAgICAgLmNhdGNoKGUgPT4gd2Fybk9uY2UoZS5tZXNzYWdlKSk7XG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIGdldFF1ZXJ5UGFyYW1ldGVycyh1cmw6IHN0cmluZykge1xuICAgIGNvbnN0IHBhcmFtU3RhcnQgPSB1cmwuaW5kZXhPZignPycpO1xuICAgIHJldHVybiBwYXJhbVN0YXJ0ID4gMCA/IHVybC5zbGljZShwYXJhbVN0YXJ0ICsgMSkuc3BsaXQoJyYnKSA6IFtdO1xufVxuXG5mdW5jdGlvbiBzdHJpcFF1ZXJ5UGFyYW1ldGVycyh1cmw6IHN0cmluZykge1xuICAgIGNvbnN0IHN0YXJ0ID0gdXJsLmluZGV4T2YoJz8nKTtcbiAgICBpZiAoc3RhcnQgPCAwKSByZXR1cm4gdXJsO1xuXG4gICAgLy8gcHJlc2VydmUgYGxhbmd1YWdlYCBhbmQgYHdvcmxkdmlld2AgcGFyYW1zIGlmIGFueVxuICAgIGNvbnN0IHBhcmFtcyA9IGdldFF1ZXJ5UGFyYW1ldGVycyh1cmwpO1xuICAgIGNvbnN0IGZpbHRlcmVkUGFyYW1zID0gcGFyYW1zLmZpbHRlcihwYXJhbSA9PiB7XG4gICAgICAgIGNvbnN0IGVudHJ5ID0gcGFyYW0uc3BsaXQoJz0nKTtcbiAgICAgICAgcmV0dXJuIGVudHJ5WzBdID09PSAnbGFuZ3VhZ2UnIHx8IGVudHJ5WzBdID09PSAnd29ybGR2aWV3JztcbiAgICB9KTtcblxuICAgIGlmIChmaWx0ZXJlZFBhcmFtcy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIGAke3VybC5zbGljZSgwLCBzdGFydCl9PyR7ZmlsdGVyZWRQYXJhbXMuam9pbignJicpfWA7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVybC5zbGljZSgwLCBzdGFydCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjYWNoZUdldChyZXF1ZXN0OiBSZXF1ZXN0LCBjYWxsYmFjazogKGVycm9yOiA/YW55LCByZXNwb25zZTogP1Jlc3BvbnNlLCBmcmVzaDogP2Jvb2xlYW4pID0+IHZvaWQpOiB2b2lkIHtcbiAgICBjYWNoZU9wZW4oKTtcbiAgICBpZiAoIXNoYXJlZENhY2hlKSByZXR1cm4gY2FsbGJhY2sobnVsbCk7XG5cbiAgICBjb25zdCBzdHJpcHBlZFVSTCA9IHN0cmlwUXVlcnlQYXJhbWV0ZXJzKHJlcXVlc3QudXJsKTtcblxuICAgICgoc2hhcmVkQ2FjaGU6IGFueSk6IFByb21pc2U8Q2FjaGU+KVxuICAgICAgICAudGhlbihjYWNoZSA9PiB7XG4gICAgICAgICAgICAvLyBtYW51YWxseSBzdHJpcCBVUkwgaW5zdGVhZCBvZiBgaWdub3JlU2VhcmNoOiB0cnVlYCBiZWNhdXNlIG9mIGEga25vd25cbiAgICAgICAgICAgIC8vIHBlcmZvcm1hbmNlIGlzc3VlIGluIENocm9tZSBodHRwczovL2dpdGh1Yi5jb20vbWFwYm94L21hcGJveC1nbC1qcy9pc3N1ZXMvODQzMVxuICAgICAgICAgICAgY2FjaGUubWF0Y2goc3RyaXBwZWRVUkwpXG4gICAgICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBmcmVzaCA9IGlzRnJlc2gocmVzcG9uc2UpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIFJlaW5zZXJ0IGludG8gY2FjaGUgc28gdGhhdCBvcmRlciBvZiBrZXlzIGluIHRoZSBjYWNoZSBpcyB0aGUgb3JkZXIgb2YgYWNjZXNzLlxuICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGxpbmUgbWFrZXMgdGhlIGNhY2hlIGEgTFJVIGluc3RlYWQgb2YgYSBGSUZPIGNhY2hlLlxuICAgICAgICAgICAgICAgICAgICBjYWNoZS5kZWxldGUoc3RyaXBwZWRVUkwpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZnJlc2gpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlLnB1dChzdHJpcHBlZFVSTCwgcmVzcG9uc2UuY2xvbmUoKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhudWxsLCByZXNwb25zZSwgZnJlc2gpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKGNhbGxiYWNrKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGNhbGxiYWNrKTtcblxufVxuXG5mdW5jdGlvbiBpc0ZyZXNoKHJlc3BvbnNlOiBSZXNwb25zZSkge1xuICAgIGlmICghcmVzcG9uc2UpIHJldHVybiBmYWxzZTtcbiAgICBjb25zdCBleHBpcmVzID0gbmV3IERhdGUocmVzcG9uc2UuaGVhZGVycy5nZXQoJ0V4cGlyZXMnKSB8fCAwKTtcbiAgICBjb25zdCBjYWNoZUNvbnRyb2wgPSBwYXJzZUNhY2hlQ29udHJvbChyZXNwb25zZS5oZWFkZXJzLmdldCgnQ2FjaGUtQ29udHJvbCcpIHx8ICcnKTtcbiAgICByZXR1cm4gZXhwaXJlcyA+IERhdGUubm93KCkgJiYgIWNhY2hlQ29udHJvbFsnbm8tY2FjaGUnXTtcbn1cblxuLy8gYEluZmluaXR5YCB0cmlnZ2VycyBhIGNhY2hlIGNoZWNrIGFmdGVyIHRoZSBmaXJzdCB0aWxlIGlzIGxvYWRlZFxuLy8gc28gdGhhdCBhIGNoZWNrIGlzIHJ1biBhdCBsZWFzdCBvbmNlIG9uIGVhY2ggcGFnZSBsb2FkLlxubGV0IGdsb2JhbEVudHJ5Q291bnRlciA9IEluZmluaXR5O1xuXG4vLyBUaGUgY2FjaGUgY2hlY2sgZ2V0cyBydW4gb24gYSB3b3JrZXIuIFRoZSByZWFzb24gZm9yIHRoaXMgaXMgdGhhdFxuLy8gcHJvZmlsaW5nIHNvbWV0aW1lcyBzaG93cyB0aGlzIGFzIHRha2luZyB1cCBzaWduaWZpY2FudCB0aW1lIG9uIHRoZVxuLy8gdGhyZWFkIGl0IGdldHMgY2FsbGVkIGZyb20uIEFuZCBzb21ldGltZXMgaXQgZG9lc24ndC4gSXQgKm1heSogYmVcbi8vIGZpbmUgdG8gcnVuIHRoaXMgb24gdGhlIG1haW4gdGhyZWFkIGJ1dCBvdXQgb2YgY2F1dGlvbiB0aGlzIGlzIGJlaW5nXG4vLyBkaXNwYXRjaGVkIG9uIGEgd29ya2VyLiBUaGlzIGNhbiBiZSBpbnZlc3RpZ2F0ZWQgZnVydGhlciBpbiB0aGUgZnV0dXJlLlxuZXhwb3J0IGZ1bmN0aW9uIGNhY2hlRW50cnlQb3NzaWJseUFkZGVkKGRpc3BhdGNoZXI6IERpc3BhdGNoZXIpIHtcbiAgICBnbG9iYWxFbnRyeUNvdW50ZXIrKztcbiAgICBpZiAoZ2xvYmFsRW50cnlDb3VudGVyID4gY2FjaGVDaGVja1RocmVzaG9sZCkge1xuICAgICAgICBkaXNwYXRjaGVyLmdldEFjdG9yKCkuc2VuZCgnZW5mb3JjZUNhY2hlU2l6ZUxpbWl0JywgY2FjaGVMaW1pdCk7XG4gICAgICAgIGdsb2JhbEVudHJ5Q291bnRlciA9IDA7XG4gICAgfVxufVxuXG4vLyBydW5zIG9uIHdvcmtlciwgc2VlIGFib3ZlIGNvbW1lbnRcbmV4cG9ydCBmdW5jdGlvbiBlbmZvcmNlQ2FjaGVTaXplTGltaXQobGltaXQ6IG51bWJlcikge1xuICAgIGNhY2hlT3BlbigpO1xuICAgIGlmICghc2hhcmVkQ2FjaGUpIHJldHVybjtcblxuICAgIHNoYXJlZENhY2hlXG4gICAgICAgIC50aGVuKGNhY2hlID0+IHtcbiAgICAgICAgICAgIGNhY2hlLmtleXMoKS50aGVuKGtleXMgPT4ge1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGggLSBsaW1pdDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhY2hlLmRlbGV0ZShrZXlzW2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjbGVhclRpbGVDYWNoZShjYWxsYmFjaz86IChlcnI6ID9FcnJvcikgPT4gdm9pZCkge1xuICAgIGNvbnN0IGNhY2hlcyA9IGdldENhY2hlcygpO1xuICAgIGlmICghY2FjaGVzKSByZXR1cm47XG5cbiAgICBjb25zdCBwcm9taXNlID0gd2luZG93LmNhY2hlcy5kZWxldGUoQ0FDSEVfTkFNRSk7XG4gICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgIHByb21pc2UuY2F0Y2goY2FsbGJhY2spLnRoZW4oKCkgPT4gY2FsbGJhY2soKSk7XG4gICAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0Q2FjaGVMaW1pdHMobGltaXQ6IG51bWJlciwgY2hlY2tUaHJlc2hvbGQ6IG51bWJlcikge1xuICAgIGNhY2hlTGltaXQgPSBsaW1pdDtcbiAgICBjYWNoZUNoZWNrVGhyZXNob2xkID0gY2hlY2tUaHJlc2hvbGQ7XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgd2luZG93IGZyb20gJy4vd2luZG93LmpzJztcbmltcG9ydCB7ZXh0ZW5kLCB3YXJuT25jZSwgaXNXb3JrZXJ9IGZyb20gJy4vdXRpbC5qcyc7XG5pbXBvcnQge2lzTWFwYm94SFRUUFVSTCwgaGFzQ2FjaGVEZWZlYXRpbmdTa3V9IGZyb20gJy4vbWFwYm94LmpzJztcbmltcG9ydCBjb25maWcgZnJvbSAnLi9jb25maWcuanMnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHtjYWNoZUdldCwgY2FjaGVQdXR9IGZyb20gJy4vdGlsZV9yZXF1ZXN0X2NhY2hlLmpzJztcbmltcG9ydCB3ZWJwU3VwcG9ydGVkIGZyb20gJy4vd2VicF9zdXBwb3J0ZWQuanMnO1xuXG5pbXBvcnQgdHlwZSB7Q2FsbGJhY2t9IGZyb20gJy4uL3R5cGVzL2NhbGxiYWNrLmpzJztcbmltcG9ydCB0eXBlIHtDYW5jZWxhYmxlfSBmcm9tICcuLi90eXBlcy9jYW5jZWxhYmxlLmpzJztcblxuLyoqXG4gKiBUaGUgdHlwZSBvZiBhIHJlc291cmNlLlxuICogQHByaXZhdGVcbiAqIEByZWFkb25seVxuICogQGVudW0ge3N0cmluZ31cbiAqL1xuY29uc3QgUmVzb3VyY2VUeXBlID0ge1xuICAgIFVua25vd246ICdVbmtub3duJyxcbiAgICBTdHlsZTogJ1N0eWxlJyxcbiAgICBTb3VyY2U6ICdTb3VyY2UnLFxuICAgIFRpbGU6ICdUaWxlJyxcbiAgICBHbHlwaHM6ICdHbHlwaHMnLFxuICAgIFNwcml0ZUltYWdlOiAnU3ByaXRlSW1hZ2UnLFxuICAgIFNwcml0ZUpTT046ICdTcHJpdGVKU09OJyxcbiAgICBJbWFnZTogJ0ltYWdlJ1xufTtcbmV4cG9ydCB7UmVzb3VyY2VUeXBlfTtcblxuaWYgKHR5cGVvZiBPYmplY3QuZnJlZXplID09ICdmdW5jdGlvbicpIHtcbiAgICBPYmplY3QuZnJlZXplKFJlc291cmNlVHlwZSk7XG59XG5cbi8qKlxuICogQSBgUmVxdWVzdFBhcmFtZXRlcnNgIG9iamVjdCB0byBiZSByZXR1cm5lZCBmcm9tIE1hcC5vcHRpb25zLnRyYW5zZm9ybVJlcXVlc3QgY2FsbGJhY2tzLlxuICogQHR5cGVkZWYge09iamVjdH0gUmVxdWVzdFBhcmFtZXRlcnNcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB1cmwgVGhlIFVSTCB0byBiZSByZXF1ZXN0ZWQuXG4gKiBAcHJvcGVydHkge09iamVjdH0gaGVhZGVycyBUaGUgaGVhZGVycyB0byBiZSBzZW50IHdpdGggdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gbWV0aG9kIFJlcXVlc3QgbWV0aG9kIGAnR0VUJyB8ICdQT1NUJyB8ICdQVVQnYC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBib2R5IFJlcXVlc3QgYm9keS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB0eXBlIFJlc3BvbnNlIGJvZHkgdHlwZSB0byBiZSByZXR1cm5lZCBgJ3N0cmluZycgfCAnanNvbicgfCAnYXJyYXlCdWZmZXInYC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBjcmVkZW50aWFscyBgJ3NhbWUtb3JpZ2luJ3wnaW5jbHVkZSdgIFVzZSAnaW5jbHVkZScgdG8gc2VuZCBjb29raWVzIHdpdGggY3Jvc3Mtb3JpZ2luIHJlcXVlc3RzLlxuICogQHByb3BlcnR5IHtib29sZWFufSBjb2xsZWN0UmVzb3VyY2VUaW1pbmcgSWYgdHJ1ZSwgUmVzb3VyY2UgVGltaW5nIEFQSSBpbmZvcm1hdGlvbiB3aWxsIGJlIGNvbGxlY3RlZCBmb3IgdGhlc2UgdHJhbnNmb3JtZWQgcmVxdWVzdHMgYW5kIHJldHVybmVkIGluIGEgcmVzb3VyY2VUaW1pbmcgcHJvcGVydHkgb2YgcmVsZXZhbnQgZGF0YSBldmVudHMuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gcmVmZXJyZXJQb2xpY3kgQSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSByZXF1ZXN0J3MgcmVmZXJyZXJQb2xpY3kuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFuZCBwb3NzaWJsZSB2YWx1ZXMsIHNlZSB0aGUgW1JlZmVycmVyLVBvbGljeSBIVFRQIGhlYWRlciBwYWdlXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVFRQL0hlYWRlcnMvUmVmZXJyZXItUG9saWN5KS5cbiAqIEBleGFtcGxlXG4gKiAvLyB1c2UgdHJhbnNmb3JtUmVxdWVzdCB0byBtb2RpZnkgcmVxdWVzdHMgdGhhdCBiZWdpbiB3aXRoIGBodHRwOi8vbXlIb3N0YFxuICogY29uc3QgbWFwID0gbmV3IE1hcCh7XG4gKiAgICAgY29udGFpbmVyOiAnbWFwJyxcbiAqICAgICBzdHlsZTogJ21hcGJveDovL3N0eWxlcy9tYXBib3gvc3RyZWV0cy12MTEnLFxuICogICAgIHRyYW5zZm9ybVJlcXVlc3Q6ICh1cmwsIHJlc291cmNlVHlwZSkgPT4ge1xuICogICAgICAgICBpZiAocmVzb3VyY2VUeXBlID09PSAnU291cmNlJyAmJiB1cmwuaW5kZXhPZignaHR0cDovL215SG9zdCcpID4gLTEpIHtcbiAqICAgICAgICAgICAgIHJldHVybiB7XG4gKiAgICAgICAgICAgICAgICAgdXJsOiB1cmwucmVwbGFjZSgnaHR0cCcsICdodHRwcycpLFxuICogICAgICAgICAgICAgICAgIGhlYWRlcnM6IHsnbXktY3VzdG9tLWhlYWRlcic6IHRydWV9LFxuICogICAgICAgICAgICAgICAgIGNyZWRlbnRpYWxzOiAnaW5jbHVkZScgIC8vIEluY2x1ZGUgY29va2llcyBmb3IgY3Jvc3Mtb3JpZ2luIHJlcXVlc3RzXG4gKiAgICAgICAgICAgICB9O1xuICogICAgICAgICB9XG4gKiAgICAgfVxuICogfSk7XG4gKlxuICovXG5leHBvcnQgdHlwZSBSZXF1ZXN0UGFyYW1ldGVycyA9IHtcbiAgICB1cmw6IHN0cmluZyxcbiAgICBoZWFkZXJzPzogT2JqZWN0LFxuICAgIG1ldGhvZD86ICdHRVQnIHwgJ1BPU1QnIHwgJ1BVVCcsXG4gICAgYm9keT86IHN0cmluZyxcbiAgICB0eXBlPzogJ3N0cmluZycgfCAnanNvbicgfCAnYXJyYXlCdWZmZXInLFxuICAgIGNyZWRlbnRpYWxzPzogJ3NhbWUtb3JpZ2luJyB8ICdpbmNsdWRlJyxcbiAgICBjb2xsZWN0UmVzb3VyY2VUaW1pbmc/OiBib29sZWFuLFxuICAgIHJlZmVycmVyUG9saWN5PzogUmVmZXJyZXJQb2xpY3lUeXBlXG59XG5cbmV4cG9ydCB0eXBlIFJlc3BvbnNlQ2FsbGJhY2s8VD4gPSAoZXJyb3I6ID9FcnJvciwgZGF0YTogP1QsIGNhY2hlQ29udHJvbDogP3N0cmluZywgZXhwaXJlczogP3N0cmluZykgPT4gdm9pZDtcblxuZXhwb3J0IGNsYXNzIEFKQVhFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgICBzdGF0dXM6IG51bWJlcjtcbiAgICB1cmw6IHN0cmluZztcbiAgICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcsIHN0YXR1czogbnVtYmVyLCB1cmw6IHN0cmluZykge1xuICAgICAgICBpZiAoc3RhdHVzID09PSA0MDEgJiYgaXNNYXBib3hIVFRQVVJMKHVybCkpIHtcbiAgICAgICAgICAgIG1lc3NhZ2UgKz0gJzogeW91IG1heSBoYXZlIHByb3ZpZGVkIGFuIGludmFsaWQgTWFwYm94IGFjY2VzcyB0b2tlbi4gU2VlIGh0dHBzOi8vZG9jcy5tYXBib3guY29tL2FwaS9vdmVydmlldy8jYWNjZXNzLXRva2Vucy1hbmQtdG9rZW4tc2NvcGVzJztcbiAgICAgICAgfVxuICAgICAgICBzdXBlcihtZXNzYWdlKTtcbiAgICAgICAgdGhpcy5zdGF0dXMgPSBzdGF0dXM7XG4gICAgICAgIHRoaXMudXJsID0gdXJsO1xuICAgIH1cblxuICAgIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBgJHt0aGlzLm5hbWV9OiAke3RoaXMubWVzc2FnZX0gKCR7dGhpcy5zdGF0dXN9KTogJHt0aGlzLnVybH1gO1xuICAgIH1cbn1cblxuLy8gRW5zdXJlIHRoYXQgd2UncmUgc2VuZGluZyB0aGUgY29ycmVjdCByZWZlcnJlciBmcm9tIGJsb2IgVVJMIHdvcmtlciBidW5kbGVzLlxuLy8gRm9yIGZpbGVzIGxvYWRlZCBmcm9tIHRoZSBsb2NhbCBmaWxlIHN5c3RlbSwgYGxvY2F0aW9uLm9yaWdpbmAgd2lsbCBiZSBzZXRcbi8vIHRvIHRoZSBzdHJpbmcoISkgXCJudWxsXCIgKEZpcmVmb3gpLCBvciBcImZpbGU6Ly9cIiAoQ2hyb21lLCBTYWZhcmksIEVkZ2UsIElFKSxcbi8vIGFuZCB3ZSB3aWxsIHNldCBhbiBlbXB0eSByZWZlcnJlci4gT3RoZXJ3aXNlLCB3ZSdyZSB1c2luZyB0aGUgZG9jdW1lbnQncyBVUkwuXG4vKiBnbG9iYWwgc2VsZiAqL1xuZXhwb3J0IGNvbnN0IGdldFJlZmVycmVyOiAoKCkgPT4gc3RyaW5nKSA9IGlzV29ya2VyKCkgP1xuICAgICgpID0+IHNlbGYud29ya2VyICYmIHNlbGYud29ya2VyLnJlZmVycmVyIDpcbiAgICAoKSA9PiAod2luZG93LmxvY2F0aW9uLnByb3RvY29sID09PSAnYmxvYjonID8gd2luZG93LnBhcmVudCA6IHdpbmRvdykubG9jYXRpb24uaHJlZjtcblxuLy8gRGV0ZXJtaW5lcyB3aGV0aGVyIGEgVVJMIGlzIGEgZmlsZTovLyBVUkwuIFRoaXMgaXMgb2J2aW91c2x5IHRoZSBjYXNlIGlmIGl0IGJlZ2luc1xuLy8gd2l0aCBmaWxlOi8vLiBSZWxhdGl2ZSBVUkxzIGFyZSBhbHNvIGZpbGU6Ly8gVVJMcyBpZmYgdGhlIG9yaWdpbmFsIGRvY3VtZW50IHdhcyBsb2FkZWRcbi8vIHZpYSBhIGZpbGU6Ly8gVVJMLlxuY29uc3QgaXNGaWxlVVJMID0gKHVybDogc3RyaW5nKSA9PiAvXmZpbGU6Ly50ZXN0KHVybCkgfHwgKC9eZmlsZTovLnRlc3QoZ2V0UmVmZXJyZXIoKSkgJiYgIS9eXFx3KzovLnRlc3QodXJsKSk7XG5cbmZ1bmN0aW9uIG1ha2VGZXRjaFJlcXVlc3QocmVxdWVzdFBhcmFtZXRlcnM6IFJlcXVlc3RQYXJhbWV0ZXJzLCBjYWxsYmFjazogUmVzcG9uc2VDYWxsYmFjazxhbnk+KTogQ2FuY2VsYWJsZSB7XG4gICAgY29uc3QgY29udHJvbGxlciA9IG5ldyB3aW5kb3cuQWJvcnRDb250cm9sbGVyKCk7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyB3aW5kb3cuUmVxdWVzdChyZXF1ZXN0UGFyYW1ldGVycy51cmwsIHtcbiAgICAgICAgbWV0aG9kOiByZXF1ZXN0UGFyYW1ldGVycy5tZXRob2QgfHwgJ0dFVCcsXG4gICAgICAgIGJvZHk6IHJlcXVlc3RQYXJhbWV0ZXJzLmJvZHksXG4gICAgICAgIGNyZWRlbnRpYWxzOiByZXF1ZXN0UGFyYW1ldGVycy5jcmVkZW50aWFscyxcbiAgICAgICAgaGVhZGVyczogcmVxdWVzdFBhcmFtZXRlcnMuaGVhZGVycyxcbiAgICAgICAgcmVmZXJyZXI6IGdldFJlZmVycmVyKCksXG4gICAgICAgIHJlZmVycmVyUG9saWN5OiByZXF1ZXN0UGFyYW1ldGVycy5yZWZlcnJlclBvbGljeSxcbiAgICAgICAgc2lnbmFsOiBjb250cm9sbGVyLnNpZ25hbFxuICAgIH0pO1xuICAgIGxldCBjb21wbGV0ZSA9IGZhbHNlO1xuICAgIGxldCBhYm9ydGVkID0gZmFsc2U7XG5cbiAgICBjb25zdCBjYWNoZUlnbm9yaW5nU2VhcmNoID0gaGFzQ2FjaGVEZWZlYXRpbmdTa3UocmVxdWVzdC51cmwpO1xuXG4gICAgaWYgKHJlcXVlc3RQYXJhbWV0ZXJzLnR5cGUgPT09ICdqc29uJykge1xuICAgICAgICByZXF1ZXN0LmhlYWRlcnMuc2V0KCdBY2NlcHQnLCAnYXBwbGljYXRpb24vanNvbicpO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbGlkYXRlT3JGZXRjaCA9IChlcnI6ID9FcnJvciwgY2FjaGVkUmVzcG9uc2U6ID9SZXNwb25zZSwgcmVzcG9uc2VJc0ZyZXNoOiA/Ym9vbGVhbikgPT4ge1xuICAgICAgICBpZiAoYWJvcnRlZCkgcmV0dXJuO1xuXG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgIC8vIERvIGZldGNoIGluIGNhc2Ugb2YgY2FjaGUgZXJyb3IuXG4gICAgICAgICAgICAvLyBIVFRQIHBhZ2VzIGluIEVkZ2UgdHJpZ2dlciBhIHNlY3VyaXR5IGVycm9yIHRoYXQgY2FuIGJlIGlnbm9yZWQuXG4gICAgICAgICAgICBpZiAoZXJyLm1lc3NhZ2UgIT09ICdTZWN1cml0eUVycm9yJykge1xuICAgICAgICAgICAgICAgIHdhcm5PbmNlKGVyci50b1N0cmluZygpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjYWNoZWRSZXNwb25zZSAmJiByZXNwb25zZUlzRnJlc2gpIHtcbiAgICAgICAgICAgIHJldHVybiBmaW5pc2hSZXF1ZXN0KGNhY2hlZFJlc3BvbnNlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjYWNoZWRSZXNwb25zZSkge1xuICAgICAgICAgICAgLy8gV2UgY2FuJ3QgZG8gcmV2YWxpZGF0aW9uIHdpdGggJ0lmLU5vbmUtTWF0Y2gnIGJlY2F1c2UgdGhlbiB0aGVcbiAgICAgICAgICAgIC8vIHJlcXVlc3QgZG9lc24ndCBoYXZlIHNpbXBsZSBjb3JzIGhlYWRlcnMuXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXF1ZXN0VGltZSA9IERhdGUubm93KCk7XG5cbiAgICAgICAgd2luZG93LmZldGNoKHJlcXVlc3QpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgaWYgKHJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2FjaGVhYmxlUmVzcG9uc2UgPSBjYWNoZUlnbm9yaW5nU2VhcmNoID8gcmVzcG9uc2UuY2xvbmUoKSA6IG51bGw7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZpbmlzaFJlcXVlc3QocmVzcG9uc2UsIGNhY2hlYWJsZVJlc3BvbnNlLCByZXF1ZXN0VGltZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhuZXcgQUpBWEVycm9yKHJlc3BvbnNlLnN0YXR1c1RleHQsIHJlc3BvbnNlLnN0YXR1cywgcmVxdWVzdFBhcmFtZXRlcnMudXJsKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgIGlmIChlcnJvci5uYW1lID09PSAnQWJvcnRFcnJvcicpIHtcbiAgICAgICAgICAgICAgICAvLyBzaWxlbmNlIGV4cGVjdGVkIEFib3J0RXJyb3JcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYWxsYmFjayhuZXcgRXJyb3IoYCR7ZXJyb3IubWVzc2FnZX0gJHtyZXF1ZXN0UGFyYW1ldGVycy51cmx9YCkpO1xuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgY29uc3QgZmluaXNoUmVxdWVzdCA9IChyZXNwb25zZTogUmVzcG9uc2UsIGNhY2hlYWJsZVJlc3BvbnNlOiA/UmVzcG9uc2UsIHJlcXVlc3RUaW1lOiA/bnVtYmVyKSA9PiB7XG4gICAgICAgIChcbiAgICAgICAgICAgIHJlcXVlc3RQYXJhbWV0ZXJzLnR5cGUgPT09ICdhcnJheUJ1ZmZlcicgPyByZXNwb25zZS5hcnJheUJ1ZmZlcigpIDpcbiAgICAgICAgICAgIHJlcXVlc3RQYXJhbWV0ZXJzLnR5cGUgPT09ICdqc29uJyA/IHJlc3BvbnNlLmpzb24oKSA6XG4gICAgICAgICAgICByZXNwb25zZS50ZXh0KClcbiAgICAgICAgKS50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgICBpZiAoYWJvcnRlZCkgcmV0dXJuO1xuICAgICAgICAgICAgaWYgKGNhY2hlYWJsZVJlc3BvbnNlICYmIHJlcXVlc3RUaW1lKSB7XG4gICAgICAgICAgICAgICAgLy8gVGhlIHJlc3BvbnNlIG5lZWRzIHRvIGJlIGluc2VydGVkIGludG8gdGhlIGNhY2hlIGFmdGVyIGl0IGhhcyBjb21wbGV0ZWx5IGxvYWRlZC5cbiAgICAgICAgICAgICAgICAvLyBVbnRpbCBpdCBpcyBmdWxseSBsb2FkZWQgdGhlcmUgaXMgYSBjaGFuY2UgaXQgd2lsbCBiZSBhYm9ydGVkLiBBYm9ydGluZyB3aGlsZVxuICAgICAgICAgICAgICAgIC8vIHJlYWRpbmcgdGhlIGJvZHkgY2FuIGNhdXNlIHRoZSBjYWNoZSBpbnNlcnRpb24gdG8gZXJyb3IuIFdlIGNvdWxkIGNhdGNoIHRoaXMgZXJyb3JcbiAgICAgICAgICAgICAgICAvLyBpbiBtb3N0IGJyb3dzZXJzIGJ1dCBpbiBGaXJlZm94IGl0IHNlZW1zIHRvIHNvbWV0aW1lcyBjcmFzaCB0aGUgdGFiLiBBZGRpbmdcbiAgICAgICAgICAgICAgICAvLyBpdCB0byB0aGUgY2FjaGUgaGVyZSBhdm9pZHMgdGhhdCBlcnJvci5cbiAgICAgICAgICAgICAgICBjYWNoZVB1dChyZXF1ZXN0LCBjYWNoZWFibGVSZXNwb25zZSwgcmVxdWVzdFRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29tcGxldGUgPSB0cnVlO1xuICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgcmVzdWx0LCByZXNwb25zZS5oZWFkZXJzLmdldCgnQ2FjaGUtQ29udHJvbCcpLCByZXNwb25zZS5oZWFkZXJzLmdldCgnRXhwaXJlcycpKTtcbiAgICAgICAgfSkuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgICAgIGlmICghYWJvcnRlZCkgY2FsbGJhY2sobmV3IEVycm9yKGVyci5tZXNzYWdlKSk7XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBpZiAoY2FjaGVJZ25vcmluZ1NlYXJjaCkge1xuICAgICAgICBjYWNoZUdldChyZXF1ZXN0LCB2YWxpZGF0ZU9yRmV0Y2gpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHZhbGlkYXRlT3JGZXRjaChudWxsLCBudWxsKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge2NhbmNlbDogKCkgPT4ge1xuICAgICAgICBhYm9ydGVkID0gdHJ1ZTtcbiAgICAgICAgaWYgKCFjb21wbGV0ZSkgY29udHJvbGxlci5hYm9ydCgpO1xuICAgIH19O1xufVxuXG5mdW5jdGlvbiBtYWtlWE1MSHR0cFJlcXVlc3QocmVxdWVzdFBhcmFtZXRlcnM6IFJlcXVlc3RQYXJhbWV0ZXJzLCBjYWxsYmFjazogUmVzcG9uc2VDYWxsYmFjazxhbnk+KTogQ2FuY2VsYWJsZSB7XG4gICAgY29uc3QgeGhyOiBYTUxIdHRwUmVxdWVzdCA9IG5ldyB3aW5kb3cuWE1MSHR0cFJlcXVlc3QoKTtcblxuICAgIHhoci5vcGVuKHJlcXVlc3RQYXJhbWV0ZXJzLm1ldGhvZCB8fCAnR0VUJywgcmVxdWVzdFBhcmFtZXRlcnMudXJsLCB0cnVlKTtcbiAgICBpZiAocmVxdWVzdFBhcmFtZXRlcnMudHlwZSA9PT0gJ2FycmF5QnVmZmVyJykge1xuICAgICAgICB4aHIucmVzcG9uc2VUeXBlID0gJ2FycmF5YnVmZmVyJztcbiAgICB9XG4gICAgZm9yIChjb25zdCBrIGluIHJlcXVlc3RQYXJhbWV0ZXJzLmhlYWRlcnMpIHtcbiAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoaywgcmVxdWVzdFBhcmFtZXRlcnMuaGVhZGVyc1trXSk7XG4gICAgfVxuICAgIGlmIChyZXF1ZXN0UGFyYW1ldGVycy50eXBlID09PSAnanNvbicpIHtcbiAgICAgICAgeGhyLnJlc3BvbnNlVHlwZSA9ICd0ZXh0JztcbiAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ0FjY2VwdCcsICdhcHBsaWNhdGlvbi9qc29uJyk7XG4gICAgfVxuICAgIHhoci53aXRoQ3JlZGVudGlhbHMgPSByZXF1ZXN0UGFyYW1ldGVycy5jcmVkZW50aWFscyA9PT0gJ2luY2x1ZGUnO1xuICAgIHhoci5vbmVycm9yID0gKCkgPT4ge1xuICAgICAgICBjYWxsYmFjayhuZXcgRXJyb3IoeGhyLnN0YXR1c1RleHQpKTtcbiAgICB9O1xuICAgIHhoci5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICAgIGlmICgoKHhoci5zdGF0dXMgPj0gMjAwICYmIHhoci5zdGF0dXMgPCAzMDApIHx8IHhoci5zdGF0dXMgPT09IDApICYmIHhoci5yZXNwb25zZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgbGV0IGRhdGE6IG1peGVkID0geGhyLnJlc3BvbnNlO1xuICAgICAgICAgICAgaWYgKHJlcXVlc3RQYXJhbWV0ZXJzLnR5cGUgPT09ICdqc29uJykge1xuICAgICAgICAgICAgICAgIC8vIFdlJ3JlIG1hbnVhbGx5IHBhcnNpbmcgSlNPTiBoZXJlIHRvIGdldCBiZXR0ZXIgZXJyb3IgbWVzc2FnZXMuXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YSA9IEpTT04ucGFyc2UoeGhyLnJlc3BvbnNlKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgZGF0YSwgeGhyLmdldFJlc3BvbnNlSGVhZGVyKCdDYWNoZS1Db250cm9sJyksIHhoci5nZXRSZXNwb25zZUhlYWRlcignRXhwaXJlcycpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKG5ldyBBSkFYRXJyb3IoeGhyLnN0YXR1c1RleHQsIHhoci5zdGF0dXMsIHJlcXVlc3RQYXJhbWV0ZXJzLnVybCkpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICB4aHIuc2VuZChyZXF1ZXN0UGFyYW1ldGVycy5ib2R5KTtcbiAgICByZXR1cm4ge2NhbmNlbDogKCkgPT4geGhyLmFib3J0KCl9O1xufVxuXG5leHBvcnQgY29uc3QgbWFrZVJlcXVlc3QgPSBmdW5jdGlvbihyZXF1ZXN0UGFyYW1ldGVyczogUmVxdWVzdFBhcmFtZXRlcnMsIGNhbGxiYWNrOiBSZXNwb25zZUNhbGxiYWNrPGFueT4pOiBDYW5jZWxhYmxlIHtcbiAgICAvLyBXZSdyZSB0cnlpbmcgdG8gdXNlIHRoZSBGZXRjaCBBUEkgaWYgcG9zc2libGUuIEhvd2V2ZXIsIGluIHNvbWUgc2l0dWF0aW9ucyB3ZSBjYW4ndCB1c2UgaXQ6XG4gICAgLy8gLSBTYWZhcmkgZXhwb3NlcyB3aW5kb3cuQWJvcnRDb250cm9sbGVyLCBidXQgaXQgZG9lc24ndCB3b3JrIGFjdHVhbGx5IGFib3J0IGFueSByZXF1ZXN0cyBpblxuICAgIC8vICAgb2xkZXIgdmVyc2lvbnMgKHNlZSBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTc0OTgwI2MyKS4gSW4gdGhpcyBjYXNlLFxuICAgIC8vICAgd2UgZGlzcGF0Y2ggdGhlIHJlcXVlc3QgdG8gdGhlIG1haW4gdGhyZWFkIHNvIHRoYXQgd2UgY2FuIGdldCBhbiBhY2N1cmF0ZSByZWZlcnJlciBoZWFkZXIuXG4gICAgLy8gLSBSZXF1ZXN0cyBmb3IgcmVzb3VyY2VzIHdpdGggdGhlIGZpbGU6Ly8gVVJJIHNjaGVtZSBkb24ndCB3b3JrIHdpdGggdGhlIEZldGNoIEFQSSBlaXRoZXIuIEluXG4gICAgLy8gICB0aGlzIGNhc2Ugd2UgdW5jb25kaXRpb25hbGx5IHVzZSBYSFIgb24gdGhlIGN1cnJlbnQgdGhyZWFkIHNpbmNlIHJlZmVycmVycyBkb24ndCBtYXR0ZXIuXG4gICAgaWYgKCFpc0ZpbGVVUkwocmVxdWVzdFBhcmFtZXRlcnMudXJsKSkge1xuICAgICAgICBpZiAod2luZG93LmZldGNoICYmIHdpbmRvdy5SZXF1ZXN0ICYmIHdpbmRvdy5BYm9ydENvbnRyb2xsZXIgJiYgd2luZG93LlJlcXVlc3QucHJvdG90eXBlLmhhc093blByb3BlcnR5KCdzaWduYWwnKSkge1xuICAgICAgICAgICAgcmV0dXJuIG1ha2VGZXRjaFJlcXVlc3QocmVxdWVzdFBhcmFtZXRlcnMsIGNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNXb3JrZXIoKSAmJiBzZWxmLndvcmtlciAmJiBzZWxmLndvcmtlci5hY3Rvcikge1xuICAgICAgICAgICAgY29uc3QgcXVldWVPbk1haW5UaHJlYWQgPSB0cnVlO1xuICAgICAgICAgICAgcmV0dXJuIHNlbGYud29ya2VyLmFjdG9yLnNlbmQoJ2dldFJlc291cmNlJywgcmVxdWVzdFBhcmFtZXRlcnMsIGNhbGxiYWNrLCB1bmRlZmluZWQsIHF1ZXVlT25NYWluVGhyZWFkKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbWFrZVhNTEh0dHBSZXF1ZXN0KHJlcXVlc3RQYXJhbWV0ZXJzLCBjYWxsYmFjayk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0SlNPTiA9IGZ1bmN0aW9uKHJlcXVlc3RQYXJhbWV0ZXJzOiBSZXF1ZXN0UGFyYW1ldGVycywgY2FsbGJhY2s6IFJlc3BvbnNlQ2FsbGJhY2s8T2JqZWN0Pik6IENhbmNlbGFibGUge1xuICAgIHJldHVybiBtYWtlUmVxdWVzdChleHRlbmQocmVxdWVzdFBhcmFtZXRlcnMsIHt0eXBlOiAnanNvbid9KSwgY2FsbGJhY2spO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldEFycmF5QnVmZmVyID0gZnVuY3Rpb24ocmVxdWVzdFBhcmFtZXRlcnM6IFJlcXVlc3RQYXJhbWV0ZXJzLCBjYWxsYmFjazogUmVzcG9uc2VDYWxsYmFjazxBcnJheUJ1ZmZlcj4pOiBDYW5jZWxhYmxlIHtcbiAgICByZXR1cm4gbWFrZVJlcXVlc3QoZXh0ZW5kKHJlcXVlc3RQYXJhbWV0ZXJzLCB7dHlwZTogJ2FycmF5QnVmZmVyJ30pLCBjYWxsYmFjayk7XG59O1xuXG5leHBvcnQgY29uc3QgcG9zdERhdGEgPSBmdW5jdGlvbihyZXF1ZXN0UGFyYW1ldGVyczogUmVxdWVzdFBhcmFtZXRlcnMsIGNhbGxiYWNrOiBSZXNwb25zZUNhbGxiYWNrPHN0cmluZz4pOiBDYW5jZWxhYmxlIHtcbiAgICByZXR1cm4gbWFrZVJlcXVlc3QoZXh0ZW5kKHJlcXVlc3RQYXJhbWV0ZXJzLCB7bWV0aG9kOiAnUE9TVCd9KSwgY2FsbGJhY2spO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldERhdGEgPSBmdW5jdGlvbihyZXF1ZXN0UGFyYW1ldGVyczogUmVxdWVzdFBhcmFtZXRlcnMsIGNhbGxiYWNrOiBSZXNwb25zZUNhbGxiYWNrPHN0cmluZz4pOiBDYW5jZWxhYmxlIHtcbiAgICByZXR1cm4gbWFrZVJlcXVlc3QoZXh0ZW5kKHJlcXVlc3RQYXJhbWV0ZXJzLCB7bWV0aG9kOiAnR0VUJ30pLCBjYWxsYmFjayk7XG59O1xuXG5mdW5jdGlvbiBzYW1lT3JpZ2luKHVybDogc3RyaW5nKSB7XG4gICAgY29uc3QgYTogSFRNTEFuY2hvckVsZW1lbnQgPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO1xuICAgIGEuaHJlZiA9IHVybDtcbiAgICByZXR1cm4gYS5wcm90b2NvbCA9PT0gd2luZG93LmRvY3VtZW50LmxvY2F0aW9uLnByb3RvY29sICYmIGEuaG9zdCA9PT0gd2luZG93LmRvY3VtZW50LmxvY2F0aW9uLmhvc3Q7XG59XG5cbmNvbnN0IHRyYW5zcGFyZW50UG5nVXJsID0gJ2RhdGE6aW1hZ2UvcG5nO2Jhc2U2NCxpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBQUVBQUFBQkNBWUFBQUFmRmNTSkFBQUFDMGxFUVZRWVYyTmdBQUlBQUFVQUFhclZ5RkVBQUFBQVNVVk9SSzVDWUlJPSc7XG5cbmZ1bmN0aW9uIGFycmF5QnVmZmVyVG9JbWFnZShkYXRhOiBBcnJheUJ1ZmZlciwgY2FsbGJhY2s6IENhbGxiYWNrPEhUTUxJbWFnZUVsZW1lbnQ+KSB7XG4gICAgY29uc3QgaW1nOiBIVE1MSW1hZ2VFbGVtZW50ID0gbmV3IHdpbmRvdy5JbWFnZSgpO1xuICAgIGNvbnN0IFVSTCA9IHdpbmRvdy5VUkw7XG4gICAgaW1nLm9ubG9hZCA9ICgpID0+IHtcbiAgICAgICAgY2FsbGJhY2sobnVsbCwgaW1nKTtcbiAgICAgICAgVVJMLnJldm9rZU9iamVjdFVSTChpbWcuc3JjKTtcbiAgICAgICAgLy8gcHJldmVudCBpbWFnZSBkYXRhVVJJIG1lbW9yeSBsZWFrIGluIFNhZmFyaTtcbiAgICAgICAgLy8gYnV0IGRvbid0IGZyZWUgdGhlIGltYWdlIGltbWVkaWF0ZWx5IGJlY2F1c2UgaXQgbWlnaHQgYmUgdXBsb2FkZWQgaW4gdGhlIG5leHQgZnJhbWVcbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21hcGJveC9tYXBib3gtZ2wtanMvaXNzdWVzLzEwMjI2XG4gICAgICAgIGltZy5vbmxvYWQgPSBudWxsO1xuICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHsgaW1nLnNyYyA9IHRyYW5zcGFyZW50UG5nVXJsOyB9KTtcbiAgICB9O1xuICAgIGltZy5vbmVycm9yID0gKCkgPT4gY2FsbGJhY2sobmV3IEVycm9yKCdDb3VsZCBub3QgbG9hZCBpbWFnZS4gUGxlYXNlIG1ha2Ugc3VyZSB0byB1c2UgYSBzdXBwb3J0ZWQgaW1hZ2UgdHlwZSBzdWNoIGFzIFBORyBvciBKUEVHLiBOb3RlIHRoYXQgU1ZHcyBhcmUgbm90IHN1cHBvcnRlZC4nKSk7XG4gICAgY29uc3QgYmxvYjogQmxvYiA9IG5ldyB3aW5kb3cuQmxvYihbbmV3IFVpbnQ4QXJyYXkoZGF0YSldLCB7dHlwZTogJ2ltYWdlL3BuZyd9KTtcbiAgICBpbWcuc3JjID0gZGF0YS5ieXRlTGVuZ3RoID8gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKSA6IHRyYW5zcGFyZW50UG5nVXJsO1xufVxuXG5mdW5jdGlvbiBhcnJheUJ1ZmZlclRvSW1hZ2VCaXRtYXAoZGF0YTogQXJyYXlCdWZmZXIsIGNhbGxiYWNrOiBDYWxsYmFjazxJbWFnZUJpdG1hcD4pIHtcbiAgICBjb25zdCBibG9iOiBCbG9iID0gbmV3IHdpbmRvdy5CbG9iKFtuZXcgVWludDhBcnJheShkYXRhKV0sIHt0eXBlOiAnaW1hZ2UvcG5nJ30pO1xuICAgIHdpbmRvdy5jcmVhdGVJbWFnZUJpdG1hcChibG9iKS50aGVuKChpbWdCaXRtYXApID0+IHtcbiAgICAgICAgY2FsbGJhY2sobnVsbCwgaW1nQml0bWFwKTtcbiAgICB9KS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICBjYWxsYmFjayhuZXcgRXJyb3IoYENvdWxkIG5vdCBsb2FkIGltYWdlIGJlY2F1c2Ugb2YgJHtlLm1lc3NhZ2V9LiBQbGVhc2UgbWFrZSBzdXJlIHRvIHVzZSBhIHN1cHBvcnRlZCBpbWFnZSB0eXBlIHN1Y2ggYXMgUE5HIG9yIEpQRUcuIE5vdGUgdGhhdCBTVkdzIGFyZSBub3Qgc3VwcG9ydGVkLmApKTtcbiAgICB9KTtcbn1cblxubGV0IGltYWdlUXVldWUsIG51bUltYWdlUmVxdWVzdHM7XG5leHBvcnQgY29uc3QgcmVzZXRJbWFnZVJlcXVlc3RRdWV1ZSA9ICgpID0+IHtcbiAgICBpbWFnZVF1ZXVlID0gW107XG4gICAgbnVtSW1hZ2VSZXF1ZXN0cyA9IDA7XG59O1xucmVzZXRJbWFnZVJlcXVlc3RRdWV1ZSgpO1xuXG5leHBvcnQgY29uc3QgZ2V0SW1hZ2UgPSBmdW5jdGlvbihyZXF1ZXN0UGFyYW1ldGVyczogUmVxdWVzdFBhcmFtZXRlcnMsIGNhbGxiYWNrOiBSZXNwb25zZUNhbGxiYWNrPEhUTUxJbWFnZUVsZW1lbnQgfCBJbWFnZUJpdG1hcD4pOiBDYW5jZWxhYmxlIHtcbiAgICBpZiAod2VicFN1cHBvcnRlZC5zdXBwb3J0ZWQpIHtcbiAgICAgICAgaWYgKCFyZXF1ZXN0UGFyYW1ldGVycy5oZWFkZXJzKSB7XG4gICAgICAgICAgICByZXF1ZXN0UGFyYW1ldGVycy5oZWFkZXJzID0ge307XG4gICAgICAgIH1cbiAgICAgICAgcmVxdWVzdFBhcmFtZXRlcnMuaGVhZGVycy5hY2NlcHQgPSAnaW1hZ2Uvd2VicCwqLyonO1xuICAgIH1cblxuICAgIC8vIGxpbWl0IGNvbmN1cnJlbnQgaW1hZ2UgbG9hZHMgdG8gaGVscCB3aXRoIHJhc3RlciBzb3VyY2VzIHBlcmZvcm1hbmNlIG9uIGJpZyBzY3JlZW5zXG4gICAgaWYgKG51bUltYWdlUmVxdWVzdHMgPj0gY29uZmlnLk1BWF9QQVJBTExFTF9JTUFHRV9SRVFVRVNUUykge1xuICAgICAgICBjb25zdCBxdWV1ZWQgPSB7XG4gICAgICAgICAgICByZXF1ZXN0UGFyYW1ldGVycyxcbiAgICAgICAgICAgIGNhbGxiYWNrLFxuICAgICAgICAgICAgY2FuY2VsbGVkOiBmYWxzZSxcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbb2JqZWN0LXRoaXMtcmVmZXJlbmNlXVxuICAgICAgICAgICAgY2FuY2VsKCkgeyB0aGlzLmNhbmNlbGxlZCA9IHRydWU7IH1cbiAgICAgICAgfTtcbiAgICAgICAgaW1hZ2VRdWV1ZS5wdXNoKHF1ZXVlZCk7XG4gICAgICAgIHJldHVybiBxdWV1ZWQ7XG4gICAgfVxuICAgIG51bUltYWdlUmVxdWVzdHMrKztcblxuICAgIGxldCBhZHZhbmNlZCA9IGZhbHNlO1xuICAgIGNvbnN0IGFkdmFuY2VJbWFnZVJlcXVlc3RRdWV1ZSA9ICgpID0+IHtcbiAgICAgICAgaWYgKGFkdmFuY2VkKSByZXR1cm47XG4gICAgICAgIGFkdmFuY2VkID0gdHJ1ZTtcbiAgICAgICAgbnVtSW1hZ2VSZXF1ZXN0cy0tO1xuICAgICAgICBhc3NlcnQobnVtSW1hZ2VSZXF1ZXN0cyA+PSAwKTtcbiAgICAgICAgd2hpbGUgKGltYWdlUXVldWUubGVuZ3RoICYmIG51bUltYWdlUmVxdWVzdHMgPCBjb25maWcuTUFYX1BBUkFMTEVMX0lNQUdFX1JFUVVFU1RTKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbiAgICAgICAgICAgIGNvbnN0IHJlcXVlc3QgPSBpbWFnZVF1ZXVlLnNoaWZ0KCk7XG4gICAgICAgICAgICBjb25zdCB7cmVxdWVzdFBhcmFtZXRlcnMsIGNhbGxiYWNrLCBjYW5jZWxsZWR9ID0gcmVxdWVzdDtcbiAgICAgICAgICAgIGlmICghY2FuY2VsbGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVtjYW5ub3Qtd3JpdGVdIC0gRmxvdyBjYW4ndCBpbmZlciB0aGF0IGNhbmNlbCBpcyBhIHdyaXRhYmxlIHByb3BlcnR5XG4gICAgICAgICAgICAgICAgcmVxdWVzdC5jYW5jZWwgPSBnZXRJbWFnZShyZXF1ZXN0UGFyYW1ldGVycywgY2FsbGJhY2spLmNhbmNlbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvLyByZXF1ZXN0IHRoZSBpbWFnZSB3aXRoIFhIUiB0byB3b3JrIGFyb3VuZCBjYWNoaW5nIGlzc3Vlc1xuICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vbWFwYm94L21hcGJveC1nbC1qcy9pc3N1ZXMvMTQ3MFxuICAgIGNvbnN0IHJlcXVlc3QgPSBnZXRBcnJheUJ1ZmZlcihyZXF1ZXN0UGFyYW1ldGVycywgKGVycjogP0Vycm9yLCBkYXRhOiA/QXJyYXlCdWZmZXIsIGNhY2hlQ29udHJvbDogP3N0cmluZywgZXhwaXJlczogP3N0cmluZykgPT4ge1xuXG4gICAgICAgIGFkdmFuY2VJbWFnZVJlcXVlc3RRdWV1ZSgpO1xuXG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGVycik7XG4gICAgICAgIH0gZWxzZSBpZiAoZGF0YSkge1xuICAgICAgICAgICAgaWYgKHdpbmRvdy5jcmVhdGVJbWFnZUJpdG1hcCkge1xuICAgICAgICAgICAgICAgIGFycmF5QnVmZmVyVG9JbWFnZUJpdG1hcChkYXRhLCAoZXJyLCBpbWdCaXRtYXApID0+IGNhbGxiYWNrKGVyciwgaW1nQml0bWFwLCBjYWNoZUNvbnRyb2wsIGV4cGlyZXMpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYXJyYXlCdWZmZXJUb0ltYWdlKGRhdGEsIChlcnIsIGltZykgPT4gY2FsbGJhY2soZXJyLCBpbWcsIGNhY2hlQ29udHJvbCwgZXhwaXJlcykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBjYW5jZWw6ICgpID0+IHtcbiAgICAgICAgICAgIHJlcXVlc3QuY2FuY2VsKCk7XG4gICAgICAgICAgICBhZHZhbmNlSW1hZ2VSZXF1ZXN0UXVldWUoKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0VmlkZW8gPSBmdW5jdGlvbih1cmxzOiBBcnJheTxzdHJpbmc+LCBjYWxsYmFjazogQ2FsbGJhY2s8SFRNTFZpZGVvRWxlbWVudD4pOiBDYW5jZWxhYmxlIHtcbiAgICBjb25zdCB2aWRlbzogSFRNTFZpZGVvRWxlbWVudCA9IHdpbmRvdy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuICAgIHZpZGVvLm11dGVkID0gdHJ1ZTtcbiAgICB2aWRlby5vbmxvYWRzdGFydCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBjYWxsYmFjayhudWxsLCB2aWRlbyk7XG4gICAgfTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHVybHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgczogSFRNTFNvdXJjZUVsZW1lbnQgPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc291cmNlJyk7XG4gICAgICAgIGlmICghc2FtZU9yaWdpbih1cmxzW2ldKSkge1xuICAgICAgICAgICAgdmlkZW8uY3Jvc3NPcmlnaW4gPSAnQW5vbnltb3VzJztcbiAgICAgICAgfVxuICAgICAgICBzLnNyYyA9IHVybHNbaV07XG4gICAgICAgIHZpZGVvLmFwcGVuZENoaWxkKHMpO1xuICAgIH1cbiAgICByZXR1cm4ge2NhbmNlbDogKCkgPT4ge319O1xufTtcbiIsIi8vIEBmbG93XG5cbi8qKioqKiBTVEFSVCBXQVJOSU5HIFJFTU9WQUwgT1IgTU9ESUZJQ0FUSU9OIE9GIFRIRVxuKiBGT0xMT1dJTkcgQ09ERSBWSU9MQVRFUyBUSEUgTUFQQk9YIFRFUk1TIE9GIFNFUlZJQ0UgICoqKioqKlxuKiBUaGUgZm9sbG93aW5nIGNvZGUgaXMgdXNlZCB0byBhY2Nlc3MgTWFwYm94J3MgQVBJcy4gUmVtb3ZhbCBvciBtb2RpZmljYXRpb25cbiogb2YgdGhpcyBjb2RlIGNhbiByZXN1bHQgaW4gaGlnaGVyIGZlZXMgYW5kL29yXG4qIHRlcm1pbmF0aW9uIG9mIHlvdXIgYWNjb3VudCB3aXRoIE1hcGJveC5cbipcbiogVW5kZXIgdGhlIE1hcGJveCBUZXJtcyBvZiBTZXJ2aWNlLCB5b3UgbWF5IG5vdCB1c2UgdGhpcyBjb2RlIHRvIGFjY2VzcyBNYXBib3hcbiogTWFwcGluZyBBUElzIG90aGVyIHRoYW4gdGhyb3VnaCBNYXBib3ggU0RLcy5cbipcbiogVGhlIE1hcHBpbmcgQVBJcyBkb2N1bWVudGF0aW9uIGlzIGF2YWlsYWJsZSBhdCBodHRwczovL2RvY3MubWFwYm94LmNvbS9hcGkvbWFwcy8jbWFwc1xuKiBhbmQgdGhlIE1hcGJveCBUZXJtcyBvZiBTZXJ2aWNlIGFyZSBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cubWFwYm94LmNvbS90b3MvXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbmltcG9ydCBjb25maWcgZnJvbSAnLi9jb25maWcuanMnO1xuaW1wb3J0IHdpbmRvdyBmcm9tICcuL3dpbmRvdy5qcyc7XG5pbXBvcnQgd2VicFN1cHBvcnRlZCBmcm9tICcuL3dlYnBfc3VwcG9ydGVkLmpzJztcbmltcG9ydCB7Y3JlYXRlU2t1VG9rZW4sIFNLVV9JRH0gZnJvbSAnLi9za3VfdG9rZW4uanMnO1xuaW1wb3J0IHt2ZXJzaW9uIGFzIHNka1ZlcnNpb259IGZyb20gJy4uLy4uL3BhY2thZ2UuanNvbic7XG5pbXBvcnQge3V1aWQsIHZhbGlkYXRlVXVpZCwgc3RvcmFnZUF2YWlsYWJsZSwgYjY0RGVjb2RlVW5pY29kZSwgYjY0RW5jb2RlVW5pY29kZSwgd2Fybk9uY2UsIGV4dGVuZH0gZnJvbSAnLi91dGlsLmpzJztcbmltcG9ydCB7cG9zdERhdGEsIFJlc291cmNlVHlwZSwgZ2V0RGF0YX0gZnJvbSAnLi9hamF4LmpzJztcbmltcG9ydCB7Z2V0TGl2ZVBlcmZvcm1hbmNlTWV0cmljc30gZnJvbSAnLi4vdXRpbC9saXZlX3BlcmZvcm1hbmNlLmpzJztcbmltcG9ydCB0eXBlIHtMaXZlUGVyZm9ybWFuY2VEYXRhfSBmcm9tICcuLi91dGlsL2xpdmVfcGVyZm9ybWFuY2UuanMnO1xuaW1wb3J0IHR5cGUge1JlcXVlc3RQYXJhbWV0ZXJzfSBmcm9tICcuL2FqYXguanMnO1xuaW1wb3J0IHR5cGUge0NhbmNlbGFibGV9IGZyb20gJy4uL3R5cGVzL2NhbmNlbGFibGUuanMnO1xuaW1wb3J0IHR5cGUge1RpbGVKU09OfSBmcm9tICcuLi90eXBlcy90aWxlanNvbi5qcyc7XG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbnR5cGUgUmVzb3VyY2VUeXBlRW51bSA9ICRLZXlzPHR5cGVvZiBSZXNvdXJjZVR5cGU+O1xuZXhwb3J0IHR5cGUgUmVxdWVzdFRyYW5zZm9ybUZ1bmN0aW9uID0gKHVybDogc3RyaW5nLCByZXNvdXJjZVR5cGU/OiBSZXNvdXJjZVR5cGVFbnVtKSA9PiBSZXF1ZXN0UGFyYW1ldGVycztcblxudHlwZSBVcmxPYmplY3QgPSB7fFxuICAgIHByb3RvY29sOiBzdHJpbmcsXG4gICAgYXV0aG9yaXR5OiBzdHJpbmcsXG4gICAgcGF0aDogc3RyaW5nLFxuICAgIHBhcmFtczogQXJyYXk8c3RyaW5nPlxufH07XG5cbnR5cGUgRXZlbnRDYWxsYmFjayA9IChlcnI6ID9FcnJvcikgPT4gdm9pZDtcblxuZXhwb3J0IGNvbnN0IEFVVEhfRVJSX01TRzogc3RyaW5nID0gJ05PX0FDQ0VTU19UT0tFTic7XG5cbmV4cG9ydCBjbGFzcyBSZXF1ZXN0TWFuYWdlciB7XG4gICAgX3NrdVRva2VuOiBzdHJpbmc7XG4gICAgX3NrdVRva2VuRXhwaXJlc0F0OiBudW1iZXI7XG4gICAgX3RyYW5zZm9ybVJlcXVlc3RGbjogP1JlcXVlc3RUcmFuc2Zvcm1GdW5jdGlvbjtcbiAgICBfY3VzdG9tQWNjZXNzVG9rZW46ID9zdHJpbmc7XG4gICAgX3NpbGVuY2VBdXRoRXJyb3JzOiBib29sZWFuO1xuXG4gICAgY29uc3RydWN0b3IodHJhbnNmb3JtUmVxdWVzdEZuPzogUmVxdWVzdFRyYW5zZm9ybUZ1bmN0aW9uLCBjdXN0b21BY2Nlc3NUb2tlbj86IHN0cmluZywgc2lsZW5jZUF1dGhFcnJvcnM6ID9ib29sZWFuKSB7XG4gICAgICAgIHRoaXMuX3RyYW5zZm9ybVJlcXVlc3RGbiA9IHRyYW5zZm9ybVJlcXVlc3RGbjtcbiAgICAgICAgdGhpcy5fY3VzdG9tQWNjZXNzVG9rZW4gPSBjdXN0b21BY2Nlc3NUb2tlbjtcbiAgICAgICAgdGhpcy5fc2lsZW5jZUF1dGhFcnJvcnMgPSAhIXNpbGVuY2VBdXRoRXJyb3JzO1xuICAgICAgICB0aGlzLl9jcmVhdGVTa3VUb2tlbigpO1xuICAgIH1cblxuICAgIF9jcmVhdGVTa3VUb2tlbigpIHtcbiAgICAgICAgY29uc3Qgc2t1VG9rZW4gPSBjcmVhdGVTa3VUb2tlbigpO1xuICAgICAgICB0aGlzLl9za3VUb2tlbiA9IHNrdVRva2VuLnRva2VuO1xuICAgICAgICB0aGlzLl9za3VUb2tlbkV4cGlyZXNBdCA9IHNrdVRva2VuLnRva2VuRXhwaXJlc0F0O1xuICAgIH1cblxuICAgIF9pc1NrdVRva2VuRXhwaXJlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIERhdGUubm93KCkgPiB0aGlzLl9za3VUb2tlbkV4cGlyZXNBdDtcbiAgICB9XG5cbiAgICB0cmFuc2Zvcm1SZXF1ZXN0KHVybDogc3RyaW5nLCB0eXBlOiBSZXNvdXJjZVR5cGVFbnVtKTogUmVxdWVzdFBhcmFtZXRlcnMge1xuICAgICAgICBpZiAodGhpcy5fdHJhbnNmb3JtUmVxdWVzdEZuKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdHJhbnNmb3JtUmVxdWVzdEZuKHVybCwgdHlwZSkgfHwge3VybH07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge3VybH07XG4gICAgfVxuXG4gICAgbm9ybWFsaXplU3R5bGVVUkwodXJsOiBzdHJpbmcsIGFjY2Vzc1Rva2VuPzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKCFpc01hcGJveFVSTCh1cmwpKSByZXR1cm4gdXJsO1xuICAgICAgICBjb25zdCB1cmxPYmplY3QgPSBwYXJzZVVybCh1cmwpO1xuICAgICAgICB1cmxPYmplY3QucGF0aCA9IGAvc3R5bGVzL3YxJHt1cmxPYmplY3QucGF0aH1gO1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFrZUFQSVVSTCh1cmxPYmplY3QsIHRoaXMuX2N1c3RvbUFjY2Vzc1Rva2VuIHx8IGFjY2Vzc1Rva2VuKTtcbiAgICB9XG5cbiAgICBub3JtYWxpemVHbHlwaHNVUkwodXJsOiBzdHJpbmcsIGFjY2Vzc1Rva2VuPzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKCFpc01hcGJveFVSTCh1cmwpKSByZXR1cm4gdXJsO1xuICAgICAgICBjb25zdCB1cmxPYmplY3QgPSBwYXJzZVVybCh1cmwpO1xuICAgICAgICB1cmxPYmplY3QucGF0aCA9IGAvZm9udHMvdjEke3VybE9iamVjdC5wYXRofWA7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYWtlQVBJVVJMKHVybE9iamVjdCwgdGhpcy5fY3VzdG9tQWNjZXNzVG9rZW4gfHwgYWNjZXNzVG9rZW4pO1xuICAgIH1cblxuICAgIG5vcm1hbGl6ZVNvdXJjZVVSTCh1cmw6IHN0cmluZywgYWNjZXNzVG9rZW4/OiA/c3RyaW5nLCBsYW5ndWFnZT86ID9zdHJpbmcsIHdvcmxkdmlldz86ID9zdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBpZiAoIWlzTWFwYm94VVJMKHVybCkpIHJldHVybiB1cmw7XG4gICAgICAgIGNvbnN0IHVybE9iamVjdCA9IHBhcnNlVXJsKHVybCk7XG4gICAgICAgIHVybE9iamVjdC5wYXRoID0gYC92NC8ke3VybE9iamVjdC5hdXRob3JpdHl9Lmpzb25gO1xuICAgICAgICAvLyBUaWxlSlNPTiByZXF1ZXN0cyBuZWVkIGEgc2VjdXJlIGZsYWcgYXBwZW5kZWQgdG8gdGhlaXIgVVJMcyBzb1xuICAgICAgICAvLyB0aGF0IHRoZSBzZXJ2ZXIga25vd3MgdG8gc2VuZCBTU0wtaWZpZWQgcmVzb3VyY2UgcmVmZXJlbmNlcy5cbiAgICAgICAgdXJsT2JqZWN0LnBhcmFtcy5wdXNoKCdzZWN1cmUnKTtcbiAgICAgICAgaWYgKGxhbmd1YWdlKSB7XG4gICAgICAgICAgICB1cmxPYmplY3QucGFyYW1zLnB1c2goYGxhbmd1YWdlPSR7bGFuZ3VhZ2V9YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHdvcmxkdmlldykge1xuICAgICAgICAgICAgdXJsT2JqZWN0LnBhcmFtcy5wdXNoKGB3b3JsZHZpZXc9JHt3b3JsZHZpZXd9YCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5fbWFrZUFQSVVSTCh1cmxPYmplY3QsIHRoaXMuX2N1c3RvbUFjY2Vzc1Rva2VuIHx8IGFjY2Vzc1Rva2VuKTtcbiAgICB9XG5cbiAgICBub3JtYWxpemVTcHJpdGVVUkwodXJsOiBzdHJpbmcsIGZvcm1hdDogc3RyaW5nLCBleHRlbnNpb246IHN0cmluZywgYWNjZXNzVG9rZW4/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBjb25zdCB1cmxPYmplY3QgPSBwYXJzZVVybCh1cmwpO1xuICAgICAgICBpZiAoIWlzTWFwYm94VVJMKHVybCkpIHtcbiAgICAgICAgICAgIHVybE9iamVjdC5wYXRoICs9IGAke2Zvcm1hdH0ke2V4dGVuc2lvbn1gO1xuICAgICAgICAgICAgcmV0dXJuIGZvcm1hdFVybCh1cmxPYmplY3QpO1xuICAgICAgICB9XG4gICAgICAgIHVybE9iamVjdC5wYXRoID0gYC9zdHlsZXMvdjEke3VybE9iamVjdC5wYXRofS9zcHJpdGUke2Zvcm1hdH0ke2V4dGVuc2lvbn1gO1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFrZUFQSVVSTCh1cmxPYmplY3QsIHRoaXMuX2N1c3RvbUFjY2Vzc1Rva2VuIHx8IGFjY2Vzc1Rva2VuKTtcbiAgICB9XG5cbiAgICBub3JtYWxpemVUaWxlVVJMKHRpbGVVUkw6IHN0cmluZywgdXNlMng/OiBib29sZWFuLCByYXN0ZXJUaWxlU2l6ZT86IG51bWJlcik6IHN0cmluZyB7XG4gICAgICAgIGlmICh0aGlzLl9pc1NrdVRva2VuRXhwaXJlZCgpKSB7XG4gICAgICAgICAgICB0aGlzLl9jcmVhdGVTa3VUb2tlbigpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRpbGVVUkwgJiYgIWlzTWFwYm94VVJMKHRpbGVVUkwpKSByZXR1cm4gdGlsZVVSTDtcblxuICAgICAgICBjb25zdCB1cmxPYmplY3QgPSBwYXJzZVVybCh0aWxlVVJMKTtcbiAgICAgICAgY29uc3QgaW1hZ2VFeHRlbnNpb25SZSA9IC8oXFwuKHBuZ3xqcGcpXFxkKikoPz0kKS87XG4gICAgICAgIGNvbnN0IGV4dGVuc2lvbiA9IHdlYnBTdXBwb3J0ZWQuc3VwcG9ydGVkID8gJy53ZWJwJyA6ICckMSc7XG5cbiAgICAgICAgLy8gVGhlIHY0IG1hcGJveCB0aWxlIEFQSSBzdXBwb3J0cyA1MTJ4NTEyIGltYWdlIHRpbGVzIGJ1dCB0aGV5IG11c3QgYmUgcmVxdWVzdGVkIGFzICdAMngnIHRpbGVzLlxuICAgICAgICBjb25zdCB1c2UyeEFzNTEyID0gcmFzdGVyVGlsZVNpemUgJiYgdXJsT2JqZWN0LmF1dGhvcml0eSAhPT0gJ3Jhc3RlcicgJiYgcmFzdGVyVGlsZVNpemUgPT09IDUxMjtcblxuICAgICAgICBjb25zdCBzdWZmaXggPSB1c2UyeCB8fCB1c2UyeEFzNTEyID8gJ0AyeCcgOiAnJztcbiAgICAgICAgdXJsT2JqZWN0LnBhdGggPSB1cmxPYmplY3QucGF0aC5yZXBsYWNlKGltYWdlRXh0ZW5zaW9uUmUsIGAke3N1ZmZpeH0ke2V4dGVuc2lvbn1gKTtcblxuICAgICAgICBpZiAodXJsT2JqZWN0LmF1dGhvcml0eSA9PT0gJ3Jhc3RlcicpIHtcbiAgICAgICAgICAgIHVybE9iamVjdC5wYXRoID0gYC8ke2NvbmZpZy5SQVNURVJfVVJMX1BSRUZJWH0ke3VybE9iamVjdC5wYXRofWA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCB0aWxlVVJMQVBJUHJlZml4UmUgPSAvXi4rXFwvdjRcXC8vO1xuICAgICAgICAgICAgdXJsT2JqZWN0LnBhdGggPSB1cmxPYmplY3QucGF0aC5yZXBsYWNlKHRpbGVVUkxBUElQcmVmaXhSZSwgJy8nKTtcbiAgICAgICAgICAgIHVybE9iamVjdC5wYXRoID0gYC8ke2NvbmZpZy5USUxFX1VSTF9WRVJTSU9OfSR7dXJsT2JqZWN0LnBhdGh9YDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGFjY2Vzc1Rva2VuID0gdGhpcy5fY3VzdG9tQWNjZXNzVG9rZW4gfHwgZ2V0QWNjZXNzVG9rZW4odXJsT2JqZWN0LnBhcmFtcykgfHwgY29uZmlnLkFDQ0VTU19UT0tFTjtcbiAgICAgICAgaWYgKGNvbmZpZy5SRVFVSVJFX0FDQ0VTU19UT0tFTiAmJiBhY2Nlc3NUb2tlbiAmJiB0aGlzLl9za3VUb2tlbikge1xuICAgICAgICAgICAgdXJsT2JqZWN0LnBhcmFtcy5wdXNoKGBza3U9JHt0aGlzLl9za3VUb2tlbn1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLl9tYWtlQVBJVVJMKHVybE9iamVjdCwgYWNjZXNzVG9rZW4pO1xuICAgIH1cblxuICAgIGNhbm9uaWNhbGl6ZVRpbGVVUkwodXJsOiBzdHJpbmcsIHJlbW92ZUFjY2Vzc1Rva2VuOiBib29sZWFuKTogc3RyaW5nIHtcbiAgICAgICAgLy8gbWF0Y2hlcyBhbnkgZmlsZSBleHRlbnNpb24gc3BlY2lmaWVkIGJ5IGEgZG90IGFuZCBvbmUgb3IgbW9yZSBhbHBoYW51bWVyaWMgY2hhcmFjdGVyc1xuICAgICAgICBjb25zdCBleHRlbnNpb25SZSA9IC9cXC5bXFx3XSskLztcblxuICAgICAgICBjb25zdCB1cmxPYmplY3QgPSBwYXJzZVVybCh1cmwpO1xuICAgICAgICAvLyBNYWtlIHN1cmUgdGhhdCB3ZSBhcmUgZGVhbGluZyB3aXRoIGEgdmFsaWQgTWFwYm94IHRpbGUgVVJMLlxuICAgICAgICAvLyBIYXMgdG8gYmVnaW4gd2l0aCAvdjQvIG9yIC9yYXN0ZXIvdjEsIHdpdGggYSB2YWxpZCBmaWxlbmFtZSArIGV4dGVuc2lvblxuICAgICAgICBpZiAoIXVybE9iamVjdC5wYXRoLm1hdGNoKC9eKFxcL3Y0XFwvfFxcL3Jhc3RlclxcL3YxXFwvKS8pIHx8ICF1cmxPYmplY3QucGF0aC5tYXRjaChleHRlbnNpb25SZSkpIHtcbiAgICAgICAgICAgIC8vIE5vdCBhIHByb3BlciBNYXBib3ggdGlsZSBVUkwuXG4gICAgICAgICAgICByZXR1cm4gdXJsO1xuICAgICAgICB9XG4gICAgICAgIC8vIFJlYXNzZW1ibGUgdGhlIGNhbm9uaWNhbCBVUkwgZnJvbSB0aGUgcGFydHMgd2UndmUgcGFyc2VkIGJlZm9yZS5cbiAgICAgICAgbGV0IHJlc3VsdCA9IFwibWFwYm94Oi8vXCI7XG4gICAgICAgIGlmICh1cmxPYmplY3QucGF0aC5tYXRjaCgvXlxcL3Jhc3RlclxcL3YxXFwvLykpIHtcbiAgICAgICAgICAgIC8vIElmIHRoZSB0aWxlIHVybCBoYXMgL3Jhc3Rlci92MS8sIG1ha2UgdGhlIGZpbmFsIFVSTCBtYXBib3g6Ly9yYXN0ZXIvLi4uLlxuICAgICAgICAgICAgY29uc3QgcmFzdGVyUHJlZml4ID0gYC8ke2NvbmZpZy5SQVNURVJfVVJMX1BSRUZJWH0vYDtcbiAgICAgICAgICAgIHJlc3VsdCArPSBgcmFzdGVyLyR7dXJsT2JqZWN0LnBhdGgucmVwbGFjZShyYXN0ZXJQcmVmaXgsICcnKX1gO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgdGlsZXNQcmVmaXggPSBgLyR7Y29uZmlnLlRJTEVfVVJMX1ZFUlNJT059L2A7XG4gICAgICAgICAgICByZXN1bHQgKz0gYHRpbGVzLyR7dXJsT2JqZWN0LnBhdGgucmVwbGFjZSh0aWxlc1ByZWZpeCwgJycpfWA7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBcHBlbmQgdGhlIHF1ZXJ5IHN0cmluZywgbWludXMgdGhlIGFjY2VzcyB0b2tlbiBwYXJhbWV0ZXIuXG4gICAgICAgIGxldCBwYXJhbXMgPSB1cmxPYmplY3QucGFyYW1zO1xuICAgICAgICBpZiAocmVtb3ZlQWNjZXNzVG9rZW4pIHtcbiAgICAgICAgICAgIHBhcmFtcyA9IHBhcmFtcy5maWx0ZXIocCA9PiAhcC5tYXRjaCgvXmFjY2Vzc190b2tlbj0vKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBhcmFtcy5sZW5ndGgpIHJlc3VsdCArPSBgPyR7cGFyYW1zLmpvaW4oJyYnKX1gO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIGNhbm9uaWNhbGl6ZVRpbGVzZXQodGlsZUpTT046IFRpbGVKU09OLCBzb3VyY2VVUkw/OiBzdHJpbmcpOiBBcnJheTxzdHJpbmc+IHtcbiAgICAgICAgY29uc3QgcmVtb3ZlQWNjZXNzVG9rZW4gPSBzb3VyY2VVUkwgPyBpc01hcGJveFVSTChzb3VyY2VVUkwpIDogZmFsc2U7XG4gICAgICAgIGNvbnN0IGNhbm9uaWNhbCA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IHVybCBvZiB0aWxlSlNPTi50aWxlcyB8fCBbXSkge1xuICAgICAgICAgICAgaWYgKGlzTWFwYm94SFRUUFVSTCh1cmwpKSB7XG4gICAgICAgICAgICAgICAgY2Fub25pY2FsLnB1c2godGhpcy5jYW5vbmljYWxpemVUaWxlVVJMKHVybCwgcmVtb3ZlQWNjZXNzVG9rZW4pKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY2Fub25pY2FsLnB1c2godXJsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2Fub25pY2FsO1xuICAgIH1cblxuICAgIF9tYWtlQVBJVVJMKHVybE9iamVjdDogVXJsT2JqZWN0LCBhY2Nlc3NUb2tlbjogc3RyaW5nIHwgbnVsbCB8IHZvaWQpOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBoZWxwID0gJ1NlZSBodHRwczovL2RvY3MubWFwYm94LmNvbS9hcGkvb3ZlcnZpZXcvI2FjY2Vzcy10b2tlbnMtYW5kLXRva2VuLXNjb3Blcyc7XG4gICAgICAgIGNvbnN0IGFwaVVybE9iamVjdCA9IHBhcnNlVXJsKGNvbmZpZy5BUElfVVJMKTtcbiAgICAgICAgdXJsT2JqZWN0LnByb3RvY29sID0gYXBpVXJsT2JqZWN0LnByb3RvY29sO1xuICAgICAgICB1cmxPYmplY3QuYXV0aG9yaXR5ID0gYXBpVXJsT2JqZWN0LmF1dGhvcml0eTtcblxuICAgICAgICBpZiAodXJsT2JqZWN0LnByb3RvY29sID09PSAnaHR0cCcpIHtcbiAgICAgICAgICAgIGNvbnN0IGkgPSB1cmxPYmplY3QucGFyYW1zLmluZGV4T2YoJ3NlY3VyZScpO1xuICAgICAgICAgICAgaWYgKGkgPj0gMCkgdXJsT2JqZWN0LnBhcmFtcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYXBpVXJsT2JqZWN0LnBhdGggIT09ICcvJykge1xuICAgICAgICAgICAgdXJsT2JqZWN0LnBhdGggPSBgJHthcGlVcmxPYmplY3QucGF0aH0ke3VybE9iamVjdC5wYXRofWA7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWNvbmZpZy5SRVFVSVJFX0FDQ0VTU19UT0tFTikgcmV0dXJuIGZvcm1hdFVybCh1cmxPYmplY3QpO1xuXG4gICAgICAgIGFjY2Vzc1Rva2VuID0gYWNjZXNzVG9rZW4gfHwgY29uZmlnLkFDQ0VTU19UT0tFTjtcbiAgICAgICAgaWYgKCF0aGlzLl9zaWxlbmNlQXV0aEVycm9ycykge1xuICAgICAgICAgICAgaWYgKCFhY2Nlc3NUb2tlbilcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEFuIEFQSSBhY2Nlc3MgdG9rZW4gaXMgcmVxdWlyZWQgdG8gdXNlIE1hcGJveCBHTC4gJHtoZWxwfWApO1xuICAgICAgICAgICAgaWYgKGFjY2Vzc1Rva2VuWzBdID09PSAncycpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVc2UgYSBwdWJsaWMgYWNjZXNzIHRva2VuIChway4qKSB3aXRoIE1hcGJveCBHTCwgbm90IGEgc2VjcmV0IGFjY2VzcyB0b2tlbiAoc2suKikuICR7aGVscH1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHVybE9iamVjdC5wYXJhbXMgPSB1cmxPYmplY3QucGFyYW1zLmZpbHRlcigoZCkgPT4gZC5pbmRleE9mKCdhY2Nlc3NfdG9rZW4nKSA9PT0gLTEpO1xuICAgICAgICB1cmxPYmplY3QucGFyYW1zLnB1c2goYGFjY2Vzc190b2tlbj0ke2FjY2Vzc1Rva2VuIHx8ICcnfWApO1xuICAgICAgICByZXR1cm4gZm9ybWF0VXJsKHVybE9iamVjdCk7XG4gICAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNNYXBib3hVUkwodXJsOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdXJsLmluZGV4T2YoJ21hcGJveDonKSA9PT0gMDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzTWFwYm94SFRUUFVSTCh1cmw6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBjb25maWcuQVBJX1VSTF9SRUdFWC50ZXN0KHVybCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc01hcGJveEhUVFBDRE5VUkwodXJsOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gY29uZmlnLkFQSV9DRE5fVVJMX1JFR0VYLnRlc3QodXJsKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzTWFwYm94SFRUUFN0eWxlVVJMKHVybDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGNvbmZpZy5BUElfU1RZTEVfUkVHRVgudGVzdCh1cmwpICYmICFpc01hcGJveEhUVFBTcHJpdGVVUkwodXJsKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzTWFwYm94SFRUUFRpbGVKU09OVVJMKHVybDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGNvbmZpZy5BUElfVElMRUpTT05fUkVHRVgudGVzdCh1cmwpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNNYXBib3hIVFRQU3ByaXRlVVJMKHVybDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGNvbmZpZy5BUElfU1BSSVRFX1JFR0VYLnRlc3QodXJsKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzTWFwYm94SFRUUEZvbnRzVVJMKHVybDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGNvbmZpZy5BUElfRk9OVFNfUkVHRVgudGVzdCh1cmwpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGFzQ2FjaGVEZWZlYXRpbmdTa3UodXJsOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdXJsLmluZGV4T2YoJ3NrdT0nKSA+IDAgJiYgaXNNYXBib3hIVFRQVVJMKHVybCk7XG59XG5cbmZ1bmN0aW9uIGdldEFjY2Vzc1Rva2VuKHBhcmFtczogQXJyYXk8c3RyaW5nPik6IHN0cmluZyB8IG51bGwge1xuICAgIGZvciAoY29uc3QgcGFyYW0gb2YgcGFyYW1zKSB7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gcGFyYW0ubWF0Y2goL15hY2Nlc3NfdG9rZW49KC4qKSQvKTtcbiAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgICByZXR1cm4gbWF0Y2hbMV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5cbmNvbnN0IHVybFJlID0gL14oXFx3Kyk6XFwvXFwvKFteLz9dKikoXFwvW14/XSspP1xcPz8oLispPy87XG5cbmZ1bmN0aW9uIHBhcnNlVXJsKHVybDogc3RyaW5nKTogVXJsT2JqZWN0IHtcbiAgICBjb25zdCBwYXJ0cyA9IHVybC5tYXRjaCh1cmxSZSk7XG4gICAgaWYgKCFwYXJ0cykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBwYXJzZSBVUkwgb2JqZWN0Jyk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHByb3RvY29sOiBwYXJ0c1sxXSxcbiAgICAgICAgYXV0aG9yaXR5OiBwYXJ0c1syXSxcbiAgICAgICAgcGF0aDogcGFydHNbM10gfHwgJy8nLFxuICAgICAgICBwYXJhbXM6IHBhcnRzWzRdID8gcGFydHNbNF0uc3BsaXQoJyYnKSA6IFtdXG4gICAgfTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0VXJsKG9iajogVXJsT2JqZWN0KTogc3RyaW5nIHtcbiAgICBjb25zdCBwYXJhbXMgPSBvYmoucGFyYW1zLmxlbmd0aCA/IGA/JHtvYmoucGFyYW1zLmpvaW4oJyYnKX1gIDogJyc7XG4gICAgcmV0dXJuIGAke29iai5wcm90b2NvbH06Ly8ke29iai5hdXRob3JpdHl9JHtvYmoucGF0aH0ke3BhcmFtc31gO1xufVxuXG5jb25zdCB0ZWxlbUV2ZW50S2V5ID0gJ21hcGJveC5ldmVudERhdGEnO1xuXG5mdW5jdGlvbiBwYXJzZUFjY2Vzc1Rva2VuKGFjY2Vzc1Rva2VuOiA/c3RyaW5nKSB7XG4gICAgaWYgKCFhY2Nlc3NUb2tlbikge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBwYXJ0cyA9IGFjY2Vzc1Rva2VuLnNwbGl0KCcuJyk7XG4gICAgaWYgKCFwYXJ0cyB8fCBwYXJ0cy5sZW5ndGggIT09IDMpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3QganNvbkRhdGEgPSBKU09OLnBhcnNlKGI2NERlY29kZVVuaWNvZGUocGFydHNbMV0pKTtcbiAgICAgICAgcmV0dXJuIGpzb25EYXRhO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxufVxuXG50eXBlIFRlbGVtZXRyeUV2ZW50VHlwZSA9ICdhcHBVc2VyVHVybnN0aWxlJyB8ICdtYXAubG9hZCcgfCAnbWFwLmF1dGgnIHwgJ2dsanMucGVyZm9ybWFuY2UnO1xuXG5jbGFzcyBUZWxlbWV0cnlFdmVudCB7XG4gICAgZXZlbnREYXRhOiBhbnk7XG4gICAgYW5vbklkOiA/c3RyaW5nO1xuICAgIHF1ZXVlOiBBcnJheTxhbnk+O1xuICAgIHR5cGU6IFRlbGVtZXRyeUV2ZW50VHlwZTtcbiAgICBwZW5kaW5nUmVxdWVzdDogP0NhbmNlbGFibGU7XG4gICAgX2N1c3RvbUFjY2Vzc1Rva2VuOiA/c3RyaW5nO1xuXG4gICAgY29uc3RydWN0b3IodHlwZTogVGVsZW1ldHJ5RXZlbnRUeXBlKSB7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuYW5vbklkID0gbnVsbDtcbiAgICAgICAgdGhpcy5ldmVudERhdGEgPSB7fTtcbiAgICAgICAgdGhpcy5xdWV1ZSA9IFtdO1xuICAgICAgICB0aGlzLnBlbmRpbmdSZXF1ZXN0ID0gbnVsbDtcbiAgICB9XG5cbiAgICBnZXRTdG9yYWdlS2V5KGRvbWFpbjogP3N0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIGNvbnN0IHRva2VuRGF0YSA9IHBhcnNlQWNjZXNzVG9rZW4oY29uZmlnLkFDQ0VTU19UT0tFTik7XG4gICAgICAgIGxldCB1ID0gJyc7XG4gICAgICAgIGlmICh0b2tlbkRhdGEgJiYgdG9rZW5EYXRhWyd1J10pIHtcbiAgICAgICAgICAgIHUgPSBiNjRFbmNvZGVVbmljb2RlKHRva2VuRGF0YVsndSddKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHUgPSBjb25maWcuQUNDRVNTX1RPS0VOIHx8ICcnO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkb21haW4gP1xuICAgICAgICAgICAgYCR7dGVsZW1FdmVudEtleX0uJHtkb21haW59OiR7dX1gIDpcbiAgICAgICAgICAgIGAke3RlbGVtRXZlbnRLZXl9OiR7dX1gO1xuICAgIH1cblxuICAgIGZldGNoRXZlbnREYXRhKCkge1xuICAgICAgICBjb25zdCBpc0xvY2FsU3RvcmFnZUF2YWlsYWJsZSA9IHN0b3JhZ2VBdmFpbGFibGUoJ2xvY2FsU3RvcmFnZScpO1xuICAgICAgICBjb25zdCBzdG9yYWdlS2V5ID0gdGhpcy5nZXRTdG9yYWdlS2V5KCk7XG4gICAgICAgIGNvbnN0IHV1aWRLZXkgPSB0aGlzLmdldFN0b3JhZ2VLZXkoJ3V1aWQnKTtcblxuICAgICAgICBpZiAoaXNMb2NhbFN0b3JhZ2VBdmFpbGFibGUpIHtcbiAgICAgICAgICAgIC8vUmV0cmlldmUgY2FjaGVkIGRhdGFcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IHdpbmRvdy5sb2NhbFN0b3JhZ2UuZ2V0SXRlbShzdG9yYWdlS2V5KTtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmV2ZW50RGF0YSA9IEpTT04ucGFyc2UoZGF0YSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3QgdXVpZCA9IHdpbmRvdy5sb2NhbFN0b3JhZ2UuZ2V0SXRlbSh1dWlkS2V5KTtcbiAgICAgICAgICAgICAgICBpZiAodXVpZCkgdGhpcy5hbm9uSWQgPSB1dWlkO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIHdhcm5PbmNlKCdVbmFibGUgdG8gcmVhZCBmcm9tIExvY2FsU3RvcmFnZScpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2F2ZUV2ZW50RGF0YSgpIHtcbiAgICAgICAgY29uc3QgaXNMb2NhbFN0b3JhZ2VBdmFpbGFibGUgPSBzdG9yYWdlQXZhaWxhYmxlKCdsb2NhbFN0b3JhZ2UnKTtcbiAgICAgICAgY29uc3Qgc3RvcmFnZUtleSA9ICB0aGlzLmdldFN0b3JhZ2VLZXkoKTtcbiAgICAgICAgY29uc3QgdXVpZEtleSA9IHRoaXMuZ2V0U3RvcmFnZUtleSgndXVpZCcpO1xuICAgICAgICBpZiAoaXNMb2NhbFN0b3JhZ2VBdmFpbGFibGUpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgd2luZG93LmxvY2FsU3RvcmFnZS5zZXRJdGVtKHV1aWRLZXksIHRoaXMuYW5vbklkKTtcbiAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmtleXModGhpcy5ldmVudERhdGEpLmxlbmd0aCA+PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2Uuc2V0SXRlbShzdG9yYWdlS2V5LCBKU09OLnN0cmluZ2lmeSh0aGlzLmV2ZW50RGF0YSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICB3YXJuT25jZSgnVW5hYmxlIHRvIHdyaXRlIHRvIExvY2FsU3RvcmFnZScpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICB9XG5cbiAgICBwcm9jZXNzUmVxdWVzdHMoXzogP3N0cmluZykge31cblxuICAgIC8qXG4gICAgKiBJZiBhbnkgZXZlbnQgZGF0YSBzaG91bGQgYmUgcGVyc2lzdGVkIGFmdGVyIHRoZSBQT1NUIHJlcXVlc3QsIHRoZSBjYWxsYmFjayBzaG91bGQgbW9kaWZ5IGV2ZW50RGF0YWBcbiAgICAqIHRvIHRoZSB2YWx1ZXMgdGhhdCBzaG91bGQgYmUgc2F2ZWQuIEZvciB0aGlzIHJlYXNvbiwgdGhlIGNhbGxiYWNrIHNob3VsZCBiZSBpbnZva2VkIHByaW9yIHRvIHRoZSBjYWxsXG4gICAgKiB0byBUZWxlbWV0cnlFdmVudCNzYXZlRGF0YVxuICAgICovXG4gICAgcG9zdEV2ZW50KHRpbWVzdGFtcDogbnVtYmVyLCBhZGRpdGlvbmFsUGF5bG9hZDoge1tfOiBzdHJpbmddOiBhbnl9LCBjYWxsYmFjazogRXZlbnRDYWxsYmFjaywgY3VzdG9tQWNjZXNzVG9rZW4/OiA/c3RyaW5nKSB7XG4gICAgICAgIGlmICghY29uZmlnLkVWRU5UU19VUkwpIHJldHVybjtcbiAgICAgICAgY29uc3QgZXZlbnRzVXJsT2JqZWN0OiBVcmxPYmplY3QgPSBwYXJzZVVybChjb25maWcuRVZFTlRTX1VSTCk7XG4gICAgICAgIGV2ZW50c1VybE9iamVjdC5wYXJhbXMucHVzaChgYWNjZXNzX3Rva2VuPSR7Y3VzdG9tQWNjZXNzVG9rZW4gfHwgY29uZmlnLkFDQ0VTU19UT0tFTiB8fCAnJ31gKTtcblxuICAgICAgICBjb25zdCBwYXlsb2FkOiBPYmplY3QgPSB7XG4gICAgICAgICAgICBldmVudDogdGhpcy50eXBlLFxuICAgICAgICAgICAgY3JlYXRlZDogbmV3IERhdGUodGltZXN0YW1wKS50b0lTT1N0cmluZygpXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgZmluYWxQYXlsb2FkID0gYWRkaXRpb25hbFBheWxvYWQgPyBleHRlbmQocGF5bG9hZCwgYWRkaXRpb25hbFBheWxvYWQpIDogcGF5bG9hZDtcbiAgICAgICAgY29uc3QgcmVxdWVzdDogUmVxdWVzdFBhcmFtZXRlcnMgPSB7XG4gICAgICAgICAgICB1cmw6IGZvcm1hdFVybChldmVudHNVcmxPYmplY3QpLFxuICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAndGV4dC9wbGFpbicgLy9Ta2lwIHRoZSBwcmUtZmxpZ2h0IE9QVElPTlMgcmVxdWVzdFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KFtmaW5hbFBheWxvYWRdKVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMucGVuZGluZ1JlcXVlc3QgPSBwb3N0RGF0YShyZXF1ZXN0LCAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgIHRoaXMucGVuZGluZ1JlcXVlc3QgPSBudWxsO1xuICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IpO1xuICAgICAgICAgICAgdGhpcy5zYXZlRXZlbnREYXRhKCk7XG4gICAgICAgICAgICB0aGlzLnByb2Nlc3NSZXF1ZXN0cyhjdXN0b21BY2Nlc3NUb2tlbik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHF1ZXVlUmVxdWVzdChldmVudDogYW55LCBjdXN0b21BY2Nlc3NUb2tlbj86ID9zdHJpbmcpIHtcbiAgICAgICAgdGhpcy5xdWV1ZS5wdXNoKGV2ZW50KTtcbiAgICAgICAgdGhpcy5wcm9jZXNzUmVxdWVzdHMoY3VzdG9tQWNjZXNzVG9rZW4pO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFBlcmZvcm1hbmNlRXZlbnQgZXh0ZW5kcyBUZWxlbWV0cnlFdmVudCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCdnbGpzLnBlcmZvcm1hbmNlJyk7XG4gICAgfVxuXG4gICAgcG9zdFBlcmZvcm1hbmNlRXZlbnQoY3VzdG9tQWNjZXNzVG9rZW46ID9zdHJpbmcsIHBlcmZvcm1hbmNlRGF0YTogTGl2ZVBlcmZvcm1hbmNlRGF0YSkge1xuICAgICAgICBpZiAoY29uZmlnLkVWRU5UU19VUkwpIHtcbiAgICAgICAgICAgIGlmIChjdXN0b21BY2Nlc3NUb2tlbiB8fCBjb25maWcuQUNDRVNTX1RPS0VOKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5xdWV1ZVJlcXVlc3Qoe3RpbWVzdGFtcDogRGF0ZS5ub3coKSwgcGVyZm9ybWFuY2VEYXRhfSwgY3VzdG9tQWNjZXNzVG9rZW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJvY2Vzc1JlcXVlc3RzKGN1c3RvbUFjY2Vzc1Rva2VuPzogP3N0cmluZykge1xuICAgICAgICBpZiAodGhpcy5wZW5kaW5nUmVxdWVzdCB8fCB0aGlzLnF1ZXVlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qge3RpbWVzdGFtcCwgcGVyZm9ybWFuY2VEYXRhfSA9IHRoaXMucXVldWUuc2hpZnQoKTtcblxuICAgICAgICBjb25zdCBhZGRpdGlvbmFsUGF5bG9hZCA9IGdldExpdmVQZXJmb3JtYW5jZU1ldHJpY3MocGVyZm9ybWFuY2VEYXRhKTtcblxuICAgICAgICAvLyBTZXJ2ZXIgd2lsbCBvbmx5IHByb2Nlc3Mgc3RyaW5nIGZvciB0aGVzZSBlbnRyaWVzXG4gICAgICAgIGZvciAoY29uc3QgbWV0YWRhdGEgb2YgYWRkaXRpb25hbFBheWxvYWQubWV0YWRhdGEpIHtcbiAgICAgICAgICAgIGFzc2VydCh0eXBlb2YgbWV0YWRhdGEudmFsdWUgPT09ICdzdHJpbmcnKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGNvbnN0IGNvdW50ZXIgb2YgYWRkaXRpb25hbFBheWxvYWQuY291bnRlcnMpIHtcbiAgICAgICAgICAgIGFzc2VydCh0eXBlb2YgY291bnRlci52YWx1ZSA9PT0gJ3N0cmluZycpO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgYXR0cmlidXRlIG9mIGFkZGl0aW9uYWxQYXlsb2FkLmF0dHJpYnV0ZXMpIHtcbiAgICAgICAgICAgIGFzc2VydCh0eXBlb2YgYXR0cmlidXRlLnZhbHVlID09PSAnc3RyaW5nJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnBvc3RFdmVudCh0aW1lc3RhbXAsIGFkZGl0aW9uYWxQYXlsb2FkLCAoKSA9PiB7fSwgY3VzdG9tQWNjZXNzVG9rZW4pO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIE1hcExvYWRFdmVudCBleHRlbmRzIFRlbGVtZXRyeUV2ZW50IHtcbiAgICArc3VjY2Vzczoge1tfOiBudW1iZXJdOiBib29sZWFufTtcbiAgICBza3VUb2tlbjogc3RyaW5nO1xuICAgIGVycm9yQ2I6IEV2ZW50Q2FsbGJhY2s7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoJ21hcC5sb2FkJyk7XG4gICAgICAgIHRoaXMuc3VjY2VzcyA9IHt9O1xuICAgICAgICB0aGlzLnNrdVRva2VuID0gJyc7XG4gICAgfVxuXG4gICAgcG9zdE1hcExvYWRFdmVudChtYXBJZDogbnVtYmVyLCBza3VUb2tlbjogc3RyaW5nLCBjdXN0b21BY2Nlc3NUb2tlbjogP3N0cmluZywgY2FsbGJhY2s6IEV2ZW50Q2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5za3VUb2tlbiA9IHNrdVRva2VuO1xuICAgICAgICB0aGlzLmVycm9yQ2IgPSBjYWxsYmFjaztcblxuICAgICAgICBpZiAoY29uZmlnLkVWRU5UU19VUkwpIHtcbiAgICAgICAgICAgIGlmIChjdXN0b21BY2Nlc3NUb2tlbiB8fCBjb25maWcuQUNDRVNTX1RPS0VOKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5xdWV1ZVJlcXVlc3Qoe2lkOiBtYXBJZCwgdGltZXN0YW1wOiBEYXRlLm5vdygpfSwgY3VzdG9tQWNjZXNzVG9rZW4pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9yQ2IobmV3IEVycm9yKEFVVEhfRVJSX01TRykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJvY2Vzc1JlcXVlc3RzKGN1c3RvbUFjY2Vzc1Rva2VuPzogP3N0cmluZykge1xuICAgICAgICBpZiAodGhpcy5wZW5kaW5nUmVxdWVzdCB8fCB0aGlzLnF1ZXVlLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgICAgICBjb25zdCB7aWQsIHRpbWVzdGFtcH0gPSB0aGlzLnF1ZXVlLnNoaWZ0KCk7XG5cbiAgICAgICAgLy8gT25seSBvbmUgbG9hZCBldmVudCBzaG91bGQgZmlyZSBwZXIgbWFwXG4gICAgICAgIGlmIChpZCAmJiB0aGlzLnN1Y2Nlc3NbaWRdKSByZXR1cm47XG5cbiAgICAgICAgaWYgKCF0aGlzLmFub25JZCkge1xuICAgICAgICAgICAgdGhpcy5mZXRjaEV2ZW50RGF0YSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF2YWxpZGF0ZVV1aWQodGhpcy5hbm9uSWQpKSB7XG4gICAgICAgICAgICB0aGlzLmFub25JZCA9IHV1aWQoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGFkZGl0aW9uYWxQYXlsb2FkID0ge1xuICAgICAgICAgICAgc2RrSWRlbnRpZmllcjogJ21hcGJveC1nbC1qcycsXG4gICAgICAgICAgICBzZGtWZXJzaW9uLFxuICAgICAgICAgICAgc2t1SWQ6IFNLVV9JRCxcbiAgICAgICAgICAgIHNrdVRva2VuOiB0aGlzLnNrdVRva2VuLFxuICAgICAgICAgICAgdXNlcklkOiB0aGlzLmFub25JZFxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMucG9zdEV2ZW50KHRpbWVzdGFtcCwgYWRkaXRpb25hbFBheWxvYWQsIChlcnIpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9yQ2IoZXJyKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKGlkKSB0aGlzLnN1Y2Nlc3NbaWRdID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICB9LCBjdXN0b21BY2Nlc3NUb2tlbik7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgTWFwU2Vzc2lvbkFQSSBleHRlbmRzIFRlbGVtZXRyeUV2ZW50IHtcbiAgICArc3VjY2Vzczoge1tfOiBudW1iZXJdOiBib29sZWFufTtcbiAgICBza3VUb2tlbjogc3RyaW5nO1xuICAgIGVycm9yQ2I6IEV2ZW50Q2FsbGJhY2s7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoJ21hcC5hdXRoJyk7XG4gICAgICAgIHRoaXMuc3VjY2VzcyA9IHt9O1xuICAgICAgICB0aGlzLnNrdVRva2VuID0gJyc7XG4gICAgfVxuXG4gICAgZ2V0U2Vzc2lvbih0aW1lc3RhbXA6IG51bWJlciwgdG9rZW46IHN0cmluZywgY2FsbGJhY2s6IEV2ZW50Q2FsbGJhY2ssIGN1c3RvbUFjY2Vzc1Rva2VuPzogP3N0cmluZykge1xuICAgICAgICBpZiAoIWNvbmZpZy5BUElfVVJMIHx8ICFjb25maWcuU0VTU0lPTl9QQVRIKSByZXR1cm47XG4gICAgICAgIGNvbnN0IGF1dGhVcmxPYmplY3Q6IFVybE9iamVjdCA9IHBhcnNlVXJsKGNvbmZpZy5BUElfVVJMICsgY29uZmlnLlNFU1NJT05fUEFUSCk7XG4gICAgICAgIGF1dGhVcmxPYmplY3QucGFyYW1zLnB1c2goYHNrdT0ke3Rva2VuIHx8ICcnfWApO1xuICAgICAgICBhdXRoVXJsT2JqZWN0LnBhcmFtcy5wdXNoKGBhY2Nlc3NfdG9rZW49JHtjdXN0b21BY2Nlc3NUb2tlbiB8fCBjb25maWcuQUNDRVNTX1RPS0VOIHx8ICcnfWApO1xuXG4gICAgICAgIGNvbnN0IHJlcXVlc3Q6IFJlcXVlc3RQYXJhbWV0ZXJzID0ge1xuICAgICAgICAgICAgdXJsOiBmb3JtYXRVcmwoYXV0aFVybE9iamVjdCksXG4gICAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICd0ZXh0L3BsYWluJywgLy9Ta2lwIHRoZSBwcmUtZmxpZ2h0IE9QVElPTlMgcmVxdWVzdFxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMucGVuZGluZ1JlcXVlc3QgPSBnZXREYXRhKHJlcXVlc3QsIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgdGhpcy5wZW5kaW5nUmVxdWVzdCA9IG51bGw7XG4gICAgICAgICAgICBjYWxsYmFjayhlcnJvcik7XG4gICAgICAgICAgICB0aGlzLnNhdmVFdmVudERhdGEoKTtcbiAgICAgICAgICAgIHRoaXMucHJvY2Vzc1JlcXVlc3RzKGN1c3RvbUFjY2Vzc1Rva2VuKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZ2V0U2Vzc2lvbkFQSShtYXBJZDogbnVtYmVyLCBza3VUb2tlbjogc3RyaW5nLCBjdXN0b21BY2Nlc3NUb2tlbjogP3N0cmluZywgY2FsbGJhY2s6IEV2ZW50Q2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5za3VUb2tlbiA9IHNrdVRva2VuO1xuICAgICAgICB0aGlzLmVycm9yQ2IgPSBjYWxsYmFjaztcblxuICAgICAgICBpZiAoY29uZmlnLlNFU1NJT05fUEFUSCAmJiBjb25maWcuQVBJX1VSTCkge1xuICAgICAgICAgICAgaWYgKGN1c3RvbUFjY2Vzc1Rva2VuIHx8IGNvbmZpZy5BQ0NFU1NfVE9LRU4pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnF1ZXVlUmVxdWVzdCh7aWQ6IG1hcElkLCB0aW1lc3RhbXA6IERhdGUubm93KCl9LCBjdXN0b21BY2Nlc3NUb2tlbik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3JDYihuZXcgRXJyb3IoQVVUSF9FUlJfTVNHKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcm9jZXNzUmVxdWVzdHMoY3VzdG9tQWNjZXNzVG9rZW4/OiA/c3RyaW5nKSB7XG4gICAgICAgIGlmICh0aGlzLnBlbmRpbmdSZXF1ZXN0IHx8IHRoaXMucXVldWUubGVuZ3RoID09PSAwKSByZXR1cm47XG4gICAgICAgIGNvbnN0IHtpZCwgdGltZXN0YW1wfSA9IHRoaXMucXVldWUuc2hpZnQoKTtcblxuICAgICAgICAvLyBPbmx5IG9uZSBsb2FkIGV2ZW50IHNob3VsZCBmaXJlIHBlciBtYXBcbiAgICAgICAgaWYgKGlkICYmIHRoaXMuc3VjY2Vzc1tpZF0pIHJldHVybjtcblxuICAgICAgICB0aGlzLmdldFNlc3Npb24odGltZXN0YW1wLCB0aGlzLnNrdVRva2VuLCAoZXJyKSA9PiB7XG4gICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvckNiKGVycik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChpZCkgdGhpcy5zdWNjZXNzW2lkXSA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIGN1c3RvbUFjY2Vzc1Rva2VuKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBUdXJuc3RpbGVFdmVudCBleHRlbmRzIFRlbGVtZXRyeUV2ZW50IHtcbiAgICBjb25zdHJ1Y3RvcihjdXN0b21BY2Nlc3NUb2tlbj86ID9zdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoJ2FwcFVzZXJUdXJuc3RpbGUnKTtcbiAgICAgICAgdGhpcy5fY3VzdG9tQWNjZXNzVG9rZW4gPSBjdXN0b21BY2Nlc3NUb2tlbjtcbiAgICB9XG5cbiAgICBwb3N0VHVybnN0aWxlRXZlbnQodGlsZVVybHM6IEFycmF5PHN0cmluZz4sIGN1c3RvbUFjY2Vzc1Rva2VuPzogP3N0cmluZykge1xuICAgICAgICAvL0VuYWJsZWQgb25seSB3aGVuIE1hcGJveCBBY2Nlc3MgVG9rZW4gaXMgc2V0IGFuZCBhIHNvdXJjZSB1c2VzXG4gICAgICAgIC8vIG1hcGJveCB0aWxlcy5cbiAgICAgICAgaWYgKGNvbmZpZy5FVkVOVFNfVVJMICYmXG4gICAgICAgICAgICBjb25maWcuQUNDRVNTX1RPS0VOICYmXG4gICAgICAgICAgICBBcnJheS5pc0FycmF5KHRpbGVVcmxzKSAmJlxuICAgICAgICAgICAgdGlsZVVybHMuc29tZSh1cmwgPT4gaXNNYXBib3hVUkwodXJsKSB8fCBpc01hcGJveEhUVFBVUkwodXJsKSkpIHtcbiAgICAgICAgICAgIHRoaXMucXVldWVSZXF1ZXN0KERhdGUubm93KCksIGN1c3RvbUFjY2Vzc1Rva2VuKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByb2Nlc3NSZXF1ZXN0cyhjdXN0b21BY2Nlc3NUb2tlbj86ID9zdHJpbmcpIHtcbiAgICAgICAgaWYgKHRoaXMucGVuZGluZ1JlcXVlc3QgfHwgdGhpcy5xdWV1ZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5hbm9uSWQgfHwgIXRoaXMuZXZlbnREYXRhLmxhc3RTdWNjZXNzIHx8ICF0aGlzLmV2ZW50RGF0YS50b2tlblUpIHtcbiAgICAgICAgICAgIC8vUmV0cmlldmUgY2FjaGVkIGRhdGFcbiAgICAgICAgICAgIHRoaXMuZmV0Y2hFdmVudERhdGEoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRva2VuRGF0YSA9IHBhcnNlQWNjZXNzVG9rZW4oY29uZmlnLkFDQ0VTU19UT0tFTik7XG4gICAgICAgIGNvbnN0IHRva2VuVSA9IHRva2VuRGF0YSA/IHRva2VuRGF0YVsndSddIDogY29uZmlnLkFDQ0VTU19UT0tFTjtcbiAgICAgICAgLy9SZXNldCBldmVudCBkYXRhIGNhY2hlIGlmIHRoZSBhY2Nlc3MgdG9rZW4gb3duZXIgY2hhbmdlZC5cbiAgICAgICAgbGV0IGR1ZUZvckV2ZW50ID0gdG9rZW5VICE9PSB0aGlzLmV2ZW50RGF0YS50b2tlblU7XG5cbiAgICAgICAgaWYgKCF2YWxpZGF0ZVV1aWQodGhpcy5hbm9uSWQpKSB7XG4gICAgICAgICAgICB0aGlzLmFub25JZCA9IHV1aWQoKTtcbiAgICAgICAgICAgIGR1ZUZvckV2ZW50ID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG5leHRVcGRhdGUgPSB0aGlzLnF1ZXVlLnNoaWZ0KCk7XG4gICAgICAgIC8vIFJlY29yZCB0dXJuc3RpbGUgZXZlbnQgb25jZSBwZXIgY2FsZW5kYXIgZGF5LlxuICAgICAgICBpZiAodGhpcy5ldmVudERhdGEubGFzdFN1Y2Nlc3MpIHtcbiAgICAgICAgICAgIGNvbnN0IGxhc3RVcGRhdGUgPSBuZXcgRGF0ZSh0aGlzLmV2ZW50RGF0YS5sYXN0U3VjY2Vzcyk7XG4gICAgICAgICAgICBjb25zdCBuZXh0RGF0ZSA9IG5ldyBEYXRlKG5leHRVcGRhdGUpO1xuICAgICAgICAgICAgY29uc3QgZGF5c0VsYXBzZWQgPSAobmV4dFVwZGF0ZSAtIHRoaXMuZXZlbnREYXRhLmxhc3RTdWNjZXNzKSAvICgyNCAqIDYwICogNjAgKiAxMDAwKTtcbiAgICAgICAgICAgIGR1ZUZvckV2ZW50ID0gZHVlRm9yRXZlbnQgfHwgZGF5c0VsYXBzZWQgPj0gMSB8fCBkYXlzRWxhcHNlZCA8IC0xIHx8IGxhc3RVcGRhdGUuZ2V0RGF0ZSgpICE9PSBuZXh0RGF0ZS5nZXREYXRlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkdWVGb3JFdmVudCA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWR1ZUZvckV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLnByb2Nlc3NSZXF1ZXN0cygpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgYWRkaXRpb25hbFBheWxvYWQgPSB7XG4gICAgICAgICAgICBzZGtJZGVudGlmaWVyOiAnbWFwYm94LWdsLWpzJyxcbiAgICAgICAgICAgIHNka1ZlcnNpb24sXG4gICAgICAgICAgICBza3VJZDogU0tVX0lELFxuICAgICAgICAgICAgXCJlbmFibGVkLnRlbGVtZXRyeVwiOiBmYWxzZSxcbiAgICAgICAgICAgIHVzZXJJZDogdGhpcy5hbm9uSWRcbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLnBvc3RFdmVudChuZXh0VXBkYXRlLCBhZGRpdGlvbmFsUGF5bG9hZCwgKGVycikgPT4ge1xuICAgICAgICAgICAgaWYgKCFlcnIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50RGF0YS5sYXN0U3VjY2VzcyA9IG5leHRVcGRhdGU7XG4gICAgICAgICAgICAgICAgdGhpcy5ldmVudERhdGEudG9rZW5VID0gdG9rZW5VO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCBjdXN0b21BY2Nlc3NUb2tlbik7XG4gICAgfVxufVxuXG5jb25zdCB0dXJuc3RpbGVFdmVudF8gPSBuZXcgVHVybnN0aWxlRXZlbnQoKTtcbi8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbmV4cG9ydCBjb25zdCBwb3N0VHVybnN0aWxlRXZlbnQ6ICh0aWxlVXJsczogQXJyYXk8c3RyaW5nPiwgY3VzdG9tQWNjZXNzVG9rZW4/OiA/c3RyaW5nKSA9PiB2b2lkID0gdHVybnN0aWxlRXZlbnRfLnBvc3RUdXJuc3RpbGVFdmVudC5iaW5kKHR1cm5zdGlsZUV2ZW50Xyk7XG5cbmNvbnN0IG1hcExvYWRFdmVudF8gPSBuZXcgTWFwTG9hZEV2ZW50KCk7XG4vLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG5leHBvcnQgY29uc3QgcG9zdE1hcExvYWRFdmVudDogKG51bWJlciwgc3RyaW5nLCA/c3RyaW5nLCBFdmVudENhbGxiYWNrKSA9PiB2b2lkID0gbWFwTG9hZEV2ZW50Xy5wb3N0TWFwTG9hZEV2ZW50LmJpbmQobWFwTG9hZEV2ZW50Xyk7XG5cbmV4cG9ydCBjb25zdCBwZXJmb3JtYW5jZUV2ZW50XzogUGVyZm9ybWFuY2VFdmVudCA9IG5ldyBQZXJmb3JtYW5jZUV2ZW50KCk7XG4vLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG5leHBvcnQgY29uc3QgcG9zdFBlcmZvcm1hbmNlRXZlbnQ6ICg/c3RyaW5nLCBMaXZlUGVyZm9ybWFuY2VEYXRhKSA9PiB2b2lkID0gcGVyZm9ybWFuY2VFdmVudF8ucG9zdFBlcmZvcm1hbmNlRXZlbnQuYmluZChwZXJmb3JtYW5jZUV2ZW50Xyk7XG5cbmNvbnN0IG1hcFNlc3Npb25BUElfID0gbmV3IE1hcFNlc3Npb25BUEkoKTtcbi8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbmV4cG9ydCBjb25zdCBnZXRNYXBTZXNzaW9uQVBJOiAobnVtYmVyLCBzdHJpbmcsID9zdHJpbmcsIEV2ZW50Q2FsbGJhY2spID0+IHZvaWQgPSBtYXBTZXNzaW9uQVBJXy5nZXRTZXNzaW9uQVBJLmJpbmQobWFwU2Vzc2lvbkFQSV8pO1xuXG5jb25zdCBhdXRoZW50aWNhdGVkTWFwcyA9IG5ldyBTZXQoKTtcbmV4cG9ydCBmdW5jdGlvbiBzdG9yZUF1dGhTdGF0ZShnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0LCBzdGF0ZTogYm9vbGVhbikge1xuICAgIGlmIChzdGF0ZSkge1xuICAgICAgICBhdXRoZW50aWNhdGVkTWFwcy5hZGQoZ2wpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGF1dGhlbnRpY2F0ZWRNYXBzLmRlbGV0ZShnbCk7XG4gICAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNNYXBBdXRoZW50aWNhdGVkKGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gYXV0aGVudGljYXRlZE1hcHMuaGFzKGdsKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZUF1dGhTdGF0ZShnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0KSB7XG4gICAgYXV0aGVudGljYXRlZE1hcHMuZGVsZXRlKGdsKTtcbn1cblxuLyoqKioqIEVORCBXQVJOSU5HIC0gUkVNT1ZBTCBPUiBNT0RJRklDQVRJT04gT0YgVEhFXG5QUkVDRURJTkcgQ09ERSBWSU9MQVRFUyBUSEUgTUFQQk9YIFRFUk1TIE9GIFNFUlZJQ0UgICoqKioqKi9cbiIsIi8vIEBmbG93XG5cbmltcG9ydCB3aW5kb3cgZnJvbSAnLi93aW5kb3cuanMnO1xuaW1wb3J0IHt2ZXJzaW9uIGFzIHNka1ZlcnNpb259IGZyb20gJy4uLy4uL3BhY2thZ2UuanNvbic7XG5pbXBvcnQge1xuICAgIGlzTWFwYm94SFRUUFN0eWxlVVJMLFxuICAgIGlzTWFwYm94SFRUUFRpbGVKU09OVVJMLFxuICAgIGlzTWFwYm94SFRUUFNwcml0ZVVSTCxcbiAgICBpc01hcGJveEhUVFBGb250c1VSTCxcbiAgICBpc01hcGJveEhUVFBDRE5VUkxcbn0gZnJvbSAnLi9tYXBib3guanMnO1xuXG50eXBlIExpdmVQZXJmb3JtYW5jZU1ldHJpY3MgPSB7XG4gICAgY291bnRlcnM6IEFycmF5PE9iamVjdD4sXG4gICAgbWV0YWRhdGE6IEFycmF5PE9iamVjdD4sXG4gICAgYXR0cmlidXRlczogQXJyYXk8T2JqZWN0PlxufTtcblxuZXhwb3J0IHR5cGUgTGl2ZVBlcmZvcm1hbmNlRGF0YSA9IHtcbiAgICBpbnRlcmFjdGlvblJhbmdlOiBbbnVtYmVyLCBudW1iZXJdLFxuICAgIHZpc2liaWxpdHlIaWRkZW46IG51bWJlcixcbiAgICB3aWR0aDogbnVtYmVyLFxuICAgIGhlaWdodDogbnVtYmVyLFxuICAgIHRlcnJhaW5FbmFibGVkOiBib29sZWFuLFxuICAgIGZvZ0VuYWJsZWQ6IGJvb2xlYW4sXG4gICAgcHJvamVjdGlvbjogc3RyaW5nLFxuICAgIHpvb206IG51bWJlcixcbiAgICByZW5kZXJlcjogP3N0cmluZyxcbiAgICB2ZW5kb3I6ID9zdHJpbmdcbn07XG5cbmV4cG9ydCBjb25zdCBQZXJmb3JtYW5jZU1hcmtlcnMgPSB7XG4gICAgY3JlYXRlOiAnY3JlYXRlJyxcbiAgICBsb2FkOiAnbG9hZCcsXG4gICAgZnVsbExvYWQ6ICdmdWxsTG9hZCdcbn07XG5cbmV4cG9ydCBjb25zdCBMaXZlUGVyZm9ybWFuY2VVdGlscyA9IHtcbiAgICBtYXJrKG1hcmtlcjogJEtleXM8dHlwZW9mIFBlcmZvcm1hbmNlTWFya2Vycz4pIHtcbiAgICAgICAgd2luZG93LnBlcmZvcm1hbmNlLm1hcmsobWFya2VyKTtcbiAgICB9LFxuICAgIG1lYXN1cmUobmFtZTogc3RyaW5nLCBiZWdpbj86IHN0cmluZywgZW5kPzogc3RyaW5nKSB7XG4gICAgICAgIHdpbmRvdy5wZXJmb3JtYW5jZS5tZWFzdXJlKG5hbWUsIGJlZ2luLCBlbmQpO1xuICAgIH1cbn07XG5cbmZ1bmN0aW9uIGNhdGVnb3JpemUoYXJyOiBBcnJheTxQZXJmb3JtYW5jZVJlc291cmNlVGltaW5nPiwgZm46IChlbnRyeTogUGVyZm9ybWFuY2VSZXNvdXJjZVRpbWluZykgPT4gc3RyaW5nKToge1tzdHJpbmddOiBBcnJheTxQZXJmb3JtYW5jZVJlc291cmNlVGltaW5nPn0ge1xuICAgIGNvbnN0IG9iaiA9IHt9O1xuICAgIGlmIChhcnIpIHtcbiAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGFycikge1xuICAgICAgICAgICAgY29uc3QgY2F0ZWdvcnkgPSBmbihpdGVtKTtcbiAgICAgICAgICAgIGlmIChvYmpbY2F0ZWdvcnldID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBvYmpbY2F0ZWdvcnldID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBvYmpbY2F0ZWdvcnldLnB1c2goaXRlbSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG9iajtcbn1cblxuZnVuY3Rpb24gZ2V0Q291bnRlcnNQZXJSZXNvdXJjZVR5cGUocmVzb3VyY2VUaW1lcnM6IHsgW3N0cmluZ106IEFycmF5PFBlcmZvcm1hbmNlUmVzb3VyY2VUaW1pbmc+IH0pIHtcbiAgICBjb25zdCBvYmogPSB7fTtcbiAgICBpZiAocmVzb3VyY2VUaW1lcnMpIHtcbiAgICAgICAgZm9yIChjb25zdCBjYXRlZ29yeSBpbiByZXNvdXJjZVRpbWVycykge1xuICAgICAgICAgICAgaWYgKGNhdGVnb3J5ICE9PSAnb3RoZXInKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCB0aW1lciBvZiByZXNvdXJjZVRpbWVyc1tjYXRlZ29yeV0pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbWluID0gYCR7Y2F0ZWdvcnl9UmVzb2x2ZVJhbmdlTWluYDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF4ID0gYCR7Y2F0ZWdvcnl9UmVzb2x2ZVJhbmdlTWF4YDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVxQ291bnQgPSBgJHtjYXRlZ29yeX1SZXF1ZXN0Q291bnRgO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXFDYWNoZWRDb3VudCA9IGAke2NhdGVnb3J5fVJlcXVlc3RDYWNoZWRDb3VudGA7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gUmVzb3VyY2UgLVRyYW5zZmVyU3RhcnQgYW5kIC1UcmFuc2ZlckVuZCByZXByZXNlbnQgdGhlIHdhbGwgdGltZVxuICAgICAgICAgICAgICAgICAgICAvLyBiZXR3ZWVuIHRoZSBzdGFydCBvZiBhIHJlcXVlc3QgdG8gd2hlbiB0aGUgZGF0YSBpcyBhdmFpbGFibGVcbiAgICAgICAgICAgICAgICAgICAgb2JqW21pbl0gPSBNYXRoLm1pbihvYmpbbWluXSB8fCArSW5maW5pdHksIHRpbWVyLnN0YXJ0VGltZSk7XG4gICAgICAgICAgICAgICAgICAgIG9ialttYXhdID0gTWF0aC5tYXgob2JqW21heF0gfHwgLUluZmluaXR5LCB0aW1lci5yZXNwb25zZUVuZCk7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5jcmVtZW50ID0gKGtleTogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAob2JqW2tleV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ialtrZXldID0gMDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICsrb2JqW2tleV07XG4gICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdHJhbnNmZXJTaXplU3VwcG9ydGVkID0gdGltZXIudHJhbnNmZXJTaXplICE9PSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0cmFuc2ZlclNpemVTdXBwb3J0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc291cmNlRmV0Y2hlZEZyb21DYWNoZSA9ICh0aW1lci50cmFuc2ZlclNpemUgPT09IDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc291cmNlRmV0Y2hlZEZyb21DYWNoZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluY3JlbWVudChyZXFDYWNoZWRDb3VudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaW5jcmVtZW50KHJlcUNvdW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG9iajtcbn1cblxuZnVuY3Rpb24gZ2V0UmVzb3VyY2VDYXRlZ29yeShlbnRyeTogUGVyZm9ybWFuY2VSZXNvdXJjZVRpbWluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgdXJsID0gZW50cnkubmFtZS5zcGxpdCgnPycpWzBdO1xuXG4gICAgaWYgKGlzTWFwYm94SFRUUENETlVSTCh1cmwpICYmIHVybC5pbmNsdWRlcygnbWFwYm94LWdsLmpzJykpIHJldHVybiAnamF2YXNjcmlwdCc7XG4gICAgaWYgKGlzTWFwYm94SFRUUENETlVSTCh1cmwpICYmIHVybC5pbmNsdWRlcygnbWFwYm94LWdsLmNzcycpKSByZXR1cm4gJ2Nzcyc7XG4gICAgaWYgKGlzTWFwYm94SFRUUEZvbnRzVVJMKHVybCkpIHJldHVybiAnZm9udFJhbmdlJztcbiAgICBpZiAoaXNNYXBib3hIVFRQU3ByaXRlVVJMKHVybCkpIHJldHVybiAnc3ByaXRlJztcbiAgICBpZiAoaXNNYXBib3hIVFRQU3R5bGVVUkwodXJsKSkgcmV0dXJuICdzdHlsZSc7XG4gICAgaWYgKGlzTWFwYm94SFRUUFRpbGVKU09OVVJMKHVybCkpIHJldHVybiAndGlsZWpzb24nO1xuXG4gICAgcmV0dXJuICdvdGhlcic7XG59XG5cbmZ1bmN0aW9uIGdldFN0eWxlKHJlc291cmNlVGltZXJzOiBBcnJheTxQZXJmb3JtYW5jZUVudHJ5Pik6ID9zdHJpbmcge1xuICAgIGlmIChyZXNvdXJjZVRpbWVycykge1xuICAgICAgICBmb3IgKGNvbnN0IHRpbWVyIG9mIHJlc291cmNlVGltZXJzKSB7XG4gICAgICAgICAgICBjb25zdCB1cmwgPSB0aW1lci5uYW1lLnNwbGl0KCc/JylbMF07XG4gICAgICAgICAgICBpZiAoaXNNYXBib3hIVFRQU3R5bGVVUkwodXJsKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHNwbGl0ID0gdXJsLnNwbGl0KCcvJykuc2xpY2UoLTIpO1xuICAgICAgICAgICAgICAgIGlmIChzcGxpdC5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBtYXBib3g6Ly9zdHlsZXMvJHtzcGxpdFswXX0vJHtzcGxpdFsxXX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldExpdmVQZXJmb3JtYW5jZU1ldHJpY3MoZGF0YTogTGl2ZVBlcmZvcm1hbmNlRGF0YSk6IExpdmVQZXJmb3JtYW5jZU1ldHJpY3Mge1xuICAgIGNvbnN0IHJlc291cmNlVGltZXJzID0gd2luZG93LnBlcmZvcm1hbmNlLmdldEVudHJpZXNCeVR5cGUoJ3Jlc291cmNlJyk7XG4gICAgY29uc3QgbWFya2VyVGltZXJzID0gd2luZG93LnBlcmZvcm1hbmNlLmdldEVudHJpZXNCeVR5cGUoJ21hcmsnKTtcbiAgICBjb25zdCByZXNvdXJjZXNCeVR5cGUgPSBjYXRlZ29yaXplKHJlc291cmNlVGltZXJzLCBnZXRSZXNvdXJjZUNhdGVnb3J5KTtcbiAgICBjb25zdCBjb3VudGVycyA9IGdldENvdW50ZXJzUGVyUmVzb3VyY2VUeXBlKHJlc291cmNlc0J5VHlwZSk7XG4gICAgY29uc3QgZGV2aWNlUGl4ZWxSYXRpbyA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuICAgIGNvbnN0IGNvbm5lY3Rpb24gPSB3aW5kb3cubmF2aWdhdG9yLmNvbm5lY3Rpb24gfHwgd2luZG93Lm5hdmlnYXRvci5tb3pDb25uZWN0aW9uIHx8IHdpbmRvdy5uYXZpZ2F0b3Iud2Via2l0Q29ubmVjdGlvbjtcbiAgICBjb25zdCBtZXRyaWNzID0ge2NvdW50ZXJzOiBbXSwgbWV0YWRhdGE6IFtdLCBhdHRyaWJ1dGVzOiBbXX07XG5cbiAgICAvLyBQbGVhc2UgcmVhZCBjYXJlZnVsbHkgYmVmb3JlIGFkZGluZyBvciBtb2RpZnlpbmcgdGhlIGZvbGxvd2luZyBtZXRyaWNzOlxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXBib3gvZ2wtanMtdGVhbS9ibG9iL21haW4vZG9jcy9saXZlX3BlcmZvcm1hbmNlX21ldHJpY3MubWRcbiAgICBjb25zdCBhZGRNZXRyaWMgPSAoYXJyOiBBcnJheTx7fCBuYW1lOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcgfH0+LCBuYW1lOiBzdHJpbmcsIHZhbHVlOiA/KG51bWJlciB8IHN0cmluZykpID0+IHtcbiAgICAgICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGFyci5wdXNoKHtuYW1lLCB2YWx1ZTogdmFsdWUudG9TdHJpbmcoKX0pO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIGZvciAoY29uc3QgY291bnRlciBpbiBjb3VudGVycykge1xuICAgICAgICBhZGRNZXRyaWMobWV0cmljcy5jb3VudGVycywgY291bnRlciwgY291bnRlcnNbY291bnRlcl0pO1xuICAgIH1cbiAgICBpZiAoZGF0YS5pbnRlcmFjdGlvblJhbmdlWzBdICE9PSArSW5maW5pdHkgJiYgZGF0YS5pbnRlcmFjdGlvblJhbmdlWzFdICE9PSAtSW5maW5pdHkpIHtcbiAgICAgICAgYWRkTWV0cmljKG1ldHJpY3MuY291bnRlcnMsIFwiaW50ZXJhY3Rpb25SYW5nZU1pblwiLCBkYXRhLmludGVyYWN0aW9uUmFuZ2VbMF0pO1xuICAgICAgICBhZGRNZXRyaWMobWV0cmljcy5jb3VudGVycywgXCJpbnRlcmFjdGlvblJhbmdlTWF4XCIsIGRhdGEuaW50ZXJhY3Rpb25SYW5nZVsxXSk7XG4gICAgfVxuICAgIGlmIChtYXJrZXJUaW1lcnMpIHtcbiAgICAgICAgZm9yIChjb25zdCBtYXJrZXIgb2YgT2JqZWN0LmtleXMoUGVyZm9ybWFuY2VNYXJrZXJzKSkge1xuICAgICAgICAgICAgY29uc3QgbWFya2VyTmFtZSA9IFBlcmZvcm1hbmNlTWFya2Vyc1ttYXJrZXJdO1xuICAgICAgICAgICAgY29uc3QgbWFya2VyVGltZXIgPSBtYXJrZXJUaW1lcnMuZmluZCgoZW50cnkpID0+IGVudHJ5Lm5hbWUgPT09IG1hcmtlck5hbWUpO1xuICAgICAgICAgICAgaWYgKG1hcmtlclRpbWVyKSB7XG4gICAgICAgICAgICAgICAgYWRkTWV0cmljKG1ldHJpY3MuY291bnRlcnMsIG1hcmtlck5hbWUsIG1hcmtlclRpbWVyLnN0YXJ0VGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgYWRkTWV0cmljKG1ldHJpY3MuY291bnRlcnMsIFwidmlzaWJpbGl0eUhpZGRlblwiLCBkYXRhLnZpc2liaWxpdHlIaWRkZW4pO1xuXG4gICAgYWRkTWV0cmljKG1ldHJpY3MuYXR0cmlidXRlcywgXCJzdHlsZVwiLCBnZXRTdHlsZShyZXNvdXJjZVRpbWVycykpO1xuICAgIGFkZE1ldHJpYyhtZXRyaWNzLmF0dHJpYnV0ZXMsIFwidGVycmFpbkVuYWJsZWRcIiwgZGF0YS50ZXJyYWluRW5hYmxlZCA/IFwidHJ1ZVwiIDogXCJmYWxzZVwiKTtcbiAgICBhZGRNZXRyaWMobWV0cmljcy5hdHRyaWJ1dGVzLCBcImZvZ0VuYWJsZWRcIiwgZGF0YS5mb2dFbmFibGVkID8gXCJ0cnVlXCIgOiBcImZhbHNlXCIpO1xuICAgIGFkZE1ldHJpYyhtZXRyaWNzLmF0dHJpYnV0ZXMsIFwicHJvamVjdGlvblwiLCBkYXRhLnByb2plY3Rpb24pO1xuICAgIGFkZE1ldHJpYyhtZXRyaWNzLmF0dHJpYnV0ZXMsIFwiem9vbVwiLCBkYXRhLnpvb20pO1xuXG4gICAgYWRkTWV0cmljKG1ldHJpY3MubWV0YWRhdGEsIFwiZGV2aWNlUGl4ZWxSYXRpb1wiLCBkZXZpY2VQaXhlbFJhdGlvKTtcbiAgICBhZGRNZXRyaWMobWV0cmljcy5tZXRhZGF0YSwgXCJjb25uZWN0aW9uRWZmZWN0aXZlVHlwZVwiLCBjb25uZWN0aW9uID8gY29ubmVjdGlvbi5lZmZlY3RpdmVUeXBlIDogdW5kZWZpbmVkKTtcbiAgICBhZGRNZXRyaWMobWV0cmljcy5tZXRhZGF0YSwgXCJuYXZpZ2F0b3JVc2VyQWdlbnRcIiwgd2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQpO1xuICAgIGFkZE1ldHJpYyhtZXRyaWNzLm1ldGFkYXRhLCBcInNjcmVlbldpZHRoXCIsIHdpbmRvdy5zY3JlZW4ud2lkdGgpO1xuICAgIGFkZE1ldHJpYyhtZXRyaWNzLm1ldGFkYXRhLCBcInNjcmVlbkhlaWdodFwiLCB3aW5kb3cuc2NyZWVuLmhlaWdodCk7XG4gICAgYWRkTWV0cmljKG1ldHJpY3MubWV0YWRhdGEsIFwid2luZG93V2lkdGhcIiwgd2luZG93LmlubmVyV2lkdGgpO1xuICAgIGFkZE1ldHJpYyhtZXRyaWNzLm1ldGFkYXRhLCBcIndpbmRvd0hlaWdodFwiLCB3aW5kb3cuaW5uZXJIZWlnaHQpO1xuICAgIGFkZE1ldHJpYyhtZXRyaWNzLm1ldGFkYXRhLCBcIm1hcFdpZHRoXCIsIGRhdGEud2lkdGggLyBkZXZpY2VQaXhlbFJhdGlvKTtcbiAgICBhZGRNZXRyaWMobWV0cmljcy5tZXRhZGF0YSwgXCJtYXBIZWlnaHRcIiwgZGF0YS5oZWlnaHQgLyBkZXZpY2VQaXhlbFJhdGlvKTtcbiAgICBhZGRNZXRyaWMobWV0cmljcy5tZXRhZGF0YSwgXCJ3ZWJnbFJlbmRlcmVyXCIsIGRhdGEucmVuZGVyZXIpO1xuICAgIGFkZE1ldHJpYyhtZXRyaWNzLm1ldGFkYXRhLCBcIndlYmdsVmVuZG9yXCIsIGRhdGEudmVuZG9yKTtcbiAgICBhZGRNZXRyaWMobWV0cmljcy5tZXRhZGF0YSwgXCJzZGtWZXJzaW9uXCIsIHNka1ZlcnNpb24pO1xuICAgIGFkZE1ldHJpYyhtZXRyaWNzLm1ldGFkYXRhLCBcInNka0lkZW50aWZpZXJcIiwgXCJtYXBib3gtZ2wtanNcIik7XG5cbiAgICByZXR1cm4gbWV0cmljcztcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCB3aW5kb3cgZnJvbSAnLi4vdXRpbC93aW5kb3cuanMnO1xuaW1wb3J0IHtcbiAgICBQZXJmb3JtYW5jZU1hcmtlcnMsXG4gICAgTGl2ZVBlcmZvcm1hbmNlVXRpbHNcbn0gZnJvbSAnLi4vdXRpbC9saXZlX3BlcmZvcm1hbmNlLmpzJztcbmNvbnN0IHBlcmZvcm1hbmNlID0gd2luZG93LnBlcmZvcm1hbmNlO1xuXG5wZXJmb3JtYW5jZS5tYXJrKCdsaWJyYXJ5LWV2YWx1YXRlJyk7XG5cbmltcG9ydCB7aXNXb3JrZXJ9IGZyb20gJy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQgdHlwZSB7UmVxdWVzdFBhcmFtZXRlcnN9IGZyb20gJy4uL3V0aWwvYWpheC5qcyc7XG5cbmV4cG9ydCB0eXBlIFBlcmZvcm1hbmNlTWV0cmljcyA9IHtcbiAgICBsb2FkVGltZTogbnVtYmVyLFxuICAgIGZ1bGxMb2FkVGltZTogbnVtYmVyLFxuICAgIHBlcmNlbnREcm9wcGVkRnJhbWVzOiBudW1iZXIsXG4gICAgcGFyc2VUaWxlOiBudW1iZXIsXG4gICAgcGFyc2VUaWxlMTogbnVtYmVyLFxuICAgIHBhcnNlVGlsZTI6IG51bWJlcixcbiAgICB3b3JrZXJUYXNrOiBudW1iZXIsXG4gICAgd29ya2VySW5pdGlhbGl6YXRpb246IG51bWJlcixcbiAgICB3b3JrZXJFdmFsdWF0ZVNjcmlwdDogbnVtYmVyLFxuICAgIHdvcmtlcklkbGU6IG51bWJlcixcbiAgICB3b3JrZXJJZGxlUGVyY2VudDogbnVtYmVyLFxuICAgIHBsYWNlbWVudFRpbWU6IG51bWJlcixcbiAgICB0aW1lbGluZXM6IEFycmF5PE9iamVjdD5cbn07XG5cbmV4cG9ydCB0eXBlIFBlcmZvcm1hbmNlTWFyayA9IHttYXJrOiBzdHJpbmcsIG5hbWU6IHN0cmluZ307XG5cbmxldCBmdWxsTG9hZEZpbmlzaGVkID0gZmFsc2U7XG5sZXQgcGxhY2VtZW50VGltZSA9IDA7XG5cbmV4cG9ydCBjb25zdCBQZXJmb3JtYW5jZVV0aWxzID0ge1xuICAgIG1hcmsobWFya2VyOiAkS2V5czx0eXBlb2YgUGVyZm9ybWFuY2VNYXJrZXJzPikge1xuICAgICAgICBMaXZlUGVyZm9ybWFuY2VVdGlscy5tYXJrKG1hcmtlcik7XG5cbiAgICAgICAgaWYgKG1hcmtlciA9PT0gUGVyZm9ybWFuY2VNYXJrZXJzLmZ1bGxMb2FkKSB7XG4gICAgICAgICAgICBmdWxsTG9hZEZpbmlzaGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgbWVhc3VyZShuYW1lOiBzdHJpbmcsIGJlZ2luPzogc3RyaW5nLCBlbmQ/OiBzdHJpbmcpIHtcbiAgICAgICAgTGl2ZVBlcmZvcm1hbmNlVXRpbHMubWVhc3VyZShuYW1lLCBiZWdpbiwgZW5kKTtcbiAgICB9LFxuICAgIGJlZ2luTWVhc3VyZShuYW1lOiBzdHJpbmcpOiBQZXJmb3JtYW5jZU1hcmsge1xuICAgICAgICBjb25zdCBtYXJrID0gbmFtZTtcbiAgICAgICAgcGVyZm9ybWFuY2UubWFyayhtYXJrKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG1hcmssXG4gICAgICAgICAgICBuYW1lXG4gICAgICAgIH07XG4gICAgfSxcbiAgICBlbmRNZWFzdXJlKG06IFBlcmZvcm1hbmNlTWFyaykge1xuICAgICAgICBwZXJmb3JtYW5jZS5tZWFzdXJlKG0ubmFtZSwgbS5tYXJrKTtcbiAgICB9LFxuICAgIHJlY29yZFBsYWNlbWVudFRpbWUodGltZTogbnVtYmVyKSB7XG4gICAgICAgIC8vIElnbm9yZSBwbGFjZW1lbnRUaW1lcyBkdXJpbmcgbG9hZGluZ1xuICAgICAgICBpZiAoIWZ1bGxMb2FkRmluaXNoZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHBsYWNlbWVudFRpbWUgKz0gdGltZTtcbiAgICB9LFxuICAgIGZyYW1lKHRpbWVzdGFtcDogbnVtYmVyLCBpc1JlbmRlckZyYW1lOiBib29sZWFuKSB7XG4gICAgICAgIHBlcmZvcm1hbmNlLm1hcmsoJ2ZyYW1lJywge1xuICAgICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICAgICAgdGltZXN0YW1wLFxuICAgICAgICAgICAgICAgIGlzUmVuZGVyRnJhbWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfSxcbiAgICBjbGVhck1ldHJpY3MoKSB7XG4gICAgICAgIHBsYWNlbWVudFRpbWUgPSAwO1xuICAgICAgICBmdWxsTG9hZEZpbmlzaGVkID0gZmFsc2U7XG5cbiAgICAgICAgcGVyZm9ybWFuY2UuY2xlYXJNZWFzdXJlcygnbG9hZFRpbWUnKTtcbiAgICAgICAgcGVyZm9ybWFuY2UuY2xlYXJNZWFzdXJlcygnZnVsbExvYWRUaW1lJyk7XG5cbiAgICAgICAgZm9yIChjb25zdCBtYXJrZXIgaW4gUGVyZm9ybWFuY2VNYXJrZXJzKSB7XG4gICAgICAgICAgICBwZXJmb3JtYW5jZS5jbGVhck1hcmtzKFBlcmZvcm1hbmNlTWFya2Vyc1ttYXJrZXJdKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBnZXRQZXJmb3JtYW5jZU1ldHJpY3MoKTogUGVyZm9ybWFuY2VNZXRyaWNzIHtcbiAgICAgICAgY29uc3QgbWV0cmljcyA9IHt9O1xuXG4gICAgICAgIHBlcmZvcm1hbmNlLm1lYXN1cmUoJ2xvYWRUaW1lJywgUGVyZm9ybWFuY2VNYXJrZXJzLmNyZWF0ZSwgUGVyZm9ybWFuY2VNYXJrZXJzLmxvYWQpO1xuICAgICAgICBwZXJmb3JtYW5jZS5tZWFzdXJlKCdmdWxsTG9hZFRpbWUnLCBQZXJmb3JtYW5jZU1hcmtlcnMuY3JlYXRlLCBQZXJmb3JtYW5jZU1hcmtlcnMuZnVsbExvYWQpO1xuXG4gICAgICAgIGNvbnN0IG1lYXN1cmVzID0gcGVyZm9ybWFuY2UuZ2V0RW50cmllc0J5VHlwZSgnbWVhc3VyZScpO1xuICAgICAgICBmb3IgKGNvbnN0IG1lYXN1cmUgb2YgbWVhc3VyZXMpIHtcbiAgICAgICAgICAgIG1ldHJpY3NbbWVhc3VyZS5uYW1lXSA9IChtZXRyaWNzW21lYXN1cmUubmFtZV0gfHwgMCkgKyBtZWFzdXJlLmR1cmF0aW9uO1xuICAgICAgICB9XG5cbiAgICAgICAgbWV0cmljcy5wbGFjZW1lbnRUaW1lID0gcGxhY2VtZW50VGltZTtcblxuICAgICAgICByZXR1cm4gbWV0cmljcztcbiAgICB9LFxuXG4gICAgZ2V0V29ya2VyUGVyZm9ybWFuY2VNZXRyaWNzKCk6IHsgdGltZU9yaWdpbjogc3RyaW5nLCBlbnRyaWVzOiBBcnJheTxPYmplY3Q+LCBzY29wZTogc3RyaW5nIH0ge1xuICAgICAgICBjb25zdCBlbnRyaWVzID0gcGVyZm9ybWFuY2UuZ2V0RW50cmllcygpLm1hcChlbnRyeSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBlbnRyeS50b0pTT04oKTtcbiAgICAgICAgICAgIGlmIChlbnRyeS5kZXRhaWwpIHtcbiAgICAgICAgICAgICAgICBPYmplY3QuYXNzaWduKHJlc3VsdCwge1xuICAgICAgICAgICAgICAgICAgICBkZXRhaWw6IGVudHJ5LmRldGFpbFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzY29wZTogaXNXb3JrZXIoKSA/ICdXb3JrZXInIDogJ1dpbmRvdycsXG4gICAgICAgICAgICB0aW1lT3JpZ2luOiBwZXJmb3JtYW5jZS50aW1lT3JpZ2luLFxuICAgICAgICAgICAgZW50cmllc1xuICAgICAgICB9O1xuICAgIH1cbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQZXJmb3JtYW5jZU1lYXN1cmVtZW50KHJlcXVlc3Q6ID9SZXF1ZXN0UGFyYW1ldGVycyk6IEFycmF5PFBlcmZvcm1hbmNlRW50cnk+IHtcbiAgICBjb25zdCB1cmwgPSByZXF1ZXN0ID8gcmVxdWVzdC51cmwudG9TdHJpbmcoKSA6IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gcGVyZm9ybWFuY2UuZ2V0RW50cmllc0J5TmFtZSh1cmwpO1xufVxuXG5leHBvcnQgZGVmYXVsdCBwZXJmb3JtYW5jZTtcbiIsIi8vIEBmbG93IHN0cmljdFxuXG5pbXBvcnQgd2luZG93IGZyb20gJy4vd2luZG93LmpzJztcbmltcG9ydCB0eXBlIHtDYW5jZWxhYmxlfSBmcm9tICcuLi90eXBlcy9jYW5jZWxhYmxlLmpzJztcblxubGV0IGxpbmtFbDtcblxubGV0IHJlZHVjZWRNb3Rpb25RdWVyeTogTWVkaWFRdWVyeUxpc3Q7XG5cbmxldCBzdHViVGltZTogbnVtYmVyIHwgdm9pZDtcblxubGV0IGNhbnZhcztcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5jb25zdCBleHBvcnRlZCA9IHtcbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGVpdGhlciBwZXJmb3JtYW5jZS5ub3coKSBvciBhIHZhbHVlIHNldCBieSBzZXROb3cuXG4gICAgICogQHJldHVybnMge251bWJlcn0gVGltZSB2YWx1ZSBpbiBtaWxsaXNlY29uZHMuXG4gICAgICovXG4gICAgbm93KCk6IG51bWJlciB7XG4gICAgICAgIGlmIChzdHViVGltZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gc3R1YlRpbWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHdpbmRvdy5wZXJmb3JtYW5jZS5ub3coKTtcbiAgICB9LFxuICAgIHNldE5vdyh0aW1lOiBudW1iZXIpIHtcbiAgICAgICAgc3R1YlRpbWUgPSB0aW1lO1xuICAgIH0sXG5cbiAgICByZXN0b3JlTm93KCkge1xuICAgICAgICBzdHViVGltZSA9IHVuZGVmaW5lZDtcbiAgICB9LFxuXG4gICAgZnJhbWUoZm46IChwYWludFN0YXJ0VGltZXN0YW1wOiBudW1iZXIpID0+IHZvaWQpOiBDYW5jZWxhYmxlIHtcbiAgICAgICAgY29uc3QgZnJhbWUgPSB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKGZuKTtcbiAgICAgICAgcmV0dXJuIHtjYW5jZWw6ICgpID0+IHdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZShmcmFtZSl9O1xuICAgIH0sXG5cbiAgICBnZXRJbWFnZURhdGEoaW1nOiBDYW52YXNJbWFnZVNvdXJjZSwgcGFkZGluZz86IG51bWJlciA9IDApOiBJbWFnZURhdGEge1xuICAgICAgICBjb25zdCB7d2lkdGgsIGhlaWdodH0gPSBpbWc7XG5cbiAgICAgICAgaWYgKCFjYW52YXMpIHtcbiAgICAgICAgICAgIGNhbnZhcyA9IHdpbmRvdy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnLCB7d2lsbFJlYWRGcmVxdWVudGx5OiB0cnVlfSk7XG4gICAgICAgIGlmICghY29udGV4dCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdmYWlsZWQgdG8gY3JlYXRlIGNhbnZhcyAyZCBjb250ZXh0Jyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAod2lkdGggPiBjYW52YXMud2lkdGggfHwgaGVpZ2h0ID4gY2FudmFzLmhlaWdodCkge1xuICAgICAgICAgICAgY2FudmFzLndpZHRoID0gd2lkdGg7XG4gICAgICAgICAgICBjYW52YXMuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgICAgICB9XG5cbiAgICAgICAgY29udGV4dC5jbGVhclJlY3QoLXBhZGRpbmcsIC1wYWRkaW5nLCB3aWR0aCArIDIgKiBwYWRkaW5nLCBoZWlnaHQgKyAyICogcGFkZGluZyk7XG4gICAgICAgIGNvbnRleHQuZHJhd0ltYWdlKGltZywgMCwgMCwgd2lkdGgsIGhlaWdodCk7XG4gICAgICAgIHJldHVybiBjb250ZXh0LmdldEltYWdlRGF0YSgtcGFkZGluZywgLXBhZGRpbmcsIHdpZHRoICsgMiAqIHBhZGRpbmcsIGhlaWdodCArIDIgKiBwYWRkaW5nKTtcbiAgICB9LFxuXG4gICAgcmVzb2x2ZVVSTChwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBpZiAoIWxpbmtFbCkgbGlua0VsID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICAgICAgbGlua0VsLmhyZWYgPSBwYXRoO1xuICAgICAgICByZXR1cm4gbGlua0VsLmhyZWY7XG4gICAgfSxcblxuICAgIGdldCBkZXZpY2VQaXhlbFJhdGlvKCk6IG51bWJlciB7IHJldHVybiB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbzsgfSxcbiAgICBnZXQgcHJlZmVyc1JlZHVjZWRNb3Rpb24oKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICghd2luZG93Lm1hdGNoTWVkaWEpIHJldHVybiBmYWxzZTtcbiAgICAgICAgLy8gTGF6aWx5IGluaXRpYWxpemUgbWVkaWEgcXVlcnkuXG4gICAgICAgIGlmIChyZWR1Y2VkTW90aW9uUXVlcnkgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmVkdWNlZE1vdGlvblF1ZXJ5ID0gd2luZG93Lm1hdGNoTWVkaWEoJyhwcmVmZXJzLXJlZHVjZWQtbW90aW9uOiByZWR1Y2UpJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlZHVjZWRNb3Rpb25RdWVyeS5tYXRjaGVzO1xuICAgIH0sXG59O1xuXG5leHBvcnQgZGVmYXVsdCBleHBvcnRlZDtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCB7ZXh0ZW5kfSBmcm9tICcuL3V0aWwuanMnO1xuaW1wb3J0IHR5cGUge01hcEV2ZW50fSBmcm9tICcuLi91aS9ldmVudHMuanMnO1xuXG50eXBlIExpc3RlbmVyID0gKE9iamVjdCkgPT4gYW55O1xudHlwZSBMaXN0ZW5lcnMgPSB7W186IHN0cmluZ106IEFycmF5PExpc3RlbmVyPiB9O1xuXG5mdW5jdGlvbiBfYWRkRXZlbnRMaXN0ZW5lcih0eXBlOiBzdHJpbmcsIGxpc3RlbmVyOiBMaXN0ZW5lciwgbGlzdGVuZXJMaXN0OiBMaXN0ZW5lcnMpIHtcbiAgICBjb25zdCBsaXN0ZW5lckV4aXN0cyA9IGxpc3RlbmVyTGlzdFt0eXBlXSAmJiBsaXN0ZW5lckxpc3RbdHlwZV0uaW5kZXhPZihsaXN0ZW5lcikgIT09IC0xO1xuICAgIGlmICghbGlzdGVuZXJFeGlzdHMpIHtcbiAgICAgICAgbGlzdGVuZXJMaXN0W3R5cGVdID0gbGlzdGVuZXJMaXN0W3R5cGVdIHx8IFtdO1xuICAgICAgICBsaXN0ZW5lckxpc3RbdHlwZV0ucHVzaChsaXN0ZW5lcik7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBfcmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlOiBzdHJpbmcsIGxpc3RlbmVyOiBMaXN0ZW5lciwgbGlzdGVuZXJMaXN0OiBMaXN0ZW5lcnMpIHtcbiAgICBpZiAobGlzdGVuZXJMaXN0ICYmIGxpc3RlbmVyTGlzdFt0eXBlXSkge1xuICAgICAgICBjb25zdCBpbmRleCA9IGxpc3RlbmVyTGlzdFt0eXBlXS5pbmRleE9mKGxpc3RlbmVyKTtcbiAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgbGlzdGVuZXJMaXN0W3R5cGVdLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBFdmVudCB7XG4gICAgK3R5cGU6IHN0cmluZztcblxuICAgIGNvbnN0cnVjdG9yKHR5cGU6IHN0cmluZywgZGF0YTogT2JqZWN0ID0ge30pIHtcbiAgICAgICAgZXh0ZW5kKHRoaXMsIGRhdGEpO1xuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgIH1cbn1cblxuaW50ZXJmYWNlIEVycm9yTGlrZSB7XG4gICAgbWVzc2FnZTogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgRXJyb3JFdmVudCBleHRlbmRzIEV2ZW50IHtcbiAgICBlcnJvcjogRXJyb3JMaWtlO1xuXG4gICAgY29uc3RydWN0b3IoZXJyb3I6IEVycm9yTGlrZSwgZGF0YTogT2JqZWN0ID0ge30pIHtcbiAgICAgICAgc3VwZXIoJ2Vycm9yJywgZXh0ZW5kKHtlcnJvcn0sIGRhdGEpKTtcbiAgICB9XG59XG5cbi8qKlxuICogYEV2ZW50ZWRgIG1peGVzIG1ldGhvZHMgaW50byBvdGhlciBjbGFzc2VzIGZvciBldmVudCBjYXBhYmlsaXRpZXMuXG4gKlxuICogVW5sZXNzIHlvdSBhcmUgZGV2ZWxvcGluZyBhIHBsdWdpbiB5b3Ugd2lsbCBtb3N0IGxpa2VseSB1c2UgdGhlc2UgbWV0aG9kcyB0aHJvdWdoIGNsYXNzZXMgbGlrZSBgTWFwYCBvciBgUG9wdXBgLlxuICpcbiAqIEZvciBsaXN0cyBvZiBldmVudHMgeW91IGNhbiBsaXN0ZW4gZm9yLCBzZWUgQVBJIGRvY3VtZW50YXRpb24gZm9yIHNwZWNpZmljIGNsYXNzZXM6IFtgTWFwYF0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2FwaS9tYXAvI21hcC1ldmVudHMpLCBbYE1hcmtlcmBdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9hcGkvbWFwLyNtYXAtZXZlbnRzKSwgW2BQb3B1cGBdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9hcGkvbWFwLyNtYXAtZXZlbnRzKSwgYW5kIFtgR2VvbG9jYXRpb25Db250cm9sYF0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2FwaS9tYXAvI21hcC1ldmVudHMpLlxuICpcbiAqIEBtaXhpbiBFdmVudGVkXG4gKi9cbmV4cG9ydCBjbGFzcyBFdmVudGVkIHtcbiAgICBfbGlzdGVuZXJzOiBMaXN0ZW5lcnM7XG4gICAgX29uZVRpbWVMaXN0ZW5lcnM6IExpc3RlbmVycztcbiAgICBfZXZlbnRlZFBhcmVudDogP0V2ZW50ZWQ7XG4gICAgX2V2ZW50ZWRQYXJlbnREYXRhOiA/KE9iamVjdCB8ICgpID0+IE9iamVjdCk7XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGEgbGlzdGVuZXIgdG8gYSBzcGVjaWZpZWQgZXZlbnQgdHlwZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIFRoZSBldmVudCB0eXBlIHRvIGFkZCBhIGxpc3RlbiBmb3IuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgVGhlIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudCBpcyBmaXJlZC5cbiAgICAgKiAgIFRoZSBsaXN0ZW5lciBmdW5jdGlvbiBpcyBjYWxsZWQgd2l0aCB0aGUgZGF0YSBvYmplY3QgcGFzc2VkIHRvIGBmaXJlYCxcbiAgICAgKiAgIGV4dGVuZGVkIHdpdGggYHRhcmdldGAgYW5kIGB0eXBlYCBwcm9wZXJ0aWVzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICovXG4gICAgb24odHlwZTogTWFwRXZlbnQsIGxpc3RlbmVyOiBMaXN0ZW5lcik6IHRoaXMge1xuICAgICAgICB0aGlzLl9saXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnMgfHwge307XG4gICAgICAgIF9hZGRFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyLCB0aGlzLl9saXN0ZW5lcnMpO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYSBwcmV2aW91c2x5IHJlZ2lzdGVyZWQgZXZlbnQgbGlzdGVuZXIuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBUaGUgZXZlbnQgdHlwZSB0byByZW1vdmUgbGlzdGVuZXJzIGZvci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBUaGUgbGlzdGVuZXIgZnVuY3Rpb24gdG8gcmVtb3ZlLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICovXG4gICAgb2ZmKHR5cGU6IE1hcEV2ZW50LCBsaXN0ZW5lcjogTGlzdGVuZXIpOiB0aGlzIHtcbiAgICAgICAgX3JlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgbGlzdGVuZXIsIHRoaXMuX2xpc3RlbmVycyk7XG4gICAgICAgIF9yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyLCB0aGlzLl9vbmVUaW1lTGlzdGVuZXJzKTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGEgbGlzdGVuZXIgdGhhdCB3aWxsIGJlIGNhbGxlZCBvbmx5IG9uY2UgdG8gYSBzcGVjaWZpZWQgZXZlbnQgdHlwZS5cbiAgICAgKlxuICAgICAqIFRoZSBsaXN0ZW5lciB3aWxsIGJlIGNhbGxlZCBmaXJzdCB0aW1lIHRoZSBldmVudCBmaXJlcyBhZnRlciB0aGUgbGlzdGVuZXIgaXMgcmVnaXN0ZXJlZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIFRoZSBldmVudCB0eXBlIHRvIGxpc3RlbiBmb3IuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgKE9wdGlvbmFsKSBUaGUgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzIGZpcmVkIG9uY2UuXG4gICAgICogICBJZiBub3QgcHJvdmlkZWQsIHJldHVybnMgYSBQcm9taXNlIHRoYXQgd2lsbCBiZSByZXNvbHZlZCB3aGVuIHRoZSBldmVudCBpcyBmaXJlZCBvbmNlLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYHRoaXNgIHwgUHJvbWlzZS5cbiAgICAgKi9cbiAgICBvbmNlKHR5cGU6IE1hcEV2ZW50LCBsaXN0ZW5lcj86IExpc3RlbmVyKTogdGhpcyB8IFByb21pc2U8RXZlbnQ+IHtcbiAgICAgICAgaWYgKCFsaXN0ZW5lcikge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4gdGhpcy5vbmNlKHR5cGUsIHJlc29sdmUpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX29uZVRpbWVMaXN0ZW5lcnMgPSB0aGlzLl9vbmVUaW1lTGlzdGVuZXJzIHx8IHt9O1xuICAgICAgICBfYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lciwgdGhpcy5fb25lVGltZUxpc3RlbmVycyk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgZmlyZShldmVudDogRXZlbnQsIHByb3BlcnRpZXM/OiBPYmplY3QpOiB0aGlzIHtcbiAgICAgICAgLy8gQ29tcGF0aWJpbGl0eSB3aXRoICh0eXBlOiBzdHJpbmcsIHByb3BlcnRpZXM6IE9iamVjdCkgc2lnbmF0dXJlIGZyb20gcHJldmlvdXMgdmVyc2lvbnMuXG4gICAgICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vbWFwYm94L21hcGJveC1nbC1qcy9pc3N1ZXMvNjUyMixcbiAgICAgICAgLy8gICAgIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXBib3gvbWFwYm94LWdsLWRyYXcvaXNzdWVzLzc2NlxuICAgICAgICBpZiAodHlwZW9mIGV2ZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgZXZlbnQgPSBuZXcgRXZlbnQoZXZlbnQsIHByb3BlcnRpZXMgfHwge30pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdHlwZSA9IGV2ZW50LnR5cGU7XG5cbiAgICAgICAgaWYgKHRoaXMubGlzdGVucyh0eXBlKSkge1xuICAgICAgICAgICAgKGV2ZW50OiBhbnkpLnRhcmdldCA9IHRoaXM7XG5cbiAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSBhZGRpbmcgb3IgcmVtb3ZpbmcgbGlzdGVuZXJzIGluc2lkZSBvdGhlciBsaXN0ZW5lcnMgd29uJ3QgY2F1c2UgYW4gaW5maW5pdGUgbG9vcFxuICAgICAgICAgICAgY29uc3QgbGlzdGVuZXJzID0gdGhpcy5fbGlzdGVuZXJzICYmIHRoaXMuX2xpc3RlbmVyc1t0eXBlXSA/IHRoaXMuX2xpc3RlbmVyc1t0eXBlXS5zbGljZSgpIDogW107XG5cbiAgICAgICAgICAgIGZvciAoY29uc3QgbGlzdGVuZXIgb2YgbGlzdGVuZXJzKSB7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXIuY2FsbCh0aGlzLCBldmVudCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IG9uZVRpbWVMaXN0ZW5lcnMgPSB0aGlzLl9vbmVUaW1lTGlzdGVuZXJzICYmIHRoaXMuX29uZVRpbWVMaXN0ZW5lcnNbdHlwZV0gPyB0aGlzLl9vbmVUaW1lTGlzdGVuZXJzW3R5cGVdLnNsaWNlKCkgOiBbXTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgbGlzdGVuZXIgb2Ygb25lVGltZUxpc3RlbmVycykge1xuICAgICAgICAgICAgICAgIF9yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyLCB0aGlzLl9vbmVUaW1lTGlzdGVuZXJzKTtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lci5jYWxsKHRoaXMsIGV2ZW50KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgcGFyZW50ID0gdGhpcy5fZXZlbnRlZFBhcmVudDtcbiAgICAgICAgICAgIGlmIChwYXJlbnQpIHtcbiAgICAgICAgICAgICAgICBleHRlbmQoXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgICAgICAgICAgICB0eXBlb2YgdGhpcy5fZXZlbnRlZFBhcmVudERhdGEgPT09ICdmdW5jdGlvbicgPyB0aGlzLl9ldmVudGVkUGFyZW50RGF0YSgpIDogdGhpcy5fZXZlbnRlZFBhcmVudERhdGFcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHBhcmVudC5maXJlKGV2ZW50KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAvLyBUbyBlbnN1cmUgdGhhdCBubyBlcnJvciBldmVudHMgYXJlIGRyb3BwZWQsIHByaW50IHRoZW0gdG8gdGhlXG4gICAgICAgIC8vIGNvbnNvbGUgaWYgdGhleSBoYXZlIG5vIGxpc3RlbmVycy5cbiAgICAgICAgfSBlbHNlIGlmIChldmVudCBpbnN0YW5jZW9mIEVycm9yRXZlbnQpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXZlbnQuZXJyb3IpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgaW5zdGFuY2Ugb2YgRXZlbnRlZCBvciBhbnkgZm9yd2FyZGVkIGluc3RhbmNlcyBvZiBFdmVudGVkIGhhdmUgYSBsaXN0ZW5lciBmb3IgdGhlIHNwZWNpZmllZCB0eXBlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgVGhlIGV2ZW50IHR5cGUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZXJlIGlzIGF0IGxlYXN0IG9uZSByZWdpc3RlcmVkIGxpc3RlbmVyIGZvciBzcGVjaWZpZWQgZXZlbnQgdHlwZSwgYGZhbHNlYCBvdGhlcndpc2UuXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBsaXN0ZW5zKHR5cGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gISEoXG4gICAgICAgICAgICAodGhpcy5fbGlzdGVuZXJzICYmIHRoaXMuX2xpc3RlbmVyc1t0eXBlXSAmJiB0aGlzLl9saXN0ZW5lcnNbdHlwZV0ubGVuZ3RoID4gMCkgfHxcbiAgICAgICAgICAgICh0aGlzLl9vbmVUaW1lTGlzdGVuZXJzICYmIHRoaXMuX29uZVRpbWVMaXN0ZW5lcnNbdHlwZV0gJiYgdGhpcy5fb25lVGltZUxpc3RlbmVyc1t0eXBlXS5sZW5ndGggPiAwKSB8fFxuICAgICAgICAgICAgKHRoaXMuX2V2ZW50ZWRQYXJlbnQgJiYgdGhpcy5fZXZlbnRlZFBhcmVudC5saXN0ZW5zKHR5cGUpKVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEJ1YmJsZSBhbGwgZXZlbnRzIGZpcmVkIGJ5IHRoaXMgaW5zdGFuY2Ugb2YgRXZlbnRlZCB0byB0aGlzIHBhcmVudCBpbnN0YW5jZSBvZiBFdmVudGVkLlxuICAgICAqXG4gICAgICogQHJldHVybnMge09iamVjdH0gYHRoaXNgXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzZXRFdmVudGVkUGFyZW50KHBhcmVudDogP0V2ZW50ZWQsIGRhdGE/OiBPYmplY3QgfCAoKSA9PiBPYmplY3QpOiB0aGlzIHtcbiAgICAgICAgdGhpcy5fZXZlbnRlZFBhcmVudCA9IHBhcmVudDtcbiAgICAgICAgdGhpcy5fZXZlbnRlZFBhcmVudERhdGEgPSBkYXRhO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBzcGVjIGZyb20gJy4vdjguanNvbic7XG5cbmV4cG9ydCB0eXBlIFN0eWxlUmVmZXJlbmNlID0gdHlwZW9mIHNwZWM7XG5cbmV4cG9ydCBkZWZhdWx0IHNwZWM7XG4iLCIvLyBAZmxvd1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAob3V0cHV0OiBhbnksIC4uLmlucHV0czogQXJyYXk8YW55Pik6IGFueSB7XG4gICAgZm9yIChjb25zdCBpbnB1dCBvZiBpbnB1dHMpIHtcbiAgICAgICAgZm9yIChjb25zdCBrIGluIGlucHV0KSB7XG4gICAgICAgICAgICBvdXRwdXRba10gPSBpbnB1dFtrXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gb3V0cHV0O1xufVxuIiwiLy8gQGZsb3dcblxuLy8gVHVybiBqc29ubGludC1saW5lcy1wcmltaXRpdmVzIG9iamVjdHMgaW50byBwcmltaXRpdmUgb2JqZWN0c1xuZXhwb3J0IGZ1bmN0aW9uIHVuYnVuZGxlKHZhbHVlOiBtaXhlZCk6IG1peGVkIHtcbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBOdW1iZXIgfHwgdmFsdWUgaW5zdGFuY2VvZiBTdHJpbmcgfHwgdmFsdWUgaW5zdGFuY2VvZiBCb29sZWFuKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZS52YWx1ZU9mKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlZXBVbmJ1bmRsZSh2YWx1ZTogbWl4ZWQpOiBtaXhlZCB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZS5tYXAoZGVlcFVuYnVuZGxlKTtcbiAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgT2JqZWN0ICYmICEodmFsdWUgaW5zdGFuY2VvZiBOdW1iZXIgfHwgdmFsdWUgaW5zdGFuY2VvZiBTdHJpbmcgfHwgdmFsdWUgaW5zdGFuY2VvZiBCb29sZWFuKSkge1xuICAgICAgICBjb25zdCB1bmJ1bmRsZWRWYWx1ZTogeyBba2V5OiBzdHJpbmddOiBtaXhlZCB9ID0ge307XG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIHZhbHVlKSB7XG4gICAgICAgICAgICB1bmJ1bmRsZWRWYWx1ZVtrZXldID0gZGVlcFVuYnVuZGxlKHZhbHVlW2tleV0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1bmJ1bmRsZWRWYWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5idW5kbGUodmFsdWUpO1xufVxuIiwiLy8gQGZsb3dcblxuY2xhc3MgUGFyc2luZ0Vycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIGtleTogc3RyaW5nO1xuICAgIG1lc3NhZ2U6IHN0cmluZztcbiAgICBjb25zdHJ1Y3RvcihrZXk6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgICAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlO1xuICAgICAgICB0aGlzLmtleSA9IGtleTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFBhcnNpbmdFcnJvcjtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCB0eXBlIHtFeHByZXNzaW9ufSBmcm9tICcuL2V4cHJlc3Npb24uanMnO1xuXG4vKipcbiAqIFRyYWNrcyBgbGV0YCBiaW5kaW5ncyBkdXJpbmcgZXhwcmVzc2lvbiBwYXJzaW5nLlxuICogQHByaXZhdGVcbiAqL1xuY2xhc3MgU2NvcGUge1xuICAgIHBhcmVudDogP1Njb3BlO1xuICAgIGJpbmRpbmdzOiB7W186IHN0cmluZ106IEV4cHJlc3Npb259O1xuICAgIGNvbnN0cnVjdG9yKHBhcmVudD86IFNjb3BlLCBiaW5kaW5nczogQXJyYXk8W3N0cmluZywgRXhwcmVzc2lvbl0+ID0gW10pIHtcbiAgICAgICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7XG4gICAgICAgIHRoaXMuYmluZGluZ3MgPSB7fTtcbiAgICAgICAgZm9yIChjb25zdCBbbmFtZSwgZXhwcmVzc2lvbl0gb2YgYmluZGluZ3MpIHtcbiAgICAgICAgICAgIHRoaXMuYmluZGluZ3NbbmFtZV0gPSBleHByZXNzaW9uO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY29uY2F0KGJpbmRpbmdzOiBBcnJheTxbc3RyaW5nLCBFeHByZXNzaW9uXT4pOiBTY29wZSB7XG4gICAgICAgIHJldHVybiBuZXcgU2NvcGUodGhpcywgYmluZGluZ3MpO1xuICAgIH1cblxuICAgIGdldChuYW1lOiBzdHJpbmcpOiBFeHByZXNzaW9uIHtcbiAgICAgICAgaWYgKHRoaXMuYmluZGluZ3NbbmFtZV0pIHsgcmV0dXJuIHRoaXMuYmluZGluZ3NbbmFtZV07IH1cbiAgICAgICAgaWYgKHRoaXMucGFyZW50KSB7IHJldHVybiB0aGlzLnBhcmVudC5nZXQobmFtZSk7IH1cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke25hbWV9IG5vdCBmb3VuZCBpbiBzY29wZS5gKTtcbiAgICB9XG5cbiAgICBoYXMobmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICh0aGlzLmJpbmRpbmdzW25hbWVdKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyZW50ID8gdGhpcy5wYXJlbnQuaGFzKG5hbWUpIDogZmFsc2U7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBTY29wZTtcbiIsIi8vIEBmbG93XG5cbmV4cG9ydCB0eXBlIE51bGxUeXBlVCA9IHsga2luZDogJ251bGwnIH07XG5leHBvcnQgdHlwZSBOdW1iZXJUeXBlVCA9IHsga2luZDogJ251bWJlcicgfTtcbmV4cG9ydCB0eXBlIFN0cmluZ1R5cGVUID0geyBraW5kOiAnc3RyaW5nJyB9O1xuZXhwb3J0IHR5cGUgQm9vbGVhblR5cGVUID0geyBraW5kOiAnYm9vbGVhbicgfTtcbmV4cG9ydCB0eXBlIENvbG9yVHlwZVQgPSB7IGtpbmQ6ICdjb2xvcicgfTtcbmV4cG9ydCB0eXBlIE9iamVjdFR5cGVUID0geyBraW5kOiAnb2JqZWN0JyB9O1xuZXhwb3J0IHR5cGUgVmFsdWVUeXBlVCA9IHsga2luZDogJ3ZhbHVlJyB9O1xuZXhwb3J0IHR5cGUgRXJyb3JUeXBlVCA9IHsga2luZDogJ2Vycm9yJyB9O1xuZXhwb3J0IHR5cGUgQ29sbGF0b3JUeXBlVCA9IHsga2luZDogJ2NvbGxhdG9yJyB9O1xuZXhwb3J0IHR5cGUgRm9ybWF0dGVkVHlwZVQgPSB7IGtpbmQ6ICdmb3JtYXR0ZWQnIH07XG5leHBvcnQgdHlwZSBSZXNvbHZlZEltYWdlVHlwZVQgPSB7IGtpbmQ6ICdyZXNvbHZlZEltYWdlJyB9O1xuXG5leHBvcnQgdHlwZSBFdmFsdWF0aW9uS2luZCA9ICdjb25zdGFudCcgfCAnc291cmNlJyB8ICdjYW1lcmEnIHwgJ2NvbXBvc2l0ZSc7XG5cbmV4cG9ydCB0eXBlIFR5cGUgPVxuICAgIE51bGxUeXBlVCB8XG4gICAgTnVtYmVyVHlwZVQgfFxuICAgIFN0cmluZ1R5cGVUIHxcbiAgICBCb29sZWFuVHlwZVQgfFxuICAgIENvbG9yVHlwZVQgfFxuICAgIE9iamVjdFR5cGVUIHxcbiAgICBWYWx1ZVR5cGVUIHxcbiAgICBBcnJheVR5cGUgfCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVzZS1iZWZvcmUtZGVmaW5lXG4gICAgRXJyb3JUeXBlVCB8XG4gICAgQ29sbGF0b3JUeXBlVCB8XG4gICAgRm9ybWF0dGVkVHlwZVQgfFxuICAgIFJlc29sdmVkSW1hZ2VUeXBlVFxuXG5leHBvcnQgdHlwZSBBcnJheVR5cGUgPSB7XG4gICAga2luZDogJ2FycmF5JyxcbiAgICBpdGVtVHlwZTogVHlwZSxcbiAgICBOOiA/bnVtYmVyXG59XG5cbmV4cG9ydCB0eXBlIE5hdGl2ZVR5cGUgPSAnbnVtYmVyJyB8ICdzdHJpbmcnIHwgJ2Jvb2xlYW4nIHwgJ251bGwnIHwgJ2FycmF5JyB8ICdvYmplY3QnXG5cbmV4cG9ydCBjb25zdCBOdWxsVHlwZSA9IHtraW5kOiAnbnVsbCd9O1xuZXhwb3J0IGNvbnN0IE51bWJlclR5cGUgPSB7a2luZDogJ251bWJlcid9O1xuZXhwb3J0IGNvbnN0IFN0cmluZ1R5cGUgPSB7a2luZDogJ3N0cmluZyd9O1xuZXhwb3J0IGNvbnN0IEJvb2xlYW5UeXBlID0ge2tpbmQ6ICdib29sZWFuJ307XG5leHBvcnQgY29uc3QgQ29sb3JUeXBlID0ge2tpbmQ6ICdjb2xvcid9O1xuZXhwb3J0IGNvbnN0IE9iamVjdFR5cGUgPSB7a2luZDogJ29iamVjdCd9O1xuZXhwb3J0IGNvbnN0IFZhbHVlVHlwZSA9IHtraW5kOiAndmFsdWUnfTtcbmV4cG9ydCBjb25zdCBFcnJvclR5cGUgPSB7a2luZDogJ2Vycm9yJ307XG5leHBvcnQgY29uc3QgQ29sbGF0b3JUeXBlID0ge2tpbmQ6ICdjb2xsYXRvcid9O1xuZXhwb3J0IGNvbnN0IEZvcm1hdHRlZFR5cGUgPSB7a2luZDogJ2Zvcm1hdHRlZCd9O1xuZXhwb3J0IGNvbnN0IFJlc29sdmVkSW1hZ2VUeXBlID0ge2tpbmQ6ICdyZXNvbHZlZEltYWdlJ307XG5cbmV4cG9ydCBmdW5jdGlvbiBhcnJheShpdGVtVHlwZTogVHlwZSwgTjogP251bWJlcik6IEFycmF5VHlwZSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAga2luZDogJ2FycmF5JyxcbiAgICAgICAgaXRlbVR5cGUsXG4gICAgICAgIE5cbiAgICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdG9TdHJpbmcodHlwZTogVHlwZSk6IHN0cmluZyB7XG4gICAgaWYgKHR5cGUua2luZCA9PT0gJ2FycmF5Jykge1xuICAgICAgICBjb25zdCBpdGVtVHlwZSA9IHRvU3RyaW5nKHR5cGUuaXRlbVR5cGUpO1xuICAgICAgICByZXR1cm4gdHlwZW9mIHR5cGUuTiA9PT0gJ251bWJlcicgP1xuICAgICAgICAgICAgYGFycmF5PCR7aXRlbVR5cGV9LCAke3R5cGUuTn0+YCA6XG4gICAgICAgICAgICB0eXBlLml0ZW1UeXBlLmtpbmQgPT09ICd2YWx1ZScgPyAnYXJyYXknIDogYGFycmF5PCR7aXRlbVR5cGV9PmA7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHR5cGUua2luZDtcbiAgICB9XG59XG5cbmNvbnN0IHZhbHVlTWVtYmVyVHlwZXMgPSBbXG4gICAgTnVsbFR5cGUsXG4gICAgTnVtYmVyVHlwZSxcbiAgICBTdHJpbmdUeXBlLFxuICAgIEJvb2xlYW5UeXBlLFxuICAgIENvbG9yVHlwZSxcbiAgICBGb3JtYXR0ZWRUeXBlLFxuICAgIE9iamVjdFR5cGUsXG4gICAgYXJyYXkoVmFsdWVUeXBlKSxcbiAgICBSZXNvbHZlZEltYWdlVHlwZVxuXTtcblxuLyoqXG4gKiBSZXR1cm5zIG51bGwgaWYgYHRgIGlzIGEgc3VidHlwZSBvZiBgZXhwZWN0ZWRgOyBvdGhlcndpc2UgcmV0dXJucyBhblxuICogZXJyb3IgbWVzc2FnZS5cbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjaGVja1N1YnR5cGUoZXhwZWN0ZWQ6IFR5cGUsIHQ6IFR5cGUpOiA/c3RyaW5nIHtcbiAgICBpZiAodC5raW5kID09PSAnZXJyb3InKSB7XG4gICAgICAgIC8vIEVycm9yIGlzIGEgc3VidHlwZSBvZiBldmVyeSB0eXBlXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH0gZWxzZSBpZiAoZXhwZWN0ZWQua2luZCA9PT0gJ2FycmF5Jykge1xuICAgICAgICBpZiAodC5raW5kID09PSAnYXJyYXknICYmXG4gICAgICAgICAgICAoKHQuTiA9PT0gMCAmJiB0Lml0ZW1UeXBlLmtpbmQgPT09ICd2YWx1ZScpIHx8ICFjaGVja1N1YnR5cGUoZXhwZWN0ZWQuaXRlbVR5cGUsIHQuaXRlbVR5cGUpKSAmJlxuICAgICAgICAgICAgKHR5cGVvZiBleHBlY3RlZC5OICE9PSAnbnVtYmVyJyB8fCBleHBlY3RlZC5OID09PSB0Lk4pKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZXhwZWN0ZWQua2luZCA9PT0gdC5raW5kKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH0gZWxzZSBpZiAoZXhwZWN0ZWQua2luZCA9PT0gJ3ZhbHVlJykge1xuICAgICAgICBmb3IgKGNvbnN0IG1lbWJlclR5cGUgb2YgdmFsdWVNZW1iZXJUeXBlcykge1xuICAgICAgICAgICAgaWYgKCFjaGVja1N1YnR5cGUobWVtYmVyVHlwZSwgdCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBgRXhwZWN0ZWQgJHt0b1N0cmluZyhleHBlY3RlZCl9IGJ1dCBmb3VuZCAke3RvU3RyaW5nKHQpfSBpbnN0ZWFkLmA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkVHlwZShwcm92aWRlZDogVHlwZSwgYWxsb3dlZFR5cGVzOiBBcnJheTxUeXBlPik6IGJvb2xlYW4ge1xuICAgIHJldHVybiBhbGxvd2VkVHlwZXMuc29tZSh0ID0+IHQua2luZCA9PT0gcHJvdmlkZWQua2luZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkTmF0aXZlVHlwZShwcm92aWRlZDogYW55LCBhbGxvd2VkVHlwZXM6IEFycmF5PE5hdGl2ZVR5cGU+KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGFsbG93ZWRUeXBlcy5zb21lKHQgPT4ge1xuICAgICAgICBpZiAodCA9PT0gJ251bGwnKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvdmlkZWQgPT09IG51bGw7XG4gICAgICAgIH0gZWxzZSBpZiAodCA9PT0gJ2FycmF5Jykge1xuICAgICAgICAgICAgcmV0dXJuIEFycmF5LmlzQXJyYXkocHJvdmlkZWQpO1xuICAgICAgICB9IGVsc2UgaWYgKHQgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvdmlkZWQgJiYgIUFycmF5LmlzQXJyYXkocHJvdmlkZWQpICYmIHR5cGVvZiBwcm92aWRlZCA9PT0gJ29iamVjdCc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdCA9PT0gdHlwZW9mIHByb3ZpZGVkO1xuICAgICAgICB9XG4gICAgfSk7XG59XG4iLCIvLyAoYykgRGVhbiBNY05hbWVlIDxkZWFuQGdtYWlsLmNvbT4sIDIwMTIuXG4vL1xuLy8gaHR0cHM6Ly9naXRodWIuY29tL2RlYW5tL2Nzcy1jb2xvci1wYXJzZXItanNcbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4vLyBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0b1xuLy8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGVcbi8vIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vclxuLy8gc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lOR1xuLy8gRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HU1xuLy8gSU4gVEhFIFNPRlRXQVJFLlxuXG4vLyBodHRwOi8vd3d3LnczLm9yZy9UUi9jc3MzLWNvbG9yL1xudmFyIGtDU1NDb2xvclRhYmxlID0ge1xuICBcInRyYW5zcGFyZW50XCI6IFswLDAsMCwwXSwgXCJhbGljZWJsdWVcIjogWzI0MCwyNDgsMjU1LDFdLFxuICBcImFudGlxdWV3aGl0ZVwiOiBbMjUwLDIzNSwyMTUsMV0sIFwiYXF1YVwiOiBbMCwyNTUsMjU1LDFdLFxuICBcImFxdWFtYXJpbmVcIjogWzEyNywyNTUsMjEyLDFdLCBcImF6dXJlXCI6IFsyNDAsMjU1LDI1NSwxXSxcbiAgXCJiZWlnZVwiOiBbMjQ1LDI0NSwyMjAsMV0sIFwiYmlzcXVlXCI6IFsyNTUsMjI4LDE5NiwxXSxcbiAgXCJibGFja1wiOiBbMCwwLDAsMV0sIFwiYmxhbmNoZWRhbG1vbmRcIjogWzI1NSwyMzUsMjA1LDFdLFxuICBcImJsdWVcIjogWzAsMCwyNTUsMV0sIFwiYmx1ZXZpb2xldFwiOiBbMTM4LDQzLDIyNiwxXSxcbiAgXCJicm93blwiOiBbMTY1LDQyLDQyLDFdLCBcImJ1cmx5d29vZFwiOiBbMjIyLDE4NCwxMzUsMV0sXG4gIFwiY2FkZXRibHVlXCI6IFs5NSwxNTgsMTYwLDFdLCBcImNoYXJ0cmV1c2VcIjogWzEyNywyNTUsMCwxXSxcbiAgXCJjaG9jb2xhdGVcIjogWzIxMCwxMDUsMzAsMV0sIFwiY29yYWxcIjogWzI1NSwxMjcsODAsMV0sXG4gIFwiY29ybmZsb3dlcmJsdWVcIjogWzEwMCwxNDksMjM3LDFdLCBcImNvcm5zaWxrXCI6IFsyNTUsMjQ4LDIyMCwxXSxcbiAgXCJjcmltc29uXCI6IFsyMjAsMjAsNjAsMV0sIFwiY3lhblwiOiBbMCwyNTUsMjU1LDFdLFxuICBcImRhcmtibHVlXCI6IFswLDAsMTM5LDFdLCBcImRhcmtjeWFuXCI6IFswLDEzOSwxMzksMV0sXG4gIFwiZGFya2dvbGRlbnJvZFwiOiBbMTg0LDEzNCwxMSwxXSwgXCJkYXJrZ3JheVwiOiBbMTY5LDE2OSwxNjksMV0sXG4gIFwiZGFya2dyZWVuXCI6IFswLDEwMCwwLDFdLCBcImRhcmtncmV5XCI6IFsxNjksMTY5LDE2OSwxXSxcbiAgXCJkYXJra2hha2lcIjogWzE4OSwxODMsMTA3LDFdLCBcImRhcmttYWdlbnRhXCI6IFsxMzksMCwxMzksMV0sXG4gIFwiZGFya29saXZlZ3JlZW5cIjogWzg1LDEwNyw0NywxXSwgXCJkYXJrb3JhbmdlXCI6IFsyNTUsMTQwLDAsMV0sXG4gIFwiZGFya29yY2hpZFwiOiBbMTUzLDUwLDIwNCwxXSwgXCJkYXJrcmVkXCI6IFsxMzksMCwwLDFdLFxuICBcImRhcmtzYWxtb25cIjogWzIzMywxNTAsMTIyLDFdLCBcImRhcmtzZWFncmVlblwiOiBbMTQzLDE4OCwxNDMsMV0sXG4gIFwiZGFya3NsYXRlYmx1ZVwiOiBbNzIsNjEsMTM5LDFdLCBcImRhcmtzbGF0ZWdyYXlcIjogWzQ3LDc5LDc5LDFdLFxuICBcImRhcmtzbGF0ZWdyZXlcIjogWzQ3LDc5LDc5LDFdLCBcImRhcmt0dXJxdW9pc2VcIjogWzAsMjA2LDIwOSwxXSxcbiAgXCJkYXJrdmlvbGV0XCI6IFsxNDgsMCwyMTEsMV0sIFwiZGVlcHBpbmtcIjogWzI1NSwyMCwxNDcsMV0sXG4gIFwiZGVlcHNreWJsdWVcIjogWzAsMTkxLDI1NSwxXSwgXCJkaW1ncmF5XCI6IFsxMDUsMTA1LDEwNSwxXSxcbiAgXCJkaW1ncmV5XCI6IFsxMDUsMTA1LDEwNSwxXSwgXCJkb2RnZXJibHVlXCI6IFszMCwxNDQsMjU1LDFdLFxuICBcImZpcmVicmlja1wiOiBbMTc4LDM0LDM0LDFdLCBcImZsb3JhbHdoaXRlXCI6IFsyNTUsMjUwLDI0MCwxXSxcbiAgXCJmb3Jlc3RncmVlblwiOiBbMzQsMTM5LDM0LDFdLCBcImZ1Y2hzaWFcIjogWzI1NSwwLDI1NSwxXSxcbiAgXCJnYWluc2Jvcm9cIjogWzIyMCwyMjAsMjIwLDFdLCBcImdob3N0d2hpdGVcIjogWzI0OCwyNDgsMjU1LDFdLFxuICBcImdvbGRcIjogWzI1NSwyMTUsMCwxXSwgXCJnb2xkZW5yb2RcIjogWzIxOCwxNjUsMzIsMV0sXG4gIFwiZ3JheVwiOiBbMTI4LDEyOCwxMjgsMV0sIFwiZ3JlZW5cIjogWzAsMTI4LDAsMV0sXG4gIFwiZ3JlZW55ZWxsb3dcIjogWzE3MywyNTUsNDcsMV0sIFwiZ3JleVwiOiBbMTI4LDEyOCwxMjgsMV0sXG4gIFwiaG9uZXlkZXdcIjogWzI0MCwyNTUsMjQwLDFdLCBcImhvdHBpbmtcIjogWzI1NSwxMDUsMTgwLDFdLFxuICBcImluZGlhbnJlZFwiOiBbMjA1LDkyLDkyLDFdLCBcImluZGlnb1wiOiBbNzUsMCwxMzAsMV0sXG4gIFwiaXZvcnlcIjogWzI1NSwyNTUsMjQwLDFdLCBcImtoYWtpXCI6IFsyNDAsMjMwLDE0MCwxXSxcbiAgXCJsYXZlbmRlclwiOiBbMjMwLDIzMCwyNTAsMV0sIFwibGF2ZW5kZXJibHVzaFwiOiBbMjU1LDI0MCwyNDUsMV0sXG4gIFwibGF3bmdyZWVuXCI6IFsxMjQsMjUyLDAsMV0sIFwibGVtb25jaGlmZm9uXCI6IFsyNTUsMjUwLDIwNSwxXSxcbiAgXCJsaWdodGJsdWVcIjogWzE3MywyMTYsMjMwLDFdLCBcImxpZ2h0Y29yYWxcIjogWzI0MCwxMjgsMTI4LDFdLFxuICBcImxpZ2h0Y3lhblwiOiBbMjI0LDI1NSwyNTUsMV0sIFwibGlnaHRnb2xkZW5yb2R5ZWxsb3dcIjogWzI1MCwyNTAsMjEwLDFdLFxuICBcImxpZ2h0Z3JheVwiOiBbMjExLDIxMSwyMTEsMV0sIFwibGlnaHRncmVlblwiOiBbMTQ0LDIzOCwxNDQsMV0sXG4gIFwibGlnaHRncmV5XCI6IFsyMTEsMjExLDIxMSwxXSwgXCJsaWdodHBpbmtcIjogWzI1NSwxODIsMTkzLDFdLFxuICBcImxpZ2h0c2FsbW9uXCI6IFsyNTUsMTYwLDEyMiwxXSwgXCJsaWdodHNlYWdyZWVuXCI6IFszMiwxNzgsMTcwLDFdLFxuICBcImxpZ2h0c2t5Ymx1ZVwiOiBbMTM1LDIwNiwyNTAsMV0sIFwibGlnaHRzbGF0ZWdyYXlcIjogWzExOSwxMzYsMTUzLDFdLFxuICBcImxpZ2h0c2xhdGVncmV5XCI6IFsxMTksMTM2LDE1MywxXSwgXCJsaWdodHN0ZWVsYmx1ZVwiOiBbMTc2LDE5NiwyMjIsMV0sXG4gIFwibGlnaHR5ZWxsb3dcIjogWzI1NSwyNTUsMjI0LDFdLCBcImxpbWVcIjogWzAsMjU1LDAsMV0sXG4gIFwibGltZWdyZWVuXCI6IFs1MCwyMDUsNTAsMV0sIFwibGluZW5cIjogWzI1MCwyNDAsMjMwLDFdLFxuICBcIm1hZ2VudGFcIjogWzI1NSwwLDI1NSwxXSwgXCJtYXJvb25cIjogWzEyOCwwLDAsMV0sXG4gIFwibWVkaXVtYXF1YW1hcmluZVwiOiBbMTAyLDIwNSwxNzAsMV0sIFwibWVkaXVtYmx1ZVwiOiBbMCwwLDIwNSwxXSxcbiAgXCJtZWRpdW1vcmNoaWRcIjogWzE4Niw4NSwyMTEsMV0sIFwibWVkaXVtcHVycGxlXCI6IFsxNDcsMTEyLDIxOSwxXSxcbiAgXCJtZWRpdW1zZWFncmVlblwiOiBbNjAsMTc5LDExMywxXSwgXCJtZWRpdW1zbGF0ZWJsdWVcIjogWzEyMywxMDQsMjM4LDFdLFxuICBcIm1lZGl1bXNwcmluZ2dyZWVuXCI6IFswLDI1MCwxNTQsMV0sIFwibWVkaXVtdHVycXVvaXNlXCI6IFs3MiwyMDksMjA0LDFdLFxuICBcIm1lZGl1bXZpb2xldHJlZFwiOiBbMTk5LDIxLDEzMywxXSwgXCJtaWRuaWdodGJsdWVcIjogWzI1LDI1LDExMiwxXSxcbiAgXCJtaW50Y3JlYW1cIjogWzI0NSwyNTUsMjUwLDFdLCBcIm1pc3R5cm9zZVwiOiBbMjU1LDIyOCwyMjUsMV0sXG4gIFwibW9jY2FzaW5cIjogWzI1NSwyMjgsMTgxLDFdLCBcIm5hdmFqb3doaXRlXCI6IFsyNTUsMjIyLDE3MywxXSxcbiAgXCJuYXZ5XCI6IFswLDAsMTI4LDFdLCBcIm9sZGxhY2VcIjogWzI1MywyNDUsMjMwLDFdLFxuICBcIm9saXZlXCI6IFsxMjgsMTI4LDAsMV0sIFwib2xpdmVkcmFiXCI6IFsxMDcsMTQyLDM1LDFdLFxuICBcIm9yYW5nZVwiOiBbMjU1LDE2NSwwLDFdLCBcIm9yYW5nZXJlZFwiOiBbMjU1LDY5LDAsMV0sXG4gIFwib3JjaGlkXCI6IFsyMTgsMTEyLDIxNCwxXSwgXCJwYWxlZ29sZGVucm9kXCI6IFsyMzgsMjMyLDE3MCwxXSxcbiAgXCJwYWxlZ3JlZW5cIjogWzE1MiwyNTEsMTUyLDFdLCBcInBhbGV0dXJxdW9pc2VcIjogWzE3NSwyMzgsMjM4LDFdLFxuICBcInBhbGV2aW9sZXRyZWRcIjogWzIxOSwxMTIsMTQ3LDFdLCBcInBhcGF5YXdoaXBcIjogWzI1NSwyMzksMjEzLDFdLFxuICBcInBlYWNocHVmZlwiOiBbMjU1LDIxOCwxODUsMV0sIFwicGVydVwiOiBbMjA1LDEzMyw2MywxXSxcbiAgXCJwaW5rXCI6IFsyNTUsMTkyLDIwMywxXSwgXCJwbHVtXCI6IFsyMjEsMTYwLDIyMSwxXSxcbiAgXCJwb3dkZXJibHVlXCI6IFsxNzYsMjI0LDIzMCwxXSwgXCJwdXJwbGVcIjogWzEyOCwwLDEyOCwxXSxcbiAgXCJyZWJlY2NhcHVycGxlXCI6IFsxMDIsNTEsMTUzLDFdLFxuICBcInJlZFwiOiBbMjU1LDAsMCwxXSwgXCJyb3N5YnJvd25cIjogWzE4OCwxNDMsMTQzLDFdLFxuICBcInJveWFsYmx1ZVwiOiBbNjUsMTA1LDIyNSwxXSwgXCJzYWRkbGVicm93blwiOiBbMTM5LDY5LDE5LDFdLFxuICBcInNhbG1vblwiOiBbMjUwLDEyOCwxMTQsMV0sIFwic2FuZHlicm93blwiOiBbMjQ0LDE2NCw5NiwxXSxcbiAgXCJzZWFncmVlblwiOiBbNDYsMTM5LDg3LDFdLCBcInNlYXNoZWxsXCI6IFsyNTUsMjQ1LDIzOCwxXSxcbiAgXCJzaWVubmFcIjogWzE2MCw4Miw0NSwxXSwgXCJzaWx2ZXJcIjogWzE5MiwxOTIsMTkyLDFdLFxuICBcInNreWJsdWVcIjogWzEzNSwyMDYsMjM1LDFdLCBcInNsYXRlYmx1ZVwiOiBbMTA2LDkwLDIwNSwxXSxcbiAgXCJzbGF0ZWdyYXlcIjogWzExMiwxMjgsMTQ0LDFdLCBcInNsYXRlZ3JleVwiOiBbMTEyLDEyOCwxNDQsMV0sXG4gIFwic25vd1wiOiBbMjU1LDI1MCwyNTAsMV0sIFwic3ByaW5nZ3JlZW5cIjogWzAsMjU1LDEyNywxXSxcbiAgXCJzdGVlbGJsdWVcIjogWzcwLDEzMCwxODAsMV0sIFwidGFuXCI6IFsyMTAsMTgwLDE0MCwxXSxcbiAgXCJ0ZWFsXCI6IFswLDEyOCwxMjgsMV0sIFwidGhpc3RsZVwiOiBbMjE2LDE5MSwyMTYsMV0sXG4gIFwidG9tYXRvXCI6IFsyNTUsOTksNzEsMV0sIFwidHVycXVvaXNlXCI6IFs2NCwyMjQsMjA4LDFdLFxuICBcInZpb2xldFwiOiBbMjM4LDEzMCwyMzgsMV0sIFwid2hlYXRcIjogWzI0NSwyMjIsMTc5LDFdLFxuICBcIndoaXRlXCI6IFsyNTUsMjU1LDI1NSwxXSwgXCJ3aGl0ZXNtb2tlXCI6IFsyNDUsMjQ1LDI0NSwxXSxcbiAgXCJ5ZWxsb3dcIjogWzI1NSwyNTUsMCwxXSwgXCJ5ZWxsb3dncmVlblwiOiBbMTU0LDIwNSw1MCwxXX1cblxuZnVuY3Rpb24gY2xhbXBfY3NzX2J5dGUoaSkgeyAgLy8gQ2xhbXAgdG8gaW50ZWdlciAwIC4uIDI1NS5cbiAgaSA9IE1hdGgucm91bmQoaSk7ICAvLyBTZWVtcyB0byBiZSB3aGF0IENocm9tZSBkb2VzICh2cyB0cnVuY2F0aW9uKS5cbiAgcmV0dXJuIGkgPCAwID8gMCA6IGkgPiAyNTUgPyAyNTUgOiBpO1xufVxuXG5mdW5jdGlvbiBjbGFtcF9jc3NfZmxvYXQoZikgeyAgLy8gQ2xhbXAgdG8gZmxvYXQgMC4wIC4uIDEuMC5cbiAgcmV0dXJuIGYgPCAwID8gMCA6IGYgPiAxID8gMSA6IGY7XG59XG5cbmZ1bmN0aW9uIHBhcnNlX2Nzc19pbnQoc3RyKSB7ICAvLyBpbnQgb3IgcGVyY2VudGFnZS5cbiAgaWYgKHN0cltzdHIubGVuZ3RoIC0gMV0gPT09ICclJylcbiAgICByZXR1cm4gY2xhbXBfY3NzX2J5dGUocGFyc2VGbG9hdChzdHIpIC8gMTAwICogMjU1KTtcbiAgcmV0dXJuIGNsYW1wX2Nzc19ieXRlKHBhcnNlSW50KHN0cikpO1xufVxuXG5mdW5jdGlvbiBwYXJzZV9jc3NfZmxvYXQoc3RyKSB7ICAvLyBmbG9hdCBvciBwZXJjZW50YWdlLlxuICBpZiAoc3RyW3N0ci5sZW5ndGggLSAxXSA9PT0gJyUnKVxuICAgIHJldHVybiBjbGFtcF9jc3NfZmxvYXQocGFyc2VGbG9hdChzdHIpIC8gMTAwKTtcbiAgcmV0dXJuIGNsYW1wX2Nzc19mbG9hdChwYXJzZUZsb2F0KHN0cikpO1xufVxuXG5mdW5jdGlvbiBjc3NfaHVlX3RvX3JnYihtMSwgbTIsIGgpIHtcbiAgaWYgKGggPCAwKSBoICs9IDE7XG4gIGVsc2UgaWYgKGggPiAxKSBoIC09IDE7XG5cbiAgaWYgKGggKiA2IDwgMSkgcmV0dXJuIG0xICsgKG0yIC0gbTEpICogaCAqIDY7XG4gIGlmIChoICogMiA8IDEpIHJldHVybiBtMjtcbiAgaWYgKGggKiAzIDwgMikgcmV0dXJuIG0xICsgKG0yIC0gbTEpICogKDIvMyAtIGgpICogNjtcbiAgcmV0dXJuIG0xO1xufVxuXG5mdW5jdGlvbiBwYXJzZUNTU0NvbG9yKGNzc19zdHIpIHtcbiAgLy8gUmVtb3ZlIGFsbCB3aGl0ZXNwYWNlLCBub3QgY29tcGxpYW50LCBidXQgc2hvdWxkIGp1c3QgYmUgbW9yZSBhY2NlcHRpbmcuXG4gIHZhciBzdHIgPSBjc3Nfc3RyLnJlcGxhY2UoLyAvZywgJycpLnRvTG93ZXJDYXNlKCk7XG5cbiAgLy8gQ29sb3Iga2V5d29yZHMgKGFuZCB0cmFuc3BhcmVudCkgbG9va3VwLlxuICBpZiAoc3RyIGluIGtDU1NDb2xvclRhYmxlKSByZXR1cm4ga0NTU0NvbG9yVGFibGVbc3RyXS5zbGljZSgpOyAgLy8gZHVwLlxuXG4gIC8vICNhYmMgYW5kICNhYmMxMjMgc3ludGF4LlxuICBpZiAoc3RyWzBdID09PSAnIycpIHtcbiAgICBpZiAoc3RyLmxlbmd0aCA9PT0gNCkge1xuICAgICAgdmFyIGl2ID0gcGFyc2VJbnQoc3RyLnN1YnN0cigxKSwgMTYpOyAgLy8gVE9ETyhkZWFubSk6IFN0cmljdGVyIHBhcnNpbmcuXG4gICAgICBpZiAoIShpdiA+PSAwICYmIGl2IDw9IDB4ZmZmKSkgcmV0dXJuIG51bGw7ICAvLyBDb3ZlcnMgTmFOLlxuICAgICAgcmV0dXJuIFsoKGl2ICYgMHhmMDApID4+IDQpIHwgKChpdiAmIDB4ZjAwKSA+PiA4KSxcbiAgICAgICAgICAgICAgKGl2ICYgMHhmMCkgfCAoKGl2ICYgMHhmMCkgPj4gNCksXG4gICAgICAgICAgICAgIChpdiAmIDB4ZikgfCAoKGl2ICYgMHhmKSA8PCA0KSxcbiAgICAgICAgICAgICAgMV07XG4gICAgfSBlbHNlIGlmIChzdHIubGVuZ3RoID09PSA3KSB7XG4gICAgICB2YXIgaXYgPSBwYXJzZUludChzdHIuc3Vic3RyKDEpLCAxNik7ICAvLyBUT0RPKGRlYW5tKTogU3RyaWN0ZXIgcGFyc2luZy5cbiAgICAgIGlmICghKGl2ID49IDAgJiYgaXYgPD0gMHhmZmZmZmYpKSByZXR1cm4gbnVsbDsgIC8vIENvdmVycyBOYU4uXG4gICAgICByZXR1cm4gWyhpdiAmIDB4ZmYwMDAwKSA+PiAxNixcbiAgICAgICAgICAgICAgKGl2ICYgMHhmZjAwKSA+PiA4LFxuICAgICAgICAgICAgICBpdiAmIDB4ZmYsXG4gICAgICAgICAgICAgIDFdO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgdmFyIG9wID0gc3RyLmluZGV4T2YoJygnKSwgZXAgPSBzdHIuaW5kZXhPZignKScpO1xuICBpZiAob3AgIT09IC0xICYmIGVwICsgMSA9PT0gc3RyLmxlbmd0aCkge1xuICAgIHZhciBmbmFtZSA9IHN0ci5zdWJzdHIoMCwgb3ApO1xuICAgIHZhciBwYXJhbXMgPSBzdHIuc3Vic3RyKG9wKzEsIGVwLShvcCsxKSkuc3BsaXQoJywnKTtcbiAgICB2YXIgYWxwaGEgPSAxOyAgLy8gVG8gYWxsb3cgY2FzZSBmYWxsdGhyb3VnaC5cbiAgICBzd2l0Y2ggKGZuYW1lKSB7XG4gICAgICBjYXNlICdyZ2JhJzpcbiAgICAgICAgaWYgKHBhcmFtcy5sZW5ndGggIT09IDQpIHJldHVybiBudWxsO1xuICAgICAgICBhbHBoYSA9IHBhcnNlX2Nzc19mbG9hdChwYXJhbXMucG9wKCkpO1xuICAgICAgICAvLyBGYWxsIHRocm91Z2guXG4gICAgICBjYXNlICdyZ2InOlxuICAgICAgICBpZiAocGFyYW1zLmxlbmd0aCAhPT0gMykgcmV0dXJuIG51bGw7XG4gICAgICAgIHJldHVybiBbcGFyc2VfY3NzX2ludChwYXJhbXNbMF0pLFxuICAgICAgICAgICAgICAgIHBhcnNlX2Nzc19pbnQocGFyYW1zWzFdKSxcbiAgICAgICAgICAgICAgICBwYXJzZV9jc3NfaW50KHBhcmFtc1syXSksXG4gICAgICAgICAgICAgICAgYWxwaGFdO1xuICAgICAgY2FzZSAnaHNsYSc6XG4gICAgICAgIGlmIChwYXJhbXMubGVuZ3RoICE9PSA0KSByZXR1cm4gbnVsbDtcbiAgICAgICAgYWxwaGEgPSBwYXJzZV9jc3NfZmxvYXQocGFyYW1zLnBvcCgpKTtcbiAgICAgICAgLy8gRmFsbCB0aHJvdWdoLlxuICAgICAgY2FzZSAnaHNsJzpcbiAgICAgICAgaWYgKHBhcmFtcy5sZW5ndGggIT09IDMpIHJldHVybiBudWxsO1xuICAgICAgICB2YXIgaCA9ICgoKHBhcnNlRmxvYXQocGFyYW1zWzBdKSAlIDM2MCkgKyAzNjApICUgMzYwKSAvIDM2MDsgIC8vIDAgLi4gMVxuICAgICAgICAvLyBOT1RFKGRlYW5tKTogQWNjb3JkaW5nIHRvIHRoZSBDU1Mgc3BlYyBzL2wgc2hvdWxkIG9ubHkgYmVcbiAgICAgICAgLy8gcGVyY2VudGFnZXMsIGJ1dCB3ZSBkb24ndCBib3RoZXIgYW5kIGxldCBmbG9hdCBvciBwZXJjZW50YWdlLlxuICAgICAgICB2YXIgcyA9IHBhcnNlX2Nzc19mbG9hdChwYXJhbXNbMV0pO1xuICAgICAgICB2YXIgbCA9IHBhcnNlX2Nzc19mbG9hdChwYXJhbXNbMl0pO1xuICAgICAgICB2YXIgbTIgPSBsIDw9IDAuNSA/IGwgKiAocyArIDEpIDogbCArIHMgLSBsICogcztcbiAgICAgICAgdmFyIG0xID0gbCAqIDIgLSBtMjtcbiAgICAgICAgcmV0dXJuIFtjbGFtcF9jc3NfYnl0ZShjc3NfaHVlX3RvX3JnYihtMSwgbTIsIGgrMS8zKSAqIDI1NSksXG4gICAgICAgICAgICAgICAgY2xhbXBfY3NzX2J5dGUoY3NzX2h1ZV90b19yZ2IobTEsIG0yLCBoKSAqIDI1NSksXG4gICAgICAgICAgICAgICAgY2xhbXBfY3NzX2J5dGUoY3NzX2h1ZV90b19yZ2IobTEsIG0yLCBoLTEvMykgKiAyNTUpLFxuICAgICAgICAgICAgICAgIGFscGhhXTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG50cnkgeyBleHBvcnRzLnBhcnNlQ1NTQ29sb3IgPSBwYXJzZUNTU0NvbG9yIH0gY2F0Y2goZSkgeyB9XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge3BhcnNlQ1NTQ29sb3J9IGZyb20gJ2Nzc2NvbG9ycGFyc2VyJztcblxuLyoqXG4gKiBBbiBSR0JBIGNvbG9yIHZhbHVlLiBDcmVhdGUgaW5zdGFuY2VzIGZyb20gY29sb3Igc3RyaW5ncyB1c2luZyB0aGUgc3RhdGljXG4gKiBtZXRob2QgYENvbG9yLnBhcnNlYC4gVGhlIGNvbnN0cnVjdG9yIGFjY2VwdHMgUkdCIGNoYW5uZWwgdmFsdWVzIGluIHRoZSByYW5nZVxuICogYFswLCAxXWAsIHByZW11bHRpcGxpZWQgYnkgQS5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gciBUaGUgcmVkIGNoYW5uZWwuXG4gKiBAcGFyYW0ge251bWJlcn0gZyBUaGUgZ3JlZW4gY2hhbm5lbC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiIFRoZSBibHVlIGNoYW5uZWwuXG4gKiBAcGFyYW0ge251bWJlcn0gYSBUaGUgYWxwaGEgY2hhbm5lbC5cbiAqIEBwcml2YXRlXG4gKi9cbmNsYXNzIENvbG9yIHtcbiAgICByOiBudW1iZXI7XG4gICAgZzogbnVtYmVyO1xuICAgIGI6IG51bWJlcjtcbiAgICBhOiBudW1iZXI7XG5cbiAgICBjb25zdHJ1Y3RvcihyOiBudW1iZXIsIGc6IG51bWJlciwgYjogbnVtYmVyLCBhOiBudW1iZXIgPSAxKSB7XG4gICAgICAgIHRoaXMuciA9IHI7XG4gICAgICAgIHRoaXMuZyA9IGc7XG4gICAgICAgIHRoaXMuYiA9IGI7XG4gICAgICAgIHRoaXMuYSA9IGE7XG4gICAgfVxuXG4gICAgc3RhdGljIGJsYWNrOiBDb2xvcjtcbiAgICBzdGF0aWMgd2hpdGU6IENvbG9yO1xuICAgIHN0YXRpYyB0cmFuc3BhcmVudDogQ29sb3I7XG4gICAgc3RhdGljIHJlZDogQ29sb3I7XG4gICAgc3RhdGljIGJsdWU6IENvbG9yO1xuXG4gICAgLyoqXG4gICAgICogUGFyc2VzIHZhbGlkIENTUyBjb2xvciBzdHJpbmdzIGFuZCByZXR1cm5zIGEgYENvbG9yYCBpbnN0YW5jZS5cbiAgICAgKiBAcmV0dXJucyBBIGBDb2xvcmAgaW5zdGFuY2UsIG9yIGB1bmRlZmluZWRgIGlmIHRoZSBpbnB1dCBpcyBub3QgYSB2YWxpZCBjb2xvciBzdHJpbmcuXG4gICAgICovXG4gICAgc3RhdGljIHBhcnNlKGlucHV0Pzogc3RyaW5nIHwgQ29sb3IgfCBudWxsKTogQ29sb3IgfCB2b2lkIHtcbiAgICAgICAgaWYgKCFpbnB1dCkge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpbnB1dCBpbnN0YW5jZW9mIENvbG9yKSB7XG4gICAgICAgICAgICByZXR1cm4gaW5wdXQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGlucHV0ICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJnYmEgPSBwYXJzZUNTU0NvbG9yKGlucHV0KTtcbiAgICAgICAgaWYgKCFyZ2JhKSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBDb2xvcihcbiAgICAgICAgICAgIHJnYmFbMF0gLyAyNTUgKiByZ2JhWzNdLFxuICAgICAgICAgICAgcmdiYVsxXSAvIDI1NSAqIHJnYmFbM10sXG4gICAgICAgICAgICByZ2JhWzJdIC8gMjU1ICogcmdiYVszXSxcbiAgICAgICAgICAgIHJnYmFbM11cbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFuIFJHQkEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgY29sb3IgdmFsdWUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBbiBSR0JBIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIHZhciBwdXJwbGUgPSBuZXcgQ29sb3IucGFyc2UoJ3B1cnBsZScpO1xuICAgICAqIHB1cnBsZS50b1N0cmluZzsgLy8gPSBcInJnYmEoMTI4LDAsMTI4LDEpXCJcbiAgICAgKiB2YXIgdHJhbnNsdWNlbnRHcmVlbiA9IG5ldyBDb2xvci5wYXJzZSgncmdiYSgyNiwgMjA3LCAyNiwgLjczKScpO1xuICAgICAqIHRyYW5zbHVjZW50R3JlZW4udG9TdHJpbmcoKTsgLy8gPSBcInJnYmEoMjYsMjA3LDI2LDAuNzMpXCJcbiAgICAgKi9cbiAgICB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBbciwgZywgYiwgYV0gPSB0aGlzLnRvQXJyYXkoKTtcbiAgICAgICAgcmV0dXJuIGByZ2JhKCR7TWF0aC5yb3VuZChyKX0sJHtNYXRoLnJvdW5kKGcpfSwke01hdGgucm91bmQoYil9LCR7YX0pYDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFuIFJHQkEgYXJyYXkgb2YgdmFsdWVzIHJlcHJlc2VudGluZyB0aGUgY29sb3IsIHVucHJlbXVsdGlwbGllZCBieSBBLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQW4gYXJyYXkgb2YgUkdCQSBjb2xvciB2YWx1ZXMgaW4gdGhlIHJhbmdlIFswLCAyNTVdLlxuICAgICAqL1xuICAgIHRvQXJyYXkoKTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0ge1xuICAgICAgICBjb25zdCB7ciwgZywgYiwgYX0gPSB0aGlzO1xuICAgICAgICByZXR1cm4gYSA9PT0gMCA/IFswLCAwLCAwLCAwXSA6IFtcbiAgICAgICAgICAgIHIgKiAyNTUgLyBhLFxuICAgICAgICAgICAgZyAqIDI1NSAvIGEsXG4gICAgICAgICAgICBiICogMjU1IC8gYSxcbiAgICAgICAgICAgIGFcbiAgICAgICAgXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgUkdCQSBhcnJheSBvZiBmbG9hdCB2YWx1ZXMgcmVwcmVzZW50aW5nIHRoZSBjb2xvciwgdW5wcmVtdWx0aXBsaWVkIGJ5IEEuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBbiBhcnJheSBvZiBSR0JBIGNvbG9yIHZhbHVlcyBpbiB0aGUgcmFuZ2UgWzAsIDFdLlxuICAgICAqL1xuICAgIHRvQXJyYXkwMSgpOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSB7XG4gICAgICAgIGNvbnN0IHtyLCBnLCBiLCBhfSA9IHRoaXM7XG4gICAgICAgIHJldHVybiBhID09PSAwID8gWzAsIDAsIDAsIDBdIDogW1xuICAgICAgICAgICAgciAvIGEsXG4gICAgICAgICAgICBnIC8gYSxcbiAgICAgICAgICAgIGIgLyBhLFxuICAgICAgICAgICAgYVxuICAgICAgICBdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYW4gUkdCQSBhcnJheSBvZiB2YWx1ZXMgcmVwcmVzZW50aW5nIHRoZSBjb2xvciwgcHJlbXVsdGlwbGllZCBieSBBLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQW4gYXJyYXkgb2YgUkdCQSBjb2xvciB2YWx1ZXMgaW4gdGhlIHJhbmdlIFswLCAxXS5cbiAgICAgKi9cbiAgICB0b0FycmF5MDFQcmVtdWx0aXBsaWVkQWxwaGEoKTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0ge1xuICAgICAgICBjb25zdCB7ciwgZywgYiwgYX0gPSB0aGlzO1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgcixcbiAgICAgICAgICAgIGcsXG4gICAgICAgICAgICBiLFxuICAgICAgICAgICAgYVxuICAgICAgICBdO1xuICAgIH1cbn1cblxuQ29sb3IuYmxhY2sgPSBuZXcgQ29sb3IoMCwgMCwgMCwgMSk7XG5Db2xvci53aGl0ZSA9IG5ldyBDb2xvcigxLCAxLCAxLCAxKTtcbkNvbG9yLnRyYW5zcGFyZW50ID0gbmV3IENvbG9yKDAsIDAsIDAsIDApO1xuQ29sb3IucmVkID0gbmV3IENvbG9yKDEsIDAsIDAsIDEpO1xuQ29sb3IuYmx1ZSA9IG5ldyBDb2xvcigwLCAwLCAxLCAxKTtcblxuZXhwb3J0IGRlZmF1bHQgQ29sb3I7XG4iLCIvLyBAZmxvd1xuXG4vLyBGbG93IHR5cGUgZGVjbGFyYXRpb25zIGZvciBJbnRsIGNyaWJiZWQgZnJvbVxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL2Zsb3cvaXNzdWVzLzEyNzBcblxuZGVjbGFyZSB2YXIgSW50bDoge1xuICAgIENvbGxhdG9yOiBDbGFzczxJbnRsJENvbGxhdG9yPlxufTtcblxuZGVjbGFyZSBjbGFzcyBJbnRsJENvbGxhdG9yIHtcbiAgICBjb25zdHJ1Y3RvciAoXG4gICAgICAgIGxvY2FsZXM/OiBzdHJpbmcgfCBzdHJpbmdbXSxcbiAgICAgICAgb3B0aW9ucz86IENvbGxhdG9yT3B0aW9uc1xuICAgICk6IEludGwkQ29sbGF0b3I7XG5cbiAgICBzdGF0aWMgKFxuICAgICAgICBsb2NhbGVzPzogc3RyaW5nIHwgc3RyaW5nW10sXG4gICAgICAgIG9wdGlvbnM/OiBDb2xsYXRvck9wdGlvbnNcbiAgICApOiBJbnRsJENvbGxhdG9yO1xuXG4gICAgY29tcGFyZSAoYTogc3RyaW5nLCBiOiBzdHJpbmcpOiBudW1iZXI7XG5cbiAgICByZXNvbHZlZE9wdGlvbnMoKTogYW55O1xufVxuXG50eXBlIENvbGxhdG9yT3B0aW9ucyA9IHtcbiAgICBsb2NhbGVNYXRjaGVyPzogJ2xvb2t1cCcgfCAnYmVzdCBmaXQnLFxuICAgIHVzYWdlPzogJ3NvcnQnIHwgJ3NlYXJjaCcsXG4gICAgc2Vuc2l0aXZpdHk/OiAnYmFzZScgfCAnYWNjZW50JyB8ICdjYXNlJyB8ICd2YXJpYW50JyxcbiAgICBpZ25vcmVQdW5jdHVhdGlvbj86IGJvb2xlYW4sXG4gICAgbnVtZXJpYz86IGJvb2xlYW4sXG4gICAgY2FzZUZpcnN0PzogJ3VwcGVyJyB8ICdsb3dlcicgfCAnZmFsc2UnXG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIENvbGxhdG9yIHtcbiAgICBsb2NhbGU6IHN0cmluZyB8IG51bGw7XG4gICAgc2Vuc2l0aXZpdHk6ICdiYXNlJyB8ICdhY2NlbnQnIHwgJ2Nhc2UnIHwgJ3ZhcmlhbnQnO1xuICAgIGNvbGxhdG9yOiBJbnRsJENvbGxhdG9yO1xuXG4gICAgY29uc3RydWN0b3IoY2FzZVNlbnNpdGl2ZTogYm9vbGVhbiwgZGlhY3JpdGljU2Vuc2l0aXZlOiBib29sZWFuLCBsb2NhbGU6IHN0cmluZyB8IG51bGwpIHtcbiAgICAgICAgaWYgKGNhc2VTZW5zaXRpdmUpXG4gICAgICAgICAgICB0aGlzLnNlbnNpdGl2aXR5ID0gZGlhY3JpdGljU2Vuc2l0aXZlID8gJ3ZhcmlhbnQnIDogJ2Nhc2UnO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICB0aGlzLnNlbnNpdGl2aXR5ID0gZGlhY3JpdGljU2Vuc2l0aXZlID8gJ2FjY2VudCcgOiAnYmFzZSc7XG5cbiAgICAgICAgdGhpcy5sb2NhbGUgPSBsb2NhbGU7XG4gICAgICAgIHRoaXMuY29sbGF0b3IgPSBuZXcgSW50bC5Db2xsYXRvcih0aGlzLmxvY2FsZSA/IHRoaXMubG9jYWxlIDogW10sXG4gICAgICAgICAgICB7c2Vuc2l0aXZpdHk6IHRoaXMuc2Vuc2l0aXZpdHksIHVzYWdlOiAnc2VhcmNoJ30pO1xuICAgIH1cblxuICAgIGNvbXBhcmUobGhzOiBzdHJpbmcsIHJoczogc3RyaW5nKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29sbGF0b3IuY29tcGFyZShsaHMsIHJocyk7XG4gICAgfVxuXG4gICAgcmVzb2x2ZWRMb2NhbGUoKTogc3RyaW5nIHtcbiAgICAgICAgLy8gV2UgY3JlYXRlIGEgQ29sbGF0b3Igd2l0aG91dCBcInVzYWdlOiBzZWFyY2hcIiBiZWNhdXNlIHdlIGRvbid0IHdhbnRcbiAgICAgICAgLy8gdGhlIHNlYXJjaCBvcHRpb25zIGVuY29kZWQgaW4gb3VyIHJlc3VsdCAoZS5nLiBcImVuLXUtY28tc2VhcmNoXCIpXG4gICAgICAgIHJldHVybiBuZXcgSW50bC5Db2xsYXRvcih0aGlzLmxvY2FsZSA/IHRoaXMubG9jYWxlIDogW10pXG4gICAgICAgICAgICAucmVzb2x2ZWRPcHRpb25zKCkubG9jYWxlO1xuICAgIH1cbn1cbiIsIi8vIEBmbG93XG5pbXBvcnQgdHlwZSBDb2xvciBmcm9tICcuLi8uLi91dGlsL2NvbG9yLmpzJztcbmltcG9ydCB0eXBlIFJlc29sdmVkSW1hZ2UgZnJvbSAnLi4vdHlwZXMvcmVzb2x2ZWRfaW1hZ2UuanMnO1xuXG5leHBvcnQgY2xhc3MgRm9ybWF0dGVkU2VjdGlvbiB7XG4gICAgdGV4dDogc3RyaW5nO1xuICAgIGltYWdlOiBSZXNvbHZlZEltYWdlIHwgbnVsbDtcbiAgICBzY2FsZTogbnVtYmVyIHwgbnVsbDtcbiAgICBmb250U3RhY2s6IHN0cmluZyB8IG51bGw7XG4gICAgdGV4dENvbG9yOiBDb2xvciB8IG51bGw7XG5cbiAgICBjb25zdHJ1Y3Rvcih0ZXh0OiBzdHJpbmcsIGltYWdlOiBSZXNvbHZlZEltYWdlIHwgbnVsbCwgc2NhbGU6IG51bWJlciB8IG51bGwsIGZvbnRTdGFjazogc3RyaW5nIHwgbnVsbCwgdGV4dENvbG9yOiBDb2xvciB8IG51bGwpIHtcbiAgICAgICAgLy8gY29tYmluZSBjaGFyYWN0ZXJzIHNvIHRoYXQgZGlhY3JpdGljIG1hcmtzIGFyZSBub3Qgc2VwYXJhdGUgY29kZSBwb2ludHNcbiAgICAgICAgdGhpcy50ZXh0ID0gdGV4dC5ub3JtYWxpemUgPyB0ZXh0Lm5vcm1hbGl6ZSgpIDogdGV4dDtcbiAgICAgICAgdGhpcy5pbWFnZSA9IGltYWdlO1xuICAgICAgICB0aGlzLnNjYWxlID0gc2NhbGU7XG4gICAgICAgIHRoaXMuZm9udFN0YWNrID0gZm9udFN0YWNrO1xuICAgICAgICB0aGlzLnRleHRDb2xvciA9IHRleHRDb2xvcjtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEZvcm1hdHRlZCB7XG4gICAgc2VjdGlvbnM6IEFycmF5PEZvcm1hdHRlZFNlY3Rpb24+O1xuXG4gICAgY29uc3RydWN0b3Ioc2VjdGlvbnM6IEFycmF5PEZvcm1hdHRlZFNlY3Rpb24+KSB7XG4gICAgICAgIHRoaXMuc2VjdGlvbnMgPSBzZWN0aW9ucztcbiAgICB9XG5cbiAgICBzdGF0aWMgZnJvbVN0cmluZyh1bmZvcm1hdHRlZDogc3RyaW5nKTogRm9ybWF0dGVkIHtcbiAgICAgICAgcmV0dXJuIG5ldyBGb3JtYXR0ZWQoW25ldyBGb3JtYXR0ZWRTZWN0aW9uKHVuZm9ybWF0dGVkLCBudWxsLCBudWxsLCBudWxsLCBudWxsKV0pO1xuICAgIH1cblxuICAgIGlzRW1wdHkoKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICh0aGlzLnNlY3Rpb25zLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHRydWU7XG4gICAgICAgIHJldHVybiAhdGhpcy5zZWN0aW9ucy5zb21lKHNlY3Rpb24gPT4gc2VjdGlvbi50ZXh0Lmxlbmd0aCAhPT0gMCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNlY3Rpb24uaW1hZ2UgJiYgc2VjdGlvbi5pbWFnZS5uYW1lLmxlbmd0aCAhPT0gMCkpO1xuICAgIH1cblxuICAgIHN0YXRpYyBmYWN0b3J5KHRleHQ6IEZvcm1hdHRlZCB8IHN0cmluZyk6IEZvcm1hdHRlZCB7XG4gICAgICAgIGlmICh0ZXh0IGluc3RhbmNlb2YgRm9ybWF0dGVkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGV4dDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBGb3JtYXR0ZWQuZnJvbVN0cmluZyh0ZXh0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgICAgIGlmICh0aGlzLnNlY3Rpb25zLmxlbmd0aCA9PT0gMCkgcmV0dXJuICcnO1xuICAgICAgICByZXR1cm4gdGhpcy5zZWN0aW9ucy5tYXAoc2VjdGlvbiA9PiBzZWN0aW9uLnRleHQpLmpvaW4oJycpO1xuICAgIH1cblxuICAgIHNlcmlhbGl6ZSgpOiBBcnJheTxtaXhlZD4ge1xuICAgICAgICBjb25zdCBzZXJpYWxpemVkOiBBcnJheTxtaXhlZD4gPSBbXCJmb3JtYXRcIl07XG4gICAgICAgIGZvciAoY29uc3Qgc2VjdGlvbiBvZiB0aGlzLnNlY3Rpb25zKSB7XG4gICAgICAgICAgICBpZiAoc2VjdGlvbi5pbWFnZSkge1xuICAgICAgICAgICAgICAgIHNlcmlhbGl6ZWQucHVzaChbXCJpbWFnZVwiLCBzZWN0aW9uLmltYWdlLm5hbWVdKTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNlcmlhbGl6ZWQucHVzaChzZWN0aW9uLnRleHQpO1xuICAgICAgICAgICAgY29uc3Qgb3B0aW9uczogeyBba2V5OiBzdHJpbmddOiBtaXhlZCB9ID0ge307XG4gICAgICAgICAgICBpZiAoc2VjdGlvbi5mb250U3RhY2spIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zW1widGV4dC1mb250XCJdID0gW1wibGl0ZXJhbFwiLCBzZWN0aW9uLmZvbnRTdGFjay5zcGxpdCgnLCcpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzZWN0aW9uLnNjYWxlKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9uc1tcImZvbnQtc2NhbGVcIl0gPSBzZWN0aW9uLnNjYWxlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHNlY3Rpb24udGV4dENvbG9yKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9uc1tcInRleHQtY29sb3JcIl0gPSAoW1wicmdiYVwiXTogQXJyYXk8bWl4ZWQ+KS5jb25jYXQoc2VjdGlvbi50ZXh0Q29sb3IudG9BcnJheSgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNlcmlhbGl6ZWQucHVzaChvcHRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2VyaWFsaXplZDtcbiAgICB9XG59XG4iLCIvLyBAZmxvd1xuXG5leHBvcnQgdHlwZSBSZXNvbHZlZEltYWdlT3B0aW9ucyA9IHtcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgYXZhaWxhYmxlOiBib29sZWFuXG59O1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSZXNvbHZlZEltYWdlIHtcbiAgICBuYW1lOiBzdHJpbmc7XG4gICAgYXZhaWxhYmxlOiBib29sZWFuO1xuXG4gICAgY29uc3RydWN0b3Iob3B0aW9uczogUmVzb2x2ZWRJbWFnZU9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy5uYW1lID0gb3B0aW9ucy5uYW1lO1xuICAgICAgICB0aGlzLmF2YWlsYWJsZSA9IG9wdGlvbnMuYXZhaWxhYmxlO1xuICAgIH1cblxuICAgIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLm5hbWU7XG4gICAgfVxuXG4gICAgc3RhdGljIGZyb21TdHJpbmcobmFtZTogc3RyaW5nKTogUmVzb2x2ZWRJbWFnZSB8IG51bGwge1xuICAgICAgICBpZiAoIW5hbWUpIHJldHVybiBudWxsOyAvLyB0cmVhdCBlbXB0eSB2YWx1ZXMgYXMgbm8gaW1hZ2VcbiAgICAgICAgcmV0dXJuIG5ldyBSZXNvbHZlZEltYWdlKHtuYW1lLCBhdmFpbGFibGU6IGZhbHNlfSk7XG4gICAgfVxuXG4gICAgc2VyaWFsaXplKCk6IEFycmF5PHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gW1wiaW1hZ2VcIiwgdGhpcy5uYW1lXTtcbiAgICB9XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbmltcG9ydCBDb2xvciBmcm9tICcuLi91dGlsL2NvbG9yLmpzJztcbmltcG9ydCBDb2xsYXRvciBmcm9tICcuL3R5cGVzL2NvbGxhdG9yLmpzJztcbmltcG9ydCBGb3JtYXR0ZWQgZnJvbSAnLi90eXBlcy9mb3JtYXR0ZWQuanMnO1xuaW1wb3J0IFJlc29sdmVkSW1hZ2UgZnJvbSAnLi90eXBlcy9yZXNvbHZlZF9pbWFnZS5qcyc7XG5pbXBvcnQge051bGxUeXBlLCBOdW1iZXJUeXBlLCBTdHJpbmdUeXBlLCBCb29sZWFuVHlwZSwgQ29sb3JUeXBlLCBPYmplY3RUeXBlLCBWYWx1ZVR5cGUsIENvbGxhdG9yVHlwZSwgRm9ybWF0dGVkVHlwZSwgUmVzb2x2ZWRJbWFnZVR5cGUsIGFycmF5fSBmcm9tICcuL3R5cGVzLmpzJztcblxuaW1wb3J0IHR5cGUge1R5cGV9IGZyb20gJy4vdHlwZXMuanMnO1xuXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVSR0JBKHI6IG1peGVkLCBnOiBtaXhlZCwgYjogbWl4ZWQsIGE/OiBtaXhlZCk6IHN0cmluZyB8IG51bGwge1xuICAgIGlmICghKFxuICAgICAgICB0eXBlb2YgciA9PT0gJ251bWJlcicgJiYgciA+PSAwICYmIHIgPD0gMjU1ICYmXG4gICAgICAgIHR5cGVvZiBnID09PSAnbnVtYmVyJyAmJiBnID49IDAgJiYgZyA8PSAyNTUgJiZcbiAgICAgICAgdHlwZW9mIGIgPT09ICdudW1iZXInICYmIGIgPj0gMCAmJiBiIDw9IDI1NVxuICAgICkpIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSB0eXBlb2YgYSA9PT0gJ251bWJlcicgPyBbciwgZywgYiwgYV0gOiBbciwgZywgYl07XG4gICAgICAgIHJldHVybiBgSW52YWxpZCByZ2JhIHZhbHVlIFske3ZhbHVlLmpvaW4oJywgJyl9XTogJ3InLCAnZycsIGFuZCAnYicgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDI1NS5gO1xuICAgIH1cblxuICAgIGlmICghKFxuICAgICAgICB0eXBlb2YgYSA9PT0gJ3VuZGVmaW5lZCcgfHwgKHR5cGVvZiBhID09PSAnbnVtYmVyJyAmJiBhID49IDAgJiYgYSA8PSAxKVxuICAgICkpIHtcbiAgICAgICAgcmV0dXJuIGBJbnZhbGlkIHJnYmEgdmFsdWUgWyR7W3IsIGcsIGIsIGFdLmpvaW4oJywgJyl9XTogJ2EnIG11c3QgYmUgYmV0d2VlbiAwIGFuZCAxLmA7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG59XG5cbmV4cG9ydCB0eXBlIFZhbHVlID0gbnVsbCB8IHN0cmluZyB8IGJvb2xlYW4gfCBudW1iZXIgfCBDb2xvciB8IENvbGxhdG9yIHwgRm9ybWF0dGVkIHwgUmVzb2x2ZWRJbWFnZSB8ICRSZWFkT25seUFycmF5PFZhbHVlPiB8IHsgK1tzdHJpbmddOiBWYWx1ZSB9XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbHVlKG1peGVkOiBtaXhlZCk6IGJvb2xlYW4ge1xuICAgIGlmIChtaXhlZCA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBtaXhlZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgbWl4ZWQgPT09ICdib29sZWFuJykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBtaXhlZCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIGlmIChtaXhlZCBpbnN0YW5jZW9mIENvbG9yKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSBpZiAobWl4ZWQgaW5zdGFuY2VvZiBDb2xsYXRvcikge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKG1peGVkIGluc3RhbmNlb2YgRm9ybWF0dGVkKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSBpZiAobWl4ZWQgaW5zdGFuY2VvZiBSZXNvbHZlZEltYWdlKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShtaXhlZCkpIHtcbiAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIG1peGVkKSB7XG4gICAgICAgICAgICBpZiAoIWlzVmFsdWUoaXRlbSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgbWl4ZWQgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIG1peGVkKSB7XG4gICAgICAgICAgICBpZiAoIWlzVmFsdWUobWl4ZWRba2V5XSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHR5cGVPZih2YWx1ZTogVmFsdWUpOiBUeXBlIHtcbiAgICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIE51bGxUeXBlO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gU3RyaW5nVHlwZTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIHJldHVybiBCb29sZWFuVHlwZTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgcmV0dXJuIE51bWJlclR5cGU7XG4gICAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIENvbG9yKSB7XG4gICAgICAgIHJldHVybiBDb2xvclR5cGU7XG4gICAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIENvbGxhdG9yKSB7XG4gICAgICAgIHJldHVybiBDb2xsYXRvclR5cGU7XG4gICAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEZvcm1hdHRlZCkge1xuICAgICAgICByZXR1cm4gRm9ybWF0dGVkVHlwZTtcbiAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgUmVzb2x2ZWRJbWFnZSkge1xuICAgICAgICByZXR1cm4gUmVzb2x2ZWRJbWFnZVR5cGU7XG4gICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICBjb25zdCBsZW5ndGggPSB2YWx1ZS5sZW5ndGg7XG4gICAgICAgIGxldCBpdGVtVHlwZTogVHlwZSB8IHR5cGVvZiB1bmRlZmluZWQ7XG5cbiAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIHZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCB0ID0gdHlwZU9mKGl0ZW0pO1xuICAgICAgICAgICAgaWYgKCFpdGVtVHlwZSkge1xuICAgICAgICAgICAgICAgIGl0ZW1UeXBlID0gdDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXRlbVR5cGUgPT09IHQpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaXRlbVR5cGUgPSBWYWx1ZVR5cGU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXJyYXkoaXRlbVR5cGUgfHwgVmFsdWVUeXBlLCBsZW5ndGgpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGFzc2VydCh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKTtcbiAgICAgICAgcmV0dXJuIE9iamVjdFR5cGU7XG4gICAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gdG9TdHJpbmcodmFsdWU6IFZhbHVlKTogc3RyaW5nIHtcbiAgICBjb25zdCB0eXBlID0gdHlwZW9mIHZhbHVlO1xuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJyB8fCB0eXBlID09PSAnbnVtYmVyJyB8fCB0eXBlID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgcmV0dXJuIFN0cmluZyh2YWx1ZSk7XG4gICAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIENvbG9yIHx8IHZhbHVlIGluc3RhbmNlb2YgRm9ybWF0dGVkIHx8IHZhbHVlIGluc3RhbmNlb2YgUmVzb2x2ZWRJbWFnZSkge1xuICAgICAgICByZXR1cm4gdmFsdWUudG9TdHJpbmcoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodmFsdWUpO1xuICAgIH1cbn1cblxuZXhwb3J0IHtDb2xvciwgQ29sbGF0b3J9O1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHtpc1ZhbHVlLCB0eXBlT2YsIENvbG9yfSBmcm9tICcuLi92YWx1ZXMuanMnO1xuaW1wb3J0IEZvcm1hdHRlZCBmcm9tICcuLi90eXBlcy9mb3JtYXR0ZWQuanMnO1xuXG5pbXBvcnQgdHlwZSB7VHlwZX0gZnJvbSAnLi4vdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge1ZhbHVlfSAgZnJvbSAnLi4vdmFsdWVzLmpzJztcbmltcG9ydCB0eXBlIHtFeHByZXNzaW9uLCBTZXJpYWxpemVkRXhwcmVzc2lvbn0gZnJvbSAnLi4vZXhwcmVzc2lvbi5qcyc7XG5pbXBvcnQgdHlwZSBQYXJzaW5nQ29udGV4dCBmcm9tICcuLi9wYXJzaW5nX2NvbnRleHQuanMnO1xuXG5jbGFzcyBMaXRlcmFsIGltcGxlbWVudHMgRXhwcmVzc2lvbiB7XG4gICAgdHlwZTogVHlwZTtcbiAgICB2YWx1ZTogVmFsdWU7XG5cbiAgICBjb25zdHJ1Y3Rvcih0eXBlOiBUeXBlLCB2YWx1ZTogVmFsdWUpIHtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIHN0YXRpYyBwYXJzZShhcmdzOiAkUmVhZE9ubHlBcnJheTxtaXhlZD4sIGNvbnRleHQ6IFBhcnNpbmdDb250ZXh0KTogdm9pZCB8IExpdGVyYWwge1xuICAgICAgICBpZiAoYXJncy5sZW5ndGggIT09IDIpXG4gICAgICAgICAgICByZXR1cm4gY29udGV4dC5lcnJvcihgJ2xpdGVyYWwnIGV4cHJlc3Npb24gcmVxdWlyZXMgZXhhY3RseSBvbmUgYXJndW1lbnQsIGJ1dCBmb3VuZCAke2FyZ3MubGVuZ3RoIC0gMX0gaW5zdGVhZC5gKTtcblxuICAgICAgICBpZiAoIWlzVmFsdWUoYXJnc1sxXSkpXG4gICAgICAgICAgICByZXR1cm4gY29udGV4dC5lcnJvcihgaW52YWxpZCB2YWx1ZWApO1xuXG4gICAgICAgIGNvbnN0IHZhbHVlID0gKGFyZ3NbMV06IGFueSk7XG4gICAgICAgIGxldCB0eXBlID0gdHlwZU9mKHZhbHVlKTtcblxuICAgICAgICAvLyBzcGVjaWFsIGNhc2U6IGluZmVyIHRoZSBpdGVtIHR5cGUgaWYgcG9zc2libGUgZm9yIHplcm8tbGVuZ3RoIGFycmF5c1xuICAgICAgICBjb25zdCBleHBlY3RlZCA9IGNvbnRleHQuZXhwZWN0ZWRUeXBlO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICB0eXBlLmtpbmQgPT09ICdhcnJheScgJiZcbiAgICAgICAgICAgIHR5cGUuTiA9PT0gMCAmJlxuICAgICAgICAgICAgZXhwZWN0ZWQgJiZcbiAgICAgICAgICAgIGV4cGVjdGVkLmtpbmQgPT09ICdhcnJheScgJiZcbiAgICAgICAgICAgICh0eXBlb2YgZXhwZWN0ZWQuTiAhPT0gJ251bWJlcicgfHwgZXhwZWN0ZWQuTiA9PT0gMClcbiAgICAgICAgKSB7XG4gICAgICAgICAgICB0eXBlID0gZXhwZWN0ZWQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IExpdGVyYWwodHlwZSwgdmFsdWUpO1xuICAgIH1cblxuICAgIGV2YWx1YXRlKCk6IFZhbHVlIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWU7XG4gICAgfVxuXG4gICAgZWFjaENoaWxkKCkge31cblxuICAgIG91dHB1dERlZmluZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHNlcmlhbGl6ZSgpOiBTZXJpYWxpemVkRXhwcmVzc2lvbiB7XG4gICAgICAgIGlmICh0aGlzLnR5cGUua2luZCA9PT0gJ2FycmF5JyB8fCB0aGlzLnR5cGUua2luZCA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHJldHVybiBbXCJsaXRlcmFsXCIsIHRoaXMudmFsdWVdO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMudmFsdWUgaW5zdGFuY2VvZiBDb2xvcikge1xuICAgICAgICAgICAgLy8gQ29uc3RhbnQtZm9sZGluZyBjYW4gZ2VuZXJhdGUgTGl0ZXJhbCBleHByZXNzaW9ucyB0aGF0IHlvdVxuICAgICAgICAgICAgLy8gY291bGRuJ3QgYWN0dWFsbHkgZ2VuZXJhdGUgd2l0aCBhIFwibGl0ZXJhbFwiIGV4cHJlc3Npb24sXG4gICAgICAgICAgICAvLyBzbyB3ZSBoYXZlIHRvIGltcGxlbWVudCBhbiBlcXVpdmFsZW50IHNlcmlhbGl6YXRpb24gaGVyZVxuICAgICAgICAgICAgcmV0dXJuIFtcInJnYmFcIl0uY29uY2F0KHRoaXMudmFsdWUudG9BcnJheSgpKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnZhbHVlIGluc3RhbmNlb2YgRm9ybWF0dGVkKSB7XG4gICAgICAgICAgICAvLyBTYW1lIGFzIENvbG9yXG4gICAgICAgICAgICByZXR1cm4gdGhpcy52YWx1ZS5zZXJpYWxpemUoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFzc2VydCh0aGlzLnZhbHVlID09PSBudWxsIHx8XG4gICAgICAgICAgICAgICAgdHlwZW9mIHRoaXMudmFsdWUgPT09ICdzdHJpbmcnIHx8XG4gICAgICAgICAgICAgICAgdHlwZW9mIHRoaXMudmFsdWUgPT09ICdudW1iZXInIHx8XG4gICAgICAgICAgICAgICAgdHlwZW9mIHRoaXMudmFsdWUgPT09ICdib29sZWFuJyk7XG4gICAgICAgICAgICByZXR1cm4gKHRoaXMudmFsdWU6IGFueSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IExpdGVyYWw7XG4iLCIvLyBAZmxvd1xuXG5jbGFzcyBSdW50aW1lRXJyb3Ige1xuICAgIG5hbWU6IHN0cmluZztcbiAgICBtZXNzYWdlOiBzdHJpbmc7XG5cbiAgICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5uYW1lID0gJ0V4cHJlc3Npb25FdmFsdWF0aW9uRXJyb3InO1xuICAgICAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlO1xuICAgIH1cblxuICAgIHRvSlNPTigpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5tZXNzYWdlO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUnVudGltZUVycm9yO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuXG5pbXBvcnQge1xuICAgIE9iamVjdFR5cGUsXG4gICAgVmFsdWVUeXBlLFxuICAgIFN0cmluZ1R5cGUsXG4gICAgTnVtYmVyVHlwZSxcbiAgICBCb29sZWFuVHlwZSxcbiAgICBjaGVja1N1YnR5cGUsXG4gICAgdG9TdHJpbmcsXG4gICAgYXJyYXlcbn0gZnJvbSAnLi4vdHlwZXMuanMnO1xuaW1wb3J0IFJ1bnRpbWVFcnJvciBmcm9tICcuLi9ydW50aW1lX2Vycm9yLmpzJztcbmltcG9ydCB7dHlwZU9mfSBmcm9tICcuLi92YWx1ZXMuanMnO1xuXG5pbXBvcnQgdHlwZSB7RXhwcmVzc2lvbiwgU2VyaWFsaXplZEV4cHJlc3Npb259IGZyb20gJy4uL2V4cHJlc3Npb24uanMnO1xuaW1wb3J0IHR5cGUgUGFyc2luZ0NvbnRleHQgZnJvbSAnLi4vcGFyc2luZ19jb250ZXh0LmpzJztcbmltcG9ydCB0eXBlIEV2YWx1YXRpb25Db250ZXh0IGZyb20gJy4uL2V2YWx1YXRpb25fY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSB7VHlwZX0gZnJvbSAnLi4vdHlwZXMuanMnO1xuXG5jb25zdCB0eXBlcyA9IHtcbiAgICBzdHJpbmc6IFN0cmluZ1R5cGUsXG4gICAgbnVtYmVyOiBOdW1iZXJUeXBlLFxuICAgIGJvb2xlYW46IEJvb2xlYW5UeXBlLFxuICAgIG9iamVjdDogT2JqZWN0VHlwZVxufTtcblxuY2xhc3MgQXNzZXJ0aW9uIGltcGxlbWVudHMgRXhwcmVzc2lvbiB7XG4gICAgdHlwZTogVHlwZTtcbiAgICBhcmdzOiBBcnJheTxFeHByZXNzaW9uPjtcblxuICAgIGNvbnN0cnVjdG9yKHR5cGU6IFR5cGUsIGFyZ3M6IEFycmF5PEV4cHJlc3Npb24+KSB7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuYXJncyA9IGFyZ3M7XG4gICAgfVxuXG4gICAgc3RhdGljIHBhcnNlKGFyZ3M6ICRSZWFkT25seUFycmF5PG1peGVkPiwgY29udGV4dDogUGFyc2luZ0NvbnRleHQpOiA/RXhwcmVzc2lvbiB7XG4gICAgICAgIGlmIChhcmdzLmxlbmd0aCA8IDIpXG4gICAgICAgICAgICByZXR1cm4gY29udGV4dC5lcnJvcihgRXhwZWN0ZWQgYXQgbGVhc3Qgb25lIGFyZ3VtZW50LmApO1xuXG4gICAgICAgIGxldCBpID0gMTtcbiAgICAgICAgbGV0IHR5cGU7XG5cbiAgICAgICAgY29uc3QgbmFtZTogc3RyaW5nID0gKGFyZ3NbMF06IGFueSk7XG4gICAgICAgIGlmIChuYW1lID09PSAnYXJyYXknKSB7XG4gICAgICAgICAgICBsZXQgaXRlbVR5cGU7XG4gICAgICAgICAgICBpZiAoYXJncy5sZW5ndGggPiAyKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdHlwZSA9IGFyZ3NbMV07XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB0eXBlICE9PSAnc3RyaW5nJyB8fCAhKHR5cGUgaW4gdHlwZXMpIHx8IHR5cGUgPT09ICdvYmplY3QnKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udGV4dC5lcnJvcignVGhlIGl0ZW0gdHlwZSBhcmd1bWVudCBvZiBcImFycmF5XCIgbXVzdCBiZSBvbmUgb2Ygc3RyaW5nLCBudW1iZXIsIGJvb2xlYW4nLCAxKTtcbiAgICAgICAgICAgICAgICBpdGVtVHlwZSA9IHR5cGVzW3R5cGVdO1xuICAgICAgICAgICAgICAgIGkrKztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaXRlbVR5cGUgPSBWYWx1ZVR5cGU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBOOiA/bnVtYmVyO1xuICAgICAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID4gMykge1xuICAgICAgICAgICAgICAgIGlmIChhcmdzWzJdICE9PSBudWxsICYmXG4gICAgICAgICAgICAgICAgICAgICh0eXBlb2YgYXJnc1syXSAhPT0gJ251bWJlcicgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3NbMl0gPCAwIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBhcmdzWzJdICE9PSBNYXRoLmZsb29yKGFyZ3NbMl0pKVxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udGV4dC5lcnJvcignVGhlIGxlbmd0aCBhcmd1bWVudCB0byBcImFycmF5XCIgbXVzdCBiZSBhIHBvc2l0aXZlIGludGVnZXIgbGl0ZXJhbCcsIDIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBOID0gKChhcmdzWzJdOiBhbnkpOiBudW1iZXIpO1xuICAgICAgICAgICAgICAgIGkrKztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdHlwZSA9IGFycmF5KGl0ZW1UeXBlLCBOKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFzc2VydCh0eXBlc1tuYW1lXSwgbmFtZSk7XG4gICAgICAgICAgICB0eXBlID0gdHlwZXNbbmFtZV07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwYXJzZWQgPSBbXTtcbiAgICAgICAgZm9yICg7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBpbnB1dCA9IGNvbnRleHQucGFyc2UoYXJnc1tpXSwgaSwgVmFsdWVUeXBlKTtcbiAgICAgICAgICAgIGlmICghaW5wdXQpIHJldHVybiBudWxsO1xuICAgICAgICAgICAgcGFyc2VkLnB1c2goaW5wdXQpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBBc3NlcnRpb24odHlwZSwgcGFyc2VkKTtcbiAgICB9XG5cbiAgICBldmFsdWF0ZShjdHg6IEV2YWx1YXRpb25Db250ZXh0KTogYW55IHwgbnVsbCB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5hcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuYXJnc1tpXS5ldmFsdWF0ZShjdHgpO1xuICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBjaGVja1N1YnR5cGUodGhpcy50eXBlLCB0eXBlT2YodmFsdWUpKTtcbiAgICAgICAgICAgIGlmICghZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGkgPT09IHRoaXMuYXJncy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcihgRXhwZWN0ZWQgdmFsdWUgdG8gYmUgb2YgdHlwZSAke3RvU3RyaW5nKHRoaXMudHlwZSl9LCBidXQgZm91bmQgJHt0b1N0cmluZyh0eXBlT2YodmFsdWUpKX0gaW5zdGVhZC5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGFzc2VydChmYWxzZSk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGVhY2hDaGlsZChmbjogKF86IEV4cHJlc3Npb24pID0+IHZvaWQpIHtcbiAgICAgICAgdGhpcy5hcmdzLmZvckVhY2goZm4pO1xuICAgIH1cblxuICAgIG91dHB1dERlZmluZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmFyZ3MuZXZlcnkoYXJnID0+IGFyZy5vdXRwdXREZWZpbmVkKCkpO1xuICAgIH1cblxuICAgIHNlcmlhbGl6ZSgpOiBTZXJpYWxpemVkRXhwcmVzc2lvbiB7XG4gICAgICAgIGNvbnN0IHR5cGUgPSB0aGlzLnR5cGU7XG4gICAgICAgIGNvbnN0IHNlcmlhbGl6ZWQgPSBbdHlwZS5raW5kXTtcbiAgICAgICAgaWYgKHR5cGUua2luZCA9PT0gJ2FycmF5Jykge1xuICAgICAgICAgICAgY29uc3QgaXRlbVR5cGUgPSB0eXBlLml0ZW1UeXBlO1xuICAgICAgICAgICAgaWYgKGl0ZW1UeXBlLmtpbmQgPT09ICdzdHJpbmcnIHx8XG4gICAgICAgICAgICAgICAgaXRlbVR5cGUua2luZCA9PT0gJ251bWJlcicgfHxcbiAgICAgICAgICAgICAgICBpdGVtVHlwZS5raW5kID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgICAgICBzZXJpYWxpemVkLnB1c2goaXRlbVR5cGUua2luZCk7XG4gICAgICAgICAgICAgICAgY29uc3QgTiA9IHR5cGUuTjtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE4gPT09ICdudW1iZXInIHx8IHRoaXMuYXJncy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlcmlhbGl6ZWQucHVzaChOKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNlcmlhbGl6ZWQuY29uY2F0KHRoaXMuYXJncy5tYXAoYXJnID0+IGFyZy5zZXJpYWxpemUoKSkpO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQXNzZXJ0aW9uO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtOdW1iZXJUeXBlLCBWYWx1ZVR5cGUsIEZvcm1hdHRlZFR5cGUsIGFycmF5LCBTdHJpbmdUeXBlLCBDb2xvclR5cGUsIFJlc29sdmVkSW1hZ2VUeXBlfSBmcm9tICcuLi90eXBlcy5qcyc7XG5pbXBvcnQgRm9ybWF0dGVkLCB7Rm9ybWF0dGVkU2VjdGlvbn0gZnJvbSAnLi4vdHlwZXMvZm9ybWF0dGVkLmpzJztcbmltcG9ydCB7dG9TdHJpbmcsIHR5cGVPZn0gZnJvbSAnLi4vdmFsdWVzLmpzJztcblxuaW1wb3J0IHR5cGUge0V4cHJlc3Npb24sIFNlcmlhbGl6ZWRFeHByZXNzaW9ufSBmcm9tICcuLi9leHByZXNzaW9uLmpzJztcbmltcG9ydCB0eXBlIEV2YWx1YXRpb25Db250ZXh0IGZyb20gJy4uL2V2YWx1YXRpb25fY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSBQYXJzaW5nQ29udGV4dCBmcm9tICcuLi9wYXJzaW5nX2NvbnRleHQuanMnO1xuaW1wb3J0IHR5cGUge1R5cGV9IGZyb20gJy4uL3R5cGVzLmpzJztcblxuZXhwb3J0IHR5cGUgRm9ybWF0dGVkU2VjdGlvbkV4cHJlc3Npb24gPSB7XG4gICAgLy8gQ29udGVudCBvZiBhIHNlY3Rpb24gbWF5IGJlIEltYWdlIGV4cHJlc3Npb24gb3Igb3RoZXJcbiAgICAvLyB0eXBlIG9mIGV4cHJlc3Npb24gdGhhdCBpcyBjb2VyY2FibGUgdG8gJ3N0cmluZycuXG4gICAgY29udGVudDogRXhwcmVzc2lvbixcbiAgICBzY2FsZTogRXhwcmVzc2lvbiB8IG51bGw7XG4gICAgZm9udDogRXhwcmVzc2lvbiB8IG51bGw7XG4gICAgdGV4dENvbG9yOiBFeHByZXNzaW9uIHwgbnVsbDtcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRm9ybWF0RXhwcmVzc2lvbiBpbXBsZW1lbnRzIEV4cHJlc3Npb24ge1xuICAgIHR5cGU6IFR5cGU7XG4gICAgc2VjdGlvbnM6IEFycmF5PEZvcm1hdHRlZFNlY3Rpb25FeHByZXNzaW9uPjtcblxuICAgIGNvbnN0cnVjdG9yKHNlY3Rpb25zOiBBcnJheTxGb3JtYXR0ZWRTZWN0aW9uRXhwcmVzc2lvbj4pIHtcbiAgICAgICAgdGhpcy50eXBlID0gRm9ybWF0dGVkVHlwZTtcbiAgICAgICAgdGhpcy5zZWN0aW9ucyA9IHNlY3Rpb25zO1xuICAgIH1cblxuICAgIHN0YXRpYyBwYXJzZShhcmdzOiAkUmVhZE9ubHlBcnJheTxtaXhlZD4sIGNvbnRleHQ6IFBhcnNpbmdDb250ZXh0KTogP0V4cHJlc3Npb24ge1xuICAgICAgICBpZiAoYXJncy5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICByZXR1cm4gY29udGV4dC5lcnJvcihgRXhwZWN0ZWQgYXQgbGVhc3Qgb25lIGFyZ3VtZW50LmApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmlyc3RBcmcgPSBhcmdzWzFdO1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoZmlyc3RBcmcpICYmIHR5cGVvZiBmaXJzdEFyZyA9PT0gJ29iamVjdCcpICB7XG4gICAgICAgICAgICByZXR1cm4gY29udGV4dC5lcnJvcihgRmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhbiBpbWFnZSBvciB0ZXh0IHNlY3Rpb24uYCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzZWN0aW9uczogQXJyYXk8Rm9ybWF0dGVkU2VjdGlvbkV4cHJlc3Npb24+ID0gW107XG4gICAgICAgIGxldCBuZXh0VG9rZW5NYXlCZU9iamVjdCA9IGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8PSBhcmdzLmxlbmd0aCAtIDE7ICsraSkge1xuICAgICAgICAgICAgY29uc3QgYXJnID0gKGFyZ3NbaV06IGFueSk7XG5cbiAgICAgICAgICAgIGlmIChuZXh0VG9rZW5NYXlCZU9iamVjdCAmJiB0eXBlb2YgYXJnID09PSBcIm9iamVjdFwiICYmICFBcnJheS5pc0FycmF5KGFyZykpIHtcbiAgICAgICAgICAgICAgICBuZXh0VG9rZW5NYXlCZU9iamVjdCA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgbGV0IHNjYWxlID0gbnVsbDtcbiAgICAgICAgICAgICAgICBpZiAoYXJnWydmb250LXNjYWxlJ10pIHtcbiAgICAgICAgICAgICAgICAgICAgc2NhbGUgPSBjb250ZXh0LnBhcnNlKGFyZ1snZm9udC1zY2FsZSddLCAxLCBOdW1iZXJUeXBlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFzY2FsZSkgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgbGV0IGZvbnQgPSBudWxsO1xuICAgICAgICAgICAgICAgIGlmIChhcmdbJ3RleHQtZm9udCddKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvbnQgPSBjb250ZXh0LnBhcnNlKGFyZ1sndGV4dC1mb250J10sIDEsIGFycmF5KFN0cmluZ1R5cGUpKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFmb250KSByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBsZXQgdGV4dENvbG9yID0gbnVsbDtcbiAgICAgICAgICAgICAgICBpZiAoYXJnWyd0ZXh0LWNvbG9yJ10pIHtcbiAgICAgICAgICAgICAgICAgICAgdGV4dENvbG9yID0gY29udGV4dC5wYXJzZShhcmdbJ3RleHQtY29sb3InXSwgMSwgQ29sb3JUeXBlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0ZXh0Q29sb3IpIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IGxhc3RFeHByZXNzaW9uID0gc2VjdGlvbnNbc2VjdGlvbnMubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICAgICAgbGFzdEV4cHJlc3Npb24uc2NhbGUgPSBzY2FsZTtcbiAgICAgICAgICAgICAgICBsYXN0RXhwcmVzc2lvbi5mb250ID0gZm9udDtcbiAgICAgICAgICAgICAgICBsYXN0RXhwcmVzc2lvbi50ZXh0Q29sb3IgPSB0ZXh0Q29sb3I7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbnRlbnQgPSBjb250ZXh0LnBhcnNlKGFyZ3NbaV0sIDEsIFZhbHVlVHlwZSk7XG4gICAgICAgICAgICAgICAgaWYgKCFjb250ZW50KSByZXR1cm4gbnVsbDtcblxuICAgICAgICAgICAgICAgIGNvbnN0IGtpbmQgPSBjb250ZW50LnR5cGUua2luZDtcbiAgICAgICAgICAgICAgICBpZiAoa2luZCAhPT0gJ3N0cmluZycgJiYga2luZCAhPT0gJ3ZhbHVlJyAmJiBraW5kICE9PSAnbnVsbCcgJiYga2luZCAhPT0gJ3Jlc29sdmVkSW1hZ2UnKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udGV4dC5lcnJvcihgRm9ybWF0dGVkIHRleHQgdHlwZSBtdXN0IGJlICdzdHJpbmcnLCAndmFsdWUnLCAnaW1hZ2UnIG9yICdudWxsJy5gKTtcblxuICAgICAgICAgICAgICAgIG5leHRUb2tlbk1heUJlT2JqZWN0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBzZWN0aW9ucy5wdXNoKHtjb250ZW50LCBzY2FsZTogbnVsbCwgZm9udDogbnVsbCwgdGV4dENvbG9yOiBudWxsfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IEZvcm1hdEV4cHJlc3Npb24oc2VjdGlvbnMpO1xuICAgIH1cblxuICAgIGV2YWx1YXRlKGN0eDogRXZhbHVhdGlvbkNvbnRleHQpOiBGb3JtYXR0ZWQge1xuICAgICAgICBjb25zdCBldmFsdWF0ZVNlY3Rpb24gPSAoc2VjdGlvbjogRm9ybWF0dGVkU2VjdGlvbkV4cHJlc3Npb24pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGV2YWx1YXRlZENvbnRlbnQgPSBzZWN0aW9uLmNvbnRlbnQuZXZhbHVhdGUoY3R4KTtcbiAgICAgICAgICAgIGlmICh0eXBlT2YoZXZhbHVhdGVkQ29udGVudCkgPT09IFJlc29sdmVkSW1hZ2VUeXBlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBGb3JtYXR0ZWRTZWN0aW9uKCcnLCBldmFsdWF0ZWRDb250ZW50LCBudWxsLCBudWxsLCBudWxsKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIG5ldyBGb3JtYXR0ZWRTZWN0aW9uKFxuICAgICAgICAgICAgICAgICAgICB0b1N0cmluZyhldmFsdWF0ZWRDb250ZW50KSxcbiAgICAgICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgc2VjdGlvbi5zY2FsZSA/IHNlY3Rpb24uc2NhbGUuZXZhbHVhdGUoY3R4KSA6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIHNlY3Rpb24uZm9udCA/IHNlY3Rpb24uZm9udC5ldmFsdWF0ZShjdHgpLmpvaW4oJywnKSA6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIHNlY3Rpb24udGV4dENvbG9yID8gc2VjdGlvbi50ZXh0Q29sb3IuZXZhbHVhdGUoY3R4KSA6IG51bGxcbiAgICAgICAgICAgICk7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIG5ldyBGb3JtYXR0ZWQodGhpcy5zZWN0aW9ucy5tYXAoZXZhbHVhdGVTZWN0aW9uKSk7XG4gICAgfVxuXG4gICAgZWFjaENoaWxkKGZuOiAoXzogRXhwcmVzc2lvbikgPT4gdm9pZCkge1xuICAgICAgICBmb3IgKGNvbnN0IHNlY3Rpb24gb2YgdGhpcy5zZWN0aW9ucykge1xuICAgICAgICAgICAgZm4oc2VjdGlvbi5jb250ZW50KTtcbiAgICAgICAgICAgIGlmIChzZWN0aW9uLnNjYWxlKSB7XG4gICAgICAgICAgICAgICAgZm4oc2VjdGlvbi5zY2FsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoc2VjdGlvbi5mb250KSB7XG4gICAgICAgICAgICAgICAgZm4oc2VjdGlvbi5mb250KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzZWN0aW9uLnRleHRDb2xvcikge1xuICAgICAgICAgICAgICAgIGZuKHNlY3Rpb24udGV4dENvbG9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIG91dHB1dERlZmluZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIC8vIFRlY2huaWNhbGx5IHRoZSBjb21iaW5hdG9yaWMgc2V0IG9mIGFsbCBjaGlsZHJlblxuICAgICAgICAvLyBVc3VhbGx5LCB0aGlzLnRleHQgd2lsbCBiZSB1bmRlZmluZWQgYW55d2F5XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBzZXJpYWxpemUoKTogU2VyaWFsaXplZEV4cHJlc3Npb24ge1xuICAgICAgICBjb25zdCBzZXJpYWxpemVkID0gW1wiZm9ybWF0XCJdO1xuICAgICAgICBmb3IgKGNvbnN0IHNlY3Rpb24gb2YgdGhpcy5zZWN0aW9ucykge1xuICAgICAgICAgICAgc2VyaWFsaXplZC5wdXNoKHNlY3Rpb24uY29udGVudC5zZXJpYWxpemUoKSk7XG4gICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge307XG4gICAgICAgICAgICBpZiAoc2VjdGlvbi5zY2FsZSkge1xuICAgICAgICAgICAgICAgIG9wdGlvbnNbJ2ZvbnQtc2NhbGUnXSA9IHNlY3Rpb24uc2NhbGUuc2VyaWFsaXplKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoc2VjdGlvbi5mb250KSB7XG4gICAgICAgICAgICAgICAgb3B0aW9uc1sndGV4dC1mb250J10gPSBzZWN0aW9uLmZvbnQuc2VyaWFsaXplKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoc2VjdGlvbi50ZXh0Q29sb3IpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zWyd0ZXh0LWNvbG9yJ10gPSBzZWN0aW9uLnRleHRDb2xvci5zZXJpYWxpemUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNlcmlhbGl6ZWQucHVzaChvcHRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2VyaWFsaXplZDtcbiAgICB9XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge1Jlc29sdmVkSW1hZ2VUeXBlLCBTdHJpbmdUeXBlfSBmcm9tICcuLi90eXBlcy5qcyc7XG5pbXBvcnQgUmVzb2x2ZWRJbWFnZSBmcm9tICcuLi90eXBlcy9yZXNvbHZlZF9pbWFnZS5qcyc7XG5cbmltcG9ydCB0eXBlIHtFeHByZXNzaW9uLCBTZXJpYWxpemVkRXhwcmVzc2lvbn0gZnJvbSAnLi4vZXhwcmVzc2lvbi5qcyc7XG5pbXBvcnQgdHlwZSBFdmFsdWF0aW9uQ29udGV4dCBmcm9tICcuLi9ldmFsdWF0aW9uX2NvbnRleHQuanMnO1xuaW1wb3J0IHR5cGUgUGFyc2luZ0NvbnRleHQgZnJvbSAnLi4vcGFyc2luZ19jb250ZXh0LmpzJztcbmltcG9ydCB0eXBlIHtUeXBlfSBmcm9tICcuLi90eXBlcy5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEltYWdlRXhwcmVzc2lvbiBpbXBsZW1lbnRzIEV4cHJlc3Npb24ge1xuICAgIHR5cGU6IFR5cGU7XG4gICAgaW5wdXQ6IEV4cHJlc3Npb247XG5cbiAgICBjb25zdHJ1Y3RvcihpbnB1dDogRXhwcmVzc2lvbikge1xuICAgICAgICB0aGlzLnR5cGUgPSBSZXNvbHZlZEltYWdlVHlwZTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IGlucHV0O1xuICAgIH1cblxuICAgIHN0YXRpYyBwYXJzZShhcmdzOiAkUmVhZE9ubHlBcnJheTxtaXhlZD4sIGNvbnRleHQ6IFBhcnNpbmdDb250ZXh0KTogP0V4cHJlc3Npb24ge1xuICAgICAgICBpZiAoYXJncy5sZW5ndGggIT09IDIpIHtcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmVycm9yKGBFeHBlY3RlZCB0d28gYXJndW1lbnRzLmApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbmFtZSA9IGNvbnRleHQucGFyc2UoYXJnc1sxXSwgMSwgU3RyaW5nVHlwZSk7XG4gICAgICAgIGlmICghbmFtZSkgcmV0dXJuIGNvbnRleHQuZXJyb3IoYE5vIGltYWdlIG5hbWUgcHJvdmlkZWQuYCk7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBJbWFnZUV4cHJlc3Npb24obmFtZSk7XG4gICAgfVxuXG4gICAgZXZhbHVhdGUoY3R4OiBFdmFsdWF0aW9uQ29udGV4dCk6IG51bGwgfCBSZXNvbHZlZEltYWdlIHtcbiAgICAgICAgY29uc3QgZXZhbHVhdGVkSW1hZ2VOYW1lID0gdGhpcy5pbnB1dC5ldmFsdWF0ZShjdHgpO1xuXG4gICAgICAgIGNvbnN0IHZhbHVlID0gUmVzb2x2ZWRJbWFnZS5mcm9tU3RyaW5nKGV2YWx1YXRlZEltYWdlTmFtZSk7XG4gICAgICAgIGlmICh2YWx1ZSAmJiBjdHguYXZhaWxhYmxlSW1hZ2VzKSB2YWx1ZS5hdmFpbGFibGUgPSBjdHguYXZhaWxhYmxlSW1hZ2VzLmluZGV4T2YoZXZhbHVhdGVkSW1hZ2VOYW1lKSA+IC0xO1xuXG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICBlYWNoQ2hpbGQoZm46IChfOiBFeHByZXNzaW9uKSA9PiB2b2lkKSB7XG4gICAgICAgIGZuKHRoaXMuaW5wdXQpO1xuICAgIH1cblxuICAgIG91dHB1dERlZmluZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIC8vIFRoZSBvdXRwdXQgb2YgaW1hZ2UgaXMgZGV0ZXJtaW5lZCBieSB0aGUgbGlzdCBvZiBhdmFpbGFibGUgaW1hZ2VzIGluIHRoZSBldmFsdWF0aW9uIGNvbnRleHRcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHNlcmlhbGl6ZSgpOiBTZXJpYWxpemVkRXhwcmVzc2lvbiB7XG4gICAgICAgIHJldHVybiBbXCJpbWFnZVwiLCB0aGlzLmlucHV0LnNlcmlhbGl6ZSgpXTtcbiAgICB9XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbmltcG9ydCB7Qm9vbGVhblR5cGUsIENvbG9yVHlwZSwgTnVtYmVyVHlwZSwgU3RyaW5nVHlwZSwgVmFsdWVUeXBlfSBmcm9tICcuLi90eXBlcy5qcyc7XG5pbXBvcnQge0NvbG9yLCB0b1N0cmluZyBhcyB2YWx1ZVRvU3RyaW5nLCB2YWxpZGF0ZVJHQkF9IGZyb20gJy4uL3ZhbHVlcy5qcyc7XG5pbXBvcnQgUnVudGltZUVycm9yIGZyb20gJy4uL3J1bnRpbWVfZXJyb3IuanMnO1xuaW1wb3J0IEZvcm1hdHRlZCBmcm9tICcuLi90eXBlcy9mb3JtYXR0ZWQuanMnO1xuaW1wb3J0IEZvcm1hdEV4cHJlc3Npb24gZnJvbSAnLi4vZGVmaW5pdGlvbnMvZm9ybWF0LmpzJztcbmltcG9ydCBJbWFnZUV4cHJlc3Npb24gZnJvbSAnLi4vZGVmaW5pdGlvbnMvaW1hZ2UuanMnO1xuaW1wb3J0IFJlc29sdmVkSW1hZ2UgZnJvbSAnLi4vdHlwZXMvcmVzb2x2ZWRfaW1hZ2UuanMnO1xuXG5pbXBvcnQgdHlwZSB7RXhwcmVzc2lvbiwgU2VyaWFsaXplZEV4cHJlc3Npb259IGZyb20gJy4uL2V4cHJlc3Npb24uanMnO1xuaW1wb3J0IHR5cGUgUGFyc2luZ0NvbnRleHQgZnJvbSAnLi4vcGFyc2luZ19jb250ZXh0LmpzJztcbmltcG9ydCB0eXBlIEV2YWx1YXRpb25Db250ZXh0IGZyb20gJy4uL2V2YWx1YXRpb25fY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSB7VHlwZX0gZnJvbSAnLi4vdHlwZXMuanMnO1xuXG5jb25zdCB0eXBlcyA9IHtcbiAgICAndG8tYm9vbGVhbic6IEJvb2xlYW5UeXBlLFxuICAgICd0by1jb2xvcic6IENvbG9yVHlwZSxcbiAgICAndG8tbnVtYmVyJzogTnVtYmVyVHlwZSxcbiAgICAndG8tc3RyaW5nJzogU3RyaW5nVHlwZVxufTtcblxuLyoqXG4gKiBTcGVjaWFsIGZvcm0gZm9yIGVycm9yLWNvYWxlc2NpbmcgY29lcmNpb24gZXhwcmVzc2lvbnMgXCJ0by1udW1iZXJcIixcbiAqIFwidG8tY29sb3JcIi4gIFNpbmNlIHRoZXNlIGNvZXJjaW9ucyBjYW4gZmFpbCBhdCBydW50aW1lLCB0aGV5IGFjY2VwdCBtdWx0aXBsZVxuICogYXJndW1lbnRzLCBvbmx5IGV2YWx1YXRpbmcgb25lIGF0IGEgdGltZSB1bnRpbCBvbmUgc3VjY2VlZHMuXG4gKlxuICogQHByaXZhdGVcbiAqL1xuY2xhc3MgQ29lcmNpb24gaW1wbGVtZW50cyBFeHByZXNzaW9uIHtcbiAgICB0eXBlOiBUeXBlO1xuICAgIGFyZ3M6IEFycmF5PEV4cHJlc3Npb24+O1xuXG4gICAgY29uc3RydWN0b3IodHlwZTogVHlwZSwgYXJnczogQXJyYXk8RXhwcmVzc2lvbj4pIHtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5hcmdzID0gYXJncztcbiAgICB9XG5cbiAgICBzdGF0aWMgcGFyc2UoYXJnczogJFJlYWRPbmx5QXJyYXk8bWl4ZWQ+LCBjb250ZXh0OiBQYXJzaW5nQ29udGV4dCk6ID9FeHByZXNzaW9uIHtcbiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoIDwgMilcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmVycm9yKGBFeHBlY3RlZCBhdCBsZWFzdCBvbmUgYXJndW1lbnQuYCk7XG5cbiAgICAgICAgY29uc3QgbmFtZTogc3RyaW5nID0gKGFyZ3NbMF06IGFueSk7XG4gICAgICAgIGFzc2VydCh0eXBlc1tuYW1lXSwgbmFtZSk7XG5cbiAgICAgICAgaWYgKChuYW1lID09PSAndG8tYm9vbGVhbicgfHwgbmFtZSA9PT0gJ3RvLXN0cmluZycpICYmIGFyZ3MubGVuZ3RoICE9PSAyKVxuICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQuZXJyb3IoYEV4cGVjdGVkIG9uZSBhcmd1bWVudC5gKTtcblxuICAgICAgICBjb25zdCB0eXBlID0gdHlwZXNbbmFtZV07XG5cbiAgICAgICAgY29uc3QgcGFyc2VkID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgaW5wdXQgPSBjb250ZXh0LnBhcnNlKGFyZ3NbaV0sIGksIFZhbHVlVHlwZSk7XG4gICAgICAgICAgICBpZiAoIWlucHV0KSByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIHBhcnNlZC5wdXNoKGlucHV0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXcgQ29lcmNpb24odHlwZSwgcGFyc2VkKTtcbiAgICB9XG5cbiAgICBldmFsdWF0ZShjdHg6IEV2YWx1YXRpb25Db250ZXh0KTogbnVsbCB8IGJvb2xlYW4gfCBudW1iZXIgfCBzdHJpbmcgfCBDb2xvciB8IEZvcm1hdHRlZCB8IFJlc29sdmVkSW1hZ2Uge1xuICAgICAgICBpZiAodGhpcy50eXBlLmtpbmQgPT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgcmV0dXJuIEJvb2xlYW4odGhpcy5hcmdzWzBdLmV2YWx1YXRlKGN0eCkpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMudHlwZS5raW5kID09PSAnY29sb3InKSB7XG4gICAgICAgICAgICBsZXQgaW5wdXQ7XG4gICAgICAgICAgICBsZXQgZXJyb3I7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGFyZyBvZiB0aGlzLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICBpbnB1dCA9IGFyZy5ldmFsdWF0ZShjdHgpO1xuICAgICAgICAgICAgICAgIGVycm9yID0gbnVsbDtcbiAgICAgICAgICAgICAgICBpZiAoaW5wdXQgaW5zdGFuY2VvZiBDb2xvcikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXQ7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaW5wdXQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGMgPSBjdHgucGFyc2VDb2xvcihpbnB1dCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjKSByZXR1cm4gYztcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoaW5wdXQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpbnB1dC5sZW5ndGggPCAzIHx8IGlucHV0Lmxlbmd0aCA+IDQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gYEludmFsaWQgcmJnYSB2YWx1ZSAke0pTT04uc3RyaW5naWZ5KGlucHV0KX06IGV4cGVjdGVkIGFuIGFycmF5IGNvbnRhaW5pbmcgZWl0aGVyIHRocmVlIG9yIGZvdXIgbnVtZXJpYyB2YWx1ZXMuYDtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gdmFsaWRhdGVSR0JBKGlucHV0WzBdLCBpbnB1dFsxXSwgaW5wdXRbMl0sIGlucHV0WzNdKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IENvbG9yKChpbnB1dFswXTogYW55KSAvIDI1NSwgKGlucHV0WzFdOiBhbnkpIC8gMjU1LCAoaW5wdXRbMl06IGFueSkgLyAyNTUsIChpbnB1dFszXTogYW55KSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUVycm9yKGVycm9yIHx8IGBDb3VsZCBub3QgcGFyc2UgY29sb3IgZnJvbSB2YWx1ZSAnJHt0eXBlb2YgaW5wdXQgPT09ICdzdHJpbmcnID8gaW5wdXQgOiBTdHJpbmcoSlNPTi5zdHJpbmdpZnkoaW5wdXQpKX0nYCk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy50eXBlLmtpbmQgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICBsZXQgdmFsdWUgPSBudWxsO1xuICAgICAgICAgICAgZm9yIChjb25zdCBhcmcgb2YgdGhpcy5hcmdzKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBhcmcuZXZhbHVhdGUoY3R4KTtcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT09IG51bGwpIHJldHVybiAwO1xuICAgICAgICAgICAgICAgIGNvbnN0IG51bSA9IE51bWJlcih2YWx1ZSk7XG4gICAgICAgICAgICAgICAgaWYgKGlzTmFOKG51bSkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIHJldHVybiBudW07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUVycm9yKGBDb3VsZCBub3QgY29udmVydCAke0pTT04uc3RyaW5naWZ5KHZhbHVlKX0gdG8gbnVtYmVyLmApO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMudHlwZS5raW5kID09PSAnZm9ybWF0dGVkJykge1xuICAgICAgICAgICAgLy8gVGhlcmUgaXMgbm8gZXhwbGljaXQgJ3RvLWZvcm1hdHRlZCcgYnV0IHRoaXMgY29lcmNpb24gY2FuIGJlIGltcGxpY2l0bHlcbiAgICAgICAgICAgIC8vIGNyZWF0ZWQgYnkgcHJvcGVydGllcyB0aGF0IGV4cGVjdCB0aGUgJ2Zvcm1hdHRlZCcgdHlwZS5cbiAgICAgICAgICAgIHJldHVybiBGb3JtYXR0ZWQuZnJvbVN0cmluZyh2YWx1ZVRvU3RyaW5nKHRoaXMuYXJnc1swXS5ldmFsdWF0ZShjdHgpKSk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy50eXBlLmtpbmQgPT09ICdyZXNvbHZlZEltYWdlJykge1xuICAgICAgICAgICAgcmV0dXJuIFJlc29sdmVkSW1hZ2UuZnJvbVN0cmluZyh2YWx1ZVRvU3RyaW5nKHRoaXMuYXJnc1swXS5ldmFsdWF0ZShjdHgpKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWVUb1N0cmluZyh0aGlzLmFyZ3NbMF0uZXZhbHVhdGUoY3R4KSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBlYWNoQ2hpbGQoZm46IChfOiBFeHByZXNzaW9uKSA9PiB2b2lkKSB7XG4gICAgICAgIHRoaXMuYXJncy5mb3JFYWNoKGZuKTtcbiAgICB9XG5cbiAgICBvdXRwdXREZWZpbmVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5hcmdzLmV2ZXJ5KGFyZyA9PiBhcmcub3V0cHV0RGVmaW5lZCgpKTtcbiAgICB9XG5cbiAgICBzZXJpYWxpemUoKTogU2VyaWFsaXplZEV4cHJlc3Npb24ge1xuICAgICAgICBpZiAodGhpcy50eXBlLmtpbmQgPT09ICdmb3JtYXR0ZWQnKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEZvcm1hdEV4cHJlc3Npb24oW3tjb250ZW50OiB0aGlzLmFyZ3NbMF0sIHNjYWxlOiBudWxsLCBmb250OiBudWxsLCB0ZXh0Q29sb3I6IG51bGx9XSkuc2VyaWFsaXplKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy50eXBlLmtpbmQgPT09ICdyZXNvbHZlZEltYWdlJykge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBJbWFnZUV4cHJlc3Npb24odGhpcy5hcmdzWzBdKS5zZXJpYWxpemUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNlcmlhbGl6ZWQgPSBbYHRvLSR7dGhpcy50eXBlLmtpbmR9YF07XG4gICAgICAgIHRoaXMuZWFjaENoaWxkKGNoaWxkID0+IHsgc2VyaWFsaXplZC5wdXNoKGNoaWxkLnNlcmlhbGl6ZSgpKTsgfSk7XG4gICAgICAgIHJldHVybiBzZXJpYWxpemVkO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ29lcmNpb247XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge0NvbG9yfSBmcm9tICcuL3ZhbHVlcy5qcyc7XG5cbmltcG9ydCB0eXBlIFBvaW50IGZyb20gJ0BtYXBib3gvcG9pbnQtZ2VvbWV0cnknO1xuaW1wb3J0IHR5cGUge0Zvcm1hdHRlZFNlY3Rpb259IGZyb20gJy4vdHlwZXMvZm9ybWF0dGVkLmpzJztcbmltcG9ydCB0eXBlIHtHbG9iYWxQcm9wZXJ0aWVzLCBGZWF0dXJlLCBGZWF0dXJlU3RhdGV9IGZyb20gJy4vaW5kZXguanMnO1xuaW1wb3J0IHR5cGUge0Nhbm9uaWNhbFRpbGVJRH0gZnJvbSAnLi4vLi4vc291cmNlL3RpbGVfaWQuanMnO1xuaW1wb3J0IHR5cGUge0ZlYXR1cmVEaXN0YW5jZURhdGF9IGZyb20gJy4uL2ZlYXR1cmVfZmlsdGVyL2luZGV4LmpzJztcblxuY29uc3QgZ2VvbWV0cnlUeXBlcyA9IFsnVW5rbm93bicsICdQb2ludCcsICdMaW5lU3RyaW5nJywgJ1BvbHlnb24nXTtcblxuY2xhc3MgRXZhbHVhdGlvbkNvbnRleHQge1xuICAgIGdsb2JhbHM6IEdsb2JhbFByb3BlcnRpZXM7XG4gICAgZmVhdHVyZTogP0ZlYXR1cmU7XG4gICAgZmVhdHVyZVN0YXRlOiA/RmVhdHVyZVN0YXRlO1xuICAgIGZvcm1hdHRlZFNlY3Rpb246ID9Gb3JtYXR0ZWRTZWN0aW9uO1xuICAgIGF2YWlsYWJsZUltYWdlczogP0FycmF5PHN0cmluZz47XG4gICAgY2Fub25pY2FsOiBudWxsIHwgQ2Fub25pY2FsVGlsZUlEO1xuICAgIGZlYXR1cmVUaWxlQ29vcmQ6ID9Qb2ludDtcbiAgICBmZWF0dXJlRGlzdGFuY2VEYXRhOiA/RmVhdHVyZURpc3RhbmNlRGF0YTtcblxuICAgIF9wYXJzZUNvbG9yQ2FjaGU6IHtbXzogc3RyaW5nXTogP0NvbG9yfTtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLmdsb2JhbHMgPSAobnVsbDogYW55KTtcbiAgICAgICAgdGhpcy5mZWF0dXJlID0gbnVsbDtcbiAgICAgICAgdGhpcy5mZWF0dXJlU3RhdGUgPSBudWxsO1xuICAgICAgICB0aGlzLmZvcm1hdHRlZFNlY3Rpb24gPSBudWxsO1xuICAgICAgICB0aGlzLl9wYXJzZUNvbG9yQ2FjaGUgPSB7fTtcbiAgICAgICAgdGhpcy5hdmFpbGFibGVJbWFnZXMgPSBudWxsO1xuICAgICAgICB0aGlzLmNhbm9uaWNhbCA9IG51bGw7XG4gICAgICAgIHRoaXMuZmVhdHVyZVRpbGVDb29yZCA9IG51bGw7XG4gICAgICAgIHRoaXMuZmVhdHVyZURpc3RhbmNlRGF0YSA9IG51bGw7XG4gICAgfVxuXG4gICAgaWQoKTogbnVtYmVyIHwgbnVsbCB7XG4gICAgICAgIHJldHVybiB0aGlzLmZlYXR1cmUgJiYgdGhpcy5mZWF0dXJlLmlkICE9PSB1bmRlZmluZWQgPyB0aGlzLmZlYXR1cmUuaWQgOiBudWxsO1xuICAgIH1cblxuICAgIGdlb21ldHJ5VHlwZSgpOiBudWxsIHwgc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZmVhdHVyZSA/IHR5cGVvZiB0aGlzLmZlYXR1cmUudHlwZSA9PT0gJ251bWJlcicgPyBnZW9tZXRyeVR5cGVzW3RoaXMuZmVhdHVyZS50eXBlXSA6IHRoaXMuZmVhdHVyZS50eXBlIDogbnVsbDtcbiAgICB9XG5cbiAgICBnZW9tZXRyeSgpOiA/QXJyYXk8QXJyYXk8UG9pbnQ+PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmZlYXR1cmUgJiYgJ2dlb21ldHJ5JyBpbiB0aGlzLmZlYXR1cmUgPyB0aGlzLmZlYXR1cmUuZ2VvbWV0cnkgOiBudWxsO1xuICAgIH1cblxuICAgIGNhbm9uaWNhbElEKCk6IG51bGwgfCBDYW5vbmljYWxUaWxlSUQge1xuICAgICAgICByZXR1cm4gdGhpcy5jYW5vbmljYWw7XG4gICAgfVxuXG4gICAgcHJvcGVydGllcygpOiB7W3N0cmluZ106IGFueX0ge1xuICAgICAgICByZXR1cm4gKHRoaXMuZmVhdHVyZSAmJiB0aGlzLmZlYXR1cmUucHJvcGVydGllcykgfHwge307XG4gICAgfVxuXG4gICAgZGlzdGFuY2VGcm9tQ2VudGVyKCk6IG51bWJlciB7XG4gICAgICAgIGlmICh0aGlzLmZlYXR1cmVUaWxlQ29vcmQgJiYgdGhpcy5mZWF0dXJlRGlzdGFuY2VEYXRhKSB7XG5cbiAgICAgICAgICAgIGNvbnN0IGMgPSB0aGlzLmZlYXR1cmVEaXN0YW5jZURhdGEuY2VudGVyO1xuICAgICAgICAgICAgY29uc3Qgc2NhbGUgPSB0aGlzLmZlYXR1cmVEaXN0YW5jZURhdGEuc2NhbGU7XG4gICAgICAgICAgICBjb25zdCB7eCwgeX0gPSB0aGlzLmZlYXR1cmVUaWxlQ29vcmQ7XG5cbiAgICAgICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgZGlzdGFuY2UgdmVjdG9yIGBkYCAobGVmdCBoYW5kZWQpXG4gICAgICAgICAgICBjb25zdCBkWCA9IHggKiBzY2FsZSAtIGNbMF07XG4gICAgICAgICAgICBjb25zdCBkWSA9IHkgKiBzY2FsZSAtIGNbMV07XG5cbiAgICAgICAgICAgIC8vIFRoZSBiZWFyaW5nIHZlY3RvciBgYmAgKGxlZnQgaGFuZGVkKVxuICAgICAgICAgICAgY29uc3QgYlggPSB0aGlzLmZlYXR1cmVEaXN0YW5jZURhdGEuYmVhcmluZ1swXTtcbiAgICAgICAgICAgIGNvbnN0IGJZID0gdGhpcy5mZWF0dXJlRGlzdGFuY2VEYXRhLmJlYXJpbmdbMV07XG5cbiAgICAgICAgICAgIC8vIERpc3RhbmNlIGlzIGNhbGN1bGF0ZWQgYXMgYGRvdChkLCB2KWBcbiAgICAgICAgICAgIGNvbnN0IGRpc3QgPSAoYlggKiBkWCArIGJZICogZFkpO1xuICAgICAgICAgICAgcmV0dXJuIGRpc3Q7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICBwYXJzZUNvbG9yKGlucHV0OiBzdHJpbmcpOiA/Q29sb3Ige1xuICAgICAgICBsZXQgY2FjaGVkID0gdGhpcy5fcGFyc2VDb2xvckNhY2hlW2lucHV0XTtcbiAgICAgICAgaWYgKCFjYWNoZWQpIHtcbiAgICAgICAgICAgIGNhY2hlZCA9IHRoaXMuX3BhcnNlQ29sb3JDYWNoZVtpbnB1dF0gPSBDb2xvci5wYXJzZShpbnB1dCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNhY2hlZDtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEV2YWx1YXRpb25Db250ZXh0O1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHt0b1N0cmluZ30gZnJvbSAnLi90eXBlcy5qcyc7XG5cbmltcG9ydCBQYXJzaW5nQ29udGV4dCBmcm9tICcuL3BhcnNpbmdfY29udGV4dC5qcyc7XG5pbXBvcnQgRXZhbHVhdGlvbkNvbnRleHQgZnJvbSAnLi9ldmFsdWF0aW9uX2NvbnRleHQuanMnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuXG5pbXBvcnQgdHlwZSB7RXhwcmVzc2lvbiwgRXhwcmVzc2lvblJlZ2lzdHJ5fSBmcm9tICcuL2V4cHJlc3Npb24uanMnO1xuaW1wb3J0IHR5cGUge1R5cGV9IGZyb20gJy4vdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge1ZhbHVlfSBmcm9tICcuL3ZhbHVlcy5qcyc7XG5cbmV4cG9ydCB0eXBlIFZhcmFyZ3MgPSB7fCB0eXBlOiBUeXBlIHx9O1xudHlwZSBTaWduYXR1cmUgPSBBcnJheTxUeXBlPiB8IFZhcmFyZ3M7XG50eXBlIEV2YWx1YXRlID0gKEV2YWx1YXRpb25Db250ZXh0LCBBcnJheTxFeHByZXNzaW9uPikgPT4gVmFsdWU7XG50eXBlIERlZmluaXRpb24gPSBbVHlwZSwgU2lnbmF0dXJlLCBFdmFsdWF0ZV0gfFxuICAgIHt8dHlwZTogVHlwZSwgb3ZlcmxvYWRzOiBBcnJheTxbU2lnbmF0dXJlLCBFdmFsdWF0ZV0+fH07XG5cbmNsYXNzIENvbXBvdW5kRXhwcmVzc2lvbiBpbXBsZW1lbnRzIEV4cHJlc3Npb24ge1xuICAgIG5hbWU6IHN0cmluZztcbiAgICB0eXBlOiBUeXBlO1xuICAgIF9ldmFsdWF0ZTogRXZhbHVhdGU7XG4gICAgYXJnczogQXJyYXk8RXhwcmVzc2lvbj47XG5cbiAgICBzdGF0aWMgZGVmaW5pdGlvbnM6IHtbXzogc3RyaW5nXTogRGVmaW5pdGlvbiB9O1xuXG4gICAgY29uc3RydWN0b3IobmFtZTogc3RyaW5nLCB0eXBlOiBUeXBlLCBldmFsdWF0ZTogRXZhbHVhdGUsIGFyZ3M6IEFycmF5PEV4cHJlc3Npb24+KSB7XG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuX2V2YWx1YXRlID0gZXZhbHVhdGU7XG4gICAgICAgIHRoaXMuYXJncyA9IGFyZ3M7XG4gICAgfVxuXG4gICAgZXZhbHVhdGUoY3R4OiBFdmFsdWF0aW9uQ29udGV4dCk6IFZhbHVlIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2YWx1YXRlKGN0eCwgdGhpcy5hcmdzKTtcbiAgICB9XG5cbiAgICBlYWNoQ2hpbGQoZm46IChfOiBFeHByZXNzaW9uKSA9PiB2b2lkKSB7XG4gICAgICAgIHRoaXMuYXJncy5mb3JFYWNoKGZuKTtcbiAgICB9XG5cbiAgICBvdXRwdXREZWZpbmVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgc2VyaWFsaXplKCk6IEFycmF5PG1peGVkPiB7XG4gICAgICAgIHJldHVybiBbdGhpcy5uYW1lXS5jb25jYXQodGhpcy5hcmdzLm1hcChhcmcgPT4gYXJnLnNlcmlhbGl6ZSgpKSk7XG4gICAgfVxuXG4gICAgc3RhdGljIHBhcnNlKGFyZ3M6ICRSZWFkT25seUFycmF5PG1peGVkPiwgY29udGV4dDogUGFyc2luZ0NvbnRleHQpOiA/RXhwcmVzc2lvbiB7XG4gICAgICAgIGNvbnN0IG9wOiBzdHJpbmcgPSAoYXJnc1swXTogYW55KTtcbiAgICAgICAgY29uc3QgZGVmaW5pdGlvbiA9IENvbXBvdW5kRXhwcmVzc2lvbi5kZWZpbml0aW9uc1tvcF07XG4gICAgICAgIGlmICghZGVmaW5pdGlvbikge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQuZXJyb3IoYFVua25vd24gZXhwcmVzc2lvbiBcIiR7b3B9XCIuIElmIHlvdSB3YW50ZWQgYSBsaXRlcmFsIGFycmF5LCB1c2UgW1wibGl0ZXJhbFwiLCBbLi4uXV0uYCwgMCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBOb3cgY2hlY2sgYXJndW1lbnQgdHlwZXMgYWdhaW5zdCBlYWNoIHNpZ25hdHVyZVxuICAgICAgICBjb25zdCB0eXBlID0gQXJyYXkuaXNBcnJheShkZWZpbml0aW9uKSA/XG4gICAgICAgICAgICBkZWZpbml0aW9uWzBdIDogZGVmaW5pdGlvbi50eXBlO1xuXG4gICAgICAgIGNvbnN0IGF2YWlsYWJsZU92ZXJsb2FkcyA9IEFycmF5LmlzQXJyYXkoZGVmaW5pdGlvbikgP1xuICAgICAgICAgICAgW1tkZWZpbml0aW9uWzFdLCBkZWZpbml0aW9uWzJdXV0gOlxuICAgICAgICAgICAgZGVmaW5pdGlvbi5vdmVybG9hZHM7XG5cbiAgICAgICAgY29uc3Qgb3ZlcmxvYWRzID0gYXZhaWxhYmxlT3ZlcmxvYWRzLmZpbHRlcigoW3NpZ25hdHVyZV0pID0+IChcbiAgICAgICAgICAgICFBcnJheS5pc0FycmF5KHNpZ25hdHVyZSkgfHwgLy8gdmFyYWdzXG4gICAgICAgICAgICBzaWduYXR1cmUubGVuZ3RoID09PSBhcmdzLmxlbmd0aCAtIDEgLy8gY29ycmVjdCBwYXJhbSBjb3VudFxuICAgICAgICApKTtcblxuICAgICAgICBsZXQgc2lnbmF0dXJlQ29udGV4dDogUGFyc2luZ0NvbnRleHQgPSAobnVsbDogYW55KTtcblxuICAgICAgICBmb3IgKGNvbnN0IFtwYXJhbXMsIGV2YWx1YXRlXSBvZiBvdmVybG9hZHMpIHtcbiAgICAgICAgICAgIC8vIFVzZSBhIGZyZXNoIGNvbnRleHQgZm9yIGVhY2ggYXR0ZW1wdGVkIHNpZ25hdHVyZSBzbyB0aGF0LCBpZlxuICAgICAgICAgICAgLy8gd2UgZXZlbnR1YWxseSBzdWNjZWVkLCB3ZSBoYXZlbid0IHBvbGx1dGVkIGBjb250ZXh0LmVycm9yc2AuXG4gICAgICAgICAgICBzaWduYXR1cmVDb250ZXh0ID0gbmV3IFBhcnNpbmdDb250ZXh0KGNvbnRleHQucmVnaXN0cnksIGNvbnRleHQucGF0aCwgbnVsbCwgY29udGV4dC5zY29wZSk7XG5cbiAgICAgICAgICAgIC8vIEZpcnN0IHBhcnNlIGFsbCB0aGUgYXJncywgcG90ZW50aWFsbHkgY29lcmNpbmcgdG8gdGhlXG4gICAgICAgICAgICAvLyB0eXBlcyBleHBlY3RlZCBieSB0aGlzIG92ZXJsb2FkLlxuICAgICAgICAgICAgY29uc3QgcGFyc2VkQXJnczogQXJyYXk8RXhwcmVzc2lvbj4gPSBbXTtcbiAgICAgICAgICAgIGxldCBhcmdQYXJzZUZhaWxlZCA9IGZhbHNlO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgYXJnID0gYXJnc1tpXTtcbiAgICAgICAgICAgICAgICBjb25zdCBleHBlY3RlZFR5cGUgPSBBcnJheS5pc0FycmF5KHBhcmFtcykgP1xuICAgICAgICAgICAgICAgICAgICBwYXJhbXNbaSAtIDFdIDpcbiAgICAgICAgICAgICAgICAgICAgcGFyYW1zLnR5cGU7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBwYXJzZWQgPSBzaWduYXR1cmVDb250ZXh0LnBhcnNlKGFyZywgMSArIHBhcnNlZEFyZ3MubGVuZ3RoLCBleHBlY3RlZFR5cGUpO1xuICAgICAgICAgICAgICAgIGlmICghcGFyc2VkKSB7XG4gICAgICAgICAgICAgICAgICAgIGFyZ1BhcnNlRmFpbGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHBhcnNlZEFyZ3MucHVzaChwYXJzZWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGFyZ1BhcnNlRmFpbGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gQ291bGRuJ3QgY29lcmNlIGFyZ3Mgb2YgdGhpcyBvdmVybG9hZCB0byBleHBlY3RlZCB0eXBlLCBtb3ZlXG4gICAgICAgICAgICAgICAgLy8gb24gdG8gbmV4dCBvbmUuXG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHBhcmFtcykpIHtcbiAgICAgICAgICAgICAgICBpZiAocGFyYW1zLmxlbmd0aCAhPT0gcGFyc2VkQXJncy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgc2lnbmF0dXJlQ29udGV4dC5lcnJvcihgRXhwZWN0ZWQgJHtwYXJhbXMubGVuZ3RofSBhcmd1bWVudHMsIGJ1dCBmb3VuZCAke3BhcnNlZEFyZ3MubGVuZ3RofSBpbnN0ZWFkLmApO1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFyc2VkQXJncy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGV4cGVjdGVkID0gQXJyYXkuaXNBcnJheShwYXJhbXMpID8gcGFyYW1zW2ldIDogcGFyYW1zLnR5cGU7XG4gICAgICAgICAgICAgICAgY29uc3QgYXJnID0gcGFyc2VkQXJnc1tpXTtcbiAgICAgICAgICAgICAgICBzaWduYXR1cmVDb250ZXh0LmNvbmNhdChpICsgMSkuY2hlY2tTdWJ0eXBlKGV4cGVjdGVkLCBhcmcudHlwZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChzaWduYXR1cmVDb250ZXh0LmVycm9ycy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IENvbXBvdW5kRXhwcmVzc2lvbihvcCwgdHlwZSwgZXZhbHVhdGUsIHBhcnNlZEFyZ3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgYXNzZXJ0KCFzaWduYXR1cmVDb250ZXh0IHx8IHNpZ25hdHVyZUNvbnRleHQuZXJyb3JzLmxlbmd0aCA+IDApO1xuXG4gICAgICAgIGlmIChvdmVybG9hZHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICBjb250ZXh0LmVycm9ycy5wdXNoKC4uLnNpZ25hdHVyZUNvbnRleHQuZXJyb3JzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGV4cGVjdGVkID0gb3ZlcmxvYWRzLmxlbmd0aCA/IG92ZXJsb2FkcyA6IGF2YWlsYWJsZU92ZXJsb2FkcztcbiAgICAgICAgICAgIGNvbnN0IHNpZ25hdHVyZXMgPSBleHBlY3RlZFxuICAgICAgICAgICAgICAgIC5tYXAoKFtwYXJhbXNdKSA9PiBzdHJpbmdpZnlTaWduYXR1cmUocGFyYW1zKSlcbiAgICAgICAgICAgICAgICAuam9pbignIHwgJyk7XG5cbiAgICAgICAgICAgIGNvbnN0IGFjdHVhbFR5cGVzID0gW107XG4gICAgICAgICAgICAvLyBGb3IgZXJyb3IgbWVzc2FnZSwgcmUtcGFyc2UgYXJndW1lbnRzIHdpdGhvdXQgdHJ5aW5nIHRvXG4gICAgICAgICAgICAvLyBhcHBseSBhbnkgY29lcmNpb25zXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJzZWQgPSBjb250ZXh0LnBhcnNlKGFyZ3NbaV0sIDEgKyBhY3R1YWxUeXBlcy5sZW5ndGgpO1xuICAgICAgICAgICAgICAgIGlmICghcGFyc2VkKSByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICBhY3R1YWxUeXBlcy5wdXNoKHRvU3RyaW5nKHBhcnNlZC50eXBlKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb250ZXh0LmVycm9yKGBFeHBlY3RlZCBhcmd1bWVudHMgb2YgdHlwZSAke3NpZ25hdHVyZXN9LCBidXQgZm91bmQgKCR7YWN0dWFsVHlwZXMuam9pbignLCAnKX0pIGluc3RlYWQuYCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBzdGF0aWMgcmVnaXN0ZXIoXG4gICAgICAgIHJlZ2lzdHJ5OiBFeHByZXNzaW9uUmVnaXN0cnksXG4gICAgICAgIGRlZmluaXRpb25zOiB7W186IHN0cmluZ106IERlZmluaXRpb24gfVxuICAgICkge1xuICAgICAgICBhc3NlcnQoIUNvbXBvdW5kRXhwcmVzc2lvbi5kZWZpbml0aW9ucyk7XG4gICAgICAgIENvbXBvdW5kRXhwcmVzc2lvbi5kZWZpbml0aW9ucyA9IGRlZmluaXRpb25zO1xuICAgICAgICBmb3IgKGNvbnN0IG5hbWUgaW4gZGVmaW5pdGlvbnMpIHtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIHJlZ2lzdHJ5W25hbWVdID0gQ29tcG91bmRFeHByZXNzaW9uO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBzdHJpbmdpZnlTaWduYXR1cmUoc2lnbmF0dXJlOiBTaWduYXR1cmUpOiBzdHJpbmcge1xuICAgIGlmIChBcnJheS5pc0FycmF5KHNpZ25hdHVyZSkpIHtcbiAgICAgICAgcmV0dXJuIGAoJHtzaWduYXR1cmUubWFwKHRvU3RyaW5nKS5qb2luKCcsICcpfSlgO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBgKCR7dG9TdHJpbmcoc2lnbmF0dXJlLnR5cGUpfS4uLilgO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ29tcG91bmRFeHByZXNzaW9uO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtTdHJpbmdUeXBlLCBCb29sZWFuVHlwZSwgQ29sbGF0b3JUeXBlfSBmcm9tICcuLi90eXBlcy5qcyc7XG5pbXBvcnQgQ29sbGF0b3IgZnJvbSAnLi4vdHlwZXMvY29sbGF0b3IuanMnO1xuXG5pbXBvcnQgdHlwZSB7RXhwcmVzc2lvbiwgU2VyaWFsaXplZEV4cHJlc3Npb259IGZyb20gJy4uL2V4cHJlc3Npb24uanMnO1xuaW1wb3J0IHR5cGUgRXZhbHVhdGlvbkNvbnRleHQgZnJvbSAnLi4vZXZhbHVhdGlvbl9jb250ZXh0LmpzJztcbmltcG9ydCB0eXBlIFBhcnNpbmdDb250ZXh0IGZyb20gJy4uL3BhcnNpbmdfY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSB7VHlwZX0gZnJvbSAnLi4vdHlwZXMuanMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDb2xsYXRvckV4cHJlc3Npb24gaW1wbGVtZW50cyBFeHByZXNzaW9uIHtcbiAgICB0eXBlOiBUeXBlO1xuICAgIGNhc2VTZW5zaXRpdmU6IEV4cHJlc3Npb247XG4gICAgZGlhY3JpdGljU2Vuc2l0aXZlOiBFeHByZXNzaW9uO1xuICAgIGxvY2FsZTogRXhwcmVzc2lvbiB8IG51bGw7XG5cbiAgICBjb25zdHJ1Y3RvcihjYXNlU2Vuc2l0aXZlOiBFeHByZXNzaW9uLCBkaWFjcml0aWNTZW5zaXRpdmU6IEV4cHJlc3Npb24sIGxvY2FsZTogRXhwcmVzc2lvbiB8IG51bGwpIHtcbiAgICAgICAgdGhpcy50eXBlID0gQ29sbGF0b3JUeXBlO1xuICAgICAgICB0aGlzLmxvY2FsZSA9IGxvY2FsZTtcbiAgICAgICAgdGhpcy5jYXNlU2Vuc2l0aXZlID0gY2FzZVNlbnNpdGl2ZTtcbiAgICAgICAgdGhpcy5kaWFjcml0aWNTZW5zaXRpdmUgPSBkaWFjcml0aWNTZW5zaXRpdmU7XG4gICAgfVxuXG4gICAgc3RhdGljIHBhcnNlKGFyZ3M6ICRSZWFkT25seUFycmF5PG1peGVkPiwgY29udGV4dDogUGFyc2luZ0NvbnRleHQpOiA/RXhwcmVzc2lvbiB7XG4gICAgICAgIGlmIChhcmdzLmxlbmd0aCAhPT0gMilcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmVycm9yKGBFeHBlY3RlZCBvbmUgYXJndW1lbnQuYCk7XG5cbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IChhcmdzWzFdOiBhbnkpO1xuICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgIT09IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShvcHRpb25zKSlcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmVycm9yKGBDb2xsYXRvciBvcHRpb25zIGFyZ3VtZW50IG11c3QgYmUgYW4gb2JqZWN0LmApO1xuXG4gICAgICAgIGNvbnN0IGNhc2VTZW5zaXRpdmUgPSBjb250ZXh0LnBhcnNlKFxuICAgICAgICAgICAgb3B0aW9uc1snY2FzZS1zZW5zaXRpdmUnXSA9PT0gdW5kZWZpbmVkID8gZmFsc2UgOiBvcHRpb25zWydjYXNlLXNlbnNpdGl2ZSddLCAxLCBCb29sZWFuVHlwZSk7XG4gICAgICAgIGlmICghY2FzZVNlbnNpdGl2ZSkgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgY29uc3QgZGlhY3JpdGljU2Vuc2l0aXZlID0gY29udGV4dC5wYXJzZShcbiAgICAgICAgICAgIG9wdGlvbnNbJ2RpYWNyaXRpYy1zZW5zaXRpdmUnXSA9PT0gdW5kZWZpbmVkID8gZmFsc2UgOiBvcHRpb25zWydkaWFjcml0aWMtc2Vuc2l0aXZlJ10sIDEsIEJvb2xlYW5UeXBlKTtcbiAgICAgICAgaWYgKCFkaWFjcml0aWNTZW5zaXRpdmUpIHJldHVybiBudWxsO1xuXG4gICAgICAgIGxldCBsb2NhbGUgPSBudWxsO1xuICAgICAgICBpZiAob3B0aW9uc1snbG9jYWxlJ10pIHtcbiAgICAgICAgICAgIGxvY2FsZSA9IGNvbnRleHQucGFyc2Uob3B0aW9uc1snbG9jYWxlJ10sIDEsIFN0cmluZ1R5cGUpO1xuICAgICAgICAgICAgaWYgKCFsb2NhbGUpIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBDb2xsYXRvckV4cHJlc3Npb24oY2FzZVNlbnNpdGl2ZSwgZGlhY3JpdGljU2Vuc2l0aXZlLCBsb2NhbGUpO1xuICAgIH1cblxuICAgIGV2YWx1YXRlKGN0eDogRXZhbHVhdGlvbkNvbnRleHQpOiBDb2xsYXRvciB7XG4gICAgICAgIHJldHVybiBuZXcgQ29sbGF0b3IodGhpcy5jYXNlU2Vuc2l0aXZlLmV2YWx1YXRlKGN0eCksIHRoaXMuZGlhY3JpdGljU2Vuc2l0aXZlLmV2YWx1YXRlKGN0eCksIHRoaXMubG9jYWxlID8gdGhpcy5sb2NhbGUuZXZhbHVhdGUoY3R4KSA6IG51bGwpO1xuICAgIH1cblxuICAgIGVhY2hDaGlsZChmbjogKF86IEV4cHJlc3Npb24pID0+IHZvaWQpIHtcbiAgICAgICAgZm4odGhpcy5jYXNlU2Vuc2l0aXZlKTtcbiAgICAgICAgZm4odGhpcy5kaWFjcml0aWNTZW5zaXRpdmUpO1xuICAgICAgICBpZiAodGhpcy5sb2NhbGUpIHtcbiAgICAgICAgICAgIGZuKHRoaXMubG9jYWxlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG91dHB1dERlZmluZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIC8vIFRlY2huaWNhbGx5IHRoZSBzZXQgb2YgcG9zc2libGUgb3V0cHV0cyBpcyB0aGUgY29tYmluYXRvcmljIHNldCBvZiBDb2xsYXRvcnMgcHJvZHVjZWRcbiAgICAgICAgLy8gYnkgYWxsIHBvc3NpYmxlIG91dHB1dHMgb2YgbG9jYWxlL2Nhc2VTZW5zaXRpdmUvZGlhY3JpdGljU2Vuc2l0aXZlXG4gICAgICAgIC8vIEJ1dCBmb3IgdGhlIHByaW1hcnkgdXNlIG9mIENvbGxhdG9ycyBpbiBjb21wYXJpc29uIG9wZXJhdG9ycywgd2UgaWdub3JlIHRoZSBDb2xsYXRvcidzXG4gICAgICAgIC8vIHBvc3NpYmxlIG91dHB1dHMgYW55d2F5LCBzbyB3ZSBjYW4gZ2V0IGF3YXkgd2l0aCBsZWF2aW5nIHRoaXMgZmFsc2UgZm9yIG5vdy5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHNlcmlhbGl6ZSgpOiBTZXJpYWxpemVkRXhwcmVzc2lvbiB7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7fTtcbiAgICAgICAgb3B0aW9uc1snY2FzZS1zZW5zaXRpdmUnXSA9IHRoaXMuY2FzZVNlbnNpdGl2ZS5zZXJpYWxpemUoKTtcbiAgICAgICAgb3B0aW9uc1snZGlhY3JpdGljLXNlbnNpdGl2ZSddID0gdGhpcy5kaWFjcml0aWNTZW5zaXRpdmUuc2VyaWFsaXplKCk7XG4gICAgICAgIGlmICh0aGlzLmxvY2FsZSkge1xuICAgICAgICAgICAgb3B0aW9uc1snbG9jYWxlJ10gPSB0aGlzLmxvY2FsZS5zZXJpYWxpemUoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW1wiY29sbGF0b3JcIiwgb3B0aW9uc107XG4gICAgfVxufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtpc1ZhbHVlfSBmcm9tICcuLi92YWx1ZXMuanMnO1xuaW1wb3J0IHR5cGUge1R5cGV9IGZyb20gJy4uL3R5cGVzLmpzJztcbmltcG9ydCB7Qm9vbGVhblR5cGV9IGZyb20gJy4uL3R5cGVzLmpzJztcbmltcG9ydCB0eXBlIHtFeHByZXNzaW9uLCBTZXJpYWxpemVkRXhwcmVzc2lvbn0gZnJvbSAnLi4vZXhwcmVzc2lvbi5qcyc7XG5pbXBvcnQgdHlwZSBQYXJzaW5nQ29udGV4dCBmcm9tICcuLi9wYXJzaW5nX2NvbnRleHQuanMnO1xuaW1wb3J0IHR5cGUgRXZhbHVhdGlvbkNvbnRleHQgZnJvbSAnLi4vZXZhbHVhdGlvbl9jb250ZXh0LmpzJztcbmltcG9ydCB0eXBlIFBvaW50IGZyb20gJ0BtYXBib3gvcG9pbnQtZ2VvbWV0cnknO1xuaW1wb3J0IHR5cGUge0dlb0pTT04sIEdlb0pTT05Qb3NpdGlvbiwgR2VvSlNPTlBvbHlnb24sIEdlb0pTT05NdWx0aVBvbHlnb259IGZyb20gJ0BtYXBib3gvZ2VvanNvbi10eXBlcyc7XG5pbXBvcnQgdHlwZSB7Q2Fub25pY2FsVGlsZUlEfSBmcm9tICcuLi8uLi8uLi9zb3VyY2UvdGlsZV9pZC5qcyc7XG5cbnR5cGUgR2VvSlNPTlBvbHlnb25zID18IEdlb0pTT05Qb2x5Z29uIHwgR2VvSlNPTk11bHRpUG9seWdvbjtcblxuLy8gbWluWCwgbWluWSwgbWF4WCwgbWF4WVxudHlwZSBCQm94ID0gW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG5jb25zdCBFWFRFTlQgPSA4MTkyO1xuXG5mdW5jdGlvbiB1cGRhdGVCQm94KGJib3g6IEJCb3gsIGNvb3JkOiBHZW9KU09OUG9zaXRpb24pIHtcbiAgICBiYm94WzBdID0gTWF0aC5taW4oYmJveFswXSwgY29vcmRbMF0pO1xuICAgIGJib3hbMV0gPSBNYXRoLm1pbihiYm94WzFdLCBjb29yZFsxXSk7XG4gICAgYmJveFsyXSA9IE1hdGgubWF4KGJib3hbMl0sIGNvb3JkWzBdKTtcbiAgICBiYm94WzNdID0gTWF0aC5tYXgoYmJveFszXSwgY29vcmRbMV0pO1xufVxuXG5mdW5jdGlvbiBtZXJjYXRvclhmcm9tTG5nKGxuZzogbnVtYmVyKSB7XG4gICAgcmV0dXJuICgxODAgKyBsbmcpIC8gMzYwO1xufVxuXG5mdW5jdGlvbiBtZXJjYXRvcllmcm9tTGF0KGxhdDogbnVtYmVyKSB7XG4gICAgcmV0dXJuICgxODAgLSAoMTgwIC8gTWF0aC5QSSAqIE1hdGgubG9nKE1hdGgudGFuKE1hdGguUEkgLyA0ICsgbGF0ICogTWF0aC5QSSAvIDM2MCkpKSkgLyAzNjA7XG59XG5cbmZ1bmN0aW9uIGJveFdpdGhpbkJveChiYm94MTogQkJveCwgYmJveDI6IEJCb3gpIHtcbiAgICBpZiAoYmJveDFbMF0gPD0gYmJveDJbMF0pIHJldHVybiBmYWxzZTtcbiAgICBpZiAoYmJveDFbMl0gPj0gYmJveDJbMl0pIHJldHVybiBmYWxzZTtcbiAgICBpZiAoYmJveDFbMV0gPD0gYmJveDJbMV0pIHJldHVybiBmYWxzZTtcbiAgICBpZiAoYmJveDFbM10gPj0gYmJveDJbM10pIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gZ2V0VGlsZUNvb3JkaW5hdGVzKHA6IEdlb0pTT05Qb3NpdGlvbiwgY2Fub25pY2FsOiBDYW5vbmljYWxUaWxlSUQpIHtcbiAgICBjb25zdCB4ID0gbWVyY2F0b3JYZnJvbUxuZyhwWzBdKTtcbiAgICBjb25zdCB5ID0gbWVyY2F0b3JZZnJvbUxhdChwWzFdKTtcbiAgICBjb25zdCB0aWxlc0F0Wm9vbSA9IE1hdGgucG93KDIsIGNhbm9uaWNhbC56KTtcbiAgICByZXR1cm4gW01hdGgucm91bmQoeCAqIHRpbGVzQXRab29tICogRVhURU5UKSwgTWF0aC5yb3VuZCh5ICogdGlsZXNBdFpvb20gKiBFWFRFTlQpXTtcbn1cblxuZnVuY3Rpb24gb25Cb3VuZGFyeShwOiBHZW9KU09OUG9zaXRpb24sIHAxOiBHZW9KU09OUG9zaXRpb24sIHAyOiBHZW9KU09OUG9zaXRpb24pIHtcbiAgICBjb25zdCB4MSA9IHBbMF0gLSBwMVswXTtcbiAgICBjb25zdCB5MSA9IHBbMV0gLSBwMVsxXTtcbiAgICBjb25zdCB4MiA9IHBbMF0gLSBwMlswXTtcbiAgICBjb25zdCB5MiA9IHBbMV0gLSBwMlsxXTtcbiAgICByZXR1cm4gKHgxICogeTIgLSB4MiAqIHkxID09PSAwKSAmJiAoeDEgKiB4MiA8PSAwKSAmJiAoeTEgKiB5MiA8PSAwKTtcbn1cblxuZnVuY3Rpb24gcmF5SW50ZXJzZWN0KHA6IEdlb0pTT05Qb3NpdGlvbiwgcDE6IEdlb0pTT05Qb3NpdGlvbiwgcDI6IEdlb0pTT05Qb3NpdGlvbikge1xuICAgIHJldHVybiAoKHAxWzFdID4gcFsxXSkgIT09IChwMlsxXSA+IHBbMV0pKSAmJiAocFswXSA8IChwMlswXSAtIHAxWzBdKSAqIChwWzFdIC0gcDFbMV0pIC8gKHAyWzFdIC0gcDFbMV0pICsgcDFbMF0pO1xufVxuXG4vLyByYXkgY2FzdGluZyBhbGdvcml0aG0gZm9yIGRldGVjdGluZyBpZiBwb2ludCBpcyBpbiBwb2x5Z29uXG5mdW5jdGlvbiBwb2ludFdpdGhpblBvbHlnb24ocG9pbnQ6IEdlb0pTT05Qb3NpdGlvbiwgcmluZ3M6IEFycmF5PEFycmF5PEdlb0pTT05Qb3NpdGlvbj4+KSB7XG4gICAgbGV0IGluc2lkZSA9IGZhbHNlO1xuICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSByaW5ncy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBjb25zdCByaW5nID0gcmluZ3NbaV07XG4gICAgICAgIGZvciAobGV0IGogPSAwLCBsZW4yID0gcmluZy5sZW5ndGg7IGogPCBsZW4yIC0gMTsgaisrKSB7XG4gICAgICAgICAgICBpZiAob25Cb3VuZGFyeShwb2ludCwgcmluZ1tqXSwgcmluZ1tqICsgMV0pKSByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICBpZiAocmF5SW50ZXJzZWN0KHBvaW50LCByaW5nW2pdLCByaW5nW2ogKyAxXSkpIGluc2lkZSA9ICFpbnNpZGU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGluc2lkZTtcbn1cblxuZnVuY3Rpb24gcG9pbnRXaXRoaW5Qb2x5Z29ucyhwb2ludDogR2VvSlNPTlBvc2l0aW9uLCBwb2x5Z29uczogQXJyYXk8QXJyYXk8QXJyYXk8R2VvSlNPTlBvc2l0aW9uPj4+KSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwb2x5Z29ucy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAocG9pbnRXaXRoaW5Qb2x5Z29uKHBvaW50LCBwb2x5Z29uc1tpXSkpIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIHBlcnAodjE6IEdlb0pTT05Qb3NpdGlvbiwgdjI6IEdlb0pTT05Qb3NpdGlvbikge1xuICAgIHJldHVybiAodjFbMF0gKiB2MlsxXSAtIHYxWzFdICogdjJbMF0pO1xufVxuXG4vLyBjaGVjayBpZiBwMSBhbmQgcDIgYXJlIGluIGRpZmZlcmVudCBzaWRlcyBvZiBsaW5lIHNlZ21lbnQgcTEtPnEyXG5mdW5jdGlvbiAgdHdvU2lkZWQocDE6IEdlb0pTT05Qb3NpdGlvbiwgcDI6IEdlb0pTT05Qb3NpdGlvbiwgcTE6IEdlb0pTT05Qb3NpdGlvbiwgcTI6IEdlb0pTT05Qb3NpdGlvbikge1xuICAgIC8vIHExLT5wMSAoeDEsIHkxKSwgcTEtPnAyICh4MiwgeTIpLCBxMS0+cTIgKHgzLCB5MylcbiAgICBjb25zdCB4MSA9IHAxWzBdIC0gcTFbMF07XG4gICAgY29uc3QgeTEgPSBwMVsxXSAtIHExWzFdO1xuICAgIGNvbnN0IHgyID0gcDJbMF0gLSBxMVswXTtcbiAgICBjb25zdCB5MiA9IHAyWzFdIC0gcTFbMV07XG4gICAgY29uc3QgeDMgPSBxMlswXSAtIHExWzBdO1xuICAgIGNvbnN0IHkzID0gcTJbMV0gLSBxMVsxXTtcbiAgICBjb25zdCBkZXQxID0gKHgxICogeTMgLSB4MyAqIHkxKTtcbiAgICBjb25zdCBkZXQyID0gICh4MiAqIHkzIC0geDMgKiB5Mik7XG4gICAgaWYgKChkZXQxID4gMCAmJiBkZXQyIDwgMCkgfHwgKGRldDEgPCAwICYmIGRldDIgPiAwKSkgcmV0dXJuIHRydWU7XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuLy8gYSwgYiBhcmUgZW5kIHBvaW50cyBmb3IgbGluZSBzZWdtZW50MSwgYyBhbmQgZCBhcmUgZW5kIHBvaW50cyBmb3IgbGluZSBzZWdtZW50MlxuZnVuY3Rpb24gbGluZUludGVyc2VjdExpbmUoYTogR2VvSlNPTlBvc2l0aW9uLCBiOiBHZW9KU09OUG9zaXRpb24sIGM6IEdlb0pTT05Qb3NpdGlvbiwgZDogR2VvSlNPTlBvc2l0aW9uKSB7XG4gICAgLy8gY2hlY2sgaWYgdHdvIHNlZ21lbnRzIGFyZSBwYXJhbGxlbCBvciBub3RcbiAgICAvLyBwcmVjb25kaXRpb24gaXMgZW5kIHBvaW50IGEsIGIgaXMgaW5zaWRlIHBvbHlnb24sIGlmIGxpbmUgYS0+YiBpc1xuICAgIC8vIHBhcmFsbGVsIHRvIHBvbHlnb24gZWRnZSBjLT5kLCB0aGVuIGEtPmIgd29uJ3QgaW50ZXJzZWN0IHdpdGggYy0+ZFxuICAgIGNvbnN0IHZlY3RvclAgPSBbYlswXSAtIGFbMF0sIGJbMV0gLSBhWzFdXTtcbiAgICBjb25zdCB2ZWN0b3JRID0gW2RbMF0gLSBjWzBdLCBkWzFdIC0gY1sxXV07XG4gICAgaWYgKHBlcnAodmVjdG9yUSwgdmVjdG9yUCkgPT09IDApIHJldHVybiBmYWxzZTtcblxuICAgIC8vIElmIGxpbmVzIGFyZSBpbnRlcnNlY3Rpbmcgd2l0aCBlYWNoIG90aGVyLCB0aGUgcmVsYXRpdmUgbG9jYXRpb24gc2hvdWxkIGJlOlxuICAgIC8vIGEgYW5kIGIgbGllIGluIGRpZmZlcmVudCBzaWRlcyBvZiBzZWdtZW50IGMtPmRcbiAgICAvLyBjIGFuZCBkIGxpZSBpbiBkaWZmZXJlbnQgc2lkZXMgb2Ygc2VnbWVudCBhLT5iXG4gICAgaWYgKHR3b1NpZGVkKGEsIGIsIGMsIGQpICYmIHR3b1NpZGVkKGMsIGQsIGEsIGIpKSByZXR1cm4gdHJ1ZTtcbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGxpbmVJbnRlcnNlY3RQb2x5Z29uKHAxOiBHZW9KU09OUG9zaXRpb24sIHAyOiBHZW9KU09OUG9zaXRpb24sIHBvbHlnb246IEFycmF5PEFycmF5PEdlb0pTT05Qb3NpdGlvbj4+KSB7XG4gICAgZm9yIChjb25zdCByaW5nIG9mIHBvbHlnb24pIHtcbiAgICAgICAgLy8gbG9vcCB0aHJvdWdoIGV2ZXJ5IGVkZ2Ugb2YgdGhlIHJpbmdcbiAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCByaW5nLmxlbmd0aCAtIDE7ICsraikge1xuICAgICAgICAgICAgaWYgKGxpbmVJbnRlcnNlY3RMaW5lKHAxLCBwMiwgcmluZ1tqXSwgcmluZ1tqICsgMV0pKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBsaW5lU3RyaW5nV2l0aGluUG9seWdvbihsaW5lOiBBcnJheTxHZW9KU09OUG9zaXRpb24+LCBwb2x5Z29uOiBBcnJheTxBcnJheTxHZW9KU09OUG9zaXRpb24+Pikge1xuICAgIC8vIEZpcnN0LCBjaGVjayBpZiBnZW9tZXRyeSBwb2ludHMgb2YgbGluZSBzZWdtZW50cyBhcmUgYWxsIGluc2lkZSBwb2x5Z29uXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW5lLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIGlmICghcG9pbnRXaXRoaW5Qb2x5Z29uKGxpbmVbaV0sIHBvbHlnb24pKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBTZWNvbmQsIGNoZWNrIGlmIHRoZXJlIGlzIGxpbmUgc2VnbWVudCBpbnRlcnNlY3RpbmcgcG9seWdvbiBlZGdlXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW5lLmxlbmd0aCAtIDE7ICsraSkge1xuICAgICAgICBpZiAobGluZUludGVyc2VjdFBvbHlnb24obGluZVtpXSwgbGluZVtpICsgMV0sIHBvbHlnb24pKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGxpbmVTdHJpbmdXaXRoaW5Qb2x5Z29ucyhsaW5lOiBBcnJheTxHZW9KU09OUG9zaXRpb24+LCBwb2x5Z29uczogQXJyYXk8QXJyYXk8QXJyYXk8R2VvSlNPTlBvc2l0aW9uPj4+KSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwb2x5Z29ucy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAobGluZVN0cmluZ1dpdGhpblBvbHlnb24obGluZSwgcG9seWdvbnNbaV0pKSByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBnZXRUaWxlUG9seWdvbihjb29yZGluYXRlczogQXJyYXk8QXJyYXk8R2VvSlNPTlBvc2l0aW9uPj4sIGJib3g6IEJCb3gsIGNhbm9uaWNhbDogQ2Fub25pY2FsVGlsZUlEKSB7XG4gICAgY29uc3QgcG9seWdvbiA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29vcmRpbmF0ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgcmluZyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGNvb3JkaW5hdGVzW2ldLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICBjb25zdCBjb29yZCA9IGdldFRpbGVDb29yZGluYXRlcyhjb29yZGluYXRlc1tpXVtqXSwgY2Fub25pY2FsKTtcbiAgICAgICAgICAgIHVwZGF0ZUJCb3goYmJveCwgY29vcmQpO1xuICAgICAgICAgICAgcmluZy5wdXNoKGNvb3JkKTtcbiAgICAgICAgfVxuICAgICAgICBwb2x5Z29uLnB1c2gocmluZyk7XG4gICAgfVxuICAgIHJldHVybiBwb2x5Z29uO1xufVxuXG5mdW5jdGlvbiBnZXRUaWxlUG9seWdvbnMoY29vcmRpbmF0ZXM6IEFycmF5PEFycmF5PEFycmF5PEdlb0pTT05Qb3NpdGlvbj4+PiwgYmJveDogQkJveCwgY2Fub25pY2FsOiBDYW5vbmljYWxUaWxlSUQpIHtcbiAgICBjb25zdCBwb2x5Z29ucyA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29vcmRpbmF0ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgcG9seWdvbiA9IGdldFRpbGVQb2x5Z29uKGNvb3JkaW5hdGVzW2ldLCBiYm94LCBjYW5vbmljYWwpO1xuICAgICAgICBwb2x5Z29ucy5wdXNoKHBvbHlnb24pO1xuICAgIH1cbiAgICByZXR1cm4gcG9seWdvbnM7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVBvaW50KHA6IEdlb0pTT05Qb3NpdGlvbiwgYmJveDogQkJveCwgcG9seUJCb3g6IEFycmF5PG51bWJlcj4sIHdvcmxkU2l6ZTogbnVtYmVyKSB7XG4gICAgaWYgKHBbMF0gPCBwb2x5QkJveFswXSB8fCBwWzBdID4gcG9seUJCb3hbMl0pIHtcbiAgICAgICAgY29uc3QgaGFsZldvcmxkU2l6ZSA9IHdvcmxkU2l6ZSAqIDAuNTtcbiAgICAgICAgbGV0IHNoaWZ0ID0gKHBbMF0gLSBwb2x5QkJveFswXSA+IGhhbGZXb3JsZFNpemUpID8gLXdvcmxkU2l6ZSA6IChwb2x5QkJveFswXSAtIHBbMF0gPiBoYWxmV29ybGRTaXplKSA/IHdvcmxkU2l6ZSA6IDA7XG4gICAgICAgIGlmIChzaGlmdCA9PT0gMCkge1xuICAgICAgICAgICAgc2hpZnQgPSAocFswXSAtIHBvbHlCQm94WzJdID4gaGFsZldvcmxkU2l6ZSkgPyAtd29ybGRTaXplIDogKHBvbHlCQm94WzJdIC0gcFswXSA+IGhhbGZXb3JsZFNpemUpID8gd29ybGRTaXplIDogMDtcbiAgICAgICAgfVxuICAgICAgICBwWzBdICs9IHNoaWZ0O1xuICAgIH1cbiAgICB1cGRhdGVCQm94KGJib3gsIHApO1xufVxuXG5mdW5jdGlvbiByZXNldEJCb3goYmJveDogQkJveCkge1xuICAgIGJib3hbMF0gPSBiYm94WzFdID0gSW5maW5pdHk7XG4gICAgYmJveFsyXSA9IGJib3hbM10gPSAtSW5maW5pdHk7XG59XG5cbmZ1bmN0aW9uIGdldFRpbGVQb2ludHMoZ2VvbWV0cnk6ID9BcnJheTxBcnJheTxQb2ludD4+LCBwb2ludEJCb3g6IEJCb3gsIHBvbHlCQm94OiBBcnJheTxudW1iZXI+LCBjYW5vbmljYWw6IENhbm9uaWNhbFRpbGVJRCkge1xuICAgIGNvbnN0IHdvcmxkU2l6ZSA9IE1hdGgucG93KDIsIGNhbm9uaWNhbC56KSAqIEVYVEVOVDtcbiAgICBjb25zdCBzaGlmdHMgPSBbY2Fub25pY2FsLnggKiBFWFRFTlQsIGNhbm9uaWNhbC55ICogRVhURU5UXTtcbiAgICBjb25zdCB0aWxlUG9pbnRzID0gW107XG4gICAgaWYgKCFnZW9tZXRyeSkgcmV0dXJuIHRpbGVQb2ludHM7XG4gICAgZm9yIChjb25zdCBwb2ludHMgb2YgZ2VvbWV0cnkpIHtcbiAgICAgICAgZm9yIChjb25zdCBwb2ludCBvZiBwb2ludHMpIHtcbiAgICAgICAgICAgIGNvbnN0IHAgPSBbcG9pbnQueCArIHNoaWZ0c1swXSwgcG9pbnQueSArIHNoaWZ0c1sxXV07XG4gICAgICAgICAgICB1cGRhdGVQb2ludChwLCBwb2ludEJCb3gsIHBvbHlCQm94LCB3b3JsZFNpemUpO1xuICAgICAgICAgICAgdGlsZVBvaW50cy5wdXNoKHApO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aWxlUG9pbnRzO1xufVxuXG5mdW5jdGlvbiBnZXRUaWxlTGluZXMoZ2VvbWV0cnk6ID9BcnJheTxBcnJheTxQb2ludD4+LCBsaW5lQkJveDogQkJveCwgcG9seUJCb3g6IEFycmF5PG51bWJlcj4sIGNhbm9uaWNhbDogQ2Fub25pY2FsVGlsZUlEKSB7XG4gICAgY29uc3Qgd29ybGRTaXplID0gTWF0aC5wb3coMiwgY2Fub25pY2FsLnopICogRVhURU5UO1xuICAgIGNvbnN0IHNoaWZ0cyA9IFtjYW5vbmljYWwueCAqIEVYVEVOVCwgY2Fub25pY2FsLnkgKiBFWFRFTlRdO1xuICAgIGNvbnN0IHRpbGVMaW5lczogQXJyYXk8QXJyYXk8R2VvSlNPTlBvc2l0aW9uPj4gPSBbXTtcbiAgICBpZiAoIWdlb21ldHJ5KSByZXR1cm4gdGlsZUxpbmVzO1xuICAgIGZvciAoY29uc3QgbGluZSBvZiBnZW9tZXRyeSkge1xuICAgICAgICBjb25zdCB0aWxlTGluZSA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IHBvaW50IG9mIGxpbmUpIHtcbiAgICAgICAgICAgIGNvbnN0IHA6IEdlb0pTT05Qb3NpdGlvbiA9IFtwb2ludC54ICsgc2hpZnRzWzBdLCBwb2ludC55ICsgc2hpZnRzWzFdXTtcbiAgICAgICAgICAgIHVwZGF0ZUJCb3gobGluZUJCb3gsIHApO1xuICAgICAgICAgICAgdGlsZUxpbmUucHVzaChwKTtcbiAgICAgICAgfVxuICAgICAgICB0aWxlTGluZXMucHVzaCh0aWxlTGluZSk7XG4gICAgfVxuICAgIGlmIChsaW5lQkJveFsyXSAtIGxpbmVCQm94WzBdIDw9IHdvcmxkU2l6ZSAvIDIpIHtcbiAgICAgICAgcmVzZXRCQm94KGxpbmVCQm94KTtcbiAgICAgICAgZm9yIChjb25zdCBsaW5lIG9mIHRpbGVMaW5lcykge1xuICAgICAgICAgICAgZm9yIChjb25zdCBwIG9mIGxpbmUpIHtcbiAgICAgICAgICAgICAgICB1cGRhdGVQb2ludChwLCBsaW5lQkJveCwgcG9seUJCb3gsIHdvcmxkU2l6ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRpbGVMaW5lcztcbn1cblxuZnVuY3Rpb24gcG9pbnRzV2l0aGluUG9seWdvbnMoY3R4OiBFdmFsdWF0aW9uQ29udGV4dCwgcG9seWdvbkdlb21ldHJ5OiBHZW9KU09OUG9seWdvbnMpIHtcbiAgICBjb25zdCBwb2ludEJCb3ggPSBbSW5maW5pdHksIEluZmluaXR5LCAtSW5maW5pdHksIC1JbmZpbml0eV07XG4gICAgY29uc3QgcG9seUJCb3ggPSBbSW5maW5pdHksIEluZmluaXR5LCAtSW5maW5pdHksIC1JbmZpbml0eV07XG5cbiAgICBjb25zdCBjYW5vbmljYWwgPSBjdHguY2Fub25pY2FsSUQoKTtcbiAgICBpZiAoIWNhbm9uaWNhbCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKHBvbHlnb25HZW9tZXRyeS50eXBlID09PSAnUG9seWdvbicpIHtcbiAgICAgICAgY29uc3QgdGlsZVBvbHlnb24gPSBnZXRUaWxlUG9seWdvbihwb2x5Z29uR2VvbWV0cnkuY29vcmRpbmF0ZXMsIHBvbHlCQm94LCBjYW5vbmljYWwpO1xuICAgICAgICBjb25zdCB0aWxlUG9pbnRzID0gZ2V0VGlsZVBvaW50cyhjdHguZ2VvbWV0cnkoKSwgcG9pbnRCQm94LCBwb2x5QkJveCwgY2Fub25pY2FsKTtcbiAgICAgICAgaWYgKCFib3hXaXRoaW5Cb3gocG9pbnRCQm94LCBwb2x5QkJveCkpIHJldHVybiBmYWxzZTtcblxuICAgICAgICBmb3IgKGNvbnN0IHBvaW50IG9mIHRpbGVQb2ludHMpIHtcbiAgICAgICAgICAgIGlmICghcG9pbnRXaXRoaW5Qb2x5Z29uKHBvaW50LCB0aWxlUG9seWdvbikpIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAocG9seWdvbkdlb21ldHJ5LnR5cGUgPT09ICdNdWx0aVBvbHlnb24nKSB7XG4gICAgICAgIGNvbnN0IHRpbGVQb2x5Z29ucyA9IGdldFRpbGVQb2x5Z29ucyhwb2x5Z29uR2VvbWV0cnkuY29vcmRpbmF0ZXMsIHBvbHlCQm94LCBjYW5vbmljYWwpO1xuICAgICAgICBjb25zdCB0aWxlUG9pbnRzID0gZ2V0VGlsZVBvaW50cyhjdHguZ2VvbWV0cnkoKSwgcG9pbnRCQm94LCBwb2x5QkJveCwgY2Fub25pY2FsKTtcbiAgICAgICAgaWYgKCFib3hXaXRoaW5Cb3gocG9pbnRCQm94LCBwb2x5QkJveCkpIHJldHVybiBmYWxzZTtcblxuICAgICAgICBmb3IgKGNvbnN0IHBvaW50IG9mIHRpbGVQb2ludHMpIHtcbiAgICAgICAgICAgIGlmICghcG9pbnRXaXRoaW5Qb2x5Z29ucyhwb2ludCwgdGlsZVBvbHlnb25zKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGxpbmVzV2l0aGluUG9seWdvbnMoY3R4OiBFdmFsdWF0aW9uQ29udGV4dCwgcG9seWdvbkdlb21ldHJ5OiBHZW9KU09OUG9seWdvbnMpIHtcbiAgICBjb25zdCBsaW5lQkJveCA9IFtJbmZpbml0eSwgSW5maW5pdHksIC1JbmZpbml0eSwgLUluZmluaXR5XTtcbiAgICBjb25zdCBwb2x5QkJveCA9IFtJbmZpbml0eSwgSW5maW5pdHksIC1JbmZpbml0eSwgLUluZmluaXR5XTtcblxuICAgIGNvbnN0IGNhbm9uaWNhbCA9IGN0eC5jYW5vbmljYWxJRCgpO1xuICAgIGlmICghY2Fub25pY2FsKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAocG9seWdvbkdlb21ldHJ5LnR5cGUgPT09ICdQb2x5Z29uJykge1xuICAgICAgICBjb25zdCB0aWxlUG9seWdvbiA9IGdldFRpbGVQb2x5Z29uKHBvbHlnb25HZW9tZXRyeS5jb29yZGluYXRlcywgcG9seUJCb3gsIGNhbm9uaWNhbCk7XG4gICAgICAgIGNvbnN0IHRpbGVMaW5lcyA9IGdldFRpbGVMaW5lcyhjdHguZ2VvbWV0cnkoKSwgbGluZUJCb3gsIHBvbHlCQm94LCBjYW5vbmljYWwpO1xuICAgICAgICBpZiAoIWJveFdpdGhpbkJveChsaW5lQkJveCwgcG9seUJCb3gpKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgZm9yIChjb25zdCBsaW5lIG9mIHRpbGVMaW5lcykge1xuICAgICAgICAgICAgaWYgKCFsaW5lU3RyaW5nV2l0aGluUG9seWdvbihsaW5lLCB0aWxlUG9seWdvbikpIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAocG9seWdvbkdlb21ldHJ5LnR5cGUgPT09ICdNdWx0aVBvbHlnb24nKSB7XG4gICAgICAgIGNvbnN0IHRpbGVQb2x5Z29ucyA9IGdldFRpbGVQb2x5Z29ucyhwb2x5Z29uR2VvbWV0cnkuY29vcmRpbmF0ZXMsIHBvbHlCQm94LCBjYW5vbmljYWwpO1xuICAgICAgICBjb25zdCB0aWxlTGluZXMgPSBnZXRUaWxlTGluZXMoY3R4Lmdlb21ldHJ5KCksIGxpbmVCQm94LCBwb2x5QkJveCwgY2Fub25pY2FsKTtcbiAgICAgICAgaWYgKCFib3hXaXRoaW5Cb3gobGluZUJCb3gsIHBvbHlCQm94KSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIGZvciAoY29uc3QgbGluZSBvZiB0aWxlTGluZXMpIHtcbiAgICAgICAgICAgIGlmICghbGluZVN0cmluZ1dpdGhpblBvbHlnb25zKGxpbmUsIHRpbGVQb2x5Z29ucykpIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cblxuY2xhc3MgV2l0aGluIGltcGxlbWVudHMgRXhwcmVzc2lvbiB7XG4gICAgdHlwZTogVHlwZTtcbiAgICBnZW9qc29uOiBHZW9KU09OXG4gICAgZ2VvbWV0cmllczogR2VvSlNPTlBvbHlnb25zO1xuXG4gICAgY29uc3RydWN0b3IoZ2VvanNvbjogR2VvSlNPTiwgZ2VvbWV0cmllczogR2VvSlNPTlBvbHlnb25zKSB7XG4gICAgICAgIHRoaXMudHlwZSA9IEJvb2xlYW5UeXBlO1xuICAgICAgICB0aGlzLmdlb2pzb24gPSBnZW9qc29uO1xuICAgICAgICB0aGlzLmdlb21ldHJpZXMgPSBnZW9tZXRyaWVzO1xuICAgIH1cblxuICAgIHN0YXRpYyBwYXJzZShhcmdzOiAkUmVhZE9ubHlBcnJheTxtaXhlZD4sIGNvbnRleHQ6IFBhcnNpbmdDb250ZXh0KTogP1dpdGhpbiB7XG4gICAgICAgIGlmIChhcmdzLmxlbmd0aCAhPT0gMilcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmVycm9yKGAnd2l0aGluJyBleHByZXNzaW9uIHJlcXVpcmVzIGV4YWN0bHkgb25lIGFyZ3VtZW50LCBidXQgZm91bmQgJHthcmdzLmxlbmd0aCAtIDF9IGluc3RlYWQuYCk7XG4gICAgICAgIGlmIChpc1ZhbHVlKGFyZ3NbMV0pKSB7XG4gICAgICAgICAgICBjb25zdCBnZW9qc29uID0gKGFyZ3NbMV06IE9iamVjdCk7XG4gICAgICAgICAgICBpZiAoZ2VvanNvbi50eXBlID09PSAnRmVhdHVyZUNvbGxlY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBnZW9qc29uLmZlYXR1cmVzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHR5cGUgPSBnZW9qc29uLmZlYXR1cmVzW2ldLmdlb21ldHJ5LnR5cGU7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlID09PSAnUG9seWdvbicgfHwgdHlwZSA9PT0gJ011bHRpUG9seWdvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgV2l0aGluKGdlb2pzb24sIGdlb2pzb24uZmVhdHVyZXNbaV0uZ2VvbWV0cnkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChnZW9qc29uLnR5cGUgPT09ICdGZWF0dXJlJykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHR5cGUgPSBnZW9qc29uLmdlb21ldHJ5LnR5cGU7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdQb2x5Z29uJyB8fCB0eXBlID09PSAnTXVsdGlQb2x5Z29uJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFdpdGhpbihnZW9qc29uLCBnZW9qc29uLmdlb21ldHJ5KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGdlb2pzb24udHlwZSAgPT09ICdQb2x5Z29uJyB8fCBnZW9qc29uLnR5cGUgPT09ICdNdWx0aVBvbHlnb24nKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBXaXRoaW4oZ2VvanNvbiwgZ2VvanNvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNvbnRleHQuZXJyb3IoYCd3aXRoaW4nIGV4cHJlc3Npb24gcmVxdWlyZXMgdmFsaWQgZ2VvanNvbiBvYmplY3QgdGhhdCBjb250YWlucyBwb2x5Z29uIGdlb21ldHJ5IHR5cGUuYCk7XG4gICAgfVxuXG4gICAgZXZhbHVhdGUoY3R4OiBFdmFsdWF0aW9uQ29udGV4dCk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAoY3R4Lmdlb21ldHJ5KCkgIT0gbnVsbCAmJiBjdHguY2Fub25pY2FsSUQoKSAhPSBudWxsKSB7XG4gICAgICAgICAgICBpZiAoY3R4Lmdlb21ldHJ5VHlwZSgpID09PSAnUG9pbnQnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBvaW50c1dpdGhpblBvbHlnb25zKGN0eCwgdGhpcy5nZW9tZXRyaWVzKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY3R4Lmdlb21ldHJ5VHlwZSgpID09PSAnTGluZVN0cmluZycpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbGluZXNXaXRoaW5Qb2x5Z29ucyhjdHgsIHRoaXMuZ2VvbWV0cmllcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGVhY2hDaGlsZCgpIHt9XG5cbiAgICBvdXRwdXREZWZpbmVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBzZXJpYWxpemUoKTogU2VyaWFsaXplZEV4cHJlc3Npb24ge1xuICAgICAgICByZXR1cm4gW1wid2l0aGluXCIsIHRoaXMuZ2VvanNvbl07XG4gICAgfVxuXG59XG5cbmV4cG9ydCBkZWZhdWx0IFdpdGhpbjtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCBDb21wb3VuZEV4cHJlc3Npb24gZnJvbSAnLi9jb21wb3VuZF9leHByZXNzaW9uLmpzJztcbmltcG9ydCBXaXRoaW4gZnJvbSAnLi9kZWZpbml0aW9ucy93aXRoaW4uanMnO1xuaW1wb3J0IHR5cGUge0V4cHJlc3Npb259IGZyb20gJy4vZXhwcmVzc2lvbi5qcyc7XG5cbmZ1bmN0aW9uIGlzRmVhdHVyZUNvbnN0YW50KGU6IEV4cHJlc3Npb24pOiBib29sZWFuIHtcbiAgICBpZiAoZSBpbnN0YW5jZW9mIENvbXBvdW5kRXhwcmVzc2lvbikge1xuICAgICAgICBpZiAoZS5uYW1lID09PSAnZ2V0JyAmJiBlLmFyZ3MubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0gZWxzZSBpZiAoZS5uYW1lID09PSAnZmVhdHVyZS1zdGF0ZScpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfSBlbHNlIGlmIChlLm5hbWUgPT09ICdoYXMnICYmIGUuYXJncy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAgIGUubmFtZSA9PT0gJ3Byb3BlcnRpZXMnIHx8XG4gICAgICAgICAgICBlLm5hbWUgPT09ICdnZW9tZXRyeS10eXBlJyB8fFxuICAgICAgICAgICAgZS5uYW1lID09PSAnaWQnXG4gICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9IGVsc2UgaWYgKC9eZmlsdGVyLS8udGVzdChlLm5hbWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZSBpbnN0YW5jZW9mIFdpdGhpbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgbGV0IHJlc3VsdCA9IHRydWU7XG4gICAgZS5lYWNoQ2hpbGQoYXJnID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdCAmJiAhaXNGZWF0dXJlQ29uc3RhbnQoYXJnKSkgeyByZXN1bHQgPSBmYWxzZTsgfVxuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIGlzU3RhdGVDb25zdGFudChlOiBFeHByZXNzaW9uKTogYm9vbGVhbiB7XG4gICAgaWYgKGUgaW5zdGFuY2VvZiBDb21wb3VuZEV4cHJlc3Npb24pIHtcbiAgICAgICAgaWYgKGUubmFtZSA9PT0gJ2ZlYXR1cmUtc3RhdGUnKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgbGV0IHJlc3VsdCA9IHRydWU7XG4gICAgZS5lYWNoQ2hpbGQoYXJnID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdCAmJiAhaXNTdGF0ZUNvbnN0YW50KGFyZykpIHsgcmVzdWx0ID0gZmFsc2U7IH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBpc0dsb2JhbFByb3BlcnR5Q29uc3RhbnQoZTogRXhwcmVzc2lvbiwgcHJvcGVydGllczogQXJyYXk8c3RyaW5nPik6IGJvb2xlYW4ge1xuICAgIGlmIChlIGluc3RhbmNlb2YgQ29tcG91bmRFeHByZXNzaW9uICYmIHByb3BlcnRpZXMuaW5kZXhPZihlLm5hbWUpID49IDApIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgbGV0IHJlc3VsdCA9IHRydWU7XG4gICAgZS5lYWNoQ2hpbGQoKGFyZykgPT4ge1xuICAgICAgICBpZiAocmVzdWx0ICYmICFpc0dsb2JhbFByb3BlcnR5Q29uc3RhbnQoYXJnLCBwcm9wZXJ0aWVzKSkgeyByZXN1bHQgPSBmYWxzZTsgfVxuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbmV4cG9ydCB7aXNGZWF0dXJlQ29uc3RhbnQsIGlzR2xvYmFsUHJvcGVydHlDb25zdGFudCwgaXNTdGF0ZUNvbnN0YW50fTtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCB0eXBlIHtUeXBlfSBmcm9tICcuLi90eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSB7RXhwcmVzc2lvbn0gZnJvbSAnLi4vZXhwcmVzc2lvbi5qcyc7XG5pbXBvcnQgdHlwZSBQYXJzaW5nQ29udGV4dCBmcm9tICcuLi9wYXJzaW5nX2NvbnRleHQuanMnO1xuaW1wb3J0IHR5cGUgRXZhbHVhdGlvbkNvbnRleHQgIGZyb20gJy4uL2V2YWx1YXRpb25fY29udGV4dC5qcyc7XG5cbmNsYXNzIFZhciBpbXBsZW1lbnRzIEV4cHJlc3Npb24ge1xuICAgIHR5cGU6IFR5cGU7XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIGJvdW5kRXhwcmVzc2lvbjogRXhwcmVzc2lvbjtcblxuICAgIGNvbnN0cnVjdG9yKG5hbWU6IHN0cmluZywgYm91bmRFeHByZXNzaW9uOiBFeHByZXNzaW9uKSB7XG4gICAgICAgIHRoaXMudHlwZSA9IGJvdW5kRXhwcmVzc2lvbi50eXBlO1xuICAgICAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgICAgICB0aGlzLmJvdW5kRXhwcmVzc2lvbiA9IGJvdW5kRXhwcmVzc2lvbjtcbiAgICB9XG5cbiAgICBzdGF0aWMgcGFyc2UoYXJnczogJFJlYWRPbmx5QXJyYXk8bWl4ZWQ+LCBjb250ZXh0OiBQYXJzaW5nQ29udGV4dCk6IHZvaWQgfCBWYXIge1xuICAgICAgICBpZiAoYXJncy5sZW5ndGggIT09IDIgfHwgdHlwZW9mIGFyZ3NbMV0gIT09ICdzdHJpbmcnKVxuICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQuZXJyb3IoYCd2YXInIGV4cHJlc3Npb24gcmVxdWlyZXMgZXhhY3RseSBvbmUgc3RyaW5nIGxpdGVyYWwgYXJndW1lbnQuYCk7XG5cbiAgICAgICAgY29uc3QgbmFtZSA9IGFyZ3NbMV07XG4gICAgICAgIGlmICghY29udGV4dC5zY29wZS5oYXMobmFtZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmVycm9yKGBVbmtub3duIHZhcmlhYmxlIFwiJHtuYW1lfVwiLiBNYWtlIHN1cmUgXCIke25hbWV9XCIgaGFzIGJlZW4gYm91bmQgaW4gYW4gZW5jbG9zaW5nIFwibGV0XCIgZXhwcmVzc2lvbiBiZWZvcmUgdXNpbmcgaXQuYCwgMSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IFZhcihuYW1lLCBjb250ZXh0LnNjb3BlLmdldChuYW1lKSk7XG4gICAgfVxuXG4gICAgZXZhbHVhdGUoY3R4OiBFdmFsdWF0aW9uQ29udGV4dCk6IGFueSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJvdW5kRXhwcmVzc2lvbi5ldmFsdWF0ZShjdHgpO1xuICAgIH1cblxuICAgIGVhY2hDaGlsZCgpIHt9XG5cbiAgICBvdXRwdXREZWZpbmVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgc2VyaWFsaXplKCk6IEFycmF5PHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gW1widmFyXCIsIHRoaXMubmFtZV07XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBWYXI7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgU2NvcGUgZnJvbSAnLi9zY29wZS5qcyc7XG5pbXBvcnQge2NoZWNrU3VidHlwZX0gZnJvbSAnLi90eXBlcy5qcyc7XG5pbXBvcnQgUGFyc2luZ0Vycm9yIGZyb20gJy4vcGFyc2luZ19lcnJvci5qcyc7XG5pbXBvcnQgTGl0ZXJhbCBmcm9tICcuL2RlZmluaXRpb25zL2xpdGVyYWwuanMnO1xuaW1wb3J0IEFzc2VydGlvbiBmcm9tICcuL2RlZmluaXRpb25zL2Fzc2VydGlvbi5qcyc7XG5pbXBvcnQgQ29lcmNpb24gZnJvbSAnLi9kZWZpbml0aW9ucy9jb2VyY2lvbi5qcyc7XG5pbXBvcnQgRXZhbHVhdGlvbkNvbnRleHQgZnJvbSAnLi9ldmFsdWF0aW9uX2NvbnRleHQuanMnO1xuaW1wb3J0IENvbXBvdW5kRXhwcmVzc2lvbiBmcm9tICcuL2NvbXBvdW5kX2V4cHJlc3Npb24uanMnO1xuaW1wb3J0IENvbGxhdG9yRXhwcmVzc2lvbiBmcm9tICcuL2RlZmluaXRpb25zL2NvbGxhdG9yLmpzJztcbmltcG9ydCBXaXRoaW4gZnJvbSAnLi9kZWZpbml0aW9ucy93aXRoaW4uanMnO1xuaW1wb3J0IHtpc0dsb2JhbFByb3BlcnR5Q29uc3RhbnQsIGlzRmVhdHVyZUNvbnN0YW50fSBmcm9tICcuL2lzX2NvbnN0YW50LmpzJztcbmltcG9ydCBWYXIgZnJvbSAnLi9kZWZpbml0aW9ucy92YXIuanMnO1xuXG5pbXBvcnQgdHlwZSB7RXhwcmVzc2lvbiwgRXhwcmVzc2lvblJlZ2lzdHJ5fSBmcm9tICcuL2V4cHJlc3Npb24uanMnO1xuaW1wb3J0IHR5cGUge1R5cGV9IGZyb20gJy4vdHlwZXMuanMnO1xuXG4vKipcbiAqIFN0YXRlIGFzc29jaWF0ZWQgcGFyc2luZyBhdCBhIGdpdmVuIHBvaW50IGluIGFuIGV4cHJlc3Npb24gdHJlZS5cbiAqIEBwcml2YXRlXG4gKi9cbmNsYXNzIFBhcnNpbmdDb250ZXh0IHtcbiAgICByZWdpc3RyeTogRXhwcmVzc2lvblJlZ2lzdHJ5O1xuICAgIHBhdGg6IEFycmF5PG51bWJlcj47XG4gICAga2V5OiBzdHJpbmc7XG4gICAgc2NvcGU6IFNjb3BlO1xuICAgIGVycm9yczogQXJyYXk8UGFyc2luZ0Vycm9yPjtcblxuICAgIC8vIFRoZSBleHBlY3RlZCB0eXBlIG9mIHRoaXMgZXhwcmVzc2lvbi4gUHJvdmlkZWQgb25seSB0byBhbGxvdyBFeHByZXNzaW9uXG4gICAgLy8gaW1wbGVtZW50YXRpb25zIHRvIGluZmVyIGFyZ3VtZW50IHR5cGVzOiBFeHByZXNzaW9uI3BhcnNlKCkgbmVlZCBub3RcbiAgICAvLyBjaGVjayB0aGF0IHRoZSBvdXRwdXQgdHlwZSBvZiB0aGUgcGFyc2VkIGV4cHJlc3Npb24gbWF0Y2hlc1xuICAgIC8vIGBleHBlY3RlZFR5cGVgLlxuICAgIGV4cGVjdGVkVHlwZTogP1R5cGU7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcmVnaXN0cnk6IEV4cHJlc3Npb25SZWdpc3RyeSxcbiAgICAgICAgcGF0aDogQXJyYXk8bnVtYmVyPiA9IFtdLFxuICAgICAgICBleHBlY3RlZFR5cGU6ID9UeXBlLFxuICAgICAgICBzY29wZTogU2NvcGUgPSBuZXcgU2NvcGUoKSxcbiAgICAgICAgZXJyb3JzOiBBcnJheTxQYXJzaW5nRXJyb3I+ID0gW11cbiAgICApIHtcbiAgICAgICAgdGhpcy5yZWdpc3RyeSA9IHJlZ2lzdHJ5O1xuICAgICAgICB0aGlzLnBhdGggPSBwYXRoO1xuICAgICAgICB0aGlzLmtleSA9IHBhdGgubWFwKHBhcnQgPT4gYFske3BhcnR9XWApLmpvaW4oJycpO1xuICAgICAgICB0aGlzLnNjb3BlID0gc2NvcGU7XG4gICAgICAgIHRoaXMuZXJyb3JzID0gZXJyb3JzO1xuICAgICAgICB0aGlzLmV4cGVjdGVkVHlwZSA9IGV4cGVjdGVkVHlwZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZXhwciB0aGUgSlNPTiBleHByZXNzaW9uIHRvIHBhcnNlXG4gICAgICogQHBhcmFtIGluZGV4IHRoZSBvcHRpb25hbCBhcmd1bWVudCBpbmRleCBpZiB0aGlzIGV4cHJlc3Npb24gaXMgYW4gYXJndW1lbnQgb2YgYSBwYXJlbnQgZXhwcmVzc2lvbiB0aGF0J3MgYmVpbmcgcGFyc2VkXG4gICAgICogQHBhcmFtIG9wdGlvbnNcbiAgICAgKiBAcGFyYW0gb3B0aW9ucy5vbWl0VHlwZUFubm90YXRpb25zIHNldCB0cnVlIHRvIG9taXQgaW5mZXJyZWQgdHlwZSBhbm5vdGF0aW9ucy4gIENhbGxlciBiZXdhcmU6IHdpdGggdGhpcyBvcHRpb24gc2V0LCB0aGUgcGFyc2VkIGV4cHJlc3Npb24ncyB0eXBlIHdpbGwgTk9UIHNhdGlzZnkgYGV4cGVjdGVkVHlwZWAgaWYgaXQgd291bGQgbm9ybWFsbHkgYmUgd3JhcHBlZCBpbiBhbiBpbmZlcnJlZCBhbm5vdGF0aW9uLlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcGFyc2UoXG4gICAgICAgIGV4cHI6IG1peGVkLFxuICAgICAgICBpbmRleD86IG51bWJlcixcbiAgICAgICAgZXhwZWN0ZWRUeXBlPzogP1R5cGUsXG4gICAgICAgIGJpbmRpbmdzPzogQXJyYXk8W3N0cmluZywgRXhwcmVzc2lvbl0+LFxuICAgICAgICBvcHRpb25zOiB7dHlwZUFubm90YXRpb24/OiAnYXNzZXJ0JyB8ICdjb2VyY2UnIHwgJ29taXQnfSA9IHt9XG4gICAgKTogP0V4cHJlc3Npb24ge1xuICAgICAgICBpZiAoaW5kZXgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbmNhdChpbmRleCwgZXhwZWN0ZWRUeXBlLCBiaW5kaW5ncykuX3BhcnNlKGV4cHIsIG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJzZShleHByLCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICBfcGFyc2UoZXhwcjogbWl4ZWQsIG9wdGlvbnM6IHt0eXBlQW5ub3RhdGlvbj86ICdhc3NlcnQnIHwgJ2NvZXJjZScgfCAnb21pdCd9KTogP0V4cHJlc3Npb24ge1xuICAgICAgICBpZiAoZXhwciA9PT0gbnVsbCB8fCB0eXBlb2YgZXhwciA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIGV4cHIgPT09ICdib29sZWFuJyB8fCB0eXBlb2YgZXhwciA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIGV4cHIgPSBbJ2xpdGVyYWwnLCBleHByXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGFubm90YXRlKHBhcnNlZDogRXhwcmVzc2lvbiwgdHlwZTogVHlwZSwgdHlwZUFubm90YXRpb246ICdhc3NlcnQnIHwgJ2NvZXJjZScgfCAnb21pdCcpIHtcbiAgICAgICAgICAgIGlmICh0eXBlQW5ub3RhdGlvbiA9PT0gJ2Fzc2VydCcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEFzc2VydGlvbih0eXBlLCBbcGFyc2VkXSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVBbm5vdGF0aW9uID09PSAnY29lcmNlJykge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQ29lcmNpb24odHlwZSwgW3BhcnNlZF0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZXhwcikpIHtcbiAgICAgICAgICAgIGlmIChleHByLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVycm9yKGBFeHBlY3RlZCBhbiBhcnJheSB3aXRoIGF0IGxlYXN0IG9uZSBlbGVtZW50LiBJZiB5b3Ugd2FudGVkIGEgbGl0ZXJhbCBhcnJheSwgdXNlIFtcImxpdGVyYWxcIiwgW11dLmApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBvcCA9IGV4cHJbMF07XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9wICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3IoYEV4cHJlc3Npb24gbmFtZSBtdXN0IGJlIGEgc3RyaW5nLCBidXQgZm91bmQgJHt0eXBlb2Ygb3B9IGluc3RlYWQuIElmIHlvdSB3YW50ZWQgYSBsaXRlcmFsIGFycmF5LCB1c2UgW1wibGl0ZXJhbFwiLCBbLi4uXV0uYCwgMCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IEV4cHIgPSB0aGlzLnJlZ2lzdHJ5W29wXTtcbiAgICAgICAgICAgIGlmIChFeHByKSB7XG4gICAgICAgICAgICAgICAgbGV0IHBhcnNlZCA9IEV4cHIucGFyc2UoZXhwciwgdGhpcyk7XG4gICAgICAgICAgICAgICAgaWYgKCFwYXJzZWQpIHJldHVybiBudWxsO1xuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZXhwZWN0ZWRUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4cGVjdGVkID0gdGhpcy5leHBlY3RlZFR5cGU7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFjdHVhbCA9IHBhcnNlZC50eXBlO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gd2UgZXhwZWN0IGEgbnVtYmVyLCBzdHJpbmcsIGJvb2xlYW4sIG9yIGFycmF5IGJ1dCBoYXZlIGEgdmFsdWUsIHdyYXAgaXQgaW4gYW4gYXNzZXJ0aW9uLlxuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIHdlIGV4cGVjdCBhIGNvbG9yIG9yIGZvcm1hdHRlZCBzdHJpbmcsIGJ1dCBoYXZlIGEgc3RyaW5nIG9yIHZhbHVlLCB3cmFwIGl0IGluIGEgY29lcmNpb24uXG4gICAgICAgICAgICAgICAgICAgIC8vIE90aGVyd2lzZSwgd2UgZG8gc3RhdGljIHR5cGUtY2hlY2tpbmcuXG4gICAgICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgICAgIC8vIFRoZXNlIGJlaGF2aW9ycyBhcmUgb3ZlcnJpZGFibGUgZm9yOlxuICAgICAgICAgICAgICAgICAgICAvLyAgICogVGhlIFwiY29hbGVzY2VcIiBvcGVyYXRvciwgd2hpY2ggbmVlZHMgdG8gb21pdCB0eXBlIGFubm90YXRpb25zLlxuICAgICAgICAgICAgICAgICAgICAvLyAgICogU3RyaW5nLXZhbHVlZCBwcm9wZXJ0aWVzIChlLmcuIGB0ZXh0LWZpZWxkYCksIHdoZXJlIGNvZXJjaW9uIGlzIG1vcmUgY29udmVuaWVudCB0aGFuIGFzc2VydGlvbi5cbiAgICAgICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAgICAgaWYgKChleHBlY3RlZC5raW5kID09PSAnc3RyaW5nJyB8fCBleHBlY3RlZC5raW5kID09PSAnbnVtYmVyJyB8fCBleHBlY3RlZC5raW5kID09PSAnYm9vbGVhbicgfHwgZXhwZWN0ZWQua2luZCA9PT0gJ29iamVjdCcgfHwgZXhwZWN0ZWQua2luZCA9PT0gJ2FycmF5JykgJiYgYWN0dWFsLmtpbmQgPT09ICd2YWx1ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlZCA9IGFubm90YXRlKHBhcnNlZCwgZXhwZWN0ZWQsIG9wdGlvbnMudHlwZUFubm90YXRpb24gfHwgJ2Fzc2VydCcpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChleHBlY3RlZC5raW5kID09PSAnY29sb3InIHx8IGV4cGVjdGVkLmtpbmQgPT09ICdmb3JtYXR0ZWQnIHx8IGV4cGVjdGVkLmtpbmQgPT09ICdyZXNvbHZlZEltYWdlJykgJiYgKGFjdHVhbC5raW5kID09PSAndmFsdWUnIHx8IGFjdHVhbC5raW5kID09PSAnc3RyaW5nJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlZCA9IGFubm90YXRlKHBhcnNlZCwgZXhwZWN0ZWQsIG9wdGlvbnMudHlwZUFubm90YXRpb24gfHwgJ2NvZXJjZScpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuY2hlY2tTdWJ0eXBlKGV4cGVjdGVkLCBhY3R1YWwpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIElmIGFuIGV4cHJlc3Npb24ncyBhcmd1bWVudHMgYXJlIGFsbCBsaXRlcmFscywgd2UgY2FuIGV2YWx1YXRlXG4gICAgICAgICAgICAgICAgLy8gaXQgaW1tZWRpYXRlbHkgYW5kIHJlcGxhY2UgaXQgd2l0aCBhIGxpdGVyYWwgdmFsdWUgaW4gdGhlXG4gICAgICAgICAgICAgICAgLy8gcGFyc2VkL2NvbXBpbGVkIHJlc3VsdC4gRXhwcmVzc2lvbnMgdGhhdCBleHBlY3QgYW4gaW1hZ2Ugc2hvdWxkXG4gICAgICAgICAgICAgICAgLy8gbm90IGJlIHJlc29sdmVkIGhlcmUgc28gd2UgY2FuIGxhdGVyIGdldCB0aGUgYXZhaWxhYmxlIGltYWdlcy5cbiAgICAgICAgICAgICAgICBpZiAoIShwYXJzZWQgaW5zdGFuY2VvZiBMaXRlcmFsKSAmJiAocGFyc2VkLnR5cGUua2luZCAhPT0gJ3Jlc29sdmVkSW1hZ2UnKSAmJiBpc0NvbnN0YW50KHBhcnNlZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZWMgPSBuZXcgRXZhbHVhdGlvbkNvbnRleHQoKTtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlZCA9IG5ldyBMaXRlcmFsKHBhcnNlZC50eXBlLCBwYXJzZWQuZXZhbHVhdGUoZWMpKTtcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lcnJvcihlLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VkO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5lcnJvcihgVW5rbm93biBleHByZXNzaW9uIFwiJHtvcH1cIi4gSWYgeW91IHdhbnRlZCBhIGxpdGVyYWwgYXJyYXksIHVzZSBbXCJsaXRlcmFsXCIsIFsuLi5dXS5gLCAwKTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZXhwciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVycm9yKGAndW5kZWZpbmVkJyB2YWx1ZSBpbnZhbGlkLiBVc2UgbnVsbCBpbnN0ZWFkLmApO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBleHByID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXJyb3IoYEJhcmUgb2JqZWN0cyBpbnZhbGlkLiBVc2UgW1wibGl0ZXJhbFwiLCB7Li4ufV0gaW5zdGVhZC5gKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVycm9yKGBFeHBlY3RlZCBhbiBhcnJheSwgYnV0IGZvdW5kICR7dHlwZW9mIGV4cHJ9IGluc3RlYWQuYCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgY29weSBvZiB0aGlzIGNvbnRleHQgc3VpdGFibGUgZm9yIHBhcnNpbmcgdGhlIHN1YmV4cHJlc3Npb24gYXRcbiAgICAgKiBpbmRleCBgaW5kZXhgLCBvcHRpb25hbGx5IGFwcGVuZGluZyB0byAnbGV0JyBiaW5kaW5nIG1hcC5cbiAgICAgKlxuICAgICAqIE5vdGUgdGhhdCBgZXJyb3JzYCBwcm9wZXJ0eSwgaW50ZW5kZWQgZm9yIGNvbGxlY3RpbmcgZXJyb3JzIHdoaWxlXG4gICAgICogcGFyc2luZywgaXMgY29waWVkIGJ5IHJlZmVyZW5jZSByYXRoZXIgdGhhbiBjbG9uZWQuXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBjb25jYXQoaW5kZXg6IG51bWJlciwgZXhwZWN0ZWRUeXBlPzogP1R5cGUsIGJpbmRpbmdzPzogQXJyYXk8W3N0cmluZywgRXhwcmVzc2lvbl0+KTogUGFyc2luZ0NvbnRleHQge1xuICAgICAgICBjb25zdCBwYXRoID0gdHlwZW9mIGluZGV4ID09PSAnbnVtYmVyJyA/IHRoaXMucGF0aC5jb25jYXQoaW5kZXgpIDogdGhpcy5wYXRoO1xuICAgICAgICBjb25zdCBzY29wZSA9IGJpbmRpbmdzID8gdGhpcy5zY29wZS5jb25jYXQoYmluZGluZ3MpIDogdGhpcy5zY29wZTtcbiAgICAgICAgcmV0dXJuIG5ldyBQYXJzaW5nQ29udGV4dChcbiAgICAgICAgICAgIHRoaXMucmVnaXN0cnksXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgZXhwZWN0ZWRUeXBlIHx8IG51bGwsXG4gICAgICAgICAgICBzY29wZSxcbiAgICAgICAgICAgIHRoaXMuZXJyb3JzXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHVzaCBhIHBhcnNpbmcgKG9yIHR5cGUgY2hlY2tpbmcpIGVycm9yIGludG8gdGhlIGB0aGlzLmVycm9yc2BcbiAgICAgKiBAcGFyYW0gZXJyb3IgVGhlIG1lc3NhZ2VcbiAgICAgKiBAcGFyYW0ga2V5cyBPcHRpb25hbGx5IHNwZWNpZnkgdGhlIHNvdXJjZSBvZiB0aGUgZXJyb3IgYXQgYSBjaGlsZFxuICAgICAqIG9mIHRoZSBjdXJyZW50IGV4cHJlc3Npb24gYXQgYHRoaXMua2V5YC5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIGVycm9yKGVycm9yOiBzdHJpbmcsIC4uLmtleXM6IEFycmF5PG51bWJlcj4pIHtcbiAgICAgICAgY29uc3Qga2V5ID0gYCR7dGhpcy5rZXl9JHtrZXlzLm1hcChrID0+IGBbJHtrfV1gKS5qb2luKCcnKX1gO1xuICAgICAgICB0aGlzLmVycm9ycy5wdXNoKG5ldyBQYXJzaW5nRXJyb3Ioa2V5LCBlcnJvcikpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgbnVsbCBpZiBgdGAgaXMgYSBzdWJ0eXBlIG9mIGBleHBlY3RlZGA7IG90aGVyd2lzZSByZXR1cm5zIGFuXG4gICAgICogZXJyb3IgbWVzc2FnZSBhbmQgYWxzbyBwdXNoZXMgaXQgdG8gYHRoaXMuZXJyb3JzYC5cbiAgICAgKi9cbiAgICBjaGVja1N1YnR5cGUoZXhwZWN0ZWQ6IFR5cGUsIHQ6IFR5cGUpOiA/c3RyaW5nIHtcbiAgICAgICAgY29uc3QgZXJyb3IgPSBjaGVja1N1YnR5cGUoZXhwZWN0ZWQsIHQpO1xuICAgICAgICBpZiAoZXJyb3IpIHRoaXMuZXJyb3IoZXJyb3IpO1xuICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBQYXJzaW5nQ29udGV4dDtcblxuZnVuY3Rpb24gaXNDb25zdGFudChleHByZXNzaW9uOiBFeHByZXNzaW9uKSB7XG4gICAgaWYgKGV4cHJlc3Npb24gaW5zdGFuY2VvZiBWYXIpIHtcbiAgICAgICAgcmV0dXJuIGlzQ29uc3RhbnQoZXhwcmVzc2lvbi5ib3VuZEV4cHJlc3Npb24pO1xuICAgIH0gZWxzZSBpZiAoZXhwcmVzc2lvbiBpbnN0YW5jZW9mIENvbXBvdW5kRXhwcmVzc2lvbiAmJiBleHByZXNzaW9uLm5hbWUgPT09ICdlcnJvcicpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gZWxzZSBpZiAoZXhwcmVzc2lvbiBpbnN0YW5jZW9mIENvbGxhdG9yRXhwcmVzc2lvbikge1xuICAgICAgICAvLyBBbHRob3VnaCB0aGUgcmVzdWx0cyBvZiBhIENvbGxhdG9yIGV4cHJlc3Npb24gd2l0aCBmaXhlZCBhcmd1bWVudHNcbiAgICAgICAgLy8gZ2VuZXJhbGx5IHNob3VsZG4ndCBjaGFuZ2UgYmV0d2VlbiBleGVjdXRpb25zLCB3ZSBjYW4ndCBzZXJpYWxpemUgdGhlbVxuICAgICAgICAvLyBhcyBjb25zdGFudCBleHByZXNzaW9ucyBiZWNhdXNlIHJlc3VsdHMgY2hhbmdlIGJhc2VkIG9uIGVudmlyb25tZW50LlxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBlbHNlIGlmIChleHByZXNzaW9uIGluc3RhbmNlb2YgV2l0aGluKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCBpc1R5cGVBbm5vdGF0aW9uID0gZXhwcmVzc2lvbiBpbnN0YW5jZW9mIENvZXJjaW9uIHx8XG4gICAgICAgIGV4cHJlc3Npb24gaW5zdGFuY2VvZiBBc3NlcnRpb247XG5cbiAgICBsZXQgY2hpbGRyZW5Db25zdGFudCA9IHRydWU7XG4gICAgZXhwcmVzc2lvbi5lYWNoQ2hpbGQoY2hpbGQgPT4ge1xuICAgICAgICAvLyBXZSBjYW4gX2FsbW9zdF8gYXNzdW1lIHRoYXQgaWYgYGV4cHJlc3Npb25zYCBjaGlsZHJlbiBhcmUgY29uc3RhbnQsXG4gICAgICAgIC8vIHRoZXkgd291bGQgYWxyZWFkeSBoYXZlIGJlZW4gZXZhbHVhdGVkIHRvIExpdGVyYWwgdmFsdWVzIHdoZW4gdGhleVxuICAgICAgICAvLyB3ZXJlIHBhcnNlZC4gIFR5cGUgYW5ub3RhdGlvbnMgYXJlIHRoZSBleGNlcHRpb24sIGJlY2F1c2UgdGhleSBtaWdodFxuICAgICAgICAvLyBoYXZlIGJlZW4gaW5mZXJyZWQgYW5kIGFkZGVkIGFmdGVyIGEgY2hpbGQgd2FzIHBhcnNlZC5cblxuICAgICAgICAvLyBTbyB3ZSByZWN1cnNlIGludG8gaXNDb25zdGFudCgpIGZvciB0aGUgY2hpbGRyZW4gb2YgdHlwZSBhbm5vdGF0aW9ucyxcbiAgICAgICAgLy8gYnV0IG90aGVyd2lzZSBzaW1wbHkgY2hlY2sgd2hldGhlciB0aGV5IGFyZSBMaXRlcmFscy5cbiAgICAgICAgaWYgKGlzVHlwZUFubm90YXRpb24pIHtcbiAgICAgICAgICAgIGNoaWxkcmVuQ29uc3RhbnQgPSBjaGlsZHJlbkNvbnN0YW50ICYmIGlzQ29uc3RhbnQoY2hpbGQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2hpbGRyZW5Db25zdGFudCA9IGNoaWxkcmVuQ29uc3RhbnQgJiYgY2hpbGQgaW5zdGFuY2VvZiBMaXRlcmFsO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgaWYgKCFjaGlsZHJlbkNvbnN0YW50KSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gaXNGZWF0dXJlQ29uc3RhbnQoZXhwcmVzc2lvbikgJiZcbiAgICAgICAgaXNHbG9iYWxQcm9wZXJ0eUNvbnN0YW50KGV4cHJlc3Npb24sIFsnem9vbScsICdoZWF0bWFwLWRlbnNpdHknLCAnbGluZS1wcm9ncmVzcycsICdza3ktcmFkaWFsLXByb2dyZXNzJywgJ2FjY3VtdWxhdGVkJywgJ2lzLXN1cHBvcnRlZC1zY3JpcHQnLCAncGl0Y2gnLCAnZGlzdGFuY2UtZnJvbS1jZW50ZXInXSk7XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgUnVudGltZUVycm9yIGZyb20gJy4vcnVudGltZV9lcnJvci5qcyc7XG5cbmltcG9ydCB0eXBlIHtFeHByZXNzaW9ufSBmcm9tICcuL2V4cHJlc3Npb24uanMnO1xuXG5leHBvcnQgdHlwZSBTdG9wcyA9IEFycmF5PFtudW1iZXIsIEV4cHJlc3Npb25dPjtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBzdG9wIDw9IGlucHV0LCBvciAwIGlmIGl0IGRvZXNuJ3QgZXhpc3QuXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZmluZFN0b3BMZXNzVGhhbk9yRXF1YWxUbyhzdG9wczogQXJyYXk8bnVtYmVyPiwgaW5wdXQ6IG51bWJlcik6IG51bWJlciB7XG4gICAgY29uc3QgbGFzdEluZGV4ID0gc3RvcHMubGVuZ3RoIC0gMTtcbiAgICBsZXQgbG93ZXJJbmRleCA9IDA7XG4gICAgbGV0IHVwcGVySW5kZXggPSBsYXN0SW5kZXg7XG4gICAgbGV0IGN1cnJlbnRJbmRleCA9IDA7XG4gICAgbGV0IGN1cnJlbnRWYWx1ZSwgbmV4dFZhbHVlO1xuXG4gICAgd2hpbGUgKGxvd2VySW5kZXggPD0gdXBwZXJJbmRleCkge1xuICAgICAgICBjdXJyZW50SW5kZXggPSBNYXRoLmZsb29yKChsb3dlckluZGV4ICsgdXBwZXJJbmRleCkgLyAyKTtcbiAgICAgICAgY3VycmVudFZhbHVlID0gc3RvcHNbY3VycmVudEluZGV4XTtcbiAgICAgICAgbmV4dFZhbHVlID0gc3RvcHNbY3VycmVudEluZGV4ICsgMV07XG5cbiAgICAgICAgaWYgKGN1cnJlbnRWYWx1ZSA8PSBpbnB1dCkge1xuICAgICAgICAgICAgaWYgKGN1cnJlbnRJbmRleCA9PT0gbGFzdEluZGV4IHx8IGlucHV0IDwgbmV4dFZhbHVlKSB7IC8vIFNlYXJjaCBjb21wbGV0ZVxuICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50SW5kZXg7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxvd2VySW5kZXggPSBjdXJyZW50SW5kZXggKyAxO1xuICAgICAgICB9IGVsc2UgaWYgKGN1cnJlbnRWYWx1ZSA+IGlucHV0KSB7XG4gICAgICAgICAgICB1cHBlckluZGV4ID0gY3VycmVudEluZGV4IC0gMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXJyb3IoJ0lucHV0IGlzIG5vdCBhIG51bWJlci4nKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiAwO1xufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtOdW1iZXJUeXBlfSBmcm9tICcuLi90eXBlcy5qcyc7XG5cbmltcG9ydCB7ZmluZFN0b3BMZXNzVGhhbk9yRXF1YWxUb30gZnJvbSAnLi4vc3RvcHMuanMnO1xuXG5pbXBvcnQgdHlwZSB7U3RvcHN9IGZyb20gJy4uL3N0b3BzLmpzJztcbmltcG9ydCB0eXBlIHtFeHByZXNzaW9uLCBTZXJpYWxpemVkRXhwcmVzc2lvbn0gZnJvbSAnLi4vZXhwcmVzc2lvbi5qcyc7XG5pbXBvcnQgdHlwZSBQYXJzaW5nQ29udGV4dCBmcm9tICcuLi9wYXJzaW5nX2NvbnRleHQuanMnO1xuaW1wb3J0IHR5cGUgRXZhbHVhdGlvbkNvbnRleHQgZnJvbSAnLi4vZXZhbHVhdGlvbl9jb250ZXh0LmpzJztcbmltcG9ydCB0eXBlIHtUeXBlfSBmcm9tICcuLi90eXBlcy5qcyc7XG5cbmNsYXNzIFN0ZXAgaW1wbGVtZW50cyBFeHByZXNzaW9uIHtcbiAgICB0eXBlOiBUeXBlO1xuXG4gICAgaW5wdXQ6IEV4cHJlc3Npb247XG4gICAgbGFiZWxzOiBBcnJheTxudW1iZXI+O1xuICAgIG91dHB1dHM6IEFycmF5PEV4cHJlc3Npb24+O1xuXG4gICAgY29uc3RydWN0b3IodHlwZTogVHlwZSwgaW5wdXQ6IEV4cHJlc3Npb24sIHN0b3BzOiBTdG9wcykge1xuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLmlucHV0ID0gaW5wdXQ7XG5cbiAgICAgICAgdGhpcy5sYWJlbHMgPSBbXTtcbiAgICAgICAgdGhpcy5vdXRwdXRzID0gW107XG4gICAgICAgIGZvciAoY29uc3QgW2xhYmVsLCBleHByZXNzaW9uXSBvZiBzdG9wcykge1xuICAgICAgICAgICAgdGhpcy5sYWJlbHMucHVzaChsYWJlbCk7XG4gICAgICAgICAgICB0aGlzLm91dHB1dHMucHVzaChleHByZXNzaW9uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyBwYXJzZShhcmdzOiAkUmVhZE9ubHlBcnJheTxtaXhlZD4sIGNvbnRleHQ6IFBhcnNpbmdDb250ZXh0KTogP1N0ZXAge1xuICAgICAgICBpZiAoYXJncy5sZW5ndGggLSAxIDwgNCkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQuZXJyb3IoYEV4cGVjdGVkIGF0IGxlYXN0IDQgYXJndW1lbnRzLCBidXQgZm91bmQgb25seSAke2FyZ3MubGVuZ3RoIC0gMX0uYCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoKGFyZ3MubGVuZ3RoIC0gMSkgJSAyICE9PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gY29udGV4dC5lcnJvcihgRXhwZWN0ZWQgYW4gZXZlbiBudW1iZXIgb2YgYXJndW1lbnRzLmApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaW5wdXQgPSBjb250ZXh0LnBhcnNlKGFyZ3NbMV0sIDEsIE51bWJlclR5cGUpO1xuICAgICAgICBpZiAoIWlucHV0KSByZXR1cm4gbnVsbDtcblxuICAgICAgICBjb25zdCBzdG9wczogU3RvcHMgPSBbXTtcblxuICAgICAgICBsZXQgb3V0cHV0VHlwZTogVHlwZSA9IChudWxsOiBhbnkpO1xuICAgICAgICBpZiAoY29udGV4dC5leHBlY3RlZFR5cGUgJiYgY29udGV4dC5leHBlY3RlZFR5cGUua2luZCAhPT0gJ3ZhbHVlJykge1xuICAgICAgICAgICAgb3V0cHV0VHlwZSA9IGNvbnRleHQuZXhwZWN0ZWRUeXBlO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBhcmdzLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgICAgICAgICBjb25zdCBsYWJlbCA9IGkgPT09IDEgPyAtSW5maW5pdHkgOiBhcmdzW2ldO1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBhcmdzW2kgKyAxXTtcblxuICAgICAgICAgICAgY29uc3QgbGFiZWxLZXkgPSBpO1xuICAgICAgICAgICAgY29uc3QgdmFsdWVLZXkgPSBpICsgMTtcblxuICAgICAgICAgICAgaWYgKHR5cGVvZiBsYWJlbCAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udGV4dC5lcnJvcignSW5wdXQvb3V0cHV0IHBhaXJzIGZvciBcInN0ZXBcIiBleHByZXNzaW9ucyBtdXN0IGJlIGRlZmluZWQgdXNpbmcgbGl0ZXJhbCBudW1lcmljIHZhbHVlcyAobm90IGNvbXB1dGVkIGV4cHJlc3Npb25zKSBmb3IgdGhlIGlucHV0IHZhbHVlcy4nLCBsYWJlbEtleSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChzdG9wcy5sZW5ndGggJiYgc3RvcHNbc3RvcHMubGVuZ3RoIC0gMV1bMF0gPj0gbGFiZWwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udGV4dC5lcnJvcignSW5wdXQvb3V0cHV0IHBhaXJzIGZvciBcInN0ZXBcIiBleHByZXNzaW9ucyBtdXN0IGJlIGFycmFuZ2VkIHdpdGggaW5wdXQgdmFsdWVzIGluIHN0cmljdGx5IGFzY2VuZGluZyBvcmRlci4nLCBsYWJlbEtleSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IGNvbnRleHQucGFyc2UodmFsdWUsIHZhbHVlS2V5LCBvdXRwdXRUeXBlKTtcbiAgICAgICAgICAgIGlmICghcGFyc2VkKSByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIG91dHB1dFR5cGUgPSBvdXRwdXRUeXBlIHx8IHBhcnNlZC50eXBlO1xuICAgICAgICAgICAgc3RvcHMucHVzaChbbGFiZWwsIHBhcnNlZF0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBTdGVwKG91dHB1dFR5cGUsIGlucHV0LCBzdG9wcyk7XG4gICAgfVxuXG4gICAgZXZhbHVhdGUoY3R4OiBFdmFsdWF0aW9uQ29udGV4dCk6IGFueSB7XG4gICAgICAgIGNvbnN0IGxhYmVscyA9IHRoaXMubGFiZWxzO1xuICAgICAgICBjb25zdCBvdXRwdXRzID0gdGhpcy5vdXRwdXRzO1xuXG4gICAgICAgIGlmIChsYWJlbHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICByZXR1cm4gb3V0cHV0c1swXS5ldmFsdWF0ZShjdHgpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdmFsdWUgPSAoKHRoaXMuaW5wdXQuZXZhbHVhdGUoY3R4KTogYW55KTogbnVtYmVyKTtcbiAgICAgICAgaWYgKHZhbHVlIDw9IGxhYmVsc1swXSkge1xuICAgICAgICAgICAgcmV0dXJuIG91dHB1dHNbMF0uZXZhbHVhdGUoY3R4KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHN0b3BDb3VudCA9IGxhYmVscy5sZW5ndGg7XG4gICAgICAgIGlmICh2YWx1ZSA+PSBsYWJlbHNbc3RvcENvdW50IC0gMV0pIHtcbiAgICAgICAgICAgIHJldHVybiBvdXRwdXRzW3N0b3BDb3VudCAtIDFdLmV2YWx1YXRlKGN0eCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBpbmRleCA9IGZpbmRTdG9wTGVzc1RoYW5PckVxdWFsVG8obGFiZWxzLCB2YWx1ZSk7XG4gICAgICAgIHJldHVybiBvdXRwdXRzW2luZGV4XS5ldmFsdWF0ZShjdHgpO1xuICAgIH1cblxuICAgIGVhY2hDaGlsZChmbjogKF86IEV4cHJlc3Npb24pID0+IHZvaWQpIHtcbiAgICAgICAgZm4odGhpcy5pbnB1dCk7XG4gICAgICAgIGZvciAoY29uc3QgZXhwcmVzc2lvbiBvZiB0aGlzLm91dHB1dHMpIHtcbiAgICAgICAgICAgIGZuKGV4cHJlc3Npb24pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb3V0cHV0RGVmaW5lZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMub3V0cHV0cy5ldmVyeShvdXQgPT4gb3V0Lm91dHB1dERlZmluZWQoKSk7XG4gICAgfVxuXG4gICAgc2VyaWFsaXplKCk6IFNlcmlhbGl6ZWRFeHByZXNzaW9uIHtcbiAgICAgICAgY29uc3Qgc2VyaWFsaXplZCA9IFtcInN0ZXBcIiwgdGhpcy5pbnB1dC5zZXJpYWxpemUoKV07XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5sYWJlbHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChpID4gMCkge1xuICAgICAgICAgICAgICAgIHNlcmlhbGl6ZWQucHVzaCh0aGlzLmxhYmVsc1tpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzZXJpYWxpemVkLnB1c2godGhpcy5vdXRwdXRzW2ldLnNlcmlhbGl6ZSgpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2VyaWFsaXplZDtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFN0ZXA7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgQ29sb3IgZnJvbSAnLi9jb2xvci5qcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBudW1iZXIoYTogbnVtYmVyLCBiOiBudW1iZXIsIHQ6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIChhICogKDEgLSB0KSkgKyAoYiAqIHQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29sb3IoZnJvbTogQ29sb3IsIHRvOiBDb2xvciwgdDogbnVtYmVyKTogQ29sb3Ige1xuICAgIHJldHVybiBuZXcgQ29sb3IoXG4gICAgICAgIG51bWJlcihmcm9tLnIsIHRvLnIsIHQpLFxuICAgICAgICBudW1iZXIoZnJvbS5nLCB0by5nLCB0KSxcbiAgICAgICAgbnVtYmVyKGZyb20uYiwgdG8uYiwgdCksXG4gICAgICAgIG51bWJlcihmcm9tLmEsIHRvLmEsIHQpXG4gICAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFycmF5KGZyb206IEFycmF5PG51bWJlcj4sIHRvOiBBcnJheTxudW1iZXI+LCB0OiBudW1iZXIpOiBBcnJheTxudW1iZXI+IHtcbiAgICByZXR1cm4gZnJvbS5tYXAoKGQsIGkpID0+IHtcbiAgICAgICAgcmV0dXJuIG51bWJlcihkLCB0b1tpXSwgdCk7XG4gICAgfSk7XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgQ29sb3IgZnJvbSAnLi9jb2xvci5qcyc7XG5cbmltcG9ydCB7bnVtYmVyIGFzIGludGVycG9sYXRlTnVtYmVyfSBmcm9tICcuL2ludGVycG9sYXRlLmpzJztcblxudHlwZSBMQUJDb2xvciA9IHtcbiAgICBsOiBudW1iZXIsXG4gICAgYTogbnVtYmVyLFxuICAgIGI6IG51bWJlcixcbiAgICBhbHBoYTogbnVtYmVyXG59O1xuXG50eXBlIEhDTENvbG9yID0ge1xuICAgIGg6IG51bWJlcixcbiAgICBjOiBudW1iZXIsXG4gICAgbDogbnVtYmVyLFxuICAgIGFscGhhOiBudW1iZXJcbn07XG5cbi8vIENvbnN0YW50c1xuY29uc3QgWG4gPSAwLjk1MDQ3MCwgLy8gRDY1IHN0YW5kYXJkIHJlZmVyZW50XG4gICAgWW4gPSAxLFxuICAgIFpuID0gMS4wODg4MzAsXG4gICAgdDAgPSA0IC8gMjksXG4gICAgdDEgPSA2IC8gMjksXG4gICAgdDIgPSAzICogdDEgKiB0MSxcbiAgICB0MyA9IHQxICogdDEgKiB0MSxcbiAgICBkZWcycmFkID0gTWF0aC5QSSAvIDE4MCxcbiAgICByYWQyZGVnID0gMTgwIC8gTWF0aC5QSTtcblxuLy8gVXRpbGl0aWVzXG5mdW5jdGlvbiB4eXoybGFiKHQ6IG51bWJlcikge1xuICAgIHJldHVybiB0ID4gdDMgPyBNYXRoLnBvdyh0LCAxIC8gMykgOiB0IC8gdDIgKyB0MDtcbn1cblxuZnVuY3Rpb24gbGFiMnh5eih0OiBudW1iZXIpIHtcbiAgICByZXR1cm4gdCA+IHQxID8gdCAqIHQgKiB0IDogdDIgKiAodCAtIHQwKTtcbn1cblxuZnVuY3Rpb24geHl6MnJnYih4OiBudW1iZXIpIHtcbiAgICByZXR1cm4gMjU1ICogKHggPD0gMC4wMDMxMzA4ID8gMTIuOTIgKiB4IDogMS4wNTUgKiBNYXRoLnBvdyh4LCAxIC8gMi40KSAtIDAuMDU1KTtcbn1cblxuZnVuY3Rpb24gcmdiMnh5eih4OiBudW1iZXIpIHtcbiAgICB4IC89IDI1NTtcbiAgICByZXR1cm4geCA8PSAwLjA0MDQ1ID8geCAvIDEyLjkyIDogTWF0aC5wb3coKHggKyAwLjA1NSkgLyAxLjA1NSwgMi40KTtcbn1cblxuLy8gTEFCXG5mdW5jdGlvbiByZ2JUb0xhYihyZ2JDb2xvcjogQ29sb3IpOiBMQUJDb2xvciB7XG4gICAgY29uc3QgYiA9IHJnYjJ4eXoocmdiQ29sb3IuciksXG4gICAgICAgIGEgPSByZ2IyeHl6KHJnYkNvbG9yLmcpLFxuICAgICAgICBsID0gcmdiMnh5eihyZ2JDb2xvci5iKSxcbiAgICAgICAgeCA9IHh5ejJsYWIoKDAuNDEyNDU2NCAqIGIgKyAwLjM1NzU3NjEgKiBhICsgMC4xODA0Mzc1ICogbCkgLyBYbiksXG4gICAgICAgIHkgPSB4eXoybGFiKCgwLjIxMjY3MjkgKiBiICsgMC43MTUxNTIyICogYSArIDAuMDcyMTc1MCAqIGwpIC8gWW4pLFxuICAgICAgICB6ID0geHl6MmxhYigoMC4wMTkzMzM5ICogYiArIDAuMTE5MTkyMCAqIGEgKyAwLjk1MDMwNDEgKiBsKSAvIFpuKTtcblxuICAgIHJldHVybiB7XG4gICAgICAgIGw6IDExNiAqIHkgLSAxNixcbiAgICAgICAgYTogNTAwICogKHggLSB5KSxcbiAgICAgICAgYjogMjAwICogKHkgLSB6KSxcbiAgICAgICAgYWxwaGE6IHJnYkNvbG9yLmFcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBsYWJUb1JnYihsYWJDb2xvcjogTEFCQ29sb3IpOiBDb2xvciB7XG4gICAgbGV0IHkgPSAobGFiQ29sb3IubCArIDE2KSAvIDExNixcbiAgICAgICAgeCA9IGlzTmFOKGxhYkNvbG9yLmEpID8geSA6IHkgKyBsYWJDb2xvci5hIC8gNTAwLFxuICAgICAgICB6ID0gaXNOYU4obGFiQ29sb3IuYikgPyB5IDogeSAtIGxhYkNvbG9yLmIgLyAyMDA7XG4gICAgeSA9IFluICogbGFiMnh5eih5KTtcbiAgICB4ID0gWG4gKiBsYWIyeHl6KHgpO1xuICAgIHogPSBabiAqIGxhYjJ4eXooeik7XG4gICAgcmV0dXJuIG5ldyBDb2xvcihcbiAgICAgICAgeHl6MnJnYigzLjI0MDQ1NDIgKiB4IC0gMS41MzcxMzg1ICogeSAtIDAuNDk4NTMxNCAqIHopLCAvLyBENjUgLT4gc1JHQlxuICAgICAgICB4eXoycmdiKC0wLjk2OTI2NjAgKiB4ICsgMS44NzYwMTA4ICogeSArIDAuMDQxNTU2MCAqIHopLFxuICAgICAgICB4eXoycmdiKDAuMDU1NjQzNCAqIHggLSAwLjIwNDAyNTkgKiB5ICsgMS4wNTcyMjUyICogeiksXG4gICAgICAgIGxhYkNvbG9yLmFscGhhXG4gICAgKTtcbn1cblxuZnVuY3Rpb24gaW50ZXJwb2xhdGVMYWIoZnJvbTogTEFCQ29sb3IsIHRvOiBMQUJDb2xvciwgdDogbnVtYmVyKTogTEFCQ29sb3Ige1xuICAgIHJldHVybiB7XG4gICAgICAgIGw6IGludGVycG9sYXRlTnVtYmVyKGZyb20ubCwgdG8ubCwgdCksXG4gICAgICAgIGE6IGludGVycG9sYXRlTnVtYmVyKGZyb20uYSwgdG8uYSwgdCksXG4gICAgICAgIGI6IGludGVycG9sYXRlTnVtYmVyKGZyb20uYiwgdG8uYiwgdCksXG4gICAgICAgIGFscGhhOiBpbnRlcnBvbGF0ZU51bWJlcihmcm9tLmFscGhhLCB0by5hbHBoYSwgdClcbiAgICB9O1xufVxuXG4vLyBIQ0xcbmZ1bmN0aW9uIHJnYlRvSGNsKHJnYkNvbG9yOiBDb2xvcik6IEhDTENvbG9yIHtcbiAgICBjb25zdCB7bCwgYSwgYn0gPSByZ2JUb0xhYihyZ2JDb2xvcik7XG4gICAgY29uc3QgaCA9IE1hdGguYXRhbjIoYiwgYSkgKiByYWQyZGVnO1xuICAgIHJldHVybiB7XG4gICAgICAgIGg6IGggPCAwID8gaCArIDM2MCA6IGgsXG4gICAgICAgIGM6IE1hdGguc3FydChhICogYSArIGIgKiBiKSxcbiAgICAgICAgbCxcbiAgICAgICAgYWxwaGE6IHJnYkNvbG9yLmFcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBoY2xUb1JnYihoY2xDb2xvcjogSENMQ29sb3IpOiBDb2xvciB7XG4gICAgY29uc3QgaCA9IGhjbENvbG9yLmggKiBkZWcycmFkLFxuICAgICAgICBjID0gaGNsQ29sb3IuYyxcbiAgICAgICAgbCA9IGhjbENvbG9yLmw7XG4gICAgcmV0dXJuIGxhYlRvUmdiKHtcbiAgICAgICAgbCxcbiAgICAgICAgYTogTWF0aC5jb3MoaCkgKiBjLFxuICAgICAgICBiOiBNYXRoLnNpbihoKSAqIGMsXG4gICAgICAgIGFscGhhOiBoY2xDb2xvci5hbHBoYVxuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBpbnRlcnBvbGF0ZUh1ZShhOiBudW1iZXIsIGI6IG51bWJlciwgdDogbnVtYmVyKSB7XG4gICAgY29uc3QgZCA9IGIgLSBhO1xuICAgIHJldHVybiBhICsgdCAqIChkID4gMTgwIHx8IGQgPCAtMTgwID8gZCAtIDM2MCAqIE1hdGgucm91bmQoZCAvIDM2MCkgOiBkKTtcbn1cblxuZnVuY3Rpb24gaW50ZXJwb2xhdGVIY2woZnJvbTogSENMQ29sb3IsIHRvOiBIQ0xDb2xvciwgdDogbnVtYmVyKTogSENMQ29sb3Ige1xuICAgIHJldHVybiB7XG4gICAgICAgIGg6IGludGVycG9sYXRlSHVlKGZyb20uaCwgdG8uaCwgdCksXG4gICAgICAgIGM6IGludGVycG9sYXRlTnVtYmVyKGZyb20uYywgdG8uYywgdCksXG4gICAgICAgIGw6IGludGVycG9sYXRlTnVtYmVyKGZyb20ubCwgdG8ubCwgdCksXG4gICAgICAgIGFscGhhOiBpbnRlcnBvbGF0ZU51bWJlcihmcm9tLmFscGhhLCB0by5hbHBoYSwgdClcbiAgICB9O1xufVxuXG5leHBvcnQgY29uc3QgbGFiID0ge1xuICAgIGZvcndhcmQ6IHJnYlRvTGFiLFxuICAgIHJldmVyc2U6IGxhYlRvUmdiLFxuICAgIGludGVycG9sYXRlOiBpbnRlcnBvbGF0ZUxhYlxufTtcblxuZXhwb3J0IGNvbnN0IGhjbCA9IHtcbiAgICBmb3J3YXJkOiByZ2JUb0hjbCxcbiAgICByZXZlcnNlOiBoY2xUb1JnYixcbiAgICBpbnRlcnBvbGF0ZTogaW50ZXJwb2xhdGVIY2xcbn07XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgVW5pdEJlemllciBmcm9tICdAbWFwYm94L3VuaXRiZXppZXInO1xuXG5pbXBvcnQgKiBhcyBpbnRlcnBvbGF0ZSBmcm9tICcuLi8uLi91dGlsL2ludGVycG9sYXRlLmpzJztcbmltcG9ydCB7dG9TdHJpbmcsIE51bWJlclR5cGUsIENvbG9yVHlwZX0gZnJvbSAnLi4vdHlwZXMuanMnO1xuaW1wb3J0IHtmaW5kU3RvcExlc3NUaGFuT3JFcXVhbFRvfSBmcm9tICcuLi9zdG9wcy5qcyc7XG5pbXBvcnQge2hjbCwgbGFifSBmcm9tICcuLi8uLi91dGlsL2NvbG9yX3NwYWNlcy5qcyc7XG5pbXBvcnQgQ29sb3IgZnJvbSAnLi4vLi4vdXRpbC9jb2xvci5qcyc7XG5cbmltcG9ydCB0eXBlIHtTdG9wc30gZnJvbSAnLi4vc3RvcHMuanMnO1xuaW1wb3J0IHR5cGUge0V4cHJlc3Npb24sIFNlcmlhbGl6ZWRFeHByZXNzaW9ufSBmcm9tICcuLi9leHByZXNzaW9uLmpzJztcbmltcG9ydCB0eXBlIFBhcnNpbmdDb250ZXh0IGZyb20gJy4uL3BhcnNpbmdfY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSBFdmFsdWF0aW9uQ29udGV4dCBmcm9tICcuLi9ldmFsdWF0aW9uX2NvbnRleHQuanMnO1xuaW1wb3J0IHR5cGUge1R5cGV9IGZyb20gJy4uL3R5cGVzLmpzJztcblxuZXhwb3J0IHR5cGUgSW50ZXJwb2xhdGlvblR5cGUgPVxuICAgIHsgbmFtZTogJ2xpbmVhcicgfSB8XG4gICAgeyBuYW1lOiAnZXhwb25lbnRpYWwnLCBiYXNlOiBudW1iZXIgfSB8XG4gICAgeyBuYW1lOiAnY3ViaWMtYmV6aWVyJywgY29udHJvbFBvaW50czogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gfTtcblxuY2xhc3MgSW50ZXJwb2xhdGUgaW1wbGVtZW50cyBFeHByZXNzaW9uIHtcbiAgICB0eXBlOiBUeXBlO1xuXG4gICAgb3BlcmF0b3I6ICdpbnRlcnBvbGF0ZScgfCAnaW50ZXJwb2xhdGUtaGNsJyB8ICdpbnRlcnBvbGF0ZS1sYWInO1xuICAgIGludGVycG9sYXRpb246IEludGVycG9sYXRpb25UeXBlO1xuICAgIGlucHV0OiBFeHByZXNzaW9uO1xuICAgIGxhYmVsczogQXJyYXk8bnVtYmVyPjtcbiAgICBvdXRwdXRzOiBBcnJheTxFeHByZXNzaW9uPjtcblxuICAgIGNvbnN0cnVjdG9yKHR5cGU6IFR5cGUsIG9wZXJhdG9yOiAnaW50ZXJwb2xhdGUnIHwgJ2ludGVycG9sYXRlLWhjbCcgfCAnaW50ZXJwb2xhdGUtbGFiJywgaW50ZXJwb2xhdGlvbjogSW50ZXJwb2xhdGlvblR5cGUsIGlucHV0OiBFeHByZXNzaW9uLCBzdG9wczogU3RvcHMpIHtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5vcGVyYXRvciA9IG9wZXJhdG9yO1xuICAgICAgICB0aGlzLmludGVycG9sYXRpb24gPSBpbnRlcnBvbGF0aW9uO1xuICAgICAgICB0aGlzLmlucHV0ID0gaW5wdXQ7XG5cbiAgICAgICAgdGhpcy5sYWJlbHMgPSBbXTtcbiAgICAgICAgdGhpcy5vdXRwdXRzID0gW107XG4gICAgICAgIGZvciAoY29uc3QgW2xhYmVsLCBleHByZXNzaW9uXSBvZiBzdG9wcykge1xuICAgICAgICAgICAgdGhpcy5sYWJlbHMucHVzaChsYWJlbCk7XG4gICAgICAgICAgICB0aGlzLm91dHB1dHMucHVzaChleHByZXNzaW9uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyBpbnRlcnBvbGF0aW9uRmFjdG9yKGludGVycG9sYXRpb246IEludGVycG9sYXRpb25UeXBlLCBpbnB1dDogbnVtYmVyLCBsb3dlcjogbnVtYmVyLCB1cHBlcjogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgbGV0IHQgPSAwO1xuICAgICAgICBpZiAoaW50ZXJwb2xhdGlvbi5uYW1lID09PSAnZXhwb25lbnRpYWwnKSB7XG4gICAgICAgICAgICB0ID0gZXhwb25lbnRpYWxJbnRlcnBvbGF0aW9uKGlucHV0LCBpbnRlcnBvbGF0aW9uLmJhc2UsIGxvd2VyLCB1cHBlcik7XG4gICAgICAgIH0gZWxzZSBpZiAoaW50ZXJwb2xhdGlvbi5uYW1lID09PSAnbGluZWFyJykge1xuICAgICAgICAgICAgdCA9IGV4cG9uZW50aWFsSW50ZXJwb2xhdGlvbihpbnB1dCwgMSwgbG93ZXIsIHVwcGVyKTtcbiAgICAgICAgfSBlbHNlIGlmIChpbnRlcnBvbGF0aW9uLm5hbWUgPT09ICdjdWJpYy1iZXppZXInKSB7XG4gICAgICAgICAgICBjb25zdCBjID0gaW50ZXJwb2xhdGlvbi5jb250cm9sUG9pbnRzO1xuICAgICAgICAgICAgY29uc3QgdWIgPSBuZXcgVW5pdEJlemllcihjWzBdLCBjWzFdLCBjWzJdLCBjWzNdKTtcbiAgICAgICAgICAgIHQgPSB1Yi5zb2x2ZShleHBvbmVudGlhbEludGVycG9sYXRpb24oaW5wdXQsIDEsIGxvd2VyLCB1cHBlcikpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH1cblxuICAgIHN0YXRpYyBwYXJzZShhcmdzOiAkUmVhZE9ubHlBcnJheTxtaXhlZD4sIGNvbnRleHQ6IFBhcnNpbmdDb250ZXh0KTogP0ludGVycG9sYXRlIHtcbiAgICAgICAgbGV0IFtvcGVyYXRvciwgaW50ZXJwb2xhdGlvbiwgaW5wdXQsIC4uLnJlc3RdID0gYXJncztcblxuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoaW50ZXJwb2xhdGlvbikgfHwgaW50ZXJwb2xhdGlvbi5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmVycm9yKGBFeHBlY3RlZCBhbiBpbnRlcnBvbGF0aW9uIHR5cGUgZXhwcmVzc2lvbi5gLCAxKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpbnRlcnBvbGF0aW9uWzBdID09PSAnbGluZWFyJykge1xuICAgICAgICAgICAgaW50ZXJwb2xhdGlvbiA9IHtuYW1lOiAnbGluZWFyJ307XG4gICAgICAgIH0gZWxzZSBpZiAoaW50ZXJwb2xhdGlvblswXSA9PT0gJ2V4cG9uZW50aWFsJykge1xuICAgICAgICAgICAgY29uc3QgYmFzZSA9IGludGVycG9sYXRpb25bMV07XG4gICAgICAgICAgICBpZiAodHlwZW9mIGJhc2UgIT09ICdudW1iZXInKVxuICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmVycm9yKGBFeHBvbmVudGlhbCBpbnRlcnBvbGF0aW9uIHJlcXVpcmVzIGEgbnVtZXJpYyBiYXNlLmAsIDEsIDEpO1xuICAgICAgICAgICAgaW50ZXJwb2xhdGlvbiA9IHtcbiAgICAgICAgICAgICAgICBuYW1lOiAnZXhwb25lbnRpYWwnLFxuICAgICAgICAgICAgICAgIGJhc2VcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSBpZiAoaW50ZXJwb2xhdGlvblswXSA9PT0gJ2N1YmljLWJlemllcicpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRyb2xQb2ludHMgPSBpbnRlcnBvbGF0aW9uLnNsaWNlKDEpO1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIGNvbnRyb2xQb2ludHMubGVuZ3RoICE9PSA0IHx8XG4gICAgICAgICAgICAgICAgY29udHJvbFBvaW50cy5zb21lKHQgPT4gdHlwZW9mIHQgIT09ICdudW1iZXInIHx8IHQgPCAwIHx8IHQgPiAxKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQuZXJyb3IoJ0N1YmljIGJlemllciBpbnRlcnBvbGF0aW9uIHJlcXVpcmVzIGZvdXIgbnVtZXJpYyBhcmd1bWVudHMgd2l0aCB2YWx1ZXMgYmV0d2VlbiAwIGFuZCAxLicsIDEpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpbnRlcnBvbGF0aW9uID0ge1xuICAgICAgICAgICAgICAgIG5hbWU6ICdjdWJpYy1iZXppZXInLFxuICAgICAgICAgICAgICAgIGNvbnRyb2xQb2ludHM6IChjb250cm9sUG9pbnRzOiBhbnkpXG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQuZXJyb3IoYFVua25vd24gaW50ZXJwb2xhdGlvbiB0eXBlICR7U3RyaW5nKGludGVycG9sYXRpb25bMF0pfWAsIDEsIDApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoIC0gMSA8IDQpIHtcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmVycm9yKGBFeHBlY3RlZCBhdCBsZWFzdCA0IGFyZ3VtZW50cywgYnV0IGZvdW5kIG9ubHkgJHthcmdzLmxlbmd0aCAtIDF9LmApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKChhcmdzLmxlbmd0aCAtIDEpICUgMiAhPT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQuZXJyb3IoYEV4cGVjdGVkIGFuIGV2ZW4gbnVtYmVyIG9mIGFyZ3VtZW50cy5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlucHV0ID0gY29udGV4dC5wYXJzZShpbnB1dCwgMiwgTnVtYmVyVHlwZSk7XG4gICAgICAgIGlmICghaW5wdXQpIHJldHVybiBudWxsO1xuXG4gICAgICAgIGNvbnN0IHN0b3BzOiBTdG9wcyA9IFtdO1xuXG4gICAgICAgIGxldCBvdXRwdXRUeXBlOiBUeXBlID0gKG51bGw6IGFueSk7XG4gICAgICAgIGlmIChvcGVyYXRvciA9PT0gJ2ludGVycG9sYXRlLWhjbCcgfHwgb3BlcmF0b3IgPT09ICdpbnRlcnBvbGF0ZS1sYWInKSB7XG4gICAgICAgICAgICBvdXRwdXRUeXBlID0gQ29sb3JUeXBlO1xuICAgICAgICB9IGVsc2UgaWYgKGNvbnRleHQuZXhwZWN0ZWRUeXBlICYmIGNvbnRleHQuZXhwZWN0ZWRUeXBlLmtpbmQgIT09ICd2YWx1ZScpIHtcbiAgICAgICAgICAgIG91dHB1dFR5cGUgPSBjb250ZXh0LmV4cGVjdGVkVHlwZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVzdC5sZW5ndGg7IGkgKz0gMikge1xuICAgICAgICAgICAgY29uc3QgbGFiZWwgPSByZXN0W2ldO1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSByZXN0W2kgKyAxXTtcblxuICAgICAgICAgICAgY29uc3QgbGFiZWxLZXkgPSBpICsgMztcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlS2V5ID0gaSArIDQ7XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgbGFiZWwgIT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQuZXJyb3IoJ0lucHV0L291dHB1dCBwYWlycyBmb3IgXCJpbnRlcnBvbGF0ZVwiIGV4cHJlc3Npb25zIG11c3QgYmUgZGVmaW5lZCB1c2luZyBsaXRlcmFsIG51bWVyaWMgdmFsdWVzIChub3QgY29tcHV0ZWQgZXhwcmVzc2lvbnMpIGZvciB0aGUgaW5wdXQgdmFsdWVzLicsIGxhYmVsS2V5KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHN0b3BzLmxlbmd0aCAmJiBzdG9wc1tzdG9wcy5sZW5ndGggLSAxXVswXSA+PSBsYWJlbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmVycm9yKCdJbnB1dC9vdXRwdXQgcGFpcnMgZm9yIFwiaW50ZXJwb2xhdGVcIiBleHByZXNzaW9ucyBtdXN0IGJlIGFycmFuZ2VkIHdpdGggaW5wdXQgdmFsdWVzIGluIHN0cmljdGx5IGFzY2VuZGluZyBvcmRlci4nLCBsYWJlbEtleSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IGNvbnRleHQucGFyc2UodmFsdWUsIHZhbHVlS2V5LCBvdXRwdXRUeXBlKTtcbiAgICAgICAgICAgIGlmICghcGFyc2VkKSByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIG91dHB1dFR5cGUgPSBvdXRwdXRUeXBlIHx8IHBhcnNlZC50eXBlO1xuICAgICAgICAgICAgc3RvcHMucHVzaChbbGFiZWwsIHBhcnNlZF0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG91dHB1dFR5cGUua2luZCAhPT0gJ251bWJlcicgJiZcbiAgICAgICAgICAgIG91dHB1dFR5cGUua2luZCAhPT0gJ2NvbG9yJyAmJlxuICAgICAgICAgICAgIShcbiAgICAgICAgICAgICAgICBvdXRwdXRUeXBlLmtpbmQgPT09ICdhcnJheScgJiZcbiAgICAgICAgICAgICAgICBvdXRwdXRUeXBlLml0ZW1UeXBlLmtpbmQgPT09ICdudW1iZXInICYmXG4gICAgICAgICAgICAgICAgdHlwZW9mIG91dHB1dFR5cGUuTiA9PT0gJ251bWJlcidcbiAgICAgICAgICAgIClcbiAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4gY29udGV4dC5lcnJvcihgVHlwZSAke3RvU3RyaW5nKG91dHB1dFR5cGUpfSBpcyBub3QgaW50ZXJwb2xhdGFibGUuYCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IEludGVycG9sYXRlKG91dHB1dFR5cGUsIChvcGVyYXRvcjogYW55KSwgaW50ZXJwb2xhdGlvbiwgaW5wdXQsIHN0b3BzKTtcbiAgICB9XG5cbiAgICBldmFsdWF0ZShjdHg6IEV2YWx1YXRpb25Db250ZXh0KTogQ29sb3Ige1xuICAgICAgICBjb25zdCBsYWJlbHMgPSB0aGlzLmxhYmVscztcbiAgICAgICAgY29uc3Qgb3V0cHV0cyA9IHRoaXMub3V0cHV0cztcblxuICAgICAgICBpZiAobGFiZWxzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgcmV0dXJuIG91dHB1dHNbMF0uZXZhbHVhdGUoY3R4KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHZhbHVlID0gKCh0aGlzLmlucHV0LmV2YWx1YXRlKGN0eCk6IGFueSk6IG51bWJlcik7XG4gICAgICAgIGlmICh2YWx1ZSA8PSBsYWJlbHNbMF0pIHtcbiAgICAgICAgICAgIHJldHVybiBvdXRwdXRzWzBdLmV2YWx1YXRlKGN0eCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdG9wQ291bnQgPSBsYWJlbHMubGVuZ3RoO1xuICAgICAgICBpZiAodmFsdWUgPj0gbGFiZWxzW3N0b3BDb3VudCAtIDFdKSB7XG4gICAgICAgICAgICByZXR1cm4gb3V0cHV0c1tzdG9wQ291bnQgLSAxXS5ldmFsdWF0ZShjdHgpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaW5kZXggPSBmaW5kU3RvcExlc3NUaGFuT3JFcXVhbFRvKGxhYmVscywgdmFsdWUpO1xuICAgICAgICBjb25zdCBsb3dlciA9IGxhYmVsc1tpbmRleF07XG4gICAgICAgIGNvbnN0IHVwcGVyID0gbGFiZWxzW2luZGV4ICsgMV07XG4gICAgICAgIGNvbnN0IHQgPSBJbnRlcnBvbGF0ZS5pbnRlcnBvbGF0aW9uRmFjdG9yKHRoaXMuaW50ZXJwb2xhdGlvbiwgdmFsdWUsIGxvd2VyLCB1cHBlcik7XG5cbiAgICAgICAgY29uc3Qgb3V0cHV0TG93ZXIgPSBvdXRwdXRzW2luZGV4XS5ldmFsdWF0ZShjdHgpO1xuICAgICAgICBjb25zdCBvdXRwdXRVcHBlciA9IG91dHB1dHNbaW5kZXggKyAxXS5ldmFsdWF0ZShjdHgpO1xuXG4gICAgICAgIGlmICh0aGlzLm9wZXJhdG9yID09PSAnaW50ZXJwb2xhdGUnKSB7XG4gICAgICAgICAgICByZXR1cm4gKGludGVycG9sYXRlW3RoaXMudHlwZS5raW5kLnRvTG93ZXJDYXNlKCldOiBhbnkpKG91dHB1dExvd2VyLCBvdXRwdXRVcHBlciwgdCk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgaW1wb3J0L25hbWVzcGFjZVxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMub3BlcmF0b3IgPT09ICdpbnRlcnBvbGF0ZS1oY2wnKSB7XG4gICAgICAgICAgICByZXR1cm4gaGNsLnJldmVyc2UoaGNsLmludGVycG9sYXRlKGhjbC5mb3J3YXJkKG91dHB1dExvd2VyKSwgaGNsLmZvcndhcmQob3V0cHV0VXBwZXIpLCB0KSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbGFiLnJldmVyc2UobGFiLmludGVycG9sYXRlKGxhYi5mb3J3YXJkKG91dHB1dExvd2VyKSwgbGFiLmZvcndhcmQob3V0cHV0VXBwZXIpLCB0KSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBlYWNoQ2hpbGQoZm46IChfOiBFeHByZXNzaW9uKSA9PiB2b2lkKSB7XG4gICAgICAgIGZuKHRoaXMuaW5wdXQpO1xuICAgICAgICBmb3IgKGNvbnN0IGV4cHJlc3Npb24gb2YgdGhpcy5vdXRwdXRzKSB7XG4gICAgICAgICAgICBmbihleHByZXNzaW9uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG91dHB1dERlZmluZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLm91dHB1dHMuZXZlcnkob3V0ID0+IG91dC5vdXRwdXREZWZpbmVkKCkpO1xuICAgIH1cblxuICAgIHNlcmlhbGl6ZSgpOiBTZXJpYWxpemVkRXhwcmVzc2lvbiB7XG4gICAgICAgIGxldCBpbnRlcnBvbGF0aW9uO1xuICAgICAgICBpZiAodGhpcy5pbnRlcnBvbGF0aW9uLm5hbWUgPT09ICdsaW5lYXInKSB7XG4gICAgICAgICAgICBpbnRlcnBvbGF0aW9uID0gW1wibGluZWFyXCJdO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaW50ZXJwb2xhdGlvbi5uYW1lID09PSAnZXhwb25lbnRpYWwnKSB7XG4gICAgICAgICAgICBpZiAgKHRoaXMuaW50ZXJwb2xhdGlvbi5iYXNlID09PSAxKSB7XG4gICAgICAgICAgICAgICAgaW50ZXJwb2xhdGlvbiA9IFtcImxpbmVhclwiXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaW50ZXJwb2xhdGlvbiA9IFtcImV4cG9uZW50aWFsXCIsIHRoaXMuaW50ZXJwb2xhdGlvbi5iYXNlXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGludGVycG9sYXRpb24gPSBbXCJjdWJpYy1iZXppZXJcIiBdLmNvbmNhdCh0aGlzLmludGVycG9sYXRpb24uY29udHJvbFBvaW50cyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzZXJpYWxpemVkID0gW3RoaXMub3BlcmF0b3IsIGludGVycG9sYXRpb24sIHRoaXMuaW5wdXQuc2VyaWFsaXplKCldO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5sYWJlbHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHNlcmlhbGl6ZWQucHVzaChcbiAgICAgICAgICAgICAgICB0aGlzLmxhYmVsc1tpXSxcbiAgICAgICAgICAgICAgICB0aGlzLm91dHB1dHNbaV0uc2VyaWFsaXplKClcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNlcmlhbGl6ZWQ7XG4gICAgfVxufVxuXG4vKipcbiAqIFJldHVybnMgYSByYXRpbyB0aGF0IGNhbiBiZSB1c2VkIHRvIGludGVycG9sYXRlIGJldHdlZW4gZXhwb25lbnRpYWwgZnVuY3Rpb25cbiAqIHN0b3BzLlxuICogSG93IGl0IHdvcmtzOiBUd28gY29uc2VjdXRpdmUgc3RvcCB2YWx1ZXMgZGVmaW5lIGEgKHNjYWxlZCBhbmQgc2hpZnRlZCkgZXhwb25lbnRpYWwgZnVuY3Rpb24gYGYoeCkgPSBhICogYmFzZV54ICsgYmAsIHdoZXJlIGBiYXNlYCBpcyB0aGUgdXNlci1zcGVjaWZpZWQgYmFzZSxcbiAqIGFuZCBgYWAgYW5kIGBiYCBhcmUgY29uc3RhbnRzIGFmZm9yZGluZyBzdWZmaWNpZW50IGRlZ3JlZXMgb2YgZnJlZWRvbSB0byBmaXRcbiAqIHRoZSBmdW5jdGlvbiB0byB0aGUgZ2l2ZW4gc3RvcHMuXG4gKlxuICogSGVyZSdzIGEgYml0IG9mIGFsZ2VicmEgdGhhdCBsZXRzIHVzIGNvbXB1dGUgYGYoeClgIGRpcmVjdGx5IGZyb20gdGhlIHN0b3BcbiAqIHZhbHVlcyB3aXRob3V0IGV4cGxpY2l0bHkgc29sdmluZyBmb3IgYGFgIGFuZCBgYmA6XG4gKlxuICogRmlyc3Qgc3RvcCB2YWx1ZTogYGYoeDApID0geTAgPSBhICogYmFzZV54MCArIGJgXG4gKiBTZWNvbmQgc3RvcCB2YWx1ZTogYGYoeDEpID0geTEgPSBhICogYmFzZV54MSArIGJgXG4gKiA9PiBgeTEgLSB5MCA9IGEoYmFzZV54MSAtIGJhc2VeeDApYFxuICogPT4gYGEgPSAoeTEgLSB5MCkvKGJhc2VeeDEgLSBiYXNlXngwKWBcbiAqXG4gKiBEZXNpcmVkIHZhbHVlOiBgZih4KSA9IHkgPSBhICogYmFzZV54ICsgYmBcbiAqID0+IGBmKHgpID0geTAgKyBhICogKGJhc2VeeCAtIGJhc2VeeDApYFxuICpcbiAqIEZyb20gdGhlIGFib3ZlLCB3ZSBjYW4gcmVwbGFjZSB0aGUgYGFgIGluIGBhICogKGJhc2VeeCAtIGJhc2VeeDApYCBhbmQgZG8gYVxuICogbGl0dGxlIGFsZ2VicmE6XG4gKiBgYGBcbiAqIGEgKiAoYmFzZV54IC0gYmFzZV54MCkgPSAoeTEgLSB5MCkvKGJhc2VeeDEgLSBiYXNlXngwKSAqIChiYXNlXnggLSBiYXNlXngwKVxuICogICAgICAgICAgICAgICAgICAgICA9ICh5MSAtIHkwKSAqIChiYXNlXnggLSBiYXNlXngwKSAvIChiYXNlXngxIC0gYmFzZV54MClcbiAqIGBgYFxuICpcbiAqIElmIHdlIGxldCBgKGJhc2VeeCAtIGJhc2VeeDApIC8gKGJhc2VeeDEgYmFzZV54MClgLCB0aGVuIHdlIGhhdmVcbiAqIGBmKHgpID0geTAgKyAoeTEgLSB5MCkgKiByYXRpb2AuICBJbiBvdGhlciB3b3JkcywgYHJhdGlvYCBtYXkgYmUgdHJlYXRlZCBhc1xuICogYW4gaW50ZXJwb2xhdGlvbiBmYWN0b3IgYmV0d2VlbiB0aGUgdHdvIHN0b3BzJyBvdXRwdXQgdmFsdWVzLlxuICpcbiAqIChOb3RlOiBhIHNsaWdodGx5IGRpZmZlcmVudCBmb3JtIGZvciBgcmF0aW9gLFxuICogYChiYXNlXih4LXgwKSAtIDEpIC8gKGJhc2VeKHgxLXgwKSAtIDEpIGAsIGlzIGVxdWl2YWxlbnQsIGJ1dCByZXF1aXJlcyBmZXdlclxuICogZXhwZW5zaXZlIGBNYXRoLnBvdygpYCBvcGVyYXRpb25zLilcbiAqXG4gKiBAcHJpdmF0ZVxuKi9cbmZ1bmN0aW9uIGV4cG9uZW50aWFsSW50ZXJwb2xhdGlvbihpbnB1dDogbnVtYmVyLCBiYXNlOiBudW1iZXIsIGxvd2VyVmFsdWU6IG51bWJlciwgdXBwZXJWYWx1ZTogbnVtYmVyKSB7XG4gICAgY29uc3QgZGlmZmVyZW5jZSA9IHVwcGVyVmFsdWUgLSBsb3dlclZhbHVlO1xuICAgIGNvbnN0IHByb2dyZXNzID0gaW5wdXQgLSBsb3dlclZhbHVlO1xuXG4gICAgaWYgKGRpZmZlcmVuY2UgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfSBlbHNlIGlmIChiYXNlID09PSAxKSB7XG4gICAgICAgIHJldHVybiBwcm9ncmVzcyAvIGRpZmZlcmVuY2U7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIChNYXRoLnBvdyhiYXNlLCBwcm9ncmVzcykgLSAxKSAvIChNYXRoLnBvdyhiYXNlLCBkaWZmZXJlbmNlKSAtIDEpO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgSW50ZXJwb2xhdGU7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbmltcG9ydCB7Y2hlY2tTdWJ0eXBlLCBWYWx1ZVR5cGV9IGZyb20gJy4uL3R5cGVzLmpzJztcbmltcG9ydCBSZXNvbHZlZEltYWdlIGZyb20gJy4uL3R5cGVzL3Jlc29sdmVkX2ltYWdlLmpzJztcblxuaW1wb3J0IHR5cGUge0V4cHJlc3Npb24sIFNlcmlhbGl6ZWRFeHByZXNzaW9ufSBmcm9tICcuLi9leHByZXNzaW9uLmpzJztcbmltcG9ydCB0eXBlIFBhcnNpbmdDb250ZXh0IGZyb20gJy4uL3BhcnNpbmdfY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSBFdmFsdWF0aW9uQ29udGV4dCBmcm9tICcuLi9ldmFsdWF0aW9uX2NvbnRleHQuanMnO1xuaW1wb3J0IHR5cGUge1R5cGV9IGZyb20gJy4uL3R5cGVzLmpzJztcblxuY2xhc3MgQ29hbGVzY2UgaW1wbGVtZW50cyBFeHByZXNzaW9uIHtcbiAgICB0eXBlOiBUeXBlO1xuICAgIGFyZ3M6IEFycmF5PEV4cHJlc3Npb24+O1xuXG4gICAgY29uc3RydWN0b3IodHlwZTogVHlwZSwgYXJnczogQXJyYXk8RXhwcmVzc2lvbj4pIHtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5hcmdzID0gYXJncztcbiAgICB9XG5cbiAgICBzdGF0aWMgcGFyc2UoYXJnczogJFJlYWRPbmx5QXJyYXk8bWl4ZWQ+LCBjb250ZXh0OiBQYXJzaW5nQ29udGV4dCk6ID9Db2FsZXNjZSB7XG4gICAgICAgIGlmIChhcmdzLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmVycm9yKFwiRXhwZWN0ZWN0ZWQgYXQgbGVhc3Qgb25lIGFyZ3VtZW50LlwiKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgb3V0cHV0VHlwZTogVHlwZSA9IChudWxsOiBhbnkpO1xuICAgICAgICBjb25zdCBleHBlY3RlZFR5cGUgPSBjb250ZXh0LmV4cGVjdGVkVHlwZTtcbiAgICAgICAgaWYgKGV4cGVjdGVkVHlwZSAmJiBleHBlY3RlZFR5cGUua2luZCAhPT0gJ3ZhbHVlJykge1xuICAgICAgICAgICAgb3V0cHV0VHlwZSA9IGV4cGVjdGVkVHlwZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwYXJzZWRBcmdzID0gW107XG5cbiAgICAgICAgZm9yIChjb25zdCBhcmcgb2YgYXJncy5zbGljZSgxKSkge1xuICAgICAgICAgICAgY29uc3QgcGFyc2VkID0gY29udGV4dC5wYXJzZShhcmcsIDEgKyBwYXJzZWRBcmdzLmxlbmd0aCwgb3V0cHV0VHlwZSwgdW5kZWZpbmVkLCB7dHlwZUFubm90YXRpb246ICdvbWl0J30pO1xuICAgICAgICAgICAgaWYgKCFwYXJzZWQpIHJldHVybiBudWxsO1xuICAgICAgICAgICAgb3V0cHV0VHlwZSA9IG91dHB1dFR5cGUgfHwgcGFyc2VkLnR5cGU7XG4gICAgICAgICAgICBwYXJzZWRBcmdzLnB1c2gocGFyc2VkKTtcbiAgICAgICAgfVxuICAgICAgICBhc3NlcnQob3V0cHV0VHlwZSk7XG5cbiAgICAgICAgLy8gQWJvdmUsIHdlIHBhcnNlIGFyZ3VtZW50cyB3aXRob3V0IGluZmVycmVkIHR5cGUgYW5ub3RhdGlvbiBzbyB0aGF0XG4gICAgICAgIC8vIHRoZXkgZG9uJ3QgcHJvZHVjZSBhIHJ1bnRpbWUgZXJyb3IgZm9yIGBudWxsYCBpbnB1dCwgd2hpY2ggd291bGRcbiAgICAgICAgLy8gcHJlZW1wdCB0aGUgZGVzaXJlZCBudWxsLWNvYWxlc2NpbmcgYmVoYXZpb3IuXG4gICAgICAgIC8vIFRodXMsIGlmIGFueSBvZiBvdXIgYXJndW1lbnRzIHdvdWxkIGhhdmUgbmVlZGVkIGFuIGFubm90YXRpb24sIHdlXG4gICAgICAgIC8vIG5lZWQgdG8gd3JhcCB0aGUgZW5jbG9zaW5nIGNvYWxlc2NlIGV4cHJlc3Npb24gd2l0aCBpdCBpbnN0ZWFkLlxuICAgICAgICBjb25zdCBuZWVkc0Fubm90YXRpb24gPSBleHBlY3RlZFR5cGUgJiZcbiAgICAgICAgICAgIHBhcnNlZEFyZ3Muc29tZShhcmcgPT4gY2hlY2tTdWJ0eXBlKGV4cGVjdGVkVHlwZSwgYXJnLnR5cGUpKTtcblxuICAgICAgICByZXR1cm4gbmVlZHNBbm5vdGF0aW9uID9cbiAgICAgICAgICAgIG5ldyBDb2FsZXNjZShWYWx1ZVR5cGUsIHBhcnNlZEFyZ3MpIDpcbiAgICAgICAgICAgIG5ldyBDb2FsZXNjZSgob3V0cHV0VHlwZTogYW55KSwgcGFyc2VkQXJncyk7XG4gICAgfVxuXG4gICAgZXZhbHVhdGUoY3R4OiBFdmFsdWF0aW9uQ29udGV4dCk6IGFueSB8IG51bGwge1xuICAgICAgICBsZXQgcmVzdWx0ID0gbnVsbDtcbiAgICAgICAgbGV0IGFyZ0NvdW50ID0gMDtcbiAgICAgICAgbGV0IGZpcnN0SW1hZ2U7XG4gICAgICAgIGZvciAoY29uc3QgYXJnIG9mIHRoaXMuYXJncykge1xuICAgICAgICAgICAgYXJnQ291bnQrKztcbiAgICAgICAgICAgIHJlc3VsdCA9IGFyZy5ldmFsdWF0ZShjdHgpO1xuICAgICAgICAgICAgLy8gd2UgbmVlZCB0byBrZWVwIHRyYWNrIG9mIHRoZSBmaXJzdCByZXF1ZXN0ZWQgaW1hZ2UgaW4gYSBjb2FsZXNjZSBzdGF0ZW1lbnRcbiAgICAgICAgICAgIC8vIGlmIGNvYWxlc2NlIGNhbid0IGZpbmQgYSB2YWxpZCBpbWFnZSwgd2UgcmV0dXJuIHRoZSBmaXJzdCBpbWFnZSBzbyBzdHlsZWltYWdlbWlzc2luZyBjYW4gZmlyZVxuICAgICAgICAgICAgaWYgKHJlc3VsdCAmJiByZXN1bHQgaW5zdGFuY2VvZiBSZXNvbHZlZEltYWdlICYmICFyZXN1bHQuYXZhaWxhYmxlKSB7XG4gICAgICAgICAgICAgICAgLy8gc2V0IHRvIGZpcnN0IGltYWdlXG4gICAgICAgICAgICAgICAgaWYgKCFmaXJzdEltYWdlKSB7XG4gICAgICAgICAgICAgICAgICAgIGZpcnN0SW1hZ2UgPSByZXN1bHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IG51bGw7XG4gICAgICAgICAgICAgICAgLy8gaWYgd2UgcmVhY2ggdGhlIGVuZCwgcmV0dXJuIHRoZSBmaXJzdCBpbWFnZVxuICAgICAgICAgICAgICAgIGlmIChhcmdDb3VudCA9PT0gdGhpcy5hcmdzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmlyc3RJbWFnZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChyZXN1bHQgIT09IG51bGwpIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgZWFjaENoaWxkKGZuOiAoXzogRXhwcmVzc2lvbikgPT4gdm9pZCkge1xuICAgICAgICB0aGlzLmFyZ3MuZm9yRWFjaChmbik7XG4gICAgfVxuXG4gICAgb3V0cHV0RGVmaW5lZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXJncy5ldmVyeShhcmcgPT4gYXJnLm91dHB1dERlZmluZWQoKSk7XG4gICAgfVxuXG4gICAgc2VyaWFsaXplKCk6IFNlcmlhbGl6ZWRFeHByZXNzaW9uIHtcbiAgICAgICAgY29uc3Qgc2VyaWFsaXplZCA9IFtcImNvYWxlc2NlXCJdO1xuICAgICAgICB0aGlzLmVhY2hDaGlsZChjaGlsZCA9PiB7IHNlcmlhbGl6ZWQucHVzaChjaGlsZC5zZXJpYWxpemUoKSk7IH0pO1xuICAgICAgICByZXR1cm4gc2VyaWFsaXplZDtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IENvYWxlc2NlO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHR5cGUge1R5cGV9IGZyb20gJy4uL3R5cGVzLmpzJztcbmltcG9ydCB0eXBlIHtFeHByZXNzaW9uLCBTZXJpYWxpemVkRXhwcmVzc2lvbn0gZnJvbSAnLi4vZXhwcmVzc2lvbi5qcyc7XG5pbXBvcnQgdHlwZSBQYXJzaW5nQ29udGV4dCBmcm9tICcuLi9wYXJzaW5nX2NvbnRleHQuanMnO1xuaW1wb3J0IHR5cGUgRXZhbHVhdGlvbkNvbnRleHQgIGZyb20gJy4uL2V2YWx1YXRpb25fY29udGV4dC5qcyc7XG5cbmNsYXNzIExldCBpbXBsZW1lbnRzIEV4cHJlc3Npb24ge1xuICAgIHR5cGU6IFR5cGU7XG4gICAgYmluZGluZ3M6IEFycmF5PFtzdHJpbmcsIEV4cHJlc3Npb25dPjtcbiAgICByZXN1bHQ6IEV4cHJlc3Npb247XG5cbiAgICBjb25zdHJ1Y3RvcihiaW5kaW5nczogQXJyYXk8W3N0cmluZywgRXhwcmVzc2lvbl0+LCByZXN1bHQ6IEV4cHJlc3Npb24pIHtcbiAgICAgICAgdGhpcy50eXBlID0gcmVzdWx0LnR5cGU7XG4gICAgICAgIHRoaXMuYmluZGluZ3MgPSBbXS5jb25jYXQoYmluZGluZ3MpO1xuICAgICAgICB0aGlzLnJlc3VsdCA9IHJlc3VsdDtcbiAgICB9XG5cbiAgICBldmFsdWF0ZShjdHg6IEV2YWx1YXRpb25Db250ZXh0KTogYW55IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVzdWx0LmV2YWx1YXRlKGN0eCk7XG4gICAgfVxuXG4gICAgZWFjaENoaWxkKGZuOiAoXzogRXhwcmVzc2lvbikgPT4gdm9pZCkge1xuICAgICAgICBmb3IgKGNvbnN0IGJpbmRpbmcgb2YgdGhpcy5iaW5kaW5ncykge1xuICAgICAgICAgICAgZm4oYmluZGluZ1sxXSk7XG4gICAgICAgIH1cbiAgICAgICAgZm4odGhpcy5yZXN1bHQpO1xuICAgIH1cblxuICAgIHN0YXRpYyBwYXJzZShhcmdzOiAkUmVhZE9ubHlBcnJheTxtaXhlZD4sIGNvbnRleHQ6IFBhcnNpbmdDb250ZXh0KTogP0xldCB7XG4gICAgICAgIGlmIChhcmdzLmxlbmd0aCA8IDQpXG4gICAgICAgICAgICByZXR1cm4gY29udGV4dC5lcnJvcihgRXhwZWN0ZWQgYXQgbGVhc3QgMyBhcmd1bWVudHMsIGJ1dCBmb3VuZCAke2FyZ3MubGVuZ3RoIC0gMX0gaW5zdGVhZC5gKTtcblxuICAgICAgICBjb25zdCBiaW5kaW5nczogQXJyYXk8W3N0cmluZywgRXhwcmVzc2lvbl0+ID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgYXJncy5sZW5ndGggLSAxOyBpICs9IDIpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hbWUgPSBhcmdzW2ldO1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIG5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQuZXJyb3IoYEV4cGVjdGVkIHN0cmluZywgYnV0IGZvdW5kICR7dHlwZW9mIG5hbWV9IGluc3RlYWQuYCwgaSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICgvW15hLXpBLVowLTlfXS8udGVzdChuYW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmVycm9yKGBWYXJpYWJsZSBuYW1lcyBtdXN0IGNvbnRhaW4gb25seSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyBvciAnXycuYCwgaSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gY29udGV4dC5wYXJzZShhcmdzW2kgKyAxXSwgaSArIDEpO1xuICAgICAgICAgICAgaWYgKCF2YWx1ZSkgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgICAgIGJpbmRpbmdzLnB1c2goW25hbWUsIHZhbHVlXSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXN1bHQgPSBjb250ZXh0LnBhcnNlKGFyZ3NbYXJncy5sZW5ndGggLSAxXSwgYXJncy5sZW5ndGggLSAxLCBjb250ZXh0LmV4cGVjdGVkVHlwZSwgYmluZGluZ3MpO1xuICAgICAgICBpZiAoIXJlc3VsdCkgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBMZXQoYmluZGluZ3MsIHJlc3VsdCk7XG4gICAgfVxuXG4gICAgb3V0cHV0RGVmaW5lZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVzdWx0Lm91dHB1dERlZmluZWQoKTtcbiAgICB9XG5cbiAgICBzZXJpYWxpemUoKTogU2VyaWFsaXplZEV4cHJlc3Npb24ge1xuICAgICAgICBjb25zdCBzZXJpYWxpemVkID0gW1wibGV0XCJdO1xuICAgICAgICBmb3IgKGNvbnN0IFtuYW1lLCBleHByXSBvZiB0aGlzLmJpbmRpbmdzKSB7XG4gICAgICAgICAgICBzZXJpYWxpemVkLnB1c2gobmFtZSwgZXhwci5zZXJpYWxpemUoKSk7XG4gICAgICAgIH1cbiAgICAgICAgc2VyaWFsaXplZC5wdXNoKHRoaXMucmVzdWx0LnNlcmlhbGl6ZSgpKTtcbiAgICAgICAgcmV0dXJuIHNlcmlhbGl6ZWQ7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBMZXQ7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge2FycmF5LCBWYWx1ZVR5cGUsIE51bWJlclR5cGV9IGZyb20gJy4uL3R5cGVzLmpzJztcblxuaW1wb3J0IFJ1bnRpbWVFcnJvciBmcm9tICcuLi9ydW50aW1lX2Vycm9yLmpzJztcblxuaW1wb3J0IHR5cGUge0V4cHJlc3Npb24sIFNlcmlhbGl6ZWRFeHByZXNzaW9ufSBmcm9tICcuLi9leHByZXNzaW9uLmpzJztcbmltcG9ydCB0eXBlIFBhcnNpbmdDb250ZXh0IGZyb20gJy4uL3BhcnNpbmdfY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSBFdmFsdWF0aW9uQ29udGV4dCBmcm9tICcuLi9ldmFsdWF0aW9uX2NvbnRleHQuanMnO1xuaW1wb3J0IHR5cGUge1R5cGUsIEFycmF5VHlwZX0gZnJvbSAnLi4vdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge1ZhbHVlfSBmcm9tICcuLi92YWx1ZXMuanMnO1xuXG5jbGFzcyBBdCBpbXBsZW1lbnRzIEV4cHJlc3Npb24ge1xuICAgIHR5cGU6IFR5cGU7XG4gICAgaW5kZXg6IEV4cHJlc3Npb247XG4gICAgaW5wdXQ6IEV4cHJlc3Npb247XG5cbiAgICBjb25zdHJ1Y3Rvcih0eXBlOiBUeXBlLCBpbmRleDogRXhwcmVzc2lvbiwgaW5wdXQ6IEV4cHJlc3Npb24pIHtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5pbmRleCA9IGluZGV4O1xuICAgICAgICB0aGlzLmlucHV0ID0gaW5wdXQ7XG4gICAgfVxuXG4gICAgc3RhdGljIHBhcnNlKGFyZ3M6ICRSZWFkT25seUFycmF5PG1peGVkPiwgY29udGV4dDogUGFyc2luZ0NvbnRleHQpOiA/QXQge1xuICAgICAgICBpZiAoYXJncy5sZW5ndGggIT09IDMpXG4gICAgICAgICAgICByZXR1cm4gY29udGV4dC5lcnJvcihgRXhwZWN0ZWQgMiBhcmd1bWVudHMsIGJ1dCBmb3VuZCAke2FyZ3MubGVuZ3RoIC0gMX0gaW5zdGVhZC5gKTtcblxuICAgICAgICBjb25zdCBpbmRleCA9IGNvbnRleHQucGFyc2UoYXJnc1sxXSwgMSwgTnVtYmVyVHlwZSk7XG4gICAgICAgIGNvbnN0IGlucHV0ID0gY29udGV4dC5wYXJzZShhcmdzWzJdLCAyLCBhcnJheShjb250ZXh0LmV4cGVjdGVkVHlwZSB8fCBWYWx1ZVR5cGUpKTtcblxuICAgICAgICBpZiAoIWluZGV4IHx8ICFpbnB1dCkgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgY29uc3QgdDogQXJyYXlUeXBlID0gKGlucHV0LnR5cGU6IGFueSk7XG4gICAgICAgIHJldHVybiBuZXcgQXQodC5pdGVtVHlwZSwgaW5kZXgsIGlucHV0KTtcbiAgICB9XG5cbiAgICBldmFsdWF0ZShjdHg6IEV2YWx1YXRpb25Db250ZXh0KTogVmFsdWUge1xuICAgICAgICBjb25zdCBpbmRleCA9ICgodGhpcy5pbmRleC5ldmFsdWF0ZShjdHgpOiBhbnkpOiBudW1iZXIpO1xuICAgICAgICBjb25zdCBhcnJheSA9ICgodGhpcy5pbnB1dC5ldmFsdWF0ZShjdHgpOiBhbnkpOiBBcnJheTxWYWx1ZT4pO1xuXG4gICAgICAgIGlmIChpbmRleCA8IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXJyb3IoYEFycmF5IGluZGV4IG91dCBvZiBib3VuZHM6ICR7aW5kZXh9IDwgMC5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpbmRleCA+PSBhcnJheS5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXJyb3IoYEFycmF5IGluZGV4IG91dCBvZiBib3VuZHM6ICR7aW5kZXh9ID4gJHthcnJheS5sZW5ndGggLSAxfS5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpbmRleCAhPT0gTWF0aC5mbG9vcihpbmRleCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXJyb3IoYEFycmF5IGluZGV4IG11c3QgYmUgYW4gaW50ZWdlciwgYnV0IGZvdW5kICR7aW5kZXh9IGluc3RlYWQuYCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXJyYXlbaW5kZXhdO1xuICAgIH1cblxuICAgIGVhY2hDaGlsZChmbjogKF86IEV4cHJlc3Npb24pID0+IHZvaWQpIHtcbiAgICAgICAgZm4odGhpcy5pbmRleCk7XG4gICAgICAgIGZuKHRoaXMuaW5wdXQpO1xuICAgIH1cblxuICAgIG91dHB1dERlZmluZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBzZXJpYWxpemUoKTogU2VyaWFsaXplZEV4cHJlc3Npb24ge1xuICAgICAgICByZXR1cm4gW1wiYXRcIiwgdGhpcy5pbmRleC5zZXJpYWxpemUoKSwgdGhpcy5pbnB1dC5zZXJpYWxpemUoKV07XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBBdDtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCB7Qm9vbGVhblR5cGUsIFN0cmluZ1R5cGUsIFZhbHVlVHlwZSwgTnVsbFR5cGUsIHRvU3RyaW5nLCBOdW1iZXJUeXBlLCBpc1ZhbGlkVHlwZSwgaXNWYWxpZE5hdGl2ZVR5cGV9IGZyb20gJy4uL3R5cGVzLmpzJztcbmltcG9ydCBSdW50aW1lRXJyb3IgZnJvbSAnLi4vcnVudGltZV9lcnJvci5qcyc7XG5pbXBvcnQge3R5cGVPZn0gZnJvbSAnLi4vdmFsdWVzLmpzJztcblxuaW1wb3J0IHR5cGUge0V4cHJlc3Npb24sIFNlcmlhbGl6ZWRFeHByZXNzaW9ufSBmcm9tICcuLi9leHByZXNzaW9uLmpzJztcbmltcG9ydCB0eXBlIFBhcnNpbmdDb250ZXh0IGZyb20gJy4uL3BhcnNpbmdfY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSBFdmFsdWF0aW9uQ29udGV4dCBmcm9tICcuLi9ldmFsdWF0aW9uX2NvbnRleHQuanMnO1xuaW1wb3J0IHR5cGUge1R5cGV9IGZyb20gJy4uL3R5cGVzLmpzJztcblxuY2xhc3MgSW4gaW1wbGVtZW50cyBFeHByZXNzaW9uIHtcbiAgICB0eXBlOiBUeXBlO1xuICAgIG5lZWRsZTogRXhwcmVzc2lvbjtcbiAgICBoYXlzdGFjazogRXhwcmVzc2lvbjtcblxuICAgIGNvbnN0cnVjdG9yKG5lZWRsZTogRXhwcmVzc2lvbiwgaGF5c3RhY2s6IEV4cHJlc3Npb24pIHtcbiAgICAgICAgdGhpcy50eXBlID0gQm9vbGVhblR5cGU7XG4gICAgICAgIHRoaXMubmVlZGxlID0gbmVlZGxlO1xuICAgICAgICB0aGlzLmhheXN0YWNrID0gaGF5c3RhY2s7XG4gICAgfVxuXG4gICAgc3RhdGljIHBhcnNlKGFyZ3M6ICRSZWFkT25seUFycmF5PG1peGVkPiwgY29udGV4dDogUGFyc2luZ0NvbnRleHQpOiA/SW4ge1xuICAgICAgICBpZiAoYXJncy5sZW5ndGggIT09IDMpIHtcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmVycm9yKGBFeHBlY3RlZCAyIGFyZ3VtZW50cywgYnV0IGZvdW5kICR7YXJncy5sZW5ndGggLSAxfSBpbnN0ZWFkLmApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbmVlZGxlID0gY29udGV4dC5wYXJzZShhcmdzWzFdLCAxLCBWYWx1ZVR5cGUpO1xuXG4gICAgICAgIGNvbnN0IGhheXN0YWNrID0gY29udGV4dC5wYXJzZShhcmdzWzJdLCAyLCBWYWx1ZVR5cGUpO1xuXG4gICAgICAgIGlmICghbmVlZGxlIHx8ICFoYXlzdGFjaykgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgaWYgKCFpc1ZhbGlkVHlwZShuZWVkbGUudHlwZSwgW0Jvb2xlYW5UeXBlLCBTdHJpbmdUeXBlLCBOdW1iZXJUeXBlLCBOdWxsVHlwZSwgVmFsdWVUeXBlXSkpIHtcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmVycm9yKGBFeHBlY3RlZCBmaXJzdCBhcmd1bWVudCB0byBiZSBvZiB0eXBlIGJvb2xlYW4sIHN0cmluZywgbnVtYmVyIG9yIG51bGwsIGJ1dCBmb3VuZCAke3RvU3RyaW5nKG5lZWRsZS50eXBlKX0gaW5zdGVhZGApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBJbihuZWVkbGUsIGhheXN0YWNrKTtcbiAgICB9XG5cbiAgICBldmFsdWF0ZShjdHg6IEV2YWx1YXRpb25Db250ZXh0KTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IG5lZWRsZSA9ICh0aGlzLm5lZWRsZS5ldmFsdWF0ZShjdHgpOiBhbnkpO1xuICAgICAgICBjb25zdCBoYXlzdGFjayA9ICh0aGlzLmhheXN0YWNrLmV2YWx1YXRlKGN0eCk6IGFueSk7XG5cbiAgICAgICAgaWYgKGhheXN0YWNrID09IG51bGwpIHJldHVybiBmYWxzZTtcblxuICAgICAgICBpZiAoIWlzVmFsaWROYXRpdmVUeXBlKG5lZWRsZSwgWydib29sZWFuJywgJ3N0cmluZycsICdudW1iZXInLCAnbnVsbCddKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcihgRXhwZWN0ZWQgZmlyc3QgYXJndW1lbnQgdG8gYmUgb2YgdHlwZSBib29sZWFuLCBzdHJpbmcsIG51bWJlciBvciBudWxsLCBidXQgZm91bmQgJHt0b1N0cmluZyh0eXBlT2YobmVlZGxlKSl9IGluc3RlYWQuYCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWlzVmFsaWROYXRpdmVUeXBlKGhheXN0YWNrLCBbJ3N0cmluZycsICdhcnJheSddKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcihgRXhwZWN0ZWQgc2Vjb25kIGFyZ3VtZW50IHRvIGJlIG9mIHR5cGUgYXJyYXkgb3Igc3RyaW5nLCBidXQgZm91bmQgJHt0b1N0cmluZyh0eXBlT2YoaGF5c3RhY2spKX0gaW5zdGVhZC5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBoYXlzdGFjay5pbmRleE9mKG5lZWRsZSkgPj0gMDtcbiAgICB9XG5cbiAgICBlYWNoQ2hpbGQoZm46IChfOiBFeHByZXNzaW9uKSA9PiB2b2lkKSB7XG4gICAgICAgIGZuKHRoaXMubmVlZGxlKTtcbiAgICAgICAgZm4odGhpcy5oYXlzdGFjayk7XG4gICAgfVxuXG4gICAgb3V0cHV0RGVmaW5lZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgc2VyaWFsaXplKCk6IFNlcmlhbGl6ZWRFeHByZXNzaW9uIHtcbiAgICAgICAgcmV0dXJuIFtcImluXCIsIHRoaXMubmVlZGxlLnNlcmlhbGl6ZSgpLCB0aGlzLmhheXN0YWNrLnNlcmlhbGl6ZSgpXTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEluO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtCb29sZWFuVHlwZSwgU3RyaW5nVHlwZSwgVmFsdWVUeXBlLCBOdWxsVHlwZSwgdG9TdHJpbmcsIE51bWJlclR5cGUsIGlzVmFsaWRUeXBlLCBpc1ZhbGlkTmF0aXZlVHlwZX0gZnJvbSAnLi4vdHlwZXMuanMnO1xuaW1wb3J0IFJ1bnRpbWVFcnJvciBmcm9tICcuLi9ydW50aW1lX2Vycm9yLmpzJztcbmltcG9ydCB7dHlwZU9mfSBmcm9tICcuLi92YWx1ZXMuanMnO1xuXG5pbXBvcnQgdHlwZSB7RXhwcmVzc2lvbiwgU2VyaWFsaXplZEV4cHJlc3Npb259IGZyb20gJy4uL2V4cHJlc3Npb24uanMnO1xuaW1wb3J0IHR5cGUgUGFyc2luZ0NvbnRleHQgZnJvbSAnLi4vcGFyc2luZ19jb250ZXh0LmpzJztcbmltcG9ydCB0eXBlIEV2YWx1YXRpb25Db250ZXh0IGZyb20gJy4uL2V2YWx1YXRpb25fY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSB7VHlwZX0gZnJvbSAnLi4vdHlwZXMuanMnO1xuXG5jbGFzcyBJbmRleE9mIGltcGxlbWVudHMgRXhwcmVzc2lvbiB7XG4gICAgdHlwZTogVHlwZTtcbiAgICBuZWVkbGU6IEV4cHJlc3Npb247XG4gICAgaGF5c3RhY2s6IEV4cHJlc3Npb247XG4gICAgZnJvbUluZGV4OiA/RXhwcmVzc2lvbjtcblxuICAgIGNvbnN0cnVjdG9yKG5lZWRsZTogRXhwcmVzc2lvbiwgaGF5c3RhY2s6IEV4cHJlc3Npb24sIGZyb21JbmRleD86IEV4cHJlc3Npb24pIHtcbiAgICAgICAgdGhpcy50eXBlID0gTnVtYmVyVHlwZTtcbiAgICAgICAgdGhpcy5uZWVkbGUgPSBuZWVkbGU7XG4gICAgICAgIHRoaXMuaGF5c3RhY2sgPSBoYXlzdGFjaztcbiAgICAgICAgdGhpcy5mcm9tSW5kZXggPSBmcm9tSW5kZXg7XG4gICAgfVxuXG4gICAgc3RhdGljIHBhcnNlKGFyZ3M6ICRSZWFkT25seUFycmF5PG1peGVkPiwgY29udGV4dDogUGFyc2luZ0NvbnRleHQpOiA/SW5kZXhPZiB7XG4gICAgICAgIGlmIChhcmdzLmxlbmd0aCA8PSAyIHx8ICBhcmdzLmxlbmd0aCA+PSA1KSB7XG4gICAgICAgICAgICByZXR1cm4gY29udGV4dC5lcnJvcihgRXhwZWN0ZWQgMyBvciA0IGFyZ3VtZW50cywgYnV0IGZvdW5kICR7YXJncy5sZW5ndGggLSAxfSBpbnN0ZWFkLmApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbmVlZGxlID0gY29udGV4dC5wYXJzZShhcmdzWzFdLCAxLCBWYWx1ZVR5cGUpO1xuXG4gICAgICAgIGNvbnN0IGhheXN0YWNrID0gY29udGV4dC5wYXJzZShhcmdzWzJdLCAyLCBWYWx1ZVR5cGUpO1xuXG4gICAgICAgIGlmICghbmVlZGxlIHx8ICFoYXlzdGFjaykgcmV0dXJuIG51bGw7XG4gICAgICAgIGlmICghaXNWYWxpZFR5cGUobmVlZGxlLnR5cGUsIFtCb29sZWFuVHlwZSwgU3RyaW5nVHlwZSwgTnVtYmVyVHlwZSwgTnVsbFR5cGUsIFZhbHVlVHlwZV0pKSB7XG4gICAgICAgICAgICByZXR1cm4gY29udGV4dC5lcnJvcihgRXhwZWN0ZWQgZmlyc3QgYXJndW1lbnQgdG8gYmUgb2YgdHlwZSBib29sZWFuLCBzdHJpbmcsIG51bWJlciBvciBudWxsLCBidXQgZm91bmQgJHt0b1N0cmluZyhuZWVkbGUudHlwZSl9IGluc3RlYWRgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhcmdzLmxlbmd0aCA9PT0gNCkge1xuICAgICAgICAgICAgY29uc3QgZnJvbUluZGV4ID0gY29udGV4dC5wYXJzZShhcmdzWzNdLCAzLCBOdW1iZXJUeXBlKTtcbiAgICAgICAgICAgIGlmICghZnJvbUluZGV4KSByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIHJldHVybiBuZXcgSW5kZXhPZihuZWVkbGUsIGhheXN0YWNrLCBmcm9tSW5kZXgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBJbmRleE9mKG5lZWRsZSwgaGF5c3RhY2spO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZXZhbHVhdGUoY3R4OiBFdmFsdWF0aW9uQ29udGV4dCk6IGFueSB7XG4gICAgICAgIGNvbnN0IG5lZWRsZSA9ICh0aGlzLm5lZWRsZS5ldmFsdWF0ZShjdHgpOiBhbnkpO1xuICAgICAgICBjb25zdCBoYXlzdGFjayA9ICh0aGlzLmhheXN0YWNrLmV2YWx1YXRlKGN0eCk6IGFueSk7XG5cbiAgICAgICAgaWYgKCFpc1ZhbGlkTmF0aXZlVHlwZShuZWVkbGUsIFsnYm9vbGVhbicsICdzdHJpbmcnLCAnbnVtYmVyJywgJ251bGwnXSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXJyb3IoYEV4cGVjdGVkIGZpcnN0IGFyZ3VtZW50IHRvIGJlIG9mIHR5cGUgYm9vbGVhbiwgc3RyaW5nLCBudW1iZXIgb3IgbnVsbCwgYnV0IGZvdW5kICR7dG9TdHJpbmcodHlwZU9mKG5lZWRsZSkpfSBpbnN0ZWFkLmApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFpc1ZhbGlkTmF0aXZlVHlwZShoYXlzdGFjaywgWydzdHJpbmcnLCAnYXJyYXknXSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXJyb3IoYEV4cGVjdGVkIHNlY29uZCBhcmd1bWVudCB0byBiZSBvZiB0eXBlIGFycmF5IG9yIHN0cmluZywgYnV0IGZvdW5kICR7dG9TdHJpbmcodHlwZU9mKGhheXN0YWNrKSl9IGluc3RlYWQuYCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5mcm9tSW5kZXgpIHtcbiAgICAgICAgICAgIGNvbnN0IGZyb21JbmRleCA9ICh0aGlzLmZyb21JbmRleC5ldmFsdWF0ZShjdHgpOiBudW1iZXIpO1xuICAgICAgICAgICAgcmV0dXJuIGhheXN0YWNrLmluZGV4T2YobmVlZGxlLCBmcm9tSW5kZXgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGhheXN0YWNrLmluZGV4T2YobmVlZGxlKTtcbiAgICB9XG5cbiAgICBlYWNoQ2hpbGQoZm46IChfOiBFeHByZXNzaW9uKSA9PiB2b2lkKSB7XG4gICAgICAgIGZuKHRoaXMubmVlZGxlKTtcbiAgICAgICAgZm4odGhpcy5oYXlzdGFjayk7XG4gICAgICAgIGlmICh0aGlzLmZyb21JbmRleCkge1xuICAgICAgICAgICAgZm4odGhpcy5mcm9tSW5kZXgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb3V0cHV0RGVmaW5lZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHNlcmlhbGl6ZSgpOiBTZXJpYWxpemVkRXhwcmVzc2lvbiB7XG4gICAgICAgIGlmICh0aGlzLmZyb21JbmRleCAhPSBudWxsICYmIHRoaXMuZnJvbUluZGV4ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGNvbnN0IGZyb21JbmRleCA9IHRoaXMuZnJvbUluZGV4LnNlcmlhbGl6ZSgpO1xuICAgICAgICAgICAgcmV0dXJuIFtcImluZGV4LW9mXCIsIHRoaXMubmVlZGxlLnNlcmlhbGl6ZSgpLCB0aGlzLmhheXN0YWNrLnNlcmlhbGl6ZSgpLCBmcm9tSW5kZXhdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbXCJpbmRleC1vZlwiLCB0aGlzLm5lZWRsZS5zZXJpYWxpemUoKSwgdGhpcy5oYXlzdGFjay5zZXJpYWxpemUoKV07XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBJbmRleE9mO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuXG5pbXBvcnQge3R5cGVPZn0gZnJvbSAnLi4vdmFsdWVzLmpzJztcbmltcG9ydCB7VmFsdWVUeXBlLCB0eXBlIFR5cGV9IGZyb20gJy4uL3R5cGVzLmpzJztcblxuaW1wb3J0IHR5cGUge0V4cHJlc3Npb24sIFNlcmlhbGl6ZWRFeHByZXNzaW9ufSBmcm9tICcuLi9leHByZXNzaW9uLmpzJztcbmltcG9ydCB0eXBlIFBhcnNpbmdDb250ZXh0IGZyb20gJy4uL3BhcnNpbmdfY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSBFdmFsdWF0aW9uQ29udGV4dCBmcm9tICcuLi9ldmFsdWF0aW9uX2NvbnRleHQuanMnO1xuXG4vLyBNYXAgaW5wdXQgbGFiZWwgdmFsdWVzIHRvIG91dHB1dCBleHByZXNzaW9uIGluZGV4XG50eXBlIENhc2VzID0ge1tudW1iZXIgfCBzdHJpbmddOiBudW1iZXJ9O1xuXG5jbGFzcyBNYXRjaCBpbXBsZW1lbnRzIEV4cHJlc3Npb24ge1xuICAgIHR5cGU6IFR5cGU7XG4gICAgaW5wdXRUeXBlOiBUeXBlO1xuXG4gICAgaW5wdXQ6IEV4cHJlc3Npb247XG4gICAgY2FzZXM6IENhc2VzO1xuICAgIG91dHB1dHM6IEFycmF5PEV4cHJlc3Npb24+O1xuICAgIG90aGVyd2lzZTogRXhwcmVzc2lvbjtcblxuICAgIGNvbnN0cnVjdG9yKGlucHV0VHlwZTogVHlwZSwgb3V0cHV0VHlwZTogVHlwZSwgaW5wdXQ6IEV4cHJlc3Npb24sIGNhc2VzOiBDYXNlcywgb3V0cHV0czogQXJyYXk8RXhwcmVzc2lvbj4sIG90aGVyd2lzZTogRXhwcmVzc2lvbikge1xuICAgICAgICB0aGlzLmlucHV0VHlwZSA9IGlucHV0VHlwZTtcbiAgICAgICAgdGhpcy50eXBlID0gb3V0cHV0VHlwZTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IGlucHV0O1xuICAgICAgICB0aGlzLmNhc2VzID0gY2FzZXM7XG4gICAgICAgIHRoaXMub3V0cHV0cyA9IG91dHB1dHM7XG4gICAgICAgIHRoaXMub3RoZXJ3aXNlID0gb3RoZXJ3aXNlO1xuICAgIH1cblxuICAgIHN0YXRpYyBwYXJzZShhcmdzOiAkUmVhZE9ubHlBcnJheTxtaXhlZD4sIGNvbnRleHQ6IFBhcnNpbmdDb250ZXh0KTogP01hdGNoIHtcbiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoIDwgNSlcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmVycm9yKGBFeHBlY3RlZCBhdCBsZWFzdCA0IGFyZ3VtZW50cywgYnV0IGZvdW5kIG9ubHkgJHthcmdzLmxlbmd0aCAtIDF9LmApO1xuICAgICAgICBpZiAoYXJncy5sZW5ndGggJSAyICE9PSAxKVxuICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQuZXJyb3IoYEV4cGVjdGVkIGFuIGV2ZW4gbnVtYmVyIG9mIGFyZ3VtZW50cy5gKTtcblxuICAgICAgICBsZXQgaW5wdXRUeXBlO1xuICAgICAgICBsZXQgb3V0cHV0VHlwZTogP1R5cGU7XG4gICAgICAgIGlmIChjb250ZXh0LmV4cGVjdGVkVHlwZSAmJiBjb250ZXh0LmV4cGVjdGVkVHlwZS5raW5kICE9PSAndmFsdWUnKSB7XG4gICAgICAgICAgICBvdXRwdXRUeXBlID0gY29udGV4dC5leHBlY3RlZFR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2FzZXMgPSB7fTtcbiAgICAgICAgY29uc3Qgb3V0cHV0cyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMjsgaSA8IGFyZ3MubGVuZ3RoIC0gMTsgaSArPSAyKSB7XG4gICAgICAgICAgICBsZXQgbGFiZWxzID0gYXJnc1tpXTtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gYXJnc1tpICsgMV07XG5cbiAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShsYWJlbHMpKSB7XG4gICAgICAgICAgICAgICAgbGFiZWxzID0gW2xhYmVsc107XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGxhYmVsQ29udGV4dCA9IGNvbnRleHQuY29uY2F0KGkpO1xuICAgICAgICAgICAgaWYgKGxhYmVscy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbGFiZWxDb250ZXh0LmVycm9yKCdFeHBlY3RlZCBhdCBsZWFzdCBvbmUgYnJhbmNoIGxhYmVsLicpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGxhYmVsIG9mIGxhYmVscykge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbGFiZWwgIT09ICdudW1iZXInICYmIHR5cGVvZiBsYWJlbCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGxhYmVsQ29udGV4dC5lcnJvcihgQnJhbmNoIGxhYmVscyBtdXN0IGJlIG51bWJlcnMgb3Igc3RyaW5ncy5gKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBsYWJlbCA9PT0gJ251bWJlcicgJiYgTWF0aC5hYnMobGFiZWwpID4gTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGxhYmVsQ29udGV4dC5lcnJvcihgQnJhbmNoIGxhYmVscyBtdXN0IGJlIGludGVnZXJzIG5vIGxhcmdlciB0aGFuICR7TnVtYmVyLk1BWF9TQUZFX0lOVEVHRVJ9LmApO1xuXG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgbGFiZWwgPT09ICdudW1iZXInICYmIE1hdGguZmxvb3IobGFiZWwpICE9PSBsYWJlbCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbGFiZWxDb250ZXh0LmVycm9yKGBOdW1lcmljIGJyYW5jaCBsYWJlbHMgbXVzdCBiZSBpbnRlZ2VyIHZhbHVlcy5gKTtcblxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWlucHV0VHlwZSkge1xuICAgICAgICAgICAgICAgICAgICBpbnB1dFR5cGUgPSB0eXBlT2YobGFiZWwpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobGFiZWxDb250ZXh0LmNoZWNrU3VidHlwZShpbnB1dFR5cGUsIHR5cGVPZihsYWJlbCkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY2FzZXNbU3RyaW5nKGxhYmVsKV0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBsYWJlbENvbnRleHQuZXJyb3IoJ0JyYW5jaCBsYWJlbHMgbXVzdCBiZSB1bmlxdWUuJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY2FzZXNbU3RyaW5nKGxhYmVsKV0gPSBvdXRwdXRzLmxlbmd0aDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gY29udGV4dC5wYXJzZSh2YWx1ZSwgaSwgb3V0cHV0VHlwZSk7XG4gICAgICAgICAgICBpZiAoIXJlc3VsdCkgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICBvdXRwdXRUeXBlID0gb3V0cHV0VHlwZSB8fCByZXN1bHQudHlwZTtcbiAgICAgICAgICAgIG91dHB1dHMucHVzaChyZXN1bHQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaW5wdXQgPSBjb250ZXh0LnBhcnNlKGFyZ3NbMV0sIDEsIFZhbHVlVHlwZSk7XG4gICAgICAgIGlmICghaW5wdXQpIHJldHVybiBudWxsO1xuXG4gICAgICAgIGNvbnN0IG90aGVyd2lzZSA9IGNvbnRleHQucGFyc2UoYXJnc1thcmdzLmxlbmd0aCAtIDFdLCBhcmdzLmxlbmd0aCAtIDEsIG91dHB1dFR5cGUpO1xuICAgICAgICBpZiAoIW90aGVyd2lzZSkgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgYXNzZXJ0KGlucHV0VHlwZSAmJiBvdXRwdXRUeXBlKTtcblxuICAgICAgICBpZiAoaW5wdXQudHlwZS5raW5kICE9PSAndmFsdWUnICYmIGNvbnRleHQuY29uY2F0KDEpLmNoZWNrU3VidHlwZSgoaW5wdXRUeXBlOiBhbnkpLCBpbnB1dC50eXBlKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IE1hdGNoKChpbnB1dFR5cGU6IGFueSksIChvdXRwdXRUeXBlOiBhbnkpLCBpbnB1dCwgY2FzZXMsIG91dHB1dHMsIG90aGVyd2lzZSk7XG4gICAgfVxuXG4gICAgZXZhbHVhdGUoY3R4OiBFdmFsdWF0aW9uQ29udGV4dCk6IGFueSB7XG4gICAgICAgIGNvbnN0IGlucHV0ID0gKHRoaXMuaW5wdXQuZXZhbHVhdGUoY3R4KTogYW55KTtcbiAgICAgICAgY29uc3Qgb3V0cHV0ID0gKHR5cGVPZihpbnB1dCkgPT09IHRoaXMuaW5wdXRUeXBlICYmIHRoaXMub3V0cHV0c1t0aGlzLmNhc2VzW2lucHV0XV0pIHx8IHRoaXMub3RoZXJ3aXNlO1xuICAgICAgICByZXR1cm4gb3V0cHV0LmV2YWx1YXRlKGN0eCk7XG4gICAgfVxuXG4gICAgZWFjaENoaWxkKGZuOiAoXzogRXhwcmVzc2lvbikgPT4gdm9pZCkge1xuICAgICAgICBmbih0aGlzLmlucHV0KTtcbiAgICAgICAgdGhpcy5vdXRwdXRzLmZvckVhY2goZm4pO1xuICAgICAgICBmbih0aGlzLm90aGVyd2lzZSk7XG4gICAgfVxuXG4gICAgb3V0cHV0RGVmaW5lZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMub3V0cHV0cy5ldmVyeShvdXQgPT4gb3V0Lm91dHB1dERlZmluZWQoKSkgJiYgdGhpcy5vdGhlcndpc2Uub3V0cHV0RGVmaW5lZCgpO1xuICAgIH1cblxuICAgIHNlcmlhbGl6ZSgpOiBTZXJpYWxpemVkRXhwcmVzc2lvbiB7XG4gICAgICAgIGNvbnN0IHNlcmlhbGl6ZWQgPSBbXCJtYXRjaFwiLCB0aGlzLmlucHV0LnNlcmlhbGl6ZSgpXTtcblxuICAgICAgICAvLyBTb3J0IHNvIHNlcmlhbGl6YXRpb24gaGFzIGFuIGFyYml0cmFyeSBkZWZpbmVkIG9yZGVyLCBldmVuIHRob3VnaFxuICAgICAgICAvLyBicmFuY2ggb3JkZXIgZG9lc24ndCBhZmZlY3QgZXZhbHVhdGlvblxuICAgICAgICBjb25zdCBzb3J0ZWRMYWJlbHMgPSBPYmplY3Qua2V5cyh0aGlzLmNhc2VzKS5zb3J0KCk7XG5cbiAgICAgICAgLy8gR3JvdXAgYnJhbmNoZXMgYnkgdW5pcXVlIG1hdGNoIGV4cHJlc3Npb24gdG8gc3VwcG9ydCBjb25kZW5zZWRcbiAgICAgICAgLy8gc2VyaWFsaXphdGlvbnMgb2YgdGhlIGZvcm0gW2Nhc2UxLCBjYXNlMiwgLi4uXSAtPiBtYXRjaEV4cHJlc3Npb25cbiAgICAgICAgY29uc3QgZ3JvdXBlZEJ5T3V0cHV0OiBBcnJheTxbbnVtYmVyLCBBcnJheTxudW1iZXIgfCBzdHJpbmc+XT4gPSBbXTtcbiAgICAgICAgY29uc3Qgb3V0cHV0TG9va3VwOiB7W2luZGV4OiBudW1iZXJdOiBudW1iZXJ9ID0ge307IC8vIGxvb2t1cCBpbmRleCBpbnRvIGdyb3VwZWRCeU91dHB1dCBmb3IgYSBnaXZlbiBvdXRwdXQgZXhwcmVzc2lvblxuICAgICAgICBmb3IgKGNvbnN0IGxhYmVsIG9mIHNvcnRlZExhYmVscykge1xuICAgICAgICAgICAgY29uc3Qgb3V0cHV0SW5kZXggPSBvdXRwdXRMb29rdXBbdGhpcy5jYXNlc1tsYWJlbF1dO1xuICAgICAgICAgICAgaWYgKG91dHB1dEluZGV4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBGaXJzdCB0aW1lIHNlZWluZyB0aGlzIG91dHB1dCwgYWRkIGl0IHRvIHRoZSBlbmQgb2YgdGhlIGdyb3VwZWQgbGlzdFxuICAgICAgICAgICAgICAgIG91dHB1dExvb2t1cFt0aGlzLmNhc2VzW2xhYmVsXV0gPSBncm91cGVkQnlPdXRwdXQubGVuZ3RoO1xuICAgICAgICAgICAgICAgIGdyb3VwZWRCeU91dHB1dC5wdXNoKFt0aGlzLmNhc2VzW2xhYmVsXSwgW2xhYmVsXV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBXZSd2ZSBzZWVuIHRoaXMgZXhwcmVzc2lvbiBiZWZvcmUsIGFkZCB0aGUgbGFiZWwgdG8gdGhhdCBvdXRwdXQncyBncm91cFxuICAgICAgICAgICAgICAgIGdyb3VwZWRCeU91dHB1dFtvdXRwdXRJbmRleF1bMV0ucHVzaChsYWJlbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjb2VyY2VMYWJlbCA9IChsYWJlbDogbnVtYmVyIHwgc3RyaW5nKSA9PiB0aGlzLmlucHV0VHlwZS5raW5kID09PSAnbnVtYmVyJyA/IE51bWJlcihsYWJlbCkgOiBsYWJlbDtcblxuICAgICAgICBmb3IgKGNvbnN0IFtvdXRwdXRJbmRleCwgbGFiZWxzXSBvZiBncm91cGVkQnlPdXRwdXQpIHtcbiAgICAgICAgICAgIGlmIChsYWJlbHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAgICAgLy8gT25seSBhIHNpbmdsZSBsYWJlbCBtYXRjaGVzIHRoaXMgb3V0cHV0IGV4cHJlc3Npb25cbiAgICAgICAgICAgICAgICBzZXJpYWxpemVkLnB1c2goY29lcmNlTGFiZWwobGFiZWxzWzBdKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIEFycmF5IG9mIGxpdGVyYWwgbGFiZWxzIHBvaW50aW5nIHRvIHRoaXMgb3V0cHV0IGV4cHJlc3Npb25cbiAgICAgICAgICAgICAgICBzZXJpYWxpemVkLnB1c2gobGFiZWxzLm1hcChjb2VyY2VMYWJlbCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2VyaWFsaXplZC5wdXNoKHRoaXMub3V0cHV0c1tvdXRwdXRJbmRleF0uc2VyaWFsaXplKCkpO1xuICAgICAgICB9XG4gICAgICAgIHNlcmlhbGl6ZWQucHVzaCh0aGlzLm90aGVyd2lzZS5zZXJpYWxpemUoKSk7XG4gICAgICAgIHJldHVybiBzZXJpYWxpemVkO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTWF0Y2g7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbmltcG9ydCB7Qm9vbGVhblR5cGV9IGZyb20gJy4uL3R5cGVzLmpzJztcblxuaW1wb3J0IHR5cGUge0V4cHJlc3Npb24sIFNlcmlhbGl6ZWRFeHByZXNzaW9ufSBmcm9tICcuLi9leHByZXNzaW9uLmpzJztcbmltcG9ydCB0eXBlIFBhcnNpbmdDb250ZXh0IGZyb20gJy4uL3BhcnNpbmdfY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSBFdmFsdWF0aW9uQ29udGV4dCBmcm9tICcuLi9ldmFsdWF0aW9uX2NvbnRleHQuanMnO1xuaW1wb3J0IHR5cGUge1R5cGV9IGZyb20gJy4uL3R5cGVzLmpzJztcblxudHlwZSBCcmFuY2hlcyA9IEFycmF5PFtFeHByZXNzaW9uLCBFeHByZXNzaW9uXT47XG5cbmNsYXNzIENhc2UgaW1wbGVtZW50cyBFeHByZXNzaW9uIHtcbiAgICB0eXBlOiBUeXBlO1xuXG4gICAgYnJhbmNoZXM6IEJyYW5jaGVzO1xuICAgIG90aGVyd2lzZTogRXhwcmVzc2lvbjtcblxuICAgIGNvbnN0cnVjdG9yKHR5cGU6IFR5cGUsIGJyYW5jaGVzOiBCcmFuY2hlcywgb3RoZXJ3aXNlOiBFeHByZXNzaW9uKSB7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuYnJhbmNoZXMgPSBicmFuY2hlcztcbiAgICAgICAgdGhpcy5vdGhlcndpc2UgPSBvdGhlcndpc2U7XG4gICAgfVxuXG4gICAgc3RhdGljIHBhcnNlKGFyZ3M6ICRSZWFkT25seUFycmF5PG1peGVkPiwgY29udGV4dDogUGFyc2luZ0NvbnRleHQpOiA/Q2FzZSB7XG4gICAgICAgIGlmIChhcmdzLmxlbmd0aCA8IDQpXG4gICAgICAgICAgICByZXR1cm4gY29udGV4dC5lcnJvcihgRXhwZWN0ZWQgYXQgbGVhc3QgMyBhcmd1bWVudHMsIGJ1dCBmb3VuZCBvbmx5ICR7YXJncy5sZW5ndGggLSAxfS5gKTtcbiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoICUgMiAhPT0gMClcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmVycm9yKGBFeHBlY3RlZCBhbiBvZGQgbnVtYmVyIG9mIGFyZ3VtZW50cy5gKTtcblxuICAgICAgICBsZXQgb3V0cHV0VHlwZTogP1R5cGU7XG4gICAgICAgIGlmIChjb250ZXh0LmV4cGVjdGVkVHlwZSAmJiBjb250ZXh0LmV4cGVjdGVkVHlwZS5raW5kICE9PSAndmFsdWUnKSB7XG4gICAgICAgICAgICBvdXRwdXRUeXBlID0gY29udGV4dC5leHBlY3RlZFR5cGU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBicmFuY2hlcyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IGFyZ3MubGVuZ3RoIC0gMTsgaSArPSAyKSB7XG4gICAgICAgICAgICBjb25zdCB0ZXN0ID0gY29udGV4dC5wYXJzZShhcmdzW2ldLCBpLCBCb29sZWFuVHlwZSk7XG4gICAgICAgICAgICBpZiAoIXRlc3QpIHJldHVybiBudWxsO1xuXG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBjb250ZXh0LnBhcnNlKGFyZ3NbaSArIDFdLCBpICsgMSwgb3V0cHV0VHlwZSk7XG4gICAgICAgICAgICBpZiAoIXJlc3VsdCkgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgICAgIGJyYW5jaGVzLnB1c2goW3Rlc3QsIHJlc3VsdF0pO1xuXG4gICAgICAgICAgICBvdXRwdXRUeXBlID0gb3V0cHV0VHlwZSB8fCByZXN1bHQudHlwZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG90aGVyd2lzZSA9IGNvbnRleHQucGFyc2UoYXJnc1thcmdzLmxlbmd0aCAtIDFdLCBhcmdzLmxlbmd0aCAtIDEsIG91dHB1dFR5cGUpO1xuICAgICAgICBpZiAoIW90aGVyd2lzZSkgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgYXNzZXJ0KG91dHB1dFR5cGUpO1xuICAgICAgICByZXR1cm4gbmV3IENhc2UoKG91dHB1dFR5cGU6IGFueSksIGJyYW5jaGVzLCBvdGhlcndpc2UpO1xuICAgIH1cblxuICAgIGV2YWx1YXRlKGN0eDogRXZhbHVhdGlvbkNvbnRleHQpOiBhbnkge1xuICAgICAgICBmb3IgKGNvbnN0IFt0ZXN0LCBleHByZXNzaW9uXSBvZiB0aGlzLmJyYW5jaGVzKSB7XG4gICAgICAgICAgICBpZiAodGVzdC5ldmFsdWF0ZShjdHgpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGV4cHJlc3Npb24uZXZhbHVhdGUoY3R4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5vdGhlcndpc2UuZXZhbHVhdGUoY3R4KTtcbiAgICB9XG5cbiAgICBlYWNoQ2hpbGQoZm46IChfOiBFeHByZXNzaW9uKSA9PiB2b2lkKSB7XG4gICAgICAgIGZvciAoY29uc3QgW3Rlc3QsIGV4cHJlc3Npb25dIG9mIHRoaXMuYnJhbmNoZXMpIHtcbiAgICAgICAgICAgIGZuKHRlc3QpO1xuICAgICAgICAgICAgZm4oZXhwcmVzc2lvbik7XG4gICAgICAgIH1cbiAgICAgICAgZm4odGhpcy5vdGhlcndpc2UpO1xuICAgIH1cblxuICAgIG91dHB1dERlZmluZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmJyYW5jaGVzLmV2ZXJ5KChbXywgb3V0XSkgPT4gb3V0Lm91dHB1dERlZmluZWQoKSkgJiYgdGhpcy5vdGhlcndpc2Uub3V0cHV0RGVmaW5lZCgpO1xuICAgIH1cblxuICAgIHNlcmlhbGl6ZSgpOiBTZXJpYWxpemVkRXhwcmVzc2lvbiB7XG4gICAgICAgIGNvbnN0IHNlcmlhbGl6ZWQgPSBbXCJjYXNlXCJdO1xuICAgICAgICB0aGlzLmVhY2hDaGlsZChjaGlsZCA9PiB7IHNlcmlhbGl6ZWQucHVzaChjaGlsZC5zZXJpYWxpemUoKSk7IH0pO1xuICAgICAgICByZXR1cm4gc2VyaWFsaXplZDtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IENhc2U7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge1ZhbHVlVHlwZSwgTnVtYmVyVHlwZSwgU3RyaW5nVHlwZSwgYXJyYXksIHRvU3RyaW5nLCBpc1ZhbGlkVHlwZSwgaXNWYWxpZE5hdGl2ZVR5cGV9IGZyb20gJy4uL3R5cGVzLmpzJztcbmltcG9ydCBSdW50aW1lRXJyb3IgZnJvbSAnLi4vcnVudGltZV9lcnJvci5qcyc7XG5pbXBvcnQge3R5cGVPZn0gZnJvbSAnLi4vdmFsdWVzLmpzJztcblxuaW1wb3J0IHR5cGUge0V4cHJlc3Npb24sIFNlcmlhbGl6ZWRFeHByZXNzaW9ufSBmcm9tICcuLi9leHByZXNzaW9uLmpzJztcbmltcG9ydCB0eXBlIFBhcnNpbmdDb250ZXh0IGZyb20gJy4uL3BhcnNpbmdfY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSBFdmFsdWF0aW9uQ29udGV4dCBmcm9tICcuLi9ldmFsdWF0aW9uX2NvbnRleHQuanMnO1xuaW1wb3J0IHR5cGUge1R5cGV9IGZyb20gJy4uL3R5cGVzLmpzJztcblxuY2xhc3MgU2xpY2UgaW1wbGVtZW50cyBFeHByZXNzaW9uIHtcbiAgICB0eXBlOiBUeXBlO1xuICAgIGlucHV0OiBFeHByZXNzaW9uO1xuICAgIGJlZ2luSW5kZXg6IEV4cHJlc3Npb247XG4gICAgZW5kSW5kZXg6ID9FeHByZXNzaW9uO1xuXG4gICAgY29uc3RydWN0b3IodHlwZTogVHlwZSwgaW5wdXQ6IEV4cHJlc3Npb24sIGJlZ2luSW5kZXg6IEV4cHJlc3Npb24sIGVuZEluZGV4PzogRXhwcmVzc2lvbikge1xuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLmlucHV0ID0gaW5wdXQ7XG4gICAgICAgIHRoaXMuYmVnaW5JbmRleCA9IGJlZ2luSW5kZXg7XG4gICAgICAgIHRoaXMuZW5kSW5kZXggPSBlbmRJbmRleDtcblxuICAgIH1cblxuICAgIHN0YXRpYyBwYXJzZShhcmdzOiAkUmVhZE9ubHlBcnJheTxtaXhlZD4sIGNvbnRleHQ6IFBhcnNpbmdDb250ZXh0KTogP1NsaWNlIHtcbiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoIDw9IDIgfHwgIGFyZ3MubGVuZ3RoID49IDUpIHtcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmVycm9yKGBFeHBlY3RlZCAzIG9yIDQgYXJndW1lbnRzLCBidXQgZm91bmQgJHthcmdzLmxlbmd0aCAtIDF9IGluc3RlYWQuYCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBpbnB1dCA9IGNvbnRleHQucGFyc2UoYXJnc1sxXSwgMSwgVmFsdWVUeXBlKTtcbiAgICAgICAgY29uc3QgYmVnaW5JbmRleCA9IGNvbnRleHQucGFyc2UoYXJnc1syXSwgMiwgTnVtYmVyVHlwZSk7XG5cbiAgICAgICAgaWYgKCFpbnB1dCB8fCAhYmVnaW5JbmRleCkgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgaWYgKCFpc1ZhbGlkVHlwZShpbnB1dC50eXBlLCBbYXJyYXkoVmFsdWVUeXBlKSwgU3RyaW5nVHlwZSwgVmFsdWVUeXBlXSkpIHtcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmVycm9yKGBFeHBlY3RlZCBmaXJzdCBhcmd1bWVudCB0byBiZSBvZiB0eXBlIGFycmF5IG9yIHN0cmluZywgYnV0IGZvdW5kICR7dG9TdHJpbmcoaW5wdXQudHlwZSl9IGluc3RlYWRgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhcmdzLmxlbmd0aCA9PT0gNCkge1xuICAgICAgICAgICAgY29uc3QgZW5kSW5kZXggPSBjb250ZXh0LnBhcnNlKGFyZ3NbM10sIDMsIE51bWJlclR5cGUpO1xuICAgICAgICAgICAgaWYgKCFlbmRJbmRleCkgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFNsaWNlKGlucHV0LnR5cGUsIGlucHV0LCBiZWdpbkluZGV4LCBlbmRJbmRleCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFNsaWNlKGlucHV0LnR5cGUsIGlucHV0LCBiZWdpbkluZGV4KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGV2YWx1YXRlKGN0eDogRXZhbHVhdGlvbkNvbnRleHQpOiBhbnkge1xuICAgICAgICBjb25zdCBpbnB1dCA9ICh0aGlzLmlucHV0LmV2YWx1YXRlKGN0eCk6IGFueSk7XG4gICAgICAgIGNvbnN0IGJlZ2luSW5kZXggPSAodGhpcy5iZWdpbkluZGV4LmV2YWx1YXRlKGN0eCk6IG51bWJlcik7XG5cbiAgICAgICAgaWYgKCFpc1ZhbGlkTmF0aXZlVHlwZShpbnB1dCwgWydzdHJpbmcnLCAnYXJyYXknXSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXJyb3IoYEV4cGVjdGVkIGZpcnN0IGFyZ3VtZW50IHRvIGJlIG9mIHR5cGUgYXJyYXkgb3Igc3RyaW5nLCBidXQgZm91bmQgJHt0b1N0cmluZyh0eXBlT2YoaW5wdXQpKX0gaW5zdGVhZC5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmVuZEluZGV4KSB7XG4gICAgICAgICAgICBjb25zdCBlbmRJbmRleCA9ICh0aGlzLmVuZEluZGV4LmV2YWx1YXRlKGN0eCk6IG51bWJlcik7XG4gICAgICAgICAgICByZXR1cm4gaW5wdXQuc2xpY2UoYmVnaW5JbmRleCwgZW5kSW5kZXgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGlucHV0LnNsaWNlKGJlZ2luSW5kZXgpO1xuICAgIH1cblxuICAgIGVhY2hDaGlsZChmbjogKF86IEV4cHJlc3Npb24pID0+IHZvaWQpIHtcbiAgICAgICAgZm4odGhpcy5pbnB1dCk7XG4gICAgICAgIGZuKHRoaXMuYmVnaW5JbmRleCk7XG4gICAgICAgIGlmICh0aGlzLmVuZEluZGV4KSB7XG4gICAgICAgICAgICBmbih0aGlzLmVuZEluZGV4KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG91dHB1dERlZmluZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBzZXJpYWxpemUoKTogU2VyaWFsaXplZEV4cHJlc3Npb24ge1xuICAgICAgICBpZiAodGhpcy5lbmRJbmRleCAhPSBudWxsICYmIHRoaXMuZW5kSW5kZXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY29uc3QgZW5kSW5kZXggPSB0aGlzLmVuZEluZGV4LnNlcmlhbGl6ZSgpO1xuICAgICAgICAgICAgcmV0dXJuIFtcInNsaWNlXCIsIHRoaXMuaW5wdXQuc2VyaWFsaXplKCksIHRoaXMuYmVnaW5JbmRleC5zZXJpYWxpemUoKSwgZW5kSW5kZXhdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbXCJzbGljZVwiLCB0aGlzLmlucHV0LnNlcmlhbGl6ZSgpLCB0aGlzLmJlZ2luSW5kZXguc2VyaWFsaXplKCldO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgU2xpY2U7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge3RvU3RyaW5nLCBWYWx1ZVR5cGUsIEJvb2xlYW5UeXBlLCBDb2xsYXRvclR5cGV9IGZyb20gJy4uL3R5cGVzLmpzJztcbmltcG9ydCBBc3NlcnRpb24gZnJvbSAnLi9hc3NlcnRpb24uanMnO1xuaW1wb3J0IHt0eXBlT2Z9IGZyb20gJy4uL3ZhbHVlcy5qcyc7XG5pbXBvcnQgUnVudGltZUVycm9yIGZyb20gJy4uL3J1bnRpbWVfZXJyb3IuanMnO1xuXG5pbXBvcnQgdHlwZSB7RXhwcmVzc2lvbiwgU2VyaWFsaXplZEV4cHJlc3Npb24sIEV4cHJlc3Npb25SZWdpc3RyYXRpb259IGZyb20gJy4uL2V4cHJlc3Npb24uanMnO1xuaW1wb3J0IHR5cGUgRXZhbHVhdGlvbkNvbnRleHQgZnJvbSAnLi4vZXZhbHVhdGlvbl9jb250ZXh0LmpzJztcbmltcG9ydCB0eXBlIFBhcnNpbmdDb250ZXh0IGZyb20gJy4uL3BhcnNpbmdfY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSB7VHlwZX0gZnJvbSAnLi4vdHlwZXMuanMnO1xuXG50eXBlIENvbXBhcmlzb25PcGVyYXRvciA9ICc9PScgfCAnIT0nIHwgJzwnIHwgJz4nIHwgJzw9JyB8ICc+PScgO1xuXG5mdW5jdGlvbiBpc0NvbXBhcmFibGVUeXBlKG9wOiBDb21wYXJpc29uT3BlcmF0b3IsIHR5cGU6IFR5cGUpIHtcbiAgICBpZiAob3AgPT09ICc9PScgfHwgb3AgPT09ICchPScpIHtcbiAgICAgICAgLy8gZXF1YWxpdHkgb3BlcmF0b3JcbiAgICAgICAgcmV0dXJuIHR5cGUua2luZCA9PT0gJ2Jvb2xlYW4nIHx8XG4gICAgICAgICAgICB0eXBlLmtpbmQgPT09ICdzdHJpbmcnIHx8XG4gICAgICAgICAgICB0eXBlLmtpbmQgPT09ICdudW1iZXInIHx8XG4gICAgICAgICAgICB0eXBlLmtpbmQgPT09ICdudWxsJyB8fFxuICAgICAgICAgICAgdHlwZS5raW5kID09PSAndmFsdWUnO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG9yZGVyaW5nIG9wZXJhdG9yXG4gICAgICAgIHJldHVybiB0eXBlLmtpbmQgPT09ICdzdHJpbmcnIHx8XG4gICAgICAgICAgICB0eXBlLmtpbmQgPT09ICdudW1iZXInIHx8XG4gICAgICAgICAgICB0eXBlLmtpbmQgPT09ICd2YWx1ZSc7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBlcShjdHg6IEV2YWx1YXRpb25Db250ZXh0LCBhOiBhbnksIGI6IGFueSk6IGJvb2xlYW4geyByZXR1cm4gYSA9PT0gYjsgfVxuZnVuY3Rpb24gbmVxKGN0eDogRXZhbHVhdGlvbkNvbnRleHQsIGE6IGFueSwgYjogYW55KTogYm9vbGVhbiB7IHJldHVybiBhICE9PSBiOyB9XG5mdW5jdGlvbiBsdChjdHg6IEV2YWx1YXRpb25Db250ZXh0LCBhOiBhbnksIGI6IGFueSk6IGJvb2xlYW4geyByZXR1cm4gYSA8IGI7IH1cbmZ1bmN0aW9uIGd0KGN0eDogRXZhbHVhdGlvbkNvbnRleHQsIGE6IGFueSwgYjogYW55KTogYm9vbGVhbiB7IHJldHVybiBhID4gYjsgfVxuZnVuY3Rpb24gbHRlcShjdHg6IEV2YWx1YXRpb25Db250ZXh0LCBhOiBhbnksIGI6IGFueSk6IGJvb2xlYW4geyByZXR1cm4gYSA8PSBiOyB9XG5mdW5jdGlvbiBndGVxKGN0eDogRXZhbHVhdGlvbkNvbnRleHQsIGE6IGFueSwgYjogYW55KTogYm9vbGVhbiB7IHJldHVybiBhID49IGI7IH1cblxuZnVuY3Rpb24gZXFDb2xsYXRlKGN0eDogRXZhbHVhdGlvbkNvbnRleHQsIGE6IGFueSwgYjogYW55LCBjOiBhbnkpOiBib29sZWFuIHsgcmV0dXJuIGMuY29tcGFyZShhLCBiKSA9PT0gMDsgfVxuZnVuY3Rpb24gbmVxQ29sbGF0ZShjdHg6IEV2YWx1YXRpb25Db250ZXh0LCBhOiBhbnksIGI6IGFueSwgYzogYW55KTogYm9vbGVhbiB7IHJldHVybiAhZXFDb2xsYXRlKGN0eCwgYSwgYiwgYyk7IH1cbmZ1bmN0aW9uIGx0Q29sbGF0ZShjdHg6IEV2YWx1YXRpb25Db250ZXh0LCBhOiBhbnksIGI6IGFueSwgYzogYW55KTogYm9vbGVhbiB7IHJldHVybiBjLmNvbXBhcmUoYSwgYikgPCAwOyB9XG5mdW5jdGlvbiBndENvbGxhdGUoY3R4OiBFdmFsdWF0aW9uQ29udGV4dCwgYTogYW55LCBiOiBhbnksIGM6IGFueSk6IGJvb2xlYW4geyByZXR1cm4gYy5jb21wYXJlKGEsIGIpID4gMDsgfVxuZnVuY3Rpb24gbHRlcUNvbGxhdGUoY3R4OiBFdmFsdWF0aW9uQ29udGV4dCwgYTogYW55LCBiOiBhbnksIGM6IGFueSk6IGJvb2xlYW4geyByZXR1cm4gYy5jb21wYXJlKGEsIGIpIDw9IDA7IH1cbmZ1bmN0aW9uIGd0ZXFDb2xsYXRlKGN0eDogRXZhbHVhdGlvbkNvbnRleHQsIGE6IGFueSwgYjogYW55LCBjOiBhbnkpOiBib29sZWFuIHsgcmV0dXJuIGMuY29tcGFyZShhLCBiKSA+PSAwOyB9XG5cbi8qKlxuICogU3BlY2lhbCBmb3JtIGZvciBjb21wYXJpc29uIG9wZXJhdG9ycywgaW1wbGVtZW50aW5nIHRoZSBzaWduYXR1cmVzOlxuICogLSAoVCwgVCwgP0NvbGxhdG9yKSA9PiBib29sZWFuXG4gKiAtIChULCB2YWx1ZSwgP0NvbGxhdG9yKSA9PiBib29sZWFuXG4gKiAtICh2YWx1ZSwgVCwgP0NvbGxhdG9yKSA9PiBib29sZWFuXG4gKlxuICogRm9yIGluZXF1YWxpdGllcywgVCBtdXN0IGJlIGVpdGhlciB2YWx1ZSwgc3RyaW5nLCBvciBudW1iZXIuIEZvciA9PS8hPSwgaXRcbiAqIGNhbiBhbHNvIGJlIGJvb2xlYW4gb3IgbnVsbC5cbiAqXG4gKiBFcXVhbGl0eSBzZW1hbnRpY3MgYXJlIGVxdWl2YWxlbnQgdG8gSmF2YXNjcmlwdCdzIHN0cmljdCBlcXVhbGl0eSAoPT09LyE9PSlcbiAqIC0tIGkuZS4sIHdoZW4gdGhlIGFyZ3VtZW50cycgdHlwZXMgZG9uJ3QgbWF0Y2gsID09IGV2YWx1YXRlcyB0byBmYWxzZSwgIT0gdG9cbiAqIHRydWUuXG4gKlxuICogV2hlbiB0eXBlcyBkb24ndCBtYXRjaCBpbiBhbiBvcmRlcmluZyBjb21wYXJpc29uLCBhIHJ1bnRpbWUgZXJyb3IgaXMgdGhyb3duLlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIG1ha2VDb21wYXJpc29uKG9wOiBDb21wYXJpc29uT3BlcmF0b3IsIGNvbXBhcmVCYXNpYzogKEV2YWx1YXRpb25Db250ZXh0LCBhbnksIGFueSkgPT4gYm9vbGVhbiwgY29tcGFyZVdpdGhDb2xsYXRvcjogKEV2YWx1YXRpb25Db250ZXh0LCBhbnksIGFueSwgYW55KSA9PiBib29sZWFuKTogRXhwcmVzc2lvblJlZ2lzdHJhdGlvbiB7XG4gICAgY29uc3QgaXNPcmRlckNvbXBhcmlzb24gPSBvcCAhPT0gJz09JyAmJiBvcCAhPT0gJyE9JztcblxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICByZXR1cm4gY2xhc3MgQ29tcGFyaXNvbiBpbXBsZW1lbnRzIEV4cHJlc3Npb24ge1xuICAgICAgICB0eXBlOiBUeXBlO1xuICAgICAgICBsaHM6IEV4cHJlc3Npb247XG4gICAgICAgIHJoczogRXhwcmVzc2lvbjtcbiAgICAgICAgY29sbGF0b3I6ID9FeHByZXNzaW9uO1xuICAgICAgICBoYXNVbnR5cGVkQXJndW1lbnQ6IGJvb2xlYW47XG5cbiAgICAgICAgY29uc3RydWN0b3IobGhzOiBFeHByZXNzaW9uLCByaHM6IEV4cHJlc3Npb24sIGNvbGxhdG9yOiA/RXhwcmVzc2lvbikge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gQm9vbGVhblR5cGU7XG4gICAgICAgICAgICB0aGlzLmxocyA9IGxocztcbiAgICAgICAgICAgIHRoaXMucmhzID0gcmhzO1xuICAgICAgICAgICAgdGhpcy5jb2xsYXRvciA9IGNvbGxhdG9yO1xuICAgICAgICAgICAgdGhpcy5oYXNVbnR5cGVkQXJndW1lbnQgPSBsaHMudHlwZS5raW5kID09PSAndmFsdWUnIHx8IHJocy50eXBlLmtpbmQgPT09ICd2YWx1ZSc7XG4gICAgICAgIH1cblxuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIHN0YXRpYyBwYXJzZShhcmdzOiAkUmVhZE9ubHlBcnJheTxtaXhlZD4sIGNvbnRleHQ6IFBhcnNpbmdDb250ZXh0KTogP0V4cHJlc3Npb24ge1xuICAgICAgICAgICAgaWYgKGFyZ3MubGVuZ3RoICE9PSAzICYmIGFyZ3MubGVuZ3RoICE9PSA0KVxuICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmVycm9yKGBFeHBlY3RlZCB0d28gb3IgdGhyZWUgYXJndW1lbnRzLmApO1xuXG4gICAgICAgICAgICBjb25zdCBvcDogQ29tcGFyaXNvbk9wZXJhdG9yID0gKGFyZ3NbMF06IGFueSk7XG5cbiAgICAgICAgICAgIGxldCBsaHMgPSBjb250ZXh0LnBhcnNlKGFyZ3NbMV0sIDEsIFZhbHVlVHlwZSk7XG4gICAgICAgICAgICBpZiAoIWxocykgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICBpZiAoIWlzQ29tcGFyYWJsZVR5cGUob3AsIGxocy50eXBlKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmNvbmNhdCgxKS5lcnJvcihgXCIke29wfVwiIGNvbXBhcmlzb25zIGFyZSBub3Qgc3VwcG9ydGVkIGZvciB0eXBlICcke3RvU3RyaW5nKGxocy50eXBlKX0nLmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IHJocyA9IGNvbnRleHQucGFyc2UoYXJnc1syXSwgMiwgVmFsdWVUeXBlKTtcbiAgICAgICAgICAgIGlmICghcmhzKSByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIGlmICghaXNDb21wYXJhYmxlVHlwZShvcCwgcmhzLnR5cGUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQuY29uY2F0KDIpLmVycm9yKGBcIiR7b3B9XCIgY29tcGFyaXNvbnMgYXJlIG5vdCBzdXBwb3J0ZWQgZm9yIHR5cGUgJyR7dG9TdHJpbmcocmhzLnR5cGUpfScuYCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBsaHMudHlwZS5raW5kICE9PSByaHMudHlwZS5raW5kICYmXG4gICAgICAgICAgICAgICAgbGhzLnR5cGUua2luZCAhPT0gJ3ZhbHVlJyAmJlxuICAgICAgICAgICAgICAgIHJocy50eXBlLmtpbmQgIT09ICd2YWx1ZSdcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmVycm9yKGBDYW5ub3QgY29tcGFyZSB0eXBlcyAnJHt0b1N0cmluZyhsaHMudHlwZSl9JyBhbmQgJyR7dG9TdHJpbmcocmhzLnR5cGUpfScuYCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpc09yZGVyQ29tcGFyaXNvbikge1xuICAgICAgICAgICAgICAgIC8vIHR5cGluZyBydWxlcyBzcGVjaWZpYyB0byBsZXNzL2dyZWF0ZXIgdGhhbiBvcGVyYXRvcnNcbiAgICAgICAgICAgICAgICBpZiAobGhzLnR5cGUua2luZCA9PT0gJ3ZhbHVlJyAmJiByaHMudHlwZS5raW5kICE9PSAndmFsdWUnKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vICh2YWx1ZSwgVClcbiAgICAgICAgICAgICAgICAgICAgbGhzID0gbmV3IEFzc2VydGlvbihyaHMudHlwZSwgW2xoc10pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobGhzLnR5cGUua2luZCAhPT0gJ3ZhbHVlJyAmJiByaHMudHlwZS5raW5kID09PSAndmFsdWUnKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIChULCB2YWx1ZSlcbiAgICAgICAgICAgICAgICAgICAgcmhzID0gbmV3IEFzc2VydGlvbihsaHMudHlwZSwgW3Joc10pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IGNvbGxhdG9yID0gbnVsbDtcbiAgICAgICAgICAgIGlmIChhcmdzLmxlbmd0aCA9PT0gNCkge1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgbGhzLnR5cGUua2luZCAhPT0gJ3N0cmluZycgJiZcbiAgICAgICAgICAgICAgICAgICAgcmhzLnR5cGUua2luZCAhPT0gJ3N0cmluZycgJiZcbiAgICAgICAgICAgICAgICAgICAgbGhzLnR5cGUua2luZCAhPT0gJ3ZhbHVlJyAmJlxuICAgICAgICAgICAgICAgICAgICByaHMudHlwZS5raW5kICE9PSAndmFsdWUnXG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmVycm9yKGBDYW5ub3QgdXNlIGNvbGxhdG9yIHRvIGNvbXBhcmUgbm9uLXN0cmluZyB0eXBlcy5gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29sbGF0b3IgPSBjb250ZXh0LnBhcnNlKGFyZ3NbM10sIDMsIENvbGxhdG9yVHlwZSk7XG4gICAgICAgICAgICAgICAgaWYgKCFjb2xsYXRvcikgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBuZXcgQ29tcGFyaXNvbihsaHMsIHJocywgY29sbGF0b3IpO1xuICAgICAgICB9XG5cbiAgICAgICAgZXZhbHVhdGUoY3R4OiBFdmFsdWF0aW9uQ29udGV4dCk6IGJvb2xlYW4ge1xuICAgICAgICAgICAgY29uc3QgbGhzID0gdGhpcy5saHMuZXZhbHVhdGUoY3R4KTtcbiAgICAgICAgICAgIGNvbnN0IHJocyA9IHRoaXMucmhzLmV2YWx1YXRlKGN0eCk7XG5cbiAgICAgICAgICAgIGlmIChpc09yZGVyQ29tcGFyaXNvbiAmJiB0aGlzLmhhc1VudHlwZWRBcmd1bWVudCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGx0ID0gdHlwZU9mKGxocyk7XG4gICAgICAgICAgICAgICAgY29uc3QgcnQgPSB0eXBlT2YocmhzKTtcbiAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGF0IHR5cGUgaXMgc3RyaW5nIG9yIG51bWJlciwgYW5kIGVxdWFsXG4gICAgICAgICAgICAgICAgaWYgKGx0LmtpbmQgIT09IHJ0LmtpbmQgfHwgIShsdC5raW5kID09PSAnc3RyaW5nJyB8fCBsdC5raW5kID09PSAnbnVtYmVyJykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcihgRXhwZWN0ZWQgYXJndW1lbnRzIGZvciBcIiR7b3B9XCIgdG8gYmUgKHN0cmluZywgc3RyaW5nKSBvciAobnVtYmVyLCBudW1iZXIpLCBidXQgZm91bmQgKCR7bHQua2luZH0sICR7cnQua2luZH0pIGluc3RlYWQuYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5jb2xsYXRvciAmJiAhaXNPcmRlckNvbXBhcmlzb24gJiYgdGhpcy5oYXNVbnR5cGVkQXJndW1lbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBsdCA9IHR5cGVPZihsaHMpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJ0ID0gdHlwZU9mKHJocyk7XG4gICAgICAgICAgICAgICAgaWYgKGx0LmtpbmQgIT09ICdzdHJpbmcnIHx8IHJ0LmtpbmQgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb21wYXJlQmFzaWMoY3R4LCBsaHMsIHJocyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb2xsYXRvciA/XG4gICAgICAgICAgICAgICAgY29tcGFyZVdpdGhDb2xsYXRvcihjdHgsIGxocywgcmhzLCB0aGlzLmNvbGxhdG9yLmV2YWx1YXRlKGN0eCkpIDpcbiAgICAgICAgICAgICAgICBjb21wYXJlQmFzaWMoY3R4LCBsaHMsIHJocyk7XG4gICAgICAgIH1cblxuICAgICAgICBlYWNoQ2hpbGQoZm46IChfOiBFeHByZXNzaW9uKSA9PiB2b2lkKSB7XG4gICAgICAgICAgICBmbih0aGlzLmxocyk7XG4gICAgICAgICAgICBmbih0aGlzLnJocyk7XG4gICAgICAgICAgICBpZiAodGhpcy5jb2xsYXRvcikge1xuICAgICAgICAgICAgICAgIGZuKHRoaXMuY29sbGF0b3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgb3V0cHV0RGVmaW5lZCgpOiBib29sZWFuIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgc2VyaWFsaXplKCk6IFNlcmlhbGl6ZWRFeHByZXNzaW9uIHtcbiAgICAgICAgICAgIGNvbnN0IHNlcmlhbGl6ZWQgPSBbb3BdO1xuICAgICAgICAgICAgdGhpcy5lYWNoQ2hpbGQoY2hpbGQgPT4geyBzZXJpYWxpemVkLnB1c2goY2hpbGQuc2VyaWFsaXplKCkpOyB9KTtcbiAgICAgICAgICAgIHJldHVybiBzZXJpYWxpemVkO1xuICAgICAgICB9XG4gICAgfTtcbn1cblxuZXhwb3J0IGNvbnN0IEVxdWFsczogJENhbGw8dHlwZW9mIG1ha2VDb21wYXJpc29uLCAnPT0nLCB0eXBlb2YgZXEsIHR5cGVvZiBlcUNvbGxhdGU+ID0gbWFrZUNvbXBhcmlzb24oJz09JywgZXEsIGVxQ29sbGF0ZSk7XG5leHBvcnQgY29uc3QgTm90RXF1YWxzOiAkQ2FsbDx0eXBlb2YgbWFrZUNvbXBhcmlzb24sICchPScsIHR5cGVvZiBuZXEsIHR5cGVvZiBuZXFDb2xsYXRlPiA9IG1ha2VDb21wYXJpc29uKCchPScsIG5lcSwgbmVxQ29sbGF0ZSk7XG5leHBvcnQgY29uc3QgTGVzc1RoYW46ICRDYWxsPHR5cGVvZiBtYWtlQ29tcGFyaXNvbiwgJzwnLCB0eXBlb2YgbHQsIHR5cGVvZiBsdENvbGxhdGU+ID0gbWFrZUNvbXBhcmlzb24oJzwnLCBsdCwgbHRDb2xsYXRlKTtcbmV4cG9ydCBjb25zdCBHcmVhdGVyVGhhbjogJENhbGw8dHlwZW9mIG1ha2VDb21wYXJpc29uLCAnPicsIHR5cGVvZiBndCwgdHlwZW9mIGd0Q29sbGF0ZT4gPSBtYWtlQ29tcGFyaXNvbignPicsIGd0LCBndENvbGxhdGUpO1xuZXhwb3J0IGNvbnN0IExlc3NUaGFuT3JFcXVhbDogJENhbGw8dHlwZW9mIG1ha2VDb21wYXJpc29uLCAnPD0nLCB0eXBlb2YgbHRlcSwgdHlwZW9mIGx0ZXFDb2xsYXRlPiA9IG1ha2VDb21wYXJpc29uKCc8PScsIGx0ZXEsIGx0ZXFDb2xsYXRlKTtcbmV4cG9ydCBjb25zdCBHcmVhdGVyVGhhbk9yRXF1YWw6ICRDYWxsPHR5cGVvZiBtYWtlQ29tcGFyaXNvbiwgJz49JywgdHlwZW9mIGd0ZXEsIHR5cGVvZiBndGVxQ29sbGF0ZT4gPSBtYWtlQ29tcGFyaXNvbignPj0nLCBndGVxLCBndGVxQ29sbGF0ZSk7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge1N0cmluZ1R5cGUsIE51bWJlclR5cGV9IGZyb20gJy4uL3R5cGVzLmpzJztcblxuaW1wb3J0IHR5cGUge0V4cHJlc3Npb24sIFNlcmlhbGl6ZWRFeHByZXNzaW9ufSBmcm9tICcuLi9leHByZXNzaW9uLmpzJztcbmltcG9ydCB0eXBlIEV2YWx1YXRpb25Db250ZXh0IGZyb20gJy4uL2V2YWx1YXRpb25fY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSBQYXJzaW5nQ29udGV4dCBmcm9tICcuLi9wYXJzaW5nX2NvbnRleHQuanMnO1xuaW1wb3J0IHR5cGUge1R5cGV9IGZyb20gJy4uL3R5cGVzLmpzJztcblxuZGVjbGFyZSB2YXIgSW50bDoge1xuICAgIE51bWJlckZvcm1hdDogQ2xhc3M8SW50bCROdW1iZXJGb3JtYXQ+XG59O1xuXG5kZWNsYXJlIGNsYXNzIEludGwkTnVtYmVyRm9ybWF0IHtcbiAgICBjb25zdHJ1Y3RvciAoXG4gICAgICAgIGxvY2FsZXM/OiBzdHJpbmcgfCBzdHJpbmdbXSxcbiAgICAgICAgb3B0aW9ucz86IE51bWJlckZvcm1hdE9wdGlvbnNcbiAgICApOiBJbnRsJE51bWJlckZvcm1hdDtcblxuICAgIHN0YXRpYyAoXG4gICAgICAgIGxvY2FsZXM/OiBzdHJpbmcgfCBzdHJpbmdbXSxcbiAgICAgICAgb3B0aW9ucz86IE51bWJlckZvcm1hdE9wdGlvbnNcbiAgICApOiBJbnRsJE51bWJlckZvcm1hdDtcblxuICAgIGZvcm1hdChhOiBudW1iZXIpOiBzdHJpbmc7XG5cbiAgICByZXNvbHZlZE9wdGlvbnMoKTogYW55O1xufVxuXG50eXBlIE51bWJlckZvcm1hdE9wdGlvbnMgPSB7XG4gICAgc3R5bGU/OiAnZGVjaW1hbCcgfCAnY3VycmVuY3knIHwgJ3BlcmNlbnQnIHwgJ3VuaXQnO1xuICAgIGN1cnJlbmN5PzogbnVsbCB8IHN0cmluZztcbiAgICB1bml0PzogbnVsbCB8IHN0cmluZztcbiAgICBtaW5pbXVtRnJhY3Rpb25EaWdpdHM/OiBudWxsIHwgc3RyaW5nO1xuICAgIG1heGltdW1GcmFjdGlvbkRpZ2l0cz86IG51bGwgfCBzdHJpbmc7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBOdW1iZXJGb3JtYXQgaW1wbGVtZW50cyBFeHByZXNzaW9uIHtcbiAgICB0eXBlOiBUeXBlO1xuICAgIG51bWJlcjogRXhwcmVzc2lvbjtcbiAgICBsb2NhbGU6IEV4cHJlc3Npb24gfCBudWxsOyAgIC8vIEJDUCA0NyBsYW5ndWFnZSB0YWdcbiAgICBjdXJyZW5jeTogRXhwcmVzc2lvbiB8IG51bGw7IC8vIElTTyA0MjE3IGN1cnJlbmN5IGNvZGUsIHJlcXVpcmVkIGlmIHN0eWxlPWN1cnJlbmN5XG4gICAgdW5pdDogRXhwcmVzc2lvbiB8IG51bGw7ICAgICAvLyBTaW1wbGUgdW5pdHMgc2FuY3Rpb25lZCBmb3IgdXNlIGluIEVDTUFTY3JpcHQsIHJlcXVpcmVkIGlmIHN0eWxlPXVuaXQuIGh0dHBzOi8vdGMzOS5lcy9wcm9wb3NhbC11bmlmaWVkLWludGwtbnVtYmVyZm9ybWF0L3NlY3Rpb242L2xvY2FsZXMtY3VycmVuY2llcy10el9wcm9wb3NlZF9vdXQuaHRtbCNzZWMtaXNzYW5jdGlvbmVkc2ltcGxldW5pdGlkZW50aWZpZXJcbiAgICBtaW5GcmFjdGlvbkRpZ2l0czogRXhwcmVzc2lvbiB8IG51bGw7IC8vIERlZmF1bHQgMFxuICAgIG1heEZyYWN0aW9uRGlnaXRzOiBFeHByZXNzaW9uIHwgbnVsbDsgLy8gRGVmYXVsdCAzXG5cbiAgICBjb25zdHJ1Y3RvcihudW1iZXI6IEV4cHJlc3Npb24sXG4gICAgICAgICAgICAgICAgbG9jYWxlOiBFeHByZXNzaW9uIHwgbnVsbCxcbiAgICAgICAgICAgICAgICBjdXJyZW5jeTogRXhwcmVzc2lvbiB8IG51bGwsXG4gICAgICAgICAgICAgICAgdW5pdDogRXhwcmVzc2lvbiB8IG51bGwsXG4gICAgICAgICAgICAgICAgbWluRnJhY3Rpb25EaWdpdHM6IEV4cHJlc3Npb24gfCBudWxsLFxuICAgICAgICAgICAgICAgIG1heEZyYWN0aW9uRGlnaXRzOiBFeHByZXNzaW9uIHwgbnVsbCkge1xuICAgICAgICB0aGlzLnR5cGUgPSBTdHJpbmdUeXBlO1xuICAgICAgICB0aGlzLm51bWJlciA9IG51bWJlcjtcbiAgICAgICAgdGhpcy5sb2NhbGUgPSBsb2NhbGU7XG4gICAgICAgIHRoaXMuY3VycmVuY3kgPSBjdXJyZW5jeTtcbiAgICAgICAgdGhpcy51bml0ID0gdW5pdDtcbiAgICAgICAgdGhpcy5taW5GcmFjdGlvbkRpZ2l0cyA9IG1pbkZyYWN0aW9uRGlnaXRzO1xuICAgICAgICB0aGlzLm1heEZyYWN0aW9uRGlnaXRzID0gbWF4RnJhY3Rpb25EaWdpdHM7XG4gICAgfVxuXG4gICAgc3RhdGljIHBhcnNlKGFyZ3M6ICRSZWFkT25seUFycmF5PG1peGVkPiwgY29udGV4dDogUGFyc2luZ0NvbnRleHQpOiA/RXhwcmVzc2lvbiB7XG4gICAgICAgIGlmIChhcmdzLmxlbmd0aCAhPT0gMylcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmVycm9yKGBFeHBlY3RlZCB0d28gYXJndW1lbnRzLmApO1xuXG4gICAgICAgIGNvbnN0IG51bWJlciA9IGNvbnRleHQucGFyc2UoYXJnc1sxXSwgMSwgTnVtYmVyVHlwZSk7XG4gICAgICAgIGlmICghbnVtYmVyKSByZXR1cm4gbnVsbDtcblxuICAgICAgICBjb25zdCBvcHRpb25zID0gKGFyZ3NbMl06IGFueSk7XG4gICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucyAhPT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KG9wdGlvbnMpKVxuICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQuZXJyb3IoYE51bWJlckZvcm1hdCBvcHRpb25zIGFyZ3VtZW50IG11c3QgYmUgYW4gb2JqZWN0LmApO1xuXG4gICAgICAgIGxldCBsb2NhbGUgPSBudWxsO1xuICAgICAgICBpZiAob3B0aW9uc1snbG9jYWxlJ10pIHtcbiAgICAgICAgICAgIGxvY2FsZSA9IGNvbnRleHQucGFyc2Uob3B0aW9uc1snbG9jYWxlJ10sIDEsIFN0cmluZ1R5cGUpO1xuICAgICAgICAgICAgaWYgKCFsb2NhbGUpIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGN1cnJlbmN5ID0gbnVsbDtcbiAgICAgICAgaWYgKG9wdGlvbnNbJ2N1cnJlbmN5J10pIHtcbiAgICAgICAgICAgIGN1cnJlbmN5ID0gY29udGV4dC5wYXJzZShvcHRpb25zWydjdXJyZW5jeSddLCAxLCBTdHJpbmdUeXBlKTtcbiAgICAgICAgICAgIGlmICghY3VycmVuY3kpIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHVuaXQgPSBudWxsO1xuICAgICAgICBpZiAob3B0aW9uc1sndW5pdCddKSB7XG4gICAgICAgICAgICB1bml0ID0gY29udGV4dC5wYXJzZShvcHRpb25zWyd1bml0J10sIDEsIFN0cmluZ1R5cGUpO1xuICAgICAgICAgICAgaWYgKCF1bml0KSByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBtaW5GcmFjdGlvbkRpZ2l0cyA9IG51bGw7XG4gICAgICAgIGlmIChvcHRpb25zWydtaW4tZnJhY3Rpb24tZGlnaXRzJ10pIHtcbiAgICAgICAgICAgIG1pbkZyYWN0aW9uRGlnaXRzID0gY29udGV4dC5wYXJzZShvcHRpb25zWydtaW4tZnJhY3Rpb24tZGlnaXRzJ10sIDEsIE51bWJlclR5cGUpO1xuICAgICAgICAgICAgaWYgKCFtaW5GcmFjdGlvbkRpZ2l0cykgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgbWF4RnJhY3Rpb25EaWdpdHMgPSBudWxsO1xuICAgICAgICBpZiAob3B0aW9uc1snbWF4LWZyYWN0aW9uLWRpZ2l0cyddKSB7XG4gICAgICAgICAgICBtYXhGcmFjdGlvbkRpZ2l0cyA9IGNvbnRleHQucGFyc2Uob3B0aW9uc1snbWF4LWZyYWN0aW9uLWRpZ2l0cyddLCAxLCBOdW1iZXJUeXBlKTtcbiAgICAgICAgICAgIGlmICghbWF4RnJhY3Rpb25EaWdpdHMpIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBOdW1iZXJGb3JtYXQobnVtYmVyLCBsb2NhbGUsIGN1cnJlbmN5LCB1bml0LCBtaW5GcmFjdGlvbkRpZ2l0cywgbWF4RnJhY3Rpb25EaWdpdHMpO1xuICAgIH1cblxuICAgIGV2YWx1YXRlKGN0eDogRXZhbHVhdGlvbkNvbnRleHQpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gbmV3IEludGwuTnVtYmVyRm9ybWF0KHRoaXMubG9jYWxlID8gdGhpcy5sb2NhbGUuZXZhbHVhdGUoY3R4KSA6IFtdLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHN0eWxlOlxuICAgICAgICAgICAgICAgICAgICAodGhpcy5jdXJyZW5jeSAmJiBcImN1cnJlbmN5XCIpIHx8XG4gICAgICAgICAgICAgICAgICAgICh0aGlzLnVuaXQgJiYgXCJ1bml0XCIpIHx8XG4gICAgICAgICAgICAgICAgICAgIFwiZGVjaW1hbFwiLFxuICAgICAgICAgICAgICAgIGN1cnJlbmN5OiB0aGlzLmN1cnJlbmN5ID8gdGhpcy5jdXJyZW5jeS5ldmFsdWF0ZShjdHgpIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIHVuaXQ6IHRoaXMudW5pdCA/IHRoaXMudW5pdC5ldmFsdWF0ZShjdHgpIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIG1pbmltdW1GcmFjdGlvbkRpZ2l0czogdGhpcy5taW5GcmFjdGlvbkRpZ2l0cyA/IHRoaXMubWluRnJhY3Rpb25EaWdpdHMuZXZhbHVhdGUoY3R4KSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBtYXhpbXVtRnJhY3Rpb25EaWdpdHM6IHRoaXMubWF4RnJhY3Rpb25EaWdpdHMgPyB0aGlzLm1heEZyYWN0aW9uRGlnaXRzLmV2YWx1YXRlKGN0eCkgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICB9KS5mb3JtYXQodGhpcy5udW1iZXIuZXZhbHVhdGUoY3R4KSk7XG4gICAgfVxuXG4gICAgZWFjaENoaWxkKGZuOiAoXzogRXhwcmVzc2lvbikgPT4gdm9pZCkge1xuICAgICAgICBmbih0aGlzLm51bWJlcik7XG4gICAgICAgIGlmICh0aGlzLmxvY2FsZSkge1xuICAgICAgICAgICAgZm4odGhpcy5sb2NhbGUpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbmN5KSB7XG4gICAgICAgICAgICBmbih0aGlzLmN1cnJlbmN5KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy51bml0KSB7XG4gICAgICAgICAgICBmbih0aGlzLnVuaXQpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLm1pbkZyYWN0aW9uRGlnaXRzKSB7XG4gICAgICAgICAgICBmbih0aGlzLm1pbkZyYWN0aW9uRGlnaXRzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5tYXhGcmFjdGlvbkRpZ2l0cykge1xuICAgICAgICAgICAgZm4odGhpcy5tYXhGcmFjdGlvbkRpZ2l0cyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvdXRwdXREZWZpbmVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgc2VyaWFsaXplKCk6IFNlcmlhbGl6ZWRFeHByZXNzaW9uIHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHt9O1xuICAgICAgICBpZiAodGhpcy5sb2NhbGUpIHtcbiAgICAgICAgICAgIG9wdGlvbnNbJ2xvY2FsZSddID0gdGhpcy5sb2NhbGUuc2VyaWFsaXplKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuY3VycmVuY3kpIHtcbiAgICAgICAgICAgIG9wdGlvbnNbJ2N1cnJlbmN5J10gPSB0aGlzLmN1cnJlbmN5LnNlcmlhbGl6ZSgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnVuaXQpIHtcbiAgICAgICAgICAgIG9wdGlvbnNbJ3VuaXQnXSA9IHRoaXMudW5pdC5zZXJpYWxpemUoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5taW5GcmFjdGlvbkRpZ2l0cykge1xuICAgICAgICAgICAgb3B0aW9uc1snbWluLWZyYWN0aW9uLWRpZ2l0cyddID0gdGhpcy5taW5GcmFjdGlvbkRpZ2l0cy5zZXJpYWxpemUoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5tYXhGcmFjdGlvbkRpZ2l0cykge1xuICAgICAgICAgICAgb3B0aW9uc1snbWF4LWZyYWN0aW9uLWRpZ2l0cyddID0gdGhpcy5tYXhGcmFjdGlvbkRpZ2l0cy5zZXJpYWxpemUoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW1wibnVtYmVyLWZvcm1hdFwiLCB0aGlzLm51bWJlci5zZXJpYWxpemUoKSwgb3B0aW9uc107XG4gICAgfVxufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtOdW1iZXJUeXBlLCB0b1N0cmluZ30gZnJvbSAnLi4vdHlwZXMuanMnO1xuXG5pbXBvcnQge3R5cGVPZn0gZnJvbSAnLi4vdmFsdWVzLmpzJztcbmltcG9ydCBSdW50aW1lRXJyb3IgZnJvbSAnLi4vcnVudGltZV9lcnJvci5qcyc7XG5cbmltcG9ydCB0eXBlIHtFeHByZXNzaW9uLCBTZXJpYWxpemVkRXhwcmVzc2lvbn0gZnJvbSAnLi4vZXhwcmVzc2lvbi5qcyc7XG5pbXBvcnQgdHlwZSBQYXJzaW5nQ29udGV4dCBmcm9tICcuLi9wYXJzaW5nX2NvbnRleHQuanMnO1xuaW1wb3J0IHR5cGUgRXZhbHVhdGlvbkNvbnRleHQgZnJvbSAnLi4vZXZhbHVhdGlvbl9jb250ZXh0LmpzJztcbmltcG9ydCB0eXBlIHtUeXBlfSBmcm9tICcuLi90eXBlcy5qcyc7XG5cbmNsYXNzIExlbmd0aCBpbXBsZW1lbnRzIEV4cHJlc3Npb24ge1xuICAgIHR5cGU6IFR5cGU7XG4gICAgaW5wdXQ6IEV4cHJlc3Npb247XG5cbiAgICBjb25zdHJ1Y3RvcihpbnB1dDogRXhwcmVzc2lvbikge1xuICAgICAgICB0aGlzLnR5cGUgPSBOdW1iZXJUeXBlO1xuICAgICAgICB0aGlzLmlucHV0ID0gaW5wdXQ7XG4gICAgfVxuXG4gICAgc3RhdGljIHBhcnNlKGFyZ3M6ICRSZWFkT25seUFycmF5PG1peGVkPiwgY29udGV4dDogUGFyc2luZ0NvbnRleHQpOiA/TGVuZ3RoIHtcbiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoICE9PSAyKVxuICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQuZXJyb3IoYEV4cGVjdGVkIDEgYXJndW1lbnQsIGJ1dCBmb3VuZCAke2FyZ3MubGVuZ3RoIC0gMX0gaW5zdGVhZC5gKTtcblxuICAgICAgICBjb25zdCBpbnB1dCA9IGNvbnRleHQucGFyc2UoYXJnc1sxXSwgMSk7XG4gICAgICAgIGlmICghaW5wdXQpIHJldHVybiBudWxsO1xuXG4gICAgICAgIGlmIChpbnB1dC50eXBlLmtpbmQgIT09ICdhcnJheScgJiYgaW5wdXQudHlwZS5raW5kICE9PSAnc3RyaW5nJyAmJiBpbnB1dC50eXBlLmtpbmQgIT09ICd2YWx1ZScpXG4gICAgICAgICAgICByZXR1cm4gY29udGV4dC5lcnJvcihgRXhwZWN0ZWQgYXJndW1lbnQgb2YgdHlwZSBzdHJpbmcgb3IgYXJyYXksIGJ1dCBmb3VuZCAke3RvU3RyaW5nKGlucHV0LnR5cGUpfSBpbnN0ZWFkLmApO1xuXG4gICAgICAgIHJldHVybiBuZXcgTGVuZ3RoKGlucHV0KTtcbiAgICB9XG5cbiAgICBldmFsdWF0ZShjdHg6IEV2YWx1YXRpb25Db250ZXh0KTogYW55IHwgbnVtYmVyIHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSB0aGlzLmlucHV0LmV2YWx1YXRlKGN0eCk7XG4gICAgICAgIGlmICh0eXBlb2YgaW5wdXQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICByZXR1cm4gaW5wdXQubGVuZ3RoO1xuICAgICAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoaW5wdXQpKSB7XG4gICAgICAgICAgICByZXR1cm4gaW5wdXQubGVuZ3RoO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcihgRXhwZWN0ZWQgdmFsdWUgdG8gYmUgb2YgdHlwZSBzdHJpbmcgb3IgYXJyYXksIGJ1dCBmb3VuZCAke3RvU3RyaW5nKHR5cGVPZihpbnB1dCkpfSBpbnN0ZWFkLmApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZWFjaENoaWxkKGZuOiAoXzogRXhwcmVzc2lvbikgPT4gdm9pZCkge1xuICAgICAgICBmbih0aGlzLmlucHV0KTtcbiAgICB9XG5cbiAgICBvdXRwdXREZWZpbmVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgc2VyaWFsaXplKCk6IFNlcmlhbGl6ZWRFeHByZXNzaW9uIHtcbiAgICAgICAgY29uc3Qgc2VyaWFsaXplZCA9IFtcImxlbmd0aFwiXTtcbiAgICAgICAgdGhpcy5lYWNoQ2hpbGQoY2hpbGQgPT4geyBzZXJpYWxpemVkLnB1c2goY2hpbGQuc2VyaWFsaXplKCkpOyB9KTtcbiAgICAgICAgcmV0dXJuIHNlcmlhbGl6ZWQ7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBMZW5ndGg7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge1xuICAgIHR5cGUgVHlwZSxcbiAgICBOdW1iZXJUeXBlLFxuICAgIFN0cmluZ1R5cGUsXG4gICAgQm9vbGVhblR5cGUsXG4gICAgQ29sb3JUeXBlLFxuICAgIE9iamVjdFR5cGUsXG4gICAgVmFsdWVUeXBlLFxuICAgIEVycm9yVHlwZSxcbiAgICBDb2xsYXRvclR5cGUsXG4gICAgYXJyYXksXG4gICAgdG9TdHJpbmcgYXMgdHlwZVRvU3RyaW5nXG59IGZyb20gJy4uL3R5cGVzLmpzJztcblxuaW1wb3J0IHt0eXBlT2YsIENvbG9yLCB2YWxpZGF0ZVJHQkEsIHRvU3RyaW5nIGFzIHZhbHVlVG9TdHJpbmd9IGZyb20gJy4uL3ZhbHVlcy5qcyc7XG5pbXBvcnQgQ29tcG91bmRFeHByZXNzaW9uIGZyb20gJy4uL2NvbXBvdW5kX2V4cHJlc3Npb24uanMnO1xuaW1wb3J0IFJ1bnRpbWVFcnJvciBmcm9tICcuLi9ydW50aW1lX2Vycm9yLmpzJztcbmltcG9ydCBMZXQgZnJvbSAnLi9sZXQuanMnO1xuaW1wb3J0IFZhciBmcm9tICcuL3Zhci5qcyc7XG5pbXBvcnQgTGl0ZXJhbCBmcm9tICcuL2xpdGVyYWwuanMnO1xuaW1wb3J0IEFzc2VydGlvbiBmcm9tICcuL2Fzc2VydGlvbi5qcyc7XG5pbXBvcnQgQ29lcmNpb24gZnJvbSAnLi9jb2VyY2lvbi5qcyc7XG5pbXBvcnQgQXQgZnJvbSAnLi9hdC5qcyc7XG5pbXBvcnQgSW4gZnJvbSAnLi9pbi5qcyc7XG5pbXBvcnQgSW5kZXhPZiBmcm9tICcuL2luZGV4X29mLmpzJztcbmltcG9ydCBNYXRjaCBmcm9tICcuL21hdGNoLmpzJztcbmltcG9ydCBDYXNlIGZyb20gJy4vY2FzZS5qcyc7XG5pbXBvcnQgU2xpY2UgZnJvbSAnLi9zbGljZS5qcyc7XG5pbXBvcnQgU3RlcCBmcm9tICcuL3N0ZXAuanMnO1xuaW1wb3J0IEludGVycG9sYXRlIGZyb20gJy4vaW50ZXJwb2xhdGUuanMnO1xuaW1wb3J0IENvYWxlc2NlIGZyb20gJy4vY29hbGVzY2UuanMnO1xuaW1wb3J0IHtcbiAgICBFcXVhbHMsXG4gICAgTm90RXF1YWxzLFxuICAgIExlc3NUaGFuLFxuICAgIEdyZWF0ZXJUaGFuLFxuICAgIExlc3NUaGFuT3JFcXVhbCxcbiAgICBHcmVhdGVyVGhhbk9yRXF1YWxcbn0gZnJvbSAnLi9jb21wYXJpc29uLmpzJztcbmltcG9ydCBDb2xsYXRvckV4cHJlc3Npb24gZnJvbSAnLi9jb2xsYXRvci5qcyc7XG5pbXBvcnQgTnVtYmVyRm9ybWF0IGZyb20gJy4vbnVtYmVyX2Zvcm1hdC5qcyc7XG5pbXBvcnQgRm9ybWF0RXhwcmVzc2lvbiBmcm9tICcuL2Zvcm1hdC5qcyc7XG5pbXBvcnQgSW1hZ2VFeHByZXNzaW9uIGZyb20gJy4vaW1hZ2UuanMnO1xuaW1wb3J0IExlbmd0aCBmcm9tICcuL2xlbmd0aC5qcyc7XG5pbXBvcnQgV2l0aGluIGZyb20gJy4vd2l0aGluLmpzJztcblxuaW1wb3J0IHR5cGUgRXZhbHVhdGlvbkNvbnRleHQgZnJvbSAnLi4vZXZhbHVhdGlvbl9jb250ZXh0LmpzJztcbmltcG9ydCB0eXBlIHtWYXJhcmdzfSBmcm9tICcuLi9jb21wb3VuZF9leHByZXNzaW9uLmpzJztcbmltcG9ydCB0eXBlIHtFeHByZXNzaW9uLCBFeHByZXNzaW9uUmVnaXN0cnl9IGZyb20gJy4uL2V4cHJlc3Npb24uanMnO1xuXG5jb25zdCBleHByZXNzaW9uczogRXhwcmVzc2lvblJlZ2lzdHJ5ID0ge1xuICAgIC8vIHNwZWNpYWwgZm9ybXNcbiAgICAnPT0nOiBFcXVhbHMsXG4gICAgJyE9JzogTm90RXF1YWxzLFxuICAgICc+JzogR3JlYXRlclRoYW4sXG4gICAgJzwnOiBMZXNzVGhhbixcbiAgICAnPj0nOiBHcmVhdGVyVGhhbk9yRXF1YWwsXG4gICAgJzw9JzogTGVzc1RoYW5PckVxdWFsLFxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAnYXJyYXknOiBBc3NlcnRpb24sXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICdhdCc6IEF0LFxuICAgICdib29sZWFuJzogQXNzZXJ0aW9uLFxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAnY2FzZSc6IENhc2UsXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICdjb2FsZXNjZSc6IENvYWxlc2NlLFxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAnY29sbGF0b3InOiBDb2xsYXRvckV4cHJlc3Npb24sXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICdmb3JtYXQnOiBGb3JtYXRFeHByZXNzaW9uLFxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAnaW1hZ2UnOiBJbWFnZUV4cHJlc3Npb24sXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICdpbic6IEluLFxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAnaW5kZXgtb2YnOiBJbmRleE9mLFxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAnaW50ZXJwb2xhdGUnOiBJbnRlcnBvbGF0ZSxcbiAgICAnaW50ZXJwb2xhdGUtaGNsJzogSW50ZXJwb2xhdGUsXG4gICAgJ2ludGVycG9sYXRlLWxhYic6IEludGVycG9sYXRlLFxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAnbGVuZ3RoJzogTGVuZ3RoLFxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAnbGV0JzogTGV0LFxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAnbGl0ZXJhbCc6IExpdGVyYWwsXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICdtYXRjaCc6IE1hdGNoLFxuICAgICdudW1iZXInOiBBc3NlcnRpb24sXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICdudW1iZXItZm9ybWF0JzogTnVtYmVyRm9ybWF0LFxuICAgICdvYmplY3QnOiBBc3NlcnRpb24sXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICdzbGljZSc6IFNsaWNlLFxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAnc3RlcCc6IFN0ZXAsXG4gICAgJ3N0cmluZyc6IEFzc2VydGlvbixcbiAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgJ3RvLWJvb2xlYW4nOiBDb2VyY2lvbixcbiAgICAndG8tY29sb3InOiBDb2VyY2lvbixcbiAgICAndG8tbnVtYmVyJzogQ29lcmNpb24sXG4gICAgJ3RvLXN0cmluZyc6IENvZXJjaW9uLFxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAndmFyJzogVmFyLFxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAnd2l0aGluJzogV2l0aGluXG59O1xuXG5mdW5jdGlvbiByZ2JhKGN0eDogRXZhbHVhdGlvbkNvbnRleHQsIFtyLCBnLCBiLCBhXTogQXJyYXk8RXhwcmVzc2lvbj4pIHtcbiAgICByID0gci5ldmFsdWF0ZShjdHgpO1xuICAgIGcgPSBnLmV2YWx1YXRlKGN0eCk7XG4gICAgYiA9IGIuZXZhbHVhdGUoY3R4KTtcbiAgICBjb25zdCBhbHBoYSA9IGEgPyBhLmV2YWx1YXRlKGN0eCkgOiAxO1xuICAgIGNvbnN0IGVycm9yID0gdmFsaWRhdGVSR0JBKHIsIGcsIGIsIGFscGhhKTtcbiAgICBpZiAoZXJyb3IpIHRocm93IG5ldyBSdW50aW1lRXJyb3IoZXJyb3IpO1xuICAgIHJldHVybiBuZXcgQ29sb3IociAvIDI1NSAqIGFscGhhLCBnIC8gMjU1ICogYWxwaGEsIGIgLyAyNTUgKiBhbHBoYSwgYWxwaGEpO1xufVxuXG5mdW5jdGlvbiBoYXMoa2V5OiBzdHJpbmcsIG9iajoge1tzdHJpbmddOiBhbnl9KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGtleSBpbiBvYmo7XG59XG5cbmZ1bmN0aW9uIGdldChrZXk6IHN0cmluZywgb2JqOiB7W3N0cmluZ106IGFueX0pIHtcbiAgICBjb25zdCB2ID0gb2JqW2tleV07XG4gICAgcmV0dXJuIHR5cGVvZiB2ID09PSAndW5kZWZpbmVkJyA/IG51bGwgOiB2O1xufVxuXG5mdW5jdGlvbiBiaW5hcnlTZWFyY2godjogYW55LCBhOiB7W251bWJlcl06IGFueX0sIGk6IG51bWJlciwgajogbnVtYmVyKSB7XG4gICAgd2hpbGUgKGkgPD0gaikge1xuICAgICAgICBjb25zdCBtID0gKGkgKyBqKSA+PiAxO1xuICAgICAgICBpZiAoYVttXSA9PT0gdilcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICBpZiAoYVttXSA+IHYpXG4gICAgICAgICAgICBqID0gbSAtIDE7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIGkgPSBtICsgMTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiB2YXJhcmdzKHR5cGU6IFR5cGUpOiBWYXJhcmdzIHtcbiAgICByZXR1cm4ge3R5cGV9O1xufVxuXG5Db21wb3VuZEV4cHJlc3Npb24ucmVnaXN0ZXIoZXhwcmVzc2lvbnMsIHtcbiAgICAnZXJyb3InOiBbXG4gICAgICAgIEVycm9yVHlwZSxcbiAgICAgICAgW1N0cmluZ1R5cGVdLFxuICAgICAgICAoY3R4LCBbdl0pID0+IHsgdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcih2LmV2YWx1YXRlKGN0eCkpOyB9XG4gICAgXSxcbiAgICAndHlwZW9mJzogW1xuICAgICAgICBTdHJpbmdUeXBlLFxuICAgICAgICBbVmFsdWVUeXBlXSxcbiAgICAgICAgKGN0eCwgW3ZdKSA9PiB0eXBlVG9TdHJpbmcodHlwZU9mKHYuZXZhbHVhdGUoY3R4KSkpXG4gICAgXSxcbiAgICAndG8tcmdiYSc6IFtcbiAgICAgICAgYXJyYXkoTnVtYmVyVHlwZSwgNCksXG4gICAgICAgIFtDb2xvclR5cGVdLFxuICAgICAgICAoY3R4LCBbdl0pID0+IHtcbiAgICAgICAgICAgIHJldHVybiB2LmV2YWx1YXRlKGN0eCkudG9BcnJheSgpO1xuICAgICAgICB9XG4gICAgXSxcbiAgICAncmdiJzogW1xuICAgICAgICBDb2xvclR5cGUsXG4gICAgICAgIFtOdW1iZXJUeXBlLCBOdW1iZXJUeXBlLCBOdW1iZXJUeXBlXSxcbiAgICAgICAgcmdiYVxuICAgIF0sXG4gICAgJ3JnYmEnOiBbXG4gICAgICAgIENvbG9yVHlwZSxcbiAgICAgICAgW051bWJlclR5cGUsIE51bWJlclR5cGUsIE51bWJlclR5cGUsIE51bWJlclR5cGVdLFxuICAgICAgICByZ2JhXG4gICAgXSxcbiAgICAnaGFzJzoge1xuICAgICAgICB0eXBlOiBCb29sZWFuVHlwZSxcbiAgICAgICAgb3ZlcmxvYWRzOiBbXG4gICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgW1N0cmluZ1R5cGVdLFxuICAgICAgICAgICAgICAgIChjdHgsIFtrZXldKSA9PiBoYXMoa2V5LmV2YWx1YXRlKGN0eCksIGN0eC5wcm9wZXJ0aWVzKCkpXG4gICAgICAgICAgICBdLCBbXG4gICAgICAgICAgICAgICAgW1N0cmluZ1R5cGUsIE9iamVjdFR5cGVdLFxuICAgICAgICAgICAgICAgIChjdHgsIFtrZXksIG9ial0pID0+IGhhcyhrZXkuZXZhbHVhdGUoY3R4KSwgb2JqLmV2YWx1YXRlKGN0eCkpXG4gICAgICAgICAgICBdXG4gICAgICAgIF1cbiAgICB9LFxuICAgICdnZXQnOiB7XG4gICAgICAgIHR5cGU6IFZhbHVlVHlwZSxcbiAgICAgICAgb3ZlcmxvYWRzOiBbXG4gICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgW1N0cmluZ1R5cGVdLFxuICAgICAgICAgICAgICAgIChjdHgsIFtrZXldKSA9PiBnZXQoa2V5LmV2YWx1YXRlKGN0eCksIGN0eC5wcm9wZXJ0aWVzKCkpXG4gICAgICAgICAgICBdLCBbXG4gICAgICAgICAgICAgICAgW1N0cmluZ1R5cGUsIE9iamVjdFR5cGVdLFxuICAgICAgICAgICAgICAgIChjdHgsIFtrZXksIG9ial0pID0+IGdldChrZXkuZXZhbHVhdGUoY3R4KSwgb2JqLmV2YWx1YXRlKGN0eCkpXG4gICAgICAgICAgICBdXG4gICAgICAgIF1cbiAgICB9LFxuICAgICdmZWF0dXJlLXN0YXRlJzogW1xuICAgICAgICBWYWx1ZVR5cGUsXG4gICAgICAgIFtTdHJpbmdUeXBlXSxcbiAgICAgICAgKGN0eCwgW2tleV0pID0+IGdldChrZXkuZXZhbHVhdGUoY3R4KSwgY3R4LmZlYXR1cmVTdGF0ZSB8fCB7fSlcbiAgICBdLFxuICAgICdwcm9wZXJ0aWVzJzogW1xuICAgICAgICBPYmplY3RUeXBlLFxuICAgICAgICBbXSxcbiAgICAgICAgKGN0eCkgPT4gY3R4LnByb3BlcnRpZXMoKVxuICAgIF0sXG4gICAgJ2dlb21ldHJ5LXR5cGUnOiBbXG4gICAgICAgIFN0cmluZ1R5cGUsXG4gICAgICAgIFtdLFxuICAgICAgICAoY3R4KSA9PiBjdHguZ2VvbWV0cnlUeXBlKClcbiAgICBdLFxuICAgICdpZCc6IFtcbiAgICAgICAgVmFsdWVUeXBlLFxuICAgICAgICBbXSxcbiAgICAgICAgKGN0eCkgPT4gY3R4LmlkKClcbiAgICBdLFxuICAgICd6b29tJzogW1xuICAgICAgICBOdW1iZXJUeXBlLFxuICAgICAgICBbXSxcbiAgICAgICAgKGN0eCkgPT4gY3R4Lmdsb2JhbHMuem9vbVxuICAgIF0sXG4gICAgJ3BpdGNoJzogW1xuICAgICAgICBOdW1iZXJUeXBlLFxuICAgICAgICBbXSxcbiAgICAgICAgKGN0eCkgPT4gY3R4Lmdsb2JhbHMucGl0Y2ggfHwgMFxuICAgIF0sXG4gICAgJ2Rpc3RhbmNlLWZyb20tY2VudGVyJzogW1xuICAgICAgICBOdW1iZXJUeXBlLFxuICAgICAgICBbXSxcbiAgICAgICAgKGN0eCkgPT4gY3R4LmRpc3RhbmNlRnJvbUNlbnRlcigpXG4gICAgXSxcbiAgICAnaGVhdG1hcC1kZW5zaXR5JzogW1xuICAgICAgICBOdW1iZXJUeXBlLFxuICAgICAgICBbXSxcbiAgICAgICAgKGN0eCkgPT4gY3R4Lmdsb2JhbHMuaGVhdG1hcERlbnNpdHkgfHwgMFxuICAgIF0sXG4gICAgJ2xpbmUtcHJvZ3Jlc3MnOiBbXG4gICAgICAgIE51bWJlclR5cGUsXG4gICAgICAgIFtdLFxuICAgICAgICAoY3R4KSA9PiBjdHguZ2xvYmFscy5saW5lUHJvZ3Jlc3MgfHwgMFxuICAgIF0sXG4gICAgJ3NreS1yYWRpYWwtcHJvZ3Jlc3MnOiBbXG4gICAgICAgIE51bWJlclR5cGUsXG4gICAgICAgIFtdLFxuICAgICAgICAoY3R4KSA9PiBjdHguZ2xvYmFscy5za3lSYWRpYWxQcm9ncmVzcyB8fCAwXG4gICAgXSxcbiAgICAnYWNjdW11bGF0ZWQnOiBbXG4gICAgICAgIFZhbHVlVHlwZSxcbiAgICAgICAgW10sXG4gICAgICAgIChjdHgpID0+IGN0eC5nbG9iYWxzLmFjY3VtdWxhdGVkID09PSB1bmRlZmluZWQgPyBudWxsIDogY3R4Lmdsb2JhbHMuYWNjdW11bGF0ZWRcbiAgICBdLFxuICAgICcrJzogW1xuICAgICAgICBOdW1iZXJUeXBlLFxuICAgICAgICB2YXJhcmdzKE51bWJlclR5cGUpLFxuICAgICAgICAoY3R4LCBhcmdzKSA9PiB7XG4gICAgICAgICAgICBsZXQgcmVzdWx0ID0gMDtcbiAgICAgICAgICAgIGZvciAoY29uc3QgYXJnIG9mIGFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgKz0gYXJnLmV2YWx1YXRlKGN0eCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgXSxcbiAgICAnKic6IFtcbiAgICAgICAgTnVtYmVyVHlwZSxcbiAgICAgICAgdmFyYXJncyhOdW1iZXJUeXBlKSxcbiAgICAgICAgKGN0eCwgYXJncykgPT4ge1xuICAgICAgICAgICAgbGV0IHJlc3VsdCA9IDE7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGFyZyBvZiBhcmdzKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ICo9IGFyZy5ldmFsdWF0ZShjdHgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuICAgIF0sXG4gICAgJy0nOiB7XG4gICAgICAgIHR5cGU6IE51bWJlclR5cGUsXG4gICAgICAgIG92ZXJsb2FkczogW1xuICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgIFtOdW1iZXJUeXBlLCBOdW1iZXJUeXBlXSxcbiAgICAgICAgICAgICAgICAoY3R4LCBbYSwgYl0pID0+IGEuZXZhbHVhdGUoY3R4KSAtIGIuZXZhbHVhdGUoY3R4KVxuICAgICAgICAgICAgXSwgW1xuICAgICAgICAgICAgICAgIFtOdW1iZXJUeXBlXSxcbiAgICAgICAgICAgICAgICAoY3R4LCBbYV0pID0+IC1hLmV2YWx1YXRlKGN0eClcbiAgICAgICAgICAgIF1cbiAgICAgICAgXVxuICAgIH0sXG4gICAgJy8nOiBbXG4gICAgICAgIE51bWJlclR5cGUsXG4gICAgICAgIFtOdW1iZXJUeXBlLCBOdW1iZXJUeXBlXSxcbiAgICAgICAgKGN0eCwgW2EsIGJdKSA9PiBhLmV2YWx1YXRlKGN0eCkgLyBiLmV2YWx1YXRlKGN0eClcbiAgICBdLFxuICAgICclJzogW1xuICAgICAgICBOdW1iZXJUeXBlLFxuICAgICAgICBbTnVtYmVyVHlwZSwgTnVtYmVyVHlwZV0sXG4gICAgICAgIChjdHgsIFthLCBiXSkgPT4gYS5ldmFsdWF0ZShjdHgpICUgYi5ldmFsdWF0ZShjdHgpXG4gICAgXSxcbiAgICAnbG4yJzogW1xuICAgICAgICBOdW1iZXJUeXBlLFxuICAgICAgICBbXSxcbiAgICAgICAgKCkgPT4gTWF0aC5MTjJcbiAgICBdLFxuICAgICdwaSc6IFtcbiAgICAgICAgTnVtYmVyVHlwZSxcbiAgICAgICAgW10sXG4gICAgICAgICgpID0+IE1hdGguUElcbiAgICBdLFxuICAgICdlJzogW1xuICAgICAgICBOdW1iZXJUeXBlLFxuICAgICAgICBbXSxcbiAgICAgICAgKCkgPT4gTWF0aC5FXG4gICAgXSxcbiAgICAnXic6IFtcbiAgICAgICAgTnVtYmVyVHlwZSxcbiAgICAgICAgW051bWJlclR5cGUsIE51bWJlclR5cGVdLFxuICAgICAgICAoY3R4LCBbYiwgZV0pID0+IE1hdGgucG93KGIuZXZhbHVhdGUoY3R4KSwgZS5ldmFsdWF0ZShjdHgpKVxuICAgIF0sXG4gICAgJ3NxcnQnOiBbXG4gICAgICAgIE51bWJlclR5cGUsXG4gICAgICAgIFtOdW1iZXJUeXBlXSxcbiAgICAgICAgKGN0eCwgW3hdKSA9PiBNYXRoLnNxcnQoeC5ldmFsdWF0ZShjdHgpKVxuICAgIF0sXG4gICAgJ2xvZzEwJzogW1xuICAgICAgICBOdW1iZXJUeXBlLFxuICAgICAgICBbTnVtYmVyVHlwZV0sXG4gICAgICAgIChjdHgsIFtuXSkgPT4gTWF0aC5sb2cobi5ldmFsdWF0ZShjdHgpKSAvIE1hdGguTE4xMFxuICAgIF0sXG4gICAgJ2xuJzogW1xuICAgICAgICBOdW1iZXJUeXBlLFxuICAgICAgICBbTnVtYmVyVHlwZV0sXG4gICAgICAgIChjdHgsIFtuXSkgPT4gTWF0aC5sb2cobi5ldmFsdWF0ZShjdHgpKVxuICAgIF0sXG4gICAgJ2xvZzInOiBbXG4gICAgICAgIE51bWJlclR5cGUsXG4gICAgICAgIFtOdW1iZXJUeXBlXSxcbiAgICAgICAgKGN0eCwgW25dKSA9PiBNYXRoLmxvZyhuLmV2YWx1YXRlKGN0eCkpIC8gTWF0aC5MTjJcbiAgICBdLFxuICAgICdzaW4nOiBbXG4gICAgICAgIE51bWJlclR5cGUsXG4gICAgICAgIFtOdW1iZXJUeXBlXSxcbiAgICAgICAgKGN0eCwgW25dKSA9PiBNYXRoLnNpbihuLmV2YWx1YXRlKGN0eCkpXG4gICAgXSxcbiAgICAnY29zJzogW1xuICAgICAgICBOdW1iZXJUeXBlLFxuICAgICAgICBbTnVtYmVyVHlwZV0sXG4gICAgICAgIChjdHgsIFtuXSkgPT4gTWF0aC5jb3Mobi5ldmFsdWF0ZShjdHgpKVxuICAgIF0sXG4gICAgJ3Rhbic6IFtcbiAgICAgICAgTnVtYmVyVHlwZSxcbiAgICAgICAgW051bWJlclR5cGVdLFxuICAgICAgICAoY3R4LCBbbl0pID0+IE1hdGgudGFuKG4uZXZhbHVhdGUoY3R4KSlcbiAgICBdLFxuICAgICdhc2luJzogW1xuICAgICAgICBOdW1iZXJUeXBlLFxuICAgICAgICBbTnVtYmVyVHlwZV0sXG4gICAgICAgIChjdHgsIFtuXSkgPT4gTWF0aC5hc2luKG4uZXZhbHVhdGUoY3R4KSlcbiAgICBdLFxuICAgICdhY29zJzogW1xuICAgICAgICBOdW1iZXJUeXBlLFxuICAgICAgICBbTnVtYmVyVHlwZV0sXG4gICAgICAgIChjdHgsIFtuXSkgPT4gTWF0aC5hY29zKG4uZXZhbHVhdGUoY3R4KSlcbiAgICBdLFxuICAgICdhdGFuJzogW1xuICAgICAgICBOdW1iZXJUeXBlLFxuICAgICAgICBbTnVtYmVyVHlwZV0sXG4gICAgICAgIChjdHgsIFtuXSkgPT4gTWF0aC5hdGFuKG4uZXZhbHVhdGUoY3R4KSlcbiAgICBdLFxuICAgICdtaW4nOiBbXG4gICAgICAgIE51bWJlclR5cGUsXG4gICAgICAgIHZhcmFyZ3MoTnVtYmVyVHlwZSksXG4gICAgICAgIChjdHgsIGFyZ3MpID0+IE1hdGgubWluKC4uLmFyZ3MubWFwKGFyZyA9PiBhcmcuZXZhbHVhdGUoY3R4KSkpXG4gICAgXSxcbiAgICAnbWF4JzogW1xuICAgICAgICBOdW1iZXJUeXBlLFxuICAgICAgICB2YXJhcmdzKE51bWJlclR5cGUpLFxuICAgICAgICAoY3R4LCBhcmdzKSA9PiBNYXRoLm1heCguLi5hcmdzLm1hcChhcmcgPT4gYXJnLmV2YWx1YXRlKGN0eCkpKVxuICAgIF0sXG4gICAgJ2Ficyc6IFtcbiAgICAgICAgTnVtYmVyVHlwZSxcbiAgICAgICAgW051bWJlclR5cGVdLFxuICAgICAgICAoY3R4LCBbbl0pID0+IE1hdGguYWJzKG4uZXZhbHVhdGUoY3R4KSlcbiAgICBdLFxuICAgICdyb3VuZCc6IFtcbiAgICAgICAgTnVtYmVyVHlwZSxcbiAgICAgICAgW051bWJlclR5cGVdLFxuICAgICAgICAoY3R4LCBbbl0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHYgPSBuLmV2YWx1YXRlKGN0eCk7XG4gICAgICAgICAgICAvLyBKYXZhc2NyaXB0J3MgTWF0aC5yb3VuZCgpIHJvdW5kcyB0b3dhcmRzICtJbmZpbml0eSBmb3IgaGFsZndheVxuICAgICAgICAgICAgLy8gdmFsdWVzLCBldmVuIHdoZW4gdGhleSdyZSBuZWdhdGl2ZS4gSXQncyBtb3JlIGNvbW1vbiB0byByb3VuZFxuICAgICAgICAgICAgLy8gYXdheSBmcm9tIDAgKGUuZy4sIHRoaXMgaXMgd2hhdCBweXRob24gYW5kIEMrKyBkbylcbiAgICAgICAgICAgIHJldHVybiB2IDwgMCA/IC1NYXRoLnJvdW5kKC12KSA6IE1hdGgucm91bmQodik7XG4gICAgICAgIH1cbiAgICBdLFxuICAgICdmbG9vcic6IFtcbiAgICAgICAgTnVtYmVyVHlwZSxcbiAgICAgICAgW051bWJlclR5cGVdLFxuICAgICAgICAoY3R4LCBbbl0pID0+IE1hdGguZmxvb3Iobi5ldmFsdWF0ZShjdHgpKVxuICAgIF0sXG4gICAgJ2NlaWwnOiBbXG4gICAgICAgIE51bWJlclR5cGUsXG4gICAgICAgIFtOdW1iZXJUeXBlXSxcbiAgICAgICAgKGN0eCwgW25dKSA9PiBNYXRoLmNlaWwobi5ldmFsdWF0ZShjdHgpKVxuICAgIF0sXG4gICAgJ2ZpbHRlci09PSc6IFtcbiAgICAgICAgQm9vbGVhblR5cGUsXG4gICAgICAgIFtTdHJpbmdUeXBlLCBWYWx1ZVR5cGVdLFxuICAgICAgICAoY3R4LCBbaywgdl0pID0+IGN0eC5wcm9wZXJ0aWVzKClbKGs6IGFueSkudmFsdWVdID09PSAodjogYW55KS52YWx1ZVxuICAgIF0sXG4gICAgJ2ZpbHRlci1pZC09PSc6IFtcbiAgICAgICAgQm9vbGVhblR5cGUsXG4gICAgICAgIFtWYWx1ZVR5cGVdLFxuICAgICAgICAoY3R4LCBbdl0pID0+IGN0eC5pZCgpID09PSAodjogYW55KS52YWx1ZVxuICAgIF0sXG4gICAgJ2ZpbHRlci10eXBlLT09JzogW1xuICAgICAgICBCb29sZWFuVHlwZSxcbiAgICAgICAgW1N0cmluZ1R5cGVdLFxuICAgICAgICAoY3R4LCBbdl0pID0+IGN0eC5nZW9tZXRyeVR5cGUoKSA9PT0gKHY6IGFueSkudmFsdWVcbiAgICBdLFxuICAgICdmaWx0ZXItPCc6IFtcbiAgICAgICAgQm9vbGVhblR5cGUsXG4gICAgICAgIFtTdHJpbmdUeXBlLCBWYWx1ZVR5cGVdLFxuICAgICAgICAoY3R4LCBbaywgdl0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGEgPSBjdHgucHJvcGVydGllcygpWyhrOiBhbnkpLnZhbHVlXTtcbiAgICAgICAgICAgIGNvbnN0IGIgPSAodjogYW55KS52YWx1ZTtcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgYSA9PT0gdHlwZW9mIGIgJiYgYSA8IGI7XG4gICAgICAgIH1cbiAgICBdLFxuICAgICdmaWx0ZXItaWQtPCc6IFtcbiAgICAgICAgQm9vbGVhblR5cGUsXG4gICAgICAgIFtWYWx1ZVR5cGVdLFxuICAgICAgICAoY3R4LCBbdl0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGEgPSBjdHguaWQoKTtcbiAgICAgICAgICAgIGNvbnN0IGIgPSAodjogYW55KS52YWx1ZTtcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgYSA9PT0gdHlwZW9mIGIgJiYgYSA8IGI7XG4gICAgICAgIH1cbiAgICBdLFxuICAgICdmaWx0ZXItPic6IFtcbiAgICAgICAgQm9vbGVhblR5cGUsXG4gICAgICAgIFtTdHJpbmdUeXBlLCBWYWx1ZVR5cGVdLFxuICAgICAgICAoY3R4LCBbaywgdl0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGEgPSBjdHgucHJvcGVydGllcygpWyhrOiBhbnkpLnZhbHVlXTtcbiAgICAgICAgICAgIGNvbnN0IGIgPSAodjogYW55KS52YWx1ZTtcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgYSA9PT0gdHlwZW9mIGIgJiYgYSA+IGI7XG4gICAgICAgIH1cbiAgICBdLFxuICAgICdmaWx0ZXItaWQtPic6IFtcbiAgICAgICAgQm9vbGVhblR5cGUsXG4gICAgICAgIFtWYWx1ZVR5cGVdLFxuICAgICAgICAoY3R4LCBbdl0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGEgPSBjdHguaWQoKTtcbiAgICAgICAgICAgIGNvbnN0IGIgPSAodjogYW55KS52YWx1ZTtcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgYSA9PT0gdHlwZW9mIGIgJiYgYSA+IGI7XG4gICAgICAgIH1cbiAgICBdLFxuICAgICdmaWx0ZXItPD0nOiBbXG4gICAgICAgIEJvb2xlYW5UeXBlLFxuICAgICAgICBbU3RyaW5nVHlwZSwgVmFsdWVUeXBlXSxcbiAgICAgICAgKGN0eCwgW2ssIHZdKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhID0gY3R4LnByb3BlcnRpZXMoKVsoazogYW55KS52YWx1ZV07XG4gICAgICAgICAgICBjb25zdCBiID0gKHY6IGFueSkudmFsdWU7XG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIGEgPT09IHR5cGVvZiBiICYmIGEgPD0gYjtcbiAgICAgICAgfVxuICAgIF0sXG4gICAgJ2ZpbHRlci1pZC08PSc6IFtcbiAgICAgICAgQm9vbGVhblR5cGUsXG4gICAgICAgIFtWYWx1ZVR5cGVdLFxuICAgICAgICAoY3R4LCBbdl0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGEgPSBjdHguaWQoKTtcbiAgICAgICAgICAgIGNvbnN0IGIgPSAodjogYW55KS52YWx1ZTtcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgYSA9PT0gdHlwZW9mIGIgJiYgYSA8PSBiO1xuICAgICAgICB9XG4gICAgXSxcbiAgICAnZmlsdGVyLT49JzogW1xuICAgICAgICBCb29sZWFuVHlwZSxcbiAgICAgICAgW1N0cmluZ1R5cGUsIFZhbHVlVHlwZV0sXG4gICAgICAgIChjdHgsIFtrLCB2XSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYSA9IGN0eC5wcm9wZXJ0aWVzKClbKGs6IGFueSkudmFsdWVdO1xuICAgICAgICAgICAgY29uc3QgYiA9ICh2OiBhbnkpLnZhbHVlO1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiBhID09PSB0eXBlb2YgYiAmJiBhID49IGI7XG4gICAgICAgIH1cbiAgICBdLFxuICAgICdmaWx0ZXItaWQtPj0nOiBbXG4gICAgICAgIEJvb2xlYW5UeXBlLFxuICAgICAgICBbVmFsdWVUeXBlXSxcbiAgICAgICAgKGN0eCwgW3ZdKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhID0gY3R4LmlkKCk7XG4gICAgICAgICAgICBjb25zdCBiID0gKHY6IGFueSkudmFsdWU7XG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIGEgPT09IHR5cGVvZiBiICYmIGEgPj0gYjtcbiAgICAgICAgfVxuICAgIF0sXG4gICAgJ2ZpbHRlci1oYXMnOiBbXG4gICAgICAgIEJvb2xlYW5UeXBlLFxuICAgICAgICBbVmFsdWVUeXBlXSxcbiAgICAgICAgKGN0eCwgW2tdKSA9PiAoazogYW55KS52YWx1ZSBpbiBjdHgucHJvcGVydGllcygpXG4gICAgXSxcbiAgICAnZmlsdGVyLWhhcy1pZCc6IFtcbiAgICAgICAgQm9vbGVhblR5cGUsXG4gICAgICAgIFtdLFxuICAgICAgICAoY3R4KSA9PiAoY3R4LmlkKCkgIT09IG51bGwgJiYgY3R4LmlkKCkgIT09IHVuZGVmaW5lZClcbiAgICBdLFxuICAgICdmaWx0ZXItdHlwZS1pbic6IFtcbiAgICAgICAgQm9vbGVhblR5cGUsXG4gICAgICAgIFthcnJheShTdHJpbmdUeXBlKV0sXG4gICAgICAgIChjdHgsIFt2XSkgPT4gKHY6IGFueSkudmFsdWUuaW5kZXhPZihjdHguZ2VvbWV0cnlUeXBlKCkpID49IDBcbiAgICBdLFxuICAgICdmaWx0ZXItaWQtaW4nOiBbXG4gICAgICAgIEJvb2xlYW5UeXBlLFxuICAgICAgICBbYXJyYXkoVmFsdWVUeXBlKV0sXG4gICAgICAgIChjdHgsIFt2XSkgPT4gKHY6IGFueSkudmFsdWUuaW5kZXhPZihjdHguaWQoKSkgPj0gMFxuICAgIF0sXG4gICAgJ2ZpbHRlci1pbi1zbWFsbCc6IFtcbiAgICAgICAgQm9vbGVhblR5cGUsXG4gICAgICAgIFtTdHJpbmdUeXBlLCBhcnJheShWYWx1ZVR5cGUpXSxcbiAgICAgICAgLy8gYXNzdW1lcyB2IGlzIGFuIGFycmF5IGxpdGVyYWxcbiAgICAgICAgKGN0eCwgW2ssIHZdKSA9PiAodjogYW55KS52YWx1ZS5pbmRleE9mKGN0eC5wcm9wZXJ0aWVzKClbKGs6IGFueSkudmFsdWVdKSA+PSAwXG4gICAgXSxcbiAgICAnZmlsdGVyLWluLWxhcmdlJzogW1xuICAgICAgICBCb29sZWFuVHlwZSxcbiAgICAgICAgW1N0cmluZ1R5cGUsIGFycmF5KFZhbHVlVHlwZSldLFxuICAgICAgICAvLyBhc3N1bWVzIHYgaXMgYSBhcnJheSBsaXRlcmFsIHdpdGggdmFsdWVzIHNvcnRlZCBpbiBhc2NlbmRpbmcgb3JkZXIgYW5kIG9mIGEgc2luZ2xlIHR5cGVcbiAgICAgICAgKGN0eCwgW2ssIHZdKSA9PiBiaW5hcnlTZWFyY2goY3R4LnByb3BlcnRpZXMoKVsoazogYW55KS52YWx1ZV0sICh2OiBhbnkpLnZhbHVlLCAwLCAodjogYW55KS52YWx1ZS5sZW5ndGggLSAxKVxuICAgIF0sXG4gICAgJ2FsbCc6IHtcbiAgICAgICAgdHlwZTogQm9vbGVhblR5cGUsXG4gICAgICAgIG92ZXJsb2FkczogW1xuICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgIFtCb29sZWFuVHlwZSwgQm9vbGVhblR5cGVdLFxuICAgICAgICAgICAgICAgIChjdHgsIFthLCBiXSkgPT4gYS5ldmFsdWF0ZShjdHgpICYmIGIuZXZhbHVhdGUoY3R4KVxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICB2YXJhcmdzKEJvb2xlYW5UeXBlKSxcbiAgICAgICAgICAgICAgICAoY3R4LCBhcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgYXJnIG9mIGFyZ3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghYXJnLmV2YWx1YXRlKGN0eCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF1cbiAgICAgICAgXVxuICAgIH0sXG4gICAgJ2FueSc6IHtcbiAgICAgICAgdHlwZTogQm9vbGVhblR5cGUsXG4gICAgICAgIG92ZXJsb2FkczogW1xuICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgIFtCb29sZWFuVHlwZSwgQm9vbGVhblR5cGVdLFxuICAgICAgICAgICAgICAgIChjdHgsIFthLCBiXSkgPT4gYS5ldmFsdWF0ZShjdHgpIHx8IGIuZXZhbHVhdGUoY3R4KVxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICB2YXJhcmdzKEJvb2xlYW5UeXBlKSxcbiAgICAgICAgICAgICAgICAoY3R4LCBhcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgYXJnIG9mIGFyZ3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcmcuZXZhbHVhdGUoY3R4KSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXVxuICAgICAgICBdXG4gICAgfSxcbiAgICAnISc6IFtcbiAgICAgICAgQm9vbGVhblR5cGUsXG4gICAgICAgIFtCb29sZWFuVHlwZV0sXG4gICAgICAgIChjdHgsIFtiXSkgPT4gIWIuZXZhbHVhdGUoY3R4KVxuICAgIF0sXG4gICAgJ2lzLXN1cHBvcnRlZC1zY3JpcHQnOiBbXG4gICAgICAgIEJvb2xlYW5UeXBlLFxuICAgICAgICBbU3RyaW5nVHlwZV0sXG4gICAgICAgIC8vIEF0IHBhcnNlIHRpbWUgdGhpcyB3aWxsIGFsd2F5cyByZXR1cm4gdHJ1ZSwgc28gd2UgbmVlZCB0byBleGNsdWRlIHRoaXMgZXhwcmVzc2lvbiB3aXRoIGlzR2xvYmFsUHJvcGVydHlDb25zdGFudFxuICAgICAgICAoY3R4LCBbc10pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGlzU3VwcG9ydGVkU2NyaXB0ID0gY3R4Lmdsb2JhbHMgJiYgY3R4Lmdsb2JhbHMuaXNTdXBwb3J0ZWRTY3JpcHQ7XG4gICAgICAgICAgICBpZiAoaXNTdXBwb3J0ZWRTY3JpcHQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaXNTdXBwb3J0ZWRTY3JpcHQocy5ldmFsdWF0ZShjdHgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgXSxcbiAgICAndXBjYXNlJzogW1xuICAgICAgICBTdHJpbmdUeXBlLFxuICAgICAgICBbU3RyaW5nVHlwZV0sXG4gICAgICAgIChjdHgsIFtzXSkgPT4gcy5ldmFsdWF0ZShjdHgpLnRvVXBwZXJDYXNlKClcbiAgICBdLFxuICAgICdkb3duY2FzZSc6IFtcbiAgICAgICAgU3RyaW5nVHlwZSxcbiAgICAgICAgW1N0cmluZ1R5cGVdLFxuICAgICAgICAoY3R4LCBbc10pID0+IHMuZXZhbHVhdGUoY3R4KS50b0xvd2VyQ2FzZSgpXG4gICAgXSxcbiAgICAnY29uY2F0JzogW1xuICAgICAgICBTdHJpbmdUeXBlLFxuICAgICAgICB2YXJhcmdzKFZhbHVlVHlwZSksXG4gICAgICAgIChjdHgsIGFyZ3MpID0+IGFyZ3MubWFwKGFyZyA9PiB2YWx1ZVRvU3RyaW5nKGFyZy5ldmFsdWF0ZShjdHgpKSkuam9pbignJylcbiAgICBdLFxuICAgICdyZXNvbHZlZC1sb2NhbGUnOiBbXG4gICAgICAgIFN0cmluZ1R5cGUsXG4gICAgICAgIFtDb2xsYXRvclR5cGVdLFxuICAgICAgICAoY3R4LCBbY29sbGF0b3JdKSA9PiBjb2xsYXRvci5ldmFsdWF0ZShjdHgpLnJlc29sdmVkTG9jYWxlKClcbiAgICBdXG59KTtcblxuZXhwb3J0IGRlZmF1bHQgZXhwcmVzc2lvbnM7XG4iLCIvLyBAZmxvd1xuXG4vKipcbiAqIEEgdHlwZSB1c2VkIGZvciByZXR1cm5pbmcgYW5kIHByb3BhZ2F0aW5nIGVycm9ycy4gVGhlIGZpcnN0IGVsZW1lbnQgb2YgdGhlIHVuaW9uXG4gKiByZXByZXNlbnRzIHN1Y2Nlc3MgYW5kIGNvbnRhaW5zIGEgdmFsdWUsIGFuZCB0aGUgc2Vjb25kIHJlcHJlc2VudHMgYW4gZXJyb3IgYW5kXG4gKiBjb250YWlucyBhbiBlcnJvciB2YWx1ZS5cbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCB0eXBlIFJlc3VsdDxULCBFPiA9XG4gICAgfCB7fCByZXN1bHQ6ICdzdWNjZXNzJywgdmFsdWU6IFQgfH1cbiAgICB8IHt8IHJlc3VsdDogJ2Vycm9yJywgdmFsdWU6IEUgfH07XG5cbmV4cG9ydCBmdW5jdGlvbiBzdWNjZXNzPFQsIEU+KHZhbHVlOiBUKTogUmVzdWx0PFQsIEU+IHtcbiAgICByZXR1cm4ge3Jlc3VsdDogJ3N1Y2Nlc3MnLCB2YWx1ZX07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBlcnJvcjxULCBFPih2YWx1ZTogRSk6IFJlc3VsdDxULCBFPiB7XG4gICAgcmV0dXJuIHtyZXN1bHQ6ICdlcnJvcicsIHZhbHVlfTtcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCB0eXBlIHtTdHlsZVByb3BlcnR5U3BlY2lmaWNhdGlvbn0gZnJvbSAnLi4vc3R5bGUtc3BlYy5qcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBzdXBwb3J0c1Byb3BlcnR5RXhwcmVzc2lvbihzcGVjOiBTdHlsZVByb3BlcnR5U3BlY2lmaWNhdGlvbik6IGJvb2xlYW4ge1xuICAgIHJldHVybiBzcGVjWydwcm9wZXJ0eS10eXBlJ10gPT09ICdkYXRhLWRyaXZlbic7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzdXBwb3J0c1pvb21FeHByZXNzaW9uKHNwZWM6IFN0eWxlUHJvcGVydHlTcGVjaWZpY2F0aW9uKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhc3BlYy5leHByZXNzaW9uICYmIHNwZWMuZXhwcmVzc2lvbi5wYXJhbWV0ZXJzLmluZGV4T2YoJ3pvb20nKSA+IC0xO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc3VwcG9ydHNJbnRlcnBvbGF0aW9uKHNwZWM6IFN0eWxlUHJvcGVydHlTcGVjaWZpY2F0aW9uKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhc3BlYy5leHByZXNzaW9uICYmIHNwZWMuZXhwcmVzc2lvbi5pbnRlcnBvbGF0ZWQ7XG59XG4iLCIvLyBAZmxvd1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRUeXBlKHZhbDogbWl4ZWQpOiBzdHJpbmcge1xuICAgIGlmICh2YWwgaW5zdGFuY2VvZiBOdW1iZXIpIHtcbiAgICAgICAgcmV0dXJuICdudW1iZXInO1xuICAgIH0gZWxzZSBpZiAodmFsIGluc3RhbmNlb2YgU3RyaW5nKSB7XG4gICAgICAgIHJldHVybiAnc3RyaW5nJztcbiAgICB9IGVsc2UgaWYgKHZhbCBpbnN0YW5jZW9mIEJvb2xlYW4pIHtcbiAgICAgICAgcmV0dXJuICdib29sZWFuJztcbiAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkodmFsKSkge1xuICAgICAgICByZXR1cm4gJ2FycmF5JztcbiAgICB9IGVsc2UgaWYgKHZhbCA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gJ251bGwnO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgdmFsO1xuICAgIH1cbn1cbiIsIlxuaW1wb3J0ICogYXMgY29sb3JTcGFjZXMgZnJvbSAnLi4vdXRpbC9jb2xvcl9zcGFjZXMuanMnO1xuaW1wb3J0IENvbG9yIGZyb20gJy4uL3V0aWwvY29sb3IuanMnO1xuaW1wb3J0IGV4dGVuZCBmcm9tICcuLi91dGlsL2V4dGVuZC5qcyc7XG5pbXBvcnQgZ2V0VHlwZSBmcm9tICcuLi91dGlsL2dldF90eXBlLmpzJztcbmltcG9ydCAqIGFzIGludGVycG9sYXRlIGZyb20gJy4uL3V0aWwvaW50ZXJwb2xhdGUuanMnO1xuaW1wb3J0IEludGVycG9sYXRlIGZyb20gJy4uL2V4cHJlc3Npb24vZGVmaW5pdGlvbnMvaW50ZXJwb2xhdGUuanMnO1xuaW1wb3J0IEZvcm1hdHRlZCBmcm9tICcuLi9leHByZXNzaW9uL3R5cGVzL2Zvcm1hdHRlZC5qcyc7XG5pbXBvcnQgUmVzb2x2ZWRJbWFnZSBmcm9tICcuLi9leHByZXNzaW9uL3R5cGVzL3Jlc29sdmVkX2ltYWdlLmpzJztcbmltcG9ydCB7c3VwcG9ydHNJbnRlcnBvbGF0aW9ufSBmcm9tICcuLi91dGlsL3Byb3BlcnRpZXMuanMnO1xuaW1wb3J0IHtmaW5kU3RvcExlc3NUaGFuT3JFcXVhbFRvfSBmcm9tICcuLi9leHByZXNzaW9uL3N0b3BzLmpzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGlzRnVuY3Rpb24odmFsdWUpIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbCAmJiAhQXJyYXkuaXNBcnJheSh2YWx1ZSk7XG59XG5cbmZ1bmN0aW9uIGlkZW50aXR5RnVuY3Rpb24oeCkge1xuICAgIHJldHVybiB4O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRnVuY3Rpb24ocGFyYW1ldGVycywgcHJvcGVydHlTcGVjKSB7XG4gICAgY29uc3QgaXNDb2xvciA9IHByb3BlcnR5U3BlYy50eXBlID09PSAnY29sb3InO1xuICAgIGNvbnN0IHpvb21BbmRGZWF0dXJlRGVwZW5kZW50ID0gcGFyYW1ldGVycy5zdG9wcyAmJiB0eXBlb2YgcGFyYW1ldGVycy5zdG9wc1swXVswXSA9PT0gJ29iamVjdCc7XG4gICAgY29uc3QgZmVhdHVyZURlcGVuZGVudCA9IHpvb21BbmRGZWF0dXJlRGVwZW5kZW50IHx8IHBhcmFtZXRlcnMucHJvcGVydHkgIT09IHVuZGVmaW5lZDtcbiAgICBjb25zdCB6b29tRGVwZW5kZW50ID0gem9vbUFuZEZlYXR1cmVEZXBlbmRlbnQgfHwgIWZlYXR1cmVEZXBlbmRlbnQ7XG4gICAgY29uc3QgdHlwZSA9IHBhcmFtZXRlcnMudHlwZSB8fCAoc3VwcG9ydHNJbnRlcnBvbGF0aW9uKHByb3BlcnR5U3BlYykgPyAnZXhwb25lbnRpYWwnIDogJ2ludGVydmFsJyk7XG5cbiAgICBpZiAoaXNDb2xvcikge1xuICAgICAgICBwYXJhbWV0ZXJzID0gZXh0ZW5kKHt9LCBwYXJhbWV0ZXJzKTtcblxuICAgICAgICBpZiAocGFyYW1ldGVycy5zdG9wcykge1xuICAgICAgICAgICAgcGFyYW1ldGVycy5zdG9wcyA9IHBhcmFtZXRlcnMuc3RvcHMubWFwKChzdG9wKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtzdG9wWzBdLCBDb2xvci5wYXJzZShzdG9wWzFdKV07XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJhbWV0ZXJzLmRlZmF1bHQpIHtcbiAgICAgICAgICAgIHBhcmFtZXRlcnMuZGVmYXVsdCA9IENvbG9yLnBhcnNlKHBhcmFtZXRlcnMuZGVmYXVsdCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwYXJhbWV0ZXJzLmRlZmF1bHQgPSBDb2xvci5wYXJzZShwcm9wZXJ0eVNwZWMuZGVmYXVsdCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocGFyYW1ldGVycy5jb2xvclNwYWNlICYmIHBhcmFtZXRlcnMuY29sb3JTcGFjZSAhPT0gJ3JnYicgJiYgIWNvbG9yU3BhY2VzW3BhcmFtZXRlcnMuY29sb3JTcGFjZV0pIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBpbXBvcnQvbmFtZXNwYWNlXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBjb2xvciBzcGFjZTogJHtwYXJhbWV0ZXJzLmNvbG9yU3BhY2V9YCk7XG4gICAgfVxuXG4gICAgbGV0IGlubmVyRnVuO1xuICAgIGxldCBoYXNoZWRTdG9wcztcbiAgICBsZXQgY2F0ZWdvcmljYWxLZXlUeXBlO1xuICAgIGlmICh0eXBlID09PSAnZXhwb25lbnRpYWwnKSB7XG4gICAgICAgIGlubmVyRnVuID0gZXZhbHVhdGVFeHBvbmVudGlhbEZ1bmN0aW9uO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2ludGVydmFsJykge1xuICAgICAgICBpbm5lckZ1biA9IGV2YWx1YXRlSW50ZXJ2YWxGdW5jdGlvbjtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdjYXRlZ29yaWNhbCcpIHtcbiAgICAgICAgaW5uZXJGdW4gPSBldmFsdWF0ZUNhdGVnb3JpY2FsRnVuY3Rpb247XG5cbiAgICAgICAgLy8gRm9yIGNhdGVnb3JpY2FsIGZ1bmN0aW9ucywgZ2VuZXJhdGUgYW4gT2JqZWN0IGFzIGEgaGFzaG1hcCBvZiB0aGUgc3RvcHMgZm9yIGZhc3Qgc2VhcmNoaW5nXG4gICAgICAgIGhhc2hlZFN0b3BzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgZm9yIChjb25zdCBzdG9wIG9mIHBhcmFtZXRlcnMuc3RvcHMpIHtcbiAgICAgICAgICAgIGhhc2hlZFN0b3BzW3N0b3BbMF1dID0gc3RvcFsxXTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEluZmVyIGtleSB0eXBlIGJhc2VkIG9uIGZpcnN0IHN0b3Aga2V5LS0gdXNlZCB0byBlbmNmb3JjZSBzdHJpY3QgdHlwZSBjaGVja2luZyBsYXRlclxuICAgICAgICBjYXRlZ29yaWNhbEtleVR5cGUgPSB0eXBlb2YgcGFyYW1ldGVycy5zdG9wc1swXVswXTtcblxuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2lkZW50aXR5Jykge1xuICAgICAgICBpbm5lckZ1biA9IGV2YWx1YXRlSWRlbnRpdHlGdW5jdGlvbjtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gZnVuY3Rpb24gdHlwZSBcIiR7dHlwZX1cImApO1xuICAgIH1cblxuICAgIGlmICh6b29tQW5kRmVhdHVyZURlcGVuZGVudCkge1xuICAgICAgICBjb25zdCBmZWF0dXJlRnVuY3Rpb25zID0ge307XG4gICAgICAgIGNvbnN0IHpvb21TdG9wcyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBzID0gMDsgcyA8IHBhcmFtZXRlcnMuc3RvcHMubGVuZ3RoOyBzKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHN0b3AgPSBwYXJhbWV0ZXJzLnN0b3BzW3NdO1xuICAgICAgICAgICAgY29uc3Qgem9vbSA9IHN0b3BbMF0uem9vbTtcbiAgICAgICAgICAgIGlmIChmZWF0dXJlRnVuY3Rpb25zW3pvb21dID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBmZWF0dXJlRnVuY3Rpb25zW3pvb21dID0ge1xuICAgICAgICAgICAgICAgICAgICB6b29tLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBwYXJhbWV0ZXJzLnR5cGUsXG4gICAgICAgICAgICAgICAgICAgIHByb3BlcnR5OiBwYXJhbWV0ZXJzLnByb3BlcnR5LFxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiBwYXJhbWV0ZXJzLmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgIHN0b3BzOiBbXVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgem9vbVN0b3BzLnB1c2goem9vbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmZWF0dXJlRnVuY3Rpb25zW3pvb21dLnN0b3BzLnB1c2goW3N0b3BbMF0udmFsdWUsIHN0b3BbMV1dKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZlYXR1cmVGdW5jdGlvblN0b3BzID0gW107XG4gICAgICAgIGZvciAoY29uc3QgeiBvZiB6b29tU3RvcHMpIHtcbiAgICAgICAgICAgIGZlYXR1cmVGdW5jdGlvblN0b3BzLnB1c2goW2ZlYXR1cmVGdW5jdGlvbnNbel0uem9vbSwgY3JlYXRlRnVuY3Rpb24oZmVhdHVyZUZ1bmN0aW9uc1t6XSwgcHJvcGVydHlTcGVjKV0pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaW50ZXJwb2xhdGlvblR5cGUgPSB7bmFtZTogJ2xpbmVhcid9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAga2luZDogJ2NvbXBvc2l0ZScsXG4gICAgICAgICAgICBpbnRlcnBvbGF0aW9uVHlwZSxcbiAgICAgICAgICAgIGludGVycG9sYXRpb25GYWN0b3I6IEludGVycG9sYXRlLmludGVycG9sYXRpb25GYWN0b3IuYmluZCh1bmRlZmluZWQsIGludGVycG9sYXRpb25UeXBlKSxcbiAgICAgICAgICAgIHpvb21TdG9wczogZmVhdHVyZUZ1bmN0aW9uU3RvcHMubWFwKHMgPT4gc1swXSksXG4gICAgICAgICAgICBldmFsdWF0ZSh7em9vbX0sIHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZXZhbHVhdGVFeHBvbmVudGlhbEZ1bmN0aW9uKHtcbiAgICAgICAgICAgICAgICAgICAgc3RvcHM6IGZlYXR1cmVGdW5jdGlvblN0b3BzLFxuICAgICAgICAgICAgICAgICAgICBiYXNlOiBwYXJhbWV0ZXJzLmJhc2VcbiAgICAgICAgICAgICAgICB9LCBwcm9wZXJ0eVNwZWMsIHpvb20pLmV2YWx1YXRlKHpvb20sIHByb3BlcnRpZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH0gZWxzZSBpZiAoem9vbURlcGVuZGVudCkge1xuICAgICAgICBjb25zdCBpbnRlcnBvbGF0aW9uVHlwZSA9IHR5cGUgPT09ICdleHBvbmVudGlhbCcgP1xuICAgICAgICAgICAge25hbWU6ICdleHBvbmVudGlhbCcsIGJhc2U6IHBhcmFtZXRlcnMuYmFzZSAhPT0gdW5kZWZpbmVkID8gcGFyYW1ldGVycy5iYXNlIDogMX0gOiBudWxsO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAga2luZDogJ2NhbWVyYScsXG4gICAgICAgICAgICBpbnRlcnBvbGF0aW9uVHlwZSxcbiAgICAgICAgICAgIGludGVycG9sYXRpb25GYWN0b3I6IEludGVycG9sYXRlLmludGVycG9sYXRpb25GYWN0b3IuYmluZCh1bmRlZmluZWQsIGludGVycG9sYXRpb25UeXBlKSxcbiAgICAgICAgICAgIHpvb21TdG9wczogcGFyYW1ldGVycy5zdG9wcy5tYXAocyA9PiBzWzBdKSxcbiAgICAgICAgICAgIGV2YWx1YXRlOiAoe3pvb219KSA9PiBpbm5lckZ1bihwYXJhbWV0ZXJzLCBwcm9wZXJ0eVNwZWMsIHpvb20sIGhhc2hlZFN0b3BzLCBjYXRlZ29yaWNhbEtleVR5cGUpXG4gICAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGtpbmQ6ICdzb3VyY2UnLFxuICAgICAgICAgICAgZXZhbHVhdGUoXywgZmVhdHVyZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gZmVhdHVyZSAmJiBmZWF0dXJlLnByb3BlcnRpZXMgPyBmZWF0dXJlLnByb3BlcnRpZXNbcGFyYW1ldGVycy5wcm9wZXJ0eV0gOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvYWxlc2NlKHBhcmFtZXRlcnMuZGVmYXVsdCwgcHJvcGVydHlTcGVjLmRlZmF1bHQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gaW5uZXJGdW4ocGFyYW1ldGVycywgcHJvcGVydHlTcGVjLCB2YWx1ZSwgaGFzaGVkU3RvcHMsIGNhdGVnb3JpY2FsS2V5VHlwZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxufVxuXG5mdW5jdGlvbiBjb2FsZXNjZShhLCBiLCBjKSB7XG4gICAgaWYgKGEgIT09IHVuZGVmaW5lZCkgcmV0dXJuIGE7XG4gICAgaWYgKGIgIT09IHVuZGVmaW5lZCkgcmV0dXJuIGI7XG4gICAgaWYgKGMgIT09IHVuZGVmaW5lZCkgcmV0dXJuIGM7XG59XG5cbmZ1bmN0aW9uIGV2YWx1YXRlQ2F0ZWdvcmljYWxGdW5jdGlvbihwYXJhbWV0ZXJzLCBwcm9wZXJ0eVNwZWMsIGlucHV0LCBoYXNoZWRTdG9wcywga2V5VHlwZSkge1xuICAgIGNvbnN0IGV2YWx1YXRlZCA9IHR5cGVvZiBpbnB1dCA9PT0ga2V5VHlwZSA/IGhhc2hlZFN0b3BzW2lucHV0XSA6IHVuZGVmaW5lZDsgLy8gRW5mb3JjZSBzdHJpY3QgdHlwaW5nIG9uIGlucHV0XG4gICAgcmV0dXJuIGNvYWxlc2NlKGV2YWx1YXRlZCwgcGFyYW1ldGVycy5kZWZhdWx0LCBwcm9wZXJ0eVNwZWMuZGVmYXVsdCk7XG59XG5cbmZ1bmN0aW9uIGV2YWx1YXRlSW50ZXJ2YWxGdW5jdGlvbihwYXJhbWV0ZXJzLCBwcm9wZXJ0eVNwZWMsIGlucHV0KSB7XG4gICAgLy8gRWRnZSBjYXNlc1xuICAgIGlmIChnZXRUeXBlKGlucHV0KSAhPT0gJ251bWJlcicpIHJldHVybiBjb2FsZXNjZShwYXJhbWV0ZXJzLmRlZmF1bHQsIHByb3BlcnR5U3BlYy5kZWZhdWx0KTtcbiAgICBjb25zdCBuID0gcGFyYW1ldGVycy5zdG9wcy5sZW5ndGg7XG4gICAgaWYgKG4gPT09IDEpIHJldHVybiBwYXJhbWV0ZXJzLnN0b3BzWzBdWzFdO1xuICAgIGlmIChpbnB1dCA8PSBwYXJhbWV0ZXJzLnN0b3BzWzBdWzBdKSByZXR1cm4gcGFyYW1ldGVycy5zdG9wc1swXVsxXTtcbiAgICBpZiAoaW5wdXQgPj0gcGFyYW1ldGVycy5zdG9wc1tuIC0gMV1bMF0pIHJldHVybiBwYXJhbWV0ZXJzLnN0b3BzW24gLSAxXVsxXTtcblxuICAgIGNvbnN0IGluZGV4ID0gZmluZFN0b3BMZXNzVGhhbk9yRXF1YWxUbyhwYXJhbWV0ZXJzLnN0b3BzLm1hcCgoc3RvcCkgPT4gc3RvcFswXSksIGlucHV0KTtcblxuICAgIHJldHVybiBwYXJhbWV0ZXJzLnN0b3BzW2luZGV4XVsxXTtcbn1cblxuZnVuY3Rpb24gZXZhbHVhdGVFeHBvbmVudGlhbEZ1bmN0aW9uKHBhcmFtZXRlcnMsIHByb3BlcnR5U3BlYywgaW5wdXQpIHtcbiAgICBjb25zdCBiYXNlID0gcGFyYW1ldGVycy5iYXNlICE9PSB1bmRlZmluZWQgPyBwYXJhbWV0ZXJzLmJhc2UgOiAxO1xuXG4gICAgLy8gRWRnZSBjYXNlc1xuICAgIGlmIChnZXRUeXBlKGlucHV0KSAhPT0gJ251bWJlcicpIHJldHVybiBjb2FsZXNjZShwYXJhbWV0ZXJzLmRlZmF1bHQsIHByb3BlcnR5U3BlYy5kZWZhdWx0KTtcbiAgICBjb25zdCBuID0gcGFyYW1ldGVycy5zdG9wcy5sZW5ndGg7XG4gICAgaWYgKG4gPT09IDEpIHJldHVybiBwYXJhbWV0ZXJzLnN0b3BzWzBdWzFdO1xuICAgIGlmIChpbnB1dCA8PSBwYXJhbWV0ZXJzLnN0b3BzWzBdWzBdKSByZXR1cm4gcGFyYW1ldGVycy5zdG9wc1swXVsxXTtcbiAgICBpZiAoaW5wdXQgPj0gcGFyYW1ldGVycy5zdG9wc1tuIC0gMV1bMF0pIHJldHVybiBwYXJhbWV0ZXJzLnN0b3BzW24gLSAxXVsxXTtcblxuICAgIGNvbnN0IGluZGV4ID0gZmluZFN0b3BMZXNzVGhhbk9yRXF1YWxUbyhwYXJhbWV0ZXJzLnN0b3BzLm1hcCgoc3RvcCkgPT4gc3RvcFswXSksIGlucHV0KTtcbiAgICBjb25zdCB0ID0gaW50ZXJwb2xhdGlvbkZhY3RvcihcbiAgICAgICAgaW5wdXQsIGJhc2UsXG4gICAgICAgIHBhcmFtZXRlcnMuc3RvcHNbaW5kZXhdWzBdLFxuICAgICAgICBwYXJhbWV0ZXJzLnN0b3BzW2luZGV4ICsgMV1bMF0pO1xuXG4gICAgY29uc3Qgb3V0cHV0TG93ZXIgPSBwYXJhbWV0ZXJzLnN0b3BzW2luZGV4XVsxXTtcbiAgICBjb25zdCBvdXRwdXRVcHBlciA9IHBhcmFtZXRlcnMuc3RvcHNbaW5kZXggKyAxXVsxXTtcbiAgICBsZXQgaW50ZXJwID0gaW50ZXJwb2xhdGVbcHJvcGVydHlTcGVjLnR5cGVdIHx8IGlkZW50aXR5RnVuY3Rpb247IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgaW1wb3J0L25hbWVzcGFjZVxuXG4gICAgaWYgKHBhcmFtZXRlcnMuY29sb3JTcGFjZSAmJiBwYXJhbWV0ZXJzLmNvbG9yU3BhY2UgIT09ICdyZ2InKSB7XG4gICAgICAgIGNvbnN0IGNvbG9yc3BhY2UgPSBjb2xvclNwYWNlc1twYXJhbWV0ZXJzLmNvbG9yU3BhY2VdOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGltcG9ydC9uYW1lc3BhY2VcbiAgICAgICAgaW50ZXJwID0gKGEsIGIpID0+IGNvbG9yc3BhY2UucmV2ZXJzZShjb2xvcnNwYWNlLmludGVycG9sYXRlKGNvbG9yc3BhY2UuZm9yd2FyZChhKSwgY29sb3JzcGFjZS5mb3J3YXJkKGIpLCB0KSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvdXRwdXRMb3dlci5ldmFsdWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZXZhbHVhdGUoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGV2YWx1YXRlZExvd2VyID0gb3V0cHV0TG93ZXIuZXZhbHVhdGUuYXBwbHkodW5kZWZpbmVkLCBhcmdzKTtcbiAgICAgICAgICAgICAgICBjb25zdCBldmFsdWF0ZWRVcHBlciA9IG91dHB1dFVwcGVyLmV2YWx1YXRlLmFwcGx5KHVuZGVmaW5lZCwgYXJncyk7XG4gICAgICAgICAgICAgICAgLy8gU3BlY2lhbCBjYXNlIGZvciBmaWxsLW91dGxpbmUtY29sb3IsIHdoaWNoIGhhcyBubyBzcGVjIGRlZmF1bHQuXG4gICAgICAgICAgICAgICAgaWYgKGV2YWx1YXRlZExvd2VyID09PSB1bmRlZmluZWQgfHwgZXZhbHVhdGVkVXBwZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gaW50ZXJwKGV2YWx1YXRlZExvd2VyLCBldmFsdWF0ZWRVcHBlciwgdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIGludGVycChvdXRwdXRMb3dlciwgb3V0cHV0VXBwZXIsIHQpO1xufVxuXG5mdW5jdGlvbiBldmFsdWF0ZUlkZW50aXR5RnVuY3Rpb24ocGFyYW1ldGVycywgcHJvcGVydHlTcGVjLCBpbnB1dCkge1xuICAgIGlmIChwcm9wZXJ0eVNwZWMudHlwZSA9PT0gJ2NvbG9yJykge1xuICAgICAgICBpbnB1dCA9IENvbG9yLnBhcnNlKGlucHV0KTtcbiAgICB9IGVsc2UgaWYgKHByb3BlcnR5U3BlYy50eXBlID09PSAnZm9ybWF0dGVkJykge1xuICAgICAgICBpbnB1dCA9IEZvcm1hdHRlZC5mcm9tU3RyaW5nKGlucHV0LnRvU3RyaW5nKCkpO1xuICAgIH0gZWxzZSBpZiAocHJvcGVydHlTcGVjLnR5cGUgPT09ICdyZXNvbHZlZEltYWdlJykge1xuICAgICAgICBpbnB1dCA9IFJlc29sdmVkSW1hZ2UuZnJvbVN0cmluZyhpbnB1dC50b1N0cmluZygpKTtcbiAgICB9IGVsc2UgaWYgKGdldFR5cGUoaW5wdXQpICE9PSBwcm9wZXJ0eVNwZWMudHlwZSAmJiAocHJvcGVydHlTcGVjLnR5cGUgIT09ICdlbnVtJyB8fCAhcHJvcGVydHlTcGVjLnZhbHVlc1tpbnB1dF0pKSB7XG4gICAgICAgIGlucHV0ID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gY29hbGVzY2UoaW5wdXQsIHBhcmFtZXRlcnMuZGVmYXVsdCwgcHJvcGVydHlTcGVjLmRlZmF1bHQpO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSByYXRpbyB0aGF0IGNhbiBiZSB1c2VkIHRvIGludGVycG9sYXRlIGJldHdlZW4gZXhwb25lbnRpYWwgZnVuY3Rpb25cbiAqIHN0b3BzLlxuICpcbiAqIEhvdyBpdCB3b3JrczpcbiAqIFR3byBjb25zZWN1dGl2ZSBzdG9wIHZhbHVlcyBkZWZpbmUgYSAoc2NhbGVkIGFuZCBzaGlmdGVkKSBleHBvbmVudGlhbFxuICogZnVuY3Rpb24gYGYoeCkgPSBhICogYmFzZV54ICsgYmAsIHdoZXJlIGBiYXNlYCBpcyB0aGUgdXNlci1zcGVjaWZpZWQgYmFzZSxcbiAqIGFuZCBgYWAgYW5kIGBiYCBhcmUgY29uc3RhbnRzIGFmZm9yZGluZyBzdWZmaWNpZW50IGRlZ3JlZXMgb2YgZnJlZWRvbSB0byBmaXRcbiAqIHRoZSBmdW5jdGlvbiB0byB0aGUgZ2l2ZW4gc3RvcHMuXG4gKlxuICogSGVyZSdzIGEgYml0IG9mIGFsZ2VicmEgdGhhdCBsZXRzIHVzIGNvbXB1dGUgYGYoeClgIGRpcmVjdGx5IGZyb20gdGhlIHN0b3BcbiAqIHZhbHVlcyB3aXRob3V0IGV4cGxpY2l0bHkgc29sdmluZyBmb3IgYGFgIGFuZCBgYmA6XG4gKlxuICogRmlyc3Qgc3RvcCB2YWx1ZTogYGYoeDApID0geTAgPSBhICogYmFzZV54MCArIGJgXG4gKiBTZWNvbmQgc3RvcCB2YWx1ZTogYGYoeDEpID0geTEgPSBhICogYmFzZV54MSArIGJgXG4gKiA9PiBgeTEgLSB5MCA9IGEoYmFzZV54MSAtIGJhc2VeeDApYFxuICogPT4gYGEgPSAoeTEgLSB5MCkvKGJhc2VeeDEgLSBiYXNlXngwKWBcbiAqXG4gKiBEZXNpcmVkIHZhbHVlOiBgZih4KSA9IHkgPSBhICogYmFzZV54ICsgYmBcbiAqID0+IGBmKHgpID0geTAgKyBhICogKGJhc2VeeCAtIGJhc2VeeDApYFxuICpcbiAqIEZyb20gdGhlIGFib3ZlLCB3ZSBjYW4gcmVwbGFjZSB0aGUgYGFgIGluIGBhICogKGJhc2VeeCAtIGJhc2VeeDApYCBhbmQgZG8gYVxuICogbGl0dGxlIGFsZ2VicmE6XG4gKiBgYGBcbiAqIGEgKiAoYmFzZV54IC0gYmFzZV54MCkgPSAoeTEgLSB5MCkvKGJhc2VeeDEgLSBiYXNlXngwKSAqIChiYXNlXnggLSBiYXNlXngwKVxuICogICAgICAgICAgICAgICAgICAgICA9ICh5MSAtIHkwKSAqIChiYXNlXnggLSBiYXNlXngwKSAvIChiYXNlXngxIC0gYmFzZV54MClcbiAqIGBgYFxuICpcbiAqIElmIHdlIGxldCBgKGJhc2VeeCAtIGJhc2VeeDApIC8gKGJhc2VeeDEgYmFzZV54MClgLCB0aGVuIHdlIGhhdmVcbiAqIGBmKHgpID0geTAgKyAoeTEgLSB5MCkgKiByYXRpb2AuICBJbiBvdGhlciB3b3JkcywgYHJhdGlvYCBtYXkgYmUgdHJlYXRlZCBhc1xuICogYW4gaW50ZXJwb2xhdGlvbiBmYWN0b3IgYmV0d2VlbiB0aGUgdHdvIHN0b3BzJyBvdXRwdXQgdmFsdWVzLlxuICpcbiAqIChOb3RlOiBhIHNsaWdodGx5IGRpZmZlcmVudCBmb3JtIGZvciBgcmF0aW9gLFxuICogYChiYXNlXih4LXgwKSAtIDEpIC8gKGJhc2VeKHgxLXgwKSAtIDEpIGAsIGlzIGVxdWl2YWxlbnQsIGJ1dCByZXF1aXJlcyBmZXdlclxuICogZXhwZW5zaXZlIGBNYXRoLnBvdygpYCBvcGVyYXRpb25zLilcbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBpbnRlcnBvbGF0aW9uRmFjdG9yKGlucHV0LCBiYXNlLCBsb3dlclZhbHVlLCB1cHBlclZhbHVlKSB7XG4gICAgY29uc3QgZGlmZmVyZW5jZSA9IHVwcGVyVmFsdWUgLSBsb3dlclZhbHVlO1xuICAgIGNvbnN0IHByb2dyZXNzID0gaW5wdXQgLSBsb3dlclZhbHVlO1xuXG4gICAgaWYgKGRpZmZlcmVuY2UgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfSBlbHNlIGlmIChiYXNlID09PSAxKSB7XG4gICAgICAgIHJldHVybiBwcm9ncmVzcyAvIGRpZmZlcmVuY2U7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIChNYXRoLnBvdyhiYXNlLCBwcm9ncmVzcykgLSAxKSAvIChNYXRoLnBvdyhiYXNlLCBkaWZmZXJlbmNlKSAtIDEpO1xuICAgIH1cbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcblxuaW1wb3J0IGV4dGVuZCBmcm9tICcuLi91dGlsL2V4dGVuZC5qcyc7XG5pbXBvcnQgUGFyc2luZ0Vycm9yIGZyb20gJy4vcGFyc2luZ19lcnJvci5qcyc7XG5pbXBvcnQgUGFyc2luZ0NvbnRleHQgZnJvbSAnLi9wYXJzaW5nX2NvbnRleHQuanMnO1xuaW1wb3J0IEV2YWx1YXRpb25Db250ZXh0IGZyb20gJy4vZXZhbHVhdGlvbl9jb250ZXh0LmpzJztcbmltcG9ydCBDb21wb3VuZEV4cHJlc3Npb24gZnJvbSAnLi9jb21wb3VuZF9leHByZXNzaW9uLmpzJztcbmltcG9ydCBTdGVwIGZyb20gJy4vZGVmaW5pdGlvbnMvc3RlcC5qcyc7XG5pbXBvcnQgSW50ZXJwb2xhdGUgZnJvbSAnLi9kZWZpbml0aW9ucy9pbnRlcnBvbGF0ZS5qcyc7XG5pbXBvcnQgQ29hbGVzY2UgZnJvbSAnLi9kZWZpbml0aW9ucy9jb2FsZXNjZS5qcyc7XG5pbXBvcnQgTGV0IGZyb20gJy4vZGVmaW5pdGlvbnMvbGV0LmpzJztcbmltcG9ydCBkZWZpbml0aW9ucyBmcm9tICcuL2RlZmluaXRpb25zL2luZGV4LmpzJztcbmltcG9ydCAqIGFzIGlzQ29uc3RhbnQgZnJvbSAnLi9pc19jb25zdGFudC5qcyc7XG5pbXBvcnQgUnVudGltZUVycm9yIGZyb20gJy4vcnVudGltZV9lcnJvci5qcyc7XG5pbXBvcnQge3N1Y2Nlc3MsIGVycm9yfSBmcm9tICcuLi91dGlsL3Jlc3VsdC5qcyc7XG5pbXBvcnQge3N1cHBvcnRzUHJvcGVydHlFeHByZXNzaW9uLCBzdXBwb3J0c1pvb21FeHByZXNzaW9uLCBzdXBwb3J0c0ludGVycG9sYXRpb259IGZyb20gJy4uL3V0aWwvcHJvcGVydGllcy5qcyc7XG5cbmltcG9ydCB0eXBlIHtUeXBlLCBFdmFsdWF0aW9uS2luZH0gZnJvbSAnLi90eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSB7VmFsdWV9IGZyb20gJy4vdmFsdWVzLmpzJztcbmltcG9ydCB0eXBlIHtFeHByZXNzaW9ufSBmcm9tICcuL2V4cHJlc3Npb24uanMnO1xuaW1wb3J0IHR5cGUge1N0eWxlUHJvcGVydHlTcGVjaWZpY2F0aW9ufSBmcm9tICcuLi9zdHlsZS1zcGVjLmpzJztcbmltcG9ydCB0eXBlIHtSZXN1bHR9IGZyb20gJy4uL3V0aWwvcmVzdWx0LmpzJztcbmltcG9ydCB0eXBlIHtJbnRlcnBvbGF0aW9uVHlwZX0gZnJvbSAnLi9kZWZpbml0aW9ucy9pbnRlcnBvbGF0ZS5qcyc7XG5pbXBvcnQgdHlwZSB7UHJvcGVydHlWYWx1ZVNwZWNpZmljYXRpb259IGZyb20gJy4uL3R5cGVzLmpzJztcbmltcG9ydCB0eXBlIHtGb3JtYXR0ZWRTZWN0aW9ufSBmcm9tICcuL3R5cGVzL2Zvcm1hdHRlZC5qcyc7XG5pbXBvcnQgdHlwZSBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCB0eXBlIHtDYW5vbmljYWxUaWxlSUR9IGZyb20gJy4uLy4uL3NvdXJjZS90aWxlX2lkLmpzJztcbmltcG9ydCB0eXBlIHtGZWF0dXJlRGlzdGFuY2VEYXRhfSBmcm9tICcuLi9mZWF0dXJlX2ZpbHRlci9pbmRleC5qcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRmVhdHVyZSB7XG4gICAgK3R5cGU6IDEgfCAyIHwgMyB8ICdVbmtub3duJyB8ICdQb2ludCcgfCAnTGluZVN0cmluZycgfCAnUG9seWdvbic7XG4gICAgK2lkPzogbnVtYmVyIHwgbnVsbDtcbiAgICArcHJvcGVydGllczoge1tfOiBzdHJpbmddOiBhbnl9O1xuICAgICtwYXR0ZXJucz86IHtbXzogc3RyaW5nXTogc3RyaW5nfTtcbiAgICArZ2VvbWV0cnk/OiBBcnJheTxBcnJheTxQb2ludD4+O1xufVxuXG5leHBvcnQgdHlwZSBGZWF0dXJlU3RhdGUgPSB7W186IHN0cmluZ106IGFueX07XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2xvYmFsUHJvcGVydGllcyB7XG4gICAgK3pvb206IG51bWJlcjtcbiAgICArcGl0Y2g/OiBudW1iZXI7XG4gICAgK2hlYXRtYXBEZW5zaXR5PzogbnVtYmVyO1xuICAgICtsaW5lUHJvZ3Jlc3M/OiBudW1iZXI7XG4gICAgK3NreVJhZGlhbFByb2dyZXNzPzogbnVtYmVyO1xuICAgICtpc1N1cHBvcnRlZFNjcmlwdD86IChfOiBzdHJpbmcpID0+IGJvb2xlYW47XG4gICAgK2FjY3VtdWxhdGVkPzogVmFsdWU7XG59XG5cbmV4cG9ydCBjbGFzcyBTdHlsZUV4cHJlc3Npb24ge1xuICAgIGV4cHJlc3Npb246IEV4cHJlc3Npb247XG5cbiAgICBfZXZhbHVhdG9yOiBFdmFsdWF0aW9uQ29udGV4dDtcbiAgICBfZGVmYXVsdFZhbHVlOiBWYWx1ZTtcbiAgICBfd2FybmluZ0hpc3Rvcnk6IHtba2V5OiBzdHJpbmddOiBib29sZWFufTtcbiAgICBfZW51bVZhbHVlczogP3tbXzogc3RyaW5nXTogYW55fTtcblxuICAgIGNvbnN0cnVjdG9yKGV4cHJlc3Npb246IEV4cHJlc3Npb24sIHByb3BlcnR5U3BlYzogP1N0eWxlUHJvcGVydHlTcGVjaWZpY2F0aW9uKSB7XG4gICAgICAgIHRoaXMuZXhwcmVzc2lvbiA9IGV4cHJlc3Npb247XG4gICAgICAgIHRoaXMuX3dhcm5pbmdIaXN0b3J5ID0ge307XG4gICAgICAgIHRoaXMuX2V2YWx1YXRvciA9IG5ldyBFdmFsdWF0aW9uQ29udGV4dCgpO1xuICAgICAgICB0aGlzLl9kZWZhdWx0VmFsdWUgPSBwcm9wZXJ0eVNwZWMgPyBnZXREZWZhdWx0VmFsdWUocHJvcGVydHlTcGVjKSA6IG51bGw7XG4gICAgICAgIHRoaXMuX2VudW1WYWx1ZXMgPSBwcm9wZXJ0eVNwZWMgJiYgcHJvcGVydHlTcGVjLnR5cGUgPT09ICdlbnVtJyA/IHByb3BlcnR5U3BlYy52YWx1ZXMgOiBudWxsO1xuICAgIH1cblxuICAgIGV2YWx1YXRlV2l0aG91dEVycm9ySGFuZGxpbmcoZ2xvYmFsczogR2xvYmFsUHJvcGVydGllcywgZmVhdHVyZT86IEZlYXR1cmUsIGZlYXR1cmVTdGF0ZT86IEZlYXR1cmVTdGF0ZSwgY2Fub25pY2FsPzogQ2Fub25pY2FsVGlsZUlELCBhdmFpbGFibGVJbWFnZXM/OiBBcnJheTxzdHJpbmc+LCBmb3JtYXR0ZWRTZWN0aW9uPzogRm9ybWF0dGVkU2VjdGlvbiwgZmVhdHVyZVRpbGVDb29yZD86IFBvaW50LCBmZWF0dXJlRGlzdGFuY2VEYXRhPzogRmVhdHVyZURpc3RhbmNlRGF0YSk6IGFueSB7XG4gICAgICAgIHRoaXMuX2V2YWx1YXRvci5nbG9iYWxzID0gZ2xvYmFscztcbiAgICAgICAgdGhpcy5fZXZhbHVhdG9yLmZlYXR1cmUgPSBmZWF0dXJlO1xuICAgICAgICB0aGlzLl9ldmFsdWF0b3IuZmVhdHVyZVN0YXRlID0gZmVhdHVyZVN0YXRlO1xuICAgICAgICB0aGlzLl9ldmFsdWF0b3IuY2Fub25pY2FsID0gY2Fub25pY2FsIHx8IG51bGw7XG4gICAgICAgIHRoaXMuX2V2YWx1YXRvci5hdmFpbGFibGVJbWFnZXMgPSBhdmFpbGFibGVJbWFnZXMgfHwgbnVsbDtcbiAgICAgICAgdGhpcy5fZXZhbHVhdG9yLmZvcm1hdHRlZFNlY3Rpb24gPSBmb3JtYXR0ZWRTZWN0aW9uO1xuICAgICAgICB0aGlzLl9ldmFsdWF0b3IuZmVhdHVyZVRpbGVDb29yZCA9IGZlYXR1cmVUaWxlQ29vcmQgfHwgbnVsbDtcbiAgICAgICAgdGhpcy5fZXZhbHVhdG9yLmZlYXR1cmVEaXN0YW5jZURhdGEgPSBmZWF0dXJlRGlzdGFuY2VEYXRhIHx8IG51bGw7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZXhwcmVzc2lvbi5ldmFsdWF0ZSh0aGlzLl9ldmFsdWF0b3IpO1xuICAgIH1cblxuICAgIGV2YWx1YXRlKGdsb2JhbHM6IEdsb2JhbFByb3BlcnRpZXMsIGZlYXR1cmU/OiBGZWF0dXJlLCBmZWF0dXJlU3RhdGU/OiBGZWF0dXJlU3RhdGUsIGNhbm9uaWNhbD86IENhbm9uaWNhbFRpbGVJRCwgYXZhaWxhYmxlSW1hZ2VzPzogQXJyYXk8c3RyaW5nPiwgZm9ybWF0dGVkU2VjdGlvbj86IEZvcm1hdHRlZFNlY3Rpb24sIGZlYXR1cmVUaWxlQ29vcmQ/OiBQb2ludCwgZmVhdHVyZURpc3RhbmNlRGF0YT86IEZlYXR1cmVEaXN0YW5jZURhdGEpOiBhbnkge1xuICAgICAgICB0aGlzLl9ldmFsdWF0b3IuZ2xvYmFscyA9IGdsb2JhbHM7XG4gICAgICAgIHRoaXMuX2V2YWx1YXRvci5mZWF0dXJlID0gZmVhdHVyZSB8fCBudWxsO1xuICAgICAgICB0aGlzLl9ldmFsdWF0b3IuZmVhdHVyZVN0YXRlID0gZmVhdHVyZVN0YXRlIHx8IG51bGw7XG4gICAgICAgIHRoaXMuX2V2YWx1YXRvci5jYW5vbmljYWwgPSBjYW5vbmljYWwgfHwgbnVsbDtcbiAgICAgICAgdGhpcy5fZXZhbHVhdG9yLmF2YWlsYWJsZUltYWdlcyA9IGF2YWlsYWJsZUltYWdlcyB8fCBudWxsO1xuICAgICAgICB0aGlzLl9ldmFsdWF0b3IuZm9ybWF0dGVkU2VjdGlvbiA9IGZvcm1hdHRlZFNlY3Rpb24gfHwgbnVsbDtcbiAgICAgICAgdGhpcy5fZXZhbHVhdG9yLmZlYXR1cmVUaWxlQ29vcmQgPSBmZWF0dXJlVGlsZUNvb3JkIHx8IG51bGw7XG4gICAgICAgIHRoaXMuX2V2YWx1YXRvci5mZWF0dXJlRGlzdGFuY2VEYXRhID0gZmVhdHVyZURpc3RhbmNlRGF0YSB8fCBudWxsO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCB2YWwgPSB0aGlzLmV4cHJlc3Npb24uZXZhbHVhdGUodGhpcy5fZXZhbHVhdG9yKTtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICAgICAgICAgIGlmICh2YWwgPT09IG51bGwgfHwgdmFsID09PSB1bmRlZmluZWQgfHwgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInICYmIHZhbCAhPT0gdmFsKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9kZWZhdWx0VmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5fZW51bVZhbHVlcyAmJiAhKHZhbCBpbiB0aGlzLl9lbnVtVmFsdWVzKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXJyb3IoYEV4cGVjdGVkIHZhbHVlIHRvIGJlIG9uZSBvZiAke09iamVjdC5rZXlzKHRoaXMuX2VudW1WYWx1ZXMpLm1hcCh2ID0+IEpTT04uc3RyaW5naWZ5KHYpKS5qb2luKCcsICcpfSwgYnV0IGZvdW5kICR7SlNPTi5zdHJpbmdpZnkodmFsKX0gaW5zdGVhZC5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB2YWw7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5fd2FybmluZ0hpc3RvcnlbZS5tZXNzYWdlXSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3dhcm5pbmdIaXN0b3J5W2UubWVzc2FnZV0gPSB0cnVlO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY29uc29sZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGUubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RlZmF1bHRWYWx1ZTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzRXhwcmVzc2lvbihleHByZXNzaW9uOiBtaXhlZCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBBcnJheS5pc0FycmF5KGV4cHJlc3Npb24pICYmIGV4cHJlc3Npb24ubGVuZ3RoID4gMCAmJlxuICAgICAgICB0eXBlb2YgZXhwcmVzc2lvblswXSA9PT0gJ3N0cmluZycgJiYgZXhwcmVzc2lvblswXSBpbiBkZWZpbml0aW9ucztcbn1cblxuLyoqXG4gKiBQYXJzZSBhbmQgdHlwZWNoZWNrIHRoZSBnaXZlbiBzdHlsZSBzcGVjIEpTT04gZXhwcmVzc2lvbi4gIElmXG4gKiBvcHRpb25zLmRlZmF1bHRWYWx1ZSBpcyBwcm92aWRlZCwgdGhlbiB0aGUgcmVzdWx0aW5nIFN0eWxlRXhwcmVzc2lvbidzXG4gKiBgZXZhbHVhdGUoKWAgbWV0aG9kIHdpbGwgaGFuZGxlIGVycm9ycyBieSBsb2dnaW5nIGEgd2FybmluZyAob25jZSBwZXJcbiAqIG1lc3NhZ2UpIGFuZCByZXR1cm5pbmcgdGhlIGRlZmF1bHQgdmFsdWUuICBPdGhlcndpc2UsIGl0IHdpbGwgdGhyb3dcbiAqIGV2YWx1YXRpb24gZXJyb3JzLlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVFeHByZXNzaW9uKGV4cHJlc3Npb246IG1peGVkLCBwcm9wZXJ0eVNwZWM6ID9TdHlsZVByb3BlcnR5U3BlY2lmaWNhdGlvbik6IFJlc3VsdDxTdHlsZUV4cHJlc3Npb24sIEFycmF5PFBhcnNpbmdFcnJvcj4+IHtcbiAgICBjb25zdCBwYXJzZXIgPSBuZXcgUGFyc2luZ0NvbnRleHQoZGVmaW5pdGlvbnMsIFtdLCBwcm9wZXJ0eVNwZWMgPyBnZXRFeHBlY3RlZFR5cGUocHJvcGVydHlTcGVjKSA6IHVuZGVmaW5lZCk7XG5cbiAgICAvLyBGb3Igc3RyaW5nLXZhbHVlZCBwcm9wZXJ0aWVzLCBjb2VyY2UgdG8gc3RyaW5nIGF0IHRoZSB0b3AgbGV2ZWwgcmF0aGVyIHRoYW4gYXNzZXJ0aW5nLlxuICAgIGNvbnN0IHBhcnNlZCA9IHBhcnNlci5wYXJzZShleHByZXNzaW9uLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLFxuICAgICAgICBwcm9wZXJ0eVNwZWMgJiYgcHJvcGVydHlTcGVjLnR5cGUgPT09ICdzdHJpbmcnID8ge3R5cGVBbm5vdGF0aW9uOiAnY29lcmNlJ30gOiB1bmRlZmluZWQpO1xuXG4gICAgaWYgKCFwYXJzZWQpIHtcbiAgICAgICAgYXNzZXJ0KHBhcnNlci5lcnJvcnMubGVuZ3RoID4gMCk7XG4gICAgICAgIHJldHVybiBlcnJvcihwYXJzZXIuZXJyb3JzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc3VjY2VzcyhuZXcgU3R5bGVFeHByZXNzaW9uKHBhcnNlZCwgcHJvcGVydHlTcGVjKSk7XG59XG5cbmV4cG9ydCBjbGFzcyBab29tQ29uc3RhbnRFeHByZXNzaW9uPEtpbmQ6IEV2YWx1YXRpb25LaW5kPiB7XG4gICAga2luZDogS2luZDtcbiAgICBpc1N0YXRlRGVwZW5kZW50OiBib29sZWFuO1xuICAgIF9zdHlsZUV4cHJlc3Npb246IFN0eWxlRXhwcmVzc2lvbjtcblxuICAgIGNvbnN0cnVjdG9yKGtpbmQ6IEtpbmQsIGV4cHJlc3Npb246IFN0eWxlRXhwcmVzc2lvbikge1xuICAgICAgICB0aGlzLmtpbmQgPSBraW5kO1xuICAgICAgICB0aGlzLl9zdHlsZUV4cHJlc3Npb24gPSBleHByZXNzaW9uO1xuICAgICAgICB0aGlzLmlzU3RhdGVEZXBlbmRlbnQgPSBraW5kICE9PSAoJ2NvbnN0YW50JzogRXZhbHVhdGlvbktpbmQpICYmICFpc0NvbnN0YW50LmlzU3RhdGVDb25zdGFudChleHByZXNzaW9uLmV4cHJlc3Npb24pO1xuICAgIH1cblxuICAgIGV2YWx1YXRlV2l0aG91dEVycm9ySGFuZGxpbmcoZ2xvYmFsczogR2xvYmFsUHJvcGVydGllcywgZmVhdHVyZT86IEZlYXR1cmUsIGZlYXR1cmVTdGF0ZT86IEZlYXR1cmVTdGF0ZSwgY2Fub25pY2FsPzogQ2Fub25pY2FsVGlsZUlELCBhdmFpbGFibGVJbWFnZXM/OiBBcnJheTxzdHJpbmc+LCBmb3JtYXR0ZWRTZWN0aW9uPzogRm9ybWF0dGVkU2VjdGlvbik6IGFueSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zdHlsZUV4cHJlc3Npb24uZXZhbHVhdGVXaXRob3V0RXJyb3JIYW5kbGluZyhnbG9iYWxzLCBmZWF0dXJlLCBmZWF0dXJlU3RhdGUsIGNhbm9uaWNhbCwgYXZhaWxhYmxlSW1hZ2VzLCBmb3JtYXR0ZWRTZWN0aW9uKTtcbiAgICB9XG5cbiAgICBldmFsdWF0ZShnbG9iYWxzOiBHbG9iYWxQcm9wZXJ0aWVzLCBmZWF0dXJlPzogRmVhdHVyZSwgZmVhdHVyZVN0YXRlPzogRmVhdHVyZVN0YXRlLCBjYW5vbmljYWw/OiBDYW5vbmljYWxUaWxlSUQsIGF2YWlsYWJsZUltYWdlcz86IEFycmF5PHN0cmluZz4sIGZvcm1hdHRlZFNlY3Rpb24/OiBGb3JtYXR0ZWRTZWN0aW9uKTogYW55IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0eWxlRXhwcmVzc2lvbi5ldmFsdWF0ZShnbG9iYWxzLCBmZWF0dXJlLCBmZWF0dXJlU3RhdGUsIGNhbm9uaWNhbCwgYXZhaWxhYmxlSW1hZ2VzLCBmb3JtYXR0ZWRTZWN0aW9uKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBab29tRGVwZW5kZW50RXhwcmVzc2lvbjxLaW5kOiBFdmFsdWF0aW9uS2luZD4ge1xuICAgIGtpbmQ6IEtpbmQ7XG4gICAgem9vbVN0b3BzOiBBcnJheTxudW1iZXI+O1xuICAgIGlzU3RhdGVEZXBlbmRlbnQ6IGJvb2xlYW47XG5cbiAgICBfc3R5bGVFeHByZXNzaW9uOiBTdHlsZUV4cHJlc3Npb247XG4gICAgaW50ZXJwb2xhdGlvblR5cGU6ID9JbnRlcnBvbGF0aW9uVHlwZTtcblxuICAgIGNvbnN0cnVjdG9yKGtpbmQ6IEtpbmQsIGV4cHJlc3Npb246IFN0eWxlRXhwcmVzc2lvbiwgem9vbVN0b3BzOiBBcnJheTxudW1iZXI+LCBpbnRlcnBvbGF0aW9uVHlwZT86IEludGVycG9sYXRpb25UeXBlKSB7XG4gICAgICAgIHRoaXMua2luZCA9IGtpbmQ7XG4gICAgICAgIHRoaXMuem9vbVN0b3BzID0gem9vbVN0b3BzO1xuICAgICAgICB0aGlzLl9zdHlsZUV4cHJlc3Npb24gPSBleHByZXNzaW9uO1xuICAgICAgICB0aGlzLmlzU3RhdGVEZXBlbmRlbnQgPSBraW5kICE9PSAoJ2NhbWVyYSc6IEV2YWx1YXRpb25LaW5kKSAmJiAhaXNDb25zdGFudC5pc1N0YXRlQ29uc3RhbnQoZXhwcmVzc2lvbi5leHByZXNzaW9uKTtcbiAgICAgICAgdGhpcy5pbnRlcnBvbGF0aW9uVHlwZSA9IGludGVycG9sYXRpb25UeXBlO1xuICAgIH1cblxuICAgIGV2YWx1YXRlV2l0aG91dEVycm9ySGFuZGxpbmcoZ2xvYmFsczogR2xvYmFsUHJvcGVydGllcywgZmVhdHVyZT86IEZlYXR1cmUsIGZlYXR1cmVTdGF0ZT86IEZlYXR1cmVTdGF0ZSwgY2Fub25pY2FsPzogQ2Fub25pY2FsVGlsZUlELCBhdmFpbGFibGVJbWFnZXM/OiBBcnJheTxzdHJpbmc+LCBmb3JtYXR0ZWRTZWN0aW9uPzogRm9ybWF0dGVkU2VjdGlvbik6IGFueSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zdHlsZUV4cHJlc3Npb24uZXZhbHVhdGVXaXRob3V0RXJyb3JIYW5kbGluZyhnbG9iYWxzLCBmZWF0dXJlLCBmZWF0dXJlU3RhdGUsIGNhbm9uaWNhbCwgYXZhaWxhYmxlSW1hZ2VzLCBmb3JtYXR0ZWRTZWN0aW9uKTtcbiAgICB9XG5cbiAgICBldmFsdWF0ZShnbG9iYWxzOiBHbG9iYWxQcm9wZXJ0aWVzLCBmZWF0dXJlPzogRmVhdHVyZSwgZmVhdHVyZVN0YXRlPzogRmVhdHVyZVN0YXRlLCBjYW5vbmljYWw/OiBDYW5vbmljYWxUaWxlSUQsIGF2YWlsYWJsZUltYWdlcz86IEFycmF5PHN0cmluZz4sIGZvcm1hdHRlZFNlY3Rpb24/OiBGb3JtYXR0ZWRTZWN0aW9uKTogYW55IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0eWxlRXhwcmVzc2lvbi5ldmFsdWF0ZShnbG9iYWxzLCBmZWF0dXJlLCBmZWF0dXJlU3RhdGUsIGNhbm9uaWNhbCwgYXZhaWxhYmxlSW1hZ2VzLCBmb3JtYXR0ZWRTZWN0aW9uKTtcbiAgICB9XG5cbiAgICBpbnRlcnBvbGF0aW9uRmFjdG9yKGlucHV0OiBudW1iZXIsIGxvd2VyOiBudW1iZXIsIHVwcGVyOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBpZiAodGhpcy5pbnRlcnBvbGF0aW9uVHlwZSkge1xuICAgICAgICAgICAgcmV0dXJuIEludGVycG9sYXRlLmludGVycG9sYXRpb25GYWN0b3IodGhpcy5pbnRlcnBvbGF0aW9uVHlwZSwgaW5wdXQsIGxvd2VyLCB1cHBlcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IHR5cGUgQ29uc3RhbnRFeHByZXNzaW9uID0gaW50ZXJmYWNlIHtcbiAgICBraW5kOiAnY29uc3RhbnQnLFxuICAgICtldmFsdWF0ZTogKGdsb2JhbHM6IEdsb2JhbFByb3BlcnRpZXMsIGZlYXR1cmU/OiBGZWF0dXJlLCBmZWF0dXJlU3RhdGU/OiBGZWF0dXJlU3RhdGUsIGNhbm9uaWNhbD86IENhbm9uaWNhbFRpbGVJRCwgYXZhaWxhYmxlSW1hZ2VzPzogQXJyYXk8c3RyaW5nPikgPT4gYW55LFxufVxuXG5leHBvcnQgdHlwZSBTb3VyY2VFeHByZXNzaW9uID0gaW50ZXJmYWNlIHtcbiAgICBraW5kOiAnc291cmNlJyxcbiAgICBpc1N0YXRlRGVwZW5kZW50OiBib29sZWFuLFxuICAgICtldmFsdWF0ZTogKGdsb2JhbHM6IEdsb2JhbFByb3BlcnRpZXMsIGZlYXR1cmU/OiBGZWF0dXJlLCBmZWF0dXJlU3RhdGU/OiBGZWF0dXJlU3RhdGUsIGNhbm9uaWNhbD86IENhbm9uaWNhbFRpbGVJRCwgYXZhaWxhYmxlSW1hZ2VzPzogQXJyYXk8c3RyaW5nPiwgZm9ybWF0dGVkU2VjdGlvbj86IEZvcm1hdHRlZFNlY3Rpb24pID0+IGFueSxcbn07XG5cbmV4cG9ydCB0eXBlIENhbWVyYUV4cHJlc3Npb24gPSBpbnRlcmZhY2Uge1xuICAgIGtpbmQ6ICdjYW1lcmEnLFxuICAgICtldmFsdWF0ZTogKGdsb2JhbHM6IEdsb2JhbFByb3BlcnRpZXMsIGZlYXR1cmU/OiBGZWF0dXJlLCBmZWF0dXJlU3RhdGU/OiBGZWF0dXJlU3RhdGUsIGNhbm9uaWNhbD86IENhbm9uaWNhbFRpbGVJRCwgYXZhaWxhYmxlSW1hZ2VzPzogQXJyYXk8c3RyaW5nPikgPT4gYW55LFxuICAgICtpbnRlcnBvbGF0aW9uRmFjdG9yOiAoaW5wdXQ6IG51bWJlciwgbG93ZXI6IG51bWJlciwgdXBwZXI6IG51bWJlcikgPT4gbnVtYmVyLFxuICAgIHpvb21TdG9wczogQXJyYXk8bnVtYmVyPixcbiAgICBpbnRlcnBvbGF0aW9uVHlwZTogP0ludGVycG9sYXRpb25UeXBlXG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIENvbXBvc2l0ZUV4cHJlc3Npb24ge1xuICAgIGtpbmQ6ICdjb21wb3NpdGUnO1xuICAgIGlzU3RhdGVEZXBlbmRlbnQ6IGJvb2xlYW47XG4gICAgK2V2YWx1YXRlOiAoZ2xvYmFsczogR2xvYmFsUHJvcGVydGllcywgZmVhdHVyZT86IEZlYXR1cmUsIGZlYXR1cmVTdGF0ZT86IEZlYXR1cmVTdGF0ZSwgY2Fub25pY2FsPzogQ2Fub25pY2FsVGlsZUlELCBhdmFpbGFibGVJbWFnZXM/OiBBcnJheTxzdHJpbmc+LCBmb3JtYXR0ZWRTZWN0aW9uPzogRm9ybWF0dGVkU2VjdGlvbikgPT4gYW55O1xuICAgICtpbnRlcnBvbGF0aW9uRmFjdG9yOiAoaW5wdXQ6IG51bWJlciwgbG93ZXI6IG51bWJlciwgdXBwZXI6IG51bWJlcikgPT4gbnVtYmVyO1xuICAgIHpvb21TdG9wczogQXJyYXk8bnVtYmVyPjtcbiAgICBpbnRlcnBvbGF0aW9uVHlwZTogP0ludGVycG9sYXRpb25UeXBlO1xufVxuXG5leHBvcnQgdHlwZSBTdHlsZVByb3BlcnR5RXhwcmVzc2lvbiA9XG4gICAgfCBDb25zdGFudEV4cHJlc3Npb25cbiAgICB8IFNvdXJjZUV4cHJlc3Npb25cbiAgICB8IENhbWVyYUV4cHJlc3Npb25cbiAgICB8IENvbXBvc2l0ZUV4cHJlc3Npb247XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVQcm9wZXJ0eUV4cHJlc3Npb24oZXhwcmVzc2lvbjogbWl4ZWQsIHByb3BlcnR5U3BlYzogU3R5bGVQcm9wZXJ0eVNwZWNpZmljYXRpb24pOiBSZXN1bHQ8U3R5bGVQcm9wZXJ0eUV4cHJlc3Npb24sIEFycmF5PFBhcnNpbmdFcnJvcj4+IHtcbiAgICBleHByZXNzaW9uID0gY3JlYXRlRXhwcmVzc2lvbihleHByZXNzaW9uLCBwcm9wZXJ0eVNwZWMpO1xuICAgIGlmIChleHByZXNzaW9uLnJlc3VsdCA9PT0gJ2Vycm9yJykge1xuICAgICAgICByZXR1cm4gZXhwcmVzc2lvbjtcbiAgICB9XG5cbiAgICBjb25zdCBwYXJzZWQgPSBleHByZXNzaW9uLnZhbHVlLmV4cHJlc3Npb247XG5cbiAgICBjb25zdCBpc0ZlYXR1cmVDb25zdGFudCA9IGlzQ29uc3RhbnQuaXNGZWF0dXJlQ29uc3RhbnQocGFyc2VkKTtcbiAgICBpZiAoIWlzRmVhdHVyZUNvbnN0YW50ICYmICFzdXBwb3J0c1Byb3BlcnR5RXhwcmVzc2lvbihwcm9wZXJ0eVNwZWMpKSB7XG4gICAgICAgIHJldHVybiBlcnJvcihbbmV3IFBhcnNpbmdFcnJvcignJywgJ2RhdGEgZXhwcmVzc2lvbnMgbm90IHN1cHBvcnRlZCcpXSk7XG4gICAgfVxuXG4gICAgY29uc3QgaXNab29tQ29uc3RhbnQgPSBpc0NvbnN0YW50LmlzR2xvYmFsUHJvcGVydHlDb25zdGFudChwYXJzZWQsIFsnem9vbScsICdwaXRjaCcsICdkaXN0YW5jZS1mcm9tLWNlbnRlciddKTtcbiAgICBpZiAoIWlzWm9vbUNvbnN0YW50ICYmICFzdXBwb3J0c1pvb21FeHByZXNzaW9uKHByb3BlcnR5U3BlYykpIHtcbiAgICAgICAgcmV0dXJuIGVycm9yKFtuZXcgUGFyc2luZ0Vycm9yKCcnLCAnem9vbSBleHByZXNzaW9ucyBub3Qgc3VwcG9ydGVkJyldKTtcbiAgICB9XG5cbiAgICBjb25zdCB6b29tQ3VydmUgPSBmaW5kWm9vbUN1cnZlKHBhcnNlZCk7XG4gICAgaWYgKCF6b29tQ3VydmUgJiYgIWlzWm9vbUNvbnN0YW50KSB7XG4gICAgICAgIHJldHVybiBlcnJvcihbbmV3IFBhcnNpbmdFcnJvcignJywgJ1wiem9vbVwiIGV4cHJlc3Npb24gbWF5IG9ubHkgYmUgdXNlZCBhcyBpbnB1dCB0byBhIHRvcC1sZXZlbCBcInN0ZXBcIiBvciBcImludGVycG9sYXRlXCIgZXhwcmVzc2lvbi4nKV0pO1xuICAgIH0gZWxzZSBpZiAoem9vbUN1cnZlIGluc3RhbmNlb2YgUGFyc2luZ0Vycm9yKSB7XG4gICAgICAgIHJldHVybiBlcnJvcihbem9vbUN1cnZlXSk7XG4gICAgfSBlbHNlIGlmICh6b29tQ3VydmUgaW5zdGFuY2VvZiBJbnRlcnBvbGF0ZSAmJiAhc3VwcG9ydHNJbnRlcnBvbGF0aW9uKHByb3BlcnR5U3BlYykpIHtcbiAgICAgICAgcmV0dXJuIGVycm9yKFtuZXcgUGFyc2luZ0Vycm9yKCcnLCAnXCJpbnRlcnBvbGF0ZVwiIGV4cHJlc3Npb25zIGNhbm5vdCBiZSB1c2VkIHdpdGggdGhpcyBwcm9wZXJ0eScpXSk7XG4gICAgfVxuXG4gICAgaWYgKCF6b29tQ3VydmUpIHtcbiAgICAgICAgcmV0dXJuIHN1Y2Nlc3MoaXNGZWF0dXJlQ29uc3RhbnQgP1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgKG5ldyBab29tQ29uc3RhbnRFeHByZXNzaW9uKCdjb25zdGFudCcsIGV4cHJlc3Npb24udmFsdWUpOiBDb25zdGFudEV4cHJlc3Npb24pIDpcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIChuZXcgWm9vbUNvbnN0YW50RXhwcmVzc2lvbignc291cmNlJywgZXhwcmVzc2lvbi52YWx1ZSk6IFNvdXJjZUV4cHJlc3Npb24pKTtcbiAgICB9XG5cbiAgICBjb25zdCBpbnRlcnBvbGF0aW9uVHlwZSA9IHpvb21DdXJ2ZSBpbnN0YW5jZW9mIEludGVycG9sYXRlID8gem9vbUN1cnZlLmludGVycG9sYXRpb24gOiB1bmRlZmluZWQ7XG5cbiAgICByZXR1cm4gc3VjY2Vzcyhpc0ZlYXR1cmVDb25zdGFudCA/XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgKG5ldyBab29tRGVwZW5kZW50RXhwcmVzc2lvbignY2FtZXJhJywgZXhwcmVzc2lvbi52YWx1ZSwgem9vbUN1cnZlLmxhYmVscywgaW50ZXJwb2xhdGlvblR5cGUpOiBDYW1lcmFFeHByZXNzaW9uKSA6XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgKG5ldyBab29tRGVwZW5kZW50RXhwcmVzc2lvbignY29tcG9zaXRlJywgZXhwcmVzc2lvbi52YWx1ZSwgem9vbUN1cnZlLmxhYmVscywgaW50ZXJwb2xhdGlvblR5cGUpOiBDb21wb3NpdGVFeHByZXNzaW9uKSk7XG59XG5cbmltcG9ydCB7aXNGdW5jdGlvbiwgY3JlYXRlRnVuY3Rpb259IGZyb20gJy4uL2Z1bmN0aW9uL2luZGV4LmpzJztcbmltcG9ydCB7Q29sb3J9IGZyb20gJy4vdmFsdWVzLmpzJztcblxuLy8gc2VyaWFsaXphdGlvbiB3cmFwcGVyIGZvciBvbGQtc3R5bGUgc3RvcCBmdW5jdGlvbnMgbm9ybWFsaXplZCB0byB0aGVcbi8vIGV4cHJlc3Npb24gaW50ZXJmYWNlXG5leHBvcnQgY2xhc3MgU3R5bGVQcm9wZXJ0eUZ1bmN0aW9uPFQ+IHtcbiAgICBfcGFyYW1ldGVyczogUHJvcGVydHlWYWx1ZVNwZWNpZmljYXRpb248VD47XG4gICAgX3NwZWNpZmljYXRpb246IFN0eWxlUHJvcGVydHlTcGVjaWZpY2F0aW9uO1xuXG4gICAga2luZDogRXZhbHVhdGlvbktpbmQ7XG4gICAgZXZhbHVhdGU6IChnbG9iYWxzOiBHbG9iYWxQcm9wZXJ0aWVzLCBmZWF0dXJlPzogRmVhdHVyZSkgPT4gYW55O1xuICAgIGludGVycG9sYXRpb25GYWN0b3I6ID8oaW5wdXQ6IG51bWJlciwgbG93ZXI6IG51bWJlciwgdXBwZXI6IG51bWJlcikgPT4gbnVtYmVyO1xuICAgIHpvb21TdG9wczogP0FycmF5PG51bWJlcj47XG5cbiAgICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzOiBQcm9wZXJ0eVZhbHVlU3BlY2lmaWNhdGlvbjxUPiwgc3BlY2lmaWNhdGlvbjogU3R5bGVQcm9wZXJ0eVNwZWNpZmljYXRpb24pIHtcbiAgICAgICAgdGhpcy5fcGFyYW1ldGVycyA9IHBhcmFtZXRlcnM7XG4gICAgICAgIHRoaXMuX3NwZWNpZmljYXRpb24gPSBzcGVjaWZpY2F0aW9uO1xuICAgICAgICBleHRlbmQodGhpcywgY3JlYXRlRnVuY3Rpb24odGhpcy5fcGFyYW1ldGVycywgdGhpcy5fc3BlY2lmaWNhdGlvbikpO1xuICAgIH1cblxuICAgIHN0YXRpYyBkZXNlcmlhbGl6ZShzZXJpYWxpemVkOiB7X3BhcmFtZXRlcnM6IFByb3BlcnR5VmFsdWVTcGVjaWZpY2F0aW9uPFQ+LCBfc3BlY2lmaWNhdGlvbjogU3R5bGVQcm9wZXJ0eVNwZWNpZmljYXRpb259KTogU3R5bGVQcm9wZXJ0eUZ1bmN0aW9uPFQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBTdHlsZVByb3BlcnR5RnVuY3Rpb24oc2VyaWFsaXplZC5fcGFyYW1ldGVycywgc2VyaWFsaXplZC5fc3BlY2lmaWNhdGlvbik7XG4gICAgfVxuXG4gICAgc3RhdGljIHNlcmlhbGl6ZShpbnB1dDogU3R5bGVQcm9wZXJ0eUZ1bmN0aW9uPFQ+KToge19wYXJhbWV0ZXJzOiBQcm9wZXJ0eVZhbHVlU3BlY2lmaWNhdGlvbjxUPiwgX3NwZWNpZmljYXRpb246IFN0eWxlUHJvcGVydHlTcGVjaWZpY2F0aW9ufSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBfcGFyYW1ldGVyczogaW5wdXQuX3BhcmFtZXRlcnMsXG4gICAgICAgICAgICBfc3BlY2lmaWNhdGlvbjogaW5wdXQuX3NwZWNpZmljYXRpb25cbiAgICAgICAgfTtcbiAgICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVQcm9wZXJ0eUV4cHJlc3Npb248VD4odmFsdWU6IFByb3BlcnR5VmFsdWVTcGVjaWZpY2F0aW9uPFQ+LCBzcGVjaWZpY2F0aW9uOiBTdHlsZVByb3BlcnR5U3BlY2lmaWNhdGlvbik6IFN0eWxlUHJvcGVydHlFeHByZXNzaW9uIHtcbiAgICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIChuZXcgU3R5bGVQcm9wZXJ0eUZ1bmN0aW9uKHZhbHVlLCBzcGVjaWZpY2F0aW9uKTogYW55KTtcblxuICAgIH0gZWxzZSBpZiAoaXNFeHByZXNzaW9uKHZhbHVlKSkge1xuICAgICAgICBjb25zdCBleHByZXNzaW9uID0gY3JlYXRlUHJvcGVydHlFeHByZXNzaW9uKHZhbHVlLCBzcGVjaWZpY2F0aW9uKTtcbiAgICAgICAgaWYgKGV4cHJlc3Npb24ucmVzdWx0ID09PSAnZXJyb3InKSB7XG4gICAgICAgICAgICAvLyB0aGlzIHNob3VsZCBoYXZlIGJlZW4gY2F1Z2h0IGluIHZhbGlkYXRpb25cbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHByZXNzaW9uLnZhbHVlLm1hcChlcnIgPT4gYCR7ZXJyLmtleX06ICR7ZXJyLm1lc3NhZ2V9YCkuam9pbignLCAnKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGV4cHJlc3Npb24udmFsdWU7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgICBsZXQgY29uc3RhbnQ6IGFueSA9IHZhbHVlO1xuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiBzcGVjaWZpY2F0aW9uLnR5cGUgPT09ICdjb2xvcicpIHtcbiAgICAgICAgICAgIGNvbnN0YW50ID0gQ29sb3IucGFyc2UodmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBraW5kOiAnY29uc3RhbnQnLFxuICAgICAgICAgICAgZXZhbHVhdGU6ICgpID0+IGNvbnN0YW50XG4gICAgICAgIH07XG4gICAgfVxufVxuXG4vLyBab29tLWRlcGVuZGVudCBleHByZXNzaW9ucyBtYXkgb25seSB1c2UgW1wiem9vbVwiXSBhcyB0aGUgaW5wdXQgdG8gYSB0b3AtbGV2ZWwgXCJzdGVwXCIgb3IgXCJpbnRlcnBvbGF0ZVwiXG4vLyBleHByZXNzaW9uIChjb2xsZWN0aXZlbHkgcmVmZXJyZWQgdG8gYXMgYSBcImN1cnZlXCIpLiBUaGUgY3VydmUgbWF5IGJlIHdyYXBwZWQgaW4gb25lIG9yIG1vcmUgXCJsZXRcIiBvclxuLy8gXCJjb2FsZXNjZVwiIGV4cHJlc3Npb25zLlxuZnVuY3Rpb24gZmluZFpvb21DdXJ2ZShleHByZXNzaW9uOiBFeHByZXNzaW9uKTogU3RlcCB8IEludGVycG9sYXRlIHwgUGFyc2luZ0Vycm9yIHwgbnVsbCB7XG4gICAgbGV0IHJlc3VsdCA9IG51bGw7XG4gICAgaWYgKGV4cHJlc3Npb24gaW5zdGFuY2VvZiBMZXQpIHtcbiAgICAgICAgcmVzdWx0ID0gZmluZFpvb21DdXJ2ZShleHByZXNzaW9uLnJlc3VsdCk7XG5cbiAgICB9IGVsc2UgaWYgKGV4cHJlc3Npb24gaW5zdGFuY2VvZiBDb2FsZXNjZSkge1xuICAgICAgICBmb3IgKGNvbnN0IGFyZyBvZiBleHByZXNzaW9uLmFyZ3MpIHtcbiAgICAgICAgICAgIHJlc3VsdCA9IGZpbmRab29tQ3VydmUoYXJnKTtcbiAgICAgICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgfSBlbHNlIGlmICgoZXhwcmVzc2lvbiBpbnN0YW5jZW9mIFN0ZXAgfHwgZXhwcmVzc2lvbiBpbnN0YW5jZW9mIEludGVycG9sYXRlKSAmJlxuICAgICAgICBleHByZXNzaW9uLmlucHV0IGluc3RhbmNlb2YgQ29tcG91bmRFeHByZXNzaW9uICYmXG4gICAgICAgIGV4cHJlc3Npb24uaW5wdXQubmFtZSA9PT0gJ3pvb20nKSB7XG5cbiAgICAgICAgcmVzdWx0ID0gZXhwcmVzc2lvbjtcbiAgICB9XG5cbiAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUGFyc2luZ0Vycm9yKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgZXhwcmVzc2lvbi5lYWNoQ2hpbGQoKGNoaWxkKSA9PiB7XG4gICAgICAgIGNvbnN0IGNoaWxkUmVzdWx0ID0gZmluZFpvb21DdXJ2ZShjaGlsZCk7XG4gICAgICAgIGlmIChjaGlsZFJlc3VsdCBpbnN0YW5jZW9mIFBhcnNpbmdFcnJvcikge1xuICAgICAgICAgICAgcmVzdWx0ID0gY2hpbGRSZXN1bHQ7XG4gICAgICAgIH0gZWxzZSBpZiAoIXJlc3VsdCAmJiBjaGlsZFJlc3VsdCkge1xuICAgICAgICAgICAgcmVzdWx0ID0gbmV3IFBhcnNpbmdFcnJvcignJywgJ1wiem9vbVwiIGV4cHJlc3Npb24gbWF5IG9ubHkgYmUgdXNlZCBhcyBpbnB1dCB0byBhIHRvcC1sZXZlbCBcInN0ZXBcIiBvciBcImludGVycG9sYXRlXCIgZXhwcmVzc2lvbi4nKTtcbiAgICAgICAgfSBlbHNlIGlmIChyZXN1bHQgJiYgY2hpbGRSZXN1bHQgJiYgcmVzdWx0ICE9PSBjaGlsZFJlc3VsdCkge1xuICAgICAgICAgICAgcmVzdWx0ID0gbmV3IFBhcnNpbmdFcnJvcignJywgJ09ubHkgb25lIHpvb20tYmFzZWQgXCJzdGVwXCIgb3IgXCJpbnRlcnBvbGF0ZVwiIHN1YmV4cHJlc3Npb24gbWF5IGJlIHVzZWQgaW4gYW4gZXhwcmVzc2lvbi4nKTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuaW1wb3J0IHtDb2xvclR5cGUsIFN0cmluZ1R5cGUsIE51bWJlclR5cGUsIEJvb2xlYW5UeXBlLCBWYWx1ZVR5cGUsIEZvcm1hdHRlZFR5cGUsIFJlc29sdmVkSW1hZ2VUeXBlLCBhcnJheX0gZnJvbSAnLi90eXBlcy5qcyc7XG5cbmZ1bmN0aW9uIGdldEV4cGVjdGVkVHlwZShzcGVjOiBTdHlsZVByb3BlcnR5U3BlY2lmaWNhdGlvbik6IFR5cGUge1xuICAgIGNvbnN0IHR5cGVzID0ge1xuICAgICAgICBjb2xvcjogQ29sb3JUeXBlLFxuICAgICAgICBzdHJpbmc6IFN0cmluZ1R5cGUsXG4gICAgICAgIG51bWJlcjogTnVtYmVyVHlwZSxcbiAgICAgICAgZW51bTogU3RyaW5nVHlwZSxcbiAgICAgICAgYm9vbGVhbjogQm9vbGVhblR5cGUsXG4gICAgICAgIGZvcm1hdHRlZDogRm9ybWF0dGVkVHlwZSxcbiAgICAgICAgcmVzb2x2ZWRJbWFnZTogUmVzb2x2ZWRJbWFnZVR5cGVcbiAgICB9O1xuXG4gICAgaWYgKHNwZWMudHlwZSA9PT0gJ2FycmF5Jykge1xuICAgICAgICByZXR1cm4gYXJyYXkodHlwZXNbc3BlYy52YWx1ZV0gfHwgVmFsdWVUeXBlLCBzcGVjLmxlbmd0aCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHR5cGVzW3NwZWMudHlwZV07XG59XG5cbmZ1bmN0aW9uIGdldERlZmF1bHRWYWx1ZShzcGVjOiBTdHlsZVByb3BlcnR5U3BlY2lmaWNhdGlvbik6IFZhbHVlIHtcbiAgICBpZiAoc3BlYy50eXBlID09PSAnY29sb3InICYmIChpc0Z1bmN0aW9uKHNwZWMuZGVmYXVsdCkgfHwgQXJyYXkuaXNBcnJheShzcGVjLmRlZmF1bHQpKSkge1xuICAgICAgICAvLyBTcGVjaWFsIGNhc2UgZm9yIGhlYXRtYXAtY29sb3I6IGl0IHVzZXMgdGhlICdkZWZhdWx0OicgdG8gZGVmaW5lIGFcbiAgICAgICAgLy8gZGVmYXVsdCBjb2xvciByYW1wLCBidXQgY3JlYXRlRXhwcmVzc2lvbiBleHBlY3RzIGEgc2ltcGxlIHZhbHVlIHRvIGZhbGxcbiAgICAgICAgLy8gYmFjayB0byBpbiBjYXNlIG9mIHJ1bnRpbWUgZXJyb3JzXG4gICAgICAgIHJldHVybiBuZXcgQ29sb3IoMCwgMCwgMCwgMCk7XG4gICAgfSBlbHNlIGlmIChzcGVjLnR5cGUgPT09ICdjb2xvcicpIHtcbiAgICAgICAgcmV0dXJuIENvbG9yLnBhcnNlKHNwZWMuZGVmYXVsdCkgfHwgbnVsbDtcbiAgICB9IGVsc2UgaWYgKHNwZWMuZGVmYXVsdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBzcGVjLmRlZmF1bHQ7XG4gICAgfVxufVxuIiwiLy8gQGZsb3dcblxuLy8gTm90ZTogRG8gbm90IGluaGVyaXQgZnJvbSBFcnJvci4gSXQgYnJlYWtzIHdoZW4gdHJhbnNwaWxpbmcgdG8gRVM1LlxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWYWxpZGF0aW9uRXJyb3Ige1xuICAgIG1lc3NhZ2U6IHN0cmluZztcbiAgICBpZGVudGlmaWVyOiA/c3RyaW5nO1xuICAgIGxpbmU6ID9udW1iZXI7XG5cbiAgICBjb25zdHJ1Y3RvcihrZXk6ID9zdHJpbmcsIHZhbHVlOiA/eyBfX2xpbmVfXzogbnVtYmVyIH0sIG1lc3NhZ2U6IHN0cmluZywgaWRlbnRpZmllcjogP3N0cmluZykge1xuICAgICAgICB0aGlzLm1lc3NhZ2UgPSAoa2V5ID8gYCR7a2V5fTogYCA6ICcnKSArIG1lc3NhZ2U7XG4gICAgICAgIGlmIChpZGVudGlmaWVyKSB0aGlzLmlkZW50aWZpZXIgPSBpZGVudGlmaWVyO1xuXG4gICAgICAgIGlmICh2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlLl9fbGluZV9fKSB7XG4gICAgICAgICAgICB0aGlzLmxpbmUgPSB2YWx1ZS5fX2xpbmVfXztcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBWYWxpZGF0aW9uRXJyb3IgZnJvbSAnLi4vZXJyb3IvdmFsaWRhdGlvbl9lcnJvci5qcyc7XG5pbXBvcnQgZ2V0VHlwZSBmcm9tICcuLi91dGlsL2dldF90eXBlLmpzJztcbmltcG9ydCB2YWxpZGF0ZVNwZWMgZnJvbSAnLi92YWxpZGF0ZS5qcyc7XG5cbmltcG9ydCB0eXBlIHtWYWxpZGF0aW9uT3B0aW9uc30gZnJvbSAnLi92YWxpZGF0ZS5qcyc7XG5cbnR5cGUgT3B0aW9ucyA9IFZhbGlkYXRpb25PcHRpb25zICYge1xuICAgIG9iamVjdEVsZW1lbnRWYWxpZGF0b3JzPzogRnVuY3Rpb247XG59O1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB2YWxpZGF0ZU9iamVjdChvcHRpb25zOiBPcHRpb25zKTogQXJyYXk8VmFsaWRhdGlvbkVycm9yPiB7XG4gICAgY29uc3Qga2V5ID0gb3B0aW9ucy5rZXk7XG4gICAgY29uc3Qgb2JqZWN0ID0gb3B0aW9ucy52YWx1ZTtcbiAgICBjb25zdCBlbGVtZW50U3BlY3MgPSBvcHRpb25zLnZhbHVlU3BlYyB8fCB7fTtcbiAgICBjb25zdCBlbGVtZW50VmFsaWRhdG9ycyA9IG9wdGlvbnMub2JqZWN0RWxlbWVudFZhbGlkYXRvcnMgfHwge307XG4gICAgY29uc3Qgc3R5bGUgPSBvcHRpb25zLnN0eWxlO1xuICAgIGNvbnN0IHN0eWxlU3BlYyA9IG9wdGlvbnMuc3R5bGVTcGVjO1xuICAgIGxldCBlcnJvcnMgPSBbXTtcblxuICAgIGNvbnN0IHR5cGUgPSBnZXRUeXBlKG9iamVjdCk7XG4gICAgaWYgKHR5cGUgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBbbmV3IFZhbGlkYXRpb25FcnJvcihrZXksIG9iamVjdCwgYG9iamVjdCBleHBlY3RlZCwgJHt0eXBlfSBmb3VuZGApXTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IG9iamVjdEtleSBpbiBvYmplY3QpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudFNwZWNLZXkgPSBvYmplY3RLZXkuc3BsaXQoJy4nKVswXTsgLy8gdHJlYXQgJ3BhaW50LionIGFzICdwYWludCdcbiAgICAgICAgY29uc3QgZWxlbWVudFNwZWMgPSBlbGVtZW50U3BlY3NbZWxlbWVudFNwZWNLZXldIHx8IGVsZW1lbnRTcGVjc1snKiddO1xuXG4gICAgICAgIGxldCB2YWxpZGF0ZUVsZW1lbnQ7XG4gICAgICAgIGlmIChlbGVtZW50VmFsaWRhdG9yc1tlbGVtZW50U3BlY0tleV0pIHtcbiAgICAgICAgICAgIHZhbGlkYXRlRWxlbWVudCA9IGVsZW1lbnRWYWxpZGF0b3JzW2VsZW1lbnRTcGVjS2V5XTtcbiAgICAgICAgfSBlbHNlIGlmIChlbGVtZW50U3BlY3NbZWxlbWVudFNwZWNLZXldKSB7XG4gICAgICAgICAgICB2YWxpZGF0ZUVsZW1lbnQgPSB2YWxpZGF0ZVNwZWM7XG4gICAgICAgIH0gZWxzZSBpZiAoZWxlbWVudFZhbGlkYXRvcnNbJyonXSkge1xuICAgICAgICAgICAgdmFsaWRhdGVFbGVtZW50ID0gZWxlbWVudFZhbGlkYXRvcnNbJyonXTtcbiAgICAgICAgfSBlbHNlIGlmIChlbGVtZW50U3BlY3NbJyonXSkge1xuICAgICAgICAgICAgdmFsaWRhdGVFbGVtZW50ID0gdmFsaWRhdGVTcGVjO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF2YWxpZGF0ZUVsZW1lbnQpIHtcbiAgICAgICAgICAgIGVycm9ycy5wdXNoKG5ldyBWYWxpZGF0aW9uRXJyb3Ioa2V5LCBvYmplY3Rbb2JqZWN0S2V5XSwgYHVua25vd24gcHJvcGVydHkgXCIke29iamVjdEtleX1cImApKTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgZXJyb3JzID0gZXJyb3JzLmNvbmNhdCh2YWxpZGF0ZUVsZW1lbnQoe1xuICAgICAgICAgICAga2V5OiAoa2V5ID8gYCR7a2V5fS5gIDoga2V5KSArIG9iamVjdEtleSxcbiAgICAgICAgICAgIHZhbHVlOiBvYmplY3Rbb2JqZWN0S2V5XSxcbiAgICAgICAgICAgIHZhbHVlU3BlYzogZWxlbWVudFNwZWMsXG4gICAgICAgICAgICBzdHlsZSxcbiAgICAgICAgICAgIHN0eWxlU3BlYyxcbiAgICAgICAgICAgIG9iamVjdCxcbiAgICAgICAgICAgIG9iamVjdEtleVxuICAgICAgICAvLyAkRmxvd0ZpeE1lW2V4dHJhLWFyZ11cbiAgICAgICAgfSwgb2JqZWN0KSk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBlbGVtZW50U3BlY0tleSBpbiBlbGVtZW50U3BlY3MpIHtcbiAgICAgICAgLy8gRG9uJ3QgY2hlY2sgYHJlcXVpcmVkYCB3aGVuIHRoZXJlJ3MgYSBjdXN0b20gdmFsaWRhdG9yIGZvciB0aGF0IHByb3BlcnR5LlxuICAgICAgICBpZiAoZWxlbWVudFZhbGlkYXRvcnNbZWxlbWVudFNwZWNLZXldKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbGVtZW50U3BlY3NbZWxlbWVudFNwZWNLZXldLnJlcXVpcmVkICYmIGVsZW1lbnRTcGVjc1tlbGVtZW50U3BlY0tleV1bJ2RlZmF1bHQnXSA9PT0gdW5kZWZpbmVkICYmIG9iamVjdFtlbGVtZW50U3BlY0tleV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgZXJyb3JzLnB1c2gobmV3IFZhbGlkYXRpb25FcnJvcihrZXksIG9iamVjdCwgYG1pc3NpbmcgcmVxdWlyZWQgcHJvcGVydHkgXCIke2VsZW1lbnRTcGVjS2V5fVwiYCkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGVycm9ycztcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBnZXRUeXBlIGZyb20gJy4uL3V0aWwvZ2V0X3R5cGUuanMnO1xuaW1wb3J0IHZhbGlkYXRlIGZyb20gJy4vdmFsaWRhdGUuanMnO1xuaW1wb3J0IFZhbGlkYXRpb25FcnJvciBmcm9tICcuLi9lcnJvci92YWxpZGF0aW9uX2Vycm9yLmpzJztcblxuaW1wb3J0IHR5cGUge1ZhbGlkYXRpb25PcHRpb25zfSBmcm9tICcuL3ZhbGlkYXRlLmpzJztcblxudHlwZSBPcHRpb25zID0gVmFsaWRhdGlvbk9wdGlvbnMgJiB7XG4gICAgYXJyYXlFbGVtZW50VmFsaWRhdG9yOiBGdW5jdGlvbjtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHZhbGlkYXRlQXJyYXkob3B0aW9uczogT3B0aW9ucyk6IEFycmF5PFZhbGlkYXRpb25FcnJvcj4ge1xuICAgIGNvbnN0IGFycmF5ID0gb3B0aW9ucy52YWx1ZTtcbiAgICBjb25zdCBhcnJheVNwZWMgPSBvcHRpb25zLnZhbHVlU3BlYztcbiAgICBjb25zdCBzdHlsZSA9IG9wdGlvbnMuc3R5bGU7XG4gICAgY29uc3Qgc3R5bGVTcGVjID0gb3B0aW9ucy5zdHlsZVNwZWM7XG4gICAgY29uc3Qga2V5ID0gb3B0aW9ucy5rZXk7XG4gICAgY29uc3QgdmFsaWRhdGVBcnJheUVsZW1lbnQgPSBvcHRpb25zLmFycmF5RWxlbWVudFZhbGlkYXRvciB8fCB2YWxpZGF0ZTtcblxuICAgIGlmIChnZXRUeXBlKGFycmF5KSAhPT0gJ2FycmF5Jykge1xuICAgICAgICByZXR1cm4gW25ldyBWYWxpZGF0aW9uRXJyb3Ioa2V5LCBhcnJheSwgYGFycmF5IGV4cGVjdGVkLCAke2dldFR5cGUoYXJyYXkpfSBmb3VuZGApXTtcbiAgICB9XG5cbiAgICBpZiAoYXJyYXlTcGVjLmxlbmd0aCAmJiBhcnJheS5sZW5ndGggIT09IGFycmF5U3BlYy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIFtuZXcgVmFsaWRhdGlvbkVycm9yKGtleSwgYXJyYXksIGBhcnJheSBsZW5ndGggJHthcnJheVNwZWMubGVuZ3RofSBleHBlY3RlZCwgbGVuZ3RoICR7YXJyYXkubGVuZ3RofSBmb3VuZGApXTtcbiAgICB9XG5cbiAgICBpZiAoYXJyYXlTcGVjWydtaW4tbGVuZ3RoJ10gJiYgYXJyYXkubGVuZ3RoIDwgYXJyYXlTcGVjWydtaW4tbGVuZ3RoJ10pIHtcbiAgICAgICAgcmV0dXJuIFtuZXcgVmFsaWRhdGlvbkVycm9yKGtleSwgYXJyYXksIGBhcnJheSBsZW5ndGggYXQgbGVhc3QgJHthcnJheVNwZWNbJ21pbi1sZW5ndGgnXX0gZXhwZWN0ZWQsIGxlbmd0aCAke2FycmF5Lmxlbmd0aH0gZm91bmRgKV07XG4gICAgfVxuXG4gICAgbGV0IGFycmF5RWxlbWVudFNwZWMgPSB7XG4gICAgICAgIFwidHlwZVwiOiBhcnJheVNwZWMudmFsdWUsXG4gICAgICAgIFwidmFsdWVzXCI6IGFycmF5U3BlYy52YWx1ZXMsXG4gICAgICAgIFwibWluaW11bVwiOiBhcnJheVNwZWMubWluaW11bSxcbiAgICAgICAgXCJtYXhpbXVtXCI6IGFycmF5U3BlYy5tYXhpbXVtLFxuICAgICAgICBmdW5jdGlvbjogdW5kZWZpbmVkXG4gICAgfTtcblxuICAgIGlmIChzdHlsZVNwZWMuJHZlcnNpb24gPCA3KSB7XG4gICAgICAgIGFycmF5RWxlbWVudFNwZWMuZnVuY3Rpb24gPSBhcnJheVNwZWMuZnVuY3Rpb247XG4gICAgfVxuXG4gICAgaWYgKGdldFR5cGUoYXJyYXlTcGVjLnZhbHVlKSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgYXJyYXlFbGVtZW50U3BlYyA9IGFycmF5U3BlYy52YWx1ZTtcbiAgICB9XG5cbiAgICBsZXQgZXJyb3JzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICBlcnJvcnMgPSBlcnJvcnMuY29uY2F0KHZhbGlkYXRlQXJyYXlFbGVtZW50KHtcbiAgICAgICAgICAgIGFycmF5LFxuICAgICAgICAgICAgYXJyYXlJbmRleDogaSxcbiAgICAgICAgICAgIHZhbHVlOiBhcnJheVtpXSxcbiAgICAgICAgICAgIHZhbHVlU3BlYzogYXJyYXlFbGVtZW50U3BlYyxcbiAgICAgICAgICAgIHN0eWxlLFxuICAgICAgICAgICAgc3R5bGVTcGVjLFxuICAgICAgICAgICAga2V5OiBgJHtrZXl9WyR7aX1dYFxuICAgICAgICB9KSk7XG4gICAgfVxuICAgIHJldHVybiBlcnJvcnM7XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgZ2V0VHlwZSBmcm9tICcuLi91dGlsL2dldF90eXBlLmpzJztcbmltcG9ydCBWYWxpZGF0aW9uRXJyb3IgZnJvbSAnLi4vZXJyb3IvdmFsaWRhdGlvbl9lcnJvci5qcyc7XG5cbmltcG9ydCB0eXBlIHtWYWxpZGF0aW9uT3B0aW9uc30gZnJvbSAnLi92YWxpZGF0ZS5qcyc7XG5cbnR5cGUgT3B0aW9ucyA9IFZhbGlkYXRpb25PcHRpb25zICYge1xuICAgIGFycmF5SW5kZXg6IG51bWJlcjtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdmFsaWRhdGVOdW1iZXIob3B0aW9uczogT3B0aW9ucyk6IEFycmF5PFZhbGlkYXRpb25FcnJvcj4ge1xuICAgIGNvbnN0IGtleSA9IG9wdGlvbnMua2V5O1xuICAgIGNvbnN0IHZhbHVlID0gb3B0aW9ucy52YWx1ZTtcbiAgICBjb25zdCB2YWx1ZVNwZWMgPSBvcHRpb25zLnZhbHVlU3BlYztcbiAgICBsZXQgdHlwZSA9IGdldFR5cGUodmFsdWUpO1xuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNlbGYtY29tcGFyZVxuICAgIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiB2YWx1ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgdHlwZSA9ICdOYU4nO1xuICAgIH1cblxuICAgIGlmICh0eXBlICE9PSAnbnVtYmVyJykge1xuICAgICAgICByZXR1cm4gW25ldyBWYWxpZGF0aW9uRXJyb3Ioa2V5LCB2YWx1ZSwgYG51bWJlciBleHBlY3RlZCwgJHt0eXBlfSBmb3VuZGApXTtcbiAgICB9XG5cbiAgICBpZiAoJ21pbmltdW0nIGluIHZhbHVlU3BlYykge1xuICAgICAgICBsZXQgc3BlY01pbiA9IHZhbHVlU3BlYy5taW5pbXVtO1xuICAgICAgICBpZiAoZ2V0VHlwZSh2YWx1ZVNwZWMubWluaW11bSkgPT09ICdhcnJheScpIHtcbiAgICAgICAgICAgIGNvbnN0IGkgPSBvcHRpb25zLmFycmF5SW5kZXg7XG4gICAgICAgICAgICBzcGVjTWluID0gdmFsdWVTcGVjLm1pbmltdW1baV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZhbHVlIDwgc3BlY01pbikge1xuICAgICAgICAgICAgcmV0dXJuIFtuZXcgVmFsaWRhdGlvbkVycm9yKGtleSwgdmFsdWUsIGAke3ZhbHVlfSBpcyBsZXNzIHRoYW4gdGhlIG1pbmltdW0gdmFsdWUgJHtzcGVjTWlufWApXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmICgnbWF4aW11bScgaW4gdmFsdWVTcGVjKSB7XG4gICAgICAgIGxldCBzcGVjTWF4ID0gdmFsdWVTcGVjLm1heGltdW07XG4gICAgICAgIGlmIChnZXRUeXBlKHZhbHVlU3BlYy5tYXhpbXVtKSA9PT0gJ2FycmF5Jykge1xuICAgICAgICAgICAgY29uc3QgaSA9IG9wdGlvbnMuYXJyYXlJbmRleDtcbiAgICAgICAgICAgIHNwZWNNYXggPSB2YWx1ZVNwZWMubWF4aW11bVtpXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodmFsdWUgPiBzcGVjTWF4KSB7XG4gICAgICAgICAgICByZXR1cm4gW25ldyBWYWxpZGF0aW9uRXJyb3Ioa2V5LCB2YWx1ZSwgYCR7dmFsdWV9IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbWF4aW11bSB2YWx1ZSAke3NwZWNNYXh9YCldO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIFtdO1xufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IFZhbGlkYXRpb25FcnJvciBmcm9tICcuLi9lcnJvci92YWxpZGF0aW9uX2Vycm9yLmpzJztcbmltcG9ydCBnZXRUeXBlIGZyb20gJy4uL3V0aWwvZ2V0X3R5cGUuanMnO1xuaW1wb3J0IHZhbGlkYXRlIGZyb20gJy4vdmFsaWRhdGUuanMnO1xuaW1wb3J0IHZhbGlkYXRlT2JqZWN0IGZyb20gJy4vdmFsaWRhdGVfb2JqZWN0LmpzJztcbmltcG9ydCB2YWxpZGF0ZUFycmF5IGZyb20gJy4vdmFsaWRhdGVfYXJyYXkuanMnO1xuaW1wb3J0IHZhbGlkYXRlTnVtYmVyIGZyb20gJy4vdmFsaWRhdGVfbnVtYmVyLmpzJztcbmltcG9ydCB7aXNFeHByZXNzaW9ufSBmcm9tICcuLi9leHByZXNzaW9uL2luZGV4LmpzJztcbmltcG9ydCB7dW5idW5kbGUsIGRlZXBVbmJ1bmRsZX0gZnJvbSAnLi4vdXRpbC91bmJ1bmRsZV9qc29ubGludC5qcyc7XG5pbXBvcnQge1xuICAgIHN1cHBvcnRzUHJvcGVydHlFeHByZXNzaW9uLFxuICAgIHN1cHBvcnRzWm9vbUV4cHJlc3Npb24sXG4gICAgc3VwcG9ydHNJbnRlcnBvbGF0aW9uXG59IGZyb20gJy4uL3V0aWwvcHJvcGVydGllcy5qcyc7XG5cbmltcG9ydCB0eXBlIHtWYWxpZGF0aW9uT3B0aW9uc30gZnJvbSAnLi92YWxpZGF0ZS5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHZhbGlkYXRlRnVuY3Rpb24ob3B0aW9uczogVmFsaWRhdGlvbk9wdGlvbnMpOiBhbnkge1xuICAgIGNvbnN0IGZ1bmN0aW9uVmFsdWVTcGVjID0gb3B0aW9ucy52YWx1ZVNwZWM7XG4gICAgY29uc3QgZnVuY3Rpb25UeXBlID0gdW5idW5kbGUob3B0aW9ucy52YWx1ZS50eXBlKTtcbiAgICBsZXQgc3RvcEtleVR5cGU7XG4gICAgbGV0IHN0b3BEb21haW5WYWx1ZXM6IHtbc3RyaW5nIHwgbnVtYmVyXTogYm9vbGVhbn0gPSB7fTtcbiAgICBsZXQgcHJldmlvdXNTdG9wRG9tYWluVmFsdWU6ID9taXhlZDtcbiAgICBsZXQgcHJldmlvdXNTdG9wRG9tYWluWm9vbTtcblxuICAgIGNvbnN0IGlzWm9vbUZ1bmN0aW9uID0gZnVuY3Rpb25UeXBlICE9PSAnY2F0ZWdvcmljYWwnICYmIG9wdGlvbnMudmFsdWUucHJvcGVydHkgPT09IHVuZGVmaW5lZDtcbiAgICBjb25zdCBpc1Byb3BlcnR5RnVuY3Rpb24gPSAhaXNab29tRnVuY3Rpb247XG4gICAgY29uc3QgaXNab29tQW5kUHJvcGVydHlGdW5jdGlvbiA9XG4gICAgICAgIGdldFR5cGUob3B0aW9ucy52YWx1ZS5zdG9wcykgPT09ICdhcnJheScgJiZcbiAgICAgICAgZ2V0VHlwZShvcHRpb25zLnZhbHVlLnN0b3BzWzBdKSA9PT0gJ2FycmF5JyAmJlxuICAgICAgICBnZXRUeXBlKG9wdGlvbnMudmFsdWUuc3RvcHNbMF1bMF0pID09PSAnb2JqZWN0JztcblxuICAgIGNvbnN0IGVycm9ycyA9IHZhbGlkYXRlT2JqZWN0KHtcbiAgICAgICAga2V5OiBvcHRpb25zLmtleSxcbiAgICAgICAgdmFsdWU6IG9wdGlvbnMudmFsdWUsXG4gICAgICAgIHZhbHVlU3BlYzogb3B0aW9ucy5zdHlsZVNwZWMuZnVuY3Rpb24sXG4gICAgICAgIHN0eWxlOiBvcHRpb25zLnN0eWxlLFxuICAgICAgICBzdHlsZVNwZWM6IG9wdGlvbnMuc3R5bGVTcGVjLFxuICAgICAgICBvYmplY3RFbGVtZW50VmFsaWRhdG9yczoge1xuICAgICAgICAgICAgc3RvcHM6IHZhbGlkYXRlRnVuY3Rpb25TdG9wcyxcbiAgICAgICAgICAgIGRlZmF1bHQ6IHZhbGlkYXRlRnVuY3Rpb25EZWZhdWx0XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmIChmdW5jdGlvblR5cGUgPT09ICdpZGVudGl0eScgJiYgaXNab29tRnVuY3Rpb24pIHtcbiAgICAgICAgZXJyb3JzLnB1c2gobmV3IFZhbGlkYXRpb25FcnJvcihvcHRpb25zLmtleSwgb3B0aW9ucy52YWx1ZSwgJ21pc3NpbmcgcmVxdWlyZWQgcHJvcGVydHkgXCJwcm9wZXJ0eVwiJykpO1xuICAgIH1cblxuICAgIGlmIChmdW5jdGlvblR5cGUgIT09ICdpZGVudGl0eScgJiYgIW9wdGlvbnMudmFsdWUuc3RvcHMpIHtcbiAgICAgICAgZXJyb3JzLnB1c2gobmV3IFZhbGlkYXRpb25FcnJvcihvcHRpb25zLmtleSwgb3B0aW9ucy52YWx1ZSwgJ21pc3NpbmcgcmVxdWlyZWQgcHJvcGVydHkgXCJzdG9wc1wiJykpO1xuICAgIH1cblxuICAgIGlmIChmdW5jdGlvblR5cGUgPT09ICdleHBvbmVudGlhbCcgJiYgb3B0aW9ucy52YWx1ZVNwZWMuZXhwcmVzc2lvbiAmJiAhc3VwcG9ydHNJbnRlcnBvbGF0aW9uKG9wdGlvbnMudmFsdWVTcGVjKSkge1xuICAgICAgICBlcnJvcnMucHVzaChuZXcgVmFsaWRhdGlvbkVycm9yKG9wdGlvbnMua2V5LCBvcHRpb25zLnZhbHVlLCAnZXhwb25lbnRpYWwgZnVuY3Rpb25zIG5vdCBzdXBwb3J0ZWQnKSk7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMuc3R5bGVTcGVjLiR2ZXJzaW9uID49IDgpIHtcbiAgICAgICAgaWYgKGlzUHJvcGVydHlGdW5jdGlvbiAmJiAhc3VwcG9ydHNQcm9wZXJ0eUV4cHJlc3Npb24ob3B0aW9ucy52YWx1ZVNwZWMpKSB7XG4gICAgICAgICAgICBlcnJvcnMucHVzaChuZXcgVmFsaWRhdGlvbkVycm9yKG9wdGlvbnMua2V5LCBvcHRpb25zLnZhbHVlLCAncHJvcGVydHkgZnVuY3Rpb25zIG5vdCBzdXBwb3J0ZWQnKSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNab29tRnVuY3Rpb24gJiYgIXN1cHBvcnRzWm9vbUV4cHJlc3Npb24ob3B0aW9ucy52YWx1ZVNwZWMpKSB7XG4gICAgICAgICAgICBlcnJvcnMucHVzaChuZXcgVmFsaWRhdGlvbkVycm9yKG9wdGlvbnMua2V5LCBvcHRpb25zLnZhbHVlLCAnem9vbSBmdW5jdGlvbnMgbm90IHN1cHBvcnRlZCcpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmICgoZnVuY3Rpb25UeXBlID09PSAnY2F0ZWdvcmljYWwnIHx8IGlzWm9vbUFuZFByb3BlcnR5RnVuY3Rpb24pICYmIG9wdGlvbnMudmFsdWUucHJvcGVydHkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBlcnJvcnMucHVzaChuZXcgVmFsaWRhdGlvbkVycm9yKG9wdGlvbnMua2V5LCBvcHRpb25zLnZhbHVlLCAnXCJwcm9wZXJ0eVwiIHByb3BlcnR5IGlzIHJlcXVpcmVkJykpO1xuICAgIH1cblxuICAgIHJldHVybiBlcnJvcnM7XG5cbiAgICBmdW5jdGlvbiB2YWxpZGF0ZUZ1bmN0aW9uU3RvcHMob3B0aW9uczogVmFsaWRhdGlvbk9wdGlvbnMpIHtcbiAgICAgICAgaWYgKGZ1bmN0aW9uVHlwZSA9PT0gJ2lkZW50aXR5Jykge1xuICAgICAgICAgICAgcmV0dXJuIFtuZXcgVmFsaWRhdGlvbkVycm9yKG9wdGlvbnMua2V5LCBvcHRpb25zLnZhbHVlLCAnaWRlbnRpdHkgZnVuY3Rpb24gbWF5IG5vdCBoYXZlIGEgXCJzdG9wc1wiIHByb3BlcnR5JyldO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGVycm9ycyA9IFtdO1xuICAgICAgICBjb25zdCB2YWx1ZSA9IG9wdGlvbnMudmFsdWU7XG5cbiAgICAgICAgZXJyb3JzID0gZXJyb3JzLmNvbmNhdCh2YWxpZGF0ZUFycmF5KHtcbiAgICAgICAgICAgIGtleTogb3B0aW9ucy5rZXksXG4gICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgIHZhbHVlU3BlYzogb3B0aW9ucy52YWx1ZVNwZWMsXG4gICAgICAgICAgICBzdHlsZTogb3B0aW9ucy5zdHlsZSxcbiAgICAgICAgICAgIHN0eWxlU3BlYzogb3B0aW9ucy5zdHlsZVNwZWMsXG4gICAgICAgICAgICBhcnJheUVsZW1lbnRWYWxpZGF0b3I6IHZhbGlkYXRlRnVuY3Rpb25TdG9wXG4gICAgICAgIH0pKTtcblxuICAgICAgICBpZiAoZ2V0VHlwZSh2YWx1ZSkgPT09ICdhcnJheScgJiYgdmFsdWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBlcnJvcnMucHVzaChuZXcgVmFsaWRhdGlvbkVycm9yKG9wdGlvbnMua2V5LCB2YWx1ZSwgJ2FycmF5IG11c3QgaGF2ZSBhdCBsZWFzdCBvbmUgc3RvcCcpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBlcnJvcnM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdmFsaWRhdGVGdW5jdGlvblN0b3Aob3B0aW9uczogVmFsaWRhdGlvbk9wdGlvbnMpIHtcbiAgICAgICAgbGV0IGVycm9ycyA9IFtdO1xuICAgICAgICBjb25zdCB2YWx1ZSA9IG9wdGlvbnMudmFsdWU7XG4gICAgICAgIGNvbnN0IGtleSA9IG9wdGlvbnMua2V5O1xuXG4gICAgICAgIGlmIChnZXRUeXBlKHZhbHVlKSAhPT0gJ2FycmF5Jykge1xuICAgICAgICAgICAgcmV0dXJuIFtuZXcgVmFsaWRhdGlvbkVycm9yKGtleSwgdmFsdWUsIGBhcnJheSBleHBlY3RlZCwgJHtnZXRUeXBlKHZhbHVlKX0gZm91bmRgKV07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodmFsdWUubGVuZ3RoICE9PSAyKSB7XG4gICAgICAgICAgICByZXR1cm4gW25ldyBWYWxpZGF0aW9uRXJyb3Ioa2V5LCB2YWx1ZSwgYGFycmF5IGxlbmd0aCAyIGV4cGVjdGVkLCBsZW5ndGggJHt2YWx1ZS5sZW5ndGh9IGZvdW5kYCldO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzWm9vbUFuZFByb3BlcnR5RnVuY3Rpb24pIHtcbiAgICAgICAgICAgIGlmIChnZXRUeXBlKHZhbHVlWzBdKSAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW25ldyBWYWxpZGF0aW9uRXJyb3Ioa2V5LCB2YWx1ZSwgYG9iamVjdCBleHBlY3RlZCwgJHtnZXRUeXBlKHZhbHVlWzBdKX0gZm91bmRgKV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodmFsdWVbMF0uem9vbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtuZXcgVmFsaWRhdGlvbkVycm9yKGtleSwgdmFsdWUsICdvYmplY3Qgc3RvcCBrZXkgbXVzdCBoYXZlIHpvb20nKV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodmFsdWVbMF0udmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBbbmV3IFZhbGlkYXRpb25FcnJvcihrZXksIHZhbHVlLCAnb2JqZWN0IHN0b3Aga2V5IG11c3QgaGF2ZSB2YWx1ZScpXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgbmV4dFN0b3BEb21haW5ab29tID0gdW5idW5kbGUodmFsdWVbMF0uem9vbSk7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG5leHRTdG9wRG9tYWluWm9vbSAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW25ldyBWYWxpZGF0aW9uRXJyb3Ioa2V5LCB2YWx1ZVswXS56b29tLCAnc3RvcCB6b29tIHZhbHVlcyBtdXN0IGJlIG51bWJlcnMnKV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChwcmV2aW91c1N0b3BEb21haW5ab29tICYmIHByZXZpb3VzU3RvcERvbWFpblpvb20gPiBuZXh0U3RvcERvbWFpblpvb20pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW25ldyBWYWxpZGF0aW9uRXJyb3Ioa2V5LCB2YWx1ZVswXS56b29tLCAnc3RvcCB6b29tIHZhbHVlcyBtdXN0IGFwcGVhciBpbiBhc2NlbmRpbmcgb3JkZXInKV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobmV4dFN0b3BEb21haW5ab29tICE9PSBwcmV2aW91c1N0b3BEb21haW5ab29tKSB7XG4gICAgICAgICAgICAgICAgcHJldmlvdXNTdG9wRG9tYWluWm9vbSA9IG5leHRTdG9wRG9tYWluWm9vbTtcbiAgICAgICAgICAgICAgICBwcmV2aW91c1N0b3BEb21haW5WYWx1ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICBzdG9wRG9tYWluVmFsdWVzID0ge307XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlcnJvcnMgPSBlcnJvcnMuY29uY2F0KHZhbGlkYXRlT2JqZWN0KHtcbiAgICAgICAgICAgICAgICBrZXk6IGAke2tleX1bMF1gLFxuICAgICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZVswXSxcbiAgICAgICAgICAgICAgICB2YWx1ZVNwZWM6IHt6b29tOiB7fX0sXG4gICAgICAgICAgICAgICAgc3R5bGU6IG9wdGlvbnMuc3R5bGUsXG4gICAgICAgICAgICAgICAgc3R5bGVTcGVjOiBvcHRpb25zLnN0eWxlU3BlYyxcbiAgICAgICAgICAgICAgICBvYmplY3RFbGVtZW50VmFsaWRhdG9yczoge3pvb206IHZhbGlkYXRlTnVtYmVyLCB2YWx1ZTogdmFsaWRhdGVTdG9wRG9tYWluVmFsdWV9XG4gICAgICAgICAgICB9KSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlcnJvcnMgPSBlcnJvcnMuY29uY2F0KHZhbGlkYXRlU3RvcERvbWFpblZhbHVlKHtcbiAgICAgICAgICAgICAgICBrZXk6IGAke2tleX1bMF1gLFxuICAgICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZVswXSxcbiAgICAgICAgICAgICAgICB2YWx1ZVNwZWM6IHt9LFxuICAgICAgICAgICAgICAgIHN0eWxlOiBvcHRpb25zLnN0eWxlLFxuICAgICAgICAgICAgICAgIHN0eWxlU3BlYzogb3B0aW9ucy5zdHlsZVNwZWNcbiAgICAgICAgICAgIH0sIHZhbHVlKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNFeHByZXNzaW9uKGRlZXBVbmJ1bmRsZSh2YWx1ZVsxXSkpKSB7XG4gICAgICAgICAgICByZXR1cm4gZXJyb3JzLmNvbmNhdChbbmV3IFZhbGlkYXRpb25FcnJvcihgJHtrZXl9WzFdYCwgdmFsdWVbMV0sICdleHByZXNzaW9ucyBhcmUgbm90IGFsbG93ZWQgaW4gZnVuY3Rpb24gc3RvcHMuJyldKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBlcnJvcnMuY29uY2F0KHZhbGlkYXRlKHtcbiAgICAgICAgICAgIGtleTogYCR7a2V5fVsxXWAsXG4gICAgICAgICAgICB2YWx1ZTogdmFsdWVbMV0sXG4gICAgICAgICAgICB2YWx1ZVNwZWM6IGZ1bmN0aW9uVmFsdWVTcGVjLFxuICAgICAgICAgICAgc3R5bGU6IG9wdGlvbnMuc3R5bGUsXG4gICAgICAgICAgICBzdHlsZVNwZWM6IG9wdGlvbnMuc3R5bGVTcGVjXG4gICAgICAgIH0pKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB2YWxpZGF0ZVN0b3BEb21haW5WYWx1ZShvcHRpb25zOiBWYWxpZGF0aW9uT3B0aW9ucywgc3RvcDogYW55KSB7XG4gICAgICAgIGNvbnN0IHR5cGUgPSBnZXRUeXBlKG9wdGlvbnMudmFsdWUpO1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHVuYnVuZGxlKG9wdGlvbnMudmFsdWUpO1xuXG4gICAgICAgIGNvbnN0IHJlcG9ydFZhbHVlID0gb3B0aW9ucy52YWx1ZSAhPT0gbnVsbCA/IG9wdGlvbnMudmFsdWUgOiBzdG9wO1xuXG4gICAgICAgIGlmICghc3RvcEtleVR5cGUpIHtcbiAgICAgICAgICAgIHN0b3BLZXlUeXBlID0gdHlwZTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlICE9PSBzdG9wS2V5VHlwZSkge1xuICAgICAgICAgICAgcmV0dXJuIFtuZXcgVmFsaWRhdGlvbkVycm9yKG9wdGlvbnMua2V5LCByZXBvcnRWYWx1ZSwgYCR7dHlwZX0gc3RvcCBkb21haW4gdHlwZSBtdXN0IG1hdGNoIHByZXZpb3VzIHN0b3AgZG9tYWluIHR5cGUgJHtzdG9wS2V5VHlwZX1gKV07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZSAhPT0gJ251bWJlcicgJiYgdHlwZSAhPT0gJ3N0cmluZycgJiYgdHlwZSAhPT0gJ2Jvb2xlYW4nICYmIHR5cGVvZiB2YWx1ZSAhPT0gJ251bWJlcicgJiYgdHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJyAmJiB0eXBlb2YgdmFsdWUgIT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgcmV0dXJuIFtuZXcgVmFsaWRhdGlvbkVycm9yKG9wdGlvbnMua2V5LCByZXBvcnRWYWx1ZSwgJ3N0b3AgZG9tYWluIHZhbHVlIG11c3QgYmUgYSBudW1iZXIsIHN0cmluZywgb3IgYm9vbGVhbicpXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlICE9PSAnbnVtYmVyJyAmJiBmdW5jdGlvblR5cGUgIT09ICdjYXRlZ29yaWNhbCcpIHtcbiAgICAgICAgICAgIGxldCBtZXNzYWdlID0gYG51bWJlciBleHBlY3RlZCwgJHt0eXBlfSBmb3VuZGA7XG4gICAgICAgICAgICBpZiAoc3VwcG9ydHNQcm9wZXJ0eUV4cHJlc3Npb24oZnVuY3Rpb25WYWx1ZVNwZWMpICYmIGZ1bmN0aW9uVHlwZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgbWVzc2FnZSArPSAnXFxuSWYgeW91IGludGVuZGVkIHRvIHVzZSBhIGNhdGVnb3JpY2FsIGZ1bmN0aW9uLCBzcGVjaWZ5IGBcInR5cGVcIjogXCJjYXRlZ29yaWNhbFwiYC4nO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIFtuZXcgVmFsaWRhdGlvbkVycm9yKG9wdGlvbnMua2V5LCByZXBvcnRWYWx1ZSwgbWVzc2FnZSldO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGZ1bmN0aW9uVHlwZSA9PT0gJ2NhdGVnb3JpY2FsJyAmJiB0eXBlID09PSAnbnVtYmVyJyAmJiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJyB8fCAhaXNGaW5pdGUodmFsdWUpIHx8IE1hdGguZmxvb3IodmFsdWUpICE9PSB2YWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBbbmV3IFZhbGlkYXRpb25FcnJvcihvcHRpb25zLmtleSwgcmVwb3J0VmFsdWUsIGBpbnRlZ2VyIGV4cGVjdGVkLCBmb3VuZCAke1N0cmluZyh2YWx1ZSl9YCldO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGZ1bmN0aW9uVHlwZSAhPT0gJ2NhdGVnb3JpY2FsJyAmJiB0eXBlID09PSAnbnVtYmVyJyAmJiB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInICYmIHR5cGVvZiBwcmV2aW91c1N0b3BEb21haW5WYWx1ZSA9PT0gJ251bWJlcicgJiYgcHJldmlvdXNTdG9wRG9tYWluVmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSA8IHByZXZpb3VzU3RvcERvbWFpblZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4gW25ldyBWYWxpZGF0aW9uRXJyb3Iob3B0aW9ucy5rZXksIHJlcG9ydFZhbHVlLCAnc3RvcCBkb21haW4gdmFsdWVzIG11c3QgYXBwZWFyIGluIGFzY2VuZGluZyBvcmRlcicpXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHByZXZpb3VzU3RvcERvbWFpblZhbHVlID0gdmFsdWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZnVuY3Rpb25UeXBlID09PSAnY2F0ZWdvcmljYWwnICYmICh2YWx1ZTogYW55KSBpbiBzdG9wRG9tYWluVmFsdWVzKSB7XG4gICAgICAgICAgICByZXR1cm4gW25ldyBWYWxpZGF0aW9uRXJyb3Iob3B0aW9ucy5rZXksIHJlcG9ydFZhbHVlLCAnc3RvcCBkb21haW4gdmFsdWVzIG11c3QgYmUgdW5pcXVlJyldO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3RvcERvbWFpblZhbHVlc1sodmFsdWU6IGFueSldID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB2YWxpZGF0ZUZ1bmN0aW9uRGVmYXVsdChvcHRpb25zOiBWYWxpZGF0aW9uT3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdmFsaWRhdGUoe1xuICAgICAgICAgICAga2V5OiBvcHRpb25zLmtleSxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnZhbHVlLFxuICAgICAgICAgICAgdmFsdWVTcGVjOiBmdW5jdGlvblZhbHVlU3BlYyxcbiAgICAgICAgICAgIHN0eWxlOiBvcHRpb25zLnN0eWxlLFxuICAgICAgICAgICAgc3R5bGVTcGVjOiBvcHRpb25zLnN0eWxlU3BlY1xuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgVmFsaWRhdGlvbkVycm9yIGZyb20gJy4uL2Vycm9yL3ZhbGlkYXRpb25fZXJyb3IuanMnO1xuXG5pbXBvcnQge2NyZWF0ZUV4cHJlc3Npb24sIGNyZWF0ZVByb3BlcnR5RXhwcmVzc2lvbn0gZnJvbSAnLi4vZXhwcmVzc2lvbi9pbmRleC5qcyc7XG5pbXBvcnQge2RlZXBVbmJ1bmRsZX0gZnJvbSAnLi4vdXRpbC91bmJ1bmRsZV9qc29ubGludC5qcyc7XG5pbXBvcnQge2lzU3RhdGVDb25zdGFudCwgaXNHbG9iYWxQcm9wZXJ0eUNvbnN0YW50LCBpc0ZlYXR1cmVDb25zdGFudH0gZnJvbSAnLi4vZXhwcmVzc2lvbi9pc19jb25zdGFudC5qcyc7XG5pbXBvcnQgQ29tcG91bmRFeHByZXNzaW9uIGZyb20gJy4uL2V4cHJlc3Npb24vY29tcG91bmRfZXhwcmVzc2lvbi5qcyc7XG5cbmltcG9ydCB0eXBlIHtFeHByZXNzaW9ufSBmcm9tICcuLi9leHByZXNzaW9uL2V4cHJlc3Npb24uanMnO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB2YWxpZGF0ZUV4cHJlc3Npb24ob3B0aW9uczogYW55KTogQXJyYXk8VmFsaWRhdGlvbkVycm9yPiB7XG4gICAgY29uc3QgZXhwcmVzc2lvbiA9IChvcHRpb25zLmV4cHJlc3Npb25Db250ZXh0ID09PSAncHJvcGVydHknID8gY3JlYXRlUHJvcGVydHlFeHByZXNzaW9uIDogY3JlYXRlRXhwcmVzc2lvbikoZGVlcFVuYnVuZGxlKG9wdGlvbnMudmFsdWUpLCBvcHRpb25zLnZhbHVlU3BlYyk7XG4gICAgaWYgKGV4cHJlc3Npb24ucmVzdWx0ID09PSAnZXJyb3InKSB7XG4gICAgICAgIHJldHVybiBleHByZXNzaW9uLnZhbHVlLm1hcCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgVmFsaWRhdGlvbkVycm9yKGAke29wdGlvbnMua2V5fSR7ZXJyb3Iua2V5fWAsIG9wdGlvbnMudmFsdWUsIGVycm9yLm1lc3NhZ2UpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBleHByZXNzaW9uT2JqID0gKGV4cHJlc3Npb24udmFsdWU6IGFueSkuZXhwcmVzc2lvbiB8fCAoZXhwcmVzc2lvbi52YWx1ZTogYW55KS5fc3R5bGVFeHByZXNzaW9uLmV4cHJlc3Npb247XG5cbiAgICBpZiAob3B0aW9ucy5leHByZXNzaW9uQ29udGV4dCA9PT0gJ3Byb3BlcnR5JyAmJiAob3B0aW9ucy5wcm9wZXJ0eUtleSA9PT0gJ3RleHQtZm9udCcpICYmXG4gICAgICAgICFleHByZXNzaW9uT2JqLm91dHB1dERlZmluZWQoKSkge1xuICAgICAgICByZXR1cm4gW25ldyBWYWxpZGF0aW9uRXJyb3Iob3B0aW9ucy5rZXksIG9wdGlvbnMudmFsdWUsIGBJbnZhbGlkIGRhdGEgZXhwcmVzc2lvbiBmb3IgXCIke29wdGlvbnMucHJvcGVydHlLZXl9XCIuIE91dHB1dCB2YWx1ZXMgbXVzdCBiZSBjb250YWluZWQgYXMgbGl0ZXJhbHMgd2l0aGluIHRoZSBleHByZXNzaW9uLmApXTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5leHByZXNzaW9uQ29udGV4dCA9PT0gJ3Byb3BlcnR5JyAmJiBvcHRpb25zLnByb3BlcnR5VHlwZSA9PT0gJ2xheW91dCcgJiZcbiAgICAgICAgKCFpc1N0YXRlQ29uc3RhbnQoZXhwcmVzc2lvbk9iaikpKSB7XG4gICAgICAgIHJldHVybiBbbmV3IFZhbGlkYXRpb25FcnJvcihvcHRpb25zLmtleSwgb3B0aW9ucy52YWx1ZSwgJ1wiZmVhdHVyZS1zdGF0ZVwiIGRhdGEgZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQgd2l0aCBsYXlvdXQgcHJvcGVydGllcy4nKV07XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMuZXhwcmVzc2lvbkNvbnRleHQgPT09ICdmaWx0ZXInKSB7XG4gICAgICAgIHJldHVybiBkaXNhbGxvd2VkRmlsdGVyUGFyYW1ldGVycyhleHByZXNzaW9uT2JqLCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5leHByZXNzaW9uQ29udGV4dCAmJiBvcHRpb25zLmV4cHJlc3Npb25Db250ZXh0LmluZGV4T2YoJ2NsdXN0ZXInKSA9PT0gMCkge1xuICAgICAgICBpZiAoIWlzR2xvYmFsUHJvcGVydHlDb25zdGFudChleHByZXNzaW9uT2JqLCBbJ3pvb20nLCAnZmVhdHVyZS1zdGF0ZSddKSkge1xuICAgICAgICAgICAgcmV0dXJuIFtuZXcgVmFsaWRhdGlvbkVycm9yKG9wdGlvbnMua2V5LCBvcHRpb25zLnZhbHVlLCAnXCJ6b29tXCIgYW5kIFwiZmVhdHVyZS1zdGF0ZVwiIGV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkIHdpdGggY2x1c3RlciBwcm9wZXJ0aWVzLicpXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0aW9ucy5leHByZXNzaW9uQ29udGV4dCA9PT0gJ2NsdXN0ZXItaW5pdGlhbCcgJiYgIWlzRmVhdHVyZUNvbnN0YW50KGV4cHJlc3Npb25PYmopKSB7XG4gICAgICAgICAgICByZXR1cm4gW25ldyBWYWxpZGF0aW9uRXJyb3Iob3B0aW9ucy5rZXksIG9wdGlvbnMudmFsdWUsICdGZWF0dXJlIGRhdGEgZXhwcmVzc2lvbnMgYXJlIG5vdCBzdXBwb3J0ZWQgd2l0aCBpbml0aWFsIGV4cHJlc3Npb24gcGFydCBvZiBjbHVzdGVyIHByb3BlcnRpZXMuJyldO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIFtdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGlzYWxsb3dlZEZpbHRlclBhcmFtZXRlcnMoZTogRXhwcmVzc2lvbiwgb3B0aW9uczogYW55KTogQXJyYXk8VmFsaWRhdGlvbkVycm9yPiB7XG4gICAgY29uc3QgZGlzYWxsb3dlZFBhcmFtZXRlcnMgPSBuZXcgU2V0KFtcbiAgICAgICAgJ3pvb20nLFxuICAgICAgICAnZmVhdHVyZS1zdGF0ZScsXG4gICAgICAgICdwaXRjaCcsXG4gICAgICAgICdkaXN0YW5jZS1mcm9tLWNlbnRlcidcbiAgICBdKTtcblxuICAgIGlmIChvcHRpb25zLnZhbHVlU3BlYyAmJiBvcHRpb25zLnZhbHVlU3BlYy5leHByZXNzaW9uKSB7XG4gICAgICAgIGZvciAoY29uc3QgcGFyYW0gb2Ygb3B0aW9ucy52YWx1ZVNwZWMuZXhwcmVzc2lvbi5wYXJhbWV0ZXJzKSB7XG4gICAgICAgICAgICBkaXNhbGxvd2VkUGFyYW1ldGVycy5kZWxldGUocGFyYW0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGRpc2FsbG93ZWRQYXJhbWV0ZXJzLnNpemUgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICBjb25zdCBlcnJvcnMgPSBbXTtcblxuICAgIGlmIChlIGluc3RhbmNlb2YgQ29tcG91bmRFeHByZXNzaW9uKSB7XG4gICAgICAgIGlmIChkaXNhbGxvd2VkUGFyYW1ldGVycy5oYXMoZS5uYW1lKSkge1xuICAgICAgICAgICAgcmV0dXJuIFtuZXcgVmFsaWRhdGlvbkVycm9yKG9wdGlvbnMua2V5LCBvcHRpb25zLnZhbHVlLCBgW1wiJHtlLm5hbWV9XCJdIGV4cHJlc3Npb24gaXMgbm90IHN1cHBvcnRlZCBpbiBhIGZpbHRlciBmb3IgYSAke29wdGlvbnMub2JqZWN0LnR5cGV9IGxheWVyIHdpdGggaWQ6ICR7b3B0aW9ucy5vYmplY3QuaWR9YCldO1xuICAgICAgICB9XG4gICAgfVxuICAgIGUuZWFjaENoaWxkKChhcmcpID0+IHtcbiAgICAgICAgZXJyb3JzLnB1c2goLi4uZGlzYWxsb3dlZEZpbHRlclBhcmFtZXRlcnMoYXJnLCBvcHRpb25zKSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZXJyb3JzO1xufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IGdldFR5cGUgZnJvbSAnLi4vdXRpbC9nZXRfdHlwZS5qcyc7XG5pbXBvcnQgVmFsaWRhdGlvbkVycm9yIGZyb20gJy4uL2Vycm9yL3ZhbGlkYXRpb25fZXJyb3IuanMnO1xuXG5pbXBvcnQgdHlwZSB7VmFsaWRhdGlvbk9wdGlvbnN9IGZyb20gJy4vdmFsaWRhdGUuanMnO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB2YWxpZGF0ZUJvb2xlYW4ob3B0aW9uczogVmFsaWRhdGlvbk9wdGlvbnMpOiBBcnJheTxWYWxpZGF0aW9uRXJyb3I+IHtcbiAgICBjb25zdCB2YWx1ZSA9IG9wdGlvbnMudmFsdWU7XG4gICAgY29uc3Qga2V5ID0gb3B0aW9ucy5rZXk7XG4gICAgY29uc3QgdHlwZSA9IGdldFR5cGUodmFsdWUpO1xuXG4gICAgaWYgKHR5cGUgIT09ICdib29sZWFuJykge1xuICAgICAgICByZXR1cm4gW25ldyBWYWxpZGF0aW9uRXJyb3Ioa2V5LCB2YWx1ZSwgYGJvb2xlYW4gZXhwZWN0ZWQsICR7dHlwZX0gZm91bmRgKV07XG4gICAgfVxuXG4gICAgcmV0dXJuIFtdO1xufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IFZhbGlkYXRpb25FcnJvciBmcm9tICcuLi9lcnJvci92YWxpZGF0aW9uX2Vycm9yLmpzJztcbmltcG9ydCBnZXRUeXBlIGZyb20gJy4uL3V0aWwvZ2V0X3R5cGUuanMnO1xuaW1wb3J0IHtwYXJzZUNTU0NvbG9yfSBmcm9tICdjc3Njb2xvcnBhcnNlcic7XG5cbmltcG9ydCB0eXBlIHtWYWxpZGF0aW9uT3B0aW9uc30gZnJvbSAnLi92YWxpZGF0ZS5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHZhbGlkYXRlQ29sb3Iob3B0aW9uczogVmFsaWRhdGlvbk9wdGlvbnMpOiBBcnJheTxWYWxpZGF0aW9uRXJyb3I+IHtcbiAgICBjb25zdCBrZXkgPSBvcHRpb25zLmtleTtcbiAgICBjb25zdCB2YWx1ZSA9IG9wdGlvbnMudmFsdWU7XG4gICAgY29uc3QgdHlwZSA9IGdldFR5cGUodmFsdWUpO1xuXG4gICAgaWYgKHR5cGUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiBbbmV3IFZhbGlkYXRpb25FcnJvcihrZXksIHZhbHVlLCBgY29sb3IgZXhwZWN0ZWQsICR7dHlwZX0gZm91bmRgKV07XG4gICAgfVxuXG4gICAgaWYgKHBhcnNlQ1NTQ29sb3IodmFsdWUpID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBbbmV3IFZhbGlkYXRpb25FcnJvcihrZXksIHZhbHVlLCBgY29sb3IgZXhwZWN0ZWQsIFwiJHt2YWx1ZX1cIiBmb3VuZGApXTtcbiAgICB9XG5cbiAgICByZXR1cm4gW107XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgVmFsaWRhdGlvbkVycm9yIGZyb20gJy4uL2Vycm9yL3ZhbGlkYXRpb25fZXJyb3IuanMnO1xuaW1wb3J0IHt1bmJ1bmRsZX0gZnJvbSAnLi4vdXRpbC91bmJ1bmRsZV9qc29ubGludC5qcyc7XG5cbmltcG9ydCB0eXBlIHtWYWxpZGF0aW9uT3B0aW9uc30gZnJvbSAnLi92YWxpZGF0ZS5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHZhbGlkYXRlRW51bShvcHRpb25zOiBWYWxpZGF0aW9uT3B0aW9ucyk6IEFycmF5PFZhbGlkYXRpb25FcnJvcj4ge1xuICAgIGNvbnN0IGtleSA9IG9wdGlvbnMua2V5O1xuICAgIGNvbnN0IHZhbHVlID0gb3B0aW9ucy52YWx1ZTtcbiAgICBjb25zdCB2YWx1ZVNwZWMgPSBvcHRpb25zLnZhbHVlU3BlYztcbiAgICBjb25zdCBlcnJvcnMgPSBbXTtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlU3BlYy52YWx1ZXMpKSB7IC8vIDw9djdcbiAgICAgICAgaWYgKHZhbHVlU3BlYy52YWx1ZXMuaW5kZXhPZih1bmJ1bmRsZSh2YWx1ZSkpID09PSAtMSkge1xuICAgICAgICAgICAgZXJyb3JzLnB1c2gobmV3IFZhbGlkYXRpb25FcnJvcihrZXksIHZhbHVlLCBgZXhwZWN0ZWQgb25lIG9mIFske3ZhbHVlU3BlYy52YWx1ZXMuam9pbignLCAnKX1dLCAke0pTT04uc3RyaW5naWZ5KHZhbHVlKX0gZm91bmRgKSk7XG4gICAgICAgIH1cbiAgICB9IGVsc2UgeyAvLyA+PXY4XG4gICAgICAgIGlmIChPYmplY3Qua2V5cyh2YWx1ZVNwZWMudmFsdWVzKS5pbmRleE9mKHVuYnVuZGxlKHZhbHVlKSkgPT09IC0xKSB7XG4gICAgICAgICAgICBlcnJvcnMucHVzaChuZXcgVmFsaWRhdGlvbkVycm9yKGtleSwgdmFsdWUsIGBleHBlY3RlZCBvbmUgb2YgWyR7T2JqZWN0LmtleXModmFsdWVTcGVjLnZhbHVlcykuam9pbignLCAnKX1dLCAke0pTT04uc3RyaW5naWZ5KHZhbHVlKX0gZm91bmRgKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGVycm9ycztcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCB7Y3JlYXRlRXhwcmVzc2lvbn0gZnJvbSAnLi4vZXhwcmVzc2lvbi9pbmRleC5qcyc7XG5pbXBvcnQge2lzRmVhdHVyZUNvbnN0YW50fSBmcm9tICcuLi9leHByZXNzaW9uL2lzX2NvbnN0YW50LmpzJztcbmltcG9ydCB7ZGVlcFVuYnVuZGxlfSBmcm9tICcuLi91dGlsL3VuYnVuZGxlX2pzb25saW50LmpzJztcbmltcG9ydCBsYXRlc3QgZnJvbSAnLi4vcmVmZXJlbmNlL2xhdGVzdC5qcyc7XG5pbXBvcnQgdHlwZSB7R2xvYmFsUHJvcGVydGllcywgRmVhdHVyZX0gZnJvbSAnLi4vZXhwcmVzc2lvbi9pbmRleC5qcyc7XG5pbXBvcnQgdHlwZSB7Q2Fub25pY2FsVGlsZUlEfSBmcm9tICcuLi8uLi9zb3VyY2UvdGlsZV9pZC5qcyc7XG5pbXBvcnQgdHlwZSBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcblxuZXhwb3J0IHR5cGUgRmVhdHVyZURpc3RhbmNlRGF0YSA9IHtiZWFyaW5nOiBbbnVtYmVyLCBudW1iZXJdLCBjZW50ZXI6IFtudW1iZXIsIG51bWJlcl0sIHNjYWxlOiBudW1iZXJ9O1xuZXhwb3J0IHR5cGUgRmlsdGVyRXhwcmVzc2lvbiA9IChnbG9iYWxQcm9wZXJ0aWVzOiBHbG9iYWxQcm9wZXJ0aWVzLCBmZWF0dXJlOiBGZWF0dXJlLCBjYW5vbmljYWw/OiBDYW5vbmljYWxUaWxlSUQsIGZlYXR1cmVUaWxlQ29vcmQ/OiBQb2ludCwgZmVhdHVyZURpc3RhbmNlRGF0YT86IEZlYXR1cmVEaXN0YW5jZURhdGEpID0+IGJvb2xlYW47XG5leHBvcnQgdHlwZSBGZWF0dXJlRmlsdGVyID0ge2ZpbHRlcjogRmlsdGVyRXhwcmVzc2lvbiwgZHluYW1pY0ZpbHRlcj86IEZpbHRlckV4cHJlc3Npb24sIG5lZWRHZW9tZXRyeTogYm9vbGVhbiwgbmVlZEZlYXR1cmU6IGJvb2xlYW59O1xuXG5leHBvcnQgZGVmYXVsdCBjcmVhdGVGaWx0ZXI7XG5leHBvcnQge2lzRXhwcmVzc2lvbkZpbHRlciwgaXNEeW5hbWljRmlsdGVyLCBleHRyYWN0U3RhdGljRmlsdGVyfTtcblxuZnVuY3Rpb24gaXNFeHByZXNzaW9uRmlsdGVyKGZpbHRlcjogYW55KTogYm9vbGVhbiB7XG4gICAgaWYgKGZpbHRlciA9PT0gdHJ1ZSB8fCBmaWx0ZXIgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmICghQXJyYXkuaXNBcnJheShmaWx0ZXIpIHx8IGZpbHRlci5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBzd2l0Y2ggKGZpbHRlclswXSkge1xuICAgIGNhc2UgJ2hhcyc6XG4gICAgICAgIHJldHVybiBmaWx0ZXIubGVuZ3RoID49IDIgJiYgZmlsdGVyWzFdICE9PSAnJGlkJyAmJiBmaWx0ZXJbMV0gIT09ICckdHlwZSc7XG5cbiAgICBjYXNlICdpbic6XG4gICAgICAgIHJldHVybiBmaWx0ZXIubGVuZ3RoID49IDMgJiYgKHR5cGVvZiBmaWx0ZXJbMV0gIT09ICdzdHJpbmcnIHx8IEFycmF5LmlzQXJyYXkoZmlsdGVyWzJdKSk7XG5cbiAgICBjYXNlICchaW4nOlxuICAgIGNhc2UgJyFoYXMnOlxuICAgIGNhc2UgJ25vbmUnOlxuICAgICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICBjYXNlICc9PSc6XG4gICAgY2FzZSAnIT0nOlxuICAgIGNhc2UgJz4nOlxuICAgIGNhc2UgJz49JzpcbiAgICBjYXNlICc8JzpcbiAgICBjYXNlICc8PSc6XG4gICAgICAgIHJldHVybiBmaWx0ZXIubGVuZ3RoICE9PSAzIHx8IChBcnJheS5pc0FycmF5KGZpbHRlclsxXSkgfHwgQXJyYXkuaXNBcnJheShmaWx0ZXJbMl0pKTtcblxuICAgIGNhc2UgJ2FueSc6XG4gICAgY2FzZSAnYWxsJzpcbiAgICAgICAgZm9yIChjb25zdCBmIG9mIGZpbHRlci5zbGljZSgxKSkge1xuICAgICAgICAgICAgaWYgKCFpc0V4cHJlc3Npb25GaWx0ZXIoZikgJiYgdHlwZW9mIGYgIT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbn1cblxuLyoqXG4gKiBHaXZlbiBhIGZpbHRlciBleHByZXNzZWQgYXMgbmVzdGVkIGFycmF5cywgcmV0dXJuIGEgbmV3IGZ1bmN0aW9uXG4gKiB0aGF0IGV2YWx1YXRlcyB3aGV0aGVyIGEgZ2l2ZW4gZmVhdHVyZSAod2l0aCBhIC5wcm9wZXJ0aWVzIG9yIC50YWdzIHByb3BlcnR5KVxuICogcGFzc2VzIGl0cyB0ZXN0LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBmaWx0ZXIgbWFwYm94IGdsIGZpbHRlclxuICogQHBhcmFtIHtzdHJpbmd9IGxheWVyVHlwZSB0aGUgdHlwZSBvZiB0aGUgbGF5ZXIgdGhpcyBmaWx0ZXIgd2lsbCBiZSBhcHBsaWVkIHRvLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBmaWx0ZXItZXZhbHVhdGluZyBmdW5jdGlvblxuICovXG5mdW5jdGlvbiBjcmVhdGVGaWx0ZXIoZmlsdGVyOiBhbnksIGxheWVyVHlwZT86IHN0cmluZyA9ICdmaWxsJyk6IEZlYXR1cmVGaWx0ZXIge1xuICAgIGlmIChmaWx0ZXIgPT09IG51bGwgfHwgZmlsdGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHtmaWx0ZXI6ICgpID0+IHRydWUsIG5lZWRHZW9tZXRyeTogZmFsc2UsIG5lZWRGZWF0dXJlOiBmYWxzZX07XG4gICAgfVxuXG4gICAgaWYgKCFpc0V4cHJlc3Npb25GaWx0ZXIoZmlsdGVyKSkge1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW2luY29tcGF0aWJsZS1jYWxsXVxuICAgICAgICBmaWx0ZXIgPSBjb252ZXJ0RmlsdGVyKGZpbHRlcik7XG4gICAgfVxuICAgIGNvbnN0IGZpbHRlckV4cCA9ICgoZmlsdGVyOiBhbnkpOiBzdHJpbmdbXSB8IHN0cmluZyB8IGJvb2xlYW4pO1xuXG4gICAgbGV0IHN0YXRpY0ZpbHRlciA9IHRydWU7XG4gICAgdHJ5IHtcbiAgICAgICAgc3RhdGljRmlsdGVyID0gZXh0cmFjdFN0YXRpY0ZpbHRlcihmaWx0ZXJFeHApO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY29uc29sZS53YXJuKFxuYEZhaWxlZCB0byBleHRyYWN0IHN0YXRpYyBmaWx0ZXIuIEZpbHRlciB3aWxsIGNvbnRpbnVlIHdvcmtpbmcsIGJ1dCBhdCBoaWdoZXIgbWVtb3J5IHVzYWdlIGFuZCBzbG93ZXIgZnJhbWVyYXRlLlxuVGhpcyBpcyBtb3N0IGxpa2VseSBhIGJ1ZywgcGxlYXNlIHJlcG9ydCB0aGlzIHZpYSBodHRwczovL2dpdGh1Yi5jb20vbWFwYm94L21hcGJveC1nbC1qcy9pc3N1ZXMvbmV3P2Fzc2lnbmVlcz0mbGFiZWxzPSZ0ZW1wbGF0ZT1CdWdfcmVwb3J0Lm1kXG5hbmQgcGFzdGUgdGhlIGNvbnRlbnRzIG9mIHRoaXMgbWVzc2FnZSBpbiB0aGUgcmVwb3J0LlxuVGhhbmsgeW91IVxuRmlsdGVyIEV4cHJlc3Npb246XG4ke0pTT04uc3RyaW5naWZ5KGZpbHRlckV4cCwgbnVsbCwgMil9XG4gICAgICAgIGApO1xuICAgIH1cblxuICAgIC8vIENvbXBpbGUgdGhlIHN0YXRpYyBjb21wb25lbnQgb2YgdGhlIGZpbHRlclxuICAgIGNvbnN0IGZpbHRlclNwZWMgPSBsYXRlc3RbYGZpbHRlcl8ke2xheWVyVHlwZX1gXTtcbiAgICBjb25zdCBjb21waWxlZFN0YXRpY0ZpbHRlciA9IGNyZWF0ZUV4cHJlc3Npb24oc3RhdGljRmlsdGVyLCBmaWx0ZXJTcGVjKTtcblxuICAgIGxldCBmaWx0ZXJGdW5jID0gbnVsbDtcbiAgICBpZiAoY29tcGlsZWRTdGF0aWNGaWx0ZXIucmVzdWx0ID09PSAnZXJyb3InKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihjb21waWxlZFN0YXRpY0ZpbHRlci52YWx1ZS5tYXAoZXJyID0+IGAke2Vyci5rZXl9OiAke2Vyci5tZXNzYWdlfWApLmpvaW4oJywgJykpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGZpbHRlckZ1bmMgPSAoZ2xvYmFsUHJvcGVydGllczogR2xvYmFsUHJvcGVydGllcywgZmVhdHVyZTogRmVhdHVyZSwgY2Fub25pY2FsPzogQ2Fub25pY2FsVGlsZUlEKSA9PiBjb21waWxlZFN0YXRpY0ZpbHRlci52YWx1ZS5ldmFsdWF0ZShnbG9iYWxQcm9wZXJ0aWVzLCBmZWF0dXJlLCB7fSwgY2Fub25pY2FsKTtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGUgc3RhdGljIGNvbXBvbmVudCBpcyBub3QgZXF1YWwgdG8gdGhlIGVudGlyZSBmaWx0ZXIgdGhlbiB3ZSBoYXZlIGEgZHluYW1pYyBjb21wb25lbnRcbiAgICAvLyBDb21waWxlIHRoZSBkeW5hbWljIGNvbXBvbmVudCBzZXBhcmF0ZWx5XG4gICAgbGV0IGR5bmFtaWNGaWx0ZXJGdW5jID0gbnVsbDtcbiAgICBsZXQgbmVlZEZlYXR1cmUgPSBudWxsO1xuICAgIGlmIChzdGF0aWNGaWx0ZXIgIT09IGZpbHRlckV4cCkge1xuICAgICAgICBjb25zdCBjb21waWxlZER5bmFtaWNGaWx0ZXIgPSBjcmVhdGVFeHByZXNzaW9uKGZpbHRlckV4cCwgZmlsdGVyU3BlYyk7XG5cbiAgICAgICAgaWYgKGNvbXBpbGVkRHluYW1pY0ZpbHRlci5yZXN1bHQgPT09ICdlcnJvcicpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihjb21waWxlZER5bmFtaWNGaWx0ZXIudmFsdWUubWFwKGVyciA9PiBgJHtlcnIua2V5fTogJHtlcnIubWVzc2FnZX1gKS5qb2luKCcsICcpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGR5bmFtaWNGaWx0ZXJGdW5jID0gKGdsb2JhbFByb3BlcnRpZXM6IEdsb2JhbFByb3BlcnRpZXMsIGZlYXR1cmU6IEZlYXR1cmUsIGNhbm9uaWNhbD86IENhbm9uaWNhbFRpbGVJRCwgZmVhdHVyZVRpbGVDb29yZD86IFBvaW50LCBmZWF0dXJlRGlzdGFuY2VEYXRhPzogRmVhdHVyZURpc3RhbmNlRGF0YSkgPT4gY29tcGlsZWREeW5hbWljRmlsdGVyLnZhbHVlLmV2YWx1YXRlKGdsb2JhbFByb3BlcnRpZXMsIGZlYXR1cmUsIHt9LCBjYW5vbmljYWwsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBmZWF0dXJlVGlsZUNvb3JkLCBmZWF0dXJlRGlzdGFuY2VEYXRhKTtcbiAgICAgICAgICAgIG5lZWRGZWF0dXJlID0gIWlzRmVhdHVyZUNvbnN0YW50KGNvbXBpbGVkRHluYW1pY0ZpbHRlci52YWx1ZS5leHByZXNzaW9uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZpbHRlckZ1bmMgPSAoKGZpbHRlckZ1bmM6IGFueSk6IEZpbHRlckV4cHJlc3Npb24pO1xuICAgIGNvbnN0IG5lZWRHZW9tZXRyeSA9IGdlb21ldHJ5TmVlZGVkKHN0YXRpY0ZpbHRlcik7XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBmaWx0ZXI6IGZpbHRlckZ1bmMsXG4gICAgICAgIGR5bmFtaWNGaWx0ZXI6IGR5bmFtaWNGaWx0ZXJGdW5jID8gZHluYW1pY0ZpbHRlckZ1bmMgOiB1bmRlZmluZWQsXG4gICAgICAgIG5lZWRHZW9tZXRyeSxcbiAgICAgICAgbmVlZEZlYXR1cmU6ICEhbmVlZEZlYXR1cmVcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBleHRyYWN0U3RhdGljRmlsdGVyKGZpbHRlcjogYW55KTogYW55IHtcbiAgICBpZiAoIWlzRHluYW1pY0ZpbHRlcihmaWx0ZXIpKSB7XG4gICAgICAgIHJldHVybiBmaWx0ZXI7XG4gICAgfVxuXG4gICAgLy8gU2hhbGxvdyBjb3B5IHNvIHdlIGNhbiByZXBsYWNlIGV4cHJlc3Npb25zIGluLXBsYWNlXG4gICAgbGV0IHJlc3VsdCA9IGRlZXBVbmJ1bmRsZShmaWx0ZXIpO1xuXG4gICAgLy8gMS4gVW5pb24gYnJhbmNoZXNcbiAgICB1bmlvbkR5bmFtaWNCcmFuY2hlcyhyZXN1bHQpO1xuXG4gICAgLy8gMi4gQ29sbGFwc2UgZHluYW1pYyBjb25kaXRpb25zIHRvICBgdHJ1ZWBcbiAgICByZXN1bHQgPSBjb2xsYXBzZUR5bmFtaWNCb29sZWFuRXhwcmVzc2lvbnMocmVzdWx0KTtcblxuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIGNvbGxhcHNlRHluYW1pY0Jvb2xlYW5FeHByZXNzaW9ucyhleHByZXNzaW9uOiBhbnkpOiBhbnkge1xuICAgIGlmICghQXJyYXkuaXNBcnJheShleHByZXNzaW9uKSkge1xuICAgICAgICByZXR1cm4gZXhwcmVzc2lvbjtcbiAgICB9XG5cbiAgICBjb25zdCBjb2xsYXBzZWQgPSBjb2xsYXBzZWRFeHByZXNzaW9uKGV4cHJlc3Npb24pO1xuICAgIGlmIChjb2xsYXBzZWQgPT09IHRydWUpIHtcbiAgICAgICAgcmV0dXJuIGNvbGxhcHNlZDtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gY29sbGFwc2VkLm1hcCgoc3ViRXhwcmVzc2lvbikgPT4gY29sbGFwc2VEeW5hbWljQm9vbGVhbkV4cHJlc3Npb25zKHN1YkV4cHJlc3Npb24pKTtcbiAgICB9XG59XG5cbi8qKlxuICogVHJhdmVyc2VzIHRoZSBleHByZXNzaW9uIGFuZCByZXBsYWNlcyBhbGwgaW5zdGFuY2VzIG9mIGJyYW5jaGluZyBvbiBhXG4gKiBgZHluYW1pY2AgY29uZGl0aW9uYWwgKHN1Y2ggYXMgYFsncGl0Y2gnXWAgb3IgYFsnZGlzdGFuY2UtZnJvbS1jZW50ZXInXWApXG4gKiBpbnRvIGFuIGBhbnlgIGV4cHJlc3Npb24uXG4gKiBUaGlzIGVuc3VyZXMgdGhhdCBhbGwgcG9zc2libGUgb3V0Y29tZXMgb2YgYSBgZHluYW1pY2AgYnJhbmNoIGFyZSBjb25zaWRlcmVkXG4gKiB3aGVuIGV2YWx1YXRpbmcgdGhlIGV4cHJlc3Npb24gdXBmcm9udCBkdXJpbmcgZmlsdGVyaW5nLlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8YW55Pn0gZmlsdGVyIHRoZSBmaWx0ZXIgZXhwcmVzc2lvbiBtdXRhdGVkIGluLXBsYWNlLlxuICovXG5mdW5jdGlvbiB1bmlvbkR5bmFtaWNCcmFuY2hlcyhmaWx0ZXI6IGFueSkge1xuICAgIGxldCBpc0JyYW5jaGluZ0R5bmFtaWNhbGx5ID0gZmFsc2U7XG4gICAgY29uc3QgYnJhbmNoZXMgPSBbXTtcblxuICAgIGlmIChmaWx0ZXJbMF0gPT09ICdjYXNlJykge1xuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IGZpbHRlci5sZW5ndGggLSAxOyBpICs9IDIpIHtcbiAgICAgICAgICAgIGlzQnJhbmNoaW5nRHluYW1pY2FsbHkgPSBpc0JyYW5jaGluZ0R5bmFtaWNhbGx5IHx8IGlzRHluYW1pY0ZpbHRlcihmaWx0ZXJbaV0pO1xuICAgICAgICAgICAgYnJhbmNoZXMucHVzaChmaWx0ZXJbaSArIDFdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyYW5jaGVzLnB1c2goZmlsdGVyW2ZpbHRlci5sZW5ndGggLSAxXSk7XG4gICAgfSBlbHNlIGlmIChmaWx0ZXJbMF0gPT09ICdtYXRjaCcpIHtcbiAgICAgICAgaXNCcmFuY2hpbmdEeW5hbWljYWxseSA9IGlzQnJhbmNoaW5nRHluYW1pY2FsbHkgfHwgaXNEeW5hbWljRmlsdGVyKGZpbHRlclsxXSk7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDI7IGkgPCBmaWx0ZXIubGVuZ3RoIC0gMTsgaSArPSAyKSB7XG4gICAgICAgICAgICBicmFuY2hlcy5wdXNoKGZpbHRlcltpICsgMV0pO1xuICAgICAgICB9XG4gICAgICAgIGJyYW5jaGVzLnB1c2goZmlsdGVyW2ZpbHRlci5sZW5ndGggLSAxXSk7XG4gICAgfSBlbHNlIGlmIChmaWx0ZXJbMF0gPT09ICdzdGVwJykge1xuICAgICAgICBpc0JyYW5jaGluZ0R5bmFtaWNhbGx5ID0gaXNCcmFuY2hpbmdEeW5hbWljYWxseSB8fCBpc0R5bmFtaWNGaWx0ZXIoZmlsdGVyWzFdKTtcblxuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IGZpbHRlci5sZW5ndGggLSAxOyBpICs9IDIpIHtcbiAgICAgICAgICAgIGJyYW5jaGVzLnB1c2goZmlsdGVyW2kgKyAxXSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNCcmFuY2hpbmdEeW5hbWljYWxseSkge1xuICAgICAgICBmaWx0ZXIubGVuZ3RoID0gMDtcbiAgICAgICAgZmlsdGVyLnB1c2goJ2FueScsIC4uLmJyYW5jaGVzKTtcbiAgICB9XG5cbiAgICAvLyB0cmF2ZXJzZSBhbmQgcmVjdXJzZSBpbnRvIGNoaWxkcmVuXG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPCBmaWx0ZXIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdW5pb25EeW5hbWljQnJhbmNoZXMoZmlsdGVyW2ldKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGlzRHluYW1pY0ZpbHRlcihmaWx0ZXI6IGFueSk6IGJvb2xlYW4ge1xuICAgIC8vIEJhc2UgQ2FzZXNcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoZmlsdGVyKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChpc1Jvb3RFeHByZXNzaW9uRHluYW1pYyhmaWx0ZXJbMF0pKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgZmlsdGVyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGNoaWxkID0gZmlsdGVyW2ldO1xuICAgICAgICBpZiAoaXNEeW5hbWljRmlsdGVyKGNoaWxkKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzUm9vdEV4cHJlc3Npb25EeW5hbWljKGV4cHJlc3Npb246IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBleHByZXNzaW9uID09PSAncGl0Y2gnIHx8XG4gICAgICAgIGV4cHJlc3Npb24gPT09ICdkaXN0YW5jZS1mcm9tLWNlbnRlcic7XG59XG5cbmNvbnN0IGR5bmFtaWNDb25kaXRpb25FeHByZXNzaW9ucyA9IG5ldyBTZXQoW1xuICAgICdpbicsXG4gICAgJz09JyxcbiAgICAnIT0nLFxuICAgICc+JyxcbiAgICAnPj0nLFxuICAgICc8JyxcbiAgICAnPD0nLFxuICAgICd0by1ib29sZWFuJ1xuXSk7XG5cbmZ1bmN0aW9uIGNvbGxhcHNlZEV4cHJlc3Npb24oZXhwcmVzc2lvbjogYW55KTogYW55IHtcbiAgICBpZiAoZHluYW1pY0NvbmRpdGlvbkV4cHJlc3Npb25zLmhhcyhleHByZXNzaW9uWzBdKSkge1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgZXhwcmVzc2lvbi5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgcGFyYW0gPSBleHByZXNzaW9uW2ldO1xuICAgICAgICAgICAgaWYgKGlzRHluYW1pY0ZpbHRlcihwYXJhbSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZXhwcmVzc2lvbjtcbn1cblxuLy8gQ29tcGFyaXNvbiBmdW5jdGlvbiB0byBzb3J0IG51bWJlcnMgYW5kIHN0cmluZ3NcbmZ1bmN0aW9uIGNvbXBhcmUoYTogbnVtYmVyLCBiOiBudW1iZXIpIHtcbiAgICByZXR1cm4gYSA8IGIgPyAtMSA6IGEgPiBiID8gMSA6IDA7XG59XG5cbmZ1bmN0aW9uIGdlb21ldHJ5TmVlZGVkKGZpbHRlcjogQXJyYXk8YW55PiB8IGJvb2xlYW4pIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoZmlsdGVyKSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChmaWx0ZXJbMF0gPT09ICd3aXRoaW4nKSByZXR1cm4gdHJ1ZTtcbiAgICBmb3IgKGxldCBpbmRleCA9IDE7IGluZGV4IDwgZmlsdGVyLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICBpZiAoZ2VvbWV0cnlOZWVkZWQoZmlsdGVyW2luZGV4XSkpIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRGaWx0ZXIoZmlsdGVyOiA/QXJyYXk8YW55Pik6IG1peGVkIHtcbiAgICBpZiAoIWZpbHRlcikgcmV0dXJuIHRydWU7XG4gICAgY29uc3Qgb3AgPSBmaWx0ZXJbMF07XG4gICAgaWYgKGZpbHRlci5sZW5ndGggPD0gMSkgcmV0dXJuIChvcCAhPT0gJ2FueScpO1xuICAgIGNvbnN0IGNvbnZlcnRlZCA9XG4gICAgICAgIG9wID09PSAnPT0nID8gY29udmVydENvbXBhcmlzb25PcChmaWx0ZXJbMV0sIGZpbHRlclsyXSwgJz09JykgOlxuICAgICAgICBvcCA9PT0gJyE9JyA/IGNvbnZlcnROZWdhdGlvbihjb252ZXJ0Q29tcGFyaXNvbk9wKGZpbHRlclsxXSwgZmlsdGVyWzJdLCAnPT0nKSkgOlxuICAgICAgICBvcCA9PT0gJzwnIHx8XG4gICAgICAgIG9wID09PSAnPicgfHxcbiAgICAgICAgb3AgPT09ICc8PScgfHxcbiAgICAgICAgb3AgPT09ICc+PScgPyBjb252ZXJ0Q29tcGFyaXNvbk9wKGZpbHRlclsxXSwgZmlsdGVyWzJdLCBvcCkgOlxuICAgICAgICBvcCA9PT0gJ2FueScgPyBjb252ZXJ0RGlzanVuY3Rpb25PcChmaWx0ZXIuc2xpY2UoMSkpIDpcbiAgICAgICAgb3AgPT09ICdhbGwnID8gWydhbGwnXS5jb25jYXQoZmlsdGVyLnNsaWNlKDEpLm1hcChjb252ZXJ0RmlsdGVyKSkgOlxuICAgICAgICBvcCA9PT0gJ25vbmUnID8gWydhbGwnXS5jb25jYXQoZmlsdGVyLnNsaWNlKDEpLm1hcChjb252ZXJ0RmlsdGVyKS5tYXAoY29udmVydE5lZ2F0aW9uKSkgOlxuICAgICAgICBvcCA9PT0gJ2luJyA/IGNvbnZlcnRJbk9wKGZpbHRlclsxXSwgZmlsdGVyLnNsaWNlKDIpKSA6XG4gICAgICAgIG9wID09PSAnIWluJyA/IGNvbnZlcnROZWdhdGlvbihjb252ZXJ0SW5PcChmaWx0ZXJbMV0sIGZpbHRlci5zbGljZSgyKSkpIDpcbiAgICAgICAgb3AgPT09ICdoYXMnID8gY29udmVydEhhc09wKGZpbHRlclsxXSkgOlxuICAgICAgICBvcCA9PT0gJyFoYXMnID8gY29udmVydE5lZ2F0aW9uKGNvbnZlcnRIYXNPcChmaWx0ZXJbMV0pKSA6XG4gICAgICAgIG9wID09PSAnd2l0aGluJyA/IGZpbHRlciA6XG4gICAgICAgIHRydWU7XG4gICAgcmV0dXJuIGNvbnZlcnRlZDtcbn1cblxuZnVuY3Rpb24gY29udmVydENvbXBhcmlzb25PcChwcm9wZXJ0eTogc3RyaW5nLCB2YWx1ZTogYW55LCBvcDogc3RyaW5nKSB7XG4gICAgc3dpdGNoIChwcm9wZXJ0eSkge1xuICAgIGNhc2UgJyR0eXBlJzpcbiAgICAgICAgcmV0dXJuIFtgZmlsdGVyLXR5cGUtJHtvcH1gLCB2YWx1ZV07XG4gICAgY2FzZSAnJGlkJzpcbiAgICAgICAgcmV0dXJuIFtgZmlsdGVyLWlkLSR7b3B9YCwgdmFsdWVdO1xuICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBbYGZpbHRlci0ke29wfWAsIHByb3BlcnR5LCB2YWx1ZV07XG4gICAgfVxufVxuXG5mdW5jdGlvbiBjb252ZXJ0RGlzanVuY3Rpb25PcChmaWx0ZXJzOiBBcnJheTxBcnJheTxhbnk+Pikge1xuICAgIHJldHVybiBbJ2FueSddLmNvbmNhdChmaWx0ZXJzLm1hcChjb252ZXJ0RmlsdGVyKSk7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRJbk9wKHByb3BlcnR5OiBzdHJpbmcsIHZhbHVlczogQXJyYXk8YW55Pikge1xuICAgIGlmICh2YWx1ZXMubGVuZ3RoID09PSAwKSB7IHJldHVybiBmYWxzZTsgfVxuICAgIHN3aXRjaCAocHJvcGVydHkpIHtcbiAgICBjYXNlICckdHlwZSc6XG4gICAgICAgIHJldHVybiBbYGZpbHRlci10eXBlLWluYCwgWydsaXRlcmFsJywgdmFsdWVzXV07XG4gICAgY2FzZSAnJGlkJzpcbiAgICAgICAgcmV0dXJuIFtgZmlsdGVyLWlkLWluYCwgWydsaXRlcmFsJywgdmFsdWVzXV07XG4gICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKHZhbHVlcy5sZW5ndGggPiAyMDAgJiYgIXZhbHVlcy5zb21lKHYgPT4gdHlwZW9mIHYgIT09IHR5cGVvZiB2YWx1ZXNbMF0pKSB7XG4gICAgICAgICAgICByZXR1cm4gWydmaWx0ZXItaW4tbGFyZ2UnLCBwcm9wZXJ0eSwgWydsaXRlcmFsJywgdmFsdWVzLnNvcnQoY29tcGFyZSldXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBbJ2ZpbHRlci1pbi1zbWFsbCcsIHByb3BlcnR5LCBbJ2xpdGVyYWwnLCB2YWx1ZXNdXTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gY29udmVydEhhc09wKHByb3BlcnR5OiBzdHJpbmcpIHtcbiAgICBzd2l0Y2ggKHByb3BlcnR5KSB7XG4gICAgY2FzZSAnJHR5cGUnOlxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICBjYXNlICckaWQnOlxuICAgICAgICByZXR1cm4gW2BmaWx0ZXItaGFzLWlkYF07XG4gICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIFtgZmlsdGVyLWhhc2AsIHByb3BlcnR5XTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnROZWdhdGlvbihmaWx0ZXI6IG1peGVkKSB7XG4gICAgcmV0dXJuIFsnIScsIGZpbHRlcl07XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgVmFsaWRhdGlvbkVycm9yIGZyb20gJy4uL2Vycm9yL3ZhbGlkYXRpb25fZXJyb3IuanMnO1xuaW1wb3J0IHZhbGlkYXRlRXhwcmVzc2lvbiBmcm9tICcuL3ZhbGlkYXRlX2V4cHJlc3Npb24uanMnO1xuaW1wb3J0IHZhbGlkYXRlRW51bSBmcm9tICcuL3ZhbGlkYXRlX2VudW0uanMnO1xuaW1wb3J0IGdldFR5cGUgZnJvbSAnLi4vdXRpbC9nZXRfdHlwZS5qcyc7XG5pbXBvcnQge3VuYnVuZGxlLCBkZWVwVW5idW5kbGV9IGZyb20gJy4uL3V0aWwvdW5idW5kbGVfanNvbmxpbnQuanMnO1xuaW1wb3J0IGV4dGVuZCBmcm9tICcuLi91dGlsL2V4dGVuZC5qcyc7XG5pbXBvcnQge2lzRXhwcmVzc2lvbkZpbHRlcn0gZnJvbSAnLi4vZmVhdHVyZV9maWx0ZXIvaW5kZXguanMnO1xuXG5pbXBvcnQgdHlwZSB7VmFsaWRhdGlvbk9wdGlvbnN9IGZyb20gJy4vdmFsaWRhdGUuanMnO1xuXG50eXBlIE9wdGlvbnMgPSBWYWxpZGF0aW9uT3B0aW9ucyAmIHtcbiAgICBsYXllclR5cGU/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHZhbGlkYXRlRmlsdGVyKG9wdGlvbnM6IE9wdGlvbnMpOiBBcnJheTxWYWxpZGF0aW9uRXJyb3I+IHtcbiAgICBpZiAoaXNFeHByZXNzaW9uRmlsdGVyKGRlZXBVbmJ1bmRsZShvcHRpb25zLnZhbHVlKSkpIHtcbiAgICAgICAgLy8gV2UgZGVmYXVsdCB0byBhIGxheWVyVHlwZSBvZiBgZmlsbGAgYmVjYXVzZSB0aGF0IHBvaW50cyB0byBhIG5vbi1keW5hbWljIGZpbHRlciBkZWZpbml0aW9uIHdpdGhpbiB0aGUgc3R5bGUtc3BlYy5cbiAgICAgICAgY29uc3QgbGF5ZXJUeXBlID0gb3B0aW9ucy5sYXllclR5cGUgfHwgJ2ZpbGwnO1xuXG4gICAgICAgIHJldHVybiB2YWxpZGF0ZUV4cHJlc3Npb24oZXh0ZW5kKHt9LCBvcHRpb25zLCB7XG4gICAgICAgICAgICBleHByZXNzaW9uQ29udGV4dDogJ2ZpbHRlcicsXG4gICAgICAgICAgICB2YWx1ZVNwZWM6IG9wdGlvbnMuc3R5bGVTcGVjW2BmaWx0ZXJfJHtsYXllclR5cGV9YF1cbiAgICAgICAgfSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB2YWxpZGF0ZU5vbkV4cHJlc3Npb25GaWx0ZXIob3B0aW9ucyk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZU5vbkV4cHJlc3Npb25GaWx0ZXIob3B0aW9uczogT3B0aW9ucykge1xuICAgIGNvbnN0IHZhbHVlID0gb3B0aW9ucy52YWx1ZTtcbiAgICBjb25zdCBrZXkgPSBvcHRpb25zLmtleTtcblxuICAgIGlmIChnZXRUeXBlKHZhbHVlKSAhPT0gJ2FycmF5Jykge1xuICAgICAgICByZXR1cm4gW25ldyBWYWxpZGF0aW9uRXJyb3Ioa2V5LCB2YWx1ZSwgYGFycmF5IGV4cGVjdGVkLCAke2dldFR5cGUodmFsdWUpfSBmb3VuZGApXTtcbiAgICB9XG5cbiAgICBjb25zdCBzdHlsZVNwZWMgPSBvcHRpb25zLnN0eWxlU3BlYztcbiAgICBsZXQgdHlwZTtcblxuICAgIGxldCBlcnJvcnMgPSBbXTtcblxuICAgIGlmICh2YWx1ZS5sZW5ndGggPCAxKSB7XG4gICAgICAgIHJldHVybiBbbmV3IFZhbGlkYXRpb25FcnJvcihrZXksIHZhbHVlLCAnZmlsdGVyIGFycmF5IG11c3QgaGF2ZSBhdCBsZWFzdCAxIGVsZW1lbnQnKV07XG4gICAgfVxuXG4gICAgZXJyb3JzID0gZXJyb3JzLmNvbmNhdCh2YWxpZGF0ZUVudW0oe1xuICAgICAgICBrZXk6IGAke2tleX1bMF1gLFxuICAgICAgICB2YWx1ZTogdmFsdWVbMF0sXG4gICAgICAgIHZhbHVlU3BlYzogc3R5bGVTcGVjLmZpbHRlcl9vcGVyYXRvcixcbiAgICAgICAgc3R5bGU6IG9wdGlvbnMuc3R5bGUsXG4gICAgICAgIHN0eWxlU3BlYzogb3B0aW9ucy5zdHlsZVNwZWNcbiAgICB9KSk7XG5cbiAgICBzd2l0Y2ggKHVuYnVuZGxlKHZhbHVlWzBdKSkge1xuICAgIGNhc2UgJzwnOlxuICAgIGNhc2UgJzw9JzpcbiAgICBjYXNlICc+JzpcbiAgICBjYXNlICc+PSc6XG4gICAgICAgIGlmICh2YWx1ZS5sZW5ndGggPj0gMiAmJiB1bmJ1bmRsZSh2YWx1ZVsxXSkgPT09ICckdHlwZScpIHtcbiAgICAgICAgICAgIGVycm9ycy5wdXNoKG5ldyBWYWxpZGF0aW9uRXJyb3Ioa2V5LCB2YWx1ZSwgYFwiJHR5cGVcIiBjYW5ub3QgYmUgdXNlIHdpdGggb3BlcmF0b3IgXCIke3ZhbHVlWzBdfVwiYCkpO1xuICAgICAgICB9XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICBjYXNlICc9PSc6XG4gICAgY2FzZSAnIT0nOlxuICAgICAgICBpZiAodmFsdWUubGVuZ3RoICE9PSAzKSB7XG4gICAgICAgICAgICBlcnJvcnMucHVzaChuZXcgVmFsaWRhdGlvbkVycm9yKGtleSwgdmFsdWUsIGBmaWx0ZXIgYXJyYXkgZm9yIG9wZXJhdG9yIFwiJHt2YWx1ZVswXX1cIiBtdXN0IGhhdmUgMyBlbGVtZW50c2ApKTtcbiAgICAgICAgfVxuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgY2FzZSAnaW4nOlxuICAgIGNhc2UgJyFpbic6XG4gICAgICAgIGlmICh2YWx1ZS5sZW5ndGggPj0gMikge1xuICAgICAgICAgICAgdHlwZSA9IGdldFR5cGUodmFsdWVbMV0pO1xuICAgICAgICAgICAgaWYgKHR5cGUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JzLnB1c2gobmV3IFZhbGlkYXRpb25FcnJvcihgJHtrZXl9WzFdYCwgdmFsdWVbMV0sIGBzdHJpbmcgZXhwZWN0ZWQsICR7dHlwZX0gZm91bmRgKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgaSA9IDI7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdHlwZSA9IGdldFR5cGUodmFsdWVbaV0pO1xuICAgICAgICAgICAgaWYgKHVuYnVuZGxlKHZhbHVlWzFdKSA9PT0gJyR0eXBlJykge1xuICAgICAgICAgICAgICAgIGVycm9ycyA9IGVycm9ycy5jb25jYXQodmFsaWRhdGVFbnVtKHtcbiAgICAgICAgICAgICAgICAgICAga2V5OiBgJHtrZXl9WyR7aX1dYCxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHZhbHVlW2ldLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZVNwZWM6IHN0eWxlU3BlYy5nZW9tZXRyeV90eXBlLFxuICAgICAgICAgICAgICAgICAgICBzdHlsZTogb3B0aW9ucy5zdHlsZSxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGVTcGVjOiBvcHRpb25zLnN0eWxlU3BlY1xuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSAhPT0gJ3N0cmluZycgJiYgdHlwZSAhPT0gJ251bWJlcicgJiYgdHlwZSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JzLnB1c2gobmV3IFZhbGlkYXRpb25FcnJvcihgJHtrZXl9WyR7aX1dYCwgdmFsdWVbaV0sIGBzdHJpbmcsIG51bWJlciwgb3IgYm9vbGVhbiBleHBlY3RlZCwgJHt0eXBlfSBmb3VuZGApKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBicmVhaztcblxuICAgIGNhc2UgJ2FueSc6XG4gICAgY2FzZSAnYWxsJzpcbiAgICBjYXNlICdub25lJzpcbiAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgZXJyb3JzID0gZXJyb3JzLmNvbmNhdCh2YWxpZGF0ZU5vbkV4cHJlc3Npb25GaWx0ZXIoKHtcbiAgICAgICAgICAgICAgICBrZXk6IGAke2tleX1bJHtpfV1gLFxuICAgICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZVtpXSxcbiAgICAgICAgICAgICAgICBzdHlsZTogb3B0aW9ucy5zdHlsZSxcbiAgICAgICAgICAgICAgICBzdHlsZVNwZWM6IG9wdGlvbnMuc3R5bGVTcGVjXG4gICAgICAgICAgICB9OiBhbnkpKSk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdoYXMnOlxuICAgIGNhc2UgJyFoYXMnOlxuICAgICAgICB0eXBlID0gZ2V0VHlwZSh2YWx1ZVsxXSk7XG4gICAgICAgIGlmICh2YWx1ZS5sZW5ndGggIT09IDIpIHtcbiAgICAgICAgICAgIGVycm9ycy5wdXNoKG5ldyBWYWxpZGF0aW9uRXJyb3Ioa2V5LCB2YWx1ZSwgYGZpbHRlciBhcnJheSBmb3IgXCIke3ZhbHVlWzBdfVwiIG9wZXJhdG9yIG11c3QgaGF2ZSAyIGVsZW1lbnRzYCkpO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBlcnJvcnMucHVzaChuZXcgVmFsaWRhdGlvbkVycm9yKGAke2tleX1bMV1gLCB2YWx1ZVsxXSwgYHN0cmluZyBleHBlY3RlZCwgJHt0eXBlfSBmb3VuZGApKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICBjYXNlICd3aXRoaW4nOlxuICAgICAgICB0eXBlID0gZ2V0VHlwZSh2YWx1ZVsxXSk7XG4gICAgICAgIGlmICh2YWx1ZS5sZW5ndGggIT09IDIpIHtcbiAgICAgICAgICAgIGVycm9ycy5wdXNoKG5ldyBWYWxpZGF0aW9uRXJyb3Ioa2V5LCB2YWx1ZSwgYGZpbHRlciBhcnJheSBmb3IgXCIke3ZhbHVlWzBdfVwiIG9wZXJhdG9yIG11c3QgaGF2ZSAyIGVsZW1lbnRzYCkpO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGUgIT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBlcnJvcnMucHVzaChuZXcgVmFsaWRhdGlvbkVycm9yKGAke2tleX1bMV1gLCB2YWx1ZVsxXSwgYG9iamVjdCBleHBlY3RlZCwgJHt0eXBlfSBmb3VuZGApKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIGVycm9ycztcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCB2YWxpZGF0ZSBmcm9tICcuL3ZhbGlkYXRlLmpzJztcbmltcG9ydCBWYWxpZGF0aW9uRXJyb3IgZnJvbSAnLi4vZXJyb3IvdmFsaWRhdGlvbl9lcnJvci5qcyc7XG5pbXBvcnQgZ2V0VHlwZSBmcm9tICcuLi91dGlsL2dldF90eXBlLmpzJztcbmltcG9ydCB7aXNGdW5jdGlvbn0gZnJvbSAnLi4vZnVuY3Rpb24vaW5kZXguanMnO1xuaW1wb3J0IHt1bmJ1bmRsZSwgZGVlcFVuYnVuZGxlfSBmcm9tICcuLi91dGlsL3VuYnVuZGxlX2pzb25saW50LmpzJztcbmltcG9ydCB7c3VwcG9ydHNQcm9wZXJ0eUV4cHJlc3Npb259IGZyb20gJy4uL3V0aWwvcHJvcGVydGllcy5qcyc7XG5cbmltcG9ydCB0eXBlIHtWYWxpZGF0aW9uT3B0aW9uc30gZnJvbSAnLi92YWxpZGF0ZS5qcyc7XG5cbmV4cG9ydCB0eXBlIFByb3BlcnR5VmFsaWRhdGlvbk9wdGlvbnMgPSBWYWxpZGF0aW9uT3B0aW9ucyAmIHtcbiAgICBvYmplY3RLZXk6IHN0cmluZztcbiAgICBsYXllclR5cGU6IHN0cmluZztcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdmFsaWRhdGVQcm9wZXJ0eShvcHRpb25zOiBQcm9wZXJ0eVZhbGlkYXRpb25PcHRpb25zLCBwcm9wZXJ0eVR5cGU6IHN0cmluZyk6IEFycmF5PFZhbGlkYXRpb25FcnJvcj4ge1xuICAgIGNvbnN0IGtleSA9IG9wdGlvbnMua2V5O1xuICAgIGNvbnN0IHN0eWxlID0gb3B0aW9ucy5zdHlsZTtcbiAgICBjb25zdCBzdHlsZVNwZWMgPSBvcHRpb25zLnN0eWxlU3BlYztcbiAgICBjb25zdCB2YWx1ZSA9IG9wdGlvbnMudmFsdWU7XG4gICAgY29uc3QgcHJvcGVydHlLZXkgPSBvcHRpb25zLm9iamVjdEtleTtcbiAgICBjb25zdCBsYXllclNwZWMgPSBzdHlsZVNwZWNbYCR7cHJvcGVydHlUeXBlfV8ke29wdGlvbnMubGF5ZXJUeXBlfWBdO1xuXG4gICAgaWYgKCFsYXllclNwZWMpIHJldHVybiBbXTtcblxuICAgIGNvbnN0IHRyYW5zaXRpb25NYXRjaCA9IHByb3BlcnR5S2V5Lm1hdGNoKC9eKC4qKS10cmFuc2l0aW9uJC8pO1xuICAgIGlmIChwcm9wZXJ0eVR5cGUgPT09ICdwYWludCcgJiYgdHJhbnNpdGlvbk1hdGNoICYmIGxheWVyU3BlY1t0cmFuc2l0aW9uTWF0Y2hbMV1dICYmIGxheWVyU3BlY1t0cmFuc2l0aW9uTWF0Y2hbMV1dLnRyYW5zaXRpb24pIHtcbiAgICAgICAgcmV0dXJuIHZhbGlkYXRlKHtcbiAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgdmFsdWVTcGVjOiBzdHlsZVNwZWMudHJhbnNpdGlvbixcbiAgICAgICAgICAgIHN0eWxlLFxuICAgICAgICAgICAgc3R5bGVTcGVjXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbHVlU3BlYyA9IG9wdGlvbnMudmFsdWVTcGVjIHx8IGxheWVyU3BlY1twcm9wZXJ0eUtleV07XG4gICAgaWYgKCF2YWx1ZVNwZWMpIHtcbiAgICAgICAgcmV0dXJuIFtuZXcgVmFsaWRhdGlvbkVycm9yKGtleSwgdmFsdWUsIGB1bmtub3duIHByb3BlcnR5IFwiJHtwcm9wZXJ0eUtleX1cImApXTtcbiAgICB9XG5cbiAgICBsZXQgdG9rZW5NYXRjaDogP1JlZ0V4cCRtYXRjaFJlc3VsdDtcbiAgICBpZiAoZ2V0VHlwZSh2YWx1ZSkgPT09ICdzdHJpbmcnICYmIHN1cHBvcnRzUHJvcGVydHlFeHByZXNzaW9uKHZhbHVlU3BlYykgJiYgIXZhbHVlU3BlYy50b2tlbnMgJiYgKHRva2VuTWF0Y2ggPSAvXnsoW159XSspfSQvLmV4ZWModmFsdWUpKSkge1xuICAgICAgICBjb25zdCBleGFtcGxlID0gYFxcYHsgXCJ0eXBlXCI6IFwiaWRlbnRpdHlcIiwgXCJwcm9wZXJ0eVwiOiAke3Rva2VuTWF0Y2ggPyBKU09OLnN0cmluZ2lmeSh0b2tlbk1hdGNoWzFdKSA6ICdcIl9cIid9IH1cXGBgO1xuICAgICAgICByZXR1cm4gW25ldyBWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgICAgICBrZXksIHZhbHVlLFxuICAgICAgICAgICAgYFwiJHtwcm9wZXJ0eUtleX1cIiBkb2VzIG5vdCBzdXBwb3J0IGludGVycG9sYXRpb24gc3ludGF4XFxuYCArXG4gICAgICAgICAgICAgICAgYFVzZSBhbiBpZGVudGl0eSBwcm9wZXJ0eSBmdW5jdGlvbiBpbnN0ZWFkOiAke2V4YW1wbGV9LmApXTtcbiAgICB9XG5cbiAgICBjb25zdCBlcnJvcnMgPSBbXTtcblxuICAgIGlmIChvcHRpb25zLmxheWVyVHlwZSA9PT0gJ3N5bWJvbCcpIHtcbiAgICAgICAgaWYgKHByb3BlcnR5S2V5ID09PSAndGV4dC1maWVsZCcgJiYgc3R5bGUgJiYgIXN0eWxlLmdseXBocykge1xuICAgICAgICAgICAgZXJyb3JzLnB1c2gobmV3IFZhbGlkYXRpb25FcnJvcihrZXksIHZhbHVlLCAndXNlIG9mIFwidGV4dC1maWVsZFwiIHJlcXVpcmVzIGEgc3R5bGUgXCJnbHlwaHNcIiBwcm9wZXJ0eScpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvcGVydHlLZXkgPT09ICd0ZXh0LWZvbnQnICYmIGlzRnVuY3Rpb24oZGVlcFVuYnVuZGxlKHZhbHVlKSkgJiYgdW5idW5kbGUodmFsdWUudHlwZSkgPT09ICdpZGVudGl0eScpIHtcbiAgICAgICAgICAgIGVycm9ycy5wdXNoKG5ldyBWYWxpZGF0aW9uRXJyb3Ioa2V5LCB2YWx1ZSwgJ1widGV4dC1mb250XCIgZG9lcyBub3Qgc3VwcG9ydCBpZGVudGl0eSBmdW5jdGlvbnMnKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZXJyb3JzLmNvbmNhdCh2YWxpZGF0ZSh7XG4gICAgICAgIGtleTogb3B0aW9ucy5rZXksXG4gICAgICAgIHZhbHVlLFxuICAgICAgICB2YWx1ZVNwZWMsXG4gICAgICAgIHN0eWxlLFxuICAgICAgICBzdHlsZVNwZWMsXG4gICAgICAgIGV4cHJlc3Npb25Db250ZXh0OiAncHJvcGVydHknLFxuICAgICAgICBwcm9wZXJ0eVR5cGUsXG4gICAgICAgIHByb3BlcnR5S2V5XG4gICAgfSkpO1xufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHZhbGlkYXRlUHJvcGVydHkgZnJvbSAnLi92YWxpZGF0ZV9wcm9wZXJ0eS5qcyc7XG5cbmltcG9ydCB0eXBlIFZhbGlkYXRpb25FcnJvciBmcm9tICcuLi9lcnJvci92YWxpZGF0aW9uX2Vycm9yLmpzJztcbmltcG9ydCB0eXBlIHtQcm9wZXJ0eVZhbGlkYXRpb25PcHRpb25zfSBmcm9tICcuL3ZhbGlkYXRlX3Byb3BlcnR5LmpzJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdmFsaWRhdGVQYWludFByb3BlcnR5KG9wdGlvbnM6IFByb3BlcnR5VmFsaWRhdGlvbk9wdGlvbnMpOiBBcnJheTxWYWxpZGF0aW9uRXJyb3I+IHtcbiAgICByZXR1cm4gdmFsaWRhdGVQcm9wZXJ0eShvcHRpb25zLCAncGFpbnQnKTtcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCB2YWxpZGF0ZVByb3BlcnR5IGZyb20gJy4vdmFsaWRhdGVfcHJvcGVydHkuanMnO1xuXG5pbXBvcnQgdHlwZSBWYWxpZGF0aW9uRXJyb3IgZnJvbSAnLi4vZXJyb3IvdmFsaWRhdGlvbl9lcnJvci5qcyc7XG5pbXBvcnQgdHlwZSB7UHJvcGVydHlWYWxpZGF0aW9uT3B0aW9uc30gZnJvbSAnLi92YWxpZGF0ZV9wcm9wZXJ0eS5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHZhbGlkYXRlTGF5b3V0UHJvcGVydHkob3B0aW9uczogUHJvcGVydHlWYWxpZGF0aW9uT3B0aW9ucyk6IEFycmF5PFZhbGlkYXRpb25FcnJvcj4ge1xuICAgIHJldHVybiB2YWxpZGF0ZVByb3BlcnR5KG9wdGlvbnMsICdsYXlvdXQnKTtcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBWYWxpZGF0aW9uRXJyb3IgZnJvbSAnLi4vZXJyb3IvdmFsaWRhdGlvbl9lcnJvci5qcyc7XG5pbXBvcnQge3VuYnVuZGxlfSBmcm9tICcuLi91dGlsL3VuYnVuZGxlX2pzb25saW50LmpzJztcbmltcG9ydCB2YWxpZGF0ZU9iamVjdCBmcm9tICcuL3ZhbGlkYXRlX29iamVjdC5qcyc7XG5pbXBvcnQgdmFsaWRhdGVGaWx0ZXIgZnJvbSAnLi92YWxpZGF0ZV9maWx0ZXIuanMnO1xuaW1wb3J0IHZhbGlkYXRlUGFpbnRQcm9wZXJ0eSBmcm9tICcuL3ZhbGlkYXRlX3BhaW50X3Byb3BlcnR5LmpzJztcbmltcG9ydCB2YWxpZGF0ZUxheW91dFByb3BlcnR5IGZyb20gJy4vdmFsaWRhdGVfbGF5b3V0X3Byb3BlcnR5LmpzJztcbmltcG9ydCB2YWxpZGF0ZVNwZWMgZnJvbSAnLi92YWxpZGF0ZS5qcyc7XG5pbXBvcnQgZXh0ZW5kIGZyb20gJy4uL3V0aWwvZXh0ZW5kLmpzJztcblxuaW1wb3J0IHR5cGUge1ZhbGlkYXRpb25PcHRpb25zfSBmcm9tICcuL3ZhbGlkYXRlLmpzJztcbmltcG9ydCB0eXBlIHtMYXllclNwZWNpZmljYXRpb259IGZyb20gJy4uL3R5cGVzLmpzJztcblxudHlwZSBPcHRpb25zID0gVmFsaWRhdGlvbk9wdGlvbnMgJiB7XG4gICAgdmFsdWU6IExheWVyU3BlY2lmaWNhdGlvbjtcbiAgICBhcnJheUluZGV4OiBudW1iZXI7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHZhbGlkYXRlTGF5ZXIob3B0aW9uczogT3B0aW9ucyk6IEFycmF5PFZhbGlkYXRpb25FcnJvcj4ge1xuICAgIGxldCBlcnJvcnMgPSBbXTtcblxuICAgIGNvbnN0IGxheWVyID0gb3B0aW9ucy52YWx1ZTtcbiAgICBjb25zdCBrZXkgPSBvcHRpb25zLmtleTtcbiAgICBjb25zdCBzdHlsZSA9IG9wdGlvbnMuc3R5bGU7XG4gICAgY29uc3Qgc3R5bGVTcGVjID0gb3B0aW9ucy5zdHlsZVNwZWM7XG5cbiAgICBpZiAoIWxheWVyLnR5cGUgJiYgIWxheWVyLnJlZikge1xuICAgICAgICBlcnJvcnMucHVzaChuZXcgVmFsaWRhdGlvbkVycm9yKGtleSwgbGF5ZXIsICdlaXRoZXIgXCJ0eXBlXCIgb3IgXCJyZWZcIiBpcyByZXF1aXJlZCcpKTtcbiAgICB9XG4gICAgbGV0IHR5cGUgPSB1bmJ1bmRsZShsYXllci50eXBlKTtcbiAgICBjb25zdCByZWYgPSB1bmJ1bmRsZShsYXllci5yZWYpO1xuXG4gICAgaWYgKGxheWVyLmlkKSB7XG4gICAgICAgIGNvbnN0IGxheWVySWQgPSB1bmJ1bmRsZShsYXllci5pZCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3B0aW9ucy5hcnJheUluZGV4OyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IG90aGVyTGF5ZXIgPSBzdHlsZS5sYXllcnNbaV07XG4gICAgICAgICAgICBpZiAodW5idW5kbGUob3RoZXJMYXllci5pZCkgPT09IGxheWVySWQpIHtcbiAgICAgICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW3Byb3AtbWlzc2luZ10gLSBpZC5fX2xpbmVfXyBpcyBhZGRlZCBkeW5hbWljYWxseSBkdXJpbmcgdGhlIHJlYWRTdHlsZSBzdGVwXG4gICAgICAgICAgICAgICAgZXJyb3JzLnB1c2gobmV3IFZhbGlkYXRpb25FcnJvcihrZXksIGxheWVyLmlkLCBgZHVwbGljYXRlIGxheWVyIGlkIFwiJHtsYXllci5pZH1cIiwgcHJldmlvdXNseSB1c2VkIGF0IGxpbmUgJHtvdGhlckxheWVyLmlkLl9fbGluZV9ffWApKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmICgncmVmJyBpbiBsYXllcikge1xuICAgICAgICBbJ3R5cGUnLCAnc291cmNlJywgJ3NvdXJjZS1sYXllcicsICdmaWx0ZXInLCAnbGF5b3V0J10uZm9yRWFjaCgocCkgPT4ge1xuICAgICAgICAgICAgaWYgKHAgaW4gbGF5ZXIpIHtcbiAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChuZXcgVmFsaWRhdGlvbkVycm9yKGtleSwgbGF5ZXJbcF0sIGBcIiR7cH1cIiBpcyBwcm9oaWJpdGVkIGZvciByZWYgbGF5ZXJzYCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBsZXQgcGFyZW50O1xuXG4gICAgICAgIHN0eWxlLmxheWVycy5mb3JFYWNoKChsYXllcikgPT4ge1xuICAgICAgICAgICAgaWYgKHVuYnVuZGxlKGxheWVyLmlkKSA9PT0gcmVmKSBwYXJlbnQgPSBsYXllcjtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKCFwYXJlbnQpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcmVmID09PSAnc3RyaW5nJylcbiAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChuZXcgVmFsaWRhdGlvbkVycm9yKGtleSwgbGF5ZXIucmVmLCBgcmVmIGxheWVyIFwiJHtyZWZ9XCIgbm90IGZvdW5kYCkpO1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW3Byb3AtbWlzc2luZ10gLSByZWYgaXMgbm90IGRlZmluZWQgb24gdGhlIExheWVyU3BlY2lmaWNhdGlvbiBzdWJ0eXBlc1xuICAgICAgICB9IGVsc2UgaWYgKHBhcmVudC5yZWYpIHtcbiAgICAgICAgICAgIGVycm9ycy5wdXNoKG5ldyBWYWxpZGF0aW9uRXJyb3Ioa2V5LCBsYXllci5yZWYsICdyZWYgY2Fubm90IHJlZmVyZW5jZSBhbm90aGVyIHJlZiBsYXllcicpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHR5cGUgPSB1bmJ1bmRsZShwYXJlbnQudHlwZSk7XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCEodHlwZSA9PT0gJ2JhY2tncm91bmQnIHx8IHR5cGUgPT09ICdza3knKSkge1xuICAgICAgICBpZiAoIWxheWVyLnNvdXJjZSkge1xuICAgICAgICAgICAgZXJyb3JzLnB1c2gobmV3IFZhbGlkYXRpb25FcnJvcihrZXksIGxheWVyLCAnbWlzc2luZyByZXF1aXJlZCBwcm9wZXJ0eSBcInNvdXJjZVwiJykpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgc291cmNlID0gc3R5bGUuc291cmNlcyAmJiBzdHlsZS5zb3VyY2VzW2xheWVyLnNvdXJjZV07XG4gICAgICAgICAgICBjb25zdCBzb3VyY2VUeXBlID0gc291cmNlICYmIHVuYnVuZGxlKHNvdXJjZS50eXBlKTtcbiAgICAgICAgICAgIGlmICghc291cmNlKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JzLnB1c2gobmV3IFZhbGlkYXRpb25FcnJvcihrZXksIGxheWVyLnNvdXJjZSwgYHNvdXJjZSBcIiR7bGF5ZXIuc291cmNlfVwiIG5vdCBmb3VuZGApKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoc291cmNlVHlwZSA9PT0gJ3ZlY3RvcicgJiYgdHlwZSA9PT0gJ3Jhc3RlcicpIHtcbiAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChuZXcgVmFsaWRhdGlvbkVycm9yKGtleSwgbGF5ZXIuc291cmNlLCBgbGF5ZXIgXCIke2xheWVyLmlkfVwiIHJlcXVpcmVzIGEgcmFzdGVyIHNvdXJjZWApKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoc291cmNlVHlwZSA9PT0gJ3Jhc3RlcicgJiYgdHlwZSAhPT0gJ3Jhc3RlcicpIHtcbiAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChuZXcgVmFsaWRhdGlvbkVycm9yKGtleSwgbGF5ZXIuc291cmNlLCBgbGF5ZXIgXCIke2xheWVyLmlkfVwiIHJlcXVpcmVzIGEgdmVjdG9yIHNvdXJjZWApKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoc291cmNlVHlwZSA9PT0gJ3ZlY3RvcicgJiYgIWxheWVyWydzb3VyY2UtbGF5ZXInXSkge1xuICAgICAgICAgICAgICAgIGVycm9ycy5wdXNoKG5ldyBWYWxpZGF0aW9uRXJyb3Ioa2V5LCBsYXllciwgYGxheWVyIFwiJHtsYXllci5pZH1cIiBtdXN0IHNwZWNpZnkgYSBcInNvdXJjZS1sYXllclwiYCkpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzb3VyY2VUeXBlID09PSAncmFzdGVyLWRlbScgJiYgdHlwZSAhPT0gJ2hpbGxzaGFkZScpIHtcbiAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChuZXcgVmFsaWRhdGlvbkVycm9yKGtleSwgbGF5ZXIuc291cmNlLCAncmFzdGVyLWRlbSBzb3VyY2UgY2FuIG9ubHkgYmUgdXNlZCB3aXRoIGxheWVyIHR5cGUgXFwnaGlsbHNoYWRlXFwnLicpKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2xpbmUnICYmIGxheWVyLnBhaW50ICYmIChsYXllci5wYWludFsnbGluZS1ncmFkaWVudCddIHx8IGxheWVyLnBhaW50WydsaW5lLXRyaW0tb2Zmc2V0J10pICYmXG4gICAgICAgICAgICAgICAgICAgICAgIChzb3VyY2VUeXBlICE9PSAnZ2VvanNvbicgfHwgIXNvdXJjZS5saW5lTWV0cmljcykpIHtcbiAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChuZXcgVmFsaWRhdGlvbkVycm9yKGtleSwgbGF5ZXIsIGBsYXllciBcIiR7bGF5ZXIuaWR9XCIgc3BlY2lmaWVzIGEgbGluZS1ncmFkaWVudCwgd2hpY2ggcmVxdWlyZXMgYSBHZW9KU09OIHNvdXJjZSB3aXRoIFxcYGxpbmVNZXRyaWNzXFxgIGVuYWJsZWQuYCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZXJyb3JzID0gZXJyb3JzLmNvbmNhdCh2YWxpZGF0ZU9iamVjdCh7XG4gICAgICAgIGtleSxcbiAgICAgICAgdmFsdWU6IGxheWVyLFxuICAgICAgICB2YWx1ZVNwZWM6IHN0eWxlU3BlYy5sYXllcixcbiAgICAgICAgc3R5bGU6IG9wdGlvbnMuc3R5bGUsXG4gICAgICAgIHN0eWxlU3BlYzogb3B0aW9ucy5zdHlsZVNwZWMsXG4gICAgICAgIG9iamVjdEVsZW1lbnRWYWxpZGF0b3JzOiB7XG4gICAgICAgICAgICAnKicoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIC8vIFdlIGRvbid0IHdhbnQgdG8gZW5mb3JjZSB0aGUgc3BlYydzIGBcInJlcXVpcmVzXCI6IHRydWVgIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5IHdpdGggcmVmcztcbiAgICAgICAgICAgIC8vIHRoZSBhY3R1YWwgcmVxdWlyZW1lbnQgaXMgdmFsaWRhdGVkIGFib3ZlLiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL21hcGJveC9tYXBib3gtZ2wtanMvaXNzdWVzLzU3NzIuXG4gICAgICAgICAgICB0eXBlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWxpZGF0ZVNwZWMoe1xuICAgICAgICAgICAgICAgICAgICBrZXk6IGAke2tleX0udHlwZWAsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBsYXllci50eXBlLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZVNwZWM6IHN0eWxlU3BlYy5sYXllci50eXBlLFxuICAgICAgICAgICAgICAgICAgICBzdHlsZTogb3B0aW9ucy5zdHlsZSxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGVTcGVjOiBvcHRpb25zLnN0eWxlU3BlYyxcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0OiBsYXllcixcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0S2V5OiAndHlwZSdcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBmaWx0ZXIob3B0aW9ucykge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWxpZGF0ZUZpbHRlcihleHRlbmQoe2xheWVyVHlwZTogdHlwZX0sIG9wdGlvbnMpKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYXlvdXQob3B0aW9ucykge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWxpZGF0ZU9iamVjdCh7XG4gICAgICAgICAgICAgICAgICAgIGxheWVyLFxuICAgICAgICAgICAgICAgICAgICBrZXk6IG9wdGlvbnMua2V5LFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVTcGVjOiB7fSxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IG9wdGlvbnMuc3R5bGUsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlU3BlYzogb3B0aW9ucy5zdHlsZVNwZWMsXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdEVsZW1lbnRWYWxpZGF0b3JzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAnKicob3B0aW9ucykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWxpZGF0ZUxheW91dFByb3BlcnR5KGV4dGVuZCh7bGF5ZXJUeXBlOiB0eXBlfSwgb3B0aW9ucykpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcGFpbnQob3B0aW9ucykge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWxpZGF0ZU9iamVjdCh7XG4gICAgICAgICAgICAgICAgICAgIGxheWVyLFxuICAgICAgICAgICAgICAgICAgICBrZXk6IG9wdGlvbnMua2V5LFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVTcGVjOiB7fSxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IG9wdGlvbnMuc3R5bGUsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlU3BlYzogb3B0aW9ucy5zdHlsZVNwZWMsXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdEVsZW1lbnRWYWxpZGF0b3JzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAnKicob3B0aW9ucykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWxpZGF0ZVBhaW50UHJvcGVydHkoZXh0ZW5kKHtsYXllclR5cGU6IHR5cGV9LCBvcHRpb25zKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pKTtcblxuICAgIHJldHVybiBlcnJvcnM7XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgZ2V0VHlwZSBmcm9tICcuLi91dGlsL2dldF90eXBlLmpzJztcbmltcG9ydCBWYWxpZGF0aW9uRXJyb3IgZnJvbSAnLi4vZXJyb3IvdmFsaWRhdGlvbl9lcnJvci5qcyc7XG5cbmltcG9ydCB0eXBlIHtWYWxpZGF0aW9uT3B0aW9uc30gZnJvbSAnLi92YWxpZGF0ZS5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHZhbGlkYXRlU3RyaW5nKG9wdGlvbnM6ICRTaGFwZTxWYWxpZGF0aW9uT3B0aW9ucz4pOiBBcnJheTxWYWxpZGF0aW9uRXJyb3I+IHtcbiAgICBjb25zdCB2YWx1ZSA9IG9wdGlvbnMudmFsdWU7XG4gICAgY29uc3Qga2V5ID0gb3B0aW9ucy5rZXk7XG4gICAgY29uc3QgdHlwZSA9IGdldFR5cGUodmFsdWUpO1xuXG4gICAgaWYgKHR5cGUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiBbbmV3IFZhbGlkYXRpb25FcnJvcihrZXksIHZhbHVlLCBgc3RyaW5nIGV4cGVjdGVkLCAke3R5cGV9IGZvdW5kYCldO1xuICAgIH1cblxuICAgIHJldHVybiBbXTtcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBWYWxpZGF0aW9uRXJyb3IgZnJvbSAnLi4vZXJyb3IvdmFsaWRhdGlvbl9lcnJvci5qcyc7XG5pbXBvcnQge3VuYnVuZGxlfSBmcm9tICcuLi91dGlsL3VuYnVuZGxlX2pzb25saW50LmpzJztcbmltcG9ydCB2YWxpZGF0ZU9iamVjdCBmcm9tICcuL3ZhbGlkYXRlX29iamVjdC5qcyc7XG5pbXBvcnQgdmFsaWRhdGVFbnVtIGZyb20gJy4vdmFsaWRhdGVfZW51bS5qcyc7XG5pbXBvcnQgdmFsaWRhdGVFeHByZXNzaW9uIGZyb20gJy4vdmFsaWRhdGVfZXhwcmVzc2lvbi5qcyc7XG5pbXBvcnQgdmFsaWRhdGVTdHJpbmcgZnJvbSAnLi92YWxpZGF0ZV9zdHJpbmcuanMnO1xuaW1wb3J0IGdldFR5cGUgZnJvbSAnLi4vdXRpbC9nZXRfdHlwZS5qcyc7XG5cbmltcG9ydCB0eXBlIHtTdHlsZVJlZmVyZW5jZX0gZnJvbSAnLi4vcmVmZXJlbmNlL2xhdGVzdC5qcyc7XG5pbXBvcnQgdHlwZSB7VmFsaWRhdGlvbk9wdGlvbnN9IGZyb20gJy4vdmFsaWRhdGUuanMnO1xuXG5jb25zdCBvYmplY3RFbGVtZW50VmFsaWRhdG9ycyA9IHtcbiAgICBwcm9tb3RlSWQ6IHZhbGlkYXRlUHJvbW90ZUlkXG59O1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB2YWxpZGF0ZVNvdXJjZShvcHRpb25zOiBWYWxpZGF0aW9uT3B0aW9ucyk6IEFycmF5PFZhbGlkYXRpb25FcnJvcj4ge1xuICAgIGNvbnN0IHZhbHVlID0gb3B0aW9ucy52YWx1ZTtcbiAgICBjb25zdCBrZXkgPSBvcHRpb25zLmtleTtcbiAgICBjb25zdCBzdHlsZVNwZWMgPSBvcHRpb25zLnN0eWxlU3BlYztcbiAgICBjb25zdCBzdHlsZSA9IG9wdGlvbnMuc3R5bGU7XG5cbiAgICBpZiAoIXZhbHVlLnR5cGUpIHtcbiAgICAgICAgcmV0dXJuIFtuZXcgVmFsaWRhdGlvbkVycm9yKGtleSwgdmFsdWUsICdcInR5cGVcIiBpcyByZXF1aXJlZCcpXTtcbiAgICB9XG5cbiAgICBjb25zdCB0eXBlID0gdW5idW5kbGUodmFsdWUudHlwZSk7XG4gICAgbGV0IGVycm9ycztcblxuICAgIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgJ3ZlY3Rvcic6XG4gICAgY2FzZSAncmFzdGVyJzpcbiAgICBjYXNlICdyYXN0ZXItZGVtJzpcbiAgICAgICAgZXJyb3JzID0gdmFsaWRhdGVPYmplY3Qoe1xuICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgICB2YWx1ZVNwZWM6IHN0eWxlU3BlY1tgc291cmNlXyR7dHlwZS5yZXBsYWNlKCctJywgJ18nKX1gXSxcbiAgICAgICAgICAgIHN0eWxlOiBvcHRpb25zLnN0eWxlLFxuICAgICAgICAgICAgc3R5bGVTcGVjLFxuICAgICAgICAgICAgb2JqZWN0RWxlbWVudFZhbGlkYXRvcnNcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBlcnJvcnM7XG5cbiAgICBjYXNlICdnZW9qc29uJzpcbiAgICAgICAgZXJyb3JzID0gdmFsaWRhdGVPYmplY3Qoe1xuICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgICB2YWx1ZVNwZWM6IHN0eWxlU3BlYy5zb3VyY2VfZ2VvanNvbixcbiAgICAgICAgICAgIHN0eWxlLFxuICAgICAgICAgICAgc3R5bGVTcGVjLFxuICAgICAgICAgICAgb2JqZWN0RWxlbWVudFZhbGlkYXRvcnNcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh2YWx1ZS5jbHVzdGVyKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHByb3AgaW4gdmFsdWUuY2x1c3RlclByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBbb3BlcmF0b3IsIG1hcEV4cHJdID0gdmFsdWUuY2x1c3RlclByb3BlcnRpZXNbcHJvcF07XG4gICAgICAgICAgICAgICAgY29uc3QgcmVkdWNlRXhwciA9IHR5cGVvZiBvcGVyYXRvciA9PT0gJ3N0cmluZycgPyBbb3BlcmF0b3IsIFsnYWNjdW11bGF0ZWQnXSwgWydnZXQnLCBwcm9wXV0gOiBvcGVyYXRvcjtcblxuICAgICAgICAgICAgICAgIGVycm9ycy5wdXNoKC4uLnZhbGlkYXRlRXhwcmVzc2lvbih7XG4gICAgICAgICAgICAgICAgICAgIGtleTogYCR7a2V5fS4ke3Byb3B9Lm1hcGAsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBtYXBFeHByLFxuICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uQ29udGV4dDogJ2NsdXN0ZXItbWFwJ1xuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICBlcnJvcnMucHVzaCguLi52YWxpZGF0ZUV4cHJlc3Npb24oe1xuICAgICAgICAgICAgICAgICAgICBrZXk6IGAke2tleX0uJHtwcm9wfS5yZWR1Y2VgLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogcmVkdWNlRXhwcixcbiAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbkNvbnRleHQ6ICdjbHVzdGVyLXJlZHVjZSdcbiAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGVycm9ycztcblxuICAgIGNhc2UgJ3ZpZGVvJzpcbiAgICAgICAgcmV0dXJuIHZhbGlkYXRlT2JqZWN0KHtcbiAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgdmFsdWVTcGVjOiBzdHlsZVNwZWMuc291cmNlX3ZpZGVvLFxuICAgICAgICAgICAgc3R5bGUsXG4gICAgICAgICAgICBzdHlsZVNwZWNcbiAgICAgICAgfSk7XG5cbiAgICBjYXNlICdpbWFnZSc6XG4gICAgICAgIHJldHVybiB2YWxpZGF0ZU9iamVjdCh7XG4gICAgICAgICAgICBrZXksXG4gICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgIHZhbHVlU3BlYzogc3R5bGVTcGVjLnNvdXJjZV9pbWFnZSxcbiAgICAgICAgICAgIHN0eWxlLFxuICAgICAgICAgICAgc3R5bGVTcGVjXG4gICAgICAgIH0pO1xuXG4gICAgY2FzZSAnY2FudmFzJzpcbiAgICAgICAgcmV0dXJuIFtuZXcgVmFsaWRhdGlvbkVycm9yKGtleSwgbnVsbCwgYFBsZWFzZSB1c2UgcnVudGltZSBBUElzIHRvIGFkZCBjYW52YXMgc291cmNlcywgcmF0aGVyIHRoYW4gaW5jbHVkaW5nIHRoZW0gaW4gc3R5bGVzaGVldHMuYCwgJ3NvdXJjZS5jYW52YXMnKV07XG5cbiAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gdmFsaWRhdGVFbnVtKHtcbiAgICAgICAgICAgIGtleTogYCR7a2V5fS50eXBlYCxcbiAgICAgICAgICAgIHZhbHVlOiB2YWx1ZS50eXBlLFxuICAgICAgICAgICAgdmFsdWVTcGVjOiB7dmFsdWVzOiBnZXRTb3VyY2VUeXBlVmFsdWVzKHN0eWxlU3BlYyl9LFxuICAgICAgICAgICAgc3R5bGUsXG4gICAgICAgICAgICBzdHlsZVNwZWNcbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBnZXRTb3VyY2VUeXBlVmFsdWVzKHN0eWxlU3BlYzogU3R5bGVSZWZlcmVuY2UpIHtcbiAgICByZXR1cm4gc3R5bGVTcGVjLnNvdXJjZS5yZWR1Y2UoKG1lbW8sIHNvdXJjZSkgPT4ge1xuICAgICAgICBjb25zdCBzb3VyY2VUeXBlID0gc3R5bGVTcGVjW3NvdXJjZV07XG4gICAgICAgIGlmIChzb3VyY2VUeXBlLnR5cGUudHlwZSA9PT0gJ2VudW0nKSB7XG4gICAgICAgICAgICBtZW1vID0gbWVtby5jb25jYXQoT2JqZWN0LmtleXMoc291cmNlVHlwZS50eXBlLnZhbHVlcykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtZW1vO1xuICAgIH0sIFtdKTtcbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVQcm9tb3RlSWQoe2tleSwgdmFsdWV9OiAkU2hhcGU8VmFsaWRhdGlvbk9wdGlvbnM+KSB7XG4gICAgaWYgKGdldFR5cGUodmFsdWUpID09PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gdmFsaWRhdGVTdHJpbmcoe2tleSwgdmFsdWV9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBlcnJvcnMgPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBwcm9wIGluIHZhbHVlKSB7XG4gICAgICAgICAgICBlcnJvcnMucHVzaCguLi52YWxpZGF0ZVN0cmluZyh7a2V5OiBgJHtrZXl9LiR7cHJvcH1gLCB2YWx1ZTogdmFsdWVbcHJvcF19KSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGVycm9ycztcbiAgICB9XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgVmFsaWRhdGlvbkVycm9yIGZyb20gJy4uL2Vycm9yL3ZhbGlkYXRpb25fZXJyb3IuanMnO1xuaW1wb3J0IGdldFR5cGUgZnJvbSAnLi4vdXRpbC9nZXRfdHlwZS5qcyc7XG5pbXBvcnQgdmFsaWRhdGUgZnJvbSAnLi92YWxpZGF0ZS5qcyc7XG5cbmltcG9ydCB0eXBlIHtWYWxpZGF0aW9uT3B0aW9uc30gZnJvbSAnLi92YWxpZGF0ZS5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHZhbGlkYXRlTGlnaHQob3B0aW9uczogVmFsaWRhdGlvbk9wdGlvbnMpOiBBcnJheTxWYWxpZGF0aW9uRXJyb3I+IHtcbiAgICBjb25zdCBsaWdodCA9IG9wdGlvbnMudmFsdWU7XG4gICAgY29uc3Qgc3R5bGVTcGVjID0gb3B0aW9ucy5zdHlsZVNwZWM7XG4gICAgY29uc3QgbGlnaHRTcGVjID0gc3R5bGVTcGVjLmxpZ2h0O1xuICAgIGNvbnN0IHN0eWxlID0gb3B0aW9ucy5zdHlsZTtcblxuICAgIGxldCBlcnJvcnMgPSBbXTtcblxuICAgIGNvbnN0IHJvb3RUeXBlID0gZ2V0VHlwZShsaWdodCk7XG4gICAgaWYgKGxpZ2h0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGVycm9ycztcbiAgICB9IGVsc2UgaWYgKHJvb3RUeXBlICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMgPSBlcnJvcnMuY29uY2F0KFtuZXcgVmFsaWRhdGlvbkVycm9yKCdsaWdodCcsIGxpZ2h0LCBgb2JqZWN0IGV4cGVjdGVkLCAke3Jvb3RUeXBlfSBmb3VuZGApXSk7XG4gICAgICAgIHJldHVybiBlcnJvcnM7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBrZXkgaW4gbGlnaHQpIHtcbiAgICAgICAgY29uc3QgdHJhbnNpdGlvbk1hdGNoID0ga2V5Lm1hdGNoKC9eKC4qKS10cmFuc2l0aW9uJC8pO1xuXG4gICAgICAgIGlmICh0cmFuc2l0aW9uTWF0Y2ggJiYgbGlnaHRTcGVjW3RyYW5zaXRpb25NYXRjaFsxXV0gJiYgbGlnaHRTcGVjW3RyYW5zaXRpb25NYXRjaFsxXV0udHJhbnNpdGlvbikge1xuICAgICAgICAgICAgZXJyb3JzID0gZXJyb3JzLmNvbmNhdCh2YWxpZGF0ZSh7XG4gICAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICAgIHZhbHVlOiBsaWdodFtrZXldLFxuICAgICAgICAgICAgICAgIHZhbHVlU3BlYzogc3R5bGVTcGVjLnRyYW5zaXRpb24sXG4gICAgICAgICAgICAgICAgc3R5bGUsXG4gICAgICAgICAgICAgICAgc3R5bGVTcGVjXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgIH0gZWxzZSBpZiAobGlnaHRTcGVjW2tleV0pIHtcbiAgICAgICAgICAgIGVycm9ycyA9IGVycm9ycy5jb25jYXQodmFsaWRhdGUoe1xuICAgICAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogbGlnaHRba2V5XSxcbiAgICAgICAgICAgICAgICB2YWx1ZVNwZWM6IGxpZ2h0U3BlY1trZXldLFxuICAgICAgICAgICAgICAgIHN0eWxlLFxuICAgICAgICAgICAgICAgIHN0eWxlU3BlY1xuICAgICAgICAgICAgfSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZXJyb3JzID0gZXJyb3JzLmNvbmNhdChbbmV3IFZhbGlkYXRpb25FcnJvcihrZXksIGxpZ2h0W2tleV0sIGB1bmtub3duIHByb3BlcnR5IFwiJHtrZXl9XCJgKV0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGVycm9ycztcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBWYWxpZGF0aW9uRXJyb3IgZnJvbSAnLi4vZXJyb3IvdmFsaWRhdGlvbl9lcnJvci5qcyc7XG5pbXBvcnQgdmFsaWRhdGUgZnJvbSAnLi92YWxpZGF0ZS5qcyc7XG5pbXBvcnQgZ2V0VHlwZSBmcm9tICcuLi91dGlsL2dldF90eXBlLmpzJztcbmltcG9ydCB7dW5idW5kbGV9IGZyb20gJy4uL3V0aWwvdW5idW5kbGVfanNvbmxpbnQuanMnO1xuXG5pbXBvcnQgdHlwZSB7VmFsaWRhdGlvbk9wdGlvbnN9IGZyb20gJy4vdmFsaWRhdGUuanMnO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB2YWxpZGF0ZVRlcnJhaW4ob3B0aW9uczogVmFsaWRhdGlvbk9wdGlvbnMpOiBBcnJheTxWYWxpZGF0aW9uRXJyb3I+IHtcbiAgICBjb25zdCB0ZXJyYWluID0gb3B0aW9ucy52YWx1ZTtcbiAgICBjb25zdCBrZXkgPSBvcHRpb25zLmtleTtcbiAgICBjb25zdCBzdHlsZSA9IG9wdGlvbnMuc3R5bGU7XG4gICAgY29uc3Qgc3R5bGVTcGVjID0gb3B0aW9ucy5zdHlsZVNwZWM7XG4gICAgY29uc3QgdGVycmFpblNwZWMgPSBzdHlsZVNwZWMudGVycmFpbjtcbiAgICBsZXQgZXJyb3JzID0gW107XG5cbiAgICBjb25zdCByb290VHlwZSA9IGdldFR5cGUodGVycmFpbik7XG4gICAgaWYgKHRlcnJhaW4gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gZXJyb3JzO1xuICAgIH0gZWxzZSBpZiAocm9vdFR5cGUgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycyA9IGVycm9ycy5jb25jYXQoW25ldyBWYWxpZGF0aW9uRXJyb3IoJ3RlcnJhaW4nLCB0ZXJyYWluLCBgb2JqZWN0IGV4cGVjdGVkLCAke3Jvb3RUeXBlfSBmb3VuZGApXSk7XG4gICAgICAgIHJldHVybiBlcnJvcnM7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBrZXkgaW4gdGVycmFpbikge1xuICAgICAgICBjb25zdCB0cmFuc2l0aW9uTWF0Y2ggPSBrZXkubWF0Y2goL14oLiopLXRyYW5zaXRpb24kLyk7XG5cbiAgICAgICAgaWYgKHRyYW5zaXRpb25NYXRjaCAmJiB0ZXJyYWluU3BlY1t0cmFuc2l0aW9uTWF0Y2hbMV1dICYmIHRlcnJhaW5TcGVjW3RyYW5zaXRpb25NYXRjaFsxXV0udHJhbnNpdGlvbikge1xuICAgICAgICAgICAgZXJyb3JzID0gZXJyb3JzLmNvbmNhdCh2YWxpZGF0ZSh7XG4gICAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICAgIHZhbHVlOiB0ZXJyYWluW2tleV0sXG4gICAgICAgICAgICAgICAgdmFsdWVTcGVjOiBzdHlsZVNwZWMudHJhbnNpdGlvbixcbiAgICAgICAgICAgICAgICBzdHlsZSxcbiAgICAgICAgICAgICAgICBzdHlsZVNwZWNcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgfSBlbHNlIGlmICh0ZXJyYWluU3BlY1trZXldKSB7XG4gICAgICAgICAgICBlcnJvcnMgPSBlcnJvcnMuY29uY2F0KHZhbGlkYXRlKHtcbiAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgdmFsdWU6IHRlcnJhaW5ba2V5XSxcbiAgICAgICAgICAgICAgICB2YWx1ZVNwZWM6IHRlcnJhaW5TcGVjW2tleV0sXG4gICAgICAgICAgICAgICAgc3R5bGUsXG4gICAgICAgICAgICAgICAgc3R5bGVTcGVjXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlcnJvcnMgPSBlcnJvcnMuY29uY2F0KFtuZXcgVmFsaWRhdGlvbkVycm9yKGtleSwgdGVycmFpbltrZXldLCBgdW5rbm93biBwcm9wZXJ0eSBcIiR7a2V5fVwiYCldKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmICghdGVycmFpbi5zb3VyY2UpIHtcbiAgICAgICAgZXJyb3JzLnB1c2gobmV3IFZhbGlkYXRpb25FcnJvcihrZXksIHRlcnJhaW4sIGB0ZXJyYWluIGlzIG1pc3NpbmcgcmVxdWlyZWQgcHJvcGVydHkgXCJzb3VyY2VcImApKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBzb3VyY2UgPSBzdHlsZS5zb3VyY2VzICYmIHN0eWxlLnNvdXJjZXNbdGVycmFpbi5zb3VyY2VdO1xuICAgICAgICBjb25zdCBzb3VyY2VUeXBlID0gc291cmNlICYmIHVuYnVuZGxlKHNvdXJjZS50eXBlKTtcbiAgICAgICAgaWYgKCFzb3VyY2UpIHtcbiAgICAgICAgICAgIGVycm9ycy5wdXNoKG5ldyBWYWxpZGF0aW9uRXJyb3Ioa2V5LCB0ZXJyYWluLnNvdXJjZSwgYHNvdXJjZSBcIiR7dGVycmFpbi5zb3VyY2V9XCIgbm90IGZvdW5kYCkpO1xuICAgICAgICB9IGVsc2UgaWYgKHNvdXJjZVR5cGUgIT09ICdyYXN0ZXItZGVtJykge1xuICAgICAgICAgICAgZXJyb3JzLnB1c2gobmV3IFZhbGlkYXRpb25FcnJvcihrZXksIHRlcnJhaW4uc291cmNlLCBgdGVycmFpbiBjYW5ub3QgYmUgdXNlZCB3aXRoIGEgc291cmNlIG9mIHR5cGUgJHtTdHJpbmcoc291cmNlVHlwZSl9LCBpdCBvbmx5IGJlIHVzZWQgd2l0aCBhIFwicmFzdGVyLWRlbVwiIHNvdXJjZSB0eXBlYCkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGVycm9ycztcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBWYWxpZGF0aW9uRXJyb3IgZnJvbSAnLi4vZXJyb3IvdmFsaWRhdGlvbl9lcnJvci5qcyc7XG5pbXBvcnQgdmFsaWRhdGUgZnJvbSAnLi92YWxpZGF0ZS5qcyc7XG5pbXBvcnQgZ2V0VHlwZSBmcm9tICcuLi91dGlsL2dldF90eXBlLmpzJztcblxuaW1wb3J0IHR5cGUge1ZhbGlkYXRpb25PcHRpb25zfSBmcm9tICcuL3ZhbGlkYXRlLmpzJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdmFsaWRhdGVGb2cob3B0aW9uczogVmFsaWRhdGlvbk9wdGlvbnMpOiBBcnJheTxWYWxpZGF0aW9uRXJyb3I+IHtcbiAgICBjb25zdCBmb2cgPSBvcHRpb25zLnZhbHVlO1xuICAgIGNvbnN0IHN0eWxlID0gb3B0aW9ucy5zdHlsZTtcbiAgICBjb25zdCBzdHlsZVNwZWMgPSBvcHRpb25zLnN0eWxlU3BlYztcbiAgICBjb25zdCBmb2dTcGVjID0gc3R5bGVTcGVjLmZvZztcbiAgICBsZXQgZXJyb3JzID0gW107XG5cbiAgICBjb25zdCByb290VHlwZSA9IGdldFR5cGUoZm9nKTtcbiAgICBpZiAoZm9nID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGVycm9ycztcbiAgICB9IGVsc2UgaWYgKHJvb3RUeXBlICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMgPSBlcnJvcnMuY29uY2F0KFtuZXcgVmFsaWRhdGlvbkVycm9yKCdmb2cnLCBmb2csIGBvYmplY3QgZXhwZWN0ZWQsICR7cm9vdFR5cGV9IGZvdW5kYCldKTtcbiAgICAgICAgcmV0dXJuIGVycm9ycztcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGtleSBpbiBmb2cpIHtcbiAgICAgICAgY29uc3QgdHJhbnNpdGlvbk1hdGNoID0ga2V5Lm1hdGNoKC9eKC4qKS10cmFuc2l0aW9uJC8pO1xuXG4gICAgICAgIGlmICh0cmFuc2l0aW9uTWF0Y2ggJiYgZm9nU3BlY1t0cmFuc2l0aW9uTWF0Y2hbMV1dICYmIGZvZ1NwZWNbdHJhbnNpdGlvbk1hdGNoWzFdXS50cmFuc2l0aW9uKSB7XG4gICAgICAgICAgICBlcnJvcnMgPSBlcnJvcnMuY29uY2F0KHZhbGlkYXRlKHtcbiAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgdmFsdWU6IGZvZ1trZXldLFxuICAgICAgICAgICAgICAgIHZhbHVlU3BlYzogc3R5bGVTcGVjLnRyYW5zaXRpb24sXG4gICAgICAgICAgICAgICAgc3R5bGUsXG4gICAgICAgICAgICAgICAgc3R5bGVTcGVjXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZm9nU3BlY1trZXldKSB7XG4gICAgICAgICAgICBlcnJvcnMgPSBlcnJvcnMuY29uY2F0KHZhbGlkYXRlKHtcbiAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgdmFsdWU6IGZvZ1trZXldLFxuICAgICAgICAgICAgICAgIHZhbHVlU3BlYzogZm9nU3BlY1trZXldLFxuICAgICAgICAgICAgICAgIHN0eWxlLFxuICAgICAgICAgICAgICAgIHN0eWxlU3BlY1xuICAgICAgICAgICAgfSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZXJyb3JzID0gZXJyb3JzLmNvbmNhdChbbmV3IFZhbGlkYXRpb25FcnJvcihrZXksIGZvZ1trZXldLCBgdW5rbm93biBwcm9wZXJ0eSBcIiR7a2V5fVwiYCldKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBlcnJvcnM7XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgdmFsaWRhdGVFeHByZXNzaW9uIGZyb20gJy4vdmFsaWRhdGVfZXhwcmVzc2lvbi5qcyc7XG5pbXBvcnQgdmFsaWRhdGVTdHJpbmcgZnJvbSAnLi92YWxpZGF0ZV9zdHJpbmcuanMnO1xuXG5pbXBvcnQgdHlwZSB7VmFsaWRhdGlvbk9wdGlvbnN9IGZyb20gJy4vdmFsaWRhdGUuanMnO1xuaW1wb3J0IHR5cGUgVmFsaWRhdGlvbkVycm9yIGZyb20gJy4uL2Vycm9yL3ZhbGlkYXRpb25fZXJyb3IuanMnO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB2YWxpZGF0ZUZvcm1hdHRlZChvcHRpb25zOiBWYWxpZGF0aW9uT3B0aW9ucyk6IEFycmF5PFZhbGlkYXRpb25FcnJvcj4ge1xuICAgIGlmICh2YWxpZGF0ZVN0cmluZyhvcHRpb25zKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIHJldHVybiB2YWxpZGF0ZUV4cHJlc3Npb24ob3B0aW9ucyk7XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgdmFsaWRhdGVFeHByZXNzaW9uIGZyb20gJy4vdmFsaWRhdGVfZXhwcmVzc2lvbi5qcyc7XG5pbXBvcnQgdmFsaWRhdGVTdHJpbmcgZnJvbSAnLi92YWxpZGF0ZV9zdHJpbmcuanMnO1xuXG5pbXBvcnQgdHlwZSB7VmFsaWRhdGlvbk9wdGlvbnN9IGZyb20gJy4vdmFsaWRhdGUuanMnO1xuaW1wb3J0IHR5cGUgVmFsaWRhdGlvbkVycm9yIGZyb20gJy4uL2Vycm9yL3ZhbGlkYXRpb25fZXJyb3IuanMnO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB2YWxpZGF0ZUltYWdlKG9wdGlvbnM6IFZhbGlkYXRpb25PcHRpb25zKTogQXJyYXk8VmFsaWRhdGlvbkVycm9yPiB7XG4gICAgaWYgKHZhbGlkYXRlU3RyaW5nKG9wdGlvbnMpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbGlkYXRlRXhwcmVzc2lvbihvcHRpb25zKTtcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBWYWxpZGF0aW9uRXJyb3IgZnJvbSAnLi4vZXJyb3IvdmFsaWRhdGlvbl9lcnJvci5qcyc7XG5pbXBvcnQgZ2V0VHlwZSBmcm9tICcuLi91dGlsL2dldF90eXBlLmpzJztcbmltcG9ydCB2YWxpZGF0ZSBmcm9tICcuL3ZhbGlkYXRlLmpzJztcblxuaW1wb3J0IHR5cGUge1ZhbGlkYXRpb25PcHRpb25zfSBmcm9tICcuL3ZhbGlkYXRlLmpzJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdmFsaWRhdGVQcm9qZWN0aW9uKG9wdGlvbnM6IFZhbGlkYXRpb25PcHRpb25zKTogQXJyYXk8VmFsaWRhdGlvbkVycm9yPiB7XG4gICAgY29uc3QgcHJvamVjdGlvbiA9IG9wdGlvbnMudmFsdWU7XG4gICAgY29uc3Qgc3R5bGVTcGVjID0gb3B0aW9ucy5zdHlsZVNwZWM7XG4gICAgY29uc3QgcHJvamVjdGlvblNwZWMgPSBzdHlsZVNwZWMucHJvamVjdGlvbjtcbiAgICBjb25zdCBzdHlsZSA9IG9wdGlvbnMuc3R5bGU7XG5cbiAgICBsZXQgZXJyb3JzID0gW107XG5cbiAgICBjb25zdCByb290VHlwZSA9IGdldFR5cGUocHJvamVjdGlvbik7XG5cbiAgICBpZiAocm9vdFR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIHByb2plY3Rpb24pIHtcbiAgICAgICAgICAgIGVycm9ycyA9IGVycm9ycy5jb25jYXQodmFsaWRhdGUoe1xuICAgICAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogcHJvamVjdGlvbltrZXldLFxuICAgICAgICAgICAgICAgIHZhbHVlU3BlYzogcHJvamVjdGlvblNwZWNba2V5XSxcbiAgICAgICAgICAgICAgICBzdHlsZSxcbiAgICAgICAgICAgICAgICBzdHlsZVNwZWNcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAocm9vdFR5cGUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGVycm9ycyA9IGVycm9ycy5jb25jYXQoW25ldyBWYWxpZGF0aW9uRXJyb3IoJ3Byb2plY3Rpb24nLCBwcm9qZWN0aW9uLCBgb2JqZWN0IG9yIHN0cmluZyBleHBlY3RlZCwgJHtyb290VHlwZX0gZm91bmRgKV0pO1xuICAgIH1cblxuICAgIHJldHVybiBlcnJvcnM7XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgZXh0ZW5kIGZyb20gJy4uL3V0aWwvZXh0ZW5kLmpzJztcbmltcG9ydCB7dW5idW5kbGUsIGRlZXBVbmJ1bmRsZX0gZnJvbSAnLi4vdXRpbC91bmJ1bmRsZV9qc29ubGludC5qcyc7XG5pbXBvcnQge2lzRXhwcmVzc2lvbn0gZnJvbSAnLi4vZXhwcmVzc2lvbi9pbmRleC5qcyc7XG5pbXBvcnQge2lzRnVuY3Rpb259IGZyb20gJy4uL2Z1bmN0aW9uL2luZGV4LmpzJztcblxuaW1wb3J0IHZhbGlkYXRlRnVuY3Rpb24gZnJvbSAnLi92YWxpZGF0ZV9mdW5jdGlvbi5qcyc7XG5pbXBvcnQgdmFsaWRhdGVFeHByZXNzaW9uIGZyb20gJy4vdmFsaWRhdGVfZXhwcmVzc2lvbi5qcyc7XG5pbXBvcnQgdmFsaWRhdGVPYmplY3QgZnJvbSAnLi92YWxpZGF0ZV9vYmplY3QuanMnO1xuaW1wb3J0IHZhbGlkYXRlQXJyYXkgZnJvbSAnLi92YWxpZGF0ZV9hcnJheS5qcyc7XG5pbXBvcnQgdmFsaWRhdGVCb29sZWFuIGZyb20gJy4vdmFsaWRhdGVfYm9vbGVhbi5qcyc7XG5pbXBvcnQgdmFsaWRhdGVOdW1iZXIgZnJvbSAnLi92YWxpZGF0ZV9udW1iZXIuanMnO1xuaW1wb3J0IHZhbGlkYXRlQ29sb3IgZnJvbSAnLi92YWxpZGF0ZV9jb2xvci5qcyc7XG5pbXBvcnQgdmFsaWRhdGVFbnVtIGZyb20gJy4vdmFsaWRhdGVfZW51bS5qcyc7XG5pbXBvcnQgdmFsaWRhdGVGaWx0ZXIgZnJvbSAnLi92YWxpZGF0ZV9maWx0ZXIuanMnO1xuaW1wb3J0IHZhbGlkYXRlTGF5ZXIgZnJvbSAnLi92YWxpZGF0ZV9sYXllci5qcyc7XG5pbXBvcnQgdmFsaWRhdGVTb3VyY2UgZnJvbSAnLi92YWxpZGF0ZV9zb3VyY2UuanMnO1xuaW1wb3J0IHZhbGlkYXRlTGlnaHQgZnJvbSAnLi92YWxpZGF0ZV9saWdodC5qcyc7XG5pbXBvcnQgdmFsaWRhdGVUZXJyYWluIGZyb20gJy4vdmFsaWRhdGVfdGVycmFpbi5qcyc7XG5pbXBvcnQgdmFsaWRhdGVGb2cgZnJvbSAnLi92YWxpZGF0ZV9mb2cuanMnO1xuaW1wb3J0IHZhbGlkYXRlU3RyaW5nIGZyb20gJy4vdmFsaWRhdGVfc3RyaW5nLmpzJztcbmltcG9ydCB2YWxpZGF0ZUZvcm1hdHRlZCBmcm9tICcuL3ZhbGlkYXRlX2Zvcm1hdHRlZC5qcyc7XG5pbXBvcnQgdmFsaWRhdGVJbWFnZSBmcm9tICcuL3ZhbGlkYXRlX2ltYWdlLmpzJztcbmltcG9ydCB2YWxpZGF0ZVByb2plY3Rpb24gZnJvbSAnLi92YWxpZGF0ZV9wcm9qZWN0aW9uLmpzJztcblxuaW1wb3J0IHR5cGUge1N0eWxlUmVmZXJlbmNlfSBmcm9tICcuLi9yZWZlcmVuY2UvbGF0ZXN0LmpzJztcbmltcG9ydCB0eXBlIHtTdHlsZVNwZWNpZmljYXRpb259IGZyb20gJy4uL3R5cGVzLmpzJztcbmltcG9ydCB0eXBlIFZhbGlkYXRpb25FcnJvciBmcm9tICcuLi9lcnJvci92YWxpZGF0aW9uX2Vycm9yLmpzJztcblxuY29uc3QgVkFMSURBVE9SUyA9IHtcbiAgICAnKicoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICB9LFxuICAgICdhcnJheSc6IHZhbGlkYXRlQXJyYXksXG4gICAgJ2Jvb2xlYW4nOiB2YWxpZGF0ZUJvb2xlYW4sXG4gICAgJ251bWJlcic6IHZhbGlkYXRlTnVtYmVyLFxuICAgICdjb2xvcic6IHZhbGlkYXRlQ29sb3IsXG4gICAgJ2VudW0nOiB2YWxpZGF0ZUVudW0sXG4gICAgJ2ZpbHRlcic6IHZhbGlkYXRlRmlsdGVyLFxuICAgICdmdW5jdGlvbic6IHZhbGlkYXRlRnVuY3Rpb24sXG4gICAgJ2xheWVyJzogdmFsaWRhdGVMYXllcixcbiAgICAnb2JqZWN0JzogdmFsaWRhdGVPYmplY3QsXG4gICAgJ3NvdXJjZSc6IHZhbGlkYXRlU291cmNlLFxuICAgICdsaWdodCc6IHZhbGlkYXRlTGlnaHQsXG4gICAgJ3RlcnJhaW4nOiB2YWxpZGF0ZVRlcnJhaW4sXG4gICAgJ2ZvZyc6IHZhbGlkYXRlRm9nLFxuICAgICdzdHJpbmcnOiB2YWxpZGF0ZVN0cmluZyxcbiAgICAnZm9ybWF0dGVkJzogdmFsaWRhdGVGb3JtYXR0ZWQsXG4gICAgJ3Jlc29sdmVkSW1hZ2UnOiB2YWxpZGF0ZUltYWdlLFxuICAgICdwcm9qZWN0aW9uJzogdmFsaWRhdGVQcm9qZWN0aW9uXG59O1xuXG4vLyBNYWluIHJlY3Vyc2l2ZSB2YWxpZGF0aW9uIGZ1bmN0aW9uLiBUcmFja3M6XG4vL1xuLy8gLSBrZXk6IHN0cmluZyByZXByZXNlbnRpbmcgbG9jYXRpb24gb2YgdmFsaWRhdGlvbiBpbiBzdHlsZSB0cmVlLiBVc2VkIG9ubHlcbi8vICAgZm9yIG1vcmUgaW5mb3JtYXRpdmUgZXJyb3IgcmVwb3J0aW5nLlxuLy8gLSB2YWx1ZTogY3VycmVudCB2YWx1ZSBmcm9tIHN0eWxlIGJlaW5nIGV2YWx1YXRlZC4gTWF5IGJlIGFueXRoaW5nIGZyb20gYVxuLy8gICBoaWdoIGxldmVsIG9iamVjdCB0aGF0IG5lZWRzIHRvIGJlIGRlc2NlbmRlZCBpbnRvIGRlZXBlciBvciBhIHNpbXBsZVxuLy8gICBzY2FsYXIgdmFsdWUuXG4vLyAtIHZhbHVlU3BlYzogY3VycmVudCBzcGVjIGJlaW5nIGV2YWx1YXRlZC4gVHJhY2tzIHZhbHVlLlxuLy8gLSBzdHlsZVNwZWM6IGN1cnJlbnQgZnVsbCBzcGVjIGJlaW5nIGV2YWx1YXRlZC5cbmV4cG9ydCB0eXBlIFZhbGlkYXRpb25PcHRpb25zID0ge1xuICAgIGtleTogc3RyaW5nO1xuICAgIHZhbHVlOiBPYmplY3Q7XG4gICAgdmFsdWVTcGVjOiBPYmplY3Q7XG4gICAgc3R5bGU6ICRTaGFwZTxTdHlsZVNwZWNpZmljYXRpb24+O1xuICAgIHN0eWxlU3BlYzogU3R5bGVSZWZlcmVuY2U7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHZhbGlkYXRlKG9wdGlvbnM6IFZhbGlkYXRpb25PcHRpb25zKTogQXJyYXk8VmFsaWRhdGlvbkVycm9yPiB7XG4gICAgY29uc3QgdmFsdWUgPSBvcHRpb25zLnZhbHVlO1xuICAgIGNvbnN0IHZhbHVlU3BlYyA9IG9wdGlvbnMudmFsdWVTcGVjO1xuICAgIGNvbnN0IHN0eWxlU3BlYyA9IG9wdGlvbnMuc3R5bGVTcGVjO1xuXG4gICAgaWYgKHZhbHVlU3BlYy5leHByZXNzaW9uICYmIGlzRnVuY3Rpb24odW5idW5kbGUodmFsdWUpKSkge1xuICAgICAgICByZXR1cm4gdmFsaWRhdGVGdW5jdGlvbihvcHRpb25zKTtcblxuICAgIH0gZWxzZSBpZiAodmFsdWVTcGVjLmV4cHJlc3Npb24gJiYgaXNFeHByZXNzaW9uKGRlZXBVbmJ1bmRsZSh2YWx1ZSkpKSB7XG4gICAgICAgIHJldHVybiB2YWxpZGF0ZUV4cHJlc3Npb24ob3B0aW9ucyk7XG5cbiAgICB9IGVsc2UgaWYgKHZhbHVlU3BlYy50eXBlICYmIFZBTElEQVRPUlNbdmFsdWVTcGVjLnR5cGVdKSB7XG4gICAgICAgIHJldHVybiBWQUxJREFUT1JTW3ZhbHVlU3BlYy50eXBlXShvcHRpb25zKTtcblxuICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHZhbGlkID0gdmFsaWRhdGVPYmplY3QoZXh0ZW5kKHt9LCBvcHRpb25zLCB7XG4gICAgICAgICAgICB2YWx1ZVNwZWM6IHZhbHVlU3BlYy50eXBlID8gc3R5bGVTcGVjW3ZhbHVlU3BlYy50eXBlXSA6IHZhbHVlU3BlY1xuICAgICAgICB9KSk7XG4gICAgICAgIHJldHVybiB2YWxpZDtcbiAgICB9XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgVmFsaWRhdGlvbkVycm9yIGZyb20gJy4uL2Vycm9yL3ZhbGlkYXRpb25fZXJyb3IuanMnO1xuaW1wb3J0IHZhbGlkYXRlU3RyaW5nIGZyb20gJy4vdmFsaWRhdGVfc3RyaW5nLmpzJztcblxuaW1wb3J0IHR5cGUge1ZhbGlkYXRpb25PcHRpb25zfSBmcm9tICcuL3ZhbGlkYXRlLmpzJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24ob3B0aW9uczogVmFsaWRhdGlvbk9wdGlvbnMpOiBBcnJheTxWYWxpZGF0aW9uRXJyb3I+IHtcbiAgICBjb25zdCB2YWx1ZSA9IG9wdGlvbnMudmFsdWU7XG4gICAgY29uc3Qga2V5ID0gb3B0aW9ucy5rZXk7XG5cbiAgICBjb25zdCBlcnJvcnMgPSB2YWxpZGF0ZVN0cmluZyhvcHRpb25zKTtcbiAgICBpZiAoZXJyb3JzLmxlbmd0aCkgcmV0dXJuIGVycm9ycztcblxuICAgIGlmICh2YWx1ZS5pbmRleE9mKCd7Zm9udHN0YWNrfScpID09PSAtMSkge1xuICAgICAgICBlcnJvcnMucHVzaChuZXcgVmFsaWRhdGlvbkVycm9yKGtleSwgdmFsdWUsICdcImdseXBoc1wiIHVybCBtdXN0IGluY2x1ZGUgYSBcIntmb250c3RhY2t9XCIgdG9rZW4nKSk7XG4gICAgfVxuXG4gICAgaWYgKHZhbHVlLmluZGV4T2YoJ3tyYW5nZX0nKSA9PT0gLTEpIHtcbiAgICAgICAgZXJyb3JzLnB1c2gobmV3IFZhbGlkYXRpb25FcnJvcihrZXksIHZhbHVlLCAnXCJnbHlwaHNcIiB1cmwgbXVzdCBpbmNsdWRlIGEgXCJ7cmFuZ2V9XCIgdG9rZW4nKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVycm9ycztcbn1cbiIsIi8vIEBmbG93XG5pbXBvcnQgdmFsaWRhdGUgZnJvbSAnLi92YWxpZGF0ZS92YWxpZGF0ZS5qcyc7XG5pbXBvcnQgbGF0ZXN0U3R5bGVTcGVjIGZyb20gJy4vcmVmZXJlbmNlL2xhdGVzdC5qcyc7XG5pbXBvcnQgdmFsaWRhdGVHbHlwaHNVUkwgZnJvbSAnLi92YWxpZGF0ZS92YWxpZGF0ZV9nbHlwaHNfdXJsLmpzJztcblxuaW1wb3J0IF92YWxpZGF0ZVNvdXJjZSBmcm9tICcuL3ZhbGlkYXRlL3ZhbGlkYXRlX3NvdXJjZS5qcyc7XG5pbXBvcnQgX3ZhbGlkYXRlTGlnaHQgZnJvbSAnLi92YWxpZGF0ZS92YWxpZGF0ZV9saWdodC5qcyc7XG5pbXBvcnQgX3ZhbGlkYXRlVGVycmFpbiBmcm9tICcuL3ZhbGlkYXRlL3ZhbGlkYXRlX3RlcnJhaW4uanMnO1xuaW1wb3J0IF92YWxpZGF0ZUZvZyBmcm9tICcuL3ZhbGlkYXRlL3ZhbGlkYXRlX2ZvZy5qcyc7XG5pbXBvcnQgX3ZhbGlkYXRlTGF5ZXIgZnJvbSAnLi92YWxpZGF0ZS92YWxpZGF0ZV9sYXllci5qcyc7XG5pbXBvcnQgX3ZhbGlkYXRlRmlsdGVyIGZyb20gJy4vdmFsaWRhdGUvdmFsaWRhdGVfZmlsdGVyLmpzJztcbmltcG9ydCBfdmFsaWRhdGVQYWludFByb3BlcnR5IGZyb20gJy4vdmFsaWRhdGUvdmFsaWRhdGVfcGFpbnRfcHJvcGVydHkuanMnO1xuaW1wb3J0IF92YWxpZGF0ZUxheW91dFByb3BlcnR5IGZyb20gJy4vdmFsaWRhdGUvdmFsaWRhdGVfbGF5b3V0X3Byb3BlcnR5LmpzJztcblxuaW1wb3J0IHR5cGUge1N0eWxlU3BlY2lmaWNhdGlvbn0gZnJvbSAnLi90eXBlcy5qcyc7XG5cbmV4cG9ydCB0eXBlIFZhbGlkYXRpb25FcnJvciA9IGludGVyZmFjZSB7XG4gICAgbWVzc2FnZTogc3RyaW5nLFxuICAgIGlkZW50aWZpZXI/OiA/c3RyaW5nLFxuICAgIGxpbmU/OiA/bnVtYmVyLFxufTtcbmV4cG9ydCB0eXBlIFZhbGlkYXRpb25FcnJvcnMgPSAkUmVhZE9ubHlBcnJheTxWYWxpZGF0aW9uRXJyb3I+O1xuZXhwb3J0IHR5cGUgVmFsaWRhdG9yID0gKE9iamVjdCkgPT4gVmFsaWRhdGlvbkVycm9ycztcblxuLyoqXG4gKiBWYWxpZGF0ZSBhIE1hcGJveCBHTCBzdHlsZSBhZ2FpbnN0IHRoZSBzdHlsZSBzcGVjaWZpY2F0aW9uLiBUaGlzIGVudHJ5cG9pbnQsXG4gKiBgbWFwYm94LWdsLXN0eWxlLXNwZWMvbGliL3ZhbGlkYXRlX3N0eWxlLm1pbmAsIGlzIGRlc2lnbmVkIHRvIHByb2R1Y2UgYXNcbiAqIHNtYWxsIGEgYnJvd3NlcmlmeSBidW5kbGUgYXMgcG9zc2libGUgYnkgb21pdHRpbmcgdW5uZWNlc3NhcnkgZnVuY3Rpb25hbGl0eVxuICogYW5kIGxlZ2FjeSBzdHlsZSBzcGVjaWZpY2F0aW9ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHN0eWxlIFRoZSBzdHlsZSB0byBiZSB2YWxpZGF0ZWQuXG4gKiBAcGFyYW0ge09iamVjdH0gW3N0eWxlU3BlY10gVGhlIHN0eWxlIHNwZWNpZmljYXRpb24gdG8gdmFsaWRhdGUgYWdhaW5zdC5cbiAqICAgICBJZiBvbWl0dGVkLCB0aGUgbGF0ZXN0IHN0eWxlIHNwZWMgaXMgdXNlZC5cbiAqIEByZXR1cm5zIHtBcnJheTxWYWxpZGF0aW9uRXJyb3I+fVxuICogQGV4YW1wbGVcbiAqICAgdmFyIHZhbGlkYXRlID0gcmVxdWlyZSgnbWFwYm94LWdsLXN0eWxlLXNwZWMvbGliL3ZhbGlkYXRlX3N0eWxlLm1pbicpO1xuICogICB2YXIgZXJyb3JzID0gdmFsaWRhdGUoc3R5bGUpO1xuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVTdHlsZShzdHlsZTogU3R5bGVTcGVjaWZpY2F0aW9uLCBzdHlsZVNwZWM6IE9iamVjdCA9IGxhdGVzdFN0eWxlU3BlYyk6IFZhbGlkYXRpb25FcnJvcnMge1xuXG4gICAgY29uc3QgZXJyb3JzID0gdmFsaWRhdGUoe1xuICAgICAgICBrZXk6ICcnLFxuICAgICAgICB2YWx1ZTogc3R5bGUsXG4gICAgICAgIHZhbHVlU3BlYzogc3R5bGVTcGVjLiRyb290LFxuICAgICAgICBzdHlsZVNwZWMsXG4gICAgICAgIHN0eWxlLFxuICAgICAgICBvYmplY3RFbGVtZW50VmFsaWRhdG9yczoge1xuICAgICAgICAgICAgZ2x5cGhzOiB2YWxpZGF0ZUdseXBoc1VSTCxcbiAgICAgICAgICAgICcqJzogKCkgPT4gW11cbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBzb3J0RXJyb3JzKGVycm9ycyk7XG59XG5cbmV4cG9ydCBjb25zdCB2YWxpZGF0ZVNvdXJjZTogVmFsaWRhdG9yID0gb3B0cyA9PiBzb3J0RXJyb3JzKF92YWxpZGF0ZVNvdXJjZShvcHRzKSk7XG5leHBvcnQgY29uc3QgdmFsaWRhdGVMaWdodDogVmFsaWRhdG9yID0gb3B0cyA9PiBzb3J0RXJyb3JzKF92YWxpZGF0ZUxpZ2h0KG9wdHMpKTtcbmV4cG9ydCBjb25zdCB2YWxpZGF0ZVRlcnJhaW46IFZhbGlkYXRvciA9IG9wdHMgPT4gc29ydEVycm9ycyhfdmFsaWRhdGVUZXJyYWluKG9wdHMpKTtcbmV4cG9ydCBjb25zdCB2YWxpZGF0ZUZvZzogVmFsaWRhdG9yID0gb3B0cyA9PiBzb3J0RXJyb3JzKF92YWxpZGF0ZUZvZyhvcHRzKSk7XG5leHBvcnQgY29uc3QgdmFsaWRhdGVMYXllcjogVmFsaWRhdG9yID0gb3B0cyA9PiBzb3J0RXJyb3JzKF92YWxpZGF0ZUxheWVyKG9wdHMpKTtcbmV4cG9ydCBjb25zdCB2YWxpZGF0ZUZpbHRlcjogVmFsaWRhdG9yID0gb3B0cyA9PiBzb3J0RXJyb3JzKF92YWxpZGF0ZUZpbHRlcihvcHRzKSk7XG5leHBvcnQgY29uc3QgdmFsaWRhdGVQYWludFByb3BlcnR5OiBWYWxpZGF0b3IgPSBvcHRzID0+IHNvcnRFcnJvcnMoX3ZhbGlkYXRlUGFpbnRQcm9wZXJ0eShvcHRzKSk7XG5leHBvcnQgY29uc3QgdmFsaWRhdGVMYXlvdXRQcm9wZXJ0eTogVmFsaWRhdG9yID0gb3B0cyA9PiBzb3J0RXJyb3JzKF92YWxpZGF0ZUxheW91dFByb3BlcnR5KG9wdHMpKTtcblxuZnVuY3Rpb24gc29ydEVycm9ycyhlcnJvcnM6IFZhbGlkYXRpb25FcnJvcnMpIHtcbiAgICByZXR1cm4gZXJyb3JzLnNsaWNlKCkuc29ydCgoYSwgYikgPT4gYS5saW5lICYmIGIubGluZSA/IGEubGluZSAtIGIubGluZSA6IDApO1xufVxuIiwiLy8gQGZsb3dcbmltcG9ydCB7RXJyb3JFdmVudH0gZnJvbSAnLi4vdXRpbC9ldmVudGVkLmpzJztcblxuaW1wb3J0IHR5cGUge0V2ZW50ZWR9IGZyb20gJy4uL3V0aWwvZXZlbnRlZC5qcyc7XG5pbXBvcnQgdHlwZSB7VmFsaWRhdGlvbkVycm9ycyBhcyBfVmFsaWRhdGlvbkVycm9yc30gZnJvbSAnLi4vc3R5bGUtc3BlYy92YWxpZGF0ZV9zdHlsZS5taW4uanMnO1xuXG5leHBvcnQgdHlwZSB7VmFsaWRhdG9yLCBWYWxpZGF0aW9uRXJyb3JzfSBmcm9tICcuLi9zdHlsZS1zcGVjL3ZhbGlkYXRlX3N0eWxlLm1pbi5qcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBlbWl0VmFsaWRhdGlvbkVycm9ycyhlbWl0dGVyOiBFdmVudGVkLCBlcnJvcnM6ID9fVmFsaWRhdGlvbkVycm9ycyk6IGJvb2xlYW4ge1xuICAgIGxldCBoYXNFcnJvcnMgPSBmYWxzZTtcbiAgICBpZiAoZXJyb3JzICYmIGVycm9ycy5sZW5ndGgpIHtcbiAgICAgICAgZm9yIChjb25zdCBlcnJvciBvZiBlcnJvcnMpIHtcbiAgICAgICAgICAgIGVtaXR0ZXIuZmlyZShuZXcgRXJyb3JFdmVudChuZXcgRXJyb3IoZXJyb3IubWVzc2FnZSkpKTtcbiAgICAgICAgICAgIGhhc0Vycm9ycyA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGhhc0Vycm9ycztcbn1cblxuZXhwb3J0IHtcbiAgICB2YWxpZGF0ZVN0eWxlLFxuICAgIHZhbGlkYXRlU291cmNlLFxuICAgIHZhbGlkYXRlTGlnaHQsXG4gICAgdmFsaWRhdGVUZXJyYWluLFxuICAgIHZhbGlkYXRlRm9nLFxuICAgIHZhbGlkYXRlTGF5ZXIsXG4gICAgdmFsaWRhdGVGaWx0ZXIsXG4gICAgdmFsaWRhdGVQYWludFByb3BlcnR5LFxuICAgIHZhbGlkYXRlTGF5b3V0UHJvcGVydHlcbn0gZnJvbSAnLi4vc3R5bGUtc3BlYy92YWxpZGF0ZV9zdHlsZS5taW4uanMnO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEdyaWRJbmRleDtcblxudmFyIE5VTV9QQVJBTVMgPSAzO1xuXG5mdW5jdGlvbiBHcmlkSW5kZXgoZXh0ZW50LCBuLCBwYWRkaW5nKSB7XG4gICAgdmFyIGNlbGxzID0gdGhpcy5jZWxscyA9IFtdO1xuXG4gICAgaWYgKGV4dGVudCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgICAgIHRoaXMuYXJyYXlCdWZmZXIgPSBleHRlbnQ7XG4gICAgICAgIHZhciBhcnJheSA9IG5ldyBJbnQzMkFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgICAgICBleHRlbnQgPSBhcnJheVswXTtcbiAgICAgICAgbiA9IGFycmF5WzFdO1xuICAgICAgICBwYWRkaW5nID0gYXJyYXlbMl07XG5cbiAgICAgICAgdGhpcy5kID0gbiArIDIgKiBwYWRkaW5nO1xuICAgICAgICBmb3IgKHZhciBrID0gMDsgayA8IHRoaXMuZCAqIHRoaXMuZDsgaysrKSB7XG4gICAgICAgICAgICB2YXIgc3RhcnQgPSBhcnJheVtOVU1fUEFSQU1TICsga107XG4gICAgICAgICAgICB2YXIgZW5kID0gYXJyYXlbTlVNX1BBUkFNUyArIGsgKyAxXTtcbiAgICAgICAgICAgIGNlbGxzLnB1c2goc3RhcnQgPT09IGVuZCA/XG4gICAgICAgICAgICAgICAgICAgIG51bGwgOlxuICAgICAgICAgICAgICAgICAgICBhcnJheS5zdWJhcnJheShzdGFydCwgZW5kKSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGtleXNPZmZzZXQgPSBhcnJheVtOVU1fUEFSQU1TICsgY2VsbHMubGVuZ3RoXTtcbiAgICAgICAgdmFyIGJib3hlc09mZnNldCA9IGFycmF5W05VTV9QQVJBTVMgKyBjZWxscy5sZW5ndGggKyAxXTtcbiAgICAgICAgdGhpcy5rZXlzID0gYXJyYXkuc3ViYXJyYXkoa2V5c09mZnNldCwgYmJveGVzT2Zmc2V0KTtcbiAgICAgICAgdGhpcy5iYm94ZXMgPSBhcnJheS5zdWJhcnJheShiYm94ZXNPZmZzZXQpO1xuXG4gICAgICAgIHRoaXMuaW5zZXJ0ID0gdGhpcy5faW5zZXJ0UmVhZG9ubHk7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmQgPSBuICsgMiAqIHBhZGRpbmc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5kICogdGhpcy5kOyBpKyspIHtcbiAgICAgICAgICAgIGNlbGxzLnB1c2goW10pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMua2V5cyA9IFtdO1xuICAgICAgICB0aGlzLmJib3hlcyA9IFtdO1xuICAgIH1cblxuICAgIHRoaXMubiA9IG47XG4gICAgdGhpcy5leHRlbnQgPSBleHRlbnQ7XG4gICAgdGhpcy5wYWRkaW5nID0gcGFkZGluZztcbiAgICB0aGlzLnNjYWxlID0gbiAvIGV4dGVudDtcbiAgICB0aGlzLnVpZCA9IDA7XG5cbiAgICB2YXIgcCA9IChwYWRkaW5nIC8gbikgKiBleHRlbnQ7XG4gICAgdGhpcy5taW4gPSAtcDtcbiAgICB0aGlzLm1heCA9IGV4dGVudCArIHA7XG59XG5cblxuR3JpZEluZGV4LnByb3RvdHlwZS5pbnNlcnQgPSBmdW5jdGlvbihrZXksIHgxLCB5MSwgeDIsIHkyKSB7XG4gICAgdGhpcy5fZm9yRWFjaENlbGwoeDEsIHkxLCB4MiwgeTIsIHRoaXMuX2luc2VydENlbGwsIHRoaXMudWlkKyspO1xuICAgIHRoaXMua2V5cy5wdXNoKGtleSk7XG4gICAgdGhpcy5iYm94ZXMucHVzaCh4MSk7XG4gICAgdGhpcy5iYm94ZXMucHVzaCh5MSk7XG4gICAgdGhpcy5iYm94ZXMucHVzaCh4Mik7XG4gICAgdGhpcy5iYm94ZXMucHVzaCh5Mik7XG59O1xuXG5HcmlkSW5kZXgucHJvdG90eXBlLl9pbnNlcnRSZWFkb25seSA9IGZ1bmN0aW9uKCkge1xuICAgIHRocm93ICdDYW5ub3QgaW5zZXJ0IGludG8gYSBHcmlkSW5kZXggY3JlYXRlZCBmcm9tIGFuIEFycmF5QnVmZmVyLic7XG59O1xuXG5HcmlkSW5kZXgucHJvdG90eXBlLl9pbnNlcnRDZWxsID0gZnVuY3Rpb24oeDEsIHkxLCB4MiwgeTIsIGNlbGxJbmRleCwgdWlkKSB7XG4gICAgdGhpcy5jZWxsc1tjZWxsSW5kZXhdLnB1c2godWlkKTtcbn07XG5cbkdyaWRJbmRleC5wcm90b3R5cGUucXVlcnkgPSBmdW5jdGlvbih4MSwgeTEsIHgyLCB5MiwgaW50ZXJzZWN0aW9uVGVzdCkge1xuICAgIHZhciBtaW4gPSB0aGlzLm1pbjtcbiAgICB2YXIgbWF4ID0gdGhpcy5tYXg7XG4gICAgaWYgKHgxIDw9IG1pbiAmJiB5MSA8PSBtaW4gJiYgbWF4IDw9IHgyICYmIG1heCA8PSB5MiAmJiAhaW50ZXJzZWN0aW9uVGVzdCkge1xuICAgICAgICAvLyBXZSB1c2UgYEFycmF5I3NsaWNlYCBiZWNhdXNlIGB0aGlzLmtleXNgIG1heSBiZSBhIGBJbnQzMkFycmF5YCBhbmRcbiAgICAgICAgLy8gc29tZSBicm93c2VycyAoU2FmYXJpIGFuZCBJRSkgZG8gbm90IHN1cHBvcnQgYFR5cGVkQXJyYXkjc2xpY2VgXG4gICAgICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL1R5cGVkQXJyYXkvc2xpY2UjQnJvd3Nlcl9jb21wYXRpYmlsaXR5XG4gICAgICAgIHJldHVybiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh0aGlzLmtleXMpO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgICB2YXIgc2VlblVpZHMgPSB7fTtcbiAgICAgICAgdGhpcy5fZm9yRWFjaENlbGwoeDEsIHkxLCB4MiwgeTIsIHRoaXMuX3F1ZXJ5Q2VsbCwgcmVzdWx0LCBzZWVuVWlkcywgaW50ZXJzZWN0aW9uVGVzdCk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxufTtcblxuR3JpZEluZGV4LnByb3RvdHlwZS5fcXVlcnlDZWxsID0gZnVuY3Rpb24oeDEsIHkxLCB4MiwgeTIsIGNlbGxJbmRleCwgcmVzdWx0LCBzZWVuVWlkcywgaW50ZXJzZWN0aW9uVGVzdCkge1xuICAgIHZhciBjZWxsID0gdGhpcy5jZWxsc1tjZWxsSW5kZXhdO1xuICAgIGlmIChjZWxsICE9PSBudWxsKSB7XG4gICAgICAgIHZhciBrZXlzID0gdGhpcy5rZXlzO1xuICAgICAgICB2YXIgYmJveGVzID0gdGhpcy5iYm94ZXM7XG4gICAgICAgIGZvciAodmFyIHUgPSAwOyB1IDwgY2VsbC5sZW5ndGg7IHUrKykge1xuICAgICAgICAgICAgdmFyIHVpZCA9IGNlbGxbdV07XG4gICAgICAgICAgICBpZiAoc2VlblVpZHNbdWlkXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdmFyIG9mZnNldCA9IHVpZCAqIDQ7XG4gICAgICAgICAgICAgICAgaWYgKGludGVyc2VjdGlvblRlc3QgP1xuICAgICAgICAgICAgICAgICAgICBpbnRlcnNlY3Rpb25UZXN0KGJib3hlc1tvZmZzZXQgKyAwXSwgYmJveGVzW29mZnNldCArIDFdLCBiYm94ZXNbb2Zmc2V0ICsgMl0sIGJib3hlc1tvZmZzZXQgKyAzXSkgOlxuICAgICAgICAgICAgICAgICAgICAoKHgxIDw9IGJib3hlc1tvZmZzZXQgKyAyXSkgJiZcbiAgICAgICAgICAgICAgICAgICAgKHkxIDw9IGJib3hlc1tvZmZzZXQgKyAzXSkgJiZcbiAgICAgICAgICAgICAgICAgICAgKHgyID49IGJib3hlc1tvZmZzZXQgKyAwXSkgJiZcbiAgICAgICAgICAgICAgICAgICAgKHkyID49IGJib3hlc1tvZmZzZXQgKyAxXSkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlZW5VaWRzW3VpZF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChrZXlzW3VpZF0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHNlZW5VaWRzW3VpZF0gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5HcmlkSW5kZXgucHJvdG90eXBlLl9mb3JFYWNoQ2VsbCA9IGZ1bmN0aW9uKHgxLCB5MSwgeDIsIHkyLCBmbiwgYXJnMSwgYXJnMiwgaW50ZXJzZWN0aW9uVGVzdCkge1xuICAgIHZhciBjeDEgPSB0aGlzLl9jb252ZXJ0VG9DZWxsQ29vcmQoeDEpO1xuICAgIHZhciBjeTEgPSB0aGlzLl9jb252ZXJ0VG9DZWxsQ29vcmQoeTEpO1xuICAgIHZhciBjeDIgPSB0aGlzLl9jb252ZXJ0VG9DZWxsQ29vcmQoeDIpO1xuICAgIHZhciBjeTIgPSB0aGlzLl9jb252ZXJ0VG9DZWxsQ29vcmQoeTIpO1xuICAgIGZvciAodmFyIHggPSBjeDE7IHggPD0gY3gyOyB4KyspIHtcbiAgICAgICAgZm9yICh2YXIgeSA9IGN5MTsgeSA8PSBjeTI7IHkrKykge1xuICAgICAgICAgICAgdmFyIGNlbGxJbmRleCA9IHRoaXMuZCAqIHkgKyB4O1xuICAgICAgICAgICAgaWYgKGludGVyc2VjdGlvblRlc3QgJiYgIWludGVyc2VjdGlvblRlc3QoXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jb252ZXJ0RnJvbUNlbGxDb29yZCh4KSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2NvbnZlcnRGcm9tQ2VsbENvb3JkKHkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY29udmVydEZyb21DZWxsQ29vcmQoeCArIDEpLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY29udmVydEZyb21DZWxsQ29vcmQoeSArIDEpKSkgY29udGludWU7XG4gICAgICAgICAgICBpZiAoZm4uY2FsbCh0aGlzLCB4MSwgeTEsIHgyLCB5MiwgY2VsbEluZGV4LCBhcmcxLCBhcmcyLCBpbnRlcnNlY3Rpb25UZXN0KSkgcmV0dXJuO1xuICAgICAgICB9XG4gICAgfVxufTtcblxuR3JpZEluZGV4LnByb3RvdHlwZS5fY29udmVydEZyb21DZWxsQ29vcmQgPSBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuICh4IC0gdGhpcy5wYWRkaW5nKSAvIHRoaXMuc2NhbGU7XG59O1xuXG5HcmlkSW5kZXgucHJvdG90eXBlLl9jb252ZXJ0VG9DZWxsQ29vcmQgPSBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIE1hdGgubWF4KDAsIE1hdGgubWluKHRoaXMuZCAtIDEsIE1hdGguZmxvb3IoeCAqIHRoaXMuc2NhbGUpICsgdGhpcy5wYWRkaW5nKSk7XG59O1xuXG5HcmlkSW5kZXgucHJvdG90eXBlLnRvQXJyYXlCdWZmZXIgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5hcnJheUJ1ZmZlcikgcmV0dXJuIHRoaXMuYXJyYXlCdWZmZXI7XG5cbiAgICB2YXIgY2VsbHMgPSB0aGlzLmNlbGxzO1xuXG4gICAgdmFyIG1ldGFkYXRhTGVuZ3RoID0gTlVNX1BBUkFNUyArIHRoaXMuY2VsbHMubGVuZ3RoICsgMSArIDE7XG4gICAgdmFyIHRvdGFsQ2VsbExlbmd0aCA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmNlbGxzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRvdGFsQ2VsbExlbmd0aCArPSB0aGlzLmNlbGxzW2ldLmxlbmd0aDtcbiAgICB9XG5cbiAgICB2YXIgYXJyYXkgPSBuZXcgSW50MzJBcnJheShtZXRhZGF0YUxlbmd0aCArIHRvdGFsQ2VsbExlbmd0aCArIHRoaXMua2V5cy5sZW5ndGggKyB0aGlzLmJib3hlcy5sZW5ndGgpO1xuICAgIGFycmF5WzBdID0gdGhpcy5leHRlbnQ7XG4gICAgYXJyYXlbMV0gPSB0aGlzLm47XG4gICAgYXJyYXlbMl0gPSB0aGlzLnBhZGRpbmc7XG5cbiAgICB2YXIgb2Zmc2V0ID0gbWV0YWRhdGFMZW5ndGg7XG4gICAgZm9yICh2YXIgayA9IDA7IGsgPCBjZWxscy5sZW5ndGg7IGsrKykge1xuICAgICAgICB2YXIgY2VsbCA9IGNlbGxzW2tdO1xuICAgICAgICBhcnJheVtOVU1fUEFSQU1TICsga10gPSBvZmZzZXQ7XG4gICAgICAgIGFycmF5LnNldChjZWxsLCBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgKz0gY2VsbC5sZW5ndGg7XG4gICAgfVxuXG4gICAgYXJyYXlbTlVNX1BBUkFNUyArIGNlbGxzLmxlbmd0aF0gPSBvZmZzZXQ7XG4gICAgYXJyYXkuc2V0KHRoaXMua2V5cywgb2Zmc2V0KTtcbiAgICBvZmZzZXQgKz0gdGhpcy5rZXlzLmxlbmd0aDtcblxuICAgIGFycmF5W05VTV9QQVJBTVMgKyBjZWxscy5sZW5ndGggKyAxXSA9IG9mZnNldDtcbiAgICBhcnJheS5zZXQodGhpcy5iYm94ZXMsIG9mZnNldCk7XG4gICAgb2Zmc2V0ICs9IHRoaXMuYmJveGVzLmxlbmd0aDtcblxuICAgIHJldHVybiBhcnJheS5idWZmZXI7XG59O1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuXG5pbXBvcnQgR3JpZCBmcm9tICdncmlkLWluZGV4JztcbmltcG9ydCBDb2xvciBmcm9tICcuLi9zdHlsZS1zcGVjL3V0aWwvY29sb3IuanMnO1xuaW1wb3J0IHtTdHlsZVByb3BlcnR5RnVuY3Rpb24sIFN0eWxlRXhwcmVzc2lvbiwgWm9vbURlcGVuZGVudEV4cHJlc3Npb24sIFpvb21Db25zdGFudEV4cHJlc3Npb259IGZyb20gJy4uL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi9pbmRleC5qcyc7XG5pbXBvcnQgQ29tcG91bmRFeHByZXNzaW9uIGZyb20gJy4uL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi9jb21wb3VuZF9leHByZXNzaW9uLmpzJztcbmltcG9ydCBleHByZXNzaW9ucyBmcm9tICcuLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vZGVmaW5pdGlvbnMvaW5kZXguanMnO1xuaW1wb3J0IFJlc29sdmVkSW1hZ2UgZnJvbSAnLi4vc3R5bGUtc3BlYy9leHByZXNzaW9uL3R5cGVzL3Jlc29sdmVkX2ltYWdlLmpzJztcbmltcG9ydCB3aW5kb3cgZnJvbSAnLi93aW5kb3cuanMnO1xuaW1wb3J0IHtBSkFYRXJyb3J9IGZyb20gJy4vYWpheC5qcyc7XG5cbmltcG9ydCB0eXBlIHtUcmFuc2ZlcmFibGV9IGZyb20gJy4uL3R5cGVzL3RyYW5zZmVyYWJsZS5qcyc7XG5cbnR5cGUgU2VyaWFsaXplZE9iamVjdCA9IGludGVyZmFjZSB7IFtfOiBzdHJpbmddOiBTZXJpYWxpemVkIH07XG5leHBvcnQgdHlwZSBTZXJpYWxpemVkID1cbiAgICB8IG51bGxcbiAgICB8IHZvaWRcbiAgICB8IGJvb2xlYW5cbiAgICB8IG51bWJlclxuICAgIHwgc3RyaW5nXG4gICAgfCBCb29sZWFuXG4gICAgfCBOdW1iZXJcbiAgICB8IFN0cmluZ1xuICAgIHwgRGF0ZVxuICAgIHwgUmVnRXhwXG4gICAgfCBBcnJheUJ1ZmZlclxuICAgIHwgJEFycmF5QnVmZmVyVmlld1xuICAgIHwgSW1hZ2VEYXRhXG4gICAgfCBBcnJheTxTZXJpYWxpemVkPlxuICAgIHwgU2VyaWFsaXplZE9iamVjdDtcblxudHlwZSBSZWdpc3RyeSA9IHtcbiAgICBbXzogc3RyaW5nXToge1xuICAgICAgICBrbGFzczogQ2xhc3M8YW55PixcbiAgICAgICAgb21pdDogJFJlYWRPbmx5QXJyYXk8c3RyaW5nPlxuICAgIH1cbn07XG5cbnR5cGUgUmVnaXN0ZXJPcHRpb25zPFQ+ID0ge1xuICAgIG9taXQ/OiAkUmVhZE9ubHlBcnJheTwkS2V5czxUPj5cbn1cblxuY29uc3QgcmVnaXN0cnk6IFJlZ2lzdHJ5ID0ge307XG5cbi8qKlxuICogUmVnaXN0ZXIgdGhlIGdpdmVuIGNsYXNzIGFzIHNlcmlhbGl6YWJsZS5cbiAqXG4gKiBAcGFyYW0gb3B0aW9uc1xuICogQHBhcmFtIG9wdGlvbnMub21pdCBMaXN0IG9mIHByb3BlcnRpZXMgdG8gb21pdCBmcm9tIHNlcmlhbGl6YXRpb24gKGUuZy4sIGNhY2hlZC9jb21wdXRlZCBwcm9wZXJ0aWVzKVxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RlcjxUOiBhbnk+KGtsYXNzOiBDbGFzczxUPiwgbmFtZTogc3RyaW5nLCBvcHRpb25zOiBSZWdpc3Rlck9wdGlvbnM8VD4gPSB7fSkge1xuICAgIGFzc2VydChuYW1lLCAnQ2FuXFwndCByZWdpc3RlciBhIGNsYXNzIHdpdGhvdXQgYSBuYW1lLicpO1xuICAgIGFzc2VydCghcmVnaXN0cnlbbmFtZV0sIGAke25hbWV9IGlzIGFscmVhZHkgcmVnaXN0ZXJlZC5gKTtcbiAgICAoT2JqZWN0LmRlZmluZVByb3BlcnR5OiBhbnkpKGtsYXNzLCAnX2NsYXNzUmVnaXN0cnlLZXknLCB7XG4gICAgICAgIHZhbHVlOiBuYW1lLFxuICAgICAgICB3cml0ZWFibGU6IGZhbHNlXG4gICAgfSk7XG4gICAgcmVnaXN0cnlbbmFtZV0gPSB7XG4gICAgICAgIGtsYXNzLFxuICAgICAgICBvbWl0OiBvcHRpb25zLm9taXQgfHwgW11cbiAgICB9O1xufVxuXG5yZWdpc3RlcihPYmplY3QsICdPYmplY3QnKTtcblxudHlwZSBTZXJpYWxpemVkR3JpZCA9IHsgYnVmZmVyOiBBcnJheUJ1ZmZlciB9O1xuXG4oR3JpZDogYW55KS5zZXJpYWxpemUgPSBmdW5jdGlvbiBzZXJpYWxpemUoZ3JpZDogR3JpZCwgdHJhbnNmZXJhYmxlcz86IEFycmF5PFRyYW5zZmVyYWJsZT4pOiBTZXJpYWxpemVkR3JpZCB7XG4gICAgY29uc3QgYnVmZmVyID0gZ3JpZC50b0FycmF5QnVmZmVyKCk7XG4gICAgaWYgKHRyYW5zZmVyYWJsZXMpIHtcbiAgICAgICAgdHJhbnNmZXJhYmxlcy5wdXNoKGJ1ZmZlcik7XG4gICAgfVxuICAgIHJldHVybiB7YnVmZmVyfTtcbn07XG5cbihHcmlkOiBhbnkpLmRlc2VyaWFsaXplID0gZnVuY3Rpb24gZGVzZXJpYWxpemUoc2VyaWFsaXplZDogU2VyaWFsaXplZEdyaWQpOiBHcmlkIHtcbiAgICByZXR1cm4gbmV3IEdyaWQoc2VyaWFsaXplZC5idWZmZXIpO1xufTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEdyaWQsICduYW1lJywge3ZhbHVlOiAnR3JpZCd9KTtcblxucmVnaXN0ZXIoR3JpZCwgJ0dyaWQnKTtcblxucmVnaXN0ZXIoQ29sb3IsICdDb2xvcicpO1xucmVnaXN0ZXIoRXJyb3IsICdFcnJvcicpO1xucmVnaXN0ZXIoQUpBWEVycm9yLCAnQUpBWEVycm9yJyk7XG5yZWdpc3RlcihSZXNvbHZlZEltYWdlLCAnUmVzb2x2ZWRJbWFnZScpO1xucmVnaXN0ZXIoU3R5bGVQcm9wZXJ0eUZ1bmN0aW9uLCAnU3R5bGVQcm9wZXJ0eUZ1bmN0aW9uJyk7XG5yZWdpc3RlcihTdHlsZUV4cHJlc3Npb24sICdTdHlsZUV4cHJlc3Npb24nLCB7b21pdDogWydfZXZhbHVhdG9yJ119KTtcblxucmVnaXN0ZXIoWm9vbURlcGVuZGVudEV4cHJlc3Npb24sICdab29tRGVwZW5kZW50RXhwcmVzc2lvbicpO1xucmVnaXN0ZXIoWm9vbUNvbnN0YW50RXhwcmVzc2lvbiwgJ1pvb21Db25zdGFudEV4cHJlc3Npb24nKTtcbnJlZ2lzdGVyKENvbXBvdW5kRXhwcmVzc2lvbiwgJ0NvbXBvdW5kRXhwcmVzc2lvbicsIHtvbWl0OiBbJ19ldmFsdWF0ZSddfSk7XG5mb3IgKGNvbnN0IG5hbWUgaW4gZXhwcmVzc2lvbnMpIHtcbiAgICBpZiAoIXJlZ2lzdHJ5WyhleHByZXNzaW9uc1tuYW1lXTogYW55KS5fY2xhc3NSZWdpc3RyeUtleV0pIHJlZ2lzdGVyKGV4cHJlc3Npb25zW25hbWVdLCBgRXhwcmVzc2lvbiR7bmFtZX1gKTtcbn1cblxuZnVuY3Rpb24gaXNBcnJheUJ1ZmZlcih2YWw6IGFueSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB2YWwgJiYgdHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgICAgICAodmFsIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIgfHwgKHZhbC5jb25zdHJ1Y3RvciAmJiB2YWwuY29uc3RydWN0b3IubmFtZSA9PT0gJ0FycmF5QnVmZmVyJykpO1xufVxuXG5mdW5jdGlvbiBpc0ltYWdlQml0bWFwKHZhbDogYW55KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHdpbmRvdy5JbWFnZUJpdG1hcCAmJlxuICAgICAgICB2YWwgaW5zdGFuY2VvZiB3aW5kb3cuSW1hZ2VCaXRtYXA7XG59XG5cbi8qKlxuICogU2VyaWFsaXplIHRoZSBnaXZlbiBvYmplY3QgZm9yIHRyYW5zZmVyIHRvIG9yIGZyb20gYSB3ZWIgd29ya2VyLlxuICpcbiAqIEZvciBub24tYnVpbHRpbiB0eXBlcywgcmVjdXJzaXZlbHkgc2VyaWFsaXplIGVhY2ggcHJvcGVydHkgKHBvc3NpYmx5XG4gKiBvbWl0dGluZyBjZXJ0YWluIHByb3BlcnRpZXMgLSBzZWUgcmVnaXN0ZXIoKSksIGFuZCBwYWNrYWdlIHRoZSByZXN1bHQgYWxvbmdcbiAqIHdpdGggdGhlIGNvbnN0cnVjdG9yJ3MgYG5hbWVgIHNvIHRoYXQgdGhlIGFwcHJvcHJpYXRlIGNvbnN0cnVjdG9yIGNhbiBiZVxuICogbG9va2VkIHVwIGluIGBkZXNlcmlhbGl6ZSgpYC5cbiAqXG4gKiBJZiBhIGB0cmFuc2ZlcmFibGVzYCBhcnJheSBpcyBwcm92aWRlZCwgYWRkIGFueSB0cmFuc2ZlcmFibGUgb2JqZWN0cyAoaS5lLixcbiAqIGFueSBBcnJheUJ1ZmZlcnMgb3IgQXJyYXlCdWZmZXIgdmlld3MpIHRvIHRoZSBsaXN0LiAoSWYgYSBjb3B5IGlzIG5lZWRlZCxcbiAqIHRoaXMgc2hvdWxkIGhhcHBlbiBpbiB0aGUgY2xpZW50IGNvZGUsIGJlZm9yZSB1c2luZyBzZXJpYWxpemUoKS4pXG4gKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNlcmlhbGl6ZShpbnB1dDogbWl4ZWQsIHRyYW5zZmVyYWJsZXM6ID9BcnJheTxUcmFuc2ZlcmFibGU+KTogU2VyaWFsaXplZCB7XG4gICAgaWYgKGlucHV0ID09PSBudWxsIHx8XG4gICAgICAgIGlucHV0ID09PSB1bmRlZmluZWQgfHxcbiAgICAgICAgdHlwZW9mIGlucHV0ID09PSAnYm9vbGVhbicgfHxcbiAgICAgICAgdHlwZW9mIGlucHV0ID09PSAnbnVtYmVyJyB8fFxuICAgICAgICB0eXBlb2YgaW5wdXQgPT09ICdzdHJpbmcnIHx8XG4gICAgICAgIGlucHV0IGluc3RhbmNlb2YgQm9vbGVhbiB8fFxuICAgICAgICBpbnB1dCBpbnN0YW5jZW9mIE51bWJlciB8fFxuICAgICAgICBpbnB1dCBpbnN0YW5jZW9mIFN0cmluZyB8fFxuICAgICAgICBpbnB1dCBpbnN0YW5jZW9mIERhdGUgfHxcbiAgICAgICAgaW5wdXQgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgcmV0dXJuIGlucHV0O1xuICAgIH1cblxuICAgIGlmIChpc0FycmF5QnVmZmVyKGlucHV0KSB8fCBpc0ltYWdlQml0bWFwKGlucHV0KSkge1xuICAgICAgICBpZiAodHJhbnNmZXJhYmxlcykge1xuICAgICAgICAgICAgdHJhbnNmZXJhYmxlcy5wdXNoKCgoaW5wdXQ6IGFueSk6IEFycmF5QnVmZmVyKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIChpbnB1dDogYW55KTtcbiAgICB9XG5cbiAgICBpZiAoQXJyYXlCdWZmZXIuaXNWaWV3KGlucHV0KSkge1xuICAgICAgICBjb25zdCB2aWV3OiAkQXJyYXlCdWZmZXJWaWV3ID0gKGlucHV0OiBhbnkpO1xuICAgICAgICBpZiAodHJhbnNmZXJhYmxlcykge1xuICAgICAgICAgICAgdHJhbnNmZXJhYmxlcy5wdXNoKHZpZXcuYnVmZmVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmlldztcbiAgICB9XG5cbiAgICBpZiAoaW5wdXQgaW5zdGFuY2VvZiB3aW5kb3cuSW1hZ2VEYXRhKSB7XG4gICAgICAgIGlmICh0cmFuc2ZlcmFibGVzKSB7XG4gICAgICAgICAgICB0cmFuc2ZlcmFibGVzLnB1c2goaW5wdXQuZGF0YS5idWZmZXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbnB1dDtcbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShpbnB1dCkpIHtcbiAgICAgICAgY29uc3Qgc2VyaWFsaXplZDogQXJyYXk8U2VyaWFsaXplZD4gPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGlucHV0KSB7XG4gICAgICAgICAgICBzZXJpYWxpemVkLnB1c2goc2VyaWFsaXplKGl0ZW0sIHRyYW5zZmVyYWJsZXMpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2VyaWFsaXplZDtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGlucHV0ID09PSAnb2JqZWN0Jykge1xuICAgICAgICBjb25zdCBrbGFzcyA9IChpbnB1dC5jb25zdHJ1Y3RvcjogYW55KTtcbiAgICAgICAgY29uc3QgbmFtZSA9IGtsYXNzLl9jbGFzc1JlZ2lzdHJ5S2V5O1xuICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgY2FuJ3Qgc2VyaWFsaXplIG9iamVjdCBvZiB1bnJlZ2lzdGVyZWQgY2xhc3MgJHtuYW1lfWApO1xuICAgICAgICB9XG4gICAgICAgIGFzc2VydChyZWdpc3RyeVtuYW1lXSk7XG5cbiAgICAgICAgY29uc3QgcHJvcGVydGllczogU2VyaWFsaXplZE9iamVjdCA9IGtsYXNzLnNlcmlhbGl6ZSA/XG4gICAgICAgICAgICAvLyAoVGVtcG9yYXJ5IHdvcmthcm91bmQpIGFsbG93IGEgY2xhc3MgdG8gcHJvdmlkZSBzdGF0aWNcbiAgICAgICAgICAgIC8vIGBzZXJpYWxpemUoKWAgYW5kIGBkZXNlcmlhbGl6ZSgpYCBtZXRob2RzIHRvIGJ5cGFzcyB0aGUgZ2VuZXJpY1xuICAgICAgICAgICAgLy8gYXBwcm9hY2guXG4gICAgICAgICAgICAvLyBUaGlzIHRlbXBvcmFyeSB3b3JrYXJvdW5kIGxldHMgdXMgdXNlIHRoZSBnZW5lcmljIHNlcmlhbGl6YXRpb25cbiAgICAgICAgICAgIC8vIGFwcHJvYWNoIGZvciBvYmplY3RzIHdob3NlIG1lbWJlcnMgaW5jbHVkZSBpbnN0YW5jZXMgb2YgZHluYW1pY1xuICAgICAgICAgICAgLy8gU3RydWN0QXJyYXkgdHlwZXMuIE9uY2Ugd2UgcmVmYWN0b3IgU3RydWN0QXJyYXkgdG8gYmUgc3RhdGljLFxuICAgICAgICAgICAgLy8gd2UgY2FuIHJlbW92ZSB0aGlzIGNvbXBsZXhpdHkuXG4gICAgICAgICAgICAoa2xhc3Muc2VyaWFsaXplKGlucHV0LCB0cmFuc2ZlcmFibGVzKTogU2VyaWFsaXplZE9iamVjdCkgOiB7fTtcblxuICAgICAgICBpZiAoIWtsYXNzLnNlcmlhbGl6ZSkge1xuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gaW5wdXQpIHtcbiAgICAgICAgICAgICAgICAvLyBhbnkgY2FzdCBkdWUgdG8gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL2Zsb3cvaXNzdWVzLzUzOTNcbiAgICAgICAgICAgICAgICBpZiAoIShpbnB1dDogYW55KS5oYXNPd25Qcm9wZXJ0eShrZXkpKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICBpZiAocmVnaXN0cnlbbmFtZV0ub21pdC5pbmRleE9mKGtleSkgPj0gMCkgY29udGludWU7XG4gICAgICAgICAgICAgICAgY29uc3QgcHJvcGVydHkgPSAoaW5wdXQ6IGFueSlba2V5XTtcbiAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzW2tleV0gPSBzZXJpYWxpemUocHJvcGVydHksIHRyYW5zZmVyYWJsZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlucHV0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzWydtZXNzYWdlJ10gPSBpbnB1dC5tZXNzYWdlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gbWFrZSBzdXJlIHN0YXRpY2FsbHkgc2VyaWFsaXplZCBvYmplY3Qgc3Vydml2ZXMgdHJhbnNmZXIgb2YgJG5hbWUgcHJvcGVydHlcbiAgICAgICAgICAgIGFzc2VydCghdHJhbnNmZXJhYmxlcyB8fCBwcm9wZXJ0aWVzICE9PSB0cmFuc2ZlcmFibGVzW3RyYW5zZmVyYWJsZXMubGVuZ3RoIC0gMV0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHByb3BlcnRpZXNbJyRuYW1lJ10pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignJG5hbWUgcHJvcGVydHkgaXMgcmVzZXJ2ZWQgZm9yIHdvcmtlciBzZXJpYWxpemF0aW9uIGxvZ2ljLicpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChuYW1lICE9PSAnT2JqZWN0Jykge1xuICAgICAgICAgICAgcHJvcGVydGllc1snJG5hbWUnXSA9IG5hbWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcHJvcGVydGllcztcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoYGNhbid0IHNlcmlhbGl6ZSBvYmplY3Qgb2YgdHlwZSAke3R5cGVvZiBpbnB1dH1gKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlc2VyaWFsaXplKGlucHV0OiBTZXJpYWxpemVkKTogbWl4ZWQge1xuICAgIGlmIChpbnB1dCA9PT0gbnVsbCB8fFxuICAgICAgICBpbnB1dCA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgIHR5cGVvZiBpbnB1dCA9PT0gJ2Jvb2xlYW4nIHx8XG4gICAgICAgIHR5cGVvZiBpbnB1dCA9PT0gJ251bWJlcicgfHxcbiAgICAgICAgdHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJyB8fFxuICAgICAgICBpbnB1dCBpbnN0YW5jZW9mIEJvb2xlYW4gfHxcbiAgICAgICAgaW5wdXQgaW5zdGFuY2VvZiBOdW1iZXIgfHxcbiAgICAgICAgaW5wdXQgaW5zdGFuY2VvZiBTdHJpbmcgfHxcbiAgICAgICAgaW5wdXQgaW5zdGFuY2VvZiBEYXRlIHx8XG4gICAgICAgIGlucHV0IGluc3RhbmNlb2YgUmVnRXhwIHx8XG4gICAgICAgIGlzQXJyYXlCdWZmZXIoaW5wdXQpIHx8XG4gICAgICAgIGlzSW1hZ2VCaXRtYXAoaW5wdXQpIHx8XG4gICAgICAgIEFycmF5QnVmZmVyLmlzVmlldyhpbnB1dCkgfHxcbiAgICAgICAgaW5wdXQgaW5zdGFuY2VvZiB3aW5kb3cuSW1hZ2VEYXRhKSB7XG4gICAgICAgIHJldHVybiBpbnB1dDtcbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShpbnB1dCkpIHtcbiAgICAgICAgcmV0dXJuIGlucHV0Lm1hcChkZXNlcmlhbGl6ZSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBpbnB1dCA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgY29uc3QgbmFtZSA9IChpbnB1dDogYW55KS4kbmFtZSB8fCAnT2JqZWN0JztcblxuICAgICAgICBjb25zdCB7a2xhc3N9ID0gcmVnaXN0cnlbbmFtZV07XG4gICAgICAgIGlmICgha2xhc3MpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgY2FuJ3QgZGVzZXJpYWxpemUgdW5yZWdpc3RlcmVkIGNsYXNzICR7bmFtZX1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChrbGFzcy5kZXNlcmlhbGl6ZSkge1xuICAgICAgICAgICAgcmV0dXJuIChrbGFzcy5kZXNlcmlhbGl6ZTogdHlwZW9mIGRlc2VyaWFsaXplKShpbnB1dCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXN1bHQ6IHtbXzogc3RyaW5nXTogYW55fSA9IE9iamVjdC5jcmVhdGUoa2xhc3MucHJvdG90eXBlKTtcblxuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhpbnB1dCkpIHtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbaW5jb21wYXRpYmxlLXR5cGVdXG4gICAgICAgICAgICBpZiAoa2V5ID09PSAnJG5hbWUnKSBjb250aW51ZTtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gKGlucHV0OiBTZXJpYWxpemVkT2JqZWN0KVtrZXldO1xuICAgICAgICAgICAgcmVzdWx0W2tleV0gPSBkZXNlcmlhbGl6ZSh2YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcihgY2FuJ3QgZGVzZXJpYWxpemUgb2JqZWN0IG9mIHR5cGUgJHt0eXBlb2YgaW5wdXR9YCk7XG59XG4iLCIvLyBAZmxvd1xuXG4vLyBUaGUgZm9sbG93aW5nIHRhYmxlIGNvbWVzIGZyb20gPGh0dHA6Ly93d3cudW5pY29kZS5vcmcvUHVibGljLzEyLjAuMC91Y2QvQmxvY2tzLnR4dD4uXG4vLyBLZWVwIGl0IHN5bmNocm9uaXplZCB3aXRoIDxodHRwOi8vd3d3LnVuaWNvZGUub3JnL1B1YmxpYy9VQ0QvbGF0ZXN0L3VjZC9CbG9ja3MudHh0Pi5cblxudHlwZSBVbmljb2RlQmxvY2tMb29rdXAgPSB7W2tleTogc3RyaW5nXTogKGNoYXI6IG51bWJlcikgPT4gYm9vbGVhbn07XG5cbmNvbnN0IHVuaWNvZGVCbG9ja0xvb2t1cDogVW5pY29kZUJsb2NrTG9va3VwID0ge1xuICAgIC8vICdCYXNpYyBMYXRpbic6IChjaGFyKSA9PiBjaGFyID49IDB4MDAwMCAmJiBjaGFyIDw9IDB4MDA3RixcbiAgICAnTGF0aW4tMSBTdXBwbGVtZW50JzogKGNoYXIpID0+IGNoYXIgPj0gMHgwMDgwICYmIGNoYXIgPD0gMHgwMEZGLFxuICAgIC8vICdMYXRpbiBFeHRlbmRlZC1BJzogKGNoYXIpID0+IGNoYXIgPj0gMHgwMTAwICYmIGNoYXIgPD0gMHgwMTdGLFxuICAgIC8vICdMYXRpbiBFeHRlbmRlZC1CJzogKGNoYXIpID0+IGNoYXIgPj0gMHgwMTgwICYmIGNoYXIgPD0gMHgwMjRGLFxuICAgIC8vICdJUEEgRXh0ZW5zaW9ucyc6IChjaGFyKSA9PiBjaGFyID49IDB4MDI1MCAmJiBjaGFyIDw9IDB4MDJBRixcbiAgICAvLyAnU3BhY2luZyBNb2RpZmllciBMZXR0ZXJzJzogKGNoYXIpID0+IGNoYXIgPj0gMHgwMkIwICYmIGNoYXIgPD0gMHgwMkZGLFxuICAgIC8vICdDb21iaW5pbmcgRGlhY3JpdGljYWwgTWFya3MnOiAoY2hhcikgPT4gY2hhciA+PSAweDAzMDAgJiYgY2hhciA8PSAweDAzNkYsXG4gICAgLy8gJ0dyZWVrIGFuZCBDb3B0aWMnOiAoY2hhcikgPT4gY2hhciA+PSAweDAzNzAgJiYgY2hhciA8PSAweDAzRkYsXG4gICAgLy8gJ0N5cmlsbGljJzogKGNoYXIpID0+IGNoYXIgPj0gMHgwNDAwICYmIGNoYXIgPD0gMHgwNEZGLFxuICAgIC8vICdDeXJpbGxpYyBTdXBwbGVtZW50JzogKGNoYXIpID0+IGNoYXIgPj0gMHgwNTAwICYmIGNoYXIgPD0gMHgwNTJGLFxuICAgIC8vICdBcm1lbmlhbic6IChjaGFyKSA9PiBjaGFyID49IDB4MDUzMCAmJiBjaGFyIDw9IDB4MDU4RixcbiAgICAvLydIZWJyZXcnOiAoY2hhcikgPT4gY2hhciA+PSAweDA1OTAgJiYgY2hhciA8PSAweDA1RkYsXG4gICAgJ0FyYWJpYyc6IChjaGFyKSA9PiBjaGFyID49IDB4MDYwMCAmJiBjaGFyIDw9IDB4MDZGRixcbiAgICAvLydTeXJpYWMnOiAoY2hhcikgPT4gY2hhciA+PSAweDA3MDAgJiYgY2hhciA8PSAweDA3NEYsXG4gICAgJ0FyYWJpYyBTdXBwbGVtZW50JzogKGNoYXIpID0+IGNoYXIgPj0gMHgwNzUwICYmIGNoYXIgPD0gMHgwNzdGLFxuICAgIC8vICdUaGFhbmEnOiAoY2hhcikgPT4gY2hhciA+PSAweDA3ODAgJiYgY2hhciA8PSAweDA3QkYsXG4gICAgLy8gJ05Lbyc6IChjaGFyKSA9PiBjaGFyID49IDB4MDdDMCAmJiBjaGFyIDw9IDB4MDdGRixcbiAgICAvLyAnU2FtYXJpdGFuJzogKGNoYXIpID0+IGNoYXIgPj0gMHgwODAwICYmIGNoYXIgPD0gMHgwODNGLFxuICAgIC8vICdNYW5kYWljJzogKGNoYXIpID0+IGNoYXIgPj0gMHgwODQwICYmIGNoYXIgPD0gMHgwODVGLFxuICAgIC8vICdTeXJpYWMgU3VwcGxlbWVudCc6IChjaGFyKSA9PiBjaGFyID49IDB4MDg2MCAmJiBjaGFyIDw9IDB4MDg2RixcbiAgICAnQXJhYmljIEV4dGVuZGVkLUEnOiAoY2hhcikgPT4gY2hhciA+PSAweDA4QTAgJiYgY2hhciA8PSAweDA4RkYsXG4gICAgLy8gJ0RldmFuYWdhcmknOiAoY2hhcikgPT4gY2hhciA+PSAweDA5MDAgJiYgY2hhciA8PSAweDA5N0YsXG4gICAgLy8gJ0JlbmdhbGknOiAoY2hhcikgPT4gY2hhciA+PSAweDA5ODAgJiYgY2hhciA8PSAweDA5RkYsXG4gICAgLy8gJ0d1cm11a2hpJzogKGNoYXIpID0+IGNoYXIgPj0gMHgwQTAwICYmIGNoYXIgPD0gMHgwQTdGLFxuICAgIC8vICdHdWphcmF0aSc6IChjaGFyKSA9PiBjaGFyID49IDB4MEE4MCAmJiBjaGFyIDw9IDB4MEFGRixcbiAgICAvLyAnT3JpeWEnOiAoY2hhcikgPT4gY2hhciA+PSAweDBCMDAgJiYgY2hhciA8PSAweDBCN0YsXG4gICAgLy8gJ1RhbWlsJzogKGNoYXIpID0+IGNoYXIgPj0gMHgwQjgwICYmIGNoYXIgPD0gMHgwQkZGLFxuICAgIC8vICdUZWx1Z3UnOiAoY2hhcikgPT4gY2hhciA+PSAweDBDMDAgJiYgY2hhciA8PSAweDBDN0YsXG4gICAgLy8gJ0thbm5hZGEnOiAoY2hhcikgPT4gY2hhciA+PSAweDBDODAgJiYgY2hhciA8PSAweDBDRkYsXG4gICAgLy8gJ01hbGF5YWxhbSc6IChjaGFyKSA9PiBjaGFyID49IDB4MEQwMCAmJiBjaGFyIDw9IDB4MEQ3RixcbiAgICAvLyAnU2luaGFsYSc6IChjaGFyKSA9PiBjaGFyID49IDB4MEQ4MCAmJiBjaGFyIDw9IDB4MERGRixcbiAgICAvLyAnVGhhaSc6IChjaGFyKSA9PiBjaGFyID49IDB4MEUwMCAmJiBjaGFyIDw9IDB4MEU3RixcbiAgICAvLyAnTGFvJzogKGNoYXIpID0+IGNoYXIgPj0gMHgwRTgwICYmIGNoYXIgPD0gMHgwRUZGLFxuICAgIC8vICdUaWJldGFuJzogKGNoYXIpID0+IGNoYXIgPj0gMHgwRjAwICYmIGNoYXIgPD0gMHgwRkZGLFxuICAgIC8vICdNeWFubWFyJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxMDAwICYmIGNoYXIgPD0gMHgxMDlGLFxuICAgIC8vICdHZW9yZ2lhbic6IChjaGFyKSA9PiBjaGFyID49IDB4MTBBMCAmJiBjaGFyIDw9IDB4MTBGRixcbiAgICAnSGFuZ3VsIEphbW8nOiAoY2hhcikgPT4gY2hhciA+PSAweDExMDAgJiYgY2hhciA8PSAweDExRkYsXG4gICAgLy8gJ0V0aGlvcGljJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxMjAwICYmIGNoYXIgPD0gMHgxMzdGLFxuICAgIC8vICdFdGhpb3BpYyBTdXBwbGVtZW50JzogKGNoYXIpID0+IGNoYXIgPj0gMHgxMzgwICYmIGNoYXIgPD0gMHgxMzlGLFxuICAgIC8vICdDaGVyb2tlZSc6IChjaGFyKSA9PiBjaGFyID49IDB4MTNBMCAmJiBjaGFyIDw9IDB4MTNGRixcbiAgICAnVW5pZmllZCBDYW5hZGlhbiBBYm9yaWdpbmFsIFN5bGxhYmljcyc6IChjaGFyKSA9PiBjaGFyID49IDB4MTQwMCAmJiBjaGFyIDw9IDB4MTY3RixcbiAgICAvLyAnT2doYW0nOiAoY2hhcikgPT4gY2hhciA+PSAweDE2ODAgJiYgY2hhciA8PSAweDE2OUYsXG4gICAgLy8gJ1J1bmljJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxNkEwICYmIGNoYXIgPD0gMHgxNkZGLFxuICAgIC8vICdUYWdhbG9nJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxNzAwICYmIGNoYXIgPD0gMHgxNzFGLFxuICAgIC8vICdIYW51bm9vJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxNzIwICYmIGNoYXIgPD0gMHgxNzNGLFxuICAgIC8vICdCdWhpZCc6IChjaGFyKSA9PiBjaGFyID49IDB4MTc0MCAmJiBjaGFyIDw9IDB4MTc1RixcbiAgICAvLyAnVGFnYmFud2EnOiAoY2hhcikgPT4gY2hhciA+PSAweDE3NjAgJiYgY2hhciA8PSAweDE3N0YsXG4gICAgJ0tobWVyJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxNzgwICYmIGNoYXIgPD0gMHgxN0ZGLFxuICAgIC8vICdNb25nb2xpYW4nOiAoY2hhcikgPT4gY2hhciA+PSAweDE4MDAgJiYgY2hhciA8PSAweDE4QUYsXG4gICAgJ1VuaWZpZWQgQ2FuYWRpYW4gQWJvcmlnaW5hbCBTeWxsYWJpY3MgRXh0ZW5kZWQnOiAoY2hhcikgPT4gY2hhciA+PSAweDE4QjAgJiYgY2hhciA8PSAweDE4RkYsXG4gICAgLy8gJ0xpbWJ1JzogKGNoYXIpID0+IGNoYXIgPj0gMHgxOTAwICYmIGNoYXIgPD0gMHgxOTRGLFxuICAgIC8vICdUYWkgTGUnOiAoY2hhcikgPT4gY2hhciA+PSAweDE5NTAgJiYgY2hhciA8PSAweDE5N0YsXG4gICAgLy8gJ05ldyBUYWkgTHVlJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxOTgwICYmIGNoYXIgPD0gMHgxOURGLFxuICAgIC8vICdLaG1lciBTeW1ib2xzJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxOUUwICYmIGNoYXIgPD0gMHgxOUZGLFxuICAgIC8vICdCdWdpbmVzZSc6IChjaGFyKSA9PiBjaGFyID49IDB4MUEwMCAmJiBjaGFyIDw9IDB4MUExRixcbiAgICAvLyAnVGFpIFRoYW0nOiAoY2hhcikgPT4gY2hhciA+PSAweDFBMjAgJiYgY2hhciA8PSAweDFBQUYsXG4gICAgLy8gJ0NvbWJpbmluZyBEaWFjcml0aWNhbCBNYXJrcyBFeHRlbmRlZCc6IChjaGFyKSA9PiBjaGFyID49IDB4MUFCMCAmJiBjaGFyIDw9IDB4MUFGRixcbiAgICAvLyAnQmFsaW5lc2UnOiAoY2hhcikgPT4gY2hhciA+PSAweDFCMDAgJiYgY2hhciA8PSAweDFCN0YsXG4gICAgLy8gJ1N1bmRhbmVzZSc6IChjaGFyKSA9PiBjaGFyID49IDB4MUI4MCAmJiBjaGFyIDw9IDB4MUJCRixcbiAgICAvLyAnQmF0YWsnOiAoY2hhcikgPT4gY2hhciA+PSAweDFCQzAgJiYgY2hhciA8PSAweDFCRkYsXG4gICAgLy8gJ0xlcGNoYSc6IChjaGFyKSA9PiBjaGFyID49IDB4MUMwMCAmJiBjaGFyIDw9IDB4MUM0RixcbiAgICAvLyAnT2wgQ2hpa2knOiAoY2hhcikgPT4gY2hhciA+PSAweDFDNTAgJiYgY2hhciA8PSAweDFDN0YsXG4gICAgLy8gJ0N5cmlsbGljIEV4dGVuZGVkLUMnOiAoY2hhcikgPT4gY2hhciA+PSAweDFDODAgJiYgY2hhciA8PSAweDFDOEYsXG4gICAgLy8gJ0dlb3JnaWFuIEV4dGVuZGVkJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxQzkwICYmIGNoYXIgPD0gMHgxQ0JGLFxuICAgIC8vICdTdW5kYW5lc2UgU3VwcGxlbWVudCc6IChjaGFyKSA9PiBjaGFyID49IDB4MUNDMCAmJiBjaGFyIDw9IDB4MUNDRixcbiAgICAvLyAnVmVkaWMgRXh0ZW5zaW9ucyc6IChjaGFyKSA9PiBjaGFyID49IDB4MUNEMCAmJiBjaGFyIDw9IDB4MUNGRixcbiAgICAvLyAnUGhvbmV0aWMgRXh0ZW5zaW9ucyc6IChjaGFyKSA9PiBjaGFyID49IDB4MUQwMCAmJiBjaGFyIDw9IDB4MUQ3RixcbiAgICAvLyAnUGhvbmV0aWMgRXh0ZW5zaW9ucyBTdXBwbGVtZW50JzogKGNoYXIpID0+IGNoYXIgPj0gMHgxRDgwICYmIGNoYXIgPD0gMHgxREJGLFxuICAgIC8vICdDb21iaW5pbmcgRGlhY3JpdGljYWwgTWFya3MgU3VwcGxlbWVudCc6IChjaGFyKSA9PiBjaGFyID49IDB4MURDMCAmJiBjaGFyIDw9IDB4MURGRixcbiAgICAvLyAnTGF0aW4gRXh0ZW5kZWQgQWRkaXRpb25hbCc6IChjaGFyKSA9PiBjaGFyID49IDB4MUUwMCAmJiBjaGFyIDw9IDB4MUVGRixcbiAgICAvLyAnR3JlZWsgRXh0ZW5kZWQnOiAoY2hhcikgPT4gY2hhciA+PSAweDFGMDAgJiYgY2hhciA8PSAweDFGRkYsXG4gICAgJ0dlbmVyYWwgUHVuY3R1YXRpb24nOiAoY2hhcikgPT4gY2hhciA+PSAweDIwMDAgJiYgY2hhciA8PSAweDIwNkYsXG4gICAgLy8gJ1N1cGVyc2NyaXB0cyBhbmQgU3Vic2NyaXB0cyc6IChjaGFyKSA9PiBjaGFyID49IDB4MjA3MCAmJiBjaGFyIDw9IDB4MjA5RixcbiAgICAvLyAnQ3VycmVuY3kgU3ltYm9scyc6IChjaGFyKSA9PiBjaGFyID49IDB4MjBBMCAmJiBjaGFyIDw9IDB4MjBDRixcbiAgICAvLyAnQ29tYmluaW5nIERpYWNyaXRpY2FsIE1hcmtzIGZvciBTeW1ib2xzJzogKGNoYXIpID0+IGNoYXIgPj0gMHgyMEQwICYmIGNoYXIgPD0gMHgyMEZGLFxuICAgICdMZXR0ZXJsaWtlIFN5bWJvbHMnOiAoY2hhcikgPT4gY2hhciA+PSAweDIxMDAgJiYgY2hhciA8PSAweDIxNEYsXG4gICAgJ051bWJlciBGb3Jtcyc6IChjaGFyKSA9PiBjaGFyID49IDB4MjE1MCAmJiBjaGFyIDw9IDB4MjE4RixcbiAgICAvLyAnQXJyb3dzJzogKGNoYXIpID0+IGNoYXIgPj0gMHgyMTkwICYmIGNoYXIgPD0gMHgyMUZGLFxuICAgIC8vICdNYXRoZW1hdGljYWwgT3BlcmF0b3JzJzogKGNoYXIpID0+IGNoYXIgPj0gMHgyMjAwICYmIGNoYXIgPD0gMHgyMkZGLFxuICAgICdNaXNjZWxsYW5lb3VzIFRlY2huaWNhbCc6IChjaGFyKSA9PiBjaGFyID49IDB4MjMwMCAmJiBjaGFyIDw9IDB4MjNGRixcbiAgICAnQ29udHJvbCBQaWN0dXJlcyc6IChjaGFyKSA9PiBjaGFyID49IDB4MjQwMCAmJiBjaGFyIDw9IDB4MjQzRixcbiAgICAnT3B0aWNhbCBDaGFyYWN0ZXIgUmVjb2duaXRpb24nOiAoY2hhcikgPT4gY2hhciA+PSAweDI0NDAgJiYgY2hhciA8PSAweDI0NUYsXG4gICAgJ0VuY2xvc2VkIEFscGhhbnVtZXJpY3MnOiAoY2hhcikgPT4gY2hhciA+PSAweDI0NjAgJiYgY2hhciA8PSAweDI0RkYsXG4gICAgLy8gJ0JveCBEcmF3aW5nJzogKGNoYXIpID0+IGNoYXIgPj0gMHgyNTAwICYmIGNoYXIgPD0gMHgyNTdGLFxuICAgIC8vICdCbG9jayBFbGVtZW50cyc6IChjaGFyKSA9PiBjaGFyID49IDB4MjU4MCAmJiBjaGFyIDw9IDB4MjU5RixcbiAgICAnR2VvbWV0cmljIFNoYXBlcyc6IChjaGFyKSA9PiBjaGFyID49IDB4MjVBMCAmJiBjaGFyIDw9IDB4MjVGRixcbiAgICAnTWlzY2VsbGFuZW91cyBTeW1ib2xzJzogKGNoYXIpID0+IGNoYXIgPj0gMHgyNjAwICYmIGNoYXIgPD0gMHgyNkZGLFxuICAgIC8vICdEaW5nYmF0cyc6IChjaGFyKSA9PiBjaGFyID49IDB4MjcwMCAmJiBjaGFyIDw9IDB4MjdCRixcbiAgICAvLyAnTWlzY2VsbGFuZW91cyBNYXRoZW1hdGljYWwgU3ltYm9scy1BJzogKGNoYXIpID0+IGNoYXIgPj0gMHgyN0MwICYmIGNoYXIgPD0gMHgyN0VGLFxuICAgIC8vICdTdXBwbGVtZW50YWwgQXJyb3dzLUEnOiAoY2hhcikgPT4gY2hhciA+PSAweDI3RjAgJiYgY2hhciA8PSAweDI3RkYsXG4gICAgLy8gJ0JyYWlsbGUgUGF0dGVybnMnOiAoY2hhcikgPT4gY2hhciA+PSAweDI4MDAgJiYgY2hhciA8PSAweDI4RkYsXG4gICAgLy8gJ1N1cHBsZW1lbnRhbCBBcnJvd3MtQic6IChjaGFyKSA9PiBjaGFyID49IDB4MjkwMCAmJiBjaGFyIDw9IDB4Mjk3RixcbiAgICAvLyAnTWlzY2VsbGFuZW91cyBNYXRoZW1hdGljYWwgU3ltYm9scy1CJzogKGNoYXIpID0+IGNoYXIgPj0gMHgyOTgwICYmIGNoYXIgPD0gMHgyOUZGLFxuICAgIC8vICdTdXBwbGVtZW50YWwgTWF0aGVtYXRpY2FsIE9wZXJhdG9ycyc6IChjaGFyKSA9PiBjaGFyID49IDB4MkEwMCAmJiBjaGFyIDw9IDB4MkFGRixcbiAgICAnTWlzY2VsbGFuZW91cyBTeW1ib2xzIGFuZCBBcnJvd3MnOiAoY2hhcikgPT4gY2hhciA+PSAweDJCMDAgJiYgY2hhciA8PSAweDJCRkYsXG4gICAgLy8gJ0dsYWdvbGl0aWMnOiAoY2hhcikgPT4gY2hhciA+PSAweDJDMDAgJiYgY2hhciA8PSAweDJDNUYsXG4gICAgLy8gJ0xhdGluIEV4dGVuZGVkLUMnOiAoY2hhcikgPT4gY2hhciA+PSAweDJDNjAgJiYgY2hhciA8PSAweDJDN0YsXG4gICAgLy8gJ0NvcHRpYyc6IChjaGFyKSA9PiBjaGFyID49IDB4MkM4MCAmJiBjaGFyIDw9IDB4MkNGRixcbiAgICAvLyAnR2VvcmdpYW4gU3VwcGxlbWVudCc6IChjaGFyKSA9PiBjaGFyID49IDB4MkQwMCAmJiBjaGFyIDw9IDB4MkQyRixcbiAgICAvLyAnVGlmaW5hZ2gnOiAoY2hhcikgPT4gY2hhciA+PSAweDJEMzAgJiYgY2hhciA8PSAweDJEN0YsXG4gICAgLy8gJ0V0aGlvcGljIEV4dGVuZGVkJzogKGNoYXIpID0+IGNoYXIgPj0gMHgyRDgwICYmIGNoYXIgPD0gMHgyRERGLFxuICAgIC8vICdDeXJpbGxpYyBFeHRlbmRlZC1BJzogKGNoYXIpID0+IGNoYXIgPj0gMHgyREUwICYmIGNoYXIgPD0gMHgyREZGLFxuICAgIC8vICdTdXBwbGVtZW50YWwgUHVuY3R1YXRpb24nOiAoY2hhcikgPT4gY2hhciA+PSAweDJFMDAgJiYgY2hhciA8PSAweDJFN0YsXG4gICAgJ0NKSyBSYWRpY2FscyBTdXBwbGVtZW50JzogKGNoYXIpID0+IGNoYXIgPj0gMHgyRTgwICYmIGNoYXIgPD0gMHgyRUZGLFxuICAgICdLYW5neGkgUmFkaWNhbHMnOiAoY2hhcikgPT4gY2hhciA+PSAweDJGMDAgJiYgY2hhciA8PSAweDJGREYsXG4gICAgJ0lkZW9ncmFwaGljIERlc2NyaXB0aW9uIENoYXJhY3RlcnMnOiAoY2hhcikgPT4gY2hhciA+PSAweDJGRjAgJiYgY2hhciA8PSAweDJGRkYsXG4gICAgJ0NKSyBTeW1ib2xzIGFuZCBQdW5jdHVhdGlvbic6IChjaGFyKSA9PiBjaGFyID49IDB4MzAwMCAmJiBjaGFyIDw9IDB4MzAzRixcbiAgICAnSGlyYWdhbmEnOiAoY2hhcikgPT4gY2hhciA+PSAweDMwNDAgJiYgY2hhciA8PSAweDMwOUYsXG4gICAgJ0thdGFrYW5hJzogKGNoYXIpID0+IGNoYXIgPj0gMHgzMEEwICYmIGNoYXIgPD0gMHgzMEZGLFxuICAgICdCb3BvbW9mbyc6IChjaGFyKSA9PiBjaGFyID49IDB4MzEwMCAmJiBjaGFyIDw9IDB4MzEyRixcbiAgICAnSGFuZ3VsIENvbXBhdGliaWxpdHkgSmFtbyc6IChjaGFyKSA9PiBjaGFyID49IDB4MzEzMCAmJiBjaGFyIDw9IDB4MzE4RixcbiAgICAnS2FuYnVuJzogKGNoYXIpID0+IGNoYXIgPj0gMHgzMTkwICYmIGNoYXIgPD0gMHgzMTlGLFxuICAgICdCb3BvbW9mbyBFeHRlbmRlZCc6IChjaGFyKSA9PiBjaGFyID49IDB4MzFBMCAmJiBjaGFyIDw9IDB4MzFCRixcbiAgICAnQ0pLIFN0cm9rZXMnOiAoY2hhcikgPT4gY2hhciA+PSAweDMxQzAgJiYgY2hhciA8PSAweDMxRUYsXG4gICAgJ0thdGFrYW5hIFBob25ldGljIEV4dGVuc2lvbnMnOiAoY2hhcikgPT4gY2hhciA+PSAweDMxRjAgJiYgY2hhciA8PSAweDMxRkYsXG4gICAgJ0VuY2xvc2VkIENKSyBMZXR0ZXJzIGFuZCBNb250aHMnOiAoY2hhcikgPT4gY2hhciA+PSAweDMyMDAgJiYgY2hhciA8PSAweDMyRkYsXG4gICAgJ0NKSyBDb21wYXRpYmlsaXR5JzogKGNoYXIpID0+IGNoYXIgPj0gMHgzMzAwICYmIGNoYXIgPD0gMHgzM0ZGLFxuICAgICdDSksgVW5pZmllZCBJZGVvZ3JhcGhzIEV4dGVuc2lvbiBBJzogKGNoYXIpID0+IGNoYXIgPj0gMHgzNDAwICYmIGNoYXIgPD0gMHg0REJGLFxuICAgICdZaWppbmcgSGV4YWdyYW0gU3ltYm9scyc6IChjaGFyKSA9PiBjaGFyID49IDB4NERDMCAmJiBjaGFyIDw9IDB4NERGRixcbiAgICAnQ0pLIFVuaWZpZWQgSWRlb2dyYXBocyc6IChjaGFyKSA9PiBjaGFyID49IDB4NEUwMCAmJiBjaGFyIDw9IDB4OUZGRixcbiAgICAnWWkgU3lsbGFibGVzJzogKGNoYXIpID0+IGNoYXIgPj0gMHhBMDAwICYmIGNoYXIgPD0gMHhBNDhGLFxuICAgICdZaSBSYWRpY2Fscyc6IChjaGFyKSA9PiBjaGFyID49IDB4QTQ5MCAmJiBjaGFyIDw9IDB4QTRDRixcbiAgICAvLyAnTGlzdSc6IChjaGFyKSA9PiBjaGFyID49IDB4QTREMCAmJiBjaGFyIDw9IDB4QTRGRixcbiAgICAvLyAnVmFpJzogKGNoYXIpID0+IGNoYXIgPj0gMHhBNTAwICYmIGNoYXIgPD0gMHhBNjNGLFxuICAgIC8vICdDeXJpbGxpYyBFeHRlbmRlZC1CJzogKGNoYXIpID0+IGNoYXIgPj0gMHhBNjQwICYmIGNoYXIgPD0gMHhBNjlGLFxuICAgIC8vICdCYW11bSc6IChjaGFyKSA9PiBjaGFyID49IDB4QTZBMCAmJiBjaGFyIDw9IDB4QTZGRixcbiAgICAvLyAnTW9kaWZpZXIgVG9uZSBMZXR0ZXJzJzogKGNoYXIpID0+IGNoYXIgPj0gMHhBNzAwICYmIGNoYXIgPD0gMHhBNzFGLFxuICAgIC8vICdMYXRpbiBFeHRlbmRlZC1EJzogKGNoYXIpID0+IGNoYXIgPj0gMHhBNzIwICYmIGNoYXIgPD0gMHhBN0ZGLFxuICAgIC8vICdTeWxvdGkgTmFncmknOiAoY2hhcikgPT4gY2hhciA+PSAweEE4MDAgJiYgY2hhciA8PSAweEE4MkYsXG4gICAgLy8gJ0NvbW1vbiBJbmRpYyBOdW1iZXIgRm9ybXMnOiAoY2hhcikgPT4gY2hhciA+PSAweEE4MzAgJiYgY2hhciA8PSAweEE4M0YsXG4gICAgLy8gJ1BoYWdzLXBhJzogKGNoYXIpID0+IGNoYXIgPj0gMHhBODQwICYmIGNoYXIgPD0gMHhBODdGLFxuICAgIC8vICdTYXVyYXNodHJhJzogKGNoYXIpID0+IGNoYXIgPj0gMHhBODgwICYmIGNoYXIgPD0gMHhBOERGLFxuICAgIC8vICdEZXZhbmFnYXJpIEV4dGVuZGVkJzogKGNoYXIpID0+IGNoYXIgPj0gMHhBOEUwICYmIGNoYXIgPD0gMHhBOEZGLFxuICAgIC8vICdLYXlhaCBMaSc6IChjaGFyKSA9PiBjaGFyID49IDB4QTkwMCAmJiBjaGFyIDw9IDB4QTkyRixcbiAgICAvLyAnUmVqYW5nJzogKGNoYXIpID0+IGNoYXIgPj0gMHhBOTMwICYmIGNoYXIgPD0gMHhBOTVGLFxuICAgICdIYW5ndWwgSmFtbyBFeHRlbmRlZC1BJzogKGNoYXIpID0+IGNoYXIgPj0gMHhBOTYwICYmIGNoYXIgPD0gMHhBOTdGLFxuICAgIC8vICdKYXZhbmVzZSc6IChjaGFyKSA9PiBjaGFyID49IDB4QTk4MCAmJiBjaGFyIDw9IDB4QTlERixcbiAgICAvLyAnTXlhbm1hciBFeHRlbmRlZC1CJzogKGNoYXIpID0+IGNoYXIgPj0gMHhBOUUwICYmIGNoYXIgPD0gMHhBOUZGLFxuICAgIC8vICdDaGFtJzogKGNoYXIpID0+IGNoYXIgPj0gMHhBQTAwICYmIGNoYXIgPD0gMHhBQTVGLFxuICAgIC8vICdNeWFubWFyIEV4dGVuZGVkLUEnOiAoY2hhcikgPT4gY2hhciA+PSAweEFBNjAgJiYgY2hhciA8PSAweEFBN0YsXG4gICAgLy8gJ1RhaSBWaWV0JzogKGNoYXIpID0+IGNoYXIgPj0gMHhBQTgwICYmIGNoYXIgPD0gMHhBQURGLFxuICAgIC8vICdNZWV0ZWkgTWF5ZWsgRXh0ZW5zaW9ucyc6IChjaGFyKSA9PiBjaGFyID49IDB4QUFFMCAmJiBjaGFyIDw9IDB4QUFGRixcbiAgICAvLyAnRXRoaW9waWMgRXh0ZW5kZWQtQSc6IChjaGFyKSA9PiBjaGFyID49IDB4QUIwMCAmJiBjaGFyIDw9IDB4QUIyRixcbiAgICAvLyAnTGF0aW4gRXh0ZW5kZWQtRSc6IChjaGFyKSA9PiBjaGFyID49IDB4QUIzMCAmJiBjaGFyIDw9IDB4QUI2RixcbiAgICAvLyAnQ2hlcm9rZWUgU3VwcGxlbWVudCc6IChjaGFyKSA9PiBjaGFyID49IDB4QUI3MCAmJiBjaGFyIDw9IDB4QUJCRixcbiAgICAvLyAnTWVldGVpIE1heWVrJzogKGNoYXIpID0+IGNoYXIgPj0gMHhBQkMwICYmIGNoYXIgPD0gMHhBQkZGLFxuICAgICdIYW5ndWwgU3lsbGFibGVzJzogKGNoYXIpID0+IGNoYXIgPj0gMHhBQzAwICYmIGNoYXIgPD0gMHhEN0FGLFxuICAgICdIYW5ndWwgSmFtbyBFeHRlbmRlZC1CJzogKGNoYXIpID0+IGNoYXIgPj0gMHhEN0IwICYmIGNoYXIgPD0gMHhEN0ZGLFxuICAgIC8vICdIaWdoIFN1cnJvZ2F0ZXMnOiAoY2hhcikgPT4gY2hhciA+PSAweEQ4MDAgJiYgY2hhciA8PSAweERCN0YsXG4gICAgLy8gJ0hpZ2ggUHJpdmF0ZSBVc2UgU3Vycm9nYXRlcyc6IChjaGFyKSA9PiBjaGFyID49IDB4REI4MCAmJiBjaGFyIDw9IDB4REJGRixcbiAgICAvLyAnTG93IFN1cnJvZ2F0ZXMnOiAoY2hhcikgPT4gY2hhciA+PSAweERDMDAgJiYgY2hhciA8PSAweERGRkYsXG4gICAgJ1ByaXZhdGUgVXNlIEFyZWEnOiAoY2hhcikgPT4gY2hhciA+PSAweEUwMDAgJiYgY2hhciA8PSAweEY4RkYsXG4gICAgJ0NKSyBDb21wYXRpYmlsaXR5IElkZW9ncmFwaHMnOiAoY2hhcikgPT4gY2hhciA+PSAweEY5MDAgJiYgY2hhciA8PSAweEZBRkYsXG4gICAgLy8gJ0FscGhhYmV0aWMgUHJlc2VudGF0aW9uIEZvcm1zJzogKGNoYXIpID0+IGNoYXIgPj0gMHhGQjAwICYmIGNoYXIgPD0gMHhGQjRGLFxuICAgICdBcmFiaWMgUHJlc2VudGF0aW9uIEZvcm1zLUEnOiAoY2hhcikgPT4gY2hhciA+PSAweEZCNTAgJiYgY2hhciA8PSAweEZERkYsXG4gICAgLy8gJ1ZhcmlhdGlvbiBTZWxlY3RvcnMnOiAoY2hhcikgPT4gY2hhciA+PSAweEZFMDAgJiYgY2hhciA8PSAweEZFMEYsXG4gICAgJ1ZlcnRpY2FsIEZvcm1zJzogKGNoYXIpID0+IGNoYXIgPj0gMHhGRTEwICYmIGNoYXIgPD0gMHhGRTFGLFxuICAgIC8vICdDb21iaW5pbmcgSGFsZiBNYXJrcyc6IChjaGFyKSA9PiBjaGFyID49IDB4RkUyMCAmJiBjaGFyIDw9IDB4RkUyRixcbiAgICAnQ0pLIENvbXBhdGliaWxpdHkgRm9ybXMnOiAoY2hhcikgPT4gY2hhciA+PSAweEZFMzAgJiYgY2hhciA8PSAweEZFNEYsXG4gICAgJ1NtYWxsIEZvcm0gVmFyaWFudHMnOiAoY2hhcikgPT4gY2hhciA+PSAweEZFNTAgJiYgY2hhciA8PSAweEZFNkYsXG4gICAgJ0FyYWJpYyBQcmVzZW50YXRpb24gRm9ybXMtQic6IChjaGFyKSA9PiBjaGFyID49IDB4RkU3MCAmJiBjaGFyIDw9IDB4RkVGRixcbiAgICAnSGFsZndpZHRoIGFuZCBGdWxsd2lkdGggRm9ybXMnOiAoY2hhcikgPT4gY2hhciA+PSAweEZGMDAgJiYgY2hhciA8PSAweEZGRUZcbiAgICAvLyAnU3BlY2lhbHMnOiAoY2hhcikgPT4gY2hhciA+PSAweEZGRjAgJiYgY2hhciA8PSAweEZGRkYsXG4gICAgLy8gJ0xpbmVhciBCIFN5bGxhYmFyeSc6IChjaGFyKSA9PiBjaGFyID49IDB4MTAwMDAgJiYgY2hhciA8PSAweDEwMDdGLFxuICAgIC8vICdMaW5lYXIgQiBJZGVvZ3JhbXMnOiAoY2hhcikgPT4gY2hhciA+PSAweDEwMDgwICYmIGNoYXIgPD0gMHgxMDBGRixcbiAgICAvLyAnQWVnZWFuIE51bWJlcnMnOiAoY2hhcikgPT4gY2hhciA+PSAweDEwMTAwICYmIGNoYXIgPD0gMHgxMDEzRixcbiAgICAvLyAnQW5jaWVudCBHcmVlayBOdW1iZXJzJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxMDE0MCAmJiBjaGFyIDw9IDB4MTAxOEYsXG4gICAgLy8gJ0FuY2llbnQgU3ltYm9scyc6IChjaGFyKSA9PiBjaGFyID49IDB4MTAxOTAgJiYgY2hhciA8PSAweDEwMUNGLFxuICAgIC8vICdQaGFpc3RvcyBEaXNjJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxMDFEMCAmJiBjaGFyIDw9IDB4MTAxRkYsXG4gICAgLy8gJ0x5Y2lhbic6IChjaGFyKSA9PiBjaGFyID49IDB4MTAyODAgJiYgY2hhciA8PSAweDEwMjlGLFxuICAgIC8vICdDYXJpYW4nOiAoY2hhcikgPT4gY2hhciA+PSAweDEwMkEwICYmIGNoYXIgPD0gMHgxMDJERixcbiAgICAvLyAnQ29wdGljIEVwYWN0IE51bWJlcnMnOiAoY2hhcikgPT4gY2hhciA+PSAweDEwMkUwICYmIGNoYXIgPD0gMHgxMDJGRixcbiAgICAvLyAnT2xkIEl0YWxpYyc6IChjaGFyKSA9PiBjaGFyID49IDB4MTAzMDAgJiYgY2hhciA8PSAweDEwMzJGLFxuICAgIC8vICdHb3RoaWMnOiAoY2hhcikgPT4gY2hhciA+PSAweDEwMzMwICYmIGNoYXIgPD0gMHgxMDM0RixcbiAgICAvLyAnT2xkIFBlcm1pYyc6IChjaGFyKSA9PiBjaGFyID49IDB4MTAzNTAgJiYgY2hhciA8PSAweDEwMzdGLFxuICAgIC8vICdVZ2FyaXRpYyc6IChjaGFyKSA9PiBjaGFyID49IDB4MTAzODAgJiYgY2hhciA8PSAweDEwMzlGLFxuICAgIC8vICdPbGQgUGVyc2lhbic6IChjaGFyKSA9PiBjaGFyID49IDB4MTAzQTAgJiYgY2hhciA8PSAweDEwM0RGLFxuICAgIC8vICdEZXNlcmV0JzogKGNoYXIpID0+IGNoYXIgPj0gMHgxMDQwMCAmJiBjaGFyIDw9IDB4MTA0NEYsXG4gICAgLy8gJ1NoYXZpYW4nOiAoY2hhcikgPT4gY2hhciA+PSAweDEwNDUwICYmIGNoYXIgPD0gMHgxMDQ3RixcbiAgICAvLyAnT3NtYW55YSc6IChjaGFyKSA9PiBjaGFyID49IDB4MTA0ODAgJiYgY2hhciA8PSAweDEwNEFGLFxuICAgIC8vICdPc2FnZSc6IChjaGFyKSA9PiBjaGFyID49IDB4MTA0QjAgJiYgY2hhciA8PSAweDEwNEZGLFxuICAgIC8vICdFbGJhc2FuJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxMDUwMCAmJiBjaGFyIDw9IDB4MTA1MkYsXG4gICAgLy8gJ0NhdWNhc2lhbiBBbGJhbmlhbic6IChjaGFyKSA9PiBjaGFyID49IDB4MTA1MzAgJiYgY2hhciA8PSAweDEwNTZGLFxuICAgIC8vICdMaW5lYXIgQSc6IChjaGFyKSA9PiBjaGFyID49IDB4MTA2MDAgJiYgY2hhciA8PSAweDEwNzdGLFxuICAgIC8vICdDeXByaW90IFN5bGxhYmFyeSc6IChjaGFyKSA9PiBjaGFyID49IDB4MTA4MDAgJiYgY2hhciA8PSAweDEwODNGLFxuICAgIC8vICdJbXBlcmlhbCBBcmFtYWljJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxMDg0MCAmJiBjaGFyIDw9IDB4MTA4NUYsXG4gICAgLy8gJ1BhbG15cmVuZSc6IChjaGFyKSA9PiBjaGFyID49IDB4MTA4NjAgJiYgY2hhciA8PSAweDEwODdGLFxuICAgIC8vICdOYWJhdGFlYW4nOiAoY2hhcikgPT4gY2hhciA+PSAweDEwODgwICYmIGNoYXIgPD0gMHgxMDhBRixcbiAgICAvLyAnSGF0cmFuJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxMDhFMCAmJiBjaGFyIDw9IDB4MTA4RkYsXG4gICAgLy8gJ1Bob2VuaWNpYW4nOiAoY2hhcikgPT4gY2hhciA+PSAweDEwOTAwICYmIGNoYXIgPD0gMHgxMDkxRixcbiAgICAvLyAnTHlkaWFuJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxMDkyMCAmJiBjaGFyIDw9IDB4MTA5M0YsXG4gICAgLy8gJ01lcm9pdGljIEhpZXJvZ2x5cGhzJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxMDk4MCAmJiBjaGFyIDw9IDB4MTA5OUYsXG4gICAgLy8gJ01lcm9pdGljIEN1cnNpdmUnOiAoY2hhcikgPT4gY2hhciA+PSAweDEwOUEwICYmIGNoYXIgPD0gMHgxMDlGRixcbiAgICAvLyAnS2hhcm9zaHRoaSc6IChjaGFyKSA9PiBjaGFyID49IDB4MTBBMDAgJiYgY2hhciA8PSAweDEwQTVGLFxuICAgIC8vICdPbGQgU291dGggQXJhYmlhbic6IChjaGFyKSA9PiBjaGFyID49IDB4MTBBNjAgJiYgY2hhciA8PSAweDEwQTdGLFxuICAgIC8vICdPbGQgTm9ydGggQXJhYmlhbic6IChjaGFyKSA9PiBjaGFyID49IDB4MTBBODAgJiYgY2hhciA8PSAweDEwQTlGLFxuICAgIC8vICdNYW5pY2hhZWFuJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxMEFDMCAmJiBjaGFyIDw9IDB4MTBBRkYsXG4gICAgLy8gJ0F2ZXN0YW4nOiAoY2hhcikgPT4gY2hhciA+PSAweDEwQjAwICYmIGNoYXIgPD0gMHgxMEIzRixcbiAgICAvLyAnSW5zY3JpcHRpb25hbCBQYXJ0aGlhbic6IChjaGFyKSA9PiBjaGFyID49IDB4MTBCNDAgJiYgY2hhciA8PSAweDEwQjVGLFxuICAgIC8vICdJbnNjcmlwdGlvbmFsIFBhaGxhdmknOiAoY2hhcikgPT4gY2hhciA+PSAweDEwQjYwICYmIGNoYXIgPD0gMHgxMEI3RixcbiAgICAvLyAnUHNhbHRlciBQYWhsYXZpJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxMEI4MCAmJiBjaGFyIDw9IDB4MTBCQUYsXG4gICAgLy8gJ09sZCBUdXJraWMnOiAoY2hhcikgPT4gY2hhciA+PSAweDEwQzAwICYmIGNoYXIgPD0gMHgxMEM0RixcbiAgICAvLyAnT2xkIEh1bmdhcmlhbic6IChjaGFyKSA9PiBjaGFyID49IDB4MTBDODAgJiYgY2hhciA8PSAweDEwQ0ZGLFxuICAgIC8vICdIYW5pZmkgUm9oaW5neWEnOiAoY2hhcikgPT4gY2hhciA+PSAweDEwRDAwICYmIGNoYXIgPD0gMHgxMEQzRixcbiAgICAvLyAnUnVtaSBOdW1lcmFsIFN5bWJvbHMnOiAoY2hhcikgPT4gY2hhciA+PSAweDEwRTYwICYmIGNoYXIgPD0gMHgxMEU3RixcbiAgICAvLyAnT2xkIFNvZ2RpYW4nOiAoY2hhcikgPT4gY2hhciA+PSAweDEwRjAwICYmIGNoYXIgPD0gMHgxMEYyRixcbiAgICAvLyAnU29nZGlhbic6IChjaGFyKSA9PiBjaGFyID49IDB4MTBGMzAgJiYgY2hhciA8PSAweDEwRjZGLFxuICAgIC8vICdFbHltYWljJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxMEZFMCAmJiBjaGFyIDw9IDB4MTBGRkYsXG4gICAgLy8gJ0JyYWhtaSc6IChjaGFyKSA9PiBjaGFyID49IDB4MTEwMDAgJiYgY2hhciA8PSAweDExMDdGLFxuICAgIC8vICdLYWl0aGknOiAoY2hhcikgPT4gY2hhciA+PSAweDExMDgwICYmIGNoYXIgPD0gMHgxMTBDRixcbiAgICAvLyAnU29yYSBTb21wZW5nJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxMTBEMCAmJiBjaGFyIDw9IDB4MTEwRkYsXG4gICAgLy8gJ0NoYWttYSc6IChjaGFyKSA9PiBjaGFyID49IDB4MTExMDAgJiYgY2hhciA8PSAweDExMTRGLFxuICAgIC8vICdNYWhhamFuaSc6IChjaGFyKSA9PiBjaGFyID49IDB4MTExNTAgJiYgY2hhciA8PSAweDExMTdGLFxuICAgIC8vICdTaGFyYWRhJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxMTE4MCAmJiBjaGFyIDw9IDB4MTExREYsXG4gICAgLy8gJ1NpbmhhbGEgQXJjaGFpYyBOdW1iZXJzJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxMTFFMCAmJiBjaGFyIDw9IDB4MTExRkYsXG4gICAgLy8gJ0tob2praSc6IChjaGFyKSA9PiBjaGFyID49IDB4MTEyMDAgJiYgY2hhciA8PSAweDExMjRGLFxuICAgIC8vICdNdWx0YW5pJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxMTI4MCAmJiBjaGFyIDw9IDB4MTEyQUYsXG4gICAgLy8gJ0todWRhd2FkaSc6IChjaGFyKSA9PiBjaGFyID49IDB4MTEyQjAgJiYgY2hhciA8PSAweDExMkZGLFxuICAgIC8vICdHcmFudGhhJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxMTMwMCAmJiBjaGFyIDw9IDB4MTEzN0YsXG4gICAgLy8gJ05ld2EnOiAoY2hhcikgPT4gY2hhciA+PSAweDExNDAwICYmIGNoYXIgPD0gMHgxMTQ3RixcbiAgICAvLyAnVGlyaHV0YSc6IChjaGFyKSA9PiBjaGFyID49IDB4MTE0ODAgJiYgY2hhciA8PSAweDExNERGLFxuICAgIC8vICdTaWRkaGFtJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxMTU4MCAmJiBjaGFyIDw9IDB4MTE1RkYsXG4gICAgLy8gJ01vZGknOiAoY2hhcikgPT4gY2hhciA+PSAweDExNjAwICYmIGNoYXIgPD0gMHgxMTY1RixcbiAgICAvLyAnTW9uZ29saWFuIFN1cHBsZW1lbnQnOiAoY2hhcikgPT4gY2hhciA+PSAweDExNjYwICYmIGNoYXIgPD0gMHgxMTY3RixcbiAgICAvLyAnVGFrcmknOiAoY2hhcikgPT4gY2hhciA+PSAweDExNjgwICYmIGNoYXIgPD0gMHgxMTZDRixcbiAgICAvLyAnQWhvbSc6IChjaGFyKSA9PiBjaGFyID49IDB4MTE3MDAgJiYgY2hhciA8PSAweDExNzNGLFxuICAgIC8vICdEb2dyYSc6IChjaGFyKSA9PiBjaGFyID49IDB4MTE4MDAgJiYgY2hhciA8PSAweDExODRGLFxuICAgIC8vICdXYXJhbmcgQ2l0aSc6IChjaGFyKSA9PiBjaGFyID49IDB4MTE4QTAgJiYgY2hhciA8PSAweDExOEZGLFxuICAgIC8vICdOYW5kaW5hZ2FyaSc6IChjaGFyKSA9PiBjaGFyID49IDB4MTE5QTAgJiYgY2hhciA8PSAweDExOUZGLFxuICAgIC8vICdaYW5hYmF6YXIgU3F1YXJlJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxMUEwMCAmJiBjaGFyIDw9IDB4MTFBNEYsXG4gICAgLy8gJ1NveW9tYm8nOiAoY2hhcikgPT4gY2hhciA+PSAweDExQTUwICYmIGNoYXIgPD0gMHgxMUFBRixcbiAgICAvLyAnUGF1IENpbiBIYXUnOiAoY2hhcikgPT4gY2hhciA+PSAweDExQUMwICYmIGNoYXIgPD0gMHgxMUFGRixcbiAgICAvLyAnQmhhaWtzdWtpJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxMUMwMCAmJiBjaGFyIDw9IDB4MTFDNkYsXG4gICAgLy8gJ01hcmNoZW4nOiAoY2hhcikgPT4gY2hhciA+PSAweDExQzcwICYmIGNoYXIgPD0gMHgxMUNCRixcbiAgICAvLyAnTWFzYXJhbSBHb25kaSc6IChjaGFyKSA9PiBjaGFyID49IDB4MTFEMDAgJiYgY2hhciA8PSAweDExRDVGLFxuICAgIC8vICdHdW5qYWxhIEdvbmRpJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxMUQ2MCAmJiBjaGFyIDw9IDB4MTFEQUYsXG4gICAgLy8gJ01ha2FzYXInOiAoY2hhcikgPT4gY2hhciA+PSAweDExRUUwICYmIGNoYXIgPD0gMHgxMUVGRixcbiAgICAvLyAnVGFtaWwgU3VwcGxlbWVudCc6IChjaGFyKSA9PiBjaGFyID49IDB4MTFGQzAgJiYgY2hhciA8PSAweDExRkZGLFxuICAgIC8vICdDdW5laWZvcm0nOiAoY2hhcikgPT4gY2hhciA+PSAweDEyMDAwICYmIGNoYXIgPD0gMHgxMjNGRixcbiAgICAvLyAnQ3VuZWlmb3JtIE51bWJlcnMgYW5kIFB1bmN0dWF0aW9uJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxMjQwMCAmJiBjaGFyIDw9IDB4MTI0N0YsXG4gICAgLy8gJ0Vhcmx5IER5bmFzdGljIEN1bmVpZm9ybSc6IChjaGFyKSA9PiBjaGFyID49IDB4MTI0ODAgJiYgY2hhciA8PSAweDEyNTRGLFxuICAgIC8vICdFZ3lwdGlhbiBIaWVyb2dseXBocyc6IChjaGFyKSA9PiBjaGFyID49IDB4MTMwMDAgJiYgY2hhciA8PSAweDEzNDJGLFxuICAgIC8vICdFZ3lwdGlhbiBIaWVyb2dseXBoIEZvcm1hdCBDb250cm9scyc6IChjaGFyKSA9PiBjaGFyID49IDB4MTM0MzAgJiYgY2hhciA8PSAweDEzNDNGLFxuICAgIC8vICdBbmF0b2xpYW4gSGllcm9nbHlwaHMnOiAoY2hhcikgPT4gY2hhciA+PSAweDE0NDAwICYmIGNoYXIgPD0gMHgxNDY3RixcbiAgICAvLyAnQmFtdW0gU3VwcGxlbWVudCc6IChjaGFyKSA9PiBjaGFyID49IDB4MTY4MDAgJiYgY2hhciA8PSAweDE2QTNGLFxuICAgIC8vICdNcm8nOiAoY2hhcikgPT4gY2hhciA+PSAweDE2QTQwICYmIGNoYXIgPD0gMHgxNkE2RixcbiAgICAvLyAnQmFzc2EgVmFoJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxNkFEMCAmJiBjaGFyIDw9IDB4MTZBRkYsXG4gICAgLy8gJ1BhaGF3aCBIbW9uZyc6IChjaGFyKSA9PiBjaGFyID49IDB4MTZCMDAgJiYgY2hhciA8PSAweDE2QjhGLFxuICAgIC8vICdNZWRlZmFpZHJpbic6IChjaGFyKSA9PiBjaGFyID49IDB4MTZFNDAgJiYgY2hhciA8PSAweDE2RTlGLFxuICAgIC8vICdNaWFvJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxNkYwMCAmJiBjaGFyIDw9IDB4MTZGOUYsXG4gICAgLy8gJ0lkZW9ncmFwaGljIFN5bWJvbHMgYW5kIFB1bmN0dWF0aW9uJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxNkZFMCAmJiBjaGFyIDw9IDB4MTZGRkYsXG4gICAgLy8gJ1Rhbmd1dCc6IChjaGFyKSA9PiBjaGFyID49IDB4MTcwMDAgJiYgY2hhciA8PSAweDE4N0ZGLFxuICAgIC8vICdUYW5ndXQgQ29tcG9uZW50cyc6IChjaGFyKSA9PiBjaGFyID49IDB4MTg4MDAgJiYgY2hhciA8PSAweDE4QUZGLFxuICAgIC8vICdLYW5hIFN1cHBsZW1lbnQnOiAoY2hhcikgPT4gY2hhciA+PSAweDFCMDAwICYmIGNoYXIgPD0gMHgxQjBGRixcbiAgICAvLyAnS2FuYSBFeHRlbmRlZC1BJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxQjEwMCAmJiBjaGFyIDw9IDB4MUIxMkYsXG4gICAgLy8gJ1NtYWxsIEthbmEgRXh0ZW5zaW9uJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxQjEzMCAmJiBjaGFyIDw9IDB4MUIxNkYsXG4gICAgLy8gJ051c2h1JzogKGNoYXIpID0+IGNoYXIgPj0gMHgxQjE3MCAmJiBjaGFyIDw9IDB4MUIyRkYsXG4gICAgLy8gJ0R1cGxveWFuJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxQkMwMCAmJiBjaGFyIDw9IDB4MUJDOUYsXG4gICAgLy8gJ1Nob3J0aGFuZCBGb3JtYXQgQ29udHJvbHMnOiAoY2hhcikgPT4gY2hhciA+PSAweDFCQ0EwICYmIGNoYXIgPD0gMHgxQkNBRixcbiAgICAvLyAnQnl6YW50aW5lIE11c2ljYWwgU3ltYm9scyc6IChjaGFyKSA9PiBjaGFyID49IDB4MUQwMDAgJiYgY2hhciA8PSAweDFEMEZGLFxuICAgIC8vICdNdXNpY2FsIFN5bWJvbHMnOiAoY2hhcikgPT4gY2hhciA+PSAweDFEMTAwICYmIGNoYXIgPD0gMHgxRDFGRixcbiAgICAvLyAnQW5jaWVudCBHcmVlayBNdXNpY2FsIE5vdGF0aW9uJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxRDIwMCAmJiBjaGFyIDw9IDB4MUQyNEYsXG4gICAgLy8gJ01heWFuIE51bWVyYWxzJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxRDJFMCAmJiBjaGFyIDw9IDB4MUQyRkYsXG4gICAgLy8gJ1RhaSBYdWFuIEppbmcgU3ltYm9scyc6IChjaGFyKSA9PiBjaGFyID49IDB4MUQzMDAgJiYgY2hhciA8PSAweDFEMzVGLFxuICAgIC8vICdDb3VudGluZyBSb2QgTnVtZXJhbHMnOiAoY2hhcikgPT4gY2hhciA+PSAweDFEMzYwICYmIGNoYXIgPD0gMHgxRDM3RixcbiAgICAvLyAnTWF0aGVtYXRpY2FsIEFscGhhbnVtZXJpYyBTeW1ib2xzJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxRDQwMCAmJiBjaGFyIDw9IDB4MUQ3RkYsXG4gICAgLy8gJ1N1dHRvbiBTaWduV3JpdGluZyc6IChjaGFyKSA9PiBjaGFyID49IDB4MUQ4MDAgJiYgY2hhciA8PSAweDFEQUFGLFxuICAgIC8vICdHbGFnb2xpdGljIFN1cHBsZW1lbnQnOiAoY2hhcikgPT4gY2hhciA+PSAweDFFMDAwICYmIGNoYXIgPD0gMHgxRTAyRixcbiAgICAvLyAnTnlpYWtlbmcgUHVhY2h1ZSBIbW9uZyc6IChjaGFyKSA9PiBjaGFyID49IDB4MUUxMDAgJiYgY2hhciA8PSAweDFFMTRGLFxuICAgIC8vICdXYW5jaG8nOiAoY2hhcikgPT4gY2hhciA+PSAweDFFMkMwICYmIGNoYXIgPD0gMHgxRTJGRixcbiAgICAvLyAnTWVuZGUgS2lrYWt1aSc6IChjaGFyKSA9PiBjaGFyID49IDB4MUU4MDAgJiYgY2hhciA8PSAweDFFOERGLFxuICAgIC8vICdBZGxhbSc6IChjaGFyKSA9PiBjaGFyID49IDB4MUU5MDAgJiYgY2hhciA8PSAweDFFOTVGLFxuICAgIC8vICdJbmRpYyBTaXlhcSBOdW1iZXJzJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxRUM3MCAmJiBjaGFyIDw9IDB4MUVDQkYsXG4gICAgLy8gJ090dG9tYW4gU2l5YXEgTnVtYmVycyc6IChjaGFyKSA9PiBjaGFyID49IDB4MUVEMDAgJiYgY2hhciA8PSAweDFFRDRGLFxuICAgIC8vICdBcmFiaWMgTWF0aGVtYXRpY2FsIEFscGhhYmV0aWMgU3ltYm9scyc6IChjaGFyKSA9PiBjaGFyID49IDB4MUVFMDAgJiYgY2hhciA8PSAweDFFRUZGLFxuICAgIC8vICdNYWhqb25nIFRpbGVzJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxRjAwMCAmJiBjaGFyIDw9IDB4MUYwMkYsXG4gICAgLy8gJ0RvbWlubyBUaWxlcyc6IChjaGFyKSA9PiBjaGFyID49IDB4MUYwMzAgJiYgY2hhciA8PSAweDFGMDlGLFxuICAgIC8vICdQbGF5aW5nIENhcmRzJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxRjBBMCAmJiBjaGFyIDw9IDB4MUYwRkYsXG4gICAgLy8gJ0VuY2xvc2VkIEFscGhhbnVtZXJpYyBTdXBwbGVtZW50JzogKGNoYXIpID0+IGNoYXIgPj0gMHgxRjEwMCAmJiBjaGFyIDw9IDB4MUYxRkYsXG4gICAgLy8gJ0VuY2xvc2VkIElkZW9ncmFwaGljIFN1cHBsZW1lbnQnOiAoY2hhcikgPT4gY2hhciA+PSAweDFGMjAwICYmIGNoYXIgPD0gMHgxRjJGRixcbiAgICAvLyAnTWlzY2VsbGFuZW91cyBTeW1ib2xzIGFuZCBQaWN0b2dyYXBocyc6IChjaGFyKSA9PiBjaGFyID49IDB4MUYzMDAgJiYgY2hhciA8PSAweDFGNUZGLFxuICAgIC8vICdFbW90aWNvbnMnOiAoY2hhcikgPT4gY2hhciA+PSAweDFGNjAwICYmIGNoYXIgPD0gMHgxRjY0RixcbiAgICAvLyAnT3JuYW1lbnRhbCBEaW5nYmF0cyc6IChjaGFyKSA9PiBjaGFyID49IDB4MUY2NTAgJiYgY2hhciA8PSAweDFGNjdGLFxuICAgIC8vICdUcmFuc3BvcnQgYW5kIE1hcCBTeW1ib2xzJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxRjY4MCAmJiBjaGFyIDw9IDB4MUY2RkYsXG4gICAgLy8gJ0FsY2hlbWljYWwgU3ltYm9scyc6IChjaGFyKSA9PiBjaGFyID49IDB4MUY3MDAgJiYgY2hhciA8PSAweDFGNzdGLFxuICAgIC8vICdHZW9tZXRyaWMgU2hhcGVzIEV4dGVuZGVkJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxRjc4MCAmJiBjaGFyIDw9IDB4MUY3RkYsXG4gICAgLy8gJ1N1cHBsZW1lbnRhbCBBcnJvd3MtQyc6IChjaGFyKSA9PiBjaGFyID49IDB4MUY4MDAgJiYgY2hhciA8PSAweDFGOEZGLFxuICAgIC8vICdTdXBwbGVtZW50YWwgU3ltYm9scyBhbmQgUGljdG9ncmFwaHMnOiAoY2hhcikgPT4gY2hhciA+PSAweDFGOTAwICYmIGNoYXIgPD0gMHgxRjlGRixcbiAgICAvLyAnQ2hlc3MgU3ltYm9scyc6IChjaGFyKSA9PiBjaGFyID49IDB4MUZBMDAgJiYgY2hhciA8PSAweDFGQTZGLFxuICAgIC8vICdTeW1ib2xzIGFuZCBQaWN0b2dyYXBocyBFeHRlbmRlZC1BJzogKGNoYXIpID0+IGNoYXIgPj0gMHgxRkE3MCAmJiBjaGFyIDw9IDB4MUZBRkYsXG4gICAgLy8gJ0NKSyBVbmlmaWVkIElkZW9ncmFwaHMgRXh0ZW5zaW9uIEInOiAoY2hhcikgPT4gY2hhciA+PSAweDIwMDAwICYmIGNoYXIgPD0gMHgyQTZERixcbiAgICAvLyAnQ0pLIFVuaWZpZWQgSWRlb2dyYXBocyBFeHRlbnNpb24gQyc6IChjaGFyKSA9PiBjaGFyID49IDB4MkE3MDAgJiYgY2hhciA8PSAweDJCNzNGLFxuICAgIC8vICdDSksgVW5pZmllZCBJZGVvZ3JhcGhzIEV4dGVuc2lvbiBEJzogKGNoYXIpID0+IGNoYXIgPj0gMHgyQjc0MCAmJiBjaGFyIDw9IDB4MkI4MUYsXG4gICAgLy8gJ0NKSyBVbmlmaWVkIElkZW9ncmFwaHMgRXh0ZW5zaW9uIEUnOiAoY2hhcikgPT4gY2hhciA+PSAweDJCODIwICYmIGNoYXIgPD0gMHgyQ0VBRixcbiAgICAvLyAnQ0pLIFVuaWZpZWQgSWRlb2dyYXBocyBFeHRlbnNpb24gRic6IChjaGFyKSA9PiBjaGFyID49IDB4MkNFQjAgJiYgY2hhciA8PSAweDJFQkVGLFxuICAgIC8vICdDSksgQ29tcGF0aWJpbGl0eSBJZGVvZ3JhcGhzIFN1cHBsZW1lbnQnOiAoY2hhcikgPT4gY2hhciA+PSAweDJGODAwICYmIGNoYXIgPD0gMHgyRkExRixcbiAgICAvLyAnVGFncyc6IChjaGFyKSA9PiBjaGFyID49IDB4RTAwMDAgJiYgY2hhciA8PSAweEUwMDdGLFxuICAgIC8vICdWYXJpYXRpb24gU2VsZWN0b3JzIFN1cHBsZW1lbnQnOiAoY2hhcikgPT4gY2hhciA+PSAweEUwMTAwICYmIGNoYXIgPD0gMHhFMDFFRixcbiAgICAvLyAnU3VwcGxlbWVudGFyeSBQcml2YXRlIFVzZSBBcmVhLUEnOiAoY2hhcikgPT4gY2hhciA+PSAweEYwMDAwICYmIGNoYXIgPD0gMHhGRkZGRixcbiAgICAvLyAnU3VwcGxlbWVudGFyeSBQcml2YXRlIFVzZSBBcmVhLUInOiAoY2hhcikgPT4gY2hhciA+PSAweDEwMDAwMCAmJiBjaGFyIDw9IDB4MTBGRkZGLFxufTtcblxuZXhwb3J0IGRlZmF1bHQgdW5pY29kZUJsb2NrTG9va3VwO1xuIiwiLy8gQGZsb3dcblxuLyogZXNsaW50LWRpc2FibGUgbmV3LWNhcCAqL1xuXG5pbXBvcnQgaXNDaGFyIGZyb20gJy4vaXNfY2hhcl9pbl91bmljb2RlX2Jsb2NrLmpzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGFsbG93c0lkZW9ncmFwaGljQnJlYWtpbmcoY2hhcnM6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGZvciAoY29uc3QgY2hhciBvZiBjaGFycykge1xuICAgICAgICBpZiAoIWNoYXJBbGxvd3NJZGVvZ3JhcGhpY0JyZWFraW5nKGNoYXIuY2hhckNvZGVBdCgwKSkpIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhbGxvd3NWZXJ0aWNhbFdyaXRpbmdNb2RlKGNoYXJzOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBmb3IgKGNvbnN0IGNoYXIgb2YgY2hhcnMpIHtcbiAgICAgICAgaWYgKGNoYXJIYXNVcHJpZ2h0VmVydGljYWxPcmllbnRhdGlvbihjaGFyLmNoYXJDb2RlQXQoMCkpKSByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYWxsb3dzTGV0dGVyU3BhY2luZyhjaGFyczogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgZm9yIChjb25zdCBjaGFyIG9mIGNoYXJzKSB7XG4gICAgICAgIGlmICghY2hhckFsbG93c0xldHRlclNwYWNpbmcoY2hhci5jaGFyQ29kZUF0KDApKSkgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNoYXJBbGxvd3NMZXR0ZXJTcGFjaW5nKGNoYXI6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIGlmIChpc0NoYXJbJ0FyYWJpYyddKGNoYXIpKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKGlzQ2hhclsnQXJhYmljIFN1cHBsZW1lbnQnXShjaGFyKSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChpc0NoYXJbJ0FyYWJpYyBFeHRlbmRlZC1BJ10oY2hhcikpIHJldHVybiBmYWxzZTtcbiAgICBpZiAoaXNDaGFyWydBcmFiaWMgUHJlc2VudGF0aW9uIEZvcm1zLUEnXShjaGFyKSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChpc0NoYXJbJ0FyYWJpYyBQcmVzZW50YXRpb24gRm9ybXMtQiddKGNoYXIpKSByZXR1cm4gZmFsc2U7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNoYXJBbGxvd3NJZGVvZ3JhcGhpY0JyZWFraW5nKGNoYXI6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIC8vIFJldHVybiBlYXJseSBmb3IgY2hhcmFjdGVycyBvdXRzaWRlIGFsbCBpZGVvZ3JhcGhpYyByYW5nZXMuXG4gICAgaWYgKGNoYXIgPCAweDJFODApIHJldHVybiBmYWxzZTtcblxuICAgIGlmIChpc0NoYXJbJ0JvcG9tb2ZvIEV4dGVuZGVkJ10oY2hhcikpIHJldHVybiB0cnVlO1xuICAgIGlmIChpc0NoYXJbJ0JvcG9tb2ZvJ10oY2hhcikpIHJldHVybiB0cnVlO1xuICAgIGlmIChpc0NoYXJbJ0NKSyBDb21wYXRpYmlsaXR5IEZvcm1zJ10oY2hhcikpIHJldHVybiB0cnVlO1xuICAgIGlmIChpc0NoYXJbJ0NKSyBDb21wYXRpYmlsaXR5IElkZW9ncmFwaHMnXShjaGFyKSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKGlzQ2hhclsnQ0pLIENvbXBhdGliaWxpdHknXShjaGFyKSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKGlzQ2hhclsnQ0pLIFJhZGljYWxzIFN1cHBsZW1lbnQnXShjaGFyKSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKGlzQ2hhclsnQ0pLIFN0cm9rZXMnXShjaGFyKSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKGlzQ2hhclsnQ0pLIFN5bWJvbHMgYW5kIFB1bmN0dWF0aW9uJ10oY2hhcikpIHJldHVybiB0cnVlO1xuICAgIGlmIChpc0NoYXJbJ0NKSyBVbmlmaWVkIElkZW9ncmFwaHMgRXh0ZW5zaW9uIEEnXShjaGFyKSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKGlzQ2hhclsnQ0pLIFVuaWZpZWQgSWRlb2dyYXBocyddKGNoYXIpKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoaXNDaGFyWydFbmNsb3NlZCBDSksgTGV0dGVycyBhbmQgTW9udGhzJ10oY2hhcikpIHJldHVybiB0cnVlO1xuICAgIGlmIChpc0NoYXJbJ0hhbGZ3aWR0aCBhbmQgRnVsbHdpZHRoIEZvcm1zJ10oY2hhcikpIHJldHVybiB0cnVlO1xuICAgIGlmIChpc0NoYXJbJ0hpcmFnYW5hJ10oY2hhcikpIHJldHVybiB0cnVlO1xuICAgIGlmIChpc0NoYXJbJ0lkZW9ncmFwaGljIERlc2NyaXB0aW9uIENoYXJhY3RlcnMnXShjaGFyKSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKGlzQ2hhclsnS2FuZ3hpIFJhZGljYWxzJ10oY2hhcikpIHJldHVybiB0cnVlO1xuICAgIGlmIChpc0NoYXJbJ0thdGFrYW5hIFBob25ldGljIEV4dGVuc2lvbnMnXShjaGFyKSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKGlzQ2hhclsnS2F0YWthbmEnXShjaGFyKSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKGlzQ2hhclsnVmVydGljYWwgRm9ybXMnXShjaGFyKSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKGlzQ2hhclsnWWkgUmFkaWNhbHMnXShjaGFyKSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKGlzQ2hhclsnWWkgU3lsbGFibGVzJ10oY2hhcikpIHJldHVybiB0cnVlO1xuXG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG4vLyBUaGUgZm9sbG93aW5nIGxvZ2ljIGNvbWVzIGZyb21cbi8vIDxodHRwOi8vd3d3LnVuaWNvZGUub3JnL1B1YmxpYy8xMi4wLjAvdWNkL1ZlcnRpY2FsT3JpZW50YXRpb24udHh0Pi5cbi8vIEtlZXAgaXQgc3luY2hyb25pemVkIHdpdGhcbi8vIDxodHRwOi8vd3d3LnVuaWNvZGUub3JnL1B1YmxpYy9VQ0QvbGF0ZXN0L3VjZC9WZXJ0aWNhbE9yaWVudGF0aW9uLnR4dD4uXG4vLyBUaGUgZGF0YSBmaWxlIGRlbm90ZXMgd2l0aCDigJxV4oCdIG9yIOKAnFR14oCdIGFueSBjb2RlcG9pbnQgdGhhdCBtYXkgYmUgZHJhd25cbi8vIHVwcmlnaHQgaW4gdmVydGljYWwgdGV4dCBidXQgZG9lcyBub3QgZGlzdGluZ3Vpc2ggYmV0d2VlbiB1cHJpZ2h0IGFuZFxuLy8g4oCcbmV1dHJhbOKAnSBjaGFyYWN0ZXJzLlxuXG4vLyBCbG9ja3MgaW4gdGhlIFVuaWNvZGUgc3VwcGxlbWVudGFyeSBwbGFuZXMgYXJlIGV4Y2x1ZGVkIGZyb20gdGhpcyBtb2R1bGUgZHVlXG4vLyB0byA8aHR0cHM6Ly9naXRodWIuY29tL21hcGJveC9tYXBib3gtZ2wvaXNzdWVzLzI5Pi5cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIFVuaWNvZGUgY29kZXBvaW50IGlkZW50aWZpZXMgYSBjaGFyYWN0ZXIgd2l0aFxuICogdXByaWdodCBvcmllbnRhdGlvbi5cbiAqXG4gKiBBIGNoYXJhY3RlciBoYXMgdXByaWdodCBvcmllbnRhdGlvbiBpZiBpdCBpcyBkcmF3biB1cHJpZ2h0ICh1bnJvdGF0ZWQpXG4gKiB3aGV0aGVyIHRoZSBsaW5lIGlzIG9yaWVudGVkIGhvcml6b250YWxseSBvciB2ZXJ0aWNhbGx5LCBldmVuIGlmIGJvdGhcbiAqIGFkamFjZW50IGNoYXJhY3RlcnMgY2FuIGJlIHJvdGF0ZWQuIEZvciBleGFtcGxlLCBhIENoaW5lc2UgY2hhcmFjdGVyIGlzXG4gKiBhbHdheXMgZHJhd24gdXByaWdodC4gQW4gdXByaWdodGx5IG9yaWVudGVkIGNoYXJhY3RlciBjYXVzZXMgYW4gYWRqYWNlbnRcbiAqIOKAnG5ldXRyYWzigJ0gY2hhcmFjdGVyIHRvIGJlIGRyYXduIHVwcmlnaHQgYXMgd2VsbC5cbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjaGFySGFzVXByaWdodFZlcnRpY2FsT3JpZW50YXRpb24oY2hhcjogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgaWYgKGNoYXIgPT09IDB4MDJFQSAvKiBtb2RpZmllciBsZXR0ZXIgeWluIGRlcGFydGluZyB0b25lIG1hcmsgKi8gfHxcbiAgICAgICAgY2hhciA9PT0gMHgwMkVCIC8qIG1vZGlmaWVyIGxldHRlciB5YW5nIGRlcGFydGluZyB0b25lIG1hcmsgKi8pIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLy8gUmV0dXJuIGVhcmx5IGZvciBjaGFyYWN0ZXJzIG91dHNpZGUgYWxsIHJhbmdlcyB3aG9zZSBjaGFyYWN0ZXJzIHJlbWFpblxuICAgIC8vIHVwcmlnaHQgaW4gdmVydGljYWwgd3JpdGluZyBtb2RlLlxuICAgIGlmIChjaGFyIDwgMHgxMTAwKSByZXR1cm4gZmFsc2U7XG5cbiAgICBpZiAoaXNDaGFyWydCb3BvbW9mbyBFeHRlbmRlZCddKGNoYXIpKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoaXNDaGFyWydCb3BvbW9mbyddKGNoYXIpKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoaXNDaGFyWydDSksgQ29tcGF0aWJpbGl0eSBGb3JtcyddKGNoYXIpKSB7XG4gICAgICAgIGlmICghKChjaGFyID49IDB4RkU0OSAvKiBkYXNoZWQgb3ZlcmxpbmUgKi8gJiYgY2hhciA8PSAweEZFNEYpIC8qIHdhdnkgbG93IGxpbmUgKi8pKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoaXNDaGFyWydDSksgQ29tcGF0aWJpbGl0eSBJZGVvZ3JhcGhzJ10oY2hhcikpIHJldHVybiB0cnVlO1xuICAgIGlmIChpc0NoYXJbJ0NKSyBDb21wYXRpYmlsaXR5J10oY2hhcikpIHJldHVybiB0cnVlO1xuICAgIGlmIChpc0NoYXJbJ0NKSyBSYWRpY2FscyBTdXBwbGVtZW50J10oY2hhcikpIHJldHVybiB0cnVlO1xuICAgIGlmIChpc0NoYXJbJ0NKSyBTdHJva2VzJ10oY2hhcikpIHJldHVybiB0cnVlO1xuICAgIGlmIChpc0NoYXJbJ0NKSyBTeW1ib2xzIGFuZCBQdW5jdHVhdGlvbiddKGNoYXIpKSB7XG4gICAgICAgIGlmICghKChjaGFyID49IDB4MzAwOCAvKiBsZWZ0IGFuZ2xlIGJyYWNrZXQgKi8gJiYgY2hhciA8PSAweDMwMTEpIC8qIHJpZ2h0IGJsYWNrIGxlbnRpY3VsYXIgYnJhY2tldCAqLykgJiZcbiAgICAgICAgICAgICEoKGNoYXIgPj0gMHgzMDE0IC8qIGxlZnQgdG9ydG9pc2Ugc2hlbGwgYnJhY2tldCAqLyAmJiBjaGFyIDw9IDB4MzAxRikgLyogbG93IGRvdWJsZSBwcmltZSBxdW90YXRpb24gbWFyayAqLykgJiZcbiAgICAgICAgICAgIGNoYXIgIT09IDB4MzAzMCAvKiB3YXZ5IGRhc2ggKi8pIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChpc0NoYXJbJ0NKSyBVbmlmaWVkIElkZW9ncmFwaHMgRXh0ZW5zaW9uIEEnXShjaGFyKSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKGlzQ2hhclsnQ0pLIFVuaWZpZWQgSWRlb2dyYXBocyddKGNoYXIpKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoaXNDaGFyWydFbmNsb3NlZCBDSksgTGV0dGVycyBhbmQgTW9udGhzJ10oY2hhcikpIHJldHVybiB0cnVlO1xuICAgIGlmIChpc0NoYXJbJ0hhbmd1bCBDb21wYXRpYmlsaXR5IEphbW8nXShjaGFyKSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKGlzQ2hhclsnSGFuZ3VsIEphbW8gRXh0ZW5kZWQtQSddKGNoYXIpKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoaXNDaGFyWydIYW5ndWwgSmFtbyBFeHRlbmRlZC1CJ10oY2hhcikpIHJldHVybiB0cnVlO1xuICAgIGlmIChpc0NoYXJbJ0hhbmd1bCBKYW1vJ10oY2hhcikpIHJldHVybiB0cnVlO1xuICAgIGlmIChpc0NoYXJbJ0hhbmd1bCBTeWxsYWJsZXMnXShjaGFyKSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKGlzQ2hhclsnSGlyYWdhbmEnXShjaGFyKSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKGlzQ2hhclsnSWRlb2dyYXBoaWMgRGVzY3JpcHRpb24gQ2hhcmFjdGVycyddKGNoYXIpKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoaXNDaGFyWydLYW5idW4nXShjaGFyKSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKGlzQ2hhclsnS2FuZ3hpIFJhZGljYWxzJ10oY2hhcikpIHJldHVybiB0cnVlO1xuICAgIGlmIChpc0NoYXJbJ0thdGFrYW5hIFBob25ldGljIEV4dGVuc2lvbnMnXShjaGFyKSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKGlzQ2hhclsnS2F0YWthbmEnXShjaGFyKSkge1xuICAgICAgICBpZiAoY2hhciAhPT0gMHgzMEZDIC8qIGthdGFrYW5hLWhpcmFnYW5hIHByb2xvbmdlZCBzb3VuZCBtYXJrICovKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoaXNDaGFyWydIYWxmd2lkdGggYW5kIEZ1bGx3aWR0aCBGb3JtcyddKGNoYXIpKSB7XG4gICAgICAgIGlmIChjaGFyICE9PSAweEZGMDggLyogZnVsbHdpZHRoIGxlZnQgcGFyZW50aGVzaXMgKi8gJiZcbiAgICAgICAgICAgIGNoYXIgIT09IDB4RkYwOSAvKiBmdWxsd2lkdGggcmlnaHQgcGFyZW50aGVzaXMgKi8gJiZcbiAgICAgICAgICAgIGNoYXIgIT09IDB4RkYwRCAvKiBmdWxsd2lkdGggaHlwaGVuLW1pbnVzICovICYmXG4gICAgICAgICAgICAhKChjaGFyID49IDB4RkYxQSAvKiBmdWxsd2lkdGggY29sb24gKi8gJiYgY2hhciA8PSAweEZGMUUpIC8qIGZ1bGx3aWR0aCBncmVhdGVyLXRoYW4gc2lnbiAqLykgJiZcbiAgICAgICAgICAgIGNoYXIgIT09IDB4RkYzQiAvKiBmdWxsd2lkdGggbGVmdCBzcXVhcmUgYnJhY2tldCAqLyAmJlxuICAgICAgICAgICAgY2hhciAhPT0gMHhGRjNEIC8qIGZ1bGx3aWR0aCByaWdodCBzcXVhcmUgYnJhY2tldCAqLyAmJlxuICAgICAgICAgICAgY2hhciAhPT0gMHhGRjNGIC8qIGZ1bGx3aWR0aCBsb3cgbGluZSAqLyAmJlxuICAgICAgICAgICAgIShjaGFyID49IDB4RkY1QiAvKiBmdWxsd2lkdGggbGVmdCBjdXJseSBicmFja2V0ICovICYmIGNoYXIgPD0gMHhGRkRGKSAmJlxuICAgICAgICAgICAgY2hhciAhPT0gMHhGRkUzIC8qIGZ1bGx3aWR0aCBtYWNyb24gKi8gJiZcbiAgICAgICAgICAgICEoY2hhciA+PSAweEZGRTggLyogaGFsZndpZHRoIGZvcm1zIGxpZ2h0IHZlcnRpY2FsICovICYmIGNoYXIgPD0gMHhGRkVGKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGlzQ2hhclsnU21hbGwgRm9ybSBWYXJpYW50cyddKGNoYXIpKSB7XG4gICAgICAgIGlmICghKChjaGFyID49IDB4RkU1OCAvKiBzbWFsbCBlbSBkYXNoICovICYmIGNoYXIgPD0gMHhGRTVFKSAvKiBzbWFsbCByaWdodCB0b3J0b2lzZSBzaGVsbCBicmFja2V0ICovKSAmJlxuICAgICAgICAgICAgISgoY2hhciA+PSAweEZFNjMgLyogc21hbGwgaHlwaGVuLW1pbnVzICovICYmIGNoYXIgPD0gMHhGRTY2KSAvKiBzbWFsbCBlcXVhbHMgc2lnbiAqLykpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChpc0NoYXJbJ1VuaWZpZWQgQ2FuYWRpYW4gQWJvcmlnaW5hbCBTeWxsYWJpY3MnXShjaGFyKSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKGlzQ2hhclsnVW5pZmllZCBDYW5hZGlhbiBBYm9yaWdpbmFsIFN5bGxhYmljcyBFeHRlbmRlZCddKGNoYXIpKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoaXNDaGFyWydWZXJ0aWNhbCBGb3JtcyddKGNoYXIpKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoaXNDaGFyWydZaWppbmcgSGV4YWdyYW0gU3ltYm9scyddKGNoYXIpKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoaXNDaGFyWydZaSBTeWxsYWJsZXMnXShjaGFyKSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKGlzQ2hhclsnWWkgUmFkaWNhbHMnXShjaGFyKSkgcmV0dXJuIHRydWU7XG5cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBVbmljb2RlIGNvZGVwb2ludCBpZGVudGlmaWVzIGEgY2hhcmFjdGVyIHdpdGhcbiAqIG5ldXRyYWwgb3JpZW50YXRpb24uXG4gKlxuICogQSBjaGFyYWN0ZXIgaGFzIG5ldXRyYWwgb3JpZW50YXRpb24gaWYgaXQgbWF5IGJlIGRyYXduIHJvdGF0ZWQgb3IgdW5yb3RhdGVkXG4gKiB3aGVuIHRoZSBsaW5lIGlzIG9yaWVudGVkIHZlcnRpY2FsbHksIGRlcGVuZGluZyBvbiB0aGUgb3JpZW50YXRpb24gb2YgdGhlXG4gKiBhZGphY2VudCBjaGFyYWN0ZXJzLiBGb3IgZXhhbXBsZSwgYWxvbmcgYSB2ZXJ0aWNsbHkgb3JpZW50ZWQgbGluZSwgdGhlIHZ1bGdhclxuICogZnJhY3Rpb24gwr0gaXMgZHJhd24gdXByaWdodCBhbW9uZyBDaGluZXNlIGNoYXJhY3RlcnMgYnV0IHJvdGF0ZWQgYW1vbmcgTGF0aW5cbiAqIGxldHRlcnMuIEEgbmV1dHJhbGx5IG9yaWVudGVkIGNoYXJhY3RlciBkb2VzIG5vdCBpbmZsdWVuY2Ugd2hldGhlciBhblxuICogYWRqYWNlbnQgY2hhcmFjdGVyIGlzIGRyYXduIHVwcmlnaHQgb3Igcm90YXRlZC5cbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjaGFySGFzTmV1dHJhbFZlcnRpY2FsT3JpZW50YXRpb24oY2hhcjogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgaWYgKGlzQ2hhclsnTGF0aW4tMSBTdXBwbGVtZW50J10oY2hhcikpIHtcbiAgICAgICAgaWYgKGNoYXIgPT09IDB4MDBBNyAvKiBzZWN0aW9uIHNpZ24gKi8gfHxcbiAgICAgICAgICAgIGNoYXIgPT09IDB4MDBBOSAvKiBjb3B5cmlnaHQgc2lnbiAqLyB8fFxuICAgICAgICAgICAgY2hhciA9PT0gMHgwMEFFIC8qIHJlZ2lzdGVyZWQgc2lnbiAqLyB8fFxuICAgICAgICAgICAgY2hhciA9PT0gMHgwMEIxIC8qIHBsdXMtbWludXMgc2lnbiAqLyB8fFxuICAgICAgICAgICAgY2hhciA9PT0gMHgwMEJDIC8qIHZ1bGdhciBmcmFjdGlvbiBvbmUgcXVhcnRlciAqLyB8fFxuICAgICAgICAgICAgY2hhciA9PT0gMHgwMEJEIC8qIHZ1bGdhciBmcmFjdGlvbiBvbmUgaGFsZiAqLyB8fFxuICAgICAgICAgICAgY2hhciA9PT0gMHgwMEJFIC8qIHZ1bGdhciBmcmFjdGlvbiB0aHJlZSBxdWFydGVycyAqLyB8fFxuICAgICAgICAgICAgY2hhciA9PT0gMHgwMEQ3IC8qIG11bHRpcGxpY2F0aW9uIHNpZ24gKi8gfHxcbiAgICAgICAgICAgIGNoYXIgPT09IDB4MDBGNyAvKiBkaXZpc2lvbiBzaWduICovKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoaXNDaGFyWydHZW5lcmFsIFB1bmN0dWF0aW9uJ10oY2hhcikpIHtcbiAgICAgICAgaWYgKGNoYXIgPT09IDB4MjAxNiAvKiBkb3VibGUgdmVydGljYWwgbGluZSAqLyB8fFxuICAgICAgICAgICAgY2hhciA9PT0gMHgyMDIwIC8qIGRhZ2dlciAqLyB8fFxuICAgICAgICAgICAgY2hhciA9PT0gMHgyMDIxIC8qIGRvdWJsZSBkYWdnZXIgKi8gfHxcbiAgICAgICAgICAgIGNoYXIgPT09IDB4MjAzMCAvKiBwZXIgbWlsbGUgc2lnbiAqLyB8fFxuICAgICAgICAgICAgY2hhciA9PT0gMHgyMDMxIC8qIHBlciB0ZW4gdGhvdXNhbmQgc2lnbiAqLyB8fFxuICAgICAgICAgICAgY2hhciA9PT0gMHgyMDNCIC8qIHJlZmVyZW5jZSBtYXJrICovIHx8XG4gICAgICAgICAgICBjaGFyID09PSAweDIwM0MgLyogZG91YmxlIGV4Y2xhbWF0aW9uIG1hcmsgKi8gfHxcbiAgICAgICAgICAgIGNoYXIgPT09IDB4MjA0MiAvKiBhc3RlcmlzbSAqLyB8fFxuICAgICAgICAgICAgY2hhciA9PT0gMHgyMDQ3IC8qIGRvdWJsZSBxdWVzdGlvbiBtYXJrICovIHx8XG4gICAgICAgICAgICBjaGFyID09PSAweDIwNDggLyogcXVlc3Rpb24gZXhjbGFtYXRpb24gbWFyayAqLyB8fFxuICAgICAgICAgICAgY2hhciA9PT0gMHgyMDQ5IC8qIGV4Y2xhbWF0aW9uIHF1ZXN0aW9uIG1hcmsgKi8gfHxcbiAgICAgICAgICAgIGNoYXIgPT09IDB4MjA1MSAvKiB0d28gYXN0ZXJpc2tzIGFsaWduZWQgdmVydGljYWxseSAqLykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGlzQ2hhclsnTGV0dGVybGlrZSBTeW1ib2xzJ10oY2hhcikpIHJldHVybiB0cnVlO1xuICAgIGlmIChpc0NoYXJbJ051bWJlciBGb3JtcyddKGNoYXIpKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoaXNDaGFyWydNaXNjZWxsYW5lb3VzIFRlY2huaWNhbCddKGNoYXIpKSB7XG4gICAgICAgIGlmICgoY2hhciA+PSAweDIzMDAgLyogZGlhbWV0ZXIgc2lnbiAqLyAmJiBjaGFyIDw9IDB4MjMwNyAvKiB3YXZ5IGxpbmUgKi8pIHx8XG4gICAgICAgICAgICAoY2hhciA+PSAweDIzMEMgLyogYm90dG9tIHJpZ2h0IGNyb3AgKi8gJiYgY2hhciA8PSAweDIzMUYgLyogYm90dG9tIHJpZ2h0IGNvcm5lciAqLykgfHxcbiAgICAgICAgICAgIChjaGFyID49IDB4MjMyNCAvKiB1cCBhcnJvd2hlYWQgYmV0d2VlbiB0d28gaG9yaXpvbnRhbCBiYXJzICovICYmIGNoYXIgPD0gMHgyMzI4IC8qIGtleWJvYXJkICovKSB8fFxuICAgICAgICAgICAgY2hhciA9PT0gMHgyMzJCIC8qIGVyYXNlIHRvIHRoZSBsZWZ0ICovIHx8XG4gICAgICAgICAgICAoY2hhciA+PSAweDIzN0QgLyogc2hvdWxkZXJlZCBvcGVuIGJveCAqLyAmJiBjaGFyIDw9IDB4MjM5QSAvKiBjbGVhciBzY3JlZW4gc3ltYm9sICovKSB8fFxuICAgICAgICAgICAgKGNoYXIgPj0gMHgyM0JFIC8qIGRlbnRpc3RyeSBzeW1ib2wgbGlnaHQgdmVydGljYWwgYW5kIHRvcCByaWdodCAqLyAmJiBjaGFyIDw9IDB4MjNDRCAvKiBzcXVhcmUgZm9vdCAqLykgfHxcbiAgICAgICAgICAgIGNoYXIgPT09IDB4MjNDRiAvKiBlamVjdCBzeW1ib2wgKi8gfHxcbiAgICAgICAgICAgIChjaGFyID49IDB4MjNEMSAvKiBtZXRyaWNhbCBicmV2ZSAqLyAmJiBjaGFyIDw9IDB4MjNEQiAvKiBmdXNlICovKSB8fFxuICAgICAgICAgICAgKGNoYXIgPj0gMHgyM0UyIC8qIHdoaXRlIHRyYXBleml1bSAqLyAmJiBjaGFyIDw9IDB4MjNGRikpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChpc0NoYXJbJ0NvbnRyb2wgUGljdHVyZXMnXShjaGFyKSAmJiBjaGFyICE9PSAweDI0MjMgLyogb3BlbiBib3ggKi8pIHJldHVybiB0cnVlO1xuICAgIGlmIChpc0NoYXJbJ09wdGljYWwgQ2hhcmFjdGVyIFJlY29nbml0aW9uJ10oY2hhcikpIHJldHVybiB0cnVlO1xuICAgIGlmIChpc0NoYXJbJ0VuY2xvc2VkIEFscGhhbnVtZXJpY3MnXShjaGFyKSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKGlzQ2hhclsnR2VvbWV0cmljIFNoYXBlcyddKGNoYXIpKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoaXNDaGFyWydNaXNjZWxsYW5lb3VzIFN5bWJvbHMnXShjaGFyKSkge1xuICAgICAgICBpZiAoISgoY2hhciA+PSAweDI2MUEgLyogYmxhY2sgbGVmdCBwb2ludGluZyBpbmRleCAqLyAmJiBjaGFyIDw9IDB4MjYxRikgLyogd2hpdGUgZG93biBwb2ludGluZyBpbmRleCAqLykpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChpc0NoYXJbJ01pc2NlbGxhbmVvdXMgU3ltYm9scyBhbmQgQXJyb3dzJ10oY2hhcikpIHtcbiAgICAgICAgaWYgKChjaGFyID49IDB4MkIxMiAvKiBzcXVhcmUgd2l0aCB0b3AgaGFsZiBibGFjayAqLyAmJiBjaGFyIDw9IDB4MkIyRiAvKiB3aGl0ZSB2ZXJ0aWNhbCBlbGxpcHNlICovKSB8fFxuICAgICAgICAgICAgKGNoYXIgPj0gMHgyQjUwIC8qIHdoaXRlIG1lZGl1bSBzdGFyICovICYmIGNoYXIgPD0gMHgyQjU5IC8qIGhlYXZ5IGNpcmNsZWQgc2FsdGlyZSAqLykgfHxcbiAgICAgICAgICAgIChjaGFyID49IDB4MkJCOCAvKiB1cHdhcmRzIHdoaXRlIGFycm93IGZyb20gYmFyIHdpdGggaG9yaXpvbnRhbCBiYXIgKi8gJiYgY2hhciA8PSAweDJCRUIpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoaXNDaGFyWydDSksgU3ltYm9scyBhbmQgUHVuY3R1YXRpb24nXShjaGFyKSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKGlzQ2hhclsnS2F0YWthbmEnXShjaGFyKSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKGlzQ2hhclsnUHJpdmF0ZSBVc2UgQXJlYSddKGNoYXIpKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoaXNDaGFyWydDSksgQ29tcGF0aWJpbGl0eSBGb3JtcyddKGNoYXIpKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoaXNDaGFyWydTbWFsbCBGb3JtIFZhcmlhbnRzJ10oY2hhcikpIHJldHVybiB0cnVlO1xuICAgIGlmIChpc0NoYXJbJ0hhbGZ3aWR0aCBhbmQgRnVsbHdpZHRoIEZvcm1zJ10oY2hhcikpIHJldHVybiB0cnVlO1xuXG4gICAgaWYgKGNoYXIgPT09IDB4MjIxRSAvKiBpbmZpbml0eSAqLyB8fFxuICAgICAgICBjaGFyID09PSAweDIyMzQgLyogdGhlcmVmb3JlICovIHx8XG4gICAgICAgIGNoYXIgPT09IDB4MjIzNSAvKiBiZWNhdXNlICovIHx8XG4gICAgICAgIChjaGFyID49IDB4MjcwMCAvKiBibGFjayBzYWZldHkgc2Npc3NvcnMgKi8gJiYgY2hhciA8PSAweDI3NjcgLyogcm90YXRlZCBmbG9yYWwgaGVhcnQgYnVsbGV0ICovKSB8fFxuICAgICAgICAoY2hhciA+PSAweDI3NzYgLyogZGluZ2JhdCBuZWdhdGl2ZSBjaXJjbGVkIGRpZ2l0IG9uZSAqLyAmJiBjaGFyIDw9IDB4Mjc5MyAvKiBkaW5nYmF0IG5lZ2F0aXZlIGNpcmNsZWQgc2Fucy1zZXJpZiBudW1iZXIgdGVuICovKSB8fFxuICAgICAgICBjaGFyID09PSAweEZGRkMgLyogb2JqZWN0IHJlcGxhY2VtZW50IGNoYXJhY3RlciAqLyB8fFxuICAgICAgICBjaGFyID09PSAweEZGRkQgLyogcmVwbGFjZW1lbnQgY2hhcmFjdGVyICovKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIFVuaWNvZGUgY29kZXBvaW50IGlkZW50aWZpZXMgYSBjaGFyYWN0ZXIgd2l0aFxuICogcm90YXRlZCBvcmllbnRhdGlvbi5cbiAqXG4gKiBBIGNoYXJhY3RlciBoYXMgcm90YXRlZCBvcmllbnRhdGlvbiBpZiBpdCBpcyBkcmF3biByb3RhdGVkIHdoZW4gdGhlIGxpbmUgaXNcbiAqIG9yaWVudGVkIHZlcnRpY2FsbHksIGV2ZW4gaWYgYm90aCBhZGphY2VudCBjaGFyYWN0ZXJzIGFyZSB1cHJpZ2h0LiBGb3JcbiAqIGV4YW1wbGUsIGEgTGF0aW4gbGV0dGVyIGlzIGRyYXduIHJvdGF0ZWQgYWxvbmcgYSB2ZXJ0aWNhbCBsaW5lLiBBIHJvdGF0ZWRcbiAqIGNoYXJhY3RlciBjYXVzZXMgYW4gYWRqYWNlbnQg4oCcbmV1dHJhbOKAnSBjaGFyYWN0ZXIgdG8gYmUgZHJhd24gcm90YXRlZCBhcyB3ZWxsLlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNoYXJIYXNSb3RhdGVkVmVydGljYWxPcmllbnRhdGlvbihjaGFyOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gIShjaGFySGFzVXByaWdodFZlcnRpY2FsT3JpZW50YXRpb24oY2hhcikgfHxcbiAgICAgICAgICAgICBjaGFySGFzTmV1dHJhbFZlcnRpY2FsT3JpZW50YXRpb24oY2hhcikpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2hhckluQ29tcGxleFNoYXBpbmdTY3JpcHQoY2hhcjogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGlzQ2hhclsnQXJhYmljJ10oY2hhcikgfHxcbiAgICAgICAgICAgaXNDaGFyWydBcmFiaWMgU3VwcGxlbWVudCddKGNoYXIpIHx8XG4gICAgICAgICAgIGlzQ2hhclsnQXJhYmljIEV4dGVuZGVkLUEnXShjaGFyKSB8fFxuICAgICAgICAgICBpc0NoYXJbJ0FyYWJpYyBQcmVzZW50YXRpb24gRm9ybXMtQSddKGNoYXIpIHx8XG4gICAgICAgICAgIGlzQ2hhclsnQXJhYmljIFByZXNlbnRhdGlvbiBGb3Jtcy1CJ10oY2hhcik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjaGFySW5SVExTY3JpcHQoY2hhcjogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgLy8gTWFpbiBibG9ja3MgZm9yIEhlYnJldywgQXJhYmljLCBUaGFhbmEgYW5kIG90aGVyIFJUTCBzY3JpcHRzXG4gICAgcmV0dXJuIChjaGFyID49IDB4MDU5MCAmJiBjaGFyIDw9IDB4MDhGRikgfHxcbiAgICAgICAgaXNDaGFyWydBcmFiaWMgUHJlc2VudGF0aW9uIEZvcm1zLUEnXShjaGFyKSB8fFxuICAgICAgICBpc0NoYXJbJ0FyYWJpYyBQcmVzZW50YXRpb24gRm9ybXMtQiddKGNoYXIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2hhckluU3VwcG9ydGVkU2NyaXB0KGNoYXI6IG51bWJlciwgY2FuUmVuZGVyUlRMOiBib29sZWFuKTogYm9vbGVhbiB7XG4gICAgLy8gVGhpcyBpcyBhIHJvdWdoIGhldXJpc3RpYzogd2hldGhlciB3ZSBcImNhbiByZW5kZXJcIiBhIHNjcmlwdFxuICAgIC8vIGFjdHVhbGx5IGRlcGVuZHMgb24gdGhlIHByb3BlcnRpZXMgb2YgdGhlIGZvbnQgYmVpbmcgdXNlZFxuICAgIC8vIGFuZCB3aGV0aGVyIGRpZmZlcmVuY2VzIGZyb20gdGhlIGlkZWFsIHJlbmRlcmluZyBhcmUgY29uc2lkZXJlZFxuICAgIC8vIHNlbWFudGljYWxseSBzaWduaWZpY2FudC5cblxuICAgIC8vIEV2ZW4gaW4gTGF0aW4gc2NyaXB0LCB3ZSBcImNhbid0IHJlbmRlclwiIGNvbWJpbmF0aW9ucyBzdWNoIGFzIHRoZSBmaVxuICAgIC8vIGxpZ2F0dXJlLCBidXQgd2UgZG9uJ3QgY29uc2lkZXIgdGhhdCBzZW1hbnRpY2FsbHkgc2lnbmlmaWNhbnQuXG4gICAgaWYgKCFjYW5SZW5kZXJSVEwgJiYgY2hhckluUlRMU2NyaXB0KGNoYXIpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKChjaGFyID49IDB4MDkwMCAmJiBjaGFyIDw9IDB4MERGRikgfHxcbiAgICAgICAgLy8gTWFpbiBibG9ja3MgZm9yIEluZGljIHNjcmlwdHMgYW5kIFNpbmhhbGFcbiAgICAgICAgKGNoYXIgPj0gMHgwRjAwICYmIGNoYXIgPD0gMHgxMDlGKSB8fFxuICAgICAgICAvLyBNYWluIGJsb2NrcyBmb3IgVGliZXRhbiBhbmQgTXlhbm1hclxuICAgICAgICBpc0NoYXJbJ0tobWVyJ10oY2hhcikpIHtcbiAgICAgICAgLy8gVGhlc2UgYmxvY2tzIGNvdmVyIGNvbW1vbiBzY3JpcHRzIHRoYXQgcmVxdWlyZVxuICAgICAgICAvLyBjb21wbGV4IHRleHQgc2hhcGluZywgYmFzZWQgb24gdW5pY29kZSBzY3JpcHQgbWV0YWRhdGE6XG4gICAgICAgIC8vIGh0dHA6Ly93d3cudW5pY29kZS5vcmcvcmVwb3MvY2xkci90cnVuay9jb21tb24vcHJvcGVydGllcy9zY3JpcHRNZXRhZGF0YS50eHRcbiAgICAgICAgLy8gd2hlcmUgXCJXZWIgUmFuayA8PSAzMlwiIFwiU2hhcGluZyBSZXF1aXJlZCA9IFlFU1wiXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzdHJpbmdDb250YWluc1JUTFRleHQoY2hhcnM6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGZvciAoY29uc3QgY2hhciBvZiBjaGFycykge1xuICAgICAgICBpZiAoY2hhckluUlRMU2NyaXB0KGNoYXIuY2hhckNvZGVBdCgwKSkpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzU3RyaW5nSW5TdXBwb3J0ZWRTY3JpcHQoY2hhcnM6IHN0cmluZywgY2FuUmVuZGVyUlRMOiBib29sZWFuKTogYm9vbGVhbiB7XG4gICAgZm9yIChjb25zdCBjaGFyIG9mIGNoYXJzKSB7XG4gICAgICAgIGlmICghY2hhckluU3VwcG9ydGVkU2NyaXB0KGNoYXIuY2hhckNvZGVBdCgwKSwgY2FuUmVuZGVyUlRMKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtFdmVudCwgRXZlbnRlZH0gZnJvbSAnLi4vdXRpbC9ldmVudGVkLmpzJztcbmltcG9ydCB7Z2V0QXJyYXlCdWZmZXJ9IGZyb20gJy4uL3V0aWwvYWpheC5qcyc7XG5pbXBvcnQgYnJvd3NlciBmcm9tICcuLi91dGlsL2Jyb3dzZXIuanMnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHtpc1dvcmtlcn0gZnJvbSAnLi4vdXRpbC91dGlsLmpzJztcbmltcG9ydCB0eXBlIHtDYWxsYmFja30gZnJvbSAnLi4vdHlwZXMvY2FsbGJhY2suanMnO1xuXG5jb25zdCBzdGF0dXMgPSB7XG4gICAgdW5hdmFpbGFibGU6ICd1bmF2YWlsYWJsZScsIC8vIE5vdCBsb2FkZWRcbiAgICBkZWZlcnJlZDogJ2RlZmVycmVkJywgLy8gVGhlIHBsdWdpbiBVUkwgaGFzIGJlZW4gc3BlY2lmaWVkLCBidXQgbG9hZGluZyBoYXMgYmVlbiBkZWZlcnJlZFxuICAgIGxvYWRpbmc6ICdsb2FkaW5nJywgLy8gcmVxdWVzdCBpbi1mbGlnaHRcbiAgICBsb2FkZWQ6ICdsb2FkZWQnLFxuICAgIGVycm9yOiAnZXJyb3InXG59O1xuXG5leHBvcnQgdHlwZSBQbHVnaW5TdGF0ZSA9IHtcbiAgICBwbHVnaW5TdGF0dXM6ICRWYWx1ZXM8dHlwZW9mIHN0YXR1cz47XG4gICAgcGx1Z2luVVJMOiA/c3RyaW5nXG59O1xuXG50eXBlIFBsdWdpblN0YXRlU3luY0NhbGxiYWNrID0gKHN0YXRlOiBQbHVnaW5TdGF0ZSkgPT4gdm9pZDtcbmxldCBfY29tcGxldGlvbkNhbGxiYWNrID0gbnVsbDtcblxuLy9WYXJpYWJsZXMgZGVmaW5pbmcgdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIHBsdWdpblxubGV0IHBsdWdpblN0YXR1cyA9IHN0YXR1cy51bmF2YWlsYWJsZTtcbmxldCBwbHVnaW5VUkw6ID9zdHJpbmcgPSBudWxsO1xuXG5leHBvcnQgY29uc3QgdHJpZ2dlclBsdWdpbkNvbXBsZXRpb25FdmVudCA9IGZ1bmN0aW9uKGVycm9yOiA/RXJyb3IpIHtcbiAgICAvLyBOZXR3b3JrRXJyb3IncyBhcmUgbm90IGNvcnJlY3RseSByZWZsZWN0ZWQgYnkgdGhlIHBsdWdpbiBzdGF0dXMgd2hpY2ggcHJldmVudHMgcmVsb2FkaW5nIHBsdWdpblxuICAgIGlmIChlcnJvciAmJiB0eXBlb2YgZXJyb3IgPT09ICdzdHJpbmcnICYmIGVycm9yLmluZGV4T2YoJ05ldHdvcmtFcnJvcicpID4gLTEpIHtcbiAgICAgICAgcGx1Z2luU3RhdHVzID0gc3RhdHVzLmVycm9yO1xuICAgIH1cblxuICAgIGlmIChfY29tcGxldGlvbkNhbGxiYWNrKSB7XG4gICAgICAgIF9jb21wbGV0aW9uQ2FsbGJhY2soZXJyb3IpO1xuICAgIH1cbn07XG5cbmZ1bmN0aW9uIHNlbmRQbHVnaW5TdGF0ZVRvV29ya2VyKCkge1xuICAgIGV2ZW50ZWQuZmlyZShuZXcgRXZlbnQoJ3BsdWdpblN0YXRlQ2hhbmdlJywge3BsdWdpblN0YXR1cywgcGx1Z2luVVJMfSkpO1xufVxuXG5leHBvcnQgY29uc3QgZXZlbnRlZDogRXZlbnRlZCA9IG5ldyBFdmVudGVkKCk7XG5cbmV4cG9ydCBjb25zdCBnZXRSVExUZXh0UGx1Z2luU3RhdHVzID0gZnVuY3Rpb24gKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHBsdWdpblN0YXR1cztcbn07XG5cbmV4cG9ydCBjb25zdCByZWdpc3RlckZvclBsdWdpblN0YXRlQ2hhbmdlID0gZnVuY3Rpb24oY2FsbGJhY2s6IFBsdWdpblN0YXRlU3luY0NhbGxiYWNrKTogUGx1Z2luU3RhdGVTeW5jQ2FsbGJhY2sge1xuICAgIC8vIERvIGFuIGluaXRpYWwgc3luYyBvZiB0aGUgc3RhdGVcbiAgICBjYWxsYmFjayh7cGx1Z2luU3RhdHVzLCBwbHVnaW5VUkx9KTtcbiAgICAvLyBMaXN0ZW4gZm9yIGFsbCBmdXR1cmUgc3RhdGUgY2hhbmdlc1xuICAgIGV2ZW50ZWQub24oJ3BsdWdpblN0YXRlQ2hhbmdlJywgY2FsbGJhY2spO1xuICAgIHJldHVybiBjYWxsYmFjaztcbn07XG5cbmV4cG9ydCBjb25zdCBjbGVhclJUTFRleHRQbHVnaW4gPSBmdW5jdGlvbigpIHtcbiAgICBwbHVnaW5TdGF0dXMgPSBzdGF0dXMudW5hdmFpbGFibGU7XG4gICAgcGx1Z2luVVJMID0gbnVsbDtcbn07XG5cbmV4cG9ydCBjb25zdCBzZXRSVExUZXh0UGx1Z2luID0gZnVuY3Rpb24odXJsOiBzdHJpbmcsIGNhbGxiYWNrOiA/Q2FsbGJhY2s8e2VycjogP0Vycm9yfT4sIGRlZmVycmVkOiBib29sZWFuID0gZmFsc2UpIHtcbiAgICBpZiAocGx1Z2luU3RhdHVzID09PSBzdGF0dXMuZGVmZXJyZWQgfHwgcGx1Z2luU3RhdHVzID09PSBzdGF0dXMubG9hZGluZyB8fCBwbHVnaW5TdGF0dXMgPT09IHN0YXR1cy5sb2FkZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdzZXRSVExUZXh0UGx1Z2luIGNhbm5vdCBiZSBjYWxsZWQgbXVsdGlwbGUgdGltZXMuJyk7XG4gICAgfVxuICAgIHBsdWdpblVSTCA9IGJyb3dzZXIucmVzb2x2ZVVSTCh1cmwpO1xuICAgIHBsdWdpblN0YXR1cyA9IHN0YXR1cy5kZWZlcnJlZDtcbiAgICBfY29tcGxldGlvbkNhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgc2VuZFBsdWdpblN0YXRlVG9Xb3JrZXIoKTtcblxuICAgIC8vU3RhcnQgZG93bmxvYWRpbmcgdGhlIHBsdWdpbiBpbW1lZGlhdGVseSBpZiBub3QgaW50ZW5kaW5nIHRvIGxhenktbG9hZFxuICAgIGlmICghZGVmZXJyZWQpIHtcbiAgICAgICAgZG93bmxvYWRSVExUZXh0UGx1Z2luKCk7XG4gICAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGRvd25sb2FkUlRMVGV4dFBsdWdpbiA9IGZ1bmN0aW9uKCkge1xuICAgIGlmIChwbHVnaW5TdGF0dXMgIT09IHN0YXR1cy5kZWZlcnJlZCB8fCAhcGx1Z2luVVJMKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigncnRsLXRleHQtcGx1Z2luIGNhbm5vdCBiZSBkb3dubG9hZGVkIHVubGVzcyBhIHBsdWdpblVSTCBpcyBzcGVjaWZpZWQnKTtcbiAgICB9XG4gICAgcGx1Z2luU3RhdHVzID0gc3RhdHVzLmxvYWRpbmc7XG4gICAgc2VuZFBsdWdpblN0YXRlVG9Xb3JrZXIoKTtcbiAgICBpZiAocGx1Z2luVVJMKSB7XG4gICAgICAgIGdldEFycmF5QnVmZmVyKHt1cmw6IHBsdWdpblVSTH0sIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgdHJpZ2dlclBsdWdpbkNvbXBsZXRpb25FdmVudChlcnJvcik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHBsdWdpblN0YXR1cyA9IHN0YXR1cy5sb2FkZWQ7XG4gICAgICAgICAgICAgICAgc2VuZFBsdWdpblN0YXRlVG9Xb3JrZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHBsdWdpbjoge1xuICAgIGFwcGx5QXJhYmljU2hhcGluZzogP0Z1bmN0aW9uLFxuICAgIHByb2Nlc3NCaWRpcmVjdGlvbmFsVGV4dDogPyhzdHJpbmcsIEFycmF5PG51bWJlcj4pID0+IEFycmF5PHN0cmluZz4sXG4gICAgcHJvY2Vzc1N0eWxlZEJpZGlyZWN0aW9uYWxUZXh0OiA/KHN0cmluZywgQXJyYXk8bnVtYmVyPiwgQXJyYXk8bnVtYmVyPikgPT4gQXJyYXk8W3N0cmluZywgQXJyYXk8bnVtYmVyPl0+LFxuICAgIGlzTG9hZGVkOiAoKSA9PiBib29sZWFuLFxuICAgIGlzTG9hZGluZzogKCkgPT4gYm9vbGVhbixcbiAgICBzZXRTdGF0ZTogKHN0YXRlOiBQbHVnaW5TdGF0ZSkgPT4gdm9pZCxcbiAgICBpc1BhcnNlZDogKCkgPT4gYm9vbGVhbixcbiAgICBnZXRQbHVnaW5VUkw6ICgpID0+ID9zdHJpbmdcbn0gPSB7XG4gICAgYXBwbHlBcmFiaWNTaGFwaW5nOiBudWxsLFxuICAgIHByb2Nlc3NCaWRpcmVjdGlvbmFsVGV4dDogbnVsbCxcbiAgICBwcm9jZXNzU3R5bGVkQmlkaXJlY3Rpb25hbFRleHQ6IG51bGwsXG4gICAgaXNMb2FkZWQoKSB7XG4gICAgICAgIHJldHVybiBwbHVnaW5TdGF0dXMgPT09IHN0YXR1cy5sb2FkZWQgfHwgLy8gTWFpbiBUaHJlYWQ6IGxvYWRlZCBpZiB0aGUgY29tcGxldGlvbiBjYWxsYmFjayByZXR1cm5lZCBzdWNjZXNzZnVsbHlcbiAgICAgICAgICAgIHBsdWdpbi5hcHBseUFyYWJpY1NoYXBpbmcgIT0gbnVsbDsgLy8gV2ViLXdvcmtlcjogbG9hZGVkIGlmIHRoZSBwbHVnaW4gZnVuY3Rpb25zIGhhdmUgYmVlbiBjb21waWxlZFxuICAgIH0sXG4gICAgaXNMb2FkaW5nKCkgeyAvLyBNYWluIFRocmVhZCBPbmx5OiBxdWVyeSB0aGUgbG9hZGluZyBzdGF0dXMsIHRoaXMgZnVuY3Rpb24gZG9lcyBub3QgcmV0dXJuIHRoZSBjb3JyZWN0IHZhbHVlIGluIHRoZSB3b3JrZXIgY29udGV4dC5cbiAgICAgICAgcmV0dXJuIHBsdWdpblN0YXR1cyA9PT0gc3RhdHVzLmxvYWRpbmc7XG4gICAgfSxcbiAgICBzZXRTdGF0ZShzdGF0ZTogUGx1Z2luU3RhdGUpIHsgLy8gV29ya2VyIHRocmVhZCBvbmx5OiB0aGlzIHRlbGxzIHRoZSB3b3JrZXIgdGhyZWFkcyB0aGF0IHRoZSBwbHVnaW4gaXMgYXZhaWxhYmxlIG9uIHRoZSBNYWluIHRocmVhZFxuICAgICAgICBhc3NlcnQoaXNXb3JrZXIoKSwgJ0Nhbm5vdCBzZXQgdGhlIHN0YXRlIG9mIHRoZSBydGwtdGV4dC1wbHVnaW4gd2hlbiBub3QgaW4gdGhlIHdlYi13b3JrZXIgY29udGV4dCcpO1xuXG4gICAgICAgIHBsdWdpblN0YXR1cyA9IHN0YXRlLnBsdWdpblN0YXR1cztcbiAgICAgICAgcGx1Z2luVVJMID0gc3RhdGUucGx1Z2luVVJMO1xuICAgIH0sXG4gICAgaXNQYXJzZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIGFzc2VydChpc1dvcmtlcigpLCAncnRsLXRleHQtcGx1Z2luIGlzIG9ubHkgcGFyc2VkIG9uIHRoZSB3b3JrZXItdGhyZWFkcycpO1xuXG4gICAgICAgIHJldHVybiBwbHVnaW4uYXBwbHlBcmFiaWNTaGFwaW5nICE9IG51bGwgJiZcbiAgICAgICAgICAgIHBsdWdpbi5wcm9jZXNzQmlkaXJlY3Rpb25hbFRleHQgIT0gbnVsbCAmJlxuICAgICAgICAgICAgcGx1Z2luLnByb2Nlc3NTdHlsZWRCaWRpcmVjdGlvbmFsVGV4dCAhPSBudWxsO1xuICAgIH0sXG4gICAgZ2V0UGx1Z2luVVJMKCk6ID9zdHJpbmcge1xuICAgICAgICBhc3NlcnQoaXNXb3JrZXIoKSwgJ3J0bC10ZXh0LXBsdWdpbiB1cmwgY2FuIG9ubHkgYmUgcXVlcmllZCBmcm9tIHRoZSB3b3JrZXIgdGhyZWFkcycpO1xuICAgICAgICByZXR1cm4gcGx1Z2luVVJMO1xuICAgIH1cbn07XG5cbmV4cG9ydCBjb25zdCBsYXp5TG9hZFJUTFRleHRQbHVnaW4gPSBmdW5jdGlvbigpIHtcbiAgICBpZiAoIXBsdWdpbi5pc0xvYWRpbmcoKSAmJlxuICAgICAgICAhcGx1Z2luLmlzTG9hZGVkKCkgJiZcbiAgICAgICAgZ2V0UlRMVGV4dFBsdWdpblN0YXR1cygpID09PSAnZGVmZXJyZWQnXG4gICAgKSB7XG4gICAgICAgIGRvd25sb2FkUlRMVGV4dFBsdWdpbigpO1xuICAgIH1cbn07XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge2lzU3RyaW5nSW5TdXBwb3J0ZWRTY3JpcHR9IGZyb20gJy4uL3V0aWwvc2NyaXB0X2RldGVjdGlvbi5qcyc7XG5pbXBvcnQge3BsdWdpbiBhcyBydGxUZXh0UGx1Z2lufSBmcm9tICcuLi9zb3VyY2UvcnRsX3RleHRfcGx1Z2luLmpzJztcblxuaW1wb3J0IHR5cGUge1RyYW5zaXRpb25TcGVjaWZpY2F0aW9ufSBmcm9tICcuLi9zdHlsZS1zcGVjL3R5cGVzLmpzJztcblxuY2xhc3MgRXZhbHVhdGlvblBhcmFtZXRlcnMge1xuICAgIHpvb206IG51bWJlcjtcbiAgICBwaXRjaDogbnVtYmVyO1xuICAgIG5vdzogbnVtYmVyO1xuICAgIGZhZGVEdXJhdGlvbjogbnVtYmVyO1xuICAgIHRyYW5zaXRpb246IFRyYW5zaXRpb25TcGVjaWZpY2F0aW9uO1xuXG4gICAgLy8gXCJvcHRpb25zXCIgbWF5IGFsc28gYmUgYW5vdGhlciBFdmFsdWF0aW9uUGFyYW1ldGVycyB0byBjb3B5XG4gICAgY29uc3RydWN0b3Ioem9vbTogbnVtYmVyLCBvcHRpb25zPzogYW55KSB7XG4gICAgICAgIHRoaXMuem9vbSA9IHpvb207XG5cbiAgICAgICAgaWYgKG9wdGlvbnMpIHtcbiAgICAgICAgICAgIHRoaXMubm93ID0gb3B0aW9ucy5ub3c7XG4gICAgICAgICAgICB0aGlzLmZhZGVEdXJhdGlvbiA9IG9wdGlvbnMuZmFkZUR1cmF0aW9uO1xuICAgICAgICAgICAgdGhpcy50cmFuc2l0aW9uID0gb3B0aW9ucy50cmFuc2l0aW9uO1xuICAgICAgICAgICAgdGhpcy5waXRjaCA9IG9wdGlvbnMucGl0Y2g7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLm5vdyA9IDA7XG4gICAgICAgICAgICB0aGlzLmZhZGVEdXJhdGlvbiA9IDA7XG4gICAgICAgICAgICB0aGlzLnRyYW5zaXRpb24gPSB7fTtcbiAgICAgICAgICAgIHRoaXMucGl0Y2ggPSAwO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaXNTdXBwb3J0ZWRTY3JpcHQoc3RyOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIGlzU3RyaW5nSW5TdXBwb3J0ZWRTY3JpcHQoc3RyLCBydGxUZXh0UGx1Z2luLmlzTG9hZGVkKCkpO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgRXZhbHVhdGlvblBhcmFtZXRlcnM7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQge2Nsb25lLCBleHRlbmQsIGVhc2VDdWJpY0luT3V0fSBmcm9tICcuLi91dGlsL3V0aWwuanMnO1xuaW1wb3J0ICogYXMgaW50ZXJwb2xhdGUgZnJvbSAnLi4vc3R5bGUtc3BlYy91dGlsL2ludGVycG9sYXRlLmpzJztcbmltcG9ydCB7bm9ybWFsaXplUHJvcGVydHlFeHByZXNzaW9ufSBmcm9tICcuLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vaW5kZXguanMnO1xuaW1wb3J0IENvbG9yIGZyb20gJy4uL3N0eWxlLXNwZWMvdXRpbC9jb2xvci5qcyc7XG5pbXBvcnQge3JlZ2lzdGVyfSBmcm9tICcuLi91dGlsL3dlYl93b3JrZXJfdHJhbnNmZXIuanMnO1xuaW1wb3J0IEV2YWx1YXRpb25QYXJhbWV0ZXJzIGZyb20gJy4vZXZhbHVhdGlvbl9wYXJhbWV0ZXJzLmpzJztcblxuaW1wb3J0IHR5cGUge0Nhbm9uaWNhbFRpbGVJRH0gZnJvbSAnLi4vc291cmNlL3RpbGVfaWQuanMnO1xuaW1wb3J0IHR5cGUge1N0eWxlUHJvcGVydHlTcGVjaWZpY2F0aW9ufSBmcm9tICcuLi9zdHlsZS1zcGVjL3N0eWxlLXNwZWMuanMnO1xuaW1wb3J0IHR5cGUge1xuICAgIFRyYW5zaXRpb25TcGVjaWZpY2F0aW9uLFxuICAgIFByb3BlcnR5VmFsdWVTcGVjaWZpY2F0aW9uXG59IGZyb20gJy4uL3N0eWxlLXNwZWMvdHlwZXMuanMnO1xuXG5pbXBvcnQgdHlwZSB7XG4gICAgRmVhdHVyZSxcbiAgICBGZWF0dXJlU3RhdGUsXG4gICAgU3R5bGVQcm9wZXJ0eUV4cHJlc3Npb24sXG4gICAgU291cmNlRXhwcmVzc2lvbixcbiAgICBDb21wb3NpdGVFeHByZXNzaW9uXG59IGZyb20gJy4uL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi9pbmRleC5qcyc7XG5cbnR5cGUgVGltZVBvaW50ID0gbnVtYmVyO1xuXG4vKipcbiAqIEltcGxlbWVudHMgYSBudW1iZXIgb2YgY2xhc3NlcyB0aGF0IGRlZmluZSBzdGF0ZSBhbmQgYmVoYXZpb3IgZm9yIHBhaW50IGFuZCBsYXlvdXQgcHJvcGVydGllcywgbW9zdFxuICogaW1wb3J0YW50bHkgdGhlaXIgcmVzcGVjdGl2ZSBldmFsdWF0aW9uIGNoYWluczpcbiAqXG4gKiAgICAgICBUcmFuc2l0aW9uYWJsZSBwYWludCBwcm9wZXJ0eSB2YWx1ZVxuICogICAgIOKGkiBUcmFuc2l0aW9uaW5nIHBhaW50IHByb3BlcnR5IHZhbHVlXG4gKiAgICAg4oaSIFBvc3NpYmx5IGV2YWx1YXRlZCBwYWludCBwcm9wZXJ0eSB2YWx1ZVxuICogICAgIOKGkiBGdWxseSBldmFsdWF0ZWQgcGFpbnQgcHJvcGVydHkgdmFsdWVcbiAqXG4gKiAgICAgICBMYXlvdXQgcHJvcGVydHkgdmFsdWVcbiAqICAgICDihpIgUG9zc2libHkgZXZhbHVhdGVkIGxheW91dCBwcm9wZXJ0eSB2YWx1ZVxuICogICAgIOKGkiBGdWxseSBldmFsdWF0ZWQgbGF5b3V0IHByb3BlcnR5IHZhbHVlXG4gKlxuICogQG1vZHVsZVxuICogQHByaXZhdGVcbiAqL1xuXG4vKipcbiAqICBJbXBsZW1lbnRhdGlvbnMgb2YgdGhlIGBQcm9wZXJ0eWAgaW50ZXJmYWNlOlxuICpcbiAqICAqIEhvbGQgbWV0YWRhdGEgYWJvdXQgYSBwcm9wZXJ0eSB0aGF0J3MgaW5kZXBlbmRlbnQgb2YgYW55IHNwZWNpZmljIHZhbHVlOiBzdHVmZiBsaWtlIHRoZSB0eXBlIG9mIHRoZSB2YWx1ZSxcbiAqICAgIHRoZSBkZWZhdWx0IHZhbHVlLCBldGMuIFRoaXMgY29tZXMgZnJvbSB0aGUgc3R5bGUgc3BlY2lmaWNhdGlvbiBKU09OLlxuICogICogRGVmaW5lIGJlaGF2aW9yIHRoYXQgbmVlZHMgdG8gYmUgcG9seW1vcnBoaWMgYWNyb3NzIGRpZmZlcmVudCBwcm9wZXJ0aWVzOiBcInBvc3NpYmx5IGV2YWx1YXRpbmdcIlxuICogICAgYW4gaW5wdXQgdmFsdWUgKHNlZSBiZWxvdyksIGFuZCBpbnRlcnBvbGF0aW5nIGJldHdlZW4gdHdvIHBvc3NpYmx5LWV2YWx1dGVkIHZhbHVlcy5cbiAqXG4gKiAgVGhlIHR5cGUgYFRgIGlzIHRoZSBmdWxseS1ldmFsdWF0ZWQgdmFsdWUgdHlwZSAoZS5nLiBgbnVtYmVyYCwgYHN0cmluZ2AsIGBDb2xvcmApLlxuICogIFRoZSB0eXBlIGBSYCBpcyB0aGUgaW50ZXJtZWRpYXRlIFwicG9zc2libHkgZXZhbHVhdGVkXCIgdmFsdWUgdHlwZS4gU2VlIGJlbG93LlxuICpcbiAqICBUaGVyZSBhcmUgdHdvIG1haW4gaW1wbGVtZW50YXRpb25zIG9mIHRoZSBpbnRlcmZhY2UgLS0gb25lIGZvciBwcm9wZXJ0aWVzIHRoYXQgYWxsb3cgZGF0YS1kcml2ZW4gdmFsdWVzLFxuICogIGFuZCBvbmUgZm9yIHByb3BlcnRpZXMgdGhhdCBkb24ndC4gVGhlcmUgYXJlIGEgZmV3IFwic3BlY2lhbCBjYXNlXCIgaW1wbGVtZW50YXRpb25zIGFzIHdlbGw6XG4gKiAgb25lIGZvciBgaGVhdG1hcC1jb2xvcmAgYW5kIGBsaW5lLWdyYWRpZW50YCwgYW5kIG9uZSBmb3IgYGxpZ2h0LXBvc2l0aW9uYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIFByb3BlcnR5PFQsIFI+IHtcbiAgICBzcGVjaWZpY2F0aW9uOiBTdHlsZVByb3BlcnR5U3BlY2lmaWNhdGlvbjtcbiAgICBwb3NzaWJseUV2YWx1YXRlKHZhbHVlOiBQcm9wZXJ0eVZhbHVlPFQsIFI+LCBwYXJhbWV0ZXJzOiBFdmFsdWF0aW9uUGFyYW1ldGVycywgY2Fub25pY2FsPzogQ2Fub25pY2FsVGlsZUlELCBhdmFpbGFibGVJbWFnZXM/OiBBcnJheTxzdHJpbmc+KTogUjtcbiAgICBpbnRlcnBvbGF0ZShhOiBSLCBiOiBSLCB0OiBudW1iZXIpOiBSO1xufVxuXG4vKipcbiAqICBgUHJvcGVydHlWYWx1ZWAgcmVwcmVzZW50cyB0aGUgdmFsdWUgcGFydCBvZiBhIHByb3BlcnR5IGtleS12YWx1ZSB1bml0LiBJdCdzIHVzZWQgdG8gcmVwcmVzZW50IGJvdGhcbiAqICBwYWludCBhbmQgbGF5b3V0IHByb3BlcnR5IHZhbHVlcywgYW5kIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciBvciBub3QgdGhlaXIgcHJvcGVydHkgc3VwcG9ydHMgZGF0YS1kcml2ZW5cbiAqICBleHByZXNzaW9ucy5cbiAqXG4gKiAgYFByb3BlcnR5VmFsdWVgIHN0b3JlcyB0aGUgcmF3IGlucHV0IHZhbHVlIGFzIHNlZW4gaW4gYSBzdHlsZSBvciBhIHJ1bnRpbWUgc3R5bGluZyBBUEkgY2FsbCwgaS5lLiBvbmUgb2YgdGhlXG4gKiAgZm9sbG93aW5nOlxuICpcbiAqICAgICogQSBjb25zdGFudCB2YWx1ZSBvZiB0aGUgdHlwZSBhcHByb3ByaWF0ZSBmb3IgdGhlIHByb3BlcnR5XG4gKiAgICAqIEEgZnVuY3Rpb24gd2hpY2ggcHJvZHVjZXMgYSB2YWx1ZSBvZiB0aGF0IHR5cGUgKGJ1dCBmdW5jdGlvbnMgYXJlIHF1YXNpLWRlcHJlY2F0ZWQgaW4gZmF2b3Igb2YgZXhwcmVzc2lvbnMpXG4gKiAgICAqIEFuIGV4cHJlc3Npb24gd2hpY2ggcHJvZHVjZXMgYSB2YWx1ZSBvZiB0aGF0IHR5cGVcbiAqICAgICogXCJ1bmRlZmluZWRcIi9cIm5vdCBwcmVzZW50XCIsIGluIHdoaWNoIGNhc2UgdGhlIHByb3BlcnR5IGlzIGFzc3VtZWQgdG8gdGFrZSBvbiBpdHMgZGVmYXVsdCB2YWx1ZS5cbiAqXG4gKiAgSW4gYWRkaXRpb24gdG8gc3RvcmluZyB0aGUgb3JpZ2luYWwgaW5wdXQgdmFsdWUsIGBQcm9wZXJ0eVZhbHVlYCBhbHNvIHN0b3JlcyBhIG5vcm1hbGl6ZWQgcmVwcmVzZW50YXRpb24sXG4gKiAgZWZmZWN0aXZlbHkgdHJlYXRpbmcgZnVuY3Rpb25zIGFzIGlmIHRoZXkgYXJlIGV4cHJlc3Npb25zLCBhbmQgY29uc3RhbnQgb3IgZGVmYXVsdCB2YWx1ZXMgYXMgaWYgdGhleSBhcmVcbiAqICAoY29uc3RhbnQpIGV4cHJlc3Npb25zLlxuICpcbiAqICBAcHJpdmF0ZVxuICovXG5leHBvcnQgY2xhc3MgUHJvcGVydHlWYWx1ZTxULCBSPiB7XG4gICAgcHJvcGVydHk6IFByb3BlcnR5PFQsIFI+O1xuICAgIHZhbHVlOiBQcm9wZXJ0eVZhbHVlU3BlY2lmaWNhdGlvbjxUPiB8IHZvaWQ7XG4gICAgZXhwcmVzc2lvbjogU3R5bGVQcm9wZXJ0eUV4cHJlc3Npb247XG5cbiAgICBjb25zdHJ1Y3Rvcihwcm9wZXJ0eTogUHJvcGVydHk8VCwgUj4sIHZhbHVlOiBQcm9wZXJ0eVZhbHVlU3BlY2lmaWNhdGlvbjxUPiB8IHZvaWQpIHtcbiAgICAgICAgdGhpcy5wcm9wZXJ0eSA9IHByb3BlcnR5O1xuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgICAgIHRoaXMuZXhwcmVzc2lvbiA9IG5vcm1hbGl6ZVByb3BlcnR5RXhwcmVzc2lvbih2YWx1ZSA9PT0gdW5kZWZpbmVkID8gcHJvcGVydHkuc3BlY2lmaWNhdGlvbi5kZWZhdWx0IDogdmFsdWUsIHByb3BlcnR5LnNwZWNpZmljYXRpb24pO1xuICAgIH1cblxuICAgIGlzRGF0YURyaXZlbigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZXhwcmVzc2lvbi5raW5kID09PSAnc291cmNlJyB8fCB0aGlzLmV4cHJlc3Npb24ua2luZCA9PT0gJ2NvbXBvc2l0ZSc7XG4gICAgfVxuXG4gICAgcG9zc2libHlFdmFsdWF0ZShwYXJhbWV0ZXJzOiBFdmFsdWF0aW9uUGFyYW1ldGVycywgY2Fub25pY2FsPzogQ2Fub25pY2FsVGlsZUlELCBhdmFpbGFibGVJbWFnZXM/OiBBcnJheTxzdHJpbmc+KTogUiB7XG4gICAgICAgIHJldHVybiB0aGlzLnByb3BlcnR5LnBvc3NpYmx5RXZhbHVhdGUodGhpcywgcGFyYW1ldGVycywgY2Fub25pY2FsLCBhdmFpbGFibGVJbWFnZXMpO1xuICAgIH1cbn1cblxuLy8gLS0tLS0tLSBUcmFuc2l0aW9uYWJsZSAtLS0tLS0tXG5cbmV4cG9ydCB0eXBlIFRyYW5zaXRpb25QYXJhbWV0ZXJzID0gaW50ZXJmYWNlIHtcbiAgICBub3c6IFRpbWVQb2ludCxcbiAgICB0cmFuc2l0aW9uOiBUcmFuc2l0aW9uU3BlY2lmaWNhdGlvbixcbn07XG5cbi8qKlxuICogUGFpbnQgcHJvcGVydGllcyBhcmUgX3RyYW5zaXRpb25hYmxlXzogdGhleSBjYW4gY2hhbmdlIGluIGEgZmx1aWQgbWFubmVyLCBpbnRlcnBvbGF0aW5nIG9yIGNyb3NzLWZhZGluZyBiZXR3ZWVuXG4gKiBvbGQgYW5kIG5ldyB2YWx1ZS4gVGhlIGR1cmF0aW9uIG9mIHRoZSB0cmFuc2l0aW9uLCBhbmQgdGhlIGRlbGF5IGJlZm9yZSBpdCBiZWdpbnMsIGlzIGNvbmZpZ3VyYWJsZS5cbiAqXG4gKiBgVHJhbnNpdGlvbmFibGVQcm9wZXJ0eVZhbHVlYCBpcyBhIGNvbXBvc2l0aW9uYWwgY2xhc3MgdGhhdCBzdG9yZXMgYm90aCB0aGUgcHJvcGVydHkgdmFsdWUgYW5kIHRoYXQgdHJhbnNpdGlvblxuICogY29uZmlndXJhdGlvbi5cbiAqXG4gKiBBIGBUcmFuc2l0aW9uYWJsZVByb3BlcnR5VmFsdWVgIGNhbiBjYWxjdWxhdGUgdGhlIG5leHQgc3RlcCBpbiB0aGUgZXZhbHVhdGlvbiBjaGFpbiBmb3IgcGFpbnQgcHJvcGVydHkgdmFsdWVzOlxuICogYFRyYW5zaXRpb25pbmdQcm9wZXJ0eVZhbHVlYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5jbGFzcyBUcmFuc2l0aW9uYWJsZVByb3BlcnR5VmFsdWU8VCwgUj4ge1xuICAgIHByb3BlcnR5OiBQcm9wZXJ0eTxULCBSPjtcbiAgICB2YWx1ZTogUHJvcGVydHlWYWx1ZTxULCBSPjtcbiAgICB0cmFuc2l0aW9uOiBUcmFuc2l0aW9uU3BlY2lmaWNhdGlvbiB8IHZvaWQ7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcm9wZXJ0eTogUHJvcGVydHk8VCwgUj4pIHtcbiAgICAgICAgdGhpcy5wcm9wZXJ0eSA9IHByb3BlcnR5O1xuICAgICAgICB0aGlzLnZhbHVlID0gbmV3IFByb3BlcnR5VmFsdWUocHJvcGVydHksIHVuZGVmaW5lZCk7XG4gICAgfVxuXG4gICAgdHJhbnNpdGlvbmVkKHBhcmFtZXRlcnM6IFRyYW5zaXRpb25QYXJhbWV0ZXJzLFxuICAgICAgICAgICAgICAgICBwcmlvcjogVHJhbnNpdGlvbmluZ1Byb3BlcnR5VmFsdWU8VCwgUj4pOiBUcmFuc2l0aW9uaW5nUHJvcGVydHlWYWx1ZTxULCBSPiB7XG4gICAgICAgIHJldHVybiBuZXcgVHJhbnNpdGlvbmluZ1Byb3BlcnR5VmFsdWUodGhpcy5wcm9wZXJ0eSwgdGhpcy52YWx1ZSwgcHJpb3IsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdXNlLWJlZm9yZS1kZWZpbmVcbiAgICAgICAgICAgIGV4dGVuZCh7fSwgcGFyYW1ldGVycy50cmFuc2l0aW9uLCB0aGlzLnRyYW5zaXRpb24pLCBwYXJhbWV0ZXJzLm5vdyk7XG4gICAgfVxuXG4gICAgdW50cmFuc2l0aW9uZWQoKTogVHJhbnNpdGlvbmluZ1Byb3BlcnR5VmFsdWU8VCwgUj4ge1xuICAgICAgICByZXR1cm4gbmV3IFRyYW5zaXRpb25pbmdQcm9wZXJ0eVZhbHVlKHRoaXMucHJvcGVydHksIHRoaXMudmFsdWUsIG51bGwsIHt9LCAwKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11c2UtYmVmb3JlLWRlZmluZVxuICAgIH1cbn1cblxuLyoqXG4gKiBBIGhlbHBlciB0eXBlOiBnaXZlbiBhbiBvYmplY3QgdHlwZSBgUHJvcGVydGllc2Agd2hvc2UgdmFsdWVzIGFyZSBlYWNoIG9mIHR5cGUgYFByb3BlcnR5PFQsIFI+YCwgaXQgY2FsY3VsYXRlc1xuICogYW4gb2JqZWN0IHR5cGUgd2l0aCB0aGUgc2FtZSBrZXlzIGFuZCB2YWx1ZXMgb2YgdHlwZSBgVHJhbnNpdGlvbmFibGVQcm9wZXJ0eVZhbHVlPFQsIFI+YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG50eXBlIFRyYW5zaXRpb25hYmxlUHJvcGVydHlWYWx1ZXM8UHJvcHM6IE9iamVjdD5cbiAgICA9ICRFeGFjdDwkT2JqTWFwPFByb3BzLCA8VCwgUj4ocDogUHJvcGVydHk8VCwgUj4pID0+IFRyYW5zaXRpb25hYmxlUHJvcGVydHlWYWx1ZTxULCBSPj4+XG5cbi8qKlxuICogYFRyYW5zaXRpb25hYmxlYCBzdG9yZXMgYSBtYXAgb2YgYWxsIChwcm9wZXJ0eSBuYW1lLCBgVHJhbnNpdGlvbmFibGVQcm9wZXJ0eVZhbHVlYCkgcGFpcnMgZm9yIHBhaW50IHByb3BlcnRpZXMgb2YgYVxuICogZ2l2ZW4gbGF5ZXIgdHlwZS4gSXQgY2FuIGNhbGN1bGF0ZSB0aGUgYFRyYW5zaXRpb25pbmdQcm9wZXJ0eVZhbHVlYHMgZm9yIGFsbCBvZiB0aGVtIGF0IG9uY2UsIHByb2R1Y2luZyBhXG4gKiBgVHJhbnNpdGlvbmluZ2AgaW5zdGFuY2UgZm9yIHRoZSBzYW1lIHNldCBvZiBwcm9wZXJ0aWVzLlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBjbGFzcyBUcmFuc2l0aW9uYWJsZTxQcm9wczogT2JqZWN0PiB7XG4gICAgX3Byb3BlcnRpZXM6IFByb3BlcnRpZXM8UHJvcHM+O1xuICAgIF92YWx1ZXM6IFRyYW5zaXRpb25hYmxlUHJvcGVydHlWYWx1ZXM8UHJvcHM+O1xuXG4gICAgY29uc3RydWN0b3IocHJvcGVydGllczogUHJvcGVydGllczxQcm9wcz4pIHtcbiAgICAgICAgdGhpcy5fcHJvcGVydGllcyA9IHByb3BlcnRpZXM7XG4gICAgICAgIHRoaXMuX3ZhbHVlcyA9IChPYmplY3QuY3JlYXRlKHByb3BlcnRpZXMuZGVmYXVsdFRyYW5zaXRpb25hYmxlUHJvcGVydHlWYWx1ZXMpOiBhbnkpO1xuICAgIH1cblxuICAgIGdldFZhbHVlPFM6IHN0cmluZywgVD4obmFtZTogUyk6IFByb3BlcnR5VmFsdWVTcGVjaWZpY2F0aW9uPFQ+IHwgdm9pZCB7XG4gICAgICAgIHJldHVybiBjbG9uZSh0aGlzLl92YWx1ZXNbbmFtZV0udmFsdWUudmFsdWUpO1xuICAgIH1cblxuICAgIHNldFZhbHVlPFM6IHN0cmluZywgVD4obmFtZTogUywgdmFsdWU6IFByb3BlcnR5VmFsdWVTcGVjaWZpY2F0aW9uPFQ+IHwgdm9pZCkge1xuICAgICAgICBpZiAoIXRoaXMuX3ZhbHVlcy5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xuICAgICAgICAgICAgdGhpcy5fdmFsdWVzW25hbWVdID0gbmV3IFRyYW5zaXRpb25hYmxlUHJvcGVydHlWYWx1ZSh0aGlzLl92YWx1ZXNbbmFtZV0ucHJvcGVydHkpO1xuICAgICAgICB9XG4gICAgICAgIC8vIE5vdGUgdGhhdCB3ZSBkbyBub3QgX3JlbW92ZV8gYW4gb3duIHByb3BlcnR5IGluIHRoZSBjYXNlIHdoZXJlIGEgdmFsdWUgaXMgYmVpbmcgcmVzZXRcbiAgICAgICAgLy8gdG8gdGhlIGRlZmF1bHQ6IHRoZSB0cmFuc2l0aW9uIG1pZ2h0IHN0aWxsIGJlIG5vbi1kZWZhdWx0LlxuICAgICAgICB0aGlzLl92YWx1ZXNbbmFtZV0udmFsdWUgPSBuZXcgUHJvcGVydHlWYWx1ZSh0aGlzLl92YWx1ZXNbbmFtZV0ucHJvcGVydHksIHZhbHVlID09PSBudWxsID8gdW5kZWZpbmVkIDogY2xvbmUodmFsdWUpKTtcbiAgICB9XG5cbiAgICBnZXRUcmFuc2l0aW9uPFM6IHN0cmluZz4obmFtZTogUyk6IFRyYW5zaXRpb25TcGVjaWZpY2F0aW9uIHwgdm9pZCB7XG4gICAgICAgIHJldHVybiBjbG9uZSh0aGlzLl92YWx1ZXNbbmFtZV0udHJhbnNpdGlvbik7XG4gICAgfVxuXG4gICAgc2V0VHJhbnNpdGlvbjxTOiBzdHJpbmc+KG5hbWU6IFMsIHZhbHVlOiBUcmFuc2l0aW9uU3BlY2lmaWNhdGlvbiB8IHZvaWQpIHtcbiAgICAgICAgaWYgKCF0aGlzLl92YWx1ZXMuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICAgICAgICAgIHRoaXMuX3ZhbHVlc1tuYW1lXSA9IG5ldyBUcmFuc2l0aW9uYWJsZVByb3BlcnR5VmFsdWUodGhpcy5fdmFsdWVzW25hbWVdLnByb3BlcnR5KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl92YWx1ZXNbbmFtZV0udHJhbnNpdGlvbiA9IGNsb25lKHZhbHVlKSB8fCB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgc2VyaWFsaXplKCk6IFByb3BlcnR5VmFsdWVTcGVjaWZpY2F0aW9uczxQcm9wcz4ge1xuICAgICAgICBjb25zdCByZXN1bHQ6IE9iamVjdCA9IHt9O1xuICAgICAgICBmb3IgKGNvbnN0IHByb3BlcnR5IG9mIE9iamVjdC5rZXlzKHRoaXMuX3ZhbHVlcykpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5nZXRWYWx1ZShwcm9wZXJ0eSk7XG4gICAgICAgICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJlc3VsdFtwcm9wZXJ0eV0gPSB2YWx1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgdHJhbnNpdGlvbiA9IHRoaXMuZ2V0VHJhbnNpdGlvbihwcm9wZXJ0eSk7XG4gICAgICAgICAgICBpZiAodHJhbnNpdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0W2Ake3Byb3BlcnR5fS10cmFuc2l0aW9uYF0gPSB0cmFuc2l0aW9uO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgdHJhbnNpdGlvbmVkKHBhcmFtZXRlcnM6IFRyYW5zaXRpb25QYXJhbWV0ZXJzLCBwcmlvcjogVHJhbnNpdGlvbmluZzxQcm9wcz4pOiBUcmFuc2l0aW9uaW5nPFByb3BzPiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IG5ldyBUcmFuc2l0aW9uaW5nKHRoaXMuX3Byb3BlcnRpZXMpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVzZS1iZWZvcmUtZGVmaW5lXG4gICAgICAgIGZvciAoY29uc3QgcHJvcGVydHkgb2YgT2JqZWN0LmtleXModGhpcy5fdmFsdWVzKSkge1xuICAgICAgICAgICAgcmVzdWx0Ll92YWx1ZXNbcHJvcGVydHldID0gdGhpcy5fdmFsdWVzW3Byb3BlcnR5XS50cmFuc2l0aW9uZWQocGFyYW1ldGVycywgcHJpb3IuX3ZhbHVlc1twcm9wZXJ0eV0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgdW50cmFuc2l0aW9uZWQoKTogVHJhbnNpdGlvbmluZzxQcm9wcz4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBuZXcgVHJhbnNpdGlvbmluZyh0aGlzLl9wcm9wZXJ0aWVzKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11c2UtYmVmb3JlLWRlZmluZVxuICAgICAgICBmb3IgKGNvbnN0IHByb3BlcnR5IG9mIE9iamVjdC5rZXlzKHRoaXMuX3ZhbHVlcykpIHtcbiAgICAgICAgICAgIHJlc3VsdC5fdmFsdWVzW3Byb3BlcnR5XSA9IHRoaXMuX3ZhbHVlc1twcm9wZXJ0eV0udW50cmFuc2l0aW9uZWQoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbn1cblxuLy8gLS0tLS0tLSBUcmFuc2l0aW9uaW5nIC0tLS0tLS1cblxuLyoqXG4gKiBgVHJhbnNpdGlvbmluZ1Byb3BlcnR5VmFsdWVgIGltcGxlbWVudHMgdGhlIGZpcnN0IG9mIHR3byBpbnRlcm1lZGlhdGUgc3RlcHMgaW4gdGhlIGV2YWx1YXRpb24gY2hhaW4gb2YgYSBwYWludFxuICogcHJvcGVydHkgdmFsdWUuIEluIHRoaXMgc3RlcCwgdHJhbnNpdGlvbnMgYmV0d2VlbiBvbGQgYW5kIG5ldyB2YWx1ZXMgYXJlIGhhbmRsZWQ6IGFzIGxvbmcgYXMgdGhlIHRyYW5zaXRpb24gaXMgaW5cbiAqIHByb2dyZXNzLCBgVHJhbnNpdGlvbmluZ1Byb3BlcnR5VmFsdWVgIG1haW50YWlucyBhIHJlZmVyZW5jZSB0byB0aGUgcHJpb3IgdmFsdWUsIGFuZCBpbnRlcnBvbGF0ZXMgYmV0d2VlbiBpdCBhbmRcbiAqIHRoZSBuZXcgdmFsdWUgYmFzZWQgb24gdGhlIGN1cnJlbnQgdGltZSBhbmQgdGhlIGNvbmZpZ3VyZWQgdHJhbnNpdGlvbiBkdXJhdGlvbiBhbmQgZGVsYXkuIFRoZSBwcm9kdWN0IGlzIHRoZSBuZXh0XG4gKiBzdGVwIGluIHRoZSBldmFsdWF0aW9uIGNoYWluOiB0aGUgXCJwb3NzaWJseSBldmFsdWF0ZWRcIiByZXN1bHQgdHlwZSBgUmAuIFNlZSBiZWxvdyBmb3IgbW9yZSBvbiB0aGlzIGNvbmNlcHQuXG4gKlxuICogQHByaXZhdGVcbiAqL1xuY2xhc3MgVHJhbnNpdGlvbmluZ1Byb3BlcnR5VmFsdWU8VCwgUj4ge1xuICAgIHByb3BlcnR5OiBQcm9wZXJ0eTxULCBSPjtcbiAgICB2YWx1ZTogUHJvcGVydHlWYWx1ZTxULCBSPjtcbiAgICBwcmlvcjogP1RyYW5zaXRpb25pbmdQcm9wZXJ0eVZhbHVlPFQsIFI+O1xuICAgIGJlZ2luOiBUaW1lUG9pbnQ7XG4gICAgZW5kOiBUaW1lUG9pbnQ7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcm9wZXJ0eTogUHJvcGVydHk8VCwgUj4sXG4gICAgICAgICAgICAgICAgdmFsdWU6IFByb3BlcnR5VmFsdWU8VCwgUj4sXG4gICAgICAgICAgICAgICAgcHJpb3I6ID9UcmFuc2l0aW9uaW5nUHJvcGVydHlWYWx1ZTxULCBSPixcbiAgICAgICAgICAgICAgICB0cmFuc2l0aW9uOiBUcmFuc2l0aW9uU3BlY2lmaWNhdGlvbixcbiAgICAgICAgICAgICAgICBub3c6IFRpbWVQb2ludCkge1xuICAgICAgICBjb25zdCBkZWxheSA9IHRyYW5zaXRpb24uZGVsYXkgfHwgMDtcbiAgICAgICAgY29uc3QgZHVyYXRpb24gPSB0cmFuc2l0aW9uLmR1cmF0aW9uIHx8IDA7XG4gICAgICAgIG5vdyA9IG5vdyB8fCAwO1xuICAgICAgICB0aGlzLnByb3BlcnR5ID0gcHJvcGVydHk7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5iZWdpbiA9IG5vdyArIGRlbGF5O1xuICAgICAgICB0aGlzLmVuZCA9IHRoaXMuYmVnaW4gKyBkdXJhdGlvbjtcbiAgICAgICAgaWYgKHByb3BlcnR5LnNwZWNpZmljYXRpb24udHJhbnNpdGlvbiAmJiAodHJhbnNpdGlvbi5kZWxheSB8fCB0cmFuc2l0aW9uLmR1cmF0aW9uKSkge1xuICAgICAgICAgICAgdGhpcy5wcmlvciA9IHByaW9yO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcG9zc2libHlFdmFsdWF0ZShwYXJhbWV0ZXJzOiBFdmFsdWF0aW9uUGFyYW1ldGVycywgY2Fub25pY2FsOiBDYW5vbmljYWxUaWxlSUQsIGF2YWlsYWJsZUltYWdlczogQXJyYXk8c3RyaW5nPik6IFIge1xuICAgICAgICBjb25zdCBub3cgPSBwYXJhbWV0ZXJzLm5vdyB8fCAwO1xuICAgICAgICBjb25zdCBmaW5hbFZhbHVlID0gdGhpcy52YWx1ZS5wb3NzaWJseUV2YWx1YXRlKHBhcmFtZXRlcnMsIGNhbm9uaWNhbCwgYXZhaWxhYmxlSW1hZ2VzKTtcbiAgICAgICAgY29uc3QgcHJpb3IgPSB0aGlzLnByaW9yO1xuICAgICAgICBpZiAoIXByaW9yKSB7XG4gICAgICAgICAgICAvLyBObyBwcmlvciB2YWx1ZS5cbiAgICAgICAgICAgIHJldHVybiBmaW5hbFZhbHVlO1xuICAgICAgICB9IGVsc2UgaWYgKG5vdyA+IHRoaXMuZW5kKSB7XG4gICAgICAgICAgICAvLyBUcmFuc2l0aW9uIGZyb20gcHJpb3IgdmFsdWUgaXMgbm93IGNvbXBsZXRlLlxuICAgICAgICAgICAgdGhpcy5wcmlvciA9IG51bGw7XG4gICAgICAgICAgICByZXR1cm4gZmluYWxWYWx1ZTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnZhbHVlLmlzRGF0YURyaXZlbigpKSB7XG4gICAgICAgICAgICAvLyBUcmFuc2l0aW9ucyB0byBkYXRhLWRyaXZlbiBwcm9wZXJ0aWVzIGFyZSBub3Qgc3VwcG9ydGVkLlxuICAgICAgICAgICAgLy8gV2Ugc25hcCBpbW1lZGlhdGVseSB0byB0aGUgZGF0YS1kcml2ZW4gdmFsdWUgc28gdGhhdCwgd2hlbiB3ZSBwZXJmb3JtIGxheW91dCxcbiAgICAgICAgICAgIC8vIHdlIHNlZSB0aGUgZGF0YS1kcml2ZW4gZnVuY3Rpb24gYW5kIGNhbiB1c2UgaXQgdG8gcG9wdWxhdGUgdmVydGV4IGJ1ZmZlcnMuXG4gICAgICAgICAgICB0aGlzLnByaW9yID0gbnVsbDtcbiAgICAgICAgICAgIHJldHVybiBmaW5hbFZhbHVlO1xuICAgICAgICB9IGVsc2UgaWYgKG5vdyA8IHRoaXMuYmVnaW4pIHtcbiAgICAgICAgICAgIC8vIFRyYW5zaXRpb24gaGFzbid0IHN0YXJ0ZWQgeWV0LlxuICAgICAgICAgICAgcmV0dXJuIHByaW9yLnBvc3NpYmx5RXZhbHVhdGUocGFyYW1ldGVycywgY2Fub25pY2FsLCBhdmFpbGFibGVJbWFnZXMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gSW50ZXJwb2xhdGUgYmV0d2VlbiByZWN1cnNpdmVseS1jYWxjdWxhdGVkIHByaW9yIHZhbHVlIGFuZCBmaW5hbC5cbiAgICAgICAgICAgIGNvbnN0IHQgPSAobm93IC0gdGhpcy5iZWdpbikgLyAodGhpcy5lbmQgLSB0aGlzLmJlZ2luKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnByb3BlcnR5LmludGVycG9sYXRlKHByaW9yLnBvc3NpYmx5RXZhbHVhdGUocGFyYW1ldGVycywgY2Fub25pY2FsLCBhdmFpbGFibGVJbWFnZXMpLCBmaW5hbFZhbHVlLCBlYXNlQ3ViaWNJbk91dCh0KSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKlxuICogQSBoZWxwZXIgdHlwZTogZ2l2ZW4gYW4gb2JqZWN0IHR5cGUgYFByb3BlcnRpZXNgIHdob3NlIHZhbHVlcyBhcmUgZWFjaCBvZiB0eXBlIGBQcm9wZXJ0eTxULCBSPmAsIGl0IGNhbGN1bGF0ZXNcbiAqIGFuIG9iamVjdCB0eXBlIHdpdGggdGhlIHNhbWUga2V5cyBhbmQgdmFsdWVzIG9mIHR5cGUgYFRyYW5zaXRpb25pbmdQcm9wZXJ0eVZhbHVlPFQsIFI+YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG50eXBlIFRyYW5zaXRpb25pbmdQcm9wZXJ0eVZhbHVlczxQcm9wczogT2JqZWN0PlxuICAgID0gJEV4YWN0PCRPYmpNYXA8UHJvcHMsIDxULCBSPihwOiBQcm9wZXJ0eTxULCBSPikgPT4gVHJhbnNpdGlvbmluZ1Byb3BlcnR5VmFsdWU8VCwgUj4+PlxuXG4vKipcbiAqIGBUcmFuc2l0aW9uaW5nYCBzdG9yZXMgYSBtYXAgb2YgYWxsIChwcm9wZXJ0eSBuYW1lLCBgVHJhbnNpdGlvbmluZ1Byb3BlcnR5VmFsdWVgKSBwYWlycyBmb3IgcGFpbnQgcHJvcGVydGllcyBvZiBhXG4gKiBnaXZlbiBsYXllciB0eXBlLiBJdCBjYW4gY2FsY3VsYXRlIHRoZSBwb3NzaWJseS1ldmFsdWF0ZWQgdmFsdWVzIGZvciBhbGwgb2YgdGhlbSBhdCBvbmNlLCBwcm9kdWNpbmcgYVxuICogYFBvc3NpYmx5RXZhbHVhdGVkYCBpbnN0YW5jZSBmb3IgdGhlIHNhbWUgc2V0IG9mIHByb3BlcnRpZXMuXG4gKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGNsYXNzIFRyYW5zaXRpb25pbmc8UHJvcHM6IE9iamVjdD4ge1xuICAgIF9wcm9wZXJ0aWVzOiBQcm9wZXJ0aWVzPFByb3BzPjtcbiAgICBfdmFsdWVzOiBUcmFuc2l0aW9uaW5nUHJvcGVydHlWYWx1ZXM8UHJvcHM+O1xuXG4gICAgY29uc3RydWN0b3IocHJvcGVydGllczogUHJvcGVydGllczxQcm9wcz4pIHtcbiAgICAgICAgdGhpcy5fcHJvcGVydGllcyA9IHByb3BlcnRpZXM7XG4gICAgICAgIHRoaXMuX3ZhbHVlcyA9IChPYmplY3QuY3JlYXRlKHByb3BlcnRpZXMuZGVmYXVsdFRyYW5zaXRpb25pbmdQcm9wZXJ0eVZhbHVlcyk6IGFueSk7XG4gICAgfVxuXG4gICAgcG9zc2libHlFdmFsdWF0ZShwYXJhbWV0ZXJzOiBFdmFsdWF0aW9uUGFyYW1ldGVycywgY2Fub25pY2FsPzogQ2Fub25pY2FsVGlsZUlELCBhdmFpbGFibGVJbWFnZXM/OiBBcnJheTxzdHJpbmc+KTogUG9zc2libHlFdmFsdWF0ZWQ8UHJvcHM+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gbmV3IFBvc3NpYmx5RXZhbHVhdGVkKHRoaXMuX3Byb3BlcnRpZXMpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVzZS1iZWZvcmUtZGVmaW5lXG4gICAgICAgIGZvciAoY29uc3QgcHJvcGVydHkgb2YgT2JqZWN0LmtleXModGhpcy5fdmFsdWVzKSkge1xuICAgICAgICAgICAgcmVzdWx0Ll92YWx1ZXNbcHJvcGVydHldID0gdGhpcy5fdmFsdWVzW3Byb3BlcnR5XS5wb3NzaWJseUV2YWx1YXRlKHBhcmFtZXRlcnMsIGNhbm9uaWNhbCwgYXZhaWxhYmxlSW1hZ2VzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIGhhc1RyYW5zaXRpb24oKTogYm9vbGVhbiB7XG4gICAgICAgIGZvciAoY29uc3QgcHJvcGVydHkgb2YgT2JqZWN0LmtleXModGhpcy5fdmFsdWVzKSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3ZhbHVlc1twcm9wZXJ0eV0ucHJpb3IpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuXG4vLyAtLS0tLS0tIExheW91dCAtLS0tLS0tXG5cbi8qKlxuICogQSBoZWxwZXIgdHlwZTogZ2l2ZW4gYW4gb2JqZWN0IHR5cGUgYFByb3BlcnRpZXNgIHdob3NlIHZhbHVlcyBhcmUgZWFjaCBvZiB0eXBlIGBQcm9wZXJ0eTxULCBSPmAsIGl0IGNhbGN1bGF0ZXNcbiAqIGFuIG9iamVjdCB0eXBlIHdpdGggdGhlIHNhbWUga2V5cyBhbmQgdmFsdWVzIG9mIHR5cGUgYFByb3BlcnR5VmFsdWU8VCwgUj5gLlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbnR5cGUgUHJvcGVydHlWYWx1ZXM8UHJvcHM6IE9iamVjdD5cbiAgICA9ICRFeGFjdDwkT2JqTWFwPFByb3BzLCA8VCwgUj4ocDogUHJvcGVydHk8VCwgUj4pID0+IFByb3BlcnR5VmFsdWU8VCwgUj4+PlxuXG4vKipcbiAqIEEgaGVscGVyIHR5cGU6IGdpdmVuIGFuIG9iamVjdCB0eXBlIGBQcm9wZXJ0aWVzYCB3aG9zZSB2YWx1ZXMgYXJlIGVhY2ggb2YgdHlwZSBgUHJvcGVydHk8VCwgUj5gLCBpdCBjYWxjdWxhdGVzXG4gKiBhbiBvYmplY3QgdHlwZSB3aXRoIHRoZSBzYW1lIGtleXMgYW5kIHZhbHVlcyBvZiB0eXBlIGBQcm9wZXJ0eVZhbHVlU3BlY2lmaWNhdGlvbjxUPmAuXG4gKlxuICogQHByaXZhdGVcbiAqL1xudHlwZSBQcm9wZXJ0eVZhbHVlU3BlY2lmaWNhdGlvbnM8UHJvcHM6IE9iamVjdD5cbiAgICA9ICRFeGFjdDwkT2JqTWFwPFByb3BzLCA8VCwgUj4ocDogUHJvcGVydHk8VCwgUj4pID0+IFByb3BlcnR5VmFsdWVTcGVjaWZpY2F0aW9uPFQ+Pj5cblxuLyoqXG4gKiBCZWNhdXNlIGxheW91dCBwcm9wZXJ0aWVzIGFyZSBub3QgdHJhbnNpdGlvbmFibGUsIHRoZXkgaGF2ZSBhIHNpbXBsZXIgcmVwcmVzZW50YXRpb24gYW5kIGV2YWx1YXRpb24gY2hhaW4gdGhhblxuICogcGFpbnQgcHJvcGVydGllczogYFByb3BlcnR5VmFsdWVgcyBhcmUgcG9zc2libHkgZXZhbHVhdGVkLCBwcm9kdWNpbmcgcG9zc2libHkgZXZhbHVhdGVkIHZhbHVlcywgd2hpY2ggYXJlIHRoZW5cbiAqIGZ1bGx5IGV2YWx1YXRlZC5cbiAqXG4gKiBgTGF5b3V0YCBzdG9yZXMgYSBtYXAgb2YgYWxsIChwcm9wZXJ0eSBuYW1lLCBgUHJvcGVydHlWYWx1ZWApIHBhaXJzIGZvciBsYXlvdXQgcHJvcGVydGllcyBvZiBhXG4gKiBnaXZlbiBsYXllciB0eXBlLiBJdCBjYW4gY2FsY3VsYXRlIHRoZSBwb3NzaWJseS1ldmFsdWF0ZWQgdmFsdWVzIGZvciBhbGwgb2YgdGhlbSBhdCBvbmNlLCBwcm9kdWNpbmcgYVxuICogYFBvc3NpYmx5RXZhbHVhdGVkYCBpbnN0YW5jZSBmb3IgdGhlIHNhbWUgc2V0IG9mIHByb3BlcnRpZXMuXG4gKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGNsYXNzIExheW91dDxQcm9wczogT2JqZWN0PiB7XG4gICAgX3Byb3BlcnRpZXM6IFByb3BlcnRpZXM8UHJvcHM+O1xuICAgIF92YWx1ZXM6IFByb3BlcnR5VmFsdWVzPFByb3BzPjtcblxuICAgIGNvbnN0cnVjdG9yKHByb3BlcnRpZXM6IFByb3BlcnRpZXM8UHJvcHM+KSB7XG4gICAgICAgIHRoaXMuX3Byb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgICAgICB0aGlzLl92YWx1ZXMgPSAoT2JqZWN0LmNyZWF0ZShwcm9wZXJ0aWVzLmRlZmF1bHRQcm9wZXJ0eVZhbHVlcyk6IGFueSk7XG4gICAgfVxuXG4gICAgZ2V0VmFsdWU8Uzogc3RyaW5nLCBUPihuYW1lOiBTKTogUHJvcGVydHlWYWx1ZVNwZWNpZmljYXRpb248VD4gfCB2b2lkIHtcbiAgICAgICAgcmV0dXJuIGNsb25lKHRoaXMuX3ZhbHVlc1tuYW1lXS52YWx1ZSk7XG4gICAgfVxuXG4gICAgc2V0VmFsdWU8Uzogc3RyaW5nPihuYW1lOiBTLCB2YWx1ZTogYW55KSB7XG4gICAgICAgIHRoaXMuX3ZhbHVlc1tuYW1lXSA9IG5ldyBQcm9wZXJ0eVZhbHVlKHRoaXMuX3ZhbHVlc1tuYW1lXS5wcm9wZXJ0eSwgdmFsdWUgPT09IG51bGwgPyB1bmRlZmluZWQgOiBjbG9uZSh2YWx1ZSkpO1xuICAgIH1cblxuICAgIHNlcmlhbGl6ZSgpOiBQcm9wZXJ0eVZhbHVlU3BlY2lmaWNhdGlvbnM8UHJvcHM+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0OiBPYmplY3QgPSB7fTtcbiAgICAgICAgZm9yIChjb25zdCBwcm9wZXJ0eSBvZiBPYmplY3Qua2V5cyh0aGlzLl92YWx1ZXMpKSB7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZ2V0VmFsdWUocHJvcGVydHkpO1xuICAgICAgICAgICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXN1bHRbcHJvcGVydHldID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBwb3NzaWJseUV2YWx1YXRlKHBhcmFtZXRlcnM6IEV2YWx1YXRpb25QYXJhbWV0ZXJzLCBjYW5vbmljYWw/OiBDYW5vbmljYWxUaWxlSUQsIGF2YWlsYWJsZUltYWdlcz86IEFycmF5PHN0cmluZz4pOiBQb3NzaWJseUV2YWx1YXRlZDxQcm9wcz4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBuZXcgUG9zc2libHlFdmFsdWF0ZWQodGhpcy5fcHJvcGVydGllcyk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdXNlLWJlZm9yZS1kZWZpbmVcbiAgICAgICAgZm9yIChjb25zdCBwcm9wZXJ0eSBvZiBPYmplY3Qua2V5cyh0aGlzLl92YWx1ZXMpKSB7XG4gICAgICAgICAgICByZXN1bHQuX3ZhbHVlc1twcm9wZXJ0eV0gPSB0aGlzLl92YWx1ZXNbcHJvcGVydHldLnBvc3NpYmx5RXZhbHVhdGUocGFyYW1ldGVycywgY2Fub25pY2FsLCBhdmFpbGFibGVJbWFnZXMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxufVxuXG4vLyAtLS0tLS0tIFBvc3NpYmx5RXZhbHVhdGVkIC0tLS0tLS1cblxuLyoqXG4gKiBcIlBvc3NpYmx5IGV2YWx1YXRlZCB2YWx1ZVwiIGlzIGFuIGludGVybWVkaWF0ZSBzdGFnZSBpbiB0aGUgZXZhbHVhdGlvbiBjaGFpbiBmb3IgYm90aCBwYWludCBhbmQgbGF5b3V0IHByb3BlcnR5XG4gKiB2YWx1ZXMuIFRoZSBwdXJwb3NlIG9mIHRoaXMgc3RhZ2UgaXMgdG8gb3B0aW1pemUgYXdheSB1bm5lY2Vzc2FyeSByZWNhbGN1bGF0aW9ucyBmb3IgZGF0YS1kcml2ZW4gcHJvcGVydGllcy4gQ29kZVxuICogd2hpY2ggdXNlcyBkYXRhLWRyaXZlbiBwcm9wZXJ0eSB2YWx1ZXMgbXVzdCBhc3N1bWUgdGhhdCB0aGUgdmFsdWUgaXMgZGVwZW5kZW50IG9uIGZlYXR1cmUgZGF0YSwgYW5kIHJlcXVlc3QgdGhhdCBpdFxuICogYmUgZXZhbHVhdGVkIGZvciBlYWNoIGZlYXR1cmUuIEJ1dCB3aGVuIHRoYXQgcHJvcGVydHkgdmFsdWUgaXMgaW4gZmFjdCBhIGNvbnN0YW50IG9yIGNhbWVyYSBmdW5jdGlvbiwgdGhlIGNhbGN1bGF0aW9uXG4gKiB3aWxsIG5vdCBhY3R1YWxseSBkZXBlbmQgb24gdGhlIGZlYXR1cmUsIGFuZCB3ZSBjYW4gYmVuZWZpdCBmcm9tIHJldHVybmluZyB0aGUgcHJpb3IgcmVzdWx0IG9mIGhhdmluZyBkb25lIHRoZVxuICogZXZhbHVhdGlvbiBvbmNlLCBhaGVhZCBvZiB0aW1lLCBpbiBhbiBpbnRlcm1lZGlhdGUgc3RlcCB3aG9zZSBpbnB1dHMgYXJlIGp1c3QgdGhlIHZhbHVlIGFuZCBcImdsb2JhbFwiIHBhcmFtZXRlcnNcbiAqIHN1Y2ggYXMgY3VycmVudCB6b29tIGxldmVsLlxuICpcbiAqIGBQb3NzaWJseUV2YWx1YXRlZFZhbHVlYCByZXByZXNlbnRzIHRoZSB0aHJlZSBwb3NzaWJsZSBvdXRjb21lcyBvZiB0aGlzIHN0ZXA6IGlmIHRoZSBpbnB1dCB2YWx1ZSB3YXMgYSBjb25zdGFudCBvclxuICogY2FtZXJhIGV4cHJlc3Npb24sIHRoZW4gdGhlIFwicG9zc2libHkgZXZhbHVhdGVkXCIgcmVzdWx0IGlzIGEgY29uc3RhbnQgdmFsdWUuIE90aGVyd2lzZSwgdGhlIGlucHV0IHZhbHVlIHdhcyBlaXRoZXJcbiAqIGEgc291cmNlIG9yIGNvbXBvc2l0ZSBleHByZXNzaW9uLCBhbmQgd2UgbXVzdCBkZWZlciBmaW5hbCBldmFsdWF0aW9uIHVudGlsIHN1cHBsaWVkIGEgZmVhdHVyZS4gV2Ugc2VwYXJhdGVcbiAqIHRoZSBzb3VyY2UgYW5kIGNvbXBvc2l0ZSBjYXNlcyBiZWNhdXNlIHRoZXkgYXJlIGhhbmRsZWQgZGlmZmVyZW50bHkgd2hlbiBnZW5lcmF0aW5nIEdMIGF0dHJpYnV0ZXMsIGJ1ZmZlcnMsIGFuZFxuICogdW5pZm9ybXMuXG4gKlxuICogTm90ZSB0aGF0IGBQb3NzaWJseUV2YWx1YXRlZFZhbHVlYCAoYW5kIGBQb3NzaWJseUV2YWx1YXRlZFByb3BlcnR5VmFsdWVgLCBiZWxvdykgYXJlIF9ub3RfIHVzZWQgZm9yIHByb3BlcnRpZXMgdGhhdFxuICogZG8gbm90IGFsbG93IGRhdGEtZHJpdmVuIHZhbHVlcy4gRm9yIHN1Y2ggcHJvcGVydGllcywgd2Uga25vdyB0aGF0IHRoZSBcInBvc3NpYmx5IGV2YWx1YXRlZFwiIHJlc3VsdCBpcyBhbHdheXMgYSBjb25zdGFudFxuICogc2NhbGFyIHZhbHVlLiBTZWUgYmVsb3cuXG4gKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IHR5cGUgUG9zc2libHlFdmFsdWF0ZWRWYWx1ZTxUPiA9XG4gICAgfCB7a2luZDogJ2NvbnN0YW50JywgdmFsdWU6IFR9XG4gICAgfCBTb3VyY2VFeHByZXNzaW9uXG4gICAgfCBDb21wb3NpdGVFeHByZXNzaW9uO1xuXG4vKipcbiAqIGBQb3NzaWJseUV2YWx1YXRlZFByb3BlcnR5VmFsdWVgIGlzIHVzZWQgZm9yIGRhdGEtZHJpdmVuIHBhaW50IGFuZCBsYXlvdXQgcHJvcGVydHkgdmFsdWVzLiBJdCBob2xkcyBhXG4gKiBgUG9zc2libHlFdmFsdWF0ZWRWYWx1ZWAgYW5kIHRoZSBgR2xvYmFsUHJvcGVydGllc2AgdGhhdCB3ZXJlIHVzZWQgdG8gZ2VuZXJhdGUgaXQuIFlvdSdyZSBub3QgYWxsb3dlZCB0byBzdXBwbHlcbiAqIGEgZGlmZmVyZW50IHNldCBvZiBgR2xvYmFsUHJvcGVydGllc2Agd2hlbiBwZXJmb3JtaW5nIHRoZSBmaW5hbCBldmFsdWF0aW9uIGJlY2F1c2UgdGhleSB3b3VsZCBiZSBpZ25vcmVkIGluIHRoZVxuICogY2FzZSB3aGVyZSB0aGUgaW5wdXQgdmFsdWUgd2FzIGEgY29uc3RhbnQgb3IgY2FtZXJhIGZ1bmN0aW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBjbGFzcyBQb3NzaWJseUV2YWx1YXRlZFByb3BlcnR5VmFsdWU8VD4ge1xuICAgIHByb3BlcnR5OiBEYXRhRHJpdmVuUHJvcGVydHk8VD47XG4gICAgdmFsdWU6IFBvc3NpYmx5RXZhbHVhdGVkVmFsdWU8VD47XG4gICAgcGFyYW1ldGVyczogRXZhbHVhdGlvblBhcmFtZXRlcnM7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcm9wZXJ0eTogRGF0YURyaXZlblByb3BlcnR5PFQ+LCB2YWx1ZTogUG9zc2libHlFdmFsdWF0ZWRWYWx1ZTxUPiwgcGFyYW1ldGVyczogRXZhbHVhdGlvblBhcmFtZXRlcnMpIHtcbiAgICAgICAgdGhpcy5wcm9wZXJ0eSA9IHByb3BlcnR5O1xuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgICAgIHRoaXMucGFyYW1ldGVycyA9IHBhcmFtZXRlcnM7XG4gICAgfVxuXG4gICAgaXNDb25zdGFudCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWUua2luZCA9PT0gJ2NvbnN0YW50JztcbiAgICB9XG5cbiAgICBjb25zdGFudE9yKHZhbHVlOiBUKTogVCB7XG4gICAgICAgIGlmICh0aGlzLnZhbHVlLmtpbmQgPT09ICdjb25zdGFudCcpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlLnZhbHVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZXZhbHVhdGUoZmVhdHVyZTogRmVhdHVyZSwgZmVhdHVyZVN0YXRlOiBGZWF0dXJlU3RhdGUsIGNhbm9uaWNhbD86IENhbm9uaWNhbFRpbGVJRCwgYXZhaWxhYmxlSW1hZ2VzPzogQXJyYXk8c3RyaW5nPik6IFQge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0eS5ldmFsdWF0ZSh0aGlzLnZhbHVlLCB0aGlzLnBhcmFtZXRlcnMsIGZlYXR1cmUsIGZlYXR1cmVTdGF0ZSwgY2Fub25pY2FsLCBhdmFpbGFibGVJbWFnZXMpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBBIGhlbHBlciB0eXBlOiBnaXZlbiBhbiBvYmplY3QgdHlwZSBgUHJvcGVydGllc2Agd2hvc2UgdmFsdWVzIGFyZSBlYWNoIG9mIHR5cGUgYFByb3BlcnR5PFQsIFI+YCwgaXQgY2FsY3VsYXRlc1xuICogYW4gb2JqZWN0IHR5cGUgd2l0aCB0aGUgc2FtZSBrZXlzLCBhbmQgdmFsdWVzIG9mIHR5cGUgYFJgLlxuICpcbiAqIEZvciBwcm9wZXJ0aWVzIHRoYXQgZG9uJ3QgYWxsb3cgZGF0YS1kcml2ZW4gdmFsdWVzLCBgUmAgaXMgYSBzY2FsYXIgdHlwZSBzdWNoIGFzIGBudW1iZXJgLCBgc3RyaW5nYCwgb3IgYENvbG9yYC5cbiAqIEZvciBkYXRhLWRyaXZlbiBwcm9wZXJ0aWVzLCBpdCBpcyBgUG9zc2libHlFdmFsdWF0ZWRQcm9wZXJ0eVZhbHVlYC4gQ3JpdGljYWxseSwgdGhlIHR5cGUgZGVmaW5pdGlvbnMgYXJlIHNldCB1cFxuICogaW4gYSB3YXkgdGhhdCBhbGxvd3MgZmxvdyB0byBrbm93IHdoaWNoIG9mIHRoZXNlIHR3byBjYXNlcyBhcHBsaWVzIGZvciBhbnkgZ2l2ZW4gcHJvcGVydHkgbmFtZSwgYW5kIGlmIHlvdSBhdHRlbXB0XG4gKiB0byB1c2UgYSBgUG9zc2libHlFdmFsdWF0ZWRQcm9wZXJ0eVZhbHVlYCBhcyBpZiBpdCB3YXMgYSBzY2FsYXIsIG9yIHZpY2UgdmVyc2EsIHlvdSB3aWxsIGdldCBhIHR5cGUgZXJyb3IuIChIb3dldmVyLFxuICogdGhlcmUncyBhdCBsZWFzdCBvbmUgY2FzZSBpbiB3aGljaCBmbG93IGZhaWxzIHRvIHByb2R1Y2UgYSB0eXBlIGVycm9yIHRoYXQgeW91IHNob3VsZCBiZSBhd2FyZSBvZjogaW4gYSBjb250ZXh0IHN1Y2hcbiAqIGFzIGBsYXllci5wYWludC5nZXQoJ2Zvby1vcGFjaXR5JykgPT09IDBgLCBpZiBgZm9vLW9wYWNpdHlgIGlzIGRhdGEtZHJpdmVuLCB0aGFuIHRoZSBsZWZ0LWhhbmQgc2lkZSBpcyBvZiB0eXBlXG4gKiBgUG9zc2libHlFdmFsdWF0ZWRQcm9wZXJ0eVZhbHVlPG51bWJlcj5gLCBidXQgZmxvdyB3aWxsIG5vdCBjb21wbGFpbiBhYm91dCBjb21wYXJpbmcgdGhpcyB0byBhIG51bWJlciB1c2luZyBgPT09YC5cbiAqIFNlZSBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svZmxvdy9pc3N1ZXMvMjM1OS4pXG4gKlxuICogQHByaXZhdGVcbiAqL1xudHlwZSBQb3NzaWJseUV2YWx1YXRlZFByb3BlcnR5VmFsdWVzPFByb3BzOiBPYmplY3Q+XG4gICAgPSAkRXhhY3Q8JE9iak1hcDxQcm9wcywgPFQsIFI+KHA6IFByb3BlcnR5PFQsIFI+KSA9PiBSPj5cblxuLyoqXG4gKiBgUG9zc2libHlFdmFsdWF0ZWRgIHN0b3JlcyBhIG1hcCBvZiBhbGwgKHByb3BlcnR5IG5hbWUsIGBSYCkgcGFpcnMgZm9yIHBhaW50IG9yIGxheW91dCBwcm9wZXJ0aWVzIG9mIGFcbiAqIGdpdmVuIGxheWVyIHR5cGUuXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgY2xhc3MgUG9zc2libHlFdmFsdWF0ZWQ8UHJvcHM6IE9iamVjdD4ge1xuICAgIF9wcm9wZXJ0aWVzOiBQcm9wZXJ0aWVzPFByb3BzPjtcbiAgICBfdmFsdWVzOiBQb3NzaWJseUV2YWx1YXRlZFByb3BlcnR5VmFsdWVzPFByb3BzPjtcblxuICAgIGNvbnN0cnVjdG9yKHByb3BlcnRpZXM6IFByb3BlcnRpZXM8UHJvcHM+KSB7XG4gICAgICAgIHRoaXMuX3Byb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgICAgICB0aGlzLl92YWx1ZXMgPSAoT2JqZWN0LmNyZWF0ZShwcm9wZXJ0aWVzLmRlZmF1bHRQb3NzaWJseUV2YWx1YXRlZFZhbHVlcyk6IGFueSk7XG4gICAgfVxuXG4gICAgZ2V0PFM6IHN0cmluZz4obmFtZTogUyk6ICRFbGVtZW50VHlwZTxQb3NzaWJseUV2YWx1YXRlZFByb3BlcnR5VmFsdWVzPFByb3BzPiwgUz4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fdmFsdWVzW25hbWVdO1xuICAgIH1cbn1cblxuLyoqXG4gKiBBbiBpbXBsZW1lbnRhdGlvbiBvZiBgUHJvcGVydHlgIGZvciBwcm9wZXJ0aWVzIHRoYXQgZG8gbm90IHBlcm1pdCBkYXRhLWRyaXZlbiAoc291cmNlIG9yIGNvbXBvc2l0ZSkgZXhwcmVzc2lvbnMuXG4gKiBUaGlzIHJlc3RyaWN0aW9uIGFsbG93cyB1cyB0byBkZWNsYXJlIHN0YXRpY2FsbHkgdGhhdCB0aGUgcmVzdWx0IG9mIHBvc3NpYmx5IGV2YWx1YXRpbmcgdGhpcyBraW5kIG9mIHByb3BlcnR5XG4gKiBpcyBpbiBmYWN0IGFsd2F5cyB0aGUgc2NhbGFyIHR5cGUgYFRgLCBhbmQgY2FuIGJlIHVzZWQgd2l0aG91dCBmdXJ0aGVyIGV2YWx1YXRpbmcgdGhlIHZhbHVlIG9uIGEgcGVyLWZlYXR1cmUgYmFzaXMuXG4gKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGNsYXNzIERhdGFDb25zdGFudFByb3BlcnR5PFQ+IGltcGxlbWVudHMgUHJvcGVydHk8VCwgVD4ge1xuICAgIHNwZWNpZmljYXRpb246IFN0eWxlUHJvcGVydHlTcGVjaWZpY2F0aW9uO1xuXG4gICAgY29uc3RydWN0b3Ioc3BlY2lmaWNhdGlvbjogU3R5bGVQcm9wZXJ0eVNwZWNpZmljYXRpb24pIHtcbiAgICAgICAgdGhpcy5zcGVjaWZpY2F0aW9uID0gc3BlY2lmaWNhdGlvbjtcbiAgICB9XG5cbiAgICBwb3NzaWJseUV2YWx1YXRlKHZhbHVlOiBQcm9wZXJ0eVZhbHVlPFQsIFQ+LCBwYXJhbWV0ZXJzOiBFdmFsdWF0aW9uUGFyYW1ldGVycyk6IFQge1xuICAgICAgICBhc3NlcnQoIXZhbHVlLmlzRGF0YURyaXZlbigpKTtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICByZXR1cm4gdmFsdWUuZXhwcmVzc2lvbi5ldmFsdWF0ZShwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICBpbnRlcnBvbGF0ZShhOiBULCBiOiBULCB0OiBudW1iZXIpOiBUIHtcbiAgICAgICAgY29uc3QgaW50ZXJwOiA/KGE6IFQsIGI6IFQsIHQ6IG51bWJlcikgPT4gVCA9IChpbnRlcnBvbGF0ZTogYW55KVt0aGlzLnNwZWNpZmljYXRpb24udHlwZV07XG4gICAgICAgIGlmIChpbnRlcnApIHtcbiAgICAgICAgICAgIHJldHVybiBpbnRlcnAoYSwgYiwgdCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gYTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqXG4gKiBBbiBpbXBsZW1lbnRhdGlvbiBvZiBgUHJvcGVydHlgIGZvciBwcm9wZXJ0aWVzIHRoYXQgcGVybWl0IGRhdGEtZHJpdmVuIChzb3VyY2Ugb3IgY29tcG9zaXRlKSBleHByZXNzaW9ucy5cbiAqIFRoZSByZXN1bHQgb2YgcG9zc2libHkgZXZhbHVhdGluZyB0aGlzIGtpbmQgb2YgcHJvcGVydHkgaXMgYFBvc3NpYmx5RXZhbHVhdGVkUHJvcGVydHlWYWx1ZTxUPmA7IG9idGFpbmluZ1xuICogYSBzY2FsYXIgdmFsdWUgYFRgIHJlcXVpcmVzIGZ1cnRoZXIgZXZhbHVhdGlvbiBvbiBhIHBlci1mZWF0dXJlIGJhc2lzLlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBjbGFzcyBEYXRhRHJpdmVuUHJvcGVydHk8VD4gaW1wbGVtZW50cyBQcm9wZXJ0eTxULCBQb3NzaWJseUV2YWx1YXRlZFByb3BlcnR5VmFsdWU8VD4+IHtcbiAgICBzcGVjaWZpY2F0aW9uOiBTdHlsZVByb3BlcnR5U3BlY2lmaWNhdGlvbjtcbiAgICBvdmVycmlkZXM6ID9PYmplY3Q7XG4gICAgdXNlSW50ZWdlclpvb206ID9ib29sZWFuO1xuXG4gICAgY29uc3RydWN0b3Ioc3BlY2lmaWNhdGlvbjogU3R5bGVQcm9wZXJ0eVNwZWNpZmljYXRpb24sIG92ZXJyaWRlcz86IE9iamVjdCkge1xuICAgICAgICB0aGlzLnNwZWNpZmljYXRpb24gPSBzcGVjaWZpY2F0aW9uO1xuICAgICAgICB0aGlzLm92ZXJyaWRlcyA9IG92ZXJyaWRlcztcbiAgICB9XG5cbiAgICBwb3NzaWJseUV2YWx1YXRlKHZhbHVlOiBQcm9wZXJ0eVZhbHVlPFQsIFBvc3NpYmx5RXZhbHVhdGVkUHJvcGVydHlWYWx1ZTxUPj4sIHBhcmFtZXRlcnM6IEV2YWx1YXRpb25QYXJhbWV0ZXJzLCBjYW5vbmljYWw/OiBDYW5vbmljYWxUaWxlSUQsIGF2YWlsYWJsZUltYWdlcz86IEFycmF5PHN0cmluZz4pOiBQb3NzaWJseUV2YWx1YXRlZFByb3BlcnR5VmFsdWU8VD4ge1xuICAgICAgICBpZiAodmFsdWUuZXhwcmVzc2lvbi5raW5kID09PSAnY29uc3RhbnQnIHx8IHZhbHVlLmV4cHJlc3Npb24ua2luZCA9PT0gJ2NhbWVyYScpIHtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIHJldHVybiBuZXcgUG9zc2libHlFdmFsdWF0ZWRQcm9wZXJ0eVZhbHVlKHRoaXMsIHtraW5kOiAnY29uc3RhbnQnLCB2YWx1ZTogdmFsdWUuZXhwcmVzc2lvbi5ldmFsdWF0ZShwYXJhbWV0ZXJzLCAobnVsbDogYW55KSwge30sIGNhbm9uaWNhbCwgYXZhaWxhYmxlSW1hZ2VzKX0sIHBhcmFtZXRlcnMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBQb3NzaWJseUV2YWx1YXRlZFByb3BlcnR5VmFsdWUodGhpcywgdmFsdWUuZXhwcmVzc2lvbiwgcGFyYW1ldGVycyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpbnRlcnBvbGF0ZShhOiBQb3NzaWJseUV2YWx1YXRlZFByb3BlcnR5VmFsdWU8VD4sXG4gICAgICAgICAgICAgICAgYjogUG9zc2libHlFdmFsdWF0ZWRQcm9wZXJ0eVZhbHVlPFQ+LFxuICAgICAgICAgICAgICAgIHQ6IG51bWJlcik6IFBvc3NpYmx5RXZhbHVhdGVkUHJvcGVydHlWYWx1ZTxUPiB7XG4gICAgICAgIC8vIElmIGVpdGhlciBwb3NzaWJseS1ldmFsdWF0ZWQgdmFsdWUgaXMgbm9uLWNvbnN0YW50LCBnaXZlIHVwOiB3ZSBhcmVuJ3QgYWJsZSB0byBpbnRlcnBvbGF0ZSBkYXRhLWRyaXZlbiB2YWx1ZXMuXG4gICAgICAgIGlmIChhLnZhbHVlLmtpbmQgIT09ICdjb25zdGFudCcgfHwgYi52YWx1ZS5raW5kICE9PSAnY29uc3RhbnQnKSB7XG4gICAgICAgICAgICByZXR1cm4gYTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNwZWNpYWwgY2FzZSBoYWNrIHNvbGVseSBmb3IgZmlsbC1vdXRsaW5lLWNvbG9yLiBUaGUgdW5kZWZpbmVkIHZhbHVlIGlzIHN1YnNlcXVlbnRseSBoYW5kbGVkIGluXG4gICAgICAgIC8vIEZpbGxTdHlsZUxheWVyI3JlY2FsY3VsYXRlLCB3aGljaCBzZXRzIGZpbGwtb3V0bGluZS1jb2xvciB0byB0aGUgZmlsbC1jb2xvciB2YWx1ZSBpZiB0aGUgZm9ybWVyXG4gICAgICAgIC8vIGlzIGEgUG9zc2libHlFdmFsdWF0ZWRQcm9wZXJ0eVZhbHVlIGNvbnRhaW5pbmcgYSBjb25zdGFudCB1bmRlZmluZWQgdmFsdWUuIEluIGFkZGl0aW9uIHRvIHRoZVxuICAgICAgICAvLyByZXR1cm4gdmFsdWUgaGVyZSwgdGhlIG90aGVyIHNvdXJjZSBvZiBhIFBvc3NpYmx5RXZhbHVhdGVkUHJvcGVydHlWYWx1ZSBjb250YWluaW5nIGEgY29uc3RhbnRcbiAgICAgICAgLy8gdW5kZWZpbmVkIHZhbHVlIGlzIHRoZSBcImRlZmF1bHQgdmFsdWVcIiBmb3IgZmlsbC1vdXRsaW5lLWNvbG9yIGhlbGQgaW5cbiAgICAgICAgLy8gYFByb3BlcnRpZXMjZGVmYXVsdFBvc3NpYmx5RXZhbHVhdGVkVmFsdWVzYCwgd2hpY2ggc2VydmVzIGFzIHRoZSBwcm90b3R5cGUgb2ZcbiAgICAgICAgLy8gYFBvc3NpYmx5RXZhbHVhdGVkI192YWx1ZXNgLlxuICAgICAgICBpZiAoYS52YWx1ZS52YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IGIudmFsdWUudmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBQb3NzaWJseUV2YWx1YXRlZFByb3BlcnR5VmFsdWUodGhpcywge2tpbmQ6ICdjb25zdGFudCcsIHZhbHVlOiAodW5kZWZpbmVkOiBhbnkpfSwgYS5wYXJhbWV0ZXJzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGludGVycDogPyhhOiBULCBiOiBULCB0OiBudW1iZXIpID0+IFQgPSAoaW50ZXJwb2xhdGU6IGFueSlbdGhpcy5zcGVjaWZpY2F0aW9uLnR5cGVdO1xuICAgICAgICBpZiAoaW50ZXJwKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFBvc3NpYmx5RXZhbHVhdGVkUHJvcGVydHlWYWx1ZSh0aGlzLCB7a2luZDogJ2NvbnN0YW50JywgdmFsdWU6IGludGVycChhLnZhbHVlLnZhbHVlLCBiLnZhbHVlLnZhbHVlLCB0KX0sIGEucGFyYW1ldGVycyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gYTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGV2YWx1YXRlKHZhbHVlOiBQb3NzaWJseUV2YWx1YXRlZFZhbHVlPFQ+LCBwYXJhbWV0ZXJzOiBFdmFsdWF0aW9uUGFyYW1ldGVycywgZmVhdHVyZTogRmVhdHVyZSwgZmVhdHVyZVN0YXRlOiBGZWF0dXJlU3RhdGUsIGNhbm9uaWNhbD86IENhbm9uaWNhbFRpbGVJRCwgYXZhaWxhYmxlSW1hZ2VzPzogQXJyYXk8c3RyaW5nPik6IFQge1xuICAgICAgICBpZiAodmFsdWUua2luZCA9PT0gJ2NvbnN0YW50Jykge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlLnZhbHVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlLmV2YWx1YXRlKHBhcmFtZXRlcnMsIGZlYXR1cmUsIGZlYXR1cmVTdGF0ZSwgY2Fub25pY2FsLCBhdmFpbGFibGVJbWFnZXMpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG4vKipcbiAqIEFuIGltcGxlbWVudGF0aW9uIG9mIGBQcm9wZXJ0eWAgZm9yIGBoZWF0bWFwLWNvbG9yYCBhbmQgYGxpbmUtZ3JhZGllbnRgLiBJbnRlcnBvbGF0aW9uIGlzIGEgbm8tb3AsIGFuZFxuICogZXZhbHVhdGlvbiByZXR1cm5zIGEgYm9vbGVhbiB2YWx1ZSBpbiBvcmRlciB0byBpbmRpY2F0ZSBpdHMgcHJlc2VuY2UsIGJ1dCB0aGUgcmVhbFxuICogZXZhbHVhdGlvbiBoYXBwZW5zIGluIFN0eWxlTGF5ZXIgY2xhc3Nlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgY2xhc3MgQ29sb3JSYW1wUHJvcGVydHkgaW1wbGVtZW50cyBQcm9wZXJ0eTxDb2xvciwgYm9vbGVhbj4ge1xuICAgIHNwZWNpZmljYXRpb246IFN0eWxlUHJvcGVydHlTcGVjaWZpY2F0aW9uO1xuXG4gICAgY29uc3RydWN0b3Ioc3BlY2lmaWNhdGlvbjogU3R5bGVQcm9wZXJ0eVNwZWNpZmljYXRpb24pIHtcbiAgICAgICAgdGhpcy5zcGVjaWZpY2F0aW9uID0gc3BlY2lmaWNhdGlvbjtcbiAgICB9XG5cbiAgICBwb3NzaWJseUV2YWx1YXRlKHZhbHVlOiBQcm9wZXJ0eVZhbHVlPENvbG9yLCBib29sZWFuPiwgcGFyYW1ldGVyczogRXZhbHVhdGlvblBhcmFtZXRlcnMsIGNhbm9uaWNhbD86IENhbm9uaWNhbFRpbGVJRCwgYXZhaWxhYmxlSW1hZ2VzPzogQXJyYXk8c3RyaW5nPik6IGJvb2xlYW4ge1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIHJldHVybiAhIXZhbHVlLmV4cHJlc3Npb24uZXZhbHVhdGUocGFyYW1ldGVycywgKG51bGw6IGFueSksIHt9LCBjYW5vbmljYWwsIGF2YWlsYWJsZUltYWdlcyk7XG4gICAgfVxuXG4gICAgaW50ZXJwb2xhdGUoKTogYm9vbGVhbiB7IHJldHVybiBmYWxzZTsgfVxufVxuXG4vKipcbiAqIGBQcm9wZXJ0aWVzYCBob2xkcyBvYmplY3RzIGNvbnRhaW5pbmcgZGVmYXVsdCB2YWx1ZXMgZm9yIHRoZSBsYXlvdXQgb3IgcGFpbnQgcHJvcGVydHkgc2V0IG9mIGEgZ2l2ZW5cbiAqIGxheWVyIHR5cGUuIFRoZXNlIG9iamVjdHMgYXJlIGltbXV0YWJsZSwgYW5kIHRoZXkgYXJlIHVzZWQgYXMgdGhlIHByb3RvdHlwZXMgZm9yIHRoZSBgX3ZhbHVlc2AgbWVtYmVycyBvZlxuICogYFRyYW5zaXRpb25hYmxlYCwgYFRyYW5zaXRpb25pbmdgLCBgTGF5b3V0YCwgYW5kIGBQb3NzaWJseUV2YWx1YXRlZGAuIFRoaXMgYWxsb3dzIHRoZXNlIGNsYXNzZXMgdG8gYXZvaWRcbiAqIGRvaW5nIHdvcmsgaW4gdGhlIGNvbW1vbiBjYXNlIHdoZXJlIGEgcHJvcGVydHkgaGFzIG5vIGV4cGxpY2l0IHZhbHVlIHNldCBhbmQgc2hvdWxkIGJlIGNvbnNpZGVyZWQgdG8gdGFrZVxuICogb24gdGhlIGRlZmF1bHQgdmFsdWU6IHVzaW5nIGBmb3IgKGNvbnN0IHByb3BlcnR5IG9mIE9iamVjdC5rZXlzKHRoaXMuX3ZhbHVlcykpYCwgdGhleSBjYW4gaXRlcmF0ZSBvdmVyXG4gKiBvbmx5IHRoZSBfb3duXyBwcm9wZXJ0aWVzIG9mIGBfdmFsdWVzYCwgc2tpcHBpbmcgcmVwZWF0ZWQgY2FsY3VsYXRpb24gb2YgdHJhbnNpdGlvbnMgYW5kIHBvc3NpYmxlL2ZpbmFsXG4gKiBldmFsdWF0aW9ucyBmb3IgZGVmYXVsdHMsIHRoZSByZXN1bHQgb2Ygd2hpY2ggd2lsbCBhbHdheXMgYmUgdGhlIHNhbWUuXG4gKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGNsYXNzIFByb3BlcnRpZXM8UHJvcHM6IE9iamVjdD4ge1xuICAgIHByb3BlcnRpZXM6IFByb3BzO1xuICAgIGRlZmF1bHRQcm9wZXJ0eVZhbHVlczogUHJvcGVydHlWYWx1ZXM8UHJvcHM+O1xuICAgIGRlZmF1bHRUcmFuc2l0aW9uYWJsZVByb3BlcnR5VmFsdWVzOiBUcmFuc2l0aW9uYWJsZVByb3BlcnR5VmFsdWVzPFByb3BzPjtcbiAgICBkZWZhdWx0VHJhbnNpdGlvbmluZ1Byb3BlcnR5VmFsdWVzOiBUcmFuc2l0aW9uaW5nUHJvcGVydHlWYWx1ZXM8UHJvcHM+O1xuICAgIGRlZmF1bHRQb3NzaWJseUV2YWx1YXRlZFZhbHVlczogUG9zc2libHlFdmFsdWF0ZWRQcm9wZXJ0eVZhbHVlczxQcm9wcz47XG4gICAgb3ZlcnJpZGFibGVQcm9wZXJ0aWVzOiBBcnJheTxzdHJpbmc+O1xuXG4gICAgY29uc3RydWN0b3IocHJvcGVydGllczogUHJvcHMpIHtcbiAgICAgICAgdGhpcy5wcm9wZXJ0aWVzID0gcHJvcGVydGllcztcbiAgICAgICAgdGhpcy5kZWZhdWx0UHJvcGVydHlWYWx1ZXMgPSAoe306IGFueSk7XG4gICAgICAgIHRoaXMuZGVmYXVsdFRyYW5zaXRpb25hYmxlUHJvcGVydHlWYWx1ZXMgPSAoe306IGFueSk7XG4gICAgICAgIHRoaXMuZGVmYXVsdFRyYW5zaXRpb25pbmdQcm9wZXJ0eVZhbHVlcyA9ICh7fTogYW55KTtcbiAgICAgICAgdGhpcy5kZWZhdWx0UG9zc2libHlFdmFsdWF0ZWRWYWx1ZXMgPSAoe306IGFueSk7XG4gICAgICAgIHRoaXMub3ZlcnJpZGFibGVQcm9wZXJ0aWVzID0gKFtdOiBhbnkpO1xuXG4gICAgICAgIGNvbnN0IGRlZmF1bHRQYXJhbWV0ZXJzID0gbmV3IEV2YWx1YXRpb25QYXJhbWV0ZXJzKDAsIHt9KTtcbiAgICAgICAgZm9yIChjb25zdCBwcm9wZXJ0eSBpbiBwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICBjb25zdCBwcm9wID0gcHJvcGVydGllc1twcm9wZXJ0eV07XG4gICAgICAgICAgICBpZiAocHJvcC5zcGVjaWZpY2F0aW9uLm92ZXJyaWRhYmxlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vdmVycmlkYWJsZVByb3BlcnRpZXMucHVzaChwcm9wZXJ0eSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBkZWZhdWx0UHJvcGVydHlWYWx1ZSA9IHRoaXMuZGVmYXVsdFByb3BlcnR5VmFsdWVzW3Byb3BlcnR5XSA9XG4gICAgICAgICAgICAgICAgbmV3IFByb3BlcnR5VmFsdWUocHJvcCwgdW5kZWZpbmVkKTtcbiAgICAgICAgICAgIGNvbnN0IGRlZmF1bHRUcmFuc2l0aW9uYWJsZVByb3BlcnR5VmFsdWUgPSB0aGlzLmRlZmF1bHRUcmFuc2l0aW9uYWJsZVByb3BlcnR5VmFsdWVzW3Byb3BlcnR5XSA9XG4gICAgICAgICAgICAgICAgbmV3IFRyYW5zaXRpb25hYmxlUHJvcGVydHlWYWx1ZShwcm9wKTtcbiAgICAgICAgICAgIHRoaXMuZGVmYXVsdFRyYW5zaXRpb25pbmdQcm9wZXJ0eVZhbHVlc1twcm9wZXJ0eV0gPVxuICAgICAgICAgICAgICAgIGRlZmF1bHRUcmFuc2l0aW9uYWJsZVByb3BlcnR5VmFsdWUudW50cmFuc2l0aW9uZWQoKTtcbiAgICAgICAgICAgIHRoaXMuZGVmYXVsdFBvc3NpYmx5RXZhbHVhdGVkVmFsdWVzW3Byb3BlcnR5XSA9XG4gICAgICAgICAgICAgICAgZGVmYXVsdFByb3BlcnR5VmFsdWUucG9zc2libHlFdmFsdWF0ZShkZWZhdWx0UGFyYW1ldGVycyk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbnJlZ2lzdGVyKERhdGFEcml2ZW5Qcm9wZXJ0eSwgJ0RhdGFEcml2ZW5Qcm9wZXJ0eScpO1xucmVnaXN0ZXIoRGF0YUNvbnN0YW50UHJvcGVydHksICdEYXRhQ29uc3RhbnRQcm9wZXJ0eScpO1xucmVnaXN0ZXIoQ29sb3JSYW1wUHJvcGVydHksICdDb2xvclJhbXBQcm9wZXJ0eScpO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtjbGFtcH0gZnJvbSAnLi4vdXRpbC91dGlsLmpzJztcblxuLyoqXG4gKiBQYWNrcyB0d28gbnVtYmVycywgaW50ZXJwcmV0ZWQgYXMgOC1iaXQgdW5zaWduZWQgaW50ZWdlcnMsIGludG8gYSBzaW5nbGVcbiAqIGZsb2F0LiAgVW5wYWNrIHRoZW0gaW4gdGhlIHNoYWRlciB1c2luZyB0aGUgYHVucGFja19mbG9hdCgpYCBmdW5jdGlvbixcbiAqIGRlZmluZWQgaW4gX3ByZWx1ZGUudmVydGV4Lmdsc2xcbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFja1VpbnQ4VG9GbG9hdChhOiBudW1iZXIsIGI6IG51bWJlcik6IG51bWJlciB7XG4gICAgLy8gY29lcmNlIGEgYW5kIGIgdG8gOC1iaXQgaW50c1xuICAgIGEgPSBjbGFtcChNYXRoLmZsb29yKGEpLCAwLCAyNTUpO1xuICAgIGIgPSBjbGFtcChNYXRoLmZsb29yKGIpLCAwLCAyNTUpO1xuICAgIHJldHVybiAyNTYgKiBhICsgYjtcbn1cbiIsIi8vIEBmbG93XG5cbi8vIE5vdGU6IGFsbCBcInNpemVzXCIgYXJlIG1lYXN1cmVkIGluIGJ5dGVzXG5cbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcblxuaW1wb3J0IHR5cGUge1RyYW5zZmVyYWJsZX0gZnJvbSAnLi4vdHlwZXMvdHJhbnNmZXJhYmxlLmpzJztcblxuY29uc3Qgdmlld1R5cGVzID0ge1xuICAgICdJbnQ4JzogSW50OEFycmF5LFxuICAgICdVaW50OCc6IFVpbnQ4QXJyYXksXG4gICAgJ0ludDE2JzogSW50MTZBcnJheSxcbiAgICAnVWludDE2JzogVWludDE2QXJyYXksXG4gICAgJ0ludDMyJzogSW50MzJBcnJheSxcbiAgICAnVWludDMyJzogVWludDMyQXJyYXksXG4gICAgJ0Zsb2F0MzInOiBGbG9hdDMyQXJyYXlcbn07XG5cbmV4cG9ydCB0eXBlIFZpZXdUeXBlID0gJEtleXM8dHlwZW9mIHZpZXdUeXBlcz47XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuY2xhc3MgU3RydWN0IHtcbiAgICAvLyBXaGVuIHJlYWRpbmcgdGhlIEFycmF5QnVmZmVyIGFzIGFuIGFycmF5IG9mIGRpZmZlcmVudCBkYXRhIHR5cGVzLCBhcnJheXMgaGF2ZSBkaWZmZXJlbnQgbGVuZ3RoXG4gICAgLy8gZGVwZW5kaW5nIG9uIGRhdGEgdHlwZSBzaXplLiBTbyB0byBhY2VzcyB0aGUgc2FtZSBwb3NpdGlvbixcbiAgICAvLyB3ZSBuZWVkIHRvIHJlYWQgZGlmZmVyZW50IGluZGV4ZXMgZGVwZW5kaW5nIG9uIGFycmF5IGRhdGEgc2l6ZS5cbiAgICAvLyBfcG9zMSBpcyB0aGUgaW5kZXggcmVhZGluZyBhbiBhcnJheSB3aXRoIDEgYnl0ZSBkYXRhLFxuICAgIC8vIF9wb3MyIGlzIHJlYWRpbmcgMiBieXRlIGRhdGEsIGFuZCBzbyBmb3J0aC5cbiAgICBfcG9zMTogbnVtYmVyO1xuICAgIF9wb3MyOiBudW1iZXI7XG4gICAgX3BvczQ6IG51bWJlcjtcbiAgICBfcG9zODogbnVtYmVyO1xuICAgICtfc3RydWN0QXJyYXk6IFN0cnVjdEFycmF5O1xuXG4gICAgLy8gVGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzIGFyZSBkZWZpbmVkIG9uIHRoZSBwcm90b3R5cGUgb2Ygc3ViIGNsYXNzZXMuXG4gICAgc2l6ZTogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJ1Y3RBcnJheX0gc3RydWN0QXJyYXkgVGhlIFN0cnVjdEFycmF5IHRoZSBzdHJ1Y3QgaXMgc3RvcmVkIGluXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IFRoZSBpbmRleCBvZiB0aGUgc3RydWN0IGluIHRoZSBTdHJ1Y3RBcnJheS5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHN0cnVjdEFycmF5OiBTdHJ1Y3RBcnJheSwgaW5kZXg6IG51bWJlcikge1xuICAgICAgICAodGhpczogYW55KS5fc3RydWN0QXJyYXkgPSBzdHJ1Y3RBcnJheTtcbiAgICAgICAgdGhpcy5fcG9zMSA9IGluZGV4ICogdGhpcy5zaXplO1xuICAgICAgICB0aGlzLl9wb3MyID0gdGhpcy5fcG9zMSAvIDI7XG4gICAgICAgIHRoaXMuX3BvczQgPSB0aGlzLl9wb3MxIC8gNDtcbiAgICAgICAgdGhpcy5fcG9zOCA9IHRoaXMuX3BvczEgLyA4O1xuICAgIH1cbn1cblxuY29uc3QgREVGQVVMVF9DQVBBQ0lUWSA9IDEyODtcbmNvbnN0IFJFU0laRV9NVUxUSVBMSUVSID0gNTtcblxuZXhwb3J0IHR5cGUgU3RydWN0QXJyYXlNZW1iZXIgPSB7XG4gICAgbmFtZTogc3RyaW5nLFxuICAgIHR5cGU6IFZpZXdUeXBlLFxuICAgIGNvbXBvbmVudHM6IG51bWJlcixcbiAgICBvZmZzZXQ6IG51bWJlclxufTtcblxuZXhwb3J0IHR5cGUgU3RydWN0QXJyYXlMYXlvdXQgPSB7XG4gICAgbWVtYmVyczogQXJyYXk8U3RydWN0QXJyYXlNZW1iZXI+LFxuICAgIHNpemU6IG51bWJlcixcbiAgICBhbGlnbm1lbnQ6ID9udW1iZXJcbn1cblxuZXhwb3J0IHR5cGUgU2VyaWFsaXplZFN0cnVjdEFycmF5ID0ge1xuICAgIGxlbmd0aDogbnVtYmVyLFxuICAgIGFycmF5QnVmZmVyOiBBcnJheUJ1ZmZlclxufTtcblxuLyoqXG4gKiBgU3RydWN0QXJyYXlgIHByb3ZpZGVzIGFuIGFic3RyYWN0aW9uIG92ZXIgYEFycmF5QnVmZmVyYCBhbmQgYFR5cGVkQXJyYXlgXG4gKiBtYWtpbmcgaXQgYmVoYXZlIGxpa2UgYW4gYXJyYXkgb2YgdHlwZWQgc3RydWN0cy5cbiAqXG4gKiBDb25jZXB0dWFsbHksIGEgU3RydWN0QXJyYXkgaXMgY29tcHJpc2VkIG9mIGVsZW1lbnRzLCBpLmUuLCBpbnN0YW5jZXMgb2YgaXRzXG4gKiBhc3NvY2lhdGVkIHN0cnVjdCB0eXBlLiBFYWNoIHBhcnRpY3VsYXIgc3RydWN0IHR5cGUsIHRvZ2V0aGVyIHdpdGggYW5cbiAqIGFsaWdubWVudCBzaXplLCBkZXRlcm1pbmVzIHRoZSBtZW1vcnkgbGF5b3V0IG9mIGEgU3RydWN0QXJyYXkgd2hvc2UgZWxlbWVudHNcbiAqIGFyZSBvZiB0aGF0IHR5cGUuICBUaHVzLCBmb3IgZWFjaCBzdWNoIGxheW91dCB0aGF0IHdlIG5lZWQsIHdlIGhhdmVcbiAqIGEgY29ycnNlcG9uZGluZyBTdHJ1Y3RBcnJheUxheW91dCBjbGFzcywgaW5oZXJpdGluZyBmcm9tIFN0cnVjdEFycmF5IGFuZFxuICogaW1wbGVtZW50aW5nIGBlbXBsYWNlQmFjaygpYCBhbmQgYF9yZWZyZXNoVmlld3MoKWAuXG4gKlxuICogSW4gc29tZSBjYXNlcywgd2hlcmUgd2UgbmVlZCB0byBhY2Nlc3MgcGFydGljdWxhciBlbGVtZW50cyBvZiBhIFN0cnVjdEFycmF5LFxuICogd2UgaW1wbGVtZW50IGEgbW9yZSBzcGVjaWZpYyBzdWJjbGFzcyB0aGF0IGluaGVyaXRzIGZyb20gb25lIG9mIHRoZVxuICogU3RydWN0QXJyYXlMYXlvdXRzIGFuZCBhZGRzIGEgYGdldChpKTogVGAgYWNjZXNzb3IgdGhhdCByZXR1cm5zIGEgc3RydWN0dXJlZFxuICogb2JqZWN0IHdob3NlIHByb3BlcnRpZXMgYXJlIHByb3hpZXMgaW50byB0aGUgdW5kZXJseWluZyBtZW1vcnkgc3BhY2UgZm9yIHRoZVxuICogaS10aCBlbGVtZW50LiAgVGhpcyBhZmZvcmRzIHRoZSBjb252aWVuY2Ugb2Ygd29ya2luZyB3aXRoIChzZWVtaW5nbHkpIHBsYWluXG4gKiBKYXZhc2NyaXB0IG9iamVjdHMgd2l0aG91dCB0aGUgb3ZlcmhlYWQgb2Ygc2VyaWFsaXppbmcvZGVzZXJpYWxpemluZyB0aGVtXG4gKiBpbnRvIEFycmF5QnVmZmVycyBmb3IgZWZmaWNpZW50IHdlYiB3b3JrZXIgdHJhbnNmZXIuXG4gKlxuICogQHByaXZhdGVcbiAqL1xuY2xhc3MgU3RydWN0QXJyYXkge1xuICAgIGNhcGFjaXR5OiBudW1iZXI7XG4gICAgbGVuZ3RoOiBudW1iZXI7XG4gICAgaXNUcmFuc2ZlcnJlZDogYm9vbGVhbjtcbiAgICBhcnJheUJ1ZmZlcjogQXJyYXlCdWZmZXI7XG4gICAgdWludDg6IFVpbnQ4QXJyYXk7XG5cbiAgICAvLyBUaGUgZm9sbG93aW5nIHByb3BlcnRpZXMgYXJlIGRlZmluZWQgb24gdGhlIHByb3RvdHlwZS5cbiAgICBtZW1iZXJzOiBBcnJheTxTdHJ1Y3RBcnJheU1lbWJlcj47XG4gICAgYnl0ZXNQZXJFbGVtZW50OiBudW1iZXI7XG4gICAgK2VtcGxhY2VCYWNrOiBGdW5jdGlvbjtcbiAgICArZW1wbGFjZTogRnVuY3Rpb247XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5pc1RyYW5zZmVycmVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuY2FwYWNpdHkgPSAtMTtcbiAgICAgICAgdGhpcy5yZXNpemUoMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VyaWFsaXplIGEgU3RydWN0QXJyYXkgaW5zdGFuY2UuICBTZXJpYWxpemVzIGJvdGggdGhlIHJhdyBkYXRhIGFuZCB0aGVcbiAgICAgKiBtZXRhZGF0YSBuZWVkZWQgdG8gcmVjb25zdHJ1Y3QgdGhlIFN0cnVjdEFycmF5IGJhc2UgY2xhc3MgZHVyaW5nXG4gICAgICogZGVzZXJpYWxpemF0aW9uLlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIHNlcmlhbGl6ZShhcnJheTogU3RydWN0QXJyYXksIHRyYW5zZmVyYWJsZXM/OiBBcnJheTxUcmFuc2ZlcmFibGU+KTogU2VyaWFsaXplZFN0cnVjdEFycmF5IHtcbiAgICAgICAgYXNzZXJ0KCFhcnJheS5pc1RyYW5zZmVycmVkKTtcblxuICAgICAgICBhcnJheS5fdHJpbSgpO1xuXG4gICAgICAgIGlmICh0cmFuc2ZlcmFibGVzKSB7XG4gICAgICAgICAgICBhcnJheS5pc1RyYW5zZmVycmVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRyYW5zZmVyYWJsZXMucHVzaChhcnJheS5hcnJheUJ1ZmZlcik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbGVuZ3RoOiBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgICBhcnJheUJ1ZmZlcjogYXJyYXkuYXJyYXlCdWZmZXIsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgc3RhdGljIGRlc2VyaWFsaXplKGlucHV0OiBTZXJpYWxpemVkU3RydWN0QXJyYXkpOiBTdHJ1Y3RBcnJheSB7XG4gICAgICAgIC8vICRGbG93Rml4TWUgbm90LWFuLW9iamVjdCAtIG5ld2VyIEZsb3cgZG9lc24ndCB1bmRlcnN0YW5kIHRoaXMgcGF0dGVybiwgc2lsZW5jZSBmb3Igbm93XG4gICAgICAgIGNvbnN0IHN0cnVjdEFycmF5OiB7W186IHN0cmluZ106IGFueX0gPSBPYmplY3QuY3JlYXRlKHRoaXMucHJvdG90eXBlKTtcbiAgICAgICAgc3RydWN0QXJyYXkuYXJyYXlCdWZmZXIgPSBpbnB1dC5hcnJheUJ1ZmZlcjtcbiAgICAgICAgc3RydWN0QXJyYXkubGVuZ3RoID0gaW5wdXQubGVuZ3RoO1xuICAgICAgICBzdHJ1Y3RBcnJheS5jYXBhY2l0eSA9IGlucHV0LmFycmF5QnVmZmVyLmJ5dGVMZW5ndGggLyBzdHJ1Y3RBcnJheS5ieXRlc1BlckVsZW1lbnQ7XG4gICAgICAgIHN0cnVjdEFycmF5Ll9yZWZyZXNoVmlld3MoKTtcbiAgICAgICAgcmV0dXJuICgoc3RydWN0QXJyYXk6IGFueSk6IFN0cnVjdEFycmF5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXNpemUgdGhlIGFycmF5IHRvIGRpc2NhcmQgdW51c2VkIGNhcGFjaXR5LlxuICAgICAqL1xuICAgIF90cmltKCkge1xuICAgICAgICBpZiAodGhpcy5sZW5ndGggIT09IHRoaXMuY2FwYWNpdHkpIHtcbiAgICAgICAgICAgIHRoaXMuY2FwYWNpdHkgPSB0aGlzLmxlbmd0aDtcbiAgICAgICAgICAgIHRoaXMuYXJyYXlCdWZmZXIgPSB0aGlzLmFycmF5QnVmZmVyLnNsaWNlKDAsIHRoaXMubGVuZ3RoICogdGhpcy5ieXRlc1BlckVsZW1lbnQpO1xuICAgICAgICAgICAgdGhpcy5fcmVmcmVzaFZpZXdzKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXNldHMgdGhlIHRoZSBsZW5ndGggb2YgdGhlIGFycmF5IHRvIDAgd2l0aG91dCBkZS1hbGxvY2F0aW5nIGNhcGNhY2l0eS5cbiAgICAgKi9cbiAgICBjbGVhcigpIHtcbiAgICAgICAgdGhpcy5sZW5ndGggPSAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc2l6ZSB0aGUgYXJyYXkuXG4gICAgICogSWYgYG5gIGlzIGdyZWF0ZXIgdGhhbiB0aGUgY3VycmVudCBsZW5ndGggdGhlbiBhZGRpdGlvbmFsIGVsZW1lbnRzIHdpdGggdW5kZWZpbmVkIHZhbHVlcyBhcmUgYWRkZWQuXG4gICAgICogSWYgYG5gIGlzIGxlc3MgdGhhbiB0aGUgY3VycmVudCBsZW5ndGggdGhlbiB0aGUgYXJyYXkgd2lsbCBiZSByZWR1Y2VkIHRvIHRoZSBmaXJzdCBgbmAgZWxlbWVudHMuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG5ldyBzaXplIG9mIHRoZSBhcnJheS5cbiAgICAgKi9cbiAgICByZXNpemUobjogbnVtYmVyKSB7XG4gICAgICAgIGFzc2VydCghdGhpcy5pc1RyYW5zZmVycmVkKTtcbiAgICAgICAgdGhpcy5yZXNlcnZlKG4pO1xuICAgICAgICB0aGlzLmxlbmd0aCA9IG47XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW5kaWNhdGUgYSBwbGFubmVkIGluY3JlYXNlIGluIHNpemUsIHNvIHRoYXQgYW55IG5lY2Vzc2FyeSBhbGxvY2F0aW9uIG1heVxuICAgICAqIGJlIGRvbmUgb25jZSwgYWhlYWQgb2YgdGltZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbiBUaGUgZXhwZWN0ZWQgc2l6ZSBvZiB0aGUgYXJyYXkuXG4gICAgICovXG4gICAgcmVzZXJ2ZShuOiBudW1iZXIpIHtcbiAgICAgICAgaWYgKG4gPiB0aGlzLmNhcGFjaXR5KSB7XG4gICAgICAgICAgICB0aGlzLmNhcGFjaXR5ID0gTWF0aC5tYXgobiwgTWF0aC5mbG9vcih0aGlzLmNhcGFjaXR5ICogUkVTSVpFX01VTFRJUExJRVIpLCBERUZBVUxUX0NBUEFDSVRZKTtcbiAgICAgICAgICAgIHRoaXMuYXJyYXlCdWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIodGhpcy5jYXBhY2l0eSAqIHRoaXMuYnl0ZXNQZXJFbGVtZW50KTtcblxuICAgICAgICAgICAgY29uc3Qgb2xkVWludDhBcnJheSA9IHRoaXMudWludDg7XG4gICAgICAgICAgICB0aGlzLl9yZWZyZXNoVmlld3MoKTtcbiAgICAgICAgICAgIGlmIChvbGRVaW50OEFycmF5KSB0aGlzLnVpbnQ4LnNldChvbGRVaW50OEFycmF5KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBUeXBlZEFycmF5IHZpZXdzIGZvciB0aGUgY3VycmVudCBBcnJheUJ1ZmZlci5cbiAgICAgKi9cbiAgICBfcmVmcmVzaFZpZXdzKCk6IHZvaWQge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ19yZWZyZXNoVmlld3MoKSBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IGVhY2ggY29uY3JldGUgU3RydWN0QXJyYXkgbGF5b3V0Jyk7XG4gICAgfVxuXG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVxuICAgICAgICB0aGlzLmludDggPSB0aGlzLnVpbnQ4ID0gdGhpcy5pbnQxNiA9IHRoaXMudWludDE2ID0gdGhpcy5pbnQzMiA9IHRoaXMudWludDMyID0gdGhpcy5mbG9hdDMyID0gbnVsbDtcbiAgICAgICAgdGhpcy5hcnJheUJ1ZmZlciA9IChudWxsOiBhbnkpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBHaXZlbiBhIGxpc3Qgb2YgbWVtYmVyIGZpZWxkcywgY3JlYXRlIGEgZnVsbCBTdHJ1Y3RBcnJheUxheW91dCwgaW5cbiAqIHBhcnRpY3VsYXIgY2FsY3VsYXRpbmcgdGhlIGNvcnJlY3QgYnl0ZSBvZmZzZXQgZm9yIGVhY2ggZmllbGQuICBUaGlzIGRhdGFcbiAqIGlzIHVzZWQgYXQgYnVpbGQgdGltZSB0byBnZW5lcmF0ZSBTdHJ1Y3RBcnJheUxheW91dF8qI2VtcGxhY2VCYWNrKCkgYW5kXG4gKiBvdGhlciBhY2Nlc3NvcnMsIGFuZCBhdCBydW50aW1lIGZvciBiaW5kaW5nIHZlcnRleCBidWZmZXIgYXR0cmlidXRlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBjcmVhdGVMYXlvdXQoXG4gICAgbWVtYmVyczogQXJyYXk8eyBuYW1lOiBzdHJpbmcsIHR5cGU6IFZpZXdUeXBlLCArY29tcG9uZW50cz86IG51bWJlciwgfT4sXG4gICAgYWxpZ25tZW50OiBudW1iZXIgPSAxXG4pOiBTdHJ1Y3RBcnJheUxheW91dCB7XG5cbiAgICBsZXQgb2Zmc2V0ID0gMDtcbiAgICBsZXQgbWF4U2l6ZSA9IDA7XG4gICAgY29uc3QgbGF5b3V0TWVtYmVycyA9IG1lbWJlcnMubWFwKChtZW1iZXIpID0+IHtcbiAgICAgICAgYXNzZXJ0KG1lbWJlci5uYW1lLmxlbmd0aCk7XG4gICAgICAgIGNvbnN0IHR5cGVTaXplID0gc2l6ZU9mKG1lbWJlci50eXBlKTtcbiAgICAgICAgY29uc3QgbWVtYmVyT2Zmc2V0ID0gb2Zmc2V0ID0gYWxpZ24ob2Zmc2V0LCBNYXRoLm1heChhbGlnbm1lbnQsIHR5cGVTaXplKSk7XG4gICAgICAgIGNvbnN0IGNvbXBvbmVudHMgPSBtZW1iZXIuY29tcG9uZW50cyB8fCAxO1xuXG4gICAgICAgIG1heFNpemUgPSBNYXRoLm1heChtYXhTaXplLCB0eXBlU2l6ZSk7XG4gICAgICAgIG9mZnNldCArPSB0eXBlU2l6ZSAqIGNvbXBvbmVudHM7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG5hbWU6IG1lbWJlci5uYW1lLFxuICAgICAgICAgICAgdHlwZTogbWVtYmVyLnR5cGUsXG4gICAgICAgICAgICBjb21wb25lbnRzLFxuICAgICAgICAgICAgb2Zmc2V0OiBtZW1iZXJPZmZzZXQsXG4gICAgICAgIH07XG4gICAgfSk7XG5cbiAgICBjb25zdCBzaXplID0gYWxpZ24ob2Zmc2V0LCBNYXRoLm1heChtYXhTaXplLCBhbGlnbm1lbnQpKTtcblxuICAgIHJldHVybiB7XG4gICAgICAgIG1lbWJlcnM6IGxheW91dE1lbWJlcnMsXG4gICAgICAgIHNpemUsXG4gICAgICAgIGFsaWdubWVudFxuICAgIH07XG59XG5cbmZ1bmN0aW9uIHNpemVPZih0eXBlOiBWaWV3VHlwZSk6IG51bWJlciB7XG4gICAgcmV0dXJuIHZpZXdUeXBlc1t0eXBlXS5CWVRFU19QRVJfRUxFTUVOVDtcbn1cblxuZnVuY3Rpb24gYWxpZ24ob2Zmc2V0OiBudW1iZXIsIHNpemU6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIE1hdGguY2VpbChvZmZzZXQgLyBzaXplKSAqIHNpemU7XG59XG5cbmV4cG9ydCB7U3RydWN0QXJyYXksIFN0cnVjdCwgdmlld1R5cGVzLCBjcmVhdGVMYXlvdXR9O1xuIiwiLy8gVGhpcyBmaWxlIGlzIGdlbmVyYXRlZC4gRWRpdCBidWlsZC9nZW5lcmF0ZS1zdHJ1Y3QtYXJyYXlzLmpzLCB0aGVuIHJ1biBgeWFybiBydW4gY29kZWdlbmAuXG4vKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8vIEBmbG93XG5cbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCB7U3RydWN0LCBTdHJ1Y3RBcnJheX0gZnJvbSAnLi4vdXRpbC9zdHJ1Y3RfYXJyYXkuanMnO1xuaW1wb3J0IHtyZWdpc3Rlcn0gZnJvbSAnLi4vdXRpbC93ZWJfd29ya2VyX3RyYW5zZmVyLmpzJztcblxuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU3RydWN0QXJyYXkgbGF5b3V0OlxuICogWzBdOiBJbnQxNlsyXVxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmNsYXNzIFN0cnVjdEFycmF5TGF5b3V0Mmk0IGV4dGVuZHMgU3RydWN0QXJyYXkge1xuICAgIHVpbnQ4OiBVaW50OEFycmF5O1xuICAgIGludDE2OiBJbnQxNkFycmF5O1xuXG4gICAgX3JlZnJlc2hWaWV3cygpIHtcbiAgICAgICAgdGhpcy51aW50OCA9IG5ldyBVaW50OEFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgICAgICB0aGlzLmludDE2ID0gbmV3IEludDE2QXJyYXkodGhpcy5hcnJheUJ1ZmZlcik7XG4gICAgfVxuXG4gICAgZW1wbGFjZUJhY2sodjA6IG51bWJlciwgdjE6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IGkgPSB0aGlzLmxlbmd0aDtcbiAgICAgICAgdGhpcy5yZXNpemUoaSArIDEpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbXBsYWNlKGksIHYwLCB2MSk7XG4gICAgfVxuXG4gICAgZW1wbGFjZShpOiBudW1iZXIsIHYwOiBudW1iZXIsIHYxOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBvMiA9IGkgKiAyO1xuICAgICAgICB0aGlzLmludDE2W28yICsgMF0gPSB2MDtcbiAgICAgICAgdGhpcy5pbnQxNltvMiArIDFdID0gdjE7XG4gICAgICAgIHJldHVybiBpO1xuICAgIH1cbn1cblxuU3RydWN0QXJyYXlMYXlvdXQyaTQucHJvdG90eXBlLmJ5dGVzUGVyRWxlbWVudCA9IDQ7XG5yZWdpc3RlcihTdHJ1Y3RBcnJheUxheW91dDJpNCwgJ1N0cnVjdEFycmF5TGF5b3V0Mmk0Jyk7XG5cbi8qKlxuICogSW1wbGVtZW50YXRpb24gb2YgdGhlIFN0cnVjdEFycmF5IGxheW91dDpcbiAqIFswXTogSW50MTZbM11cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5jbGFzcyBTdHJ1Y3RBcnJheUxheW91dDNpNiBleHRlbmRzIFN0cnVjdEFycmF5IHtcbiAgICB1aW50ODogVWludDhBcnJheTtcbiAgICBpbnQxNjogSW50MTZBcnJheTtcblxuICAgIF9yZWZyZXNoVmlld3MoKSB7XG4gICAgICAgIHRoaXMudWludDggPSBuZXcgVWludDhBcnJheSh0aGlzLmFycmF5QnVmZmVyKTtcbiAgICAgICAgdGhpcy5pbnQxNiA9IG5ldyBJbnQxNkFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgIH1cblxuICAgIGVtcGxhY2VCYWNrKHYwOiBudW1iZXIsIHYxOiBudW1iZXIsIHYyOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBpID0gdGhpcy5sZW5ndGg7XG4gICAgICAgIHRoaXMucmVzaXplKGkgKyAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1wbGFjZShpLCB2MCwgdjEsIHYyKTtcbiAgICB9XG5cbiAgICBlbXBsYWNlKGk6IG51bWJlciwgdjA6IG51bWJlciwgdjE6IG51bWJlciwgdjI6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IG8yID0gaSAqIDM7XG4gICAgICAgIHRoaXMuaW50MTZbbzIgKyAwXSA9IHYwO1xuICAgICAgICB0aGlzLmludDE2W28yICsgMV0gPSB2MTtcbiAgICAgICAgdGhpcy5pbnQxNltvMiArIDJdID0gdjI7XG4gICAgICAgIHJldHVybiBpO1xuICAgIH1cbn1cblxuU3RydWN0QXJyYXlMYXlvdXQzaTYucHJvdG90eXBlLmJ5dGVzUGVyRWxlbWVudCA9IDY7XG5yZWdpc3RlcihTdHJ1Y3RBcnJheUxheW91dDNpNiwgJ1N0cnVjdEFycmF5TGF5b3V0M2k2Jyk7XG5cbi8qKlxuICogSW1wbGVtZW50YXRpb24gb2YgdGhlIFN0cnVjdEFycmF5IGxheW91dDpcbiAqIFswXTogSW50MTZbNF1cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5jbGFzcyBTdHJ1Y3RBcnJheUxheW91dDRpOCBleHRlbmRzIFN0cnVjdEFycmF5IHtcbiAgICB1aW50ODogVWludDhBcnJheTtcbiAgICBpbnQxNjogSW50MTZBcnJheTtcblxuICAgIF9yZWZyZXNoVmlld3MoKSB7XG4gICAgICAgIHRoaXMudWludDggPSBuZXcgVWludDhBcnJheSh0aGlzLmFycmF5QnVmZmVyKTtcbiAgICAgICAgdGhpcy5pbnQxNiA9IG5ldyBJbnQxNkFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgIH1cblxuICAgIGVtcGxhY2VCYWNrKHYwOiBudW1iZXIsIHYxOiBudW1iZXIsIHYyOiBudW1iZXIsIHYzOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBpID0gdGhpcy5sZW5ndGg7XG4gICAgICAgIHRoaXMucmVzaXplKGkgKyAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1wbGFjZShpLCB2MCwgdjEsIHYyLCB2Myk7XG4gICAgfVxuXG4gICAgZW1wbGFjZShpOiBudW1iZXIsIHYwOiBudW1iZXIsIHYxOiBudW1iZXIsIHYyOiBudW1iZXIsIHYzOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBvMiA9IGkgKiA0O1xuICAgICAgICB0aGlzLmludDE2W28yICsgMF0gPSB2MDtcbiAgICAgICAgdGhpcy5pbnQxNltvMiArIDFdID0gdjE7XG4gICAgICAgIHRoaXMuaW50MTZbbzIgKyAyXSA9IHYyO1xuICAgICAgICB0aGlzLmludDE2W28yICsgM10gPSB2MztcbiAgICAgICAgcmV0dXJuIGk7XG4gICAgfVxufVxuXG5TdHJ1Y3RBcnJheUxheW91dDRpOC5wcm90b3R5cGUuYnl0ZXNQZXJFbGVtZW50ID0gODtcbnJlZ2lzdGVyKFN0cnVjdEFycmF5TGF5b3V0NGk4LCAnU3RydWN0QXJyYXlMYXlvdXQ0aTgnKTtcblxuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU3RydWN0QXJyYXkgbGF5b3V0OlxuICogWzBdOiBJbnQxNlsyXVxuICogWzRdOiBVaW50OFs0XVxuICogWzhdOiBGbG9hdDMyWzFdXG4gKlxuICogQHByaXZhdGVcbiAqL1xuY2xhc3MgU3RydWN0QXJyYXlMYXlvdXQyaTR1YjFmMTIgZXh0ZW5kcyBTdHJ1Y3RBcnJheSB7XG4gICAgdWludDg6IFVpbnQ4QXJyYXk7XG4gICAgaW50MTY6IEludDE2QXJyYXk7XG4gICAgZmxvYXQzMjogRmxvYXQzMkFycmF5O1xuXG4gICAgX3JlZnJlc2hWaWV3cygpIHtcbiAgICAgICAgdGhpcy51aW50OCA9IG5ldyBVaW50OEFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgICAgICB0aGlzLmludDE2ID0gbmV3IEludDE2QXJyYXkodGhpcy5hcnJheUJ1ZmZlcik7XG4gICAgICAgIHRoaXMuZmxvYXQzMiA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5hcnJheUJ1ZmZlcik7XG4gICAgfVxuXG4gICAgZW1wbGFjZUJhY2sodjA6IG51bWJlciwgdjE6IG51bWJlciwgdjI6IG51bWJlciwgdjM6IG51bWJlciwgdjQ6IG51bWJlciwgdjU6IG51bWJlciwgdjY6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IGkgPSB0aGlzLmxlbmd0aDtcbiAgICAgICAgdGhpcy5yZXNpemUoaSArIDEpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbXBsYWNlKGksIHYwLCB2MSwgdjIsIHYzLCB2NCwgdjUsIHY2KTtcbiAgICB9XG5cbiAgICBlbXBsYWNlKGk6IG51bWJlciwgdjA6IG51bWJlciwgdjE6IG51bWJlciwgdjI6IG51bWJlciwgdjM6IG51bWJlciwgdjQ6IG51bWJlciwgdjU6IG51bWJlciwgdjY6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IG8yID0gaSAqIDY7XG4gICAgICAgIGNvbnN0IG8xID0gaSAqIDEyO1xuICAgICAgICBjb25zdCBvNCA9IGkgKiAzO1xuICAgICAgICB0aGlzLmludDE2W28yICsgMF0gPSB2MDtcbiAgICAgICAgdGhpcy5pbnQxNltvMiArIDFdID0gdjE7XG4gICAgICAgIHRoaXMudWludDhbbzEgKyA0XSA9IHYyO1xuICAgICAgICB0aGlzLnVpbnQ4W28xICsgNV0gPSB2MztcbiAgICAgICAgdGhpcy51aW50OFtvMSArIDZdID0gdjQ7XG4gICAgICAgIHRoaXMudWludDhbbzEgKyA3XSA9IHY1O1xuICAgICAgICB0aGlzLmZsb2F0MzJbbzQgKyAyXSA9IHY2O1xuICAgICAgICByZXR1cm4gaTtcbiAgICB9XG59XG5cblN0cnVjdEFycmF5TGF5b3V0Mmk0dWIxZjEyLnByb3RvdHlwZS5ieXRlc1BlckVsZW1lbnQgPSAxMjtcbnJlZ2lzdGVyKFN0cnVjdEFycmF5TGF5b3V0Mmk0dWIxZjEyLCAnU3RydWN0QXJyYXlMYXlvdXQyaTR1YjFmMTInKTtcblxuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU3RydWN0QXJyYXkgbGF5b3V0OlxuICogWzBdOiBGbG9hdDMyWzRdXG4gKlxuICogQHByaXZhdGVcbiAqL1xuY2xhc3MgU3RydWN0QXJyYXlMYXlvdXQ0ZjE2IGV4dGVuZHMgU3RydWN0QXJyYXkge1xuICAgIHVpbnQ4OiBVaW50OEFycmF5O1xuICAgIGZsb2F0MzI6IEZsb2F0MzJBcnJheTtcblxuICAgIF9yZWZyZXNoVmlld3MoKSB7XG4gICAgICAgIHRoaXMudWludDggPSBuZXcgVWludDhBcnJheSh0aGlzLmFycmF5QnVmZmVyKTtcbiAgICAgICAgdGhpcy5mbG9hdDMyID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmFycmF5QnVmZmVyKTtcbiAgICB9XG5cbiAgICBlbXBsYWNlQmFjayh2MDogbnVtYmVyLCB2MTogbnVtYmVyLCB2MjogbnVtYmVyLCB2MzogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgaSA9IHRoaXMubGVuZ3RoO1xuICAgICAgICB0aGlzLnJlc2l6ZShpICsgMSk7XG4gICAgICAgIHJldHVybiB0aGlzLmVtcGxhY2UoaSwgdjAsIHYxLCB2MiwgdjMpO1xuICAgIH1cblxuICAgIGVtcGxhY2UoaTogbnVtYmVyLCB2MDogbnVtYmVyLCB2MTogbnVtYmVyLCB2MjogbnVtYmVyLCB2MzogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgbzQgPSBpICogNDtcbiAgICAgICAgdGhpcy5mbG9hdDMyW280ICsgMF0gPSB2MDtcbiAgICAgICAgdGhpcy5mbG9hdDMyW280ICsgMV0gPSB2MTtcbiAgICAgICAgdGhpcy5mbG9hdDMyW280ICsgMl0gPSB2MjtcbiAgICAgICAgdGhpcy5mbG9hdDMyW280ICsgM10gPSB2MztcbiAgICAgICAgcmV0dXJuIGk7XG4gICAgfVxufVxuXG5TdHJ1Y3RBcnJheUxheW91dDRmMTYucHJvdG90eXBlLmJ5dGVzUGVyRWxlbWVudCA9IDE2O1xucmVnaXN0ZXIoU3RydWN0QXJyYXlMYXlvdXQ0ZjE2LCAnU3RydWN0QXJyYXlMYXlvdXQ0ZjE2Jyk7XG5cbi8qKlxuICogSW1wbGVtZW50YXRpb24gb2YgdGhlIFN0cnVjdEFycmF5IGxheW91dDpcbiAqIFswXTogVWludDE2WzRdXG4gKiBbOF06IEZsb2F0MzJbMV1cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5jbGFzcyBTdHJ1Y3RBcnJheUxheW91dDR1aTFmMTIgZXh0ZW5kcyBTdHJ1Y3RBcnJheSB7XG4gICAgdWludDg6IFVpbnQ4QXJyYXk7XG4gICAgdWludDE2OiBVaW50MTZBcnJheTtcbiAgICBmbG9hdDMyOiBGbG9hdDMyQXJyYXk7XG5cbiAgICBfcmVmcmVzaFZpZXdzKCkge1xuICAgICAgICB0aGlzLnVpbnQ4ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5hcnJheUJ1ZmZlcik7XG4gICAgICAgIHRoaXMudWludDE2ID0gbmV3IFVpbnQxNkFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgICAgICB0aGlzLmZsb2F0MzIgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgIH1cblxuICAgIGVtcGxhY2VCYWNrKHYwOiBudW1iZXIsIHYxOiBudW1iZXIsIHYyOiBudW1iZXIsIHYzOiBudW1iZXIsIHY0OiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBpID0gdGhpcy5sZW5ndGg7XG4gICAgICAgIHRoaXMucmVzaXplKGkgKyAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1wbGFjZShpLCB2MCwgdjEsIHYyLCB2MywgdjQpO1xuICAgIH1cblxuICAgIGVtcGxhY2UoaTogbnVtYmVyLCB2MDogbnVtYmVyLCB2MTogbnVtYmVyLCB2MjogbnVtYmVyLCB2MzogbnVtYmVyLCB2NDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgbzIgPSBpICogNjtcbiAgICAgICAgY29uc3QgbzQgPSBpICogMztcbiAgICAgICAgdGhpcy51aW50MTZbbzIgKyAwXSA9IHYwO1xuICAgICAgICB0aGlzLnVpbnQxNltvMiArIDFdID0gdjE7XG4gICAgICAgIHRoaXMudWludDE2W28yICsgMl0gPSB2MjtcbiAgICAgICAgdGhpcy51aW50MTZbbzIgKyAzXSA9IHYzO1xuICAgICAgICB0aGlzLmZsb2F0MzJbbzQgKyAyXSA9IHY0O1xuICAgICAgICByZXR1cm4gaTtcbiAgICB9XG59XG5cblN0cnVjdEFycmF5TGF5b3V0NHVpMWYxMi5wcm90b3R5cGUuYnl0ZXNQZXJFbGVtZW50ID0gMTI7XG5yZWdpc3RlcihTdHJ1Y3RBcnJheUxheW91dDR1aTFmMTIsICdTdHJ1Y3RBcnJheUxheW91dDR1aTFmMTInKTtcblxuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU3RydWN0QXJyYXkgbGF5b3V0OlxuICogWzBdOiBVaW50MTZbNF1cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5jbGFzcyBTdHJ1Y3RBcnJheUxheW91dDR1aTggZXh0ZW5kcyBTdHJ1Y3RBcnJheSB7XG4gICAgdWludDg6IFVpbnQ4QXJyYXk7XG4gICAgdWludDE2OiBVaW50MTZBcnJheTtcblxuICAgIF9yZWZyZXNoVmlld3MoKSB7XG4gICAgICAgIHRoaXMudWludDggPSBuZXcgVWludDhBcnJheSh0aGlzLmFycmF5QnVmZmVyKTtcbiAgICAgICAgdGhpcy51aW50MTYgPSBuZXcgVWludDE2QXJyYXkodGhpcy5hcnJheUJ1ZmZlcik7XG4gICAgfVxuXG4gICAgZW1wbGFjZUJhY2sodjA6IG51bWJlciwgdjE6IG51bWJlciwgdjI6IG51bWJlciwgdjM6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IGkgPSB0aGlzLmxlbmd0aDtcbiAgICAgICAgdGhpcy5yZXNpemUoaSArIDEpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbXBsYWNlKGksIHYwLCB2MSwgdjIsIHYzKTtcbiAgICB9XG5cbiAgICBlbXBsYWNlKGk6IG51bWJlciwgdjA6IG51bWJlciwgdjE6IG51bWJlciwgdjI6IG51bWJlciwgdjM6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IG8yID0gaSAqIDQ7XG4gICAgICAgIHRoaXMudWludDE2W28yICsgMF0gPSB2MDtcbiAgICAgICAgdGhpcy51aW50MTZbbzIgKyAxXSA9IHYxO1xuICAgICAgICB0aGlzLnVpbnQxNltvMiArIDJdID0gdjI7XG4gICAgICAgIHRoaXMudWludDE2W28yICsgM10gPSB2MztcbiAgICAgICAgcmV0dXJuIGk7XG4gICAgfVxufVxuXG5TdHJ1Y3RBcnJheUxheW91dDR1aTgucHJvdG90eXBlLmJ5dGVzUGVyRWxlbWVudCA9IDg7XG5yZWdpc3RlcihTdHJ1Y3RBcnJheUxheW91dDR1aTgsICdTdHJ1Y3RBcnJheUxheW91dDR1aTgnKTtcblxuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU3RydWN0QXJyYXkgbGF5b3V0OlxuICogWzBdOiBJbnQxNls2XVxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmNsYXNzIFN0cnVjdEFycmF5TGF5b3V0NmkxMiBleHRlbmRzIFN0cnVjdEFycmF5IHtcbiAgICB1aW50ODogVWludDhBcnJheTtcbiAgICBpbnQxNjogSW50MTZBcnJheTtcblxuICAgIF9yZWZyZXNoVmlld3MoKSB7XG4gICAgICAgIHRoaXMudWludDggPSBuZXcgVWludDhBcnJheSh0aGlzLmFycmF5QnVmZmVyKTtcbiAgICAgICAgdGhpcy5pbnQxNiA9IG5ldyBJbnQxNkFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgIH1cblxuICAgIGVtcGxhY2VCYWNrKHYwOiBudW1iZXIsIHYxOiBudW1iZXIsIHYyOiBudW1iZXIsIHYzOiBudW1iZXIsIHY0OiBudW1iZXIsIHY1OiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBpID0gdGhpcy5sZW5ndGg7XG4gICAgICAgIHRoaXMucmVzaXplKGkgKyAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1wbGFjZShpLCB2MCwgdjEsIHYyLCB2MywgdjQsIHY1KTtcbiAgICB9XG5cbiAgICBlbXBsYWNlKGk6IG51bWJlciwgdjA6IG51bWJlciwgdjE6IG51bWJlciwgdjI6IG51bWJlciwgdjM6IG51bWJlciwgdjQ6IG51bWJlciwgdjU6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IG8yID0gaSAqIDY7XG4gICAgICAgIHRoaXMuaW50MTZbbzIgKyAwXSA9IHYwO1xuICAgICAgICB0aGlzLmludDE2W28yICsgMV0gPSB2MTtcbiAgICAgICAgdGhpcy5pbnQxNltvMiArIDJdID0gdjI7XG4gICAgICAgIHRoaXMuaW50MTZbbzIgKyAzXSA9IHYzO1xuICAgICAgICB0aGlzLmludDE2W28yICsgNF0gPSB2NDtcbiAgICAgICAgdGhpcy5pbnQxNltvMiArIDVdID0gdjU7XG4gICAgICAgIHJldHVybiBpO1xuICAgIH1cbn1cblxuU3RydWN0QXJyYXlMYXlvdXQ2aTEyLnByb3RvdHlwZS5ieXRlc1BlckVsZW1lbnQgPSAxMjtcbnJlZ2lzdGVyKFN0cnVjdEFycmF5TGF5b3V0NmkxMiwgJ1N0cnVjdEFycmF5TGF5b3V0NmkxMicpO1xuXG4vKipcbiAqIEltcGxlbWVudGF0aW9uIG9mIHRoZSBTdHJ1Y3RBcnJheSBsYXlvdXQ6XG4gKiBbMF06IEludDE2WzRdXG4gKiBbOF06IFVpbnQxNls0XVxuICogWzE2XTogSW50MTZbNF1cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5jbGFzcyBTdHJ1Y3RBcnJheUxheW91dDRpNHVpNGkyNCBleHRlbmRzIFN0cnVjdEFycmF5IHtcbiAgICB1aW50ODogVWludDhBcnJheTtcbiAgICBpbnQxNjogSW50MTZBcnJheTtcbiAgICB1aW50MTY6IFVpbnQxNkFycmF5O1xuXG4gICAgX3JlZnJlc2hWaWV3cygpIHtcbiAgICAgICAgdGhpcy51aW50OCA9IG5ldyBVaW50OEFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgICAgICB0aGlzLmludDE2ID0gbmV3IEludDE2QXJyYXkodGhpcy5hcnJheUJ1ZmZlcik7XG4gICAgICAgIHRoaXMudWludDE2ID0gbmV3IFVpbnQxNkFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgIH1cblxuICAgIGVtcGxhY2VCYWNrKHYwOiBudW1iZXIsIHYxOiBudW1iZXIsIHYyOiBudW1iZXIsIHYzOiBudW1iZXIsIHY0OiBudW1iZXIsIHY1OiBudW1iZXIsIHY2OiBudW1iZXIsIHY3OiBudW1iZXIsIHY4OiBudW1iZXIsIHY5OiBudW1iZXIsIHYxMDogbnVtYmVyLCB2MTE6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IGkgPSB0aGlzLmxlbmd0aDtcbiAgICAgICAgdGhpcy5yZXNpemUoaSArIDEpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbXBsYWNlKGksIHYwLCB2MSwgdjIsIHYzLCB2NCwgdjUsIHY2LCB2NywgdjgsIHY5LCB2MTAsIHYxMSk7XG4gICAgfVxuXG4gICAgZW1wbGFjZShpOiBudW1iZXIsIHYwOiBudW1iZXIsIHYxOiBudW1iZXIsIHYyOiBudW1iZXIsIHYzOiBudW1iZXIsIHY0OiBudW1iZXIsIHY1OiBudW1iZXIsIHY2OiBudW1iZXIsIHY3OiBudW1iZXIsIHY4OiBudW1iZXIsIHY5OiBudW1iZXIsIHYxMDogbnVtYmVyLCB2MTE6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IG8yID0gaSAqIDEyO1xuICAgICAgICB0aGlzLmludDE2W28yICsgMF0gPSB2MDtcbiAgICAgICAgdGhpcy5pbnQxNltvMiArIDFdID0gdjE7XG4gICAgICAgIHRoaXMuaW50MTZbbzIgKyAyXSA9IHYyO1xuICAgICAgICB0aGlzLmludDE2W28yICsgM10gPSB2MztcbiAgICAgICAgdGhpcy51aW50MTZbbzIgKyA0XSA9IHY0O1xuICAgICAgICB0aGlzLnVpbnQxNltvMiArIDVdID0gdjU7XG4gICAgICAgIHRoaXMudWludDE2W28yICsgNl0gPSB2NjtcbiAgICAgICAgdGhpcy51aW50MTZbbzIgKyA3XSA9IHY3O1xuICAgICAgICB0aGlzLmludDE2W28yICsgOF0gPSB2ODtcbiAgICAgICAgdGhpcy5pbnQxNltvMiArIDldID0gdjk7XG4gICAgICAgIHRoaXMuaW50MTZbbzIgKyAxMF0gPSB2MTA7XG4gICAgICAgIHRoaXMuaW50MTZbbzIgKyAxMV0gPSB2MTE7XG4gICAgICAgIHJldHVybiBpO1xuICAgIH1cbn1cblxuU3RydWN0QXJyYXlMYXlvdXQ0aTR1aTRpMjQucHJvdG90eXBlLmJ5dGVzUGVyRWxlbWVudCA9IDI0O1xucmVnaXN0ZXIoU3RydWN0QXJyYXlMYXlvdXQ0aTR1aTRpMjQsICdTdHJ1Y3RBcnJheUxheW91dDRpNHVpNGkyNCcpO1xuXG4vKipcbiAqIEltcGxlbWVudGF0aW9uIG9mIHRoZSBTdHJ1Y3RBcnJheSBsYXlvdXQ6XG4gKiBbMF06IEludDE2WzNdXG4gKiBbOF06IEZsb2F0MzJbM11cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5jbGFzcyBTdHJ1Y3RBcnJheUxheW91dDNpM2YyMCBleHRlbmRzIFN0cnVjdEFycmF5IHtcbiAgICB1aW50ODogVWludDhBcnJheTtcbiAgICBpbnQxNjogSW50MTZBcnJheTtcbiAgICBmbG9hdDMyOiBGbG9hdDMyQXJyYXk7XG5cbiAgICBfcmVmcmVzaFZpZXdzKCkge1xuICAgICAgICB0aGlzLnVpbnQ4ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5hcnJheUJ1ZmZlcik7XG4gICAgICAgIHRoaXMuaW50MTYgPSBuZXcgSW50MTZBcnJheSh0aGlzLmFycmF5QnVmZmVyKTtcbiAgICAgICAgdGhpcy5mbG9hdDMyID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmFycmF5QnVmZmVyKTtcbiAgICB9XG5cbiAgICBlbXBsYWNlQmFjayh2MDogbnVtYmVyLCB2MTogbnVtYmVyLCB2MjogbnVtYmVyLCB2MzogbnVtYmVyLCB2NDogbnVtYmVyLCB2NTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgaSA9IHRoaXMubGVuZ3RoO1xuICAgICAgICB0aGlzLnJlc2l6ZShpICsgMSk7XG4gICAgICAgIHJldHVybiB0aGlzLmVtcGxhY2UoaSwgdjAsIHYxLCB2MiwgdjMsIHY0LCB2NSk7XG4gICAgfVxuXG4gICAgZW1wbGFjZShpOiBudW1iZXIsIHYwOiBudW1iZXIsIHYxOiBudW1iZXIsIHYyOiBudW1iZXIsIHYzOiBudW1iZXIsIHY0OiBudW1iZXIsIHY1OiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBvMiA9IGkgKiAxMDtcbiAgICAgICAgY29uc3QgbzQgPSBpICogNTtcbiAgICAgICAgdGhpcy5pbnQxNltvMiArIDBdID0gdjA7XG4gICAgICAgIHRoaXMuaW50MTZbbzIgKyAxXSA9IHYxO1xuICAgICAgICB0aGlzLmludDE2W28yICsgMl0gPSB2MjtcbiAgICAgICAgdGhpcy5mbG9hdDMyW280ICsgMl0gPSB2MztcbiAgICAgICAgdGhpcy5mbG9hdDMyW280ICsgM10gPSB2NDtcbiAgICAgICAgdGhpcy5mbG9hdDMyW280ICsgNF0gPSB2NTtcbiAgICAgICAgcmV0dXJuIGk7XG4gICAgfVxufVxuXG5TdHJ1Y3RBcnJheUxheW91dDNpM2YyMC5wcm90b3R5cGUuYnl0ZXNQZXJFbGVtZW50ID0gMjA7XG5yZWdpc3RlcihTdHJ1Y3RBcnJheUxheW91dDNpM2YyMCwgJ1N0cnVjdEFycmF5TGF5b3V0M2kzZjIwJyk7XG5cbi8qKlxuICogSW1wbGVtZW50YXRpb24gb2YgdGhlIFN0cnVjdEFycmF5IGxheW91dDpcbiAqIFswXTogVWludDMyWzFdXG4gKlxuICogQHByaXZhdGVcbiAqL1xuY2xhc3MgU3RydWN0QXJyYXlMYXlvdXQxdWw0IGV4dGVuZHMgU3RydWN0QXJyYXkge1xuICAgIHVpbnQ4OiBVaW50OEFycmF5O1xuICAgIHVpbnQzMjogVWludDMyQXJyYXk7XG5cbiAgICBfcmVmcmVzaFZpZXdzKCkge1xuICAgICAgICB0aGlzLnVpbnQ4ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5hcnJheUJ1ZmZlcik7XG4gICAgICAgIHRoaXMudWludDMyID0gbmV3IFVpbnQzMkFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgIH1cblxuICAgIGVtcGxhY2VCYWNrKHYwOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBpID0gdGhpcy5sZW5ndGg7XG4gICAgICAgIHRoaXMucmVzaXplKGkgKyAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1wbGFjZShpLCB2MCk7XG4gICAgfVxuXG4gICAgZW1wbGFjZShpOiBudW1iZXIsIHYwOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBvNCA9IGkgKiAxO1xuICAgICAgICB0aGlzLnVpbnQzMltvNCArIDBdID0gdjA7XG4gICAgICAgIHJldHVybiBpO1xuICAgIH1cbn1cblxuU3RydWN0QXJyYXlMYXlvdXQxdWw0LnByb3RvdHlwZS5ieXRlc1BlckVsZW1lbnQgPSA0O1xucmVnaXN0ZXIoU3RydWN0QXJyYXlMYXlvdXQxdWw0LCAnU3RydWN0QXJyYXlMYXlvdXQxdWw0Jyk7XG5cbi8qKlxuICogSW1wbGVtZW50YXRpb24gb2YgdGhlIFN0cnVjdEFycmF5IGxheW91dDpcbiAqIFswXTogSW50MTZbNV1cbiAqIFsxMl06IEZsb2F0MzJbNF1cbiAqIFsyOF06IEludDE2WzFdXG4gKiBbMzJdOiBVaW50MzJbMV1cbiAqIFszNl06IFVpbnQxNlsyXVxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmNsYXNzIFN0cnVjdEFycmF5TGF5b3V0NWk0ZjFpMXVsMnVpNDAgZXh0ZW5kcyBTdHJ1Y3RBcnJheSB7XG4gICAgdWludDg6IFVpbnQ4QXJyYXk7XG4gICAgaW50MTY6IEludDE2QXJyYXk7XG4gICAgZmxvYXQzMjogRmxvYXQzMkFycmF5O1xuICAgIHVpbnQzMjogVWludDMyQXJyYXk7XG4gICAgdWludDE2OiBVaW50MTZBcnJheTtcblxuICAgIF9yZWZyZXNoVmlld3MoKSB7XG4gICAgICAgIHRoaXMudWludDggPSBuZXcgVWludDhBcnJheSh0aGlzLmFycmF5QnVmZmVyKTtcbiAgICAgICAgdGhpcy5pbnQxNiA9IG5ldyBJbnQxNkFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgICAgICB0aGlzLmZsb2F0MzIgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgICAgICB0aGlzLnVpbnQzMiA9IG5ldyBVaW50MzJBcnJheSh0aGlzLmFycmF5QnVmZmVyKTtcbiAgICAgICAgdGhpcy51aW50MTYgPSBuZXcgVWludDE2QXJyYXkodGhpcy5hcnJheUJ1ZmZlcik7XG4gICAgfVxuXG4gICAgZW1wbGFjZUJhY2sodjA6IG51bWJlciwgdjE6IG51bWJlciwgdjI6IG51bWJlciwgdjM6IG51bWJlciwgdjQ6IG51bWJlciwgdjU6IG51bWJlciwgdjY6IG51bWJlciwgdjc6IG51bWJlciwgdjg6IG51bWJlciwgdjk6IG51bWJlciwgdjEwOiBudW1iZXIsIHYxMTogbnVtYmVyLCB2MTI6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IGkgPSB0aGlzLmxlbmd0aDtcbiAgICAgICAgdGhpcy5yZXNpemUoaSArIDEpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbXBsYWNlKGksIHYwLCB2MSwgdjIsIHYzLCB2NCwgdjUsIHY2LCB2NywgdjgsIHY5LCB2MTAsIHYxMSwgdjEyKTtcbiAgICB9XG5cbiAgICBlbXBsYWNlKGk6IG51bWJlciwgdjA6IG51bWJlciwgdjE6IG51bWJlciwgdjI6IG51bWJlciwgdjM6IG51bWJlciwgdjQ6IG51bWJlciwgdjU6IG51bWJlciwgdjY6IG51bWJlciwgdjc6IG51bWJlciwgdjg6IG51bWJlciwgdjk6IG51bWJlciwgdjEwOiBudW1iZXIsIHYxMTogbnVtYmVyLCB2MTI6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IG8yID0gaSAqIDIwO1xuICAgICAgICBjb25zdCBvNCA9IGkgKiAxMDtcbiAgICAgICAgdGhpcy5pbnQxNltvMiArIDBdID0gdjA7XG4gICAgICAgIHRoaXMuaW50MTZbbzIgKyAxXSA9IHYxO1xuICAgICAgICB0aGlzLmludDE2W28yICsgMl0gPSB2MjtcbiAgICAgICAgdGhpcy5pbnQxNltvMiArIDNdID0gdjM7XG4gICAgICAgIHRoaXMuaW50MTZbbzIgKyA0XSA9IHY0O1xuICAgICAgICB0aGlzLmZsb2F0MzJbbzQgKyAzXSA9IHY1O1xuICAgICAgICB0aGlzLmZsb2F0MzJbbzQgKyA0XSA9IHY2O1xuICAgICAgICB0aGlzLmZsb2F0MzJbbzQgKyA1XSA9IHY3O1xuICAgICAgICB0aGlzLmZsb2F0MzJbbzQgKyA2XSA9IHY4O1xuICAgICAgICB0aGlzLmludDE2W28yICsgMTRdID0gdjk7XG4gICAgICAgIHRoaXMudWludDMyW280ICsgOF0gPSB2MTA7XG4gICAgICAgIHRoaXMudWludDE2W28yICsgMThdID0gdjExO1xuICAgICAgICB0aGlzLnVpbnQxNltvMiArIDE5XSA9IHYxMjtcbiAgICAgICAgcmV0dXJuIGk7XG4gICAgfVxufVxuXG5TdHJ1Y3RBcnJheUxheW91dDVpNGYxaTF1bDJ1aTQwLnByb3RvdHlwZS5ieXRlc1BlckVsZW1lbnQgPSA0MDtcbnJlZ2lzdGVyKFN0cnVjdEFycmF5TGF5b3V0NWk0ZjFpMXVsMnVpNDAsICdTdHJ1Y3RBcnJheUxheW91dDVpNGYxaTF1bDJ1aTQwJyk7XG5cbi8qKlxuICogSW1wbGVtZW50YXRpb24gb2YgdGhlIFN0cnVjdEFycmF5IGxheW91dDpcbiAqIFswXTogSW50MTZbM11cbiAqIFs4XTogSW50MTZbMl1cbiAqIFsxMl06IEludDE2WzJdXG4gKlxuICogQHByaXZhdGVcbiAqL1xuY2xhc3MgU3RydWN0QXJyYXlMYXlvdXQzaTJpMmkxNiBleHRlbmRzIFN0cnVjdEFycmF5IHtcbiAgICB1aW50ODogVWludDhBcnJheTtcbiAgICBpbnQxNjogSW50MTZBcnJheTtcblxuICAgIF9yZWZyZXNoVmlld3MoKSB7XG4gICAgICAgIHRoaXMudWludDggPSBuZXcgVWludDhBcnJheSh0aGlzLmFycmF5QnVmZmVyKTtcbiAgICAgICAgdGhpcy5pbnQxNiA9IG5ldyBJbnQxNkFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgIH1cblxuICAgIGVtcGxhY2VCYWNrKHYwOiBudW1iZXIsIHYxOiBudW1iZXIsIHYyOiBudW1iZXIsIHYzOiBudW1iZXIsIHY0OiBudW1iZXIsIHY1OiBudW1iZXIsIHY2OiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBpID0gdGhpcy5sZW5ndGg7XG4gICAgICAgIHRoaXMucmVzaXplKGkgKyAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1wbGFjZShpLCB2MCwgdjEsIHYyLCB2MywgdjQsIHY1LCB2Nik7XG4gICAgfVxuXG4gICAgZW1wbGFjZShpOiBudW1iZXIsIHYwOiBudW1iZXIsIHYxOiBudW1iZXIsIHYyOiBudW1iZXIsIHYzOiBudW1iZXIsIHY0OiBudW1iZXIsIHY1OiBudW1iZXIsIHY2OiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBvMiA9IGkgKiA4O1xuICAgICAgICB0aGlzLmludDE2W28yICsgMF0gPSB2MDtcbiAgICAgICAgdGhpcy5pbnQxNltvMiArIDFdID0gdjE7XG4gICAgICAgIHRoaXMuaW50MTZbbzIgKyAyXSA9IHYyO1xuICAgICAgICB0aGlzLmludDE2W28yICsgNF0gPSB2MztcbiAgICAgICAgdGhpcy5pbnQxNltvMiArIDVdID0gdjQ7XG4gICAgICAgIHRoaXMuaW50MTZbbzIgKyA2XSA9IHY1O1xuICAgICAgICB0aGlzLmludDE2W28yICsgN10gPSB2NjtcbiAgICAgICAgcmV0dXJuIGk7XG4gICAgfVxufVxuXG5TdHJ1Y3RBcnJheUxheW91dDNpMmkyaTE2LnByb3RvdHlwZS5ieXRlc1BlckVsZW1lbnQgPSAxNjtcbnJlZ2lzdGVyKFN0cnVjdEFycmF5TGF5b3V0M2kyaTJpMTYsICdTdHJ1Y3RBcnJheUxheW91dDNpMmkyaTE2Jyk7XG5cbi8qKlxuICogSW1wbGVtZW50YXRpb24gb2YgdGhlIFN0cnVjdEFycmF5IGxheW91dDpcbiAqIFswXTogRmxvYXQzMlsyXVxuICogWzhdOiBGbG9hdDMyWzFdXG4gKiBbMTJdOiBJbnQxNlsyXVxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmNsYXNzIFN0cnVjdEFycmF5TGF5b3V0MmYxZjJpMTYgZXh0ZW5kcyBTdHJ1Y3RBcnJheSB7XG4gICAgdWludDg6IFVpbnQ4QXJyYXk7XG4gICAgZmxvYXQzMjogRmxvYXQzMkFycmF5O1xuICAgIGludDE2OiBJbnQxNkFycmF5O1xuXG4gICAgX3JlZnJlc2hWaWV3cygpIHtcbiAgICAgICAgdGhpcy51aW50OCA9IG5ldyBVaW50OEFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgICAgICB0aGlzLmZsb2F0MzIgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgICAgICB0aGlzLmludDE2ID0gbmV3IEludDE2QXJyYXkodGhpcy5hcnJheUJ1ZmZlcik7XG4gICAgfVxuXG4gICAgZW1wbGFjZUJhY2sodjA6IG51bWJlciwgdjE6IG51bWJlciwgdjI6IG51bWJlciwgdjM6IG51bWJlciwgdjQ6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IGkgPSB0aGlzLmxlbmd0aDtcbiAgICAgICAgdGhpcy5yZXNpemUoaSArIDEpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbXBsYWNlKGksIHYwLCB2MSwgdjIsIHYzLCB2NCk7XG4gICAgfVxuXG4gICAgZW1wbGFjZShpOiBudW1iZXIsIHYwOiBudW1iZXIsIHYxOiBudW1iZXIsIHYyOiBudW1iZXIsIHYzOiBudW1iZXIsIHY0OiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBvNCA9IGkgKiA0O1xuICAgICAgICBjb25zdCBvMiA9IGkgKiA4O1xuICAgICAgICB0aGlzLmZsb2F0MzJbbzQgKyAwXSA9IHYwO1xuICAgICAgICB0aGlzLmZsb2F0MzJbbzQgKyAxXSA9IHYxO1xuICAgICAgICB0aGlzLmZsb2F0MzJbbzQgKyAyXSA9IHYyO1xuICAgICAgICB0aGlzLmludDE2W28yICsgNl0gPSB2MztcbiAgICAgICAgdGhpcy5pbnQxNltvMiArIDddID0gdjQ7XG4gICAgICAgIHJldHVybiBpO1xuICAgIH1cbn1cblxuU3RydWN0QXJyYXlMYXlvdXQyZjFmMmkxNi5wcm90b3R5cGUuYnl0ZXNQZXJFbGVtZW50ID0gMTY7XG5yZWdpc3RlcihTdHJ1Y3RBcnJheUxheW91dDJmMWYyaTE2LCAnU3RydWN0QXJyYXlMYXlvdXQyZjFmMmkxNicpO1xuXG4vKipcbiAqIEltcGxlbWVudGF0aW9uIG9mIHRoZSBTdHJ1Y3RBcnJheSBsYXlvdXQ6XG4gKiBbMF06IFVpbnQ4WzJdXG4gKiBbNF06IEZsb2F0MzJbMl1cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5jbGFzcyBTdHJ1Y3RBcnJheUxheW91dDJ1YjJmMTIgZXh0ZW5kcyBTdHJ1Y3RBcnJheSB7XG4gICAgdWludDg6IFVpbnQ4QXJyYXk7XG4gICAgZmxvYXQzMjogRmxvYXQzMkFycmF5O1xuXG4gICAgX3JlZnJlc2hWaWV3cygpIHtcbiAgICAgICAgdGhpcy51aW50OCA9IG5ldyBVaW50OEFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgICAgICB0aGlzLmZsb2F0MzIgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgIH1cblxuICAgIGVtcGxhY2VCYWNrKHYwOiBudW1iZXIsIHYxOiBudW1iZXIsIHYyOiBudW1iZXIsIHYzOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBpID0gdGhpcy5sZW5ndGg7XG4gICAgICAgIHRoaXMucmVzaXplKGkgKyAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1wbGFjZShpLCB2MCwgdjEsIHYyLCB2Myk7XG4gICAgfVxuXG4gICAgZW1wbGFjZShpOiBudW1iZXIsIHYwOiBudW1iZXIsIHYxOiBudW1iZXIsIHYyOiBudW1iZXIsIHYzOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBvMSA9IGkgKiAxMjtcbiAgICAgICAgY29uc3QgbzQgPSBpICogMztcbiAgICAgICAgdGhpcy51aW50OFtvMSArIDBdID0gdjA7XG4gICAgICAgIHRoaXMudWludDhbbzEgKyAxXSA9IHYxO1xuICAgICAgICB0aGlzLmZsb2F0MzJbbzQgKyAxXSA9IHYyO1xuICAgICAgICB0aGlzLmZsb2F0MzJbbzQgKyAyXSA9IHYzO1xuICAgICAgICByZXR1cm4gaTtcbiAgICB9XG59XG5cblN0cnVjdEFycmF5TGF5b3V0MnViMmYxMi5wcm90b3R5cGUuYnl0ZXNQZXJFbGVtZW50ID0gMTI7XG5yZWdpc3RlcihTdHJ1Y3RBcnJheUxheW91dDJ1YjJmMTIsICdTdHJ1Y3RBcnJheUxheW91dDJ1YjJmMTInKTtcblxuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU3RydWN0QXJyYXkgbGF5b3V0OlxuICogWzBdOiBGbG9hdDMyWzNdXG4gKlxuICogQHByaXZhdGVcbiAqL1xuY2xhc3MgU3RydWN0QXJyYXlMYXlvdXQzZjEyIGV4dGVuZHMgU3RydWN0QXJyYXkge1xuICAgIHVpbnQ4OiBVaW50OEFycmF5O1xuICAgIGZsb2F0MzI6IEZsb2F0MzJBcnJheTtcblxuICAgIF9yZWZyZXNoVmlld3MoKSB7XG4gICAgICAgIHRoaXMudWludDggPSBuZXcgVWludDhBcnJheSh0aGlzLmFycmF5QnVmZmVyKTtcbiAgICAgICAgdGhpcy5mbG9hdDMyID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmFycmF5QnVmZmVyKTtcbiAgICB9XG5cbiAgICBlbXBsYWNlQmFjayh2MDogbnVtYmVyLCB2MTogbnVtYmVyLCB2MjogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgaSA9IHRoaXMubGVuZ3RoO1xuICAgICAgICB0aGlzLnJlc2l6ZShpICsgMSk7XG4gICAgICAgIHJldHVybiB0aGlzLmVtcGxhY2UoaSwgdjAsIHYxLCB2Mik7XG4gICAgfVxuXG4gICAgZW1wbGFjZShpOiBudW1iZXIsIHYwOiBudW1iZXIsIHYxOiBudW1iZXIsIHYyOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBvNCA9IGkgKiAzO1xuICAgICAgICB0aGlzLmZsb2F0MzJbbzQgKyAwXSA9IHYwO1xuICAgICAgICB0aGlzLmZsb2F0MzJbbzQgKyAxXSA9IHYxO1xuICAgICAgICB0aGlzLmZsb2F0MzJbbzQgKyAyXSA9IHYyO1xuICAgICAgICByZXR1cm4gaTtcbiAgICB9XG59XG5cblN0cnVjdEFycmF5TGF5b3V0M2YxMi5wcm90b3R5cGUuYnl0ZXNQZXJFbGVtZW50ID0gMTI7XG5yZWdpc3RlcihTdHJ1Y3RBcnJheUxheW91dDNmMTIsICdTdHJ1Y3RBcnJheUxheW91dDNmMTInKTtcblxuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU3RydWN0QXJyYXkgbGF5b3V0OlxuICogWzBdOiBVaW50MTZbM11cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5jbGFzcyBTdHJ1Y3RBcnJheUxheW91dDN1aTYgZXh0ZW5kcyBTdHJ1Y3RBcnJheSB7XG4gICAgdWludDg6IFVpbnQ4QXJyYXk7XG4gICAgdWludDE2OiBVaW50MTZBcnJheTtcblxuICAgIF9yZWZyZXNoVmlld3MoKSB7XG4gICAgICAgIHRoaXMudWludDggPSBuZXcgVWludDhBcnJheSh0aGlzLmFycmF5QnVmZmVyKTtcbiAgICAgICAgdGhpcy51aW50MTYgPSBuZXcgVWludDE2QXJyYXkodGhpcy5hcnJheUJ1ZmZlcik7XG4gICAgfVxuXG4gICAgZW1wbGFjZUJhY2sodjA6IG51bWJlciwgdjE6IG51bWJlciwgdjI6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IGkgPSB0aGlzLmxlbmd0aDtcbiAgICAgICAgdGhpcy5yZXNpemUoaSArIDEpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbXBsYWNlKGksIHYwLCB2MSwgdjIpO1xuICAgIH1cblxuICAgIGVtcGxhY2UoaTogbnVtYmVyLCB2MDogbnVtYmVyLCB2MTogbnVtYmVyLCB2MjogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgbzIgPSBpICogMztcbiAgICAgICAgdGhpcy51aW50MTZbbzIgKyAwXSA9IHYwO1xuICAgICAgICB0aGlzLnVpbnQxNltvMiArIDFdID0gdjE7XG4gICAgICAgIHRoaXMudWludDE2W28yICsgMl0gPSB2MjtcbiAgICAgICAgcmV0dXJuIGk7XG4gICAgfVxufVxuXG5TdHJ1Y3RBcnJheUxheW91dDN1aTYucHJvdG90eXBlLmJ5dGVzUGVyRWxlbWVudCA9IDY7XG5yZWdpc3RlcihTdHJ1Y3RBcnJheUxheW91dDN1aTYsICdTdHJ1Y3RBcnJheUxheW91dDN1aTYnKTtcblxuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU3RydWN0QXJyYXkgbGF5b3V0OlxuICogWzBdOiBJbnQxNlszXVxuICogWzhdOiBGbG9hdDMyWzJdXG4gKiBbMTZdOiBVaW50MTZbMl1cbiAqIFsyMF06IFVpbnQzMlszXVxuICogWzMyXTogVWludDE2WzNdXG4gKiBbNDBdOiBGbG9hdDMyWzJdXG4gKiBbNDhdOiBVaW50OFszXVxuICogWzUyXTogVWludDMyWzFdXG4gKiBbNTZdOiBJbnQxNlsxXVxuICogWzU4XTogVWludDhbMV1cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5jbGFzcyBTdHJ1Y3RBcnJheUxheW91dDNpMmYydWkzdWwzdWkyZjN1YjF1bDFpMXViNjAgZXh0ZW5kcyBTdHJ1Y3RBcnJheSB7XG4gICAgdWludDg6IFVpbnQ4QXJyYXk7XG4gICAgaW50MTY6IEludDE2QXJyYXk7XG4gICAgZmxvYXQzMjogRmxvYXQzMkFycmF5O1xuICAgIHVpbnQxNjogVWludDE2QXJyYXk7XG4gICAgdWludDMyOiBVaW50MzJBcnJheTtcblxuICAgIF9yZWZyZXNoVmlld3MoKSB7XG4gICAgICAgIHRoaXMudWludDggPSBuZXcgVWludDhBcnJheSh0aGlzLmFycmF5QnVmZmVyKTtcbiAgICAgICAgdGhpcy5pbnQxNiA9IG5ldyBJbnQxNkFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgICAgICB0aGlzLmZsb2F0MzIgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgICAgICB0aGlzLnVpbnQxNiA9IG5ldyBVaW50MTZBcnJheSh0aGlzLmFycmF5QnVmZmVyKTtcbiAgICAgICAgdGhpcy51aW50MzIgPSBuZXcgVWludDMyQXJyYXkodGhpcy5hcnJheUJ1ZmZlcik7XG4gICAgfVxuXG4gICAgZW1wbGFjZUJhY2sodjA6IG51bWJlciwgdjE6IG51bWJlciwgdjI6IG51bWJlciwgdjM6IG51bWJlciwgdjQ6IG51bWJlciwgdjU6IG51bWJlciwgdjY6IG51bWJlciwgdjc6IG51bWJlciwgdjg6IG51bWJlciwgdjk6IG51bWJlciwgdjEwOiBudW1iZXIsIHYxMTogbnVtYmVyLCB2MTI6IG51bWJlciwgdjEzOiBudW1iZXIsIHYxNDogbnVtYmVyLCB2MTU6IG51bWJlciwgdjE2OiBudW1iZXIsIHYxNzogbnVtYmVyLCB2MTg6IG51bWJlciwgdjE5OiBudW1iZXIsIHYyMDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgaSA9IHRoaXMubGVuZ3RoO1xuICAgICAgICB0aGlzLnJlc2l6ZShpICsgMSk7XG4gICAgICAgIHJldHVybiB0aGlzLmVtcGxhY2UoaSwgdjAsIHYxLCB2MiwgdjMsIHY0LCB2NSwgdjYsIHY3LCB2OCwgdjksIHYxMCwgdjExLCB2MTIsIHYxMywgdjE0LCB2MTUsIHYxNiwgdjE3LCB2MTgsIHYxOSwgdjIwKTtcbiAgICB9XG5cbiAgICBlbXBsYWNlKGk6IG51bWJlciwgdjA6IG51bWJlciwgdjE6IG51bWJlciwgdjI6IG51bWJlciwgdjM6IG51bWJlciwgdjQ6IG51bWJlciwgdjU6IG51bWJlciwgdjY6IG51bWJlciwgdjc6IG51bWJlciwgdjg6IG51bWJlciwgdjk6IG51bWJlciwgdjEwOiBudW1iZXIsIHYxMTogbnVtYmVyLCB2MTI6IG51bWJlciwgdjEzOiBudW1iZXIsIHYxNDogbnVtYmVyLCB2MTU6IG51bWJlciwgdjE2OiBudW1iZXIsIHYxNzogbnVtYmVyLCB2MTg6IG51bWJlciwgdjE5OiBudW1iZXIsIHYyMDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgbzIgPSBpICogMzA7XG4gICAgICAgIGNvbnN0IG80ID0gaSAqIDE1O1xuICAgICAgICBjb25zdCBvMSA9IGkgKiA2MDtcbiAgICAgICAgdGhpcy5pbnQxNltvMiArIDBdID0gdjA7XG4gICAgICAgIHRoaXMuaW50MTZbbzIgKyAxXSA9IHYxO1xuICAgICAgICB0aGlzLmludDE2W28yICsgMl0gPSB2MjtcbiAgICAgICAgdGhpcy5mbG9hdDMyW280ICsgMl0gPSB2MztcbiAgICAgICAgdGhpcy5mbG9hdDMyW280ICsgM10gPSB2NDtcbiAgICAgICAgdGhpcy51aW50MTZbbzIgKyA4XSA9IHY1O1xuICAgICAgICB0aGlzLnVpbnQxNltvMiArIDldID0gdjY7XG4gICAgICAgIHRoaXMudWludDMyW280ICsgNV0gPSB2NztcbiAgICAgICAgdGhpcy51aW50MzJbbzQgKyA2XSA9IHY4O1xuICAgICAgICB0aGlzLnVpbnQzMltvNCArIDddID0gdjk7XG4gICAgICAgIHRoaXMudWludDE2W28yICsgMTZdID0gdjEwO1xuICAgICAgICB0aGlzLnVpbnQxNltvMiArIDE3XSA9IHYxMTtcbiAgICAgICAgdGhpcy51aW50MTZbbzIgKyAxOF0gPSB2MTI7XG4gICAgICAgIHRoaXMuZmxvYXQzMltvNCArIDEwXSA9IHYxMztcbiAgICAgICAgdGhpcy5mbG9hdDMyW280ICsgMTFdID0gdjE0O1xuICAgICAgICB0aGlzLnVpbnQ4W28xICsgNDhdID0gdjE1O1xuICAgICAgICB0aGlzLnVpbnQ4W28xICsgNDldID0gdjE2O1xuICAgICAgICB0aGlzLnVpbnQ4W28xICsgNTBdID0gdjE3O1xuICAgICAgICB0aGlzLnVpbnQzMltvNCArIDEzXSA9IHYxODtcbiAgICAgICAgdGhpcy5pbnQxNltvMiArIDI4XSA9IHYxOTtcbiAgICAgICAgdGhpcy51aW50OFtvMSArIDU4XSA9IHYyMDtcbiAgICAgICAgcmV0dXJuIGk7XG4gICAgfVxufVxuXG5TdHJ1Y3RBcnJheUxheW91dDNpMmYydWkzdWwzdWkyZjN1YjF1bDFpMXViNjAucHJvdG90eXBlLmJ5dGVzUGVyRWxlbWVudCA9IDYwO1xucmVnaXN0ZXIoU3RydWN0QXJyYXlMYXlvdXQzaTJmMnVpM3VsM3VpMmYzdWIxdWwxaTF1YjYwLCAnU3RydWN0QXJyYXlMYXlvdXQzaTJmMnVpM3VsM3VpMmYzdWIxdWwxaTF1YjYwJyk7XG5cbi8qKlxuICogSW1wbGVtZW50YXRpb24gb2YgdGhlIFN0cnVjdEFycmF5IGxheW91dDpcbiAqIFswXTogSW50MTZbM11cbiAqIFs4XTogRmxvYXQzMlsyXVxuICogWzE2XTogSW50MTZbNl1cbiAqIFsyOF06IFVpbnQxNlsxNV1cbiAqIFs2MF06IFVpbnQzMlsxXVxuICogWzY0XTogRmxvYXQzMlszXVxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmNsYXNzIFN0cnVjdEFycmF5TGF5b3V0M2kyZjZpMTV1aTF1bDNmNzYgZXh0ZW5kcyBTdHJ1Y3RBcnJheSB7XG4gICAgdWludDg6IFVpbnQ4QXJyYXk7XG4gICAgaW50MTY6IEludDE2QXJyYXk7XG4gICAgZmxvYXQzMjogRmxvYXQzMkFycmF5O1xuICAgIHVpbnQxNjogVWludDE2QXJyYXk7XG4gICAgdWludDMyOiBVaW50MzJBcnJheTtcblxuICAgIF9yZWZyZXNoVmlld3MoKSB7XG4gICAgICAgIHRoaXMudWludDggPSBuZXcgVWludDhBcnJheSh0aGlzLmFycmF5QnVmZmVyKTtcbiAgICAgICAgdGhpcy5pbnQxNiA9IG5ldyBJbnQxNkFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgICAgICB0aGlzLmZsb2F0MzIgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgICAgICB0aGlzLnVpbnQxNiA9IG5ldyBVaW50MTZBcnJheSh0aGlzLmFycmF5QnVmZmVyKTtcbiAgICAgICAgdGhpcy51aW50MzIgPSBuZXcgVWludDMyQXJyYXkodGhpcy5hcnJheUJ1ZmZlcik7XG4gICAgfVxuXG4gICAgZW1wbGFjZUJhY2sodjA6IG51bWJlciwgdjE6IG51bWJlciwgdjI6IG51bWJlciwgdjM6IG51bWJlciwgdjQ6IG51bWJlciwgdjU6IG51bWJlciwgdjY6IG51bWJlciwgdjc6IG51bWJlciwgdjg6IG51bWJlciwgdjk6IG51bWJlciwgdjEwOiBudW1iZXIsIHYxMTogbnVtYmVyLCB2MTI6IG51bWJlciwgdjEzOiBudW1iZXIsIHYxNDogbnVtYmVyLCB2MTU6IG51bWJlciwgdjE2OiBudW1iZXIsIHYxNzogbnVtYmVyLCB2MTg6IG51bWJlciwgdjE5OiBudW1iZXIsIHYyMDogbnVtYmVyLCB2MjE6IG51bWJlciwgdjIyOiBudW1iZXIsIHYyMzogbnVtYmVyLCB2MjQ6IG51bWJlciwgdjI1OiBudW1iZXIsIHYyNjogbnVtYmVyLCB2Mjc6IG51bWJlciwgdjI4OiBudW1iZXIsIHYyOTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgaSA9IHRoaXMubGVuZ3RoO1xuICAgICAgICB0aGlzLnJlc2l6ZShpICsgMSk7XG4gICAgICAgIHJldHVybiB0aGlzLmVtcGxhY2UoaSwgdjAsIHYxLCB2MiwgdjMsIHY0LCB2NSwgdjYsIHY3LCB2OCwgdjksIHYxMCwgdjExLCB2MTIsIHYxMywgdjE0LCB2MTUsIHYxNiwgdjE3LCB2MTgsIHYxOSwgdjIwLCB2MjEsIHYyMiwgdjIzLCB2MjQsIHYyNSwgdjI2LCB2MjcsIHYyOCwgdjI5KTtcbiAgICB9XG5cbiAgICBlbXBsYWNlKGk6IG51bWJlciwgdjA6IG51bWJlciwgdjE6IG51bWJlciwgdjI6IG51bWJlciwgdjM6IG51bWJlciwgdjQ6IG51bWJlciwgdjU6IG51bWJlciwgdjY6IG51bWJlciwgdjc6IG51bWJlciwgdjg6IG51bWJlciwgdjk6IG51bWJlciwgdjEwOiBudW1iZXIsIHYxMTogbnVtYmVyLCB2MTI6IG51bWJlciwgdjEzOiBudW1iZXIsIHYxNDogbnVtYmVyLCB2MTU6IG51bWJlciwgdjE2OiBudW1iZXIsIHYxNzogbnVtYmVyLCB2MTg6IG51bWJlciwgdjE5OiBudW1iZXIsIHYyMDogbnVtYmVyLCB2MjE6IG51bWJlciwgdjIyOiBudW1iZXIsIHYyMzogbnVtYmVyLCB2MjQ6IG51bWJlciwgdjI1OiBudW1iZXIsIHYyNjogbnVtYmVyLCB2Mjc6IG51bWJlciwgdjI4OiBudW1iZXIsIHYyOTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgbzIgPSBpICogMzg7XG4gICAgICAgIGNvbnN0IG80ID0gaSAqIDE5O1xuICAgICAgICB0aGlzLmludDE2W28yICsgMF0gPSB2MDtcbiAgICAgICAgdGhpcy5pbnQxNltvMiArIDFdID0gdjE7XG4gICAgICAgIHRoaXMuaW50MTZbbzIgKyAyXSA9IHYyO1xuICAgICAgICB0aGlzLmZsb2F0MzJbbzQgKyAyXSA9IHYzO1xuICAgICAgICB0aGlzLmZsb2F0MzJbbzQgKyAzXSA9IHY0O1xuICAgICAgICB0aGlzLmludDE2W28yICsgOF0gPSB2NTtcbiAgICAgICAgdGhpcy5pbnQxNltvMiArIDldID0gdjY7XG4gICAgICAgIHRoaXMuaW50MTZbbzIgKyAxMF0gPSB2NztcbiAgICAgICAgdGhpcy5pbnQxNltvMiArIDExXSA9IHY4O1xuICAgICAgICB0aGlzLmludDE2W28yICsgMTJdID0gdjk7XG4gICAgICAgIHRoaXMuaW50MTZbbzIgKyAxM10gPSB2MTA7XG4gICAgICAgIHRoaXMudWludDE2W28yICsgMTRdID0gdjExO1xuICAgICAgICB0aGlzLnVpbnQxNltvMiArIDE1XSA9IHYxMjtcbiAgICAgICAgdGhpcy51aW50MTZbbzIgKyAxNl0gPSB2MTM7XG4gICAgICAgIHRoaXMudWludDE2W28yICsgMTddID0gdjE0O1xuICAgICAgICB0aGlzLnVpbnQxNltvMiArIDE4XSA9IHYxNTtcbiAgICAgICAgdGhpcy51aW50MTZbbzIgKyAxOV0gPSB2MTY7XG4gICAgICAgIHRoaXMudWludDE2W28yICsgMjBdID0gdjE3O1xuICAgICAgICB0aGlzLnVpbnQxNltvMiArIDIxXSA9IHYxODtcbiAgICAgICAgdGhpcy51aW50MTZbbzIgKyAyMl0gPSB2MTk7XG4gICAgICAgIHRoaXMudWludDE2W28yICsgMjNdID0gdjIwO1xuICAgICAgICB0aGlzLnVpbnQxNltvMiArIDI0XSA9IHYyMTtcbiAgICAgICAgdGhpcy51aW50MTZbbzIgKyAyNV0gPSB2MjI7XG4gICAgICAgIHRoaXMudWludDE2W28yICsgMjZdID0gdjIzO1xuICAgICAgICB0aGlzLnVpbnQxNltvMiArIDI3XSA9IHYyNDtcbiAgICAgICAgdGhpcy51aW50MTZbbzIgKyAyOF0gPSB2MjU7XG4gICAgICAgIHRoaXMudWludDMyW280ICsgMTVdID0gdjI2O1xuICAgICAgICB0aGlzLmZsb2F0MzJbbzQgKyAxNl0gPSB2Mjc7XG4gICAgICAgIHRoaXMuZmxvYXQzMltvNCArIDE3XSA9IHYyODtcbiAgICAgICAgdGhpcy5mbG9hdDMyW280ICsgMThdID0gdjI5O1xuICAgICAgICByZXR1cm4gaTtcbiAgICB9XG59XG5cblN0cnVjdEFycmF5TGF5b3V0M2kyZjZpMTV1aTF1bDNmNzYucHJvdG90eXBlLmJ5dGVzUGVyRWxlbWVudCA9IDc2O1xucmVnaXN0ZXIoU3RydWN0QXJyYXlMYXlvdXQzaTJmNmkxNXVpMXVsM2Y3NiwgJ1N0cnVjdEFycmF5TGF5b3V0M2kyZjZpMTV1aTF1bDNmNzYnKTtcblxuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU3RydWN0QXJyYXkgbGF5b3V0OlxuICogWzBdOiBGbG9hdDMyWzFdXG4gKlxuICogQHByaXZhdGVcbiAqL1xuY2xhc3MgU3RydWN0QXJyYXlMYXlvdXQxZjQgZXh0ZW5kcyBTdHJ1Y3RBcnJheSB7XG4gICAgdWludDg6IFVpbnQ4QXJyYXk7XG4gICAgZmxvYXQzMjogRmxvYXQzMkFycmF5O1xuXG4gICAgX3JlZnJlc2hWaWV3cygpIHtcbiAgICAgICAgdGhpcy51aW50OCA9IG5ldyBVaW50OEFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgICAgICB0aGlzLmZsb2F0MzIgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgIH1cblxuICAgIGVtcGxhY2VCYWNrKHYwOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBpID0gdGhpcy5sZW5ndGg7XG4gICAgICAgIHRoaXMucmVzaXplKGkgKyAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1wbGFjZShpLCB2MCk7XG4gICAgfVxuXG4gICAgZW1wbGFjZShpOiBudW1iZXIsIHYwOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBvNCA9IGkgKiAxO1xuICAgICAgICB0aGlzLmZsb2F0MzJbbzQgKyAwXSA9IHYwO1xuICAgICAgICByZXR1cm4gaTtcbiAgICB9XG59XG5cblN0cnVjdEFycmF5TGF5b3V0MWY0LnByb3RvdHlwZS5ieXRlc1BlckVsZW1lbnQgPSA0O1xucmVnaXN0ZXIoU3RydWN0QXJyYXlMYXlvdXQxZjQsICdTdHJ1Y3RBcnJheUxheW91dDFmNCcpO1xuXG4vKipcbiAqIEltcGxlbWVudGF0aW9uIG9mIHRoZSBTdHJ1Y3RBcnJheSBsYXlvdXQ6XG4gKiBbMF06IEZsb2F0MzJbNV1cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5jbGFzcyBTdHJ1Y3RBcnJheUxheW91dDVmMjAgZXh0ZW5kcyBTdHJ1Y3RBcnJheSB7XG4gICAgdWludDg6IFVpbnQ4QXJyYXk7XG4gICAgZmxvYXQzMjogRmxvYXQzMkFycmF5O1xuXG4gICAgX3JlZnJlc2hWaWV3cygpIHtcbiAgICAgICAgdGhpcy51aW50OCA9IG5ldyBVaW50OEFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgICAgICB0aGlzLmZsb2F0MzIgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgIH1cblxuICAgIGVtcGxhY2VCYWNrKHYwOiBudW1iZXIsIHYxOiBudW1iZXIsIHYyOiBudW1iZXIsIHYzOiBudW1iZXIsIHY0OiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBpID0gdGhpcy5sZW5ndGg7XG4gICAgICAgIHRoaXMucmVzaXplKGkgKyAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1wbGFjZShpLCB2MCwgdjEsIHYyLCB2MywgdjQpO1xuICAgIH1cblxuICAgIGVtcGxhY2UoaTogbnVtYmVyLCB2MDogbnVtYmVyLCB2MTogbnVtYmVyLCB2MjogbnVtYmVyLCB2MzogbnVtYmVyLCB2NDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgbzQgPSBpICogNTtcbiAgICAgICAgdGhpcy5mbG9hdDMyW280ICsgMF0gPSB2MDtcbiAgICAgICAgdGhpcy5mbG9hdDMyW280ICsgMV0gPSB2MTtcbiAgICAgICAgdGhpcy5mbG9hdDMyW280ICsgMl0gPSB2MjtcbiAgICAgICAgdGhpcy5mbG9hdDMyW280ICsgM10gPSB2MztcbiAgICAgICAgdGhpcy5mbG9hdDMyW280ICsgNF0gPSB2NDtcbiAgICAgICAgcmV0dXJuIGk7XG4gICAgfVxufVxuXG5TdHJ1Y3RBcnJheUxheW91dDVmMjAucHJvdG90eXBlLmJ5dGVzUGVyRWxlbWVudCA9IDIwO1xucmVnaXN0ZXIoU3RydWN0QXJyYXlMYXlvdXQ1ZjIwLCAnU3RydWN0QXJyYXlMYXlvdXQ1ZjIwJyk7XG5cbi8qKlxuICogSW1wbGVtZW50YXRpb24gb2YgdGhlIFN0cnVjdEFycmF5IGxheW91dDpcbiAqIFswXTogVWludDMyWzFdXG4gKiBbNF06IFVpbnQxNlszXVxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmNsYXNzIFN0cnVjdEFycmF5TGF5b3V0MXVsM3VpMTIgZXh0ZW5kcyBTdHJ1Y3RBcnJheSB7XG4gICAgdWludDg6IFVpbnQ4QXJyYXk7XG4gICAgdWludDMyOiBVaW50MzJBcnJheTtcbiAgICB1aW50MTY6IFVpbnQxNkFycmF5O1xuXG4gICAgX3JlZnJlc2hWaWV3cygpIHtcbiAgICAgICAgdGhpcy51aW50OCA9IG5ldyBVaW50OEFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgICAgICB0aGlzLnVpbnQzMiA9IG5ldyBVaW50MzJBcnJheSh0aGlzLmFycmF5QnVmZmVyKTtcbiAgICAgICAgdGhpcy51aW50MTYgPSBuZXcgVWludDE2QXJyYXkodGhpcy5hcnJheUJ1ZmZlcik7XG4gICAgfVxuXG4gICAgZW1wbGFjZUJhY2sodjA6IG51bWJlciwgdjE6IG51bWJlciwgdjI6IG51bWJlciwgdjM6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IGkgPSB0aGlzLmxlbmd0aDtcbiAgICAgICAgdGhpcy5yZXNpemUoaSArIDEpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbXBsYWNlKGksIHYwLCB2MSwgdjIsIHYzKTtcbiAgICB9XG5cbiAgICBlbXBsYWNlKGk6IG51bWJlciwgdjA6IG51bWJlciwgdjE6IG51bWJlciwgdjI6IG51bWJlciwgdjM6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IG80ID0gaSAqIDM7XG4gICAgICAgIGNvbnN0IG8yID0gaSAqIDY7XG4gICAgICAgIHRoaXMudWludDMyW280ICsgMF0gPSB2MDtcbiAgICAgICAgdGhpcy51aW50MTZbbzIgKyAyXSA9IHYxO1xuICAgICAgICB0aGlzLnVpbnQxNltvMiArIDNdID0gdjI7XG4gICAgICAgIHRoaXMudWludDE2W28yICsgNF0gPSB2MztcbiAgICAgICAgcmV0dXJuIGk7XG4gICAgfVxufVxuXG5TdHJ1Y3RBcnJheUxheW91dDF1bDN1aTEyLnByb3RvdHlwZS5ieXRlc1BlckVsZW1lbnQgPSAxMjtcbnJlZ2lzdGVyKFN0cnVjdEFycmF5TGF5b3V0MXVsM3VpMTIsICdTdHJ1Y3RBcnJheUxheW91dDF1bDN1aTEyJyk7XG5cbi8qKlxuICogSW1wbGVtZW50YXRpb24gb2YgdGhlIFN0cnVjdEFycmF5IGxheW91dDpcbiAqIFswXTogVWludDE2WzJdXG4gKlxuICogQHByaXZhdGVcbiAqL1xuY2xhc3MgU3RydWN0QXJyYXlMYXlvdXQydWk0IGV4dGVuZHMgU3RydWN0QXJyYXkge1xuICAgIHVpbnQ4OiBVaW50OEFycmF5O1xuICAgIHVpbnQxNjogVWludDE2QXJyYXk7XG5cbiAgICBfcmVmcmVzaFZpZXdzKCkge1xuICAgICAgICB0aGlzLnVpbnQ4ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5hcnJheUJ1ZmZlcik7XG4gICAgICAgIHRoaXMudWludDE2ID0gbmV3IFVpbnQxNkFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgIH1cblxuICAgIGVtcGxhY2VCYWNrKHYwOiBudW1iZXIsIHYxOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBpID0gdGhpcy5sZW5ndGg7XG4gICAgICAgIHRoaXMucmVzaXplKGkgKyAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1wbGFjZShpLCB2MCwgdjEpO1xuICAgIH1cblxuICAgIGVtcGxhY2UoaTogbnVtYmVyLCB2MDogbnVtYmVyLCB2MTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgbzIgPSBpICogMjtcbiAgICAgICAgdGhpcy51aW50MTZbbzIgKyAwXSA9IHYwO1xuICAgICAgICB0aGlzLnVpbnQxNltvMiArIDFdID0gdjE7XG4gICAgICAgIHJldHVybiBpO1xuICAgIH1cbn1cblxuU3RydWN0QXJyYXlMYXlvdXQydWk0LnByb3RvdHlwZS5ieXRlc1BlckVsZW1lbnQgPSA0O1xucmVnaXN0ZXIoU3RydWN0QXJyYXlMYXlvdXQydWk0LCAnU3RydWN0QXJyYXlMYXlvdXQydWk0Jyk7XG5cbi8qKlxuICogSW1wbGVtZW50YXRpb24gb2YgdGhlIFN0cnVjdEFycmF5IGxheW91dDpcbiAqIFswXTogVWludDE2WzFdXG4gKlxuICogQHByaXZhdGVcbiAqL1xuY2xhc3MgU3RydWN0QXJyYXlMYXlvdXQxdWkyIGV4dGVuZHMgU3RydWN0QXJyYXkge1xuICAgIHVpbnQ4OiBVaW50OEFycmF5O1xuICAgIHVpbnQxNjogVWludDE2QXJyYXk7XG5cbiAgICBfcmVmcmVzaFZpZXdzKCkge1xuICAgICAgICB0aGlzLnVpbnQ4ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5hcnJheUJ1ZmZlcik7XG4gICAgICAgIHRoaXMudWludDE2ID0gbmV3IFVpbnQxNkFycmF5KHRoaXMuYXJyYXlCdWZmZXIpO1xuICAgIH1cblxuICAgIGVtcGxhY2VCYWNrKHYwOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBpID0gdGhpcy5sZW5ndGg7XG4gICAgICAgIHRoaXMucmVzaXplKGkgKyAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1wbGFjZShpLCB2MCk7XG4gICAgfVxuXG4gICAgZW1wbGFjZShpOiBudW1iZXIsIHYwOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBvMiA9IGkgKiAxO1xuICAgICAgICB0aGlzLnVpbnQxNltvMiArIDBdID0gdjA7XG4gICAgICAgIHJldHVybiBpO1xuICAgIH1cbn1cblxuU3RydWN0QXJyYXlMYXlvdXQxdWkyLnByb3RvdHlwZS5ieXRlc1BlckVsZW1lbnQgPSAyO1xucmVnaXN0ZXIoU3RydWN0QXJyYXlMYXlvdXQxdWkyLCAnU3RydWN0QXJyYXlMYXlvdXQxdWkyJyk7XG5cbi8qKlxuICogSW1wbGVtZW50YXRpb24gb2YgdGhlIFN0cnVjdEFycmF5IGxheW91dDpcbiAqIFswXTogRmxvYXQzMlsyXVxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmNsYXNzIFN0cnVjdEFycmF5TGF5b3V0MmY4IGV4dGVuZHMgU3RydWN0QXJyYXkge1xuICAgIHVpbnQ4OiBVaW50OEFycmF5O1xuICAgIGZsb2F0MzI6IEZsb2F0MzJBcnJheTtcblxuICAgIF9yZWZyZXNoVmlld3MoKSB7XG4gICAgICAgIHRoaXMudWludDggPSBuZXcgVWludDhBcnJheSh0aGlzLmFycmF5QnVmZmVyKTtcbiAgICAgICAgdGhpcy5mbG9hdDMyID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmFycmF5QnVmZmVyKTtcbiAgICB9XG5cbiAgICBlbXBsYWNlQmFjayh2MDogbnVtYmVyLCB2MTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgaSA9IHRoaXMubGVuZ3RoO1xuICAgICAgICB0aGlzLnJlc2l6ZShpICsgMSk7XG4gICAgICAgIHJldHVybiB0aGlzLmVtcGxhY2UoaSwgdjAsIHYxKTtcbiAgICB9XG5cbiAgICBlbXBsYWNlKGk6IG51bWJlciwgdjA6IG51bWJlciwgdjE6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IG80ID0gaSAqIDI7XG4gICAgICAgIHRoaXMuZmxvYXQzMltvNCArIDBdID0gdjA7XG4gICAgICAgIHRoaXMuZmxvYXQzMltvNCArIDFdID0gdjE7XG4gICAgICAgIHJldHVybiBpO1xuICAgIH1cbn1cblxuU3RydWN0QXJyYXlMYXlvdXQyZjgucHJvdG90eXBlLmJ5dGVzUGVyRWxlbWVudCA9IDg7XG5yZWdpc3RlcihTdHJ1Y3RBcnJheUxheW91dDJmOCwgJ1N0cnVjdEFycmF5TGF5b3V0MmY4Jyk7XG5cbmNsYXNzIENvbGxpc2lvbkJveFN0cnVjdCBleHRlbmRzIFN0cnVjdCB7XG4gICAgX3N0cnVjdEFycmF5OiBDb2xsaXNpb25Cb3hBcnJheTtcbiAgICBnZXQgcHJvamVjdGVkQW5jaG9yWCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkuaW50MTZbdGhpcy5fcG9zMiArIDBdOyB9XG4gICAgZ2V0IHByb2plY3RlZEFuY2hvclkoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3N0cnVjdEFycmF5LmludDE2W3RoaXMuX3BvczIgKyAxXTsgfVxuICAgIGdldCBwcm9qZWN0ZWRBbmNob3JaKCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9zdHJ1Y3RBcnJheS5pbnQxNlt0aGlzLl9wb3MyICsgMl07IH1cbiAgICBnZXQgdGlsZUFuY2hvclgoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3N0cnVjdEFycmF5LmludDE2W3RoaXMuX3BvczIgKyAzXTsgfVxuICAgIGdldCB0aWxlQW5jaG9yWSgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkuaW50MTZbdGhpcy5fcG9zMiArIDRdOyB9XG4gICAgZ2V0IHgxKCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9zdHJ1Y3RBcnJheS5mbG9hdDMyW3RoaXMuX3BvczQgKyAzXTsgfVxuICAgIGdldCB5MSgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkuZmxvYXQzMlt0aGlzLl9wb3M0ICsgNF07IH1cbiAgICBnZXQgeDIoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3N0cnVjdEFycmF5LmZsb2F0MzJbdGhpcy5fcG9zNCArIDVdOyB9XG4gICAgZ2V0IHkyKCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9zdHJ1Y3RBcnJheS5mbG9hdDMyW3RoaXMuX3BvczQgKyA2XTsgfVxuICAgIGdldCBwYWRkaW5nKCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9zdHJ1Y3RBcnJheS5pbnQxNlt0aGlzLl9wb3MyICsgMTRdOyB9XG4gICAgZ2V0IGZlYXR1cmVJbmRleCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkudWludDMyW3RoaXMuX3BvczQgKyA4XTsgfVxuICAgIGdldCBzb3VyY2VMYXllckluZGV4KCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9zdHJ1Y3RBcnJheS51aW50MTZbdGhpcy5fcG9zMiArIDE4XTsgfVxuICAgIGdldCBidWNrZXRJbmRleCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkudWludDE2W3RoaXMuX3BvczIgKyAxOV07IH1cbn1cblxuQ29sbGlzaW9uQm94U3RydWN0LnByb3RvdHlwZS5zaXplID0gNDA7XG5cbmV4cG9ydCB0eXBlIENvbGxpc2lvbkJveCA9IENvbGxpc2lvbkJveFN0cnVjdDtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgY2xhc3MgQ29sbGlzaW9uQm94QXJyYXkgZXh0ZW5kcyBTdHJ1Y3RBcnJheUxheW91dDVpNGYxaTF1bDJ1aTQwIHtcbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIENvbGxpc2lvbkJveFN0cnVjdCBhdCB0aGUgZ2l2ZW4gbG9jYXRpb24gaW4gdGhlIGFycmF5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQuXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBnZXQoaW5kZXg6IG51bWJlcik6IENvbGxpc2lvbkJveFN0cnVjdCB7XG4gICAgICAgIGFzc2VydCghdGhpcy5pc1RyYW5zZmVycmVkKTtcbiAgICAgICAgYXNzZXJ0KGluZGV4ID49IDApO1xuICAgICAgICBhc3NlcnQoaW5kZXggPCB0aGlzLmxlbmd0aCk7XG4gICAgICAgIHJldHVybiBuZXcgQ29sbGlzaW9uQm94U3RydWN0KHRoaXMsIGluZGV4KTtcbiAgICB9XG59XG5cbnJlZ2lzdGVyKENvbGxpc2lvbkJveEFycmF5LCAnQ29sbGlzaW9uQm94QXJyYXknKTtcblxuY2xhc3MgUGxhY2VkU3ltYm9sU3RydWN0IGV4dGVuZHMgU3RydWN0IHtcbiAgICBfc3RydWN0QXJyYXk6IFBsYWNlZFN5bWJvbEFycmF5O1xuICAgIGdldCBwcm9qZWN0ZWRBbmNob3JYKCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9zdHJ1Y3RBcnJheS5pbnQxNlt0aGlzLl9wb3MyICsgMF07IH1cbiAgICBnZXQgcHJvamVjdGVkQW5jaG9yWSgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkuaW50MTZbdGhpcy5fcG9zMiArIDFdOyB9XG4gICAgZ2V0IHByb2plY3RlZEFuY2hvclooKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3N0cnVjdEFycmF5LmludDE2W3RoaXMuX3BvczIgKyAyXTsgfVxuICAgIGdldCB0aWxlQW5jaG9yWCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkuZmxvYXQzMlt0aGlzLl9wb3M0ICsgMl07IH1cbiAgICBnZXQgdGlsZUFuY2hvclkoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3N0cnVjdEFycmF5LmZsb2F0MzJbdGhpcy5fcG9zNCArIDNdOyB9XG4gICAgZ2V0IGdseXBoU3RhcnRJbmRleCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkudWludDE2W3RoaXMuX3BvczIgKyA4XTsgfVxuICAgIGdldCBudW1HbHlwaHMoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3N0cnVjdEFycmF5LnVpbnQxNlt0aGlzLl9wb3MyICsgOV07IH1cbiAgICBnZXQgdmVydGV4U3RhcnRJbmRleCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkudWludDMyW3RoaXMuX3BvczQgKyA1XTsgfVxuICAgIGdldCBsaW5lU3RhcnRJbmRleCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkudWludDMyW3RoaXMuX3BvczQgKyA2XTsgfVxuICAgIGdldCBsaW5lTGVuZ3RoKCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9zdHJ1Y3RBcnJheS51aW50MzJbdGhpcy5fcG9zNCArIDddOyB9XG4gICAgZ2V0IHNlZ21lbnQoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3N0cnVjdEFycmF5LnVpbnQxNlt0aGlzLl9wb3MyICsgMTZdOyB9XG4gICAgZ2V0IGxvd2VyU2l6ZSgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkudWludDE2W3RoaXMuX3BvczIgKyAxN107IH1cbiAgICBnZXQgdXBwZXJTaXplKCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9zdHJ1Y3RBcnJheS51aW50MTZbdGhpcy5fcG9zMiArIDE4XTsgfVxuICAgIGdldCBsaW5lT2Zmc2V0WCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkuZmxvYXQzMlt0aGlzLl9wb3M0ICsgMTBdOyB9XG4gICAgZ2V0IGxpbmVPZmZzZXRZKCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9zdHJ1Y3RBcnJheS5mbG9hdDMyW3RoaXMuX3BvczQgKyAxMV07IH1cbiAgICBnZXQgd3JpdGluZ01vZGUoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3N0cnVjdEFycmF5LnVpbnQ4W3RoaXMuX3BvczEgKyA0OF07IH1cbiAgICBnZXQgcGxhY2VkT3JpZW50YXRpb24oKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3N0cnVjdEFycmF5LnVpbnQ4W3RoaXMuX3BvczEgKyA0OV07IH1cbiAgICBzZXQgcGxhY2VkT3JpZW50YXRpb24oeDogbnVtYmVyKSB7IHRoaXMuX3N0cnVjdEFycmF5LnVpbnQ4W3RoaXMuX3BvczEgKyA0OV0gPSB4OyB9XG4gICAgZ2V0IGhpZGRlbigpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkudWludDhbdGhpcy5fcG9zMSArIDUwXTsgfVxuICAgIHNldCBoaWRkZW4oeDogbnVtYmVyKSB7IHRoaXMuX3N0cnVjdEFycmF5LnVpbnQ4W3RoaXMuX3BvczEgKyA1MF0gPSB4OyB9XG4gICAgZ2V0IGNyb3NzVGlsZUlEKCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9zdHJ1Y3RBcnJheS51aW50MzJbdGhpcy5fcG9zNCArIDEzXTsgfVxuICAgIHNldCBjcm9zc1RpbGVJRCh4OiBudW1iZXIpIHsgdGhpcy5fc3RydWN0QXJyYXkudWludDMyW3RoaXMuX3BvczQgKyAxM10gPSB4OyB9XG4gICAgZ2V0IGFzc29jaWF0ZWRJY29uSW5kZXgoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3N0cnVjdEFycmF5LmludDE2W3RoaXMuX3BvczIgKyAyOF07IH1cbiAgICBnZXQgZmxpcFN0YXRlKCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9zdHJ1Y3RBcnJheS51aW50OFt0aGlzLl9wb3MxICsgNThdOyB9XG4gICAgc2V0IGZsaXBTdGF0ZSh4OiBudW1iZXIpIHsgdGhpcy5fc3RydWN0QXJyYXkudWludDhbdGhpcy5fcG9zMSArIDU4XSA9IHg7IH1cbn1cblxuUGxhY2VkU3ltYm9sU3RydWN0LnByb3RvdHlwZS5zaXplID0gNjA7XG5cbmV4cG9ydCB0eXBlIFBsYWNlZFN5bWJvbCA9IFBsYWNlZFN5bWJvbFN0cnVjdDtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgY2xhc3MgUGxhY2VkU3ltYm9sQXJyYXkgZXh0ZW5kcyBTdHJ1Y3RBcnJheUxheW91dDNpMmYydWkzdWwzdWkyZjN1YjF1bDFpMXViNjAge1xuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgUGxhY2VkU3ltYm9sU3RydWN0IGF0IHRoZSBnaXZlbiBsb2NhdGlvbiBpbiB0aGUgYXJyYXkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudC5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIGdldChpbmRleDogbnVtYmVyKTogUGxhY2VkU3ltYm9sU3RydWN0IHtcbiAgICAgICAgYXNzZXJ0KCF0aGlzLmlzVHJhbnNmZXJyZWQpO1xuICAgICAgICBhc3NlcnQoaW5kZXggPj0gMCk7XG4gICAgICAgIGFzc2VydChpbmRleCA8IHRoaXMubGVuZ3RoKTtcbiAgICAgICAgcmV0dXJuIG5ldyBQbGFjZWRTeW1ib2xTdHJ1Y3QodGhpcywgaW5kZXgpO1xuICAgIH1cbn1cblxucmVnaXN0ZXIoUGxhY2VkU3ltYm9sQXJyYXksICdQbGFjZWRTeW1ib2xBcnJheScpO1xuXG5jbGFzcyBTeW1ib2xJbnN0YW5jZVN0cnVjdCBleHRlbmRzIFN0cnVjdCB7XG4gICAgX3N0cnVjdEFycmF5OiBTeW1ib2xJbnN0YW5jZUFycmF5O1xuICAgIGdldCBwcm9qZWN0ZWRBbmNob3JYKCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9zdHJ1Y3RBcnJheS5pbnQxNlt0aGlzLl9wb3MyICsgMF07IH1cbiAgICBnZXQgcHJvamVjdGVkQW5jaG9yWSgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkuaW50MTZbdGhpcy5fcG9zMiArIDFdOyB9XG4gICAgZ2V0IHByb2plY3RlZEFuY2hvclooKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3N0cnVjdEFycmF5LmludDE2W3RoaXMuX3BvczIgKyAyXTsgfVxuICAgIGdldCB0aWxlQW5jaG9yWCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkuZmxvYXQzMlt0aGlzLl9wb3M0ICsgMl07IH1cbiAgICBnZXQgdGlsZUFuY2hvclkoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3N0cnVjdEFycmF5LmZsb2F0MzJbdGhpcy5fcG9zNCArIDNdOyB9XG4gICAgZ2V0IHJpZ2h0SnVzdGlmaWVkVGV4dFN5bWJvbEluZGV4KCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9zdHJ1Y3RBcnJheS5pbnQxNlt0aGlzLl9wb3MyICsgOF07IH1cbiAgICBnZXQgY2VudGVySnVzdGlmaWVkVGV4dFN5bWJvbEluZGV4KCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9zdHJ1Y3RBcnJheS5pbnQxNlt0aGlzLl9wb3MyICsgOV07IH1cbiAgICBnZXQgbGVmdEp1c3RpZmllZFRleHRTeW1ib2xJbmRleCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkuaW50MTZbdGhpcy5fcG9zMiArIDEwXTsgfVxuICAgIGdldCB2ZXJ0aWNhbFBsYWNlZFRleHRTeW1ib2xJbmRleCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkuaW50MTZbdGhpcy5fcG9zMiArIDExXTsgfVxuICAgIGdldCBwbGFjZWRJY29uU3ltYm9sSW5kZXgoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3N0cnVjdEFycmF5LmludDE2W3RoaXMuX3BvczIgKyAxMl07IH1cbiAgICBnZXQgdmVydGljYWxQbGFjZWRJY29uU3ltYm9sSW5kZXgoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3N0cnVjdEFycmF5LmludDE2W3RoaXMuX3BvczIgKyAxM107IH1cbiAgICBnZXQga2V5KCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9zdHJ1Y3RBcnJheS51aW50MTZbdGhpcy5fcG9zMiArIDE0XTsgfVxuICAgIGdldCB0ZXh0Qm94U3RhcnRJbmRleCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkudWludDE2W3RoaXMuX3BvczIgKyAxNV07IH1cbiAgICBnZXQgdGV4dEJveEVuZEluZGV4KCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9zdHJ1Y3RBcnJheS51aW50MTZbdGhpcy5fcG9zMiArIDE2XTsgfVxuICAgIGdldCB2ZXJ0aWNhbFRleHRCb3hTdGFydEluZGV4KCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9zdHJ1Y3RBcnJheS51aW50MTZbdGhpcy5fcG9zMiArIDE3XTsgfVxuICAgIGdldCB2ZXJ0aWNhbFRleHRCb3hFbmRJbmRleCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkudWludDE2W3RoaXMuX3BvczIgKyAxOF07IH1cbiAgICBnZXQgaWNvbkJveFN0YXJ0SW5kZXgoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3N0cnVjdEFycmF5LnVpbnQxNlt0aGlzLl9wb3MyICsgMTldOyB9XG4gICAgZ2V0IGljb25Cb3hFbmRJbmRleCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkudWludDE2W3RoaXMuX3BvczIgKyAyMF07IH1cbiAgICBnZXQgdmVydGljYWxJY29uQm94U3RhcnRJbmRleCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkudWludDE2W3RoaXMuX3BvczIgKyAyMV07IH1cbiAgICBnZXQgdmVydGljYWxJY29uQm94RW5kSW5kZXgoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3N0cnVjdEFycmF5LnVpbnQxNlt0aGlzLl9wb3MyICsgMjJdOyB9XG4gICAgZ2V0IGZlYXR1cmVJbmRleCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkudWludDE2W3RoaXMuX3BvczIgKyAyM107IH1cbiAgICBnZXQgbnVtSG9yaXpvbnRhbEdseXBoVmVydGljZXMoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3N0cnVjdEFycmF5LnVpbnQxNlt0aGlzLl9wb3MyICsgMjRdOyB9XG4gICAgZ2V0IG51bVZlcnRpY2FsR2x5cGhWZXJ0aWNlcygpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkudWludDE2W3RoaXMuX3BvczIgKyAyNV07IH1cbiAgICBnZXQgbnVtSWNvblZlcnRpY2VzKCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9zdHJ1Y3RBcnJheS51aW50MTZbdGhpcy5fcG9zMiArIDI2XTsgfVxuICAgIGdldCBudW1WZXJ0aWNhbEljb25WZXJ0aWNlcygpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkudWludDE2W3RoaXMuX3BvczIgKyAyN107IH1cbiAgICBnZXQgdXNlUnVudGltZUNvbGxpc2lvbkNpcmNsZXMoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3N0cnVjdEFycmF5LnVpbnQxNlt0aGlzLl9wb3MyICsgMjhdOyB9XG4gICAgZ2V0IGNyb3NzVGlsZUlEKCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9zdHJ1Y3RBcnJheS51aW50MzJbdGhpcy5fcG9zNCArIDE1XTsgfVxuICAgIHNldCBjcm9zc1RpbGVJRCh4OiBudW1iZXIpIHsgdGhpcy5fc3RydWN0QXJyYXkudWludDMyW3RoaXMuX3BvczQgKyAxNV0gPSB4OyB9XG4gICAgZ2V0IHRleHRPZmZzZXQwKCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9zdHJ1Y3RBcnJheS5mbG9hdDMyW3RoaXMuX3BvczQgKyAxNl07IH1cbiAgICBnZXQgdGV4dE9mZnNldDEoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3N0cnVjdEFycmF5LmZsb2F0MzJbdGhpcy5fcG9zNCArIDE3XTsgfVxuICAgIGdldCBjb2xsaXNpb25DaXJjbGVEaWFtZXRlcigpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkuZmxvYXQzMlt0aGlzLl9wb3M0ICsgMThdOyB9XG59XG5cblN5bWJvbEluc3RhbmNlU3RydWN0LnByb3RvdHlwZS5zaXplID0gNzY7XG5cbmV4cG9ydCB0eXBlIFN5bWJvbEluc3RhbmNlID0gU3ltYm9sSW5zdGFuY2VTdHJ1Y3Q7XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGNsYXNzIFN5bWJvbEluc3RhbmNlQXJyYXkgZXh0ZW5kcyBTdHJ1Y3RBcnJheUxheW91dDNpMmY2aTE1dWkxdWwzZjc2IHtcbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIFN5bWJvbEluc3RhbmNlU3RydWN0IGF0IHRoZSBnaXZlbiBsb2NhdGlvbiBpbiB0aGUgYXJyYXkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudC5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIGdldChpbmRleDogbnVtYmVyKTogU3ltYm9sSW5zdGFuY2VTdHJ1Y3Qge1xuICAgICAgICBhc3NlcnQoIXRoaXMuaXNUcmFuc2ZlcnJlZCk7XG4gICAgICAgIGFzc2VydChpbmRleCA+PSAwKTtcbiAgICAgICAgYXNzZXJ0KGluZGV4IDwgdGhpcy5sZW5ndGgpO1xuICAgICAgICByZXR1cm4gbmV3IFN5bWJvbEluc3RhbmNlU3RydWN0KHRoaXMsIGluZGV4KTtcbiAgICB9XG59XG5cbnJlZ2lzdGVyKFN5bWJvbEluc3RhbmNlQXJyYXksICdTeW1ib2xJbnN0YW5jZUFycmF5Jyk7XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGNsYXNzIEdseXBoT2Zmc2V0QXJyYXkgZXh0ZW5kcyBTdHJ1Y3RBcnJheUxheW91dDFmNCB7XG4gICAgZ2V0b2Zmc2V0WChpbmRleDogbnVtYmVyKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuZmxvYXQzMltpbmRleCAqIDEgKyAwXTsgfVxufVxuXG5yZWdpc3RlcihHbHlwaE9mZnNldEFycmF5LCAnR2x5cGhPZmZzZXRBcnJheScpO1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBjbGFzcyBTeW1ib2xMaW5lVmVydGV4QXJyYXkgZXh0ZW5kcyBTdHJ1Y3RBcnJheUxheW91dDJpNCB7XG4gICAgZ2V0eChpbmRleDogbnVtYmVyKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuaW50MTZbaW5kZXggKiAyICsgMF07IH1cbiAgICBnZXR5KGluZGV4OiBudW1iZXIpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5pbnQxNltpbmRleCAqIDIgKyAxXTsgfVxufVxuXG5yZWdpc3RlcihTeW1ib2xMaW5lVmVydGV4QXJyYXksICdTeW1ib2xMaW5lVmVydGV4QXJyYXknKTtcblxuY2xhc3MgRmVhdHVyZUluZGV4U3RydWN0IGV4dGVuZHMgU3RydWN0IHtcbiAgICBfc3RydWN0QXJyYXk6IEZlYXR1cmVJbmRleEFycmF5O1xuICAgIGdldCBmZWF0dXJlSW5kZXgoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3N0cnVjdEFycmF5LnVpbnQzMlt0aGlzLl9wb3M0ICsgMF07IH1cbiAgICBnZXQgc291cmNlTGF5ZXJJbmRleCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkudWludDE2W3RoaXMuX3BvczIgKyAyXTsgfVxuICAgIGdldCBidWNrZXRJbmRleCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkudWludDE2W3RoaXMuX3BvczIgKyAzXTsgfVxuICAgIGdldCBsYXlvdXRWZXJ0ZXhBcnJheU9mZnNldCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc3RydWN0QXJyYXkudWludDE2W3RoaXMuX3BvczIgKyA0XTsgfVxufVxuXG5GZWF0dXJlSW5kZXhTdHJ1Y3QucHJvdG90eXBlLnNpemUgPSAxMjtcblxuZXhwb3J0IHR5cGUgRmVhdHVyZUluZGV4ID0gRmVhdHVyZUluZGV4U3RydWN0O1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBjbGFzcyBGZWF0dXJlSW5kZXhBcnJheSBleHRlbmRzIFN0cnVjdEFycmF5TGF5b3V0MXVsM3VpMTIge1xuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgRmVhdHVyZUluZGV4U3RydWN0IGF0IHRoZSBnaXZlbiBsb2NhdGlvbiBpbiB0aGUgYXJyYXkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudC5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIGdldChpbmRleDogbnVtYmVyKTogRmVhdHVyZUluZGV4U3RydWN0IHtcbiAgICAgICAgYXNzZXJ0KCF0aGlzLmlzVHJhbnNmZXJyZWQpO1xuICAgICAgICBhc3NlcnQoaW5kZXggPj0gMCk7XG4gICAgICAgIGFzc2VydChpbmRleCA8IHRoaXMubGVuZ3RoKTtcbiAgICAgICAgcmV0dXJuIG5ldyBGZWF0dXJlSW5kZXhTdHJ1Y3QodGhpcywgaW5kZXgpO1xuICAgIH1cbn1cblxucmVnaXN0ZXIoRmVhdHVyZUluZGV4QXJyYXksICdGZWF0dXJlSW5kZXhBcnJheScpO1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWxsRXh0cnVzaW9uQ2VudHJvaWRBcnJheSBleHRlbmRzIFN0cnVjdEFycmF5TGF5b3V0MnVpNCB7XG4gICAgZ2V0YV9jZW50cm9pZF9wb3MwKGluZGV4OiBudW1iZXIpOiBudW1iZXIgeyByZXR1cm4gdGhpcy51aW50MTZbaW5kZXggKiAyICsgMF07IH1cbiAgICBnZXRhX2NlbnRyb2lkX3BvczEoaW5kZXg6IG51bWJlcik6IG51bWJlciB7IHJldHVybiB0aGlzLnVpbnQxNltpbmRleCAqIDIgKyAxXTsgfVxufVxuXG5yZWdpc3RlcihGaWxsRXh0cnVzaW9uQ2VudHJvaWRBcnJheSwgJ0ZpbGxFeHRydXNpb25DZW50cm9pZEFycmF5Jyk7XG5cbmV4cG9ydCB7XG4gICAgU3RydWN0QXJyYXlMYXlvdXQyaTQsXG4gICAgU3RydWN0QXJyYXlMYXlvdXQzaTYsXG4gICAgU3RydWN0QXJyYXlMYXlvdXQ0aTgsXG4gICAgU3RydWN0QXJyYXlMYXlvdXQyaTR1YjFmMTIsXG4gICAgU3RydWN0QXJyYXlMYXlvdXQ0ZjE2LFxuICAgIFN0cnVjdEFycmF5TGF5b3V0NHVpMWYxMixcbiAgICBTdHJ1Y3RBcnJheUxheW91dDR1aTgsXG4gICAgU3RydWN0QXJyYXlMYXlvdXQ2aTEyLFxuICAgIFN0cnVjdEFycmF5TGF5b3V0NGk0dWk0aTI0LFxuICAgIFN0cnVjdEFycmF5TGF5b3V0M2kzZjIwLFxuICAgIFN0cnVjdEFycmF5TGF5b3V0MXVsNCxcbiAgICBTdHJ1Y3RBcnJheUxheW91dDVpNGYxaTF1bDJ1aTQwLFxuICAgIFN0cnVjdEFycmF5TGF5b3V0M2kyaTJpMTYsXG4gICAgU3RydWN0QXJyYXlMYXlvdXQyZjFmMmkxNixcbiAgICBTdHJ1Y3RBcnJheUxheW91dDJ1YjJmMTIsXG4gICAgU3RydWN0QXJyYXlMYXlvdXQzZjEyLFxuICAgIFN0cnVjdEFycmF5TGF5b3V0M3VpNixcbiAgICBTdHJ1Y3RBcnJheUxheW91dDNpMmYydWkzdWwzdWkyZjN1YjF1bDFpMXViNjAsXG4gICAgU3RydWN0QXJyYXlMYXlvdXQzaTJmNmkxNXVpMXVsM2Y3NixcbiAgICBTdHJ1Y3RBcnJheUxheW91dDFmNCxcbiAgICBTdHJ1Y3RBcnJheUxheW91dDVmMjAsXG4gICAgU3RydWN0QXJyYXlMYXlvdXQxdWwzdWkxMixcbiAgICBTdHJ1Y3RBcnJheUxheW91dDJ1aTQsXG4gICAgU3RydWN0QXJyYXlMYXlvdXQxdWkyLFxuICAgIFN0cnVjdEFycmF5TGF5b3V0MmY4LFxuICAgIFN0cnVjdEFycmF5TGF5b3V0Mmk0IGFzIFBvc0FycmF5LFxuICAgIFN0cnVjdEFycmF5TGF5b3V0M2k2IGFzIFBvc0dsb2JlRXh0QXJyYXksXG4gICAgU3RydWN0QXJyYXlMYXlvdXQ0aTggYXMgUmFzdGVyQm91bmRzQXJyYXksXG4gICAgU3RydWN0QXJyYXlMYXlvdXQyaTQgYXMgQ2lyY2xlTGF5b3V0QXJyYXksXG4gICAgU3RydWN0QXJyYXlMYXlvdXQyaTQgYXMgRmlsbExheW91dEFycmF5LFxuICAgIFN0cnVjdEFycmF5TGF5b3V0NGk4IGFzIEZpbGxFeHRydXNpb25MYXlvdXRBcnJheSxcbiAgICBTdHJ1Y3RBcnJheUxheW91dDJpNCBhcyBIZWF0bWFwTGF5b3V0QXJyYXksXG4gICAgU3RydWN0QXJyYXlMYXlvdXQyaTR1YjFmMTIgYXMgTGluZUxheW91dEFycmF5LFxuICAgIFN0cnVjdEFycmF5TGF5b3V0NGYxNiBhcyBMaW5lRXh0TGF5b3V0QXJyYXksXG4gICAgU3RydWN0QXJyYXlMYXlvdXQ0dWkxZjEyIGFzIFBhdHRlcm5MYXlvdXRBcnJheSxcbiAgICBTdHJ1Y3RBcnJheUxheW91dDR1aTggYXMgRGFzaExheW91dEFycmF5LFxuICAgIFN0cnVjdEFycmF5TGF5b3V0NmkxMiBhcyBGaWxsRXh0cnVzaW9uRXh0QXJyYXksXG4gICAgU3RydWN0QXJyYXlMYXlvdXQ0aTR1aTRpMjQgYXMgU3ltYm9sTGF5b3V0QXJyYXksXG4gICAgU3RydWN0QXJyYXlMYXlvdXQzaTNmMjAgYXMgU3ltYm9sR2xvYmVFeHRBcnJheSxcbiAgICBTdHJ1Y3RBcnJheUxheW91dDRmMTYgYXMgU3ltYm9sRHluYW1pY0xheW91dEFycmF5LFxuICAgIFN0cnVjdEFycmF5TGF5b3V0MXVsNCBhcyBTeW1ib2xPcGFjaXR5QXJyYXksXG4gICAgU3RydWN0QXJyYXlMYXlvdXQzaTJpMmkxNiBhcyBDb2xsaXNpb25Cb3hMYXlvdXRBcnJheSxcbiAgICBTdHJ1Y3RBcnJheUxheW91dDJmMWYyaTE2IGFzIENvbGxpc2lvbkNpcmNsZUxheW91dEFycmF5LFxuICAgIFN0cnVjdEFycmF5TGF5b3V0MnViMmYxMiBhcyBDb2xsaXNpb25WZXJ0ZXhBcnJheSxcbiAgICBTdHJ1Y3RBcnJheUxheW91dDNmMTIgYXMgQ29sbGlzaW9uVmVydGV4RXh0QXJyYXksXG4gICAgU3RydWN0QXJyYXlMYXlvdXQzdWk2IGFzIFF1YWRUcmlhbmdsZUFycmF5LFxuICAgIFN0cnVjdEFycmF5TGF5b3V0NWYyMCBhcyBHbG9iZVZlcnRleEFycmF5LFxuICAgIFN0cnVjdEFycmF5TGF5b3V0NWYyMCBhcyBBdG1vc3BoZXJlVmVydGV4QXJyYXksXG4gICAgU3RydWN0QXJyYXlMYXlvdXQzdWk2IGFzIFRyaWFuZ2xlSW5kZXhBcnJheSxcbiAgICBTdHJ1Y3RBcnJheUxheW91dDJ1aTQgYXMgTGluZUluZGV4QXJyYXksXG4gICAgU3RydWN0QXJyYXlMYXlvdXQxdWkyIGFzIExpbmVTdHJpcEluZGV4QXJyYXksXG4gICAgU3RydWN0QXJyYXlMYXlvdXQzZjEyIGFzIFNreWJveFZlcnRleEFycmF5LFxuICAgIFN0cnVjdEFycmF5TGF5b3V0NGk4IGFzIFRpbGVCb3VuZHNBcnJheSxcbiAgICBTdHJ1Y3RBcnJheUxheW91dDZpMTIgYXMgQ2lyY2xlR2xvYmVFeHRBcnJheVxufTtcbiIsIi8vIEBmbG93XG5pbXBvcnQge2NyZWF0ZUxheW91dH0gZnJvbSAnLi4vLi4vdXRpbC9zdHJ1Y3RfYXJyYXkuanMnO1xuXG5pbXBvcnQgdHlwZSB7U3RydWN0QXJyYXlMYXlvdXR9IGZyb20gJy4uLy4uL3V0aWwvc3RydWN0X2FycmF5LmpzJztcblxuY29uc3QgcGF0dGVybkF0dHJpYnV0ZXM6IFN0cnVjdEFycmF5TGF5b3V0ID0gY3JlYXRlTGF5b3V0KFtcbiAgICAvLyBbdGwueCwgdGwueSwgYnIueCwgYnIueV1cbiAgICB7bmFtZTogJ2FfcGF0dGVybicsIGNvbXBvbmVudHM6IDQsIHR5cGU6ICdVaW50MTYnfSxcbiAgICB7bmFtZTogJ2FfcGl4ZWxfcmF0aW8nLCBjb21wb25lbnRzOiAxLCB0eXBlOiAnRmxvYXQzMid9XG5dKTtcblxuZXhwb3J0IGRlZmF1bHQgcGF0dGVybkF0dHJpYnV0ZXM7XG4iLCIvLyBAZmxvd1xuaW1wb3J0IHtjcmVhdGVMYXlvdXR9IGZyb20gJy4uLy4uL3V0aWwvc3RydWN0X2FycmF5LmpzJztcblxuaW1wb3J0IHR5cGUge1N0cnVjdEFycmF5TGF5b3V0fSBmcm9tICcuLi8uLi91dGlsL3N0cnVjdF9hcnJheS5qcyc7XG5cbmNvbnN0IGRhc2hBdHRyaWJ1dGVzOiBTdHJ1Y3RBcnJheUxheW91dCA9IGNyZWF0ZUxheW91dChbXG4gICAge25hbWU6ICdhX2Rhc2gnLCBjb21wb25lbnRzOiA0LCB0eXBlOiAnVWludDE2J30gLy8gW3gsIHksIHdpZHRoLCB1bnVzZWRdXG5dKTtcblxuZXhwb3J0IGRlZmF1bHQgZGFzaEF0dHJpYnV0ZXM7XG4iLCIvKipcbiAqIEpTIEltcGxlbWVudGF0aW9uIG9mIE11cm11ckhhc2gzIChyMTM2KSAoYXMgb2YgTWF5IDIwLCAyMDExKVxuICogXG4gKiBAYXV0aG9yIDxhIGhyZWY9XCJtYWlsdG86Z2FyeS5jb3VydEBnbWFpbC5jb21cIj5HYXJ5IENvdXJ0PC9hPlxuICogQHNlZSBodHRwOi8vZ2l0aHViLmNvbS9nYXJ5Y291cnQvbXVybXVyaGFzaC1qc1xuICogQGF1dGhvciA8YSBocmVmPVwibWFpbHRvOmFhcHBsZWJ5QGdtYWlsLmNvbVwiPkF1c3RpbiBBcHBsZWJ5PC9hPlxuICogQHNlZSBodHRwOi8vc2l0ZXMuZ29vZ2xlLmNvbS9zaXRlL211cm11cmhhc2gvXG4gKiBcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgQVNDSUkgb25seVxuICogQHBhcmFtIHtudW1iZXJ9IHNlZWQgUG9zaXRpdmUgaW50ZWdlciBvbmx5XG4gKiBAcmV0dXJuIHtudW1iZXJ9IDMyLWJpdCBwb3NpdGl2ZSBpbnRlZ2VyIGhhc2ggXG4gKi9cblxuZnVuY3Rpb24gbXVybXVyaGFzaDNfMzJfZ2Moa2V5LCBzZWVkKSB7XG5cdHZhciByZW1haW5kZXIsIGJ5dGVzLCBoMSwgaDFiLCBjMSwgYzFiLCBjMiwgYzJiLCBrMSwgaTtcblx0XG5cdHJlbWFpbmRlciA9IGtleS5sZW5ndGggJiAzOyAvLyBrZXkubGVuZ3RoICUgNFxuXHRieXRlcyA9IGtleS5sZW5ndGggLSByZW1haW5kZXI7XG5cdGgxID0gc2VlZDtcblx0YzEgPSAweGNjOWUyZDUxO1xuXHRjMiA9IDB4MWI4NzM1OTM7XG5cdGkgPSAwO1xuXHRcblx0d2hpbGUgKGkgPCBieXRlcykge1xuXHQgIFx0azEgPSBcblx0ICBcdCAgKChrZXkuY2hhckNvZGVBdChpKSAmIDB4ZmYpKSB8XG5cdCAgXHQgICgoa2V5LmNoYXJDb2RlQXQoKytpKSAmIDB4ZmYpIDw8IDgpIHxcblx0ICBcdCAgKChrZXkuY2hhckNvZGVBdCgrK2kpICYgMHhmZikgPDwgMTYpIHxcblx0ICBcdCAgKChrZXkuY2hhckNvZGVBdCgrK2kpICYgMHhmZikgPDwgMjQpO1xuXHRcdCsraTtcblx0XHRcblx0XHRrMSA9ICgoKChrMSAmIDB4ZmZmZikgKiBjMSkgKyAoKCgoazEgPj4+IDE2KSAqIGMxKSAmIDB4ZmZmZikgPDwgMTYpKSkgJiAweGZmZmZmZmZmO1xuXHRcdGsxID0gKGsxIDw8IDE1KSB8IChrMSA+Pj4gMTcpO1xuXHRcdGsxID0gKCgoKGsxICYgMHhmZmZmKSAqIGMyKSArICgoKChrMSA+Pj4gMTYpICogYzIpICYgMHhmZmZmKSA8PCAxNikpKSAmIDB4ZmZmZmZmZmY7XG5cblx0XHRoMSBePSBrMTtcbiAgICAgICAgaDEgPSAoaDEgPDwgMTMpIHwgKGgxID4+PiAxOSk7XG5cdFx0aDFiID0gKCgoKGgxICYgMHhmZmZmKSAqIDUpICsgKCgoKGgxID4+PiAxNikgKiA1KSAmIDB4ZmZmZikgPDwgMTYpKSkgJiAweGZmZmZmZmZmO1xuXHRcdGgxID0gKCgoaDFiICYgMHhmZmZmKSArIDB4NmI2NCkgKyAoKCgoaDFiID4+PiAxNikgKyAweGU2NTQpICYgMHhmZmZmKSA8PCAxNikpO1xuXHR9XG5cdFxuXHRrMSA9IDA7XG5cdFxuXHRzd2l0Y2ggKHJlbWFpbmRlcikge1xuXHRcdGNhc2UgMzogazEgXj0gKGtleS5jaGFyQ29kZUF0KGkgKyAyKSAmIDB4ZmYpIDw8IDE2O1xuXHRcdGNhc2UgMjogazEgXj0gKGtleS5jaGFyQ29kZUF0KGkgKyAxKSAmIDB4ZmYpIDw8IDg7XG5cdFx0Y2FzZSAxOiBrMSBePSAoa2V5LmNoYXJDb2RlQXQoaSkgJiAweGZmKTtcblx0XHRcblx0XHRrMSA9ICgoKGsxICYgMHhmZmZmKSAqIGMxKSArICgoKChrMSA+Pj4gMTYpICogYzEpICYgMHhmZmZmKSA8PCAxNikpICYgMHhmZmZmZmZmZjtcblx0XHRrMSA9IChrMSA8PCAxNSkgfCAoazEgPj4+IDE3KTtcblx0XHRrMSA9ICgoKGsxICYgMHhmZmZmKSAqIGMyKSArICgoKChrMSA+Pj4gMTYpICogYzIpICYgMHhmZmZmKSA8PCAxNikpICYgMHhmZmZmZmZmZjtcblx0XHRoMSBePSBrMTtcblx0fVxuXHRcblx0aDEgXj0ga2V5Lmxlbmd0aDtcblxuXHRoMSBePSBoMSA+Pj4gMTY7XG5cdGgxID0gKCgoaDEgJiAweGZmZmYpICogMHg4NWViY2E2YikgKyAoKCgoaDEgPj4+IDE2KSAqIDB4ODVlYmNhNmIpICYgMHhmZmZmKSA8PCAxNikpICYgMHhmZmZmZmZmZjtcblx0aDEgXj0gaDEgPj4+IDEzO1xuXHRoMSA9ICgoKChoMSAmIDB4ZmZmZikgKiAweGMyYjJhZTM1KSArICgoKChoMSA+Pj4gMTYpICogMHhjMmIyYWUzNSkgJiAweGZmZmYpIDw8IDE2KSkpICYgMHhmZmZmZmZmZjtcblx0aDEgXj0gaDEgPj4+IDE2O1xuXG5cdHJldHVybiBoMSA+Pj4gMDtcbn1cblxuaWYodHlwZW9mIG1vZHVsZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICBtb2R1bGUuZXhwb3J0cyA9IG11cm11cmhhc2gzXzMyX2djXG59IiwiLyoqXG4gKiBKUyBJbXBsZW1lbnRhdGlvbiBvZiBNdXJtdXJIYXNoMlxuICogXG4gKiBAYXV0aG9yIDxhIGhyZWY9XCJtYWlsdG86Z2FyeS5jb3VydEBnbWFpbC5jb21cIj5HYXJ5IENvdXJ0PC9hPlxuICogQHNlZSBodHRwOi8vZ2l0aHViLmNvbS9nYXJ5Y291cnQvbXVybXVyaGFzaC1qc1xuICogQGF1dGhvciA8YSBocmVmPVwibWFpbHRvOmFhcHBsZWJ5QGdtYWlsLmNvbVwiPkF1c3RpbiBBcHBsZWJ5PC9hPlxuICogQHNlZSBodHRwOi8vc2l0ZXMuZ29vZ2xlLmNvbS9zaXRlL211cm11cmhhc2gvXG4gKiBcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgQVNDSUkgb25seVxuICogQHBhcmFtIHtudW1iZXJ9IHNlZWQgUG9zaXRpdmUgaW50ZWdlciBvbmx5XG4gKiBAcmV0dXJuIHtudW1iZXJ9IDMyLWJpdCBwb3NpdGl2ZSBpbnRlZ2VyIGhhc2hcbiAqL1xuXG5mdW5jdGlvbiBtdXJtdXJoYXNoMl8zMl9nYyhzdHIsIHNlZWQpIHtcbiAgdmFyXG4gICAgbCA9IHN0ci5sZW5ndGgsXG4gICAgaCA9IHNlZWQgXiBsLFxuICAgIGkgPSAwLFxuICAgIGs7XG4gIFxuICB3aGlsZSAobCA+PSA0KSB7XG4gIFx0ayA9IFxuICBcdCAgKChzdHIuY2hhckNvZGVBdChpKSAmIDB4ZmYpKSB8XG4gIFx0ICAoKHN0ci5jaGFyQ29kZUF0KCsraSkgJiAweGZmKSA8PCA4KSB8XG4gIFx0ICAoKHN0ci5jaGFyQ29kZUF0KCsraSkgJiAweGZmKSA8PCAxNikgfFxuICBcdCAgKChzdHIuY2hhckNvZGVBdCgrK2kpICYgMHhmZikgPDwgMjQpO1xuICAgIFxuICAgIGsgPSAoKChrICYgMHhmZmZmKSAqIDB4NWJkMWU5OTUpICsgKCgoKGsgPj4+IDE2KSAqIDB4NWJkMWU5OTUpICYgMHhmZmZmKSA8PCAxNikpO1xuICAgIGsgXj0gayA+Pj4gMjQ7XG4gICAgayA9ICgoKGsgJiAweGZmZmYpICogMHg1YmQxZTk5NSkgKyAoKCgoayA+Pj4gMTYpICogMHg1YmQxZTk5NSkgJiAweGZmZmYpIDw8IDE2KSk7XG5cblx0aCA9ICgoKGggJiAweGZmZmYpICogMHg1YmQxZTk5NSkgKyAoKCgoaCA+Pj4gMTYpICogMHg1YmQxZTk5NSkgJiAweGZmZmYpIDw8IDE2KSkgXiBrO1xuXG4gICAgbCAtPSA0O1xuICAgICsraTtcbiAgfVxuICBcbiAgc3dpdGNoIChsKSB7XG4gIGNhc2UgMzogaCBePSAoc3RyLmNoYXJDb2RlQXQoaSArIDIpICYgMHhmZikgPDwgMTY7XG4gIGNhc2UgMjogaCBePSAoc3RyLmNoYXJDb2RlQXQoaSArIDEpICYgMHhmZikgPDwgODtcbiAgY2FzZSAxOiBoIF49IChzdHIuY2hhckNvZGVBdChpKSAmIDB4ZmYpO1xuICAgICAgICAgIGggPSAoKChoICYgMHhmZmZmKSAqIDB4NWJkMWU5OTUpICsgKCgoKGggPj4+IDE2KSAqIDB4NWJkMWU5OTUpICYgMHhmZmZmKSA8PCAxNikpO1xuICB9XG5cbiAgaCBePSBoID4+PiAxMztcbiAgaCA9ICgoKGggJiAweGZmZmYpICogMHg1YmQxZTk5NSkgKyAoKCgoaCA+Pj4gMTYpICogMHg1YmQxZTk5NSkgJiAweGZmZmYpIDw8IDE2KSk7XG4gIGggXj0gaCA+Pj4gMTU7XG5cbiAgcmV0dXJuIGggPj4+IDA7XG59XG5cbmlmKHR5cGVvZiBtb2R1bGUgIT09IHVuZGVmaW5lZCkge1xuICBtb2R1bGUuZXhwb3J0cyA9IG11cm11cmhhc2gyXzMyX2djXG59XG4iLCJ2YXIgbXVybXVyMyA9IHJlcXVpcmUoXCIuL211cm11cmhhc2gzX2djLmpzXCIpXG52YXIgbXVybXVyMiA9IHJlcXVpcmUoXCIuL211cm11cmhhc2gyX2djLmpzXCIpXG5cbm1vZHVsZS5leHBvcnRzID0gbXVybXVyM1xubW9kdWxlLmV4cG9ydHMubXVybXVyMyA9IG11cm11cjNcbm1vZHVsZS5leHBvcnRzLm11cm11cjIgPSBtdXJtdXIyXG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgbXVybXVyMyBmcm9tICdtdXJtdXJoYXNoLWpzJztcbmltcG9ydCB7cmVnaXN0ZXJ9IGZyb20gJy4uL3V0aWwvd2ViX3dvcmtlcl90cmFuc2Zlci5qcyc7XG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbnR5cGUgU2VyaWFsaXplZEZlYXR1cmVQb3NpdGlvbk1hcCA9IHtcbiAgICBpZHM6IEZsb2F0NjRBcnJheTtcbiAgICBwb3NpdGlvbnM6IFVpbnQzMkFycmF5O1xufTtcblxudHlwZSBGZWF0dXJlUG9zaXRpb24gPSB7XG4gICAgaW5kZXg6IG51bWJlcjtcbiAgICBzdGFydDogbnVtYmVyO1xuICAgIGVuZDogbnVtYmVyO1xufTtcblxuLy8gQSB0cmFuc2ZlcmFibGUgZGF0YSBzdHJ1Y3R1cmUgdGhhdCBtYXBzIGZlYXR1cmUgaWRzIHRvIHRoZWlyIGluZGljZXMgYW5kIGJ1ZmZlciBvZmZzZXRzXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBGZWF0dXJlUG9zaXRpb25NYXAge1xuICAgIGlkczogQXJyYXk8bnVtYmVyPjtcbiAgICBwb3NpdGlvbnM6IEFycmF5PG51bWJlcj47XG4gICAgaW5kZXhlZDogYm9vbGVhbjtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLmlkcyA9IFtdO1xuICAgICAgICB0aGlzLnBvc2l0aW9ucyA9IFtdO1xuICAgICAgICB0aGlzLmluZGV4ZWQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBhZGQoaWQ6IG1peGVkLCBpbmRleDogbnVtYmVyLCBzdGFydDogbnVtYmVyLCBlbmQ6IG51bWJlcikge1xuICAgICAgICB0aGlzLmlkcy5wdXNoKGdldE51bWVyaWNJZChpZCkpO1xuICAgICAgICB0aGlzLnBvc2l0aW9ucy5wdXNoKGluZGV4LCBzdGFydCwgZW5kKTtcbiAgICB9XG5cbiAgICBnZXRQb3NpdGlvbnMoaWQ6IG1peGVkKTogQXJyYXk8RmVhdHVyZVBvc2l0aW9uPiB7XG4gICAgICAgIGFzc2VydCh0aGlzLmluZGV4ZWQpO1xuXG4gICAgICAgIGNvbnN0IGludElkID0gZ2V0TnVtZXJpY0lkKGlkKTtcblxuICAgICAgICAvLyBiaW5hcnkgc2VhcmNoIGZvciB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiBpZCBpbiB0aGlzLmlkcztcbiAgICAgICAgLy8gcmVsaWVzIG9uIGlkcy9wb3NpdGlvbnMgYmVpbmcgc29ydGVkIGJ5IGlkLCB3aGljaCBoYXBwZW5zIGluIHNlcmlhbGl6YXRpb25cbiAgICAgICAgbGV0IGkgPSAwO1xuICAgICAgICBsZXQgaiA9IHRoaXMuaWRzLmxlbmd0aCAtIDE7XG4gICAgICAgIHdoaWxlIChpIDwgaikge1xuICAgICAgICAgICAgY29uc3QgbSA9IChpICsgaikgPj4gMTtcbiAgICAgICAgICAgIGlmICh0aGlzLmlkc1ttXSA+PSBpbnRJZCkge1xuICAgICAgICAgICAgICAgIGogPSBtO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpID0gbSArIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcG9zaXRpb25zID0gW107XG4gICAgICAgIHdoaWxlICh0aGlzLmlkc1tpXSA9PT0gaW50SWQpIHtcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5wb3NpdGlvbnNbMyAqIGldO1xuICAgICAgICAgICAgY29uc3Qgc3RhcnQgPSB0aGlzLnBvc2l0aW9uc1szICogaSArIDFdO1xuICAgICAgICAgICAgY29uc3QgZW5kID0gdGhpcy5wb3NpdGlvbnNbMyAqIGkgKyAyXTtcbiAgICAgICAgICAgIHBvc2l0aW9ucy5wdXNoKHtpbmRleCwgc3RhcnQsIGVuZH0pO1xuICAgICAgICAgICAgaSsrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwb3NpdGlvbnM7XG4gICAgfVxuXG4gICAgc3RhdGljIHNlcmlhbGl6ZShtYXA6IEZlYXR1cmVQb3NpdGlvbk1hcCwgdHJhbnNmZXJhYmxlczogQXJyYXk8QXJyYXlCdWZmZXI+KTogU2VyaWFsaXplZEZlYXR1cmVQb3NpdGlvbk1hcCB7XG4gICAgICAgIGNvbnN0IGlkcyA9IG5ldyBGbG9hdDY0QXJyYXkobWFwLmlkcyk7XG4gICAgICAgIGNvbnN0IHBvc2l0aW9ucyA9IG5ldyBVaW50MzJBcnJheShtYXAucG9zaXRpb25zKTtcblxuICAgICAgICBzb3J0KGlkcywgcG9zaXRpb25zLCAwLCBpZHMubGVuZ3RoIC0gMSk7XG5cbiAgICAgICAgaWYgKHRyYW5zZmVyYWJsZXMpIHtcbiAgICAgICAgICAgIHRyYW5zZmVyYWJsZXMucHVzaChpZHMuYnVmZmVyLCBwb3NpdGlvbnMuYnVmZmVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7aWRzLCBwb3NpdGlvbnN9O1xuICAgIH1cblxuICAgIHN0YXRpYyBkZXNlcmlhbGl6ZShvYmo6IFNlcmlhbGl6ZWRGZWF0dXJlUG9zaXRpb25NYXApOiBGZWF0dXJlUG9zaXRpb25NYXAge1xuICAgICAgICBjb25zdCBtYXAgPSBuZXcgRmVhdHVyZVBvc2l0aW9uTWFwKCk7XG4gICAgICAgIC8vIGFmdGVyIHRyYW5zZmVycmluZywgd2Ugb25seSB1c2UgdGhlc2UgYXJyYXlzIHN0YXRpY2FsbHkgKG5vIHB1c2hlcyksXG4gICAgICAgIC8vIHNvIFR5cGVkQXJyYXkgdnMgQXJyYXkgZGlzdGluY3Rpb24gdGhhdCBmbG93IHBvaW50cyBvdXQgZG9lc24ndCBtYXR0ZXJcbiAgICAgICAgbWFwLmlkcyA9IChvYmouaWRzOiBhbnkpO1xuICAgICAgICBtYXAucG9zaXRpb25zID0gKG9iai5wb3NpdGlvbnM6IGFueSk7XG4gICAgICAgIG1hcC5pbmRleGVkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIG1hcDtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGdldE51bWVyaWNJZCh2YWx1ZTogbWl4ZWQpIHtcbiAgICBjb25zdCBudW1WYWx1ZSA9ICt2YWx1ZTtcbiAgICBpZiAoIWlzTmFOKG51bVZhbHVlKSAmJiBOdW1iZXIuTUlOX1NBRkVfSU5URUdFUiA8PSBudW1WYWx1ZSAmJiBudW1WYWx1ZSA8PSBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUikge1xuICAgICAgICByZXR1cm4gbnVtVmFsdWU7XG4gICAgfVxuICAgIHJldHVybiBtdXJtdXIzKFN0cmluZyh2YWx1ZSkpO1xufVxuXG4vLyBjdXN0b20gcXVpY2tzb3J0IHRoYXQgc29ydHMgaWRzLCBpbmRpY2VzIGFuZCBvZmZzZXRzIHRvZ2V0aGVyIChieSBpZHMpXG4vLyB1c2VzIEhvYXJlIHBhcnRpdGlvbmluZyAmIG1hbnVhbCB0YWlsIGNhbGwgb3B0aW1pemF0aW9uIHRvIGF2b2lkIHdvcnN0IGNhc2Ugc2NlbmFyaW9zXG5mdW5jdGlvbiBzb3J0KGlkczogRmxvYXQ2NEFycmF5LCBwb3NpdGlvbnM6IFVpbnQzMkFycmF5LCBsZWZ0OiBudW1iZXIsIHJpZ2h0OiBudW1iZXIpIHtcbiAgICB3aGlsZSAobGVmdCA8IHJpZ2h0KSB7XG4gICAgICAgIGNvbnN0IHBpdm90ID0gaWRzWyhsZWZ0ICsgcmlnaHQpID4+IDFdO1xuICAgICAgICBsZXQgaSA9IGxlZnQgLSAxO1xuICAgICAgICBsZXQgaiA9IHJpZ2h0ICsgMTtcblxuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgZG8gaSsrOyB3aGlsZSAoaWRzW2ldIDwgcGl2b3QpO1xuICAgICAgICAgICAgZG8gai0tOyB3aGlsZSAoaWRzW2pdID4gcGl2b3QpO1xuICAgICAgICAgICAgaWYgKGkgPj0gaikgYnJlYWs7XG4gICAgICAgICAgICBzd2FwKGlkcywgaSwgaik7XG4gICAgICAgICAgICBzd2FwKHBvc2l0aW9ucywgMyAqIGksIDMgKiBqKTtcbiAgICAgICAgICAgIHN3YXAocG9zaXRpb25zLCAzICogaSArIDEsIDMgKiBqICsgMSk7XG4gICAgICAgICAgICBzd2FwKHBvc2l0aW9ucywgMyAqIGkgKyAyLCAzICogaiArIDIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGogLSBsZWZ0IDwgcmlnaHQgLSBqKSB7XG4gICAgICAgICAgICBzb3J0KGlkcywgcG9zaXRpb25zLCBsZWZ0LCBqKTtcbiAgICAgICAgICAgIGxlZnQgPSBqICsgMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNvcnQoaWRzLCBwb3NpdGlvbnMsIGogKyAxLCByaWdodCk7XG4gICAgICAgICAgICByaWdodCA9IGo7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIHN3YXAoYXJyOiBVaW50MzJBcnJheSB8IEZsb2F0NjRBcnJheSwgaTogbnVtYmVyLCBqOiBudW1iZXIpIHtcbiAgICBjb25zdCB0bXAgPSBhcnJbaV07XG4gICAgYXJyW2ldID0gYXJyW2pdO1xuICAgIGFycltqXSA9IHRtcDtcbn1cblxucmVnaXN0ZXIoRmVhdHVyZVBvc2l0aW9uTWFwLCAnRmVhdHVyZVBvc2l0aW9uTWFwJyk7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgQ29sb3IgZnJvbSAnLi4vc3R5bGUtc3BlYy91dGlsL2NvbG9yLmpzJztcbmltcG9ydCB0eXBlIENvbnRleHQgZnJvbSAnLi4vZ2wvY29udGV4dC5qcyc7XG5cbmV4cG9ydCB0eXBlIFVuaWZvcm1WYWx1ZXM8VXM6IE9iamVjdD5cbiAgICA9ICRFeGFjdDwkT2JqTWFwPFVzLCA8Vj4odTogVW5pZm9ybTxWPikgPT4gVj4+O1xuXG5jbGFzcyBVbmlmb3JtPFQ+IHtcbiAgICBnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0O1xuICAgIGxvY2F0aW9uOiA/V2ViR0xVbmlmb3JtTG9jYXRpb247XG4gICAgY3VycmVudDogVDtcbiAgICBpbml0aWFsaXplZDogYm9vbGVhbjtcblxuICAgIGNvbnN0cnVjdG9yKGNvbnRleHQ6IENvbnRleHQpIHtcbiAgICAgICAgdGhpcy5nbCA9IGNvbnRleHQuZ2w7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBmZXRjaFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtOiBXZWJHTFByb2dyYW0sIG5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAoIXRoaXMubG9jYXRpb24gJiYgIXRoaXMuaW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgICAgIHRoaXMubG9jYXRpb24gPSB0aGlzLmdsLmdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCBuYW1lKTtcbiAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAhIXRoaXMubG9jYXRpb247XG4gICAgfVxuXG4gICAgK3NldDogKHByb2dyYW06IFdlYkdMUHJvZ3JhbSwgbmFtZTogc3RyaW5nLCB2OiBUKSA9PiB2b2lkO1xufVxuXG5jbGFzcyBVbmlmb3JtMWkgZXh0ZW5kcyBVbmlmb3JtPG51bWJlcj4ge1xuICAgIGNvbnN0cnVjdG9yKGNvbnRleHQ6IENvbnRleHQpIHtcbiAgICAgICAgc3VwZXIoY29udGV4dCk7XG4gICAgICAgIHRoaXMuY3VycmVudCA9IDA7XG4gICAgfVxuXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIHNldChwcm9ncmFtOiBXZWJHTFByb2dyYW0sIG5hbWU6IHN0cmluZywgdjogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5mZXRjaFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCBuYW1lKSkgcmV0dXJuO1xuICAgICAgICBpZiAodGhpcy5jdXJyZW50ICE9PSB2KSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnQgPSB2O1xuICAgICAgICAgICAgdGhpcy5nbC51bmlmb3JtMWkodGhpcy5sb2NhdGlvbiwgdik7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIFVuaWZvcm0xZiBleHRlbmRzIFVuaWZvcm08bnVtYmVyPiB7XG4gICAgY29uc3RydWN0b3IoY29udGV4dDogQ29udGV4dCkge1xuICAgICAgICBzdXBlcihjb250ZXh0KTtcbiAgICAgICAgdGhpcy5jdXJyZW50ID0gMDtcbiAgICB9XG5cbiAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgc2V0KHByb2dyYW06IFdlYkdMUHJvZ3JhbSwgbmFtZTogc3RyaW5nLCB2OiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLmZldGNoVW5pZm9ybUxvY2F0aW9uKHByb2dyYW0sIG5hbWUpKSByZXR1cm47XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnQgIT09IHYpIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudCA9IHY7XG4gICAgICAgICAgICB0aGlzLmdsLnVuaWZvcm0xZih0aGlzLmxvY2F0aW9uLCB2KTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuY2xhc3MgVW5pZm9ybTJmIGV4dGVuZHMgVW5pZm9ybTxbbnVtYmVyLCBudW1iZXJdPiB7XG4gICAgY29uc3RydWN0b3IoY29udGV4dDogQ29udGV4dCkge1xuICAgICAgICBzdXBlcihjb250ZXh0KTtcbiAgICAgICAgdGhpcy5jdXJyZW50ID0gWzAsIDBdO1xuICAgIH1cblxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICBzZXQocHJvZ3JhbTogV2ViR0xQcm9ncmFtLCBuYW1lOiBzdHJpbmcsIHY6IFtudW1iZXIsIG51bWJlcl0pOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLmZldGNoVW5pZm9ybUxvY2F0aW9uKHByb2dyYW0sIG5hbWUpKSByZXR1cm47XG4gICAgICAgIGlmICh2WzBdICE9PSB0aGlzLmN1cnJlbnRbMF0gfHwgdlsxXSAhPT0gdGhpcy5jdXJyZW50WzFdKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnQgPSB2O1xuICAgICAgICAgICAgdGhpcy5nbC51bmlmb3JtMmYodGhpcy5sb2NhdGlvbiwgdlswXSwgdlsxXSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIFVuaWZvcm0zZiBleHRlbmRzIFVuaWZvcm08W251bWJlciwgbnVtYmVyLCBudW1iZXJdPiB7XG4gICAgY29uc3RydWN0b3IoY29udGV4dDogQ29udGV4dCkge1xuICAgICAgICBzdXBlcihjb250ZXh0KTtcbiAgICAgICAgdGhpcy5jdXJyZW50ID0gWzAsIDAsIDBdO1xuICAgIH1cblxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICBzZXQocHJvZ3JhbTogV2ViR0xQcm9ncmFtLCBuYW1lOiBzdHJpbmcsIHY6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMuZmV0Y2hVbmlmb3JtTG9jYXRpb24ocHJvZ3JhbSwgbmFtZSkpIHJldHVybjtcbiAgICAgICAgaWYgKHZbMF0gIT09IHRoaXMuY3VycmVudFswXSB8fCB2WzFdICE9PSB0aGlzLmN1cnJlbnRbMV0gfHwgdlsyXSAhPT0gdGhpcy5jdXJyZW50WzJdKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnQgPSB2O1xuICAgICAgICAgICAgdGhpcy5nbC51bmlmb3JtM2YodGhpcy5sb2NhdGlvbiwgdlswXSwgdlsxXSwgdlsyXSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIFVuaWZvcm00ZiBleHRlbmRzIFVuaWZvcm08W251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0+IHtcbiAgICBjb25zdHJ1Y3Rvcihjb250ZXh0OiBDb250ZXh0KSB7XG4gICAgICAgIHN1cGVyKGNvbnRleHQpO1xuICAgICAgICB0aGlzLmN1cnJlbnQgPSBbMCwgMCwgMCwgMF07XG4gICAgfVxuXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIHNldChwcm9ncmFtOiBXZWJHTFByb2dyYW0sIG5hbWU6IHN0cmluZywgdjogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0pOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLmZldGNoVW5pZm9ybUxvY2F0aW9uKHByb2dyYW0sIG5hbWUpKSByZXR1cm47XG4gICAgICAgIGlmICh2WzBdICE9PSB0aGlzLmN1cnJlbnRbMF0gfHwgdlsxXSAhPT0gdGhpcy5jdXJyZW50WzFdIHx8XG4gICAgICAgICAgICB2WzJdICE9PSB0aGlzLmN1cnJlbnRbMl0gfHwgdlszXSAhPT0gdGhpcy5jdXJyZW50WzNdKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnQgPSB2O1xuICAgICAgICAgICAgdGhpcy5nbC51bmlmb3JtNGYodGhpcy5sb2NhdGlvbiwgdlswXSwgdlsxXSwgdlsyXSwgdlszXSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIFVuaWZvcm1Db2xvciBleHRlbmRzIFVuaWZvcm08Q29sb3I+IHtcbiAgICBjb25zdHJ1Y3Rvcihjb250ZXh0OiBDb250ZXh0KSB7XG4gICAgICAgIHN1cGVyKGNvbnRleHQpO1xuICAgICAgICB0aGlzLmN1cnJlbnQgPSBDb2xvci50cmFuc3BhcmVudDtcbiAgICB9XG5cbiAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgc2V0KHByb2dyYW06IFdlYkdMUHJvZ3JhbSwgbmFtZTogc3RyaW5nLCB2OiBDb2xvcik6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMuZmV0Y2hVbmlmb3JtTG9jYXRpb24ocHJvZ3JhbSwgbmFtZSkpIHJldHVybjtcbiAgICAgICAgaWYgKHYuciAhPT0gdGhpcy5jdXJyZW50LnIgfHwgdi5nICE9PSB0aGlzLmN1cnJlbnQuZyB8fFxuICAgICAgICAgICAgdi5iICE9PSB0aGlzLmN1cnJlbnQuYiB8fCB2LmEgIT09IHRoaXMuY3VycmVudC5hKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnQgPSB2O1xuICAgICAgICAgICAgdGhpcy5nbC51bmlmb3JtNGYodGhpcy5sb2NhdGlvbiwgdi5yLCB2LmcsIHYuYiwgdi5hKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuY29uc3QgZW1wdHlNYXQ0ID0gbmV3IEZsb2F0MzJBcnJheSgxNik7XG5jbGFzcyBVbmlmb3JtTWF0cml4NGYgZXh0ZW5kcyBVbmlmb3JtPEZsb2F0MzJBcnJheT4ge1xuICAgIGNvbnN0cnVjdG9yKGNvbnRleHQ6IENvbnRleHQpIHtcbiAgICAgICAgc3VwZXIoY29udGV4dCk7XG4gICAgICAgIHRoaXMuY3VycmVudCA9IGVtcHR5TWF0NDtcbiAgICB9XG5cbiAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgc2V0KHByb2dyYW06IFdlYkdMUHJvZ3JhbSwgbmFtZTogc3RyaW5nLCB2OiBGbG9hdDMyQXJyYXkpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLmZldGNoVW5pZm9ybUxvY2F0aW9uKHByb2dyYW0sIG5hbWUpKSByZXR1cm47XG4gICAgICAgIC8vIFRoZSB2YXN0IG1ham9yaXR5IG9mIG1hdHJpeCBjb21wYXJpc29ucyB0aGF0IHdpbGwgdHJpcCB0aGlzIHNldFxuICAgICAgICAvLyBoYXBwZW4gYXQgaT0xMiBvciBpPTAsIHNvIHdlIGNoZWNrIHRob3NlIGZpcnN0IHRvIGF2b2lkIGxvdHMgb2ZcbiAgICAgICAgLy8gdW5uZWNlc3NhcnkgaXRlcmF0aW9uOlxuICAgICAgICBpZiAodlsxMl0gIT09IHRoaXMuY3VycmVudFsxMl0gfHwgdlswXSAhPT0gdGhpcy5jdXJyZW50WzBdKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnQgPSB2O1xuICAgICAgICAgICAgdGhpcy5nbC51bmlmb3JtTWF0cml4NGZ2KHRoaXMubG9jYXRpb24sIGZhbHNlLCB2KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IDE2OyBpKyspIHtcbiAgICAgICAgICAgIGlmICh2W2ldICE9PSB0aGlzLmN1cnJlbnRbaV0pIHtcbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnQgPSB2O1xuICAgICAgICAgICAgICAgIHRoaXMuZ2wudW5pZm9ybU1hdHJpeDRmdih0aGlzLmxvY2F0aW9uLCBmYWxzZSwgdik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNvbnN0IGVtcHR5TWF0MyA9IG5ldyBGbG9hdDMyQXJyYXkoOSk7XG5jbGFzcyBVbmlmb3JtTWF0cml4M2YgZXh0ZW5kcyBVbmlmb3JtPEZsb2F0MzJBcnJheT4ge1xuICAgIGNvbnN0cnVjdG9yKGNvbnRleHQ6IENvbnRleHQpIHtcbiAgICAgICAgc3VwZXIoY29udGV4dCk7XG4gICAgICAgIHRoaXMuY3VycmVudCA9IGVtcHR5TWF0MztcbiAgICB9XG5cbiAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgc2V0KHByb2dyYW06IFdlYkdMUHJvZ3JhbSwgbmFtZTogc3RyaW5nLCB2OiBGbG9hdDMyQXJyYXkpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLmZldGNoVW5pZm9ybUxvY2F0aW9uKHByb2dyYW0sIG5hbWUpKSByZXR1cm47XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgOTsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodltpXSAhPT0gdGhpcy5jdXJyZW50W2ldKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50ID0gdjtcbiAgICAgICAgICAgICAgICB0aGlzLmdsLnVuaWZvcm1NYXRyaXgzZnYodGhpcy5sb2NhdGlvbiwgZmFsc2UsIHYpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG5jb25zdCBlbXB0eU1hdDIgPSBuZXcgRmxvYXQzMkFycmF5KDQpO1xuY2xhc3MgVW5pZm9ybU1hdHJpeDJmIGV4dGVuZHMgVW5pZm9ybTxGbG9hdDMyQXJyYXk+IHtcbiAgICBjb25zdHJ1Y3Rvcihjb250ZXh0OiBDb250ZXh0KSB7XG4gICAgICAgIHN1cGVyKGNvbnRleHQpO1xuICAgICAgICB0aGlzLmN1cnJlbnQgPSBlbXB0eU1hdDI7XG4gICAgfVxuXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIHNldChwcm9ncmFtOiBXZWJHTFByb2dyYW0sIG5hbWU6IHN0cmluZywgdjogRmxvYXQzMkFycmF5KTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5mZXRjaFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCBuYW1lKSkgcmV0dXJuO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgICAgICAgICAgaWYgKHZbaV0gIT09IHRoaXMuY3VycmVudFtpXSkge1xuICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudCA9IHY7XG4gICAgICAgICAgICAgICAgdGhpcy5nbC51bmlmb3JtTWF0cml4MmZ2KHRoaXMubG9jYXRpb24sIGZhbHNlLCB2KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IHtcbiAgICBVbmlmb3JtLFxuICAgIFVuaWZvcm0xaSxcbiAgICBVbmlmb3JtMWYsXG4gICAgVW5pZm9ybTJmLFxuICAgIFVuaWZvcm0zZixcbiAgICBVbmlmb3JtNGYsXG4gICAgVW5pZm9ybUNvbG9yLFxuICAgIFVuaWZvcm1NYXRyaXgyZixcbiAgICBVbmlmb3JtTWF0cml4M2YsXG4gICAgVW5pZm9ybU1hdHJpeDRmXG59O1xuXG5leHBvcnQgdHlwZSBVbmlmb3JtQmluZGluZ3MgPSB7W186IHN0cmluZ106IFVuaWZvcm08YW55Pn07XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge3BhY2tVaW50OFRvRmxvYXR9IGZyb20gJy4uL3NoYWRlcnMvZW5jb2RlX2F0dHJpYnV0ZS5qcyc7XG5pbXBvcnQgQ29sb3IgZnJvbSAnLi4vc3R5bGUtc3BlYy91dGlsL2NvbG9yLmpzJztcbmltcG9ydCB7c3VwcG9ydHNQcm9wZXJ0eUV4cHJlc3Npb259IGZyb20gJy4uL3N0eWxlLXNwZWMvdXRpbC9wcm9wZXJ0aWVzLmpzJztcbmltcG9ydCB7cmVnaXN0ZXJ9IGZyb20gJy4uL3V0aWwvd2ViX3dvcmtlcl90cmFuc2Zlci5qcyc7XG5pbXBvcnQge1Bvc3NpYmx5RXZhbHVhdGVkUHJvcGVydHlWYWx1ZX0gZnJvbSAnLi4vc3R5bGUvcHJvcGVydGllcy5qcyc7XG5pbXBvcnQge1N0cnVjdEFycmF5TGF5b3V0MWY0LCBTdHJ1Y3RBcnJheUxheW91dDJmOCwgU3RydWN0QXJyYXlMYXlvdXQ0ZjE2LCBQYXR0ZXJuTGF5b3V0QXJyYXksIERhc2hMYXlvdXRBcnJheX0gZnJvbSAnLi9hcnJheV90eXBlcy5qcyc7XG5pbXBvcnQge2NsYW1wfSBmcm9tICcuLi91dGlsL3V0aWwuanMnO1xuaW1wb3J0IHBhdHRlcm5BdHRyaWJ1dGVzIGZyb20gJy4vYnVja2V0L3BhdHRlcm5fYXR0cmlidXRlcy5qcyc7XG5pbXBvcnQgZGFzaEF0dHJpYnV0ZXMgZnJvbSAnLi9idWNrZXQvZGFzaF9hdHRyaWJ1dGVzLmpzJztcbmltcG9ydCBFdmFsdWF0aW9uUGFyYW1ldGVycyBmcm9tICcuLi9zdHlsZS9ldmFsdWF0aW9uX3BhcmFtZXRlcnMuanMnO1xuaW1wb3J0IEZlYXR1cmVQb3NpdGlvbk1hcCBmcm9tICcuL2ZlYXR1cmVfcG9zaXRpb25fbWFwLmpzJztcbmltcG9ydCB7XG4gICAgVW5pZm9ybSxcbiAgICBVbmlmb3JtMWYsXG4gICAgVW5pZm9ybUNvbG9yLFxuICAgIFVuaWZvcm00ZlxufSBmcm9tICcuLi9yZW5kZXIvdW5pZm9ybV9iaW5kaW5nLmpzJztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcblxuaW1wb3J0IHR5cGUge0Nhbm9uaWNhbFRpbGVJRH0gZnJvbSAnLi4vc291cmNlL3RpbGVfaWQuanMnO1xuaW1wb3J0IHR5cGUgQ29udGV4dCBmcm9tICcuLi9nbC9jb250ZXh0LmpzJztcbmltcG9ydCB0eXBlIHtUeXBlZFN0eWxlTGF5ZXJ9IGZyb20gJy4uL3N0eWxlL3N0eWxlX2xheWVyL3R5cGVkX3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCB0eXBlIHtTdHJ1Y3RBcnJheSwgU3RydWN0QXJyYXlNZW1iZXJ9IGZyb20gJy4uL3V0aWwvc3RydWN0X2FycmF5LmpzJztcbmltcG9ydCB0eXBlIFZlcnRleEJ1ZmZlciBmcm9tICcuLi9nbC92ZXJ0ZXhfYnVmZmVyLmpzJztcbmltcG9ydCB0eXBlIHtTcHJpdGVQb3NpdGlvbiwgU3ByaXRlUG9zaXRpb25zfSBmcm9tICcuLi91dGlsL2ltYWdlLmpzJztcbmltcG9ydCB0eXBlIHtcbiAgICBGZWF0dXJlLFxuICAgIEZlYXR1cmVTdGF0ZSxcbiAgICBHbG9iYWxQcm9wZXJ0aWVzLFxuICAgIFNvdXJjZUV4cHJlc3Npb24sXG4gICAgQ29tcG9zaXRlRXhwcmVzc2lvblxufSBmcm9tICcuLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vaW5kZXguanMnO1xuaW1wb3J0IHR5cGUge1Bvc3NpYmx5RXZhbHVhdGVkfSBmcm9tICcuLi9zdHlsZS9wcm9wZXJ0aWVzLmpzJztcbmltcG9ydCB0eXBlIHtGZWF0dXJlU3RhdGVzfSBmcm9tICcuLi9zb3VyY2Uvc291cmNlX3N0YXRlLmpzJztcbmltcG9ydCB0eXBlIHtGb3JtYXR0ZWRTZWN0aW9ufSBmcm9tICcuLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vdHlwZXMvZm9ybWF0dGVkLmpzJztcbmltcG9ydCB0eXBlIHtJVmVjdG9yVGlsZUxheWVyfSBmcm9tICdAbWFwYm94L3ZlY3Rvci10aWxlJztcblxuZXhwb3J0IHR5cGUgQmluZGVyVW5pZm9ybSA9IHtcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgcHJvcGVydHk6IHN0cmluZyxcbiAgICBiaW5kaW5nOiBVbmlmb3JtPGFueT5cbn07XG5cbmZ1bmN0aW9uIHBhY2tDb2xvcihjb2xvcjogQ29sb3IpOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgICByZXR1cm4gW1xuICAgICAgICBwYWNrVWludDhUb0Zsb2F0KDI1NSAqIGNvbG9yLnIsIDI1NSAqIGNvbG9yLmcpLFxuICAgICAgICBwYWNrVWludDhUb0Zsb2F0KDI1NSAqIGNvbG9yLmIsIDI1NSAqIGNvbG9yLmEpXG4gICAgXTtcbn1cblxuLyoqXG4gKiAgYEJpbmRlcmAgaXMgdGhlIGludGVyZmFjZSBkZWZpbml0aW9uIGZvciB0aGUgc3RyYXRlZ2llcyBmb3IgY29uc3RydWN0aW5nLFxuICogIHVwbG9hZGluZywgYW5kIGJpbmRpbmcgcGFpbnQgcHJvcGVydHkgZGF0YSBhcyBHTFNMIGF0dHJpYnV0ZXMuIE1vc3Qgc3R5bGUtXG4gKiAgc3BlYyBwcm9wZXJ0aWVzIGhhdmUgYSAxOjEgcmVsYXRpb25zaGlwIHRvIHNoYWRlciBhdHRyaWJ1dGUvdW5pZm9ybXMsIGJ1dFxuICogIHNvbWUgcmVxdWlyZSBtdWx0aXBsZSB2YWx1ZXMgcGVyIGZlYXR1cmUgdG8gYmUgcGFzc2VkIHRvIHRoZSBHUFUsIGFuZCBpblxuICogIHRob3NlIGNhc2VzIHdlIGJpbmQgbXVsdGlwbGUgYXR0cmlidXRlcy91bmlmb3Jtcy5cbiAqXG4gKiAgSXQgaGFzIHRocmVlIGltcGxlbWVudGF0aW9ucywgb25lIGZvciBlYWNoIG9mIHRoZSB0aHJlZSBzdHJhdGVnaWVzIHdlIHVzZTpcbiAqXG4gKiAgKiBGb3IgX2NvbnN0YW50XyBwcm9wZXJ0aWVzIC0tIHRob3NlIHdob3NlIHZhbHVlIGlzIGEgY29uc3RhbnQsIG9yIHRoZSBjb25zdGFudFxuICogICAgcmVzdWx0IG9mIGV2YWx1YXRpbmcgYSBjYW1lcmEgZXhwcmVzc2lvbiBhdCBhIHBhcnRpY3VsYXIgY2FtZXJhIHBvc2l0aW9uIC0tIHdlXG4gKiAgICBkb24ndCBuZWVkIGEgdmVydGV4IGF0dHJpYnV0ZSBidWZmZXIsIGFuZCBpbnN0ZWFkIHVzZSBhIHVuaWZvcm0uXG4gKiAgKiBGb3IgZGF0YSBleHByZXNzaW9ucywgd2UgdXNlIGEgdmVydGV4IGJ1ZmZlciB3aXRoIGEgc2luZ2xlIGF0dHJpYnV0ZSB2YWx1ZSxcbiAqICAgIHRoZSBldmFsdWF0ZWQgcmVzdWx0IG9mIHRoZSBzb3VyY2UgZnVuY3Rpb24gZm9yIHRoZSBnaXZlbiBmZWF0dXJlLlxuICogICogRm9yIGNvbXBvc2l0ZSBleHByZXNzaW9ucywgd2UgdXNlIGEgdmVydGV4IGJ1ZmZlciB3aXRoIHR3byBhdHRyaWJ1dGVzOiBtaW4gYW5kXG4gKiAgICBtYXggdmFsdWVzIGNvdmVyaW5nIHRoZSByYW5nZSBvZiB6b29tcyBhdCB3aGljaCB3ZSBleHBlY3QgdGhlIHRpbGUgdG8gYmVcbiAqICAgIGRpc3BsYXllZC4gVGhlc2UgdmFsdWVzIGFyZSBjYWxjdWxhdGVkIGJ5IGV2YWx1YXRpbmcgdGhlIGNvbXBvc2l0ZSBleHByZXNzaW9uIGZvclxuICogICAgdGhlIGdpdmVuIGZlYXR1cmUgYXQgc3RyYXRlZ2ljYWxseSBjaG9zZW4gem9vbSBsZXZlbHMuIEluIGFkZGl0aW9uIHRvIHRoaXNcbiAqICAgIGF0dHJpYnV0ZSBkYXRhLCB3ZSBhbHNvIHVzZSBhIHVuaWZvcm0gdmFsdWUgd2hpY2ggdGhlIHNoYWRlciB1c2VzIHRvIGludGVycG9sYXRlXG4gKiAgICBiZXR3ZWVuIHRoZSBtaW4gYW5kIG1heCB2YWx1ZSBhdCB0aGUgZmluYWwgZGlzcGxheWVkIHpvb20gbGV2ZWwuIFRoZSB1c2Ugb2YgYVxuICogICAgdW5pZm9ybSBhbGxvd3MgdXMgdG8gY2hlYXBseSB1cGRhdGUgdGhlIHZhbHVlIG9uIGV2ZXJ5IGZyYW1lLlxuICpcbiAqICBOb3RlIHRoYXQgdGhlIHNoYWRlciBzb3VyY2UgdmFyaWVzIGRlcGVuZGluZyBvbiB3aGV0aGVyIHdlJ3JlIHVzaW5nIGEgdW5pZm9ybSBvclxuICogIGF0dHJpYnV0ZS4gV2UgZHluYW1pY2FsbHkgY29tcGlsZSBzaGFkZXJzIGF0IHJ1bnRpbWUgdG8gYWNjb21tb2RhdGUgdGhpcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5cbmludGVyZmFjZSBBdHRyaWJ1dGVCaW5kZXIge1xuICAgIHBvcHVsYXRlUGFpbnRBcnJheShsZW5ndGg6IG51bWJlciwgZmVhdHVyZTogRmVhdHVyZSwgaW1hZ2VQb3NpdGlvbnM6IFNwcml0ZVBvc2l0aW9ucywgYXZhaWxhYmxlSW1hZ2VzOiBBcnJheTxzdHJpbmc+LCBjYW5vbmljYWw/OiBDYW5vbmljYWxUaWxlSUQsIGZvcm1hdHRlZFNlY3Rpb24/OiBGb3JtYXR0ZWRTZWN0aW9uKTogdm9pZDtcbiAgICB1cGRhdGVQYWludEFycmF5KHN0YXJ0OiBudW1iZXIsIGxlbmd0aDogbnVtYmVyLCBmZWF0dXJlOiBGZWF0dXJlLCBmZWF0dXJlU3RhdGU6IEZlYXR1cmVTdGF0ZSwgYXZhaWxhYmxlSW1hZ2VzOiBBcnJheTxzdHJpbmc+LCBpbWFnZVBvc2l0aW9uczogU3ByaXRlUG9zaXRpb25zKTogdm9pZDtcbiAgICB1cGxvYWQoQ29udGV4dCk6IHZvaWQ7XG4gICAgZGVzdHJveSgpOiB2b2lkO1xufVxuXG5pbnRlcmZhY2UgVW5pZm9ybUJpbmRlciB7XG4gICAgdW5pZm9ybU5hbWVzOiBBcnJheTxzdHJpbmc+O1xuICAgIHNldFVuaWZvcm0ocHJvZ3JhbTogV2ViR0xQcm9ncmFtLCB1bmlmb3JtOiBVbmlmb3JtPCo+LCBnbG9iYWxzOiBHbG9iYWxQcm9wZXJ0aWVzLCBjdXJyZW50VmFsdWU6IFBvc3NpYmx5RXZhbHVhdGVkUHJvcGVydHlWYWx1ZTwqPiwgdW5pZm9ybU5hbWU6IHN0cmluZyk6IHZvaWQ7XG4gICAgZ2V0QmluZGluZyhjb250ZXh0OiBDb250ZXh0LCBuYW1lOiBzdHJpbmcpOiAkU2hhcGU8VW5pZm9ybTwqPj47XG59XG5cbmNsYXNzIENvbnN0YW50QmluZGVyIGltcGxlbWVudHMgVW5pZm9ybUJpbmRlciB7XG4gICAgdmFsdWU6IG1peGVkO1xuICAgIHR5cGU6IHN0cmluZztcbiAgICB1bmlmb3JtTmFtZXM6IEFycmF5PHN0cmluZz47XG5cbiAgICBjb25zdHJ1Y3Rvcih2YWx1ZTogbWl4ZWQsIG5hbWVzOiBBcnJheTxzdHJpbmc+LCB0eXBlOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgICAgICB0aGlzLnVuaWZvcm1OYW1lcyA9IG5hbWVzLm1hcChuYW1lID0+IGB1XyR7bmFtZX1gKTtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICB9XG5cbiAgICBzZXRVbmlmb3JtKHByb2dyYW06IFdlYkdMUHJvZ3JhbSwgdW5pZm9ybTogVW5pZm9ybTwqPiwgZ2xvYmFsczogR2xvYmFsUHJvcGVydGllcywgY3VycmVudFZhbHVlOiBQb3NzaWJseUV2YWx1YXRlZFByb3BlcnR5VmFsdWU8bWl4ZWQ+LCB1bmlmb3JtTmFtZTogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIHVuaWZvcm0uc2V0KHByb2dyYW0sIHVuaWZvcm1OYW1lLCBjdXJyZW50VmFsdWUuY29uc3RhbnRPcih0aGlzLnZhbHVlKSk7XG4gICAgfVxuXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIGdldEJpbmRpbmcoY29udGV4dDogQ29udGV4dCwgXzogc3RyaW5nKTogJFNoYXBlPFVuaWZvcm08YW55Pj4ge1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIHJldHVybiAodGhpcy50eXBlID09PSAnY29sb3InKSA/XG4gICAgICAgICAgICBuZXcgVW5pZm9ybUNvbG9yKGNvbnRleHQpIDpcbiAgICAgICAgICAgIG5ldyBVbmlmb3JtMWYoY29udGV4dCk7XG4gICAgfVxufVxuXG5jbGFzcyBQYXR0ZXJuQ29uc3RhbnRCaW5kZXIgaW1wbGVtZW50cyBVbmlmb3JtQmluZGVyIHtcbiAgICB1bmlmb3JtTmFtZXM6IEFycmF5PHN0cmluZz47XG4gICAgcGF0dGVybjogP0FycmF5PG51bWJlcj47XG4gICAgcGl4ZWxSYXRpbzogbnVtYmVyO1xuXG4gICAgY29uc3RydWN0b3IodmFsdWU6IG1peGVkLCBuYW1lczogQXJyYXk8c3RyaW5nPikge1xuICAgICAgICB0aGlzLnVuaWZvcm1OYW1lcyA9IG5hbWVzLm1hcChuYW1lID0+IGB1XyR7bmFtZX1gKTtcbiAgICAgICAgdGhpcy5wYXR0ZXJuID0gbnVsbDtcbiAgICAgICAgdGhpcy5waXhlbFJhdGlvID0gMTtcbiAgICB9XG5cbiAgICBzZXRDb25zdGFudFBhdHRlcm5Qb3NpdGlvbnMocG9zVG86IFNwcml0ZVBvc2l0aW9uKSB7XG4gICAgICAgIHRoaXMucGl4ZWxSYXRpbyA9IHBvc1RvLnBpeGVsUmF0aW8gfHwgMTtcbiAgICAgICAgdGhpcy5wYXR0ZXJuID0gcG9zVG8udGwuY29uY2F0KHBvc1RvLmJyKTtcbiAgICB9XG5cbiAgICBzZXRVbmlmb3JtKHByb2dyYW06IFdlYkdMUHJvZ3JhbSwgdW5pZm9ybTogVW5pZm9ybTwqPiwgZ2xvYmFsczogR2xvYmFsUHJvcGVydGllcywgY3VycmVudFZhbHVlOiBQb3NzaWJseUV2YWx1YXRlZFByb3BlcnR5VmFsdWU8bWl4ZWQ+LCB1bmlmb3JtTmFtZTogc3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IHBvcyA9XG4gICAgICAgICAgICB1bmlmb3JtTmFtZSA9PT0gJ3VfcGF0dGVybicgfHwgdW5pZm9ybU5hbWUgPT09ICd1X2Rhc2gnID8gdGhpcy5wYXR0ZXJuIDpcbiAgICAgICAgICAgIHVuaWZvcm1OYW1lID09PSAndV9waXhlbF9yYXRpbycgPyB0aGlzLnBpeGVsUmF0aW8gOiBudWxsO1xuICAgICAgICBpZiAocG9zKSB1bmlmb3JtLnNldChwcm9ncmFtLCB1bmlmb3JtTmFtZSwgcG9zKTtcbiAgICB9XG5cbiAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgZ2V0QmluZGluZyhjb250ZXh0OiBDb250ZXh0LCBuYW1lOiBzdHJpbmcpOiAkU2hhcGU8VW5pZm9ybTxhbnk+PiB7XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgcmV0dXJuIG5hbWUgPT09ICd1X3BhdHRlcm4nIHx8IG5hbWUgPT09ICd1X2Rhc2gnID9cbiAgICAgICAgICAgIG5ldyBVbmlmb3JtNGYoY29udGV4dCkgOlxuICAgICAgICAgICAgbmV3IFVuaWZvcm0xZihjb250ZXh0KTtcbiAgICB9XG59XG5cbmNsYXNzIFNvdXJjZUV4cHJlc3Npb25CaW5kZXIgaW1wbGVtZW50cyBBdHRyaWJ1dGVCaW5kZXIge1xuICAgIGV4cHJlc3Npb246IFNvdXJjZUV4cHJlc3Npb247XG4gICAgdHlwZTogc3RyaW5nO1xuICAgIG1heFZhbHVlOiBudW1iZXI7XG5cbiAgICBwYWludFZlcnRleEFycmF5OiBTdHJ1Y3RBcnJheTtcbiAgICBwYWludFZlcnRleEF0dHJpYnV0ZXM6IEFycmF5PFN0cnVjdEFycmF5TWVtYmVyPjtcbiAgICBwYWludFZlcnRleEJ1ZmZlcjogP1ZlcnRleEJ1ZmZlcjtcblxuICAgIGNvbnN0cnVjdG9yKGV4cHJlc3Npb246IFNvdXJjZUV4cHJlc3Npb24sIG5hbWVzOiBBcnJheTxzdHJpbmc+LCB0eXBlOiBzdHJpbmcsIFBhaW50VmVydGV4QXJyYXk6IENsYXNzPFN0cnVjdEFycmF5Pikge1xuICAgICAgICB0aGlzLmV4cHJlc3Npb24gPSBleHByZXNzaW9uO1xuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLm1heFZhbHVlID0gMDtcbiAgICAgICAgdGhpcy5wYWludFZlcnRleEF0dHJpYnV0ZXMgPSBuYW1lcy5tYXAoKG5hbWUpID0+ICh7XG4gICAgICAgICAgICBuYW1lOiBgYV8ke25hbWV9YCxcbiAgICAgICAgICAgIHR5cGU6ICdGbG9hdDMyJyxcbiAgICAgICAgICAgIGNvbXBvbmVudHM6IHR5cGUgPT09ICdjb2xvcicgPyAyIDogMSxcbiAgICAgICAgICAgIG9mZnNldDogMFxuICAgICAgICB9KSk7XG4gICAgICAgIHRoaXMucGFpbnRWZXJ0ZXhBcnJheSA9IG5ldyBQYWludFZlcnRleEFycmF5KCk7XG4gICAgfVxuXG4gICAgcG9wdWxhdGVQYWludEFycmF5KG5ld0xlbmd0aDogbnVtYmVyLCBmZWF0dXJlOiBGZWF0dXJlLCBpbWFnZVBvc2l0aW9uczogU3ByaXRlUG9zaXRpb25zLCBhdmFpbGFibGVJbWFnZXM6IEFycmF5PHN0cmluZz4sIGNhbm9uaWNhbD86IENhbm9uaWNhbFRpbGVJRCwgZm9ybWF0dGVkU2VjdGlvbj86IEZvcm1hdHRlZFNlY3Rpb24pIHtcbiAgICAgICAgY29uc3Qgc3RhcnQgPSB0aGlzLnBhaW50VmVydGV4QXJyYXkubGVuZ3RoO1xuICAgICAgICBhc3NlcnQoQXJyYXkuaXNBcnJheShhdmFpbGFibGVJbWFnZXMpKTtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZXhwcmVzc2lvbi5ldmFsdWF0ZShuZXcgRXZhbHVhdGlvblBhcmFtZXRlcnMoMCksIGZlYXR1cmUsIHt9LCBjYW5vbmljYWwsIGF2YWlsYWJsZUltYWdlcywgZm9ybWF0dGVkU2VjdGlvbik7XG4gICAgICAgIHRoaXMucGFpbnRWZXJ0ZXhBcnJheS5yZXNpemUobmV3TGVuZ3RoKTtcbiAgICAgICAgdGhpcy5fc2V0UGFpbnRWYWx1ZShzdGFydCwgbmV3TGVuZ3RoLCB2YWx1ZSk7XG4gICAgfVxuXG4gICAgdXBkYXRlUGFpbnRBcnJheShzdGFydDogbnVtYmVyLCBlbmQ6IG51bWJlciwgZmVhdHVyZTogRmVhdHVyZSwgZmVhdHVyZVN0YXRlOiBGZWF0dXJlU3RhdGUsIGF2YWlsYWJsZUltYWdlczogQXJyYXk8c3RyaW5nPikge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZXhwcmVzc2lvbi5ldmFsdWF0ZSh7em9vbTogMH0sIGZlYXR1cmUsIGZlYXR1cmVTdGF0ZSwgdW5kZWZpbmVkLCBhdmFpbGFibGVJbWFnZXMpO1xuICAgICAgICB0aGlzLl9zZXRQYWludFZhbHVlKHN0YXJ0LCBlbmQsIHZhbHVlKTtcbiAgICB9XG5cbiAgICBfc2V0UGFpbnRWYWx1ZShzdGFydDogbnVtYmVyLCBlbmQ6IG51bWJlciwgdmFsdWU6IGFueSkge1xuICAgICAgICBpZiAodGhpcy50eXBlID09PSAnY29sb3InKSB7XG4gICAgICAgICAgICBjb25zdCBjb2xvciA9IHBhY2tDb2xvcih2YWx1ZSk7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgICAgICAgICAgIHRoaXMucGFpbnRWZXJ0ZXhBcnJheS5lbXBsYWNlKGksIGNvbG9yWzBdLCBjb2xvclsxXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgICAgICAgICAgIHRoaXMucGFpbnRWZXJ0ZXhBcnJheS5lbXBsYWNlKGksIHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMubWF4VmFsdWUgPSBNYXRoLm1heCh0aGlzLm1heFZhbHVlLCBNYXRoLmFicyh2YWx1ZSkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdXBsb2FkKGNvbnRleHQ6IENvbnRleHQpIHtcbiAgICAgICAgaWYgKHRoaXMucGFpbnRWZXJ0ZXhBcnJheSAmJiB0aGlzLnBhaW50VmVydGV4QXJyYXkuYXJyYXlCdWZmZXIpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnBhaW50VmVydGV4QnVmZmVyICYmIHRoaXMucGFpbnRWZXJ0ZXhCdWZmZXIuYnVmZmVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wYWludFZlcnRleEJ1ZmZlci51cGRhdGVEYXRhKHRoaXMucGFpbnRWZXJ0ZXhBcnJheSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMucGFpbnRWZXJ0ZXhCdWZmZXIgPSBjb250ZXh0LmNyZWF0ZVZlcnRleEJ1ZmZlcih0aGlzLnBhaW50VmVydGV4QXJyYXksIHRoaXMucGFpbnRWZXJ0ZXhBdHRyaWJ1dGVzLCB0aGlzLmV4cHJlc3Npb24uaXNTdGF0ZURlcGVuZGVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBkZXN0cm95KCkge1xuICAgICAgICBpZiAodGhpcy5wYWludFZlcnRleEJ1ZmZlcikge1xuICAgICAgICAgICAgdGhpcy5wYWludFZlcnRleEJ1ZmZlci5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIENvbXBvc2l0ZUV4cHJlc3Npb25CaW5kZXIgaW1wbGVtZW50cyBBdHRyaWJ1dGVCaW5kZXIsIFVuaWZvcm1CaW5kZXIge1xuICAgIGV4cHJlc3Npb246IENvbXBvc2l0ZUV4cHJlc3Npb247XG4gICAgdW5pZm9ybU5hbWVzOiBBcnJheTxzdHJpbmc+O1xuICAgIHR5cGU6IHN0cmluZztcbiAgICB1c2VJbnRlZ2VyWm9vbTogYm9vbGVhbjtcbiAgICB6b29tOiBudW1iZXI7XG4gICAgbWF4VmFsdWU6IG51bWJlcjtcblxuICAgIHBhaW50VmVydGV4QXJyYXk6IFN0cnVjdEFycmF5O1xuICAgIHBhaW50VmVydGV4QXR0cmlidXRlczogQXJyYXk8U3RydWN0QXJyYXlNZW1iZXI+O1xuICAgIHBhaW50VmVydGV4QnVmZmVyOiA/VmVydGV4QnVmZmVyO1xuXG4gICAgY29uc3RydWN0b3IoZXhwcmVzc2lvbjogQ29tcG9zaXRlRXhwcmVzc2lvbiwgbmFtZXM6IEFycmF5PHN0cmluZz4sIHR5cGU6IHN0cmluZywgdXNlSW50ZWdlclpvb206IGJvb2xlYW4sIHpvb206IG51bWJlciwgUGFpbnRWZXJ0ZXhBcnJheTogQ2xhc3M8U3RydWN0QXJyYXk+KSB7XG4gICAgICAgIHRoaXMuZXhwcmVzc2lvbiA9IGV4cHJlc3Npb247XG4gICAgICAgIHRoaXMudW5pZm9ybU5hbWVzID0gbmFtZXMubWFwKG5hbWUgPT4gYHVfJHtuYW1lfV90YCk7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMudXNlSW50ZWdlclpvb20gPSB1c2VJbnRlZ2VyWm9vbTtcbiAgICAgICAgdGhpcy56b29tID0gem9vbTtcbiAgICAgICAgdGhpcy5tYXhWYWx1ZSA9IDA7XG4gICAgICAgIHRoaXMucGFpbnRWZXJ0ZXhBdHRyaWJ1dGVzID0gbmFtZXMubWFwKChuYW1lKSA9PiAoe1xuICAgICAgICAgICAgbmFtZTogYGFfJHtuYW1lfWAsXG4gICAgICAgICAgICB0eXBlOiAnRmxvYXQzMicsXG4gICAgICAgICAgICBjb21wb25lbnRzOiB0eXBlID09PSAnY29sb3InID8gNCA6IDIsXG4gICAgICAgICAgICBvZmZzZXQ6IDBcbiAgICAgICAgfSkpO1xuICAgICAgICB0aGlzLnBhaW50VmVydGV4QXJyYXkgPSBuZXcgUGFpbnRWZXJ0ZXhBcnJheSgpO1xuICAgIH1cblxuICAgIHBvcHVsYXRlUGFpbnRBcnJheShuZXdMZW5ndGg6IG51bWJlciwgZmVhdHVyZTogRmVhdHVyZSwgaW1hZ2VQb3NpdGlvbnM6IFNwcml0ZVBvc2l0aW9ucywgYXZhaWxhYmxlSW1hZ2VzOiBBcnJheTxzdHJpbmc+LCBjYW5vbmljYWw/OiBDYW5vbmljYWxUaWxlSUQsIGZvcm1hdHRlZFNlY3Rpb24/OiBGb3JtYXR0ZWRTZWN0aW9uKSB7XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgY29uc3QgbWluID0gdGhpcy5leHByZXNzaW9uLmV2YWx1YXRlKG5ldyBFdmFsdWF0aW9uUGFyYW1ldGVycyh0aGlzLnpvb20pLCBmZWF0dXJlLCB7fSwgY2Fub25pY2FsLCBhdmFpbGFibGVJbWFnZXMsIGZvcm1hdHRlZFNlY3Rpb24pO1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIGNvbnN0IG1heCA9IHRoaXMuZXhwcmVzc2lvbi5ldmFsdWF0ZShuZXcgRXZhbHVhdGlvblBhcmFtZXRlcnModGhpcy56b29tICsgMSksIGZlYXR1cmUsIHt9LCBjYW5vbmljYWwsIGF2YWlsYWJsZUltYWdlcywgZm9ybWF0dGVkU2VjdGlvbik7XG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5wYWludFZlcnRleEFycmF5Lmxlbmd0aDtcbiAgICAgICAgdGhpcy5wYWludFZlcnRleEFycmF5LnJlc2l6ZShuZXdMZW5ndGgpO1xuICAgICAgICB0aGlzLl9zZXRQYWludFZhbHVlKHN0YXJ0LCBuZXdMZW5ndGgsIG1pbiwgbWF4KTtcbiAgICB9XG5cbiAgICB1cGRhdGVQYWludEFycmF5KHN0YXJ0OiBudW1iZXIsIGVuZDogbnVtYmVyLCBmZWF0dXJlOiBGZWF0dXJlLCBmZWF0dXJlU3RhdGU6IEZlYXR1cmVTdGF0ZSwgYXZhaWxhYmxlSW1hZ2VzOiBBcnJheTxzdHJpbmc+KSB7XG4gICAgICAgIGNvbnN0IG1pbiA9IHRoaXMuZXhwcmVzc2lvbi5ldmFsdWF0ZSh7em9vbTogdGhpcy56b29tfSwgZmVhdHVyZSwgZmVhdHVyZVN0YXRlLCB1bmRlZmluZWQsIGF2YWlsYWJsZUltYWdlcyk7XG4gICAgICAgIGNvbnN0IG1heCA9IHRoaXMuZXhwcmVzc2lvbi5ldmFsdWF0ZSh7em9vbTogdGhpcy56b29tICsgMX0sIGZlYXR1cmUsIGZlYXR1cmVTdGF0ZSwgdW5kZWZpbmVkLCBhdmFpbGFibGVJbWFnZXMpO1xuICAgICAgICB0aGlzLl9zZXRQYWludFZhbHVlKHN0YXJ0LCBlbmQsIG1pbiwgbWF4KTtcbiAgICB9XG5cbiAgICBfc2V0UGFpbnRWYWx1ZShzdGFydDogbnVtYmVyLCBlbmQ6IG51bWJlciwgbWluOiBhbnksIG1heDogYW55KSB7XG4gICAgICAgIGlmICh0aGlzLnR5cGUgPT09ICdjb2xvcicpIHtcbiAgICAgICAgICAgIGNvbnN0IG1pbkNvbG9yID0gcGFja0NvbG9yKG1pbik7XG4gICAgICAgICAgICBjb25zdCBtYXhDb2xvciA9IHBhY2tDb2xvcihtYXgpO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBhaW50VmVydGV4QXJyYXkuZW1wbGFjZShpLCBtaW5Db2xvclswXSwgbWluQ29sb3JbMV0sIG1heENvbG9yWzBdLCBtYXhDb2xvclsxXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgICAgICAgICAgIHRoaXMucGFpbnRWZXJ0ZXhBcnJheS5lbXBsYWNlKGksIG1pbiwgbWF4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMubWF4VmFsdWUgPSBNYXRoLm1heCh0aGlzLm1heFZhbHVlLCBNYXRoLmFicyhtaW4pLCBNYXRoLmFicyhtYXgpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHVwbG9hZChjb250ZXh0OiBDb250ZXh0KSB7XG4gICAgICAgIGlmICh0aGlzLnBhaW50VmVydGV4QXJyYXkgJiYgdGhpcy5wYWludFZlcnRleEFycmF5LmFycmF5QnVmZmVyKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYWludFZlcnRleEJ1ZmZlciAmJiB0aGlzLnBhaW50VmVydGV4QnVmZmVyLmJ1ZmZlcikge1xuICAgICAgICAgICAgICAgIHRoaXMucGFpbnRWZXJ0ZXhCdWZmZXIudXBkYXRlRGF0YSh0aGlzLnBhaW50VmVydGV4QXJyYXkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBhaW50VmVydGV4QnVmZmVyID0gY29udGV4dC5jcmVhdGVWZXJ0ZXhCdWZmZXIodGhpcy5wYWludFZlcnRleEFycmF5LCB0aGlzLnBhaW50VmVydGV4QXR0cmlidXRlcywgdGhpcy5leHByZXNzaW9uLmlzU3RhdGVEZXBlbmRlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgaWYgKHRoaXMucGFpbnRWZXJ0ZXhCdWZmZXIpIHtcbiAgICAgICAgICAgIHRoaXMucGFpbnRWZXJ0ZXhCdWZmZXIuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0VW5pZm9ybShwcm9ncmFtOiBXZWJHTFByb2dyYW0sIHVuaWZvcm06IFVuaWZvcm08Kj4sIGdsb2JhbHM6IEdsb2JhbFByb3BlcnRpZXMsIF86IFBvc3NpYmx5RXZhbHVhdGVkUHJvcGVydHlWYWx1ZTwqPiwgdW5pZm9ybU5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBjb25zdCBjdXJyZW50Wm9vbSA9IHRoaXMudXNlSW50ZWdlclpvb20gPyBNYXRoLmZsb29yKGdsb2JhbHMuem9vbSkgOiBnbG9iYWxzLnpvb207XG4gICAgICAgIGNvbnN0IGZhY3RvciA9IGNsYW1wKHRoaXMuZXhwcmVzc2lvbi5pbnRlcnBvbGF0aW9uRmFjdG9yKGN1cnJlbnRab29tLCB0aGlzLnpvb20sIHRoaXMuem9vbSArIDEpLCAwLCAxKTtcbiAgICAgICAgdW5pZm9ybS5zZXQocHJvZ3JhbSwgdW5pZm9ybU5hbWUsIGZhY3Rvcik7XG4gICAgfVxuXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIGdldEJpbmRpbmcoY29udGV4dDogQ29udGV4dCwgXzogc3RyaW5nKTogVW5pZm9ybTFmIHtcbiAgICAgICAgcmV0dXJuIG5ldyBVbmlmb3JtMWYoY29udGV4dCk7XG4gICAgfVxufVxuXG5jbGFzcyBQYXR0ZXJuQ29tcG9zaXRlQmluZGVyIGltcGxlbWVudHMgQXR0cmlidXRlQmluZGVyIHtcbiAgICBleHByZXNzaW9uOiBDb21wb3NpdGVFeHByZXNzaW9uO1xuICAgIGxheWVySWQ6IHN0cmluZztcblxuICAgIHBhaW50VmVydGV4QXJyYXk6IFN0cnVjdEFycmF5O1xuICAgIHBhaW50VmVydGV4QnVmZmVyOiA/VmVydGV4QnVmZmVyO1xuICAgIHBhaW50VmVydGV4QXR0cmlidXRlczogQXJyYXk8U3RydWN0QXJyYXlNZW1iZXI+O1xuXG4gICAgY29uc3RydWN0b3IoZXhwcmVzc2lvbjogQ29tcG9zaXRlRXhwcmVzc2lvbiwgbmFtZXM6IEFycmF5PHN0cmluZz4sIHR5cGU6IHN0cmluZywgUGFpbnRWZXJ0ZXhBcnJheTogQ2xhc3M8U3RydWN0QXJyYXk+LCBsYXllcklkOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5leHByZXNzaW9uID0gZXhwcmVzc2lvbjtcbiAgICAgICAgdGhpcy5sYXllcklkID0gbGF5ZXJJZDtcblxuICAgICAgICB0aGlzLnBhaW50VmVydGV4QXR0cmlidXRlcyA9ICh0eXBlID09PSAnYXJyYXknID8gZGFzaEF0dHJpYnV0ZXMgOiBwYXR0ZXJuQXR0cmlidXRlcykubWVtYmVycztcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuYW1lcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgYXNzZXJ0KGBhXyR7bmFtZXNbaV19YCA9PT0gdGhpcy5wYWludFZlcnRleEF0dHJpYnV0ZXNbaV0ubmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnBhaW50VmVydGV4QXJyYXkgPSBuZXcgUGFpbnRWZXJ0ZXhBcnJheSgpO1xuICAgIH1cblxuICAgIHBvcHVsYXRlUGFpbnRBcnJheShsZW5ndGg6IG51bWJlciwgZmVhdHVyZTogRmVhdHVyZSwgaW1hZ2VQb3NpdGlvbnM6IFNwcml0ZVBvc2l0aW9ucykge1xuICAgICAgICBjb25zdCBzdGFydCA9IHRoaXMucGFpbnRWZXJ0ZXhBcnJheS5sZW5ndGg7XG4gICAgICAgIHRoaXMucGFpbnRWZXJ0ZXhBcnJheS5yZXNpemUobGVuZ3RoKTtcbiAgICAgICAgdGhpcy5fc2V0UGFpbnRWYWx1ZXMoc3RhcnQsIGxlbmd0aCwgZmVhdHVyZS5wYXR0ZXJucyAmJiBmZWF0dXJlLnBhdHRlcm5zW3RoaXMubGF5ZXJJZF0sIGltYWdlUG9zaXRpb25zKTtcbiAgICB9XG5cbiAgICB1cGRhdGVQYWludEFycmF5KHN0YXJ0OiBudW1iZXIsIGVuZDogbnVtYmVyLCBmZWF0dXJlOiBGZWF0dXJlLCBmZWF0dXJlU3RhdGU6IEZlYXR1cmVTdGF0ZSwgYXZhaWxhYmxlSW1hZ2VzOiBBcnJheTxzdHJpbmc+LCBpbWFnZVBvc2l0aW9uczogU3ByaXRlUG9zaXRpb25zKSB7XG4gICAgICAgIHRoaXMuX3NldFBhaW50VmFsdWVzKHN0YXJ0LCBlbmQsIGZlYXR1cmUucGF0dGVybnMgJiYgZmVhdHVyZS5wYXR0ZXJuc1t0aGlzLmxheWVySWRdLCBpbWFnZVBvc2l0aW9ucyk7XG4gICAgfVxuXG4gICAgX3NldFBhaW50VmFsdWVzKHN0YXJ0OiBudW1iZXIsIGVuZDogbnVtYmVyLCBwYXR0ZXJuczogP3N0cmluZywgcG9zaXRpb25zOiBTcHJpdGVQb3NpdGlvbnMpIHtcbiAgICAgICAgaWYgKCFwb3NpdGlvbnMgfHwgIXBhdHRlcm5zKSByZXR1cm47XG5cbiAgICAgICAgY29uc3QgcG9zID0gcG9zaXRpb25zW3BhdHRlcm5zXTtcbiAgICAgICAgaWYgKCFwb3MpIHJldHVybjtcblxuICAgICAgICBjb25zdCB7dGwsIGJyLCBwaXhlbFJhdGlvfSA9IHBvcztcbiAgICAgICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICAgICAgICAgIHRoaXMucGFpbnRWZXJ0ZXhBcnJheS5lbXBsYWNlKGksIHRsWzBdLCB0bFsxXSwgYnJbMF0sIGJyWzFdLCBwaXhlbFJhdGlvKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHVwbG9hZChjb250ZXh0OiBDb250ZXh0KSB7XG4gICAgICAgIGlmICh0aGlzLnBhaW50VmVydGV4QXJyYXkgJiYgdGhpcy5wYWludFZlcnRleEFycmF5LmFycmF5QnVmZmVyKSB7XG4gICAgICAgICAgICB0aGlzLnBhaW50VmVydGV4QnVmZmVyID0gY29udGV4dC5jcmVhdGVWZXJ0ZXhCdWZmZXIodGhpcy5wYWludFZlcnRleEFycmF5LCB0aGlzLnBhaW50VmVydGV4QXR0cmlidXRlcywgdGhpcy5leHByZXNzaW9uLmlzU3RhdGVEZXBlbmRlbnQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgaWYgKHRoaXMucGFpbnRWZXJ0ZXhCdWZmZXIpIHRoaXMucGFpbnRWZXJ0ZXhCdWZmZXIuZGVzdHJveSgpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBQcm9ncmFtQ29uZmlndXJhdGlvbiBjb250YWlucyB0aGUgbG9naWMgZm9yIGJpbmRpbmcgc3R5bGUgbGF5ZXIgcHJvcGVydGllcyBhbmQgdGlsZVxuICogbGF5ZXIgZmVhdHVyZSBkYXRhIGludG8gR0wgcHJvZ3JhbSB1bmlmb3JtcyBhbmQgdmVydGV4IGF0dHJpYnV0ZXMuXG4gKlxuICogTm9uLWRhdGEtZHJpdmVuIHByb3BlcnR5IHZhbHVlcyBhcmUgYm91bmQgdG8gc2hhZGVyIHVuaWZvcm1zLiBEYXRhLWRyaXZlbiBwcm9wZXJ0eVxuICogdmFsdWVzIGFyZSBib3VuZCB0byB2ZXJ0ZXggYXR0cmlidXRlcy4gSW4gb3JkZXIgdG8gc3VwcG9ydCBhIHVuaWZvcm0gR0xTTCBzeW50YXggb3ZlclxuICogYm90aCwgW01hcGJveCBHTCBTaGFkZXJzXShodHRwczovL2dpdGh1Yi5jb20vbWFwYm94L21hcGJveC1nbC1zaGFkZXJzKSBkZWZpbmVzIGEgYCNwcmFnbWFgXG4gKiBhYnN0cmFjdGlvbiwgd2hpY2ggUHJvZ3JhbUNvbmZpZ3VyYXRpb24gaXMgcmVzcG9uc2libGUgZm9yIGltcGxlbWVudGluZy4gQXQgcnVudGltZSxcbiAqIGl0IGV4YW1pbmVzIHRoZSBhdHRyaWJ1dGVzIG9mIGEgcGFydGljdWxhciBsYXllciwgY29tYmluZXMgdGhpcyB3aXRoIGZpeGVkIGtub3dsZWRnZVxuICogYWJvdXQgaG93IGxheWVycyBvZiB0aGUgcGFydGljdWxhciB0eXBlIGFyZSBpbXBsZW1lbnRlZCwgYW5kIGRldGVybWluZXMgd2hpY2ggdW5pZm9ybXNcbiAqIGFuZCB2ZXJ0ZXggYXR0cmlidXRlcyB3aWxsIGJlIHJlcXVpcmVkLiBJdCBjYW4gdGhlbiBzdWJzdGl0dXRlIHRoZSBhcHByb3ByaWF0ZSB0ZXh0XG4gKiBpbnRvIHRoZSBzaGFkZXIgc291cmNlIGNvZGUsIGNyZWF0ZSBhbmQgbGluayBhIHByb2dyYW0sIGFuZCBiaW5kIHRoZSB1bmlmb3JtcyBhbmRcbiAqIHZlcnRleCBhdHRyaWJ1dGVzIGluIHByZXBhcmF0aW9uIGZvciBkcmF3aW5nLlxuICpcbiAqIFdoZW4gYSB2ZWN0b3IgdGlsZSBpcyBwYXJzZWQsIHRoaXMgc2FtZSBjb25maWd1cmF0aW9uIGluZm9ybWF0aW9uIGlzIHVzZWQgdG9cbiAqIHBvcHVsYXRlIHRoZSBhdHRyaWJ1dGUgYnVmZmVycyBuZWVkZWQgZm9yIGRhdGEtZHJpdmVuIHN0eWxpbmcgdXNpbmcgdGhlIHpvb21cbiAqIGxldmVsIGFuZCBmZWF0dXJlIHByb3BlcnR5IGRhdGEuXG4gKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUHJvZ3JhbUNvbmZpZ3VyYXRpb24ge1xuICAgIGJpbmRlcnM6IHtbXzogc3RyaW5nXTogKEF0dHJpYnV0ZUJpbmRlciB8IFVuaWZvcm1CaW5kZXIpIH07XG4gICAgY2FjaGVLZXk6IHN0cmluZztcblxuICAgIF9idWZmZXJzOiBBcnJheTxWZXJ0ZXhCdWZmZXI+O1xuXG4gICAgY29uc3RydWN0b3IobGF5ZXI6IFR5cGVkU3R5bGVMYXllciwgem9vbTogbnVtYmVyLCBmaWx0ZXJQcm9wZXJ0aWVzOiAoXzogc3RyaW5nKSA9PiBib29sZWFuID0gKCkgPT4gdHJ1ZSkge1xuICAgICAgICB0aGlzLmJpbmRlcnMgPSB7fTtcbiAgICAgICAgdGhpcy5fYnVmZmVycyA9IFtdO1xuXG4gICAgICAgIGNvbnN0IGtleXMgPSBbXTtcblxuICAgICAgICBmb3IgKGNvbnN0IHByb3BlcnR5IGluIGxheWVyLnBhaW50Ll92YWx1ZXMpIHtcbiAgICAgICAgICAgIGlmICghZmlsdGVyUHJvcGVydGllcyhwcm9wZXJ0eSkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBsYXllci5wYWludC5nZXQocHJvcGVydHkpO1xuICAgICAgICAgICAgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBQb3NzaWJseUV2YWx1YXRlZFByb3BlcnR5VmFsdWUpIHx8ICFzdXBwb3J0c1Byb3BlcnR5RXhwcmVzc2lvbih2YWx1ZS5wcm9wZXJ0eS5zcGVjaWZpY2F0aW9uKSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbmFtZXMgPSBwYWludEF0dHJpYnV0ZU5hbWVzKHByb3BlcnR5LCBsYXllci50eXBlKTtcbiAgICAgICAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSB2YWx1ZS52YWx1ZTtcbiAgICAgICAgICAgIGNvbnN0IHR5cGUgPSB2YWx1ZS5wcm9wZXJ0eS5zcGVjaWZpY2F0aW9uLnR5cGU7XG4gICAgICAgICAgICBjb25zdCB1c2VJbnRlZ2VyWm9vbSA9ICEhdmFsdWUucHJvcGVydHkudXNlSW50ZWdlclpvb207XG4gICAgICAgICAgICBjb25zdCBpc1BhdHRlcm4gPSBwcm9wZXJ0eSA9PT0gJ2xpbmUtZGFzaGFycmF5JyB8fCBwcm9wZXJ0eS5lbmRzV2l0aCgncGF0dGVybicpO1xuICAgICAgICAgICAgY29uc3Qgc291cmNlRXhjZXB0aW9uID0gcHJvcGVydHkgPT09ICdsaW5lLWRhc2hhcnJheScgJiYgKGxheWVyLmxheW91dDogYW55KS5nZXQoJ2xpbmUtY2FwJykudmFsdWUua2luZCAhPT0gJ2NvbnN0YW50JztcblxuICAgICAgICAgICAgaWYgKGV4cHJlc3Npb24ua2luZCA9PT0gJ2NvbnN0YW50JyAmJiAhc291cmNlRXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5iaW5kZXJzW3Byb3BlcnR5XSA9IGlzUGF0dGVybiA/XG4gICAgICAgICAgICAgICAgICAgIG5ldyBQYXR0ZXJuQ29uc3RhbnRCaW5kZXIoZXhwcmVzc2lvbi52YWx1ZSwgbmFtZXMpIDpcbiAgICAgICAgICAgICAgICAgICAgbmV3IENvbnN0YW50QmluZGVyKGV4cHJlc3Npb24udmFsdWUsIG5hbWVzLCB0eXBlKTtcbiAgICAgICAgICAgICAgICBrZXlzLnB1c2goYC91XyR7cHJvcGVydHl9YCk7XG5cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZXhwcmVzc2lvbi5raW5kID09PSAnc291cmNlJyB8fCBzb3VyY2VFeGNlcHRpb24gfHwgaXNQYXR0ZXJuKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgU3RydWN0QXJyYXlMYXlvdXQgPSBsYXlvdXRUeXBlKHByb3BlcnR5LCB0eXBlLCAnc291cmNlJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5iaW5kZXJzW3Byb3BlcnR5XSA9IGlzUGF0dGVybiA/XG4gICAgICAgICAgICAgICAgICAgIC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXVxuICAgICAgICAgICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW2luY29tcGF0aWJsZS1jYWxsXSAtIGV4cHJlc3Npb24gY2FuIGJlIGEgYGNvbXBvc2l0ZWAgb3IgYGNvbnN0YW50YCBraW5kIGV4cHJlc3Npb25cbiAgICAgICAgICAgICAgICAgICAgbmV3IFBhdHRlcm5Db21wb3NpdGVCaW5kZXIoZXhwcmVzc2lvbiwgbmFtZXMsIHR5cGUsIFN0cnVjdEFycmF5TGF5b3V0LCBsYXllci5pZCkgOlxuICAgICAgICAgICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW3Byb3AtbWlzc2luZ11cbiAgICAgICAgICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtY2FsbF0gLSBleHByZXNzaW9uIGNhbiBiZSBhIGBjb21wb3NpdGVgIG9yIGBjb25zdGFudGAga2luZCBleHByZXNzaW9uXG4gICAgICAgICAgICAgICAgICAgIG5ldyBTb3VyY2VFeHByZXNzaW9uQmluZGVyKGV4cHJlc3Npb24sIG5hbWVzLCB0eXBlLCBTdHJ1Y3RBcnJheUxheW91dCk7XG5cbiAgICAgICAgICAgICAgICBrZXlzLnB1c2goYC9hXyR7cHJvcGVydHl9YCk7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgU3RydWN0QXJyYXlMYXlvdXQgPSBsYXlvdXRUeXBlKHByb3BlcnR5LCB0eXBlLCAnY29tcG9zaXRlJyk7XG4gICAgICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVtwcm9wLW1pc3NpbmddXG4gICAgICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtY2FsbF0g4oCUIGV4cHJlc3Npb24gY2FuIGJlIGEgYGNvbnN0YW50YCBraW5kIGV4cHJlc3Npb25cbiAgICAgICAgICAgICAgICB0aGlzLmJpbmRlcnNbcHJvcGVydHldID0gbmV3IENvbXBvc2l0ZUV4cHJlc3Npb25CaW5kZXIoZXhwcmVzc2lvbiwgbmFtZXMsIHR5cGUsIHVzZUludGVnZXJab29tLCB6b29tLCBTdHJ1Y3RBcnJheUxheW91dCk7XG4gICAgICAgICAgICAgICAga2V5cy5wdXNoKGAvel8ke3Byb3BlcnR5fWApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jYWNoZUtleSA9IGtleXMuc29ydCgpLmpvaW4oJycpO1xuICAgIH1cblxuICAgIGdldE1heFZhbHVlKHByb3BlcnR5OiBzdHJpbmcpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBiaW5kZXIgPSB0aGlzLmJpbmRlcnNbcHJvcGVydHldO1xuICAgICAgICByZXR1cm4gYmluZGVyIGluc3RhbmNlb2YgU291cmNlRXhwcmVzc2lvbkJpbmRlciB8fCBiaW5kZXIgaW5zdGFuY2VvZiBDb21wb3NpdGVFeHByZXNzaW9uQmluZGVyID8gYmluZGVyLm1heFZhbHVlIDogMDtcbiAgICB9XG5cbiAgICBwb3B1bGF0ZVBhaW50QXJyYXlzKG5ld0xlbmd0aDogbnVtYmVyLCBmZWF0dXJlOiBGZWF0dXJlLCBpbWFnZVBvc2l0aW9uczogU3ByaXRlUG9zaXRpb25zLCBhdmFpbGFibGVJbWFnZXM6IEFycmF5PHN0cmluZz4sIGNhbm9uaWNhbD86IENhbm9uaWNhbFRpbGVJRCwgZm9ybWF0dGVkU2VjdGlvbj86IEZvcm1hdHRlZFNlY3Rpb24pIHtcbiAgICAgICAgZm9yIChjb25zdCBwcm9wZXJ0eSBpbiB0aGlzLmJpbmRlcnMpIHtcbiAgICAgICAgICAgIGNvbnN0IGJpbmRlciA9IHRoaXMuYmluZGVyc1twcm9wZXJ0eV07XG4gICAgICAgICAgICBpZiAoYmluZGVyIGluc3RhbmNlb2YgU291cmNlRXhwcmVzc2lvbkJpbmRlciB8fCBiaW5kZXIgaW5zdGFuY2VvZiBDb21wb3NpdGVFeHByZXNzaW9uQmluZGVyIHx8IGJpbmRlciBpbnN0YW5jZW9mIFBhdHRlcm5Db21wb3NpdGVCaW5kZXIpXG4gICAgICAgICAgICAgICAgKGJpbmRlcjogQXR0cmlidXRlQmluZGVyKS5wb3B1bGF0ZVBhaW50QXJyYXkobmV3TGVuZ3RoLCBmZWF0dXJlLCBpbWFnZVBvc2l0aW9ucywgYXZhaWxhYmxlSW1hZ2VzLCBjYW5vbmljYWwsIGZvcm1hdHRlZFNlY3Rpb24pO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldENvbnN0YW50UGF0dGVyblBvc2l0aW9ucyhwb3NUbzogU3ByaXRlUG9zaXRpb24pIHtcbiAgICAgICAgZm9yIChjb25zdCBwcm9wZXJ0eSBpbiB0aGlzLmJpbmRlcnMpIHtcbiAgICAgICAgICAgIGNvbnN0IGJpbmRlciA9IHRoaXMuYmluZGVyc1twcm9wZXJ0eV07XG4gICAgICAgICAgICBpZiAoYmluZGVyIGluc3RhbmNlb2YgUGF0dGVybkNvbnN0YW50QmluZGVyKVxuICAgICAgICAgICAgICAgIGJpbmRlci5zZXRDb25zdGFudFBhdHRlcm5Qb3NpdGlvbnMocG9zVG8pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdXBkYXRlUGFpbnRBcnJheXMoZmVhdHVyZVN0YXRlczogRmVhdHVyZVN0YXRlcywgZmVhdHVyZU1hcDogRmVhdHVyZVBvc2l0aW9uTWFwLCB2dExheWVyOiBJVmVjdG9yVGlsZUxheWVyLCBsYXllcjogVHlwZWRTdHlsZUxheWVyLCBhdmFpbGFibGVJbWFnZXM6IEFycmF5PHN0cmluZz4sIGltYWdlUG9zaXRpb25zOiBTcHJpdGVQb3NpdGlvbnMpOiBib29sZWFuIHtcbiAgICAgICAgbGV0IGRpcnR5OiBib29sZWFuID0gZmFsc2U7XG4gICAgICAgIGZvciAoY29uc3QgaWQgaW4gZmVhdHVyZVN0YXRlcykge1xuICAgICAgICAgICAgY29uc3QgcG9zaXRpb25zID0gZmVhdHVyZU1hcC5nZXRQb3NpdGlvbnMoaWQpO1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHBvcyBvZiBwb3NpdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmZWF0dXJlID0gdnRMYXllci5mZWF0dXJlKHBvcy5pbmRleCk7XG5cbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHByb3BlcnR5IGluIHRoaXMuYmluZGVycykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBiaW5kZXIgPSB0aGlzLmJpbmRlcnNbcHJvcGVydHldO1xuICAgICAgICAgICAgICAgICAgICBpZiAoKGJpbmRlciBpbnN0YW5jZW9mIFNvdXJjZUV4cHJlc3Npb25CaW5kZXIgfHwgYmluZGVyIGluc3RhbmNlb2YgQ29tcG9zaXRlRXhwcmVzc2lvbkJpbmRlciB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgIGJpbmRlciBpbnN0YW5jZW9mIFBhdHRlcm5Db21wb3NpdGVCaW5kZXIpICYmIChiaW5kZXI6IGFueSkuZXhwcmVzc2lvbi5pc1N0YXRlRGVwZW5kZW50ID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvL0FITTogUmVtb3ZlIGFmdGVyIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXBib3gvbWFwYm94LWdsLWpzL2lzc3Vlcy82MjU1XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGxheWVyLnBhaW50LmdldChwcm9wZXJ0eSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAoYmluZGVyOiBhbnkpLmV4cHJlc3Npb24gPSB2YWx1ZS52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIChiaW5kZXI6IEF0dHJpYnV0ZUJpbmRlcikudXBkYXRlUGFpbnRBcnJheShwb3Muc3RhcnQsIHBvcy5lbmQsIGZlYXR1cmUsIGZlYXR1cmVTdGF0ZXNbaWRdLCBhdmFpbGFibGVJbWFnZXMsIGltYWdlUG9zaXRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpcnR5ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGlydHk7XG4gICAgfVxuXG4gICAgZGVmaW5lcygpOiBBcnJheTxzdHJpbmc+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gW107XG4gICAgICAgIGZvciAoY29uc3QgcHJvcGVydHkgaW4gdGhpcy5iaW5kZXJzKSB7XG4gICAgICAgICAgICBjb25zdCBiaW5kZXIgPSB0aGlzLmJpbmRlcnNbcHJvcGVydHldO1xuICAgICAgICAgICAgaWYgKGJpbmRlciBpbnN0YW5jZW9mIENvbnN0YW50QmluZGVyIHx8IGJpbmRlciBpbnN0YW5jZW9mIFBhdHRlcm5Db25zdGFudEJpbmRlcikge1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKC4uLmJpbmRlci51bmlmb3JtTmFtZXMubWFwKG5hbWUgPT4gYCNkZWZpbmUgSEFTX1VOSUZPUk1fJHtuYW1lfWApKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIGdldEJpbmRlckF0dHJpYnV0ZXMoKTogQXJyYXk8c3RyaW5nPiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IHByb3BlcnR5IGluIHRoaXMuYmluZGVycykge1xuICAgICAgICAgICAgY29uc3QgYmluZGVyID0gdGhpcy5iaW5kZXJzW3Byb3BlcnR5XTtcbiAgICAgICAgICAgIGlmIChiaW5kZXIgaW5zdGFuY2VvZiBTb3VyY2VFeHByZXNzaW9uQmluZGVyIHx8IGJpbmRlciBpbnN0YW5jZW9mIENvbXBvc2l0ZUV4cHJlc3Npb25CaW5kZXIgfHwgYmluZGVyIGluc3RhbmNlb2YgUGF0dGVybkNvbXBvc2l0ZUJpbmRlcikge1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYmluZGVyLnBhaW50VmVydGV4QXR0cmlidXRlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChiaW5kZXIucGFpbnRWZXJ0ZXhBdHRyaWJ1dGVzW2ldLm5hbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIGdldEJpbmRlclVuaWZvcm1zKCk6IEFycmF5PHN0cmluZz4ge1xuICAgICAgICBjb25zdCB1bmlmb3JtcyA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IHByb3BlcnR5IGluIHRoaXMuYmluZGVycykge1xuICAgICAgICAgICAgY29uc3QgYmluZGVyID0gdGhpcy5iaW5kZXJzW3Byb3BlcnR5XTtcbiAgICAgICAgICAgIGlmIChiaW5kZXIgaW5zdGFuY2VvZiBDb25zdGFudEJpbmRlciB8fCBiaW5kZXIgaW5zdGFuY2VvZiBQYXR0ZXJuQ29uc3RhbnRCaW5kZXIgfHwgYmluZGVyIGluc3RhbmNlb2YgQ29tcG9zaXRlRXhwcmVzc2lvbkJpbmRlcikge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdW5pZm9ybU5hbWUgb2YgYmluZGVyLnVuaWZvcm1OYW1lcykge1xuICAgICAgICAgICAgICAgICAgICB1bmlmb3Jtcy5wdXNoKHVuaWZvcm1OYW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuaWZvcm1zO1xuICAgIH1cblxuICAgIGdldFBhaW50VmVydGV4QnVmZmVycygpOiBBcnJheTxWZXJ0ZXhCdWZmZXI+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcnM7XG4gICAgfVxuXG4gICAgZ2V0VW5pZm9ybXMoY29udGV4dDogQ29udGV4dCk6IEFycmF5PEJpbmRlclVuaWZvcm0+IHtcbiAgICAgICAgY29uc3QgdW5pZm9ybXMgPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBwcm9wZXJ0eSBpbiB0aGlzLmJpbmRlcnMpIHtcbiAgICAgICAgICAgIGNvbnN0IGJpbmRlciA9IHRoaXMuYmluZGVyc1twcm9wZXJ0eV07XG4gICAgICAgICAgICBpZiAoYmluZGVyIGluc3RhbmNlb2YgQ29uc3RhbnRCaW5kZXIgfHwgYmluZGVyIGluc3RhbmNlb2YgUGF0dGVybkNvbnN0YW50QmluZGVyIHx8IGJpbmRlciBpbnN0YW5jZW9mIENvbXBvc2l0ZUV4cHJlc3Npb25CaW5kZXIpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgYmluZGVyLnVuaWZvcm1OYW1lcykge1xuICAgICAgICAgICAgICAgICAgICB1bmlmb3Jtcy5wdXNoKHtuYW1lLCBwcm9wZXJ0eSwgYmluZGluZzogYmluZGVyLmdldEJpbmRpbmcoY29udGV4dCwgbmFtZSl9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuaWZvcm1zO1xuICAgIH1cblxuICAgIHNldFVuaWZvcm1zPFByb3BlcnRpZXM6IE9iamVjdD4ocHJvZ3JhbTogV2ViR0xQcm9ncmFtLCBjb250ZXh0OiBDb250ZXh0LCBiaW5kZXJVbmlmb3JtczogQXJyYXk8QmluZGVyVW5pZm9ybT4sIHByb3BlcnRpZXM6IFBvc3NpYmx5RXZhbHVhdGVkPFByb3BlcnRpZXM+LCBnbG9iYWxzOiBHbG9iYWxQcm9wZXJ0aWVzKSB7XG4gICAgICAgIC8vIFVuaWZvcm0gc3RhdGUgYmluZGluZ3MgYXJlIG93bmVkIGJ5IHRoZSBQcm9ncmFtLCBidXQgd2Ugc2V0IHRoZW1cbiAgICAgICAgLy8gZnJvbSB3aXRoaW4gdGhlIFByb2dyYW1Db25maWd1cmF0aW9uJ3MgYmluZGVyIG1lbWJlcnMuXG4gICAgICAgIGZvciAoY29uc3Qge25hbWUsIHByb3BlcnR5LCBiaW5kaW5nfSBvZiBiaW5kZXJVbmlmb3Jtcykge1xuICAgICAgICAgICAgKHRoaXMuYmluZGVyc1twcm9wZXJ0eV06IGFueSkuc2V0VW5pZm9ybShwcm9ncmFtLCBiaW5kaW5nLCBnbG9iYWxzLCBwcm9wZXJ0aWVzLmdldChwcm9wZXJ0eSksIG5hbWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdXBkYXRlUGFpbnRCdWZmZXJzKCkge1xuICAgICAgICB0aGlzLl9idWZmZXJzID0gW107XG5cbiAgICAgICAgZm9yIChjb25zdCBwcm9wZXJ0eSBpbiB0aGlzLmJpbmRlcnMpIHtcbiAgICAgICAgICAgIGNvbnN0IGJpbmRlciA9IHRoaXMuYmluZGVyc1twcm9wZXJ0eV07XG4gICAgICAgICAgICBpZiAoKFxuICAgICAgICAgICAgICAgIGJpbmRlciBpbnN0YW5jZW9mIFNvdXJjZUV4cHJlc3Npb25CaW5kZXIgfHxcbiAgICAgICAgICAgICAgICBiaW5kZXIgaW5zdGFuY2VvZiBDb21wb3NpdGVFeHByZXNzaW9uQmluZGVyIHx8XG4gICAgICAgICAgICAgICAgYmluZGVyIGluc3RhbmNlb2YgUGF0dGVybkNvbXBvc2l0ZUJpbmRlcikgJiYgYmluZGVyLnBhaW50VmVydGV4QnVmZmVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVycy5wdXNoKGJpbmRlci5wYWludFZlcnRleEJ1ZmZlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB1cGxvYWQoY29udGV4dDogQ29udGV4dCkge1xuICAgICAgICBmb3IgKGNvbnN0IHByb3BlcnR5IGluIHRoaXMuYmluZGVycykge1xuICAgICAgICAgICAgY29uc3QgYmluZGVyID0gdGhpcy5iaW5kZXJzW3Byb3BlcnR5XTtcbiAgICAgICAgICAgIGlmIChiaW5kZXIgaW5zdGFuY2VvZiBTb3VyY2VFeHByZXNzaW9uQmluZGVyIHx8IGJpbmRlciBpbnN0YW5jZW9mIENvbXBvc2l0ZUV4cHJlc3Npb25CaW5kZXIgfHwgYmluZGVyIGluc3RhbmNlb2YgUGF0dGVybkNvbXBvc2l0ZUJpbmRlcilcbiAgICAgICAgICAgICAgICBiaW5kZXIudXBsb2FkKGNvbnRleHQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudXBkYXRlUGFpbnRCdWZmZXJzKCk7XG4gICAgfVxuXG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgZm9yIChjb25zdCBwcm9wZXJ0eSBpbiB0aGlzLmJpbmRlcnMpIHtcbiAgICAgICAgICAgIGNvbnN0IGJpbmRlciA9IHRoaXMuYmluZGVyc1twcm9wZXJ0eV07XG4gICAgICAgICAgICBpZiAoYmluZGVyIGluc3RhbmNlb2YgU291cmNlRXhwcmVzc2lvbkJpbmRlciB8fCBiaW5kZXIgaW5zdGFuY2VvZiBDb21wb3NpdGVFeHByZXNzaW9uQmluZGVyIHx8IGJpbmRlciBpbnN0YW5jZW9mIFBhdHRlcm5Db21wb3NpdGVCaW5kZXIpXG4gICAgICAgICAgICAgICAgYmluZGVyLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFByb2dyYW1Db25maWd1cmF0aW9uU2V0PExheWVyOiBUeXBlZFN0eWxlTGF5ZXI+IHtcbiAgICBwcm9ncmFtQ29uZmlndXJhdGlvbnM6IHtbXzogc3RyaW5nXTogUHJvZ3JhbUNvbmZpZ3VyYXRpb259O1xuICAgIG5lZWRzVXBsb2FkOiBib29sZWFuO1xuICAgIF9mZWF0dXJlTWFwOiBGZWF0dXJlUG9zaXRpb25NYXA7XG4gICAgX2J1ZmZlck9mZnNldDogbnVtYmVyO1xuXG4gICAgY29uc3RydWN0b3IobGF5ZXJzOiAkUmVhZE9ubHlBcnJheTxMYXllcj4sIHpvb206IG51bWJlciwgZmlsdGVyUHJvcGVydGllczogKF86IHN0cmluZykgPT4gYm9vbGVhbiA9ICgpID0+IHRydWUpIHtcbiAgICAgICAgdGhpcy5wcm9ncmFtQ29uZmlndXJhdGlvbnMgPSB7fTtcbiAgICAgICAgZm9yIChjb25zdCBsYXllciBvZiBsYXllcnMpIHtcbiAgICAgICAgICAgIHRoaXMucHJvZ3JhbUNvbmZpZ3VyYXRpb25zW2xheWVyLmlkXSA9IG5ldyBQcm9ncmFtQ29uZmlndXJhdGlvbihsYXllciwgem9vbSwgZmlsdGVyUHJvcGVydGllcyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5uZWVkc1VwbG9hZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9mZWF0dXJlTWFwID0gbmV3IEZlYXR1cmVQb3NpdGlvbk1hcCgpO1xuICAgICAgICB0aGlzLl9idWZmZXJPZmZzZXQgPSAwO1xuICAgIH1cblxuICAgIHBvcHVsYXRlUGFpbnRBcnJheXMobGVuZ3RoOiBudW1iZXIsIGZlYXR1cmU6IEZlYXR1cmUsIGluZGV4OiBudW1iZXIsIGltYWdlUG9zaXRpb25zOiBTcHJpdGVQb3NpdGlvbnMsIGF2YWlsYWJsZUltYWdlczogQXJyYXk8c3RyaW5nPiwgY2Fub25pY2FsOiBDYW5vbmljYWxUaWxlSUQsIGZvcm1hdHRlZFNlY3Rpb24/OiBGb3JtYXR0ZWRTZWN0aW9uKSB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIHRoaXMucHJvZ3JhbUNvbmZpZ3VyYXRpb25zKSB7XG4gICAgICAgICAgICB0aGlzLnByb2dyYW1Db25maWd1cmF0aW9uc1trZXldLnBvcHVsYXRlUGFpbnRBcnJheXMobGVuZ3RoLCBmZWF0dXJlLCBpbWFnZVBvc2l0aW9ucywgYXZhaWxhYmxlSW1hZ2VzLCBjYW5vbmljYWwsIGZvcm1hdHRlZFNlY3Rpb24pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGZlYXR1cmUuaWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5fZmVhdHVyZU1hcC5hZGQoZmVhdHVyZS5pZCwgaW5kZXgsIHRoaXMuX2J1ZmZlck9mZnNldCwgbGVuZ3RoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9idWZmZXJPZmZzZXQgPSBsZW5ndGg7XG5cbiAgICAgICAgdGhpcy5uZWVkc1VwbG9hZCA9IHRydWU7XG4gICAgfVxuXG4gICAgdXBkYXRlUGFpbnRBcnJheXMoZmVhdHVyZVN0YXRlczogRmVhdHVyZVN0YXRlcywgdnRMYXllcjogSVZlY3RvclRpbGVMYXllciwgbGF5ZXJzOiAkUmVhZE9ubHlBcnJheTxUeXBlZFN0eWxlTGF5ZXI+LCBhdmFpbGFibGVJbWFnZXM6IEFycmF5PHN0cmluZz4sIGltYWdlUG9zaXRpb25zOiBTcHJpdGVQb3NpdGlvbnMpIHtcbiAgICAgICAgZm9yIChjb25zdCBsYXllciBvZiBsYXllcnMpIHtcbiAgICAgICAgICAgIHRoaXMubmVlZHNVcGxvYWQgPSB0aGlzLnByb2dyYW1Db25maWd1cmF0aW9uc1tsYXllci5pZF0udXBkYXRlUGFpbnRBcnJheXMoZmVhdHVyZVN0YXRlcywgdGhpcy5fZmVhdHVyZU1hcCwgdnRMYXllciwgbGF5ZXIsIGF2YWlsYWJsZUltYWdlcywgaW1hZ2VQb3NpdGlvbnMpIHx8IHRoaXMubmVlZHNVcGxvYWQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXQobGF5ZXJJZDogc3RyaW5nKTogUHJvZ3JhbUNvbmZpZ3VyYXRpb24ge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9ncmFtQ29uZmlndXJhdGlvbnNbbGF5ZXJJZF07XG4gICAgfVxuXG4gICAgdXBsb2FkKGNvbnRleHQ6IENvbnRleHQpIHtcbiAgICAgICAgaWYgKCF0aGlzLm5lZWRzVXBsb2FkKSByZXR1cm47XG4gICAgICAgIGZvciAoY29uc3QgbGF5ZXJJZCBpbiB0aGlzLnByb2dyYW1Db25maWd1cmF0aW9ucykge1xuICAgICAgICAgICAgdGhpcy5wcm9ncmFtQ29uZmlndXJhdGlvbnNbbGF5ZXJJZF0udXBsb2FkKGNvbnRleHQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubmVlZHNVcGxvYWQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBkZXN0cm95KCkge1xuICAgICAgICBmb3IgKGNvbnN0IGxheWVySWQgaW4gdGhpcy5wcm9ncmFtQ29uZmlndXJhdGlvbnMpIHtcbiAgICAgICAgICAgIHRoaXMucHJvZ3JhbUNvbmZpZ3VyYXRpb25zW2xheWVySWRdLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuY29uc3QgYXR0cmlidXRlTmFtZUV4Y2VwdGlvbnMgPSB7XG4gICAgJ3RleHQtb3BhY2l0eSc6IFsnb3BhY2l0eSddLFxuICAgICdpY29uLW9wYWNpdHknOiBbJ29wYWNpdHknXSxcbiAgICAndGV4dC1jb2xvcic6IFsnZmlsbF9jb2xvciddLFxuICAgICdpY29uLWNvbG9yJzogWydmaWxsX2NvbG9yJ10sXG4gICAgJ3RleHQtaGFsby1jb2xvcic6IFsnaGFsb19jb2xvciddLFxuICAgICdpY29uLWhhbG8tY29sb3InOiBbJ2hhbG9fY29sb3InXSxcbiAgICAndGV4dC1oYWxvLWJsdXInOiBbJ2hhbG9fYmx1ciddLFxuICAgICdpY29uLWhhbG8tYmx1cic6IFsnaGFsb19ibHVyJ10sXG4gICAgJ3RleHQtaGFsby13aWR0aCc6IFsnaGFsb193aWR0aCddLFxuICAgICdpY29uLWhhbG8td2lkdGgnOiBbJ2hhbG9fd2lkdGgnXSxcbiAgICAnbGluZS1nYXAtd2lkdGgnOiBbJ2dhcHdpZHRoJ10sXG4gICAgJ2xpbmUtcGF0dGVybic6IFsncGF0dGVybicsICdwaXhlbF9yYXRpbyddLFxuICAgICdmaWxsLXBhdHRlcm4nOiBbJ3BhdHRlcm4nLCAncGl4ZWxfcmF0aW8nXSxcbiAgICAnZmlsbC1leHRydXNpb24tcGF0dGVybic6IFsncGF0dGVybicsICdwaXhlbF9yYXRpbyddLFxuICAgICdsaW5lLWRhc2hhcnJheSc6IFsnZGFzaCddXG59O1xuXG5mdW5jdGlvbiBwYWludEF0dHJpYnV0ZU5hbWVzKHByb3BlcnR5OiBzdHJpbmcsIHR5cGU6IHN0cmluZykge1xuICAgIHJldHVybiBhdHRyaWJ1dGVOYW1lRXhjZXB0aW9uc1twcm9wZXJ0eV0gfHwgW3Byb3BlcnR5LnJlcGxhY2UoYCR7dHlwZX0tYCwgJycpLnJlcGxhY2UoLy0vZywgJ18nKV07XG59XG5cbmNvbnN0IHByb3BlcnR5RXhjZXB0aW9ucyA9IHtcbiAgICAnbGluZS1wYXR0ZXJuJzoge1xuICAgICAgICAnc291cmNlJzogUGF0dGVybkxheW91dEFycmF5LFxuICAgICAgICAnY29tcG9zaXRlJzogUGF0dGVybkxheW91dEFycmF5XG4gICAgfSxcbiAgICAnZmlsbC1wYXR0ZXJuJzoge1xuICAgICAgICAnc291cmNlJzogUGF0dGVybkxheW91dEFycmF5LFxuICAgICAgICAnY29tcG9zaXRlJzogUGF0dGVybkxheW91dEFycmF5XG4gICAgfSxcbiAgICAnZmlsbC1leHRydXNpb24tcGF0dGVybic6e1xuICAgICAgICAnc291cmNlJzogUGF0dGVybkxheW91dEFycmF5LFxuICAgICAgICAnY29tcG9zaXRlJzogUGF0dGVybkxheW91dEFycmF5XG4gICAgfSxcbiAgICAnbGluZS1kYXNoYXJyYXknOiB7IC8vIHRlbXBvcmFyeSBsYXlvdXRcbiAgICAgICAgJ3NvdXJjZSc6IERhc2hMYXlvdXRBcnJheSxcbiAgICAgICAgJ2NvbXBvc2l0ZSc6IERhc2hMYXlvdXRBcnJheVxuICAgIH1cbn07XG5cbmNvbnN0IGRlZmF1bHRMYXlvdXRzID0ge1xuICAgICdjb2xvcic6IHtcbiAgICAgICAgJ3NvdXJjZSc6IFN0cnVjdEFycmF5TGF5b3V0MmY4LFxuICAgICAgICAnY29tcG9zaXRlJzogU3RydWN0QXJyYXlMYXlvdXQ0ZjE2XG4gICAgfSxcbiAgICAnbnVtYmVyJzoge1xuICAgICAgICAnc291cmNlJzogU3RydWN0QXJyYXlMYXlvdXQxZjQsXG4gICAgICAgICdjb21wb3NpdGUnOiBTdHJ1Y3RBcnJheUxheW91dDJmOFxuICAgIH1cbn07XG5cbnR5cGUgTGF5b3V0VHlwZSA9ICdhcnJheScgfCAnYm9vbGVhbicgfCAnY29sb3InIHwgJ2VudW0nIHwgJ251bWJlcicgfCAncmVzb2x2ZWRJbWFnZScgfCAnc3RyaW5nJztcblxuZnVuY3Rpb24gbGF5b3V0VHlwZShwcm9wZXJ0eTogc3RyaW5nLCB0eXBlOiBMYXlvdXRUeXBlLCBiaW5kZXJUeXBlOiBzdHJpbmcpIHtcbiAgICBjb25zdCBsYXlvdXRFeGNlcHRpb24gPSBwcm9wZXJ0eUV4Y2VwdGlvbnNbcHJvcGVydHldO1xuICAgIC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXSAtIHdlIGRvbid0IGNvdmVyIGFsbCB0eXBlcyBpbiBkZWZhdWx0TGF5b3V0cyBmb3Igc29tZSByZWFzb25cbiAgICByZXR1cm4gKGxheW91dEV4Y2VwdGlvbiAmJiBsYXlvdXRFeGNlcHRpb25bYmluZGVyVHlwZV0pIHx8IGRlZmF1bHRMYXlvdXRzW3R5cGVdW2JpbmRlclR5cGVdO1xufVxuXG5yZWdpc3RlcihDb25zdGFudEJpbmRlciwgJ0NvbnN0YW50QmluZGVyJyk7XG5yZWdpc3RlcihQYXR0ZXJuQ29uc3RhbnRCaW5kZXIsICdQYXR0ZXJuQ29uc3RhbnRCaW5kZXInKTtcbnJlZ2lzdGVyKFNvdXJjZUV4cHJlc3Npb25CaW5kZXIsICdTb3VyY2VFeHByZXNzaW9uQmluZGVyJyk7XG5yZWdpc3RlcihQYXR0ZXJuQ29tcG9zaXRlQmluZGVyLCAnUGF0dGVybkNvbXBvc2l0ZUJpbmRlcicpO1xucmVnaXN0ZXIoQ29tcG9zaXRlRXhwcmVzc2lvbkJpbmRlciwgJ0NvbXBvc2l0ZUV4cHJlc3Npb25CaW5kZXInKTtcbnJlZ2lzdGVyKFByb2dyYW1Db25maWd1cmF0aW9uLCAnUHJvZ3JhbUNvbmZpZ3VyYXRpb24nLCB7b21pdDogWydfYnVmZmVycyddfSk7XG5yZWdpc3RlcihQcm9ncmFtQ29uZmlndXJhdGlvblNldCwgJ1Byb2dyYW1Db25maWd1cmF0aW9uU2V0Jyk7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge2VuZHNXaXRoLCBmaWx0ZXJPYmplY3R9IGZyb20gJy4uL3V0aWwvdXRpbC5qcyc7XG5cbmltcG9ydCBzdHlsZVNwZWMgZnJvbSAnLi4vc3R5bGUtc3BlYy9yZWZlcmVuY2UvbGF0ZXN0LmpzJztcbmltcG9ydCB7XG4gICAgdmFsaWRhdGVTdHlsZSxcbiAgICB2YWxpZGF0ZUxheW91dFByb3BlcnR5LFxuICAgIHZhbGlkYXRlUGFpbnRQcm9wZXJ0eSxcbiAgICBlbWl0VmFsaWRhdGlvbkVycm9yc1xufSBmcm9tICcuL3ZhbGlkYXRlX3N0eWxlLmpzJztcbmltcG9ydCB7RXZlbnRlZH0gZnJvbSAnLi4vdXRpbC9ldmVudGVkLmpzJztcbmltcG9ydCB7TGF5b3V0LCBUcmFuc2l0aW9uYWJsZSwgVHJhbnNpdGlvbmluZywgUHJvcGVydGllcywgUG9zc2libHlFdmFsdWF0ZWQsIFBvc3NpYmx5RXZhbHVhdGVkUHJvcGVydHlWYWx1ZX0gZnJvbSAnLi9wcm9wZXJ0aWVzLmpzJztcbmltcG9ydCB7c3VwcG9ydHNQcm9wZXJ0eUV4cHJlc3Npb259IGZyb20gJy4uL3N0eWxlLXNwZWMvdXRpbC9wcm9wZXJ0aWVzLmpzJztcbmltcG9ydCBQcm9ncmFtQ29uZmlndXJhdGlvbiBmcm9tICcuLi9kYXRhL3Byb2dyYW1fY29uZmlndXJhdGlvbi5qcyc7XG5pbXBvcnQgZmVhdHVyZUZpbHRlciBmcm9tICcuLi9zdHlsZS1zcGVjL2ZlYXR1cmVfZmlsdGVyL2luZGV4LmpzJztcblxuaW1wb3J0IHR5cGUge0ZlYXR1cmVTdGF0ZX0gZnJvbSAnLi4vc3R5bGUtc3BlYy9leHByZXNzaW9uL2luZGV4LmpzJztcbmltcG9ydCB0eXBlIHtCdWNrZXR9IGZyb20gJy4uL2RhdGEvYnVja2V0LmpzJztcbmltcG9ydCB0eXBlIFBvaW50IGZyb20gJ0BtYXBib3gvcG9pbnQtZ2VvbWV0cnknO1xuaW1wb3J0IHR5cGUge0ZlYXR1cmVGaWx0ZXIsIEZpbHRlckV4cHJlc3Npb259IGZyb20gJy4uL3N0eWxlLXNwZWMvZmVhdHVyZV9maWx0ZXIvaW5kZXguanMnO1xuaW1wb3J0IHR5cGUge1RyYW5zaXRpb25QYXJhbWV0ZXJzLCBQcm9wZXJ0eVZhbHVlfSBmcm9tICcuL3Byb3BlcnRpZXMuanMnO1xuaW1wb3J0IHR5cGUgRXZhbHVhdGlvblBhcmFtZXRlcnMgZnJvbSAnLi9ldmFsdWF0aW9uX3BhcmFtZXRlcnMuanMnO1xuaW1wb3J0IHR5cGUgVHJhbnNmb3JtIGZyb20gJy4uL2dlby90cmFuc2Zvcm0uanMnO1xuaW1wb3J0IHR5cGUge1xuICAgIExheWVyU3BlY2lmaWNhdGlvbixcbiAgICBGaWx0ZXJTcGVjaWZpY2F0aW9uLFxuICAgIFRyYW5zaXRpb25TcGVjaWZpY2F0aW9uLFxuICAgIFByb3BlcnR5VmFsdWVTcGVjaWZpY2F0aW9uXG59IGZyb20gJy4uL3N0eWxlLXNwZWMvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge0N1c3RvbUxheWVySW50ZXJmYWNlfSBmcm9tICcuL3N0eWxlX2xheWVyL2N1c3RvbV9zdHlsZV9sYXllci5qcyc7XG5pbXBvcnQgdHlwZSBNYXAgZnJvbSAnLi4vdWkvbWFwLmpzJztcbmltcG9ydCB0eXBlIHtTdHlsZVNldHRlck9wdGlvbnN9IGZyb20gJy4vc3R5bGUuanMnO1xuaW1wb3J0IHR5cGUge1RpbGVzcGFjZVF1ZXJ5R2VvbWV0cnl9IGZyb20gJy4vcXVlcnlfZ2VvbWV0cnkuanMnO1xuaW1wb3J0IHR5cGUge0RFTVNhbXBsZXJ9IGZyb20gJy4uL3RlcnJhaW4vZWxldmF0aW9uLmpzJztcbmltcG9ydCB0eXBlIHtJVmVjdG9yVGlsZUZlYXR1cmV9IGZyb20gJ0BtYXBib3gvdmVjdG9yLXRpbGUnO1xuXG5jb25zdCBUUkFOU0lUSU9OX1NVRkZJWCA9ICctdHJhbnNpdGlvbic7XG5cbmNsYXNzIFN0eWxlTGF5ZXIgZXh0ZW5kcyBFdmVudGVkIHtcbiAgICBpZDogc3RyaW5nO1xuICAgIG1ldGFkYXRhOiBtaXhlZDtcbiAgICB0eXBlOiBzdHJpbmc7XG4gICAgc291cmNlOiBzdHJpbmc7XG4gICAgc291cmNlTGF5ZXI6ID9zdHJpbmc7XG4gICAgbWluem9vbTogP251bWJlcjtcbiAgICBtYXh6b29tOiA/bnVtYmVyO1xuICAgIGZpbHRlcjogRmlsdGVyU3BlY2lmaWNhdGlvbiB8IHZvaWQ7XG4gICAgdmlzaWJpbGl0eTogJ3Zpc2libGUnIHwgJ25vbmUnIHwgdm9pZDtcblxuICAgIF91bmV2YWx1YXRlZExheW91dDogTGF5b3V0PGFueT47XG4gICAgK2xheW91dDogbWl4ZWQ7XG5cbiAgICBfdHJhbnNpdGlvbmFibGVQYWludDogVHJhbnNpdGlvbmFibGU8YW55PjtcbiAgICBfdHJhbnNpdGlvbmluZ1BhaW50OiBUcmFuc2l0aW9uaW5nPGFueT47XG4gICAgK3BhaW50OiBtaXhlZDtcblxuICAgIF9mZWF0dXJlRmlsdGVyOiBGZWF0dXJlRmlsdGVyO1xuICAgIF9maWx0ZXJDb21waWxlZDogYm9vbGVhbjtcblxuICAgICtxdWVyeVJhZGl1czogKGJ1Y2tldDogQnVja2V0KSA9PiBudW1iZXI7XG4gICAgK3F1ZXJ5SW50ZXJzZWN0c0ZlYXR1cmU6IChxdWVyeUdlb21ldHJ5OiBUaWxlc3BhY2VRdWVyeUdlb21ldHJ5LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmVhdHVyZTogSVZlY3RvclRpbGVGZWF0dXJlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmVhdHVyZVN0YXRlOiBGZWF0dXJlU3RhdGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW9tZXRyeTogQXJyYXk8QXJyYXk8UG9pbnQ+PixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHpvb206IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybTogVHJhbnNmb3JtLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGl4ZWxQb3NNYXRyaXg6IEZsb2F0MzJBcnJheSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZXZhdGlvbkhlbHBlcjogP0RFTVNhbXBsZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXlvdXRWZXJ0ZXhBcnJheU9mZnNldDogbnVtYmVyKSA9PiBib29sZWFuIHwgbnVtYmVyO1xuXG4gICAgK29uQWRkOiA/KG1hcDogTWFwKSA9PiB2b2lkO1xuICAgICtvblJlbW92ZTogPyhtYXA6IE1hcCkgPT4gdm9pZDtcblxuICAgIGNvbnN0cnVjdG9yKGxheWVyOiBMYXllclNwZWNpZmljYXRpb24gfCBDdXN0b21MYXllckludGVyZmFjZSwgcHJvcGVydGllczogJFJlYWRPbmx5PHtsYXlvdXQ/OiBQcm9wZXJ0aWVzPCo+LCBwYWludD86IFByb3BlcnRpZXM8Kj59Pikge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIHRoaXMuaWQgPSBsYXllci5pZDtcbiAgICAgICAgdGhpcy50eXBlID0gbGF5ZXIudHlwZTtcbiAgICAgICAgdGhpcy5fZmVhdHVyZUZpbHRlciA9IHtmaWx0ZXI6ICgpID0+IHRydWUsIG5lZWRHZW9tZXRyeTogZmFsc2UsIG5lZWRGZWF0dXJlOiBmYWxzZX07XG4gICAgICAgIHRoaXMuX2ZpbHRlckNvbXBpbGVkID0gZmFsc2U7XG5cbiAgICAgICAgaWYgKGxheWVyLnR5cGUgPT09ICdjdXN0b20nKSByZXR1cm47XG5cbiAgICAgICAgbGF5ZXIgPSAoKGxheWVyOiBhbnkpOiBMYXllclNwZWNpZmljYXRpb24pO1xuXG4gICAgICAgIHRoaXMubWV0YWRhdGEgPSBsYXllci5tZXRhZGF0YTtcbiAgICAgICAgdGhpcy5taW56b29tID0gbGF5ZXIubWluem9vbTtcbiAgICAgICAgdGhpcy5tYXh6b29tID0gbGF5ZXIubWF4em9vbTtcblxuICAgICAgICBpZiAobGF5ZXIudHlwZSAhPT0gJ2JhY2tncm91bmQnICYmIGxheWVyLnR5cGUgIT09ICdza3knKSB7XG4gICAgICAgICAgICB0aGlzLnNvdXJjZSA9IGxheWVyLnNvdXJjZTtcbiAgICAgICAgICAgIHRoaXMuc291cmNlTGF5ZXIgPSBsYXllclsnc291cmNlLWxheWVyJ107XG4gICAgICAgICAgICB0aGlzLmZpbHRlciA9IGxheWVyLmZpbHRlcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLmxheW91dCkge1xuICAgICAgICAgICAgdGhpcy5fdW5ldmFsdWF0ZWRMYXlvdXQgPSBuZXcgTGF5b3V0KHByb3BlcnRpZXMubGF5b3V0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLnBhaW50KSB7XG4gICAgICAgICAgICB0aGlzLl90cmFuc2l0aW9uYWJsZVBhaW50ID0gbmV3IFRyYW5zaXRpb25hYmxlKHByb3BlcnRpZXMucGFpbnQpO1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHByb3BlcnR5IGluIGxheWVyLnBhaW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRQYWludFByb3BlcnR5KHByb3BlcnR5LCBsYXllci5wYWludFtwcm9wZXJ0eV0sIHt2YWxpZGF0ZTogZmFsc2V9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAoY29uc3QgcHJvcGVydHkgaW4gbGF5ZXIubGF5b3V0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRMYXlvdXRQcm9wZXJ0eShwcm9wZXJ0eSwgbGF5ZXIubGF5b3V0W3Byb3BlcnR5XSwge3ZhbGlkYXRlOiBmYWxzZX0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLl90cmFuc2l0aW9uaW5nUGFpbnQgPSB0aGlzLl90cmFuc2l0aW9uYWJsZVBhaW50LnVudHJhbnNpdGlvbmVkKCk7XG4gICAgICAgICAgICAvLyRGbG93Rml4TWVcbiAgICAgICAgICAgIHRoaXMucGFpbnQgPSBuZXcgUG9zc2libHlFdmFsdWF0ZWQocHJvcGVydGllcy5wYWludCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRMYXlvdXRQcm9wZXJ0eShuYW1lOiBzdHJpbmcpOiBQcm9wZXJ0eVZhbHVlU3BlY2lmaWNhdGlvbjxtaXhlZD4ge1xuICAgICAgICBpZiAobmFtZSA9PT0gJ3Zpc2liaWxpdHknKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy52aXNpYmlsaXR5O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX3VuZXZhbHVhdGVkTGF5b3V0LmdldFZhbHVlKG5hbWUpO1xuICAgIH1cblxuICAgIHNldExheW91dFByb3BlcnR5KG5hbWU6IHN0cmluZywgdmFsdWU6IGFueSwgb3B0aW9uczogU3R5bGVTZXR0ZXJPcHRpb25zID0ge30pIHtcbiAgICAgICAgaWYgKHZhbHVlICE9PSBudWxsICYmIHZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGNvbnN0IGtleSA9IGBsYXllcnMuJHt0aGlzLmlkfS5sYXlvdXQuJHtuYW1lfWA7XG4gICAgICAgICAgICBpZiAodGhpcy5fdmFsaWRhdGUodmFsaWRhdGVMYXlvdXRQcm9wZXJ0eSwga2V5LCBuYW1lLCB2YWx1ZSwgb3B0aW9ucykpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobmFtZSA9PT0gJ3Zpc2liaWxpdHknKSB7XG4gICAgICAgICAgICB0aGlzLnZpc2liaWxpdHkgPSB2YWx1ZTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3VuZXZhbHVhdGVkTGF5b3V0LnNldFZhbHVlKG5hbWUsIHZhbHVlKTtcbiAgICB9XG5cbiAgICBnZXRQYWludFByb3BlcnR5KG5hbWU6IHN0cmluZyk6IHZvaWQgfCBUcmFuc2l0aW9uU3BlY2lmaWNhdGlvbiB8IFByb3BlcnR5VmFsdWVTcGVjaWZpY2F0aW9uPG1peGVkPiB7XG4gICAgICAgIGlmIChlbmRzV2l0aChuYW1lLCBUUkFOU0lUSU9OX1NVRkZJWCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl90cmFuc2l0aW9uYWJsZVBhaW50LmdldFRyYW5zaXRpb24obmFtZS5zbGljZSgwLCAtVFJBTlNJVElPTl9TVUZGSVgubGVuZ3RoKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdHJhbnNpdGlvbmFibGVQYWludC5nZXRWYWx1ZShuYW1lKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldFBhaW50UHJvcGVydHkobmFtZTogc3RyaW5nLCB2YWx1ZTogbWl4ZWQsIG9wdGlvbnM6IFN0eWxlU2V0dGVyT3B0aW9ucyA9IHt9KTogYm9vbGVhbiB7XG4gICAgICAgIGlmICh2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBjb25zdCBrZXkgPSBgbGF5ZXJzLiR7dGhpcy5pZH0ucGFpbnQuJHtuYW1lfWA7XG4gICAgICAgICAgICBpZiAodGhpcy5fdmFsaWRhdGUodmFsaWRhdGVQYWludFByb3BlcnR5LCBrZXksIG5hbWUsIHZhbHVlLCBvcHRpb25zKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbmRzV2l0aChuYW1lLCBUUkFOU0lUSU9OX1NVRkZJWCkpIHtcbiAgICAgICAgICAgIHRoaXMuX3RyYW5zaXRpb25hYmxlUGFpbnQuc2V0VHJhbnNpdGlvbihuYW1lLnNsaWNlKDAsIC1UUkFOU0lUSU9OX1NVRkZJWC5sZW5ndGgpLCAodmFsdWU6IGFueSkgfHwgdW5kZWZpbmVkKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHRyYW5zaXRpb25hYmxlID0gdGhpcy5fdHJhbnNpdGlvbmFibGVQYWludC5fdmFsdWVzW25hbWVdO1xuICAgICAgICAgICAgY29uc3Qgd2FzRGF0YURyaXZlbiA9IHRyYW5zaXRpb25hYmxlLnZhbHVlLmlzRGF0YURyaXZlbigpO1xuICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWUgPSB0cmFuc2l0aW9uYWJsZS52YWx1ZTtcblxuICAgICAgICAgICAgdGhpcy5fdHJhbnNpdGlvbmFibGVQYWludC5zZXRWYWx1ZShuYW1lLCB2YWx1ZSk7XG4gICAgICAgICAgICB0aGlzLl9oYW5kbGVTcGVjaWFsUGFpbnRQcm9wZXJ0eVVwZGF0ZShuYW1lKTtcblxuICAgICAgICAgICAgY29uc3QgbmV3VmFsdWUgPSB0aGlzLl90cmFuc2l0aW9uYWJsZVBhaW50Ll92YWx1ZXNbbmFtZV0udmFsdWU7XG4gICAgICAgICAgICBjb25zdCBpc0RhdGFEcml2ZW4gPSBuZXdWYWx1ZS5pc0RhdGFEcml2ZW4oKTtcbiAgICAgICAgICAgIGNvbnN0IGlzUGF0dGVybiA9IGVuZHNXaXRoKG5hbWUsICdwYXR0ZXJuJykgfHwgbmFtZSA9PT0gJ2xpbmUtZGFzaGFycmF5JztcblxuICAgICAgICAgICAgLy8gaWYgYSBwYXR0ZXJuIHZhbHVlIGlzIGNoYW5nZWQsIHdlIG5lZWQgdG8gbWFrZSBzdXJlIHRoZSBuZXcgaWNvbnMgZ2V0IGFkZGVkIHRvIGVhY2ggdGlsZSdzIGljb25BdGxhc1xuICAgICAgICAgICAgLy8gc28gYSBjYWxsIHRvIF91cGRhdGVMYXllciBpcyBuZWNlc3NhcnksIGFuZCB3ZSByZXR1cm4gdHJ1ZSBmcm9tIHRoaXMgZnVuY3Rpb24gc28gaXQgZ2V0cyBjYWxsZWQgaW5cbiAgICAgICAgICAgIC8vIFN0eWxlI3NldFBhaW50UHJvcGVydHlcbiAgICAgICAgICAgIHJldHVybiBpc0RhdGFEcml2ZW4gfHwgd2FzRGF0YURyaXZlbiB8fCBpc1BhdHRlcm4gfHwgdGhpcy5faGFuZGxlT3ZlcnJpZGFibGVQYWludFByb3BlcnR5VXBkYXRlKG5hbWUsIG9sZFZhbHVlLCBuZXdWYWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfaGFuZGxlU3BlY2lhbFBhaW50UHJvcGVydHlVcGRhdGUoXzogc3RyaW5nKSB7XG4gICAgICAgIC8vIE5vLW9wOyBjYW4gYmUgb3ZlcnJpZGRlbiBieSBkZXJpdmVkIGNsYXNzZXMuXG4gICAgfVxuXG4gICAgZ2V0UHJvZ3JhbUlkcygpOiBzdHJpbmdbXSB8IG51bGwge1xuICAgICAgICAvLyBOby1vcDsgY2FuIGJlIG92ZXJyaWRkZW4gYnkgZGVyaXZlZCBjbGFzc2VzLlxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBnZXRQcm9ncmFtQ29uZmlndXJhdGlvbihfOiBudW1iZXIpOiBQcm9ncmFtQ29uZmlndXJhdGlvbiB8IG51bGwge1xuICAgICAgICAvLyBOby1vcDsgY2FuIGJlIG92ZXJyaWRkZW4gYnkgZGVyaXZlZCBjbGFzc2VzLlxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICBfaGFuZGxlT3ZlcnJpZGFibGVQYWludFByb3BlcnR5VXBkYXRlPFQsIFI+KG5hbWU6IHN0cmluZywgb2xkVmFsdWU6IFByb3BlcnR5VmFsdWU8VCwgUj4sIG5ld1ZhbHVlOiBQcm9wZXJ0eVZhbHVlPFQsIFI+KTogYm9vbGVhbiB7XG4gICAgICAgIC8vIE5vLW9wOyBjYW4gYmUgb3ZlcnJpZGRlbiBieSBkZXJpdmVkIGNsYXNzZXMuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpc0hpZGRlbih6b29tOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKHRoaXMubWluem9vbSAmJiB6b29tIDwgdGhpcy5taW56b29tKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgaWYgKHRoaXMubWF4em9vbSAmJiB6b29tID49IHRoaXMubWF4em9vbSkgcmV0dXJuIHRydWU7XG4gICAgICAgIHJldHVybiB0aGlzLnZpc2liaWxpdHkgPT09ICdub25lJztcbiAgICB9XG5cbiAgICB1cGRhdGVUcmFuc2l0aW9ucyhwYXJhbWV0ZXJzOiBUcmFuc2l0aW9uUGFyYW1ldGVycykge1xuICAgICAgICB0aGlzLl90cmFuc2l0aW9uaW5nUGFpbnQgPSB0aGlzLl90cmFuc2l0aW9uYWJsZVBhaW50LnRyYW5zaXRpb25lZChwYXJhbWV0ZXJzLCB0aGlzLl90cmFuc2l0aW9uaW5nUGFpbnQpO1xuICAgIH1cblxuICAgIGhhc1RyYW5zaXRpb24oKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl90cmFuc2l0aW9uaW5nUGFpbnQuaGFzVHJhbnNpdGlvbigpO1xuICAgIH1cblxuICAgIHJlY2FsY3VsYXRlKHBhcmFtZXRlcnM6IEV2YWx1YXRpb25QYXJhbWV0ZXJzLCBhdmFpbGFibGVJbWFnZXM6IEFycmF5PHN0cmluZz4pIHtcbiAgICAgICAgaWYgKHRoaXMuX3VuZXZhbHVhdGVkTGF5b3V0KSB7XG4gICAgICAgICAgICAodGhpczogYW55KS5sYXlvdXQgPSB0aGlzLl91bmV2YWx1YXRlZExheW91dC5wb3NzaWJseUV2YWx1YXRlKHBhcmFtZXRlcnMsIHVuZGVmaW5lZCwgYXZhaWxhYmxlSW1hZ2VzKTtcbiAgICAgICAgfVxuXG4gICAgICAgICh0aGlzOiBhbnkpLnBhaW50ID0gdGhpcy5fdHJhbnNpdGlvbmluZ1BhaW50LnBvc3NpYmx5RXZhbHVhdGUocGFyYW1ldGVycywgdW5kZWZpbmVkLCBhdmFpbGFibGVJbWFnZXMpO1xuICAgIH1cblxuICAgIHNlcmlhbGl6ZSgpOiBMYXllclNwZWNpZmljYXRpb24ge1xuICAgICAgICBjb25zdCBvdXRwdXQ6IGFueSA9IHtcbiAgICAgICAgICAgICdpZCc6IHRoaXMuaWQsXG4gICAgICAgICAgICAndHlwZSc6IHRoaXMudHlwZSxcbiAgICAgICAgICAgICdzb3VyY2UnOiB0aGlzLnNvdXJjZSxcbiAgICAgICAgICAgICdzb3VyY2UtbGF5ZXInOiB0aGlzLnNvdXJjZUxheWVyLFxuICAgICAgICAgICAgJ21ldGFkYXRhJzogdGhpcy5tZXRhZGF0YSxcbiAgICAgICAgICAgICdtaW56b29tJzogdGhpcy5taW56b29tLFxuICAgICAgICAgICAgJ21heHpvb20nOiB0aGlzLm1heHpvb20sXG4gICAgICAgICAgICAnZmlsdGVyJzogdGhpcy5maWx0ZXIsXG4gICAgICAgICAgICAnbGF5b3V0JzogdGhpcy5fdW5ldmFsdWF0ZWRMYXlvdXQgJiYgdGhpcy5fdW5ldmFsdWF0ZWRMYXlvdXQuc2VyaWFsaXplKCksXG4gICAgICAgICAgICAncGFpbnQnOiB0aGlzLl90cmFuc2l0aW9uYWJsZVBhaW50ICYmIHRoaXMuX3RyYW5zaXRpb25hYmxlUGFpbnQuc2VyaWFsaXplKClcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAodGhpcy52aXNpYmlsaXR5KSB7XG4gICAgICAgICAgICBvdXRwdXQubGF5b3V0ID0gb3V0cHV0LmxheW91dCB8fCB7fTtcbiAgICAgICAgICAgIG91dHB1dC5sYXlvdXQudmlzaWJpbGl0eSA9IHRoaXMudmlzaWJpbGl0eTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmaWx0ZXJPYmplY3Qob3V0cHV0LCAodmFsdWUsIGtleSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAgICAgICAhKGtleSA9PT0gJ2xheW91dCcgJiYgIU9iamVjdC5rZXlzKHZhbHVlKS5sZW5ndGgpICYmXG4gICAgICAgICAgICAgICAgIShrZXkgPT09ICdwYWludCcgJiYgIU9iamVjdC5rZXlzKHZhbHVlKS5sZW5ndGgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBfdmFsaWRhdGUodmFsaWRhdGU6IEZ1bmN0aW9uLCBrZXk6IHN0cmluZywgbmFtZTogc3RyaW5nLCB2YWx1ZTogbWl4ZWQsIG9wdGlvbnM6IFN0eWxlU2V0dGVyT3B0aW9ucyA9IHt9KTogYm9vbGVhbiB7XG4gICAgICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMudmFsaWRhdGUgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGVtaXRWYWxpZGF0aW9uRXJyb3JzKHRoaXMsIHZhbGlkYXRlLmNhbGwodmFsaWRhdGVTdHlsZSwge1xuICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgbGF5ZXJUeXBlOiB0aGlzLnR5cGUsXG4gICAgICAgICAgICBvYmplY3RLZXk6IG5hbWUsXG4gICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgIHN0eWxlU3BlYyxcbiAgICAgICAgICAgIC8vIFdvcmthcm91bmQgZm9yIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXBib3gvbWFwYm94LWdsLWpzL2lzc3Vlcy8yNDA3XG4gICAgICAgICAgICBzdHlsZToge2dseXBoczogdHJ1ZSwgc3ByaXRlOiB0cnVlfVxuICAgICAgICB9KSk7XG4gICAgfVxuXG4gICAgaXMzRCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlzU2t5KCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaXNUaWxlQ2xpcHBlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGhhc09mZnNjcmVlblBhc3MoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXNpemUoKSB7XG4gICAgICAgIC8vIG5vb3BcbiAgICB9XG5cbiAgICBpc1N0YXRlRGVwZW5kZW50KCk6IGJvb2xlYW4ge1xuICAgICAgICBmb3IgKGNvbnN0IHByb3BlcnR5IGluICh0aGlzOiBhbnkpLnBhaW50Ll92YWx1ZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gKHRoaXM6IGFueSkucGFpbnQuZ2V0KHByb3BlcnR5KTtcbiAgICAgICAgICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgUG9zc2libHlFdmFsdWF0ZWRQcm9wZXJ0eVZhbHVlKSB8fCAhc3VwcG9ydHNQcm9wZXJ0eUV4cHJlc3Npb24odmFsdWUucHJvcGVydHkuc3BlY2lmaWNhdGlvbikpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCh2YWx1ZS52YWx1ZS5raW5kID09PSAnc291cmNlJyB8fCB2YWx1ZS52YWx1ZS5raW5kID09PSAnY29tcG9zaXRlJykgJiZcbiAgICAgICAgICAgICAgICB2YWx1ZS52YWx1ZS5pc1N0YXRlRGVwZW5kZW50KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbXBpbGVGaWx0ZXIoKSB7XG4gICAgICAgIGlmICghdGhpcy5fZmlsdGVyQ29tcGlsZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX2ZlYXR1cmVGaWx0ZXIgPSBmZWF0dXJlRmlsdGVyKHRoaXMuZmlsdGVyKTtcbiAgICAgICAgICAgIHRoaXMuX2ZpbHRlckNvbXBpbGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGludmFsaWRhdGVDb21waWxlZEZpbHRlcigpIHtcbiAgICAgICAgdGhpcy5fZmlsdGVyQ29tcGlsZWQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBkeW5hbWljRmlsdGVyKCk6ID9GaWx0ZXJFeHByZXNzaW9uIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZlYXR1cmVGaWx0ZXIuZHluYW1pY0ZpbHRlcjtcbiAgICB9XG5cbiAgICBkeW5hbWljRmlsdGVyTmVlZHNGZWF0dXJlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fZmVhdHVyZUZpbHRlci5uZWVkRmVhdHVyZTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFN0eWxlTGF5ZXI7XG4iLCIvLyBAZmxvd1xuaW1wb3J0IHtjcmVhdGVMYXlvdXR9IGZyb20gJy4uLy4uL3V0aWwvc3RydWN0X2FycmF5LmpzJztcblxuaW1wb3J0IHR5cGUge1N0cnVjdEFycmF5TGF5b3V0fSBmcm9tICcuLi8uLi91dGlsL3N0cnVjdF9hcnJheS5qcyc7XG5cbmV4cG9ydCBjb25zdCBjaXJjbGVBdHRyaWJ1dGVzOiBTdHJ1Y3RBcnJheUxheW91dCA9IGNyZWF0ZUxheW91dChbXG4gICAge25hbWU6ICdhX3BvcycsIGNvbXBvbmVudHM6IDIsIHR5cGU6ICdJbnQxNid9XG5dLCA0KTtcblxuZXhwb3J0IGNvbnN0IGNpcmNsZUdsb2JlQXR0cmlidXRlc0V4dDogU3RydWN0QXJyYXlMYXlvdXQgPSBjcmVhdGVMYXlvdXQoW1xuICAgIHtuYW1lOiAnYV9wb3NfMycsIGNvbXBvbmVudHM6IDMsIHR5cGU6ICdJbnQxNid9LFxuICAgIHtuYW1lOiAnYV9wb3Nfbm9ybWFsXzMnLCBjb21wb25lbnRzOiAzLCB0eXBlOiAnSW50MTYnfVxuXSk7XG5cbmV4cG9ydCBjb25zdCB7bWVtYmVycywgc2l6ZSwgYWxpZ25tZW50fSA9IGNpcmNsZUF0dHJpYnV0ZXM7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge3dhcm5PbmNlfSBmcm9tICcuLi91dGlsL3V0aWwuanMnO1xuXG5pbXBvcnQge3JlZ2lzdGVyfSBmcm9tICcuLi91dGlsL3dlYl93b3JrZXJfdHJhbnNmZXIuanMnO1xuXG5pbXBvcnQgdHlwZSBWZXJ0ZXhBcnJheU9iamVjdCBmcm9tICcuLi9yZW5kZXIvdmVydGV4X2FycmF5X29iamVjdC5qcyc7XG5pbXBvcnQgdHlwZSB7U3RydWN0QXJyYXl9IGZyb20gJy4uL3V0aWwvc3RydWN0X2FycmF5LmpzJztcblxuZXhwb3J0IHR5cGUgU2VnbWVudCA9IHtcbiAgICBzb3J0S2V5OiBudW1iZXIgfCB2b2lkLFxuICAgIHZlcnRleE9mZnNldDogbnVtYmVyLFxuICAgIHByaW1pdGl2ZU9mZnNldDogbnVtYmVyLFxuICAgIHZlcnRleExlbmd0aDogbnVtYmVyLFxuICAgIHByaW1pdGl2ZUxlbmd0aDogbnVtYmVyLFxuICAgIHZhb3M6IHtbXzogc3RyaW5nXTogVmVydGV4QXJyYXlPYmplY3R9XG59XG5cbmNsYXNzIFNlZ21lbnRWZWN0b3Ige1xuICAgIHN0YXRpYyBNQVhfVkVSVEVYX0FSUkFZX0xFTkdUSDogbnVtYmVyO1xuICAgIHNlZ21lbnRzOiBBcnJheTxTZWdtZW50PjtcblxuICAgIGNvbnN0cnVjdG9yKHNlZ21lbnRzPzogQXJyYXk8U2VnbWVudD4gPSBbXSkge1xuICAgICAgICB0aGlzLnNlZ21lbnRzID0gc2VnbWVudHM7XG4gICAgfVxuXG4gICAgcHJlcGFyZVNlZ21lbnQobnVtVmVydGljZXM6IG51bWJlciwgbGF5b3V0VmVydGV4QXJyYXk6IFN0cnVjdEFycmF5LCBpbmRleEFycmF5OiBTdHJ1Y3RBcnJheSwgc29ydEtleT86IG51bWJlcik6IFNlZ21lbnQge1xuICAgICAgICBsZXQgc2VnbWVudDogU2VnbWVudCA9IHRoaXMuc2VnbWVudHNbdGhpcy5zZWdtZW50cy5sZW5ndGggLSAxXTtcbiAgICAgICAgaWYgKG51bVZlcnRpY2VzID4gU2VnbWVudFZlY3Rvci5NQVhfVkVSVEVYX0FSUkFZX0xFTkdUSCkgd2Fybk9uY2UoYE1heCB2ZXJ0aWNlcyBwZXIgc2VnbWVudCBpcyAke1NlZ21lbnRWZWN0b3IuTUFYX1ZFUlRFWF9BUlJBWV9MRU5HVEh9OiBidWNrZXQgcmVxdWVzdGVkICR7bnVtVmVydGljZXN9YCk7XG4gICAgICAgIGlmICghc2VnbWVudCB8fCBzZWdtZW50LnZlcnRleExlbmd0aCArIG51bVZlcnRpY2VzID4gU2VnbWVudFZlY3Rvci5NQVhfVkVSVEVYX0FSUkFZX0xFTkdUSCB8fCBzZWdtZW50LnNvcnRLZXkgIT09IHNvcnRLZXkpIHtcbiAgICAgICAgICAgIHNlZ21lbnQgPSAoe1xuICAgICAgICAgICAgICAgIHZlcnRleE9mZnNldDogbGF5b3V0VmVydGV4QXJyYXkubGVuZ3RoLFxuICAgICAgICAgICAgICAgIHByaW1pdGl2ZU9mZnNldDogaW5kZXhBcnJheS5sZW5ndGgsXG4gICAgICAgICAgICAgICAgdmVydGV4TGVuZ3RoOiAwLFxuICAgICAgICAgICAgICAgIHByaW1pdGl2ZUxlbmd0aDogMFxuICAgICAgICAgICAgfTogYW55KTtcbiAgICAgICAgICAgIGlmIChzb3J0S2V5ICE9PSB1bmRlZmluZWQpIHNlZ21lbnQuc29ydEtleSA9IHNvcnRLZXk7XG4gICAgICAgICAgICB0aGlzLnNlZ21lbnRzLnB1c2goc2VnbWVudCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNlZ21lbnQ7XG4gICAgfVxuXG4gICAgZ2V0KCk6IEFycmF5PFNlZ21lbnQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VnbWVudHM7XG4gICAgfVxuXG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgZm9yIChjb25zdCBzZWdtZW50IG9mIHRoaXMuc2VnbWVudHMpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgayBpbiBzZWdtZW50LnZhb3MpIHtcbiAgICAgICAgICAgICAgICBzZWdtZW50LnZhb3Nba10uZGVzdHJveSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhdGljIHNpbXBsZVNlZ21lbnQodmVydGV4T2Zmc2V0OiBudW1iZXIsIHByaW1pdGl2ZU9mZnNldDogbnVtYmVyLCB2ZXJ0ZXhMZW5ndGg6IG51bWJlciwgcHJpbWl0aXZlTGVuZ3RoOiBudW1iZXIpOiBTZWdtZW50VmVjdG9yIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTZWdtZW50VmVjdG9yKFt7XG4gICAgICAgICAgICB2ZXJ0ZXhPZmZzZXQsXG4gICAgICAgICAgICBwcmltaXRpdmVPZmZzZXQsXG4gICAgICAgICAgICB2ZXJ0ZXhMZW5ndGgsXG4gICAgICAgICAgICBwcmltaXRpdmVMZW5ndGgsXG4gICAgICAgICAgICB2YW9zOiB7fSxcbiAgICAgICAgICAgIHNvcnRLZXk6IDBcbiAgICAgICAgfV0pO1xuICAgIH1cbn1cblxuLypcbiAqIFRoZSBtYXhpbXVtIHNpemUgb2YgYSB2ZXJ0ZXggYXJyYXkuIFRoaXMgbGltaXQgaXMgaW1wb3NlZCBieSBXZWJHTCdzIDE2IGJpdFxuICogYWRkcmVzc2luZyBvZiB2ZXJ0ZXggYnVmZmVycy5cbiAqIEBwcml2YXRlXG4gKiBAcmVhZG9ubHlcbiAqL1xuU2VnbWVudFZlY3Rvci5NQVhfVkVSVEVYX0FSUkFZX0xFTkdUSCA9IE1hdGgucG93KDIsIDE2KSAtIDE7XG5cbnJlZ2lzdGVyKFNlZ21lbnRWZWN0b3IsICdTZWdtZW50VmVjdG9yJyk7XG5leHBvcnQgZGVmYXVsdCBTZWdtZW50VmVjdG9yO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtcbiAgICBMaW5lSW5kZXhBcnJheSxcbiAgICBUcmlhbmdsZUluZGV4QXJyYXksXG4gICAgTGluZVN0cmlwSW5kZXhBcnJheVxufSBmcm9tICcuL2FycmF5X3R5cGVzLmpzJztcblxuLyoqXG4gKiBBbiBpbmRleCBhcnJheSBzdG9yZXMgVWludDE2IGluZGljZXMgb2YgdmVydGV4ZXMgaW4gYSBjb3JyZXNwb25kaW5nIHZlcnRleCBhcnJheS4gV2UgdXNlXG4gKiB0aHJlZSBraW5kcyBvZiBpbmRleCBhcnJheXM6IGFycmF5cyBzdG9yaW5nIGdyb3VwcyBvZiB0aHJlZSBpbmRpY2VzLCBmb3JtaW5nIHRyaWFuZ2xlcztcbiAqIGFycmF5cyBzdG9yaW5nIHBhaXJzIG9mIGluZGljZXMsIGZvcm1pbmcgbGluZSBzZWdtZW50czsgYW5kIGFycmF5cyBzdG9yaW5nIHNpbmdsZSBpbmRpY2VzLFxuICogZm9ybWluZyBhIGxpbmUgc3RyaXAuXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQge0xpbmVJbmRleEFycmF5LCBUcmlhbmdsZUluZGV4QXJyYXksIExpbmVTdHJpcEluZGV4QXJyYXl9O1xuIiwiLy8gQGZsb3dcblxuLyoqXG4gKiBUaGUgbWF4aW11bSB2YWx1ZSBvZiBhIGNvb3JkaW5hdGUgaW4gdGhlIGludGVybmFsIHRpbGUgY29vcmRpbmF0ZSBzeXN0ZW0uIENvb3JkaW5hdGVzIG9mXG4gKiBhbGwgc291cmNlIGZlYXR1cmVzIG5vcm1hbGl6ZWQgdG8gdGhpcyBleHRlbnQgdXBvbiBsb2FkLlxuICpcbiAqIFRoZSB2YWx1ZSBpcyBhIGNvbnNlcXVlbmNlIG9mIHRoZSBmb2xsb3dpbmc6XG4gKlxuICogKiBWZXJ0ZXggYnVmZmVyIHN0b3JlIHBvc2l0aW9ucyBhcyBzaWduZWQgMTYgYml0IGludGVnZXJzLlxuICogKiBPbmUgYml0IGlzIGxvc3QgZm9yIHNpZ25lZG5lc3MgdG8gc3VwcG9ydCB0aWxlIGJ1ZmZlcnMuXG4gKiAqIE9uZSBiaXQgaXMgbG9zdCBiZWNhdXNlIHRoZSBsaW5lIHZlcnRleCBidWZmZXIgdXNlZCB0byBwYWNrIDEgYml0IG9mIG90aGVyIGRhdGEgaW50byB0aGUgaW50LlxuICogKiBPbmUgYml0IGlzIGxvc3QgdG8gc3VwcG9ydCBmZWF0dXJlcyBleHRlbmRpbmcgcGFzdCB0aGUgZXh0ZW50IG9uIHRoZSByaWdodCBlZGdlIG9mIHRoZSB0aWxlLlxuICogKiBUaGlzIGxlYXZlcyB1cyB3aXRoIDJeMTMgPSA4MTkyXG4gKlxuICogQHByaXZhdGVcbiAqIEByZWFkb25seVxuICovXG5leHBvcnQgZGVmYXVsdCA4MTkyO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IExuZ0xhdCBmcm9tICcuL2xuZ19sYXQuanMnO1xuXG5pbXBvcnQgdHlwZSB7TG5nTGF0TGlrZX0gZnJvbSAnLi9sbmdfbGF0LmpzJztcblxuLyoqXG4gKiBBIGBMbmdMYXRCb3VuZHNgIG9iamVjdCByZXByZXNlbnRzIGEgZ2VvZ3JhcGhpY2FsIGJvdW5kaW5nIGJveCxcbiAqIGRlZmluZWQgYnkgaXRzIHNvdXRod2VzdCBhbmQgbm9ydGhlYXN0IHBvaW50cyBpbiBsb25naXR1ZGUgYW5kIGxhdGl0dWRlLlxuICpcbiAqIElmIG5vIGFyZ3VtZW50cyBhcmUgcHJvdmlkZWQgdG8gdGhlIGNvbnN0cnVjdG9yLCBhIGBudWxsYCBib3VuZGluZyBib3ggaXMgY3JlYXRlZC5cbiAqXG4gKiBOb3RlIHRoYXQgYW55IE1hcGJveCBHTCBtZXRob2QgdGhhdCBhY2NlcHRzIGEgYExuZ0xhdEJvdW5kc2Agb2JqZWN0IGFzIGFuIGFyZ3VtZW50IG9yIG9wdGlvblxuICogY2FuIGFsc28gYWNjZXB0IGFuIGBBcnJheWAgb2YgdHdvIHtAbGluayBMbmdMYXRMaWtlfSBjb25zdHJ1Y3RzIGFuZCB3aWxsIHBlcmZvcm0gYW4gaW1wbGljaXQgY29udmVyc2lvbi5cbiAqIFRoaXMgZmxleGlibGUgdHlwZSBpcyBkb2N1bWVudGVkIGFzIHtAbGluayBMbmdMYXRCb3VuZHNMaWtlfS5cbiAqXG4gKiBAcGFyYW0ge0xuZ0xhdExpa2V9IFtzd10gVGhlIHNvdXRod2VzdCBjb3JuZXIgb2YgdGhlIGJvdW5kaW5nIGJveC5cbiAqIEBwYXJhbSB7TG5nTGF0TGlrZX0gW25lXSBUaGUgbm9ydGhlYXN0IGNvcm5lciBvZiB0aGUgYm91bmRpbmcgYm94LlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHN3ID0gbmV3IG1hcGJveGdsLkxuZ0xhdCgtNzMuOTg3NiwgNDAuNzY2MSk7XG4gKiBjb25zdCBuZSA9IG5ldyBtYXBib3hnbC5MbmdMYXQoLTczLjkzOTcsIDQwLjgwMDIpO1xuICogY29uc3QgbGxiID0gbmV3IG1hcGJveGdsLkxuZ0xhdEJvdW5kcyhzdywgbmUpO1xuICovXG5jbGFzcyBMbmdMYXRCb3VuZHMge1xuICAgIF9uZTogTG5nTGF0O1xuICAgIF9zdzogTG5nTGF0O1xuXG4gICAgLy8gVGhpcyBjb25zdHJ1Y3RvciBpcyB0b28gZmxleGlibGUgdG8gdHlwZS4gSXQgc2hvdWxkIG5vdCBiZSBzbyBmbGV4aWJsZS5cbiAgICBjb25zdHJ1Y3RvcihzdzogYW55LCBuZTogYW55KSB7XG4gICAgICAgIGlmICghc3cpIHtcbiAgICAgICAgICAgIC8vIG5vb3BcbiAgICAgICAgfSBlbHNlIGlmIChuZSkge1xuICAgICAgICAgICAgdGhpcy5zZXRTb3V0aFdlc3Qoc3cpLnNldE5vcnRoRWFzdChuZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoc3cubGVuZ3RoID09PSA0KSB7XG4gICAgICAgICAgICB0aGlzLnNldFNvdXRoV2VzdChbc3dbMF0sIHN3WzFdXSkuc2V0Tm9ydGhFYXN0KFtzd1syXSwgc3dbM11dKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U291dGhXZXN0KHN3WzBdKS5zZXROb3J0aEVhc3Qoc3dbMV0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBub3J0aGVhc3QgY29ybmVyIG9mIHRoZSBib3VuZGluZyBib3guXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0xuZ0xhdExpa2V9IG5lIEEge0BsaW5rIExuZ0xhdExpa2V9IG9iamVjdCBkZXNjcmliaW5nIHRoZSBub3J0aGVhc3QgY29ybmVyIG9mIHRoZSBib3VuZGluZyBib3guXG4gICAgICogQHJldHVybnMge0xuZ0xhdEJvdW5kc30gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHN3ID0gbmV3IG1hcGJveGdsLkxuZ0xhdCgtNzMuOTg3NiwgNDAuNzY2MSk7XG4gICAgICogY29uc3QgbmUgPSBuZXcgbWFwYm94Z2wuTG5nTGF0KC03My45Mzk3LCA0MC44MDAyKTtcbiAgICAgKiBjb25zdCBsbGIgPSBuZXcgbWFwYm94Z2wuTG5nTGF0Qm91bmRzKHN3LCBuZSk7XG4gICAgICogbGxiLnNldE5vcnRoRWFzdChbLTczLjkzOTcsIDQyLjgwMDJdKTtcbiAgICAgKi9cbiAgICBzZXROb3J0aEVhc3QobmU6IExuZ0xhdExpa2UpOiB0aGlzIHtcbiAgICAgICAgdGhpcy5fbmUgPSBuZSBpbnN0YW5jZW9mIExuZ0xhdCA/IG5ldyBMbmdMYXQobmUubG5nLCBuZS5sYXQpIDogTG5nTGF0LmNvbnZlcnQobmUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIHNvdXRod2VzdCBjb3JuZXIgb2YgdGhlIGJvdW5kaW5nIGJveC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7TG5nTGF0TGlrZX0gc3cgQSB7QGxpbmsgTG5nTGF0TGlrZX0gb2JqZWN0IGRlc2NyaWJpbmcgdGhlIHNvdXRod2VzdCBjb3JuZXIgb2YgdGhlIGJvdW5kaW5nIGJveC5cbiAgICAgKiBAcmV0dXJucyB7TG5nTGF0Qm91bmRzfSBSZXR1cm5zIGl0c2VsZiB0byBhbGxvdyBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgc3cgPSBuZXcgbWFwYm94Z2wuTG5nTGF0KC03My45ODc2LCA0MC43NjYxKTtcbiAgICAgKiBjb25zdCBuZSA9IG5ldyBtYXBib3hnbC5MbmdMYXQoLTczLjkzOTcsIDQwLjgwMDIpO1xuICAgICAqIGNvbnN0IGxsYiA9IG5ldyBtYXBib3hnbC5MbmdMYXRCb3VuZHMoc3csIG5lKTtcbiAgICAgKiBsbGIuc2V0U291dGhXZXN0KFstNzMuOTg3NiwgNDAuMjY2MV0pO1xuICAgICAqL1xuICAgIHNldFNvdXRoV2VzdChzdzogTG5nTGF0TGlrZSk6IHRoaXMge1xuICAgICAgICB0aGlzLl9zdyA9IHN3IGluc3RhbmNlb2YgTG5nTGF0ID8gbmV3IExuZ0xhdChzdy5sbmcsIHN3LmxhdCkgOiBMbmdMYXQuY29udmVydChzdyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4dGVuZCB0aGUgYm91bmRzIHRvIGluY2x1ZGUgYSBnaXZlbiBMbmdMYXRMaWtlIG9yIExuZ0xhdEJvdW5kc0xpa2UuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0xuZ0xhdExpa2V8TG5nTGF0Qm91bmRzTGlrZX0gb2JqIE9iamVjdCB0byBleHRlbmQgdG8uXG4gICAgICogQHJldHVybnMge0xuZ0xhdEJvdW5kc30gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHN3ID0gbmV3IG1hcGJveGdsLkxuZ0xhdCgtNzMuOTg3NiwgNDAuNzY2MSk7XG4gICAgICogY29uc3QgbmUgPSBuZXcgbWFwYm94Z2wuTG5nTGF0KC03My45Mzk3LCA0MC44MDAyKTtcbiAgICAgKiBjb25zdCBsbGIgPSBuZXcgbWFwYm94Z2wuTG5nTGF0Qm91bmRzKHN3LCBuZSk7XG4gICAgICogbGxiLmV4dGVuZChbLTcyLjk4NzYsIDQyLjI2NjFdKTtcbiAgICAgKi9cbiAgICBleHRlbmQob2JqOiBMbmdMYXRMaWtlIHwgTG5nTGF0Qm91bmRzTGlrZSk6IHRoaXMge1xuICAgICAgICBjb25zdCBzdyA9IHRoaXMuX3N3LFxuICAgICAgICAgICAgbmUgPSB0aGlzLl9uZTtcbiAgICAgICAgbGV0IHN3MiwgbmUyO1xuXG4gICAgICAgIGlmIChvYmogaW5zdGFuY2VvZiBMbmdMYXQpIHtcbiAgICAgICAgICAgIHN3MiA9IG9iajtcbiAgICAgICAgICAgIG5lMiA9IG9iajtcblxuICAgICAgICB9IGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIExuZ0xhdEJvdW5kcykge1xuICAgICAgICAgICAgc3cyID0gb2JqLl9zdztcbiAgICAgICAgICAgIG5lMiA9IG9iai5fbmU7XG5cbiAgICAgICAgICAgIGlmICghc3cyIHx8ICFuZTIpIHJldHVybiB0aGlzO1xuXG4gICAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICBpZiAob2JqLmxlbmd0aCA9PT0gNCB8fCBvYmouZXZlcnkoQXJyYXkuaXNBcnJheSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBsbmdMYXRCb3VuZHNPYmogPSAoKG9iajogYW55KTogTG5nTGF0Qm91bmRzTGlrZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXh0ZW5kKExuZ0xhdEJvdW5kcy5jb252ZXJ0KGxuZ0xhdEJvdW5kc09iaikpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBsbmdMYXRPYmogPSAoKG9iajogYW55KTogTG5nTGF0TGlrZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXh0ZW5kKExuZ0xhdC5jb252ZXJ0KGxuZ0xhdE9iaikpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIG9iaiAhPT0gbnVsbCAmJiBvYmouaGFzT3duUHJvcGVydHkoXCJsYXRcIikgJiYgKG9iai5oYXNPd25Qcm9wZXJ0eShcImxvblwiKSB8fCBvYmouaGFzT3duUHJvcGVydHkoXCJsbmdcIikpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5leHRlbmQoTG5nTGF0LmNvbnZlcnQob2JqKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghc3cgJiYgIW5lKSB7XG4gICAgICAgICAgICB0aGlzLl9zdyA9IG5ldyBMbmdMYXQoc3cyLmxuZywgc3cyLmxhdCk7XG4gICAgICAgICAgICB0aGlzLl9uZSA9IG5ldyBMbmdMYXQobmUyLmxuZywgbmUyLmxhdCk7XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN3LmxuZyA9IE1hdGgubWluKHN3Mi5sbmcsIHN3LmxuZyk7XG4gICAgICAgICAgICBzdy5sYXQgPSBNYXRoLm1pbihzdzIubGF0LCBzdy5sYXQpO1xuICAgICAgICAgICAgbmUubG5nID0gTWF0aC5tYXgobmUyLmxuZywgbmUubG5nKTtcbiAgICAgICAgICAgIG5lLmxhdCA9IE1hdGgubWF4KG5lMi5sYXQsIG5lLmxhdCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBnZW9ncmFwaGljYWwgY29vcmRpbmF0ZSBlcXVpZGlzdGFudCBmcm9tIHRoZSBib3VuZGluZyBib3gncyBjb3JuZXJzLlxuICAgICAqXG4gICAgICogQHJldHVybnMge0xuZ0xhdH0gVGhlIGJvdW5kaW5nIGJveCdzIGNlbnRlci5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGxsYiA9IG5ldyBtYXBib3hnbC5MbmdMYXRCb3VuZHMoWy03My45ODc2LCA0MC43NjYxXSwgWy03My45Mzk3LCA0MC44MDAyXSk7XG4gICAgICogbGxiLmdldENlbnRlcigpOyAvLyA9IExuZ0xhdCB7bG5nOiAtNzMuOTYzNjUsIGxhdDogNDAuNzgzMTV9XG4gICAgICovXG4gICAgZ2V0Q2VudGVyKCk6IExuZ0xhdCB7XG4gICAgICAgIHJldHVybiBuZXcgTG5nTGF0KCh0aGlzLl9zdy5sbmcgKyB0aGlzLl9uZS5sbmcpIC8gMiwgKHRoaXMuX3N3LmxhdCArIHRoaXMuX25lLmxhdCkgLyAyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBzb3V0aHdlc3QgY29ybmVyIG9mIHRoZSBib3VuZGluZyBib3guXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7TG5nTGF0fSBUaGUgc291dGh3ZXN0IGNvcm5lciBvZiB0aGUgYm91bmRpbmcgYm94LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgbGxiID0gbmV3IG1hcGJveGdsLkxuZ0xhdEJvdW5kcyhbLTczLjk4NzYsIDQwLjc2NjFdLCBbLTczLjkzOTcsIDQwLjgwMDJdKTtcbiAgICAgKiBsbGIuZ2V0U291dGhXZXN0KCk7IC8vIExuZ0xhdCB7bG5nOiAtNzMuOTg3NiwgbGF0OiA0MC43NjYxfVxuICAgICAqL1xuICAgIGdldFNvdXRoV2VzdCgpOiBMbmdMYXQgeyByZXR1cm4gdGhpcy5fc3c7IH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIG5vcnRoZWFzdCBjb3JuZXIgb2YgdGhlIGJvdW5kaW5nIGJveC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtMbmdMYXR9IFRoZSBub3J0aGVhc3QgY29ybmVyIG9mIHRoZSBib3VuZGluZyBib3guXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBsbGIgPSBuZXcgbWFwYm94Z2wuTG5nTGF0Qm91bmRzKFstNzMuOTg3NiwgNDAuNzY2MV0sIFstNzMuOTM5NywgNDAuODAwMl0pO1xuICAgICAqIGxsYi5nZXROb3J0aEVhc3QoKTsgLy8gTG5nTGF0IHtsbmc6IC03My45Mzk3LCBsYXQ6IDQwLjgwMDJ9XG4gICAgICovXG4gICAgZ2V0Tm9ydGhFYXN0KCk6IExuZ0xhdCB7IHJldHVybiB0aGlzLl9uZTsgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgbm9ydGh3ZXN0IGNvcm5lciBvZiB0aGUgYm91bmRpbmcgYm94LlxuICAgICAqXG4gICAgICogQHJldHVybnMge0xuZ0xhdH0gVGhlIG5vcnRod2VzdCBjb3JuZXIgb2YgdGhlIGJvdW5kaW5nIGJveC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGxsYiA9IG5ldyBtYXBib3hnbC5MbmdMYXRCb3VuZHMoWy03My45ODc2LCA0MC43NjYxXSwgWy03My45Mzk3LCA0MC44MDAyXSk7XG4gICAgICogbGxiLmdldE5vcnRoV2VzdCgpOyAvLyBMbmdMYXQge2xuZzogLTczLjk4NzYsIGxhdDogNDAuODAwMn1cbiAgICAgKi9cbiAgICBnZXROb3J0aFdlc3QoKTogTG5nTGF0IHsgcmV0dXJuIG5ldyBMbmdMYXQodGhpcy5nZXRXZXN0KCksIHRoaXMuZ2V0Tm9ydGgoKSk7IH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHNvdXRoZWFzdCBjb3JuZXIgb2YgdGhlIGJvdW5kaW5nIGJveC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtMbmdMYXR9IFRoZSBzb3V0aGVhc3QgY29ybmVyIG9mIHRoZSBib3VuZGluZyBib3guXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBsbGIgPSBuZXcgbWFwYm94Z2wuTG5nTGF0Qm91bmRzKFstNzMuOTg3NiwgNDAuNzY2MV0sIFstNzMuOTM5NywgNDAuODAwMl0pO1xuICAgICAqIGxsYi5nZXRTb3V0aEVhc3QoKTsgLy8gTG5nTGF0IHtsbmc6IC03My45Mzk3LCBsYXQ6IDQwLjc2NjF9XG4gICAgICovXG4gICAgZ2V0U291dGhFYXN0KCk6IExuZ0xhdCB7IHJldHVybiBuZXcgTG5nTGF0KHRoaXMuZ2V0RWFzdCgpLCB0aGlzLmdldFNvdXRoKCkpOyB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB3ZXN0IGVkZ2Ugb2YgdGhlIGJvdW5kaW5nIGJveC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFRoZSB3ZXN0IGVkZ2Ugb2YgdGhlIGJvdW5kaW5nIGJveC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGxsYiA9IG5ldyBtYXBib3hnbC5MbmdMYXRCb3VuZHMoWy03My45ODc2LCA0MC43NjYxXSwgWy03My45Mzk3LCA0MC44MDAyXSk7XG4gICAgICogbGxiLmdldFdlc3QoKTsgLy8gLTczLjk4NzZcbiAgICAgKi9cbiAgICBnZXRXZXN0KCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9zdy5sbmc7IH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHNvdXRoIGVkZ2Ugb2YgdGhlIGJvdW5kaW5nIGJveC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFRoZSBzb3V0aCBlZGdlIG9mIHRoZSBib3VuZGluZyBib3guXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBsbGIgPSBuZXcgbWFwYm94Z2wuTG5nTGF0Qm91bmRzKFstNzMuOTg3NiwgNDAuNzY2MV0sIFstNzMuOTM5NywgNDAuODAwMl0pO1xuICAgICAqIGxsYi5nZXRTb3V0aCgpOyAvLyA0MC43NjYxXG4gICAgICovXG4gICAgZ2V0U291dGgoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3N3LmxhdDsgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgZWFzdCBlZGdlIG9mIHRoZSBib3VuZGluZyBib3guXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgZWFzdCBlZGdlIG9mIHRoZSBib3VuZGluZyBib3guXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBsbGIgPSBuZXcgbWFwYm94Z2wuTG5nTGF0Qm91bmRzKFstNzMuOTg3NiwgNDAuNzY2MV0sIFstNzMuOTM5NywgNDAuODAwMl0pO1xuICAgICAqIGxsYi5nZXRFYXN0KCk7IC8vIC03My45Mzk3XG4gICAgICovXG4gICAgZ2V0RWFzdCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fbmUubG5nOyB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBub3J0aCBlZGdlIG9mIHRoZSBib3VuZGluZyBib3guXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgbm9ydGggZWRnZSBvZiB0aGUgYm91bmRpbmcgYm94LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgbGxiID0gbmV3IG1hcGJveGdsLkxuZ0xhdEJvdW5kcyhbLTczLjk4NzYsIDQwLjc2NjFdLCBbLTczLjkzOTcsIDQwLjgwMDJdKTtcbiAgICAgKiBsbGIuZ2V0Tm9ydGgoKTsgLy8gNDAuODAwMlxuICAgICAqL1xuICAgIGdldE5vcnRoKCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9uZS5sYXQ7IH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGJvdW5kaW5nIGJveCByZXByZXNlbnRlZCBhcyBhbiBhcnJheS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtBcnJheTxBcnJheTxudW1iZXI+Pn0gVGhlIGJvdW5kaW5nIGJveCByZXByZXNlbnRlZCBhcyBhbiBhcnJheSwgY29uc2lzdGluZyBvZiB0aGVcbiAgICAgKiAgIHNvdXRod2VzdCBhbmQgbm9ydGhlYXN0IGNvb3JkaW5hdGVzIG9mIHRoZSBib3VuZGluZyByZXByZXNlbnRlZCBhcyBhcnJheXMgb2YgbnVtYmVycy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGxsYiA9IG5ldyBtYXBib3hnbC5MbmdMYXRCb3VuZHMoWy03My45ODc2LCA0MC43NjYxXSwgWy03My45Mzk3LCA0MC44MDAyXSk7XG4gICAgICogbGxiLnRvQXJyYXkoKTsgLy8gPSBbWy03My45ODc2LCA0MC43NjYxXSwgWy03My45Mzk3LCA0MC44MDAyXV1cbiAgICAgKi9cbiAgICB0b0FycmF5KCk6IFtbbnVtYmVyLCBudW1iZXJdLCBbbnVtYmVyLCBudW1iZXJdXSB7XG4gICAgICAgIHJldHVybiBbdGhpcy5fc3cudG9BcnJheSgpLCB0aGlzLl9uZS50b0FycmF5KCldO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgYm91bmRpbmcgYm94IHJlcHJlc2VudGVkIGFzIGEgc3RyaW5nLlxuICAgICAqXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGJvdW5kaW5nIGJveCByZXByZXNlbnRzIGFzIGEgc3RyaW5nIG9mIHRoZSBmb3JtYXRcbiAgICAgKiAgIGAnTG5nTGF0Qm91bmRzKExuZ0xhdChsbmcsIGxhdCksIExuZ0xhdChsbmcsIGxhdCkpJ2AuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBsbGIgPSBuZXcgbWFwYm94Z2wuTG5nTGF0Qm91bmRzKFstNzMuOTg3NiwgNDAuNzY2MV0sIFstNzMuOTM5NywgNDAuODAwMl0pO1xuICAgICAqIGxsYi50b1N0cmluZygpOyAvLyA9IFwiTG5nTGF0Qm91bmRzKExuZ0xhdCgtNzMuOTg3NiwgNDAuNzY2MSksIExuZ0xhdCgtNzMuOTM5NywgNDAuODAwMikpXCJcbiAgICAgKi9cbiAgICB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gYExuZ0xhdEJvdW5kcygke3RoaXMuX3N3LnRvU3RyaW5nKCl9LCAke3RoaXMuX25lLnRvU3RyaW5nKCl9KWA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2sgaWYgdGhlIGJvdW5kaW5nIGJveCBpcyBhbiBlbXB0eS9gbnVsbGAtdHlwZSBib3guXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBib3VuZHMgaGF2ZSBiZWVuIGRlZmluZWQsIG90aGVyd2lzZSBmYWxzZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGxsYiA9IG5ldyBtYXBib3hnbC5MbmdMYXRCb3VuZHMoKTtcbiAgICAgKiBsbGIuaXNFbXB0eSgpOyAvLyB0cnVlXG4gICAgICogbGxiLnNldE5vcnRoRWFzdChbLTczLjk4NzYsIDQwLjc2NjFdKTtcbiAgICAgKiBsbGIuc2V0U291dGhXZXN0KFstNzMuOTM5NywgNDAuODAwMl0pO1xuICAgICAqIGxsYi5pc0VtcHR5KCk7IC8vIGZhbHNlXG4gICAgICovXG4gICAgaXNFbXB0eSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICEodGhpcy5fc3cgJiYgdGhpcy5fbmUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQ2hlY2sgaWYgdGhlIHBvaW50IGlzIHdpdGhpbiB0aGUgYm91bmRpbmcgYm94LlxuICAgICpcbiAgICAqIEBwYXJhbSB7TG5nTGF0TGlrZX0gbG5nbGF0IEdlb2dyYXBoaWMgcG9pbnQgdG8gY2hlY2sgYWdhaW5zdC5cbiAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSBwb2ludCBpcyB3aXRoaW4gdGhlIGJvdW5kaW5nIGJveC5cbiAgICAqIEBleGFtcGxlXG4gICAgKiBjb25zdCBsbGIgPSBuZXcgbWFwYm94Z2wuTG5nTGF0Qm91bmRzKFxuICAgICogICBuZXcgbWFwYm94Z2wuTG5nTGF0KC03My45ODc2LCA0MC43NjYxKSxcbiAgICAqICAgbmV3IG1hcGJveGdsLkxuZ0xhdCgtNzMuOTM5NywgNDAuODAwMilcbiAgICAqICk7XG4gICAgKlxuICAgICogY29uc3QgbGwgPSBuZXcgbWFwYm94Z2wuTG5nTGF0KC03My45NTY3LCA0MC43Nzg5KTtcbiAgICAqXG4gICAgKiBjb25zb2xlLmxvZyhsbGIuY29udGFpbnMobGwpKTsgLy8gPSB0cnVlXG4gICAgKi9cbiAgICBjb250YWlucyhsbmdsYXQ6IExuZ0xhdExpa2UpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3Qge2xuZywgbGF0fSA9IExuZ0xhdC5jb252ZXJ0KGxuZ2xhdCk7XG5cbiAgICAgICAgY29uc3QgY29udGFpbnNMYXRpdHVkZSA9IHRoaXMuX3N3LmxhdCA8PSBsYXQgJiYgbGF0IDw9IHRoaXMuX25lLmxhdDtcbiAgICAgICAgbGV0IGNvbnRhaW5zTG9uZ2l0dWRlID0gdGhpcy5fc3cubG5nIDw9IGxuZyAmJiBsbmcgPD0gdGhpcy5fbmUubG5nO1xuICAgICAgICBpZiAodGhpcy5fc3cubG5nID4gdGhpcy5fbmUubG5nKSB7IC8vIHdyYXBwZWQgY29vcmRpbmF0ZXNcbiAgICAgICAgICAgIGNvbnRhaW5zTG9uZ2l0dWRlID0gdGhpcy5fc3cubG5nID49IGxuZyAmJiBsbmcgPj0gdGhpcy5fbmUubG5nO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvbnRhaW5zTGF0aXR1ZGUgJiYgY29udGFpbnNMb25naXR1ZGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYW4gYXJyYXkgdG8gYSBgTG5nTGF0Qm91bmRzYCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBJZiBhIGBMbmdMYXRCb3VuZHNgIG9iamVjdCBpcyBwYXNzZWQgaW4sIHRoZSBmdW5jdGlvbiByZXR1cm5zIGl0IHVuY2hhbmdlZC5cbiAgICAgKlxuICAgICAqIEludGVybmFsbHksIHRoZSBmdW5jdGlvbiBjYWxscyBgTG5nTGF0I2NvbnZlcnRgIHRvIGNvbnZlcnQgYXJyYXlzIHRvIGBMbmdMYXRgIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7TG5nTGF0Qm91bmRzTGlrZX0gaW5wdXQgQW4gYXJyYXkgb2YgdHdvIGNvb3JkaW5hdGVzIHRvIGNvbnZlcnQsIG9yIGEgYExuZ0xhdEJvdW5kc2Agb2JqZWN0IHRvIHJldHVybi5cbiAgICAgKiBAcmV0dXJucyB7TG5nTGF0Qm91bmRzfSBBIG5ldyBgTG5nTGF0Qm91bmRzYCBvYmplY3QsIGlmIGEgY29udmVyc2lvbiBvY2N1cnJlZCwgb3IgdGhlIG9yaWdpbmFsIGBMbmdMYXRCb3VuZHNgIG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGFyciA9IFtbLTczLjk4NzYsIDQwLjc2NjFdLCBbLTczLjkzOTcsIDQwLjgwMDJdXTtcbiAgICAgKiBjb25zdCBsbGIgPSBtYXBib3hnbC5MbmdMYXRCb3VuZHMuY29udmVydChhcnIpO1xuICAgICAqIGNvbnNvbGUubG9nKGxsYik7ICAgLy8gPSBMbmdMYXRCb3VuZHMge19zdzogTG5nTGF0IHtsbmc6IC03My45ODc2LCBsYXQ6IDQwLjc2NjF9LCBfbmU6IExuZ0xhdCB7bG5nOiAtNzMuOTM5NywgbGF0OiA0MC44MDAyfX1cbiAgICAgKi9cbiAgICBzdGF0aWMgY29udmVydChpbnB1dDogTG5nTGF0Qm91bmRzTGlrZSk6IExuZ0xhdEJvdW5kcyB7XG4gICAgICAgIGlmICghaW5wdXQgfHwgaW5wdXQgaW5zdGFuY2VvZiBMbmdMYXRCb3VuZHMpIHJldHVybiBpbnB1dDtcbiAgICAgICAgcmV0dXJuIG5ldyBMbmdMYXRCb3VuZHMoaW5wdXQpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBBIHtAbGluayBMbmdMYXRCb3VuZHN9IG9iamVjdCwgYW4gYXJyYXkgb2Yge0BsaW5rIExuZ0xhdExpa2V9IG9iamVjdHMgaW4gW3N3LCBuZV0gb3JkZXIsXG4gKiBvciBhbiBhcnJheSBvZiBudW1iZXJzIGluIFt3ZXN0LCBzb3V0aCwgZWFzdCwgbm9ydGhdIG9yZGVyLlxuICpcbiAqIEB0eXBlZGVmIHtMbmdMYXRCb3VuZHMgfCBbTG5nTGF0TGlrZSwgTG5nTGF0TGlrZV0gfCBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXX0gTG5nTGF0Qm91bmRzTGlrZVxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHYxID0gbmV3IG1hcGJveGdsLkxuZ0xhdEJvdW5kcyhcbiAqICAgbmV3IG1hcGJveGdsLkxuZ0xhdCgtNzMuOTg3NiwgNDAuNzY2MSksXG4gKiAgIG5ldyBtYXBib3hnbC5MbmdMYXQoLTczLjkzOTcsIDQwLjgwMDIpXG4gKiApO1xuICogY29uc3QgdjIgPSBuZXcgbWFwYm94Z2wuTG5nTGF0Qm91bmRzKFstNzMuOTg3NiwgNDAuNzY2MV0sIFstNzMuOTM5NywgNDAuODAwMl0pO1xuICogY29uc3QgdjMgPSBbWy03My45ODc2LCA0MC43NjYxXSwgWy03My45Mzk3LCA0MC44MDAyXV07XG4gKi9cbmV4cG9ydCB0eXBlIExuZ0xhdEJvdW5kc0xpa2UgPSBMbmdMYXRCb3VuZHMgfCBbTG5nTGF0TGlrZSwgTG5nTGF0TGlrZV0gfCBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcblxuZXhwb3J0IGRlZmF1bHQgTG5nTGF0Qm91bmRzO1xuIiwiLyoqXG4gKiBDb21tb24gdXRpbGl0aWVzXG4gKiBAbW9kdWxlIGdsTWF0cml4XG4gKi9cbi8vIENvbmZpZ3VyYXRpb24gQ29uc3RhbnRzXG5leHBvcnQgdmFyIEVQU0lMT04gPSAwLjAwMDAwMTtcbmV4cG9ydCB2YXIgQVJSQVlfVFlQRSA9IHR5cGVvZiBGbG9hdDMyQXJyYXkgIT09ICd1bmRlZmluZWQnID8gRmxvYXQzMkFycmF5IDogQXJyYXk7XG5leHBvcnQgdmFyIFJBTkRPTSA9IE1hdGgucmFuZG9tO1xuLyoqXG4gKiBTZXRzIHRoZSB0eXBlIG9mIGFycmF5IHVzZWQgd2hlbiBjcmVhdGluZyBuZXcgdmVjdG9ycyBhbmQgbWF0cmljZXNcbiAqXG4gKiBAcGFyYW0ge0Zsb2F0MzJBcnJheUNvbnN0cnVjdG9yIHwgQXJyYXlDb25zdHJ1Y3Rvcn0gdHlwZSBBcnJheSB0eXBlLCBzdWNoIGFzIEZsb2F0MzJBcnJheSBvciBBcnJheVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRNYXRyaXhBcnJheVR5cGUodHlwZSkge1xuICBBUlJBWV9UWVBFID0gdHlwZTtcbn1cbnZhciBkZWdyZWUgPSBNYXRoLlBJIC8gMTgwO1xuLyoqXG4gKiBDb252ZXJ0IERlZ3JlZSBUbyBSYWRpYW5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gYSBBbmdsZSBpbiBEZWdyZWVzXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRvUmFkaWFuKGEpIHtcbiAgcmV0dXJuIGEgKiBkZWdyZWU7XG59XG4vKipcbiAqIFRlc3RzIHdoZXRoZXIgb3Igbm90IHRoZSBhcmd1bWVudHMgaGF2ZSBhcHByb3hpbWF0ZWx5IHRoZSBzYW1lIHZhbHVlLCB3aXRoaW4gYW4gYWJzb2x1dGVcbiAqIG9yIHJlbGF0aXZlIHRvbGVyYW5jZSBvZiBnbE1hdHJpeC5FUFNJTE9OIChhbiBhYnNvbHV0ZSB0b2xlcmFuY2UgaXMgdXNlZCBmb3IgdmFsdWVzIGxlc3NcbiAqIHRoYW4gb3IgZXF1YWwgdG8gMS4wLCBhbmQgYSByZWxhdGl2ZSB0b2xlcmFuY2UgaXMgdXNlZCBmb3IgbGFyZ2VyIHZhbHVlcylcbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gYSBUaGUgZmlyc3QgbnVtYmVyIHRvIHRlc3QuXG4gKiBAcGFyYW0ge051bWJlcn0gYiBUaGUgc2Vjb25kIG51bWJlciB0byB0ZXN0LlxuICogQHJldHVybnMge0Jvb2xlYW59IFRydWUgaWYgdGhlIG51bWJlcnMgYXJlIGFwcHJveGltYXRlbHkgZXF1YWwsIGZhbHNlIG90aGVyd2lzZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXF1YWxzKGEsIGIpIHtcbiAgcmV0dXJuIE1hdGguYWJzKGEgLSBiKSA8PSBFUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhKSwgTWF0aC5hYnMoYikpO1xufVxuaWYgKCFNYXRoLmh5cG90KSBNYXRoLmh5cG90ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgeSA9IDAsXG4gICAgICBpID0gYXJndW1lbnRzLmxlbmd0aDtcblxuICB3aGlsZSAoaS0tKSB7XG4gICAgeSArPSBhcmd1bWVudHNbaV0gKiBhcmd1bWVudHNbaV07XG4gIH1cblxuICByZXR1cm4gTWF0aC5zcXJ0KHkpO1xufTsiLCJpbXBvcnQgKiBhcyBnbE1hdHJpeCBmcm9tIFwiLi9jb21tb24uanNcIjtcbi8qKlxuICogMngyIE1hdHJpeFxuICogQG1vZHVsZSBtYXQyXG4gKi9cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGlkZW50aXR5IG1hdDJcbiAqXG4gKiBAcmV0dXJucyB7bWF0Mn0gYSBuZXcgMngyIG1hdHJpeFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGUoKSB7XG4gIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSg0KTtcblxuICBpZiAoZ2xNYXRyaXguQVJSQVlfVFlQRSAhPSBGbG9hdDMyQXJyYXkpIHtcbiAgICBvdXRbMV0gPSAwO1xuICAgIG91dFsyXSA9IDA7XG4gIH1cblxuICBvdXRbMF0gPSAxO1xuICBvdXRbM10gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IG1hdDIgaW5pdGlhbGl6ZWQgd2l0aCB2YWx1ZXMgZnJvbSBhbiBleGlzdGluZyBtYXRyaXhcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0Mn0gYSBtYXRyaXggdG8gY2xvbmVcbiAqIEByZXR1cm5zIHttYXQyfSBhIG5ldyAyeDIgbWF0cml4XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNsb25lKGEpIHtcbiAgdmFyIG91dCA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDQpO1xuICBvdXRbMF0gPSBhWzBdO1xuICBvdXRbMV0gPSBhWzFdO1xuICBvdXRbMl0gPSBhWzJdO1xuICBvdXRbM10gPSBhWzNdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDb3B5IHRoZSB2YWx1ZXMgZnJvbSBvbmUgbWF0MiB0byBhbm90aGVyXG4gKlxuICogQHBhcmFtIHttYXQyfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyfSBhIHRoZSBzb3VyY2UgbWF0cml4XG4gKiBAcmV0dXJucyB7bWF0Mn0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNvcHkob3V0LCBhKSB7XG4gIG91dFswXSA9IGFbMF07XG4gIG91dFsxXSA9IGFbMV07XG4gIG91dFsyXSA9IGFbMl07XG4gIG91dFszXSA9IGFbM107XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFNldCBhIG1hdDIgdG8gdGhlIGlkZW50aXR5IG1hdHJpeFxuICpcbiAqIEBwYXJhbSB7bWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcmV0dXJucyB7bWF0Mn0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGlkZW50aXR5KG91dCkge1xuICBvdXRbMF0gPSAxO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgbWF0MiB3aXRoIHRoZSBnaXZlbiB2YWx1ZXNcbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gbTAwIENvbXBvbmVudCBpbiBjb2x1bW4gMCwgcm93IDAgcG9zaXRpb24gKGluZGV4IDApXG4gKiBAcGFyYW0ge051bWJlcn0gbTAxIENvbXBvbmVudCBpbiBjb2x1bW4gMCwgcm93IDEgcG9zaXRpb24gKGluZGV4IDEpXG4gKiBAcGFyYW0ge051bWJlcn0gbTEwIENvbXBvbmVudCBpbiBjb2x1bW4gMSwgcm93IDAgcG9zaXRpb24gKGluZGV4IDIpXG4gKiBAcGFyYW0ge051bWJlcn0gbTExIENvbXBvbmVudCBpbiBjb2x1bW4gMSwgcm93IDEgcG9zaXRpb24gKGluZGV4IDMpXG4gKiBAcmV0dXJucyB7bWF0Mn0gb3V0IEEgbmV3IDJ4MiBtYXRyaXhcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbVZhbHVlcyhtMDAsIG0wMSwgbTEwLCBtMTEpIHtcbiAgdmFyIG91dCA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDQpO1xuICBvdXRbMF0gPSBtMDA7XG4gIG91dFsxXSA9IG0wMTtcbiAgb3V0WzJdID0gbTEwO1xuICBvdXRbM10gPSBtMTE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFNldCB0aGUgY29tcG9uZW50cyBvZiBhIG1hdDIgdG8gdGhlIGdpdmVuIHZhbHVlc1xuICpcbiAqIEBwYXJhbSB7bWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge051bWJlcn0gbTAwIENvbXBvbmVudCBpbiBjb2x1bW4gMCwgcm93IDAgcG9zaXRpb24gKGluZGV4IDApXG4gKiBAcGFyYW0ge051bWJlcn0gbTAxIENvbXBvbmVudCBpbiBjb2x1bW4gMCwgcm93IDEgcG9zaXRpb24gKGluZGV4IDEpXG4gKiBAcGFyYW0ge051bWJlcn0gbTEwIENvbXBvbmVudCBpbiBjb2x1bW4gMSwgcm93IDAgcG9zaXRpb24gKGluZGV4IDIpXG4gKiBAcGFyYW0ge051bWJlcn0gbTExIENvbXBvbmVudCBpbiBjb2x1bW4gMSwgcm93IDEgcG9zaXRpb24gKGluZGV4IDMpXG4gKiBAcmV0dXJucyB7bWF0Mn0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNldChvdXQsIG0wMCwgbTAxLCBtMTAsIG0xMSkge1xuICBvdXRbMF0gPSBtMDA7XG4gIG91dFsxXSA9IG0wMTtcbiAgb3V0WzJdID0gbTEwO1xuICBvdXRbM10gPSBtMTE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFRyYW5zcG9zZSB0aGUgdmFsdWVzIG9mIGEgbWF0MlxuICpcbiAqIEBwYXJhbSB7bWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0Mn0gYSB0aGUgc291cmNlIG1hdHJpeFxuICogQHJldHVybnMge21hdDJ9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc3Bvc2Uob3V0LCBhKSB7XG4gIC8vIElmIHdlIGFyZSB0cmFuc3Bvc2luZyBvdXJzZWx2ZXMgd2UgY2FuIHNraXAgYSBmZXcgc3RlcHMgYnV0IGhhdmUgdG8gY2FjaGVcbiAgLy8gc29tZSB2YWx1ZXNcbiAgaWYgKG91dCA9PT0gYSkge1xuICAgIHZhciBhMSA9IGFbMV07XG4gICAgb3V0WzFdID0gYVsyXTtcbiAgICBvdXRbMl0gPSBhMTtcbiAgfSBlbHNlIHtcbiAgICBvdXRbMF0gPSBhWzBdO1xuICAgIG91dFsxXSA9IGFbMl07XG4gICAgb3V0WzJdID0gYVsxXTtcbiAgICBvdXRbM10gPSBhWzNdO1xuICB9XG5cbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogSW52ZXJ0cyBhIG1hdDJcbiAqXG4gKiBAcGFyYW0ge21hdDJ9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seU1hdDJ9IGEgdGhlIHNvdXJjZSBtYXRyaXhcbiAqIEByZXR1cm5zIHttYXQyfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaW52ZXJ0KG91dCwgYSkge1xuICB2YXIgYTAgPSBhWzBdLFxuICAgICAgYTEgPSBhWzFdLFxuICAgICAgYTIgPSBhWzJdLFxuICAgICAgYTMgPSBhWzNdOyAvLyBDYWxjdWxhdGUgdGhlIGRldGVybWluYW50XG5cbiAgdmFyIGRldCA9IGEwICogYTMgLSBhMiAqIGExO1xuXG4gIGlmICghZGV0KSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBkZXQgPSAxLjAgLyBkZXQ7XG4gIG91dFswXSA9IGEzICogZGV0O1xuICBvdXRbMV0gPSAtYTEgKiBkZXQ7XG4gIG91dFsyXSA9IC1hMiAqIGRldDtcbiAgb3V0WzNdID0gYTAgKiBkZXQ7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGFkanVnYXRlIG9mIGEgbWF0MlxuICpcbiAqIEBwYXJhbSB7bWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0Mn0gYSB0aGUgc291cmNlIG1hdHJpeFxuICogQHJldHVybnMge21hdDJ9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhZGpvaW50KG91dCwgYSkge1xuICAvLyBDYWNoaW5nIHRoaXMgdmFsdWUgaXMgbmVzc2VjYXJ5IGlmIG91dCA9PSBhXG4gIHZhciBhMCA9IGFbMF07XG4gIG91dFswXSA9IGFbM107XG4gIG91dFsxXSA9IC1hWzFdO1xuICBvdXRbMl0gPSAtYVsyXTtcbiAgb3V0WzNdID0gYTA7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGRldGVybWluYW50IG9mIGEgbWF0MlxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyfSBhIHRoZSBzb3VyY2UgbWF0cml4XG4gKiBAcmV0dXJucyB7TnVtYmVyfSBkZXRlcm1pbmFudCBvZiBhXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGRldGVybWluYW50KGEpIHtcbiAgcmV0dXJuIGFbMF0gKiBhWzNdIC0gYVsyXSAqIGFbMV07XG59XG4vKipcbiAqIE11bHRpcGxpZXMgdHdvIG1hdDInc1xuICpcbiAqIEBwYXJhbSB7bWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0Mn0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seU1hdDJ9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7bWF0Mn0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG11bHRpcGx5KG91dCwgYSwgYikge1xuICB2YXIgYTAgPSBhWzBdLFxuICAgICAgYTEgPSBhWzFdLFxuICAgICAgYTIgPSBhWzJdLFxuICAgICAgYTMgPSBhWzNdO1xuICB2YXIgYjAgPSBiWzBdLFxuICAgICAgYjEgPSBiWzFdLFxuICAgICAgYjIgPSBiWzJdLFxuICAgICAgYjMgPSBiWzNdO1xuICBvdXRbMF0gPSBhMCAqIGIwICsgYTIgKiBiMTtcbiAgb3V0WzFdID0gYTEgKiBiMCArIGEzICogYjE7XG4gIG91dFsyXSA9IGEwICogYjIgKyBhMiAqIGIzO1xuICBvdXRbM10gPSBhMSAqIGIyICsgYTMgKiBiMztcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUm90YXRlcyBhIG1hdDIgYnkgdGhlIGdpdmVuIGFuZ2xlXG4gKlxuICogQHBhcmFtIHttYXQyfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyfSBhIHRoZSBtYXRyaXggdG8gcm90YXRlXG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIHRoZSBhbmdsZSB0byByb3RhdGUgdGhlIG1hdHJpeCBieVxuICogQHJldHVybnMge21hdDJ9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByb3RhdGUob3V0LCBhLCByYWQpIHtcbiAgdmFyIGEwID0gYVswXSxcbiAgICAgIGExID0gYVsxXSxcbiAgICAgIGEyID0gYVsyXSxcbiAgICAgIGEzID0gYVszXTtcbiAgdmFyIHMgPSBNYXRoLnNpbihyYWQpO1xuICB2YXIgYyA9IE1hdGguY29zKHJhZCk7XG4gIG91dFswXSA9IGEwICogYyArIGEyICogcztcbiAgb3V0WzFdID0gYTEgKiBjICsgYTMgKiBzO1xuICBvdXRbMl0gPSBhMCAqIC1zICsgYTIgKiBjO1xuICBvdXRbM10gPSBhMSAqIC1zICsgYTMgKiBjO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBTY2FsZXMgdGhlIG1hdDIgYnkgdGhlIGRpbWVuc2lvbnMgaW4gdGhlIGdpdmVuIHZlYzJcbiAqXG4gKiBAcGFyYW0ge21hdDJ9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seU1hdDJ9IGEgdGhlIG1hdHJpeCB0byByb3RhdGVcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSB2IHRoZSB2ZWMyIHRvIHNjYWxlIHRoZSBtYXRyaXggYnlcbiAqIEByZXR1cm5zIHttYXQyfSBvdXRcbiAqKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNjYWxlKG91dCwgYSwgdikge1xuICB2YXIgYTAgPSBhWzBdLFxuICAgICAgYTEgPSBhWzFdLFxuICAgICAgYTIgPSBhWzJdLFxuICAgICAgYTMgPSBhWzNdO1xuICB2YXIgdjAgPSB2WzBdLFxuICAgICAgdjEgPSB2WzFdO1xuICBvdXRbMF0gPSBhMCAqIHYwO1xuICBvdXRbMV0gPSBhMSAqIHYwO1xuICBvdXRbMl0gPSBhMiAqIHYxO1xuICBvdXRbM10gPSBhMyAqIHYxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgbWF0cml4IGZyb20gYSBnaXZlbiBhbmdsZVxuICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIChidXQgbXVjaCBmYXN0ZXIgdGhhbik6XG4gKlxuICogICAgIG1hdDIuaWRlbnRpdHkoZGVzdCk7XG4gKiAgICAgbWF0Mi5yb3RhdGUoZGVzdCwgZGVzdCwgcmFkKTtcbiAqXG4gKiBAcGFyYW0ge21hdDJ9IG91dCBtYXQyIHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIHRoZSBhbmdsZSB0byByb3RhdGUgdGhlIG1hdHJpeCBieVxuICogQHJldHVybnMge21hdDJ9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9tUm90YXRpb24ob3V0LCByYWQpIHtcbiAgdmFyIHMgPSBNYXRoLnNpbihyYWQpO1xuICB2YXIgYyA9IE1hdGguY29zKHJhZCk7XG4gIG91dFswXSA9IGM7XG4gIG91dFsxXSA9IHM7XG4gIG91dFsyXSA9IC1zO1xuICBvdXRbM10gPSBjO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgbWF0cml4IGZyb20gYSB2ZWN0b3Igc2NhbGluZ1xuICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIChidXQgbXVjaCBmYXN0ZXIgdGhhbik6XG4gKlxuICogICAgIG1hdDIuaWRlbnRpdHkoZGVzdCk7XG4gKiAgICAgbWF0Mi5zY2FsZShkZXN0LCBkZXN0LCB2ZWMpO1xuICpcbiAqIEBwYXJhbSB7bWF0Mn0gb3V0IG1hdDIgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSB2IFNjYWxpbmcgdmVjdG9yXG4gKiBAcmV0dXJucyB7bWF0Mn0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21TY2FsaW5nKG91dCwgdikge1xuICBvdXRbMF0gPSB2WzBdO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSB2WzFdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgbWF0MlxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyfSBhIG1hdHJpeCB0byByZXByZXNlbnQgYXMgYSBzdHJpbmdcbiAqIEByZXR1cm5zIHtTdHJpbmd9IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgbWF0cml4XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHN0cihhKSB7XG4gIHJldHVybiBcIm1hdDIoXCIgKyBhWzBdICsgXCIsIFwiICsgYVsxXSArIFwiLCBcIiArIGFbMl0gKyBcIiwgXCIgKyBhWzNdICsgXCIpXCI7XG59XG4vKipcbiAqIFJldHVybnMgRnJvYmVuaXVzIG5vcm0gb2YgYSBtYXQyXG4gKlxuICogQHBhcmFtIHtSZWFkb25seU1hdDJ9IGEgdGhlIG1hdHJpeCB0byBjYWxjdWxhdGUgRnJvYmVuaXVzIG5vcm0gb2ZcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IEZyb2Jlbml1cyBub3JtXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb2IoYSkge1xuICByZXR1cm4gTWF0aC5oeXBvdChhWzBdLCBhWzFdLCBhWzJdLCBhWzNdKTtcbn1cbi8qKlxuICogUmV0dXJucyBMLCBEIGFuZCBVIG1hdHJpY2VzIChMb3dlciB0cmlhbmd1bGFyLCBEaWFnb25hbCBhbmQgVXBwZXIgdHJpYW5ndWxhcikgYnkgZmFjdG9yaXppbmcgdGhlIGlucHV0IG1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seU1hdDJ9IEwgdGhlIGxvd2VyIHRyaWFuZ3VsYXIgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0Mn0gRCB0aGUgZGlhZ29uYWwgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0Mn0gVSB0aGUgdXBwZXIgdHJpYW5ndWxhciBtYXRyaXhcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyfSBhIHRoZSBpbnB1dCBtYXRyaXggdG8gZmFjdG9yaXplXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIExEVShMLCBELCBVLCBhKSB7XG4gIExbMl0gPSBhWzJdIC8gYVswXTtcbiAgVVswXSA9IGFbMF07XG4gIFVbMV0gPSBhWzFdO1xuICBVWzNdID0gYVszXSAtIExbMl0gKiBVWzFdO1xuICByZXR1cm4gW0wsIEQsIFVdO1xufVxuLyoqXG4gKiBBZGRzIHR3byBtYXQyJ3NcbiAqXG4gKiBAcGFyYW0ge21hdDJ9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seU1hdDJ9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge21hdDJ9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhZGQob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IGFbMF0gKyBiWzBdO1xuICBvdXRbMV0gPSBhWzFdICsgYlsxXTtcbiAgb3V0WzJdID0gYVsyXSArIGJbMl07XG4gIG91dFszXSA9IGFbM10gKyBiWzNdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBTdWJ0cmFjdHMgbWF0cml4IGIgZnJvbSBtYXRyaXggYVxuICpcbiAqIEBwYXJhbSB7bWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0Mn0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seU1hdDJ9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7bWF0Mn0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHN1YnRyYWN0KG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdIC0gYlswXTtcbiAgb3V0WzFdID0gYVsxXSAtIGJbMV07XG4gIG91dFsyXSA9IGFbMl0gLSBiWzJdO1xuICBvdXRbM10gPSBhWzNdIC0gYlszXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgbWF0cmljZXMgaGF2ZSBleGFjdGx5IHRoZSBzYW1lIGVsZW1lbnRzIGluIHRoZSBzYW1lIHBvc2l0aW9uICh3aGVuIGNvbXBhcmVkIHdpdGggPT09KVxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyfSBhIFRoZSBmaXJzdCBtYXRyaXguXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0Mn0gYiBUaGUgc2Vjb25kIG1hdHJpeC5cbiAqIEByZXR1cm5zIHtCb29sZWFufSBUcnVlIGlmIHRoZSBtYXRyaWNlcyBhcmUgZXF1YWwsIGZhbHNlIG90aGVyd2lzZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXhhY3RFcXVhbHMoYSwgYikge1xuICByZXR1cm4gYVswXSA9PT0gYlswXSAmJiBhWzFdID09PSBiWzFdICYmIGFbMl0gPT09IGJbMl0gJiYgYVszXSA9PT0gYlszXTtcbn1cbi8qKlxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgbWF0cmljZXMgaGF2ZSBhcHByb3hpbWF0ZWx5IHRoZSBzYW1lIGVsZW1lbnRzIGluIHRoZSBzYW1lIHBvc2l0aW9uLlxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyfSBhIFRoZSBmaXJzdCBtYXRyaXguXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0Mn0gYiBUaGUgc2Vjb25kIG1hdHJpeC5cbiAqIEByZXR1cm5zIHtCb29sZWFufSBUcnVlIGlmIHRoZSBtYXRyaWNlcyBhcmUgZXF1YWwsIGZhbHNlIG90aGVyd2lzZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXF1YWxzKGEsIGIpIHtcbiAgdmFyIGEwID0gYVswXSxcbiAgICAgIGExID0gYVsxXSxcbiAgICAgIGEyID0gYVsyXSxcbiAgICAgIGEzID0gYVszXTtcbiAgdmFyIGIwID0gYlswXSxcbiAgICAgIGIxID0gYlsxXSxcbiAgICAgIGIyID0gYlsyXSxcbiAgICAgIGIzID0gYlszXTtcbiAgcmV0dXJuIE1hdGguYWJzKGEwIC0gYjApIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGEwKSwgTWF0aC5hYnMoYjApKSAmJiBNYXRoLmFicyhhMSAtIGIxKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMSksIE1hdGguYWJzKGIxKSkgJiYgTWF0aC5hYnMoYTIgLSBiMikgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTIpLCBNYXRoLmFicyhiMikpICYmIE1hdGguYWJzKGEzIC0gYjMpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGEzKSwgTWF0aC5hYnMoYjMpKTtcbn1cbi8qKlxuICogTXVsdGlwbHkgZWFjaCBlbGVtZW50IG9mIHRoZSBtYXRyaXggYnkgYSBzY2FsYXIuXG4gKlxuICogQHBhcmFtIHttYXQyfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyfSBhIHRoZSBtYXRyaXggdG8gc2NhbGVcbiAqIEBwYXJhbSB7TnVtYmVyfSBiIGFtb3VudCB0byBzY2FsZSB0aGUgbWF0cml4J3MgZWxlbWVudHMgYnlcbiAqIEByZXR1cm5zIHttYXQyfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbXVsdGlwbHlTY2FsYXIob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IGFbMF0gKiBiO1xuICBvdXRbMV0gPSBhWzFdICogYjtcbiAgb3V0WzJdID0gYVsyXSAqIGI7XG4gIG91dFszXSA9IGFbM10gKiBiO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBBZGRzIHR3byBtYXQyJ3MgYWZ0ZXIgbXVsdGlwbHlpbmcgZWFjaCBlbGVtZW50IG9mIHRoZSBzZWNvbmQgb3BlcmFuZCBieSBhIHNjYWxhciB2YWx1ZS5cbiAqXG4gKiBAcGFyYW0ge21hdDJ9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seU1hdDJ9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHBhcmFtIHtOdW1iZXJ9IHNjYWxlIHRoZSBhbW91bnQgdG8gc2NhbGUgYidzIGVsZW1lbnRzIGJ5IGJlZm9yZSBhZGRpbmdcbiAqIEByZXR1cm5zIHttYXQyfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbXVsdGlwbHlTY2FsYXJBbmRBZGQob3V0LCBhLCBiLCBzY2FsZSkge1xuICBvdXRbMF0gPSBhWzBdICsgYlswXSAqIHNjYWxlO1xuICBvdXRbMV0gPSBhWzFdICsgYlsxXSAqIHNjYWxlO1xuICBvdXRbMl0gPSBhWzJdICsgYlsyXSAqIHNjYWxlO1xuICBvdXRbM10gPSBhWzNdICsgYlszXSAqIHNjYWxlO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIG1hdDIubXVsdGlwbHl9XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIG11bCA9IG11bHRpcGx5O1xuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIG1hdDIuc3VidHJhY3R9XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIHN1YiA9IHN1YnRyYWN0OyIsImltcG9ydCAqIGFzIGdsTWF0cml4IGZyb20gXCIuL2NvbW1vbi5qc1wiO1xuLyoqXG4gKiAyeDMgTWF0cml4XG4gKiBAbW9kdWxlIG1hdDJkXG4gKiBAZGVzY3JpcHRpb25cbiAqIEEgbWF0MmQgY29udGFpbnMgc2l4IGVsZW1lbnRzIGRlZmluZWQgYXM6XG4gKiA8cHJlPlxuICogW2EsIGIsXG4gKiAgYywgZCxcbiAqICB0eCwgdHldXG4gKiA8L3ByZT5cbiAqIFRoaXMgaXMgYSBzaG9ydCBmb3JtIGZvciB0aGUgM3gzIG1hdHJpeDpcbiAqIDxwcmU+XG4gKiBbYSwgYiwgMCxcbiAqICBjLCBkLCAwLFxuICogIHR4LCB0eSwgMV1cbiAqIDwvcHJlPlxuICogVGhlIGxhc3QgY29sdW1uIGlzIGlnbm9yZWQgc28gdGhlIGFycmF5IGlzIHNob3J0ZXIgYW5kIG9wZXJhdGlvbnMgYXJlIGZhc3Rlci5cbiAqL1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgaWRlbnRpdHkgbWF0MmRcbiAqXG4gKiBAcmV0dXJucyB7bWF0MmR9IGEgbmV3IDJ4MyBtYXRyaXhcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlKCkge1xuICB2YXIgb3V0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoNik7XG5cbiAgaWYgKGdsTWF0cml4LkFSUkFZX1RZUEUgIT0gRmxvYXQzMkFycmF5KSB7XG4gICAgb3V0WzFdID0gMDtcbiAgICBvdXRbMl0gPSAwO1xuICAgIG91dFs0XSA9IDA7XG4gICAgb3V0WzVdID0gMDtcbiAgfVxuXG4gIG91dFswXSA9IDE7XG4gIG91dFszXSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgbWF0MmQgaW5pdGlhbGl6ZWQgd2l0aCB2YWx1ZXMgZnJvbSBhbiBleGlzdGluZyBtYXRyaXhcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0MmR9IGEgbWF0cml4IHRvIGNsb25lXG4gKiBAcmV0dXJucyB7bWF0MmR9IGEgbmV3IDJ4MyBtYXRyaXhcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY2xvbmUoYSkge1xuICB2YXIgb3V0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoNik7XG4gIG91dFswXSA9IGFbMF07XG4gIG91dFsxXSA9IGFbMV07XG4gIG91dFsyXSA9IGFbMl07XG4gIG91dFszXSA9IGFbM107XG4gIG91dFs0XSA9IGFbNF07XG4gIG91dFs1XSA9IGFbNV07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENvcHkgdGhlIHZhbHVlcyBmcm9tIG9uZSBtYXQyZCB0byBhbm90aGVyXG4gKlxuICogQHBhcmFtIHttYXQyZH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0MmR9IGEgdGhlIHNvdXJjZSBtYXRyaXhcbiAqIEByZXR1cm5zIHttYXQyZH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNvcHkob3V0LCBhKSB7XG4gIG91dFswXSA9IGFbMF07XG4gIG91dFsxXSA9IGFbMV07XG4gIG91dFsyXSA9IGFbMl07XG4gIG91dFszXSA9IGFbM107XG4gIG91dFs0XSA9IGFbNF07XG4gIG91dFs1XSA9IGFbNV07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFNldCBhIG1hdDJkIHRvIHRoZSBpZGVudGl0eSBtYXRyaXhcbiAqXG4gKiBAcGFyYW0ge21hdDJkfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEByZXR1cm5zIHttYXQyZH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGlkZW50aXR5KG91dCkge1xuICBvdXRbMF0gPSAxO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAxO1xuICBvdXRbNF0gPSAwO1xuICBvdXRbNV0gPSAwO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgbWF0MmQgd2l0aCB0aGUgZ2l2ZW4gdmFsdWVzXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IGEgQ29tcG9uZW50IEEgKGluZGV4IDApXG4gKiBAcGFyYW0ge051bWJlcn0gYiBDb21wb25lbnQgQiAoaW5kZXggMSlcbiAqIEBwYXJhbSB7TnVtYmVyfSBjIENvbXBvbmVudCBDIChpbmRleCAyKVxuICogQHBhcmFtIHtOdW1iZXJ9IGQgQ29tcG9uZW50IEQgKGluZGV4IDMpXG4gKiBAcGFyYW0ge051bWJlcn0gdHggQ29tcG9uZW50IFRYIChpbmRleCA0KVxuICogQHBhcmFtIHtOdW1iZXJ9IHR5IENvbXBvbmVudCBUWSAoaW5kZXggNSlcbiAqIEByZXR1cm5zIHttYXQyZH0gQSBuZXcgbWF0MmRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbVZhbHVlcyhhLCBiLCBjLCBkLCB0eCwgdHkpIHtcbiAgdmFyIG91dCA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDYpO1xuICBvdXRbMF0gPSBhO1xuICBvdXRbMV0gPSBiO1xuICBvdXRbMl0gPSBjO1xuICBvdXRbM10gPSBkO1xuICBvdXRbNF0gPSB0eDtcbiAgb3V0WzVdID0gdHk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFNldCB0aGUgY29tcG9uZW50cyBvZiBhIG1hdDJkIHRvIHRoZSBnaXZlbiB2YWx1ZXNcbiAqXG4gKiBAcGFyYW0ge21hdDJkfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7TnVtYmVyfSBhIENvbXBvbmVudCBBIChpbmRleCAwKVxuICogQHBhcmFtIHtOdW1iZXJ9IGIgQ29tcG9uZW50IEIgKGluZGV4IDEpXG4gKiBAcGFyYW0ge051bWJlcn0gYyBDb21wb25lbnQgQyAoaW5kZXggMilcbiAqIEBwYXJhbSB7TnVtYmVyfSBkIENvbXBvbmVudCBEIChpbmRleCAzKVxuICogQHBhcmFtIHtOdW1iZXJ9IHR4IENvbXBvbmVudCBUWCAoaW5kZXggNClcbiAqIEBwYXJhbSB7TnVtYmVyfSB0eSBDb21wb25lbnQgVFkgKGluZGV4IDUpXG4gKiBAcmV0dXJucyB7bWF0MmR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzZXQob3V0LCBhLCBiLCBjLCBkLCB0eCwgdHkpIHtcbiAgb3V0WzBdID0gYTtcbiAgb3V0WzFdID0gYjtcbiAgb3V0WzJdID0gYztcbiAgb3V0WzNdID0gZDtcbiAgb3V0WzRdID0gdHg7XG4gIG91dFs1XSA9IHR5O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBJbnZlcnRzIGEgbWF0MmRcbiAqXG4gKiBAcGFyYW0ge21hdDJkfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyZH0gYSB0aGUgc291cmNlIG1hdHJpeFxuICogQHJldHVybnMge21hdDJkfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaW52ZXJ0KG91dCwgYSkge1xuICB2YXIgYWEgPSBhWzBdLFxuICAgICAgYWIgPSBhWzFdLFxuICAgICAgYWMgPSBhWzJdLFxuICAgICAgYWQgPSBhWzNdO1xuICB2YXIgYXR4ID0gYVs0XSxcbiAgICAgIGF0eSA9IGFbNV07XG4gIHZhciBkZXQgPSBhYSAqIGFkIC0gYWIgKiBhYztcblxuICBpZiAoIWRldCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZGV0ID0gMS4wIC8gZGV0O1xuICBvdXRbMF0gPSBhZCAqIGRldDtcbiAgb3V0WzFdID0gLWFiICogZGV0O1xuICBvdXRbMl0gPSAtYWMgKiBkZXQ7XG4gIG91dFszXSA9IGFhICogZGV0O1xuICBvdXRbNF0gPSAoYWMgKiBhdHkgLSBhZCAqIGF0eCkgKiBkZXQ7XG4gIG91dFs1XSA9IChhYiAqIGF0eCAtIGFhICogYXR5KSAqIGRldDtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgZGV0ZXJtaW5hbnQgb2YgYSBtYXQyZFxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyZH0gYSB0aGUgc291cmNlIG1hdHJpeFxuICogQHJldHVybnMge051bWJlcn0gZGV0ZXJtaW5hbnQgb2YgYVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBkZXRlcm1pbmFudChhKSB7XG4gIHJldHVybiBhWzBdICogYVszXSAtIGFbMV0gKiBhWzJdO1xufVxuLyoqXG4gKiBNdWx0aXBsaWVzIHR3byBtYXQyZCdzXG4gKlxuICogQHBhcmFtIHttYXQyZH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0MmR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyZH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHttYXQyZH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG11bHRpcGx5KG91dCwgYSwgYikge1xuICB2YXIgYTAgPSBhWzBdLFxuICAgICAgYTEgPSBhWzFdLFxuICAgICAgYTIgPSBhWzJdLFxuICAgICAgYTMgPSBhWzNdLFxuICAgICAgYTQgPSBhWzRdLFxuICAgICAgYTUgPSBhWzVdO1xuICB2YXIgYjAgPSBiWzBdLFxuICAgICAgYjEgPSBiWzFdLFxuICAgICAgYjIgPSBiWzJdLFxuICAgICAgYjMgPSBiWzNdLFxuICAgICAgYjQgPSBiWzRdLFxuICAgICAgYjUgPSBiWzVdO1xuICBvdXRbMF0gPSBhMCAqIGIwICsgYTIgKiBiMTtcbiAgb3V0WzFdID0gYTEgKiBiMCArIGEzICogYjE7XG4gIG91dFsyXSA9IGEwICogYjIgKyBhMiAqIGIzO1xuICBvdXRbM10gPSBhMSAqIGIyICsgYTMgKiBiMztcbiAgb3V0WzRdID0gYTAgKiBiNCArIGEyICogYjUgKyBhNDtcbiAgb3V0WzVdID0gYTEgKiBiNCArIGEzICogYjUgKyBhNTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUm90YXRlcyBhIG1hdDJkIGJ5IHRoZSBnaXZlbiBhbmdsZVxuICpcbiAqIEBwYXJhbSB7bWF0MmR9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seU1hdDJkfSBhIHRoZSBtYXRyaXggdG8gcm90YXRlXG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIHRoZSBhbmdsZSB0byByb3RhdGUgdGhlIG1hdHJpeCBieVxuICogQHJldHVybnMge21hdDJkfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcm90YXRlKG91dCwgYSwgcmFkKSB7XG4gIHZhciBhMCA9IGFbMF0sXG4gICAgICBhMSA9IGFbMV0sXG4gICAgICBhMiA9IGFbMl0sXG4gICAgICBhMyA9IGFbM10sXG4gICAgICBhNCA9IGFbNF0sXG4gICAgICBhNSA9IGFbNV07XG4gIHZhciBzID0gTWF0aC5zaW4ocmFkKTtcbiAgdmFyIGMgPSBNYXRoLmNvcyhyYWQpO1xuICBvdXRbMF0gPSBhMCAqIGMgKyBhMiAqIHM7XG4gIG91dFsxXSA9IGExICogYyArIGEzICogcztcbiAgb3V0WzJdID0gYTAgKiAtcyArIGEyICogYztcbiAgb3V0WzNdID0gYTEgKiAtcyArIGEzICogYztcbiAgb3V0WzRdID0gYTQ7XG4gIG91dFs1XSA9IGE1O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBTY2FsZXMgdGhlIG1hdDJkIGJ5IHRoZSBkaW1lbnNpb25zIGluIHRoZSBnaXZlbiB2ZWMyXG4gKlxuICogQHBhcmFtIHttYXQyZH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0MmR9IGEgdGhlIG1hdHJpeCB0byB0cmFuc2xhdGVcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSB2IHRoZSB2ZWMyIHRvIHNjYWxlIHRoZSBtYXRyaXggYnlcbiAqIEByZXR1cm5zIHttYXQyZH0gb3V0XG4gKiovXG5cbmV4cG9ydCBmdW5jdGlvbiBzY2FsZShvdXQsIGEsIHYpIHtcbiAgdmFyIGEwID0gYVswXSxcbiAgICAgIGExID0gYVsxXSxcbiAgICAgIGEyID0gYVsyXSxcbiAgICAgIGEzID0gYVszXSxcbiAgICAgIGE0ID0gYVs0XSxcbiAgICAgIGE1ID0gYVs1XTtcbiAgdmFyIHYwID0gdlswXSxcbiAgICAgIHYxID0gdlsxXTtcbiAgb3V0WzBdID0gYTAgKiB2MDtcbiAgb3V0WzFdID0gYTEgKiB2MDtcbiAgb3V0WzJdID0gYTIgKiB2MTtcbiAgb3V0WzNdID0gYTMgKiB2MTtcbiAgb3V0WzRdID0gYTQ7XG4gIG91dFs1XSA9IGE1O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBUcmFuc2xhdGVzIHRoZSBtYXQyZCBieSB0aGUgZGltZW5zaW9ucyBpbiB0aGUgZ2l2ZW4gdmVjMlxuICpcbiAqIEBwYXJhbSB7bWF0MmR9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seU1hdDJkfSBhIHRoZSBtYXRyaXggdG8gdHJhbnNsYXRlXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gdiB0aGUgdmVjMiB0byB0cmFuc2xhdGUgdGhlIG1hdHJpeCBieVxuICogQHJldHVybnMge21hdDJkfSBvdXRcbiAqKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zbGF0ZShvdXQsIGEsIHYpIHtcbiAgdmFyIGEwID0gYVswXSxcbiAgICAgIGExID0gYVsxXSxcbiAgICAgIGEyID0gYVsyXSxcbiAgICAgIGEzID0gYVszXSxcbiAgICAgIGE0ID0gYVs0XSxcbiAgICAgIGE1ID0gYVs1XTtcbiAgdmFyIHYwID0gdlswXSxcbiAgICAgIHYxID0gdlsxXTtcbiAgb3V0WzBdID0gYTA7XG4gIG91dFsxXSA9IGExO1xuICBvdXRbMl0gPSBhMjtcbiAgb3V0WzNdID0gYTM7XG4gIG91dFs0XSA9IGEwICogdjAgKyBhMiAqIHYxICsgYTQ7XG4gIG91dFs1XSA9IGExICogdjAgKyBhMyAqIHYxICsgYTU7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENyZWF0ZXMgYSBtYXRyaXggZnJvbSBhIGdpdmVuIGFuZ2xlXG4gKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gKGJ1dCBtdWNoIGZhc3RlciB0aGFuKTpcbiAqXG4gKiAgICAgbWF0MmQuaWRlbnRpdHkoZGVzdCk7XG4gKiAgICAgbWF0MmQucm90YXRlKGRlc3QsIGRlc3QsIHJhZCk7XG4gKlxuICogQHBhcmFtIHttYXQyZH0gb3V0IG1hdDJkIHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIHRoZSBhbmdsZSB0byByb3RhdGUgdGhlIG1hdHJpeCBieVxuICogQHJldHVybnMge21hdDJkfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbVJvdGF0aW9uKG91dCwgcmFkKSB7XG4gIHZhciBzID0gTWF0aC5zaW4ocmFkKSxcbiAgICAgIGMgPSBNYXRoLmNvcyhyYWQpO1xuICBvdXRbMF0gPSBjO1xuICBvdXRbMV0gPSBzO1xuICBvdXRbMl0gPSAtcztcbiAgb3V0WzNdID0gYztcbiAgb3V0WzRdID0gMDtcbiAgb3V0WzVdID0gMDtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIG1hdHJpeCBmcm9tIGEgdmVjdG9yIHNjYWxpbmdcbiAqIFRoaXMgaXMgZXF1aXZhbGVudCB0byAoYnV0IG11Y2ggZmFzdGVyIHRoYW4pOlxuICpcbiAqICAgICBtYXQyZC5pZGVudGl0eShkZXN0KTtcbiAqICAgICBtYXQyZC5zY2FsZShkZXN0LCBkZXN0LCB2ZWMpO1xuICpcbiAqIEBwYXJhbSB7bWF0MmR9IG91dCBtYXQyZCByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IHYgU2NhbGluZyB2ZWN0b3JcbiAqIEByZXR1cm5zIHttYXQyZH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21TY2FsaW5nKG91dCwgdikge1xuICBvdXRbMF0gPSB2WzBdO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSB2WzFdO1xuICBvdXRbNF0gPSAwO1xuICBvdXRbNV0gPSAwO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgbWF0cml4IGZyb20gYSB2ZWN0b3IgdHJhbnNsYXRpb25cbiAqIFRoaXMgaXMgZXF1aXZhbGVudCB0byAoYnV0IG11Y2ggZmFzdGVyIHRoYW4pOlxuICpcbiAqICAgICBtYXQyZC5pZGVudGl0eShkZXN0KTtcbiAqICAgICBtYXQyZC50cmFuc2xhdGUoZGVzdCwgZGVzdCwgdmVjKTtcbiAqXG4gKiBAcGFyYW0ge21hdDJkfSBvdXQgbWF0MmQgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSB2IFRyYW5zbGF0aW9uIHZlY3RvclxuICogQHJldHVybnMge21hdDJkfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbVRyYW5zbGF0aW9uKG91dCwgdikge1xuICBvdXRbMF0gPSAxO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAxO1xuICBvdXRbNF0gPSB2WzBdO1xuICBvdXRbNV0gPSB2WzFdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgbWF0MmRcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0MmR9IGEgbWF0cml4IHRvIHJlcHJlc2VudCBhcyBhIHN0cmluZ1xuICogQHJldHVybnMge1N0cmluZ30gc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtYXRyaXhcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc3RyKGEpIHtcbiAgcmV0dXJuIFwibWF0MmQoXCIgKyBhWzBdICsgXCIsIFwiICsgYVsxXSArIFwiLCBcIiArIGFbMl0gKyBcIiwgXCIgKyBhWzNdICsgXCIsIFwiICsgYVs0XSArIFwiLCBcIiArIGFbNV0gKyBcIilcIjtcbn1cbi8qKlxuICogUmV0dXJucyBGcm9iZW5pdXMgbm9ybSBvZiBhIG1hdDJkXG4gKlxuICogQHBhcmFtIHtSZWFkb25seU1hdDJkfSBhIHRoZSBtYXRyaXggdG8gY2FsY3VsYXRlIEZyb2Jlbml1cyBub3JtIG9mXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBGcm9iZW5pdXMgbm9ybVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9iKGEpIHtcbiAgcmV0dXJuIE1hdGguaHlwb3QoYVswXSwgYVsxXSwgYVsyXSwgYVszXSwgYVs0XSwgYVs1XSwgMSk7XG59XG4vKipcbiAqIEFkZHMgdHdvIG1hdDJkJ3NcbiAqXG4gKiBAcGFyYW0ge21hdDJkfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyZH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seU1hdDJkfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge21hdDJkfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYWRkKG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdICsgYlswXTtcbiAgb3V0WzFdID0gYVsxXSArIGJbMV07XG4gIG91dFsyXSA9IGFbMl0gKyBiWzJdO1xuICBvdXRbM10gPSBhWzNdICsgYlszXTtcbiAgb3V0WzRdID0gYVs0XSArIGJbNF07XG4gIG91dFs1XSA9IGFbNV0gKyBiWzVdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBTdWJ0cmFjdHMgbWF0cml4IGIgZnJvbSBtYXRyaXggYVxuICpcbiAqIEBwYXJhbSB7bWF0MmR9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seU1hdDJkfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0MmR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7bWF0MmR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzdWJ0cmFjdChvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gYVswXSAtIGJbMF07XG4gIG91dFsxXSA9IGFbMV0gLSBiWzFdO1xuICBvdXRbMl0gPSBhWzJdIC0gYlsyXTtcbiAgb3V0WzNdID0gYVszXSAtIGJbM107XG4gIG91dFs0XSA9IGFbNF0gLSBiWzRdO1xuICBvdXRbNV0gPSBhWzVdIC0gYls1XTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogTXVsdGlwbHkgZWFjaCBlbGVtZW50IG9mIHRoZSBtYXRyaXggYnkgYSBzY2FsYXIuXG4gKlxuICogQHBhcmFtIHttYXQyZH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0MmR9IGEgdGhlIG1hdHJpeCB0byBzY2FsZVxuICogQHBhcmFtIHtOdW1iZXJ9IGIgYW1vdW50IHRvIHNjYWxlIHRoZSBtYXRyaXgncyBlbGVtZW50cyBieVxuICogQHJldHVybnMge21hdDJkfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbXVsdGlwbHlTY2FsYXIob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IGFbMF0gKiBiO1xuICBvdXRbMV0gPSBhWzFdICogYjtcbiAgb3V0WzJdID0gYVsyXSAqIGI7XG4gIG91dFszXSA9IGFbM10gKiBiO1xuICBvdXRbNF0gPSBhWzRdICogYjtcbiAgb3V0WzVdID0gYVs1XSAqIGI7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIEFkZHMgdHdvIG1hdDJkJ3MgYWZ0ZXIgbXVsdGlwbHlpbmcgZWFjaCBlbGVtZW50IG9mIHRoZSBzZWNvbmQgb3BlcmFuZCBieSBhIHNjYWxhciB2YWx1ZS5cbiAqXG4gKiBAcGFyYW0ge21hdDJkfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyZH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seU1hdDJkfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHBhcmFtIHtOdW1iZXJ9IHNjYWxlIHRoZSBhbW91bnQgdG8gc2NhbGUgYidzIGVsZW1lbnRzIGJ5IGJlZm9yZSBhZGRpbmdcbiAqIEByZXR1cm5zIHttYXQyZH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG11bHRpcGx5U2NhbGFyQW5kQWRkKG91dCwgYSwgYiwgc2NhbGUpIHtcbiAgb3V0WzBdID0gYVswXSArIGJbMF0gKiBzY2FsZTtcbiAgb3V0WzFdID0gYVsxXSArIGJbMV0gKiBzY2FsZTtcbiAgb3V0WzJdID0gYVsyXSArIGJbMl0gKiBzY2FsZTtcbiAgb3V0WzNdID0gYVszXSArIGJbM10gKiBzY2FsZTtcbiAgb3V0WzRdID0gYVs0XSArIGJbNF0gKiBzY2FsZTtcbiAgb3V0WzVdID0gYVs1XSArIGJbNV0gKiBzY2FsZTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgbWF0cmljZXMgaGF2ZSBleGFjdGx5IHRoZSBzYW1lIGVsZW1lbnRzIGluIHRoZSBzYW1lIHBvc2l0aW9uICh3aGVuIGNvbXBhcmVkIHdpdGggPT09KVxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyZH0gYSBUaGUgZmlyc3QgbWF0cml4LlxuICogQHBhcmFtIHtSZWFkb25seU1hdDJkfSBiIFRoZSBzZWNvbmQgbWF0cml4LlxuICogQHJldHVybnMge0Jvb2xlYW59IFRydWUgaWYgdGhlIG1hdHJpY2VzIGFyZSBlcXVhbCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBleGFjdEVxdWFscyhhLCBiKSB7XG4gIHJldHVybiBhWzBdID09PSBiWzBdICYmIGFbMV0gPT09IGJbMV0gJiYgYVsyXSA9PT0gYlsyXSAmJiBhWzNdID09PSBiWzNdICYmIGFbNF0gPT09IGJbNF0gJiYgYVs1XSA9PT0gYls1XTtcbn1cbi8qKlxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgbWF0cmljZXMgaGF2ZSBhcHByb3hpbWF0ZWx5IHRoZSBzYW1lIGVsZW1lbnRzIGluIHRoZSBzYW1lIHBvc2l0aW9uLlxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyZH0gYSBUaGUgZmlyc3QgbWF0cml4LlxuICogQHBhcmFtIHtSZWFkb25seU1hdDJkfSBiIFRoZSBzZWNvbmQgbWF0cml4LlxuICogQHJldHVybnMge0Jvb2xlYW59IFRydWUgaWYgdGhlIG1hdHJpY2VzIGFyZSBlcXVhbCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBlcXVhbHMoYSwgYikge1xuICB2YXIgYTAgPSBhWzBdLFxuICAgICAgYTEgPSBhWzFdLFxuICAgICAgYTIgPSBhWzJdLFxuICAgICAgYTMgPSBhWzNdLFxuICAgICAgYTQgPSBhWzRdLFxuICAgICAgYTUgPSBhWzVdO1xuICB2YXIgYjAgPSBiWzBdLFxuICAgICAgYjEgPSBiWzFdLFxuICAgICAgYjIgPSBiWzJdLFxuICAgICAgYjMgPSBiWzNdLFxuICAgICAgYjQgPSBiWzRdLFxuICAgICAgYjUgPSBiWzVdO1xuICByZXR1cm4gTWF0aC5hYnMoYTAgLSBiMCkgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTApLCBNYXRoLmFicyhiMCkpICYmIE1hdGguYWJzKGExIC0gYjEpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGExKSwgTWF0aC5hYnMoYjEpKSAmJiBNYXRoLmFicyhhMiAtIGIyKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMiksIE1hdGguYWJzKGIyKSkgJiYgTWF0aC5hYnMoYTMgLSBiMykgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTMpLCBNYXRoLmFicyhiMykpICYmIE1hdGguYWJzKGE0IC0gYjQpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGE0KSwgTWF0aC5hYnMoYjQpKSAmJiBNYXRoLmFicyhhNSAtIGI1KSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhNSksIE1hdGguYWJzKGI1KSk7XG59XG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgbWF0MmQubXVsdGlwbHl9XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIG11bCA9IG11bHRpcGx5O1xuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIG1hdDJkLnN1YnRyYWN0fVxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBzdWIgPSBzdWJ0cmFjdDsiLCJpbXBvcnQgKiBhcyBnbE1hdHJpeCBmcm9tIFwiLi9jb21tb24uanNcIjtcbi8qKlxuICogM3gzIE1hdHJpeFxuICogQG1vZHVsZSBtYXQzXG4gKi9cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGlkZW50aXR5IG1hdDNcbiAqXG4gKiBAcmV0dXJucyB7bWF0M30gYSBuZXcgM3gzIG1hdHJpeFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGUoKSB7XG4gIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSg5KTtcblxuICBpZiAoZ2xNYXRyaXguQVJSQVlfVFlQRSAhPSBGbG9hdDMyQXJyYXkpIHtcbiAgICBvdXRbMV0gPSAwO1xuICAgIG91dFsyXSA9IDA7XG4gICAgb3V0WzNdID0gMDtcbiAgICBvdXRbNV0gPSAwO1xuICAgIG91dFs2XSA9IDA7XG4gICAgb3V0WzddID0gMDtcbiAgfVxuXG4gIG91dFswXSA9IDE7XG4gIG91dFs0XSA9IDE7XG4gIG91dFs4XSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENvcGllcyB0aGUgdXBwZXItbGVmdCAzeDMgdmFsdWVzIGludG8gdGhlIGdpdmVuIG1hdDMuXG4gKlxuICogQHBhcmFtIHttYXQzfSBvdXQgdGhlIHJlY2VpdmluZyAzeDMgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYSAgIHRoZSBzb3VyY2UgNHg0IG1hdHJpeFxuICogQHJldHVybnMge21hdDN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9tTWF0NChvdXQsIGEpIHtcbiAgb3V0WzBdID0gYVswXTtcbiAgb3V0WzFdID0gYVsxXTtcbiAgb3V0WzJdID0gYVsyXTtcbiAgb3V0WzNdID0gYVs0XTtcbiAgb3V0WzRdID0gYVs1XTtcbiAgb3V0WzVdID0gYVs2XTtcbiAgb3V0WzZdID0gYVs4XTtcbiAgb3V0WzddID0gYVs5XTtcbiAgb3V0WzhdID0gYVsxMF07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgbWF0MyBpbml0aWFsaXplZCB3aXRoIHZhbHVlcyBmcm9tIGFuIGV4aXN0aW5nIG1hdHJpeFxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQzfSBhIG1hdHJpeCB0byBjbG9uZVxuICogQHJldHVybnMge21hdDN9IGEgbmV3IDN4MyBtYXRyaXhcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY2xvbmUoYSkge1xuICB2YXIgb3V0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoOSk7XG4gIG91dFswXSA9IGFbMF07XG4gIG91dFsxXSA9IGFbMV07XG4gIG91dFsyXSA9IGFbMl07XG4gIG91dFszXSA9IGFbM107XG4gIG91dFs0XSA9IGFbNF07XG4gIG91dFs1XSA9IGFbNV07XG4gIG91dFs2XSA9IGFbNl07XG4gIG91dFs3XSA9IGFbN107XG4gIG91dFs4XSA9IGFbOF07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENvcHkgdGhlIHZhbHVlcyBmcm9tIG9uZSBtYXQzIHRvIGFub3RoZXJcbiAqXG4gKiBAcGFyYW0ge21hdDN9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGEgdGhlIHNvdXJjZSBtYXRyaXhcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY29weShvdXQsIGEpIHtcbiAgb3V0WzBdID0gYVswXTtcbiAgb3V0WzFdID0gYVsxXTtcbiAgb3V0WzJdID0gYVsyXTtcbiAgb3V0WzNdID0gYVszXTtcbiAgb3V0WzRdID0gYVs0XTtcbiAgb3V0WzVdID0gYVs1XTtcbiAgb3V0WzZdID0gYVs2XTtcbiAgb3V0WzddID0gYVs3XTtcbiAgb3V0WzhdID0gYVs4XTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ3JlYXRlIGEgbmV3IG1hdDMgd2l0aCB0aGUgZ2l2ZW4gdmFsdWVzXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG0wMCBDb21wb25lbnQgaW4gY29sdW1uIDAsIHJvdyAwIHBvc2l0aW9uIChpbmRleCAwKVxuICogQHBhcmFtIHtOdW1iZXJ9IG0wMSBDb21wb25lbnQgaW4gY29sdW1uIDAsIHJvdyAxIHBvc2l0aW9uIChpbmRleCAxKVxuICogQHBhcmFtIHtOdW1iZXJ9IG0wMiBDb21wb25lbnQgaW4gY29sdW1uIDAsIHJvdyAyIHBvc2l0aW9uIChpbmRleCAyKVxuICogQHBhcmFtIHtOdW1iZXJ9IG0xMCBDb21wb25lbnQgaW4gY29sdW1uIDEsIHJvdyAwIHBvc2l0aW9uIChpbmRleCAzKVxuICogQHBhcmFtIHtOdW1iZXJ9IG0xMSBDb21wb25lbnQgaW4gY29sdW1uIDEsIHJvdyAxIHBvc2l0aW9uIChpbmRleCA0KVxuICogQHBhcmFtIHtOdW1iZXJ9IG0xMiBDb21wb25lbnQgaW4gY29sdW1uIDEsIHJvdyAyIHBvc2l0aW9uIChpbmRleCA1KVxuICogQHBhcmFtIHtOdW1iZXJ9IG0yMCBDb21wb25lbnQgaW4gY29sdW1uIDIsIHJvdyAwIHBvc2l0aW9uIChpbmRleCA2KVxuICogQHBhcmFtIHtOdW1iZXJ9IG0yMSBDb21wb25lbnQgaW4gY29sdW1uIDIsIHJvdyAxIHBvc2l0aW9uIChpbmRleCA3KVxuICogQHBhcmFtIHtOdW1iZXJ9IG0yMiBDb21wb25lbnQgaW4gY29sdW1uIDIsIHJvdyAyIHBvc2l0aW9uIChpbmRleCA4KVxuICogQHJldHVybnMge21hdDN9IEEgbmV3IG1hdDNcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbVZhbHVlcyhtMDAsIG0wMSwgbTAyLCBtMTAsIG0xMSwgbTEyLCBtMjAsIG0yMSwgbTIyKSB7XG4gIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSg5KTtcbiAgb3V0WzBdID0gbTAwO1xuICBvdXRbMV0gPSBtMDE7XG4gIG91dFsyXSA9IG0wMjtcbiAgb3V0WzNdID0gbTEwO1xuICBvdXRbNF0gPSBtMTE7XG4gIG91dFs1XSA9IG0xMjtcbiAgb3V0WzZdID0gbTIwO1xuICBvdXRbN10gPSBtMjE7XG4gIG91dFs4XSA9IG0yMjtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogU2V0IHRoZSBjb21wb25lbnRzIG9mIGEgbWF0MyB0byB0aGUgZ2l2ZW4gdmFsdWVzXG4gKlxuICogQHBhcmFtIHttYXQzfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMDAgQ29tcG9uZW50IGluIGNvbHVtbiAwLCByb3cgMCBwb3NpdGlvbiAoaW5kZXggMClcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMDEgQ29tcG9uZW50IGluIGNvbHVtbiAwLCByb3cgMSBwb3NpdGlvbiAoaW5kZXggMSlcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMDIgQ29tcG9uZW50IGluIGNvbHVtbiAwLCByb3cgMiBwb3NpdGlvbiAoaW5kZXggMilcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMTAgQ29tcG9uZW50IGluIGNvbHVtbiAxLCByb3cgMCBwb3NpdGlvbiAoaW5kZXggMylcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMTEgQ29tcG9uZW50IGluIGNvbHVtbiAxLCByb3cgMSBwb3NpdGlvbiAoaW5kZXggNClcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMTIgQ29tcG9uZW50IGluIGNvbHVtbiAxLCByb3cgMiBwb3NpdGlvbiAoaW5kZXggNSlcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMjAgQ29tcG9uZW50IGluIGNvbHVtbiAyLCByb3cgMCBwb3NpdGlvbiAoaW5kZXggNilcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMjEgQ29tcG9uZW50IGluIGNvbHVtbiAyLCByb3cgMSBwb3NpdGlvbiAoaW5kZXggNylcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMjIgQ29tcG9uZW50IGluIGNvbHVtbiAyLCByb3cgMiBwb3NpdGlvbiAoaW5kZXggOClcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc2V0KG91dCwgbTAwLCBtMDEsIG0wMiwgbTEwLCBtMTEsIG0xMiwgbTIwLCBtMjEsIG0yMikge1xuICBvdXRbMF0gPSBtMDA7XG4gIG91dFsxXSA9IG0wMTtcbiAgb3V0WzJdID0gbTAyO1xuICBvdXRbM10gPSBtMTA7XG4gIG91dFs0XSA9IG0xMTtcbiAgb3V0WzVdID0gbTEyO1xuICBvdXRbNl0gPSBtMjA7XG4gIG91dFs3XSA9IG0yMTtcbiAgb3V0WzhdID0gbTIyO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBTZXQgYSBtYXQzIHRvIHRoZSBpZGVudGl0eSBtYXRyaXhcbiAqXG4gKiBAcGFyYW0ge21hdDN9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHJldHVybnMge21hdDN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBpZGVudGl0eShvdXQpIHtcbiAgb3V0WzBdID0gMTtcbiAgb3V0WzFdID0gMDtcbiAgb3V0WzJdID0gMDtcbiAgb3V0WzNdID0gMDtcbiAgb3V0WzRdID0gMTtcbiAgb3V0WzVdID0gMDtcbiAgb3V0WzZdID0gMDtcbiAgb3V0WzddID0gMDtcbiAgb3V0WzhdID0gMTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogVHJhbnNwb3NlIHRoZSB2YWx1ZXMgb2YgYSBtYXQzXG4gKlxuICogQHBhcmFtIHttYXQzfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQzfSBhIHRoZSBzb3VyY2UgbWF0cml4XG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zcG9zZShvdXQsIGEpIHtcbiAgLy8gSWYgd2UgYXJlIHRyYW5zcG9zaW5nIG91cnNlbHZlcyB3ZSBjYW4gc2tpcCBhIGZldyBzdGVwcyBidXQgaGF2ZSB0byBjYWNoZSBzb21lIHZhbHVlc1xuICBpZiAob3V0ID09PSBhKSB7XG4gICAgdmFyIGEwMSA9IGFbMV0sXG4gICAgICAgIGEwMiA9IGFbMl0sXG4gICAgICAgIGExMiA9IGFbNV07XG4gICAgb3V0WzFdID0gYVszXTtcbiAgICBvdXRbMl0gPSBhWzZdO1xuICAgIG91dFszXSA9IGEwMTtcbiAgICBvdXRbNV0gPSBhWzddO1xuICAgIG91dFs2XSA9IGEwMjtcbiAgICBvdXRbN10gPSBhMTI7XG4gIH0gZWxzZSB7XG4gICAgb3V0WzBdID0gYVswXTtcbiAgICBvdXRbMV0gPSBhWzNdO1xuICAgIG91dFsyXSA9IGFbNl07XG4gICAgb3V0WzNdID0gYVsxXTtcbiAgICBvdXRbNF0gPSBhWzRdO1xuICAgIG91dFs1XSA9IGFbN107XG4gICAgb3V0WzZdID0gYVsyXTtcbiAgICBvdXRbN10gPSBhWzVdO1xuICAgIG91dFs4XSA9IGFbOF07XG4gIH1cblxuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBJbnZlcnRzIGEgbWF0M1xuICpcbiAqIEBwYXJhbSB7bWF0M30gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gYSB0aGUgc291cmNlIG1hdHJpeFxuICogQHJldHVybnMge21hdDN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBpbnZlcnQob3V0LCBhKSB7XG4gIHZhciBhMDAgPSBhWzBdLFxuICAgICAgYTAxID0gYVsxXSxcbiAgICAgIGEwMiA9IGFbMl07XG4gIHZhciBhMTAgPSBhWzNdLFxuICAgICAgYTExID0gYVs0XSxcbiAgICAgIGExMiA9IGFbNV07XG4gIHZhciBhMjAgPSBhWzZdLFxuICAgICAgYTIxID0gYVs3XSxcbiAgICAgIGEyMiA9IGFbOF07XG4gIHZhciBiMDEgPSBhMjIgKiBhMTEgLSBhMTIgKiBhMjE7XG4gIHZhciBiMTEgPSAtYTIyICogYTEwICsgYTEyICogYTIwO1xuICB2YXIgYjIxID0gYTIxICogYTEwIC0gYTExICogYTIwOyAvLyBDYWxjdWxhdGUgdGhlIGRldGVybWluYW50XG5cbiAgdmFyIGRldCA9IGEwMCAqIGIwMSArIGEwMSAqIGIxMSArIGEwMiAqIGIyMTtcblxuICBpZiAoIWRldCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZGV0ID0gMS4wIC8gZGV0O1xuICBvdXRbMF0gPSBiMDEgKiBkZXQ7XG4gIG91dFsxXSA9ICgtYTIyICogYTAxICsgYTAyICogYTIxKSAqIGRldDtcbiAgb3V0WzJdID0gKGExMiAqIGEwMSAtIGEwMiAqIGExMSkgKiBkZXQ7XG4gIG91dFszXSA9IGIxMSAqIGRldDtcbiAgb3V0WzRdID0gKGEyMiAqIGEwMCAtIGEwMiAqIGEyMCkgKiBkZXQ7XG4gIG91dFs1XSA9ICgtYTEyICogYTAwICsgYTAyICogYTEwKSAqIGRldDtcbiAgb3V0WzZdID0gYjIxICogZGV0O1xuICBvdXRbN10gPSAoLWEyMSAqIGEwMCArIGEwMSAqIGEyMCkgKiBkZXQ7XG4gIG91dFs4XSA9IChhMTEgKiBhMDAgLSBhMDEgKiBhMTApICogZGV0O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBhZGp1Z2F0ZSBvZiBhIG1hdDNcbiAqXG4gKiBAcGFyYW0ge21hdDN9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGEgdGhlIHNvdXJjZSBtYXRyaXhcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYWRqb2ludChvdXQsIGEpIHtcbiAgdmFyIGEwMCA9IGFbMF0sXG4gICAgICBhMDEgPSBhWzFdLFxuICAgICAgYTAyID0gYVsyXTtcbiAgdmFyIGExMCA9IGFbM10sXG4gICAgICBhMTEgPSBhWzRdLFxuICAgICAgYTEyID0gYVs1XTtcbiAgdmFyIGEyMCA9IGFbNl0sXG4gICAgICBhMjEgPSBhWzddLFxuICAgICAgYTIyID0gYVs4XTtcbiAgb3V0WzBdID0gYTExICogYTIyIC0gYTEyICogYTIxO1xuICBvdXRbMV0gPSBhMDIgKiBhMjEgLSBhMDEgKiBhMjI7XG4gIG91dFsyXSA9IGEwMSAqIGExMiAtIGEwMiAqIGExMTtcbiAgb3V0WzNdID0gYTEyICogYTIwIC0gYTEwICogYTIyO1xuICBvdXRbNF0gPSBhMDAgKiBhMjIgLSBhMDIgKiBhMjA7XG4gIG91dFs1XSA9IGEwMiAqIGExMCAtIGEwMCAqIGExMjtcbiAgb3V0WzZdID0gYTEwICogYTIxIC0gYTExICogYTIwO1xuICBvdXRbN10gPSBhMDEgKiBhMjAgLSBhMDAgKiBhMjE7XG4gIG91dFs4XSA9IGEwMCAqIGExMSAtIGEwMSAqIGExMDtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgZGV0ZXJtaW5hbnQgb2YgYSBtYXQzXG4gKlxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGEgdGhlIHNvdXJjZSBtYXRyaXhcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IGRldGVybWluYW50IG9mIGFcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZGV0ZXJtaW5hbnQoYSkge1xuICB2YXIgYTAwID0gYVswXSxcbiAgICAgIGEwMSA9IGFbMV0sXG4gICAgICBhMDIgPSBhWzJdO1xuICB2YXIgYTEwID0gYVszXSxcbiAgICAgIGExMSA9IGFbNF0sXG4gICAgICBhMTIgPSBhWzVdO1xuICB2YXIgYTIwID0gYVs2XSxcbiAgICAgIGEyMSA9IGFbN10sXG4gICAgICBhMjIgPSBhWzhdO1xuICByZXR1cm4gYTAwICogKGEyMiAqIGExMSAtIGExMiAqIGEyMSkgKyBhMDEgKiAoLWEyMiAqIGExMCArIGExMiAqIGEyMCkgKyBhMDIgKiAoYTIxICogYTEwIC0gYTExICogYTIwKTtcbn1cbi8qKlxuICogTXVsdGlwbGllcyB0d28gbWF0MydzXG4gKlxuICogQHBhcmFtIHttYXQzfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQzfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbXVsdGlwbHkob3V0LCBhLCBiKSB7XG4gIHZhciBhMDAgPSBhWzBdLFxuICAgICAgYTAxID0gYVsxXSxcbiAgICAgIGEwMiA9IGFbMl07XG4gIHZhciBhMTAgPSBhWzNdLFxuICAgICAgYTExID0gYVs0XSxcbiAgICAgIGExMiA9IGFbNV07XG4gIHZhciBhMjAgPSBhWzZdLFxuICAgICAgYTIxID0gYVs3XSxcbiAgICAgIGEyMiA9IGFbOF07XG4gIHZhciBiMDAgPSBiWzBdLFxuICAgICAgYjAxID0gYlsxXSxcbiAgICAgIGIwMiA9IGJbMl07XG4gIHZhciBiMTAgPSBiWzNdLFxuICAgICAgYjExID0gYls0XSxcbiAgICAgIGIxMiA9IGJbNV07XG4gIHZhciBiMjAgPSBiWzZdLFxuICAgICAgYjIxID0gYls3XSxcbiAgICAgIGIyMiA9IGJbOF07XG4gIG91dFswXSA9IGIwMCAqIGEwMCArIGIwMSAqIGExMCArIGIwMiAqIGEyMDtcbiAgb3V0WzFdID0gYjAwICogYTAxICsgYjAxICogYTExICsgYjAyICogYTIxO1xuICBvdXRbMl0gPSBiMDAgKiBhMDIgKyBiMDEgKiBhMTIgKyBiMDIgKiBhMjI7XG4gIG91dFszXSA9IGIxMCAqIGEwMCArIGIxMSAqIGExMCArIGIxMiAqIGEyMDtcbiAgb3V0WzRdID0gYjEwICogYTAxICsgYjExICogYTExICsgYjEyICogYTIxO1xuICBvdXRbNV0gPSBiMTAgKiBhMDIgKyBiMTEgKiBhMTIgKyBiMTIgKiBhMjI7XG4gIG91dFs2XSA9IGIyMCAqIGEwMCArIGIyMSAqIGExMCArIGIyMiAqIGEyMDtcbiAgb3V0WzddID0gYjIwICogYTAxICsgYjIxICogYTExICsgYjIyICogYTIxO1xuICBvdXRbOF0gPSBiMjAgKiBhMDIgKyBiMjEgKiBhMTIgKyBiMjIgKiBhMjI7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFRyYW5zbGF0ZSBhIG1hdDMgYnkgdGhlIGdpdmVuIHZlY3RvclxuICpcbiAqIEBwYXJhbSB7bWF0M30gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gYSB0aGUgbWF0cml4IHRvIHRyYW5zbGF0ZVxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IHYgdmVjdG9yIHRvIHRyYW5zbGF0ZSBieVxuICogQHJldHVybnMge21hdDN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2xhdGUob3V0LCBhLCB2KSB7XG4gIHZhciBhMDAgPSBhWzBdLFxuICAgICAgYTAxID0gYVsxXSxcbiAgICAgIGEwMiA9IGFbMl0sXG4gICAgICBhMTAgPSBhWzNdLFxuICAgICAgYTExID0gYVs0XSxcbiAgICAgIGExMiA9IGFbNV0sXG4gICAgICBhMjAgPSBhWzZdLFxuICAgICAgYTIxID0gYVs3XSxcbiAgICAgIGEyMiA9IGFbOF0sXG4gICAgICB4ID0gdlswXSxcbiAgICAgIHkgPSB2WzFdO1xuICBvdXRbMF0gPSBhMDA7XG4gIG91dFsxXSA9IGEwMTtcbiAgb3V0WzJdID0gYTAyO1xuICBvdXRbM10gPSBhMTA7XG4gIG91dFs0XSA9IGExMTtcbiAgb3V0WzVdID0gYTEyO1xuICBvdXRbNl0gPSB4ICogYTAwICsgeSAqIGExMCArIGEyMDtcbiAgb3V0WzddID0geCAqIGEwMSArIHkgKiBhMTEgKyBhMjE7XG4gIG91dFs4XSA9IHggKiBhMDIgKyB5ICogYTEyICsgYTIyO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBSb3RhdGVzIGEgbWF0MyBieSB0aGUgZ2l2ZW4gYW5nbGVcbiAqXG4gKiBAcGFyYW0ge21hdDN9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGEgdGhlIG1hdHJpeCB0byByb3RhdGVcbiAqIEBwYXJhbSB7TnVtYmVyfSByYWQgdGhlIGFuZ2xlIHRvIHJvdGF0ZSB0aGUgbWF0cml4IGJ5XG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJvdGF0ZShvdXQsIGEsIHJhZCkge1xuICB2YXIgYTAwID0gYVswXSxcbiAgICAgIGEwMSA9IGFbMV0sXG4gICAgICBhMDIgPSBhWzJdLFxuICAgICAgYTEwID0gYVszXSxcbiAgICAgIGExMSA9IGFbNF0sXG4gICAgICBhMTIgPSBhWzVdLFxuICAgICAgYTIwID0gYVs2XSxcbiAgICAgIGEyMSA9IGFbN10sXG4gICAgICBhMjIgPSBhWzhdLFxuICAgICAgcyA9IE1hdGguc2luKHJhZCksXG4gICAgICBjID0gTWF0aC5jb3MocmFkKTtcbiAgb3V0WzBdID0gYyAqIGEwMCArIHMgKiBhMTA7XG4gIG91dFsxXSA9IGMgKiBhMDEgKyBzICogYTExO1xuICBvdXRbMl0gPSBjICogYTAyICsgcyAqIGExMjtcbiAgb3V0WzNdID0gYyAqIGExMCAtIHMgKiBhMDA7XG4gIG91dFs0XSA9IGMgKiBhMTEgLSBzICogYTAxO1xuICBvdXRbNV0gPSBjICogYTEyIC0gcyAqIGEwMjtcbiAgb3V0WzZdID0gYTIwO1xuICBvdXRbN10gPSBhMjE7XG4gIG91dFs4XSA9IGEyMjtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogU2NhbGVzIHRoZSBtYXQzIGJ5IHRoZSBkaW1lbnNpb25zIGluIHRoZSBnaXZlbiB2ZWMyXG4gKlxuICogQHBhcmFtIHttYXQzfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQzfSBhIHRoZSBtYXRyaXggdG8gcm90YXRlXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gdiB0aGUgdmVjMiB0byBzY2FsZSB0aGUgbWF0cml4IGJ5XG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XG4gKiovXG5cbmV4cG9ydCBmdW5jdGlvbiBzY2FsZShvdXQsIGEsIHYpIHtcbiAgdmFyIHggPSB2WzBdLFxuICAgICAgeSA9IHZbMV07XG4gIG91dFswXSA9IHggKiBhWzBdO1xuICBvdXRbMV0gPSB4ICogYVsxXTtcbiAgb3V0WzJdID0geCAqIGFbMl07XG4gIG91dFszXSA9IHkgKiBhWzNdO1xuICBvdXRbNF0gPSB5ICogYVs0XTtcbiAgb3V0WzVdID0geSAqIGFbNV07XG4gIG91dFs2XSA9IGFbNl07XG4gIG91dFs3XSA9IGFbN107XG4gIG91dFs4XSA9IGFbOF07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENyZWF0ZXMgYSBtYXRyaXggZnJvbSBhIHZlY3RvciB0cmFuc2xhdGlvblxuICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIChidXQgbXVjaCBmYXN0ZXIgdGhhbik6XG4gKlxuICogICAgIG1hdDMuaWRlbnRpdHkoZGVzdCk7XG4gKiAgICAgbWF0My50cmFuc2xhdGUoZGVzdCwgZGVzdCwgdmVjKTtcbiAqXG4gKiBAcGFyYW0ge21hdDN9IG91dCBtYXQzIHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gdiBUcmFuc2xhdGlvbiB2ZWN0b3JcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbVRyYW5zbGF0aW9uKG91dCwgdikge1xuICBvdXRbMF0gPSAxO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSAxO1xuICBvdXRbNV0gPSAwO1xuICBvdXRbNl0gPSB2WzBdO1xuICBvdXRbN10gPSB2WzFdO1xuICBvdXRbOF0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgbWF0cml4IGZyb20gYSBnaXZlbiBhbmdsZVxuICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIChidXQgbXVjaCBmYXN0ZXIgdGhhbik6XG4gKlxuICogICAgIG1hdDMuaWRlbnRpdHkoZGVzdCk7XG4gKiAgICAgbWF0My5yb3RhdGUoZGVzdCwgZGVzdCwgcmFkKTtcbiAqXG4gKiBAcGFyYW0ge21hdDN9IG91dCBtYXQzIHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIHRoZSBhbmdsZSB0byByb3RhdGUgdGhlIG1hdHJpeCBieVxuICogQHJldHVybnMge21hdDN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9tUm90YXRpb24ob3V0LCByYWQpIHtcbiAgdmFyIHMgPSBNYXRoLnNpbihyYWQpLFxuICAgICAgYyA9IE1hdGguY29zKHJhZCk7XG4gIG91dFswXSA9IGM7XG4gIG91dFsxXSA9IHM7XG4gIG91dFsyXSA9IDA7XG4gIG91dFszXSA9IC1zO1xuICBvdXRbNF0gPSBjO1xuICBvdXRbNV0gPSAwO1xuICBvdXRbNl0gPSAwO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgbWF0cml4IGZyb20gYSB2ZWN0b3Igc2NhbGluZ1xuICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIChidXQgbXVjaCBmYXN0ZXIgdGhhbik6XG4gKlxuICogICAgIG1hdDMuaWRlbnRpdHkoZGVzdCk7XG4gKiAgICAgbWF0My5zY2FsZShkZXN0LCBkZXN0LCB2ZWMpO1xuICpcbiAqIEBwYXJhbSB7bWF0M30gb3V0IG1hdDMgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSB2IFNjYWxpbmcgdmVjdG9yXG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21TY2FsaW5nKG91dCwgdikge1xuICBvdXRbMF0gPSB2WzBdO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSB2WzFdO1xuICBvdXRbNV0gPSAwO1xuICBvdXRbNl0gPSAwO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDb3BpZXMgdGhlIHZhbHVlcyBmcm9tIGEgbWF0MmQgaW50byBhIG1hdDNcbiAqXG4gKiBAcGFyYW0ge21hdDN9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seU1hdDJkfSBhIHRoZSBtYXRyaXggdG8gY29weVxuICogQHJldHVybnMge21hdDN9IG91dFxuICoqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbU1hdDJkKG91dCwgYSkge1xuICBvdXRbMF0gPSBhWzBdO1xuICBvdXRbMV0gPSBhWzFdO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSBhWzJdO1xuICBvdXRbNF0gPSBhWzNdO1xuICBvdXRbNV0gPSAwO1xuICBvdXRbNl0gPSBhWzRdO1xuICBvdXRbN10gPSBhWzVdO1xuICBvdXRbOF0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDYWxjdWxhdGVzIGEgM3gzIG1hdHJpeCBmcm9tIHRoZSBnaXZlbiBxdWF0ZXJuaW9uXG4gKlxuICogQHBhcmFtIHttYXQzfSBvdXQgbWF0MyByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IHEgUXVhdGVybmlvbiB0byBjcmVhdGUgbWF0cml4IGZyb21cbiAqXG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21RdWF0KG91dCwgcSkge1xuICB2YXIgeCA9IHFbMF0sXG4gICAgICB5ID0gcVsxXSxcbiAgICAgIHogPSBxWzJdLFxuICAgICAgdyA9IHFbM107XG4gIHZhciB4MiA9IHggKyB4O1xuICB2YXIgeTIgPSB5ICsgeTtcbiAgdmFyIHoyID0geiArIHo7XG4gIHZhciB4eCA9IHggKiB4MjtcbiAgdmFyIHl4ID0geSAqIHgyO1xuICB2YXIgeXkgPSB5ICogeTI7XG4gIHZhciB6eCA9IHogKiB4MjtcbiAgdmFyIHp5ID0geiAqIHkyO1xuICB2YXIgenogPSB6ICogejI7XG4gIHZhciB3eCA9IHcgKiB4MjtcbiAgdmFyIHd5ID0gdyAqIHkyO1xuICB2YXIgd3ogPSB3ICogejI7XG4gIG91dFswXSA9IDEgLSB5eSAtIHp6O1xuICBvdXRbM10gPSB5eCAtIHd6O1xuICBvdXRbNl0gPSB6eCArIHd5O1xuICBvdXRbMV0gPSB5eCArIHd6O1xuICBvdXRbNF0gPSAxIC0geHggLSB6ejtcbiAgb3V0WzddID0genkgLSB3eDtcbiAgb3V0WzJdID0genggLSB3eTtcbiAgb3V0WzVdID0genkgKyB3eDtcbiAgb3V0WzhdID0gMSAtIHh4IC0geXk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENhbGN1bGF0ZXMgYSAzeDMgbm9ybWFsIG1hdHJpeCAodHJhbnNwb3NlIGludmVyc2UpIGZyb20gdGhlIDR4NCBtYXRyaXhcbiAqXG4gKiBAcGFyYW0ge21hdDN9IG91dCBtYXQzIHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYSBNYXQ0IHRvIGRlcml2ZSB0aGUgbm9ybWFsIG1hdHJpeCBmcm9tXG4gKlxuICogQHJldHVybnMge21hdDN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxGcm9tTWF0NChvdXQsIGEpIHtcbiAgdmFyIGEwMCA9IGFbMF0sXG4gICAgICBhMDEgPSBhWzFdLFxuICAgICAgYTAyID0gYVsyXSxcbiAgICAgIGEwMyA9IGFbM107XG4gIHZhciBhMTAgPSBhWzRdLFxuICAgICAgYTExID0gYVs1XSxcbiAgICAgIGExMiA9IGFbNl0sXG4gICAgICBhMTMgPSBhWzddO1xuICB2YXIgYTIwID0gYVs4XSxcbiAgICAgIGEyMSA9IGFbOV0sXG4gICAgICBhMjIgPSBhWzEwXSxcbiAgICAgIGEyMyA9IGFbMTFdO1xuICB2YXIgYTMwID0gYVsxMl0sXG4gICAgICBhMzEgPSBhWzEzXSxcbiAgICAgIGEzMiA9IGFbMTRdLFxuICAgICAgYTMzID0gYVsxNV07XG4gIHZhciBiMDAgPSBhMDAgKiBhMTEgLSBhMDEgKiBhMTA7XG4gIHZhciBiMDEgPSBhMDAgKiBhMTIgLSBhMDIgKiBhMTA7XG4gIHZhciBiMDIgPSBhMDAgKiBhMTMgLSBhMDMgKiBhMTA7XG4gIHZhciBiMDMgPSBhMDEgKiBhMTIgLSBhMDIgKiBhMTE7XG4gIHZhciBiMDQgPSBhMDEgKiBhMTMgLSBhMDMgKiBhMTE7XG4gIHZhciBiMDUgPSBhMDIgKiBhMTMgLSBhMDMgKiBhMTI7XG4gIHZhciBiMDYgPSBhMjAgKiBhMzEgLSBhMjEgKiBhMzA7XG4gIHZhciBiMDcgPSBhMjAgKiBhMzIgLSBhMjIgKiBhMzA7XG4gIHZhciBiMDggPSBhMjAgKiBhMzMgLSBhMjMgKiBhMzA7XG4gIHZhciBiMDkgPSBhMjEgKiBhMzIgLSBhMjIgKiBhMzE7XG4gIHZhciBiMTAgPSBhMjEgKiBhMzMgLSBhMjMgKiBhMzE7XG4gIHZhciBiMTEgPSBhMjIgKiBhMzMgLSBhMjMgKiBhMzI7IC8vIENhbGN1bGF0ZSB0aGUgZGV0ZXJtaW5hbnRcblxuICB2YXIgZGV0ID0gYjAwICogYjExIC0gYjAxICogYjEwICsgYjAyICogYjA5ICsgYjAzICogYjA4IC0gYjA0ICogYjA3ICsgYjA1ICogYjA2O1xuXG4gIGlmICghZGV0KSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBkZXQgPSAxLjAgLyBkZXQ7XG4gIG91dFswXSA9IChhMTEgKiBiMTEgLSBhMTIgKiBiMTAgKyBhMTMgKiBiMDkpICogZGV0O1xuICBvdXRbMV0gPSAoYTEyICogYjA4IC0gYTEwICogYjExIC0gYTEzICogYjA3KSAqIGRldDtcbiAgb3V0WzJdID0gKGExMCAqIGIxMCAtIGExMSAqIGIwOCArIGExMyAqIGIwNikgKiBkZXQ7XG4gIG91dFszXSA9IChhMDIgKiBiMTAgLSBhMDEgKiBiMTEgLSBhMDMgKiBiMDkpICogZGV0O1xuICBvdXRbNF0gPSAoYTAwICogYjExIC0gYTAyICogYjA4ICsgYTAzICogYjA3KSAqIGRldDtcbiAgb3V0WzVdID0gKGEwMSAqIGIwOCAtIGEwMCAqIGIxMCAtIGEwMyAqIGIwNikgKiBkZXQ7XG4gIG91dFs2XSA9IChhMzEgKiBiMDUgLSBhMzIgKiBiMDQgKyBhMzMgKiBiMDMpICogZGV0O1xuICBvdXRbN10gPSAoYTMyICogYjAyIC0gYTMwICogYjA1IC0gYTMzICogYjAxKSAqIGRldDtcbiAgb3V0WzhdID0gKGEzMCAqIGIwNCAtIGEzMSAqIGIwMiArIGEzMyAqIGIwMCkgKiBkZXQ7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIEdlbmVyYXRlcyBhIDJEIHByb2plY3Rpb24gbWF0cml4IHdpdGggdGhlIGdpdmVuIGJvdW5kc1xuICpcbiAqIEBwYXJhbSB7bWF0M30gb3V0IG1hdDMgZnJ1c3R1bSBtYXRyaXggd2lsbCBiZSB3cml0dGVuIGludG9cbiAqIEBwYXJhbSB7bnVtYmVyfSB3aWR0aCBXaWR0aCBvZiB5b3VyIGdsIGNvbnRleHRcbiAqIEBwYXJhbSB7bnVtYmVyfSBoZWlnaHQgSGVpZ2h0IG9mIGdsIGNvbnRleHRcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcHJvamVjdGlvbihvdXQsIHdpZHRoLCBoZWlnaHQpIHtcbiAgb3V0WzBdID0gMiAvIHdpZHRoO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSAtMiAvIGhlaWdodDtcbiAgb3V0WzVdID0gMDtcbiAgb3V0WzZdID0gLTE7XG4gIG91dFs3XSA9IDE7XG4gIG91dFs4XSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBtYXQzXG4gKlxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGEgbWF0cml4IHRvIHJlcHJlc2VudCBhcyBhIHN0cmluZ1xuICogQHJldHVybnMge1N0cmluZ30gc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtYXRyaXhcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc3RyKGEpIHtcbiAgcmV0dXJuIFwibWF0MyhcIiArIGFbMF0gKyBcIiwgXCIgKyBhWzFdICsgXCIsIFwiICsgYVsyXSArIFwiLCBcIiArIGFbM10gKyBcIiwgXCIgKyBhWzRdICsgXCIsIFwiICsgYVs1XSArIFwiLCBcIiArIGFbNl0gKyBcIiwgXCIgKyBhWzddICsgXCIsIFwiICsgYVs4XSArIFwiKVwiO1xufVxuLyoqXG4gKiBSZXR1cm5zIEZyb2Jlbml1cyBub3JtIG9mIGEgbWF0M1xuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQzfSBhIHRoZSBtYXRyaXggdG8gY2FsY3VsYXRlIEZyb2Jlbml1cyBub3JtIG9mXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBGcm9iZW5pdXMgbm9ybVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9iKGEpIHtcbiAgcmV0dXJuIE1hdGguaHlwb3QoYVswXSwgYVsxXSwgYVsyXSwgYVszXSwgYVs0XSwgYVs1XSwgYVs2XSwgYVs3XSwgYVs4XSk7XG59XG4vKipcbiAqIEFkZHMgdHdvIG1hdDMnc1xuICpcbiAqIEBwYXJhbSB7bWF0M30gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZChvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gYVswXSArIGJbMF07XG4gIG91dFsxXSA9IGFbMV0gKyBiWzFdO1xuICBvdXRbMl0gPSBhWzJdICsgYlsyXTtcbiAgb3V0WzNdID0gYVszXSArIGJbM107XG4gIG91dFs0XSA9IGFbNF0gKyBiWzRdO1xuICBvdXRbNV0gPSBhWzVdICsgYls1XTtcbiAgb3V0WzZdID0gYVs2XSArIGJbNl07XG4gIG91dFs3XSA9IGFbN10gKyBiWzddO1xuICBvdXRbOF0gPSBhWzhdICsgYls4XTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogU3VidHJhY3RzIG1hdHJpeCBiIGZyb20gbWF0cml4IGFcbiAqXG4gKiBAcGFyYW0ge21hdDN9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQzfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge21hdDN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzdWJ0cmFjdChvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gYVswXSAtIGJbMF07XG4gIG91dFsxXSA9IGFbMV0gLSBiWzFdO1xuICBvdXRbMl0gPSBhWzJdIC0gYlsyXTtcbiAgb3V0WzNdID0gYVszXSAtIGJbM107XG4gIG91dFs0XSA9IGFbNF0gLSBiWzRdO1xuICBvdXRbNV0gPSBhWzVdIC0gYls1XTtcbiAgb3V0WzZdID0gYVs2XSAtIGJbNl07XG4gIG91dFs3XSA9IGFbN10gLSBiWzddO1xuICBvdXRbOF0gPSBhWzhdIC0gYls4XTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogTXVsdGlwbHkgZWFjaCBlbGVtZW50IG9mIHRoZSBtYXRyaXggYnkgYSBzY2FsYXIuXG4gKlxuICogQHBhcmFtIHttYXQzfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQzfSBhIHRoZSBtYXRyaXggdG8gc2NhbGVcbiAqIEBwYXJhbSB7TnVtYmVyfSBiIGFtb3VudCB0byBzY2FsZSB0aGUgbWF0cml4J3MgZWxlbWVudHMgYnlcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbXVsdGlwbHlTY2FsYXIob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IGFbMF0gKiBiO1xuICBvdXRbMV0gPSBhWzFdICogYjtcbiAgb3V0WzJdID0gYVsyXSAqIGI7XG4gIG91dFszXSA9IGFbM10gKiBiO1xuICBvdXRbNF0gPSBhWzRdICogYjtcbiAgb3V0WzVdID0gYVs1XSAqIGI7XG4gIG91dFs2XSA9IGFbNl0gKiBiO1xuICBvdXRbN10gPSBhWzddICogYjtcbiAgb3V0WzhdID0gYVs4XSAqIGI7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIEFkZHMgdHdvIG1hdDMncyBhZnRlciBtdWx0aXBseWluZyBlYWNoIGVsZW1lbnQgb2YgdGhlIHNlY29uZCBvcGVyYW5kIGJ5IGEgc2NhbGFyIHZhbHVlLlxuICpcbiAqIEBwYXJhbSB7bWF0M30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcGFyYW0ge051bWJlcn0gc2NhbGUgdGhlIGFtb3VudCB0byBzY2FsZSBiJ3MgZWxlbWVudHMgYnkgYmVmb3JlIGFkZGluZ1xuICogQHJldHVybnMge21hdDN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBtdWx0aXBseVNjYWxhckFuZEFkZChvdXQsIGEsIGIsIHNjYWxlKSB7XG4gIG91dFswXSA9IGFbMF0gKyBiWzBdICogc2NhbGU7XG4gIG91dFsxXSA9IGFbMV0gKyBiWzFdICogc2NhbGU7XG4gIG91dFsyXSA9IGFbMl0gKyBiWzJdICogc2NhbGU7XG4gIG91dFszXSA9IGFbM10gKyBiWzNdICogc2NhbGU7XG4gIG91dFs0XSA9IGFbNF0gKyBiWzRdICogc2NhbGU7XG4gIG91dFs1XSA9IGFbNV0gKyBiWzVdICogc2NhbGU7XG4gIG91dFs2XSA9IGFbNl0gKyBiWzZdICogc2NhbGU7XG4gIG91dFs3XSA9IGFbN10gKyBiWzddICogc2NhbGU7XG4gIG91dFs4XSA9IGFbOF0gKyBiWzhdICogc2NhbGU7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhlIG1hdHJpY2VzIGhhdmUgZXhhY3RseSB0aGUgc2FtZSBlbGVtZW50cyBpbiB0aGUgc2FtZSBwb3NpdGlvbiAod2hlbiBjb21wYXJlZCB3aXRoID09PSlcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gYSBUaGUgZmlyc3QgbWF0cml4LlxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGIgVGhlIHNlY29uZCBtYXRyaXguXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gVHJ1ZSBpZiB0aGUgbWF0cmljZXMgYXJlIGVxdWFsLCBmYWxzZSBvdGhlcndpc2UuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGV4YWN0RXF1YWxzKGEsIGIpIHtcbiAgcmV0dXJuIGFbMF0gPT09IGJbMF0gJiYgYVsxXSA9PT0gYlsxXSAmJiBhWzJdID09PSBiWzJdICYmIGFbM10gPT09IGJbM10gJiYgYVs0XSA9PT0gYls0XSAmJiBhWzVdID09PSBiWzVdICYmIGFbNl0gPT09IGJbNl0gJiYgYVs3XSA9PT0gYls3XSAmJiBhWzhdID09PSBiWzhdO1xufVxuLyoqXG4gKiBSZXR1cm5zIHdoZXRoZXIgb3Igbm90IHRoZSBtYXRyaWNlcyBoYXZlIGFwcHJveGltYXRlbHkgdGhlIHNhbWUgZWxlbWVudHMgaW4gdGhlIHNhbWUgcG9zaXRpb24uXG4gKlxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGEgVGhlIGZpcnN0IG1hdHJpeC5cbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQzfSBiIFRoZSBzZWNvbmQgbWF0cml4LlxuICogQHJldHVybnMge0Jvb2xlYW59IFRydWUgaWYgdGhlIG1hdHJpY2VzIGFyZSBlcXVhbCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBlcXVhbHMoYSwgYikge1xuICB2YXIgYTAgPSBhWzBdLFxuICAgICAgYTEgPSBhWzFdLFxuICAgICAgYTIgPSBhWzJdLFxuICAgICAgYTMgPSBhWzNdLFxuICAgICAgYTQgPSBhWzRdLFxuICAgICAgYTUgPSBhWzVdLFxuICAgICAgYTYgPSBhWzZdLFxuICAgICAgYTcgPSBhWzddLFxuICAgICAgYTggPSBhWzhdO1xuICB2YXIgYjAgPSBiWzBdLFxuICAgICAgYjEgPSBiWzFdLFxuICAgICAgYjIgPSBiWzJdLFxuICAgICAgYjMgPSBiWzNdLFxuICAgICAgYjQgPSBiWzRdLFxuICAgICAgYjUgPSBiWzVdLFxuICAgICAgYjYgPSBiWzZdLFxuICAgICAgYjcgPSBiWzddLFxuICAgICAgYjggPSBiWzhdO1xuICByZXR1cm4gTWF0aC5hYnMoYTAgLSBiMCkgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTApLCBNYXRoLmFicyhiMCkpICYmIE1hdGguYWJzKGExIC0gYjEpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGExKSwgTWF0aC5hYnMoYjEpKSAmJiBNYXRoLmFicyhhMiAtIGIyKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMiksIE1hdGguYWJzKGIyKSkgJiYgTWF0aC5hYnMoYTMgLSBiMykgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTMpLCBNYXRoLmFicyhiMykpICYmIE1hdGguYWJzKGE0IC0gYjQpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGE0KSwgTWF0aC5hYnMoYjQpKSAmJiBNYXRoLmFicyhhNSAtIGI1KSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhNSksIE1hdGguYWJzKGI1KSkgJiYgTWF0aC5hYnMoYTYgLSBiNikgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTYpLCBNYXRoLmFicyhiNikpICYmIE1hdGguYWJzKGE3IC0gYjcpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGE3KSwgTWF0aC5hYnMoYjcpKSAmJiBNYXRoLmFicyhhOCAtIGI4KSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhOCksIE1hdGguYWJzKGI4KSk7XG59XG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgbWF0My5tdWx0aXBseX1cbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgbXVsID0gbXVsdGlwbHk7XG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgbWF0My5zdWJ0cmFjdH1cbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgc3ViID0gc3VidHJhY3Q7IiwiaW1wb3J0ICogYXMgZ2xNYXRyaXggZnJvbSBcIi4vY29tbW9uLmpzXCI7XG4vKipcbiAqIDR4NCBNYXRyaXg8YnI+Rm9ybWF0OiBjb2x1bW4tbWFqb3IsIHdoZW4gdHlwZWQgb3V0IGl0IGxvb2tzIGxpa2Ugcm93LW1ham9yPGJyPlRoZSBtYXRyaWNlcyBhcmUgYmVpbmcgcG9zdCBtdWx0aXBsaWVkLlxuICogQG1vZHVsZSBtYXQ0XG4gKi9cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGlkZW50aXR5IG1hdDRcbiAqXG4gKiBAcmV0dXJucyB7bWF0NH0gYSBuZXcgNHg0IG1hdHJpeFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGUoKSB7XG4gIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSgxNik7XG5cbiAgaWYgKGdsTWF0cml4LkFSUkFZX1RZUEUgIT0gRmxvYXQzMkFycmF5KSB7XG4gICAgb3V0WzFdID0gMDtcbiAgICBvdXRbMl0gPSAwO1xuICAgIG91dFszXSA9IDA7XG4gICAgb3V0WzRdID0gMDtcbiAgICBvdXRbNl0gPSAwO1xuICAgIG91dFs3XSA9IDA7XG4gICAgb3V0WzhdID0gMDtcbiAgICBvdXRbOV0gPSAwO1xuICAgIG91dFsxMV0gPSAwO1xuICAgIG91dFsxMl0gPSAwO1xuICAgIG91dFsxM10gPSAwO1xuICAgIG91dFsxNF0gPSAwO1xuICB9XG5cbiAgb3V0WzBdID0gMTtcbiAgb3V0WzVdID0gMTtcbiAgb3V0WzEwXSA9IDE7XG4gIG91dFsxNV0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IG1hdDQgaW5pdGlhbGl6ZWQgd2l0aCB2YWx1ZXMgZnJvbSBhbiBleGlzdGluZyBtYXRyaXhcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYSBtYXRyaXggdG8gY2xvbmVcbiAqIEByZXR1cm5zIHttYXQ0fSBhIG5ldyA0eDQgbWF0cml4XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNsb25lKGEpIHtcbiAgdmFyIG91dCA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDE2KTtcbiAgb3V0WzBdID0gYVswXTtcbiAgb3V0WzFdID0gYVsxXTtcbiAgb3V0WzJdID0gYVsyXTtcbiAgb3V0WzNdID0gYVszXTtcbiAgb3V0WzRdID0gYVs0XTtcbiAgb3V0WzVdID0gYVs1XTtcbiAgb3V0WzZdID0gYVs2XTtcbiAgb3V0WzddID0gYVs3XTtcbiAgb3V0WzhdID0gYVs4XTtcbiAgb3V0WzldID0gYVs5XTtcbiAgb3V0WzEwXSA9IGFbMTBdO1xuICBvdXRbMTFdID0gYVsxMV07XG4gIG91dFsxMl0gPSBhWzEyXTtcbiAgb3V0WzEzXSA9IGFbMTNdO1xuICBvdXRbMTRdID0gYVsxNF07XG4gIG91dFsxNV0gPSBhWzE1XTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ29weSB0aGUgdmFsdWVzIGZyb20gb25lIG1hdDQgdG8gYW5vdGhlclxuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYSB0aGUgc291cmNlIG1hdHJpeFxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjb3B5KG91dCwgYSkge1xuICBvdXRbMF0gPSBhWzBdO1xuICBvdXRbMV0gPSBhWzFdO1xuICBvdXRbMl0gPSBhWzJdO1xuICBvdXRbM10gPSBhWzNdO1xuICBvdXRbNF0gPSBhWzRdO1xuICBvdXRbNV0gPSBhWzVdO1xuICBvdXRbNl0gPSBhWzZdO1xuICBvdXRbN10gPSBhWzddO1xuICBvdXRbOF0gPSBhWzhdO1xuICBvdXRbOV0gPSBhWzldO1xuICBvdXRbMTBdID0gYVsxMF07XG4gIG91dFsxMV0gPSBhWzExXTtcbiAgb3V0WzEyXSA9IGFbMTJdO1xuICBvdXRbMTNdID0gYVsxM107XG4gIG91dFsxNF0gPSBhWzE0XTtcbiAgb3V0WzE1XSA9IGFbMTVdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgbWF0NCB3aXRoIHRoZSBnaXZlbiB2YWx1ZXNcbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gbTAwIENvbXBvbmVudCBpbiBjb2x1bW4gMCwgcm93IDAgcG9zaXRpb24gKGluZGV4IDApXG4gKiBAcGFyYW0ge051bWJlcn0gbTAxIENvbXBvbmVudCBpbiBjb2x1bW4gMCwgcm93IDEgcG9zaXRpb24gKGluZGV4IDEpXG4gKiBAcGFyYW0ge051bWJlcn0gbTAyIENvbXBvbmVudCBpbiBjb2x1bW4gMCwgcm93IDIgcG9zaXRpb24gKGluZGV4IDIpXG4gKiBAcGFyYW0ge051bWJlcn0gbTAzIENvbXBvbmVudCBpbiBjb2x1bW4gMCwgcm93IDMgcG9zaXRpb24gKGluZGV4IDMpXG4gKiBAcGFyYW0ge051bWJlcn0gbTEwIENvbXBvbmVudCBpbiBjb2x1bW4gMSwgcm93IDAgcG9zaXRpb24gKGluZGV4IDQpXG4gKiBAcGFyYW0ge051bWJlcn0gbTExIENvbXBvbmVudCBpbiBjb2x1bW4gMSwgcm93IDEgcG9zaXRpb24gKGluZGV4IDUpXG4gKiBAcGFyYW0ge051bWJlcn0gbTEyIENvbXBvbmVudCBpbiBjb2x1bW4gMSwgcm93IDIgcG9zaXRpb24gKGluZGV4IDYpXG4gKiBAcGFyYW0ge051bWJlcn0gbTEzIENvbXBvbmVudCBpbiBjb2x1bW4gMSwgcm93IDMgcG9zaXRpb24gKGluZGV4IDcpXG4gKiBAcGFyYW0ge051bWJlcn0gbTIwIENvbXBvbmVudCBpbiBjb2x1bW4gMiwgcm93IDAgcG9zaXRpb24gKGluZGV4IDgpXG4gKiBAcGFyYW0ge051bWJlcn0gbTIxIENvbXBvbmVudCBpbiBjb2x1bW4gMiwgcm93IDEgcG9zaXRpb24gKGluZGV4IDkpXG4gKiBAcGFyYW0ge051bWJlcn0gbTIyIENvbXBvbmVudCBpbiBjb2x1bW4gMiwgcm93IDIgcG9zaXRpb24gKGluZGV4IDEwKVxuICogQHBhcmFtIHtOdW1iZXJ9IG0yMyBDb21wb25lbnQgaW4gY29sdW1uIDIsIHJvdyAzIHBvc2l0aW9uIChpbmRleCAxMSlcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMzAgQ29tcG9uZW50IGluIGNvbHVtbiAzLCByb3cgMCBwb3NpdGlvbiAoaW5kZXggMTIpXG4gKiBAcGFyYW0ge051bWJlcn0gbTMxIENvbXBvbmVudCBpbiBjb2x1bW4gMywgcm93IDEgcG9zaXRpb24gKGluZGV4IDEzKVxuICogQHBhcmFtIHtOdW1iZXJ9IG0zMiBDb21wb25lbnQgaW4gY29sdW1uIDMsIHJvdyAyIHBvc2l0aW9uIChpbmRleCAxNClcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMzMgQ29tcG9uZW50IGluIGNvbHVtbiAzLCByb3cgMyBwb3NpdGlvbiAoaW5kZXggMTUpXG4gKiBAcmV0dXJucyB7bWF0NH0gQSBuZXcgbWF0NFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9tVmFsdWVzKG0wMCwgbTAxLCBtMDIsIG0wMywgbTEwLCBtMTEsIG0xMiwgbTEzLCBtMjAsIG0yMSwgbTIyLCBtMjMsIG0zMCwgbTMxLCBtMzIsIG0zMykge1xuICB2YXIgb3V0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoMTYpO1xuICBvdXRbMF0gPSBtMDA7XG4gIG91dFsxXSA9IG0wMTtcbiAgb3V0WzJdID0gbTAyO1xuICBvdXRbM10gPSBtMDM7XG4gIG91dFs0XSA9IG0xMDtcbiAgb3V0WzVdID0gbTExO1xuICBvdXRbNl0gPSBtMTI7XG4gIG91dFs3XSA9IG0xMztcbiAgb3V0WzhdID0gbTIwO1xuICBvdXRbOV0gPSBtMjE7XG4gIG91dFsxMF0gPSBtMjI7XG4gIG91dFsxMV0gPSBtMjM7XG4gIG91dFsxMl0gPSBtMzA7XG4gIG91dFsxM10gPSBtMzE7XG4gIG91dFsxNF0gPSBtMzI7XG4gIG91dFsxNV0gPSBtMzM7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFNldCB0aGUgY29tcG9uZW50cyBvZiBhIG1hdDQgdG8gdGhlIGdpdmVuIHZhbHVlc1xuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge051bWJlcn0gbTAwIENvbXBvbmVudCBpbiBjb2x1bW4gMCwgcm93IDAgcG9zaXRpb24gKGluZGV4IDApXG4gKiBAcGFyYW0ge051bWJlcn0gbTAxIENvbXBvbmVudCBpbiBjb2x1bW4gMCwgcm93IDEgcG9zaXRpb24gKGluZGV4IDEpXG4gKiBAcGFyYW0ge051bWJlcn0gbTAyIENvbXBvbmVudCBpbiBjb2x1bW4gMCwgcm93IDIgcG9zaXRpb24gKGluZGV4IDIpXG4gKiBAcGFyYW0ge051bWJlcn0gbTAzIENvbXBvbmVudCBpbiBjb2x1bW4gMCwgcm93IDMgcG9zaXRpb24gKGluZGV4IDMpXG4gKiBAcGFyYW0ge051bWJlcn0gbTEwIENvbXBvbmVudCBpbiBjb2x1bW4gMSwgcm93IDAgcG9zaXRpb24gKGluZGV4IDQpXG4gKiBAcGFyYW0ge051bWJlcn0gbTExIENvbXBvbmVudCBpbiBjb2x1bW4gMSwgcm93IDEgcG9zaXRpb24gKGluZGV4IDUpXG4gKiBAcGFyYW0ge051bWJlcn0gbTEyIENvbXBvbmVudCBpbiBjb2x1bW4gMSwgcm93IDIgcG9zaXRpb24gKGluZGV4IDYpXG4gKiBAcGFyYW0ge051bWJlcn0gbTEzIENvbXBvbmVudCBpbiBjb2x1bW4gMSwgcm93IDMgcG9zaXRpb24gKGluZGV4IDcpXG4gKiBAcGFyYW0ge051bWJlcn0gbTIwIENvbXBvbmVudCBpbiBjb2x1bW4gMiwgcm93IDAgcG9zaXRpb24gKGluZGV4IDgpXG4gKiBAcGFyYW0ge051bWJlcn0gbTIxIENvbXBvbmVudCBpbiBjb2x1bW4gMiwgcm93IDEgcG9zaXRpb24gKGluZGV4IDkpXG4gKiBAcGFyYW0ge051bWJlcn0gbTIyIENvbXBvbmVudCBpbiBjb2x1bW4gMiwgcm93IDIgcG9zaXRpb24gKGluZGV4IDEwKVxuICogQHBhcmFtIHtOdW1iZXJ9IG0yMyBDb21wb25lbnQgaW4gY29sdW1uIDIsIHJvdyAzIHBvc2l0aW9uIChpbmRleCAxMSlcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMzAgQ29tcG9uZW50IGluIGNvbHVtbiAzLCByb3cgMCBwb3NpdGlvbiAoaW5kZXggMTIpXG4gKiBAcGFyYW0ge051bWJlcn0gbTMxIENvbXBvbmVudCBpbiBjb2x1bW4gMywgcm93IDEgcG9zaXRpb24gKGluZGV4IDEzKVxuICogQHBhcmFtIHtOdW1iZXJ9IG0zMiBDb21wb25lbnQgaW4gY29sdW1uIDMsIHJvdyAyIHBvc2l0aW9uIChpbmRleCAxNClcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMzMgQ29tcG9uZW50IGluIGNvbHVtbiAzLCByb3cgMyBwb3NpdGlvbiAoaW5kZXggMTUpXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNldChvdXQsIG0wMCwgbTAxLCBtMDIsIG0wMywgbTEwLCBtMTEsIG0xMiwgbTEzLCBtMjAsIG0yMSwgbTIyLCBtMjMsIG0zMCwgbTMxLCBtMzIsIG0zMykge1xuICBvdXRbMF0gPSBtMDA7XG4gIG91dFsxXSA9IG0wMTtcbiAgb3V0WzJdID0gbTAyO1xuICBvdXRbM10gPSBtMDM7XG4gIG91dFs0XSA9IG0xMDtcbiAgb3V0WzVdID0gbTExO1xuICBvdXRbNl0gPSBtMTI7XG4gIG91dFs3XSA9IG0xMztcbiAgb3V0WzhdID0gbTIwO1xuICBvdXRbOV0gPSBtMjE7XG4gIG91dFsxMF0gPSBtMjI7XG4gIG91dFsxMV0gPSBtMjM7XG4gIG91dFsxMl0gPSBtMzA7XG4gIG91dFsxM10gPSBtMzE7XG4gIG91dFsxNF0gPSBtMzI7XG4gIG91dFsxNV0gPSBtMzM7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFNldCBhIG1hdDQgdG8gdGhlIGlkZW50aXR5IG1hdHJpeFxuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGlkZW50aXR5KG91dCkge1xuICBvdXRbMF0gPSAxO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSAwO1xuICBvdXRbNV0gPSAxO1xuICBvdXRbNl0gPSAwO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSAwO1xuICBvdXRbOV0gPSAwO1xuICBvdXRbMTBdID0gMTtcbiAgb3V0WzExXSA9IDA7XG4gIG91dFsxMl0gPSAwO1xuICBvdXRbMTNdID0gMDtcbiAgb3V0WzE0XSA9IDA7XG4gIG91dFsxNV0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBUcmFuc3Bvc2UgdGhlIHZhbHVlcyBvZiBhIG1hdDRcbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGEgdGhlIHNvdXJjZSBtYXRyaXhcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNwb3NlKG91dCwgYSkge1xuICAvLyBJZiB3ZSBhcmUgdHJhbnNwb3Npbmcgb3Vyc2VsdmVzIHdlIGNhbiBza2lwIGEgZmV3IHN0ZXBzIGJ1dCBoYXZlIHRvIGNhY2hlIHNvbWUgdmFsdWVzXG4gIGlmIChvdXQgPT09IGEpIHtcbiAgICB2YXIgYTAxID0gYVsxXSxcbiAgICAgICAgYTAyID0gYVsyXSxcbiAgICAgICAgYTAzID0gYVszXTtcbiAgICB2YXIgYTEyID0gYVs2XSxcbiAgICAgICAgYTEzID0gYVs3XTtcbiAgICB2YXIgYTIzID0gYVsxMV07XG4gICAgb3V0WzFdID0gYVs0XTtcbiAgICBvdXRbMl0gPSBhWzhdO1xuICAgIG91dFszXSA9IGFbMTJdO1xuICAgIG91dFs0XSA9IGEwMTtcbiAgICBvdXRbNl0gPSBhWzldO1xuICAgIG91dFs3XSA9IGFbMTNdO1xuICAgIG91dFs4XSA9IGEwMjtcbiAgICBvdXRbOV0gPSBhMTI7XG4gICAgb3V0WzExXSA9IGFbMTRdO1xuICAgIG91dFsxMl0gPSBhMDM7XG4gICAgb3V0WzEzXSA9IGExMztcbiAgICBvdXRbMTRdID0gYTIzO1xuICB9IGVsc2Uge1xuICAgIG91dFswXSA9IGFbMF07XG4gICAgb3V0WzFdID0gYVs0XTtcbiAgICBvdXRbMl0gPSBhWzhdO1xuICAgIG91dFszXSA9IGFbMTJdO1xuICAgIG91dFs0XSA9IGFbMV07XG4gICAgb3V0WzVdID0gYVs1XTtcbiAgICBvdXRbNl0gPSBhWzldO1xuICAgIG91dFs3XSA9IGFbMTNdO1xuICAgIG91dFs4XSA9IGFbMl07XG4gICAgb3V0WzldID0gYVs2XTtcbiAgICBvdXRbMTBdID0gYVsxMF07XG4gICAgb3V0WzExXSA9IGFbMTRdO1xuICAgIG91dFsxMl0gPSBhWzNdO1xuICAgIG91dFsxM10gPSBhWzddO1xuICAgIG91dFsxNF0gPSBhWzExXTtcbiAgICBvdXRbMTVdID0gYVsxNV07XG4gIH1cblxuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBJbnZlcnRzIGEgbWF0NFxuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYSB0aGUgc291cmNlIG1hdHJpeFxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBpbnZlcnQob3V0LCBhKSB7XG4gIHZhciBhMDAgPSBhWzBdLFxuICAgICAgYTAxID0gYVsxXSxcbiAgICAgIGEwMiA9IGFbMl0sXG4gICAgICBhMDMgPSBhWzNdO1xuICB2YXIgYTEwID0gYVs0XSxcbiAgICAgIGExMSA9IGFbNV0sXG4gICAgICBhMTIgPSBhWzZdLFxuICAgICAgYTEzID0gYVs3XTtcbiAgdmFyIGEyMCA9IGFbOF0sXG4gICAgICBhMjEgPSBhWzldLFxuICAgICAgYTIyID0gYVsxMF0sXG4gICAgICBhMjMgPSBhWzExXTtcbiAgdmFyIGEzMCA9IGFbMTJdLFxuICAgICAgYTMxID0gYVsxM10sXG4gICAgICBhMzIgPSBhWzE0XSxcbiAgICAgIGEzMyA9IGFbMTVdO1xuICB2YXIgYjAwID0gYTAwICogYTExIC0gYTAxICogYTEwO1xuICB2YXIgYjAxID0gYTAwICogYTEyIC0gYTAyICogYTEwO1xuICB2YXIgYjAyID0gYTAwICogYTEzIC0gYTAzICogYTEwO1xuICB2YXIgYjAzID0gYTAxICogYTEyIC0gYTAyICogYTExO1xuICB2YXIgYjA0ID0gYTAxICogYTEzIC0gYTAzICogYTExO1xuICB2YXIgYjA1ID0gYTAyICogYTEzIC0gYTAzICogYTEyO1xuICB2YXIgYjA2ID0gYTIwICogYTMxIC0gYTIxICogYTMwO1xuICB2YXIgYjA3ID0gYTIwICogYTMyIC0gYTIyICogYTMwO1xuICB2YXIgYjA4ID0gYTIwICogYTMzIC0gYTIzICogYTMwO1xuICB2YXIgYjA5ID0gYTIxICogYTMyIC0gYTIyICogYTMxO1xuICB2YXIgYjEwID0gYTIxICogYTMzIC0gYTIzICogYTMxO1xuICB2YXIgYjExID0gYTIyICogYTMzIC0gYTIzICogYTMyOyAvLyBDYWxjdWxhdGUgdGhlIGRldGVybWluYW50XG5cbiAgdmFyIGRldCA9IGIwMCAqIGIxMSAtIGIwMSAqIGIxMCArIGIwMiAqIGIwOSArIGIwMyAqIGIwOCAtIGIwNCAqIGIwNyArIGIwNSAqIGIwNjtcblxuICBpZiAoIWRldCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZGV0ID0gMS4wIC8gZGV0O1xuICBvdXRbMF0gPSAoYTExICogYjExIC0gYTEyICogYjEwICsgYTEzICogYjA5KSAqIGRldDtcbiAgb3V0WzFdID0gKGEwMiAqIGIxMCAtIGEwMSAqIGIxMSAtIGEwMyAqIGIwOSkgKiBkZXQ7XG4gIG91dFsyXSA9IChhMzEgKiBiMDUgLSBhMzIgKiBiMDQgKyBhMzMgKiBiMDMpICogZGV0O1xuICBvdXRbM10gPSAoYTIyICogYjA0IC0gYTIxICogYjA1IC0gYTIzICogYjAzKSAqIGRldDtcbiAgb3V0WzRdID0gKGExMiAqIGIwOCAtIGExMCAqIGIxMSAtIGExMyAqIGIwNykgKiBkZXQ7XG4gIG91dFs1XSA9IChhMDAgKiBiMTEgLSBhMDIgKiBiMDggKyBhMDMgKiBiMDcpICogZGV0O1xuICBvdXRbNl0gPSAoYTMyICogYjAyIC0gYTMwICogYjA1IC0gYTMzICogYjAxKSAqIGRldDtcbiAgb3V0WzddID0gKGEyMCAqIGIwNSAtIGEyMiAqIGIwMiArIGEyMyAqIGIwMSkgKiBkZXQ7XG4gIG91dFs4XSA9IChhMTAgKiBiMTAgLSBhMTEgKiBiMDggKyBhMTMgKiBiMDYpICogZGV0O1xuICBvdXRbOV0gPSAoYTAxICogYjA4IC0gYTAwICogYjEwIC0gYTAzICogYjA2KSAqIGRldDtcbiAgb3V0WzEwXSA9IChhMzAgKiBiMDQgLSBhMzEgKiBiMDIgKyBhMzMgKiBiMDApICogZGV0O1xuICBvdXRbMTFdID0gKGEyMSAqIGIwMiAtIGEyMCAqIGIwNCAtIGEyMyAqIGIwMCkgKiBkZXQ7XG4gIG91dFsxMl0gPSAoYTExICogYjA3IC0gYTEwICogYjA5IC0gYTEyICogYjA2KSAqIGRldDtcbiAgb3V0WzEzXSA9IChhMDAgKiBiMDkgLSBhMDEgKiBiMDcgKyBhMDIgKiBiMDYpICogZGV0O1xuICBvdXRbMTRdID0gKGEzMSAqIGIwMSAtIGEzMCAqIGIwMyAtIGEzMiAqIGIwMCkgKiBkZXQ7XG4gIG91dFsxNV0gPSAoYTIwICogYjAzIC0gYTIxICogYjAxICsgYTIyICogYjAwKSAqIGRldDtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgYWRqdWdhdGUgb2YgYSBtYXQ0XG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhIHRoZSBzb3VyY2UgbWF0cml4XG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGFkam9pbnQob3V0LCBhKSB7XG4gIHZhciBhMDAgPSBhWzBdLFxuICAgICAgYTAxID0gYVsxXSxcbiAgICAgIGEwMiA9IGFbMl0sXG4gICAgICBhMDMgPSBhWzNdO1xuICB2YXIgYTEwID0gYVs0XSxcbiAgICAgIGExMSA9IGFbNV0sXG4gICAgICBhMTIgPSBhWzZdLFxuICAgICAgYTEzID0gYVs3XTtcbiAgdmFyIGEyMCA9IGFbOF0sXG4gICAgICBhMjEgPSBhWzldLFxuICAgICAgYTIyID0gYVsxMF0sXG4gICAgICBhMjMgPSBhWzExXTtcbiAgdmFyIGEzMCA9IGFbMTJdLFxuICAgICAgYTMxID0gYVsxM10sXG4gICAgICBhMzIgPSBhWzE0XSxcbiAgICAgIGEzMyA9IGFbMTVdO1xuICBvdXRbMF0gPSBhMTEgKiAoYTIyICogYTMzIC0gYTIzICogYTMyKSAtIGEyMSAqIChhMTIgKiBhMzMgLSBhMTMgKiBhMzIpICsgYTMxICogKGExMiAqIGEyMyAtIGExMyAqIGEyMik7XG4gIG91dFsxXSA9IC0oYTAxICogKGEyMiAqIGEzMyAtIGEyMyAqIGEzMikgLSBhMjEgKiAoYTAyICogYTMzIC0gYTAzICogYTMyKSArIGEzMSAqIChhMDIgKiBhMjMgLSBhMDMgKiBhMjIpKTtcbiAgb3V0WzJdID0gYTAxICogKGExMiAqIGEzMyAtIGExMyAqIGEzMikgLSBhMTEgKiAoYTAyICogYTMzIC0gYTAzICogYTMyKSArIGEzMSAqIChhMDIgKiBhMTMgLSBhMDMgKiBhMTIpO1xuICBvdXRbM10gPSAtKGEwMSAqIChhMTIgKiBhMjMgLSBhMTMgKiBhMjIpIC0gYTExICogKGEwMiAqIGEyMyAtIGEwMyAqIGEyMikgKyBhMjEgKiAoYTAyICogYTEzIC0gYTAzICogYTEyKSk7XG4gIG91dFs0XSA9IC0oYTEwICogKGEyMiAqIGEzMyAtIGEyMyAqIGEzMikgLSBhMjAgKiAoYTEyICogYTMzIC0gYTEzICogYTMyKSArIGEzMCAqIChhMTIgKiBhMjMgLSBhMTMgKiBhMjIpKTtcbiAgb3V0WzVdID0gYTAwICogKGEyMiAqIGEzMyAtIGEyMyAqIGEzMikgLSBhMjAgKiAoYTAyICogYTMzIC0gYTAzICogYTMyKSArIGEzMCAqIChhMDIgKiBhMjMgLSBhMDMgKiBhMjIpO1xuICBvdXRbNl0gPSAtKGEwMCAqIChhMTIgKiBhMzMgLSBhMTMgKiBhMzIpIC0gYTEwICogKGEwMiAqIGEzMyAtIGEwMyAqIGEzMikgKyBhMzAgKiAoYTAyICogYTEzIC0gYTAzICogYTEyKSk7XG4gIG91dFs3XSA9IGEwMCAqIChhMTIgKiBhMjMgLSBhMTMgKiBhMjIpIC0gYTEwICogKGEwMiAqIGEyMyAtIGEwMyAqIGEyMikgKyBhMjAgKiAoYTAyICogYTEzIC0gYTAzICogYTEyKTtcbiAgb3V0WzhdID0gYTEwICogKGEyMSAqIGEzMyAtIGEyMyAqIGEzMSkgLSBhMjAgKiAoYTExICogYTMzIC0gYTEzICogYTMxKSArIGEzMCAqIChhMTEgKiBhMjMgLSBhMTMgKiBhMjEpO1xuICBvdXRbOV0gPSAtKGEwMCAqIChhMjEgKiBhMzMgLSBhMjMgKiBhMzEpIC0gYTIwICogKGEwMSAqIGEzMyAtIGEwMyAqIGEzMSkgKyBhMzAgKiAoYTAxICogYTIzIC0gYTAzICogYTIxKSk7XG4gIG91dFsxMF0gPSBhMDAgKiAoYTExICogYTMzIC0gYTEzICogYTMxKSAtIGExMCAqIChhMDEgKiBhMzMgLSBhMDMgKiBhMzEpICsgYTMwICogKGEwMSAqIGExMyAtIGEwMyAqIGExMSk7XG4gIG91dFsxMV0gPSAtKGEwMCAqIChhMTEgKiBhMjMgLSBhMTMgKiBhMjEpIC0gYTEwICogKGEwMSAqIGEyMyAtIGEwMyAqIGEyMSkgKyBhMjAgKiAoYTAxICogYTEzIC0gYTAzICogYTExKSk7XG4gIG91dFsxMl0gPSAtKGExMCAqIChhMjEgKiBhMzIgLSBhMjIgKiBhMzEpIC0gYTIwICogKGExMSAqIGEzMiAtIGExMiAqIGEzMSkgKyBhMzAgKiAoYTExICogYTIyIC0gYTEyICogYTIxKSk7XG4gIG91dFsxM10gPSBhMDAgKiAoYTIxICogYTMyIC0gYTIyICogYTMxKSAtIGEyMCAqIChhMDEgKiBhMzIgLSBhMDIgKiBhMzEpICsgYTMwICogKGEwMSAqIGEyMiAtIGEwMiAqIGEyMSk7XG4gIG91dFsxNF0gPSAtKGEwMCAqIChhMTEgKiBhMzIgLSBhMTIgKiBhMzEpIC0gYTEwICogKGEwMSAqIGEzMiAtIGEwMiAqIGEzMSkgKyBhMzAgKiAoYTAxICogYTEyIC0gYTAyICogYTExKSk7XG4gIG91dFsxNV0gPSBhMDAgKiAoYTExICogYTIyIC0gYTEyICogYTIxKSAtIGExMCAqIChhMDEgKiBhMjIgLSBhMDIgKiBhMjEpICsgYTIwICogKGEwMSAqIGExMiAtIGEwMiAqIGExMSk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGRldGVybWluYW50IG9mIGEgbWF0NFxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhIHRoZSBzb3VyY2UgbWF0cml4XG4gKiBAcmV0dXJucyB7TnVtYmVyfSBkZXRlcm1pbmFudCBvZiBhXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGRldGVybWluYW50KGEpIHtcbiAgdmFyIGEwMCA9IGFbMF0sXG4gICAgICBhMDEgPSBhWzFdLFxuICAgICAgYTAyID0gYVsyXSxcbiAgICAgIGEwMyA9IGFbM107XG4gIHZhciBhMTAgPSBhWzRdLFxuICAgICAgYTExID0gYVs1XSxcbiAgICAgIGExMiA9IGFbNl0sXG4gICAgICBhMTMgPSBhWzddO1xuICB2YXIgYTIwID0gYVs4XSxcbiAgICAgIGEyMSA9IGFbOV0sXG4gICAgICBhMjIgPSBhWzEwXSxcbiAgICAgIGEyMyA9IGFbMTFdO1xuICB2YXIgYTMwID0gYVsxMl0sXG4gICAgICBhMzEgPSBhWzEzXSxcbiAgICAgIGEzMiA9IGFbMTRdLFxuICAgICAgYTMzID0gYVsxNV07XG4gIHZhciBiMDAgPSBhMDAgKiBhMTEgLSBhMDEgKiBhMTA7XG4gIHZhciBiMDEgPSBhMDAgKiBhMTIgLSBhMDIgKiBhMTA7XG4gIHZhciBiMDIgPSBhMDAgKiBhMTMgLSBhMDMgKiBhMTA7XG4gIHZhciBiMDMgPSBhMDEgKiBhMTIgLSBhMDIgKiBhMTE7XG4gIHZhciBiMDQgPSBhMDEgKiBhMTMgLSBhMDMgKiBhMTE7XG4gIHZhciBiMDUgPSBhMDIgKiBhMTMgLSBhMDMgKiBhMTI7XG4gIHZhciBiMDYgPSBhMjAgKiBhMzEgLSBhMjEgKiBhMzA7XG4gIHZhciBiMDcgPSBhMjAgKiBhMzIgLSBhMjIgKiBhMzA7XG4gIHZhciBiMDggPSBhMjAgKiBhMzMgLSBhMjMgKiBhMzA7XG4gIHZhciBiMDkgPSBhMjEgKiBhMzIgLSBhMjIgKiBhMzE7XG4gIHZhciBiMTAgPSBhMjEgKiBhMzMgLSBhMjMgKiBhMzE7XG4gIHZhciBiMTEgPSBhMjIgKiBhMzMgLSBhMjMgKiBhMzI7IC8vIENhbGN1bGF0ZSB0aGUgZGV0ZXJtaW5hbnRcblxuICByZXR1cm4gYjAwICogYjExIC0gYjAxICogYjEwICsgYjAyICogYjA5ICsgYjAzICogYjA4IC0gYjA0ICogYjA3ICsgYjA1ICogYjA2O1xufVxuLyoqXG4gKiBNdWx0aXBsaWVzIHR3byBtYXQ0c1xuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG11bHRpcGx5KG91dCwgYSwgYikge1xuICB2YXIgYTAwID0gYVswXSxcbiAgICAgIGEwMSA9IGFbMV0sXG4gICAgICBhMDIgPSBhWzJdLFxuICAgICAgYTAzID0gYVszXTtcbiAgdmFyIGExMCA9IGFbNF0sXG4gICAgICBhMTEgPSBhWzVdLFxuICAgICAgYTEyID0gYVs2XSxcbiAgICAgIGExMyA9IGFbN107XG4gIHZhciBhMjAgPSBhWzhdLFxuICAgICAgYTIxID0gYVs5XSxcbiAgICAgIGEyMiA9IGFbMTBdLFxuICAgICAgYTIzID0gYVsxMV07XG4gIHZhciBhMzAgPSBhWzEyXSxcbiAgICAgIGEzMSA9IGFbMTNdLFxuICAgICAgYTMyID0gYVsxNF0sXG4gICAgICBhMzMgPSBhWzE1XTsgLy8gQ2FjaGUgb25seSB0aGUgY3VycmVudCBsaW5lIG9mIHRoZSBzZWNvbmQgbWF0cml4XG5cbiAgdmFyIGIwID0gYlswXSxcbiAgICAgIGIxID0gYlsxXSxcbiAgICAgIGIyID0gYlsyXSxcbiAgICAgIGIzID0gYlszXTtcbiAgb3V0WzBdID0gYjAgKiBhMDAgKyBiMSAqIGExMCArIGIyICogYTIwICsgYjMgKiBhMzA7XG4gIG91dFsxXSA9IGIwICogYTAxICsgYjEgKiBhMTEgKyBiMiAqIGEyMSArIGIzICogYTMxO1xuICBvdXRbMl0gPSBiMCAqIGEwMiArIGIxICogYTEyICsgYjIgKiBhMjIgKyBiMyAqIGEzMjtcbiAgb3V0WzNdID0gYjAgKiBhMDMgKyBiMSAqIGExMyArIGIyICogYTIzICsgYjMgKiBhMzM7XG4gIGIwID0gYls0XTtcbiAgYjEgPSBiWzVdO1xuICBiMiA9IGJbNl07XG4gIGIzID0gYls3XTtcbiAgb3V0WzRdID0gYjAgKiBhMDAgKyBiMSAqIGExMCArIGIyICogYTIwICsgYjMgKiBhMzA7XG4gIG91dFs1XSA9IGIwICogYTAxICsgYjEgKiBhMTEgKyBiMiAqIGEyMSArIGIzICogYTMxO1xuICBvdXRbNl0gPSBiMCAqIGEwMiArIGIxICogYTEyICsgYjIgKiBhMjIgKyBiMyAqIGEzMjtcbiAgb3V0WzddID0gYjAgKiBhMDMgKyBiMSAqIGExMyArIGIyICogYTIzICsgYjMgKiBhMzM7XG4gIGIwID0gYls4XTtcbiAgYjEgPSBiWzldO1xuICBiMiA9IGJbMTBdO1xuICBiMyA9IGJbMTFdO1xuICBvdXRbOF0gPSBiMCAqIGEwMCArIGIxICogYTEwICsgYjIgKiBhMjAgKyBiMyAqIGEzMDtcbiAgb3V0WzldID0gYjAgKiBhMDEgKyBiMSAqIGExMSArIGIyICogYTIxICsgYjMgKiBhMzE7XG4gIG91dFsxMF0gPSBiMCAqIGEwMiArIGIxICogYTEyICsgYjIgKiBhMjIgKyBiMyAqIGEzMjtcbiAgb3V0WzExXSA9IGIwICogYTAzICsgYjEgKiBhMTMgKyBiMiAqIGEyMyArIGIzICogYTMzO1xuICBiMCA9IGJbMTJdO1xuICBiMSA9IGJbMTNdO1xuICBiMiA9IGJbMTRdO1xuICBiMyA9IGJbMTVdO1xuICBvdXRbMTJdID0gYjAgKiBhMDAgKyBiMSAqIGExMCArIGIyICogYTIwICsgYjMgKiBhMzA7XG4gIG91dFsxM10gPSBiMCAqIGEwMSArIGIxICogYTExICsgYjIgKiBhMjEgKyBiMyAqIGEzMTtcbiAgb3V0WzE0XSA9IGIwICogYTAyICsgYjEgKiBhMTIgKyBiMiAqIGEyMiArIGIzICogYTMyO1xuICBvdXRbMTVdID0gYjAgKiBhMDMgKyBiMSAqIGExMyArIGIyICogYTIzICsgYjMgKiBhMzM7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFRyYW5zbGF0ZSBhIG1hdDQgYnkgdGhlIGdpdmVuIHZlY3RvclxuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYSB0aGUgbWF0cml4IHRvIHRyYW5zbGF0ZVxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IHYgdmVjdG9yIHRvIHRyYW5zbGF0ZSBieVxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2xhdGUob3V0LCBhLCB2KSB7XG4gIHZhciB4ID0gdlswXSxcbiAgICAgIHkgPSB2WzFdLFxuICAgICAgeiA9IHZbMl07XG4gIHZhciBhMDAsIGEwMSwgYTAyLCBhMDM7XG4gIHZhciBhMTAsIGExMSwgYTEyLCBhMTM7XG4gIHZhciBhMjAsIGEyMSwgYTIyLCBhMjM7XG5cbiAgaWYgKGEgPT09IG91dCkge1xuICAgIG91dFsxMl0gPSBhWzBdICogeCArIGFbNF0gKiB5ICsgYVs4XSAqIHogKyBhWzEyXTtcbiAgICBvdXRbMTNdID0gYVsxXSAqIHggKyBhWzVdICogeSArIGFbOV0gKiB6ICsgYVsxM107XG4gICAgb3V0WzE0XSA9IGFbMl0gKiB4ICsgYVs2XSAqIHkgKyBhWzEwXSAqIHogKyBhWzE0XTtcbiAgICBvdXRbMTVdID0gYVszXSAqIHggKyBhWzddICogeSArIGFbMTFdICogeiArIGFbMTVdO1xuICB9IGVsc2Uge1xuICAgIGEwMCA9IGFbMF07XG4gICAgYTAxID0gYVsxXTtcbiAgICBhMDIgPSBhWzJdO1xuICAgIGEwMyA9IGFbM107XG4gICAgYTEwID0gYVs0XTtcbiAgICBhMTEgPSBhWzVdO1xuICAgIGExMiA9IGFbNl07XG4gICAgYTEzID0gYVs3XTtcbiAgICBhMjAgPSBhWzhdO1xuICAgIGEyMSA9IGFbOV07XG4gICAgYTIyID0gYVsxMF07XG4gICAgYTIzID0gYVsxMV07XG4gICAgb3V0WzBdID0gYTAwO1xuICAgIG91dFsxXSA9IGEwMTtcbiAgICBvdXRbMl0gPSBhMDI7XG4gICAgb3V0WzNdID0gYTAzO1xuICAgIG91dFs0XSA9IGExMDtcbiAgICBvdXRbNV0gPSBhMTE7XG4gICAgb3V0WzZdID0gYTEyO1xuICAgIG91dFs3XSA9IGExMztcbiAgICBvdXRbOF0gPSBhMjA7XG4gICAgb3V0WzldID0gYTIxO1xuICAgIG91dFsxMF0gPSBhMjI7XG4gICAgb3V0WzExXSA9IGEyMztcbiAgICBvdXRbMTJdID0gYTAwICogeCArIGExMCAqIHkgKyBhMjAgKiB6ICsgYVsxMl07XG4gICAgb3V0WzEzXSA9IGEwMSAqIHggKyBhMTEgKiB5ICsgYTIxICogeiArIGFbMTNdO1xuICAgIG91dFsxNF0gPSBhMDIgKiB4ICsgYTEyICogeSArIGEyMiAqIHogKyBhWzE0XTtcbiAgICBvdXRbMTVdID0gYTAzICogeCArIGExMyAqIHkgKyBhMjMgKiB6ICsgYVsxNV07XG4gIH1cblxuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBTY2FsZXMgdGhlIG1hdDQgYnkgdGhlIGRpbWVuc2lvbnMgaW4gdGhlIGdpdmVuIHZlYzMgbm90IHVzaW5nIHZlY3Rvcml6YXRpb25cbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGEgdGhlIG1hdHJpeCB0byBzY2FsZVxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IHYgdGhlIHZlYzMgdG8gc2NhbGUgdGhlIG1hdHJpeCBieVxuICogQHJldHVybnMge21hdDR9IG91dFxuICoqL1xuXG5leHBvcnQgZnVuY3Rpb24gc2NhbGUob3V0LCBhLCB2KSB7XG4gIHZhciB4ID0gdlswXSxcbiAgICAgIHkgPSB2WzFdLFxuICAgICAgeiA9IHZbMl07XG4gIG91dFswXSA9IGFbMF0gKiB4O1xuICBvdXRbMV0gPSBhWzFdICogeDtcbiAgb3V0WzJdID0gYVsyXSAqIHg7XG4gIG91dFszXSA9IGFbM10gKiB4O1xuICBvdXRbNF0gPSBhWzRdICogeTtcbiAgb3V0WzVdID0gYVs1XSAqIHk7XG4gIG91dFs2XSA9IGFbNl0gKiB5O1xuICBvdXRbN10gPSBhWzddICogeTtcbiAgb3V0WzhdID0gYVs4XSAqIHo7XG4gIG91dFs5XSA9IGFbOV0gKiB6O1xuICBvdXRbMTBdID0gYVsxMF0gKiB6O1xuICBvdXRbMTFdID0gYVsxMV0gKiB6O1xuICBvdXRbMTJdID0gYVsxMl07XG4gIG91dFsxM10gPSBhWzEzXTtcbiAgb3V0WzE0XSA9IGFbMTRdO1xuICBvdXRbMTVdID0gYVsxNV07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFJvdGF0ZXMgYSBtYXQ0IGJ5IHRoZSBnaXZlbiBhbmdsZSBhcm91bmQgdGhlIGdpdmVuIGF4aXNcbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGEgdGhlIG1hdHJpeCB0byByb3RhdGVcbiAqIEBwYXJhbSB7TnVtYmVyfSByYWQgdGhlIGFuZ2xlIHRvIHJvdGF0ZSB0aGUgbWF0cml4IGJ5XG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYXhpcyB0aGUgYXhpcyB0byByb3RhdGUgYXJvdW5kXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJvdGF0ZShvdXQsIGEsIHJhZCwgYXhpcykge1xuICB2YXIgeCA9IGF4aXNbMF0sXG4gICAgICB5ID0gYXhpc1sxXSxcbiAgICAgIHogPSBheGlzWzJdO1xuICB2YXIgbGVuID0gTWF0aC5oeXBvdCh4LCB5LCB6KTtcbiAgdmFyIHMsIGMsIHQ7XG4gIHZhciBhMDAsIGEwMSwgYTAyLCBhMDM7XG4gIHZhciBhMTAsIGExMSwgYTEyLCBhMTM7XG4gIHZhciBhMjAsIGEyMSwgYTIyLCBhMjM7XG4gIHZhciBiMDAsIGIwMSwgYjAyO1xuICB2YXIgYjEwLCBiMTEsIGIxMjtcbiAgdmFyIGIyMCwgYjIxLCBiMjI7XG5cbiAgaWYgKGxlbiA8IGdsTWF0cml4LkVQU0lMT04pIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGxlbiA9IDEgLyBsZW47XG4gIHggKj0gbGVuO1xuICB5ICo9IGxlbjtcbiAgeiAqPSBsZW47XG4gIHMgPSBNYXRoLnNpbihyYWQpO1xuICBjID0gTWF0aC5jb3MocmFkKTtcbiAgdCA9IDEgLSBjO1xuICBhMDAgPSBhWzBdO1xuICBhMDEgPSBhWzFdO1xuICBhMDIgPSBhWzJdO1xuICBhMDMgPSBhWzNdO1xuICBhMTAgPSBhWzRdO1xuICBhMTEgPSBhWzVdO1xuICBhMTIgPSBhWzZdO1xuICBhMTMgPSBhWzddO1xuICBhMjAgPSBhWzhdO1xuICBhMjEgPSBhWzldO1xuICBhMjIgPSBhWzEwXTtcbiAgYTIzID0gYVsxMV07IC8vIENvbnN0cnVjdCB0aGUgZWxlbWVudHMgb2YgdGhlIHJvdGF0aW9uIG1hdHJpeFxuXG4gIGIwMCA9IHggKiB4ICogdCArIGM7XG4gIGIwMSA9IHkgKiB4ICogdCArIHogKiBzO1xuICBiMDIgPSB6ICogeCAqIHQgLSB5ICogcztcbiAgYjEwID0geCAqIHkgKiB0IC0geiAqIHM7XG4gIGIxMSA9IHkgKiB5ICogdCArIGM7XG4gIGIxMiA9IHogKiB5ICogdCArIHggKiBzO1xuICBiMjAgPSB4ICogeiAqIHQgKyB5ICogcztcbiAgYjIxID0geSAqIHogKiB0IC0geCAqIHM7XG4gIGIyMiA9IHogKiB6ICogdCArIGM7IC8vIFBlcmZvcm0gcm90YXRpb24tc3BlY2lmaWMgbWF0cml4IG11bHRpcGxpY2F0aW9uXG5cbiAgb3V0WzBdID0gYTAwICogYjAwICsgYTEwICogYjAxICsgYTIwICogYjAyO1xuICBvdXRbMV0gPSBhMDEgKiBiMDAgKyBhMTEgKiBiMDEgKyBhMjEgKiBiMDI7XG4gIG91dFsyXSA9IGEwMiAqIGIwMCArIGExMiAqIGIwMSArIGEyMiAqIGIwMjtcbiAgb3V0WzNdID0gYTAzICogYjAwICsgYTEzICogYjAxICsgYTIzICogYjAyO1xuICBvdXRbNF0gPSBhMDAgKiBiMTAgKyBhMTAgKiBiMTEgKyBhMjAgKiBiMTI7XG4gIG91dFs1XSA9IGEwMSAqIGIxMCArIGExMSAqIGIxMSArIGEyMSAqIGIxMjtcbiAgb3V0WzZdID0gYTAyICogYjEwICsgYTEyICogYjExICsgYTIyICogYjEyO1xuICBvdXRbN10gPSBhMDMgKiBiMTAgKyBhMTMgKiBiMTEgKyBhMjMgKiBiMTI7XG4gIG91dFs4XSA9IGEwMCAqIGIyMCArIGExMCAqIGIyMSArIGEyMCAqIGIyMjtcbiAgb3V0WzldID0gYTAxICogYjIwICsgYTExICogYjIxICsgYTIxICogYjIyO1xuICBvdXRbMTBdID0gYTAyICogYjIwICsgYTEyICogYjIxICsgYTIyICogYjIyO1xuICBvdXRbMTFdID0gYTAzICogYjIwICsgYTEzICogYjIxICsgYTIzICogYjIyO1xuXG4gIGlmIChhICE9PSBvdXQpIHtcbiAgICAvLyBJZiB0aGUgc291cmNlIGFuZCBkZXN0aW5hdGlvbiBkaWZmZXIsIGNvcHkgdGhlIHVuY2hhbmdlZCBsYXN0IHJvd1xuICAgIG91dFsxMl0gPSBhWzEyXTtcbiAgICBvdXRbMTNdID0gYVsxM107XG4gICAgb3V0WzE0XSA9IGFbMTRdO1xuICAgIG91dFsxNV0gPSBhWzE1XTtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFJvdGF0ZXMgYSBtYXRyaXggYnkgdGhlIGdpdmVuIGFuZ2xlIGFyb3VuZCB0aGUgWCBheGlzXG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhIHRoZSBtYXRyaXggdG8gcm90YXRlXG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIHRoZSBhbmdsZSB0byByb3RhdGUgdGhlIG1hdHJpeCBieVxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByb3RhdGVYKG91dCwgYSwgcmFkKSB7XG4gIHZhciBzID0gTWF0aC5zaW4ocmFkKTtcbiAgdmFyIGMgPSBNYXRoLmNvcyhyYWQpO1xuICB2YXIgYTEwID0gYVs0XTtcbiAgdmFyIGExMSA9IGFbNV07XG4gIHZhciBhMTIgPSBhWzZdO1xuICB2YXIgYTEzID0gYVs3XTtcbiAgdmFyIGEyMCA9IGFbOF07XG4gIHZhciBhMjEgPSBhWzldO1xuICB2YXIgYTIyID0gYVsxMF07XG4gIHZhciBhMjMgPSBhWzExXTtcblxuICBpZiAoYSAhPT0gb3V0KSB7XG4gICAgLy8gSWYgdGhlIHNvdXJjZSBhbmQgZGVzdGluYXRpb24gZGlmZmVyLCBjb3B5IHRoZSB1bmNoYW5nZWQgcm93c1xuICAgIG91dFswXSA9IGFbMF07XG4gICAgb3V0WzFdID0gYVsxXTtcbiAgICBvdXRbMl0gPSBhWzJdO1xuICAgIG91dFszXSA9IGFbM107XG4gICAgb3V0WzEyXSA9IGFbMTJdO1xuICAgIG91dFsxM10gPSBhWzEzXTtcbiAgICBvdXRbMTRdID0gYVsxNF07XG4gICAgb3V0WzE1XSA9IGFbMTVdO1xuICB9IC8vIFBlcmZvcm0gYXhpcy1zcGVjaWZpYyBtYXRyaXggbXVsdGlwbGljYXRpb25cblxuXG4gIG91dFs0XSA9IGExMCAqIGMgKyBhMjAgKiBzO1xuICBvdXRbNV0gPSBhMTEgKiBjICsgYTIxICogcztcbiAgb3V0WzZdID0gYTEyICogYyArIGEyMiAqIHM7XG4gIG91dFs3XSA9IGExMyAqIGMgKyBhMjMgKiBzO1xuICBvdXRbOF0gPSBhMjAgKiBjIC0gYTEwICogcztcbiAgb3V0WzldID0gYTIxICogYyAtIGExMSAqIHM7XG4gIG91dFsxMF0gPSBhMjIgKiBjIC0gYTEyICogcztcbiAgb3V0WzExXSA9IGEyMyAqIGMgLSBhMTMgKiBzO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBSb3RhdGVzIGEgbWF0cml4IGJ5IHRoZSBnaXZlbiBhbmdsZSBhcm91bmQgdGhlIFkgYXhpc1xuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYSB0aGUgbWF0cml4IHRvIHJvdGF0ZVxuICogQHBhcmFtIHtOdW1iZXJ9IHJhZCB0aGUgYW5nbGUgdG8gcm90YXRlIHRoZSBtYXRyaXggYnlcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcm90YXRlWShvdXQsIGEsIHJhZCkge1xuICB2YXIgcyA9IE1hdGguc2luKHJhZCk7XG4gIHZhciBjID0gTWF0aC5jb3MocmFkKTtcbiAgdmFyIGEwMCA9IGFbMF07XG4gIHZhciBhMDEgPSBhWzFdO1xuICB2YXIgYTAyID0gYVsyXTtcbiAgdmFyIGEwMyA9IGFbM107XG4gIHZhciBhMjAgPSBhWzhdO1xuICB2YXIgYTIxID0gYVs5XTtcbiAgdmFyIGEyMiA9IGFbMTBdO1xuICB2YXIgYTIzID0gYVsxMV07XG5cbiAgaWYgKGEgIT09IG91dCkge1xuICAgIC8vIElmIHRoZSBzb3VyY2UgYW5kIGRlc3RpbmF0aW9uIGRpZmZlciwgY29weSB0aGUgdW5jaGFuZ2VkIHJvd3NcbiAgICBvdXRbNF0gPSBhWzRdO1xuICAgIG91dFs1XSA9IGFbNV07XG4gICAgb3V0WzZdID0gYVs2XTtcbiAgICBvdXRbN10gPSBhWzddO1xuICAgIG91dFsxMl0gPSBhWzEyXTtcbiAgICBvdXRbMTNdID0gYVsxM107XG4gICAgb3V0WzE0XSA9IGFbMTRdO1xuICAgIG91dFsxNV0gPSBhWzE1XTtcbiAgfSAvLyBQZXJmb3JtIGF4aXMtc3BlY2lmaWMgbWF0cml4IG11bHRpcGxpY2F0aW9uXG5cblxuICBvdXRbMF0gPSBhMDAgKiBjIC0gYTIwICogcztcbiAgb3V0WzFdID0gYTAxICogYyAtIGEyMSAqIHM7XG4gIG91dFsyXSA9IGEwMiAqIGMgLSBhMjIgKiBzO1xuICBvdXRbM10gPSBhMDMgKiBjIC0gYTIzICogcztcbiAgb3V0WzhdID0gYTAwICogcyArIGEyMCAqIGM7XG4gIG91dFs5XSA9IGEwMSAqIHMgKyBhMjEgKiBjO1xuICBvdXRbMTBdID0gYTAyICogcyArIGEyMiAqIGM7XG4gIG91dFsxMV0gPSBhMDMgKiBzICsgYTIzICogYztcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUm90YXRlcyBhIG1hdHJpeCBieSB0aGUgZ2l2ZW4gYW5nbGUgYXJvdW5kIHRoZSBaIGF4aXNcbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGEgdGhlIG1hdHJpeCB0byByb3RhdGVcbiAqIEBwYXJhbSB7TnVtYmVyfSByYWQgdGhlIGFuZ2xlIHRvIHJvdGF0ZSB0aGUgbWF0cml4IGJ5XG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJvdGF0ZVoob3V0LCBhLCByYWQpIHtcbiAgdmFyIHMgPSBNYXRoLnNpbihyYWQpO1xuICB2YXIgYyA9IE1hdGguY29zKHJhZCk7XG4gIHZhciBhMDAgPSBhWzBdO1xuICB2YXIgYTAxID0gYVsxXTtcbiAgdmFyIGEwMiA9IGFbMl07XG4gIHZhciBhMDMgPSBhWzNdO1xuICB2YXIgYTEwID0gYVs0XTtcbiAgdmFyIGExMSA9IGFbNV07XG4gIHZhciBhMTIgPSBhWzZdO1xuICB2YXIgYTEzID0gYVs3XTtcblxuICBpZiAoYSAhPT0gb3V0KSB7XG4gICAgLy8gSWYgdGhlIHNvdXJjZSBhbmQgZGVzdGluYXRpb24gZGlmZmVyLCBjb3B5IHRoZSB1bmNoYW5nZWQgbGFzdCByb3dcbiAgICBvdXRbOF0gPSBhWzhdO1xuICAgIG91dFs5XSA9IGFbOV07XG4gICAgb3V0WzEwXSA9IGFbMTBdO1xuICAgIG91dFsxMV0gPSBhWzExXTtcbiAgICBvdXRbMTJdID0gYVsxMl07XG4gICAgb3V0WzEzXSA9IGFbMTNdO1xuICAgIG91dFsxNF0gPSBhWzE0XTtcbiAgICBvdXRbMTVdID0gYVsxNV07XG4gIH0gLy8gUGVyZm9ybSBheGlzLXNwZWNpZmljIG1hdHJpeCBtdWx0aXBsaWNhdGlvblxuXG5cbiAgb3V0WzBdID0gYTAwICogYyArIGExMCAqIHM7XG4gIG91dFsxXSA9IGEwMSAqIGMgKyBhMTEgKiBzO1xuICBvdXRbMl0gPSBhMDIgKiBjICsgYTEyICogcztcbiAgb3V0WzNdID0gYTAzICogYyArIGExMyAqIHM7XG4gIG91dFs0XSA9IGExMCAqIGMgLSBhMDAgKiBzO1xuICBvdXRbNV0gPSBhMTEgKiBjIC0gYTAxICogcztcbiAgb3V0WzZdID0gYTEyICogYyAtIGEwMiAqIHM7XG4gIG91dFs3XSA9IGExMyAqIGMgLSBhMDMgKiBzO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgbWF0cml4IGZyb20gYSB2ZWN0b3IgdHJhbnNsYXRpb25cbiAqIFRoaXMgaXMgZXF1aXZhbGVudCB0byAoYnV0IG11Y2ggZmFzdGVyIHRoYW4pOlxuICpcbiAqICAgICBtYXQ0LmlkZW50aXR5KGRlc3QpO1xuICogICAgIG1hdDQudHJhbnNsYXRlKGRlc3QsIGRlc3QsIHZlYyk7XG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgbWF0NCByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IHYgVHJhbnNsYXRpb24gdmVjdG9yXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21UcmFuc2xhdGlvbihvdXQsIHYpIHtcbiAgb3V0WzBdID0gMTtcbiAgb3V0WzFdID0gMDtcbiAgb3V0WzJdID0gMDtcbiAgb3V0WzNdID0gMDtcbiAgb3V0WzRdID0gMDtcbiAgb3V0WzVdID0gMTtcbiAgb3V0WzZdID0gMDtcbiAgb3V0WzddID0gMDtcbiAgb3V0WzhdID0gMDtcbiAgb3V0WzldID0gMDtcbiAgb3V0WzEwXSA9IDE7XG4gIG91dFsxMV0gPSAwO1xuICBvdXRbMTJdID0gdlswXTtcbiAgb3V0WzEzXSA9IHZbMV07XG4gIG91dFsxNF0gPSB2WzJdO1xuICBvdXRbMTVdID0gMTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIG1hdHJpeCBmcm9tIGEgdmVjdG9yIHNjYWxpbmdcbiAqIFRoaXMgaXMgZXF1aXZhbGVudCB0byAoYnV0IG11Y2ggZmFzdGVyIHRoYW4pOlxuICpcbiAqICAgICBtYXQ0LmlkZW50aXR5KGRlc3QpO1xuICogICAgIG1hdDQuc2NhbGUoZGVzdCwgZGVzdCwgdmVjKTtcbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gdiBTY2FsaW5nIHZlY3RvclxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9tU2NhbGluZyhvdXQsIHYpIHtcbiAgb3V0WzBdID0gdlswXTtcbiAgb3V0WzFdID0gMDtcbiAgb3V0WzJdID0gMDtcbiAgb3V0WzNdID0gMDtcbiAgb3V0WzRdID0gMDtcbiAgb3V0WzVdID0gdlsxXTtcbiAgb3V0WzZdID0gMDtcbiAgb3V0WzddID0gMDtcbiAgb3V0WzhdID0gMDtcbiAgb3V0WzldID0gMDtcbiAgb3V0WzEwXSA9IHZbMl07XG4gIG91dFsxMV0gPSAwO1xuICBvdXRbMTJdID0gMDtcbiAgb3V0WzEzXSA9IDA7XG4gIG91dFsxNF0gPSAwO1xuICBvdXRbMTVdID0gMTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIG1hdHJpeCBmcm9tIGEgZ2l2ZW4gYW5nbGUgYXJvdW5kIGEgZ2l2ZW4gYXhpc1xuICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIChidXQgbXVjaCBmYXN0ZXIgdGhhbik6XG4gKlxuICogICAgIG1hdDQuaWRlbnRpdHkoZGVzdCk7XG4gKiAgICAgbWF0NC5yb3RhdGUoZGVzdCwgZGVzdCwgcmFkLCBheGlzKTtcbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIHRoZSBhbmdsZSB0byByb3RhdGUgdGhlIG1hdHJpeCBieVxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGF4aXMgdGhlIGF4aXMgdG8gcm90YXRlIGFyb3VuZFxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9tUm90YXRpb24ob3V0LCByYWQsIGF4aXMpIHtcbiAgdmFyIHggPSBheGlzWzBdLFxuICAgICAgeSA9IGF4aXNbMV0sXG4gICAgICB6ID0gYXhpc1syXTtcbiAgdmFyIGxlbiA9IE1hdGguaHlwb3QoeCwgeSwgeik7XG4gIHZhciBzLCBjLCB0O1xuXG4gIGlmIChsZW4gPCBnbE1hdHJpeC5FUFNJTE9OKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBsZW4gPSAxIC8gbGVuO1xuICB4ICo9IGxlbjtcbiAgeSAqPSBsZW47XG4gIHogKj0gbGVuO1xuICBzID0gTWF0aC5zaW4ocmFkKTtcbiAgYyA9IE1hdGguY29zKHJhZCk7XG4gIHQgPSAxIC0gYzsgLy8gUGVyZm9ybSByb3RhdGlvbi1zcGVjaWZpYyBtYXRyaXggbXVsdGlwbGljYXRpb25cblxuICBvdXRbMF0gPSB4ICogeCAqIHQgKyBjO1xuICBvdXRbMV0gPSB5ICogeCAqIHQgKyB6ICogcztcbiAgb3V0WzJdID0geiAqIHggKiB0IC0geSAqIHM7XG4gIG91dFszXSA9IDA7XG4gIG91dFs0XSA9IHggKiB5ICogdCAtIHogKiBzO1xuICBvdXRbNV0gPSB5ICogeSAqIHQgKyBjO1xuICBvdXRbNl0gPSB6ICogeSAqIHQgKyB4ICogcztcbiAgb3V0WzddID0gMDtcbiAgb3V0WzhdID0geCAqIHogKiB0ICsgeSAqIHM7XG4gIG91dFs5XSA9IHkgKiB6ICogdCAtIHggKiBzO1xuICBvdXRbMTBdID0geiAqIHogKiB0ICsgYztcbiAgb3V0WzExXSA9IDA7XG4gIG91dFsxMl0gPSAwO1xuICBvdXRbMTNdID0gMDtcbiAgb3V0WzE0XSA9IDA7XG4gIG91dFsxNV0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgbWF0cml4IGZyb20gdGhlIGdpdmVuIGFuZ2xlIGFyb3VuZCB0aGUgWCBheGlzXG4gKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gKGJ1dCBtdWNoIGZhc3RlciB0aGFuKTpcbiAqXG4gKiAgICAgbWF0NC5pZGVudGl0eShkZXN0KTtcbiAqICAgICBtYXQ0LnJvdGF0ZVgoZGVzdCwgZGVzdCwgcmFkKTtcbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIHRoZSBhbmdsZSB0byByb3RhdGUgdGhlIG1hdHJpeCBieVxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9tWFJvdGF0aW9uKG91dCwgcmFkKSB7XG4gIHZhciBzID0gTWF0aC5zaW4ocmFkKTtcbiAgdmFyIGMgPSBNYXRoLmNvcyhyYWQpOyAvLyBQZXJmb3JtIGF4aXMtc3BlY2lmaWMgbWF0cml4IG11bHRpcGxpY2F0aW9uXG5cbiAgb3V0WzBdID0gMTtcbiAgb3V0WzFdID0gMDtcbiAgb3V0WzJdID0gMDtcbiAgb3V0WzNdID0gMDtcbiAgb3V0WzRdID0gMDtcbiAgb3V0WzVdID0gYztcbiAgb3V0WzZdID0gcztcbiAgb3V0WzddID0gMDtcbiAgb3V0WzhdID0gMDtcbiAgb3V0WzldID0gLXM7XG4gIG91dFsxMF0gPSBjO1xuICBvdXRbMTFdID0gMDtcbiAgb3V0WzEyXSA9IDA7XG4gIG91dFsxM10gPSAwO1xuICBvdXRbMTRdID0gMDtcbiAgb3V0WzE1XSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENyZWF0ZXMgYSBtYXRyaXggZnJvbSB0aGUgZ2l2ZW4gYW5nbGUgYXJvdW5kIHRoZSBZIGF4aXNcbiAqIFRoaXMgaXMgZXF1aXZhbGVudCB0byAoYnV0IG11Y2ggZmFzdGVyIHRoYW4pOlxuICpcbiAqICAgICBtYXQ0LmlkZW50aXR5KGRlc3QpO1xuICogICAgIG1hdDQucm90YXRlWShkZXN0LCBkZXN0LCByYWQpO1xuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IG1hdDQgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBwYXJhbSB7TnVtYmVyfSByYWQgdGhlIGFuZ2xlIHRvIHJvdGF0ZSB0aGUgbWF0cml4IGJ5XG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21ZUm90YXRpb24ob3V0LCByYWQpIHtcbiAgdmFyIHMgPSBNYXRoLnNpbihyYWQpO1xuICB2YXIgYyA9IE1hdGguY29zKHJhZCk7IC8vIFBlcmZvcm0gYXhpcy1zcGVjaWZpYyBtYXRyaXggbXVsdGlwbGljYXRpb25cblxuICBvdXRbMF0gPSBjO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAtcztcbiAgb3V0WzNdID0gMDtcbiAgb3V0WzRdID0gMDtcbiAgb3V0WzVdID0gMTtcbiAgb3V0WzZdID0gMDtcbiAgb3V0WzddID0gMDtcbiAgb3V0WzhdID0gcztcbiAgb3V0WzldID0gMDtcbiAgb3V0WzEwXSA9IGM7XG4gIG91dFsxMV0gPSAwO1xuICBvdXRbMTJdID0gMDtcbiAgb3V0WzEzXSA9IDA7XG4gIG91dFsxNF0gPSAwO1xuICBvdXRbMTVdID0gMTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIG1hdHJpeCBmcm9tIHRoZSBnaXZlbiBhbmdsZSBhcm91bmQgdGhlIFogYXhpc1xuICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIChidXQgbXVjaCBmYXN0ZXIgdGhhbik6XG4gKlxuICogICAgIG1hdDQuaWRlbnRpdHkoZGVzdCk7XG4gKiAgICAgbWF0NC5yb3RhdGVaKGRlc3QsIGRlc3QsIHJhZCk7XG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgbWF0NCByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxuICogQHBhcmFtIHtOdW1iZXJ9IHJhZCB0aGUgYW5nbGUgdG8gcm90YXRlIHRoZSBtYXRyaXggYnlcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbVpSb3RhdGlvbihvdXQsIHJhZCkge1xuICB2YXIgcyA9IE1hdGguc2luKHJhZCk7XG4gIHZhciBjID0gTWF0aC5jb3MocmFkKTsgLy8gUGVyZm9ybSBheGlzLXNwZWNpZmljIG1hdHJpeCBtdWx0aXBsaWNhdGlvblxuXG4gIG91dFswXSA9IGM7XG4gIG91dFsxXSA9IHM7XG4gIG91dFsyXSA9IDA7XG4gIG91dFszXSA9IDA7XG4gIG91dFs0XSA9IC1zO1xuICBvdXRbNV0gPSBjO1xuICBvdXRbNl0gPSAwO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSAwO1xuICBvdXRbOV0gPSAwO1xuICBvdXRbMTBdID0gMTtcbiAgb3V0WzExXSA9IDA7XG4gIG91dFsxMl0gPSAwO1xuICBvdXRbMTNdID0gMDtcbiAgb3V0WzE0XSA9IDA7XG4gIG91dFsxNV0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgbWF0cml4IGZyb20gYSBxdWF0ZXJuaW9uIHJvdGF0aW9uIGFuZCB2ZWN0b3IgdHJhbnNsYXRpb25cbiAqIFRoaXMgaXMgZXF1aXZhbGVudCB0byAoYnV0IG11Y2ggZmFzdGVyIHRoYW4pOlxuICpcbiAqICAgICBtYXQ0LmlkZW50aXR5KGRlc3QpO1xuICogICAgIG1hdDQudHJhbnNsYXRlKGRlc3QsIHZlYyk7XG4gKiAgICAgbGV0IHF1YXRNYXQgPSBtYXQ0LmNyZWF0ZSgpO1xuICogICAgIHF1YXQ0LnRvTWF0NChxdWF0LCBxdWF0TWF0KTtcbiAqICAgICBtYXQ0Lm11bHRpcGx5KGRlc3QsIHF1YXRNYXQpO1xuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IG1hdDQgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBwYXJhbSB7cXVhdDR9IHEgUm90YXRpb24gcXVhdGVybmlvblxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IHYgVHJhbnNsYXRpb24gdmVjdG9yXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21Sb3RhdGlvblRyYW5zbGF0aW9uKG91dCwgcSwgdikge1xuICAvLyBRdWF0ZXJuaW9uIG1hdGhcbiAgdmFyIHggPSBxWzBdLFxuICAgICAgeSA9IHFbMV0sXG4gICAgICB6ID0gcVsyXSxcbiAgICAgIHcgPSBxWzNdO1xuICB2YXIgeDIgPSB4ICsgeDtcbiAgdmFyIHkyID0geSArIHk7XG4gIHZhciB6MiA9IHogKyB6O1xuICB2YXIgeHggPSB4ICogeDI7XG4gIHZhciB4eSA9IHggKiB5MjtcbiAgdmFyIHh6ID0geCAqIHoyO1xuICB2YXIgeXkgPSB5ICogeTI7XG4gIHZhciB5eiA9IHkgKiB6MjtcbiAgdmFyIHp6ID0geiAqIHoyO1xuICB2YXIgd3ggPSB3ICogeDI7XG4gIHZhciB3eSA9IHcgKiB5MjtcbiAgdmFyIHd6ID0gdyAqIHoyO1xuICBvdXRbMF0gPSAxIC0gKHl5ICsgenopO1xuICBvdXRbMV0gPSB4eSArIHd6O1xuICBvdXRbMl0gPSB4eiAtIHd5O1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSB4eSAtIHd6O1xuICBvdXRbNV0gPSAxIC0gKHh4ICsgenopO1xuICBvdXRbNl0gPSB5eiArIHd4O1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSB4eiArIHd5O1xuICBvdXRbOV0gPSB5eiAtIHd4O1xuICBvdXRbMTBdID0gMSAtICh4eCArIHl5KTtcbiAgb3V0WzExXSA9IDA7XG4gIG91dFsxMl0gPSB2WzBdO1xuICBvdXRbMTNdID0gdlsxXTtcbiAgb3V0WzE0XSA9IHZbMl07XG4gIG91dFsxNV0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IG1hdDQgZnJvbSBhIGR1YWwgcXVhdC5cbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCBNYXRyaXhcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gYSBEdWFsIFF1YXRlcm5pb25cbiAqIEByZXR1cm5zIHttYXQ0fSBtYXQ0IHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21RdWF0MihvdXQsIGEpIHtcbiAgdmFyIHRyYW5zbGF0aW9uID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoMyk7XG4gIHZhciBieCA9IC1hWzBdLFxuICAgICAgYnkgPSAtYVsxXSxcbiAgICAgIGJ6ID0gLWFbMl0sXG4gICAgICBidyA9IGFbM10sXG4gICAgICBheCA9IGFbNF0sXG4gICAgICBheSA9IGFbNV0sXG4gICAgICBheiA9IGFbNl0sXG4gICAgICBhdyA9IGFbN107XG4gIHZhciBtYWduaXR1ZGUgPSBieCAqIGJ4ICsgYnkgKiBieSArIGJ6ICogYnogKyBidyAqIGJ3OyAvL09ubHkgc2NhbGUgaWYgaXQgbWFrZXMgc2Vuc2VcblxuICBpZiAobWFnbml0dWRlID4gMCkge1xuICAgIHRyYW5zbGF0aW9uWzBdID0gKGF4ICogYncgKyBhdyAqIGJ4ICsgYXkgKiBieiAtIGF6ICogYnkpICogMiAvIG1hZ25pdHVkZTtcbiAgICB0cmFuc2xhdGlvblsxXSA9IChheSAqIGJ3ICsgYXcgKiBieSArIGF6ICogYnggLSBheCAqIGJ6KSAqIDIgLyBtYWduaXR1ZGU7XG4gICAgdHJhbnNsYXRpb25bMl0gPSAoYXogKiBidyArIGF3ICogYnogKyBheCAqIGJ5IC0gYXkgKiBieCkgKiAyIC8gbWFnbml0dWRlO1xuICB9IGVsc2Uge1xuICAgIHRyYW5zbGF0aW9uWzBdID0gKGF4ICogYncgKyBhdyAqIGJ4ICsgYXkgKiBieiAtIGF6ICogYnkpICogMjtcbiAgICB0cmFuc2xhdGlvblsxXSA9IChheSAqIGJ3ICsgYXcgKiBieSArIGF6ICogYnggLSBheCAqIGJ6KSAqIDI7XG4gICAgdHJhbnNsYXRpb25bMl0gPSAoYXogKiBidyArIGF3ICogYnogKyBheCAqIGJ5IC0gYXkgKiBieCkgKiAyO1xuICB9XG5cbiAgZnJvbVJvdGF0aW9uVHJhbnNsYXRpb24ob3V0LCBhLCB0cmFuc2xhdGlvbik7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFJldHVybnMgdGhlIHRyYW5zbGF0aW9uIHZlY3RvciBjb21wb25lbnQgb2YgYSB0cmFuc2Zvcm1hdGlvblxuICogIG1hdHJpeC4gSWYgYSBtYXRyaXggaXMgYnVpbHQgd2l0aCBmcm9tUm90YXRpb25UcmFuc2xhdGlvbixcbiAqICB0aGUgcmV0dXJuZWQgdmVjdG9yIHdpbGwgYmUgdGhlIHNhbWUgYXMgdGhlIHRyYW5zbGF0aW9uIHZlY3RvclxuICogIG9yaWdpbmFsbHkgc3VwcGxpZWQuXG4gKiBAcGFyYW0gIHt2ZWMzfSBvdXQgVmVjdG9yIHRvIHJlY2VpdmUgdHJhbnNsYXRpb24gY29tcG9uZW50XG4gKiBAcGFyYW0gIHtSZWFkb25seU1hdDR9IG1hdCBNYXRyaXggdG8gYmUgZGVjb21wb3NlZCAoaW5wdXQpXG4gKiBAcmV0dXJuIHt2ZWMzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VHJhbnNsYXRpb24ob3V0LCBtYXQpIHtcbiAgb3V0WzBdID0gbWF0WzEyXTtcbiAgb3V0WzFdID0gbWF0WzEzXTtcbiAgb3V0WzJdID0gbWF0WzE0XTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUmV0dXJucyB0aGUgc2NhbGluZyBmYWN0b3IgY29tcG9uZW50IG9mIGEgdHJhbnNmb3JtYXRpb25cbiAqICBtYXRyaXguIElmIGEgbWF0cml4IGlzIGJ1aWx0IHdpdGggZnJvbVJvdGF0aW9uVHJhbnNsYXRpb25TY2FsZVxuICogIHdpdGggYSBub3JtYWxpemVkIFF1YXRlcm5pb24gcGFyYW10ZXIsIHRoZSByZXR1cm5lZCB2ZWN0b3Igd2lsbCBiZVxuICogIHRoZSBzYW1lIGFzIHRoZSBzY2FsaW5nIHZlY3RvclxuICogIG9yaWdpbmFsbHkgc3VwcGxpZWQuXG4gKiBAcGFyYW0gIHt2ZWMzfSBvdXQgVmVjdG9yIHRvIHJlY2VpdmUgc2NhbGluZyBmYWN0b3IgY29tcG9uZW50XG4gKiBAcGFyYW0gIHtSZWFkb25seU1hdDR9IG1hdCBNYXRyaXggdG8gYmUgZGVjb21wb3NlZCAoaW5wdXQpXG4gKiBAcmV0dXJuIHt2ZWMzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2NhbGluZyhvdXQsIG1hdCkge1xuICB2YXIgbTExID0gbWF0WzBdO1xuICB2YXIgbTEyID0gbWF0WzFdO1xuICB2YXIgbTEzID0gbWF0WzJdO1xuICB2YXIgbTIxID0gbWF0WzRdO1xuICB2YXIgbTIyID0gbWF0WzVdO1xuICB2YXIgbTIzID0gbWF0WzZdO1xuICB2YXIgbTMxID0gbWF0WzhdO1xuICB2YXIgbTMyID0gbWF0WzldO1xuICB2YXIgbTMzID0gbWF0WzEwXTtcbiAgb3V0WzBdID0gTWF0aC5oeXBvdChtMTEsIG0xMiwgbTEzKTtcbiAgb3V0WzFdID0gTWF0aC5oeXBvdChtMjEsIG0yMiwgbTIzKTtcbiAgb3V0WzJdID0gTWF0aC5oeXBvdChtMzEsIG0zMiwgbTMzKTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUmV0dXJucyBhIHF1YXRlcm5pb24gcmVwcmVzZW50aW5nIHRoZSByb3RhdGlvbmFsIGNvbXBvbmVudFxuICogIG9mIGEgdHJhbnNmb3JtYXRpb24gbWF0cml4LiBJZiBhIG1hdHJpeCBpcyBidWlsdCB3aXRoXG4gKiAgZnJvbVJvdGF0aW9uVHJhbnNsYXRpb24sIHRoZSByZXR1cm5lZCBxdWF0ZXJuaW9uIHdpbGwgYmUgdGhlXG4gKiAgc2FtZSBhcyB0aGUgcXVhdGVybmlvbiBvcmlnaW5hbGx5IHN1cHBsaWVkLlxuICogQHBhcmFtIHtxdWF0fSBvdXQgUXVhdGVybmlvbiB0byByZWNlaXZlIHRoZSByb3RhdGlvbiBjb21wb25lbnRcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBtYXQgTWF0cml4IHRvIGJlIGRlY29tcG9zZWQgKGlucHV0KVxuICogQHJldHVybiB7cXVhdH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFJvdGF0aW9uKG91dCwgbWF0KSB7XG4gIHZhciBzY2FsaW5nID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoMyk7XG4gIGdldFNjYWxpbmcoc2NhbGluZywgbWF0KTtcbiAgdmFyIGlzMSA9IDEgLyBzY2FsaW5nWzBdO1xuICB2YXIgaXMyID0gMSAvIHNjYWxpbmdbMV07XG4gIHZhciBpczMgPSAxIC8gc2NhbGluZ1syXTtcbiAgdmFyIHNtMTEgPSBtYXRbMF0gKiBpczE7XG4gIHZhciBzbTEyID0gbWF0WzFdICogaXMyO1xuICB2YXIgc20xMyA9IG1hdFsyXSAqIGlzMztcbiAgdmFyIHNtMjEgPSBtYXRbNF0gKiBpczE7XG4gIHZhciBzbTIyID0gbWF0WzVdICogaXMyO1xuICB2YXIgc20yMyA9IG1hdFs2XSAqIGlzMztcbiAgdmFyIHNtMzEgPSBtYXRbOF0gKiBpczE7XG4gIHZhciBzbTMyID0gbWF0WzldICogaXMyO1xuICB2YXIgc20zMyA9IG1hdFsxMF0gKiBpczM7XG4gIHZhciB0cmFjZSA9IHNtMTEgKyBzbTIyICsgc20zMztcbiAgdmFyIFMgPSAwO1xuXG4gIGlmICh0cmFjZSA+IDApIHtcbiAgICBTID0gTWF0aC5zcXJ0KHRyYWNlICsgMS4wKSAqIDI7XG4gICAgb3V0WzNdID0gMC4yNSAqIFM7XG4gICAgb3V0WzBdID0gKHNtMjMgLSBzbTMyKSAvIFM7XG4gICAgb3V0WzFdID0gKHNtMzEgLSBzbTEzKSAvIFM7XG4gICAgb3V0WzJdID0gKHNtMTIgLSBzbTIxKSAvIFM7XG4gIH0gZWxzZSBpZiAoc20xMSA+IHNtMjIgJiYgc20xMSA+IHNtMzMpIHtcbiAgICBTID0gTWF0aC5zcXJ0KDEuMCArIHNtMTEgLSBzbTIyIC0gc20zMykgKiAyO1xuICAgIG91dFszXSA9IChzbTIzIC0gc20zMikgLyBTO1xuICAgIG91dFswXSA9IDAuMjUgKiBTO1xuICAgIG91dFsxXSA9IChzbTEyICsgc20yMSkgLyBTO1xuICAgIG91dFsyXSA9IChzbTMxICsgc20xMykgLyBTO1xuICB9IGVsc2UgaWYgKHNtMjIgPiBzbTMzKSB7XG4gICAgUyA9IE1hdGguc3FydCgxLjAgKyBzbTIyIC0gc20xMSAtIHNtMzMpICogMjtcbiAgICBvdXRbM10gPSAoc20zMSAtIHNtMTMpIC8gUztcbiAgICBvdXRbMF0gPSAoc20xMiArIHNtMjEpIC8gUztcbiAgICBvdXRbMV0gPSAwLjI1ICogUztcbiAgICBvdXRbMl0gPSAoc20yMyArIHNtMzIpIC8gUztcbiAgfSBlbHNlIHtcbiAgICBTID0gTWF0aC5zcXJ0KDEuMCArIHNtMzMgLSBzbTExIC0gc20yMikgKiAyO1xuICAgIG91dFszXSA9IChzbTEyIC0gc20yMSkgLyBTO1xuICAgIG91dFswXSA9IChzbTMxICsgc20xMykgLyBTO1xuICAgIG91dFsxXSA9IChzbTIzICsgc20zMikgLyBTO1xuICAgIG91dFsyXSA9IDAuMjUgKiBTO1xuICB9XG5cbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIG1hdHJpeCBmcm9tIGEgcXVhdGVybmlvbiByb3RhdGlvbiwgdmVjdG9yIHRyYW5zbGF0aW9uIGFuZCB2ZWN0b3Igc2NhbGVcbiAqIFRoaXMgaXMgZXF1aXZhbGVudCB0byAoYnV0IG11Y2ggZmFzdGVyIHRoYW4pOlxuICpcbiAqICAgICBtYXQ0LmlkZW50aXR5KGRlc3QpO1xuICogICAgIG1hdDQudHJhbnNsYXRlKGRlc3QsIHZlYyk7XG4gKiAgICAgbGV0IHF1YXRNYXQgPSBtYXQ0LmNyZWF0ZSgpO1xuICogICAgIHF1YXQ0LnRvTWF0NChxdWF0LCBxdWF0TWF0KTtcbiAqICAgICBtYXQ0Lm11bHRpcGx5KGRlc3QsIHF1YXRNYXQpO1xuICogICAgIG1hdDQuc2NhbGUoZGVzdCwgc2NhbGUpXG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgbWF0NCByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxuICogQHBhcmFtIHtxdWF0NH0gcSBSb3RhdGlvbiBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gdiBUcmFuc2xhdGlvbiB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBzIFNjYWxpbmcgdmVjdG9yXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21Sb3RhdGlvblRyYW5zbGF0aW9uU2NhbGUob3V0LCBxLCB2LCBzKSB7XG4gIC8vIFF1YXRlcm5pb24gbWF0aFxuICB2YXIgeCA9IHFbMF0sXG4gICAgICB5ID0gcVsxXSxcbiAgICAgIHogPSBxWzJdLFxuICAgICAgdyA9IHFbM107XG4gIHZhciB4MiA9IHggKyB4O1xuICB2YXIgeTIgPSB5ICsgeTtcbiAgdmFyIHoyID0geiArIHo7XG4gIHZhciB4eCA9IHggKiB4MjtcbiAgdmFyIHh5ID0geCAqIHkyO1xuICB2YXIgeHogPSB4ICogejI7XG4gIHZhciB5eSA9IHkgKiB5MjtcbiAgdmFyIHl6ID0geSAqIHoyO1xuICB2YXIgenogPSB6ICogejI7XG4gIHZhciB3eCA9IHcgKiB4MjtcbiAgdmFyIHd5ID0gdyAqIHkyO1xuICB2YXIgd3ogPSB3ICogejI7XG4gIHZhciBzeCA9IHNbMF07XG4gIHZhciBzeSA9IHNbMV07XG4gIHZhciBzeiA9IHNbMl07XG4gIG91dFswXSA9ICgxIC0gKHl5ICsgenopKSAqIHN4O1xuICBvdXRbMV0gPSAoeHkgKyB3eikgKiBzeDtcbiAgb3V0WzJdID0gKHh6IC0gd3kpICogc3g7XG4gIG91dFszXSA9IDA7XG4gIG91dFs0XSA9ICh4eSAtIHd6KSAqIHN5O1xuICBvdXRbNV0gPSAoMSAtICh4eCArIHp6KSkgKiBzeTtcbiAgb3V0WzZdID0gKHl6ICsgd3gpICogc3k7XG4gIG91dFs3XSA9IDA7XG4gIG91dFs4XSA9ICh4eiArIHd5KSAqIHN6O1xuICBvdXRbOV0gPSAoeXogLSB3eCkgKiBzejtcbiAgb3V0WzEwXSA9ICgxIC0gKHh4ICsgeXkpKSAqIHN6O1xuICBvdXRbMTFdID0gMDtcbiAgb3V0WzEyXSA9IHZbMF07XG4gIG91dFsxM10gPSB2WzFdO1xuICBvdXRbMTRdID0gdlsyXTtcbiAgb3V0WzE1XSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENyZWF0ZXMgYSBtYXRyaXggZnJvbSBhIHF1YXRlcm5pb24gcm90YXRpb24sIHZlY3RvciB0cmFuc2xhdGlvbiBhbmQgdmVjdG9yIHNjYWxlLCByb3RhdGluZyBhbmQgc2NhbGluZyBhcm91bmQgdGhlIGdpdmVuIG9yaWdpblxuICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIChidXQgbXVjaCBmYXN0ZXIgdGhhbik6XG4gKlxuICogICAgIG1hdDQuaWRlbnRpdHkoZGVzdCk7XG4gKiAgICAgbWF0NC50cmFuc2xhdGUoZGVzdCwgdmVjKTtcbiAqICAgICBtYXQ0LnRyYW5zbGF0ZShkZXN0LCBvcmlnaW4pO1xuICogICAgIGxldCBxdWF0TWF0ID0gbWF0NC5jcmVhdGUoKTtcbiAqICAgICBxdWF0NC50b01hdDQocXVhdCwgcXVhdE1hdCk7XG4gKiAgICAgbWF0NC5tdWx0aXBseShkZXN0LCBxdWF0TWF0KTtcbiAqICAgICBtYXQ0LnNjYWxlKGRlc3QsIHNjYWxlKVxuICogICAgIG1hdDQudHJhbnNsYXRlKGRlc3QsIG5lZ2F0aXZlT3JpZ2luKTtcbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XG4gKiBAcGFyYW0ge3F1YXQ0fSBxIFJvdGF0aW9uIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSB2IFRyYW5zbGF0aW9uIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IHMgU2NhbGluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBvIFRoZSBvcmlnaW4gdmVjdG9yIGFyb3VuZCB3aGljaCB0byBzY2FsZSBhbmQgcm90YXRlXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21Sb3RhdGlvblRyYW5zbGF0aW9uU2NhbGVPcmlnaW4ob3V0LCBxLCB2LCBzLCBvKSB7XG4gIC8vIFF1YXRlcm5pb24gbWF0aFxuICB2YXIgeCA9IHFbMF0sXG4gICAgICB5ID0gcVsxXSxcbiAgICAgIHogPSBxWzJdLFxuICAgICAgdyA9IHFbM107XG4gIHZhciB4MiA9IHggKyB4O1xuICB2YXIgeTIgPSB5ICsgeTtcbiAgdmFyIHoyID0geiArIHo7XG4gIHZhciB4eCA9IHggKiB4MjtcbiAgdmFyIHh5ID0geCAqIHkyO1xuICB2YXIgeHogPSB4ICogejI7XG4gIHZhciB5eSA9IHkgKiB5MjtcbiAgdmFyIHl6ID0geSAqIHoyO1xuICB2YXIgenogPSB6ICogejI7XG4gIHZhciB3eCA9IHcgKiB4MjtcbiAgdmFyIHd5ID0gdyAqIHkyO1xuICB2YXIgd3ogPSB3ICogejI7XG4gIHZhciBzeCA9IHNbMF07XG4gIHZhciBzeSA9IHNbMV07XG4gIHZhciBzeiA9IHNbMl07XG4gIHZhciBveCA9IG9bMF07XG4gIHZhciBveSA9IG9bMV07XG4gIHZhciBveiA9IG9bMl07XG4gIHZhciBvdXQwID0gKDEgLSAoeXkgKyB6eikpICogc3g7XG4gIHZhciBvdXQxID0gKHh5ICsgd3opICogc3g7XG4gIHZhciBvdXQyID0gKHh6IC0gd3kpICogc3g7XG4gIHZhciBvdXQ0ID0gKHh5IC0gd3opICogc3k7XG4gIHZhciBvdXQ1ID0gKDEgLSAoeHggKyB6eikpICogc3k7XG4gIHZhciBvdXQ2ID0gKHl6ICsgd3gpICogc3k7XG4gIHZhciBvdXQ4ID0gKHh6ICsgd3kpICogc3o7XG4gIHZhciBvdXQ5ID0gKHl6IC0gd3gpICogc3o7XG4gIHZhciBvdXQxMCA9ICgxIC0gKHh4ICsgeXkpKSAqIHN6O1xuICBvdXRbMF0gPSBvdXQwO1xuICBvdXRbMV0gPSBvdXQxO1xuICBvdXRbMl0gPSBvdXQyO1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSBvdXQ0O1xuICBvdXRbNV0gPSBvdXQ1O1xuICBvdXRbNl0gPSBvdXQ2O1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSBvdXQ4O1xuICBvdXRbOV0gPSBvdXQ5O1xuICBvdXRbMTBdID0gb3V0MTA7XG4gIG91dFsxMV0gPSAwO1xuICBvdXRbMTJdID0gdlswXSArIG94IC0gKG91dDAgKiBveCArIG91dDQgKiBveSArIG91dDggKiBveik7XG4gIG91dFsxM10gPSB2WzFdICsgb3kgLSAob3V0MSAqIG94ICsgb3V0NSAqIG95ICsgb3V0OSAqIG96KTtcbiAgb3V0WzE0XSA9IHZbMl0gKyBveiAtIChvdXQyICogb3ggKyBvdXQ2ICogb3kgKyBvdXQxMCAqIG96KTtcbiAgb3V0WzE1XSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENhbGN1bGF0ZXMgYSA0eDQgbWF0cml4IGZyb20gdGhlIGdpdmVuIHF1YXRlcm5pb25cbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gcSBRdWF0ZXJuaW9uIHRvIGNyZWF0ZSBtYXRyaXggZnJvbVxuICpcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbVF1YXQob3V0LCBxKSB7XG4gIHZhciB4ID0gcVswXSxcbiAgICAgIHkgPSBxWzFdLFxuICAgICAgeiA9IHFbMl0sXG4gICAgICB3ID0gcVszXTtcbiAgdmFyIHgyID0geCArIHg7XG4gIHZhciB5MiA9IHkgKyB5O1xuICB2YXIgejIgPSB6ICsgejtcbiAgdmFyIHh4ID0geCAqIHgyO1xuICB2YXIgeXggPSB5ICogeDI7XG4gIHZhciB5eSA9IHkgKiB5MjtcbiAgdmFyIHp4ID0geiAqIHgyO1xuICB2YXIgenkgPSB6ICogeTI7XG4gIHZhciB6eiA9IHogKiB6MjtcbiAgdmFyIHd4ID0gdyAqIHgyO1xuICB2YXIgd3kgPSB3ICogeTI7XG4gIHZhciB3eiA9IHcgKiB6MjtcbiAgb3V0WzBdID0gMSAtIHl5IC0geno7XG4gIG91dFsxXSA9IHl4ICsgd3o7XG4gIG91dFsyXSA9IHp4IC0gd3k7XG4gIG91dFszXSA9IDA7XG4gIG91dFs0XSA9IHl4IC0gd3o7XG4gIG91dFs1XSA9IDEgLSB4eCAtIHp6O1xuICBvdXRbNl0gPSB6eSArIHd4O1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSB6eCArIHd5O1xuICBvdXRbOV0gPSB6eSAtIHd4O1xuICBvdXRbMTBdID0gMSAtIHh4IC0geXk7XG4gIG91dFsxMV0gPSAwO1xuICBvdXRbMTJdID0gMDtcbiAgb3V0WzEzXSA9IDA7XG4gIG91dFsxNF0gPSAwO1xuICBvdXRbMTVdID0gMTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogR2VuZXJhdGVzIGEgZnJ1c3R1bSBtYXRyaXggd2l0aCB0aGUgZ2l2ZW4gYm91bmRzXG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgbWF0NCBmcnVzdHVtIG1hdHJpeCB3aWxsIGJlIHdyaXR0ZW4gaW50b1xuICogQHBhcmFtIHtOdW1iZXJ9IGxlZnQgTGVmdCBib3VuZCBvZiB0aGUgZnJ1c3R1bVxuICogQHBhcmFtIHtOdW1iZXJ9IHJpZ2h0IFJpZ2h0IGJvdW5kIG9mIHRoZSBmcnVzdHVtXG4gKiBAcGFyYW0ge051bWJlcn0gYm90dG9tIEJvdHRvbSBib3VuZCBvZiB0aGUgZnJ1c3R1bVxuICogQHBhcmFtIHtOdW1iZXJ9IHRvcCBUb3AgYm91bmQgb2YgdGhlIGZydXN0dW1cbiAqIEBwYXJhbSB7TnVtYmVyfSBuZWFyIE5lYXIgYm91bmQgb2YgdGhlIGZydXN0dW1cbiAqIEBwYXJhbSB7TnVtYmVyfSBmYXIgRmFyIGJvdW5kIG9mIHRoZSBmcnVzdHVtXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZydXN0dW0ob3V0LCBsZWZ0LCByaWdodCwgYm90dG9tLCB0b3AsIG5lYXIsIGZhcikge1xuICB2YXIgcmwgPSAxIC8gKHJpZ2h0IC0gbGVmdCk7XG4gIHZhciB0YiA9IDEgLyAodG9wIC0gYm90dG9tKTtcbiAgdmFyIG5mID0gMSAvIChuZWFyIC0gZmFyKTtcbiAgb3V0WzBdID0gbmVhciAqIDIgKiBybDtcbiAgb3V0WzFdID0gMDtcbiAgb3V0WzJdID0gMDtcbiAgb3V0WzNdID0gMDtcbiAgb3V0WzRdID0gMDtcbiAgb3V0WzVdID0gbmVhciAqIDIgKiB0YjtcbiAgb3V0WzZdID0gMDtcbiAgb3V0WzddID0gMDtcbiAgb3V0WzhdID0gKHJpZ2h0ICsgbGVmdCkgKiBybDtcbiAgb3V0WzldID0gKHRvcCArIGJvdHRvbSkgKiB0YjtcbiAgb3V0WzEwXSA9IChmYXIgKyBuZWFyKSAqIG5mO1xuICBvdXRbMTFdID0gLTE7XG4gIG91dFsxMl0gPSAwO1xuICBvdXRbMTNdID0gMDtcbiAgb3V0WzE0XSA9IGZhciAqIG5lYXIgKiAyICogbmY7XG4gIG91dFsxNV0gPSAwO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBHZW5lcmF0ZXMgYSBwZXJzcGVjdGl2ZSBwcm9qZWN0aW9uIG1hdHJpeCB3aXRoIHRoZSBnaXZlbiBib3VuZHMuXG4gKiBUaGUgbmVhci9mYXIgY2xpcCBwbGFuZXMgY29ycmVzcG9uZCB0byBhIG5vcm1hbGl6ZWQgZGV2aWNlIGNvb3JkaW5hdGUgWiByYW5nZSBvZiBbLTEsIDFdLFxuICogd2hpY2ggbWF0Y2hlcyBXZWJHTC9PcGVuR0wncyBjbGlwIHZvbHVtZS5cbiAqIFBhc3NpbmcgbnVsbC91bmRlZmluZWQvbm8gdmFsdWUgZm9yIGZhciB3aWxsIGdlbmVyYXRlIGluZmluaXRlIHByb2plY3Rpb24gbWF0cml4LlxuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IG1hdDQgZnJ1c3R1bSBtYXRyaXggd2lsbCBiZSB3cml0dGVuIGludG9cbiAqIEBwYXJhbSB7bnVtYmVyfSBmb3Z5IFZlcnRpY2FsIGZpZWxkIG9mIHZpZXcgaW4gcmFkaWFuc1xuICogQHBhcmFtIHtudW1iZXJ9IGFzcGVjdCBBc3BlY3QgcmF0aW8uIHR5cGljYWxseSB2aWV3cG9ydCB3aWR0aC9oZWlnaHRcbiAqIEBwYXJhbSB7bnVtYmVyfSBuZWFyIE5lYXIgYm91bmQgb2YgdGhlIGZydXN0dW1cbiAqIEBwYXJhbSB7bnVtYmVyfSBmYXIgRmFyIGJvdW5kIG9mIHRoZSBmcnVzdHVtLCBjYW4gYmUgbnVsbCBvciBJbmZpbml0eVxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBwZXJzcGVjdGl2ZU5PKG91dCwgZm92eSwgYXNwZWN0LCBuZWFyLCBmYXIpIHtcbiAgdmFyIGYgPSAxLjAgLyBNYXRoLnRhbihmb3Z5IC8gMiksXG4gICAgICBuZjtcbiAgb3V0WzBdID0gZiAvIGFzcGVjdDtcbiAgb3V0WzFdID0gMDtcbiAgb3V0WzJdID0gMDtcbiAgb3V0WzNdID0gMDtcbiAgb3V0WzRdID0gMDtcbiAgb3V0WzVdID0gZjtcbiAgb3V0WzZdID0gMDtcbiAgb3V0WzddID0gMDtcbiAgb3V0WzhdID0gMDtcbiAgb3V0WzldID0gMDtcbiAgb3V0WzExXSA9IC0xO1xuICBvdXRbMTJdID0gMDtcbiAgb3V0WzEzXSA9IDA7XG4gIG91dFsxNV0gPSAwO1xuXG4gIGlmIChmYXIgIT0gbnVsbCAmJiBmYXIgIT09IEluZmluaXR5KSB7XG4gICAgbmYgPSAxIC8gKG5lYXIgLSBmYXIpO1xuICAgIG91dFsxMF0gPSAoZmFyICsgbmVhcikgKiBuZjtcbiAgICBvdXRbMTRdID0gMiAqIGZhciAqIG5lYXIgKiBuZjtcbiAgfSBlbHNlIHtcbiAgICBvdXRbMTBdID0gLTE7XG4gICAgb3V0WzE0XSA9IC0yICogbmVhcjtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgbWF0NC5wZXJzcGVjdGl2ZU5PfVxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBwZXJzcGVjdGl2ZSA9IHBlcnNwZWN0aXZlTk87XG4vKipcbiAqIEdlbmVyYXRlcyBhIHBlcnNwZWN0aXZlIHByb2plY3Rpb24gbWF0cml4IHN1aXRhYmxlIGZvciBXZWJHUFUgd2l0aCB0aGUgZ2l2ZW4gYm91bmRzLlxuICogVGhlIG5lYXIvZmFyIGNsaXAgcGxhbmVzIGNvcnJlc3BvbmQgdG8gYSBub3JtYWxpemVkIGRldmljZSBjb29yZGluYXRlIFogcmFuZ2Ugb2YgWzAsIDFdLFxuICogd2hpY2ggbWF0Y2hlcyBXZWJHUFUvVnVsa2FuL0RpcmVjdFgvTWV0YWwncyBjbGlwIHZvbHVtZS5cbiAqIFBhc3NpbmcgbnVsbC91bmRlZmluZWQvbm8gdmFsdWUgZm9yIGZhciB3aWxsIGdlbmVyYXRlIGluZmluaXRlIHByb2plY3Rpb24gbWF0cml4LlxuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IG1hdDQgZnJ1c3R1bSBtYXRyaXggd2lsbCBiZSB3cml0dGVuIGludG9cbiAqIEBwYXJhbSB7bnVtYmVyfSBmb3Z5IFZlcnRpY2FsIGZpZWxkIG9mIHZpZXcgaW4gcmFkaWFuc1xuICogQHBhcmFtIHtudW1iZXJ9IGFzcGVjdCBBc3BlY3QgcmF0aW8uIHR5cGljYWxseSB2aWV3cG9ydCB3aWR0aC9oZWlnaHRcbiAqIEBwYXJhbSB7bnVtYmVyfSBuZWFyIE5lYXIgYm91bmQgb2YgdGhlIGZydXN0dW1cbiAqIEBwYXJhbSB7bnVtYmVyfSBmYXIgRmFyIGJvdW5kIG9mIHRoZSBmcnVzdHVtLCBjYW4gYmUgbnVsbCBvciBJbmZpbml0eVxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBwZXJzcGVjdGl2ZVpPKG91dCwgZm92eSwgYXNwZWN0LCBuZWFyLCBmYXIpIHtcbiAgdmFyIGYgPSAxLjAgLyBNYXRoLnRhbihmb3Z5IC8gMiksXG4gICAgICBuZjtcbiAgb3V0WzBdID0gZiAvIGFzcGVjdDtcbiAgb3V0WzFdID0gMDtcbiAgb3V0WzJdID0gMDtcbiAgb3V0WzNdID0gMDtcbiAgb3V0WzRdID0gMDtcbiAgb3V0WzVdID0gZjtcbiAgb3V0WzZdID0gMDtcbiAgb3V0WzddID0gMDtcbiAgb3V0WzhdID0gMDtcbiAgb3V0WzldID0gMDtcbiAgb3V0WzExXSA9IC0xO1xuICBvdXRbMTJdID0gMDtcbiAgb3V0WzEzXSA9IDA7XG4gIG91dFsxNV0gPSAwO1xuXG4gIGlmIChmYXIgIT0gbnVsbCAmJiBmYXIgIT09IEluZmluaXR5KSB7XG4gICAgbmYgPSAxIC8gKG5lYXIgLSBmYXIpO1xuICAgIG91dFsxMF0gPSBmYXIgKiBuZjtcbiAgICBvdXRbMTRdID0gZmFyICogbmVhciAqIG5mO1xuICB9IGVsc2Uge1xuICAgIG91dFsxMF0gPSAtMTtcbiAgICBvdXRbMTRdID0gLW5lYXI7XG4gIH1cblxuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBHZW5lcmF0ZXMgYSBwZXJzcGVjdGl2ZSBwcm9qZWN0aW9uIG1hdHJpeCB3aXRoIHRoZSBnaXZlbiBmaWVsZCBvZiB2aWV3LlxuICogVGhpcyBpcyBwcmltYXJpbHkgdXNlZnVsIGZvciBnZW5lcmF0aW5nIHByb2plY3Rpb24gbWF0cmljZXMgdG8gYmUgdXNlZFxuICogd2l0aCB0aGUgc3RpbGwgZXhwZXJpZW1lbnRhbCBXZWJWUiBBUEkuXG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgbWF0NCBmcnVzdHVtIG1hdHJpeCB3aWxsIGJlIHdyaXR0ZW4gaW50b1xuICogQHBhcmFtIHtPYmplY3R9IGZvdiBPYmplY3QgY29udGFpbmluZyB0aGUgZm9sbG93aW5nIHZhbHVlczogdXBEZWdyZWVzLCBkb3duRGVncmVlcywgbGVmdERlZ3JlZXMsIHJpZ2h0RGVncmVlc1xuICogQHBhcmFtIHtudW1iZXJ9IG5lYXIgTmVhciBib3VuZCBvZiB0aGUgZnJ1c3R1bVxuICogQHBhcmFtIHtudW1iZXJ9IGZhciBGYXIgYm91bmQgb2YgdGhlIGZydXN0dW1cbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcGVyc3BlY3RpdmVGcm9tRmllbGRPZlZpZXcob3V0LCBmb3YsIG5lYXIsIGZhcikge1xuICB2YXIgdXBUYW4gPSBNYXRoLnRhbihmb3YudXBEZWdyZWVzICogTWF0aC5QSSAvIDE4MC4wKTtcbiAgdmFyIGRvd25UYW4gPSBNYXRoLnRhbihmb3YuZG93bkRlZ3JlZXMgKiBNYXRoLlBJIC8gMTgwLjApO1xuICB2YXIgbGVmdFRhbiA9IE1hdGgudGFuKGZvdi5sZWZ0RGVncmVlcyAqIE1hdGguUEkgLyAxODAuMCk7XG4gIHZhciByaWdodFRhbiA9IE1hdGgudGFuKGZvdi5yaWdodERlZ3JlZXMgKiBNYXRoLlBJIC8gMTgwLjApO1xuICB2YXIgeFNjYWxlID0gMi4wIC8gKGxlZnRUYW4gKyByaWdodFRhbik7XG4gIHZhciB5U2NhbGUgPSAyLjAgLyAodXBUYW4gKyBkb3duVGFuKTtcbiAgb3V0WzBdID0geFNjYWxlO1xuICBvdXRbMV0gPSAwLjA7XG4gIG91dFsyXSA9IDAuMDtcbiAgb3V0WzNdID0gMC4wO1xuICBvdXRbNF0gPSAwLjA7XG4gIG91dFs1XSA9IHlTY2FsZTtcbiAgb3V0WzZdID0gMC4wO1xuICBvdXRbN10gPSAwLjA7XG4gIG91dFs4XSA9IC0oKGxlZnRUYW4gLSByaWdodFRhbikgKiB4U2NhbGUgKiAwLjUpO1xuICBvdXRbOV0gPSAodXBUYW4gLSBkb3duVGFuKSAqIHlTY2FsZSAqIDAuNTtcbiAgb3V0WzEwXSA9IGZhciAvIChuZWFyIC0gZmFyKTtcbiAgb3V0WzExXSA9IC0xLjA7XG4gIG91dFsxMl0gPSAwLjA7XG4gIG91dFsxM10gPSAwLjA7XG4gIG91dFsxNF0gPSBmYXIgKiBuZWFyIC8gKG5lYXIgLSBmYXIpO1xuICBvdXRbMTVdID0gMC4wO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBHZW5lcmF0ZXMgYSBvcnRob2dvbmFsIHByb2plY3Rpb24gbWF0cml4IHdpdGggdGhlIGdpdmVuIGJvdW5kcy5cbiAqIFRoZSBuZWFyL2ZhciBjbGlwIHBsYW5lcyBjb3JyZXNwb25kIHRvIGEgbm9ybWFsaXplZCBkZXZpY2UgY29vcmRpbmF0ZSBaIHJhbmdlIG9mIFstMSwgMV0sXG4gKiB3aGljaCBtYXRjaGVzIFdlYkdML09wZW5HTCdzIGNsaXAgdm9sdW1lLlxuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IG1hdDQgZnJ1c3R1bSBtYXRyaXggd2lsbCBiZSB3cml0dGVuIGludG9cbiAqIEBwYXJhbSB7bnVtYmVyfSBsZWZ0IExlZnQgYm91bmQgb2YgdGhlIGZydXN0dW1cbiAqIEBwYXJhbSB7bnVtYmVyfSByaWdodCBSaWdodCBib3VuZCBvZiB0aGUgZnJ1c3R1bVxuICogQHBhcmFtIHtudW1iZXJ9IGJvdHRvbSBCb3R0b20gYm91bmQgb2YgdGhlIGZydXN0dW1cbiAqIEBwYXJhbSB7bnVtYmVyfSB0b3AgVG9wIGJvdW5kIG9mIHRoZSBmcnVzdHVtXG4gKiBAcGFyYW0ge251bWJlcn0gbmVhciBOZWFyIGJvdW5kIG9mIHRoZSBmcnVzdHVtXG4gKiBAcGFyYW0ge251bWJlcn0gZmFyIEZhciBib3VuZCBvZiB0aGUgZnJ1c3R1bVxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBvcnRob05PKG91dCwgbGVmdCwgcmlnaHQsIGJvdHRvbSwgdG9wLCBuZWFyLCBmYXIpIHtcbiAgdmFyIGxyID0gMSAvIChsZWZ0IC0gcmlnaHQpO1xuICB2YXIgYnQgPSAxIC8gKGJvdHRvbSAtIHRvcCk7XG4gIHZhciBuZiA9IDEgLyAobmVhciAtIGZhcik7XG4gIG91dFswXSA9IC0yICogbHI7XG4gIG91dFsxXSA9IDA7XG4gIG91dFsyXSA9IDA7XG4gIG91dFszXSA9IDA7XG4gIG91dFs0XSA9IDA7XG4gIG91dFs1XSA9IC0yICogYnQ7XG4gIG91dFs2XSA9IDA7XG4gIG91dFs3XSA9IDA7XG4gIG91dFs4XSA9IDA7XG4gIG91dFs5XSA9IDA7XG4gIG91dFsxMF0gPSAyICogbmY7XG4gIG91dFsxMV0gPSAwO1xuICBvdXRbMTJdID0gKGxlZnQgKyByaWdodCkgKiBscjtcbiAgb3V0WzEzXSA9ICh0b3AgKyBib3R0b20pICogYnQ7XG4gIG91dFsxNF0gPSAoZmFyICsgbmVhcikgKiBuZjtcbiAgb3V0WzE1XSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgbWF0NC5vcnRob05PfVxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBvcnRobyA9IG9ydGhvTk87XG4vKipcbiAqIEdlbmVyYXRlcyBhIG9ydGhvZ29uYWwgcHJvamVjdGlvbiBtYXRyaXggd2l0aCB0aGUgZ2l2ZW4gYm91bmRzLlxuICogVGhlIG5lYXIvZmFyIGNsaXAgcGxhbmVzIGNvcnJlc3BvbmQgdG8gYSBub3JtYWxpemVkIGRldmljZSBjb29yZGluYXRlIFogcmFuZ2Ugb2YgWzAsIDFdLFxuICogd2hpY2ggbWF0Y2hlcyBXZWJHUFUvVnVsa2FuL0RpcmVjdFgvTWV0YWwncyBjbGlwIHZvbHVtZS5cbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IGZydXN0dW0gbWF0cml4IHdpbGwgYmUgd3JpdHRlbiBpbnRvXG4gKiBAcGFyYW0ge251bWJlcn0gbGVmdCBMZWZ0IGJvdW5kIG9mIHRoZSBmcnVzdHVtXG4gKiBAcGFyYW0ge251bWJlcn0gcmlnaHQgUmlnaHQgYm91bmQgb2YgdGhlIGZydXN0dW1cbiAqIEBwYXJhbSB7bnVtYmVyfSBib3R0b20gQm90dG9tIGJvdW5kIG9mIHRoZSBmcnVzdHVtXG4gKiBAcGFyYW0ge251bWJlcn0gdG9wIFRvcCBib3VuZCBvZiB0aGUgZnJ1c3R1bVxuICogQHBhcmFtIHtudW1iZXJ9IG5lYXIgTmVhciBib3VuZCBvZiB0aGUgZnJ1c3R1bVxuICogQHBhcmFtIHtudW1iZXJ9IGZhciBGYXIgYm91bmQgb2YgdGhlIGZydXN0dW1cbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gb3J0aG9aTyhvdXQsIGxlZnQsIHJpZ2h0LCBib3R0b20sIHRvcCwgbmVhciwgZmFyKSB7XG4gIHZhciBsciA9IDEgLyAobGVmdCAtIHJpZ2h0KTtcbiAgdmFyIGJ0ID0gMSAvIChib3R0b20gLSB0b3ApO1xuICB2YXIgbmYgPSAxIC8gKG5lYXIgLSBmYXIpO1xuICBvdXRbMF0gPSAtMiAqIGxyO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSAwO1xuICBvdXRbNV0gPSAtMiAqIGJ0O1xuICBvdXRbNl0gPSAwO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSAwO1xuICBvdXRbOV0gPSAwO1xuICBvdXRbMTBdID0gbmY7XG4gIG91dFsxMV0gPSAwO1xuICBvdXRbMTJdID0gKGxlZnQgKyByaWdodCkgKiBscjtcbiAgb3V0WzEzXSA9ICh0b3AgKyBib3R0b20pICogYnQ7XG4gIG91dFsxNF0gPSBuZWFyICogbmY7XG4gIG91dFsxNV0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBHZW5lcmF0ZXMgYSBsb29rLWF0IG1hdHJpeCB3aXRoIHRoZSBnaXZlbiBleWUgcG9zaXRpb24sIGZvY2FsIHBvaW50LCBhbmQgdXAgYXhpcy5cbiAqIElmIHlvdSB3YW50IGEgbWF0cml4IHRoYXQgYWN0dWFsbHkgbWFrZXMgYW4gb2JqZWN0IGxvb2sgYXQgYW5vdGhlciBvYmplY3QsIHlvdSBzaG91bGQgdXNlIHRhcmdldFRvIGluc3RlYWQuXG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgbWF0NCBmcnVzdHVtIG1hdHJpeCB3aWxsIGJlIHdyaXR0ZW4gaW50b1xuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGV5ZSBQb3NpdGlvbiBvZiB0aGUgdmlld2VyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gY2VudGVyIFBvaW50IHRoZSB2aWV3ZXIgaXMgbG9va2luZyBhdFxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IHVwIHZlYzMgcG9pbnRpbmcgdXBcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbG9va0F0KG91dCwgZXllLCBjZW50ZXIsIHVwKSB7XG4gIHZhciB4MCwgeDEsIHgyLCB5MCwgeTEsIHkyLCB6MCwgejEsIHoyLCBsZW47XG4gIHZhciBleWV4ID0gZXllWzBdO1xuICB2YXIgZXlleSA9IGV5ZVsxXTtcbiAgdmFyIGV5ZXogPSBleWVbMl07XG4gIHZhciB1cHggPSB1cFswXTtcbiAgdmFyIHVweSA9IHVwWzFdO1xuICB2YXIgdXB6ID0gdXBbMl07XG4gIHZhciBjZW50ZXJ4ID0gY2VudGVyWzBdO1xuICB2YXIgY2VudGVyeSA9IGNlbnRlclsxXTtcbiAgdmFyIGNlbnRlcnogPSBjZW50ZXJbMl07XG5cbiAgaWYgKE1hdGguYWJzKGV5ZXggLSBjZW50ZXJ4KSA8IGdsTWF0cml4LkVQU0lMT04gJiYgTWF0aC5hYnMoZXlleSAtIGNlbnRlcnkpIDwgZ2xNYXRyaXguRVBTSUxPTiAmJiBNYXRoLmFicyhleWV6IC0gY2VudGVyeikgPCBnbE1hdHJpeC5FUFNJTE9OKSB7XG4gICAgcmV0dXJuIGlkZW50aXR5KG91dCk7XG4gIH1cblxuICB6MCA9IGV5ZXggLSBjZW50ZXJ4O1xuICB6MSA9IGV5ZXkgLSBjZW50ZXJ5O1xuICB6MiA9IGV5ZXogLSBjZW50ZXJ6O1xuICBsZW4gPSAxIC8gTWF0aC5oeXBvdCh6MCwgejEsIHoyKTtcbiAgejAgKj0gbGVuO1xuICB6MSAqPSBsZW47XG4gIHoyICo9IGxlbjtcbiAgeDAgPSB1cHkgKiB6MiAtIHVweiAqIHoxO1xuICB4MSA9IHVweiAqIHowIC0gdXB4ICogejI7XG4gIHgyID0gdXB4ICogejEgLSB1cHkgKiB6MDtcbiAgbGVuID0gTWF0aC5oeXBvdCh4MCwgeDEsIHgyKTtcblxuICBpZiAoIWxlbikge1xuICAgIHgwID0gMDtcbiAgICB4MSA9IDA7XG4gICAgeDIgPSAwO1xuICB9IGVsc2Uge1xuICAgIGxlbiA9IDEgLyBsZW47XG4gICAgeDAgKj0gbGVuO1xuICAgIHgxICo9IGxlbjtcbiAgICB4MiAqPSBsZW47XG4gIH1cblxuICB5MCA9IHoxICogeDIgLSB6MiAqIHgxO1xuICB5MSA9IHoyICogeDAgLSB6MCAqIHgyO1xuICB5MiA9IHowICogeDEgLSB6MSAqIHgwO1xuICBsZW4gPSBNYXRoLmh5cG90KHkwLCB5MSwgeTIpO1xuXG4gIGlmICghbGVuKSB7XG4gICAgeTAgPSAwO1xuICAgIHkxID0gMDtcbiAgICB5MiA9IDA7XG4gIH0gZWxzZSB7XG4gICAgbGVuID0gMSAvIGxlbjtcbiAgICB5MCAqPSBsZW47XG4gICAgeTEgKj0gbGVuO1xuICAgIHkyICo9IGxlbjtcbiAgfVxuXG4gIG91dFswXSA9IHgwO1xuICBvdXRbMV0gPSB5MDtcbiAgb3V0WzJdID0gejA7XG4gIG91dFszXSA9IDA7XG4gIG91dFs0XSA9IHgxO1xuICBvdXRbNV0gPSB5MTtcbiAgb3V0WzZdID0gejE7XG4gIG91dFs3XSA9IDA7XG4gIG91dFs4XSA9IHgyO1xuICBvdXRbOV0gPSB5MjtcbiAgb3V0WzEwXSA9IHoyO1xuICBvdXRbMTFdID0gMDtcbiAgb3V0WzEyXSA9IC0oeDAgKiBleWV4ICsgeDEgKiBleWV5ICsgeDIgKiBleWV6KTtcbiAgb3V0WzEzXSA9IC0oeTAgKiBleWV4ICsgeTEgKiBleWV5ICsgeTIgKiBleWV6KTtcbiAgb3V0WzE0XSA9IC0oejAgKiBleWV4ICsgejEgKiBleWV5ICsgejIgKiBleWV6KTtcbiAgb3V0WzE1XSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIEdlbmVyYXRlcyBhIG1hdHJpeCB0aGF0IG1ha2VzIHNvbWV0aGluZyBsb29rIGF0IHNvbWV0aGluZyBlbHNlLlxuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IG1hdDQgZnJ1c3R1bSBtYXRyaXggd2lsbCBiZSB3cml0dGVuIGludG9cbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBleWUgUG9zaXRpb24gb2YgdGhlIHZpZXdlclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGNlbnRlciBQb2ludCB0aGUgdmlld2VyIGlzIGxvb2tpbmcgYXRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSB1cCB2ZWMzIHBvaW50aW5nIHVwXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRhcmdldFRvKG91dCwgZXllLCB0YXJnZXQsIHVwKSB7XG4gIHZhciBleWV4ID0gZXllWzBdLFxuICAgICAgZXlleSA9IGV5ZVsxXSxcbiAgICAgIGV5ZXogPSBleWVbMl0sXG4gICAgICB1cHggPSB1cFswXSxcbiAgICAgIHVweSA9IHVwWzFdLFxuICAgICAgdXB6ID0gdXBbMl07XG4gIHZhciB6MCA9IGV5ZXggLSB0YXJnZXRbMF0sXG4gICAgICB6MSA9IGV5ZXkgLSB0YXJnZXRbMV0sXG4gICAgICB6MiA9IGV5ZXogLSB0YXJnZXRbMl07XG4gIHZhciBsZW4gPSB6MCAqIHowICsgejEgKiB6MSArIHoyICogejI7XG5cbiAgaWYgKGxlbiA+IDApIHtcbiAgICBsZW4gPSAxIC8gTWF0aC5zcXJ0KGxlbik7XG4gICAgejAgKj0gbGVuO1xuICAgIHoxICo9IGxlbjtcbiAgICB6MiAqPSBsZW47XG4gIH1cblxuICB2YXIgeDAgPSB1cHkgKiB6MiAtIHVweiAqIHoxLFxuICAgICAgeDEgPSB1cHogKiB6MCAtIHVweCAqIHoyLFxuICAgICAgeDIgPSB1cHggKiB6MSAtIHVweSAqIHowO1xuICBsZW4gPSB4MCAqIHgwICsgeDEgKiB4MSArIHgyICogeDI7XG5cbiAgaWYgKGxlbiA+IDApIHtcbiAgICBsZW4gPSAxIC8gTWF0aC5zcXJ0KGxlbik7XG4gICAgeDAgKj0gbGVuO1xuICAgIHgxICo9IGxlbjtcbiAgICB4MiAqPSBsZW47XG4gIH1cblxuICBvdXRbMF0gPSB4MDtcbiAgb3V0WzFdID0geDE7XG4gIG91dFsyXSA9IHgyO1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSB6MSAqIHgyIC0gejIgKiB4MTtcbiAgb3V0WzVdID0gejIgKiB4MCAtIHowICogeDI7XG4gIG91dFs2XSA9IHowICogeDEgLSB6MSAqIHgwO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSB6MDtcbiAgb3V0WzldID0gejE7XG4gIG91dFsxMF0gPSB6MjtcbiAgb3V0WzExXSA9IDA7XG4gIG91dFsxMl0gPSBleWV4O1xuICBvdXRbMTNdID0gZXlleTtcbiAgb3V0WzE0XSA9IGV5ZXo7XG4gIG91dFsxNV0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgbWF0NFxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhIG1hdHJpeCB0byByZXByZXNlbnQgYXMgYSBzdHJpbmdcbiAqIEByZXR1cm5zIHtTdHJpbmd9IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgbWF0cml4XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHN0cihhKSB7XG4gIHJldHVybiBcIm1hdDQoXCIgKyBhWzBdICsgXCIsIFwiICsgYVsxXSArIFwiLCBcIiArIGFbMl0gKyBcIiwgXCIgKyBhWzNdICsgXCIsIFwiICsgYVs0XSArIFwiLCBcIiArIGFbNV0gKyBcIiwgXCIgKyBhWzZdICsgXCIsIFwiICsgYVs3XSArIFwiLCBcIiArIGFbOF0gKyBcIiwgXCIgKyBhWzldICsgXCIsIFwiICsgYVsxMF0gKyBcIiwgXCIgKyBhWzExXSArIFwiLCBcIiArIGFbMTJdICsgXCIsIFwiICsgYVsxM10gKyBcIiwgXCIgKyBhWzE0XSArIFwiLCBcIiArIGFbMTVdICsgXCIpXCI7XG59XG4vKipcbiAqIFJldHVybnMgRnJvYmVuaXVzIG5vcm0gb2YgYSBtYXQ0XG4gKlxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGEgdGhlIG1hdHJpeCB0byBjYWxjdWxhdGUgRnJvYmVuaXVzIG5vcm0gb2ZcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IEZyb2Jlbml1cyBub3JtXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb2IoYSkge1xuICByZXR1cm4gTWF0aC5oeXBvdChhWzBdLCBhWzFdLCBhWzJdLCBhWzNdLCBhWzRdLCBhWzVdLCBhWzZdLCBhWzddLCBhWzhdLCBhWzldLCBhWzEwXSwgYVsxMV0sIGFbMTJdLCBhWzEzXSwgYVsxNF0sIGFbMTVdKTtcbn1cbi8qKlxuICogQWRkcyB0d28gbWF0NCdzXG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYWRkKG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdICsgYlswXTtcbiAgb3V0WzFdID0gYVsxXSArIGJbMV07XG4gIG91dFsyXSA9IGFbMl0gKyBiWzJdO1xuICBvdXRbM10gPSBhWzNdICsgYlszXTtcbiAgb3V0WzRdID0gYVs0XSArIGJbNF07XG4gIG91dFs1XSA9IGFbNV0gKyBiWzVdO1xuICBvdXRbNl0gPSBhWzZdICsgYls2XTtcbiAgb3V0WzddID0gYVs3XSArIGJbN107XG4gIG91dFs4XSA9IGFbOF0gKyBiWzhdO1xuICBvdXRbOV0gPSBhWzldICsgYls5XTtcbiAgb3V0WzEwXSA9IGFbMTBdICsgYlsxMF07XG4gIG91dFsxMV0gPSBhWzExXSArIGJbMTFdO1xuICBvdXRbMTJdID0gYVsxMl0gKyBiWzEyXTtcbiAgb3V0WzEzXSA9IGFbMTNdICsgYlsxM107XG4gIG91dFsxNF0gPSBhWzE0XSArIGJbMTRdO1xuICBvdXRbMTVdID0gYVsxNV0gKyBiWzE1XTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogU3VidHJhY3RzIG1hdHJpeCBiIGZyb20gbWF0cml4IGFcbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzdWJ0cmFjdChvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gYVswXSAtIGJbMF07XG4gIG91dFsxXSA9IGFbMV0gLSBiWzFdO1xuICBvdXRbMl0gPSBhWzJdIC0gYlsyXTtcbiAgb3V0WzNdID0gYVszXSAtIGJbM107XG4gIG91dFs0XSA9IGFbNF0gLSBiWzRdO1xuICBvdXRbNV0gPSBhWzVdIC0gYls1XTtcbiAgb3V0WzZdID0gYVs2XSAtIGJbNl07XG4gIG91dFs3XSA9IGFbN10gLSBiWzddO1xuICBvdXRbOF0gPSBhWzhdIC0gYls4XTtcbiAgb3V0WzldID0gYVs5XSAtIGJbOV07XG4gIG91dFsxMF0gPSBhWzEwXSAtIGJbMTBdO1xuICBvdXRbMTFdID0gYVsxMV0gLSBiWzExXTtcbiAgb3V0WzEyXSA9IGFbMTJdIC0gYlsxMl07XG4gIG91dFsxM10gPSBhWzEzXSAtIGJbMTNdO1xuICBvdXRbMTRdID0gYVsxNF0gLSBiWzE0XTtcbiAgb3V0WzE1XSA9IGFbMTVdIC0gYlsxNV07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIE11bHRpcGx5IGVhY2ggZWxlbWVudCBvZiB0aGUgbWF0cml4IGJ5IGEgc2NhbGFyLlxuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYSB0aGUgbWF0cml4IHRvIHNjYWxlXG4gKiBAcGFyYW0ge051bWJlcn0gYiBhbW91bnQgdG8gc2NhbGUgdGhlIG1hdHJpeCdzIGVsZW1lbnRzIGJ5XG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG11bHRpcGx5U2NhbGFyKG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdICogYjtcbiAgb3V0WzFdID0gYVsxXSAqIGI7XG4gIG91dFsyXSA9IGFbMl0gKiBiO1xuICBvdXRbM10gPSBhWzNdICogYjtcbiAgb3V0WzRdID0gYVs0XSAqIGI7XG4gIG91dFs1XSA9IGFbNV0gKiBiO1xuICBvdXRbNl0gPSBhWzZdICogYjtcbiAgb3V0WzddID0gYVs3XSAqIGI7XG4gIG91dFs4XSA9IGFbOF0gKiBiO1xuICBvdXRbOV0gPSBhWzldICogYjtcbiAgb3V0WzEwXSA9IGFbMTBdICogYjtcbiAgb3V0WzExXSA9IGFbMTFdICogYjtcbiAgb3V0WzEyXSA9IGFbMTJdICogYjtcbiAgb3V0WzEzXSA9IGFbMTNdICogYjtcbiAgb3V0WzE0XSA9IGFbMTRdICogYjtcbiAgb3V0WzE1XSA9IGFbMTVdICogYjtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQWRkcyB0d28gbWF0NCdzIGFmdGVyIG11bHRpcGx5aW5nIGVhY2ggZWxlbWVudCBvZiB0aGUgc2Vjb25kIG9wZXJhbmQgYnkgYSBzY2FsYXIgdmFsdWUuXG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEBwYXJhbSB7TnVtYmVyfSBzY2FsZSB0aGUgYW1vdW50IHRvIHNjYWxlIGIncyBlbGVtZW50cyBieSBiZWZvcmUgYWRkaW5nXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG11bHRpcGx5U2NhbGFyQW5kQWRkKG91dCwgYSwgYiwgc2NhbGUpIHtcbiAgb3V0WzBdID0gYVswXSArIGJbMF0gKiBzY2FsZTtcbiAgb3V0WzFdID0gYVsxXSArIGJbMV0gKiBzY2FsZTtcbiAgb3V0WzJdID0gYVsyXSArIGJbMl0gKiBzY2FsZTtcbiAgb3V0WzNdID0gYVszXSArIGJbM10gKiBzY2FsZTtcbiAgb3V0WzRdID0gYVs0XSArIGJbNF0gKiBzY2FsZTtcbiAgb3V0WzVdID0gYVs1XSArIGJbNV0gKiBzY2FsZTtcbiAgb3V0WzZdID0gYVs2XSArIGJbNl0gKiBzY2FsZTtcbiAgb3V0WzddID0gYVs3XSArIGJbN10gKiBzY2FsZTtcbiAgb3V0WzhdID0gYVs4XSArIGJbOF0gKiBzY2FsZTtcbiAgb3V0WzldID0gYVs5XSArIGJbOV0gKiBzY2FsZTtcbiAgb3V0WzEwXSA9IGFbMTBdICsgYlsxMF0gKiBzY2FsZTtcbiAgb3V0WzExXSA9IGFbMTFdICsgYlsxMV0gKiBzY2FsZTtcbiAgb3V0WzEyXSA9IGFbMTJdICsgYlsxMl0gKiBzY2FsZTtcbiAgb3V0WzEzXSA9IGFbMTNdICsgYlsxM10gKiBzY2FsZTtcbiAgb3V0WzE0XSA9IGFbMTRdICsgYlsxNF0gKiBzY2FsZTtcbiAgb3V0WzE1XSA9IGFbMTVdICsgYlsxNV0gKiBzY2FsZTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgbWF0cmljZXMgaGF2ZSBleGFjdGx5IHRoZSBzYW1lIGVsZW1lbnRzIGluIHRoZSBzYW1lIHBvc2l0aW9uICh3aGVuIGNvbXBhcmVkIHdpdGggPT09KVxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhIFRoZSBmaXJzdCBtYXRyaXguXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYiBUaGUgc2Vjb25kIG1hdHJpeC5cbiAqIEByZXR1cm5zIHtCb29sZWFufSBUcnVlIGlmIHRoZSBtYXRyaWNlcyBhcmUgZXF1YWwsIGZhbHNlIG90aGVyd2lzZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXhhY3RFcXVhbHMoYSwgYikge1xuICByZXR1cm4gYVswXSA9PT0gYlswXSAmJiBhWzFdID09PSBiWzFdICYmIGFbMl0gPT09IGJbMl0gJiYgYVszXSA9PT0gYlszXSAmJiBhWzRdID09PSBiWzRdICYmIGFbNV0gPT09IGJbNV0gJiYgYVs2XSA9PT0gYls2XSAmJiBhWzddID09PSBiWzddICYmIGFbOF0gPT09IGJbOF0gJiYgYVs5XSA9PT0gYls5XSAmJiBhWzEwXSA9PT0gYlsxMF0gJiYgYVsxMV0gPT09IGJbMTFdICYmIGFbMTJdID09PSBiWzEyXSAmJiBhWzEzXSA9PT0gYlsxM10gJiYgYVsxNF0gPT09IGJbMTRdICYmIGFbMTVdID09PSBiWzE1XTtcbn1cbi8qKlxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgbWF0cmljZXMgaGF2ZSBhcHByb3hpbWF0ZWx5IHRoZSBzYW1lIGVsZW1lbnRzIGluIHRoZSBzYW1lIHBvc2l0aW9uLlxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhIFRoZSBmaXJzdCBtYXRyaXguXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYiBUaGUgc2Vjb25kIG1hdHJpeC5cbiAqIEByZXR1cm5zIHtCb29sZWFufSBUcnVlIGlmIHRoZSBtYXRyaWNlcyBhcmUgZXF1YWwsIGZhbHNlIG90aGVyd2lzZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXF1YWxzKGEsIGIpIHtcbiAgdmFyIGEwID0gYVswXSxcbiAgICAgIGExID0gYVsxXSxcbiAgICAgIGEyID0gYVsyXSxcbiAgICAgIGEzID0gYVszXTtcbiAgdmFyIGE0ID0gYVs0XSxcbiAgICAgIGE1ID0gYVs1XSxcbiAgICAgIGE2ID0gYVs2XSxcbiAgICAgIGE3ID0gYVs3XTtcbiAgdmFyIGE4ID0gYVs4XSxcbiAgICAgIGE5ID0gYVs5XSxcbiAgICAgIGExMCA9IGFbMTBdLFxuICAgICAgYTExID0gYVsxMV07XG4gIHZhciBhMTIgPSBhWzEyXSxcbiAgICAgIGExMyA9IGFbMTNdLFxuICAgICAgYTE0ID0gYVsxNF0sXG4gICAgICBhMTUgPSBhWzE1XTtcbiAgdmFyIGIwID0gYlswXSxcbiAgICAgIGIxID0gYlsxXSxcbiAgICAgIGIyID0gYlsyXSxcbiAgICAgIGIzID0gYlszXTtcbiAgdmFyIGI0ID0gYls0XSxcbiAgICAgIGI1ID0gYls1XSxcbiAgICAgIGI2ID0gYls2XSxcbiAgICAgIGI3ID0gYls3XTtcbiAgdmFyIGI4ID0gYls4XSxcbiAgICAgIGI5ID0gYls5XSxcbiAgICAgIGIxMCA9IGJbMTBdLFxuICAgICAgYjExID0gYlsxMV07XG4gIHZhciBiMTIgPSBiWzEyXSxcbiAgICAgIGIxMyA9IGJbMTNdLFxuICAgICAgYjE0ID0gYlsxNF0sXG4gICAgICBiMTUgPSBiWzE1XTtcbiAgcmV0dXJuIE1hdGguYWJzKGEwIC0gYjApIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGEwKSwgTWF0aC5hYnMoYjApKSAmJiBNYXRoLmFicyhhMSAtIGIxKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMSksIE1hdGguYWJzKGIxKSkgJiYgTWF0aC5hYnMoYTIgLSBiMikgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTIpLCBNYXRoLmFicyhiMikpICYmIE1hdGguYWJzKGEzIC0gYjMpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGEzKSwgTWF0aC5hYnMoYjMpKSAmJiBNYXRoLmFicyhhNCAtIGI0KSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhNCksIE1hdGguYWJzKGI0KSkgJiYgTWF0aC5hYnMoYTUgLSBiNSkgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTUpLCBNYXRoLmFicyhiNSkpICYmIE1hdGguYWJzKGE2IC0gYjYpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGE2KSwgTWF0aC5hYnMoYjYpKSAmJiBNYXRoLmFicyhhNyAtIGI3KSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhNyksIE1hdGguYWJzKGI3KSkgJiYgTWF0aC5hYnMoYTggLSBiOCkgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTgpLCBNYXRoLmFicyhiOCkpICYmIE1hdGguYWJzKGE5IC0gYjkpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGE5KSwgTWF0aC5hYnMoYjkpKSAmJiBNYXRoLmFicyhhMTAgLSBiMTApIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGExMCksIE1hdGguYWJzKGIxMCkpICYmIE1hdGguYWJzKGExMSAtIGIxMSkgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTExKSwgTWF0aC5hYnMoYjExKSkgJiYgTWF0aC5hYnMoYTEyIC0gYjEyKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMTIpLCBNYXRoLmFicyhiMTIpKSAmJiBNYXRoLmFicyhhMTMgLSBiMTMpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGExMyksIE1hdGguYWJzKGIxMykpICYmIE1hdGguYWJzKGExNCAtIGIxNCkgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTE0KSwgTWF0aC5hYnMoYjE0KSkgJiYgTWF0aC5hYnMoYTE1IC0gYjE1KSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMTUpLCBNYXRoLmFicyhiMTUpKTtcbn1cbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayBtYXQ0Lm11bHRpcGx5fVxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBtdWwgPSBtdWx0aXBseTtcbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayBtYXQ0LnN1YnRyYWN0fVxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBzdWIgPSBzdWJ0cmFjdDsiLCJpbXBvcnQgKiBhcyBnbE1hdHJpeCBmcm9tIFwiLi9jb21tb24uanNcIjtcbi8qKlxuICogMyBEaW1lbnNpb25hbCBWZWN0b3JcbiAqIEBtb2R1bGUgdmVjM1xuICovXG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldywgZW1wdHkgdmVjM1xuICpcbiAqIEByZXR1cm5zIHt2ZWMzfSBhIG5ldyAzRCB2ZWN0b3JcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlKCkge1xuICB2YXIgb3V0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoMyk7XG5cbiAgaWYgKGdsTWF0cml4LkFSUkFZX1RZUEUgIT0gRmxvYXQzMkFycmF5KSB7XG4gICAgb3V0WzBdID0gMDtcbiAgICBvdXRbMV0gPSAwO1xuICAgIG91dFsyXSA9IDA7XG4gIH1cblxuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHZlYzMgaW5pdGlhbGl6ZWQgd2l0aCB2YWx1ZXMgZnJvbSBhbiBleGlzdGluZyB2ZWN0b3JcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB2ZWN0b3IgdG8gY2xvbmVcbiAqIEByZXR1cm5zIHt2ZWMzfSBhIG5ldyAzRCB2ZWN0b3JcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY2xvbmUoYSkge1xuICB2YXIgb3V0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoMyk7XG4gIG91dFswXSA9IGFbMF07XG4gIG91dFsxXSA9IGFbMV07XG4gIG91dFsyXSA9IGFbMl07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGxlbmd0aCBvZiBhIHZlYzNcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB2ZWN0b3IgdG8gY2FsY3VsYXRlIGxlbmd0aCBvZlxuICogQHJldHVybnMge051bWJlcn0gbGVuZ3RoIG9mIGFcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbGVuZ3RoKGEpIHtcbiAgdmFyIHggPSBhWzBdO1xuICB2YXIgeSA9IGFbMV07XG4gIHZhciB6ID0gYVsyXTtcbiAgcmV0dXJuIE1hdGguaHlwb3QoeCwgeSwgeik7XG59XG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgdmVjMyBpbml0aWFsaXplZCB3aXRoIHRoZSBnaXZlbiB2YWx1ZXNcbiAqXG4gKiBAcGFyYW0ge051bWJlcn0geCBYIGNvbXBvbmVudFxuICogQHBhcmFtIHtOdW1iZXJ9IHkgWSBjb21wb25lbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSB6IFogY29tcG9uZW50XG4gKiBAcmV0dXJucyB7dmVjM30gYSBuZXcgM0QgdmVjdG9yXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21WYWx1ZXMoeCwgeSwgeikge1xuICB2YXIgb3V0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoMyk7XG4gIG91dFswXSA9IHg7XG4gIG91dFsxXSA9IHk7XG4gIG91dFsyXSA9IHo7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENvcHkgdGhlIHZhbHVlcyBmcm9tIG9uZSB2ZWMzIHRvIGFub3RoZXJcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdGhlIHNvdXJjZSB2ZWN0b3JcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY29weShvdXQsIGEpIHtcbiAgb3V0WzBdID0gYVswXTtcbiAgb3V0WzFdID0gYVsxXTtcbiAgb3V0WzJdID0gYVsyXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogU2V0IHRoZSBjb21wb25lbnRzIG9mIGEgdmVjMyB0byB0aGUgZ2l2ZW4gdmFsdWVzXG4gKlxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7TnVtYmVyfSB4IFggY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0geSBZIGNvbXBvbmVudFxuICogQHBhcmFtIHtOdW1iZXJ9IHogWiBjb21wb25lbnRcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc2V0KG91dCwgeCwgeSwgeikge1xuICBvdXRbMF0gPSB4O1xuICBvdXRbMV0gPSB5O1xuICBvdXRbMl0gPSB6O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBBZGRzIHR3byB2ZWMzJ3NcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhZGQob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IGFbMF0gKyBiWzBdO1xuICBvdXRbMV0gPSBhWzFdICsgYlsxXTtcbiAgb3V0WzJdID0gYVsyXSArIGJbMl07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFN1YnRyYWN0cyB2ZWN0b3IgYiBmcm9tIHZlY3RvciBhXG4gKlxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc3VidHJhY3Qob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IGFbMF0gLSBiWzBdO1xuICBvdXRbMV0gPSBhWzFdIC0gYlsxXTtcbiAgb3V0WzJdID0gYVsyXSAtIGJbMl07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIE11bHRpcGxpZXMgdHdvIHZlYzMnc1xuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG11bHRpcGx5KG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdICogYlswXTtcbiAgb3V0WzFdID0gYVsxXSAqIGJbMV07XG4gIG91dFsyXSA9IGFbMl0gKiBiWzJdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBEaXZpZGVzIHR3byB2ZWMzJ3NcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBkaXZpZGUob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IGFbMF0gLyBiWzBdO1xuICBvdXRbMV0gPSBhWzFdIC8gYlsxXTtcbiAgb3V0WzJdID0gYVsyXSAvIGJbMl07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIE1hdGguY2VpbCB0aGUgY29tcG9uZW50cyBvZiBhIHZlYzNcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdmVjdG9yIHRvIGNlaWxcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY2VpbChvdXQsIGEpIHtcbiAgb3V0WzBdID0gTWF0aC5jZWlsKGFbMF0pO1xuICBvdXRbMV0gPSBNYXRoLmNlaWwoYVsxXSk7XG4gIG91dFsyXSA9IE1hdGguY2VpbChhWzJdKTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogTWF0aC5mbG9vciB0aGUgY29tcG9uZW50cyBvZiBhIHZlYzNcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdmVjdG9yIHRvIGZsb29yXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZsb29yKG91dCwgYSkge1xuICBvdXRbMF0gPSBNYXRoLmZsb29yKGFbMF0pO1xuICBvdXRbMV0gPSBNYXRoLmZsb29yKGFbMV0pO1xuICBvdXRbMl0gPSBNYXRoLmZsb29yKGFbMl0pO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBSZXR1cm5zIHRoZSBtaW5pbXVtIG9mIHR3byB2ZWMzJ3NcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBtaW4ob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IE1hdGgubWluKGFbMF0sIGJbMF0pO1xuICBvdXRbMV0gPSBNYXRoLm1pbihhWzFdLCBiWzFdKTtcbiAgb3V0WzJdID0gTWF0aC5taW4oYVsyXSwgYlsyXSk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFJldHVybnMgdGhlIG1heGltdW0gb2YgdHdvIHZlYzMnc1xuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG1heChvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gTWF0aC5tYXgoYVswXSwgYlswXSk7XG4gIG91dFsxXSA9IE1hdGgubWF4KGFbMV0sIGJbMV0pO1xuICBvdXRbMl0gPSBNYXRoLm1heChhWzJdLCBiWzJdKTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogTWF0aC5yb3VuZCB0aGUgY29tcG9uZW50cyBvZiBhIHZlYzNcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdmVjdG9yIHRvIHJvdW5kXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJvdW5kKG91dCwgYSkge1xuICBvdXRbMF0gPSBNYXRoLnJvdW5kKGFbMF0pO1xuICBvdXRbMV0gPSBNYXRoLnJvdW5kKGFbMV0pO1xuICBvdXRbMl0gPSBNYXRoLnJvdW5kKGFbMl0pO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBTY2FsZXMgYSB2ZWMzIGJ5IGEgc2NhbGFyIG51bWJlclxuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB0aGUgdmVjdG9yIHRvIHNjYWxlXG4gKiBAcGFyYW0ge051bWJlcn0gYiBhbW91bnQgdG8gc2NhbGUgdGhlIHZlY3RvciBieVxuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzY2FsZShvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gYVswXSAqIGI7XG4gIG91dFsxXSA9IGFbMV0gKiBiO1xuICBvdXRbMl0gPSBhWzJdICogYjtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQWRkcyB0d28gdmVjMydzIGFmdGVyIHNjYWxpbmcgdGhlIHNlY29uZCBvcGVyYW5kIGJ5IGEgc2NhbGFyIHZhbHVlXG4gKlxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEBwYXJhbSB7TnVtYmVyfSBzY2FsZSB0aGUgYW1vdW50IHRvIHNjYWxlIGIgYnkgYmVmb3JlIGFkZGluZ1xuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzY2FsZUFuZEFkZChvdXQsIGEsIGIsIHNjYWxlKSB7XG4gIG91dFswXSA9IGFbMF0gKyBiWzBdICogc2NhbGU7XG4gIG91dFsxXSA9IGFbMV0gKyBiWzFdICogc2NhbGU7XG4gIG91dFsyXSA9IGFbMl0gKyBiWzJdICogc2NhbGU7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGV1Y2xpZGlhbiBkaXN0YW5jZSBiZXR3ZWVuIHR3byB2ZWMzJ3NcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBkaXN0YW5jZSBiZXR3ZWVuIGEgYW5kIGJcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZGlzdGFuY2UoYSwgYikge1xuICB2YXIgeCA9IGJbMF0gLSBhWzBdO1xuICB2YXIgeSA9IGJbMV0gLSBhWzFdO1xuICB2YXIgeiA9IGJbMl0gLSBhWzJdO1xuICByZXR1cm4gTWF0aC5oeXBvdCh4LCB5LCB6KTtcbn1cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgc3F1YXJlZCBldWNsaWRpYW4gZGlzdGFuY2UgYmV0d2VlbiB0d28gdmVjMydzXG4gKlxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge051bWJlcn0gc3F1YXJlZCBkaXN0YW5jZSBiZXR3ZWVuIGEgYW5kIGJcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc3F1YXJlZERpc3RhbmNlKGEsIGIpIHtcbiAgdmFyIHggPSBiWzBdIC0gYVswXTtcbiAgdmFyIHkgPSBiWzFdIC0gYVsxXTtcbiAgdmFyIHogPSBiWzJdIC0gYVsyXTtcbiAgcmV0dXJuIHggKiB4ICsgeSAqIHkgKyB6ICogejtcbn1cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgc3F1YXJlZCBsZW5ndGggb2YgYSB2ZWMzXG4gKlxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdmVjdG9yIHRvIGNhbGN1bGF0ZSBzcXVhcmVkIGxlbmd0aCBvZlxuICogQHJldHVybnMge051bWJlcn0gc3F1YXJlZCBsZW5ndGggb2YgYVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzcXVhcmVkTGVuZ3RoKGEpIHtcbiAgdmFyIHggPSBhWzBdO1xuICB2YXIgeSA9IGFbMV07XG4gIHZhciB6ID0gYVsyXTtcbiAgcmV0dXJuIHggKiB4ICsgeSAqIHkgKyB6ICogejtcbn1cbi8qKlxuICogTmVnYXRlcyB0aGUgY29tcG9uZW50cyBvZiBhIHZlYzNcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdmVjdG9yIHRvIG5lZ2F0ZVxuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBuZWdhdGUob3V0LCBhKSB7XG4gIG91dFswXSA9IC1hWzBdO1xuICBvdXRbMV0gPSAtYVsxXTtcbiAgb3V0WzJdID0gLWFbMl07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFJldHVybnMgdGhlIGludmVyc2Ugb2YgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWMzXG4gKlxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHZlY3RvciB0byBpbnZlcnRcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaW52ZXJzZShvdXQsIGEpIHtcbiAgb3V0WzBdID0gMS4wIC8gYVswXTtcbiAgb3V0WzFdID0gMS4wIC8gYVsxXTtcbiAgb3V0WzJdID0gMS4wIC8gYVsyXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogTm9ybWFsaXplIGEgdmVjM1xuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB2ZWN0b3IgdG8gbm9ybWFsaXplXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZShvdXQsIGEpIHtcbiAgdmFyIHggPSBhWzBdO1xuICB2YXIgeSA9IGFbMV07XG4gIHZhciB6ID0gYVsyXTtcbiAgdmFyIGxlbiA9IHggKiB4ICsgeSAqIHkgKyB6ICogejtcblxuICBpZiAobGVuID4gMCkge1xuICAgIC8vVE9ETzogZXZhbHVhdGUgdXNlIG9mIGdsbV9pbnZzcXJ0IGhlcmU/XG4gICAgbGVuID0gMSAvIE1hdGguc3FydChsZW4pO1xuICB9XG5cbiAgb3V0WzBdID0gYVswXSAqIGxlbjtcbiAgb3V0WzFdID0gYVsxXSAqIGxlbjtcbiAgb3V0WzJdID0gYVsyXSAqIGxlbjtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgZG90IHByb2R1Y3Qgb2YgdHdvIHZlYzMnc1xuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IGRvdCBwcm9kdWN0IG9mIGEgYW5kIGJcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZG90KGEsIGIpIHtcbiAgcmV0dXJuIGFbMF0gKiBiWzBdICsgYVsxXSAqIGJbMV0gKyBhWzJdICogYlsyXTtcbn1cbi8qKlxuICogQ29tcHV0ZXMgdGhlIGNyb3NzIHByb2R1Y3Qgb2YgdHdvIHZlYzMnc1xuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyb3NzKG91dCwgYSwgYikge1xuICB2YXIgYXggPSBhWzBdLFxuICAgICAgYXkgPSBhWzFdLFxuICAgICAgYXogPSBhWzJdO1xuICB2YXIgYnggPSBiWzBdLFxuICAgICAgYnkgPSBiWzFdLFxuICAgICAgYnogPSBiWzJdO1xuICBvdXRbMF0gPSBheSAqIGJ6IC0gYXogKiBieTtcbiAgb3V0WzFdID0gYXogKiBieCAtIGF4ICogYno7XG4gIG91dFsyXSA9IGF4ICogYnkgLSBheSAqIGJ4O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBQZXJmb3JtcyBhIGxpbmVhciBpbnRlcnBvbGF0aW9uIGJldHdlZW4gdHdvIHZlYzMnc1xuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcGFyYW0ge051bWJlcn0gdCBpbnRlcnBvbGF0aW9uIGFtb3VudCwgaW4gdGhlIHJhbmdlIFswLTFdLCBiZXR3ZWVuIHRoZSB0d28gaW5wdXRzXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGxlcnAob3V0LCBhLCBiLCB0KSB7XG4gIHZhciBheCA9IGFbMF07XG4gIHZhciBheSA9IGFbMV07XG4gIHZhciBheiA9IGFbMl07XG4gIG91dFswXSA9IGF4ICsgdCAqIChiWzBdIC0gYXgpO1xuICBvdXRbMV0gPSBheSArIHQgKiAoYlsxXSAtIGF5KTtcbiAgb3V0WzJdID0gYXogKyB0ICogKGJbMl0gLSBheik7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFBlcmZvcm1zIGEgaGVybWl0ZSBpbnRlcnBvbGF0aW9uIHdpdGggdHdvIGNvbnRyb2wgcG9pbnRzXG4gKlxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBjIHRoZSB0aGlyZCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gZCB0aGUgZm91cnRoIG9wZXJhbmRcbiAqIEBwYXJhbSB7TnVtYmVyfSB0IGludGVycG9sYXRpb24gYW1vdW50LCBpbiB0aGUgcmFuZ2UgWzAtMV0sIGJldHdlZW4gdGhlIHR3byBpbnB1dHNcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaGVybWl0ZShvdXQsIGEsIGIsIGMsIGQsIHQpIHtcbiAgdmFyIGZhY3RvclRpbWVzMiA9IHQgKiB0O1xuICB2YXIgZmFjdG9yMSA9IGZhY3RvclRpbWVzMiAqICgyICogdCAtIDMpICsgMTtcbiAgdmFyIGZhY3RvcjIgPSBmYWN0b3JUaW1lczIgKiAodCAtIDIpICsgdDtcbiAgdmFyIGZhY3RvcjMgPSBmYWN0b3JUaW1lczIgKiAodCAtIDEpO1xuICB2YXIgZmFjdG9yNCA9IGZhY3RvclRpbWVzMiAqICgzIC0gMiAqIHQpO1xuICBvdXRbMF0gPSBhWzBdICogZmFjdG9yMSArIGJbMF0gKiBmYWN0b3IyICsgY1swXSAqIGZhY3RvcjMgKyBkWzBdICogZmFjdG9yNDtcbiAgb3V0WzFdID0gYVsxXSAqIGZhY3RvcjEgKyBiWzFdICogZmFjdG9yMiArIGNbMV0gKiBmYWN0b3IzICsgZFsxXSAqIGZhY3RvcjQ7XG4gIG91dFsyXSA9IGFbMl0gKiBmYWN0b3IxICsgYlsyXSAqIGZhY3RvcjIgKyBjWzJdICogZmFjdG9yMyArIGRbMl0gKiBmYWN0b3I0O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBQZXJmb3JtcyBhIGJlemllciBpbnRlcnBvbGF0aW9uIHdpdGggdHdvIGNvbnRyb2wgcG9pbnRzXG4gKlxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBjIHRoZSB0aGlyZCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gZCB0aGUgZm91cnRoIG9wZXJhbmRcbiAqIEBwYXJhbSB7TnVtYmVyfSB0IGludGVycG9sYXRpb24gYW1vdW50LCBpbiB0aGUgcmFuZ2UgWzAtMV0sIGJldHdlZW4gdGhlIHR3byBpbnB1dHNcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYmV6aWVyKG91dCwgYSwgYiwgYywgZCwgdCkge1xuICB2YXIgaW52ZXJzZUZhY3RvciA9IDEgLSB0O1xuICB2YXIgaW52ZXJzZUZhY3RvclRpbWVzVHdvID0gaW52ZXJzZUZhY3RvciAqIGludmVyc2VGYWN0b3I7XG4gIHZhciBmYWN0b3JUaW1lczIgPSB0ICogdDtcbiAgdmFyIGZhY3RvcjEgPSBpbnZlcnNlRmFjdG9yVGltZXNUd28gKiBpbnZlcnNlRmFjdG9yO1xuICB2YXIgZmFjdG9yMiA9IDMgKiB0ICogaW52ZXJzZUZhY3RvclRpbWVzVHdvO1xuICB2YXIgZmFjdG9yMyA9IDMgKiBmYWN0b3JUaW1lczIgKiBpbnZlcnNlRmFjdG9yO1xuICB2YXIgZmFjdG9yNCA9IGZhY3RvclRpbWVzMiAqIHQ7XG4gIG91dFswXSA9IGFbMF0gKiBmYWN0b3IxICsgYlswXSAqIGZhY3RvcjIgKyBjWzBdICogZmFjdG9yMyArIGRbMF0gKiBmYWN0b3I0O1xuICBvdXRbMV0gPSBhWzFdICogZmFjdG9yMSArIGJbMV0gKiBmYWN0b3IyICsgY1sxXSAqIGZhY3RvcjMgKyBkWzFdICogZmFjdG9yNDtcbiAgb3V0WzJdID0gYVsyXSAqIGZhY3RvcjEgKyBiWzJdICogZmFjdG9yMiArIGNbMl0gKiBmYWN0b3IzICsgZFsyXSAqIGZhY3RvcjQ7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIEdlbmVyYXRlcyBhIHJhbmRvbSB2ZWN0b3Igd2l0aCB0aGUgZ2l2ZW4gc2NhbGVcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtOdW1iZXJ9IFtzY2FsZV0gTGVuZ3RoIG9mIHRoZSByZXN1bHRpbmcgdmVjdG9yLiBJZiBvbW1pdHRlZCwgYSB1bml0IHZlY3RvciB3aWxsIGJlIHJldHVybmVkXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJhbmRvbShvdXQsIHNjYWxlKSB7XG4gIHNjYWxlID0gc2NhbGUgfHwgMS4wO1xuICB2YXIgciA9IGdsTWF0cml4LlJBTkRPTSgpICogMi4wICogTWF0aC5QSTtcbiAgdmFyIHogPSBnbE1hdHJpeC5SQU5ET00oKSAqIDIuMCAtIDEuMDtcbiAgdmFyIHpTY2FsZSA9IE1hdGguc3FydCgxLjAgLSB6ICogeikgKiBzY2FsZTtcbiAgb3V0WzBdID0gTWF0aC5jb3MocikgKiB6U2NhbGU7XG4gIG91dFsxXSA9IE1hdGguc2luKHIpICogelNjYWxlO1xuICBvdXRbMl0gPSB6ICogc2NhbGU7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFRyYW5zZm9ybXMgdGhlIHZlYzMgd2l0aCBhIG1hdDQuXG4gKiA0dGggdmVjdG9yIGNvbXBvbmVudCBpcyBpbXBsaWNpdGx5ICcxJ1xuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB0aGUgdmVjdG9yIHRvIHRyYW5zZm9ybVxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IG0gbWF0cml4IHRvIHRyYW5zZm9ybSB3aXRoXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybU1hdDQob3V0LCBhLCBtKSB7XG4gIHZhciB4ID0gYVswXSxcbiAgICAgIHkgPSBhWzFdLFxuICAgICAgeiA9IGFbMl07XG4gIHZhciB3ID0gbVszXSAqIHggKyBtWzddICogeSArIG1bMTFdICogeiArIG1bMTVdO1xuICB3ID0gdyB8fCAxLjA7XG4gIG91dFswXSA9IChtWzBdICogeCArIG1bNF0gKiB5ICsgbVs4XSAqIHogKyBtWzEyXSkgLyB3O1xuICBvdXRbMV0gPSAobVsxXSAqIHggKyBtWzVdICogeSArIG1bOV0gKiB6ICsgbVsxM10pIC8gdztcbiAgb3V0WzJdID0gKG1bMl0gKiB4ICsgbVs2XSAqIHkgKyBtWzEwXSAqIHogKyBtWzE0XSkgLyB3O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBUcmFuc2Zvcm1zIHRoZSB2ZWMzIHdpdGggYSBtYXQzLlxuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB0aGUgdmVjdG9yIHRvIHRyYW5zZm9ybVxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IG0gdGhlIDN4MyBtYXRyaXggdG8gdHJhbnNmb3JtIHdpdGhcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNmb3JtTWF0MyhvdXQsIGEsIG0pIHtcbiAgdmFyIHggPSBhWzBdLFxuICAgICAgeSA9IGFbMV0sXG4gICAgICB6ID0gYVsyXTtcbiAgb3V0WzBdID0geCAqIG1bMF0gKyB5ICogbVszXSArIHogKiBtWzZdO1xuICBvdXRbMV0gPSB4ICogbVsxXSArIHkgKiBtWzRdICsgeiAqIG1bN107XG4gIG91dFsyXSA9IHggKiBtWzJdICsgeSAqIG1bNV0gKyB6ICogbVs4XTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogVHJhbnNmb3JtcyB0aGUgdmVjMyB3aXRoIGEgcXVhdFxuICogQ2FuIGFsc28gYmUgdXNlZCBmb3IgZHVhbCBxdWF0ZXJuaW9ucy4gKE11bHRpcGx5IGl0IHdpdGggdGhlIHJlYWwgcGFydClcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdGhlIHZlY3RvciB0byB0cmFuc2Zvcm1cbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBxIHF1YXRlcm5pb24gdG8gdHJhbnNmb3JtIHdpdGhcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNmb3JtUXVhdChvdXQsIGEsIHEpIHtcbiAgLy8gYmVuY2htYXJrczogaHR0cHM6Ly9qc3BlcmYuY29tL3F1YXRlcm5pb24tdHJhbnNmb3JtLXZlYzMtaW1wbGVtZW50YXRpb25zLWZpeGVkXG4gIHZhciBxeCA9IHFbMF0sXG4gICAgICBxeSA9IHFbMV0sXG4gICAgICBxeiA9IHFbMl0sXG4gICAgICBxdyA9IHFbM107XG4gIHZhciB4ID0gYVswXSxcbiAgICAgIHkgPSBhWzFdLFxuICAgICAgeiA9IGFbMl07IC8vIHZhciBxdmVjID0gW3F4LCBxeSwgcXpdO1xuICAvLyB2YXIgdXYgPSB2ZWMzLmNyb3NzKFtdLCBxdmVjLCBhKTtcblxuICB2YXIgdXZ4ID0gcXkgKiB6IC0gcXogKiB5LFxuICAgICAgdXZ5ID0gcXogKiB4IC0gcXggKiB6LFxuICAgICAgdXZ6ID0gcXggKiB5IC0gcXkgKiB4OyAvLyB2YXIgdXV2ID0gdmVjMy5jcm9zcyhbXSwgcXZlYywgdXYpO1xuXG4gIHZhciB1dXZ4ID0gcXkgKiB1dnogLSBxeiAqIHV2eSxcbiAgICAgIHV1dnkgPSBxeiAqIHV2eCAtIHF4ICogdXZ6LFxuICAgICAgdXV2eiA9IHF4ICogdXZ5IC0gcXkgKiB1dng7IC8vIHZlYzMuc2NhbGUodXYsIHV2LCAyICogdyk7XG5cbiAgdmFyIHcyID0gcXcgKiAyO1xuICB1dnggKj0gdzI7XG4gIHV2eSAqPSB3MjtcbiAgdXZ6ICo9IHcyOyAvLyB2ZWMzLnNjYWxlKHV1diwgdXV2LCAyKTtcblxuICB1dXZ4ICo9IDI7XG4gIHV1dnkgKj0gMjtcbiAgdXV2eiAqPSAyOyAvLyByZXR1cm4gdmVjMy5hZGQob3V0LCBhLCB2ZWMzLmFkZChvdXQsIHV2LCB1dXYpKTtcblxuICBvdXRbMF0gPSB4ICsgdXZ4ICsgdXV2eDtcbiAgb3V0WzFdID0geSArIHV2eSArIHV1dnk7XG4gIG91dFsyXSA9IHogKyB1dnogKyB1dXZ6O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBSb3RhdGUgYSAzRCB2ZWN0b3IgYXJvdW5kIHRoZSB4LWF4aXNcbiAqIEBwYXJhbSB7dmVjM30gb3V0IFRoZSByZWNlaXZpbmcgdmVjM1xuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgVGhlIHZlYzMgcG9pbnQgdG8gcm90YXRlXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYiBUaGUgb3JpZ2luIG9mIHRoZSByb3RhdGlvblxuICogQHBhcmFtIHtOdW1iZXJ9IHJhZCBUaGUgYW5nbGUgb2Ygcm90YXRpb24gaW4gcmFkaWFuc1xuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByb3RhdGVYKG91dCwgYSwgYiwgcmFkKSB7XG4gIHZhciBwID0gW10sXG4gICAgICByID0gW107IC8vVHJhbnNsYXRlIHBvaW50IHRvIHRoZSBvcmlnaW5cblxuICBwWzBdID0gYVswXSAtIGJbMF07XG4gIHBbMV0gPSBhWzFdIC0gYlsxXTtcbiAgcFsyXSA9IGFbMl0gLSBiWzJdOyAvL3BlcmZvcm0gcm90YXRpb25cblxuICByWzBdID0gcFswXTtcbiAgclsxXSA9IHBbMV0gKiBNYXRoLmNvcyhyYWQpIC0gcFsyXSAqIE1hdGguc2luKHJhZCk7XG4gIHJbMl0gPSBwWzFdICogTWF0aC5zaW4ocmFkKSArIHBbMl0gKiBNYXRoLmNvcyhyYWQpOyAvL3RyYW5zbGF0ZSB0byBjb3JyZWN0IHBvc2l0aW9uXG5cbiAgb3V0WzBdID0gclswXSArIGJbMF07XG4gIG91dFsxXSA9IHJbMV0gKyBiWzFdO1xuICBvdXRbMl0gPSByWzJdICsgYlsyXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUm90YXRlIGEgM0QgdmVjdG9yIGFyb3VuZCB0aGUgeS1heGlzXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCBUaGUgcmVjZWl2aW5nIHZlYzNcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIFRoZSB2ZWMzIHBvaW50IHRvIHJvdGF0ZVxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGIgVGhlIG9yaWdpbiBvZiB0aGUgcm90YXRpb25cbiAqIEBwYXJhbSB7TnVtYmVyfSByYWQgVGhlIGFuZ2xlIG9mIHJvdGF0aW9uIGluIHJhZGlhbnNcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcm90YXRlWShvdXQsIGEsIGIsIHJhZCkge1xuICB2YXIgcCA9IFtdLFxuICAgICAgciA9IFtdOyAvL1RyYW5zbGF0ZSBwb2ludCB0byB0aGUgb3JpZ2luXG5cbiAgcFswXSA9IGFbMF0gLSBiWzBdO1xuICBwWzFdID0gYVsxXSAtIGJbMV07XG4gIHBbMl0gPSBhWzJdIC0gYlsyXTsgLy9wZXJmb3JtIHJvdGF0aW9uXG5cbiAgclswXSA9IHBbMl0gKiBNYXRoLnNpbihyYWQpICsgcFswXSAqIE1hdGguY29zKHJhZCk7XG4gIHJbMV0gPSBwWzFdO1xuICByWzJdID0gcFsyXSAqIE1hdGguY29zKHJhZCkgLSBwWzBdICogTWF0aC5zaW4ocmFkKTsgLy90cmFuc2xhdGUgdG8gY29ycmVjdCBwb3NpdGlvblxuXG4gIG91dFswXSA9IHJbMF0gKyBiWzBdO1xuICBvdXRbMV0gPSByWzFdICsgYlsxXTtcbiAgb3V0WzJdID0gclsyXSArIGJbMl07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFJvdGF0ZSBhIDNEIHZlY3RvciBhcm91bmQgdGhlIHotYXhpc1xuICogQHBhcmFtIHt2ZWMzfSBvdXQgVGhlIHJlY2VpdmluZyB2ZWMzXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSBUaGUgdmVjMyBwb2ludCB0byByb3RhdGVcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBiIFRoZSBvcmlnaW4gb2YgdGhlIHJvdGF0aW9uXG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIFRoZSBhbmdsZSBvZiByb3RhdGlvbiBpbiByYWRpYW5zXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJvdGF0ZVoob3V0LCBhLCBiLCByYWQpIHtcbiAgdmFyIHAgPSBbXSxcbiAgICAgIHIgPSBbXTsgLy9UcmFuc2xhdGUgcG9pbnQgdG8gdGhlIG9yaWdpblxuXG4gIHBbMF0gPSBhWzBdIC0gYlswXTtcbiAgcFsxXSA9IGFbMV0gLSBiWzFdO1xuICBwWzJdID0gYVsyXSAtIGJbMl07IC8vcGVyZm9ybSByb3RhdGlvblxuXG4gIHJbMF0gPSBwWzBdICogTWF0aC5jb3MocmFkKSAtIHBbMV0gKiBNYXRoLnNpbihyYWQpO1xuICByWzFdID0gcFswXSAqIE1hdGguc2luKHJhZCkgKyBwWzFdICogTWF0aC5jb3MocmFkKTtcbiAgclsyXSA9IHBbMl07IC8vdHJhbnNsYXRlIHRvIGNvcnJlY3QgcG9zaXRpb25cblxuICBvdXRbMF0gPSByWzBdICsgYlswXTtcbiAgb3V0WzFdID0gclsxXSArIGJbMV07XG4gIG91dFsyXSA9IHJbMl0gKyBiWzJdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBHZXQgdGhlIGFuZ2xlIGJldHdlZW4gdHdvIDNEIHZlY3RvcnNcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIFRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYiBUaGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IFRoZSBhbmdsZSBpbiByYWRpYW5zXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGFuZ2xlKGEsIGIpIHtcbiAgdmFyIGF4ID0gYVswXSxcbiAgICAgIGF5ID0gYVsxXSxcbiAgICAgIGF6ID0gYVsyXSxcbiAgICAgIGJ4ID0gYlswXSxcbiAgICAgIGJ5ID0gYlsxXSxcbiAgICAgIGJ6ID0gYlsyXSxcbiAgICAgIG1hZzEgPSBNYXRoLnNxcnQoYXggKiBheCArIGF5ICogYXkgKyBheiAqIGF6KSxcbiAgICAgIG1hZzIgPSBNYXRoLnNxcnQoYnggKiBieCArIGJ5ICogYnkgKyBieiAqIGJ6KSxcbiAgICAgIG1hZyA9IG1hZzEgKiBtYWcyLFxuICAgICAgY29zaW5lID0gbWFnICYmIGRvdChhLCBiKSAvIG1hZztcbiAgcmV0dXJuIE1hdGguYWNvcyhNYXRoLm1pbihNYXRoLm1heChjb3NpbmUsIC0xKSwgMSkpO1xufVxuLyoqXG4gKiBTZXQgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWMzIHRvIHplcm9cbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB6ZXJvKG91dCkge1xuICBvdXRbMF0gPSAwLjA7XG4gIG91dFsxXSA9IDAuMDtcbiAgb3V0WzJdID0gMC4wO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgdmVjdG9yXG4gKlxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdmVjdG9yIHRvIHJlcHJlc2VudCBhcyBhIHN0cmluZ1xuICogQHJldHVybnMge1N0cmluZ30gc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB2ZWN0b3JcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc3RyKGEpIHtcbiAgcmV0dXJuIFwidmVjMyhcIiArIGFbMF0gKyBcIiwgXCIgKyBhWzFdICsgXCIsIFwiICsgYVsyXSArIFwiKVwiO1xufVxuLyoqXG4gKiBSZXR1cm5zIHdoZXRoZXIgb3Igbm90IHRoZSB2ZWN0b3JzIGhhdmUgZXhhY3RseSB0aGUgc2FtZSBlbGVtZW50cyBpbiB0aGUgc2FtZSBwb3NpdGlvbiAod2hlbiBjb21wYXJlZCB3aXRoID09PSlcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSBUaGUgZmlyc3QgdmVjdG9yLlxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGIgVGhlIHNlY29uZCB2ZWN0b3IuXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gVHJ1ZSBpZiB0aGUgdmVjdG9ycyBhcmUgZXF1YWwsIGZhbHNlIG90aGVyd2lzZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXhhY3RFcXVhbHMoYSwgYikge1xuICByZXR1cm4gYVswXSA9PT0gYlswXSAmJiBhWzFdID09PSBiWzFdICYmIGFbMl0gPT09IGJbMl07XG59XG4vKipcbiAqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhlIHZlY3RvcnMgaGF2ZSBhcHByb3hpbWF0ZWx5IHRoZSBzYW1lIGVsZW1lbnRzIGluIHRoZSBzYW1lIHBvc2l0aW9uLlxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIFRoZSBmaXJzdCB2ZWN0b3IuXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYiBUaGUgc2Vjb25kIHZlY3Rvci5cbiAqIEByZXR1cm5zIHtCb29sZWFufSBUcnVlIGlmIHRoZSB2ZWN0b3JzIGFyZSBlcXVhbCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBlcXVhbHMoYSwgYikge1xuICB2YXIgYTAgPSBhWzBdLFxuICAgICAgYTEgPSBhWzFdLFxuICAgICAgYTIgPSBhWzJdO1xuICB2YXIgYjAgPSBiWzBdLFxuICAgICAgYjEgPSBiWzFdLFxuICAgICAgYjIgPSBiWzJdO1xuICByZXR1cm4gTWF0aC5hYnMoYTAgLSBiMCkgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTApLCBNYXRoLmFicyhiMCkpICYmIE1hdGguYWJzKGExIC0gYjEpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGExKSwgTWF0aC5hYnMoYjEpKSAmJiBNYXRoLmFicyhhMiAtIGIyKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMiksIE1hdGguYWJzKGIyKSk7XG59XG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjMy5zdWJ0cmFjdH1cbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgc3ViID0gc3VidHJhY3Q7XG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjMy5tdWx0aXBseX1cbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgbXVsID0gbXVsdGlwbHk7XG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjMy5kaXZpZGV9XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIGRpdiA9IGRpdmlkZTtcbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayB2ZWMzLmRpc3RhbmNlfVxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBkaXN0ID0gZGlzdGFuY2U7XG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjMy5zcXVhcmVkRGlzdGFuY2V9XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIHNxckRpc3QgPSBzcXVhcmVkRGlzdGFuY2U7XG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjMy5sZW5ndGh9XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIGxlbiA9IGxlbmd0aDtcbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayB2ZWMzLnNxdWFyZWRMZW5ndGh9XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIHNxckxlbiA9IHNxdWFyZWRMZW5ndGg7XG4vKipcbiAqIFBlcmZvcm0gc29tZSBvcGVyYXRpb24gb3ZlciBhbiBhcnJheSBvZiB2ZWMzcy5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBhIHRoZSBhcnJheSBvZiB2ZWN0b3JzIHRvIGl0ZXJhdGUgb3ZlclxuICogQHBhcmFtIHtOdW1iZXJ9IHN0cmlkZSBOdW1iZXIgb2YgZWxlbWVudHMgYmV0d2VlbiB0aGUgc3RhcnQgb2YgZWFjaCB2ZWMzLiBJZiAwIGFzc3VtZXMgdGlnaHRseSBwYWNrZWRcbiAqIEBwYXJhbSB7TnVtYmVyfSBvZmZzZXQgTnVtYmVyIG9mIGVsZW1lbnRzIHRvIHNraXAgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgYXJyYXlcbiAqIEBwYXJhbSB7TnVtYmVyfSBjb3VudCBOdW1iZXIgb2YgdmVjM3MgdG8gaXRlcmF0ZSBvdmVyLiBJZiAwIGl0ZXJhdGVzIG92ZXIgZW50aXJlIGFycmF5XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBGdW5jdGlvbiB0byBjYWxsIGZvciBlYWNoIHZlY3RvciBpbiB0aGUgYXJyYXlcbiAqIEBwYXJhbSB7T2JqZWN0fSBbYXJnXSBhZGRpdGlvbmFsIGFyZ3VtZW50IHRvIHBhc3MgdG8gZm5cbiAqIEByZXR1cm5zIHtBcnJheX0gYVxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBmb3JFYWNoID0gZnVuY3Rpb24gKCkge1xuICB2YXIgdmVjID0gY3JlYXRlKCk7XG4gIHJldHVybiBmdW5jdGlvbiAoYSwgc3RyaWRlLCBvZmZzZXQsIGNvdW50LCBmbiwgYXJnKSB7XG4gICAgdmFyIGksIGw7XG5cbiAgICBpZiAoIXN0cmlkZSkge1xuICAgICAgc3RyaWRlID0gMztcbiAgICB9XG5cbiAgICBpZiAoIW9mZnNldCkge1xuICAgICAgb2Zmc2V0ID0gMDtcbiAgICB9XG5cbiAgICBpZiAoY291bnQpIHtcbiAgICAgIGwgPSBNYXRoLm1pbihjb3VudCAqIHN0cmlkZSArIG9mZnNldCwgYS5sZW5ndGgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsID0gYS5sZW5ndGg7XG4gICAgfVxuXG4gICAgZm9yIChpID0gb2Zmc2V0OyBpIDwgbDsgaSArPSBzdHJpZGUpIHtcbiAgICAgIHZlY1swXSA9IGFbaV07XG4gICAgICB2ZWNbMV0gPSBhW2kgKyAxXTtcbiAgICAgIHZlY1syXSA9IGFbaSArIDJdO1xuICAgICAgZm4odmVjLCB2ZWMsIGFyZyk7XG4gICAgICBhW2ldID0gdmVjWzBdO1xuICAgICAgYVtpICsgMV0gPSB2ZWNbMV07XG4gICAgICBhW2kgKyAyXSA9IHZlY1syXTtcbiAgICB9XG5cbiAgICByZXR1cm4gYTtcbiAgfTtcbn0oKTsiLCJpbXBvcnQgKiBhcyBnbE1hdHJpeCBmcm9tIFwiLi9jb21tb24uanNcIjtcbi8qKlxuICogNCBEaW1lbnNpb25hbCBWZWN0b3JcbiAqIEBtb2R1bGUgdmVjNFxuICovXG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldywgZW1wdHkgdmVjNFxuICpcbiAqIEByZXR1cm5zIHt2ZWM0fSBhIG5ldyA0RCB2ZWN0b3JcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlKCkge1xuICB2YXIgb3V0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoNCk7XG5cbiAgaWYgKGdsTWF0cml4LkFSUkFZX1RZUEUgIT0gRmxvYXQzMkFycmF5KSB7XG4gICAgb3V0WzBdID0gMDtcbiAgICBvdXRbMV0gPSAwO1xuICAgIG91dFsyXSA9IDA7XG4gICAgb3V0WzNdID0gMDtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgdmVjNCBpbml0aWFsaXplZCB3aXRoIHZhbHVlcyBmcm9tIGFuIGV4aXN0aW5nIHZlY3RvclxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHZlY3RvciB0byBjbG9uZVxuICogQHJldHVybnMge3ZlYzR9IGEgbmV3IDREIHZlY3RvclxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjbG9uZShhKSB7XG4gIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSg0KTtcbiAgb3V0WzBdID0gYVswXTtcbiAgb3V0WzFdID0gYVsxXTtcbiAgb3V0WzJdID0gYVsyXTtcbiAgb3V0WzNdID0gYVszXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyB2ZWM0IGluaXRpYWxpemVkIHdpdGggdGhlIGdpdmVuIHZhbHVlc1xuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSB4IFggY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0geSBZIGNvbXBvbmVudFxuICogQHBhcmFtIHtOdW1iZXJ9IHogWiBjb21wb25lbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSB3IFcgY29tcG9uZW50XG4gKiBAcmV0dXJucyB7dmVjNH0gYSBuZXcgNEQgdmVjdG9yXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21WYWx1ZXMoeCwgeSwgeiwgdykge1xuICB2YXIgb3V0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoNCk7XG4gIG91dFswXSA9IHg7XG4gIG91dFsxXSA9IHk7XG4gIG91dFsyXSA9IHo7XG4gIG91dFszXSA9IHc7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENvcHkgdGhlIHZhbHVlcyBmcm9tIG9uZSB2ZWM0IHRvIGFub3RoZXJcbiAqXG4gKiBAcGFyYW0ge3ZlYzR9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgdGhlIHNvdXJjZSB2ZWN0b3JcbiAqIEByZXR1cm5zIHt2ZWM0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY29weShvdXQsIGEpIHtcbiAgb3V0WzBdID0gYVswXTtcbiAgb3V0WzFdID0gYVsxXTtcbiAgb3V0WzJdID0gYVsyXTtcbiAgb3V0WzNdID0gYVszXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogU2V0IHRoZSBjb21wb25lbnRzIG9mIGEgdmVjNCB0byB0aGUgZ2l2ZW4gdmFsdWVzXG4gKlxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7TnVtYmVyfSB4IFggY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0geSBZIGNvbXBvbmVudFxuICogQHBhcmFtIHtOdW1iZXJ9IHogWiBjb21wb25lbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSB3IFcgY29tcG9uZW50XG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNldChvdXQsIHgsIHksIHosIHcpIHtcbiAgb3V0WzBdID0geDtcbiAgb3V0WzFdID0geTtcbiAgb3V0WzJdID0gejtcbiAgb3V0WzNdID0gdztcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQWRkcyB0d28gdmVjNCdzXG4gKlxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHt2ZWM0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYWRkKG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdICsgYlswXTtcbiAgb3V0WzFdID0gYVsxXSArIGJbMV07XG4gIG91dFsyXSA9IGFbMl0gKyBiWzJdO1xuICBvdXRbM10gPSBhWzNdICsgYlszXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogU3VidHJhY3RzIHZlY3RvciBiIGZyb20gdmVjdG9yIGFcbiAqXG4gKiBAcGFyYW0ge3ZlYzR9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzdWJ0cmFjdChvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gYVswXSAtIGJbMF07XG4gIG91dFsxXSA9IGFbMV0gLSBiWzFdO1xuICBvdXRbMl0gPSBhWzJdIC0gYlsyXTtcbiAgb3V0WzNdID0gYVszXSAtIGJbM107XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIE11bHRpcGxpZXMgdHdvIHZlYzQnc1xuICpcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG11bHRpcGx5KG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdICogYlswXTtcbiAgb3V0WzFdID0gYVsxXSAqIGJbMV07XG4gIG91dFsyXSA9IGFbMl0gKiBiWzJdO1xuICBvdXRbM10gPSBhWzNdICogYlszXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogRGl2aWRlcyB0d28gdmVjNCdzXG4gKlxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHt2ZWM0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZGl2aWRlKG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdIC8gYlswXTtcbiAgb3V0WzFdID0gYVsxXSAvIGJbMV07XG4gIG91dFsyXSA9IGFbMl0gLyBiWzJdO1xuICBvdXRbM10gPSBhWzNdIC8gYlszXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogTWF0aC5jZWlsIHRoZSBjb21wb25lbnRzIG9mIGEgdmVjNFxuICpcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSB2ZWN0b3IgdG8gY2VpbFxuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjZWlsKG91dCwgYSkge1xuICBvdXRbMF0gPSBNYXRoLmNlaWwoYVswXSk7XG4gIG91dFsxXSA9IE1hdGguY2VpbChhWzFdKTtcbiAgb3V0WzJdID0gTWF0aC5jZWlsKGFbMl0pO1xuICBvdXRbM10gPSBNYXRoLmNlaWwoYVszXSk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIE1hdGguZmxvb3IgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWM0XG4gKlxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHZlY3RvciB0byBmbG9vclxuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmbG9vcihvdXQsIGEpIHtcbiAgb3V0WzBdID0gTWF0aC5mbG9vcihhWzBdKTtcbiAgb3V0WzFdID0gTWF0aC5mbG9vcihhWzFdKTtcbiAgb3V0WzJdID0gTWF0aC5mbG9vcihhWzJdKTtcbiAgb3V0WzNdID0gTWF0aC5mbG9vcihhWzNdKTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUmV0dXJucyB0aGUgbWluaW11bSBvZiB0d28gdmVjNCdzXG4gKlxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHt2ZWM0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbWluKG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBNYXRoLm1pbihhWzBdLCBiWzBdKTtcbiAgb3V0WzFdID0gTWF0aC5taW4oYVsxXSwgYlsxXSk7XG4gIG91dFsyXSA9IE1hdGgubWluKGFbMl0sIGJbMl0pO1xuICBvdXRbM10gPSBNYXRoLm1pbihhWzNdLCBiWzNdKTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUmV0dXJucyB0aGUgbWF4aW11bSBvZiB0d28gdmVjNCdzXG4gKlxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHt2ZWM0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbWF4KG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBNYXRoLm1heChhWzBdLCBiWzBdKTtcbiAgb3V0WzFdID0gTWF0aC5tYXgoYVsxXSwgYlsxXSk7XG4gIG91dFsyXSA9IE1hdGgubWF4KGFbMl0sIGJbMl0pO1xuICBvdXRbM10gPSBNYXRoLm1heChhWzNdLCBiWzNdKTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogTWF0aC5yb3VuZCB0aGUgY29tcG9uZW50cyBvZiBhIHZlYzRcbiAqXG4gKiBAcGFyYW0ge3ZlYzR9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgdmVjdG9yIHRvIHJvdW5kXG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJvdW5kKG91dCwgYSkge1xuICBvdXRbMF0gPSBNYXRoLnJvdW5kKGFbMF0pO1xuICBvdXRbMV0gPSBNYXRoLnJvdW5kKGFbMV0pO1xuICBvdXRbMl0gPSBNYXRoLnJvdW5kKGFbMl0pO1xuICBvdXRbM10gPSBNYXRoLnJvdW5kKGFbM10pO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBTY2FsZXMgYSB2ZWM0IGJ5IGEgc2NhbGFyIG51bWJlclxuICpcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSB0aGUgdmVjdG9yIHRvIHNjYWxlXG4gKiBAcGFyYW0ge051bWJlcn0gYiBhbW91bnQgdG8gc2NhbGUgdGhlIHZlY3RvciBieVxuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzY2FsZShvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gYVswXSAqIGI7XG4gIG91dFsxXSA9IGFbMV0gKiBiO1xuICBvdXRbMl0gPSBhWzJdICogYjtcbiAgb3V0WzNdID0gYVszXSAqIGI7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIEFkZHMgdHdvIHZlYzQncyBhZnRlciBzY2FsaW5nIHRoZSBzZWNvbmQgb3BlcmFuZCBieSBhIHNjYWxhciB2YWx1ZVxuICpcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcGFyYW0ge051bWJlcn0gc2NhbGUgdGhlIGFtb3VudCB0byBzY2FsZSBiIGJ5IGJlZm9yZSBhZGRpbmdcbiAqIEByZXR1cm5zIHt2ZWM0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc2NhbGVBbmRBZGQob3V0LCBhLCBiLCBzY2FsZSkge1xuICBvdXRbMF0gPSBhWzBdICsgYlswXSAqIHNjYWxlO1xuICBvdXRbMV0gPSBhWzFdICsgYlsxXSAqIHNjYWxlO1xuICBvdXRbMl0gPSBhWzJdICsgYlsyXSAqIHNjYWxlO1xuICBvdXRbM10gPSBhWzNdICsgYlszXSAqIHNjYWxlO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBldWNsaWRpYW4gZGlzdGFuY2UgYmV0d2VlbiB0d28gdmVjNCdzXG4gKlxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge051bWJlcn0gZGlzdGFuY2UgYmV0d2VlbiBhIGFuZCBiXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGRpc3RhbmNlKGEsIGIpIHtcbiAgdmFyIHggPSBiWzBdIC0gYVswXTtcbiAgdmFyIHkgPSBiWzFdIC0gYVsxXTtcbiAgdmFyIHogPSBiWzJdIC0gYVsyXTtcbiAgdmFyIHcgPSBiWzNdIC0gYVszXTtcbiAgcmV0dXJuIE1hdGguaHlwb3QoeCwgeSwgeiwgdyk7XG59XG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIHNxdWFyZWQgZXVjbGlkaWFuIGRpc3RhbmNlIGJldHdlZW4gdHdvIHZlYzQnc1xuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IHNxdWFyZWQgZGlzdGFuY2UgYmV0d2VlbiBhIGFuZCBiXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNxdWFyZWREaXN0YW5jZShhLCBiKSB7XG4gIHZhciB4ID0gYlswXSAtIGFbMF07XG4gIHZhciB5ID0gYlsxXSAtIGFbMV07XG4gIHZhciB6ID0gYlsyXSAtIGFbMl07XG4gIHZhciB3ID0gYlszXSAtIGFbM107XG4gIHJldHVybiB4ICogeCArIHkgKiB5ICsgeiAqIHogKyB3ICogdztcbn1cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgbGVuZ3RoIG9mIGEgdmVjNFxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHZlY3RvciB0byBjYWxjdWxhdGUgbGVuZ3RoIG9mXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBsZW5ndGggb2YgYVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBsZW5ndGgoYSkge1xuICB2YXIgeCA9IGFbMF07XG4gIHZhciB5ID0gYVsxXTtcbiAgdmFyIHogPSBhWzJdO1xuICB2YXIgdyA9IGFbM107XG4gIHJldHVybiBNYXRoLmh5cG90KHgsIHksIHosIHcpO1xufVxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBzcXVhcmVkIGxlbmd0aCBvZiBhIHZlYzRcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSB2ZWN0b3IgdG8gY2FsY3VsYXRlIHNxdWFyZWQgbGVuZ3RoIG9mXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBzcXVhcmVkIGxlbmd0aCBvZiBhXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNxdWFyZWRMZW5ndGgoYSkge1xuICB2YXIgeCA9IGFbMF07XG4gIHZhciB5ID0gYVsxXTtcbiAgdmFyIHogPSBhWzJdO1xuICB2YXIgdyA9IGFbM107XG4gIHJldHVybiB4ICogeCArIHkgKiB5ICsgeiAqIHogKyB3ICogdztcbn1cbi8qKlxuICogTmVnYXRlcyB0aGUgY29tcG9uZW50cyBvZiBhIHZlYzRcbiAqXG4gKiBAcGFyYW0ge3ZlYzR9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgdmVjdG9yIHRvIG5lZ2F0ZVxuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBuZWdhdGUob3V0LCBhKSB7XG4gIG91dFswXSA9IC1hWzBdO1xuICBvdXRbMV0gPSAtYVsxXTtcbiAgb3V0WzJdID0gLWFbMl07XG4gIG91dFszXSA9IC1hWzNdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBSZXR1cm5zIHRoZSBpbnZlcnNlIG9mIHRoZSBjb21wb25lbnRzIG9mIGEgdmVjNFxuICpcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSB2ZWN0b3IgdG8gaW52ZXJ0XG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGludmVyc2Uob3V0LCBhKSB7XG4gIG91dFswXSA9IDEuMCAvIGFbMF07XG4gIG91dFsxXSA9IDEuMCAvIGFbMV07XG4gIG91dFsyXSA9IDEuMCAvIGFbMl07XG4gIG91dFszXSA9IDEuMCAvIGFbM107XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIE5vcm1hbGl6ZSBhIHZlYzRcbiAqXG4gKiBAcGFyYW0ge3ZlYzR9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgdmVjdG9yIHRvIG5vcm1hbGl6ZVxuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemUob3V0LCBhKSB7XG4gIHZhciB4ID0gYVswXTtcbiAgdmFyIHkgPSBhWzFdO1xuICB2YXIgeiA9IGFbMl07XG4gIHZhciB3ID0gYVszXTtcbiAgdmFyIGxlbiA9IHggKiB4ICsgeSAqIHkgKyB6ICogeiArIHcgKiB3O1xuXG4gIGlmIChsZW4gPiAwKSB7XG4gICAgbGVuID0gMSAvIE1hdGguc3FydChsZW4pO1xuICB9XG5cbiAgb3V0WzBdID0geCAqIGxlbjtcbiAgb3V0WzFdID0geSAqIGxlbjtcbiAgb3V0WzJdID0geiAqIGxlbjtcbiAgb3V0WzNdID0gdyAqIGxlbjtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgZG90IHByb2R1Y3Qgb2YgdHdvIHZlYzQnc1xuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IGRvdCBwcm9kdWN0IG9mIGEgYW5kIGJcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZG90KGEsIGIpIHtcbiAgcmV0dXJuIGFbMF0gKiBiWzBdICsgYVsxXSAqIGJbMV0gKyBhWzJdICogYlsyXSArIGFbM10gKiBiWzNdO1xufVxuLyoqXG4gKiBSZXR1cm5zIHRoZSBjcm9zcy1wcm9kdWN0IG9mIHRocmVlIHZlY3RvcnMgaW4gYSA0LWRpbWVuc2lvbmFsIHNwYWNlXG4gKlxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IHJlc3VsdCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IFUgdGhlIGZpcnN0IHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IFYgdGhlIHNlY29uZCB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBXIHRoZSB0aGlyZCB2ZWN0b3JcbiAqIEByZXR1cm5zIHt2ZWM0fSByZXN1bHRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3Jvc3Mob3V0LCB1LCB2LCB3KSB7XG4gIHZhciBBID0gdlswXSAqIHdbMV0gLSB2WzFdICogd1swXSxcbiAgICAgIEIgPSB2WzBdICogd1syXSAtIHZbMl0gKiB3WzBdLFxuICAgICAgQyA9IHZbMF0gKiB3WzNdIC0gdlszXSAqIHdbMF0sXG4gICAgICBEID0gdlsxXSAqIHdbMl0gLSB2WzJdICogd1sxXSxcbiAgICAgIEUgPSB2WzFdICogd1szXSAtIHZbM10gKiB3WzFdLFxuICAgICAgRiA9IHZbMl0gKiB3WzNdIC0gdlszXSAqIHdbMl07XG4gIHZhciBHID0gdVswXTtcbiAgdmFyIEggPSB1WzFdO1xuICB2YXIgSSA9IHVbMl07XG4gIHZhciBKID0gdVszXTtcbiAgb3V0WzBdID0gSCAqIEYgLSBJICogRSArIEogKiBEO1xuICBvdXRbMV0gPSAtKEcgKiBGKSArIEkgKiBDIC0gSiAqIEI7XG4gIG91dFsyXSA9IEcgKiBFIC0gSCAqIEMgKyBKICogQTtcbiAgb3V0WzNdID0gLShHICogRCkgKyBIICogQiAtIEkgKiBBO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBQZXJmb3JtcyBhIGxpbmVhciBpbnRlcnBvbGF0aW9uIGJldHdlZW4gdHdvIHZlYzQnc1xuICpcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcGFyYW0ge051bWJlcn0gdCBpbnRlcnBvbGF0aW9uIGFtb3VudCwgaW4gdGhlIHJhbmdlIFswLTFdLCBiZXR3ZWVuIHRoZSB0d28gaW5wdXRzXG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGxlcnAob3V0LCBhLCBiLCB0KSB7XG4gIHZhciBheCA9IGFbMF07XG4gIHZhciBheSA9IGFbMV07XG4gIHZhciBheiA9IGFbMl07XG4gIHZhciBhdyA9IGFbM107XG4gIG91dFswXSA9IGF4ICsgdCAqIChiWzBdIC0gYXgpO1xuICBvdXRbMV0gPSBheSArIHQgKiAoYlsxXSAtIGF5KTtcbiAgb3V0WzJdID0gYXogKyB0ICogKGJbMl0gLSBheik7XG4gIG91dFszXSA9IGF3ICsgdCAqIChiWzNdIC0gYXcpO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBHZW5lcmF0ZXMgYSByYW5kb20gdmVjdG9yIHdpdGggdGhlIGdpdmVuIHNjYWxlXG4gKlxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7TnVtYmVyfSBbc2NhbGVdIExlbmd0aCBvZiB0aGUgcmVzdWx0aW5nIHZlY3Rvci4gSWYgb21taXR0ZWQsIGEgdW5pdCB2ZWN0b3Igd2lsbCBiZSByZXR1cm5lZFxuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByYW5kb20ob3V0LCBzY2FsZSkge1xuICBzY2FsZSA9IHNjYWxlIHx8IDEuMDsgLy8gTWFyc2FnbGlhLCBHZW9yZ2UuIENob29zaW5nIGEgUG9pbnQgZnJvbSB0aGUgU3VyZmFjZSBvZiBhXG4gIC8vIFNwaGVyZS4gQW5uLiBNYXRoLiBTdGF0aXN0LiA0MyAoMTk3MiksIG5vLiAyLCA2NDUtLTY0Ni5cbiAgLy8gaHR0cDovL3Byb2plY3RldWNsaWQub3JnL2V1Y2xpZC5hb21zLzExNzc2OTI2NDQ7XG5cbiAgdmFyIHYxLCB2MiwgdjMsIHY0O1xuICB2YXIgczEsIHMyO1xuXG4gIGRvIHtcbiAgICB2MSA9IGdsTWF0cml4LlJBTkRPTSgpICogMiAtIDE7XG4gICAgdjIgPSBnbE1hdHJpeC5SQU5ET00oKSAqIDIgLSAxO1xuICAgIHMxID0gdjEgKiB2MSArIHYyICogdjI7XG4gIH0gd2hpbGUgKHMxID49IDEpO1xuXG4gIGRvIHtcbiAgICB2MyA9IGdsTWF0cml4LlJBTkRPTSgpICogMiAtIDE7XG4gICAgdjQgPSBnbE1hdHJpeC5SQU5ET00oKSAqIDIgLSAxO1xuICAgIHMyID0gdjMgKiB2MyArIHY0ICogdjQ7XG4gIH0gd2hpbGUgKHMyID49IDEpO1xuXG4gIHZhciBkID0gTWF0aC5zcXJ0KCgxIC0gczEpIC8gczIpO1xuICBvdXRbMF0gPSBzY2FsZSAqIHYxO1xuICBvdXRbMV0gPSBzY2FsZSAqIHYyO1xuICBvdXRbMl0gPSBzY2FsZSAqIHYzICogZDtcbiAgb3V0WzNdID0gc2NhbGUgKiB2NCAqIGQ7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFRyYW5zZm9ybXMgdGhlIHZlYzQgd2l0aCBhIG1hdDQuXG4gKlxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHRoZSB2ZWN0b3IgdG8gdHJhbnNmb3JtXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gbSBtYXRyaXggdG8gdHJhbnNmb3JtIHdpdGhcbiAqIEByZXR1cm5zIHt2ZWM0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNmb3JtTWF0NChvdXQsIGEsIG0pIHtcbiAgdmFyIHggPSBhWzBdLFxuICAgICAgeSA9IGFbMV0sXG4gICAgICB6ID0gYVsyXSxcbiAgICAgIHcgPSBhWzNdO1xuICBvdXRbMF0gPSBtWzBdICogeCArIG1bNF0gKiB5ICsgbVs4XSAqIHogKyBtWzEyXSAqIHc7XG4gIG91dFsxXSA9IG1bMV0gKiB4ICsgbVs1XSAqIHkgKyBtWzldICogeiArIG1bMTNdICogdztcbiAgb3V0WzJdID0gbVsyXSAqIHggKyBtWzZdICogeSArIG1bMTBdICogeiArIG1bMTRdICogdztcbiAgb3V0WzNdID0gbVszXSAqIHggKyBtWzddICogeSArIG1bMTFdICogeiArIG1bMTVdICogdztcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogVHJhbnNmb3JtcyB0aGUgdmVjNCB3aXRoIGEgcXVhdFxuICpcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSB0aGUgdmVjdG9yIHRvIHRyYW5zZm9ybVxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IHEgcXVhdGVybmlvbiB0byB0cmFuc2Zvcm0gd2l0aFxuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2Zvcm1RdWF0KG91dCwgYSwgcSkge1xuICB2YXIgeCA9IGFbMF0sXG4gICAgICB5ID0gYVsxXSxcbiAgICAgIHogPSBhWzJdO1xuICB2YXIgcXggPSBxWzBdLFxuICAgICAgcXkgPSBxWzFdLFxuICAgICAgcXogPSBxWzJdLFxuICAgICAgcXcgPSBxWzNdOyAvLyBjYWxjdWxhdGUgcXVhdCAqIHZlY1xuXG4gIHZhciBpeCA9IHF3ICogeCArIHF5ICogeiAtIHF6ICogeTtcbiAgdmFyIGl5ID0gcXcgKiB5ICsgcXogKiB4IC0gcXggKiB6O1xuICB2YXIgaXogPSBxdyAqIHogKyBxeCAqIHkgLSBxeSAqIHg7XG4gIHZhciBpdyA9IC1xeCAqIHggLSBxeSAqIHkgLSBxeiAqIHo7IC8vIGNhbGN1bGF0ZSByZXN1bHQgKiBpbnZlcnNlIHF1YXRcblxuICBvdXRbMF0gPSBpeCAqIHF3ICsgaXcgKiAtcXggKyBpeSAqIC1xeiAtIGl6ICogLXF5O1xuICBvdXRbMV0gPSBpeSAqIHF3ICsgaXcgKiAtcXkgKyBpeiAqIC1xeCAtIGl4ICogLXF6O1xuICBvdXRbMl0gPSBpeiAqIHF3ICsgaXcgKiAtcXogKyBpeCAqIC1xeSAtIGl5ICogLXF4O1xuICBvdXRbM10gPSBhWzNdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBTZXQgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWM0IHRvIHplcm9cbiAqXG4gKiBAcGFyYW0ge3ZlYzR9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB6ZXJvKG91dCkge1xuICBvdXRbMF0gPSAwLjA7XG4gIG91dFsxXSA9IDAuMDtcbiAgb3V0WzJdID0gMC4wO1xuICBvdXRbM10gPSAwLjA7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSB2ZWN0b3JcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSB2ZWN0b3IgdG8gcmVwcmVzZW50IGFzIGEgc3RyaW5nXG4gKiBAcmV0dXJucyB7U3RyaW5nfSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHZlY3RvclxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzdHIoYSkge1xuICByZXR1cm4gXCJ2ZWM0KFwiICsgYVswXSArIFwiLCBcIiArIGFbMV0gKyBcIiwgXCIgKyBhWzJdICsgXCIsIFwiICsgYVszXSArIFwiKVwiO1xufVxuLyoqXG4gKiBSZXR1cm5zIHdoZXRoZXIgb3Igbm90IHRoZSB2ZWN0b3JzIGhhdmUgZXhhY3RseSB0aGUgc2FtZSBlbGVtZW50cyBpbiB0aGUgc2FtZSBwb3NpdGlvbiAod2hlbiBjb21wYXJlZCB3aXRoID09PSlcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSBUaGUgZmlyc3QgdmVjdG9yLlxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGIgVGhlIHNlY29uZCB2ZWN0b3IuXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gVHJ1ZSBpZiB0aGUgdmVjdG9ycyBhcmUgZXF1YWwsIGZhbHNlIG90aGVyd2lzZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXhhY3RFcXVhbHMoYSwgYikge1xuICByZXR1cm4gYVswXSA9PT0gYlswXSAmJiBhWzFdID09PSBiWzFdICYmIGFbMl0gPT09IGJbMl0gJiYgYVszXSA9PT0gYlszXTtcbn1cbi8qKlxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgdmVjdG9ycyBoYXZlIGFwcHJveGltYXRlbHkgdGhlIHNhbWUgZWxlbWVudHMgaW4gdGhlIHNhbWUgcG9zaXRpb24uXG4gKlxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgVGhlIGZpcnN0IHZlY3Rvci5cbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBiIFRoZSBzZWNvbmQgdmVjdG9yLlxuICogQHJldHVybnMge0Jvb2xlYW59IFRydWUgaWYgdGhlIHZlY3RvcnMgYXJlIGVxdWFsLCBmYWxzZSBvdGhlcndpc2UuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGVxdWFscyhhLCBiKSB7XG4gIHZhciBhMCA9IGFbMF0sXG4gICAgICBhMSA9IGFbMV0sXG4gICAgICBhMiA9IGFbMl0sXG4gICAgICBhMyA9IGFbM107XG4gIHZhciBiMCA9IGJbMF0sXG4gICAgICBiMSA9IGJbMV0sXG4gICAgICBiMiA9IGJbMl0sXG4gICAgICBiMyA9IGJbM107XG4gIHJldHVybiBNYXRoLmFicyhhMCAtIGIwKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMCksIE1hdGguYWJzKGIwKSkgJiYgTWF0aC5hYnMoYTEgLSBiMSkgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTEpLCBNYXRoLmFicyhiMSkpICYmIE1hdGguYWJzKGEyIC0gYjIpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGEyKSwgTWF0aC5hYnMoYjIpKSAmJiBNYXRoLmFicyhhMyAtIGIzKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMyksIE1hdGguYWJzKGIzKSk7XG59XG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjNC5zdWJ0cmFjdH1cbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgc3ViID0gc3VidHJhY3Q7XG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjNC5tdWx0aXBseX1cbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgbXVsID0gbXVsdGlwbHk7XG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjNC5kaXZpZGV9XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIGRpdiA9IGRpdmlkZTtcbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayB2ZWM0LmRpc3RhbmNlfVxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBkaXN0ID0gZGlzdGFuY2U7XG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjNC5zcXVhcmVkRGlzdGFuY2V9XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIHNxckRpc3QgPSBzcXVhcmVkRGlzdGFuY2U7XG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjNC5sZW5ndGh9XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIGxlbiA9IGxlbmd0aDtcbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayB2ZWM0LnNxdWFyZWRMZW5ndGh9XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIHNxckxlbiA9IHNxdWFyZWRMZW5ndGg7XG4vKipcbiAqIFBlcmZvcm0gc29tZSBvcGVyYXRpb24gb3ZlciBhbiBhcnJheSBvZiB2ZWM0cy5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBhIHRoZSBhcnJheSBvZiB2ZWN0b3JzIHRvIGl0ZXJhdGUgb3ZlclxuICogQHBhcmFtIHtOdW1iZXJ9IHN0cmlkZSBOdW1iZXIgb2YgZWxlbWVudHMgYmV0d2VlbiB0aGUgc3RhcnQgb2YgZWFjaCB2ZWM0LiBJZiAwIGFzc3VtZXMgdGlnaHRseSBwYWNrZWRcbiAqIEBwYXJhbSB7TnVtYmVyfSBvZmZzZXQgTnVtYmVyIG9mIGVsZW1lbnRzIHRvIHNraXAgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgYXJyYXlcbiAqIEBwYXJhbSB7TnVtYmVyfSBjb3VudCBOdW1iZXIgb2YgdmVjNHMgdG8gaXRlcmF0ZSBvdmVyLiBJZiAwIGl0ZXJhdGVzIG92ZXIgZW50aXJlIGFycmF5XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBGdW5jdGlvbiB0byBjYWxsIGZvciBlYWNoIHZlY3RvciBpbiB0aGUgYXJyYXlcbiAqIEBwYXJhbSB7T2JqZWN0fSBbYXJnXSBhZGRpdGlvbmFsIGFyZ3VtZW50IHRvIHBhc3MgdG8gZm5cbiAqIEByZXR1cm5zIHtBcnJheX0gYVxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBmb3JFYWNoID0gZnVuY3Rpb24gKCkge1xuICB2YXIgdmVjID0gY3JlYXRlKCk7XG4gIHJldHVybiBmdW5jdGlvbiAoYSwgc3RyaWRlLCBvZmZzZXQsIGNvdW50LCBmbiwgYXJnKSB7XG4gICAgdmFyIGksIGw7XG5cbiAgICBpZiAoIXN0cmlkZSkge1xuICAgICAgc3RyaWRlID0gNDtcbiAgICB9XG5cbiAgICBpZiAoIW9mZnNldCkge1xuICAgICAgb2Zmc2V0ID0gMDtcbiAgICB9XG5cbiAgICBpZiAoY291bnQpIHtcbiAgICAgIGwgPSBNYXRoLm1pbihjb3VudCAqIHN0cmlkZSArIG9mZnNldCwgYS5sZW5ndGgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsID0gYS5sZW5ndGg7XG4gICAgfVxuXG4gICAgZm9yIChpID0gb2Zmc2V0OyBpIDwgbDsgaSArPSBzdHJpZGUpIHtcbiAgICAgIHZlY1swXSA9IGFbaV07XG4gICAgICB2ZWNbMV0gPSBhW2kgKyAxXTtcbiAgICAgIHZlY1syXSA9IGFbaSArIDJdO1xuICAgICAgdmVjWzNdID0gYVtpICsgM107XG4gICAgICBmbih2ZWMsIHZlYywgYXJnKTtcbiAgICAgIGFbaV0gPSB2ZWNbMF07XG4gICAgICBhW2kgKyAxXSA9IHZlY1sxXTtcbiAgICAgIGFbaSArIDJdID0gdmVjWzJdO1xuICAgICAgYVtpICsgM10gPSB2ZWNbM107XG4gICAgfVxuXG4gICAgcmV0dXJuIGE7XG4gIH07XG59KCk7IiwiaW1wb3J0ICogYXMgZ2xNYXRyaXggZnJvbSBcIi4vY29tbW9uLmpzXCI7XG5pbXBvcnQgKiBhcyBtYXQzIGZyb20gXCIuL21hdDMuanNcIjtcbmltcG9ydCAqIGFzIHZlYzMgZnJvbSBcIi4vdmVjMy5qc1wiO1xuaW1wb3J0ICogYXMgdmVjNCBmcm9tIFwiLi92ZWM0LmpzXCI7XG4vKipcbiAqIFF1YXRlcm5pb25cbiAqIEBtb2R1bGUgcXVhdFxuICovXG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBpZGVudGl0eSBxdWF0XG4gKlxuICogQHJldHVybnMge3F1YXR9IGEgbmV3IHF1YXRlcm5pb25cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlKCkge1xuICB2YXIgb3V0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoNCk7XG5cbiAgaWYgKGdsTWF0cml4LkFSUkFZX1RZUEUgIT0gRmxvYXQzMkFycmF5KSB7XG4gICAgb3V0WzBdID0gMDtcbiAgICBvdXRbMV0gPSAwO1xuICAgIG91dFsyXSA9IDA7XG4gIH1cblxuICBvdXRbM10gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBTZXQgYSBxdWF0IHRvIHRoZSBpZGVudGl0eSBxdWF0ZXJuaW9uXG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGlkZW50aXR5KG91dCkge1xuICBvdXRbMF0gPSAwO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBTZXRzIGEgcXVhdCBmcm9tIHRoZSBnaXZlbiBhbmdsZSBhbmQgcm90YXRpb24gYXhpcyxcbiAqIHRoZW4gcmV0dXJucyBpdC5cbiAqXG4gKiBAcGFyYW0ge3F1YXR9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBheGlzIHRoZSBheGlzIGFyb3VuZCB3aGljaCB0byByb3RhdGVcbiAqIEBwYXJhbSB7TnVtYmVyfSByYWQgdGhlIGFuZ2xlIGluIHJhZGlhbnNcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNldEF4aXNBbmdsZShvdXQsIGF4aXMsIHJhZCkge1xuICByYWQgPSByYWQgKiAwLjU7XG4gIHZhciBzID0gTWF0aC5zaW4ocmFkKTtcbiAgb3V0WzBdID0gcyAqIGF4aXNbMF07XG4gIG91dFsxXSA9IHMgKiBheGlzWzFdO1xuICBvdXRbMl0gPSBzICogYXhpc1syXTtcbiAgb3V0WzNdID0gTWF0aC5jb3MocmFkKTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogR2V0cyB0aGUgcm90YXRpb24gYXhpcyBhbmQgYW5nbGUgZm9yIGEgZ2l2ZW5cbiAqICBxdWF0ZXJuaW9uLiBJZiBhIHF1YXRlcm5pb24gaXMgY3JlYXRlZCB3aXRoXG4gKiAgc2V0QXhpc0FuZ2xlLCB0aGlzIG1ldGhvZCB3aWxsIHJldHVybiB0aGUgc2FtZVxuICogIHZhbHVlcyBhcyBwcm92aWRpZWQgaW4gdGhlIG9yaWdpbmFsIHBhcmFtZXRlciBsaXN0XG4gKiAgT1IgZnVuY3Rpb25hbGx5IGVxdWl2YWxlbnQgdmFsdWVzLlxuICogRXhhbXBsZTogVGhlIHF1YXRlcm5pb24gZm9ybWVkIGJ5IGF4aXMgWzAsIDAsIDFdIGFuZFxuICogIGFuZ2xlIC05MCBpcyB0aGUgc2FtZSBhcyB0aGUgcXVhdGVybmlvbiBmb3JtZWQgYnlcbiAqICBbMCwgMCwgMV0gYW5kIDI3MC4gVGhpcyBtZXRob2QgZmF2b3JzIHRoZSBsYXR0ZXIuXG4gKiBAcGFyYW0gIHt2ZWMzfSBvdXRfYXhpcyAgVmVjdG9yIHJlY2VpdmluZyB0aGUgYXhpcyBvZiByb3RhdGlvblxuICogQHBhcmFtICB7UmVhZG9ubHlRdWF0fSBxICAgICBRdWF0ZXJuaW9uIHRvIGJlIGRlY29tcG9zZWRcbiAqIEByZXR1cm4ge051bWJlcn0gICAgIEFuZ2xlLCBpbiByYWRpYW5zLCBvZiB0aGUgcm90YXRpb25cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QXhpc0FuZ2xlKG91dF9heGlzLCBxKSB7XG4gIHZhciByYWQgPSBNYXRoLmFjb3MocVszXSkgKiAyLjA7XG4gIHZhciBzID0gTWF0aC5zaW4ocmFkIC8gMi4wKTtcblxuICBpZiAocyA+IGdsTWF0cml4LkVQU0lMT04pIHtcbiAgICBvdXRfYXhpc1swXSA9IHFbMF0gLyBzO1xuICAgIG91dF9heGlzWzFdID0gcVsxXSAvIHM7XG4gICAgb3V0X2F4aXNbMl0gPSBxWzJdIC8gcztcbiAgfSBlbHNlIHtcbiAgICAvLyBJZiBzIGlzIHplcm8sIHJldHVybiBhbnkgYXhpcyAobm8gcm90YXRpb24gLSBheGlzIGRvZXMgbm90IG1hdHRlcilcbiAgICBvdXRfYXhpc1swXSA9IDE7XG4gICAgb3V0X2F4aXNbMV0gPSAwO1xuICAgIG91dF9heGlzWzJdID0gMDtcbiAgfVxuXG4gIHJldHVybiByYWQ7XG59XG4vKipcbiAqIEdldHMgdGhlIGFuZ3VsYXIgZGlzdGFuY2UgYmV0d2VlbiB0d28gdW5pdCBxdWF0ZXJuaW9uc1xuICpcbiAqIEBwYXJhbSAge1JlYWRvbmx5UXVhdH0gYSAgICAgT3JpZ2luIHVuaXQgcXVhdGVybmlvblxuICogQHBhcmFtICB7UmVhZG9ubHlRdWF0fSBiICAgICBEZXN0aW5hdGlvbiB1bml0IHF1YXRlcm5pb25cbiAqIEByZXR1cm4ge051bWJlcn0gICAgIEFuZ2xlLCBpbiByYWRpYW5zLCBiZXR3ZWVuIHRoZSB0d28gcXVhdGVybmlvbnNcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QW5nbGUoYSwgYikge1xuICB2YXIgZG90cHJvZHVjdCA9IGRvdChhLCBiKTtcbiAgcmV0dXJuIE1hdGguYWNvcygyICogZG90cHJvZHVjdCAqIGRvdHByb2R1Y3QgLSAxKTtcbn1cbi8qKlxuICogTXVsdGlwbGllcyB0d28gcXVhdCdzXG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG11bHRpcGx5KG91dCwgYSwgYikge1xuICB2YXIgYXggPSBhWzBdLFxuICAgICAgYXkgPSBhWzFdLFxuICAgICAgYXogPSBhWzJdLFxuICAgICAgYXcgPSBhWzNdO1xuICB2YXIgYnggPSBiWzBdLFxuICAgICAgYnkgPSBiWzFdLFxuICAgICAgYnogPSBiWzJdLFxuICAgICAgYncgPSBiWzNdO1xuICBvdXRbMF0gPSBheCAqIGJ3ICsgYXcgKiBieCArIGF5ICogYnogLSBheiAqIGJ5O1xuICBvdXRbMV0gPSBheSAqIGJ3ICsgYXcgKiBieSArIGF6ICogYnggLSBheCAqIGJ6O1xuICBvdXRbMl0gPSBheiAqIGJ3ICsgYXcgKiBieiArIGF4ICogYnkgLSBheSAqIGJ4O1xuICBvdXRbM10gPSBhdyAqIGJ3IC0gYXggKiBieCAtIGF5ICogYnkgLSBheiAqIGJ6O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBSb3RhdGVzIGEgcXVhdGVybmlvbiBieSB0aGUgZ2l2ZW4gYW5nbGUgYWJvdXQgdGhlIFggYXhpc1xuICpcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHF1YXQgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIHF1YXQgdG8gcm90YXRlXG4gKiBAcGFyYW0ge251bWJlcn0gcmFkIGFuZ2xlIChpbiByYWRpYW5zKSB0byByb3RhdGVcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcm90YXRlWChvdXQsIGEsIHJhZCkge1xuICByYWQgKj0gMC41O1xuICB2YXIgYXggPSBhWzBdLFxuICAgICAgYXkgPSBhWzFdLFxuICAgICAgYXogPSBhWzJdLFxuICAgICAgYXcgPSBhWzNdO1xuICB2YXIgYnggPSBNYXRoLnNpbihyYWQpLFxuICAgICAgYncgPSBNYXRoLmNvcyhyYWQpO1xuICBvdXRbMF0gPSBheCAqIGJ3ICsgYXcgKiBieDtcbiAgb3V0WzFdID0gYXkgKiBidyArIGF6ICogYng7XG4gIG91dFsyXSA9IGF6ICogYncgLSBheSAqIGJ4O1xuICBvdXRbM10gPSBhdyAqIGJ3IC0gYXggKiBieDtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUm90YXRlcyBhIHF1YXRlcm5pb24gYnkgdGhlIGdpdmVuIGFuZ2xlIGFib3V0IHRoZSBZIGF4aXNcbiAqXG4gKiBAcGFyYW0ge3F1YXR9IG91dCBxdWF0IHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSBxdWF0IHRvIHJvdGF0ZVxuICogQHBhcmFtIHtudW1iZXJ9IHJhZCBhbmdsZSAoaW4gcmFkaWFucykgdG8gcm90YXRlXG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJvdGF0ZVkob3V0LCBhLCByYWQpIHtcbiAgcmFkICo9IDAuNTtcbiAgdmFyIGF4ID0gYVswXSxcbiAgICAgIGF5ID0gYVsxXSxcbiAgICAgIGF6ID0gYVsyXSxcbiAgICAgIGF3ID0gYVszXTtcbiAgdmFyIGJ5ID0gTWF0aC5zaW4ocmFkKSxcbiAgICAgIGJ3ID0gTWF0aC5jb3MocmFkKTtcbiAgb3V0WzBdID0gYXggKiBidyAtIGF6ICogYnk7XG4gIG91dFsxXSA9IGF5ICogYncgKyBhdyAqIGJ5O1xuICBvdXRbMl0gPSBheiAqIGJ3ICsgYXggKiBieTtcbiAgb3V0WzNdID0gYXcgKiBidyAtIGF5ICogYnk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFJvdGF0ZXMgYSBxdWF0ZXJuaW9uIGJ5IHRoZSBnaXZlbiBhbmdsZSBhYm91dCB0aGUgWiBheGlzXG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgcXVhdCByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGEgcXVhdCB0byByb3RhdGVcbiAqIEBwYXJhbSB7bnVtYmVyfSByYWQgYW5nbGUgKGluIHJhZGlhbnMpIHRvIHJvdGF0ZVxuICogQHJldHVybnMge3F1YXR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByb3RhdGVaKG91dCwgYSwgcmFkKSB7XG4gIHJhZCAqPSAwLjU7XG4gIHZhciBheCA9IGFbMF0sXG4gICAgICBheSA9IGFbMV0sXG4gICAgICBheiA9IGFbMl0sXG4gICAgICBhdyA9IGFbM107XG4gIHZhciBieiA9IE1hdGguc2luKHJhZCksXG4gICAgICBidyA9IE1hdGguY29zKHJhZCk7XG4gIG91dFswXSA9IGF4ICogYncgKyBheSAqIGJ6O1xuICBvdXRbMV0gPSBheSAqIGJ3IC0gYXggKiBiejtcbiAgb3V0WzJdID0gYXogKiBidyArIGF3ICogYno7XG4gIG91dFszXSA9IGF3ICogYncgLSBheiAqIGJ6O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBXIGNvbXBvbmVudCBvZiBhIHF1YXQgZnJvbSB0aGUgWCwgWSwgYW5kIFogY29tcG9uZW50cy5cbiAqIEFzc3VtZXMgdGhhdCBxdWF0ZXJuaW9uIGlzIDEgdW5pdCBpbiBsZW5ndGguXG4gKiBBbnkgZXhpc3RpbmcgVyBjb21wb25lbnQgd2lsbCBiZSBpZ25vcmVkLlxuICpcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGEgcXVhdCB0byBjYWxjdWxhdGUgVyBjb21wb25lbnQgb2ZcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlVyhvdXQsIGEpIHtcbiAgdmFyIHggPSBhWzBdLFxuICAgICAgeSA9IGFbMV0sXG4gICAgICB6ID0gYVsyXTtcbiAgb3V0WzBdID0geDtcbiAgb3V0WzFdID0geTtcbiAgb3V0WzJdID0gejtcbiAgb3V0WzNdID0gTWF0aC5zcXJ0KE1hdGguYWJzKDEuMCAtIHggKiB4IC0geSAqIHkgLSB6ICogeikpO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDYWxjdWxhdGUgdGhlIGV4cG9uZW50aWFsIG9mIGEgdW5pdCBxdWF0ZXJuaW9uLlxuICpcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGEgcXVhdCB0byBjYWxjdWxhdGUgdGhlIGV4cG9uZW50aWFsIG9mXG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGV4cChvdXQsIGEpIHtcbiAgdmFyIHggPSBhWzBdLFxuICAgICAgeSA9IGFbMV0sXG4gICAgICB6ID0gYVsyXSxcbiAgICAgIHcgPSBhWzNdO1xuICB2YXIgciA9IE1hdGguc3FydCh4ICogeCArIHkgKiB5ICsgeiAqIHopO1xuICB2YXIgZXQgPSBNYXRoLmV4cCh3KTtcbiAgdmFyIHMgPSByID4gMCA/IGV0ICogTWF0aC5zaW4ocikgLyByIDogMDtcbiAgb3V0WzBdID0geCAqIHM7XG4gIG91dFsxXSA9IHkgKiBzO1xuICBvdXRbMl0gPSB6ICogcztcbiAgb3V0WzNdID0gZXQgKiBNYXRoLmNvcyhyKTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ2FsY3VsYXRlIHRoZSBuYXR1cmFsIGxvZ2FyaXRobSBvZiBhIHVuaXQgcXVhdGVybmlvbi5cbiAqXG4gKiBAcGFyYW0ge3F1YXR9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIHF1YXQgdG8gY2FsY3VsYXRlIHRoZSBleHBvbmVudGlhbCBvZlxuICogQHJldHVybnMge3F1YXR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBsbihvdXQsIGEpIHtcbiAgdmFyIHggPSBhWzBdLFxuICAgICAgeSA9IGFbMV0sXG4gICAgICB6ID0gYVsyXSxcbiAgICAgIHcgPSBhWzNdO1xuICB2YXIgciA9IE1hdGguc3FydCh4ICogeCArIHkgKiB5ICsgeiAqIHopO1xuICB2YXIgdCA9IHIgPiAwID8gTWF0aC5hdGFuMihyLCB3KSAvIHIgOiAwO1xuICBvdXRbMF0gPSB4ICogdDtcbiAgb3V0WzFdID0geSAqIHQ7XG4gIG91dFsyXSA9IHogKiB0O1xuICBvdXRbM10gPSAwLjUgKiBNYXRoLmxvZyh4ICogeCArIHkgKiB5ICsgeiAqIHogKyB3ICogdyk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENhbGN1bGF0ZSB0aGUgc2NhbGFyIHBvd2VyIG9mIGEgdW5pdCBxdWF0ZXJuaW9uLlxuICpcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGEgcXVhdCB0byBjYWxjdWxhdGUgdGhlIGV4cG9uZW50aWFsIG9mXG4gKiBAcGFyYW0ge051bWJlcn0gYiBhbW91bnQgdG8gc2NhbGUgdGhlIHF1YXRlcm5pb24gYnlcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcG93KG91dCwgYSwgYikge1xuICBsbihvdXQsIGEpO1xuICBzY2FsZShvdXQsIG91dCwgYik7XG4gIGV4cChvdXQsIG91dCk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFBlcmZvcm1zIGEgc3BoZXJpY2FsIGxpbmVhciBpbnRlcnBvbGF0aW9uIGJldHdlZW4gdHdvIHF1YXRcbiAqXG4gKiBAcGFyYW0ge3F1YXR9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEBwYXJhbSB7TnVtYmVyfSB0IGludGVycG9sYXRpb24gYW1vdW50LCBpbiB0aGUgcmFuZ2UgWzAtMV0sIGJldHdlZW4gdGhlIHR3byBpbnB1dHNcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc2xlcnAob3V0LCBhLCBiLCB0KSB7XG4gIC8vIGJlbmNobWFya3M6XG4gIC8vICAgIGh0dHA6Ly9qc3BlcmYuY29tL3F1YXRlcm5pb24tc2xlcnAtaW1wbGVtZW50YXRpb25zXG4gIHZhciBheCA9IGFbMF0sXG4gICAgICBheSA9IGFbMV0sXG4gICAgICBheiA9IGFbMl0sXG4gICAgICBhdyA9IGFbM107XG4gIHZhciBieCA9IGJbMF0sXG4gICAgICBieSA9IGJbMV0sXG4gICAgICBieiA9IGJbMl0sXG4gICAgICBidyA9IGJbM107XG4gIHZhciBvbWVnYSwgY29zb20sIHNpbm9tLCBzY2FsZTAsIHNjYWxlMTsgLy8gY2FsYyBjb3NpbmVcblxuICBjb3NvbSA9IGF4ICogYnggKyBheSAqIGJ5ICsgYXogKiBieiArIGF3ICogYnc7IC8vIGFkanVzdCBzaWducyAoaWYgbmVjZXNzYXJ5KVxuXG4gIGlmIChjb3NvbSA8IDAuMCkge1xuICAgIGNvc29tID0gLWNvc29tO1xuICAgIGJ4ID0gLWJ4O1xuICAgIGJ5ID0gLWJ5O1xuICAgIGJ6ID0gLWJ6O1xuICAgIGJ3ID0gLWJ3O1xuICB9IC8vIGNhbGN1bGF0ZSBjb2VmZmljaWVudHNcblxuXG4gIGlmICgxLjAgLSBjb3NvbSA+IGdsTWF0cml4LkVQU0lMT04pIHtcbiAgICAvLyBzdGFuZGFyZCBjYXNlIChzbGVycClcbiAgICBvbWVnYSA9IE1hdGguYWNvcyhjb3NvbSk7XG4gICAgc2lub20gPSBNYXRoLnNpbihvbWVnYSk7XG4gICAgc2NhbGUwID0gTWF0aC5zaW4oKDEuMCAtIHQpICogb21lZ2EpIC8gc2lub207XG4gICAgc2NhbGUxID0gTWF0aC5zaW4odCAqIG9tZWdhKSAvIHNpbm9tO1xuICB9IGVsc2Uge1xuICAgIC8vIFwiZnJvbVwiIGFuZCBcInRvXCIgcXVhdGVybmlvbnMgYXJlIHZlcnkgY2xvc2VcbiAgICAvLyAgLi4uIHNvIHdlIGNhbiBkbyBhIGxpbmVhciBpbnRlcnBvbGF0aW9uXG4gICAgc2NhbGUwID0gMS4wIC0gdDtcbiAgICBzY2FsZTEgPSB0O1xuICB9IC8vIGNhbGN1bGF0ZSBmaW5hbCB2YWx1ZXNcblxuXG4gIG91dFswXSA9IHNjYWxlMCAqIGF4ICsgc2NhbGUxICogYng7XG4gIG91dFsxXSA9IHNjYWxlMCAqIGF5ICsgc2NhbGUxICogYnk7XG4gIG91dFsyXSA9IHNjYWxlMCAqIGF6ICsgc2NhbGUxICogYno7XG4gIG91dFszXSA9IHNjYWxlMCAqIGF3ICsgc2NhbGUxICogYnc7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIEdlbmVyYXRlcyBhIHJhbmRvbSB1bml0IHF1YXRlcm5pb25cbiAqXG4gKiBAcGFyYW0ge3F1YXR9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcmFuZG9tKG91dCkge1xuICAvLyBJbXBsZW1lbnRhdGlvbiBvZiBodHRwOi8vcGxhbm5pbmcuY3MudWl1Yy5lZHUvbm9kZTE5OC5odG1sXG4gIC8vIFRPRE86IENhbGxpbmcgcmFuZG9tIDMgdGltZXMgaXMgcHJvYmFibHkgbm90IHRoZSBmYXN0ZXN0IHNvbHV0aW9uXG4gIHZhciB1MSA9IGdsTWF0cml4LlJBTkRPTSgpO1xuICB2YXIgdTIgPSBnbE1hdHJpeC5SQU5ET00oKTtcbiAgdmFyIHUzID0gZ2xNYXRyaXguUkFORE9NKCk7XG4gIHZhciBzcXJ0MU1pbnVzVTEgPSBNYXRoLnNxcnQoMSAtIHUxKTtcbiAgdmFyIHNxcnRVMSA9IE1hdGguc3FydCh1MSk7XG4gIG91dFswXSA9IHNxcnQxTWludXNVMSAqIE1hdGguc2luKDIuMCAqIE1hdGguUEkgKiB1Mik7XG4gIG91dFsxXSA9IHNxcnQxTWludXNVMSAqIE1hdGguY29zKDIuMCAqIE1hdGguUEkgKiB1Mik7XG4gIG91dFsyXSA9IHNxcnRVMSAqIE1hdGguc2luKDIuMCAqIE1hdGguUEkgKiB1Myk7XG4gIG91dFszXSA9IHNxcnRVMSAqIE1hdGguY29zKDIuMCAqIE1hdGguUEkgKiB1Myk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGludmVyc2Ugb2YgYSBxdWF0XG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSBxdWF0IHRvIGNhbGN1bGF0ZSBpbnZlcnNlIG9mXG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGludmVydChvdXQsIGEpIHtcbiAgdmFyIGEwID0gYVswXSxcbiAgICAgIGExID0gYVsxXSxcbiAgICAgIGEyID0gYVsyXSxcbiAgICAgIGEzID0gYVszXTtcbiAgdmFyIGRvdCA9IGEwICogYTAgKyBhMSAqIGExICsgYTIgKiBhMiArIGEzICogYTM7XG4gIHZhciBpbnZEb3QgPSBkb3QgPyAxLjAgLyBkb3QgOiAwOyAvLyBUT0RPOiBXb3VsZCBiZSBmYXN0ZXIgdG8gcmV0dXJuIFswLDAsMCwwXSBpbW1lZGlhdGVseSBpZiBkb3QgPT0gMFxuXG4gIG91dFswXSA9IC1hMCAqIGludkRvdDtcbiAgb3V0WzFdID0gLWExICogaW52RG90O1xuICBvdXRbMl0gPSAtYTIgKiBpbnZEb3Q7XG4gIG91dFszXSA9IGEzICogaW52RG90O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBjb25qdWdhdGUgb2YgYSBxdWF0XG4gKiBJZiB0aGUgcXVhdGVybmlvbiBpcyBub3JtYWxpemVkLCB0aGlzIGZ1bmN0aW9uIGlzIGZhc3RlciB0aGFuIHF1YXQuaW52ZXJzZSBhbmQgcHJvZHVjZXMgdGhlIHNhbWUgcmVzdWx0LlxuICpcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGEgcXVhdCB0byBjYWxjdWxhdGUgY29uanVnYXRlIG9mXG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbmp1Z2F0ZShvdXQsIGEpIHtcbiAgb3V0WzBdID0gLWFbMF07XG4gIG91dFsxXSA9IC1hWzFdO1xuICBvdXRbMl0gPSAtYVsyXTtcbiAgb3V0WzNdID0gYVszXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIHF1YXRlcm5pb24gZnJvbSB0aGUgZ2l2ZW4gM3gzIHJvdGF0aW9uIG1hdHJpeC5cbiAqXG4gKiBOT1RFOiBUaGUgcmVzdWx0YW50IHF1YXRlcm5pb24gaXMgbm90IG5vcm1hbGl6ZWQsIHNvIHlvdSBzaG91bGQgYmUgc3VyZVxuICogdG8gcmVub3JtYWxpemUgdGhlIHF1YXRlcm5pb24geW91cnNlbGYgd2hlcmUgbmVjZXNzYXJ5LlxuICpcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IG0gcm90YXRpb24gbWF0cml4XG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbU1hdDMob3V0LCBtKSB7XG4gIC8vIEFsZ29yaXRobSBpbiBLZW4gU2hvZW1ha2UncyBhcnRpY2xlIGluIDE5ODcgU0lHR1JBUEggY291cnNlIG5vdGVzXG4gIC8vIGFydGljbGUgXCJRdWF0ZXJuaW9uIENhbGN1bHVzIGFuZCBGYXN0IEFuaW1hdGlvblwiLlxuICB2YXIgZlRyYWNlID0gbVswXSArIG1bNF0gKyBtWzhdO1xuICB2YXIgZlJvb3Q7XG5cbiAgaWYgKGZUcmFjZSA+IDAuMCkge1xuICAgIC8vIHx3fCA+IDEvMiwgbWF5IGFzIHdlbGwgY2hvb3NlIHcgPiAxLzJcbiAgICBmUm9vdCA9IE1hdGguc3FydChmVHJhY2UgKyAxLjApOyAvLyAyd1xuXG4gICAgb3V0WzNdID0gMC41ICogZlJvb3Q7XG4gICAgZlJvb3QgPSAwLjUgLyBmUm9vdDsgLy8gMS8oNHcpXG5cbiAgICBvdXRbMF0gPSAobVs1XSAtIG1bN10pICogZlJvb3Q7XG4gICAgb3V0WzFdID0gKG1bNl0gLSBtWzJdKSAqIGZSb290O1xuICAgIG91dFsyXSA9IChtWzFdIC0gbVszXSkgKiBmUm9vdDtcbiAgfSBlbHNlIHtcbiAgICAvLyB8d3wgPD0gMS8yXG4gICAgdmFyIGkgPSAwO1xuICAgIGlmIChtWzRdID4gbVswXSkgaSA9IDE7XG4gICAgaWYgKG1bOF0gPiBtW2kgKiAzICsgaV0pIGkgPSAyO1xuICAgIHZhciBqID0gKGkgKyAxKSAlIDM7XG4gICAgdmFyIGsgPSAoaSArIDIpICUgMztcbiAgICBmUm9vdCA9IE1hdGguc3FydChtW2kgKiAzICsgaV0gLSBtW2ogKiAzICsgal0gLSBtW2sgKiAzICsga10gKyAxLjApO1xuICAgIG91dFtpXSA9IDAuNSAqIGZSb290O1xuICAgIGZSb290ID0gMC41IC8gZlJvb3Q7XG4gICAgb3V0WzNdID0gKG1baiAqIDMgKyBrXSAtIG1bayAqIDMgKyBqXSkgKiBmUm9vdDtcbiAgICBvdXRbal0gPSAobVtqICogMyArIGldICsgbVtpICogMyArIGpdKSAqIGZSb290O1xuICAgIG91dFtrXSA9IChtW2sgKiAzICsgaV0gKyBtW2kgKiAzICsga10pICogZlJvb3Q7XG4gIH1cblxuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgcXVhdGVybmlvbiBmcm9tIHRoZSBnaXZlbiBldWxlciBhbmdsZSB4LCB5LCB6LlxuICpcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxuICogQHBhcmFtIHt4fSBBbmdsZSB0byByb3RhdGUgYXJvdW5kIFggYXhpcyBpbiBkZWdyZWVzLlxuICogQHBhcmFtIHt5fSBBbmdsZSB0byByb3RhdGUgYXJvdW5kIFkgYXhpcyBpbiBkZWdyZWVzLlxuICogQHBhcmFtIHt6fSBBbmdsZSB0byByb3RhdGUgYXJvdW5kIFogYXhpcyBpbiBkZWdyZWVzLlxuICogQHJldHVybnMge3F1YXR9IG91dFxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21FdWxlcihvdXQsIHgsIHksIHopIHtcbiAgdmFyIGhhbGZUb1JhZCA9IDAuNSAqIE1hdGguUEkgLyAxODAuMDtcbiAgeCAqPSBoYWxmVG9SYWQ7XG4gIHkgKj0gaGFsZlRvUmFkO1xuICB6ICo9IGhhbGZUb1JhZDtcbiAgdmFyIHN4ID0gTWF0aC5zaW4oeCk7XG4gIHZhciBjeCA9IE1hdGguY29zKHgpO1xuICB2YXIgc3kgPSBNYXRoLnNpbih5KTtcbiAgdmFyIGN5ID0gTWF0aC5jb3MoeSk7XG4gIHZhciBzeiA9IE1hdGguc2luKHopO1xuICB2YXIgY3ogPSBNYXRoLmNvcyh6KTtcbiAgb3V0WzBdID0gc3ggKiBjeSAqIGN6IC0gY3ggKiBzeSAqIHN6O1xuICBvdXRbMV0gPSBjeCAqIHN5ICogY3ogKyBzeCAqIGN5ICogc3o7XG4gIG91dFsyXSA9IGN4ICogY3kgKiBzeiAtIHN4ICogc3kgKiBjejtcbiAgb3V0WzNdID0gY3ggKiBjeSAqIGN6ICsgc3ggKiBzeSAqIHN6O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgcXVhdGVuaW9uXG4gKlxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGEgdmVjdG9yIHRvIHJlcHJlc2VudCBhcyBhIHN0cmluZ1xuICogQHJldHVybnMge1N0cmluZ30gc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB2ZWN0b3JcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc3RyKGEpIHtcbiAgcmV0dXJuIFwicXVhdChcIiArIGFbMF0gKyBcIiwgXCIgKyBhWzFdICsgXCIsIFwiICsgYVsyXSArIFwiLCBcIiArIGFbM10gKyBcIilcIjtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBxdWF0IGluaXRpYWxpemVkIHdpdGggdmFsdWVzIGZyb20gYW4gZXhpc3RpbmcgcXVhdGVybmlvblxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIHF1YXRlcm5pb24gdG8gY2xvbmVcbiAqIEByZXR1cm5zIHtxdWF0fSBhIG5ldyBxdWF0ZXJuaW9uXG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIGNsb25lID0gdmVjNC5jbG9uZTtcbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBxdWF0IGluaXRpYWxpemVkIHdpdGggdGhlIGdpdmVuIHZhbHVlc1xuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSB4IFggY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0geSBZIGNvbXBvbmVudFxuICogQHBhcmFtIHtOdW1iZXJ9IHogWiBjb21wb25lbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSB3IFcgY29tcG9uZW50XG4gKiBAcmV0dXJucyB7cXVhdH0gYSBuZXcgcXVhdGVybmlvblxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBmcm9tVmFsdWVzID0gdmVjNC5mcm9tVmFsdWVzO1xuLyoqXG4gKiBDb3B5IHRoZSB2YWx1ZXMgZnJvbSBvbmUgcXVhdCB0byBhbm90aGVyXG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSB0aGUgc291cmNlIHF1YXRlcm5pb25cbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgY29weSA9IHZlYzQuY29weTtcbi8qKlxuICogU2V0IHRoZSBjb21wb25lbnRzIG9mIGEgcXVhdCB0byB0aGUgZ2l2ZW4gdmFsdWVzXG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge051bWJlcn0geCBYIGNvbXBvbmVudFxuICogQHBhcmFtIHtOdW1iZXJ9IHkgWSBjb21wb25lbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSB6IFogY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0gdyBXIGNvbXBvbmVudFxuICogQHJldHVybnMge3F1YXR9IG91dFxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBzZXQgPSB2ZWM0LnNldDtcbi8qKlxuICogQWRkcyB0d28gcXVhdCdzXG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIGFkZCA9IHZlYzQuYWRkO1xuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHF1YXQubXVsdGlwbHl9XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIG11bCA9IG11bHRpcGx5O1xuLyoqXG4gKiBTY2FsZXMgYSBxdWF0IGJ5IGEgc2NhbGFyIG51bWJlclxuICpcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSB0aGUgdmVjdG9yIHRvIHNjYWxlXG4gKiBAcGFyYW0ge051bWJlcn0gYiBhbW91bnQgdG8gc2NhbGUgdGhlIHZlY3RvciBieVxuICogQHJldHVybnMge3F1YXR9IG91dFxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBzY2FsZSA9IHZlYzQuc2NhbGU7XG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGRvdCBwcm9kdWN0IG9mIHR3byBxdWF0J3NcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBkb3QgcHJvZHVjdCBvZiBhIGFuZCBiXG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIGRvdCA9IHZlYzQuZG90O1xuLyoqXG4gKiBQZXJmb3JtcyBhIGxpbmVhciBpbnRlcnBvbGF0aW9uIGJldHdlZW4gdHdvIHF1YXQnc1xuICpcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHBhcmFtIHtOdW1iZXJ9IHQgaW50ZXJwb2xhdGlvbiBhbW91bnQsIGluIHRoZSByYW5nZSBbMC0xXSwgYmV0d2VlbiB0aGUgdHdvIGlucHV0c1xuICogQHJldHVybnMge3F1YXR9IG91dFxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBsZXJwID0gdmVjNC5sZXJwO1xuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBsZW5ndGggb2YgYSBxdWF0XG4gKlxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGEgdmVjdG9yIHRvIGNhbGN1bGF0ZSBsZW5ndGggb2ZcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IGxlbmd0aCBvZiBhXG4gKi9cblxuZXhwb3J0IHZhciBsZW5ndGggPSB2ZWM0Lmxlbmd0aDtcbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayBxdWF0Lmxlbmd0aH1cbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgbGVuID0gbGVuZ3RoO1xuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBzcXVhcmVkIGxlbmd0aCBvZiBhIHF1YXRcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSB2ZWN0b3IgdG8gY2FsY3VsYXRlIHNxdWFyZWQgbGVuZ3RoIG9mXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBzcXVhcmVkIGxlbmd0aCBvZiBhXG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIHNxdWFyZWRMZW5ndGggPSB2ZWM0LnNxdWFyZWRMZW5ndGg7XG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgcXVhdC5zcXVhcmVkTGVuZ3RofVxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBzcXJMZW4gPSBzcXVhcmVkTGVuZ3RoO1xuLyoqXG4gKiBOb3JtYWxpemUgYSBxdWF0XG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSBxdWF0ZXJuaW9uIHRvIG5vcm1hbGl6ZVxuICogQHJldHVybnMge3F1YXR9IG91dFxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBub3JtYWxpemUgPSB2ZWM0Lm5vcm1hbGl6ZTtcbi8qKlxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgcXVhdGVybmlvbnMgaGF2ZSBleGFjdGx5IHRoZSBzYW1lIGVsZW1lbnRzIGluIHRoZSBzYW1lIHBvc2l0aW9uICh3aGVuIGNvbXBhcmVkIHdpdGggPT09KVxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIFRoZSBmaXJzdCBxdWF0ZXJuaW9uLlxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGIgVGhlIHNlY29uZCBxdWF0ZXJuaW9uLlxuICogQHJldHVybnMge0Jvb2xlYW59IFRydWUgaWYgdGhlIHZlY3RvcnMgYXJlIGVxdWFsLCBmYWxzZSBvdGhlcndpc2UuXG4gKi9cblxuZXhwb3J0IHZhciBleGFjdEVxdWFscyA9IHZlYzQuZXhhY3RFcXVhbHM7XG4vKipcbiAqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhlIHF1YXRlcm5pb25zIGhhdmUgYXBwcm94aW1hdGVseSB0aGUgc2FtZSBlbGVtZW50cyBpbiB0aGUgc2FtZSBwb3NpdGlvbi5cbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSBUaGUgZmlyc3QgdmVjdG9yLlxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGIgVGhlIHNlY29uZCB2ZWN0b3IuXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gVHJ1ZSBpZiB0aGUgdmVjdG9ycyBhcmUgZXF1YWwsIGZhbHNlIG90aGVyd2lzZS5cbiAqL1xuXG5leHBvcnQgdmFyIGVxdWFscyA9IHZlYzQuZXF1YWxzO1xuLyoqXG4gKiBTZXRzIGEgcXVhdGVybmlvbiB0byByZXByZXNlbnQgdGhlIHNob3J0ZXN0IHJvdGF0aW9uIGZyb20gb25lXG4gKiB2ZWN0b3IgdG8gYW5vdGhlci5cbiAqXG4gKiBCb3RoIHZlY3RvcnMgYXJlIGFzc3VtZWQgdG8gYmUgdW5pdCBsZW5ndGguXG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uLlxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdGhlIGluaXRpYWwgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYiB0aGUgZGVzdGluYXRpb24gdmVjdG9yXG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XG4gKi9cblxuZXhwb3J0IHZhciByb3RhdGlvblRvID0gZnVuY3Rpb24gKCkge1xuICB2YXIgdG1wdmVjMyA9IHZlYzMuY3JlYXRlKCk7XG4gIHZhciB4VW5pdFZlYzMgPSB2ZWMzLmZyb21WYWx1ZXMoMSwgMCwgMCk7XG4gIHZhciB5VW5pdFZlYzMgPSB2ZWMzLmZyb21WYWx1ZXMoMCwgMSwgMCk7XG4gIHJldHVybiBmdW5jdGlvbiAob3V0LCBhLCBiKSB7XG4gICAgdmFyIGRvdCA9IHZlYzMuZG90KGEsIGIpO1xuXG4gICAgaWYgKGRvdCA8IC0wLjk5OTk5OSkge1xuICAgICAgdmVjMy5jcm9zcyh0bXB2ZWMzLCB4VW5pdFZlYzMsIGEpO1xuICAgICAgaWYgKHZlYzMubGVuKHRtcHZlYzMpIDwgMC4wMDAwMDEpIHZlYzMuY3Jvc3ModG1wdmVjMywgeVVuaXRWZWMzLCBhKTtcbiAgICAgIHZlYzMubm9ybWFsaXplKHRtcHZlYzMsIHRtcHZlYzMpO1xuICAgICAgc2V0QXhpc0FuZ2xlKG91dCwgdG1wdmVjMywgTWF0aC5QSSk7XG4gICAgICByZXR1cm4gb3V0O1xuICAgIH0gZWxzZSBpZiAoZG90ID4gMC45OTk5OTkpIHtcbiAgICAgIG91dFswXSA9IDA7XG4gICAgICBvdXRbMV0gPSAwO1xuICAgICAgb3V0WzJdID0gMDtcbiAgICAgIG91dFszXSA9IDE7XG4gICAgICByZXR1cm4gb3V0O1xuICAgIH0gZWxzZSB7XG4gICAgICB2ZWMzLmNyb3NzKHRtcHZlYzMsIGEsIGIpO1xuICAgICAgb3V0WzBdID0gdG1wdmVjM1swXTtcbiAgICAgIG91dFsxXSA9IHRtcHZlYzNbMV07XG4gICAgICBvdXRbMl0gPSB0bXB2ZWMzWzJdO1xuICAgICAgb3V0WzNdID0gMSArIGRvdDtcbiAgICAgIHJldHVybiBub3JtYWxpemUob3V0LCBvdXQpO1xuICAgIH1cbiAgfTtcbn0oKTtcbi8qKlxuICogUGVyZm9ybXMgYSBzcGhlcmljYWwgbGluZWFyIGludGVycG9sYXRpb24gd2l0aCB0d28gY29udHJvbCBwb2ludHNcbiAqXG4gKiBAcGFyYW0ge3F1YXR9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBjIHRoZSB0aGlyZCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gZCB0aGUgZm91cnRoIG9wZXJhbmRcbiAqIEBwYXJhbSB7TnVtYmVyfSB0IGludGVycG9sYXRpb24gYW1vdW50LCBpbiB0aGUgcmFuZ2UgWzAtMV0sIGJldHdlZW4gdGhlIHR3byBpbnB1dHNcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqL1xuXG5leHBvcnQgdmFyIHNxbGVycCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHRlbXAxID0gY3JlYXRlKCk7XG4gIHZhciB0ZW1wMiA9IGNyZWF0ZSgpO1xuICByZXR1cm4gZnVuY3Rpb24gKG91dCwgYSwgYiwgYywgZCwgdCkge1xuICAgIHNsZXJwKHRlbXAxLCBhLCBkLCB0KTtcbiAgICBzbGVycCh0ZW1wMiwgYiwgYywgdCk7XG4gICAgc2xlcnAob3V0LCB0ZW1wMSwgdGVtcDIsIDIgKiB0ICogKDEgLSB0KSk7XG4gICAgcmV0dXJuIG91dDtcbiAgfTtcbn0oKTtcbi8qKlxuICogU2V0cyB0aGUgc3BlY2lmaWVkIHF1YXRlcm5pb24gd2l0aCB2YWx1ZXMgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW5cbiAqIGF4ZXMuIEVhY2ggYXhpcyBpcyBhIHZlYzMgYW5kIGlzIGV4cGVjdGVkIHRvIGJlIHVuaXQgbGVuZ3RoIGFuZFxuICogcGVycGVuZGljdWxhciB0byBhbGwgb3RoZXIgc3BlY2lmaWVkIGF4ZXMuXG4gKlxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IHZpZXcgIHRoZSB2ZWN0b3IgcmVwcmVzZW50aW5nIHRoZSB2aWV3aW5nIGRpcmVjdGlvblxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IHJpZ2h0IHRoZSB2ZWN0b3IgcmVwcmVzZW50aW5nIHRoZSBsb2NhbCBcInJpZ2h0XCIgZGlyZWN0aW9uXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gdXAgICAgdGhlIHZlY3RvciByZXByZXNlbnRpbmcgdGhlIGxvY2FsIFwidXBcIiBkaXJlY3Rpb25cbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqL1xuXG5leHBvcnQgdmFyIHNldEF4ZXMgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBtYXRyID0gbWF0My5jcmVhdGUoKTtcbiAgcmV0dXJuIGZ1bmN0aW9uIChvdXQsIHZpZXcsIHJpZ2h0LCB1cCkge1xuICAgIG1hdHJbMF0gPSByaWdodFswXTtcbiAgICBtYXRyWzNdID0gcmlnaHRbMV07XG4gICAgbWF0cls2XSA9IHJpZ2h0WzJdO1xuICAgIG1hdHJbMV0gPSB1cFswXTtcbiAgICBtYXRyWzRdID0gdXBbMV07XG4gICAgbWF0cls3XSA9IHVwWzJdO1xuICAgIG1hdHJbMl0gPSAtdmlld1swXTtcbiAgICBtYXRyWzVdID0gLXZpZXdbMV07XG4gICAgbWF0cls4XSA9IC12aWV3WzJdO1xuICAgIHJldHVybiBub3JtYWxpemUob3V0LCBmcm9tTWF0MyhvdXQsIG1hdHIpKTtcbiAgfTtcbn0oKTsiLCJpbXBvcnQgKiBhcyBnbE1hdHJpeCBmcm9tIFwiLi9jb21tb24uanNcIjtcbmltcG9ydCAqIGFzIHF1YXQgZnJvbSBcIi4vcXVhdC5qc1wiO1xuaW1wb3J0ICogYXMgbWF0NCBmcm9tIFwiLi9tYXQ0LmpzXCI7XG4vKipcbiAqIER1YWwgUXVhdGVybmlvbjxicj5cbiAqIEZvcm1hdDogW3JlYWwsIGR1YWxdPGJyPlxuICogUXVhdGVybmlvbiBmb3JtYXQ6IFhZWlc8YnI+XG4gKiBNYWtlIHN1cmUgdG8gaGF2ZSBub3JtYWxpemVkIGR1YWwgcXVhdGVybmlvbnMsIG90aGVyd2lzZSB0aGUgZnVuY3Rpb25zIG1heSBub3Qgd29yayBhcyBpbnRlbmRlZC48YnI+XG4gKiBAbW9kdWxlIHF1YXQyXG4gKi9cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGlkZW50aXR5IGR1YWwgcXVhdFxuICpcbiAqIEByZXR1cm5zIHtxdWF0Mn0gYSBuZXcgZHVhbCBxdWF0ZXJuaW9uIFtyZWFsIC0+IHJvdGF0aW9uLCBkdWFsIC0+IHRyYW5zbGF0aW9uXVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGUoKSB7XG4gIHZhciBkcSA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDgpO1xuXG4gIGlmIChnbE1hdHJpeC5BUlJBWV9UWVBFICE9IEZsb2F0MzJBcnJheSkge1xuICAgIGRxWzBdID0gMDtcbiAgICBkcVsxXSA9IDA7XG4gICAgZHFbMl0gPSAwO1xuICAgIGRxWzRdID0gMDtcbiAgICBkcVs1XSA9IDA7XG4gICAgZHFbNl0gPSAwO1xuICAgIGRxWzddID0gMDtcbiAgfVxuXG4gIGRxWzNdID0gMTtcbiAgcmV0dXJuIGRxO1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHF1YXQgaW5pdGlhbGl6ZWQgd2l0aCB2YWx1ZXMgZnJvbSBhbiBleGlzdGluZyBxdWF0ZXJuaW9uXG4gKlxuICogQHBhcmFtIHtSZWFkb25seVF1YXQyfSBhIGR1YWwgcXVhdGVybmlvbiB0byBjbG9uZVxuICogQHJldHVybnMge3F1YXQyfSBuZXcgZHVhbCBxdWF0ZXJuaW9uXG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY2xvbmUoYSkge1xuICB2YXIgZHEgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSg4KTtcbiAgZHFbMF0gPSBhWzBdO1xuICBkcVsxXSA9IGFbMV07XG4gIGRxWzJdID0gYVsyXTtcbiAgZHFbM10gPSBhWzNdO1xuICBkcVs0XSA9IGFbNF07XG4gIGRxWzVdID0gYVs1XTtcbiAgZHFbNl0gPSBhWzZdO1xuICBkcVs3XSA9IGFbN107XG4gIHJldHVybiBkcTtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBkdWFsIHF1YXQgaW5pdGlhbGl6ZWQgd2l0aCB0aGUgZ2l2ZW4gdmFsdWVzXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IHgxIFggY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0geTEgWSBjb21wb25lbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSB6MSBaIGNvbXBvbmVudFxuICogQHBhcmFtIHtOdW1iZXJ9IHcxIFcgY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0geDIgWCBjb21wb25lbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSB5MiBZIGNvbXBvbmVudFxuICogQHBhcmFtIHtOdW1iZXJ9IHoyIFogY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0gdzIgVyBjb21wb25lbnRcbiAqIEByZXR1cm5zIHtxdWF0Mn0gbmV3IGR1YWwgcXVhdGVybmlvblxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21WYWx1ZXMoeDEsIHkxLCB6MSwgdzEsIHgyLCB5MiwgejIsIHcyKSB7XG4gIHZhciBkcSA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDgpO1xuICBkcVswXSA9IHgxO1xuICBkcVsxXSA9IHkxO1xuICBkcVsyXSA9IHoxO1xuICBkcVszXSA9IHcxO1xuICBkcVs0XSA9IHgyO1xuICBkcVs1XSA9IHkyO1xuICBkcVs2XSA9IHoyO1xuICBkcVs3XSA9IHcyO1xuICByZXR1cm4gZHE7XG59XG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgZHVhbCBxdWF0IGZyb20gdGhlIGdpdmVuIHZhbHVlcyAocXVhdCBhbmQgdHJhbnNsYXRpb24pXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IHgxIFggY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0geTEgWSBjb21wb25lbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSB6MSBaIGNvbXBvbmVudFxuICogQHBhcmFtIHtOdW1iZXJ9IHcxIFcgY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0geDIgWCBjb21wb25lbnQgKHRyYW5zbGF0aW9uKVxuICogQHBhcmFtIHtOdW1iZXJ9IHkyIFkgY29tcG9uZW50ICh0cmFuc2xhdGlvbilcbiAqIEBwYXJhbSB7TnVtYmVyfSB6MiBaIGNvbXBvbmVudCAodHJhbnNsYXRpb24pXG4gKiBAcmV0dXJucyB7cXVhdDJ9IG5ldyBkdWFsIHF1YXRlcm5pb25cbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9tUm90YXRpb25UcmFuc2xhdGlvblZhbHVlcyh4MSwgeTEsIHoxLCB3MSwgeDIsIHkyLCB6Mikge1xuICB2YXIgZHEgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSg4KTtcbiAgZHFbMF0gPSB4MTtcbiAgZHFbMV0gPSB5MTtcbiAgZHFbMl0gPSB6MTtcbiAgZHFbM10gPSB3MTtcbiAgdmFyIGF4ID0geDIgKiAwLjUsXG4gICAgICBheSA9IHkyICogMC41LFxuICAgICAgYXogPSB6MiAqIDAuNTtcbiAgZHFbNF0gPSBheCAqIHcxICsgYXkgKiB6MSAtIGF6ICogeTE7XG4gIGRxWzVdID0gYXkgKiB3MSArIGF6ICogeDEgLSBheCAqIHoxO1xuICBkcVs2XSA9IGF6ICogdzEgKyBheCAqIHkxIC0gYXkgKiB4MTtcbiAgZHFbN10gPSAtYXggKiB4MSAtIGF5ICogeTEgLSBheiAqIHoxO1xuICByZXR1cm4gZHE7XG59XG4vKipcbiAqIENyZWF0ZXMgYSBkdWFsIHF1YXQgZnJvbSBhIHF1YXRlcm5pb24gYW5kIGEgdHJhbnNsYXRpb25cbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdDJ9IGR1YWwgcXVhdGVybmlvbiByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IHEgYSBub3JtYWxpemVkIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSB0IHRyYW5sYXRpb24gdmVjdG9yXG4gKiBAcmV0dXJucyB7cXVhdDJ9IGR1YWwgcXVhdGVybmlvbiByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21Sb3RhdGlvblRyYW5zbGF0aW9uKG91dCwgcSwgdCkge1xuICB2YXIgYXggPSB0WzBdICogMC41LFxuICAgICAgYXkgPSB0WzFdICogMC41LFxuICAgICAgYXogPSB0WzJdICogMC41LFxuICAgICAgYnggPSBxWzBdLFxuICAgICAgYnkgPSBxWzFdLFxuICAgICAgYnogPSBxWzJdLFxuICAgICAgYncgPSBxWzNdO1xuICBvdXRbMF0gPSBieDtcbiAgb3V0WzFdID0gYnk7XG4gIG91dFsyXSA9IGJ6O1xuICBvdXRbM10gPSBidztcbiAgb3V0WzRdID0gYXggKiBidyArIGF5ICogYnogLSBheiAqIGJ5O1xuICBvdXRbNV0gPSBheSAqIGJ3ICsgYXogKiBieCAtIGF4ICogYno7XG4gIG91dFs2XSA9IGF6ICogYncgKyBheCAqIGJ5IC0gYXkgKiBieDtcbiAgb3V0WzddID0gLWF4ICogYnggLSBheSAqIGJ5IC0gYXogKiBiejtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIGR1YWwgcXVhdCBmcm9tIGEgdHJhbnNsYXRpb25cbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdDJ9IGR1YWwgcXVhdGVybmlvbiByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IHQgdHJhbnNsYXRpb24gdmVjdG9yXG4gKiBAcmV0dXJucyB7cXVhdDJ9IGR1YWwgcXVhdGVybmlvbiByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21UcmFuc2xhdGlvbihvdXQsIHQpIHtcbiAgb3V0WzBdID0gMDtcbiAgb3V0WzFdID0gMDtcbiAgb3V0WzJdID0gMDtcbiAgb3V0WzNdID0gMTtcbiAgb3V0WzRdID0gdFswXSAqIDAuNTtcbiAgb3V0WzVdID0gdFsxXSAqIDAuNTtcbiAgb3V0WzZdID0gdFsyXSAqIDAuNTtcbiAgb3V0WzddID0gMDtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIGR1YWwgcXVhdCBmcm9tIGEgcXVhdGVybmlvblxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gZHVhbCBxdWF0ZXJuaW9uIHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gcSB0aGUgcXVhdGVybmlvblxuICogQHJldHVybnMge3F1YXQyfSBkdWFsIHF1YXRlcm5pb24gcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9tUm90YXRpb24ob3V0LCBxKSB7XG4gIG91dFswXSA9IHFbMF07XG4gIG91dFsxXSA9IHFbMV07XG4gIG91dFsyXSA9IHFbMl07XG4gIG91dFszXSA9IHFbM107XG4gIG91dFs0XSA9IDA7XG4gIG91dFs1XSA9IDA7XG4gIG91dFs2XSA9IDA7XG4gIG91dFs3XSA9IDA7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgZHVhbCBxdWF0IGZyb20gYSBtYXRyaXggKDR4NClcbiAqXG4gKiBAcGFyYW0ge3F1YXQyfSBvdXQgdGhlIGR1YWwgcXVhdGVybmlvblxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGEgdGhlIG1hdHJpeFxuICogQHJldHVybnMge3F1YXQyfSBkdWFsIHF1YXQgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9tTWF0NChvdXQsIGEpIHtcbiAgLy9UT0RPIE9wdGltaXplIHRoaXNcbiAgdmFyIG91dGVyID0gcXVhdC5jcmVhdGUoKTtcbiAgbWF0NC5nZXRSb3RhdGlvbihvdXRlciwgYSk7XG4gIHZhciB0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoMyk7XG4gIG1hdDQuZ2V0VHJhbnNsYXRpb24odCwgYSk7XG4gIGZyb21Sb3RhdGlvblRyYW5zbGF0aW9uKG91dCwgb3V0ZXIsIHQpO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDb3B5IHRoZSB2YWx1ZXMgZnJvbSBvbmUgZHVhbCBxdWF0IHRvIGFub3RoZXJcbiAqXG4gKiBAcGFyYW0ge3F1YXQyfSBvdXQgdGhlIHJlY2VpdmluZyBkdWFsIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gYSB0aGUgc291cmNlIGR1YWwgcXVhdGVybmlvblxuICogQHJldHVybnMge3F1YXQyfSBvdXRcbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjb3B5KG91dCwgYSkge1xuICBvdXRbMF0gPSBhWzBdO1xuICBvdXRbMV0gPSBhWzFdO1xuICBvdXRbMl0gPSBhWzJdO1xuICBvdXRbM10gPSBhWzNdO1xuICBvdXRbNF0gPSBhWzRdO1xuICBvdXRbNV0gPSBhWzVdO1xuICBvdXRbNl0gPSBhWzZdO1xuICBvdXRbN10gPSBhWzddO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBTZXQgYSBkdWFsIHF1YXQgdG8gdGhlIGlkZW50aXR5IGR1YWwgcXVhdGVybmlvblxuICpcbiAqIEBwYXJhbSB7cXVhdDJ9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cbiAqIEByZXR1cm5zIHtxdWF0Mn0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGlkZW50aXR5KG91dCkge1xuICBvdXRbMF0gPSAwO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAxO1xuICBvdXRbNF0gPSAwO1xuICBvdXRbNV0gPSAwO1xuICBvdXRbNl0gPSAwO1xuICBvdXRbN10gPSAwO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBTZXQgdGhlIGNvbXBvbmVudHMgb2YgYSBkdWFsIHF1YXQgdG8gdGhlIGdpdmVuIHZhbHVlc1xuICpcbiAqIEBwYXJhbSB7cXVhdDJ9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7TnVtYmVyfSB4MSBYIGNvbXBvbmVudFxuICogQHBhcmFtIHtOdW1iZXJ9IHkxIFkgY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0gejEgWiBjb21wb25lbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSB3MSBXIGNvbXBvbmVudFxuICogQHBhcmFtIHtOdW1iZXJ9IHgyIFggY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0geTIgWSBjb21wb25lbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSB6MiBaIGNvbXBvbmVudFxuICogQHBhcmFtIHtOdW1iZXJ9IHcyIFcgY29tcG9uZW50XG4gKiBAcmV0dXJucyB7cXVhdDJ9IG91dFxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNldChvdXQsIHgxLCB5MSwgejEsIHcxLCB4MiwgeTIsIHoyLCB3Mikge1xuICBvdXRbMF0gPSB4MTtcbiAgb3V0WzFdID0geTE7XG4gIG91dFsyXSA9IHoxO1xuICBvdXRbM10gPSB3MTtcbiAgb3V0WzRdID0geDI7XG4gIG91dFs1XSA9IHkyO1xuICBvdXRbNl0gPSB6MjtcbiAgb3V0WzddID0gdzI7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIEdldHMgdGhlIHJlYWwgcGFydCBvZiBhIGR1YWwgcXVhdFxuICogQHBhcmFtICB7cXVhdH0gb3V0IHJlYWwgcGFydFxuICogQHBhcmFtICB7UmVhZG9ubHlRdWF0Mn0gYSBEdWFsIFF1YXRlcm5pb25cbiAqIEByZXR1cm4ge3F1YXR9IHJlYWwgcGFydFxuICovXG5cbmV4cG9ydCB2YXIgZ2V0UmVhbCA9IHF1YXQuY29weTtcbi8qKlxuICogR2V0cyB0aGUgZHVhbCBwYXJ0IG9mIGEgZHVhbCBxdWF0XG4gKiBAcGFyYW0gIHtxdWF0fSBvdXQgZHVhbCBwYXJ0XG4gKiBAcGFyYW0gIHtSZWFkb25seVF1YXQyfSBhIER1YWwgUXVhdGVybmlvblxuICogQHJldHVybiB7cXVhdH0gZHVhbCBwYXJ0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldER1YWwob3V0LCBhKSB7XG4gIG91dFswXSA9IGFbNF07XG4gIG91dFsxXSA9IGFbNV07XG4gIG91dFsyXSA9IGFbNl07XG4gIG91dFszXSA9IGFbN107XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFNldCB0aGUgcmVhbCBjb21wb25lbnQgb2YgYSBkdWFsIHF1YXQgdG8gdGhlIGdpdmVuIHF1YXRlcm5pb25cbiAqXG4gKiBAcGFyYW0ge3F1YXQyfSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gcSBhIHF1YXRlcm5pb24gcmVwcmVzZW50aW5nIHRoZSByZWFsIHBhcnRcbiAqIEByZXR1cm5zIHtxdWF0Mn0gb3V0XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIHNldFJlYWwgPSBxdWF0LmNvcHk7XG4vKipcbiAqIFNldCB0aGUgZHVhbCBjb21wb25lbnQgb2YgYSBkdWFsIHF1YXQgdG8gdGhlIGdpdmVuIHF1YXRlcm5pb25cbiAqXG4gKiBAcGFyYW0ge3F1YXQyfSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gcSBhIHF1YXRlcm5pb24gcmVwcmVzZW50aW5nIHRoZSBkdWFsIHBhcnRcbiAqIEByZXR1cm5zIHtxdWF0Mn0gb3V0XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc2V0RHVhbChvdXQsIHEpIHtcbiAgb3V0WzRdID0gcVswXTtcbiAgb3V0WzVdID0gcVsxXTtcbiAgb3V0WzZdID0gcVsyXTtcbiAgb3V0WzddID0gcVszXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogR2V0cyB0aGUgdHJhbnNsYXRpb24gb2YgYSBub3JtYWxpemVkIGR1YWwgcXVhdFxuICogQHBhcmFtICB7dmVjM30gb3V0IHRyYW5zbGF0aW9uXG4gKiBAcGFyYW0gIHtSZWFkb25seVF1YXQyfSBhIER1YWwgUXVhdGVybmlvbiB0byBiZSBkZWNvbXBvc2VkXG4gKiBAcmV0dXJuIHt2ZWMzfSB0cmFuc2xhdGlvblxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUcmFuc2xhdGlvbihvdXQsIGEpIHtcbiAgdmFyIGF4ID0gYVs0XSxcbiAgICAgIGF5ID0gYVs1XSxcbiAgICAgIGF6ID0gYVs2XSxcbiAgICAgIGF3ID0gYVs3XSxcbiAgICAgIGJ4ID0gLWFbMF0sXG4gICAgICBieSA9IC1hWzFdLFxuICAgICAgYnogPSAtYVsyXSxcbiAgICAgIGJ3ID0gYVszXTtcbiAgb3V0WzBdID0gKGF4ICogYncgKyBhdyAqIGJ4ICsgYXkgKiBieiAtIGF6ICogYnkpICogMjtcbiAgb3V0WzFdID0gKGF5ICogYncgKyBhdyAqIGJ5ICsgYXogKiBieCAtIGF4ICogYnopICogMjtcbiAgb3V0WzJdID0gKGF6ICogYncgKyBhdyAqIGJ6ICsgYXggKiBieSAtIGF5ICogYngpICogMjtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogVHJhbnNsYXRlcyBhIGR1YWwgcXVhdCBieSB0aGUgZ2l2ZW4gdmVjdG9yXG4gKlxuICogQHBhcmFtIHtxdWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgZHVhbCBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdDJ9IGEgdGhlIGR1YWwgcXVhdGVybmlvbiB0byB0cmFuc2xhdGVcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSB2IHZlY3RvciB0byB0cmFuc2xhdGUgYnlcbiAqIEByZXR1cm5zIHtxdWF0Mn0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zbGF0ZShvdXQsIGEsIHYpIHtcbiAgdmFyIGF4MSA9IGFbMF0sXG4gICAgICBheTEgPSBhWzFdLFxuICAgICAgYXoxID0gYVsyXSxcbiAgICAgIGF3MSA9IGFbM10sXG4gICAgICBieDEgPSB2WzBdICogMC41LFxuICAgICAgYnkxID0gdlsxXSAqIDAuNSxcbiAgICAgIGJ6MSA9IHZbMl0gKiAwLjUsXG4gICAgICBheDIgPSBhWzRdLFxuICAgICAgYXkyID0gYVs1XSxcbiAgICAgIGF6MiA9IGFbNl0sXG4gICAgICBhdzIgPSBhWzddO1xuICBvdXRbMF0gPSBheDE7XG4gIG91dFsxXSA9IGF5MTtcbiAgb3V0WzJdID0gYXoxO1xuICBvdXRbM10gPSBhdzE7XG4gIG91dFs0XSA9IGF3MSAqIGJ4MSArIGF5MSAqIGJ6MSAtIGF6MSAqIGJ5MSArIGF4MjtcbiAgb3V0WzVdID0gYXcxICogYnkxICsgYXoxICogYngxIC0gYXgxICogYnoxICsgYXkyO1xuICBvdXRbNl0gPSBhdzEgKiBiejEgKyBheDEgKiBieTEgLSBheTEgKiBieDEgKyBhejI7XG4gIG91dFs3XSA9IC1heDEgKiBieDEgLSBheTEgKiBieTEgLSBhejEgKiBiejEgKyBhdzI7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFJvdGF0ZXMgYSBkdWFsIHF1YXQgYXJvdW5kIHRoZSBYIGF4aXNcbiAqXG4gKiBAcGFyYW0ge3F1YXQyfSBvdXQgdGhlIHJlY2VpdmluZyBkdWFsIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gYSB0aGUgZHVhbCBxdWF0ZXJuaW9uIHRvIHJvdGF0ZVxuICogQHBhcmFtIHtudW1iZXJ9IHJhZCBob3cgZmFyIHNob3VsZCB0aGUgcm90YXRpb24gYmVcbiAqIEByZXR1cm5zIHtxdWF0Mn0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJvdGF0ZVgob3V0LCBhLCByYWQpIHtcbiAgdmFyIGJ4ID0gLWFbMF0sXG4gICAgICBieSA9IC1hWzFdLFxuICAgICAgYnogPSAtYVsyXSxcbiAgICAgIGJ3ID0gYVszXSxcbiAgICAgIGF4ID0gYVs0XSxcbiAgICAgIGF5ID0gYVs1XSxcbiAgICAgIGF6ID0gYVs2XSxcbiAgICAgIGF3ID0gYVs3XSxcbiAgICAgIGF4MSA9IGF4ICogYncgKyBhdyAqIGJ4ICsgYXkgKiBieiAtIGF6ICogYnksXG4gICAgICBheTEgPSBheSAqIGJ3ICsgYXcgKiBieSArIGF6ICogYnggLSBheCAqIGJ6LFxuICAgICAgYXoxID0gYXogKiBidyArIGF3ICogYnogKyBheCAqIGJ5IC0gYXkgKiBieCxcbiAgICAgIGF3MSA9IGF3ICogYncgLSBheCAqIGJ4IC0gYXkgKiBieSAtIGF6ICogYno7XG4gIHF1YXQucm90YXRlWChvdXQsIGEsIHJhZCk7XG4gIGJ4ID0gb3V0WzBdO1xuICBieSA9IG91dFsxXTtcbiAgYnogPSBvdXRbMl07XG4gIGJ3ID0gb3V0WzNdO1xuICBvdXRbNF0gPSBheDEgKiBidyArIGF3MSAqIGJ4ICsgYXkxICogYnogLSBhejEgKiBieTtcbiAgb3V0WzVdID0gYXkxICogYncgKyBhdzEgKiBieSArIGF6MSAqIGJ4IC0gYXgxICogYno7XG4gIG91dFs2XSA9IGF6MSAqIGJ3ICsgYXcxICogYnogKyBheDEgKiBieSAtIGF5MSAqIGJ4O1xuICBvdXRbN10gPSBhdzEgKiBidyAtIGF4MSAqIGJ4IC0gYXkxICogYnkgLSBhejEgKiBiejtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUm90YXRlcyBhIGR1YWwgcXVhdCBhcm91bmQgdGhlIFkgYXhpc1xuICpcbiAqIEBwYXJhbSB7cXVhdDJ9IG91dCB0aGUgcmVjZWl2aW5nIGR1YWwgcXVhdGVybmlvblxuICogQHBhcmFtIHtSZWFkb25seVF1YXQyfSBhIHRoZSBkdWFsIHF1YXRlcm5pb24gdG8gcm90YXRlXG4gKiBAcGFyYW0ge251bWJlcn0gcmFkIGhvdyBmYXIgc2hvdWxkIHRoZSByb3RhdGlvbiBiZVxuICogQHJldHVybnMge3F1YXQyfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcm90YXRlWShvdXQsIGEsIHJhZCkge1xuICB2YXIgYnggPSAtYVswXSxcbiAgICAgIGJ5ID0gLWFbMV0sXG4gICAgICBieiA9IC1hWzJdLFxuICAgICAgYncgPSBhWzNdLFxuICAgICAgYXggPSBhWzRdLFxuICAgICAgYXkgPSBhWzVdLFxuICAgICAgYXogPSBhWzZdLFxuICAgICAgYXcgPSBhWzddLFxuICAgICAgYXgxID0gYXggKiBidyArIGF3ICogYnggKyBheSAqIGJ6IC0gYXogKiBieSxcbiAgICAgIGF5MSA9IGF5ICogYncgKyBhdyAqIGJ5ICsgYXogKiBieCAtIGF4ICogYnosXG4gICAgICBhejEgPSBheiAqIGJ3ICsgYXcgKiBieiArIGF4ICogYnkgLSBheSAqIGJ4LFxuICAgICAgYXcxID0gYXcgKiBidyAtIGF4ICogYnggLSBheSAqIGJ5IC0gYXogKiBiejtcbiAgcXVhdC5yb3RhdGVZKG91dCwgYSwgcmFkKTtcbiAgYnggPSBvdXRbMF07XG4gIGJ5ID0gb3V0WzFdO1xuICBieiA9IG91dFsyXTtcbiAgYncgPSBvdXRbM107XG4gIG91dFs0XSA9IGF4MSAqIGJ3ICsgYXcxICogYnggKyBheTEgKiBieiAtIGF6MSAqIGJ5O1xuICBvdXRbNV0gPSBheTEgKiBidyArIGF3MSAqIGJ5ICsgYXoxICogYnggLSBheDEgKiBiejtcbiAgb3V0WzZdID0gYXoxICogYncgKyBhdzEgKiBieiArIGF4MSAqIGJ5IC0gYXkxICogYng7XG4gIG91dFs3XSA9IGF3MSAqIGJ3IC0gYXgxICogYnggLSBheTEgKiBieSAtIGF6MSAqIGJ6O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBSb3RhdGVzIGEgZHVhbCBxdWF0IGFyb3VuZCB0aGUgWiBheGlzXG4gKlxuICogQHBhcmFtIHtxdWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgZHVhbCBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdDJ9IGEgdGhlIGR1YWwgcXVhdGVybmlvbiB0byByb3RhdGVcbiAqIEBwYXJhbSB7bnVtYmVyfSByYWQgaG93IGZhciBzaG91bGQgdGhlIHJvdGF0aW9uIGJlXG4gKiBAcmV0dXJucyB7cXVhdDJ9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByb3RhdGVaKG91dCwgYSwgcmFkKSB7XG4gIHZhciBieCA9IC1hWzBdLFxuICAgICAgYnkgPSAtYVsxXSxcbiAgICAgIGJ6ID0gLWFbMl0sXG4gICAgICBidyA9IGFbM10sXG4gICAgICBheCA9IGFbNF0sXG4gICAgICBheSA9IGFbNV0sXG4gICAgICBheiA9IGFbNl0sXG4gICAgICBhdyA9IGFbN10sXG4gICAgICBheDEgPSBheCAqIGJ3ICsgYXcgKiBieCArIGF5ICogYnogLSBheiAqIGJ5LFxuICAgICAgYXkxID0gYXkgKiBidyArIGF3ICogYnkgKyBheiAqIGJ4IC0gYXggKiBieixcbiAgICAgIGF6MSA9IGF6ICogYncgKyBhdyAqIGJ6ICsgYXggKiBieSAtIGF5ICogYngsXG4gICAgICBhdzEgPSBhdyAqIGJ3IC0gYXggKiBieCAtIGF5ICogYnkgLSBheiAqIGJ6O1xuICBxdWF0LnJvdGF0ZVoob3V0LCBhLCByYWQpO1xuICBieCA9IG91dFswXTtcbiAgYnkgPSBvdXRbMV07XG4gIGJ6ID0gb3V0WzJdO1xuICBidyA9IG91dFszXTtcbiAgb3V0WzRdID0gYXgxICogYncgKyBhdzEgKiBieCArIGF5MSAqIGJ6IC0gYXoxICogYnk7XG4gIG91dFs1XSA9IGF5MSAqIGJ3ICsgYXcxICogYnkgKyBhejEgKiBieCAtIGF4MSAqIGJ6O1xuICBvdXRbNl0gPSBhejEgKiBidyArIGF3MSAqIGJ6ICsgYXgxICogYnkgLSBheTEgKiBieDtcbiAgb3V0WzddID0gYXcxICogYncgLSBheDEgKiBieCAtIGF5MSAqIGJ5IC0gYXoxICogYno7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFJvdGF0ZXMgYSBkdWFsIHF1YXQgYnkgYSBnaXZlbiBxdWF0ZXJuaW9uIChhICogcSlcbiAqXG4gKiBAcGFyYW0ge3F1YXQyfSBvdXQgdGhlIHJlY2VpdmluZyBkdWFsIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gYSB0aGUgZHVhbCBxdWF0ZXJuaW9uIHRvIHJvdGF0ZVxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IHEgcXVhdGVybmlvbiB0byByb3RhdGUgYnlcbiAqIEByZXR1cm5zIHtxdWF0Mn0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJvdGF0ZUJ5UXVhdEFwcGVuZChvdXQsIGEsIHEpIHtcbiAgdmFyIHF4ID0gcVswXSxcbiAgICAgIHF5ID0gcVsxXSxcbiAgICAgIHF6ID0gcVsyXSxcbiAgICAgIHF3ID0gcVszXSxcbiAgICAgIGF4ID0gYVswXSxcbiAgICAgIGF5ID0gYVsxXSxcbiAgICAgIGF6ID0gYVsyXSxcbiAgICAgIGF3ID0gYVszXTtcbiAgb3V0WzBdID0gYXggKiBxdyArIGF3ICogcXggKyBheSAqIHF6IC0gYXogKiBxeTtcbiAgb3V0WzFdID0gYXkgKiBxdyArIGF3ICogcXkgKyBheiAqIHF4IC0gYXggKiBxejtcbiAgb3V0WzJdID0gYXogKiBxdyArIGF3ICogcXogKyBheCAqIHF5IC0gYXkgKiBxeDtcbiAgb3V0WzNdID0gYXcgKiBxdyAtIGF4ICogcXggLSBheSAqIHF5IC0gYXogKiBxejtcbiAgYXggPSBhWzRdO1xuICBheSA9IGFbNV07XG4gIGF6ID0gYVs2XTtcbiAgYXcgPSBhWzddO1xuICBvdXRbNF0gPSBheCAqIHF3ICsgYXcgKiBxeCArIGF5ICogcXogLSBheiAqIHF5O1xuICBvdXRbNV0gPSBheSAqIHF3ICsgYXcgKiBxeSArIGF6ICogcXggLSBheCAqIHF6O1xuICBvdXRbNl0gPSBheiAqIHF3ICsgYXcgKiBxeiArIGF4ICogcXkgLSBheSAqIHF4O1xuICBvdXRbN10gPSBhdyAqIHF3IC0gYXggKiBxeCAtIGF5ICogcXkgLSBheiAqIHF6O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBSb3RhdGVzIGEgZHVhbCBxdWF0IGJ5IGEgZ2l2ZW4gcXVhdGVybmlvbiAocSAqIGEpXG4gKlxuICogQHBhcmFtIHtxdWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgZHVhbCBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gcSBxdWF0ZXJuaW9uIHRvIHJvdGF0ZSBieVxuICogQHBhcmFtIHtSZWFkb25seVF1YXQyfSBhIHRoZSBkdWFsIHF1YXRlcm5pb24gdG8gcm90YXRlXG4gKiBAcmV0dXJucyB7cXVhdDJ9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByb3RhdGVCeVF1YXRQcmVwZW5kKG91dCwgcSwgYSkge1xuICB2YXIgcXggPSBxWzBdLFxuICAgICAgcXkgPSBxWzFdLFxuICAgICAgcXogPSBxWzJdLFxuICAgICAgcXcgPSBxWzNdLFxuICAgICAgYnggPSBhWzBdLFxuICAgICAgYnkgPSBhWzFdLFxuICAgICAgYnogPSBhWzJdLFxuICAgICAgYncgPSBhWzNdO1xuICBvdXRbMF0gPSBxeCAqIGJ3ICsgcXcgKiBieCArIHF5ICogYnogLSBxeiAqIGJ5O1xuICBvdXRbMV0gPSBxeSAqIGJ3ICsgcXcgKiBieSArIHF6ICogYnggLSBxeCAqIGJ6O1xuICBvdXRbMl0gPSBxeiAqIGJ3ICsgcXcgKiBieiArIHF4ICogYnkgLSBxeSAqIGJ4O1xuICBvdXRbM10gPSBxdyAqIGJ3IC0gcXggKiBieCAtIHF5ICogYnkgLSBxeiAqIGJ6O1xuICBieCA9IGFbNF07XG4gIGJ5ID0gYVs1XTtcbiAgYnogPSBhWzZdO1xuICBidyA9IGFbN107XG4gIG91dFs0XSA9IHF4ICogYncgKyBxdyAqIGJ4ICsgcXkgKiBieiAtIHF6ICogYnk7XG4gIG91dFs1XSA9IHF5ICogYncgKyBxdyAqIGJ5ICsgcXogKiBieCAtIHF4ICogYno7XG4gIG91dFs2XSA9IHF6ICogYncgKyBxdyAqIGJ6ICsgcXggKiBieSAtIHF5ICogYng7XG4gIG91dFs3XSA9IHF3ICogYncgLSBxeCAqIGJ4IC0gcXkgKiBieSAtIHF6ICogYno7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFJvdGF0ZXMgYSBkdWFsIHF1YXQgYXJvdW5kIGEgZ2l2ZW4gYXhpcy4gRG9lcyB0aGUgbm9ybWFsaXNhdGlvbiBhdXRvbWF0aWNhbGx5XG4gKlxuICogQHBhcmFtIHtxdWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgZHVhbCBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdDJ9IGEgdGhlIGR1YWwgcXVhdGVybmlvbiB0byByb3RhdGVcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBheGlzIHRoZSBheGlzIHRvIHJvdGF0ZSBhcm91bmRcbiAqIEBwYXJhbSB7TnVtYmVyfSByYWQgaG93IGZhciB0aGUgcm90YXRpb24gc2hvdWxkIGJlXG4gKiBAcmV0dXJucyB7cXVhdDJ9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByb3RhdGVBcm91bmRBeGlzKG91dCwgYSwgYXhpcywgcmFkKSB7XG4gIC8vU3BlY2lhbCBjYXNlIGZvciByYWQgPSAwXG4gIGlmIChNYXRoLmFicyhyYWQpIDwgZ2xNYXRyaXguRVBTSUxPTikge1xuICAgIHJldHVybiBjb3B5KG91dCwgYSk7XG4gIH1cblxuICB2YXIgYXhpc0xlbmd0aCA9IE1hdGguaHlwb3QoYXhpc1swXSwgYXhpc1sxXSwgYXhpc1syXSk7XG4gIHJhZCA9IHJhZCAqIDAuNTtcbiAgdmFyIHMgPSBNYXRoLnNpbihyYWQpO1xuICB2YXIgYnggPSBzICogYXhpc1swXSAvIGF4aXNMZW5ndGg7XG4gIHZhciBieSA9IHMgKiBheGlzWzFdIC8gYXhpc0xlbmd0aDtcbiAgdmFyIGJ6ID0gcyAqIGF4aXNbMl0gLyBheGlzTGVuZ3RoO1xuICB2YXIgYncgPSBNYXRoLmNvcyhyYWQpO1xuICB2YXIgYXgxID0gYVswXSxcbiAgICAgIGF5MSA9IGFbMV0sXG4gICAgICBhejEgPSBhWzJdLFxuICAgICAgYXcxID0gYVszXTtcbiAgb3V0WzBdID0gYXgxICogYncgKyBhdzEgKiBieCArIGF5MSAqIGJ6IC0gYXoxICogYnk7XG4gIG91dFsxXSA9IGF5MSAqIGJ3ICsgYXcxICogYnkgKyBhejEgKiBieCAtIGF4MSAqIGJ6O1xuICBvdXRbMl0gPSBhejEgKiBidyArIGF3MSAqIGJ6ICsgYXgxICogYnkgLSBheTEgKiBieDtcbiAgb3V0WzNdID0gYXcxICogYncgLSBheDEgKiBieCAtIGF5MSAqIGJ5IC0gYXoxICogYno7XG4gIHZhciBheCA9IGFbNF0sXG4gICAgICBheSA9IGFbNV0sXG4gICAgICBheiA9IGFbNl0sXG4gICAgICBhdyA9IGFbN107XG4gIG91dFs0XSA9IGF4ICogYncgKyBhdyAqIGJ4ICsgYXkgKiBieiAtIGF6ICogYnk7XG4gIG91dFs1XSA9IGF5ICogYncgKyBhdyAqIGJ5ICsgYXogKiBieCAtIGF4ICogYno7XG4gIG91dFs2XSA9IGF6ICogYncgKyBhdyAqIGJ6ICsgYXggKiBieSAtIGF5ICogYng7XG4gIG91dFs3XSA9IGF3ICogYncgLSBheCAqIGJ4IC0gYXkgKiBieSAtIGF6ICogYno7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIEFkZHMgdHdvIGR1YWwgcXVhdCdzXG4gKlxuICogQHBhcmFtIHtxdWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgZHVhbCBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdDJ9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHtxdWF0Mn0gb3V0XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYWRkKG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdICsgYlswXTtcbiAgb3V0WzFdID0gYVsxXSArIGJbMV07XG4gIG91dFsyXSA9IGFbMl0gKyBiWzJdO1xuICBvdXRbM10gPSBhWzNdICsgYlszXTtcbiAgb3V0WzRdID0gYVs0XSArIGJbNF07XG4gIG91dFs1XSA9IGFbNV0gKyBiWzVdO1xuICBvdXRbNl0gPSBhWzZdICsgYls2XTtcbiAgb3V0WzddID0gYVs3XSArIGJbN107XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIE11bHRpcGxpZXMgdHdvIGR1YWwgcXVhdCdzXG4gKlxuICogQHBhcmFtIHtxdWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgZHVhbCBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdDJ9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHtxdWF0Mn0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG11bHRpcGx5KG91dCwgYSwgYikge1xuICB2YXIgYXgwID0gYVswXSxcbiAgICAgIGF5MCA9IGFbMV0sXG4gICAgICBhejAgPSBhWzJdLFxuICAgICAgYXcwID0gYVszXSxcbiAgICAgIGJ4MSA9IGJbNF0sXG4gICAgICBieTEgPSBiWzVdLFxuICAgICAgYnoxID0gYls2XSxcbiAgICAgIGJ3MSA9IGJbN10sXG4gICAgICBheDEgPSBhWzRdLFxuICAgICAgYXkxID0gYVs1XSxcbiAgICAgIGF6MSA9IGFbNl0sXG4gICAgICBhdzEgPSBhWzddLFxuICAgICAgYngwID0gYlswXSxcbiAgICAgIGJ5MCA9IGJbMV0sXG4gICAgICBiejAgPSBiWzJdLFxuICAgICAgYncwID0gYlszXTtcbiAgb3V0WzBdID0gYXgwICogYncwICsgYXcwICogYngwICsgYXkwICogYnowIC0gYXowICogYnkwO1xuICBvdXRbMV0gPSBheTAgKiBidzAgKyBhdzAgKiBieTAgKyBhejAgKiBieDAgLSBheDAgKiBiejA7XG4gIG91dFsyXSA9IGF6MCAqIGJ3MCArIGF3MCAqIGJ6MCArIGF4MCAqIGJ5MCAtIGF5MCAqIGJ4MDtcbiAgb3V0WzNdID0gYXcwICogYncwIC0gYXgwICogYngwIC0gYXkwICogYnkwIC0gYXowICogYnowO1xuICBvdXRbNF0gPSBheDAgKiBidzEgKyBhdzAgKiBieDEgKyBheTAgKiBiejEgLSBhejAgKiBieTEgKyBheDEgKiBidzAgKyBhdzEgKiBieDAgKyBheTEgKiBiejAgLSBhejEgKiBieTA7XG4gIG91dFs1XSA9IGF5MCAqIGJ3MSArIGF3MCAqIGJ5MSArIGF6MCAqIGJ4MSAtIGF4MCAqIGJ6MSArIGF5MSAqIGJ3MCArIGF3MSAqIGJ5MCArIGF6MSAqIGJ4MCAtIGF4MSAqIGJ6MDtcbiAgb3V0WzZdID0gYXowICogYncxICsgYXcwICogYnoxICsgYXgwICogYnkxIC0gYXkwICogYngxICsgYXoxICogYncwICsgYXcxICogYnowICsgYXgxICogYnkwIC0gYXkxICogYngwO1xuICBvdXRbN10gPSBhdzAgKiBidzEgLSBheDAgKiBieDEgLSBheTAgKiBieTEgLSBhejAgKiBiejEgKyBhdzEgKiBidzAgLSBheDEgKiBieDAgLSBheTEgKiBieTAgLSBhejEgKiBiejA7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgcXVhdDIubXVsdGlwbHl9XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIG11bCA9IG11bHRpcGx5O1xuLyoqXG4gKiBTY2FsZXMgYSBkdWFsIHF1YXQgYnkgYSBzY2FsYXIgbnVtYmVyXG4gKlxuICogQHBhcmFtIHtxdWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgZHVhbCBxdWF0XG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdDJ9IGEgdGhlIGR1YWwgcXVhdCB0byBzY2FsZVxuICogQHBhcmFtIHtOdW1iZXJ9IGIgYW1vdW50IHRvIHNjYWxlIHRoZSBkdWFsIHF1YXQgYnlcbiAqIEByZXR1cm5zIHtxdWF0Mn0gb3V0XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc2NhbGUob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IGFbMF0gKiBiO1xuICBvdXRbMV0gPSBhWzFdICogYjtcbiAgb3V0WzJdID0gYVsyXSAqIGI7XG4gIG91dFszXSA9IGFbM10gKiBiO1xuICBvdXRbNF0gPSBhWzRdICogYjtcbiAgb3V0WzVdID0gYVs1XSAqIGI7XG4gIG91dFs2XSA9IGFbNl0gKiBiO1xuICBvdXRbN10gPSBhWzddICogYjtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgZG90IHByb2R1Y3Qgb2YgdHdvIGR1YWwgcXVhdCdzIChUaGUgZG90IHByb2R1Y3Qgb2YgdGhlIHJlYWwgcGFydHMpXG4gKlxuICogQHBhcmFtIHtSZWFkb25seVF1YXQyfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdDJ9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBkb3QgcHJvZHVjdCBvZiBhIGFuZCBiXG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIGRvdCA9IHF1YXQuZG90O1xuLyoqXG4gKiBQZXJmb3JtcyBhIGxpbmVhciBpbnRlcnBvbGF0aW9uIGJldHdlZW4gdHdvIGR1YWwgcXVhdHMnc1xuICogTk9URTogVGhlIHJlc3VsdGluZyBkdWFsIHF1YXRlcm5pb25zIHdvbid0IGFsd2F5cyBiZSBub3JtYWxpemVkIChUaGUgZXJyb3IgaXMgbW9zdCBub3RpY2VhYmxlIHdoZW4gdCA9IDAuNSlcbiAqXG4gKiBAcGFyYW0ge3F1YXQyfSBvdXQgdGhlIHJlY2VpdmluZyBkdWFsIHF1YXRcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVF1YXQyfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHBhcmFtIHtOdW1iZXJ9IHQgaW50ZXJwb2xhdGlvbiBhbW91bnQsIGluIHRoZSByYW5nZSBbMC0xXSwgYmV0d2VlbiB0aGUgdHdvIGlucHV0c1xuICogQHJldHVybnMge3F1YXQyfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbGVycChvdXQsIGEsIGIsIHQpIHtcbiAgdmFyIG10ID0gMSAtIHQ7XG4gIGlmIChkb3QoYSwgYikgPCAwKSB0ID0gLXQ7XG4gIG91dFswXSA9IGFbMF0gKiBtdCArIGJbMF0gKiB0O1xuICBvdXRbMV0gPSBhWzFdICogbXQgKyBiWzFdICogdDtcbiAgb3V0WzJdID0gYVsyXSAqIG10ICsgYlsyXSAqIHQ7XG4gIG91dFszXSA9IGFbM10gKiBtdCArIGJbM10gKiB0O1xuICBvdXRbNF0gPSBhWzRdICogbXQgKyBiWzRdICogdDtcbiAgb3V0WzVdID0gYVs1XSAqIG10ICsgYls1XSAqIHQ7XG4gIG91dFs2XSA9IGFbNl0gKiBtdCArIGJbNl0gKiB0O1xuICBvdXRbN10gPSBhWzddICogbXQgKyBiWzddICogdDtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgaW52ZXJzZSBvZiBhIGR1YWwgcXVhdC4gSWYgdGhleSBhcmUgbm9ybWFsaXplZCwgY29uanVnYXRlIGlzIGNoZWFwZXJcbiAqXG4gKiBAcGFyYW0ge3F1YXQyfSBvdXQgdGhlIHJlY2VpdmluZyBkdWFsIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gYSBkdWFsIHF1YXQgdG8gY2FsY3VsYXRlIGludmVyc2Ugb2ZcbiAqIEByZXR1cm5zIHtxdWF0Mn0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGludmVydChvdXQsIGEpIHtcbiAgdmFyIHNxbGVuID0gc3F1YXJlZExlbmd0aChhKTtcbiAgb3V0WzBdID0gLWFbMF0gLyBzcWxlbjtcbiAgb3V0WzFdID0gLWFbMV0gLyBzcWxlbjtcbiAgb3V0WzJdID0gLWFbMl0gLyBzcWxlbjtcbiAgb3V0WzNdID0gYVszXSAvIHNxbGVuO1xuICBvdXRbNF0gPSAtYVs0XSAvIHNxbGVuO1xuICBvdXRbNV0gPSAtYVs1XSAvIHNxbGVuO1xuICBvdXRbNl0gPSAtYVs2XSAvIHNxbGVuO1xuICBvdXRbN10gPSBhWzddIC8gc3FsZW47XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGNvbmp1Z2F0ZSBvZiBhIGR1YWwgcXVhdFxuICogSWYgdGhlIGR1YWwgcXVhdGVybmlvbiBpcyBub3JtYWxpemVkLCB0aGlzIGZ1bmN0aW9uIGlzIGZhc3RlciB0aGFuIHF1YXQyLmludmVyc2UgYW5kIHByb2R1Y2VzIHRoZSBzYW1lIHJlc3VsdC5cbiAqXG4gKiBAcGFyYW0ge3F1YXQyfSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdDJ9IGEgcXVhdCB0byBjYWxjdWxhdGUgY29uanVnYXRlIG9mXG4gKiBAcmV0dXJucyB7cXVhdDJ9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjb25qdWdhdGUob3V0LCBhKSB7XG4gIG91dFswXSA9IC1hWzBdO1xuICBvdXRbMV0gPSAtYVsxXTtcbiAgb3V0WzJdID0gLWFbMl07XG4gIG91dFszXSA9IGFbM107XG4gIG91dFs0XSA9IC1hWzRdO1xuICBvdXRbNV0gPSAtYVs1XTtcbiAgb3V0WzZdID0gLWFbNl07XG4gIG91dFs3XSA9IGFbN107XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGxlbmd0aCBvZiBhIGR1YWwgcXVhdFxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gYSBkdWFsIHF1YXQgdG8gY2FsY3VsYXRlIGxlbmd0aCBvZlxuICogQHJldHVybnMge051bWJlcn0gbGVuZ3RoIG9mIGFcbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgbGVuZ3RoID0gcXVhdC5sZW5ndGg7XG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgcXVhdDIubGVuZ3RofVxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBsZW4gPSBsZW5ndGg7XG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIHNxdWFyZWQgbGVuZ3RoIG9mIGEgZHVhbCBxdWF0XG4gKlxuICogQHBhcmFtIHtSZWFkb25seVF1YXQyfSBhIGR1YWwgcXVhdCB0byBjYWxjdWxhdGUgc3F1YXJlZCBsZW5ndGggb2ZcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IHNxdWFyZWQgbGVuZ3RoIG9mIGFcbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgc3F1YXJlZExlbmd0aCA9IHF1YXQuc3F1YXJlZExlbmd0aDtcbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayBxdWF0Mi5zcXVhcmVkTGVuZ3RofVxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBzcXJMZW4gPSBzcXVhcmVkTGVuZ3RoO1xuLyoqXG4gKiBOb3JtYWxpemUgYSBkdWFsIHF1YXRcbiAqXG4gKiBAcGFyYW0ge3F1YXQyfSBvdXQgdGhlIHJlY2VpdmluZyBkdWFsIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gYSBkdWFsIHF1YXRlcm5pb24gdG8gbm9ybWFsaXplXG4gKiBAcmV0dXJucyB7cXVhdDJ9IG91dFxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZShvdXQsIGEpIHtcbiAgdmFyIG1hZ25pdHVkZSA9IHNxdWFyZWRMZW5ndGgoYSk7XG5cbiAgaWYgKG1hZ25pdHVkZSA+IDApIHtcbiAgICBtYWduaXR1ZGUgPSBNYXRoLnNxcnQobWFnbml0dWRlKTtcbiAgICB2YXIgYTAgPSBhWzBdIC8gbWFnbml0dWRlO1xuICAgIHZhciBhMSA9IGFbMV0gLyBtYWduaXR1ZGU7XG4gICAgdmFyIGEyID0gYVsyXSAvIG1hZ25pdHVkZTtcbiAgICB2YXIgYTMgPSBhWzNdIC8gbWFnbml0dWRlO1xuICAgIHZhciBiMCA9IGFbNF07XG4gICAgdmFyIGIxID0gYVs1XTtcbiAgICB2YXIgYjIgPSBhWzZdO1xuICAgIHZhciBiMyA9IGFbN107XG4gICAgdmFyIGFfZG90X2IgPSBhMCAqIGIwICsgYTEgKiBiMSArIGEyICogYjIgKyBhMyAqIGIzO1xuICAgIG91dFswXSA9IGEwO1xuICAgIG91dFsxXSA9IGExO1xuICAgIG91dFsyXSA9IGEyO1xuICAgIG91dFszXSA9IGEzO1xuICAgIG91dFs0XSA9IChiMCAtIGEwICogYV9kb3RfYikgLyBtYWduaXR1ZGU7XG4gICAgb3V0WzVdID0gKGIxIC0gYTEgKiBhX2RvdF9iKSAvIG1hZ25pdHVkZTtcbiAgICBvdXRbNl0gPSAoYjIgLSBhMiAqIGFfZG90X2IpIC8gbWFnbml0dWRlO1xuICAgIG91dFs3XSA9IChiMyAtIGEzICogYV9kb3RfYikgLyBtYWduaXR1ZGU7XG4gIH1cblxuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgZHVhbCBxdWF0ZW5pb25cbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdDJ9IGEgZHVhbCBxdWF0ZXJuaW9uIHRvIHJlcHJlc2VudCBhcyBhIHN0cmluZ1xuICogQHJldHVybnMge1N0cmluZ30gc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBkdWFsIHF1YXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc3RyKGEpIHtcbiAgcmV0dXJuIFwicXVhdDIoXCIgKyBhWzBdICsgXCIsIFwiICsgYVsxXSArIFwiLCBcIiArIGFbMl0gKyBcIiwgXCIgKyBhWzNdICsgXCIsIFwiICsgYVs0XSArIFwiLCBcIiArIGFbNV0gKyBcIiwgXCIgKyBhWzZdICsgXCIsIFwiICsgYVs3XSArIFwiKVwiO1xufVxuLyoqXG4gKiBSZXR1cm5zIHdoZXRoZXIgb3Igbm90IHRoZSBkdWFsIHF1YXRlcm5pb25zIGhhdmUgZXhhY3RseSB0aGUgc2FtZSBlbGVtZW50cyBpbiB0aGUgc2FtZSBwb3NpdGlvbiAod2hlbiBjb21wYXJlZCB3aXRoID09PSlcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdDJ9IGEgdGhlIGZpcnN0IGR1YWwgcXVhdGVybmlvbi5cbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gYiB0aGUgc2Vjb25kIGR1YWwgcXVhdGVybmlvbi5cbiAqIEByZXR1cm5zIHtCb29sZWFufSB0cnVlIGlmIHRoZSBkdWFsIHF1YXRlcm5pb25zIGFyZSBlcXVhbCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBleGFjdEVxdWFscyhhLCBiKSB7XG4gIHJldHVybiBhWzBdID09PSBiWzBdICYmIGFbMV0gPT09IGJbMV0gJiYgYVsyXSA9PT0gYlsyXSAmJiBhWzNdID09PSBiWzNdICYmIGFbNF0gPT09IGJbNF0gJiYgYVs1XSA9PT0gYls1XSAmJiBhWzZdID09PSBiWzZdICYmIGFbN10gPT09IGJbN107XG59XG4vKipcbiAqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhlIGR1YWwgcXVhdGVybmlvbnMgaGF2ZSBhcHByb3hpbWF0ZWx5IHRoZSBzYW1lIGVsZW1lbnRzIGluIHRoZSBzYW1lIHBvc2l0aW9uLlxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gYSB0aGUgZmlyc3QgZHVhbCBxdWF0LlxuICogQHBhcmFtIHtSZWFkb25seVF1YXQyfSBiIHRoZSBzZWNvbmQgZHVhbCBxdWF0LlxuICogQHJldHVybnMge0Jvb2xlYW59IHRydWUgaWYgdGhlIGR1YWwgcXVhdHMgYXJlIGVxdWFsLCBmYWxzZSBvdGhlcndpc2UuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGVxdWFscyhhLCBiKSB7XG4gIHZhciBhMCA9IGFbMF0sXG4gICAgICBhMSA9IGFbMV0sXG4gICAgICBhMiA9IGFbMl0sXG4gICAgICBhMyA9IGFbM10sXG4gICAgICBhNCA9IGFbNF0sXG4gICAgICBhNSA9IGFbNV0sXG4gICAgICBhNiA9IGFbNl0sXG4gICAgICBhNyA9IGFbN107XG4gIHZhciBiMCA9IGJbMF0sXG4gICAgICBiMSA9IGJbMV0sXG4gICAgICBiMiA9IGJbMl0sXG4gICAgICBiMyA9IGJbM10sXG4gICAgICBiNCA9IGJbNF0sXG4gICAgICBiNSA9IGJbNV0sXG4gICAgICBiNiA9IGJbNl0sXG4gICAgICBiNyA9IGJbN107XG4gIHJldHVybiBNYXRoLmFicyhhMCAtIGIwKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMCksIE1hdGguYWJzKGIwKSkgJiYgTWF0aC5hYnMoYTEgLSBiMSkgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTEpLCBNYXRoLmFicyhiMSkpICYmIE1hdGguYWJzKGEyIC0gYjIpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGEyKSwgTWF0aC5hYnMoYjIpKSAmJiBNYXRoLmFicyhhMyAtIGIzKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMyksIE1hdGguYWJzKGIzKSkgJiYgTWF0aC5hYnMoYTQgLSBiNCkgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTQpLCBNYXRoLmFicyhiNCkpICYmIE1hdGguYWJzKGE1IC0gYjUpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGE1KSwgTWF0aC5hYnMoYjUpKSAmJiBNYXRoLmFicyhhNiAtIGI2KSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhNiksIE1hdGguYWJzKGI2KSkgJiYgTWF0aC5hYnMoYTcgLSBiNykgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTcpLCBNYXRoLmFicyhiNykpO1xufSIsImltcG9ydCAqIGFzIGdsTWF0cml4IGZyb20gXCIuL2NvbW1vbi5qc1wiO1xuLyoqXG4gKiAyIERpbWVuc2lvbmFsIFZlY3RvclxuICogQG1vZHVsZSB2ZWMyXG4gKi9cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3LCBlbXB0eSB2ZWMyXG4gKlxuICogQHJldHVybnMge3ZlYzJ9IGEgbmV3IDJEIHZlY3RvclxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGUoKSB7XG4gIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSgyKTtcblxuICBpZiAoZ2xNYXRyaXguQVJSQVlfVFlQRSAhPSBGbG9hdDMyQXJyYXkpIHtcbiAgICBvdXRbMF0gPSAwO1xuICAgIG91dFsxXSA9IDA7XG4gIH1cblxuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHZlYzIgaW5pdGlhbGl6ZWQgd2l0aCB2YWx1ZXMgZnJvbSBhbiBleGlzdGluZyB2ZWN0b3JcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYSB2ZWN0b3IgdG8gY2xvbmVcbiAqIEByZXR1cm5zIHt2ZWMyfSBhIG5ldyAyRCB2ZWN0b3JcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY2xvbmUoYSkge1xuICB2YXIgb3V0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoMik7XG4gIG91dFswXSA9IGFbMF07XG4gIG91dFsxXSA9IGFbMV07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgdmVjMiBpbml0aWFsaXplZCB3aXRoIHRoZSBnaXZlbiB2YWx1ZXNcbiAqXG4gKiBAcGFyYW0ge051bWJlcn0geCBYIGNvbXBvbmVudFxuICogQHBhcmFtIHtOdW1iZXJ9IHkgWSBjb21wb25lbnRcbiAqIEByZXR1cm5zIHt2ZWMyfSBhIG5ldyAyRCB2ZWN0b3JcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbVZhbHVlcyh4LCB5KSB7XG4gIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSgyKTtcbiAgb3V0WzBdID0geDtcbiAgb3V0WzFdID0geTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ29weSB0aGUgdmFsdWVzIGZyb20gb25lIHZlYzIgdG8gYW5vdGhlclxuICpcbiAqIEBwYXJhbSB7dmVjMn0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYSB0aGUgc291cmNlIHZlY3RvclxuICogQHJldHVybnMge3ZlYzJ9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjb3B5KG91dCwgYSkge1xuICBvdXRbMF0gPSBhWzBdO1xuICBvdXRbMV0gPSBhWzFdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBTZXQgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWMyIHRvIHRoZSBnaXZlbiB2YWx1ZXNcbiAqXG4gKiBAcGFyYW0ge3ZlYzJ9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtOdW1iZXJ9IHggWCBjb21wb25lbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSB5IFkgY29tcG9uZW50XG4gKiBAcmV0dXJucyB7dmVjMn0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNldChvdXQsIHgsIHkpIHtcbiAgb3V0WzBdID0geDtcbiAgb3V0WzFdID0geTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQWRkcyB0d28gdmVjMidzXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHt2ZWMyfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYWRkKG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdICsgYlswXTtcbiAgb3V0WzFdID0gYVsxXSArIGJbMV07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFN1YnRyYWN0cyB2ZWN0b3IgYiBmcm9tIHZlY3RvciBhXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHt2ZWMyfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc3VidHJhY3Qob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IGFbMF0gLSBiWzBdO1xuICBvdXRbMV0gPSBhWzFdIC0gYlsxXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogTXVsdGlwbGllcyB0d28gdmVjMidzXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHt2ZWMyfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbXVsdGlwbHkob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IGFbMF0gKiBiWzBdO1xuICBvdXRbMV0gPSBhWzFdICogYlsxXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogRGl2aWRlcyB0d28gdmVjMidzXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHt2ZWMyfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZGl2aWRlKG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdIC8gYlswXTtcbiAgb3V0WzFdID0gYVsxXSAvIGJbMV07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIE1hdGguY2VpbCB0aGUgY29tcG9uZW50cyBvZiBhIHZlYzJcbiAqXG4gKiBAcGFyYW0ge3ZlYzJ9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGEgdmVjdG9yIHRvIGNlaWxcbiAqIEByZXR1cm5zIHt2ZWMyfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY2VpbChvdXQsIGEpIHtcbiAgb3V0WzBdID0gTWF0aC5jZWlsKGFbMF0pO1xuICBvdXRbMV0gPSBNYXRoLmNlaWwoYVsxXSk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIE1hdGguZmxvb3IgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWMyXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHZlY3RvciB0byBmbG9vclxuICogQHJldHVybnMge3ZlYzJ9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmbG9vcihvdXQsIGEpIHtcbiAgb3V0WzBdID0gTWF0aC5mbG9vcihhWzBdKTtcbiAgb3V0WzFdID0gTWF0aC5mbG9vcihhWzFdKTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUmV0dXJucyB0aGUgbWluaW11bSBvZiB0d28gdmVjMidzXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHt2ZWMyfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbWluKG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBNYXRoLm1pbihhWzBdLCBiWzBdKTtcbiAgb3V0WzFdID0gTWF0aC5taW4oYVsxXSwgYlsxXSk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFJldHVybnMgdGhlIG1heGltdW0gb2YgdHdvIHZlYzInc1xuICpcbiAqIEBwYXJhbSB7dmVjMn0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7dmVjMn0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG1heChvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gTWF0aC5tYXgoYVswXSwgYlswXSk7XG4gIG91dFsxXSA9IE1hdGgubWF4KGFbMV0sIGJbMV0pO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBNYXRoLnJvdW5kIHRoZSBjb21wb25lbnRzIG9mIGEgdmVjMlxuICpcbiAqIEBwYXJhbSB7dmVjMn0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYSB2ZWN0b3IgdG8gcm91bmRcbiAqIEByZXR1cm5zIHt2ZWMyfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcm91bmQob3V0LCBhKSB7XG4gIG91dFswXSA9IE1hdGgucm91bmQoYVswXSk7XG4gIG91dFsxXSA9IE1hdGgucm91bmQoYVsxXSk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFNjYWxlcyBhIHZlYzIgYnkgYSBzY2FsYXIgbnVtYmVyXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHRoZSB2ZWN0b3IgdG8gc2NhbGVcbiAqIEBwYXJhbSB7TnVtYmVyfSBiIGFtb3VudCB0byBzY2FsZSB0aGUgdmVjdG9yIGJ5XG4gKiBAcmV0dXJucyB7dmVjMn0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNjYWxlKG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdICogYjtcbiAgb3V0WzFdID0gYVsxXSAqIGI7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIEFkZHMgdHdvIHZlYzIncyBhZnRlciBzY2FsaW5nIHRoZSBzZWNvbmQgb3BlcmFuZCBieSBhIHNjYWxhciB2YWx1ZVxuICpcbiAqIEBwYXJhbSB7dmVjMn0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcGFyYW0ge051bWJlcn0gc2NhbGUgdGhlIGFtb3VudCB0byBzY2FsZSBiIGJ5IGJlZm9yZSBhZGRpbmdcbiAqIEByZXR1cm5zIHt2ZWMyfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc2NhbGVBbmRBZGQob3V0LCBhLCBiLCBzY2FsZSkge1xuICBvdXRbMF0gPSBhWzBdICsgYlswXSAqIHNjYWxlO1xuICBvdXRbMV0gPSBhWzFdICsgYlsxXSAqIHNjYWxlO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBldWNsaWRpYW4gZGlzdGFuY2UgYmV0d2VlbiB0d28gdmVjMidzXG4gKlxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge051bWJlcn0gZGlzdGFuY2UgYmV0d2VlbiBhIGFuZCBiXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGRpc3RhbmNlKGEsIGIpIHtcbiAgdmFyIHggPSBiWzBdIC0gYVswXSxcbiAgICAgIHkgPSBiWzFdIC0gYVsxXTtcbiAgcmV0dXJuIE1hdGguaHlwb3QoeCwgeSk7XG59XG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIHNxdWFyZWQgZXVjbGlkaWFuIGRpc3RhbmNlIGJldHdlZW4gdHdvIHZlYzInc1xuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IHNxdWFyZWQgZGlzdGFuY2UgYmV0d2VlbiBhIGFuZCBiXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNxdWFyZWREaXN0YW5jZShhLCBiKSB7XG4gIHZhciB4ID0gYlswXSAtIGFbMF0sXG4gICAgICB5ID0gYlsxXSAtIGFbMV07XG4gIHJldHVybiB4ICogeCArIHkgKiB5O1xufVxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBsZW5ndGggb2YgYSB2ZWMyXG4gKlxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGEgdmVjdG9yIHRvIGNhbGN1bGF0ZSBsZW5ndGggb2ZcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IGxlbmd0aCBvZiBhXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGxlbmd0aChhKSB7XG4gIHZhciB4ID0gYVswXSxcbiAgICAgIHkgPSBhWzFdO1xuICByZXR1cm4gTWF0aC5oeXBvdCh4LCB5KTtcbn1cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgc3F1YXJlZCBsZW5ndGggb2YgYSB2ZWMyXG4gKlxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGEgdmVjdG9yIHRvIGNhbGN1bGF0ZSBzcXVhcmVkIGxlbmd0aCBvZlxuICogQHJldHVybnMge051bWJlcn0gc3F1YXJlZCBsZW5ndGggb2YgYVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzcXVhcmVkTGVuZ3RoKGEpIHtcbiAgdmFyIHggPSBhWzBdLFxuICAgICAgeSA9IGFbMV07XG4gIHJldHVybiB4ICogeCArIHkgKiB5O1xufVxuLyoqXG4gKiBOZWdhdGVzIHRoZSBjb21wb25lbnRzIG9mIGEgdmVjMlxuICpcbiAqIEBwYXJhbSB7dmVjMn0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYSB2ZWN0b3IgdG8gbmVnYXRlXG4gKiBAcmV0dXJucyB7dmVjMn0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG5lZ2F0ZShvdXQsIGEpIHtcbiAgb3V0WzBdID0gLWFbMF07XG4gIG91dFsxXSA9IC1hWzFdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBSZXR1cm5zIHRoZSBpbnZlcnNlIG9mIHRoZSBjb21wb25lbnRzIG9mIGEgdmVjMlxuICpcbiAqIEBwYXJhbSB7dmVjMn0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYSB2ZWN0b3IgdG8gaW52ZXJ0XG4gKiBAcmV0dXJucyB7dmVjMn0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGludmVyc2Uob3V0LCBhKSB7XG4gIG91dFswXSA9IDEuMCAvIGFbMF07XG4gIG91dFsxXSA9IDEuMCAvIGFbMV07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIE5vcm1hbGl6ZSBhIHZlYzJcbiAqXG4gKiBAcGFyYW0ge3ZlYzJ9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGEgdmVjdG9yIHRvIG5vcm1hbGl6ZVxuICogQHJldHVybnMge3ZlYzJ9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemUob3V0LCBhKSB7XG4gIHZhciB4ID0gYVswXSxcbiAgICAgIHkgPSBhWzFdO1xuICB2YXIgbGVuID0geCAqIHggKyB5ICogeTtcblxuICBpZiAobGVuID4gMCkge1xuICAgIC8vVE9ETzogZXZhbHVhdGUgdXNlIG9mIGdsbV9pbnZzcXJ0IGhlcmU/XG4gICAgbGVuID0gMSAvIE1hdGguc3FydChsZW4pO1xuICB9XG5cbiAgb3V0WzBdID0gYVswXSAqIGxlbjtcbiAgb3V0WzFdID0gYVsxXSAqIGxlbjtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgZG90IHByb2R1Y3Qgb2YgdHdvIHZlYzInc1xuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IGRvdCBwcm9kdWN0IG9mIGEgYW5kIGJcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZG90KGEsIGIpIHtcbiAgcmV0dXJuIGFbMF0gKiBiWzBdICsgYVsxXSAqIGJbMV07XG59XG4vKipcbiAqIENvbXB1dGVzIHRoZSBjcm9zcyBwcm9kdWN0IG9mIHR3byB2ZWMyJ3NcbiAqIE5vdGUgdGhhdCB0aGUgY3Jvc3MgcHJvZHVjdCBtdXN0IGJ5IGRlZmluaXRpb24gcHJvZHVjZSBhIDNEIHZlY3RvclxuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyb3NzKG91dCwgYSwgYikge1xuICB2YXIgeiA9IGFbMF0gKiBiWzFdIC0gYVsxXSAqIGJbMF07XG4gIG91dFswXSA9IG91dFsxXSA9IDA7XG4gIG91dFsyXSA9IHo7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFBlcmZvcm1zIGEgbGluZWFyIGludGVycG9sYXRpb24gYmV0d2VlbiB0d28gdmVjMidzXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEBwYXJhbSB7TnVtYmVyfSB0IGludGVycG9sYXRpb24gYW1vdW50LCBpbiB0aGUgcmFuZ2UgWzAtMV0sIGJldHdlZW4gdGhlIHR3byBpbnB1dHNcbiAqIEByZXR1cm5zIHt2ZWMyfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbGVycChvdXQsIGEsIGIsIHQpIHtcbiAgdmFyIGF4ID0gYVswXSxcbiAgICAgIGF5ID0gYVsxXTtcbiAgb3V0WzBdID0gYXggKyB0ICogKGJbMF0gLSBheCk7XG4gIG91dFsxXSA9IGF5ICsgdCAqIChiWzFdIC0gYXkpO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBHZW5lcmF0ZXMgYSByYW5kb20gdmVjdG9yIHdpdGggdGhlIGdpdmVuIHNjYWxlXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7TnVtYmVyfSBbc2NhbGVdIExlbmd0aCBvZiB0aGUgcmVzdWx0aW5nIHZlY3Rvci4gSWYgb21taXR0ZWQsIGEgdW5pdCB2ZWN0b3Igd2lsbCBiZSByZXR1cm5lZFxuICogQHJldHVybnMge3ZlYzJ9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByYW5kb20ob3V0LCBzY2FsZSkge1xuICBzY2FsZSA9IHNjYWxlIHx8IDEuMDtcbiAgdmFyIHIgPSBnbE1hdHJpeC5SQU5ET00oKSAqIDIuMCAqIE1hdGguUEk7XG4gIG91dFswXSA9IE1hdGguY29zKHIpICogc2NhbGU7XG4gIG91dFsxXSA9IE1hdGguc2luKHIpICogc2NhbGU7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFRyYW5zZm9ybXMgdGhlIHZlYzIgd2l0aCBhIG1hdDJcbiAqXG4gKiBAcGFyYW0ge3ZlYzJ9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGEgdGhlIHZlY3RvciB0byB0cmFuc2Zvcm1cbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyfSBtIG1hdHJpeCB0byB0cmFuc2Zvcm0gd2l0aFxuICogQHJldHVybnMge3ZlYzJ9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2Zvcm1NYXQyKG91dCwgYSwgbSkge1xuICB2YXIgeCA9IGFbMF0sXG4gICAgICB5ID0gYVsxXTtcbiAgb3V0WzBdID0gbVswXSAqIHggKyBtWzJdICogeTtcbiAgb3V0WzFdID0gbVsxXSAqIHggKyBtWzNdICogeTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogVHJhbnNmb3JtcyB0aGUgdmVjMiB3aXRoIGEgbWF0MmRcbiAqXG4gKiBAcGFyYW0ge3ZlYzJ9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGEgdGhlIHZlY3RvciB0byB0cmFuc2Zvcm1cbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyZH0gbSBtYXRyaXggdG8gdHJhbnNmb3JtIHdpdGhcbiAqIEByZXR1cm5zIHt2ZWMyfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNmb3JtTWF0MmQob3V0LCBhLCBtKSB7XG4gIHZhciB4ID0gYVswXSxcbiAgICAgIHkgPSBhWzFdO1xuICBvdXRbMF0gPSBtWzBdICogeCArIG1bMl0gKiB5ICsgbVs0XTtcbiAgb3V0WzFdID0gbVsxXSAqIHggKyBtWzNdICogeSArIG1bNV07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFRyYW5zZm9ybXMgdGhlIHZlYzIgd2l0aCBhIG1hdDNcbiAqIDNyZCB2ZWN0b3IgY29tcG9uZW50IGlzIGltcGxpY2l0bHkgJzEnXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHRoZSB2ZWN0b3IgdG8gdHJhbnNmb3JtXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gbSBtYXRyaXggdG8gdHJhbnNmb3JtIHdpdGhcbiAqIEByZXR1cm5zIHt2ZWMyfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNmb3JtTWF0MyhvdXQsIGEsIG0pIHtcbiAgdmFyIHggPSBhWzBdLFxuICAgICAgeSA9IGFbMV07XG4gIG91dFswXSA9IG1bMF0gKiB4ICsgbVszXSAqIHkgKyBtWzZdO1xuICBvdXRbMV0gPSBtWzFdICogeCArIG1bNF0gKiB5ICsgbVs3XTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogVHJhbnNmb3JtcyB0aGUgdmVjMiB3aXRoIGEgbWF0NFxuICogM3JkIHZlY3RvciBjb21wb25lbnQgaXMgaW1wbGljaXRseSAnMCdcbiAqIDR0aCB2ZWN0b3IgY29tcG9uZW50IGlzIGltcGxpY2l0bHkgJzEnXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHRoZSB2ZWN0b3IgdG8gdHJhbnNmb3JtXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gbSBtYXRyaXggdG8gdHJhbnNmb3JtIHdpdGhcbiAqIEByZXR1cm5zIHt2ZWMyfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNmb3JtTWF0NChvdXQsIGEsIG0pIHtcbiAgdmFyIHggPSBhWzBdO1xuICB2YXIgeSA9IGFbMV07XG4gIG91dFswXSA9IG1bMF0gKiB4ICsgbVs0XSAqIHkgKyBtWzEyXTtcbiAgb3V0WzFdID0gbVsxXSAqIHggKyBtWzVdICogeSArIG1bMTNdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBSb3RhdGUgYSAyRCB2ZWN0b3JcbiAqIEBwYXJhbSB7dmVjMn0gb3V0IFRoZSByZWNlaXZpbmcgdmVjMlxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGEgVGhlIHZlYzIgcG9pbnQgdG8gcm90YXRlXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYiBUaGUgb3JpZ2luIG9mIHRoZSByb3RhdGlvblxuICogQHBhcmFtIHtOdW1iZXJ9IHJhZCBUaGUgYW5nbGUgb2Ygcm90YXRpb24gaW4gcmFkaWFuc1xuICogQHJldHVybnMge3ZlYzJ9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByb3RhdGUob3V0LCBhLCBiLCByYWQpIHtcbiAgLy9UcmFuc2xhdGUgcG9pbnQgdG8gdGhlIG9yaWdpblxuICB2YXIgcDAgPSBhWzBdIC0gYlswXSxcbiAgICAgIHAxID0gYVsxXSAtIGJbMV0sXG4gICAgICBzaW5DID0gTWF0aC5zaW4ocmFkKSxcbiAgICAgIGNvc0MgPSBNYXRoLmNvcyhyYWQpOyAvL3BlcmZvcm0gcm90YXRpb24gYW5kIHRyYW5zbGF0ZSB0byBjb3JyZWN0IHBvc2l0aW9uXG5cbiAgb3V0WzBdID0gcDAgKiBjb3NDIC0gcDEgKiBzaW5DICsgYlswXTtcbiAgb3V0WzFdID0gcDAgKiBzaW5DICsgcDEgKiBjb3NDICsgYlsxXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogR2V0IHRoZSBhbmdsZSBiZXR3ZWVuIHR3byAyRCB2ZWN0b3JzXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYSBUaGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGIgVGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBUaGUgYW5nbGUgaW4gcmFkaWFuc1xuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhbmdsZShhLCBiKSB7XG4gIHZhciB4MSA9IGFbMF0sXG4gICAgICB5MSA9IGFbMV0sXG4gICAgICB4MiA9IGJbMF0sXG4gICAgICB5MiA9IGJbMV0sXG4gICAgICAvLyBtYWcgaXMgdGhlIHByb2R1Y3Qgb2YgdGhlIG1hZ25pdHVkZXMgb2YgYSBhbmQgYlxuICBtYWcgPSBNYXRoLnNxcnQoeDEgKiB4MSArIHkxICogeTEpICogTWF0aC5zcXJ0KHgyICogeDIgKyB5MiAqIHkyKSxcbiAgICAgIC8vIG1hZyAmJi4uIHNob3J0IGNpcmN1aXRzIGlmIG1hZyA9PSAwXG4gIGNvc2luZSA9IG1hZyAmJiAoeDEgKiB4MiArIHkxICogeTIpIC8gbWFnOyAvLyBNYXRoLm1pbihNYXRoLm1heChjb3NpbmUsIC0xKSwgMSkgY2xhbXBzIHRoZSBjb3NpbmUgYmV0d2VlbiAtMSBhbmQgMVxuXG4gIHJldHVybiBNYXRoLmFjb3MoTWF0aC5taW4oTWF0aC5tYXgoY29zaW5lLCAtMSksIDEpKTtcbn1cbi8qKlxuICogU2V0IHRoZSBjb21wb25lbnRzIG9mIGEgdmVjMiB0byB6ZXJvXG4gKlxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEByZXR1cm5zIHt2ZWMyfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gemVybyhvdXQpIHtcbiAgb3V0WzBdID0gMC4wO1xuICBvdXRbMV0gPSAwLjA7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSB2ZWN0b3JcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYSB2ZWN0b3IgdG8gcmVwcmVzZW50IGFzIGEgc3RyaW5nXG4gKiBAcmV0dXJucyB7U3RyaW5nfSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHZlY3RvclxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzdHIoYSkge1xuICByZXR1cm4gXCJ2ZWMyKFwiICsgYVswXSArIFwiLCBcIiArIGFbMV0gKyBcIilcIjtcbn1cbi8qKlxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgdmVjdG9ycyBleGFjdGx5IGhhdmUgdGhlIHNhbWUgZWxlbWVudHMgaW4gdGhlIHNhbWUgcG9zaXRpb24gKHdoZW4gY29tcGFyZWQgd2l0aCA9PT0pXG4gKlxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGEgVGhlIGZpcnN0IHZlY3Rvci5cbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBiIFRoZSBzZWNvbmQgdmVjdG9yLlxuICogQHJldHVybnMge0Jvb2xlYW59IFRydWUgaWYgdGhlIHZlY3RvcnMgYXJlIGVxdWFsLCBmYWxzZSBvdGhlcndpc2UuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGV4YWN0RXF1YWxzKGEsIGIpIHtcbiAgcmV0dXJuIGFbMF0gPT09IGJbMF0gJiYgYVsxXSA9PT0gYlsxXTtcbn1cbi8qKlxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgdmVjdG9ycyBoYXZlIGFwcHJveGltYXRlbHkgdGhlIHNhbWUgZWxlbWVudHMgaW4gdGhlIHNhbWUgcG9zaXRpb24uXG4gKlxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGEgVGhlIGZpcnN0IHZlY3Rvci5cbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBiIFRoZSBzZWNvbmQgdmVjdG9yLlxuICogQHJldHVybnMge0Jvb2xlYW59IFRydWUgaWYgdGhlIHZlY3RvcnMgYXJlIGVxdWFsLCBmYWxzZSBvdGhlcndpc2UuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGVxdWFscyhhLCBiKSB7XG4gIHZhciBhMCA9IGFbMF0sXG4gICAgICBhMSA9IGFbMV07XG4gIHZhciBiMCA9IGJbMF0sXG4gICAgICBiMSA9IGJbMV07XG4gIHJldHVybiBNYXRoLmFicyhhMCAtIGIwKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMCksIE1hdGguYWJzKGIwKSkgJiYgTWF0aC5hYnMoYTEgLSBiMSkgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTEpLCBNYXRoLmFicyhiMSkpO1xufVxuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHZlYzIubGVuZ3RofVxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBsZW4gPSBsZW5ndGg7XG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjMi5zdWJ0cmFjdH1cbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgc3ViID0gc3VidHJhY3Q7XG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjMi5tdWx0aXBseX1cbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgbXVsID0gbXVsdGlwbHk7XG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjMi5kaXZpZGV9XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIGRpdiA9IGRpdmlkZTtcbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayB2ZWMyLmRpc3RhbmNlfVxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBkaXN0ID0gZGlzdGFuY2U7XG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjMi5zcXVhcmVkRGlzdGFuY2V9XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIHNxckRpc3QgPSBzcXVhcmVkRGlzdGFuY2U7XG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjMi5zcXVhcmVkTGVuZ3RofVxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBzcXJMZW4gPSBzcXVhcmVkTGVuZ3RoO1xuLyoqXG4gKiBQZXJmb3JtIHNvbWUgb3BlcmF0aW9uIG92ZXIgYW4gYXJyYXkgb2YgdmVjMnMuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gYSB0aGUgYXJyYXkgb2YgdmVjdG9ycyB0byBpdGVyYXRlIG92ZXJcbiAqIEBwYXJhbSB7TnVtYmVyfSBzdHJpZGUgTnVtYmVyIG9mIGVsZW1lbnRzIGJldHdlZW4gdGhlIHN0YXJ0IG9mIGVhY2ggdmVjMi4gSWYgMCBhc3N1bWVzIHRpZ2h0bHkgcGFja2VkXG4gKiBAcGFyYW0ge051bWJlcn0gb2Zmc2V0IE51bWJlciBvZiBlbGVtZW50cyB0byBza2lwIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGFycmF5XG4gKiBAcGFyYW0ge051bWJlcn0gY291bnQgTnVtYmVyIG9mIHZlYzJzIHRvIGl0ZXJhdGUgb3Zlci4gSWYgMCBpdGVyYXRlcyBvdmVyIGVudGlyZSBhcnJheVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gRnVuY3Rpb24gdG8gY2FsbCBmb3IgZWFjaCB2ZWN0b3IgaW4gdGhlIGFycmF5XG4gKiBAcGFyYW0ge09iamVjdH0gW2FyZ10gYWRkaXRpb25hbCBhcmd1bWVudCB0byBwYXNzIHRvIGZuXG4gKiBAcmV0dXJucyB7QXJyYXl9IGFcbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgZm9yRWFjaCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHZlYyA9IGNyZWF0ZSgpO1xuICByZXR1cm4gZnVuY3Rpb24gKGEsIHN0cmlkZSwgb2Zmc2V0LCBjb3VudCwgZm4sIGFyZykge1xuICAgIHZhciBpLCBsO1xuXG4gICAgaWYgKCFzdHJpZGUpIHtcbiAgICAgIHN0cmlkZSA9IDI7XG4gICAgfVxuXG4gICAgaWYgKCFvZmZzZXQpIHtcbiAgICAgIG9mZnNldCA9IDA7XG4gICAgfVxuXG4gICAgaWYgKGNvdW50KSB7XG4gICAgICBsID0gTWF0aC5taW4oY291bnQgKiBzdHJpZGUgKyBvZmZzZXQsIGEubGVuZ3RoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbCA9IGEubGVuZ3RoO1xuICAgIH1cblxuICAgIGZvciAoaSA9IG9mZnNldDsgaSA8IGw7IGkgKz0gc3RyaWRlKSB7XG4gICAgICB2ZWNbMF0gPSBhW2ldO1xuICAgICAgdmVjWzFdID0gYVtpICsgMV07XG4gICAgICBmbih2ZWMsIHZlYywgYXJnKTtcbiAgICAgIGFbaV0gPSB2ZWNbMF07XG4gICAgICBhW2kgKyAxXSA9IHZlY1sxXTtcbiAgICB9XG5cbiAgICByZXR1cm4gYTtcbiAgfTtcbn0oKTsiLCIvLyBAZmxvd1xuaW1wb3J0IHtjcmVhdGVMYXlvdXR9IGZyb20gJy4uL3V0aWwvc3RydWN0X2FycmF5LmpzJztcblxuaW1wb3J0IHR5cGUge1N0cnVjdEFycmF5TGF5b3V0fSBmcm9tICcuLi91dGlsL3N0cnVjdF9hcnJheS5qcyc7XG5cbmNvbnN0IGxheW91dDogU3RydWN0QXJyYXlMYXlvdXQgPSBjcmVhdGVMYXlvdXQoW1xuICAgIHt0eXBlOiAnRmxvYXQzMicsIG5hbWU6ICdhX2dsb2JlX3BvcycsIGNvbXBvbmVudHM6IDN9LFxuICAgIHt0eXBlOiAnRmxvYXQzMicsIG5hbWU6ICdhX3V2JywgY29tcG9uZW50czogMn1cbl0pO1xuXG5leHBvcnQgZGVmYXVsdCBsYXlvdXQ7XG5leHBvcnQgY29uc3Qge21lbWJlcnMsIHNpemUsIGFsaWdubWVudH0gPSBsYXlvdXQ7XG4iLCIvLyBAZmxvd1xuaW1wb3J0IHtjcmVhdGVMYXlvdXR9IGZyb20gJy4uL3V0aWwvc3RydWN0X2FycmF5LmpzJztcblxuaW1wb3J0IHR5cGUge1N0cnVjdEFycmF5TGF5b3V0fSBmcm9tICcuLi91dGlsL3N0cnVjdF9hcnJheS5qcyc7XG5cbmV4cG9ydCBjb25zdCBwb3NBdHRyaWJ1dGVzR2xvYmVFeHQ6IFN0cnVjdEFycmF5TGF5b3V0ID0gY3JlYXRlTGF5b3V0KFtcbiAgICB7bmFtZTogJ2FfcG9zXzMnLCBjb21wb25lbnRzOiAzLCB0eXBlOiAnSW50MTYnfSxcbl0pO1xuXG5leHBvcnQgZGVmYXVsdCAoY3JlYXRlTGF5b3V0KFtcbiAgICB7bmFtZTogJ2FfcG9zJywgdHlwZTogJ0ludDE2JywgY29tcG9uZW50czogMn1cbl0pOiBTdHJ1Y3RBcnJheUxheW91dCk7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge3ZlYzMsIHZlYzR9IGZyb20gJ2dsLW1hdHJpeCc7XG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbmltcG9ydCB0eXBlIHtWZWMzLCBNYXQ0fSBmcm9tICdnbC1tYXRyaXgnO1xuXG5jbGFzcyBSYXkge1xuICAgIHBvczogVmVjMztcbiAgICBkaXI6IFZlYzM7XG5cbiAgICBjb25zdHJ1Y3Rvcihwb3NfOiBWZWMzLCBkaXJfOiBWZWMzKSB7XG4gICAgICAgIHRoaXMucG9zID0gcG9zXztcbiAgICAgICAgdGhpcy5kaXIgPSBkaXJfO1xuICAgIH1cblxuICAgIGludGVyc2VjdHNQbGFuZShwdDogVmVjMywgbm9ybWFsOiBWZWMzLCBvdXQ6IFZlYzMpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgRCA9IHZlYzMuZG90KG5vcm1hbCwgdGhpcy5kaXIpO1xuXG4gICAgICAgIC8vIHJheSBpcyBwYXJhbGxlbCB0byBwbGFuZSwgc28gaXQgbWlzc2VzXG4gICAgICAgIGlmIChNYXRoLmFicyhEKSA8IDFlLTYpIHsgcmV0dXJuIGZhbHNlOyB9XG5cbiAgICAgICAgY29uc3QgdCA9IChcbiAgICAgICAgICAgIChwdFswXSAtIHRoaXMucG9zWzBdKSAqIG5vcm1hbFswXSArXG4gICAgICAgICAgICAocHRbMV0gLSB0aGlzLnBvc1sxXSkgKiBub3JtYWxbMV0gK1xuICAgICAgICAgICAgKHB0WzJdIC0gdGhpcy5wb3NbMl0pICogbm9ybWFsWzJdKSAvIEQ7XG5cbiAgICAgICAgb3V0WzBdID0gdGhpcy5wb3NbMF0gKyB0aGlzLmRpclswXSAqIHQ7XG4gICAgICAgIG91dFsxXSA9IHRoaXMucG9zWzFdICsgdGhpcy5kaXJbMV0gKiB0O1xuICAgICAgICBvdXRbMl0gPSB0aGlzLnBvc1syXSArIHRoaXMuZGlyWzJdICogdDtcblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBjbG9zZXN0UG9pbnRPblNwaGVyZShjZW50ZXI6IFZlYzMsIHI6IG51bWJlciwgb3V0OiBWZWMzKTogYm9vbGVhbiB7XG4gICAgICAgIGFzc2VydCh2ZWMzLnNxdWFyZWRMZW5ndGgodGhpcy5kaXIpID4gMC4wICYmIHIgPj0gMC4wKTtcblxuICAgICAgICBpZiAodmVjMy5lcXVhbHModGhpcy5wb3MsIGNlbnRlcikgfHwgciA9PT0gMC4wKSB7XG4gICAgICAgICAgICBvdXRbMF0gPSBvdXRbMV0gPSBvdXRbMl0gPSAwO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgW2R4LCBkeSwgZHpdID0gdGhpcy5kaXI7XG5cbiAgICAgICAgY29uc3QgcHggPSB0aGlzLnBvc1swXSAtIGNlbnRlclswXTtcbiAgICAgICAgY29uc3QgcHkgPSB0aGlzLnBvc1sxXSAtIGNlbnRlclsxXTtcbiAgICAgICAgY29uc3QgcHogPSB0aGlzLnBvc1syXSAtIGNlbnRlclsyXTtcblxuICAgICAgICBjb25zdCBhID0gZHggKiBkeCArIGR5ICogZHkgKyBkeiAqIGR6O1xuICAgICAgICBjb25zdCBiID0gMi4wICogKHB4ICogZHggKyBweSAqIGR5ICsgcHogKiBkeik7XG4gICAgICAgIGNvbnN0IGMgPSAocHggKiBweCArIHB5ICogcHkgKyBweiAqIHB6KSAtIHIgKiByO1xuICAgICAgICBjb25zdCBkID0gYiAqIGIgLSA0ICogYSAqIGM7XG5cbiAgICAgICAgaWYgKGQgPCAwLjApIHtcbiAgICAgICAgICAgIC8vIE5vIGludGVyc2VjdGlvbiwgZmluZCBkaXN0YW5jZSBiZXR3ZWVuIGNsb3Nlc3QgcG9pbnRzXG4gICAgICAgICAgICBjb25zdCB0ID0gTWF0aC5tYXgoLWIgLyAyLCAwLjApO1xuICAgICAgICAgICAgY29uc3QgZ3ggPSBweCArIGR4ICogdDsgLy8gcG9pbnQgdG8gZ2xvYmVcbiAgICAgICAgICAgIGNvbnN0IGd5ID0gcHkgKyBkeSAqIHQ7XG4gICAgICAgICAgICBjb25zdCBneiA9IHB6ICsgZHogKiB0O1xuICAgICAgICAgICAgY29uc3QgZ2xlbiA9IE1hdGguaHlwb3QoZ3gsIGd5LCBneik7XG4gICAgICAgICAgICBvdXRbMF0gPSBneCAqIHIgLyBnbGVuO1xuICAgICAgICAgICAgb3V0WzFdID0gZ3kgKiByIC8gZ2xlbjtcbiAgICAgICAgICAgIG91dFsyXSA9IGd6ICogciAvIGdsZW47XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFzc2VydChhID4gMC4wKTtcbiAgICAgICAgICAgIGNvbnN0IHQgPSAoLWIgLSBNYXRoLnNxcnQoZCkpIC8gKDIuMCAqIGEpO1xuXG4gICAgICAgICAgICBpZiAodCA8IDAuMCkge1xuICAgICAgICAgICAgICAgIC8vIFJheSBpcyBwb2ludGluZyBhd2F5IGZyb20gdGhlIHNwaGVyZVxuICAgICAgICAgICAgICAgIGNvbnN0IHBsZW4gPSBNYXRoLmh5cG90KHB4LCBweSwgcHopO1xuICAgICAgICAgICAgICAgIG91dFswXSA9IHB4ICogciAvIHBsZW47XG4gICAgICAgICAgICAgICAgb3V0WzFdID0gcHkgKiByIC8gcGxlbjtcbiAgICAgICAgICAgICAgICBvdXRbMl0gPSBweiAqIHIgLyBwbGVuO1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcblxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBvdXRbMF0gPSBweCArIGR4ICogdDtcbiAgICAgICAgICAgICAgICBvdXRbMV0gPSBweSArIGR5ICogdDtcbiAgICAgICAgICAgICAgICBvdXRbMl0gPSBweiArIGR6ICogdDtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuY2xhc3MgRnJ1c3R1bUNvcm5lcnMge1xuICAgIFRMOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gICAgVFI6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbiAgICBCUjogW251bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICAgIEJMOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gICAgaG9yaXpvbjogbnVtYmVyO1xuXG4gICAgY29uc3RydWN0b3IoVExfOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sIFRSXzogW251bWJlciwgbnVtYmVyLCBudW1iZXJdLCBCUl86IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSwgQkxfOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sIGhvcml6b25fOiBudW1iZXIpIHtcbiAgICAgICAgdGhpcy5UTCA9IFRMXztcbiAgICAgICAgdGhpcy5UUiA9IFRSXztcbiAgICAgICAgdGhpcy5CUiA9IEJSXztcbiAgICAgICAgdGhpcy5CTCA9IEJMXztcbiAgICAgICAgdGhpcy5ob3Jpem9uID0gaG9yaXpvbl87XG4gICAgfVxuXG4gICAgc3RhdGljIGZyb21JbnZQcm9qZWN0aW9uTWF0cml4KGludlByb2o6IEFycmF5PG51bWJlcj4sIGhvcml6b25Gcm9tVG9wOiBudW1iZXIsIHZpZXdwb3J0SGVpZ2h0OiBudW1iZXIpOiBGcnVzdHVtQ29ybmVycyB7XG4gICAgICAgIGNvbnN0IFRMQ2xpcCA9IFstMSwgMSwgMV07XG4gICAgICAgIGNvbnN0IFRSQ2xpcCA9IFsxLCAxLCAxXTtcbiAgICAgICAgY29uc3QgQlJDbGlwID0gWzEsIC0xLCAxXTtcbiAgICAgICAgY29uc3QgQkxDbGlwID0gWy0xLCAtMSwgMV07XG5cbiAgICAgICAgY29uc3QgVEwgPSB2ZWMzLnRyYW5zZm9ybU1hdDQoVExDbGlwLCBUTENsaXAsIGludlByb2opO1xuICAgICAgICBjb25zdCBUUiA9IHZlYzMudHJhbnNmb3JtTWF0NChUUkNsaXAsIFRSQ2xpcCwgaW52UHJvaik7XG4gICAgICAgIGNvbnN0IEJSID0gdmVjMy50cmFuc2Zvcm1NYXQ0KEJSQ2xpcCwgQlJDbGlwLCBpbnZQcm9qKTtcbiAgICAgICAgY29uc3QgQkwgPSB2ZWMzLnRyYW5zZm9ybU1hdDQoQkxDbGlwLCBCTENsaXAsIGludlByb2opO1xuXG4gICAgICAgIHJldHVybiBuZXcgRnJ1c3R1bUNvcm5lcnMoVEwsIFRSLCBCUiwgQkwsIGhvcml6b25Gcm9tVG9wIC8gdmlld3BvcnRIZWlnaHQpO1xuICAgIH1cbn1cblxuY2xhc3MgRnJ1c3R1bSB7XG4gICAgcG9pbnRzOiBBcnJheTxBcnJheTxudW1iZXI+PjtcbiAgICBwbGFuZXM6IEFycmF5PEFycmF5PG51bWJlcj4+O1xuXG4gICAgY29uc3RydWN0b3IocG9pbnRzXzogQXJyYXk8QXJyYXk8bnVtYmVyPj4sIHBsYW5lc186IEFycmF5PEFycmF5PG51bWJlcj4+KSB7XG4gICAgICAgIHRoaXMucG9pbnRzID0gcG9pbnRzXztcbiAgICAgICAgdGhpcy5wbGFuZXMgPSBwbGFuZXNfO1xuICAgIH1cblxuICAgIHN0YXRpYyBmcm9tSW52UHJvamVjdGlvbk1hdHJpeChpbnZQcm9qOiBGbG9hdDY0QXJyYXksIHdvcmxkU2l6ZTogbnVtYmVyLCB6b29tOiBudW1iZXIsIHpJbk1ldGVyczogYm9vbGVhbik6IEZydXN0dW0ge1xuICAgICAgICBjb25zdCBjbGlwU3BhY2VDb3JuZXJzID0gW1xuICAgICAgICAgICAgWy0xLCAxLCAtMSwgMV0sXG4gICAgICAgICAgICBbIDEsIDEsIC0xLCAxXSxcbiAgICAgICAgICAgIFsgMSwgLTEsIC0xLCAxXSxcbiAgICAgICAgICAgIFstMSwgLTEsIC0xLCAxXSxcbiAgICAgICAgICAgIFstMSwgMSwgMSwgMV0sXG4gICAgICAgICAgICBbIDEsIDEsIDEsIDFdLFxuICAgICAgICAgICAgWyAxLCAtMSwgMSwgMV0sXG4gICAgICAgICAgICBbLTEsIC0xLCAxLCAxXVxuICAgICAgICBdO1xuXG4gICAgICAgIGNvbnN0IHNjYWxlID0gTWF0aC5wb3coMiwgem9vbSk7XG5cbiAgICAgICAgLy8gVHJhbnNmb3JtIGZydXN0dW0gY29ybmVyIHBvaW50cyBmcm9tIGNsaXAgc3BhY2UgdG8gdGlsZSBzcGFjZVxuICAgICAgICBjb25zdCBmcnVzdHVtQ29vcmRzID0gY2xpcFNwYWNlQ29ybmVyc1xuICAgICAgICAgICAgLm1hcCh2ID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBzID0gdmVjNC50cmFuc2Zvcm1NYXQ0KFtdLCB2LCBpbnZQcm9qKTtcbiAgICAgICAgICAgICAgICBjb25zdCBrID0gMS4wIC8gc1szXSAvIHdvcmxkU2l6ZSAqIHNjYWxlO1xuICAgICAgICAgICAgICAgIC8vIFogc2NhbGUgaW4gbWV0ZXJzLlxuICAgICAgICAgICAgICAgIHJldHVybiB2ZWM0Lm11bChzLCBzLCBbaywgaywgekluTWV0ZXJzID8gMS4wIC8gc1szXSA6IGssIGtdKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGZydXN0dW1QbGFuZVBvaW50SW5kaWNlcyA9IFtcbiAgICAgICAgICAgIFswLCAxLCAyXSwgIC8vIG5lYXJcbiAgICAgICAgICAgIFs2LCA1LCA0XSwgIC8vIGZhclxuICAgICAgICAgICAgWzAsIDMsIDddLCAgLy8gbGVmdFxuICAgICAgICAgICAgWzIsIDEsIDVdLCAgLy8gcmlnaHRcbiAgICAgICAgICAgIFszLCAyLCA2XSwgIC8vIGJvdHRvbVxuICAgICAgICAgICAgWzAsIDQsIDVdICAgLy8gdG9wXG4gICAgICAgIF07XG5cbiAgICAgICAgY29uc3QgZnJ1c3R1bVBsYW5lcyA9IGZydXN0dW1QbGFuZVBvaW50SW5kaWNlcy5tYXAoKHA6IEFycmF5PG51bWJlcj4pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGEgPSB2ZWMzLnN1YihbXSwgZnJ1c3R1bUNvb3Jkc1twWzBdXSwgZnJ1c3R1bUNvb3Jkc1twWzFdXSk7XG4gICAgICAgICAgICBjb25zdCBiID0gdmVjMy5zdWIoW10sIGZydXN0dW1Db29yZHNbcFsyXV0sIGZydXN0dW1Db29yZHNbcFsxXV0pO1xuICAgICAgICAgICAgY29uc3QgbiA9IHZlYzMubm9ybWFsaXplKFtdLCB2ZWMzLmNyb3NzKFtdLCBhLCBiKSk7XG4gICAgICAgICAgICBjb25zdCBkID0gLXZlYzMuZG90KG4sIGZydXN0dW1Db29yZHNbcFsxXV0pO1xuICAgICAgICAgICAgcmV0dXJuIG4uY29uY2F0KGQpO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gbmV3IEZydXN0dW0oZnJ1c3R1bUNvb3JkcywgZnJ1c3R1bVBsYW5lcyk7XG4gICAgfVxufVxuXG5jbGFzcyBBYWJiIHtcbiAgICBtaW46IFZlYzM7XG4gICAgbWF4OiBWZWMzO1xuICAgIGNlbnRlcjogVmVjMztcblxuICAgIHN0YXRpYyBmcm9tUG9pbnRzKHBvaW50czogQXJyYXk8VmVjMz4pOiBBYWJiIHtcbiAgICAgICAgY29uc3QgbWluID0gW0luZmluaXR5LCBJbmZpbml0eSwgSW5maW5pdHldO1xuICAgICAgICBjb25zdCBtYXggPSBbLUluZmluaXR5LCAtSW5maW5pdHksIC1JbmZpbml0eV07XG5cbiAgICAgICAgZm9yIChjb25zdCBwIG9mIHBvaW50cykge1xuICAgICAgICAgICAgdmVjMy5taW4obWluLCBtaW4sIHApO1xuICAgICAgICAgICAgdmVjMy5tYXgobWF4LCBtYXgsIHApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBBYWJiKG1pbiwgbWF4KTtcbiAgICB9XG5cbiAgICBzdGF0aWMgYXBwbHlUcmFuc2Zvcm0oYWFiYjogQWFiYiwgdHJhbnNmb3JtOiBNYXQ0KTogQWFiYiB7XG4gICAgICAgIGNvbnN0IGNvcm5lcnMgPSBhYWJiLmdldENvcm5lcnMoKTtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvcm5lcnMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIHZlYzMudHJhbnNmb3JtTWF0NChjb3JuZXJzW2ldLCBjb3JuZXJzW2ldLCB0cmFuc2Zvcm0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBBYWJiLmZyb21Qb2ludHMoY29ybmVycyk7XG4gICAgfVxuXG4gICAgY29uc3RydWN0b3IobWluXzogVmVjMywgbWF4XzogVmVjMykge1xuICAgICAgICB0aGlzLm1pbiA9IG1pbl87XG4gICAgICAgIHRoaXMubWF4ID0gbWF4XztcbiAgICAgICAgdGhpcy5jZW50ZXIgPSB2ZWMzLnNjYWxlKFtdLCB2ZWMzLmFkZChbXSwgdGhpcy5taW4sIHRoaXMubWF4KSwgMC41KTtcbiAgICB9XG5cbiAgICBxdWFkcmFudChpbmRleDogbnVtYmVyKTogQWFiYiB7XG4gICAgICAgIGNvbnN0IHNwbGl0ID0gWyhpbmRleCAlIDIpID09PSAwLCBpbmRleCA8IDJdO1xuICAgICAgICBjb25zdCBxTWluID0gdmVjMy5jbG9uZSh0aGlzLm1pbik7XG4gICAgICAgIGNvbnN0IHFNYXggPSB2ZWMzLmNsb25lKHRoaXMubWF4KTtcbiAgICAgICAgZm9yIChsZXQgYXhpcyA9IDA7IGF4aXMgPCBzcGxpdC5sZW5ndGg7IGF4aXMrKykge1xuICAgICAgICAgICAgcU1pbltheGlzXSA9IHNwbGl0W2F4aXNdID8gdGhpcy5taW5bYXhpc10gOiB0aGlzLmNlbnRlcltheGlzXTtcbiAgICAgICAgICAgIHFNYXhbYXhpc10gPSBzcGxpdFtheGlzXSA/IHRoaXMuY2VudGVyW2F4aXNdIDogdGhpcy5tYXhbYXhpc107XG4gICAgICAgIH1cbiAgICAgICAgLy8gVGVtcG9yYXJpbHksIGVsZXZhdGlvbiBpcyBjb25zdGFudCwgaGVuY2UgcXVhZHJhbnQubWF4LnogPSB0aGlzLm1heC56XG4gICAgICAgIHFNYXhbMl0gPSB0aGlzLm1heFsyXTtcbiAgICAgICAgcmV0dXJuIG5ldyBBYWJiKHFNaW4sIHFNYXgpO1xuICAgIH1cblxuICAgIGRpc3RhbmNlWChwb2ludDogQXJyYXk8bnVtYmVyPik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IHBvaW50T25BYWJiID0gTWF0aC5tYXgoTWF0aC5taW4odGhpcy5tYXhbMF0sIHBvaW50WzBdKSwgdGhpcy5taW5bMF0pO1xuICAgICAgICByZXR1cm4gcG9pbnRPbkFhYmIgLSBwb2ludFswXTtcbiAgICB9XG5cbiAgICBkaXN0YW5jZVkocG9pbnQ6IEFycmF5PG51bWJlcj4pOiBudW1iZXIge1xuICAgICAgICBjb25zdCBwb2ludE9uQWFiYiA9IE1hdGgubWF4KE1hdGgubWluKHRoaXMubWF4WzFdLCBwb2ludFsxXSksIHRoaXMubWluWzFdKTtcbiAgICAgICAgcmV0dXJuIHBvaW50T25BYWJiIC0gcG9pbnRbMV07XG4gICAgfVxuXG4gICAgZGlzdGFuY2VaKHBvaW50OiBBcnJheTxudW1iZXI+KTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgcG9pbnRPbkFhYmIgPSBNYXRoLm1heChNYXRoLm1pbih0aGlzLm1heFsyXSwgcG9pbnRbMl0pLCB0aGlzLm1pblsyXSk7XG4gICAgICAgIHJldHVybiBwb2ludE9uQWFiYiAtIHBvaW50WzJdO1xuICAgIH1cblxuICAgIGdldENvcm5lcnMoKTogQXJyYXk8VmVjMz4ge1xuICAgICAgICBjb25zdCBtbiA9IHRoaXMubWluO1xuICAgICAgICBjb25zdCBteCA9IHRoaXMubWF4O1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgW21uWzBdLCBtblsxXSwgbW5bMl1dLFxuICAgICAgICAgICAgW214WzBdLCBtblsxXSwgbW5bMl1dLFxuICAgICAgICAgICAgW214WzBdLCBteFsxXSwgbW5bMl1dLFxuICAgICAgICAgICAgW21uWzBdLCBteFsxXSwgbW5bMl1dLFxuICAgICAgICAgICAgW21uWzBdLCBtblsxXSwgbXhbMl1dLFxuICAgICAgICAgICAgW214WzBdLCBtblsxXSwgbXhbMl1dLFxuICAgICAgICAgICAgW214WzBdLCBteFsxXSwgbXhbMl1dLFxuICAgICAgICAgICAgW21uWzBdLCBteFsxXSwgbXhbMl1dLFxuICAgICAgICBdO1xuICAgIH1cblxuICAgIC8vIFBlcmZvcm1zIGEgZnJ1c3R1bS1hYWJiIGludGVyc2VjdGlvbiB0ZXN0LiBSZXR1cm5zIDAgaWYgdGhlcmUncyBubyBpbnRlcnNlY3Rpb24sXG4gICAgLy8gMSBpZiBzaGFwZXMgYXJlIGludGVyc2VjdGluZyBhbmQgMiBpZiB0aGUgYWFiYiBpZiBmdWxseSBpbnNpZGUgdGhlIGZydXN0dW0uXG4gICAgaW50ZXJzZWN0cyhmcnVzdHVtOiBGcnVzdHVtKTogbnVtYmVyIHtcbiAgICAgICAgLy8gRXhlY3V0ZSBzZXBhcmF0aW5nIGF4aXMgdGVzdCBiZXR3ZWVuIHR3byBjb252ZXggb2JqZWN0cyB0byBmaW5kIGludGVyc2VjdGlvbnNcbiAgICAgICAgLy8gRWFjaCBmcnVzdHVtIHBsYW5lIHRvZ2V0aGVyIHdpdGggMyBtYWpvciBheGVzIGRlZmluZSB0aGUgc2VwYXJhdGluZyBheGVzXG5cbiAgICAgICAgY29uc3QgYWFiYlBvaW50cyA9IHRoaXMuZ2V0Q29ybmVycygpO1xuICAgICAgICBsZXQgZnVsbHlJbnNpZGUgPSB0cnVlO1xuXG4gICAgICAgIGZvciAobGV0IHAgPSAwOyBwIDwgZnJ1c3R1bS5wbGFuZXMubGVuZ3RoOyBwKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHBsYW5lID0gZnJ1c3R1bS5wbGFuZXNbcF07XG4gICAgICAgICAgICBsZXQgcG9pbnRzSW5zaWRlID0gMDtcblxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhYWJiUG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgcG9pbnRzSW5zaWRlICs9IHZlYzMuZG90KHBsYW5lLCBhYWJiUG9pbnRzW2ldKSArIHBsYW5lWzNdID49IDA7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChwb2ludHNJbnNpZGUgPT09IDApXG4gICAgICAgICAgICAgICAgcmV0dXJuIDA7XG5cbiAgICAgICAgICAgIGlmIChwb2ludHNJbnNpZGUgIT09IGFhYmJQb2ludHMubGVuZ3RoKVxuICAgICAgICAgICAgICAgIGZ1bGx5SW5zaWRlID0gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZnVsbHlJbnNpZGUpXG4gICAgICAgICAgICByZXR1cm4gMjtcblxuICAgICAgICBmb3IgKGxldCBheGlzID0gMDsgYXhpcyA8IDM7IGF4aXMrKykge1xuICAgICAgICAgICAgbGV0IHByb2pNaW4gPSBOdW1iZXIuTUFYX1ZBTFVFO1xuICAgICAgICAgICAgbGV0IHByb2pNYXggPSAtTnVtYmVyLk1BWF9WQUxVRTtcblxuICAgICAgICAgICAgZm9yIChsZXQgcCA9IDA7IHAgPCBmcnVzdHVtLnBvaW50cy5sZW5ndGg7IHArKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHByb2plY3RlZFBvaW50ID0gZnJ1c3R1bS5wb2ludHNbcF1bYXhpc10gLSB0aGlzLm1pbltheGlzXTtcblxuICAgICAgICAgICAgICAgIHByb2pNaW4gPSBNYXRoLm1pbihwcm9qTWluLCBwcm9qZWN0ZWRQb2ludCk7XG4gICAgICAgICAgICAgICAgcHJvak1heCA9IE1hdGgubWF4KHByb2pNYXgsIHByb2plY3RlZFBvaW50KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHByb2pNYXggPCAwIHx8IHByb2pNaW4gPiB0aGlzLm1heFtheGlzXSAtIHRoaXMubWluW2F4aXNdKVxuICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIDE7XG4gICAgfVxufVxuZXhwb3J0IHtcbiAgICBBYWJiLFxuICAgIEZydXN0dW0sXG4gICAgRnJ1c3R1bUNvcm5lcnMsXG4gICAgUmF5XG59O1xuIiwiLy8gQGZsb3dcbmltcG9ydCBNZXJjYXRvckNvb3JkaW5hdGUsIHtcbiAgICBsbmdGcm9tTWVyY2F0b3JYLFxuICAgIGxhdEZyb21NZXJjYXRvclksXG4gICAgbWVyY2F0b3JaZnJvbUFsdGl0dWRlLFxuICAgIG1lcmNhdG9yWGZyb21MbmcsXG4gICAgbWVyY2F0b3JZZnJvbUxhdCxcbiAgICBNQVhfTUVSQ0FUT1JfTEFUSVRVREVcbn0gZnJvbSAnLi4vbWVyY2F0b3JfY29vcmRpbmF0ZS5qcyc7XG5pbXBvcnQgRVhURU5UIGZyb20gJy4uLy4uL2RhdGEvZXh0ZW50LmpzJztcbmltcG9ydCB7bnVtYmVyIGFzIGludGVycG9sYXRlfSBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL3V0aWwvaW50ZXJwb2xhdGUuanMnO1xuaW1wb3J0IHtkZWdUb1JhZCwgcmFkVG9EZWcsIGNsYW1wLCBzbW9vdGhzdGVwLCBnZXRDb2x1bW4sIHNob3J0ZXN0QW5nbGV9IGZyb20gJy4uLy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQge3ZlYzMsIHZlYzQsIG1hdDMsIG1hdDR9IGZyb20gJ2dsLW1hdHJpeCc7XG5pbXBvcnQgU2VnbWVudFZlY3RvciBmcm9tICcuLi8uLi9kYXRhL3NlZ21lbnQuanMnO1xuaW1wb3J0IHttZW1iZXJzIGFzIGdsb2JlTGF5b3V0QXR0cmlidXRlc30gZnJvbSAnLi4vLi4vdGVycmFpbi9nbG9iZV9hdHRyaWJ1dGVzLmpzJztcbmltcG9ydCBwb3NBdHRyaWJ1dGVzIGZyb20gJy4uLy4uL2RhdGEvcG9zX2F0dHJpYnV0ZXMuanMnO1xuaW1wb3J0IHtUcmlhbmdsZUluZGV4QXJyYXksIEdsb2JlVmVydGV4QXJyYXksIExpbmVJbmRleEFycmF5LCBQb3NBcnJheX0gZnJvbSAnLi4vLi4vZGF0YS9hcnJheV90eXBlcy5qcyc7XG5pbXBvcnQge0FhYmIsIFJheX0gZnJvbSAnLi4vLi4vdXRpbC9wcmltaXRpdmVzLmpzJztcbmltcG9ydCBMbmdMYXQsIHtlYXJ0aFJhZGl1c30gZnJvbSAnLi4vbG5nX2xhdC5qcyc7XG5pbXBvcnQgTG5nTGF0Qm91bmRzIGZyb20gJy4uL2xuZ19sYXRfYm91bmRzLmpzJztcblxuaW1wb3J0IHR5cGUgUGFpbnRlciBmcm9tICcuLi8uLi9yZW5kZXIvcGFpbnRlci5qcyc7XG5pbXBvcnQgdHlwZSB7Q2Fub25pY2FsVGlsZUlELCBVbndyYXBwZWRUaWxlSUR9IGZyb20gJy4uLy4uL3NvdXJjZS90aWxlX2lkLmpzJztcbmltcG9ydCB0eXBlIENvbnRleHQgZnJvbSAnLi4vLi4vZ2wvY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSB7VmVjMywgTWF0NH0gZnJvbSAnZ2wtbWF0cml4JztcbmltcG9ydCB0eXBlIEluZGV4QnVmZmVyIGZyb20gJy4uLy4uL2dsL2luZGV4X2J1ZmZlci5qcyc7XG5pbXBvcnQgdHlwZSBWZXJ0ZXhCdWZmZXIgZnJvbSAnLi4vLi4vZ2wvdmVydGV4X2J1ZmZlci5qcyc7XG5pbXBvcnQgdHlwZSBUcmFuc2Zvcm0gZnJvbSAnLi4vdHJhbnNmb3JtLmpzJztcbmltcG9ydCBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcblxuZXhwb3J0IGNvbnN0IEdMT0JFX1pPT01fVEhSRVNIT0xEX01JTiA9IDU7XG5leHBvcnQgY29uc3QgR0xPQkVfWk9PTV9USFJFU0hPTERfTUFYID0gNjtcblxuLy8gQXQgbG93IHpvb20gbGV2ZWxzIHRoZSBnbG9iZSBnZXRzIHJlbmRlcmVkIHNvIHRoYXQgdGhlIHNjYWxlIGF0IHRoaXNcbi8vIGxhdGl0dWRlIG1hdGNoZXMgaXQncyBzY2FsZSBpbiBhIG1lcmNhdG9yIG1hcC4gVGhlIGNob2ljZSBvZiBsYXRpdHVkZSBpc1xuLy8gYSBiaXQgYXJiaXRyYXJ5LiBEaWZmZXJlbnQgY2hvaWNlcyB3aWxsIG1hdGNoIG1lcmNhdG9yIG1vcmUgY2xvc2VseSBpbiBkaWZmZXJlbnRcbi8vIHZpZXdzLiA0NSBpcyBhIGdvb2QgZW5vdWdoIGNob2ljZSBiZWNhdXNlOlxuLy8gLSBpdCdzIGhhbGYgd2F5IGZyb20gdGhlIHBvbGUgdG8gdGhlIGVxdWF0b3Jcbi8vIC0gbWF0Y2hlcyBtb3N0IG1pZGRsZSBsYXRpdHVkZXMgcmVhc29uYWJseSB3ZWxsXG4vLyAtIGJpYXNlcyB0b3dhcmRzIGluY3JlYXNpbmcgc2l6ZSByYXRoZXIgdGhhbiBkZWNyZWFzaW5nXG4vLyAtIG1ha2VzIHRoZSBnbG9iZSBzbGlnaHRseSBsYXJnZXIgYXQgdmVyeSBsb3cgem9vbSBsZXZlbHMsIHdoZXJlIGl0IGFscmVhZHlcbi8vICAgY292ZXJzIGxlc3MgcGl4ZWxzIHRoYW4gbWVyY2F0b3IgKGR1ZSB0byB0aGUgY3VydmVkIHN1cmZhY2UpXG4vL1xuLy8gICBDaGFuZ2luZyB0aGlzIHZhbHVlIHdpbGwgY2hhbmdlIGhvdyBsYXJnZSBhIGdsb2JlIGlzIHJlbmRlcmVkIGFuZCBjb3VsZCBhZmZlY3Rcbi8vICAgZW5kIHVzZXJzLiBUaGlzIHNob3VsZCBvbmx5IGJlIGRvbmUgb2YgdGhlIHRyYWRlb2ZmcyBiZXR3ZWVuIGNoYW5nZSBhbmQgaW1wcm92ZW1lbnRcbi8vICAgYXJlIGNhcmVmdWxseSBjb25zaWRlcmVkLlxuZXhwb3J0IGNvbnN0IEdMT0JFX1NDQUxFX01BVENIX0xBVElUVURFID0gNDU7XG5cbmV4cG9ydCBjb25zdCBHTE9CRV9SQURJVVMgPSBFWFRFTlQgLyBNYXRoLlBJIC8gMi4wO1xuY29uc3QgR0xPQkVfTk9STUFMSVpBVElPTl9CSVRfUkFOR0UgPSAxNTtcbmNvbnN0IEdMT0JFX05PUk1BTElaQVRJT05fTUFTSyA9ICgxIDw8IChHTE9CRV9OT1JNQUxJWkFUSU9OX0JJVF9SQU5HRSAtIDEpKSAtIDE7XG5jb25zdCBHTE9CRV9WRVJURVhfR1JJRF9TSVpFID0gNjQ7XG5jb25zdCBHTE9CRV9MQVRJVFVESU5BTF9HUklEX0xPRF9UQUJMRSA9IFtHTE9CRV9WRVJURVhfR1JJRF9TSVpFLCBHTE9CRV9WRVJURVhfR1JJRF9TSVpFIC8gMiwgR0xPQkVfVkVSVEVYX0dSSURfU0laRSAvIDRdO1xuY29uc3QgVElMRV9TSVpFID0gNTEyO1xuXG5jb25zdCBHTE9CRV9NSU4gPSAtR0xPQkVfUkFESVVTO1xuY29uc3QgR0xPQkVfTUFYID0gR0xPQkVfUkFESVVTO1xuXG5jb25zdCBHTE9CRV9MT1dfWk9PTV9USUxFX0FBQkJTID0gW1xuICAgIC8vIHogPT0gMFxuICAgIG5ldyBBYWJiKFtHTE9CRV9NSU4sIEdMT0JFX01JTiwgR0xPQkVfTUlOXSwgW0dMT0JFX01BWCwgR0xPQkVfTUFYLCBHTE9CRV9NQVhdKSxcbiAgICAvLyB6ID09IDFcbiAgICBuZXcgQWFiYihbR0xPQkVfTUlOLCBHTE9CRV9NSU4sIEdMT0JFX01JTl0sIFswLCAwLCBHTE9CRV9NQVhdKSwgLy8geD0wLCB5PTBcbiAgICBuZXcgQWFiYihbMCwgR0xPQkVfTUlOLCBHTE9CRV9NSU5dLCBbR0xPQkVfTUFYLCAwLCBHTE9CRV9NQVhdKSwgLy8geD0xLCB5PTBcbiAgICBuZXcgQWFiYihbR0xPQkVfTUlOLCAwLCBHTE9CRV9NSU5dLCBbMCwgR0xPQkVfTUFYLCBHTE9CRV9NQVhdKSwgLy8geD0wLCB5PTFcbiAgICBuZXcgQWFiYihbMCwgMCwgR0xPQkVfTUlOXSwgW0dMT0JFX01BWCwgR0xPQkVfTUFYLCBHTE9CRV9NQVhdKSAgLy8geD0xLCB5PTFcbl07XG5cbmV4cG9ydCBmdW5jdGlvbiBnbG9iZU1ldGVyc1RvRWNlZihkOiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiBkICogR0xPQkVfUkFESVVTIC8gZWFydGhSYWRpdXM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnbG9iZVBvaW50Q29vcmRpbmF0ZSh0cjogVHJhbnNmb3JtLCB4OiBudW1iZXIsIHk6IG51bWJlciwgY2xhbXBUb0hvcml6b246IGJvb2xlYW4gPSB0cnVlKTogP01lcmNhdG9yQ29vcmRpbmF0ZSB7XG4gICAgY29uc3QgcG9pbnQwID0gdmVjMy5zY2FsZShbXSwgdHIuX2NhbWVyYS5wb3NpdGlvbiwgdHIud29ybGRTaXplKTtcbiAgICBjb25zdCBwb2ludDEgPSBbeCwgeSwgMSwgMV07XG5cbiAgICB2ZWM0LnRyYW5zZm9ybU1hdDQocG9pbnQxLCBwb2ludDEsIHRyLnBpeGVsTWF0cml4SW52ZXJzZSk7XG4gICAgdmVjNC5zY2FsZShwb2ludDEsIHBvaW50MSwgMSAvIHBvaW50MVszXSk7XG5cbiAgICBjb25zdCBwMHAxID0gdmVjMy5zdWIoW10sIHBvaW50MSwgcG9pbnQwKTtcbiAgICBjb25zdCBkaXIgPSB2ZWMzLm5vcm1hbGl6ZShbXSwgcDBwMSk7XG5cbiAgICAvLyBGaW5kIGNsb3Nlc3QgcG9pbnQgb24gdGhlIHNwaGVyZSB0byB0aGUgcmF5LiBUaGlzIGlzIGEgYml0IG1vcmUgaW52b2x2aW5nIG9wZXJhdGlvblxuICAgIC8vIGlmIHRoZSByYXkgaXMgbm90IGludGVyc2VjdGluZyB3aXRoIHRoZSBzcGhlcmUsIGluIHdoaWNoIGNhc2Ugd2UgXCJjbGFtcFwiIHRoZSByYXlcbiAgICAvLyB0byB0aGUgc3VyZmFjZSBvZiB0aGUgc3BoZXJlLCBpLmUuIGZpbmQgYSB0YW5nZW50IHZlY3RvciB0aGF0IG9yaWdpbmF0ZXMgZnJvbSB0aGUgY2FtZXJhIHBvc2l0aW9uXG4gICAgY29uc3QgbSA9IHRyLmdsb2JlTWF0cml4O1xuICAgIGNvbnN0IGdsb2JlQ2VudGVyID0gW21bMTJdLCBtWzEzXSwgbVsxNF1dO1xuICAgIGNvbnN0IHAwdG9DZW50ZXIgPSB2ZWMzLnN1YihbXSwgZ2xvYmVDZW50ZXIsIHBvaW50MCk7XG4gICAgY29uc3QgcDB0b0NlbnRlckRpc3QgPSB2ZWMzLmxlbmd0aChwMHRvQ2VudGVyKTtcbiAgICBjb25zdCBjZW50ZXJEaXIgPSB2ZWMzLm5vcm1hbGl6ZShbXSwgcDB0b0NlbnRlcik7XG4gICAgY29uc3QgcmFkaXVzID0gdHIud29ybGRTaXplIC8gKDIuMCAqIE1hdGguUEkpO1xuICAgIGNvbnN0IGNvc0FuZ2xlID0gdmVjMy5kb3QoY2VudGVyRGlyLCBkaXIpO1xuXG4gICAgY29uc3Qgb3JpZ29UYW5nZW50QW5nbGUgPSBNYXRoLmFzaW4ocmFkaXVzIC8gcDB0b0NlbnRlckRpc3QpO1xuICAgIGNvbnN0IG9yaWdvRGlyQW5nbGUgPSBNYXRoLmFjb3MoY29zQW5nbGUpO1xuXG4gICAgaWYgKG9yaWdvVGFuZ2VudEFuZ2xlIDwgb3JpZ29EaXJBbmdsZSkge1xuICAgICAgICBpZiAoIWNsYW1wVG9Ib3Jpem9uKSByZXR1cm4gbnVsbDtcblxuICAgICAgICAvLyBGaW5kIHRoZSB0YW5nZW50IHZlY3RvciBieSBpbnRlcnBvbGF0aW5nIGJldHdlZW4gY2FtZXJhLXRvLWdsb2JlIGFuZCBjYW1lcmEtdG8tY2xpY2sgdmVjdG9ycy5cbiAgICAgICAgLy8gRmlyc3Qgd2UnbGwgZmluZCBhIHBvaW50IFAxIG9uIHRoZSBjbGlja2VkIHJheSB0aGF0IGZvcm1zIGEgcmlnaHQtYW5nbGVkIHRyaWFuZ2xlIHdpdGggdGhlIGNhbWVyYSBwb3NpdGlvblxuICAgICAgICAvLyBhbmQgdGhlIGNlbnRlciBvZiB0aGUgZ2xvYmUuIEFuZ2xlIG9mIHRoZSB0YW5nZXQgdmVjdG9yIGlzIHRoZW4gdXNlZCBhcyB0aGUgaW50ZXJwb2xhdGlvbiBmYWN0b3JcbiAgICAgICAgY29uc3QgY2xhbXBlZFAxID0gW10sIG9yaWdvVG9QMSA9IFtdO1xuXG4gICAgICAgIHZlYzMuc2NhbGUoY2xhbXBlZFAxLCBkaXIsIHAwdG9DZW50ZXJEaXN0IC8gY29zQW5nbGUpO1xuICAgICAgICB2ZWMzLm5vcm1hbGl6ZShvcmlnb1RvUDEsIHZlYzMuc3ViKG9yaWdvVG9QMSwgY2xhbXBlZFAxLCBwMHRvQ2VudGVyKSk7XG4gICAgICAgIHZlYzMubm9ybWFsaXplKGRpciwgdmVjMy5hZGQoZGlyLCBwMHRvQ2VudGVyLCB2ZWMzLnNjYWxlKGRpciwgb3JpZ29Ub1AxLCBNYXRoLnRhbihvcmlnb1RhbmdlbnRBbmdsZSkgKiBwMHRvQ2VudGVyRGlzdCkpKTtcbiAgICB9XG5cbiAgICBjb25zdCBwb2ludE9uR2xvYmUgPSBbXTtcbiAgICBjb25zdCByYXkgPSBuZXcgUmF5KHBvaW50MCwgZGlyKTtcblxuICAgIHJheS5jbG9zZXN0UG9pbnRPblNwaGVyZShnbG9iZUNlbnRlciwgcmFkaXVzLCBwb2ludE9uR2xvYmUpO1xuXG4gICAgLy8gVHJhbnNmb3JtIGNvb3JkaW5hdGUgYXhlcyB0byBmaW5kIGxhdCAmIGxuZyBvZiB0aGUgcG9zaXRpb25cbiAgICBjb25zdCB4YSA9IHZlYzMubm9ybWFsaXplKFtdLCBnZXRDb2x1bW4obSwgMCkpO1xuICAgIGNvbnN0IHlhID0gdmVjMy5ub3JtYWxpemUoW10sIGdldENvbHVtbihtLCAxKSk7XG4gICAgY29uc3QgemEgPSB2ZWMzLm5vcm1hbGl6ZShbXSwgZ2V0Q29sdW1uKG0sIDIpKTtcblxuICAgIGNvbnN0IHhwID0gdmVjMy5kb3QoeGEsIHBvaW50T25HbG9iZSk7XG4gICAgY29uc3QgeXAgPSB2ZWMzLmRvdCh5YSwgcG9pbnRPbkdsb2JlKTtcbiAgICBjb25zdCB6cCA9IHZlYzMuZG90KHphLCBwb2ludE9uR2xvYmUpO1xuXG4gICAgY29uc3QgbGF0ID0gcmFkVG9EZWcoTWF0aC5hc2luKC15cCAvIHJhZGl1cykpO1xuICAgIGxldCBsbmcgPSByYWRUb0RlZyhNYXRoLmF0YW4yKHhwLCB6cCkpO1xuXG4gICAgLy8gQ2hlY2sgdGhhdCB0aGUgcmV0dXJuZWQgbG9uZ2l0dWRlIGFuZ2xlIGlzIG5vdCB3cmFwcGVkXG4gICAgbG5nID0gdHIuY2VudGVyLmxuZyArIHNob3J0ZXN0QW5nbGUodHIuY2VudGVyLmxuZywgbG5nKTtcblxuICAgIGNvbnN0IG14ID0gbWVyY2F0b3JYZnJvbUxuZyhsbmcpO1xuICAgIGNvbnN0IG15ID0gY2xhbXAobWVyY2F0b3JZZnJvbUxhdChsYXQpLCAwLCAxKTtcblxuICAgIHJldHVybiBuZXcgTWVyY2F0b3JDb29yZGluYXRlKG14LCBteSk7XG59XG5cbmV4cG9ydCBjbGFzcyBBcmMge1xuICAgIGNvbnN0cnVjdG9yKHAwOiBWZWMzLCBwMTogVmVjMywgY2VudGVyOiBWZWMzKSB7XG4gICAgICAgIHRoaXMuYSA9IHZlYzMuc3ViKFtdLCBwMCwgY2VudGVyKTtcbiAgICAgICAgdGhpcy5iID0gdmVjMy5zdWIoW10sIHAxLCBjZW50ZXIpO1xuICAgICAgICB0aGlzLmNlbnRlciA9IGNlbnRlcjtcbiAgICAgICAgY29uc3QgYW4gPSB2ZWMzLm5vcm1hbGl6ZShbXSwgdGhpcy5hKTtcbiAgICAgICAgY29uc3QgYm4gPSB2ZWMzLm5vcm1hbGl6ZShbXSwgdGhpcy5iKTtcbiAgICAgICAgdGhpcy5hbmdsZSA9IE1hdGguYWNvcyh2ZWMzLmRvdChhbiwgYm4pKTtcbiAgICB9XG5cbiAgICBhOiBWZWMzO1xuICAgIGI6IFZlYzM7XG4gICAgY2VudGVyOiBWZWMzO1xuICAgIGFuZ2xlOiBudW1iZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzbGVycChhOiBudW1iZXIsIGI6IG51bWJlciwgYW5nbGU6IG51bWJlciwgdDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBjb25zdCBzaW5hID0gTWF0aC5zaW4oYW5nbGUpO1xuICAgIHJldHVybiBhICogKE1hdGguc2luKCgxLjAgLSB0KSAqIGFuZ2xlKSAvIHNpbmEpICsgYiAqIChNYXRoLnNpbih0ICogYW5nbGUpIC8gc2luYSk7XG59XG5cbi8vIENvbXB1dGVzIGxvY2FsIGV4dHJlbXVtIHBvaW50IG9mIGFuIGFyYyBvbiBvbmUgb2YgdGhlIGRpbWVuc2lvbnMgKHgsIHkgb3IgeiksXG4vLyBpLmUuIHZhbHVlIG9mIGEgcG9pbnQgd2hlcmUgZC9kdCpmKHgseSx0KSA9PSAwXG5leHBvcnQgZnVuY3Rpb24gbG9jYWxFeHRyZW11bShhcmM6IEFyYywgZGltOiBudW1iZXIpOiA/bnVtYmVyIHtcbiAgICAvLyBkL2R0KnNsZXJwKHgseSx0KSA9IDBcbiAgICAvLyA9PiB0ID0gKDEvYSkqYXRhbih5Lyh4KnNpbihhKSktMS90YW4oYSkpLCB4ID4gMFxuICAgIC8vID0+IHQgPSAoMS9hKSoocGkvMiksIHggPT0gMFxuICAgIGlmIChhcmMuYW5nbGUgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgbGV0IHQ6IG51bWJlcjtcbiAgICBpZiAoYXJjLmFbZGltXSA9PT0gMCkge1xuICAgICAgICB0ID0gKDEuMCAvIGFyYy5hbmdsZSkgKiAwLjUgKiBNYXRoLlBJO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHQgPSAxLjAgLyBhcmMuYW5nbGUgKiBNYXRoLmF0YW4oYXJjLmJbZGltXSAvIGFyYy5hW2RpbV0gLyBNYXRoLnNpbihhcmMuYW5nbGUpIC0gMS4wIC8gTWF0aC50YW4oYXJjLmFuZ2xlKSk7XG4gICAgfVxuXG4gICAgaWYgKHQgPCAwIHx8IHQgPiAxKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBzbGVycChhcmMuYVtkaW1dLCBhcmMuYltkaW1dLCBhcmMuYW5nbGUsIGNsYW1wKHQsIDAuMCwgMS4wKSkgKyBhcmMuY2VudGVyW2RpbV07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnbG9iZVRpbGVCb3VuZHMoaWQ6IENhbm9uaWNhbFRpbGVJRCk6IEFhYmIge1xuICAgIGlmIChpZC56IDw9IDEpIHtcbiAgICAgICAgcmV0dXJuIEdMT0JFX0xPV19aT09NX1RJTEVfQUFCQlNbaWQueiArIGlkLnkgKiAyICsgaWQueF07XG4gICAgfVxuXG4gICAgLy8gQWZ0ZXIgem9vbSAxIHN1cmZhY2UgZnVuY3Rpb24gaXMgbW9ub3RvbmljIGZvciBhbGwgdGlsZSBwYXRjaGVzXG4gICAgLy8gPT4gaXQgaXMgZW5vdWdoIHRvIHByb2plY3QgY29ybmVyIHBvaW50c1xuICAgIGNvbnN0IGJvdW5kcyA9IHRpbGVDb3JuZXJzVG9Cb3VuZHMoaWQpO1xuICAgIGNvbnN0IGNvcm5lcnMgPSBib3VuZHNUb0VDRUYoYm91bmRzKTtcblxuICAgIHJldHVybiBBYWJiLmZyb21Qb2ludHMoY29ybmVycyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpbnRlcnBvbGF0ZVZlYzMoZnJvbTogVmVjMywgdG86IFZlYzMsIHBoYXNlOiBudW1iZXIpOiBWZWMzIHtcbiAgICB2ZWMzLnNjYWxlKGZyb20sIGZyb20sIDEgLSBwaGFzZSk7XG4gICAgcmV0dXJuIHZlYzMuc2NhbGVBbmRBZGQoZnJvbSwgZnJvbSwgdG8sIHBoYXNlKTtcbn1cblxuLy8gU2ltaWxhciB0byBnbG9iZVRpbGVCb3VuZHMoKSBidXQgYWNjb3VudHMgZm9yIGdsb2JlIHRvIE1lcmNhdG9yIHRyYW5zaXRpb24uXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNpdGlvblRpbGVBQUJCaW5FQ0VGKGlkOiBDYW5vbmljYWxUaWxlSUQsIHRyOiBUcmFuc2Zvcm0pOiBBYWJiIHtcbiAgICBjb25zdCBwaGFzZSA9IGdsb2JlVG9NZXJjYXRvclRyYW5zaXRpb24odHIuem9vbSk7XG4gICAgaWYgKHBoYXNlID09PSAwKSB7XG4gICAgICAgIHJldHVybiBnbG9iZVRpbGVCb3VuZHMoaWQpO1xuICAgIH1cblxuICAgIGNvbnN0IGJvdW5kcyA9IHRpbGVDb3JuZXJzVG9Cb3VuZHMoaWQpO1xuICAgIGNvbnN0IGNvcm5lcnMgPSBib3VuZHNUb0VDRUYoYm91bmRzKTtcblxuICAgIGNvbnN0IHcgPSBtZXJjYXRvclhmcm9tTG5nKGJvdW5kcy5nZXRXZXN0KCkpICogdHIud29ybGRTaXplO1xuICAgIGNvbnN0IGUgPSBtZXJjYXRvclhmcm9tTG5nKGJvdW5kcy5nZXRFYXN0KCkpICogdHIud29ybGRTaXplO1xuICAgIGNvbnN0IG4gPSBtZXJjYXRvcllmcm9tTGF0KGJvdW5kcy5nZXROb3J0aCgpKSAqIHRyLndvcmxkU2l6ZTtcbiAgICBjb25zdCBzID0gbWVyY2F0b3JZZnJvbUxhdChib3VuZHMuZ2V0U291dGgoKSkgKiB0ci53b3JsZFNpemU7XG4gICAgLy8gTWVyY2F0b3IgYm91bmRzIGdsb2JlQ29ybmVycyBpbiB3b3JsZC9waXhlbCBzcGFjZVxuICAgIGNvbnN0IG53ID0gW3csIG4sIDBdO1xuICAgIGNvbnN0IG5lID0gW2UsIG4sIDBdO1xuICAgIGNvbnN0IHN3ID0gW3csIHMsIDBdO1xuICAgIGNvbnN0IHNlID0gW2UsIHMsIDBdO1xuICAgIC8vIFRyYW5zZm9ybSBNZXJjYXRvciBnbG9iZUNvcm5lcnMgdG8gRUNFRlxuICAgIGNvbnN0IHdvcmxkVG9FQ0VGTWF0cml4ID0gbWF0NC5pbnZlcnQoW10sIHRyLmdsb2JlTWF0cml4KTtcbiAgICB2ZWMzLnRyYW5zZm9ybU1hdDQobncsIG53LCB3b3JsZFRvRUNFRk1hdHJpeCk7XG4gICAgdmVjMy50cmFuc2Zvcm1NYXQ0KG5lLCBuZSwgd29ybGRUb0VDRUZNYXRyaXgpO1xuICAgIHZlYzMudHJhbnNmb3JtTWF0NChzdywgc3csIHdvcmxkVG9FQ0VGTWF0cml4KTtcbiAgICB2ZWMzLnRyYW5zZm9ybU1hdDQoc2UsIHNlLCB3b3JsZFRvRUNFRk1hdHJpeCk7XG4gICAgLy8gSW50ZXJwb2xhdGUgTWVyY2F0b3IgY29ybmVycyBhbmQgZ2xvYmUgY29ybmVyc1xuICAgIGNvcm5lcnNbMF0gPSBpbnRlcnBvbGF0ZVZlYzMoY29ybmVyc1swXSwgc3csIHBoYXNlKTtcbiAgICBjb3JuZXJzWzFdID0gaW50ZXJwb2xhdGVWZWMzKGNvcm5lcnNbMV0sIHNlLCBwaGFzZSk7XG4gICAgY29ybmVyc1syXSA9IGludGVycG9sYXRlVmVjMyhjb3JuZXJzWzJdLCBuZSwgcGhhc2UpO1xuICAgIGNvcm5lcnNbM10gPSBpbnRlcnBvbGF0ZVZlYzMoY29ybmVyc1szXSwgbncsIHBoYXNlKTtcblxuICAgIHJldHVybiBBYWJiLmZyb21Qb2ludHMoY29ybmVycyk7XG59XG5cbmZ1bmN0aW9uIHRyYW5zZm9ybVBvaW50cyhjb3JuZXJzOiBBcnJheTxWZWMzPiwgZ2xvYmVNYXRyaXg6IE1hdDQsIHNjYWxlOiBudW1iZXIpIHtcbiAgICBmb3IgKGNvbnN0IGNvcm5lciBvZiBjb3JuZXJzKSB7XG4gICAgICAgIHZlYzMudHJhbnNmb3JtTWF0NChjb3JuZXIsIGNvcm5lciwgZ2xvYmVNYXRyaXgpO1xuICAgICAgICB2ZWMzLnNjYWxlKGNvcm5lciwgY29ybmVyLCBzY2FsZSk7XG4gICAgfVxufVxuXG4vLyBSZXR1cm5zIEFBQkIgaW4gd29ybGQvY2FtZXJhIHNwYWNlIHNjYWxlZCBieSBudW1UaWxlcyAvIHRyLndvcmxkU2l6ZVxuZXhwb3J0IGZ1bmN0aW9uIGFhYmJGb3JUaWxlT25HbG9iZSh0cjogVHJhbnNmb3JtLCBudW1UaWxlczogbnVtYmVyLCB0aWxlSWQ6IENhbm9uaWNhbFRpbGVJRCk6IEFhYmIge1xuICAgIGNvbnN0IHNjYWxlID0gbnVtVGlsZXMgLyB0ci53b3JsZFNpemU7XG4gICAgY29uc3QgbSA9IHRyLmdsb2JlTWF0cml4O1xuXG4gICAgaWYgKHRpbGVJZC56IDw9IDEpIHtcbiAgICAgICAgLy8gQ29tcHV0ZSB3b3JsZC9waXhlbCBzcGFjZSBBQUJCIHRoYXQgZnVsbHkgZW5jYXBzdWxhdGVzXG4gICAgICAgIC8vIHRyYW5zZm9ybWVkIGNvcm5lcnMgb2YgdGhlIEVDRUYgQUFCQlxuICAgICAgICBjb25zdCBjb3JuZXJzID0gZ2xvYmVUaWxlQm91bmRzKHRpbGVJZCkuZ2V0Q29ybmVycygpO1xuICAgICAgICB0cmFuc2Zvcm1Qb2ludHMoY29ybmVycywgbSwgc2NhbGUpO1xuICAgICAgICByZXR1cm4gQWFiYi5mcm9tUG9pbnRzKGNvcm5lcnMpO1xuICAgIH1cblxuICAgIC8vIEZpbmQgbWluaW1hbCBhYWJiIGZvciBhIHRpbGUuIENvcnJlY3Qgc29sdXRpb24gd291bGQgYmUgdG8gY29tcHV0ZSBib3VuZGluZyBib3ggdGhhdFxuICAgIC8vIGZ1bGx5IGVuY2Fwc3VsYXRlcyB0aGUgY3VydmVkIHBhdGNoIHRoYXQgcmVwcmVzZW50cyB0aGUgdGlsZSBvbiBnbG9iZXMgc3VyZmFjZS5cbiAgICAvLyBUaGlzIGNhbiBiZSBzaW1wbGlmaWVkIGEgYml0IGFzIHRoZSBnbG9iZSB0cmFuc2Zvcm1hdGlvbiBpcyBjb25zdHJhaW5lZDpcbiAgICAvLyAgMS4gQ2FtZXJhIGFsd2F5cyBmYWNlcyB0aGUgY2VudGVyIHBvaW50IG9uIHRoZSBtYXBcbiAgICAvLyAgMi4gQ2FtZXJhIGlzIGFsd2F5cyBhYm92ZSAoei1jb29yZGluYXRlKSBhbGwgb2YgdGhlIHRpbGVzXG4gICAgLy8gIDMuIFVwIGRpcmVjdGlvbiBvZiB0aGUgY29vcmRpbmF0ZSBzcGFjZSAocGl4ZWwgc3BhY2UpIGlzIGFsd2F5cyArei4gVGhpcyBtZWFucyB0aGF0XG4gICAgLy8gICAgIHRoZSBcImhpZ2hlc3RcIiBwb2ludCBvZiB0aGUgbWFwIGlzIGF0IHRoZSBjZW50ZXIuXG4gICAgLy8gIDQuIHotY29vcmRpbmF0ZSBvZiBhbnkgcG9pbnQgaW4gYW55IHRpbGUgZGVzY2VuZHMgYXMgYSBmdW5jdGlvbiBvZiB0aGUgZGlzdGFuY2UgZnJvbSB0aGUgY2VudGVyXG5cbiAgICAvLyBTaW1wbGlmaWVkIGFhYmIgaXMgY29tcHV0ZWQgYnkgZmlyc3QgZW5jYXBzdWxhdGluZyA0IHRyYW5zZm9ybWVkIGNvcm5lciBwb2ludHMgb2YgdGhlIHRpbGUuXG4gICAgLy8gVGhlIHJlc3VsdGluZyBhYWJiIGlzIG5vdCBjb21wbGV0ZSB5ZXQgYXMgY3VydmVkIGVkZ2VzIG9mIHRoZSB0aWxlIG1pZ2h0IHNwYW4gb3V0c2lkZSBvZiB0aGUgYm91bmRhcmllcy5cbiAgICAvLyBJdCBpcyBlbm91Z2ggdG8gZXh0ZW5kIHRoZSBhYWJiIHRvIGNvbnRhaW4gb25seSB0aGUgZWRnZSB0aGF0J3MgY2xvc2VzdCB0byB0aGUgY2VudGVyIHBvaW50LlxuICAgIGNvbnN0IGJvdW5kcyA9IHRpbGVDb3JuZXJzVG9Cb3VuZHModGlsZUlkKTtcbiAgICBjb25zdCBjb3JuZXJzID0gYm91bmRzVG9FQ0VGKGJvdW5kcyk7XG5cbiAgICAvLyBUcmFuc2Zvcm0gdGhlIGNvcm5lcnMgdG8gd29ybGQgc3BhY2VcbiAgICB0cmFuc2Zvcm1Qb2ludHMoY29ybmVycywgbSwgc2NhbGUpO1xuXG4gICAgY29uc3QgbXggPSBOdW1iZXIuTUFYX1ZBTFVFO1xuICAgIGNvbnN0IGNvcm5lck1heCA9IFstbXgsIC1teCwgLW14XTtcbiAgICBjb25zdCBjb3JuZXJNaW4gPSBbbXgsIG14LCBteF07XG5cbiAgICAvLyBFeHRlbmQgdGhlIGFhYmIgYnkgaW5jbHVkaW5nIHRoZSBjZW50ZXIgcG9pbnQuIFRoZXJlIGFyZSBzb21lIGNvcm5lciBjYXNlcyB3aGVyZSBjZW50ZXIgcG9pbnQgaXMgaW5zaWRlIHRoZVxuICAgIC8vIHRpbGUgYnV0IGR1ZSB0byBjdXJ2YXR1cmUgYWFiYiBjb21wdXRlZCBmcm9tIGNvcm5lciBwb2ludHMgZG9lcyBub3QgY292ZXIgdGhlIGN1cnZlZCBhcmVhLlxuICAgIGlmIChib3VuZHMuY29udGFpbnModHIuY2VudGVyKSkge1xuXG4gICAgICAgIGZvciAoY29uc3QgY29ybmVyIG9mIGNvcm5lcnMpIHtcbiAgICAgICAgICAgIHZlYzMubWluKGNvcm5lck1pbiwgY29ybmVyTWluLCBjb3JuZXIpO1xuICAgICAgICAgICAgdmVjMy5tYXgoY29ybmVyTWF4LCBjb3JuZXJNYXgsIGNvcm5lcik7XG4gICAgICAgIH1cbiAgICAgICAgY29ybmVyTWF4WzJdID0gMC4wO1xuICAgICAgICBjb25zdCBwb2ludCA9IHRyLnBvaW50O1xuICAgICAgICBjb25zdCBjZW50ZXIgPSBbcG9pbnQueCAqIHNjYWxlLCBwb2ludC55ICogc2NhbGUsIDBdO1xuICAgICAgICB2ZWMzLm1pbihjb3JuZXJNaW4sIGNvcm5lck1pbiwgY2VudGVyKTtcbiAgICAgICAgdmVjMy5tYXgoY29ybmVyTWF4LCBjb3JuZXJNYXgsIGNlbnRlcik7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBBYWJiKGNvcm5lck1pbiwgY29ybmVyTWF4KTtcbiAgICB9XG5cbiAgICAvLyBDb21wdXRlIGFyY3MgZGVzY3JpYmluZyBlZGdlcyBvZiB0aGUgdGlsZSBvbiB0aGUgZ2xvYmUgc3VyZmFjZS5cbiAgICAvLyBWZXJ0aWNhbCBlZGdlcyByZXZvbHZlcyBhcm91bmQgdGhlIGdsb2JlIG9yaWdpbiB3aGVyZWFzIGhvcml6b250YWwgZWRnZXMgcmV2b2x2ZXMgYXJvdW5kIHRoZSB5LWF4aXMuXG4gICAgY29uc3QgYXJjQ2VudGVyID0gW21bMTJdICogc2NhbGUsIG1bMTNdICogc2NhbGUsIG1bMTRdICogc2NhbGVdO1xuXG4gICAgY29uc3QgdGlsZUNlbnRlciA9IGJvdW5kcy5nZXRDZW50ZXIoKTtcbiAgICBjb25zdCBjZW50ZXJMYXQgPSBjbGFtcCh0ci5jZW50ZXIubGF0LCAtTUFYX01FUkNBVE9SX0xBVElUVURFLCBNQVhfTUVSQ0FUT1JfTEFUSVRVREUpO1xuICAgIGNvbnN0IHRpbGVDZW50ZXJMYXQgPSBjbGFtcCh0aWxlQ2VudGVyLmxhdCwgLU1BWF9NRVJDQVRPUl9MQVRJVFVERSwgTUFYX01FUkNBVE9SX0xBVElUVURFKTtcbiAgICBjb25zdCBjYW1YID0gbWVyY2F0b3JYZnJvbUxuZyh0ci5jZW50ZXIubG5nKTtcbiAgICBjb25zdCBjYW1ZID0gbWVyY2F0b3JZZnJvbUxhdChjZW50ZXJMYXQpO1xuXG4gICAgbGV0IGR4ID0gY2FtWCAtIG1lcmNhdG9yWGZyb21MbmcodGlsZUNlbnRlci5sbmcpO1xuICAgIGNvbnN0IGR5ID0gY2FtWSAtIG1lcmNhdG9yWWZyb21MYXQodGlsZUNlbnRlckxhdCk7XG5cbiAgICAvLyBTaG9ydGVzdCBkaXN0YW5jZSBtaWdodCBiZSBhY3Jvc3MgdGhlIGFudGltZXJpZGlhblxuICAgIGlmIChkeCA+IC41KSB7XG4gICAgICAgIGR4IC09IDE7XG4gICAgfSBlbHNlIGlmIChkeCA8IC0uNSkge1xuICAgICAgICBkeCArPSAxO1xuICAgIH1cblxuICAgIC8vIEhlcmUgd2UgZGV0ZXJtaW5lIHRoZSBhcmMgd2hpY2ggaXMgY2xvc2VzdCB0byB0aGUgbWFwIGNlbnRlciBwb2ludC5cbiAgICAvLyBIb3Jpem9udGFsIGFyY3Mgb3JpZ2luID0gZ2xvYmUgY2VudGVyXG4gICAgLy8gVmVydGljYWwgYXJjcyBvcmlnaW4gPSBnbG9iZSBjZW50ZXIgKyB5QXhpcyAqIHNoaWZ0LlxuICAgIC8vIFdoZXJlIGBzaGlmdGAgaXMgZGV0ZXJtaW5lZCBieSBsYXRpdHVkZS5cbiAgICBsZXQgY2xvc2VzdEFyY0lkeCA9IDA7XG4gICAgaWYgKE1hdGguYWJzKGR4KSA+IE1hdGguYWJzKGR5KSkge1xuICAgICAgICBjbG9zZXN0QXJjSWR4ID0gZHggPj0gMCA/IDEgOiAzO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGNsb3Nlc3RBcmNJZHggPSBkeSA+PSAwID8gMCA6IDI7XG4gICAgICAgIGNvbnN0IHlBeGlzID0gW21bNF0gKiBzY2FsZSwgbVs1XSAqIHNjYWxlLCBtWzZdICogc2NhbGVdO1xuICAgICAgICBjb25zdCBzaGlmdCA9IC1NYXRoLnNpbihkZWdUb1JhZChkeSA+PSAwID8gYm91bmRzLmdldFNvdXRoKCkgOiBib3VuZHMuZ2V0Tm9ydGgoKSkpICogR0xPQkVfUkFESVVTO1xuICAgICAgICB2ZWMzLnNjYWxlQW5kQWRkKGFyY0NlbnRlciwgYXJjQ2VudGVyLCB5QXhpcywgc2hpZnQpO1xuICAgIH1cblxuICAgIGNvbnN0IGFyY1N0YXJ0ID0gY29ybmVyc1tjbG9zZXN0QXJjSWR4XTtcbiAgICBjb25zdCBhcmNFbmQgPSBjb3JuZXJzWyhjbG9zZXN0QXJjSWR4ICsgMSkgJSA0XTtcblxuICAgIGNvbnN0IGNsb3Nlc3RBcmMgPSBuZXcgQXJjKGFyY1N0YXJ0LCBhcmNFbmQsIGFyY0NlbnRlcik7XG4gICAgY29uc3QgYXJjRXh0cmVtdW0gPSBbXG4gICAgICAgIChsb2NhbEV4dHJlbXVtKGNsb3Nlc3RBcmMsIDApIHx8IGFyY1N0YXJ0WzBdKSxcbiAgICAgICAgKGxvY2FsRXh0cmVtdW0oY2xvc2VzdEFyYywgMSkgfHwgYXJjU3RhcnRbMV0pLFxuICAgICAgICAobG9jYWxFeHRyZW11bShjbG9zZXN0QXJjLCAyKSB8fCBhcmNTdGFydFsyXSldO1xuXG4gICAgY29uc3QgcGhhc2UgPSBnbG9iZVRvTWVyY2F0b3JUcmFuc2l0aW9uKHRyLnpvb20pO1xuICAgIGlmIChwaGFzZSA+IDAuMCkge1xuICAgICAgICBjb25zdCBtZXJjYXRvckNvcm5lcnMgPSBtZXJjYXRvclRpbGVDb3JuZXJzSW5DYW1lcmFTcGFjZSh0aWxlSWQsIG51bVRpbGVzLCB0ci5fcGl4ZWxzUGVyTWVyY2F0b3JQaXhlbCwgY2FtWCwgY2FtWSk7XG4gICAgICAgIC8vIEludGVycG9sYXRlIHRoZSBmb3VyIGNvcm5lcnMgdG93YXJkcyB0aGVpciB3b3JsZCBzcGFjZSBsb2NhdGlvbiBpbiBtZXJjYXRvciBwcm9qZWN0aW9uIGR1cmluZyB0cmFuc2l0aW9uLlxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvcm5lcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGludGVycG9sYXRlVmVjMyhjb3JuZXJzW2ldLCBtZXJjYXRvckNvcm5lcnNbaV0sIHBoYXNlKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBDYWxjdWxhdGUgdGhlIG1pZHBvaW50IG9mIHRoZSBjbG9zZXN0IGVkZ2UgbWlkcG9pbnQgaW4gTWVyY2F0b3JcbiAgICAgICAgY29uc3QgbWVyY2F0b3JNaWRwb2ludCA9IHZlYzMuYWRkKFtdLCBtZXJjYXRvckNvcm5lcnNbY2xvc2VzdEFyY0lkeF0sIG1lcmNhdG9yQ29ybmVyc1soY2xvc2VzdEFyY0lkeCArIDEpICUgNF0pO1xuICAgICAgICB2ZWMzLnNjYWxlKG1lcmNhdG9yTWlkcG9pbnQsIG1lcmNhdG9yTWlkcG9pbnQsIC41KTtcbiAgICAgICAgLy8gSW50ZXJwb2xhdGUgZ2xvYmUgZXh0cmVtdW0gdG93YXJkIE1lcmNhdG9yIG1pZHBvaW50XG4gICAgICAgIGludGVycG9sYXRlVmVjMyhhcmNFeHRyZW11bSwgbWVyY2F0b3JNaWRwb2ludCwgcGhhc2UpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgY29ybmVyIG9mIGNvcm5lcnMpIHtcbiAgICAgICAgdmVjMy5taW4oY29ybmVyTWluLCBjb3JuZXJNaW4sIGNvcm5lcik7XG4gICAgICAgIHZlYzMubWF4KGNvcm5lck1heCwgY29ybmVyTWF4LCBjb3JuZXIpO1xuICAgIH1cblxuICAgIC8vIFJlZHVjZSBoZWlnaHQgb2YgdGhlIGFhYmIgdG8gbWF0Y2ggaGVpZ2h0IG9mIHRoZSBjbG9zZXN0IGFyYy4gVGhpcyByZWR1Y2VzIGZhbHNlIHBvc2l0aXZlc1xuICAgIC8vIG9mIHRpbGVzIGZhcnRoZXIgYXdheSBmcm9tIHRoZSBjZW50ZXIgYXMgdGhleSB3b3VsZCBvdGhlcndpc2UgaW50ZXJzZWN0IHdpdGggZmFyIGVuZFxuICAgIC8vIG9mIHRoZSB2aWV3IGZydXN0dW1cbiAgICBjb3JuZXJNaW5bMl0gPSBNYXRoLm1pbihhcmNTdGFydFsyXSwgYXJjRW5kWzJdKTtcblxuICAgIHZlYzMubWluKGNvcm5lck1pbiwgY29ybmVyTWluLCBhcmNFeHRyZW11bSk7XG4gICAgdmVjMy5tYXgoY29ybmVyTWF4LCBjb3JuZXJNYXgsIGFyY0V4dHJlbXVtKTtcblxuICAgIHJldHVybiBuZXcgQWFiYihjb3JuZXJNaW4sIGNvcm5lck1heCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0aWxlQ29ybmVyc1RvQm91bmRzKHt4LCB5LCB6fTogQ2Fub25pY2FsVGlsZUlEKTogTG5nTGF0Qm91bmRzIHtcbiAgICBjb25zdCBzID0gMS4wIC8gKDEgPDwgeik7XG4gICAgY29uc3Qgc3cgPSBuZXcgTG5nTGF0KGxuZ0Zyb21NZXJjYXRvclgoeCAqIHMpLCBsYXRGcm9tTWVyY2F0b3JZKCh5ICsgMSkgKiBzKSk7XG4gICAgY29uc3QgbmUgPSBuZXcgTG5nTGF0KGxuZ0Zyb21NZXJjYXRvclgoKHggKyAxKSAqIHMpLCBsYXRGcm9tTWVyY2F0b3JZKHkgKiBzKSk7XG4gICAgcmV0dXJuIG5ldyBMbmdMYXRCb3VuZHMoc3csIG5lKTtcbn1cblxuZnVuY3Rpb24gbWVyY2F0b3JUaWxlQ29ybmVyc0luQ2FtZXJhU3BhY2Uoe3gsIHksIHp9OiBDYW5vbmljYWxUaWxlSUQsIG51bVRpbGVzOiBudW1iZXIsIG1lcmNhdG9yU2NhbGU6IG51bWJlciwgY2FtWDogbnVtYmVyLCBjYW1ZOiBudW1iZXIpOiBBcnJheTxWZWMzPiB7XG5cbiAgICBjb25zdCB0aWxlU2NhbGUgPSAxLjAgLyAoMSA8PCB6KTtcbiAgICAvLyBWYWx1ZXMgaW4gTWVyY2F0b3IgY29vcmRpbmF0ZXMgKDAgLSAxKVxuICAgIGxldCB3ID0geCAqIHRpbGVTY2FsZTtcbiAgICBsZXQgZSA9IHcgKyB0aWxlU2NhbGU7XG4gICAgbGV0IG4gPSB5ICogdGlsZVNjYWxlO1xuICAgIGxldCBzID0gbiArIHRpbGVTY2FsZTtcblxuICAgIC8vIC8vIEVuc3VyZSB0aGF0IHRoZSB0aWxlIHZpZXdlZCBpcyB0aGUgbmVhcmVzdCB3aGVuIGFjcm9zcyB0aGUgYW50aW1lcmlkaWFuXG4gICAgbGV0IHdyYXAgPSAwO1xuICAgIGNvbnN0IHRpbGVDZW50ZXJYRnJvbUNhbWVyYSA9ICh3ICsgZSkgLyAyIC0gY2FtWDtcbiAgICBpZiAodGlsZUNlbnRlclhGcm9tQ2FtZXJhID4gLjUpIHtcbiAgICAgICAgd3JhcCA9IC0xO1xuICAgIH0gZWxzZSBpZiAodGlsZUNlbnRlclhGcm9tQ2FtZXJhIDwgLS41KSB7XG4gICAgICAgIHdyYXAgPSAxO1xuICAgIH1cblxuICAgIGNhbVggKj0gbnVtVGlsZXM7XG4gICAgY2FtWSAqPSBudW1UaWxlcztcblxuICAgIC8vICBUcmFuc2Zvcm0gTWVyY2F0b3IgY29vcmRpbmF0ZXMgdG8gcG9pbnRzIG9uIHRoZSBwbGFuZSB0YW5nZW50IHRvIHRoZSBnbG9iZSBhdCBjYW1lcmFDZW50ZXIuXG4gICAgdyA9ICgodyArIHdyYXApICogbnVtVGlsZXMgLSBjYW1YKSAqIG1lcmNhdG9yU2NhbGUgKyBjYW1YO1xuICAgIGUgPSAoKGUgKyB3cmFwKSAqIG51bVRpbGVzIC0gY2FtWCkgKiBtZXJjYXRvclNjYWxlICsgY2FtWDtcbiAgICBuID0gKG4gKiBudW1UaWxlcyAtIGNhbVkpICogbWVyY2F0b3JTY2FsZSArIGNhbVk7XG4gICAgcyA9IChzICogbnVtVGlsZXMgLSBjYW1ZKSAqIG1lcmNhdG9yU2NhbGUgKyBjYW1ZO1xuXG4gICAgcmV0dXJuIFtbdywgcywgMF0sXG4gICAgICAgIFtlLCBzLCAwXSxcbiAgICAgICAgW2UsIG4sIDBdLFxuICAgICAgICBbdywgbiwgMF1dO1xufVxuXG5mdW5jdGlvbiBib3VuZHNUb0VDRUYoYm91bmRzOiBMbmdMYXRCb3VuZHMpOiBBcnJheTxWZWMzPiB7XG4gICAgY29uc3QgbnkgPSBkZWdUb1JhZChib3VuZHMuZ2V0Tm9ydGgoKSk7XG4gICAgY29uc3Qgc3kgPSBkZWdUb1JhZChib3VuZHMuZ2V0U291dGgoKSk7XG4gICAgY29uc3QgY29zTiA9IE1hdGguY29zKG55KTtcbiAgICBjb25zdCBjb3NTID0gTWF0aC5jb3Moc3kpO1xuICAgIGNvbnN0IHNpbk4gPSBNYXRoLnNpbihueSk7XG4gICAgY29uc3Qgc2luUyA9IE1hdGguc2luKHN5KTtcbiAgICBjb25zdCB3ID0gYm91bmRzLmdldFdlc3QoKTtcbiAgICBjb25zdCBlID0gYm91bmRzLmdldEVhc3QoKTtcbiAgICByZXR1cm4gW1xuICAgICAgICBjc0xhdExuZ1RvRUNFRihjb3NTLCBzaW5TLCB3KSxcbiAgICAgICAgY3NMYXRMbmdUb0VDRUYoY29zUywgc2luUywgZSksXG4gICAgICAgIGNzTGF0TG5nVG9FQ0VGKGNvc04sIHNpbk4sIGUpLFxuICAgICAgICBjc0xhdExuZ1RvRUNFRihjb3NOLCBzaW5OLCB3KVxuICAgIF07XG59XG5cbmZ1bmN0aW9uIGNzTGF0TG5nVG9FQ0VGKGNvc0xhdDogbnVtYmVyLCBzaW5MYXQ6IG51bWJlciwgbG5nOiBudW1iZXIsIHJhZGl1czogbnVtYmVyID0gR0xPQkVfUkFESVVTKTogVmVjMyB7XG4gICAgbG5nID0gZGVnVG9SYWQobG5nKTtcblxuICAgIC8vIENvbnZlcnQgbGF0ICYgbG5nIHRvIHNwaGVyaWNhbCByZXByZXNlbnRhdGlvbi4gVXNlIHpvb209MCBhcyBhIHJlZmVyZW5jZVxuICAgIGNvbnN0IHN4ID0gY29zTGF0ICogTWF0aC5zaW4obG5nKSAqIHJhZGl1cztcbiAgICBjb25zdCBzeSA9IC1zaW5MYXQgKiByYWRpdXM7XG4gICAgY29uc3Qgc3ogPSBjb3NMYXQgKiBNYXRoLmNvcyhsbmcpICogcmFkaXVzO1xuXG4gICAgcmV0dXJuIFtzeCwgc3ksIHN6XTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGVjZWZUb0xhdExuZyhbeCwgeSwgel06IEFycmF5PG51bWJlcj4pOiBMbmdMYXQge1xuICAgIGNvbnN0IHJhZGl1cyA9IE1hdGguaHlwb3QoeCwgeSwgeik7XG4gICAgY29uc3QgbG5nID0gTWF0aC5hdGFuMih4LCB6KTtcbiAgICBjb25zdCBsYXQgPSBNYXRoLlBJICogMC41IC0gTWF0aC5hY29zKC15IC8gcmFkaXVzKTtcblxuICAgIHJldHVybiBuZXcgTG5nTGF0KHJhZFRvRGVnKGxuZyksIHJhZFRvRGVnKGxhdCkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbGF0TG5nVG9FQ0VGKGxhdDogbnVtYmVyLCBsbmc6IG51bWJlciwgcmFkaXVzPzogbnVtYmVyKTogVmVjMyB7XG4gICAgYXNzZXJ0KGxhdCA8PSA5MCAmJiBsYXQgPj0gLTkwLCAnTGF0dGl0dWRlIG11c3QgYmUgYmV0d2VlbiAtOTAgYW5kIDkwJyk7XG4gICAgcmV0dXJuIGNzTGF0TG5nVG9FQ0VGKE1hdGguY29zKGRlZ1RvUmFkKGxhdCkpLCBNYXRoLnNpbihkZWdUb1JhZChsYXQpKSwgbG5nLCByYWRpdXMpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdGlsZUNvb3JkVG9FQ0VGKHg6IG51bWJlciwgeTogbnVtYmVyLCBpZDogQ2Fub25pY2FsVGlsZUlELCByYWRpdXM/OiBudW1iZXIpOiBWZWMzIHtcbiAgICBjb25zdCB0aWxlQ291bnQgPSAxIDw8IGlkLno7XG4gICAgY29uc3QgbWVyY2F0b3JYID0gKHggLyBFWFRFTlQgKyBpZC54KSAvIHRpbGVDb3VudDtcbiAgICBjb25zdCBtZXJjYXRvclkgPSAoeSAvIEVYVEVOVCArIGlkLnkpIC8gdGlsZUNvdW50O1xuICAgIGNvbnN0IGxhdCA9IGxhdEZyb21NZXJjYXRvclkobWVyY2F0b3JZKTtcbiAgICBjb25zdCBsbmcgPSBsbmdGcm9tTWVyY2F0b3JYKG1lcmNhdG9yWCk7XG4gICAgY29uc3QgcG9zID0gbGF0TG5nVG9FQ0VGKGxhdCwgbG5nLCByYWRpdXMpO1xuICAgIHJldHVybiBwb3M7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnbG9iZUVDRUZPcmlnaW4odGlsZU1hdHJpeDogTWF0NCwgaWQ6IFVud3JhcHBlZFRpbGVJRCk6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSB7XG4gICAgY29uc3Qgb3JpZ2luID0gWzAsIDAsIDBdO1xuICAgIGNvbnN0IGJvdW5kcyA9IGdsb2JlVGlsZUJvdW5kcyhpZC5jYW5vbmljYWwpO1xuICAgIGNvbnN0IG5vcm1hbGl6YXRpb25NYXRyaXggPSBnbG9iZU5vcm1hbGl6ZUVDRUYoYm91bmRzKTtcbiAgICB2ZWMzLnRyYW5zZm9ybU1hdDQob3JpZ2luLCBvcmlnaW4sIG5vcm1hbGl6YXRpb25NYXRyaXgpO1xuICAgIHZlYzMudHJhbnNmb3JtTWF0NChvcmlnaW4sIG9yaWdpbiwgdGlsZU1hdHJpeCk7XG4gICAgcmV0dXJuIG9yaWdpbjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdsb2JlRUNFRk5vcm1hbGl6YXRpb25TY2FsZSh7bWluLCBtYXh9OiBBYWJiKTogbnVtYmVyIHtcbiAgICByZXR1cm4gR0xPQkVfTk9STUFMSVpBVElPTl9NQVNLIC8gTWF0aC5tYXgobWF4WzBdIC0gbWluWzBdLCBtYXhbMV0gLSBtaW5bMV0sIG1heFsyXSAtIG1pblsyXSk7XG59XG5cbi8vIGF2b2lkIHJlZHVuZGFudCBhbGxvY2F0aW9ucyBieSBzaGFyaW5nIHRoZSBzYW1lIHR5cGVkIGFycmF5IGZvciBub3JtYWxpemF0aW9uL2Rlbm9ybWFsaXphdGlvbiBtYXRyaWNlcztcbi8vIHdlIG5ldmVyIHVzZSBtdWx0aXBsZSBpbnN0YW5jZXMgb2YgdGhlc2UgYXQgdGhlIHNhbWUgdGltZSwgYnV0IHRoaXMgbWlnaHQgY2hhbmdlLCBzbyBsZXQncyBiZSBjYXJlZnVsIGhlcmUhXG5jb25zdCB0ZW1wTWF0cml4ID0gbmV3IEZsb2F0NjRBcnJheSgxNik7XG5cbmV4cG9ydCBmdW5jdGlvbiBnbG9iZU5vcm1hbGl6ZUVDRUYoYm91bmRzOiBBYWJiKTogRmxvYXQ2NEFycmF5IHtcbiAgICBjb25zdCBzY2FsZSA9IGdsb2JlRUNFRk5vcm1hbGl6YXRpb25TY2FsZShib3VuZHMpO1xuICAgIGNvbnN0IG0gPSBtYXQ0LmZyb21TY2FsaW5nKHRlbXBNYXRyaXgsIFtzY2FsZSwgc2NhbGUsIHNjYWxlXSk7XG4gICAgcmV0dXJuIG1hdDQudHJhbnNsYXRlKG0sIG0sIHZlYzMubmVnYXRlKFtdLCBib3VuZHMubWluKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnbG9iZURlbm9ybWFsaXplRUNFRihib3VuZHM6IEFhYmIpOiBGbG9hdDY0QXJyYXkge1xuICAgIGNvbnN0IG0gPSBtYXQ0LmZyb21UcmFuc2xhdGlvbih0ZW1wTWF0cml4LCBib3VuZHMubWluKTtcbiAgICBjb25zdCBzY2FsZSA9IDEuMCAvIGdsb2JlRUNFRk5vcm1hbGl6YXRpb25TY2FsZShib3VuZHMpO1xuICAgIHJldHVybiBtYXQ0LnNjYWxlKG0sIG0sIFtzY2FsZSwgc2NhbGUsIHNjYWxlXSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnbG9iZUVDRUZVbml0c1RvUGl4ZWxTY2FsZSh3b3JsZFNpemU6IG51bWJlcik6IG51bWJlciB7XG4gICAgY29uc3QgbG9jYWxSYWRpdXMgPSBFWFRFTlQgLyAoMi4wICogTWF0aC5QSSk7XG4gICAgY29uc3Qgd3NSYWRpdXMgPSB3b3JsZFNpemUgLyAoMi4wICogTWF0aC5QSSk7XG4gICAgcmV0dXJuIHdzUmFkaXVzIC8gbG9jYWxSYWRpdXM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnbG9iZVBpeGVsc1RvVGlsZVVuaXRzKHpvb206IG51bWJlciwgaWQ6IENhbm9uaWNhbFRpbGVJRCk6IG51bWJlciB7XG4gICAgY29uc3QgZWNlZlBlclBpeGVsID0gRVhURU5UIC8gKFRJTEVfU0laRSAqIE1hdGgucG93KDIsIHpvb20pKTtcbiAgICBjb25zdCBub3JtQ29lZmYgPSBnbG9iZUVDRUZOb3JtYWxpemF0aW9uU2NhbGUoZ2xvYmVUaWxlQm91bmRzKGlkKSk7XG5cbiAgICByZXR1cm4gZWNlZlBlclBpeGVsICogbm9ybUNvZWZmO1xufVxuXG5mdW5jdGlvbiBjYWxjdWxhdGVHbG9iZVBvc01hdHJpeCh4OiBudW1iZXIsIHk6IG51bWJlciwgd29ybGRTaXplOiBudW1iZXIsIGxuZzogbnVtYmVyLCBsYXQ6IG51bWJlcik6IEZsb2F0NjRBcnJheSB7XG4gICAgLy8gdHJhbnNmb3JtIHRoZSBnbG9iZSBmcm9tIHJlZmVyZW5jZSBjb29yZGluYXRlIHNwYWNlIHRvIHdvcmxkIHNwYWNlXG4gICAgY29uc3Qgc2NhbGUgPSBnbG9iZUVDRUZVbml0c1RvUGl4ZWxTY2FsZSh3b3JsZFNpemUpO1xuICAgIGNvbnN0IG9mZnNldCA9IFt4LCB5LCAtd29ybGRTaXplIC8gKDIuMCAqIE1hdGguUEkpXTtcbiAgICBjb25zdCBtID0gbWF0NC5pZGVudGl0eShuZXcgRmxvYXQ2NEFycmF5KDE2KSk7XG4gICAgbWF0NC50cmFuc2xhdGUobSwgbSwgb2Zmc2V0KTtcbiAgICBtYXQ0LnNjYWxlKG0sIG0sIFtzY2FsZSwgc2NhbGUsIHNjYWxlXSk7XG4gICAgbWF0NC5yb3RhdGVYKG0sIG0sIGRlZ1RvUmFkKC1sYXQpKTtcbiAgICBtYXQ0LnJvdGF0ZVkobSwgbSwgZGVnVG9SYWQoLWxuZykpO1xuICAgIHJldHVybiBtO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlR2xvYmVNYXRyaXgodHI6IFRyYW5zZm9ybSk6IEZsb2F0NjRBcnJheSB7XG4gICAgY29uc3Qge3gsIHl9ID0gdHIucG9pbnQ7XG4gICAgY29uc3Qge2xuZywgbGF0fSA9IHRyLl9jZW50ZXI7XG4gICAgcmV0dXJuIGNhbGN1bGF0ZUdsb2JlUG9zTWF0cml4KHgsIHksIHRyLndvcmxkU2l6ZSwgbG5nLCBsYXQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlR2xvYmVMYWJlbE1hdHJpeCh0cjogVHJhbnNmb3JtLCBpZDogQ2Fub25pY2FsVGlsZUlEKTogRmxvYXQ2NEFycmF5IHtcbiAgICBjb25zdCB7eCwgeX0gPSB0ci5wb2ludDtcblxuICAgIC8vIE1hcCBhbGlnbmVkIGxhYmVsIHNwYWNlIGZvciBnbG9iZSB2aWV3IGlzIHRoZSBub24tcm90YXRlZCBnbG9iZSBpdHNlbGYgaW4gcGl4ZWwgY29vcmRpbmF0ZXMuXG5cbiAgICAvLyBDYW1lcmEgaXMgbW92ZWQgY2xvc2VyIHRvd2FyZHMgdGhlIGdyb3VuZCBuZWFyIHBvbGVzIGFzIHBhcnQgb2ZcbiAgICAvLyBjb21wZXNhbnRpbmcgdGhlIHJlcHJvamVjdGlvbi4gVGhpcyBoYXMgdG8gYmUgY29tcGVuc2F0ZWQgZm9yIHRoZVxuICAgIC8vIG1hcCBhbGlnbmVkIGxhYmVsIHNwYWNlLiBXaGl0aG91dCB0aGlzIGxvZ2ljIG1hcCBhbGlnbmVkIHN5bWJvbHNcbiAgICAvLyB3b3VsZCBhcHBlYXIgbGFyZ2VyIHRoYW4gaW50ZW5kZWQuXG4gICAgY29uc3QgbSA9IGNhbGN1bGF0ZUdsb2JlUG9zTWF0cml4KHgsIHksIHRyLndvcmxkU2l6ZSAvIHRyLl9waXhlbHNQZXJNZXJjYXRvclBpeGVsLCAwLCAwKTtcbiAgICByZXR1cm4gbWF0NC5tdWx0aXBseShtLCBtLCBnbG9iZURlbm9ybWFsaXplRUNFRihnbG9iZVRpbGVCb3VuZHMoaWQpKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjYWxjdWxhdGVHbG9iZU1lcmNhdG9yTWF0cml4KHRyOiBUcmFuc2Zvcm0pOiBGbG9hdDMyQXJyYXkge1xuICAgIGNvbnN0IHpTY2FsZSA9IHRyLnBpeGVsc1Blck1ldGVyO1xuICAgIGNvbnN0IHdzID0gelNjYWxlIC8gbWVyY2F0b3JaZnJvbUFsdGl0dWRlKDEsIHRyLmNlbnRlci5sYXQpO1xuXG4gICAgY29uc3QgcG9zTWF0cml4ID0gbWF0NC5pZGVudGl0eShuZXcgRmxvYXQ2NEFycmF5KDE2KSk7XG4gICAgbWF0NC50cmFuc2xhdGUocG9zTWF0cml4LCBwb3NNYXRyaXgsIFt0ci5wb2ludC54LCB0ci5wb2ludC55LCAwLjBdKTtcbiAgICBtYXQ0LnNjYWxlKHBvc01hdHJpeCwgcG9zTWF0cml4LCBbd3MsIHdzLCB6U2NhbGVdKTtcblxuICAgIHJldHVybiBGbG9hdDMyQXJyYXkuZnJvbShwb3NNYXRyaXgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2xvYmVUb01lcmNhdG9yVHJhbnNpdGlvbih6b29tOiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiBzbW9vdGhzdGVwKEdMT0JFX1pPT01fVEhSRVNIT0xEX01JTiwgR0xPQkVfWk9PTV9USFJFU0hPTERfTUFYLCB6b29tKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdsb2JlTWF0cml4Rm9yVGlsZShpZDogQ2Fub25pY2FsVGlsZUlELCBnbG9iZU1hdHJpeDogRmxvYXQ2NEFycmF5KTogRmxvYXQzMkFycmF5IHtcbiAgICBjb25zdCBkZWNvZGUgPSBnbG9iZURlbm9ybWFsaXplRUNFRihnbG9iZVRpbGVCb3VuZHMoaWQpKTtcbiAgICByZXR1cm4gbWF0NC5tdWwobWF0NC5jcmVhdGUoKSwgZ2xvYmVNYXRyaXgsIGRlY29kZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnbG9iZVBvbGVNYXRyaXhGb3JUaWxlKHo6IG51bWJlciwgeDogbnVtYmVyLCB0cjogVHJhbnNmb3JtKTogRmxvYXQzMkFycmF5IHtcbiAgICBjb25zdCBwb2xlTWF0cml4ID0gbWF0NC5pZGVudGl0eShuZXcgRmxvYXQ2NEFycmF5KDE2KSk7XG5cbiAgICAvLyBSb3RhdGUgdGhlIHBvbGUgdHJpYW5nbGUgZmFuIHRvIHRoZSBjb3JyZWN0IGxvY2F0aW9uXG4gICAgY29uc3QgbnVtVGlsZXMgPSAxIDw8IHo7XG4gICAgY29uc3QgeE9mZnNldEFuZ2xlID0gKHggLyBudW1UaWxlcyAtIDAuNSkgKiBNYXRoLlBJICogMi4wO1xuICAgIG1hdDQucm90YXRlWShwb2xlTWF0cml4LCB0ci5nbG9iZU1hdHJpeCwgeE9mZnNldEFuZ2xlKTtcblxuICAgIHJldHVybiBGbG9hdDMyQXJyYXkuZnJvbShwb2xlTWF0cml4KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdsb2JlVXNlQ3VzdG9tQW50aUFsaWFzaW5nKHBhaW50ZXI6IFBhaW50ZXIsIGNvbnRleHQ6IENvbnRleHQsIHRyYW5zZm9ybTogVHJhbnNmb3JtKTogYm9vbGVhbiB7XG4gICAgY29uc3QgdHJhbnNpdGlvblQgPSBnbG9iZVRvTWVyY2F0b3JUcmFuc2l0aW9uKHRyYW5zZm9ybS56b29tKTtcbiAgICBjb25zdCB1c2VDb250ZXh0QUEgPSBwYWludGVyLnN0eWxlLm1hcC5fYW50aWFsaWFzO1xuICAgIGNvbnN0IGhhc1N0YW5kYXJkRGVyaXZhdGl2ZXMgPSAhIWNvbnRleHQuZXh0U3RhbmRhcmREZXJpdmF0aXZlcztcbiAgICBjb25zdCBkaXNhYmxlZCA9IGNvbnRleHQuZXh0U3RhbmRhcmREZXJpdmF0aXZlc0ZvcmNlT2ZmIHx8IChwYWludGVyLnRlcnJhaW4gJiYgcGFpbnRlci50ZXJyYWluLmV4YWdnZXJhdGlvbigpID4gMC4wKTtcbiAgICByZXR1cm4gdHJhbnNpdGlvblQgPT09IDAuMCAmJiAhdXNlQ29udGV4dEFBICYmICFkaXNhYmxlZCAmJiBoYXNTdGFuZGFyZERlcml2YXRpdmVzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0R3JpZE1hdHJpeChpZDogQ2Fub25pY2FsVGlsZUlELCBib3VuZHM6IExuZ0xhdEJvdW5kcywgbGF0aXR1ZGluYWxMb2Q6IG51bWJlciwgd29ybGRTaXplOiBudW1iZXIpOiBNYXQ0IHtcbiAgICBjb25zdCBuID0gYm91bmRzLmdldE5vcnRoKCk7XG4gICAgY29uc3QgcyA9IGJvdW5kcy5nZXRTb3V0aCgpO1xuICAgIGNvbnN0IHcgPSBib3VuZHMuZ2V0V2VzdCgpO1xuICAgIGNvbnN0IGUgPSBib3VuZHMuZ2V0RWFzdCgpO1xuXG4gICAgLy8gQ29uc3RydWN0IHRyYW5zZm9ybWF0aW9uIG1hdHJpeCBmb3IgY29udmVydGluZyB0aWxlIGNvb3JkaW5hdGVzIGludG8gTGF0TG5nc1xuICAgIGNvbnN0IHRpbGVzID0gMSA8PCBpZC56O1xuICAgIGNvbnN0IHRpbGVXaWR0aCA9IGUgLSB3O1xuICAgIGNvbnN0IHRpbGVIZWlnaHQgPSBuIC0gcztcbiAgICBjb25zdCB0aWxlVG9MbmcgPSB0aWxlV2lkdGggLyBHTE9CRV9WRVJURVhfR1JJRF9TSVpFO1xuICAgIGNvbnN0IHRpbGVUb0xhdCA9IC10aWxlSGVpZ2h0IC8gR0xPQkVfTEFUSVRVRElOQUxfR1JJRF9MT0RfVEFCTEVbbGF0aXR1ZGluYWxMb2RdO1xuXG4gICAgY29uc3QgbWF0cml4ID0gWzAsIHRpbGVUb0xuZywgMCwgdGlsZVRvTGF0LCAwLCAwLCBuLCB3LCAwXTtcblxuICAgIGlmIChpZC56ID4gMCkge1xuICAgICAgICAvLyBBZGQgc2xpZ2h0IHBhZGRpbmcgdG8gcGF0Y2ggc2VhbXMgYmV0d2VlbiB0aWxlcy5cbiAgICAgICAgLy8gVGhpcyBpcyBkb25lIGJ5IGV4dHJ1ZGluZyB2ZXJ0aWNlcyBieSBhIGZpeGVkIGFtb3VudC4gUGl4ZWwgcGFkZGluZ1xuICAgICAgICAvLyBpcyBmaXJzdCBjb252ZXJ0ZWQgdG8gZGVncmVlcyBhbmQgdGhlbiB0byB0aWxlIHVuaXRzIGJlZm9yZSBiZWluZ1xuICAgICAgICAvLyBhcHBsaWVkIHRvIHRoZSBmaW5hbCB0cmFuc2Zvcm1hdGlvbiBtYXRyaXguXG4gICAgICAgIGNvbnN0IHBpeGVsUGFkZGluZyA9IDAuNTtcbiAgICAgICAgY29uc3QgcGFkZGluZyA9IHBpeGVsUGFkZGluZyAqIDM2MC4wIC8gd29ybGRTaXplO1xuXG4gICAgICAgIGNvbnN0IHhTY2FsZSA9IHBhZGRpbmcgLyB0aWxlV2lkdGggKyAxO1xuICAgICAgICBjb25zdCB5U2NhbGUgPSBwYWRkaW5nIC8gdGlsZUhlaWdodCArIDE7XG4gICAgICAgIGNvbnN0IHBhZE1hdHJpeCA9IFt4U2NhbGUsIDAsIDAsIDAsIHlTY2FsZSwgMCwgLTAuNSAqIHBhZGRpbmcgLyB0aWxlVG9MbmcsIDAuNSAqIHBhZGRpbmcgLyB0aWxlVG9MYXQsIDFdO1xuXG4gICAgICAgIG1hdDMubXVsdGlwbHkobWF0cml4LCBtYXRyaXgsIHBhZE1hdHJpeCk7XG4gICAgfVxuXG4gICAgLy8gRW1iZWQgYWRkaXRpb25hbCB2YXJpYWJsZXMgdG8gdGhlIGxhc3Qgcm93IG9mIHRoZSBtYXRyaXhcbiAgICBtYXRyaXhbMl0gPSB0aWxlcztcbiAgICBtYXRyaXhbNV0gPSBpZC54O1xuICAgIG1hdHJpeFs4XSA9IGlkLnk7XG5cbiAgICByZXR1cm4gbWF0cml4O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TGF0aXR1ZGluYWxMb2QobGF0OiBudW1iZXIpOiBudW1iZXIge1xuICAgIGNvbnN0IFVQUEVSX0xBVElUVURFID0gTUFYX01FUkNBVE9SX0xBVElUVURFIC0gNS4wO1xuICAgIGxhdCA9IGNsYW1wKGxhdCwgLVVQUEVSX0xBVElUVURFLCBVUFBFUl9MQVRJVFVERSkgLyBVUFBFUl9MQVRJVFVERSAqIDkwLjA7XG4gICAgLy8gY29uc3QgdCA9IE1hdGgucG93KDEuMCAtIE1hdGguY29zKGRlZ1RvUmFkKGxhdCkpLCAyKTtcbiAgICBjb25zdCB0ID0gTWF0aC5wb3coTWF0aC5hYnMoTWF0aC5zaW4oZGVnVG9SYWQobGF0KSkpLCAzKTtcbiAgICBjb25zdCBsb2QgPSBNYXRoLnJvdW5kKHQgKiAoR0xPQkVfTEFUSVRVRElOQUxfR1JJRF9MT0RfVEFCTEUubGVuZ3RoIC0gMSkpO1xuICAgIHJldHVybiBsb2Q7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnbG9iZUNlbnRlclRvU2NyZWVuUG9pbnQodHI6IFRyYW5zZm9ybSk6IFBvaW50IHtcbiAgICBjb25zdCBwb3MgPSBbMCwgMCwgMF07XG4gICAgY29uc3QgbWF0cml4ID0gbWF0NC5pZGVudGl0eShuZXcgRmxvYXQ2NEFycmF5KDE2KSk7XG4gICAgbWF0NC5tdWx0aXBseShtYXRyaXgsIHRyLnBpeGVsTWF0cml4LCB0ci5nbG9iZU1hdHJpeCk7XG4gICAgdmVjMy50cmFuc2Zvcm1NYXQ0KHBvcywgcG9zLCBtYXRyaXgpO1xuICAgIHJldHVybiBuZXcgUG9pbnQocG9zWzBdLCBwb3NbMV0pO1xufVxuXG5mdW5jdGlvbiBjYW1lcmFQb3NpdGlvbkluRUNFRih0cjogVHJhbnNmb3JtKTogQXJyYXk8bnVtYmVyPiB7XG4gICAgLy8gSGVyZSBcImNlbnRlclwiIGlzIHRoZSBjZW50ZXIgb2YgdGhlIGdsb2JlLiBXZSByZWZlciB0byB0cmFuc2Zvcm0uX2NlbnRlclxuICAgIC8vICh0aGUgc3VyZmFjZSBvZiB0aGUgbWFwIG9uIHRoZSBjZW50ZXIgb2YgdGhlIHNjcmVlbikgYXMgXCJwaXZvdFwiIHRvIGF2b2lkIGNvbmZ1c2lvbi5cbiAgICBjb25zdCBjZW50ZXJUb1Bpdm90ID0gbGF0TG5nVG9FQ0VGKHRyLl9jZW50ZXIubGF0LCB0ci5fY2VudGVyLmxuZyk7XG5cbiAgICAvLyBTZXQgYXhpcyB0byBFYXN0LVdlc3QgbGluZSB0YW5nZW50IHRvIHNwaGVyZSBhdCBwaXZvdFxuICAgIGNvbnN0IHNvdXRoID0gdmVjMy5mcm9tVmFsdWVzKDAsIDEsIDApO1xuICAgIGxldCBheGlzID0gdmVjMy5jcm9zcyhbXSwgc291dGgsIGNlbnRlclRvUGl2b3QpO1xuXG4gICAgLy8gUm90YXRlIGF4aXMgYXJvdW5kIHBpdm90IGJ5IGJlYXJpbmdcbiAgICBjb25zdCByb3RhdGlvbiA9IG1hdDQuZnJvbVJvdGF0aW9uKFtdLCAtdHIuYW5nbGUsIGNlbnRlclRvUGl2b3QpO1xuICAgIGF4aXMgPSB2ZWMzLnRyYW5zZm9ybU1hdDQoYXhpcywgYXhpcywgcm90YXRpb24pO1xuXG4gICAgLy8gUm90YXRlIGNhbWVyYSBhcm91bmQgYXhpcyBieSBwaXRjaFxuICAgIG1hdDQuZnJvbVJvdGF0aW9uKHJvdGF0aW9uLCAtdHIuX3BpdGNoLCBheGlzKTtcblxuICAgIGNvbnN0IHBpdm90VG9DYW1lcmEgPSB2ZWMzLm5vcm1hbGl6ZShbXSwgY2VudGVyVG9QaXZvdCk7XG4gICAgdmVjMy5zY2FsZShwaXZvdFRvQ2FtZXJhLCBwaXZvdFRvQ2FtZXJhLCBnbG9iZU1ldGVyc1RvRWNlZih0ci5jYW1lcmFUb0NlbnRlckRpc3RhbmNlIC8gdHIucGl4ZWxzUGVyTWV0ZXIpKTtcbiAgICB2ZWMzLnRyYW5zZm9ybU1hdDQocGl2b3RUb0NhbWVyYSwgcGl2b3RUb0NhbWVyYSwgcm90YXRpb24pO1xuXG4gICAgcmV0dXJuIHZlYzMuYWRkKFtdLCBjZW50ZXJUb1Bpdm90LCBwaXZvdFRvQ2FtZXJhKTtcbn1cblxuLy8gUmV0dXJuIHRoZSBhbmdsZSBvZiB0aGUgbm9ybWFsIHZlY3RvciBhdCBhIHBvaW50IG9uIHRoZSBnbG9iZSByZWxhdGl2ZSB0byB0aGUgY2FtZXJhLlxuLy8gaS5lLiBob3cgbXVjaCB0byB0aWx0IG1hcC1hbGlnbmVkIG1hcmtlcnMuXG5leHBvcnQgZnVuY3Rpb24gZ2xvYmVUaWx0QXRMbmdMYXQodHI6IFRyYW5zZm9ybSwgbG5nTGF0OiBMbmdMYXQpOiBudW1iZXIge1xuICAgIGNvbnN0IGNlbnRlclRvUG9pbnQgPSBsYXRMbmdUb0VDRUYobG5nTGF0LmxhdCwgbG5nTGF0LmxuZyk7XG4gICAgY29uc3QgY2VudGVyVG9DYW1lcmEgPSBjYW1lcmFQb3NpdGlvbkluRUNFRih0cik7XG4gICAgY29uc3QgcG9pbnRUb0NhbWVyYSA9IHZlYzMuc3VidHJhY3QoW10sIGNlbnRlclRvQ2FtZXJhLCBjZW50ZXJUb1BvaW50KTtcbiAgICByZXR1cm4gdmVjMy5hbmdsZShwb2ludFRvQ2FtZXJhLCBjZW50ZXJUb1BvaW50KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzTG5nTGF0QmVoaW5kR2xvYmUodHI6IFRyYW5zZm9ybSwgbG5nTGF0OiBMbmdMYXQpOiBib29sZWFuIHtcbiAgICAvLyBXZSBjb25zaWRlciAxJSBwYXN0IHRoZSBob3Jpem9uIG5vdCBvY2NsdWRlZCwgdGhpcyBhbGxvd3MgcG9wdXBzIHRvIGJlIGRyYWdnZWQgYXJvdW5kIHRoZSBnbG9iZSBlZGdlIHdpdGhvdXQgZmFkaW5nLlxuICAgIHJldHVybiAoZ2xvYmVUaWx0QXRMbmdMYXQodHIsIGxuZ0xhdCkgPiBNYXRoLlBJIC8gMiAqIDEuMDEpO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIHBvbGVzIGFyZSB2aXNpYmxlIGluc2lkZSB0aGUgY3VycmVudCB2aWV3cG9ydFxuICpcbiAqIEBwYXJhbSB7VHJhbnNmb3JtfSB0cmFuc2Zvcm0gVGhlIGN1cnJlbnQgbWFwIHRyYW5zZm9ybS5cbiAqIEByZXR1cm5zIHtbYm9vbGVhbiwgYm9vbGVhbl19IEEgdHVwbGUgb2YgYm9vbGVhbnMgW25vcnRoSW5WaWV3cG9ydCwgc291dGhJblZpZXdwb3J0XVxuICovXG5leHBvcnQgZnVuY3Rpb24gcG9sZXNJblZpZXdwb3J0KHRyOiBUcmFuc2Zvcm0pOiBbYm9vbGVhbiwgYm9vbGVhbl0ge1xuICAgIC8vIENyZWF0ZSBtYXRyaXggZnJvbSBFQ0VGIHRvIHNjcmVlbiBjb29yZGluYXRlc1xuICAgIGNvbnN0IGVjZWZUb1NjcmVlbk1hdHJpeCA9IG1hdDQuaWRlbnRpdHkobmV3IEZsb2F0NjRBcnJheSgxNikpO1xuICAgIG1hdDQubXVsdGlwbHkoZWNlZlRvU2NyZWVuTWF0cml4LCB0ci5waXhlbE1hdHJpeCwgdHIuZ2xvYmVNYXRyaXgpO1xuXG4gICAgY29uc3Qgbm9ydGggPSBbMCwgR0xPQkVfTUlOLCAwXTtcbiAgICBjb25zdCBzb3V0aCA9IFswLCBHTE9CRV9NQVgsIDBdO1xuXG4gICAgLy8gVHJhbnNsYXRlIHRoZSBwb2xlcyBmcm9tIEVDRUYgdG8gc2NyZWVuIGNvb3JkaW5hdGVzXG4gICAgdmVjMy50cmFuc2Zvcm1NYXQ0KG5vcnRoLCBub3J0aCwgZWNlZlRvU2NyZWVuTWF0cml4KTtcbiAgICB2ZWMzLnRyYW5zZm9ybU1hdDQoc291dGgsIHNvdXRoLCBlY2VmVG9TY3JlZW5NYXRyaXgpO1xuXG4gICAgLy8gQ2hlY2sgaWYgdGhlIHBvbGVzIGFyZSBpbnNpZGUgdGhlIHZpZXdwb3J0IGFuZCBub3QgYmVoaW5kIHRoZSBnbG9iZSBzdXJmYWNlXG4gICAgY29uc3Qgbm9ydGhJblZpZXdwb3J0ID1cbiAgICAgICAgbm9ydGhbMF0gPiAwICYmIG5vcnRoWzBdIDw9IHRyLndpZHRoICYmXG4gICAgICAgIG5vcnRoWzFdID4gMCAmJiBub3J0aFsxXSA8PSB0ci5oZWlnaHQgJiZcbiAgICAgICAgIWlzTG5nTGF0QmVoaW5kR2xvYmUodHIsIG5ldyBMbmdMYXQodHIuY2VudGVyLmxhdCwgOTApKTtcblxuICAgIGNvbnN0IHNvdXRoSW5WaWV3cG9ydCA9XG4gICAgICAgIHNvdXRoWzBdID4gMCAmJiBzb3V0aFswXSA8PSB0ci53aWR0aCAmJlxuICAgICAgICBzb3V0aFsxXSA+IDAgJiYgc291dGhbMV0gPD0gdHIuaGVpZ2h0ICYmXG4gICAgICAgICFpc0xuZ0xhdEJlaGluZEdsb2JlKHRyLCBuZXcgTG5nTGF0KHRyLmNlbnRlci5sYXQsIC05MCkpO1xuXG4gICAgcmV0dXJuIFtub3J0aEluVmlld3BvcnQsIHNvdXRoSW5WaWV3cG9ydF07XG59XG5cbmNvbnN0IFBPTEVfUkFEID0gZGVnVG9SYWQoODUuMCk7XG5jb25zdCBQT0xFX0NPUyA9IE1hdGguY29zKFBPTEVfUkFEKTtcbmNvbnN0IFBPTEVfU0lOID0gTWF0aC5zaW4oUE9MRV9SQUQpO1xuXG4vLyBHZW5lcmF0ZSB0ZXJyYWluIGdyaWQgd2l0aCBlbWJlZGRlZCBza2lydHNcbmNvbnN0IEVNQkVEX1NLSVJUUyA9IHRydWU7XG5cbnR5cGUgR3JpZExvZFNlZ21lbnRzID0ge1xuICAgIHdpdGhvdXRTa2lydHM6IFNlZ21lbnRWZWN0b3IsXG4gICAgd2l0aFNraXJ0czogU2VnbWVudFZlY3RvclxufTtcblxudHlwZSBHcmlkV2l0aExvZHMgPSB7XG4gICAgdmVydGljZXM6IFBvc0FycmF5LFxuICAgIGluZGljZXM6IFRyaWFuZ2xlSW5kZXhBcnJheSxcbiAgICBzZWdtZW50czogQXJyYXk8R3JpZExvZFNlZ21lbnRzPlxufTtcblxuZXhwb3J0IGNsYXNzIEdsb2JlU2hhcmVkQnVmZmVycyB7XG4gICAgX3BvbGVOb3J0aFZlcnRleEJ1ZmZlcjogVmVydGV4QnVmZmVyO1xuICAgIF9wb2xlU291dGhWZXJ0ZXhCdWZmZXI6IFZlcnRleEJ1ZmZlcjtcbiAgICBfcG9sZUluZGV4QnVmZmVyOiBJbmRleEJ1ZmZlcjtcbiAgICBfcG9sZVNlZ21lbnRzOiBBcnJheTxTZWdtZW50VmVjdG9yPjtcblxuICAgIF9ncmlkQnVmZmVyOiBWZXJ0ZXhCdWZmZXI7XG4gICAgX2dyaWRJbmRleEJ1ZmZlcjogSW5kZXhCdWZmZXI7XG4gICAgX2dyaWRTZWdtZW50czogQXJyYXk8R3JpZExvZFNlZ21lbnRzPjtcblxuICAgIF93aXJlZnJhbWVJbmRleEJ1ZmZlcjogSW5kZXhCdWZmZXI7XG4gICAgX3dpcmVmcmFtZVNlZ21lbnRzOiBBcnJheTxTZWdtZW50VmVjdG9yPjtcblxuICAgIGNvbnN0cnVjdG9yKGNvbnRleHQ6IENvbnRleHQpIHtcbiAgICAgICAgdGhpcy5fY3JlYXRlR3JpZChjb250ZXh0KTtcbiAgICAgICAgdGhpcy5fY3JlYXRlUG9sZXMoY29udGV4dCk7XG4gICAgfVxuXG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5fcG9sZUluZGV4QnVmZmVyLmRlc3Ryb3koKTtcbiAgICAgICAgdGhpcy5fZ3JpZEJ1ZmZlci5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMuX2dyaWRJbmRleEJ1ZmZlci5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMuX3BvbGVOb3J0aFZlcnRleEJ1ZmZlci5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMuX3BvbGVTb3V0aFZlcnRleEJ1ZmZlci5kZXN0cm95KCk7XG4gICAgICAgIGZvciAoY29uc3Qgc2VnbWVudHMgb2YgdGhpcy5fcG9sZVNlZ21lbnRzKSBzZWdtZW50cy5kZXN0cm95KCk7XG4gICAgICAgIGZvciAoY29uc3Qgc2VnbWVudHMgb2YgdGhpcy5fZ3JpZFNlZ21lbnRzKSB7XG4gICAgICAgICAgICBzZWdtZW50cy53aXRoU2tpcnRzLmRlc3Ryb3koKTtcbiAgICAgICAgICAgIHNlZ21lbnRzLndpdGhvdXRTa2lydHMuZGVzdHJveSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuX3dpcmVmcmFtZUluZGV4QnVmZmVyKSB7XG4gICAgICAgICAgICB0aGlzLl93aXJlZnJhbWVJbmRleEJ1ZmZlci5kZXN0cm95KCk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHNlZ21lbnRzIG9mIHRoaXMuX3dpcmVmcmFtZVNlZ21lbnRzKSBzZWdtZW50cy5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBHZW5lcmF0ZSB0ZXJyYWluIGdyaWQgdmVydGljZXMgYW5kIGluZGljZXMgZm9yIGFsbCBMT0Qnc1xuICAgIC8vXG4gICAgLy8gR3JpZCB2ZXJ0aWNlcyBtZW1vcnkgbGF5b3V0OlxuICAgIC8vXG4gICAgLy8gICAgICAgICAgRmlyc3QgbGluZSBTa2lydFxuICAgIC8vICAgICAgICAgIOKUjOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUkFxuICAgIC8vICAgICAgICAgIOKUguKUjOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUkOKUglxuICAgIC8vIExlZnQgICAgIOKUguKUguKUvOKUvOKUvOKUvOKUvOKUvOKUvOKUvOKUvOKUvOKUvOKUvOKUvOKUguKUgiBSaWdodFxuICAgIC8vIEJvcmRlciAgIOKUguKUguKUvOKUvOKUvOKUvOKUvOKUvOKUvOKUvOKUvOKUvOKUvOKUvOKUvOKUguKUgiBCb3JkZXJcbiAgICAvLyBTa2lydCAgICDilILilJzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilKTilIIgU2tpcnRcbiAgICAvLyAgICAgICAgICDilILilIIgIE1haW4gR3JpZCAg4pSC4pSCXG4gICAgLy8gICAgICAgICAg4pSC4pSc4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSk4pSCXG4gICAgLy8gICAgICAgICAg4pSC4pSC4pS84pS84pS84pS84pS84pS84pS84pS84pS84pS84pS84pS84pS84pSC4pSCXG4gICAgLy8gICAgICAgICAg4pSC4pSC4pS84pS84pS84pS84pS84pS84pS84pS84pS84pS84pS84pS84pS84pSC4pSCXG4gICAgLy8gICAgICAgICAg4pSC4pSU4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSY4pSCXG4gICAgLy8gICAgICAgICAg4pSc4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSkXG4gICAgLy8gICAgICAgICAg4pSc4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSkXG4gICAgLy8gICAgICAgICAg4pSU4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSYXG4gICAgLy8gICAgICBCb3R0b20gU2tpcnQgPSBOdW1iZXIgb2YgTE9EJ3NcbiAgICAvL1xuICAgIF9maWxsR3JpZE1lc2hXaXRoTG9kcyhsb25naXR1ZGluYWxDZWxsc0NvdW50OiBudW1iZXIsIGxhdGl0dWRpbmFsTG9kczogbnVtYmVyW10pOiBHcmlkV2l0aExvZHMge1xuICAgICAgICBjb25zdCB2ZXJ0aWNlcyA9IG5ldyBQb3NBcnJheSgpO1xuICAgICAgICBjb25zdCBpbmRpY2VzID0gbmV3IFRyaWFuZ2xlSW5kZXhBcnJheSgpO1xuICAgICAgICBjb25zdCBzZWdtZW50czogQXJyYXk8R3JpZExvZFNlZ21lbnRzPiA9IFtdO1xuXG4gICAgICAgIGNvbnN0IHhWZXJ0aWNlcyA9IGxvbmdpdHVkaW5hbENlbGxzQ291bnQgKyAxICsgMiAqIChFTUJFRF9TS0lSVFMgPyAxIDogMCk7XG4gICAgICAgIGNvbnN0IHlWZXJ0aWNlc0hpZ2hMb2ROb1N0cmlwID0gbGF0aXR1ZGluYWxMb2RzWzBdICsgMTtcbiAgICAgICAgY29uc3QgeVZlcnRpY2VzSGlnaExvZFdpdGhTdHJpcCA9IGxhdGl0dWRpbmFsTG9kc1swXSArIDEgKyAoRU1CRURfU0tJUlRTID8gMSArIGxhdGl0dWRpbmFsTG9kcy5sZW5ndGggOiAwKTtcblxuICAgICAgICAvLyBJbmRleCBhZGp1c3RtZW50LCB1c2VkIHRvIG1ha2Ugc3RyaXAgKHgsIHkpIHZlcnRleCBpbnB1dCBhdHRyaWJ1dGUgZGF0YVxuICAgICAgICAvLyB0byBtYXRjaCBzYW1lIGRhdGEgb24gb3JkaW5hcnkgZ3JpZCBlZGdlc1xuICAgICAgICBjb25zdCBwcmVwYXJlVmVydGV4ID0gKHg6IG51bWJlciwgeTogbnVtYmVyLCBpc1NraXJ0OiBib29sZWFuKSA9PiB7XG4gICAgICAgICAgICBpZiAoIUVNQkVEX1NLSVJUUykgcmV0dXJuIFt4LCB5XTtcblxuICAgICAgICAgICAgbGV0IGFkanVzdGVkWCA9ICgoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHggPT09IHhWZXJ0aWNlcyAtIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHggLSAyO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoeCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4geDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4geCAtIDE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkoKTtcblxuICAgICAgICAgICAgLy8gU2tpcnQgZmFjdG9yIGlzIGludHJvZHVjZXMgYXMgYW4gb2Zmc2V0IHRvIHRoZSAueCBjb29yZGluYXRlLCBzaW1pbGFyIHRvIGhvdyBpdCdzIGRvbmUgZm9yIG1lcmNhdG9yIGdyaWRzXG4gICAgICAgICAgICBjb25zdCBza2lydE9mZnNldCA9IDI0NTc1O1xuICAgICAgICAgICAgYWRqdXN0ZWRYICs9IGlzU2tpcnQgPyBza2lydE9mZnNldCA6IDA7XG5cbiAgICAgICAgICAgIHJldHVybiBbYWRqdXN0ZWRYLCB5XTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBBZGQgZmlyc3QgaG9yaXpvbnRhbCBzdHJpcCBpZiBwcmVzZW50XG4gICAgICAgIGlmIChFTUJFRF9TS0lSVFMpIHtcbiAgICAgICAgICAgIGZvciAobGV0IHggPSAwOyB4IDwgeFZlcnRpY2VzOyArK3gpIHtcbiAgICAgICAgICAgICAgICB2ZXJ0aWNlcy5lbXBsYWNlQmFjayguLi5wcmVwYXJlVmVydGV4KHgsIDAsIHRydWUpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFkZCBtYWluIGdyaWQgcGFydCB3aXRoIHZlcnRpY2VzIHN0cmlwcyBlbWJlZGRlZFxuICAgICAgICBmb3IgKGxldCB5ID0gMDsgeSA8IHlWZXJ0aWNlc0hpZ2hMb2ROb1N0cmlwOyArK3kpIHtcbiAgICAgICAgICAgIGZvciAobGV0IHggPSAwOyB4IDwgeFZlcnRpY2VzOyArK3gpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBpc1NpZGVCb3JkZXIgPSAoeCA9PT0gMCB8fCB4ID09PSB4VmVydGljZXMgLSAxKTtcblxuICAgICAgICAgICAgICAgIHZlcnRpY2VzLmVtcGxhY2VCYWNrKC4uLnByZXBhcmVWZXJ0ZXgoeCwgeSwgaXNTaWRlQm9yZGVyICYmIEVNQkVEX1NLSVJUUykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gQWRkIGJvdHRvbSBzdHJpcHMgZm9yIGVhY2ggTE9EXG4gICAgICAgIGlmIChFTUJFRF9TS0lSVFMpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGxvZElkeCA9IDA7IGxvZElkeCA8IGxhdGl0dWRpbmFsTG9kcy5sZW5ndGg7ICsrbG9kSWR4KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbGFzdFlSb3dGb3JMb2QgPSBsYXRpdHVkaW5hbExvZHNbbG9kSWR4XTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCB4ID0gMDsgeCA8IHhWZXJ0aWNlczsgKyt4KSB7XG4gICAgICAgICAgICAgICAgICAgIHZlcnRpY2VzLmVtcGxhY2VCYWNrKC4uLnByZXBhcmVWZXJ0ZXgoeCwgbGFzdFlSb3dGb3JMb2QsIHRydWUpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGaWxsIHRyaWFuZ2xlc1xuICAgICAgICBmb3IgKGxldCBsb2RJZHggPSAwOyBsb2RJZHggPCBsYXRpdHVkaW5hbExvZHMubGVuZ3RoOyArK2xvZElkeCkge1xuICAgICAgICAgICAgY29uc3QgaW5kZXhPZmZzZXQgPSBpbmRpY2VzLmxlbmd0aDtcblxuICAgICAgICAgICAgY29uc3QgeVZlcnRpY2VzTG9kID0gbGF0aXR1ZGluYWxMb2RzW2xvZElkeF0gKyAxICsgMiAqIChFTUJFRF9TS0lSVFMgPyAxIDogMCk7XG5cbiAgICAgICAgICAgIGNvbnN0IHNraXJ0c09ubHlJbmRpY2VzID0gbmV3IFRyaWFuZ2xlSW5kZXhBcnJheSgpO1xuXG4gICAgICAgICAgICBmb3IgKGxldCB5ID0gMDsgeSA8IHlWZXJ0aWNlc0xvZCAtIDE7IHkrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGlzTGFzdExpbmUgPSAoeSA9PT0geVZlcnRpY2VzTG9kIC0gMik7XG4gICAgICAgICAgICAgICAgY29uc3Qgb2Zmc2V0VG9OZXh0Um93ID1cbiAgICAgICAgICAgICAgICAgICAgKGlzTGFzdExpbmUgJiYgRU1CRURfU0tJUlRTID9cbiAgICAgICAgICAgICAgICAgICAgICAgICh4VmVydGljZXMgKiAoeVZlcnRpY2VzSGlnaExvZFdpdGhTdHJpcCAtIGxhdGl0dWRpbmFsTG9kcy5sZW5ndGggKyBsb2RJZHggLSB5KSkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgeFZlcnRpY2VzKTtcblxuICAgICAgICAgICAgICAgIGZvciAobGV0IHggPSAwOyB4IDwgeFZlcnRpY2VzIC0gMTsgeCsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGlkeCA9IHkgKiB4VmVydGljZXMgKyB4O1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGlzU2tpcnQgPSBFTUJFRF9TS0lSVFMgJiYgKHkgPT09IDAgfHwgaXNMYXN0TGluZSB8fCB4ID09PSAwIHx8IHggPT09IHhWZXJ0aWNlcyAtIDIpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChpc1NraXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBza2lydHNPbmx5SW5kaWNlcy5lbXBsYWNlQmFjayhpZHggKyAxLCBpZHgsIGlkeCArIG9mZnNldFRvTmV4dFJvdyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBza2lydHNPbmx5SW5kaWNlcy5lbXBsYWNlQmFjayhpZHggKyBvZmZzZXRUb05leHRSb3csIGlkeCArIG9mZnNldFRvTmV4dFJvdyArIDEsIGlkeCArIDEpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5kaWNlcy5lbXBsYWNlQmFjayhpZHggKyAxLCBpZHgsIGlkeCArIG9mZnNldFRvTmV4dFJvdyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbmRpY2VzLmVtcGxhY2VCYWNrKGlkeCArIG9mZnNldFRvTmV4dFJvdywgaWR4ICsgb2Zmc2V0VG9OZXh0Um93ICsgMSwgaWR4ICsgMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFNlZ21lbnRzIGdyaWQgb25seVxuICAgICAgICAgICAgY29uc3Qgd2l0aG91dFNraXJ0cyA9IFNlZ21lbnRWZWN0b3Iuc2ltcGxlU2VnbWVudCgwLCBpbmRleE9mZnNldCwgdmVydGljZXMubGVuZ3RoLCBpbmRpY2VzLmxlbmd0aCAtIGluZGV4T2Zmc2V0KTtcblxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBza2lydHNPbmx5SW5kaWNlcy51aW50MTYubGVuZ3RoOyBpICs9IDMpIHtcbiAgICAgICAgICAgICAgICBpbmRpY2VzLmVtcGxhY2VCYWNrKHNraXJ0c09ubHlJbmRpY2VzLnVpbnQxNltpXSwgc2tpcnRzT25seUluZGljZXMudWludDE2W2kgKyAxXSwgc2tpcnRzT25seUluZGljZXMudWludDE2W2kgKyAyXSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFNlZ21lbnRzIGdyaWQgKyBza2lydHMgb25seVxuICAgICAgICAgICAgY29uc3Qgd2l0aFNraXJ0cyA9IFNlZ21lbnRWZWN0b3Iuc2ltcGxlU2VnbWVudCgwLCBpbmRleE9mZnNldCwgdmVydGljZXMubGVuZ3RoLCBpbmRpY2VzLmxlbmd0aCAtIGluZGV4T2Zmc2V0KTtcbiAgICAgICAgICAgIHNlZ21lbnRzLnB1c2goe3dpdGhvdXRTa2lydHMsIHdpdGhTa2lydHN9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7dmVydGljZXMsIGluZGljZXMsIHNlZ21lbnRzfTtcbiAgICB9XG5cbiAgICBfY3JlYXRlR3JpZChjb250ZXh0OiBDb250ZXh0KSB7XG4gICAgICAgIGNvbnN0IGdyaWRXaXRoTG9kcyA9IHRoaXMuX2ZpbGxHcmlkTWVzaFdpdGhMb2RzKEdMT0JFX1ZFUlRFWF9HUklEX1NJWkUsIEdMT0JFX0xBVElUVURJTkFMX0dSSURfTE9EX1RBQkxFKTtcbiAgICAgICAgdGhpcy5fZ3JpZFNlZ21lbnRzID0gZ3JpZFdpdGhMb2RzLnNlZ21lbnRzO1xuXG4gICAgICAgIHRoaXMuX2dyaWRCdWZmZXIgPSBjb250ZXh0LmNyZWF0ZVZlcnRleEJ1ZmZlcihncmlkV2l0aExvZHMudmVydGljZXMsIHBvc0F0dHJpYnV0ZXMubWVtYmVycyk7XG4gICAgICAgIHRoaXMuX2dyaWRJbmRleEJ1ZmZlciA9IGNvbnRleHQuY3JlYXRlSW5kZXhCdWZmZXIoZ3JpZFdpdGhMb2RzLmluZGljZXMsIHRydWUpO1xuICAgIH1cblxuICAgIF9jcmVhdGVQb2xlcyhjb250ZXh0OiBDb250ZXh0KSB7XG4gICAgICAgIGNvbnN0IHBvbGVJbmRpY2VzID0gbmV3IFRyaWFuZ2xlSW5kZXhBcnJheSgpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8PSBHTE9CRV9WRVJURVhfR1JJRF9TSVpFOyBpKyspIHtcbiAgICAgICAgICAgIHBvbGVJbmRpY2VzLmVtcGxhY2VCYWNrKDAsIGkgKyAxLCBpICsgMik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fcG9sZUluZGV4QnVmZmVyID0gY29udGV4dC5jcmVhdGVJbmRleEJ1ZmZlcihwb2xlSW5kaWNlcywgdHJ1ZSk7XG5cbiAgICAgICAgY29uc3Qgbm9ydGhWZXJ0aWNlcyA9IG5ldyBHbG9iZVZlcnRleEFycmF5KCk7XG4gICAgICAgIGNvbnN0IHNvdXRoVmVydGljZXMgPSBuZXcgR2xvYmVWZXJ0ZXhBcnJheSgpO1xuICAgICAgICBjb25zdCBwb2xlUHJpbWl0aXZlcyA9IEdMT0JFX1ZFUlRFWF9HUklEX1NJWkU7XG4gICAgICAgIGNvbnN0IHBvbGVWZXJ0aWNlcyA9IEdMT0JFX1ZFUlRFWF9HUklEX1NJWkUgKyAyO1xuICAgICAgICB0aGlzLl9wb2xlU2VnbWVudHMgPSBbXTtcblxuICAgICAgICBmb3IgKGxldCB6b29tID0gMCwgb2Zmc2V0ID0gMDsgem9vbSA8IEdMT0JFX1pPT01fVEhSRVNIT0xEX01JTjsgem9vbSsrKSB7XG4gICAgICAgICAgICBjb25zdCB0aWxlcyA9IDEgPDwgem9vbTtcbiAgICAgICAgICAgIGNvbnN0IGVuZEFuZ2xlID0gMzYwLjAgLyB0aWxlcztcblxuICAgICAgICAgICAgbm9ydGhWZXJ0aWNlcy5lbXBsYWNlQmFjaygwLCAtR0xPQkVfUkFESVVTLCAwLCAwLjUsIDApOyAvLyBwbGFjZSB0aGUgdGlwXG4gICAgICAgICAgICBzb3V0aFZlcnRpY2VzLmVtcGxhY2VCYWNrKDAsIC1HTE9CRV9SQURJVVMsIDAsIDAuNSwgMSk7XG5cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDw9IEdMT0JFX1ZFUlRFWF9HUklEX1NJWkU7IGkrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHV2WCA9IGkgLyBHTE9CRV9WRVJURVhfR1JJRF9TSVpFO1xuICAgICAgICAgICAgICAgIGNvbnN0IGFuZ2xlID0gaW50ZXJwb2xhdGUoMCwgZW5kQW5nbGUsIHV2WCk7XG4gICAgICAgICAgICAgICAgY29uc3QgW2d4LCBneSwgZ3pdID0gY3NMYXRMbmdUb0VDRUYoUE9MRV9DT1MsIFBPTEVfU0lOLCBhbmdsZSwgR0xPQkVfUkFESVVTKTtcbiAgICAgICAgICAgICAgICBub3J0aFZlcnRpY2VzLmVtcGxhY2VCYWNrKGd4LCBneSwgZ3osIHV2WCwgMCk7XG4gICAgICAgICAgICAgICAgc291dGhWZXJ0aWNlcy5lbXBsYWNlQmFjayhneCwgZ3ksIGd6LCB1dlgsIDEpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLl9wb2xlU2VnbWVudHMucHVzaChTZWdtZW50VmVjdG9yLnNpbXBsZVNlZ21lbnQob2Zmc2V0LCAwLCBwb2xlVmVydGljZXMsIHBvbGVQcmltaXRpdmVzKSk7XG5cbiAgICAgICAgICAgIG9mZnNldCArPSBwb2xlVmVydGljZXM7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9wb2xlTm9ydGhWZXJ0ZXhCdWZmZXIgPSBjb250ZXh0LmNyZWF0ZVZlcnRleEJ1ZmZlcihub3J0aFZlcnRpY2VzLCBnbG9iZUxheW91dEF0dHJpYnV0ZXMsIGZhbHNlKTtcbiAgICAgICAgdGhpcy5fcG9sZVNvdXRoVmVydGV4QnVmZmVyID0gY29udGV4dC5jcmVhdGVWZXJ0ZXhCdWZmZXIoc291dGhWZXJ0aWNlcywgZ2xvYmVMYXlvdXRBdHRyaWJ1dGVzLCBmYWxzZSk7XG4gICAgfVxuXG4gICAgZ2V0R3JpZEJ1ZmZlcnMobGF0aXR1ZGluYWxMb2Q6IG51bWJlciwgd2l0aFNraXJ0czogYm9vbGVhbik6IFtWZXJ0ZXhCdWZmZXIsIEluZGV4QnVmZmVyLCBTZWdtZW50VmVjdG9yXSB7XG4gICAgICAgIHJldHVybiBbdGhpcy5fZ3JpZEJ1ZmZlciwgdGhpcy5fZ3JpZEluZGV4QnVmZmVyLCB3aXRoU2tpcnRzID8gdGhpcy5fZ3JpZFNlZ21lbnRzW2xhdGl0dWRpbmFsTG9kXS53aXRoU2tpcnRzIDogdGhpcy5fZ3JpZFNlZ21lbnRzW2xhdGl0dWRpbmFsTG9kXS53aXRob3V0U2tpcnRzXTtcbiAgICB9XG5cbiAgICBnZXRQb2xlQnVmZmVycyh6OiBudW1iZXIpOiBbVmVydGV4QnVmZmVyLCBWZXJ0ZXhCdWZmZXIsIEluZGV4QnVmZmVyLCBTZWdtZW50VmVjdG9yXSB7XG4gICAgICAgIHJldHVybiBbdGhpcy5fcG9sZU5vcnRoVmVydGV4QnVmZmVyLCB0aGlzLl9wb2xlU291dGhWZXJ0ZXhCdWZmZXIsIHRoaXMuX3BvbGVJbmRleEJ1ZmZlciwgdGhpcy5fcG9sZVNlZ21lbnRzW3pdXTtcbiAgICB9XG5cbiAgICBnZXRXaXJlZmFtZUJ1ZmZlcnMoY29udGV4dDogQ29udGV4dCwgbG9kOiBudW1iZXIpOiBbVmVydGV4QnVmZmVyLCBJbmRleEJ1ZmZlciwgU2VnbWVudFZlY3Rvcl0ge1xuICAgICAgICBpZiAoIXRoaXMuX3dpcmVmcmFtZVNlZ21lbnRzKSB7XG4gICAgICAgICAgICBjb25zdCB3aXJlZnJhbWVJbmRpY2VzID0gbmV3IExpbmVJbmRleEFycmF5KCk7XG4gICAgICAgICAgICBjb25zdCBxdWFkRXh0ID0gR0xPQkVfVkVSVEVYX0dSSURfU0laRTtcbiAgICAgICAgICAgIGNvbnN0IHZlcnRleEV4dCA9IHF1YWRFeHQgKyAxICsgKEVNQkVEX1NLSVJUUyA/IDIgOiAwKTtcblxuICAgICAgICAgICAgY29uc3QgaXRlck9mZnNldCA9IEVNQkVEX1NLSVJUUyA/IDEgOiAwO1xuXG4gICAgICAgICAgICB0aGlzLl93aXJlZnJhbWVTZWdtZW50cyA9IFtdO1xuICAgICAgICAgICAgZm9yIChsZXQgayA9IDAsIHByaW1pdGl2ZU9mZnNldCA9IDA7IGsgPCBHTE9CRV9MQVRJVFVESU5BTF9HUklEX0xPRF9UQUJMRS5sZW5ndGg7IGsrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGxhdGl0dWRpbmFsTG9kID0gR0xPQkVfTEFUSVRVRElOQUxfR1JJRF9MT0RfVEFCTEVba107XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IGl0ZXJPZmZzZXQ7IGogPCBsYXRpdHVkaW5hbExvZCArIGl0ZXJPZmZzZXQ7IGorKykge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gaXRlck9mZnNldDsgaSA8IHF1YWRFeHQgKyBpdGVyT2Zmc2V0OyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gaiAqIHZlcnRleEV4dCArIGk7XG4gICAgICAgICAgICAgICAgICAgICAgICB3aXJlZnJhbWVJbmRpY2VzLmVtcGxhY2VCYWNrKGluZGV4LCBpbmRleCArIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgd2lyZWZyYW1lSW5kaWNlcy5lbXBsYWNlQmFjayhpbmRleCwgaW5kZXggKyB2ZXJ0ZXhFeHQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgd2lyZWZyYW1lSW5kaWNlcy5lbXBsYWNlQmFjayhpbmRleCwgaW5kZXggKyB2ZXJ0ZXhFeHQgKyAxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IG51bVZlcnRpY2VzID0gKGxhdGl0dWRpbmFsTG9kICsgMSkgKiB2ZXJ0ZXhFeHQ7XG4gICAgICAgICAgICAgICAgY29uc3QgbnVtUHJpbWl0aXZlcyA9IGxhdGl0dWRpbmFsTG9kICogcXVhZEV4dCAqIDM7XG5cbiAgICAgICAgICAgICAgICB0aGlzLl93aXJlZnJhbWVTZWdtZW50cy5wdXNoKFNlZ21lbnRWZWN0b3Iuc2ltcGxlU2VnbWVudCgwLCBwcmltaXRpdmVPZmZzZXQsIG51bVZlcnRpY2VzLCBudW1QcmltaXRpdmVzKSk7XG4gICAgICAgICAgICAgICAgcHJpbWl0aXZlT2Zmc2V0ICs9IG51bVByaW1pdGl2ZXM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuX3dpcmVmcmFtZUluZGV4QnVmZmVyID0gY29udGV4dC5jcmVhdGVJbmRleEJ1ZmZlcih3aXJlZnJhbWVJbmRpY2VzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW3RoaXMuX2dyaWRCdWZmZXIsIHRoaXMuX3dpcmVmcmFtZUluZGV4QnVmZmVyLCB0aGlzLl93aXJlZnJhbWVTZWdtZW50c1tsb2RdXTtcbiAgICB9XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge3dyYXB9IGZyb20gJy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQgTG5nTGF0Qm91bmRzIGZyb20gJy4vbG5nX2xhdF9ib3VuZHMuanMnO1xuaW1wb3J0IHtHTE9CRV9SQURJVVMsIGdsb2JlTWV0ZXJzVG9FY2VmLCBsYXRMbmdUb0VDRUZ9IGZyb20gJy4uL2dlby9wcm9qZWN0aW9uL2dsb2JlX3V0aWwuanMnO1xuXG4vKlxuKiBBcHByb3hpbWF0ZSByYWRpdXMgb2YgdGhlIGVhcnRoIGluIG1ldGVycy5cbiogVXNlcyB0aGUgV0dTLTg0IGFwcHJveGltYXRpb24uIFRoZSByYWRpdXMgYXQgdGhlIGVxdWF0b3IgaXMgfjYzNzgxMzcgYW5kIGF0IHRoZSBwb2xlcyBpcyB+NjM1Njc1Mi4gaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvV29ybGRfR2VvZGV0aWNfU3lzdGVtI1dHUzg0XG4qIDYzNzEwMDguOCBpcyBvbmUgcHVibGlzaGVkIFwiYXZlcmFnZSByYWRpdXNcIiBzZWUgaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRWFydGhfcmFkaXVzI01lYW5fcmFkaXVzLCBvciBmdHA6Ly9hdGhlbmEuZnN2LmN2dXQuY3ovWkZHL2dyczgwLU1vcml0ei5wZGYgcC40XG4qL1xuZXhwb3J0IGNvbnN0IGVhcnRoUmFkaXVzID0gNjM3MTAwOC44O1xuXG4vKlxuICogVGhlIGF2ZXJhZ2UgY2lyY3VtZmVyZW5jZSBvZiB0aGUgZWFydGggaW4gbWV0ZXJzLlxuICovXG5leHBvcnQgY29uc3QgZWFydGhDaXJjdW1mZXJlbmNlID0gMiAqIE1hdGguUEkgKiBlYXJ0aFJhZGl1cztcblxuLyoqXG4gKiBBIGBMbmdMYXRgIG9iamVjdCByZXByZXNlbnRzIGEgZ2l2ZW4gbG9uZ2l0dWRlIGFuZCBsYXRpdHVkZSBjb29yZGluYXRlLCBtZWFzdXJlZCBpbiBkZWdyZWVzLlxuICogVGhlc2UgY29vcmRpbmF0ZXMgdXNlIGxvbmdpdHVkZSwgbGF0aXR1ZGUgY29vcmRpbmF0ZSBvcmRlciAoYXMgb3Bwb3NlZCB0byBsYXRpdHVkZSwgbG9uZ2l0dWRlKVxuICogdG8gbWF0Y2ggdGhlIFtHZW9KU09OIHNwZWNpZmljYXRpb25dKGh0dHBzOi8vZGF0YXRyYWNrZXIuaWV0Zi5vcmcvZG9jL2h0bWwvcmZjNzk0NiNzZWN0aW9uLTQpLFxuICogd2hpY2ggaXMgZXF1aXZhbGVudCB0byB0aGUgT0dDOkNSUzg0IGNvb3JkaW5hdGUgcmVmZXJlbmNlIHN5c3RlbS5cbiAqXG4gKiBOb3RlIHRoYXQgYW55IE1hcGJveCBHTCBtZXRob2QgdGhhdCBhY2NlcHRzIGEgYExuZ0xhdGAgb2JqZWN0IGFzIGFuIGFyZ3VtZW50IG9yIG9wdGlvblxuICogY2FuIGFsc28gYWNjZXB0IGFuIGBBcnJheWAgb2YgdHdvIG51bWJlcnMgYW5kIHdpbGwgcGVyZm9ybSBhbiBpbXBsaWNpdCBjb252ZXJzaW9uLlxuICogVGhpcyBmbGV4aWJsZSB0eXBlIGlzIGRvY3VtZW50ZWQgYXMge0BsaW5rIExuZ0xhdExpa2V9LlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBsbmcgTG9uZ2l0dWRlLCBtZWFzdXJlZCBpbiBkZWdyZWVzLlxuICogQHBhcmFtIHtudW1iZXJ9IGxhdCBMYXRpdHVkZSwgbWVhc3VyZWQgaW4gZGVncmVlcy5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBsbCA9IG5ldyBtYXBib3hnbC5MbmdMYXQoLTEyMy45NzQ5LCA0MC43NzM2KTtcbiAqIGNvbnNvbGUubG9nKGxsLmxuZyk7IC8vID0gLTEyMy45NzQ5XG4gKiBAc2VlIFtFeGFtcGxlOiBHZXQgY29vcmRpbmF0ZXMgb2YgdGhlIG1vdXNlIHBvaW50ZXJdKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvbW91c2UtcG9zaXRpb24vKVxuICogQHNlZSBbRXhhbXBsZTogRGlzcGxheSBhIHBvcHVwXShodHRwczovL3d3dy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL3BvcHVwLylcbiAqIEBzZWUgW0V4YW1wbGU6IEhpZ2hsaWdodCBmZWF0dXJlcyB3aXRoaW4gYSBib3VuZGluZyBib3hdKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvdXNpbmctYm94LXF1ZXJ5cmVuZGVyZWRmZWF0dXJlcy8pXG4gKiBAc2VlIFtFeGFtcGxlOiBDcmVhdGUgYSB0aW1lbGluZSBhbmltYXRpb25dKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvdGltZWxpbmUtYW5pbWF0aW9uLylcbiAqL1xuY2xhc3MgTG5nTGF0IHtcbiAgICBsbmc6IG51bWJlcjtcbiAgICBsYXQ6IG51bWJlcjtcblxuICAgIGNvbnN0cnVjdG9yKGxuZzogbnVtYmVyLCBsYXQ6IG51bWJlcikge1xuICAgICAgICBpZiAoaXNOYU4obG5nKSB8fCBpc05hTihsYXQpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgTG5nTGF0IG9iamVjdDogKCR7bG5nfSwgJHtsYXR9KWApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubG5nID0gK2xuZztcbiAgICAgICAgdGhpcy5sYXQgPSArbGF0O1xuICAgICAgICBpZiAodGhpcy5sYXQgPiA5MCB8fCB0aGlzLmxhdCA8IC05MCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIExuZ0xhdCBsYXRpdHVkZSB2YWx1ZTogbXVzdCBiZSBiZXR3ZWVuIC05MCBhbmQgOTAnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBuZXcgYExuZ0xhdGAgb2JqZWN0IHdob3NlIGxvbmdpdHVkZSBpcyB3cmFwcGVkIHRvIHRoZSByYW5nZSAoLTE4MCwgMTgwKS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtMbmdMYXR9IFRoZSB3cmFwcGVkIGBMbmdMYXRgIG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGxsID0gbmV3IG1hcGJveGdsLkxuZ0xhdCgyODYuMDI1MSwgNDAuNzczNik7XG4gICAgICogY29uc3Qgd3JhcHBlZCA9IGxsLndyYXAoKTtcbiAgICAgKiBjb25zb2xlLmxvZyh3cmFwcGVkLmxuZyk7IC8vID0gLTczLjk3NDlcbiAgICAgKi9cbiAgICB3cmFwKCk6IExuZ0xhdCB7XG4gICAgICAgIHJldHVybiBuZXcgTG5nTGF0KHdyYXAodGhpcy5sbmcsIC0xODAsIDE4MCksIHRoaXMubGF0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBjb29yZGluYXRlcyByZXByZXNlbnRlZCBhcyBhbiBhcnJheSBvZiB0d28gbnVtYmVycy5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtBcnJheTxudW1iZXI+fSBUaGUgY29vcmRpbmF0ZXMgcmVwcmVzZXRlZCBhcyBhbiBhcnJheSBvZiBsb25naXR1ZGUgYW5kIGxhdGl0dWRlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgbGwgPSBuZXcgbWFwYm94Z2wuTG5nTGF0KC03My45NzQ5LCA0MC43NzM2KTtcbiAgICAgKiBsbC50b0FycmF5KCk7IC8vID0gWy03My45NzQ5LCA0MC43NzM2XVxuICAgICAqL1xuICAgIHRvQXJyYXkoKTogW251bWJlciwgbnVtYmVyXSB7XG4gICAgICAgIHJldHVybiBbdGhpcy5sbmcsIHRoaXMubGF0XTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBjb29yZGluYXRlcyByZXByZXNlbnQgYXMgYSBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgY29vcmRpbmF0ZXMgcmVwcmVzZW50ZWQgYXMgYSBzdHJpbmcgb2YgdGhlIGZvcm1hdCBgJ0xuZ0xhdChsbmcsIGxhdCknYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGxsID0gbmV3IG1hcGJveGdsLkxuZ0xhdCgtNzMuOTc0OSwgNDAuNzczNik7XG4gICAgICogbGwudG9TdHJpbmcoKTsgLy8gPSBcIkxuZ0xhdCgtNzMuOTc0OSwgNDAuNzczNilcIlxuICAgICAqL1xuICAgIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBgTG5nTGF0KCR7dGhpcy5sbmd9LCAke3RoaXMubGF0fSlgO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGFwcHJveGltYXRlIGRpc3RhbmNlIGJldHdlZW4gYSBwYWlyIG9mIGNvb3JkaW5hdGVzIGluIG1ldGVycy5cbiAgICAgKiBVc2VzIHRoZSBIYXZlcnNpbmUgRm9ybXVsYSAoZnJvbSBSLlcuIFNpbm5vdHQsIFwiVmlydHVlcyBvZiB0aGUgSGF2ZXJzaW5lXCIsIFNreSBhbmQgVGVsZXNjb3BlLCB2b2wuIDY4LCBuby4gMiwgMTk4NCwgcC4gMTU5KS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7TG5nTGF0fSBsbmdMYXQgQ29vcmRpbmF0ZXMgdG8gY29tcHV0ZSB0aGUgZGlzdGFuY2UgdG8uXG4gICAgICogQHJldHVybnMge251bWJlcn0gRGlzdGFuY2UgaW4gbWV0ZXJzIGJldHdlZW4gdGhlIHR3byBjb29yZGluYXRlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG5ld1lvcmsgPSBuZXcgbWFwYm94Z2wuTG5nTGF0KC03NC4wMDYwLCA0MC43MTI4KTtcbiAgICAgKiBjb25zdCBsb3NBbmdlbGVzID0gbmV3IG1hcGJveGdsLkxuZ0xhdCgtMTE4LjI0MzcsIDM0LjA1MjIpO1xuICAgICAqIG5ld1lvcmsuZGlzdGFuY2VUbyhsb3NBbmdlbGVzKTsgLy8gPSAzOTM1NzUxLjY5MDg5Mzk4NywgXCJ0cnVlIGRpc3RhbmNlXCIgdXNpbmcgYSBub24tc3BoZXJpY2FsIGFwcHJveGltYXRpb24gaXMgfjM5NjZrbVxuICAgICAqL1xuICAgIGRpc3RhbmNlVG8obG5nTGF0OiBMbmdMYXQpOiBudW1iZXIge1xuICAgICAgICBjb25zdCByYWQgPSBNYXRoLlBJIC8gMTgwO1xuICAgICAgICBjb25zdCBsYXQxID0gdGhpcy5sYXQgKiByYWQ7XG4gICAgICAgIGNvbnN0IGxhdDIgPSBsbmdMYXQubGF0ICogcmFkO1xuICAgICAgICBjb25zdCBhID0gTWF0aC5zaW4obGF0MSkgKiBNYXRoLnNpbihsYXQyKSArIE1hdGguY29zKGxhdDEpICogTWF0aC5jb3MobGF0MikgKiBNYXRoLmNvcygobG5nTGF0LmxuZyAtIHRoaXMubG5nKSAqIHJhZCk7XG5cbiAgICAgICAgY29uc3QgbWF4TWV0ZXJzID0gZWFydGhSYWRpdXMgKiBNYXRoLmFjb3MoTWF0aC5taW4oYSwgMSkpO1xuICAgICAgICByZXR1cm4gbWF4TWV0ZXJzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBgTG5nTGF0Qm91bmRzYCBmcm9tIHRoZSBjb29yZGluYXRlcyBleHRlbmRlZCBieSBhIGdpdmVuIGByYWRpdXNgLiBUaGUgcmV0dXJuZWQgYExuZ0xhdEJvdW5kc2AgY29tcGxldGVseSBjb250YWlucyB0aGUgYHJhZGl1c2AuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3JhZGl1cz0wXSBEaXN0YW5jZSBpbiBtZXRlcnMgZnJvbSB0aGUgY29vcmRpbmF0ZXMgdG8gZXh0ZW5kIHRoZSBib3VuZHMuXG4gICAgICogQHJldHVybnMge0xuZ0xhdEJvdW5kc30gQSBuZXcgYExuZ0xhdEJvdW5kc2Agb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgY29vcmRpbmF0ZXMgZXh0ZW5kZWQgYnkgdGhlIGByYWRpdXNgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgbGwgPSBuZXcgbWFwYm94Z2wuTG5nTGF0KC03My45NzQ5LCA0MC43NzM2KTtcbiAgICAgKiBsbC50b0JvdW5kcygxMDApLnRvQXJyYXkoKTsgLy8gPSBbWy03My45NzUwMTg2MjE0MTMyOCwgNDAuNzczNTEwMTY4NDcyMjldLCBbLTczLjk3NDc4MTM3ODU4NjczLCA0MC43NzM2ODk4MzE1Mjc3MV1dXG4gICAgICovXG4gICAgdG9Cb3VuZHMocmFkaXVzPzogbnVtYmVyID0gMCk6IExuZ0xhdEJvdW5kcyB7XG4gICAgICAgIGNvbnN0IGVhcnRoQ2lyY3VtZmVyZW5jZUluTWV0ZXJzQXRFcXVhdG9yID0gNDAwNzUwMTc7XG4gICAgICAgIGNvbnN0IGxhdEFjY3VyYWN5ID0gMzYwICogcmFkaXVzIC8gZWFydGhDaXJjdW1mZXJlbmNlSW5NZXRlcnNBdEVxdWF0b3IsXG4gICAgICAgICAgICBsbmdBY2N1cmFjeSA9IGxhdEFjY3VyYWN5IC8gTWF0aC5jb3MoKE1hdGguUEkgLyAxODApICogdGhpcy5sYXQpO1xuXG4gICAgICAgIHJldHVybiBuZXcgTG5nTGF0Qm91bmRzKG5ldyBMbmdMYXQodGhpcy5sbmcgLSBsbmdBY2N1cmFjeSwgdGhpcy5sYXQgLSBsYXRBY2N1cmFjeSksXG4gICAgICAgICAgICBuZXcgTG5nTGF0KHRoaXMubG5nICsgbG5nQWNjdXJhY3ksIHRoaXMubGF0ICsgbGF0QWNjdXJhY3kpKTtcbiAgICB9XG5cbiAgICB0b0VjZWYoYWx0aXR1ZGU6IG51bWJlcik6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSB7XG4gICAgICAgIGNvbnN0IGFsdEluRWNlZiA9IGdsb2JlTWV0ZXJzVG9FY2VmKGFsdGl0dWRlKTtcbiAgICAgICAgY29uc3QgcmFkaXVzID0gR0xPQkVfUkFESVVTICsgYWx0SW5FY2VmO1xuICAgICAgICByZXR1cm4gKGxhdExuZ1RvRUNFRih0aGlzLmxhdCwgdGhpcy5sbmcsIHJhZGl1cyk6IGFueSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYW4gYXJyYXkgb2YgdHdvIG51bWJlcnMgb3IgYW4gb2JqZWN0IHdpdGggYGxuZ2AgYW5kIGBsYXRgIG9yIGBsb25gIGFuZCBgbGF0YCBwcm9wZXJ0aWVzXG4gICAgICogdG8gYSBgTG5nTGF0YCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBJZiBhIGBMbmdMYXRgIG9iamVjdCBpcyBwYXNzZWQgaW4sIHRoZSBmdW5jdGlvbiByZXR1cm5zIGl0IHVuY2hhbmdlZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7TG5nTGF0TGlrZX0gaW5wdXQgQW4gYXJyYXkgb2YgdHdvIG51bWJlcnMgb3Igb2JqZWN0IHRvIGNvbnZlcnQsIG9yIGEgYExuZ0xhdGAgb2JqZWN0IHRvIHJldHVybi5cbiAgICAgKiBAcmV0dXJucyB7TG5nTGF0fSBBIG5ldyBgTG5nTGF0YCBvYmplY3QsIGlmIGEgY29udmVyc2lvbiBvY2N1cnJlZCwgb3IgdGhlIG9yaWdpbmFsIGBMbmdMYXRgIG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGFyciA9IFstNzMuOTc0OSwgNDAuNzczNl07XG4gICAgICogY29uc3QgbGwgPSBtYXBib3hnbC5MbmdMYXQuY29udmVydChhcnIpO1xuICAgICAqIGNvbnNvbGUubG9nKGxsKTsgICAvLyA9IExuZ0xhdCB7bG5nOiAtNzMuOTc0OSwgbGF0OiA0MC43NzM2fVxuICAgICAqL1xuICAgIHN0YXRpYyBjb252ZXJ0KGlucHV0OiBMbmdMYXRMaWtlKTogTG5nTGF0IHtcbiAgICAgICAgaWYgKGlucHV0IGluc3RhbmNlb2YgTG5nTGF0KSB7XG4gICAgICAgICAgICByZXR1cm4gaW5wdXQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoaW5wdXQpICYmIChpbnB1dC5sZW5ndGggPT09IDIgfHwgaW5wdXQubGVuZ3RoID09PSAzKSkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBMbmdMYXQoTnVtYmVyKGlucHV0WzBdKSwgTnVtYmVyKGlucHV0WzFdKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGlucHV0KSAmJiB0eXBlb2YgaW5wdXQgPT09ICdvYmplY3QnICYmIGlucHV0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IExuZ0xhdChcbiAgICAgICAgICAgICAgICAvLyBmbG93IGNhbid0IHJlZmluZSB0aGlzIHRvIGhhdmUgb25lIG9mIGxuZyBvciBsYXQsIHNvIHdlIGhhdmUgdG8gY2FzdCB0byBhbnlcbiAgICAgICAgICAgICAgICBOdW1iZXIoJ2xuZycgaW4gaW5wdXQgPyAoaW5wdXQ6IGFueSkubG5nIDogKGlucHV0OiBhbnkpLmxvbiksXG4gICAgICAgICAgICAgICAgTnVtYmVyKGlucHV0LmxhdClcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiYExuZ0xhdExpa2VgIGFyZ3VtZW50IG11c3QgYmUgc3BlY2lmaWVkIGFzIGEgTG5nTGF0IGluc3RhbmNlLCBhbiBvYmplY3Qge2xuZzogPGxuZz4sIGxhdDogPGxhdD59LCBhbiBvYmplY3Qge2xvbjogPGxuZz4sIGxhdDogPGxhdD59LCBvciBhbiBhcnJheSBvZiBbPGxuZz4sIDxsYXQ+XVwiKTtcbiAgICB9XG59XG5cbi8qKlxuICogQSB7QGxpbmsgTG5nTGF0fSBvYmplY3QsIGFuIGFycmF5IG9mIHR3byBudW1iZXJzIHJlcHJlc2VudGluZyBsb25naXR1ZGUgYW5kIGxhdGl0dWRlLFxuICogb3IgYW4gb2JqZWN0IHdpdGggYGxuZ2AgYW5kIGBsYXRgIG9yIGBsb25gIGFuZCBgbGF0YCBwcm9wZXJ0aWVzLlxuICpcbiAqIEB0eXBlZGVmIHtMbmdMYXQgfCB7bG5nOiBudW1iZXIsIGxhdDogbnVtYmVyfSB8IHtsb246IG51bWJlciwgbGF0OiBudW1iZXJ9IHwgW251bWJlciwgbnVtYmVyXX0gTG5nTGF0TGlrZVxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHYxID0gbmV3IG1hcGJveGdsLkxuZ0xhdCgtMTIyLjQyMDY3OSwgMzcuNzcyNTM3KTtcbiAqIGNvbnN0IHYyID0gWy0xMjIuNDIwNjc5LCAzNy43NzI1MzddO1xuICogY29uc3QgdjMgPSB7bG9uOiAtMTIyLjQyMDY3OSwgbGF0OiAzNy43NzI1Mzd9O1xuICovXG5leHBvcnQgdHlwZSBMbmdMYXRMaWtlID0gTG5nTGF0IHwge2xuZzogbnVtYmVyLCBsYXQ6IG51bWJlcn0gfCB7bG9uOiBudW1iZXIsIGxhdDogbnVtYmVyfSB8IFtudW1iZXIsIG51bWJlcl07XG5cbmV4cG9ydCBkZWZhdWx0IExuZ0xhdDtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCBMbmdMYXQsIHtlYXJ0aENpcmN1bWZlcmVuY2V9IGZyb20gJy4uL2dlby9sbmdfbGF0LmpzJztcbmltcG9ydCB0eXBlIHtMbmdMYXRMaWtlfSBmcm9tICcuLi9nZW8vbG5nX2xhdC5qcyc7XG5cbi8qXG4gKiBUaGUgY2lyY3VtZmVyZW5jZSBhdCBhIGxpbmUgb2YgbGF0aXR1ZGUgaW4gbWV0ZXJzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2lyY3VtZmVyZW5jZUF0TGF0aXR1ZGUobGF0aXR1ZGU6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIGVhcnRoQ2lyY3VtZmVyZW5jZSAqIE1hdGguY29zKGxhdGl0dWRlICogTWF0aC5QSSAvIDE4MCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtZXJjYXRvclhmcm9tTG5nKGxuZzogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gKDE4MCArIGxuZykgLyAzNjA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtZXJjYXRvcllmcm9tTGF0KGxhdDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gKDE4MCAtICgxODAgLyBNYXRoLlBJICogTWF0aC5sb2coTWF0aC50YW4oTWF0aC5QSSAvIDQgKyBsYXQgKiBNYXRoLlBJIC8gMzYwKSkpKSAvIDM2MDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1lcmNhdG9yWmZyb21BbHRpdHVkZShhbHRpdHVkZTogbnVtYmVyLCBsYXQ6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIGFsdGl0dWRlIC8gY2lyY3VtZmVyZW5jZUF0TGF0aXR1ZGUobGF0KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxuZ0Zyb21NZXJjYXRvclgoeDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4geCAqIDM2MCAtIDE4MDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxhdEZyb21NZXJjYXRvclkoeTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBjb25zdCB5MiA9IDE4MCAtIHkgKiAzNjA7XG4gICAgcmV0dXJuIDM2MCAvIE1hdGguUEkgKiBNYXRoLmF0YW4oTWF0aC5leHAoeTIgKiBNYXRoLlBJIC8gMTgwKSkgLSA5MDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFsdGl0dWRlRnJvbU1lcmNhdG9yWih6OiBudW1iZXIsIHk6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIHogKiBjaXJjdW1mZXJlbmNlQXRMYXRpdHVkZShsYXRGcm9tTWVyY2F0b3JZKHkpKTtcbn1cblxuZXhwb3J0IGNvbnN0IE1BWF9NRVJDQVRPUl9MQVRJVFVERSA9IDg1LjA1MTEyOTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgdGhlIE1lcmNhdG9yIHNjYWxlIGZhY3RvciBmb3IgYSBnaXZlbiBsYXRpdHVkZSwgc2VlXG4gKiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9NZXJjYXRvcl9wcm9qZWN0aW9uI1NjYWxlX2ZhY3RvclxuICpcbiAqIEF0IHRoZSBlcXVhdG9yIHRoZSBzY2FsZSBmYWN0b3Igd2lsbCBiZSAxLCB3aGljaCBpbmNyZWFzZXMgYXQgaGlnaGVyIGxhdGl0dWRlcy5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gbGF0IExhdGl0dWRlXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBzY2FsZSBmYWN0b3JcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZXJjYXRvclNjYWxlKGxhdDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gMSAvIE1hdGguY29zKGxhdCAqIE1hdGguUEkgLyAxODApO1xufVxuXG4vKipcbiAqIEEgYE1lcmNhdG9yQ29vcmRpbmF0ZWAgb2JqZWN0IHJlcHJlc2VudHMgYSBwcm9qZWN0ZWQgdGhyZWUgZGltZW5zaW9uYWwgcG9zaXRpb24uXG4gKlxuICogYE1lcmNhdG9yQ29vcmRpbmF0ZWAgdXNlcyB0aGUgd2ViIG1lcmNhdG9yIHByb2plY3Rpb24gKFtFUFNHOjM4NTddKGh0dHBzOi8vZXBzZy5pby8zODU3KSkgd2l0aCBzbGlnaHRseSBkaWZmZXJlbnQgdW5pdHM6XG4gKiAtIHRoZSBzaXplIG9mIDEgdW5pdCBpcyB0aGUgd2lkdGggb2YgdGhlIHByb2plY3RlZCB3b3JsZCBpbnN0ZWFkIG9mIHRoZSBcIm1lcmNhdG9yIG1ldGVyXCJcbiAqIC0gdGhlIG9yaWdpbiBvZiB0aGUgY29vcmRpbmF0ZSBzcGFjZSBpcyBhdCB0aGUgbm9ydGgtd2VzdCBjb3JuZXIgaW5zdGVhZCBvZiB0aGUgbWlkZGxlLlxuICpcbiAqIEZvciBleGFtcGxlLCBgTWVyY2F0b3JDb29yZGluYXRlKDAsIDAsIDApYCBpcyB0aGUgbm9ydGgtd2VzdCBjb3JuZXIgb2YgdGhlIG1lcmNhdG9yIHdvcmxkIGFuZFxuICogYE1lcmNhdG9yQ29vcmRpbmF0ZSgxLCAxLCAwKWAgaXMgdGhlIHNvdXRoLWVhc3QgY29ybmVyLiBJZiB5b3UgYXJlIGZhbWlsaWFyIHdpdGhcbiAqIFt2ZWN0b3IgdGlsZXNdKGh0dHBzOi8vZ2l0aHViLmNvbS9tYXBib3gvdmVjdG9yLXRpbGUtc3BlYykgaXQgbWF5IGJlIGhlbHBmdWwgdG8gdGhpbmtcbiAqIG9mIHRoZSBjb29yZGluYXRlIHNwYWNlIGFzIHRoZSBgMC8wLzBgIHRpbGUgd2l0aCBhbiBleHRlbnQgb2YgYDFgLlxuICpcbiAqIFRoZSBgemAgZGltZW5zaW9uIG9mIGBNZXJjYXRvckNvb3JkaW5hdGVgIGlzIGNvbmZvcm1hbC4gQSBjdWJlIGluIHRoZSBtZXJjYXRvciBjb29yZGluYXRlIHNwYWNlIHdvdWxkIGJlIHJlbmRlcmVkIGFzIGEgY3ViZS5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0geCBUaGUgeCBjb21wb25lbnQgb2YgdGhlIHBvc2l0aW9uLlxuICogQHBhcmFtIHtudW1iZXJ9IHkgVGhlIHkgY29tcG9uZW50IG9mIHRoZSBwb3NpdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSB6IFRoZSB6IGNvbXBvbmVudCBvZiB0aGUgcG9zaXRpb24uXG4gKiBAZXhhbXBsZVxuICogY29uc3QgbnVsbElzbGFuZCA9IG5ldyBtYXBib3hnbC5NZXJjYXRvckNvb3JkaW5hdGUoMC41LCAwLjUsIDApO1xuICpcbiAqIEBzZWUgW0V4YW1wbGU6IEFkZCBhIGN1c3RvbSBzdHlsZSBsYXllcl0oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9jdXN0b20tc3R5bGUtbGF5ZXIvKVxuICovXG5jbGFzcyBNZXJjYXRvckNvb3JkaW5hdGUge1xuICAgIHg6IG51bWJlcjtcbiAgICB5OiBudW1iZXI7XG4gICAgejogbnVtYmVyO1xuXG4gICAgY29uc3RydWN0b3IoeDogbnVtYmVyLCB5OiBudW1iZXIsIHo6IG51bWJlciA9IDApIHtcbiAgICAgICAgdGhpcy54ID0gK3g7XG4gICAgICAgIHRoaXMueSA9ICt5O1xuICAgICAgICB0aGlzLnogPSArejtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcm9qZWN0IGEgYExuZ0xhdGAgdG8gYSBgTWVyY2F0b3JDb29yZGluYXRlYC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7TG5nTGF0TGlrZX0gbG5nTGF0TGlrZSBUaGUgbG9jYXRpb24gdG8gcHJvamVjdC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYWx0aXR1ZGUgVGhlIGFsdGl0dWRlIGluIG1ldGVycyBvZiB0aGUgcG9zaXRpb24uXG4gICAgICogQHJldHVybnMge01lcmNhdG9yQ29vcmRpbmF0ZX0gVGhlIHByb2plY3RlZCBtZXJjYXRvciBjb29yZGluYXRlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgY29vcmQgPSBtYXBib3hnbC5NZXJjYXRvckNvb3JkaW5hdGUuZnJvbUxuZ0xhdCh7bG5nOiAwLCBsYXQ6IDB9LCAwKTtcbiAgICAgKiBjb25zb2xlLmxvZyhjb29yZCk7IC8vIE1lcmNhdG9yQ29vcmRpbmF0ZSgwLjUsIDAuNSwgMClcbiAgICAgKi9cbiAgICBzdGF0aWMgZnJvbUxuZ0xhdChsbmdMYXRMaWtlOiBMbmdMYXRMaWtlLCBhbHRpdHVkZTogbnVtYmVyID0gMCk6IE1lcmNhdG9yQ29vcmRpbmF0ZSB7XG4gICAgICAgIGNvbnN0IGxuZ0xhdCA9IExuZ0xhdC5jb252ZXJ0KGxuZ0xhdExpa2UpO1xuXG4gICAgICAgIHJldHVybiBuZXcgTWVyY2F0b3JDb29yZGluYXRlKFxuICAgICAgICAgICAgICAgIG1lcmNhdG9yWGZyb21MbmcobG5nTGF0LmxuZyksXG4gICAgICAgICAgICAgICAgbWVyY2F0b3JZZnJvbUxhdChsbmdMYXQubGF0KSxcbiAgICAgICAgICAgICAgICBtZXJjYXRvclpmcm9tQWx0aXR1ZGUoYWx0aXR1ZGUsIGxuZ0xhdC5sYXQpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBgTG5nTGF0YCBmb3IgdGhlIGNvb3JkaW5hdGUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7TG5nTGF0fSBUaGUgYExuZ0xhdGAgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgY29vcmQgPSBuZXcgbWFwYm94Z2wuTWVyY2F0b3JDb29yZGluYXRlKDAuNSwgMC41LCAwKTtcbiAgICAgKiBjb25zdCBsbmdMYXQgPSBjb29yZC50b0xuZ0xhdCgpOyAvLyBMbmdMYXQoMCwgMClcbiAgICAgKi9cbiAgICB0b0xuZ0xhdCgpOiBMbmdMYXQge1xuICAgICAgICByZXR1cm4gbmV3IExuZ0xhdChcbiAgICAgICAgICAgICAgICBsbmdGcm9tTWVyY2F0b3JYKHRoaXMueCksXG4gICAgICAgICAgICAgICAgbGF0RnJvbU1lcmNhdG9yWSh0aGlzLnkpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBhbHRpdHVkZSBpbiBtZXRlcnMgb2YgdGhlIGNvb3JkaW5hdGUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgYWx0aXR1ZGUgaW4gbWV0ZXJzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgY29vcmQgPSBuZXcgbWFwYm94Z2wuTWVyY2F0b3JDb29yZGluYXRlKDAsIDAsIDAuMDIpO1xuICAgICAqIGNvb3JkLnRvQWx0aXR1ZGUoKTsgLy8gNjkxNC4yODE5NTYyOTUzMzlcbiAgICAgKi9cbiAgICB0b0FsdGl0dWRlKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiBhbHRpdHVkZUZyb21NZXJjYXRvcloodGhpcy56LCB0aGlzLnkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGRpc3RhbmNlIG9mIDEgbWV0ZXIgaW4gYE1lcmNhdG9yQ29vcmRpbmF0ZWAgdW5pdHMgYXQgdGhpcyBsYXRpdHVkZS5cbiAgICAgKlxuICAgICAqIEZvciBjb29yZGluYXRlcyBpbiByZWFsIHdvcmxkIHVuaXRzIHVzaW5nIG1ldGVycywgdGhpcyBuYXR1cmFsbHkgcHJvdmlkZXMgdGhlIHNjYWxlXG4gICAgICogdG8gdHJhbnNmb3JtIGludG8gYE1lcmNhdG9yQ29vcmRpbmF0ZWBzLlxuICAgICAqXG4gICAgICogQHJldHVybnMge251bWJlcn0gRGlzdGFuY2Ugb2YgMSBtZXRlciBpbiBgTWVyY2F0b3JDb29yZGluYXRlYCB1bml0cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIENhbGN1bGF0ZSBhIG5ldyBNZXJjYXRvckNvb3JkaW5hdGUgdGhhdCBpcyAxNTAgbWV0ZXJzIHdlc3Qgb2YgdGhlIG90aGVyIGNvb3JkLlxuICAgICAqIGNvbnN0IGNvb3JkID0gbmV3IG1hcGJveGdsLk1lcmNhdG9yQ29vcmRpbmF0ZSgwLjUsIDAuMjUsIDApO1xuICAgICAqIGNvbnN0IG9mZnNldEluTWV0ZXJzID0gMTUwO1xuICAgICAqIGNvbnN0IG9mZnNldEluTWVyY2F0b3JDb29yZGluYXRlVW5pdHMgPSBvZmZzZXRJbk1ldGVycyAqIGNvb3JkLm1ldGVySW5NZXJjYXRvckNvb3JkaW5hdGVVbml0cygpO1xuICAgICAqIGNvbnN0IHdlc3RDb29yZCA9IG5ldyBtYXBib3hnbC5NZXJjYXRvckNvb3JkaW5hdGUoY29vcmQueCAtIG9mZnNldEluTWVyY2F0b3JDb29yZGluYXRlVW5pdHMsIGNvb3JkLnksIGNvb3JkLnopO1xuICAgICAqL1xuICAgIG1ldGVySW5NZXJjYXRvckNvb3JkaW5hdGVVbml0cygpOiBudW1iZXIge1xuICAgICAgICAvLyAxIG1ldGVyIC8gY2lyY3VtZmVyZW5jZSBhdCBlcXVhdG9yIGluIG1ldGVycyAqIE1lcmNhdG9yIHByb2plY3Rpb24gc2NhbGUgZmFjdG9yIGF0IHRoaXMgbGF0aXR1ZGVcbiAgICAgICAgcmV0dXJuIDEgLyBlYXJ0aENpcmN1bWZlcmVuY2UgKiBtZXJjYXRvclNjYWxlKGxhdEZyb21NZXJjYXRvclkodGhpcy55KSk7XG4gICAgfVxuXG59XG5cbmV4cG9ydCBkZWZhdWx0IE1lcmNhdG9yQ29vcmRpbmF0ZTtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcblxuZnVuY3Rpb24gcG9pbnRUb0xpbmVEaXN0KHB4OiBudW1iZXIsIHB5OiBudW1iZXIsIGF4OiBudW1iZXIsIGF5OiBudW1iZXIsIGJ4OiBudW1iZXIsIGJ5OiBudW1iZXIpIHtcbiAgICBjb25zdCBkeCA9IGF4IC0gYng7XG4gICAgY29uc3QgZHkgPSBheSAtIGJ5O1xuICAgIHJldHVybiBNYXRoLmFicygoYXkgLSBweSkgKiBkeCAtIChheCAtIHB4KSAqIGR5KSAvIE1hdGguaHlwb3QoZHgsIGR5KTtcbn1cblxuZnVuY3Rpb24gYWRkUmVzYW1wbGVkKHJlc2FtcGxlZDogQXJyYXk8UG9pbnQ+LCBteDA6IG51bWJlciwgbXkwOiBudW1iZXIsIG14MjogbnVtYmVyLCBteTI6IG51bWJlciwgc3RhcnQ6IFBvaW50LCBlbmQ6IFBvaW50LCByZXByb2plY3Q6ICgoUG9pbnQpID0+IHZvaWQpLCB0b2xlcmFuY2U6IG51bWJlcikge1xuICAgIGNvbnN0IG14MSA9IChteDAgKyBteDIpIC8gMjtcbiAgICBjb25zdCBteTEgPSAobXkwICsgbXkyKSAvIDI7XG4gICAgY29uc3QgbWlkID0gbmV3IFBvaW50KG14MSwgbXkxKTtcbiAgICByZXByb2plY3QobWlkKTtcbiAgICBjb25zdCBlcnIgPSBwb2ludFRvTGluZURpc3QobWlkLngsIG1pZC55LCBzdGFydC54LCBzdGFydC55LCBlbmQueCwgZW5kLnkpO1xuXG4gICAgLy8gaWYgcmVwcm9qZWN0ZWQgbWlkUG9pbnQgaXMgdG9vIGZhciBmcm9tIGdlb21ldHJpYyBtaWRwb2ludCwgcmVjdXJzZSBpbnRvIHR3byBoYWx2ZXNcbiAgICBpZiAoZXJyID49IHRvbGVyYW5jZSkge1xuICAgICAgICAvLyB3ZSdyZSB2ZXJ5IHVubGlrZWx5IHRvIGhpdCBtYXggY2FsbCBzdGFjayBleGNlZWRlZCBoZXJlLFxuICAgICAgICAvLyBidXQgd2UgbWlnaHQgd2FudCB0byBzYWZlZ3VhcmQgYWdhaW5zdCBpdCBpbiB0aGUgZnV0dXJlXG4gICAgICAgIGFkZFJlc2FtcGxlZChyZXNhbXBsZWQsIG14MCwgbXkwLCBteDEsIG15MSwgc3RhcnQsIG1pZCwgcmVwcm9qZWN0LCB0b2xlcmFuY2UpO1xuICAgICAgICBhZGRSZXNhbXBsZWQocmVzYW1wbGVkLCBteDEsIG15MSwgbXgyLCBteTIsIG1pZCwgZW5kLCByZXByb2plY3QsIHRvbGVyYW5jZSk7XG5cbiAgICB9IGVsc2UgeyAvLyBvdGhlcndpc2UsIGp1c3QgYWRkIHRoZSBwb2ludFxuICAgICAgICByZXNhbXBsZWQucHVzaChlbmQpO1xuICAgIH1cbn1cblxuLy8gcmVwcm9qZWN0IGFuZCByZXNhbXBsZSBhIGxpbmUsIGFkZGluZyBwb2ludCB3aGVyZSBuZWNlc3NhcnkgZm9yIGxpbmVzIHRoYXQgYmVjb21lIGN1cnZlcztcbi8vIG5vdGUgdGhhdCB0aGlzIG9wZXJhdGlvbiBpcyBtdXRhYmxlIChtb2RpZnlpbmcgb3JpZ2luYWwgcG9pbnRzKSBmb3IgcGVyZm9ybWFuY2VcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHJlc2FtcGxlKGxpbmU6IEFycmF5PFBvaW50PiwgcmVwcm9qZWN0OiAoUG9pbnQpID0+IHZvaWQsIHRvbGVyYW5jZTogbnVtYmVyKTogQXJyYXk8UG9pbnQ+IHtcbiAgICBsZXQgcHJldiA9IGxpbmVbMF07XG4gICAgbGV0IG14MCA9IHByZXYueDtcbiAgICBsZXQgbXkwID0gcHJldi55O1xuICAgIHJlcHJvamVjdChwcmV2KTtcbiAgICBjb25zdCByZXNhbXBsZWQgPSBbcHJldl07XG5cbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IGxpbmUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgcG9pbnQgPSBsaW5lW2ldO1xuICAgICAgICBjb25zdCB7eCwgeX0gPSBwb2ludDtcbiAgICAgICAgcmVwcm9qZWN0KHBvaW50KTtcbiAgICAgICAgYWRkUmVzYW1wbGVkKHJlc2FtcGxlZCwgbXgwLCBteTAsIHgsIHksIHByZXYsIHBvaW50LCByZXByb2plY3QsIHRvbGVyYW5jZSk7XG4gICAgICAgIG14MCA9IHg7XG4gICAgICAgIG15MCA9IHk7XG4gICAgICAgIHByZXYgPSBwb2ludDtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzYW1wbGVkO1xufVxuXG5mdW5jdGlvbiBhZGRSZXNhbXBsZWRQcmVkKHJlc2FtcGxlZDogUG9pbnRbXSwgYTogUG9pbnQsIGI6IFBvaW50LCBwcmVkOiAoKFBvaW50LCBQb2ludCkgPT4gYm9vbGVhbikpIHtcbiAgICBjb25zdCBzcGxpdCA9IHByZWQoYSwgYik7XG5cbiAgICAvLyBpZiB0aGUgcHJlZGljYXRlIGNvbmRpdGlvbiBpcyBtZXQsIHJlY3Vyc2UgaW50byB0d28gaGFsdmVzXG4gICAgaWYgKHNwbGl0KSB7XG4gICAgICAgIGNvbnN0IG1pZCA9IGEuYWRkKGIpLl9tdWx0KDAuNSk7XG4gICAgICAgIGFkZFJlc2FtcGxlZFByZWQocmVzYW1wbGVkLCBhLCBtaWQsIHByZWQpO1xuICAgICAgICBhZGRSZXNhbXBsZWRQcmVkKHJlc2FtcGxlZCwgbWlkLCBiLCBwcmVkKTtcblxuICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc2FtcGxlZC5wdXNoKGIpO1xuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlc2FtcGxlUHJlZChsaW5lOiBQb2ludFtdLCBwcmVkaWNhdGU6IChQb2ludCwgUG9pbnQpID0+IGJvb2xlYW4pOiBQb2ludFtdIHtcbiAgICBsZXQgcHJldiA9IGxpbmVbMF07XG4gICAgY29uc3QgcmVzYW1wbGVkID0gW3ByZXZdO1xuXG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPCBsaW5lLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHBvaW50ID0gbGluZVtpXTtcbiAgICAgICAgYWRkUmVzYW1wbGVkUHJlZChyZXNhbXBsZWQsIHByZXYsIHBvaW50LCBwcmVkaWNhdGUpO1xuICAgICAgICBwcmV2ID0gcG9pbnQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc2FtcGxlZDtcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCB7d2Fybk9uY2UsIGNsYW1wfSBmcm9tICcuLi91dGlsL3V0aWwuanMnO1xuXG5pbXBvcnQgRVhURU5UIGZyb20gJy4vZXh0ZW50LmpzJztcbmltcG9ydCB7bG5nRnJvbU1lcmNhdG9yWCwgbGF0RnJvbU1lcmNhdG9yWX0gZnJvbSAnLi4vZ2VvL21lcmNhdG9yX2Nvb3JkaW5hdGUuanMnO1xuaW1wb3J0IHJlc2FtcGxlIGZyb20gJy4uL2dlby9wcm9qZWN0aW9uL3Jlc2FtcGxlLmpzJztcbmltcG9ydCBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcblxuaW1wb3J0IHR5cGUge0Nhbm9uaWNhbFRpbGVJRH0gZnJvbSAnLi4vc291cmNlL3RpbGVfaWQuanMnO1xuaW1wb3J0IHR5cGUge1RpbGVUcmFuc2Zvcm19IGZyb20gJy4uL2dlby9wcm9qZWN0aW9uL3RpbGVfdHJhbnNmb3JtLmpzJztcblxuLy8gVGhlc2UgYm91bmRzIGRlZmluZSB0aGUgbWluaW11bSBhbmQgbWF4aW11bSBzdXBwb3J0ZWQgY29vcmRpbmF0ZSB2YWx1ZXMuXG4vLyBXaGlsZSB2aXNpYmxlIGNvb3JkaW5hdGVzIGFyZSB3aXRoaW4gWzAsIEVYVEVOVF0sIHRpbGVzIG1heSB0aGVvcmV0aWNhbGx5XG4vLyBjb250YWluIGNvb3JkaW5hdGVzIHdpdGhpbiBbLUluZmluaXR5LCBJbmZpbml0eV0uIE91ciByYW5nZSBpcyBsaW1pdGVkIGJ5IHRoZVxuLy8gbnVtYmVyIG9mIGJpdHMgdXNlZCB0byByZXByZXNlbnQgdGhlIGNvb3JkaW5hdGUuXG5jb25zdCBCSVRTID0gMTU7XG5jb25zdCBNQVggPSBNYXRoLnBvdygyLCBCSVRTIC0gMSkgLSAxO1xuY29uc3QgTUlOID0gLU1BWCAtIDE7XG5cbmZ1bmN0aW9uIHByZXBhcmVQb2ludChwb2ludDogUG9pbnQsIHNjYWxlOiBudW1iZXIpIHtcbiAgICBjb25zdCB4ID0gTWF0aC5yb3VuZChwb2ludC54ICogc2NhbGUpO1xuICAgIGNvbnN0IHkgPSBNYXRoLnJvdW5kKHBvaW50LnkgKiBzY2FsZSk7XG4gICAgcG9pbnQueCA9IGNsYW1wKHgsIE1JTiwgTUFYKTtcbiAgICBwb2ludC55ID0gY2xhbXAoeSwgTUlOLCBNQVgpO1xuICAgIGlmICh4IDwgcG9pbnQueCB8fCB4ID4gcG9pbnQueCArIDEgfHwgeSA8IHBvaW50LnkgfHwgeSA+IHBvaW50LnkgKyAxKSB7XG4gICAgICAgIC8vIHdhcm4gd2hlbiBleGNlZWRpbmcgYWxsb3dlZCBleHRlbnQgZXhjZXB0IGZvciB0aGUgMS1weC1vZmYgY2FzZVxuICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbWFwYm94L21hcGJveC1nbC1qcy9pc3N1ZXMvODk5MlxuICAgICAgICB3YXJuT25jZSgnR2VvbWV0cnkgZXhjZWVkcyBhbGxvd2VkIGV4dGVudCwgcmVkdWNlIHlvdXIgdmVjdG9yIHRpbGUgYnVmZmVyIHNpemUnKTtcbiAgICB9XG4gICAgcmV0dXJuIHBvaW50O1xufVxuXG4vLyBhIHN1YnNldCBvZiBWZWN0b3JUaWxlR2VvbWV0cnlcbmludGVyZmFjZSBGZWF0dXJlV2l0aEdlb21ldHJ5IHtcbiAgICBleHRlbnQ6IG51bWJlcjtcbiAgICB0eXBlOiAxIHwgMiB8IDM7XG4gICAgbG9hZEdlb21ldHJ5KCk6IEFycmF5PEFycmF5PFBvaW50Pj47XG59XG5cbi8qKlxuICogTG9hZHMgYSBnZW9tZXRyeSBmcm9tIGEgVmVjdG9yVGlsZUZlYXR1cmUgYW5kIHNjYWxlcyBpdCB0byB0aGUgY29tbW9uIGV4dGVudFxuICogdXNlZCBpbnRlcm5hbGx5LlxuICogQHBhcmFtIHtWZWN0b3JUaWxlRmVhdHVyZX0gZmVhdHVyZVxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gbG9hZEdlb21ldHJ5KGZlYXR1cmU6IEZlYXR1cmVXaXRoR2VvbWV0cnksIGNhbm9uaWNhbD86IENhbm9uaWNhbFRpbGVJRCwgdGlsZVRyYW5zZm9ybT86IFRpbGVUcmFuc2Zvcm0pOiBBcnJheTxBcnJheTxQb2ludD4+IHtcbiAgICBjb25zdCBnZW9tZXRyeSA9IGZlYXR1cmUubG9hZEdlb21ldHJ5KCk7XG4gICAgY29uc3QgZXh0ZW50ID0gZmVhdHVyZS5leHRlbnQ7XG4gICAgY29uc3QgZXh0ZW50U2NhbGUgPSBFWFRFTlQgLyBleHRlbnQ7XG5cbiAgICBpZiAoY2Fub25pY2FsICYmIHRpbGVUcmFuc2Zvcm0gJiYgdGlsZVRyYW5zZm9ybS5wcm9qZWN0aW9uLmlzUmVwcm9qZWN0ZWRJblRpbGVTcGFjZSkge1xuICAgICAgICBjb25zdCB6MiA9IDEgPDwgY2Fub25pY2FsLno7XG4gICAgICAgIGNvbnN0IHtzY2FsZSwgeCwgeSwgcHJvamVjdGlvbn0gPSB0aWxlVHJhbnNmb3JtO1xuXG4gICAgICAgIGNvbnN0IHJlcHJvamVjdCA9IChwOiBQb2ludCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbG5nID0gbG5nRnJvbU1lcmNhdG9yWCgoY2Fub25pY2FsLnggKyBwLnggLyBleHRlbnQpIC8gejIpO1xuICAgICAgICAgICAgY29uc3QgbGF0ID0gbGF0RnJvbU1lcmNhdG9yWSgoY2Fub25pY2FsLnkgKyBwLnkgLyBleHRlbnQpIC8gejIpO1xuICAgICAgICAgICAgY29uc3QgcDIgPSBwcm9qZWN0aW9uLnByb2plY3QobG5nLCBsYXQpO1xuICAgICAgICAgICAgcC54ID0gKHAyLnggKiBzY2FsZSAtIHgpICogZXh0ZW50O1xuICAgICAgICAgICAgcC55ID0gKHAyLnkgKiBzY2FsZSAtIHkpICogZXh0ZW50O1xuICAgICAgICB9O1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZ2VvbWV0cnkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChmZWF0dXJlLnR5cGUgIT09IDEpIHtcbiAgICAgICAgICAgICAgICBnZW9tZXRyeVtpXSA9IHJlc2FtcGxlKGdlb21ldHJ5W2ldLCByZXByb2plY3QsIDEpOyAvLyByZXNhbXBsZSBsaW5lcyBhbmQgcG9seWdvbnNcblxuICAgICAgICAgICAgfSBlbHNlIHsgLy8gcG9pbnRzXG4gICAgICAgICAgICAgICAgY29uc3QgbGluZSA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcCBvZiBnZW9tZXRyeVtpXSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBmaWx0ZXIgb3V0IHBvaW50IGZlYXR1cmVzIG91dHNpZGUgdGlsZSBib3VuZGFyaWVzIG5vdzsgaXQnZCBiZSBoYXJkZXIgdG8gZG8gbGF0ZXJcbiAgICAgICAgICAgICAgICAgICAgLy8gd2hlbiB0aGUgY29vcmRzIGFyZSByZXByb2plY3RlZCBhbmQgbm8gbG9uZ2VyIGF4aXMtYWxpZ25lZDsgaWRlYWxseSB0aGlzIHdvdWxkIGhhcHBlblxuICAgICAgICAgICAgICAgICAgICAvLyBvciBub3QgZGVwZW5kaW5nIG9uIGhvdyB0aGUgZ2VvbWV0cnkgaXMgdXNlZCwgYnV0IHdlIGZvcmVnbyB0aGUgY29tcGxleGl0eSBmb3Igbm93XG4gICAgICAgICAgICAgICAgICAgIGlmIChwLnggPCAwIHx8IHAueCA+PSBleHRlbnQgfHwgcC55IDwgMCB8fCBwLnkgPj0gZXh0ZW50KSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgcmVwcm9qZWN0KHApO1xuICAgICAgICAgICAgICAgICAgICBsaW5lLnB1c2gocCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGdlb21ldHJ5W2ldID0gbGluZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgbGluZSBvZiBnZW9tZXRyeSkge1xuICAgICAgICBmb3IgKGNvbnN0IHAgb2YgbGluZSkge1xuICAgICAgICAgICAgcHJlcGFyZVBvaW50KHAsIGV4dGVudFNjYWxlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBnZW9tZXRyeTtcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBsb2FkR2VvbWV0cnkgZnJvbSAnLi9sb2FkX2dlb21ldHJ5LmpzJztcblxuaW1wb3J0IHR5cGUgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5pbXBvcnQgdHlwZSB7SVZlY3RvclRpbGVGZWF0dXJlfSBmcm9tICdAbWFwYm94L3ZlY3Rvci10aWxlJztcblxudHlwZSBFdmFsdWF0aW9uRmVhdHVyZSA9IHtcbiAgICArdHlwZTogMSB8IDIgfCAzIHwgJ1Vua25vd24nIHwgJ1BvaW50JyB8ICdMaW5lU3RyaW5nJyB8ICdQb2x5Z29uJyxcbiAgICAraWQ/OiBhbnksXG4gICAgK3Byb3BlcnRpZXM6IHtbXzogc3RyaW5nXTogYW55fSxcbiAgICArcGF0dGVybnM/OiB7W186IHN0cmluZ106IHN0cmluZ30sXG4gICAgZ2VvbWV0cnk6IEFycmF5PEFycmF5PFBvaW50Pj5cbn07XG5cbi8qKlxuICogQ29uc3RydWN0IGEgbmV3IGZlYXR1cmUgYmFzZWQgb24gYSBWZWN0b3JUaWxlRmVhdHVyZSBmb3IgZXhwcmVzc2lvbiBldmFsdWF0aW9uLCB0aGUgZ2VvbWV0cnkgb2Ygd2hpY2hcbiAqIHdpbGwgYmUgbG9hZGVkIGJhc2VkIG9uIG5lY2Vzc2l0eS5cbiAqIEBwYXJhbSB7VmVjdG9yVGlsZUZlYXR1cmV9IGZlYXR1cmVcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gbmVlZEdlb21ldHJ5XG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB0b0V2YWx1YXRpb25GZWF0dXJlKGZlYXR1cmU6IElWZWN0b3JUaWxlRmVhdHVyZSwgbmVlZEdlb21ldHJ5OiBib29sZWFuKTogRXZhbHVhdGlvbkZlYXR1cmUge1xuICAgIHJldHVybiB7dHlwZTogZmVhdHVyZS50eXBlLFxuICAgICAgICBpZDogZmVhdHVyZS5pZCxcbiAgICAgICAgcHJvcGVydGllczpmZWF0dXJlLnByb3BlcnRpZXMsXG4gICAgICAgIGdlb21ldHJ5OiBuZWVkR2VvbWV0cnkgPyBsb2FkR2VvbWV0cnkoZmVhdHVyZSkgOiBbXX07XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge0NpcmNsZUxheW91dEFycmF5LCBDaXJjbGVHbG9iZUV4dEFycmF5fSBmcm9tICcuLi9hcnJheV90eXBlcy5qcyc7XG5cbmltcG9ydCB7Y2lyY2xlQXR0cmlidXRlcywgY2lyY2xlR2xvYmVBdHRyaWJ1dGVzRXh0fSBmcm9tICcuL2NpcmNsZV9hdHRyaWJ1dGVzLmpzJztcbmltcG9ydCBTZWdtZW50VmVjdG9yIGZyb20gJy4uL3NlZ21lbnQuanMnO1xuaW1wb3J0IHtQcm9ncmFtQ29uZmlndXJhdGlvblNldH0gZnJvbSAnLi4vcHJvZ3JhbV9jb25maWd1cmF0aW9uLmpzJztcbmltcG9ydCB7VHJpYW5nbGVJbmRleEFycmF5fSBmcm9tICcuLi9pbmRleF9hcnJheV90eXBlLmpzJztcbmltcG9ydCBsb2FkR2VvbWV0cnkgZnJvbSAnLi4vbG9hZF9nZW9tZXRyeS5qcyc7XG5pbXBvcnQgdG9FdmFsdWF0aW9uRmVhdHVyZSBmcm9tICcuLi9ldmFsdWF0aW9uX2ZlYXR1cmUuanMnO1xuaW1wb3J0IEVYVEVOVCBmcm9tICcuLi9leHRlbnQuanMnO1xuaW1wb3J0IHtyZWdpc3Rlcn0gZnJvbSAnLi4vLi4vdXRpbC93ZWJfd29ya2VyX3RyYW5zZmVyLmpzJztcbmltcG9ydCBFdmFsdWF0aW9uUGFyYW1ldGVycyBmcm9tICcuLi8uLi9zdHlsZS9ldmFsdWF0aW9uX3BhcmFtZXRlcnMuanMnO1xuXG5pbXBvcnQgdHlwZSB7Q2Fub25pY2FsVGlsZUlEfSBmcm9tICcuLi8uLi9zb3VyY2UvdGlsZV9pZC5qcyc7XG5pbXBvcnQgdHlwZSB7XG4gICAgQnVja2V0LFxuICAgIEJ1Y2tldFBhcmFtZXRlcnMsXG4gICAgQnVja2V0RmVhdHVyZSxcbiAgICBJbmRleGVkRmVhdHVyZSxcbiAgICBQb3B1bGF0ZVBhcmFtZXRlcnNcbn0gZnJvbSAnLi4vYnVja2V0LmpzJztcbmltcG9ydCB0eXBlIENpcmNsZVN0eWxlTGF5ZXIgZnJvbSAnLi4vLi4vc3R5bGUvc3R5bGVfbGF5ZXIvY2lyY2xlX3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCB0eXBlIEhlYXRtYXBTdHlsZUxheWVyIGZyb20gJy4uLy4uL3N0eWxlL3N0eWxlX2xheWVyL2hlYXRtYXBfc3R5bGVfbGF5ZXIuanMnO1xuaW1wb3J0IHR5cGUgQ29udGV4dCBmcm9tICcuLi8uLi9nbC9jb250ZXh0LmpzJztcbmltcG9ydCB0eXBlIEluZGV4QnVmZmVyIGZyb20gJy4uLy4uL2dsL2luZGV4X2J1ZmZlci5qcyc7XG5pbXBvcnQgdHlwZSBWZXJ0ZXhCdWZmZXIgZnJvbSAnLi4vLi4vZ2wvdmVydGV4X2J1ZmZlci5qcyc7XG5pbXBvcnQgdHlwZSBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCB0eXBlIHtGZWF0dXJlU3RhdGVzfSBmcm9tICcuLi8uLi9zb3VyY2Uvc291cmNlX3N0YXRlLmpzJztcbmltcG9ydCB0eXBlIHtTcHJpdGVQb3NpdGlvbnN9IGZyb20gJy4uLy4uL3V0aWwvaW1hZ2UuanMnO1xuaW1wb3J0IHR5cGUge1RpbGVUcmFuc2Zvcm19IGZyb20gJy4uLy4uL2dlby9wcm9qZWN0aW9uL3RpbGVfdHJhbnNmb3JtLmpzJztcbmltcG9ydCB0eXBlIHtQcm9qZWN0aW9uU3BlY2lmaWNhdGlvbn0gZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy90eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSBQcm9qZWN0aW9uIGZyb20gJy4uLy4uL2dlby9wcm9qZWN0aW9uL3Byb2plY3Rpb24uanMnO1xuaW1wb3J0IHR5cGUge1ZlYzN9IGZyb20gJ2dsLW1hdHJpeCc7XG5pbXBvcnQgdHlwZSB7SVZlY3RvclRpbGVMYXllcn0gZnJvbSAnQG1hcGJveC92ZWN0b3ItdGlsZSc7XG5cbmZ1bmN0aW9uIGFkZENpcmNsZVZlcnRleChsYXlvdXRWZXJ0ZXhBcnJheTogQ2lyY2xlTGF5b3V0QXJyYXksIHg6IG51bWJlciwgeTogbnVtYmVyLCBleHRydWRlWDogbnVtYmVyLCBleHRydWRlWTogbnVtYmVyKSB7XG4gICAgbGF5b3V0VmVydGV4QXJyYXkuZW1wbGFjZUJhY2soXG4gICAgICAgICh4ICogMikgKyAoKGV4dHJ1ZGVYICsgMSkgLyAyKSxcbiAgICAgICAgKHkgKiAyKSArICgoZXh0cnVkZVkgKyAxKSAvIDIpKTtcbn1cblxuZnVuY3Rpb24gYWRkR2xvYmVFeHRWZXJ0ZXgodmVydGV4QXJyYXk6IENpcmNsZUdsb2JlRXh0QXJyYXksIHBvczoge3g6IG51bWJlciwgeTogbnVtYmVyLCB6OiBudW1iZXJ9LCBub3JtYWw6IFZlYzMpIHtcbiAgICBjb25zdCBlbmNvZGUgPSAxIDw8IDE0O1xuICAgIHZlcnRleEFycmF5LmVtcGxhY2VCYWNrKFxuICAgICAgICBwb3MueCwgcG9zLnksIHBvcy56LFxuICAgICAgICBub3JtYWxbMF0gKiBlbmNvZGUsIG5vcm1hbFsxXSAqIGVuY29kZSwgbm9ybWFsWzJdICogZW5jb2RlKTtcbn1cblxuLyoqXG4gKiBDaXJjbGVzIGFyZSByZXByZXNlbnRlZCBieSB0d28gdHJpYW5nbGVzLlxuICpcbiAqIEVhY2ggY29ybmVyIGhhcyBhIHBvcyB0aGF0IGlzIHRoZSBjZW50ZXIgb2YgdGhlIGNpcmNsZSBhbmQgYW4gZXh0cnVzaW9uXG4gKiB2ZWN0b3IgdGhhdCBpcyB3aGVyZSBpdCBwb2ludHMuXG4gKiBAcHJpdmF0ZVxuICovXG5jbGFzcyBDaXJjbGVCdWNrZXQ8TGF5ZXI6IENpcmNsZVN0eWxlTGF5ZXIgfCBIZWF0bWFwU3R5bGVMYXllcj4gaW1wbGVtZW50cyBCdWNrZXQge1xuICAgIGluZGV4OiBudW1iZXI7XG4gICAgem9vbTogbnVtYmVyO1xuICAgIG92ZXJzY2FsaW5nOiBudW1iZXI7XG4gICAgbGF5ZXJJZHM6IEFycmF5PHN0cmluZz47XG4gICAgbGF5ZXJzOiBBcnJheTxMYXllcj47XG4gICAgc3RhdGVEZXBlbmRlbnRMYXllcnM6IEFycmF5PExheWVyPjtcbiAgICBzdGF0ZURlcGVuZGVudExheWVySWRzOiBBcnJheTxzdHJpbmc+O1xuXG4gICAgbGF5b3V0VmVydGV4QXJyYXk6IENpcmNsZUxheW91dEFycmF5O1xuICAgIGxheW91dFZlcnRleEJ1ZmZlcjogVmVydGV4QnVmZmVyO1xuICAgIGdsb2JlRXh0VmVydGV4QXJyYXk6ID9DaXJjbGVHbG9iZUV4dEFycmF5O1xuICAgIGdsb2JlRXh0VmVydGV4QnVmZmVyOiA/VmVydGV4QnVmZmVyO1xuXG4gICAgaW5kZXhBcnJheTogVHJpYW5nbGVJbmRleEFycmF5O1xuICAgIGluZGV4QnVmZmVyOiBJbmRleEJ1ZmZlcjtcblxuICAgIGhhc1BhdHRlcm46IGJvb2xlYW47XG4gICAgcHJvZ3JhbUNvbmZpZ3VyYXRpb25zOiBQcm9ncmFtQ29uZmlndXJhdGlvblNldDxMYXllcj47XG4gICAgc2VnbWVudHM6IFNlZ21lbnRWZWN0b3I7XG4gICAgdXBsb2FkZWQ6IGJvb2xlYW47XG4gICAgcHJvamVjdGlvbjogUHJvamVjdGlvblNwZWNpZmljYXRpb247XG5cbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zOiBCdWNrZXRQYXJhbWV0ZXJzPExheWVyPikge1xuICAgICAgICB0aGlzLnpvb20gPSBvcHRpb25zLnpvb207XG4gICAgICAgIHRoaXMub3ZlcnNjYWxpbmcgPSBvcHRpb25zLm92ZXJzY2FsaW5nO1xuICAgICAgICB0aGlzLmxheWVycyA9IG9wdGlvbnMubGF5ZXJzO1xuICAgICAgICB0aGlzLmxheWVySWRzID0gdGhpcy5sYXllcnMubWFwKGxheWVyID0+IGxheWVyLmlkKTtcbiAgICAgICAgdGhpcy5pbmRleCA9IG9wdGlvbnMuaW5kZXg7XG4gICAgICAgIHRoaXMuaGFzUGF0dGVybiA9IGZhbHNlO1xuICAgICAgICB0aGlzLnByb2plY3Rpb24gPSBvcHRpb25zLnByb2plY3Rpb247XG5cbiAgICAgICAgdGhpcy5sYXlvdXRWZXJ0ZXhBcnJheSA9IG5ldyBDaXJjbGVMYXlvdXRBcnJheSgpO1xuICAgICAgICB0aGlzLmluZGV4QXJyYXkgPSBuZXcgVHJpYW5nbGVJbmRleEFycmF5KCk7XG4gICAgICAgIHRoaXMuc2VnbWVudHMgPSBuZXcgU2VnbWVudFZlY3RvcigpO1xuICAgICAgICB0aGlzLnByb2dyYW1Db25maWd1cmF0aW9ucyA9IG5ldyBQcm9ncmFtQ29uZmlndXJhdGlvblNldChvcHRpb25zLmxheWVycywgb3B0aW9ucy56b29tKTtcbiAgICAgICAgdGhpcy5zdGF0ZURlcGVuZGVudExheWVySWRzID0gdGhpcy5sYXllcnMuZmlsdGVyKChsKSA9PiBsLmlzU3RhdGVEZXBlbmRlbnQoKSkubWFwKChsKSA9PiBsLmlkKTtcbiAgICB9XG5cbiAgICBwb3B1bGF0ZShmZWF0dXJlczogQXJyYXk8SW5kZXhlZEZlYXR1cmU+LCBvcHRpb25zOiBQb3B1bGF0ZVBhcmFtZXRlcnMsIGNhbm9uaWNhbDogQ2Fub25pY2FsVGlsZUlELCB0aWxlVHJhbnNmb3JtOiBUaWxlVHJhbnNmb3JtKSB7XG4gICAgICAgIGNvbnN0IHN0eWxlTGF5ZXIgPSB0aGlzLmxheWVyc1swXTtcbiAgICAgICAgY29uc3QgYnVja2V0RmVhdHVyZXMgPSBbXTtcbiAgICAgICAgbGV0IGNpcmNsZVNvcnRLZXkgPSBudWxsO1xuXG4gICAgICAgIC8vIEhlYXRtYXAgbGF5ZXJzIGFyZSBoYW5kbGVkIGluIHRoaXMgYnVja2V0IGFuZCBoYXZlIG5vIGV2YWx1YXRlZCBwcm9wZXJ0aWVzLCBzbyB3ZSBjaGVjayBvdXIgYWNjZXNzXG4gICAgICAgIGlmIChzdHlsZUxheWVyLnR5cGUgPT09ICdjaXJjbGUnKSB7XG4gICAgICAgICAgICBjaXJjbGVTb3J0S2V5ID0gKChzdHlsZUxheWVyOiBhbnkpOiBDaXJjbGVTdHlsZUxheWVyKS5sYXlvdXQuZ2V0KCdjaXJjbGUtc29ydC1rZXknKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoY29uc3Qge2ZlYXR1cmUsIGlkLCBpbmRleCwgc291cmNlTGF5ZXJJbmRleH0gb2YgZmVhdHVyZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5lZWRHZW9tZXRyeSA9IHRoaXMubGF5ZXJzWzBdLl9mZWF0dXJlRmlsdGVyLm5lZWRHZW9tZXRyeTtcbiAgICAgICAgICAgIGNvbnN0IGV2YWx1YXRpb25GZWF0dXJlID0gdG9FdmFsdWF0aW9uRmVhdHVyZShmZWF0dXJlLCBuZWVkR2VvbWV0cnkpO1xuXG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICBpZiAoIXRoaXMubGF5ZXJzWzBdLl9mZWF0dXJlRmlsdGVyLmZpbHRlcihuZXcgRXZhbHVhdGlvblBhcmFtZXRlcnModGhpcy56b29tKSwgZXZhbHVhdGlvbkZlYXR1cmUsIGNhbm9uaWNhbCkpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICBjb25zdCBzb3J0S2V5ID0gY2lyY2xlU29ydEtleSA/XG4gICAgICAgICAgICAgICAgY2lyY2xlU29ydEtleS5ldmFsdWF0ZShldmFsdWF0aW9uRmVhdHVyZSwge30sIGNhbm9uaWNhbCkgOlxuICAgICAgICAgICAgICAgIHVuZGVmaW5lZDtcblxuICAgICAgICAgICAgY29uc3QgYnVja2V0RmVhdHVyZTogQnVja2V0RmVhdHVyZSA9IHtcbiAgICAgICAgICAgICAgICBpZCxcbiAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiBmZWF0dXJlLnByb3BlcnRpZXMsXG4gICAgICAgICAgICAgICAgdHlwZTogZmVhdHVyZS50eXBlLFxuICAgICAgICAgICAgICAgIHNvdXJjZUxheWVySW5kZXgsXG4gICAgICAgICAgICAgICAgaW5kZXgsXG4gICAgICAgICAgICAgICAgZ2VvbWV0cnk6IG5lZWRHZW9tZXRyeSA/IGV2YWx1YXRpb25GZWF0dXJlLmdlb21ldHJ5IDogbG9hZEdlb21ldHJ5KGZlYXR1cmUsIGNhbm9uaWNhbCwgdGlsZVRyYW5zZm9ybSksXG4gICAgICAgICAgICAgICAgcGF0dGVybnM6IHt9LFxuICAgICAgICAgICAgICAgIHNvcnRLZXlcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGJ1Y2tldEZlYXR1cmVzLnB1c2goYnVja2V0RmVhdHVyZSk7XG5cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjaXJjbGVTb3J0S2V5KSB7XG4gICAgICAgICAgICBidWNrZXRGZWF0dXJlcy5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gYS5zb3J0S2V5IGlzIGFsd2F5cyBhIG51bWJlciB3aGVuIGluIHVzZVxuICAgICAgICAgICAgICAgIHJldHVybiAoKGEuc29ydEtleTogYW55KTogbnVtYmVyKSAtICgoYi5zb3J0S2V5OiBhbnkpOiBudW1iZXIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgZ2xvYmVQcm9qZWN0aW9uOiA/UHJvamVjdGlvbiA9IG51bGw7XG5cbiAgICAgICAgaWYgKHRpbGVUcmFuc2Zvcm0ucHJvamVjdGlvbi5uYW1lID09PSAnZ2xvYmUnKSB7XG4gICAgICAgICAgICAvLyBFeHRlbmQgdmVydGV4IGF0dHJpYnV0ZXMgaWYgdGhlIGdsb2JlIHByb2plY3Rpb24gaXMgZW5hYmxlZFxuICAgICAgICAgICAgdGhpcy5nbG9iZUV4dFZlcnRleEFycmF5ID0gbmV3IENpcmNsZUdsb2JlRXh0QXJyYXkoKTtcbiAgICAgICAgICAgIGdsb2JlUHJvamVjdGlvbiA9IHRpbGVUcmFuc2Zvcm0ucHJvamVjdGlvbjtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoY29uc3QgYnVja2V0RmVhdHVyZSBvZiBidWNrZXRGZWF0dXJlcykge1xuICAgICAgICAgICAgY29uc3Qge2dlb21ldHJ5LCBpbmRleCwgc291cmNlTGF5ZXJJbmRleH0gPSBidWNrZXRGZWF0dXJlO1xuICAgICAgICAgICAgY29uc3QgZmVhdHVyZSA9IGZlYXR1cmVzW2luZGV4XS5mZWF0dXJlO1xuXG4gICAgICAgICAgICB0aGlzLmFkZEZlYXR1cmUoYnVja2V0RmVhdHVyZSwgZ2VvbWV0cnksIGluZGV4LCBvcHRpb25zLmF2YWlsYWJsZUltYWdlcywgY2Fub25pY2FsLCBnbG9iZVByb2plY3Rpb24pO1xuICAgICAgICAgICAgb3B0aW9ucy5mZWF0dXJlSW5kZXguaW5zZXJ0KGZlYXR1cmUsIGdlb21ldHJ5LCBpbmRleCwgc291cmNlTGF5ZXJJbmRleCwgdGhpcy5pbmRleCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB1cGRhdGUoc3RhdGVzOiBGZWF0dXJlU3RhdGVzLCB2dExheWVyOiBJVmVjdG9yVGlsZUxheWVyLCBhdmFpbGFibGVJbWFnZXM6IEFycmF5PHN0cmluZz4sIGltYWdlUG9zaXRpb25zOiBTcHJpdGVQb3NpdGlvbnMpIHtcbiAgICAgICAgaWYgKCF0aGlzLnN0YXRlRGVwZW5kZW50TGF5ZXJzLmxlbmd0aCkgcmV0dXJuO1xuICAgICAgICB0aGlzLnByb2dyYW1Db25maWd1cmF0aW9ucy51cGRhdGVQYWludEFycmF5cyhzdGF0ZXMsIHZ0TGF5ZXIsIHRoaXMuc3RhdGVEZXBlbmRlbnRMYXllcnMsIGF2YWlsYWJsZUltYWdlcywgaW1hZ2VQb3NpdGlvbnMpO1xuICAgIH1cblxuICAgIGlzRW1wdHkoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmxheW91dFZlcnRleEFycmF5Lmxlbmd0aCA9PT0gMDtcbiAgICB9XG5cbiAgICB1cGxvYWRQZW5kaW5nKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gIXRoaXMudXBsb2FkZWQgfHwgdGhpcy5wcm9ncmFtQ29uZmlndXJhdGlvbnMubmVlZHNVcGxvYWQ7XG4gICAgfVxuXG4gICAgdXBsb2FkKGNvbnRleHQ6IENvbnRleHQpIHtcbiAgICAgICAgaWYgKCF0aGlzLnVwbG9hZGVkKSB7XG4gICAgICAgICAgICB0aGlzLmxheW91dFZlcnRleEJ1ZmZlciA9IGNvbnRleHQuY3JlYXRlVmVydGV4QnVmZmVyKHRoaXMubGF5b3V0VmVydGV4QXJyYXksIGNpcmNsZUF0dHJpYnV0ZXMubWVtYmVycyk7XG4gICAgICAgICAgICB0aGlzLmluZGV4QnVmZmVyID0gY29udGV4dC5jcmVhdGVJbmRleEJ1ZmZlcih0aGlzLmluZGV4QXJyYXkpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5nbG9iZUV4dFZlcnRleEFycmF5KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5nbG9iZUV4dFZlcnRleEJ1ZmZlciA9IGNvbnRleHQuY3JlYXRlVmVydGV4QnVmZmVyKHRoaXMuZ2xvYmVFeHRWZXJ0ZXhBcnJheSwgY2lyY2xlR2xvYmVBdHRyaWJ1dGVzRXh0Lm1lbWJlcnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMucHJvZ3JhbUNvbmZpZ3VyYXRpb25zLnVwbG9hZChjb250ZXh0KTtcbiAgICAgICAgdGhpcy51cGxvYWRlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmxheW91dFZlcnRleEJ1ZmZlcikgcmV0dXJuO1xuICAgICAgICB0aGlzLmxheW91dFZlcnRleEJ1ZmZlci5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMuaW5kZXhCdWZmZXIuZGVzdHJveSgpO1xuICAgICAgICB0aGlzLnByb2dyYW1Db25maWd1cmF0aW9ucy5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMuc2VnbWVudHMuZGVzdHJveSgpO1xuICAgICAgICBpZiAodGhpcy5nbG9iZUV4dFZlcnRleEJ1ZmZlcikge1xuICAgICAgICAgICAgdGhpcy5nbG9iZUV4dFZlcnRleEJ1ZmZlci5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhZGRGZWF0dXJlKGZlYXR1cmU6IEJ1Y2tldEZlYXR1cmUsIGdlb21ldHJ5OiBBcnJheTxBcnJheTxQb2ludD4+LCBpbmRleDogbnVtYmVyLCBhdmFpbGFibGVJbWFnZXM6IEFycmF5PHN0cmluZz4sIGNhbm9uaWNhbDogQ2Fub25pY2FsVGlsZUlELCBwcm9qZWN0aW9uPzogP1Byb2plY3Rpb24pIHtcbiAgICAgICAgZm9yIChjb25zdCByaW5nIG9mIGdlb21ldHJ5KSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHBvaW50IG9mIHJpbmcpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB4ID0gcG9pbnQueDtcbiAgICAgICAgICAgICAgICBjb25zdCB5ID0gcG9pbnQueTtcblxuICAgICAgICAgICAgICAgIC8vIERvIG5vdCBpbmNsdWRlIHBvaW50cyB0aGF0IGFyZSBvdXRzaWRlIHRoZSB0aWxlIGJvdW5kYXJpZXMuXG4gICAgICAgICAgICAgICAgaWYgKHggPCAwIHx8IHggPj0gRVhURU5UIHx8IHkgPCAwIHx8IHkgPj0gRVhURU5UKSBjb250aW51ZTtcblxuICAgICAgICAgICAgICAgIC8vIHRoaXMgZ2VvbWV0cnkgd2lsbCBiZSBvZiB0aGUgUG9pbnQgdHlwZSwgYW5kIHdlJ2xsIGRlcml2ZVxuICAgICAgICAgICAgICAgIC8vIHR3byB0cmlhbmdsZXMgZnJvbSBpdC5cbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIC8vIOKUjOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUkFxuICAgICAgICAgICAgICAgIC8vIOKUgiAzICAgICAyIOKUglxuICAgICAgICAgICAgICAgIC8vIOKUgiAgICAgICAgIOKUglxuICAgICAgICAgICAgICAgIC8vIOKUgiAwICAgICAxIOKUglxuICAgICAgICAgICAgICAgIC8vIOKUlOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUmFxuXG4gICAgICAgICAgICAgICAgaWYgKHByb2plY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcHJvamVjdGVkUG9pbnQgPSBwcm9qZWN0aW9uLnByb2plY3RUaWxlUG9pbnQoeCwgeSwgY2Fub25pY2FsKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgbm9ybWFsID0gcHJvamVjdGlvbi51cFZlY3RvcihjYW5vbmljYWwsIHgsIHkpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhcnJheTogYW55ID0gdGhpcy5nbG9iZUV4dFZlcnRleEFycmF5O1xuXG4gICAgICAgICAgICAgICAgICAgIGFkZEdsb2JlRXh0VmVydGV4KGFycmF5LCBwcm9qZWN0ZWRQb2ludCwgbm9ybWFsKTtcbiAgICAgICAgICAgICAgICAgICAgYWRkR2xvYmVFeHRWZXJ0ZXgoYXJyYXksIHByb2plY3RlZFBvaW50LCBub3JtYWwpO1xuICAgICAgICAgICAgICAgICAgICBhZGRHbG9iZUV4dFZlcnRleChhcnJheSwgcHJvamVjdGVkUG9pbnQsIG5vcm1hbCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZEdsb2JlRXh0VmVydGV4KGFycmF5LCBwcm9qZWN0ZWRQb2ludCwgbm9ybWFsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3Qgc2VnbWVudCA9IHRoaXMuc2VnbWVudHMucHJlcGFyZVNlZ21lbnQoNCwgdGhpcy5sYXlvdXRWZXJ0ZXhBcnJheSwgdGhpcy5pbmRleEFycmF5LCBmZWF0dXJlLnNvcnRLZXkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gc2VnbWVudC52ZXJ0ZXhMZW5ndGg7XG5cbiAgICAgICAgICAgICAgICBhZGRDaXJjbGVWZXJ0ZXgodGhpcy5sYXlvdXRWZXJ0ZXhBcnJheSwgeCwgeSwgLTEsIC0xKTtcbiAgICAgICAgICAgICAgICBhZGRDaXJjbGVWZXJ0ZXgodGhpcy5sYXlvdXRWZXJ0ZXhBcnJheSwgeCwgeSwgMSwgLTEpO1xuICAgICAgICAgICAgICAgIGFkZENpcmNsZVZlcnRleCh0aGlzLmxheW91dFZlcnRleEFycmF5LCB4LCB5LCAxLCAxKTtcbiAgICAgICAgICAgICAgICBhZGRDaXJjbGVWZXJ0ZXgodGhpcy5sYXlvdXRWZXJ0ZXhBcnJheSwgeCwgeSwgLTEsIDEpO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5pbmRleEFycmF5LmVtcGxhY2VCYWNrKGluZGV4LCBpbmRleCArIDEsIGluZGV4ICsgMik7XG4gICAgICAgICAgICAgICAgdGhpcy5pbmRleEFycmF5LmVtcGxhY2VCYWNrKGluZGV4LCBpbmRleCArIDIsIGluZGV4ICsgMyk7XG5cbiAgICAgICAgICAgICAgICBzZWdtZW50LnZlcnRleExlbmd0aCArPSA0O1xuICAgICAgICAgICAgICAgIHNlZ21lbnQucHJpbWl0aXZlTGVuZ3RoICs9IDI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnByb2dyYW1Db25maWd1cmF0aW9ucy5wb3B1bGF0ZVBhaW50QXJyYXlzKHRoaXMubGF5b3V0VmVydGV4QXJyYXkubGVuZ3RoLCBmZWF0dXJlLCBpbmRleCwge30sIGF2YWlsYWJsZUltYWdlcywgY2Fub25pY2FsKTtcbiAgICB9XG59XG5cbnJlZ2lzdGVyKENpcmNsZUJ1Y2tldCwgJ0NpcmNsZUJ1Y2tldCcsIHtvbWl0OiBbJ2xheWVycyddfSk7XG5cbmV4cG9ydCBkZWZhdWx0IENpcmNsZUJ1Y2tldDtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCB7aXNDb3VudGVyQ2xvY2t3aXNlfSBmcm9tICcuL3V0aWwuanMnO1xuXG5pbXBvcnQgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5cbmV4cG9ydCB7cG9seWdvbkludGVyc2VjdHNCdWZmZXJlZFBvaW50LCBwb2x5Z29uSW50ZXJzZWN0c011bHRpUG9seWdvbiwgcG9seWdvbkludGVyc2VjdHNCdWZmZXJlZE11bHRpTGluZSwgcG9seWdvbkludGVyc2VjdHNQb2x5Z29uLCBkaXN0VG9TZWdtZW50U3F1YXJlZCwgcG9seWdvbkludGVyc2VjdHNCb3gsIHBvbHlnb25Db250YWluc1BvaW50fTtcblxudHlwZSBMaW5lID0gJFJlYWRPbmx5QXJyYXk8UG9pbnQ+O1xudHlwZSBNdWx0aUxpbmUgPSAkUmVhZE9ubHlBcnJheTxMaW5lPjtcbnR5cGUgUmluZyA9ICRSZWFkT25seUFycmF5PFBvaW50PjtcbnR5cGUgUG9seWdvbiA9ICRSZWFkT25seUFycmF5PFBvaW50PjtcbnR5cGUgTXVsdGlQb2x5Z29uID0gJFJlYWRPbmx5QXJyYXk8UG9seWdvbj47XG5cbmZ1bmN0aW9uIHBvbHlnb25JbnRlcnNlY3RzUG9seWdvbihwb2x5Z29uQTogUG9seWdvbiwgcG9seWdvbkI6IFBvbHlnb24pOiBib29sZWFuIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBvbHlnb25BLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChwb2x5Z29uQ29udGFpbnNQb2ludChwb2x5Z29uQiwgcG9seWdvbkFbaV0pKSByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBvbHlnb25CLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChwb2x5Z29uQ29udGFpbnNQb2ludChwb2x5Z29uQSwgcG9seWdvbkJbaV0pKSByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAobGluZUludGVyc2VjdHNMaW5lKHBvbHlnb25BLCBwb2x5Z29uQikpIHJldHVybiB0cnVlO1xuXG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBwb2x5Z29uSW50ZXJzZWN0c0J1ZmZlcmVkUG9pbnQocG9seWdvbjogUG9seWdvbiwgcG9pbnQ6IFBvaW50LCByYWRpdXM6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIGlmIChwb2x5Z29uQ29udGFpbnNQb2ludChwb2x5Z29uLCBwb2ludCkpIHJldHVybiB0cnVlO1xuICAgIGlmIChwb2ludEludGVyc2VjdHNCdWZmZXJlZExpbmUocG9pbnQsIHBvbHlnb24sIHJhZGl1cykpIHJldHVybiB0cnVlO1xuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gcG9seWdvbkludGVyc2VjdHNNdWx0aVBvbHlnb24ocG9seWdvbjogUG9seWdvbiwgbXVsdGlQb2x5Z29uOiBNdWx0aVBvbHlnb24pOiBib29sZWFuIHtcblxuICAgIGlmIChwb2x5Z29uLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICByZXR1cm4gbXVsdGlQb2x5Z29uQ29udGFpbnNQb2ludChtdWx0aVBvbHlnb24sIHBvbHlnb25bMF0pO1xuICAgIH1cblxuICAgIGZvciAobGV0IG0gPSAwOyBtIDwgbXVsdGlQb2x5Z29uLmxlbmd0aDsgbSsrKSB7XG4gICAgICAgIGNvbnN0IHJpbmcgPSBtdWx0aVBvbHlnb25bbV07XG4gICAgICAgIGZvciAobGV0IG4gPSAwOyBuIDwgcmluZy5sZW5ndGg7IG4rKykge1xuICAgICAgICAgICAgaWYgKHBvbHlnb25Db250YWluc1BvaW50KHBvbHlnb24sIHJpbmdbbl0pKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcG9seWdvbi5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAobXVsdGlQb2x5Z29uQ29udGFpbnNQb2ludChtdWx0aVBvbHlnb24sIHBvbHlnb25baV0pKSByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBrID0gMDsgayA8IG11bHRpUG9seWdvbi5sZW5ndGg7IGsrKykge1xuICAgICAgICBpZiAobGluZUludGVyc2VjdHNMaW5lKHBvbHlnb24sIG11bHRpUG9seWdvbltrXSkpIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gcG9seWdvbkludGVyc2VjdHNCdWZmZXJlZE11bHRpTGluZShwb2x5Z29uOiBQb2x5Z29uLCBtdWx0aUxpbmU6IE11bHRpTGluZSwgcmFkaXVzOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG11bHRpTGluZS5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBsaW5lID0gbXVsdGlMaW5lW2ldO1xuXG4gICAgICAgIGlmIChwb2x5Z29uLmxlbmd0aCA+PSAzKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IGxpbmUubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgICAgICAgICBpZiAocG9seWdvbkNvbnRhaW5zUG9pbnQocG9seWdvbiwgbGluZVtrXSkpIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGxpbmVJbnRlcnNlY3RzQnVmZmVyZWRMaW5lKHBvbHlnb24sIGxpbmUsIHJhZGl1cykpIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGxpbmVJbnRlcnNlY3RzQnVmZmVyZWRMaW5lKGxpbmVBOiBMaW5lLCBsaW5lQjogTGluZSwgcmFkaXVzOiBudW1iZXIpIHtcblxuICAgIGlmIChsaW5lQS5sZW5ndGggPiAxKSB7XG4gICAgICAgIGlmIChsaW5lSW50ZXJzZWN0c0xpbmUobGluZUEsIGxpbmVCKSkgcmV0dXJuIHRydWU7XG5cbiAgICAgICAgLy8gQ2hlY2sgd2hldGhlciBhbnkgcG9pbnQgaW4gZWl0aGVyIGxpbmUgaXMgd2l0aGluIHJhZGl1cyBvZiB0aGUgb3RoZXIgbGluZVxuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGxpbmVCLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICBpZiAocG9pbnRJbnRlcnNlY3RzQnVmZmVyZWRMaW5lKGxpbmVCW2pdLCBsaW5lQSwgcmFkaXVzKSkgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGxldCBrID0gMDsgayA8IGxpbmVBLmxlbmd0aDsgaysrKSB7XG4gICAgICAgIGlmIChwb2ludEludGVyc2VjdHNCdWZmZXJlZExpbmUobGluZUFba10sIGxpbmVCLCByYWRpdXMpKSByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGxpbmVJbnRlcnNlY3RzTGluZShsaW5lQTogTGluZSwgbGluZUI6IExpbmUpIHtcbiAgICBpZiAobGluZUEubGVuZ3RoID09PSAwIHx8IGxpbmVCLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGZhbHNlO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGluZUEubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGEwID0gbGluZUFbaV07XG4gICAgICAgIGNvbnN0IGExID0gbGluZUFbaSArIDFdO1xuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGxpbmVCLmxlbmd0aCAtIDE7IGorKykge1xuICAgICAgICAgICAgY29uc3QgYjAgPSBsaW5lQltqXTtcbiAgICAgICAgICAgIGNvbnN0IGIxID0gbGluZUJbaiArIDFdO1xuICAgICAgICAgICAgaWYgKGxpbmVTZWdtZW50SW50ZXJzZWN0c0xpbmVTZWdtZW50KGEwLCBhMSwgYjAsIGIxKSkgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBsaW5lU2VnbWVudEludGVyc2VjdHNMaW5lU2VnbWVudChhMDogUG9pbnQsIGExOiBQb2ludCwgYjA6IFBvaW50LCBiMTogUG9pbnQpIHtcbiAgICByZXR1cm4gaXNDb3VudGVyQ2xvY2t3aXNlKGEwLCBiMCwgYjEpICE9PSBpc0NvdW50ZXJDbG9ja3dpc2UoYTEsIGIwLCBiMSkgJiZcbiAgICAgICAgaXNDb3VudGVyQ2xvY2t3aXNlKGEwLCBhMSwgYjApICE9PSBpc0NvdW50ZXJDbG9ja3dpc2UoYTAsIGExLCBiMSk7XG59XG5cbmZ1bmN0aW9uIHBvaW50SW50ZXJzZWN0c0J1ZmZlcmVkTGluZShwOiBQb2ludCwgbGluZTogTGluZSwgcmFkaXVzOiBudW1iZXIpIHtcbiAgICBjb25zdCByYWRpdXNTcXVhcmVkID0gcmFkaXVzICogcmFkaXVzO1xuXG4gICAgaWYgKGxpbmUubGVuZ3RoID09PSAxKSByZXR1cm4gcC5kaXN0U3FyKGxpbmVbMF0pIDwgcmFkaXVzU3F1YXJlZDtcblxuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgbGluZS5sZW5ndGg7IGkrKykge1xuICAgICAgICAvLyBGaW5kIGxpbmUgc2VnbWVudHMgdGhhdCBoYXZlIGEgZGlzdGFuY2UgPD0gcmFkaXVzXjIgdG8gcFxuICAgICAgICAvLyBJbiB0aGF0IGNhc2UsIHdlIHRyZWF0IHRoZSBsaW5lIGFzIFwiY29udGFpbmluZyBwb2ludCBwXCIuXG4gICAgICAgIGNvbnN0IHYgPSBsaW5lW2kgLSAxXSwgdyA9IGxpbmVbaV07XG4gICAgICAgIGlmIChkaXN0VG9TZWdtZW50U3F1YXJlZChwLCB2LCB3KSA8IHJhZGl1c1NxdWFyZWQpIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbi8vIENvZGUgZnJvbSBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8xNTAxNzI1LzMzMTM3OS5cbmZ1bmN0aW9uIGRpc3RUb1NlZ21lbnRTcXVhcmVkKHA6IFBvaW50LCB2OiBQb2ludCwgdzogUG9pbnQpOiBudW1iZXIge1xuICAgIGNvbnN0IGwyID0gdi5kaXN0U3FyKHcpO1xuICAgIGlmIChsMiA9PT0gMCkgcmV0dXJuIHAuZGlzdFNxcih2KTtcbiAgICBjb25zdCB0ID0gKChwLnggLSB2LngpICogKHcueCAtIHYueCkgKyAocC55IC0gdi55KSAqICh3LnkgLSB2LnkpKSAvIGwyO1xuICAgIGlmICh0IDwgMCkgcmV0dXJuIHAuZGlzdFNxcih2KTtcbiAgICBpZiAodCA+IDEpIHJldHVybiBwLmRpc3RTcXIodyk7XG4gICAgcmV0dXJuIHAuZGlzdFNxcih3LnN1Yih2KS5fbXVsdCh0KS5fYWRkKHYpKTtcbn1cblxuLy8gcG9pbnQgaW4gcG9seWdvbiByYXkgY2FzdGluZyBhbGdvcml0aG1cbmZ1bmN0aW9uIG11bHRpUG9seWdvbkNvbnRhaW5zUG9pbnQocmluZ3M6IE11bHRpUG9seWdvbiwgcDogUG9pbnQpIHtcbiAgICBsZXQgYyA9IGZhbHNlLFxuICAgICAgICByaW5nLCBwMSwgcDI7XG5cbiAgICBmb3IgKGxldCBrID0gMDsgayA8IHJpbmdzLmxlbmd0aDsgaysrKSB7XG4gICAgICAgIHJpbmcgPSByaW5nc1trXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGogPSByaW5nLmxlbmd0aCAtIDE7IGkgPCByaW5nLmxlbmd0aDsgaiA9IGkrKykge1xuICAgICAgICAgICAgcDEgPSByaW5nW2ldO1xuICAgICAgICAgICAgcDIgPSByaW5nW2pdO1xuICAgICAgICAgICAgaWYgKCgocDEueSA+IHAueSkgIT09IChwMi55ID4gcC55KSkgJiYgKHAueCA8IChwMi54IC0gcDEueCkgKiAocC55IC0gcDEueSkgLyAocDIueSAtIHAxLnkpICsgcDEueCkpIHtcbiAgICAgICAgICAgICAgICBjID0gIWM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGM7XG59XG5cbmZ1bmN0aW9uIHBvbHlnb25Db250YWluc1BvaW50KHJpbmc6IFJpbmcsIHA6IFBvaW50KTogYm9vbGVhbiB7XG4gICAgbGV0IGMgPSBmYWxzZTtcbiAgICBmb3IgKGxldCBpID0gMCwgaiA9IHJpbmcubGVuZ3RoIC0gMTsgaSA8IHJpbmcubGVuZ3RoOyBqID0gaSsrKSB7XG4gICAgICAgIGNvbnN0IHAxID0gcmluZ1tpXTtcbiAgICAgICAgY29uc3QgcDIgPSByaW5nW2pdO1xuICAgICAgICBpZiAoKChwMS55ID4gcC55KSAhPT0gKHAyLnkgPiBwLnkpKSAmJiAocC54IDwgKHAyLnggLSBwMS54KSAqIChwLnkgLSBwMS55KSAvIChwMi55IC0gcDEueSkgKyBwMS54KSkge1xuICAgICAgICAgICAgYyA9ICFjO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBjO1xufVxuXG5mdW5jdGlvbiBwb2x5Z29uSW50ZXJzZWN0c0JveChyaW5nOiBSaW5nLCBib3hYMTogbnVtYmVyLCBib3hZMTogbnVtYmVyLCBib3hYMjogbnVtYmVyLCBib3hZMjogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgZm9yIChjb25zdCBwIG9mIHJpbmcpIHtcbiAgICAgICAgaWYgKGJveFgxIDw9IHAueCAmJlxuICAgICAgICAgICAgYm94WTEgPD0gcC55ICYmXG4gICAgICAgICAgICBib3hYMiA+PSBwLnggJiZcbiAgICAgICAgICAgIGJveFkyID49IHAueSkgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgY29uc3QgY29ybmVycyA9IFtcbiAgICAgICAgbmV3IFBvaW50KGJveFgxLCBib3hZMSksXG4gICAgICAgIG5ldyBQb2ludChib3hYMSwgYm94WTIpLFxuICAgICAgICBuZXcgUG9pbnQoYm94WDIsIGJveFkyKSxcbiAgICAgICAgbmV3IFBvaW50KGJveFgyLCBib3hZMSldO1xuXG4gICAgaWYgKHJpbmcubGVuZ3RoID4gMikge1xuICAgICAgICBmb3IgKGNvbnN0IGNvcm5lciBvZiBjb3JuZXJzKSB7XG4gICAgICAgICAgICBpZiAocG9seWdvbkNvbnRhaW5zUG9pbnQocmluZywgY29ybmVyKSkgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJpbmcubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHAxID0gcmluZ1tpXTtcbiAgICAgICAgY29uc3QgcDIgPSByaW5nW2kgKyAxXTtcbiAgICAgICAgaWYgKGVkZ2VJbnRlcnNlY3RzQm94KHAxLCBwMiwgY29ybmVycykpIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gZWRnZUludGVyc2VjdHNCb3goZTE6IFBvaW50LCBlMjogUG9pbnQsIGNvcm5lcnM6IEFycmF5PFBvaW50Pikge1xuICAgIGNvbnN0IHRsID0gY29ybmVyc1swXTtcbiAgICBjb25zdCBiciA9IGNvcm5lcnNbMl07XG4gICAgLy8gdGhlIGVkZ2UgYW5kIGJveCBkbyBub3QgaW50ZXJzZWN0IGluIGVpdGhlciB0aGUgeCBvciB5IGRpbWVuc2lvbnNcbiAgICBpZiAoKChlMS54IDwgdGwueCkgJiYgKGUyLnggPCB0bC54KSkgfHxcbiAgICAgICAgKChlMS54ID4gYnIueCkgJiYgKGUyLnggPiBici54KSkgfHxcbiAgICAgICAgKChlMS55IDwgdGwueSkgJiYgKGUyLnkgPCB0bC55KSkgfHxcbiAgICAgICAgKChlMS55ID4gYnIueSkgJiYgKGUyLnkgPiBici55KSkpIHJldHVybiBmYWxzZTtcblxuICAgIC8vIGNoZWNrIGlmIGFsbCBjb3JuZXJzIG9mIHRoZSBib3ggYXJlIG9uIHRoZSBzYW1lIHNpZGUgb2YgdGhlIGVkZ2VcbiAgICBjb25zdCBkaXIgPSBpc0NvdW50ZXJDbG9ja3dpc2UoZTEsIGUyLCBjb3JuZXJzWzBdKTtcbiAgICByZXR1cm4gZGlyICE9PSBpc0NvdW50ZXJDbG9ja3dpc2UoZTEsIGUyLCBjb3JuZXJzWzFdKSB8fFxuICAgICAgICBkaXIgIT09IGlzQ291bnRlckNsb2Nrd2lzZShlMSwgZTIsIGNvcm5lcnNbMl0pIHx8XG4gICAgICAgIGRpciAhPT0gaXNDb3VudGVyQ2xvY2t3aXNlKGUxLCBlMiwgY29ybmVyc1szXSk7XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5cbmltcG9ydCB0eXBlIHtQb3NzaWJseUV2YWx1YXRlZFByb3BlcnR5VmFsdWV9IGZyb20gJy4vcHJvcGVydGllcy5qcyc7XG5pbXBvcnQgdHlwZSBTdHlsZUxheWVyIGZyb20gJy4uL3N0eWxlL3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCB0eXBlIENpcmNsZUJ1Y2tldCBmcm9tICcuLi9kYXRhL2J1Y2tldC9jaXJjbGVfYnVja2V0LmpzJztcbmltcG9ydCB0eXBlIExpbmVCdWNrZXQgZnJvbSAnLi4vZGF0YS9idWNrZXQvbGluZV9idWNrZXQuanMnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TWF4aW11bVBhaW50VmFsdWUocHJvcGVydHk6IHN0cmluZywgbGF5ZXI6IFN0eWxlTGF5ZXIsIGJ1Y2tldDogQ2lyY2xlQnVja2V0PCo+IHwgTGluZUJ1Y2tldCk6IG51bWJlciB7XG4gICAgY29uc3QgdmFsdWUgPSAoKGxheWVyLnBhaW50OiBhbnkpLmdldChwcm9wZXJ0eSk6IFBvc3NpYmx5RXZhbHVhdGVkUHJvcGVydHlWYWx1ZTxhbnk+KS52YWx1ZTtcbiAgICBpZiAodmFsdWUua2luZCA9PT0gJ2NvbnN0YW50Jykge1xuICAgICAgICByZXR1cm4gdmFsdWUudmFsdWU7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGJ1Y2tldC5wcm9ncmFtQ29uZmlndXJhdGlvbnMuZ2V0KGxheWVyLmlkKS5nZXRNYXhWYWx1ZShwcm9wZXJ0eSk7XG4gICAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNsYXRlRGlzdGFuY2UodHJhbnNsYXRlOiBbbnVtYmVyLCBudW1iZXJdKTogbnVtYmVyIHtcbiAgICByZXR1cm4gTWF0aC5zcXJ0KHRyYW5zbGF0ZVswXSAqIHRyYW5zbGF0ZVswXSArIHRyYW5zbGF0ZVsxXSAqIHRyYW5zbGF0ZVsxXSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2xhdGUocXVlcnlHZW9tZXRyeTogQXJyYXk8UG9pbnQ+LFxuICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZTogW251bWJlciwgbnVtYmVyXSxcbiAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGVBbmNob3I6ICd2aWV3cG9ydCcgfCAnbWFwJyxcbiAgICAgICAgICAgICAgICAgICBiZWFyaW5nOiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgcGl4ZWxzVG9UaWxlVW5pdHM6IG51bWJlcik6IEFycmF5PFBvaW50PiB7XG4gICAgaWYgKCF0cmFuc2xhdGVbMF0gJiYgIXRyYW5zbGF0ZVsxXSkge1xuICAgICAgICByZXR1cm4gcXVlcnlHZW9tZXRyeTtcbiAgICB9XG4gICAgY29uc3QgcHQgPSBQb2ludC5jb252ZXJ0KHRyYW5zbGF0ZSkuX211bHQocGl4ZWxzVG9UaWxlVW5pdHMpO1xuXG4gICAgaWYgKHRyYW5zbGF0ZUFuY2hvciA9PT0gXCJ2aWV3cG9ydFwiKSB7XG4gICAgICAgIHB0Ll9yb3RhdGUoLWJlYXJpbmcpO1xuICAgIH1cblxuICAgIGNvbnN0IHRyYW5zbGF0ZWQgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHF1ZXJ5R2VvbWV0cnkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgcG9pbnQgPSBxdWVyeUdlb21ldHJ5W2ldO1xuICAgICAgICB0cmFuc2xhdGVkLnB1c2gocG9pbnQuc3ViKHB0KSk7XG4gICAgfVxuICAgIHJldHVybiB0cmFuc2xhdGVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdGlsZXNwYWNlVHJhbnNsYXRlKHRyYW5zbGF0ZTogW251bWJlciwgbnVtYmVyXSxcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlQW5jaG9yOiAndmlld3BvcnQnIHwgJ21hcCcsXG4gICAgICAgICAgICAgICAgICAgIGJlYXJpbmc6IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgcGl4ZWxzVG9UaWxlVW5pdHM6IG51bWJlcik6IFBvaW50IHtcbiAgICBjb25zdCBwdCA9IFBvaW50LmNvbnZlcnQodHJhbnNsYXRlKS5fbXVsdChwaXhlbHNUb1RpbGVVbml0cyk7XG5cbiAgICBpZiAodHJhbnNsYXRlQW5jaG9yID09PSBcInZpZXdwb3J0XCIpIHtcbiAgICAgICAgcHQuX3JvdGF0ZSgtYmVhcmluZyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHB0O1xufVxuIiwiLy8gVGhpcyBmaWxlIGlzIGdlbmVyYXRlZC4gRWRpdCBidWlsZC9nZW5lcmF0ZS1zdHlsZS1jb2RlLmpzLCB0aGVuIHJ1biBgeWFybiBydW4gY29kZWdlbmAuXG4vLyBAZmxvd1xuLyogZXNsaW50LWRpc2FibGUgKi9cblxuaW1wb3J0IHN0eWxlU3BlYyBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL3JlZmVyZW5jZS9sYXRlc3QuanMnO1xuXG5pbXBvcnQge1xuICAgIFByb3BlcnRpZXMsXG4gICAgRGF0YUNvbnN0YW50UHJvcGVydHksXG4gICAgRGF0YURyaXZlblByb3BlcnR5LFxuICAgIENvbG9yUmFtcFByb3BlcnR5XG59IGZyb20gJy4uL3Byb3BlcnRpZXMuanMnO1xuXG5pbXBvcnQgdHlwZSBDb2xvciBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL3V0aWwvY29sb3IuanMnO1xuXG5pbXBvcnQgdHlwZSBGb3JtYXR0ZWQgZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy9leHByZXNzaW9uL3R5cGVzL2Zvcm1hdHRlZC5qcyc7XG5cbmltcG9ydCB0eXBlIFJlc29sdmVkSW1hZ2UgZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy9leHByZXNzaW9uL3R5cGVzL3Jlc29sdmVkX2ltYWdlLmpzJztcblxuZXhwb3J0IHR5cGUgTGF5b3V0UHJvcHMgPSB7fFxuICAgIFwiY2lyY2xlLXNvcnQta2V5XCI6IERhdGFEcml2ZW5Qcm9wZXJ0eTxudW1iZXI+LFxufH07XG5cbmNvbnN0IGxheW91dDogUHJvcGVydGllczxMYXlvdXRQcm9wcz4gPSBuZXcgUHJvcGVydGllcyh7XG4gICAgXCJjaXJjbGUtc29ydC1rZXlcIjogbmV3IERhdGFEcml2ZW5Qcm9wZXJ0eShzdHlsZVNwZWNbXCJsYXlvdXRfY2lyY2xlXCJdW1wiY2lyY2xlLXNvcnQta2V5XCJdKSxcbn0pO1xuXG5leHBvcnQgdHlwZSBQYWludFByb3BzID0ge3xcbiAgICBcImNpcmNsZS1yYWRpdXNcIjogRGF0YURyaXZlblByb3BlcnR5PG51bWJlcj4sXG4gICAgXCJjaXJjbGUtY29sb3JcIjogRGF0YURyaXZlblByb3BlcnR5PENvbG9yPixcbiAgICBcImNpcmNsZS1ibHVyXCI6IERhdGFEcml2ZW5Qcm9wZXJ0eTxudW1iZXI+LFxuICAgIFwiY2lyY2xlLW9wYWNpdHlcIjogRGF0YURyaXZlblByb3BlcnR5PG51bWJlcj4sXG4gICAgXCJjaXJjbGUtdHJhbnNsYXRlXCI6IERhdGFDb25zdGFudFByb3BlcnR5PFtudW1iZXIsIG51bWJlcl0+LFxuICAgIFwiY2lyY2xlLXRyYW5zbGF0ZS1hbmNob3JcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8XCJtYXBcIiB8IFwidmlld3BvcnRcIj4sXG4gICAgXCJjaXJjbGUtcGl0Y2gtc2NhbGVcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8XCJtYXBcIiB8IFwidmlld3BvcnRcIj4sXG4gICAgXCJjaXJjbGUtcGl0Y2gtYWxpZ25tZW50XCI6IERhdGFDb25zdGFudFByb3BlcnR5PFwibWFwXCIgfCBcInZpZXdwb3J0XCI+LFxuICAgIFwiY2lyY2xlLXN0cm9rZS13aWR0aFwiOiBEYXRhRHJpdmVuUHJvcGVydHk8bnVtYmVyPixcbiAgICBcImNpcmNsZS1zdHJva2UtY29sb3JcIjogRGF0YURyaXZlblByb3BlcnR5PENvbG9yPixcbiAgICBcImNpcmNsZS1zdHJva2Utb3BhY2l0eVwiOiBEYXRhRHJpdmVuUHJvcGVydHk8bnVtYmVyPixcbnx9O1xuXG5jb25zdCBwYWludDogUHJvcGVydGllczxQYWludFByb3BzPiA9IG5ldyBQcm9wZXJ0aWVzKHtcbiAgICBcImNpcmNsZS1yYWRpdXNcIjogbmV3IERhdGFEcml2ZW5Qcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9jaXJjbGVcIl1bXCJjaXJjbGUtcmFkaXVzXCJdKSxcbiAgICBcImNpcmNsZS1jb2xvclwiOiBuZXcgRGF0YURyaXZlblByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X2NpcmNsZVwiXVtcImNpcmNsZS1jb2xvclwiXSksXG4gICAgXCJjaXJjbGUtYmx1clwiOiBuZXcgRGF0YURyaXZlblByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X2NpcmNsZVwiXVtcImNpcmNsZS1ibHVyXCJdKSxcbiAgICBcImNpcmNsZS1vcGFjaXR5XCI6IG5ldyBEYXRhRHJpdmVuUHJvcGVydHkoc3R5bGVTcGVjW1wicGFpbnRfY2lyY2xlXCJdW1wiY2lyY2xlLW9wYWNpdHlcIl0pLFxuICAgIFwiY2lyY2xlLXRyYW5zbGF0ZVwiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjW1wicGFpbnRfY2lyY2xlXCJdW1wiY2lyY2xlLXRyYW5zbGF0ZVwiXSksXG4gICAgXCJjaXJjbGUtdHJhbnNsYXRlLWFuY2hvclwiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjW1wicGFpbnRfY2lyY2xlXCJdW1wiY2lyY2xlLXRyYW5zbGF0ZS1hbmNob3JcIl0pLFxuICAgIFwiY2lyY2xlLXBpdGNoLXNjYWxlXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9jaXJjbGVcIl1bXCJjaXJjbGUtcGl0Y2gtc2NhbGVcIl0pLFxuICAgIFwiY2lyY2xlLXBpdGNoLWFsaWdubWVudFwiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjW1wicGFpbnRfY2lyY2xlXCJdW1wiY2lyY2xlLXBpdGNoLWFsaWdubWVudFwiXSksXG4gICAgXCJjaXJjbGUtc3Ryb2tlLXdpZHRoXCI6IG5ldyBEYXRhRHJpdmVuUHJvcGVydHkoc3R5bGVTcGVjW1wicGFpbnRfY2lyY2xlXCJdW1wiY2lyY2xlLXN0cm9rZS13aWR0aFwiXSksXG4gICAgXCJjaXJjbGUtc3Ryb2tlLWNvbG9yXCI6IG5ldyBEYXRhRHJpdmVuUHJvcGVydHkoc3R5bGVTcGVjW1wicGFpbnRfY2lyY2xlXCJdW1wiY2lyY2xlLXN0cm9rZS1jb2xvclwiXSksXG4gICAgXCJjaXJjbGUtc3Ryb2tlLW9wYWNpdHlcIjogbmV3IERhdGFEcml2ZW5Qcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9jaXJjbGVcIl1bXCJjaXJjbGUtc3Ryb2tlLW9wYWNpdHlcIl0pLFxufSk7XG5cbi8vIE5vdGU6IHdpdGhvdXQgYWRkaW5nIHRoZSBleHBsaWNpdCB0eXBlIGFubm90YXRpb24sIEZsb3cgaW5mZXJzIHdlYWtlciB0eXBlc1xuLy8gZm9yIHRoZXNlIG9iamVjdHMgZnJvbSB0aGVpciB1c2UgaW4gdGhlIGNvbnN0cnVjdG9yIHRvIFN0eWxlTGF5ZXIsIGFzXG4vLyB7bGF5b3V0PzogUHJvcGVydGllczwuLi4+LCBwYWludDogUHJvcGVydGllczwuLi4+fVxuZXhwb3J0IGRlZmF1bHQgKHsgcGFpbnQsIGxheW91dCB9OiAkRXhhY3Q8e1xuICBwYWludDogUHJvcGVydGllczxQYWludFByb3BzPiwgbGF5b3V0OiBQcm9wZXJ0aWVzPExheW91dFByb3BzPlxufT4pO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IFN0eWxlTGF5ZXIgZnJvbSAnLi4vc3R5bGVfbGF5ZXIuanMnO1xuXG5pbXBvcnQgQ2lyY2xlQnVja2V0IGZyb20gJy4uLy4uL2RhdGEvYnVja2V0L2NpcmNsZV9idWNrZXQuanMnO1xuaW1wb3J0IHtwb2x5Z29uSW50ZXJzZWN0c0J1ZmZlcmVkUG9pbnR9IGZyb20gJy4uLy4uL3V0aWwvaW50ZXJzZWN0aW9uX3Rlc3RzLmpzJztcbmltcG9ydCB7Z2V0TWF4aW11bVBhaW50VmFsdWUsIHRyYW5zbGF0ZURpc3RhbmNlLCB0aWxlc3BhY2VUcmFuc2xhdGV9IGZyb20gJy4uL3F1ZXJ5X3V0aWxzLmpzJztcbmltcG9ydCBwcm9wZXJ0aWVzIGZyb20gJy4vY2lyY2xlX3N0eWxlX2xheWVyX3Byb3BlcnRpZXMuanMnO1xuaW1wb3J0IHtUcmFuc2l0aW9uYWJsZSwgVHJhbnNpdGlvbmluZywgTGF5b3V0LCBQb3NzaWJseUV2YWx1YXRlZH0gZnJvbSAnLi4vcHJvcGVydGllcy5qcyc7XG5pbXBvcnQge3ZlYzQsIHZlYzN9IGZyb20gJ2dsLW1hdHJpeCc7XG5pbXBvcnQgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5pbXBvcnQgUHJvZ3JhbUNvbmZpZ3VyYXRpb24gZnJvbSAnLi4vLi4vZGF0YS9wcm9ncmFtX2NvbmZpZ3VyYXRpb24uanMnO1xuaW1wb3J0IHtSYXl9IGZyb20gJy4uLy4uL3V0aWwvcHJpbWl0aXZlcy5qcyc7XG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQge2xhdEZyb21NZXJjYXRvclksIG1lcmNhdG9yWmZyb21BbHRpdHVkZX0gZnJvbSAnLi4vLi4vZ2VvL21lcmNhdG9yX2Nvb3JkaW5hdGUuanMnO1xuaW1wb3J0IEVYVEVOVCBmcm9tICcuLi8uLi9kYXRhL2V4dGVudC5qcyc7XG5cbmltcG9ydCB0eXBlIHtGZWF0dXJlU3RhdGV9IGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi9pbmRleC5qcyc7XG5pbXBvcnQgdHlwZSBUcmFuc2Zvcm0gZnJvbSAnLi4vLi4vZ2VvL3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQgdHlwZSB7QnVja2V0LCBCdWNrZXRQYXJhbWV0ZXJzfSBmcm9tICcuLi8uLi9kYXRhL2J1Y2tldC5qcyc7XG5pbXBvcnQgdHlwZSB7TGF5b3V0UHJvcHMsIFBhaW50UHJvcHN9IGZyb20gJy4vY2lyY2xlX3N0eWxlX2xheWVyX3Byb3BlcnRpZXMuanMnO1xuaW1wb3J0IHR5cGUge0xheWVyU3BlY2lmaWNhdGlvbn0gZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy90eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSB7VGlsZXNwYWNlUXVlcnlHZW9tZXRyeX0gZnJvbSAnLi4vcXVlcnlfZ2VvbWV0cnkuanMnO1xuaW1wb3J0IHR5cGUge0RFTVNhbXBsZXJ9IGZyb20gJy4uLy4uL3RlcnJhaW4vZWxldmF0aW9uLmpzJztcbmltcG9ydCB0eXBlIHtJVmVjdG9yVGlsZUZlYXR1cmV9IGZyb20gJ0BtYXBib3gvdmVjdG9yLXRpbGUnO1xuXG5jbGFzcyBDaXJjbGVTdHlsZUxheWVyIGV4dGVuZHMgU3R5bGVMYXllciB7XG4gICAgX3VuZXZhbHVhdGVkTGF5b3V0OiBMYXlvdXQ8TGF5b3V0UHJvcHM+O1xuICAgIGxheW91dDogUG9zc2libHlFdmFsdWF0ZWQ8TGF5b3V0UHJvcHM+O1xuXG4gICAgX3RyYW5zaXRpb25hYmxlUGFpbnQ6IFRyYW5zaXRpb25hYmxlPFBhaW50UHJvcHM+O1xuICAgIF90cmFuc2l0aW9uaW5nUGFpbnQ6IFRyYW5zaXRpb25pbmc8UGFpbnRQcm9wcz47XG4gICAgcGFpbnQ6IFBvc3NpYmx5RXZhbHVhdGVkPFBhaW50UHJvcHM+O1xuXG4gICAgY29uc3RydWN0b3IobGF5ZXI6IExheWVyU3BlY2lmaWNhdGlvbikge1xuICAgICAgICBzdXBlcihsYXllciwgcHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgY3JlYXRlQnVja2V0KHBhcmFtZXRlcnM6IEJ1Y2tldFBhcmFtZXRlcnM8Q2lyY2xlU3R5bGVMYXllcj4pOiBDaXJjbGVCdWNrZXQ8Q2lyY2xlU3R5bGVMYXllcj4ge1xuICAgICAgICByZXR1cm4gbmV3IENpcmNsZUJ1Y2tldChwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgcXVlcnlSYWRpdXMoYnVja2V0OiBCdWNrZXQpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBjaXJjbGVCdWNrZXQ6IENpcmNsZUJ1Y2tldDxDaXJjbGVTdHlsZUxheWVyPiA9IChidWNrZXQ6IGFueSk7XG4gICAgICAgIHJldHVybiBnZXRNYXhpbXVtUGFpbnRWYWx1ZSgnY2lyY2xlLXJhZGl1cycsIHRoaXMsIGNpcmNsZUJ1Y2tldCkgK1xuICAgICAgICAgICAgZ2V0TWF4aW11bVBhaW50VmFsdWUoJ2NpcmNsZS1zdHJva2Utd2lkdGgnLCB0aGlzLCBjaXJjbGVCdWNrZXQpICtcbiAgICAgICAgICAgIHRyYW5zbGF0ZURpc3RhbmNlKHRoaXMucGFpbnQuZ2V0KCdjaXJjbGUtdHJhbnNsYXRlJykpO1xuICAgIH1cblxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICBxdWVyeUludGVyc2VjdHNGZWF0dXJlKHF1ZXJ5R2VvbWV0cnk6IFRpbGVzcGFjZVF1ZXJ5R2VvbWV0cnksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBmZWF0dXJlOiBJVmVjdG9yVGlsZUZlYXR1cmUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBmZWF0dXJlU3RhdGU6IEZlYXR1cmVTdGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlb21ldHJ5OiBBcnJheTxBcnJheTxQb2ludD4+LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgem9vbTogbnVtYmVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtOiBUcmFuc2Zvcm0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBwaXhlbFBvc01hdHJpeDogRmxvYXQzMkFycmF5LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxldmF0aW9uSGVscGVyOiA/REVNU2FtcGxlcik6IGJvb2xlYW4ge1xuXG4gICAgICAgIGNvbnN0IHRyYW5zbGF0aW9uID0gdGlsZXNwYWNlVHJhbnNsYXRlKFxuICAgICAgICAgICAgdGhpcy5wYWludC5nZXQoJ2NpcmNsZS10cmFuc2xhdGUnKSxcbiAgICAgICAgICAgIHRoaXMucGFpbnQuZ2V0KCdjaXJjbGUtdHJhbnNsYXRlLWFuY2hvcicpLFxuICAgICAgICAgICAgdHJhbnNmb3JtLmFuZ2xlLCBxdWVyeUdlb21ldHJ5LnBpeGVsVG9UaWxlVW5pdHNGYWN0b3IpO1xuXG4gICAgICAgIGNvbnN0IHNpemUgPSB0aGlzLnBhaW50LmdldCgnY2lyY2xlLXJhZGl1cycpLmV2YWx1YXRlKGZlYXR1cmUsIGZlYXR1cmVTdGF0ZSkgK1xuICAgICAgICAgICAgdGhpcy5wYWludC5nZXQoJ2NpcmNsZS1zdHJva2Utd2lkdGgnKS5ldmFsdWF0ZShmZWF0dXJlLCBmZWF0dXJlU3RhdGUpO1xuXG4gICAgICAgIHJldHVybiBxdWVyeUludGVyc2VjdHNDaXJjbGUocXVlcnlHZW9tZXRyeSwgZ2VvbWV0cnksIHRyYW5zZm9ybSwgcGl4ZWxQb3NNYXRyaXgsIGVsZXZhdGlvbkhlbHBlcixcbiAgICAgICAgICAgIHRoaXMucGFpbnQuZ2V0KCdjaXJjbGUtcGl0Y2gtYWxpZ25tZW50JykgPT09ICdtYXAnLFxuICAgICAgICAgICAgdGhpcy5wYWludC5nZXQoJ2NpcmNsZS1waXRjaC1zY2FsZScpID09PSAnbWFwJywgdHJhbnNsYXRpb24sIHNpemUpO1xuICAgIH1cblxuICAgIGdldFByb2dyYW1JZHMoKTogQXJyYXk8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiBbJ2NpcmNsZSddO1xuICAgIH1cblxuICAgIGdldFByb2dyYW1Db25maWd1cmF0aW9uKHpvb206IG51bWJlcik6IFByb2dyYW1Db25maWd1cmF0aW9uIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9ncmFtQ29uZmlndXJhdGlvbih0aGlzLCB6b29tKTtcbiAgICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBxdWVyeUludGVyc2VjdHNDaXJjbGUocXVlcnlHZW9tZXRyeTogVGlsZXNwYWNlUXVlcnlHZW9tZXRyeSxcbiAgICAgICAgICAgICAgICAgICAgICAgZ2VvbWV0cnk6IEFycmF5PEFycmF5PFBvaW50Pj4sXG4gICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybTogVHJhbnNmb3JtLFxuICAgICAgICAgICAgICAgICAgICAgICBwaXhlbFBvc01hdHJpeDogRmxvYXQzMkFycmF5LFxuICAgICAgICAgICAgICAgICAgICAgICBlbGV2YXRpb25IZWxwZXI6ID9ERU1TYW1wbGVyLFxuICAgICAgICAgICAgICAgICAgICAgICBhbGlnbldpdGhNYXA6IGJvb2xlYW4sXG4gICAgICAgICAgICAgICAgICAgICAgIHNjYWxlV2l0aE1hcDogYm9vbGVhbixcbiAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRpb246IFBvaW50LFxuICAgICAgICAgICAgICAgICAgICAgICBzaXplOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICBpZiAoYWxpZ25XaXRoTWFwICYmIHF1ZXJ5R2VvbWV0cnkucXVlcnlHZW9tZXRyeS5pc0Fib3ZlSG9yaXpvbikgcmV0dXJuIGZhbHNlO1xuXG4gICAgLy8gRm9yIHBpdGNoLWFsaWdubWVudDogbWFwLCBjb21wYXJlIGZlYXR1cmUgZ2VvbWV0cnkgdG8gcXVlcnkgZ2VvbWV0cnkgaW4gdGhlIHBsYW5lIG9mIHRoZSB0aWxlXG4gICAgLy8gLy8gT3RoZXJ3aXNlLCBjb21wYXJlIGdlb21ldHJ5IGluIHRoZSBwbGFuZSBvZiB0aGUgdmlld3BvcnRcbiAgICAvLyAvLyBBIGNpcmNsZSB3aXRoIGZpeGVkIHNjYWxpbmcgcmVsYXRpdmUgdG8gdGhlIHZpZXdwb3J0IGdldHMgbGFyZ2VyIGluIHRpbGUgc3BhY2UgYXMgaXQgbW92ZXMgaW50byB0aGUgZGlzdGFuY2VcbiAgICAvLyAvLyBBIGNpcmNsZSB3aXRoIGZpeGVkIHNjYWxpbmcgcmVsYXRpdmUgdG8gdGhlIG1hcCBnZXRzIHNtYWxsZXIgaW4gdmlld3BvcnQgc3BhY2UgYXMgaXQgbW92ZXMgaW50byB0aGUgZGlzdGFuY2VcbiAgICBpZiAoYWxpZ25XaXRoTWFwKSBzaXplICo9IHF1ZXJ5R2VvbWV0cnkucGl4ZWxUb1RpbGVVbml0c0ZhY3RvcjtcblxuICAgIGNvbnN0IHRpbGVJZCA9IHF1ZXJ5R2VvbWV0cnkudGlsZUlELmNhbm9uaWNhbDtcbiAgICBjb25zdCBlbGV2YXRpb25TY2FsZSA9IHRyYW5zZm9ybS5wcm9qZWN0aW9uLnVwVmVjdG9yU2NhbGUodGlsZUlkLCB0cmFuc2Zvcm0uY2VudGVyLmxhdCwgdHJhbnNmb3JtLndvcmxkU2l6ZSkubWV0ZXJzVG9UaWxlO1xuXG4gICAgZm9yIChjb25zdCByaW5nIG9mIGdlb21ldHJ5KSB7XG4gICAgICAgIGZvciAoY29uc3QgcG9pbnQgb2YgcmluZykge1xuICAgICAgICAgICAgY29uc3QgdHJhbnNsYXRlZFBvaW50ID0gcG9pbnQuYWRkKHRyYW5zbGF0aW9uKTtcbiAgICAgICAgICAgIGNvbnN0IHogPSAoZWxldmF0aW9uSGVscGVyICYmIHRyYW5zZm9ybS5lbGV2YXRpb24pID9cbiAgICAgICAgICAgICAgICB0cmFuc2Zvcm0uZWxldmF0aW9uLmV4YWdnZXJhdGlvbigpICogZWxldmF0aW9uSGVscGVyLmdldEVsZXZhdGlvbkF0KHRyYW5zbGF0ZWRQb2ludC54LCB0cmFuc2xhdGVkUG9pbnQueSwgdHJ1ZSkgOlxuICAgICAgICAgICAgICAgIDA7XG5cbiAgICAgICAgICAgIC8vIFJlcHJvamVjdCB0aWxlIGNvb3JkaW5hdGUgdG8gdGhlIGxvY2FsIGNvb3JkaW5hdGUgc3BhY2UgdXNlZCBieSB0aGUgcHJvamVjdGlvblxuICAgICAgICAgICAgY29uc3QgcmVwcm9qID0gdHJhbnNmb3JtLnByb2plY3Rpb24ucHJvamVjdFRpbGVQb2ludCh0cmFuc2xhdGVkUG9pbnQueCwgdHJhbnNsYXRlZFBvaW50LnksIHRpbGVJZCk7XG5cbiAgICAgICAgICAgIGlmICh6ID4gMCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRpciA9IHRyYW5zZm9ybS5wcm9qZWN0aW9uLnVwVmVjdG9yKHRpbGVJZCwgdHJhbnNsYXRlZFBvaW50LngsIHRyYW5zbGF0ZWRQb2ludC55KTtcbiAgICAgICAgICAgICAgICByZXByb2oueCArPSBkaXJbMF0gKiBlbGV2YXRpb25TY2FsZSAqIHo7XG4gICAgICAgICAgICAgICAgcmVwcm9qLnkgKz0gZGlyWzFdICogZWxldmF0aW9uU2NhbGUgKiB6O1xuICAgICAgICAgICAgICAgIHJlcHJvai56ICs9IGRpclsyXSAqIGVsZXZhdGlvblNjYWxlICogejtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgdHJhbnNmb3JtZWRQb2ludCA9IGFsaWduV2l0aE1hcCA/IHRyYW5zbGF0ZWRQb2ludCA6IHByb2plY3RQb2ludChyZXByb2oueCwgcmVwcm9qLnksIHJlcHJvai56LCBwaXhlbFBvc01hdHJpeCk7XG4gICAgICAgICAgICBjb25zdCB0cmFuc2Zvcm1lZFBvbHlnb24gPSBhbGlnbldpdGhNYXAgP1xuICAgICAgICAgICAgICAgIHF1ZXJ5R2VvbWV0cnkudGlsZXNwYWNlUmF5cy5tYXAoKHIpID0+IGludGVyc2VjdEF0SGVpZ2h0KHIsIHopKSA6XG4gICAgICAgICAgICAgICAgcXVlcnlHZW9tZXRyeS5xdWVyeUdlb21ldHJ5LnNjcmVlbkdlb21ldHJ5O1xuXG4gICAgICAgICAgICBjb25zdCBwcm9qZWN0ZWRDZW50ZXIgPSB2ZWM0LnRyYW5zZm9ybU1hdDQoW10sIFtyZXByb2oueCwgcmVwcm9qLnksIHJlcHJvai56LCAxXSwgcGl4ZWxQb3NNYXRyaXgpO1xuICAgICAgICAgICAgaWYgKCFzY2FsZVdpdGhNYXAgJiYgYWxpZ25XaXRoTWFwKSB7XG4gICAgICAgICAgICAgICAgc2l6ZSAqPSBwcm9qZWN0ZWRDZW50ZXJbM10gLyB0cmFuc2Zvcm0uY2FtZXJhVG9DZW50ZXJEaXN0YW5jZTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoc2NhbGVXaXRoTWFwICYmICFhbGlnbldpdGhNYXApIHtcbiAgICAgICAgICAgICAgICBzaXplICo9IHRyYW5zZm9ybS5jYW1lcmFUb0NlbnRlckRpc3RhbmNlIC8gcHJvamVjdGVkQ2VudGVyWzNdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoYWxpZ25XaXRoTWFwKSB7XG4gICAgICAgICAgICAgICAgLy8gQXBwbHkgZXh0cmEgc2NhbGluZyB0byBjb3ZlciBkaWZmZXJlbnQgcGl4ZWxQZXJNZXRlciByYXRpb3MgYXQgZGlmZmVyZW50IGxhdGl0dWRlc1xuICAgICAgICAgICAgICAgIGNvbnN0IGxhdCA9IGxhdEZyb21NZXJjYXRvclkoKHBvaW50LnkgLyBFWFRFTlQgKyB0aWxlSWQueSkgLyAoMSA8PCB0aWxlSWQueikpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHNjYWxlID0gdHJhbnNmb3JtLnByb2plY3Rpb24ucGl4ZWxzUGVyTWV0ZXIobGF0LCAxKSAvIG1lcmNhdG9yWmZyb21BbHRpdHVkZSgxLCBsYXQpO1xuXG4gICAgICAgICAgICAgICAgc2l6ZSAvPSBzY2FsZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHBvbHlnb25JbnRlcnNlY3RzQnVmZmVyZWRQb2ludCh0cmFuc2Zvcm1lZFBvbHlnb24sIHRyYW5zZm9ybWVkUG9pbnQsIHNpemUpKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gcHJvamVjdFBvaW50KHg6IG51bWJlciwgeTogbnVtYmVyLCB6OiBudW1iZXIsIHBpeGVsUG9zTWF0cml4OiBGbG9hdDMyQXJyYXkpIHtcbiAgICBjb25zdCBwb2ludCA9IHZlYzQudHJhbnNmb3JtTWF0NChbXSwgW3gsIHksIHosIDFdLCBwaXhlbFBvc01hdHJpeCk7XG4gICAgcmV0dXJuIG5ldyBQb2ludChwb2ludFswXSAvIHBvaW50WzNdLCBwb2ludFsxXSAvIHBvaW50WzNdKTtcbn1cblxuY29uc3Qgb3JpZ2luID0gdmVjMy5mcm9tVmFsdWVzKDAsIDAsIDApO1xuY29uc3QgdXAgPSB2ZWMzLmZyb21WYWx1ZXMoMCwgMCwgMSk7XG5cbmZ1bmN0aW9uIGludGVyc2VjdEF0SGVpZ2h0KHI6IFJheSwgejogbnVtYmVyKTogUG9pbnQge1xuICAgIGNvbnN0IGludGVyc2VjdGlvblB0ID0gdmVjMy5jcmVhdGUoKTtcbiAgICBvcmlnaW5bMl0gPSB6O1xuICAgIGNvbnN0IGludGVyc2VjdHMgPSByLmludGVyc2VjdHNQbGFuZShvcmlnaW4sIHVwLCBpbnRlcnNlY3Rpb25QdCk7XG4gICAgYXNzZXJ0KGludGVyc2VjdHMsICd0aWxlc3BhY2VQb2ludCBzaG91bGQgYWx3YXlzIGJlIGJlbG93IGhvcml6b24sIGFuZCBzaW5jZSBjYW1lcmEgY2Fubm90IGhhdmUgcGl0Y2ggPjkwLCByYXkgc2hvdWxkIGFsd2F5cyBpbnRlcnNlY3QnKTtcblxuICAgIHJldHVybiBuZXcgUG9pbnQoaW50ZXJzZWN0aW9uUHRbMF0sIGludGVyc2VjdGlvblB0WzFdKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgQ2lyY2xlU3R5bGVMYXllcjtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCBDaXJjbGVCdWNrZXQgZnJvbSAnLi9jaXJjbGVfYnVja2V0LmpzJztcblxuaW1wb3J0IHtyZWdpc3Rlcn0gZnJvbSAnLi4vLi4vdXRpbC93ZWJfd29ya2VyX3RyYW5zZmVyLmpzJztcblxuaW1wb3J0IHR5cGUgSGVhdG1hcFN0eWxlTGF5ZXIgZnJvbSAnLi4vLi4vc3R5bGUvc3R5bGVfbGF5ZXIvaGVhdG1hcF9zdHlsZV9sYXllci5qcyc7XG5cbmNsYXNzIEhlYXRtYXBCdWNrZXQgZXh0ZW5kcyBDaXJjbGVCdWNrZXQ8SGVhdG1hcFN0eWxlTGF5ZXI+IHtcbiAgICAvLyBOZWVkZWQgZm9yIGZsb3cgdG8gYWNjZXB0IG9taXQ6IFsnbGF5ZXJzJ10gYmVsb3csIGR1ZSB0b1xuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9mbG93L2lzc3Vlcy80MjYyXG4gICAgbGF5ZXJzOiBBcnJheTxIZWF0bWFwU3R5bGVMYXllcj47XG59XG5cbnJlZ2lzdGVyKEhlYXRtYXBCdWNrZXQsICdIZWF0bWFwQnVja2V0Jywge29taXQ6IFsnbGF5ZXJzJ119KTtcblxuZXhwb3J0IGRlZmF1bHQgSGVhdG1hcEJ1Y2tldDtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcblxuaW1wb3J0IHtyZWdpc3Rlcn0gZnJvbSAnLi93ZWJfd29ya2VyX3RyYW5zZmVyLmpzJztcblxuZXhwb3J0IHR5cGUgU2l6ZSA9IGludGVyZmFjZSB7XG4gICAgd2lkdGg6IG51bWJlcixcbiAgICBoZWlnaHQ6IG51bWJlcixcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3ByaXRlUG9zaXRpb24ge1xuICAgICt0bDogW251bWJlciwgbnVtYmVyXSxcbiAgICArYnI6IFtudW1iZXIsIG51bWJlcl0sXG4gICAgK3BpeGVsUmF0aW8/OiBudW1iZXJcbn1cbmV4cG9ydCB0eXBlIFNwcml0ZVBvc2l0aW9ucyA9IHtbXzogc3RyaW5nXTogU3ByaXRlUG9zaXRpb259O1xuXG50eXBlIFBvaW50ID0ge1xuICAgIHg6IG51bWJlcixcbiAgICB5OiBudW1iZXJcbn07XG5cbmZ1bmN0aW9uIGNyZWF0ZUltYWdlPFQ6IEFscGhhSW1hZ2UgfCBSR0JBSW1hZ2U+KGltYWdlOiBULCB7d2lkdGgsIGhlaWdodH06IFNpemUsIGNoYW5uZWxzOiBudW1iZXIsIGRhdGE/OiBVaW50OEFycmF5IHwgVWludDhDbGFtcGVkQXJyYXkpOiBUIHtcbiAgICBpZiAoIWRhdGEpIHtcbiAgICAgICAgZGF0YSA9IG5ldyBVaW50OEFycmF5KHdpZHRoICogaGVpZ2h0ICogY2hhbm5lbHMpO1xuICAgIH0gZWxzZSBpZiAoZGF0YSBpbnN0YW5jZW9mIFVpbnQ4Q2xhbXBlZEFycmF5KSB7XG4gICAgICAgIGRhdGEgPSBuZXcgVWludDhBcnJheShkYXRhLmJ1ZmZlcik7XG4gICAgfSBlbHNlIGlmIChkYXRhLmxlbmd0aCAhPT0gd2lkdGggKiBoZWlnaHQgKiBjaGFubmVscykge1xuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignbWlzbWF0Y2hlZCBpbWFnZSBzaXplJyk7XG4gICAgfVxuICAgIGltYWdlLndpZHRoID0gd2lkdGg7XG4gICAgaW1hZ2UuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgIGltYWdlLmRhdGEgPSBkYXRhO1xuICAgIHJldHVybiBpbWFnZTtcbn1cblxuZnVuY3Rpb24gcmVzaXplSW1hZ2U8VDogQWxwaGFJbWFnZSB8IFJHQkFJbWFnZT4oaW1hZ2U6IFQsIG5ld0ltYWdlOiBULCBjaGFubmVsczogbnVtYmVyKSB7XG4gICAgY29uc3Qge3dpZHRoLCBoZWlnaHR9ID0gbmV3SW1hZ2U7XG4gICAgaWYgKHdpZHRoID09PSBpbWFnZS53aWR0aCAmJiBoZWlnaHQgPT09IGltYWdlLmhlaWdodCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29weUltYWdlKGltYWdlLCBuZXdJbWFnZSwge3g6IDAsIHk6IDB9LCB7eDogMCwgeTogMH0sIHtcbiAgICAgICAgd2lkdGg6IE1hdGgubWluKGltYWdlLndpZHRoLCB3aWR0aCksXG4gICAgICAgIGhlaWdodDogTWF0aC5taW4oaW1hZ2UuaGVpZ2h0LCBoZWlnaHQpXG4gICAgfSwgY2hhbm5lbHMpO1xuXG4gICAgaW1hZ2Uud2lkdGggPSB3aWR0aDtcbiAgICBpbWFnZS5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgaW1hZ2UuZGF0YSA9IG5ld0ltYWdlLmRhdGE7XG59XG5cbmZ1bmN0aW9uIGNvcHlJbWFnZTxUOiBSR0JBSW1hZ2UgfCBBbHBoYUltYWdlPihzcmNJbWc6IFQgfCBJbWFnZURhdGEsIGRzdEltZzogVCwgc3JjUHQ6IFBvaW50LCBkc3RQdDogUG9pbnQsIHNpemU6IFNpemUsIGNoYW5uZWxzOiBudW1iZXIpOiBUIHtcbiAgICBpZiAoc2l6ZS53aWR0aCA9PT0gMCB8fCBzaXplLmhlaWdodCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gZHN0SW1nO1xuICAgIH1cblxuICAgIGlmIChzaXplLndpZHRoID4gc3JjSW1nLndpZHRoIHx8XG4gICAgICAgIHNpemUuaGVpZ2h0ID4gc3JjSW1nLmhlaWdodCB8fFxuICAgICAgICBzcmNQdC54ID4gc3JjSW1nLndpZHRoIC0gc2l6ZS53aWR0aCB8fFxuICAgICAgICBzcmNQdC55ID4gc3JjSW1nLmhlaWdodCAtIHNpemUuaGVpZ2h0KSB7XG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdvdXQgb2YgcmFuZ2Ugc291cmNlIGNvb3JkaW5hdGVzIGZvciBpbWFnZSBjb3B5Jyk7XG4gICAgfVxuXG4gICAgaWYgKHNpemUud2lkdGggPiBkc3RJbWcud2lkdGggfHxcbiAgICAgICAgc2l6ZS5oZWlnaHQgPiBkc3RJbWcuaGVpZ2h0IHx8XG4gICAgICAgIGRzdFB0LnggPiBkc3RJbWcud2lkdGggLSBzaXplLndpZHRoIHx8XG4gICAgICAgIGRzdFB0LnkgPiBkc3RJbWcuaGVpZ2h0IC0gc2l6ZS5oZWlnaHQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ291dCBvZiByYW5nZSBkZXN0aW5hdGlvbiBjb29yZGluYXRlcyBmb3IgaW1hZ2UgY29weScpO1xuICAgIH1cblxuICAgIGNvbnN0IHNyY0RhdGEgPSBzcmNJbWcuZGF0YTtcbiAgICBjb25zdCBkc3REYXRhID0gZHN0SW1nLmRhdGE7XG5cbiAgICBhc3NlcnQoc3JjRGF0YSAhPT0gZHN0RGF0YSk7XG5cbiAgICBmb3IgKGxldCB5ID0gMDsgeSA8IHNpemUuaGVpZ2h0OyB5KyspIHtcbiAgICAgICAgY29uc3Qgc3JjT2Zmc2V0ID0gKChzcmNQdC55ICsgeSkgKiBzcmNJbWcud2lkdGggKyBzcmNQdC54KSAqIGNoYW5uZWxzO1xuICAgICAgICBjb25zdCBkc3RPZmZzZXQgPSAoKGRzdFB0LnkgKyB5KSAqIGRzdEltZy53aWR0aCArIGRzdFB0LngpICogY2hhbm5lbHM7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2l6ZS53aWR0aCAqIGNoYW5uZWxzOyBpKyspIHtcbiAgICAgICAgICAgIGRzdERhdGFbZHN0T2Zmc2V0ICsgaV0gPSBzcmNEYXRhW3NyY09mZnNldCArIGldO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkc3RJbWc7XG59XG5cbmV4cG9ydCBjbGFzcyBBbHBoYUltYWdlIHtcbiAgICB3aWR0aDogbnVtYmVyO1xuICAgIGhlaWdodDogbnVtYmVyO1xuICAgIGRhdGE6IFVpbnQ4QXJyYXk7XG5cbiAgICBjb25zdHJ1Y3RvcihzaXplOiBTaXplLCBkYXRhPzogVWludDhBcnJheSB8IFVpbnQ4Q2xhbXBlZEFycmF5KSB7XG4gICAgICAgIGNyZWF0ZUltYWdlKHRoaXMsIHNpemUsIDEsIGRhdGEpO1xuICAgIH1cblxuICAgIHJlc2l6ZShzaXplOiBTaXplKSB7XG4gICAgICAgIHJlc2l6ZUltYWdlKHRoaXMsIG5ldyBBbHBoYUltYWdlKHNpemUpLCAxKTtcbiAgICB9XG5cbiAgICBjbG9uZSgpOiBBbHBoYUltYWdlIHtcbiAgICAgICAgcmV0dXJuIG5ldyBBbHBoYUltYWdlKHt3aWR0aDogdGhpcy53aWR0aCwgaGVpZ2h0OiB0aGlzLmhlaWdodH0sIG5ldyBVaW50OEFycmF5KHRoaXMuZGF0YSkpO1xuICAgIH1cblxuICAgIHN0YXRpYyBjb3B5KHNyY0ltZzogQWxwaGFJbWFnZSwgZHN0SW1nOiBBbHBoYUltYWdlLCBzcmNQdDogUG9pbnQsIGRzdFB0OiBQb2ludCwgc2l6ZTogU2l6ZSkge1xuICAgICAgICBjb3B5SW1hZ2Uoc3JjSW1nLCBkc3RJbWcsIHNyY1B0LCBkc3RQdCwgc2l6ZSwgMSk7XG4gICAgfVxufVxuXG4vLyBOb3QgcHJlbXVsdGlwbGllZCwgYmVjYXVzZSBJbWFnZURhdGEgaXMgbm90IHByZW11bHRpcGxpZWQuXG4vLyBVTlBBQ0tfUFJFTVVMVElQTFlfQUxQSEFfV0VCR0wgbXVzdCBiZSB1c2VkIHdoZW4gdXBsb2FkaW5nIHRvIGEgdGV4dHVyZS5cbmV4cG9ydCBjbGFzcyBSR0JBSW1hZ2Uge1xuICAgIHdpZHRoOiBudW1iZXI7XG4gICAgaGVpZ2h0OiBudW1iZXI7XG5cbiAgICAvLyBkYXRhIG11c3QgYmUgYSBVaW50OEFycmF5IGluc3RlYWQgb2YgVWludDhDbGFtcGVkQXJyYXkgYmVjYXVzZSB0ZXhJbWFnZTJEIGRvZXMgbm90XG4gICAgLy8gc3VwcG9ydCBVaW50OENsYW1wZWRBcnJheSBpbiBhbGwgYnJvd3NlcnNcbiAgICBkYXRhOiBVaW50OEFycmF5O1xuXG4gICAgY29uc3RydWN0b3Ioc2l6ZTogU2l6ZSwgZGF0YT86IFVpbnQ4QXJyYXkgfCBVaW50OENsYW1wZWRBcnJheSkge1xuICAgICAgICBjcmVhdGVJbWFnZSh0aGlzLCBzaXplLCA0LCBkYXRhKTtcbiAgICB9XG5cbiAgICByZXNpemUoc2l6ZTogU2l6ZSkge1xuICAgICAgICByZXNpemVJbWFnZSh0aGlzLCBuZXcgUkdCQUltYWdlKHNpemUpLCA0KTtcbiAgICB9XG5cbiAgICByZXBsYWNlKGRhdGE6IFVpbnQ4QXJyYXkgfCBVaW50OENsYW1wZWRBcnJheSwgY29weT86IGJvb2xlYW4pIHtcbiAgICAgICAgaWYgKGNvcHkpIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5zZXQoZGF0YSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZGF0YSBpbnN0YW5jZW9mIFVpbnQ4Q2xhbXBlZEFycmF5KSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEgPSBuZXcgVWludDhBcnJheShkYXRhLmJ1ZmZlcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY2xvbmUoKTogUkdCQUltYWdlIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSR0JBSW1hZ2Uoe3dpZHRoOiB0aGlzLndpZHRoLCBoZWlnaHQ6IHRoaXMuaGVpZ2h0fSwgbmV3IFVpbnQ4QXJyYXkodGhpcy5kYXRhKSk7XG4gICAgfVxuXG4gICAgc3RhdGljIGNvcHkoc3JjSW1nOiBSR0JBSW1hZ2UgfCBJbWFnZURhdGEsIGRzdEltZzogUkdCQUltYWdlLCBzcmNQdDogUG9pbnQsIGRzdFB0OiBQb2ludCwgc2l6ZTogU2l6ZSkge1xuICAgICAgICBjb3B5SW1hZ2Uoc3JjSW1nLCBkc3RJbWcsIHNyY1B0LCBkc3RQdCwgc2l6ZSwgNCk7XG4gICAgfVxufVxuXG5yZWdpc3RlcihBbHBoYUltYWdlLCAnQWxwaGFJbWFnZScpO1xucmVnaXN0ZXIoUkdCQUltYWdlLCAnUkdCQUltYWdlJyk7XG4iLCIvLyBUaGlzIGZpbGUgaXMgZ2VuZXJhdGVkLiBFZGl0IGJ1aWxkL2dlbmVyYXRlLXN0eWxlLWNvZGUuanMsIHRoZW4gcnVuIGB5YXJuIHJ1biBjb2RlZ2VuYC5cbi8vIEBmbG93XG4vKiBlc2xpbnQtZGlzYWJsZSAqL1xuXG5pbXBvcnQgc3R5bGVTcGVjIGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvcmVmZXJlbmNlL2xhdGVzdC5qcyc7XG5cbmltcG9ydCB7XG4gICAgUHJvcGVydGllcyxcbiAgICBEYXRhQ29uc3RhbnRQcm9wZXJ0eSxcbiAgICBEYXRhRHJpdmVuUHJvcGVydHksXG4gICAgQ29sb3JSYW1wUHJvcGVydHlcbn0gZnJvbSAnLi4vcHJvcGVydGllcy5qcyc7XG5cbmltcG9ydCB0eXBlIENvbG9yIGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvdXRpbC9jb2xvci5qcyc7XG5cbmltcG9ydCB0eXBlIEZvcm1hdHRlZCBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vdHlwZXMvZm9ybWF0dGVkLmpzJztcblxuaW1wb3J0IHR5cGUgUmVzb2x2ZWRJbWFnZSBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vdHlwZXMvcmVzb2x2ZWRfaW1hZ2UuanMnO1xuXG5cbmV4cG9ydCB0eXBlIFBhaW50UHJvcHMgPSB7fFxuICAgIFwiaGVhdG1hcC1yYWRpdXNcIjogRGF0YURyaXZlblByb3BlcnR5PG51bWJlcj4sXG4gICAgXCJoZWF0bWFwLXdlaWdodFwiOiBEYXRhRHJpdmVuUHJvcGVydHk8bnVtYmVyPixcbiAgICBcImhlYXRtYXAtaW50ZW5zaXR5XCI6IERhdGFDb25zdGFudFByb3BlcnR5PG51bWJlcj4sXG4gICAgXCJoZWF0bWFwLWNvbG9yXCI6IENvbG9yUmFtcFByb3BlcnR5LFxuICAgIFwiaGVhdG1hcC1vcGFjaXR5XCI6IERhdGFDb25zdGFudFByb3BlcnR5PG51bWJlcj4sXG58fTtcblxuY29uc3QgcGFpbnQ6IFByb3BlcnRpZXM8UGFpbnRQcm9wcz4gPSBuZXcgUHJvcGVydGllcyh7XG4gICAgXCJoZWF0bWFwLXJhZGl1c1wiOiBuZXcgRGF0YURyaXZlblByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X2hlYXRtYXBcIl1bXCJoZWF0bWFwLXJhZGl1c1wiXSksXG4gICAgXCJoZWF0bWFwLXdlaWdodFwiOiBuZXcgRGF0YURyaXZlblByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X2hlYXRtYXBcIl1bXCJoZWF0bWFwLXdlaWdodFwiXSksXG4gICAgXCJoZWF0bWFwLWludGVuc2l0eVwiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjW1wicGFpbnRfaGVhdG1hcFwiXVtcImhlYXRtYXAtaW50ZW5zaXR5XCJdKSxcbiAgICBcImhlYXRtYXAtY29sb3JcIjogbmV3IENvbG9yUmFtcFByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X2hlYXRtYXBcIl1bXCJoZWF0bWFwLWNvbG9yXCJdKSxcbiAgICBcImhlYXRtYXAtb3BhY2l0eVwiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjW1wicGFpbnRfaGVhdG1hcFwiXVtcImhlYXRtYXAtb3BhY2l0eVwiXSksXG59KTtcblxuLy8gTm90ZTogd2l0aG91dCBhZGRpbmcgdGhlIGV4cGxpY2l0IHR5cGUgYW5ub3RhdGlvbiwgRmxvdyBpbmZlcnMgd2Vha2VyIHR5cGVzXG4vLyBmb3IgdGhlc2Ugb2JqZWN0cyBmcm9tIHRoZWlyIHVzZSBpbiB0aGUgY29uc3RydWN0b3IgdG8gU3R5bGVMYXllciwgYXNcbi8vIHtsYXlvdXQ/OiBQcm9wZXJ0aWVzPC4uLj4sIHBhaW50OiBQcm9wZXJ0aWVzPC4uLj59XG5leHBvcnQgZGVmYXVsdCAoeyBwYWludCB9OiAkRXhhY3Q8e1xuICBwYWludDogUHJvcGVydGllczxQYWludFByb3BzPlxufT4pO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtSR0JBSW1hZ2V9IGZyb20gJy4vaW1hZ2UuanMnO1xuaW1wb3J0IHtpc1Bvd2VyT2ZUd299IGZyb20gJy4vdXRpbC5qcyc7XG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbmltcG9ydCB0eXBlIHtTdHlsZVByb3BlcnR5RXhwcmVzc2lvbn0gZnJvbSAnLi4vc3R5bGUtc3BlYy9leHByZXNzaW9uL2luZGV4LmpzJztcblxuZXhwb3J0IHR5cGUgQ29sb3JSYW1wUGFyYW1zID0ge1xuICAgIGV4cHJlc3Npb246IFN0eWxlUHJvcGVydHlFeHByZXNzaW9uO1xuICAgIGV2YWx1YXRpb25LZXk6IHN0cmluZztcbiAgICByZXNvbHV0aW9uPzogbnVtYmVyO1xuICAgIGltYWdlPzogUkdCQUltYWdlO1xuICAgIGNsaXBzPzogQXJyYXk8T2JqZWN0Pjtcbn1cblxuLyoqXG4gKiBHaXZlbiBhbiBleHByZXNzaW9uIHRoYXQgc2hvdWxkIGV2YWx1YXRlIHRvIGEgY29sb3IgcmFtcCxcbiAqIHJldHVybiBhIFJHQkEgaW1hZ2UgcmVwcmVzZW50aW5nIHRoYXQgcmFtcCBleHByZXNzaW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW5kZXJDb2xvclJhbXAocGFyYW1zOiBDb2xvclJhbXBQYXJhbXMpOiBSR0JBSW1hZ2Uge1xuICAgIGNvbnN0IGV2YWx1YXRpb25HbG9iYWxzID0ge307XG4gICAgY29uc3Qgd2lkdGggPSBwYXJhbXMucmVzb2x1dGlvbiB8fCAyNTY7XG4gICAgY29uc3QgaGVpZ2h0ID0gcGFyYW1zLmNsaXBzID8gcGFyYW1zLmNsaXBzLmxlbmd0aCA6IDE7XG4gICAgY29uc3QgaW1hZ2UgPSBwYXJhbXMuaW1hZ2UgfHwgbmV3IFJHQkFJbWFnZSh7d2lkdGgsIGhlaWdodH0pO1xuXG4gICAgYXNzZXJ0KGlzUG93ZXJPZlR3byh3aWR0aCkpO1xuXG4gICAgY29uc3QgcmVuZGVyUGl4ZWwgPSAoc3RyaWRlOiBudW1iZXIsIGluZGV4OiBudW1iZXIsIHByb2dyZXNzOiBudW1iZXIpID0+IHtcbiAgICAgICAgZXZhbHVhdGlvbkdsb2JhbHNbcGFyYW1zLmV2YWx1YXRpb25LZXldID0gcHJvZ3Jlc3M7XG4gICAgICAgIGNvbnN0IHB4Q29sb3IgPSBwYXJhbXMuZXhwcmVzc2lvbi5ldmFsdWF0ZSgoZXZhbHVhdGlvbkdsb2JhbHM6IGFueSkpO1xuICAgICAgICAvLyB0aGUgY29sb3JzIGFyZSBiZWluZyB1bnByZW11bHRpcGxpZWQgYmVjYXVzZSBDb2xvciB1c2VzXG4gICAgICAgIC8vIHByZW11bHRpcGxpZWQgdmFsdWVzLCBhbmQgdGhlIFRleHR1cmUgY2xhc3MgZXhwZWN0cyB1bnByZW11bHRpcGxpZWQgb25lc1xuICAgICAgICBpbWFnZS5kYXRhW3N0cmlkZSArIGluZGV4ICsgMF0gPSBNYXRoLmZsb29yKHB4Q29sb3IuciAqIDI1NSAvIHB4Q29sb3IuYSk7XG4gICAgICAgIGltYWdlLmRhdGFbc3RyaWRlICsgaW5kZXggKyAxXSA9IE1hdGguZmxvb3IocHhDb2xvci5nICogMjU1IC8gcHhDb2xvci5hKTtcbiAgICAgICAgaW1hZ2UuZGF0YVtzdHJpZGUgKyBpbmRleCArIDJdID0gTWF0aC5mbG9vcihweENvbG9yLmIgKiAyNTUgLyBweENvbG9yLmEpO1xuICAgICAgICBpbWFnZS5kYXRhW3N0cmlkZSArIGluZGV4ICsgM10gPSBNYXRoLmZsb29yKHB4Q29sb3IuYSAqIDI1NSk7XG4gICAgfTtcblxuICAgIGlmICghcGFyYW1zLmNsaXBzKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBqID0gMDsgaSA8IHdpZHRoOyBpKyssIGogKz0gNCkge1xuICAgICAgICAgICAgY29uc3QgcHJvZ3Jlc3MgPSBpIC8gKHdpZHRoIC0gMSk7XG5cbiAgICAgICAgICAgIHJlbmRlclBpeGVsKDAsIGosIHByb2dyZXNzKTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIGZvciAobGV0IGNsaXAgPSAwLCBzdHJpZGUgPSAwOyBjbGlwIDwgaGVpZ2h0OyArK2NsaXAsIHN0cmlkZSArPSB3aWR0aCAqIDQpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBqID0gMDsgaSA8IHdpZHRoOyBpKyssIGogKz0gNCkge1xuICAgICAgICAgICAgICAgIC8vIFJlbWFwIHByb2dyZXNzIGJldHdlZW4gY2xpcHNcbiAgICAgICAgICAgICAgICBjb25zdCBwcm9ncmVzcyA9IGkgLyAod2lkdGggLSAxKTtcbiAgICAgICAgICAgICAgICBjb25zdCB7c3RhcnQsIGVuZH0gPSBwYXJhbXMuY2xpcHNbY2xpcF07XG4gICAgICAgICAgICAgICAgY29uc3QgZXZhbHVhdGlvblByb2dyZXNzID0gc3RhcnQgKiAoMSAtIHByb2dyZXNzKSArIGVuZCAqIHByb2dyZXNzO1xuICAgICAgICAgICAgICAgIHJlbmRlclBpeGVsKHN0cmlkZSwgaiwgZXZhbHVhdGlvblByb2dyZXNzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBpbWFnZTtcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBTdHlsZUxheWVyIGZyb20gJy4uL3N0eWxlX2xheWVyLmpzJztcblxuaW1wb3J0IEhlYXRtYXBCdWNrZXQgZnJvbSAnLi4vLi4vZGF0YS9idWNrZXQvaGVhdG1hcF9idWNrZXQuanMnO1xuaW1wb3J0IHtSR0JBSW1hZ2V9IGZyb20gJy4uLy4uL3V0aWwvaW1hZ2UuanMnO1xuaW1wb3J0IHByb3BlcnRpZXMgZnJvbSAnLi9oZWF0bWFwX3N0eWxlX2xheWVyX3Byb3BlcnRpZXMuanMnO1xuaW1wb3J0IHtyZW5kZXJDb2xvclJhbXB9IGZyb20gJy4uLy4uL3V0aWwvY29sb3JfcmFtcC5qcyc7XG5pbXBvcnQge1RyYW5zaXRpb25hYmxlLCBUcmFuc2l0aW9uaW5nLCBQb3NzaWJseUV2YWx1YXRlZH0gZnJvbSAnLi4vcHJvcGVydGllcy5qcyc7XG5pbXBvcnQge3F1ZXJ5SW50ZXJzZWN0c0NpcmNsZX0gZnJvbSAnLi9jaXJjbGVfc3R5bGVfbGF5ZXIuanMnO1xuaW1wb3J0IHtnZXRNYXhpbXVtUGFpbnRWYWx1ZX0gZnJvbSAnLi4vcXVlcnlfdXRpbHMuanMnO1xuaW1wb3J0IFBvaW50IGZyb20gJ0BtYXBib3gvcG9pbnQtZ2VvbWV0cnknO1xuXG5pbXBvcnQgdHlwZSB7QnVja2V0LCBCdWNrZXRQYXJhbWV0ZXJzfSBmcm9tICcuLi8uLi9kYXRhL2J1Y2tldC5qcyc7XG5pbXBvcnQgdHlwZSBUZXh0dXJlIGZyb20gJy4uLy4uL3JlbmRlci90ZXh0dXJlLmpzJztcbmltcG9ydCB0eXBlIEZyYW1lYnVmZmVyIGZyb20gJy4uLy4uL2dsL2ZyYW1lYnVmZmVyLmpzJztcbmltcG9ydCB0eXBlIHtQYWludFByb3BzfSBmcm9tICcuL2hlYXRtYXBfc3R5bGVfbGF5ZXJfcHJvcGVydGllcy5qcyc7XG5pbXBvcnQgdHlwZSB7TGF5ZXJTcGVjaWZpY2F0aW9ufSBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL3R5cGVzLmpzJztcbmltcG9ydCBQcm9ncmFtQ29uZmlndXJhdGlvbiBmcm9tICcuLi8uLi9kYXRhL3Byb2dyYW1fY29uZmlndXJhdGlvbi5qcyc7XG5pbXBvcnQgdHlwZSB7VGlsZXNwYWNlUXVlcnlHZW9tZXRyeX0gZnJvbSAnLi4vcXVlcnlfZ2VvbWV0cnkuanMnO1xuaW1wb3J0IHR5cGUge0RFTVNhbXBsZXJ9IGZyb20gJy4uLy4uL3RlcnJhaW4vZWxldmF0aW9uLmpzJztcbmltcG9ydCB0eXBlIHtGZWF0dXJlU3RhdGV9IGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi9pbmRleC5qcyc7XG5pbXBvcnQgdHlwZSBUcmFuc2Zvcm0gZnJvbSAnLi4vLi4vZ2VvL3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQgdHlwZSBDaXJjbGVCdWNrZXQgZnJvbSAnLi4vLi4vZGF0YS9idWNrZXQvY2lyY2xlX2J1Y2tldC5qcyc7XG5pbXBvcnQgdHlwZSB7SVZlY3RvclRpbGVGZWF0dXJlfSBmcm9tICdAbWFwYm94L3ZlY3Rvci10aWxlJztcblxuY2xhc3MgSGVhdG1hcFN0eWxlTGF5ZXIgZXh0ZW5kcyBTdHlsZUxheWVyIHtcblxuICAgIGhlYXRtYXBGYm86ID9GcmFtZWJ1ZmZlcjtcbiAgICBjb2xvclJhbXA6IFJHQkFJbWFnZTtcbiAgICBjb2xvclJhbXBUZXh0dXJlOiA/VGV4dHVyZTtcblxuICAgIF90cmFuc2l0aW9uYWJsZVBhaW50OiBUcmFuc2l0aW9uYWJsZTxQYWludFByb3BzPjtcbiAgICBfdHJhbnNpdGlvbmluZ1BhaW50OiBUcmFuc2l0aW9uaW5nPFBhaW50UHJvcHM+O1xuICAgIHBhaW50OiBQb3NzaWJseUV2YWx1YXRlZDxQYWludFByb3BzPjtcblxuICAgIGNyZWF0ZUJ1Y2tldChwYXJhbWV0ZXJzOiBCdWNrZXRQYXJhbWV0ZXJzPEhlYXRtYXBTdHlsZUxheWVyPik6IEhlYXRtYXBCdWNrZXQge1xuICAgICAgICByZXR1cm4gbmV3IEhlYXRtYXBCdWNrZXQocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgY29uc3RydWN0b3IobGF5ZXI6IExheWVyU3BlY2lmaWNhdGlvbikge1xuICAgICAgICBzdXBlcihsYXllciwgcHJvcGVydGllcyk7XG5cbiAgICAgICAgLy8gbWFrZSBzdXJlIGNvbG9yIHJhbXAgdGV4dHVyZSBpcyBnZW5lcmF0ZWQgZm9yIGRlZmF1bHQgaGVhdG1hcCBjb2xvciB0b29cbiAgICAgICAgdGhpcy5fdXBkYXRlQ29sb3JSYW1wKCk7XG4gICAgfVxuXG4gICAgX2hhbmRsZVNwZWNpYWxQYWludFByb3BlcnR5VXBkYXRlKG5hbWU6IHN0cmluZykge1xuICAgICAgICBpZiAobmFtZSA9PT0gJ2hlYXRtYXAtY29sb3InKSB7XG4gICAgICAgICAgICB0aGlzLl91cGRhdGVDb2xvclJhbXAoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF91cGRhdGVDb2xvclJhbXAoKSB7XG4gICAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSB0aGlzLl90cmFuc2l0aW9uYWJsZVBhaW50Ll92YWx1ZXNbJ2hlYXRtYXAtY29sb3InXS52YWx1ZS5leHByZXNzaW9uO1xuICAgICAgICB0aGlzLmNvbG9yUmFtcCA9IHJlbmRlckNvbG9yUmFtcCh7XG4gICAgICAgICAgICBleHByZXNzaW9uLFxuICAgICAgICAgICAgZXZhbHVhdGlvbktleTogJ2hlYXRtYXBEZW5zaXR5JyxcbiAgICAgICAgICAgIGltYWdlOiB0aGlzLmNvbG9yUmFtcFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5jb2xvclJhbXBUZXh0dXJlID0gbnVsbDtcbiAgICB9XG5cbiAgICByZXNpemUoKSB7XG4gICAgICAgIGlmICh0aGlzLmhlYXRtYXBGYm8pIHtcbiAgICAgICAgICAgIHRoaXMuaGVhdG1hcEZiby5kZXN0cm95KCk7XG4gICAgICAgICAgICB0aGlzLmhlYXRtYXBGYm8gPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIHF1ZXJ5UmFkaXVzKGJ1Y2tldDogQnVja2V0KTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIGdldE1heGltdW1QYWludFZhbHVlKCdoZWF0bWFwLXJhZGl1cycsIHRoaXMsICgoYnVja2V0OiBhbnkpOiBDaXJjbGVCdWNrZXQ8Kj4pKTtcbiAgICB9XG5cbiAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgcXVlcnlJbnRlcnNlY3RzRmVhdHVyZShxdWVyeUdlb21ldHJ5OiBUaWxlc3BhY2VRdWVyeUdlb21ldHJ5LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgZmVhdHVyZTogSVZlY3RvclRpbGVGZWF0dXJlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgZmVhdHVyZVN0YXRlOiBGZWF0dXJlU3RhdGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBnZW9tZXRyeTogQXJyYXk8QXJyYXk8UG9pbnQ+PixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHpvb206IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybTogVHJhbnNmb3JtLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgcGl4ZWxQb3NNYXRyaXg6IEZsb2F0MzJBcnJheSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZXZhdGlvbkhlbHBlcjogP0RFTVNhbXBsZXIpOiBib29sZWFuIHtcblxuICAgICAgICBjb25zdCBzaXplID0gdGhpcy5wYWludC5nZXQoJ2hlYXRtYXAtcmFkaXVzJykuZXZhbHVhdGUoZmVhdHVyZSwgZmVhdHVyZVN0YXRlKTtcbiAgICAgICAgcmV0dXJuIHF1ZXJ5SW50ZXJzZWN0c0NpcmNsZShcbiAgICAgICAgICAgIHF1ZXJ5R2VvbWV0cnksIGdlb21ldHJ5LCB0cmFuc2Zvcm0sIHBpeGVsUG9zTWF0cml4LCBlbGV2YXRpb25IZWxwZXIsXG4gICAgICAgICAgICB0cnVlLCB0cnVlLCBuZXcgUG9pbnQoMCwgMCksIHNpemUpO1xuICAgIH1cblxuICAgIGhhc09mZnNjcmVlblBhc3MoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhaW50LmdldCgnaGVhdG1hcC1vcGFjaXR5JykgIT09IDAgJiYgdGhpcy52aXNpYmlsaXR5ICE9PSAnbm9uZSc7XG4gICAgfVxuXG4gICAgZ2V0UHJvZ3JhbUlkcygpOiBBcnJheTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIFsnaGVhdG1hcCcsICdoZWF0bWFwVGV4dHVyZSddO1xuICAgIH1cblxuICAgIGdldFByb2dyYW1Db25maWd1cmF0aW9uKHpvb206IG51bWJlcik6IFByb2dyYW1Db25maWd1cmF0aW9uIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9ncmFtQ29uZmlndXJhdGlvbih0aGlzLCB6b29tKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEhlYXRtYXBTdHlsZUxheWVyO1xuIiwiLy8gVGhpcyBmaWxlIGlzIGdlbmVyYXRlZC4gRWRpdCBidWlsZC9nZW5lcmF0ZS1zdHlsZS1jb2RlLmpzLCB0aGVuIHJ1biBgeWFybiBydW4gY29kZWdlbmAuXG4vLyBAZmxvd1xuLyogZXNsaW50LWRpc2FibGUgKi9cblxuaW1wb3J0IHN0eWxlU3BlYyBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL3JlZmVyZW5jZS9sYXRlc3QuanMnO1xuXG5pbXBvcnQge1xuICAgIFByb3BlcnRpZXMsXG4gICAgRGF0YUNvbnN0YW50UHJvcGVydHksXG4gICAgRGF0YURyaXZlblByb3BlcnR5LFxuICAgIENvbG9yUmFtcFByb3BlcnR5XG59IGZyb20gJy4uL3Byb3BlcnRpZXMuanMnO1xuXG5pbXBvcnQgdHlwZSBDb2xvciBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL3V0aWwvY29sb3IuanMnO1xuXG5pbXBvcnQgdHlwZSBGb3JtYXR0ZWQgZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy9leHByZXNzaW9uL3R5cGVzL2Zvcm1hdHRlZC5qcyc7XG5cbmltcG9ydCB0eXBlIFJlc29sdmVkSW1hZ2UgZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy9leHByZXNzaW9uL3R5cGVzL3Jlc29sdmVkX2ltYWdlLmpzJztcblxuXG5leHBvcnQgdHlwZSBQYWludFByb3BzID0ge3xcbiAgICBcImhpbGxzaGFkZS1pbGx1bWluYXRpb24tZGlyZWN0aW9uXCI6IERhdGFDb25zdGFudFByb3BlcnR5PG51bWJlcj4sXG4gICAgXCJoaWxsc2hhZGUtaWxsdW1pbmF0aW9uLWFuY2hvclwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxcIm1hcFwiIHwgXCJ2aWV3cG9ydFwiPixcbiAgICBcImhpbGxzaGFkZS1leGFnZ2VyYXRpb25cIjogRGF0YUNvbnN0YW50UHJvcGVydHk8bnVtYmVyPixcbiAgICBcImhpbGxzaGFkZS1zaGFkb3ctY29sb3JcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8Q29sb3I+LFxuICAgIFwiaGlsbHNoYWRlLWhpZ2hsaWdodC1jb2xvclwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxDb2xvcj4sXG4gICAgXCJoaWxsc2hhZGUtYWNjZW50LWNvbG9yXCI6IERhdGFDb25zdGFudFByb3BlcnR5PENvbG9yPixcbnx9O1xuXG5jb25zdCBwYWludDogUHJvcGVydGllczxQYWludFByb3BzPiA9IG5ldyBQcm9wZXJ0aWVzKHtcbiAgICBcImhpbGxzaGFkZS1pbGx1bWluYXRpb24tZGlyZWN0aW9uXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9oaWxsc2hhZGVcIl1bXCJoaWxsc2hhZGUtaWxsdW1pbmF0aW9uLWRpcmVjdGlvblwiXSksXG4gICAgXCJoaWxsc2hhZGUtaWxsdW1pbmF0aW9uLWFuY2hvclwiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjW1wicGFpbnRfaGlsbHNoYWRlXCJdW1wiaGlsbHNoYWRlLWlsbHVtaW5hdGlvbi1hbmNob3JcIl0pLFxuICAgIFwiaGlsbHNoYWRlLWV4YWdnZXJhdGlvblwiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjW1wicGFpbnRfaGlsbHNoYWRlXCJdW1wiaGlsbHNoYWRlLWV4YWdnZXJhdGlvblwiXSksXG4gICAgXCJoaWxsc2hhZGUtc2hhZG93LWNvbG9yXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9oaWxsc2hhZGVcIl1bXCJoaWxsc2hhZGUtc2hhZG93LWNvbG9yXCJdKSxcbiAgICBcImhpbGxzaGFkZS1oaWdobGlnaHQtY29sb3JcIjogbmV3IERhdGFDb25zdGFudFByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X2hpbGxzaGFkZVwiXVtcImhpbGxzaGFkZS1oaWdobGlnaHQtY29sb3JcIl0pLFxuICAgIFwiaGlsbHNoYWRlLWFjY2VudC1jb2xvclwiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjW1wicGFpbnRfaGlsbHNoYWRlXCJdW1wiaGlsbHNoYWRlLWFjY2VudC1jb2xvclwiXSksXG59KTtcblxuLy8gTm90ZTogd2l0aG91dCBhZGRpbmcgdGhlIGV4cGxpY2l0IHR5cGUgYW5ub3RhdGlvbiwgRmxvdyBpbmZlcnMgd2Vha2VyIHR5cGVzXG4vLyBmb3IgdGhlc2Ugb2JqZWN0cyBmcm9tIHRoZWlyIHVzZSBpbiB0aGUgY29uc3RydWN0b3IgdG8gU3R5bGVMYXllciwgYXNcbi8vIHtsYXlvdXQ/OiBQcm9wZXJ0aWVzPC4uLj4sIHBhaW50OiBQcm9wZXJ0aWVzPC4uLj59XG5leHBvcnQgZGVmYXVsdCAoeyBwYWludCB9OiAkRXhhY3Q8e1xuICBwYWludDogUHJvcGVydGllczxQYWludFByb3BzPlxufT4pO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IFN0eWxlTGF5ZXIgZnJvbSAnLi4vc3R5bGVfbGF5ZXIuanMnO1xuXG5pbXBvcnQgcHJvcGVydGllcyBmcm9tICcuL2hpbGxzaGFkZV9zdHlsZV9sYXllcl9wcm9wZXJ0aWVzLmpzJztcbmltcG9ydCB7VHJhbnNpdGlvbmFibGUsIFRyYW5zaXRpb25pbmcsIFBvc3NpYmx5RXZhbHVhdGVkfSBmcm9tICcuLi9wcm9wZXJ0aWVzLmpzJztcblxuaW1wb3J0IHR5cGUge1BhaW50UHJvcHN9IGZyb20gJy4vaGlsbHNoYWRlX3N0eWxlX2xheWVyX3Byb3BlcnRpZXMuanMnO1xuaW1wb3J0IHR5cGUge0xheWVyU3BlY2lmaWNhdGlvbn0gZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy90eXBlcy5qcyc7XG5cbmNsYXNzIEhpbGxzaGFkZVN0eWxlTGF5ZXIgZXh0ZW5kcyBTdHlsZUxheWVyIHtcbiAgICBfdHJhbnNpdGlvbmFibGVQYWludDogVHJhbnNpdGlvbmFibGU8UGFpbnRQcm9wcz47XG4gICAgX3RyYW5zaXRpb25pbmdQYWludDogVHJhbnNpdGlvbmluZzxQYWludFByb3BzPjtcbiAgICBwYWludDogUG9zc2libHlFdmFsdWF0ZWQ8UGFpbnRQcm9wcz47XG5cbiAgICBjb25zdHJ1Y3RvcihsYXllcjogTGF5ZXJTcGVjaWZpY2F0aW9uKSB7XG4gICAgICAgIHN1cGVyKGxheWVyLCBwcm9wZXJ0aWVzKTtcbiAgICB9XG5cbiAgICBoYXNPZmZzY3JlZW5QYXNzKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5wYWludC5nZXQoJ2hpbGxzaGFkZS1leGFnZ2VyYXRpb24nKSAhPT0gMCAmJiB0aGlzLnZpc2liaWxpdHkgIT09ICdub25lJztcbiAgICB9XG5cbiAgICBnZXRQcm9ncmFtSWRzKCk6IEFycmF5PHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gWydoaWxsc2hhZGUnLCAnaGlsbHNoYWRlUHJlcGFyZSddO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgSGlsbHNoYWRlU3R5bGVMYXllcjtcbiIsIi8vIEBmbG93XG5pbXBvcnQge2NyZWF0ZUxheW91dH0gZnJvbSAnLi4vLi4vdXRpbC9zdHJ1Y3RfYXJyYXkuanMnO1xuXG5pbXBvcnQgdHlwZSB7U3RydWN0QXJyYXlMYXlvdXR9IGZyb20gJy4uLy4uL3V0aWwvc3RydWN0X2FycmF5LmpzJztcblxuY29uc3QgbGF5b3V0OiBTdHJ1Y3RBcnJheUxheW91dCA9IGNyZWF0ZUxheW91dChbXG4gICAge25hbWU6ICdhX3BvcycsIGNvbXBvbmVudHM6IDIsIHR5cGU6ICdJbnQxNid9XG5dLCA0KTtcblxuZXhwb3J0IGRlZmF1bHQgbGF5b3V0O1xuZXhwb3J0IGNvbnN0IHttZW1iZXJzLCBzaXplLCBhbGlnbm1lbnR9ID0gbGF5b3V0O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGVhcmN1dDtcbm1vZHVsZS5leHBvcnRzLmRlZmF1bHQgPSBlYXJjdXQ7XG5cbmZ1bmN0aW9uIGVhcmN1dChkYXRhLCBob2xlSW5kaWNlcywgZGltKSB7XG5cbiAgICBkaW0gPSBkaW0gfHwgMjtcblxuICAgIHZhciBoYXNIb2xlcyA9IGhvbGVJbmRpY2VzICYmIGhvbGVJbmRpY2VzLmxlbmd0aCxcbiAgICAgICAgb3V0ZXJMZW4gPSBoYXNIb2xlcyA/IGhvbGVJbmRpY2VzWzBdICogZGltIDogZGF0YS5sZW5ndGgsXG4gICAgICAgIG91dGVyTm9kZSA9IGxpbmtlZExpc3QoZGF0YSwgMCwgb3V0ZXJMZW4sIGRpbSwgdHJ1ZSksXG4gICAgICAgIHRyaWFuZ2xlcyA9IFtdO1xuXG4gICAgaWYgKCFvdXRlck5vZGUgfHwgb3V0ZXJOb2RlLm5leHQgPT09IG91dGVyTm9kZS5wcmV2KSByZXR1cm4gdHJpYW5nbGVzO1xuXG4gICAgdmFyIG1pblgsIG1pblksIG1heFgsIG1heFksIHgsIHksIGludlNpemU7XG5cbiAgICBpZiAoaGFzSG9sZXMpIG91dGVyTm9kZSA9IGVsaW1pbmF0ZUhvbGVzKGRhdGEsIGhvbGVJbmRpY2VzLCBvdXRlck5vZGUsIGRpbSk7XG5cbiAgICAvLyBpZiB0aGUgc2hhcGUgaXMgbm90IHRvbyBzaW1wbGUsIHdlJ2xsIHVzZSB6LW9yZGVyIGN1cnZlIGhhc2ggbGF0ZXI7IGNhbGN1bGF0ZSBwb2x5Z29uIGJib3hcbiAgICBpZiAoZGF0YS5sZW5ndGggPiA4MCAqIGRpbSkge1xuICAgICAgICBtaW5YID0gbWF4WCA9IGRhdGFbMF07XG4gICAgICAgIG1pblkgPSBtYXhZID0gZGF0YVsxXTtcblxuICAgICAgICBmb3IgKHZhciBpID0gZGltOyBpIDwgb3V0ZXJMZW47IGkgKz0gZGltKSB7XG4gICAgICAgICAgICB4ID0gZGF0YVtpXTtcbiAgICAgICAgICAgIHkgPSBkYXRhW2kgKyAxXTtcbiAgICAgICAgICAgIGlmICh4IDwgbWluWCkgbWluWCA9IHg7XG4gICAgICAgICAgICBpZiAoeSA8IG1pblkpIG1pblkgPSB5O1xuICAgICAgICAgICAgaWYgKHggPiBtYXhYKSBtYXhYID0geDtcbiAgICAgICAgICAgIGlmICh5ID4gbWF4WSkgbWF4WSA9IHk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBtaW5YLCBtaW5ZIGFuZCBpbnZTaXplIGFyZSBsYXRlciB1c2VkIHRvIHRyYW5zZm9ybSBjb29yZHMgaW50byBpbnRlZ2VycyBmb3Igei1vcmRlciBjYWxjdWxhdGlvblxuICAgICAgICBpbnZTaXplID0gTWF0aC5tYXgobWF4WCAtIG1pblgsIG1heFkgLSBtaW5ZKTtcbiAgICAgICAgaW52U2l6ZSA9IGludlNpemUgIT09IDAgPyAzMjc2NyAvIGludlNpemUgOiAwO1xuICAgIH1cblxuICAgIGVhcmN1dExpbmtlZChvdXRlck5vZGUsIHRyaWFuZ2xlcywgZGltLCBtaW5YLCBtaW5ZLCBpbnZTaXplLCAwKTtcblxuICAgIHJldHVybiB0cmlhbmdsZXM7XG59XG5cbi8vIGNyZWF0ZSBhIGNpcmN1bGFyIGRvdWJseSBsaW5rZWQgbGlzdCBmcm9tIHBvbHlnb24gcG9pbnRzIGluIHRoZSBzcGVjaWZpZWQgd2luZGluZyBvcmRlclxuZnVuY3Rpb24gbGlua2VkTGlzdChkYXRhLCBzdGFydCwgZW5kLCBkaW0sIGNsb2Nrd2lzZSkge1xuICAgIHZhciBpLCBsYXN0O1xuXG4gICAgaWYgKGNsb2Nrd2lzZSA9PT0gKHNpZ25lZEFyZWEoZGF0YSwgc3RhcnQsIGVuZCwgZGltKSA+IDApKSB7XG4gICAgICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgZW5kOyBpICs9IGRpbSkgbGFzdCA9IGluc2VydE5vZGUoaSwgZGF0YVtpXSwgZGF0YVtpICsgMV0sIGxhc3QpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGZvciAoaSA9IGVuZCAtIGRpbTsgaSA+PSBzdGFydDsgaSAtPSBkaW0pIGxhc3QgPSBpbnNlcnROb2RlKGksIGRhdGFbaV0sIGRhdGFbaSArIDFdLCBsYXN0KTtcbiAgICB9XG5cbiAgICBpZiAobGFzdCAmJiBlcXVhbHMobGFzdCwgbGFzdC5uZXh0KSkge1xuICAgICAgICByZW1vdmVOb2RlKGxhc3QpO1xuICAgICAgICBsYXN0ID0gbGFzdC5uZXh0O1xuICAgIH1cblxuICAgIHJldHVybiBsYXN0O1xufVxuXG4vLyBlbGltaW5hdGUgY29saW5lYXIgb3IgZHVwbGljYXRlIHBvaW50c1xuZnVuY3Rpb24gZmlsdGVyUG9pbnRzKHN0YXJ0LCBlbmQpIHtcbiAgICBpZiAoIXN0YXJ0KSByZXR1cm4gc3RhcnQ7XG4gICAgaWYgKCFlbmQpIGVuZCA9IHN0YXJ0O1xuXG4gICAgdmFyIHAgPSBzdGFydCxcbiAgICAgICAgYWdhaW47XG4gICAgZG8ge1xuICAgICAgICBhZ2FpbiA9IGZhbHNlO1xuXG4gICAgICAgIGlmICghcC5zdGVpbmVyICYmIChlcXVhbHMocCwgcC5uZXh0KSB8fCBhcmVhKHAucHJldiwgcCwgcC5uZXh0KSA9PT0gMCkpIHtcbiAgICAgICAgICAgIHJlbW92ZU5vZGUocCk7XG4gICAgICAgICAgICBwID0gZW5kID0gcC5wcmV2O1xuICAgICAgICAgICAgaWYgKHAgPT09IHAubmV4dCkgYnJlYWs7XG4gICAgICAgICAgICBhZ2FpbiA9IHRydWU7XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHAgPSBwLm5leHQ7XG4gICAgICAgIH1cbiAgICB9IHdoaWxlIChhZ2FpbiB8fCBwICE9PSBlbmQpO1xuXG4gICAgcmV0dXJuIGVuZDtcbn1cblxuLy8gbWFpbiBlYXIgc2xpY2luZyBsb29wIHdoaWNoIHRyaWFuZ3VsYXRlcyBhIHBvbHlnb24gKGdpdmVuIGFzIGEgbGlua2VkIGxpc3QpXG5mdW5jdGlvbiBlYXJjdXRMaW5rZWQoZWFyLCB0cmlhbmdsZXMsIGRpbSwgbWluWCwgbWluWSwgaW52U2l6ZSwgcGFzcykge1xuICAgIGlmICghZWFyKSByZXR1cm47XG5cbiAgICAvLyBpbnRlcmxpbmsgcG9seWdvbiBub2RlcyBpbiB6LW9yZGVyXG4gICAgaWYgKCFwYXNzICYmIGludlNpemUpIGluZGV4Q3VydmUoZWFyLCBtaW5YLCBtaW5ZLCBpbnZTaXplKTtcblxuICAgIHZhciBzdG9wID0gZWFyLFxuICAgICAgICBwcmV2LCBuZXh0O1xuXG4gICAgLy8gaXRlcmF0ZSB0aHJvdWdoIGVhcnMsIHNsaWNpbmcgdGhlbSBvbmUgYnkgb25lXG4gICAgd2hpbGUgKGVhci5wcmV2ICE9PSBlYXIubmV4dCkge1xuICAgICAgICBwcmV2ID0gZWFyLnByZXY7XG4gICAgICAgIG5leHQgPSBlYXIubmV4dDtcblxuICAgICAgICBpZiAoaW52U2l6ZSA/IGlzRWFySGFzaGVkKGVhciwgbWluWCwgbWluWSwgaW52U2l6ZSkgOiBpc0VhcihlYXIpKSB7XG4gICAgICAgICAgICAvLyBjdXQgb2ZmIHRoZSB0cmlhbmdsZVxuICAgICAgICAgICAgdHJpYW5nbGVzLnB1c2gocHJldi5pIC8gZGltIHwgMCk7XG4gICAgICAgICAgICB0cmlhbmdsZXMucHVzaChlYXIuaSAvIGRpbSB8IDApO1xuICAgICAgICAgICAgdHJpYW5nbGVzLnB1c2gobmV4dC5pIC8gZGltIHwgMCk7XG5cbiAgICAgICAgICAgIHJlbW92ZU5vZGUoZWFyKTtcblxuICAgICAgICAgICAgLy8gc2tpcHBpbmcgdGhlIG5leHQgdmVydGV4IGxlYWRzIHRvIGxlc3Mgc2xpdmVyIHRyaWFuZ2xlc1xuICAgICAgICAgICAgZWFyID0gbmV4dC5uZXh0O1xuICAgICAgICAgICAgc3RvcCA9IG5leHQubmV4dDtcblxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBlYXIgPSBuZXh0O1xuXG4gICAgICAgIC8vIGlmIHdlIGxvb3BlZCB0aHJvdWdoIHRoZSB3aG9sZSByZW1haW5pbmcgcG9seWdvbiBhbmQgY2FuJ3QgZmluZCBhbnkgbW9yZSBlYXJzXG4gICAgICAgIGlmIChlYXIgPT09IHN0b3ApIHtcbiAgICAgICAgICAgIC8vIHRyeSBmaWx0ZXJpbmcgcG9pbnRzIGFuZCBzbGljaW5nIGFnYWluXG4gICAgICAgICAgICBpZiAoIXBhc3MpIHtcbiAgICAgICAgICAgICAgICBlYXJjdXRMaW5rZWQoZmlsdGVyUG9pbnRzKGVhciksIHRyaWFuZ2xlcywgZGltLCBtaW5YLCBtaW5ZLCBpbnZTaXplLCAxKTtcblxuICAgICAgICAgICAgLy8gaWYgdGhpcyBkaWRuJ3Qgd29yaywgdHJ5IGN1cmluZyBhbGwgc21hbGwgc2VsZi1pbnRlcnNlY3Rpb25zIGxvY2FsbHlcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocGFzcyA9PT0gMSkge1xuICAgICAgICAgICAgICAgIGVhciA9IGN1cmVMb2NhbEludGVyc2VjdGlvbnMoZmlsdGVyUG9pbnRzKGVhciksIHRyaWFuZ2xlcywgZGltKTtcbiAgICAgICAgICAgICAgICBlYXJjdXRMaW5rZWQoZWFyLCB0cmlhbmdsZXMsIGRpbSwgbWluWCwgbWluWSwgaW52U2l6ZSwgMik7XG5cbiAgICAgICAgICAgIC8vIGFzIGEgbGFzdCByZXNvcnQsIHRyeSBzcGxpdHRpbmcgdGhlIHJlbWFpbmluZyBwb2x5Z29uIGludG8gdHdvXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHBhc3MgPT09IDIpIHtcbiAgICAgICAgICAgICAgICBzcGxpdEVhcmN1dChlYXIsIHRyaWFuZ2xlcywgZGltLCBtaW5YLCBtaW5ZLCBpbnZTaXplKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8vIGNoZWNrIHdoZXRoZXIgYSBwb2x5Z29uIG5vZGUgZm9ybXMgYSB2YWxpZCBlYXIgd2l0aCBhZGphY2VudCBub2Rlc1xuZnVuY3Rpb24gaXNFYXIoZWFyKSB7XG4gICAgdmFyIGEgPSBlYXIucHJldixcbiAgICAgICAgYiA9IGVhcixcbiAgICAgICAgYyA9IGVhci5uZXh0O1xuXG4gICAgaWYgKGFyZWEoYSwgYiwgYykgPj0gMCkgcmV0dXJuIGZhbHNlOyAvLyByZWZsZXgsIGNhbid0IGJlIGFuIGVhclxuXG4gICAgLy8gbm93IG1ha2Ugc3VyZSB3ZSBkb24ndCBoYXZlIG90aGVyIHBvaW50cyBpbnNpZGUgdGhlIHBvdGVudGlhbCBlYXJcbiAgICB2YXIgYXggPSBhLngsIGJ4ID0gYi54LCBjeCA9IGMueCwgYXkgPSBhLnksIGJ5ID0gYi55LCBjeSA9IGMueTtcblxuICAgIC8vIHRyaWFuZ2xlIGJib3g7IG1pbiAmIG1heCBhcmUgY2FsY3VsYXRlZCBsaWtlIHRoaXMgZm9yIHNwZWVkXG4gICAgdmFyIHgwID0gYXggPCBieCA/IChheCA8IGN4ID8gYXggOiBjeCkgOiAoYnggPCBjeCA/IGJ4IDogY3gpLFxuICAgICAgICB5MCA9IGF5IDwgYnkgPyAoYXkgPCBjeSA/IGF5IDogY3kpIDogKGJ5IDwgY3kgPyBieSA6IGN5KSxcbiAgICAgICAgeDEgPSBheCA+IGJ4ID8gKGF4ID4gY3ggPyBheCA6IGN4KSA6IChieCA+IGN4ID8gYnggOiBjeCksXG4gICAgICAgIHkxID0gYXkgPiBieSA/IChheSA+IGN5ID8gYXkgOiBjeSkgOiAoYnkgPiBjeSA/IGJ5IDogY3kpO1xuXG4gICAgdmFyIHAgPSBjLm5leHQ7XG4gICAgd2hpbGUgKHAgIT09IGEpIHtcbiAgICAgICAgaWYgKHAueCA+PSB4MCAmJiBwLnggPD0geDEgJiYgcC55ID49IHkwICYmIHAueSA8PSB5MSAmJlxuICAgICAgICAgICAgcG9pbnRJblRyaWFuZ2xlKGF4LCBheSwgYngsIGJ5LCBjeCwgY3ksIHAueCwgcC55KSAmJlxuICAgICAgICAgICAgYXJlYShwLnByZXYsIHAsIHAubmV4dCkgPj0gMCkgcmV0dXJuIGZhbHNlO1xuICAgICAgICBwID0gcC5uZXh0O1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBpc0Vhckhhc2hlZChlYXIsIG1pblgsIG1pblksIGludlNpemUpIHtcbiAgICB2YXIgYSA9IGVhci5wcmV2LFxuICAgICAgICBiID0gZWFyLFxuICAgICAgICBjID0gZWFyLm5leHQ7XG5cbiAgICBpZiAoYXJlYShhLCBiLCBjKSA+PSAwKSByZXR1cm4gZmFsc2U7IC8vIHJlZmxleCwgY2FuJ3QgYmUgYW4gZWFyXG5cbiAgICB2YXIgYXggPSBhLngsIGJ4ID0gYi54LCBjeCA9IGMueCwgYXkgPSBhLnksIGJ5ID0gYi55LCBjeSA9IGMueTtcblxuICAgIC8vIHRyaWFuZ2xlIGJib3g7IG1pbiAmIG1heCBhcmUgY2FsY3VsYXRlZCBsaWtlIHRoaXMgZm9yIHNwZWVkXG4gICAgdmFyIHgwID0gYXggPCBieCA/IChheCA8IGN4ID8gYXggOiBjeCkgOiAoYnggPCBjeCA/IGJ4IDogY3gpLFxuICAgICAgICB5MCA9IGF5IDwgYnkgPyAoYXkgPCBjeSA/IGF5IDogY3kpIDogKGJ5IDwgY3kgPyBieSA6IGN5KSxcbiAgICAgICAgeDEgPSBheCA+IGJ4ID8gKGF4ID4gY3ggPyBheCA6IGN4KSA6IChieCA+IGN4ID8gYnggOiBjeCksXG4gICAgICAgIHkxID0gYXkgPiBieSA/IChheSA+IGN5ID8gYXkgOiBjeSkgOiAoYnkgPiBjeSA/IGJ5IDogY3kpO1xuXG4gICAgLy8gei1vcmRlciByYW5nZSBmb3IgdGhlIGN1cnJlbnQgdHJpYW5nbGUgYmJveDtcbiAgICB2YXIgbWluWiA9IHpPcmRlcih4MCwgeTAsIG1pblgsIG1pblksIGludlNpemUpLFxuICAgICAgICBtYXhaID0gek9yZGVyKHgxLCB5MSwgbWluWCwgbWluWSwgaW52U2l6ZSk7XG5cbiAgICB2YXIgcCA9IGVhci5wcmV2WixcbiAgICAgICAgbiA9IGVhci5uZXh0WjtcblxuICAgIC8vIGxvb2sgZm9yIHBvaW50cyBpbnNpZGUgdGhlIHRyaWFuZ2xlIGluIGJvdGggZGlyZWN0aW9uc1xuICAgIHdoaWxlIChwICYmIHAueiA+PSBtaW5aICYmIG4gJiYgbi56IDw9IG1heFopIHtcbiAgICAgICAgaWYgKHAueCA+PSB4MCAmJiBwLnggPD0geDEgJiYgcC55ID49IHkwICYmIHAueSA8PSB5MSAmJiBwICE9PSBhICYmIHAgIT09IGMgJiZcbiAgICAgICAgICAgIHBvaW50SW5UcmlhbmdsZShheCwgYXksIGJ4LCBieSwgY3gsIGN5LCBwLngsIHAueSkgJiYgYXJlYShwLnByZXYsIHAsIHAubmV4dCkgPj0gMCkgcmV0dXJuIGZhbHNlO1xuICAgICAgICBwID0gcC5wcmV2WjtcblxuICAgICAgICBpZiAobi54ID49IHgwICYmIG4ueCA8PSB4MSAmJiBuLnkgPj0geTAgJiYgbi55IDw9IHkxICYmIG4gIT09IGEgJiYgbiAhPT0gYyAmJlxuICAgICAgICAgICAgcG9pbnRJblRyaWFuZ2xlKGF4LCBheSwgYngsIGJ5LCBjeCwgY3ksIG4ueCwgbi55KSAmJiBhcmVhKG4ucHJldiwgbiwgbi5uZXh0KSA+PSAwKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIG4gPSBuLm5leHRaO1xuICAgIH1cblxuICAgIC8vIGxvb2sgZm9yIHJlbWFpbmluZyBwb2ludHMgaW4gZGVjcmVhc2luZyB6LW9yZGVyXG4gICAgd2hpbGUgKHAgJiYgcC56ID49IG1pblopIHtcbiAgICAgICAgaWYgKHAueCA+PSB4MCAmJiBwLnggPD0geDEgJiYgcC55ID49IHkwICYmIHAueSA8PSB5MSAmJiBwICE9PSBhICYmIHAgIT09IGMgJiZcbiAgICAgICAgICAgIHBvaW50SW5UcmlhbmdsZShheCwgYXksIGJ4LCBieSwgY3gsIGN5LCBwLngsIHAueSkgJiYgYXJlYShwLnByZXYsIHAsIHAubmV4dCkgPj0gMCkgcmV0dXJuIGZhbHNlO1xuICAgICAgICBwID0gcC5wcmV2WjtcbiAgICB9XG5cbiAgICAvLyBsb29rIGZvciByZW1haW5pbmcgcG9pbnRzIGluIGluY3JlYXNpbmcgei1vcmRlclxuICAgIHdoaWxlIChuICYmIG4ueiA8PSBtYXhaKSB7XG4gICAgICAgIGlmIChuLnggPj0geDAgJiYgbi54IDw9IHgxICYmIG4ueSA+PSB5MCAmJiBuLnkgPD0geTEgJiYgbiAhPT0gYSAmJiBuICE9PSBjICYmXG4gICAgICAgICAgICBwb2ludEluVHJpYW5nbGUoYXgsIGF5LCBieCwgYnksIGN4LCBjeSwgbi54LCBuLnkpICYmIGFyZWEobi5wcmV2LCBuLCBuLm5leHQpID49IDApIHJldHVybiBmYWxzZTtcbiAgICAgICAgbiA9IG4ubmV4dFo7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG59XG5cbi8vIGdvIHRocm91Z2ggYWxsIHBvbHlnb24gbm9kZXMgYW5kIGN1cmUgc21hbGwgbG9jYWwgc2VsZi1pbnRlcnNlY3Rpb25zXG5mdW5jdGlvbiBjdXJlTG9jYWxJbnRlcnNlY3Rpb25zKHN0YXJ0LCB0cmlhbmdsZXMsIGRpbSkge1xuICAgIHZhciBwID0gc3RhcnQ7XG4gICAgZG8ge1xuICAgICAgICB2YXIgYSA9IHAucHJldixcbiAgICAgICAgICAgIGIgPSBwLm5leHQubmV4dDtcblxuICAgICAgICBpZiAoIWVxdWFscyhhLCBiKSAmJiBpbnRlcnNlY3RzKGEsIHAsIHAubmV4dCwgYikgJiYgbG9jYWxseUluc2lkZShhLCBiKSAmJiBsb2NhbGx5SW5zaWRlKGIsIGEpKSB7XG5cbiAgICAgICAgICAgIHRyaWFuZ2xlcy5wdXNoKGEuaSAvIGRpbSB8IDApO1xuICAgICAgICAgICAgdHJpYW5nbGVzLnB1c2gocC5pIC8gZGltIHwgMCk7XG4gICAgICAgICAgICB0cmlhbmdsZXMucHVzaChiLmkgLyBkaW0gfCAwKTtcblxuICAgICAgICAgICAgLy8gcmVtb3ZlIHR3byBub2RlcyBpbnZvbHZlZFxuICAgICAgICAgICAgcmVtb3ZlTm9kZShwKTtcbiAgICAgICAgICAgIHJlbW92ZU5vZGUocC5uZXh0KTtcblxuICAgICAgICAgICAgcCA9IHN0YXJ0ID0gYjtcbiAgICAgICAgfVxuICAgICAgICBwID0gcC5uZXh0O1xuICAgIH0gd2hpbGUgKHAgIT09IHN0YXJ0KTtcblxuICAgIHJldHVybiBmaWx0ZXJQb2ludHMocCk7XG59XG5cbi8vIHRyeSBzcGxpdHRpbmcgcG9seWdvbiBpbnRvIHR3byBhbmQgdHJpYW5ndWxhdGUgdGhlbSBpbmRlcGVuZGVudGx5XG5mdW5jdGlvbiBzcGxpdEVhcmN1dChzdGFydCwgdHJpYW5nbGVzLCBkaW0sIG1pblgsIG1pblksIGludlNpemUpIHtcbiAgICAvLyBsb29rIGZvciBhIHZhbGlkIGRpYWdvbmFsIHRoYXQgZGl2aWRlcyB0aGUgcG9seWdvbiBpbnRvIHR3b1xuICAgIHZhciBhID0gc3RhcnQ7XG4gICAgZG8ge1xuICAgICAgICB2YXIgYiA9IGEubmV4dC5uZXh0O1xuICAgICAgICB3aGlsZSAoYiAhPT0gYS5wcmV2KSB7XG4gICAgICAgICAgICBpZiAoYS5pICE9PSBiLmkgJiYgaXNWYWxpZERpYWdvbmFsKGEsIGIpKSB7XG4gICAgICAgICAgICAgICAgLy8gc3BsaXQgdGhlIHBvbHlnb24gaW4gdHdvIGJ5IHRoZSBkaWFnb25hbFxuICAgICAgICAgICAgICAgIHZhciBjID0gc3BsaXRQb2x5Z29uKGEsIGIpO1xuXG4gICAgICAgICAgICAgICAgLy8gZmlsdGVyIGNvbGluZWFyIHBvaW50cyBhcm91bmQgdGhlIGN1dHNcbiAgICAgICAgICAgICAgICBhID0gZmlsdGVyUG9pbnRzKGEsIGEubmV4dCk7XG4gICAgICAgICAgICAgICAgYyA9IGZpbHRlclBvaW50cyhjLCBjLm5leHQpO1xuXG4gICAgICAgICAgICAgICAgLy8gcnVuIGVhcmN1dCBvbiBlYWNoIGhhbGZcbiAgICAgICAgICAgICAgICBlYXJjdXRMaW5rZWQoYSwgdHJpYW5nbGVzLCBkaW0sIG1pblgsIG1pblksIGludlNpemUsIDApO1xuICAgICAgICAgICAgICAgIGVhcmN1dExpbmtlZChjLCB0cmlhbmdsZXMsIGRpbSwgbWluWCwgbWluWSwgaW52U2l6ZSwgMCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYiA9IGIubmV4dDtcbiAgICAgICAgfVxuICAgICAgICBhID0gYS5uZXh0O1xuICAgIH0gd2hpbGUgKGEgIT09IHN0YXJ0KTtcbn1cblxuLy8gbGluayBldmVyeSBob2xlIGludG8gdGhlIG91dGVyIGxvb3AsIHByb2R1Y2luZyBhIHNpbmdsZS1yaW5nIHBvbHlnb24gd2l0aG91dCBob2xlc1xuZnVuY3Rpb24gZWxpbWluYXRlSG9sZXMoZGF0YSwgaG9sZUluZGljZXMsIG91dGVyTm9kZSwgZGltKSB7XG4gICAgdmFyIHF1ZXVlID0gW10sXG4gICAgICAgIGksIGxlbiwgc3RhcnQsIGVuZCwgbGlzdDtcblxuICAgIGZvciAoaSA9IDAsIGxlbiA9IGhvbGVJbmRpY2VzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHN0YXJ0ID0gaG9sZUluZGljZXNbaV0gKiBkaW07XG4gICAgICAgIGVuZCA9IGkgPCBsZW4gLSAxID8gaG9sZUluZGljZXNbaSArIDFdICogZGltIDogZGF0YS5sZW5ndGg7XG4gICAgICAgIGxpc3QgPSBsaW5rZWRMaXN0KGRhdGEsIHN0YXJ0LCBlbmQsIGRpbSwgZmFsc2UpO1xuICAgICAgICBpZiAobGlzdCA9PT0gbGlzdC5uZXh0KSBsaXN0LnN0ZWluZXIgPSB0cnVlO1xuICAgICAgICBxdWV1ZS5wdXNoKGdldExlZnRtb3N0KGxpc3QpKTtcbiAgICB9XG5cbiAgICBxdWV1ZS5zb3J0KGNvbXBhcmVYKTtcblxuICAgIC8vIHByb2Nlc3MgaG9sZXMgZnJvbSBsZWZ0IHRvIHJpZ2h0XG4gICAgZm9yIChpID0gMDsgaSA8IHF1ZXVlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIG91dGVyTm9kZSA9IGVsaW1pbmF0ZUhvbGUocXVldWVbaV0sIG91dGVyTm9kZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dGVyTm9kZTtcbn1cblxuZnVuY3Rpb24gY29tcGFyZVgoYSwgYikge1xuICAgIHJldHVybiBhLnggLSBiLng7XG59XG5cbi8vIGZpbmQgYSBicmlkZ2UgYmV0d2VlbiB2ZXJ0aWNlcyB0aGF0IGNvbm5lY3RzIGhvbGUgd2l0aCBhbiBvdXRlciByaW5nIGFuZCBhbmQgbGluayBpdFxuZnVuY3Rpb24gZWxpbWluYXRlSG9sZShob2xlLCBvdXRlck5vZGUpIHtcbiAgICB2YXIgYnJpZGdlID0gZmluZEhvbGVCcmlkZ2UoaG9sZSwgb3V0ZXJOb2RlKTtcbiAgICBpZiAoIWJyaWRnZSkge1xuICAgICAgICByZXR1cm4gb3V0ZXJOb2RlO1xuICAgIH1cblxuICAgIHZhciBicmlkZ2VSZXZlcnNlID0gc3BsaXRQb2x5Z29uKGJyaWRnZSwgaG9sZSk7XG5cbiAgICAvLyBmaWx0ZXIgY29sbGluZWFyIHBvaW50cyBhcm91bmQgdGhlIGN1dHNcbiAgICBmaWx0ZXJQb2ludHMoYnJpZGdlUmV2ZXJzZSwgYnJpZGdlUmV2ZXJzZS5uZXh0KTtcbiAgICByZXR1cm4gZmlsdGVyUG9pbnRzKGJyaWRnZSwgYnJpZGdlLm5leHQpO1xufVxuXG4vLyBEYXZpZCBFYmVybHkncyBhbGdvcml0aG0gZm9yIGZpbmRpbmcgYSBicmlkZ2UgYmV0d2VlbiBob2xlIGFuZCBvdXRlciBwb2x5Z29uXG5mdW5jdGlvbiBmaW5kSG9sZUJyaWRnZShob2xlLCBvdXRlck5vZGUpIHtcbiAgICB2YXIgcCA9IG91dGVyTm9kZSxcbiAgICAgICAgaHggPSBob2xlLngsXG4gICAgICAgIGh5ID0gaG9sZS55LFxuICAgICAgICBxeCA9IC1JbmZpbml0eSxcbiAgICAgICAgbTtcblxuICAgIC8vIGZpbmQgYSBzZWdtZW50IGludGVyc2VjdGVkIGJ5IGEgcmF5IGZyb20gdGhlIGhvbGUncyBsZWZ0bW9zdCBwb2ludCB0byB0aGUgbGVmdDtcbiAgICAvLyBzZWdtZW50J3MgZW5kcG9pbnQgd2l0aCBsZXNzZXIgeCB3aWxsIGJlIHBvdGVudGlhbCBjb25uZWN0aW9uIHBvaW50XG4gICAgZG8ge1xuICAgICAgICBpZiAoaHkgPD0gcC55ICYmIGh5ID49IHAubmV4dC55ICYmIHAubmV4dC55ICE9PSBwLnkpIHtcbiAgICAgICAgICAgIHZhciB4ID0gcC54ICsgKGh5IC0gcC55KSAqIChwLm5leHQueCAtIHAueCkgLyAocC5uZXh0LnkgLSBwLnkpO1xuICAgICAgICAgICAgaWYgKHggPD0gaHggJiYgeCA+IHF4KSB7XG4gICAgICAgICAgICAgICAgcXggPSB4O1xuICAgICAgICAgICAgICAgIG0gPSBwLnggPCBwLm5leHQueCA/IHAgOiBwLm5leHQ7XG4gICAgICAgICAgICAgICAgaWYgKHggPT09IGh4KSByZXR1cm4gbTsgLy8gaG9sZSB0b3VjaGVzIG91dGVyIHNlZ21lbnQ7IHBpY2sgbGVmdG1vc3QgZW5kcG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBwID0gcC5uZXh0O1xuICAgIH0gd2hpbGUgKHAgIT09IG91dGVyTm9kZSk7XG5cbiAgICBpZiAoIW0pIHJldHVybiBudWxsO1xuXG4gICAgLy8gbG9vayBmb3IgcG9pbnRzIGluc2lkZSB0aGUgdHJpYW5nbGUgb2YgaG9sZSBwb2ludCwgc2VnbWVudCBpbnRlcnNlY3Rpb24gYW5kIGVuZHBvaW50O1xuICAgIC8vIGlmIHRoZXJlIGFyZSBubyBwb2ludHMgZm91bmQsIHdlIGhhdmUgYSB2YWxpZCBjb25uZWN0aW9uO1xuICAgIC8vIG90aGVyd2lzZSBjaG9vc2UgdGhlIHBvaW50IG9mIHRoZSBtaW5pbXVtIGFuZ2xlIHdpdGggdGhlIHJheSBhcyBjb25uZWN0aW9uIHBvaW50XG5cbiAgICB2YXIgc3RvcCA9IG0sXG4gICAgICAgIG14ID0gbS54LFxuICAgICAgICBteSA9IG0ueSxcbiAgICAgICAgdGFuTWluID0gSW5maW5pdHksXG4gICAgICAgIHRhbjtcblxuICAgIHAgPSBtO1xuXG4gICAgZG8ge1xuICAgICAgICBpZiAoaHggPj0gcC54ICYmIHAueCA+PSBteCAmJiBoeCAhPT0gcC54ICYmXG4gICAgICAgICAgICAgICAgcG9pbnRJblRyaWFuZ2xlKGh5IDwgbXkgPyBoeCA6IHF4LCBoeSwgbXgsIG15LCBoeSA8IG15ID8gcXggOiBoeCwgaHksIHAueCwgcC55KSkge1xuXG4gICAgICAgICAgICB0YW4gPSBNYXRoLmFicyhoeSAtIHAueSkgLyAoaHggLSBwLngpOyAvLyB0YW5nZW50aWFsXG5cbiAgICAgICAgICAgIGlmIChsb2NhbGx5SW5zaWRlKHAsIGhvbGUpICYmXG4gICAgICAgICAgICAgICAgKHRhbiA8IHRhbk1pbiB8fCAodGFuID09PSB0YW5NaW4gJiYgKHAueCA+IG0ueCB8fCAocC54ID09PSBtLnggJiYgc2VjdG9yQ29udGFpbnNTZWN0b3IobSwgcCkpKSkpKSB7XG4gICAgICAgICAgICAgICAgbSA9IHA7XG4gICAgICAgICAgICAgICAgdGFuTWluID0gdGFuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcCA9IHAubmV4dDtcbiAgICB9IHdoaWxlIChwICE9PSBzdG9wKTtcblxuICAgIHJldHVybiBtO1xufVxuXG4vLyB3aGV0aGVyIHNlY3RvciBpbiB2ZXJ0ZXggbSBjb250YWlucyBzZWN0b3IgaW4gdmVydGV4IHAgaW4gdGhlIHNhbWUgY29vcmRpbmF0ZXNcbmZ1bmN0aW9uIHNlY3RvckNvbnRhaW5zU2VjdG9yKG0sIHApIHtcbiAgICByZXR1cm4gYXJlYShtLnByZXYsIG0sIHAucHJldikgPCAwICYmIGFyZWEocC5uZXh0LCBtLCBtLm5leHQpIDwgMDtcbn1cblxuLy8gaW50ZXJsaW5rIHBvbHlnb24gbm9kZXMgaW4gei1vcmRlclxuZnVuY3Rpb24gaW5kZXhDdXJ2ZShzdGFydCwgbWluWCwgbWluWSwgaW52U2l6ZSkge1xuICAgIHZhciBwID0gc3RhcnQ7XG4gICAgZG8ge1xuICAgICAgICBpZiAocC56ID09PSAwKSBwLnogPSB6T3JkZXIocC54LCBwLnksIG1pblgsIG1pblksIGludlNpemUpO1xuICAgICAgICBwLnByZXZaID0gcC5wcmV2O1xuICAgICAgICBwLm5leHRaID0gcC5uZXh0O1xuICAgICAgICBwID0gcC5uZXh0O1xuICAgIH0gd2hpbGUgKHAgIT09IHN0YXJ0KTtcblxuICAgIHAucHJldloubmV4dFogPSBudWxsO1xuICAgIHAucHJldlogPSBudWxsO1xuXG4gICAgc29ydExpbmtlZChwKTtcbn1cblxuLy8gU2ltb24gVGF0aGFtJ3MgbGlua2VkIGxpc3QgbWVyZ2Ugc29ydCBhbGdvcml0aG1cbi8vIGh0dHA6Ly93d3cuY2hpYXJrLmdyZWVuZW5kLm9yZy51ay9+c2d0YXRoYW0vYWxnb3JpdGhtcy9saXN0c29ydC5odG1sXG5mdW5jdGlvbiBzb3J0TGlua2VkKGxpc3QpIHtcbiAgICB2YXIgaSwgcCwgcSwgZSwgdGFpbCwgbnVtTWVyZ2VzLCBwU2l6ZSwgcVNpemUsXG4gICAgICAgIGluU2l6ZSA9IDE7XG5cbiAgICBkbyB7XG4gICAgICAgIHAgPSBsaXN0O1xuICAgICAgICBsaXN0ID0gbnVsbDtcbiAgICAgICAgdGFpbCA9IG51bGw7XG4gICAgICAgIG51bU1lcmdlcyA9IDA7XG5cbiAgICAgICAgd2hpbGUgKHApIHtcbiAgICAgICAgICAgIG51bU1lcmdlcysrO1xuICAgICAgICAgICAgcSA9IHA7XG4gICAgICAgICAgICBwU2l6ZSA9IDA7XG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgaW5TaXplOyBpKyspIHtcbiAgICAgICAgICAgICAgICBwU2l6ZSsrO1xuICAgICAgICAgICAgICAgIHEgPSBxLm5leHRaO1xuICAgICAgICAgICAgICAgIGlmICghcSkgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBxU2l6ZSA9IGluU2l6ZTtcblxuICAgICAgICAgICAgd2hpbGUgKHBTaXplID4gMCB8fCAocVNpemUgPiAwICYmIHEpKSB7XG5cbiAgICAgICAgICAgICAgICBpZiAocFNpemUgIT09IDAgJiYgKHFTaXplID09PSAwIHx8ICFxIHx8IHAueiA8PSBxLnopKSB7XG4gICAgICAgICAgICAgICAgICAgIGUgPSBwO1xuICAgICAgICAgICAgICAgICAgICBwID0gcC5uZXh0WjtcbiAgICAgICAgICAgICAgICAgICAgcFNpemUtLTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBlID0gcTtcbiAgICAgICAgICAgICAgICAgICAgcSA9IHEubmV4dFo7XG4gICAgICAgICAgICAgICAgICAgIHFTaXplLS07XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHRhaWwpIHRhaWwubmV4dFogPSBlO1xuICAgICAgICAgICAgICAgIGVsc2UgbGlzdCA9IGU7XG5cbiAgICAgICAgICAgICAgICBlLnByZXZaID0gdGFpbDtcbiAgICAgICAgICAgICAgICB0YWlsID0gZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcCA9IHE7XG4gICAgICAgIH1cblxuICAgICAgICB0YWlsLm5leHRaID0gbnVsbDtcbiAgICAgICAgaW5TaXplICo9IDI7XG5cbiAgICB9IHdoaWxlIChudW1NZXJnZXMgPiAxKTtcblxuICAgIHJldHVybiBsaXN0O1xufVxuXG4vLyB6LW9yZGVyIG9mIGEgcG9pbnQgZ2l2ZW4gY29vcmRzIGFuZCBpbnZlcnNlIG9mIHRoZSBsb25nZXIgc2lkZSBvZiBkYXRhIGJib3hcbmZ1bmN0aW9uIHpPcmRlcih4LCB5LCBtaW5YLCBtaW5ZLCBpbnZTaXplKSB7XG4gICAgLy8gY29vcmRzIGFyZSB0cmFuc2Zvcm1lZCBpbnRvIG5vbi1uZWdhdGl2ZSAxNS1iaXQgaW50ZWdlciByYW5nZVxuICAgIHggPSAoeCAtIG1pblgpICogaW52U2l6ZSB8IDA7XG4gICAgeSA9ICh5IC0gbWluWSkgKiBpbnZTaXplIHwgMDtcblxuICAgIHggPSAoeCB8ICh4IDw8IDgpKSAmIDB4MDBGRjAwRkY7XG4gICAgeCA9ICh4IHwgKHggPDwgNCkpICYgMHgwRjBGMEYwRjtcbiAgICB4ID0gKHggfCAoeCA8PCAyKSkgJiAweDMzMzMzMzMzO1xuICAgIHggPSAoeCB8ICh4IDw8IDEpKSAmIDB4NTU1NTU1NTU7XG5cbiAgICB5ID0gKHkgfCAoeSA8PCA4KSkgJiAweDAwRkYwMEZGO1xuICAgIHkgPSAoeSB8ICh5IDw8IDQpKSAmIDB4MEYwRjBGMEY7XG4gICAgeSA9ICh5IHwgKHkgPDwgMikpICYgMHgzMzMzMzMzMztcbiAgICB5ID0gKHkgfCAoeSA8PCAxKSkgJiAweDU1NTU1NTU1O1xuXG4gICAgcmV0dXJuIHggfCAoeSA8PCAxKTtcbn1cblxuLy8gZmluZCB0aGUgbGVmdG1vc3Qgbm9kZSBvZiBhIHBvbHlnb24gcmluZ1xuZnVuY3Rpb24gZ2V0TGVmdG1vc3Qoc3RhcnQpIHtcbiAgICB2YXIgcCA9IHN0YXJ0LFxuICAgICAgICBsZWZ0bW9zdCA9IHN0YXJ0O1xuICAgIGRvIHtcbiAgICAgICAgaWYgKHAueCA8IGxlZnRtb3N0LnggfHwgKHAueCA9PT0gbGVmdG1vc3QueCAmJiBwLnkgPCBsZWZ0bW9zdC55KSkgbGVmdG1vc3QgPSBwO1xuICAgICAgICBwID0gcC5uZXh0O1xuICAgIH0gd2hpbGUgKHAgIT09IHN0YXJ0KTtcblxuICAgIHJldHVybiBsZWZ0bW9zdDtcbn1cblxuLy8gY2hlY2sgaWYgYSBwb2ludCBsaWVzIHdpdGhpbiBhIGNvbnZleCB0cmlhbmdsZVxuZnVuY3Rpb24gcG9pbnRJblRyaWFuZ2xlKGF4LCBheSwgYngsIGJ5LCBjeCwgY3ksIHB4LCBweSkge1xuICAgIHJldHVybiAoY3ggLSBweCkgKiAoYXkgLSBweSkgPj0gKGF4IC0gcHgpICogKGN5IC0gcHkpICYmXG4gICAgICAgICAgIChheCAtIHB4KSAqIChieSAtIHB5KSA+PSAoYnggLSBweCkgKiAoYXkgLSBweSkgJiZcbiAgICAgICAgICAgKGJ4IC0gcHgpICogKGN5IC0gcHkpID49IChjeCAtIHB4KSAqIChieSAtIHB5KTtcbn1cblxuLy8gY2hlY2sgaWYgYSBkaWFnb25hbCBiZXR3ZWVuIHR3byBwb2x5Z29uIG5vZGVzIGlzIHZhbGlkIChsaWVzIGluIHBvbHlnb24gaW50ZXJpb3IpXG5mdW5jdGlvbiBpc1ZhbGlkRGlhZ29uYWwoYSwgYikge1xuICAgIHJldHVybiBhLm5leHQuaSAhPT0gYi5pICYmIGEucHJldi5pICE9PSBiLmkgJiYgIWludGVyc2VjdHNQb2x5Z29uKGEsIGIpICYmIC8vIGRvbmVzJ3QgaW50ZXJzZWN0IG90aGVyIGVkZ2VzXG4gICAgICAgICAgIChsb2NhbGx5SW5zaWRlKGEsIGIpICYmIGxvY2FsbHlJbnNpZGUoYiwgYSkgJiYgbWlkZGxlSW5zaWRlKGEsIGIpICYmIC8vIGxvY2FsbHkgdmlzaWJsZVxuICAgICAgICAgICAgKGFyZWEoYS5wcmV2LCBhLCBiLnByZXYpIHx8IGFyZWEoYSwgYi5wcmV2LCBiKSkgfHwgLy8gZG9lcyBub3QgY3JlYXRlIG9wcG9zaXRlLWZhY2luZyBzZWN0b3JzXG4gICAgICAgICAgICBlcXVhbHMoYSwgYikgJiYgYXJlYShhLnByZXYsIGEsIGEubmV4dCkgPiAwICYmIGFyZWEoYi5wcmV2LCBiLCBiLm5leHQpID4gMCk7IC8vIHNwZWNpYWwgemVyby1sZW5ndGggY2FzZVxufVxuXG4vLyBzaWduZWQgYXJlYSBvZiBhIHRyaWFuZ2xlXG5mdW5jdGlvbiBhcmVhKHAsIHEsIHIpIHtcbiAgICByZXR1cm4gKHEueSAtIHAueSkgKiAoci54IC0gcS54KSAtIChxLnggLSBwLngpICogKHIueSAtIHEueSk7XG59XG5cbi8vIGNoZWNrIGlmIHR3byBwb2ludHMgYXJlIGVxdWFsXG5mdW5jdGlvbiBlcXVhbHMocDEsIHAyKSB7XG4gICAgcmV0dXJuIHAxLnggPT09IHAyLnggJiYgcDEueSA9PT0gcDIueTtcbn1cblxuLy8gY2hlY2sgaWYgdHdvIHNlZ21lbnRzIGludGVyc2VjdFxuZnVuY3Rpb24gaW50ZXJzZWN0cyhwMSwgcTEsIHAyLCBxMikge1xuICAgIHZhciBvMSA9IHNpZ24oYXJlYShwMSwgcTEsIHAyKSk7XG4gICAgdmFyIG8yID0gc2lnbihhcmVhKHAxLCBxMSwgcTIpKTtcbiAgICB2YXIgbzMgPSBzaWduKGFyZWEocDIsIHEyLCBwMSkpO1xuICAgIHZhciBvNCA9IHNpZ24oYXJlYShwMiwgcTIsIHExKSk7XG5cbiAgICBpZiAobzEgIT09IG8yICYmIG8zICE9PSBvNCkgcmV0dXJuIHRydWU7IC8vIGdlbmVyYWwgY2FzZVxuXG4gICAgaWYgKG8xID09PSAwICYmIG9uU2VnbWVudChwMSwgcDIsIHExKSkgcmV0dXJuIHRydWU7IC8vIHAxLCBxMSBhbmQgcDIgYXJlIGNvbGxpbmVhciBhbmQgcDIgbGllcyBvbiBwMXExXG4gICAgaWYgKG8yID09PSAwICYmIG9uU2VnbWVudChwMSwgcTIsIHExKSkgcmV0dXJuIHRydWU7IC8vIHAxLCBxMSBhbmQgcTIgYXJlIGNvbGxpbmVhciBhbmQgcTIgbGllcyBvbiBwMXExXG4gICAgaWYgKG8zID09PSAwICYmIG9uU2VnbWVudChwMiwgcDEsIHEyKSkgcmV0dXJuIHRydWU7IC8vIHAyLCBxMiBhbmQgcDEgYXJlIGNvbGxpbmVhciBhbmQgcDEgbGllcyBvbiBwMnEyXG4gICAgaWYgKG80ID09PSAwICYmIG9uU2VnbWVudChwMiwgcTEsIHEyKSkgcmV0dXJuIHRydWU7IC8vIHAyLCBxMiBhbmQgcTEgYXJlIGNvbGxpbmVhciBhbmQgcTEgbGllcyBvbiBwMnEyXG5cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbi8vIGZvciBjb2xsaW5lYXIgcG9pbnRzIHAsIHEsIHIsIGNoZWNrIGlmIHBvaW50IHEgbGllcyBvbiBzZWdtZW50IHByXG5mdW5jdGlvbiBvblNlZ21lbnQocCwgcSwgcikge1xuICAgIHJldHVybiBxLnggPD0gTWF0aC5tYXgocC54LCByLngpICYmIHEueCA+PSBNYXRoLm1pbihwLngsIHIueCkgJiYgcS55IDw9IE1hdGgubWF4KHAueSwgci55KSAmJiBxLnkgPj0gTWF0aC5taW4ocC55LCByLnkpO1xufVxuXG5mdW5jdGlvbiBzaWduKG51bSkge1xuICAgIHJldHVybiBudW0gPiAwID8gMSA6IG51bSA8IDAgPyAtMSA6IDA7XG59XG5cbi8vIGNoZWNrIGlmIGEgcG9seWdvbiBkaWFnb25hbCBpbnRlcnNlY3RzIGFueSBwb2x5Z29uIHNlZ21lbnRzXG5mdW5jdGlvbiBpbnRlcnNlY3RzUG9seWdvbihhLCBiKSB7XG4gICAgdmFyIHAgPSBhO1xuICAgIGRvIHtcbiAgICAgICAgaWYgKHAuaSAhPT0gYS5pICYmIHAubmV4dC5pICE9PSBhLmkgJiYgcC5pICE9PSBiLmkgJiYgcC5uZXh0LmkgIT09IGIuaSAmJlxuICAgICAgICAgICAgICAgIGludGVyc2VjdHMocCwgcC5uZXh0LCBhLCBiKSkgcmV0dXJuIHRydWU7XG4gICAgICAgIHAgPSBwLm5leHQ7XG4gICAgfSB3aGlsZSAocCAhPT0gYSk7XG5cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbi8vIGNoZWNrIGlmIGEgcG9seWdvbiBkaWFnb25hbCBpcyBsb2NhbGx5IGluc2lkZSB0aGUgcG9seWdvblxuZnVuY3Rpb24gbG9jYWxseUluc2lkZShhLCBiKSB7XG4gICAgcmV0dXJuIGFyZWEoYS5wcmV2LCBhLCBhLm5leHQpIDwgMCA/XG4gICAgICAgIGFyZWEoYSwgYiwgYS5uZXh0KSA+PSAwICYmIGFyZWEoYSwgYS5wcmV2LCBiKSA+PSAwIDpcbiAgICAgICAgYXJlYShhLCBiLCBhLnByZXYpIDwgMCB8fCBhcmVhKGEsIGEubmV4dCwgYikgPCAwO1xufVxuXG4vLyBjaGVjayBpZiB0aGUgbWlkZGxlIHBvaW50IG9mIGEgcG9seWdvbiBkaWFnb25hbCBpcyBpbnNpZGUgdGhlIHBvbHlnb25cbmZ1bmN0aW9uIG1pZGRsZUluc2lkZShhLCBiKSB7XG4gICAgdmFyIHAgPSBhLFxuICAgICAgICBpbnNpZGUgPSBmYWxzZSxcbiAgICAgICAgcHggPSAoYS54ICsgYi54KSAvIDIsXG4gICAgICAgIHB5ID0gKGEueSArIGIueSkgLyAyO1xuICAgIGRvIHtcbiAgICAgICAgaWYgKCgocC55ID4gcHkpICE9PSAocC5uZXh0LnkgPiBweSkpICYmIHAubmV4dC55ICE9PSBwLnkgJiZcbiAgICAgICAgICAgICAgICAocHggPCAocC5uZXh0LnggLSBwLngpICogKHB5IC0gcC55KSAvIChwLm5leHQueSAtIHAueSkgKyBwLngpKVxuICAgICAgICAgICAgaW5zaWRlID0gIWluc2lkZTtcbiAgICAgICAgcCA9IHAubmV4dDtcbiAgICB9IHdoaWxlIChwICE9PSBhKTtcblxuICAgIHJldHVybiBpbnNpZGU7XG59XG5cbi8vIGxpbmsgdHdvIHBvbHlnb24gdmVydGljZXMgd2l0aCBhIGJyaWRnZTsgaWYgdGhlIHZlcnRpY2VzIGJlbG9uZyB0byB0aGUgc2FtZSByaW5nLCBpdCBzcGxpdHMgcG9seWdvbiBpbnRvIHR3bztcbi8vIGlmIG9uZSBiZWxvbmdzIHRvIHRoZSBvdXRlciByaW5nIGFuZCBhbm90aGVyIHRvIGEgaG9sZSwgaXQgbWVyZ2VzIGl0IGludG8gYSBzaW5nbGUgcmluZ1xuZnVuY3Rpb24gc3BsaXRQb2x5Z29uKGEsIGIpIHtcbiAgICB2YXIgYTIgPSBuZXcgTm9kZShhLmksIGEueCwgYS55KSxcbiAgICAgICAgYjIgPSBuZXcgTm9kZShiLmksIGIueCwgYi55KSxcbiAgICAgICAgYW4gPSBhLm5leHQsXG4gICAgICAgIGJwID0gYi5wcmV2O1xuXG4gICAgYS5uZXh0ID0gYjtcbiAgICBiLnByZXYgPSBhO1xuXG4gICAgYTIubmV4dCA9IGFuO1xuICAgIGFuLnByZXYgPSBhMjtcblxuICAgIGIyLm5leHQgPSBhMjtcbiAgICBhMi5wcmV2ID0gYjI7XG5cbiAgICBicC5uZXh0ID0gYjI7XG4gICAgYjIucHJldiA9IGJwO1xuXG4gICAgcmV0dXJuIGIyO1xufVxuXG4vLyBjcmVhdGUgYSBub2RlIGFuZCBvcHRpb25hbGx5IGxpbmsgaXQgd2l0aCBwcmV2aW91cyBvbmUgKGluIGEgY2lyY3VsYXIgZG91Ymx5IGxpbmtlZCBsaXN0KVxuZnVuY3Rpb24gaW5zZXJ0Tm9kZShpLCB4LCB5LCBsYXN0KSB7XG4gICAgdmFyIHAgPSBuZXcgTm9kZShpLCB4LCB5KTtcblxuICAgIGlmICghbGFzdCkge1xuICAgICAgICBwLnByZXYgPSBwO1xuICAgICAgICBwLm5leHQgPSBwO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgICAgcC5uZXh0ID0gbGFzdC5uZXh0O1xuICAgICAgICBwLnByZXYgPSBsYXN0O1xuICAgICAgICBsYXN0Lm5leHQucHJldiA9IHA7XG4gICAgICAgIGxhc3QubmV4dCA9IHA7XG4gICAgfVxuICAgIHJldHVybiBwO1xufVxuXG5mdW5jdGlvbiByZW1vdmVOb2RlKHApIHtcbiAgICBwLm5leHQucHJldiA9IHAucHJldjtcbiAgICBwLnByZXYubmV4dCA9IHAubmV4dDtcblxuICAgIGlmIChwLnByZXZaKSBwLnByZXZaLm5leHRaID0gcC5uZXh0WjtcbiAgICBpZiAocC5uZXh0WikgcC5uZXh0Wi5wcmV2WiA9IHAucHJldlo7XG59XG5cbmZ1bmN0aW9uIE5vZGUoaSwgeCwgeSkge1xuICAgIC8vIHZlcnRleCBpbmRleCBpbiBjb29yZGluYXRlcyBhcnJheVxuICAgIHRoaXMuaSA9IGk7XG5cbiAgICAvLyB2ZXJ0ZXggY29vcmRpbmF0ZXNcbiAgICB0aGlzLnggPSB4O1xuICAgIHRoaXMueSA9IHk7XG5cbiAgICAvLyBwcmV2aW91cyBhbmQgbmV4dCB2ZXJ0ZXggbm9kZXMgaW4gYSBwb2x5Z29uIHJpbmdcbiAgICB0aGlzLnByZXYgPSBudWxsO1xuICAgIHRoaXMubmV4dCA9IG51bGw7XG5cbiAgICAvLyB6LW9yZGVyIGN1cnZlIHZhbHVlXG4gICAgdGhpcy56ID0gMDtcblxuICAgIC8vIHByZXZpb3VzIGFuZCBuZXh0IG5vZGVzIGluIHotb3JkZXJcbiAgICB0aGlzLnByZXZaID0gbnVsbDtcbiAgICB0aGlzLm5leHRaID0gbnVsbDtcblxuICAgIC8vIGluZGljYXRlcyB3aGV0aGVyIHRoaXMgaXMgYSBzdGVpbmVyIHBvaW50XG4gICAgdGhpcy5zdGVpbmVyID0gZmFsc2U7XG59XG5cbi8vIHJldHVybiBhIHBlcmNlbnRhZ2UgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBwb2x5Z29uIGFyZWEgYW5kIGl0cyB0cmlhbmd1bGF0aW9uIGFyZWE7XG4vLyB1c2VkIHRvIHZlcmlmeSBjb3JyZWN0bmVzcyBvZiB0cmlhbmd1bGF0aW9uXG5lYXJjdXQuZGV2aWF0aW9uID0gZnVuY3Rpb24gKGRhdGEsIGhvbGVJbmRpY2VzLCBkaW0sIHRyaWFuZ2xlcykge1xuICAgIHZhciBoYXNIb2xlcyA9IGhvbGVJbmRpY2VzICYmIGhvbGVJbmRpY2VzLmxlbmd0aDtcbiAgICB2YXIgb3V0ZXJMZW4gPSBoYXNIb2xlcyA/IGhvbGVJbmRpY2VzWzBdICogZGltIDogZGF0YS5sZW5ndGg7XG5cbiAgICB2YXIgcG9seWdvbkFyZWEgPSBNYXRoLmFicyhzaWduZWRBcmVhKGRhdGEsIDAsIG91dGVyTGVuLCBkaW0pKTtcbiAgICBpZiAoaGFzSG9sZXMpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGhvbGVJbmRpY2VzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgc3RhcnQgPSBob2xlSW5kaWNlc1tpXSAqIGRpbTtcbiAgICAgICAgICAgIHZhciBlbmQgPSBpIDwgbGVuIC0gMSA/IGhvbGVJbmRpY2VzW2kgKyAxXSAqIGRpbSA6IGRhdGEubGVuZ3RoO1xuICAgICAgICAgICAgcG9seWdvbkFyZWEgLT0gTWF0aC5hYnMoc2lnbmVkQXJlYShkYXRhLCBzdGFydCwgZW5kLCBkaW0pKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciB0cmlhbmdsZXNBcmVhID0gMDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgdHJpYW5nbGVzLmxlbmd0aDsgaSArPSAzKSB7XG4gICAgICAgIHZhciBhID0gdHJpYW5nbGVzW2ldICogZGltO1xuICAgICAgICB2YXIgYiA9IHRyaWFuZ2xlc1tpICsgMV0gKiBkaW07XG4gICAgICAgIHZhciBjID0gdHJpYW5nbGVzW2kgKyAyXSAqIGRpbTtcbiAgICAgICAgdHJpYW5nbGVzQXJlYSArPSBNYXRoLmFicyhcbiAgICAgICAgICAgIChkYXRhW2FdIC0gZGF0YVtjXSkgKiAoZGF0YVtiICsgMV0gLSBkYXRhW2EgKyAxXSkgLVxuICAgICAgICAgICAgKGRhdGFbYV0gLSBkYXRhW2JdKSAqIChkYXRhW2MgKyAxXSAtIGRhdGFbYSArIDFdKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBvbHlnb25BcmVhID09PSAwICYmIHRyaWFuZ2xlc0FyZWEgPT09IDAgPyAwIDpcbiAgICAgICAgTWF0aC5hYnMoKHRyaWFuZ2xlc0FyZWEgLSBwb2x5Z29uQXJlYSkgLyBwb2x5Z29uQXJlYSk7XG59O1xuXG5mdW5jdGlvbiBzaWduZWRBcmVhKGRhdGEsIHN0YXJ0LCBlbmQsIGRpbSkge1xuICAgIHZhciBzdW0gPSAwO1xuICAgIGZvciAodmFyIGkgPSBzdGFydCwgaiA9IGVuZCAtIGRpbTsgaSA8IGVuZDsgaSArPSBkaW0pIHtcbiAgICAgICAgc3VtICs9IChkYXRhW2pdIC0gZGF0YVtpXSkgKiAoZGF0YVtpICsgMV0gKyBkYXRhW2ogKyAxXSk7XG4gICAgICAgIGogPSBpO1xuICAgIH1cbiAgICByZXR1cm4gc3VtO1xufVxuXG4vLyB0dXJuIGEgcG9seWdvbiBpbiBhIG11bHRpLWRpbWVuc2lvbmFsIGFycmF5IGZvcm0gKGUuZy4gYXMgaW4gR2VvSlNPTikgaW50byBhIGZvcm0gRWFyY3V0IGFjY2VwdHNcbmVhcmN1dC5mbGF0dGVuID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgICB2YXIgZGltID0gZGF0YVswXVswXS5sZW5ndGgsXG4gICAgICAgIHJlc3VsdCA9IHt2ZXJ0aWNlczogW10sIGhvbGVzOiBbXSwgZGltZW5zaW9uczogZGltfSxcbiAgICAgICAgaG9sZUluZGV4ID0gMDtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGRhdGFbaV0ubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIGZvciAodmFyIGQgPSAwOyBkIDwgZGltOyBkKyspIHJlc3VsdC52ZXJ0aWNlcy5wdXNoKGRhdGFbaV1bal1bZF0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpID4gMCkge1xuICAgICAgICAgICAgaG9sZUluZGV4ICs9IGRhdGFbaSAtIDFdLmxlbmd0aDtcbiAgICAgICAgICAgIHJlc3VsdC5ob2xlcy5wdXNoKGhvbGVJbmRleCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn07XG4iLCJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHF1aWNrc2VsZWN0KGFyciwgaywgbGVmdCwgcmlnaHQsIGNvbXBhcmUpIHtcbiAgICBxdWlja3NlbGVjdFN0ZXAoYXJyLCBrLCBsZWZ0IHx8IDAsIHJpZ2h0IHx8IChhcnIubGVuZ3RoIC0gMSksIGNvbXBhcmUgfHwgZGVmYXVsdENvbXBhcmUpO1xufVxuXG5mdW5jdGlvbiBxdWlja3NlbGVjdFN0ZXAoYXJyLCBrLCBsZWZ0LCByaWdodCwgY29tcGFyZSkge1xuXG4gICAgd2hpbGUgKHJpZ2h0ID4gbGVmdCkge1xuICAgICAgICBpZiAocmlnaHQgLSBsZWZ0ID4gNjAwKSB7XG4gICAgICAgICAgICB2YXIgbiA9IHJpZ2h0IC0gbGVmdCArIDE7XG4gICAgICAgICAgICB2YXIgbSA9IGsgLSBsZWZ0ICsgMTtcbiAgICAgICAgICAgIHZhciB6ID0gTWF0aC5sb2cobik7XG4gICAgICAgICAgICB2YXIgcyA9IDAuNSAqIE1hdGguZXhwKDIgKiB6IC8gMyk7XG4gICAgICAgICAgICB2YXIgc2QgPSAwLjUgKiBNYXRoLnNxcnQoeiAqIHMgKiAobiAtIHMpIC8gbikgKiAobSAtIG4gLyAyIDwgMCA/IC0xIDogMSk7XG4gICAgICAgICAgICB2YXIgbmV3TGVmdCA9IE1hdGgubWF4KGxlZnQsIE1hdGguZmxvb3IoayAtIG0gKiBzIC8gbiArIHNkKSk7XG4gICAgICAgICAgICB2YXIgbmV3UmlnaHQgPSBNYXRoLm1pbihyaWdodCwgTWF0aC5mbG9vcihrICsgKG4gLSBtKSAqIHMgLyBuICsgc2QpKTtcbiAgICAgICAgICAgIHF1aWNrc2VsZWN0U3RlcChhcnIsIGssIG5ld0xlZnQsIG5ld1JpZ2h0LCBjb21wYXJlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciB0ID0gYXJyW2tdO1xuICAgICAgICB2YXIgaSA9IGxlZnQ7XG4gICAgICAgIHZhciBqID0gcmlnaHQ7XG5cbiAgICAgICAgc3dhcChhcnIsIGxlZnQsIGspO1xuICAgICAgICBpZiAoY29tcGFyZShhcnJbcmlnaHRdLCB0KSA+IDApIHN3YXAoYXJyLCBsZWZ0LCByaWdodCk7XG5cbiAgICAgICAgd2hpbGUgKGkgPCBqKSB7XG4gICAgICAgICAgICBzd2FwKGFyciwgaSwgaik7XG4gICAgICAgICAgICBpKys7XG4gICAgICAgICAgICBqLS07XG4gICAgICAgICAgICB3aGlsZSAoY29tcGFyZShhcnJbaV0sIHQpIDwgMCkgaSsrO1xuICAgICAgICAgICAgd2hpbGUgKGNvbXBhcmUoYXJyW2pdLCB0KSA+IDApIGotLTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb21wYXJlKGFycltsZWZ0XSwgdCkgPT09IDApIHN3YXAoYXJyLCBsZWZ0LCBqKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBqKys7XG4gICAgICAgICAgICBzd2FwKGFyciwgaiwgcmlnaHQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGogPD0gaykgbGVmdCA9IGogKyAxO1xuICAgICAgICBpZiAoayA8PSBqKSByaWdodCA9IGogLSAxO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gc3dhcChhcnIsIGksIGopIHtcbiAgICB2YXIgdG1wID0gYXJyW2ldO1xuICAgIGFycltpXSA9IGFycltqXTtcbiAgICBhcnJbal0gPSB0bXA7XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRDb21wYXJlKGEsIGIpIHtcbiAgICByZXR1cm4gYSA8IGIgPyAtMSA6IGEgPiBiID8gMSA6IDA7XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgcXVpY2tzZWxlY3QgZnJvbSAncXVpY2tzZWxlY3QnO1xuXG5pbXBvcnQge2NhbGN1bGF0ZVNpZ25lZEFyZWF9IGZyb20gJy4vdXRpbC5qcyc7XG5cbmltcG9ydCB0eXBlIFBvaW50IGZyb20gJ0BtYXBib3gvcG9pbnQtZ2VvbWV0cnknO1xuXG4vLyBjbGFzc2lmaWVzIGFuIGFycmF5IG9mIHJpbmdzIGludG8gcG9seWdvbnMgd2l0aCBvdXRlciByaW5ncyBhbmQgaG9sZXNcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGNsYXNzaWZ5UmluZ3MocmluZ3M6IEFycmF5PEFycmF5PFBvaW50Pj4sIG1heFJpbmdzOiBudW1iZXIpOiBBcnJheTxBcnJheTxBcnJheTxQb2ludD4+PiB7XG4gICAgY29uc3QgbGVuID0gcmluZ3MubGVuZ3RoO1xuXG4gICAgaWYgKGxlbiA8PSAxKSByZXR1cm4gW3JpbmdzXTtcblxuICAgIGNvbnN0IHBvbHlnb25zID0gW107XG4gICAgbGV0IHBvbHlnb24sXG4gICAgICAgIGNjdztcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgY29uc3QgYXJlYSA9IGNhbGN1bGF0ZVNpZ25lZEFyZWEocmluZ3NbaV0pO1xuICAgICAgICBpZiAoYXJlYSA9PT0gMCkgY29udGludWU7XG5cbiAgICAgICAgKHJpbmdzW2ldOiBhbnkpLmFyZWEgPSBNYXRoLmFicyhhcmVhKTtcblxuICAgICAgICBpZiAoY2N3ID09PSB1bmRlZmluZWQpIGNjdyA9IGFyZWEgPCAwO1xuXG4gICAgICAgIGlmIChjY3cgPT09IGFyZWEgPCAwKSB7XG4gICAgICAgICAgICBpZiAocG9seWdvbikgcG9seWdvbnMucHVzaChwb2x5Z29uKTtcbiAgICAgICAgICAgIHBvbHlnb24gPSBbcmluZ3NbaV1dO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAocG9seWdvbjogYW55KS5wdXNoKHJpbmdzW2ldKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAocG9seWdvbikgcG9seWdvbnMucHVzaChwb2x5Z29uKTtcblxuICAgIC8vIEVhcmN1dCBwZXJmb3JtYW5jZSBkZWdyYWRlcyB3aXRoIHRoZSAjIG9mIHJpbmdzIGluIGEgcG9seWdvbi4gRm9yIHRoaXNcbiAgICAvLyByZWFzb24sIHdlIGxpbWl0IHN0cmlwIG91dCBhbGwgYnV0IHRoZSBgbWF4UmluZ3NgIGxhcmdlc3QgcmluZ3MuXG4gICAgaWYgKG1heFJpbmdzID4gMSkge1xuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHBvbHlnb25zLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICBpZiAocG9seWdvbnNbal0ubGVuZ3RoIDw9IG1heFJpbmdzKSBjb250aW51ZTtcbiAgICAgICAgICAgIHF1aWNrc2VsZWN0KHBvbHlnb25zW2pdLCBtYXhSaW5ncywgMSwgcG9seWdvbnNbal0ubGVuZ3RoIC0gMSwgY29tcGFyZUFyZWFzKTtcbiAgICAgICAgICAgIHBvbHlnb25zW2pdID0gcG9seWdvbnNbal0uc2xpY2UoMCwgbWF4UmluZ3MpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHBvbHlnb25zO1xufVxuXG5mdW5jdGlvbiBjb21wYXJlQXJlYXMoYToge2FyZWE6IG51bWJlcn0sIGI6IHthcmVhOiBudW1iZXJ9KSB7XG4gICAgcmV0dXJuIGIuYXJlYSAtIGEuYXJlYTtcbn1cbiIsIi8vIEBmbG93XG5pbXBvcnQgdHlwZSBGaWxsU3R5bGVMYXllciBmcm9tICcuLi8uLi9zdHlsZS9zdHlsZV9sYXllci9maWxsX3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCB0eXBlIEZpbGxFeHRydXNpb25TdHlsZUxheWVyIGZyb20gJy4uLy4uL3N0eWxlL3N0eWxlX2xheWVyL2ZpbGxfZXh0cnVzaW9uX3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCB0eXBlIExpbmVTdHlsZUxheWVyIGZyb20gJy4uLy4uL3N0eWxlL3N0eWxlX2xheWVyL2xpbmVfc3R5bGVfbGF5ZXIuanMnO1xuXG5pbXBvcnQgdHlwZSB7XG4gICAgQnVja2V0RmVhdHVyZSxcbiAgICBQb3B1bGF0ZVBhcmFtZXRlcnNcbn0gZnJvbSAnLi4vYnVja2V0LmpzJztcblxudHlwZSBQYXR0ZXJuU3R5bGVMYXllcnMgPVxuICAgIEFycmF5PExpbmVTdHlsZUxheWVyPiB8XG4gICAgQXJyYXk8RmlsbFN0eWxlTGF5ZXI+IHxcbiAgICBBcnJheTxGaWxsRXh0cnVzaW9uU3R5bGVMYXllcj47XG5cbmV4cG9ydCBmdW5jdGlvbiBoYXNQYXR0ZXJuKHR5cGU6IHN0cmluZywgbGF5ZXJzOiBQYXR0ZXJuU3R5bGVMYXllcnMsIG9wdGlvbnM6IFBvcHVsYXRlUGFyYW1ldGVycyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHBhdHRlcm5zID0gb3B0aW9ucy5wYXR0ZXJuRGVwZW5kZW5jaWVzO1xuICAgIGxldCBoYXNQYXR0ZXJuID0gZmFsc2U7XG5cbiAgICBmb3IgKGNvbnN0IGxheWVyIG9mIGxheWVycykge1xuICAgICAgICBjb25zdCBwYXR0ZXJuUHJvcGVydHkgPSBsYXllci5wYWludC5nZXQoYCR7dHlwZX0tcGF0dGVybmApO1xuICAgICAgICBpZiAoIXBhdHRlcm5Qcm9wZXJ0eS5pc0NvbnN0YW50KCkpIHtcbiAgICAgICAgICAgIGhhc1BhdHRlcm4gPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY29uc3RhbnRQYXR0ZXJuID0gcGF0dGVyblByb3BlcnR5LmNvbnN0YW50T3IobnVsbCk7XG4gICAgICAgIGlmIChjb25zdGFudFBhdHRlcm4pIHtcbiAgICAgICAgICAgIGhhc1BhdHRlcm4gPSB0cnVlO1xuICAgICAgICAgICAgcGF0dGVybnNbY29uc3RhbnRQYXR0ZXJuXSA9ICB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGhhc1BhdHRlcm47XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRQYXR0ZXJuRGVwZW5kZW5jaWVzKHR5cGU6IHN0cmluZywgbGF5ZXJzOiBQYXR0ZXJuU3R5bGVMYXllcnMsIHBhdHRlcm5GZWF0dXJlOiBCdWNrZXRGZWF0dXJlLCB6b29tOiBudW1iZXIsIG9wdGlvbnM6IFBvcHVsYXRlUGFyYW1ldGVycyk6IEJ1Y2tldEZlYXR1cmUge1xuICAgIGNvbnN0IHBhdHRlcm5zID0gb3B0aW9ucy5wYXR0ZXJuRGVwZW5kZW5jaWVzO1xuICAgIGZvciAoY29uc3QgbGF5ZXIgb2YgbGF5ZXJzKSB7XG4gICAgICAgIGNvbnN0IHBhdHRlcm5Qcm9wZXJ0eSA9IGxheWVyLnBhaW50LmdldChgJHt0eXBlfS1wYXR0ZXJuYCk7XG5cbiAgICAgICAgY29uc3QgcGF0dGVyblByb3BlcnR5VmFsdWUgPSBwYXR0ZXJuUHJvcGVydHkudmFsdWU7XG4gICAgICAgIGlmIChwYXR0ZXJuUHJvcGVydHlWYWx1ZS5raW5kICE9PSBcImNvbnN0YW50XCIpIHtcbiAgICAgICAgICAgIGxldCBwYXR0ZXJuID0gcGF0dGVyblByb3BlcnR5VmFsdWUuZXZhbHVhdGUoe3pvb219LCBwYXR0ZXJuRmVhdHVyZSwge30sIG9wdGlvbnMuYXZhaWxhYmxlSW1hZ2VzKTtcbiAgICAgICAgICAgIHBhdHRlcm4gPSBwYXR0ZXJuICYmIHBhdHRlcm4ubmFtZSA/IHBhdHRlcm4ubmFtZSA6IHBhdHRlcm47XG5cbiAgICAgICAgICAgIC8vIGFkZCB0byBwYXR0ZXJuRGVwZW5kZW5jaWVzXG4gICAgICAgICAgICBwYXR0ZXJuc1twYXR0ZXJuXSA9IHRydWU7XG5cbiAgICAgICAgICAgIC8vIHNhdmUgZm9yIGxheW91dFxuICAgICAgICAgICAgcGF0dGVybkZlYXR1cmUucGF0dGVybnNbbGF5ZXIuaWRdID0gcGF0dGVybjtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcGF0dGVybkZlYXR1cmU7XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge0ZpbGxMYXlvdXRBcnJheX0gZnJvbSAnLi4vYXJyYXlfdHlwZXMuanMnO1xuXG5pbXBvcnQge21lbWJlcnMgYXMgbGF5b3V0QXR0cmlidXRlc30gZnJvbSAnLi9maWxsX2F0dHJpYnV0ZXMuanMnO1xuaW1wb3J0IFNlZ21lbnRWZWN0b3IgZnJvbSAnLi4vc2VnbWVudC5qcyc7XG5pbXBvcnQge1Byb2dyYW1Db25maWd1cmF0aW9uU2V0fSBmcm9tICcuLi9wcm9ncmFtX2NvbmZpZ3VyYXRpb24uanMnO1xuaW1wb3J0IHtMaW5lSW5kZXhBcnJheSwgVHJpYW5nbGVJbmRleEFycmF5fSBmcm9tICcuLi9pbmRleF9hcnJheV90eXBlLmpzJztcbmltcG9ydCBlYXJjdXQgZnJvbSAnZWFyY3V0JztcbmltcG9ydCBjbGFzc2lmeVJpbmdzIGZyb20gJy4uLy4uL3V0aWwvY2xhc3NpZnlfcmluZ3MuanMnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuY29uc3QgRUFSQ1VUX01BWF9SSU5HUyA9IDUwMDtcbmltcG9ydCB7cmVnaXN0ZXJ9IGZyb20gJy4uLy4uL3V0aWwvd2ViX3dvcmtlcl90cmFuc2Zlci5qcyc7XG5pbXBvcnQge2hhc1BhdHRlcm4sIGFkZFBhdHRlcm5EZXBlbmRlbmNpZXN9IGZyb20gJy4vcGF0dGVybl9idWNrZXRfZmVhdHVyZXMuanMnO1xuaW1wb3J0IGxvYWRHZW9tZXRyeSBmcm9tICcuLi9sb2FkX2dlb21ldHJ5LmpzJztcbmltcG9ydCB0b0V2YWx1YXRpb25GZWF0dXJlIGZyb20gJy4uL2V2YWx1YXRpb25fZmVhdHVyZS5qcyc7XG5pbXBvcnQgRXZhbHVhdGlvblBhcmFtZXRlcnMgZnJvbSAnLi4vLi4vc3R5bGUvZXZhbHVhdGlvbl9wYXJhbWV0ZXJzLmpzJztcblxuaW1wb3J0IHR5cGUge0Nhbm9uaWNhbFRpbGVJRH0gZnJvbSAnLi4vLi4vc291cmNlL3RpbGVfaWQuanMnO1xuaW1wb3J0IHR5cGUge1xuICAgIEJ1Y2tldCxcbiAgICBCdWNrZXRQYXJhbWV0ZXJzLFxuICAgIEJ1Y2tldEZlYXR1cmUsXG4gICAgSW5kZXhlZEZlYXR1cmUsXG4gICAgUG9wdWxhdGVQYXJhbWV0ZXJzXG59IGZyb20gJy4uL2J1Y2tldC5qcyc7XG5pbXBvcnQgdHlwZSBGaWxsU3R5bGVMYXllciBmcm9tICcuLi8uLi9zdHlsZS9zdHlsZV9sYXllci9maWxsX3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCB0eXBlIENvbnRleHQgZnJvbSAnLi4vLi4vZ2wvY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSBJbmRleEJ1ZmZlciBmcm9tICcuLi8uLi9nbC9pbmRleF9idWZmZXIuanMnO1xuaW1wb3J0IHR5cGUgVmVydGV4QnVmZmVyIGZyb20gJy4uLy4uL2dsL3ZlcnRleF9idWZmZXIuanMnO1xuaW1wb3J0IHR5cGUgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5pbXBvcnQgdHlwZSB7RmVhdHVyZVN0YXRlc30gZnJvbSAnLi4vLi4vc291cmNlL3NvdXJjZV9zdGF0ZS5qcyc7XG5pbXBvcnQgdHlwZSB7U3ByaXRlUG9zaXRpb25zfSBmcm9tICcuLi8uLi91dGlsL2ltYWdlLmpzJztcbmltcG9ydCB0eXBlIHtQcm9qZWN0aW9uU3BlY2lmaWNhdGlvbn0gZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy90eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSB7VGlsZVRyYW5zZm9ybX0gZnJvbSAnLi4vLi4vZ2VvL3Byb2plY3Rpb24vdGlsZV90cmFuc2Zvcm0uanMnO1xuaW1wb3J0IHR5cGUge0lWZWN0b3JUaWxlTGF5ZXJ9IGZyb20gJ0BtYXBib3gvdmVjdG9yLXRpbGUnO1xuXG5jbGFzcyBGaWxsQnVja2V0IGltcGxlbWVudHMgQnVja2V0IHtcbiAgICBpbmRleDogbnVtYmVyO1xuICAgIHpvb206IG51bWJlcjtcbiAgICBvdmVyc2NhbGluZzogbnVtYmVyO1xuICAgIGxheWVyczogQXJyYXk8RmlsbFN0eWxlTGF5ZXI+O1xuICAgIGxheWVySWRzOiBBcnJheTxzdHJpbmc+O1xuICAgIHN0YXRlRGVwZW5kZW50TGF5ZXJzOiBBcnJheTxGaWxsU3R5bGVMYXllcj47XG4gICAgc3RhdGVEZXBlbmRlbnRMYXllcklkczogQXJyYXk8c3RyaW5nPjtcbiAgICBwYXR0ZXJuRmVhdHVyZXM6IEFycmF5PEJ1Y2tldEZlYXR1cmU+O1xuXG4gICAgbGF5b3V0VmVydGV4QXJyYXk6IEZpbGxMYXlvdXRBcnJheTtcbiAgICBsYXlvdXRWZXJ0ZXhCdWZmZXI6IFZlcnRleEJ1ZmZlcjtcblxuICAgIGluZGV4QXJyYXk6IFRyaWFuZ2xlSW5kZXhBcnJheTtcbiAgICBpbmRleEJ1ZmZlcjogSW5kZXhCdWZmZXI7XG5cbiAgICBpbmRleEFycmF5MjogTGluZUluZGV4QXJyYXk7XG4gICAgaW5kZXhCdWZmZXIyOiBJbmRleEJ1ZmZlcjtcblxuICAgIGhhc1BhdHRlcm46IGJvb2xlYW47XG4gICAgcHJvZ3JhbUNvbmZpZ3VyYXRpb25zOiBQcm9ncmFtQ29uZmlndXJhdGlvblNldDxGaWxsU3R5bGVMYXllcj47XG4gICAgc2VnbWVudHM6IFNlZ21lbnRWZWN0b3I7XG4gICAgc2VnbWVudHMyOiBTZWdtZW50VmVjdG9yO1xuICAgIHVwbG9hZGVkOiBib29sZWFuO1xuICAgIHByb2plY3Rpb246IFByb2plY3Rpb25TcGVjaWZpY2F0aW9uO1xuXG4gICAgY29uc3RydWN0b3Iob3B0aW9uczogQnVja2V0UGFyYW1ldGVyczxGaWxsU3R5bGVMYXllcj4pIHtcbiAgICAgICAgdGhpcy56b29tID0gb3B0aW9ucy56b29tO1xuICAgICAgICB0aGlzLm92ZXJzY2FsaW5nID0gb3B0aW9ucy5vdmVyc2NhbGluZztcbiAgICAgICAgdGhpcy5sYXllcnMgPSBvcHRpb25zLmxheWVycztcbiAgICAgICAgdGhpcy5sYXllcklkcyA9IHRoaXMubGF5ZXJzLm1hcChsYXllciA9PiBsYXllci5pZCk7XG4gICAgICAgIHRoaXMuaW5kZXggPSBvcHRpb25zLmluZGV4O1xuICAgICAgICB0aGlzLmhhc1BhdHRlcm4gPSBmYWxzZTtcbiAgICAgICAgdGhpcy5wYXR0ZXJuRmVhdHVyZXMgPSBbXTtcblxuICAgICAgICB0aGlzLmxheW91dFZlcnRleEFycmF5ID0gbmV3IEZpbGxMYXlvdXRBcnJheSgpO1xuICAgICAgICB0aGlzLmluZGV4QXJyYXkgPSBuZXcgVHJpYW5nbGVJbmRleEFycmF5KCk7XG4gICAgICAgIHRoaXMuaW5kZXhBcnJheTIgPSBuZXcgTGluZUluZGV4QXJyYXkoKTtcbiAgICAgICAgdGhpcy5wcm9ncmFtQ29uZmlndXJhdGlvbnMgPSBuZXcgUHJvZ3JhbUNvbmZpZ3VyYXRpb25TZXQob3B0aW9ucy5sYXllcnMsIG9wdGlvbnMuem9vbSk7XG4gICAgICAgIHRoaXMuc2VnbWVudHMgPSBuZXcgU2VnbWVudFZlY3RvcigpO1xuICAgICAgICB0aGlzLnNlZ21lbnRzMiA9IG5ldyBTZWdtZW50VmVjdG9yKCk7XG4gICAgICAgIHRoaXMuc3RhdGVEZXBlbmRlbnRMYXllcklkcyA9IHRoaXMubGF5ZXJzLmZpbHRlcigobCkgPT4gbC5pc1N0YXRlRGVwZW5kZW50KCkpLm1hcCgobCkgPT4gbC5pZCk7XG4gICAgICAgIHRoaXMucHJvamVjdGlvbiA9IG9wdGlvbnMucHJvamVjdGlvbjtcbiAgICB9XG5cbiAgICBwb3B1bGF0ZShmZWF0dXJlczogQXJyYXk8SW5kZXhlZEZlYXR1cmU+LCBvcHRpb25zOiBQb3B1bGF0ZVBhcmFtZXRlcnMsIGNhbm9uaWNhbDogQ2Fub25pY2FsVGlsZUlELCB0aWxlVHJhbnNmb3JtOiBUaWxlVHJhbnNmb3JtKSB7XG4gICAgICAgIHRoaXMuaGFzUGF0dGVybiA9IGhhc1BhdHRlcm4oJ2ZpbGwnLCB0aGlzLmxheWVycywgb3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGZpbGxTb3J0S2V5ID0gdGhpcy5sYXllcnNbMF0ubGF5b3V0LmdldCgnZmlsbC1zb3J0LWtleScpO1xuICAgICAgICBjb25zdCBidWNrZXRGZWF0dXJlcyA9IFtdO1xuXG4gICAgICAgIGZvciAoY29uc3Qge2ZlYXR1cmUsIGlkLCBpbmRleCwgc291cmNlTGF5ZXJJbmRleH0gb2YgZmVhdHVyZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5lZWRHZW9tZXRyeSA9IHRoaXMubGF5ZXJzWzBdLl9mZWF0dXJlRmlsdGVyLm5lZWRHZW9tZXRyeTtcbiAgICAgICAgICAgIGNvbnN0IGV2YWx1YXRpb25GZWF0dXJlID0gdG9FdmFsdWF0aW9uRmVhdHVyZShmZWF0dXJlLCBuZWVkR2VvbWV0cnkpO1xuXG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICBpZiAoIXRoaXMubGF5ZXJzWzBdLl9mZWF0dXJlRmlsdGVyLmZpbHRlcihuZXcgRXZhbHVhdGlvblBhcmFtZXRlcnModGhpcy56b29tKSwgZXZhbHVhdGlvbkZlYXR1cmUsIGNhbm9uaWNhbCkpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICBjb25zdCBzb3J0S2V5ID0gZmlsbFNvcnRLZXkgP1xuICAgICAgICAgICAgICAgIGZpbGxTb3J0S2V5LmV2YWx1YXRlKGV2YWx1YXRpb25GZWF0dXJlLCB7fSwgY2Fub25pY2FsLCBvcHRpb25zLmF2YWlsYWJsZUltYWdlcykgOlxuICAgICAgICAgICAgICAgIHVuZGVmaW5lZDtcblxuICAgICAgICAgICAgY29uc3QgYnVja2V0RmVhdHVyZTogQnVja2V0RmVhdHVyZSA9IHtcbiAgICAgICAgICAgICAgICBpZCxcbiAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiBmZWF0dXJlLnByb3BlcnRpZXMsXG4gICAgICAgICAgICAgICAgdHlwZTogZmVhdHVyZS50eXBlLFxuICAgICAgICAgICAgICAgIHNvdXJjZUxheWVySW5kZXgsXG4gICAgICAgICAgICAgICAgaW5kZXgsXG4gICAgICAgICAgICAgICAgZ2VvbWV0cnk6IG5lZWRHZW9tZXRyeSA/IGV2YWx1YXRpb25GZWF0dXJlLmdlb21ldHJ5IDogbG9hZEdlb21ldHJ5KGZlYXR1cmUsIGNhbm9uaWNhbCwgdGlsZVRyYW5zZm9ybSksXG4gICAgICAgICAgICAgICAgcGF0dGVybnM6IHt9LFxuICAgICAgICAgICAgICAgIHNvcnRLZXlcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGJ1Y2tldEZlYXR1cmVzLnB1c2goYnVja2V0RmVhdHVyZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZmlsbFNvcnRLZXkpIHtcbiAgICAgICAgICAgIGJ1Y2tldEZlYXR1cmVzLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBhLnNvcnRLZXkgaXMgYWx3YXlzIGEgbnVtYmVyIHdoZW4gaW4gdXNlXG4gICAgICAgICAgICAgICAgcmV0dXJuICgoYS5zb3J0S2V5OiBhbnkpOiBudW1iZXIpIC0gKChiLnNvcnRLZXk6IGFueSk6IG51bWJlcik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoY29uc3QgYnVja2V0RmVhdHVyZSBvZiBidWNrZXRGZWF0dXJlcykge1xuICAgICAgICAgICAgY29uc3Qge2dlb21ldHJ5LCBpbmRleCwgc291cmNlTGF5ZXJJbmRleH0gPSBidWNrZXRGZWF0dXJlO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5oYXNQYXR0ZXJuKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGF0dGVybkZlYXR1cmUgPSBhZGRQYXR0ZXJuRGVwZW5kZW5jaWVzKCdmaWxsJywgdGhpcy5sYXllcnMsIGJ1Y2tldEZlYXR1cmUsIHRoaXMuem9vbSwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgLy8gcGF0dGVybiBmZWF0dXJlcyBhcmUgYWRkZWQgb25seSBvbmNlIHRoZSBwYXR0ZXJuIGlzIGxvYWRlZCBpbnRvIHRoZSBpbWFnZSBhdGxhc1xuICAgICAgICAgICAgICAgIC8vIHNvIGFyZSBzdG9yZWQgZHVyaW5nIHBvcHVsYXRlIHVudGlsIGxhdGVyIHVwZGF0ZWQgd2l0aCBwb3NpdGlvbnMgYnkgdGlsZSB3b3JrZXIgaW4gYWRkRmVhdHVyZXNcbiAgICAgICAgICAgICAgICB0aGlzLnBhdHRlcm5GZWF0dXJlcy5wdXNoKHBhdHRlcm5GZWF0dXJlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRGZWF0dXJlKGJ1Y2tldEZlYXR1cmUsIGdlb21ldHJ5LCBpbmRleCwgY2Fub25pY2FsLCB7fSwgb3B0aW9ucy5hdmFpbGFibGVJbWFnZXMpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBmZWF0dXJlID0gZmVhdHVyZXNbaW5kZXhdLmZlYXR1cmU7XG4gICAgICAgICAgICBvcHRpb25zLmZlYXR1cmVJbmRleC5pbnNlcnQoZmVhdHVyZSwgZ2VvbWV0cnksIGluZGV4LCBzb3VyY2VMYXllckluZGV4LCB0aGlzLmluZGV4KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHVwZGF0ZShzdGF0ZXM6IEZlYXR1cmVTdGF0ZXMsIHZ0TGF5ZXI6IElWZWN0b3JUaWxlTGF5ZXIsIGF2YWlsYWJsZUltYWdlczogQXJyYXk8c3RyaW5nPiwgaW1hZ2VQb3NpdGlvbnM6IFNwcml0ZVBvc2l0aW9ucykge1xuICAgICAgICBpZiAoIXRoaXMuc3RhdGVEZXBlbmRlbnRMYXllcnMubGVuZ3RoKSByZXR1cm47XG4gICAgICAgIHRoaXMucHJvZ3JhbUNvbmZpZ3VyYXRpb25zLnVwZGF0ZVBhaW50QXJyYXlzKHN0YXRlcywgdnRMYXllciwgdGhpcy5zdGF0ZURlcGVuZGVudExheWVycywgYXZhaWxhYmxlSW1hZ2VzLCBpbWFnZVBvc2l0aW9ucyk7XG4gICAgfVxuXG4gICAgYWRkRmVhdHVyZXMob3B0aW9uczogUG9wdWxhdGVQYXJhbWV0ZXJzLCBjYW5vbmljYWw6IENhbm9uaWNhbFRpbGVJRCwgaW1hZ2VQb3NpdGlvbnM6IFNwcml0ZVBvc2l0aW9ucywgYXZhaWxhYmxlSW1hZ2VzOiBBcnJheTxzdHJpbmc+LCBfOiBUaWxlVHJhbnNmb3JtKSB7XG4gICAgICAgIGZvciAoY29uc3QgZmVhdHVyZSBvZiB0aGlzLnBhdHRlcm5GZWF0dXJlcykge1xuICAgICAgICAgICAgdGhpcy5hZGRGZWF0dXJlKGZlYXR1cmUsIGZlYXR1cmUuZ2VvbWV0cnksIGZlYXR1cmUuaW5kZXgsIGNhbm9uaWNhbCwgaW1hZ2VQb3NpdGlvbnMsIGF2YWlsYWJsZUltYWdlcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpc0VtcHR5KCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5sYXlvdXRWZXJ0ZXhBcnJheS5sZW5ndGggPT09IDA7XG4gICAgfVxuXG4gICAgdXBsb2FkUGVuZGluZygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICF0aGlzLnVwbG9hZGVkIHx8IHRoaXMucHJvZ3JhbUNvbmZpZ3VyYXRpb25zLm5lZWRzVXBsb2FkO1xuICAgIH1cbiAgICB1cGxvYWQoY29udGV4dDogQ29udGV4dCkge1xuICAgICAgICBpZiAoIXRoaXMudXBsb2FkZWQpIHtcbiAgICAgICAgICAgIHRoaXMubGF5b3V0VmVydGV4QnVmZmVyID0gY29udGV4dC5jcmVhdGVWZXJ0ZXhCdWZmZXIodGhpcy5sYXlvdXRWZXJ0ZXhBcnJheSwgbGF5b3V0QXR0cmlidXRlcyk7XG4gICAgICAgICAgICB0aGlzLmluZGV4QnVmZmVyID0gY29udGV4dC5jcmVhdGVJbmRleEJ1ZmZlcih0aGlzLmluZGV4QXJyYXkpO1xuICAgICAgICAgICAgdGhpcy5pbmRleEJ1ZmZlcjIgPSBjb250ZXh0LmNyZWF0ZUluZGV4QnVmZmVyKHRoaXMuaW5kZXhBcnJheTIpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucHJvZ3JhbUNvbmZpZ3VyYXRpb25zLnVwbG9hZChjb250ZXh0KTtcbiAgICAgICAgdGhpcy51cGxvYWRlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmxheW91dFZlcnRleEJ1ZmZlcikgcmV0dXJuO1xuICAgICAgICB0aGlzLmxheW91dFZlcnRleEJ1ZmZlci5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMuaW5kZXhCdWZmZXIuZGVzdHJveSgpO1xuICAgICAgICB0aGlzLmluZGV4QnVmZmVyMi5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMucHJvZ3JhbUNvbmZpZ3VyYXRpb25zLmRlc3Ryb3koKTtcbiAgICAgICAgdGhpcy5zZWdtZW50cy5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMuc2VnbWVudHMyLmRlc3Ryb3koKTtcbiAgICB9XG5cbiAgICBhZGRGZWF0dXJlKGZlYXR1cmU6IEJ1Y2tldEZlYXR1cmUsIGdlb21ldHJ5OiBBcnJheTxBcnJheTxQb2ludD4+LCBpbmRleDogbnVtYmVyLCBjYW5vbmljYWw6IENhbm9uaWNhbFRpbGVJRCwgaW1hZ2VQb3NpdGlvbnM6IFNwcml0ZVBvc2l0aW9ucywgYXZhaWxhYmxlSW1hZ2VzOiBBcnJheTxzdHJpbmc+ID0gW10pIHtcbiAgICAgICAgZm9yIChjb25zdCBwb2x5Z29uIG9mIGNsYXNzaWZ5UmluZ3MoZ2VvbWV0cnksIEVBUkNVVF9NQVhfUklOR1MpKSB7XG4gICAgICAgICAgICBsZXQgbnVtVmVydGljZXMgPSAwO1xuICAgICAgICAgICAgZm9yIChjb25zdCByaW5nIG9mIHBvbHlnb24pIHtcbiAgICAgICAgICAgICAgICBudW1WZXJ0aWNlcyArPSByaW5nLmxlbmd0aDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgdHJpYW5nbGVTZWdtZW50ID0gdGhpcy5zZWdtZW50cy5wcmVwYXJlU2VnbWVudChudW1WZXJ0aWNlcywgdGhpcy5sYXlvdXRWZXJ0ZXhBcnJheSwgdGhpcy5pbmRleEFycmF5KTtcbiAgICAgICAgICAgIGNvbnN0IHRyaWFuZ2xlSW5kZXggPSB0cmlhbmdsZVNlZ21lbnQudmVydGV4TGVuZ3RoO1xuXG4gICAgICAgICAgICBjb25zdCBmbGF0dGVuZWQgPSBbXTtcbiAgICAgICAgICAgIGNvbnN0IGhvbGVJbmRpY2VzID0gW107XG5cbiAgICAgICAgICAgIGZvciAoY29uc3QgcmluZyBvZiBwb2x5Z29uKSB7XG4gICAgICAgICAgICAgICAgaWYgKHJpbmcubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChyaW5nICE9PSBwb2x5Z29uWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGhvbGVJbmRpY2VzLnB1c2goZmxhdHRlbmVkLmxlbmd0aCAvIDIpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IGxpbmVTZWdtZW50ID0gdGhpcy5zZWdtZW50czIucHJlcGFyZVNlZ21lbnQocmluZy5sZW5ndGgsIHRoaXMubGF5b3V0VmVydGV4QXJyYXksIHRoaXMuaW5kZXhBcnJheTIpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGxpbmVJbmRleCA9IGxpbmVTZWdtZW50LnZlcnRleExlbmd0aDtcblxuICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0VmVydGV4QXJyYXkuZW1wbGFjZUJhY2socmluZ1swXS54LCByaW5nWzBdLnkpO1xuICAgICAgICAgICAgICAgIHRoaXMuaW5kZXhBcnJheTIuZW1wbGFjZUJhY2sobGluZUluZGV4ICsgcmluZy5sZW5ndGggLSAxLCBsaW5lSW5kZXgpO1xuICAgICAgICAgICAgICAgIGZsYXR0ZW5lZC5wdXNoKHJpbmdbMF0ueCk7XG4gICAgICAgICAgICAgICAgZmxhdHRlbmVkLnB1c2gocmluZ1swXS55KTtcblxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgcmluZy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmxheW91dFZlcnRleEFycmF5LmVtcGxhY2VCYWNrKHJpbmdbaV0ueCwgcmluZ1tpXS55KTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbmRleEFycmF5Mi5lbXBsYWNlQmFjayhsaW5lSW5kZXggKyBpIC0gMSwgbGluZUluZGV4ICsgaSk7XG4gICAgICAgICAgICAgICAgICAgIGZsYXR0ZW5lZC5wdXNoKHJpbmdbaV0ueCk7XG4gICAgICAgICAgICAgICAgICAgIGZsYXR0ZW5lZC5wdXNoKHJpbmdbaV0ueSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgbGluZVNlZ21lbnQudmVydGV4TGVuZ3RoICs9IHJpbmcubGVuZ3RoO1xuICAgICAgICAgICAgICAgIGxpbmVTZWdtZW50LnByaW1pdGl2ZUxlbmd0aCArPSByaW5nLmxlbmd0aDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgaW5kaWNlcyA9IGVhcmN1dChmbGF0dGVuZWQsIGhvbGVJbmRpY2VzKTtcbiAgICAgICAgICAgIGFzc2VydChpbmRpY2VzLmxlbmd0aCAlIDMgPT09IDApO1xuXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGluZGljZXMubGVuZ3RoOyBpICs9IDMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmluZGV4QXJyYXkuZW1wbGFjZUJhY2soXG4gICAgICAgICAgICAgICAgICAgIHRyaWFuZ2xlSW5kZXggKyBpbmRpY2VzW2ldLFxuICAgICAgICAgICAgICAgICAgICB0cmlhbmdsZUluZGV4ICsgaW5kaWNlc1tpICsgMV0sXG4gICAgICAgICAgICAgICAgICAgIHRyaWFuZ2xlSW5kZXggKyBpbmRpY2VzW2kgKyAyXSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRyaWFuZ2xlU2VnbWVudC52ZXJ0ZXhMZW5ndGggKz0gbnVtVmVydGljZXM7XG4gICAgICAgICAgICB0cmlhbmdsZVNlZ21lbnQucHJpbWl0aXZlTGVuZ3RoICs9IGluZGljZXMubGVuZ3RoIC8gMztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnByb2dyYW1Db25maWd1cmF0aW9ucy5wb3B1bGF0ZVBhaW50QXJyYXlzKHRoaXMubGF5b3V0VmVydGV4QXJyYXkubGVuZ3RoLCBmZWF0dXJlLCBpbmRleCwgaW1hZ2VQb3NpdGlvbnMsIGF2YWlsYWJsZUltYWdlcywgY2Fub25pY2FsKTtcbiAgICB9XG59XG5cbnJlZ2lzdGVyKEZpbGxCdWNrZXQsICdGaWxsQnVja2V0Jywge29taXQ6IFsnbGF5ZXJzJywgJ3BhdHRlcm5GZWF0dXJlcyddfSk7XG5cbmV4cG9ydCBkZWZhdWx0IEZpbGxCdWNrZXQ7XG4iLCIvLyBUaGlzIGZpbGUgaXMgZ2VuZXJhdGVkLiBFZGl0IGJ1aWxkL2dlbmVyYXRlLXN0eWxlLWNvZGUuanMsIHRoZW4gcnVuIGB5YXJuIHJ1biBjb2RlZ2VuYC5cbi8vIEBmbG93XG4vKiBlc2xpbnQtZGlzYWJsZSAqL1xuXG5pbXBvcnQgc3R5bGVTcGVjIGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvcmVmZXJlbmNlL2xhdGVzdC5qcyc7XG5cbmltcG9ydCB7XG4gICAgUHJvcGVydGllcyxcbiAgICBEYXRhQ29uc3RhbnRQcm9wZXJ0eSxcbiAgICBEYXRhRHJpdmVuUHJvcGVydHksXG4gICAgQ29sb3JSYW1wUHJvcGVydHlcbn0gZnJvbSAnLi4vcHJvcGVydGllcy5qcyc7XG5cbmltcG9ydCB0eXBlIENvbG9yIGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvdXRpbC9jb2xvci5qcyc7XG5cbmltcG9ydCB0eXBlIEZvcm1hdHRlZCBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vdHlwZXMvZm9ybWF0dGVkLmpzJztcblxuaW1wb3J0IHR5cGUgUmVzb2x2ZWRJbWFnZSBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vdHlwZXMvcmVzb2x2ZWRfaW1hZ2UuanMnO1xuXG5leHBvcnQgdHlwZSBMYXlvdXRQcm9wcyA9IHt8XG4gICAgXCJmaWxsLXNvcnQta2V5XCI6IERhdGFEcml2ZW5Qcm9wZXJ0eTxudW1iZXI+LFxufH07XG5cbmNvbnN0IGxheW91dDogUHJvcGVydGllczxMYXlvdXRQcm9wcz4gPSBuZXcgUHJvcGVydGllcyh7XG4gICAgXCJmaWxsLXNvcnQta2V5XCI6IG5ldyBEYXRhRHJpdmVuUHJvcGVydHkoc3R5bGVTcGVjW1wibGF5b3V0X2ZpbGxcIl1bXCJmaWxsLXNvcnQta2V5XCJdKSxcbn0pO1xuXG5leHBvcnQgdHlwZSBQYWludFByb3BzID0ge3xcbiAgICBcImZpbGwtYW50aWFsaWFzXCI6IERhdGFDb25zdGFudFByb3BlcnR5PGJvb2xlYW4+LFxuICAgIFwiZmlsbC1vcGFjaXR5XCI6IERhdGFEcml2ZW5Qcm9wZXJ0eTxudW1iZXI+LFxuICAgIFwiZmlsbC1jb2xvclwiOiBEYXRhRHJpdmVuUHJvcGVydHk8Q29sb3I+LFxuICAgIFwiZmlsbC1vdXRsaW5lLWNvbG9yXCI6IERhdGFEcml2ZW5Qcm9wZXJ0eTxDb2xvcj4sXG4gICAgXCJmaWxsLXRyYW5zbGF0ZVwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxbbnVtYmVyLCBudW1iZXJdPixcbiAgICBcImZpbGwtdHJhbnNsYXRlLWFuY2hvclwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxcIm1hcFwiIHwgXCJ2aWV3cG9ydFwiPixcbiAgICBcImZpbGwtcGF0dGVyblwiOiBEYXRhRHJpdmVuUHJvcGVydHk8P1Jlc29sdmVkSW1hZ2U+LFxufH07XG5cbmNvbnN0IHBhaW50OiBQcm9wZXJ0aWVzPFBhaW50UHJvcHM+ID0gbmV3IFByb3BlcnRpZXMoe1xuICAgIFwiZmlsbC1hbnRpYWxpYXNcIjogbmV3IERhdGFDb25zdGFudFByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X2ZpbGxcIl1bXCJmaWxsLWFudGlhbGlhc1wiXSksXG4gICAgXCJmaWxsLW9wYWNpdHlcIjogbmV3IERhdGFEcml2ZW5Qcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9maWxsXCJdW1wiZmlsbC1vcGFjaXR5XCJdKSxcbiAgICBcImZpbGwtY29sb3JcIjogbmV3IERhdGFEcml2ZW5Qcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9maWxsXCJdW1wiZmlsbC1jb2xvclwiXSksXG4gICAgXCJmaWxsLW91dGxpbmUtY29sb3JcIjogbmV3IERhdGFEcml2ZW5Qcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9maWxsXCJdW1wiZmlsbC1vdXRsaW5lLWNvbG9yXCJdKSxcbiAgICBcImZpbGwtdHJhbnNsYXRlXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9maWxsXCJdW1wiZmlsbC10cmFuc2xhdGVcIl0pLFxuICAgIFwiZmlsbC10cmFuc2xhdGUtYW5jaG9yXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9maWxsXCJdW1wiZmlsbC10cmFuc2xhdGUtYW5jaG9yXCJdKSxcbiAgICBcImZpbGwtcGF0dGVyblwiOiBuZXcgRGF0YURyaXZlblByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X2ZpbGxcIl1bXCJmaWxsLXBhdHRlcm5cIl0pLFxufSk7XG5cbi8vIE5vdGU6IHdpdGhvdXQgYWRkaW5nIHRoZSBleHBsaWNpdCB0eXBlIGFubm90YXRpb24sIEZsb3cgaW5mZXJzIHdlYWtlciB0eXBlc1xuLy8gZm9yIHRoZXNlIG9iamVjdHMgZnJvbSB0aGVpciB1c2UgaW4gdGhlIGNvbnN0cnVjdG9yIHRvIFN0eWxlTGF5ZXIsIGFzXG4vLyB7bGF5b3V0PzogUHJvcGVydGllczwuLi4+LCBwYWludDogUHJvcGVydGllczwuLi4+fVxuZXhwb3J0IGRlZmF1bHQgKHsgcGFpbnQsIGxheW91dCB9OiAkRXhhY3Q8e1xuICBwYWludDogUHJvcGVydGllczxQYWludFByb3BzPiwgbGF5b3V0OiBQcm9wZXJ0aWVzPExheW91dFByb3BzPlxufT4pO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IFN0eWxlTGF5ZXIgZnJvbSAnLi4vc3R5bGVfbGF5ZXIuanMnO1xuXG5pbXBvcnQgRmlsbEJ1Y2tldCBmcm9tICcuLi8uLi9kYXRhL2J1Y2tldC9maWxsX2J1Y2tldC5qcyc7XG5pbXBvcnQge3BvbHlnb25JbnRlcnNlY3RzTXVsdGlQb2x5Z29ufSBmcm9tICcuLi8uLi91dGlsL2ludGVyc2VjdGlvbl90ZXN0cy5qcyc7XG5pbXBvcnQge3RyYW5zbGF0ZURpc3RhbmNlLCB0cmFuc2xhdGV9IGZyb20gJy4uL3F1ZXJ5X3V0aWxzLmpzJztcbmltcG9ydCBwcm9wZXJ0aWVzIGZyb20gJy4vZmlsbF9zdHlsZV9sYXllcl9wcm9wZXJ0aWVzLmpzJztcbmltcG9ydCB7VHJhbnNpdGlvbmFibGUsIFRyYW5zaXRpb25pbmcsIExheW91dCwgUG9zc2libHlFdmFsdWF0ZWR9IGZyb20gJy4uL3Byb3BlcnRpZXMuanMnO1xuaW1wb3J0IFByb2dyYW1Db25maWd1cmF0aW9uIGZyb20gJy4uLy4uL2RhdGEvcHJvZ3JhbV9jb25maWd1cmF0aW9uLmpzJztcblxuaW1wb3J0IHR5cGUge0ZlYXR1cmVTdGF0ZX0gZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy9leHByZXNzaW9uL2luZGV4LmpzJztcbmltcG9ydCB0eXBlIHtCdWNrZXRQYXJhbWV0ZXJzfSBmcm9tICcuLi8uLi9kYXRhL2J1Y2tldC5qcyc7XG5pbXBvcnQgdHlwZSBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCB0eXBlIHtMYXlvdXRQcm9wcywgUGFpbnRQcm9wc30gZnJvbSAnLi9maWxsX3N0eWxlX2xheWVyX3Byb3BlcnRpZXMuanMnO1xuaW1wb3J0IHR5cGUgRXZhbHVhdGlvblBhcmFtZXRlcnMgZnJvbSAnLi4vZXZhbHVhdGlvbl9wYXJhbWV0ZXJzLmpzJztcbmltcG9ydCB0eXBlIFRyYW5zZm9ybSBmcm9tICcuLi8uLi9nZW8vdHJhbnNmb3JtLmpzJztcbmltcG9ydCB0eXBlIHtMYXllclNwZWNpZmljYXRpb259IGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge1RpbGVzcGFjZVF1ZXJ5R2VvbWV0cnl9IGZyb20gJy4uL3F1ZXJ5X2dlb21ldHJ5LmpzJztcbmltcG9ydCB0eXBlIHtJVmVjdG9yVGlsZUZlYXR1cmV9IGZyb20gJ0BtYXBib3gvdmVjdG9yLXRpbGUnO1xuXG5jbGFzcyBGaWxsU3R5bGVMYXllciBleHRlbmRzIFN0eWxlTGF5ZXIge1xuICAgIF91bmV2YWx1YXRlZExheW91dDogTGF5b3V0PExheW91dFByb3BzPjtcbiAgICBsYXlvdXQ6IFBvc3NpYmx5RXZhbHVhdGVkPExheW91dFByb3BzPjtcblxuICAgIF90cmFuc2l0aW9uYWJsZVBhaW50OiBUcmFuc2l0aW9uYWJsZTxQYWludFByb3BzPjtcbiAgICBfdHJhbnNpdGlvbmluZ1BhaW50OiBUcmFuc2l0aW9uaW5nPFBhaW50UHJvcHM+O1xuICAgIHBhaW50OiBQb3NzaWJseUV2YWx1YXRlZDxQYWludFByb3BzPjtcblxuICAgIGNvbnN0cnVjdG9yKGxheWVyOiBMYXllclNwZWNpZmljYXRpb24pIHtcbiAgICAgICAgc3VwZXIobGF5ZXIsIHByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIGdldFByb2dyYW1JZHMoKTogc3RyaW5nW10ge1xuICAgICAgICBjb25zdCBwYXR0ZXJuID0gdGhpcy5wYWludC5nZXQoJ2ZpbGwtcGF0dGVybicpO1xuICAgICAgICBjb25zdCBpbWFnZSA9IHBhdHRlcm4gJiYgcGF0dGVybi5jb25zdGFudE9yKCgxOiBhbnkpKTtcblxuICAgICAgICBjb25zdCBpZHMgPSBbaW1hZ2UgPyAnZmlsbFBhdHRlcm4nIDogJ2ZpbGwnXTtcblxuICAgICAgICBpZiAodGhpcy5wYWludC5nZXQoJ2ZpbGwtYW50aWFsaWFzJykpIHtcbiAgICAgICAgICAgIGlkcy5wdXNoKGltYWdlICYmICF0aGlzLmdldFBhaW50UHJvcGVydHkoJ2ZpbGwtb3V0bGluZS1jb2xvcicpID8gJ2ZpbGxPdXRsaW5lUGF0dGVybicgOiAnZmlsbE91dGxpbmUnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBpZHM7XG4gICAgfVxuXG4gICAgZ2V0UHJvZ3JhbUNvbmZpZ3VyYXRpb24oem9vbTogbnVtYmVyKTogUHJvZ3JhbUNvbmZpZ3VyYXRpb24ge1xuICAgICAgICByZXR1cm4gbmV3IFByb2dyYW1Db25maWd1cmF0aW9uKHRoaXMsIHpvb20pO1xuICAgIH1cblxuICAgIHJlY2FsY3VsYXRlKHBhcmFtZXRlcnM6IEV2YWx1YXRpb25QYXJhbWV0ZXJzLCBhdmFpbGFibGVJbWFnZXM6IEFycmF5PHN0cmluZz4pIHtcbiAgICAgICAgc3VwZXIucmVjYWxjdWxhdGUocGFyYW1ldGVycywgYXZhaWxhYmxlSW1hZ2VzKTtcblxuICAgICAgICBjb25zdCBvdXRsaW5lQ29sb3IgPSB0aGlzLnBhaW50Ll92YWx1ZXNbJ2ZpbGwtb3V0bGluZS1jb2xvciddO1xuICAgICAgICBpZiAob3V0bGluZUNvbG9yLnZhbHVlLmtpbmQgPT09ICdjb25zdGFudCcgJiYgb3V0bGluZUNvbG9yLnZhbHVlLnZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMucGFpbnQuX3ZhbHVlc1snZmlsbC1vdXRsaW5lLWNvbG9yJ10gPSB0aGlzLnBhaW50Ll92YWx1ZXNbJ2ZpbGwtY29sb3InXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNyZWF0ZUJ1Y2tldChwYXJhbWV0ZXJzOiBCdWNrZXRQYXJhbWV0ZXJzPEZpbGxTdHlsZUxheWVyPik6IEZpbGxCdWNrZXQge1xuICAgICAgICByZXR1cm4gbmV3IEZpbGxCdWNrZXQocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIHF1ZXJ5UmFkaXVzKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0cmFuc2xhdGVEaXN0YW5jZSh0aGlzLnBhaW50LmdldCgnZmlsbC10cmFuc2xhdGUnKSk7XG4gICAgfVxuXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIHF1ZXJ5SW50ZXJzZWN0c0ZlYXR1cmUocXVlcnlHZW9tZXRyeTogVGlsZXNwYWNlUXVlcnlHZW9tZXRyeSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZlYXR1cmU6IElWZWN0b3JUaWxlRmVhdHVyZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZlYXR1cmVTdGF0ZTogRmVhdHVyZVN0YXRlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbWV0cnk6IEFycmF5PEFycmF5PFBvaW50Pj4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICB6b29tOiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm06IFRyYW5zZm9ybSk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAocXVlcnlHZW9tZXRyeS5xdWVyeUdlb21ldHJ5LmlzQWJvdmVIb3Jpem9uKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgY29uc3QgdHJhbnNsYXRlZFBvbHlnb24gPSB0cmFuc2xhdGUocXVlcnlHZW9tZXRyeS50aWxlc3BhY2VHZW9tZXRyeSxcbiAgICAgICAgICAgIHRoaXMucGFpbnQuZ2V0KCdmaWxsLXRyYW5zbGF0ZScpLFxuICAgICAgICAgICAgdGhpcy5wYWludC5nZXQoJ2ZpbGwtdHJhbnNsYXRlLWFuY2hvcicpLFxuICAgICAgICAgICAgdHJhbnNmb3JtLmFuZ2xlLCBxdWVyeUdlb21ldHJ5LnBpeGVsVG9UaWxlVW5pdHNGYWN0b3IpO1xuICAgICAgICByZXR1cm4gcG9seWdvbkludGVyc2VjdHNNdWx0aVBvbHlnb24odHJhbnNsYXRlZFBvbHlnb24sIGdlb21ldHJ5KTtcbiAgICB9XG5cbiAgICBpc1RpbGVDbGlwcGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEZpbGxTdHlsZUxheWVyO1xuIiwiLy8gQGZsb3dcbmltcG9ydCB7Y3JlYXRlTGF5b3V0fSBmcm9tICcuLi8uLi91dGlsL3N0cnVjdF9hcnJheS5qcyc7XG5cbmltcG9ydCB0eXBlIHtTdHJ1Y3RBcnJheUxheW91dH0gZnJvbSAnLi4vLi4vdXRpbC9zdHJ1Y3RfYXJyYXkuanMnO1xuXG5leHBvcnQgY29uc3QgZmlsbEV4dHJ1c2lvbkF0dHJpYnV0ZXM6IFN0cnVjdEFycmF5TGF5b3V0ID0gY3JlYXRlTGF5b3V0KFtcbiAgICB7bmFtZTogJ2FfcG9zX25vcm1hbF9lZCcsIGNvbXBvbmVudHM6IDQsIHR5cGU6ICdJbnQxNid9XG5dKTtcblxuZXhwb3J0IGNvbnN0IGNlbnRyb2lkQXR0cmlidXRlczogU3RydWN0QXJyYXlMYXlvdXQgPSBjcmVhdGVMYXlvdXQoW1xuICAgIHtuYW1lOiAnYV9jZW50cm9pZF9wb3MnLCAgY29tcG9uZW50czogMiwgdHlwZTogJ1VpbnQxNid9XG5dKTtcblxuZXhwb3J0IGNvbnN0IGZpbGxFeHRydXNpb25BdHRyaWJ1dGVzRXh0OiBTdHJ1Y3RBcnJheUxheW91dCA9IGNyZWF0ZUxheW91dChbXG4gICAge25hbWU6ICdhX3Bvc18zJywgY29tcG9uZW50czogMywgdHlwZTogJ0ludDE2J30sXG4gICAge25hbWU6ICdhX3Bvc19ub3JtYWxfMycsIGNvbXBvbmVudHM6IDMsIHR5cGU6ICdJbnQxNid9XG5dKTtcblxuZXhwb3J0IGNvbnN0IHttZW1iZXJzLCBzaXplLCBhbGlnbm1lbnR9ID0gZmlsbEV4dHJ1c2lvbkF0dHJpYnV0ZXM7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBQb2ludCA9IHJlcXVpcmUoJ0BtYXBib3gvcG9pbnQtZ2VvbWV0cnknKTtcblxubW9kdWxlLmV4cG9ydHMgPSBWZWN0b3JUaWxlRmVhdHVyZTtcblxuZnVuY3Rpb24gVmVjdG9yVGlsZUZlYXR1cmUocGJmLCBlbmQsIGV4dGVudCwga2V5cywgdmFsdWVzKSB7XG4gICAgLy8gUHVibGljXG4gICAgdGhpcy5wcm9wZXJ0aWVzID0ge307XG4gICAgdGhpcy5leHRlbnQgPSBleHRlbnQ7XG4gICAgdGhpcy50eXBlID0gMDtcblxuICAgIC8vIFByaXZhdGVcbiAgICB0aGlzLl9wYmYgPSBwYmY7XG4gICAgdGhpcy5fZ2VvbWV0cnkgPSAtMTtcbiAgICB0aGlzLl9rZXlzID0ga2V5cztcbiAgICB0aGlzLl92YWx1ZXMgPSB2YWx1ZXM7XG5cbiAgICBwYmYucmVhZEZpZWxkcyhyZWFkRmVhdHVyZSwgdGhpcywgZW5kKTtcbn1cblxuZnVuY3Rpb24gcmVhZEZlYXR1cmUodGFnLCBmZWF0dXJlLCBwYmYpIHtcbiAgICBpZiAodGFnID09IDEpIGZlYXR1cmUuaWQgPSBwYmYucmVhZFZhcmludCgpO1xuICAgIGVsc2UgaWYgKHRhZyA9PSAyKSByZWFkVGFnKHBiZiwgZmVhdHVyZSk7XG4gICAgZWxzZSBpZiAodGFnID09IDMpIGZlYXR1cmUudHlwZSA9IHBiZi5yZWFkVmFyaW50KCk7XG4gICAgZWxzZSBpZiAodGFnID09IDQpIGZlYXR1cmUuX2dlb21ldHJ5ID0gcGJmLnBvcztcbn1cblxuZnVuY3Rpb24gcmVhZFRhZyhwYmYsIGZlYXR1cmUpIHtcbiAgICB2YXIgZW5kID0gcGJmLnJlYWRWYXJpbnQoKSArIHBiZi5wb3M7XG5cbiAgICB3aGlsZSAocGJmLnBvcyA8IGVuZCkge1xuICAgICAgICB2YXIga2V5ID0gZmVhdHVyZS5fa2V5c1twYmYucmVhZFZhcmludCgpXSxcbiAgICAgICAgICAgIHZhbHVlID0gZmVhdHVyZS5fdmFsdWVzW3BiZi5yZWFkVmFyaW50KCldO1xuICAgICAgICBmZWF0dXJlLnByb3BlcnRpZXNba2V5XSA9IHZhbHVlO1xuICAgIH1cbn1cblxuVmVjdG9yVGlsZUZlYXR1cmUudHlwZXMgPSBbJ1Vua25vd24nLCAnUG9pbnQnLCAnTGluZVN0cmluZycsICdQb2x5Z29uJ107XG5cblZlY3RvclRpbGVGZWF0dXJlLnByb3RvdHlwZS5sb2FkR2VvbWV0cnkgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgcGJmID0gdGhpcy5fcGJmO1xuICAgIHBiZi5wb3MgPSB0aGlzLl9nZW9tZXRyeTtcblxuICAgIHZhciBlbmQgPSBwYmYucmVhZFZhcmludCgpICsgcGJmLnBvcyxcbiAgICAgICAgY21kID0gMSxcbiAgICAgICAgbGVuZ3RoID0gMCxcbiAgICAgICAgeCA9IDAsXG4gICAgICAgIHkgPSAwLFxuICAgICAgICBsaW5lcyA9IFtdLFxuICAgICAgICBsaW5lO1xuXG4gICAgd2hpbGUgKHBiZi5wb3MgPCBlbmQpIHtcbiAgICAgICAgaWYgKGxlbmd0aCA8PSAwKSB7XG4gICAgICAgICAgICB2YXIgY21kTGVuID0gcGJmLnJlYWRWYXJpbnQoKTtcbiAgICAgICAgICAgIGNtZCA9IGNtZExlbiAmIDB4NztcbiAgICAgICAgICAgIGxlbmd0aCA9IGNtZExlbiA+PiAzO1xuICAgICAgICB9XG5cbiAgICAgICAgbGVuZ3RoLS07XG5cbiAgICAgICAgaWYgKGNtZCA9PT0gMSB8fCBjbWQgPT09IDIpIHtcbiAgICAgICAgICAgIHggKz0gcGJmLnJlYWRTVmFyaW50KCk7XG4gICAgICAgICAgICB5ICs9IHBiZi5yZWFkU1ZhcmludCgpO1xuXG4gICAgICAgICAgICBpZiAoY21kID09PSAxKSB7IC8vIG1vdmVUb1xuICAgICAgICAgICAgICAgIGlmIChsaW5lKSBsaW5lcy5wdXNoKGxpbmUpO1xuICAgICAgICAgICAgICAgIGxpbmUgPSBbXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGluZS5wdXNoKG5ldyBQb2ludCh4LCB5KSk7XG5cbiAgICAgICAgfSBlbHNlIGlmIChjbWQgPT09IDcpIHtcblxuICAgICAgICAgICAgLy8gV29ya2Fyb3VuZCBmb3IgaHR0cHM6Ly9naXRodWIuY29tL21hcGJveC9tYXBuaWstdmVjdG9yLXRpbGUvaXNzdWVzLzkwXG4gICAgICAgICAgICBpZiAobGluZSkge1xuICAgICAgICAgICAgICAgIGxpbmUucHVzaChsaW5lWzBdLmNsb25lKCkpOyAvLyBjbG9zZVBvbHlnb25cbiAgICAgICAgICAgIH1cblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIGNvbW1hbmQgJyArIGNtZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobGluZSkgbGluZXMucHVzaChsaW5lKTtcblxuICAgIHJldHVybiBsaW5lcztcbn07XG5cblZlY3RvclRpbGVGZWF0dXJlLnByb3RvdHlwZS5iYm94ID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHBiZiA9IHRoaXMuX3BiZjtcbiAgICBwYmYucG9zID0gdGhpcy5fZ2VvbWV0cnk7XG5cbiAgICB2YXIgZW5kID0gcGJmLnJlYWRWYXJpbnQoKSArIHBiZi5wb3MsXG4gICAgICAgIGNtZCA9IDEsXG4gICAgICAgIGxlbmd0aCA9IDAsXG4gICAgICAgIHggPSAwLFxuICAgICAgICB5ID0gMCxcbiAgICAgICAgeDEgPSBJbmZpbml0eSxcbiAgICAgICAgeDIgPSAtSW5maW5pdHksXG4gICAgICAgIHkxID0gSW5maW5pdHksXG4gICAgICAgIHkyID0gLUluZmluaXR5O1xuXG4gICAgd2hpbGUgKHBiZi5wb3MgPCBlbmQpIHtcbiAgICAgICAgaWYgKGxlbmd0aCA8PSAwKSB7XG4gICAgICAgICAgICB2YXIgY21kTGVuID0gcGJmLnJlYWRWYXJpbnQoKTtcbiAgICAgICAgICAgIGNtZCA9IGNtZExlbiAmIDB4NztcbiAgICAgICAgICAgIGxlbmd0aCA9IGNtZExlbiA+PiAzO1xuICAgICAgICB9XG5cbiAgICAgICAgbGVuZ3RoLS07XG5cbiAgICAgICAgaWYgKGNtZCA9PT0gMSB8fCBjbWQgPT09IDIpIHtcbiAgICAgICAgICAgIHggKz0gcGJmLnJlYWRTVmFyaW50KCk7XG4gICAgICAgICAgICB5ICs9IHBiZi5yZWFkU1ZhcmludCgpO1xuICAgICAgICAgICAgaWYgKHggPCB4MSkgeDEgPSB4O1xuICAgICAgICAgICAgaWYgKHggPiB4MikgeDIgPSB4O1xuICAgICAgICAgICAgaWYgKHkgPCB5MSkgeTEgPSB5O1xuICAgICAgICAgICAgaWYgKHkgPiB5MikgeTIgPSB5O1xuXG4gICAgICAgIH0gZWxzZSBpZiAoY21kICE9PSA3KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24gY29tbWFuZCAnICsgY21kKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBbeDEsIHkxLCB4MiwgeTJdO1xufTtcblxuVmVjdG9yVGlsZUZlYXR1cmUucHJvdG90eXBlLnRvR2VvSlNPTiA9IGZ1bmN0aW9uKHgsIHksIHopIHtcbiAgICB2YXIgc2l6ZSA9IHRoaXMuZXh0ZW50ICogTWF0aC5wb3coMiwgeiksXG4gICAgICAgIHgwID0gdGhpcy5leHRlbnQgKiB4LFxuICAgICAgICB5MCA9IHRoaXMuZXh0ZW50ICogeSxcbiAgICAgICAgY29vcmRzID0gdGhpcy5sb2FkR2VvbWV0cnkoKSxcbiAgICAgICAgdHlwZSA9IFZlY3RvclRpbGVGZWF0dXJlLnR5cGVzW3RoaXMudHlwZV0sXG4gICAgICAgIGksIGo7XG5cbiAgICBmdW5jdGlvbiBwcm9qZWN0KGxpbmUpIHtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBsaW5lLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICB2YXIgcCA9IGxpbmVbal0sIHkyID0gMTgwIC0gKHAueSArIHkwKSAqIDM2MCAvIHNpemU7XG4gICAgICAgICAgICBsaW5lW2pdID0gW1xuICAgICAgICAgICAgICAgIChwLnggKyB4MCkgKiAzNjAgLyBzaXplIC0gMTgwLFxuICAgICAgICAgICAgICAgIDM2MCAvIE1hdGguUEkgKiBNYXRoLmF0YW4oTWF0aC5leHAoeTIgKiBNYXRoLlBJIC8gMTgwKSkgLSA5MFxuICAgICAgICAgICAgXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN3aXRjaCAodGhpcy50eXBlKSB7XG4gICAgY2FzZSAxOlxuICAgICAgICB2YXIgcG9pbnRzID0gW107XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb29yZHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHBvaW50c1tpXSA9IGNvb3Jkc1tpXVswXTtcbiAgICAgICAgfVxuICAgICAgICBjb29yZHMgPSBwb2ludHM7XG4gICAgICAgIHByb2plY3QoY29vcmRzKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIDI6XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb29yZHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHByb2plY3QoY29vcmRzW2ldKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcblxuICAgIGNhc2UgMzpcbiAgICAgICAgY29vcmRzID0gY2xhc3NpZnlSaW5ncyhjb29yZHMpO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY29vcmRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgY29vcmRzW2ldLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgcHJvamVjdChjb29yZHNbaV1bal0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIGlmIChjb29yZHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIGNvb3JkcyA9IGNvb3Jkc1swXTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0eXBlID0gJ011bHRpJyArIHR5cGU7XG4gICAgfVxuXG4gICAgdmFyIHJlc3VsdCA9IHtcbiAgICAgICAgdHlwZTogXCJGZWF0dXJlXCIsXG4gICAgICAgIGdlb21ldHJ5OiB7XG4gICAgICAgICAgICB0eXBlOiB0eXBlLFxuICAgICAgICAgICAgY29vcmRpbmF0ZXM6IGNvb3Jkc1xuICAgICAgICB9LFxuICAgICAgICBwcm9wZXJ0aWVzOiB0aGlzLnByb3BlcnRpZXNcbiAgICB9O1xuXG4gICAgaWYgKCdpZCcgaW4gdGhpcykge1xuICAgICAgICByZXN1bHQuaWQgPSB0aGlzLmlkO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG59O1xuXG4vLyBjbGFzc2lmaWVzIGFuIGFycmF5IG9mIHJpbmdzIGludG8gcG9seWdvbnMgd2l0aCBvdXRlciByaW5ncyBhbmQgaG9sZXNcblxuZnVuY3Rpb24gY2xhc3NpZnlSaW5ncyhyaW5ncykge1xuICAgIHZhciBsZW4gPSByaW5ncy5sZW5ndGg7XG5cbiAgICBpZiAobGVuIDw9IDEpIHJldHVybiBbcmluZ3NdO1xuXG4gICAgdmFyIHBvbHlnb25zID0gW10sXG4gICAgICAgIHBvbHlnb24sXG4gICAgICAgIGNjdztcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgdmFyIGFyZWEgPSBzaWduZWRBcmVhKHJpbmdzW2ldKTtcbiAgICAgICAgaWYgKGFyZWEgPT09IDApIGNvbnRpbnVlO1xuXG4gICAgICAgIGlmIChjY3cgPT09IHVuZGVmaW5lZCkgY2N3ID0gYXJlYSA8IDA7XG5cbiAgICAgICAgaWYgKGNjdyA9PT0gYXJlYSA8IDApIHtcbiAgICAgICAgICAgIGlmIChwb2x5Z29uKSBwb2x5Z29ucy5wdXNoKHBvbHlnb24pO1xuICAgICAgICAgICAgcG9seWdvbiA9IFtyaW5nc1tpXV07XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBvbHlnb24ucHVzaChyaW5nc1tpXSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKHBvbHlnb24pIHBvbHlnb25zLnB1c2gocG9seWdvbik7XG5cbiAgICByZXR1cm4gcG9seWdvbnM7XG59XG5cbmZ1bmN0aW9uIHNpZ25lZEFyZWEocmluZykge1xuICAgIHZhciBzdW0gPSAwO1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSByaW5nLmxlbmd0aCwgaiA9IGxlbiAtIDEsIHAxLCBwMjsgaSA8IGxlbjsgaiA9IGkrKykge1xuICAgICAgICBwMSA9IHJpbmdbaV07XG4gICAgICAgIHAyID0gcmluZ1tqXTtcbiAgICAgICAgc3VtICs9IChwMi54IC0gcDEueCkgKiAocDEueSArIHAyLnkpO1xuICAgIH1cbiAgICByZXR1cm4gc3VtO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVmVjdG9yVGlsZUZlYXR1cmUgPSByZXF1aXJlKCcuL3ZlY3RvcnRpbGVmZWF0dXJlLmpzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gVmVjdG9yVGlsZUxheWVyO1xuXG5mdW5jdGlvbiBWZWN0b3JUaWxlTGF5ZXIocGJmLCBlbmQpIHtcbiAgICAvLyBQdWJsaWNcbiAgICB0aGlzLnZlcnNpb24gPSAxO1xuICAgIHRoaXMubmFtZSA9IG51bGw7XG4gICAgdGhpcy5leHRlbnQgPSA0MDk2O1xuICAgIHRoaXMubGVuZ3RoID0gMDtcblxuICAgIC8vIFByaXZhdGVcbiAgICB0aGlzLl9wYmYgPSBwYmY7XG4gICAgdGhpcy5fa2V5cyA9IFtdO1xuICAgIHRoaXMuX3ZhbHVlcyA9IFtdO1xuICAgIHRoaXMuX2ZlYXR1cmVzID0gW107XG5cbiAgICBwYmYucmVhZEZpZWxkcyhyZWFkTGF5ZXIsIHRoaXMsIGVuZCk7XG5cbiAgICB0aGlzLmxlbmd0aCA9IHRoaXMuX2ZlYXR1cmVzLmxlbmd0aDtcbn1cblxuZnVuY3Rpb24gcmVhZExheWVyKHRhZywgbGF5ZXIsIHBiZikge1xuICAgIGlmICh0YWcgPT09IDE1KSBsYXllci52ZXJzaW9uID0gcGJmLnJlYWRWYXJpbnQoKTtcbiAgICBlbHNlIGlmICh0YWcgPT09IDEpIGxheWVyLm5hbWUgPSBwYmYucmVhZFN0cmluZygpO1xuICAgIGVsc2UgaWYgKHRhZyA9PT0gNSkgbGF5ZXIuZXh0ZW50ID0gcGJmLnJlYWRWYXJpbnQoKTtcbiAgICBlbHNlIGlmICh0YWcgPT09IDIpIGxheWVyLl9mZWF0dXJlcy5wdXNoKHBiZi5wb3MpO1xuICAgIGVsc2UgaWYgKHRhZyA9PT0gMykgbGF5ZXIuX2tleXMucHVzaChwYmYucmVhZFN0cmluZygpKTtcbiAgICBlbHNlIGlmICh0YWcgPT09IDQpIGxheWVyLl92YWx1ZXMucHVzaChyZWFkVmFsdWVNZXNzYWdlKHBiZikpO1xufVxuXG5mdW5jdGlvbiByZWFkVmFsdWVNZXNzYWdlKHBiZikge1xuICAgIHZhciB2YWx1ZSA9IG51bGwsXG4gICAgICAgIGVuZCA9IHBiZi5yZWFkVmFyaW50KCkgKyBwYmYucG9zO1xuXG4gICAgd2hpbGUgKHBiZi5wb3MgPCBlbmQpIHtcbiAgICAgICAgdmFyIHRhZyA9IHBiZi5yZWFkVmFyaW50KCkgPj4gMztcblxuICAgICAgICB2YWx1ZSA9IHRhZyA9PT0gMSA/IHBiZi5yZWFkU3RyaW5nKCkgOlxuICAgICAgICAgICAgdGFnID09PSAyID8gcGJmLnJlYWRGbG9hdCgpIDpcbiAgICAgICAgICAgIHRhZyA9PT0gMyA/IHBiZi5yZWFkRG91YmxlKCkgOlxuICAgICAgICAgICAgdGFnID09PSA0ID8gcGJmLnJlYWRWYXJpbnQ2NCgpIDpcbiAgICAgICAgICAgIHRhZyA9PT0gNSA/IHBiZi5yZWFkVmFyaW50KCkgOlxuICAgICAgICAgICAgdGFnID09PSA2ID8gcGJmLnJlYWRTVmFyaW50KCkgOlxuICAgICAgICAgICAgdGFnID09PSA3ID8gcGJmLnJlYWRCb29sZWFuKCkgOiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZTtcbn1cblxuLy8gcmV0dXJuIGZlYXR1cmUgYGlgIGZyb20gdGhpcyBsYXllciBhcyBhIGBWZWN0b3JUaWxlRmVhdHVyZWBcblZlY3RvclRpbGVMYXllci5wcm90b3R5cGUuZmVhdHVyZSA9IGZ1bmN0aW9uKGkpIHtcbiAgICBpZiAoaSA8IDAgfHwgaSA+PSB0aGlzLl9mZWF0dXJlcy5sZW5ndGgpIHRocm93IG5ldyBFcnJvcignZmVhdHVyZSBpbmRleCBvdXQgb2YgYm91bmRzJyk7XG5cbiAgICB0aGlzLl9wYmYucG9zID0gdGhpcy5fZmVhdHVyZXNbaV07XG5cbiAgICB2YXIgZW5kID0gdGhpcy5fcGJmLnJlYWRWYXJpbnQoKSArIHRoaXMuX3BiZi5wb3M7XG4gICAgcmV0dXJuIG5ldyBWZWN0b3JUaWxlRmVhdHVyZSh0aGlzLl9wYmYsIGVuZCwgdGhpcy5leHRlbnQsIHRoaXMuX2tleXMsIHRoaXMuX3ZhbHVlcyk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVmVjdG9yVGlsZUxheWVyID0gcmVxdWlyZSgnLi92ZWN0b3J0aWxlbGF5ZXInKTtcblxubW9kdWxlLmV4cG9ydHMgPSBWZWN0b3JUaWxlO1xuXG5mdW5jdGlvbiBWZWN0b3JUaWxlKHBiZiwgZW5kKSB7XG4gICAgdGhpcy5sYXllcnMgPSBwYmYucmVhZEZpZWxkcyhyZWFkVGlsZSwge30sIGVuZCk7XG59XG5cbmZ1bmN0aW9uIHJlYWRUaWxlKHRhZywgbGF5ZXJzLCBwYmYpIHtcbiAgICBpZiAodGFnID09PSAzKSB7XG4gICAgICAgIHZhciBsYXllciA9IG5ldyBWZWN0b3JUaWxlTGF5ZXIocGJmLCBwYmYucmVhZFZhcmludCgpICsgcGJmLnBvcyk7XG4gICAgICAgIGlmIChsYXllci5sZW5ndGgpIGxheWVyc1tsYXllci5uYW1lXSA9IGxheWVyO1xuICAgIH1cbn1cblxuIiwibW9kdWxlLmV4cG9ydHMuVmVjdG9yVGlsZSA9IHJlcXVpcmUoJy4vbGliL3ZlY3RvcnRpbGUuanMnKTtcbm1vZHVsZS5leHBvcnRzLlZlY3RvclRpbGVGZWF0dXJlID0gcmVxdWlyZSgnLi9saWIvdmVjdG9ydGlsZWZlYXR1cmUuanMnKTtcbm1vZHVsZS5leHBvcnRzLlZlY3RvclRpbGVMYXllciA9IHJlcXVpcmUoJy4vbGliL3ZlY3RvcnRpbGVsYXllci5qcycpO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IFBvaW50IGZyb20gJ0BtYXBib3gvcG9pbnQtZ2VvbWV0cnknO1xuXG5leHBvcnQgdHlwZSBDbGlwcGVkUG9seWdvbiA9IHtcbiAgICBwb2x5Z29uOiBBcnJheTxBcnJheTxQb2ludD4+LFxuICAgIGJvdW5kczogW1BvaW50LCBQb2ludF1cbn07XG5cbnR5cGUgUG9seWdvbkFycmF5ID0gQXJyYXk8QXJyYXk8QXJyYXk8UG9pbnQ+Pj47XG5cbmZ1bmN0aW9uIGNsaXBQb2x5Z29uKHBvbHlnb25zOiBQb2x5Z29uQXJyYXksIGNsaXBBeGlzMTogbnVtYmVyLCBjbGlwQXhpczI6IG51bWJlciwgYXhpczogbnVtYmVyKTogUG9seWdvbkFycmF5IHtcbiAgICBjb25zdCBpbnRlcnNlY3RYID0gKHJpbmc6IEFycmF5PFBvaW50PiwgYXg6IG51bWJlciwgYXk6IG51bWJlciwgYng6IG51bWJlciwgYnk6IG51bWJlciwgeDogbnVtYmVyKSA9PiB7XG4gICAgICAgIHJpbmcucHVzaChuZXcgUG9pbnQoeCwgYXkgKyAoYnkgLSBheSkgKiAoKHggLSBheCkgLyAoYnggLSBheCkpKSk7XG4gICAgfTtcbiAgICBjb25zdCBpbnRlcnNlY3RZID0gKHJpbmc6IEFycmF5PFBvaW50PiwgYXg6IG51bWJlciwgYXk6IG51bWJlciwgYng6IG51bWJlciwgYnk6IG51bWJlciwgeTogbnVtYmVyKSA9PiB7XG4gICAgICAgIHJpbmcucHVzaChuZXcgUG9pbnQoYXggKyAoYnggLSBheCkgKiAoKHkgLSBheSkgLyAoYnkgLSBheSkpLCB5KSk7XG4gICAgfTtcblxuICAgIGNvbnN0IHBvbHlnb25zQ2xpcHBlZCA9IFtdO1xuICAgIGNvbnN0IGludGVyc2VjdCA9IGF4aXMgPT09IDAgPyBpbnRlcnNlY3RYIDogaW50ZXJzZWN0WTtcbiAgICBmb3IgKGNvbnN0IHBvbHlnb24gb2YgcG9seWdvbnMpIHtcbiAgICAgICAgY29uc3QgcG9seWdvbkNsaXBwZWQgPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCByaW5nIG9mIHBvbHlnb24pIHtcbiAgICAgICAgICAgIGlmIChyaW5nLmxlbmd0aCA8PSAyKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGNsaXBwZWQgPSBbXTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmluZy5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBheCA9IHJpbmdbaV0ueDtcbiAgICAgICAgICAgICAgICBjb25zdCBheSA9IHJpbmdbaV0ueTtcbiAgICAgICAgICAgICAgICBjb25zdCBieCA9IHJpbmdbaSArIDFdLng7XG4gICAgICAgICAgICAgICAgY29uc3QgYnkgPSByaW5nW2kgKyAxXS55O1xuICAgICAgICAgICAgICAgIGNvbnN0IGEgPSBheGlzID09PSAwID8gYXggOiBheTtcbiAgICAgICAgICAgICAgICBjb25zdCBiID0gYXhpcyA9PT0gMCA/IGJ4IDogYnk7XG4gICAgICAgICAgICAgICAgaWYgKGEgPCBjbGlwQXhpczEpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGIgPiBjbGlwQXhpczEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGludGVyc2VjdChjbGlwcGVkLCBheCwgYXksIGJ4LCBieSwgY2xpcEF4aXMxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYSA+IGNsaXBBeGlzMikge1xuICAgICAgICAgICAgICAgICAgICBpZiAoYiA8IGNsaXBBeGlzMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJzZWN0KGNsaXBwZWQsIGF4LCBheSwgYngsIGJ5LCBjbGlwQXhpczIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY2xpcHBlZC5wdXNoKHJpbmdbaV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoYiA8IGNsaXBBeGlzMSAmJiBhID49IGNsaXBBeGlzMSkge1xuICAgICAgICAgICAgICAgICAgICBpbnRlcnNlY3QoY2xpcHBlZCwgYXgsIGF5LCBieCwgYnksIGNsaXBBeGlzMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChiID4gY2xpcEF4aXMyICYmIGEgPD0gY2xpcEF4aXMyKSB7XG4gICAgICAgICAgICAgICAgICAgIGludGVyc2VjdChjbGlwcGVkLCBheCwgYXksIGJ4LCBieSwgY2xpcEF4aXMyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBsYXN0ID0gcmluZ1tyaW5nLmxlbmd0aCAtIDFdO1xuICAgICAgICAgICAgY29uc3QgYSA9IGF4aXMgPT09IDAgPyBsYXN0LnggOiBsYXN0Lnk7XG4gICAgICAgICAgICBpZiAoYSA+PSBjbGlwQXhpczEgJiYgYSA8PSBjbGlwQXhpczIpIHtcbiAgICAgICAgICAgICAgICBjbGlwcGVkLnB1c2gobGFzdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY2xpcHBlZC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBsYXN0ID0gY2xpcHBlZFtjbGlwcGVkLmxlbmd0aCAtIDFdO1xuICAgICAgICAgICAgICAgIGlmIChjbGlwcGVkWzBdLnggIT09IGxhc3QueCB8fCBjbGlwcGVkWzBdLnkgIT09IGxhc3QueSkge1xuICAgICAgICAgICAgICAgICAgICBjbGlwcGVkLnB1c2goY2xpcHBlZFswXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHBvbHlnb25DbGlwcGVkLnB1c2goY2xpcHBlZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBvbHlnb25DbGlwcGVkLmxlbmd0aCkge1xuICAgICAgICAgICAgcG9seWdvbnNDbGlwcGVkLnB1c2gocG9seWdvbkNsaXBwZWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHBvbHlnb25zQ2xpcHBlZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHN1YmRpdmlkZVBvbHlnb25zKHBvbHlnb25zOiBQb2x5Z29uQXJyYXksIGJvdW5kczogW1BvaW50LCBQb2ludF0sIGdyaWRTaXplWDogbnVtYmVyLCBncmlkU2l6ZVk6IG51bWJlciwgcGFkZGluZzogbnVtYmVyID0gMC4wLCBzcGxpdEZuOiBGdW5jdGlvbik6IEFycmF5PENsaXBwZWRQb2x5Z29uPiB7XG4gICAgY29uc3Qgb3V0UG9seWdvbnMgPSBbXTtcblxuICAgIGlmICghcG9seWdvbnMubGVuZ3RoIHx8ICFncmlkU2l6ZVggfHwgIWdyaWRTaXplWSkge1xuICAgICAgICByZXR1cm4gb3V0UG9seWdvbnM7XG4gICAgfVxuXG4gICAgY29uc3QgYWRkUmVzdWx0ID0gKGNsaXBwZWQ6IFBvbHlnb25BcnJheSwgYm91bmRzOiBbUG9pbnQsIFBvaW50XSkgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IHBvbHlnb24gb2YgY2xpcHBlZCkge1xuICAgICAgICAgICAgb3V0UG9seWdvbnMucHVzaCh7cG9seWdvbiwgYm91bmRzfSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgY29uc3QgaFNwbGl0cyA9IE1hdGguY2VpbChNYXRoLmxvZzIoZ3JpZFNpemVYKSk7XG4gICAgY29uc3QgdlNwbGl0cyA9IE1hdGguY2VpbChNYXRoLmxvZzIoZ3JpZFNpemVZKSk7XG5cbiAgICBjb25zdCBpbml0aWFsU3BsaXRzID0gaFNwbGl0cyAtIHZTcGxpdHM7XG5cbiAgICBjb25zdCBzcGxpdHMgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IE1hdGguYWJzKGluaXRpYWxTcGxpdHMpOyBpKyspIHtcbiAgICAgICAgc3BsaXRzLnB1c2goaW5pdGlhbFNwbGl0cyA+IDAgPyAwIDogMSk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBNYXRoLm1pbihoU3BsaXRzLCB2U3BsaXRzKTsgaSsrKSB7XG4gICAgICAgIHNwbGl0cy5wdXNoKDApOyAvLyB4XG4gICAgICAgIHNwbGl0cy5wdXNoKDEpOyAvLyB5XG4gICAgfVxuXG4gICAgbGV0IHNwbGl0ID0gcG9seWdvbnM7XG5cbiAgICBzcGxpdCA9IGNsaXBQb2x5Z29uKHNwbGl0LCBib3VuZHNbMF0ueSAtIHBhZGRpbmcsIGJvdW5kc1sxXS55ICsgcGFkZGluZywgMSk7XG4gICAgc3BsaXQgPSBjbGlwUG9seWdvbihzcGxpdCwgYm91bmRzWzBdLnggLSBwYWRkaW5nLCBib3VuZHNbMV0ueCArIHBhZGRpbmcsIDApO1xuXG4gICAgaWYgKCFzcGxpdC5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIG91dFBvbHlnb25zO1xuICAgIH1cblxuICAgIGNvbnN0IHN0YWNrID0gW107XG4gICAgaWYgKHNwbGl0cy5sZW5ndGgpIHtcbiAgICAgICAgc3RhY2sucHVzaCh7cG9seWdvbnM6IHNwbGl0LCBib3VuZHMsIGRlcHRoOiAwfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgYWRkUmVzdWx0KHNwbGl0LCBib3VuZHMpO1xuICAgIH1cblxuICAgIHdoaWxlIChzdGFjay5sZW5ndGgpIHtcbiAgICAgICAgY29uc3QgZnJhbWUgPSBzdGFjay5wb3AoKTtcblxuICAgICAgICBhc3NlcnQoZnJhbWUucG9seWdvbnMubGVuZ3RoID4gMCk7XG5cbiAgICAgICAgY29uc3QgZGVwdGggPSBmcmFtZS5kZXB0aDtcbiAgICAgICAgY29uc3QgYXhpcyA9IHNwbGl0c1tkZXB0aF07XG5cbiAgICAgICAgY29uc3QgYmJveE1pbiA9IGZyYW1lLmJvdW5kc1swXTtcbiAgICAgICAgY29uc3QgYmJveE1heCA9IGZyYW1lLmJvdW5kc1sxXTtcblxuICAgICAgICBjb25zdCBzcGxpdE1pbiA9IGF4aXMgPT09IDAgPyBiYm94TWluLnggOiBiYm94TWluLnk7XG4gICAgICAgIGNvbnN0IHNwbGl0TWF4ID0gYXhpcyA9PT0gMCA/IGJib3hNYXgueCA6IGJib3hNYXgueTtcblxuICAgICAgICBjb25zdCBzcGxpdE1pZCA9IHNwbGl0Rm4gPyBzcGxpdEZuKGF4aXMsIHNwbGl0TWluLCBzcGxpdE1heCkgOiAwLjUgKiAoc3BsaXRNaW4gKyBzcGxpdE1heCk7XG5cbiAgICAgICAgY29uc3QgbGNsaXAgPSBjbGlwUG9seWdvbihmcmFtZS5wb2x5Z29ucywgc3BsaXRNaW4gLSBwYWRkaW5nLCBzcGxpdE1pZCArIHBhZGRpbmcsIGF4aXMpO1xuICAgICAgICBjb25zdCByY2xpcCA9IGNsaXBQb2x5Z29uKGZyYW1lLnBvbHlnb25zLCBzcGxpdE1pZCAtIHBhZGRpbmcsIHNwbGl0TWF4ICsgcGFkZGluZywgYXhpcyk7XG5cbiAgICAgICAgaWYgKGxjbGlwLmxlbmd0aCkge1xuICAgICAgICAgICAgY29uc3QgYmJNYXhYID0gYXhpcyA9PT0gMCA/IHNwbGl0TWlkIDogYmJveE1heC54O1xuICAgICAgICAgICAgY29uc3QgYmJNYXhZID0gYXhpcyA9PT0gMSA/IHNwbGl0TWlkIDogYmJveE1heC55O1xuXG4gICAgICAgICAgICBjb25zdCBiYk1heCA9IG5ldyBQb2ludChiYk1heFgsIGJiTWF4WSk7XG5cbiAgICAgICAgICAgIGNvbnN0IGxjbGlwQm91bmRzID0gW2Jib3hNaW4sIGJiTWF4XTtcblxuICAgICAgICAgICAgaWYgKHNwbGl0cy5sZW5ndGggPiBkZXB0aCArIDEpIHtcbiAgICAgICAgICAgICAgICBzdGFjay5wdXNoKHtwb2x5Z29uczogbGNsaXAsIGJvdW5kczogbGNsaXBCb3VuZHMsIGRlcHRoOiBkZXB0aCArIDF9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYWRkUmVzdWx0KGxjbGlwLCBsY2xpcEJvdW5kcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmNsaXAubGVuZ3RoKSB7XG4gICAgICAgICAgICBjb25zdCBiYk1pblggPSBheGlzID09PSAwID8gc3BsaXRNaWQgOiBiYm94TWluLng7XG4gICAgICAgICAgICBjb25zdCBiYk1pblkgPSBheGlzID09PSAxID8gc3BsaXRNaWQgOiBiYm94TWluLnk7XG5cbiAgICAgICAgICAgIGNvbnN0IGJiTWluID0gbmV3IFBvaW50KGJiTWluWCwgYmJNaW5ZKTtcblxuICAgICAgICAgICAgY29uc3QgcmNsaXBCb3VuZHMgPSBbYmJNaW4sIGJib3hNYXhdO1xuXG4gICAgICAgICAgICBpZiAoc3BsaXRzLmxlbmd0aCA+IGRlcHRoICsgMSkge1xuICAgICAgICAgICAgICAgIHN0YWNrLnB1c2goe3BvbHlnb25zOiByY2xpcCwgYm91bmRzOiByY2xpcEJvdW5kcywgZGVwdGg6IGRlcHRoICsgMX0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBhZGRSZXN1bHQocmNsaXAsIHJjbGlwQm91bmRzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvdXRQb2x5Z29ucztcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCB7RmlsbEV4dHJ1c2lvbkxheW91dEFycmF5LCBGaWxsRXh0cnVzaW9uRXh0QXJyYXksIEZpbGxFeHRydXNpb25DZW50cm9pZEFycmF5fSBmcm9tICcuLi9hcnJheV90eXBlcy5qcyc7XG5cbmltcG9ydCB7bWVtYmVycyBhcyBsYXlvdXRBdHRyaWJ1dGVzLCBjZW50cm9pZEF0dHJpYnV0ZXMsIGZpbGxFeHRydXNpb25BdHRyaWJ1dGVzRXh0fSBmcm9tICcuL2ZpbGxfZXh0cnVzaW9uX2F0dHJpYnV0ZXMuanMnO1xuaW1wb3J0IFNlZ21lbnRWZWN0b3IgZnJvbSAnLi4vc2VnbWVudC5qcyc7XG5pbXBvcnQge1Byb2dyYW1Db25maWd1cmF0aW9uU2V0fSBmcm9tICcuLi9wcm9ncmFtX2NvbmZpZ3VyYXRpb24uanMnO1xuaW1wb3J0IHtUcmlhbmdsZUluZGV4QXJyYXl9IGZyb20gJy4uL2luZGV4X2FycmF5X3R5cGUuanMnO1xuaW1wb3J0IEVYVEVOVCBmcm9tICcuLi9leHRlbnQuanMnO1xuaW1wb3J0IGVhcmN1dCBmcm9tICdlYXJjdXQnO1xuaW1wb3J0IHtWZWN0b3JUaWxlRmVhdHVyZX0gZnJvbSAnQG1hcGJveC92ZWN0b3ItdGlsZSc7XG5jb25zdCB2ZWN0b3JUaWxlRmVhdHVyZVR5cGVzID0gVmVjdG9yVGlsZUZlYXR1cmUudHlwZXM7XG5pbXBvcnQgY2xhc3NpZnlSaW5ncyBmcm9tICcuLi8uLi91dGlsL2NsYXNzaWZ5X3JpbmdzLmpzJztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmNvbnN0IEVBUkNVVF9NQVhfUklOR1MgPSA1MDA7XG5pbXBvcnQge3JlZ2lzdGVyfSBmcm9tICcuLi8uLi91dGlsL3dlYl93b3JrZXJfdHJhbnNmZXIuanMnO1xuaW1wb3J0IHtoYXNQYXR0ZXJuLCBhZGRQYXR0ZXJuRGVwZW5kZW5jaWVzfSBmcm9tICcuL3BhdHRlcm5fYnVja2V0X2ZlYXR1cmVzLmpzJztcbmltcG9ydCBsb2FkR2VvbWV0cnkgZnJvbSAnLi4vbG9hZF9nZW9tZXRyeS5qcyc7XG5pbXBvcnQgdG9FdmFsdWF0aW9uRmVhdHVyZSBmcm9tICcuLi9ldmFsdWF0aW9uX2ZlYXR1cmUuanMnO1xuaW1wb3J0IEV2YWx1YXRpb25QYXJhbWV0ZXJzIGZyb20gJy4uLy4uL3N0eWxlL2V2YWx1YXRpb25fcGFyYW1ldGVycy5qcyc7XG5pbXBvcnQgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5pbXBvcnQge251bWJlciBhcyBpbnRlcnBvbGF0ZX0gZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy91dGlsL2ludGVycG9sYXRlLmpzJztcbmltcG9ydCB7bG5nRnJvbU1lcmNhdG9yWCwgbGF0RnJvbU1lcmNhdG9yWSwgbWVyY2F0b3JZZnJvbUxhdH0gZnJvbSAnLi4vLi4vZ2VvL21lcmNhdG9yX2Nvb3JkaW5hdGUuanMnO1xuaW1wb3J0IHtzdWJkaXZpZGVQb2x5Z29uc30gZnJvbSAnLi4vLi4vdXRpbC9wb2x5Z29uX2NsaXBwaW5nLmpzJztcbmltcG9ydCB0eXBlIHtDbGlwcGVkUG9seWdvbn0gZnJvbSAnLi4vLi4vdXRpbC9wb2x5Z29uX2NsaXBwaW5nLmpzJztcbmltcG9ydCB0eXBlIHtWZWMzfSBmcm9tICdnbC1tYXRyaXgnO1xuaW1wb3J0IHR5cGUge0Nhbm9uaWNhbFRpbGVJRH0gZnJvbSAnLi4vLi4vc291cmNlL3RpbGVfaWQuanMnO1xuaW1wb3J0IHR5cGUge1xuICAgIEJ1Y2tldCxcbiAgICBCdWNrZXRQYXJhbWV0ZXJzLFxuICAgIEJ1Y2tldEZlYXR1cmUsXG4gICAgSW5kZXhlZEZlYXR1cmUsXG4gICAgUG9wdWxhdGVQYXJhbWV0ZXJzXG59IGZyb20gJy4uL2J1Y2tldC5qcyc7XG5pbXBvcnQge2VhcnRoUmFkaXVzfSBmcm9tICcuLi8uLi9nZW8vbG5nX2xhdC5qcyc7XG5cbmltcG9ydCB0eXBlIEZpbGxFeHRydXNpb25TdHlsZUxheWVyIGZyb20gJy4uLy4uL3N0eWxlL3N0eWxlX2xheWVyL2ZpbGxfZXh0cnVzaW9uX3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCB0eXBlIENvbnRleHQgZnJvbSAnLi4vLi4vZ2wvY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSBJbmRleEJ1ZmZlciBmcm9tICcuLi8uLi9nbC9pbmRleF9idWZmZXIuanMnO1xuaW1wb3J0IHR5cGUgVmVydGV4QnVmZmVyIGZyb20gJy4uLy4uL2dsL3ZlcnRleF9idWZmZXIuanMnO1xuaW1wb3J0IHR5cGUge0ZlYXR1cmVTdGF0ZXN9IGZyb20gJy4uLy4uL3NvdXJjZS9zb3VyY2Vfc3RhdGUuanMnO1xuaW1wb3J0IHR5cGUge1Nwcml0ZVBvc2l0aW9uc30gZnJvbSAnLi4vLi4vdXRpbC9pbWFnZS5qcyc7XG5pbXBvcnQgdHlwZSB7UHJvamVjdGlvblNwZWNpZmljYXRpb259IGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge1RpbGVUcmFuc2Zvcm19IGZyb20gJy4uLy4uL2dlby9wcm9qZWN0aW9uL3RpbGVfdHJhbnNmb3JtLmpzJztcbmltcG9ydCB0eXBlIHtJVmVjdG9yVGlsZUxheWVyfSBmcm9tICdAbWFwYm94L3ZlY3Rvci10aWxlJztcblxuY29uc3QgRkFDVE9SID0gTWF0aC5wb3coMiwgMTMpO1xuXG4vLyBBbHNvIGRlY2xhcmVkIGluIF9wcmVsdWRlX3RlcnJhaW4udmVydGV4Lmdsc2xcbi8vIFVzZWQgdG8gc2NhbGUgbW9zdCBsaWtlbHkgZWxldmF0aW9uIHZhbHVlcyB0byBmaXQgd2VsbCBpbiBhbiB1aW50MTZcbi8vIChFbGV2YXRpb24gb2YgRGVhZCBTZWEgKyBFTEVWQVRJT05fT0ZGU0VUKSAqIEVMRVZBVElPTl9TQ0FMRSBpcyByb3VnaGx5IDBcbi8vIChIZWlnaHQgb2YgbXQgZXZlcmVzdCArIEVMRVZBVElPTl9PRkZTRVQpICogRUxFVkFUSU9OX1NDQUxFIGlzIHJvdWdobHkgNjRrXG5leHBvcnQgY29uc3QgRUxFVkFUSU9OX1NDQUxFID0gNy4wO1xuZXhwb3J0IGNvbnN0IEVMRVZBVElPTl9PRkZTRVQgPSA0NTA7XG5cbmZ1bmN0aW9uIGFkZFZlcnRleCh2ZXJ0ZXhBcnJheTogRmlsbEV4dHJ1c2lvbkxheW91dEFycmF5LCB4OiBudW1iZXIsIHk6IG51bWJlciwgbnhSYXRpbzogbnVtYmVyLCBueVNpZ246IG51bWJlciwgbm9ybWFsVXA6IG51bWJlciwgdG9wOiBudW1iZXIsIGU6IG51bWJlcikge1xuICAgIHZlcnRleEFycmF5LmVtcGxhY2VCYWNrKFxuICAgICAgICAvLyBhX3Bvc19ub3JtYWxfZWQ6XG4gICAgICAgIC8vIEVuY29kZSB0b3AgYW5kIHNpZGUvdXAgbm9ybWFsIHVzaW5nIHRoZSBsZWFzdCBzaWduaWZpY2FudCBiaXRzXG4gICAgICAgICh4IDw8IDEpICsgdG9wLFxuICAgICAgICAoeSA8PCAxKSArIG5vcm1hbFVwLFxuICAgICAgICAvLyBkeGR5IGlzIHNpZ25lZCwgZW5jb2RlIHF1YWRyYW50IGluZm8gdXNpbmcgdGhlIGxlYXN0IHNpZ25pZmljYW50IGJpdFxuICAgICAgICAoTWF0aC5mbG9vcihueFJhdGlvICogRkFDVE9SKSA8PCAxKSArIG55U2lnbixcbiAgICAgICAgLy8gZWRnZWRpc3RhbmNlICh1c2VkIGZvciB3cmFwcGluZyBwYXR0ZXJucyBhcm91bmQgZXh0cnVzaW9uIHNpZGVzKVxuICAgICAgICBNYXRoLnJvdW5kKGUpXG4gICAgKTtcbn1cblxuZnVuY3Rpb24gYWRkR2xvYmVFeHRWZXJ0ZXgodmVydGV4QXJyYXk6IEZpbGxFeHRydXNpb25FeHRBcnJheSwgcG9zOiB7eDogbnVtYmVyLCB5OiBudW1iZXIsIHo6IG51bWJlcn0sIG5vcm1hbDogVmVjMykge1xuICAgIGNvbnN0IGVuY29kZSA9IDEgPDwgMTQ7XG4gICAgdmVydGV4QXJyYXkuZW1wbGFjZUJhY2soXG4gICAgICAgIHBvcy54LCBwb3MueSwgcG9zLnosXG4gICAgICAgIG5vcm1hbFswXSAqIGVuY29kZSwgbm9ybWFsWzFdICogZW5jb2RlLCBub3JtYWxbMl0gKiBlbmNvZGUpO1xufVxuXG5leHBvcnQgY2xhc3MgUGFydE1ldGFkYXRhIHtcbiAgICBhY2M6IFBvaW50O1xuICAgIG1pbjogUG9pbnQ7XG4gICAgbWF4OiBQb2ludDtcbiAgICBwb2x5Q291bnQ6IEFycmF5PHtlZGdlczogbnVtYmVyLCB0b3A6IG51bWJlcn0+O1xuICAgIGN1cnJlbnRQb2x5Q291bnQ6IHtlZGdlczogbnVtYmVyLCB0b3A6IG51bWJlcn07XG4gICAgYm9yZGVyczogQXJyYXk8W251bWJlciwgbnVtYmVyXT47IC8vIEFycmF5PFttaW4sIG1heF0+XG4gICAgdmVydGV4QXJyYXlPZmZzZXQ6IG51bWJlcjtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLmFjYyA9IG5ldyBQb2ludCgwLCAwKTtcbiAgICAgICAgdGhpcy5wb2x5Q291bnQgPSBbXTtcbiAgICB9XG5cbiAgICBzdGFydFJpbmcocDogUG9pbnQpIHtcbiAgICAgICAgdGhpcy5jdXJyZW50UG9seUNvdW50ID0ge2VkZ2VzOiAwLCB0b3A6IDB9O1xuICAgICAgICB0aGlzLnBvbHlDb3VudC5wdXNoKHRoaXMuY3VycmVudFBvbHlDb3VudCk7XG4gICAgICAgIGlmICh0aGlzLm1pbikgcmV0dXJuO1xuICAgICAgICB0aGlzLm1pbiA9IG5ldyBQb2ludChwLngsIHAueSk7XG4gICAgICAgIHRoaXMubWF4ID0gbmV3IFBvaW50KHAueCwgcC55KTtcbiAgICB9XG5cbiAgICBhcHBlbmQocDogUG9pbnQsIHByZXY6IFBvaW50KSB7XG4gICAgICAgIHRoaXMuY3VycmVudFBvbHlDb3VudC5lZGdlcysrO1xuXG4gICAgICAgIHRoaXMuYWNjLl9hZGQocCk7XG4gICAgICAgIGNvbnN0IG1pbiA9IHRoaXMubWluLCBtYXggPSB0aGlzLm1heDtcbiAgICAgICAgaWYgKHAueCA8IG1pbi54KSB7XG4gICAgICAgICAgICBtaW4ueCA9IHAueDtcbiAgICAgICAgfSBlbHNlIGlmIChwLnggPiBtYXgueCkge1xuICAgICAgICAgICAgbWF4LnggPSBwLng7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHAueSA8IG1pbi55KSB7XG4gICAgICAgICAgICBtaW4ueSA9IHAueTtcbiAgICAgICAgfSBlbHNlIGlmIChwLnkgPiBtYXgueSkge1xuICAgICAgICAgICAgbWF4LnkgPSBwLnk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCgocC54ID09PSAwIHx8IHAueCA9PT0gRVhURU5UKSAmJiBwLnggPT09IHByZXYueCkgIT09ICgocC55ID09PSAwIHx8IHAueSA9PT0gRVhURU5UKSAmJiBwLnkgPT09IHByZXYueSkpIHtcbiAgICAgICAgICAgIC8vIEN1c3RvbSBkZWZpbmVkIGdlb2pzb24gYnVpbGRpbmdzIGFyZSBjdXQgb24gYm9yZGVycy4gUG9pbnRzIGFyZVxuICAgICAgICAgICAgLy8gcmVwZWF0ZWQgd2hlbiBlZGdlIGN1dHMgdGlsZSBjb3JuZXIgKHJlYXNvbiBmb3IgdXNpbmcgeG9yKS5cbiAgICAgICAgICAgIHRoaXMucHJvY2Vzc0JvcmRlck92ZXJsYXAocCwgcHJldik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gY2hlY2sgYm9yZGVyIGludGVyc2VjdGlvblxuICAgICAgICBpZiAoKHByZXYueCA8IDApICE9PSAocC54IDwgMCkpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkQm9yZGVySW50ZXJzZWN0aW9uKDAsIGludGVycG9sYXRlKHByZXYueSwgcC55LCAoMCAtIHByZXYueCkgLyAocC54IC0gcHJldi54KSkpO1xuICAgICAgICB9XG4gICAgICAgIGlmICgocHJldi54ID4gRVhURU5UKSAhPT0gKHAueCA+IEVYVEVOVCkpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkQm9yZGVySW50ZXJzZWN0aW9uKDEsIGludGVycG9sYXRlKHByZXYueSwgcC55LCAoRVhURU5UIC0gcHJldi54KSAvIChwLnggLSBwcmV2LngpKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKChwcmV2LnkgPCAwKSAhPT0gKHAueSA8IDApKSB7XG4gICAgICAgICAgICB0aGlzLmFkZEJvcmRlckludGVyc2VjdGlvbigyLCBpbnRlcnBvbGF0ZShwcmV2LngsIHAueCwgKDAgLSBwcmV2LnkpIC8gKHAueSAtIHByZXYueSkpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoKHByZXYueSA+IEVYVEVOVCkgIT09IChwLnkgPiBFWFRFTlQpKSB7XG4gICAgICAgICAgICB0aGlzLmFkZEJvcmRlckludGVyc2VjdGlvbigzLCBpbnRlcnBvbGF0ZShwcmV2LngsIHAueCwgKEVYVEVOVCAtIHByZXYueSkgLyAocC55IC0gcHJldi55KSkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYWRkQm9yZGVySW50ZXJzZWN0aW9uKGluZGV4OiAwIHwgMSB8IDIgfCAzLCBpOiBudW1iZXIpIHtcbiAgICAgICAgaWYgKCF0aGlzLmJvcmRlcnMpIHtcbiAgICAgICAgICAgIHRoaXMuYm9yZGVycyA9IFtcbiAgICAgICAgICAgICAgICBbTnVtYmVyLk1BWF9WQUxVRSwgLU51bWJlci5NQVhfVkFMVUVdLFxuICAgICAgICAgICAgICAgIFtOdW1iZXIuTUFYX1ZBTFVFLCAtTnVtYmVyLk1BWF9WQUxVRV0sXG4gICAgICAgICAgICAgICAgW051bWJlci5NQVhfVkFMVUUsIC1OdW1iZXIuTUFYX1ZBTFVFXSxcbiAgICAgICAgICAgICAgICBbTnVtYmVyLk1BWF9WQUxVRSwgLU51bWJlci5NQVhfVkFMVUVdXG4gICAgICAgICAgICBdO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGIgPSB0aGlzLmJvcmRlcnNbaW5kZXhdO1xuICAgICAgICBpZiAoaSA8IGJbMF0pIGJbMF0gPSBpO1xuICAgICAgICBpZiAoaSA+IGJbMV0pIGJbMV0gPSBpO1xuICAgIH1cblxuICAgIHByb2Nlc3NCb3JkZXJPdmVybGFwKHA6IFBvaW50LCBwcmV2OiBQb2ludCkge1xuICAgICAgICBpZiAocC54ID09PSBwcmV2LngpIHtcbiAgICAgICAgICAgIGlmIChwLnkgPT09IHByZXYueSkgcmV0dXJuOyAvLyBjdXN0b20gZGVmaW5lZCBnZW9qc29uIGNvdWxkIGhhdmUgcG9pbnRzIHJlcGVhdGVkLlxuICAgICAgICAgICAgY29uc3QgaW5kZXggPSBwLnggPT09IDAgPyAwIDogMTtcbiAgICAgICAgICAgIHRoaXMuYWRkQm9yZGVySW50ZXJzZWN0aW9uKGluZGV4LCBwcmV2LnkpO1xuICAgICAgICAgICAgdGhpcy5hZGRCb3JkZXJJbnRlcnNlY3Rpb24oaW5kZXgsIHAueSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhc3NlcnQocC55ID09PSBwcmV2LnkpO1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSBwLnkgPT09IDAgPyAyIDogMztcbiAgICAgICAgICAgIHRoaXMuYWRkQm9yZGVySW50ZXJzZWN0aW9uKGluZGV4LCBwcmV2LngpO1xuICAgICAgICAgICAgdGhpcy5hZGRCb3JkZXJJbnRlcnNlY3Rpb24oaW5kZXgsIHAueCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjZW50cm9pZCgpOiBQb2ludCB7XG4gICAgICAgIGNvbnN0IGNvdW50ID0gdGhpcy5wb2x5Q291bnQucmVkdWNlKChhY2MsIHApID0+IGFjYyArIHAuZWRnZXMsIDApO1xuICAgICAgICByZXR1cm4gY291bnQgIT09IDAgPyB0aGlzLmFjYy5kaXYoY291bnQpLl9yb3VuZCgpIDogbmV3IFBvaW50KDAsIDApO1xuICAgIH1cblxuICAgIHNwYW4oKTogUG9pbnQge1xuICAgICAgICByZXR1cm4gbmV3IFBvaW50KHRoaXMubWF4LnggLSB0aGlzLm1pbi54LCB0aGlzLm1heC55IC0gdGhpcy5taW4ueSk7XG4gICAgfVxuXG4gICAgaW50ZXJzZWN0c0NvdW50KCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLmJvcmRlcnMucmVkdWNlKChhY2MsIHApID0+IGFjYyArICsocFswXSAhPT0gTnVtYmVyLk1BWF9WQUxVRSksIDApO1xuICAgIH1cbn1cblxuY2xhc3MgRmlsbEV4dHJ1c2lvbkJ1Y2tldCBpbXBsZW1lbnRzIEJ1Y2tldCB7XG4gICAgaW5kZXg6IG51bWJlcjtcbiAgICB6b29tOiBudW1iZXI7XG4gICAgY2Fub25pY2FsOiBDYW5vbmljYWxUaWxlSUQ7XG4gICAgb3ZlcnNjYWxpbmc6IG51bWJlcjtcbiAgICBlbmFibGVUZXJyYWluOiBib29sZWFuO1xuICAgIGxheWVyczogQXJyYXk8RmlsbEV4dHJ1c2lvblN0eWxlTGF5ZXI+O1xuICAgIGxheWVySWRzOiBBcnJheTxzdHJpbmc+O1xuICAgIHN0YXRlRGVwZW5kZW50TGF5ZXJzOiBBcnJheTxGaWxsRXh0cnVzaW9uU3R5bGVMYXllcj47XG4gICAgc3RhdGVEZXBlbmRlbnRMYXllcklkczogQXJyYXk8c3RyaW5nPjtcblxuICAgIGxheW91dFZlcnRleEFycmF5OiBGaWxsRXh0cnVzaW9uTGF5b3V0QXJyYXk7XG4gICAgbGF5b3V0VmVydGV4QnVmZmVyOiBWZXJ0ZXhCdWZmZXI7XG5cbiAgICBjZW50cm9pZFZlcnRleEFycmF5OiBGaWxsRXh0cnVzaW9uQ2VudHJvaWRBcnJheTtcbiAgICBjZW50cm9pZFZlcnRleEJ1ZmZlcjogVmVydGV4QnVmZmVyO1xuXG4gICAgbGF5b3V0VmVydGV4RXh0QXJyYXk6ID9GaWxsRXh0cnVzaW9uRXh0QXJyYXk7XG4gICAgbGF5b3V0VmVydGV4RXh0QnVmZmVyOiA/VmVydGV4QnVmZmVyO1xuXG4gICAgaW5kZXhBcnJheTogVHJpYW5nbGVJbmRleEFycmF5O1xuICAgIGluZGV4QnVmZmVyOiBJbmRleEJ1ZmZlcjtcblxuICAgIGhhc1BhdHRlcm46IGJvb2xlYW47XG4gICAgZWRnZVJhZGl1czogbnVtYmVyO1xuICAgIHByb2dyYW1Db25maWd1cmF0aW9uczogUHJvZ3JhbUNvbmZpZ3VyYXRpb25TZXQ8RmlsbEV4dHJ1c2lvblN0eWxlTGF5ZXI+O1xuICAgIHNlZ21lbnRzOiBTZWdtZW50VmVjdG9yO1xuICAgIHVwbG9hZGVkOiBib29sZWFuO1xuICAgIGZlYXR1cmVzOiBBcnJheTxCdWNrZXRGZWF0dXJlPjtcblxuICAgIGZlYXR1cmVzT25Cb3JkZXI6IEFycmF5PFBhcnRNZXRhZGF0YT47XG4gICAgLy8gYm9yZGVycyAvIGJvcmRlckRvbmVXaXRoTmVpZ2hib3JaOiAwIC0gbGVmdCwgMSwgcmlnaHQsIDIgLSB0b3AsIDMgLSBib3R0b21cbiAgICBib3JkZXJzOiBBcnJheTxBcnJheTxudW1iZXI+PjsgLy8gRm9yIGVhY2ggc2lkZSwgaW5kaWNlcyBpbnRvIGZlYXR1cmVzT25Cb3JkZXIgYXJyYXkuXG4gICAgYm9yZGVyRG9uZVdpdGhOZWlnaGJvclo6IEFycmF5PG51bWJlcj47XG4gICAgbmVlZHNDZW50cm9pZFVwZGF0ZTogYm9vbGVhbjtcbiAgICB0aWxlVG9NZXRlcjogbnVtYmVyOyAvLyBjYWNoZSBjb252ZXJzaW9uLlxuICAgIHByb2plY3Rpb246IFByb2plY3Rpb25TcGVjaWZpY2F0aW9uO1xuXG4gICAgY29uc3RydWN0b3Iob3B0aW9uczogQnVja2V0UGFyYW1ldGVyczxGaWxsRXh0cnVzaW9uU3R5bGVMYXllcj4pIHtcbiAgICAgICAgdGhpcy56b29tID0gb3B0aW9ucy56b29tO1xuICAgICAgICB0aGlzLmNhbm9uaWNhbCA9IG9wdGlvbnMuY2Fub25pY2FsO1xuICAgICAgICB0aGlzLm92ZXJzY2FsaW5nID0gb3B0aW9ucy5vdmVyc2NhbGluZztcbiAgICAgICAgdGhpcy5sYXllcnMgPSBvcHRpb25zLmxheWVycztcbiAgICAgICAgdGhpcy5sYXllcklkcyA9IHRoaXMubGF5ZXJzLm1hcChsYXllciA9PiBsYXllci5pZCk7XG4gICAgICAgIHRoaXMuaW5kZXggPSBvcHRpb25zLmluZGV4O1xuICAgICAgICB0aGlzLmhhc1BhdHRlcm4gPSBmYWxzZTtcbiAgICAgICAgdGhpcy5lZGdlUmFkaXVzID0gMDtcbiAgICAgICAgdGhpcy5wcm9qZWN0aW9uID0gb3B0aW9ucy5wcm9qZWN0aW9uO1xuXG4gICAgICAgIHRoaXMubGF5b3V0VmVydGV4QXJyYXkgPSBuZXcgRmlsbEV4dHJ1c2lvbkxheW91dEFycmF5KCk7XG4gICAgICAgIHRoaXMuY2VudHJvaWRWZXJ0ZXhBcnJheSA9IG5ldyBGaWxsRXh0cnVzaW9uQ2VudHJvaWRBcnJheSgpO1xuICAgICAgICB0aGlzLmluZGV4QXJyYXkgPSBuZXcgVHJpYW5nbGVJbmRleEFycmF5KCk7XG4gICAgICAgIHRoaXMucHJvZ3JhbUNvbmZpZ3VyYXRpb25zID0gbmV3IFByb2dyYW1Db25maWd1cmF0aW9uU2V0KG9wdGlvbnMubGF5ZXJzLCBvcHRpb25zLnpvb20pO1xuICAgICAgICB0aGlzLnNlZ21lbnRzID0gbmV3IFNlZ21lbnRWZWN0b3IoKTtcbiAgICAgICAgdGhpcy5zdGF0ZURlcGVuZGVudExheWVySWRzID0gdGhpcy5sYXllcnMuZmlsdGVyKChsKSA9PiBsLmlzU3RhdGVEZXBlbmRlbnQoKSkubWFwKChsKSA9PiBsLmlkKTtcbiAgICAgICAgdGhpcy5lbmFibGVUZXJyYWluID0gb3B0aW9ucy5lbmFibGVUZXJyYWluO1xuICAgIH1cblxuICAgIHBvcHVsYXRlKGZlYXR1cmVzOiBBcnJheTxJbmRleGVkRmVhdHVyZT4sIG9wdGlvbnM6IFBvcHVsYXRlUGFyYW1ldGVycywgY2Fub25pY2FsOiBDYW5vbmljYWxUaWxlSUQsIHRpbGVUcmFuc2Zvcm06IFRpbGVUcmFuc2Zvcm0pIHtcbiAgICAgICAgdGhpcy5mZWF0dXJlcyA9IFtdO1xuICAgICAgICB0aGlzLmhhc1BhdHRlcm4gPSBoYXNQYXR0ZXJuKCdmaWxsLWV4dHJ1c2lvbicsIHRoaXMubGF5ZXJzLCBvcHRpb25zKTtcbiAgICAgICAgdGhpcy5mZWF0dXJlc09uQm9yZGVyID0gW107XG4gICAgICAgIHRoaXMuYm9yZGVycyA9IFtbXSwgW10sIFtdLCBbXV07XG4gICAgICAgIHRoaXMuYm9yZGVyRG9uZVdpdGhOZWlnaGJvclogPSBbLTEsIC0xLCAtMSwgLTFdO1xuICAgICAgICB0aGlzLnRpbGVUb01ldGVyID0gdGlsZVRvTWV0ZXIoY2Fub25pY2FsKTtcbiAgICAgICAgdGhpcy5lZGdlUmFkaXVzID0gdGhpcy5sYXllcnNbMF0ubGF5b3V0LmdldCgnZmlsbC1leHRydXNpb24tZWRnZS1yYWRpdXMnKSAvIHRoaXMudGlsZVRvTWV0ZXI7XG5cbiAgICAgICAgZm9yIChjb25zdCB7ZmVhdHVyZSwgaWQsIGluZGV4LCBzb3VyY2VMYXllckluZGV4fSBvZiBmZWF0dXJlcykge1xuICAgICAgICAgICAgY29uc3QgbmVlZEdlb21ldHJ5ID0gdGhpcy5sYXllcnNbMF0uX2ZlYXR1cmVGaWx0ZXIubmVlZEdlb21ldHJ5O1xuICAgICAgICAgICAgY29uc3QgZXZhbHVhdGlvbkZlYXR1cmUgPSB0b0V2YWx1YXRpb25GZWF0dXJlKGZlYXR1cmUsIG5lZWRHZW9tZXRyeSk7XG5cbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIGlmICghdGhpcy5sYXllcnNbMF0uX2ZlYXR1cmVGaWx0ZXIuZmlsdGVyKG5ldyBFdmFsdWF0aW9uUGFyYW1ldGVycyh0aGlzLnpvb20pLCBldmFsdWF0aW9uRmVhdHVyZSwgY2Fub25pY2FsKSkgY29udGludWU7XG5cbiAgICAgICAgICAgIGNvbnN0IGJ1Y2tldEZlYXR1cmU6IEJ1Y2tldEZlYXR1cmUgPSB7XG4gICAgICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICAgICAgc291cmNlTGF5ZXJJbmRleCxcbiAgICAgICAgICAgICAgICBpbmRleCxcbiAgICAgICAgICAgICAgICBnZW9tZXRyeTogbmVlZEdlb21ldHJ5ID8gZXZhbHVhdGlvbkZlYXR1cmUuZ2VvbWV0cnkgOiBsb2FkR2VvbWV0cnkoZmVhdHVyZSwgY2Fub25pY2FsLCB0aWxlVHJhbnNmb3JtKSxcbiAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiBmZWF0dXJlLnByb3BlcnRpZXMsXG4gICAgICAgICAgICAgICAgdHlwZTogZmVhdHVyZS50eXBlLFxuICAgICAgICAgICAgICAgIHBhdHRlcm5zOiB7fVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3QgdmVydGV4QXJyYXlPZmZzZXQgPSB0aGlzLmxheW91dFZlcnRleEFycmF5Lmxlbmd0aDtcbiAgICAgICAgICAgIGlmICh0aGlzLmhhc1BhdHRlcm4pIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZlYXR1cmVzLnB1c2goYWRkUGF0dGVybkRlcGVuZGVuY2llcygnZmlsbC1leHRydXNpb24nLCB0aGlzLmxheWVycywgYnVja2V0RmVhdHVyZSwgdGhpcy56b29tLCBvcHRpb25zKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkRmVhdHVyZShidWNrZXRGZWF0dXJlLCBidWNrZXRGZWF0dXJlLmdlb21ldHJ5LCBpbmRleCwgY2Fub25pY2FsLCB7fSwgb3B0aW9ucy5hdmFpbGFibGVJbWFnZXMsIHRpbGVUcmFuc2Zvcm0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBvcHRpb25zLmZlYXR1cmVJbmRleC5pbnNlcnQoZmVhdHVyZSwgYnVja2V0RmVhdHVyZS5nZW9tZXRyeSwgaW5kZXgsIHNvdXJjZUxheWVySW5kZXgsIHRoaXMuaW5kZXgsIHZlcnRleEFycmF5T2Zmc2V0KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNvcnRCb3JkZXJzKCk7XG4gICAgfVxuXG4gICAgYWRkRmVhdHVyZXMob3B0aW9uczogUG9wdWxhdGVQYXJhbWV0ZXJzLCBjYW5vbmljYWw6IENhbm9uaWNhbFRpbGVJRCwgaW1hZ2VQb3NpdGlvbnM6IFNwcml0ZVBvc2l0aW9ucywgYXZhaWxhYmxlSW1hZ2VzOiBBcnJheTxzdHJpbmc+LCB0aWxlVHJhbnNmb3JtOiBUaWxlVHJhbnNmb3JtKSB7XG4gICAgICAgIGZvciAoY29uc3QgZmVhdHVyZSBvZiB0aGlzLmZlYXR1cmVzKSB7XG4gICAgICAgICAgICBjb25zdCB7Z2VvbWV0cnl9ID0gZmVhdHVyZTtcbiAgICAgICAgICAgIHRoaXMuYWRkRmVhdHVyZShmZWF0dXJlLCBnZW9tZXRyeSwgZmVhdHVyZS5pbmRleCwgY2Fub25pY2FsLCBpbWFnZVBvc2l0aW9ucywgYXZhaWxhYmxlSW1hZ2VzLCB0aWxlVHJhbnNmb3JtKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNvcnRCb3JkZXJzKCk7XG4gICAgfVxuXG4gICAgdXBkYXRlKHN0YXRlczogRmVhdHVyZVN0YXRlcywgdnRMYXllcjogSVZlY3RvclRpbGVMYXllciwgYXZhaWxhYmxlSW1hZ2VzOiBBcnJheTxzdHJpbmc+LCBpbWFnZVBvc2l0aW9uczogU3ByaXRlUG9zaXRpb25zKSB7XG4gICAgICAgIGlmICghdGhpcy5zdGF0ZURlcGVuZGVudExheWVycy5sZW5ndGgpIHJldHVybjtcbiAgICAgICAgdGhpcy5wcm9ncmFtQ29uZmlndXJhdGlvbnMudXBkYXRlUGFpbnRBcnJheXMoc3RhdGVzLCB2dExheWVyLCB0aGlzLnN0YXRlRGVwZW5kZW50TGF5ZXJzLCBhdmFpbGFibGVJbWFnZXMsIGltYWdlUG9zaXRpb25zKTtcbiAgICB9XG5cbiAgICBpc0VtcHR5KCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5sYXlvdXRWZXJ0ZXhBcnJheS5sZW5ndGggPT09IDA7XG4gICAgfVxuXG4gICAgdXBsb2FkUGVuZGluZygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICF0aGlzLnVwbG9hZGVkIHx8IHRoaXMucHJvZ3JhbUNvbmZpZ3VyYXRpb25zLm5lZWRzVXBsb2FkO1xuICAgIH1cblxuICAgIHVwbG9hZChjb250ZXh0OiBDb250ZXh0KSB7XG4gICAgICAgIGlmICghdGhpcy51cGxvYWRlZCkge1xuICAgICAgICAgICAgdGhpcy5sYXlvdXRWZXJ0ZXhCdWZmZXIgPSBjb250ZXh0LmNyZWF0ZVZlcnRleEJ1ZmZlcih0aGlzLmxheW91dFZlcnRleEFycmF5LCBsYXlvdXRBdHRyaWJ1dGVzKTtcbiAgICAgICAgICAgIHRoaXMuaW5kZXhCdWZmZXIgPSBjb250ZXh0LmNyZWF0ZUluZGV4QnVmZmVyKHRoaXMuaW5kZXhBcnJheSk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmxheW91dFZlcnRleEV4dEFycmF5KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sYXlvdXRWZXJ0ZXhFeHRCdWZmZXIgPSBjb250ZXh0LmNyZWF0ZVZlcnRleEJ1ZmZlcih0aGlzLmxheW91dFZlcnRleEV4dEFycmF5LCBmaWxsRXh0cnVzaW9uQXR0cmlidXRlc0V4dC5tZW1iZXJzLCB0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnByb2dyYW1Db25maWd1cmF0aW9ucy51cGxvYWQoY29udGV4dCk7XG4gICAgICAgIHRoaXMudXBsb2FkZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIHVwbG9hZENlbnRyb2lkKGNvbnRleHQ6IENvbnRleHQpIHtcbiAgICAgICAgaWYgKHRoaXMuY2VudHJvaWRWZXJ0ZXhBcnJheS5sZW5ndGggPT09IDApIHJldHVybjtcbiAgICAgICAgaWYgKCF0aGlzLmNlbnRyb2lkVmVydGV4QnVmZmVyKSB7XG4gICAgICAgICAgICB0aGlzLmNlbnRyb2lkVmVydGV4QnVmZmVyID0gY29udGV4dC5jcmVhdGVWZXJ0ZXhCdWZmZXIodGhpcy5jZW50cm9pZFZlcnRleEFycmF5LCBjZW50cm9pZEF0dHJpYnV0ZXMubWVtYmVycywgdHJ1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5uZWVkc0NlbnRyb2lkVXBkYXRlKSB7XG4gICAgICAgICAgICB0aGlzLmNlbnRyb2lkVmVydGV4QnVmZmVyLnVwZGF0ZURhdGEodGhpcy5jZW50cm9pZFZlcnRleEFycmF5KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm5lZWRzQ2VudHJvaWRVcGRhdGUgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBkZXN0cm95KCkge1xuICAgICAgICBpZiAoIXRoaXMubGF5b3V0VmVydGV4QnVmZmVyKSByZXR1cm47XG4gICAgICAgIHRoaXMubGF5b3V0VmVydGV4QnVmZmVyLmRlc3Ryb3koKTtcbiAgICAgICAgaWYgKHRoaXMuY2VudHJvaWRWZXJ0ZXhCdWZmZXIpIHtcbiAgICAgICAgICAgIHRoaXMuY2VudHJvaWRWZXJ0ZXhCdWZmZXIuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmxheW91dFZlcnRleEV4dEJ1ZmZlcikge1xuICAgICAgICAgICAgdGhpcy5sYXlvdXRWZXJ0ZXhFeHRCdWZmZXIuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaW5kZXhCdWZmZXIuZGVzdHJveSgpO1xuICAgICAgICB0aGlzLnByb2dyYW1Db25maWd1cmF0aW9ucy5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMuc2VnbWVudHMuZGVzdHJveSgpO1xuICAgIH1cblxuICAgIGFkZEZlYXR1cmUoZmVhdHVyZTogQnVja2V0RmVhdHVyZSwgZ2VvbWV0cnk6IEFycmF5PEFycmF5PFBvaW50Pj4sIGluZGV4OiBudW1iZXIsIGNhbm9uaWNhbDogQ2Fub25pY2FsVGlsZUlELCBpbWFnZVBvc2l0aW9uczogU3ByaXRlUG9zaXRpb25zLCBhdmFpbGFibGVJbWFnZXM6IEFycmF5PHN0cmluZz4sIHRpbGVUcmFuc2Zvcm06IFRpbGVUcmFuc2Zvcm0pIHtcbiAgICAgICAgY29uc3QgdGlsZUJvdW5kcyA9IFtuZXcgUG9pbnQoMCwgMCksIG5ldyBQb2ludChFWFRFTlQsIEVYVEVOVCldO1xuICAgICAgICBjb25zdCBwcm9qZWN0aW9uID0gdGlsZVRyYW5zZm9ybS5wcm9qZWN0aW9uO1xuICAgICAgICBjb25zdCBpc0dsb2JlID0gcHJvamVjdGlvbi5uYW1lID09PSAnZ2xvYmUnO1xuICAgICAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuZW5hYmxlVGVycmFpbiAmJiAhaXNHbG9iZSA/IG5ldyBQYXJ0TWV0YWRhdGEoKSA6IG51bGw7XG4gICAgICAgIGNvbnN0IGlzUG9seWdvbiA9IHZlY3RvclRpbGVGZWF0dXJlVHlwZXNbZmVhdHVyZS50eXBlXSA9PT0gJ1BvbHlnb24nO1xuXG4gICAgICAgIGlmIChpc0dsb2JlICYmICF0aGlzLmxheW91dFZlcnRleEV4dEFycmF5KSB7XG4gICAgICAgICAgICB0aGlzLmxheW91dFZlcnRleEV4dEFycmF5ID0gbmV3IEZpbGxFeHRydXNpb25FeHRBcnJheSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcG9seWdvbnMgPSBjbGFzc2lmeVJpbmdzKGdlb21ldHJ5LCBFQVJDVVRfTUFYX1JJTkdTKTtcblxuICAgICAgICBmb3IgKGxldCBpID0gcG9seWdvbnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGNvbnN0IHBvbHlnb24gPSBwb2x5Z29uc1tpXTtcbiAgICAgICAgICAgIGlmIChwb2x5Z29uLmxlbmd0aCA9PT0gMCB8fCBpc0VudGlyZWx5T3V0c2lkZShwb2x5Z29uWzBdKSkge1xuICAgICAgICAgICAgICAgIHBvbHlnb25zLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBjbGlwcGVkUG9seWdvbnM6IENsaXBwZWRQb2x5Z29uW107XG4gICAgICAgIGlmIChpc0dsb2JlKSB7XG4gICAgICAgICAgICAvLyBQZXJmb3JtIHRlc3NlbGF0aW9uIGZvciBwb2x5Z29ucyBvZiB0aWxlcyBpbiBvcmRlciB0byBzdXBwb3J0IGxvbmcgcGxhbmFyXG4gICAgICAgICAgICAvLyB0cmlhbmdsZXMgb24gdGhlIGN1cnZlZCBzdXJmYWNlIG9mIHRoZSBnbG9iZS4gVGhpcyBpcyBkb25lIGZvciBhbGwgcG9seWdvbnNcbiAgICAgICAgICAgIC8vIHJlZ2FyZGxlc3Mgb2YgdGhlaXIgc2l6ZSBpbiBvcmRlciBndWFyYW50ZWUgaWRlbnRpY2FsIHJlc3VsdHMgb24gYWxsIHNpZGVzIG9mXG4gICAgICAgICAgICAvLyB0aWxlIGJvdW5kYXJpZXMuXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gVGhlIGdsb2JlIGlzIHN1YmRpdmlkZWQgaW50byBhIDMyeDE2IGdyaWQuIFRoZSBudW1iZXIgb2Ygc3ViZGl2aXNpb25zIGRvbmVcbiAgICAgICAgICAgIC8vIGZvciBhIHRpbGUgZGVwZW5kcyBvbiB0aGUgem9vbSBsZXZlbC4gRm9yIGV4YW1wbGUgdGlsZSB3aXRoIHo9MCByZXF1aXJlcyAy4oG0XG4gICAgICAgICAgICAvLyBzdWJkaXZpc2lvbnMsIHRpbGUgd2l0aCB6PTEgMsKzIGV0Yy4gVGhlIHN1YmRpdmlzaW9uIGlzIGRvbmUgaW4gcG9sYXIgY29vcmRpbmF0ZXNcbiAgICAgICAgICAgIC8vIGluc3RlYWQgb2YgdGlsZSBjb29yZGluYXRlcy5cbiAgICAgICAgICAgIGNsaXBwZWRQb2x5Z29ucyA9IHJlc2FtcGxlRmlsbEV4dHJ1c2lvblBvbHlnb25zRm9yR2xvYmUocG9seWdvbnMsIHRpbGVCb3VuZHMsIGNhbm9uaWNhbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjbGlwcGVkUG9seWdvbnMgPSBbXTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgcG9seWdvbiBvZiBwb2x5Z29ucykge1xuICAgICAgICAgICAgICAgIGNsaXBwZWRQb2x5Z29ucy5wdXNoKHtwb2x5Z29uLCBib3VuZHM6IHRpbGVCb3VuZHN9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGVkZ2VSYWRpdXMgPSBpc1BvbHlnb24gPyB0aGlzLmVkZ2VSYWRpdXMgOiAwO1xuXG4gICAgICAgIGZvciAoY29uc3Qge3BvbHlnb24sIGJvdW5kc30gb2YgY2xpcHBlZFBvbHlnb25zKSB7XG4gICAgICAgICAgICAvLyBPbmx5IHRyaWFuZ3VsYXRlIGFuZCBkcmF3IHRoZSBhcmVhIG9mIHRoZSBmZWF0dXJlIGlmIGl0IGlzIGEgcG9seWdvblxuICAgICAgICAgICAgLy8gT3RoZXIgZmVhdHVyZSB0eXBlcyAoZS5nLiBMaW5lU3RyaW5nKSBkbyBub3QgaGF2ZSBhcmVhLCBzbyB0cmlhbmd1bGF0aW9uIGlzIHBvaW50bGVzcyAvIHVuZGVmaW5lZFxuICAgICAgICAgICAgbGV0IHRvcEluZGV4ID0gMDtcbiAgICAgICAgICAgIGxldCBudW1WZXJ0aWNlcyA9IDA7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHJpbmcgb2YgcG9seWdvbikge1xuICAgICAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSB0aGUgcmluZyBjbG9zZXNcbiAgICAgICAgICAgICAgICBpZiAoaXNQb2x5Z29uICYmICFyaW5nWzBdLmVxdWFscyhyaW5nW3JpbmcubGVuZ3RoIC0gMV0pKSByaW5nLnB1c2gocmluZ1swXSk7XG4gICAgICAgICAgICAgICAgbnVtVmVydGljZXMgKz0gKGlzUG9seWdvbiA/IChyaW5nLmxlbmd0aCAtIDEpIDogcmluZy5sZW5ndGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gV2UgdXNlIFwiKGlzUG9seWdvbiA/IDUgOiA0KSAqIG51bVZlcnRpY2VzXCIgYXMgYW4gZXN0aW1hdGUgdG8gZW5zdXJlIHdoZXRoZXIgYWRkaXRpb25hbCBzZWdtZW50cyBhcmUgbmVlZGVkIG9yIG5vdCAoc2VlIFNlZ21lbnRWZWN0b3IuTUFYX1ZFUlRFWF9BUlJBWV9MRU5HVEgpLlxuICAgICAgICAgICAgY29uc3Qgc2VnbWVudCA9IHRoaXMuc2VnbWVudHMucHJlcGFyZVNlZ21lbnQoKGlzUG9seWdvbiA/IDUgOiA0KSAqIG51bVZlcnRpY2VzLCB0aGlzLmxheW91dFZlcnRleEFycmF5LCB0aGlzLmluZGV4QXJyYXkpO1xuICAgICAgICAgICAgaWYgKGlzUG9seWdvbikge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZsYXR0ZW5lZCA9IFtdO1xuICAgICAgICAgICAgICAgIGNvbnN0IGhvbGVJbmRpY2VzID0gW107XG4gICAgICAgICAgICAgICAgdG9wSW5kZXggPSBzZWdtZW50LnZlcnRleExlbmd0aDtcblxuICAgICAgICAgICAgICAgIC8vIEZpcnN0IHdlIG9mZnNldCAoaW5zZXQpIHRoZSB0b3AgdmVydGljZXMgKGkuZSB0aGUgdmVydGljZXMgdGhhdCBtYWtlIHVwIHRoZSByb29mKS5cbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHJpbmcgb2YgcG9seWdvbikge1xuICAgICAgICAgICAgICAgICAgICBpZiAocmluZy5sZW5ndGggJiYgcmluZyAhPT0gcG9seWdvblswXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaG9sZUluZGljZXMucHVzaChmbGF0dGVuZWQubGVuZ3RoIC8gMik7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBUaGUgZm9sbG93aW5nIHZlY3RvcnMgYXJlIHVzZWQgdG8gYXZvaWQgZHVwbGljYXRlIG5vcm1hbCBjYWxjdWxhdGlvbnMgd2hlbiBnb2luZyBvdmVyIHRoZSB2ZXJ0aWNlcy5cbiAgICAgICAgICAgICAgICAgICAgbGV0IG5hLCBuYjtcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcDAgPSByaW5nWzBdO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcDEgPSByaW5nWzFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgbmEgPSBwMS5zdWIocDApLl9wZXJwKCkuX3VuaXQoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IHJpbmcubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHAxID0gcmluZ1tpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHAyID0gcmluZ1tpID09PSByaW5nLmxlbmd0aCAtIDEgPyAxIDogaSArIDFdO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQge3gsIHl9ID0gcDE7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWRnZVJhZGl1cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5iID0gcDIuc3ViKHAxKS5fcGVycCgpLl91bml0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgbm0gPSBuYS5hZGQobmIpLl91bml0KCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb3NIYWxmQW5nbGUgPSBuYS54ICogbm0ueCArIG5hLnkgKiBubS55O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9mZnNldCA9IGVkZ2VSYWRpdXMgKiBNYXRoLm1pbig0LCAxIC8gY29zSGFsZkFuZ2xlKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gb2Zmc2V0ICogbm0ueDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ICs9IG9mZnNldCAqIG5tLnk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYSA9IG5iO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRWZXJ0ZXgodGhpcy5sYXlvdXRWZXJ0ZXhBcnJheSwgeCwgeSwgMCwgMCwgMSwgMSwgMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZWdtZW50LnZlcnRleExlbmd0aCsrO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB0cmlhbmd1bGF0ZSBhcyBpZiB2ZXJ0aWNlcyB3ZXJlIG5vdCBvZmZzZXQgdG8gZW5zdXJlIGNvcnJlY3QgdHJpYW5ndWxhdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgZmxhdHRlbmVkLnB1c2gocDEueCwgcDEueSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0dsb2JlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYXJyYXk6IGFueSA9IHRoaXMubGF5b3V0VmVydGV4RXh0QXJyYXk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcHJvamVjdGVkUCA9IHByb2plY3Rpb24ucHJvamVjdFRpbGVQb2ludCh4LCB5LCBjYW5vbmljYWwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG4gPSBwcm9qZWN0aW9uLnVwVmVjdG9yKGNhbm9uaWNhbCwgeCwgeSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkR2xvYmVFeHRWZXJ0ZXgoYXJyYXksIHByb2plY3RlZFAsIG4pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3QgaW5kaWNlcyA9IGVhcmN1dChmbGF0dGVuZWQsIGhvbGVJbmRpY2VzKTtcbiAgICAgICAgICAgICAgICBhc3NlcnQoaW5kaWNlcy5sZW5ndGggJSAzID09PSAwKTtcblxuICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5kaWNlcy5sZW5ndGg7IGogKz0gMykge1xuICAgICAgICAgICAgICAgICAgICAvLyBjbG9ja3dpc2Ugd2luZGluZyBvcmRlci5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbmRleEFycmF5LmVtcGxhY2VCYWNrKFxuICAgICAgICAgICAgICAgICAgICAgICAgdG9wSW5kZXggKyBpbmRpY2VzW2pdLFxuICAgICAgICAgICAgICAgICAgICAgICAgdG9wSW5kZXggKyBpbmRpY2VzW2ogKyAyXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvcEluZGV4ICsgaW5kaWNlc1tqICsgMV0pO1xuICAgICAgICAgICAgICAgICAgICBzZWdtZW50LnByaW1pdGl2ZUxlbmd0aCsrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9yIChjb25zdCByaW5nIG9mIHBvbHlnb24pIHtcbiAgICAgICAgICAgICAgICBpZiAobWV0YWRhdGEgJiYgcmluZy5sZW5ndGgpIG1ldGFkYXRhLnN0YXJ0UmluZyhyaW5nWzBdKTtcbiAgICAgICAgICAgICAgICBsZXQgaXNQcmV2Q29ybmVyQ29uY2F2ZSA9IHJpbmcubGVuZ3RoID4gNCAmJiBpc0FPQ29uY2F2ZUFuZ2xlKHJpbmdbcmluZy5sZW5ndGggLSAyXSwgcmluZ1swXSwgcmluZ1sxXSk7XG4gICAgICAgICAgICAgICAgbGV0IG9mZnNldFByZXYgPSBlZGdlUmFkaXVzID8gZ2V0Um91bmRlZEVkZ2VPZmZzZXQocmluZ1tyaW5nLmxlbmd0aCAtIDJdLCByaW5nWzBdLCByaW5nWzFdLCBlZGdlUmFkaXVzKSA6IDA7XG5cbiAgICAgICAgICAgICAgICBsZXQga0ZpcnN0O1xuXG4gICAgICAgICAgICAgICAgLy8gVGhlIGZvbGxvd2luZyB2ZWN0b3JzIGFyZSB1c2VkIHRvIGF2b2lkIGR1cGxpY2F0ZSBub3JtYWwgY2FsY3VsYXRpb25zIHdoZW4gZ29pbmcgb3ZlciB0aGUgdmVydGljZXMuXG4gICAgICAgICAgICAgICAgbGV0IG5hLCBuYjtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHAwID0gcmluZ1swXTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcDEgPSByaW5nWzFdO1xuICAgICAgICAgICAgICAgICAgICBuYSA9IHAxLnN1YihwMCkuX3BlcnAoKS5fdW5pdCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgY2FwID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMSwgZWRnZURpc3RhbmNlID0gMDsgaSA8IHJpbmcubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHAwID0gcmluZ1tpIC0gMV07XG4gICAgICAgICAgICAgICAgICAgIGxldCBwMSA9IHJpbmdbaV07XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHAyID0gcmluZ1tpID09PSByaW5nLmxlbmd0aCAtIDEgPyAxIDogaSArIDFdO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChtZXRhZGF0YSAmJiBpc1BvbHlnb24pIG1ldGFkYXRhLmN1cnJlbnRQb2x5Q291bnQudG9wKys7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0VkZ2VPdXRzaWRlQm91bmRzKHAxLCBwMCwgYm91bmRzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVkZ2VSYWRpdXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYSA9IHAyLnN1YihwMSkuX3BlcnAoKS5fdW5pdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcCA9ICFjYXA7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAobWV0YWRhdGEpIG1ldGFkYXRhLmFwcGVuZChwMSwgcDApO1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGQgPSBwMS5zdWIocDApLl9wZXJwKCk7XG4gICAgICAgICAgICAgICAgICAgIC8vIEdpdmVuIHRoYXQgbnogPT09IDAsIGVuY29kZSBueCAvIChhYnMobngpICsgYWJzKG55KSkgYW5kIHNpZ25zLlxuICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGluZm9ybWF0aW9uIGlzIHN1ZmZpY2llbnQgdG8gcmVjb25zdHJ1Y3Qgbm9ybWFsIHZlY3RvciBpbiB2ZXJ0ZXggc2hhZGVyLlxuICAgICAgICAgICAgICAgICAgICBjb25zdCBueFJhdGlvID0gZC54IC8gKE1hdGguYWJzKGQueCkgKyBNYXRoLmFicyhkLnkpKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbnlTaWduID0gZC55ID4gMCA/IDEgOiAwO1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGRpc3QgPSBwMC5kaXN0KHAxKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVkZ2VEaXN0YW5jZSArIGRpc3QgPiAzMjc2OCkgZWRnZURpc3RhbmNlID0gMDtcblxuICAgICAgICAgICAgICAgICAgICAvLyBOZXh0IG9mZnNldCB0aGUgdmVydGljZXMgYWxvbmcgdGhlIGVkZ2VzIGFuZCBjcmVhdGUgYSBjaGFtZmVyIHNwYWNlIGJldHdlZW4gdGhlbTpcbiAgICAgICAgICAgICAgICAgICAgLy8gU28gaWYgd2UgaGF2ZSB0aGUgZm9sbG93aW5nICh3aGVyZSAneCcgZGVub3RlcyBhIHZlcnRleClcbiAgICAgICAgICAgICAgICAgICAgLy8geOKUgOKUgOKUgOKUgOKUgOKUgHhcbiAgICAgICAgICAgICAgICAgICAgLy8gfCAgICAgIHxcbiAgICAgICAgICAgICAgICAgICAgLy8gfCAgICAgIHxcbiAgICAgICAgICAgICAgICAgICAgLy8gfCAgICAgIHxcbiAgICAgICAgICAgICAgICAgICAgLy8gfCAgICAgIHxcbiAgICAgICAgICAgICAgICAgICAgLy8geOKUgOKUgOKUgOKUgOKUgOKUgHhcbiAgICAgICAgICAgICAgICAgICAgLy8gd2UgZW5kIHVwIHdpdGg6XG4gICAgICAgICAgICAgICAgICAgIC8vICB44pSA4pSA4pSA4pSAeFxuICAgICAgICAgICAgICAgICAgICAvLyB4ICAgICAgeFxuICAgICAgICAgICAgICAgICAgICAvLyB8ICAgICAgfFxuICAgICAgICAgICAgICAgICAgICAvLyB8ICAgICAgfFxuICAgICAgICAgICAgICAgICAgICAvLyB4ICAgICAgeFxuICAgICAgICAgICAgICAgICAgICAvLyAgeOKUgOKUgOKUgOKUgHhcbiAgICAgICAgICAgICAgICAgICAgLy8gKGRyYXdpbmcgaXNuJ3QgZXhhY3QgYnV0IGhvcGVmdWxseSBnZXRzIHRoZSBwb2ludCBhY3Jvc3MpLlxuXG4gICAgICAgICAgICAgICAgICAgIGlmIChlZGdlUmFkaXVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYiA9IHAyLnN1YihwMSkuX3BlcnAoKS5fdW5pdCgpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb3NIYWxmQW5nbGUgPSBnZXRDb3NIYWxmQW5nbGUobmEsIG5iKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBvZmZzZXROZXh0ID0gX2dldFJvdW5kZWRFZGdlT2Zmc2V0KHAwLCBwMSwgcDIsIGNvc0hhbGZBbmdsZSwgZWRnZVJhZGl1cyk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc05hTihvZmZzZXROZXh0KSkgb2Zmc2V0TmV4dCA9IDA7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuRWRnZSA9IHAxLnN1YihwMCkuX3VuaXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHAwID0gcDAuYWRkKG5FZGdlLm11bHQob2Zmc2V0UHJldikpLl9yb3VuZCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcDEgPSBwMS5hZGQobkVkZ2UubXVsdCgtb2Zmc2V0TmV4dCkpLl9yb3VuZCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0UHJldiA9IG9mZnNldE5leHQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIG5hID0gbmI7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBrID0gc2VnbWVudC52ZXJ0ZXhMZW5ndGg7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaXNDb25jYXZlQ29ybmVyID0gcmluZy5sZW5ndGggPiA0ICYmIGlzQU9Db25jYXZlQW5nbGUocDAsIHAxLCBwMik7XG4gICAgICAgICAgICAgICAgICAgIGxldCBlbmNvZGVkRWRnZURpc3RhbmNlID0gZW5jb2RlQU9Ub0VkZ2VEaXN0YW5jZShlZGdlRGlzdGFuY2UsIGlzUHJldkNvcm5lckNvbmNhdmUsIGNhcCk7XG5cbiAgICAgICAgICAgICAgICAgICAgYWRkVmVydGV4KHRoaXMubGF5b3V0VmVydGV4QXJyYXksIHAwLngsIHAwLnksIG54UmF0aW8sIG55U2lnbiwgMCwgMCwgZW5jb2RlZEVkZ2VEaXN0YW5jZSk7XG4gICAgICAgICAgICAgICAgICAgIGFkZFZlcnRleCh0aGlzLmxheW91dFZlcnRleEFycmF5LCBwMC54LCBwMC55LCBueFJhdGlvLCBueVNpZ24sIDAsIDEsIGVuY29kZWRFZGdlRGlzdGFuY2UpO1xuXG4gICAgICAgICAgICAgICAgICAgIGVkZ2VEaXN0YW5jZSArPSBkaXN0O1xuICAgICAgICAgICAgICAgICAgICBlbmNvZGVkRWRnZURpc3RhbmNlID0gZW5jb2RlQU9Ub0VkZ2VEaXN0YW5jZShlZGdlRGlzdGFuY2UsIGlzQ29uY2F2ZUNvcm5lciwgIWNhcCk7XG4gICAgICAgICAgICAgICAgICAgIGlzUHJldkNvcm5lckNvbmNhdmUgPSBpc0NvbmNhdmVDb3JuZXI7XG5cbiAgICAgICAgICAgICAgICAgICAgYWRkVmVydGV4KHRoaXMubGF5b3V0VmVydGV4QXJyYXksIHAxLngsIHAxLnksIG54UmF0aW8sIG55U2lnbiwgMCwgMCwgZW5jb2RlZEVkZ2VEaXN0YW5jZSk7XG4gICAgICAgICAgICAgICAgICAgIGFkZFZlcnRleCh0aGlzLmxheW91dFZlcnRleEFycmF5LCBwMS54LCBwMS55LCBueFJhdGlvLCBueVNpZ24sIDAsIDEsIGVuY29kZWRFZGdlRGlzdGFuY2UpO1xuXG4gICAgICAgICAgICAgICAgICAgIHNlZ21lbnQudmVydGV4TGVuZ3RoICs9IDQ7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8g4pSM4pSA4pSA4pSA4pSA4pSA4pSA4pSQXG4gICAgICAgICAgICAgICAgICAgIC8vIOKUgiAxICAzIOKUgiBjbG9ja3dpc2Ugd2luZGluZyBvcmRlci5cbiAgICAgICAgICAgICAgICAgICAgLy8g4pSCICAgICAg4pSCIFRyaWFuZ2xlIDE6IDAgPT4gMSA9PiAyXG4gICAgICAgICAgICAgICAgICAgIC8vIOKUgiAwICAyIOKUgiBUcmlhbmdsZSAyOiAxID0+IDMgPT4gMlxuICAgICAgICAgICAgICAgICAgICAvLyDilJTilIDilIDilIDilIDilIDilIDilJhcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbmRleEFycmF5LmVtcGxhY2VCYWNrKGsgKyAwLCBrICsgMSwgayArIDIpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmluZGV4QXJyYXkuZW1wbGFjZUJhY2soayArIDEsIGsgKyAzLCBrICsgMik7XG4gICAgICAgICAgICAgICAgICAgIHNlZ21lbnQucHJpbWl0aXZlTGVuZ3RoICs9IDI7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGVkZ2VSYWRpdXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vdGUgdGhhdCBpbiB0aGUgcHJldmlvdXMgZm9yLWxvb3Agd2Ugc3RhcnQgZnJvbSBpbmRleCAxIHRvIGFkZCB0aGUgdG9wIHZlcnRpY2VzIHdoaWNoIGV4cGxhaW5zIHRoZSBuZXh0IGxpbmUuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0MCA9IHRvcEluZGV4ICsgKGkgPT09IDEgPyByaW5nLmxlbmd0aCAtIDIgOiBpIC0gMik7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0MSA9IGkgPT09IDEgPyB0b3BJbmRleCA6IHQwICsgMTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gdG9wIGNoYW1mZXIgYWxvbmcgdGhlIHNpZGUgKGkuZS4gdGhlIHNwYWNlIGJldHdlZW4gdGhlIHdhbGwgYW5kIHRoZSByb29mKS5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW5kZXhBcnJheS5lbXBsYWNlQmFjayhrICsgMSwgdDAsIGsgKyAzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW5kZXhBcnJheS5lbXBsYWNlQmFjayh0MCwgdDEsIGsgKyAzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlZ21lbnQucHJpbWl0aXZlTGVuZ3RoICs9IDI7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChrRmlyc3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtGaXJzdCA9IGs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0byBmaWxsIGluIHRoZSBnYXAgaW4gdGhlIGNvcm5lciBvbmx5IHdoZW4gYm90aCBjb3JyZXNwb25kaW5nIGVkZ2VzIGFyZSBpbiB0aWxlIGJvdW5kcy5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaXNFZGdlT3V0c2lkZUJvdW5kcyhwMiwgcmluZ1tpXSwgYm91bmRzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGwgPSBpID09PSByaW5nLmxlbmd0aCAtIDEgPyBrRmlyc3QgOiBzZWdtZW50LnZlcnRleExlbmd0aDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZlcnRpY2FsIHNpZGUgY2hhbWZlciBpLmUuIHRoZSBzcGFjZSBiZXR3ZWVuIGNvbnNlY3V0aXZlIHdhbGxzLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW5kZXhBcnJheS5lbXBsYWNlQmFjayhrICsgMiwgayArIDMsIGwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW5kZXhBcnJheS5lbXBsYWNlQmFjayhrICsgMywgbCArIDEsIGwpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdG9wIGNvcm5lciB3aGVyZSB0aGUgdG9wKHJvb2YpIGFuZCB0d28gc2lkZXMod2FsbHMpIG1lZXQuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbmRleEFycmF5LmVtcGxhY2VCYWNrKGsgKyAzLCB0MSwgbCArIDEpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VnbWVudC5wcmltaXRpdmVMZW5ndGggKz0gMztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNhcCA9ICFjYXA7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoaXNHbG9iZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYXJyYXk6IGFueSA9IHRoaXMubGF5b3V0VmVydGV4RXh0QXJyYXk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHByb2plY3RlZFAwID0gcHJvamVjdGlvbi5wcm9qZWN0VGlsZVBvaW50KHAwLngsIHAwLnksIGNhbm9uaWNhbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwcm9qZWN0ZWRQMSA9IHByb2plY3Rpb24ucHJvamVjdFRpbGVQb2ludChwMS54LCBwMS55LCBjYW5vbmljYWwpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuMCA9IHByb2plY3Rpb24udXBWZWN0b3IoY2Fub25pY2FsLCBwMC54LCBwMC55KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG4xID0gcHJvamVjdGlvbi51cFZlY3RvcihjYW5vbmljYWwsIHAxLngsIHAxLnkpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRHbG9iZUV4dFZlcnRleChhcnJheSwgcHJvamVjdGVkUDAsIG4wKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZEdsb2JlRXh0VmVydGV4KGFycmF5LCBwcm9qZWN0ZWRQMCwgbjApO1xuICAgICAgICAgICAgICAgICAgICAgICAgYWRkR2xvYmVFeHRWZXJ0ZXgoYXJyYXksIHByb2plY3RlZFAxLCBuMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRHbG9iZUV4dFZlcnRleChhcnJheSwgcHJvamVjdGVkUDEsIG4xKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoaXNQb2x5Z29uKSB0b3BJbmRleCArPSAocmluZy5sZW5ndGggLSAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGFzc2VydCghaXNHbG9iZSB8fCAodGhpcy5sYXlvdXRWZXJ0ZXhFeHRBcnJheSAmJiB0aGlzLmxheW91dFZlcnRleEV4dEFycmF5Lmxlbmd0aCA9PT0gdGhpcy5sYXlvdXRWZXJ0ZXhBcnJheS5sZW5ndGgpKTtcblxuICAgICAgICBpZiAobWV0YWRhdGEgJiYgbWV0YWRhdGEucG9seUNvdW50Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIC8vIFdoZW4gYnVpbGRpbmcgaXMgc3BsaXQgYmV0d2VlbiB0aWxlcywgZG9uJ3QgaGFuZGxlIGZsYXQgcm9vZnMgaGVyZS5cbiAgICAgICAgICAgIGlmIChtZXRhZGF0YS5ib3JkZXJzKSB7XG4gICAgICAgICAgICAgICAgLy8gU3RvcmUgdG8gdGhlIGJ1Y2tldC4gRmxhdCByb29mcyBhcmUgaGFuZGxlZCBpbiBmbGF0Um9vZnNVcGRhdGUsXG4gICAgICAgICAgICAgICAgLy8gYWZ0ZXIgam9pbmluZyBwYXJ0cyB0aGF0IGxheSBpbiBkaWZmZXJlbnQgYnVja2V0cy5cbiAgICAgICAgICAgICAgICBtZXRhZGF0YS52ZXJ0ZXhBcnJheU9mZnNldCA9IHRoaXMuY2VudHJvaWRWZXJ0ZXhBcnJheS5sZW5ndGg7XG4gICAgICAgICAgICAgICAgY29uc3QgYm9yZGVycyA9IG1ldGFkYXRhLmJvcmRlcnM7XG4gICAgICAgICAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLmZlYXR1cmVzT25Cb3JkZXIucHVzaChtZXRhZGF0YSkgLSAxO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChib3JkZXJzW2ldWzBdICE9PSBOdW1iZXIuTUFYX1ZBTFVFKSB7IHRoaXMuYm9yZGVyc1tpXS5wdXNoKGluZGV4KTsgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZW5jb2RlQ2VudHJvaWQobWV0YWRhdGEuYm9yZGVycyA/IHVuZGVmaW5lZCA6IG1ldGFkYXRhLmNlbnRyb2lkKCksIG1ldGFkYXRhKTtcbiAgICAgICAgICAgIGFzc2VydCghdGhpcy5jZW50cm9pZFZlcnRleEFycmF5Lmxlbmd0aCB8fCB0aGlzLmNlbnRyb2lkVmVydGV4QXJyYXkubGVuZ3RoID09PSB0aGlzLmxheW91dFZlcnRleEFycmF5Lmxlbmd0aCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnByb2dyYW1Db25maWd1cmF0aW9ucy5wb3B1bGF0ZVBhaW50QXJyYXlzKHRoaXMubGF5b3V0VmVydGV4QXJyYXkubGVuZ3RoLCBmZWF0dXJlLCBpbmRleCwgaW1hZ2VQb3NpdGlvbnMsIGF2YWlsYWJsZUltYWdlcywgY2Fub25pY2FsKTtcbiAgICB9XG5cbiAgICBzb3J0Qm9yZGVycygpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICAgICAgICAgIC8vIFNvcnQgYnkgYm9yZGVyIGludGVyc2VjdGlvbiBhcmVhIG1pbmltdW1zLCBhc2NlbmRpbmcuXG4gICAgICAgICAgICB0aGlzLmJvcmRlcnNbaV0uc29ydCgoYSwgYikgPT4gdGhpcy5mZWF0dXJlc09uQm9yZGVyW2FdLmJvcmRlcnNbaV1bMF0gLSB0aGlzLmZlYXR1cmVzT25Cb3JkZXJbYl0uYm9yZGVyc1tpXVswXSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBlbmNvZGVDZW50cm9pZChjOiA/UG9pbnQsIG1ldGFkYXRhOiBQYXJ0TWV0YWRhdGEsIGFwcGVuZDogYm9vbGVhbiA9IHRydWUpIHtcbiAgICAgICAgbGV0IHgsIHk7XG4gICAgICAgIC8vIEVuY29kZWQgY2VudHJvaWQgeCBhbmQgeTpcbiAgICAgICAgLy8gICAgIHggICAgIHlcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIC8vICAgICAwICAgICAwICAgIERlZmF1bHQsIG5vIGZsYXQgcm9vZi5cbiAgICAgICAgLy8gICAgIDAgICAgIDEgICAgSGlkZSwgdXNlZCB0byBoaWRlIHBhcnRzIG9mIGJ1aWxkaW5ncyBvbiBib3JkZXIgd2hpbGUgZXhwZWN0aW5nIHRoZSBvdGhlciBzaWRlIHRvIGdldCBsb2FkZWRcbiAgICAgICAgLy8gICAgPjAgICAgIDAgICAgRWxldmF0aW9uIGVuY29kZWQgdG8gdWludDE2IHdvcmRcbiAgICAgICAgLy8gICAgPjAgICAgPjAgICAgRW5jb2RlZCBjZW50cm9pZCBwb3NpdGlvbiBhbmQgeCAmIHkgc3BhblxuICAgICAgICBpZiAoYykge1xuICAgICAgICAgICAgaWYgKGMueSAhPT0gMCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHNwYW4gPSBtZXRhZGF0YS5zcGFuKCkuX211bHQodGhpcy50aWxlVG9NZXRlcik7XG4gICAgICAgICAgICAgICAgeCA9IChNYXRoLm1heChjLngsIDEpIDw8IDMpICsgTWF0aC5taW4oNywgTWF0aC5yb3VuZChzcGFuLnggLyAxMCkpO1xuICAgICAgICAgICAgICAgIHkgPSAoTWF0aC5tYXgoYy55LCAxKSA8PCAzKSArIE1hdGgubWluKDcsIE1hdGgucm91bmQoc3Bhbi55IC8gMTApKTtcbiAgICAgICAgICAgIH0gZWxzZSB7IC8vIGVuY29kZSBoZWlnaHQ6XG4gICAgICAgICAgICAgICAgeCA9IE1hdGguY2VpbCgoYy54ICsgRUxFVkFUSU9OX09GRlNFVCkgKiBFTEVWQVRJT05fU0NBTEUpO1xuICAgICAgICAgICAgICAgIHkgPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gVXNlIHRoZSBpbXBvc3NpYmxlIHNpdHVhdGlvbiAoYnVpbGRpbmcgdGhhdCBoYXMgd2lkdGggYW5kIGRvZXNuJ3QgY3Jvc3MgYm9yZGVyIGNhbm5vdCBoYXZlIGNlbnRyb2lkXG4gICAgICAgICAgICAvLyBhdCBib3JkZXIpIHRvIGVuY29kZSB1bnByb2Nlc3NlZCBib3JkZXIgYnVpbGRpbmc6IGl0IGlzIGluaXRpYWxseSAoYXBwZW5kID09PSB0cnVlKSBoaWRkZW4gdW50aWxcbiAgICAgICAgICAgIC8vIGNvbXB1dGluZyBjZW50cm9pZCBmb3Igam9pbmVkIGJ1aWxkaW5nIHBhcnRzIGluIHJlbmRlcmluZyB0aHJlYWQgKGZsYXRSb29mc1VwZGF0ZSkuIElmIGl0IGludGVyc2VjdHMgbW9yZSB0aGFuXG4gICAgICAgICAgICAvLyB0d28gYm9yZGVycywgZmxhdCByb29mIGFwcHJvYWNoIGlzIG5vdCBhcHBsaWVkLlxuICAgICAgICAgICAgeCA9IDA7XG4gICAgICAgICAgICB5ID0gK2FwcGVuZDsgLy8gSGlkZSAoMSkgaW5pdGlhbGx5IHdoZW4gY3JlYXRpbmcgLSB2aXNpYmlsaXR5IGlzIGNoYW5nZWQgaW4gZHJhd19maWxsX2V4dHJ1c2lvbiBhcyBzb29uIGFzIG5laWdoYm9yIHRpbGUgZ2V0cyBsb2FkZWQuXG4gICAgICAgIH1cblxuICAgICAgICBhc3NlcnQoYXBwZW5kIHx8IG1ldGFkYXRhLnZlcnRleEFycmF5T2Zmc2V0ICE9PSB1bmRlZmluZWQpO1xuICAgICAgICBsZXQgb2Zmc2V0ID0gYXBwZW5kID8gdGhpcy5jZW50cm9pZFZlcnRleEFycmF5Lmxlbmd0aCA6IG1ldGFkYXRhLnZlcnRleEFycmF5T2Zmc2V0O1xuICAgICAgICBmb3IgKGNvbnN0IHBvbHlJbmZvIG9mIG1ldGFkYXRhLnBvbHlDb3VudCkge1xuICAgICAgICAgICAgaWYgKGFwcGVuZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuY2VudHJvaWRWZXJ0ZXhBcnJheS5yZXNpemUodGhpcy5jZW50cm9pZFZlcnRleEFycmF5Lmxlbmd0aCArIHBvbHlJbmZvLmVkZ2VzICogNCArIHBvbHlJbmZvLnRvcCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBvbHlJbmZvLnRvcDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jZW50cm9pZFZlcnRleEFycmF5LmVtcGxhY2Uob2Zmc2V0KyssIHgsIHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwb2x5SW5mby5lZGdlcyAqIDI7IGkrKykge1xuICAgICAgICAgICAgICAgIHRoaXMuY2VudHJvaWRWZXJ0ZXhBcnJheS5lbXBsYWNlKG9mZnNldCsrLCAwLCB5KTtcbiAgICAgICAgICAgICAgICB0aGlzLmNlbnRyb2lkVmVydGV4QXJyYXkuZW1wbGFjZShvZmZzZXQrKywgeCwgeSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIGdldENvc0hhbGZBbmdsZShuYTogUG9pbnQsIG5iOiBQb2ludCkge1xuICAgIGNvbnN0IG5tID0gbmEuYWRkKG5iKS5fdW5pdCgpO1xuICAgIGNvbnN0IGNvc0hhbGZBbmdsZSA9IG5hLnggKiBubS54ICsgbmEueSAqIG5tLnk7XG4gICAgcmV0dXJuIGNvc0hhbGZBbmdsZTtcbn1cblxuZnVuY3Rpb24gZ2V0Um91bmRlZEVkZ2VPZmZzZXQocDA6IFBvaW50LCBwMTogUG9pbnQsIHAyOiBQb2ludCwgZWRnZVJhZGl1czogbnVtYmVyKSB7XG4gICAgY29uc3QgbmEgPSBwMS5zdWIocDApLl9wZXJwKCkuX3VuaXQoKTtcbiAgICBjb25zdCBuYiA9IHAyLnN1YihwMSkuX3BlcnAoKS5fdW5pdCgpO1xuICAgIGNvbnN0IGNvc0hhbGZBbmdsZSA9IGdldENvc0hhbGZBbmdsZShuYSwgbmIpO1xuICAgIHJldHVybiBfZ2V0Um91bmRlZEVkZ2VPZmZzZXQocDAsIHAxLCBwMiwgY29zSGFsZkFuZ2xlLCBlZGdlUmFkaXVzKTtcbn1cblxuZnVuY3Rpb24gX2dldFJvdW5kZWRFZGdlT2Zmc2V0KHAwOiBQb2ludCwgcDE6IFBvaW50LCBwMjogUG9pbnQsIGNvc0hhbGZBbmdsZTogbnVtYmVyLCBlZGdlUmFkaXVzOiBudW1iZXIpIHtcbiAgICBjb25zdCBzaW5IYWxmQW5nbGUgPSBNYXRoLnNxcnQoMSAtIGNvc0hhbGZBbmdsZSAqIGNvc0hhbGZBbmdsZSk7XG4gICAgcmV0dXJuIE1hdGgubWluKHAwLmRpc3QocDEpIC8gMywgcDEuZGlzdChwMikgLyAzLCBlZGdlUmFkaXVzICogc2luSGFsZkFuZ2xlIC8gY29zSGFsZkFuZ2xlKTtcbn1cblxucmVnaXN0ZXIoRmlsbEV4dHJ1c2lvbkJ1Y2tldCwgJ0ZpbGxFeHRydXNpb25CdWNrZXQnLCB7b21pdDogWydsYXllcnMnLCAnZmVhdHVyZXMnXX0pO1xucmVnaXN0ZXIoUGFydE1ldGFkYXRhLCAnUGFydE1ldGFkYXRhJyk7XG5cbmV4cG9ydCBkZWZhdWx0IEZpbGxFeHRydXNpb25CdWNrZXQ7XG5cbi8vIEVkZ2VzIHRoYXQgYXJlIG91dHNpZGUgdGlsZSBib3VuZHMgYXJlIGRlZmluZWQgaW4gdGlsZSBhY3Jvc3MgdGhlIGJvcmRlci5cbi8vIFJlbmRlcmluZyB0aGVtIHR3aWNlIG9mdGVuIHJlc3VsdHMgd2l0aCBaLWZpZ2h0aW5nLlxuLy8gSW4gY2FzZSBvZiBnbG9iZSBhbmQgYXhpcyBhbGlnbmVkIGJvdW5kcywgaXQgaXMgYWxzbyB1c2VmdWwgdG9cbi8vIGRpc2NhcmQgZWRnZXMgdGhhdCBoYXZlIHRoZSBib3RoIGVuZHBvaW50cyBvdXRzaWRlIHRoZSBzYW1lIGJvdW5kLlxuZnVuY3Rpb24gaXNFZGdlT3V0c2lkZUJvdW5kcyhwMTogUG9pbnQsIHAyOiBQb2ludCwgYm91bmRzOiBbUG9pbnQsIFBvaW50XSkge1xuICAgIHJldHVybiAocDEueCA8IGJvdW5kc1swXS54ICYmIHAyLnggPCBib3VuZHNbMF0ueCkgfHxcbiAgICAgICAgICAgKHAxLnggPiBib3VuZHNbMV0ueCAmJiBwMi54ID4gYm91bmRzWzFdLngpIHx8XG4gICAgICAgICAgIChwMS55IDwgYm91bmRzWzBdLnkgJiYgcDIueSA8IGJvdW5kc1swXS55KSB8fFxuICAgICAgICAgICAocDEueSA+IGJvdW5kc1sxXS55ICYmIHAyLnkgPiBib3VuZHNbMV0ueSk7XG59XG5cbmZ1bmN0aW9uIGlzRW50aXJlbHlPdXRzaWRlKHJpbmc6IEFycmF5PFBvaW50Pikge1xuICAgIC8vIERpc2NhcmQgcmluZ3Mgd2l0aCBjb3JuZXJzIG9uIGJvcmRlciBpZiBhbGwgb3RoZXIgdmVydGljZXMgYXJlIG91dHNpZGU6IHRoZXkgZ2V0IGRlZmluZWRcbiAgICAvLyBhbHNvIGluIHRoZSB0aWxlIGFjcm9zcyB0aGUgYm9yZGVyLiBFdmVudHVhbCB6ZXJvIGFyZWEgcmluZ3MgYXQgYm9yZGVyIGFyZSBkaXNjYXJkZWQgYnkgY2xhc3NpZnlSaW5nc1xuICAgIC8vIGFuZCB0aGVyZSBpcyBubyBuZWVkIHRvIGhhbmRsZSB0aGF0IGNhc2UgaGVyZS5cbiAgICByZXR1cm4gcmluZy5ldmVyeShwID0+IHAueCA8PSAwKSB8fFxuICAgICAgICByaW5nLmV2ZXJ5KHAgPT4gcC54ID49IEVYVEVOVCkgfHxcbiAgICAgICAgcmluZy5ldmVyeShwID0+IHAueSA8PSAwKSB8fFxuICAgICAgICByaW5nLmV2ZXJ5KHAgPT4gcC55ID49IEVYVEVOVCk7XG59XG5cbmZ1bmN0aW9uIHRpbGVUb01ldGVyKGNhbm9uaWNhbDogQ2Fub25pY2FsVGlsZUlEKSB7XG4gICAgY29uc3QgY2lyY3VtZmVyZW5jZUF0RXF1YXRvciA9IDQwMDc1MDE3O1xuICAgIGNvbnN0IG1lcmNhdG9yWSA9IGNhbm9uaWNhbC55IC8gKDEgPDwgY2Fub25pY2FsLnopO1xuICAgIGNvbnN0IGV4cCA9IE1hdGguZXhwKE1hdGguUEkgKiAoMSAtIDIgKiBtZXJjYXRvclkpKTtcbiAgICAvLyBzaW1wbGlmeSBjb3MoMiAqIGF0YW4oZSkgLSBQSS8yKSBmcm9tIG1lcmNhdG9yX2Nvb3JkaW5hdGUuanMsIHJlbW92ZSB0cmlnb25vbWV0cmljcy5cbiAgICByZXR1cm4gY2lyY3VtZmVyZW5jZUF0RXF1YXRvciAqIDIgKiBleHAgLyAoZXhwICogZXhwICsgMSkgLyBFWFRFTlQgLyAoMSA8PCBjYW5vbmljYWwueik7XG59XG5cbmZ1bmN0aW9uIGlzQU9Db25jYXZlQW5nbGUocDI6IFBvaW50LCBwMTogUG9pbnQsIHAzOiBQb2ludCkge1xuICAgIGlmIChwMi54IDwgMCB8fCBwMi54ID49IEVYVEVOVCB8fCBwMS54IDwgMCB8fCBwMS54ID49IEVYVEVOVCB8fCBwMy54IDwgMCB8fCBwMy54ID49IEVYVEVOVCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7IC8vIGFuZ2xlcyBhcmUgbm90IHByb2Nlc3NlZCBmb3IgZWRnZXMgdGhhdCBleHRlbmQgb3ZlciB0aWxlIGJvcmRlcnNcbiAgICB9XG4gICAgY29uc3QgYSA9IHAzLnN1YihwMSk7XG4gICAgY29uc3QgYW4gPSBhLnBlcnAoKTtcbiAgICBjb25zdCBiID0gcDIuc3ViKHAxKTtcbiAgICBjb25zdCBhYiA9IGEueCAqIGIueCArIGEueSAqIGIueTtcbiAgICBjb25zdCBjb3NBQiA9IGFiIC8gTWF0aC5zcXJ0KCgoYS54ICogYS54ICsgYS55ICogYS55KSAqIChiLnggKiBiLnggKyBiLnkgKiBiLnkpKSk7XG4gICAgY29uc3QgZG90UHJvZHVjdFdpdGhOb3JtYWwgPSBhbi54ICogYi54ICsgYW4ueSAqIGIueTtcblxuICAgIC8vIEhldXJpc3RpY3M6IGRvbid0IHNoYWRlIGNvbmNhdmUgYW5nbGVzIGFib3ZlIDE1MMKwIChhcmNjb3MoLTAuODY2KSkuXG4gICAgcmV0dXJuIGNvc0FCID4gLTAuODY2ICYmIGRvdFByb2R1Y3RXaXRoTm9ybWFsIDwgMDtcbn1cblxuZnVuY3Rpb24gZW5jb2RlQU9Ub0VkZ2VEaXN0YW5jZShlZGdlRGlzdGFuY2U6IG51bWJlciwgaXNDb25jYXZlQ29ybmVyOiBib29sZWFuLCBlZGdlU3RhcnQ6IGJvb2xlYW4pIHtcbiAgICAvLyBFbmNvZGUgY29uY2F2aXR5IGFuZCBlZGdlIHN0YXJ0L2VuZCB1c2luZyB0aGUgbGVhc3Qgc2lnbmlmaWNhbnQgYml0cy5cbiAgICAvLyBTZWNvbmQgbGVhc3Qgc2lnbmlmaWNhbnQgYml0IDEgZW5jb2RlcyBjb25jYXZpdHkuXG4gICAgLy8gVGhlIGxlYXN0IHNpZ25pZmljYW50IGJpdCAxIG1hcmtzIHRoZSBlZGdlIHN0YXJ0LCAwIGZvciBlZGdlIGVuZC5cbiAgICBjb25zdCBlbmNvZGVkRWRnZURpc3RhbmNlID0gaXNDb25jYXZlQ29ybmVyID8gKGVkZ2VEaXN0YW5jZSB8IDIpIDogKGVkZ2VEaXN0YW5jZSAmIH4yKTtcbiAgICByZXR1cm4gZWRnZVN0YXJ0ID8gKGVuY29kZWRFZGdlRGlzdGFuY2UgfCAxKSA6IChlbmNvZGVkRWRnZURpc3RhbmNlICYgfjEpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZmlsbEV4dHJ1c2lvbkhlaWdodExpZnQoKTogbnVtYmVyIHtcbiAgICAvLyBBIHJlY3RhbmdsZSBjb3ZlcmluZyBnbG9iZSBpcyBzdWJkaXZpZGVkIGludG8gYSBncmlkIG9mIDMyIGNlbGxzXG4gICAgLy8gVGhpcyBpbmZvcm1hdGlvbiBjYW4gYmUgdXNlZCB0byBkZWR1Y2UgYSBtaW5pbXVtIGxpZnQgdmFsdWUgc28gdGhhdFxuICAgIC8vIGZpbGwgZXh0cnVzaW9ucyB3aXRoIDAgaGVpZ2h0IHdpbGwgbmV2ZXIgZ28gYmVsb3cgdGhlIGdyb3VuZC5cbiAgICBjb25zdCBhbmdsZSA9IE1hdGguUEkgLyAzMi4wO1xuICAgIGNvbnN0IHRhbkFuZ2xlID0gTWF0aC50YW4oYW5nbGUpO1xuICAgIGNvbnN0IHIgPSBlYXJ0aFJhZGl1cztcbiAgICByZXR1cm4gciAqIE1hdGguc3FydCgxLjAgKyAyLjAgKiB0YW5BbmdsZSAqIHRhbkFuZ2xlKSAtIHI7XG59XG5cbi8vIFJlc2FtcGxlcyBmaWxsIGV4dHJ1c2lvbiBwb2x5Z29ucyBieSBzdWJkaXZpZGluZyB0aGVtIGludG8gMzJ4MTYgY2VsbHMgaW4gbWVyY2F0b3Igc3BhY2UuXG4vLyBUaGUgaWRlYSBpcyB0byBhbGxvdyByZXByb2plY3Rpb24gb2YgbGFyZ2UgY29udGludW91cyBwbGFuYXIgc2hhcGVzIG9uIHRoZSBzdXJmYWNlIG9mIHRoZSBnbG9iZVxuZXhwb3J0IGZ1bmN0aW9uIHJlc2FtcGxlRmlsbEV4dHJ1c2lvblBvbHlnb25zRm9yR2xvYmUocG9seWdvbnM6IFBvaW50W11bXVtdLCB0aWxlQm91bmRzOiBbUG9pbnQsIFBvaW50XSwgdGlsZUlEOiBDYW5vbmljYWxUaWxlSUQpOiBDbGlwcGVkUG9seWdvbltdIHtcbiAgICBjb25zdCBjZWxsQ291bnQgPSAzNjAuMCAvIDMyLjA7XG4gICAgY29uc3QgdGlsZXMgPSAxIDw8IHRpbGVJRC56O1xuICAgIGNvbnN0IGxlZnRMbmcgPSBsbmdGcm9tTWVyY2F0b3JYKHRpbGVJRC54IC8gdGlsZXMpO1xuICAgIGNvbnN0IHJpZ2h0TG5nID0gbG5nRnJvbU1lcmNhdG9yWCgodGlsZUlELnggKyAxKSAvIHRpbGVzKTtcbiAgICBjb25zdCB0b3BMYXQgPSBsYXRGcm9tTWVyY2F0b3JZKHRpbGVJRC55IC8gdGlsZXMpO1xuICAgIGNvbnN0IGJvdHRvbUxhdCA9IGxhdEZyb21NZXJjYXRvclkoKHRpbGVJRC55ICsgMSkgLyB0aWxlcyk7XG4gICAgY29uc3QgY2VsbENvdW50T25YQXhpcyA9IE1hdGguY2VpbCgocmlnaHRMbmcgLSBsZWZ0TG5nKSAvIGNlbGxDb3VudCk7XG4gICAgY29uc3QgY2VsbENvdW50T25ZQXhpcyA9IE1hdGguY2VpbCgodG9wTGF0IC0gYm90dG9tTGF0KSAvIGNlbGxDb3VudCk7XG5cbiAgICBjb25zdCBzcGxpdEZuID0gKGF4aXM6IG51bWJlciwgbWluOiBudW1iZXIsIG1heDogbnVtYmVyKSA9PiB7XG4gICAgICAgIGlmIChheGlzID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gMC41ICogKG1pbiArIG1heCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBtYXhMYXQgPSBsYXRGcm9tTWVyY2F0b3JZKCh0aWxlSUQueSArIG1pbiAvIEVYVEVOVCkgLyB0aWxlcyk7XG4gICAgICAgICAgICBjb25zdCBtaW5MYXQgPSBsYXRGcm9tTWVyY2F0b3JZKCh0aWxlSUQueSArIG1heCAvIEVYVEVOVCkgLyB0aWxlcyk7XG4gICAgICAgICAgICBjb25zdCBtaWRMYXQgPSAwLjUgKiAobWluTGF0ICsgbWF4TGF0KTtcbiAgICAgICAgICAgIHJldHVybiAobWVyY2F0b3JZZnJvbUxhdChtaWRMYXQpICogdGlsZXMgLSB0aWxlSUQueSkgKiBFWFRFTlQ7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIHN1YmRpdmlkZVBvbHlnb25zKHBvbHlnb25zLCB0aWxlQm91bmRzLCBjZWxsQ291bnRPblhBeGlzLCBjZWxsQ291bnRPbllBeGlzLCAxLjAsIHNwbGl0Rm4pO1xufVxuIiwiLy8gVGhpcyBmaWxlIGlzIGdlbmVyYXRlZC4gRWRpdCBidWlsZC9nZW5lcmF0ZS1zdHlsZS1jb2RlLmpzLCB0aGVuIHJ1biBgeWFybiBydW4gY29kZWdlbmAuXG4vLyBAZmxvd1xuLyogZXNsaW50LWRpc2FibGUgKi9cblxuaW1wb3J0IHN0eWxlU3BlYyBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL3JlZmVyZW5jZS9sYXRlc3QuanMnO1xuXG5pbXBvcnQge1xuICAgIFByb3BlcnRpZXMsXG4gICAgRGF0YUNvbnN0YW50UHJvcGVydHksXG4gICAgRGF0YURyaXZlblByb3BlcnR5LFxuICAgIENvbG9yUmFtcFByb3BlcnR5XG59IGZyb20gJy4uL3Byb3BlcnRpZXMuanMnO1xuXG5pbXBvcnQgdHlwZSBDb2xvciBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL3V0aWwvY29sb3IuanMnO1xuXG5pbXBvcnQgdHlwZSBGb3JtYXR0ZWQgZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy9leHByZXNzaW9uL3R5cGVzL2Zvcm1hdHRlZC5qcyc7XG5cbmltcG9ydCB0eXBlIFJlc29sdmVkSW1hZ2UgZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy9leHByZXNzaW9uL3R5cGVzL3Jlc29sdmVkX2ltYWdlLmpzJztcblxuZXhwb3J0IHR5cGUgTGF5b3V0UHJvcHMgPSB7fFxuICAgIFwiZmlsbC1leHRydXNpb24tZWRnZS1yYWRpdXNcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8bnVtYmVyPixcbnx9O1xuXG5jb25zdCBsYXlvdXQ6IFByb3BlcnRpZXM8TGF5b3V0UHJvcHM+ID0gbmV3IFByb3BlcnRpZXMoe1xuICAgIFwiZmlsbC1leHRydXNpb24tZWRnZS1yYWRpdXNcIjogbmV3IERhdGFDb25zdGFudFByb3BlcnR5KHN0eWxlU3BlY1tcImxheW91dF9maWxsLWV4dHJ1c2lvblwiXVtcImZpbGwtZXh0cnVzaW9uLWVkZ2UtcmFkaXVzXCJdKSxcbn0pO1xuXG5leHBvcnQgdHlwZSBQYWludFByb3BzID0ge3xcbiAgICBcImZpbGwtZXh0cnVzaW9uLW9wYWNpdHlcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8bnVtYmVyPixcbiAgICBcImZpbGwtZXh0cnVzaW9uLWNvbG9yXCI6IERhdGFEcml2ZW5Qcm9wZXJ0eTxDb2xvcj4sXG4gICAgXCJmaWxsLWV4dHJ1c2lvbi10cmFuc2xhdGVcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8W251bWJlciwgbnVtYmVyXT4sXG4gICAgXCJmaWxsLWV4dHJ1c2lvbi10cmFuc2xhdGUtYW5jaG9yXCI6IERhdGFDb25zdGFudFByb3BlcnR5PFwibWFwXCIgfCBcInZpZXdwb3J0XCI+LFxuICAgIFwiZmlsbC1leHRydXNpb24tcGF0dGVyblwiOiBEYXRhRHJpdmVuUHJvcGVydHk8P1Jlc29sdmVkSW1hZ2U+LFxuICAgIFwiZmlsbC1leHRydXNpb24taGVpZ2h0XCI6IERhdGFEcml2ZW5Qcm9wZXJ0eTxudW1iZXI+LFxuICAgIFwiZmlsbC1leHRydXNpb24tYmFzZVwiOiBEYXRhRHJpdmVuUHJvcGVydHk8bnVtYmVyPixcbiAgICBcImZpbGwtZXh0cnVzaW9uLXZlcnRpY2FsLWdyYWRpZW50XCI6IERhdGFDb25zdGFudFByb3BlcnR5PGJvb2xlYW4+LFxuICAgIFwiZmlsbC1leHRydXNpb24tYW1iaWVudC1vY2NsdXNpb24taW50ZW5zaXR5XCI6IERhdGFDb25zdGFudFByb3BlcnR5PG51bWJlcj4sXG4gICAgXCJmaWxsLWV4dHJ1c2lvbi1hbWJpZW50LW9jY2x1c2lvbi1yYWRpdXNcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8bnVtYmVyPixcbiAgICBcImZpbGwtZXh0cnVzaW9uLXJvdW5kZWQtcm9vZlwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxib29sZWFuPixcbnx9O1xuXG5jb25zdCBwYWludDogUHJvcGVydGllczxQYWludFByb3BzPiA9IG5ldyBQcm9wZXJ0aWVzKHtcbiAgICBcImZpbGwtZXh0cnVzaW9uLW9wYWNpdHlcIjogbmV3IERhdGFDb25zdGFudFByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X2ZpbGwtZXh0cnVzaW9uXCJdW1wiZmlsbC1leHRydXNpb24tb3BhY2l0eVwiXSksXG4gICAgXCJmaWxsLWV4dHJ1c2lvbi1jb2xvclwiOiBuZXcgRGF0YURyaXZlblByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X2ZpbGwtZXh0cnVzaW9uXCJdW1wiZmlsbC1leHRydXNpb24tY29sb3JcIl0pLFxuICAgIFwiZmlsbC1leHRydXNpb24tdHJhbnNsYXRlXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9maWxsLWV4dHJ1c2lvblwiXVtcImZpbGwtZXh0cnVzaW9uLXRyYW5zbGF0ZVwiXSksXG4gICAgXCJmaWxsLWV4dHJ1c2lvbi10cmFuc2xhdGUtYW5jaG9yXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9maWxsLWV4dHJ1c2lvblwiXVtcImZpbGwtZXh0cnVzaW9uLXRyYW5zbGF0ZS1hbmNob3JcIl0pLFxuICAgIFwiZmlsbC1leHRydXNpb24tcGF0dGVyblwiOiBuZXcgRGF0YURyaXZlblByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X2ZpbGwtZXh0cnVzaW9uXCJdW1wiZmlsbC1leHRydXNpb24tcGF0dGVyblwiXSksXG4gICAgXCJmaWxsLWV4dHJ1c2lvbi1oZWlnaHRcIjogbmV3IERhdGFEcml2ZW5Qcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9maWxsLWV4dHJ1c2lvblwiXVtcImZpbGwtZXh0cnVzaW9uLWhlaWdodFwiXSksXG4gICAgXCJmaWxsLWV4dHJ1c2lvbi1iYXNlXCI6IG5ldyBEYXRhRHJpdmVuUHJvcGVydHkoc3R5bGVTcGVjW1wicGFpbnRfZmlsbC1leHRydXNpb25cIl1bXCJmaWxsLWV4dHJ1c2lvbi1iYXNlXCJdKSxcbiAgICBcImZpbGwtZXh0cnVzaW9uLXZlcnRpY2FsLWdyYWRpZW50XCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9maWxsLWV4dHJ1c2lvblwiXVtcImZpbGwtZXh0cnVzaW9uLXZlcnRpY2FsLWdyYWRpZW50XCJdKSxcbiAgICBcImZpbGwtZXh0cnVzaW9uLWFtYmllbnQtb2NjbHVzaW9uLWludGVuc2l0eVwiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjW1wicGFpbnRfZmlsbC1leHRydXNpb25cIl1bXCJmaWxsLWV4dHJ1c2lvbi1hbWJpZW50LW9jY2x1c2lvbi1pbnRlbnNpdHlcIl0pLFxuICAgIFwiZmlsbC1leHRydXNpb24tYW1iaWVudC1vY2NsdXNpb24tcmFkaXVzXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9maWxsLWV4dHJ1c2lvblwiXVtcImZpbGwtZXh0cnVzaW9uLWFtYmllbnQtb2NjbHVzaW9uLXJhZGl1c1wiXSksXG4gICAgXCJmaWxsLWV4dHJ1c2lvbi1yb3VuZGVkLXJvb2ZcIjogbmV3IERhdGFDb25zdGFudFByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X2ZpbGwtZXh0cnVzaW9uXCJdW1wiZmlsbC1leHRydXNpb24tcm91bmRlZC1yb29mXCJdKSxcbn0pO1xuXG4vLyBOb3RlOiB3aXRob3V0IGFkZGluZyB0aGUgZXhwbGljaXQgdHlwZSBhbm5vdGF0aW9uLCBGbG93IGluZmVycyB3ZWFrZXIgdHlwZXNcbi8vIGZvciB0aGVzZSBvYmplY3RzIGZyb20gdGhlaXIgdXNlIGluIHRoZSBjb25zdHJ1Y3RvciB0byBTdHlsZUxheWVyLCBhc1xuLy8ge2xheW91dD86IFByb3BlcnRpZXM8Li4uPiwgcGFpbnQ6IFByb3BlcnRpZXM8Li4uPn1cbmV4cG9ydCBkZWZhdWx0ICh7IHBhaW50LCBsYXlvdXQgfTogJEV4YWN0PHtcbiAgcGFpbnQ6IFByb3BlcnRpZXM8UGFpbnRQcm9wcz4sIGxheW91dDogUHJvcGVydGllczxMYXlvdXRQcm9wcz5cbn0+KTtcbiIsImV4cG9ydCB7IGdldFVSTCwgZ2V0VGlsZUJCb3gsIGdldE1lcmNDb29yZHMgfTtcblxuXG4vKipcbiAqIGdldFVSTFxuICpcbiAqIEBwYXJhbSAgICB7U3RyaW5nfSAgYmFzZVVybCAgQmFzZSB1cmwgb2YgdGhlIFdNUyBzZXJ2ZXJcbiAqIEBwYXJhbSAgICB7U3RyaW5nfSAgbGF5ZXIgICAgTGF5ZXIgbmFtZVxuICogQHBhcmFtICAgIHtOdW1iZXJ9ICB4ICAgICAgICBUaWxlIGNvb3JkaW5hdGUgeFxuICogQHBhcmFtICAgIHtOdW1iZXJ9ICB5ICAgICAgICBUaWxlIGNvb3JkaW5hdGUgeVxuICogQHBhcmFtICAgIHtOdW1iZXJ9ICB6ICAgICAgICBUaWxlIHpvb21cbiAqIEBwYXJhbSAgICB7T2JqZWN0fSAgW29wdGlvbnNdXG4gKiBAcGFyYW0gICAge1N0cmluZ30gIFtvcHRpb25zLmZvcm1hdD0naW1hZ2UvcG5nJ11cbiAqIEBwYXJhbSAgICB7U3RyaW5nfSAgW29wdGlvbnMuc2VydmljZT0nV01TJ11cbiAqIEBwYXJhbSAgICB7U3RyaW5nfSAgW29wdGlvbnMudmVyc2lvbj0nMS4xLjEnXVxuICogQHBhcmFtICAgIHtTdHJpbmd9ICBbb3B0aW9ucy5yZXF1ZXN0PSdHZXRNYXAnXVxuICogQHBhcmFtICAgIHtTdHJpbmd9ICBbb3B0aW9ucy5zcnM9J0VQU0c6Mzg1NyddXG4gKiBAcGFyYW0gICAge051bWJlcn0gIFtvcHRpb25zLndpZHRoPScyNTYnXVxuICogQHBhcmFtICAgIHtOdW1iZXJ9ICBbb3B0aW9ucy5oZWlnaHQ9JzI1NiddXG4gKiBAcmV0dXJucyAge1N0cmluZ30gIHVybFxuICogQGV4YW1wbGVcbiAqIHZhciBiYXNlVXJsID0gJ2h0dHA6Ly9nZW9kYXRhLnN0YXRlLm5qLnVzL2ltYWdlcnl3bXMvTmF0dXJhbDIwMTUnO1xuICogdmFyIGxheWVyID0gJ05hdHVyYWwyMDE1JztcbiAqIHZhciB1cmwgPSB3aG9vdHMuZ2V0VVJMKGJhc2VVcmwsIGxheWVyLCAxNTQzMDgsIDE5NzE2NywgMTkpO1xuICovXG5mdW5jdGlvbiBnZXRVUkwoYmFzZVVybCwgbGF5ZXIsIHgsIHksIHosIG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAgIHZhciB1cmwgPSBiYXNlVXJsICsgJz8nICsgW1xuICAgICAgICAnYmJveD0nICAgICsgZ2V0VGlsZUJCb3goeCwgeSwgeiksXG4gICAgICAgICdmb3JtYXQ9JyAgKyAob3B0aW9ucy5mb3JtYXQgfHwgJ2ltYWdlL3BuZycpLFxuICAgICAgICAnc2VydmljZT0nICsgKG9wdGlvbnMuc2VydmljZSB8fCAnV01TJyksXG4gICAgICAgICd2ZXJzaW9uPScgKyAob3B0aW9ucy52ZXJzaW9uIHx8ICcxLjEuMScpLFxuICAgICAgICAncmVxdWVzdD0nICsgKG9wdGlvbnMucmVxdWVzdCB8fCAnR2V0TWFwJyksXG4gICAgICAgICdzcnM9JyAgICAgKyAob3B0aW9ucy5zcnMgfHwgJ0VQU0c6Mzg1NycpLFxuICAgICAgICAnd2lkdGg9JyAgICsgKG9wdGlvbnMud2lkdGggfHwgMjU2KSxcbiAgICAgICAgJ2hlaWdodD0nICArIChvcHRpb25zLmhlaWdodCB8fCAyNTYpLFxuICAgICAgICAnbGF5ZXJzPScgICsgbGF5ZXJcbiAgICBdLmpvaW4oJyYnKTtcblxuICAgIHJldHVybiB1cmw7XG59XG5cblxuLyoqXG4gKiBnZXRUaWxlQkJveFxuICpcbiAqIEBwYXJhbSAgICB7TnVtYmVyfSAgeCAgVGlsZSBjb29yZGluYXRlIHhcbiAqIEBwYXJhbSAgICB7TnVtYmVyfSAgeSAgVGlsZSBjb29yZGluYXRlIHlcbiAqIEBwYXJhbSAgICB7TnVtYmVyfSAgeiAgVGlsZSB6b29tXG4gKiBAcmV0dXJucyAge1N0cmluZ30gIFN0cmluZyBvZiB0aGUgYm91bmRpbmcgYm94XG4gKi9cbmZ1bmN0aW9uIGdldFRpbGVCQm94KHgsIHksIHopIHtcbiAgICAvLyBmb3IgR29vZ2xlL09TTSB0aWxlIHNjaGVtZSB3ZSBuZWVkIHRvIGFsdGVyIHRoZSB5XG4gICAgeSA9IChNYXRoLnBvdygyLCB6KSAtIHkgLSAxKTtcblxuICAgIHZhciBtaW4gPSBnZXRNZXJjQ29vcmRzKHggKiAyNTYsIHkgKiAyNTYsIHopLFxuICAgICAgICBtYXggPSBnZXRNZXJjQ29vcmRzKCh4ICsgMSkgKiAyNTYsICh5ICsgMSkgKiAyNTYsIHopO1xuXG4gICAgcmV0dXJuIG1pblswXSArICcsJyArIG1pblsxXSArICcsJyArIG1heFswXSArICcsJyArIG1heFsxXTtcbn1cblxuXG4vKipcbiAqIGdldE1lcmNDb29yZHNcbiAqXG4gKiBAcGFyYW0gICAge051bWJlcn0gIHggIFBpeGVsIGNvb3JkaW5hdGUgeFxuICogQHBhcmFtICAgIHtOdW1iZXJ9ICB5ICBQaXhlbCBjb29yZGluYXRlIHlcbiAqIEBwYXJhbSAgICB7TnVtYmVyfSAgeiAgVGlsZSB6b29tXG4gKiBAcmV0dXJucyAge0FycmF5fSAgIFt4LCB5XVxuICovXG5mdW5jdGlvbiBnZXRNZXJjQ29vcmRzKHgsIHksIHopIHtcbiAgICB2YXIgcmVzb2x1dGlvbiA9ICgyICogTWF0aC5QSSAqIDYzNzgxMzcgLyAyNTYpIC8gTWF0aC5wb3coMiwgeiksXG4gICAgICAgIG1lcmNfeCA9ICh4ICogcmVzb2x1dGlvbiAtIDIgKiBNYXRoLlBJICAqIDYzNzgxMzcgLyAyLjApLFxuICAgICAgICBtZXJjX3kgPSAoeSAqIHJlc29sdXRpb24gLSAyICogTWF0aC5QSSAgKiA2Mzc4MTM3IC8gMi4wKTtcblxuICAgIHJldHVybiBbbWVyY194LCBtZXJjX3ldO1xufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtnZXRUaWxlQkJveH0gZnJvbSAnQG1hcGJveC93aG9vdHMtanMnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHtyZWdpc3Rlcn0gZnJvbSAnLi4vdXRpbC93ZWJfd29ya2VyX3RyYW5zZmVyLmpzJztcblxuZXhwb3J0IGNsYXNzIENhbm9uaWNhbFRpbGVJRCB7XG4gICAgejogbnVtYmVyO1xuICAgIHg6IG51bWJlcjtcbiAgICB5OiBudW1iZXI7XG4gICAga2V5OiBudW1iZXI7XG5cbiAgICBjb25zdHJ1Y3Rvcih6OiBudW1iZXIsIHg6IG51bWJlciwgeTogbnVtYmVyKSB7XG4gICAgICAgIGFzc2VydCh6ID49IDAgJiYgeiA8PSAyNSk7XG4gICAgICAgIGFzc2VydCh4ID49IDAgJiYgeCA8IE1hdGgucG93KDIsIHopKTtcbiAgICAgICAgYXNzZXJ0KHkgPj0gMCAmJiB5IDwgTWF0aC5wb3coMiwgeikpO1xuICAgICAgICB0aGlzLnogPSB6O1xuICAgICAgICB0aGlzLnggPSB4O1xuICAgICAgICB0aGlzLnkgPSB5O1xuICAgICAgICB0aGlzLmtleSA9IGNhbGN1bGF0ZUtleSgwLCB6LCB6LCB4LCB5KTtcbiAgICB9XG5cbiAgICBlcXVhbHMoaWQ6IENhbm9uaWNhbFRpbGVJRCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy56ID09PSBpZC56ICYmIHRoaXMueCA9PT0gaWQueCAmJiB0aGlzLnkgPT09IGlkLnk7XG4gICAgfVxuXG4gICAgLy8gZ2l2ZW4gYSBsaXN0IG9mIHVybHMsIGNob29zZSBhIHVybCB0ZW1wbGF0ZSBhbmQgcmV0dXJuIGEgdGlsZSBVUkxcbiAgICB1cmwodXJsczogQXJyYXk8c3RyaW5nPiwgc2NoZW1lOiA/c3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgY29uc3QgYmJveCA9IGdldFRpbGVCQm94KHRoaXMueCwgdGhpcy55LCB0aGlzLnopO1xuICAgICAgICBjb25zdCBxdWFka2V5ID0gZ2V0UXVhZGtleSh0aGlzLnosIHRoaXMueCwgdGhpcy55KTtcblxuICAgICAgICByZXR1cm4gdXJsc1sodGhpcy54ICsgdGhpcy55KSAlIHVybHMubGVuZ3RoXVxuICAgICAgICAgICAgLnJlcGxhY2UoJ3twcmVmaXh9JywgKHRoaXMueCAlIDE2KS50b1N0cmluZygxNikgKyAodGhpcy55ICUgMTYpLnRvU3RyaW5nKDE2KSlcbiAgICAgICAgICAgIC5yZXBsYWNlKC97en0vZywgU3RyaW5nKHRoaXMueikpXG4gICAgICAgICAgICAucmVwbGFjZSgve3h9L2csIFN0cmluZyh0aGlzLngpKVxuICAgICAgICAgICAgLnJlcGxhY2UoL3t5fS9nLCBTdHJpbmcoc2NoZW1lID09PSAndG1zJyA/IChNYXRoLnBvdygyLCB0aGlzLnopIC0gdGhpcy55IC0gMSkgOiB0aGlzLnkpKVxuICAgICAgICAgICAgLnJlcGxhY2UoJ3txdWFka2V5fScsIHF1YWRrZXkpXG4gICAgICAgICAgICAucmVwbGFjZSgne2Jib3gtZXBzZy0zODU3fScsIGJib3gpO1xuICAgIH1cblxuICAgIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBgJHt0aGlzLnp9LyR7dGhpcy54fS8ke3RoaXMueX1gO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFVud3JhcHBlZFRpbGVJRCB7XG4gICAgd3JhcDogbnVtYmVyO1xuICAgIGNhbm9uaWNhbDogQ2Fub25pY2FsVGlsZUlEO1xuICAgIGtleTogbnVtYmVyO1xuXG4gICAgY29uc3RydWN0b3Iod3JhcDogbnVtYmVyLCBjYW5vbmljYWw6IENhbm9uaWNhbFRpbGVJRCkge1xuICAgICAgICB0aGlzLndyYXAgPSB3cmFwO1xuICAgICAgICB0aGlzLmNhbm9uaWNhbCA9IGNhbm9uaWNhbDtcbiAgICAgICAgdGhpcy5rZXkgPSBjYWxjdWxhdGVLZXkod3JhcCwgY2Fub25pY2FsLnosIGNhbm9uaWNhbC56LCBjYW5vbmljYWwueCwgY2Fub25pY2FsLnkpO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIE92ZXJzY2FsZWRUaWxlSUQge1xuICAgIG92ZXJzY2FsZWRaOiBudW1iZXI7XG4gICAgd3JhcDogbnVtYmVyO1xuICAgIGNhbm9uaWNhbDogQ2Fub25pY2FsVGlsZUlEO1xuICAgIGtleTogbnVtYmVyO1xuICAgIHByb2pNYXRyaXg6IEZsb2F0MzJBcnJheTtcblxuICAgIGNvbnN0cnVjdG9yKG92ZXJzY2FsZWRaOiBudW1iZXIsIHdyYXA6IG51bWJlciwgejogbnVtYmVyLCB4OiBudW1iZXIsIHk6IG51bWJlcikge1xuICAgICAgICBhc3NlcnQob3ZlcnNjYWxlZFogPj0geik7XG4gICAgICAgIHRoaXMub3ZlcnNjYWxlZFogPSBvdmVyc2NhbGVkWjtcbiAgICAgICAgdGhpcy53cmFwID0gd3JhcDtcbiAgICAgICAgdGhpcy5jYW5vbmljYWwgPSBuZXcgQ2Fub25pY2FsVGlsZUlEKHosICt4LCAreSk7XG4gICAgICAgIHRoaXMua2V5ID0gd3JhcCA9PT0gMCAmJiBvdmVyc2NhbGVkWiA9PT0geiA/IHRoaXMuY2Fub25pY2FsLmtleSA6IGNhbGN1bGF0ZUtleSh3cmFwLCBvdmVyc2NhbGVkWiwgeiwgeCwgeSk7XG4gICAgfVxuXG4gICAgZXF1YWxzKGlkOiBPdmVyc2NhbGVkVGlsZUlEKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLm92ZXJzY2FsZWRaID09PSBpZC5vdmVyc2NhbGVkWiAmJiB0aGlzLndyYXAgPT09IGlkLndyYXAgJiYgdGhpcy5jYW5vbmljYWwuZXF1YWxzKGlkLmNhbm9uaWNhbCk7XG4gICAgfVxuXG4gICAgc2NhbGVkVG8odGFyZ2V0WjogbnVtYmVyKTogT3ZlcnNjYWxlZFRpbGVJRCB7XG4gICAgICAgIGFzc2VydCh0YXJnZXRaIDw9IHRoaXMub3ZlcnNjYWxlZFopO1xuICAgICAgICBjb25zdCB6RGlmZmVyZW5jZSA9IHRoaXMuY2Fub25pY2FsLnogLSB0YXJnZXRaO1xuICAgICAgICBpZiAodGFyZ2V0WiA+IHRoaXMuY2Fub25pY2FsLnopIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgT3ZlcnNjYWxlZFRpbGVJRCh0YXJnZXRaLCB0aGlzLndyYXAsIHRoaXMuY2Fub25pY2FsLnosIHRoaXMuY2Fub25pY2FsLngsIHRoaXMuY2Fub25pY2FsLnkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBPdmVyc2NhbGVkVGlsZUlEKHRhcmdldFosIHRoaXMud3JhcCwgdGFyZ2V0WiwgdGhpcy5jYW5vbmljYWwueCA+PiB6RGlmZmVyZW5jZSwgdGhpcy5jYW5vbmljYWwueSA+PiB6RGlmZmVyZW5jZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKlxuICAgICAqIGNhbGN1bGF0ZVNjYWxlZEtleSBpcyBhbiBvcHRpbWl6YXRpb246XG4gICAgICogd2hlbiB3aXRoV3JhcCA9PSB0cnVlLCBpbXBsZW1lbnRzIHRoZSBzYW1lIGFzIHRoaXMuc2NhbGVkVG8oeikua2V5LFxuICAgICAqIHdoZW4gd2l0aFdyYXAgPT0gZmFsc2UsIGltcGxlbWVudHMgdGhlIHNhbWUgYXMgdGhpcy5zY2FsZWRUbyh6KS53cmFwcGVkKCkua2V5LlxuICAgICAqL1xuICAgIGNhbGN1bGF0ZVNjYWxlZEtleSh0YXJnZXRaOiBudW1iZXIsIHdpdGhXcmFwOiBib29sZWFuID0gdHJ1ZSk6IG51bWJlciB7XG4gICAgICAgIGlmICh0aGlzLm92ZXJzY2FsZWRaID09PSB0YXJnZXRaICYmIHdpdGhXcmFwKSByZXR1cm4gdGhpcy5rZXk7XG4gICAgICAgIGlmICh0YXJnZXRaID4gdGhpcy5jYW5vbmljYWwueikge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGN1bGF0ZUtleSh0aGlzLndyYXAgKiArd2l0aFdyYXAsIHRhcmdldFosIHRoaXMuY2Fub25pY2FsLnosIHRoaXMuY2Fub25pY2FsLngsIHRoaXMuY2Fub25pY2FsLnkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgekRpZmZlcmVuY2UgPSB0aGlzLmNhbm9uaWNhbC56IC0gdGFyZ2V0WjtcbiAgICAgICAgICAgIHJldHVybiBjYWxjdWxhdGVLZXkodGhpcy53cmFwICogK3dpdGhXcmFwLCB0YXJnZXRaLCB0YXJnZXRaLCB0aGlzLmNhbm9uaWNhbC54ID4+IHpEaWZmZXJlbmNlLCB0aGlzLmNhbm9uaWNhbC55ID4+IHpEaWZmZXJlbmNlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlzQ2hpbGRPZihwYXJlbnQ6IE92ZXJzY2FsZWRUaWxlSUQpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKHBhcmVudC53cmFwICE9PSB0aGlzLndyYXApIHtcbiAgICAgICAgICAgIC8vIFdlIGNhbid0IGJlIGEgY2hpbGQgaWYgd2UncmUgaW4gYSBkaWZmZXJlbnQgd29ybGQgY29weVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHpEaWZmZXJlbmNlID0gdGhpcy5jYW5vbmljYWwueiAtIHBhcmVudC5jYW5vbmljYWwuejtcbiAgICAgICAgLy8gV2UncmUgZmlyc3QgdGVzdGluZyBmb3IgeiA9PSAwLCB0byBhdm9pZCBhIDMyIGJpdCBzaGlmdCwgd2hpY2ggaXMgdW5kZWZpbmVkLlxuICAgICAgICByZXR1cm4gcGFyZW50Lm92ZXJzY2FsZWRaID09PSAwIHx8IChcbiAgICAgICAgICAgIHBhcmVudC5vdmVyc2NhbGVkWiA8IHRoaXMub3ZlcnNjYWxlZFogJiZcbiAgICAgICAgICAgICAgICBwYXJlbnQuY2Fub25pY2FsLnggPT09ICh0aGlzLmNhbm9uaWNhbC54ID4+IHpEaWZmZXJlbmNlKSAmJlxuICAgICAgICAgICAgICAgIHBhcmVudC5jYW5vbmljYWwueSA9PT0gKHRoaXMuY2Fub25pY2FsLnkgPj4gekRpZmZlcmVuY2UpKTtcbiAgICB9XG5cbiAgICBjaGlsZHJlbihzb3VyY2VNYXhab29tOiBudW1iZXIpOiBBcnJheTxPdmVyc2NhbGVkVGlsZUlEPiB7XG4gICAgICAgIGlmICh0aGlzLm92ZXJzY2FsZWRaID49IHNvdXJjZU1heFpvb20pIHtcbiAgICAgICAgICAgIC8vIHJldHVybiBhIHNpbmdsZSB0aWxlIGNvb3JkIHJlcHJlc2VudGluZyBhIGFuIG92ZXJzY2FsZWQgdGlsZVxuICAgICAgICAgICAgcmV0dXJuIFtuZXcgT3ZlcnNjYWxlZFRpbGVJRCh0aGlzLm92ZXJzY2FsZWRaICsgMSwgdGhpcy53cmFwLCB0aGlzLmNhbm9uaWNhbC56LCB0aGlzLmNhbm9uaWNhbC54LCB0aGlzLmNhbm9uaWNhbC55KV07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB6ID0gdGhpcy5jYW5vbmljYWwueiArIDE7XG4gICAgICAgIGNvbnN0IHggPSB0aGlzLmNhbm9uaWNhbC54ICogMjtcbiAgICAgICAgY29uc3QgeSA9IHRoaXMuY2Fub25pY2FsLnkgKiAyO1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgbmV3IE92ZXJzY2FsZWRUaWxlSUQoeiwgdGhpcy53cmFwLCB6LCB4LCB5KSxcbiAgICAgICAgICAgIG5ldyBPdmVyc2NhbGVkVGlsZUlEKHosIHRoaXMud3JhcCwgeiwgeCArIDEsIHkpLFxuICAgICAgICAgICAgbmV3IE92ZXJzY2FsZWRUaWxlSUQoeiwgdGhpcy53cmFwLCB6LCB4LCB5ICsgMSksXG4gICAgICAgICAgICBuZXcgT3ZlcnNjYWxlZFRpbGVJRCh6LCB0aGlzLndyYXAsIHosIHggKyAxLCB5ICsgMSlcbiAgICAgICAgXTtcbiAgICB9XG5cbiAgICBpc0xlc3NUaGFuKHJoczogT3ZlcnNjYWxlZFRpbGVJRCk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAodGhpcy53cmFwIDwgcmhzLndyYXApIHJldHVybiB0cnVlO1xuICAgICAgICBpZiAodGhpcy53cmFwID4gcmhzLndyYXApIHJldHVybiBmYWxzZTtcblxuICAgICAgICBpZiAodGhpcy5vdmVyc2NhbGVkWiA8IHJocy5vdmVyc2NhbGVkWikgcmV0dXJuIHRydWU7XG4gICAgICAgIGlmICh0aGlzLm92ZXJzY2FsZWRaID4gcmhzLm92ZXJzY2FsZWRaKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgaWYgKHRoaXMuY2Fub25pY2FsLnggPCByaHMuY2Fub25pY2FsLngpIHJldHVybiB0cnVlO1xuICAgICAgICBpZiAodGhpcy5jYW5vbmljYWwueCA+IHJocy5jYW5vbmljYWwueCkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIGlmICh0aGlzLmNhbm9uaWNhbC55IDwgcmhzLmNhbm9uaWNhbC55KSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHdyYXBwZWQoKTogT3ZlcnNjYWxlZFRpbGVJRCB7XG4gICAgICAgIHJldHVybiBuZXcgT3ZlcnNjYWxlZFRpbGVJRCh0aGlzLm92ZXJzY2FsZWRaLCAwLCB0aGlzLmNhbm9uaWNhbC56LCB0aGlzLmNhbm9uaWNhbC54LCB0aGlzLmNhbm9uaWNhbC55KTtcbiAgICB9XG5cbiAgICB1bndyYXBUbyh3cmFwOiBudW1iZXIpOiBPdmVyc2NhbGVkVGlsZUlEIHtcbiAgICAgICAgcmV0dXJuIG5ldyBPdmVyc2NhbGVkVGlsZUlEKHRoaXMub3ZlcnNjYWxlZFosIHdyYXAsIHRoaXMuY2Fub25pY2FsLnosIHRoaXMuY2Fub25pY2FsLngsIHRoaXMuY2Fub25pY2FsLnkpO1xuICAgIH1cblxuICAgIG92ZXJzY2FsZUZhY3RvcigpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gTWF0aC5wb3coMiwgdGhpcy5vdmVyc2NhbGVkWiAtIHRoaXMuY2Fub25pY2FsLnopO1xuICAgIH1cblxuICAgIHRvVW53cmFwcGVkKCk6IFVud3JhcHBlZFRpbGVJRCB7XG4gICAgICAgIHJldHVybiBuZXcgVW53cmFwcGVkVGlsZUlEKHRoaXMud3JhcCwgdGhpcy5jYW5vbmljYWwpO1xuICAgIH1cblxuICAgIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBgJHt0aGlzLm92ZXJzY2FsZWRafS8ke3RoaXMuY2Fub25pY2FsLnh9LyR7dGhpcy5jYW5vbmljYWwueX1gO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gY2FsY3VsYXRlS2V5KHdyYXA6IG51bWJlciwgb3ZlcnNjYWxlZFo6IG51bWJlciwgejogbnVtYmVyLCB4OiBudW1iZXIsIHk6IG51bWJlcik6IG51bWJlciB7XG4gICAgLy8gb25seSB1c2UgMjIgYml0cyBmb3IgeCAmIHkgc28gdGhhdCB0aGUga2V5IGZpdHMgaW50byBNQVhfU0FGRV9JTlRFR0VSXG4gICAgY29uc3QgZGltID0gMSA8PCBNYXRoLm1pbih6LCAyMik7XG4gICAgbGV0IHh5ID0gZGltICogKHkgJSBkaW0pICsgKHggJSBkaW0pO1xuXG4gICAgLy8gemlnemFnLWVuY29kZSB3cmFwIGlmIHdlIGhhdmUgdGhlIHJvb20gZm9yIGl0XG4gICAgaWYgKHdyYXAgJiYgeiA8IDIyKSB7XG4gICAgICAgIGNvbnN0IGJpdHNBdmFpbGFibGUgPSAyICogKDIyIC0geik7XG4gICAgICAgIHh5ICs9IGRpbSAqIGRpbSAqICgod3JhcCA8IDAgPyAtMiAqIHdyYXAgLSAxIDogMiAqIHdyYXApICUgKDEgPDwgYml0c0F2YWlsYWJsZSkpO1xuICAgIH1cblxuICAgIC8vIGVuY29kZSB6IGludG8gNSBiaXRzICgyNCBtYXgpIGFuZCBvdmVyc2NhbGVkWiBpbnRvIDQgYml0cyAoMTAgbWF4KVxuICAgIGNvbnN0IGtleSA9ICgoeHkgKiAzMikgKyB6KSAqIDE2ICsgKG92ZXJzY2FsZWRaIC0geik7XG4gICAgYXNzZXJ0KGtleSA+PSAwICYmIGtleSA8PSBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUik7XG5cbiAgICByZXR1cm4ga2V5O1xufVxuXG5mdW5jdGlvbiBnZXRRdWFka2V5KHo6IG51bWJlciwgeDogbnVtYmVyLCB5OiBudW1iZXIpIHtcbiAgICBsZXQgcXVhZGtleSA9ICcnLCBtYXNrO1xuICAgIGZvciAobGV0IGkgPSB6OyBpID4gMDsgaS0tKSB7XG4gICAgICAgIG1hc2sgPSAxIDw8IChpIC0gMSk7XG4gICAgICAgIHF1YWRrZXkgKz0gKCh4ICYgbWFzayA/IDEgOiAwKSArICh5ICYgbWFzayA/IDIgOiAwKSk7XG4gICAgfVxuICAgIHJldHVybiBxdWFka2V5O1xufVxuXG5yZWdpc3RlcihDYW5vbmljYWxUaWxlSUQsICdDYW5vbmljYWxUaWxlSUQnKTtcbnJlZ2lzdGVyKE92ZXJzY2FsZWRUaWxlSUQsICdPdmVyc2NhbGVkVGlsZUlEJywge29taXQ6IFsncHJvak1hdHJpeCddfSk7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgU3R5bGVMYXllciBmcm9tICcuLi9zdHlsZV9sYXllci5qcyc7XG5pbXBvcnQgRmlsbEV4dHJ1c2lvbkJ1Y2tldCwge0VMRVZBVElPTl9TQ0FMRSwgRUxFVkFUSU9OX09GRlNFVCwgZmlsbEV4dHJ1c2lvbkhlaWdodExpZnQsIHJlc2FtcGxlRmlsbEV4dHJ1c2lvblBvbHlnb25zRm9yR2xvYmV9IGZyb20gJy4uLy4uL2RhdGEvYnVja2V0L2ZpbGxfZXh0cnVzaW9uX2J1Y2tldC5qcyc7XG5pbXBvcnQge3BvbHlnb25JbnRlcnNlY3RzUG9seWdvbiwgcG9seWdvbkludGVyc2VjdHNNdWx0aVBvbHlnb259IGZyb20gJy4uLy4uL3V0aWwvaW50ZXJzZWN0aW9uX3Rlc3RzLmpzJztcbmltcG9ydCB7dHJhbnNsYXRlRGlzdGFuY2UsIHRpbGVzcGFjZVRyYW5zbGF0ZX0gZnJvbSAnLi4vcXVlcnlfdXRpbHMuanMnO1xuaW1wb3J0IHByb3BlcnRpZXMgZnJvbSAnLi9maWxsX2V4dHJ1c2lvbl9zdHlsZV9sYXllcl9wcm9wZXJ0aWVzLmpzJztcbmltcG9ydCB7VHJhbnNpdGlvbmFibGUsIFRyYW5zaXRpb25pbmcsIFBvc3NpYmx5RXZhbHVhdGVkfSBmcm9tICcuLi9wcm9wZXJ0aWVzLmpzJztcbmltcG9ydCBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCBQcm9ncmFtQ29uZmlndXJhdGlvbiBmcm9tICcuLi8uLi9kYXRhL3Byb2dyYW1fY29uZmlndXJhdGlvbi5qcyc7XG5pbXBvcnQge3ZlYzMsIHZlYzR9IGZyb20gJ2dsLW1hdHJpeCc7XG5pbXBvcnQgRVhURU5UIGZyb20gJy4uLy4uL2RhdGEvZXh0ZW50LmpzJztcbmltcG9ydCB7Q2Fub25pY2FsVGlsZUlEfSBmcm9tICcuLi8uLi9zb3VyY2UvdGlsZV9pZC5qcyc7XG5cbmltcG9ydCB0eXBlIHtGZWF0dXJlU3RhdGV9IGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi9pbmRleC5qcyc7XG5pbXBvcnQgdHlwZSB7QnVja2V0UGFyYW1ldGVyc30gZnJvbSAnLi4vLi4vZGF0YS9idWNrZXQuanMnO1xuaW1wb3J0IHR5cGUge1BhaW50UHJvcHMsIExheW91dFByb3BzfSBmcm9tICcuL2ZpbGxfZXh0cnVzaW9uX3N0eWxlX2xheWVyX3Byb3BlcnRpZXMuanMnO1xuaW1wb3J0IHR5cGUgVHJhbnNmb3JtIGZyb20gJy4uLy4uL2dlby90cmFuc2Zvcm0uanMnO1xuaW1wb3J0IHR5cGUge0xheWVyU3BlY2lmaWNhdGlvbn0gZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy90eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSB7VGlsZXNwYWNlUXVlcnlHZW9tZXRyeX0gZnJvbSAnLi4vcXVlcnlfZ2VvbWV0cnkuanMnO1xuaW1wb3J0IHR5cGUge0RFTVNhbXBsZXJ9IGZyb20gJy4uLy4uL3RlcnJhaW4vZWxldmF0aW9uLmpzJztcbmltcG9ydCB0eXBlIHtWZWMyLCBWZWM0fSBmcm9tICdnbC1tYXRyaXgnO1xuaW1wb3J0IHR5cGUge0lWZWN0b3JUaWxlRmVhdHVyZX0gZnJvbSAnQG1hcGJveC92ZWN0b3ItdGlsZSc7XG5cbmNsYXNzIFBvaW50M0QgZXh0ZW5kcyBQb2ludCB7XG4gICAgejogbnVtYmVyO1xuXG4gICAgY29uc3RydWN0b3IoeDogbnVtYmVyLCB5OiBudW1iZXIsIHo6IG51bWJlcikge1xuICAgICAgICBzdXBlcih4LCB5KTtcbiAgICAgICAgdGhpcy56ID0gejtcbiAgICB9XG59XG5cbmNsYXNzIEZpbGxFeHRydXNpb25TdHlsZUxheWVyIGV4dGVuZHMgU3R5bGVMYXllciB7XG4gICAgX3RyYW5zaXRpb25hYmxlUGFpbnQ6IFRyYW5zaXRpb25hYmxlPFBhaW50UHJvcHM+O1xuICAgIF90cmFuc2l0aW9uaW5nUGFpbnQ6IFRyYW5zaXRpb25pbmc8UGFpbnRQcm9wcz47XG4gICAgcGFpbnQ6IFBvc3NpYmx5RXZhbHVhdGVkPFBhaW50UHJvcHM+O1xuICAgIGxheW91dDogUG9zc2libHlFdmFsdWF0ZWQ8TGF5b3V0UHJvcHM+O1xuXG4gICAgY29uc3RydWN0b3IobGF5ZXI6IExheWVyU3BlY2lmaWNhdGlvbikge1xuICAgICAgICBzdXBlcihsYXllciwgcHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgY3JlYXRlQnVja2V0KHBhcmFtZXRlcnM6IEJ1Y2tldFBhcmFtZXRlcnM8RmlsbEV4dHJ1c2lvblN0eWxlTGF5ZXI+KTogRmlsbEV4dHJ1c2lvbkJ1Y2tldCB7XG4gICAgICAgIHJldHVybiBuZXcgRmlsbEV4dHJ1c2lvbkJ1Y2tldChwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgcXVlcnlSYWRpdXMoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRyYW5zbGF0ZURpc3RhbmNlKHRoaXMucGFpbnQuZ2V0KCdmaWxsLWV4dHJ1c2lvbi10cmFuc2xhdGUnKSk7XG4gICAgfVxuXG4gICAgaXMzRCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgZ2V0UHJvZ3JhbUlkcygpOiBzdHJpbmdbXSB7XG4gICAgICAgIGNvbnN0IHBhdHRlcm5Qcm9wZXJ0eSA9IHRoaXMucGFpbnQuZ2V0KCdmaWxsLWV4dHJ1c2lvbi1wYXR0ZXJuJyk7XG4gICAgICAgIGNvbnN0IGltYWdlID0gcGF0dGVyblByb3BlcnR5LmNvbnN0YW50T3IoKDE6IGFueSkpO1xuICAgICAgICByZXR1cm4gW2ltYWdlID8gJ2ZpbGxFeHRydXNpb25QYXR0ZXJuJyA6ICdmaWxsRXh0cnVzaW9uJ107XG4gICAgfVxuXG4gICAgZ2V0UHJvZ3JhbUNvbmZpZ3VyYXRpb24oem9vbTogbnVtYmVyKTogUHJvZ3JhbUNvbmZpZ3VyYXRpb24ge1xuICAgICAgICByZXR1cm4gbmV3IFByb2dyYW1Db25maWd1cmF0aW9uKHRoaXMsIHpvb20pO1xuICAgIH1cblxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICBxdWVyeUludGVyc2VjdHNGZWF0dXJlKHF1ZXJ5R2VvbWV0cnk6IFRpbGVzcGFjZVF1ZXJ5R2VvbWV0cnksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBmZWF0dXJlOiBJVmVjdG9yVGlsZUZlYXR1cmUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBmZWF0dXJlU3RhdGU6IEZlYXR1cmVTdGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlb21ldHJ5OiBBcnJheTxBcnJheTxQb2ludD4+LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgem9vbTogbnVtYmVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtOiBUcmFuc2Zvcm0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBwaXhlbFBvc01hdHJpeDogRmxvYXQzMkFycmF5LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxldmF0aW9uSGVscGVyOiA/REVNU2FtcGxlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxheW91dFZlcnRleEFycmF5T2Zmc2V0OiBudW1iZXIpOiBib29sZWFuIHwgbnVtYmVyIHtcblxuICAgICAgICBjb25zdCB0cmFuc2xhdGlvbiA9IHRpbGVzcGFjZVRyYW5zbGF0ZSh0aGlzLnBhaW50LmdldCgnZmlsbC1leHRydXNpb24tdHJhbnNsYXRlJyksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGFpbnQuZ2V0KCdmaWxsLWV4dHJ1c2lvbi10cmFuc2xhdGUtYW5jaG9yJyksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybS5hbmdsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVlcnlHZW9tZXRyeS5waXhlbFRvVGlsZVVuaXRzRmFjdG9yKTtcbiAgICAgICAgY29uc3QgaGVpZ2h0ID0gdGhpcy5wYWludC5nZXQoJ2ZpbGwtZXh0cnVzaW9uLWhlaWdodCcpLmV2YWx1YXRlKGZlYXR1cmUsIGZlYXR1cmVTdGF0ZSk7XG4gICAgICAgIGNvbnN0IGJhc2UgPSB0aGlzLnBhaW50LmdldCgnZmlsbC1leHRydXNpb24tYmFzZScpLmV2YWx1YXRlKGZlYXR1cmUsIGZlYXR1cmVTdGF0ZSk7XG5cbiAgICAgICAgY29uc3QgY2VudHJvaWQgPSBbMCwgMF07XG4gICAgICAgIGNvbnN0IHRlcnJhaW5WaXNpYmxlID0gZWxldmF0aW9uSGVscGVyICYmIHRyYW5zZm9ybS5lbGV2YXRpb247XG4gICAgICAgIGNvbnN0IGV4YWdnZXJhdGlvbiA9IHRyYW5zZm9ybS5lbGV2YXRpb24gPyB0cmFuc2Zvcm0uZWxldmF0aW9uLmV4YWdnZXJhdGlvbigpIDogMTtcbiAgICAgICAgY29uc3QgYnVja2V0ID0gcXVlcnlHZW9tZXRyeS50aWxlLmdldEJ1Y2tldCh0aGlzKTtcbiAgICAgICAgaWYgKHRlcnJhaW5WaXNpYmxlICYmIGJ1Y2tldCBpbnN0YW5jZW9mIEZpbGxFeHRydXNpb25CdWNrZXQpIHtcbiAgICAgICAgICAgIGNvbnN0IGNlbnRyb2lkVmVydGV4QXJyYXkgPSBidWNrZXQuY2VudHJvaWRWZXJ0ZXhBcnJheTtcblxuICAgICAgICAgICAgLy8gU2VlIEZpbGxFeHRydXNpb25CdWNrZXQjZW5jb2RlQ2VudHJvaWQoKSwgY2VudHJvaWQgaXMgaW5zZXJ0ZWQgYXQgdmVydGV4T2Zmc2V0ICsgMVxuICAgICAgICAgICAgY29uc3QgY2VudHJvaWRPZmZzZXQgPSBsYXlvdXRWZXJ0ZXhBcnJheU9mZnNldCArIDE7XG4gICAgICAgICAgICBpZiAoY2VudHJvaWRPZmZzZXQgPCBjZW50cm9pZFZlcnRleEFycmF5Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGNlbnRyb2lkWzBdID0gY2VudHJvaWRWZXJ0ZXhBcnJheS5nZXRhX2NlbnRyb2lkX3BvczAoY2VudHJvaWRPZmZzZXQpO1xuICAgICAgICAgICAgICAgIGNlbnRyb2lkWzFdID0gY2VudHJvaWRWZXJ0ZXhBcnJheS5nZXRhX2NlbnRyb2lkX3BvczEoY2VudHJvaWRPZmZzZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gRWFybHkgZXhpdCBpZiBmaWxsIGV4dHJ1c2lvbiBpcyBzdGlsbCBoaWRkZW4gd2hpbGUgd2FpdGluZyBmb3IgYmFja2ZpbGxcbiAgICAgICAgY29uc3QgaXNIaWRkZW4gPSBjZW50cm9pZFswXSA9PT0gMCAmJiBjZW50cm9pZFsxXSA9PT0gMTtcbiAgICAgICAgaWYgKGlzSGlkZGVuKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgaWYgKHRyYW5zZm9ybS5wcm9qZWN0aW9uLm5hbWUgPT09ICdnbG9iZScpIHtcbiAgICAgICAgICAgIC8vIEZpbGwgZXh0cnVzaW9uIGdlb21ldHJ5IGhhcyB0byBiZSByZXNhbXBsZWQgc28gdGhhdCBsYXJnZSBwbGFuYXIgcG9seWdvbnNcbiAgICAgICAgICAgIC8vIGNhbiBiZSByZW5kZXJlZCBvbiB0aGUgY3VydmVkIHN1cmZhY2VcbiAgICAgICAgICAgIGNvbnN0IGJvdW5kcyA9IFtuZXcgUG9pbnQoMCwgMCksIG5ldyBQb2ludChFWFRFTlQsIEVYVEVOVCldO1xuICAgICAgICAgICAgY29uc3QgcmVzYW1wbGVkR2VvbWV0cnkgPSByZXNhbXBsZUZpbGxFeHRydXNpb25Qb2x5Z29uc0Zvckdsb2JlKFtnZW9tZXRyeV0sIGJvdW5kcywgcXVlcnlHZW9tZXRyeS50aWxlSUQuY2Fub25pY2FsKTtcbiAgICAgICAgICAgIGdlb21ldHJ5ID0gcmVzYW1wbGVkR2VvbWV0cnkubWFwKGNsaXBwZWQgPT4gY2xpcHBlZC5wb2x5Z29uKS5mbGF0KCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkZW1TYW1wbGVyID0gdGVycmFpblZpc2libGUgPyBlbGV2YXRpb25IZWxwZXIgOiBudWxsO1xuICAgICAgICBjb25zdCBbcHJvamVjdGVkQmFzZSwgcHJvamVjdGVkVG9wXSA9IHByb2plY3RFeHRydXNpb24odHJhbnNmb3JtLCBnZW9tZXRyeSwgYmFzZSwgaGVpZ2h0LCB0cmFuc2xhdGlvbiwgcGl4ZWxQb3NNYXRyaXgsIGRlbVNhbXBsZXIsIGNlbnRyb2lkLCBleGFnZ2VyYXRpb24sIHRyYW5zZm9ybS5jZW50ZXIubGF0LCBxdWVyeUdlb21ldHJ5LnRpbGVJRC5jYW5vbmljYWwpO1xuXG4gICAgICAgIGNvbnN0IHNjcmVlblF1ZXJ5ID0gcXVlcnlHZW9tZXRyeS5xdWVyeUdlb21ldHJ5O1xuICAgICAgICBjb25zdCBwcm9qZWN0ZWRRdWVyeUdlb21ldHJ5ID0gc2NyZWVuUXVlcnkuaXNQb2ludFF1ZXJ5KCkgPyBzY3JlZW5RdWVyeS5zY3JlZW5Cb3VuZHMgOiBzY3JlZW5RdWVyeS5zY3JlZW5HZW9tZXRyeTtcbiAgICAgICAgcmV0dXJuIGNoZWNrSW50ZXJzZWN0aW9uKHByb2plY3RlZEJhc2UsIHByb2plY3RlZFRvcCwgcHJvamVjdGVkUXVlcnlHZW9tZXRyeSk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkb3QoYTogUG9pbnQsIGI6IFBvaW50KSB7XG4gICAgcmV0dXJuIGEueCAqIGIueCArIGEueSAqIGIueTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEludGVyc2VjdGlvbkRpc3RhbmNlKHByb2plY3RlZFF1ZXJ5R2VvbWV0cnk6IEFycmF5PFBvaW50PiwgcHJvamVjdGVkRmFjZTogQXJyYXk8UG9pbnQzRD4pOiBudW1iZXIge1xuXG4gICAgaWYgKHByb2plY3RlZFF1ZXJ5R2VvbWV0cnkubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIC8vIEZvciBwb2ludCBxdWVyaWVzIGNhbGN1bGF0ZSB0aGUgeiBhdCB3aGljaCB0aGUgcG9pbnQgaW50ZXJzZWN0cyB0aGUgZmFjZVxuICAgICAgICAvLyB1c2luZyBiYXJ5Y2VudHJpYyBjb29yZGluYXRlcy5cblxuICAgICAgICAvLyBGaW5kIHRoZSBiYXJ5Y2VudHJpYyBjb29yZGluYXRlcyBvZiB0aGUgcHJvamVjdGVkIHBvaW50IHdpdGhpbiB0aGUgZmlyc3RcbiAgICAgICAgLy8gdHJpYW5nbGUgb2YgdGhlIGZhY2UsIHVzaW5nIG9ubHkgdGhlIHh5IHBsYW5lLiBJdCBkb2Vzbid0IG1hdHRlciBpZiB0aGVcbiAgICAgICAgLy8gcG9pbnQgaXMgb3V0c2lkZSB0aGUgZmlyc3QgdHJpYW5nbGUgYmVjYXVzZSBhbGwgdGhlIHRyaWFuZ2xlcyBpbiB0aGUgZmFjZVxuICAgICAgICAvLyBhcmUgaW4gdGhlIHNhbWUgcGxhbmUuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIENoZWNrIHdoZXRoZXIgcG9pbnRzIGFyZSBjb2luY2lkZW50IGFuZCB1c2Ugb3RoZXIgcG9pbnRzIGlmIHRoZXkgYXJlLlxuICAgICAgICBsZXQgaSA9IDA7XG4gICAgICAgIGNvbnN0IGEgPSBwcm9qZWN0ZWRGYWNlW2krK107XG4gICAgICAgIGxldCBiO1xuICAgICAgICB3aGlsZSAoIWIgfHwgYS5lcXVhbHMoYikpIHtcbiAgICAgICAgICAgIGIgPSBwcm9qZWN0ZWRGYWNlW2krK107XG4gICAgICAgICAgICBpZiAoIWIpIHJldHVybiBJbmZpbml0eTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIExvb3AgdW50aWwgcG9pbnQgYGNgIGlzIG5vdCBjb2xpbmVhciB3aXRoIHBvaW50cyBgYWAgYW5kIGBiYC5cbiAgICAgICAgZm9yICg7IGkgPCBwcm9qZWN0ZWRGYWNlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBjID0gcHJvamVjdGVkRmFjZVtpXTtcblxuICAgICAgICAgICAgY29uc3QgcCA9IHByb2plY3RlZFF1ZXJ5R2VvbWV0cnlbMF07XG5cbiAgICAgICAgICAgIGNvbnN0IGFiID0gYi5zdWIoYSk7XG4gICAgICAgICAgICBjb25zdCBhYyA9IGMuc3ViKGEpO1xuICAgICAgICAgICAgY29uc3QgYXAgPSBwLnN1YihhKTtcblxuICAgICAgICAgICAgY29uc3QgZG90QUJBQiA9IGRvdChhYiwgYWIpO1xuICAgICAgICAgICAgY29uc3QgZG90QUJBQyA9IGRvdChhYiwgYWMpO1xuICAgICAgICAgICAgY29uc3QgZG90QUNBQyA9IGRvdChhYywgYWMpO1xuICAgICAgICAgICAgY29uc3QgZG90QVBBQiA9IGRvdChhcCwgYWIpO1xuICAgICAgICAgICAgY29uc3QgZG90QVBBQyA9IGRvdChhcCwgYWMpO1xuICAgICAgICAgICAgY29uc3QgZGVub20gPSBkb3RBQkFCICogZG90QUNBQyAtIGRvdEFCQUMgKiBkb3RBQkFDO1xuXG4gICAgICAgICAgICBjb25zdCB2ID0gKGRvdEFDQUMgKiBkb3RBUEFCIC0gZG90QUJBQyAqIGRvdEFQQUMpIC8gZGVub207XG4gICAgICAgICAgICBjb25zdCB3ID0gKGRvdEFCQUIgKiBkb3RBUEFDIC0gZG90QUJBQyAqIGRvdEFQQUIpIC8gZGVub207XG4gICAgICAgICAgICBjb25zdCB1ID0gMSAtIHYgLSB3O1xuXG4gICAgICAgICAgICAvLyBVc2UgdGhlIGJhcnljZW50cmljIHdlaWdodGluZyBhbG9uZyB3aXRoIHRoZSBvcmlnaW5hbCB0cmlhbmdsZSB6IGNvb3JkaW5hdGVzIHRvIGdldCB0aGUgcG9pbnQgb2YgaW50ZXJzZWN0aW9uLlxuICAgICAgICAgICAgY29uc3QgZGlzdGFuY2UgPSBhLnogKiB1ICsgYi56ICogdiArIGMueiAqIHc7XG5cbiAgICAgICAgICAgIGlmIChpc0Zpbml0ZShkaXN0YW5jZSkpIHJldHVybiBkaXN0YW5jZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBJbmZpbml0eTtcblxuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRoZSBjb3VudHMgYXMgY2xvc2VzdCBpcyBsZXNzIGNsZWFyIHdoZW4gdGhlIHF1ZXJ5IGlzIGEgYm94LiBUaGlzXG4gICAgICAgIC8vIHJldHVybnMgdGhlIGRpc3RhbmNlIHRvIHRoZSBuZWFyZXN0IHBvaW50IG9uIHRoZSBmYWNlLCB3aGV0aGVyIGl0IGlzXG4gICAgICAgIC8vIHdpdGhpbiB0aGUgcXVlcnkgb3Igbm90LiBJdCBjb3VsZCBiZSBtb3JlIGNvcnJlY3QgdG8gcmV0dXJuIHRoZVxuICAgICAgICAvLyBkaXN0YW5jZSB0byB0aGUgY2xvc2VzdCBwb2ludCB3aXRoaW4gdGhlIHF1ZXJ5IGJveCBidXQgdGhpcyB3b3VsZCBiZVxuICAgICAgICAvLyBtb3JlIGNvbXBsaWNhdGVkIGFuZCBleHBlbnNpdmUgdG8gY2FsY3VsYXRlIHdpdGggbGl0dGxlIGJlbmVmaXQuXG4gICAgICAgIGxldCBjbG9zZXN0RGlzdGFuY2UgPSBJbmZpbml0eTtcbiAgICAgICAgZm9yIChjb25zdCBwIG9mIHByb2plY3RlZEZhY2UpIHtcbiAgICAgICAgICAgIGNsb3Nlc3REaXN0YW5jZSA9IE1hdGgubWluKGNsb3Nlc3REaXN0YW5jZSwgcC56KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2xvc2VzdERpc3RhbmNlO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gY2hlY2tJbnRlcnNlY3Rpb24ocHJvamVjdGVkQmFzZTogQXJyYXk8QXJyYXk8UG9pbnQzRD4+LCBwcm9qZWN0ZWRUb3A6IEFycmF5PEFycmF5PFBvaW50M0Q+PiwgcHJvamVjdGVkUXVlcnlHZW9tZXRyeTogQXJyYXk8UG9pbnQ+KSB7XG4gICAgbGV0IGNsb3Nlc3REaXN0YW5jZSA9IEluZmluaXR5O1xuXG4gICAgaWYgKHBvbHlnb25JbnRlcnNlY3RzTXVsdGlQb2x5Z29uKHByb2plY3RlZFF1ZXJ5R2VvbWV0cnksIHByb2plY3RlZFRvcCkpIHtcbiAgICAgICAgY2xvc2VzdERpc3RhbmNlID0gZ2V0SW50ZXJzZWN0aW9uRGlzdGFuY2UocHJvamVjdGVkUXVlcnlHZW9tZXRyeSwgcHJvamVjdGVkVG9wWzBdKTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCByID0gMDsgciA8IHByb2plY3RlZFRvcC5sZW5ndGg7IHIrKykge1xuICAgICAgICBjb25zdCByaW5nVG9wID0gcHJvamVjdGVkVG9wW3JdO1xuICAgICAgICBjb25zdCByaW5nQmFzZSA9IHByb2plY3RlZEJhc2Vbcl07XG4gICAgICAgIGZvciAobGV0IHAgPSAwOyBwIDwgcmluZ1RvcC5sZW5ndGggLSAxOyBwKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHRvcEEgPSByaW5nVG9wW3BdO1xuICAgICAgICAgICAgY29uc3QgdG9wQiA9IHJpbmdUb3BbcCArIDFdO1xuICAgICAgICAgICAgY29uc3QgYmFzZUEgPSByaW5nQmFzZVtwXTtcbiAgICAgICAgICAgIGNvbnN0IGJhc2VCID0gcmluZ0Jhc2VbcCArIDFdO1xuICAgICAgICAgICAgY29uc3QgZmFjZSA9IFt0b3BBLCB0b3BCLCBiYXNlQiwgYmFzZUEsIHRvcEFdO1xuICAgICAgICAgICAgaWYgKHBvbHlnb25JbnRlcnNlY3RzUG9seWdvbihwcm9qZWN0ZWRRdWVyeUdlb21ldHJ5LCBmYWNlKSkge1xuICAgICAgICAgICAgICAgIGNsb3Nlc3REaXN0YW5jZSA9IE1hdGgubWluKGNsb3Nlc3REaXN0YW5jZSwgZ2V0SW50ZXJzZWN0aW9uRGlzdGFuY2UocHJvamVjdGVkUXVlcnlHZW9tZXRyeSwgZmFjZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGNsb3Nlc3REaXN0YW5jZSA9PT0gSW5maW5pdHkgPyBmYWxzZSA6IGNsb3Nlc3REaXN0YW5jZTtcbn1cblxuZnVuY3Rpb24gcHJvamVjdEV4dHJ1c2lvbih0cjogVHJhbnNmb3JtLCBnZW9tZXRyeTogQXJyYXk8QXJyYXk8UG9pbnQ+PiwgekJhc2U6IG51bWJlciwgelRvcDogbnVtYmVyLCB0cmFuc2xhdGlvbjogUG9pbnQsIG06IEZsb2F0MzJBcnJheSwgZGVtU2FtcGxlcjogP0RFTVNhbXBsZXIsIGNlbnRyb2lkOiBWZWMyLCBleGFnZ2VyYXRpb246IG51bWJlciwgbGF0OiBudW1iZXIsIHRpbGVJRDogQ2Fub25pY2FsVGlsZUlEKSB7XG4gICAgaWYgKHRyLnByb2plY3Rpb24ubmFtZSA9PT0gJ2dsb2JlJykge1xuICAgICAgICByZXR1cm4gcHJvamVjdEV4dHJ1c2lvbkdsb2JlKHRyLCBnZW9tZXRyeSwgekJhc2UsIHpUb3AsIHRyYW5zbGF0aW9uLCBtLCBkZW1TYW1wbGVyLCBjZW50cm9pZCwgZXhhZ2dlcmF0aW9uLCBsYXQsIHRpbGVJRCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGRlbVNhbXBsZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9qZWN0RXh0cnVzaW9uM0QoZ2VvbWV0cnksIHpCYXNlLCB6VG9wLCB0cmFuc2xhdGlvbiwgbSwgZGVtU2FtcGxlciwgY2VudHJvaWQsIGV4YWdnZXJhdGlvbiwgbGF0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9qZWN0RXh0cnVzaW9uMkQoZ2VvbWV0cnksIHpCYXNlLCB6VG9wLCB0cmFuc2xhdGlvbiwgbSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIHByb2plY3RFeHRydXNpb25HbG9iZSh0cjogVHJhbnNmb3JtLCBnZW9tZXRyeTogQXJyYXk8QXJyYXk8UG9pbnQ+PiwgekJhc2U6IG51bWJlciwgelRvcDogbnVtYmVyLCB0cmFuc2xhdGlvbjogUG9pbnQsIG06IEZsb2F0MzJBcnJheSwgZGVtU2FtcGxlcjogP0RFTVNhbXBsZXIsIGNlbnRyb2lkOiBWZWMyLCBleGFnZ2VyYXRpb246IG51bWJlciwgbGF0OiBudW1iZXIsIHRpbGVJRDogQ2Fub25pY2FsVGlsZUlEKSB7XG4gICAgY29uc3QgcHJvamVjdGVkQmFzZSA9IFtdO1xuICAgIGNvbnN0IHByb2plY3RlZFRvcCA9IFtdO1xuICAgIGNvbnN0IGVsZXZhdGlvblNjYWxlID0gdHIucHJvamVjdGlvbi51cFZlY3RvclNjYWxlKHRpbGVJRCwgdHIuY2VudGVyLmxhdCwgdHIud29ybGRTaXplKS5tZXRlcnNUb1RpbGU7XG4gICAgY29uc3QgYmFzZVBvaW50ID0gWzAsIDAsIDAsIDFdO1xuICAgIGNvbnN0IHRvcFBvaW50ID0gWzAsIDAsIDAsIDFdO1xuXG4gICAgY29uc3Qgc2V0UG9pbnQgPSAocG9pbnQ6IEFycmF5PG51bWJlcj4sIHg6IG51bWJlciwgeTogbnVtYmVyLCB6OiBudW1iZXIpID0+IHtcbiAgICAgICAgcG9pbnRbMF0gPSB4O1xuICAgICAgICBwb2ludFsxXSA9IHk7XG4gICAgICAgIHBvaW50WzJdID0gejtcbiAgICAgICAgcG9pbnRbM10gPSAxO1xuICAgIH07XG5cbiAgICAvLyBGaXhlZCBcImxpZnRcIiB2YWx1ZSBpcyBhZGRlZCB0byBoZWlnaHQgc28gdGhhdCAwLWhlaWdodCBmaWxsIGV4dHJ1c2lvbnMgd29udCBjbGlwIHdpdGggZ2xvYmUncyBzdXJmYWNlXG4gICAgY29uc3QgbGlmdCA9IGZpbGxFeHRydXNpb25IZWlnaHRMaWZ0KCk7XG5cbiAgICBpZiAoekJhc2UgPiAwKSB7XG4gICAgICAgIHpCYXNlICs9IGxpZnQ7XG4gICAgfVxuICAgIHpUb3AgKz0gbGlmdDtcblxuICAgIGZvciAoY29uc3QgciBvZiBnZW9tZXRyeSkge1xuICAgICAgICBjb25zdCByaW5nQmFzZSA9IFtdO1xuICAgICAgICBjb25zdCByaW5nVG9wID0gW107XG4gICAgICAgIGZvciAoY29uc3QgcCBvZiByKSB7XG4gICAgICAgICAgICBjb25zdCB4ID0gcC54ICsgdHJhbnNsYXRpb24ueDtcbiAgICAgICAgICAgIGNvbnN0IHkgPSBwLnkgKyB0cmFuc2xhdGlvbi55O1xuXG4gICAgICAgICAgICAvLyBSZXByb2plY3QgdGlsZSBjb29yZGluYXRlIGludG8gZWNlZiBhbmQgYXBwbHkgZWxldmF0aW9uIHRvIGNvcnJlY3QgZGlyZWN0aW9uXG4gICAgICAgICAgICBjb25zdCByZXByb2ogPSB0ci5wcm9qZWN0aW9uLnByb2plY3RUaWxlUG9pbnQoeCwgeSwgdGlsZUlEKTtcbiAgICAgICAgICAgIGNvbnN0IGRpciA9IHRyLnByb2plY3Rpb24udXBWZWN0b3IodGlsZUlELCBwLngsIHAueSk7XG5cbiAgICAgICAgICAgIGxldCB6QmFzZVBvaW50ID0gekJhc2U7XG4gICAgICAgICAgICBsZXQgelRvcFBvaW50ID0gelRvcDtcblxuICAgICAgICAgICAgaWYgKGRlbVNhbXBsZXIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvZmZzZXQgPSBnZXRUZXJyYWluSGVpZ2h0T2Zmc2V0KHgsIHksIHpCYXNlLCB6VG9wLCBkZW1TYW1wbGVyLCBjZW50cm9pZCwgZXhhZ2dlcmF0aW9uLCBsYXQpO1xuXG4gICAgICAgICAgICAgICAgekJhc2VQb2ludCArPSBvZmZzZXQuYmFzZTtcbiAgICAgICAgICAgICAgICB6VG9wUG9pbnQgKz0gb2Zmc2V0LnRvcDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHpCYXNlICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgc2V0UG9pbnQoXG4gICAgICAgICAgICAgICAgICAgIGJhc2VQb2ludCxcbiAgICAgICAgICAgICAgICAgICAgcmVwcm9qLnggKyBkaXJbMF0gKiBlbGV2YXRpb25TY2FsZSAqIHpCYXNlUG9pbnQsXG4gICAgICAgICAgICAgICAgICAgIHJlcHJvai55ICsgZGlyWzFdICogZWxldmF0aW9uU2NhbGUgKiB6QmFzZVBvaW50LFxuICAgICAgICAgICAgICAgICAgICByZXByb2oueiArIGRpclsyXSAqIGVsZXZhdGlvblNjYWxlICogekJhc2VQb2ludCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNldFBvaW50KGJhc2VQb2ludCwgcmVwcm9qLngsIHJlcHJvai55LCByZXByb2oueik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHNldFBvaW50KFxuICAgICAgICAgICAgICAgIHRvcFBvaW50LFxuICAgICAgICAgICAgICAgIHJlcHJvai54ICsgZGlyWzBdICogZWxldmF0aW9uU2NhbGUgKiB6VG9wUG9pbnQsXG4gICAgICAgICAgICAgICAgcmVwcm9qLnkgKyBkaXJbMV0gKiBlbGV2YXRpb25TY2FsZSAqIHpUb3BQb2ludCxcbiAgICAgICAgICAgICAgICByZXByb2oueiArIGRpclsyXSAqIGVsZXZhdGlvblNjYWxlICogelRvcFBvaW50KTtcblxuICAgICAgICAgICAgdmVjMy50cmFuc2Zvcm1NYXQ0KGJhc2VQb2ludCwgYmFzZVBvaW50LCBtKTtcbiAgICAgICAgICAgIHZlYzMudHJhbnNmb3JtTWF0NCh0b3BQb2ludCwgdG9wUG9pbnQsIG0pO1xuXG4gICAgICAgICAgICByaW5nQmFzZS5wdXNoKG5ldyBQb2ludDNEKGJhc2VQb2ludFswXSwgYmFzZVBvaW50WzFdLCBiYXNlUG9pbnRbMl0pKTtcbiAgICAgICAgICAgIHJpbmdUb3AucHVzaChuZXcgUG9pbnQzRCh0b3BQb2ludFswXSwgdG9wUG9pbnRbMV0sIHRvcFBvaW50WzJdKSk7XG4gICAgICAgIH1cbiAgICAgICAgcHJvamVjdGVkQmFzZS5wdXNoKHJpbmdCYXNlKTtcbiAgICAgICAgcHJvamVjdGVkVG9wLnB1c2gocmluZ1RvcCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIFtwcm9qZWN0ZWRCYXNlLCBwcm9qZWN0ZWRUb3BdO1xufVxuXG4vKlxuICogUHJvamVjdCB0aGUgZ2VvbWV0cnkgdXNpbmcgbWF0cml4IGBtYC4gVGhpcyBpcyBlc3NlbnRpYWxseSBkb2luZ1xuICogYHZlYzQudHJhbnNmb3JtTWF0NChbXSwgW3AueCwgcC55LCB6LCAxXSwgbSlgIGJ1dCB0aGUgbXVsdGlwbGljYXRpb25cbiAqIGlzIGlubGluZWQgc28gdGhhdCBwYXJ0cyBvZiB0aGUgcHJvamVjdGlvbiB0aGF0IGFyZSB0aGUgc2FtZSBhY3Jvc3NcbiAqIGRpZmZlcmVudCBwb2ludHMgY2FuIG9ubHkgYmUgZG9uZSBvbmNlLiBUaGlzIHByb2R1Y2VkIGEgbWVhc3VyYWJsZVxuICogcGVyZm9ybWFuY2UgaW1wcm92ZW1lbnQuXG4gKi9cbmZ1bmN0aW9uIHByb2plY3RFeHRydXNpb24yRChnZW9tZXRyeTogQXJyYXk8QXJyYXk8UG9pbnQ+PiwgekJhc2U6IG51bWJlciwgelRvcDogbnVtYmVyLCB0cmFuc2xhdGlvbjogUG9pbnQsIG06IEZsb2F0MzJBcnJheSkge1xuICAgIGNvbnN0IHByb2plY3RlZEJhc2UgPSBbXTtcbiAgICBjb25zdCBwcm9qZWN0ZWRUb3AgPSBbXTtcblxuICAgIGNvbnN0IGJhc2VYWiA9IG1bOF0gKiB6QmFzZTtcbiAgICBjb25zdCBiYXNlWVogPSBtWzldICogekJhc2U7XG4gICAgY29uc3QgYmFzZVpaID0gbVsxMF0gKiB6QmFzZTtcbiAgICBjb25zdCBiYXNlV1ogPSBtWzExXSAqIHpCYXNlO1xuICAgIGNvbnN0IHRvcFhaID0gbVs4XSAqIHpUb3A7XG4gICAgY29uc3QgdG9wWVogPSBtWzldICogelRvcDtcbiAgICBjb25zdCB0b3BaWiA9IG1bMTBdICogelRvcDtcbiAgICBjb25zdCB0b3BXWiA9IG1bMTFdICogelRvcDtcblxuICAgIGZvciAoY29uc3QgciBvZiBnZW9tZXRyeSkge1xuICAgICAgICBjb25zdCByaW5nQmFzZSA9IFtdO1xuICAgICAgICBjb25zdCByaW5nVG9wID0gW107XG4gICAgICAgIGZvciAoY29uc3QgcCBvZiByKSB7XG4gICAgICAgICAgICBjb25zdCB4ID0gcC54ICsgdHJhbnNsYXRpb24ueDtcbiAgICAgICAgICAgIGNvbnN0IHkgPSBwLnkgKyB0cmFuc2xhdGlvbi55O1xuXG4gICAgICAgICAgICBjb25zdCBzWCA9IG1bMF0gKiB4ICsgbVs0XSAqIHkgKyBtWzEyXTtcbiAgICAgICAgICAgIGNvbnN0IHNZID0gbVsxXSAqIHggKyBtWzVdICogeSArIG1bMTNdO1xuICAgICAgICAgICAgY29uc3Qgc1ogPSBtWzJdICogeCArIG1bNl0gKiB5ICsgbVsxNF07XG4gICAgICAgICAgICBjb25zdCBzVyA9IG1bM10gKiB4ICsgbVs3XSAqIHkgKyBtWzE1XTtcblxuICAgICAgICAgICAgY29uc3QgYmFzZVggPSBzWCArIGJhc2VYWjtcbiAgICAgICAgICAgIGNvbnN0IGJhc2VZID0gc1kgKyBiYXNlWVo7XG4gICAgICAgICAgICBjb25zdCBiYXNlWiA9IHNaICsgYmFzZVpaO1xuICAgICAgICAgICAgY29uc3QgYmFzZVcgPSBNYXRoLm1heChzVyArIGJhc2VXWiwgMC4wMDAwMSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHRvcFggPSBzWCArIHRvcFhaO1xuICAgICAgICAgICAgY29uc3QgdG9wWSA9IHNZICsgdG9wWVo7XG4gICAgICAgICAgICBjb25zdCB0b3BaID0gc1ogKyB0b3BaWjtcbiAgICAgICAgICAgIGNvbnN0IHRvcFcgPSBNYXRoLm1heChzVyArIHRvcFdaLCAwLjAwMDAxKTtcblxuICAgICAgICAgICAgcmluZ0Jhc2UucHVzaChuZXcgUG9pbnQzRChiYXNlWCAvIGJhc2VXLCBiYXNlWSAvIGJhc2VXLCBiYXNlWiAvIGJhc2VXKSk7XG4gICAgICAgICAgICByaW5nVG9wLnB1c2gobmV3IFBvaW50M0QodG9wWCAvIHRvcFcsIHRvcFkgLyB0b3BXLCB0b3BaIC8gdG9wVykpO1xuICAgICAgICB9XG4gICAgICAgIHByb2plY3RlZEJhc2UucHVzaChyaW5nQmFzZSk7XG4gICAgICAgIHByb2plY3RlZFRvcC5wdXNoKHJpbmdUb3ApO1xuICAgIH1cbiAgICByZXR1cm4gW3Byb2plY3RlZEJhc2UsIHByb2plY3RlZFRvcF07XG59XG5cbi8qXG4gKiBQcm9qZWN0cyBhIGZpbGwgZXh0cnVzaW9uIHZlcnRpY2VzIHRvIHNjcmVlbiB3aGlsZSBhY2NvdW50aW5nIGZvciB0ZXJyYWluLlxuICogVGhpcyBhbmQgaXRzIGRlcGVuZGVudCBmdW5jdGlvbnMgYXJlIHBvcnRlZCBkaXJlY3RseSBmcm9tIGBmaWxsX2V4dHJ1c2lvbi52ZXJ0ZXguZ2xzbGBcbiAqIHdpdGggYSBmZXcgY28tb3JkaW5hdGUgc3BhY2UgZGlmZmVyZW5jZXMuXG4gKlxuICogLSBNYXRyaXggYG1gIHByb2plY3RzIHRvIHNjcmVlbi1waXhlbCBzcGFjZSBpbnN0ZWFkIG9mIHRvIGdsLWNvb3JkaW5hdGVzIChOREMpXG4gKiAtIFRleHR1cmUgcXVlcnlpbmcgaXMgcGVyZm9ybWVkIGluIHRleHR1cmUgcGl4ZWwgY29vcmRpbmF0ZXMgaW5zdGVhZCBvZiAgbm9ybWFsaXplZCB1diBjb29yZGluYXRlcy5cbiAqIC0gSGVpZ2h0IG9mZnNldCBjYWxjdWxhdGlvbiBmb3IgZmlsbC1leHRydXNpb24tYmFzZSBpcyBvZmZzZXQgd2l0aCAtMSBpbnN0ZWFkIG9mIC01IHRvIHByZXZlbnQgdW5kZXJncm91bmQgcGlja2luZy5cbiAqL1xuZnVuY3Rpb24gcHJvamVjdEV4dHJ1c2lvbjNEKGdlb21ldHJ5OiBBcnJheTxBcnJheTxQb2ludD4+LCB6QmFzZTogbnVtYmVyLCB6VG9wOiBudW1iZXIsIHRyYW5zbGF0aW9uOiBQb2ludCwgbTogRmxvYXQzMkFycmF5LCBkZW1TYW1wbGVyOiBERU1TYW1wbGVyLCBjZW50cm9pZDogVmVjMiwgZXhhZ2dlcmF0aW9uOiBudW1iZXIsIGxhdDogbnVtYmVyKSB7XG4gICAgY29uc3QgcHJvamVjdGVkQmFzZSA9IFtdO1xuICAgIGNvbnN0IHByb2plY3RlZFRvcCA9IFtdO1xuICAgIGNvbnN0IHYgPSBbMCwgMCwgMCwgMV07XG5cbiAgICBmb3IgKGNvbnN0IHIgb2YgZ2VvbWV0cnkpIHtcbiAgICAgICAgY29uc3QgcmluZ0Jhc2UgPSBbXTtcbiAgICAgICAgY29uc3QgcmluZ1RvcCA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IHAgb2Ygcikge1xuICAgICAgICAgICAgY29uc3QgeCA9IHAueCArIHRyYW5zbGF0aW9uLng7XG4gICAgICAgICAgICBjb25zdCB5ID0gcC55ICsgdHJhbnNsYXRpb24ueTtcbiAgICAgICAgICAgIGNvbnN0IGhlaWdodE9mZnNldCA9IGdldFRlcnJhaW5IZWlnaHRPZmZzZXQoeCwgeSwgekJhc2UsIHpUb3AsIGRlbVNhbXBsZXIsIGNlbnRyb2lkLCBleGFnZ2VyYXRpb24sIGxhdCk7XG5cbiAgICAgICAgICAgIHZbMF0gPSB4O1xuICAgICAgICAgICAgdlsxXSA9IHk7XG4gICAgICAgICAgICB2WzJdID0gaGVpZ2h0T2Zmc2V0LmJhc2U7XG4gICAgICAgICAgICB2WzNdID0gMTtcbiAgICAgICAgICAgIHZlYzQudHJhbnNmb3JtTWF0NCh2LCB2LCBtKTtcbiAgICAgICAgICAgIHZbM10gPSBNYXRoLm1heCh2WzNdLCAwLjAwMDAxKTtcbiAgICAgICAgICAgIGNvbnN0IGJhc2UgPSBuZXcgUG9pbnQzRCh2WzBdIC8gdlszXSwgdlsxXSAvIHZbM10sIHZbMl0gLyB2WzNdKTtcblxuICAgICAgICAgICAgdlswXSA9IHg7XG4gICAgICAgICAgICB2WzFdID0geTtcbiAgICAgICAgICAgIHZbMl0gPSBoZWlnaHRPZmZzZXQudG9wO1xuICAgICAgICAgICAgdlszXSA9IDE7XG4gICAgICAgICAgICB2ZWM0LnRyYW5zZm9ybU1hdDQodiwgdiwgbSk7XG4gICAgICAgICAgICB2WzNdID0gTWF0aC5tYXgodlszXSwgMC4wMDAwMSk7XG4gICAgICAgICAgICBjb25zdCB0b3AgPSBuZXcgUG9pbnQzRCh2WzBdIC8gdlszXSwgdlsxXSAvIHZbM10sIHZbMl0gLyB2WzNdKTtcblxuICAgICAgICAgICAgcmluZ0Jhc2UucHVzaChiYXNlKTtcbiAgICAgICAgICAgIHJpbmdUb3AucHVzaCh0b3ApO1xuICAgICAgICB9XG4gICAgICAgIHByb2plY3RlZEJhc2UucHVzaChyaW5nQmFzZSk7XG4gICAgICAgIHByb2plY3RlZFRvcC5wdXNoKHJpbmdUb3ApO1xuICAgIH1cbiAgICByZXR1cm4gW3Byb2plY3RlZEJhc2UsIHByb2plY3RlZFRvcF07XG59XG5cbmZ1bmN0aW9uIGdldFRlcnJhaW5IZWlnaHRPZmZzZXQoeDogbnVtYmVyLCB5OiBudW1iZXIsIHpCYXNlOiBudW1iZXIsIHpUb3A6IG51bWJlciwgZGVtU2FtcGxlcjogREVNU2FtcGxlciwgY2VudHJvaWQ6IFZlYzIsIGV4YWdnZXJhdGlvbjogbnVtYmVyLCBsYXQ6IG51bWJlcik6IHsgYmFzZTogbnVtYmVyLCB0b3A6IG51bWJlcn0ge1xuICAgIGNvbnN0IGVsZSA9IGV4YWdnZXJhdGlvbiAqIGRlbVNhbXBsZXIuZ2V0RWxldmF0aW9uQXQoeCwgeSwgdHJ1ZSwgdHJ1ZSk7XG4gICAgY29uc3QgZmxhdFJvb2YgPSBjZW50cm9pZFswXSAhPT0gMDtcbiAgICBjb25zdCBjZW50cm9pZEVsZXZhdGlvbiA9IGZsYXRSb29mID8gY2VudHJvaWRbMV0gPT09IDAgPyBleGFnZ2VyYXRpb24gKiBlbGV2YXRpb25Gcm9tVWludDE2KGNlbnRyb2lkWzBdKSA6IGV4YWdnZXJhdGlvbiAqIGZsYXRFbGV2YXRpb24oZGVtU2FtcGxlciwgY2VudHJvaWQsIGxhdCkgOiBlbGU7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgYmFzZTogZWxlICsgKHpCYXNlID09PSAwKSA/IC0xIDogekJhc2UsIC8vIFVzZSAtMSBpbnN0ZWFkIG9mIC01IGluIHNoYWRlciB0byBwcmV2ZW50IHBpY2tpbmcgdW5kZXJncm91bmRcbiAgICAgICAgdG9wOiBmbGF0Um9vZiA/IE1hdGgubWF4KGNlbnRyb2lkRWxldmF0aW9uICsgelRvcCwgZWxlICsgekJhc2UgKyAyKSA6IGVsZSArIHpUb3BcbiAgICB9O1xufVxuXG4vLyBFbGV2YXRpb24gaXMgZW5jb2RlZCBpbnRvIHVuaXQxNiBpbiBmaWxsX2V4dHJ1c2lvbl9idWNrZXQuanMgRmlsbEV4dHJ1c2lvbkJ1Y2tldCNlbmNvZGVDZW50cm9pZFxuZnVuY3Rpb24gZWxldmF0aW9uRnJvbVVpbnQxNihuOiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiBuIC8gRUxFVkFUSU9OX1NDQUxFIC0gRUxFVkFUSU9OX09GRlNFVDtcbn1cblxuLy8gRXF1aXZhbGVudCBHUFUgc2lkZSBmdW5jdGlvbiBpcyBpbiBfcHJlbHVkZV90ZXJyYWluLnZlcnRleC5nbHNsXG5mdW5jdGlvbiBmbGF0RWxldmF0aW9uKGRlbVNhbXBsZXI6IERFTVNhbXBsZXIsIGNlbnRyb2lkOiBWZWMyLCBsYXQ6IG51bWJlcik6IG51bWJlciB7XG4gICAgLy8gU3BhbiBhbmQgcG9zIGFyZSBwYWNrZWQgdHdvIDE2IGJpdCB1aW50MTYgdmFsdWVzIGluIGZpbGxfZXh0cnVzaW9uX2J1Y2tldC5qcyBGaWxsRXh0cnVzaW9uQnVja2V0I2VuY29kZUNlbnRyb2lkXG4gICAgLy8gcG9zIGlzIGVuY29kZWQgYnkgPDwgYnkgMyBiaXRzIHRodXMgZGl2aWRpbmcgYnkgOCBwZXJmb3JtcyBlcXVpdmFsZW50IG9mIHJpZ2h0IHNoaWZ0aW5nIGl0IGJhY2suXG4gICAgY29uc3QgcG9zWCA9IE1hdGguZmxvb3IoY2VudHJvaWRbMF0gLyA4KTtcbiAgICBjb25zdCBwb3NZID0gTWF0aC5mbG9vcihjZW50cm9pZFsxXSAvIDgpO1xuXG4gICAgLy8gU3BhbiBpcyBzdG9yZWQgaW4gdGhlIGxvd2VyIHRocmVlIGJpdHMgaW4gbXVsdGlwbGVzIG9mIDEwXG4gICAgY29uc3Qgc3BhblggPSAxMCAqIChjZW50cm9pZFswXSAtIHBvc1ggKiA4KTtcbiAgICBjb25zdCBzcGFuWSA9IDEwICogKGNlbnRyb2lkWzFdIC0gcG9zWSAqIDgpO1xuXG4gICAgLy8gR2V0IGhlaWdodCBhdCBjZW50cm9pZFxuICAgIGNvbnN0IHogPSBkZW1TYW1wbGVyLmdldEVsZXZhdGlvbkF0KHBvc1gsIHBvc1ksIHRydWUsIHRydWUpO1xuICAgIGNvbnN0IG1ldGVyVG9ERU0gPSBkZW1TYW1wbGVyLmdldE1ldGVyVG9ERU0obGF0KTtcblxuICAgIGNvbnN0IHdYID0gTWF0aC5mbG9vcigwLjUgKiAoc3BhblggKiBtZXRlclRvREVNIC0gMSkpO1xuICAgIGNvbnN0IHdZID0gTWF0aC5mbG9vcigwLjUgKiAoc3BhblkgKiBtZXRlclRvREVNIC0gMSkpO1xuXG4gICAgY29uc3QgcG9zUHggPSBkZW1TYW1wbGVyLnRpbGVDb29yZFRvUGl4ZWwocG9zWCwgcG9zWSk7XG5cbiAgICBjb25zdCBvZmZzZXRYID0gMiAqIHdYICsgMTtcbiAgICBjb25zdCBvZmZzZXRZID0gMiAqIHdZICsgMTtcbiAgICBjb25zdCBjb3JuZXJzID0gZm91clNhbXBsZShkZW1TYW1wbGVyLCBwb3NQeC54IC0gd1gsIHBvc1B4LnkgLSB3WSwgb2Zmc2V0WCwgb2Zmc2V0WSk7XG5cbiAgICBjb25zdCBkaWZmWCA9IE1hdGguYWJzKGNvcm5lcnNbMF0gLSBjb3JuZXJzWzFdKTtcbiAgICBjb25zdCBkaWZmWSA9IE1hdGguYWJzKGNvcm5lcnNbMl0gLSBjb3JuZXJzWzNdKTtcbiAgICBjb25zdCBkaWZmWiA9IE1hdGguYWJzKGNvcm5lcnNbMF0gLSBjb3JuZXJzWzJdKTtcbiAgICBjb25zdCBkaWZmVyA9IE1hdGguYWJzKGNvcm5lcnNbMV0gLSBjb3JuZXJzWzNdKTtcblxuICAgIGNvbnN0IGRpZmZTdW1YID0gZGlmZlggKyBkaWZmWTtcbiAgICBjb25zdCBkaWZmU3VtWSA9IGRpZmZaICsgZGlmZlc7XG5cbiAgICBjb25zdCBzbG9wZVggPSBNYXRoLm1pbigwLjI1LCBtZXRlclRvREVNICogMC41ICogZGlmZlN1bVggLyBvZmZzZXRYKTtcbiAgICBjb25zdCBzbG9wZVkgPSBNYXRoLm1pbigwLjI1LCBtZXRlclRvREVNICogMC41ICogZGlmZlN1bVkgLyBvZmZzZXRZKTtcblxuICAgIHJldHVybiB6ICsgTWF0aC5tYXgoc2xvcGVYICogc3BhblgsIHNsb3BlWSAqIHNwYW5ZKTtcbn1cblxuZnVuY3Rpb24gZm91clNhbXBsZShkZW1TYW1wbGVyOiBERU1TYW1wbGVyLCBwb3NYOiBudW1iZXIsIHBvc1k6IG51bWJlciwgb2Zmc2V0WDogbnVtYmVyLCBvZmZzZXRZOiBudW1iZXIpOiBWZWM0IHtcbiAgICByZXR1cm4gW1xuICAgICAgICBkZW1TYW1wbGVyLmdldEVsZXZhdGlvbkF0UGl4ZWwocG9zWCwgcG9zWSwgdHJ1ZSksXG4gICAgICAgIGRlbVNhbXBsZXIuZ2V0RWxldmF0aW9uQXRQaXhlbChwb3NYICsgb2Zmc2V0WSwgcG9zWSwgdHJ1ZSksXG4gICAgICAgIGRlbVNhbXBsZXIuZ2V0RWxldmF0aW9uQXRQaXhlbChwb3NYLCBwb3NZICsgb2Zmc2V0WSwgdHJ1ZSksXG4gICAgICAgIGRlbVNhbXBsZXIuZ2V0RWxldmF0aW9uQXRQaXhlbChwb3NYICsgb2Zmc2V0WCwgcG9zWSArIG9mZnNldFksIHRydWUpXG4gICAgXTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgRmlsbEV4dHJ1c2lvblN0eWxlTGF5ZXI7XG4iLCIvLyBAZmxvd1xuaW1wb3J0IHtjcmVhdGVMYXlvdXR9IGZyb20gJy4uLy4uL3V0aWwvc3RydWN0X2FycmF5LmpzJztcblxuaW1wb3J0IHR5cGUge1N0cnVjdEFycmF5TGF5b3V0fSBmcm9tICcuLi8uLi91dGlsL3N0cnVjdF9hcnJheS5qcyc7XG5cbmNvbnN0IGxpbmVMYXlvdXRBdHRyaWJ1dGVzOiBTdHJ1Y3RBcnJheUxheW91dCA9IGNyZWF0ZUxheW91dChbXG4gICAge25hbWU6ICdhX3Bvc19ub3JtYWwnLCBjb21wb25lbnRzOiAyLCB0eXBlOiAnSW50MTYnfSxcbiAgICB7bmFtZTogJ2FfZGF0YScsIGNvbXBvbmVudHM6IDQsIHR5cGU6ICdVaW50OCd9LFxuICAgIHtuYW1lOiAnYV9saW5lc29mYXInLCBjb21wb25lbnRzOiAxLCB0eXBlOiAnRmxvYXQzMid9XG5dLCA0KTtcblxuZXhwb3J0IGRlZmF1bHQgbGluZUxheW91dEF0dHJpYnV0ZXM7XG5leHBvcnQgY29uc3Qge21lbWJlcnMsIHNpemUsIGFsaWdubWVudH0gPSBsaW5lTGF5b3V0QXR0cmlidXRlcztcbiIsIi8vIEBmbG93XG5pbXBvcnQge2NyZWF0ZUxheW91dH0gZnJvbSAnLi4vLi4vdXRpbC9zdHJ1Y3RfYXJyYXkuanMnO1xuXG5pbXBvcnQgdHlwZSB7U3RydWN0QXJyYXlMYXlvdXR9IGZyb20gJy4uLy4uL3V0aWwvc3RydWN0X2FycmF5LmpzJztcblxuY29uc3QgbGluZUxheW91dEF0dHJpYnV0ZXNFeHQ6IFN0cnVjdEFycmF5TGF5b3V0ID0gY3JlYXRlTGF5b3V0KFtcbiAgICB7bmFtZTogJ2FfcGFja2VkJywgY29tcG9uZW50czogNCwgdHlwZTogJ0Zsb2F0MzInfVxuXSk7XG5cbmV4cG9ydCBkZWZhdWx0IGxpbmVMYXlvdXRBdHRyaWJ1dGVzRXh0O1xuZXhwb3J0IGNvbnN0IHttZW1iZXJzLCBzaXplLCBhbGlnbm1lbnR9ID0gbGluZUxheW91dEF0dHJpYnV0ZXNFeHQ7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge0xpbmVMYXlvdXRBcnJheSwgTGluZUV4dExheW91dEFycmF5fSBmcm9tICcuLi9hcnJheV90eXBlcy5qcyc7XG5cbmltcG9ydCB7bWVtYmVycyBhcyBsYXlvdXRBdHRyaWJ1dGVzfSBmcm9tICcuL2xpbmVfYXR0cmlidXRlcy5qcyc7XG5pbXBvcnQge21lbWJlcnMgYXMgbGF5b3V0QXR0cmlidXRlc0V4dH0gZnJvbSAnLi9saW5lX2F0dHJpYnV0ZXNfZXh0LmpzJztcbmltcG9ydCBTZWdtZW50VmVjdG9yIGZyb20gJy4uL3NlZ21lbnQuanMnO1xuaW1wb3J0IHtQcm9ncmFtQ29uZmlndXJhdGlvblNldH0gZnJvbSAnLi4vcHJvZ3JhbV9jb25maWd1cmF0aW9uLmpzJztcbmltcG9ydCB7VHJpYW5nbGVJbmRleEFycmF5fSBmcm9tICcuLi9pbmRleF9hcnJheV90eXBlLmpzJztcbmltcG9ydCBFWFRFTlQgZnJvbSAnLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7VmVjdG9yVGlsZUZlYXR1cmV9IGZyb20gJ0BtYXBib3gvdmVjdG9yLXRpbGUnO1xuY29uc3QgdmVjdG9yVGlsZUZlYXR1cmVUeXBlcyA9IFZlY3RvclRpbGVGZWF0dXJlLnR5cGVzO1xuaW1wb3J0IHtyZWdpc3Rlcn0gZnJvbSAnLi4vLi4vdXRpbC93ZWJfd29ya2VyX3RyYW5zZmVyLmpzJztcbmltcG9ydCB7aGFzUGF0dGVybiwgYWRkUGF0dGVybkRlcGVuZGVuY2llc30gZnJvbSAnLi9wYXR0ZXJuX2J1Y2tldF9mZWF0dXJlcy5qcyc7XG5pbXBvcnQgbG9hZEdlb21ldHJ5IGZyb20gJy4uL2xvYWRfZ2VvbWV0cnkuanMnO1xuaW1wb3J0IHRvRXZhbHVhdGlvbkZlYXR1cmUgZnJvbSAnLi4vZXZhbHVhdGlvbl9mZWF0dXJlLmpzJztcbmltcG9ydCBFdmFsdWF0aW9uUGFyYW1ldGVycyBmcm9tICcuLi8uLi9zdHlsZS9ldmFsdWF0aW9uX3BhcmFtZXRlcnMuanMnO1xuaW1wb3J0IHR5cGUge1Byb2plY3Rpb25TcGVjaWZpY2F0aW9ufSBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL3R5cGVzLmpzJztcbmltcG9ydCB0eXBlIHtDYW5vbmljYWxUaWxlSUR9IGZyb20gJy4uLy4uL3NvdXJjZS90aWxlX2lkLmpzJztcbmltcG9ydCB0eXBlIHtcbiAgICBCdWNrZXQsXG4gICAgQnVja2V0UGFyYW1ldGVycyxcbiAgICBCdWNrZXRGZWF0dXJlLFxuICAgIEluZGV4ZWRGZWF0dXJlLFxuICAgIFBvcHVsYXRlUGFyYW1ldGVyc1xufSBmcm9tICcuLi9idWNrZXQuanMnO1xuaW1wb3J0IHR5cGUgTGluZVN0eWxlTGF5ZXIgZnJvbSAnLi4vLi4vc3R5bGUvc3R5bGVfbGF5ZXIvbGluZV9zdHlsZV9sYXllci5qcyc7XG5pbXBvcnQgdHlwZSBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCB0eXBlIHtTZWdtZW50fSBmcm9tICcuLi9zZWdtZW50LmpzJztcbmltcG9ydCB0eXBlIHtSR0JBSW1hZ2UsIFNwcml0ZVBvc2l0aW9uc30gZnJvbSAnLi4vLi4vdXRpbC9pbWFnZS5qcyc7XG5pbXBvcnQgdHlwZSBDb250ZXh0IGZyb20gJy4uLy4uL2dsL2NvbnRleHQuanMnO1xuaW1wb3J0IHR5cGUgVGV4dHVyZSBmcm9tICcuLi8uLi9yZW5kZXIvdGV4dHVyZS5qcyc7XG5pbXBvcnQgdHlwZSBJbmRleEJ1ZmZlciBmcm9tICcuLi8uLi9nbC9pbmRleF9idWZmZXIuanMnO1xuaW1wb3J0IHR5cGUgVmVydGV4QnVmZmVyIGZyb20gJy4uLy4uL2dsL3ZlcnRleF9idWZmZXIuanMnO1xuaW1wb3J0IHR5cGUge0ZlYXR1cmVTdGF0ZXN9IGZyb20gJy4uLy4uL3NvdXJjZS9zb3VyY2Vfc3RhdGUuanMnO1xuaW1wb3J0IHR5cGUgTGluZUF0bGFzIGZyb20gJy4uLy4uL3JlbmRlci9saW5lX2F0bGFzLmpzJztcbmltcG9ydCB0eXBlIHtUaWxlVHJhbnNmb3JtfSBmcm9tICcuLi8uLi9nZW8vcHJvamVjdGlvbi90aWxlX3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQgdHlwZSB7SVZlY3RvclRpbGVMYXllcn0gZnJvbSAnQG1hcGJveC92ZWN0b3ItdGlsZSc7XG5cbi8vIE5PVEUgT04gRVhUUlVERSBTQ0FMRTpcbi8vIHNjYWxlIHRoZSBleHRydXNpb24gdmVjdG9yIHNvIHRoYXQgdGhlIG5vcm1hbCBsZW5ndGggaXMgdGhpcyB2YWx1ZS5cbi8vIGNvbnRhaW5zIHRoZSBcInRleHR1cmVcIiBub3JtYWxzICgtMS4uMSkuIHRoaXMgaXMgZGlzdGluY3QgZnJvbSB0aGUgZXh0cnVkZVxuLy8gbm9ybWFscyBmb3IgbGluZSBqb2lucywgYmVjYXVzZSB0aGUgeC12YWx1ZSByZW1haW5zIDAgZm9yIHRoZSB0ZXh0dXJlXG4vLyBub3JtYWwgYXJyYXksIHdoaWxlIHRoZSBleHRydWRlIG5vcm1hbCBhY3R1YWxseSBtb3ZlcyB0aGUgdmVydGV4IHRvIGNyZWF0ZVxuLy8gdGhlIGFjdXRlL2JldmVsbGVkIGxpbmUgam9pbi5cbmNvbnN0IEVYVFJVREVfU0NBTEUgPSA2MztcblxuLypcbiAqIFNoYXJwIGNvcm5lcnMgY2F1c2UgZGFzaGVkIGxpbmVzIHRvIHRpbHQgYmVjYXVzZSB0aGUgZGlzdGFuY2UgYWxvbmcgdGhlIGxpbmVcbiAqIGlzIHRoZSBzYW1lIGF0IGJvdGggdGhlIGlubmVyIGFuZCBvdXRlciBjb3JuZXJzLiBUbyBpbXByb3ZlIHRoZSBhcHBlYXJhbmNlIG9mXG4gKiBkYXNoZWQgbGluZXMgd2UgYWRkIGV4dHJhIHBvaW50cyBuZWFyIHNoYXJwIGNvcm5lcnMgc28gdGhhdCBhIHNtYWxsZXIgcGFydFxuICogb2YgdGhlIGxpbmUgaXMgdGlsdGVkLlxuICpcbiAqIENPU19IQUxGX1NIQVJQX0NPUk5FUiBjb250cm9scyBob3cgc2hhcnAgYSBjb3JuZXIgaGFzIHRvIGJlIGZvciB1cyB0byBhZGQgYW5cbiAqIGV4dHJhIHZlcnRleC4gVGhlIGRlZmF1bHQgaXMgNzUgZGVncmVlcy5cbiAqXG4gKiBUaGUgbmV3bHkgY3JlYXRlZCB2ZXJ0aWNlcyBhcmUgcGxhY2VkIFNIQVJQX0NPUk5FUl9PRkZTRVQgcGl4ZWxzIGZyb20gdGhlIGNvcm5lci5cbiAqL1xuY29uc3QgQ09TX0hBTEZfU0hBUlBfQ09STkVSID0gTWF0aC5jb3MoNzUgLyAyICogKE1hdGguUEkgLyAxODApKTtcbmNvbnN0IFNIQVJQX0NPUk5FUl9PRkZTRVQgPSAxNTtcblxuLy8gQW5nbGUgcGVyIHRyaWFuZ2xlIGZvciBhcHByb3hpbWF0aW5nIHJvdW5kIGxpbmUgam9pbnMuXG5jb25zdCBERUdfUEVSX1RSSUFOR0xFID0gMjA7XG5cbnR5cGUgTGluZUNsaXBzID0ge1xuICAgIHN0YXJ0OiBudW1iZXI7XG4gICAgZW5kOiBudW1iZXI7XG59XG5cbnR5cGUgR3JhZGllbnRUZXh0dXJlID0ge1xuICAgIHRleHR1cmU6IFRleHR1cmU7XG4gICAgZ3JhZGllbnQ6ID9SR0JBSW1hZ2U7XG4gICAgdmVyc2lvbjogbnVtYmVyO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmNsYXNzIExpbmVCdWNrZXQgaW1wbGVtZW50cyBCdWNrZXQge1xuICAgIGRpc3RhbmNlOiBudW1iZXI7XG4gICAgdG90YWxEaXN0YW5jZTogbnVtYmVyO1xuICAgIG1heExpbmVMZW5ndGg6IG51bWJlcjtcbiAgICBzY2FsZWREaXN0YW5jZTogbnVtYmVyO1xuICAgIGxpbmVTb0ZhcjogbnVtYmVyO1xuICAgIGxpbmVDbGlwczogP0xpbmVDbGlwcztcblxuICAgIGUxOiBudW1iZXI7XG4gICAgZTI6IG51bWJlcjtcblxuICAgIGluZGV4OiBudW1iZXI7XG4gICAgem9vbTogbnVtYmVyO1xuICAgIG92ZXJzY2FsaW5nOiBudW1iZXI7XG4gICAgbGF5ZXJzOiBBcnJheTxMaW5lU3R5bGVMYXllcj47XG4gICAgbGF5ZXJJZHM6IEFycmF5PHN0cmluZz47XG4gICAgZ3JhZGllbnRzOiB7W3N0cmluZ106IEdyYWRpZW50VGV4dHVyZX07XG4gICAgc3RhdGVEZXBlbmRlbnRMYXllcnM6IEFycmF5PGFueT47XG4gICAgc3RhdGVEZXBlbmRlbnRMYXllcklkczogQXJyYXk8c3RyaW5nPjtcbiAgICBwYXR0ZXJuRmVhdHVyZXM6IEFycmF5PEJ1Y2tldEZlYXR1cmU+O1xuICAgIGxpbmVDbGlwc0FycmF5OiBBcnJheTxMaW5lQ2xpcHM+O1xuXG4gICAgbGF5b3V0VmVydGV4QXJyYXk6IExpbmVMYXlvdXRBcnJheTtcbiAgICBsYXlvdXRWZXJ0ZXhCdWZmZXI6IFZlcnRleEJ1ZmZlcjtcbiAgICBsYXlvdXRWZXJ0ZXhBcnJheTI6IExpbmVFeHRMYXlvdXRBcnJheTtcbiAgICBsYXlvdXRWZXJ0ZXhCdWZmZXIyOiBWZXJ0ZXhCdWZmZXI7XG5cbiAgICBpbmRleEFycmF5OiBUcmlhbmdsZUluZGV4QXJyYXk7XG4gICAgaW5kZXhCdWZmZXI6IEluZGV4QnVmZmVyO1xuXG4gICAgaGFzUGF0dGVybjogYm9vbGVhbjtcbiAgICBwcm9ncmFtQ29uZmlndXJhdGlvbnM6IFByb2dyYW1Db25maWd1cmF0aW9uU2V0PExpbmVTdHlsZUxheWVyPjtcbiAgICBzZWdtZW50czogU2VnbWVudFZlY3RvcjtcbiAgICB1cGxvYWRlZDogYm9vbGVhbjtcbiAgICBwcm9qZWN0aW9uOiBQcm9qZWN0aW9uU3BlY2lmaWNhdGlvbjtcblxuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnM6IEJ1Y2tldFBhcmFtZXRlcnM8TGluZVN0eWxlTGF5ZXI+KSB7XG4gICAgICAgIHRoaXMuem9vbSA9IG9wdGlvbnMuem9vbTtcbiAgICAgICAgdGhpcy5vdmVyc2NhbGluZyA9IG9wdGlvbnMub3ZlcnNjYWxpbmc7XG4gICAgICAgIHRoaXMubGF5ZXJzID0gb3B0aW9ucy5sYXllcnM7XG4gICAgICAgIHRoaXMubGF5ZXJJZHMgPSB0aGlzLmxheWVycy5tYXAobGF5ZXIgPT4gbGF5ZXIuaWQpO1xuICAgICAgICB0aGlzLmluZGV4ID0gb3B0aW9ucy5pbmRleDtcbiAgICAgICAgdGhpcy5wcm9qZWN0aW9uID0gb3B0aW9ucy5wcm9qZWN0aW9uO1xuICAgICAgICB0aGlzLmhhc1BhdHRlcm4gPSBmYWxzZTtcbiAgICAgICAgdGhpcy5wYXR0ZXJuRmVhdHVyZXMgPSBbXTtcbiAgICAgICAgdGhpcy5saW5lQ2xpcHNBcnJheSA9IFtdO1xuICAgICAgICB0aGlzLmdyYWRpZW50cyA9IHt9O1xuICAgICAgICB0aGlzLmxheWVycy5mb3JFYWNoKGxheWVyID0+IHtcbiAgICAgICAgICAgIHRoaXMuZ3JhZGllbnRzW2xheWVyLmlkXSA9IHt9O1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLmxheW91dFZlcnRleEFycmF5ID0gbmV3IExpbmVMYXlvdXRBcnJheSgpO1xuICAgICAgICB0aGlzLmxheW91dFZlcnRleEFycmF5MiA9IG5ldyBMaW5lRXh0TGF5b3V0QXJyYXkoKTtcbiAgICAgICAgdGhpcy5pbmRleEFycmF5ID0gbmV3IFRyaWFuZ2xlSW5kZXhBcnJheSgpO1xuICAgICAgICB0aGlzLnByb2dyYW1Db25maWd1cmF0aW9ucyA9IG5ldyBQcm9ncmFtQ29uZmlndXJhdGlvblNldChvcHRpb25zLmxheWVycywgb3B0aW9ucy56b29tKTtcbiAgICAgICAgdGhpcy5zZWdtZW50cyA9IG5ldyBTZWdtZW50VmVjdG9yKCk7XG4gICAgICAgIHRoaXMubWF4TGluZUxlbmd0aCA9IDA7XG5cbiAgICAgICAgdGhpcy5zdGF0ZURlcGVuZGVudExheWVySWRzID0gdGhpcy5sYXllcnMuZmlsdGVyKChsKSA9PiBsLmlzU3RhdGVEZXBlbmRlbnQoKSkubWFwKChsKSA9PiBsLmlkKTtcbiAgICB9XG5cbiAgICBwb3B1bGF0ZShmZWF0dXJlczogQXJyYXk8SW5kZXhlZEZlYXR1cmU+LCBvcHRpb25zOiBQb3B1bGF0ZVBhcmFtZXRlcnMsIGNhbm9uaWNhbDogQ2Fub25pY2FsVGlsZUlELCB0aWxlVHJhbnNmb3JtOiBUaWxlVHJhbnNmb3JtKSB7XG4gICAgICAgIHRoaXMuaGFzUGF0dGVybiA9IGhhc1BhdHRlcm4oJ2xpbmUnLCB0aGlzLmxheWVycywgb3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGxpbmVTb3J0S2V5ID0gdGhpcy5sYXllcnNbMF0ubGF5b3V0LmdldCgnbGluZS1zb3J0LWtleScpO1xuICAgICAgICBjb25zdCBidWNrZXRGZWF0dXJlcyA9IFtdO1xuXG4gICAgICAgIGZvciAoY29uc3Qge2ZlYXR1cmUsIGlkLCBpbmRleCwgc291cmNlTGF5ZXJJbmRleH0gb2YgZmVhdHVyZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5lZWRHZW9tZXRyeSA9IHRoaXMubGF5ZXJzWzBdLl9mZWF0dXJlRmlsdGVyLm5lZWRHZW9tZXRyeTtcbiAgICAgICAgICAgIGNvbnN0IGV2YWx1YXRpb25GZWF0dXJlID0gdG9FdmFsdWF0aW9uRmVhdHVyZShmZWF0dXJlLCBuZWVkR2VvbWV0cnkpO1xuXG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICBpZiAoIXRoaXMubGF5ZXJzWzBdLl9mZWF0dXJlRmlsdGVyLmZpbHRlcihuZXcgRXZhbHVhdGlvblBhcmFtZXRlcnModGhpcy56b29tKSwgZXZhbHVhdGlvbkZlYXR1cmUsIGNhbm9uaWNhbCkpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICBjb25zdCBzb3J0S2V5ID0gbGluZVNvcnRLZXkgP1xuICAgICAgICAgICAgICAgIGxpbmVTb3J0S2V5LmV2YWx1YXRlKGV2YWx1YXRpb25GZWF0dXJlLCB7fSwgY2Fub25pY2FsKSA6XG4gICAgICAgICAgICAgICAgdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICBjb25zdCBidWNrZXRGZWF0dXJlOiBCdWNrZXRGZWF0dXJlID0ge1xuICAgICAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgICAgIHByb3BlcnRpZXM6IGZlYXR1cmUucHJvcGVydGllcyxcbiAgICAgICAgICAgICAgICB0eXBlOiBmZWF0dXJlLnR5cGUsXG4gICAgICAgICAgICAgICAgc291cmNlTGF5ZXJJbmRleCxcbiAgICAgICAgICAgICAgICBpbmRleCxcbiAgICAgICAgICAgICAgICBnZW9tZXRyeTogbmVlZEdlb21ldHJ5ID8gZXZhbHVhdGlvbkZlYXR1cmUuZ2VvbWV0cnkgOiBsb2FkR2VvbWV0cnkoZmVhdHVyZSwgY2Fub25pY2FsLCB0aWxlVHJhbnNmb3JtKSxcbiAgICAgICAgICAgICAgICBwYXR0ZXJuczoge30sXG4gICAgICAgICAgICAgICAgc29ydEtleVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgYnVja2V0RmVhdHVyZXMucHVzaChidWNrZXRGZWF0dXJlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChsaW5lU29ydEtleSkge1xuICAgICAgICAgICAgYnVja2V0RmVhdHVyZXMuc29ydCgoYSwgYikgPT4ge1xuICAgICAgICAgICAgICAgIC8vIGEuc29ydEtleSBpcyBhbHdheXMgYSBudW1iZXIgd2hlbiBpbiB1c2VcbiAgICAgICAgICAgICAgICByZXR1cm4gKChhLnNvcnRLZXk6IGFueSk6IG51bWJlcikgLSAoKGIuc29ydEtleTogYW55KTogbnVtYmVyKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qge2xpbmVBdGxhcywgZmVhdHVyZUluZGV4fSA9IG9wdGlvbnM7XG4gICAgICAgIGNvbnN0IGhhc0ZlYXR1cmVEYXNoZXMgPSB0aGlzLmFkZENvbnN0YW50RGFzaGVzKGxpbmVBdGxhcyk7XG5cbiAgICAgICAgZm9yIChjb25zdCBidWNrZXRGZWF0dXJlIG9mIGJ1Y2tldEZlYXR1cmVzKSB7XG4gICAgICAgICAgICBjb25zdCB7Z2VvbWV0cnksIGluZGV4LCBzb3VyY2VMYXllckluZGV4fSA9IGJ1Y2tldEZlYXR1cmU7XG5cbiAgICAgICAgICAgIGlmIChoYXNGZWF0dXJlRGFzaGVzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRGZWF0dXJlRGFzaGVzKGJ1Y2tldEZlYXR1cmUsIGxpbmVBdGxhcyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmhhc1BhdHRlcm4pIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXR0ZXJuQnVja2V0RmVhdHVyZSA9IGFkZFBhdHRlcm5EZXBlbmRlbmNpZXMoJ2xpbmUnLCB0aGlzLmxheWVycywgYnVja2V0RmVhdHVyZSwgdGhpcy56b29tLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAvLyBwYXR0ZXJuIGZlYXR1cmVzIGFyZSBhZGRlZCBvbmx5IG9uY2UgdGhlIHBhdHRlcm4gaXMgbG9hZGVkIGludG8gdGhlIGltYWdlIGF0bGFzXG4gICAgICAgICAgICAgICAgLy8gc28gYXJlIHN0b3JlZCBkdXJpbmcgcG9wdWxhdGUgdW50aWwgbGF0ZXIgdXBkYXRlZCB3aXRoIHBvc2l0aW9ucyBieSB0aWxlIHdvcmtlciBpbiBhZGRGZWF0dXJlc1xuICAgICAgICAgICAgICAgIHRoaXMucGF0dGVybkZlYXR1cmVzLnB1c2gocGF0dGVybkJ1Y2tldEZlYXR1cmUpO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkRmVhdHVyZShidWNrZXRGZWF0dXJlLCBnZW9tZXRyeSwgaW5kZXgsIGNhbm9uaWNhbCwgbGluZUF0bGFzLnBvc2l0aW9ucywgb3B0aW9ucy5hdmFpbGFibGVJbWFnZXMpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBmZWF0dXJlID0gZmVhdHVyZXNbaW5kZXhdLmZlYXR1cmU7XG4gICAgICAgICAgICBmZWF0dXJlSW5kZXguaW5zZXJ0KGZlYXR1cmUsIGdlb21ldHJ5LCBpbmRleCwgc291cmNlTGF5ZXJJbmRleCwgdGhpcy5pbmRleCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhZGRDb25zdGFudERhc2hlcyhsaW5lQXRsYXM6IExpbmVBdGxhcyk6IGJvb2xlYW4ge1xuICAgICAgICBsZXQgaGFzRmVhdHVyZURhc2hlcyA9IGZhbHNlO1xuXG4gICAgICAgIGZvciAoY29uc3QgbGF5ZXIgb2YgdGhpcy5sYXllcnMpIHtcbiAgICAgICAgICAgIGNvbnN0IGRhc2hQcm9wZXJ0eVZhbHVlID0gbGF5ZXIucGFpbnQuZ2V0KCdsaW5lLWRhc2hhcnJheScpLnZhbHVlO1xuICAgICAgICAgICAgY29uc3QgY2FwUHJvcGVydHlWYWx1ZSA9IGxheWVyLmxheW91dC5nZXQoJ2xpbmUtY2FwJykudmFsdWU7XG5cbiAgICAgICAgICAgIGlmIChkYXNoUHJvcGVydHlWYWx1ZS5raW5kICE9PSAnY29uc3RhbnQnIHx8IGNhcFByb3BlcnR5VmFsdWUua2luZCAhPT0gJ2NvbnN0YW50Jykge1xuICAgICAgICAgICAgICAgIGhhc0ZlYXR1cmVEYXNoZXMgPSB0cnVlO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbnN0Q2FwID0gY2FwUHJvcGVydHlWYWx1ZS52YWx1ZTtcbiAgICAgICAgICAgICAgICBjb25zdCBjb25zdERhc2ggPSBkYXNoUHJvcGVydHlWYWx1ZS52YWx1ZTtcbiAgICAgICAgICAgICAgICBpZiAoIWNvbnN0RGFzaCkgY29udGludWU7XG4gICAgICAgICAgICAgICAgbGluZUF0bGFzLmFkZERhc2goY29uc3REYXNoLCBjb25zdENhcCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gaGFzRmVhdHVyZURhc2hlcztcbiAgICB9XG5cbiAgICBhZGRGZWF0dXJlRGFzaGVzKGZlYXR1cmU6IEJ1Y2tldEZlYXR1cmUsIGxpbmVBdGxhczogTGluZUF0bGFzKSB7XG5cbiAgICAgICAgY29uc3Qgem9vbSA9IHRoaXMuem9vbTtcblxuICAgICAgICBmb3IgKGNvbnN0IGxheWVyIG9mIHRoaXMubGF5ZXJzKSB7XG4gICAgICAgICAgICBjb25zdCBkYXNoUHJvcGVydHlWYWx1ZSA9IGxheWVyLnBhaW50LmdldCgnbGluZS1kYXNoYXJyYXknKS52YWx1ZTtcbiAgICAgICAgICAgIGNvbnN0IGNhcFByb3BlcnR5VmFsdWUgPSBsYXllci5sYXlvdXQuZ2V0KCdsaW5lLWNhcCcpLnZhbHVlO1xuXG4gICAgICAgICAgICBpZiAoZGFzaFByb3BlcnR5VmFsdWUua2luZCA9PT0gJ2NvbnN0YW50JyAmJiBjYXBQcm9wZXJ0eVZhbHVlLmtpbmQgPT09ICdjb25zdGFudCcpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICBsZXQgZGFzaEFycmF5LCBjYXA7XG5cbiAgICAgICAgICAgIGlmIChkYXNoUHJvcGVydHlWYWx1ZS5raW5kID09PSAnY29uc3RhbnQnKSB7XG4gICAgICAgICAgICAgICAgZGFzaEFycmF5ID0gZGFzaFByb3BlcnR5VmFsdWUudmFsdWU7XG4gICAgICAgICAgICAgICAgaWYgKCFkYXNoQXJyYXkpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGRhc2hBcnJheSA9IGRhc2hQcm9wZXJ0eVZhbHVlLmV2YWx1YXRlKHt6b29tfSwgZmVhdHVyZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjYXBQcm9wZXJ0eVZhbHVlLmtpbmQgPT09ICdjb25zdGFudCcpIHtcbiAgICAgICAgICAgICAgICBjYXAgPSBjYXBQcm9wZXJ0eVZhbHVlLnZhbHVlO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNhcCA9IGNhcFByb3BlcnR5VmFsdWUuZXZhbHVhdGUoe3pvb219LCBmZWF0dXJlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGluZUF0bGFzLmFkZERhc2goZGFzaEFycmF5LCBjYXApO1xuXG4gICAgICAgICAgICAvLyBzYXZlIHBvc2l0aW9ucyBmb3IgcGFpbnQgYXJyYXlcbiAgICAgICAgICAgIGZlYXR1cmUucGF0dGVybnNbbGF5ZXIuaWRdID0gbGluZUF0bGFzLmdldEtleShkYXNoQXJyYXksIGNhcCk7XG4gICAgICAgIH1cblxuICAgIH1cblxuICAgIHVwZGF0ZShzdGF0ZXM6IEZlYXR1cmVTdGF0ZXMsIHZ0TGF5ZXI6IElWZWN0b3JUaWxlTGF5ZXIsIGF2YWlsYWJsZUltYWdlczogQXJyYXk8c3RyaW5nPiwgaW1hZ2VQb3NpdGlvbnM6IFNwcml0ZVBvc2l0aW9ucykge1xuICAgICAgICBpZiAoIXRoaXMuc3RhdGVEZXBlbmRlbnRMYXllcnMubGVuZ3RoKSByZXR1cm47XG4gICAgICAgIHRoaXMucHJvZ3JhbUNvbmZpZ3VyYXRpb25zLnVwZGF0ZVBhaW50QXJyYXlzKHN0YXRlcywgdnRMYXllciwgdGhpcy5zdGF0ZURlcGVuZGVudExheWVycywgYXZhaWxhYmxlSW1hZ2VzLCBpbWFnZVBvc2l0aW9ucyk7XG4gICAgfVxuXG4gICAgYWRkRmVhdHVyZXMob3B0aW9uczogUG9wdWxhdGVQYXJhbWV0ZXJzLCBjYW5vbmljYWw6IENhbm9uaWNhbFRpbGVJRCwgaW1hZ2VQb3NpdGlvbnM6IFNwcml0ZVBvc2l0aW9ucywgYXZhaWxhYmxlSW1hZ2VzOiBBcnJheTxzdHJpbmc+LCBfOiBUaWxlVHJhbnNmb3JtKSB7XG4gICAgICAgIGZvciAoY29uc3QgZmVhdHVyZSBvZiB0aGlzLnBhdHRlcm5GZWF0dXJlcykge1xuICAgICAgICAgICAgdGhpcy5hZGRGZWF0dXJlKGZlYXR1cmUsIGZlYXR1cmUuZ2VvbWV0cnksIGZlYXR1cmUuaW5kZXgsIGNhbm9uaWNhbCwgaW1hZ2VQb3NpdGlvbnMsIGF2YWlsYWJsZUltYWdlcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpc0VtcHR5KCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5sYXlvdXRWZXJ0ZXhBcnJheS5sZW5ndGggPT09IDA7XG4gICAgfVxuXG4gICAgdXBsb2FkUGVuZGluZygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICF0aGlzLnVwbG9hZGVkIHx8IHRoaXMucHJvZ3JhbUNvbmZpZ3VyYXRpb25zLm5lZWRzVXBsb2FkO1xuICAgIH1cblxuICAgIHVwbG9hZChjb250ZXh0OiBDb250ZXh0KSB7XG4gICAgICAgIGlmICghdGhpcy51cGxvYWRlZCkge1xuICAgICAgICAgICAgaWYgKHRoaXMubGF5b3V0VmVydGV4QXJyYXkyLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0VmVydGV4QnVmZmVyMiA9IGNvbnRleHQuY3JlYXRlVmVydGV4QnVmZmVyKHRoaXMubGF5b3V0VmVydGV4QXJyYXkyLCBsYXlvdXRBdHRyaWJ1dGVzRXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMubGF5b3V0VmVydGV4QnVmZmVyID0gY29udGV4dC5jcmVhdGVWZXJ0ZXhCdWZmZXIodGhpcy5sYXlvdXRWZXJ0ZXhBcnJheSwgbGF5b3V0QXR0cmlidXRlcyk7XG4gICAgICAgICAgICB0aGlzLmluZGV4QnVmZmVyID0gY29udGV4dC5jcmVhdGVJbmRleEJ1ZmZlcih0aGlzLmluZGV4QXJyYXkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucHJvZ3JhbUNvbmZpZ3VyYXRpb25zLnVwbG9hZChjb250ZXh0KTtcbiAgICAgICAgdGhpcy51cGxvYWRlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmxheW91dFZlcnRleEJ1ZmZlcikgcmV0dXJuO1xuICAgICAgICB0aGlzLmxheW91dFZlcnRleEJ1ZmZlci5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMuaW5kZXhCdWZmZXIuZGVzdHJveSgpO1xuICAgICAgICB0aGlzLnByb2dyYW1Db25maWd1cmF0aW9ucy5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMuc2VnbWVudHMuZGVzdHJveSgpO1xuICAgIH1cblxuICAgIGxpbmVGZWF0dXJlQ2xpcHMoZmVhdHVyZTogQnVja2V0RmVhdHVyZSk6ID9MaW5lQ2xpcHMge1xuICAgICAgICBpZiAoISFmZWF0dXJlLnByb3BlcnRpZXMgJiYgZmVhdHVyZS5wcm9wZXJ0aWVzLmhhc093blByb3BlcnR5KCdtYXBib3hfY2xpcF9zdGFydCcpICYmIGZlYXR1cmUucHJvcGVydGllcy5oYXNPd25Qcm9wZXJ0eSgnbWFwYm94X2NsaXBfZW5kJykpIHtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0ID0gK2ZlYXR1cmUucHJvcGVydGllc1snbWFwYm94X2NsaXBfc3RhcnQnXTtcbiAgICAgICAgICAgIGNvbnN0IGVuZCA9ICtmZWF0dXJlLnByb3BlcnRpZXNbJ21hcGJveF9jbGlwX2VuZCddO1xuICAgICAgICAgICAgcmV0dXJuIHtzdGFydCwgZW5kfTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFkZEZlYXR1cmUoZmVhdHVyZTogQnVja2V0RmVhdHVyZSwgZ2VvbWV0cnk6IEFycmF5PEFycmF5PFBvaW50Pj4sIGluZGV4OiBudW1iZXIsIGNhbm9uaWNhbDogQ2Fub25pY2FsVGlsZUlELCBpbWFnZVBvc2l0aW9uczogU3ByaXRlUG9zaXRpb25zLCBhdmFpbGFibGVJbWFnZXM6IEFycmF5PHN0cmluZz4pIHtcbiAgICAgICAgY29uc3QgbGF5b3V0ID0gdGhpcy5sYXllcnNbMF0ubGF5b3V0O1xuICAgICAgICBjb25zdCBqb2luID0gbGF5b3V0LmdldCgnbGluZS1qb2luJykuZXZhbHVhdGUoZmVhdHVyZSwge30pO1xuICAgICAgICBjb25zdCBjYXAgPSBsYXlvdXQuZ2V0KCdsaW5lLWNhcCcpLmV2YWx1YXRlKGZlYXR1cmUsIHt9KTtcbiAgICAgICAgY29uc3QgbWl0ZXJMaW1pdCA9IGxheW91dC5nZXQoJ2xpbmUtbWl0ZXItbGltaXQnKTtcbiAgICAgICAgY29uc3Qgcm91bmRMaW1pdCA9IGxheW91dC5nZXQoJ2xpbmUtcm91bmQtbGltaXQnKTtcbiAgICAgICAgdGhpcy5saW5lQ2xpcHMgPSB0aGlzLmxpbmVGZWF0dXJlQ2xpcHMoZmVhdHVyZSk7XG5cbiAgICAgICAgZm9yIChjb25zdCBsaW5lIG9mIGdlb21ldHJ5KSB7XG4gICAgICAgICAgICB0aGlzLmFkZExpbmUobGluZSwgZmVhdHVyZSwgam9pbiwgY2FwLCBtaXRlckxpbWl0LCByb3VuZExpbWl0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucHJvZ3JhbUNvbmZpZ3VyYXRpb25zLnBvcHVsYXRlUGFpbnRBcnJheXModGhpcy5sYXlvdXRWZXJ0ZXhBcnJheS5sZW5ndGgsIGZlYXR1cmUsIGluZGV4LCBpbWFnZVBvc2l0aW9ucywgYXZhaWxhYmxlSW1hZ2VzLCBjYW5vbmljYWwpO1xuICAgIH1cblxuICAgIGFkZExpbmUodmVydGljZXM6IEFycmF5PFBvaW50PiwgZmVhdHVyZTogQnVja2V0RmVhdHVyZSwgam9pbjogc3RyaW5nLCBjYXA6IHN0cmluZywgbWl0ZXJMaW1pdDogbnVtYmVyLCByb3VuZExpbWl0OiBudW1iZXIpIHtcbiAgICAgICAgdGhpcy5kaXN0YW5jZSA9IDA7XG4gICAgICAgIHRoaXMuc2NhbGVkRGlzdGFuY2UgPSAwO1xuICAgICAgICB0aGlzLnRvdGFsRGlzdGFuY2UgPSAwO1xuICAgICAgICB0aGlzLmxpbmVTb0ZhciA9IDA7XG5cbiAgICAgICAgaWYgKHRoaXMubGluZUNsaXBzKSB7XG4gICAgICAgICAgICB0aGlzLmxpbmVDbGlwc0FycmF5LnB1c2godGhpcy5saW5lQ2xpcHMpO1xuICAgICAgICAgICAgLy8gQ2FsY3VsYXRlIHRoZSB0b3RhbCBkaXN0YW5jZSwgaW4gdGlsZSB1bml0cywgb2YgdGhpcyB0aWxlZCBsaW5lIGZlYXR1cmVcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmVydGljZXMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50b3RhbERpc3RhbmNlICs9IHZlcnRpY2VzW2ldLmRpc3QodmVydGljZXNbaSArIDFdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMudXBkYXRlU2NhbGVkRGlzdGFuY2UoKTtcbiAgICAgICAgICAgIHRoaXMubWF4TGluZUxlbmd0aCA9IE1hdGgubWF4KHRoaXMubWF4TGluZUxlbmd0aCwgdGhpcy50b3RhbERpc3RhbmNlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGlzUG9seWdvbiA9IHZlY3RvclRpbGVGZWF0dXJlVHlwZXNbZmVhdHVyZS50eXBlXSA9PT0gJ1BvbHlnb24nO1xuXG4gICAgICAgIC8vIElmIHRoZSBsaW5lIGhhcyBkdXBsaWNhdGUgdmVydGljZXMgYXQgdGhlIGVuZHMsIGFkanVzdCBzdGFydC9sZW5ndGggdG8gcmVtb3ZlIHRoZW0uXG4gICAgICAgIGxldCBsZW4gPSB2ZXJ0aWNlcy5sZW5ndGg7XG4gICAgICAgIHdoaWxlIChsZW4gPj0gMiAmJiB2ZXJ0aWNlc1tsZW4gLSAxXS5lcXVhbHModmVydGljZXNbbGVuIC0gMl0pKSB7XG4gICAgICAgICAgICBsZW4tLTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgZmlyc3QgPSAwO1xuICAgICAgICB3aGlsZSAoZmlyc3QgPCBsZW4gLSAxICYmIHZlcnRpY2VzW2ZpcnN0XS5lcXVhbHModmVydGljZXNbZmlyc3QgKyAxXSkpIHtcbiAgICAgICAgICAgIGZpcnN0Kys7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZ25vcmUgaW52YWxpZCBnZW9tZXRyeS5cbiAgICAgICAgaWYgKGxlbiA8IChpc1BvbHlnb24gPyAzIDogMikpIHJldHVybjtcblxuICAgICAgICBpZiAoam9pbiA9PT0gJ2JldmVsJykgbWl0ZXJMaW1pdCA9IDEuMDU7XG5cbiAgICAgICAgY29uc3Qgc2hhcnBDb3JuZXJPZmZzZXQgPSB0aGlzLm92ZXJzY2FsaW5nIDw9IDE2ID9cbiAgICAgICAgICAgIFNIQVJQX0NPUk5FUl9PRkZTRVQgKiBFWFRFTlQgLyAoNTEyICogdGhpcy5vdmVyc2NhbGluZykgOlxuICAgICAgICAgICAgMDtcblxuICAgICAgICAvLyB3ZSBjb3VsZCBiZSBtb3JlIHByZWNpc2UsIGJ1dCBpdCB3b3VsZCBvbmx5IHNhdmUgYSBuZWdsaWdpYmxlIGFtb3VudCBvZiBzcGFjZVxuICAgICAgICBjb25zdCBzZWdtZW50ID0gdGhpcy5zZWdtZW50cy5wcmVwYXJlU2VnbWVudChsZW4gKiAxMCwgdGhpcy5sYXlvdXRWZXJ0ZXhBcnJheSwgdGhpcy5pbmRleEFycmF5KTtcblxuICAgICAgICBsZXQgY3VycmVudFZlcnRleDtcbiAgICAgICAgbGV0IHByZXZWZXJ0ZXggPSAoKHVuZGVmaW5lZDogYW55KTogUG9pbnQpO1xuICAgICAgICBsZXQgbmV4dFZlcnRleCA9ICgodW5kZWZpbmVkOiBhbnkpOiBQb2ludCk7XG4gICAgICAgIGxldCBwcmV2Tm9ybWFsID0gKCh1bmRlZmluZWQ6IGFueSk6IFBvaW50KTtcbiAgICAgICAgbGV0IG5leHROb3JtYWwgPSAoKHVuZGVmaW5lZDogYW55KTogUG9pbnQpO1xuXG4gICAgICAgIC8vIHRoZSBsYXN0IHR3byB2ZXJ0aWNlcyBhZGRlZFxuICAgICAgICB0aGlzLmUxID0gdGhpcy5lMiA9IC0xO1xuXG4gICAgICAgIGlmIChpc1BvbHlnb24pIHtcbiAgICAgICAgICAgIGN1cnJlbnRWZXJ0ZXggPSB2ZXJ0aWNlc1tsZW4gLSAyXTtcbiAgICAgICAgICAgIG5leHROb3JtYWwgPSB2ZXJ0aWNlc1tmaXJzdF0uc3ViKGN1cnJlbnRWZXJ0ZXgpLl91bml0KCkuX3BlcnAoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAobGV0IGkgPSBmaXJzdDsgaSA8IGxlbjsgaSsrKSB7XG5cbiAgICAgICAgICAgIG5leHRWZXJ0ZXggPSBpID09PSBsZW4gLSAxID9cbiAgICAgICAgICAgICAgICAoaXNQb2x5Z29uID8gdmVydGljZXNbZmlyc3QgKyAxXSA6ICh1bmRlZmluZWQ6IGFueSkpIDogLy8gaWYgaXQncyBhIHBvbHlnb24sIHRyZWF0IHRoZSBsYXN0IHZlcnRleCBsaWtlIHRoZSBmaXJzdFxuICAgICAgICAgICAgICAgIHZlcnRpY2VzW2kgKyAxXTsgLy8ganVzdCB0aGUgbmV4dCB2ZXJ0ZXhcblxuICAgICAgICAgICAgLy8gaWYgdHdvIGNvbnNlY3V0aXZlIHZlcnRpY2VzIGV4aXN0LCBza2lwIHRoZSBjdXJyZW50IG9uZVxuICAgICAgICAgICAgaWYgKG5leHRWZXJ0ZXggJiYgdmVydGljZXNbaV0uZXF1YWxzKG5leHRWZXJ0ZXgpKSBjb250aW51ZTtcblxuICAgICAgICAgICAgaWYgKG5leHROb3JtYWwpIHByZXZOb3JtYWwgPSBuZXh0Tm9ybWFsO1xuICAgICAgICAgICAgaWYgKGN1cnJlbnRWZXJ0ZXgpIHByZXZWZXJ0ZXggPSBjdXJyZW50VmVydGV4O1xuXG4gICAgICAgICAgICBjdXJyZW50VmVydGV4ID0gdmVydGljZXNbaV07XG5cbiAgICAgICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgbm9ybWFsIHRvd2FyZHMgdGhlIG5leHQgdmVydGV4IGluIHRoaXMgbGluZS4gSW4gY2FzZVxuICAgICAgICAgICAgLy8gdGhlcmUgaXMgbm8gbmV4dCB2ZXJ0ZXgsIHByZXRlbmQgdGhhdCB0aGUgbGluZSBpcyBjb250aW51aW5nIHN0cmFpZ2h0LFxuICAgICAgICAgICAgLy8gbWVhbmluZyB0aGF0IHdlIGFyZSBqdXN0IHVzaW5nIHRoZSBwcmV2aW91cyBub3JtYWwuXG4gICAgICAgICAgICBuZXh0Tm9ybWFsID0gbmV4dFZlcnRleCA/IG5leHRWZXJ0ZXguc3ViKGN1cnJlbnRWZXJ0ZXgpLl91bml0KCkuX3BlcnAoKSA6IHByZXZOb3JtYWw7XG5cbiAgICAgICAgICAgIC8vIElmIHdlIHN0aWxsIGRvbid0IGhhdmUgYSBwcmV2aW91cyBub3JtYWwsIHRoaXMgaXMgdGhlIGJlZ2lubmluZyBvZiBhXG4gICAgICAgICAgICAvLyBub24tY2xvc2VkIGxpbmUsIHNvIHdlJ3JlIGRvaW5nIGEgc3RyYWlnaHQgXCJqb2luXCIuXG4gICAgICAgICAgICBwcmV2Tm9ybWFsID0gcHJldk5vcm1hbCB8fCBuZXh0Tm9ybWFsO1xuXG4gICAgICAgICAgICAvLyBEZXRlcm1pbmUgdGhlIG5vcm1hbCBvZiB0aGUgam9pbiBleHRydXNpb24uIEl0IGlzIHRoZSBhbmdsZSBiaXNlY3RvclxuICAgICAgICAgICAgLy8gb2YgdGhlIHNlZ21lbnRzIGJldHdlZW4gdGhlIHByZXZpb3VzIGxpbmUgYW5kIHRoZSBuZXh0IGxpbmUuXG4gICAgICAgICAgICAvLyBJbiB0aGUgY2FzZSBvZiAxODDCsCBhbmdsZXMsIHRoZSBwcmV2IGFuZCBuZXh0IG5vcm1hbHMgY2FuY2VsIGVhY2ggb3RoZXIgb3V0OlxuICAgICAgICAgICAgLy8gcHJldk5vcm1hbCArIG5leHROb3JtYWwgPSAoMCwgMCksIGl0cyBtYWduaXR1ZGUgaXMgMCwgc28gdGhlIHVuaXQgdmVjdG9yIHdvdWxkIGJlXG4gICAgICAgICAgICAvLyB1bmRlZmluZWQuIEluIHRoYXQgY2FzZSwgd2UncmUga2VlcGluZyB0aGUgam9pbk5vcm1hbCBhdCAoMCwgMCksIHNvIHRoYXQgdGhlIGNvc0hhbGZBbmdsZVxuICAgICAgICAgICAgLy8gYmVsb3cgd2lsbCBhbHNvIGJlY29tZSAwIGFuZCBtaXRlckxlbmd0aCB3aWxsIGJlY29tZSBJbmZpbml0eS5cbiAgICAgICAgICAgIGxldCBqb2luTm9ybWFsID0gcHJldk5vcm1hbC5hZGQobmV4dE5vcm1hbCk7XG4gICAgICAgICAgICBpZiAoam9pbk5vcm1hbC54ICE9PSAwIHx8IGpvaW5Ob3JtYWwueSAhPT0gMCkge1xuICAgICAgICAgICAgICAgIGpvaW5Ob3JtYWwuX3VuaXQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8qICBqb2luTm9ybWFsICAgICBwcmV2Tm9ybWFsXG4gICAgICAgICAgICAgKiAgICAgICAgICAgICDihpYgICAgICDihpFcbiAgICAgICAgICAgICAqICAgICAgICAgICAgICAgIC5fX19fX19fXy4gcHJldlZlcnRleFxuICAgICAgICAgICAgICogICAgICAgICAgICAgICAgfFxuICAgICAgICAgICAgICogbmV4dE5vcm1hbCAg4oaQICB8ICBjdXJyZW50VmVydGV4XG4gICAgICAgICAgICAgKiAgICAgICAgICAgICAgICB8XG4gICAgICAgICAgICAgKiAgICAgbmV4dFZlcnRleCAhXG4gICAgICAgICAgICAgKlxuICAgICAgICAgICAgICovXG5cbiAgICAgICAgICAgIC8vIGNhbGN1bGF0ZSBjb3NpbmVzIG9mIHRoZSBhbmdsZSAoYW5kIGl0cyBoYWxmKSB1c2luZyBkb3QgcHJvZHVjdFxuICAgICAgICAgICAgY29uc3QgY29zQW5nbGUgPSBwcmV2Tm9ybWFsLnggKiBuZXh0Tm9ybWFsLnggKyBwcmV2Tm9ybWFsLnkgKiBuZXh0Tm9ybWFsLnk7XG4gICAgICAgICAgICBjb25zdCBjb3NIYWxmQW5nbGUgPSBqb2luTm9ybWFsLnggKiBuZXh0Tm9ybWFsLnggKyBqb2luTm9ybWFsLnkgKiBuZXh0Tm9ybWFsLnk7XG5cbiAgICAgICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgbGVuZ3RoIG9mIHRoZSBtaXRlciAodGhlIHJhdGlvIG9mIHRoZSBtaXRlciB0byB0aGUgd2lkdGgpXG4gICAgICAgICAgICAvLyBhcyB0aGUgaW52ZXJzZSBvZiBjb3NpbmUgb2YgdGhlIGFuZ2xlIGJldHdlZW4gbmV4dCBhbmQgam9pbiBub3JtYWxzXG4gICAgICAgICAgICBjb25zdCBtaXRlckxlbmd0aCA9IGNvc0hhbGZBbmdsZSAhPT0gMCA/IDEgLyBjb3NIYWxmQW5nbGUgOiBJbmZpbml0eTtcblxuICAgICAgICAgICAgLy8gYXBwcm94aW1hdGUgYW5nbGUgZnJvbSBjb3NpbmVcbiAgICAgICAgICAgIGNvbnN0IGFwcHJveEFuZ2xlID0gMiAqIE1hdGguc3FydCgyIC0gMiAqIGNvc0hhbGZBbmdsZSk7XG5cbiAgICAgICAgICAgIGNvbnN0IGlzU2hhcnBDb3JuZXIgPSBjb3NIYWxmQW5nbGUgPCBDT1NfSEFMRl9TSEFSUF9DT1JORVIgJiYgcHJldlZlcnRleCAmJiBuZXh0VmVydGV4O1xuICAgICAgICAgICAgY29uc3QgbGluZVR1cm5zTGVmdCA9IHByZXZOb3JtYWwueCAqIG5leHROb3JtYWwueSAtIHByZXZOb3JtYWwueSAqIG5leHROb3JtYWwueCA+IDA7XG5cbiAgICAgICAgICAgIGlmIChpc1NoYXJwQ29ybmVyICYmIGkgPiBmaXJzdCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHByZXZTZWdtZW50TGVuZ3RoID0gY3VycmVudFZlcnRleC5kaXN0KHByZXZWZXJ0ZXgpO1xuICAgICAgICAgICAgICAgIGlmIChwcmV2U2VnbWVudExlbmd0aCA+IDIgKiBzaGFycENvcm5lck9mZnNldCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdQcmV2VmVydGV4ID0gY3VycmVudFZlcnRleC5zdWIoY3VycmVudFZlcnRleC5zdWIocHJldlZlcnRleCkuX211bHQoc2hhcnBDb3JuZXJPZmZzZXQgLyBwcmV2U2VnbWVudExlbmd0aCkuX3JvdW5kKCkpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZURpc3RhbmNlKHByZXZWZXJ0ZXgsIG5ld1ByZXZWZXJ0ZXgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZEN1cnJlbnRWZXJ0ZXgobmV3UHJldlZlcnRleCwgcHJldk5vcm1hbCwgMCwgMCwgc2VnbWVudCk7XG4gICAgICAgICAgICAgICAgICAgIHByZXZWZXJ0ZXggPSBuZXdQcmV2VmVydGV4O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gVGhlIGpvaW4gaWYgYSBtaWRkbGUgdmVydGV4LCBvdGhlcndpc2UgdGhlIGNhcC5cbiAgICAgICAgICAgIGNvbnN0IG1pZGRsZVZlcnRleCA9IHByZXZWZXJ0ZXggJiYgbmV4dFZlcnRleDtcbiAgICAgICAgICAgIGxldCBjdXJyZW50Sm9pbiA9IG1pZGRsZVZlcnRleCA/IGpvaW4gOiBpc1BvbHlnb24gPyAnYnV0dCcgOiBjYXA7XG5cbiAgICAgICAgICAgIGlmIChtaWRkbGVWZXJ0ZXggJiYgY3VycmVudEpvaW4gPT09ICdyb3VuZCcpIHtcbiAgICAgICAgICAgICAgICBpZiAobWl0ZXJMZW5ndGggPCByb3VuZExpbWl0KSB7XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRKb2luID0gJ21pdGVyJztcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG1pdGVyTGVuZ3RoIDw9IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudEpvaW4gPSAnZmFrZXJvdW5kJztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjdXJyZW50Sm9pbiA9PT0gJ21pdGVyJyAmJiBtaXRlckxlbmd0aCA+IG1pdGVyTGltaXQpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50Sm9pbiA9ICdiZXZlbCc7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjdXJyZW50Sm9pbiA9PT0gJ2JldmVsJykge1xuICAgICAgICAgICAgICAgIC8vIFRoZSBtYXhpbXVtIGV4dHJ1ZGUgbGVuZ3RoIGlzIDEyOCAvIDYzID0gMiB0aW1lcyB0aGUgd2lkdGggb2YgdGhlIGxpbmVcbiAgICAgICAgICAgICAgICAvLyBzbyBpZiBtaXRlckxlbmd0aCA+PSAyIHdlIG5lZWQgdG8gZHJhdyBhIGRpZmZlcmVudCB0eXBlIG9mIGJldmVsIGhlcmUuXG4gICAgICAgICAgICAgICAgaWYgKG1pdGVyTGVuZ3RoID4gMikgY3VycmVudEpvaW4gPSAnZmxpcGJldmVsJztcblxuICAgICAgICAgICAgICAgIC8vIElmIHRoZSBtaXRlckxlbmd0aCBpcyByZWFsbHkgc21hbGwgYW5kIHRoZSBsaW5lIGJldmVsIHdvdWxkbid0IGJlIHZpc2libGUsXG4gICAgICAgICAgICAgICAgLy8ganVzdCBkcmF3IGEgbWl0ZXIgam9pbiB0byBzYXZlIGEgdHJpYW5nbGUuXG4gICAgICAgICAgICAgICAgaWYgKG1pdGVyTGVuZ3RoIDwgbWl0ZXJMaW1pdCkgY3VycmVudEpvaW4gPSAnbWl0ZXInO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBDYWxjdWxhdGUgaG93IGZhciBhbG9uZyB0aGUgbGluZSB0aGUgY3VycmVudFZlcnRleCBpc1xuICAgICAgICAgICAgaWYgKHByZXZWZXJ0ZXgpIHRoaXMudXBkYXRlRGlzdGFuY2UocHJldlZlcnRleCwgY3VycmVudFZlcnRleCk7XG5cbiAgICAgICAgICAgIGlmIChjdXJyZW50Sm9pbiA9PT0gJ21pdGVyJykge1xuXG4gICAgICAgICAgICAgICAgam9pbk5vcm1hbC5fbXVsdChtaXRlckxlbmd0aCk7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRDdXJyZW50VmVydGV4KGN1cnJlbnRWZXJ0ZXgsIGpvaW5Ob3JtYWwsIDAsIDAsIHNlZ21lbnQpO1xuXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGN1cnJlbnRKb2luID09PSAnZmxpcGJldmVsJykge1xuICAgICAgICAgICAgICAgIC8vIG1pdGVyIGlzIHRvbyBiaWcsIGZsaXAgdGhlIGRpcmVjdGlvbiB0byBtYWtlIGEgYmV2ZWxlZCBqb2luXG5cbiAgICAgICAgICAgICAgICBpZiAobWl0ZXJMZW5ndGggPiAxMDApIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQWxtb3N0IHBhcmFsbGVsIGxpbmVzXG4gICAgICAgICAgICAgICAgICAgIGpvaW5Ob3JtYWwgPSBuZXh0Tm9ybWFsLm11bHQoLTEpO1xuXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYmV2ZWxMZW5ndGggPSBtaXRlckxlbmd0aCAqIHByZXZOb3JtYWwuYWRkKG5leHROb3JtYWwpLm1hZygpIC8gcHJldk5vcm1hbC5zdWIobmV4dE5vcm1hbCkubWFnKCk7XG4gICAgICAgICAgICAgICAgICAgIGpvaW5Ob3JtYWwuX3BlcnAoKS5fbXVsdChiZXZlbExlbmd0aCAqIChsaW5lVHVybnNMZWZ0ID8gLTEgOiAxKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuYWRkQ3VycmVudFZlcnRleChjdXJyZW50VmVydGV4LCBqb2luTm9ybWFsLCAwLCAwLCBzZWdtZW50KTtcbiAgICAgICAgICAgICAgICB0aGlzLmFkZEN1cnJlbnRWZXJ0ZXgoY3VycmVudFZlcnRleCwgam9pbk5vcm1hbC5tdWx0KC0xKSwgMCwgMCwgc2VnbWVudCk7XG5cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY3VycmVudEpvaW4gPT09ICdiZXZlbCcgfHwgY3VycmVudEpvaW4gPT09ICdmYWtlcm91bmQnKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb2Zmc2V0ID0gLU1hdGguc3FydChtaXRlckxlbmd0aCAqIG1pdGVyTGVuZ3RoIC0gMSk7XG4gICAgICAgICAgICAgICAgY29uc3Qgb2Zmc2V0QSA9IGxpbmVUdXJuc0xlZnQgPyBvZmZzZXQgOiAwO1xuICAgICAgICAgICAgICAgIGNvbnN0IG9mZnNldEIgPSBsaW5lVHVybnNMZWZ0ID8gMCA6IG9mZnNldDtcblxuICAgICAgICAgICAgICAgIC8vIENsb3NlIHByZXZpb3VzIHNlZ21lbnQgd2l0aCBhIGJldmVsXG4gICAgICAgICAgICAgICAgaWYgKHByZXZWZXJ0ZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGRDdXJyZW50VmVydGV4KGN1cnJlbnRWZXJ0ZXgsIHByZXZOb3JtYWwsIG9mZnNldEEsIG9mZnNldEIsIHNlZ21lbnQpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChjdXJyZW50Sm9pbiA9PT0gJ2Zha2Vyb3VuZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGpvaW4gYW5nbGUgaXMgc2hhcnAgZW5vdWdoIHRoYXQgYSByb3VuZCBqb2luIHdvdWxkIGJlIHZpc2libGUuXG4gICAgICAgICAgICAgICAgICAgIC8vIEJldmVsIGpvaW5zIGZpbGwgdGhlIGdhcCBiZXR3ZWVuIHNlZ21lbnRzIHdpdGggYSBzaW5nbGUgcGllIHNsaWNlIHRyaWFuZ2xlLlxuICAgICAgICAgICAgICAgICAgICAvLyBDcmVhdGUgYSByb3VuZCBqb2luIGJ5IGFkZGluZyBtdWx0aXBsZSBwaWUgc2xpY2VzLiBUaGUgam9pbiBpc24ndCBhY3R1YWxseSByb3VuZCwgYnV0XG4gICAgICAgICAgICAgICAgICAgIC8vIGl0IGxvb2tzIGxpa2UgaXQgaXMgYXQgdGhlIHNpemVzIHdlIHJlbmRlciBsaW5lcyBhdC5cblxuICAgICAgICAgICAgICAgICAgICAvLyBwaWNrIHRoZSBudW1iZXIgb2YgdHJpYW5nbGVzIGZvciBhcHByb3hpbWF0aW5nIHJvdW5kIGpvaW4gYnkgYmFzZWQgb24gdGhlIGFuZ2xlIGJldHdlZW4gbm9ybWFsc1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBuID0gTWF0aC5yb3VuZCgoYXBwcm94QW5nbGUgKiAxODAgLyBNYXRoLlBJKSAvIERFR19QRVJfVFJJQU5HTEUpO1xuXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IG0gPSAxOyBtIDwgbjsgbSsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgdCA9IG0gLyBuO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHQgIT09IDAuNSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFwcHJveGltYXRlIHNwaGVyaWNhbCBpbnRlcnBvbGF0aW9uIGh0dHBzOi8vb2JzZXJ2YWJsZWhxLmNvbS9AbW91cm5lci9hcHByb3hpbWF0aW5nLWdlb21ldHJpYy1zbGVycFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHQyID0gdCAtIDAuNTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBID0gMS4wOTA0ICsgY29zQW5nbGUgKiAoLTMuMjQ1MiArIGNvc0FuZ2xlICogKDMuNTU2NDUgLSBjb3NBbmdsZSAqIDEuNDM1MTkpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBCID0gMC44NDgwMTMgKyBjb3NBbmdsZSAqICgtMS4wNjAyMSArIGNvc0FuZ2xlICogMC4yMTU2MzgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQgPSB0ICsgdCAqIHQyICogKHQgLSAxKSAqIChBICogdDIgKiB0MiArIEIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXh0cnVkZSA9IG5leHROb3JtYWwuc3ViKHByZXZOb3JtYWwpLl9tdWx0KHQpLl9hZGQocHJldk5vcm1hbCkuX3VuaXQoKS5fbXVsdChsaW5lVHVybnNMZWZ0ID8gLTEgOiAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYWRkSGFsZlZlcnRleChjdXJyZW50VmVydGV4LCBleHRydWRlLngsIGV4dHJ1ZGUueSwgZmFsc2UsIGxpbmVUdXJuc0xlZnQsIDAsIHNlZ21lbnQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKG5leHRWZXJ0ZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU3RhcnQgbmV4dCBzZWdtZW50XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWRkQ3VycmVudFZlcnRleChjdXJyZW50VmVydGV4LCBuZXh0Tm9ybWFsLCAtb2Zmc2V0QSwgLW9mZnNldEIsIHNlZ21lbnQpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgfSBlbHNlIGlmIChjdXJyZW50Sm9pbiA9PT0gJ2J1dHQnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRDdXJyZW50VmVydGV4KGN1cnJlbnRWZXJ0ZXgsIGpvaW5Ob3JtYWwsIDAsIDAsIHNlZ21lbnQpOyAvLyBidXR0IGNhcFxuXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGN1cnJlbnRKb2luID09PSAnc3F1YXJlJykge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9mZnNldCA9IHByZXZWZXJ0ZXggPyAxIDogLTE7IC8vIGNsb3Npbmcgb3Igc3RhcnRpbmcgc3F1YXJlIGNhcFxuXG4gICAgICAgICAgICAgICAgaWYgKCFwcmV2VmVydGV4KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWRkQ3VycmVudFZlcnRleChjdXJyZW50VmVydGV4LCBqb2luTm9ybWFsLCBvZmZzZXQsIG9mZnNldCwgc2VnbWVudCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gbWFrZSB0aGUgY2FwIGl0J3Mgb3duIHF1YWQgdG8gYXZvaWQgdGhlIGNhcCBhZmZlY3RpbmcgdGhlIGxpbmUgZGlzdGFuY2VcbiAgICAgICAgICAgICAgICB0aGlzLmFkZEN1cnJlbnRWZXJ0ZXgoY3VycmVudFZlcnRleCwgam9pbk5vcm1hbCwgMCwgMCwgc2VnbWVudCk7XG5cbiAgICAgICAgICAgICAgICBpZiAocHJldlZlcnRleCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZEN1cnJlbnRWZXJ0ZXgoY3VycmVudFZlcnRleCwgam9pbk5vcm1hbCwgb2Zmc2V0LCBvZmZzZXQsIHNlZ21lbnQpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgfSBlbHNlIGlmIChjdXJyZW50Sm9pbiA9PT0gJ3JvdW5kJykge1xuXG4gICAgICAgICAgICAgICAgaWYgKHByZXZWZXJ0ZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQ2xvc2UgcHJldmlvdXMgc2VnbWVudCB3aXRoIGJ1dHRcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGRDdXJyZW50VmVydGV4KGN1cnJlbnRWZXJ0ZXgsIHByZXZOb3JtYWwsIDAsIDAsIHNlZ21lbnQpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIEFkZCByb3VuZCBjYXAgb3IgbGluZWpvaW4gYXQgZW5kIG9mIHNlZ21lbnRcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGRDdXJyZW50VmVydGV4KGN1cnJlbnRWZXJ0ZXgsIHByZXZOb3JtYWwsIDEsIDEsIHNlZ21lbnQsIHRydWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAobmV4dFZlcnRleCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBBZGQgcm91bmQgY2FwIGJlZm9yZSBmaXJzdCBzZWdtZW50XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWRkQ3VycmVudFZlcnRleChjdXJyZW50VmVydGV4LCBuZXh0Tm9ybWFsLCAtMSwgLTEsIHNlZ21lbnQsIHRydWUpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIFN0YXJ0IG5leHQgc2VnbWVudCB3aXRoIGEgYnV0dFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZEN1cnJlbnRWZXJ0ZXgoY3VycmVudFZlcnRleCwgbmV4dE5vcm1hbCwgMCwgMCwgc2VnbWVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoaXNTaGFycENvcm5lciAmJiBpIDwgbGVuIC0gMSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5leHRTZWdtZW50TGVuZ3RoID0gY3VycmVudFZlcnRleC5kaXN0KG5leHRWZXJ0ZXgpO1xuICAgICAgICAgICAgICAgIGlmIChuZXh0U2VnbWVudExlbmd0aCA+IDIgKiBzaGFycENvcm5lck9mZnNldCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdDdXJyZW50VmVydGV4ID0gY3VycmVudFZlcnRleC5hZGQobmV4dFZlcnRleC5zdWIoY3VycmVudFZlcnRleCkuX211bHQoc2hhcnBDb3JuZXJPZmZzZXQgLyBuZXh0U2VnbWVudExlbmd0aCkuX3JvdW5kKCkpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZURpc3RhbmNlKGN1cnJlbnRWZXJ0ZXgsIG5ld0N1cnJlbnRWZXJ0ZXgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZEN1cnJlbnRWZXJ0ZXgobmV3Q3VycmVudFZlcnRleCwgbmV4dE5vcm1hbCwgMCwgMCwgc2VnbWVudCk7XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRWZXJ0ZXggPSBuZXdDdXJyZW50VmVydGV4O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZCB0d28gdmVydGljZXMgdG8gdGhlIGJ1ZmZlcnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gcCB0aGUgbGluZSB2ZXJ0ZXggdG8gYWRkIGJ1ZmZlciB2ZXJ0aWNlcyBmb3JcbiAgICAgKiBAcGFyYW0gbm9ybWFsIHZlcnRleCBub3JtYWxcbiAgICAgKiBAcGFyYW0gZW5kTGVmdCBleHRydWRlIHRvIHNoaWZ0IHRoZSBsZWZ0IHZlcnRleCBhbG9uZyB0aGUgbGluZVxuICAgICAqIEBwYXJhbSBlbmRSaWdodCBleHRydWRlIHRvIHNoaWZ0IHRoZSBsZWZ0IHZlcnRleCBhbG9uZyB0aGUgbGluZVxuICAgICAqIEBwYXJhbSBzZWdtZW50IHRoZSBzZWdtZW50IG9iamVjdCB0byBhZGQgdGhlIHZlcnRleCB0b1xuICAgICAqIEBwYXJhbSByb3VuZCB3aGV0aGVyIHRoaXMgaXMgYSByb3VuZCBjYXBcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIGFkZEN1cnJlbnRWZXJ0ZXgocDogUG9pbnQsIG5vcm1hbDogUG9pbnQsIGVuZExlZnQ6IG51bWJlciwgZW5kUmlnaHQ6IG51bWJlciwgc2VnbWVudDogU2VnbWVudCwgcm91bmQ6IGJvb2xlYW4gPSBmYWxzZSkge1xuICAgICAgICAvLyBsZWZ0IGFuZCByaWdodCBleHRydWRlIHZlY3RvcnMsIHBlcnBlbmRpY3VsYXJseSBzaGlmdGVkIGJ5IGVuZExlZnQvZW5kUmlnaHRcbiAgICAgICAgY29uc3QgbGVmdFggPSBub3JtYWwueCArIG5vcm1hbC55ICogZW5kTGVmdDtcbiAgICAgICAgY29uc3QgbGVmdFkgPSBub3JtYWwueSAtIG5vcm1hbC54ICogZW5kTGVmdDtcbiAgICAgICAgY29uc3QgcmlnaHRYID0gLW5vcm1hbC54ICsgbm9ybWFsLnkgKiBlbmRSaWdodDtcbiAgICAgICAgY29uc3QgcmlnaHRZID0gLW5vcm1hbC55IC0gbm9ybWFsLnggKiBlbmRSaWdodDtcblxuICAgICAgICB0aGlzLmFkZEhhbGZWZXJ0ZXgocCwgbGVmdFgsIGxlZnRZLCByb3VuZCwgZmFsc2UsIGVuZExlZnQsIHNlZ21lbnQpO1xuICAgICAgICB0aGlzLmFkZEhhbGZWZXJ0ZXgocCwgcmlnaHRYLCByaWdodFksIHJvdW5kLCB0cnVlLCAtZW5kUmlnaHQsIHNlZ21lbnQpO1xuICAgIH1cblxuICAgIGFkZEhhbGZWZXJ0ZXgoe3gsIHl9OiBQb2ludCwgZXh0cnVkZVg6IG51bWJlciwgZXh0cnVkZVk6IG51bWJlciwgcm91bmQ6IGJvb2xlYW4sIHVwOiBib29sZWFuLCBkaXI6IG51bWJlciwgc2VnbWVudDogU2VnbWVudCkge1xuICAgICAgICB0aGlzLmxheW91dFZlcnRleEFycmF5LmVtcGxhY2VCYWNrKFxuICAgICAgICAgICAgLy8gYV9wb3Nfbm9ybWFsXG4gICAgICAgICAgICAvLyBFbmNvZGUgcm91bmQvdXAgdGhlIGxlYXN0IHNpZ25pZmljYW50IGJpdHNcbiAgICAgICAgICAgICh4IDw8IDEpICsgKHJvdW5kID8gMSA6IDApLFxuICAgICAgICAgICAgKHkgPDwgMSkgKyAodXAgPyAxIDogMCksXG4gICAgICAgICAgICAvLyBhX2RhdGFcbiAgICAgICAgICAgIC8vIGFkZCAxMjggdG8gc3RvcmUgYSBieXRlIGluIGFuIHVuc2lnbmVkIGJ5dGVcbiAgICAgICAgICAgIE1hdGgucm91bmQoRVhUUlVERV9TQ0FMRSAqIGV4dHJ1ZGVYKSArIDEyOCxcbiAgICAgICAgICAgIE1hdGgucm91bmQoRVhUUlVERV9TQ0FMRSAqIGV4dHJ1ZGVZKSArIDEyOCxcbiAgICAgICAgICAgICgoZGlyID09PSAwID8gMCA6IChkaXIgPCAwID8gLTEgOiAxKSkgKyAxKSxcbiAgICAgICAgICAgIDAsIC8vIHVudXNlZFxuICAgICAgICAgICAgLy8gYV9saW5lc29mYXJcbiAgICAgICAgICAgIHRoaXMubGluZVNvRmFyKTtcblxuICAgICAgICAvLyBDb25zdHJ1Y3RzIGEgc2Vjb25kIHZlcnRleCBidWZmZXIgd2l0aCBoaWdoZXIgcHJlY2lzaW9uIGxpbmUgcHJvZ3Jlc3NcbiAgICAgICAgaWYgKHRoaXMubGluZUNsaXBzKSB7XG4gICAgICAgICAgICB0aGlzLmxheW91dFZlcnRleEFycmF5Mi5lbXBsYWNlQmFjayh0aGlzLnNjYWxlZERpc3RhbmNlLCB0aGlzLmxpbmVDbGlwc0FycmF5Lmxlbmd0aCwgdGhpcy5saW5lQ2xpcHMuc3RhcnQsIHRoaXMubGluZUNsaXBzLmVuZCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBlID0gc2VnbWVudC52ZXJ0ZXhMZW5ndGgrKztcbiAgICAgICAgaWYgKHRoaXMuZTEgPj0gMCAmJiB0aGlzLmUyID49IDApIHtcbiAgICAgICAgICAgIHRoaXMuaW5kZXhBcnJheS5lbXBsYWNlQmFjayh0aGlzLmUxLCB0aGlzLmUyLCBlKTtcbiAgICAgICAgICAgIHNlZ21lbnQucHJpbWl0aXZlTGVuZ3RoKys7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHVwKSB7XG4gICAgICAgICAgICB0aGlzLmUyID0gZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZTEgPSBlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdXBkYXRlU2NhbGVkRGlzdGFuY2UoKSB7XG4gICAgICAgIC8vIEtub3dpbmcgdGhlIHJhdGlvIG9mIHRoZSBmdWxsIGxpbmVzdHJpbmcgY292ZXJlZCBieSB0aGlzIHRpbGVkIGZlYXR1cmUsIGFzIHdlbGxcbiAgICAgICAgLy8gYXMgdGhlIHRvdGFsIGRpc3RhbmNlIChpbiB0aWxlIHVuaXRzKSBvZiB0aGlzIHRpbGVkIGZlYXR1cmUsIGFuZCB0aGUgZGlzdGFuY2VcbiAgICAgICAgLy8gKGluIHRpbGUgdW5pdHMpIG9mIHRoZSBjdXJyZW50IHZlcnRleCwgd2UgY2FuIGRldGVybWluZSB0aGUgcmVsYXRpdmUgZGlzdGFuY2VcbiAgICAgICAgLy8gb2YgdGhpcyB2ZXJ0ZXggYWxvbmcgdGhlIGZ1bGwgbGluZXN0cmluZyBmZWF0dXJlLlxuICAgICAgICBpZiAodGhpcy5saW5lQ2xpcHMpIHtcbiAgICAgICAgICAgIGNvbnN0IGZlYXR1cmVTaGFyZSA9IHRoaXMubGluZUNsaXBzLmVuZCAtIHRoaXMubGluZUNsaXBzLnN0YXJ0O1xuICAgICAgICAgICAgY29uc3QgdG90YWxGZWF0dXJlTGVuZ3RoID0gdGhpcy50b3RhbERpc3RhbmNlIC8gZmVhdHVyZVNoYXJlO1xuICAgICAgICAgICAgdGhpcy5zY2FsZWREaXN0YW5jZSA9IHRoaXMuZGlzdGFuY2UgLyB0aGlzLnRvdGFsRGlzdGFuY2U7XG4gICAgICAgICAgICB0aGlzLmxpbmVTb0ZhciA9IHRvdGFsRmVhdHVyZUxlbmd0aCAqIHRoaXMubGluZUNsaXBzLnN0YXJ0ICsgdGhpcy5kaXN0YW5jZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubGluZVNvRmFyID0gdGhpcy5kaXN0YW5jZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHVwZGF0ZURpc3RhbmNlKHByZXY6IFBvaW50LCBuZXh0OiBQb2ludCkge1xuICAgICAgICB0aGlzLmRpc3RhbmNlICs9IHByZXYuZGlzdChuZXh0KTtcbiAgICAgICAgdGhpcy51cGRhdGVTY2FsZWREaXN0YW5jZSgpO1xuICAgIH1cbn1cblxucmVnaXN0ZXIoTGluZUJ1Y2tldCwgJ0xpbmVCdWNrZXQnLCB7b21pdDogWydsYXllcnMnLCAncGF0dGVybkZlYXR1cmVzJ119KTtcblxuZXhwb3J0IGRlZmF1bHQgTGluZUJ1Y2tldDtcbiIsIi8vIFRoaXMgZmlsZSBpcyBnZW5lcmF0ZWQuIEVkaXQgYnVpbGQvZ2VuZXJhdGUtc3R5bGUtY29kZS5qcywgdGhlbiBydW4gYHlhcm4gcnVuIGNvZGVnZW5gLlxuLy8gQGZsb3dcbi8qIGVzbGludC1kaXNhYmxlICovXG5cbmltcG9ydCBzdHlsZVNwZWMgZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy9yZWZlcmVuY2UvbGF0ZXN0LmpzJztcblxuaW1wb3J0IHtcbiAgICBQcm9wZXJ0aWVzLFxuICAgIERhdGFDb25zdGFudFByb3BlcnR5LFxuICAgIERhdGFEcml2ZW5Qcm9wZXJ0eSxcbiAgICBDb2xvclJhbXBQcm9wZXJ0eVxufSBmcm9tICcuLi9wcm9wZXJ0aWVzLmpzJztcblxuaW1wb3J0IHR5cGUgQ29sb3IgZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy91dGlsL2NvbG9yLmpzJztcblxuaW1wb3J0IHR5cGUgRm9ybWF0dGVkIGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi90eXBlcy9mb3JtYXR0ZWQuanMnO1xuXG5pbXBvcnQgdHlwZSBSZXNvbHZlZEltYWdlIGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi90eXBlcy9yZXNvbHZlZF9pbWFnZS5qcyc7XG5cbmV4cG9ydCB0eXBlIExheW91dFByb3BzID0ge3xcbiAgICBcImxpbmUtY2FwXCI6IERhdGFEcml2ZW5Qcm9wZXJ0eTxcImJ1dHRcIiB8IFwicm91bmRcIiB8IFwic3F1YXJlXCI+LFxuICAgIFwibGluZS1qb2luXCI6IERhdGFEcml2ZW5Qcm9wZXJ0eTxcImJldmVsXCIgfCBcInJvdW5kXCIgfCBcIm1pdGVyXCI+LFxuICAgIFwibGluZS1taXRlci1saW1pdFwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxudW1iZXI+LFxuICAgIFwibGluZS1yb3VuZC1saW1pdFwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxudW1iZXI+LFxuICAgIFwibGluZS1zb3J0LWtleVwiOiBEYXRhRHJpdmVuUHJvcGVydHk8bnVtYmVyPixcbnx9O1xuXG5jb25zdCBsYXlvdXQ6IFByb3BlcnRpZXM8TGF5b3V0UHJvcHM+ID0gbmV3IFByb3BlcnRpZXMoe1xuICAgIFwibGluZS1jYXBcIjogbmV3IERhdGFEcml2ZW5Qcm9wZXJ0eShzdHlsZVNwZWNbXCJsYXlvdXRfbGluZVwiXVtcImxpbmUtY2FwXCJdKSxcbiAgICBcImxpbmUtam9pblwiOiBuZXcgRGF0YURyaXZlblByb3BlcnR5KHN0eWxlU3BlY1tcImxheW91dF9saW5lXCJdW1wibGluZS1qb2luXCJdKSxcbiAgICBcImxpbmUtbWl0ZXItbGltaXRcIjogbmV3IERhdGFDb25zdGFudFByb3BlcnR5KHN0eWxlU3BlY1tcImxheW91dF9saW5lXCJdW1wibGluZS1taXRlci1saW1pdFwiXSksXG4gICAgXCJsaW5lLXJvdW5kLWxpbWl0XCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJsYXlvdXRfbGluZVwiXVtcImxpbmUtcm91bmQtbGltaXRcIl0pLFxuICAgIFwibGluZS1zb3J0LWtleVwiOiBuZXcgRGF0YURyaXZlblByb3BlcnR5KHN0eWxlU3BlY1tcImxheW91dF9saW5lXCJdW1wibGluZS1zb3J0LWtleVwiXSksXG59KTtcblxuZXhwb3J0IHR5cGUgUGFpbnRQcm9wcyA9IHt8XG4gICAgXCJsaW5lLW9wYWNpdHlcIjogRGF0YURyaXZlblByb3BlcnR5PG51bWJlcj4sXG4gICAgXCJsaW5lLWNvbG9yXCI6IERhdGFEcml2ZW5Qcm9wZXJ0eTxDb2xvcj4sXG4gICAgXCJsaW5lLXRyYW5zbGF0ZVwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxbbnVtYmVyLCBudW1iZXJdPixcbiAgICBcImxpbmUtdHJhbnNsYXRlLWFuY2hvclwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxcIm1hcFwiIHwgXCJ2aWV3cG9ydFwiPixcbiAgICBcImxpbmUtd2lkdGhcIjogRGF0YURyaXZlblByb3BlcnR5PG51bWJlcj4sXG4gICAgXCJsaW5lLWdhcC13aWR0aFwiOiBEYXRhRHJpdmVuUHJvcGVydHk8bnVtYmVyPixcbiAgICBcImxpbmUtb2Zmc2V0XCI6IERhdGFEcml2ZW5Qcm9wZXJ0eTxudW1iZXI+LFxuICAgIFwibGluZS1ibHVyXCI6IERhdGFEcml2ZW5Qcm9wZXJ0eTxudW1iZXI+LFxuICAgIFwibGluZS1kYXNoYXJyYXlcIjogRGF0YURyaXZlblByb3BlcnR5PD9BcnJheTxudW1iZXI+PixcbiAgICBcImxpbmUtcGF0dGVyblwiOiBEYXRhRHJpdmVuUHJvcGVydHk8P1Jlc29sdmVkSW1hZ2U+LFxuICAgIFwibGluZS1ncmFkaWVudFwiOiBDb2xvclJhbXBQcm9wZXJ0eSxcbiAgICBcImxpbmUtdHJpbS1vZmZzZXRcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8W251bWJlciwgbnVtYmVyXT4sXG58fTtcblxuY29uc3QgcGFpbnQ6IFByb3BlcnRpZXM8UGFpbnRQcm9wcz4gPSBuZXcgUHJvcGVydGllcyh7XG4gICAgXCJsaW5lLW9wYWNpdHlcIjogbmV3IERhdGFEcml2ZW5Qcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9saW5lXCJdW1wibGluZS1vcGFjaXR5XCJdKSxcbiAgICBcImxpbmUtY29sb3JcIjogbmV3IERhdGFEcml2ZW5Qcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9saW5lXCJdW1wibGluZS1jb2xvclwiXSksXG4gICAgXCJsaW5lLXRyYW5zbGF0ZVwiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjW1wicGFpbnRfbGluZVwiXVtcImxpbmUtdHJhbnNsYXRlXCJdKSxcbiAgICBcImxpbmUtdHJhbnNsYXRlLWFuY2hvclwiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjW1wicGFpbnRfbGluZVwiXVtcImxpbmUtdHJhbnNsYXRlLWFuY2hvclwiXSksXG4gICAgXCJsaW5lLXdpZHRoXCI6IG5ldyBEYXRhRHJpdmVuUHJvcGVydHkoc3R5bGVTcGVjW1wicGFpbnRfbGluZVwiXVtcImxpbmUtd2lkdGhcIl0pLFxuICAgIFwibGluZS1nYXAtd2lkdGhcIjogbmV3IERhdGFEcml2ZW5Qcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9saW5lXCJdW1wibGluZS1nYXAtd2lkdGhcIl0pLFxuICAgIFwibGluZS1vZmZzZXRcIjogbmV3IERhdGFEcml2ZW5Qcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9saW5lXCJdW1wibGluZS1vZmZzZXRcIl0pLFxuICAgIFwibGluZS1ibHVyXCI6IG5ldyBEYXRhRHJpdmVuUHJvcGVydHkoc3R5bGVTcGVjW1wicGFpbnRfbGluZVwiXVtcImxpbmUtYmx1clwiXSksXG4gICAgXCJsaW5lLWRhc2hhcnJheVwiOiBuZXcgRGF0YURyaXZlblByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X2xpbmVcIl1bXCJsaW5lLWRhc2hhcnJheVwiXSksXG4gICAgXCJsaW5lLXBhdHRlcm5cIjogbmV3IERhdGFEcml2ZW5Qcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9saW5lXCJdW1wibGluZS1wYXR0ZXJuXCJdKSxcbiAgICBcImxpbmUtZ3JhZGllbnRcIjogbmV3IENvbG9yUmFtcFByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X2xpbmVcIl1bXCJsaW5lLWdyYWRpZW50XCJdKSxcbiAgICBcImxpbmUtdHJpbS1vZmZzZXRcIjogbmV3IERhdGFDb25zdGFudFByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X2xpbmVcIl1bXCJsaW5lLXRyaW0tb2Zmc2V0XCJdKSxcbn0pO1xuXG4vLyBOb3RlOiB3aXRob3V0IGFkZGluZyB0aGUgZXhwbGljaXQgdHlwZSBhbm5vdGF0aW9uLCBGbG93IGluZmVycyB3ZWFrZXIgdHlwZXNcbi8vIGZvciB0aGVzZSBvYmplY3RzIGZyb20gdGhlaXIgdXNlIGluIHRoZSBjb25zdHJ1Y3RvciB0byBTdHlsZUxheWVyLCBhc1xuLy8ge2xheW91dD86IFByb3BlcnRpZXM8Li4uPiwgcGFpbnQ6IFByb3BlcnRpZXM8Li4uPn1cbmV4cG9ydCBkZWZhdWx0ICh7IHBhaW50LCBsYXlvdXQgfTogJEV4YWN0PHtcbiAgcGFpbnQ6IFByb3BlcnRpZXM8UGFpbnRQcm9wcz4sIGxheW91dDogUHJvcGVydGllczxMYXlvdXRQcm9wcz5cbn0+KTtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcblxuaW1wb3J0IFN0eWxlTGF5ZXIgZnJvbSAnLi4vc3R5bGVfbGF5ZXIuanMnO1xuaW1wb3J0IExpbmVCdWNrZXQgZnJvbSAnLi4vLi4vZGF0YS9idWNrZXQvbGluZV9idWNrZXQuanMnO1xuaW1wb3J0IHtwb2x5Z29uSW50ZXJzZWN0c0J1ZmZlcmVkTXVsdGlMaW5lfSBmcm9tICcuLi8uLi91dGlsL2ludGVyc2VjdGlvbl90ZXN0cy5qcyc7XG5pbXBvcnQge2dldE1heGltdW1QYWludFZhbHVlLCB0cmFuc2xhdGVEaXN0YW5jZSwgdHJhbnNsYXRlfSBmcm9tICcuLi9xdWVyeV91dGlscy5qcyc7XG5pbXBvcnQgcHJvcGVydGllcyBmcm9tICcuL2xpbmVfc3R5bGVfbGF5ZXJfcHJvcGVydGllcy5qcyc7XG5pbXBvcnQge2V4dGVuZH0gZnJvbSAnLi4vLi4vdXRpbC91dGlsLmpzJztcbmltcG9ydCBFdmFsdWF0aW9uUGFyYW1ldGVycyBmcm9tICcuLi9ldmFsdWF0aW9uX3BhcmFtZXRlcnMuanMnO1xuaW1wb3J0IHtUcmFuc2l0aW9uYWJsZSwgVHJhbnNpdGlvbmluZywgTGF5b3V0LCBQb3NzaWJseUV2YWx1YXRlZCwgRGF0YURyaXZlblByb3BlcnR5fSBmcm9tICcuLi9wcm9wZXJ0aWVzLmpzJztcbmltcG9ydCBQcm9ncmFtQ29uZmlndXJhdGlvbiBmcm9tICcuLi8uLi9kYXRhL3Byb2dyYW1fY29uZmlndXJhdGlvbi5qcyc7XG5cbmltcG9ydCBTdGVwIGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi9kZWZpbml0aW9ucy9zdGVwLmpzJztcbmltcG9ydCB0eXBlIHtQb3NzaWJseUV2YWx1YXRlZFZhbHVlLCBQcm9wZXJ0eVZhbHVlLCBQb3NzaWJseUV2YWx1YXRlZFByb3BlcnR5VmFsdWV9IGZyb20gJy4uL3Byb3BlcnRpZXMuanMnO1xuaW1wb3J0IHR5cGUge0ZlYXR1cmUsIEZlYXR1cmVTdGF0ZSwgWm9vbUNvbnN0YW50RXhwcmVzc2lvbiwgU3R5bGVQcm9wZXJ0eUV4cHJlc3Npb259IGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi9pbmRleC5qcyc7XG5pbXBvcnQgdHlwZSB7QnVja2V0LCBCdWNrZXRQYXJhbWV0ZXJzfSBmcm9tICcuLi8uLi9kYXRhL2J1Y2tldC5qcyc7XG5pbXBvcnQgdHlwZSB7TGF5b3V0UHJvcHMsIFBhaW50UHJvcHN9IGZyb20gJy4vbGluZV9zdHlsZV9sYXllcl9wcm9wZXJ0aWVzLmpzJztcbmltcG9ydCB0eXBlIFRyYW5zZm9ybSBmcm9tICcuLi8uLi9nZW8vdHJhbnNmb3JtLmpzJztcbmltcG9ydCB0eXBlIHtMYXllclNwZWNpZmljYXRpb259IGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge1RpbGVzcGFjZVF1ZXJ5R2VvbWV0cnl9IGZyb20gJy4uL3F1ZXJ5X2dlb21ldHJ5LmpzJztcbmltcG9ydCB0eXBlIHtJVmVjdG9yVGlsZUZlYXR1cmV9IGZyb20gJ0BtYXBib3gvdmVjdG9yLXRpbGUnO1xuXG5jbGFzcyBMaW5lRmxvb3J3aWR0aFByb3BlcnR5IGV4dGVuZHMgRGF0YURyaXZlblByb3BlcnR5PG51bWJlcj4ge1xuICAgIHVzZUludGVnZXJab29tOiA/Ym9vbGVhbjtcblxuICAgIHBvc3NpYmx5RXZhbHVhdGUodmFsdWU6IFByb3BlcnR5VmFsdWU8bnVtYmVyLCBQb3NzaWJseUV2YWx1YXRlZFByb3BlcnR5VmFsdWU8bnVtYmVyPj4sIHBhcmFtZXRlcnM6IEV2YWx1YXRpb25QYXJhbWV0ZXJzKTogUG9zc2libHlFdmFsdWF0ZWRQcm9wZXJ0eVZhbHVlPG51bWJlcj4ge1xuICAgICAgICBwYXJhbWV0ZXJzID0gbmV3IEV2YWx1YXRpb25QYXJhbWV0ZXJzKE1hdGguZmxvb3IocGFyYW1ldGVycy56b29tKSwge1xuICAgICAgICAgICAgbm93OiBwYXJhbWV0ZXJzLm5vdyxcbiAgICAgICAgICAgIGZhZGVEdXJhdGlvbjogcGFyYW1ldGVycy5mYWRlRHVyYXRpb24sXG4gICAgICAgICAgICB0cmFuc2l0aW9uOiBwYXJhbWV0ZXJzLnRyYW5zaXRpb25cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBzdXBlci5wb3NzaWJseUV2YWx1YXRlKHZhbHVlLCBwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICBldmFsdWF0ZSh2YWx1ZTogUG9zc2libHlFdmFsdWF0ZWRWYWx1ZTxudW1iZXI+LCBnbG9iYWxzOiBFdmFsdWF0aW9uUGFyYW1ldGVycywgZmVhdHVyZTogRmVhdHVyZSwgZmVhdHVyZVN0YXRlOiBGZWF0dXJlU3RhdGUpOiBudW1iZXIge1xuICAgICAgICBnbG9iYWxzID0gZXh0ZW5kKHt9LCBnbG9iYWxzLCB7em9vbTogTWF0aC5mbG9vcihnbG9iYWxzLnpvb20pfSk7XG4gICAgICAgIHJldHVybiBzdXBlci5ldmFsdWF0ZSh2YWx1ZSwgZ2xvYmFscywgZmVhdHVyZSwgZmVhdHVyZVN0YXRlKTtcbiAgICB9XG59XG5cbmNvbnN0IGxpbmVGbG9vcndpZHRoUHJvcGVydHkgPSBuZXcgTGluZUZsb29yd2lkdGhQcm9wZXJ0eShwcm9wZXJ0aWVzLnBhaW50LnByb3BlcnRpZXNbJ2xpbmUtd2lkdGgnXS5zcGVjaWZpY2F0aW9uKTtcbmxpbmVGbG9vcndpZHRoUHJvcGVydHkudXNlSW50ZWdlclpvb20gPSB0cnVlO1xuXG5jbGFzcyBMaW5lU3R5bGVMYXllciBleHRlbmRzIFN0eWxlTGF5ZXIge1xuICAgIF91bmV2YWx1YXRlZExheW91dDogTGF5b3V0PExheW91dFByb3BzPjtcbiAgICBsYXlvdXQ6IFBvc3NpYmx5RXZhbHVhdGVkPExheW91dFByb3BzPjtcblxuICAgIGdyYWRpZW50VmVyc2lvbjogbnVtYmVyO1xuICAgIHN0ZXBJbnRlcnBvbGFudDogYm9vbGVhbjtcblxuICAgIF90cmFuc2l0aW9uYWJsZVBhaW50OiBUcmFuc2l0aW9uYWJsZTxQYWludFByb3BzPjtcbiAgICBfdHJhbnNpdGlvbmluZ1BhaW50OiBUcmFuc2l0aW9uaW5nPFBhaW50UHJvcHM+O1xuICAgIHBhaW50OiBQb3NzaWJseUV2YWx1YXRlZDxQYWludFByb3BzPjtcblxuICAgIGNvbnN0cnVjdG9yKGxheWVyOiBMYXllclNwZWNpZmljYXRpb24pIHtcbiAgICAgICAgc3VwZXIobGF5ZXIsIHByb3BlcnRpZXMpO1xuICAgICAgICB0aGlzLmdyYWRpZW50VmVyc2lvbiA9IDA7XG4gICAgfVxuXG4gICAgX2hhbmRsZVNwZWNpYWxQYWludFByb3BlcnR5VXBkYXRlKG5hbWU6IHN0cmluZykge1xuICAgICAgICBpZiAobmFtZSA9PT0gJ2xpbmUtZ3JhZGllbnQnKSB7XG4gICAgICAgICAgICBjb25zdCBleHByZXNzaW9uOiBab29tQ29uc3RhbnRFeHByZXNzaW9uPCdzb3VyY2UnPiA9ICgodGhpcy5fdHJhbnNpdGlvbmFibGVQYWludC5fdmFsdWVzWydsaW5lLWdyYWRpZW50J10udmFsdWUuZXhwcmVzc2lvbik6IGFueSk7XG4gICAgICAgICAgICB0aGlzLnN0ZXBJbnRlcnBvbGFudCA9IGV4cHJlc3Npb24uX3N0eWxlRXhwcmVzc2lvbiAmJiBleHByZXNzaW9uLl9zdHlsZUV4cHJlc3Npb24uZXhwcmVzc2lvbiBpbnN0YW5jZW9mIFN0ZXA7XG4gICAgICAgICAgICB0aGlzLmdyYWRpZW50VmVyc2lvbiA9ICh0aGlzLmdyYWRpZW50VmVyc2lvbiArIDEpICUgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBncmFkaWVudEV4cHJlc3Npb24oKTogU3R5bGVQcm9wZXJ0eUV4cHJlc3Npb24ge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHJhbnNpdGlvbmFibGVQYWludC5fdmFsdWVzWydsaW5lLWdyYWRpZW50J10udmFsdWUuZXhwcmVzc2lvbjtcbiAgICB9XG5cbiAgICB3aWR0aEV4cHJlc3Npb24oKTogU3R5bGVQcm9wZXJ0eUV4cHJlc3Npb24ge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHJhbnNpdGlvbmFibGVQYWludC5fdmFsdWVzWydsaW5lLXdpZHRoJ10udmFsdWUuZXhwcmVzc2lvbjtcbiAgICB9XG5cbiAgICByZWNhbGN1bGF0ZShwYXJhbWV0ZXJzOiBFdmFsdWF0aW9uUGFyYW1ldGVycywgYXZhaWxhYmxlSW1hZ2VzOiBBcnJheTxzdHJpbmc+KSB7XG4gICAgICAgIHN1cGVyLnJlY2FsY3VsYXRlKHBhcmFtZXRlcnMsIGF2YWlsYWJsZUltYWdlcyk7XG5cbiAgICAgICAgKHRoaXMucGFpbnQuX3ZhbHVlczogYW55KVsnbGluZS1mbG9vcndpZHRoJ10gPVxuICAgICAgICAgICAgbGluZUZsb29yd2lkdGhQcm9wZXJ0eS5wb3NzaWJseUV2YWx1YXRlKHRoaXMuX3RyYW5zaXRpb25pbmdQYWludC5fdmFsdWVzWydsaW5lLXdpZHRoJ10udmFsdWUsIHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIGNyZWF0ZUJ1Y2tldChwYXJhbWV0ZXJzOiBCdWNrZXRQYXJhbWV0ZXJzPExpbmVTdHlsZUxheWVyPik6IExpbmVCdWNrZXQge1xuICAgICAgICByZXR1cm4gbmV3IExpbmVCdWNrZXQocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgZ2V0UHJvZ3JhbUlkcygpOiBzdHJpbmdbXSB7XG4gICAgICAgIGNvbnN0IHBhdHRlcm5Qcm9wZXJ0eSA9IHRoaXMucGFpbnQuZ2V0KCdsaW5lLXBhdHRlcm4nKTtcbiAgICAgICAgY29uc3QgaW1hZ2UgPSBwYXR0ZXJuUHJvcGVydHkuY29uc3RhbnRPcigoMTogYW55KSk7XG4gICAgICAgIGNvbnN0IHByb2dyYW1JZCA9IGltYWdlID8gJ2xpbmVQYXR0ZXJuJyA6ICdsaW5lJztcbiAgICAgICAgcmV0dXJuIFtwcm9ncmFtSWRdO1xuICAgIH1cblxuICAgIGdldFByb2dyYW1Db25maWd1cmF0aW9uKHpvb206IG51bWJlcik6IFByb2dyYW1Db25maWd1cmF0aW9uIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9ncmFtQ29uZmlndXJhdGlvbih0aGlzLCB6b29tKTtcbiAgICB9XG5cbiAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgcXVlcnlSYWRpdXMoYnVja2V0OiBCdWNrZXQpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBsaW5lQnVja2V0OiBMaW5lQnVja2V0ID0gKGJ1Y2tldDogYW55KTtcbiAgICAgICAgY29uc3Qgd2lkdGggPSBnZXRMaW5lV2lkdGgoXG4gICAgICAgICAgICBnZXRNYXhpbXVtUGFpbnRWYWx1ZSgnbGluZS13aWR0aCcsIHRoaXMsIGxpbmVCdWNrZXQpLFxuICAgICAgICAgICAgZ2V0TWF4aW11bVBhaW50VmFsdWUoJ2xpbmUtZ2FwLXdpZHRoJywgdGhpcywgbGluZUJ1Y2tldCkpO1xuICAgICAgICBjb25zdCBvZmZzZXQgPSBnZXRNYXhpbXVtUGFpbnRWYWx1ZSgnbGluZS1vZmZzZXQnLCB0aGlzLCBsaW5lQnVja2V0KTtcbiAgICAgICAgcmV0dXJuIHdpZHRoIC8gMiArIE1hdGguYWJzKG9mZnNldCkgKyB0cmFuc2xhdGVEaXN0YW5jZSh0aGlzLnBhaW50LmdldCgnbGluZS10cmFuc2xhdGUnKSk7XG4gICAgfVxuXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIHF1ZXJ5SW50ZXJzZWN0c0ZlYXR1cmUocXVlcnlHZW9tZXRyeTogVGlsZXNwYWNlUXVlcnlHZW9tZXRyeSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZlYXR1cmU6IElWZWN0b3JUaWxlRmVhdHVyZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZlYXR1cmVTdGF0ZTogRmVhdHVyZVN0YXRlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbWV0cnk6IEFycmF5PEFycmF5PFBvaW50Pj4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICB6b29tOiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm06IFRyYW5zZm9ybSk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAocXVlcnlHZW9tZXRyeS5xdWVyeUdlb21ldHJ5LmlzQWJvdmVIb3Jpem9uKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgY29uc3QgdHJhbnNsYXRlZFBvbHlnb24gPSB0cmFuc2xhdGUocXVlcnlHZW9tZXRyeS50aWxlc3BhY2VHZW9tZXRyeSxcbiAgICAgICAgICAgIHRoaXMucGFpbnQuZ2V0KCdsaW5lLXRyYW5zbGF0ZScpLFxuICAgICAgICAgICAgdGhpcy5wYWludC5nZXQoJ2xpbmUtdHJhbnNsYXRlLWFuY2hvcicpLFxuICAgICAgICAgICAgdHJhbnNmb3JtLmFuZ2xlLCBxdWVyeUdlb21ldHJ5LnBpeGVsVG9UaWxlVW5pdHNGYWN0b3IpO1xuICAgICAgICBjb25zdCBoYWxmV2lkdGggPSBxdWVyeUdlb21ldHJ5LnBpeGVsVG9UaWxlVW5pdHNGYWN0b3IgLyAyICogZ2V0TGluZVdpZHRoKFxuICAgICAgICAgICAgdGhpcy5wYWludC5nZXQoJ2xpbmUtd2lkdGgnKS5ldmFsdWF0ZShmZWF0dXJlLCBmZWF0dXJlU3RhdGUpLFxuICAgICAgICAgICAgdGhpcy5wYWludC5nZXQoJ2xpbmUtZ2FwLXdpZHRoJykuZXZhbHVhdGUoZmVhdHVyZSwgZmVhdHVyZVN0YXRlKSk7XG4gICAgICAgIGNvbnN0IGxpbmVPZmZzZXQgPSB0aGlzLnBhaW50LmdldCgnbGluZS1vZmZzZXQnKS5ldmFsdWF0ZShmZWF0dXJlLCBmZWF0dXJlU3RhdGUpO1xuICAgICAgICBpZiAobGluZU9mZnNldCkge1xuICAgICAgICAgICAgZ2VvbWV0cnkgPSBvZmZzZXRMaW5lKGdlb21ldHJ5LCBsaW5lT2Zmc2V0ICogcXVlcnlHZW9tZXRyeS5waXhlbFRvVGlsZVVuaXRzRmFjdG9yKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBwb2x5Z29uSW50ZXJzZWN0c0J1ZmZlcmVkTXVsdGlMaW5lKHRyYW5zbGF0ZWRQb2x5Z29uLCBnZW9tZXRyeSwgaGFsZldpZHRoKTtcbiAgICB9XG5cbiAgICBpc1RpbGVDbGlwcGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IExpbmVTdHlsZUxheWVyO1xuXG5mdW5jdGlvbiBnZXRMaW5lV2lkdGgobGluZVdpZHRoOiBudW1iZXIsIGxpbmVHYXBXaWR0aDogbnVtYmVyKSB7XG4gICAgaWYgKGxpbmVHYXBXaWR0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIGxpbmVHYXBXaWR0aCArIDIgKiBsaW5lV2lkdGg7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGxpbmVXaWR0aDtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIG9mZnNldExpbmUocmluZ3M6IEFycmF5PEFycmF5PFBvaW50Pj4sIG9mZnNldDogbnVtYmVyKSB7XG4gICAgY29uc3QgbmV3UmluZ3MgPSBbXTtcbiAgICBjb25zdCB6ZXJvID0gbmV3IFBvaW50KDAsIDApO1xuICAgIGZvciAobGV0IGsgPSAwOyBrIDwgcmluZ3MubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgY29uc3QgcmluZyA9IHJpbmdzW2tdO1xuICAgICAgICBjb25zdCBuZXdSaW5nID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmluZy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgYSA9IHJpbmdbaSAtIDFdO1xuICAgICAgICAgICAgY29uc3QgYiA9IHJpbmdbaV07XG4gICAgICAgICAgICBjb25zdCBjID0gcmluZ1tpICsgMV07XG4gICAgICAgICAgICBjb25zdCBhVG9CID0gaSA9PT0gMCA/IHplcm8gOiBiLnN1YihhKS5fdW5pdCgpLl9wZXJwKCk7XG4gICAgICAgICAgICBjb25zdCBiVG9DID0gaSA9PT0gcmluZy5sZW5ndGggLSAxID8gemVybyA6IGMuc3ViKGIpLl91bml0KCkuX3BlcnAoKTtcbiAgICAgICAgICAgIGNvbnN0IGV4dHJ1ZGUgPSBhVG9CLl9hZGQoYlRvQykuX3VuaXQoKTtcblxuICAgICAgICAgICAgY29uc3QgY29zSGFsZkFuZ2xlID0gZXh0cnVkZS54ICogYlRvQy54ICsgZXh0cnVkZS55ICogYlRvQy55O1xuICAgICAgICAgICAgZXh0cnVkZS5fbXVsdCgxIC8gY29zSGFsZkFuZ2xlKTtcblxuICAgICAgICAgICAgbmV3UmluZy5wdXNoKGV4dHJ1ZGUuX211bHQob2Zmc2V0KS5fYWRkKGIpKTtcbiAgICAgICAgfVxuICAgICAgICBuZXdSaW5ncy5wdXNoKG5ld1JpbmcpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3UmluZ3M7XG59XG4iLCIvLyBAZmxvd1xuaW1wb3J0IHtjcmVhdGVMYXlvdXR9IGZyb20gJy4uLy4uL3V0aWwvc3RydWN0X2FycmF5LmpzJztcblxuaW1wb3J0IHR5cGUge1N0cnVjdEFycmF5TGF5b3V0fSBmcm9tICcuLi8uLi91dGlsL3N0cnVjdF9hcnJheS5qcyc7XG5cbmV4cG9ydCBjb25zdCBzeW1ib2xMYXlvdXRBdHRyaWJ1dGVzOiBTdHJ1Y3RBcnJheUxheW91dCA9IGNyZWF0ZUxheW91dChbXG4gICAge25hbWU6ICdhX3Bvc19vZmZzZXQnLCAgIGNvbXBvbmVudHM6IDQsIHR5cGU6ICdJbnQxNid9LFxuICAgIHtuYW1lOiAnYV90ZXhfc2l6ZScsICAgICBjb21wb25lbnRzOiA0LCB0eXBlOiAnVWludDE2J30sXG4gICAge25hbWU6ICdhX3BpeGVsb2Zmc2V0JywgIGNvbXBvbmVudHM6IDQsIHR5cGU6ICdJbnQxNid9XG5dLCA0KTtcblxuZXhwb3J0IGNvbnN0IHN5bWJvbEdsb2JlRXh0QXR0cmlidXRlczogU3RydWN0QXJyYXlMYXlvdXQgPSBjcmVhdGVMYXlvdXQoW1xuICAgIHtuYW1lOiAnYV9nbG9iZV9hbmNob3InLCBjb21wb25lbnRzOiAzLCB0eXBlOiAnSW50MTYnfSxcbiAgICB7bmFtZTogJ2FfZ2xvYmVfbm9ybWFsJywgY29tcG9uZW50czogMywgdHlwZTogJ0Zsb2F0MzInfSxcbl0sIDQpO1xuXG5leHBvcnQgY29uc3QgZHluYW1pY0xheW91dEF0dHJpYnV0ZXM6IFN0cnVjdEFycmF5TGF5b3V0ID0gY3JlYXRlTGF5b3V0KFtcbiAgICB7bmFtZTogJ2FfcHJvamVjdGVkX3BvcycsIGNvbXBvbmVudHM6IDQsIHR5cGU6ICdGbG9hdDMyJ31cbl0sIDQpO1xuXG5leHBvcnQgY29uc3QgcGxhY2VtZW50T3BhY2l0eUF0dHJpYnV0ZXM6IFN0cnVjdEFycmF5TGF5b3V0ID0gY3JlYXRlTGF5b3V0KFtcbiAgICB7bmFtZTogJ2FfZmFkZV9vcGFjaXR5JywgY29tcG9uZW50czogMSwgdHlwZTogJ1VpbnQzMid9XG5dLCA0KTtcblxuZXhwb3J0IGNvbnN0IGNvbGxpc2lvblZlcnRleEF0dHJpYnV0ZXM6IFN0cnVjdEFycmF5TGF5b3V0ID0gY3JlYXRlTGF5b3V0KFtcbiAgICB7bmFtZTogJ2FfcGxhY2VkJywgY29tcG9uZW50czogMiwgdHlwZTogJ1VpbnQ4J30sXG4gICAge25hbWU6ICdhX3NoaWZ0JywgY29tcG9uZW50czogMiwgdHlwZTogJ0Zsb2F0MzInfSxcbl0pO1xuXG5leHBvcnQgY29uc3QgY29sbGlzaW9uVmVydGV4QXR0cmlidXRlc0V4dDogU3RydWN0QXJyYXlMYXlvdXQgPSBjcmVhdGVMYXlvdXQoW1xuICAgIHtuYW1lOiAnYV9zaXplX3NjYWxlJywgY29tcG9uZW50czogMSwgdHlwZTogJ0Zsb2F0MzInfSxcbiAgICB7bmFtZTogJ2FfcGFkZGluZycsIGNvbXBvbmVudHM6IDIsIHR5cGU6ICdGbG9hdDMyJ30sXG5dKTtcblxuZXhwb3J0IGNvbnN0IGNvbGxpc2lvbkJveDogU3RydWN0QXJyYXlMYXlvdXQgPSBjcmVhdGVMYXlvdXQoW1xuICAgIC8vIHRoZSBib3ggaXMgY2VudGVyZWQgYXJvdW5kIHRoZSBhbmNob3IgcG9pbnRcbiAgICB7dHlwZTogJ0ludDE2JywgbmFtZTogJ3Byb2plY3RlZEFuY2hvclgnfSxcbiAgICB7dHlwZTogJ0ludDE2JywgbmFtZTogJ3Byb2plY3RlZEFuY2hvclknfSxcbiAgICB7dHlwZTogJ0ludDE2JywgbmFtZTogJ3Byb2plY3RlZEFuY2hvclonfSxcblxuICAgIHt0eXBlOiAnSW50MTYnLCBuYW1lOiAndGlsZUFuY2hvclgnfSxcbiAgICB7dHlwZTogJ0ludDE2JywgbmFtZTogJ3RpbGVBbmNob3JZJ30sXG5cbiAgICAvLyBkaXN0YW5jZXMgdG8gdGhlIGVkZ2VzIGZyb20gdGhlIGFuY2hvclxuICAgIHt0eXBlOiAnRmxvYXQzMicsIG5hbWU6ICd4MSd9LFxuICAgIHt0eXBlOiAnRmxvYXQzMicsIG5hbWU6ICd5MSd9LFxuICAgIHt0eXBlOiAnRmxvYXQzMicsIG5hbWU6ICd4Mid9LFxuICAgIHt0eXBlOiAnRmxvYXQzMicsIG5hbWU6ICd5Mid9LFxuXG4gICAge3R5cGU6ICdJbnQxNicsIG5hbWU6ICdwYWRkaW5nJ30sXG5cbiAgICAvLyB0aGUgaW5kZXggb2YgdGhlIGZlYXR1cmUgaW4gdGhlIG9yaWdpbmFsIHZlY3RvcnRpbGVcbiAgICB7dHlwZTogJ1VpbnQzMicsIG5hbWU6ICdmZWF0dXJlSW5kZXgnfSxcbiAgICAvLyB0aGUgc291cmNlIGxheWVyIHRoZSBmZWF0dXJlIGFwcGVhcnMgaW5cbiAgICB7dHlwZTogJ1VpbnQxNicsIG5hbWU6ICdzb3VyY2VMYXllckluZGV4J30sXG4gICAgLy8gdGhlIGJ1Y2tldCB0aGUgZmVhdHVyZSBhcHBlYXJzIGluXG4gICAge3R5cGU6ICdVaW50MTYnLCBuYW1lOiAnYnVja2V0SW5kZXgnfSxcbl0pO1xuXG5leHBvcnQgY29uc3QgY29sbGlzaW9uQm94TGF5b3V0OiBTdHJ1Y3RBcnJheUxheW91dCA9IGNyZWF0ZUxheW91dChbIC8vIHVzZWQgdG8gcmVuZGVyIGNvbGxpc2lvbiBib3hlcyBmb3IgZGVidWdnaW5nIHB1cnBvc2VzXG4gICAge25hbWU6ICdhX3BvcycsICAgICAgICAgICAgIGNvbXBvbmVudHM6IDMsIHR5cGU6ICdJbnQxNid9LFxuICAgIHtuYW1lOiAnYV9hbmNob3JfcG9zJywgICAgICBjb21wb25lbnRzOiAyLCB0eXBlOiAnSW50MTYnfSxcbiAgICB7bmFtZTogJ2FfZXh0cnVkZScsICAgICAgICAgY29tcG9uZW50czogMiwgdHlwZTogJ0ludDE2J31cbl0sIDQpO1xuXG5leHBvcnQgY29uc3QgY29sbGlzaW9uQ2lyY2xlTGF5b3V0OiBTdHJ1Y3RBcnJheUxheW91dCA9IGNyZWF0ZUxheW91dChbIC8vIHVzZWQgdG8gcmVuZGVyIGNvbGxpc2lvbiBjaXJjbGVzIGZvciBkZWJ1Z2dpbmcgcHVycG9zZXNcbiAgICB7bmFtZTogJ2FfcG9zXzJmJywgICAgIGNvbXBvbmVudHM6IDIsIHR5cGU6ICdGbG9hdDMyJ30sXG4gICAge25hbWU6ICdhX3JhZGl1cycsICAgICBjb21wb25lbnRzOiAxLCB0eXBlOiAnRmxvYXQzMid9LFxuICAgIHtuYW1lOiAnYV9mbGFncycsICAgICAgY29tcG9uZW50czogMiwgdHlwZTogJ0ludDE2J31cbl0sIDQpO1xuXG5leHBvcnQgY29uc3QgcXVhZFRyaWFuZ2xlOiBTdHJ1Y3RBcnJheUxheW91dCA9IGNyZWF0ZUxheW91dChbXG4gICAge25hbWU6ICd0cmlhbmdsZScsIGNvbXBvbmVudHM6IDMsIHR5cGU6ICdVaW50MTYnfSxcbl0pO1xuXG5leHBvcnQgY29uc3QgcGxhY2VtZW50OiBTdHJ1Y3RBcnJheUxheW91dCA9IGNyZWF0ZUxheW91dChbXG4gICAge3R5cGU6ICdJbnQxNicsIG5hbWU6ICdwcm9qZWN0ZWRBbmNob3JYJ30sXG4gICAge3R5cGU6ICdJbnQxNicsIG5hbWU6ICdwcm9qZWN0ZWRBbmNob3JZJ30sXG4gICAge3R5cGU6ICdJbnQxNicsIG5hbWU6ICdwcm9qZWN0ZWRBbmNob3JaJ30sXG4gICAge3R5cGU6ICdGbG9hdDMyJywgbmFtZTogJ3RpbGVBbmNob3JYJ30sXG4gICAge3R5cGU6ICdGbG9hdDMyJywgbmFtZTogJ3RpbGVBbmNob3JZJ30sXG4gICAge3R5cGU6ICdVaW50MTYnLCBuYW1lOiAnZ2x5cGhTdGFydEluZGV4J30sXG4gICAge3R5cGU6ICdVaW50MTYnLCBuYW1lOiAnbnVtR2x5cGhzJ30sXG4gICAge3R5cGU6ICdVaW50MzInLCBuYW1lOiAndmVydGV4U3RhcnRJbmRleCd9LFxuICAgIHt0eXBlOiAnVWludDMyJywgbmFtZTogJ2xpbmVTdGFydEluZGV4J30sXG4gICAge3R5cGU6ICdVaW50MzInLCBuYW1lOiAnbGluZUxlbmd0aCd9LFxuICAgIHt0eXBlOiAnVWludDE2JywgbmFtZTogJ3NlZ21lbnQnfSxcbiAgICB7dHlwZTogJ1VpbnQxNicsIG5hbWU6ICdsb3dlclNpemUnfSxcbiAgICB7dHlwZTogJ1VpbnQxNicsIG5hbWU6ICd1cHBlclNpemUnfSxcbiAgICB7dHlwZTogJ0Zsb2F0MzInLCBuYW1lOiAnbGluZU9mZnNldFgnfSxcbiAgICB7dHlwZTogJ0Zsb2F0MzInLCBuYW1lOiAnbGluZU9mZnNldFknfSxcbiAgICB7dHlwZTogJ1VpbnQ4JywgbmFtZTogJ3dyaXRpbmdNb2RlJ30sXG4gICAge3R5cGU6ICdVaW50OCcsIG5hbWU6ICdwbGFjZWRPcmllbnRhdGlvbid9LFxuICAgIHt0eXBlOiAnVWludDgnLCBuYW1lOiAnaGlkZGVuJ30sXG4gICAge3R5cGU6ICdVaW50MzInLCBuYW1lOiAnY3Jvc3NUaWxlSUQnfSxcbiAgICB7dHlwZTogJ0ludDE2JywgbmFtZTogJ2Fzc29jaWF0ZWRJY29uSW5kZXgnfSxcbiAgICB7dHlwZTogJ1VpbnQ4JywgbmFtZTogJ2ZsaXBTdGF0ZSd9XG5dKTtcblxuZXhwb3J0IGNvbnN0IHN5bWJvbEluc3RhbmNlOiBTdHJ1Y3RBcnJheUxheW91dCA9IGNyZWF0ZUxheW91dChbXG4gICAge3R5cGU6ICdJbnQxNicsIG5hbWU6ICdwcm9qZWN0ZWRBbmNob3JYJ30sXG4gICAge3R5cGU6ICdJbnQxNicsIG5hbWU6ICdwcm9qZWN0ZWRBbmNob3JZJ30sXG4gICAge3R5cGU6ICdJbnQxNicsIG5hbWU6ICdwcm9qZWN0ZWRBbmNob3JaJ30sXG4gICAge3R5cGU6ICdGbG9hdDMyJywgbmFtZTogJ3RpbGVBbmNob3JYJ30sXG4gICAge3R5cGU6ICdGbG9hdDMyJywgbmFtZTogJ3RpbGVBbmNob3JZJ30sXG4gICAge3R5cGU6ICdJbnQxNicsIG5hbWU6ICdyaWdodEp1c3RpZmllZFRleHRTeW1ib2xJbmRleCd9LFxuICAgIHt0eXBlOiAnSW50MTYnLCBuYW1lOiAnY2VudGVySnVzdGlmaWVkVGV4dFN5bWJvbEluZGV4J30sXG4gICAge3R5cGU6ICdJbnQxNicsIG5hbWU6ICdsZWZ0SnVzdGlmaWVkVGV4dFN5bWJvbEluZGV4J30sXG4gICAge3R5cGU6ICdJbnQxNicsIG5hbWU6ICd2ZXJ0aWNhbFBsYWNlZFRleHRTeW1ib2xJbmRleCd9LFxuICAgIHt0eXBlOiAnSW50MTYnLCBuYW1lOiAncGxhY2VkSWNvblN5bWJvbEluZGV4J30sXG4gICAge3R5cGU6ICdJbnQxNicsIG5hbWU6ICd2ZXJ0aWNhbFBsYWNlZEljb25TeW1ib2xJbmRleCd9LFxuICAgIHt0eXBlOiAnVWludDE2JywgbmFtZTogJ2tleSd9LFxuICAgIHt0eXBlOiAnVWludDE2JywgbmFtZTogJ3RleHRCb3hTdGFydEluZGV4J30sXG4gICAge3R5cGU6ICdVaW50MTYnLCBuYW1lOiAndGV4dEJveEVuZEluZGV4J30sXG4gICAge3R5cGU6ICdVaW50MTYnLCBuYW1lOiAndmVydGljYWxUZXh0Qm94U3RhcnRJbmRleCd9LFxuICAgIHt0eXBlOiAnVWludDE2JywgbmFtZTogJ3ZlcnRpY2FsVGV4dEJveEVuZEluZGV4J30sXG4gICAge3R5cGU6ICdVaW50MTYnLCBuYW1lOiAnaWNvbkJveFN0YXJ0SW5kZXgnfSxcbiAgICB7dHlwZTogJ1VpbnQxNicsIG5hbWU6ICdpY29uQm94RW5kSW5kZXgnfSxcbiAgICB7dHlwZTogJ1VpbnQxNicsIG5hbWU6ICd2ZXJ0aWNhbEljb25Cb3hTdGFydEluZGV4J30sXG4gICAge3R5cGU6ICdVaW50MTYnLCBuYW1lOiAndmVydGljYWxJY29uQm94RW5kSW5kZXgnfSxcbiAgICB7dHlwZTogJ1VpbnQxNicsIG5hbWU6ICdmZWF0dXJlSW5kZXgnfSxcbiAgICB7dHlwZTogJ1VpbnQxNicsIG5hbWU6ICdudW1Ib3Jpem9udGFsR2x5cGhWZXJ0aWNlcyd9LFxuICAgIHt0eXBlOiAnVWludDE2JywgbmFtZTogJ251bVZlcnRpY2FsR2x5cGhWZXJ0aWNlcyd9LFxuICAgIHt0eXBlOiAnVWludDE2JywgbmFtZTogJ251bUljb25WZXJ0aWNlcyd9LFxuICAgIHt0eXBlOiAnVWludDE2JywgbmFtZTogJ251bVZlcnRpY2FsSWNvblZlcnRpY2VzJ30sXG4gICAge3R5cGU6ICdVaW50MTYnLCBuYW1lOiAndXNlUnVudGltZUNvbGxpc2lvbkNpcmNsZXMnfSxcbiAgICB7dHlwZTogJ1VpbnQzMicsIG5hbWU6ICdjcm9zc1RpbGVJRCd9LFxuICAgIHt0eXBlOiAnRmxvYXQzMicsIGNvbXBvbmVudHM6IDIsIG5hbWU6ICd0ZXh0T2Zmc2V0J30sXG4gICAge3R5cGU6ICdGbG9hdDMyJywgbmFtZTogJ2NvbGxpc2lvbkNpcmNsZURpYW1ldGVyJ30sXG5dKTtcblxuZXhwb3J0IGNvbnN0IGdseXBoT2Zmc2V0OiBTdHJ1Y3RBcnJheUxheW91dCA9IGNyZWF0ZUxheW91dChbXG4gICAge3R5cGU6ICdGbG9hdDMyJywgbmFtZTogJ29mZnNldFgnfVxuXSk7XG5cbmV4cG9ydCBjb25zdCBsaW5lVmVydGV4OiBTdHJ1Y3RBcnJheUxheW91dCA9IGNyZWF0ZUxheW91dChbXG4gICAge3R5cGU6ICdJbnQxNicsIG5hbWU6ICd4J30sXG4gICAge3R5cGU6ICdJbnQxNicsIG5hbWU6ICd5J31cbl0pO1xuIiwiLy8gQGZsb3dcbi8vIE9ORV9FTSBjb25zdGFudCB1c2VkIHRvIGdvIGJldHdlZW4gXCJlbVwiIHVuaXRzIHVzZWQgaW4gc3R5bGUgc3BlYyBhbmQgXCJwb2ludHNcIiB1c2VkIGludGVybmFsbHkgZm9yIGxheW91dFxuXG5leHBvcnQgZGVmYXVsdCAyNDtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCB7bnVtYmVyIGFzIGludGVycG9sYXRlfSBmcm9tICcuLi9zdHlsZS1zcGVjL3V0aWwvaW50ZXJwb2xhdGUuanMnO1xuaW1wb3J0IEludGVycG9sYXRlIGZyb20gJy4uL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi9kZWZpbml0aW9ucy9pbnRlcnBvbGF0ZS5qcyc7XG5pbXBvcnQge2NsYW1wfSBmcm9tICcuLi91dGlsL3V0aWwuanMnO1xuaW1wb3J0IEV2YWx1YXRpb25QYXJhbWV0ZXJzIGZyb20gJy4uL3N0eWxlL2V2YWx1YXRpb25fcGFyYW1ldGVycy5qcyc7XG5cbmltcG9ydCB0eXBlIHtQcm9wZXJ0eVZhbHVlLCBQb3NzaWJseUV2YWx1YXRlZFByb3BlcnR5VmFsdWV9IGZyb20gJy4uL3N0eWxlL3Byb3BlcnRpZXMuanMnO1xuaW1wb3J0IHR5cGUge0ludGVycG9sYXRpb25UeXBlfSBmcm9tICcuLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vZGVmaW5pdGlvbnMvaW50ZXJwb2xhdGUuanMnO1xuXG5jb25zdCBTSVpFX1BBQ0tfRkFDVE9SID0gMTI4O1xuXG5leHBvcnQge2dldFNpemVEYXRhLCBldmFsdWF0ZVNpemVGb3JGZWF0dXJlLCBldmFsdWF0ZVNpemVGb3Jab29tLCBTSVpFX1BBQ0tfRkFDVE9SfTtcblxuZXhwb3J0IHR5cGUgU2l6ZURhdGEgPSB7XG4gICAga2luZDogJ2NvbnN0YW50JyxcbiAgICBsYXlvdXRTaXplOiBudW1iZXJcbn0gfCB7XG4gICAga2luZDogJ3NvdXJjZSdcbn0gfCB7XG4gICAga2luZDogJ2NhbWVyYScsXG4gICAgbWluWm9vbTogbnVtYmVyLFxuICAgIG1heFpvb206IG51bWJlcixcbiAgICBtaW5TaXplOiBudW1iZXIsXG4gICAgbWF4U2l6ZTogbnVtYmVyLFxuICAgIGludGVycG9sYXRpb25UeXBlOiA/SW50ZXJwb2xhdGlvblR5cGVcbn0gfCB7XG4gICAga2luZDogJ2NvbXBvc2l0ZScsXG4gICAgbWluWm9vbTogbnVtYmVyLFxuICAgIG1heFpvb206IG51bWJlcixcbiAgICBpbnRlcnBvbGF0aW9uVHlwZTogP0ludGVycG9sYXRpb25UeXBlXG59O1xuXG5leHBvcnQgdHlwZSBJbnRlcnBvbGF0ZWRTaXplID0ge3xcbiAgICB1U2l6ZTogbnVtYmVyLFxuICAgIHVTaXplVDogbnVtYmVyXG58fTtcblxuLy8gRm9yIHt0ZXh0LGljb259LXNpemUsIGdldCB0aGUgYnVja2V0LWxldmVsIGRhdGEgdGhhdCB3aWxsIGJlIG5lZWRlZCBieVxuLy8gdGhlIHBhaW50ZXIgdG8gc2V0IHN5bWJvbC1zaXplLXJlbGF0ZWQgdW5pZm9ybXNcbmZ1bmN0aW9uIGdldFNpemVEYXRhKHRpbGVab29tOiBudW1iZXIsIHZhbHVlOiBQcm9wZXJ0eVZhbHVlPG51bWJlciwgUG9zc2libHlFdmFsdWF0ZWRQcm9wZXJ0eVZhbHVlPG51bWJlcj4+KTogU2l6ZURhdGEge1xuICAgIGNvbnN0IHtleHByZXNzaW9ufSA9IHZhbHVlO1xuXG4gICAgaWYgKGV4cHJlc3Npb24ua2luZCA9PT0gJ2NvbnN0YW50Jykge1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIGNvbnN0IGxheW91dFNpemUgPSBleHByZXNzaW9uLmV2YWx1YXRlKG5ldyBFdmFsdWF0aW9uUGFyYW1ldGVycyh0aWxlWm9vbSArIDEpKTtcbiAgICAgICAgcmV0dXJuIHtraW5kOiAnY29uc3RhbnQnLCBsYXlvdXRTaXplfTtcblxuICAgIH0gZWxzZSBpZiAoZXhwcmVzc2lvbi5raW5kID09PSAnc291cmNlJykge1xuICAgICAgICByZXR1cm4ge2tpbmQ6ICdzb3VyY2UnfTtcblxuICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHt6b29tU3RvcHMsIGludGVycG9sYXRpb25UeXBlfSA9IGV4cHJlc3Npb247XG5cbiAgICAgICAgLy8gY2FsY3VsYXRlIGNvdmVyaW5nIHpvb20gc3RvcHMgZm9yIHpvb20tZGVwZW5kZW50IHZhbHVlc1xuICAgICAgICBsZXQgbG93ZXIgPSAwO1xuICAgICAgICB3aGlsZSAobG93ZXIgPCB6b29tU3RvcHMubGVuZ3RoICYmIHpvb21TdG9wc1tsb3dlcl0gPD0gdGlsZVpvb20pIGxvd2VyKys7XG4gICAgICAgIGxvd2VyID0gTWF0aC5tYXgoMCwgbG93ZXIgLSAxKTtcbiAgICAgICAgbGV0IHVwcGVyID0gbG93ZXI7XG4gICAgICAgIHdoaWxlICh1cHBlciA8IHpvb21TdG9wcy5sZW5ndGggJiYgem9vbVN0b3BzW3VwcGVyXSA8IHRpbGVab29tICsgMSkgdXBwZXIrKztcbiAgICAgICAgdXBwZXIgPSBNYXRoLm1pbih6b29tU3RvcHMubGVuZ3RoIC0gMSwgdXBwZXIpO1xuXG4gICAgICAgIGNvbnN0IG1pblpvb20gPSB6b29tU3RvcHNbbG93ZXJdO1xuICAgICAgICBjb25zdCBtYXhab29tID0gem9vbVN0b3BzW3VwcGVyXTtcblxuICAgICAgICAvLyBXZSdkIGxpa2UgdG8gYmUgYWJsZSB0byB1c2UgQ2FtZXJhRXhwcmVzc2lvbiBvciBDb21wb3NpdGVFeHByZXNzaW9uIGluIHRoZXNlXG4gICAgICAgIC8vIHJldHVybiB0eXBlcyByYXRoZXIgdGhhbiBFeHByZXNzaW9uU3BlY2lmaWNhdGlvbiwgYnV0IHRoZSBmb3JtZXIgYXJlIG5vdFxuICAgICAgICAvLyB0cmFuc2ZlcnJhYmxlIGFjcm9zcyBXZWIgV29ya2VyIGJvdW5kYXJpZXMuXG4gICAgICAgIGlmIChleHByZXNzaW9uLmtpbmQgPT09ICdjb21wb3NpdGUnKSB7XG4gICAgICAgICAgICByZXR1cm4ge2tpbmQ6ICdjb21wb3NpdGUnLCBtaW5ab29tLCBtYXhab29tLCBpbnRlcnBvbGF0aW9uVHlwZX07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBmb3IgY2FtZXJhIGZ1bmN0aW9ucywgYWxzbyBzYXZlIG9mZiB0aGUgZnVuY3Rpb24gdmFsdWVzXG4gICAgICAgIC8vIGV2YWx1YXRlZCBhdCB0aGUgY292ZXJpbmcgem9vbSBsZXZlbHNcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICBjb25zdCBtaW5TaXplID0gZXhwcmVzc2lvbi5ldmFsdWF0ZShuZXcgRXZhbHVhdGlvblBhcmFtZXRlcnMobWluWm9vbSkpO1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIGNvbnN0IG1heFNpemUgPSBleHByZXNzaW9uLmV2YWx1YXRlKG5ldyBFdmFsdWF0aW9uUGFyYW1ldGVycyhtYXhab29tKSk7XG5cbiAgICAgICAgcmV0dXJuIHtraW5kOiAnY2FtZXJhJywgbWluWm9vbSwgbWF4Wm9vbSwgbWluU2l6ZSwgbWF4U2l6ZSwgaW50ZXJwb2xhdGlvblR5cGV9O1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZXZhbHVhdGVTaXplRm9yRmVhdHVyZShzaXplRGF0YTogU2l6ZURhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt1U2l6ZSwgdVNpemVUfTogSW50ZXJwb2xhdGVkU2l6ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge2xvd2VyU2l6ZSwgdXBwZXJTaXplfTogaW50ZXJmYWNlIHsrbG93ZXJTaXplOiBudW1iZXIsICt1cHBlclNpemU6IG51bWJlcn0pOiBudW1iZXIge1xuICAgIGlmIChzaXplRGF0YS5raW5kID09PSAnc291cmNlJykge1xuICAgICAgICByZXR1cm4gbG93ZXJTaXplIC8gU0laRV9QQUNLX0ZBQ1RPUjtcbiAgICB9IGVsc2UgaWYgKHNpemVEYXRhLmtpbmQgPT09ICdjb21wb3NpdGUnKSB7XG4gICAgICAgIHJldHVybiBpbnRlcnBvbGF0ZShsb3dlclNpemUgLyBTSVpFX1BBQ0tfRkFDVE9SLCB1cHBlclNpemUgLyBTSVpFX1BBQ0tfRkFDVE9SLCB1U2l6ZVQpO1xuICAgIH1cbiAgICByZXR1cm4gdVNpemU7XG59XG5cbmZ1bmN0aW9uIGV2YWx1YXRlU2l6ZUZvclpvb20oc2l6ZURhdGE6IFNpemVEYXRhLCB6b29tOiBudW1iZXIpOiBJbnRlcnBvbGF0ZWRTaXplIHtcbiAgICBsZXQgdVNpemVUID0gMDtcbiAgICBsZXQgdVNpemUgPSAwO1xuXG4gICAgaWYgKHNpemVEYXRhLmtpbmQgPT09ICdjb25zdGFudCcpIHtcbiAgICAgICAgdVNpemUgPSBzaXplRGF0YS5sYXlvdXRTaXplO1xuXG4gICAgfSBlbHNlIGlmIChzaXplRGF0YS5raW5kICE9PSAnc291cmNlJykge1xuICAgICAgICBjb25zdCB7aW50ZXJwb2xhdGlvblR5cGUsIG1pblpvb20sIG1heFpvb219ID0gc2l6ZURhdGE7XG5cbiAgICAgICAgLy8gRXZlbiB0aG91Z2ggd2UgY291bGQgZ2V0IHRoZSBleGFjdCB2YWx1ZSBvZiB0aGUgY2FtZXJhIGZ1bmN0aW9uXG4gICAgICAgIC8vIGF0IHogPSB0ci56b29tLCB3ZSBpbnRlbnRpb25hbGx5IGRvIG5vdDogaW5zdGVhZCwgd2UgaW50ZXJwb2xhdGVcbiAgICAgICAgLy8gYmV0d2VlbiB0aGUgY2FtZXJhIGZ1bmN0aW9uIHZhbHVlcyBhdCBhIHBhaXIgb2Ygem9vbSBzdG9wcyBjb3ZlcmluZ1xuICAgICAgICAvLyBbdGlsZVpvb20sIHRpbGVab29tICsgMV0gaW4gb3JkZXIgdG8gYmUgY29uc2lzdGVudCB3aXRoIHRoaXNcbiAgICAgICAgLy8gcmVzdHJpY3Rpb24gb24gY29tcG9zaXRlIGZ1bmN0aW9uc1xuICAgICAgICBjb25zdCB0ID0gIWludGVycG9sYXRpb25UeXBlID8gMCA6IGNsYW1wKFxuICAgICAgICAgICAgSW50ZXJwb2xhdGUuaW50ZXJwb2xhdGlvbkZhY3RvcihpbnRlcnBvbGF0aW9uVHlwZSwgem9vbSwgbWluWm9vbSwgbWF4Wm9vbSksIDAsIDEpO1xuXG4gICAgICAgIGlmIChzaXplRGF0YS5raW5kID09PSAnY2FtZXJhJykge1xuICAgICAgICAgICAgdVNpemUgPSBpbnRlcnBvbGF0ZShzaXplRGF0YS5taW5TaXplLCBzaXplRGF0YS5tYXhTaXplLCB0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHVTaXplVCA9IHQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge3VTaXplVCwgdVNpemV9O1xufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtwbHVnaW4gYXMgcnRsVGV4dFBsdWdpbn0gZnJvbSAnLi4vc291cmNlL3J0bF90ZXh0X3BsdWdpbi5qcyc7XG5cbmltcG9ydCB0eXBlIFN5bWJvbFN0eWxlTGF5ZXIgZnJvbSAnLi4vc3R5bGUvc3R5bGVfbGF5ZXIvc3ltYm9sX3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCB0eXBlIHtGZWF0dXJlfSBmcm9tICcuLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vaW5kZXguanMnO1xuaW1wb3J0IEZvcm1hdHRlZCBmcm9tICcuLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vdHlwZXMvZm9ybWF0dGVkLmpzJztcblxuZnVuY3Rpb24gdHJhbnNmb3JtVGV4dCh0ZXh0OiBzdHJpbmcsIGxheWVyOiBTeW1ib2xTdHlsZUxheWVyLCBmZWF0dXJlOiBGZWF0dXJlKSB7XG4gICAgY29uc3QgdHJhbnNmb3JtID0gbGF5ZXIubGF5b3V0LmdldCgndGV4dC10cmFuc2Zvcm0nKS5ldmFsdWF0ZShmZWF0dXJlLCB7fSk7XG4gICAgaWYgKHRyYW5zZm9ybSA9PT0gJ3VwcGVyY2FzZScpIHtcbiAgICAgICAgdGV4dCA9IHRleHQudG9Mb2NhbGVVcHBlckNhc2UoKTtcbiAgICB9IGVsc2UgaWYgKHRyYW5zZm9ybSA9PT0gJ2xvd2VyY2FzZScpIHtcbiAgICAgICAgdGV4dCA9IHRleHQudG9Mb2NhbGVMb3dlckNhc2UoKTtcbiAgICB9XG5cbiAgICBpZiAocnRsVGV4dFBsdWdpbi5hcHBseUFyYWJpY1NoYXBpbmcpIHtcbiAgICAgICAgdGV4dCA9IHJ0bFRleHRQbHVnaW4uYXBwbHlBcmFiaWNTaGFwaW5nKHRleHQpO1xuICAgIH1cblxuICAgIHJldHVybiB0ZXh0O1xufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbih0ZXh0OiBGb3JtYXR0ZWQsIGxheWVyOiBTeW1ib2xTdHlsZUxheWVyLCBmZWF0dXJlOiBGZWF0dXJlKTogRm9ybWF0dGVkIHtcbiAgICB0ZXh0LnNlY3Rpb25zLmZvckVhY2goc2VjdGlvbiA9PiB7XG4gICAgICAgIHNlY3Rpb24udGV4dCA9IHRyYW5zZm9ybVRleHQoc2VjdGlvbi50ZXh0LCBsYXllciwgZmVhdHVyZSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRleHQ7XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgdHlwZSBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCB0eXBlIHtTeW1ib2xGZWF0dXJlfSBmcm9tICcuLi9kYXRhL2J1Y2tldC9zeW1ib2xfYnVja2V0LmpzJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKGZlYXR1cmVzOiBBcnJheTxTeW1ib2xGZWF0dXJlPik6IEFycmF5PFN5bWJvbEZlYXR1cmU+IHtcbiAgICBjb25zdCBsZWZ0SW5kZXg6IHtbXzogc3RyaW5nXTogbnVtYmVyfSA9IHt9O1xuICAgIGNvbnN0IHJpZ2h0SW5kZXg6IHtbXzogc3RyaW5nXTogbnVtYmVyfSA9IHt9O1xuICAgIGNvbnN0IG1lcmdlZEZlYXR1cmVzID0gW107XG4gICAgbGV0IG1lcmdlZEluZGV4ID0gMDtcblxuICAgIGZ1bmN0aW9uIGFkZChrOiBudW1iZXIpIHtcbiAgICAgICAgbWVyZ2VkRmVhdHVyZXMucHVzaChmZWF0dXJlc1trXSk7XG4gICAgICAgIG1lcmdlZEluZGV4Kys7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWVyZ2VGcm9tUmlnaHQobGVmdEtleTogc3RyaW5nLCByaWdodEtleTogc3RyaW5nLCBnZW9tOiBBcnJheTxBcnJheTxQb2ludD4+KSB7XG4gICAgICAgIGNvbnN0IGkgPSByaWdodEluZGV4W2xlZnRLZXldO1xuICAgICAgICBkZWxldGUgcmlnaHRJbmRleFtsZWZ0S2V5XTtcbiAgICAgICAgcmlnaHRJbmRleFtyaWdodEtleV0gPSBpO1xuXG4gICAgICAgIG1lcmdlZEZlYXR1cmVzW2ldLmdlb21ldHJ5WzBdLnBvcCgpO1xuICAgICAgICBtZXJnZWRGZWF0dXJlc1tpXS5nZW9tZXRyeVswXSA9IG1lcmdlZEZlYXR1cmVzW2ldLmdlb21ldHJ5WzBdLmNvbmNhdChnZW9tWzBdKTtcbiAgICAgICAgcmV0dXJuIGk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWVyZ2VGcm9tTGVmdChsZWZ0S2V5OiBzdHJpbmcsIHJpZ2h0S2V5OiBzdHJpbmcsIGdlb206IEFycmF5PEFycmF5PFBvaW50Pj4pIHtcbiAgICAgICAgY29uc3QgaSA9IGxlZnRJbmRleFtyaWdodEtleV07XG4gICAgICAgIGRlbGV0ZSBsZWZ0SW5kZXhbcmlnaHRLZXldO1xuICAgICAgICBsZWZ0SW5kZXhbbGVmdEtleV0gPSBpO1xuXG4gICAgICAgIG1lcmdlZEZlYXR1cmVzW2ldLmdlb21ldHJ5WzBdLnNoaWZ0KCk7XG4gICAgICAgIG1lcmdlZEZlYXR1cmVzW2ldLmdlb21ldHJ5WzBdID0gZ2VvbVswXS5jb25jYXQobWVyZ2VkRmVhdHVyZXNbaV0uZ2VvbWV0cnlbMF0pO1xuICAgICAgICByZXR1cm4gaTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRLZXkodGV4dDogc3RyaW5nLCBnZW9tOiBBcnJheTxBcnJheTxQb2ludD4+LCBvblJpZ2h0OiA/Ym9vbGVhbikge1xuICAgICAgICBjb25zdCBwb2ludCA9IG9uUmlnaHQgPyBnZW9tWzBdW2dlb21bMF0ubGVuZ3RoIC0gMV0gOiBnZW9tWzBdWzBdO1xuICAgICAgICByZXR1cm4gYCR7dGV4dH06JHtwb2ludC54fToke3BvaW50Lnl9YDtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBrID0gMDsgayA8IGZlYXR1cmVzLmxlbmd0aDsgaysrKSB7XG4gICAgICAgIGNvbnN0IGZlYXR1cmUgPSBmZWF0dXJlc1trXTtcbiAgICAgICAgY29uc3QgZ2VvbSA9IGZlYXR1cmUuZ2VvbWV0cnk7XG4gICAgICAgIGNvbnN0IHRleHQgPSBmZWF0dXJlLnRleHQgPyBmZWF0dXJlLnRleHQudG9TdHJpbmcoKSA6IG51bGw7XG5cbiAgICAgICAgaWYgKCF0ZXh0KSB7XG4gICAgICAgICAgICBhZGQoayk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxlZnRLZXkgPSBnZXRLZXkodGV4dCwgZ2VvbSksXG4gICAgICAgICAgICByaWdodEtleSA9IGdldEtleSh0ZXh0LCBnZW9tLCB0cnVlKTtcblxuICAgICAgICBpZiAoKGxlZnRLZXkgaW4gcmlnaHRJbmRleCkgJiYgKHJpZ2h0S2V5IGluIGxlZnRJbmRleCkgJiYgKHJpZ2h0SW5kZXhbbGVmdEtleV0gIT09IGxlZnRJbmRleFtyaWdodEtleV0pKSB7XG4gICAgICAgICAgICAvLyBmb3VuZCBsaW5lcyB3aXRoIHRoZSBzYW1lIHRleHQgYWRqYWNlbnQgdG8gYm90aCBlbmRzIG9mIHRoZSBjdXJyZW50IGxpbmUsIG1lcmdlIGFsbCB0aHJlZVxuICAgICAgICAgICAgY29uc3QgaiA9IG1lcmdlRnJvbUxlZnQobGVmdEtleSwgcmlnaHRLZXksIGdlb20pO1xuICAgICAgICAgICAgY29uc3QgaSA9IG1lcmdlRnJvbVJpZ2h0KGxlZnRLZXksIHJpZ2h0S2V5LCBtZXJnZWRGZWF0dXJlc1tqXS5nZW9tZXRyeSk7XG5cbiAgICAgICAgICAgIGRlbGV0ZSBsZWZ0SW5kZXhbbGVmdEtleV07XG4gICAgICAgICAgICBkZWxldGUgcmlnaHRJbmRleFtyaWdodEtleV07XG5cbiAgICAgICAgICAgIHJpZ2h0SW5kZXhbZ2V0S2V5KHRleHQsIG1lcmdlZEZlYXR1cmVzW2ldLmdlb21ldHJ5LCB0cnVlKV0gPSBpO1xuICAgICAgICAgICAgbWVyZ2VkRmVhdHVyZXNbal0uZ2VvbWV0cnkgPSAobnVsbDogYW55KTtcblxuICAgICAgICB9IGVsc2UgaWYgKGxlZnRLZXkgaW4gcmlnaHRJbmRleCkge1xuICAgICAgICAgICAgLy8gZm91bmQgbWVyZ2VhYmxlIGxpbmUgYWRqYWNlbnQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBjdXJyZW50IGxpbmUsIG1lcmdlXG4gICAgICAgICAgICBtZXJnZUZyb21SaWdodChsZWZ0S2V5LCByaWdodEtleSwgZ2VvbSk7XG5cbiAgICAgICAgfSBlbHNlIGlmIChyaWdodEtleSBpbiBsZWZ0SW5kZXgpIHtcbiAgICAgICAgICAgIC8vIGZvdW5kIG1lcmdlYWJsZSBsaW5lIGFkamFjZW50IHRvIHRoZSBlbmQgb2YgdGhlIGN1cnJlbnQgbGluZSwgbWVyZ2VcbiAgICAgICAgICAgIG1lcmdlRnJvbUxlZnQobGVmdEtleSwgcmlnaHRLZXksIGdlb20pO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBubyBhZGphY2VudCBsaW5lcywgYWRkIGFzIGEgbmV3IGl0ZW1cbiAgICAgICAgICAgIGFkZChrKTtcbiAgICAgICAgICAgIGxlZnRJbmRleFtsZWZ0S2V5XSA9IG1lcmdlZEluZGV4IC0gMTtcbiAgICAgICAgICAgIHJpZ2h0SW5kZXhbcmlnaHRLZXldID0gbWVyZ2VkSW5kZXggLSAxO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG1lcmdlZEZlYXR1cmVzLmZpbHRlcigoZikgPT4gZi5nZW9tZXRyeSk7XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge2NoYXJIYXNSb3RhdGVkVmVydGljYWxPcmllbnRhdGlvbn0gZnJvbSAnLi9zY3JpcHRfZGV0ZWN0aW9uLmpzJztcblxuZXhwb3J0IGNvbnN0IHZlcnRpY2FsaXplZENoYXJhY3Rlck1hcCA9IHtcbiAgICAnISc6ICfvuJUnLFxuICAgICcjJzogJ++8gycsXG4gICAgJyQnOiAn77yEJyxcbiAgICAnJSc6ICfvvIUnLFxuICAgICcmJzogJ++8hicsXG4gICAgJygnOiAn77i1JyxcbiAgICAnKSc6ICfvuLYnLFxuICAgICcqJzogJ++8iicsXG4gICAgJysnOiAn77yLJyxcbiAgICAnLCc6ICfvuJAnLFxuICAgICctJzogJ++4sicsXG4gICAgJy4nOiAn44O7JyxcbiAgICAnLyc6ICfvvI8nLFxuICAgICc6JzogJ++4kycsXG4gICAgJzsnOiAn77iUJyxcbiAgICAnPCc6ICfvuL8nLFxuICAgICc9JzogJ++8nScsXG4gICAgJz4nOiAn77mAJyxcbiAgICAnPyc6ICfvuJYnLFxuICAgICdAJzogJ++8oCcsXG4gICAgJ1snOiAn77mHJyxcbiAgICAnXFxcXCc6ICfvvLwnLFxuICAgICddJzogJ++5iCcsXG4gICAgJ14nOiAn77y+JyxcbiAgICAnXyc6ICfvuLMnLFxuICAgICdgJzogJ++9gCcsXG4gICAgJ3snOiAn77i3JyxcbiAgICAnfCc6ICfigJUnLFxuICAgICd9JzogJ++4uCcsXG4gICAgJ34nOiAn772eJyxcbiAgICAnwqInOiAn77+gJyxcbiAgICAnwqMnOiAn77+hJyxcbiAgICAnwqUnOiAn77+lJyxcbiAgICAnwqYnOiAn77+kJyxcbiAgICAnwqwnOiAn77+iJyxcbiAgICAnwq8nOiAn77+jJyxcbiAgICAn4oCTJzogJ++4sicsXG4gICAgJ+KAlCc6ICfvuLEnLFxuICAgICfigJgnOiAn77mDJyxcbiAgICAn4oCZJzogJ++5hCcsXG4gICAgJ+KAnCc6ICfvuYEnLFxuICAgICfigJ0nOiAn77mCJyxcbiAgICAn4oCmJzogJ++4mScsXG4gICAgJ+KApyc6ICfjg7snLFxuICAgICfigqknOiAn77+mJyxcbiAgICAn44CBJzogJ++4kScsXG4gICAgJ+OAgic6ICfvuJInLFxuICAgICfjgIgnOiAn77i/JyxcbiAgICAn44CJJzogJ++5gCcsXG4gICAgJ+OAiic6ICfvuL0nLFxuICAgICfjgIsnOiAn77i+JyxcbiAgICAn44CMJzogJ++5gScsXG4gICAgJ+OAjSc6ICfvuYInLFxuICAgICfjgI4nOiAn77mDJyxcbiAgICAn44CPJzogJ++5hCcsXG4gICAgJ+OAkCc6ICfvuLsnLFxuICAgICfjgJEnOiAn77i8JyxcbiAgICAn44CUJzogJ++4uScsXG4gICAgJ+OAlSc6ICfvuLonLFxuICAgICfjgJYnOiAn77iXJyxcbiAgICAn44CXJzogJ++4mCcsXG4gICAgJ++8gSc6ICfvuJUnLFxuICAgICfvvIgnOiAn77i1JyxcbiAgICAn77yJJzogJ++4ticsXG4gICAgJ++8jCc6ICfvuJAnLFxuICAgICfvvI0nOiAn77iyJyxcbiAgICAn77yOJzogJ+ODuycsXG4gICAgJ++8mic6ICfvuJMnLFxuICAgICfvvJsnOiAn77iUJyxcbiAgICAn77ycJzogJ++4vycsXG4gICAgJ++8nic6ICfvuYAnLFxuICAgICfvvJ8nOiAn77iWJyxcbiAgICAn77y7JzogJ++5hycsXG4gICAgJ++8vSc6ICfvuYgnLFxuICAgICfvvL8nOiAn77izJyxcbiAgICAn772bJzogJ++4tycsXG4gICAgJ++9nCc6ICfigJUnLFxuICAgICfvvZ0nOiAn77i4JyxcbiAgICAn772fJzogJ++4tScsXG4gICAgJ++9oCc6ICfvuLYnLFxuICAgICfvvaEnOiAn77iSJyxcbiAgICAn772iJzogJ++5gScsXG4gICAgJ++9oyc6ICfvuYInLFxuICAgICfihpAnOiAn4oaRJyxcbiAgICAn4oaSJzogJ+KGkydcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHZlcnRpY2FsaXplUHVuY3R1YXRpb24oaW5wdXQ6IHN0cmluZywgc2tpcENvbnRleHRDaGVja2luZzogYm9vbGVhbik6IHN0cmluZyB7XG4gICAgbGV0IG91dHB1dCA9ICcnO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dC5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBuZXh0Q2hhckNvZGUgPSBpbnB1dC5jaGFyQ29kZUF0KGkgKyAxKSB8fCBudWxsO1xuICAgICAgICBjb25zdCBwcmV2Q2hhckNvZGUgPSBpbnB1dC5jaGFyQ29kZUF0KGkgLSAxKSB8fCBudWxsO1xuXG4gICAgICAgIGNvbnN0IGNhblJlcGxhY2VQdW5jdHVhdGlvbiA9IHNraXBDb250ZXh0Q2hlY2tpbmcgfHwgKFxuICAgICAgICAgICAgKCFuZXh0Q2hhckNvZGUgfHwgIWNoYXJIYXNSb3RhdGVkVmVydGljYWxPcmllbnRhdGlvbihuZXh0Q2hhckNvZGUpIHx8IHZlcnRpY2FsaXplZENoYXJhY3Rlck1hcFtpbnB1dFtpICsgMV1dKSAmJlxuICAgICAgICAgICAgKCFwcmV2Q2hhckNvZGUgfHwgIWNoYXJIYXNSb3RhdGVkVmVydGljYWxPcmllbnRhdGlvbihwcmV2Q2hhckNvZGUpIHx8IHZlcnRpY2FsaXplZENoYXJhY3Rlck1hcFtpbnB1dFtpIC0gMV1dKVxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChjYW5SZXBsYWNlUHVuY3R1YXRpb24gJiYgdmVydGljYWxpemVkQ2hhcmFjdGVyTWFwW2lucHV0W2ldXSkge1xuICAgICAgICAgICAgb3V0cHV0ICs9IHZlcnRpY2FsaXplZENoYXJhY3Rlck1hcFtpbnB1dFtpXV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBvdXRwdXQgKz0gaW5wdXRbaV07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gb3V0cHV0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNWZXJ0aWNhbENsb3NlUHVuY3R1YXRpb24oY2hyOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gY2hyID09PSAn77i2JyB8fCBjaHIgPT09ICfvuYgnIHx8IGNociA9PT0gJ++4uCcgfHwgY2hyID09PSAn77mEJyB8fCBjaHIgPT09ICfvuYInIHx8IGNociA9PT0gJ++4vicgfHxcbiAgICAgICAgICAgY2hyID09PSAn77i8JyB8fCBjaHIgPT09ICfvuLonIHx8IGNociA9PT0gJ++4mCcgfHwgY2hyID09PSAn77mAJyB8fCBjaHIgPT09ICfvuJAnIHx8IGNociA9PT0gJ++4kycgfHxcbiAgICAgICAgICAgY2hyID09PSAn77iUJyB8fCBjaHIgPT09ICfvvYAnIHx8IGNociA9PT0gJ++/oycgfHwgY2hyID09PSAn77iRJyB8fCBjaHIgPT09ICfvuJInO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNWZXJ0aWNhbE9wZW5QdW5jdHVhdGlvbihjaHI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBjaHIgPT09ICfvuLUnIHx8IGNociA9PT0gJ++5hycgfHwgY2hyID09PSAn77i3JyB8fCBjaHIgPT09ICfvuYMnIHx8IGNociA9PT0gJ++5gScgfHwgY2hyID09PSAn77i9JyB8fFxuICAgICAgICAgICBjaHIgPT09ICfvuLsnIHx8IGNociA9PT0gJ++4uScgfHwgY2hyID09PSAn77iXJyB8fCBjaHIgPT09ICfvuL8nO1xufVxuIiwiLyohIGllZWU3NTQuIEJTRC0zLUNsYXVzZSBMaWNlbnNlLiBGZXJvc3MgQWJvdWtoYWRpamVoIDxodHRwczovL2Zlcm9zcy5vcmcvb3BlbnNvdXJjZT4gKi9cbmV4cG9ydHMucmVhZCA9IGZ1bmN0aW9uIChidWZmZXIsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtXG4gIHZhciBlTGVuID0gKG5CeXRlcyAqIDgpIC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBuQml0cyA9IC03XG4gIHZhciBpID0gaXNMRSA/IChuQnl0ZXMgLSAxKSA6IDBcbiAgdmFyIGQgPSBpc0xFID8gLTEgOiAxXG4gIHZhciBzID0gYnVmZmVyW29mZnNldCArIGldXG5cbiAgaSArPSBkXG5cbiAgZSA9IHMgJiAoKDEgPDwgKC1uQml0cykpIC0gMSlcbiAgcyA+Pj0gKC1uQml0cylcbiAgbkJpdHMgKz0gZUxlblxuICBmb3IgKDsgbkJpdHMgPiAwOyBlID0gKGUgKiAyNTYpICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgbSA9IGUgJiAoKDEgPDwgKC1uQml0cykpIC0gMSlcbiAgZSA+Pj0gKC1uQml0cylcbiAgbkJpdHMgKz0gbUxlblxuICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gKG0gKiAyNTYpICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgaWYgKGUgPT09IDApIHtcbiAgICBlID0gMSAtIGVCaWFzXG4gIH0gZWxzZSBpZiAoZSA9PT0gZU1heCkge1xuICAgIHJldHVybiBtID8gTmFOIDogKChzID8gLTEgOiAxKSAqIEluZmluaXR5KVxuICB9IGVsc2Uge1xuICAgIG0gPSBtICsgTWF0aC5wb3coMiwgbUxlbilcbiAgICBlID0gZSAtIGVCaWFzXG4gIH1cbiAgcmV0dXJuIChzID8gLTEgOiAxKSAqIG0gKiBNYXRoLnBvdygyLCBlIC0gbUxlbilcbn1cblxuZXhwb3J0cy53cml0ZSA9IGZ1bmN0aW9uIChidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbSwgY1xuICB2YXIgZUxlbiA9IChuQnl0ZXMgKiA4KSAtIG1MZW4gLSAxXG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxXG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMVxuICB2YXIgcnQgPSAobUxlbiA9PT0gMjMgPyBNYXRoLnBvdygyLCAtMjQpIC0gTWF0aC5wb3coMiwgLTc3KSA6IDApXG4gIHZhciBpID0gaXNMRSA/IDAgOiAobkJ5dGVzIC0gMSlcbiAgdmFyIGQgPSBpc0xFID8gMSA6IC0xXG4gIHZhciBzID0gdmFsdWUgPCAwIHx8ICh2YWx1ZSA9PT0gMCAmJiAxIC8gdmFsdWUgPCAwKSA/IDEgOiAwXG5cbiAgdmFsdWUgPSBNYXRoLmFicyh2YWx1ZSlcblxuICBpZiAoaXNOYU4odmFsdWUpIHx8IHZhbHVlID09PSBJbmZpbml0eSkge1xuICAgIG0gPSBpc05hTih2YWx1ZSkgPyAxIDogMFxuICAgIGUgPSBlTWF4XG4gIH0gZWxzZSB7XG4gICAgZSA9IE1hdGguZmxvb3IoTWF0aC5sb2codmFsdWUpIC8gTWF0aC5MTjIpXG4gICAgaWYgKHZhbHVlICogKGMgPSBNYXRoLnBvdygyLCAtZSkpIDwgMSkge1xuICAgICAgZS0tXG4gICAgICBjICo9IDJcbiAgICB9XG4gICAgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICB2YWx1ZSArPSBydCAvIGNcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUgKz0gcnQgKiBNYXRoLnBvdygyLCAxIC0gZUJpYXMpXG4gICAgfVxuICAgIGlmICh2YWx1ZSAqIGMgPj0gMikge1xuICAgICAgZSsrXG4gICAgICBjIC89IDJcbiAgICB9XG5cbiAgICBpZiAoZSArIGVCaWFzID49IGVNYXgpIHtcbiAgICAgIG0gPSAwXG4gICAgICBlID0gZU1heFxuICAgIH0gZWxzZSBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIG0gPSAoKHZhbHVlICogYykgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gZSArIGVCaWFzXG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSB2YWx1ZSAqIE1hdGgucG93KDIsIGVCaWFzIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IDBcbiAgICB9XG4gIH1cblxuICBmb3IgKDsgbUxlbiA+PSA4OyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBtICYgMHhmZiwgaSArPSBkLCBtIC89IDI1NiwgbUxlbiAtPSA4KSB7fVxuXG4gIGUgPSAoZSA8PCBtTGVuKSB8IG1cbiAgZUxlbiArPSBtTGVuXG4gIGZvciAoOyBlTGVuID4gMDsgYnVmZmVyW29mZnNldCArIGldID0gZSAmIDB4ZmYsIGkgKz0gZCwgZSAvPSAyNTYsIGVMZW4gLT0gOCkge31cblxuICBidWZmZXJbb2Zmc2V0ICsgaSAtIGRdIHw9IHMgKiAxMjhcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBQYmY7XG5cbnZhciBpZWVlNzU0ID0gcmVxdWlyZSgnaWVlZTc1NCcpO1xuXG5mdW5jdGlvbiBQYmYoYnVmKSB7XG4gICAgdGhpcy5idWYgPSBBcnJheUJ1ZmZlci5pc1ZpZXcgJiYgQXJyYXlCdWZmZXIuaXNWaWV3KGJ1ZikgPyBidWYgOiBuZXcgVWludDhBcnJheShidWYgfHwgMCk7XG4gICAgdGhpcy5wb3MgPSAwO1xuICAgIHRoaXMudHlwZSA9IDA7XG4gICAgdGhpcy5sZW5ndGggPSB0aGlzLmJ1Zi5sZW5ndGg7XG59XG5cblBiZi5WYXJpbnQgID0gMDsgLy8gdmFyaW50OiBpbnQzMiwgaW50NjQsIHVpbnQzMiwgdWludDY0LCBzaW50MzIsIHNpbnQ2NCwgYm9vbCwgZW51bVxuUGJmLkZpeGVkNjQgPSAxOyAvLyA2NC1iaXQ6IGRvdWJsZSwgZml4ZWQ2NCwgc2ZpeGVkNjRcblBiZi5CeXRlcyAgID0gMjsgLy8gbGVuZ3RoLWRlbGltaXRlZDogc3RyaW5nLCBieXRlcywgZW1iZWRkZWQgbWVzc2FnZXMsIHBhY2tlZCByZXBlYXRlZCBmaWVsZHNcblBiZi5GaXhlZDMyID0gNTsgLy8gMzItYml0OiBmbG9hdCwgZml4ZWQzMiwgc2ZpeGVkMzJcblxudmFyIFNISUZUX0xFRlRfMzIgPSAoMSA8PCAxNikgKiAoMSA8PCAxNiksXG4gICAgU0hJRlRfUklHSFRfMzIgPSAxIC8gU0hJRlRfTEVGVF8zMjtcblxuLy8gVGhyZXNob2xkIGNob3NlbiBiYXNlZCBvbiBib3RoIGJlbmNobWFya2luZyBhbmQga25vd2xlZGdlIGFib3V0IGJyb3dzZXIgc3RyaW5nXG4vLyBkYXRhIHN0cnVjdHVyZXMgKHdoaWNoIGN1cnJlbnRseSBzd2l0Y2ggc3RydWN0dXJlIHR5cGVzIGF0IDEyIGJ5dGVzIG9yIG1vcmUpXG52YXIgVEVYVF9ERUNPREVSX01JTl9MRU5HVEggPSAxMjtcbnZhciB1dGY4VGV4dERlY29kZXIgPSB0eXBlb2YgVGV4dERlY29kZXIgPT09ICd1bmRlZmluZWQnID8gbnVsbCA6IG5ldyBUZXh0RGVjb2RlcigndXRmOCcpO1xuXG5QYmYucHJvdG90eXBlID0ge1xuXG4gICAgZGVzdHJveTogZnVuY3Rpb24oKSB7XG4gICAgICAgIHRoaXMuYnVmID0gbnVsbDtcbiAgICB9LFxuXG4gICAgLy8gPT09IFJFQURJTkcgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAgIHJlYWRGaWVsZHM6IGZ1bmN0aW9uKHJlYWRGaWVsZCwgcmVzdWx0LCBlbmQpIHtcbiAgICAgICAgZW5kID0gZW5kIHx8IHRoaXMubGVuZ3RoO1xuXG4gICAgICAgIHdoaWxlICh0aGlzLnBvcyA8IGVuZCkge1xuICAgICAgICAgICAgdmFyIHZhbCA9IHRoaXMucmVhZFZhcmludCgpLFxuICAgICAgICAgICAgICAgIHRhZyA9IHZhbCA+PiAzLFxuICAgICAgICAgICAgICAgIHN0YXJ0UG9zID0gdGhpcy5wb3M7XG5cbiAgICAgICAgICAgIHRoaXMudHlwZSA9IHZhbCAmIDB4NztcbiAgICAgICAgICAgIHJlYWRGaWVsZCh0YWcsIHJlc3VsdCwgdGhpcyk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnBvcyA9PT0gc3RhcnRQb3MpIHRoaXMuc2tpcCh2YWwpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSxcblxuICAgIHJlYWRNZXNzYWdlOiBmdW5jdGlvbihyZWFkRmllbGQsIHJlc3VsdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWFkRmllbGRzKHJlYWRGaWVsZCwgcmVzdWx0LCB0aGlzLnJlYWRWYXJpbnQoKSArIHRoaXMucG9zKTtcbiAgICB9LFxuXG4gICAgcmVhZEZpeGVkMzI6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgdmFsID0gcmVhZFVJbnQzMih0aGlzLmJ1ZiwgdGhpcy5wb3MpO1xuICAgICAgICB0aGlzLnBvcyArPSA0O1xuICAgICAgICByZXR1cm4gdmFsO1xuICAgIH0sXG5cbiAgICByZWFkU0ZpeGVkMzI6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgdmFsID0gcmVhZEludDMyKHRoaXMuYnVmLCB0aGlzLnBvcyk7XG4gICAgICAgIHRoaXMucG9zICs9IDQ7XG4gICAgICAgIHJldHVybiB2YWw7XG4gICAgfSxcblxuICAgIC8vIDY0LWJpdCBpbnQgaGFuZGxpbmcgaXMgYmFzZWQgb24gZ2l0aHViLmNvbS9kcHcvbm9kZS1idWZmZXItbW9yZS1pbnRzIChNSVQtbGljZW5zZWQpXG5cbiAgICByZWFkRml4ZWQ2NDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciB2YWwgPSByZWFkVUludDMyKHRoaXMuYnVmLCB0aGlzLnBvcykgKyByZWFkVUludDMyKHRoaXMuYnVmLCB0aGlzLnBvcyArIDQpICogU0hJRlRfTEVGVF8zMjtcbiAgICAgICAgdGhpcy5wb3MgKz0gODtcbiAgICAgICAgcmV0dXJuIHZhbDtcbiAgICB9LFxuXG4gICAgcmVhZFNGaXhlZDY0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIHZhbCA9IHJlYWRVSW50MzIodGhpcy5idWYsIHRoaXMucG9zKSArIHJlYWRJbnQzMih0aGlzLmJ1ZiwgdGhpcy5wb3MgKyA0KSAqIFNISUZUX0xFRlRfMzI7XG4gICAgICAgIHRoaXMucG9zICs9IDg7XG4gICAgICAgIHJldHVybiB2YWw7XG4gICAgfSxcblxuICAgIHJlYWRGbG9hdDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciB2YWwgPSBpZWVlNzU0LnJlYWQodGhpcy5idWYsIHRoaXMucG9zLCB0cnVlLCAyMywgNCk7XG4gICAgICAgIHRoaXMucG9zICs9IDQ7XG4gICAgICAgIHJldHVybiB2YWw7XG4gICAgfSxcblxuICAgIHJlYWREb3VibGU6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgdmFsID0gaWVlZTc1NC5yZWFkKHRoaXMuYnVmLCB0aGlzLnBvcywgdHJ1ZSwgNTIsIDgpO1xuICAgICAgICB0aGlzLnBvcyArPSA4O1xuICAgICAgICByZXR1cm4gdmFsO1xuICAgIH0sXG5cbiAgICByZWFkVmFyaW50OiBmdW5jdGlvbihpc1NpZ25lZCkge1xuICAgICAgICB2YXIgYnVmID0gdGhpcy5idWYsXG4gICAgICAgICAgICB2YWwsIGI7XG5cbiAgICAgICAgYiA9IGJ1Zlt0aGlzLnBvcysrXTsgdmFsICA9ICBiICYgMHg3ZjsgICAgICAgIGlmIChiIDwgMHg4MCkgcmV0dXJuIHZhbDtcbiAgICAgICAgYiA9IGJ1Zlt0aGlzLnBvcysrXTsgdmFsIHw9IChiICYgMHg3ZikgPDwgNzsgIGlmIChiIDwgMHg4MCkgcmV0dXJuIHZhbDtcbiAgICAgICAgYiA9IGJ1Zlt0aGlzLnBvcysrXTsgdmFsIHw9IChiICYgMHg3ZikgPDwgMTQ7IGlmIChiIDwgMHg4MCkgcmV0dXJuIHZhbDtcbiAgICAgICAgYiA9IGJ1Zlt0aGlzLnBvcysrXTsgdmFsIHw9IChiICYgMHg3ZikgPDwgMjE7IGlmIChiIDwgMHg4MCkgcmV0dXJuIHZhbDtcbiAgICAgICAgYiA9IGJ1Zlt0aGlzLnBvc107ICAgdmFsIHw9IChiICYgMHgwZikgPDwgMjg7XG5cbiAgICAgICAgcmV0dXJuIHJlYWRWYXJpbnRSZW1haW5kZXIodmFsLCBpc1NpZ25lZCwgdGhpcyk7XG4gICAgfSxcblxuICAgIHJlYWRWYXJpbnQ2NDogZnVuY3Rpb24oKSB7IC8vIGZvciBjb21wYXRpYmlsaXR5IHdpdGggdjIuMC4xXG4gICAgICAgIHJldHVybiB0aGlzLnJlYWRWYXJpbnQodHJ1ZSk7XG4gICAgfSxcblxuICAgIHJlYWRTVmFyaW50OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIG51bSA9IHRoaXMucmVhZFZhcmludCgpO1xuICAgICAgICByZXR1cm4gbnVtICUgMiA9PT0gMSA/IChudW0gKyAxKSAvIC0yIDogbnVtIC8gMjsgLy8gemlnemFnIGVuY29kaW5nXG4gICAgfSxcblxuICAgIHJlYWRCb29sZWFuOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIEJvb2xlYW4odGhpcy5yZWFkVmFyaW50KCkpO1xuICAgIH0sXG5cbiAgICByZWFkU3RyaW5nOiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGVuZCA9IHRoaXMucmVhZFZhcmludCgpICsgdGhpcy5wb3M7XG4gICAgICAgIHZhciBwb3MgPSB0aGlzLnBvcztcbiAgICAgICAgdGhpcy5wb3MgPSBlbmQ7XG5cbiAgICAgICAgaWYgKGVuZCAtIHBvcyA+PSBURVhUX0RFQ09ERVJfTUlOX0xFTkdUSCAmJiB1dGY4VGV4dERlY29kZXIpIHtcbiAgICAgICAgICAgIC8vIGxvbmdlciBzdHJpbmdzIGFyZSBmYXN0IHdpdGggdGhlIGJ1aWx0LWluIGJyb3dzZXIgVGV4dERlY29kZXIgQVBJXG4gICAgICAgICAgICByZXR1cm4gcmVhZFV0ZjhUZXh0RGVjb2Rlcih0aGlzLmJ1ZiwgcG9zLCBlbmQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHNob3J0IHN0cmluZ3MgYXJlIGZhc3Qgd2l0aCBvdXIgY3VzdG9tIGltcGxlbWVudGF0aW9uXG4gICAgICAgIHJldHVybiByZWFkVXRmOCh0aGlzLmJ1ZiwgcG9zLCBlbmQpO1xuICAgIH0sXG5cbiAgICByZWFkQnl0ZXM6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgZW5kID0gdGhpcy5yZWFkVmFyaW50KCkgKyB0aGlzLnBvcyxcbiAgICAgICAgICAgIGJ1ZmZlciA9IHRoaXMuYnVmLnN1YmFycmF5KHRoaXMucG9zLCBlbmQpO1xuICAgICAgICB0aGlzLnBvcyA9IGVuZDtcbiAgICAgICAgcmV0dXJuIGJ1ZmZlcjtcbiAgICB9LFxuXG4gICAgLy8gdmVyYm9zZSBmb3IgcGVyZm9ybWFuY2UgcmVhc29uczsgZG9lc24ndCBhZmZlY3QgZ3ppcHBlZCBzaXplXG5cbiAgICByZWFkUGFja2VkVmFyaW50OiBmdW5jdGlvbihhcnIsIGlzU2lnbmVkKSB7XG4gICAgICAgIGlmICh0aGlzLnR5cGUgIT09IFBiZi5CeXRlcykgcmV0dXJuIGFyci5wdXNoKHRoaXMucmVhZFZhcmludChpc1NpZ25lZCkpO1xuICAgICAgICB2YXIgZW5kID0gcmVhZFBhY2tlZEVuZCh0aGlzKTtcbiAgICAgICAgYXJyID0gYXJyIHx8IFtdO1xuICAgICAgICB3aGlsZSAodGhpcy5wb3MgPCBlbmQpIGFyci5wdXNoKHRoaXMucmVhZFZhcmludChpc1NpZ25lZCkpO1xuICAgICAgICByZXR1cm4gYXJyO1xuICAgIH0sXG4gICAgcmVhZFBhY2tlZFNWYXJpbnQ6IGZ1bmN0aW9uKGFycikge1xuICAgICAgICBpZiAodGhpcy50eXBlICE9PSBQYmYuQnl0ZXMpIHJldHVybiBhcnIucHVzaCh0aGlzLnJlYWRTVmFyaW50KCkpO1xuICAgICAgICB2YXIgZW5kID0gcmVhZFBhY2tlZEVuZCh0aGlzKTtcbiAgICAgICAgYXJyID0gYXJyIHx8IFtdO1xuICAgICAgICB3aGlsZSAodGhpcy5wb3MgPCBlbmQpIGFyci5wdXNoKHRoaXMucmVhZFNWYXJpbnQoKSk7XG4gICAgICAgIHJldHVybiBhcnI7XG4gICAgfSxcbiAgICByZWFkUGFja2VkQm9vbGVhbjogZnVuY3Rpb24oYXJyKSB7XG4gICAgICAgIGlmICh0aGlzLnR5cGUgIT09IFBiZi5CeXRlcykgcmV0dXJuIGFyci5wdXNoKHRoaXMucmVhZEJvb2xlYW4oKSk7XG4gICAgICAgIHZhciBlbmQgPSByZWFkUGFja2VkRW5kKHRoaXMpO1xuICAgICAgICBhcnIgPSBhcnIgfHwgW107XG4gICAgICAgIHdoaWxlICh0aGlzLnBvcyA8IGVuZCkgYXJyLnB1c2godGhpcy5yZWFkQm9vbGVhbigpKTtcbiAgICAgICAgcmV0dXJuIGFycjtcbiAgICB9LFxuICAgIHJlYWRQYWNrZWRGbG9hdDogZnVuY3Rpb24oYXJyKSB7XG4gICAgICAgIGlmICh0aGlzLnR5cGUgIT09IFBiZi5CeXRlcykgcmV0dXJuIGFyci5wdXNoKHRoaXMucmVhZEZsb2F0KCkpO1xuICAgICAgICB2YXIgZW5kID0gcmVhZFBhY2tlZEVuZCh0aGlzKTtcbiAgICAgICAgYXJyID0gYXJyIHx8IFtdO1xuICAgICAgICB3aGlsZSAodGhpcy5wb3MgPCBlbmQpIGFyci5wdXNoKHRoaXMucmVhZEZsb2F0KCkpO1xuICAgICAgICByZXR1cm4gYXJyO1xuICAgIH0sXG4gICAgcmVhZFBhY2tlZERvdWJsZTogZnVuY3Rpb24oYXJyKSB7XG4gICAgICAgIGlmICh0aGlzLnR5cGUgIT09IFBiZi5CeXRlcykgcmV0dXJuIGFyci5wdXNoKHRoaXMucmVhZERvdWJsZSgpKTtcbiAgICAgICAgdmFyIGVuZCA9IHJlYWRQYWNrZWRFbmQodGhpcyk7XG4gICAgICAgIGFyciA9IGFyciB8fCBbXTtcbiAgICAgICAgd2hpbGUgKHRoaXMucG9zIDwgZW5kKSBhcnIucHVzaCh0aGlzLnJlYWREb3VibGUoKSk7XG4gICAgICAgIHJldHVybiBhcnI7XG4gICAgfSxcbiAgICByZWFkUGFja2VkRml4ZWQzMjogZnVuY3Rpb24oYXJyKSB7XG4gICAgICAgIGlmICh0aGlzLnR5cGUgIT09IFBiZi5CeXRlcykgcmV0dXJuIGFyci5wdXNoKHRoaXMucmVhZEZpeGVkMzIoKSk7XG4gICAgICAgIHZhciBlbmQgPSByZWFkUGFja2VkRW5kKHRoaXMpO1xuICAgICAgICBhcnIgPSBhcnIgfHwgW107XG4gICAgICAgIHdoaWxlICh0aGlzLnBvcyA8IGVuZCkgYXJyLnB1c2godGhpcy5yZWFkRml4ZWQzMigpKTtcbiAgICAgICAgcmV0dXJuIGFycjtcbiAgICB9LFxuICAgIHJlYWRQYWNrZWRTRml4ZWQzMjogZnVuY3Rpb24oYXJyKSB7XG4gICAgICAgIGlmICh0aGlzLnR5cGUgIT09IFBiZi5CeXRlcykgcmV0dXJuIGFyci5wdXNoKHRoaXMucmVhZFNGaXhlZDMyKCkpO1xuICAgICAgICB2YXIgZW5kID0gcmVhZFBhY2tlZEVuZCh0aGlzKTtcbiAgICAgICAgYXJyID0gYXJyIHx8IFtdO1xuICAgICAgICB3aGlsZSAodGhpcy5wb3MgPCBlbmQpIGFyci5wdXNoKHRoaXMucmVhZFNGaXhlZDMyKCkpO1xuICAgICAgICByZXR1cm4gYXJyO1xuICAgIH0sXG4gICAgcmVhZFBhY2tlZEZpeGVkNjQ6IGZ1bmN0aW9uKGFycikge1xuICAgICAgICBpZiAodGhpcy50eXBlICE9PSBQYmYuQnl0ZXMpIHJldHVybiBhcnIucHVzaCh0aGlzLnJlYWRGaXhlZDY0KCkpO1xuICAgICAgICB2YXIgZW5kID0gcmVhZFBhY2tlZEVuZCh0aGlzKTtcbiAgICAgICAgYXJyID0gYXJyIHx8IFtdO1xuICAgICAgICB3aGlsZSAodGhpcy5wb3MgPCBlbmQpIGFyci5wdXNoKHRoaXMucmVhZEZpeGVkNjQoKSk7XG4gICAgICAgIHJldHVybiBhcnI7XG4gICAgfSxcbiAgICByZWFkUGFja2VkU0ZpeGVkNjQ6IGZ1bmN0aW9uKGFycikge1xuICAgICAgICBpZiAodGhpcy50eXBlICE9PSBQYmYuQnl0ZXMpIHJldHVybiBhcnIucHVzaCh0aGlzLnJlYWRTRml4ZWQ2NCgpKTtcbiAgICAgICAgdmFyIGVuZCA9IHJlYWRQYWNrZWRFbmQodGhpcyk7XG4gICAgICAgIGFyciA9IGFyciB8fCBbXTtcbiAgICAgICAgd2hpbGUgKHRoaXMucG9zIDwgZW5kKSBhcnIucHVzaCh0aGlzLnJlYWRTRml4ZWQ2NCgpKTtcbiAgICAgICAgcmV0dXJuIGFycjtcbiAgICB9LFxuXG4gICAgc2tpcDogZnVuY3Rpb24odmFsKSB7XG4gICAgICAgIHZhciB0eXBlID0gdmFsICYgMHg3O1xuICAgICAgICBpZiAodHlwZSA9PT0gUGJmLlZhcmludCkgd2hpbGUgKHRoaXMuYnVmW3RoaXMucG9zKytdID4gMHg3Zikge31cbiAgICAgICAgZWxzZSBpZiAodHlwZSA9PT0gUGJmLkJ5dGVzKSB0aGlzLnBvcyA9IHRoaXMucmVhZFZhcmludCgpICsgdGhpcy5wb3M7XG4gICAgICAgIGVsc2UgaWYgKHR5cGUgPT09IFBiZi5GaXhlZDMyKSB0aGlzLnBvcyArPSA0O1xuICAgICAgICBlbHNlIGlmICh0eXBlID09PSBQYmYuRml4ZWQ2NCkgdGhpcy5wb3MgKz0gODtcbiAgICAgICAgZWxzZSB0aHJvdyBuZXcgRXJyb3IoJ1VuaW1wbGVtZW50ZWQgdHlwZTogJyArIHR5cGUpO1xuICAgIH0sXG5cbiAgICAvLyA9PT0gV1JJVElORyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gICAgd3JpdGVUYWc6IGZ1bmN0aW9uKHRhZywgdHlwZSkge1xuICAgICAgICB0aGlzLndyaXRlVmFyaW50KCh0YWcgPDwgMykgfCB0eXBlKTtcbiAgICB9LFxuXG4gICAgcmVhbGxvYzogZnVuY3Rpb24obWluKSB7XG4gICAgICAgIHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aCB8fCAxNjtcblxuICAgICAgICB3aGlsZSAobGVuZ3RoIDwgdGhpcy5wb3MgKyBtaW4pIGxlbmd0aCAqPSAyO1xuXG4gICAgICAgIGlmIChsZW5ndGggIT09IHRoaXMubGVuZ3RoKSB7XG4gICAgICAgICAgICB2YXIgYnVmID0gbmV3IFVpbnQ4QXJyYXkobGVuZ3RoKTtcbiAgICAgICAgICAgIGJ1Zi5zZXQodGhpcy5idWYpO1xuICAgICAgICAgICAgdGhpcy5idWYgPSBidWY7XG4gICAgICAgICAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aDtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBmaW5pc2g6IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLmxlbmd0aCA9IHRoaXMucG9zO1xuICAgICAgICB0aGlzLnBvcyA9IDA7XG4gICAgICAgIHJldHVybiB0aGlzLmJ1Zi5zdWJhcnJheSgwLCB0aGlzLmxlbmd0aCk7XG4gICAgfSxcblxuICAgIHdyaXRlRml4ZWQzMjogZnVuY3Rpb24odmFsKSB7XG4gICAgICAgIHRoaXMucmVhbGxvYyg0KTtcbiAgICAgICAgd3JpdGVJbnQzMih0aGlzLmJ1ZiwgdmFsLCB0aGlzLnBvcyk7XG4gICAgICAgIHRoaXMucG9zICs9IDQ7XG4gICAgfSxcblxuICAgIHdyaXRlU0ZpeGVkMzI6IGZ1bmN0aW9uKHZhbCkge1xuICAgICAgICB0aGlzLnJlYWxsb2MoNCk7XG4gICAgICAgIHdyaXRlSW50MzIodGhpcy5idWYsIHZhbCwgdGhpcy5wb3MpO1xuICAgICAgICB0aGlzLnBvcyArPSA0O1xuICAgIH0sXG5cbiAgICB3cml0ZUZpeGVkNjQ6IGZ1bmN0aW9uKHZhbCkge1xuICAgICAgICB0aGlzLnJlYWxsb2MoOCk7XG4gICAgICAgIHdyaXRlSW50MzIodGhpcy5idWYsIHZhbCAmIC0xLCB0aGlzLnBvcyk7XG4gICAgICAgIHdyaXRlSW50MzIodGhpcy5idWYsIE1hdGguZmxvb3IodmFsICogU0hJRlRfUklHSFRfMzIpLCB0aGlzLnBvcyArIDQpO1xuICAgICAgICB0aGlzLnBvcyArPSA4O1xuICAgIH0sXG5cbiAgICB3cml0ZVNGaXhlZDY0OiBmdW5jdGlvbih2YWwpIHtcbiAgICAgICAgdGhpcy5yZWFsbG9jKDgpO1xuICAgICAgICB3cml0ZUludDMyKHRoaXMuYnVmLCB2YWwgJiAtMSwgdGhpcy5wb3MpO1xuICAgICAgICB3cml0ZUludDMyKHRoaXMuYnVmLCBNYXRoLmZsb29yKHZhbCAqIFNISUZUX1JJR0hUXzMyKSwgdGhpcy5wb3MgKyA0KTtcbiAgICAgICAgdGhpcy5wb3MgKz0gODtcbiAgICB9LFxuXG4gICAgd3JpdGVWYXJpbnQ6IGZ1bmN0aW9uKHZhbCkge1xuICAgICAgICB2YWwgPSArdmFsIHx8IDA7XG5cbiAgICAgICAgaWYgKHZhbCA+IDB4ZmZmZmZmZiB8fCB2YWwgPCAwKSB7XG4gICAgICAgICAgICB3cml0ZUJpZ1ZhcmludCh2YWwsIHRoaXMpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5yZWFsbG9jKDQpO1xuXG4gICAgICAgIHRoaXMuYnVmW3RoaXMucG9zKytdID0gICAgICAgICAgIHZhbCAmIDB4N2YgIHwgKHZhbCA+IDB4N2YgPyAweDgwIDogMCk7IGlmICh2YWwgPD0gMHg3ZikgcmV0dXJuO1xuICAgICAgICB0aGlzLmJ1Zlt0aGlzLnBvcysrXSA9ICgodmFsID4+Pj0gNykgJiAweDdmKSB8ICh2YWwgPiAweDdmID8gMHg4MCA6IDApOyBpZiAodmFsIDw9IDB4N2YpIHJldHVybjtcbiAgICAgICAgdGhpcy5idWZbdGhpcy5wb3MrK10gPSAoKHZhbCA+Pj49IDcpICYgMHg3ZikgfCAodmFsID4gMHg3ZiA/IDB4ODAgOiAwKTsgaWYgKHZhbCA8PSAweDdmKSByZXR1cm47XG4gICAgICAgIHRoaXMuYnVmW3RoaXMucG9zKytdID0gICAodmFsID4+PiA3KSAmIDB4N2Y7XG4gICAgfSxcblxuICAgIHdyaXRlU1ZhcmludDogZnVuY3Rpb24odmFsKSB7XG4gICAgICAgIHRoaXMud3JpdGVWYXJpbnQodmFsIDwgMCA/IC12YWwgKiAyIC0gMSA6IHZhbCAqIDIpO1xuICAgIH0sXG5cbiAgICB3cml0ZUJvb2xlYW46IGZ1bmN0aW9uKHZhbCkge1xuICAgICAgICB0aGlzLndyaXRlVmFyaW50KEJvb2xlYW4odmFsKSk7XG4gICAgfSxcblxuICAgIHdyaXRlU3RyaW5nOiBmdW5jdGlvbihzdHIpIHtcbiAgICAgICAgc3RyID0gU3RyaW5nKHN0cik7XG4gICAgICAgIHRoaXMucmVhbGxvYyhzdHIubGVuZ3RoICogNCk7XG5cbiAgICAgICAgdGhpcy5wb3MrKzsgLy8gcmVzZXJ2ZSAxIGJ5dGUgZm9yIHNob3J0IHN0cmluZyBsZW5ndGhcblxuICAgICAgICB2YXIgc3RhcnRQb3MgPSB0aGlzLnBvcztcbiAgICAgICAgLy8gd3JpdGUgdGhlIHN0cmluZyBkaXJlY3RseSB0byB0aGUgYnVmZmVyIGFuZCBzZWUgaG93IG11Y2ggd2FzIHdyaXR0ZW5cbiAgICAgICAgdGhpcy5wb3MgPSB3cml0ZVV0ZjgodGhpcy5idWYsIHN0ciwgdGhpcy5wb3MpO1xuICAgICAgICB2YXIgbGVuID0gdGhpcy5wb3MgLSBzdGFydFBvcztcblxuICAgICAgICBpZiAobGVuID49IDB4ODApIG1ha2VSb29tRm9yRXh0cmFMZW5ndGgoc3RhcnRQb3MsIGxlbiwgdGhpcyk7XG5cbiAgICAgICAgLy8gZmluYWxseSwgd3JpdGUgdGhlIG1lc3NhZ2UgbGVuZ3RoIGluIHRoZSByZXNlcnZlZCBwbGFjZSBhbmQgcmVzdG9yZSB0aGUgcG9zaXRpb25cbiAgICAgICAgdGhpcy5wb3MgPSBzdGFydFBvcyAtIDE7XG4gICAgICAgIHRoaXMud3JpdGVWYXJpbnQobGVuKTtcbiAgICAgICAgdGhpcy5wb3MgKz0gbGVuO1xuICAgIH0sXG5cbiAgICB3cml0ZUZsb2F0OiBmdW5jdGlvbih2YWwpIHtcbiAgICAgICAgdGhpcy5yZWFsbG9jKDQpO1xuICAgICAgICBpZWVlNzU0LndyaXRlKHRoaXMuYnVmLCB2YWwsIHRoaXMucG9zLCB0cnVlLCAyMywgNCk7XG4gICAgICAgIHRoaXMucG9zICs9IDQ7XG4gICAgfSxcblxuICAgIHdyaXRlRG91YmxlOiBmdW5jdGlvbih2YWwpIHtcbiAgICAgICAgdGhpcy5yZWFsbG9jKDgpO1xuICAgICAgICBpZWVlNzU0LndyaXRlKHRoaXMuYnVmLCB2YWwsIHRoaXMucG9zLCB0cnVlLCA1MiwgOCk7XG4gICAgICAgIHRoaXMucG9zICs9IDg7XG4gICAgfSxcblxuICAgIHdyaXRlQnl0ZXM6IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgICB2YXIgbGVuID0gYnVmZmVyLmxlbmd0aDtcbiAgICAgICAgdGhpcy53cml0ZVZhcmludChsZW4pO1xuICAgICAgICB0aGlzLnJlYWxsb2MobGVuKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykgdGhpcy5idWZbdGhpcy5wb3MrK10gPSBidWZmZXJbaV07XG4gICAgfSxcblxuICAgIHdyaXRlUmF3TWVzc2FnZTogZnVuY3Rpb24oZm4sIG9iaikge1xuICAgICAgICB0aGlzLnBvcysrOyAvLyByZXNlcnZlIDEgYnl0ZSBmb3Igc2hvcnQgbWVzc2FnZSBsZW5ndGhcblxuICAgICAgICAvLyB3cml0ZSB0aGUgbWVzc2FnZSBkaXJlY3RseSB0byB0aGUgYnVmZmVyIGFuZCBzZWUgaG93IG11Y2ggd2FzIHdyaXR0ZW5cbiAgICAgICAgdmFyIHN0YXJ0UG9zID0gdGhpcy5wb3M7XG4gICAgICAgIGZuKG9iaiwgdGhpcyk7XG4gICAgICAgIHZhciBsZW4gPSB0aGlzLnBvcyAtIHN0YXJ0UG9zO1xuXG4gICAgICAgIGlmIChsZW4gPj0gMHg4MCkgbWFrZVJvb21Gb3JFeHRyYUxlbmd0aChzdGFydFBvcywgbGVuLCB0aGlzKTtcblxuICAgICAgICAvLyBmaW5hbGx5LCB3cml0ZSB0aGUgbWVzc2FnZSBsZW5ndGggaW4gdGhlIHJlc2VydmVkIHBsYWNlIGFuZCByZXN0b3JlIHRoZSBwb3NpdGlvblxuICAgICAgICB0aGlzLnBvcyA9IHN0YXJ0UG9zIC0gMTtcbiAgICAgICAgdGhpcy53cml0ZVZhcmludChsZW4pO1xuICAgICAgICB0aGlzLnBvcyArPSBsZW47XG4gICAgfSxcblxuICAgIHdyaXRlTWVzc2FnZTogZnVuY3Rpb24odGFnLCBmbiwgb2JqKSB7XG4gICAgICAgIHRoaXMud3JpdGVUYWcodGFnLCBQYmYuQnl0ZXMpO1xuICAgICAgICB0aGlzLndyaXRlUmF3TWVzc2FnZShmbiwgb2JqKTtcbiAgICB9LFxuXG4gICAgd3JpdGVQYWNrZWRWYXJpbnQ6ICAgZnVuY3Rpb24odGFnLCBhcnIpIHsgaWYgKGFyci5sZW5ndGgpIHRoaXMud3JpdGVNZXNzYWdlKHRhZywgd3JpdGVQYWNrZWRWYXJpbnQsIGFycik7ICAgfSxcbiAgICB3cml0ZVBhY2tlZFNWYXJpbnQ6ICBmdW5jdGlvbih0YWcsIGFycikgeyBpZiAoYXJyLmxlbmd0aCkgdGhpcy53cml0ZU1lc3NhZ2UodGFnLCB3cml0ZVBhY2tlZFNWYXJpbnQsIGFycik7ICB9LFxuICAgIHdyaXRlUGFja2VkQm9vbGVhbjogIGZ1bmN0aW9uKHRhZywgYXJyKSB7IGlmIChhcnIubGVuZ3RoKSB0aGlzLndyaXRlTWVzc2FnZSh0YWcsIHdyaXRlUGFja2VkQm9vbGVhbiwgYXJyKTsgIH0sXG4gICAgd3JpdGVQYWNrZWRGbG9hdDogICAgZnVuY3Rpb24odGFnLCBhcnIpIHsgaWYgKGFyci5sZW5ndGgpIHRoaXMud3JpdGVNZXNzYWdlKHRhZywgd3JpdGVQYWNrZWRGbG9hdCwgYXJyKTsgICAgfSxcbiAgICB3cml0ZVBhY2tlZERvdWJsZTogICBmdW5jdGlvbih0YWcsIGFycikgeyBpZiAoYXJyLmxlbmd0aCkgdGhpcy53cml0ZU1lc3NhZ2UodGFnLCB3cml0ZVBhY2tlZERvdWJsZSwgYXJyKTsgICB9LFxuICAgIHdyaXRlUGFja2VkRml4ZWQzMjogIGZ1bmN0aW9uKHRhZywgYXJyKSB7IGlmIChhcnIubGVuZ3RoKSB0aGlzLndyaXRlTWVzc2FnZSh0YWcsIHdyaXRlUGFja2VkRml4ZWQzMiwgYXJyKTsgIH0sXG4gICAgd3JpdGVQYWNrZWRTRml4ZWQzMjogZnVuY3Rpb24odGFnLCBhcnIpIHsgaWYgKGFyci5sZW5ndGgpIHRoaXMud3JpdGVNZXNzYWdlKHRhZywgd3JpdGVQYWNrZWRTRml4ZWQzMiwgYXJyKTsgfSxcbiAgICB3cml0ZVBhY2tlZEZpeGVkNjQ6ICBmdW5jdGlvbih0YWcsIGFycikgeyBpZiAoYXJyLmxlbmd0aCkgdGhpcy53cml0ZU1lc3NhZ2UodGFnLCB3cml0ZVBhY2tlZEZpeGVkNjQsIGFycik7ICB9LFxuICAgIHdyaXRlUGFja2VkU0ZpeGVkNjQ6IGZ1bmN0aW9uKHRhZywgYXJyKSB7IGlmIChhcnIubGVuZ3RoKSB0aGlzLndyaXRlTWVzc2FnZSh0YWcsIHdyaXRlUGFja2VkU0ZpeGVkNjQsIGFycik7IH0sXG5cbiAgICB3cml0ZUJ5dGVzRmllbGQ6IGZ1bmN0aW9uKHRhZywgYnVmZmVyKSB7XG4gICAgICAgIHRoaXMud3JpdGVUYWcodGFnLCBQYmYuQnl0ZXMpO1xuICAgICAgICB0aGlzLndyaXRlQnl0ZXMoYnVmZmVyKTtcbiAgICB9LFxuICAgIHdyaXRlRml4ZWQzMkZpZWxkOiBmdW5jdGlvbih0YWcsIHZhbCkge1xuICAgICAgICB0aGlzLndyaXRlVGFnKHRhZywgUGJmLkZpeGVkMzIpO1xuICAgICAgICB0aGlzLndyaXRlRml4ZWQzMih2YWwpO1xuICAgIH0sXG4gICAgd3JpdGVTRml4ZWQzMkZpZWxkOiBmdW5jdGlvbih0YWcsIHZhbCkge1xuICAgICAgICB0aGlzLndyaXRlVGFnKHRhZywgUGJmLkZpeGVkMzIpO1xuICAgICAgICB0aGlzLndyaXRlU0ZpeGVkMzIodmFsKTtcbiAgICB9LFxuICAgIHdyaXRlRml4ZWQ2NEZpZWxkOiBmdW5jdGlvbih0YWcsIHZhbCkge1xuICAgICAgICB0aGlzLndyaXRlVGFnKHRhZywgUGJmLkZpeGVkNjQpO1xuICAgICAgICB0aGlzLndyaXRlRml4ZWQ2NCh2YWwpO1xuICAgIH0sXG4gICAgd3JpdGVTRml4ZWQ2NEZpZWxkOiBmdW5jdGlvbih0YWcsIHZhbCkge1xuICAgICAgICB0aGlzLndyaXRlVGFnKHRhZywgUGJmLkZpeGVkNjQpO1xuICAgICAgICB0aGlzLndyaXRlU0ZpeGVkNjQodmFsKTtcbiAgICB9LFxuICAgIHdyaXRlVmFyaW50RmllbGQ6IGZ1bmN0aW9uKHRhZywgdmFsKSB7XG4gICAgICAgIHRoaXMud3JpdGVUYWcodGFnLCBQYmYuVmFyaW50KTtcbiAgICAgICAgdGhpcy53cml0ZVZhcmludCh2YWwpO1xuICAgIH0sXG4gICAgd3JpdGVTVmFyaW50RmllbGQ6IGZ1bmN0aW9uKHRhZywgdmFsKSB7XG4gICAgICAgIHRoaXMud3JpdGVUYWcodGFnLCBQYmYuVmFyaW50KTtcbiAgICAgICAgdGhpcy53cml0ZVNWYXJpbnQodmFsKTtcbiAgICB9LFxuICAgIHdyaXRlU3RyaW5nRmllbGQ6IGZ1bmN0aW9uKHRhZywgc3RyKSB7XG4gICAgICAgIHRoaXMud3JpdGVUYWcodGFnLCBQYmYuQnl0ZXMpO1xuICAgICAgICB0aGlzLndyaXRlU3RyaW5nKHN0cik7XG4gICAgfSxcbiAgICB3cml0ZUZsb2F0RmllbGQ6IGZ1bmN0aW9uKHRhZywgdmFsKSB7XG4gICAgICAgIHRoaXMud3JpdGVUYWcodGFnLCBQYmYuRml4ZWQzMik7XG4gICAgICAgIHRoaXMud3JpdGVGbG9hdCh2YWwpO1xuICAgIH0sXG4gICAgd3JpdGVEb3VibGVGaWVsZDogZnVuY3Rpb24odGFnLCB2YWwpIHtcbiAgICAgICAgdGhpcy53cml0ZVRhZyh0YWcsIFBiZi5GaXhlZDY0KTtcbiAgICAgICAgdGhpcy53cml0ZURvdWJsZSh2YWwpO1xuICAgIH0sXG4gICAgd3JpdGVCb29sZWFuRmllbGQ6IGZ1bmN0aW9uKHRhZywgdmFsKSB7XG4gICAgICAgIHRoaXMud3JpdGVWYXJpbnRGaWVsZCh0YWcsIEJvb2xlYW4odmFsKSk7XG4gICAgfVxufTtcblxuZnVuY3Rpb24gcmVhZFZhcmludFJlbWFpbmRlcihsLCBzLCBwKSB7XG4gICAgdmFyIGJ1ZiA9IHAuYnVmLFxuICAgICAgICBoLCBiO1xuXG4gICAgYiA9IGJ1ZltwLnBvcysrXTsgaCAgPSAoYiAmIDB4NzApID4+IDQ7ICBpZiAoYiA8IDB4ODApIHJldHVybiB0b051bShsLCBoLCBzKTtcbiAgICBiID0gYnVmW3AucG9zKytdOyBoIHw9IChiICYgMHg3ZikgPDwgMzsgIGlmIChiIDwgMHg4MCkgcmV0dXJuIHRvTnVtKGwsIGgsIHMpO1xuICAgIGIgPSBidWZbcC5wb3MrK107IGggfD0gKGIgJiAweDdmKSA8PCAxMDsgaWYgKGIgPCAweDgwKSByZXR1cm4gdG9OdW0obCwgaCwgcyk7XG4gICAgYiA9IGJ1ZltwLnBvcysrXTsgaCB8PSAoYiAmIDB4N2YpIDw8IDE3OyBpZiAoYiA8IDB4ODApIHJldHVybiB0b051bShsLCBoLCBzKTtcbiAgICBiID0gYnVmW3AucG9zKytdOyBoIHw9IChiICYgMHg3ZikgPDwgMjQ7IGlmIChiIDwgMHg4MCkgcmV0dXJuIHRvTnVtKGwsIGgsIHMpO1xuICAgIGIgPSBidWZbcC5wb3MrK107IGggfD0gKGIgJiAweDAxKSA8PCAzMTsgaWYgKGIgPCAweDgwKSByZXR1cm4gdG9OdW0obCwgaCwgcyk7XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIHZhcmludCBub3QgbW9yZSB0aGFuIDEwIGJ5dGVzJyk7XG59XG5cbmZ1bmN0aW9uIHJlYWRQYWNrZWRFbmQocGJmKSB7XG4gICAgcmV0dXJuIHBiZi50eXBlID09PSBQYmYuQnl0ZXMgP1xuICAgICAgICBwYmYucmVhZFZhcmludCgpICsgcGJmLnBvcyA6IHBiZi5wb3MgKyAxO1xufVxuXG5mdW5jdGlvbiB0b051bShsb3csIGhpZ2gsIGlzU2lnbmVkKSB7XG4gICAgaWYgKGlzU2lnbmVkKSB7XG4gICAgICAgIHJldHVybiBoaWdoICogMHgxMDAwMDAwMDAgKyAobG93ID4+PiAwKTtcbiAgICB9XG5cbiAgICByZXR1cm4gKChoaWdoID4+PiAwKSAqIDB4MTAwMDAwMDAwKSArIChsb3cgPj4+IDApO1xufVxuXG5mdW5jdGlvbiB3cml0ZUJpZ1ZhcmludCh2YWwsIHBiZikge1xuICAgIHZhciBsb3csIGhpZ2g7XG5cbiAgICBpZiAodmFsID49IDApIHtcbiAgICAgICAgbG93ICA9ICh2YWwgJSAweDEwMDAwMDAwMCkgfCAwO1xuICAgICAgICBoaWdoID0gKHZhbCAvIDB4MTAwMDAwMDAwKSB8IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgbG93ICA9IH4oLXZhbCAlIDB4MTAwMDAwMDAwKTtcbiAgICAgICAgaGlnaCA9IH4oLXZhbCAvIDB4MTAwMDAwMDAwKTtcblxuICAgICAgICBpZiAobG93IF4gMHhmZmZmZmZmZikge1xuICAgICAgICAgICAgbG93ID0gKGxvdyArIDEpIHwgMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxvdyA9IDA7XG4gICAgICAgICAgICBoaWdoID0gKGhpZ2ggKyAxKSB8IDA7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodmFsID49IDB4MTAwMDAwMDAwMDAwMDAwMDAgfHwgdmFsIDwgLTB4MTAwMDAwMDAwMDAwMDAwMDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdHaXZlbiB2YXJpbnQgZG9lc25cXCd0IGZpdCBpbnRvIDEwIGJ5dGVzJyk7XG4gICAgfVxuXG4gICAgcGJmLnJlYWxsb2MoMTApO1xuXG4gICAgd3JpdGVCaWdWYXJpbnRMb3cobG93LCBoaWdoLCBwYmYpO1xuICAgIHdyaXRlQmlnVmFyaW50SGlnaChoaWdoLCBwYmYpO1xufVxuXG5mdW5jdGlvbiB3cml0ZUJpZ1ZhcmludExvdyhsb3csIGhpZ2gsIHBiZikge1xuICAgIHBiZi5idWZbcGJmLnBvcysrXSA9IGxvdyAmIDB4N2YgfCAweDgwOyBsb3cgPj4+PSA3O1xuICAgIHBiZi5idWZbcGJmLnBvcysrXSA9IGxvdyAmIDB4N2YgfCAweDgwOyBsb3cgPj4+PSA3O1xuICAgIHBiZi5idWZbcGJmLnBvcysrXSA9IGxvdyAmIDB4N2YgfCAweDgwOyBsb3cgPj4+PSA3O1xuICAgIHBiZi5idWZbcGJmLnBvcysrXSA9IGxvdyAmIDB4N2YgfCAweDgwOyBsb3cgPj4+PSA3O1xuICAgIHBiZi5idWZbcGJmLnBvc10gICA9IGxvdyAmIDB4N2Y7XG59XG5cbmZ1bmN0aW9uIHdyaXRlQmlnVmFyaW50SGlnaChoaWdoLCBwYmYpIHtcbiAgICB2YXIgbHNiID0gKGhpZ2ggJiAweDA3KSA8PCA0O1xuXG4gICAgcGJmLmJ1ZltwYmYucG9zKytdIHw9IGxzYiAgICAgICAgIHwgKChoaWdoID4+Pj0gMykgPyAweDgwIDogMCk7IGlmICghaGlnaCkgcmV0dXJuO1xuICAgIHBiZi5idWZbcGJmLnBvcysrXSAgPSBoaWdoICYgMHg3ZiB8ICgoaGlnaCA+Pj49IDcpID8gMHg4MCA6IDApOyBpZiAoIWhpZ2gpIHJldHVybjtcbiAgICBwYmYuYnVmW3BiZi5wb3MrK10gID0gaGlnaCAmIDB4N2YgfCAoKGhpZ2ggPj4+PSA3KSA/IDB4ODAgOiAwKTsgaWYgKCFoaWdoKSByZXR1cm47XG4gICAgcGJmLmJ1ZltwYmYucG9zKytdICA9IGhpZ2ggJiAweDdmIHwgKChoaWdoID4+Pj0gNykgPyAweDgwIDogMCk7IGlmICghaGlnaCkgcmV0dXJuO1xuICAgIHBiZi5idWZbcGJmLnBvcysrXSAgPSBoaWdoICYgMHg3ZiB8ICgoaGlnaCA+Pj49IDcpID8gMHg4MCA6IDApOyBpZiAoIWhpZ2gpIHJldHVybjtcbiAgICBwYmYuYnVmW3BiZi5wb3MrK10gID0gaGlnaCAmIDB4N2Y7XG59XG5cbmZ1bmN0aW9uIG1ha2VSb29tRm9yRXh0cmFMZW5ndGgoc3RhcnRQb3MsIGxlbiwgcGJmKSB7XG4gICAgdmFyIGV4dHJhTGVuID1cbiAgICAgICAgbGVuIDw9IDB4M2ZmZiA/IDEgOlxuICAgICAgICBsZW4gPD0gMHgxZmZmZmYgPyAyIDpcbiAgICAgICAgbGVuIDw9IDB4ZmZmZmZmZiA/IDMgOiBNYXRoLmZsb29yKE1hdGgubG9nKGxlbikgLyAoTWF0aC5MTjIgKiA3KSk7XG5cbiAgICAvLyBpZiAxIGJ5dGUgaXNuJ3QgZW5vdWdoIGZvciBlbmNvZGluZyBtZXNzYWdlIGxlbmd0aCwgc2hpZnQgdGhlIGRhdGEgdG8gdGhlIHJpZ2h0XG4gICAgcGJmLnJlYWxsb2MoZXh0cmFMZW4pO1xuICAgIGZvciAodmFyIGkgPSBwYmYucG9zIC0gMTsgaSA+PSBzdGFydFBvczsgaS0tKSBwYmYuYnVmW2kgKyBleHRyYUxlbl0gPSBwYmYuYnVmW2ldO1xufVxuXG5mdW5jdGlvbiB3cml0ZVBhY2tlZFZhcmludChhcnIsIHBiZikgICB7IGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSBwYmYud3JpdGVWYXJpbnQoYXJyW2ldKTsgICB9XG5mdW5jdGlvbiB3cml0ZVBhY2tlZFNWYXJpbnQoYXJyLCBwYmYpICB7IGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSBwYmYud3JpdGVTVmFyaW50KGFycltpXSk7ICB9XG5mdW5jdGlvbiB3cml0ZVBhY2tlZEZsb2F0KGFyciwgcGJmKSAgICB7IGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSBwYmYud3JpdGVGbG9hdChhcnJbaV0pOyAgICB9XG5mdW5jdGlvbiB3cml0ZVBhY2tlZERvdWJsZShhcnIsIHBiZikgICB7IGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSBwYmYud3JpdGVEb3VibGUoYXJyW2ldKTsgICB9XG5mdW5jdGlvbiB3cml0ZVBhY2tlZEJvb2xlYW4oYXJyLCBwYmYpICB7IGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSBwYmYud3JpdGVCb29sZWFuKGFycltpXSk7ICB9XG5mdW5jdGlvbiB3cml0ZVBhY2tlZEZpeGVkMzIoYXJyLCBwYmYpICB7IGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSBwYmYud3JpdGVGaXhlZDMyKGFycltpXSk7ICB9XG5mdW5jdGlvbiB3cml0ZVBhY2tlZFNGaXhlZDMyKGFyciwgcGJmKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSBwYmYud3JpdGVTRml4ZWQzMihhcnJbaV0pOyB9XG5mdW5jdGlvbiB3cml0ZVBhY2tlZEZpeGVkNjQoYXJyLCBwYmYpICB7IGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSBwYmYud3JpdGVGaXhlZDY0KGFycltpXSk7ICB9XG5mdW5jdGlvbiB3cml0ZVBhY2tlZFNGaXhlZDY0KGFyciwgcGJmKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSBwYmYud3JpdGVTRml4ZWQ2NChhcnJbaV0pOyB9XG5cbi8vIEJ1ZmZlciBjb2RlIGJlbG93IGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9idWZmZXIsIE1JVC1saWNlbnNlZFxuXG5mdW5jdGlvbiByZWFkVUludDMyKGJ1ZiwgcG9zKSB7XG4gICAgcmV0dXJuICgoYnVmW3Bvc10pIHxcbiAgICAgICAgKGJ1Zltwb3MgKyAxXSA8PCA4KSB8XG4gICAgICAgIChidWZbcG9zICsgMl0gPDwgMTYpKSArXG4gICAgICAgIChidWZbcG9zICsgM10gKiAweDEwMDAwMDApO1xufVxuXG5mdW5jdGlvbiB3cml0ZUludDMyKGJ1ZiwgdmFsLCBwb3MpIHtcbiAgICBidWZbcG9zXSA9IHZhbDtcbiAgICBidWZbcG9zICsgMV0gPSAodmFsID4+PiA4KTtcbiAgICBidWZbcG9zICsgMl0gPSAodmFsID4+PiAxNik7XG4gICAgYnVmW3BvcyArIDNdID0gKHZhbCA+Pj4gMjQpO1xufVxuXG5mdW5jdGlvbiByZWFkSW50MzIoYnVmLCBwb3MpIHtcbiAgICByZXR1cm4gKChidWZbcG9zXSkgfFxuICAgICAgICAoYnVmW3BvcyArIDFdIDw8IDgpIHxcbiAgICAgICAgKGJ1Zltwb3MgKyAyXSA8PCAxNikpICtcbiAgICAgICAgKGJ1Zltwb3MgKyAzXSA8PCAyNCk7XG59XG5cbmZ1bmN0aW9uIHJlYWRVdGY4KGJ1ZiwgcG9zLCBlbmQpIHtcbiAgICB2YXIgc3RyID0gJyc7XG4gICAgdmFyIGkgPSBwb3M7XG5cbiAgICB3aGlsZSAoaSA8IGVuZCkge1xuICAgICAgICB2YXIgYjAgPSBidWZbaV07XG4gICAgICAgIHZhciBjID0gbnVsbDsgLy8gY29kZXBvaW50XG4gICAgICAgIHZhciBieXRlc1BlclNlcXVlbmNlID1cbiAgICAgICAgICAgIGIwID4gMHhFRiA/IDQgOlxuICAgICAgICAgICAgYjAgPiAweERGID8gMyA6XG4gICAgICAgICAgICBiMCA+IDB4QkYgPyAyIDogMTtcblxuICAgICAgICBpZiAoaSArIGJ5dGVzUGVyU2VxdWVuY2UgPiBlbmQpIGJyZWFrO1xuXG4gICAgICAgIHZhciBiMSwgYjIsIGIzO1xuXG4gICAgICAgIGlmIChieXRlc1BlclNlcXVlbmNlID09PSAxKSB7XG4gICAgICAgICAgICBpZiAoYjAgPCAweDgwKSB7XG4gICAgICAgICAgICAgICAgYyA9IGIwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzUGVyU2VxdWVuY2UgPT09IDIpIHtcbiAgICAgICAgICAgIGIxID0gYnVmW2kgKyAxXTtcbiAgICAgICAgICAgIGlmICgoYjEgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgICAgIGMgPSAoYjAgJiAweDFGKSA8PCAweDYgfCAoYjEgJiAweDNGKTtcbiAgICAgICAgICAgICAgICBpZiAoYyA8PSAweDdGKSB7XG4gICAgICAgICAgICAgICAgICAgIGMgPSBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChieXRlc1BlclNlcXVlbmNlID09PSAzKSB7XG4gICAgICAgICAgICBiMSA9IGJ1ZltpICsgMV07XG4gICAgICAgICAgICBiMiA9IGJ1ZltpICsgMl07XG4gICAgICAgICAgICBpZiAoKGIxICYgMHhDMCkgPT09IDB4ODAgJiYgKGIyICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgICAgICBjID0gKGIwICYgMHhGKSA8PCAweEMgfCAoYjEgJiAweDNGKSA8PCAweDYgfCAoYjIgJiAweDNGKTtcbiAgICAgICAgICAgICAgICBpZiAoYyA8PSAweDdGRiB8fCAoYyA+PSAweEQ4MDAgJiYgYyA8PSAweERGRkYpKSB7XG4gICAgICAgICAgICAgICAgICAgIGMgPSBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChieXRlc1BlclNlcXVlbmNlID09PSA0KSB7XG4gICAgICAgICAgICBiMSA9IGJ1ZltpICsgMV07XG4gICAgICAgICAgICBiMiA9IGJ1ZltpICsgMl07XG4gICAgICAgICAgICBiMyA9IGJ1ZltpICsgM107XG4gICAgICAgICAgICBpZiAoKGIxICYgMHhDMCkgPT09IDB4ODAgJiYgKGIyICYgMHhDMCkgPT09IDB4ODAgJiYgKGIzICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgICAgICBjID0gKGIwICYgMHhGKSA8PCAweDEyIHwgKGIxICYgMHgzRikgPDwgMHhDIHwgKGIyICYgMHgzRikgPDwgMHg2IHwgKGIzICYgMHgzRik7XG4gICAgICAgICAgICAgICAgaWYgKGMgPD0gMHhGRkZGIHx8IGMgPj0gMHgxMTAwMDApIHtcbiAgICAgICAgICAgICAgICAgICAgYyA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGMgPT09IG51bGwpIHtcbiAgICAgICAgICAgIGMgPSAweEZGRkQ7XG4gICAgICAgICAgICBieXRlc1BlclNlcXVlbmNlID0gMTtcblxuICAgICAgICB9IGVsc2UgaWYgKGMgPiAweEZGRkYpIHtcbiAgICAgICAgICAgIGMgLT0gMHgxMDAwMDtcbiAgICAgICAgICAgIHN0ciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGMgPj4+IDEwICYgMHgzRkYgfCAweEQ4MDApO1xuICAgICAgICAgICAgYyA9IDB4REMwMCB8IGMgJiAweDNGRjtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0ciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGMpO1xuICAgICAgICBpICs9IGJ5dGVzUGVyU2VxdWVuY2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN0cjtcbn1cblxuZnVuY3Rpb24gcmVhZFV0ZjhUZXh0RGVjb2RlcihidWYsIHBvcywgZW5kKSB7XG4gICAgcmV0dXJuIHV0ZjhUZXh0RGVjb2Rlci5kZWNvZGUoYnVmLnN1YmFycmF5KHBvcywgZW5kKSk7XG59XG5cbmZ1bmN0aW9uIHdyaXRlVXRmOChidWYsIHN0ciwgcG9zKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIGMsIGxlYWQ7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgYyA9IHN0ci5jaGFyQ29kZUF0KGkpOyAvLyBjb2RlIHBvaW50XG5cbiAgICAgICAgaWYgKGMgPiAweEQ3RkYgJiYgYyA8IDB4RTAwMCkge1xuICAgICAgICAgICAgaWYgKGxlYWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoYyA8IDB4REMwMCkge1xuICAgICAgICAgICAgICAgICAgICBidWZbcG9zKytdID0gMHhFRjtcbiAgICAgICAgICAgICAgICAgICAgYnVmW3BvcysrXSA9IDB4QkY7XG4gICAgICAgICAgICAgICAgICAgIGJ1Zltwb3MrK10gPSAweEJEO1xuICAgICAgICAgICAgICAgICAgICBsZWFkID0gYztcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYyA9IGxlYWQgLSAweEQ4MDAgPDwgMTAgfCBjIC0gMHhEQzAwIHwgMHgxMDAwMDtcbiAgICAgICAgICAgICAgICAgICAgbGVhZCA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAoYyA+IDB4REJGRiB8fCAoaSArIDEgPT09IHN0ci5sZW5ndGgpKSB7XG4gICAgICAgICAgICAgICAgICAgIGJ1Zltwb3MrK10gPSAweEVGO1xuICAgICAgICAgICAgICAgICAgICBidWZbcG9zKytdID0gMHhCRjtcbiAgICAgICAgICAgICAgICAgICAgYnVmW3BvcysrXSA9IDB4QkQ7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbGVhZCA9IGM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGxlYWQpIHtcbiAgICAgICAgICAgIGJ1Zltwb3MrK10gPSAweEVGO1xuICAgICAgICAgICAgYnVmW3BvcysrXSA9IDB4QkY7XG4gICAgICAgICAgICBidWZbcG9zKytdID0gMHhCRDtcbiAgICAgICAgICAgIGxlYWQgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGMgPCAweDgwKSB7XG4gICAgICAgICAgICBidWZbcG9zKytdID0gYztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChjIDwgMHg4MDApIHtcbiAgICAgICAgICAgICAgICBidWZbcG9zKytdID0gYyA+PiAweDYgfCAweEMwO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAoYyA8IDB4MTAwMDApIHtcbiAgICAgICAgICAgICAgICAgICAgYnVmW3BvcysrXSA9IGMgPj4gMHhDIHwgMHhFMDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBidWZbcG9zKytdID0gYyA+PiAweDEyIHwgMHhGMDtcbiAgICAgICAgICAgICAgICAgICAgYnVmW3BvcysrXSA9IGMgPj4gMHhDICYgMHgzRiB8IDB4ODA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJ1Zltwb3MrK10gPSBjID4+IDB4NiAmIDB4M0YgfCAweDgwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnVmW3BvcysrXSA9IGMgJiAweDNGIHwgMHg4MDtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcG9zO1xufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtBbHBoYUltYWdlfSBmcm9tICcuLi91dGlsL2ltYWdlLmpzJztcblxuaW1wb3J0IFByb3RvYnVmIGZyb20gJ3BiZic7XG5jb25zdCBib3JkZXIgPSAzO1xuXG5pbXBvcnQgdHlwZSB7U3R5bGVHbHlwaH0gZnJvbSAnLi9zdHlsZV9nbHlwaC5qcyc7XG5cbmZ1bmN0aW9uIHJlYWRGb250c3RhY2tzKHRhZzogbnVtYmVyLCBnbHlwaERhdGE6IHtnbHlwaHM6IEFycmF5PFN0eWxlR2x5cGg+LCBhc2NlbmRlcj86IG51bWJlciwgZGVzY2VuZGVyPzogbnVtYmVyfSwgcGJmOiBQcm90b2J1Zikge1xuICAgIGdseXBoRGF0YS5nbHlwaHMgPSBbXTtcbiAgICBpZiAodGFnID09PSAxKSB7XG4gICAgICAgIHBiZi5yZWFkTWVzc2FnZShyZWFkRm9udHN0YWNrLCBnbHlwaERhdGEpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gcmVhZEZvbnRzdGFjayh0YWc6IG51bWJlciwgIGdseXBoRGF0YToge2dseXBoczogQXJyYXk8U3R5bGVHbHlwaD4sIGFzY2VuZGVyPzogbnVtYmVyLCBkZXNjZW5kZXI/OiBudW1iZXJ9LCBwYmY6IFByb3RvYnVmKSB7XG4gICAgaWYgKHRhZyA9PT0gMykge1xuICAgICAgICBjb25zdCB7aWQsIGJpdG1hcCwgd2lkdGgsIGhlaWdodCwgbGVmdCwgdG9wLCBhZHZhbmNlfSA9IHBiZi5yZWFkTWVzc2FnZShyZWFkR2x5cGgsIHt9KTtcbiAgICAgICAgZ2x5cGhEYXRhLmdseXBocy5wdXNoKHtcbiAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgYml0bWFwOiBuZXcgQWxwaGFJbWFnZSh7XG4gICAgICAgICAgICAgICAgd2lkdGg6IHdpZHRoICsgMiAqIGJvcmRlcixcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IGhlaWdodCArIDIgKiBib3JkZXJcbiAgICAgICAgICAgIH0sIGJpdG1hcCksXG4gICAgICAgICAgICBtZXRyaWNzOiB7d2lkdGgsIGhlaWdodCwgbGVmdCwgdG9wLCBhZHZhbmNlfVxuICAgICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHRhZyA9PT0gNCkge1xuICAgICAgICBnbHlwaERhdGEuYXNjZW5kZXIgPSBwYmYucmVhZFNWYXJpbnQoKTtcbiAgICB9IGVsc2UgaWYgKHRhZyA9PT0gNSkge1xuICAgICAgICBnbHlwaERhdGEuZGVzY2VuZGVyID0gcGJmLnJlYWRTVmFyaW50KCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiByZWFkR2x5cGgodGFnOiBudW1iZXIsIGdseXBoOiBPYmplY3QsIHBiZjogUHJvdG9idWYpIHtcbiAgICBpZiAodGFnID09PSAxKSBnbHlwaC5pZCA9IHBiZi5yZWFkVmFyaW50KCk7XG4gICAgZWxzZSBpZiAodGFnID09PSAyKSBnbHlwaC5iaXRtYXAgPSBwYmYucmVhZEJ5dGVzKCk7XG4gICAgZWxzZSBpZiAodGFnID09PSAzKSBnbHlwaC53aWR0aCA9IHBiZi5yZWFkVmFyaW50KCk7XG4gICAgZWxzZSBpZiAodGFnID09PSA0KSBnbHlwaC5oZWlnaHQgPSBwYmYucmVhZFZhcmludCgpO1xuICAgIGVsc2UgaWYgKHRhZyA9PT0gNSkgZ2x5cGgubGVmdCA9IHBiZi5yZWFkU1ZhcmludCgpO1xuICAgIGVsc2UgaWYgKHRhZyA9PT0gNikgZ2x5cGgudG9wID0gcGJmLnJlYWRTVmFyaW50KCk7XG4gICAgZWxzZSBpZiAodGFnID09PSA3KSBnbHlwaC5hZHZhbmNlID0gcGJmLnJlYWRWYXJpbnQoKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKGRhdGE6IEFycmF5QnVmZmVyIHwgVWludDhBcnJheSk6IHtnbHlwaHM6IEFycmF5PFN0eWxlR2x5cGg+LCBhc2NlbmRlcj86IG51bWJlciwgZGVzY2VuZGVyPzogbnVtYmVyfSB7XG4gICAgcmV0dXJuIG5ldyBQcm90b2J1ZihkYXRhKS5yZWFkRmllbGRzKHJlYWRGb250c3RhY2tzLCB7fSk7XG59XG5cbmV4cG9ydCBjb25zdCBHTFlQSF9QQkZfQk9SREVSID0gYm9yZGVyO1xuIiwiXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBwb3RwYWNrKGJveGVzKSB7XG5cbiAgICAvLyBjYWxjdWxhdGUgdG90YWwgYm94IGFyZWEgYW5kIG1heGltdW0gYm94IHdpZHRoXG4gICAgbGV0IGFyZWEgPSAwO1xuICAgIGxldCBtYXhXaWR0aCA9IDA7XG5cbiAgICBmb3IgKGNvbnN0IGJveCBvZiBib3hlcykge1xuICAgICAgICBhcmVhICs9IGJveC53ICogYm94Lmg7XG4gICAgICAgIG1heFdpZHRoID0gTWF0aC5tYXgobWF4V2lkdGgsIGJveC53KTtcbiAgICB9XG5cbiAgICAvLyBzb3J0IHRoZSBib3hlcyBmb3IgaW5zZXJ0aW9uIGJ5IGhlaWdodCwgZGVzY2VuZGluZ1xuICAgIGJveGVzLnNvcnQoKGEsIGIpID0+IGIuaCAtIGEuaCk7XG5cbiAgICAvLyBhaW0gZm9yIGEgc3F1YXJpc2ggcmVzdWx0aW5nIGNvbnRhaW5lcixcbiAgICAvLyBzbGlnaHRseSBhZGp1c3RlZCBmb3Igc3ViLTEwMCUgc3BhY2UgdXRpbGl6YXRpb25cbiAgICBjb25zdCBzdGFydFdpZHRoID0gTWF0aC5tYXgoTWF0aC5jZWlsKE1hdGguc3FydChhcmVhIC8gMC45NSkpLCBtYXhXaWR0aCk7XG5cbiAgICAvLyBzdGFydCB3aXRoIGEgc2luZ2xlIGVtcHR5IHNwYWNlLCB1bmJvdW5kZWQgYXQgdGhlIGJvdHRvbVxuICAgIGNvbnN0IHNwYWNlcyA9IFt7eDogMCwgeTogMCwgdzogc3RhcnRXaWR0aCwgaDogSW5maW5pdHl9XTtcblxuICAgIGxldCB3aWR0aCA9IDA7XG4gICAgbGV0IGhlaWdodCA9IDA7XG5cbiAgICBmb3IgKGNvbnN0IGJveCBvZiBib3hlcykge1xuICAgICAgICAvLyBsb29rIHRocm91Z2ggc3BhY2VzIGJhY2t3YXJkcyBzbyB0aGF0IHdlIGNoZWNrIHNtYWxsZXIgc3BhY2VzIGZpcnN0XG4gICAgICAgIGZvciAobGV0IGkgPSBzcGFjZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGNvbnN0IHNwYWNlID0gc3BhY2VzW2ldO1xuXG4gICAgICAgICAgICAvLyBsb29rIGZvciBlbXB0eSBzcGFjZXMgdGhhdCBjYW4gYWNjb21tb2RhdGUgdGhlIGN1cnJlbnQgYm94XG4gICAgICAgICAgICBpZiAoYm94LncgPiBzcGFjZS53IHx8IGJveC5oID4gc3BhY2UuaCkgY29udGludWU7XG5cbiAgICAgICAgICAgIC8vIGZvdW5kIHRoZSBzcGFjZTsgYWRkIHRoZSBib3ggdG8gaXRzIHRvcC1sZWZ0IGNvcm5lclxuICAgICAgICAgICAgLy8gfC0tLS0tLS18LS0tLS0tLXxcbiAgICAgICAgICAgIC8vIHwgIGJveCAgfCAgICAgICB8XG4gICAgICAgICAgICAvLyB8X19fX19fX3wgICAgICAgfFxuICAgICAgICAgICAgLy8gfCAgICAgICAgIHNwYWNlIHxcbiAgICAgICAgICAgIC8vIHxfX19fX19fX19fX19fX198XG4gICAgICAgICAgICBib3gueCA9IHNwYWNlLng7XG4gICAgICAgICAgICBib3gueSA9IHNwYWNlLnk7XG5cbiAgICAgICAgICAgIGhlaWdodCA9IE1hdGgubWF4KGhlaWdodCwgYm94LnkgKyBib3guaCk7XG4gICAgICAgICAgICB3aWR0aCA9IE1hdGgubWF4KHdpZHRoLCBib3gueCArIGJveC53KTtcblxuICAgICAgICAgICAgaWYgKGJveC53ID09PSBzcGFjZS53ICYmIGJveC5oID09PSBzcGFjZS5oKSB7XG4gICAgICAgICAgICAgICAgLy8gc3BhY2UgbWF0Y2hlcyB0aGUgYm94IGV4YWN0bHk7IHJlbW92ZSBpdFxuICAgICAgICAgICAgICAgIGNvbnN0IGxhc3QgPSBzcGFjZXMucG9wKCk7XG4gICAgICAgICAgICAgICAgaWYgKGkgPCBzcGFjZXMubGVuZ3RoKSBzcGFjZXNbaV0gPSBsYXN0O1xuXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGJveC5oID09PSBzcGFjZS5oKSB7XG4gICAgICAgICAgICAgICAgLy8gc3BhY2UgbWF0Y2hlcyB0aGUgYm94IGhlaWdodDsgdXBkYXRlIGl0IGFjY29yZGluZ2x5XG4gICAgICAgICAgICAgICAgLy8gfC0tLS0tLS18LS0tLS0tLS0tLS0tLS0tfFxuICAgICAgICAgICAgICAgIC8vIHwgIGJveCAgfCB1cGRhdGVkIHNwYWNlIHxcbiAgICAgICAgICAgICAgICAvLyB8X19fX19fX3xfX19fX19fX19fX19fX198XG4gICAgICAgICAgICAgICAgc3BhY2UueCArPSBib3gudztcbiAgICAgICAgICAgICAgICBzcGFjZS53IC09IGJveC53O1xuXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGJveC53ID09PSBzcGFjZS53KSB7XG4gICAgICAgICAgICAgICAgLy8gc3BhY2UgbWF0Y2hlcyB0aGUgYm94IHdpZHRoOyB1cGRhdGUgaXQgYWNjb3JkaW5nbHlcbiAgICAgICAgICAgICAgICAvLyB8LS0tLS0tLS0tLS0tLS0tfFxuICAgICAgICAgICAgICAgIC8vIHwgICAgICBib3ggICAgICB8XG4gICAgICAgICAgICAgICAgLy8gfF9fX19fX19fX19fX19fX3xcbiAgICAgICAgICAgICAgICAvLyB8IHVwZGF0ZWQgc3BhY2UgfFxuICAgICAgICAgICAgICAgIC8vIHxfX19fX19fX19fX19fX198XG4gICAgICAgICAgICAgICAgc3BhY2UueSArPSBib3guaDtcbiAgICAgICAgICAgICAgICBzcGFjZS5oIC09IGJveC5oO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIG90aGVyd2lzZSB0aGUgYm94IHNwbGl0cyB0aGUgc3BhY2UgaW50byB0d28gc3BhY2VzXG4gICAgICAgICAgICAgICAgLy8gfC0tLS0tLS18LS0tLS0tLS0tLS18XG4gICAgICAgICAgICAgICAgLy8gfCAgYm94ICB8IG5ldyBzcGFjZSB8XG4gICAgICAgICAgICAgICAgLy8gfF9fX19fX198X19fX19fX19fX198XG4gICAgICAgICAgICAgICAgLy8gfCB1cGRhdGVkIHNwYWNlICAgICB8XG4gICAgICAgICAgICAgICAgLy8gfF9fX19fX19fX19fX19fX19fX198XG4gICAgICAgICAgICAgICAgc3BhY2VzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICB4OiBzcGFjZS54ICsgYm94LncsXG4gICAgICAgICAgICAgICAgICAgIHk6IHNwYWNlLnksXG4gICAgICAgICAgICAgICAgICAgIHc6IHNwYWNlLncgLSBib3gudyxcbiAgICAgICAgICAgICAgICAgICAgaDogYm94LmhcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBzcGFjZS55ICs9IGJveC5oO1xuICAgICAgICAgICAgICAgIHNwYWNlLmggLT0gYm94Lmg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIHc6IHdpZHRoLCAvLyBjb250YWluZXIgd2lkdGhcbiAgICAgICAgaDogaGVpZ2h0LCAvLyBjb250YWluZXIgaGVpZ2h0XG4gICAgICAgIGZpbGw6IChhcmVhIC8gKHdpZHRoICogaGVpZ2h0KSkgfHwgMCAvLyBzcGFjZSB1dGlsaXphdGlvblxuICAgIH07XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge1JHQkFJbWFnZX0gZnJvbSAnLi4vdXRpbC9pbWFnZS5qcyc7XG5pbXBvcnQge3JlZ2lzdGVyfSBmcm9tICcuLi91dGlsL3dlYl93b3JrZXJfdHJhbnNmZXIuanMnO1xuaW1wb3J0IHBvdHBhY2sgZnJvbSAncG90cGFjayc7XG5cbmltcG9ydCB0eXBlIHtTdHlsZUltYWdlfSBmcm9tICcuLi9zdHlsZS9zdHlsZV9pbWFnZS5qcyc7XG5pbXBvcnQgdHlwZSBJbWFnZU1hbmFnZXIgZnJvbSAnLi9pbWFnZV9tYW5hZ2VyLmpzJztcbmltcG9ydCB0eXBlIFRleHR1cmUgZnJvbSAnLi90ZXh0dXJlLmpzJztcbmltcG9ydCB0eXBlIHtTcHJpdGVQb3NpdGlvbn0gZnJvbSAnLi4vdXRpbC9pbWFnZS5qcyc7XG5cbmNvbnN0IElNQUdFX1BBRERJTkc6IG51bWJlciA9IDE7XG5leHBvcnQge0lNQUdFX1BBRERJTkd9O1xuXG50eXBlIFJlY3QgPSB7XG4gICAgeDogbnVtYmVyLFxuICAgIHk6IG51bWJlcixcbiAgICB3OiBudW1iZXIsXG4gICAgaDogbnVtYmVyXG59O1xuXG5leHBvcnQgY2xhc3MgSW1hZ2VQb3NpdGlvbiBpbXBsZW1lbnRzIFNwcml0ZVBvc2l0aW9uIHtcbiAgICBwYWRkZWRSZWN0OiBSZWN0O1xuICAgIHBpeGVsUmF0aW86IG51bWJlcjtcbiAgICB2ZXJzaW9uOiBudW1iZXI7XG4gICAgc3RyZXRjaFk6ID9BcnJheTxbbnVtYmVyLCBudW1iZXJdPjtcbiAgICBzdHJldGNoWDogP0FycmF5PFtudW1iZXIsIG51bWJlcl0+O1xuICAgIGNvbnRlbnQ6ID9bbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcblxuICAgIGNvbnN0cnVjdG9yKHBhZGRlZFJlY3Q6IFJlY3QsIHtwaXhlbFJhdGlvLCB2ZXJzaW9uLCBzdHJldGNoWCwgc3RyZXRjaFksIGNvbnRlbnR9OiBTdHlsZUltYWdlKSB7XG4gICAgICAgIHRoaXMucGFkZGVkUmVjdCA9IHBhZGRlZFJlY3Q7XG4gICAgICAgIHRoaXMucGl4ZWxSYXRpbyA9IHBpeGVsUmF0aW87XG4gICAgICAgIHRoaXMuc3RyZXRjaFggPSBzdHJldGNoWDtcbiAgICAgICAgdGhpcy5zdHJldGNoWSA9IHN0cmV0Y2hZO1xuICAgICAgICB0aGlzLmNvbnRlbnQgPSBjb250ZW50O1xuICAgICAgICB0aGlzLnZlcnNpb24gPSB2ZXJzaW9uO1xuICAgIH1cblxuICAgIGdldCB0bCgpOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIHRoaXMucGFkZGVkUmVjdC54ICsgSU1BR0VfUEFERElORyxcbiAgICAgICAgICAgIHRoaXMucGFkZGVkUmVjdC55ICsgSU1BR0VfUEFERElOR1xuICAgICAgICBdO1xuICAgIH1cblxuICAgIGdldCBicigpOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIHRoaXMucGFkZGVkUmVjdC54ICsgdGhpcy5wYWRkZWRSZWN0LncgLSBJTUFHRV9QQURESU5HLFxuICAgICAgICAgICAgdGhpcy5wYWRkZWRSZWN0LnkgKyB0aGlzLnBhZGRlZFJlY3QuaCAtIElNQUdFX1BBRERJTkdcbiAgICAgICAgXTtcbiAgICB9XG5cbiAgICBnZXQgZGlzcGxheVNpemUoKTogW251bWJlciwgbnVtYmVyXSB7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICAodGhpcy5wYWRkZWRSZWN0LncgLSBJTUFHRV9QQURESU5HICogMikgLyB0aGlzLnBpeGVsUmF0aW8sXG4gICAgICAgICAgICAodGhpcy5wYWRkZWRSZWN0LmggLSBJTUFHRV9QQURESU5HICogMikgLyB0aGlzLnBpeGVsUmF0aW9cbiAgICAgICAgXTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEltYWdlQXRsYXMge1xuICAgIGltYWdlOiBSR0JBSW1hZ2U7XG4gICAgaWNvblBvc2l0aW9uczoge1tfOiBzdHJpbmddOiBJbWFnZVBvc2l0aW9ufTtcbiAgICBwYXR0ZXJuUG9zaXRpb25zOiB7W186IHN0cmluZ106IEltYWdlUG9zaXRpb259O1xuICAgIGhhdmVSZW5kZXJDYWxsYmFja3M6IEFycmF5PHN0cmluZz47XG4gICAgdXBsb2FkZWQ6ID9ib29sZWFuO1xuXG4gICAgY29uc3RydWN0b3IoaWNvbnM6IHtbXzogc3RyaW5nXTogU3R5bGVJbWFnZX0sIHBhdHRlcm5zOiB7W186IHN0cmluZ106IFN0eWxlSW1hZ2V9KSB7XG4gICAgICAgIGNvbnN0IGljb25Qb3NpdGlvbnMgPSB7fSwgcGF0dGVyblBvc2l0aW9ucyA9IHt9O1xuICAgICAgICB0aGlzLmhhdmVSZW5kZXJDYWxsYmFja3MgPSBbXTtcblxuICAgICAgICBjb25zdCBiaW5zID0gW107XG5cbiAgICAgICAgdGhpcy5hZGRJbWFnZXMoaWNvbnMsIGljb25Qb3NpdGlvbnMsIGJpbnMpO1xuICAgICAgICB0aGlzLmFkZEltYWdlcyhwYXR0ZXJucywgcGF0dGVyblBvc2l0aW9ucywgYmlucyk7XG5cbiAgICAgICAgY29uc3Qge3csIGh9ID0gcG90cGFjayhiaW5zKTtcbiAgICAgICAgY29uc3QgaW1hZ2UgPSBuZXcgUkdCQUltYWdlKHt3aWR0aDogdyB8fCAxLCBoZWlnaHQ6IGggfHwgMX0pO1xuXG4gICAgICAgIGZvciAoY29uc3QgaWQgaW4gaWNvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IHNyYyA9IGljb25zW2lkXTtcbiAgICAgICAgICAgIGNvbnN0IGJpbiA9IGljb25Qb3NpdGlvbnNbaWRdLnBhZGRlZFJlY3Q7XG4gICAgICAgICAgICBSR0JBSW1hZ2UuY29weShzcmMuZGF0YSwgaW1hZ2UsIHt4OiAwLCB5OiAwfSwge3g6IGJpbi54ICsgSU1BR0VfUEFERElORywgeTogYmluLnkgKyBJTUFHRV9QQURESU5HfSwgc3JjLmRhdGEpO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChjb25zdCBpZCBpbiBwYXR0ZXJucykge1xuICAgICAgICAgICAgY29uc3Qgc3JjID0gcGF0dGVybnNbaWRdO1xuICAgICAgICAgICAgY29uc3QgYmluID0gcGF0dGVyblBvc2l0aW9uc1tpZF0ucGFkZGVkUmVjdDtcbiAgICAgICAgICAgIGNvbnN0IHggPSBiaW4ueCArIElNQUdFX1BBRERJTkcsXG4gICAgICAgICAgICAgICAgeSA9IGJpbi55ICsgSU1BR0VfUEFERElORyxcbiAgICAgICAgICAgICAgICB3ID0gc3JjLmRhdGEud2lkdGgsXG4gICAgICAgICAgICAgICAgaCA9IHNyYy5kYXRhLmhlaWdodDtcblxuICAgICAgICAgICAgUkdCQUltYWdlLmNvcHkoc3JjLmRhdGEsIGltYWdlLCB7eDogMCwgeTogMH0sIHt4LCB5fSwgc3JjLmRhdGEpO1xuICAgICAgICAgICAgLy8gQWRkIDEgcGl4ZWwgd3JhcHBlZCBwYWRkaW5nIG9uIGVhY2ggc2lkZSBvZiB0aGUgaW1hZ2UuXG4gICAgICAgICAgICBSR0JBSW1hZ2UuY29weShzcmMuZGF0YSwgaW1hZ2UsIHt4OiAwLCB5OiBoIC0gMX0sIHt4LCB5OiB5IC0gMX0sIHt3aWR0aDogdywgaGVpZ2h0OiAxfSk7IC8vIFRcbiAgICAgICAgICAgIFJHQkFJbWFnZS5jb3B5KHNyYy5kYXRhLCBpbWFnZSwge3g6IDAsIHk6ICAgICAwfSwge3gsIHk6IHkgKyBofSwge3dpZHRoOiB3LCBoZWlnaHQ6IDF9KTsgLy8gQlxuICAgICAgICAgICAgUkdCQUltYWdlLmNvcHkoc3JjLmRhdGEsIGltYWdlLCB7eDogdyAtIDEsIHk6IDB9LCB7eDogeCAtIDEsIHl9LCB7d2lkdGg6IDEsIGhlaWdodDogaH0pOyAvLyBMXG4gICAgICAgICAgICBSR0JBSW1hZ2UuY29weShzcmMuZGF0YSwgaW1hZ2UsIHt4OiAwLCAgICAgeTogMH0sIHt4OiB4ICsgdywgeX0sIHt3aWR0aDogMSwgaGVpZ2h0OiBofSk7IC8vIFJcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuaW1hZ2UgPSBpbWFnZTtcbiAgICAgICAgdGhpcy5pY29uUG9zaXRpb25zID0gaWNvblBvc2l0aW9ucztcbiAgICAgICAgdGhpcy5wYXR0ZXJuUG9zaXRpb25zID0gcGF0dGVyblBvc2l0aW9ucztcbiAgICB9XG5cbiAgICBhZGRJbWFnZXMoaW1hZ2VzOiB7W186IHN0cmluZ106IFN0eWxlSW1hZ2V9LCBwb3NpdGlvbnM6IHtbXzogc3RyaW5nXTogSW1hZ2VQb3NpdGlvbn0sIGJpbnM6IEFycmF5PFJlY3Q+KSB7XG4gICAgICAgIGZvciAoY29uc3QgaWQgaW4gaW1hZ2VzKSB7XG4gICAgICAgICAgICBjb25zdCBzcmMgPSBpbWFnZXNbaWRdO1xuICAgICAgICAgICAgY29uc3QgYmluID0ge1xuICAgICAgICAgICAgICAgIHg6IDAsXG4gICAgICAgICAgICAgICAgeTogMCxcbiAgICAgICAgICAgICAgICB3OiBzcmMuZGF0YS53aWR0aCArIDIgKiBJTUFHRV9QQURESU5HLFxuICAgICAgICAgICAgICAgIGg6IHNyYy5kYXRhLmhlaWdodCArIDIgKiBJTUFHRV9QQURESU5HLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGJpbnMucHVzaChiaW4pO1xuICAgICAgICAgICAgcG9zaXRpb25zW2lkXSA9IG5ldyBJbWFnZVBvc2l0aW9uKGJpbiwgc3JjKTtcblxuICAgICAgICAgICAgaWYgKHNyYy5oYXNSZW5kZXJDYWxsYmFjaykge1xuICAgICAgICAgICAgICAgIHRoaXMuaGF2ZVJlbmRlckNhbGxiYWNrcy5wdXNoKGlkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHBhdGNoVXBkYXRlZEltYWdlcyhpbWFnZU1hbmFnZXI6IEltYWdlTWFuYWdlciwgdGV4dHVyZTogVGV4dHVyZSkge1xuICAgICAgICB0aGlzLmhhdmVSZW5kZXJDYWxsYmFja3MgPSB0aGlzLmhhdmVSZW5kZXJDYWxsYmFja3MuZmlsdGVyKGlkID0+IGltYWdlTWFuYWdlci5oYXNJbWFnZShpZCkpO1xuICAgICAgICBpbWFnZU1hbmFnZXIuZGlzcGF0Y2hSZW5kZXJDYWxsYmFja3ModGhpcy5oYXZlUmVuZGVyQ2FsbGJhY2tzKTtcbiAgICAgICAgZm9yIChjb25zdCBuYW1lIGluIGltYWdlTWFuYWdlci51cGRhdGVkSW1hZ2VzKSB7XG4gICAgICAgICAgICB0aGlzLnBhdGNoVXBkYXRlZEltYWdlKHRoaXMuaWNvblBvc2l0aW9uc1tuYW1lXSwgaW1hZ2VNYW5hZ2VyLmdldEltYWdlKG5hbWUpLCB0ZXh0dXJlKTtcbiAgICAgICAgICAgIHRoaXMucGF0Y2hVcGRhdGVkSW1hZ2UodGhpcy5wYXR0ZXJuUG9zaXRpb25zW25hbWVdLCBpbWFnZU1hbmFnZXIuZ2V0SW1hZ2UobmFtZSksIHRleHR1cmUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcGF0Y2hVcGRhdGVkSW1hZ2UocG9zaXRpb246ID9JbWFnZVBvc2l0aW9uLCBpbWFnZTogP1N0eWxlSW1hZ2UsIHRleHR1cmU6IFRleHR1cmUpIHtcbiAgICAgICAgaWYgKCFwb3NpdGlvbiB8fCAhaW1hZ2UpIHJldHVybjtcblxuICAgICAgICBpZiAocG9zaXRpb24udmVyc2lvbiA9PT0gaW1hZ2UudmVyc2lvbikgcmV0dXJuO1xuXG4gICAgICAgIHBvc2l0aW9uLnZlcnNpb24gPSBpbWFnZS52ZXJzaW9uO1xuICAgICAgICBjb25zdCBbeCwgeV0gPSBwb3NpdGlvbi50bDtcbiAgICAgICAgdGV4dHVyZS51cGRhdGUoaW1hZ2UuZGF0YSwgdW5kZWZpbmVkLCB7eCwgeX0pO1xuICAgIH1cblxufVxuXG5yZWdpc3RlcihJbWFnZVBvc2l0aW9uLCAnSW1hZ2VQb3NpdGlvbicpO1xucmVnaXN0ZXIoSW1hZ2VBdGxhcywgJ0ltYWdlQXRsYXMnKTtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCB7XG4gICAgY2hhckhhc1VwcmlnaHRWZXJ0aWNhbE9yaWVudGF0aW9uLFxuICAgIGNoYXJBbGxvd3NJZGVvZ3JhcGhpY0JyZWFraW5nLFxuICAgIGNoYXJJbkNvbXBsZXhTaGFwaW5nU2NyaXB0XG59IGZyb20gJy4uL3V0aWwvc2NyaXB0X2RldGVjdGlvbi5qcyc7XG5pbXBvcnQgdmVydGljYWxpemVQdW5jdHVhdGlvbiBmcm9tICcuLi91dGlsL3ZlcnRpY2FsaXplX3B1bmN0dWF0aW9uLmpzJztcbmltcG9ydCB7cGx1Z2luIGFzIHJ0bFRleHRQbHVnaW59IGZyb20gJy4uL3NvdXJjZS9ydGxfdGV4dF9wbHVnaW4uanMnO1xuaW1wb3J0IE9ORV9FTSBmcm9tICcuL29uZV9lbS5qcyc7XG5pbXBvcnQge3dhcm5PbmNlfSBmcm9tICcuLi91dGlsL3V0aWwuanMnO1xuXG5pbXBvcnQgdHlwZSB7U3R5bGVHbHlwaCwgR2x5cGhNZXRyaWNzfSBmcm9tICcuLi9zdHlsZS9zdHlsZV9nbHlwaC5qcyc7XG5pbXBvcnQge0dMWVBIX1BCRl9CT1JERVJ9IGZyb20gJy4uL3N0eWxlL3BhcnNlX2dseXBoX3BiZi5qcyc7XG5pbXBvcnQgdHlwZSB7SW1hZ2VQb3NpdGlvbn0gZnJvbSAnLi4vcmVuZGVyL2ltYWdlX2F0bGFzLmpzJztcbmltcG9ydCB7SU1BR0VfUEFERElOR30gZnJvbSAnLi4vcmVuZGVyL2ltYWdlX2F0bGFzLmpzJztcbmltcG9ydCB0eXBlIHtHbHlwaFJlY3QsIEdseXBoUG9zaXRpb25zfSBmcm9tICcuLi9yZW5kZXIvZ2x5cGhfYXRsYXMuanMnO1xuaW1wb3J0IEZvcm1hdHRlZCwge0Zvcm1hdHRlZFNlY3Rpb259IGZyb20gJy4uL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi90eXBlcy9mb3JtYXR0ZWQuanMnO1xuXG5jb25zdCBXcml0aW5nTW9kZSA9IHtcbiAgICBob3Jpem9udGFsOiAxLFxuICAgIHZlcnRpY2FsOiAyLFxuICAgIGhvcml6b250YWxPbmx5OiAzXG59O1xuXG5jb25zdCBTSEFQSU5HX0RFRkFVTFRfT0ZGU0VUID0gLTE3O1xuZXhwb3J0IHtzaGFwZVRleHQsIHNoYXBlSWNvbiwgZml0SWNvblRvVGV4dCwgZ2V0QW5jaG9yQWxpZ25tZW50LCBXcml0aW5nTW9kZSwgU0hBUElOR19ERUZBVUxUX09GRlNFVH07XG5cbi8vIFRoZSBwb3NpdGlvbiBvZiBhIGdseXBoIHJlbGF0aXZlIHRvIHRoZSB0ZXh0J3MgYW5jaG9yIHBvaW50LlxuZXhwb3J0IHR5cGUgUG9zaXRpb25lZEdseXBoID0ge1xuICAgIGdseXBoOiBudW1iZXIsXG4gICAgaW1hZ2VOYW1lOiBzdHJpbmcgfCBudWxsLFxuICAgIHg6IG51bWJlcixcbiAgICB5OiBudW1iZXIsXG4gICAgdmVydGljYWw6IGJvb2xlYW4sXG4gICAgc2NhbGU6IG51bWJlcixcbiAgICBmb250U3RhY2s6IHN0cmluZyxcbiAgICBzZWN0aW9uSW5kZXg6IG51bWJlcixcbiAgICBtZXRyaWNzOiBHbHlwaE1ldHJpY3MsXG4gICAgcmVjdDogR2x5cGhSZWN0IHwgbnVsbCxcbiAgICBsb2NhbEdseXBoPzogYm9vbGVhblxufTtcblxuZXhwb3J0IHR5cGUgUG9zaXRpb25lZExpbmUgPSB7XG4gICAgcG9zaXRpb25lZEdseXBoczogQXJyYXk8UG9zaXRpb25lZEdseXBoPixcbiAgICBsaW5lT2Zmc2V0OiBudW1iZXJcbn07XG5cbi8vIEEgY29sbGVjdGlvbiBvZiBwb3NpdGlvbmVkIGdseXBocyBhbmQgc29tZSBtZXRhZGF0YVxuZXhwb3J0IHR5cGUgU2hhcGluZyA9IHtcbiAgICBwb3NpdGlvbmVkTGluZXM6IEFycmF5PFBvc2l0aW9uZWRMaW5lPixcbiAgICB0b3A6IG51bWJlcixcbiAgICBib3R0b206IG51bWJlcixcbiAgICBsZWZ0OiBudW1iZXIsXG4gICAgcmlnaHQ6IG51bWJlcixcbiAgICB3cml0aW5nTW9kZTogMSB8IDIsXG4gICAgdGV4dDogc3RyaW5nLFxuICAgIGljb25zSW5UZXh0OiBib29sZWFuLFxuICAgIHZlcnRpY2FsaXphYmxlOiBib29sZWFuLFxuICAgIGhhc0Jhc2VsaW5lOiBib29sZWFuXG59O1xuXG50eXBlIEFuY2hvckFsaWdubWVudCA9IHt8XG4gICAgaG9yaXpvbnRhbEFsaWduOiBudW1iZXIsXG4gICAgdmVydGljYWxBbGlnbjogbnVtYmVyXG58fTtcblxuZnVuY3Rpb24gaXNFbXB0eShwb3NpdGlvbmVkTGluZXM6IEFycmF5PFBvc2l0aW9uZWRMaW5lPikge1xuICAgIGZvciAoY29uc3QgbGluZSBvZiBwb3NpdGlvbmVkTGluZXMpIHtcbiAgICAgICAgaWYgKGxpbmUucG9zaXRpb25lZEdseXBocy5sZW5ndGggIT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cblxuZXhwb3J0IHR5cGUgU3ltYm9sQW5jaG9yID0gJ2NlbnRlcicgfCAnbGVmdCcgfCAncmlnaHQnIHwgJ3RvcCcgfCAnYm90dG9tJyB8ICd0b3AtbGVmdCcgfCAndG9wLXJpZ2h0JyB8ICdib3R0b20tbGVmdCcgfCAnYm90dG9tLXJpZ2h0JztcbmV4cG9ydCB0eXBlIFRleHRKdXN0aWZ5ID0gJ2xlZnQnIHwgJ2NlbnRlcicgfCAncmlnaHQnO1xuXG4vLyBNYXggbnVtYmVyIG9mIGltYWdlcyBpbiBsYWJlbCBpcyA2NDAxIFUrRTAwMOKAk1UrRjhGRiB0aGF0IGNvdmVyc1xuLy8gQmFzaWMgTXVsdGlsaW5ndWFsIFBsYW5lIFVuaWNvZGUgUHJpdmF0ZSBVc2UgQXJlYSAoUFVBKS5cbmNvbnN0IFBVQWJlZ2luID0gMHhFMDAwO1xuY29uc3QgUFVBZW5kID0gMHhGOEZGO1xuXG5jbGFzcyBTZWN0aW9uT3B0aW9ucyB7XG4gICAgLy8gVGV4dCBvcHRpb25zXG4gICAgc2NhbGU6IG51bWJlcjtcbiAgICBmb250U3RhY2s6IHN0cmluZztcbiAgICAvLyBJbWFnZSBvcHRpb25zXG4gICAgaW1hZ2VOYW1lOiBzdHJpbmcgfCBudWxsO1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuc2NhbGUgPSAxLjA7XG4gICAgICAgIHRoaXMuZm9udFN0YWNrID0gXCJcIjtcbiAgICAgICAgdGhpcy5pbWFnZU5hbWUgPSBudWxsO1xuICAgIH1cblxuICAgIHN0YXRpYyBmb3JUZXh0KHNjYWxlOiA/bnVtYmVyLCBmb250U3RhY2s6IHN0cmluZyk6IFNlY3Rpb25PcHRpb25zIHtcbiAgICAgICAgY29uc3QgdGV4dE9wdGlvbnMgPSBuZXcgU2VjdGlvbk9wdGlvbnMoKTtcbiAgICAgICAgdGV4dE9wdGlvbnMuc2NhbGUgPSBzY2FsZSB8fCAxO1xuICAgICAgICB0ZXh0T3B0aW9ucy5mb250U3RhY2sgPSBmb250U3RhY2s7XG4gICAgICAgIHJldHVybiB0ZXh0T3B0aW9ucztcbiAgICB9XG5cbiAgICBzdGF0aWMgZm9ySW1hZ2UoaW1hZ2VOYW1lOiBzdHJpbmcpOiBTZWN0aW9uT3B0aW9ucyB7XG4gICAgICAgIGNvbnN0IGltYWdlT3B0aW9ucyA9IG5ldyBTZWN0aW9uT3B0aW9ucygpO1xuICAgICAgICBpbWFnZU9wdGlvbnMuaW1hZ2VOYW1lID0gaW1hZ2VOYW1lO1xuICAgICAgICByZXR1cm4gaW1hZ2VPcHRpb25zO1xuICAgIH1cblxufVxuXG5jbGFzcyBUYWdnZWRTdHJpbmcge1xuICAgIHRleHQ6IHN0cmluZztcbiAgICBzZWN0aW9uSW5kZXg6IEFycmF5PG51bWJlcj4gLy8gbWFwcyBlYWNoIGNoYXJhY3RlciBpbiAndGV4dCcgdG8gaXRzIGNvcnJlc3BvbmRpbmcgZW50cnkgaW4gJ3NlY3Rpb25zJ1xuICAgIHNlY3Rpb25zOiBBcnJheTxTZWN0aW9uT3B0aW9ucz5cbiAgICBpbWFnZVNlY3Rpb25JRDogbnVtYmVyIHwgbnVsbDtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnRleHQgPSBcIlwiO1xuICAgICAgICB0aGlzLnNlY3Rpb25JbmRleCA9IFtdO1xuICAgICAgICB0aGlzLnNlY3Rpb25zID0gW107XG4gICAgICAgIHRoaXMuaW1hZ2VTZWN0aW9uSUQgPSBudWxsO1xuICAgIH1cblxuICAgIHN0YXRpYyBmcm9tRmVhdHVyZSh0ZXh0OiBGb3JtYXR0ZWQsIGRlZmF1bHRGb250U3RhY2s6IHN0cmluZyk6IFRhZ2dlZFN0cmluZyB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IG5ldyBUYWdnZWRTdHJpbmcoKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0ZXh0LnNlY3Rpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBzZWN0aW9uID0gdGV4dC5zZWN0aW9uc1tpXTtcbiAgICAgICAgICAgIGlmICghc2VjdGlvbi5pbWFnZSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdC5hZGRUZXh0U2VjdGlvbihzZWN0aW9uLCBkZWZhdWx0Rm9udFN0YWNrKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LmFkZEltYWdlU2VjdGlvbihzZWN0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIGxlbmd0aCgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy50ZXh0Lmxlbmd0aDtcbiAgICB9XG5cbiAgICBnZXRTZWN0aW9uKGluZGV4OiBudW1iZXIpOiBTZWN0aW9uT3B0aW9ucyB7XG4gICAgICAgIHJldHVybiB0aGlzLnNlY3Rpb25zW3RoaXMuc2VjdGlvbkluZGV4W2luZGV4XV07XG4gICAgfVxuXG4gICAgZ2V0U2VjdGlvbnMoKTogQXJyYXk8U2VjdGlvbk9wdGlvbnM+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VjdGlvbnM7XG4gICAgfVxuXG4gICAgZ2V0U2VjdGlvbkluZGV4KGluZGV4OiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5zZWN0aW9uSW5kZXhbaW5kZXhdO1xuICAgIH1cblxuICAgIGdldENoYXJDb2RlKGluZGV4OiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy50ZXh0LmNoYXJDb2RlQXQoaW5kZXgpO1xuICAgIH1cblxuICAgIHZlcnRpY2FsaXplUHVuY3R1YXRpb24oc2tpcENvbnRleHRDaGVja2luZzogYm9vbGVhbikge1xuICAgICAgICB0aGlzLnRleHQgPSB2ZXJ0aWNhbGl6ZVB1bmN0dWF0aW9uKHRoaXMudGV4dCwgc2tpcENvbnRleHRDaGVja2luZyk7XG4gICAgfVxuXG4gICAgdHJpbSgpIHtcbiAgICAgICAgbGV0IGJlZ2lubmluZ1doaXRlc3BhY2UgPSAwO1xuICAgICAgICBmb3IgKGxldCBpID0gMDtcbiAgICAgICAgICAgIGkgPCB0aGlzLnRleHQubGVuZ3RoICYmIHdoaXRlc3BhY2VbdGhpcy50ZXh0LmNoYXJDb2RlQXQoaSldO1xuICAgICAgICAgICAgaSsrKSB7XG4gICAgICAgICAgICBiZWdpbm5pbmdXaGl0ZXNwYWNlKys7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHRyYWlsaW5nV2hpdGVzcGFjZSA9IHRoaXMudGV4dC5sZW5ndGg7XG4gICAgICAgIGZvciAobGV0IGkgPSB0aGlzLnRleHQubGVuZ3RoIC0gMTtcbiAgICAgICAgICAgIGkgPj0gMCAmJiBpID49IGJlZ2lubmluZ1doaXRlc3BhY2UgJiYgd2hpdGVzcGFjZVt0aGlzLnRleHQuY2hhckNvZGVBdChpKV07XG4gICAgICAgICAgICBpLS0pIHtcbiAgICAgICAgICAgIHRyYWlsaW5nV2hpdGVzcGFjZS0tO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudGV4dCA9IHRoaXMudGV4dC5zdWJzdHJpbmcoYmVnaW5uaW5nV2hpdGVzcGFjZSwgdHJhaWxpbmdXaGl0ZXNwYWNlKTtcbiAgICAgICAgdGhpcy5zZWN0aW9uSW5kZXggPSB0aGlzLnNlY3Rpb25JbmRleC5zbGljZShiZWdpbm5pbmdXaGl0ZXNwYWNlLCB0cmFpbGluZ1doaXRlc3BhY2UpO1xuICAgIH1cblxuICAgIHN1YnN0cmluZyhzdGFydDogbnVtYmVyLCBlbmQ6IG51bWJlcik6IFRhZ2dlZFN0cmluZyB7XG4gICAgICAgIGNvbnN0IHN1YnN0cmluZyA9IG5ldyBUYWdnZWRTdHJpbmcoKTtcbiAgICAgICAgc3Vic3RyaW5nLnRleHQgPSB0aGlzLnRleHQuc3Vic3RyaW5nKHN0YXJ0LCBlbmQpO1xuICAgICAgICBzdWJzdHJpbmcuc2VjdGlvbkluZGV4ID0gdGhpcy5zZWN0aW9uSW5kZXguc2xpY2Uoc3RhcnQsIGVuZCk7XG4gICAgICAgIHN1YnN0cmluZy5zZWN0aW9ucyA9IHRoaXMuc2VjdGlvbnM7XG4gICAgICAgIHJldHVybiBzdWJzdHJpbmc7XG4gICAgfVxuXG4gICAgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGV4dDtcbiAgICB9XG5cbiAgICBnZXRNYXhTY2FsZSgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5zZWN0aW9uSW5kZXgucmVkdWNlKChtYXgsIGluZGV4KSA9PiBNYXRoLm1heChtYXgsIHRoaXMuc2VjdGlvbnNbaW5kZXhdLnNjYWxlKSwgMCk7XG4gICAgfVxuXG4gICAgYWRkVGV4dFNlY3Rpb24oc2VjdGlvbjogRm9ybWF0dGVkU2VjdGlvbiwgZGVmYXVsdEZvbnRTdGFjazogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMudGV4dCArPSBzZWN0aW9uLnRleHQ7XG4gICAgICAgIHRoaXMuc2VjdGlvbnMucHVzaChTZWN0aW9uT3B0aW9ucy5mb3JUZXh0KHNlY3Rpb24uc2NhbGUsIHNlY3Rpb24uZm9udFN0YWNrIHx8IGRlZmF1bHRGb250U3RhY2spKTtcbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLnNlY3Rpb25zLmxlbmd0aCAtIDE7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VjdGlvbi50ZXh0Lmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICB0aGlzLnNlY3Rpb25JbmRleC5wdXNoKGluZGV4KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFkZEltYWdlU2VjdGlvbihzZWN0aW9uOiBGb3JtYXR0ZWRTZWN0aW9uKSB7XG4gICAgICAgIGNvbnN0IGltYWdlTmFtZSA9IHNlY3Rpb24uaW1hZ2UgPyBzZWN0aW9uLmltYWdlLm5hbWUgOiAnJztcbiAgICAgICAgaWYgKGltYWdlTmFtZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHdhcm5PbmNlKGBDYW4ndCBhZGQgRm9ybWF0dGVkU2VjdGlvbiB3aXRoIGFuIGVtcHR5IGltYWdlLmApO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbmV4dEltYWdlU2VjdGlvbkNoYXJDb2RlID0gdGhpcy5nZXROZXh0SW1hZ2VTZWN0aW9uQ2hhckNvZGUoKTtcbiAgICAgICAgaWYgKCFuZXh0SW1hZ2VTZWN0aW9uQ2hhckNvZGUpIHtcbiAgICAgICAgICAgIHdhcm5PbmNlKGBSZWFjaGVkIG1heGltdW0gbnVtYmVyIG9mIGltYWdlcyAke1BVQWVuZCAtIFBVQWJlZ2luICsgMn1gKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKG5leHRJbWFnZVNlY3Rpb25DaGFyQ29kZSk7XG4gICAgICAgIHRoaXMuc2VjdGlvbnMucHVzaChTZWN0aW9uT3B0aW9ucy5mb3JJbWFnZShpbWFnZU5hbWUpKTtcbiAgICAgICAgdGhpcy5zZWN0aW9uSW5kZXgucHVzaCh0aGlzLnNlY3Rpb25zLmxlbmd0aCAtIDEpO1xuICAgIH1cblxuICAgIGdldE5leHRJbWFnZVNlY3Rpb25DaGFyQ29kZSgpOiBudW1iZXIgfCBudWxsIHtcbiAgICAgICAgaWYgKCF0aGlzLmltYWdlU2VjdGlvbklEKSB7XG4gICAgICAgICAgICB0aGlzLmltYWdlU2VjdGlvbklEID0gUFVBYmVnaW47XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5pbWFnZVNlY3Rpb25JRDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmltYWdlU2VjdGlvbklEID49IFBVQWVuZCkgcmV0dXJuIG51bGw7XG4gICAgICAgIHJldHVybiArK3RoaXMuaW1hZ2VTZWN0aW9uSUQ7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBicmVha0xpbmVzKGlucHV0OiBUYWdnZWRTdHJpbmcsIGxpbmVCcmVha1BvaW50czogQXJyYXk8bnVtYmVyPik6IEFycmF5PFRhZ2dlZFN0cmluZz4ge1xuICAgIGNvbnN0IGxpbmVzID0gW107XG4gICAgY29uc3QgdGV4dCA9IGlucHV0LnRleHQ7XG4gICAgbGV0IHN0YXJ0ID0gMDtcbiAgICBmb3IgKGNvbnN0IGxpbmVCcmVhayBvZiBsaW5lQnJlYWtQb2ludHMpIHtcbiAgICAgICAgbGluZXMucHVzaChpbnB1dC5zdWJzdHJpbmcoc3RhcnQsIGxpbmVCcmVhaykpO1xuICAgICAgICBzdGFydCA9IGxpbmVCcmVhaztcbiAgICB9XG5cbiAgICBpZiAoc3RhcnQgPCB0ZXh0Lmxlbmd0aCkge1xuICAgICAgICBsaW5lcy5wdXNoKGlucHV0LnN1YnN0cmluZyhzdGFydCwgdGV4dC5sZW5ndGgpKTtcbiAgICB9XG4gICAgcmV0dXJuIGxpbmVzO1xufVxuXG5mdW5jdGlvbiBzaGFwZVRleHQodGV4dDogRm9ybWF0dGVkLFxuICAgICAgICAgICAgICAgICAgIGdseXBoTWFwOiB7W186IHN0cmluZ106IHtnbHlwaHM6IHtbXzogbnVtYmVyXTogP1N0eWxlR2x5cGh9LCBhc2NlbmRlcj86IG51bWJlciwgZGVzY2VuZGVyPzogbnVtYmVyfX0sXG4gICAgICAgICAgICAgICAgICAgZ2x5cGhQb3NpdGlvbnM6IEdseXBoUG9zaXRpb25zLFxuICAgICAgICAgICAgICAgICAgIGltYWdlUG9zaXRpb25zOiB7W186IHN0cmluZ106IEltYWdlUG9zaXRpb259LFxuICAgICAgICAgICAgICAgICAgIGRlZmF1bHRGb250U3RhY2s6IHN0cmluZyxcbiAgICAgICAgICAgICAgICAgICBtYXhXaWR0aDogbnVtYmVyLFxuICAgICAgICAgICAgICAgICAgIGxpbmVIZWlnaHQ6IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICB0ZXh0QW5jaG9yOiBTeW1ib2xBbmNob3IsXG4gICAgICAgICAgICAgICAgICAgdGV4dEp1c3RpZnk6IFRleHRKdXN0aWZ5LFxuICAgICAgICAgICAgICAgICAgIHNwYWNpbmc6IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGU6IFtudW1iZXIsIG51bWJlcl0sXG4gICAgICAgICAgICAgICAgICAgd3JpdGluZ01vZGU6IDEgfCAyLFxuICAgICAgICAgICAgICAgICAgIGFsbG93VmVydGljYWxQbGFjZW1lbnQ6IGJvb2xlYW4sXG4gICAgICAgICAgICAgICAgICAgbGF5b3V0VGV4dFNpemU6IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICBsYXlvdXRUZXh0U2l6ZVRoaXNab29tOiBudW1iZXIpOiBTaGFwaW5nIHwgZmFsc2Uge1xuICAgIGNvbnN0IGxvZ2ljYWxJbnB1dCA9IFRhZ2dlZFN0cmluZy5mcm9tRmVhdHVyZSh0ZXh0LCBkZWZhdWx0Rm9udFN0YWNrKTtcblxuICAgIGlmICh3cml0aW5nTW9kZSA9PT0gV3JpdGluZ01vZGUudmVydGljYWwpIHtcbiAgICAgICAgbG9naWNhbElucHV0LnZlcnRpY2FsaXplUHVuY3R1YXRpb24oYWxsb3dWZXJ0aWNhbFBsYWNlbWVudCk7XG4gICAgfVxuXG4gICAgbGV0IGxpbmVzOiBBcnJheTxUYWdnZWRTdHJpbmc+ID0gW107XG5cbiAgICBjb25zdCBsaW5lQnJlYWtzID0gZGV0ZXJtaW5lTGluZUJyZWFrcyhsb2dpY2FsSW5wdXQsIHNwYWNpbmcsIG1heFdpZHRoLCBnbHlwaE1hcCwgaW1hZ2VQb3NpdGlvbnMsIGxheW91dFRleHRTaXplKTtcblxuICAgIGNvbnN0IHtwcm9jZXNzQmlkaXJlY3Rpb25hbFRleHQsIHByb2Nlc3NTdHlsZWRCaWRpcmVjdGlvbmFsVGV4dH0gPSBydGxUZXh0UGx1Z2luO1xuICAgIGlmIChwcm9jZXNzQmlkaXJlY3Rpb25hbFRleHQgJiYgbG9naWNhbElucHV0LnNlY3Rpb25zLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAvLyBCaWRpIGRvZXNuJ3QgaGF2ZSB0byBiZSBzdHlsZS1hd2FyZVxuICAgICAgICBjb25zdCB1bnRhZ2dlZExpbmVzID0gcHJvY2Vzc0JpZGlyZWN0aW9uYWxUZXh0KGxvZ2ljYWxJbnB1dC50b1N0cmluZygpLCBsaW5lQnJlYWtzKTtcbiAgICAgICAgZm9yIChjb25zdCBsaW5lIG9mIHVudGFnZ2VkTGluZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHRhZ2dlZExpbmUgPSBuZXcgVGFnZ2VkU3RyaW5nKCk7XG4gICAgICAgICAgICB0YWdnZWRMaW5lLnRleHQgPSBsaW5lO1xuICAgICAgICAgICAgdGFnZ2VkTGluZS5zZWN0aW9ucyA9IGxvZ2ljYWxJbnB1dC5zZWN0aW9ucztcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGluZS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHRhZ2dlZExpbmUuc2VjdGlvbkluZGV4LnB1c2goMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsaW5lcy5wdXNoKHRhZ2dlZExpbmUpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIGlmIChwcm9jZXNzU3R5bGVkQmlkaXJlY3Rpb25hbFRleHQpIHtcbiAgICAgICAgLy8gTmVlZCB2ZXJzaW9uIG9mIG1hcGJveC1nbC1ydGwtdGV4dCB3aXRoIHN0eWxlIHN1cHBvcnQgZm9yIGNvbWJpbmluZyBSVEwgdGV4dCB3aXRoIGZvcm1hdHRpbmdcbiAgICAgICAgY29uc3QgcHJvY2Vzc2VkTGluZXMgPSBwcm9jZXNzU3R5bGVkQmlkaXJlY3Rpb25hbFRleHQobG9naWNhbElucHV0LnRleHQsIGxvZ2ljYWxJbnB1dC5zZWN0aW9uSW5kZXgsIGxpbmVCcmVha3MpO1xuICAgICAgICBmb3IgKGNvbnN0IGxpbmUgb2YgcHJvY2Vzc2VkTGluZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHRhZ2dlZExpbmUgPSBuZXcgVGFnZ2VkU3RyaW5nKCk7XG4gICAgICAgICAgICB0YWdnZWRMaW5lLnRleHQgPSBsaW5lWzBdO1xuICAgICAgICAgICAgdGFnZ2VkTGluZS5zZWN0aW9uSW5kZXggPSBsaW5lWzFdO1xuICAgICAgICAgICAgdGFnZ2VkTGluZS5zZWN0aW9ucyA9IGxvZ2ljYWxJbnB1dC5zZWN0aW9ucztcbiAgICAgICAgICAgIGxpbmVzLnB1c2godGFnZ2VkTGluZSk7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBsaW5lcyA9IGJyZWFrTGluZXMobG9naWNhbElucHV0LCBsaW5lQnJlYWtzKTtcbiAgICB9XG5cbiAgICBjb25zdCBwb3NpdGlvbmVkTGluZXMgPSBbXTtcbiAgICBjb25zdCBzaGFwaW5nID0ge1xuICAgICAgICBwb3NpdGlvbmVkTGluZXMsXG4gICAgICAgIHRleHQ6IGxvZ2ljYWxJbnB1dC50b1N0cmluZygpLFxuICAgICAgICB0b3A6IHRyYW5zbGF0ZVsxXSxcbiAgICAgICAgYm90dG9tOiB0cmFuc2xhdGVbMV0sXG4gICAgICAgIGxlZnQ6IHRyYW5zbGF0ZVswXSxcbiAgICAgICAgcmlnaHQ6IHRyYW5zbGF0ZVswXSxcbiAgICAgICAgd3JpdGluZ01vZGUsXG4gICAgICAgIGljb25zSW5UZXh0OiBmYWxzZSxcbiAgICAgICAgdmVydGljYWxpemFibGU6IGZhbHNlLFxuICAgICAgICBoYXNCYXNlbGluZTogZmFsc2VcbiAgICB9O1xuXG4gICAgc2hhcGVMaW5lcyhzaGFwaW5nLCBnbHlwaE1hcCwgZ2x5cGhQb3NpdGlvbnMsIGltYWdlUG9zaXRpb25zLCBsaW5lcywgbGluZUhlaWdodCwgdGV4dEFuY2hvciwgdGV4dEp1c3RpZnksIHdyaXRpbmdNb2RlLCBzcGFjaW5nLCBhbGxvd1ZlcnRpY2FsUGxhY2VtZW50LCBsYXlvdXRUZXh0U2l6ZVRoaXNab29tKTtcbiAgICBpZiAoaXNFbXB0eShwb3NpdGlvbmVkTGluZXMpKSByZXR1cm4gZmFsc2U7XG5cbiAgICByZXR1cm4gc2hhcGluZztcbn1cblxuLy8gdXNpbmcgY29tcHV0ZWQgcHJvcGVydGllcyBkdWUgdG8gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL2Zsb3cvaXNzdWVzLzM4MFxuLyogZXNsaW50IG5vLXVzZWxlc3MtY29tcHV0ZWQta2V5OiAwICovXG5cbmNvbnN0IHdoaXRlc3BhY2U6IHtbXzogbnVtYmVyXTogYm9vbGVhbn0gPSB7XG4gICAgWzB4MDldOiB0cnVlLCAvLyB0YWJcbiAgICBbMHgwYV06IHRydWUsIC8vIG5ld2xpbmVcbiAgICBbMHgwYl06IHRydWUsIC8vIHZlcnRpY2FsIHRhYlxuICAgIFsweDBjXTogdHJ1ZSwgLy8gZm9ybSBmZWVkXG4gICAgWzB4MGRdOiB0cnVlLCAvLyBjYXJyaWFnZSByZXR1cm5cbiAgICBbMHgyMF06IHRydWUsIC8vIHNwYWNlXG59O1xuXG5jb25zdCBicmVha2FibGU6IHtbXzogbnVtYmVyXTogYm9vbGVhbn0gPSB7XG4gICAgWzB4MGFdOiAgIHRydWUsIC8vIG5ld2xpbmVcbiAgICBbMHgyMF06ICAgdHJ1ZSwgLy8gc3BhY2VcbiAgICBbMHgyNl06ICAgdHJ1ZSwgLy8gYW1wZXJzYW5kXG4gICAgWzB4MjhdOiAgIHRydWUsIC8vIGxlZnQgcGFyZW50aGVzaXNcbiAgICBbMHgyOV06ICAgdHJ1ZSwgLy8gcmlnaHQgcGFyZW50aGVzaXNcbiAgICBbMHgyYl06ICAgdHJ1ZSwgLy8gcGx1cyBzaWduXG4gICAgWzB4MmRdOiAgIHRydWUsIC8vIGh5cGhlbi1taW51c1xuICAgIFsweDJmXTogICB0cnVlLCAvLyBzb2xpZHVzXG4gICAgWzB4YWRdOiAgIHRydWUsIC8vIHNvZnQgaHlwaGVuXG4gICAgWzB4YjddOiAgIHRydWUsIC8vIG1pZGRsZSBkb3RcbiAgICBbMHgyMDBiXTogdHJ1ZSwgLy8gemVyby13aWR0aCBzcGFjZVxuICAgIFsweDIwMTBdOiB0cnVlLCAvLyBoeXBoZW5cbiAgICBbMHgyMDEzXTogdHJ1ZSwgLy8gZW4gZGFzaFxuICAgIFsweDIwMjddOiB0cnVlICAvLyBpbnRlcnB1bmN0XG4gICAgLy8gTWFueSBvdGhlciBjaGFyYWN0ZXJzIG1heSBiZSByZWFzb25hYmxlIGJyZWFrcG9pbnRzXG4gICAgLy8gQ29uc2lkZXIgXCJuZXV0cmFsIG9yaWVudGF0aW9uXCIgY2hhcmFjdGVycyBhdCBzY3JpcHREZXRlY3Rpb24uY2hhckhhc05ldXRyYWxWZXJ0aWNhbE9yaWVudGF0aW9uXG4gICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXBib3gvbWFwYm94LWdsLWpzL2lzc3Vlcy8zNjU4XG59O1xuXG5mdW5jdGlvbiBnZXRHbHlwaEFkdmFuY2UoY29kZVBvaW50OiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgc2VjdGlvbjogU2VjdGlvbk9wdGlvbnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgZ2x5cGhNYXA6IHtbXzogc3RyaW5nXToge2dseXBoczoge1tfOiBudW1iZXJdOiA/U3R5bGVHbHlwaH0sIGFzY2VuZGVyPzogbnVtYmVyLCBkZXNjZW5kZXI/OiBudW1iZXJ9fSxcbiAgICAgICAgICAgICAgICAgICAgICAgICBpbWFnZVBvc2l0aW9uczoge1tfOiBzdHJpbmddOiBJbWFnZVBvc2l0aW9ufSxcbiAgICAgICAgICAgICAgICAgICAgICAgICBzcGFjaW5nOiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgbGF5b3V0VGV4dFNpemU6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKCFzZWN0aW9uLmltYWdlTmFtZSkge1xuICAgICAgICBjb25zdCBwb3NpdGlvbnMgPSBnbHlwaE1hcFtzZWN0aW9uLmZvbnRTdGFja107XG4gICAgICAgIGNvbnN0IGdseXBoID0gcG9zaXRpb25zICYmIHBvc2l0aW9ucy5nbHlwaHNbY29kZVBvaW50XTtcbiAgICAgICAgaWYgKCFnbHlwaCkgcmV0dXJuIDA7XG4gICAgICAgIHJldHVybiBnbHlwaC5tZXRyaWNzLmFkdmFuY2UgKiBzZWN0aW9uLnNjYWxlICsgc3BhY2luZztcbiAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBpbWFnZVBvc2l0aW9uID0gaW1hZ2VQb3NpdGlvbnNbc2VjdGlvbi5pbWFnZU5hbWVdO1xuICAgICAgICBpZiAoIWltYWdlUG9zaXRpb24pIHJldHVybiAwO1xuICAgICAgICByZXR1cm4gaW1hZ2VQb3NpdGlvbi5kaXNwbGF5U2l6ZVswXSAqIHNlY3Rpb24uc2NhbGUgKiBPTkVfRU0gLyBsYXlvdXRUZXh0U2l6ZSArIHNwYWNpbmc7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkZXRlcm1pbmVBdmVyYWdlTGluZVdpZHRoKGxvZ2ljYWxJbnB1dDogVGFnZ2VkU3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGFjaW5nOiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heFdpZHRoOiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdseXBoTWFwOiB7W186IHN0cmluZ106IHtnbHlwaHM6IHtbXzogbnVtYmVyXTogP1N0eWxlR2x5cGh9LCBhc2NlbmRlcj86IG51bWJlciwgZGVzY2VuZGVyPzogbnVtYmVyfX0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlUG9zaXRpb25zOiB7W186IHN0cmluZ106IEltYWdlUG9zaXRpb259LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXlvdXRUZXh0U2l6ZTogbnVtYmVyKSB7XG4gICAgbGV0IHRvdGFsV2lkdGggPSAwO1xuXG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGxvZ2ljYWxJbnB1dC5sZW5ndGgoKTsgaW5kZXgrKykge1xuICAgICAgICBjb25zdCBzZWN0aW9uID0gbG9naWNhbElucHV0LmdldFNlY3Rpb24oaW5kZXgpO1xuICAgICAgICB0b3RhbFdpZHRoICs9IGdldEdseXBoQWR2YW5jZShsb2dpY2FsSW5wdXQuZ2V0Q2hhckNvZGUoaW5kZXgpLCBzZWN0aW9uLCBnbHlwaE1hcCwgaW1hZ2VQb3NpdGlvbnMsIHNwYWNpbmcsIGxheW91dFRleHRTaXplKTtcbiAgICB9XG5cbiAgICBjb25zdCBsaW5lQ291bnQgPSBNYXRoLm1heCgxLCBNYXRoLmNlaWwodG90YWxXaWR0aCAvIG1heFdpZHRoKSk7XG4gICAgcmV0dXJuIHRvdGFsV2lkdGggLyBsaW5lQ291bnQ7XG59XG5cbmZ1bmN0aW9uIGNhbGN1bGF0ZUJhZG5lc3MobGluZVdpZHRoOiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldFdpZHRoOiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHBlbmFsdHk6IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgaXNMYXN0QnJlYWs6IGJvb2xlYW4pIHtcbiAgICBjb25zdCByYWdnZWRuZXNzID0gTWF0aC5wb3cobGluZVdpZHRoIC0gdGFyZ2V0V2lkdGgsIDIpO1xuICAgIGlmIChpc0xhc3RCcmVhaykge1xuICAgICAgICAvLyBGYXZvciBmaW5hbHMgbGluZXMgc2hvcnRlciB0aGFuIGF2ZXJhZ2Ugb3ZlciBsb25nZXIgdGhhbiBhdmVyYWdlXG4gICAgICAgIGlmIChsaW5lV2lkdGggPCB0YXJnZXRXaWR0aCkge1xuICAgICAgICAgICAgcmV0dXJuIHJhZ2dlZG5lc3MgLyAyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHJhZ2dlZG5lc3MgKiAyO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJhZ2dlZG5lc3MgKyBNYXRoLmFicyhwZW5hbHR5KSAqIHBlbmFsdHk7XG59XG5cbmZ1bmN0aW9uIGNhbGN1bGF0ZVBlbmFsdHkoY29kZVBvaW50OiBudW1iZXIsIG5leHRDb2RlUG9pbnQ6IG51bWJlciwgcGVuYWxpemFibGVJZGVvZ3JhcGhpY0JyZWFrOiBib29sZWFuKSB7XG4gICAgbGV0IHBlbmFsdHkgPSAwO1xuICAgIC8vIEZvcmNlIGJyZWFrIG9uIG5ld2xpbmVcbiAgICBpZiAoY29kZVBvaW50ID09PSAweDBhKSB7XG4gICAgICAgIHBlbmFsdHkgLT0gMTAwMDA7XG4gICAgfVxuICAgIC8vIFBlbmFsaXplIGJyZWFrcyBiZXR3ZWVuIGNoYXJhY3RlcnMgdGhhdCBhbGxvdyBpZGVvZ3JhcGhpYyBicmVha2luZyBiZWNhdXNlXG4gICAgLy8gdGhleSBhcmUgbGVzcyBwcmVmZXJhYmxlIHRoYW4gYnJlYWtzIGF0IHNwYWNlcyAob3IgemVybyB3aWR0aCBzcGFjZXMpLlxuICAgIGlmIChwZW5hbGl6YWJsZUlkZW9ncmFwaGljQnJlYWspIHtcbiAgICAgICAgcGVuYWx0eSArPSAxNTA7XG4gICAgfVxuXG4gICAgLy8gUGVuYWxpemUgb3BlbiBwYXJlbnRoZXNpcyBhdCBlbmQgb2YgbGluZVxuICAgIGlmIChjb2RlUG9pbnQgPT09IDB4MjggfHwgY29kZVBvaW50ID09PSAweGZmMDgpIHtcbiAgICAgICAgcGVuYWx0eSArPSA1MDtcbiAgICB9XG5cbiAgICAvLyBQZW5hbGl6ZSBjbG9zZSBwYXJlbnRoZXNpcyBhdCBiZWdpbm5pbmcgb2YgbGluZVxuICAgIGlmIChuZXh0Q29kZVBvaW50ID09PSAweDI5IHx8IG5leHRDb2RlUG9pbnQgPT09IDB4ZmYwOSkge1xuICAgICAgICBwZW5hbHR5ICs9IDUwO1xuICAgIH1cbiAgICByZXR1cm4gcGVuYWx0eTtcbn1cblxudHlwZSBCcmVhayA9IHtcbiAgICBpbmRleDogbnVtYmVyLFxuICAgIHg6IG51bWJlcixcbiAgICBwcmlvckJyZWFrOiA/QnJlYWssXG4gICAgYmFkbmVzczogbnVtYmVyXG59O1xuXG5mdW5jdGlvbiBldmFsdWF0ZUJyZWFrKGJyZWFrSW5kZXg6IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtYOiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgIHRhcmdldFdpZHRoOiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgIHBvdGVudGlhbEJyZWFrczogQXJyYXk8QnJlYWs+LFxuICAgICAgICAgICAgICAgICAgICAgICBwZW5hbHR5OiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgIGlzTGFzdEJyZWFrOiBib29sZWFuKTogQnJlYWsge1xuICAgIC8vIFdlIGNvdWxkIHNraXAgZXZhbHVhdGluZyBicmVha3Mgd2hlcmUgdGhlIGxpbmUgbGVuZ3RoIChicmVha1ggLSBwcmlvckJyZWFrLngpID4gbWF4V2lkdGhcbiAgICAvLyAgLi4uYnV0IGluIGZhY3Qgd2UgYWxsb3cgbGluZXMgbG9uZ2VyIHRoYW4gbWF4V2lkdGggKGlmIHRoZXJlJ3Mgbm8gYnJlYWsgcG9pbnRzKVxuICAgIC8vICAuLi5hbmQgd2hlbiB0YXJnZXRXaWR0aCBhbmQgbWF4V2lkdGggYXJlIGNsb3NlLCBzdHJpY3RseSBlbmZvcmNpbmcgbWF4V2lkdGggY2FuIGdpdmVcbiAgICAvLyAgICAgbW9yZSBsb3BzaWRlZCByZXN1bHRzLlxuXG4gICAgbGV0IGJlc3RQcmlvckJyZWFrOiA/QnJlYWsgPSBudWxsO1xuICAgIGxldCBiZXN0QnJlYWtCYWRuZXNzID0gY2FsY3VsYXRlQmFkbmVzcyhicmVha1gsIHRhcmdldFdpZHRoLCBwZW5hbHR5LCBpc0xhc3RCcmVhayk7XG5cbiAgICBmb3IgKGNvbnN0IHBvdGVudGlhbEJyZWFrIG9mIHBvdGVudGlhbEJyZWFrcykge1xuICAgICAgICBjb25zdCBsaW5lV2lkdGggPSBicmVha1ggLSBwb3RlbnRpYWxCcmVhay54O1xuICAgICAgICBjb25zdCBicmVha0JhZG5lc3MgPVxuICAgICAgICAgICAgY2FsY3VsYXRlQmFkbmVzcyhsaW5lV2lkdGgsIHRhcmdldFdpZHRoLCBwZW5hbHR5LCBpc0xhc3RCcmVhaykgKyBwb3RlbnRpYWxCcmVhay5iYWRuZXNzO1xuICAgICAgICBpZiAoYnJlYWtCYWRuZXNzIDw9IGJlc3RCcmVha0JhZG5lc3MpIHtcbiAgICAgICAgICAgIGJlc3RQcmlvckJyZWFrID0gcG90ZW50aWFsQnJlYWs7XG4gICAgICAgICAgICBiZXN0QnJlYWtCYWRuZXNzID0gYnJlYWtCYWRuZXNzO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgaW5kZXg6IGJyZWFrSW5kZXgsXG4gICAgICAgIHg6IGJyZWFrWCxcbiAgICAgICAgcHJpb3JCcmVhazogYmVzdFByaW9yQnJlYWssXG4gICAgICAgIGJhZG5lc3M6IGJlc3RCcmVha0JhZG5lc3NcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBsZWFzdEJhZEJyZWFrcyhsYXN0TGluZUJyZWFrOiA/QnJlYWspOiBBcnJheTxudW1iZXI+IHtcbiAgICBpZiAoIWxhc3RMaW5lQnJlYWspIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICByZXR1cm4gbGVhc3RCYWRCcmVha3MobGFzdExpbmVCcmVhay5wcmlvckJyZWFrKS5jb25jYXQobGFzdExpbmVCcmVhay5pbmRleCk7XG59XG5cbmZ1bmN0aW9uIGRldGVybWluZUxpbmVCcmVha3MobG9naWNhbElucHV0OiBUYWdnZWRTdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYWNpbmc6IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4V2lkdGg6IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2x5cGhNYXA6IHtbXzogc3RyaW5nXToge2dseXBoczoge1tfOiBudW1iZXJdOiA/U3R5bGVHbHlwaH0sIGFzY2VuZGVyPzogbnVtYmVyLCBkZXNjZW5kZXI/OiBudW1iZXJ9fSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1hZ2VQb3NpdGlvbnM6IHtbXzogc3RyaW5nXTogSW1hZ2VQb3NpdGlvbn0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxheW91dFRleHRTaXplOiBudW1iZXIpOiBBcnJheTxudW1iZXI+IHtcbiAgICBpZiAoIWxvZ2ljYWxJbnB1dClcbiAgICAgICAgcmV0dXJuIFtdO1xuXG4gICAgY29uc3QgcG90ZW50aWFsTGluZUJyZWFrcyA9IFtdO1xuICAgIGNvbnN0IHRhcmdldFdpZHRoID0gZGV0ZXJtaW5lQXZlcmFnZUxpbmVXaWR0aChsb2dpY2FsSW5wdXQsIHNwYWNpbmcsIG1heFdpZHRoLCBnbHlwaE1hcCwgaW1hZ2VQb3NpdGlvbnMsIGxheW91dFRleHRTaXplKTtcblxuICAgIGNvbnN0IGhhc1NlcnZlclN1Z2dlc3RlZEJyZWFrcG9pbnRzID0gbG9naWNhbElucHV0LnRleHQuaW5kZXhPZihcIlxcdTIwMGJcIikgPj0gMDtcblxuICAgIGxldCBjdXJyZW50WCA9IDA7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxvZ2ljYWxJbnB1dC5sZW5ndGgoKTsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHNlY3Rpb24gPSBsb2dpY2FsSW5wdXQuZ2V0U2VjdGlvbihpKTtcbiAgICAgICAgY29uc3QgY29kZVBvaW50ID0gbG9naWNhbElucHV0LmdldENoYXJDb2RlKGkpO1xuICAgICAgICBpZiAoIXdoaXRlc3BhY2VbY29kZVBvaW50XSkgY3VycmVudFggKz0gZ2V0R2x5cGhBZHZhbmNlKGNvZGVQb2ludCwgc2VjdGlvbiwgZ2x5cGhNYXAsIGltYWdlUG9zaXRpb25zLCBzcGFjaW5nLCBsYXlvdXRUZXh0U2l6ZSk7XG5cbiAgICAgICAgLy8gSWRlb2dyYXBoaWMgY2hhcmFjdGVycywgc3BhY2VzLCBhbmQgd29yZC1icmVha2luZyBwdW5jdHVhdGlvbiB0aGF0IG9mdGVuIGFwcGVhciB3aXRob3V0XG4gICAgICAgIC8vIHN1cnJvdW5kaW5nIHNwYWNlcy5cbiAgICAgICAgaWYgKChpIDwgbG9naWNhbElucHV0Lmxlbmd0aCgpIC0gMSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGlkZW9ncmFwaGljQnJlYWsgPSBjaGFyQWxsb3dzSWRlb2dyYXBoaWNCcmVha2luZyhjb2RlUG9pbnQpO1xuICAgICAgICAgICAgaWYgKGJyZWFrYWJsZVtjb2RlUG9pbnRdIHx8IGlkZW9ncmFwaGljQnJlYWsgfHwgc2VjdGlvbi5pbWFnZU5hbWUpIHtcblxuICAgICAgICAgICAgICAgIHBvdGVudGlhbExpbmVCcmVha3MucHVzaChcbiAgICAgICAgICAgICAgICAgICAgZXZhbHVhdGVCcmVhayhcbiAgICAgICAgICAgICAgICAgICAgICAgIGkgKyAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudFgsXG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRXaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvdGVudGlhbExpbmVCcmVha3MsXG4gICAgICAgICAgICAgICAgICAgICAgICBjYWxjdWxhdGVQZW5hbHR5KGNvZGVQb2ludCwgbG9naWNhbElucHV0LmdldENoYXJDb2RlKGkgKyAxKSwgaWRlb2dyYXBoaWNCcmVhayAmJiBoYXNTZXJ2ZXJTdWdnZXN0ZWRCcmVha3BvaW50cyksXG4gICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGxlYXN0QmFkQnJlYWtzKFxuICAgICAgICBldmFsdWF0ZUJyZWFrKFxuICAgICAgICAgICAgbG9naWNhbElucHV0Lmxlbmd0aCgpLFxuICAgICAgICAgICAgY3VycmVudFgsXG4gICAgICAgICAgICB0YXJnZXRXaWR0aCxcbiAgICAgICAgICAgIHBvdGVudGlhbExpbmVCcmVha3MsXG4gICAgICAgICAgICAwLFxuICAgICAgICAgICAgdHJ1ZSkpO1xufVxuXG5mdW5jdGlvbiBnZXRBbmNob3JBbGlnbm1lbnQoYW5jaG9yOiBTeW1ib2xBbmNob3IpOiBBbmNob3JBbGlnbm1lbnQge1xuICAgIGxldCBob3Jpem9udGFsQWxpZ24gPSAwLjUsIHZlcnRpY2FsQWxpZ24gPSAwLjU7XG5cbiAgICBzd2l0Y2ggKGFuY2hvcikge1xuICAgIGNhc2UgJ3JpZ2h0JzpcbiAgICBjYXNlICd0b3AtcmlnaHQnOlxuICAgIGNhc2UgJ2JvdHRvbS1yaWdodCc6XG4gICAgICAgIGhvcml6b250YWxBbGlnbiA9IDE7XG4gICAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2xlZnQnOlxuICAgIGNhc2UgJ3RvcC1sZWZ0JzpcbiAgICBjYXNlICdib3R0b20tbGVmdCc6XG4gICAgICAgIGhvcml6b250YWxBbGlnbiA9IDA7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHN3aXRjaCAoYW5jaG9yKSB7XG4gICAgY2FzZSAnYm90dG9tJzpcbiAgICBjYXNlICdib3R0b20tcmlnaHQnOlxuICAgIGNhc2UgJ2JvdHRvbS1sZWZ0JzpcbiAgICAgICAgdmVydGljYWxBbGlnbiA9IDE7XG4gICAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3RvcCc6XG4gICAgY2FzZSAndG9wLXJpZ2h0JzpcbiAgICBjYXNlICd0b3AtbGVmdCc6XG4gICAgICAgIHZlcnRpY2FsQWxpZ24gPSAwO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICByZXR1cm4ge2hvcml6b250YWxBbGlnbiwgdmVydGljYWxBbGlnbn07XG59XG5cbmZ1bmN0aW9uIHNoYXBlTGluZXMoc2hhcGluZzogU2hhcGluZyxcbiAgICAgICAgICAgICAgICAgICAgZ2x5cGhNYXA6IHtbXzogc3RyaW5nXToge2dseXBoczoge1tfOiBudW1iZXJdOiA/U3R5bGVHbHlwaH0sIGFzY2VuZGVyPzogbnVtYmVyLCBkZXNjZW5kZXI/OiBudW1iZXJ9fSxcbiAgICAgICAgICAgICAgICAgICAgZ2x5cGhQb3NpdGlvbnM6IEdseXBoUG9zaXRpb25zLFxuICAgICAgICAgICAgICAgICAgICBpbWFnZVBvc2l0aW9uczoge1tfOiBzdHJpbmddOiBJbWFnZVBvc2l0aW9ufSxcbiAgICAgICAgICAgICAgICAgICAgbGluZXM6IEFycmF5PFRhZ2dlZFN0cmluZz4sXG4gICAgICAgICAgICAgICAgICAgIGxpbmVIZWlnaHQ6IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgdGV4dEFuY2hvcjogU3ltYm9sQW5jaG9yLFxuICAgICAgICAgICAgICAgICAgICB0ZXh0SnVzdGlmeTogVGV4dEp1c3RpZnksXG4gICAgICAgICAgICAgICAgICAgIHdyaXRpbmdNb2RlOiAxIHwgMixcbiAgICAgICAgICAgICAgICAgICAgc3BhY2luZzogbnVtYmVyLFxuICAgICAgICAgICAgICAgICAgICBhbGxvd1ZlcnRpY2FsUGxhY2VtZW50OiBib29sZWFuLFxuICAgICAgICAgICAgICAgICAgICBsYXlvdXRUZXh0U2l6ZVRoaXNab29tOiBudW1iZXIpIHtcblxuICAgIGxldCB4ID0gMDtcbiAgICBsZXQgeSA9IDA7XG5cbiAgICBsZXQgbWF4TGluZUxlbmd0aCA9IDA7XG4gICAgbGV0IG1heExpbmVIZWlnaHQgPSAwO1xuXG4gICAgY29uc3QganVzdGlmeSA9XG4gICAgICAgIHRleHRKdXN0aWZ5ID09PSAncmlnaHQnID8gMSA6XG4gICAgICAgIHRleHRKdXN0aWZ5ID09PSAnbGVmdCcgPyAwIDogMC41O1xuXG4gICAgbGV0IGhhc0Jhc2VsaW5lID0gZmFsc2U7XG4gICAgZm9yIChjb25zdCBsaW5lIG9mIGxpbmVzKSB7XG4gICAgICAgIGNvbnN0IHNlY3Rpb25zID0gbGluZS5nZXRTZWN0aW9ucygpO1xuICAgICAgICBmb3IgKGNvbnN0IHNlY3Rpb24gb2Ygc2VjdGlvbnMpIHtcbiAgICAgICAgICAgIGlmIChzZWN0aW9uLmltYWdlTmFtZSkgY29udGludWU7XG5cbiAgICAgICAgICAgIGNvbnN0IGdseXBoRGF0YSA9IGdseXBoTWFwW3NlY3Rpb24uZm9udFN0YWNrXTtcbiAgICAgICAgICAgIGlmICghZ2x5cGhEYXRhKSBjb250aW51ZTtcblxuICAgICAgICAgICAgaGFzQmFzZWxpbmUgPSBnbHlwaERhdGEuYXNjZW5kZXIgIT09IHVuZGVmaW5lZCAmJiBnbHlwaERhdGEuZGVzY2VuZGVyICE9PSB1bmRlZmluZWQ7XG4gICAgICAgICAgICBpZiAoIWhhc0Jhc2VsaW5lKSBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWhhc0Jhc2VsaW5lKSBicmVhaztcbiAgICB9XG5cbiAgICBsZXQgbGluZUluZGV4ID0gMDtcbiAgICBmb3IgKGNvbnN0IGxpbmUgb2YgbGluZXMpIHtcbiAgICAgICAgbGluZS50cmltKCk7XG5cbiAgICAgICAgY29uc3QgbGluZU1heFNjYWxlID0gbGluZS5nZXRNYXhTY2FsZSgpO1xuICAgICAgICBjb25zdCBtYXhMaW5lT2Zmc2V0ID0gKGxpbmVNYXhTY2FsZSAtIDEpICogT05FX0VNO1xuICAgICAgICBjb25zdCBwb3NpdGlvbmVkTGluZSA9IHtwb3NpdGlvbmVkR2x5cGhzOiBbXSwgbGluZU9mZnNldDogMH07XG4gICAgICAgIHNoYXBpbmcucG9zaXRpb25lZExpbmVzW2xpbmVJbmRleF0gPSBwb3NpdGlvbmVkTGluZTtcbiAgICAgICAgY29uc3QgcG9zaXRpb25lZEdseXBocyA9IHBvc2l0aW9uZWRMaW5lLnBvc2l0aW9uZWRHbHlwaHM7XG4gICAgICAgIGxldCBsaW5lT2Zmc2V0ID0gMC4wO1xuXG4gICAgICAgIGlmICghbGluZS5sZW5ndGgoKSkge1xuICAgICAgICAgICAgeSArPSBsaW5lSGVpZ2h0OyAvLyBTdGlsbCBuZWVkIGEgbGluZSBmZWVkIGFmdGVyIGVtcHR5IGxpbmVcbiAgICAgICAgICAgICsrbGluZUluZGV4O1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgYmlnZ2VzdEhlaWdodCA9IDA7XG4gICAgICAgIGxldCBiYXNlbGluZU9mZnNldCA9IDA7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGluZS5sZW5ndGgoKTsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBzZWN0aW9uID0gbGluZS5nZXRTZWN0aW9uKGkpO1xuICAgICAgICAgICAgY29uc3Qgc2VjdGlvbkluZGV4ID0gbGluZS5nZXRTZWN0aW9uSW5kZXgoaSk7XG4gICAgICAgICAgICBjb25zdCBjb2RlUG9pbnQgPSBsaW5lLmdldENoYXJDb2RlKGkpO1xuXG4gICAgICAgICAgICBsZXQgc2VjdGlvblNjYWxlID0gc2VjdGlvbi5zY2FsZTtcbiAgICAgICAgICAgIGxldCBtZXRyaWNzID0gbnVsbDtcbiAgICAgICAgICAgIGxldCByZWN0ID0gbnVsbDtcbiAgICAgICAgICAgIGxldCBpbWFnZU5hbWUgPSBudWxsO1xuICAgICAgICAgICAgbGV0IHZlcnRpY2FsQWR2YW5jZSA9IE9ORV9FTTtcbiAgICAgICAgICAgIGxldCBnbHlwaE9mZnNldCA9IDA7XG5cbiAgICAgICAgICAgIGNvbnN0IHZlcnRpY2FsID0gISh3cml0aW5nTW9kZSA9PT0gV3JpdGluZ01vZGUuaG9yaXpvbnRhbCB8fFxuICAgICAgICAgICAgICAgIC8vIERvbid0IHZlcnRpY2FsaXplIGdseXBocyB0aGF0IGhhdmUgbm8gdXByaWdodCBvcmllbnRhdGlvbiBpZiB2ZXJ0aWNhbCBwbGFjZW1lbnQgaXMgZGlzYWJsZWQuXG4gICAgICAgICAgICAgICAgKCFhbGxvd1ZlcnRpY2FsUGxhY2VtZW50ICYmICFjaGFySGFzVXByaWdodFZlcnRpY2FsT3JpZW50YXRpb24oY29kZVBvaW50KSkgfHxcbiAgICAgICAgICAgICAgICAvLyBJZiB2ZXJ0aWNhbCBwbGFjZW1lbnQgaXMgZW5hYmxlZCwgZG9uJ3QgdmVydGljYWxpemUgZ2x5cGhzIHRoYXRcbiAgICAgICAgICAgICAgICAvLyBhcmUgZnJvbSBjb21wbGV4IHRleHQgbGF5b3V0IHNjcmlwdCwgb3Igd2hpdGVzcGFjZXMuXG4gICAgICAgICAgICAgICAgKGFsbG93VmVydGljYWxQbGFjZW1lbnQgJiYgKHdoaXRlc3BhY2VbY29kZVBvaW50XSB8fCBjaGFySW5Db21wbGV4U2hhcGluZ1NjcmlwdChjb2RlUG9pbnQpKSkpO1xuXG4gICAgICAgICAgICBpZiAoIXNlY3Rpb24uaW1hZ2VOYW1lKSB7XG4gICAgICAgICAgICAgICAgLy8gRmluZCBnbHlwaCBwb3NpdGlvbiBpbiB0aGUgZ2x5cGggYXRsYXMsIGlmIGJpdG1hcCBpcyBudWxsLFxuICAgICAgICAgICAgICAgIC8vIGdseXBoUG9zaXRpb24gd2lsbCBub3QgZXhpdCBpbiB0aGUgZ2x5cGhQb3NpdGlvbiBtYXBcbiAgICAgICAgICAgICAgICBjb25zdCBnbHlwaFBvc2l0aW9uRGF0YSA9IGdseXBoUG9zaXRpb25zW3NlY3Rpb24uZm9udFN0YWNrXTtcbiAgICAgICAgICAgICAgICBpZiAoIWdseXBoUG9zaXRpb25EYXRhKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICBpZiAoZ2x5cGhQb3NpdGlvbkRhdGFbY29kZVBvaW50XSkge1xuICAgICAgICAgICAgICAgICAgICByZWN0ID0gZ2x5cGhQb3NpdGlvbkRhdGFbY29kZVBvaW50XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgZ2x5cGhEYXRhID0gZ2x5cGhNYXBbc2VjdGlvbi5mb250U3RhY2tdO1xuICAgICAgICAgICAgICAgIGlmICghZ2x5cGhEYXRhKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICBjb25zdCBnbHlwaCA9IGdseXBoRGF0YS5nbHlwaHNbY29kZVBvaW50XTtcbiAgICAgICAgICAgICAgICBpZiAoIWdseXBoKSBjb250aW51ZTtcblxuICAgICAgICAgICAgICAgIG1ldHJpY3MgPSBnbHlwaC5tZXRyaWNzO1xuICAgICAgICAgICAgICAgIHZlcnRpY2FsQWR2YW5jZSA9IGNvZGVQb2ludCAhPT0gMHgyMDBiID8gT05FX0VNIDogMDtcblxuICAgICAgICAgICAgICAgIC8vIEluIG9yZGVyIHRvIG1ha2UgZGlmZmVyZW50IGZvbnRzIGFsaWduZWQsIHRoZXkgbXVzdCBzaGFyZSBhIGdlbmVyYWwgYmFzZWxpbmUgdGhhdCBhbGlnbnMgd2l0aCBldmVyeVxuICAgICAgICAgICAgICAgIC8vIGZvbnQncyByZWFsIGJhc2VsaW5lLiBHbHlwaCdzIG9mZnNldCBpcyBjb3VudGVkIGZyb20gdGhlIHRvcCBsZWZ0IGNvcm5lciwgd2hlcmUgdGhlIGFzY2VuZGVyIGxpbmVcbiAgICAgICAgICAgICAgICAvLyBzdGFydHMuXG4gICAgICAgICAgICAgICAgLy8gRmlyc3Qgb2YgYWxsLCBlYWNoIGdseXBoJ3MgYmFzZWxpbmUgbGllcyBvbiB0aGUgY2VudGVyIGxpbmUgb2YgdGhlIHNoYXBpbmcgbGluZS4gU2luY2UgYXNjZW5kZXJcbiAgICAgICAgICAgICAgICAvLyBpcyBhYm92ZSB0aGUgYmFzZWxpbmUsIHRoZSBnbHlwaE9mZnNldCBpcyB0aGUgbmVnYXRpdmUgc2hpZnQuIFRoZW4sIGluIG9yZGVyIHRvIG1ha2UgZ2x5cGhzIGZpdCBpblxuICAgICAgICAgICAgICAgIC8vIHRoZSBzaGFwaW5nIGJveCwgZm9yIGVhY2ggbGluZSwgd2Ugc2hpZnQgdGhlIGdseXBoIHdpdGggYmlnZ2VzdCBoZWlnaHQod2l0aCBzY2FsZSkgdG8gbWFrZSBpdHMgY2VudGVyXG4gICAgICAgICAgICAgICAgLy8gbGllIG9uIHRoZSBjZW50ZXIgbGluZSBvZiB0aGUgbGluZSwgd2hpY2ggd2lsbCBsZWFkIHRvIGEgYmFzZWxpbmUgc2hpZnQuIFRoZW4gYWRqdXN0IHRoZSB3aG9sZSBsaW5lXG4gICAgICAgICAgICAgICAgLy8gd2l0aCB0aGUgYmFzZWxpbmUgb2Zmc2V0IHdlIGNhbGN1bGF0ZWQgZnJvbSB0aGUgc2hpZnQuXG4gICAgICAgICAgICAgICAgaWYgKGhhc0Jhc2VsaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFzY2VuZGVyID0gZ2x5cGhEYXRhLmFzY2VuZGVyICE9PSB1bmRlZmluZWQgPyBNYXRoLmFicyhnbHlwaERhdGEuYXNjZW5kZXIpIDogMDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVzY2VuZGVyID0gZ2x5cGhEYXRhLmRlc2NlbmRlciAhPT0gdW5kZWZpbmVkID8gTWF0aC5hYnMoZ2x5cGhEYXRhLmRlc2NlbmRlcikgOiAwO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IChhc2NlbmRlciArIGRlc2NlbmRlcikgKiBzZWN0aW9uU2NhbGU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChiaWdnZXN0SGVpZ2h0IDwgdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJpZ2dlc3RIZWlnaHQgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhc2VsaW5lT2Zmc2V0ID0gKGFzY2VuZGVyIC0gZGVzY2VuZGVyKSAvIDIgKiBzZWN0aW9uU2NhbGU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZ2x5cGhPZmZzZXQgPSAtYXNjZW5kZXIgKiBzZWN0aW9uU2NhbGU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgZm9udCdzIGJhc2VsaW5lIGlzIG5vdCBhcHBsaWNhYmxlLCBmYWxsIGJhY2sgdG8gdXNlIGEgZGVmYXVsdCBiYXNlbGluZSBvZmZzZXQsIHNlZVxuICAgICAgICAgICAgICAgICAgICAvLyBTaGFwaW5nOjp5T2Zmc2V0LiBTaW5jZSB3ZSdyZSBsYXlpbmcgb3V0IGF0IDI0IHBvaW50cywgd2UgbmVlZCBhbHNvIGNhbGN1bGF0ZSBob3cgbXVjaCBpdCB3aWxsXG4gICAgICAgICAgICAgICAgICAgIC8vIG1vdmUgd2hlbiB3ZSBzY2FsZSB1cCBvciBkb3duLlxuICAgICAgICAgICAgICAgICAgICBnbHlwaE9mZnNldCA9IFNIQVBJTkdfREVGQVVMVF9PRkZTRVQgKyAobGluZU1heFNjYWxlIC0gc2VjdGlvblNjYWxlKSAqIE9ORV9FTTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IGltYWdlUG9zaXRpb24gPSBpbWFnZVBvc2l0aW9uc1tzZWN0aW9uLmltYWdlTmFtZV07XG4gICAgICAgICAgICAgICAgaWYgKCFpbWFnZVBvc2l0aW9uKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICBpbWFnZU5hbWUgPSBzZWN0aW9uLmltYWdlTmFtZTtcbiAgICAgICAgICAgICAgICBzaGFwaW5nLmljb25zSW5UZXh0ID0gc2hhcGluZy5pY29uc0luVGV4dCB8fCB0cnVlO1xuICAgICAgICAgICAgICAgIHJlY3QgPSBpbWFnZVBvc2l0aW9uLnBhZGRlZFJlY3Q7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2l6ZSA9IGltYWdlUG9zaXRpb24uZGlzcGxheVNpemU7XG4gICAgICAgICAgICAgICAgLy8gSWYgbmVlZGVkLCBhbGxvdyB0byBzZXQgc2NhbGUgZmFjdG9yIGZvciBhbiBpbWFnZSB1c2luZ1xuICAgICAgICAgICAgICAgIC8vIGFsaWFzIFwiaW1hZ2Utc2NhbGVcIiB0aGF0IGNvdWxkIGJlIGFsaWFzIGZvciBcImZvbnQtc2NhbGVcIlxuICAgICAgICAgICAgICAgIC8vIHdoZW4gRm9ybWF0dGVkU2VjdGlvbiBpcyBhbiBpbWFnZSBzZWN0aW9uLlxuICAgICAgICAgICAgICAgIHNlY3Rpb25TY2FsZSA9IHNlY3Rpb25TY2FsZSAqIE9ORV9FTSAvIGxheW91dFRleHRTaXplVGhpc1pvb207XG5cbiAgICAgICAgICAgICAgICBtZXRyaWNzID0ge3dpZHRoOiBzaXplWzBdLFxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IHNpemVbMV0sXG4gICAgICAgICAgICAgICAgICAgIGxlZnQ6IElNQUdFX1BBRERJTkcsXG4gICAgICAgICAgICAgICAgICAgIHRvcDogLUdMWVBIX1BCRl9CT1JERVIsXG4gICAgICAgICAgICAgICAgICAgIGFkdmFuY2U6IHZlcnRpY2FsID8gc2l6ZVsxXSA6IHNpemVbMF0sXG4gICAgICAgICAgICAgICAgICAgIGxvY2FsR2x5cGg6IGZhbHNlfTtcblxuICAgICAgICAgICAgICAgIGlmICghaGFzQmFzZWxpbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgZ2x5cGhPZmZzZXQgPSBTSEFQSU5HX0RFRkFVTFRfT0ZGU0VUICsgbGluZU1heFNjYWxlICogT05FX0VNIC0gc2l6ZVsxXSAqIHNlY3Rpb25TY2FsZTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBCYXNlZCBvbiBub2RlLWZvbnRuaWs6ICd0b3AgPSBoZWlnaHRBYm92ZUJhc2VsaW5lIC0gQXNjZW5kZXInKGl0IGlzIG5vdCB2YWxpZCBmb3IgbG9jYWxseVxuICAgICAgICAgICAgICAgICAgICAvLyBnZW5lcmF0ZWQgZ2x5cGgpLiBTaW5jZSB0aGUgdG9wIGlzIGEgY29uc3RhbnQ6IGdseXBoJ3MgYm9yZGVyU2l6ZS4gU28gaWYgd2Ugc2V0IGltYWdlIGdseXBoIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgLy8gJ2FzY2VuZGVyID0gaGVpZ2h0JywgaXQgbWVhbnMgd2UgcHVsbCBkb3duIHRoZSBnbHlwaCB1bmRlciBiYXNlbGluZSB3aXRoIGEgZGlzdGFuY2Ugb2YgZ2x5cGgncyBib3JkZXJTaXplLlxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpbWFnZUFzY2VuZGVyID0gbWV0cmljcy5oZWlnaHQ7XG4gICAgICAgICAgICAgICAgICAgIGdseXBoT2Zmc2V0ID0gLWltYWdlQXNjZW5kZXIgKiBzZWN0aW9uU2NhbGU7XG5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmVydGljYWxBZHZhbmNlID0gbWV0cmljcy5hZHZhbmNlO1xuXG4gICAgICAgICAgICAgICAgLy8gRGlmZmVyZW5jZSBiZXR3ZWVuIGhlaWdodCBvZiBhbiBpbWFnZSBhbmQgb25lIEVNIGF0IG1heCBsaW5lIHNjYWxlLlxuICAgICAgICAgICAgICAgIC8vIFB1c2hlcyBjdXJyZW50IGxpbmUgZG93biBpZiBhbiBpbWFnZSBzaXplIGlzIG92ZXIgMSBFTSBhdCBtYXggbGluZSBzY2FsZS5cbiAgICAgICAgICAgICAgICBjb25zdCBvZmZzZXQgPSAodmVydGljYWwgPyBzaXplWzBdIDogc2l6ZVsxXSkgKiBzZWN0aW9uU2NhbGUgLSBPTkVfRU0gKiBsaW5lTWF4U2NhbGU7XG4gICAgICAgICAgICAgICAgaWYgKG9mZnNldCA+IDAgJiYgb2Zmc2V0ID4gbGluZU9mZnNldCkge1xuICAgICAgICAgICAgICAgICAgICBsaW5lT2Zmc2V0ID0gb2Zmc2V0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCF2ZXJ0aWNhbCkge1xuICAgICAgICAgICAgICAgIHBvc2l0aW9uZWRHbHlwaHMucHVzaCh7Z2x5cGg6IGNvZGVQb2ludCwgaW1hZ2VOYW1lLCB4LCB5OiB5ICsgZ2x5cGhPZmZzZXQsIHZlcnRpY2FsLCBzY2FsZTogc2VjdGlvblNjYWxlLCBsb2NhbEdseXBoOiBtZXRyaWNzLmxvY2FsR2x5cGgsIGZvbnRTdGFjazogc2VjdGlvbi5mb250U3RhY2ssIHNlY3Rpb25JbmRleCwgbWV0cmljcywgcmVjdH0pO1xuICAgICAgICAgICAgICAgIHggKz0gbWV0cmljcy5hZHZhbmNlICogc2VjdGlvblNjYWxlICsgc3BhY2luZztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc2hhcGluZy52ZXJ0aWNhbGl6YWJsZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgcG9zaXRpb25lZEdseXBocy5wdXNoKHtnbHlwaDogY29kZVBvaW50LCBpbWFnZU5hbWUsIHgsIHk6IHkgKyBnbHlwaE9mZnNldCwgdmVydGljYWwsIHNjYWxlOiBzZWN0aW9uU2NhbGUsIGxvY2FsR2x5cGg6IG1ldHJpY3MubG9jYWxHbHlwaCwgZm9udFN0YWNrOiBzZWN0aW9uLmZvbnRTdGFjaywgc2VjdGlvbkluZGV4LCBtZXRyaWNzLCByZWN0fSk7XG4gICAgICAgICAgICAgICAgeCArPSB2ZXJ0aWNhbEFkdmFuY2UgKiBzZWN0aW9uU2NhbGUgKyBzcGFjaW5nO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gT25seSBqdXN0aWZ5IGlmIHdlIHBsYWNlZCBhdCBsZWFzdCBvbmUgZ2x5cGhcbiAgICAgICAgaWYgKHBvc2l0aW9uZWRHbHlwaHMubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgICBjb25zdCBsaW5lTGVuZ3RoID0geCAtIHNwYWNpbmc7XG4gICAgICAgICAgICBtYXhMaW5lTGVuZ3RoID0gTWF0aC5tYXgobGluZUxlbmd0aCwgbWF4TGluZUxlbmd0aCk7XG4gICAgICAgICAgICAvLyBKdXN0aWZ5IHRoZSBsaW5lIHNvIHRoYXQgaXRzIHRvcCBpcyBhbGlnbmVkIHdpdGggdGhlIGN1cnJlbnQgaGVpZ2h0IG9mIHksIGFuZCBpdHMgaG9yaXpvbnRhbCBjb29yZGluYXRlc1xuICAgICAgICAgICAgLy8gYXJlIGp1c3RpZmllZCBhY2NvcmRpbmcgdG8gdGhlIFRleHRKdXN0aWZ5VHlwZVxuICAgICAgICAgICAgaWYgKGhhc0Jhc2VsaW5lKSB7XG4gICAgICAgICAgICAgICAganVzdGlmeUxpbmUocG9zaXRpb25lZEdseXBocywganVzdGlmeSwgbGluZU9mZnNldCwgYmFzZWxpbmVPZmZzZXQsIGxpbmVIZWlnaHQgKiBsaW5lTWF4U2NhbGUgLyAyKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gU2NhbGVkIGxpbmUgaGVpZ2h0IG9mZnNldCBpcyBjb3VudGVkIGluIGdseXBoT2Zmc2V0LCBzbyBoZXJlIGp1c3QgdXNlIGFuIHVuc2NhbGVkIGxpbmUgaGVpZ2h0XG4gICAgICAgICAgICAgICAganVzdGlmeUxpbmUocG9zaXRpb25lZEdseXBocywganVzdGlmeSwgbGluZU9mZnNldCwgMCwgbGluZUhlaWdodCAvIDIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgeCA9IDA7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRMaW5lSGVpZ2h0ID0gbGluZUhlaWdodCAqIGxpbmVNYXhTY2FsZSArIGxpbmVPZmZzZXQ7XG4gICAgICAgIHBvc2l0aW9uZWRMaW5lLmxpbmVPZmZzZXQgPSBNYXRoLm1heChsaW5lT2Zmc2V0LCBtYXhMaW5lT2Zmc2V0KTtcbiAgICAgICAgeSArPSBjdXJyZW50TGluZUhlaWdodDtcbiAgICAgICAgbWF4TGluZUhlaWdodCA9IE1hdGgubWF4KGN1cnJlbnRMaW5lSGVpZ2h0LCBtYXhMaW5lSGVpZ2h0KTtcbiAgICAgICAgKytsaW5lSW5kZXg7XG4gICAgfVxuXG4gICAgY29uc3QgaGVpZ2h0ID0geTtcbiAgICBjb25zdCB7aG9yaXpvbnRhbEFsaWduLCB2ZXJ0aWNhbEFsaWdufSA9IGdldEFuY2hvckFsaWdubWVudCh0ZXh0QW5jaG9yKTtcbiAgICBhbGlnbihzaGFwaW5nLnBvc2l0aW9uZWRMaW5lcywganVzdGlmeSwgaG9yaXpvbnRhbEFsaWduLCB2ZXJ0aWNhbEFsaWduLCBtYXhMaW5lTGVuZ3RoLCBoZWlnaHQpO1xuICAgIC8vIENhbGN1bGF0ZSB0aGUgYm91bmRpbmcgYm94XG4gICAgc2hhcGluZy50b3AgKz0gLXZlcnRpY2FsQWxpZ24gKiBoZWlnaHQ7XG4gICAgc2hhcGluZy5ib3R0b20gPSBzaGFwaW5nLnRvcCArIGhlaWdodDtcbiAgICBzaGFwaW5nLmxlZnQgKz0gLWhvcml6b250YWxBbGlnbiAqIG1heExpbmVMZW5ndGg7XG4gICAgc2hhcGluZy5yaWdodCA9IHNoYXBpbmcubGVmdCArIG1heExpbmVMZW5ndGg7XG4gICAgc2hhcGluZy5oYXNCYXNlbGluZSA9IGhhc0Jhc2VsaW5lO1xufVxuXG4vLyBqdXN0aWZ5IHJpZ2h0ID0gMSwgbGVmdCA9IDAsIGNlbnRlciA9IDAuNVxuZnVuY3Rpb24ganVzdGlmeUxpbmUocG9zaXRpb25lZEdseXBoczogQXJyYXk8UG9zaXRpb25lZEdseXBoPixcbiAgICAgICAgICAgICAgICAgICAgIGp1c3RpZnk6IDEgfCAwIHwgMC41LFxuICAgICAgICAgICAgICAgICAgICAgbGluZU9mZnNldDogbnVtYmVyLFxuICAgICAgICAgICAgICAgICAgICAgYmFzZWxpbmVPZmZzZXQ6IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgIGhhbGZMaW5lSGVpZ2h0OiBudW1iZXIpIHtcbiAgICBpZiAoIWp1c3RpZnkgJiYgIWxpbmVPZmZzZXQgJiYgIWJhc2VsaW5lT2Zmc2V0ICYmICFoYWxmTGluZUhlaWdodCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGVuZCA9IHBvc2l0aW9uZWRHbHlwaHMubGVuZ3RoIC0gMTtcbiAgICBjb25zdCBsYXN0R2x5cGggPSBwb3NpdGlvbmVkR2x5cGhzW2VuZF07XG4gICAgY29uc3QgbGFzdEFkdmFuY2UgPSBsYXN0R2x5cGgubWV0cmljcy5hZHZhbmNlICogbGFzdEdseXBoLnNjYWxlO1xuICAgIGNvbnN0IGxpbmVJbmRlbnQgPSAobGFzdEdseXBoLnggKyBsYXN0QWR2YW5jZSkgKiBqdXN0aWZ5O1xuXG4gICAgZm9yIChsZXQgaiA9IDA7IGogPD0gZW5kOyBqKyspIHtcbiAgICAgICAgcG9zaXRpb25lZEdseXBoc1tqXS54IC09IGxpbmVJbmRlbnQ7XG4gICAgICAgIHBvc2l0aW9uZWRHbHlwaHNbal0ueSArPSBsaW5lT2Zmc2V0ICsgYmFzZWxpbmVPZmZzZXQgKyBoYWxmTGluZUhlaWdodDtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGFsaWduKHBvc2l0aW9uZWRMaW5lczogQXJyYXk8UG9zaXRpb25lZExpbmU+LFxuICAgICAgICAgICAgICAganVzdGlmeTogbnVtYmVyLFxuICAgICAgICAgICAgICAgaG9yaXpvbnRhbEFsaWduOiBudW1iZXIsXG4gICAgICAgICAgICAgICB2ZXJ0aWNhbEFsaWduOiBudW1iZXIsXG4gICAgICAgICAgICAgICBtYXhMaW5lTGVuZ3RoOiBudW1iZXIsXG4gICAgICAgICAgICAgICBibG9ja0hlaWdodDogbnVtYmVyKSB7XG4gICAgY29uc3Qgc2hpZnRYID0gKGp1c3RpZnkgLSBob3Jpem9udGFsQWxpZ24pICogbWF4TGluZUxlbmd0aDtcblxuICAgIGNvbnN0IHNoaWZ0WSA9IC1ibG9ja0hlaWdodCAqIHZlcnRpY2FsQWxpZ247XG4gICAgZm9yIChjb25zdCBsaW5lIG9mIHBvc2l0aW9uZWRMaW5lcykge1xuICAgICAgICBmb3IgKGNvbnN0IHBvc2l0aW9uZWRHbHlwaCBvZiBsaW5lLnBvc2l0aW9uZWRHbHlwaHMpIHtcbiAgICAgICAgICAgIHBvc2l0aW9uZWRHbHlwaC54ICs9IHNoaWZ0WDtcbiAgICAgICAgICAgIHBvc2l0aW9uZWRHbHlwaC55ICs9IHNoaWZ0WTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IHR5cGUgUG9zaXRpb25lZEljb24gPSB7XG4gICAgaW1hZ2U6IEltYWdlUG9zaXRpb24sXG4gICAgdG9wOiBudW1iZXIsXG4gICAgYm90dG9tOiBudW1iZXIsXG4gICAgbGVmdDogbnVtYmVyLFxuICAgIHJpZ2h0OiBudW1iZXIsXG4gICAgY29sbGlzaW9uUGFkZGluZz86IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdXG59O1xuXG5mdW5jdGlvbiBzaGFwZUljb24oaW1hZ2U6IEltYWdlUG9zaXRpb24sIGljb25PZmZzZXQ6IFtudW1iZXIsIG51bWJlcl0sIGljb25BbmNob3I6IFN5bWJvbEFuY2hvcik6IFBvc2l0aW9uZWRJY29uIHtcbiAgICBjb25zdCB7aG9yaXpvbnRhbEFsaWduLCB2ZXJ0aWNhbEFsaWdufSA9IGdldEFuY2hvckFsaWdubWVudChpY29uQW5jaG9yKTtcbiAgICBjb25zdCBkeCA9IGljb25PZmZzZXRbMF07XG4gICAgY29uc3QgZHkgPSBpY29uT2Zmc2V0WzFdO1xuICAgIGNvbnN0IHgxID0gZHggLSBpbWFnZS5kaXNwbGF5U2l6ZVswXSAqIGhvcml6b250YWxBbGlnbjtcbiAgICBjb25zdCB4MiA9IHgxICsgaW1hZ2UuZGlzcGxheVNpemVbMF07XG4gICAgY29uc3QgeTEgPSBkeSAtIGltYWdlLmRpc3BsYXlTaXplWzFdICogdmVydGljYWxBbGlnbjtcbiAgICBjb25zdCB5MiA9IHkxICsgaW1hZ2UuZGlzcGxheVNpemVbMV07XG4gICAgcmV0dXJuIHtpbWFnZSwgdG9wOiB5MSwgYm90dG9tOiB5MiwgbGVmdDogeDEsIHJpZ2h0OiB4Mn07XG59XG5cbmZ1bmN0aW9uIGZpdEljb25Ub1RleHQoc2hhcGVkSWNvbjogUG9zaXRpb25lZEljb24sIHNoYXBlZFRleHQ6IFNoYXBpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgIHRleHRGaXQ6IHN0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgcGFkZGluZzogWyBudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXIgXSxcbiAgICAgICAgICAgICAgICAgICAgICAgaWNvbk9mZnNldDogWyBudW1iZXIsIG51bWJlciBdLCBmb250U2NhbGU6IG51bWJlcik6IFBvc2l0aW9uZWRJY29uIHtcbiAgICBhc3NlcnQodGV4dEZpdCAhPT0gJ25vbmUnKTtcbiAgICBhc3NlcnQoQXJyYXkuaXNBcnJheShwYWRkaW5nKSAmJiBwYWRkaW5nLmxlbmd0aCA9PT0gNCk7XG4gICAgYXNzZXJ0KEFycmF5LmlzQXJyYXkoaWNvbk9mZnNldCkgJiYgaWNvbk9mZnNldC5sZW5ndGggPT09IDIpO1xuXG4gICAgY29uc3QgaW1hZ2UgPSBzaGFwZWRJY29uLmltYWdlO1xuXG4gICAgbGV0IGNvbGxpc2lvblBhZGRpbmc7XG4gICAgaWYgKGltYWdlLmNvbnRlbnQpIHtcbiAgICAgICAgY29uc3QgY29udGVudCA9IGltYWdlLmNvbnRlbnQ7XG4gICAgICAgIGNvbnN0IHBpeGVsUmF0aW8gPSBpbWFnZS5waXhlbFJhdGlvIHx8IDE7XG4gICAgICAgIGNvbGxpc2lvblBhZGRpbmcgPSBbXG4gICAgICAgICAgICBjb250ZW50WzBdIC8gcGl4ZWxSYXRpbyxcbiAgICAgICAgICAgIGNvbnRlbnRbMV0gLyBwaXhlbFJhdGlvLFxuICAgICAgICAgICAgaW1hZ2UuZGlzcGxheVNpemVbMF0gLSBjb250ZW50WzJdIC8gcGl4ZWxSYXRpbyxcbiAgICAgICAgICAgIGltYWdlLmRpc3BsYXlTaXplWzFdIC0gY29udGVudFszXSAvIHBpeGVsUmF0aW9cbiAgICAgICAgXTtcbiAgICB9XG5cbiAgICAvLyBXZSBkb24ndCByZXNwZWN0IHRoZSBpY29uLWFuY2hvciwgYmVjYXVzZSBpY29uLXRleHQtZml0IGlzIHNldC4gSW5zdGVhZCxcbiAgICAvLyB0aGUgaWNvbiB3aWxsIGJlIGNlbnRlcmVkIG9uIHRoZSB0ZXh0LCB0aGVuIHN0cmV0Y2hlZCBpbiB0aGUgZ2l2ZW5cbiAgICAvLyBkaW1lbnNpb25zLlxuXG4gICAgY29uc3QgdGV4dExlZnQgPSBzaGFwZWRUZXh0LmxlZnQgKiBmb250U2NhbGU7XG4gICAgY29uc3QgdGV4dFJpZ2h0ID0gc2hhcGVkVGV4dC5yaWdodCAqIGZvbnRTY2FsZTtcblxuICAgIGxldCB0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnQ7XG4gICAgaWYgKHRleHRGaXQgPT09ICd3aWR0aCcgfHwgdGV4dEZpdCA9PT0gJ2JvdGgnKSB7XG4gICAgICAgIC8vIFN0cmV0Y2hlZCBob3Jpem9udGFsbHkgdG8gdGhlIHRleHQgd2lkdGhcbiAgICAgICAgbGVmdCA9IGljb25PZmZzZXRbMF0gKyB0ZXh0TGVmdCAtIHBhZGRpbmdbM107XG4gICAgICAgIHJpZ2h0ID0gaWNvbk9mZnNldFswXSArIHRleHRSaWdodCArIHBhZGRpbmdbMV07XG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQ2VudGVyZWQgb24gdGhlIHRleHRcbiAgICAgICAgbGVmdCA9IGljb25PZmZzZXRbMF0gKyAodGV4dExlZnQgKyB0ZXh0UmlnaHQgLSBpbWFnZS5kaXNwbGF5U2l6ZVswXSkgLyAyO1xuICAgICAgICByaWdodCA9IGxlZnQgKyBpbWFnZS5kaXNwbGF5U2l6ZVswXTtcbiAgICB9XG5cbiAgICBjb25zdCB0ZXh0VG9wID0gc2hhcGVkVGV4dC50b3AgKiBmb250U2NhbGU7XG4gICAgY29uc3QgdGV4dEJvdHRvbSA9IHNoYXBlZFRleHQuYm90dG9tICogZm9udFNjYWxlO1xuICAgIGlmICh0ZXh0Rml0ID09PSAnaGVpZ2h0JyB8fCB0ZXh0Rml0ID09PSAnYm90aCcpIHtcbiAgICAgICAgLy8gU3RyZXRjaGVkIHZlcnRpY2FsbHkgdG8gdGhlIHRleHQgaGVpZ2h0XG4gICAgICAgIHRvcCA9IGljb25PZmZzZXRbMV0gKyB0ZXh0VG9wIC0gcGFkZGluZ1swXTtcbiAgICAgICAgYm90dG9tID0gaWNvbk9mZnNldFsxXSArIHRleHRCb3R0b20gKyBwYWRkaW5nWzJdO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIENlbnRlcmVkIG9uIHRoZSB0ZXh0XG4gICAgICAgIHRvcCA9IGljb25PZmZzZXRbMV0gKyAodGV4dFRvcCArIHRleHRCb3R0b20gLSBpbWFnZS5kaXNwbGF5U2l6ZVsxXSkgLyAyO1xuICAgICAgICBib3R0b20gPSB0b3AgKyBpbWFnZS5kaXNwbGF5U2l6ZVsxXTtcbiAgICB9XG5cbiAgICByZXR1cm4ge2ltYWdlLCB0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnQsIGNvbGxpc2lvblBhZGRpbmd9O1xufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IFBvaW50IGZyb20gJ0BtYXBib3gvcG9pbnQtZ2VvbWV0cnknO1xuXG5pbXBvcnQge3JlZ2lzdGVyfSBmcm9tICcuLi91dGlsL3dlYl93b3JrZXJfdHJhbnNmZXIuanMnO1xuXG5jbGFzcyBBbmNob3IgZXh0ZW5kcyBQb2ludCB7XG4gICAgYW5nbGU6IGFueTtcbiAgICB6OiBudW1iZXI7XG4gICAgc2VnbWVudDogbnVtYmVyIHwgdm9pZDtcblxuICAgIGNvbnN0cnVjdG9yKHg6IG51bWJlciwgeTogbnVtYmVyLCB6OiBudW1iZXIsIGFuZ2xlOiBudW1iZXIsIHNlZ21lbnQ/OiBudW1iZXIpIHtcbiAgICAgICAgc3VwZXIoeCwgeSk7XG4gICAgICAgIHRoaXMuYW5nbGUgPSBhbmdsZTtcbiAgICAgICAgdGhpcy56ID0gejtcbiAgICAgICAgaWYgKHNlZ21lbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5zZWdtZW50ID0gc2VnbWVudDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNsb25lKCk6IEFuY2hvciB7XG4gICAgICAgIHJldHVybiBuZXcgQW5jaG9yKHRoaXMueCwgdGhpcy55LCB0aGlzLnosIHRoaXMuYW5nbGUsIHRoaXMuc2VnbWVudCk7XG4gICAgfVxufVxuXG5yZWdpc3RlcihBbmNob3IsICdBbmNob3InKTtcblxuZXhwb3J0IGRlZmF1bHQgQW5jaG9yO1xuIiwiLy8gQGZsb3dcblxuZXhwb3J0IGRlZmF1bHQgY2hlY2tNYXhBbmdsZTtcblxuaW1wb3J0IHR5cGUgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5pbXBvcnQgdHlwZSBBbmNob3IgZnJvbSAnLi9hbmNob3IuanMnO1xuXG4vKipcbiAqIExhYmVscyBwbGFjZWQgYXJvdW5kIHJlYWxseSBzaGFycCBhbmdsZXMgYXJlbid0IHJlYWRhYmxlLiBDaGVjayBpZiBhbnlcbiAqIHBhcnQgb2YgdGhlIHBvdGVudGlhbCBsYWJlbCBoYXMgYSBjb21iaW5lZCBhbmdsZSB0aGF0IGlzIHRvbyBiaWcuXG4gKlxuICogQHBhcmFtIGxpbmVcbiAqIEBwYXJhbSBhbmNob3IgVGhlIHBvaW50IG9uIHRoZSBsaW5lIGFyb3VuZCB3aGljaCB0aGUgbGFiZWwgaXMgYW5jaG9yZWQuXG4gKiBAcGFyYW0gbGFiZWxMZW5ndGggVGhlIGxlbmd0aCBvZiB0aGUgbGFiZWwgaW4gZ2VvbWV0cnkgdW5pdHMuXG4gKiBAcGFyYW0gd2luZG93U2l6ZSBUaGUgY2hlY2sgZmFpbHMgaWYgdGhlIGNvbWJpbmVkIGFuZ2xlcyB3aXRoaW4gYSBwYXJ0IG9mIHRoZSBsaW5lIHRoYXQgaXMgYHdpbmRvd1NpemVgIGxvbmcgaXMgdG9vIGJpZy5cbiAqIEBwYXJhbSBtYXhBbmdsZSBUaGUgbWF4aW11bSBjb21iaW5lZCBhbmdsZSB0aGF0IGFueSB3aW5kb3cgYWxvbmcgdGhlIGxhYmVsIGlzIGFsbG93ZWQgdG8gaGF2ZS5cbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gd2hldGhlciB0aGUgbGFiZWwgc2hvdWxkIGJlIHBsYWNlZFxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gY2hlY2tNYXhBbmdsZShsaW5lOiBBcnJheTxQb2ludD4sIGFuY2hvcjogQW5jaG9yLCBsYWJlbExlbmd0aDogbnVtYmVyLCB3aW5kb3dTaXplOiBudW1iZXIsIG1heEFuZ2xlOiBudW1iZXIpOiBib29sZWFuIHtcblxuICAgIC8vIGhvcml6b250YWwgbGFiZWxzIGFsd2F5cyBwYXNzXG4gICAgaWYgKGFuY2hvci5zZWdtZW50ID09PSB1bmRlZmluZWQpIHJldHVybiB0cnVlO1xuXG4gICAgbGV0IHA6IFBvaW50ID0gYW5jaG9yO1xuICAgIGxldCBpbmRleCA9IGFuY2hvci5zZWdtZW50ICsgMTtcbiAgICBsZXQgYW5jaG9yRGlzdGFuY2UgPSAwO1xuXG4gICAgLy8gbW92ZSBiYWNrd2FyZHMgYWxvbmcgdGhlIGxpbmUgdG8gdGhlIGZpcnN0IHNlZ21lbnQgdGhlIGxhYmVsIGFwcGVhcnMgb25cbiAgICB3aGlsZSAoYW5jaG9yRGlzdGFuY2UgPiAtbGFiZWxMZW5ndGggLyAyKSB7XG4gICAgICAgIGluZGV4LS07XG5cbiAgICAgICAgLy8gdGhlcmUgaXNuJ3QgZW5vdWdoIHJvb20gZm9yIHRoZSBsYWJlbCBhZnRlciB0aGUgYmVnaW5uaW5nIG9mIHRoZSBsaW5lXG4gICAgICAgIGlmIChpbmRleCA8IDApIHJldHVybiBmYWxzZTtcblxuICAgICAgICBhbmNob3JEaXN0YW5jZSAtPSBsaW5lW2luZGV4XS5kaXN0KHApO1xuICAgICAgICBwID0gbGluZVtpbmRleF07XG4gICAgfVxuXG4gICAgYW5jaG9yRGlzdGFuY2UgKz0gbGluZVtpbmRleF0uZGlzdChsaW5lW2luZGV4ICsgMV0pO1xuICAgIGluZGV4Kys7XG5cbiAgICAvLyBzdG9yZSByZWNlbnQgY29ybmVycyBhbmQgdGhlaXIgdG90YWwgYW5nbGUgZGlmZmVyZW5jZVxuICAgIGNvbnN0IHJlY2VudENvcm5lcnMgPSBbXTtcbiAgICBsZXQgcmVjZW50QW5nbGVEZWx0YSA9IDA7XG5cbiAgICAvLyBtb3ZlIGZvcndhcmRzIGJ5IHRoZSBsZW5ndGggb2YgdGhlIGxhYmVsIGFuZCBjaGVjayBhbmdsZXMgYWxvbmcgdGhlIHdheVxuICAgIHdoaWxlIChhbmNob3JEaXN0YW5jZSA8IGxhYmVsTGVuZ3RoIC8gMikge1xuICAgICAgICBjb25zdCBwcmV2ID0gbGluZVtpbmRleCAtIDFdO1xuICAgICAgICBjb25zdCBjdXJyZW50ID0gbGluZVtpbmRleF07XG4gICAgICAgIGNvbnN0IG5leHQgPSBsaW5lW2luZGV4ICsgMV07XG5cbiAgICAgICAgLy8gdGhlcmUgaXNuJ3QgZW5vdWdoIHJvb20gZm9yIHRoZSBsYWJlbCBiZWZvcmUgdGhlIGVuZCBvZiB0aGUgbGluZVxuICAgICAgICBpZiAoIW5leHQpIHJldHVybiBmYWxzZTtcblxuICAgICAgICBsZXQgYW5nbGVEZWx0YSA9IHByZXYuYW5nbGVUbyhjdXJyZW50KSAtIGN1cnJlbnQuYW5nbGVUbyhuZXh0KTtcbiAgICAgICAgLy8gcmVzdHJpY3QgYW5nbGUgdG8gLXBpLi5waSByYW5nZVxuICAgICAgICBhbmdsZURlbHRhID0gTWF0aC5hYnMoKChhbmdsZURlbHRhICsgMyAqIE1hdGguUEkpICUgKE1hdGguUEkgKiAyKSkgLSBNYXRoLlBJKTtcblxuICAgICAgICByZWNlbnRDb3JuZXJzLnB1c2goe1xuICAgICAgICAgICAgZGlzdGFuY2U6IGFuY2hvckRpc3RhbmNlLFxuICAgICAgICAgICAgYW5nbGVEZWx0YVxuICAgICAgICB9KTtcbiAgICAgICAgcmVjZW50QW5nbGVEZWx0YSArPSBhbmdsZURlbHRhO1xuXG4gICAgICAgIC8vIHJlbW92ZSBjb3JuZXJzIHRoYXQgYXJlIGZhciBlbm91Z2ggYXdheSBmcm9tIHRoZSBsaXN0IG9mIHJlY2VudCBhbmNob3JzXG4gICAgICAgIHdoaWxlIChhbmNob3JEaXN0YW5jZSAtIHJlY2VudENvcm5lcnNbMF0uZGlzdGFuY2UgPiB3aW5kb3dTaXplKSB7XG4gICAgICAgICAgICByZWNlbnRBbmdsZURlbHRhIC09IHJlY2VudENvcm5lcnMuc2hpZnQoKS5hbmdsZURlbHRhO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdGhlIHN1bSBvZiBhbmdsZXMgd2l0aGluIHRoZSB3aW5kb3cgYXJlYSBleGNlZWRzIHRoZSBtYXhpbXVtIGFsbG93ZWQgdmFsdWUuIGNoZWNrIGZhaWxzLlxuICAgICAgICBpZiAocmVjZW50QW5nbGVEZWx0YSA+IG1heEFuZ2xlKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgaW5kZXgrKztcbiAgICAgICAgYW5jaG9yRGlzdGFuY2UgKz0gY3VycmVudC5kaXN0KG5leHQpO1xuICAgIH1cblxuICAgIC8vIG5vIHBhcnQgb2YgdGhlIGxpbmUgaGFkIGFuIGFuZ2xlIGdyZWF0ZXIgdGhhbiB0aGUgbWF4aW11bSBhbGxvd2VkLiBjaGVjayBwYXNzZXMuXG4gICAgcmV0dXJuIHRydWU7XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge251bWJlciBhcyBpbnRlcnBvbGF0ZX0gZnJvbSAnLi4vc3R5bGUtc3BlYy91dGlsL2ludGVycG9sYXRlLmpzJztcblxuaW1wb3J0IEFuY2hvciBmcm9tICcuLi9zeW1ib2wvYW5jaG9yLmpzJztcbmltcG9ydCBjaGVja01heEFuZ2xlIGZyb20gJy4vY2hlY2tfbWF4X2FuZ2xlLmpzJztcblxuaW1wb3J0IHR5cGUgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5pbXBvcnQgdHlwZSB7U2hhcGluZywgUG9zaXRpb25lZEljb259IGZyb20gJy4vc2hhcGluZy5qcyc7XG5cbmV4cG9ydCB7Z2V0QW5jaG9ycywgZ2V0Q2VudGVyQW5jaG9yfTtcblxuZnVuY3Rpb24gZ2V0TGluZUxlbmd0aChsaW5lOiBBcnJheTxQb2ludD4pOiBudW1iZXIge1xuICAgIGxldCBsaW5lTGVuZ3RoID0gMDtcbiAgICBmb3IgKGxldCBrID0gMDsgayA8IGxpbmUubGVuZ3RoIC0gMTsgaysrKSB7XG4gICAgICAgIGxpbmVMZW5ndGggKz0gbGluZVtrXS5kaXN0KGxpbmVbayArIDFdKTtcbiAgICB9XG4gICAgcmV0dXJuIGxpbmVMZW5ndGg7XG59XG5cbmZ1bmN0aW9uIGdldEFuZ2xlV2luZG93U2l6ZShzaGFwZWRUZXh0OiA/U2hhcGluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbHlwaFNpemU6IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3hTY2FsZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gc2hhcGVkVGV4dCA/XG4gICAgICAgIDMgLyA1ICogZ2x5cGhTaXplICogYm94U2NhbGUgOlxuICAgICAgICAwO1xufVxuXG5mdW5jdGlvbiBnZXRTaGFwZWRMYWJlbExlbmd0aChzaGFwZWRUZXh0OiA/U2hhcGluZywgc2hhcGVkSWNvbjogP1Bvc2l0aW9uZWRJY29uKTogbnVtYmVyIHtcbiAgICByZXR1cm4gTWF0aC5tYXgoXG4gICAgICAgIHNoYXBlZFRleHQgPyBzaGFwZWRUZXh0LnJpZ2h0IC0gc2hhcGVkVGV4dC5sZWZ0IDogMCxcbiAgICAgICAgc2hhcGVkSWNvbiA/IHNoYXBlZEljb24ucmlnaHQgLSBzaGFwZWRJY29uLmxlZnQgOiAwKTtcbn1cblxuZnVuY3Rpb24gZ2V0Q2VudGVyQW5jaG9yKGxpbmU6IEFycmF5PFBvaW50PixcbiAgICAgICAgICAgICAgICAgICAgICAgICBtYXhBbmdsZTogbnVtYmVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgIHNoYXBlZFRleHQ6ID9TaGFwaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgIHNoYXBlZEljb246ID9Qb3NpdGlvbmVkSWNvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICBnbHlwaFNpemU6IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICBib3hTY2FsZTogbnVtYmVyKTogP0FuY2hvciB7XG4gICAgY29uc3QgYW5nbGVXaW5kb3dTaXplID0gZ2V0QW5nbGVXaW5kb3dTaXplKHNoYXBlZFRleHQsIGdseXBoU2l6ZSwgYm94U2NhbGUpO1xuICAgIGNvbnN0IGxhYmVsTGVuZ3RoID0gZ2V0U2hhcGVkTGFiZWxMZW5ndGgoc2hhcGVkVGV4dCwgc2hhcGVkSWNvbikgKiBib3hTY2FsZTtcblxuICAgIGxldCBwcmV2RGlzdGFuY2UgPSAwO1xuICAgIGNvbnN0IGNlbnRlckRpc3RhbmNlID0gZ2V0TGluZUxlbmd0aChsaW5lKSAvIDI7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmUubGVuZ3RoIC0gMTsgaSsrKSB7XG5cbiAgICAgICAgY29uc3QgYSA9IGxpbmVbaV0sXG4gICAgICAgICAgICBiID0gbGluZVtpICsgMV07XG5cbiAgICAgICAgY29uc3Qgc2VnbWVudERpc3RhbmNlID0gYS5kaXN0KGIpO1xuXG4gICAgICAgIGlmIChwcmV2RGlzdGFuY2UgKyBzZWdtZW50RGlzdGFuY2UgPiBjZW50ZXJEaXN0YW5jZSkge1xuICAgICAgICAgICAgLy8gVGhlIGNlbnRlciBpcyBvbiB0aGlzIHNlZ21lbnRcbiAgICAgICAgICAgIGNvbnN0IHQgPSAoY2VudGVyRGlzdGFuY2UgLSBwcmV2RGlzdGFuY2UpIC8gc2VnbWVudERpc3RhbmNlLFxuICAgICAgICAgICAgICAgIHggPSBpbnRlcnBvbGF0ZShhLngsIGIueCwgdCksXG4gICAgICAgICAgICAgICAgeSA9IGludGVycG9sYXRlKGEueSwgYi55LCB0KTtcblxuICAgICAgICAgICAgY29uc3QgYW5jaG9yID0gbmV3IEFuY2hvcih4LCB5LCAwLCBiLmFuZ2xlVG8oYSksIGkpO1xuICAgICAgICAgICAgaWYgKCFhbmdsZVdpbmRvd1NpemUgfHwgY2hlY2tNYXhBbmdsZShsaW5lLCBhbmNob3IsIGxhYmVsTGVuZ3RoLCBhbmdsZVdpbmRvd1NpemUsIG1heEFuZ2xlKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBhbmNob3I7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHByZXZEaXN0YW5jZSArPSBzZWdtZW50RGlzdGFuY2U7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBnZXRBbmNob3JzKGxpbmU6IEFycmF5PFBvaW50PixcbiAgICAgICAgICAgICAgICAgICAgc3BhY2luZzogbnVtYmVyLFxuICAgICAgICAgICAgICAgICAgICBtYXhBbmdsZTogbnVtYmVyLFxuICAgICAgICAgICAgICAgICAgICBzaGFwZWRUZXh0OiA/U2hhcGluZyxcbiAgICAgICAgICAgICAgICAgICAgc2hhcGVkSWNvbjogP1Bvc2l0aW9uZWRJY29uLFxuICAgICAgICAgICAgICAgICAgICBnbHlwaFNpemU6IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgYm94U2NhbGU6IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgb3ZlcnNjYWxpbmc6IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgdGlsZUV4dGVudDogbnVtYmVyKTogQXJyYXk8QW5jaG9yPiB7XG5cbiAgICAvLyBSZXNhbXBsZSBhIGxpbmUgdG8gZ2V0IGFuY2hvciBwb2ludHMgZm9yIGxhYmVscyBhbmQgY2hlY2sgdGhhdCBlYWNoXG4gICAgLy8gcG90ZW50aWFsIGxhYmVsIHBhc3NlcyB0ZXh0LW1heC1hbmdsZSBjaGVjayBhbmQgaGFzIGVub3VnaCBmcm9vbSB0byBmaXRcbiAgICAvLyBvbiB0aGUgbGluZS5cblxuICAgIGNvbnN0IGFuZ2xlV2luZG93U2l6ZSA9IGdldEFuZ2xlV2luZG93U2l6ZShzaGFwZWRUZXh0LCBnbHlwaFNpemUsIGJveFNjYWxlKTtcbiAgICBjb25zdCBzaGFwZWRMYWJlbExlbmd0aCA9IGdldFNoYXBlZExhYmVsTGVuZ3RoKHNoYXBlZFRleHQsIHNoYXBlZEljb24pO1xuICAgIGNvbnN0IGxhYmVsTGVuZ3RoID0gc2hhcGVkTGFiZWxMZW5ndGggKiBib3hTY2FsZTtcblxuICAgIC8vIElzIHRoZSBsaW5lIGNvbnRpbnVlZCBmcm9tIG91dHNpZGUgdGhlIHRpbGUgYm91bmRhcnk/XG4gICAgY29uc3QgaXNMaW5lQ29udGludWVkID0gbGluZVswXS54ID09PSAwIHx8IGxpbmVbMF0ueCA9PT0gdGlsZUV4dGVudCB8fCBsaW5lWzBdLnkgPT09IDAgfHwgbGluZVswXS55ID09PSB0aWxlRXh0ZW50O1xuXG4gICAgLy8gSXMgdGhlIGxhYmVsIGxvbmcsIHJlbGF0aXZlIHRvIHRoZSBzcGFjaW5nP1xuICAgIC8vIElmIHNvLCBhZGp1c3QgdGhlIHNwYWNpbmcgc28gdGhlcmUgaXMgYWx3YXlzIGEgbWluaW11bSBzcGFjZSBvZiBgc3BhY2luZyAvIDRgIGJldHdlZW4gbGFiZWwgZWRnZXMuXG4gICAgaWYgKHNwYWNpbmcgLSBsYWJlbExlbmd0aCA8IHNwYWNpbmcgLyA0KSB7XG4gICAgICAgIHNwYWNpbmcgPSBsYWJlbExlbmd0aCArIHNwYWNpbmcgLyA0O1xuICAgIH1cblxuICAgIC8vIE9mZnNldCB0aGUgZmlyc3QgYW5jaG9yIGJ5OlxuICAgIC8vIEVpdGhlciBoYWxmIHRoZSBsYWJlbCBsZW5ndGggcGx1cyBhIGZpeGVkIGV4dHJhIG9mZnNldCBpZiB0aGUgbGluZSBpcyBub3QgY29udGludWVkXG4gICAgLy8gT3IgaGFsZiB0aGUgc3BhY2luZyBpZiB0aGUgbGluZSBpcyBjb250aW51ZWQuXG5cbiAgICAvLyBGb3Igbm9uLWNvbnRpbnVlZCBsaW5lcywgYWRkIGEgYml0IG9mIGZpeGVkIGV4dHJhIG9mZnNldCB0byBhdm9pZCBjb2xsaXNpb25zIGF0IFQgaW50ZXJzZWN0aW9ucy5cbiAgICBjb25zdCBmaXhlZEV4dHJhT2Zmc2V0ID0gZ2x5cGhTaXplICogMjtcblxuICAgIGNvbnN0IG9mZnNldCA9ICFpc0xpbmVDb250aW51ZWQgP1xuICAgICAgICAoKHNoYXBlZExhYmVsTGVuZ3RoIC8gMiArIGZpeGVkRXh0cmFPZmZzZXQpICogYm94U2NhbGUgKiBvdmVyc2NhbGluZykgJSBzcGFjaW5nIDpcbiAgICAgICAgKHNwYWNpbmcgLyAyICogb3ZlcnNjYWxpbmcpICUgc3BhY2luZztcblxuICAgIHJldHVybiByZXNhbXBsZShsaW5lLCBvZmZzZXQsIHNwYWNpbmcsIGFuZ2xlV2luZG93U2l6ZSwgbWF4QW5nbGUsIGxhYmVsTGVuZ3RoLCBpc0xpbmVDb250aW51ZWQsIGZhbHNlLCB0aWxlRXh0ZW50KTtcbn1cblxuZnVuY3Rpb24gcmVzYW1wbGUobGluZTogQXJyYXk8UG9pbnQ+LCBvZmZzZXQ6IG51bWJlciwgc3BhY2luZzogbnVtYmVyLCBhbmdsZVdpbmRvd1NpemU6IG51bWJlciwgbWF4QW5nbGU6IG51bWJlciwgbGFiZWxMZW5ndGg6IG51bWJlciwgaXNMaW5lQ29udGludWVkOiBib29sZWFuLCBwbGFjZUF0TWlkZGxlOiBib29sZWFuLCB0aWxlRXh0ZW50OiBudW1iZXIpIHtcblxuICAgIGNvbnN0IGhhbGZMYWJlbExlbmd0aCA9IGxhYmVsTGVuZ3RoIC8gMjtcbiAgICBjb25zdCBsaW5lTGVuZ3RoID0gZ2V0TGluZUxlbmd0aChsaW5lKTtcblxuICAgIGxldCBkaXN0YW5jZSA9IDAsXG4gICAgICAgIG1hcmtlZERpc3RhbmNlID0gb2Zmc2V0IC0gc3BhY2luZztcblxuICAgIGxldCBhbmNob3JzID0gW107XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmUubGVuZ3RoIC0gMTsgaSsrKSB7XG5cbiAgICAgICAgY29uc3QgYSA9IGxpbmVbaV0sXG4gICAgICAgICAgICBiID0gbGluZVtpICsgMV07XG5cbiAgICAgICAgY29uc3Qgc2VnbWVudERpc3QgPSBhLmRpc3QoYiksXG4gICAgICAgICAgICBhbmdsZSA9IGIuYW5nbGVUbyhhKTtcblxuICAgICAgICB3aGlsZSAobWFya2VkRGlzdGFuY2UgKyBzcGFjaW5nIDwgZGlzdGFuY2UgKyBzZWdtZW50RGlzdCkge1xuICAgICAgICAgICAgbWFya2VkRGlzdGFuY2UgKz0gc3BhY2luZztcblxuICAgICAgICAgICAgY29uc3QgdCA9IChtYXJrZWREaXN0YW5jZSAtIGRpc3RhbmNlKSAvIHNlZ21lbnREaXN0LFxuICAgICAgICAgICAgICAgIHggPSBpbnRlcnBvbGF0ZShhLngsIGIueCwgdCksXG4gICAgICAgICAgICAgICAgeSA9IGludGVycG9sYXRlKGEueSwgYi55LCB0KTtcblxuICAgICAgICAgICAgLy8gQ2hlY2sgdGhhdCB0aGUgcG9pbnQgaXMgd2l0aGluIHRoZSB0aWxlIGJvdW5kYXJpZXMgYW5kIHRoYXRcbiAgICAgICAgICAgIC8vIHRoZSBsYWJlbCB3b3VsZCBmaXQgYmVmb3JlIHRoZSBiZWdpbm5pbmcgYW5kIGVuZCBvZiB0aGUgbGluZVxuICAgICAgICAgICAgLy8gaWYgcGxhY2VkIGF0IHRoaXMgcG9pbnQuXG4gICAgICAgICAgICBpZiAoeCA+PSAwICYmIHggPCB0aWxlRXh0ZW50ICYmIHkgPj0gMCAmJiB5IDwgdGlsZUV4dGVudCAmJlxuICAgICAgICAgICAgICAgICAgICBtYXJrZWREaXN0YW5jZSAtIGhhbGZMYWJlbExlbmd0aCA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgIG1hcmtlZERpc3RhbmNlICsgaGFsZkxhYmVsTGVuZ3RoIDw9IGxpbmVMZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBhbmNob3IgPSBuZXcgQW5jaG9yKHgsIHksIDAsIGFuZ2xlLCBpKTtcbiAgICAgICAgICAgICAgICBhbmNob3IuX3JvdW5kKCk7XG5cbiAgICAgICAgICAgICAgICBpZiAoIWFuZ2xlV2luZG93U2l6ZSB8fCBjaGVja01heEFuZ2xlKGxpbmUsIGFuY2hvciwgbGFiZWxMZW5ndGgsIGFuZ2xlV2luZG93U2l6ZSwgbWF4QW5nbGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGFuY2hvcnMucHVzaChhbmNob3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGRpc3RhbmNlICs9IHNlZ21lbnREaXN0O1xuICAgIH1cblxuICAgIGlmICghcGxhY2VBdE1pZGRsZSAmJiAhYW5jaG9ycy5sZW5ndGggJiYgIWlzTGluZUNvbnRpbnVlZCkge1xuICAgICAgICAvLyBUaGUgZmlyc3QgYXR0ZW1wdCBhdCBmaW5kaW5nIGFuY2hvcnMgYXQgd2hpY2ggbGFiZWxzIGNhbiBiZSBwbGFjZWQgZmFpbGVkLlxuICAgICAgICAvLyBUcnkgYWdhaW4sIGJ1dCB0aGlzIHRpbWUganVzdCB0cnkgcGxhY2luZyBvbmUgYW5jaG9yIGF0IHRoZSBtaWRkbGUgb2YgdGhlIGxpbmUuXG4gICAgICAgIC8vIFRoaXMgaGFzIHRoZSBtb3N0IGVmZmVjdCBmb3Igc2hvcnQgbGluZXMgaW4gb3ZlcnNjYWxlZCB0aWxlcywgc2luY2UgdGhlXG4gICAgICAgIC8vIGluaXRpYWwgb2Zmc2V0IHVzZWQgaW4gb3ZlcnNjYWxlZCB0aWxlcyBpcyBjYWxjdWxhdGVkIHRvIGFsaWduIGxhYmVscyB3aXRoIHBvc2l0aW9ucyBpblxuICAgICAgICAvLyBwYXJlbnQgdGlsZXMgaW5zdGVhZCBvZiBwbGFjaW5nIHRoZSBsYWJlbCBhcyBjbG9zZSB0byB0aGUgYmVnaW5uaW5nIGFzIHBvc3NpYmxlLlxuICAgICAgICBhbmNob3JzID0gcmVzYW1wbGUobGluZSwgZGlzdGFuY2UgLyAyLCBzcGFjaW5nLCBhbmdsZVdpbmRvd1NpemUsIG1heEFuZ2xlLCBsYWJlbExlbmd0aCwgaXNMaW5lQ29udGludWVkLCB0cnVlLCB0aWxlRXh0ZW50KTtcbiAgICB9XG5cbiAgICByZXR1cm4gYW5jaG9ycztcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcblxuZXhwb3J0IGRlZmF1bHQgY2xpcExpbmU7XG5cbi8qKlxuICogUmV0dXJucyB0aGUgcGFydCBvZiBhIG11bHRpbGluZSB0aGF0IGludGVyc2VjdHMgd2l0aCB0aGUgcHJvdmlkZWQgcmVjdGFuZ3VsYXIgYm94LlxuICpcbiAqIEBwYXJhbSBsaW5lc1xuICogQHBhcmFtIHgxIHRoZSBsZWZ0IGVkZ2Ugb2YgdGhlIGJveFxuICogQHBhcmFtIHkxIHRoZSB0b3AgZWRnZSBvZiB0aGUgYm94XG4gKiBAcGFyYW0geDIgdGhlIHJpZ2h0IGVkZ2Ugb2YgdGhlIGJveFxuICogQHBhcmFtIHkyIHRoZSBib3R0b20gZWRnZSBvZiB0aGUgYm94XG4gKiBAcmV0dXJucyBsaW5lc1xuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gY2xpcExpbmUobGluZXM6IEFycmF5PEFycmF5PFBvaW50Pj4sIHgxOiBudW1iZXIsIHkxOiBudW1iZXIsIHgyOiBudW1iZXIsIHkyOiBudW1iZXIpOiBBcnJheTxBcnJheTxQb2ludD4+IHtcbiAgICBjb25zdCBjbGlwcGVkTGluZXMgPSBbXTtcblxuICAgIGZvciAobGV0IGwgPSAwOyBsIDwgbGluZXMubGVuZ3RoOyBsKyspIHtcbiAgICAgICAgY29uc3QgbGluZSA9IGxpbmVzW2xdO1xuICAgICAgICBsZXQgY2xpcHBlZExpbmU7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW5lLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICAgICAgbGV0IHAwID0gbGluZVtpXTtcbiAgICAgICAgICAgIGxldCBwMSA9IGxpbmVbaSArIDFdO1xuXG4gICAgICAgICAgICBpZiAocDAueCA8IHgxICYmIHAxLnggPCB4MSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChwMC54IDwgeDEpIHtcbiAgICAgICAgICAgICAgICBwMCA9IG5ldyBQb2ludCh4MSwgcDAueSArIChwMS55IC0gcDAueSkgKiAoKHgxIC0gcDAueCkgLyAocDEueCAtIHAwLngpKSkuX3JvdW5kKCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHAxLnggPCB4MSkge1xuICAgICAgICAgICAgICAgIHAxID0gbmV3IFBvaW50KHgxLCBwMC55ICsgKHAxLnkgLSBwMC55KSAqICgoeDEgLSBwMC54KSAvIChwMS54IC0gcDAueCkpKS5fcm91bmQoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHAwLnkgPCB5MSAmJiBwMS55IDwgeTEpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocDAueSA8IHkxKSB7XG4gICAgICAgICAgICAgICAgcDAgPSBuZXcgUG9pbnQocDAueCArIChwMS54IC0gcDAueCkgKiAoKHkxIC0gcDAueSkgLyAocDEueSAtIHAwLnkpKSwgeTEpLl9yb3VuZCgpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChwMS55IDwgeTEpIHtcbiAgICAgICAgICAgICAgICBwMSA9IG5ldyBQb2ludChwMC54ICsgKHAxLnggLSBwMC54KSAqICgoeTEgLSBwMC55KSAvIChwMS55IC0gcDAueSkpLCB5MSkuX3JvdW5kKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChwMC54ID49IHgyICYmIHAxLnggPj0geDIpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocDAueCA+PSB4Mikge1xuICAgICAgICAgICAgICAgIHAwID0gbmV3IFBvaW50KHgyLCBwMC55ICsgKHAxLnkgLSBwMC55KSAqICgoeDIgLSBwMC54KSAvIChwMS54IC0gcDAueCkpKS5fcm91bmQoKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocDEueCA+PSB4Mikge1xuICAgICAgICAgICAgICAgIHAxID0gbmV3IFBvaW50KHgyLCBwMC55ICsgKHAxLnkgLSBwMC55KSAqICgoeDIgLSBwMC54KSAvIChwMS54IC0gcDAueCkpKS5fcm91bmQoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHAwLnkgPj0geTIgJiYgcDEueSA+PSB5Mikge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChwMC55ID49IHkyKSB7XG4gICAgICAgICAgICAgICAgcDAgPSBuZXcgUG9pbnQocDAueCArIChwMS54IC0gcDAueCkgKiAoKHkyIC0gcDAueSkgLyAocDEueSAtIHAwLnkpKSwgeTIpLl9yb3VuZCgpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChwMS55ID49IHkyKSB7XG4gICAgICAgICAgICAgICAgcDEgPSBuZXcgUG9pbnQocDAueCArIChwMS54IC0gcDAueCkgKiAoKHkyIC0gcDAueSkgLyAocDEueSAtIHAwLnkpKSwgeTIpLl9yb3VuZCgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIWNsaXBwZWRMaW5lIHx8ICFwMC5lcXVhbHMoY2xpcHBlZExpbmVbY2xpcHBlZExpbmUubGVuZ3RoIC0gMV0pKSB7XG4gICAgICAgICAgICAgICAgY2xpcHBlZExpbmUgPSBbcDBdO1xuICAgICAgICAgICAgICAgIGNsaXBwZWRMaW5lcy5wdXNoKGNsaXBwZWRMaW5lKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2xpcHBlZExpbmUucHVzaChwMSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY2xpcHBlZExpbmVzO1xufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtnZXRBcnJheUJ1ZmZlciwgUmVzb3VyY2VUeXBlfSBmcm9tICcuLi91dGlsL2FqYXguanMnO1xuXG5pbXBvcnQgcGFyc2VHbHlwaFBCRiBmcm9tICcuL3BhcnNlX2dseXBoX3BiZi5qcyc7XG5cbmltcG9ydCB0eXBlIHtTdHlsZUdseXBofSBmcm9tICcuL3N0eWxlX2dseXBoLmpzJztcbmltcG9ydCB0eXBlIHtSZXF1ZXN0TWFuYWdlcn0gZnJvbSAnLi4vdXRpbC9tYXBib3guanMnO1xuaW1wb3J0IHR5cGUge0NhbGxiYWNrfSBmcm9tICcuLi90eXBlcy9jYWxsYmFjay5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChmb250c3RhY2s6IHN0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlOiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICB1cmxUZW1wbGF0ZTogc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdE1hbmFnZXI6IFJlcXVlc3RNYW5hZ2VyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2s6IENhbGxiYWNrPHtnbHlwaHM6IHtbbnVtYmVyXTogU3R5bGVHbHlwaCB8IG51bGx9LCBhc2NlbmRlcj86IG51bWJlciwgZGVzY2VuZGVyPzogbnVtYmVyfT4pIHtcbiAgICBjb25zdCBiZWdpbiA9IHJhbmdlICogMjU2O1xuICAgIGNvbnN0IGVuZCA9IGJlZ2luICsgMjU1O1xuXG4gICAgY29uc3QgcmVxdWVzdCA9IHJlcXVlc3RNYW5hZ2VyLnRyYW5zZm9ybVJlcXVlc3QoXG4gICAgICAgIHJlcXVlc3RNYW5hZ2VyLm5vcm1hbGl6ZUdseXBoc1VSTCh1cmxUZW1wbGF0ZSlcbiAgICAgICAgICAgIC5yZXBsYWNlKCd7Zm9udHN0YWNrfScsIGZvbnRzdGFjaylcbiAgICAgICAgICAgIC5yZXBsYWNlKCd7cmFuZ2V9JywgYCR7YmVnaW59LSR7ZW5kfWApLFxuICAgICAgICBSZXNvdXJjZVR5cGUuR2x5cGhzKTtcblxuICAgIGdldEFycmF5QnVmZmVyKHJlcXVlc3QsIChlcnI6ID9FcnJvciwgZGF0YTogP0FycmF5QnVmZmVyKSA9PiB7XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGVycik7XG4gICAgICAgIH0gZWxzZSBpZiAoZGF0YSkge1xuICAgICAgICAgICAgY29uc3QgZ2x5cGhzID0ge307XG4gICAgICAgICAgICBjb25zdCBnbHlwaERhdGEgPSBwYXJzZUdseXBoUEJGKGRhdGEpO1xuICAgICAgICAgICAgZm9yIChjb25zdCBnbHlwaCBvZiBnbHlwaERhdGEuZ2x5cGhzKSB7XG4gICAgICAgICAgICAgICAgZ2x5cGhzW2dseXBoLmlkXSA9IGdseXBoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwge2dseXBocywgYXNjZW5kZXI6IGdseXBoRGF0YS5hc2NlbmRlciwgZGVzY2VuZGVyOiBnbHlwaERhdGEuZGVzY2VuZGVyfSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbiIsImNvbnN0IElORiA9IDFlMjA7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRpbnlTREYge1xuICAgIGNvbnN0cnVjdG9yKHtcbiAgICAgICAgZm9udFNpemUgPSAyNCxcbiAgICAgICAgYnVmZmVyID0gMyxcbiAgICAgICAgcmFkaXVzID0gOCxcbiAgICAgICAgY3V0b2ZmID0gMC4yNSxcbiAgICAgICAgZm9udEZhbWlseSA9ICdzYW5zLXNlcmlmJyxcbiAgICAgICAgZm9udFdlaWdodCA9ICdub3JtYWwnLFxuICAgICAgICBmb250U3R5bGUgPSAnbm9ybWFsJ1xuICAgIH0gPSB7fSkge1xuICAgICAgICB0aGlzLmJ1ZmZlciA9IGJ1ZmZlcjtcbiAgICAgICAgdGhpcy5jdXRvZmYgPSBjdXRvZmY7XG4gICAgICAgIHRoaXMucmFkaXVzID0gcmFkaXVzO1xuXG4gICAgICAgIC8vIG1ha2UgdGhlIGNhbnZhcyBzaXplIGJpZyBlbm91Z2ggdG8gYm90aCBoYXZlIHRoZSBzcGVjaWZpZWQgYnVmZmVyIGFyb3VuZCB0aGUgZ2x5cGhcbiAgICAgICAgLy8gZm9yIFwiaGFsb1wiLCBhbmQgYWNjb3VudCBmb3Igc29tZSBnbHlwaHMgcG9zc2libHkgYmVpbmcgbGFyZ2VyIHRoYW4gdGhlaXIgZm9udCBzaXplXG4gICAgICAgIGNvbnN0IHNpemUgPSB0aGlzLnNpemUgPSBmb250U2l6ZSArIGJ1ZmZlciAqIDQ7XG5cbiAgICAgICAgY29uc3QgY2FudmFzID0gdGhpcy5fY3JlYXRlQ2FudmFzKHNpemUpO1xuICAgICAgICBjb25zdCBjdHggPSB0aGlzLmN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcsIHt3aWxsUmVhZEZyZXF1ZW50bHk6IHRydWV9KTtcbiAgICAgICAgY3R4LmZvbnQgPSBgJHtmb250U3R5bGV9ICR7Zm9udFdlaWdodH0gJHtmb250U2l6ZX1weCAke2ZvbnRGYW1pbHl9YDtcblxuICAgICAgICBjdHgudGV4dEJhc2VsaW5lID0gJ2FscGhhYmV0aWMnO1xuICAgICAgICBjdHgudGV4dEFsaWduID0gJ2xlZnQnOyAvLyBOZWNlc3Nhcnkgc28gdGhhdCBSVEwgdGV4dCBkb2Vzbid0IGhhdmUgZGlmZmVyZW50IGFsaWdubWVudFxuICAgICAgICBjdHguZmlsbFN0eWxlID0gJ2JsYWNrJztcblxuICAgICAgICAvLyB0ZW1wb3JhcnkgYXJyYXlzIGZvciB0aGUgZGlzdGFuY2UgdHJhbnNmb3JtXG4gICAgICAgIHRoaXMuZ3JpZE91dGVyID0gbmV3IEZsb2F0NjRBcnJheShzaXplICogc2l6ZSk7XG4gICAgICAgIHRoaXMuZ3JpZElubmVyID0gbmV3IEZsb2F0NjRBcnJheShzaXplICogc2l6ZSk7XG4gICAgICAgIHRoaXMuZiA9IG5ldyBGbG9hdDY0QXJyYXkoc2l6ZSk7XG4gICAgICAgIHRoaXMueiA9IG5ldyBGbG9hdDY0QXJyYXkoc2l6ZSArIDEpO1xuICAgICAgICB0aGlzLnYgPSBuZXcgVWludDE2QXJyYXkoc2l6ZSk7XG4gICAgfVxuXG4gICAgX2NyZWF0ZUNhbnZhcyhzaXplKSB7XG4gICAgICAgIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgICAgICBjYW52YXMud2lkdGggPSBjYW52YXMuaGVpZ2h0ID0gc2l6ZTtcbiAgICAgICAgcmV0dXJuIGNhbnZhcztcbiAgICB9XG5cbiAgICBkcmF3KGNoYXIpIHtcbiAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgd2lkdGg6IGdseXBoQWR2YW5jZSxcbiAgICAgICAgICAgIGFjdHVhbEJvdW5kaW5nQm94QXNjZW50LFxuICAgICAgICAgICAgYWN0dWFsQm91bmRpbmdCb3hEZXNjZW50LFxuICAgICAgICAgICAgYWN0dWFsQm91bmRpbmdCb3hMZWZ0LFxuICAgICAgICAgICAgYWN0dWFsQm91bmRpbmdCb3hSaWdodFxuICAgICAgICB9ID0gdGhpcy5jdHgubWVhc3VyZVRleHQoY2hhcik7XG5cbiAgICAgICAgLy8gVGhlIGludGVnZXIvcGl4ZWwgcGFydCBvZiB0aGUgdG9wIGFsaWdubWVudCBpcyBlbmNvZGVkIGluIG1ldHJpY3MuZ2x5cGhUb3BcbiAgICAgICAgLy8gVGhlIHJlbWFpbmRlciBpcyBpbXBsaWNpdGx5IGVuY29kZWQgaW4gdGhlIHJhc3Rlcml6YXRpb25cbiAgICAgICAgY29uc3QgZ2x5cGhUb3AgPSBNYXRoLmNlaWwoYWN0dWFsQm91bmRpbmdCb3hBc2NlbnQpO1xuICAgICAgICBjb25zdCBnbHlwaExlZnQgPSAwO1xuXG4gICAgICAgIC8vIElmIHRoZSBnbHlwaCBvdmVyZmxvd3MgdGhlIGNhbnZhcyBzaXplLCBpdCB3aWxsIGJlIGNsaXBwZWQgYXQgdGhlIGJvdHRvbS9yaWdodFxuICAgICAgICBjb25zdCBnbHlwaFdpZHRoID0gTWF0aC5tYXgoMCwgTWF0aC5taW4odGhpcy5zaXplIC0gdGhpcy5idWZmZXIsIE1hdGguY2VpbChhY3R1YWxCb3VuZGluZ0JveFJpZ2h0IC0gYWN0dWFsQm91bmRpbmdCb3hMZWZ0KSkpO1xuICAgICAgICBjb25zdCBnbHlwaEhlaWdodCA9IE1hdGgubWluKHRoaXMuc2l6ZSAtIHRoaXMuYnVmZmVyLCBnbHlwaFRvcCArIE1hdGguY2VpbChhY3R1YWxCb3VuZGluZ0JveERlc2NlbnQpKTtcblxuICAgICAgICBjb25zdCB3aWR0aCA9IGdseXBoV2lkdGggKyAyICogdGhpcy5idWZmZXI7XG4gICAgICAgIGNvbnN0IGhlaWdodCA9IGdseXBoSGVpZ2h0ICsgMiAqIHRoaXMuYnVmZmVyO1xuXG4gICAgICAgIGNvbnN0IGxlbiA9IE1hdGgubWF4KHdpZHRoICogaGVpZ2h0LCAwKTtcbiAgICAgICAgY29uc3QgZGF0YSA9IG5ldyBVaW50OENsYW1wZWRBcnJheShsZW4pO1xuICAgICAgICBjb25zdCBnbHlwaCA9IHtkYXRhLCB3aWR0aCwgaGVpZ2h0LCBnbHlwaFdpZHRoLCBnbHlwaEhlaWdodCwgZ2x5cGhUb3AsIGdseXBoTGVmdCwgZ2x5cGhBZHZhbmNlfTtcbiAgICAgICAgaWYgKGdseXBoV2lkdGggPT09IDAgfHwgZ2x5cGhIZWlnaHQgPT09IDApIHJldHVybiBnbHlwaDtcblxuICAgICAgICBjb25zdCB7Y3R4LCBidWZmZXIsIGdyaWRJbm5lciwgZ3JpZE91dGVyfSA9IHRoaXM7XG4gICAgICAgIGN0eC5jbGVhclJlY3QoYnVmZmVyLCBidWZmZXIsIGdseXBoV2lkdGgsIGdseXBoSGVpZ2h0KTtcbiAgICAgICAgY3R4LmZpbGxUZXh0KGNoYXIsIGJ1ZmZlciwgYnVmZmVyICsgZ2x5cGhUb3ApO1xuICAgICAgICBjb25zdCBpbWdEYXRhID0gY3R4LmdldEltYWdlRGF0YShidWZmZXIsIGJ1ZmZlciwgZ2x5cGhXaWR0aCwgZ2x5cGhIZWlnaHQpO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgZ3JpZHMgb3V0c2lkZSB0aGUgZ2x5cGggcmFuZ2UgdG8gYWxwaGEgMFxuICAgICAgICBncmlkT3V0ZXIuZmlsbChJTkYsIDAsIGxlbik7XG4gICAgICAgIGdyaWRJbm5lci5maWxsKDAsIDAsIGxlbik7XG5cbiAgICAgICAgZm9yIChsZXQgeSA9IDA7IHkgPCBnbHlwaEhlaWdodDsgeSsrKSB7XG4gICAgICAgICAgICBmb3IgKGxldCB4ID0gMDsgeCA8IGdseXBoV2lkdGg7IHgrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGEgPSBpbWdEYXRhLmRhdGFbNCAqICh5ICogZ2x5cGhXaWR0aCArIHgpICsgM10gLyAyNTU7IC8vIGFscGhhIHZhbHVlXG4gICAgICAgICAgICAgICAgaWYgKGEgPT09IDApIGNvbnRpbnVlOyAvLyBlbXB0eSBwaXhlbHNcblxuICAgICAgICAgICAgICAgIGNvbnN0IGogPSAoeSArIGJ1ZmZlcikgKiB3aWR0aCArIHggKyBidWZmZXI7XG5cbiAgICAgICAgICAgICAgICBpZiAoYSA9PT0gMSkgeyAvLyBmdWxseSBkcmF3biBwaXhlbHNcbiAgICAgICAgICAgICAgICAgICAgZ3JpZE91dGVyW2pdID0gMDtcbiAgICAgICAgICAgICAgICAgICAgZ3JpZElubmVyW2pdID0gSU5GO1xuXG4gICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gYWxpYXNlZCBwaXhlbHNcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZCA9IDAuNSAtIGE7XG4gICAgICAgICAgICAgICAgICAgIGdyaWRPdXRlcltqXSA9IGQgPiAwID8gZCAqIGQgOiAwO1xuICAgICAgICAgICAgICAgICAgICBncmlkSW5uZXJbal0gPSBkIDwgMCA/IGQgKiBkIDogMDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBlZHQoZ3JpZE91dGVyLCAwLCAwLCB3aWR0aCwgaGVpZ2h0LCB3aWR0aCwgdGhpcy5mLCB0aGlzLnYsIHRoaXMueik7XG4gICAgICAgIGVkdChncmlkSW5uZXIsIGJ1ZmZlciwgYnVmZmVyLCBnbHlwaFdpZHRoLCBnbHlwaEhlaWdodCwgd2lkdGgsIHRoaXMuZiwgdGhpcy52LCB0aGlzLnopO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IGQgPSBNYXRoLnNxcnQoZ3JpZE91dGVyW2ldKSAtIE1hdGguc3FydChncmlkSW5uZXJbaV0pO1xuICAgICAgICAgICAgZGF0YVtpXSA9IE1hdGgucm91bmQoMjU1IC0gMjU1ICogKGQgLyB0aGlzLnJhZGl1cyArIHRoaXMuY3V0b2ZmKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZ2x5cGg7XG4gICAgfVxufVxuXG4vLyAyRCBFdWNsaWRlYW4gc3F1YXJlZCBkaXN0YW5jZSB0cmFuc2Zvcm0gYnkgRmVsemVuc3p3YWxiICYgSHV0dGVubG9jaGVyIGh0dHBzOi8vY3MuYnJvd24uZWR1L35wZmYvcGFwZXJzL2R0LWZpbmFsLnBkZlxuZnVuY3Rpb24gZWR0KGRhdGEsIHgwLCB5MCwgd2lkdGgsIGhlaWdodCwgZ3JpZFNpemUsIGYsIHYsIHopIHtcbiAgICBmb3IgKGxldCB4ID0geDA7IHggPCB4MCArIHdpZHRoOyB4KyspIGVkdDFkKGRhdGEsIHkwICogZ3JpZFNpemUgKyB4LCBncmlkU2l6ZSwgaGVpZ2h0LCBmLCB2LCB6KTtcbiAgICBmb3IgKGxldCB5ID0geTA7IHkgPCB5MCArIGhlaWdodDsgeSsrKSBlZHQxZChkYXRhLCB5ICogZ3JpZFNpemUgKyB4MCwgMSwgd2lkdGgsIGYsIHYsIHopO1xufVxuXG4vLyAxRCBzcXVhcmVkIGRpc3RhbmNlIHRyYW5zZm9ybVxuZnVuY3Rpb24gZWR0MWQoZ3JpZCwgb2Zmc2V0LCBzdHJpZGUsIGxlbmd0aCwgZiwgdiwgeikge1xuICAgIHZbMF0gPSAwO1xuICAgIHpbMF0gPSAtSU5GO1xuICAgIHpbMV0gPSBJTkY7XG4gICAgZlswXSA9IGdyaWRbb2Zmc2V0XTtcblxuICAgIGZvciAobGV0IHEgPSAxLCBrID0gMCwgcyA9IDA7IHEgPCBsZW5ndGg7IHErKykge1xuICAgICAgICBmW3FdID0gZ3JpZFtvZmZzZXQgKyBxICogc3RyaWRlXTtcbiAgICAgICAgY29uc3QgcTIgPSBxICogcTtcbiAgICAgICAgZG8ge1xuICAgICAgICAgICAgY29uc3QgciA9IHZba107XG4gICAgICAgICAgICBzID0gKGZbcV0gLSBmW3JdICsgcTIgLSByICogcikgLyAocSAtIHIpIC8gMjtcbiAgICAgICAgfSB3aGlsZSAocyA8PSB6W2tdICYmIC0tayA+IC0xKTtcblxuICAgICAgICBrKys7XG4gICAgICAgIHZba10gPSBxO1xuICAgICAgICB6W2tdID0gcztcbiAgICAgICAgeltrICsgMV0gPSBJTkY7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgcSA9IDAsIGsgPSAwOyBxIDwgbGVuZ3RoOyBxKyspIHtcbiAgICAgICAgd2hpbGUgKHpbayArIDFdIDwgcSkgaysrO1xuICAgICAgICBjb25zdCByID0gdltrXTtcbiAgICAgICAgY29uc3QgcXIgPSBxIC0gcjtcbiAgICAgICAgZ3JpZFtvZmZzZXQgKyBxICogc3RyaWRlXSA9IGZbcl0gKyBxciAqIHFyO1xuICAgIH1cbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBsb2FkR2x5cGhSYW5nZSBmcm9tICcuLi9zdHlsZS9sb2FkX2dseXBoX3JhbmdlLmpzJztcblxuaW1wb3J0IFRpbnlTREYgZnJvbSAnQG1hcGJveC90aW55LXNkZic7XG5pbXBvcnQgaXNDaGFyIGZyb20gJy4uL3V0aWwvaXNfY2hhcl9pbl91bmljb2RlX2Jsb2NrLmpzJztcbmltcG9ydCB7YXN5bmNBbGx9IGZyb20gJy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQge0FscGhhSW1hZ2V9IGZyb20gJy4uL3V0aWwvaW1hZ2UuanMnO1xuXG5pbXBvcnQgdHlwZSB7U3R5bGVHbHlwaH0gZnJvbSAnLi4vc3R5bGUvc3R5bGVfZ2x5cGguanMnO1xuaW1wb3J0IHR5cGUge1JlcXVlc3RNYW5hZ2VyfSBmcm9tICcuLi91dGlsL21hcGJveC5qcyc7XG5pbXBvcnQgdHlwZSB7Q2FsbGJhY2t9IGZyb20gJy4uL3R5cGVzL2NhbGxiYWNrLmpzJztcblxuLypcbiAgU0RGX1NDQUxFIGNvbnRyb2xzIHRoZSBwaXhlbCBkZW5zaXR5IG9mIGxvY2FsbHkgZ2VuZXJhdGVkIGdseXBocyByZWxhdGl2ZVxuICB0byBcIm5vcm1hbFwiIFNERnMgd2hpY2ggYXJlIGdlbmVyYXRlZCBhdCAyNHB0IGZvbnQgYW5kIGEgXCJwaXhlbCByYXRpb1wiIG9mIDEuXG4gIFRoZSBHbHlwaE1hbmFnZXIgd2lsbCBnZW5lcmF0ZSBnbHlwaHMgU0RGX1NDQUxFIHRpbWVzIGFzIGxhcmdlLFxuICBidXQgd2l0aCB0aGUgc2FtZSBnbHlwaCBtZXRyaWNzLCBhbmQgdGhlIHF1YWQgZ2VuZXJhdGlvbiBjb2RlIHdpbGwgc2NhbGUgdGhlbVxuICBiYWNrIGRvd24gc28gdGhleSBkaXNwbGF5IGF0IHRoZSBzYW1lIHNpemUuXG5cbiAgVGhlIGNob2ljZSBvZiBTREZfU0NBTEUgaXMgYSB0cmFkZS1vZmYgYmV0d2VlbiBwZXJmb3JtYW5jZSBhbmQgcXVhbGl0eS5cbiAgR2x5cGggZ2VuZXJhdGlvbiB0aW1lIGdyb3dzIHF1YWRyYXRpY2FsbHkgd2l0aCB0aGUgdGhlIHNjYWxlLCB3aGlsZSBxdWFsaXR5XG4gIGltcHJvdmVtZW50cyBkcm9wIG9mZiByYXBpZGx5IHdoZW4gdGhlIHNjYWxlIGlzIGhpZ2hlciB0aGFuIHRoZSBwaXhlbCByYXRpb1xuICBvZiB0aGUgZGV2aWNlLiBUaGUgc2NhbGUgb2YgMiBidXlzIG5vdGljZWFibGUgaW1wcm92ZW1lbnRzIG9uIEhEUEkgc2NyZWVuc1xuICBhdCBhY2NlcHRhYmxlIGNvc3QuXG5cbiAgVGhlIHNjYWxlIGNhbiBiZSBhbnkgdmFsdWUsIGJ1dCBpbiBvcmRlciB0byBhdm9pZCBzbWFsbCBkaXN0b3J0aW9ucywgdGhlc2VcbiAgcGl4ZWwtYmFzZWQgdmFsdWVzIG11c3QgY29tZSBvdXQgdG8gaW50ZWdlcnM6XG4gICAtIFwibG9jYWxHbHlwaFBhZGRpbmdcIiBpbiBHbHlwaEF0bGFzXG4gICAtIEZvbnQvQ2FudmFzL0J1ZmZlciBzaXplIGZvciBUaW55U0RGXG4gIGxvY2FsR2x5cGhQYWRkaW5nICsgYnVmZmVyIHNob3VsZCBlcXVhbCA0ICogU0RGX1NDQUxFLiBTbyBpZiB5b3Ugd2FudGVkIHRvXG4gIHVzZSBhbiBTREZfU0NBTEUgb2YgMS43NSwgeW91IGNvdWxkIG1hbnVhbGx5IHNldCBsb2NhbEdseXBoQWRkaW5nIHRvIDIgYW5kXG4gIGJ1ZmZlciB0byA1LlxuKi9cbmV4cG9ydCBjb25zdCBTREZfU0NBTEUgPSAyO1xuXG50eXBlIEVudHJ5ID0ge1xuICAgIC8vIG51bGwgbWVhbnMgd2UndmUgcmVxdWVzdGVkIHRoZSByYW5nZSwgYnV0IHRoZSBnbHlwaCB3YXNuJ3QgaW5jbHVkZWQgaW4gdGhlIHJlc3VsdC5cbiAgICBnbHlwaHM6IHtbaWQ6IG51bWJlcl06IFN0eWxlR2x5cGggfCBudWxsfSxcbiAgICByZXF1ZXN0czoge1tyYW5nZTogbnVtYmVyXTogQXJyYXk8Q2FsbGJhY2s8e2dseXBoczoge1tudW1iZXJdOiBTdHlsZUdseXBoIHwgbnVsbH0sIGFzY2VuZGVyPzogbnVtYmVyLCBkZXNjZW5kZXI/OiBudW1iZXJ9Pj59LFxuICAgIHJhbmdlczoge1tyYW5nZTogbnVtYmVyXTogYm9vbGVhbiB8IG51bGx9LFxuICAgIHRpbnlTREY/OiBUaW55U0RGLFxuICAgIGFzY2VuZGVyPzogbnVtYmVyLFxuICAgIGRlc2NlbmRlcj86IG51bWJlclxufTtcblxuZXhwb3J0IGNvbnN0IExvY2FsR2x5cGhNb2RlID0ge1xuICAgIG5vbmU6IDAsXG4gICAgaWRlb2dyYXBoczogMSxcbiAgICBhbGw6IDJcbn07XG5cbmNsYXNzIEdseXBoTWFuYWdlciB7XG4gICAgcmVxdWVzdE1hbmFnZXI6IFJlcXVlc3RNYW5hZ2VyO1xuICAgIGxvY2FsRm9udEZhbWlseTogP3N0cmluZztcbiAgICBsb2NhbEdseXBoTW9kZTogbnVtYmVyO1xuICAgIGVudHJpZXM6IHtbXzogc3RyaW5nXTogRW50cnl9O1xuICAgIC8vIE11bHRpcGxlIGZvbnRzdGFja3MgbWF5IHNoYXJlIHRoZSBzYW1lIGxvY2FsIGdseXBocywgc28ga2VlcCBhbiBpbmRleFxuICAgIC8vIGludG8gdGhlIGdseXBocyBiYXNlZCBzb2xleSBvbiBmb250IHdlaWdodFxuICAgIGxvY2FsR2x5cGhzOiB7W186IHN0cmluZ106IHtnbHlwaHM6IHtbaWQ6IG51bWJlcl06IFN0eWxlR2x5cGggfCBudWxsfSwgYXNjZW5kZXI6ID9udW1iZXIsIGRlc2NlbmRlcjogP251bWJlcn19O1xuICAgIHVybDogP3N0cmluZztcblxuICAgIC8vIGV4cG9zZWQgYXMgc3RhdGljcyB0byBlbmFibGUgc3R1YmJpbmcgaW4gdW5pdCB0ZXN0c1xuICAgIHN0YXRpYyBsb2FkR2x5cGhSYW5nZTogdHlwZW9mIGxvYWRHbHlwaFJhbmdlO1xuICAgIHN0YXRpYyBUaW55U0RGOiBDbGFzczxUaW55U0RGPjtcblxuICAgIGNvbnN0cnVjdG9yKHJlcXVlc3RNYW5hZ2VyOiBSZXF1ZXN0TWFuYWdlciwgbG9jYWxHbHlwaE1vZGU6IG51bWJlciwgbG9jYWxGb250RmFtaWx5OiA/c3RyaW5nKSB7XG4gICAgICAgIHRoaXMucmVxdWVzdE1hbmFnZXIgPSByZXF1ZXN0TWFuYWdlcjtcbiAgICAgICAgdGhpcy5sb2NhbEdseXBoTW9kZSA9IGxvY2FsR2x5cGhNb2RlO1xuICAgICAgICB0aGlzLmxvY2FsRm9udEZhbWlseSA9IGxvY2FsRm9udEZhbWlseTtcbiAgICAgICAgdGhpcy5lbnRyaWVzID0ge307XG4gICAgICAgIHRoaXMubG9jYWxHbHlwaHMgPSB7XG4gICAgICAgICAgICAvLyBPbmx5IHRoZXNlIGZvdXIgZm9udCB3ZWlnaHRzIGFyZSBzdXBwb3J0ZWRcbiAgICAgICAgICAgICcyMDAnOiB7fSxcbiAgICAgICAgICAgICc0MDAnOiB7fSxcbiAgICAgICAgICAgICc1MDAnOiB7fSxcbiAgICAgICAgICAgICc5MDAnOiB7fVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHNldFVSTCh1cmw6ID9zdHJpbmcpIHtcbiAgICAgICAgdGhpcy51cmwgPSB1cmw7XG4gICAgfVxuXG4gICAgZ2V0R2x5cGhzKGdseXBoczoge1tzdGFjazogc3RyaW5nXTogQXJyYXk8bnVtYmVyPn0sIGNhbGxiYWNrOiBDYWxsYmFjazx7W3N0YWNrOiBzdHJpbmddOiB7Z2x5cGhzOiB7W186IG51bWJlcl06ID9TdHlsZUdseXBofSwgYXNjZW5kZXI/OiBudW1iZXIsIGRlc2NlbmRlcj86IG51bWJlcn19Pikge1xuICAgICAgICBjb25zdCBhbGwgPSBbXTtcblxuICAgICAgICBmb3IgKGNvbnN0IHN0YWNrIGluIGdseXBocykge1xuICAgICAgICAgICAgZm9yIChjb25zdCBpZCBvZiBnbHlwaHNbc3RhY2tdKSB7XG4gICAgICAgICAgICAgICAgYWxsLnB1c2goe3N0YWNrLCBpZH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgYXN5bmNBbGwoYWxsLCAoe3N0YWNrLCBpZH0sIGZuQ2FsbGJhY2s6IENhbGxiYWNrPHtzdGFjazogc3RyaW5nLCBpZDogbnVtYmVyLCBnbHlwaDogP1N0eWxlR2x5cGh9PikgPT4ge1xuICAgICAgICAgICAgbGV0IGVudHJ5ID0gdGhpcy5lbnRyaWVzW3N0YWNrXTtcbiAgICAgICAgICAgIGlmICghZW50cnkpIHtcbiAgICAgICAgICAgICAgICBlbnRyeSA9IHRoaXMuZW50cmllc1tzdGFja10gPSB7XG4gICAgICAgICAgICAgICAgICAgIGdseXBoczoge30sXG4gICAgICAgICAgICAgICAgICAgIHJlcXVlc3RzOiB7fSxcbiAgICAgICAgICAgICAgICAgICAgcmFuZ2VzOiB7fSxcbiAgICAgICAgICAgICAgICAgICAgYXNjZW5kZXI6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgZGVzY2VuZGVyOiB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgZ2x5cGggPSBlbnRyeS5nbHlwaHNbaWRdO1xuICAgICAgICAgICAgaWYgKGdseXBoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBmbkNhbGxiYWNrKG51bGwsIHtzdGFjaywgaWQsIGdseXBofSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBnbHlwaCA9IHRoaXMuX3RpbnlTREYoZW50cnksIHN0YWNrLCBpZCk7XG4gICAgICAgICAgICBpZiAoZ2x5cGgpIHtcbiAgICAgICAgICAgICAgICBlbnRyeS5nbHlwaHNbaWRdID0gZ2x5cGg7XG4gICAgICAgICAgICAgICAgZm5DYWxsYmFjayhudWxsLCB7c3RhY2ssIGlkLCBnbHlwaH0pO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgcmFuZ2UgPSBNYXRoLmZsb29yKGlkIC8gMjU2KTtcbiAgICAgICAgICAgIGlmIChyYW5nZSAqIDI1NiA+IDY1NTM1KSB7XG4gICAgICAgICAgICAgICAgZm5DYWxsYmFjayhuZXcgRXJyb3IoJ2dseXBocyA+IDY1NTM1IG5vdCBzdXBwb3J0ZWQnKSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZW50cnkucmFuZ2VzW3JhbmdlXSkge1xuICAgICAgICAgICAgICAgIGZuQ2FsbGJhY2sobnVsbCwge3N0YWNrLCBpZCwgZ2x5cGh9KTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCByZXF1ZXN0cyA9IGVudHJ5LnJlcXVlc3RzW3JhbmdlXTtcbiAgICAgICAgICAgIGlmICghcmVxdWVzdHMpIHtcbiAgICAgICAgICAgICAgICByZXF1ZXN0cyA9IGVudHJ5LnJlcXVlc3RzW3JhbmdlXSA9IFtdO1xuICAgICAgICAgICAgICAgIEdseXBoTWFuYWdlci5sb2FkR2x5cGhSYW5nZShzdGFjaywgcmFuZ2UsICh0aGlzLnVybDogYW55KSwgdGhpcy5yZXF1ZXN0TWFuYWdlcixcbiAgICAgICAgICAgICAgICAgICAgKGVyciwgcmVzcG9uc2U6ID97Z2x5cGhzOiB7W186IG51bWJlcl06IFN0eWxlR2x5cGggfCBudWxsfSwgYXNjZW5kZXI/OiBudW1iZXIsIGRlc2NlbmRlcj86IG51bWJlcn0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudHJ5LmFzY2VuZGVyID0gcmVzcG9uc2UuYXNjZW5kZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW50cnkuZGVzY2VuZGVyID0gcmVzcG9uc2UuZGVzY2VuZGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgaWQgaW4gcmVzcG9uc2UuZ2x5cGhzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5fZG9lc0NoYXJTdXBwb3J0TG9jYWxHbHlwaCgraWQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnRyeS5nbHlwaHNbK2lkXSA9IHJlc3BvbnNlLmdseXBoc1sraWRdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudHJ5LnJhbmdlc1tyYW5nZV0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBjYiBvZiByZXF1ZXN0cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNiKGVyciwgcmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGVudHJ5LnJlcXVlc3RzW3JhbmdlXTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJlcXVlc3RzLnB1c2goKGVyciwgcmVzdWx0OiA/e2dseXBoczoge1tfOiBudW1iZXJdOiBTdHlsZUdseXBoIHwgbnVsbH0sIGFzY2VuZGVyPzogbnVtYmVyLCBkZXNjZW5kZXI/OiBudW1iZXJ9KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgICAgICBmbkNhbGxiYWNrKGVycik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgICAgICAgICAgZm5DYWxsYmFjayhudWxsLCB7c3RhY2ssIGlkLCBnbHlwaDogcmVzdWx0LmdseXBoc1tpZF0gfHwgbnVsbH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCAoZXJyLCBnbHlwaHM6ID9BcnJheTx7c3RhY2s6IHN0cmluZywgaWQ6IG51bWJlciwgZ2x5cGg6ID9TdHlsZUdseXBofT4pID0+IHtcbiAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnIpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChnbHlwaHMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSB7fTtcblxuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qge3N0YWNrLCBpZCwgZ2x5cGh9IG9mIGdseXBocykge1xuICAgICAgICAgICAgICAgICAgICAvLyBDbG9uZSB0aGUgZ2x5cGggc28gdGhhdCBvdXIgb3duIGNvcHkgb2YgaXRzIEFycmF5QnVmZmVyIGRvZXNuJ3QgZ2V0IHRyYW5zZmVycmVkLlxuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0W3N0YWNrXSA9PT0gdW5kZWZpbmVkKSByZXN1bHRbc3RhY2tdID0ge307XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHRbc3RhY2tdLmdseXBocyA9PT0gdW5kZWZpbmVkKSByZXN1bHRbc3RhY2tdLmdseXBocyA9IHt9O1xuICAgICAgICAgICAgICAgICAgICByZXN1bHRbc3RhY2tdLmdseXBoc1tpZF0gPSBnbHlwaCAmJiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZDogZ2x5cGguaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBiaXRtYXA6IGdseXBoLmJpdG1hcC5jbG9uZSgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljczogZ2x5cGgubWV0cmljc1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICByZXN1bHRbc3RhY2tdLmFzY2VuZGVyID0gdGhpcy5lbnRyaWVzW3N0YWNrXS5hc2NlbmRlcjtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0W3N0YWNrXS5kZXNjZW5kZXIgPSB0aGlzLmVudHJpZXNbc3RhY2tdLmRlc2NlbmRlcjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjYWxsYmFjayhudWxsLCByZXN1bHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBfZG9lc0NoYXJTdXBwb3J0TG9jYWxHbHlwaChpZDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICh0aGlzLmxvY2FsR2x5cGhNb2RlID09PSBMb2NhbEdseXBoTW9kZS5ub25lKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5sb2NhbEdseXBoTW9kZSA9PT0gTG9jYWxHbHlwaE1vZGUuYWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gISF0aGlzLmxvY2FsRm9udEZhbWlseTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5ldy1jYXAgKi9cbiAgICAgICAgICAgIHJldHVybiAhIXRoaXMubG9jYWxGb250RmFtaWx5ICYmXG4gICAgICAgICAgICAoKGlzQ2hhclsnQ0pLIFVuaWZpZWQgSWRlb2dyYXBocyddKGlkKSB8fFxuICAgICAgICAgICAgICAgIGlzQ2hhclsnSGFuZ3VsIFN5bGxhYmxlcyddKGlkKSB8fFxuICAgICAgICAgICAgICAgIGlzQ2hhclsnSGlyYWdhbmEnXShpZCkgfHxcbiAgICAgICAgICAgICAgICBpc0NoYXJbJ0thdGFrYW5hJ10oaWQpKSB8fFxuICAgICAgICAgICAgICAgIC8vIGdsLW5hdGl2ZSBwYXJpdHk6IEV4dGVuZCBJZGVvZ3JhcGhzIHJhc3Rlcml6YXRpb24gcmFuZ2UgdG8gaW5jbHVkZSBDSksgc3ltYm9scyBhbmQgcHVuY3R1YXRpb25zXG4gICAgICAgICAgICAgICAgaXNDaGFyWydDSksgU3ltYm9scyBhbmQgUHVuY3R1YXRpb24nXShpZCkpO1xuICAgICAgICAgICAgLyogZXNsaW50LWVuYWJsZSBuZXctY2FwICovXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfdGlueVNERihlbnRyeTogRW50cnksIHN0YWNrOiBzdHJpbmcsIGlkOiBudW1iZXIpOiA/U3R5bGVHbHlwaCB7XG4gICAgICAgIGNvbnN0IGZvbnRGYW1pbHkgPSB0aGlzLmxvY2FsRm9udEZhbWlseTtcbiAgICAgICAgaWYgKCFmb250RmFtaWx5IHx8ICF0aGlzLl9kb2VzQ2hhclN1cHBvcnRMb2NhbEdseXBoKGlkKSkgcmV0dXJuO1xuXG4gICAgICAgIGxldCB0aW55U0RGID0gZW50cnkudGlueVNERjtcbiAgICAgICAgaWYgKCF0aW55U0RGKSB7XG4gICAgICAgICAgICBsZXQgZm9udFdlaWdodCA9ICc0MDAnO1xuICAgICAgICAgICAgaWYgKC9ib2xkL2kudGVzdChzdGFjaykpIHtcbiAgICAgICAgICAgICAgICBmb250V2VpZ2h0ID0gJzkwMCc7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKC9tZWRpdW0vaS50ZXN0KHN0YWNrKSkge1xuICAgICAgICAgICAgICAgIGZvbnRXZWlnaHQgPSAnNTAwJztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoL2xpZ2h0L2kudGVzdChzdGFjaykpIHtcbiAgICAgICAgICAgICAgICBmb250V2VpZ2h0ID0gJzIwMCc7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGZvbnRTaXplID0gMjQgKiBTREZfU0NBTEU7XG4gICAgICAgICAgICBjb25zdCBidWZmZXIgPSAzICogU0RGX1NDQUxFO1xuICAgICAgICAgICAgY29uc3QgcmFkaXVzID0gOCAqIFNERl9TQ0FMRTtcbiAgICAgICAgICAgIHRpbnlTREYgPSBlbnRyeS50aW55U0RGID0gbmV3IEdseXBoTWFuYWdlci5UaW55U0RGKHtmb250RmFtaWx5LCBmb250V2VpZ2h0LCBmb250U2l6ZSwgYnVmZmVyLCByYWRpdXN9KTtcbiAgICAgICAgICAgIHRpbnlTREYuZm9udFdlaWdodCA9IGZvbnRXZWlnaHQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5sb2NhbEdseXBoc1t0aW55U0RGLmZvbnRXZWlnaHRdW2lkXSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxHbHlwaHNbdGlueVNERi5mb250V2VpZ2h0XVtpZF07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjaGFyID0gU3RyaW5nLmZyb21DaGFyQ29kZShpZCk7XG4gICAgICAgIGNvbnN0IHtkYXRhLCB3aWR0aCwgaGVpZ2h0LCBnbHlwaFdpZHRoLCBnbHlwaEhlaWdodCwgZ2x5cGhMZWZ0LCBnbHlwaFRvcCwgZ2x5cGhBZHZhbmNlfSA9IHRpbnlTREYuZHJhdyhjaGFyKTtcbiAgICAgICAgLypcbiAgICAgICAgVGlueVNERidzIFwidG9wXCIgaXMgdGhlIGRpc3RhbmNlIGZyb20gdGhlIGFscGhhYmV0aWMgYmFzZWxpbmUgdG8gdGhlXG4gICAgICAgICB0b3Agb2YgdGhlIGdseXBoLlxuXG4gICAgICAgIFNlcnZlci1nZW5lcmF0ZWQgZm9udHMgc3BlY2lmeSBcInRvcFwiIHJlbGF0aXZlIHRvIGFuIG9yaWdpbiBhYm92ZSB0aGVcbiAgICAgICAgIGVtIGJveCAodGhlIG9yaWdpbiBjb21lcyBmcm9tIEZyZWVUeXBlLCBidXQgSSdtIHVuY2xlYXIgb24gZXhhY3RseVxuICAgICAgICAgaG93IGl0J3MgZGVyaXZlZClcbiAgICAgICAgICByZWY6IGh0dHBzOi8vZ2l0aHViLmNvbS9tYXBib3gvc2RmLWdseXBoLWZvdW5kcnlcblxuICAgICAgICBTZXJ2ZXIgZm9udHMgZG9uJ3QgeWV0IGluY2x1ZGUgYmFzZWxpbmUgaW5mb3JtYXRpb24sIHNvIHdlIGNhbid0IGxpbmVcbiAgICAgICAgdXAgZXhhY3RseSB3aXRoIHRoZW0gKGFuZCB0aGV5IGRvbid0IGxpbmUgdXAgd2l0aCBlYWNoIG90aGVyKVxuICAgICAgICAgIHJlZjogaHR0cHM6Ly9naXRodWIuY29tL21hcGJveC9ub2RlLWZvbnRuaWsvcHVsbC8xNjBcblxuICAgICAgICBUbyBhcHByb3hpbWF0ZWx5IGFsaWduIFRpbnlTREYgZ2x5cGhzIHdpdGggc2VydmVyLXByb3ZpZGVkIGdseXBocywgd2VcbiAgICAgICAgdXNlIHRoaXMgYmFzZWxpbmUgYWRqdXN0bWVudCBmYWN0b3IgY2FsaWJyYXRlZCB0byBiZSBpbiBiZXR3ZWVuIERJTiBQcm9cbiAgICAgICAgYW5kIEFyaWFsIFVuaWNvZGUgKGJ1dCBjbG9zZXIgdG8gQXJpYWwgVW5pY29kZSlcbiAgICAgICAgKi9cbiAgICAgICAgY29uc3QgYmFzZWxpbmVBZGp1c3RtZW50ID0gMjc7XG5cbiAgICAgICAgY29uc3QgZ2x5cGggPSB0aGlzLmxvY2FsR2x5cGhzW3RpbnlTREYuZm9udFdlaWdodF1baWRdID0ge1xuICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICBiaXRtYXA6IG5ldyBBbHBoYUltYWdlKHt3aWR0aCwgaGVpZ2h0fSwgZGF0YSksXG4gICAgICAgICAgICBtZXRyaWNzOiB7XG4gICAgICAgICAgICAgICAgd2lkdGg6IGdseXBoV2lkdGggLyBTREZfU0NBTEUsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiBnbHlwaEhlaWdodCAvIFNERl9TQ0FMRSxcbiAgICAgICAgICAgICAgICBsZWZ0OiBnbHlwaExlZnQgLyBTREZfU0NBTEUsXG4gICAgICAgICAgICAgICAgdG9wOiBnbHlwaFRvcCAvIFNERl9TQ0FMRSAtIGJhc2VsaW5lQWRqdXN0bWVudCxcbiAgICAgICAgICAgICAgICBhZHZhbmNlOiBnbHlwaEFkdmFuY2UgLyBTREZfU0NBTEUsXG4gICAgICAgICAgICAgICAgbG9jYWxHbHlwaDogdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gZ2x5cGg7XG4gICAgfVxufVxuXG5HbHlwaE1hbmFnZXIubG9hZEdseXBoUmFuZ2UgPSBsb2FkR2x5cGhSYW5nZTtcbkdseXBoTWFuYWdlci5UaW55U0RGID0gVGlueVNERjtcblxuZXhwb3J0IGRlZmF1bHQgR2x5cGhNYW5hZ2VyO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IFBvaW50IGZyb20gJ0BtYXBib3gvcG9pbnQtZ2VvbWV0cnknO1xuXG5pbXBvcnQge0dMWVBIX1BCRl9CT1JERVJ9IGZyb20gJy4uL3N0eWxlL3BhcnNlX2dseXBoX3BiZi5qcyc7XG5cbmltcG9ydCB0eXBlIEFuY2hvciBmcm9tICcuL2FuY2hvci5qcyc7XG5pbXBvcnQgdHlwZSB7UG9zaXRpb25lZEljb24sIFNoYXBpbmd9IGZyb20gJy4vc2hhcGluZy5qcyc7XG5pbXBvcnQge0lNQUdFX1BBRERJTkd9IGZyb20gJy4uL3JlbmRlci9pbWFnZV9hdGxhcy5qcyc7XG5pbXBvcnQge1NERl9TQ0FMRX0gZnJvbSAnLi4vcmVuZGVyL2dseXBoX21hbmFnZXIuanMnO1xuaW1wb3J0IHR5cGUgU3ltYm9sU3R5bGVMYXllciBmcm9tICcuLi9zdHlsZS9zdHlsZV9sYXllci9zeW1ib2xfc3R5bGVfbGF5ZXIuanMnO1xuaW1wb3J0IHR5cGUge0ZlYXR1cmV9IGZyb20gJy4uL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi9pbmRleC5qcyc7XG5pbXBvcnQgdHlwZSB7U3R5bGVJbWFnZX0gZnJvbSAnLi4vc3R5bGUvc3R5bGVfaW1hZ2UuanMnO1xuaW1wb3J0IHtpc1ZlcnRpY2FsQ2xvc2VQdW5jdHVhdGlvbiwgaXNWZXJ0aWNhbE9wZW5QdW5jdHVhdGlvbn0gZnJvbSAnLi4vdXRpbC92ZXJ0aWNhbGl6ZV9wdW5jdHVhdGlvbi5qcyc7XG5pbXBvcnQgT05FX0VNIGZyb20gJy4vb25lX2VtLmpzJztcbmltcG9ydCB7d2Fybk9uY2V9IGZyb20gJy4uL3V0aWwvdXRpbC5qcyc7XG5cbnR5cGUgU2l6ZSA9IHt8IGZpeGVkOiBudW1iZXIsIHN0cmV0Y2g6IG51bWJlciB8fTtcblxuLyoqXG4gKiBBIHRleHR1cmVkIHF1YWQgZm9yIHJlbmRlcmluZyBhIHNpbmdsZSBpY29uIG9yIGdseXBoLlxuICpcbiAqIFRoZSB6b29tIHJhbmdlIHRoZSBnbHlwaCBjYW4gYmUgc2hvd24gaXMgZGVmaW5lZCBieSBtaW5TY2FsZSBhbmQgbWF4U2NhbGUuXG4gKlxuICogQHBhcmFtIHRsIFRoZSBvZmZzZXQgb2YgdGhlIHRvcCBsZWZ0IGNvcm5lciBmcm9tIHRoZSBhbmNob3IuXG4gKiBAcGFyYW0gdHIgVGhlIG9mZnNldCBvZiB0aGUgdG9wIHJpZ2h0IGNvcm5lciBmcm9tIHRoZSBhbmNob3IuXG4gKiBAcGFyYW0gYmwgVGhlIG9mZnNldCBvZiB0aGUgYm90dG9tIGxlZnQgY29ybmVyIGZyb20gdGhlIGFuY2hvci5cbiAqIEBwYXJhbSBiciBUaGUgb2Zmc2V0IG9mIHRoZSBib3R0b20gcmlnaHQgY29ybmVyIGZyb20gdGhlIGFuY2hvci5cbiAqIEBwYXJhbSB0ZXggVGhlIHRleHR1cmUgY29vcmRpbmF0ZXMuXG4gKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IHR5cGUgU3ltYm9sUXVhZCA9IHtcbiAgICB0bDogUG9pbnQsXG4gICAgdHI6IFBvaW50LFxuICAgIGJsOiBQb2ludCxcbiAgICBicjogUG9pbnQsXG4gICAgdGV4OiB7XG4gICAgICAgIHg6IG51bWJlcixcbiAgICAgICAgeTogbnVtYmVyLFxuICAgICAgICB3OiBudW1iZXIsXG4gICAgICAgIGg6IG51bWJlclxuICAgIH0sXG4gICAgcGl4ZWxPZmZzZXRUTDogUG9pbnQsXG4gICAgcGl4ZWxPZmZzZXRCUjogUG9pbnQsXG4gICAgd3JpdGluZ01vZGU6IGFueSB8IHZvaWQsXG4gICAgZ2x5cGhPZmZzZXQ6IFtudW1iZXIsIG51bWJlcl0sXG4gICAgc2VjdGlvbkluZGV4OiBudW1iZXIsXG4gICAgaXNTREY6IGJvb2xlYW4sXG4gICAgbWluRm9udFNjYWxlWDogbnVtYmVyLFxuICAgIG1pbkZvbnRTY2FsZVk6IG51bWJlclxufTtcblxuLy8gSWYgeW91IGhhdmUgYSAxMHB4IGljb24gdGhhdCBpc24ndCBwZXJmZWN0bHkgYWxpZ25lZCB0byB0aGUgcGl4ZWwgZ3JpZCBpdCB3aWxsIGNvdmVyIDExIGFjdHVhbFxuLy8gcGl4ZWxzLiBUaGUgcXVhZCBuZWVkcyB0byBiZSBwYWRkZWQgdG8gYWNjb3VudCBmb3IgdGhpcywgb3RoZXJ3aXNlIHRoZXknbGwgbG9vayBzbGlnaHRseSBjbGlwcGVkXG4vLyBvbiBvbmUgZWRnZSBpbiBzb21lIGNhc2VzLlxuY29uc3QgYm9yZGVyID0gSU1BR0VfUEFERElORztcblxuLyoqXG4gKiBDcmVhdGUgdGhlIHF1YWRzIHVzZWQgZm9yIHJlbmRlcmluZyBhbiBpY29uLlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEljb25RdWFkcyhcbiAgICAgICAgICAgICAgICAgICAgICBzaGFwZWRJY29uOiBQb3NpdGlvbmVkSWNvbixcbiAgICAgICAgICAgICAgICAgICAgICBpY29uUm90YXRlOiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgaXNTREZJY29uOiBib29sZWFuLFxuICAgICAgICAgICAgICAgICAgICAgIGhhc0ljb25UZXh0Rml0OiBib29sZWFuKTogQXJyYXk8U3ltYm9sUXVhZD4ge1xuICAgIGNvbnN0IHF1YWRzID0gW107XG5cbiAgICBjb25zdCBpbWFnZSA9IHNoYXBlZEljb24uaW1hZ2U7XG4gICAgY29uc3QgcGl4ZWxSYXRpbyA9IGltYWdlLnBpeGVsUmF0aW87XG4gICAgY29uc3QgaW1hZ2VXaWR0aCA9IGltYWdlLnBhZGRlZFJlY3QudyAtIDIgKiBib3JkZXI7XG4gICAgY29uc3QgaW1hZ2VIZWlnaHQgPSBpbWFnZS5wYWRkZWRSZWN0LmggLSAyICogYm9yZGVyO1xuXG4gICAgY29uc3QgaWNvbldpZHRoID0gc2hhcGVkSWNvbi5yaWdodCAtIHNoYXBlZEljb24ubGVmdDtcbiAgICBjb25zdCBpY29uSGVpZ2h0ID0gc2hhcGVkSWNvbi5ib3R0b20gLSBzaGFwZWRJY29uLnRvcDtcblxuICAgIGNvbnN0IHN0cmV0Y2hYID0gaW1hZ2Uuc3RyZXRjaFggfHwgW1swLCBpbWFnZVdpZHRoXV07XG4gICAgY29uc3Qgc3RyZXRjaFkgPSBpbWFnZS5zdHJldGNoWSB8fCBbWzAsIGltYWdlSGVpZ2h0XV07XG5cbiAgICBjb25zdCByZWR1Y2VSYW5nZXMgPSAoc3VtOiBudW1iZXIsIHJhbmdlOiBbbnVtYmVyLCBudW1iZXJdKSA9PiBzdW0gKyByYW5nZVsxXSAtIHJhbmdlWzBdO1xuICAgIGNvbnN0IHN0cmV0Y2hXaWR0aCA9IHN0cmV0Y2hYLnJlZHVjZShyZWR1Y2VSYW5nZXMsIDApO1xuICAgIGNvbnN0IHN0cmV0Y2hIZWlnaHQgPSBzdHJldGNoWS5yZWR1Y2UocmVkdWNlUmFuZ2VzLCAwKTtcbiAgICBjb25zdCBmaXhlZFdpZHRoID0gaW1hZ2VXaWR0aCAtIHN0cmV0Y2hXaWR0aDtcbiAgICBjb25zdCBmaXhlZEhlaWdodCA9IGltYWdlSGVpZ2h0IC0gc3RyZXRjaEhlaWdodDtcblxuICAgIGxldCBzdHJldGNoT2Zmc2V0WCA9IDA7XG4gICAgbGV0IHN0cmV0Y2hDb250ZW50V2lkdGggPSBzdHJldGNoV2lkdGg7XG4gICAgbGV0IHN0cmV0Y2hPZmZzZXRZID0gMDtcbiAgICBsZXQgc3RyZXRjaENvbnRlbnRIZWlnaHQgPSBzdHJldGNoSGVpZ2h0O1xuICAgIGxldCBmaXhlZE9mZnNldFggPSAwO1xuICAgIGxldCBmaXhlZENvbnRlbnRXaWR0aCA9IGZpeGVkV2lkdGg7XG4gICAgbGV0IGZpeGVkT2Zmc2V0WSA9IDA7XG4gICAgbGV0IGZpeGVkQ29udGVudEhlaWdodCA9IGZpeGVkSGVpZ2h0O1xuXG4gICAgaWYgKGltYWdlLmNvbnRlbnQgJiYgaGFzSWNvblRleHRGaXQpIHtcbiAgICAgICAgY29uc3QgY29udGVudCA9IGltYWdlLmNvbnRlbnQ7XG4gICAgICAgIHN0cmV0Y2hPZmZzZXRYID0gc3VtV2l0aGluUmFuZ2Uoc3RyZXRjaFgsIDAsIGNvbnRlbnRbMF0pO1xuICAgICAgICBzdHJldGNoT2Zmc2V0WSA9IHN1bVdpdGhpblJhbmdlKHN0cmV0Y2hZLCAwLCBjb250ZW50WzFdKTtcbiAgICAgICAgc3RyZXRjaENvbnRlbnRXaWR0aCA9IHN1bVdpdGhpblJhbmdlKHN0cmV0Y2hYLCBjb250ZW50WzBdLCBjb250ZW50WzJdKTtcbiAgICAgICAgc3RyZXRjaENvbnRlbnRIZWlnaHQgPSBzdW1XaXRoaW5SYW5nZShzdHJldGNoWSwgY29udGVudFsxXSwgY29udGVudFszXSk7XG4gICAgICAgIGZpeGVkT2Zmc2V0WCA9IGNvbnRlbnRbMF0gLSBzdHJldGNoT2Zmc2V0WDtcbiAgICAgICAgZml4ZWRPZmZzZXRZID0gY29udGVudFsxXSAtIHN0cmV0Y2hPZmZzZXRZO1xuICAgICAgICBmaXhlZENvbnRlbnRXaWR0aCA9IGNvbnRlbnRbMl0gLSBjb250ZW50WzBdIC0gc3RyZXRjaENvbnRlbnRXaWR0aDtcbiAgICAgICAgZml4ZWRDb250ZW50SGVpZ2h0ID0gY29udGVudFszXSAtIGNvbnRlbnRbMV0gLSBzdHJldGNoQ29udGVudEhlaWdodDtcbiAgICB9XG5cbiAgICBjb25zdCBtYWtlQm94ID0gKGxlZnQ6IFNpemUsIHRvcDogU2l6ZSwgcmlnaHQ6IFNpemUsIGJvdHRvbTogU2l6ZSkgPT4ge1xuXG4gICAgICAgIGNvbnN0IGxlZnRFbSA9IGdldEVtT2Zmc2V0KGxlZnQuc3RyZXRjaCAtIHN0cmV0Y2hPZmZzZXRYLCBzdHJldGNoQ29udGVudFdpZHRoLCBpY29uV2lkdGgsIHNoYXBlZEljb24ubGVmdCk7XG4gICAgICAgIGNvbnN0IGxlZnRQeCA9IGdldFB4T2Zmc2V0KGxlZnQuZml4ZWQgLSBmaXhlZE9mZnNldFgsIGZpeGVkQ29udGVudFdpZHRoLCBsZWZ0LnN0cmV0Y2gsIHN0cmV0Y2hXaWR0aCk7XG5cbiAgICAgICAgY29uc3QgdG9wRW0gPSBnZXRFbU9mZnNldCh0b3Auc3RyZXRjaCAtIHN0cmV0Y2hPZmZzZXRZLCBzdHJldGNoQ29udGVudEhlaWdodCwgaWNvbkhlaWdodCwgc2hhcGVkSWNvbi50b3ApO1xuICAgICAgICBjb25zdCB0b3BQeCA9IGdldFB4T2Zmc2V0KHRvcC5maXhlZCAtIGZpeGVkT2Zmc2V0WSwgZml4ZWRDb250ZW50SGVpZ2h0LCB0b3Auc3RyZXRjaCwgc3RyZXRjaEhlaWdodCk7XG5cbiAgICAgICAgY29uc3QgcmlnaHRFbSA9IGdldEVtT2Zmc2V0KHJpZ2h0LnN0cmV0Y2ggLSBzdHJldGNoT2Zmc2V0WCwgc3RyZXRjaENvbnRlbnRXaWR0aCwgaWNvbldpZHRoLCBzaGFwZWRJY29uLmxlZnQpO1xuICAgICAgICBjb25zdCByaWdodFB4ID0gZ2V0UHhPZmZzZXQocmlnaHQuZml4ZWQgLSBmaXhlZE9mZnNldFgsIGZpeGVkQ29udGVudFdpZHRoLCByaWdodC5zdHJldGNoLCBzdHJldGNoV2lkdGgpO1xuXG4gICAgICAgIGNvbnN0IGJvdHRvbUVtID0gZ2V0RW1PZmZzZXQoYm90dG9tLnN0cmV0Y2ggLSBzdHJldGNoT2Zmc2V0WSwgc3RyZXRjaENvbnRlbnRIZWlnaHQsIGljb25IZWlnaHQsIHNoYXBlZEljb24udG9wKTtcbiAgICAgICAgY29uc3QgYm90dG9tUHggPSBnZXRQeE9mZnNldChib3R0b20uZml4ZWQgLSBmaXhlZE9mZnNldFksIGZpeGVkQ29udGVudEhlaWdodCwgYm90dG9tLnN0cmV0Y2gsIHN0cmV0Y2hIZWlnaHQpO1xuXG4gICAgICAgIGNvbnN0IHRsID0gbmV3IFBvaW50KGxlZnRFbSwgdG9wRW0pO1xuICAgICAgICBjb25zdCB0ciA9IG5ldyBQb2ludChyaWdodEVtLCB0b3BFbSk7XG4gICAgICAgIGNvbnN0IGJyID0gbmV3IFBvaW50KHJpZ2h0RW0sIGJvdHRvbUVtKTtcbiAgICAgICAgY29uc3QgYmwgPSBuZXcgUG9pbnQobGVmdEVtLCBib3R0b21FbSk7XG4gICAgICAgIGNvbnN0IHBpeGVsT2Zmc2V0VEwgPSBuZXcgUG9pbnQobGVmdFB4IC8gcGl4ZWxSYXRpbywgdG9wUHggLyBwaXhlbFJhdGlvKTtcbiAgICAgICAgY29uc3QgcGl4ZWxPZmZzZXRCUiA9IG5ldyBQb2ludChyaWdodFB4IC8gcGl4ZWxSYXRpbywgYm90dG9tUHggLyBwaXhlbFJhdGlvKTtcblxuICAgICAgICBjb25zdCBhbmdsZSA9IGljb25Sb3RhdGUgKiBNYXRoLlBJIC8gMTgwO1xuXG4gICAgICAgIGlmIChhbmdsZSkge1xuICAgICAgICAgICAgY29uc3Qgc2luID0gTWF0aC5zaW4oYW5nbGUpLFxuICAgICAgICAgICAgICAgIGNvcyA9IE1hdGguY29zKGFuZ2xlKSxcbiAgICAgICAgICAgICAgICBtYXRyaXggPSBbY29zLCAtc2luLCBzaW4sIGNvc107XG5cbiAgICAgICAgICAgIHRsLl9tYXRNdWx0KG1hdHJpeCk7XG4gICAgICAgICAgICB0ci5fbWF0TXVsdChtYXRyaXgpO1xuICAgICAgICAgICAgYmwuX21hdE11bHQobWF0cml4KTtcbiAgICAgICAgICAgIGJyLl9tYXRNdWx0KG1hdHJpeCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB4MSA9IGxlZnQuc3RyZXRjaCArIGxlZnQuZml4ZWQ7XG4gICAgICAgIGNvbnN0IHgyID0gcmlnaHQuc3RyZXRjaCArIHJpZ2h0LmZpeGVkO1xuICAgICAgICBjb25zdCB5MSA9IHRvcC5zdHJldGNoICsgdG9wLmZpeGVkO1xuICAgICAgICBjb25zdCB5MiA9IGJvdHRvbS5zdHJldGNoICsgYm90dG9tLmZpeGVkO1xuXG4gICAgICAgIGNvbnN0IHN1YlJlY3QgPSB7XG4gICAgICAgICAgICB4OiBpbWFnZS5wYWRkZWRSZWN0LnggKyBib3JkZXIgKyB4MSxcbiAgICAgICAgICAgIHk6IGltYWdlLnBhZGRlZFJlY3QueSArIGJvcmRlciArIHkxLFxuICAgICAgICAgICAgdzogeDIgLSB4MSxcbiAgICAgICAgICAgIGg6IHkyIC0geTFcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBtaW5Gb250U2NhbGVYID0gZml4ZWRDb250ZW50V2lkdGggLyBwaXhlbFJhdGlvIC8gaWNvbldpZHRoO1xuICAgICAgICBjb25zdCBtaW5Gb250U2NhbGVZID0gZml4ZWRDb250ZW50SGVpZ2h0IC8gcGl4ZWxSYXRpbyAvIGljb25IZWlnaHQ7XG5cbiAgICAgICAgLy8gSWNvbiBxdWFkIGlzIHBhZGRlZCwgc28gdGV4dHVyZSBjb29yZGluYXRlcyBhbHNvIG5lZWQgdG8gYmUgcGFkZGVkLlxuICAgICAgICByZXR1cm4ge3RsLCB0ciwgYmwsIGJyLCB0ZXg6IHN1YlJlY3QsIHdyaXRpbmdNb2RlOiB1bmRlZmluZWQsIGdseXBoT2Zmc2V0OiBbMCwgMF0sIHNlY3Rpb25JbmRleDogMCwgcGl4ZWxPZmZzZXRUTCwgcGl4ZWxPZmZzZXRCUiwgbWluRm9udFNjYWxlWCwgbWluRm9udFNjYWxlWSwgaXNTREY6IGlzU0RGSWNvbn07XG4gICAgfTtcblxuICAgIGlmICghaGFzSWNvblRleHRGaXQgfHwgKCFpbWFnZS5zdHJldGNoWCAmJiAhaW1hZ2Uuc3RyZXRjaFkpKSB7XG4gICAgICAgIHF1YWRzLnB1c2gobWFrZUJveChcbiAgICAgICAgICAgIHtmaXhlZDogMCwgc3RyZXRjaDogLTF9LFxuICAgICAgICAgICAge2ZpeGVkOiAwLCBzdHJldGNoOiAtMX0sXG4gICAgICAgICAgICB7Zml4ZWQ6IDAsIHN0cmV0Y2g6IGltYWdlV2lkdGggKyAxfSxcbiAgICAgICAgICAgIHtmaXhlZDogMCwgc3RyZXRjaDogaW1hZ2VIZWlnaHQgKyAxfSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHhDdXRzID0gc3RyZXRjaFpvbmVzVG9DdXRzKHN0cmV0Y2hYLCBmaXhlZFdpZHRoLCBzdHJldGNoV2lkdGgpO1xuICAgICAgICBjb25zdCB5Q3V0cyA9IHN0cmV0Y2hab25lc1RvQ3V0cyhzdHJldGNoWSwgZml4ZWRIZWlnaHQsIHN0cmV0Y2hIZWlnaHQpO1xuXG4gICAgICAgIGZvciAobGV0IHhpID0gMDsgeGkgPCB4Q3V0cy5sZW5ndGggLSAxOyB4aSsrKSB7XG4gICAgICAgICAgICBjb25zdCB4MSA9IHhDdXRzW3hpXTtcbiAgICAgICAgICAgIGNvbnN0IHgyID0geEN1dHNbeGkgKyAxXTtcbiAgICAgICAgICAgIGZvciAobGV0IHlpID0gMDsgeWkgPCB5Q3V0cy5sZW5ndGggLSAxOyB5aSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeTEgPSB5Q3V0c1t5aV07XG4gICAgICAgICAgICAgICAgY29uc3QgeTIgPSB5Q3V0c1t5aSArIDFdO1xuICAgICAgICAgICAgICAgIHF1YWRzLnB1c2gobWFrZUJveCh4MSwgeTEsIHgyLCB5MikpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHF1YWRzO1xufVxuXG5mdW5jdGlvbiBzdW1XaXRoaW5SYW5nZShyYW5nZXM6IEFycmF5PFtudW1iZXIsIG51bWJlcl0+LCBtaW46IG51bWJlciwgbWF4OiBudW1iZXIpIHtcbiAgICBsZXQgc3VtID0gMDtcbiAgICBmb3IgKGNvbnN0IHJhbmdlIG9mIHJhbmdlcykge1xuICAgICAgICBzdW0gKz0gTWF0aC5tYXgobWluLCBNYXRoLm1pbihtYXgsIHJhbmdlWzFdKSkgLSBNYXRoLm1heChtaW4sIE1hdGgubWluKG1heCwgcmFuZ2VbMF0pKTtcbiAgICB9XG4gICAgcmV0dXJuIHN1bTtcbn1cblxuZnVuY3Rpb24gc3RyZXRjaFpvbmVzVG9DdXRzKHN0cmV0Y2hab25lczogQXJyYXk8W251bWJlciwgbnVtYmVyXT4sIGZpeGVkU2l6ZTogbnVtYmVyLCBzdHJldGNoU2l6ZTogbnVtYmVyKSB7XG4gICAgY29uc3QgY3V0cyA9IFt7Zml4ZWQ6IC1ib3JkZXIsIHN0cmV0Y2g6IDB9XTtcblxuICAgIGZvciAoY29uc3QgW2MxLCBjMl0gb2Ygc3RyZXRjaFpvbmVzKSB7XG4gICAgICAgIGNvbnN0IGxhc3QgPSBjdXRzW2N1dHMubGVuZ3RoIC0gMV07XG4gICAgICAgIGN1dHMucHVzaCh7XG4gICAgICAgICAgICBmaXhlZDogYzEgLSBsYXN0LnN0cmV0Y2gsXG4gICAgICAgICAgICBzdHJldGNoOiBsYXN0LnN0cmV0Y2hcbiAgICAgICAgfSk7XG4gICAgICAgIGN1dHMucHVzaCh7XG4gICAgICAgICAgICBmaXhlZDogYzEgLSBsYXN0LnN0cmV0Y2gsXG4gICAgICAgICAgICBzdHJldGNoOiBsYXN0LnN0cmV0Y2ggKyAoYzIgLSBjMSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGN1dHMucHVzaCh7XG4gICAgICAgIGZpeGVkOiBmaXhlZFNpemUgKyBib3JkZXIsXG4gICAgICAgIHN0cmV0Y2g6IHN0cmV0Y2hTaXplXG4gICAgfSk7XG4gICAgcmV0dXJuIGN1dHM7XG59XG5cbmZ1bmN0aW9uIGdldEVtT2Zmc2V0KHN0cmV0Y2hPZmZzZXQ6IG51bWJlciwgc3RyZXRjaFNpemU6IG51bWJlciwgaWNvblNpemU6IG51bWJlciwgaWNvbk9mZnNldDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIHN0cmV0Y2hPZmZzZXQgLyBzdHJldGNoU2l6ZSAqIGljb25TaXplICsgaWNvbk9mZnNldDtcbn1cblxuZnVuY3Rpb24gZ2V0UHhPZmZzZXQoZml4ZWRPZmZzZXQ6IG51bWJlciwgZml4ZWRTaXplOiBudW1iZXIsIHN0cmV0Y2hPZmZzZXQ6IG51bWJlciwgc3RyZXRjaFNpemU6IG51bWJlcikge1xuICAgIHJldHVybiBmaXhlZE9mZnNldCAtIGZpeGVkU2l6ZSAqIHN0cmV0Y2hPZmZzZXQgLyBzdHJldGNoU2l6ZTtcbn1cblxuZnVuY3Rpb24gZ2V0Um90YXRlT2Zmc2V0KHRleHRPZmZzZXQ6IFtudW1iZXIsIG51bWJlcl0pIHtcbiAgICBjb25zdCB4ID0gdGV4dE9mZnNldFswXSwgeSA9IHRleHRPZmZzZXRbMV07XG4gICAgY29uc3QgcHJvZHVjdCA9IHggKiB5O1xuICAgIGlmIChwcm9kdWN0ID4gMCkge1xuICAgICAgICByZXR1cm4gW3gsIC15XTtcbiAgICB9IGVsc2UgaWYgKHByb2R1Y3QgPCAwKSB7XG4gICAgICAgIHJldHVybiBbLXgsIHldO1xuICAgIH0gZWxzZSBpZiAoeCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gW3ksIHhdO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBbeSwgLXhdO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZ2V0TWlkbGluZU9mZnNldChzaGFwaW5nOiBTaGFwaW5nLCBsaW5lSGVpZ2h0OiBudW1iZXIsIHByZXZpb3VzT2Zmc2V0OiBudW1iZXIsIGxpbmVJbmRleDogbnVtYmVyKSB7XG4gICAgY29uc3QgY3VycmVudExpbmVIZWlnaHQgPSAobGluZUhlaWdodCArIHNoYXBpbmcucG9zaXRpb25lZExpbmVzW2xpbmVJbmRleF0ubGluZU9mZnNldCk7XG4gICAgaWYgKGxpbmVJbmRleCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gcHJldmlvdXNPZmZzZXQgKyBjdXJyZW50TGluZUhlaWdodCAvIDIuMDtcbiAgICB9XG4gICAgY29uc3QgYWJvdmVMaW5lSGVpZ2h0ID0gKGxpbmVIZWlnaHQgKyBzaGFwaW5nLnBvc2l0aW9uZWRMaW5lc1tsaW5lSW5kZXggLSAxXS5saW5lT2Zmc2V0KTtcbiAgICByZXR1cm4gcHJldmlvdXNPZmZzZXQgKyAoY3VycmVudExpbmVIZWlnaHQgKyBhYm92ZUxpbmVIZWlnaHQpIC8gMi4wO1xufVxuXG4vKipcbiAqIENyZWF0ZSB0aGUgcXVhZHMgdXNlZCBmb3IgcmVuZGVyaW5nIGEgdGV4dCBsYWJlbC5cbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRHbHlwaFF1YWRzKGFuY2hvcjogQW5jaG9yLFxuICAgICAgICAgICAgICAgICAgICAgICBzaGFwaW5nOiBTaGFwaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICB0ZXh0T2Zmc2V0OiBbbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICAgICAgICAgICAgICAgICBsYXllcjogU3ltYm9sU3R5bGVMYXllcixcbiAgICAgICAgICAgICAgICAgICAgICAgYWxvbmdMaW5lOiBib29sZWFuLFxuICAgICAgICAgICAgICAgICAgICAgICBmZWF0dXJlOiBGZWF0dXJlLFxuICAgICAgICAgICAgICAgICAgICAgICBpbWFnZU1hcDoge1tfOiBzdHJpbmddOiBTdHlsZUltYWdlfSxcbiAgICAgICAgICAgICAgICAgICAgICAgYWxsb3dWZXJ0aWNhbFBsYWNlbWVudDogYm9vbGVhbik6IEFycmF5PFN5bWJvbFF1YWQ+IHtcbiAgICBjb25zdCBxdWFkcyA9IFtdO1xuICAgIGlmIChzaGFwaW5nLnBvc2l0aW9uZWRMaW5lcy5sZW5ndGggPT09IDApIHJldHVybiBxdWFkcztcblxuICAgIGNvbnN0IHRleHRSb3RhdGUgPSBsYXllci5sYXlvdXQuZ2V0KCd0ZXh0LXJvdGF0ZScpLmV2YWx1YXRlKGZlYXR1cmUsIHt9KSAqIE1hdGguUEkgLyAxODA7XG4gICAgY29uc3Qgcm90YXRlT2Zmc2V0ID0gZ2V0Um90YXRlT2Zmc2V0KHRleHRPZmZzZXQpO1xuXG4gICAgbGV0IHNoYXBpbmdIZWlnaHQgPSBNYXRoLmFicyhzaGFwaW5nLnRvcCAtIHNoYXBpbmcuYm90dG9tKTtcbiAgICBmb3IgKGNvbnN0IGxpbmUgb2Ygc2hhcGluZy5wb3NpdGlvbmVkTGluZXMpIHtcbiAgICAgICAgc2hhcGluZ0hlaWdodCAtPSBsaW5lLmxpbmVPZmZzZXQ7XG4gICAgfVxuICAgIGNvbnN0IGxpbmVDb3VudHMgPSBzaGFwaW5nLnBvc2l0aW9uZWRMaW5lcy5sZW5ndGg7XG4gICAgY29uc3QgbGluZUhlaWdodCA9IHNoYXBpbmdIZWlnaHQgLyBsaW5lQ291bnRzO1xuICAgIGxldCBjdXJyZW50T2Zmc2V0ID0gc2hhcGluZy50b3AgLSB0ZXh0T2Zmc2V0WzFdO1xuICAgIGZvciAobGV0IGxpbmVJbmRleCA9IDA7IGxpbmVJbmRleCA8IGxpbmVDb3VudHM7ICsrbGluZUluZGV4KSB7XG4gICAgICAgIGNvbnN0IGxpbmUgPSBzaGFwaW5nLnBvc2l0aW9uZWRMaW5lc1tsaW5lSW5kZXhdO1xuICAgICAgICBjdXJyZW50T2Zmc2V0ID0gZ2V0TWlkbGluZU9mZnNldChzaGFwaW5nLCBsaW5lSGVpZ2h0LCBjdXJyZW50T2Zmc2V0LCBsaW5lSW5kZXgpO1xuICAgICAgICBmb3IgKGNvbnN0IHBvc2l0aW9uZWRHbHlwaCBvZiBsaW5lLnBvc2l0aW9uZWRHbHlwaHMpIHtcbiAgICAgICAgICAgIGlmICghcG9zaXRpb25lZEdseXBoLnJlY3QpIGNvbnRpbnVlO1xuICAgICAgICAgICAgY29uc3QgdGV4dHVyZVJlY3QgPSBwb3NpdGlvbmVkR2x5cGgucmVjdCB8fCB7fTtcblxuICAgICAgICAgICAgLy8gVGhlIHJlY3RzIGhhdmUgYW4gYWRkaXRpb25hbCBidWZmZXIgdGhhdCBpcyBub3QgaW5jbHVkZWQgaW4gdGhlaXIgc2l6ZS5cbiAgICAgICAgICAgIGNvbnN0IGdseXBoUGFkZGluZyA9IDEuMDtcbiAgICAgICAgICAgIGxldCByZWN0QnVmZmVyID0gR0xZUEhfUEJGX0JPUkRFUiArIGdseXBoUGFkZGluZztcbiAgICAgICAgICAgIGxldCBpc1NERiA9IHRydWU7XG4gICAgICAgICAgICBsZXQgcGl4ZWxSYXRpbyA9IDEuMDtcbiAgICAgICAgICAgIGxldCBsaW5lT2Zmc2V0ID0gMC4wO1xuICAgICAgICAgICAgaWYgKHBvc2l0aW9uZWRHbHlwaC5pbWFnZU5hbWUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBpbWFnZSA9IGltYWdlTWFwW3Bvc2l0aW9uZWRHbHlwaC5pbWFnZU5hbWVdO1xuICAgICAgICAgICAgICAgIGlmICghaW1hZ2UpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIGlmIChpbWFnZS5zZGYpIHtcbiAgICAgICAgICAgICAgICAgICAgd2Fybk9uY2UoXCJTREYgaW1hZ2VzIGFyZSBub3Qgc3VwcG9ydGVkIGluIGZvcm1hdHRlZCB0ZXh0IGFuZCB3aWxsIGJlIGlnbm9yZWQuXCIpO1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaXNTREYgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBwaXhlbFJhdGlvID0gaW1hZ2UucGl4ZWxSYXRpbztcbiAgICAgICAgICAgICAgICByZWN0QnVmZmVyID0gSU1BR0VfUEFERElORyAvIHBpeGVsUmF0aW87XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHJvdGF0ZVZlcnRpY2FsR2x5cGggPSAoYWxvbmdMaW5lIHx8IGFsbG93VmVydGljYWxQbGFjZW1lbnQpICYmIHBvc2l0aW9uZWRHbHlwaC52ZXJ0aWNhbDtcbiAgICAgICAgICAgIGNvbnN0IGhhbGZBZHZhbmNlID0gcG9zaXRpb25lZEdseXBoLm1ldHJpY3MuYWR2YW5jZSAqIHBvc2l0aW9uZWRHbHlwaC5zY2FsZSAvIDI7XG4gICAgICAgICAgICBjb25zdCBtZXRyaWNzID0gcG9zaXRpb25lZEdseXBoLm1ldHJpY3M7XG4gICAgICAgICAgICBjb25zdCByZWN0ID0gcG9zaXRpb25lZEdseXBoLnJlY3Q7XG4gICAgICAgICAgICBpZiAocmVjdCA9PT0gbnVsbCkgY29udGludWU7XG5cbiAgICAgICAgICAgIC8vIEFsaWduIGltYWdlcyBhbmQgc2NhbGVkIGdseXBocyBpbiB0aGUgbWlkZGxlIG9mIGEgdmVydGljYWwgbGluZS5cbiAgICAgICAgICAgIGlmIChhbGxvd1ZlcnRpY2FsUGxhY2VtZW50ICYmIHNoYXBpbmcudmVydGljYWxpemFibGUpIHtcbiAgICAgICAgICAgICAgICAvLyBpbWFnZSdzIGFkdmFuY2UgZm9yIHZlcnRpY2FsIHNoYXBpbmcgaXMgaXRzIGhlaWdodCwgc28gdGhhdCB3ZSBoYXZlIHRvIHRha2UgdGhlIGRpZmZlcmVuY2UgaW50b1xuICAgICAgICAgICAgICAgIC8vIGFjY291bnQgYWZ0ZXIgaW1hZ2UgZ2x5cGggaXMgcm90YXRlZFxuICAgICAgICAgICAgICAgIGxpbmVPZmZzZXQgPSBwb3NpdGlvbmVkR2x5cGguaW1hZ2VOYW1lID8gaGFsZkFkdmFuY2UgLSBwb3NpdGlvbmVkR2x5cGgubWV0cmljcy53aWR0aCAqIHBvc2l0aW9uZWRHbHlwaC5zY2FsZSAvIDIuMCA6IDA7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGdseXBoT2Zmc2V0ID0gYWxvbmdMaW5lID9cbiAgICAgICAgICAgICAgICBbcG9zaXRpb25lZEdseXBoLnggKyBoYWxmQWR2YW5jZSwgcG9zaXRpb25lZEdseXBoLnldIDpcbiAgICAgICAgICAgICAgICBbMCwgMF07XG5cbiAgICAgICAgICAgIGxldCBidWlsdEluT2Zmc2V0ID0gWzAsIDBdO1xuICAgICAgICAgICAgbGV0IHZlcnRpY2FsaXplZExhYmVsT2Zmc2V0ID0gWzAsIDBdO1xuICAgICAgICAgICAgbGV0IHVzZVJvdGF0ZU9mZnNldCA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKCFhbG9uZ0xpbmUpIHtcbiAgICAgICAgICAgICAgICBpZiAocm90YXRlVmVydGljYWxHbHlwaCkge1xuICAgICAgICAgICAgICAgIC8vIFZlcnRpY2FsIFBPSSBsYWJlbHMgdGhhdCBhcmUgcm90YXRlZCA5MGRlZyBDVyBhbmQgd2hvc2UgZ2x5cGhzIG11c3QgcHJlc2VydmUgdXByaWdodCBvcmllbnRhdGlvblxuICAgICAgICAgICAgICAgIC8vIG5lZWQgdG8gYmUgcm90YXRlZCA5MGRlZyBDQ1cuIEFmdGVyIGEgcXVhZCBpcyByb3RhdGVkLCBpdCBpcyB0cmFuc2xhdGVkIHRvIHRoZSBvcmlnaW5hbCBidWlsdC1pbiBvZmZzZXQuXG4gICAgICAgICAgICAgICAgICAgIHZlcnRpY2FsaXplZExhYmVsT2Zmc2V0ID1cbiAgICAgICAgICAgICAgICAgICAgICAgIFtwb3NpdGlvbmVkR2x5cGgueCArIGhhbGZBZHZhbmNlICsgcm90YXRlT2Zmc2V0WzBdLCBwb3NpdGlvbmVkR2x5cGgueSArIHJvdGF0ZU9mZnNldFsxXSAtIGxpbmVPZmZzZXRdO1xuICAgICAgICAgICAgICAgICAgICB1c2VSb3RhdGVPZmZzZXQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGJ1aWx0SW5PZmZzZXQgPSAgW3Bvc2l0aW9uZWRHbHlwaC54ICsgaGFsZkFkdmFuY2UgKyB0ZXh0T2Zmc2V0WzBdLCBwb3NpdGlvbmVkR2x5cGgueSArIHRleHRPZmZzZXRbMV0gLSBsaW5lT2Zmc2V0XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHBhZGRlZFdpZHRoID1cbiAgICAgICAgICAgICAgICByZWN0LncgKiBwb3NpdGlvbmVkR2x5cGguc2NhbGUgLyAocGl4ZWxSYXRpbyAqIChwb3NpdGlvbmVkR2x5cGgubG9jYWxHbHlwaCA/IFNERl9TQ0FMRSA6IDEpKTtcbiAgICAgICAgICAgIGNvbnN0ICBwYWRkZWRIZWlnaHQgPVxuICAgICAgICAgICAgICAgIHJlY3QuaCAqIHBvc2l0aW9uZWRHbHlwaC5zY2FsZSAvIChwaXhlbFJhdGlvICogKHBvc2l0aW9uZWRHbHlwaC5sb2NhbEdseXBoID8gU0RGX1NDQUxFIDogMSkpO1xuXG4gICAgICAgICAgICBsZXQgdGwsIHRyLCBibCwgYnI7XG4gICAgICAgICAgICBpZiAoIXJvdGF0ZVZlcnRpY2FsR2x5cGgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB4MSA9IChtZXRyaWNzLmxlZnQgLSByZWN0QnVmZmVyKSAqIHBvc2l0aW9uZWRHbHlwaC5zY2FsZSAtIGhhbGZBZHZhbmNlICsgYnVpbHRJbk9mZnNldFswXTtcbiAgICAgICAgICAgICAgICBjb25zdCB5MSA9ICgtbWV0cmljcy50b3AgLSByZWN0QnVmZmVyKSAqIHBvc2l0aW9uZWRHbHlwaC5zY2FsZSArIGJ1aWx0SW5PZmZzZXRbMV07XG4gICAgICAgICAgICAgICAgY29uc3QgeDIgPSB4MSArIHBhZGRlZFdpZHRoO1xuICAgICAgICAgICAgICAgIGNvbnN0IHkyID0geTEgKyBwYWRkZWRIZWlnaHQ7XG5cbiAgICAgICAgICAgICAgICB0bCA9IG5ldyBQb2ludCh4MSwgeTEpO1xuICAgICAgICAgICAgICAgIHRyID0gbmV3IFBvaW50KHgyLCB5MSk7XG4gICAgICAgICAgICAgICAgYmwgPSBuZXcgUG9pbnQoeDEsIHkyKTtcbiAgICAgICAgICAgICAgICBiciA9IG5ldyBQb2ludCh4MiwgeTIpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBGb3IgdmVydGljYWwgZ2x5cGggcGxhY2VtZW50LCBmb2xsb3cgdGhlIHN0ZXBzIHRvIHB1dCB0aGUgZ2x5cGggYml0bWFwIGluIHJpZ2h0IGNvb3JkaW5hdGVzOlxuICAgICAgICAgICAgICAgIC8vIDEuIFJvdGF0ZSB0aGUgZ2x5cGggYnkgdXNpbmcgb3JpZ2luYWwgZ2x5cGggY29vcmRpbmF0ZXMgaW5zdGVhZCBvZiBwYWRkZWQgY29vcmRpbmF0ZXMsIHNpbmNlIHRoZVxuICAgICAgICAgICAgICAgIC8vIHJvdGF0aW9uIGNlbnRlciBhbmQgeE9mZnNldENvcnJlY3Rpb24gYXJlIGFsbCBiYXNlZCBvbiBvcmlnaW5hbCBnbHlwaCdzIHNpemUuXG4gICAgICAgICAgICAgICAgLy8gMi4gRG8geCBvZmZzZXQgY29ycmVjdGlvbiBzbyB0aGF0ICd0bCcgaXMgc2hpZnRlZCB0byB0aGUgc2FtZSB4IGNvb3JkaW5hdGUgYmVmb3JlIHJvdGF0aW9uLlxuICAgICAgICAgICAgICAgIC8vIDMuIEFkanVzdCBnbHlwaCBwb3NpdG9uIGZvciAndGwnIGJ5IGFwcGx5aW5nIHZlcnRpYWwgcGFkZGluZyBhbmQgaG9yaXpvbnRhbCBzaGlmdCwgbm93ICd0bCcgaXMgdGhlXG4gICAgICAgICAgICAgICAgLy8gY29vcmRpbmF0ZSB3aGVyZSB3ZSBkcmF3IHRoZSBnbHlwaCBiaXRtYXAuXG4gICAgICAgICAgICAgICAgLy8gNC4gQ2FsY3VsYXRlIG90aGVyIHRocmVlIGJpdG1hcCBjb29yZGluYXRlcy5cblxuICAgICAgICAgICAgICAgIC8vIFZlcnRpY2FsLXN1cHBvcnRpbmcgZ2x5cGhzIGFyZSBsYWlkIG91dCBpbiAyNHgyNCBwb2ludCBib3hlcyAoMSBzcXVhcmUgZW0pXG4gICAgICAgICAgICAgICAgLy8gSW4gaG9yaXpvbnRhbCBvcmllbnRhdGlvbiwgdGhlIFwieVNoaWZ0XCIgaXMgdGhlIG5lZ2F0aXZlIHZhbHVlIG9mIHRoZSBoZWlnaHQgdGhhdFxuICAgICAgICAgICAgICAgIC8vIHRoZSBnbHlwaCBpcyBhYm92ZSB0aGUgaG9yaXpvbnRhbCBtaWRsaW5lLlxuICAgICAgICAgICAgICAgIC8vIEJ5IHJvdGF0aW5nIGNvdW50ZXItY2xvY2t3aXNlIGFyb3VuZCB0aGUgcG9pbnQgYXQgdGhlIGNlbnRlciBvZiB0aGUgbGVmdFxuICAgICAgICAgICAgICAgIC8vIGVkZ2Ugb2YgYSAyNHgyNCBsYXlvdXQgYm94IGNlbnRlcmVkIGJlbG93IHRoZSBtaWRsaW5lLCB3ZSBhbGlnbiB0aGUgbWlkbGluZVxuICAgICAgICAgICAgICAgIC8vIG9mIHRoZSByb3RhdGVkIGdseXBocyB3aXRoIHRoZSBob3Jpem9udGFsIG1pZGxpbmUsIHNvIHRoZSB5U2hpZnQgaXMgbm8gbG9uZ2VyXG4gICAgICAgICAgICAgICAgLy8gbmVjZXNzYXJ5LCBidXQgd2UgYWxzbyBwdWxsIHRoZSBnbHlwaCB0byB0aGUgbGVmdCBhbG9uZyB0aGUgeCBheGlzLlxuICAgICAgICAgICAgICAgIGNvbnN0IHlTaGlmdCA9IChwb3NpdGlvbmVkR2x5cGgueSAtIGN1cnJlbnRPZmZzZXQpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNlbnRlciA9IG5ldyBQb2ludCgtaGFsZkFkdmFuY2UsIGhhbGZBZHZhbmNlIC0geVNoaWZ0KTtcbiAgICAgICAgICAgICAgICBjb25zdCB2ZXJ0aWNhbFJvdGF0aW9uID0gLU1hdGguUEkgLyAyO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZlcnRpY2FsT2Zmc2V0Q29ycmVjdGlvbiA9IG5ldyBQb2ludCguLi52ZXJ0aWNhbGl6ZWRMYWJlbE9mZnNldCk7XG4gICAgICAgICAgICAgICAgLy8gUmVsYXRpdmUgcG9zaXRpb24gYmVmb3JlIHJvdGF0aW9uXG4gICAgICAgICAgICAgICAgLy8gdGwgLS0tLS0gdHJcbiAgICAgICAgICAgICAgICAvLyAgIHwgICAgIHxcbiAgICAgICAgICAgICAgICAvLyAgIHwgICAgIHxcbiAgICAgICAgICAgICAgICAvLyBibCAtLS0tLSBiclxuICAgICAgICAgICAgICAgIHRsID0gbmV3IFBvaW50KC1oYWxmQWR2YW5jZSArIGJ1aWx0SW5PZmZzZXRbMF0sIGJ1aWx0SW5PZmZzZXRbMV0pO1xuICAgICAgICAgICAgICAgIHRsLl9yb3RhdGVBcm91bmQodmVydGljYWxSb3RhdGlvbiwgY2VudGVyKS5fYWRkKHZlcnRpY2FsT2Zmc2V0Q29ycmVjdGlvbik7XG5cbiAgICAgICAgICAgICAgICAvLyBSZWxhdGl2ZSBwb3NpdGlvbiBhZnRlciByb3RhdGluZ1xuICAgICAgICAgICAgICAgIC8vIHRyIC0tLS0tIGJyXG4gICAgICAgICAgICAgICAgLy8gICB8ICAgICB8XG4gICAgICAgICAgICAgICAgLy8gICB8ICAgICB8XG4gICAgICAgICAgICAgICAgLy8gdGwgLS0tLS0gYmxcbiAgICAgICAgICAgICAgICAvLyBBZnRlciByb3RhdGlvbiwgZ2x5cGggbGllcyBvbiB0aGUgaG9yaXpvbnRhbCBtaWRsaW5lLlxuICAgICAgICAgICAgICAgIC8vIFNoaWZ0IGJhY2sgdG8gdGwncyBvcmlnaW5hbCB4IGNvb3JkaW5hdGUgYmVmb3JlIHJvdGF0aW9uIGJ5IGFwcGx5aW5nICd4T2Zmc2V0Q29ycmVjdGlvbicuXG4gICAgICAgICAgICAgICAgdGwueCArPSAteVNoaWZ0ICsgaGFsZkFkdmFuY2U7XG5cbiAgICAgICAgICAgICAgICAvLyBBZGQgcGFkZGluZyBmb3IgeSBjb29yZGluYXRlJ3MganVzdGlmaWNhdGlvblxuICAgICAgICAgICAgICAgIHRsLnkgLT0gKG1ldHJpY3MubGVmdCAtIHJlY3RCdWZmZXIpICogcG9zaXRpb25lZEdseXBoLnNjYWxlO1xuXG4gICAgICAgICAgICAgICAgLy8gQWRqdXN0IHggY29vcmRpbmF0ZSBhY2NvcmRpbmcgdG8gZ2x5cGggYml0bWFwJ3MgaGVpZ2h0IGFuZCB0aGUgdmVjdGljYWwgYWR2YW5jZVxuICAgICAgICAgICAgICAgIGNvbnN0IHZlcnRpY2FsQWR2YW5jZSA9IHBvc2l0aW9uZWRHbHlwaC5pbWFnZU5hbWUgPyBtZXRyaWNzLmFkdmFuY2UgKiBwb3NpdGlvbmVkR2x5cGguc2NhbGUgOlxuICAgICAgICAgICAgICAgICAgICBPTkVfRU0gKiBwb3NpdGlvbmVkR2x5cGguc2NhbGU7XG4gICAgICAgICAgICAgICAgLy8gQ2hlY2sgd2V0aGVyIHRoZSBnbHlwaCBpcyBnZW5lcmF0ZWQgZnJvbSBzZXJ2ZXIgc2lkZSBvciBsb2NhbGx5XG4gICAgICAgICAgICAgICAgY29uc3QgY2hyID0gU3RyaW5nLmZyb21DaGFyQ29kZShwb3NpdGlvbmVkR2x5cGguZ2x5cGgpO1xuICAgICAgICAgICAgICAgIGlmIChpc1ZlcnRpY2FsQ2xvc2VQdW5jdHVhdGlvbihjaHIpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFBsYWNlIHZlcnRpY2FsIHB1bmN0dWF0aW9uIGluIHJpZ2h0IHBsYWNlLCBwdWxsIGRvd24gMSBwaXhlbCdzIHNwYWNlIGZvciBjbG9zZSBwdW5jdHVhdGlvbnNcbiAgICAgICAgICAgICAgICAgICAgdGwueCArPSAoLXJlY3RCdWZmZXIgKyAxKSAqIHBvc2l0aW9uZWRHbHlwaC5zY2FsZTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGlzVmVydGljYWxPcGVuUHVuY3R1YXRpb24oY2hyKSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB4T2Zmc2V0ID0gdmVydGljYWxBZHZhbmNlIC0gbWV0cmljcy5oZWlnaHQgKiBwb3NpdGlvbmVkR2x5cGguc2NhbGU7XG4gICAgICAgICAgICAgICAgICAgIC8vIFBsYWNlIHZlcnRpY2FsIHB1bmN0dWF0aW9uIGluIHJpZ2h0IHBsYWNlLCBwdWxsIHVwIDEgcGl4ZWwncyBzcGFjZSBmb3Igb3BlbiBwdW5jdHVhdGlvbnNcbiAgICAgICAgICAgICAgICAgICAgdGwueCArPSB4T2Zmc2V0ICsgKC1yZWN0QnVmZmVyIC0gMSkgKiBwb3NpdGlvbmVkR2x5cGguc2NhbGU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICghcG9zaXRpb25lZEdseXBoLmltYWdlTmFtZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgKChtZXRyaWNzLndpZHRoICsgcmVjdEJ1ZmZlciAqIDIpICE9PSByZWN0LncgfHwgbWV0cmljcy5oZWlnaHQgKyByZWN0QnVmZmVyICogMiAhPT0gcmVjdC5oKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBMb2NhbGx5IGdlbmVyYXRlZCBnbHlwaHMnIGJpdG1hcCBkbyBub3QgaGF2ZSBleGFjdCAncmVjdEJ1ZmZlcicgcGFkZGVkIGFyb3VuZCB0aGUgZ2x5cGhzLFxuICAgICAgICAgICAgICAgICAgICAvLyBidXQgdGhlIG9yaWdpbmFsIHRsIGRvIGhhdmUgZGlzdGFuY2Ugb2YgcmVjdEJ1ZmZlciBwYWRkZWQgdG8gdGhlIHRvcCBvZiB0aGUgZ2x5cGguXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBlcmZlY3RQYWRkZWRIZWlnaHQgPSAobWV0cmljcy5oZWlnaHQgKyByZWN0QnVmZmVyICogMikgKiBwb3NpdGlvbmVkR2x5cGguc2NhbGU7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGRlbHRhID0gdmVydGljYWxBZHZhbmNlIC0gcGVyZmVjdFBhZGRlZEhlaWdodDtcbiAgICAgICAgICAgICAgICAgICAgdGwueCArPSBkZWx0YSAvIDI7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUGxhY2UgdGhlIGdseXBoIGJpdG1hcCByaWdodCBpbiB0aGUgY2VudGVyIG9mIHRoZSAyNHgyNCBwb2ludCBib3hlc1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWx0YSA9IHZlcnRpY2FsQWR2YW5jZSAtIHBhZGRlZEhlaWdodDtcbiAgICAgICAgICAgICAgICAgICAgdGwueCArPSBkZWx0YSAvIDI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIENhbGN1bGF0ZSBvdGhlciB0aHJlZSBwb2ludHNcbiAgICAgICAgICAgICAgICB0ciA9IG5ldyBQb2ludCh0bC54LCB0bC55IC0gcGFkZGVkV2lkdGgpO1xuICAgICAgICAgICAgICAgIGJsID0gbmV3IFBvaW50KHRsLnggKyBwYWRkZWRIZWlnaHQsIHRsLnkpO1xuICAgICAgICAgICAgICAgIGJyID0gbmV3IFBvaW50KHRsLnggKyBwYWRkZWRIZWlnaHQsIHRsLnkgLSBwYWRkZWRXaWR0aCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0ZXh0Um90YXRlKSB7XG4gICAgICAgICAgICAgICAgbGV0IGNlbnRlcjtcbiAgICAgICAgICAgICAgICBpZiAoIWFsb25nTGluZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodXNlUm90YXRlT2Zmc2V0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjZW50ZXIgPSBuZXcgUG9pbnQocm90YXRlT2Zmc2V0WzBdLCByb3RhdGVPZmZzZXRbMV0pO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2VudGVyID0gbmV3IFBvaW50KHRleHRPZmZzZXRbMF0sIHRleHRPZmZzZXRbMV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY2VudGVyID0gbmV3IFBvaW50KDAsIDApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0bC5fcm90YXRlQXJvdW5kKHRleHRSb3RhdGUsIGNlbnRlcik7XG4gICAgICAgICAgICAgICAgdHIuX3JvdGF0ZUFyb3VuZCh0ZXh0Um90YXRlLCBjZW50ZXIpO1xuICAgICAgICAgICAgICAgIGJsLl9yb3RhdGVBcm91bmQodGV4dFJvdGF0ZSwgY2VudGVyKTtcbiAgICAgICAgICAgICAgICBici5fcm90YXRlQXJvdW5kKHRleHRSb3RhdGUsIGNlbnRlcik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHBpeGVsT2Zmc2V0VEwgPSBuZXcgUG9pbnQoMCwgMCk7XG4gICAgICAgICAgICBjb25zdCBwaXhlbE9mZnNldEJSID0gbmV3IFBvaW50KDAsIDApO1xuICAgICAgICAgICAgY29uc3QgbWluRm9udFNjYWxlWCA9IDA7XG4gICAgICAgICAgICBjb25zdCBtaW5Gb250U2NhbGVZID0gMDtcbiAgICAgICAgICAgIHF1YWRzLnB1c2goe3RsLCB0ciwgYmwsIGJyLCB0ZXg6IHRleHR1cmVSZWN0LCB3cml0aW5nTW9kZTogc2hhcGluZy53cml0aW5nTW9kZSwgZ2x5cGhPZmZzZXQsIHNlY3Rpb25JbmRleDogcG9zaXRpb25lZEdseXBoLnNlY3Rpb25JbmRleCwgaXNTREYsIHBpeGVsT2Zmc2V0VEwsIHBpeGVsT2Zmc2V0QlIsIG1pbkZvbnRTY2FsZVgsIG1pbkZvbnRTY2FsZVl9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBxdWFkcztcbn1cbiIsIlxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVGlueVF1ZXVlIHtcbiAgICBjb25zdHJ1Y3RvcihkYXRhID0gW10sIGNvbXBhcmUgPSBkZWZhdWx0Q29tcGFyZSkge1xuICAgICAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICAgICAgICB0aGlzLmxlbmd0aCA9IHRoaXMuZGF0YS5sZW5ndGg7XG4gICAgICAgIHRoaXMuY29tcGFyZSA9IGNvbXBhcmU7XG5cbiAgICAgICAgaWYgKHRoaXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9ICh0aGlzLmxlbmd0aCA+PiAxKSAtIDE7IGkgPj0gMDsgaS0tKSB0aGlzLl9kb3duKGkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVzaChpdGVtKSB7XG4gICAgICAgIHRoaXMuZGF0YS5wdXNoKGl0ZW0pO1xuICAgICAgICB0aGlzLmxlbmd0aCsrO1xuICAgICAgICB0aGlzLl91cCh0aGlzLmxlbmd0aCAtIDEpO1xuICAgIH1cblxuICAgIHBvcCgpIHtcbiAgICAgICAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgICAgIGNvbnN0IHRvcCA9IHRoaXMuZGF0YVswXTtcbiAgICAgICAgY29uc3QgYm90dG9tID0gdGhpcy5kYXRhLnBvcCgpO1xuICAgICAgICB0aGlzLmxlbmd0aC0tO1xuXG4gICAgICAgIGlmICh0aGlzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YVswXSA9IGJvdHRvbTtcbiAgICAgICAgICAgIHRoaXMuX2Rvd24oMCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdG9wO1xuICAgIH1cblxuICAgIHBlZWsoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGFbMF07XG4gICAgfVxuXG4gICAgX3VwKHBvcykge1xuICAgICAgICBjb25zdCB7ZGF0YSwgY29tcGFyZX0gPSB0aGlzO1xuICAgICAgICBjb25zdCBpdGVtID0gZGF0YVtwb3NdO1xuXG4gICAgICAgIHdoaWxlIChwb3MgPiAwKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJlbnQgPSAocG9zIC0gMSkgPj4gMTtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnQgPSBkYXRhW3BhcmVudF07XG4gICAgICAgICAgICBpZiAoY29tcGFyZShpdGVtLCBjdXJyZW50KSA+PSAwKSBicmVhaztcbiAgICAgICAgICAgIGRhdGFbcG9zXSA9IGN1cnJlbnQ7XG4gICAgICAgICAgICBwb3MgPSBwYXJlbnQ7XG4gICAgICAgIH1cblxuICAgICAgICBkYXRhW3Bvc10gPSBpdGVtO1xuICAgIH1cblxuICAgIF9kb3duKHBvcykge1xuICAgICAgICBjb25zdCB7ZGF0YSwgY29tcGFyZX0gPSB0aGlzO1xuICAgICAgICBjb25zdCBoYWxmTGVuZ3RoID0gdGhpcy5sZW5ndGggPj4gMTtcbiAgICAgICAgY29uc3QgaXRlbSA9IGRhdGFbcG9zXTtcblxuICAgICAgICB3aGlsZSAocG9zIDwgaGFsZkxlbmd0aCkge1xuICAgICAgICAgICAgbGV0IGxlZnQgPSAocG9zIDw8IDEpICsgMTtcbiAgICAgICAgICAgIGxldCBiZXN0ID0gZGF0YVtsZWZ0XTtcbiAgICAgICAgICAgIGNvbnN0IHJpZ2h0ID0gbGVmdCArIDE7XG5cbiAgICAgICAgICAgIGlmIChyaWdodCA8IHRoaXMubGVuZ3RoICYmIGNvbXBhcmUoZGF0YVtyaWdodF0sIGJlc3QpIDwgMCkge1xuICAgICAgICAgICAgICAgIGxlZnQgPSByaWdodDtcbiAgICAgICAgICAgICAgICBiZXN0ID0gZGF0YVtyaWdodF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY29tcGFyZShiZXN0LCBpdGVtKSA+PSAwKSBicmVhaztcblxuICAgICAgICAgICAgZGF0YVtwb3NdID0gYmVzdDtcbiAgICAgICAgICAgIHBvcyA9IGxlZnQ7XG4gICAgICAgIH1cblxuICAgICAgICBkYXRhW3Bvc10gPSBpdGVtO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZGVmYXVsdENvbXBhcmUoYSwgYikge1xuICAgIHJldHVybiBhIDwgYiA/IC0xIDogYSA+IGIgPyAxIDogMDtcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBRdWV1ZSBmcm9tICd0aW55cXVldWUnO1xuXG5pbXBvcnQgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5pbXBvcnQge2Rpc3RUb1NlZ21lbnRTcXVhcmVkfSBmcm9tICcuL2ludGVyc2VjdGlvbl90ZXN0cy5qcyc7XG5cbi8qKlxuICogRmluZHMgYW4gYXBwcm94aW1hdGlvbiBvZiBhIHBvbHlnb24ncyBQb2xlIE9mIEluYWNjZXNzaWJpbGl0eSBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Qb2xlX29mX2luYWNjZXNzaWJpbGl0eVxuICogVGhpcyBpcyBhIGNvcHkgb2YgaHR0cDovL2dpdGh1Yi5jb20vbWFwYm94L3BvbHlsYWJlbCBhZGFwdGVkIHRvIHVzZSBQb2ludHNcbiAqXG4gKiBAcGFyYW0gcG9seWdvblJpbmdzIGZpcnN0IGl0ZW0gaW4gYXJyYXkgaXMgdGhlIG91dGVyIHJpbmcgZm9sbG93ZWQgb3B0aW9uYWxseSBieSB0aGUgbGlzdCBvZiBob2xlcywgc2hvdWxkIGJlIGFuIGVsZW1lbnQgb2YgdGhlIHJlc3VsdCBvZiB1dGlsL2NsYXNzaWZ5X3JpbmdzXG4gKiBAcGFyYW0gcHJlY2lzaW9uIFNwZWNpZmllZCBpbiBpbnB1dCBjb29yZGluYXRlIHVuaXRzLiBJZiAwIHJldHVybnMgYWZ0ZXIgZmlyc3QgcnVuLCBpZiA+IDAgcmVwZWF0ZWRseSBuYXJyb3dzIHRoZSBzZWFyY2ggc3BhY2UgdW50aWwgdGhlIHJhZGl1cyBvZiB0aGUgYXJlYSBzZWFyY2hlZCBmb3IgdGhlIGJlc3QgcG9sZSBpcyBsZXNzIHRoYW4gcHJlY2lzaW9uXG4gKiBAcGFyYW0gZGVidWcgUHJpbnQgc29tZSBzdGF0aXN0aWNzIHRvIHRoZSBjb25zb2xlIGR1cmluZyBleGVjdXRpb25cbiAqIEByZXR1cm5zIFBvbGUgb2YgSW5hY2Nlc3NpYmlsaXR5LlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKHBvbHlnb25SaW5nczogQXJyYXk8QXJyYXk8UG9pbnQ+PiwgcHJlY2lzaW9uPzogbnVtYmVyID0gMSwgZGVidWc/OiBib29sZWFuID0gZmFsc2UpOiBQb2ludCB7XG4gICAgLy8gZmluZCB0aGUgYm91bmRpbmcgYm94IG9mIHRoZSBvdXRlciByaW5nXG4gICAgbGV0IG1pblggPSBJbmZpbml0eSwgbWluWSA9IEluZmluaXR5LCBtYXhYID0gLUluZmluaXR5LCBtYXhZID0gLUluZmluaXR5O1xuICAgIGNvbnN0IG91dGVyUmluZyA9IHBvbHlnb25SaW5nc1swXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG91dGVyUmluZy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBwID0gb3V0ZXJSaW5nW2ldO1xuICAgICAgICBpZiAoIWkgfHwgcC54IDwgbWluWCkgbWluWCA9IHAueDtcbiAgICAgICAgaWYgKCFpIHx8IHAueSA8IG1pblkpIG1pblkgPSBwLnk7XG4gICAgICAgIGlmICghaSB8fCBwLnggPiBtYXhYKSBtYXhYID0gcC54O1xuICAgICAgICBpZiAoIWkgfHwgcC55ID4gbWF4WSkgbWF4WSA9IHAueTtcbiAgICB9XG5cbiAgICBjb25zdCB3aWR0aCA9IG1heFggLSBtaW5YO1xuICAgIGNvbnN0IGhlaWdodCA9IG1heFkgLSBtaW5ZO1xuICAgIGNvbnN0IGNlbGxTaXplID0gTWF0aC5taW4od2lkdGgsIGhlaWdodCk7XG4gICAgbGV0IGggPSBjZWxsU2l6ZSAvIDI7XG5cbiAgICAvLyBhIHByaW9yaXR5IHF1ZXVlIG9mIGNlbGxzIGluIG9yZGVyIG9mIHRoZWlyIFwicG90ZW50aWFsXCIgKG1heCBkaXN0YW5jZSB0byBwb2x5Z29uKVxuICAgIGNvbnN0IGNlbGxRdWV1ZSA9IG5ldyBRdWV1ZShbXSwgY29tcGFyZU1heCk7XG5cbiAgICBpZiAoY2VsbFNpemUgPT09IDApIHJldHVybiBuZXcgUG9pbnQobWluWCwgbWluWSk7XG5cbiAgICAvLyBjb3ZlciBwb2x5Z29uIHdpdGggaW5pdGlhbCBjZWxsc1xuICAgIGZvciAobGV0IHggPSBtaW5YOyB4IDwgbWF4WDsgeCArPSBjZWxsU2l6ZSkge1xuICAgICAgICBmb3IgKGxldCB5ID0gbWluWTsgeSA8IG1heFk7IHkgKz0gY2VsbFNpemUpIHtcbiAgICAgICAgICAgIGNlbGxRdWV1ZS5wdXNoKG5ldyBDZWxsKHggKyBoLCB5ICsgaCwgaCwgcG9seWdvblJpbmdzKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyB0YWtlIGNlbnRyb2lkIGFzIHRoZSBmaXJzdCBiZXN0IGd1ZXNzXG4gICAgbGV0IGJlc3RDZWxsID0gZ2V0Q2VudHJvaWRDZWxsKHBvbHlnb25SaW5ncyk7XG4gICAgbGV0IG51bVByb2JlcyA9IGNlbGxRdWV1ZS5sZW5ndGg7XG5cbiAgICB3aGlsZSAoY2VsbFF1ZXVlLmxlbmd0aCkge1xuICAgICAgICAvLyBwaWNrIHRoZSBtb3N0IHByb21pc2luZyBjZWxsIGZyb20gdGhlIHF1ZXVlXG4gICAgICAgIGNvbnN0IGNlbGwgPSBjZWxsUXVldWUucG9wKCk7XG5cbiAgICAgICAgLy8gdXBkYXRlIHRoZSBiZXN0IGNlbGwgaWYgd2UgZm91bmQgYSBiZXR0ZXIgb25lXG4gICAgICAgIGlmIChjZWxsLmQgPiBiZXN0Q2VsbC5kIHx8ICFiZXN0Q2VsbC5kKSB7XG4gICAgICAgICAgICBiZXN0Q2VsbCA9IGNlbGw7XG4gICAgICAgICAgICBpZiAoZGVidWcpIGNvbnNvbGUubG9nKCdmb3VuZCBiZXN0ICVkIGFmdGVyICVkIHByb2JlcycsIE1hdGgucm91bmQoMWU0ICogY2VsbC5kKSAvIDFlNCwgbnVtUHJvYmVzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGRvIG5vdCBkcmlsbCBkb3duIGZ1cnRoZXIgaWYgdGhlcmUncyBubyBjaGFuY2Ugb2YgYSBiZXR0ZXIgc29sdXRpb25cbiAgICAgICAgaWYgKGNlbGwubWF4IC0gYmVzdENlbGwuZCA8PSBwcmVjaXNpb24pIGNvbnRpbnVlO1xuXG4gICAgICAgIC8vIHNwbGl0IHRoZSBjZWxsIGludG8gZm91ciBjZWxsc1xuICAgICAgICBoID0gY2VsbC5oIC8gMjtcbiAgICAgICAgY2VsbFF1ZXVlLnB1c2gobmV3IENlbGwoY2VsbC5wLnggLSBoLCBjZWxsLnAueSAtIGgsIGgsIHBvbHlnb25SaW5ncykpO1xuICAgICAgICBjZWxsUXVldWUucHVzaChuZXcgQ2VsbChjZWxsLnAueCArIGgsIGNlbGwucC55IC0gaCwgaCwgcG9seWdvblJpbmdzKSk7XG4gICAgICAgIGNlbGxRdWV1ZS5wdXNoKG5ldyBDZWxsKGNlbGwucC54IC0gaCwgY2VsbC5wLnkgKyBoLCBoLCBwb2x5Z29uUmluZ3MpKTtcbiAgICAgICAgY2VsbFF1ZXVlLnB1c2gobmV3IENlbGwoY2VsbC5wLnggKyBoLCBjZWxsLnAueSArIGgsIGgsIHBvbHlnb25SaW5ncykpO1xuICAgICAgICBudW1Qcm9iZXMgKz0gNDtcbiAgICB9XG5cbiAgICBpZiAoZGVidWcpIHtcbiAgICAgICAgY29uc29sZS5sb2coYG51bSBwcm9iZXM6ICR7bnVtUHJvYmVzfWApO1xuICAgICAgICBjb25zb2xlLmxvZyhgYmVzdCBkaXN0YW5jZTogJHtiZXN0Q2VsbC5kfWApO1xuICAgIH1cblxuICAgIHJldHVybiBiZXN0Q2VsbC5wO1xufVxuXG5mdW5jdGlvbiBjb21wYXJlTWF4KGE6IENlbGwsIGI6IENlbGwpIHtcbiAgICByZXR1cm4gYi5tYXggLSBhLm1heDtcbn1cblxuY2xhc3MgQ2VsbCB7XG4gICAgcDogUG9pbnQ7XG4gICAgaDogbnVtYmVyO1xuICAgIGQ6IG51bWJlcjtcbiAgICBtYXg6IG51bWJlcjtcblxuICAgIGNvbnN0cnVjdG9yKHg6IG51bWJlciwgeTogbnVtYmVyLCBoOiBudW1iZXIsIHBvbHlnb246IEFycmF5PEFycmF5PFBvaW50Pj4pIHtcbiAgICAgICAgdGhpcy5wID0gbmV3IFBvaW50KHgsIHkpO1xuICAgICAgICB0aGlzLmggPSBoOyAvLyBoYWxmIHRoZSBjZWxsIHNpemVcbiAgICAgICAgdGhpcy5kID0gcG9pbnRUb1BvbHlnb25EaXN0KHRoaXMucCwgcG9seWdvbik7IC8vIGRpc3RhbmNlIGZyb20gY2VsbCBjZW50ZXIgdG8gcG9seWdvblxuICAgICAgICB0aGlzLm1heCA9IHRoaXMuZCArIHRoaXMuaCAqIE1hdGguU1FSVDI7IC8vIG1heCBkaXN0YW5jZSB0byBwb2x5Z29uIHdpdGhpbiBhIGNlbGxcbiAgICB9XG59XG5cbi8vIHNpZ25lZCBkaXN0YW5jZSBmcm9tIHBvaW50IHRvIHBvbHlnb24gb3V0bGluZSAobmVnYXRpdmUgaWYgcG9pbnQgaXMgb3V0c2lkZSlcbmZ1bmN0aW9uIHBvaW50VG9Qb2x5Z29uRGlzdChwOiBQb2ludCwgcG9seWdvbjogQXJyYXk8QXJyYXk8UG9pbnQ+Pikge1xuICAgIGxldCBpbnNpZGUgPSBmYWxzZTtcbiAgICBsZXQgbWluRGlzdFNxID0gSW5maW5pdHk7XG5cbiAgICBmb3IgKGxldCBrID0gMDsgayA8IHBvbHlnb24ubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgY29uc3QgcmluZyA9IHBvbHlnb25ba107XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHJpbmcubGVuZ3RoLCBqID0gbGVuIC0gMTsgaSA8IGxlbjsgaiA9IGkrKykge1xuICAgICAgICAgICAgY29uc3QgYSA9IHJpbmdbaV07XG4gICAgICAgICAgICBjb25zdCBiID0gcmluZ1tqXTtcblxuICAgICAgICAgICAgaWYgKChhLnkgPiBwLnkgIT09IGIueSA+IHAueSkgJiZcbiAgICAgICAgICAgICAgICAocC54IDwgKGIueCAtIGEueCkgKiAocC55IC0gYS55KSAvIChiLnkgLSBhLnkpICsgYS54KSkgaW5zaWRlID0gIWluc2lkZTtcblxuICAgICAgICAgICAgbWluRGlzdFNxID0gTWF0aC5taW4obWluRGlzdFNxLCBkaXN0VG9TZWdtZW50U3F1YXJlZChwLCBhLCBiKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gKGluc2lkZSA/IDEgOiAtMSkgKiBNYXRoLnNxcnQobWluRGlzdFNxKTtcbn1cblxuLy8gZ2V0IHBvbHlnb24gY2VudHJvaWRcbmZ1bmN0aW9uIGdldENlbnRyb2lkQ2VsbChwb2x5Z29uOiBBcnJheTxBcnJheTxQb2ludD4+KSB7XG4gICAgbGV0IGFyZWEgPSAwO1xuICAgIGxldCB4ID0gMDtcbiAgICBsZXQgeSA9IDA7XG4gICAgY29uc3QgcG9pbnRzID0gcG9seWdvblswXTtcbiAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gcG9pbnRzLmxlbmd0aCwgaiA9IGxlbiAtIDE7IGkgPCBsZW47IGogPSBpKyspIHtcbiAgICAgICAgY29uc3QgYSA9IHBvaW50c1tpXTtcbiAgICAgICAgY29uc3QgYiA9IHBvaW50c1tqXTtcbiAgICAgICAgY29uc3QgZiA9IGEueCAqIGIueSAtIGIueCAqIGEueTtcbiAgICAgICAgeCArPSAoYS54ICsgYi54KSAqIGY7XG4gICAgICAgIHkgKz0gKGEueSArIGIueSkgKiBmO1xuICAgICAgICBhcmVhICs9IGYgKiAzO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IENlbGwoeCAvIGFyZWEsIHkgLyBhcmVhLCAwLCBwb2x5Z29uKTtcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBBbmNob3IgZnJvbSAnLi9hbmNob3IuanMnO1xuXG5pbXBvcnQge2dldEFuY2hvcnMsIGdldENlbnRlckFuY2hvcn0gZnJvbSAnLi9nZXRfYW5jaG9ycy5qcyc7XG5pbXBvcnQgY2xpcExpbmUgZnJvbSAnLi9jbGlwX2xpbmUuanMnO1xuaW1wb3J0IHtzaGFwZVRleHQsIHNoYXBlSWNvbiwgV3JpdGluZ01vZGUsIGZpdEljb25Ub1RleHR9IGZyb20gJy4vc2hhcGluZy5qcyc7XG5pbXBvcnQge2dldEdseXBoUXVhZHMsIGdldEljb25RdWFkc30gZnJvbSAnLi9xdWFkcy5qcyc7XG5pbXBvcnQge3dhcm5PbmNlLCBkZWdUb1JhZH0gZnJvbSAnLi4vdXRpbC91dGlsLmpzJztcbmltcG9ydCB7XG4gICAgYWxsb3dzVmVydGljYWxXcml0aW5nTW9kZSxcbiAgICBhbGxvd3NMZXR0ZXJTcGFjaW5nXG59IGZyb20gJy4uL3V0aWwvc2NyaXB0X2RldGVjdGlvbi5qcyc7XG5pbXBvcnQgZmluZFBvbGVPZkluYWNjZXNzaWJpbGl0eSBmcm9tICcuLi91dGlsL2ZpbmRfcG9sZV9vZl9pbmFjY2Vzc2liaWxpdHkuanMnO1xuaW1wb3J0IGNsYXNzaWZ5UmluZ3MgZnJvbSAnLi4vdXRpbC9jbGFzc2lmeV9yaW5ncy5qcyc7XG5pbXBvcnQgRVhURU5UIGZyb20gJy4uL2RhdGEvZXh0ZW50LmpzJztcbmltcG9ydCBTeW1ib2xCdWNrZXQgZnJvbSAnLi4vZGF0YS9idWNrZXQvc3ltYm9sX2J1Y2tldC5qcyc7XG5pbXBvcnQgRXZhbHVhdGlvblBhcmFtZXRlcnMgZnJvbSAnLi4vc3R5bGUvZXZhbHVhdGlvbl9wYXJhbWV0ZXJzLmpzJztcbmltcG9ydCB7U0laRV9QQUNLX0ZBQ1RPUn0gZnJvbSAnLi9zeW1ib2xfc2l6ZS5qcyc7XG5pbXBvcnQgT05FX0VNIGZyb20gJy4vb25lX2VtLmpzJztcbmltcG9ydCB0eXBlIHtDYW5vbmljYWxUaWxlSUR9IGZyb20gJy4uL3NvdXJjZS90aWxlX2lkLmpzJztcbmltcG9ydCB0eXBlIHtTaGFwaW5nLCBQb3NpdGlvbmVkSWNvbiwgVGV4dEp1c3RpZnl9IGZyb20gJy4vc2hhcGluZy5qcyc7XG5pbXBvcnQgdHlwZSB7Q29sbGlzaW9uQm94QXJyYXl9IGZyb20gJy4uL2RhdGEvYXJyYXlfdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge1N5bWJvbEZlYXR1cmV9IGZyb20gJy4uL2RhdGEvYnVja2V0L3N5bWJvbF9idWNrZXQuanMnO1xuaW1wb3J0IHR5cGUge1N0eWxlSW1hZ2V9IGZyb20gJy4uL3N0eWxlL3N0eWxlX2ltYWdlLmpzJztcbmltcG9ydCB0eXBlIHtTdHlsZUdseXBofSBmcm9tICcuLi9zdHlsZS9zdHlsZV9nbHlwaC5qcyc7XG5pbXBvcnQgdHlwZSBTeW1ib2xTdHlsZUxheWVyIGZyb20gJy4uL3N0eWxlL3N0eWxlX2xheWVyL3N5bWJvbF9zdHlsZV9sYXllci5qcyc7XG5pbXBvcnQgdHlwZSB7SW1hZ2VQb3NpdGlvbn0gZnJvbSAnLi4vcmVuZGVyL2ltYWdlX2F0bGFzLmpzJztcbmltcG9ydCB0eXBlIHtHbHlwaFBvc2l0aW9uc30gZnJvbSAnLi4vcmVuZGVyL2dseXBoX2F0bGFzLmpzJztcbmltcG9ydCB0eXBlIHtQb3NzaWJseUV2YWx1YXRlZFByb3BlcnR5VmFsdWV9IGZyb20gJy4uL3N0eWxlL3Byb3BlcnRpZXMuanMnO1xuaW1wb3J0IHR5cGUgUHJvamVjdGlvbiBmcm9tICcuLi9nZW8vcHJvamVjdGlvbi9wcm9qZWN0aW9uLmpzJztcbmltcG9ydCB0eXBlIHtWZWMzfSBmcm9tICdnbC1tYXRyaXgnO1xuXG5pbXBvcnQgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5pbXBvcnQgbXVybXVyMyBmcm9tICdtdXJtdXJoYXNoLWpzJztcblxuLy8gVGhlIHN5bWJvbCBsYXlvdXQgcHJvY2VzcyBuZWVkcyBgdGV4dC1zaXplYCBldmFsdWF0ZWQgYXQgdXAgdG8gZml2ZSBkaWZmZXJlbnQgem9vbSBsZXZlbHMsIGFuZFxuLy8gYGljb24tc2l6ZWAgYXQgdXAgdG8gdGhyZWU6XG4vL1xuLy8gICAxLiBgdGV4dC1zaXplYCBhdCB0aGUgem9vbSBsZXZlbCBvZiB0aGUgYnVja2V0LiBVc2VkIHRvIGNhbGN1bGF0ZSBhIHBlci1mZWF0dXJlIHNpemUgZm9yIHNvdXJjZSBgdGV4dC1zaXplYFxuLy8gICAgICAgZXhwcmVzc2lvbnMsIGFuZCB0byBjYWxjdWxhdGUgdGhlIGJveCBkaW1lbnNpb25zIGZvciBpY29uLXRleHQtZml0LlxuLy8gICAyLiBgaWNvbi1zaXplYCBhdCB0aGUgem9vbSBsZXZlbCBvZiB0aGUgYnVja2V0LiBVc2VkIHRvIGNhbGN1bGF0ZSBhIHBlci1mZWF0dXJlIHNpemUgZm9yIHNvdXJjZSBgaWNvbi1zaXplYFxuLy8gICAgICAgZXhwcmVzc2lvbnMuXG4vLyAgIDMuIGB0ZXh0LXNpemVgIGFuZCBgaWNvbi1zaXplYCBhdCB0aGUgem9vbSBsZXZlbCBvZiB0aGUgYnVja2V0LCBwbHVzIG9uZS4gVXNlZCB0byBjYWxjdWxhdGUgY29sbGlzaW9uIGJveGVzLlxuLy8gICA0LiBgdGV4dC1zaXplYCBhdCB6b29tIGxldmVsIDE4LiBVc2VkIGZvciBzb21ldGhpbmcgbGluZS1zeW1ib2wtcGxhY2VtZW50LXJlbGF0ZWQuXG4vLyAgIDUuICBGb3IgY29tcG9zaXRlIGAqLXNpemVgIGV4cHJlc3Npb25zOiB0d28gem9vbSBsZXZlbHMgb2YgY3VydmUgc3RvcHMgdGhhdCBcImNvdmVyXCIgdGhlIHpvb20gbGV2ZWwgb2YgdGhlXG4vLyAgICAgICBidWNrZXQuIFRoZXNlIGdvIGludG8gYSB2ZXJ0ZXggYnVmZmVyIGFuZCBhcmUgdXNlZCBieSB0aGUgc2hhZGVyIHRvIGludGVycG9sYXRlIHRoZSBzaXplIGF0IHJlbmRlciB0aW1lLlxuLy9cbi8vICgxKSBhbmQgKDIpIGFyZSBzdG9yZWQgaW4gYGJ1Y2tldC5sYXllcnNbMF0ubGF5b3V0YC4gVGhlIHJlbWFpbmRlciBhcmUgYmVsb3cuXG4vL1xudHlwZSBTaXplcyA9IHtcbiAgICBsYXlvdXRUZXh0U2l6ZTogUG9zc2libHlFdmFsdWF0ZWRQcm9wZXJ0eVZhbHVlPG51bWJlcj4sIC8vICgzKVxuICAgIGxheW91dEljb25TaXplOiBQb3NzaWJseUV2YWx1YXRlZFByb3BlcnR5VmFsdWU8bnVtYmVyPiwgLy8gKDMpXG4gICAgdGV4dE1heFNpemU6IFBvc3NpYmx5RXZhbHVhdGVkUHJvcGVydHlWYWx1ZTxudW1iZXI+LCAgICAvLyAoNClcbiAgICBjb21wb3NpdGVUZXh0U2l6ZXM6IFtQb3NzaWJseUV2YWx1YXRlZFByb3BlcnR5VmFsdWU8bnVtYmVyPiwgUG9zc2libHlFdmFsdWF0ZWRQcm9wZXJ0eVZhbHVlPG51bWJlcj5dLCAvLyAoNSlcbiAgICBjb21wb3NpdGVJY29uU2l6ZXM6IFtQb3NzaWJseUV2YWx1YXRlZFByb3BlcnR5VmFsdWU8bnVtYmVyPiwgUG9zc2libHlFdmFsdWF0ZWRQcm9wZXJ0eVZhbHVlPG51bWJlcj5dLCAvLyAoNSlcbn07XG5cbmV4cG9ydCB0eXBlIFRleHRBbmNob3IgPSAnY2VudGVyJyB8ICdsZWZ0JyB8ICdyaWdodCcgfCAndG9wJyB8ICdib3R0b20nIHwgJ3RvcC1sZWZ0JyB8ICd0b3AtcmlnaHQnIHwgJ2JvdHRvbS1sZWZ0JyB8ICdib3R0b20tcmlnaHQnO1xuXG4vLyBUaGUgcmFkaWFsIG9mZnNldCBpcyB0byB0aGUgZWRnZSBvZiB0aGUgdGV4dCBib3hcbi8vIEluIHRoZSBob3Jpem9udGFsIGRpcmVjdGlvbiwgdGhlIGVkZ2Ugb2YgdGhlIHRleHQgYm94IGlzIHdoZXJlIGdseXBocyBzdGFydFxuLy8gQnV0IGluIHRoZSB2ZXJ0aWNhbCBkaXJlY3Rpb24sIHRoZSBnbHlwaHMgYXBwZWFyIHRvIFwic3RhcnRcIiBhdCB0aGUgYmFzZWxpbmVcbi8vIFdlIGRvbid0IGFjdHVhbGx5IGxvYWQgYmFzZWxpbmUgZGF0YSwgYnV0IHdlIGFzc3VtZSBhbiBvZmZzZXQgb2YgT05FX0VNIC0gMTdcbi8vIChzZWUgXCJ5T2Zmc2V0XCIgaW4gc2hhcGluZy5qcylcbmNvbnN0IGJhc2VsaW5lT2Zmc2V0ID0gNztcbmNvbnN0IElOVkFMSURfVEVYVF9PRkZTRVQgPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG5jb25zdCBzcXJ0MiA9IE1hdGguc3FydCgyKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGV2YWx1YXRlVmFyaWFibGVPZmZzZXQoYW5jaG9yOiBUZXh0QW5jaG9yLCBbb2Zmc2V0WCwgb2Zmc2V0WV06IFtudW1iZXIsIG51bWJlcl0pOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgICBsZXQgeCA9IDAsIHkgPSAwO1xuXG4gICAgaWYgKG9mZnNldFkgPT09IElOVkFMSURfVEVYVF9PRkZTRVQpIHsgLy8gcmFkaWFsIG9mZnNldFxuICAgICAgICBpZiAob2Zmc2V0WCA8IDApIG9mZnNldFggPSAwOyAvLyBJZ25vcmUgbmVnYXRpdmUgb2Zmc2V0LlxuICAgICAgICAvLyBzb2x2ZSBmb3IgciB3aGVyZSByXjIgKyByXjIgPSBvZmZzZXRYXjJcbiAgICAgICAgY29uc3QgaHlwb3RlbnVzZSA9IG9mZnNldFggLyBzcXJ0MjtcbiAgICAgICAgc3dpdGNoIChhbmNob3IpIHtcbiAgICAgICAgY2FzZSAndG9wLXJpZ2h0JzpcbiAgICAgICAgY2FzZSAndG9wLWxlZnQnOlxuICAgICAgICAgICAgeSA9IGh5cG90ZW51c2UgLSBiYXNlbGluZU9mZnNldDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdib3R0b20tcmlnaHQnOlxuICAgICAgICBjYXNlICdib3R0b20tbGVmdCc6XG4gICAgICAgICAgICB5ID0gLWh5cG90ZW51c2UgKyBiYXNlbGluZU9mZnNldDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdib3R0b20nOlxuICAgICAgICAgICAgeSA9IC1vZmZzZXRYICsgYmFzZWxpbmVPZmZzZXQ7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAndG9wJzpcbiAgICAgICAgICAgIHkgPSBvZmZzZXRYIC0gYmFzZWxpbmVPZmZzZXQ7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIHN3aXRjaCAoYW5jaG9yKSB7XG4gICAgICAgIGNhc2UgJ3RvcC1yaWdodCc6XG4gICAgICAgIGNhc2UgJ2JvdHRvbS1yaWdodCc6XG4gICAgICAgICAgICB4ID0gLWh5cG90ZW51c2U7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAndG9wLWxlZnQnOlxuICAgICAgICBjYXNlICdib3R0b20tbGVmdCc6XG4gICAgICAgICAgICB4ID0gaHlwb3RlbnVzZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdsZWZ0JzpcbiAgICAgICAgICAgIHggPSBvZmZzZXRYO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3JpZ2h0JzpcbiAgICAgICAgICAgIHggPSAtb2Zmc2V0WDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICB9IGVsc2UgeyAvLyB0ZXh0IG9mZnNldFxuICAgICAgICAvLyBVc2UgYWJzb2x1dGUgb2Zmc2V0IHZhbHVlcy5cbiAgICAgICAgb2Zmc2V0WCA9IE1hdGguYWJzKG9mZnNldFgpO1xuICAgICAgICBvZmZzZXRZID0gTWF0aC5hYnMob2Zmc2V0WSk7XG5cbiAgICAgICAgc3dpdGNoIChhbmNob3IpIHtcbiAgICAgICAgY2FzZSAndG9wLXJpZ2h0JzpcbiAgICAgICAgY2FzZSAndG9wLWxlZnQnOlxuICAgICAgICBjYXNlICd0b3AnOlxuICAgICAgICAgICAgeSA9IG9mZnNldFkgLSBiYXNlbGluZU9mZnNldDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdib3R0b20tcmlnaHQnOlxuICAgICAgICBjYXNlICdib3R0b20tbGVmdCc6XG4gICAgICAgIGNhc2UgJ2JvdHRvbSc6XG4gICAgICAgICAgICB5ID0gLW9mZnNldFkgKyBiYXNlbGluZU9mZnNldDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgc3dpdGNoIChhbmNob3IpIHtcbiAgICAgICAgY2FzZSAndG9wLXJpZ2h0JzpcbiAgICAgICAgY2FzZSAnYm90dG9tLXJpZ2h0JzpcbiAgICAgICAgY2FzZSAncmlnaHQnOlxuICAgICAgICAgICAgeCA9IC1vZmZzZXRYO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3RvcC1sZWZ0JzpcbiAgICAgICAgY2FzZSAnYm90dG9tLWxlZnQnOlxuICAgICAgICBjYXNlICdsZWZ0JzpcbiAgICAgICAgICAgIHggPSBvZmZzZXRYO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gW3gsIHldO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGVyZm9ybVN5bWJvbExheW91dChidWNrZXQ6IFN5bWJvbEJ1Y2tldCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2x5cGhNYXA6IHtbXzogc3RyaW5nXToge2dseXBoczoge1tfOiBudW1iZXJdOiA/U3R5bGVHbHlwaH0sIGFzY2VuZGVyPzogbnVtYmVyLCBkZXNjZW5kZXI/OiBudW1iZXJ9fSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2x5cGhQb3NpdGlvbnM6IEdseXBoUG9zaXRpb25zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbWFnZU1hcDoge1tfOiBzdHJpbmddOiBTdHlsZUltYWdlfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1hZ2VQb3NpdGlvbnM6IHtbXzogc3RyaW5nXTogSW1hZ2VQb3NpdGlvbn0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3dDb2xsaXNpb25Cb3hlczogYm9vbGVhbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXZhaWxhYmxlSW1hZ2VzOiBBcnJheTxzdHJpbmc+LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYW5vbmljYWw6IENhbm9uaWNhbFRpbGVJRCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGlsZVpvb206IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvamVjdGlvbjogUHJvamVjdGlvbikge1xuICAgIGJ1Y2tldC5jcmVhdGVBcnJheXMoKTtcblxuICAgIGNvbnN0IHRpbGVTaXplID0gNTEyICogYnVja2V0Lm92ZXJzY2FsaW5nO1xuICAgIGJ1Y2tldC50aWxlUGl4ZWxSYXRpbyA9IEVYVEVOVCAvIHRpbGVTaXplO1xuICAgIGJ1Y2tldC5jb21wYXJlVGV4dCA9IHt9O1xuICAgIGJ1Y2tldC5pY29uc05lZWRMaW5lYXIgPSBmYWxzZTtcblxuICAgIGNvbnN0IGxheW91dCA9IGJ1Y2tldC5sYXllcnNbMF0ubGF5b3V0O1xuICAgIGNvbnN0IHVuZXZhbHVhdGVkTGF5b3V0VmFsdWVzID0gYnVja2V0LmxheWVyc1swXS5fdW5ldmFsdWF0ZWRMYXlvdXQuX3ZhbHVlcztcblxuICAgIGNvbnN0IHNpemVzID0ge307XG5cbiAgICBpZiAoYnVja2V0LnRleHRTaXplRGF0YS5raW5kID09PSAnY29tcG9zaXRlJykge1xuICAgICAgICBjb25zdCB7bWluWm9vbSwgbWF4Wm9vbX0gPSBidWNrZXQudGV4dFNpemVEYXRhO1xuICAgICAgICBzaXplcy5jb21wb3NpdGVUZXh0U2l6ZXMgPSBbXG4gICAgICAgICAgICB1bmV2YWx1YXRlZExheW91dFZhbHVlc1sndGV4dC1zaXplJ10ucG9zc2libHlFdmFsdWF0ZShuZXcgRXZhbHVhdGlvblBhcmFtZXRlcnMobWluWm9vbSksIGNhbm9uaWNhbCksXG4gICAgICAgICAgICB1bmV2YWx1YXRlZExheW91dFZhbHVlc1sndGV4dC1zaXplJ10ucG9zc2libHlFdmFsdWF0ZShuZXcgRXZhbHVhdGlvblBhcmFtZXRlcnMobWF4Wm9vbSksIGNhbm9uaWNhbClcbiAgICAgICAgXTtcbiAgICB9XG5cbiAgICBpZiAoYnVja2V0Lmljb25TaXplRGF0YS5raW5kID09PSAnY29tcG9zaXRlJykge1xuICAgICAgICBjb25zdCB7bWluWm9vbSwgbWF4Wm9vbX0gPSBidWNrZXQuaWNvblNpemVEYXRhO1xuICAgICAgICBzaXplcy5jb21wb3NpdGVJY29uU2l6ZXMgPSBbXG4gICAgICAgICAgICB1bmV2YWx1YXRlZExheW91dFZhbHVlc1snaWNvbi1zaXplJ10ucG9zc2libHlFdmFsdWF0ZShuZXcgRXZhbHVhdGlvblBhcmFtZXRlcnMobWluWm9vbSksIGNhbm9uaWNhbCksXG4gICAgICAgICAgICB1bmV2YWx1YXRlZExheW91dFZhbHVlc1snaWNvbi1zaXplJ10ucG9zc2libHlFdmFsdWF0ZShuZXcgRXZhbHVhdGlvblBhcmFtZXRlcnMobWF4Wm9vbSksIGNhbm9uaWNhbClcbiAgICAgICAgXTtcbiAgICB9XG5cbiAgICBzaXplcy5sYXlvdXRUZXh0U2l6ZSA9IHVuZXZhbHVhdGVkTGF5b3V0VmFsdWVzWyd0ZXh0LXNpemUnXS5wb3NzaWJseUV2YWx1YXRlKG5ldyBFdmFsdWF0aW9uUGFyYW1ldGVycyh0aWxlWm9vbSArIDEpLCBjYW5vbmljYWwpO1xuICAgIHNpemVzLmxheW91dEljb25TaXplID0gdW5ldmFsdWF0ZWRMYXlvdXRWYWx1ZXNbJ2ljb24tc2l6ZSddLnBvc3NpYmx5RXZhbHVhdGUobmV3IEV2YWx1YXRpb25QYXJhbWV0ZXJzKHRpbGVab29tICsgMSksIGNhbm9uaWNhbCk7XG4gICAgc2l6ZXMudGV4dE1heFNpemUgPSB1bmV2YWx1YXRlZExheW91dFZhbHVlc1sndGV4dC1zaXplJ10ucG9zc2libHlFdmFsdWF0ZShuZXcgRXZhbHVhdGlvblBhcmFtZXRlcnMoMTgpLCBjYW5vbmljYWwpO1xuXG4gICAgY29uc3QgdGV4dEFsb25nTGluZSA9IGxheW91dC5nZXQoJ3RleHQtcm90YXRpb24tYWxpZ25tZW50JykgPT09ICdtYXAnICYmIGxheW91dC5nZXQoJ3N5bWJvbC1wbGFjZW1lbnQnKSAhPT0gJ3BvaW50JztcbiAgICBjb25zdCB0ZXh0U2l6ZSA9IGxheW91dC5nZXQoJ3RleHQtc2l6ZScpO1xuXG4gICAgZm9yIChjb25zdCBmZWF0dXJlIG9mIGJ1Y2tldC5mZWF0dXJlcykge1xuICAgICAgICBjb25zdCBmb250c3RhY2sgPSBsYXlvdXQuZ2V0KCd0ZXh0LWZvbnQnKS5ldmFsdWF0ZShmZWF0dXJlLCB7fSwgY2Fub25pY2FsKS5qb2luKCcsJyk7XG4gICAgICAgIGNvbnN0IGxheW91dFRleHRTaXplVGhpc1pvb20gPSB0ZXh0U2l6ZS5ldmFsdWF0ZShmZWF0dXJlLCB7fSwgY2Fub25pY2FsKTtcbiAgICAgICAgY29uc3QgbGF5b3V0VGV4dFNpemUgPSBzaXplcy5sYXlvdXRUZXh0U2l6ZS5ldmFsdWF0ZShmZWF0dXJlLCB7fSwgY2Fub25pY2FsKTtcbiAgICAgICAgY29uc3QgbGF5b3V0SWNvblNpemUgPSBzaXplcy5sYXlvdXRJY29uU2l6ZS5ldmFsdWF0ZShmZWF0dXJlLCB7fSwgY2Fub25pY2FsKTtcblxuICAgICAgICBjb25zdCBzaGFwZWRUZXh0T3JpZW50YXRpb25zID0ge1xuICAgICAgICAgICAgaG9yaXpvbnRhbDoge30sXG4gICAgICAgICAgICB2ZXJ0aWNhbDogdW5kZWZpbmVkXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHRleHQgPSBmZWF0dXJlLnRleHQ7XG4gICAgICAgIGxldCB0ZXh0T2Zmc2V0OiBbbnVtYmVyLCBudW1iZXJdID0gWzAsIDBdO1xuICAgICAgICBpZiAodGV4dCkge1xuICAgICAgICAgICAgY29uc3QgdW5mb3JtYXR0ZWRUZXh0ID0gdGV4dC50b1N0cmluZygpO1xuICAgICAgICAgICAgY29uc3Qgc3BhY2luZyA9IGxheW91dC5nZXQoJ3RleHQtbGV0dGVyLXNwYWNpbmcnKS5ldmFsdWF0ZShmZWF0dXJlLCB7fSwgY2Fub25pY2FsKSAqIE9ORV9FTTtcbiAgICAgICAgICAgIGNvbnN0IGxpbmVIZWlnaHQgPSBsYXlvdXQuZ2V0KCd0ZXh0LWxpbmUtaGVpZ2h0JykuZXZhbHVhdGUoZmVhdHVyZSwge30sIGNhbm9uaWNhbCkgKiBPTkVfRU07XG4gICAgICAgICAgICBjb25zdCBzcGFjaW5nSWZBbGxvd2VkID0gYWxsb3dzTGV0dGVyU3BhY2luZyh1bmZvcm1hdHRlZFRleHQpID8gc3BhY2luZyA6IDA7XG5cbiAgICAgICAgICAgIGNvbnN0IHRleHRBbmNob3IgPSBsYXlvdXQuZ2V0KCd0ZXh0LWFuY2hvcicpLmV2YWx1YXRlKGZlYXR1cmUsIHt9LCBjYW5vbmljYWwpO1xuICAgICAgICAgICAgY29uc3QgdmFyaWFibGVUZXh0QW5jaG9yID0gbGF5b3V0LmdldCgndGV4dC12YXJpYWJsZS1hbmNob3InKTtcblxuICAgICAgICAgICAgaWYgKCF2YXJpYWJsZVRleHRBbmNob3IpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByYWRpYWxPZmZzZXQgPSBsYXlvdXQuZ2V0KCd0ZXh0LXJhZGlhbC1vZmZzZXQnKS5ldmFsdWF0ZShmZWF0dXJlLCB7fSwgY2Fub25pY2FsKTtcbiAgICAgICAgICAgICAgICAvLyBMYXllcnMgd2l0aCB2YXJpYWJsZSBhbmNob3JzIHVzZSB0aGUgYHRleHQtcmFkaWFsLW9mZnNldGAgcHJvcGVydHkgYW5kIHRoZSBbeCwgeV0gb2Zmc2V0IHZlY3RvclxuICAgICAgICAgICAgICAgIC8vIGlzIGNhbGN1bGF0ZWQgYXQgcGxhY2VtZW50IHRpbWUgaW5zdGVhZCBvZiBsYXlvdXQgdGltZVxuICAgICAgICAgICAgICAgIGlmIChyYWRpYWxPZmZzZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIHN0eWxlIHNwZWMgc2F5cyBkb24ndCB1c2UgYHRleHQtb2Zmc2V0YCBhbmQgYHRleHQtcmFkaWFsLW9mZnNldGAgdG9nZXRoZXJcbiAgICAgICAgICAgICAgICAgICAgLy8gYnV0IGRvZXNuJ3QgYWN0dWFsbHkgc3BlY2lmeSB3aGF0IGhhcHBlbnMgaWYgeW91IHVzZSBib3RoLiBXZSBnbyB3aXRoIHRoZSByYWRpYWwgb2Zmc2V0LlxuICAgICAgICAgICAgICAgICAgICB0ZXh0T2Zmc2V0ID0gZXZhbHVhdGVWYXJpYWJsZU9mZnNldCh0ZXh0QW5jaG9yLCBbcmFkaWFsT2Zmc2V0ICogT05FX0VNLCBJTlZBTElEX1RFWFRfT0ZGU0VUXSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGV4dE9mZnNldCA9IChsYXlvdXQuZ2V0KCd0ZXh0LW9mZnNldCcpLmV2YWx1YXRlKGZlYXR1cmUsIHt9LCBjYW5vbmljYWwpLm1hcCh0ID0+IHQgKiBPTkVfRU0pOiBhbnkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IHRleHRKdXN0aWZ5ID0gdGV4dEFsb25nTGluZSA/XG4gICAgICAgICAgICAgICAgXCJjZW50ZXJcIiA6XG4gICAgICAgICAgICAgICAgbGF5b3V0LmdldCgndGV4dC1qdXN0aWZ5JykuZXZhbHVhdGUoZmVhdHVyZSwge30sIGNhbm9uaWNhbCk7XG5cbiAgICAgICAgICAgIGNvbnN0IGlzUG9pbnRQbGFjZW1lbnQgPSBsYXlvdXQuZ2V0KCdzeW1ib2wtcGxhY2VtZW50JykgPT09ICdwb2ludCc7XG4gICAgICAgICAgICBjb25zdCBtYXhXaWR0aCA9IGlzUG9pbnRQbGFjZW1lbnQgP1xuICAgICAgICAgICAgICAgIGxheW91dC5nZXQoJ3RleHQtbWF4LXdpZHRoJykuZXZhbHVhdGUoZmVhdHVyZSwge30sIGNhbm9uaWNhbCkgKiBPTkVfRU0gOlxuICAgICAgICAgICAgICAgIEluZmluaXR5O1xuXG4gICAgICAgICAgICBjb25zdCBhZGRWZXJ0aWNhbFNoYXBpbmdJZk5lZWRlZCA9ICh0ZXh0SnVzdGlmeTogVGV4dEp1c3RpZnkpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoYnVja2V0LmFsbG93VmVydGljYWxQbGFjZW1lbnQgJiYgYWxsb3dzVmVydGljYWxXcml0aW5nTW9kZSh1bmZvcm1hdHRlZFRleHQpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFZlcnRpY2FsIFBPSSBsYWJlbCBwbGFjZW1lbnQgaXMgbWVhbnQgdG8gYmUgdXNlZCBmb3Igc2NyaXB0cyB0aGF0IHN1cHBvcnQgdmVydGljYWxcbiAgICAgICAgICAgICAgICAgICAgLy8gd3JpdGluZyBtb2RlLCB0aHVzLCBkZWZhdWx0IGxlZnQganVzdGlmaWNhdGlvbiBpcyB1c2VkLiBJZiBMYXRpblxuICAgICAgICAgICAgICAgICAgICAvLyBzY3JpcHRzIHdvdWxkIG5lZWQgdG8gYmUgc3VwcG9ydGVkLCB0aGlzIHNob3VsZCB0YWtlIGludG8gYWNjb3VudCBvdGhlciBqdXN0aWZpY2F0aW9ucy5cbiAgICAgICAgICAgICAgICAgICAgc2hhcGVkVGV4dE9yaWVudGF0aW9ucy52ZXJ0aWNhbCA9IHNoYXBlVGV4dCh0ZXh0LCBnbHlwaE1hcCwgZ2x5cGhQb3NpdGlvbnMsIGltYWdlUG9zaXRpb25zLCBmb250c3RhY2ssIG1heFdpZHRoLCBsaW5lSGVpZ2h0LCB0ZXh0QW5jaG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHRKdXN0aWZ5LCBzcGFjaW5nSWZBbGxvd2VkLCB0ZXh0T2Zmc2V0LCBXcml0aW5nTW9kZS52ZXJ0aWNhbCwgdHJ1ZSwgbGF5b3V0VGV4dFNpemUsIGxheW91dFRleHRTaXplVGhpc1pvb20pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8vIElmIHRoaXMgbGF5ZXIgdXNlcyB0ZXh0LXZhcmlhYmxlLWFuY2hvciwgZ2VuZXJhdGUgc2hhcGluZ3MgZm9yIGFsbCBqdXN0aWZpY2F0aW9uIHBvc3NpYmlsaXRpZXMuXG4gICAgICAgICAgICBpZiAoIXRleHRBbG9uZ0xpbmUgJiYgdmFyaWFibGVUZXh0QW5jaG9yKSB7XG4gICAgICAgICAgICAgICAgY29uc3QganVzdGlmaWNhdGlvbnMgPSB0ZXh0SnVzdGlmeSA9PT0gXCJhdXRvXCIgP1xuICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZVRleHRBbmNob3IubWFwKGEgPT4gZ2V0QW5jaG9ySnVzdGlmaWNhdGlvbihhKSkgOlxuICAgICAgICAgICAgICAgICAgICBbdGV4dEp1c3RpZnldO1xuXG4gICAgICAgICAgICAgICAgbGV0IHNpbmdsZUxpbmUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGp1c3RpZmljYXRpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGp1c3RpZmljYXRpb246IFRleHRKdXN0aWZ5ID0ganVzdGlmaWNhdGlvbnNbaV07XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaGFwZWRUZXh0T3JpZW50YXRpb25zLmhvcml6b250YWxbanVzdGlmaWNhdGlvbl0pIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2luZ2xlTGluZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIHNoYXBpbmcgZm9yIHRoZSBmaXJzdCBqdXN0aWZpY2F0aW9uIHdhcyBvbmx5IGEgc2luZ2xlIGxpbmUsIHdlXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBjYW4gcmUtdXNlIGl0IGZvciB0aGUgb3RoZXIganVzdGlmaWNhdGlvbnNcbiAgICAgICAgICAgICAgICAgICAgICAgIHNoYXBlZFRleHRPcmllbnRhdGlvbnMuaG9yaXpvbnRhbFtqdXN0aWZpY2F0aW9uXSA9IHNoYXBlZFRleHRPcmllbnRhdGlvbnMuaG9yaXpvbnRhbFswXTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHVzaW5nIHRleHQtdmFyaWFibGUtYW5jaG9yIGZvciB0aGUgbGF5ZXIsIHdlIHVzZSBhIGNlbnRlciBhbmNob3IgZm9yIGFsbCBzaGFwaW5ncyBhbmQgYXBwbHlcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSBvZmZzZXRzIGZvciB0aGUgYW5jaG9yIGluIHRoZSBwbGFjZW1lbnQgc3RlcC5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNoYXBpbmcgPSBzaGFwZVRleHQodGV4dCwgZ2x5cGhNYXAsIGdseXBoUG9zaXRpb25zLCBpbWFnZVBvc2l0aW9ucywgZm9udHN0YWNrLCBtYXhXaWR0aCwgbGluZUhlaWdodCwgJ2NlbnRlcicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGp1c3RpZmljYXRpb24sIHNwYWNpbmdJZkFsbG93ZWQsIHRleHRPZmZzZXQsIFdyaXRpbmdNb2RlLmhvcml6b250YWwsIGZhbHNlLCBsYXlvdXRUZXh0U2l6ZSwgbGF5b3V0VGV4dFNpemVUaGlzWm9vbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2hhcGluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYXBlZFRleHRPcmllbnRhdGlvbnMuaG9yaXpvbnRhbFtqdXN0aWZpY2F0aW9uXSA9IHNoYXBpbmc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2luZ2xlTGluZSA9IHNoYXBpbmcucG9zaXRpb25lZExpbmVzLmxlbmd0aCA9PT0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGFkZFZlcnRpY2FsU2hhcGluZ0lmTmVlZGVkKCdsZWZ0Jyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICh0ZXh0SnVzdGlmeSA9PT0gXCJhdXRvXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGV4dEp1c3RpZnkgPSBnZXRBbmNob3JKdXN0aWZpY2F0aW9uKHRleHRBbmNob3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBBZGQgaG9yaXpvbnRhbCBzaGFwaW5nIGZvciBhbGwgcG9pbnQgbGFiZWxzIGFuZCBsaW5lIGxhYmVscyB0aGF0IG5lZWQgaG9yaXpvbnRhbCB3cml0aW5nIG1vZGUuXG4gICAgICAgICAgICAgICAgaWYgKGlzUG9pbnRQbGFjZW1lbnQgfHwgKChsYXlvdXQuZ2V0KFwidGV4dC13cml0aW5nLW1vZGVcIikuaW5kZXhPZignaG9yaXpvbnRhbCcpID49IDApIHx8ICFhbGxvd3NWZXJ0aWNhbFdyaXRpbmdNb2RlKHVuZm9ybWF0dGVkVGV4dCkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNoYXBpbmcgPSBzaGFwZVRleHQodGV4dCwgZ2x5cGhNYXAsIGdseXBoUG9zaXRpb25zLCBpbWFnZVBvc2l0aW9ucywgZm9udHN0YWNrLCBtYXhXaWR0aCwgbGluZUhlaWdodCwgdGV4dEFuY2hvciwgdGV4dEp1c3RpZnksIHNwYWNpbmdJZkFsbG93ZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHRPZmZzZXQsIFdyaXRpbmdNb2RlLmhvcml6b250YWwsIGZhbHNlLCBsYXlvdXRUZXh0U2l6ZSwgbGF5b3V0VGV4dFNpemVUaGlzWm9vbSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaGFwaW5nKSBzaGFwZWRUZXh0T3JpZW50YXRpb25zLmhvcml6b250YWxbdGV4dEp1c3RpZnldID0gc2hhcGluZztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBWZXJ0aWNhbCBwb2ludCBsYWJlbCAoaWYgYWxsb3dWZXJ0aWNhbFBsYWNlbWVudCBpcyBlbmFibGVkKS5cbiAgICAgICAgICAgICAgICBhZGRWZXJ0aWNhbFNoYXBpbmdJZk5lZWRlZChpc1BvaW50UGxhY2VtZW50ID8gJ2xlZnQnIDogdGV4dEp1c3RpZnkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHNoYXBlZEljb247XG4gICAgICAgIGxldCBpc1NERkljb24gPSBmYWxzZTtcbiAgICAgICAgaWYgKGZlYXR1cmUuaWNvbiAmJiBmZWF0dXJlLmljb24ubmFtZSkge1xuICAgICAgICAgICAgY29uc3QgaW1hZ2UgPSBpbWFnZU1hcFtmZWF0dXJlLmljb24ubmFtZV07XG4gICAgICAgICAgICBpZiAoaW1hZ2UpIHtcbiAgICAgICAgICAgICAgICBzaGFwZWRJY29uID0gc2hhcGVJY29uKFxuICAgICAgICAgICAgICAgICAgICBpbWFnZVBvc2l0aW9uc1tmZWF0dXJlLmljb24ubmFtZV0sXG4gICAgICAgICAgICAgICAgICAgIGxheW91dC5nZXQoJ2ljb24tb2Zmc2V0JykuZXZhbHVhdGUoZmVhdHVyZSwge30sIGNhbm9uaWNhbCksXG4gICAgICAgICAgICAgICAgICAgIGxheW91dC5nZXQoJ2ljb24tYW5jaG9yJykuZXZhbHVhdGUoZmVhdHVyZSwge30sIGNhbm9uaWNhbCkpO1xuICAgICAgICAgICAgICAgIGlzU0RGSWNvbiA9IGltYWdlLnNkZjtcbiAgICAgICAgICAgICAgICBpZiAoYnVja2V0LnNkZkljb25zID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgYnVja2V0LnNkZkljb25zID0gaW1hZ2Uuc2RmO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYnVja2V0LnNkZkljb25zICE9PSBpbWFnZS5zZGYpIHtcbiAgICAgICAgICAgICAgICAgICAgd2Fybk9uY2UoJ1N0eWxlIHNoZWV0IHdhcm5pbmc6IENhbm5vdCBtaXggU0RGIGFuZCBub24tU0RGIGljb25zIGluIG9uZSBidWZmZXInKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGltYWdlLnBpeGVsUmF0aW8gIT09IGJ1Y2tldC5waXhlbFJhdGlvKSB7XG4gICAgICAgICAgICAgICAgICAgIGJ1Y2tldC5pY29uc05lZWRMaW5lYXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobGF5b3V0LmdldCgnaWNvbi1yb3RhdGUnKS5jb25zdGFudE9yKDEpICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGJ1Y2tldC5pY29uc05lZWRMaW5lYXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNoYXBlZFRleHQgPSBnZXREZWZhdWx0SG9yaXpvbnRhbFNoYXBpbmcoc2hhcGVkVGV4dE9yaWVudGF0aW9ucy5ob3Jpem9udGFsKSB8fCBzaGFwZWRUZXh0T3JpZW50YXRpb25zLnZlcnRpY2FsO1xuICAgICAgICBpZiAoIWJ1Y2tldC5pY29uc0luVGV4dCkge1xuICAgICAgICAgICAgYnVja2V0Lmljb25zSW5UZXh0ID0gc2hhcGVkVGV4dCA/IHNoYXBlZFRleHQuaWNvbnNJblRleHQgOiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2hhcGVkVGV4dCB8fCBzaGFwZWRJY29uKSB7XG4gICAgICAgICAgICBhZGRGZWF0dXJlKGJ1Y2tldCwgZmVhdHVyZSwgc2hhcGVkVGV4dE9yaWVudGF0aW9ucywgc2hhcGVkSWNvbiwgaW1hZ2VNYXAsIHNpemVzLCBsYXlvdXRUZXh0U2l6ZSwgbGF5b3V0SWNvblNpemUsIHRleHRPZmZzZXQsIGlzU0RGSWNvbiwgYXZhaWxhYmxlSW1hZ2VzLCBjYW5vbmljYWwsIHByb2plY3Rpb24pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNob3dDb2xsaXNpb25Cb3hlcykge1xuICAgICAgICBidWNrZXQuZ2VuZXJhdGVDb2xsaXNpb25EZWJ1Z0J1ZmZlcnModGlsZVpvb20sIGJ1Y2tldC5jb2xsaXNpb25Cb3hBcnJheSk7XG4gICAgfVxufVxuXG4vLyBDaG9vc2UgdGhlIGp1c3RpZmljYXRpb24gdGhhdCBtYXRjaGVzIHRoZSBkaXJlY3Rpb24gb2YgdGhlIFRleHRBbmNob3JcbmV4cG9ydCBmdW5jdGlvbiBnZXRBbmNob3JKdXN0aWZpY2F0aW9uKGFuY2hvcjogVGV4dEFuY2hvcik6IFRleHRKdXN0aWZ5ICB7XG4gICAgc3dpdGNoIChhbmNob3IpIHtcbiAgICBjYXNlICdyaWdodCc6XG4gICAgY2FzZSAndG9wLXJpZ2h0JzpcbiAgICBjYXNlICdib3R0b20tcmlnaHQnOlxuICAgICAgICByZXR1cm4gJ3JpZ2h0JztcbiAgICBjYXNlICdsZWZ0JzpcbiAgICBjYXNlICd0b3AtbGVmdCc6XG4gICAgY2FzZSAnYm90dG9tLWxlZnQnOlxuICAgICAgICByZXR1cm4gJ2xlZnQnO1xuICAgIH1cbiAgICByZXR1cm4gJ2NlbnRlcic7XG59XG5cbi8qKlxuICogZm9yIFwidmVyeVwiIG92ZXJzY2FsZWQgdGlsZXMgKG92ZXJzY2FsZUZhY3RvciA+IDIpIG9uIGhpZ2ggem9vbSBsZXZlbHMgKHogPiAxOClcbiAqIHdlIHVzZSB0aGUgdGlsZSBwaXhlbCByYXRpbyBmcm9tIHRoZSBwcmV2aW91cyB6b29tIGxldmVsIGFuZCBjbGFtcCBpdCB0byAxXG4gKiBpbiBvcmRlciB0byB0aGluIG91dCBsYWJlbHMgZGVuc2l0eSBhbmQgc2F2ZSBtZW1vcnkgYW5kIENQVSAuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiB0aWxlUGl4ZWxSYXRpb0ZvclN5bWJvbFNwYWNpbmcob3ZlcnNjYWxlRmFjdG9yOiBudW1iZXIsIG92ZXJzY2FsZWRaOiBudW1iZXIpIHtcbiAgICBpZiAob3ZlcnNjYWxlZFogPiAxOCAmJiBvdmVyc2NhbGVGYWN0b3IgPiAyKSB7XG4gICAgICAgIG92ZXJzY2FsZUZhY3RvciA+Pj0gMTtcbiAgICB9XG4gICAgY29uc3QgdGlsZVBpeGVsUmF0aW8gPSBFWFRFTlQgLyAoNTEyICogb3ZlcnNjYWxlRmFjdG9yKTtcbiAgICByZXR1cm4gTWF0aC5tYXgodGlsZVBpeGVsUmF0aW8sIDEpO1xufVxuXG4vKipcbiAqIEdpdmVuIGEgZmVhdHVyZSBhbmQgaXRzIHNoYXBlZCB0ZXh0IGFuZCBpY29uIGRhdGEsIGFkZCBhICdzeW1ib2xcbiAqIGluc3RhbmNlJyBmb3IgZWFjaCBfcG9zc2libGVfIHBsYWNlbWVudCBvZiB0aGUgc3ltYm9sIGZlYXR1cmUuXG4gKiAoQXQgcmVuZGVyIHRpbWUgUGxhY2VtZW50LnVwZGF0ZUJ1Y2tldE9wYWNpdGllcygpIHNlbGVjdHMgd2hpY2ggb2YgdGhlc2VcbiAqIGluc3RhbmNlcyB0byBzaG93IG9yIGhpZGUgYmFzZWQgb24gY29sbGlzaW9ucyB3aXRoIHN5bWJvbHMgaW4gb3RoZXIgbGF5ZXJzLilcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGFkZEZlYXR1cmUoYnVja2V0OiBTeW1ib2xCdWNrZXQsXG4gICAgICAgICAgICAgICAgICAgIGZlYXR1cmU6IFN5bWJvbEZlYXR1cmUsXG4gICAgICAgICAgICAgICAgICAgIHNoYXBlZFRleHRPcmllbnRhdGlvbnM6IGFueSxcbiAgICAgICAgICAgICAgICAgICAgc2hhcGVkSWNvbjogUG9zaXRpb25lZEljb24gfCB2b2lkLFxuICAgICAgICAgICAgICAgICAgICBpbWFnZU1hcDoge1tfOiBzdHJpbmddOiBTdHlsZUltYWdlfSxcbiAgICAgICAgICAgICAgICAgICAgc2l6ZXM6IFNpemVzLFxuICAgICAgICAgICAgICAgICAgICBsYXlvdXRUZXh0U2l6ZTogbnVtYmVyLFxuICAgICAgICAgICAgICAgICAgICBsYXlvdXRJY29uU2l6ZTogbnVtYmVyLFxuICAgICAgICAgICAgICAgICAgICB0ZXh0T2Zmc2V0OiBbbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICAgICAgICAgICAgICBpc1NERkljb246IGJvb2xlYW4sXG4gICAgICAgICAgICAgICAgICAgIGF2YWlsYWJsZUltYWdlczogQXJyYXk8c3RyaW5nPixcbiAgICAgICAgICAgICAgICAgICAgY2Fub25pY2FsOiBDYW5vbmljYWxUaWxlSUQsXG4gICAgICAgICAgICAgICAgICAgIHByb2plY3Rpb246IFByb2plY3Rpb24pIHtcbiAgICAvLyBUbyByZWR1Y2UgdGhlIG51bWJlciBvZiBsYWJlbHMgdGhhdCBqdW1wIGFyb3VuZCB3aGVuIHpvb21pbmcgd2UgbmVlZFxuICAgIC8vIHRvIHVzZSBhIHRleHQtc2l6ZSB2YWx1ZSB0aGF0IGlzIHRoZSBzYW1lIGZvciBhbGwgem9vbSBsZXZlbHMuXG4gICAgLy8gYnVja2V0IGNhbGN1bGF0ZXMgdGV4dC1zaXplIGF0IGEgaGlnaCB6b29tIGxldmVsIHNvIHRoYXQgYWxsIHRpbGVzIGNhblxuICAgIC8vIHVzZSB0aGUgc2FtZSB2YWx1ZSB3aGVuIGNhbGN1bGF0aW5nIGFuY2hvciBwb3NpdGlvbnMuXG4gICAgbGV0IHRleHRNYXhTaXplID0gc2l6ZXMudGV4dE1heFNpemUuZXZhbHVhdGUoZmVhdHVyZSwge30sIGNhbm9uaWNhbCk7XG4gICAgaWYgKHRleHRNYXhTaXplID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGV4dE1heFNpemUgPSBsYXlvdXRUZXh0U2l6ZTtcbiAgICB9XG4gICAgY29uc3QgbGF5b3V0ID0gYnVja2V0LmxheWVyc1swXS5sYXlvdXQ7XG4gICAgY29uc3QgaWNvbk9mZnNldCA9IGxheW91dC5nZXQoJ2ljb24tb2Zmc2V0JykuZXZhbHVhdGUoZmVhdHVyZSwge30sIGNhbm9uaWNhbCk7XG4gICAgY29uc3QgZGVmYXVsdFNoYXBpbmcgPSBnZXREZWZhdWx0SG9yaXpvbnRhbFNoYXBpbmcoc2hhcGVkVGV4dE9yaWVudGF0aW9ucy5ob3Jpem9udGFsKSB8fCBzaGFwZWRUZXh0T3JpZW50YXRpb25zLnZlcnRpY2FsO1xuICAgIGNvbnN0IGlzR2xvYmUgPSBwcm9qZWN0aW9uLm5hbWUgPT09ICdnbG9iZSc7XG5cbiAgICBjb25zdCBnbHlwaFNpemUgPSBPTkVfRU0sXG4gICAgICAgIGZvbnRTY2FsZSA9IGxheW91dFRleHRTaXplIC8gZ2x5cGhTaXplLFxuICAgICAgICB0ZXh0TWF4Qm94U2NhbGUgPSBidWNrZXQudGlsZVBpeGVsUmF0aW8gKiB0ZXh0TWF4U2l6ZSAvIGdseXBoU2l6ZSxcbiAgICAgICAgaWNvbkJveFNjYWxlID0gYnVja2V0LnRpbGVQaXhlbFJhdGlvICogbGF5b3V0SWNvblNpemUsXG4gICAgICAgIHN5bWJvbE1pbkRpc3RhbmNlID0gdGlsZVBpeGVsUmF0aW9Gb3JTeW1ib2xTcGFjaW5nKGJ1Y2tldC5vdmVyc2NhbGluZywgYnVja2V0Lnpvb20pICogbGF5b3V0LmdldCgnc3ltYm9sLXNwYWNpbmcnKSxcbiAgICAgICAgdGV4dFBhZGRpbmcgPSBsYXlvdXQuZ2V0KCd0ZXh0LXBhZGRpbmcnKSAqIGJ1Y2tldC50aWxlUGl4ZWxSYXRpbyxcbiAgICAgICAgaWNvblBhZGRpbmcgPSBsYXlvdXQuZ2V0KCdpY29uLXBhZGRpbmcnKSAqIGJ1Y2tldC50aWxlUGl4ZWxSYXRpbyxcbiAgICAgICAgdGV4dE1heEFuZ2xlID0gZGVnVG9SYWQobGF5b3V0LmdldCgndGV4dC1tYXgtYW5nbGUnKSksXG4gICAgICAgIHRleHRBbG9uZ0xpbmUgPSBsYXlvdXQuZ2V0KCd0ZXh0LXJvdGF0aW9uLWFsaWdubWVudCcpID09PSAnbWFwJyAmJiBsYXlvdXQuZ2V0KCdzeW1ib2wtcGxhY2VtZW50JykgIT09ICdwb2ludCcsXG4gICAgICAgIGljb25BbG9uZ0xpbmUgPSBsYXlvdXQuZ2V0KCdpY29uLXJvdGF0aW9uLWFsaWdubWVudCcpID09PSAnbWFwJyAmJiBsYXlvdXQuZ2V0KCdzeW1ib2wtcGxhY2VtZW50JykgIT09ICdwb2ludCcsXG4gICAgICAgIHN5bWJvbFBsYWNlbWVudCA9IGxheW91dC5nZXQoJ3N5bWJvbC1wbGFjZW1lbnQnKSxcbiAgICAgICAgdGV4dFJlcGVhdERpc3RhbmNlID0gc3ltYm9sTWluRGlzdGFuY2UgLyAyO1xuXG4gICAgY29uc3QgaWNvblRleHRGaXQgPSBsYXlvdXQuZ2V0KCdpY29uLXRleHQtZml0Jyk7XG4gICAgbGV0IHZlcnRpY2FsbHlTaGFwZWRJY29uO1xuXG4gICAgLy8gQWRqdXN0IHNoYXBlZCBpY29uIHNpemUgd2hlbiBpY29uLXRleHQtZml0IGlzIHVzZWQuXG4gICAgaWYgKHNoYXBlZEljb24gJiYgaWNvblRleHRGaXQgIT09ICdub25lJykge1xuICAgICAgICBpZiAoYnVja2V0LmFsbG93VmVydGljYWxQbGFjZW1lbnQgJiYgc2hhcGVkVGV4dE9yaWVudGF0aW9ucy52ZXJ0aWNhbCkge1xuICAgICAgICAgICAgdmVydGljYWxseVNoYXBlZEljb24gPSBmaXRJY29uVG9UZXh0KHNoYXBlZEljb24sIHNoYXBlZFRleHRPcmllbnRhdGlvbnMudmVydGljYWwsIGljb25UZXh0Rml0LFxuICAgICAgICAgICAgICAgIGxheW91dC5nZXQoJ2ljb24tdGV4dC1maXQtcGFkZGluZycpLCBpY29uT2Zmc2V0LCBmb250U2NhbGUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkZWZhdWx0U2hhcGluZykge1xuICAgICAgICAgICAgc2hhcGVkSWNvbiA9IGZpdEljb25Ub1RleHQoc2hhcGVkSWNvbiwgZGVmYXVsdFNoYXBpbmcsIGljb25UZXh0Rml0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF5b3V0LmdldCgnaWNvbi10ZXh0LWZpdC1wYWRkaW5nJyksIGljb25PZmZzZXQsIGZvbnRTY2FsZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBhZGRTeW1ib2xBdEFuY2hvciA9IChsaW5lOiBBcnJheTxQb2ludD4sIGFuY2hvcjogQW5jaG9yLCBjYW5vbmljYWxJZDogQ2Fub25pY2FsVGlsZUlEKSA9PiB7XG4gICAgICAgIGlmIChhbmNob3IueCA8IDAgfHwgYW5jaG9yLnggPj0gRVhURU5UIHx8IGFuY2hvci55IDwgMCB8fCBhbmNob3IueSA+PSBFWFRFTlQpIHtcbiAgICAgICAgICAgIC8vIFN5bWJvbCBsYXllcnMgYXJlIGRyYXduIGFjcm9zcyB0aWxlIGJvdW5kYXJpZXMsIFdlIGZpbHRlciBvdXQgc3ltYm9sc1xuICAgICAgICAgICAgLy8gb3V0c2lkZSBvdXIgdGlsZSBib3VuZGFyaWVzICh3aGljaCBtYXkgYmUgaW5jbHVkZWQgaW4gdmVjdG9yIHRpbGUgYnVmZmVycylcbiAgICAgICAgICAgIC8vIHRvIHByZXZlbnQgZG91YmxlLWRyYXdpbmcgc3ltYm9scy5cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBnbG9iZTogP3thbmNob3I6IEFuY2hvciwgdXA6IFZlYzN9ID0gbnVsbDtcbiAgICAgICAgaWYgKGlzR2xvYmUpIHtcbiAgICAgICAgICAgIGNvbnN0IHt4LCB5LCB6fSA9IHByb2plY3Rpb24ucHJvamVjdFRpbGVQb2ludChhbmNob3IueCwgYW5jaG9yLnksIGNhbm9uaWNhbElkKTtcbiAgICAgICAgICAgIGdsb2JlID0ge1xuICAgICAgICAgICAgICAgIGFuY2hvcjogbmV3IEFuY2hvcih4LCB5LCB6LCAwLCB1bmRlZmluZWQpLFxuICAgICAgICAgICAgICAgIHVwOiBwcm9qZWN0aW9uLnVwVmVjdG9yKGNhbm9uaWNhbElkLCBhbmNob3IueCwgYW5jaG9yLnkpXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgYWRkU3ltYm9sKGJ1Y2tldCwgYW5jaG9yLCBnbG9iZSwgbGluZSwgc2hhcGVkVGV4dE9yaWVudGF0aW9ucywgc2hhcGVkSWNvbiwgaW1hZ2VNYXAsIHZlcnRpY2FsbHlTaGFwZWRJY29uLCBidWNrZXQubGF5ZXJzWzBdLFxuICAgICAgICAgICAgYnVja2V0LmNvbGxpc2lvbkJveEFycmF5LCBmZWF0dXJlLmluZGV4LCBmZWF0dXJlLnNvdXJjZUxheWVySW5kZXgsXG4gICAgICAgICAgICBidWNrZXQuaW5kZXgsIHRleHRQYWRkaW5nLCB0ZXh0QWxvbmdMaW5lLCB0ZXh0T2Zmc2V0LFxuICAgICAgICAgICAgaWNvbkJveFNjYWxlLCBpY29uUGFkZGluZywgaWNvbkFsb25nTGluZSwgaWNvbk9mZnNldCxcbiAgICAgICAgICAgIGZlYXR1cmUsIHNpemVzLCBpc1NERkljb24sIGF2YWlsYWJsZUltYWdlcywgY2Fub25pY2FsKTtcbiAgICB9O1xuXG4gICAgaWYgKHN5bWJvbFBsYWNlbWVudCA9PT0gJ2xpbmUnKSB7XG4gICAgICAgIGZvciAoY29uc3QgbGluZSBvZiBjbGlwTGluZShmZWF0dXJlLmdlb21ldHJ5LCAwLCAwLCBFWFRFTlQsIEVYVEVOVCkpIHtcbiAgICAgICAgICAgIGNvbnN0IGFuY2hvcnMgPSBnZXRBbmNob3JzKFxuICAgICAgICAgICAgICAgIGxpbmUsXG4gICAgICAgICAgICAgICAgc3ltYm9sTWluRGlzdGFuY2UsXG4gICAgICAgICAgICAgICAgdGV4dE1heEFuZ2xlLFxuICAgICAgICAgICAgICAgIHNoYXBlZFRleHRPcmllbnRhdGlvbnMudmVydGljYWwgfHwgZGVmYXVsdFNoYXBpbmcsXG4gICAgICAgICAgICAgICAgc2hhcGVkSWNvbixcbiAgICAgICAgICAgICAgICBnbHlwaFNpemUsXG4gICAgICAgICAgICAgICAgdGV4dE1heEJveFNjYWxlLFxuICAgICAgICAgICAgICAgIGJ1Y2tldC5vdmVyc2NhbGluZyxcbiAgICAgICAgICAgICAgICBFWFRFTlRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGFuY2hvciBvZiBhbmNob3JzKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2hhcGVkVGV4dCA9IGRlZmF1bHRTaGFwaW5nO1xuICAgICAgICAgICAgICAgIGlmICghc2hhcGVkVGV4dCB8fCAhYW5jaG9ySXNUb29DbG9zZShidWNrZXQsIHNoYXBlZFRleHQudGV4dCwgdGV4dFJlcGVhdERpc3RhbmNlLCBhbmNob3IpKSB7XG4gICAgICAgICAgICAgICAgICAgIGFkZFN5bWJvbEF0QW5jaG9yKGxpbmUsIGFuY2hvciwgY2Fub25pY2FsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHN5bWJvbFBsYWNlbWVudCA9PT0gJ2xpbmUtY2VudGVyJykge1xuICAgICAgICAvLyBObyBjbGlwcGluZywgbXVsdGlwbGUgbGluZXMgcGVyIGZlYXR1cmUgYXJlIGFsbG93ZWRcbiAgICAgICAgLy8gXCJsaW5lc1wiIHdpdGggb25seSBvbmUgcG9pbnQgYXJlIGlnbm9yZWQgYXMgaW4gY2xpcExpbmVzXG4gICAgICAgIGZvciAoY29uc3QgbGluZSBvZiBmZWF0dXJlLmdlb21ldHJ5KSB7XG4gICAgICAgICAgICBpZiAobGluZS5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgYW5jaG9yID0gZ2V0Q2VudGVyQW5jaG9yKFxuICAgICAgICAgICAgICAgICAgICBsaW5lLFxuICAgICAgICAgICAgICAgICAgICB0ZXh0TWF4QW5nbGUsXG4gICAgICAgICAgICAgICAgICAgIHNoYXBlZFRleHRPcmllbnRhdGlvbnMudmVydGljYWwgfHwgZGVmYXVsdFNoYXBpbmcsXG4gICAgICAgICAgICAgICAgICAgIHNoYXBlZEljb24sXG4gICAgICAgICAgICAgICAgICAgIGdseXBoU2l6ZSxcbiAgICAgICAgICAgICAgICAgICAgdGV4dE1heEJveFNjYWxlKTtcbiAgICAgICAgICAgICAgICBpZiAoYW5jaG9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGFkZFN5bWJvbEF0QW5jaG9yKGxpbmUsIGFuY2hvciwgY2Fub25pY2FsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGZlYXR1cmUudHlwZSA9PT0gJ1BvbHlnb24nKSB7XG4gICAgICAgIGZvciAoY29uc3QgcG9seWdvbiBvZiBjbGFzc2lmeVJpbmdzKGZlYXR1cmUuZ2VvbWV0cnksIDApKSB7XG4gICAgICAgICAgICAvLyAxNiBoZXJlIHJlcHJlc2VudHMgMiBwaXhlbHNcbiAgICAgICAgICAgIGNvbnN0IHBvaSA9IGZpbmRQb2xlT2ZJbmFjY2Vzc2liaWxpdHkocG9seWdvbiwgMTYpO1xuICAgICAgICAgICAgYWRkU3ltYm9sQXRBbmNob3IocG9seWdvblswXSwgbmV3IEFuY2hvcihwb2kueCwgcG9pLnksIDAsIDAsIHVuZGVmaW5lZCksIGNhbm9uaWNhbCk7XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGZlYXR1cmUudHlwZSA9PT0gJ0xpbmVTdHJpbmcnKSB7XG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXBib3gvbWFwYm94LWdsLWpzL2lzc3Vlcy8zODA4XG4gICAgICAgIGZvciAoY29uc3QgbGluZSBvZiBmZWF0dXJlLmdlb21ldHJ5KSB7XG4gICAgICAgICAgICBhZGRTeW1ib2xBdEFuY2hvcihsaW5lLCBuZXcgQW5jaG9yKGxpbmVbMF0ueCwgbGluZVswXS55LCAwLCAwLCB1bmRlZmluZWQpLCBjYW5vbmljYWwpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIGlmIChmZWF0dXJlLnR5cGUgPT09ICdQb2ludCcpIHtcbiAgICAgICAgZm9yIChjb25zdCBwb2ludHMgb2YgZmVhdHVyZS5nZW9tZXRyeSkge1xuICAgICAgICAgICAgZm9yIChjb25zdCBwb2ludCBvZiBwb2ludHMpIHtcbiAgICAgICAgICAgICAgICBhZGRTeW1ib2xBdEFuY2hvcihbcG9pbnRdLCBuZXcgQW5jaG9yKHBvaW50LngsIHBvaW50LnksIDAsIDAsIHVuZGVmaW5lZCksIGNhbm9uaWNhbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNvbnN0IE1BWF9HTFlQSF9JQ09OX1NJWkUgPSAyNTU7XG5jb25zdCBNQVhfUEFDS0VEX1NJWkUgPSBNQVhfR0xZUEhfSUNPTl9TSVpFICogU0laRV9QQUNLX0ZBQ1RPUjtcbmV4cG9ydCB7TUFYX1BBQ0tFRF9TSVpFfTtcblxuZnVuY3Rpb24gYWRkVGV4dFZlcnRpY2VzKGJ1Y2tldDogU3ltYm9sQnVja2V0LFxuICAgICAgICAgICAgICAgICAgICAgICAgIGdsb2JlOiA/eyBhbmNob3I6IEFuY2hvciwgdXA6IFZlYzMgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICB0aWxlQW5jaG9yOiBBbmNob3IsXG4gICAgICAgICAgICAgICAgICAgICAgICAgc2hhcGVkVGV4dDogU2hhcGluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgICBpbWFnZU1hcDoge1tfOiBzdHJpbmddOiBTdHlsZUltYWdlfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICBsYXllcjogU3ltYm9sU3R5bGVMYXllcixcbiAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0QWxvbmdMaW5lOiBib29sZWFuLFxuICAgICAgICAgICAgICAgICAgICAgICAgIGZlYXR1cmU6IFN5bWJvbEZlYXR1cmUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgdGV4dE9mZnNldDogW251bWJlciwgbnVtYmVyXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lQXJyYXk6IHtsaW5lU3RhcnRJbmRleDogbnVtYmVyLCBsaW5lTGVuZ3RoOiBudW1iZXJ9LFxuICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRpbmdNb2RlOiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2VtZW50VHlwZXM6IEFycmF5PCd2ZXJ0aWNhbCcgfCAnY2VudGVyJyB8ICdsZWZ0JyB8ICdyaWdodCc+LFxuICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlZFRleHRTeW1ib2xJbmRpY2VzOiB7W186IHN0cmluZ106IG51bWJlcn0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2VkSWNvbkluZGV4OiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZXM6IFNpemVzLFxuICAgICAgICAgICAgICAgICAgICAgICAgIGF2YWlsYWJsZUltYWdlczogQXJyYXk8c3RyaW5nPixcbiAgICAgICAgICAgICAgICAgICAgICAgICBjYW5vbmljYWw6IENhbm9uaWNhbFRpbGVJRCkge1xuICAgIGNvbnN0IGdseXBoUXVhZHMgPSBnZXRHbHlwaFF1YWRzKHRpbGVBbmNob3IsIHNoYXBlZFRleHQsIHRleHRPZmZzZXQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF5ZXIsIHRleHRBbG9uZ0xpbmUsIGZlYXR1cmUsIGltYWdlTWFwLCBidWNrZXQuYWxsb3dWZXJ0aWNhbFBsYWNlbWVudCk7XG5cbiAgICBjb25zdCBzaXplRGF0YSA9IGJ1Y2tldC50ZXh0U2l6ZURhdGE7XG4gICAgbGV0IHRleHRTaXplRGF0YSA9IG51bGw7XG5cbiAgICBpZiAoc2l6ZURhdGEua2luZCA9PT0gJ3NvdXJjZScpIHtcbiAgICAgICAgdGV4dFNpemVEYXRhID0gW1xuICAgICAgICAgICAgU0laRV9QQUNLX0ZBQ1RPUiAqIGxheWVyLmxheW91dC5nZXQoJ3RleHQtc2l6ZScpLmV2YWx1YXRlKGZlYXR1cmUsIHt9LCBjYW5vbmljYWwpXG4gICAgICAgIF07XG4gICAgICAgIGlmICh0ZXh0U2l6ZURhdGFbMF0gPiBNQVhfUEFDS0VEX1NJWkUpIHtcbiAgICAgICAgICAgIHdhcm5PbmNlKGAke2J1Y2tldC5sYXllcklkc1swXX06IFZhbHVlIGZvciBcInRleHQtc2l6ZVwiIGlzID49ICR7TUFYX0dMWVBIX0lDT05fU0laRX0uIFJlZHVjZSB5b3VyIFwidGV4dC1zaXplXCIuYCk7XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHNpemVEYXRhLmtpbmQgPT09ICdjb21wb3NpdGUnKSB7XG4gICAgICAgIHRleHRTaXplRGF0YSA9IFtcbiAgICAgICAgICAgIFNJWkVfUEFDS19GQUNUT1IgKiBzaXplcy5jb21wb3NpdGVUZXh0U2l6ZXNbMF0uZXZhbHVhdGUoZmVhdHVyZSwge30sIGNhbm9uaWNhbCksXG4gICAgICAgICAgICBTSVpFX1BBQ0tfRkFDVE9SICogc2l6ZXMuY29tcG9zaXRlVGV4dFNpemVzWzFdLmV2YWx1YXRlKGZlYXR1cmUsIHt9LCBjYW5vbmljYWwpXG4gICAgICAgIF07XG4gICAgICAgIGlmICh0ZXh0U2l6ZURhdGFbMF0gPiBNQVhfUEFDS0VEX1NJWkUgfHwgdGV4dFNpemVEYXRhWzFdID4gTUFYX1BBQ0tFRF9TSVpFKSB7XG4gICAgICAgICAgICB3YXJuT25jZShgJHtidWNrZXQubGF5ZXJJZHNbMF19OiBWYWx1ZSBmb3IgXCJ0ZXh0LXNpemVcIiBpcyA+PSAke01BWF9HTFlQSF9JQ09OX1NJWkV9LiBSZWR1Y2UgeW91ciBcInRleHQtc2l6ZVwiLmApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYnVja2V0LmFkZFN5bWJvbHMoXG4gICAgICAgIGJ1Y2tldC50ZXh0LFxuICAgICAgICBnbHlwaFF1YWRzLFxuICAgICAgICB0ZXh0U2l6ZURhdGEsXG4gICAgICAgIHRleHRPZmZzZXQsXG4gICAgICAgIHRleHRBbG9uZ0xpbmUsXG4gICAgICAgIGZlYXR1cmUsXG4gICAgICAgIHdyaXRpbmdNb2RlLFxuICAgICAgICBnbG9iZSxcbiAgICAgICAgdGlsZUFuY2hvcixcbiAgICAgICAgbGluZUFycmF5LmxpbmVTdGFydEluZGV4LFxuICAgICAgICBsaW5lQXJyYXkubGluZUxlbmd0aCxcbiAgICAgICAgcGxhY2VkSWNvbkluZGV4LFxuICAgICAgICBhdmFpbGFibGVJbWFnZXMsXG4gICAgICAgIGNhbm9uaWNhbCk7XG5cbiAgICAvLyBUaGUgcGxhY2VkU3ltYm9sQXJyYXkgaXMgdXNlZCBhdCByZW5kZXIgdGltZSBpbiBkcmF3VGlsZVN5bWJvbHNcbiAgICAvLyBUaGVzZSBpbmRpY2VzIGFsbG93IGFjY2VzcyB0byB0aGUgYXJyYXkgYXQgY29sbGlzaW9uIGRldGVjdGlvbiB0aW1lXG4gICAgZm9yIChjb25zdCBwbGFjZW1lbnRUeXBlIG9mIHBsYWNlbWVudFR5cGVzKSB7XG4gICAgICAgIHBsYWNlZFRleHRTeW1ib2xJbmRpY2VzW3BsYWNlbWVudFR5cGVdID0gYnVja2V0LnRleHQucGxhY2VkU3ltYm9sQXJyYXkubGVuZ3RoIC0gMTtcbiAgICB9XG5cbiAgICByZXR1cm4gZ2x5cGhRdWFkcy5sZW5ndGggKiA0O1xufVxuXG5mdW5jdGlvbiBnZXREZWZhdWx0SG9yaXpvbnRhbFNoYXBpbmcoaG9yaXpvbnRhbFNoYXBpbmc6IHtbXzogVGV4dEp1c3RpZnldOiBTaGFwaW5nfSk6IFNoYXBpbmcgfCBudWxsIHtcbiAgICAvLyBXZSBkb24ndCBjYXJlIHdoaWNoIHNoYXBpbmcgd2UgZ2V0IGJlY2F1c2UgdGhpcyBpcyB1c2VkIGZvciBjb2xsaXNpb24gcHVycG9zZXNcbiAgICAvLyBhbmQgYWxsIHRoZSBqdXN0aWZpY2F0aW9ucyBoYXZlIHRoZSBzYW1lIGNvbGxpc2lvbiBib3hcbiAgICBmb3IgKGNvbnN0IGp1c3RpZmljYXRpb246IGFueSBpbiBob3Jpem9udGFsU2hhcGluZykge1xuICAgICAgICByZXR1cm4gaG9yaXpvbnRhbFNoYXBpbmdbanVzdGlmaWNhdGlvbl07XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXZhbHVhdGVCb3hDb2xsaXNpb25GZWF0dXJlKGNvbGxpc2lvbkJveEFycmF5OiBDb2xsaXNpb25Cb3hBcnJheSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9qZWN0ZWRBbmNob3I6IEFuY2hvcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aWxlQW5jaG9yOiBBbmNob3IsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmVhdHVyZUluZGV4OiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlTGF5ZXJJbmRleDogbnVtYmVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1Y2tldEluZGV4OiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhcGVkOiBPYmplY3QsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFkZGluZzogbnVtYmVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdGF0ZTogbnVtYmVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHRPZmZzZXQ6ID9bbnVtYmVyLCBudW1iZXJdKTogbnVtYmVyIHtcbiAgICBsZXQgeTEgPSBzaGFwZWQudG9wO1xuICAgIGxldCB5MiA9IHNoYXBlZC5ib3R0b207XG4gICAgbGV0IHgxID0gc2hhcGVkLmxlZnQ7XG4gICAgbGV0IHgyID0gc2hhcGVkLnJpZ2h0O1xuXG4gICAgY29uc3QgY29sbGlzaW9uUGFkZGluZyA9IHNoYXBlZC5jb2xsaXNpb25QYWRkaW5nO1xuICAgIGlmIChjb2xsaXNpb25QYWRkaW5nKSB7XG4gICAgICAgIHgxIC09IGNvbGxpc2lvblBhZGRpbmdbMF07XG4gICAgICAgIHkxIC09IGNvbGxpc2lvblBhZGRpbmdbMV07XG4gICAgICAgIHgyICs9IGNvbGxpc2lvblBhZGRpbmdbMl07XG4gICAgICAgIHkyICs9IGNvbGxpc2lvblBhZGRpbmdbM107XG4gICAgfVxuXG4gICAgaWYgKHJvdGF0ZSkge1xuICAgICAgICAvLyBBY2NvdW50IGZvciAqLXJvdGF0ZSBpbiBwb2ludCBjb2xsaXNpb24gYm94ZXNcbiAgICAgICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXBib3gvbWFwYm94LWdsLWpzL2lzc3Vlcy82MDc1XG4gICAgICAgIC8vIERvZXNuJ3QgYWNjb3VudCBmb3IgaWNvbi10ZXh0LWZpdFxuXG4gICAgICAgIGNvbnN0IHRsID0gbmV3IFBvaW50KHgxLCB5MSk7XG4gICAgICAgIGNvbnN0IHRyID0gbmV3IFBvaW50KHgyLCB5MSk7XG4gICAgICAgIGNvbnN0IGJsID0gbmV3IFBvaW50KHgxLCB5Mik7XG4gICAgICAgIGNvbnN0IGJyID0gbmV3IFBvaW50KHgyLCB5Mik7XG5cbiAgICAgICAgY29uc3Qgcm90YXRlUmFkaWFucyA9IGRlZ1RvUmFkKHJvdGF0ZSk7XG4gICAgICAgIGxldCByb3RhdGVDZW50ZXIgPSBuZXcgUG9pbnQoMCwgMCk7XG5cbiAgICAgICAgaWYgKHRleHRPZmZzZXQpIHtcbiAgICAgICAgICAgIHJvdGF0ZUNlbnRlciA9IG5ldyBQb2ludCh0ZXh0T2Zmc2V0WzBdLCB0ZXh0T2Zmc2V0WzFdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRsLl9yb3RhdGVBcm91bmQocm90YXRlUmFkaWFucywgcm90YXRlQ2VudGVyKTtcbiAgICAgICAgdHIuX3JvdGF0ZUFyb3VuZChyb3RhdGVSYWRpYW5zLCByb3RhdGVDZW50ZXIpO1xuICAgICAgICBibC5fcm90YXRlQXJvdW5kKHJvdGF0ZVJhZGlhbnMsIHJvdGF0ZUNlbnRlcik7XG4gICAgICAgIGJyLl9yb3RhdGVBcm91bmQocm90YXRlUmFkaWFucywgcm90YXRlQ2VudGVyKTtcblxuICAgICAgICAvLyBDb2xsaXNpb24gZmVhdHVyZXMgcmVxdWlyZSBhbiBcIm9uLWF4aXNcIiBnZW9tZXRyeSxcbiAgICAgICAgLy8gc28gdGFrZSB0aGUgZW52ZWxvcGUgb2YgdGhlIHJvdGF0ZWQgZ2VvbWV0cnlcbiAgICAgICAgLy8gKG1heSBiZSBxdWl0ZSBsYXJnZSBmb3Igd2lkZSBsYWJlbHMgcm90YXRlZCA0NSBkZWdyZWVzKVxuICAgICAgICB4MSA9IE1hdGgubWluKHRsLngsIHRyLngsIGJsLngsIGJyLngpO1xuICAgICAgICB4MiA9IE1hdGgubWF4KHRsLngsIHRyLngsIGJsLngsIGJyLngpO1xuICAgICAgICB5MSA9IE1hdGgubWluKHRsLnksIHRyLnksIGJsLnksIGJyLnkpO1xuICAgICAgICB5MiA9IE1hdGgubWF4KHRsLnksIHRyLnksIGJsLnksIGJyLnkpO1xuICAgIH1cblxuICAgIGNvbGxpc2lvbkJveEFycmF5LmVtcGxhY2VCYWNrKHByb2plY3RlZEFuY2hvci54LCBwcm9qZWN0ZWRBbmNob3IueSwgcHJvamVjdGVkQW5jaG9yLnosIHRpbGVBbmNob3IueCwgdGlsZUFuY2hvci55LCB4MSwgeTEsIHgyLCB5MiwgcGFkZGluZywgZmVhdHVyZUluZGV4LCBzb3VyY2VMYXllckluZGV4LCBidWNrZXRJbmRleCk7XG5cbiAgICByZXR1cm4gY29sbGlzaW9uQm94QXJyYXkubGVuZ3RoIC0gMTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV2YWx1YXRlQ2lyY2xlQ29sbGlzaW9uRmVhdHVyZShzaGFwZWQ6IE9iamVjdCk6IG51bWJlciB8IG51bGwge1xuICAgIGlmIChzaGFwZWQuY29sbGlzaW9uUGFkZGluZykge1xuICAgICAgICAvLyBDb21wdXRlIGhlaWdodCBvZiB0aGUgc2hhcGUgaW4gZ2x5cGggbWV0cmljcyBhbmQgYXBwbHkgcGFkZGluZy5cbiAgICAgICAgLy8gTm90ZSB0aGF0IHRoZSBwaXhlbCBiYXNlZCAndGV4dC1wYWRkaW5nJyBpcyBhcHBsaWVkIGF0IHJ1bnRpbWVcbiAgICAgICAgc2hhcGVkLnRvcCAtPSBzaGFwZWQuY29sbGlzaW9uUGFkZGluZ1sxXTtcbiAgICAgICAgc2hhcGVkLmJvdHRvbSArPSBzaGFwZWQuY29sbGlzaW9uUGFkZGluZ1szXTtcbiAgICB9XG5cbiAgICAvLyBTZXQgbWluaW11bSBib3ggaGVpZ2h0IHRvIGF2b2lkIHZlcnkgbWFueSBzbWFsbCBsYWJlbHNcbiAgICBjb25zdCBoZWlnaHQgPSBzaGFwZWQuYm90dG9tIC0gc2hhcGVkLnRvcDtcbiAgICByZXR1cm4gaGVpZ2h0ID4gMCA/IE1hdGgubWF4KDEwLCBoZWlnaHQpIDogbnVsbDtcbn1cblxuLyoqXG4gKiBBZGQgYSBzaW5nbGUgbGFiZWwgJiBpY29uIHBsYWNlbWVudC5cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBhZGRTeW1ib2woYnVja2V0OiBTeW1ib2xCdWNrZXQsXG4gICAgICAgICAgICAgICAgICAgYW5jaG9yOiBBbmNob3IsXG4gICAgICAgICAgICAgICAgICAgZ2xvYmU6ID97IGFuY2hvcjogQW5jaG9yLCB1cDogVmVjMyB9LFxuICAgICAgICAgICAgICAgICAgIGxpbmU6IEFycmF5PFBvaW50PixcbiAgICAgICAgICAgICAgICAgICBzaGFwZWRUZXh0T3JpZW50YXRpb25zOiBhbnksXG4gICAgICAgICAgICAgICAgICAgc2hhcGVkSWNvbjogUG9zaXRpb25lZEljb24gfCB2b2lkLFxuICAgICAgICAgICAgICAgICAgIGltYWdlTWFwOiB7W186IHN0cmluZ106IFN0eWxlSW1hZ2V9LFxuICAgICAgICAgICAgICAgICAgIHZlcnRpY2FsbHlTaGFwZWRJY29uOiBQb3NpdGlvbmVkSWNvbiB8IHZvaWQsXG4gICAgICAgICAgICAgICAgICAgbGF5ZXI6IFN5bWJvbFN0eWxlTGF5ZXIsXG4gICAgICAgICAgICAgICAgICAgY29sbGlzaW9uQm94QXJyYXk6IENvbGxpc2lvbkJveEFycmF5LFxuICAgICAgICAgICAgICAgICAgIGZlYXR1cmVJbmRleDogbnVtYmVyLFxuICAgICAgICAgICAgICAgICAgIHNvdXJjZUxheWVySW5kZXg6IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICBidWNrZXRJbmRleDogbnVtYmVyLFxuICAgICAgICAgICAgICAgICAgIHRleHRQYWRkaW5nOiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgdGV4dEFsb25nTGluZTogYm9vbGVhbixcbiAgICAgICAgICAgICAgICAgICB0ZXh0T2Zmc2V0OiBbbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICAgICAgICAgICAgIGljb25Cb3hTY2FsZTogbnVtYmVyLFxuICAgICAgICAgICAgICAgICAgIGljb25QYWRkaW5nOiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgaWNvbkFsb25nTGluZTogYm9vbGVhbixcbiAgICAgICAgICAgICAgICAgICBpY29uT2Zmc2V0OiBbbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICAgICAgICAgICAgIGZlYXR1cmU6IFN5bWJvbEZlYXR1cmUsXG4gICAgICAgICAgICAgICAgICAgc2l6ZXM6IFNpemVzLFxuICAgICAgICAgICAgICAgICAgIGlzU0RGSWNvbjogYm9vbGVhbixcbiAgICAgICAgICAgICAgICAgICBhdmFpbGFibGVJbWFnZXM6IEFycmF5PHN0cmluZz4sXG4gICAgICAgICAgICAgICAgICAgY2Fub25pY2FsOiBDYW5vbmljYWxUaWxlSUQpIHtcbiAgICBjb25zdCBsaW5lQXJyYXkgPSBidWNrZXQuYWRkVG9MaW5lVmVydGV4QXJyYXkoYW5jaG9yLCBsaW5lKTtcbiAgICBsZXQgdGV4dEJveEluZGV4LCBpY29uQm94SW5kZXgsIHZlcnRpY2FsVGV4dEJveEluZGV4LCB2ZXJ0aWNhbEljb25Cb3hJbmRleDtcbiAgICBsZXQgdGV4dENpcmNsZSwgdmVydGljYWxUZXh0Q2lyY2xlLCB2ZXJ0aWNhbEljb25DaXJjbGU7XG5cbiAgICBsZXQgbnVtSWNvblZlcnRpY2VzID0gMDtcbiAgICBsZXQgbnVtVmVydGljYWxJY29uVmVydGljZXMgPSAwO1xuICAgIGxldCBudW1Ib3Jpem9udGFsR2x5cGhWZXJ0aWNlcyA9IDA7XG4gICAgbGV0IG51bVZlcnRpY2FsR2x5cGhWZXJ0aWNlcyA9IDA7XG4gICAgbGV0IHBsYWNlZEljb25TeW1ib2xJbmRleCA9IC0xO1xuICAgIGxldCB2ZXJ0aWNhbFBsYWNlZEljb25TeW1ib2xJbmRleCA9IC0xO1xuICAgIGNvbnN0IHBsYWNlZFRleHRTeW1ib2xJbmRpY2VzID0ge307XG4gICAgbGV0IGtleSA9IG11cm11cjMoJycpO1xuICAgIGNvbnN0IGNvbGxpc2lvbkZlYXR1cmVBbmNob3I6IEFuY2hvciA9IGdsb2JlID8gZ2xvYmUuYW5jaG9yIDogYW5jaG9yO1xuXG4gICAgbGV0IHRleHRPZmZzZXQwID0gMDtcbiAgICBsZXQgdGV4dE9mZnNldDEgPSAwO1xuICAgIGlmIChsYXllci5fdW5ldmFsdWF0ZWRMYXlvdXQuZ2V0VmFsdWUoJ3RleHQtcmFkaWFsLW9mZnNldCcpID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgW3RleHRPZmZzZXQwLCB0ZXh0T2Zmc2V0MV0gPSAobGF5ZXIubGF5b3V0LmdldCgndGV4dC1vZmZzZXQnKS5ldmFsdWF0ZShmZWF0dXJlLCB7fSwgY2Fub25pY2FsKS5tYXAodCA9PiB0ICogT05FX0VNKTogYW55KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0ZXh0T2Zmc2V0MCA9IGxheWVyLmxheW91dC5nZXQoJ3RleHQtcmFkaWFsLW9mZnNldCcpLmV2YWx1YXRlKGZlYXR1cmUsIHt9LCBjYW5vbmljYWwpICogT05FX0VNO1xuICAgICAgICB0ZXh0T2Zmc2V0MSA9IElOVkFMSURfVEVYVF9PRkZTRVQ7XG4gICAgfVxuXG4gICAgaWYgKGJ1Y2tldC5hbGxvd1ZlcnRpY2FsUGxhY2VtZW50ICYmIHNoYXBlZFRleHRPcmllbnRhdGlvbnMudmVydGljYWwpIHtcbiAgICAgICAgY29uc3QgdmVydGljYWxTaGFwaW5nID0gc2hhcGVkVGV4dE9yaWVudGF0aW9ucy52ZXJ0aWNhbDtcbiAgICAgICAgaWYgKHRleHRBbG9uZ0xpbmUpIHtcbiAgICAgICAgICAgIHZlcnRpY2FsVGV4dENpcmNsZSA9IGV2YWx1YXRlQ2lyY2xlQ29sbGlzaW9uRmVhdHVyZSh2ZXJ0aWNhbFNoYXBpbmcpO1xuICAgICAgICAgICAgaWYgKHZlcnRpY2FsbHlTaGFwZWRJY29uKSB7XG4gICAgICAgICAgICAgICAgdmVydGljYWxJY29uQ2lyY2xlID0gZXZhbHVhdGVDaXJjbGVDb2xsaXNpb25GZWF0dXJlKHZlcnRpY2FsbHlTaGFwZWRJY29uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHRleHRSb3RhdGlvbiA9IGxheWVyLmxheW91dC5nZXQoJ3RleHQtcm90YXRlJykuZXZhbHVhdGUoZmVhdHVyZSwge30sIGNhbm9uaWNhbCk7XG4gICAgICAgICAgICBjb25zdCB2ZXJ0aWNhbFRleHRSb3RhdGlvbiA9IHRleHRSb3RhdGlvbiArIDkwLjA7XG4gICAgICAgICAgICB2ZXJ0aWNhbFRleHRCb3hJbmRleCA9IGV2YWx1YXRlQm94Q29sbGlzaW9uRmVhdHVyZShjb2xsaXNpb25Cb3hBcnJheSwgY29sbGlzaW9uRmVhdHVyZUFuY2hvciwgYW5jaG9yLCBmZWF0dXJlSW5kZXgsIHNvdXJjZUxheWVySW5kZXgsIGJ1Y2tldEluZGV4LCB2ZXJ0aWNhbFNoYXBpbmcsIHRleHRQYWRkaW5nLCB2ZXJ0aWNhbFRleHRSb3RhdGlvbiwgdGV4dE9mZnNldCk7XG4gICAgICAgICAgICBpZiAodmVydGljYWxseVNoYXBlZEljb24pIHtcbiAgICAgICAgICAgICAgICB2ZXJ0aWNhbEljb25Cb3hJbmRleCA9IGV2YWx1YXRlQm94Q29sbGlzaW9uRmVhdHVyZShjb2xsaXNpb25Cb3hBcnJheSwgY29sbGlzaW9uRmVhdHVyZUFuY2hvciwgYW5jaG9yLCBmZWF0dXJlSW5kZXgsIHNvdXJjZUxheWVySW5kZXgsIGJ1Y2tldEluZGV4LCB2ZXJ0aWNhbGx5U2hhcGVkSWNvbiwgaWNvblBhZGRpbmcsIHZlcnRpY2FsVGV4dFJvdGF0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFBsYWNlIGljb24gZmlyc3QsIHNvIHRleHQgY2FuIGhhdmUgYSByZWZlcmVuY2UgdG8gaXRzIGluZGV4IGluIHRoZSBwbGFjZWQgc3ltYm9sIGFycmF5LlxuICAgIC8vIFRleHQgc3ltYm9scyBjYW4gbGF6aWx5IHNoaWZ0IGF0IHJlbmRlci10aW1lIGJlY2F1c2Ugb2YgdmFyaWFibGUgYW5jaG9yIHBsYWNlbWVudC5cbiAgICAvLyBJZiB0aGUgc3R5bGUgc3BlY2lmaWVzIGFuIGBpY29uLXRleHQtZml0YCB0aGVuIHRoZSBpY29uIHdvdWxkIGhhdmUgdG8gc2hpZnQgYWxvbmcgd2l0aCBpdC5cbiAgICAvLyBGb3IgbW9yZSBpbmZvIGNoZWNrIGB1cGRhdGVWYXJpYWJsZUFuY2hvcnNgIGluIGBkcmF3X3N5bWJvbC5qc2AgLlxuXG4gICAgaWYgKHNoYXBlZEljb24pIHtcbiAgICAgICAgY29uc3QgaWNvblJvdGF0ZSA9IGxheWVyLmxheW91dC5nZXQoJ2ljb24tcm90YXRlJykuZXZhbHVhdGUoZmVhdHVyZSwge30sIGNhbm9uaWNhbCk7XG4gICAgICAgIGNvbnN0IGhhc0ljb25UZXh0Rml0ID0gbGF5ZXIubGF5b3V0LmdldCgnaWNvbi10ZXh0LWZpdCcpICE9PSAnbm9uZSc7XG4gICAgICAgIGNvbnN0IGljb25RdWFkcyA9IGdldEljb25RdWFkcyhzaGFwZWRJY29uLCBpY29uUm90YXRlLCBpc1NERkljb24sIGhhc0ljb25UZXh0Rml0KTtcbiAgICAgICAgY29uc3QgdmVydGljYWxJY29uUXVhZHMgPSB2ZXJ0aWNhbGx5U2hhcGVkSWNvbiA/IGdldEljb25RdWFkcyh2ZXJ0aWNhbGx5U2hhcGVkSWNvbiwgaWNvblJvdGF0ZSwgaXNTREZJY29uLCBoYXNJY29uVGV4dEZpdCkgOiB1bmRlZmluZWQ7XG4gICAgICAgIGljb25Cb3hJbmRleCA9IGV2YWx1YXRlQm94Q29sbGlzaW9uRmVhdHVyZShjb2xsaXNpb25Cb3hBcnJheSwgY29sbGlzaW9uRmVhdHVyZUFuY2hvciwgYW5jaG9yLCBmZWF0dXJlSW5kZXgsIHNvdXJjZUxheWVySW5kZXgsIGJ1Y2tldEluZGV4LCBzaGFwZWRJY29uLCBpY29uUGFkZGluZywgaWNvblJvdGF0ZSk7XG4gICAgICAgIG51bUljb25WZXJ0aWNlcyA9IGljb25RdWFkcy5sZW5ndGggKiA0O1xuXG4gICAgICAgIGNvbnN0IHNpemVEYXRhID0gYnVja2V0Lmljb25TaXplRGF0YTtcbiAgICAgICAgbGV0IGljb25TaXplRGF0YSA9IG51bGw7XG5cbiAgICAgICAgaWYgKHNpemVEYXRhLmtpbmQgPT09ICdzb3VyY2UnKSB7XG4gICAgICAgICAgICBpY29uU2l6ZURhdGEgPSBbXG4gICAgICAgICAgICAgICAgU0laRV9QQUNLX0ZBQ1RPUiAqIGxheWVyLmxheW91dC5nZXQoJ2ljb24tc2l6ZScpLmV2YWx1YXRlKGZlYXR1cmUsIHt9LCBjYW5vbmljYWwpXG4gICAgICAgICAgICBdO1xuICAgICAgICAgICAgaWYgKGljb25TaXplRGF0YVswXSA+IE1BWF9QQUNLRURfU0laRSkge1xuICAgICAgICAgICAgICAgIHdhcm5PbmNlKGAke2J1Y2tldC5sYXllcklkc1swXX06IFZhbHVlIGZvciBcImljb24tc2l6ZVwiIGlzID49ICR7TUFYX0dMWVBIX0lDT05fU0laRX0uIFJlZHVjZSB5b3VyIFwiaWNvbi1zaXplXCIuYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoc2l6ZURhdGEua2luZCA9PT0gJ2NvbXBvc2l0ZScpIHtcbiAgICAgICAgICAgIGljb25TaXplRGF0YSA9IFtcbiAgICAgICAgICAgICAgICBTSVpFX1BBQ0tfRkFDVE9SICogc2l6ZXMuY29tcG9zaXRlSWNvblNpemVzWzBdLmV2YWx1YXRlKGZlYXR1cmUsIHt9LCBjYW5vbmljYWwpLFxuICAgICAgICAgICAgICAgIFNJWkVfUEFDS19GQUNUT1IgKiBzaXplcy5jb21wb3NpdGVJY29uU2l6ZXNbMV0uZXZhbHVhdGUoZmVhdHVyZSwge30sIGNhbm9uaWNhbClcbiAgICAgICAgICAgIF07XG4gICAgICAgICAgICBpZiAoaWNvblNpemVEYXRhWzBdID4gTUFYX1BBQ0tFRF9TSVpFIHx8IGljb25TaXplRGF0YVsxXSA+IE1BWF9QQUNLRURfU0laRSkge1xuICAgICAgICAgICAgICAgIHdhcm5PbmNlKGAke2J1Y2tldC5sYXllcklkc1swXX06IFZhbHVlIGZvciBcImljb24tc2l6ZVwiIGlzID49ICR7TUFYX0dMWVBIX0lDT05fU0laRX0uIFJlZHVjZSB5b3VyIFwiaWNvbi1zaXplXCIuYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBidWNrZXQuYWRkU3ltYm9scyhcbiAgICAgICAgICAgIGJ1Y2tldC5pY29uLFxuICAgICAgICAgICAgaWNvblF1YWRzLFxuICAgICAgICAgICAgaWNvblNpemVEYXRhLFxuICAgICAgICAgICAgaWNvbk9mZnNldCxcbiAgICAgICAgICAgIGljb25BbG9uZ0xpbmUsXG4gICAgICAgICAgICBmZWF0dXJlLFxuICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICBnbG9iZSxcbiAgICAgICAgICAgIGFuY2hvcixcbiAgICAgICAgICAgIGxpbmVBcnJheS5saW5lU3RhcnRJbmRleCxcbiAgICAgICAgICAgIGxpbmVBcnJheS5saW5lTGVuZ3RoLFxuICAgICAgICAgICAgLy8gVGhlIGljb24gaXRzZWxmIGRvZXMgbm90IGhhdmUgYW4gYXNzb2NpYXRlZCBzeW1ib2wgc2luY2UgdGhlIHRleHQgaXNudCBwbGFjZWQgeWV0XG4gICAgICAgICAgICAtMSxcbiAgICAgICAgICAgIGF2YWlsYWJsZUltYWdlcyxcbiAgICAgICAgICAgIGNhbm9uaWNhbCk7XG5cbiAgICAgICAgcGxhY2VkSWNvblN5bWJvbEluZGV4ID0gYnVja2V0Lmljb24ucGxhY2VkU3ltYm9sQXJyYXkubGVuZ3RoIC0gMTtcblxuICAgICAgICBpZiAodmVydGljYWxJY29uUXVhZHMpIHtcbiAgICAgICAgICAgIG51bVZlcnRpY2FsSWNvblZlcnRpY2VzID0gdmVydGljYWxJY29uUXVhZHMubGVuZ3RoICogNDtcblxuICAgICAgICAgICAgYnVja2V0LmFkZFN5bWJvbHMoXG4gICAgICAgICAgICAgICAgYnVja2V0Lmljb24sXG4gICAgICAgICAgICAgICAgdmVydGljYWxJY29uUXVhZHMsXG4gICAgICAgICAgICAgICAgaWNvblNpemVEYXRhLFxuICAgICAgICAgICAgICAgIGljb25PZmZzZXQsXG4gICAgICAgICAgICAgICAgaWNvbkFsb25nTGluZSxcbiAgICAgICAgICAgICAgICBmZWF0dXJlLFxuICAgICAgICAgICAgICAgIFdyaXRpbmdNb2RlLnZlcnRpY2FsLFxuICAgICAgICAgICAgICAgIGdsb2JlLFxuICAgICAgICAgICAgICAgIGFuY2hvcixcbiAgICAgICAgICAgICAgICBsaW5lQXJyYXkubGluZVN0YXJ0SW5kZXgsXG4gICAgICAgICAgICAgICAgbGluZUFycmF5LmxpbmVMZW5ndGgsXG4gICAgICAgICAgICAgICAgLy8gVGhlIGljb24gaXRzZWxmIGRvZXMgbm90IGhhdmUgYW4gYXNzb2NpYXRlZCBzeW1ib2wgc2luY2UgdGhlIHRleHQgaXNudCBwbGFjZWQgeWV0XG4gICAgICAgICAgICAgICAgLTEsXG4gICAgICAgICAgICAgICAgYXZhaWxhYmxlSW1hZ2VzLFxuICAgICAgICAgICAgICAgIGNhbm9uaWNhbCk7XG5cbiAgICAgICAgICAgIHZlcnRpY2FsUGxhY2VkSWNvblN5bWJvbEluZGV4ID0gYnVja2V0Lmljb24ucGxhY2VkU3ltYm9sQXJyYXkubGVuZ3RoIC0gMTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QganVzdGlmaWNhdGlvbjogYW55IGluIHNoYXBlZFRleHRPcmllbnRhdGlvbnMuaG9yaXpvbnRhbCkge1xuICAgICAgICBjb25zdCBzaGFwaW5nID0gc2hhcGVkVGV4dE9yaWVudGF0aW9ucy5ob3Jpem9udGFsW2p1c3RpZmljYXRpb25dO1xuXG4gICAgICAgIGlmICghdGV4dEJveEluZGV4KSB7XG4gICAgICAgICAgICBrZXkgPSBtdXJtdXIzKHNoYXBpbmcudGV4dCk7XG4gICAgICAgICAgICAvLyBBcyBhIGNvbGxpc2lvbiBhcHByb3hpbWF0aW9uLCB3ZSBjYW4gdXNlIGVpdGhlciB0aGUgdmVydGljYWwgb3IgYW55IG9mIHRoZSBob3Jpem9udGFsIHZlcnNpb25zIG9mIHRoZSBmZWF0dXJlXG4gICAgICAgICAgICAvLyBXZSdyZSBjb3VudGluZyBvbiBhbGwgdmVyc2lvbnMgaGF2aW5nIHNpbWlsYXIgZGltZW5zaW9uc1xuICAgICAgICAgICAgaWYgKHRleHRBbG9uZ0xpbmUpIHtcbiAgICAgICAgICAgICAgICB0ZXh0Q2lyY2xlID0gZXZhbHVhdGVDaXJjbGVDb2xsaXNpb25GZWF0dXJlKHNoYXBpbmcpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0ZXh0Um90YXRlID0gbGF5ZXIubGF5b3V0LmdldCgndGV4dC1yb3RhdGUnKS5ldmFsdWF0ZShmZWF0dXJlLCB7fSwgY2Fub25pY2FsKTtcbiAgICAgICAgICAgICAgICB0ZXh0Qm94SW5kZXggPSBldmFsdWF0ZUJveENvbGxpc2lvbkZlYXR1cmUoY29sbGlzaW9uQm94QXJyYXksIGNvbGxpc2lvbkZlYXR1cmVBbmNob3IsIGFuY2hvciwgZmVhdHVyZUluZGV4LCBzb3VyY2VMYXllckluZGV4LCBidWNrZXRJbmRleCwgc2hhcGluZywgdGV4dFBhZGRpbmcsIHRleHRSb3RhdGUsIHRleHRPZmZzZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc2luZ2xlTGluZSA9IHNoYXBpbmcucG9zaXRpb25lZExpbmVzLmxlbmd0aCA9PT0gMTtcbiAgICAgICAgbnVtSG9yaXpvbnRhbEdseXBoVmVydGljZXMgKz0gYWRkVGV4dFZlcnRpY2VzKFxuICAgICAgICAgICAgYnVja2V0LCBnbG9iZSwgYW5jaG9yLCBzaGFwaW5nLCBpbWFnZU1hcCwgbGF5ZXIsIHRleHRBbG9uZ0xpbmUsIGZlYXR1cmUsIHRleHRPZmZzZXQsIGxpbmVBcnJheSxcbiAgICAgICAgICAgIHNoYXBlZFRleHRPcmllbnRhdGlvbnMudmVydGljYWwgPyBXcml0aW5nTW9kZS5ob3Jpem9udGFsIDogV3JpdGluZ01vZGUuaG9yaXpvbnRhbE9ubHksXG4gICAgICAgICAgICBzaW5nbGVMaW5lID8gKE9iamVjdC5rZXlzKHNoYXBlZFRleHRPcmllbnRhdGlvbnMuaG9yaXpvbnRhbCk6IGFueSkgOiBbanVzdGlmaWNhdGlvbl0sXG4gICAgICAgICAgICBwbGFjZWRUZXh0U3ltYm9sSW5kaWNlcywgcGxhY2VkSWNvblN5bWJvbEluZGV4LCBzaXplcywgYXZhaWxhYmxlSW1hZ2VzLCBjYW5vbmljYWwpO1xuXG4gICAgICAgIGlmIChzaW5nbGVMaW5lKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzaGFwZWRUZXh0T3JpZW50YXRpb25zLnZlcnRpY2FsKSB7XG4gICAgICAgIG51bVZlcnRpY2FsR2x5cGhWZXJ0aWNlcyArPSBhZGRUZXh0VmVydGljZXMoXG4gICAgICAgICAgICBidWNrZXQsIGdsb2JlLCBhbmNob3IsIHNoYXBlZFRleHRPcmllbnRhdGlvbnMudmVydGljYWwsIGltYWdlTWFwLCBsYXllciwgdGV4dEFsb25nTGluZSwgZmVhdHVyZSxcbiAgICAgICAgICAgIHRleHRPZmZzZXQsIGxpbmVBcnJheSwgV3JpdGluZ01vZGUudmVydGljYWwsIFsndmVydGljYWwnXSwgcGxhY2VkVGV4dFN5bWJvbEluZGljZXMsIHZlcnRpY2FsUGxhY2VkSWNvblN5bWJvbEluZGV4LCBzaXplcywgYXZhaWxhYmxlSW1hZ2VzLCBjYW5vbmljYWwpO1xuICAgIH1cblxuICAgIC8vIENoZWNrIGlmIHJ1bnRpbWUgY29sbGlzaW9uIGNpcmNsZXMgc2hvdWxkIGJlIHVzZWQgZm9yIGFueSBvZiB0aGUgY29sbGlzaW9uIGZlYXR1cmVzLlxuICAgIC8vIEl0IGlzIGVub3VnaCB0byBjaG9vc2UgdGhlIHRhbGxlc3QgZmVhdHVyZSBzaGFwZSBhcyBjaXJjbGVzIGFyZSBhbHdheXMgcGxhY2VkIG9uIGEgbGluZS5cbiAgICAvLyBBbGwgbWVhc3VyZW1lbnRzIGFyZSBpbiBnbHlwaCBtZXRyaWNzIGFuZCBsYXRlciBjb252ZXJ0ZWQgaW50byBwaXhlbHMgdXNpbmcgcHJvcGVyIGZvbnQgc2l6ZSBcImxheW91dFRleHRTaXplXCJcbiAgICBsZXQgY29sbGlzaW9uQ2lyY2xlRGlhbWV0ZXIgPSAtMTtcblxuICAgIGNvbnN0IGdldENvbGxpc2lvbkNpcmNsZUhlaWdodCA9IChkaWFtZXRlcjogP251bWJlciwgcHJldkhlaWdodDogbnVtYmVyKTogbnVtYmVyID0+IHtcbiAgICAgICAgcmV0dXJuIGRpYW1ldGVyID8gTWF0aC5tYXgoZGlhbWV0ZXIsIHByZXZIZWlnaHQpIDogcHJldkhlaWdodDtcbiAgICB9O1xuXG4gICAgY29sbGlzaW9uQ2lyY2xlRGlhbWV0ZXIgPSBnZXRDb2xsaXNpb25DaXJjbGVIZWlnaHQodGV4dENpcmNsZSwgY29sbGlzaW9uQ2lyY2xlRGlhbWV0ZXIpO1xuICAgIGNvbGxpc2lvbkNpcmNsZURpYW1ldGVyID0gZ2V0Q29sbGlzaW9uQ2lyY2xlSGVpZ2h0KHZlcnRpY2FsVGV4dENpcmNsZSwgY29sbGlzaW9uQ2lyY2xlRGlhbWV0ZXIpO1xuICAgIGNvbGxpc2lvbkNpcmNsZURpYW1ldGVyID0gZ2V0Q29sbGlzaW9uQ2lyY2xlSGVpZ2h0KHZlcnRpY2FsSWNvbkNpcmNsZSwgY29sbGlzaW9uQ2lyY2xlRGlhbWV0ZXIpO1xuICAgIGNvbnN0IHVzZVJ1bnRpbWVDb2xsaXNpb25DaXJjbGVzID0gKGNvbGxpc2lvbkNpcmNsZURpYW1ldGVyID4gLTEpID8gMSA6IDA7XG5cbiAgICBpZiAoYnVja2V0LmdseXBoT2Zmc2V0QXJyYXkubGVuZ3RoID49IFN5bWJvbEJ1Y2tldC5NQVhfR0xZUEhTKSB3YXJuT25jZShcbiAgICAgICAgXCJUb28gbWFueSBnbHlwaHMgYmVpbmcgcmVuZGVyZWQgaW4gYSB0aWxlLiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL21hcGJveC9tYXBib3gtZ2wtanMvaXNzdWVzLzI5MDdcIlxuICAgICk7XG5cbiAgICBpZiAoZmVhdHVyZS5zb3J0S2V5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgYnVja2V0LmFkZFRvU29ydEtleVJhbmdlcyhidWNrZXQuc3ltYm9sSW5zdGFuY2VzLmxlbmd0aCwgZmVhdHVyZS5zb3J0S2V5KTtcbiAgICB9XG5cbiAgICBjb25zdCBwcm9qZWN0ZWRBbmNob3IgPSBjb2xsaXNpb25GZWF0dXJlQW5jaG9yO1xuXG4gICAgYnVja2V0LnN5bWJvbEluc3RhbmNlcy5lbXBsYWNlQmFjayhcbiAgICAgICAgcHJvamVjdGVkQW5jaG9yLngsXG4gICAgICAgIHByb2plY3RlZEFuY2hvci55LFxuICAgICAgICBwcm9qZWN0ZWRBbmNob3IueixcbiAgICAgICAgYW5jaG9yLngsXG4gICAgICAgIGFuY2hvci55LFxuICAgICAgICBwbGFjZWRUZXh0U3ltYm9sSW5kaWNlcy5yaWdodCA+PSAwID8gcGxhY2VkVGV4dFN5bWJvbEluZGljZXMucmlnaHQgOiAtMSxcbiAgICAgICAgcGxhY2VkVGV4dFN5bWJvbEluZGljZXMuY2VudGVyID49IDAgPyBwbGFjZWRUZXh0U3ltYm9sSW5kaWNlcy5jZW50ZXIgOiAtMSxcbiAgICAgICAgcGxhY2VkVGV4dFN5bWJvbEluZGljZXMubGVmdCA+PSAwID8gcGxhY2VkVGV4dFN5bWJvbEluZGljZXMubGVmdCA6IC0xLFxuICAgICAgICBwbGFjZWRUZXh0U3ltYm9sSW5kaWNlcy52ZXJ0aWNhbCAgPj0gMCA/IHBsYWNlZFRleHRTeW1ib2xJbmRpY2VzLnZlcnRpY2FsIDogLTEsXG4gICAgICAgIHBsYWNlZEljb25TeW1ib2xJbmRleCxcbiAgICAgICAgdmVydGljYWxQbGFjZWRJY29uU3ltYm9sSW5kZXgsXG4gICAgICAgIGtleSxcbiAgICAgICAgdGV4dEJveEluZGV4ICE9PSB1bmRlZmluZWQgPyB0ZXh0Qm94SW5kZXggOiBidWNrZXQuY29sbGlzaW9uQm94QXJyYXkubGVuZ3RoLFxuICAgICAgICB0ZXh0Qm94SW5kZXggIT09IHVuZGVmaW5lZCA/IHRleHRCb3hJbmRleCArIDEgOiBidWNrZXQuY29sbGlzaW9uQm94QXJyYXkubGVuZ3RoLFxuICAgICAgICB2ZXJ0aWNhbFRleHRCb3hJbmRleCAhPT0gdW5kZWZpbmVkID8gdmVydGljYWxUZXh0Qm94SW5kZXggOiBidWNrZXQuY29sbGlzaW9uQm94QXJyYXkubGVuZ3RoLFxuICAgICAgICB2ZXJ0aWNhbFRleHRCb3hJbmRleCAhPT0gdW5kZWZpbmVkID8gdmVydGljYWxUZXh0Qm94SW5kZXggKyAxIDogYnVja2V0LmNvbGxpc2lvbkJveEFycmF5Lmxlbmd0aCxcbiAgICAgICAgaWNvbkJveEluZGV4ICE9PSB1bmRlZmluZWQgPyBpY29uQm94SW5kZXggOiBidWNrZXQuY29sbGlzaW9uQm94QXJyYXkubGVuZ3RoLFxuICAgICAgICBpY29uQm94SW5kZXggIT09IHVuZGVmaW5lZCA/IGljb25Cb3hJbmRleCArIDEgOiBidWNrZXQuY29sbGlzaW9uQm94QXJyYXkubGVuZ3RoLFxuICAgICAgICB2ZXJ0aWNhbEljb25Cb3hJbmRleCA/IHZlcnRpY2FsSWNvbkJveEluZGV4IDogYnVja2V0LmNvbGxpc2lvbkJveEFycmF5Lmxlbmd0aCxcbiAgICAgICAgdmVydGljYWxJY29uQm94SW5kZXggPyB2ZXJ0aWNhbEljb25Cb3hJbmRleCArIDEgOiBidWNrZXQuY29sbGlzaW9uQm94QXJyYXkubGVuZ3RoLFxuICAgICAgICBmZWF0dXJlSW5kZXgsXG4gICAgICAgIG51bUhvcml6b250YWxHbHlwaFZlcnRpY2VzLFxuICAgICAgICBudW1WZXJ0aWNhbEdseXBoVmVydGljZXMsXG4gICAgICAgIG51bUljb25WZXJ0aWNlcyxcbiAgICAgICAgbnVtVmVydGljYWxJY29uVmVydGljZXMsXG4gICAgICAgIHVzZVJ1bnRpbWVDb2xsaXNpb25DaXJjbGVzLFxuICAgICAgICAwLFxuICAgICAgICB0ZXh0T2Zmc2V0MCxcbiAgICAgICAgdGV4dE9mZnNldDEsXG4gICAgICAgIGNvbGxpc2lvbkNpcmNsZURpYW1ldGVyKTtcbn1cblxuZnVuY3Rpb24gYW5jaG9ySXNUb29DbG9zZShidWNrZXQ6IGFueSwgdGV4dDogc3RyaW5nLCByZXBlYXREaXN0YW5jZTogbnVtYmVyLCBhbmNob3I6IFBvaW50KSB7XG4gICAgY29uc3QgY29tcGFyZVRleHQgPSBidWNrZXQuY29tcGFyZVRleHQ7XG4gICAgaWYgKCEodGV4dCBpbiBjb21wYXJlVGV4dCkpIHtcbiAgICAgICAgY29tcGFyZVRleHRbdGV4dF0gPSBbXTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBvdGhlckFuY2hvcnMgPSBjb21wYXJlVGV4dFt0ZXh0XTtcbiAgICAgICAgZm9yIChsZXQgayA9IG90aGVyQW5jaG9ycy5sZW5ndGggLSAxOyBrID49IDA7IGstLSkge1xuICAgICAgICAgICAgaWYgKGFuY2hvci5kaXN0KG90aGVyQW5jaG9yc1trXSkgPCByZXBlYXREaXN0YW5jZSkge1xuICAgICAgICAgICAgICAgIC8vIElmIGl0J3Mgd2l0aGluIHJlcGVhdERpc3RhbmNlIG9mIG9uZSBhbmNob3IsIHN0b3AgbG9va2luZ1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8vIElmIGFuY2hvciBpcyBub3Qgd2l0aGluIHJlcGVhdERpc3RhbmNlIG9mIGFueSBvdGhlciBhbmNob3IsIGFkZCB0byBhcnJheVxuICAgIGNvbXBhcmVUZXh0W3RleHRdLnB1c2goYW5jaG9yKTtcbiAgICByZXR1cm4gZmFsc2U7XG59XG4iLCIvLyBAZmxvd1xuaW1wb3J0IHt2ZWMzfSBmcm9tICdnbC1tYXRyaXgnO1xuaW1wb3J0IHtSYXl9IGZyb20gJy4uLy4uL3V0aWwvcHJpbWl0aXZlcy5qcyc7XG5pbXBvcnQgdHlwZSBUcmFuc2Zvcm0gZnJvbSAnLi4vdHJhbnNmb3JtLmpzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGZhcnRoZXN0UGl4ZWxEaXN0YW5jZU9uUGxhbmUodHI6IFRyYW5zZm9ybSwgcGl4ZWxzUGVyTWV0ZXI6IG51bWJlcik6IG51bWJlciB7XG4gICAgLy8gRmluZCB0aGUgZGlzdGFuY2UgZnJvbSB0aGUgY2VudGVyIHBvaW50IFt3aWR0aC8yICsgb2Zmc2V0LngsIGhlaWdodC8yICsgb2Zmc2V0LnldIHRvIHRoZVxuICAgIC8vIGNlbnRlciB0b3AgcG9pbnQgW3dpZHRoLzIgKyBvZmZzZXQueCwgMF0gaW4gWiB1bml0cywgdXNpbmcgdGhlIGxhdyBvZiBzaW5lcy5cbiAgICAvLyAxIFogdW5pdCBpcyBlcXVpdmFsZW50IHRvIDEgaG9yaXpvbnRhbCBweCBhdCB0aGUgY2VudGVyIG9mIHRoZSBtYXBcbiAgICAvLyAodGhlIGRpc3RhbmNlIGJldHdlZW5bd2lkdGgvMiwgaGVpZ2h0LzJdIGFuZCBbd2lkdGgvMiArIDEsIGhlaWdodC8yXSlcbiAgICBjb25zdCBmb3ZBYm92ZUNlbnRlciA9IHRyLmZvdkFib3ZlQ2VudGVyO1xuXG4gICAgLy8gQWRqdXN0IGRpc3RhbmNlIHRvIE1TTCBieSB0aGUgbWluaW11bSBwb3NzaWJsZSBlbGV2YXRpb24gdmlzaWJsZSBvbiBzY3JlZW4sXG4gICAgLy8gdGhpcyB3YXkgdGhlIGZhciBwbGFuZSBpcyBwdXNoZWQgZnVydGhlciBpbiB0aGUgY2FzZSBvZiBuZWdhdGl2ZSBlbGV2YXRpb24uXG4gICAgY29uc3QgbWluRWxldmF0aW9uSW5QaXhlbHMgPSB0ci5lbGV2YXRpb24gP1xuICAgICAgICB0ci5lbGV2YXRpb24uZ2V0TWluRWxldmF0aW9uQmVsb3dNU0woKSAqIHBpeGVsc1Blck1ldGVyIDpcbiAgICAgICAgMDtcbiAgICBjb25zdCBjYW1lcmFUb1NlYUxldmVsRGlzdGFuY2UgPSAoKHRyLl9jYW1lcmEucG9zaXRpb25bMl0gKiB0ci53b3JsZFNpemUpIC0gbWluRWxldmF0aW9uSW5QaXhlbHMpIC8gTWF0aC5jb3ModHIuX3BpdGNoKTtcbiAgICBjb25zdCB0b3BIYWxmU3VyZmFjZURpc3RhbmNlID0gTWF0aC5zaW4oZm92QWJvdmVDZW50ZXIpICogY2FtZXJhVG9TZWFMZXZlbERpc3RhbmNlIC8gTWF0aC5zaW4oTWF0aC5tYXgoTWF0aC5QSSAvIDIuMCAtIHRyLl9waXRjaCAtIGZvdkFib3ZlQ2VudGVyLCAwLjAxKSk7XG5cbiAgICAvLyBDYWxjdWxhdGUgeiBkaXN0YW5jZSBvZiB0aGUgZmFydGhlc3QgZnJhZ21lbnQgdGhhdCBzaG91bGQgYmUgcmVuZGVyZWQuXG4gICAgY29uc3QgZnVydGhlc3REaXN0YW5jZSA9IE1hdGguc2luKHRyLl9waXRjaCkgKiB0b3BIYWxmU3VyZmFjZURpc3RhbmNlICsgY2FtZXJhVG9TZWFMZXZlbERpc3RhbmNlO1xuICAgIGNvbnN0IGhvcml6b25EaXN0YW5jZSA9IGNhbWVyYVRvU2VhTGV2ZWxEaXN0YW5jZSAqICgxIC8gdHIuX2hvcml6b25TaGlmdCk7XG5cbiAgICAvLyBBZGQgYSBiaXQgZXh0cmEgdG8gYXZvaWQgcHJlY2lzaW9uIHByb2JsZW1zIHdoZW4gYSBmcmFnbWVudCdzIGRpc3RhbmNlIGlzIGV4YWN0bHkgYGZ1cnRoZXN0RGlzdGFuY2VgXG4gICAgcmV0dXJuIE1hdGgubWluKGZ1cnRoZXN0RGlzdGFuY2UgKiAxLjAxLCBob3Jpem9uRGlzdGFuY2UpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZmFydGhlc3RQaXhlbERpc3RhbmNlT25TcGhlcmUodHI6IFRyYW5zZm9ybSwgcGl4ZWxzUGVyTWV0ZXI6IG51bWJlcik6IG51bWJlciB7XG4gICAgLy8gRmluZCBmYXJ0aGVzdCBkaXN0YW5jZSBvZiB0aGUgZ2xvYmUgdGhhdCBpcyBwb3RlbnRpYWxseSB2aXNpYmxlIHRvIHRoZSBjYW1lcmEuXG4gICAgLy8gRmlyc3QgY2hlY2sgaWYgdGhlIHZpZXcgZnJ1c3R1bSBpcyBmdWxseSBjb3ZlcmVkIGJ5IHRoZSBtYXAgYnkgY2FzdGluZyBhIHJheVxuICAgIC8vIGZyb20gdGhlIHRvcCBsZWZ0L3JpZ2h0IGNvcm5lciBhbmQgc2VlIGlmIGl0IGludGVyc2VjdHMgd2l0aCB0aGUgZ2xvYmUuIEluIGNhc2VcbiAgICAvLyBvZiBubyBpbnRlcnNlY3Rpb24gd2UgbmVlZCB0byBmaW5kIGRpc3RhbmNlIHRvIHRoZSBob3Jpem9uIHBvaW50IHdoZXJlIHRoZVxuICAgIC8vIHN1cmZhY2Ugbm9ybWFsIGlzIHBlcnBlbmRpY3VsYXIgdG8gdGhlIGNhbWVyYSBmb3J3YXJkIGRpcmVjdGlvbi5cbiAgICBjb25zdCBjYW1lcmFEaXN0YW5jZSA9IHRyLmNhbWVyYVRvQ2VudGVyRGlzdGFuY2U7XG4gICAgY29uc3QgY2VudGVyUGl4ZWxBbHRpdHVkZSA9IHRyLl9jZW50ZXJBbHRpdHVkZSAqIHBpeGVsc1Blck1ldGVyO1xuXG4gICAgY29uc3QgY2FtZXJhID0gdHIuX2NhbWVyYTtcbiAgICBjb25zdCBmb3J3YXJkID0gdHIuX2NhbWVyYS5mb3J3YXJkKCk7XG4gICAgY29uc3QgY2FtZXJhUG9zaXRpb24gPSB2ZWMzLmFkZChbXSwgdmVjMy5zY2FsZShbXSwgZm9yd2FyZCwgLWNhbWVyYURpc3RhbmNlKSwgWzAsIDAsIGNlbnRlclBpeGVsQWx0aXR1ZGVdKTtcblxuICAgIGNvbnN0IGdsb2JlUmFkaXVzID0gdHIud29ybGRTaXplIC8gKDIuMCAqIE1hdGguUEkpO1xuICAgIGNvbnN0IGdsb2JlQ2VudGVyID0gWzAsIDAsIC1nbG9iZVJhZGl1c107XG5cbiAgICBjb25zdCBhc3BlY3RSYXRpbyA9IHRyLndpZHRoIC8gdHIuaGVpZ2h0O1xuICAgIGNvbnN0IHRhbkZvdkFib3ZlQ2VudGVyID0gTWF0aC50YW4odHIuZm92QWJvdmVDZW50ZXIpO1xuXG4gICAgY29uc3QgdXAgPSB2ZWMzLnNjYWxlKFtdLCBjYW1lcmEudXAoKSwgdGFuRm92QWJvdmVDZW50ZXIpO1xuICAgIGNvbnN0IHJpZ2h0ID0gdmVjMy5zY2FsZShbXSwgY2FtZXJhLnJpZ2h0KCksIHRhbkZvdkFib3ZlQ2VudGVyICogYXNwZWN0UmF0aW8pO1xuICAgIGNvbnN0IGRpciA9IHZlYzMubm9ybWFsaXplKFtdLCB2ZWMzLmFkZChbXSwgdmVjMy5hZGQoW10sIGZvcndhcmQsIHVwKSwgcmlnaHQpKTtcblxuICAgIGNvbnN0IHBvaW50T25HbG9iZSA9IFtdO1xuICAgIGNvbnN0IHJheSA9IG5ldyBSYXkoY2FtZXJhUG9zaXRpb24sIGRpcik7XG5cbiAgICBsZXQgcGl4ZWxEaXN0YW5jZTtcbiAgICBpZiAocmF5LmNsb3Nlc3RQb2ludE9uU3BoZXJlKGdsb2JlQ2VudGVyLCBnbG9iZVJhZGl1cywgcG9pbnRPbkdsb2JlKSkge1xuICAgICAgICBjb25zdCBwMCA9IHZlYzMuYWRkKFtdLCBwb2ludE9uR2xvYmUsIGdsb2JlQ2VudGVyKTtcbiAgICAgICAgY29uc3QgcDEgPSB2ZWMzLnN1YihbXSwgcDAsIGNhbWVyYVBvc2l0aW9uKTtcbiAgICAgICAgLy8gR2xvYmUgaXMgZnVsbHkgY292ZXJpbmcgdGhlIHZpZXcgZnJ1c3R1bS4gUHJvamVjdCB0aGUgaW50ZXJzZWN0aW9uXG4gICAgICAgIC8vIHBvaW50IHRvIHRoZSBjYW1lcmEgdmlldyB2ZWN0b3IgaW4gb3JkZXIgdG8gZmluZCB0aGUgcGl4ZWwgZGlzdGFuY2VcbiAgICAgICAgcGl4ZWxEaXN0YW5jZSA9IE1hdGguY29zKHRyLmZvdkFib3ZlQ2VudGVyKSAqIHZlYzMubGVuZ3RoKHAxKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICAvLyBCYWNrZ3JvdW5kIHNwYWNlIGlzIHZpc2libGUuIEZpbmQgZGlzdGFuY2UgdG8gdGhlIHBvaW50IG9mIHRoZVxuICAgICAgICAvLyBnbG9iZSB3aGVyZSBzdXJmYWNlIG5vcm1hbCBpcyBwYXJhbGxlbCB0byB0aGUgdmlldyB2ZWN0b3JcbiAgICAgICAgY29uc3QgZ2xvYmVDZW50ZXJUb0NhbWVyYSA9IHZlYzMuc3ViKFtdLCBjYW1lcmFQb3NpdGlvbiwgZ2xvYmVDZW50ZXIpO1xuICAgICAgICBjb25zdCBjYW1lcmFUb0dsb2JlID0gdmVjMy5zdWIoW10sIGdsb2JlQ2VudGVyLCBjYW1lcmFQb3NpdGlvbik7XG4gICAgICAgIHZlYzMubm9ybWFsaXplKGNhbWVyYVRvR2xvYmUsIGNhbWVyYVRvR2xvYmUpO1xuXG4gICAgICAgIGNvbnN0IGNhbWVyYUhlaWdodCA9IHZlYzMubGVuZ3RoKGdsb2JlQ2VudGVyVG9DYW1lcmEpIC0gZ2xvYmVSYWRpdXM7XG4gICAgICAgIHBpeGVsRGlzdGFuY2UgPSBNYXRoLnNxcnQoY2FtZXJhSGVpZ2h0ICogKGNhbWVyYUhlaWdodCArIDIgKiBnbG9iZVJhZGl1cykpO1xuICAgICAgICBjb25zdCBhbmdsZSA9IE1hdGguYWNvcyhwaXhlbERpc3RhbmNlIC8gKGdsb2JlUmFkaXVzICsgY2FtZXJhSGVpZ2h0KSkgLSBNYXRoLmFjb3ModmVjMy5kb3QoZm9yd2FyZCwgY2FtZXJhVG9HbG9iZSkpO1xuICAgICAgICBwaXhlbERpc3RhbmNlICo9IE1hdGguY29zKGFuZ2xlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGl4ZWxEaXN0YW5jZSAqIDEuMDE7XG59XG4iLCIvLyBAZmxvd1xuaW1wb3J0IFBvaW50IGZyb20gJ0BtYXBib3gvcG9pbnQtZ2VvbWV0cnknO1xuaW1wb3J0IE1lcmNhdG9yQ29vcmRpbmF0ZSwge2FsdGl0dWRlRnJvbU1lcmNhdG9yWiwgbG5nRnJvbU1lcmNhdG9yWCwgbGF0RnJvbU1lcmNhdG9yWX0gZnJvbSAnLi4vbWVyY2F0b3JfY29vcmRpbmF0ZS5qcyc7XG5pbXBvcnQgRVhURU5UIGZyb20gJy4uLy4uL2RhdGEvZXh0ZW50LmpzJztcbmltcG9ydCB7dmVjM30gZnJvbSAnZ2wtbWF0cml4JztcbmltcG9ydCB7QWFiYn0gZnJvbSAnLi4vLi4vdXRpbC9wcmltaXRpdmVzLmpzJztcbmltcG9ydCB7YWFiYkZvclRpbGVPbkdsb2JlfSBmcm9tICcuL2dsb2JlX3V0aWwuanMnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHtDYW5vbmljYWxUaWxlSUR9IGZyb20gJy4uLy4uL3NvdXJjZS90aWxlX2lkLmpzJztcblxuaW1wb3J0IHR5cGUge1ZlYzN9IGZyb20gJ2dsLW1hdHJpeCc7XG5pbXBvcnQgdHlwZSBQcm9qZWN0aW9uLCB7UHJvamVjdGVkUG9pbnR9IGZyb20gJy4vcHJvamVjdGlvbi5qcyc7XG5pbXBvcnQgdHlwZSBUcmFuc2Zvcm0gZnJvbSAnLi4vdHJhbnNmb3JtLmpzJztcblxuZXhwb3J0IHR5cGUgVGlsZVRyYW5zZm9ybSA9IHtcbiAgICBzY2FsZTogbnVtYmVyLFxuICAgIHg6IG51bWJlcixcbiAgICB5OiBudW1iZXIsXG4gICAgeDI6IG51bWJlcixcbiAgICB5MjogbnVtYmVyLFxuICAgIHByb2plY3Rpb246IFByb2plY3Rpb25cbn07XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHRpbGVUcmFuc2Zvcm0oaWQ6IE9iamVjdCwgcHJvamVjdGlvbjogUHJvamVjdGlvbik6IFRpbGVUcmFuc2Zvcm0ge1xuICAgIGlmICghcHJvamVjdGlvbi5pc1JlcHJvamVjdGVkSW5UaWxlU3BhY2UpIHtcbiAgICAgICAgcmV0dXJuIHtzY2FsZTogMSA8PCBpZC56LCB4OiBpZC54LCB5OiBpZC55LCB4MjogaWQueCArIDEsIHkyOiBpZC55ICsgMSwgcHJvamVjdGlvbn07XG4gICAgfVxuXG4gICAgY29uc3QgcyA9IE1hdGgucG93KDIsIC1pZC56KTtcblxuICAgIGNvbnN0IHgxID0gKGlkLngpICogcztcbiAgICBjb25zdCB4MiA9IChpZC54ICsgMSkgKiBzO1xuICAgIGNvbnN0IHkxID0gKGlkLnkpICogcztcbiAgICBjb25zdCB5MiA9IChpZC55ICsgMSkgKiBzO1xuXG4gICAgY29uc3QgbG5nMSA9IGxuZ0Zyb21NZXJjYXRvclgoeDEpO1xuICAgIGNvbnN0IGxuZzIgPSBsbmdGcm9tTWVyY2F0b3JYKHgyKTtcbiAgICBjb25zdCBsYXQxID0gbGF0RnJvbU1lcmNhdG9yWSh5MSk7XG4gICAgY29uc3QgbGF0MiA9IGxhdEZyb21NZXJjYXRvclkoeTIpO1xuXG4gICAgY29uc3QgcDAgPSBwcm9qZWN0aW9uLnByb2plY3QobG5nMSwgbGF0MSk7XG4gICAgY29uc3QgcDEgPSBwcm9qZWN0aW9uLnByb2plY3QobG5nMiwgbGF0MSk7XG4gICAgY29uc3QgcDIgPSBwcm9qZWN0aW9uLnByb2plY3QobG5nMiwgbGF0Mik7XG4gICAgY29uc3QgcDMgPSBwcm9qZWN0aW9uLnByb2plY3QobG5nMSwgbGF0Mik7XG5cbiAgICBsZXQgbWluWCA9IE1hdGgubWluKHAwLngsIHAxLngsIHAyLngsIHAzLngpO1xuICAgIGxldCBtaW5ZID0gTWF0aC5taW4ocDAueSwgcDEueSwgcDIueSwgcDMueSk7XG4gICAgbGV0IG1heFggPSBNYXRoLm1heChwMC54LCBwMS54LCBwMi54LCBwMy54KTtcbiAgICBsZXQgbWF4WSA9IE1hdGgubWF4KHAwLnksIHAxLnksIHAyLnksIHAzLnkpO1xuXG4gICAgLy8gd2UgcGljayBhbiBlcnJvciB0aHJlc2hvbGQgZm9yIGNhbGN1bGF0aW5nIHRoZSBiYm94IHRoYXQgYmFsYW5jZXMgYmV0d2VlbiBwZXJmb3JtYW5jZSBhbmQgcHJlY2lzaW9uXG4gICAgY29uc3QgbWF4RXJyID0gcyAvIDE2O1xuXG4gICAgZnVuY3Rpb24gcHJvY2Vzc1NlZ21lbnQocGE6IFByb2plY3RlZFBvaW50LCBwYjogUHJvamVjdGVkUG9pbnQsIGF4OiBudW1iZXIsIGF5OiBudW1iZXIsIGJ4OiBudW1iZXIsIGJ5OiBudW1iZXIpIHtcbiAgICAgICAgY29uc3QgbXggPSAoYXggKyBieCkgLyAyO1xuICAgICAgICBjb25zdCBteSA9IChheSArIGJ5KSAvIDI7XG5cbiAgICAgICAgY29uc3QgcG0gPSBwcm9qZWN0aW9uLnByb2plY3QobG5nRnJvbU1lcmNhdG9yWChteCksIGxhdEZyb21NZXJjYXRvclkobXkpKTtcbiAgICAgICAgY29uc3QgZXJyID0gTWF0aC5tYXgoMCwgbWluWCAtIHBtLngsIG1pblkgLSBwbS55LCBwbS54IC0gbWF4WCwgcG0ueSAtIG1heFkpO1xuXG4gICAgICAgIG1pblggPSBNYXRoLm1pbihtaW5YLCBwbS54KTtcbiAgICAgICAgbWF4WCA9IE1hdGgubWF4KG1heFgsIHBtLngpO1xuICAgICAgICBtaW5ZID0gTWF0aC5taW4obWluWSwgcG0ueSk7XG4gICAgICAgIG1heFkgPSBNYXRoLm1heChtYXhZLCBwbS55KTtcblxuICAgICAgICBpZiAoZXJyID4gbWF4RXJyKSB7XG4gICAgICAgICAgICBwcm9jZXNzU2VnbWVudChwYSwgcG0sIGF4LCBheSwgbXgsIG15KTtcbiAgICAgICAgICAgIHByb2Nlc3NTZWdtZW50KHBtLCBwYiwgbXgsIG15LCBieCwgYnkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJvY2Vzc1NlZ21lbnQocDAsIHAxLCB4MSwgeTEsIHgyLCB5MSk7XG4gICAgcHJvY2Vzc1NlZ21lbnQocDEsIHAyLCB4MiwgeTEsIHgyLCB5Mik7XG4gICAgcHJvY2Vzc1NlZ21lbnQocDIsIHAzLCB4MiwgeTIsIHgxLCB5Mik7XG4gICAgcHJvY2Vzc1NlZ21lbnQocDMsIHAwLCB4MSwgeTIsIHgxLCB5MSk7XG5cbiAgICAvLyBleHRlbmQgdGhlIGJib3ggYnkgbWF4IGVycm9yIHRvIG1ha2Ugc3VyZSBjb29yZHMgZG9uJ3QgZ28gcGFzdCB0aWxlIGV4dGVudFxuICAgIG1pblggLT0gbWF4RXJyO1xuICAgIG1pblkgLT0gbWF4RXJyO1xuICAgIG1heFggKz0gbWF4RXJyO1xuICAgIG1heFkgKz0gbWF4RXJyO1xuXG4gICAgY29uc3QgbWF4ID0gTWF0aC5tYXgobWF4WCAtIG1pblgsIG1heFkgLSBtaW5ZKTtcbiAgICBjb25zdCBzY2FsZSA9IDEgLyBtYXg7XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBzY2FsZSxcbiAgICAgICAgeDogbWluWCAqIHNjYWxlLFxuICAgICAgICB5OiBtaW5ZICogc2NhbGUsXG4gICAgICAgIHgyOiBtYXhYICogc2NhbGUsXG4gICAgICAgIHkyOiBtYXhZICogc2NhbGUsXG4gICAgICAgIHByb2plY3Rpb25cbiAgICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdGlsZUFBQkIodHI6IFRyYW5zZm9ybSwgbnVtVGlsZXM6IG51bWJlciwgejogbnVtYmVyLCB4OiBudW1iZXIsIHk6IG51bWJlciwgd3JhcDogbnVtYmVyLCBtaW46IG51bWJlciwgbWF4OiBudW1iZXIsIHByb2plY3Rpb246IFByb2plY3Rpb24pOiBBYWJiIHtcbiAgICBpZiAocHJvamVjdGlvbi5uYW1lID09PSAnZ2xvYmUnKSB7XG4gICAgICAgIGNvbnN0IHRpbGVJZCA9IG5ldyBDYW5vbmljYWxUaWxlSUQoeiwgeCwgeSk7XG4gICAgICAgIHJldHVybiBhYWJiRm9yVGlsZU9uR2xvYmUodHIsIG51bVRpbGVzLCB0aWxlSWQpO1xuICAgIH1cblxuICAgIGNvbnN0IHR0ID0gdGlsZVRyYW5zZm9ybSh7eiwgeCwgeX0sIHByb2plY3Rpb24pO1xuICAgIGNvbnN0IHR4ID0gdHQueCAvIHR0LnNjYWxlO1xuICAgIGNvbnN0IHR5ID0gdHQueSAvIHR0LnNjYWxlO1xuICAgIGNvbnN0IHR4MiA9IHR0LngyIC8gdHQuc2NhbGU7XG4gICAgY29uc3QgdHkyID0gdHQueTIgLyB0dC5zY2FsZTtcblxuICAgIGlmIChpc05hTih0eCkgfHwgaXNOYU4odHgyKSB8fCBpc05hTih0eSkgfHwgaXNOYU4odHkyKSkge1xuICAgICAgICBhc3NlcnQoZmFsc2UpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgQWFiYihcbiAgICAgICAgWyh3cmFwICsgdHgpICogbnVtVGlsZXMsIG51bVRpbGVzICogdHksIG1pbl0sXG4gICAgICAgIFsod3JhcCAgKyB0eDIpICogbnVtVGlsZXMsIG51bVRpbGVzICogdHkyLCBtYXhdKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRpbGVQb2ludCh0aWxlVHJhbnNmb3JtOiBUaWxlVHJhbnNmb3JtLCB7eCwgeX06IGludGVyZmFjZSB7IHg6IG51bWJlciwgeTogbnVtYmVyIH0sIHdyYXA6IG51bWJlciA9IDApOiBQb2ludCB7XG4gICAgcmV0dXJuIG5ldyBQb2ludChcbiAgICAgICAgKCh4IC0gd3JhcCkgKiB0aWxlVHJhbnNmb3JtLnNjYWxlIC0gdGlsZVRyYW5zZm9ybS54KSAqIEVYVEVOVCxcbiAgICAgICAgKHkgKiB0aWxlVHJhbnNmb3JtLnNjYWxlIC0gdGlsZVRyYW5zZm9ybS55KSAqIEVYVEVOVCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUaWxlVmVjMyh0aWxlVHJhbnNmb3JtOiBUaWxlVHJhbnNmb3JtLCBjb29yZDogTWVyY2F0b3JDb29yZGluYXRlLCB3cmFwOiBudW1iZXIgPSAwKTogVmVjMyB7XG4gICAgY29uc3QgeCA9ICgoY29vcmQueCAtIHdyYXApICogdGlsZVRyYW5zZm9ybS5zY2FsZSAtIHRpbGVUcmFuc2Zvcm0ueCkgKiBFWFRFTlQ7XG4gICAgY29uc3QgeSA9IChjb29yZC55ICogdGlsZVRyYW5zZm9ybS5zY2FsZSAtIHRpbGVUcmFuc2Zvcm0ueSkgKiBFWFRFTlQ7XG4gICAgcmV0dXJuIHZlYzMuZnJvbVZhbHVlcyh4LCB5LCBhbHRpdHVkZUZyb21NZXJjYXRvclooY29vcmQueiwgY29vcmQueSkpO1xufVxuIiwiLy8gQGZsb3dcbmltcG9ydCBMbmdMYXQgZnJvbSAnLi4vbG5nX2xhdC5qcyc7XG5pbXBvcnQge21lcmNhdG9yWmZyb21BbHRpdHVkZX0gZnJvbSAnLi4vbWVyY2F0b3JfY29vcmRpbmF0ZS5qcyc7XG5pbXBvcnQgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5pbXBvcnQge2ZhcnRoZXN0UGl4ZWxEaXN0YW5jZU9uUGxhbmV9IGZyb20gJy4vZmFyX3ouanMnO1xuaW1wb3J0IHttYXQ0fSBmcm9tICdnbC1tYXRyaXgnO1xuaW1wb3J0IEVYVEVOVCBmcm9tICcuLi8uLi9kYXRhL2V4dGVudC5qcyc7XG5pbXBvcnQgdGlsZVRyYW5zZm9ybSBmcm9tICcuL3RpbGVfdHJhbnNmb3JtLmpzJztcblxuaW1wb3J0IHR5cGUgVHJhbnNmb3JtIGZyb20gJy4uLy4uL2dlby90cmFuc2Zvcm0uanMnO1xuaW1wb3J0IHR5cGUge1ZlYzN9IGZyb20gJ2dsLW1hdHJpeCc7XG5pbXBvcnQgdHlwZSBNZXJjYXRvckNvb3JkaW5hdGUgZnJvbSAnLi4vbWVyY2F0b3JfY29vcmRpbmF0ZS5qcyc7XG5pbXBvcnQgdHlwZSB7UHJvamVjdGlvblNwZWNpZmljYXRpb259IGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge0Nhbm9uaWNhbFRpbGVJRCwgVW53cmFwcGVkVGlsZUlEfSBmcm9tICcuLi8uLi9zb3VyY2UvdGlsZV9pZC5qcyc7XG5cbmV4cG9ydCB0eXBlIFByb2plY3RlZFBvaW50ID0ge1xuICAgIHg6IG51bWJlcjtcbiAgICB5OiBudW1iZXI7XG4gICAgejogbnVtYmVyO1xufTtcblxuZXhwb3J0IHR5cGUgRWxldmF0aW9uU2NhbGUgPSB7XG4gICAgLy8gYG1ldGVyc1RvVGlsZWAgY29udmVydHMgbWV0ZXJzIHRvIHVuaXRzIHVzZWQgdG8gZGVzY3JpYmUgZWxldmF0aW9uIGluIHRpbGUgc3BhY2UuXG4gICAgLy8gRGVmYXVsdCB1bml0cyBpbiBtZXJjYXRvciBzcGFjZSBhcmUgeCAmIHk6IFswLCA4MTkyXSBhbmQgejogbWV0ZXJzXG4gICAgbWV0ZXJzVG9UaWxlOiBudW1iZXJcbn1cblxuY29uc3QgaWRlbnRpdHkgPSBtYXQ0LmlkZW50aXR5KG5ldyBGbG9hdDMyQXJyYXkoMTYpKTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUHJvamVjdGlvbiB7XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIHdyYXA6IGJvb2xlYW47XG4gICAgY29uaWM6IGJvb2xlYW47XG4gICAgcmVxdWlyZXNEcmFwaW5nOiBib29sZWFuO1xuICAgIHN1cHBvcnRzV29ybGRDb3BpZXM6IGJvb2xlYW47XG4gICAgc3VwcG9ydHNUZXJyYWluOiBib29sZWFuO1xuICAgIHN1cHBvcnRzRm9nOiBib29sZWFuO1xuICAgIHN1cHBvcnRzRnJlZUNhbWVyYTogYm9vbGVhbjtcbiAgICB6QXhpc1VuaXQ6ICdtZXRlcnMnIHwgJ3BpeGVscyc7XG4gICAgaXNSZXByb2plY3RlZEluVGlsZVNwYWNlOiBib29sZWFuO1xuICAgIGNlbnRlcjogW251bWJlciwgbnVtYmVyXTtcbiAgICByYW5nZTogP1tudW1iZXIsIG51bWJlcl07XG4gICAgcGFyYWxsZWxzOiA/W251bWJlciwgbnVtYmVyXTtcbiAgICB1bnN1cHBvcnRlZExheWVyczogQXJyYXk8c3RyaW5nPjtcbiAgICBzcGVjOiBQcm9qZWN0aW9uU3BlY2lmaWNhdGlvbjtcblxuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFByb2plY3Rpb25TcGVjaWZpY2F0aW9uKSB7XG4gICAgICAgIHRoaXMuc3BlYyA9IG9wdGlvbnM7XG4gICAgICAgIHRoaXMubmFtZSA9IG9wdGlvbnMubmFtZTtcbiAgICAgICAgdGhpcy53cmFwID0gZmFsc2U7XG4gICAgICAgIHRoaXMucmVxdWlyZXNEcmFwaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc3VwcG9ydHNXb3JsZENvcGllcyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnN1cHBvcnRzVGVycmFpbiA9IGZhbHNlO1xuICAgICAgICB0aGlzLnN1cHBvcnRzRm9nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc3VwcG9ydHNGcmVlQ2FtZXJhID0gZmFsc2U7XG4gICAgICAgIHRoaXMuekF4aXNVbml0ID0gJ21ldGVycyc7XG4gICAgICAgIHRoaXMuaXNSZXByb2plY3RlZEluVGlsZVNwYWNlID0gdHJ1ZTtcbiAgICAgICAgdGhpcy51bnN1cHBvcnRlZExheWVycyA9IFsnY3VzdG9tJ107XG4gICAgICAgIHRoaXMuY2VudGVyID0gWzAsIDBdO1xuICAgICAgICB0aGlzLnJhbmdlID0gWzMuNSwgN107XG4gICAgfVxuXG4gICAgcHJvamVjdChsbmc6IG51bWJlciwgbGF0OiBudW1iZXIpOiBQcm9qZWN0ZWRQb2ludCB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbiAgICAgICAgcmV0dXJuIHt4OiAwLCB5OiAwLCB6OiAwfTsgLy8gb3ZlcnJpZGVuIGluIHN1YmNsYXNzZXNcbiAgICB9XG5cbiAgICB1bnByb2plY3QoeDogbnVtYmVyLCB5OiBudW1iZXIpOiBMbmdMYXQgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG4gICAgICAgIHJldHVybiBuZXcgTG5nTGF0KDAsIDApOyAvLyBvdmVycmlkZW4gaW4gc3ViY2xhc3Nlc1xuICAgIH1cblxuICAgIHByb2plY3RUaWxlUG9pbnQoeDogbnVtYmVyLCB5OiBudW1iZXIsIF86IENhbm9uaWNhbFRpbGVJRCk6IFByb2plY3RlZFBvaW50IHtcbiAgICAgICAgcmV0dXJuIHt4LCB5LCB6OiAwfTtcbiAgICB9XG5cbiAgICBsb2NhdGlvblBvaW50KHRyOiBUcmFuc2Zvcm0sIGxuZ0xhdDogTG5nTGF0LCB0ZXJyYWluOiBib29sZWFuID0gdHJ1ZSk6IFBvaW50IHtcbiAgICAgICAgcmV0dXJuIHRyLl9jb29yZGluYXRlUG9pbnQodHIubG9jYXRpb25Db29yZGluYXRlKGxuZ0xhdCksIHRlcnJhaW4pO1xuICAgIH1cblxuICAgIHBpeGVsc1Blck1ldGVyKGxhdDogbnVtYmVyLCB3b3JsZFNpemU6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIHJldHVybiBtZXJjYXRvclpmcm9tQWx0aXR1ZGUoMSwgbGF0KSAqIHdvcmxkU2l6ZTtcbiAgICB9XG5cbiAgICAvLyBwaXhlbHMtcGVyLW1ldGVyIGlzIHVzZWQgdG8gZGVzY3JpYmUgcmVsYXRpb24gYmV0d2VlbiByZWFsIHdvcmxkIGFuZCBwaXhlbCBkaXN0YW5jZXMuXG4gICAgLy8gYHBpeGVsU3BhY2VDb252ZXJzaW9uYCBjYW4gYmUgdXNlZCB0byBjb252ZXJ0IHRoZSByYXRpbyBmcm9tIG1lcmNhdG9yIHByb2plY3Rpb24gdG9cbiAgICAvLyB0aGUgY3VycmVudGx5IGFjdGl2ZSBwcm9qZWN0aW9uLlxuICAgIC8vXG4gICAgLy8gYHBpeGVsU3BhY2VDb252ZXJzaW9uYCBpcyB1c2VmdWwgZm9yIGNvbnZlcnRpbmcgYmV0d2VlbiBwaXhlbCBzcGFjZXMgd2hlcmUgc29tZSBsb2dpY1xuICAgIC8vIGV4cGVjdHMgbWVyY2F0b3IgcGl4ZWxzLCBzdWNoIGFzIHJheWNhc3Rpbmcgd2hlcmUgdGhlIHNjYWxlIGlzIGV4cGVjdGVkIHRvIGJlIGluXG4gICAgLy8gbWVyY2F0b3IgcGl4ZWxzLlxuICAgIHBpeGVsU3BhY2VDb252ZXJzaW9uKGxhdDogbnVtYmVyLCB3b3JsZFNpemU6IG51bWJlciwgaW50ZXJwb2xhdGlvblQ6IG51bWJlcik6IG51bWJlciB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbiAgICAgICAgcmV0dXJuIDEuMDtcbiAgICB9XG5cbiAgICBmYXJ0aGVzdFBpeGVsRGlzdGFuY2UodHI6IFRyYW5zZm9ybSk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiBmYXJ0aGVzdFBpeGVsRGlzdGFuY2VPblBsYW5lKHRyLCB0ci5waXhlbHNQZXJNZXRlcik7XG4gICAgfVxuXG4gICAgcG9pbnRDb29yZGluYXRlKHRyOiBUcmFuc2Zvcm0sIHg6IG51bWJlciwgeTogbnVtYmVyLCB6OiBudW1iZXIpOiBNZXJjYXRvckNvb3JkaW5hdGUge1xuICAgICAgICBjb25zdCBob3Jpem9uT2Zmc2V0ID0gdHIuaG9yaXpvbkxpbmVGcm9tVG9wKGZhbHNlKTtcbiAgICAgICAgY29uc3QgY2xhbXBlZCA9IG5ldyBQb2ludCh4LCBNYXRoLm1heChob3Jpem9uT2Zmc2V0LCB5KSk7XG4gICAgICAgIHJldHVybiB0ci5yYXlJbnRlcnNlY3Rpb25Db29yZGluYXRlKHRyLnBvaW50UmF5SW50ZXJzZWN0aW9uKGNsYW1wZWQsIHopKTtcbiAgICB9XG5cbiAgICBwb2ludENvb3JkaW5hdGUzRCh0cjogVHJhbnNmb3JtLCB4OiBudW1iZXIsIHk6IG51bWJlcik6ID9WZWMzIHtcbiAgICAgICAgY29uc3QgcCA9IG5ldyBQb2ludCh4LCB5KTtcbiAgICAgICAgaWYgKHRyLmVsZXZhdGlvbikge1xuICAgICAgICAgICAgcmV0dXJuIHRyLmVsZXZhdGlvbi5wb2ludENvb3JkaW5hdGUocCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBtYyA9IHRoaXMucG9pbnRDb29yZGluYXRlKHRyLCBwLngsIHAueSwgMCk7XG4gICAgICAgICAgICByZXR1cm4gW21jLngsIG1jLnksIG1jLnpdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaXNQb2ludEFib3ZlSG9yaXpvbih0cjogVHJhbnNmb3JtLCBwOiBQb2ludCk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAodHIuZWxldmF0aW9uKSB7XG4gICAgICAgICAgICBjb25zdCByYXljYXN0T25UZXJyYWluID0gdGhpcy5wb2ludENvb3JkaW5hdGUzRCh0ciwgcC54LCBwLnkpO1xuICAgICAgICAgICAgcmV0dXJuICFyYXljYXN0T25UZXJyYWluO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGhvcml6b24gPSB0ci5ob3Jpem9uTGluZUZyb21Ub3AoKTtcbiAgICAgICAgcmV0dXJuIHAueSA8IGhvcml6b247XG4gICAgfVxuXG4gICAgY3JlYXRlSW52ZXJzaW9uTWF0cml4KHRyOiBUcmFuc2Zvcm0sIGlkOiBDYW5vbmljYWxUaWxlSUQpOiBGbG9hdDMyQXJyYXkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG4gICAgICAgIHJldHVybiBpZGVudGl0eTtcbiAgICB9XG5cbiAgICBjcmVhdGVUaWxlTWF0cml4KHRyOiBUcmFuc2Zvcm0sIHdvcmxkU2l6ZTogbnVtYmVyLCBpZDogVW53cmFwcGVkVGlsZUlEKTogRmxvYXQ2NEFycmF5IHtcbiAgICAgICAgbGV0IHNjYWxlLCBzY2FsZWRYLCBzY2FsZWRZO1xuICAgICAgICBjb25zdCBjYW5vbmljYWwgPSBpZC5jYW5vbmljYWw7XG4gICAgICAgIGNvbnN0IHBvc01hdHJpeCA9IG1hdDQuaWRlbnRpdHkobmV3IEZsb2F0NjRBcnJheSgxNikpO1xuXG4gICAgICAgIGlmICh0aGlzLmlzUmVwcm9qZWN0ZWRJblRpbGVTcGFjZSkge1xuICAgICAgICAgICAgY29uc3QgY3MgPSB0aWxlVHJhbnNmb3JtKGNhbm9uaWNhbCwgdGhpcyk7XG4gICAgICAgICAgICBzY2FsZSA9IDE7XG4gICAgICAgICAgICBzY2FsZWRYID0gY3MueCArIGlkLndyYXAgKiBjcy5zY2FsZTtcbiAgICAgICAgICAgIHNjYWxlZFkgPSBjcy55O1xuICAgICAgICAgICAgbWF0NC5zY2FsZShwb3NNYXRyaXgsIHBvc01hdHJpeCwgW3NjYWxlIC8gY3Muc2NhbGUsIHNjYWxlIC8gY3Muc2NhbGUsIHRyLnBpeGVsc1Blck1ldGVyIC8gd29ybGRTaXplXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzY2FsZSA9IHdvcmxkU2l6ZSAvIHRyLnpvb21TY2FsZShjYW5vbmljYWwueik7XG4gICAgICAgICAgICBjb25zdCB1bndyYXBwZWRYID0gY2Fub25pY2FsLnggKyBNYXRoLnBvdygyLCBjYW5vbmljYWwueikgKiBpZC53cmFwO1xuICAgICAgICAgICAgc2NhbGVkWCA9IHVud3JhcHBlZFggKiBzY2FsZTtcbiAgICAgICAgICAgIHNjYWxlZFkgPSBjYW5vbmljYWwueSAqIHNjYWxlO1xuICAgICAgICB9XG5cbiAgICAgICAgbWF0NC50cmFuc2xhdGUocG9zTWF0cml4LCBwb3NNYXRyaXgsIFtzY2FsZWRYLCBzY2FsZWRZLCAwXSk7XG4gICAgICAgIG1hdDQuc2NhbGUocG9zTWF0cml4LCBwb3NNYXRyaXgsIFtzY2FsZSAvIEVYVEVOVCwgc2NhbGUgLyBFWFRFTlQsIDFdKTtcblxuICAgICAgICByZXR1cm4gcG9zTWF0cml4O1xuICAgIH1cblxuICAgIHVwVmVjdG9yKGlkOiBDYW5vbmljYWxUaWxlSUQsIHg6IG51bWJlciwgeTogbnVtYmVyKTogVmVjMyB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbiAgICAgICAgcmV0dXJuIFswLCAwLCAxXTtcbiAgICB9XG5cbiAgICB1cFZlY3RvclNjYWxlKGlkOiBDYW5vbmljYWxUaWxlSUQsIGxhdGl0dWRlOiBudW1iZXIsIHdvcmxkU2l6ZTogbnVtYmVyKTogRWxldmF0aW9uU2NhbGUgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG4gICAgICAgIHJldHVybiB7bWV0ZXJzVG9UaWxlOiAxfTtcbiAgICB9XG59XG4iLCIvLyBAZmxvd1xuaW1wb3J0IExuZ0xhdCBmcm9tICcuLi9sbmdfbGF0LmpzJztcbmltcG9ydCB7Y2xhbXAsIHdyYXAsIGRlZ1RvUmFkLCByYWRUb0RlZ30gZnJvbSAnLi4vLi4vdXRpbC91dGlsLmpzJztcbmltcG9ydCB7TUFYX01FUkNBVE9SX0xBVElUVURFfSBmcm9tICcuLi9tZXJjYXRvcl9jb29yZGluYXRlLmpzJztcbmltcG9ydCBQcm9qZWN0aW9uIGZyb20gJy4vcHJvamVjdGlvbi5qcyc7XG5cbmltcG9ydCB0eXBlIHtQcm9qZWN0aW9uU3BlY2lmaWNhdGlvbn0gZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy90eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSB7UHJvamVjdGVkUG9pbnR9IGZyb20gJy4vcHJvamVjdGlvbi5qcyc7XG5cbi8vIGJhc2VkIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9kMy9kMy1nZW8tcHJvamVjdGlvbiwgTUlULWxpY2Vuc2VkXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBBbGJlcnMgZXh0ZW5kcyBQcm9qZWN0aW9uIHtcbiAgICBuOiBudW1iZXI7XG4gICAgYzogbnVtYmVyO1xuICAgIHIwOiBudW1iZXI7XG5cbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zOiBQcm9qZWN0aW9uU3BlY2lmaWNhdGlvbikge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgdGhpcy5yYW5nZSA9IFs0LCA3XTtcbiAgICAgICAgdGhpcy5jZW50ZXIgPSBvcHRpb25zLmNlbnRlciB8fCBbLTk2LCAzNy41XTtcbiAgICAgICAgY29uc3QgW2xhdDAsIGxhdDFdID0gdGhpcy5wYXJhbGxlbHMgPSBvcHRpb25zLnBhcmFsbGVscyB8fCBbMjkuNSwgNDUuNV07XG5cbiAgICAgICAgY29uc3Qgc3kwID0gTWF0aC5zaW4oZGVnVG9SYWQobGF0MCkpO1xuICAgICAgICB0aGlzLm4gPSAoc3kwICsgTWF0aC5zaW4oZGVnVG9SYWQobGF0MSkpKSAvIDI7XG4gICAgICAgIHRoaXMuYyA9IDEgKyBzeTAgKiAoMiAqIHRoaXMubiAtIHN5MCk7XG4gICAgICAgIHRoaXMucjAgPSBNYXRoLnNxcnQodGhpcy5jKSAvIHRoaXMubjtcbiAgICB9XG5cbiAgICBwcm9qZWN0KGxuZzogbnVtYmVyLCBsYXQ6IG51bWJlcik6IFByb2plY3RlZFBvaW50IHtcbiAgICAgICAgY29uc3Qge24sIGMsIHIwfSA9IHRoaXM7XG4gICAgICAgIGNvbnN0IGxhbWJkYSA9IGRlZ1RvUmFkKGxuZyAtIHRoaXMuY2VudGVyWzBdKTtcbiAgICAgICAgY29uc3QgcGhpID0gZGVnVG9SYWQobGF0KTtcblxuICAgICAgICBjb25zdCByID0gTWF0aC5zcXJ0KGMgLSAyICogbiAqIE1hdGguc2luKHBoaSkpIC8gbjtcbiAgICAgICAgY29uc3QgeCA9IHIgKiBNYXRoLnNpbihsYW1iZGEgKiBuKTtcbiAgICAgICAgY29uc3QgeSA9IHIgKiBNYXRoLmNvcyhsYW1iZGEgKiBuKSAtIHIwO1xuICAgICAgICByZXR1cm4ge3gsIHksIHo6IDB9O1xuICAgIH1cblxuICAgIHVucHJvamVjdCh4OiBudW1iZXIsIHk6IG51bWJlcik6IExuZ0xhdCB7XG4gICAgICAgIGNvbnN0IHtuLCBjLCByMH0gPSB0aGlzO1xuICAgICAgICBjb25zdCByMHkgPSByMCArIHk7XG4gICAgICAgIGxldCBsID0gTWF0aC5hdGFuMih4LCBNYXRoLmFicyhyMHkpKSAqIE1hdGguc2lnbihyMHkpO1xuICAgICAgICBpZiAocjB5ICogbiA8IDApIHtcbiAgICAgICAgICAgIGwgLT0gTWF0aC5QSSAqIE1hdGguc2lnbih4KSAqIE1hdGguc2lnbihyMHkpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGR0ID0gZGVnVG9SYWQodGhpcy5jZW50ZXJbMF0pICogbjtcbiAgICAgICAgbCA9IHdyYXAobCwgLU1hdGguUEkgLSBkdCwgTWF0aC5QSSAtIGR0KTtcblxuICAgICAgICBjb25zdCBsbmcgPSBjbGFtcChyYWRUb0RlZyhsIC8gbikgKyB0aGlzLmNlbnRlclswXSwgLTE4MCwgMTgwKTtcbiAgICAgICAgY29uc3QgcGhpID0gTWF0aC5hc2luKGNsYW1wKChjIC0gKHggKiB4ICsgcjB5ICogcjB5KSAqIG4gKiBuKSAvICgyICogbiksIC0xLCAxKSk7XG4gICAgICAgIGNvbnN0IGxhdCA9IGNsYW1wKHJhZFRvRGVnKHBoaSksIC1NQVhfTUVSQ0FUT1JfTEFUSVRVREUsIE1BWF9NRVJDQVRPUl9MQVRJVFVERSk7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBMbmdMYXQobG5nLCBsYXQpO1xuICAgIH1cbn1cbiIsIi8vIEBmbG93XG5pbXBvcnQgTG5nTGF0IGZyb20gJy4uL2xuZ19sYXQuanMnO1xuaW1wb3J0IHtjbGFtcH0gZnJvbSAnLi4vLi4vdXRpbC91dGlsLmpzJztcbmltcG9ydCB7TUFYX01FUkNBVE9SX0xBVElUVURFfSBmcm9tICcuLi9tZXJjYXRvcl9jb29yZGluYXRlLmpzJztcbmltcG9ydCBQcm9qZWN0aW9uIGZyb20gJy4vcHJvamVjdGlvbi5qcyc7XG5cbmltcG9ydCB0eXBlIHtQcm9qZWN0ZWRQb2ludH0gZnJvbSAnLi9wcm9qZWN0aW9uLmpzJztcblxuY29uc3QgYTEgPSAxLjM0MDI2NDtcbmNvbnN0IGEyID0gLTAuMDgxMTA2O1xuY29uc3QgYTMgPSAwLjAwMDg5MztcbmNvbnN0IGE0ID0gMC4wMDM3OTY7XG5jb25zdCBNID0gTWF0aC5zcXJ0KDMpIC8gMjtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRXF1YWxFYXJ0aCBleHRlbmRzIFByb2plY3Rpb24ge1xuXG4gICAgcHJvamVjdChsbmc6IG51bWJlciwgbGF0OiBudW1iZXIpOiBQcm9qZWN0ZWRQb2ludCB7XG4gICAgICAgIC8vIGJhc2VkIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9kMy9kMy1nZW8sIE1JVC1saWNlbnNlZFxuICAgICAgICBsYXQgPSBsYXQgLyAxODAgKiBNYXRoLlBJO1xuICAgICAgICBsbmcgPSBsbmcgLyAxODAgKiBNYXRoLlBJO1xuICAgICAgICBjb25zdCB0aGV0YSA9IE1hdGguYXNpbihNICogTWF0aC5zaW4obGF0KSk7XG4gICAgICAgIGNvbnN0IHRoZXRhMiA9IHRoZXRhICogdGhldGE7XG4gICAgICAgIGNvbnN0IHRoZXRhNiA9IHRoZXRhMiAqIHRoZXRhMiAqIHRoZXRhMjtcbiAgICAgICAgY29uc3QgeCA9IGxuZyAqIE1hdGguY29zKHRoZXRhKSAvIChNICogKGExICsgMyAqIGEyICogdGhldGEyICsgdGhldGE2ICogKDcgKiBhMyArIDkgKiBhNCAqIHRoZXRhMikpKTtcbiAgICAgICAgY29uc3QgeSA9IHRoZXRhICogKGExICsgYTIgKiB0aGV0YTIgKyB0aGV0YTYgKiAoYTMgKyBhNCAqIHRoZXRhMikpO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiAoeCAvIE1hdGguUEkgKyAwLjUpICogMC41LFxuICAgICAgICAgICAgeTogMSAtICh5IC8gTWF0aC5QSSArIDEpICogMC41LFxuICAgICAgICAgICAgejogMFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHVucHJvamVjdCh4OiBudW1iZXIsIHk6IG51bWJlcik6IExuZ0xhdCB7XG4gICAgICAgIC8vIGJhc2VkIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9kMy9kMy1nZW8sIE1JVC1saWNlbnNlZFxuICAgICAgICB4ID0gKDIgKiB4IC0gMC41KSAqIE1hdGguUEk7XG4gICAgICAgIHkgPSAoMiAqICgxIC0geSkgLSAxKSAqIE1hdGguUEk7XG4gICAgICAgIGxldCB0aGV0YSA9IHk7XG4gICAgICAgIGxldCB0aGV0YTIgPSB0aGV0YSAqIHRoZXRhO1xuICAgICAgICBsZXQgdGhldGE2ID0gdGhldGEyICogdGhldGEyICogdGhldGEyO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBkZWx0YSwgZnksIGZweTsgaSA8IDEyOyArK2kpIHtcbiAgICAgICAgICAgIGZ5ID0gdGhldGEgKiAoYTEgKyBhMiAqIHRoZXRhMiArIHRoZXRhNiAqIChhMyArIGE0ICogdGhldGEyKSkgLSB5O1xuICAgICAgICAgICAgZnB5ID0gYTEgKyAzICogYTIgKiB0aGV0YTIgKyB0aGV0YTYgKiAoNyAqIGEzICsgOSAqIGE0ICogdGhldGEyKTtcbiAgICAgICAgICAgIGRlbHRhID0gZnkgLyBmcHk7XG4gICAgICAgICAgICB0aGV0YSA9IGNsYW1wKHRoZXRhIC0gZGVsdGEsIC1NYXRoLlBJIC8gMywgTWF0aC5QSSAvIDMpO1xuICAgICAgICAgICAgdGhldGEyID0gdGhldGEgKiB0aGV0YTtcbiAgICAgICAgICAgIHRoZXRhNiA9IHRoZXRhMiAqIHRoZXRhMiAqIHRoZXRhMjtcbiAgICAgICAgICAgIGlmIChNYXRoLmFicyhkZWx0YSkgPCAxZS0xMikgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBsYW1iZGEgPSBNICogeCAqIChhMSArIDMgKiBhMiAqIHRoZXRhMiArIHRoZXRhNiAqICg3ICogYTMgKyA5ICogYTQgKiB0aGV0YTIpKSAvIE1hdGguY29zKHRoZXRhKTtcbiAgICAgICAgY29uc3QgcGhpID0gTWF0aC5hc2luKE1hdGguc2luKHRoZXRhKSAvIE0pO1xuICAgICAgICBjb25zdCBsbmcgPSBjbGFtcChsYW1iZGEgKiAxODAgLyBNYXRoLlBJLCAtMTgwLCAxODApO1xuICAgICAgICBjb25zdCBsYXQgPSBjbGFtcChwaGkgKiAxODAgLyBNYXRoLlBJLCAtTUFYX01FUkNBVE9SX0xBVElUVURFLCBNQVhfTUVSQ0FUT1JfTEFUSVRVREUpO1xuXG4gICAgICAgIHJldHVybiBuZXcgTG5nTGF0KGxuZywgbGF0KTtcbiAgICB9XG59XG4iLCIvLyBAZmxvd1xuaW1wb3J0IExuZ0xhdCBmcm9tICcuLi9sbmdfbGF0LmpzJztcbmltcG9ydCB7Y2xhbXB9IGZyb20gJy4uLy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQge01BWF9NRVJDQVRPUl9MQVRJVFVERX0gZnJvbSAnLi4vbWVyY2F0b3JfY29vcmRpbmF0ZS5qcyc7XG5pbXBvcnQgUHJvamVjdGlvbiBmcm9tICcuL3Byb2plY3Rpb24uanMnO1xuXG5pbXBvcnQgdHlwZSB7UHJvamVjdGlvblNwZWNpZmljYXRpb259IGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge1Byb2plY3RlZFBvaW50fSBmcm9tICcuL3Byb2plY3Rpb24uanMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBFcXVpcmVjdGFuZ3VsYXIgZXh0ZW5kcyBQcm9qZWN0aW9uIHtcblxuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFByb2plY3Rpb25TcGVjaWZpY2F0aW9uKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICB0aGlzLndyYXAgPSB0cnVlO1xuICAgICAgICB0aGlzLnN1cHBvcnRzV29ybGRDb3BpZXMgPSB0cnVlO1xuICAgIH1cblxuICAgIHByb2plY3QobG5nOiBudW1iZXIsIGxhdDogbnVtYmVyKTogUHJvamVjdGVkUG9pbnQge1xuICAgICAgICBjb25zdCB4ID0gMC41ICsgbG5nIC8gMzYwO1xuICAgICAgICBjb25zdCB5ID0gMC41IC0gbGF0IC8gMzYwO1xuICAgICAgICByZXR1cm4ge3gsIHksIHo6IDB9O1xuICAgIH1cblxuICAgIHVucHJvamVjdCh4OiBudW1iZXIsIHk6IG51bWJlcik6IExuZ0xhdCB7XG4gICAgICAgIGNvbnN0IGxuZyA9ICh4IC0gMC41KSAqIDM2MDtcbiAgICAgICAgY29uc3QgbGF0ID0gY2xhbXAoKDAuNSAtIHkpICogMzYwLCAtTUFYX01FUkNBVE9SX0xBVElUVURFLCBNQVhfTUVSQ0FUT1JfTEFUSVRVREUpO1xuICAgICAgICByZXR1cm4gbmV3IExuZ0xhdChsbmcsIGxhdCk7XG4gICAgfVxufVxuIiwiLy8gQGZsb3dcbmltcG9ydCBMbmdMYXQgZnJvbSAnLi4vbG5nX2xhdC5qcyc7XG5pbXBvcnQge2NsYW1wLCBkZWdUb1JhZCwgcmFkVG9EZWd9IGZyb20gJy4uLy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQge01BWF9NRVJDQVRPUl9MQVRJVFVERX0gZnJvbSAnLi4vbWVyY2F0b3JfY29vcmRpbmF0ZS5qcyc7XG5pbXBvcnQgUHJvamVjdGlvbiBmcm9tICcuL3Byb2plY3Rpb24uanMnO1xuXG5pbXBvcnQgdHlwZSB7UHJvamVjdGlvblNwZWNpZmljYXRpb259IGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge1Byb2plY3RlZFBvaW50fSBmcm9tICcuL3Byb2plY3Rpb24uanMnO1xuXG5jb25zdCBoYWxmUGkgPSBNYXRoLlBJIC8gMjtcblxuZnVuY3Rpb24gdGFueSh5OiBudW1iZXIpIHtcbiAgICByZXR1cm4gTWF0aC50YW4oKGhhbGZQaSArIHkpIC8gMik7XG59XG5cbi8vIGJhc2VkIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9kMy9kMy1nZW8sIE1JVC1saWNlbnNlZFxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTGFtYmVydENvbmZvcm1hbENvbmljIGV4dGVuZHMgUHJvamVjdGlvbiB7XG4gICAgbjogbnVtYmVyO1xuICAgIGY6IG51bWJlcjtcbiAgICBzb3V0aGVybkNlbnRlcjogYm9vbGVhbjtcblxuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFByb2plY3Rpb25TcGVjaWZpY2F0aW9uKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICB0aGlzLmNlbnRlciA9IG9wdGlvbnMuY2VudGVyIHx8IFswLCAzMF07XG4gICAgICAgIGNvbnN0IFtsYXQwLCBsYXQxXSA9IHRoaXMucGFyYWxsZWxzID0gb3B0aW9ucy5wYXJhbGxlbHMgfHwgWzMwLCAzMF07XG5cbiAgICAgICAgbGV0IHkwID0gZGVnVG9SYWQobGF0MCk7XG4gICAgICAgIGxldCB5MSA9IGRlZ1RvUmFkKGxhdDEpO1xuICAgICAgICAvLyBSdW4gcHJvamVjdGlvbiBtYXRoIG9uIGludmVydGVkIGxhdHRpdHVkZXMgaWYgdGhlIHBhcmFsZWxsIGxpbmVzIGFyZSBzb3V0aCBvZiB0aGUgZXF1YXRvclxuICAgICAgICAvLyBUaGlzIGZpeGVzIGRpdmlkZSBieSB6ZXJvIGVycm9ycyB3aXRoIGEgU291dGggcG9sYXIgcHJvamVjdGlvblxuICAgICAgICB0aGlzLnNvdXRoZXJuQ2VudGVyID0gKHkwICsgeTEpIDwgMDtcbiAgICAgICAgaWYgKHRoaXMuc291dGhlcm5DZW50ZXIpIHtcbiAgICAgICAgICAgIHkwID0gLXkwO1xuICAgICAgICAgICAgeTEgPSAteTE7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY3kwID0gTWF0aC5jb3MoeTApO1xuICAgICAgICBjb25zdCB0YW55MCA9IHRhbnkoeTApO1xuXG4gICAgICAgIHRoaXMubiA9IHkwID09PSB5MSA/IE1hdGguc2luKHkwKSA6IE1hdGgubG9nKGN5MCAvIE1hdGguY29zKHkxKSkgLyBNYXRoLmxvZyh0YW55KHkxKSAvIHRhbnkwKTtcbiAgICAgICAgdGhpcy5mID0gY3kwICogTWF0aC5wb3codGFueSh5MCksIHRoaXMubikgLyB0aGlzLm47XG4gICAgfVxuXG4gICAgcHJvamVjdChsbmc6IG51bWJlciwgbGF0OiBudW1iZXIpOiBQcm9qZWN0ZWRQb2ludCB7XG4gICAgICAgIGxhdCA9IGRlZ1RvUmFkKGxhdCk7XG4gICAgICAgIGlmICh0aGlzLnNvdXRoZXJuQ2VudGVyKSBsYXQgPSAtbGF0O1xuICAgICAgICBsbmcgPSBkZWdUb1JhZChsbmcgLSB0aGlzLmNlbnRlclswXSk7XG5cbiAgICAgICAgY29uc3QgZXBzaWxvbiA9IDFlLTY7XG4gICAgICAgIGNvbnN0IHtuLCBmfSA9IHRoaXM7XG5cbiAgICAgICAgaWYgKGYgPiAwKSB7XG4gICAgICAgICAgICBpZiAobGF0IDwgLWhhbGZQaSArIGVwc2lsb24pIGxhdCA9IC1oYWxmUGkgKyBlcHNpbG9uO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGxhdCA+IGhhbGZQaSAtIGVwc2lsb24pIGxhdCA9IGhhbGZQaSAtIGVwc2lsb247XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByID0gZiAvIE1hdGgucG93KHRhbnkobGF0KSwgbik7XG4gICAgICAgIGxldCB4ID0gciAqIE1hdGguc2luKG4gKiBsbmcpO1xuICAgICAgICBsZXQgeSA9IGYgLSByICogTWF0aC5jb3MobiAqIGxuZyk7XG4gICAgICAgIHggPSAoeCAvIE1hdGguUEkgKyAwLjUpICogMC41O1xuICAgICAgICB5ID0gKHkgLyBNYXRoLlBJICsgMC41KSAqIDAuNTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeCxcbiAgICAgICAgICAgIHk6IHRoaXMuc291dGhlcm5DZW50ZXIgPyB5IDogMSAtIHksXG4gICAgICAgICAgICB6OiAwXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgdW5wcm9qZWN0KHg6IG51bWJlciwgeTogbnVtYmVyKTogTG5nTGF0IHtcbiAgICAgICAgeCA9ICgyICogeCAtIDAuNSkgKiBNYXRoLlBJO1xuICAgICAgICBpZiAodGhpcy5zb3V0aGVybkNlbnRlcikgeSA9IDEgLSB5O1xuICAgICAgICB5ID0gKDIgKiAoMSAtIHkpIC0gMC41KSAqIE1hdGguUEk7XG4gICAgICAgIGNvbnN0IHtuLCBmfSA9IHRoaXM7XG4gICAgICAgIGNvbnN0IGZ5ID0gZiAtIHk7XG4gICAgICAgIGNvbnN0IHNpZ25GeSA9IE1hdGguc2lnbihmeSk7XG4gICAgICAgIGNvbnN0IHIgPSBNYXRoLnNpZ24obikgKiBNYXRoLnNxcnQoeCAqIHggKyBmeSAqIGZ5KTtcbiAgICAgICAgbGV0IGwgPSBNYXRoLmF0YW4yKHgsIE1hdGguYWJzKGZ5KSkgKiBzaWduRnk7XG5cbiAgICAgICAgaWYgKGZ5ICogbiA8IDApIGwgLT0gTWF0aC5QSSAqIE1hdGguc2lnbih4KSAqIHNpZ25GeTtcblxuICAgICAgICBjb25zdCBsbmcgPSBjbGFtcChyYWRUb0RlZyhsIC8gbikgKyB0aGlzLmNlbnRlclswXSwgLTE4MCwgMTgwKTtcbiAgICAgICAgY29uc3QgcGhpID0gMiAqIE1hdGguYXRhbihNYXRoLnBvdyhmIC8gciwgMSAvIG4pKSAtIGhhbGZQaTtcbiAgICAgICAgY29uc3QgbGF0ID0gY2xhbXAocmFkVG9EZWcocGhpKSwgLU1BWF9NRVJDQVRPUl9MQVRJVFVERSwgTUFYX01FUkNBVE9SX0xBVElUVURFKTtcblxuICAgICAgICByZXR1cm4gbmV3IExuZ0xhdChsbmcsIHRoaXMuc291dGhlcm5DZW50ZXIgPyAtbGF0IDogbGF0KTtcbiAgICB9XG59XG4iLCIvLyBAZmxvd1xuaW1wb3J0IExuZ0xhdCBmcm9tICcuLi9sbmdfbGF0LmpzJztcbmltcG9ydCB7bWVyY2F0b3JYZnJvbUxuZywgbWVyY2F0b3JZZnJvbUxhdCwgbG5nRnJvbU1lcmNhdG9yWCwgbGF0RnJvbU1lcmNhdG9yWX0gZnJvbSAnLi4vbWVyY2F0b3JfY29vcmRpbmF0ZS5qcyc7XG5pbXBvcnQgUHJvamVjdGlvbiBmcm9tICcuL3Byb2plY3Rpb24uanMnO1xuXG5pbXBvcnQgdHlwZSB7UHJvamVjdGlvblNwZWNpZmljYXRpb259IGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge1Byb2plY3RlZFBvaW50fSBmcm9tICcuL3Byb2plY3Rpb24uanMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNZXJjYXRvciBleHRlbmRzIFByb2plY3Rpb24ge1xuXG4gICAgY29uc3RydWN0b3Iob3B0aW9uczogUHJvamVjdGlvblNwZWNpZmljYXRpb24pIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIHRoaXMud3JhcCA9IHRydWU7XG4gICAgICAgIHRoaXMuc3VwcG9ydHNXb3JsZENvcGllcyA9IHRydWU7XG4gICAgICAgIHRoaXMuc3VwcG9ydHNUZXJyYWluID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5zdXBwb3J0c0ZvZyA9IHRydWU7XG4gICAgICAgIHRoaXMuc3VwcG9ydHNGcmVlQ2FtZXJhID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5pc1JlcHJvamVjdGVkSW5UaWxlU3BhY2UgPSBmYWxzZTtcbiAgICAgICAgdGhpcy51bnN1cHBvcnRlZExheWVycyA9IFtdO1xuICAgICAgICB0aGlzLnJhbmdlID0gbnVsbDtcbiAgICB9XG5cbiAgICBwcm9qZWN0KGxuZzogbnVtYmVyLCBsYXQ6IG51bWJlcik6IFByb2plY3RlZFBvaW50IHtcbiAgICAgICAgY29uc3QgeCA9IG1lcmNhdG9yWGZyb21MbmcobG5nKTtcbiAgICAgICAgY29uc3QgeSA9IG1lcmNhdG9yWWZyb21MYXQobGF0KTtcbiAgICAgICAgcmV0dXJuIHt4LCB5LCB6OiAwfTtcbiAgICB9XG5cbiAgICB1bnByb2plY3QoeDogbnVtYmVyLCB5OiBudW1iZXIpOiBMbmdMYXQge1xuICAgICAgICBjb25zdCBsbmcgPSBsbmdGcm9tTWVyY2F0b3JYKHgpO1xuICAgICAgICBjb25zdCBsYXQgPSBsYXRGcm9tTWVyY2F0b3JZKHkpO1xuICAgICAgICByZXR1cm4gbmV3IExuZ0xhdChsbmcsIGxhdCk7XG4gICAgfVxufVxuIiwiLy8gQGZsb3dcbmltcG9ydCBMbmdMYXQgZnJvbSAnLi4vbG5nX2xhdC5qcyc7XG5pbXBvcnQge2NsYW1wLCBkZWdUb1JhZCwgcmFkVG9EZWd9IGZyb20gJy4uLy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQge01BWF9NRVJDQVRPUl9MQVRJVFVERX0gZnJvbSAnLi4vbWVyY2F0b3JfY29vcmRpbmF0ZS5qcyc7XG5pbXBvcnQgUHJvamVjdGlvbiBmcm9tICcuL3Byb2plY3Rpb24uanMnO1xuXG5pbXBvcnQgdHlwZSB7UHJvamVjdGVkUG9pbnR9IGZyb20gJy4vcHJvamVjdGlvbi5qcyc7XG5cbmNvbnN0IG1heFBoaSA9IGRlZ1RvUmFkKE1BWF9NRVJDQVRPUl9MQVRJVFVERSk7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE5hdHVyYWxFYXJ0aCBleHRlbmRzIFByb2plY3Rpb24ge1xuXG4gICAgcHJvamVjdChsbmc6IG51bWJlciwgbGF0OiBudW1iZXIpOiBQcm9qZWN0ZWRQb2ludCB7XG4gICAgICAgIC8vIGJhc2VkIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9kMy9kMy1nZW8sIE1JVC1saWNlbnNlZFxuICAgICAgICBsYXQgPSBkZWdUb1JhZChsYXQpO1xuICAgICAgICBsbmcgPSBkZWdUb1JhZChsbmcpO1xuXG4gICAgICAgIGNvbnN0IHBoaTIgPSBsYXQgKiBsYXQ7XG4gICAgICAgIGNvbnN0IHBoaTQgPSBwaGkyICogcGhpMjtcbiAgICAgICAgY29uc3QgeCA9IGxuZyAqICgwLjg3MDcgLSAwLjEzMTk3OSAqIHBoaTIgKyBwaGk0ICogKC0wLjAxMzc5MSArIHBoaTQgKiAoMC4wMDM5NzEgKiBwaGkyIC0gMC4wMDE1MjkgKiBwaGk0KSkpO1xuICAgICAgICBjb25zdCB5ID0gbGF0ICogKDEuMDA3MjI2ICsgcGhpMiAqICgwLjAxNTA4NSArIHBoaTQgKiAoLTAuMDQ0NDc1ICsgMC4wMjg4NzQgKiBwaGkyIC0gMC4wMDU5MTYgKiBwaGk0KSkpO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiAoeCAvIE1hdGguUEkgKyAwLjUpICogMC41LFxuICAgICAgICAgICAgeTogMSAtICh5IC8gTWF0aC5QSSArIDEpICogMC41LFxuICAgICAgICAgICAgejogMFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHVucHJvamVjdCh4OiBudW1iZXIsIHk6IG51bWJlcik6IExuZ0xhdCB7XG4gICAgICAgIC8vIGJhc2VkIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9kMy9kMy1nZW8sIE1JVC1saWNlbnNlZFxuICAgICAgICB4ID0gKDIgKiB4IC0gMC41KSAqIE1hdGguUEk7XG4gICAgICAgIHkgPSAoMiAqICgxIC0geSkgLSAxKSAqIE1hdGguUEk7XG4gICAgICAgIGNvbnN0IGVwc2lsb24gPSAxZS02O1xuICAgICAgICBsZXQgcGhpID0geTtcbiAgICAgICAgbGV0IGkgPSAyNTtcbiAgICAgICAgbGV0IGRlbHRhID0gMDtcbiAgICAgICAgbGV0IHBoaTIgPSBwaGkgKiBwaGk7XG5cbiAgICAgICAgZG8ge1xuICAgICAgICAgICAgcGhpMiA9IHBoaSAqIHBoaTtcbiAgICAgICAgICAgIGNvbnN0IHBoaTQgPSBwaGkyICogcGhpMjtcbiAgICAgICAgICAgIGRlbHRhID0gKHBoaSAqICgxLjAwNzIyNiArIHBoaTIgKiAoMC4wMTUwODUgKyBwaGk0ICogKC0wLjA0NDQ3NSArIDAuMDI4ODc0ICogcGhpMiAtIDAuMDA1OTE2ICogcGhpNCkpKSAtIHkpIC9cbiAgICAgICAgICAgICAgICAoMS4wMDcyMjYgKyBwaGkyICogKDAuMDE1MDg1ICogMyArIHBoaTQgKiAoLTAuMDQ0NDc1ICogNyArIDAuMDI4ODc0ICogOSAqIHBoaTIgLSAwLjAwNTkxNiAqIDExICogcGhpNCkpKTtcbiAgICAgICAgICAgIHBoaSA9IGNsYW1wKHBoaSAtIGRlbHRhLCAtbWF4UGhpLCBtYXhQaGkpO1xuICAgICAgICB9IHdoaWxlIChNYXRoLmFicyhkZWx0YSkgPiBlcHNpbG9uICYmIC0taSA+IDApO1xuXG4gICAgICAgIHBoaTIgPSBwaGkgKiBwaGk7XG4gICAgICAgIGNvbnN0IGxhbWJkYSA9IHggLyAoMC44NzA3ICsgcGhpMiAqICgtMC4xMzE5NzkgKyBwaGkyICogKC0wLjAxMzc5MSArIHBoaTIgKiBwaGkyICogcGhpMiAqICgwLjAwMzk3MSAtIDAuMDAxNTI5ICogcGhpMikpKSk7XG5cbiAgICAgICAgY29uc3QgbG5nID0gY2xhbXAocmFkVG9EZWcobGFtYmRhKSwgLTE4MCwgMTgwKTtcbiAgICAgICAgY29uc3QgbGF0ID0gcmFkVG9EZWcocGhpKTtcblxuICAgICAgICByZXR1cm4gbmV3IExuZ0xhdChsbmcsIGxhdCk7XG4gICAgfVxufVxuIiwiLy8gQGZsb3dcbmltcG9ydCBMbmdMYXQgZnJvbSAnLi4vbG5nX2xhdC5qcyc7XG5pbXBvcnQge2NsYW1wLCBkZWdUb1JhZCwgcmFkVG9EZWd9IGZyb20gJy4uLy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQge01BWF9NRVJDQVRPUl9MQVRJVFVERX0gZnJvbSAnLi4vbWVyY2F0b3JfY29vcmRpbmF0ZS5qcyc7XG5pbXBvcnQgUHJvamVjdGlvbiBmcm9tICcuL3Byb2plY3Rpb24uanMnO1xuXG5pbXBvcnQgdHlwZSB7UHJvamVjdGVkUG9pbnR9IGZyb20gJy4vcHJvamVjdGlvbi5qcyc7XG5cbmNvbnN0IG1heFBoaSA9IGRlZ1RvUmFkKE1BWF9NRVJDQVRPUl9MQVRJVFVERSk7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFdpbmtlbFRyaXBlbCBleHRlbmRzIFByb2plY3Rpb24ge1xuXG4gICAgcHJvamVjdChsbmc6IG51bWJlciwgbGF0OiBudW1iZXIpOiBQcm9qZWN0ZWRQb2ludCB7XG4gICAgICAgIGxhdCA9IGRlZ1RvUmFkKGxhdCk7XG4gICAgICAgIGxuZyA9IGRlZ1RvUmFkKGxuZyk7XG4gICAgICAgIGNvbnN0IGNvc0xhdCA9IE1hdGguY29zKGxhdCk7XG4gICAgICAgIGNvbnN0IHR3b092ZXJQaSA9IDIgLyBNYXRoLlBJO1xuICAgICAgICBjb25zdCBhbHBoYSA9IE1hdGguYWNvcyhjb3NMYXQgKiBNYXRoLmNvcyhsbmcgLyAyKSk7XG4gICAgICAgIGNvbnN0IHNpbkFscGhhT3ZlckFscGhhID0gTWF0aC5zaW4oYWxwaGEpIC8gYWxwaGE7XG4gICAgICAgIGNvbnN0IHggPSAwLjUgKiAobG5nICogdHdvT3ZlclBpICsgKDIgKiBjb3NMYXQgKiBNYXRoLnNpbihsbmcgLyAyKSkgLyBzaW5BbHBoYU92ZXJBbHBoYSkgfHwgMDtcbiAgICAgICAgY29uc3QgeSA9IDAuNSAqIChsYXQgKyBNYXRoLnNpbihsYXQpIC8gc2luQWxwaGFPdmVyQWxwaGEpIHx8IDA7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiAoeCAvIE1hdGguUEkgKyAwLjUpICogMC41LFxuICAgICAgICAgICAgeTogMSAtICh5IC8gTWF0aC5QSSArIDEpICogMC41LFxuICAgICAgICAgICAgejogMFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHVucHJvamVjdCh4OiBudW1iZXIsIHk6IG51bWJlcik6IExuZ0xhdCB7XG4gICAgICAgIC8vIGJhc2VkIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9kMy9kMy1nZW8tcHJvamVjdGlvbiwgTUlULWxpY2Vuc2VkXG4gICAgICAgIHggPSAoMiAqIHggLSAwLjUpICogTWF0aC5QSTtcbiAgICAgICAgeSA9ICgyICogKDEgLSB5KSAtIDEpICogTWF0aC5QSTtcbiAgICAgICAgbGV0IGxhbWJkYSA9IHg7XG4gICAgICAgIGxldCBwaGkgPSB5O1xuICAgICAgICBsZXQgaSA9IDI1O1xuICAgICAgICBjb25zdCBlcHNpbG9uID0gMWUtNjtcbiAgICAgICAgbGV0IGRsYW1iZGEgPSAwLCBkcGhpID0gMDtcbiAgICAgICAgZG8ge1xuICAgICAgICAgICAgY29uc3QgY29zcGhpID0gTWF0aC5jb3MocGhpKSxcbiAgICAgICAgICAgICAgICBzaW5waGkgPSBNYXRoLnNpbihwaGkpLFxuICAgICAgICAgICAgICAgIHNpbnBoaTIgPSAyICogc2lucGhpICogY29zcGhpLFxuICAgICAgICAgICAgICAgIHNpbjJwaGkgPSBzaW5waGkgKiBzaW5waGksXG4gICAgICAgICAgICAgICAgY29zMnBoaSA9IGNvc3BoaSAqIGNvc3BoaSxcbiAgICAgICAgICAgICAgICBjb3NsYW1iZGEyID0gTWF0aC5jb3MobGFtYmRhIC8gMiksXG4gICAgICAgICAgICAgICAgc2lubGFtYmRhMiA9IE1hdGguc2luKGxhbWJkYSAvIDIpLFxuICAgICAgICAgICAgICAgIHNpbmxhbWJkYSA9IDIgKiBjb3NsYW1iZGEyICogc2lubGFtYmRhMixcbiAgICAgICAgICAgICAgICBzaW4ybGFtYmRhMiA9IHNpbmxhbWJkYTIgKiBzaW5sYW1iZGEyLFxuICAgICAgICAgICAgICAgIEMgPSAxIC0gY29zMnBoaSAqIGNvc2xhbWJkYTIgKiBjb3NsYW1iZGEyLFxuICAgICAgICAgICAgICAgIEYgPSBDID8gMSAvIEMgOiAwLFxuICAgICAgICAgICAgICAgIEUgPSBDID8gTWF0aC5hY29zKGNvc3BoaSAqIGNvc2xhbWJkYTIpICogTWF0aC5zcXJ0KDEgLyBDKSA6IDAsXG4gICAgICAgICAgICAgICAgZnggPSAwLjUgKiAoMiAqIEUgKiBjb3NwaGkgKiBzaW5sYW1iZGEyICsgbGFtYmRhICogMiAvIE1hdGguUEkpIC0geCxcbiAgICAgICAgICAgICAgICBmeSA9IDAuNSAqIChFICogc2lucGhpICsgcGhpKSAtIHksXG4gICAgICAgICAgICAgICAgZHhkbGFtYmRhID0gMC41ICogRiAqIChjb3MycGhpICogc2luMmxhbWJkYTIgKyBFICogY29zcGhpICogY29zbGFtYmRhMiAqIHNpbjJwaGkpICsgMSAvIE1hdGguUEksXG4gICAgICAgICAgICAgICAgZHhkcGhpID0gRiAqIChzaW5sYW1iZGEgKiBzaW5waGkyIC8gNCAtIEUgKiBzaW5waGkgKiBzaW5sYW1iZGEyKSxcbiAgICAgICAgICAgICAgICBkeWRsYW1iZGEgPSAwLjEyNSAqIEYgKiAoc2lucGhpMiAqIHNpbmxhbWJkYTIgLSBFICogc2lucGhpICogY29zMnBoaSAqIHNpbmxhbWJkYSksXG4gICAgICAgICAgICAgICAgZHlkcGhpID0gMC41ICogRiAqIChzaW4ycGhpICogY29zbGFtYmRhMiArIEUgKiBzaW4ybGFtYmRhMiAqIGNvc3BoaSkgKyAwLjUsXG4gICAgICAgICAgICAgICAgZGVub21pbmF0b3IgPSBkeGRwaGkgKiBkeWRsYW1iZGEgLSBkeWRwaGkgKiBkeGRsYW1iZGE7XG5cbiAgICAgICAgICAgIGRsYW1iZGEgPSAoZnkgKiBkeGRwaGkgLSBmeCAqIGR5ZHBoaSkgLyBkZW5vbWluYXRvcjtcbiAgICAgICAgICAgIGRwaGkgPSAoZnggKiBkeWRsYW1iZGEgLSBmeSAqIGR4ZGxhbWJkYSkgLyBkZW5vbWluYXRvcjtcbiAgICAgICAgICAgIGxhbWJkYSA9IGNsYW1wKGxhbWJkYSAtIGRsYW1iZGEsIC1NYXRoLlBJLCBNYXRoLlBJKTtcbiAgICAgICAgICAgIHBoaSA9IGNsYW1wKHBoaSAtIGRwaGksIC1tYXhQaGksIG1heFBoaSk7XG5cbiAgICAgICAgfSB3aGlsZSAoKE1hdGguYWJzKGRsYW1iZGEpID4gZXBzaWxvbiB8fCBNYXRoLmFicyhkcGhpKSA+IGVwc2lsb24pICYmIC0taSA+IDApO1xuXG4gICAgICAgIHJldHVybiBuZXcgTG5nTGF0KHJhZFRvRGVnKGxhbWJkYSksIHJhZFRvRGVnKHBoaSkpO1xuICAgIH1cbn1cbiIsIi8vIEBmbG93XG5pbXBvcnQgTG5nTGF0IGZyb20gJy4uL2xuZ19sYXQuanMnO1xuaW1wb3J0IHtjbGFtcCwgZGVnVG9SYWQsIHJhZFRvRGVnfSBmcm9tICcuLi8uLi91dGlsL3V0aWwuanMnO1xuaW1wb3J0IHtNQVhfTUVSQ0FUT1JfTEFUSVRVREV9IGZyb20gJy4uL21lcmNhdG9yX2Nvb3JkaW5hdGUuanMnO1xuaW1wb3J0IFByb2plY3Rpb24gZnJvbSAnLi9wcm9qZWN0aW9uLmpzJztcblxuaW1wb3J0IHR5cGUge1Byb2plY3Rpb25TcGVjaWZpY2F0aW9ufSBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL3R5cGVzLmpzJztcbmltcG9ydCB0eXBlIHtQcm9qZWN0ZWRQb2ludH0gZnJvbSAnLi9wcm9qZWN0aW9uLmpzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ3lsaW5kcmljYWxFcXVhbEFyZWEgZXh0ZW5kcyBQcm9qZWN0aW9uIHtcbiAgICBjb3NQaGk6IG51bWJlcjtcbiAgICBzY2FsZTogbnVtYmVyO1xuXG4gICAgY29uc3RydWN0b3Iob3B0aW9uczogUHJvamVjdGlvblNwZWNpZmljYXRpb24pIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIHRoaXMuY2VudGVyID0gb3B0aW9ucy5jZW50ZXIgfHwgWzAsIDBdO1xuICAgICAgICB0aGlzLnBhcmFsbGVscyA9IG9wdGlvbnMucGFyYWxsZWxzIHx8IFswLCAwXTtcbiAgICAgICAgdGhpcy5jb3NQaGkgPSBNYXRoLm1heCgwLjAxLCBNYXRoLmNvcyhkZWdUb1JhZCh0aGlzLnBhcmFsbGVsc1swXSkpKTtcbiAgICAgICAgLy8gc2NhbGUgY29vcmRpbmF0ZXMgYmV0d2VlbiAwIGFuZCAxIHRvIGF2b2lkIGNvbnN0cmFpbnQgaXNzdWVzXG4gICAgICAgIHRoaXMuc2NhbGUgPSAxIC8gKDIgKiBNYXRoLm1heChNYXRoLlBJICogdGhpcy5jb3NQaGksIDEgLyB0aGlzLmNvc1BoaSkpO1xuICAgICAgICB0aGlzLndyYXAgPSB0cnVlO1xuICAgICAgICB0aGlzLnN1cHBvcnRzV29ybGRDb3BpZXMgPSB0cnVlO1xuICAgIH1cblxuICAgIHByb2plY3QobG5nOiBudW1iZXIsIGxhdDogbnVtYmVyKTogUHJvamVjdGVkUG9pbnQge1xuICAgICAgICBjb25zdCB7c2NhbGUsIGNvc1BoaX0gPSB0aGlzO1xuICAgICAgICBjb25zdCB4ID0gZGVnVG9SYWQobG5nKSAqIGNvc1BoaTtcbiAgICAgICAgY29uc3QgeSA9IE1hdGguc2luKGRlZ1RvUmFkKGxhdCkpIC8gY29zUGhpO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiAoeCAqIHNjYWxlKSArIDAuNSxcbiAgICAgICAgICAgIHk6ICgteSAqIHNjYWxlKSArIDAuNSxcbiAgICAgICAgICAgIHo6IDBcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICB1bnByb2plY3QoeDogbnVtYmVyLCB5OiBudW1iZXIpOiBMbmdMYXQge1xuICAgICAgICBjb25zdCB7c2NhbGUsIGNvc1BoaX0gPSB0aGlzO1xuICAgICAgICBjb25zdCB4XyA9ICh4IC0gMC41KSAvIHNjYWxlO1xuICAgICAgICBjb25zdCB5XyA9IC0oeSAtIDAuNSkgLyBzY2FsZTtcbiAgICAgICAgY29uc3QgbG5nID0gY2xhbXAocmFkVG9EZWcoeF8pIC8gY29zUGhpLCAtMTgwLCAxODApO1xuICAgICAgICBjb25zdCB5MiA9IHlfICogY29zUGhpO1xuICAgICAgICBjb25zdCB5MyA9IE1hdGguYXNpbihjbGFtcCh5MiwgLTEsIDEpKTtcbiAgICAgICAgY29uc3QgbGF0ID0gY2xhbXAocmFkVG9EZWcoeTMpLCAtTUFYX01FUkNBVE9SX0xBVElUVURFLCBNQVhfTUVSQ0FUT1JfTEFUSVRVREUpO1xuXG4gICAgICAgIHJldHVybiBuZXcgTG5nTGF0KGxuZywgbGF0KTtcbiAgICB9XG59XG4iLCIvLyBAZmxvd1xuaW1wb3J0IHttYXQ0LCB2ZWMzfSBmcm9tICdnbC1tYXRyaXgnO1xuaW1wb3J0IEVYVEVOVCBmcm9tICcuLi8uLi9kYXRhL2V4dGVudC5qcyc7XG5pbXBvcnQgTG5nTGF0IGZyb20gJy4uL2xuZ19sYXQuanMnO1xuaW1wb3J0IHtkZWdUb1JhZH0gZnJvbSAnLi4vLi4vdXRpbC91dGlsLmpzJztcbmltcG9ydCBNZXJjYXRvckNvb3JkaW5hdGUsIHtcbiAgICBtZXJjYXRvclpmcm9tQWx0aXR1ZGUsXG59IGZyb20gJy4uL21lcmNhdG9yX2Nvb3JkaW5hdGUuanMnO1xuaW1wb3J0IE1lcmNhdG9yIGZyb20gJy4vbWVyY2F0b3IuanMnO1xuaW1wb3J0IFBvaW50IGZyb20gJ0BtYXBib3gvcG9pbnQtZ2VvbWV0cnknO1xuaW1wb3J0IHtmYXJ0aGVzdFBpeGVsRGlzdGFuY2VPblBsYW5lLCBmYXJ0aGVzdFBpeGVsRGlzdGFuY2VPblNwaGVyZX0gZnJvbSAnLi9mYXJfei5qcyc7XG5pbXBvcnQge251bWJlciBhcyBpbnRlcnBvbGF0ZX0gZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy91dGlsL2ludGVycG9sYXRlLmpzJztcbmltcG9ydCB7XG4gICAgR0xPQkVfU0NBTEVfTUFUQ0hfTEFUSVRVREUsXG4gICAgbGF0TG5nVG9FQ0VGLFxuICAgIGdsb2JlVGlsZUJvdW5kcyxcbiAgICBnbG9iZU5vcm1hbGl6ZUVDRUYsXG4gICAgZ2xvYmVEZW5vcm1hbGl6ZUVDRUYsXG4gICAgZ2xvYmVFQ0VGTm9ybWFsaXphdGlvblNjYWxlLFxuICAgIGdsb2JlVG9NZXJjYXRvclRyYW5zaXRpb24sXG4gICAgZ2xvYmVQb2ludENvb3JkaW5hdGUsXG4gICAgdGlsZUNvb3JkVG9FQ0VGLFxuICAgIGdsb2JlTWV0ZXJzVG9FY2VmXG59IGZyb20gJy4vZ2xvYmVfdXRpbC5qcyc7XG5cbmltcG9ydCB0eXBlIFRyYW5zZm9ybSBmcm9tICcuLi90cmFuc2Zvcm0uanMnO1xuaW1wb3J0IHR5cGUge0VsZXZhdGlvblNjYWxlfSBmcm9tICcuL3Byb2plY3Rpb24uanMnO1xuaW1wb3J0IHR5cGUge1ZlYzN9IGZyb20gJ2dsLW1hdHJpeCc7XG5pbXBvcnQgdHlwZSB7UHJvamVjdGlvblNwZWNpZmljYXRpb259IGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge0Nhbm9uaWNhbFRpbGVJRCwgVW53cmFwcGVkVGlsZUlEfSBmcm9tICcuLi8uLi9zb3VyY2UvdGlsZV9pZC5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEdsb2JlIGV4dGVuZHMgTWVyY2F0b3Ige1xuXG4gICAgY29uc3RydWN0b3Iob3B0aW9uczogUHJvamVjdGlvblNwZWNpZmljYXRpb24pIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIHRoaXMucmVxdWlyZXNEcmFwaW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5zdXBwb3J0c1dvcmxkQ29waWVzID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc3VwcG9ydHNGb2cgPSB0cnVlO1xuICAgICAgICB0aGlzLnpBeGlzVW5pdCA9IFwicGl4ZWxzXCI7XG4gICAgICAgIHRoaXMudW5zdXBwb3J0ZWRMYXllcnMgPSBbJ2RlYnVnJ107XG4gICAgICAgIHRoaXMucmFuZ2UgPSBbMywgNV07XG4gICAgfVxuXG4gICAgcHJvamVjdFRpbGVQb2ludCh4OiBudW1iZXIsIHk6IG51bWJlciwgaWQ6IENhbm9uaWNhbFRpbGVJRCk6IHt4OiBudW1iZXIsIHk6IG51bWJlciwgejogbnVtYmVyfSB7XG4gICAgICAgIGNvbnN0IHBvcyA9IHRpbGVDb29yZFRvRUNFRih4LCB5LCBpZCk7XG4gICAgICAgIGNvbnN0IGJvdW5kcyA9IGdsb2JlVGlsZUJvdW5kcyhpZCk7XG4gICAgICAgIGNvbnN0IG5vcm1hbGl6YXRpb25NYXRyaXggPSBnbG9iZU5vcm1hbGl6ZUVDRUYoYm91bmRzKTtcbiAgICAgICAgdmVjMy50cmFuc2Zvcm1NYXQ0KHBvcywgcG9zLCBub3JtYWxpemF0aW9uTWF0cml4KTtcblxuICAgICAgICByZXR1cm4ge3g6IHBvc1swXSwgeTogcG9zWzFdLCB6OiBwb3NbMl19O1xuICAgIH1cblxuICAgIGxvY2F0aW9uUG9pbnQodHI6IFRyYW5zZm9ybSwgbG5nTGF0OiBMbmdMYXQpOiBQb2ludCB7XG4gICAgICAgIGNvbnN0IHBvcyA9IGxhdExuZ1RvRUNFRihsbmdMYXQubGF0LCBsbmdMYXQubG5nKTtcbiAgICAgICAgY29uc3QgdXAgPSB2ZWMzLm5vcm1hbGl6ZShbXSwgcG9zKTtcblxuICAgICAgICBjb25zdCBlbGV2YXRpb24gPSB0ci5lbGV2YXRpb24gP1xuICAgICAgICAgICAgdHIuZWxldmF0aW9uLmdldEF0UG9pbnRPclplcm8odHIubG9jYXRpb25Db29yZGluYXRlKGxuZ0xhdCksIHRyLl9jZW50ZXJBbHRpdHVkZSkgOlxuICAgICAgICAgICAgdHIuX2NlbnRlckFsdGl0dWRlO1xuXG4gICAgICAgIGNvbnN0IHVwU2NhbGUgPSBtZXJjYXRvclpmcm9tQWx0aXR1ZGUoMSwgMCkgKiBFWFRFTlQgKiBlbGV2YXRpb247XG4gICAgICAgIHZlYzMuc2NhbGVBbmRBZGQocG9zLCBwb3MsIHVwLCB1cFNjYWxlKTtcbiAgICAgICAgY29uc3QgbWF0cml4ID0gbWF0NC5pZGVudGl0eShuZXcgRmxvYXQ2NEFycmF5KDE2KSk7XG4gICAgICAgIG1hdDQubXVsdGlwbHkobWF0cml4LCB0ci5waXhlbE1hdHJpeCwgdHIuZ2xvYmVNYXRyaXgpO1xuICAgICAgICB2ZWMzLnRyYW5zZm9ybU1hdDQocG9zLCBwb3MsIG1hdHJpeCk7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQb2ludChwb3NbMF0sIHBvc1sxXSk7XG4gICAgfVxuXG4gICAgcGl4ZWxzUGVyTWV0ZXIobGF0OiBudW1iZXIsIHdvcmxkU2l6ZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIG1lcmNhdG9yWmZyb21BbHRpdHVkZSgxLCAwKSAqIHdvcmxkU2l6ZTtcbiAgICB9XG5cbiAgICBwaXhlbFNwYWNlQ29udmVyc2lvbihsYXQ6IG51bWJlciwgd29ybGRTaXplOiBudW1iZXIsIGludGVycG9sYXRpb25UOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICAvLyBVc2luZyBvbmx5IHRoZSBjZW50ZXIgbGF0aXR1ZGUgdG8gZGV0ZXJtaW5lIHNjYWxlIGNhdXNlcyB0aGUgZ2xvYmUgdG8gcmFwaWRseSBjaGFuZ2VcbiAgICAgICAgLy8gc2l6ZSBhcyB5b3UgcGFuIHVwIGFuZCBkb3duLiBBcyB5b3UgYXBwcm9hY2ggdGhlIHBvbGUsIHRoZSBnbG9iZSdzIHNpemUgYXBwcm9hY2hlcyBpbmZpbml0eS5cbiAgICAgICAgLy8gVGhpcyBpcyBiZWNhdXNlIHpvb20gbGV2ZWxzIGFyZSBiYXNlZCBvbiBtZXJjYXRvci5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gSW5zdGVhZCwgdXNlIGEgZml4ZWQgcmVmZXJlbmNlIGxhdGl0dWRlIGF0IGxvd2VyIHpvb20gbGV2ZWxzLiBBbmQgdHJhbnNpdGlvbiBiZXR3ZWVuXG4gICAgICAgIC8vIHRoaXMgbGF0aXR1ZGUgYW5kIHRoZSBjZW50ZXIncyBsYXRpdHVkZSBhcyB5b3Ugem9vbSBpbi4gVGhpcyBpcyBhIGNvbXByb21pc2UgdGhhdFxuICAgICAgICAvLyBtYWtlcyBnbG9iZSB2aWV3IG1vcmUgdXNhYmxlIHdpdGggZXhpc3RpbmcgY2FtZXJhIHBhcmFtZXRlcnMsIHN0eWxlcyBhbmQgZGF0YS5cbiAgICAgICAgY29uc3QgY2VudGVyU2NhbGUgPSBtZXJjYXRvclpmcm9tQWx0aXR1ZGUoMSwgbGF0KSAqIHdvcmxkU2l6ZTtcbiAgICAgICAgY29uc3QgcmVmZXJlbmNlU2NhbGUgPSBtZXJjYXRvclpmcm9tQWx0aXR1ZGUoMSwgR0xPQkVfU0NBTEVfTUFUQ0hfTEFUSVRVREUpICogd29ybGRTaXplO1xuICAgICAgICBjb25zdCBjb21iaW5lZFNjYWxlID0gaW50ZXJwb2xhdGUocmVmZXJlbmNlU2NhbGUsIGNlbnRlclNjYWxlLCBpbnRlcnBvbGF0aW9uVCk7XG4gICAgICAgIHJldHVybiB0aGlzLnBpeGVsc1Blck1ldGVyKGxhdCwgd29ybGRTaXplKSAvIGNvbWJpbmVkU2NhbGU7XG4gICAgfVxuXG4gICAgY3JlYXRlVGlsZU1hdHJpeCh0cjogVHJhbnNmb3JtLCB3b3JsZFNpemU6IG51bWJlciwgaWQ6IFVud3JhcHBlZFRpbGVJRCk6IEZsb2F0NjRBcnJheSB7XG4gICAgICAgIGNvbnN0IGRlY29kZSA9IGdsb2JlRGVub3JtYWxpemVFQ0VGKGdsb2JlVGlsZUJvdW5kcyhpZC5jYW5vbmljYWwpKTtcbiAgICAgICAgcmV0dXJuIG1hdDQubXVsdGlwbHkobmV3IEZsb2F0NjRBcnJheSgxNiksIHRyLmdsb2JlTWF0cml4LCBkZWNvZGUpO1xuICAgIH1cblxuICAgIGNyZWF0ZUludmVyc2lvbk1hdHJpeCh0cjogVHJhbnNmb3JtLCBpZDogQ2Fub25pY2FsVGlsZUlEKTogRmxvYXQzMkFycmF5IHtcbiAgICAgICAgY29uc3Qge2NlbnRlcn0gPSB0cjtcbiAgICAgICAgY29uc3QgbWF0cml4ID0gZ2xvYmVOb3JtYWxpemVFQ0VGKGdsb2JlVGlsZUJvdW5kcyhpZCkpO1xuICAgICAgICBtYXQ0LnJvdGF0ZVkobWF0cml4LCBtYXRyaXgsIGRlZ1RvUmFkKGNlbnRlci5sbmcpKTtcbiAgICAgICAgbWF0NC5yb3RhdGVYKG1hdHJpeCwgbWF0cml4LCBkZWdUb1JhZChjZW50ZXIubGF0KSk7XG4gICAgICAgIG1hdDQuc2NhbGUobWF0cml4LCBtYXRyaXgsIFt0ci5fcGl4ZWxzUGVyTWVyY2F0b3JQaXhlbCwgdHIuX3BpeGVsc1Blck1lcmNhdG9yUGl4ZWwsIDEuMF0pO1xuICAgICAgICByZXR1cm4gRmxvYXQzMkFycmF5LmZyb20obWF0cml4KTtcbiAgICB9XG5cbiAgICBwb2ludENvb3JkaW5hdGUodHI6IFRyYW5zZm9ybSwgeDogbnVtYmVyLCB5OiBudW1iZXIsIF86IG51bWJlcik6IE1lcmNhdG9yQ29vcmRpbmF0ZSB7XG4gICAgICAgIGNvbnN0IGNvb3JkID0gZ2xvYmVQb2ludENvb3JkaW5hdGUodHIsIHgsIHksIHRydWUpO1xuICAgICAgICBpZiAoIWNvb3JkKSB7IHJldHVybiBuZXcgTWVyY2F0b3JDb29yZGluYXRlKDAsIDApOyB9IC8vIFRoaXMgd29uJ3QgaGFwcGVuLCBpcyBoZXJlIGZvciBGbG93XG4gICAgICAgIHJldHVybiBjb29yZDtcbiAgICB9XG5cbiAgICBwb2ludENvb3JkaW5hdGUzRCh0cjogVHJhbnNmb3JtLCB4OiBudW1iZXIsIHk6IG51bWJlcik6ID9WZWMzIHtcbiAgICAgICAgY29uc3QgY29vcmQgPSB0aGlzLnBvaW50Q29vcmRpbmF0ZSh0ciwgeCwgeSwgMCk7XG4gICAgICAgIHJldHVybiBbY29vcmQueCwgY29vcmQueSwgY29vcmQuel07XG4gICAgfVxuXG4gICAgaXNQb2ludEFib3ZlSG9yaXpvbih0cjogVHJhbnNmb3JtLCBwOiBQb2ludCk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCByYXljYXN0T25HbG9iZSA9IGdsb2JlUG9pbnRDb29yZGluYXRlKHRyLCBwLngsIHAueSwgZmFsc2UpO1xuICAgICAgICByZXR1cm4gIXJheWNhc3RPbkdsb2JlO1xuICAgIH1cblxuICAgIGZhcnRoZXN0UGl4ZWxEaXN0YW5jZSh0cjogVHJhbnNmb3JtKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgcGl4ZWxzUGVyTWV0ZXIgPSB0aGlzLnBpeGVsc1Blck1ldGVyKHRyLmNlbnRlci5sYXQsIHRyLndvcmxkU2l6ZSk7XG4gICAgICAgIGNvbnN0IGdsb2JlUGl4ZWxEaXN0YW5jZSA9IGZhcnRoZXN0UGl4ZWxEaXN0YW5jZU9uU3BoZXJlKHRyLCBwaXhlbHNQZXJNZXRlcik7XG4gICAgICAgIGNvbnN0IHQgPSBnbG9iZVRvTWVyY2F0b3JUcmFuc2l0aW9uKHRyLnpvb20pO1xuICAgICAgICBpZiAodCA+IDAuMCkge1xuICAgICAgICAgICAgY29uc3QgbWVyY2F0b3JQaXhlbHNQZXJNZXRlciA9IG1lcmNhdG9yWmZyb21BbHRpdHVkZSgxLCB0ci5jZW50ZXIubGF0KSAqIHRyLndvcmxkU2l6ZTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmNhdG9yUGl4ZWxEaXN0YW5jZSA9IGZhcnRoZXN0UGl4ZWxEaXN0YW5jZU9uUGxhbmUodHIsIG1lcmNhdG9yUGl4ZWxzUGVyTWV0ZXIpO1xuICAgICAgICAgICAgY29uc3QgcGl4ZWxSYWRpdXMgPSB0ci53b3JsZFNpemUgLyAoMi4wICogTWF0aC5QSSk7XG4gICAgICAgICAgICBjb25zdCBhcHByb3hUaWxlQXJjSGFsZkFuZ2xlID0gTWF0aC5tYXgodHIud2lkdGgsIHRyLmhlaWdodCkgLyB0ci53b3JsZFNpemUgKiBNYXRoLlBJO1xuICAgICAgICAgICAgY29uc3QgcGFkZGluZyA9IHBpeGVsUmFkaXVzICogKDEuMCAtIE1hdGguY29zKGFwcHJveFRpbGVBcmNIYWxmQW5nbGUpKTtcblxuICAgICAgICAgICAgLy8gRHVyaW5nIHRyYW5zaXRpb24gdG8gbWVyY2F0b3Igd2Ugd291bGQgbGlrZSB0byBrZWVwXG4gICAgICAgICAgICAvLyB0aGUgZmFyIHBsYW5lIGxvd2VyIHRvIGVuc3VyZSB0aGF0IGdlb21ldHJpZXMgKGUuZy4gY2lyY2xlcykgdGhhdCBhcmUgZmFyIGF3YXkgYW5kIGFyZSBub3Qgc3VwcG9zZWRcbiAgICAgICAgICAgIC8vIHRvIGJlIHJlbmRlcmVkIGdldCBjdWxsZWQgb3V0IGNvcnJlY3RseS4gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXBib3gvbWFwYm94LWdsLWpzL2lzc3Vlcy8xMTQ3NlxuICAgICAgICAgICAgLy8gVG8gYWNoaWV2ZSB0aGlzIHdlIGRhbXBlbiB0aGUgaW50ZXJwb2xhdGlvbi5cbiAgICAgICAgICAgIHJldHVybiBpbnRlcnBvbGF0ZShnbG9iZVBpeGVsRGlzdGFuY2UsIG1lcmNhdG9yUGl4ZWxEaXN0YW5jZSArIHBhZGRpbmcsIE1hdGgucG93KHQsIDEwLjApKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZ2xvYmVQaXhlbERpc3RhbmNlO1xuICAgIH1cblxuICAgIHVwVmVjdG9yKGlkOiBDYW5vbmljYWxUaWxlSUQsIHg6IG51bWJlciwgeTogbnVtYmVyKTogVmVjMyB7XG4gICAgICAgIHJldHVybiB0aWxlQ29vcmRUb0VDRUYoeCwgeSwgaWQsIDEpO1xuICAgIH1cblxuICAgIHVwVmVjdG9yU2NhbGUoaWQ6IENhbm9uaWNhbFRpbGVJRCk6IEVsZXZhdGlvblNjYWxlIHtcbiAgICAgICAgcmV0dXJuIHttZXRlcnNUb1RpbGU6IGdsb2JlTWV0ZXJzVG9FY2VmKGdsb2JlRUNFRk5vcm1hbGl6YXRpb25TY2FsZShnbG9iZVRpbGVCb3VuZHMoaWQpKSl9O1xuICAgIH1cbn1cbiIsIi8vIEBmbG93XG5pbXBvcnQgQWxiZXJzIGZyb20gJy4vYWxiZXJzLmpzJztcbmltcG9ydCBFcXVhbEVhcnRoIGZyb20gJy4vZXF1YWxfZWFydGguanMnO1xuaW1wb3J0IEVxdWlyZWN0YW5ndWxhciBmcm9tICcuL2VxdWlyZWN0YW5ndWxhci5qcyc7XG5pbXBvcnQgTGFtYmVydENvbmZvcm1hbENvbmljIGZyb20gJy4vbGFtYmVydC5qcyc7XG5pbXBvcnQgTWVyY2F0b3IgZnJvbSAnLi9tZXJjYXRvci5qcyc7XG5pbXBvcnQgTmF0dXJhbEVhcnRoIGZyb20gJy4vbmF0dXJhbF9lYXJ0aC5qcyc7XG5pbXBvcnQgV2lua2VsVHJpcGVsIGZyb20gJy4vd2lua2VsX3RyaXBlbC5qcyc7XG5pbXBvcnQgQ3lsaW5kcmljYWxFcXVhbEFyZWEgZnJvbSAnLi9jeWxpbmRyaWNhbF9lcXVhbF9hcmVhLmpzJztcbmltcG9ydCBHbG9iZSBmcm9tICcuL2dsb2JlLmpzJztcblxuaW1wb3J0IHR5cGUge1Byb2plY3Rpb25TcGVjaWZpY2F0aW9ufSBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL3R5cGVzLmpzJztcbmltcG9ydCB0eXBlIFByb2plY3Rpb24gZnJvbSAnLi9wcm9qZWN0aW9uLmpzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGdldFByb2plY3Rpb24oY29uZmlnOiBQcm9qZWN0aW9uU3BlY2lmaWNhdGlvbik6IFByb2plY3Rpb24ge1xuXG4gICAgY29uc3QgcGFyYWxsZWxzID0gY29uZmlnLnBhcmFsbGVscztcbiAgICBjb25zdCBpc0RlZ2VuZXJhdGVDb25pYyA9IHBhcmFsbGVscyA/IE1hdGguYWJzKHBhcmFsbGVsc1swXSArIHBhcmFsbGVsc1sxXSkgPCAwLjAxIDogZmFsc2U7XG5cbiAgICBzd2l0Y2ggKGNvbmZpZy5uYW1lKSB7XG4gICAgY2FzZSAnbWVyY2F0b3InOlxuICAgICAgICByZXR1cm4gbmV3IE1lcmNhdG9yKGNvbmZpZyk7XG4gICAgY2FzZSAnZXF1aXJlY3Rhbmd1bGFyJzpcbiAgICAgICAgcmV0dXJuIG5ldyBFcXVpcmVjdGFuZ3VsYXIoY29uZmlnKTtcbiAgICBjYXNlICduYXR1cmFsRWFydGgnOlxuICAgICAgICByZXR1cm4gbmV3IE5hdHVyYWxFYXJ0aChjb25maWcpO1xuICAgIGNhc2UgJ2VxdWFsRWFydGgnOlxuICAgICAgICByZXR1cm4gbmV3IEVxdWFsRWFydGgoY29uZmlnKTtcbiAgICBjYXNlICd3aW5rZWxUcmlwZWwnOlxuICAgICAgICByZXR1cm4gbmV3IFdpbmtlbFRyaXBlbChjb25maWcpO1xuICAgIGNhc2UgJ2FsYmVycyc6XG4gICAgICAgIHJldHVybiBpc0RlZ2VuZXJhdGVDb25pYyA/IG5ldyBDeWxpbmRyaWNhbEVxdWFsQXJlYShjb25maWcpIDogbmV3IEFsYmVycyhjb25maWcpO1xuICAgIGNhc2UgJ2xhbWJlcnRDb25mb3JtYWxDb25pYyc6XG4gICAgICAgIHJldHVybiBpc0RlZ2VuZXJhdGVDb25pYyA/IG5ldyBDeWxpbmRyaWNhbEVxdWFsQXJlYShjb25maWcpIDogbmV3IExhbWJlcnRDb25mb3JtYWxDb25pYyhjb25maWcpO1xuICAgIGNhc2UgJ2dsb2JlJzpcbiAgICAgICAgcmV0dXJuIG5ldyBHbG9iZShjb25maWcpO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBwcm9qZWN0aW9uIG5hbWU6ICR7Y29uZmlnLm5hbWV9YCk7XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge3N5bWJvbExheW91dEF0dHJpYnV0ZXMsXG4gICAgc3ltYm9sR2xvYmVFeHRBdHRyaWJ1dGVzLFxuICAgIGNvbGxpc2lvblZlcnRleEF0dHJpYnV0ZXMsXG4gICAgY29sbGlzaW9uVmVydGV4QXR0cmlidXRlc0V4dCxcbiAgICBjb2xsaXNpb25Cb3hMYXlvdXQsXG4gICAgZHluYW1pY0xheW91dEF0dHJpYnV0ZXNcbn0gZnJvbSAnLi9zeW1ib2xfYXR0cmlidXRlcy5qcyc7XG5cbmltcG9ydCB7U3ltYm9sTGF5b3V0QXJyYXksXG4gICAgU3ltYm9sR2xvYmVFeHRBcnJheSxcbiAgICBTeW1ib2xEeW5hbWljTGF5b3V0QXJyYXksXG4gICAgU3ltYm9sT3BhY2l0eUFycmF5LFxuICAgIENvbGxpc2lvbkJveExheW91dEFycmF5LFxuICAgIENvbGxpc2lvblZlcnRleEV4dEFycmF5LFxuICAgIENvbGxpc2lvblZlcnRleEFycmF5LFxuICAgIFBsYWNlZFN5bWJvbEFycmF5LFxuICAgIFN5bWJvbEluc3RhbmNlQXJyYXksXG4gICAgR2x5cGhPZmZzZXRBcnJheSxcbiAgICBTeW1ib2xMaW5lVmVydGV4QXJyYXlcbn0gZnJvbSAnLi4vYXJyYXlfdHlwZXMuanMnO1xuXG5pbXBvcnQgT05FX0VNIGZyb20gJy4uLy4uL3N5bWJvbC9vbmVfZW0uanMnO1xuaW1wb3J0ICogYXMgc3ltYm9sU2l6ZSBmcm9tICcuLi8uLi9zeW1ib2wvc3ltYm9sX3NpemUuanMnO1xuaW1wb3J0IFBvaW50IGZyb20gJ0BtYXBib3gvcG9pbnQtZ2VvbWV0cnknO1xuaW1wb3J0IFNlZ21lbnRWZWN0b3IgZnJvbSAnLi4vc2VnbWVudC5qcyc7XG5pbXBvcnQge1Byb2dyYW1Db25maWd1cmF0aW9uU2V0fSBmcm9tICcuLi9wcm9ncmFtX2NvbmZpZ3VyYXRpb24uanMnO1xuaW1wb3J0IHtUcmlhbmdsZUluZGV4QXJyYXksIExpbmVJbmRleEFycmF5fSBmcm9tICcuLi9pbmRleF9hcnJheV90eXBlLmpzJztcbmltcG9ydCB0cmFuc2Zvcm1UZXh0IGZyb20gJy4uLy4uL3N5bWJvbC90cmFuc2Zvcm1fdGV4dC5qcyc7XG5pbXBvcnQgbWVyZ2VMaW5lcyBmcm9tICcuLi8uLi9zeW1ib2wvbWVyZ2VsaW5lcy5qcyc7XG5pbXBvcnQge2FsbG93c1ZlcnRpY2FsV3JpdGluZ01vZGUsIHN0cmluZ0NvbnRhaW5zUlRMVGV4dH0gZnJvbSAnLi4vLi4vdXRpbC9zY3JpcHRfZGV0ZWN0aW9uLmpzJztcbmltcG9ydCB7V3JpdGluZ01vZGV9IGZyb20gJy4uLy4uL3N5bWJvbC9zaGFwaW5nLmpzJztcbmltcG9ydCBsb2FkR2VvbWV0cnkgZnJvbSAnLi4vbG9hZF9nZW9tZXRyeS5qcyc7XG5pbXBvcnQgdG9FdmFsdWF0aW9uRmVhdHVyZSBmcm9tICcuLi9ldmFsdWF0aW9uX2ZlYXR1cmUuanMnO1xuaW1wb3J0IHtWZWN0b3JUaWxlRmVhdHVyZX0gZnJvbSAnQG1hcGJveC92ZWN0b3ItdGlsZSc7XG5jb25zdCB2ZWN0b3JUaWxlRmVhdHVyZVR5cGVzID0gVmVjdG9yVGlsZUZlYXR1cmUudHlwZXM7XG5pbXBvcnQge3ZlcnRpY2FsaXplZENoYXJhY3Rlck1hcH0gZnJvbSAnLi4vLi4vdXRpbC92ZXJ0aWNhbGl6ZV9wdW5jdHVhdGlvbi5qcyc7XG5pbXBvcnQgQW5jaG9yIGZyb20gJy4uLy4uL3N5bWJvbC9hbmNob3IuanMnO1xuaW1wb3J0IHtnZXRTaXplRGF0YX0gZnJvbSAnLi4vLi4vc3ltYm9sL3N5bWJvbF9zaXplLmpzJztcbmltcG9ydCB7TUFYX1BBQ0tFRF9TSVpFfSBmcm9tICcuLi8uLi9zeW1ib2wvc3ltYm9sX2xheW91dC5qcyc7XG5pbXBvcnQge3JlZ2lzdGVyfSBmcm9tICcuLi8uLi91dGlsL3dlYl93b3JrZXJfdHJhbnNmZXIuanMnO1xuaW1wb3J0IEV2YWx1YXRpb25QYXJhbWV0ZXJzIGZyb20gJy4uLy4uL3N0eWxlL2V2YWx1YXRpb25fcGFyYW1ldGVycy5qcyc7XG5pbXBvcnQgRm9ybWF0dGVkIGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi90eXBlcy9mb3JtYXR0ZWQuanMnO1xuaW1wb3J0IFJlc29sdmVkSW1hZ2UgZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy9leHByZXNzaW9uL3R5cGVzL3Jlc29sdmVkX2ltYWdlLmpzJztcbmltcG9ydCB7cGx1Z2luIGFzIGdsb2JhbFJUTFRleHRQbHVnaW4sIGdldFJUTFRleHRQbHVnaW5TdGF0dXN9IGZyb20gJy4uLy4uL3NvdXJjZS9ydGxfdGV4dF9wbHVnaW4uanMnO1xuaW1wb3J0IHtyZXNhbXBsZVByZWR9IGZyb20gJy4uLy4uL2dlby9wcm9qZWN0aW9uL3Jlc2FtcGxlLmpzJztcbmltcG9ydCB7dGlsZUNvb3JkVG9FQ0VGfSBmcm9tICcuLi8uLi9nZW8vcHJvamVjdGlvbi9nbG9iZV91dGlsLmpzJztcbmltcG9ydCB0eXBlIHtQcm9qZWN0aW9uU3BlY2lmaWNhdGlvbn0gZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy90eXBlcy5qcyc7XG5pbXBvcnQge2dldFByb2plY3Rpb259IGZyb20gJy4uLy4uL2dlby9wcm9qZWN0aW9uL2luZGV4LmpzJztcbmltcG9ydCB0eXBlIFByb2plY3Rpb24gZnJvbSAnLi4vLi4vZ2VvL3Byb2plY3Rpb24vcHJvamVjdGlvbi5qcyc7XG5pbXBvcnQge21hdDQsIHZlYzN9IGZyb20gJ2dsLW1hdHJpeCc7XG5cbmltcG9ydCB0eXBlIHtDYW5vbmljYWxUaWxlSUQsIE92ZXJzY2FsZWRUaWxlSUR9IGZyb20gJy4uLy4uL3NvdXJjZS90aWxlX2lkLmpzJztcbmltcG9ydCB0eXBlIHtcbiAgICBCdWNrZXQsXG4gICAgQnVja2V0UGFyYW1ldGVycyxcbiAgICBJbmRleGVkRmVhdHVyZSxcbiAgICBQb3B1bGF0ZVBhcmFtZXRlcnNcbn0gZnJvbSAnLi4vYnVja2V0LmpzJztcbmltcG9ydCB0eXBlIHtDb2xsaXNpb25Cb3hBcnJheSwgQ29sbGlzaW9uQm94LCBTeW1ib2xJbnN0YW5jZX0gZnJvbSAnLi4vYXJyYXlfdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge1N0cnVjdEFycmF5LCBTdHJ1Y3RBcnJheU1lbWJlcn0gZnJvbSAnLi4vLi4vdXRpbC9zdHJ1Y3RfYXJyYXkuanMnO1xuaW1wb3J0IFN5bWJvbFN0eWxlTGF5ZXIgZnJvbSAnLi4vLi4vc3R5bGUvc3R5bGVfbGF5ZXIvc3ltYm9sX3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCB0eXBlIENvbnRleHQgZnJvbSAnLi4vLi4vZ2wvY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSBJbmRleEJ1ZmZlciBmcm9tICcuLi8uLi9nbC9pbmRleF9idWZmZXIuanMnO1xuaW1wb3J0IHR5cGUgVmVydGV4QnVmZmVyIGZyb20gJy4uLy4uL2dsL3ZlcnRleF9idWZmZXIuanMnO1xuaW1wb3J0IHR5cGUge1N5bWJvbFF1YWR9IGZyb20gJy4uLy4uL3N5bWJvbC9xdWFkcy5qcyc7XG5pbXBvcnQgdHlwZSB7U2l6ZURhdGF9IGZyb20gJy4uLy4uL3N5bWJvbC9zeW1ib2xfc2l6ZS5qcyc7XG5pbXBvcnQgdHlwZSB7RmVhdHVyZVN0YXRlc30gZnJvbSAnLi4vLi4vc291cmNlL3NvdXJjZV9zdGF0ZS5qcyc7XG5pbXBvcnQgdHlwZSB7VGlsZVRyYW5zZm9ybX0gZnJvbSAnLi4vLi4vZ2VvL3Byb2plY3Rpb24vdGlsZV90cmFuc2Zvcm0uanMnO1xuZXhwb3J0IHR5cGUgU2luZ2xlQ29sbGlzaW9uQm94ID0ge1xuICAgIHgxOiBudW1iZXI7XG4gICAgeTE6IG51bWJlcjtcbiAgICB4MjogbnVtYmVyO1xuICAgIHkyOiBudW1iZXI7XG4gICAgcGFkZGluZzogbnVtYmVyO1xuICAgIHByb2plY3RlZEFuY2hvclg6IG51bWJlcjtcbiAgICBwcm9qZWN0ZWRBbmNob3JZOiBudW1iZXI7XG4gICAgcHJvamVjdGVkQW5jaG9yWjogbnVtYmVyO1xuICAgIHRpbGVBbmNob3JYOiBudW1iZXI7XG4gICAgdGlsZUFuY2hvclk6IG51bWJlcjtcbiAgICBlbGV2YXRpb24/OiBudW1iZXI7XG4gICAgdGlsZUlEPzogT3ZlcnNjYWxlZFRpbGVJRDtcbn07XG5pbXBvcnQgdHlwZSB7TWF0NCwgVmVjM30gZnJvbSAnZ2wtbWF0cml4JztcbmltcG9ydCB0eXBlIHtTcHJpdGVQb3NpdGlvbnN9IGZyb20gJy4uLy4uL3V0aWwvaW1hZ2UuanMnO1xuaW1wb3J0IHR5cGUge0lWZWN0b3JUaWxlTGF5ZXJ9IGZyb20gJ0BtYXBib3gvdmVjdG9yLXRpbGUnO1xuXG5leHBvcnQgdHlwZSBDb2xsaXNpb25BcnJheXMgPSB7XG4gICAgdGV4dEJveD86IFNpbmdsZUNvbGxpc2lvbkJveDtcbiAgICB2ZXJ0aWNhbFRleHRCb3g/OiBTaW5nbGVDb2xsaXNpb25Cb3g7XG4gICAgaWNvbkJveD86IFNpbmdsZUNvbGxpc2lvbkJveDtcbiAgICB2ZXJ0aWNhbEljb25Cb3g/OiBTaW5nbGVDb2xsaXNpb25Cb3g7XG4gICAgdGV4dEZlYXR1cmVJbmRleD86IG51bWJlcjtcbiAgICB2ZXJ0aWNhbFRleHRGZWF0dXJlSW5kZXg/OiBudW1iZXI7XG4gICAgaWNvbkZlYXR1cmVJbmRleD86IG51bWJlcjtcbiAgICB2ZXJ0aWNhbEljb25GZWF0dXJlSW5kZXg/OiBudW1iZXI7XG59O1xuXG5leHBvcnQgdHlwZSBTeW1ib2xGZWF0dXJlID0ge3xcbiAgICBzb3J0S2V5OiBudW1iZXIgfCB2b2lkLFxuICAgIHRleHQ6IEZvcm1hdHRlZCB8IHZvaWQsXG4gICAgaWNvbjogP1Jlc29sdmVkSW1hZ2UsXG4gICAgaW5kZXg6IG51bWJlcixcbiAgICBzb3VyY2VMYXllckluZGV4OiBudW1iZXIsXG4gICAgZ2VvbWV0cnk6IEFycmF5PEFycmF5PFBvaW50Pj4sXG4gICAgcHJvcGVydGllczogT2JqZWN0LFxuICAgIHR5cGU6ICdQb2ludCcgfCAnTGluZVN0cmluZycgfCAnUG9seWdvbicsXG4gICAgaWQ/OiBhbnlcbnx9O1xuXG5leHBvcnQgdHlwZSBTb3J0S2V5UmFuZ2UgPSB7XG4gICAgc29ydEtleTogbnVtYmVyLFxuICAgIHN5bWJvbEluc3RhbmNlU3RhcnQ6IG51bWJlcixcbiAgICBzeW1ib2xJbnN0YW5jZUVuZDogbnVtYmVyXG59O1xuXG50eXBlIExpbmVWZXJ0ZXhSYW5nZSA9IHt8XG4gICAgbGluZUxlbmd0aDogbnVtYmVyLFxuICAgIGxpbmVTdGFydEluZGV4OiBudW1iZXJcbnx9O1xuXG4vLyBPcGFjaXR5IGFycmF5cyBhcmUgZnJlcXVlbnRseSB1cGRhdGVkIGJ1dCBkb24ndCBjb250YWluIGEgbG90IG9mIGluZm9ybWF0aW9uLCBzbyB3ZSBwYWNrIHRoZW1cbi8vIHRpZ2h0LiBFYWNoIFVpbnQzMiBpcyBhY3R1YWxseSBmb3VyIGR1cGxpY2F0ZSBVaW50OHMgZm9yIHRoZSBmb3VyIGNvcm5lcnMgb2YgYSBnbHlwaFxuLy8gNyBiaXRzIGFyZSBmb3IgdGhlIGN1cnJlbnQgb3BhY2l0eSwgYW5kIHRoZSBsb3dlc3QgYml0IGlzIHRoZSB0YXJnZXQgb3BhY2l0eVxuXG4vLyBhY3R1YWxseSBkZWZpbmVkIGluIHN5bWJvbF9hdHRyaWJ1dGVzLmpzXG4vLyBjb25zdCBwbGFjZW1lbnRPcGFjaXR5QXR0cmlidXRlcyA9IFtcbi8vICAgICB7IG5hbWU6ICdhX2ZhZGVfb3BhY2l0eScsIGNvbXBvbmVudHM6IDEsIHR5cGU6ICdVaW50MzInIH1cbi8vIF07XG5jb25zdCBzaGFkZXJPcGFjaXR5QXR0cmlidXRlcyA9IFtcbiAgICB7bmFtZTogJ2FfZmFkZV9vcGFjaXR5JywgY29tcG9uZW50czogMSwgdHlwZTogJ1VpbnQ4Jywgb2Zmc2V0OiAwfVxuXTtcblxuZnVuY3Rpb24gYWRkVmVydGV4KGFycmF5OiBTeW1ib2xMYXlvdXRBcnJheSwgdGlsZUFuY2hvclg6IG51bWJlciwgdGlsZUFuY2hvclk6IG51bWJlciwgb3g6IG51bWJlciwgb3k6IG51bWJlciwgdHg6IG51bWJlciwgdHk6IG51bWJlciwgc2l6ZVZlcnRleDogYW55LCBpc1NERjogYm9vbGVhbiwgcGl4ZWxPZmZzZXRYOiBudW1iZXIsIHBpeGVsT2Zmc2V0WTogbnVtYmVyLCBtaW5Gb250U2NhbGVYOiBudW1iZXIsIG1pbkZvbnRTY2FsZVk6IG51bWJlcikge1xuICAgIGNvbnN0IGFTaXplWCA9IHNpemVWZXJ0ZXggPyBNYXRoLm1pbihNQVhfUEFDS0VEX1NJWkUsIE1hdGgucm91bmQoc2l6ZVZlcnRleFswXSkpIDogMDtcbiAgICBjb25zdCBhU2l6ZVkgPSBzaXplVmVydGV4ID8gTWF0aC5taW4oTUFYX1BBQ0tFRF9TSVpFLCBNYXRoLnJvdW5kKHNpemVWZXJ0ZXhbMV0pKSA6IDA7XG5cbiAgICBhcnJheS5lbXBsYWNlQmFjayhcbiAgICAgICAgLy8gYV9wb3Nfb2Zmc2V0XG4gICAgICAgIHRpbGVBbmNob3JYLFxuICAgICAgICB0aWxlQW5jaG9yWSxcbiAgICAgICAgTWF0aC5yb3VuZChveCAqIDMyKSxcbiAgICAgICAgTWF0aC5yb3VuZChveSAqIDMyKSxcblxuICAgICAgICAvLyBhX2RhdGFcbiAgICAgICAgdHgsIC8vIHggY29vcmRpbmF0ZSBvZiBzeW1ib2wgb24gZ2x5cGggYXRsYXMgdGV4dHVyZVxuICAgICAgICB0eSwgLy8geSBjb29yZGluYXRlIG9mIHN5bWJvbCBvbiBnbHlwaCBhdGxhcyB0ZXh0dXJlXG4gICAgICAgIChhU2l6ZVggPDwgMSkgKyAoaXNTREYgPyAxIDogMCksXG4gICAgICAgIGFTaXplWSxcbiAgICAgICAgcGl4ZWxPZmZzZXRYICogMTYsXG4gICAgICAgIHBpeGVsT2Zmc2V0WSAqIDE2LFxuICAgICAgICBtaW5Gb250U2NhbGVYICogMjU2LFxuICAgICAgICBtaW5Gb250U2NhbGVZICogMjU2XG4gICAgKTtcbn1cblxuZnVuY3Rpb24gYWRkR2xvYmVWZXJ0ZXgoYXJyYXk6IFN5bWJvbEdsb2JlRXh0QXJyYXksIHByb2pBbmNob3JYOiBudW1iZXIsIHByb2pBbmNob3JZOiBudW1iZXIsIHByb2pBbmNob3JaOiBudW1iZXIsIG5vcm1YOiBudW1iZXIsIG5vcm1ZOiBudW1iZXIsIG5vcm1aOiBudW1iZXIpIHtcbiAgICBhcnJheS5lbXBsYWNlQmFjayhcbiAgICAgICAgLy8gYV9nbG9iZV9hbmNob3JcbiAgICAgICAgcHJvakFuY2hvclgsXG4gICAgICAgIHByb2pBbmNob3JZLFxuICAgICAgICBwcm9qQW5jaG9yWixcblxuICAgICAgICAvLyBhX2dsb2JlX25vcm1hbFxuICAgICAgICBub3JtWCxcbiAgICAgICAgbm9ybVksXG4gICAgICAgIG5vcm1aXG4gICAgKTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlR2xvYmVWZXJ0ZXhOb3JtYWwoYXJyYXk6IFN5bWJvbEdsb2JlRXh0QXJyYXksIHZlcnRleElkeDogbnVtYmVyLCBub3JtWDogbnVtYmVyLCBub3JtWTogbnVtYmVyLCBub3JtWjogbnVtYmVyKSB7XG4gICAgLy8gTW9kaWZ5IGZsb2F0MzIgYXJyYXkgZGlyZWN0bHkuIDIwIGJ5dGVzIHBlciBlbnRyeSwgM3hJbnQxNiBmb3IgcG9zaXRpb24sIDN4ZmxvYXQzMiBmb3Igbm9ybWFsXG4gICAgY29uc3Qgb2Zmc2V0ID0gdmVydGV4SWR4ICogNSArIDI7XG4gICAgYXJyYXkuZmxvYXQzMltvZmZzZXQgKyAwXSA9IG5vcm1YO1xuICAgIGFycmF5LmZsb2F0MzJbb2Zmc2V0ICsgMV0gPSBub3JtWTtcbiAgICBhcnJheS5mbG9hdDMyW29mZnNldCArIDJdID0gbm9ybVo7XG59XG5cbmZ1bmN0aW9uIGFkZER5bmFtaWNBdHRyaWJ1dGVzKGR5bmFtaWNMYXlvdXRWZXJ0ZXhBcnJheTogU3RydWN0QXJyYXksIHg6IG51bWJlciwgeTogbnVtYmVyLCB6OiBudW1iZXIsIGFuZ2xlOiBudW1iZXIpIHtcbiAgICBkeW5hbWljTGF5b3V0VmVydGV4QXJyYXkuZW1wbGFjZUJhY2soeCwgeSwgeiwgYW5nbGUpO1xuICAgIGR5bmFtaWNMYXlvdXRWZXJ0ZXhBcnJheS5lbXBsYWNlQmFjayh4LCB5LCB6LCBhbmdsZSk7XG4gICAgZHluYW1pY0xheW91dFZlcnRleEFycmF5LmVtcGxhY2VCYWNrKHgsIHksIHosIGFuZ2xlKTtcbiAgICBkeW5hbWljTGF5b3V0VmVydGV4QXJyYXkuZW1wbGFjZUJhY2soeCwgeSwgeiwgYW5nbGUpO1xufVxuXG5mdW5jdGlvbiBjb250YWluc1JUTFRleHQoZm9ybWF0dGVkVGV4dDogRm9ybWF0dGVkKTogYm9vbGVhbiB7XG4gICAgZm9yIChjb25zdCBzZWN0aW9uIG9mIGZvcm1hdHRlZFRleHQuc2VjdGlvbnMpIHtcbiAgICAgICAgaWYgKHN0cmluZ0NvbnRhaW5zUlRMVGV4dChzZWN0aW9uLnRleHQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCBjbGFzcyBTeW1ib2xCdWZmZXJzIHtcbiAgICBsYXlvdXRWZXJ0ZXhBcnJheTogU3ltYm9sTGF5b3V0QXJyYXk7XG4gICAgbGF5b3V0VmVydGV4QnVmZmVyOiBWZXJ0ZXhCdWZmZXI7XG5cbiAgICBpbmRleEFycmF5OiBUcmlhbmdsZUluZGV4QXJyYXk7XG4gICAgaW5kZXhCdWZmZXI6IEluZGV4QnVmZmVyO1xuXG4gICAgcHJvZ3JhbUNvbmZpZ3VyYXRpb25zOiBQcm9ncmFtQ29uZmlndXJhdGlvblNldDxTeW1ib2xTdHlsZUxheWVyPjtcbiAgICBzZWdtZW50czogU2VnbWVudFZlY3RvcjtcblxuICAgIGR5bmFtaWNMYXlvdXRWZXJ0ZXhBcnJheTogU3ltYm9sRHluYW1pY0xheW91dEFycmF5O1xuICAgIGR5bmFtaWNMYXlvdXRWZXJ0ZXhCdWZmZXI6IFZlcnRleEJ1ZmZlcjtcblxuICAgIG9wYWNpdHlWZXJ0ZXhBcnJheTogU3ltYm9sT3BhY2l0eUFycmF5O1xuICAgIG9wYWNpdHlWZXJ0ZXhCdWZmZXI6IFZlcnRleEJ1ZmZlcjtcblxuICAgIGdsb2JlRXh0VmVydGV4QXJyYXk6IFN5bWJvbEdsb2JlRXh0QXJyYXk7XG4gICAgZ2xvYmVFeHRWZXJ0ZXhCdWZmZXI6IFZlcnRleEJ1ZmZlcjtcblxuICAgIHBsYWNlZFN5bWJvbEFycmF5OiBQbGFjZWRTeW1ib2xBcnJheTtcblxuICAgIGNvbnN0cnVjdG9yKHByb2dyYW1Db25maWd1cmF0aW9uczogUHJvZ3JhbUNvbmZpZ3VyYXRpb25TZXQ8U3ltYm9sU3R5bGVMYXllcj4pIHtcbiAgICAgICAgdGhpcy5sYXlvdXRWZXJ0ZXhBcnJheSA9IG5ldyBTeW1ib2xMYXlvdXRBcnJheSgpO1xuICAgICAgICB0aGlzLmluZGV4QXJyYXkgPSBuZXcgVHJpYW5nbGVJbmRleEFycmF5KCk7XG4gICAgICAgIHRoaXMucHJvZ3JhbUNvbmZpZ3VyYXRpb25zID0gcHJvZ3JhbUNvbmZpZ3VyYXRpb25zO1xuICAgICAgICB0aGlzLnNlZ21lbnRzID0gbmV3IFNlZ21lbnRWZWN0b3IoKTtcbiAgICAgICAgdGhpcy5keW5hbWljTGF5b3V0VmVydGV4QXJyYXkgPSBuZXcgU3ltYm9sRHluYW1pY0xheW91dEFycmF5KCk7XG4gICAgICAgIHRoaXMub3BhY2l0eVZlcnRleEFycmF5ID0gbmV3IFN5bWJvbE9wYWNpdHlBcnJheSgpO1xuICAgICAgICB0aGlzLnBsYWNlZFN5bWJvbEFycmF5ID0gbmV3IFBsYWNlZFN5bWJvbEFycmF5KCk7XG4gICAgICAgIHRoaXMuZ2xvYmVFeHRWZXJ0ZXhBcnJheSA9IG5ldyBTeW1ib2xHbG9iZUV4dEFycmF5KCk7XG4gICAgfVxuXG4gICAgaXNFbXB0eSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubGF5b3V0VmVydGV4QXJyYXkubGVuZ3RoID09PSAwICYmXG4gICAgICAgICAgICB0aGlzLmluZGV4QXJyYXkubGVuZ3RoID09PSAwICYmXG4gICAgICAgICAgICB0aGlzLmR5bmFtaWNMYXlvdXRWZXJ0ZXhBcnJheS5sZW5ndGggPT09IDAgJiZcbiAgICAgICAgICAgIHRoaXMub3BhY2l0eVZlcnRleEFycmF5Lmxlbmd0aCA9PT0gMDtcbiAgICB9XG5cbiAgICB1cGxvYWQoY29udGV4dDogQ29udGV4dCwgZHluYW1pY0luZGV4QnVmZmVyOiBib29sZWFuLCB1cGxvYWQ/OiBib29sZWFuLCB1cGRhdGU/OiBib29sZWFuKSB7XG4gICAgICAgIGlmICh0aGlzLmlzRW1wdHkoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHVwbG9hZCkge1xuICAgICAgICAgICAgdGhpcy5sYXlvdXRWZXJ0ZXhCdWZmZXIgPSBjb250ZXh0LmNyZWF0ZVZlcnRleEJ1ZmZlcih0aGlzLmxheW91dFZlcnRleEFycmF5LCBzeW1ib2xMYXlvdXRBdHRyaWJ1dGVzLm1lbWJlcnMpO1xuICAgICAgICAgICAgdGhpcy5pbmRleEJ1ZmZlciA9IGNvbnRleHQuY3JlYXRlSW5kZXhCdWZmZXIodGhpcy5pbmRleEFycmF5LCBkeW5hbWljSW5kZXhCdWZmZXIpO1xuICAgICAgICAgICAgdGhpcy5keW5hbWljTGF5b3V0VmVydGV4QnVmZmVyID0gY29udGV4dC5jcmVhdGVWZXJ0ZXhCdWZmZXIodGhpcy5keW5hbWljTGF5b3V0VmVydGV4QXJyYXksIGR5bmFtaWNMYXlvdXRBdHRyaWJ1dGVzLm1lbWJlcnMsIHRydWUpO1xuICAgICAgICAgICAgdGhpcy5vcGFjaXR5VmVydGV4QnVmZmVyID0gY29udGV4dC5jcmVhdGVWZXJ0ZXhCdWZmZXIodGhpcy5vcGFjaXR5VmVydGV4QXJyYXksIHNoYWRlck9wYWNpdHlBdHRyaWJ1dGVzLCB0cnVlKTtcbiAgICAgICAgICAgIGlmICh0aGlzLmdsb2JlRXh0VmVydGV4QXJyYXkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZ2xvYmVFeHRWZXJ0ZXhCdWZmZXIgPSBjb250ZXh0LmNyZWF0ZVZlcnRleEJ1ZmZlcih0aGlzLmdsb2JlRXh0VmVydGV4QXJyYXksIHN5bWJvbEdsb2JlRXh0QXR0cmlidXRlcy5tZW1iZXJzLCB0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFRoaXMgaXMgYSBwZXJmb3JtYW5jZSBoYWNrIHNvIHRoYXQgd2UgY2FuIHdyaXRlIHRvIG9wYWNpdHlWZXJ0ZXhBcnJheSB3aXRoIHVpbnQzMnNcbiAgICAgICAgICAgIC8vIGV2ZW4gdGhvdWdoIHRoZSBzaGFkZXJzIHJlYWQgdWludDhzXG4gICAgICAgICAgICB0aGlzLm9wYWNpdHlWZXJ0ZXhCdWZmZXIuaXRlbVNpemUgPSAxO1xuICAgICAgICB9XG4gICAgICAgIGlmICh1cGxvYWQgfHwgdXBkYXRlKSB7XG4gICAgICAgICAgICB0aGlzLnByb2dyYW1Db25maWd1cmF0aW9ucy51cGxvYWQoY29udGV4dCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBkZXN0cm95KCkge1xuICAgICAgICBpZiAoIXRoaXMubGF5b3V0VmVydGV4QnVmZmVyKSByZXR1cm47XG4gICAgICAgIHRoaXMubGF5b3V0VmVydGV4QnVmZmVyLmRlc3Ryb3koKTtcbiAgICAgICAgdGhpcy5pbmRleEJ1ZmZlci5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMucHJvZ3JhbUNvbmZpZ3VyYXRpb25zLmRlc3Ryb3koKTtcbiAgICAgICAgdGhpcy5zZWdtZW50cy5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMuZHluYW1pY0xheW91dFZlcnRleEJ1ZmZlci5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMub3BhY2l0eVZlcnRleEJ1ZmZlci5kZXN0cm95KCk7XG4gICAgICAgIGlmICh0aGlzLmdsb2JlRXh0VmVydGV4QnVmZmVyKSB7XG4gICAgICAgICAgICB0aGlzLmdsb2JlRXh0VmVydGV4QnVmZmVyLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxucmVnaXN0ZXIoU3ltYm9sQnVmZmVycywgJ1N5bWJvbEJ1ZmZlcnMnKTtcblxuY2xhc3MgQ29sbGlzaW9uQnVmZmVycyB7XG4gICAgbGF5b3V0VmVydGV4QXJyYXk6IFN0cnVjdEFycmF5O1xuICAgIGxheW91dEF0dHJpYnV0ZXM6IEFycmF5PFN0cnVjdEFycmF5TWVtYmVyPjtcbiAgICBsYXlvdXRWZXJ0ZXhCdWZmZXI6IFZlcnRleEJ1ZmZlcjtcblxuICAgIGluZGV4QXJyYXk6IFRyaWFuZ2xlSW5kZXhBcnJheSB8IExpbmVJbmRleEFycmF5O1xuICAgIGluZGV4QnVmZmVyOiBJbmRleEJ1ZmZlcjtcblxuICAgIHNlZ21lbnRzOiBTZWdtZW50VmVjdG9yO1xuXG4gICAgY29sbGlzaW9uVmVydGV4QXJyYXk6IENvbGxpc2lvblZlcnRleEFycmF5O1xuICAgIGNvbGxpc2lvblZlcnRleEJ1ZmZlcjogVmVydGV4QnVmZmVyO1xuXG4gICAgY29sbGlzaW9uVmVydGV4QXJyYXlFeHQ6IENvbGxpc2lvblZlcnRleEV4dEFycmF5O1xuICAgIGNvbGxpc2lvblZlcnRleEJ1ZmZlckV4dDogVmVydGV4QnVmZmVyO1xuXG4gICAgY29uc3RydWN0b3IoTGF5b3V0QXJyYXk6IENsYXNzPFN0cnVjdEFycmF5PixcbiAgICAgICAgICAgICAgICBsYXlvdXRBdHRyaWJ1dGVzOiBBcnJheTxTdHJ1Y3RBcnJheU1lbWJlcj4sXG4gICAgICAgICAgICAgICAgSW5kZXhBcnJheTogQ2xhc3M8VHJpYW5nbGVJbmRleEFycmF5IHwgTGluZUluZGV4QXJyYXk+KSB7XG4gICAgICAgIHRoaXMubGF5b3V0VmVydGV4QXJyYXkgPSBuZXcgTGF5b3V0QXJyYXkoKTtcbiAgICAgICAgdGhpcy5sYXlvdXRBdHRyaWJ1dGVzID0gbGF5b3V0QXR0cmlidXRlcztcbiAgICAgICAgdGhpcy5pbmRleEFycmF5ID0gbmV3IEluZGV4QXJyYXkoKTtcbiAgICAgICAgdGhpcy5zZWdtZW50cyA9IG5ldyBTZWdtZW50VmVjdG9yKCk7XG4gICAgICAgIHRoaXMuY29sbGlzaW9uVmVydGV4QXJyYXkgPSBuZXcgQ29sbGlzaW9uVmVydGV4QXJyYXkoKTtcbiAgICAgICAgdGhpcy5jb2xsaXNpb25WZXJ0ZXhBcnJheUV4dCA9IG5ldyBDb2xsaXNpb25WZXJ0ZXhFeHRBcnJheSgpO1xuICAgIH1cblxuICAgIHVwbG9hZChjb250ZXh0OiBDb250ZXh0KSB7XG4gICAgICAgIHRoaXMubGF5b3V0VmVydGV4QnVmZmVyID0gY29udGV4dC5jcmVhdGVWZXJ0ZXhCdWZmZXIodGhpcy5sYXlvdXRWZXJ0ZXhBcnJheSwgdGhpcy5sYXlvdXRBdHRyaWJ1dGVzKTtcbiAgICAgICAgdGhpcy5pbmRleEJ1ZmZlciA9IGNvbnRleHQuY3JlYXRlSW5kZXhCdWZmZXIodGhpcy5pbmRleEFycmF5KTtcbiAgICAgICAgdGhpcy5jb2xsaXNpb25WZXJ0ZXhCdWZmZXIgPSBjb250ZXh0LmNyZWF0ZVZlcnRleEJ1ZmZlcih0aGlzLmNvbGxpc2lvblZlcnRleEFycmF5LCBjb2xsaXNpb25WZXJ0ZXhBdHRyaWJ1dGVzLm1lbWJlcnMsIHRydWUpO1xuICAgICAgICB0aGlzLmNvbGxpc2lvblZlcnRleEJ1ZmZlckV4dCA9IGNvbnRleHQuY3JlYXRlVmVydGV4QnVmZmVyKHRoaXMuY29sbGlzaW9uVmVydGV4QXJyYXlFeHQsIGNvbGxpc2lvblZlcnRleEF0dHJpYnV0ZXNFeHQubWVtYmVycywgdHJ1ZSk7XG4gICAgfVxuXG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmxheW91dFZlcnRleEJ1ZmZlcikgcmV0dXJuO1xuICAgICAgICB0aGlzLmxheW91dFZlcnRleEJ1ZmZlci5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMuaW5kZXhCdWZmZXIuZGVzdHJveSgpO1xuICAgICAgICB0aGlzLnNlZ21lbnRzLmRlc3Ryb3koKTtcbiAgICAgICAgdGhpcy5jb2xsaXNpb25WZXJ0ZXhCdWZmZXIuZGVzdHJveSgpO1xuICAgICAgICB0aGlzLmNvbGxpc2lvblZlcnRleEJ1ZmZlckV4dC5kZXN0cm95KCk7XG4gICAgfVxufVxuXG5yZWdpc3RlcihDb2xsaXNpb25CdWZmZXJzLCAnQ29sbGlzaW9uQnVmZmVycycpO1xuXG4vKipcbiAqIFVubGlrZSBvdGhlciBidWNrZXRzLCB3aGljaCBzaW1wbHkgaW1wbGVtZW50ICNhZGRGZWF0dXJlIHdpdGggdHlwZS1zcGVjaWZpY1xuICogbG9naWMgZm9yIChlc3NlbnRpYWxseSkgdHJpYW5ndWxhdGluZyBmZWF0dXJlIGdlb21ldHJpZXMsIFN5bWJvbEJ1Y2tldFxuICogcmVxdWlyZXMgc3BlY2lhbGl6ZWQgYmVoYXZpb3I6XG4gKlxuICogMS4gV29ya2VyVGlsZSNwYXJzZSgpLCB0aGUgbG9naWNhbCBvd25lciBvZiB0aGUgYnVja2V0IGNyZWF0aW9uIHByb2Nlc3MsXG4gKiAgICBjYWxscyBTeW1ib2xCdWNrZXQjcG9wdWxhdGUoKSwgd2hpY2ggcmVzb2x2ZXMgdGV4dCBhbmQgaWNvbiB0b2tlbnMgb25cbiAqICAgIGVhY2ggZmVhdHVyZSwgYWRkcyBlYWNoIGdseXBocyBhbmQgc3ltYm9scyBuZWVkZWQgdG8gdGhlIHBhc3NlZC1pblxuICogICAgY29sbGVjdGlvbnMgb3B0aW9ucy5nbHlwaERlcGVuZGVuY2llcyBhbmQgb3B0aW9ucy5pY29uRGVwZW5kZW5jaWVzLCBhbmRcbiAqICAgIHN0b3JlcyB0aGUgZmVhdHVyZSBkYXRhIGZvciB1c2UgaW4gc3Vic2VxdWVudCBzdGVwICh0aGlzLmZlYXR1cmVzKS5cbiAqXG4gKiAyLiBXb3JrZXJUaWxlIGFzeW5jaHJvbm91c2x5IHJlcXVlc3RzIGZyb20gdGhlIG1haW4gdGhyZWFkIGFsbCBvZiB0aGUgZ2x5cGhzXG4gKiAgICBhbmQgaWNvbnMgbmVlZGVkIChieSB0aGlzIGJ1Y2tldCBhbmQgYW55IG90aGVycykuIFdoZW4gZ2x5cGhzIGFuZCBpY29uc1xuICogICAgaGF2ZSBiZWVuIHJlY2VpdmVkLCB0aGUgV29ya2VyVGlsZSBjcmVhdGVzIGEgQ29sbGlzaW9uSW5kZXggYW5kIGludm9rZXM6XG4gKlxuICogMy4gcGVyZm9ybVN5bWJvbExheW91dChidWNrZXQsIHN0YWNrcywgaWNvbnMpIHBlcmZvcm0gdGV4dHMgc2hhcGluZyBhbmRcbiAqICAgIGxheW91dCBvbiBhIFN5bWJvbCBCdWNrZXQuIFRoaXMgc3RlcCBwb3B1bGF0ZXM6XG4gKiAgICAgIGB0aGlzLnN5bWJvbEluc3RhbmNlc2A6IG1ldGFkYXRhIG9uIGdlbmVyYXRlZCBzeW1ib2xzXG4gKiAgICAgIGBjb2xsaXNpb25Cb3hBcnJheWA6IGNvbGxpc2lvbiBkYXRhIGZvciB1c2UgYnkgZm9yZWdyb3VuZFxuICogICAgICBgdGhpcy50ZXh0YDogU3ltYm9sQnVmZmVycyBmb3IgdGV4dCBzeW1ib2xzXG4gKiAgICAgIGB0aGlzLmljb25zYDogU3ltYm9sQnVmZmVycyBmb3IgaWNvbnNcbiAqICAgICAgYHRoaXMuaWNvbkNvbGxpc2lvbkJveGA6IERlYnVnIFN5bWJvbEJ1ZmZlcnMgZm9yIGljb24gY29sbGlzaW9uIGJveGVzXG4gKiAgICAgIGB0aGlzLnRleHRDb2xsaXNpb25Cb3hgOiBEZWJ1ZyBTeW1ib2xCdWZmZXJzIGZvciB0ZXh0IGNvbGxpc2lvbiBib3hlc1xuICogICAgVGhlIHJlc3VsdHMgYXJlIHNlbnQgdG8gdGhlIGZvcmVncm91bmQgZm9yIHJlbmRlcmluZ1xuICpcbiAqIDQuIFBsYWNlbWVudC51cGRhdGVCdWNrZXRPcGFjaXRpZXMoKSBpcyBydW4gb24gdGhlIGZvcmVncm91bmQsXG4gKiAgICBhbmQgdXNlcyB0aGUgQ29sbGlzaW9uSW5kZXggYWxvbmcgd2l0aCBjdXJyZW50IGNhbWVyYSBzZXR0aW5ncyB0byBkZXRlcm1pbmVcbiAqICAgIHdoaWNoIHN5bWJvbHMgY2FuIGFjdHVhbGx5IHNob3cgb24gdGhlIG1hcC4gQ29sbGlkZWQgc3ltYm9scyBhcmUgaGlkZGVuXG4gKiAgICB1c2luZyBhIGR5bmFtaWMgXCJPcGFjaXR5VmVydGV4QXJyYXlcIi5cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5jbGFzcyBTeW1ib2xCdWNrZXQgaW1wbGVtZW50cyBCdWNrZXQge1xuICAgIHN0YXRpYyBNQVhfR0xZUEhTOiBudW1iZXI7XG4gICAgc3RhdGljIGFkZER5bmFtaWNBdHRyaWJ1dGVzOiB0eXBlb2YgYWRkRHluYW1pY0F0dHJpYnV0ZXM7XG5cbiAgICBjb2xsaXNpb25Cb3hBcnJheTogQ29sbGlzaW9uQm94QXJyYXk7XG4gICAgem9vbTogbnVtYmVyO1xuICAgIG92ZXJzY2FsaW5nOiBudW1iZXI7XG4gICAgbGF5ZXJzOiBBcnJheTxTeW1ib2xTdHlsZUxheWVyPjtcbiAgICBsYXllcklkczogQXJyYXk8c3RyaW5nPjtcbiAgICBzdGF0ZURlcGVuZGVudExheWVyczogQXJyYXk8U3ltYm9sU3R5bGVMYXllcj47XG4gICAgc3RhdGVEZXBlbmRlbnRMYXllcklkczogQXJyYXk8c3RyaW5nPjtcblxuICAgIGluZGV4OiBudW1iZXI7XG4gICAgc2RmSWNvbnM6IGJvb2xlYW47XG4gICAgaWNvbnNJblRleHQ6IGJvb2xlYW47XG4gICAgaWNvbnNOZWVkTGluZWFyOiBib29sZWFuO1xuICAgIGJ1Y2tldEluc3RhbmNlSWQ6IG51bWJlcjtcbiAgICBqdXN0UmVsb2FkZWQ6IGJvb2xlYW47XG4gICAgaGFzUGF0dGVybjogYm9vbGVhbjtcbiAgICBmdWxseUNsaXBwZWQ6IGJvb2xlYW47XG5cbiAgICB0ZXh0U2l6ZURhdGE6IFNpemVEYXRhO1xuICAgIGljb25TaXplRGF0YTogU2l6ZURhdGE7XG5cbiAgICBnbHlwaE9mZnNldEFycmF5OiBHbHlwaE9mZnNldEFycmF5O1xuICAgIGxpbmVWZXJ0ZXhBcnJheTogU3ltYm9sTGluZVZlcnRleEFycmF5O1xuICAgIGZlYXR1cmVzOiBBcnJheTxTeW1ib2xGZWF0dXJlPjtcbiAgICBzeW1ib2xJbnN0YW5jZXM6IFN5bWJvbEluc3RhbmNlQXJyYXk7XG4gICAgY29sbGlzaW9uQXJyYXlzOiBBcnJheTxDb2xsaXNpb25BcnJheXM+O1xuICAgIHNvcnRLZXlSYW5nZXM6IEFycmF5PFNvcnRLZXlSYW5nZT47XG4gICAgcGl4ZWxSYXRpbzogbnVtYmVyO1xuICAgIHRpbGVQaXhlbFJhdGlvOiBudW1iZXI7XG4gICAgY29tcGFyZVRleHQ6IHtbXzogc3RyaW5nXTogQXJyYXk8UG9pbnQ+fTtcbiAgICBmYWRlU3RhcnRUaW1lOiBudW1iZXI7XG4gICAgc29ydEZlYXR1cmVzQnlLZXk6IGJvb2xlYW47XG4gICAgc29ydEZlYXR1cmVzQnlZOiBib29sZWFuO1xuICAgIGNhbk92ZXJsYXA6IGJvb2xlYW47XG4gICAgc29ydGVkQW5nbGU6IG51bWJlcjtcbiAgICBmZWF0dXJlU29ydE9yZGVyOiBBcnJheTxudW1iZXI+O1xuXG4gICAgY29sbGlzaW9uQ2lyY2xlQXJyYXk6IEFycmF5PG51bWJlcj47XG4gICAgcGxhY2VtZW50SW52UHJvak1hdHJpeDogTWF0NDtcbiAgICBwbGFjZW1lbnRWaWV3cG9ydE1hdHJpeDogTWF0NDtcblxuICAgIHRleHQ6IFN5bWJvbEJ1ZmZlcnM7XG4gICAgaWNvbjogU3ltYm9sQnVmZmVycztcbiAgICB0ZXh0Q29sbGlzaW9uQm94OiBDb2xsaXNpb25CdWZmZXJzO1xuICAgIGljb25Db2xsaXNpb25Cb3g6IENvbGxpc2lvbkJ1ZmZlcnM7XG4gICAgdXBsb2FkZWQ6IGJvb2xlYW47XG4gICAgc291cmNlTGF5ZXJJbmRleDogbnVtYmVyO1xuICAgIHNvdXJjZUlEOiBzdHJpbmc7XG4gICAgc3ltYm9sSW5zdGFuY2VJbmRleGVzOiBBcnJheTxudW1iZXI+O1xuICAgIHdyaXRpbmdNb2RlczogQXJyYXk8bnVtYmVyPjtcbiAgICBhbGxvd1ZlcnRpY2FsUGxhY2VtZW50OiBib29sZWFuO1xuICAgIGhhc1JUTFRleHQ6IGJvb2xlYW47XG4gICAgcHJvamVjdGlvbjogUHJvamVjdGlvblNwZWNpZmljYXRpb247XG4gICAgcHJvamVjdGlvbkluc3RhbmNlOiA/UHJvamVjdGlvbjtcblxuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnM6IEJ1Y2tldFBhcmFtZXRlcnM8U3ltYm9sU3R5bGVMYXllcj4pIHtcbiAgICAgICAgdGhpcy5jb2xsaXNpb25Cb3hBcnJheSA9IG9wdGlvbnMuY29sbGlzaW9uQm94QXJyYXk7XG4gICAgICAgIHRoaXMuem9vbSA9IG9wdGlvbnMuem9vbTtcbiAgICAgICAgdGhpcy5vdmVyc2NhbGluZyA9IG9wdGlvbnMub3ZlcnNjYWxpbmc7XG4gICAgICAgIHRoaXMubGF5ZXJzID0gb3B0aW9ucy5sYXllcnM7XG4gICAgICAgIHRoaXMubGF5ZXJJZHMgPSB0aGlzLmxheWVycy5tYXAobGF5ZXIgPT4gbGF5ZXIuaWQpO1xuICAgICAgICB0aGlzLmluZGV4ID0gb3B0aW9ucy5pbmRleDtcbiAgICAgICAgdGhpcy5waXhlbFJhdGlvID0gb3B0aW9ucy5waXhlbFJhdGlvO1xuICAgICAgICB0aGlzLnNvdXJjZUxheWVySW5kZXggPSBvcHRpb25zLnNvdXJjZUxheWVySW5kZXg7XG4gICAgICAgIHRoaXMuaGFzUGF0dGVybiA9IGZhbHNlO1xuICAgICAgICB0aGlzLmhhc1JUTFRleHQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5mdWxseUNsaXBwZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5zb3J0S2V5UmFuZ2VzID0gW107XG5cbiAgICAgICAgdGhpcy5jb2xsaXNpb25DaXJjbGVBcnJheSA9IFtdO1xuICAgICAgICB0aGlzLnBsYWNlbWVudEludlByb2pNYXRyaXggPSBtYXQ0LmlkZW50aXR5KFtdKTtcbiAgICAgICAgdGhpcy5wbGFjZW1lbnRWaWV3cG9ydE1hdHJpeCA9IG1hdDQuaWRlbnRpdHkoW10pO1xuXG4gICAgICAgIGNvbnN0IGxheWVyID0gdGhpcy5sYXllcnNbMF07XG4gICAgICAgIGNvbnN0IHVuZXZhbHVhdGVkTGF5b3V0VmFsdWVzID0gbGF5ZXIuX3VuZXZhbHVhdGVkTGF5b3V0Ll92YWx1ZXM7XG5cbiAgICAgICAgdGhpcy50ZXh0U2l6ZURhdGEgPSBnZXRTaXplRGF0YSh0aGlzLnpvb20sIHVuZXZhbHVhdGVkTGF5b3V0VmFsdWVzWyd0ZXh0LXNpemUnXSk7XG4gICAgICAgIHRoaXMuaWNvblNpemVEYXRhID0gZ2V0U2l6ZURhdGEodGhpcy56b29tLCB1bmV2YWx1YXRlZExheW91dFZhbHVlc1snaWNvbi1zaXplJ10pO1xuXG4gICAgICAgIGNvbnN0IGxheW91dCA9IHRoaXMubGF5ZXJzWzBdLmxheW91dDtcbiAgICAgICAgY29uc3Qgc29ydEtleSA9IGxheW91dC5nZXQoJ3N5bWJvbC1zb3J0LWtleScpO1xuICAgICAgICBjb25zdCB6T3JkZXIgPSBsYXlvdXQuZ2V0KCdzeW1ib2wtei1vcmRlcicpO1xuICAgICAgICB0aGlzLmNhbk92ZXJsYXAgPVxuICAgICAgICAgICAgbGF5b3V0LmdldCgndGV4dC1hbGxvdy1vdmVybGFwJykgfHxcbiAgICAgICAgICAgIGxheW91dC5nZXQoJ2ljb24tYWxsb3ctb3ZlcmxhcCcpIHx8XG4gICAgICAgICAgICBsYXlvdXQuZ2V0KCd0ZXh0LWlnbm9yZS1wbGFjZW1lbnQnKSB8fFxuICAgICAgICAgICAgbGF5b3V0LmdldCgnaWNvbi1pZ25vcmUtcGxhY2VtZW50Jyk7XG4gICAgICAgIHRoaXMuc29ydEZlYXR1cmVzQnlLZXkgPSB6T3JkZXIgIT09ICd2aWV3cG9ydC15JyAmJiBzb3J0S2V5LmNvbnN0YW50T3IoMSkgIT09IHVuZGVmaW5lZDtcbiAgICAgICAgY29uc3Qgek9yZGVyQnlWaWV3cG9ydFkgPSB6T3JkZXIgPT09ICd2aWV3cG9ydC15JyB8fCAoek9yZGVyID09PSAnYXV0bycgJiYgIXRoaXMuc29ydEZlYXR1cmVzQnlLZXkpO1xuICAgICAgICB0aGlzLnNvcnRGZWF0dXJlc0J5WSA9IHpPcmRlckJ5Vmlld3BvcnRZICYmIHRoaXMuY2FuT3ZlcmxhcDtcblxuICAgICAgICB0aGlzLndyaXRpbmdNb2RlcyA9IGxheW91dC5nZXQoJ3RleHQtd3JpdGluZy1tb2RlJykubWFwKHdtID0+IFdyaXRpbmdNb2RlW3dtXSk7XG5cbiAgICAgICAgdGhpcy5zdGF0ZURlcGVuZGVudExheWVySWRzID0gdGhpcy5sYXllcnMuZmlsdGVyKChsKSA9PiBsLmlzU3RhdGVEZXBlbmRlbnQoKSkubWFwKChsKSA9PiBsLmlkKTtcblxuICAgICAgICB0aGlzLnNvdXJjZUlEID0gb3B0aW9ucy5zb3VyY2VJRDtcbiAgICAgICAgdGhpcy5wcm9qZWN0aW9uID0gb3B0aW9ucy5wcm9qZWN0aW9uO1xuICAgIH1cblxuICAgIGNyZWF0ZUFycmF5cygpIHtcbiAgICAgICAgdGhpcy50ZXh0ID0gbmV3IFN5bWJvbEJ1ZmZlcnMobmV3IFByb2dyYW1Db25maWd1cmF0aW9uU2V0KHRoaXMubGF5ZXJzLCB0aGlzLnpvb20sIHByb3BlcnR5ID0+IC9edGV4dC8udGVzdChwcm9wZXJ0eSkpKTtcbiAgICAgICAgdGhpcy5pY29uID0gbmV3IFN5bWJvbEJ1ZmZlcnMobmV3IFByb2dyYW1Db25maWd1cmF0aW9uU2V0KHRoaXMubGF5ZXJzLCB0aGlzLnpvb20sIHByb3BlcnR5ID0+IC9eaWNvbi8udGVzdChwcm9wZXJ0eSkpKTtcblxuICAgICAgICB0aGlzLmdseXBoT2Zmc2V0QXJyYXkgPSBuZXcgR2x5cGhPZmZzZXRBcnJheSgpO1xuICAgICAgICB0aGlzLmxpbmVWZXJ0ZXhBcnJheSA9IG5ldyBTeW1ib2xMaW5lVmVydGV4QXJyYXkoKTtcbiAgICAgICAgdGhpcy5zeW1ib2xJbnN0YW5jZXMgPSBuZXcgU3ltYm9sSW5zdGFuY2VBcnJheSgpO1xuICAgIH1cblxuICAgIGNhbGN1bGF0ZUdseXBoRGVwZW5kZW5jaWVzKHRleHQ6IHN0cmluZywgc3RhY2s6IHtbXzogbnVtYmVyXTogYm9vbGVhbn0sIHRleHRBbG9uZ0xpbmU6IGJvb2xlYW4sIGFsbG93VmVydGljYWxQbGFjZW1lbnQ6IGJvb2xlYW4sIGRvZXNBbGxvd1ZlcnRpY2FsV3JpdGluZ01vZGU6IGJvb2xlYW4pIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0ZXh0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBzdGFja1t0ZXh0LmNoYXJDb2RlQXQoaSldID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChhbGxvd1ZlcnRpY2FsUGxhY2VtZW50ICYmIGRvZXNBbGxvd1ZlcnRpY2FsV3JpdGluZ01vZGUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB2ZXJ0aWNhbENoYXIgPSB2ZXJ0aWNhbGl6ZWRDaGFyYWN0ZXJNYXBbdGV4dC5jaGFyQXQoaSldO1xuICAgICAgICAgICAgICAgIGlmICh2ZXJ0aWNhbENoYXIpIHtcbiAgICAgICAgICAgICAgICAgICAgc3RhY2tbdmVydGljYWxDaGFyLmNoYXJDb2RlQXQoMCldID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwb3B1bGF0ZShmZWF0dXJlczogQXJyYXk8SW5kZXhlZEZlYXR1cmU+LCBvcHRpb25zOiBQb3B1bGF0ZVBhcmFtZXRlcnMsIGNhbm9uaWNhbDogQ2Fub25pY2FsVGlsZUlELCB0aWxlVHJhbnNmb3JtOiBUaWxlVHJhbnNmb3JtKSB7XG4gICAgICAgIGNvbnN0IGxheWVyID0gdGhpcy5sYXllcnNbMF07XG4gICAgICAgIGNvbnN0IGxheW91dCA9IGxheWVyLmxheW91dDtcbiAgICAgICAgY29uc3QgaXNHbG9iZSA9IHRoaXMucHJvamVjdGlvbi5uYW1lID09PSAnZ2xvYmUnO1xuXG4gICAgICAgIGNvbnN0IHRleHRGb250ID0gbGF5b3V0LmdldCgndGV4dC1mb250Jyk7XG4gICAgICAgIGNvbnN0IHRleHRGaWVsZCA9IGxheW91dC5nZXQoJ3RleHQtZmllbGQnKTtcbiAgICAgICAgY29uc3QgaWNvbkltYWdlID0gbGF5b3V0LmdldCgnaWNvbi1pbWFnZScpO1xuICAgICAgICBjb25zdCBoYXNUZXh0ID1cbiAgICAgICAgICAgICh0ZXh0RmllbGQudmFsdWUua2luZCAhPT0gJ2NvbnN0YW50JyB8fFxuICAgICAgICAgICAgICAgICh0ZXh0RmllbGQudmFsdWUudmFsdWUgaW5zdGFuY2VvZiBGb3JtYXR0ZWQgJiYgIXRleHRGaWVsZC52YWx1ZS52YWx1ZS5pc0VtcHR5KCkpIHx8XG4gICAgICAgICAgICAgICAgdGV4dEZpZWxkLnZhbHVlLnZhbHVlLnRvU3RyaW5nKCkubGVuZ3RoID4gMCkgJiZcbiAgICAgICAgICAgICh0ZXh0Rm9udC52YWx1ZS5raW5kICE9PSAnY29uc3RhbnQnIHx8IHRleHRGb250LnZhbHVlLnZhbHVlLmxlbmd0aCA+IDApO1xuICAgICAgICAvLyB3ZSBzaG91bGQgYWx3YXlzIHJlc29sdmUgdGhlIGljb24taW1hZ2UgdmFsdWUgaWYgdGhlIHByb3BlcnR5IHdhcyBkZWZpbmVkIGluIHRoZSBzdHlsZVxuICAgICAgICAvLyB0aGlzIGFsbG93cyB1cyB0byBmaXJlIHRoZSBzdHlsZWltYWdlbWlzc2luZyBldmVudCBpZiBpbWFnZSBldmFsdWF0aW9uIHJldHVybnMgbnVsbFxuICAgICAgICAvLyB0aGUgb25seSB3YXkgdG8gZGlzdGluZ3Vpc2ggYmV0d2VlbiBudWxsIHJldHVybmVkIGZyb20gYSBjb2FsZXNjZSBzdGF0ZW1lbnQgd2l0aCBubyB2YWxpZCBpbWFnZXNcbiAgICAgICAgLy8gYW5kIG51bGwgcmV0dXJuZWQgYmVjYXVzZSBpY29uLWltYWdlIHdhc24ndCBkZWZpbmVkIGlzIHRvIGNoZWNrIHdoZXRoZXIgb3Igbm90IGljb25JbWFnZS5wYXJhbWV0ZXJzIGlzIGFuIGVtcHR5IG9iamVjdFxuICAgICAgICBjb25zdCBoYXNJY29uID0gaWNvbkltYWdlLnZhbHVlLmtpbmQgIT09ICdjb25zdGFudCcgfHwgISFpY29uSW1hZ2UudmFsdWUudmFsdWUgfHwgT2JqZWN0LmtleXMoaWNvbkltYWdlLnBhcmFtZXRlcnMpLmxlbmd0aCA+IDA7XG4gICAgICAgIGNvbnN0IHN5bWJvbFNvcnRLZXkgPSBsYXlvdXQuZ2V0KCdzeW1ib2wtc29ydC1rZXknKTtcblxuICAgICAgICB0aGlzLmZlYXR1cmVzID0gW107XG5cbiAgICAgICAgaWYgKCFoYXNUZXh0ICYmICFoYXNJY29uKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBpY29ucyA9IG9wdGlvbnMuaWNvbkRlcGVuZGVuY2llcztcbiAgICAgICAgY29uc3Qgc3RhY2tzID0gb3B0aW9ucy5nbHlwaERlcGVuZGVuY2llcztcbiAgICAgICAgY29uc3QgYXZhaWxhYmxlSW1hZ2VzID0gb3B0aW9ucy5hdmFpbGFibGVJbWFnZXM7XG4gICAgICAgIGNvbnN0IGdsb2JhbFByb3BlcnRpZXMgPSBuZXcgRXZhbHVhdGlvblBhcmFtZXRlcnModGhpcy56b29tKTtcblxuICAgICAgICBmb3IgKGNvbnN0IHtmZWF0dXJlLCBpZCwgaW5kZXgsIHNvdXJjZUxheWVySW5kZXh9IG9mIGZlYXR1cmVzKSB7XG5cbiAgICAgICAgICAgIGNvbnN0IG5lZWRHZW9tZXRyeSA9IGxheWVyLl9mZWF0dXJlRmlsdGVyLm5lZWRHZW9tZXRyeTtcbiAgICAgICAgICAgIGNvbnN0IGV2YWx1YXRpb25GZWF0dXJlID0gdG9FdmFsdWF0aW9uRmVhdHVyZShmZWF0dXJlLCBuZWVkR2VvbWV0cnkpO1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgaWYgKCFsYXllci5fZmVhdHVyZUZpbHRlci5maWx0ZXIoZ2xvYmFsUHJvcGVydGllcywgZXZhbHVhdGlvbkZlYXR1cmUsIGNhbm9uaWNhbCkpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFuZWVkR2VvbWV0cnkpIGV2YWx1YXRpb25GZWF0dXJlLmdlb21ldHJ5ID0gbG9hZEdlb21ldHJ5KGZlYXR1cmUsIGNhbm9uaWNhbCwgdGlsZVRyYW5zZm9ybSk7XG5cbiAgICAgICAgICAgIGlmIChpc0dsb2JlICYmIGZlYXR1cmUudHlwZSAhPT0gMSAmJiBjYW5vbmljYWwueiA8PSA1KSB7XG4gICAgICAgICAgICAgICAgLy8gUmVzYW1wbGUgbG9uZyBsaW5lcyBhbmQgcG9seWdvbnMgaW4gZ2xvYmUgdmlldyBzbyB0aGF0IHRoZWlyIGxlbmd0aCB3b250IGV4Y2VlZCB+MC4xOSByYWRpYW5zICgzNjAvMzIgZGVncmVlcykuXG4gICAgICAgICAgICAgICAgLy8gT3RoZXJ3aXNlIGxpbmVzIGNvdWxkIGNsaXAgdGhyb3VnaCB0aGUgZ2xvYmUgYXMgdGhlIHJlc29sdXRpb24gaXMgbm90IGVub3VnaCB0byByZXByZXNlbnQgY3VydmVkIHBhdGhzLlxuICAgICAgICAgICAgICAgIC8vIFRoZSB0aHJlc2hvbGQgdmFsdWUgZm9sbG93cyBzdWJkaXZpc2lvbiBzaXplIHVzZWQgd2l0aCBmaWxsIGV4dHJ1c2lvbnNcbiAgICAgICAgICAgICAgICBjb25zdCBnZW9tID0gZXZhbHVhdGlvbkZlYXR1cmUuZ2VvbWV0cnk7XG5cbiAgICAgICAgICAgICAgICAvLyBjb3MoMTEuMjUgZGVncmVlcykgPSAwLjk4MDc4NTI4MDU2XG4gICAgICAgICAgICAgICAgY29uc3QgY29zQW5nbGVUaHJlc2hvbGQgPSAwLjk4MDc4NTI4MDU2O1xuICAgICAgICAgICAgICAgIGNvbnN0IHByZWRpY2F0ZSA9IChhOiBQb2ludCwgYjogUG9pbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdjAgPSB0aWxlQ29vcmRUb0VDRUYoYS54LCBhLnksIGNhbm9uaWNhbCwgMSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHYxID0gdGlsZUNvb3JkVG9FQ0VGKGIueCwgYi55LCBjYW5vbmljYWwsIDEpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmVjMy5kb3QodjAsIHYxKSA8IGNvc0FuZ2xlVGhyZXNob2xkO1xuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGdlb20ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgZ2VvbVtpXSA9IHJlc2FtcGxlUHJlZChnZW9tW2ldLCBwcmVkaWNhdGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IHRleHQ6IEZvcm1hdHRlZCB8IHZvaWQ7XG4gICAgICAgICAgICBpZiAoaGFzVGV4dCkge1xuICAgICAgICAgICAgICAgIC8vIEV4cHJlc3Npb24gZXZhbHVhdGlvbiB3aWxsIGF1dG9tYXRpY2FsbHkgY29lcmNlIHRvIEZvcm1hdHRlZFxuICAgICAgICAgICAgICAgIC8vIGJ1dCBwbGFpbiBzdHJpbmcgdG9rZW4gZXZhbHVhdGlvbiBza2lwcyB0aGF0IHBhdGh3YXkgc28gZG8gdGhlXG4gICAgICAgICAgICAgICAgLy8gY29udmVyc2lvbiBoZXJlLlxuICAgICAgICAgICAgICAgIGNvbnN0IHJlc29sdmVkVG9rZW5zID0gbGF5ZXIuZ2V0VmFsdWVBbmRSZXNvbHZlVG9rZW5zKCd0ZXh0LWZpZWxkJywgZXZhbHVhdGlvbkZlYXR1cmUsIGNhbm9uaWNhbCwgYXZhaWxhYmxlSW1hZ2VzKTtcbiAgICAgICAgICAgICAgICBjb25zdCBmb3JtYXR0ZWRUZXh0ID0gRm9ybWF0dGVkLmZhY3RvcnkocmVzb2x2ZWRUb2tlbnMpO1xuICAgICAgICAgICAgICAgIGlmIChjb250YWluc1JUTFRleHQoZm9ybWF0dGVkVGV4dCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oYXNSVExUZXh0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAhdGhpcy5oYXNSVExUZXh0IHx8IC8vIG5vbi1ydGwgdGV4dCBzbyBjYW4gcHJvY2VlZCBzYWZlbHlcbiAgICAgICAgICAgICAgICAgICAgZ2V0UlRMVGV4dFBsdWdpblN0YXR1cygpID09PSAndW5hdmFpbGFibGUnIHx8IC8vIFdlIGRvbid0IGludGVuZCB0byBsYXp5LWxvYWQgdGhlIHJ0bCB0ZXh0IHBsdWdpbiwgc28gcHJvY2VlZCB3aXRoIGluY29ycmVjdCBzaGFwaW5nXG4gICAgICAgICAgICAgICAgICAgICh0aGlzLmhhc1JUTFRleHQgJiYgZ2xvYmFsUlRMVGV4dFBsdWdpbi5pc1BhcnNlZCgpKSAvLyBVc2UgdGhlIHJ0bFRleHQgcGx1Z2luIHRvIHNoYXBlIHRleHRcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgdGV4dCA9IHRyYW5zZm9ybVRleHQoZm9ybWF0dGVkVGV4dCwgbGF5ZXIsIGV2YWx1YXRpb25GZWF0dXJlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBpY29uOiA/UmVzb2x2ZWRJbWFnZTtcbiAgICAgICAgICAgIGlmIChoYXNJY29uKSB7XG4gICAgICAgICAgICAgICAgLy8gRXhwcmVzc2lvbiBldmFsdWF0aW9uIHdpbGwgYXV0b21hdGljYWxseSBjb2VyY2UgdG8gSW1hZ2VcbiAgICAgICAgICAgICAgICAvLyBidXQgcGxhaW4gc3RyaW5nIHRva2VuIGV2YWx1YXRpb24gc2tpcHMgdGhhdCBwYXRod2F5IHNvIGRvIHRoZVxuICAgICAgICAgICAgICAgIC8vIGNvbnZlcnNpb24gaGVyZS5cbiAgICAgICAgICAgICAgICBjb25zdCByZXNvbHZlZFRva2VucyA9IGxheWVyLmdldFZhbHVlQW5kUmVzb2x2ZVRva2VucygnaWNvbi1pbWFnZScsIGV2YWx1YXRpb25GZWF0dXJlLCBjYW5vbmljYWwsIGF2YWlsYWJsZUltYWdlcyk7XG4gICAgICAgICAgICAgICAgaWYgKHJlc29sdmVkVG9rZW5zIGluc3RhbmNlb2YgUmVzb2x2ZWRJbWFnZSkge1xuICAgICAgICAgICAgICAgICAgICBpY29uID0gcmVzb2x2ZWRUb2tlbnM7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWNvbiA9IFJlc29sdmVkSW1hZ2UuZnJvbVN0cmluZyhyZXNvbHZlZFRva2Vucyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIXRleHQgJiYgIWljb24pIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHNvcnRLZXkgPSB0aGlzLnNvcnRGZWF0dXJlc0J5S2V5ID9cbiAgICAgICAgICAgICAgICBzeW1ib2xTb3J0S2V5LmV2YWx1YXRlKGV2YWx1YXRpb25GZWF0dXJlLCB7fSwgY2Fub25pY2FsKSA6XG4gICAgICAgICAgICAgICAgdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICBjb25zdCBzeW1ib2xGZWF0dXJlOiBTeW1ib2xGZWF0dXJlID0ge1xuICAgICAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgICAgIHRleHQsXG4gICAgICAgICAgICAgICAgaWNvbixcbiAgICAgICAgICAgICAgICBpbmRleCxcbiAgICAgICAgICAgICAgICBzb3VyY2VMYXllckluZGV4LFxuICAgICAgICAgICAgICAgIGdlb21ldHJ5OiBldmFsdWF0aW9uRmVhdHVyZS5nZW9tZXRyeSxcbiAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiBmZWF0dXJlLnByb3BlcnRpZXMsXG4gICAgICAgICAgICAgICAgdHlwZTogdmVjdG9yVGlsZUZlYXR1cmVUeXBlc1tmZWF0dXJlLnR5cGVdLFxuICAgICAgICAgICAgICAgIHNvcnRLZXlcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLmZlYXR1cmVzLnB1c2goc3ltYm9sRmVhdHVyZSk7XG5cbiAgICAgICAgICAgIGlmIChpY29uKSB7XG4gICAgICAgICAgICAgICAgaWNvbnNbaWNvbi5uYW1lXSA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZm9udFN0YWNrID0gdGV4dEZvbnQuZXZhbHVhdGUoZXZhbHVhdGlvbkZlYXR1cmUsIHt9LCBjYW5vbmljYWwpLmpvaW4oJywnKTtcbiAgICAgICAgICAgICAgICBjb25zdCB0ZXh0QWxvbmdMaW5lID0gbGF5b3V0LmdldCgndGV4dC1yb3RhdGlvbi1hbGlnbm1lbnQnKSA9PT0gJ21hcCcgJiYgbGF5b3V0LmdldCgnc3ltYm9sLXBsYWNlbWVudCcpICE9PSAncG9pbnQnO1xuICAgICAgICAgICAgICAgIHRoaXMuYWxsb3dWZXJ0aWNhbFBsYWNlbWVudCA9IHRoaXMud3JpdGluZ01vZGVzICYmIHRoaXMud3JpdGluZ01vZGVzLmluZGV4T2YoV3JpdGluZ01vZGUudmVydGljYWwpID49IDA7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBzZWN0aW9uIG9mIHRleHQuc2VjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFzZWN0aW9uLmltYWdlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkb2VzQWxsb3dWZXJ0aWNhbFdyaXRpbmdNb2RlID0gYWxsb3dzVmVydGljYWxXcml0aW5nTW9kZSh0ZXh0LnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2VjdGlvbkZvbnQgPSBzZWN0aW9uLmZvbnRTdGFjayB8fCBmb250U3RhY2s7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzZWN0aW9uU3RhY2sgPSBzdGFja3Nbc2VjdGlvbkZvbnRdID0gc3RhY2tzW3NlY3Rpb25Gb250XSB8fCB7fTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2FsY3VsYXRlR2x5cGhEZXBlbmRlbmNpZXMoc2VjdGlvbi50ZXh0LCBzZWN0aW9uU3RhY2ssIHRleHRBbG9uZ0xpbmUsIHRoaXMuYWxsb3dWZXJ0aWNhbFBsYWNlbWVudCwgZG9lc0FsbG93VmVydGljYWxXcml0aW5nTW9kZSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBBZGQgc2VjdGlvbiBpbWFnZSB0byB0aGUgbGlzdCBvZiBkZXBlbmRlbmNpZXMuXG4gICAgICAgICAgICAgICAgICAgICAgICBpY29uc1tzZWN0aW9uLmltYWdlLm5hbWVdID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChsYXlvdXQuZ2V0KCdzeW1ib2wtcGxhY2VtZW50JykgPT09ICdsaW5lJykge1xuICAgICAgICAgICAgLy8gTWVyZ2UgYWRqYWNlbnQgbGluZXMgd2l0aCB0aGUgc2FtZSB0ZXh0IHRvIGltcHJvdmUgbGFiZWxsaW5nLlxuICAgICAgICAgICAgLy8gSXQncyBiZXR0ZXIgdG8gcGxhY2UgbGFiZWxzIG9uIG9uZSBsb25nIGxpbmUgdGhhbiBvbiBtYW55IHNob3J0IHNlZ21lbnRzLlxuICAgICAgICAgICAgdGhpcy5mZWF0dXJlcyA9IG1lcmdlTGluZXModGhpcy5mZWF0dXJlcyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5zb3J0RmVhdHVyZXNCeUtleSkge1xuICAgICAgICAgICAgdGhpcy5mZWF0dXJlcy5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gYS5zb3J0S2V5IGlzIGFsd2F5cyBhIG51bWJlciB3aGVuIHNvcnRGZWF0dXJlc0J5S2V5IGlzIHRydWVcbiAgICAgICAgICAgICAgICByZXR1cm4gKChhLnNvcnRLZXk6IGFueSk6IG51bWJlcikgLSAoKGIuc29ydEtleTogYW55KTogbnVtYmVyKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdXBkYXRlKHN0YXRlczogRmVhdHVyZVN0YXRlcywgdnRMYXllcjogSVZlY3RvclRpbGVMYXllciwgYXZhaWxhYmxlSW1hZ2VzOiBBcnJheTxzdHJpbmc+LCBpbWFnZVBvc2l0aW9uczogU3ByaXRlUG9zaXRpb25zKSB7XG4gICAgICAgIGlmICghdGhpcy5zdGF0ZURlcGVuZGVudExheWVycy5sZW5ndGgpIHJldHVybjtcbiAgICAgICAgdGhpcy50ZXh0LnByb2dyYW1Db25maWd1cmF0aW9ucy51cGRhdGVQYWludEFycmF5cyhzdGF0ZXMsIHZ0TGF5ZXIsIHRoaXMubGF5ZXJzLCBhdmFpbGFibGVJbWFnZXMsIGltYWdlUG9zaXRpb25zKTtcbiAgICAgICAgdGhpcy5pY29uLnByb2dyYW1Db25maWd1cmF0aW9ucy51cGRhdGVQYWludEFycmF5cyhzdGF0ZXMsIHZ0TGF5ZXIsIHRoaXMubGF5ZXJzLCBhdmFpbGFibGVJbWFnZXMsIGltYWdlUG9zaXRpb25zKTtcbiAgICB9XG5cbiAgICBpc0VtcHR5KCk6IGJvb2xlYW4ge1xuICAgICAgICAvLyBXaGVuIHRoZSBidWNrZXQgZW5jb3VudGVycyBvbmx5IHJ0bC10ZXh0IGJ1dCB0aGUgcGx1Z2luIGlzbid0IGxvYWRlZCwgbm8gc3ltYm9sIGluc3RhbmNlcyB3aWxsIGJlIGNyZWF0ZWQuXG4gICAgICAgIC8vIEluIG9yZGVyIGZvciB0aGUgYnVja2V0IHRvIGJlIHNlcmlhbGl6ZWQsIGFuZCBub3QgZGlzY2FyZGVkIGFzIGFuIGVtcHR5IGJ1Y2tldCBib3RoIGNoZWNrcyBhcmUgbmVjZXNzYXJ5LlxuICAgICAgICByZXR1cm4gdGhpcy5zeW1ib2xJbnN0YW5jZXMubGVuZ3RoID09PSAwICYmICF0aGlzLmhhc1JUTFRleHQ7XG4gICAgfVxuXG4gICAgdXBsb2FkUGVuZGluZygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICF0aGlzLnVwbG9hZGVkIHx8IHRoaXMudGV4dC5wcm9ncmFtQ29uZmlndXJhdGlvbnMubmVlZHNVcGxvYWQgfHwgdGhpcy5pY29uLnByb2dyYW1Db25maWd1cmF0aW9ucy5uZWVkc1VwbG9hZDtcbiAgICB9XG5cbiAgICB1cGxvYWQoY29udGV4dDogQ29udGV4dCkge1xuICAgICAgICBpZiAoIXRoaXMudXBsb2FkZWQgJiYgdGhpcy5oYXNEZWJ1Z0RhdGEoKSkge1xuICAgICAgICAgICAgdGhpcy50ZXh0Q29sbGlzaW9uQm94LnVwbG9hZChjb250ZXh0KTtcbiAgICAgICAgICAgIHRoaXMuaWNvbkNvbGxpc2lvbkJveC51cGxvYWQoY29udGV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50ZXh0LnVwbG9hZChjb250ZXh0LCB0aGlzLnNvcnRGZWF0dXJlc0J5WSwgIXRoaXMudXBsb2FkZWQsIHRoaXMudGV4dC5wcm9ncmFtQ29uZmlndXJhdGlvbnMubmVlZHNVcGxvYWQpO1xuICAgICAgICB0aGlzLmljb24udXBsb2FkKGNvbnRleHQsIHRoaXMuc29ydEZlYXR1cmVzQnlZLCAhdGhpcy51cGxvYWRlZCwgdGhpcy5pY29uLnByb2dyYW1Db25maWd1cmF0aW9ucy5uZWVkc1VwbG9hZCk7XG4gICAgICAgIHRoaXMudXBsb2FkZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIGRlc3Ryb3lEZWJ1Z0RhdGEoKSB7XG4gICAgICAgIHRoaXMudGV4dENvbGxpc2lvbkJveC5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMuaWNvbkNvbGxpc2lvbkJveC5kZXN0cm95KCk7XG4gICAgfVxuXG4gICAgZ2V0UHJvamVjdGlvbigpOiBQcm9qZWN0aW9uIHtcbiAgICAgICAgaWYgKCF0aGlzLnByb2plY3Rpb25JbnN0YW5jZSkge1xuICAgICAgICAgICAgdGhpcy5wcm9qZWN0aW9uSW5zdGFuY2UgPSBnZXRQcm9qZWN0aW9uKHRoaXMucHJvamVjdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMucHJvamVjdGlvbkluc3RhbmNlO1xuICAgIH1cblxuICAgIGRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMudGV4dC5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMuaWNvbi5kZXN0cm95KCk7XG5cbiAgICAgICAgaWYgKHRoaXMuaGFzRGVidWdEYXRhKCkpIHtcbiAgICAgICAgICAgIHRoaXMuZGVzdHJveURlYnVnRGF0YSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYWRkVG9MaW5lVmVydGV4QXJyYXkoYW5jaG9yOiBBbmNob3IsIGxpbmU6IEFycmF5PFBvaW50Pik6IExpbmVWZXJ0ZXhSYW5nZSB7XG4gICAgICAgIGNvbnN0IGxpbmVTdGFydEluZGV4ID0gdGhpcy5saW5lVmVydGV4QXJyYXkubGVuZ3RoO1xuICAgICAgICBpZiAoYW5jaG9yLnNlZ21lbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgZm9yIChjb25zdCB7eCwgeX0gb2YgbGluZSkge1xuICAgICAgICAgICAgICAgIHRoaXMubGluZVZlcnRleEFycmF5LmVtcGxhY2VCYWNrKHgsIHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBsaW5lU3RhcnRJbmRleCxcbiAgICAgICAgICAgIGxpbmVMZW5ndGg6IHRoaXMubGluZVZlcnRleEFycmF5Lmxlbmd0aCAtIGxpbmVTdGFydEluZGV4XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgYWRkU3ltYm9scyhhcnJheXM6IFN5bWJvbEJ1ZmZlcnMsXG4gICAgICAgICAgICAgICBxdWFkczogQXJyYXk8U3ltYm9sUXVhZD4sXG4gICAgICAgICAgICAgICBzaXplVmVydGV4OiBhbnksXG4gICAgICAgICAgICAgICBsaW5lT2Zmc2V0OiBbbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICAgICAgICAgYWxvbmdMaW5lOiBib29sZWFuLFxuICAgICAgICAgICAgICAgZmVhdHVyZTogU3ltYm9sRmVhdHVyZSxcbiAgICAgICAgICAgICAgIHdyaXRpbmdNb2RlOiBhbnksXG4gICAgICAgICAgICAgICBnbG9iZTogP3sgYW5jaG9yOiBBbmNob3IsIHVwOiBWZWMzIH0sXG4gICAgICAgICAgICAgICB0aWxlQW5jaG9yOiBBbmNob3IsXG4gICAgICAgICAgICAgICBsaW5lU3RhcnRJbmRleDogbnVtYmVyLFxuICAgICAgICAgICAgICAgbGluZUxlbmd0aDogbnVtYmVyLFxuICAgICAgICAgICAgICAgYXNzb2NpYXRlZEljb25JbmRleDogbnVtYmVyLFxuICAgICAgICAgICAgICAgYXZhaWxhYmxlSW1hZ2VzOiBBcnJheTxzdHJpbmc+LFxuICAgICAgICAgICAgICAgY2Fub25pY2FsOiBDYW5vbmljYWxUaWxlSUQpIHtcbiAgICAgICAgY29uc3QgaW5kZXhBcnJheSA9IGFycmF5cy5pbmRleEFycmF5O1xuICAgICAgICBjb25zdCBsYXlvdXRWZXJ0ZXhBcnJheSA9IGFycmF5cy5sYXlvdXRWZXJ0ZXhBcnJheTtcbiAgICAgICAgY29uc3QgZ2xvYmVFeHRWZXJ0ZXhBcnJheSA9IGFycmF5cy5nbG9iZUV4dFZlcnRleEFycmF5O1xuXG4gICAgICAgIGNvbnN0IHNlZ21lbnQgPSBhcnJheXMuc2VnbWVudHMucHJlcGFyZVNlZ21lbnQoNCAqIHF1YWRzLmxlbmd0aCwgbGF5b3V0VmVydGV4QXJyYXksIGluZGV4QXJyYXksIHRoaXMuY2FuT3ZlcmxhcCA/IGZlYXR1cmUuc29ydEtleSA6IHVuZGVmaW5lZCk7XG4gICAgICAgIGNvbnN0IGdseXBoT2Zmc2V0QXJyYXlTdGFydCA9IHRoaXMuZ2x5cGhPZmZzZXRBcnJheS5sZW5ndGg7XG4gICAgICAgIGNvbnN0IHZlcnRleFN0YXJ0SW5kZXggPSBzZWdtZW50LnZlcnRleExlbmd0aDtcblxuICAgICAgICBjb25zdCBhbmdsZSA9ICh0aGlzLmFsbG93VmVydGljYWxQbGFjZW1lbnQgJiYgd3JpdGluZ01vZGUgPT09IFdyaXRpbmdNb2RlLnZlcnRpY2FsKSA/IE1hdGguUEkgLyAyIDogMDtcblxuICAgICAgICBjb25zdCBzZWN0aW9ucyA9IGZlYXR1cmUudGV4dCAmJiBmZWF0dXJlLnRleHQuc2VjdGlvbnM7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBxdWFkcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3Qge3RsLCB0ciwgYmwsIGJyLCB0ZXgsIHBpeGVsT2Zmc2V0VEwsIHBpeGVsT2Zmc2V0QlIsIG1pbkZvbnRTY2FsZVgsIG1pbkZvbnRTY2FsZVksIGdseXBoT2Zmc2V0LCBpc1NERiwgc2VjdGlvbkluZGV4fSA9IHF1YWRzW2ldO1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSBzZWdtZW50LnZlcnRleExlbmd0aDtcblxuICAgICAgICAgICAgY29uc3QgeSA9IGdseXBoT2Zmc2V0WzFdO1xuICAgICAgICAgICAgYWRkVmVydGV4KGxheW91dFZlcnRleEFycmF5LCB0aWxlQW5jaG9yLngsIHRpbGVBbmNob3IueSwgdGwueCwgeSArIHRsLnksIHRleC54LCB0ZXgueSwgc2l6ZVZlcnRleCwgaXNTREYsIHBpeGVsT2Zmc2V0VEwueCwgcGl4ZWxPZmZzZXRUTC55LCBtaW5Gb250U2NhbGVYLCBtaW5Gb250U2NhbGVZKTtcbiAgICAgICAgICAgIGFkZFZlcnRleChsYXlvdXRWZXJ0ZXhBcnJheSwgdGlsZUFuY2hvci54LCB0aWxlQW5jaG9yLnksIHRyLngsIHkgKyB0ci55LCB0ZXgueCArIHRleC53LCB0ZXgueSwgc2l6ZVZlcnRleCwgaXNTREYsIHBpeGVsT2Zmc2V0QlIueCwgcGl4ZWxPZmZzZXRUTC55LCBtaW5Gb250U2NhbGVYLCBtaW5Gb250U2NhbGVZKTtcbiAgICAgICAgICAgIGFkZFZlcnRleChsYXlvdXRWZXJ0ZXhBcnJheSwgdGlsZUFuY2hvci54LCB0aWxlQW5jaG9yLnksIGJsLngsIHkgKyBibC55LCB0ZXgueCwgdGV4LnkgKyB0ZXguaCwgc2l6ZVZlcnRleCwgaXNTREYsIHBpeGVsT2Zmc2V0VEwueCwgcGl4ZWxPZmZzZXRCUi55LCBtaW5Gb250U2NhbGVYLCBtaW5Gb250U2NhbGVZKTtcbiAgICAgICAgICAgIGFkZFZlcnRleChsYXlvdXRWZXJ0ZXhBcnJheSwgdGlsZUFuY2hvci54LCB0aWxlQW5jaG9yLnksIGJyLngsIHkgKyBici55LCB0ZXgueCArIHRleC53LCB0ZXgueSArIHRleC5oLCBzaXplVmVydGV4LCBpc1NERiwgcGl4ZWxPZmZzZXRCUi54LCBwaXhlbE9mZnNldEJSLnksIG1pbkZvbnRTY2FsZVgsIG1pbkZvbnRTY2FsZVkpO1xuXG4gICAgICAgICAgICBpZiAoZ2xvYmUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB7eCwgeSwgen0gPSBnbG9iZS5hbmNob3I7XG4gICAgICAgICAgICAgICAgY29uc3QgW3V4LCB1eSwgdXpdID0gZ2xvYmUudXA7XG4gICAgICAgICAgICAgICAgYWRkR2xvYmVWZXJ0ZXgoZ2xvYmVFeHRWZXJ0ZXhBcnJheSwgeCwgeSwgeiwgdXgsIHV5LCB1eik7XG4gICAgICAgICAgICAgICAgYWRkR2xvYmVWZXJ0ZXgoZ2xvYmVFeHRWZXJ0ZXhBcnJheSwgeCwgeSwgeiwgdXgsIHV5LCB1eik7XG4gICAgICAgICAgICAgICAgYWRkR2xvYmVWZXJ0ZXgoZ2xvYmVFeHRWZXJ0ZXhBcnJheSwgeCwgeSwgeiwgdXgsIHV5LCB1eik7XG4gICAgICAgICAgICAgICAgYWRkR2xvYmVWZXJ0ZXgoZ2xvYmVFeHRWZXJ0ZXhBcnJheSwgeCwgeSwgeiwgdXgsIHV5LCB1eik7XG5cbiAgICAgICAgICAgICAgICBhZGREeW5hbWljQXR0cmlidXRlcyhhcnJheXMuZHluYW1pY0xheW91dFZlcnRleEFycmF5LCB4LCB5LCB6LCBhbmdsZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGFkZER5bmFtaWNBdHRyaWJ1dGVzKGFycmF5cy5keW5hbWljTGF5b3V0VmVydGV4QXJyYXksIHRpbGVBbmNob3IueCwgdGlsZUFuY2hvci55LCB0aWxlQW5jaG9yLnosIGFuZ2xlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaW5kZXhBcnJheS5lbXBsYWNlQmFjayhpbmRleCwgaW5kZXggKyAxLCBpbmRleCArIDIpO1xuICAgICAgICAgICAgaW5kZXhBcnJheS5lbXBsYWNlQmFjayhpbmRleCArIDEsIGluZGV4ICsgMiwgaW5kZXggKyAzKTtcblxuICAgICAgICAgICAgc2VnbWVudC52ZXJ0ZXhMZW5ndGggKz0gNDtcbiAgICAgICAgICAgIHNlZ21lbnQucHJpbWl0aXZlTGVuZ3RoICs9IDI7XG5cbiAgICAgICAgICAgIHRoaXMuZ2x5cGhPZmZzZXRBcnJheS5lbXBsYWNlQmFjayhnbHlwaE9mZnNldFswXSk7XG5cbiAgICAgICAgICAgIGlmIChpID09PSBxdWFkcy5sZW5ndGggLSAxIHx8IHNlY3Rpb25JbmRleCAhPT0gcXVhZHNbaSArIDFdLnNlY3Rpb25JbmRleCkge1xuICAgICAgICAgICAgICAgIGFycmF5cy5wcm9ncmFtQ29uZmlndXJhdGlvbnMucG9wdWxhdGVQYWludEFycmF5cyhsYXlvdXRWZXJ0ZXhBcnJheS5sZW5ndGgsIGZlYXR1cmUsIGZlYXR1cmUuaW5kZXgsIHt9LCBhdmFpbGFibGVJbWFnZXMsIGNhbm9uaWNhbCwgc2VjdGlvbnMgJiYgc2VjdGlvbnNbc2VjdGlvbkluZGV4XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwcm9qZWN0ZWRBbmNob3IgPSBnbG9iZSA/IGdsb2JlLmFuY2hvciA6IHRpbGVBbmNob3I7XG5cbiAgICAgICAgYXJyYXlzLnBsYWNlZFN5bWJvbEFycmF5LmVtcGxhY2VCYWNrKHByb2plY3RlZEFuY2hvci54LCBwcm9qZWN0ZWRBbmNob3IueSwgcHJvamVjdGVkQW5jaG9yLnosIHRpbGVBbmNob3IueCwgdGlsZUFuY2hvci55LFxuICAgICAgICAgICAgZ2x5cGhPZmZzZXRBcnJheVN0YXJ0LCB0aGlzLmdseXBoT2Zmc2V0QXJyYXkubGVuZ3RoIC0gZ2x5cGhPZmZzZXRBcnJheVN0YXJ0LCB2ZXJ0ZXhTdGFydEluZGV4LFxuICAgICAgICAgICAgbGluZVN0YXJ0SW5kZXgsIGxpbmVMZW5ndGgsICh0aWxlQW5jaG9yLnNlZ21lbnQ6IGFueSksXG4gICAgICAgICAgICBzaXplVmVydGV4ID8gc2l6ZVZlcnRleFswXSA6IDAsIHNpemVWZXJ0ZXggPyBzaXplVmVydGV4WzFdIDogMCxcbiAgICAgICAgICAgIGxpbmVPZmZzZXRbMF0sIGxpbmVPZmZzZXRbMV0sXG4gICAgICAgICAgICB3cml0aW5nTW9kZSxcbiAgICAgICAgICAgIC8vIHBsYWNlZE9yaWVudGF0aW9uIGlzIG51bGwgaW5pdGlhbGx5OyB3aWxsIGJlIHVwZGF0ZWQgdG8gaG9yaXpvbnRhbCgxKS92ZXJ0aWNhbCgyKSBpZiBwbGFjZWRcbiAgICAgICAgICAgIDAsXG4gICAgICAgICAgICAoZmFsc2U6IGFueSksXG4gICAgICAgICAgICAvLyBUaGUgY3Jvc3NUaWxlSUQgaXMgb25seSBmaWxsZWQvdXNlZCBvbiB0aGUgZm9yZWdyb3VuZCBmb3IgZHluYW1pYyB0ZXh0IGFuY2hvcnNcbiAgICAgICAgICAgIDAsXG4gICAgICAgICAgICBhc3NvY2lhdGVkSWNvbkluZGV4LFxuICAgICAgICAgICAgLy8gZmxpcFN0YXRlIGlzIHVua25vd24gaW5pdGlhbGx5OyB3aWxsIGJlIHVwZGF0ZWQgdG8gZmxpcFJlcXVpcmVkKDEpL2ZsaXBOb3RSZXF1aXJlZCgyKSBkdXJpbmcgbGluZSBsYWJlbCByZXByb2plY3Rpb25cbiAgICAgICAgICAgIDBcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBfY29tbWl0TGF5b3V0VmVydGV4KGFycmF5OiBTdHJ1Y3RBcnJheSwgYm94VGlsZUFuY2hvclg6IG51bWJlciwgYm94VGlsZUFuY2hvclk6IG51bWJlciwgYm94VGlsZUFuY2hvclo6IG51bWJlciwgdGlsZUFuY2hvclg6IG51bWJlciwgdGlsZUFuY2hvclk6IG51bWJlciwgZXh0cnVkZTogUG9pbnQpIHtcbiAgICAgICAgYXJyYXkuZW1wbGFjZUJhY2soXG4gICAgICAgICAgICAvLyBwb3NcbiAgICAgICAgICAgIGJveFRpbGVBbmNob3JYLFxuICAgICAgICAgICAgYm94VGlsZUFuY2hvclksXG4gICAgICAgICAgICBib3hUaWxlQW5jaG9yWixcbiAgICAgICAgICAgIC8vIGFfYW5jaG9yX3Bvc1xuICAgICAgICAgICAgdGlsZUFuY2hvclgsXG4gICAgICAgICAgICB0aWxlQW5jaG9yWSxcbiAgICAgICAgICAgIC8vIGV4dHJ1ZGVcbiAgICAgICAgICAgIE1hdGgucm91bmQoZXh0cnVkZS54KSxcbiAgICAgICAgICAgIE1hdGgucm91bmQoZXh0cnVkZS55KSk7XG4gICAgfVxuXG4gICAgX2FkZENvbGxpc2lvbkRlYnVnVmVydGljZXMoYm94OiBDb2xsaXNpb25Cb3gsIHNjYWxlOiBudW1iZXIsIGFycmF5czogQ29sbGlzaW9uQnVmZmVycywgYm94VGlsZUFuY2hvclg6IG51bWJlciwgYm94VGlsZUFuY2hvclk6IG51bWJlciwgYm94VGlsZUFuY2hvclo6IG51bWJlciwgc3ltYm9sSW5zdGFuY2U6IFN5bWJvbEluc3RhbmNlKSB7XG4gICAgICAgIGNvbnN0IHNlZ21lbnQgPSBhcnJheXMuc2VnbWVudHMucHJlcGFyZVNlZ21lbnQoNCwgYXJyYXlzLmxheW91dFZlcnRleEFycmF5LCBhcnJheXMuaW5kZXhBcnJheSk7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gc2VnbWVudC52ZXJ0ZXhMZW5ndGg7XG4gICAgICAgIGNvbnN0IHN5bWJvbFRpbGVBbmNob3JYID0gc3ltYm9sSW5zdGFuY2UudGlsZUFuY2hvclg7XG4gICAgICAgIGNvbnN0IHN5bWJvbFRpbGVBbmNob3JZID0gc3ltYm9sSW5zdGFuY2UudGlsZUFuY2hvclk7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICAgICAgICAgIGFycmF5cy5jb2xsaXNpb25WZXJ0ZXhBcnJheS5lbXBsYWNlQmFjaygwLCAwLCAwLCAwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGFycmF5cy5jb2xsaXNpb25WZXJ0ZXhBcnJheUV4dC5lbXBsYWNlQmFjayhzY2FsZSwgLWJveC5wYWRkaW5nLCAtYm94LnBhZGRpbmcpO1xuICAgICAgICBhcnJheXMuY29sbGlzaW9uVmVydGV4QXJyYXlFeHQuZW1wbGFjZUJhY2soc2NhbGUsICBib3gucGFkZGluZywgLWJveC5wYWRkaW5nKTtcbiAgICAgICAgYXJyYXlzLmNvbGxpc2lvblZlcnRleEFycmF5RXh0LmVtcGxhY2VCYWNrKHNjYWxlLCAgYm94LnBhZGRpbmcsICBib3gucGFkZGluZyk7XG4gICAgICAgIGFycmF5cy5jb2xsaXNpb25WZXJ0ZXhBcnJheUV4dC5lbXBsYWNlQmFjayhzY2FsZSwgLWJveC5wYWRkaW5nLCAgYm94LnBhZGRpbmcpO1xuXG4gICAgICAgIHRoaXMuX2NvbW1pdExheW91dFZlcnRleChhcnJheXMubGF5b3V0VmVydGV4QXJyYXksIGJveFRpbGVBbmNob3JYLCBib3hUaWxlQW5jaG9yWSwgYm94VGlsZUFuY2hvclosIHN5bWJvbFRpbGVBbmNob3JYLCBzeW1ib2xUaWxlQW5jaG9yWSwgbmV3IFBvaW50KGJveC54MSwgYm94LnkxKSk7XG4gICAgICAgIHRoaXMuX2NvbW1pdExheW91dFZlcnRleChhcnJheXMubGF5b3V0VmVydGV4QXJyYXksIGJveFRpbGVBbmNob3JYLCBib3hUaWxlQW5jaG9yWSwgYm94VGlsZUFuY2hvclosIHN5bWJvbFRpbGVBbmNob3JYLCBzeW1ib2xUaWxlQW5jaG9yWSwgbmV3IFBvaW50KGJveC54MiwgYm94LnkxKSk7XG4gICAgICAgIHRoaXMuX2NvbW1pdExheW91dFZlcnRleChhcnJheXMubGF5b3V0VmVydGV4QXJyYXksIGJveFRpbGVBbmNob3JYLCBib3hUaWxlQW5jaG9yWSwgYm94VGlsZUFuY2hvclosIHN5bWJvbFRpbGVBbmNob3JYLCBzeW1ib2xUaWxlQW5jaG9yWSwgbmV3IFBvaW50KGJveC54MiwgYm94LnkyKSk7XG4gICAgICAgIHRoaXMuX2NvbW1pdExheW91dFZlcnRleChhcnJheXMubGF5b3V0VmVydGV4QXJyYXksIGJveFRpbGVBbmNob3JYLCBib3hUaWxlQW5jaG9yWSwgYm94VGlsZUFuY2hvclosIHN5bWJvbFRpbGVBbmNob3JYLCBzeW1ib2xUaWxlQW5jaG9yWSwgbmV3IFBvaW50KGJveC54MSwgYm94LnkyKSk7XG5cbiAgICAgICAgc2VnbWVudC52ZXJ0ZXhMZW5ndGggKz0gNDtcblxuICAgICAgICBjb25zdCBpbmRleEFycmF5OiBMaW5lSW5kZXhBcnJheSA9IChhcnJheXMuaW5kZXhBcnJheTogYW55KTtcbiAgICAgICAgaW5kZXhBcnJheS5lbXBsYWNlQmFjayhpbmRleCwgaW5kZXggKyAxKTtcbiAgICAgICAgaW5kZXhBcnJheS5lbXBsYWNlQmFjayhpbmRleCArIDEsIGluZGV4ICsgMik7XG4gICAgICAgIGluZGV4QXJyYXkuZW1wbGFjZUJhY2soaW5kZXggKyAyLCBpbmRleCArIDMpO1xuICAgICAgICBpbmRleEFycmF5LmVtcGxhY2VCYWNrKGluZGV4ICsgMywgaW5kZXgpO1xuXG4gICAgICAgIHNlZ21lbnQucHJpbWl0aXZlTGVuZ3RoICs9IDQ7XG4gICAgfVxuXG4gICAgX2FkZFRleHREZWJ1Z0NvbGxpc2lvbkJveGVzKHNpemU6IGFueSwgem9vbTogbnVtYmVyLCBjb2xsaXNpb25Cb3hBcnJheTogQ29sbGlzaW9uQm94QXJyYXksIHN0YXJ0SW5kZXg6IG51bWJlciwgZW5kSW5kZXg6IG51bWJlciwgaW5zdGFuY2U6IFN5bWJvbEluc3RhbmNlKSB7XG4gICAgICAgIGZvciAobGV0IGIgPSBzdGFydEluZGV4OyBiIDwgZW5kSW5kZXg7IGIrKykge1xuICAgICAgICAgICAgY29uc3QgYm94OiBDb2xsaXNpb25Cb3ggPSAoY29sbGlzaW9uQm94QXJyYXkuZ2V0KGIpOiBhbnkpO1xuICAgICAgICAgICAgY29uc3Qgc2NhbGUgPSB0aGlzLmdldFN5bWJvbEluc3RhbmNlVGV4dFNpemUoc2l6ZSwgaW5zdGFuY2UsIHpvb20sIGIpO1xuXG4gICAgICAgICAgICB0aGlzLl9hZGRDb2xsaXNpb25EZWJ1Z1ZlcnRpY2VzKGJveCwgc2NhbGUsIHRoaXMudGV4dENvbGxpc2lvbkJveCwgYm94LnByb2plY3RlZEFuY2hvclgsIGJveC5wcm9qZWN0ZWRBbmNob3JZLCBib3gucHJvamVjdGVkQW5jaG9yWiwgaW5zdGFuY2UpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX2FkZEljb25EZWJ1Z0NvbGxpc2lvbkJveGVzKHNpemU6IGFueSwgem9vbTogbnVtYmVyLCBjb2xsaXNpb25Cb3hBcnJheTogQ29sbGlzaW9uQm94QXJyYXksIHN0YXJ0SW5kZXg6IG51bWJlciwgZW5kSW5kZXg6IG51bWJlciwgaW5zdGFuY2U6IFN5bWJvbEluc3RhbmNlKSB7XG4gICAgICAgIGZvciAobGV0IGIgPSBzdGFydEluZGV4OyBiIDwgZW5kSW5kZXg7IGIrKykge1xuICAgICAgICAgICAgY29uc3QgYm94OiBDb2xsaXNpb25Cb3ggPSAoY29sbGlzaW9uQm94QXJyYXkuZ2V0KGIpOiBhbnkpO1xuICAgICAgICAgICAgY29uc3Qgc2NhbGUgPSB0aGlzLmdldFN5bWJvbEluc3RhbmNlSWNvblNpemUoc2l6ZSwgem9vbSwgaW5zdGFuY2UucGxhY2VkSWNvblN5bWJvbEluZGV4KTtcblxuICAgICAgICAgICAgdGhpcy5fYWRkQ29sbGlzaW9uRGVidWdWZXJ0aWNlcyhib3gsIHNjYWxlLCB0aGlzLmljb25Db2xsaXNpb25Cb3gsIGJveC5wcm9qZWN0ZWRBbmNob3JYLCBib3gucHJvamVjdGVkQW5jaG9yWSwgYm94LnByb2plY3RlZEFuY2hvclosIGluc3RhbmNlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdlbmVyYXRlQ29sbGlzaW9uRGVidWdCdWZmZXJzKHpvb206IG51bWJlciwgY29sbGlzaW9uQm94QXJyYXk6IENvbGxpc2lvbkJveEFycmF5KSB7XG4gICAgICAgIGlmICh0aGlzLmhhc0RlYnVnRGF0YSgpKSB7XG4gICAgICAgICAgICB0aGlzLmRlc3Ryb3lEZWJ1Z0RhdGEoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudGV4dENvbGxpc2lvbkJveCA9IG5ldyBDb2xsaXNpb25CdWZmZXJzKENvbGxpc2lvbkJveExheW91dEFycmF5LCBjb2xsaXNpb25Cb3hMYXlvdXQubWVtYmVycywgTGluZUluZGV4QXJyYXkpO1xuICAgICAgICB0aGlzLmljb25Db2xsaXNpb25Cb3ggPSBuZXcgQ29sbGlzaW9uQnVmZmVycyhDb2xsaXNpb25Cb3hMYXlvdXRBcnJheSwgY29sbGlzaW9uQm94TGF5b3V0Lm1lbWJlcnMsIExpbmVJbmRleEFycmF5KTtcblxuICAgICAgICBjb25zdCBpY29uU2l6ZSA9IHN5bWJvbFNpemUuZXZhbHVhdGVTaXplRm9yWm9vbSh0aGlzLmljb25TaXplRGF0YSwgem9vbSk7XG4gICAgICAgIGNvbnN0IHRleHRTaXplID0gc3ltYm9sU2l6ZS5ldmFsdWF0ZVNpemVGb3Jab29tKHRoaXMudGV4dFNpemVEYXRhLCB6b29tKTtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuc3ltYm9sSW5zdGFuY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBzeW1ib2xJbnN0YW5jZSA9IHRoaXMuc3ltYm9sSW5zdGFuY2VzLmdldChpKTtcbiAgICAgICAgICAgIHRoaXMuX2FkZFRleHREZWJ1Z0NvbGxpc2lvbkJveGVzKHRleHRTaXplLCB6b29tLCBjb2xsaXNpb25Cb3hBcnJheSwgc3ltYm9sSW5zdGFuY2UudGV4dEJveFN0YXJ0SW5kZXgsIHN5bWJvbEluc3RhbmNlLnRleHRCb3hFbmRJbmRleCwgc3ltYm9sSW5zdGFuY2UpO1xuICAgICAgICAgICAgdGhpcy5fYWRkVGV4dERlYnVnQ29sbGlzaW9uQm94ZXModGV4dFNpemUsIHpvb20sIGNvbGxpc2lvbkJveEFycmF5LCBzeW1ib2xJbnN0YW5jZS52ZXJ0aWNhbFRleHRCb3hTdGFydEluZGV4LCBzeW1ib2xJbnN0YW5jZS52ZXJ0aWNhbFRleHRCb3hFbmRJbmRleCwgc3ltYm9sSW5zdGFuY2UpO1xuICAgICAgICAgICAgdGhpcy5fYWRkSWNvbkRlYnVnQ29sbGlzaW9uQm94ZXMoaWNvblNpemUsIHpvb20sIGNvbGxpc2lvbkJveEFycmF5LCBzeW1ib2xJbnN0YW5jZS5pY29uQm94U3RhcnRJbmRleCwgc3ltYm9sSW5zdGFuY2UuaWNvbkJveEVuZEluZGV4LCBzeW1ib2xJbnN0YW5jZSk7XG4gICAgICAgICAgICB0aGlzLl9hZGRJY29uRGVidWdDb2xsaXNpb25Cb3hlcyhpY29uU2l6ZSwgem9vbSwgY29sbGlzaW9uQm94QXJyYXksIHN5bWJvbEluc3RhbmNlLnZlcnRpY2FsSWNvbkJveFN0YXJ0SW5kZXgsIHN5bWJvbEluc3RhbmNlLnZlcnRpY2FsSWNvbkJveEVuZEluZGV4LCBzeW1ib2xJbnN0YW5jZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRTeW1ib2xJbnN0YW5jZVRleHRTaXplKHRleHRTaXplOiBhbnksIGluc3RhbmNlOiBTeW1ib2xJbnN0YW5jZSwgem9vbTogbnVtYmVyLCBib3hJbmRleDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3Qgc3ltYm9sSW5kZXggPSBpbnN0YW5jZS5yaWdodEp1c3RpZmllZFRleHRTeW1ib2xJbmRleCA+PSAwID9cbiAgICAgICAgICAgIGluc3RhbmNlLnJpZ2h0SnVzdGlmaWVkVGV4dFN5bWJvbEluZGV4IDogaW5zdGFuY2UuY2VudGVySnVzdGlmaWVkVGV4dFN5bWJvbEluZGV4ID49IDAgP1xuICAgICAgICAgICAgICAgIGluc3RhbmNlLmNlbnRlckp1c3RpZmllZFRleHRTeW1ib2xJbmRleCA6IGluc3RhbmNlLmxlZnRKdXN0aWZpZWRUZXh0U3ltYm9sSW5kZXggPj0gMCA/XG4gICAgICAgICAgICAgICAgICAgIGluc3RhbmNlLmxlZnRKdXN0aWZpZWRUZXh0U3ltYm9sSW5kZXggOiBpbnN0YW5jZS52ZXJ0aWNhbFBsYWNlZFRleHRTeW1ib2xJbmRleCA+PSAwID9cbiAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlLnZlcnRpY2FsUGxhY2VkVGV4dFN5bWJvbEluZGV4IDogYm94SW5kZXg7XG5cbiAgICAgICAgY29uc3Qgc3ltYm9sID0gdGhpcy50ZXh0LnBsYWNlZFN5bWJvbEFycmF5LmdldChzeW1ib2xJbmRleCk7XG4gICAgICAgIGNvbnN0IGZlYXR1cmVTaXplID0gc3ltYm9sU2l6ZS5ldmFsdWF0ZVNpemVGb3JGZWF0dXJlKHRoaXMudGV4dFNpemVEYXRhLCB0ZXh0U2l6ZSwgc3ltYm9sKSAvIE9ORV9FTTtcblxuICAgICAgICByZXR1cm4gdGhpcy50aWxlUGl4ZWxSYXRpbyAqIGZlYXR1cmVTaXplO1xuICAgIH1cblxuICAgIGdldFN5bWJvbEluc3RhbmNlSWNvblNpemUoaWNvblNpemU6IGFueSwgem9vbTogbnVtYmVyLCBpY29uSW5kZXg6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IHN5bWJvbCA9IHRoaXMuaWNvbi5wbGFjZWRTeW1ib2xBcnJheS5nZXQoaWNvbkluZGV4KTtcbiAgICAgICAgY29uc3QgZmVhdHVyZVNpemUgPSBzeW1ib2xTaXplLmV2YWx1YXRlU2l6ZUZvckZlYXR1cmUodGhpcy5pY29uU2l6ZURhdGEsIGljb25TaXplLCBzeW1ib2wpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLnRpbGVQaXhlbFJhdGlvICogZmVhdHVyZVNpemU7XG4gICAgfVxuXG4gICAgX2NvbW1pdERlYnVnQ29sbGlzaW9uVmVydGV4VXBkYXRlKGFycmF5OiBTdHJ1Y3RBcnJheSwgc2NhbGU6IG51bWJlciwgcGFkZGluZzogbnVtYmVyKSB7XG4gICAgICAgIGFycmF5LmVtcGxhY2VCYWNrKHNjYWxlLCAtcGFkZGluZywgLXBhZGRpbmcpO1xuICAgICAgICBhcnJheS5lbXBsYWNlQmFjayhzY2FsZSwgIHBhZGRpbmcsIC1wYWRkaW5nKTtcbiAgICAgICAgYXJyYXkuZW1wbGFjZUJhY2soc2NhbGUsICBwYWRkaW5nLCAgcGFkZGluZyk7XG4gICAgICAgIGFycmF5LmVtcGxhY2VCYWNrKHNjYWxlLCAtcGFkZGluZywgIHBhZGRpbmcpO1xuICAgIH1cblxuICAgIF91cGRhdGVUZXh0RGVidWdDb2xsaXNpb25Cb3hlcyhzaXplOiBhbnksIHpvb206IG51bWJlciwgY29sbGlzaW9uQm94QXJyYXk6IENvbGxpc2lvbkJveEFycmF5LCBzdGFydEluZGV4OiBudW1iZXIsIGVuZEluZGV4OiBudW1iZXIsIGluc3RhbmNlOiBTeW1ib2xJbnN0YW5jZSkge1xuICAgICAgICBmb3IgKGxldCBiID0gc3RhcnRJbmRleDsgYiA8IGVuZEluZGV4OyBiKyspIHtcbiAgICAgICAgICAgIGNvbnN0IGJveDogQ29sbGlzaW9uQm94ID0gKGNvbGxpc2lvbkJveEFycmF5LmdldChiKTogYW55KTtcbiAgICAgICAgICAgIGNvbnN0IHNjYWxlID0gdGhpcy5nZXRTeW1ib2xJbnN0YW5jZVRleHRTaXplKHNpemUsIGluc3RhbmNlLCB6b29tLCBiKTtcbiAgICAgICAgICAgIGNvbnN0IGFycmF5ID0gdGhpcy50ZXh0Q29sbGlzaW9uQm94LmNvbGxpc2lvblZlcnRleEFycmF5RXh0O1xuICAgICAgICAgICAgdGhpcy5fY29tbWl0RGVidWdDb2xsaXNpb25WZXJ0ZXhVcGRhdGUoYXJyYXksIHNjYWxlLCBib3gucGFkZGluZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfdXBkYXRlSWNvbkRlYnVnQ29sbGlzaW9uQm94ZXMoc2l6ZTogYW55LCB6b29tOiBudW1iZXIsIGNvbGxpc2lvbkJveEFycmF5OiBDb2xsaXNpb25Cb3hBcnJheSwgc3RhcnRJbmRleDogbnVtYmVyLCBlbmRJbmRleDogbnVtYmVyLCBzeW1ib2xJbmRleDogbnVtYmVyKSB7XG4gICAgICAgIGZvciAobGV0IGIgPSBzdGFydEluZGV4OyBiIDwgZW5kSW5kZXg7IGIrKykge1xuICAgICAgICAgICAgY29uc3QgYm94ID0gKGNvbGxpc2lvbkJveEFycmF5LmdldChiKSk7XG4gICAgICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuZ2V0U3ltYm9sSW5zdGFuY2VJY29uU2l6ZShzaXplLCB6b29tLCBzeW1ib2xJbmRleCk7XG4gICAgICAgICAgICBjb25zdCBhcnJheSA9IHRoaXMuaWNvbkNvbGxpc2lvbkJveC5jb2xsaXNpb25WZXJ0ZXhBcnJheUV4dDtcbiAgICAgICAgICAgIHRoaXMuX2NvbW1pdERlYnVnQ29sbGlzaW9uVmVydGV4VXBkYXRlKGFycmF5LCBzY2FsZSwgYm94LnBhZGRpbmcpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdXBkYXRlQ29sbGlzaW9uRGVidWdCdWZmZXJzKHpvb206IG51bWJlciwgY29sbGlzaW9uQm94QXJyYXk6IENvbGxpc2lvbkJveEFycmF5KSB7XG4gICAgICAgIGlmICghdGhpcy5oYXNEZWJ1Z0RhdGEoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuaGFzVGV4dENvbGxpc2lvbkJveERhdGEoKSkgdGhpcy50ZXh0Q29sbGlzaW9uQm94LmNvbGxpc2lvblZlcnRleEFycmF5RXh0LmNsZWFyKCk7XG4gICAgICAgIGlmICh0aGlzLmhhc0ljb25Db2xsaXNpb25Cb3hEYXRhKCkpIHRoaXMuaWNvbkNvbGxpc2lvbkJveC5jb2xsaXNpb25WZXJ0ZXhBcnJheUV4dC5jbGVhcigpO1xuXG4gICAgICAgIGNvbnN0IGljb25TaXplID0gc3ltYm9sU2l6ZS5ldmFsdWF0ZVNpemVGb3Jab29tKHRoaXMuaWNvblNpemVEYXRhLCB6b29tKTtcbiAgICAgICAgY29uc3QgdGV4dFNpemUgPSBzeW1ib2xTaXplLmV2YWx1YXRlU2l6ZUZvclpvb20odGhpcy50ZXh0U2l6ZURhdGEsIHpvb20pO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zeW1ib2xJbnN0YW5jZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHN5bWJvbEluc3RhbmNlID0gdGhpcy5zeW1ib2xJbnN0YW5jZXMuZ2V0KGkpO1xuICAgICAgICAgICAgdGhpcy5fdXBkYXRlVGV4dERlYnVnQ29sbGlzaW9uQm94ZXModGV4dFNpemUsIHpvb20sIGNvbGxpc2lvbkJveEFycmF5LCBzeW1ib2xJbnN0YW5jZS50ZXh0Qm94U3RhcnRJbmRleCwgc3ltYm9sSW5zdGFuY2UudGV4dEJveEVuZEluZGV4LCBzeW1ib2xJbnN0YW5jZSk7XG4gICAgICAgICAgICB0aGlzLl91cGRhdGVUZXh0RGVidWdDb2xsaXNpb25Cb3hlcyh0ZXh0U2l6ZSwgem9vbSwgY29sbGlzaW9uQm94QXJyYXksIHN5bWJvbEluc3RhbmNlLnZlcnRpY2FsVGV4dEJveFN0YXJ0SW5kZXgsIHN5bWJvbEluc3RhbmNlLnZlcnRpY2FsVGV4dEJveEVuZEluZGV4LCBzeW1ib2xJbnN0YW5jZSk7XG4gICAgICAgICAgICB0aGlzLl91cGRhdGVJY29uRGVidWdDb2xsaXNpb25Cb3hlcyhpY29uU2l6ZSwgem9vbSwgY29sbGlzaW9uQm94QXJyYXksIHN5bWJvbEluc3RhbmNlLmljb25Cb3hTdGFydEluZGV4LCBzeW1ib2xJbnN0YW5jZS5pY29uQm94RW5kSW5kZXgsIHN5bWJvbEluc3RhbmNlLnBsYWNlZEljb25TeW1ib2xJbmRleCk7XG4gICAgICAgICAgICB0aGlzLl91cGRhdGVJY29uRGVidWdDb2xsaXNpb25Cb3hlcyhpY29uU2l6ZSwgem9vbSwgY29sbGlzaW9uQm94QXJyYXksIHN5bWJvbEluc3RhbmNlLnZlcnRpY2FsSWNvbkJveFN0YXJ0SW5kZXgsIHN5bWJvbEluc3RhbmNlLnZlcnRpY2FsSWNvbkJveEVuZEluZGV4LCBzeW1ib2xJbnN0YW5jZS5wbGFjZWRJY29uU3ltYm9sSW5kZXgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuaGFzVGV4dENvbGxpc2lvbkJveERhdGEoKSAmJiB0aGlzLnRleHRDb2xsaXNpb25Cb3guY29sbGlzaW9uVmVydGV4QnVmZmVyRXh0KSB7XG4gICAgICAgICAgICB0aGlzLnRleHRDb2xsaXNpb25Cb3guY29sbGlzaW9uVmVydGV4QnVmZmVyRXh0LnVwZGF0ZURhdGEodGhpcy50ZXh0Q29sbGlzaW9uQm94LmNvbGxpc2lvblZlcnRleEFycmF5RXh0KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5oYXNJY29uQ29sbGlzaW9uQm94RGF0YSgpICYmIHRoaXMuaWNvbkNvbGxpc2lvbkJveC5jb2xsaXNpb25WZXJ0ZXhCdWZmZXJFeHQpIHtcbiAgICAgICAgICAgIHRoaXMuaWNvbkNvbGxpc2lvbkJveC5jb2xsaXNpb25WZXJ0ZXhCdWZmZXJFeHQudXBkYXRlRGF0YSh0aGlzLmljb25Db2xsaXNpb25Cb3guY29sbGlzaW9uVmVydGV4QXJyYXlFeHQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gVGhlc2UgZmxhdCBhcnJheXMgYXJlIG1lYW50IHRvIGJlIHF1aWNrZXIgdG8gaXRlcmF0ZSBvdmVyIHRoYW4gdGhlIHNvdXJjZVxuICAgIC8vIENvbGxpc2lvbkJveEFycmF5XG4gICAgX2Rlc2VyaWFsaXplQ29sbGlzaW9uQm94ZXNGb3JTeW1ib2woY29sbGlzaW9uQm94QXJyYXk6IENvbGxpc2lvbkJveEFycmF5LFxuICAgICAgICB0ZXh0U3RhcnRJbmRleDogbnVtYmVyLCB0ZXh0RW5kSW5kZXg6IG51bWJlcixcbiAgICAgICAgdmVydGljYWxUZXh0U3RhcnRJbmRleDogbnVtYmVyLCB2ZXJ0aWNhbFRleHRFbmRJbmRleDogbnVtYmVyLFxuICAgICAgICBpY29uU3RhcnRJbmRleDogbnVtYmVyLCBpY29uRW5kSW5kZXg6IG51bWJlcixcbiAgICAgICAgdmVydGljYWxJY29uU3RhcnRJbmRleDogbnVtYmVyLCB2ZXJ0aWNhbEljb25FbmRJbmRleDogbnVtYmVyKTogQ29sbGlzaW9uQXJyYXlzIHtcblxuICAgICAgICAvLyBPbmx5IG9uZSBib3ggYWxsb3dlZCBwZXIgaW5zdGFuY2VcbiAgICAgICAgY29uc3QgY29sbGlzaW9uQXJyYXlzID0ge307XG4gICAgICAgIGlmICh0ZXh0U3RhcnRJbmRleCA8IHRleHRFbmRJbmRleCkge1xuICAgICAgICAgICAgY29uc3Qge3gxLCB5MSwgeDIsIHkyLCBwYWRkaW5nLCBwcm9qZWN0ZWRBbmNob3JYLCBwcm9qZWN0ZWRBbmNob3JZLCBwcm9qZWN0ZWRBbmNob3JaLCB0aWxlQW5jaG9yWCwgdGlsZUFuY2hvclksIGZlYXR1cmVJbmRleH0gPSBjb2xsaXNpb25Cb3hBcnJheS5nZXQodGV4dFN0YXJ0SW5kZXgpO1xuICAgICAgICAgICAgY29sbGlzaW9uQXJyYXlzLnRleHRCb3ggPSB7eDEsIHkxLCB4MiwgeTIsIHBhZGRpbmcsIHByb2plY3RlZEFuY2hvclgsIHByb2plY3RlZEFuY2hvclksIHByb2plY3RlZEFuY2hvclosIHRpbGVBbmNob3JYLCB0aWxlQW5jaG9yWX07XG4gICAgICAgICAgICBjb2xsaXNpb25BcnJheXMudGV4dEZlYXR1cmVJbmRleCA9IGZlYXR1cmVJbmRleDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodmVydGljYWxUZXh0U3RhcnRJbmRleCA8IHZlcnRpY2FsVGV4dEVuZEluZGV4KSB7XG4gICAgICAgICAgICBjb25zdCB7eDEsIHkxLCB4MiwgeTIsIHBhZGRpbmcsIHByb2plY3RlZEFuY2hvclgsIHByb2plY3RlZEFuY2hvclksIHByb2plY3RlZEFuY2hvclosIHRpbGVBbmNob3JYLCB0aWxlQW5jaG9yWSwgZmVhdHVyZUluZGV4fSA9IGNvbGxpc2lvbkJveEFycmF5LmdldCh2ZXJ0aWNhbFRleHRTdGFydEluZGV4KTtcbiAgICAgICAgICAgIGNvbGxpc2lvbkFycmF5cy52ZXJ0aWNhbFRleHRCb3ggPSB7eDEsIHkxLCB4MiwgeTIsIHBhZGRpbmcsIHByb2plY3RlZEFuY2hvclgsIHByb2plY3RlZEFuY2hvclksIHByb2plY3RlZEFuY2hvclosIHRpbGVBbmNob3JYLCB0aWxlQW5jaG9yWX07XG4gICAgICAgICAgICBjb2xsaXNpb25BcnJheXMudmVydGljYWxUZXh0RmVhdHVyZUluZGV4ID0gZmVhdHVyZUluZGV4O1xuICAgICAgICB9XG4gICAgICAgIGlmIChpY29uU3RhcnRJbmRleCA8IGljb25FbmRJbmRleCkge1xuICAgICAgICAgICAgY29uc3Qge3gxLCB5MSwgeDIsIHkyLCBwYWRkaW5nLCBwcm9qZWN0ZWRBbmNob3JYLCBwcm9qZWN0ZWRBbmNob3JZLCBwcm9qZWN0ZWRBbmNob3JaLCB0aWxlQW5jaG9yWCwgdGlsZUFuY2hvclksIGZlYXR1cmVJbmRleH0gPSBjb2xsaXNpb25Cb3hBcnJheS5nZXQoaWNvblN0YXJ0SW5kZXgpO1xuICAgICAgICAgICAgY29sbGlzaW9uQXJyYXlzLmljb25Cb3ggPSB7eDEsIHkxLCB4MiwgeTIsIHBhZGRpbmcsIHByb2plY3RlZEFuY2hvclgsIHByb2plY3RlZEFuY2hvclksIHByb2plY3RlZEFuY2hvclosIHRpbGVBbmNob3JYLCB0aWxlQW5jaG9yWX07XG4gICAgICAgICAgICBjb2xsaXNpb25BcnJheXMuaWNvbkZlYXR1cmVJbmRleCA9IGZlYXR1cmVJbmRleDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodmVydGljYWxJY29uU3RhcnRJbmRleCA8IHZlcnRpY2FsSWNvbkVuZEluZGV4KSB7XG4gICAgICAgICAgICBjb25zdCB7eDEsIHkxLCB4MiwgeTIsIHBhZGRpbmcsIHByb2plY3RlZEFuY2hvclgsIHByb2plY3RlZEFuY2hvclksIHByb2plY3RlZEFuY2hvclosIHRpbGVBbmNob3JYLCB0aWxlQW5jaG9yWSwgZmVhdHVyZUluZGV4fSA9IGNvbGxpc2lvbkJveEFycmF5LmdldCh2ZXJ0aWNhbEljb25TdGFydEluZGV4KTtcbiAgICAgICAgICAgIGNvbGxpc2lvbkFycmF5cy52ZXJ0aWNhbEljb25Cb3ggPSB7eDEsIHkxLCB4MiwgeTIsIHBhZGRpbmcsIHByb2plY3RlZEFuY2hvclgsIHByb2plY3RlZEFuY2hvclksIHByb2plY3RlZEFuY2hvclosIHRpbGVBbmNob3JYLCB0aWxlQW5jaG9yWX07XG4gICAgICAgICAgICBjb2xsaXNpb25BcnJheXMudmVydGljYWxJY29uRmVhdHVyZUluZGV4ID0gZmVhdHVyZUluZGV4O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb2xsaXNpb25BcnJheXM7XG4gICAgfVxuXG4gICAgZGVzZXJpYWxpemVDb2xsaXNpb25Cb3hlcyhjb2xsaXNpb25Cb3hBcnJheTogQ29sbGlzaW9uQm94QXJyYXkpIHtcbiAgICAgICAgdGhpcy5jb2xsaXNpb25BcnJheXMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnN5bWJvbEluc3RhbmNlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3Qgc3ltYm9sSW5zdGFuY2UgPSB0aGlzLnN5bWJvbEluc3RhbmNlcy5nZXQoaSk7XG4gICAgICAgICAgICB0aGlzLmNvbGxpc2lvbkFycmF5cy5wdXNoKHRoaXMuX2Rlc2VyaWFsaXplQ29sbGlzaW9uQm94ZXNGb3JTeW1ib2woXG4gICAgICAgICAgICAgICAgY29sbGlzaW9uQm94QXJyYXksXG4gICAgICAgICAgICAgICAgc3ltYm9sSW5zdGFuY2UudGV4dEJveFN0YXJ0SW5kZXgsXG4gICAgICAgICAgICAgICAgc3ltYm9sSW5zdGFuY2UudGV4dEJveEVuZEluZGV4LFxuICAgICAgICAgICAgICAgIHN5bWJvbEluc3RhbmNlLnZlcnRpY2FsVGV4dEJveFN0YXJ0SW5kZXgsXG4gICAgICAgICAgICAgICAgc3ltYm9sSW5zdGFuY2UudmVydGljYWxUZXh0Qm94RW5kSW5kZXgsXG4gICAgICAgICAgICAgICAgc3ltYm9sSW5zdGFuY2UuaWNvbkJveFN0YXJ0SW5kZXgsXG4gICAgICAgICAgICAgICAgc3ltYm9sSW5zdGFuY2UuaWNvbkJveEVuZEluZGV4LFxuICAgICAgICAgICAgICAgIHN5bWJvbEluc3RhbmNlLnZlcnRpY2FsSWNvbkJveFN0YXJ0SW5kZXgsXG4gICAgICAgICAgICAgICAgc3ltYm9sSW5zdGFuY2UudmVydGljYWxJY29uQm94RW5kSW5kZXhcbiAgICAgICAgICAgICkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaGFzVGV4dERhdGEoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLnRleHQuc2VnbWVudHMuZ2V0KCkubGVuZ3RoID4gMDtcbiAgICB9XG5cbiAgICBoYXNJY29uRGF0YSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaWNvbi5zZWdtZW50cy5nZXQoKS5sZW5ndGggPiAwO1xuICAgIH1cblxuICAgIGhhc0RlYnVnRGF0YSgpOiBDb2xsaXNpb25CdWZmZXJzIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGV4dENvbGxpc2lvbkJveCAmJiB0aGlzLmljb25Db2xsaXNpb25Cb3g7XG4gICAgfVxuXG4gICAgaGFzVGV4dENvbGxpc2lvbkJveERhdGEoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmhhc0RlYnVnRGF0YSgpICYmIHRoaXMudGV4dENvbGxpc2lvbkJveC5zZWdtZW50cy5nZXQoKS5sZW5ndGggPiAwO1xuICAgIH1cblxuICAgIGhhc0ljb25Db2xsaXNpb25Cb3hEYXRhKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5oYXNEZWJ1Z0RhdGEoKSAmJiB0aGlzLmljb25Db2xsaXNpb25Cb3guc2VnbWVudHMuZ2V0KCkubGVuZ3RoID4gMDtcbiAgICB9XG5cbiAgICBhZGRJbmRpY2VzRm9yUGxhY2VkU3ltYm9sKGljb25PclRleHQ6IFN5bWJvbEJ1ZmZlcnMsIHBsYWNlZFN5bWJvbEluZGV4OiBudW1iZXIpIHtcbiAgICAgICAgY29uc3QgcGxhY2VkU3ltYm9sID0gaWNvbk9yVGV4dC5wbGFjZWRTeW1ib2xBcnJheS5nZXQocGxhY2VkU3ltYm9sSW5kZXgpO1xuXG4gICAgICAgIGNvbnN0IGVuZEluZGV4ID0gcGxhY2VkU3ltYm9sLnZlcnRleFN0YXJ0SW5kZXggKyBwbGFjZWRTeW1ib2wubnVtR2x5cGhzICogNDtcbiAgICAgICAgZm9yIChsZXQgdmVydGV4SW5kZXggPSBwbGFjZWRTeW1ib2wudmVydGV4U3RhcnRJbmRleDsgdmVydGV4SW5kZXggPCBlbmRJbmRleDsgdmVydGV4SW5kZXggKz0gNCkge1xuICAgICAgICAgICAgaWNvbk9yVGV4dC5pbmRleEFycmF5LmVtcGxhY2VCYWNrKHZlcnRleEluZGV4LCB2ZXJ0ZXhJbmRleCArIDEsIHZlcnRleEluZGV4ICsgMik7XG4gICAgICAgICAgICBpY29uT3JUZXh0LmluZGV4QXJyYXkuZW1wbGFjZUJhY2sodmVydGV4SW5kZXggKyAxLCB2ZXJ0ZXhJbmRleCArIDIsIHZlcnRleEluZGV4ICsgMyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRTb3J0ZWRTeW1ib2xJbmRleGVzKGFuZ2xlOiBudW1iZXIpOiBBcnJheTxudW1iZXI+IHtcbiAgICAgICAgaWYgKHRoaXMuc29ydGVkQW5nbGUgPT09IGFuZ2xlICYmIHRoaXMuc3ltYm9sSW5zdGFuY2VJbmRleGVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnN5bWJvbEluc3RhbmNlSW5kZXhlcztcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzaW4gPSBNYXRoLnNpbihhbmdsZSk7XG4gICAgICAgIGNvbnN0IGNvcyA9IE1hdGguY29zKGFuZ2xlKTtcbiAgICAgICAgY29uc3Qgcm90YXRlZFlzID0gW107XG4gICAgICAgIGNvbnN0IGZlYXR1cmVJbmRleGVzID0gW107XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zeW1ib2xJbnN0YW5jZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKGkpO1xuICAgICAgICAgICAgY29uc3Qgc3ltYm9sSW5zdGFuY2UgPSB0aGlzLnN5bWJvbEluc3RhbmNlcy5nZXQoaSk7XG4gICAgICAgICAgICByb3RhdGVkWXMucHVzaChNYXRoLnJvdW5kKHNpbiAqIHN5bWJvbEluc3RhbmNlLnRpbGVBbmNob3JYICsgY29zICogc3ltYm9sSW5zdGFuY2UudGlsZUFuY2hvclkpIHwgMCk7XG4gICAgICAgICAgICBmZWF0dXJlSW5kZXhlcy5wdXNoKHN5bWJvbEluc3RhbmNlLmZlYXR1cmVJbmRleCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXN1bHQuc29ydCgoYUluZGV4LCBiSW5kZXgpID0+IChyb3RhdGVkWXNbYUluZGV4XSAtIHJvdGF0ZWRZc1tiSW5kZXhdKSB8fCAoZmVhdHVyZUluZGV4ZXNbYkluZGV4XSAtIGZlYXR1cmVJbmRleGVzW2FJbmRleF0pKTtcblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIGFkZFRvU29ydEtleVJhbmdlcyhzeW1ib2xJbnN0YW5jZUluZGV4OiBudW1iZXIsIHNvcnRLZXk6IG51bWJlcikge1xuICAgICAgICBjb25zdCBsYXN0ID0gdGhpcy5zb3J0S2V5UmFuZ2VzW3RoaXMuc29ydEtleVJhbmdlcy5sZW5ndGggLSAxXTtcbiAgICAgICAgaWYgKGxhc3QgJiYgbGFzdC5zb3J0S2V5ID09PSBzb3J0S2V5KSB7XG4gICAgICAgICAgICBsYXN0LnN5bWJvbEluc3RhbmNlRW5kID0gc3ltYm9sSW5zdGFuY2VJbmRleCArIDE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNvcnRLZXlSYW5nZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgc29ydEtleSxcbiAgICAgICAgICAgICAgICBzeW1ib2xJbnN0YW5jZVN0YXJ0OiBzeW1ib2xJbnN0YW5jZUluZGV4LFxuICAgICAgICAgICAgICAgIHN5bWJvbEluc3RhbmNlRW5kOiBzeW1ib2xJbnN0YW5jZUluZGV4ICsgMVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzb3J0RmVhdHVyZXMoYW5nbGU6IG51bWJlcikge1xuICAgICAgICBpZiAoIXRoaXMuc29ydEZlYXR1cmVzQnlZKSByZXR1cm47XG4gICAgICAgIGlmICh0aGlzLnNvcnRlZEFuZ2xlID09PSBhbmdsZSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIFRoZSBjdXJyZW50IGFwcHJvYWNoIHRvIHNvcnRpbmcgZG9lc24ndCBzb3J0IGFjcm9zcyBzZWdtZW50cyBzbyBkb24ndCB0cnkuXG4gICAgICAgIC8vIFNvcnRpbmcgd2l0aGluIHNlZ21lbnRzIHNlcGFyYXRlbHkgc2VlbWVkIG5vdCB0byBiZSB3b3J0aCB0aGUgY29tcGxleGl0eS5cbiAgICAgICAgaWYgKHRoaXMudGV4dC5zZWdtZW50cy5nZXQoKS5sZW5ndGggPiAxIHx8IHRoaXMuaWNvbi5zZWdtZW50cy5nZXQoKS5sZW5ndGggPiAxKSByZXR1cm47XG5cbiAgICAgICAgLy8gSWYgdGhlIHN5bWJvbHMgYXJlIGFsbG93ZWQgdG8gb3ZlcmxhcCBzb3J0IHRoZW0gYnkgdGhlaXIgdmVydGljYWwgc2NyZWVuIHBvc2l0aW9uLlxuICAgICAgICAvLyBUaGUgaW5kZXggYXJyYXkgYnVmZmVyIGlzIHJld3JpdHRlbiB0byByZWZlcmVuY2UgdGhlICh1bmNoYW5nZWQpIHZlcnRpY2VzIGluIHRoZVxuICAgICAgICAvLyBzb3J0ZWQgb3JkZXIuXG5cbiAgICAgICAgLy8gVG8gYXZvaWQgc29ydGluZyB0aGUgYWN0dWFsIHN5bWJvbEluc3RhbmNlIGFycmF5IHdlIHNvcnQgYW4gYXJyYXkgb2YgaW5kZXhlcy5cbiAgICAgICAgdGhpcy5zeW1ib2xJbnN0YW5jZUluZGV4ZXMgPSB0aGlzLmdldFNvcnRlZFN5bWJvbEluZGV4ZXMoYW5nbGUpO1xuICAgICAgICB0aGlzLnNvcnRlZEFuZ2xlID0gYW5nbGU7XG5cbiAgICAgICAgdGhpcy50ZXh0LmluZGV4QXJyYXkuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5pY29uLmluZGV4QXJyYXkuY2xlYXIoKTtcblxuICAgICAgICB0aGlzLmZlYXR1cmVTb3J0T3JkZXIgPSBbXTtcblxuICAgICAgICBmb3IgKGNvbnN0IGkgb2YgdGhpcy5zeW1ib2xJbnN0YW5jZUluZGV4ZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHN5bWJvbCA9IHRoaXMuc3ltYm9sSW5zdGFuY2VzLmdldChpKTtcbiAgICAgICAgICAgIHRoaXMuZmVhdHVyZVNvcnRPcmRlci5wdXNoKHN5bWJvbC5mZWF0dXJlSW5kZXgpO1xuICAgICAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgICAgIHJpZ2h0SnVzdGlmaWVkVGV4dFN5bWJvbEluZGV4OiByaWdodCwgY2VudGVySnVzdGlmaWVkVGV4dFN5bWJvbEluZGV4OiBjZW50ZXIsXG4gICAgICAgICAgICAgICAgbGVmdEp1c3RpZmllZFRleHRTeW1ib2xJbmRleDogbGVmdCwgdmVydGljYWxQbGFjZWRUZXh0U3ltYm9sSW5kZXg6IHZlcnRpY2FsLFxuICAgICAgICAgICAgICAgIHBsYWNlZEljb25TeW1ib2xJbmRleDogaWNvbiwgdmVydGljYWxQbGFjZWRJY29uU3ltYm9sSW5kZXg6IGljb25WZXJ0aWNhbFxuICAgICAgICAgICAgfSA9IHN5bWJvbDtcblxuICAgICAgICAgICAgLy8gT25seSBhZGQgYSBnaXZlbiBpbmRleCB0aGUgZmlyc3QgdGltZSBpdCBzaG93cyB1cCwgdG8gYXZvaWQgZHVwbGljYXRlXG4gICAgICAgICAgICAvLyBvcGFjaXR5IGVudHJpZXMgd2hlbiBtdWx0aXBsZSBqdXN0aWZpY2F0aW9ucyBzaGFyZSB0aGUgc2FtZSBnbHlwaHMuXG4gICAgICAgICAgICBpZiAocmlnaHQgPj0gMCkgdGhpcy5hZGRJbmRpY2VzRm9yUGxhY2VkU3ltYm9sKHRoaXMudGV4dCwgcmlnaHQpO1xuICAgICAgICAgICAgaWYgKGNlbnRlciA+PSAwICYmIGNlbnRlciAhPT0gcmlnaHQpIHRoaXMuYWRkSW5kaWNlc0ZvclBsYWNlZFN5bWJvbCh0aGlzLnRleHQsIGNlbnRlcik7XG4gICAgICAgICAgICBpZiAobGVmdCA+PSAwICYmIGxlZnQgIT09IGNlbnRlciAmJiBsZWZ0ICE9PSByaWdodCkgdGhpcy5hZGRJbmRpY2VzRm9yUGxhY2VkU3ltYm9sKHRoaXMudGV4dCwgbGVmdCk7XG5cbiAgICAgICAgICAgIGlmICh2ZXJ0aWNhbCA+PSAwKSB0aGlzLmFkZEluZGljZXNGb3JQbGFjZWRTeW1ib2wodGhpcy50ZXh0LCB2ZXJ0aWNhbCk7XG4gICAgICAgICAgICBpZiAoaWNvbiA+PSAwKSB0aGlzLmFkZEluZGljZXNGb3JQbGFjZWRTeW1ib2wodGhpcy5pY29uLCBpY29uKTtcbiAgICAgICAgICAgIGlmIChpY29uVmVydGljYWwgPj0gMCkgdGhpcy5hZGRJbmRpY2VzRm9yUGxhY2VkU3ltYm9sKHRoaXMuaWNvbiwgaWNvblZlcnRpY2FsKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnRleHQuaW5kZXhCdWZmZXIpIHRoaXMudGV4dC5pbmRleEJ1ZmZlci51cGRhdGVEYXRhKHRoaXMudGV4dC5pbmRleEFycmF5KTtcbiAgICAgICAgaWYgKHRoaXMuaWNvbi5pbmRleEJ1ZmZlcikgdGhpcy5pY29uLmluZGV4QnVmZmVyLnVwZGF0ZURhdGEodGhpcy5pY29uLmluZGV4QXJyYXkpO1xuICAgIH1cbn1cblxucmVnaXN0ZXIoU3ltYm9sQnVja2V0LCAnU3ltYm9sQnVja2V0Jywge1xuICAgIG9taXQ6IFsnbGF5ZXJzJywgJ2NvbGxpc2lvbkJveEFycmF5JywgJ2ZlYXR1cmVzJywgJ2NvbXBhcmVUZXh0J11cbn0pO1xuXG4vLyB0aGlzIGNvbnN0YW50IGlzIGJhc2VkIG9uIHRoZSBzaXplIG9mIFN0cnVjdEFycmF5IGluZGV4ZXMgdXNlZCBpbiBhIHN5bWJvbFxuLy8gYnVja2V0LS1uYW1lbHksIGdseXBoT2Zmc2V0QXJyYXlTdGFydFxuLy8gZWcgdGhlIG1heCB2YWxpZCBVSW50MTYgaXMgNjUsNTM1XG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL21hcGJveC9tYXBib3gtZ2wtanMvaXNzdWVzLzI5MDcgZm9yIG1vdGl2YXRpb25cbi8vIGxpbmVTdGFydEluZGV4IGFuZCB0ZXh0Qm94U3RhcnRJbmRleCBjb3VsZCBwb3RlbnRpYWxseSBiZSBjb25jZXJuc1xuLy8gYnV0IHdlIGV4cGVjdCB0aGVyZSB0byBiZSBtYW55IGZld2VyIGJveGVzL2xpbmVzIHRoYW4gZ2x5cGhzXG5TeW1ib2xCdWNrZXQuTUFYX0dMWVBIUyA9IDY1NTM1O1xuXG5TeW1ib2xCdWNrZXQuYWRkRHluYW1pY0F0dHJpYnV0ZXMgPSBhZGREeW5hbWljQXR0cmlidXRlcztcblxuZXhwb3J0IGRlZmF1bHQgU3ltYm9sQnVja2V0O1xuZXhwb3J0IHthZGREeW5hbWljQXR0cmlidXRlcywgdXBkYXRlR2xvYmVWZXJ0ZXhOb3JtYWx9O1xuIiwiLy8gQGZsb3dcbmV4cG9ydCBkZWZhdWx0IHJlc29sdmVUb2tlbnM7XG5cbi8qKlxuICogUmVwbGFjZSB0b2tlbnMgaW4gYSBzdHJpbmcgdGVtcGxhdGUgd2l0aCB2YWx1ZXMgaW4gYW4gb2JqZWN0XG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgYSBrZXkvdmFsdWUgcmVsYXRpb25zaGlwIGJldHdlZW4gdG9rZW5zIGFuZCByZXBsYWNlbWVudHNcbiAqIEBwYXJhbSB0ZXh0IHRoZSB0ZW1wbGF0ZSBzdHJpbmdcbiAqIEByZXR1cm5zIHRoZSB0ZW1wbGF0ZSB3aXRoIHRva2VucyByZXBsYWNlZFxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZVRva2Vucyhwcm9wZXJ0aWVzOiB7K1tzdHJpbmddOiBtaXhlZH0sIHRleHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRleHQucmVwbGFjZSgveyhbXnt9XSspfS9nLCAobWF0Y2gsIGtleTogc3RyaW5nKSA9PiB7XG4gICAgICAgIHJldHVybiBrZXkgaW4gcHJvcGVydGllcyA/IFN0cmluZyhwcm9wZXJ0aWVzW2tleV0pIDogJyc7XG4gICAgfSk7XG59XG4iLCIvLyBUaGlzIGZpbGUgaXMgZ2VuZXJhdGVkLiBFZGl0IGJ1aWxkL2dlbmVyYXRlLXN0eWxlLWNvZGUuanMsIHRoZW4gcnVuIGB5YXJuIHJ1biBjb2RlZ2VuYC5cbi8vIEBmbG93XG4vKiBlc2xpbnQtZGlzYWJsZSAqL1xuXG5pbXBvcnQgc3R5bGVTcGVjIGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvcmVmZXJlbmNlL2xhdGVzdC5qcyc7XG5cbmltcG9ydCB7XG4gICAgUHJvcGVydGllcyxcbiAgICBEYXRhQ29uc3RhbnRQcm9wZXJ0eSxcbiAgICBEYXRhRHJpdmVuUHJvcGVydHksXG4gICAgQ29sb3JSYW1wUHJvcGVydHlcbn0gZnJvbSAnLi4vcHJvcGVydGllcy5qcyc7XG5cbmltcG9ydCB0eXBlIENvbG9yIGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvdXRpbC9jb2xvci5qcyc7XG5cbmltcG9ydCB0eXBlIEZvcm1hdHRlZCBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vdHlwZXMvZm9ybWF0dGVkLmpzJztcblxuaW1wb3J0IHR5cGUgUmVzb2x2ZWRJbWFnZSBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vdHlwZXMvcmVzb2x2ZWRfaW1hZ2UuanMnO1xuXG5pbXBvcnQge1xuICAgIENvbG9yVHlwZVxufSBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vdHlwZXMuanMnO1xuXG5leHBvcnQgdHlwZSBMYXlvdXRQcm9wcyA9IHt8XG4gICAgXCJzeW1ib2wtcGxhY2VtZW50XCI6IERhdGFDb25zdGFudFByb3BlcnR5PFwicG9pbnRcIiB8IFwibGluZVwiIHwgXCJsaW5lLWNlbnRlclwiPixcbiAgICBcInN5bWJvbC1zcGFjaW5nXCI6IERhdGFDb25zdGFudFByb3BlcnR5PG51bWJlcj4sXG4gICAgXCJzeW1ib2wtYXZvaWQtZWRnZXNcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8Ym9vbGVhbj4sXG4gICAgXCJzeW1ib2wtc29ydC1rZXlcIjogRGF0YURyaXZlblByb3BlcnR5PG51bWJlcj4sXG4gICAgXCJzeW1ib2wtei1vcmRlclwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxcImF1dG9cIiB8IFwidmlld3BvcnQteVwiIHwgXCJzb3VyY2VcIj4sXG4gICAgXCJpY29uLWFsbG93LW92ZXJsYXBcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8Ym9vbGVhbj4sXG4gICAgXCJpY29uLWlnbm9yZS1wbGFjZW1lbnRcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8Ym9vbGVhbj4sXG4gICAgXCJpY29uLW9wdGlvbmFsXCI6IERhdGFDb25zdGFudFByb3BlcnR5PGJvb2xlYW4+LFxuICAgIFwiaWNvbi1yb3RhdGlvbi1hbGlnbm1lbnRcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8XCJtYXBcIiB8IFwidmlld3BvcnRcIiB8IFwiYXV0b1wiPixcbiAgICBcImljb24tc2l6ZVwiOiBEYXRhRHJpdmVuUHJvcGVydHk8bnVtYmVyPixcbiAgICBcImljb24tdGV4dC1maXRcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8XCJub25lXCIgfCBcIndpZHRoXCIgfCBcImhlaWdodFwiIHwgXCJib3RoXCI+LFxuICAgIFwiaWNvbi10ZXh0LWZpdC1wYWRkaW5nXCI6IERhdGFDb25zdGFudFByb3BlcnR5PFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdPixcbiAgICBcImljb24taW1hZ2VcIjogRGF0YURyaXZlblByb3BlcnR5PFJlc29sdmVkSW1hZ2U+LFxuICAgIFwiaWNvbi1yb3RhdGVcIjogRGF0YURyaXZlblByb3BlcnR5PG51bWJlcj4sXG4gICAgXCJpY29uLXBhZGRpbmdcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8bnVtYmVyPixcbiAgICBcImljb24ta2VlcC11cHJpZ2h0XCI6IERhdGFDb25zdGFudFByb3BlcnR5PGJvb2xlYW4+LFxuICAgIFwiaWNvbi1vZmZzZXRcIjogRGF0YURyaXZlblByb3BlcnR5PFtudW1iZXIsIG51bWJlcl0+LFxuICAgIFwiaWNvbi1hbmNob3JcIjogRGF0YURyaXZlblByb3BlcnR5PFwiY2VudGVyXCIgfCBcImxlZnRcIiB8IFwicmlnaHRcIiB8IFwidG9wXCIgfCBcImJvdHRvbVwiIHwgXCJ0b3AtbGVmdFwiIHwgXCJ0b3AtcmlnaHRcIiB8IFwiYm90dG9tLWxlZnRcIiB8IFwiYm90dG9tLXJpZ2h0XCI+LFxuICAgIFwiaWNvbi1waXRjaC1hbGlnbm1lbnRcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8XCJtYXBcIiB8IFwidmlld3BvcnRcIiB8IFwiYXV0b1wiPixcbiAgICBcInRleHQtcGl0Y2gtYWxpZ25tZW50XCI6IERhdGFDb25zdGFudFByb3BlcnR5PFwibWFwXCIgfCBcInZpZXdwb3J0XCIgfCBcImF1dG9cIj4sXG4gICAgXCJ0ZXh0LXJvdGF0aW9uLWFsaWdubWVudFwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxcIm1hcFwiIHwgXCJ2aWV3cG9ydFwiIHwgXCJhdXRvXCI+LFxuICAgIFwidGV4dC1maWVsZFwiOiBEYXRhRHJpdmVuUHJvcGVydHk8Rm9ybWF0dGVkPixcbiAgICBcInRleHQtZm9udFwiOiBEYXRhRHJpdmVuUHJvcGVydHk8QXJyYXk8c3RyaW5nPj4sXG4gICAgXCJ0ZXh0LXNpemVcIjogRGF0YURyaXZlblByb3BlcnR5PG51bWJlcj4sXG4gICAgXCJ0ZXh0LW1heC13aWR0aFwiOiBEYXRhRHJpdmVuUHJvcGVydHk8bnVtYmVyPixcbiAgICBcInRleHQtbGluZS1oZWlnaHRcIjogRGF0YURyaXZlblByb3BlcnR5PG51bWJlcj4sXG4gICAgXCJ0ZXh0LWxldHRlci1zcGFjaW5nXCI6IERhdGFEcml2ZW5Qcm9wZXJ0eTxudW1iZXI+LFxuICAgIFwidGV4dC1qdXN0aWZ5XCI6IERhdGFEcml2ZW5Qcm9wZXJ0eTxcImF1dG9cIiB8IFwibGVmdFwiIHwgXCJjZW50ZXJcIiB8IFwicmlnaHRcIj4sXG4gICAgXCJ0ZXh0LXJhZGlhbC1vZmZzZXRcIjogRGF0YURyaXZlblByb3BlcnR5PG51bWJlcj4sXG4gICAgXCJ0ZXh0LXZhcmlhYmxlLWFuY2hvclwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxBcnJheTxcImNlbnRlclwiIHwgXCJsZWZ0XCIgfCBcInJpZ2h0XCIgfCBcInRvcFwiIHwgXCJib3R0b21cIiB8IFwidG9wLWxlZnRcIiB8IFwidG9wLXJpZ2h0XCIgfCBcImJvdHRvbS1sZWZ0XCIgfCBcImJvdHRvbS1yaWdodFwiPj4sXG4gICAgXCJ0ZXh0LWFuY2hvclwiOiBEYXRhRHJpdmVuUHJvcGVydHk8XCJjZW50ZXJcIiB8IFwibGVmdFwiIHwgXCJyaWdodFwiIHwgXCJ0b3BcIiB8IFwiYm90dG9tXCIgfCBcInRvcC1sZWZ0XCIgfCBcInRvcC1yaWdodFwiIHwgXCJib3R0b20tbGVmdFwiIHwgXCJib3R0b20tcmlnaHRcIj4sXG4gICAgXCJ0ZXh0LW1heC1hbmdsZVwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxudW1iZXI+LFxuICAgIFwidGV4dC13cml0aW5nLW1vZGVcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8QXJyYXk8XCJob3Jpem9udGFsXCIgfCBcInZlcnRpY2FsXCI+PixcbiAgICBcInRleHQtcm90YXRlXCI6IERhdGFEcml2ZW5Qcm9wZXJ0eTxudW1iZXI+LFxuICAgIFwidGV4dC1wYWRkaW5nXCI6IERhdGFDb25zdGFudFByb3BlcnR5PG51bWJlcj4sXG4gICAgXCJ0ZXh0LWtlZXAtdXByaWdodFwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxib29sZWFuPixcbiAgICBcInRleHQtdHJhbnNmb3JtXCI6IERhdGFEcml2ZW5Qcm9wZXJ0eTxcIm5vbmVcIiB8IFwidXBwZXJjYXNlXCIgfCBcImxvd2VyY2FzZVwiPixcbiAgICBcInRleHQtb2Zmc2V0XCI6IERhdGFEcml2ZW5Qcm9wZXJ0eTxbbnVtYmVyLCBudW1iZXJdPixcbiAgICBcInRleHQtYWxsb3ctb3ZlcmxhcFwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxib29sZWFuPixcbiAgICBcInRleHQtaWdub3JlLXBsYWNlbWVudFwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxib29sZWFuPixcbiAgICBcInRleHQtb3B0aW9uYWxcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8Ym9vbGVhbj4sXG58fTtcblxuY29uc3QgbGF5b3V0OiBQcm9wZXJ0aWVzPExheW91dFByb3BzPiA9IG5ldyBQcm9wZXJ0aWVzKHtcbiAgICBcInN5bWJvbC1wbGFjZW1lbnRcIjogbmV3IERhdGFDb25zdGFudFByb3BlcnR5KHN0eWxlU3BlY1tcImxheW91dF9zeW1ib2xcIl1bXCJzeW1ib2wtcGxhY2VtZW50XCJdKSxcbiAgICBcInN5bWJvbC1zcGFjaW5nXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJsYXlvdXRfc3ltYm9sXCJdW1wic3ltYm9sLXNwYWNpbmdcIl0pLFxuICAgIFwic3ltYm9sLWF2b2lkLWVkZ2VzXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJsYXlvdXRfc3ltYm9sXCJdW1wic3ltYm9sLWF2b2lkLWVkZ2VzXCJdKSxcbiAgICBcInN5bWJvbC1zb3J0LWtleVwiOiBuZXcgRGF0YURyaXZlblByb3BlcnR5KHN0eWxlU3BlY1tcImxheW91dF9zeW1ib2xcIl1bXCJzeW1ib2wtc29ydC1rZXlcIl0pLFxuICAgIFwic3ltYm9sLXotb3JkZXJcIjogbmV3IERhdGFDb25zdGFudFByb3BlcnR5KHN0eWxlU3BlY1tcImxheW91dF9zeW1ib2xcIl1bXCJzeW1ib2wtei1vcmRlclwiXSksXG4gICAgXCJpY29uLWFsbG93LW92ZXJsYXBcIjogbmV3IERhdGFDb25zdGFudFByb3BlcnR5KHN0eWxlU3BlY1tcImxheW91dF9zeW1ib2xcIl1bXCJpY29uLWFsbG93LW92ZXJsYXBcIl0pLFxuICAgIFwiaWNvbi1pZ25vcmUtcGxhY2VtZW50XCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJsYXlvdXRfc3ltYm9sXCJdW1wiaWNvbi1pZ25vcmUtcGxhY2VtZW50XCJdKSxcbiAgICBcImljb24tb3B0aW9uYWxcIjogbmV3IERhdGFDb25zdGFudFByb3BlcnR5KHN0eWxlU3BlY1tcImxheW91dF9zeW1ib2xcIl1bXCJpY29uLW9wdGlvbmFsXCJdKSxcbiAgICBcImljb24tcm90YXRpb24tYWxpZ25tZW50XCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJsYXlvdXRfc3ltYm9sXCJdW1wiaWNvbi1yb3RhdGlvbi1hbGlnbm1lbnRcIl0pLFxuICAgIFwiaWNvbi1zaXplXCI6IG5ldyBEYXRhRHJpdmVuUHJvcGVydHkoc3R5bGVTcGVjW1wibGF5b3V0X3N5bWJvbFwiXVtcImljb24tc2l6ZVwiXSksXG4gICAgXCJpY29uLXRleHQtZml0XCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJsYXlvdXRfc3ltYm9sXCJdW1wiaWNvbi10ZXh0LWZpdFwiXSksXG4gICAgXCJpY29uLXRleHQtZml0LXBhZGRpbmdcIjogbmV3IERhdGFDb25zdGFudFByb3BlcnR5KHN0eWxlU3BlY1tcImxheW91dF9zeW1ib2xcIl1bXCJpY29uLXRleHQtZml0LXBhZGRpbmdcIl0pLFxuICAgIFwiaWNvbi1pbWFnZVwiOiBuZXcgRGF0YURyaXZlblByb3BlcnR5KHN0eWxlU3BlY1tcImxheW91dF9zeW1ib2xcIl1bXCJpY29uLWltYWdlXCJdKSxcbiAgICBcImljb24tcm90YXRlXCI6IG5ldyBEYXRhRHJpdmVuUHJvcGVydHkoc3R5bGVTcGVjW1wibGF5b3V0X3N5bWJvbFwiXVtcImljb24tcm90YXRlXCJdKSxcbiAgICBcImljb24tcGFkZGluZ1wiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjW1wibGF5b3V0X3N5bWJvbFwiXVtcImljb24tcGFkZGluZ1wiXSksXG4gICAgXCJpY29uLWtlZXAtdXByaWdodFwiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjW1wibGF5b3V0X3N5bWJvbFwiXVtcImljb24ta2VlcC11cHJpZ2h0XCJdKSxcbiAgICBcImljb24tb2Zmc2V0XCI6IG5ldyBEYXRhRHJpdmVuUHJvcGVydHkoc3R5bGVTcGVjW1wibGF5b3V0X3N5bWJvbFwiXVtcImljb24tb2Zmc2V0XCJdKSxcbiAgICBcImljb24tYW5jaG9yXCI6IG5ldyBEYXRhRHJpdmVuUHJvcGVydHkoc3R5bGVTcGVjW1wibGF5b3V0X3N5bWJvbFwiXVtcImljb24tYW5jaG9yXCJdKSxcbiAgICBcImljb24tcGl0Y2gtYWxpZ25tZW50XCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJsYXlvdXRfc3ltYm9sXCJdW1wiaWNvbi1waXRjaC1hbGlnbm1lbnRcIl0pLFxuICAgIFwidGV4dC1waXRjaC1hbGlnbm1lbnRcIjogbmV3IERhdGFDb25zdGFudFByb3BlcnR5KHN0eWxlU3BlY1tcImxheW91dF9zeW1ib2xcIl1bXCJ0ZXh0LXBpdGNoLWFsaWdubWVudFwiXSksXG4gICAgXCJ0ZXh0LXJvdGF0aW9uLWFsaWdubWVudFwiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjW1wibGF5b3V0X3N5bWJvbFwiXVtcInRleHQtcm90YXRpb24tYWxpZ25tZW50XCJdKSxcbiAgICBcInRleHQtZmllbGRcIjogbmV3IERhdGFEcml2ZW5Qcm9wZXJ0eShzdHlsZVNwZWNbXCJsYXlvdXRfc3ltYm9sXCJdW1widGV4dC1maWVsZFwiXSksXG4gICAgXCJ0ZXh0LWZvbnRcIjogbmV3IERhdGFEcml2ZW5Qcm9wZXJ0eShzdHlsZVNwZWNbXCJsYXlvdXRfc3ltYm9sXCJdW1widGV4dC1mb250XCJdKSxcbiAgICBcInRleHQtc2l6ZVwiOiBuZXcgRGF0YURyaXZlblByb3BlcnR5KHN0eWxlU3BlY1tcImxheW91dF9zeW1ib2xcIl1bXCJ0ZXh0LXNpemVcIl0pLFxuICAgIFwidGV4dC1tYXgtd2lkdGhcIjogbmV3IERhdGFEcml2ZW5Qcm9wZXJ0eShzdHlsZVNwZWNbXCJsYXlvdXRfc3ltYm9sXCJdW1widGV4dC1tYXgtd2lkdGhcIl0pLFxuICAgIFwidGV4dC1saW5lLWhlaWdodFwiOiBuZXcgRGF0YURyaXZlblByb3BlcnR5KHN0eWxlU3BlY1tcImxheW91dF9zeW1ib2xcIl1bXCJ0ZXh0LWxpbmUtaGVpZ2h0XCJdKSxcbiAgICBcInRleHQtbGV0dGVyLXNwYWNpbmdcIjogbmV3IERhdGFEcml2ZW5Qcm9wZXJ0eShzdHlsZVNwZWNbXCJsYXlvdXRfc3ltYm9sXCJdW1widGV4dC1sZXR0ZXItc3BhY2luZ1wiXSksXG4gICAgXCJ0ZXh0LWp1c3RpZnlcIjogbmV3IERhdGFEcml2ZW5Qcm9wZXJ0eShzdHlsZVNwZWNbXCJsYXlvdXRfc3ltYm9sXCJdW1widGV4dC1qdXN0aWZ5XCJdKSxcbiAgICBcInRleHQtcmFkaWFsLW9mZnNldFwiOiBuZXcgRGF0YURyaXZlblByb3BlcnR5KHN0eWxlU3BlY1tcImxheW91dF9zeW1ib2xcIl1bXCJ0ZXh0LXJhZGlhbC1vZmZzZXRcIl0pLFxuICAgIFwidGV4dC12YXJpYWJsZS1hbmNob3JcIjogbmV3IERhdGFDb25zdGFudFByb3BlcnR5KHN0eWxlU3BlY1tcImxheW91dF9zeW1ib2xcIl1bXCJ0ZXh0LXZhcmlhYmxlLWFuY2hvclwiXSksXG4gICAgXCJ0ZXh0LWFuY2hvclwiOiBuZXcgRGF0YURyaXZlblByb3BlcnR5KHN0eWxlU3BlY1tcImxheW91dF9zeW1ib2xcIl1bXCJ0ZXh0LWFuY2hvclwiXSksXG4gICAgXCJ0ZXh0LW1heC1hbmdsZVwiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjW1wibGF5b3V0X3N5bWJvbFwiXVtcInRleHQtbWF4LWFuZ2xlXCJdKSxcbiAgICBcInRleHQtd3JpdGluZy1tb2RlXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJsYXlvdXRfc3ltYm9sXCJdW1widGV4dC13cml0aW5nLW1vZGVcIl0pLFxuICAgIFwidGV4dC1yb3RhdGVcIjogbmV3IERhdGFEcml2ZW5Qcm9wZXJ0eShzdHlsZVNwZWNbXCJsYXlvdXRfc3ltYm9sXCJdW1widGV4dC1yb3RhdGVcIl0pLFxuICAgIFwidGV4dC1wYWRkaW5nXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJsYXlvdXRfc3ltYm9sXCJdW1widGV4dC1wYWRkaW5nXCJdKSxcbiAgICBcInRleHQta2VlcC11cHJpZ2h0XCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJsYXlvdXRfc3ltYm9sXCJdW1widGV4dC1rZWVwLXVwcmlnaHRcIl0pLFxuICAgIFwidGV4dC10cmFuc2Zvcm1cIjogbmV3IERhdGFEcml2ZW5Qcm9wZXJ0eShzdHlsZVNwZWNbXCJsYXlvdXRfc3ltYm9sXCJdW1widGV4dC10cmFuc2Zvcm1cIl0pLFxuICAgIFwidGV4dC1vZmZzZXRcIjogbmV3IERhdGFEcml2ZW5Qcm9wZXJ0eShzdHlsZVNwZWNbXCJsYXlvdXRfc3ltYm9sXCJdW1widGV4dC1vZmZzZXRcIl0pLFxuICAgIFwidGV4dC1hbGxvdy1vdmVybGFwXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJsYXlvdXRfc3ltYm9sXCJdW1widGV4dC1hbGxvdy1vdmVybGFwXCJdKSxcbiAgICBcInRleHQtaWdub3JlLXBsYWNlbWVudFwiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjW1wibGF5b3V0X3N5bWJvbFwiXVtcInRleHQtaWdub3JlLXBsYWNlbWVudFwiXSksXG4gICAgXCJ0ZXh0LW9wdGlvbmFsXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJsYXlvdXRfc3ltYm9sXCJdW1widGV4dC1vcHRpb25hbFwiXSksXG59KTtcblxuZXhwb3J0IHR5cGUgUGFpbnRQcm9wcyA9IHt8XG4gICAgXCJpY29uLW9wYWNpdHlcIjogRGF0YURyaXZlblByb3BlcnR5PG51bWJlcj4sXG4gICAgXCJpY29uLWNvbG9yXCI6IERhdGFEcml2ZW5Qcm9wZXJ0eTxDb2xvcj4sXG4gICAgXCJpY29uLWhhbG8tY29sb3JcIjogRGF0YURyaXZlblByb3BlcnR5PENvbG9yPixcbiAgICBcImljb24taGFsby13aWR0aFwiOiBEYXRhRHJpdmVuUHJvcGVydHk8bnVtYmVyPixcbiAgICBcImljb24taGFsby1ibHVyXCI6IERhdGFEcml2ZW5Qcm9wZXJ0eTxudW1iZXI+LFxuICAgIFwiaWNvbi10cmFuc2xhdGVcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8W251bWJlciwgbnVtYmVyXT4sXG4gICAgXCJpY29uLXRyYW5zbGF0ZS1hbmNob3JcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8XCJtYXBcIiB8IFwidmlld3BvcnRcIj4sXG4gICAgXCJ0ZXh0LW9wYWNpdHlcIjogRGF0YURyaXZlblByb3BlcnR5PG51bWJlcj4sXG4gICAgXCJ0ZXh0LWNvbG9yXCI6IERhdGFEcml2ZW5Qcm9wZXJ0eTxDb2xvcj4sXG4gICAgXCJ0ZXh0LWhhbG8tY29sb3JcIjogRGF0YURyaXZlblByb3BlcnR5PENvbG9yPixcbiAgICBcInRleHQtaGFsby13aWR0aFwiOiBEYXRhRHJpdmVuUHJvcGVydHk8bnVtYmVyPixcbiAgICBcInRleHQtaGFsby1ibHVyXCI6IERhdGFEcml2ZW5Qcm9wZXJ0eTxudW1iZXI+LFxuICAgIFwidGV4dC10cmFuc2xhdGVcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8W251bWJlciwgbnVtYmVyXT4sXG4gICAgXCJ0ZXh0LXRyYW5zbGF0ZS1hbmNob3JcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8XCJtYXBcIiB8IFwidmlld3BvcnRcIj4sXG58fTtcblxuY29uc3QgcGFpbnQ6IFByb3BlcnRpZXM8UGFpbnRQcm9wcz4gPSBuZXcgUHJvcGVydGllcyh7XG4gICAgXCJpY29uLW9wYWNpdHlcIjogbmV3IERhdGFEcml2ZW5Qcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9zeW1ib2xcIl1bXCJpY29uLW9wYWNpdHlcIl0pLFxuICAgIFwiaWNvbi1jb2xvclwiOiBuZXcgRGF0YURyaXZlblByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X3N5bWJvbFwiXVtcImljb24tY29sb3JcIl0pLFxuICAgIFwiaWNvbi1oYWxvLWNvbG9yXCI6IG5ldyBEYXRhRHJpdmVuUHJvcGVydHkoc3R5bGVTcGVjW1wicGFpbnRfc3ltYm9sXCJdW1wiaWNvbi1oYWxvLWNvbG9yXCJdKSxcbiAgICBcImljb24taGFsby13aWR0aFwiOiBuZXcgRGF0YURyaXZlblByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X3N5bWJvbFwiXVtcImljb24taGFsby13aWR0aFwiXSksXG4gICAgXCJpY29uLWhhbG8tYmx1clwiOiBuZXcgRGF0YURyaXZlblByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X3N5bWJvbFwiXVtcImljb24taGFsby1ibHVyXCJdKSxcbiAgICBcImljb24tdHJhbnNsYXRlXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9zeW1ib2xcIl1bXCJpY29uLXRyYW5zbGF0ZVwiXSksXG4gICAgXCJpY29uLXRyYW5zbGF0ZS1hbmNob3JcIjogbmV3IERhdGFDb25zdGFudFByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X3N5bWJvbFwiXVtcImljb24tdHJhbnNsYXRlLWFuY2hvclwiXSksXG4gICAgXCJ0ZXh0LW9wYWNpdHlcIjogbmV3IERhdGFEcml2ZW5Qcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9zeW1ib2xcIl1bXCJ0ZXh0LW9wYWNpdHlcIl0pLFxuICAgIFwidGV4dC1jb2xvclwiOiBuZXcgRGF0YURyaXZlblByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X3N5bWJvbFwiXVtcInRleHQtY29sb3JcIl0sIHsgcnVudGltZVR5cGU6IENvbG9yVHlwZSwgZ2V0T3ZlcnJpZGU6IChvKSA9PiBvLnRleHRDb2xvciwgaGFzT3ZlcnJpZGU6IChvKSA9PiAhIW8udGV4dENvbG9yIH0pLFxuICAgIFwidGV4dC1oYWxvLWNvbG9yXCI6IG5ldyBEYXRhRHJpdmVuUHJvcGVydHkoc3R5bGVTcGVjW1wicGFpbnRfc3ltYm9sXCJdW1widGV4dC1oYWxvLWNvbG9yXCJdKSxcbiAgICBcInRleHQtaGFsby13aWR0aFwiOiBuZXcgRGF0YURyaXZlblByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X3N5bWJvbFwiXVtcInRleHQtaGFsby13aWR0aFwiXSksXG4gICAgXCJ0ZXh0LWhhbG8tYmx1clwiOiBuZXcgRGF0YURyaXZlblByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X3N5bWJvbFwiXVtcInRleHQtaGFsby1ibHVyXCJdKSxcbiAgICBcInRleHQtdHJhbnNsYXRlXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9zeW1ib2xcIl1bXCJ0ZXh0LXRyYW5zbGF0ZVwiXSksXG4gICAgXCJ0ZXh0LXRyYW5zbGF0ZS1hbmNob3JcIjogbmV3IERhdGFDb25zdGFudFByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X3N5bWJvbFwiXVtcInRleHQtdHJhbnNsYXRlLWFuY2hvclwiXSksXG59KTtcblxuLy8gTm90ZTogd2l0aG91dCBhZGRpbmcgdGhlIGV4cGxpY2l0IHR5cGUgYW5ub3RhdGlvbiwgRmxvdyBpbmZlcnMgd2Vha2VyIHR5cGVzXG4vLyBmb3IgdGhlc2Ugb2JqZWN0cyBmcm9tIHRoZWlyIHVzZSBpbiB0aGUgY29uc3RydWN0b3IgdG8gU3R5bGVMYXllciwgYXNcbi8vIHtsYXlvdXQ/OiBQcm9wZXJ0aWVzPC4uLj4sIHBhaW50OiBQcm9wZXJ0aWVzPC4uLj59XG5leHBvcnQgZGVmYXVsdCAoeyBwYWludCwgbGF5b3V0IH06ICRFeGFjdDx7XG4gIHBhaW50OiBQcm9wZXJ0aWVzPFBhaW50UHJvcHM+LCBsYXlvdXQ6IFByb3BlcnRpZXM8TGF5b3V0UHJvcHM+XG59Pik7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgdHlwZSB7RXhwcmVzc2lvbn0gZnJvbSAnLi4vc3R5bGUtc3BlYy9leHByZXNzaW9uL2V4cHJlc3Npb24uanMnO1xuaW1wb3J0IHR5cGUgRXZhbHVhdGlvbkNvbnRleHQgZnJvbSAnLi4vc3R5bGUtc3BlYy9leHByZXNzaW9uL2V2YWx1YXRpb25fY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSB7VHlwZX0gZnJvbSAnLi4vc3R5bGUtc3BlYy9leHByZXNzaW9uL3R5cGVzLmpzJztcbmltcG9ydCB0eXBlIHtab29tQ29uc3RhbnRFeHByZXNzaW9ufSBmcm9tICcuLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vaW5kZXguanMnO1xuaW1wb3J0IHtOdWxsVHlwZX0gZnJvbSAnLi4vc3R5bGUtc3BlYy9leHByZXNzaW9uL3R5cGVzLmpzJztcbmltcG9ydCB7UG9zc2libHlFdmFsdWF0ZWRQcm9wZXJ0eVZhbHVlfSBmcm9tICcuL3Byb3BlcnRpZXMuanMnO1xuaW1wb3J0IHtyZWdpc3Rlcn0gZnJvbSAnLi4vdXRpbC93ZWJfd29ya2VyX3RyYW5zZmVyLmpzJztcblxuLy8gVGhpcyBpcyBhbiBpbnRlcm5hbCBleHByZXNzaW9uIGNsYXNzLiBJdCBpcyBvbmx5IHVzZWQgaW4gR0wgSlMgYW5kXG4vLyBoYXMgR0wgSlMgZGVwZW5kZW5jaWVzIHdoaWNoIGNhbiBicmVhayB0aGUgc3RhbmRhbG9uZSBzdHlsZS1zcGVjIG1vZHVsZVxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRm9ybWF0U2VjdGlvbk92ZXJyaWRlPFQ+IGltcGxlbWVudHMgRXhwcmVzc2lvbiB7XG4gICAgdHlwZTogVHlwZTtcbiAgICBkZWZhdWx0VmFsdWU6IFBvc3NpYmx5RXZhbHVhdGVkUHJvcGVydHlWYWx1ZTxUPjtcblxuICAgIGNvbnN0cnVjdG9yKGRlZmF1bHRWYWx1ZTogUG9zc2libHlFdmFsdWF0ZWRQcm9wZXJ0eVZhbHVlPFQ+KSB7XG4gICAgICAgIGFzc2VydChkZWZhdWx0VmFsdWUucHJvcGVydHkub3ZlcnJpZGVzICE9PSB1bmRlZmluZWQpO1xuICAgICAgICB0aGlzLnR5cGUgPSBkZWZhdWx0VmFsdWUucHJvcGVydHkub3ZlcnJpZGVzID8gZGVmYXVsdFZhbHVlLnByb3BlcnR5Lm92ZXJyaWRlcy5ydW50aW1lVHlwZSA6IE51bGxUeXBlO1xuICAgICAgICB0aGlzLmRlZmF1bHRWYWx1ZSA9IGRlZmF1bHRWYWx1ZTtcbiAgICB9XG5cbiAgICBldmFsdWF0ZShjdHg6IEV2YWx1YXRpb25Db250ZXh0KTogVCB7XG4gICAgICAgIGlmIChjdHguZm9ybWF0dGVkU2VjdGlvbikge1xuICAgICAgICAgICAgY29uc3Qgb3ZlcnJpZGVzID0gdGhpcy5kZWZhdWx0VmFsdWUucHJvcGVydHkub3ZlcnJpZGVzO1xuICAgICAgICAgICAgaWYgKG92ZXJyaWRlcyAmJiBvdmVycmlkZXMuaGFzT3ZlcnJpZGUoY3R4LmZvcm1hdHRlZFNlY3Rpb24pKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG92ZXJyaWRlcy5nZXRPdmVycmlkZShjdHguZm9ybWF0dGVkU2VjdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY3R4LmZlYXR1cmUgJiYgY3R4LmZlYXR1cmVTdGF0ZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVmYXVsdFZhbHVlLmV2YWx1YXRlKGN0eC5mZWF0dXJlLCBjdHguZmVhdHVyZVN0YXRlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIG5vdCBzdXJlIGhvdyB0byBtYWtlIEZsb3cgcmVmaW5lIHRoZSB0eXBlIHByb3Blcmx5IGhlcmUg4oCUIHdpbGwgbmVlZCBpbnZlc3RpZ2F0aW9uXG4gICAgICAgIHJldHVybiAoKHRoaXMuZGVmYXVsdFZhbHVlLnByb3BlcnR5LnNwZWNpZmljYXRpb24uZGVmYXVsdDogYW55KTogVCk7XG4gICAgfVxuXG4gICAgZWFjaENoaWxkKGZuOiAoXzogRXhwcmVzc2lvbikgPT4gdm9pZCkge1xuICAgICAgICBpZiAoIXRoaXMuZGVmYXVsdFZhbHVlLmlzQ29uc3RhbnQoKSkge1xuICAgICAgICAgICAgY29uc3QgZXhwcjogWm9vbUNvbnN0YW50RXhwcmVzc2lvbjwnc291cmNlJz4gPSAoKHRoaXMuZGVmYXVsdFZhbHVlLnZhbHVlKTogYW55KTtcbiAgICAgICAgICAgIGZuKGV4cHIuX3N0eWxlRXhwcmVzc2lvbi5leHByZXNzaW9uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIENhbm5vdCBiZSBzdGF0aWNhbGx5IGV2YWx1YXRlZCwgYXMgdGhlIG91dHB1dCBkZXBlbmRzIG9uIHRoZSBldmFsdWF0aW9uIGNvbnRleHQuXG4gICAgb3V0cHV0RGVmaW5lZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHNlcmlhbGl6ZSgpOiBudWxsIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxufVxuXG5yZWdpc3RlcihGb3JtYXRTZWN0aW9uT3ZlcnJpZGUsICdGb3JtYXRTZWN0aW9uT3ZlcnJpZGUnLCB7b21pdDogWydkZWZhdWx0VmFsdWUnXX0pO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IFN0eWxlTGF5ZXIgZnJvbSAnLi4vc3R5bGVfbGF5ZXIuanMnO1xuXG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgU3ltYm9sQnVja2V0IGZyb20gJy4uLy4uL2RhdGEvYnVja2V0L3N5bWJvbF9idWNrZXQuanMnO1xuaW1wb3J0IHJlc29sdmVUb2tlbnMgZnJvbSAnLi4vLi4vdXRpbC9yZXNvbHZlX3Rva2Vucy5qcyc7XG5pbXBvcnQgcHJvcGVydGllcyBmcm9tICcuL3N5bWJvbF9zdHlsZV9sYXllcl9wcm9wZXJ0aWVzLmpzJztcbmltcG9ydCB0eXBlIHtGb3JtYXR0ZWRTZWN0aW9ufSBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vdHlwZXMvZm9ybWF0dGVkLmpzJztcbmltcG9ydCB0eXBlIHtGb3JtYXR0ZWRTZWN0aW9uRXhwcmVzc2lvbn0gZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy9leHByZXNzaW9uL2RlZmluaXRpb25zL2Zvcm1hdC5qcyc7XG5cbmltcG9ydCB7XG4gICAgVHJhbnNpdGlvbmFibGUsXG4gICAgVHJhbnNpdGlvbmluZyxcbiAgICBMYXlvdXQsXG4gICAgUG9zc2libHlFdmFsdWF0ZWQsXG4gICAgUG9zc2libHlFdmFsdWF0ZWRQcm9wZXJ0eVZhbHVlLFxuICAgIFByb3BlcnR5VmFsdWVcbn0gZnJvbSAnLi4vcHJvcGVydGllcy5qcyc7XG5cbmltcG9ydCB7XG4gICAgaXNFeHByZXNzaW9uLFxuICAgIFN0eWxlRXhwcmVzc2lvbixcbiAgICBab29tQ29uc3RhbnRFeHByZXNzaW9uLFxuICAgIFpvb21EZXBlbmRlbnRFeHByZXNzaW9uXG59IGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi9pbmRleC5qcyc7XG5cbmltcG9ydCB0eXBlIHtCdWNrZXRQYXJhbWV0ZXJzfSBmcm9tICcuLi8uLi9kYXRhL2J1Y2tldC5qcyc7XG5pbXBvcnQgdHlwZSB7TGF5b3V0UHJvcHMsIFBhaW50UHJvcHN9IGZyb20gJy4vc3ltYm9sX3N0eWxlX2xheWVyX3Byb3BlcnRpZXMuanMnO1xuaW1wb3J0IHR5cGUgRXZhbHVhdGlvblBhcmFtZXRlcnMgZnJvbSAnLi4vZXZhbHVhdGlvbl9wYXJhbWV0ZXJzLmpzJztcbmltcG9ydCB0eXBlIHtMYXllclNwZWNpZmljYXRpb259IGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge0ZlYXR1cmUsIFNvdXJjZUV4cHJlc3Npb24sIENvbXBvc2l0ZUV4cHJlc3Npb259IGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi9pbmRleC5qcyc7XG5pbXBvcnQgdHlwZSB7RXhwcmVzc2lvbn0gZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy9leHByZXNzaW9uL2V4cHJlc3Npb24uanMnO1xuaW1wb3J0IHR5cGUge0Nhbm9uaWNhbFRpbGVJRH0gZnJvbSAnLi4vLi4vc291cmNlL3RpbGVfaWQuanMnO1xuaW1wb3J0IHtGb3JtYXR0ZWRUeXBlfSBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vdHlwZXMuanMnO1xuaW1wb3J0IHt0eXBlT2Z9IGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi92YWx1ZXMuanMnO1xuaW1wb3J0IEZvcm1hdHRlZCBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vdHlwZXMvZm9ybWF0dGVkLmpzJztcbmltcG9ydCBGb3JtYXRTZWN0aW9uT3ZlcnJpZGUgZnJvbSAnLi4vZm9ybWF0X3NlY3Rpb25fb3ZlcnJpZGUuanMnO1xuaW1wb3J0IEZvcm1hdEV4cHJlc3Npb24gZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy9leHByZXNzaW9uL2RlZmluaXRpb25zL2Zvcm1hdC5qcyc7XG5pbXBvcnQgTGl0ZXJhbCBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vZGVmaW5pdGlvbnMvbGl0ZXJhbC5qcyc7XG5pbXBvcnQgUHJvZ3JhbUNvbmZpZ3VyYXRpb24gZnJvbSAnLi4vLi4vZGF0YS9wcm9ncmFtX2NvbmZpZ3VyYXRpb24uanMnO1xuXG5jbGFzcyBTeW1ib2xTdHlsZUxheWVyIGV4dGVuZHMgU3R5bGVMYXllciB7XG4gICAgX3VuZXZhbHVhdGVkTGF5b3V0OiBMYXlvdXQ8TGF5b3V0UHJvcHM+O1xuICAgIGxheW91dDogUG9zc2libHlFdmFsdWF0ZWQ8TGF5b3V0UHJvcHM+O1xuXG4gICAgX3RyYW5zaXRpb25hYmxlUGFpbnQ6IFRyYW5zaXRpb25hYmxlPFBhaW50UHJvcHM+O1xuICAgIF90cmFuc2l0aW9uaW5nUGFpbnQ6IFRyYW5zaXRpb25pbmc8UGFpbnRQcm9wcz47XG4gICAgcGFpbnQ6IFBvc3NpYmx5RXZhbHVhdGVkPFBhaW50UHJvcHM+O1xuXG4gICAgY29uc3RydWN0b3IobGF5ZXI6IExheWVyU3BlY2lmaWNhdGlvbikge1xuICAgICAgICBzdXBlcihsYXllciwgcHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgcmVjYWxjdWxhdGUocGFyYW1ldGVyczogRXZhbHVhdGlvblBhcmFtZXRlcnMsIGF2YWlsYWJsZUltYWdlczogQXJyYXk8c3RyaW5nPikge1xuICAgICAgICBzdXBlci5yZWNhbGN1bGF0ZShwYXJhbWV0ZXJzLCBhdmFpbGFibGVJbWFnZXMpO1xuXG4gICAgICAgIGlmICh0aGlzLmxheW91dC5nZXQoJ2ljb24tcm90YXRpb24tYWxpZ25tZW50JykgPT09ICdhdXRvJykge1xuICAgICAgICAgICAgaWYgKHRoaXMubGF5b3V0LmdldCgnc3ltYm9sLXBsYWNlbWVudCcpICE9PSAncG9pbnQnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sYXlvdXQuX3ZhbHVlc1snaWNvbi1yb3RhdGlvbi1hbGlnbm1lbnQnXSA9ICdtYXAnO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxheW91dC5fdmFsdWVzWydpY29uLXJvdGF0aW9uLWFsaWdubWVudCddID0gJ3ZpZXdwb3J0JztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmxheW91dC5nZXQoJ3RleHQtcm90YXRpb24tYWxpZ25tZW50JykgPT09ICdhdXRvJykge1xuICAgICAgICAgICAgaWYgKHRoaXMubGF5b3V0LmdldCgnc3ltYm9sLXBsYWNlbWVudCcpICE9PSAncG9pbnQnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sYXlvdXQuX3ZhbHVlc1sndGV4dC1yb3RhdGlvbi1hbGlnbm1lbnQnXSA9ICdtYXAnO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxheW91dC5fdmFsdWVzWyd0ZXh0LXJvdGF0aW9uLWFsaWdubWVudCddID0gJ3ZpZXdwb3J0JztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIHVuc3BlY2lmaWVkLCBgKi1waXRjaC1hbGlnbm1lbnRgIGluaGVyaXRzIGAqLXJvdGF0aW9uLWFsaWdubWVudGBcbiAgICAgICAgaWYgKHRoaXMubGF5b3V0LmdldCgndGV4dC1waXRjaC1hbGlnbm1lbnQnKSA9PT0gJ2F1dG8nKSB7XG4gICAgICAgICAgICB0aGlzLmxheW91dC5fdmFsdWVzWyd0ZXh0LXBpdGNoLWFsaWdubWVudCddID0gdGhpcy5sYXlvdXQuZ2V0KCd0ZXh0LXJvdGF0aW9uLWFsaWdubWVudCcpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmxheW91dC5nZXQoJ2ljb24tcGl0Y2gtYWxpZ25tZW50JykgPT09ICdhdXRvJykge1xuICAgICAgICAgICAgdGhpcy5sYXlvdXQuX3ZhbHVlc1snaWNvbi1waXRjaC1hbGlnbm1lbnQnXSA9IHRoaXMubGF5b3V0LmdldCgnaWNvbi1yb3RhdGlvbi1hbGlnbm1lbnQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHdyaXRpbmdNb2RlcyA9IHRoaXMubGF5b3V0LmdldCgndGV4dC13cml0aW5nLW1vZGUnKTtcbiAgICAgICAgaWYgKHdyaXRpbmdNb2Rlcykge1xuICAgICAgICAgICAgLy8gcmVtb3ZlIGR1cGxpY2F0ZXMsIHByZXNlcnZpbmcgb3JkZXJcbiAgICAgICAgICAgIGNvbnN0IGRlZHVwZWQgPSBbXTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgbSBvZiB3cml0aW5nTW9kZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoZGVkdXBlZC5pbmRleE9mKG0pIDwgMCkgZGVkdXBlZC5wdXNoKG0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5sYXlvdXQuX3ZhbHVlc1sndGV4dC13cml0aW5nLW1vZGUnXSA9IGRlZHVwZWQ7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5sYXlvdXQuZ2V0KCdzeW1ib2wtcGxhY2VtZW50JykgPT09ICdwb2ludCcpIHtcbiAgICAgICAgICAgIC8vIGRlZmF1bHQgdmFsdWUgZm9yICdwb2ludCcgcGxhY2VtZW50IHN5bWJvbHNcbiAgICAgICAgICAgIHRoaXMubGF5b3V0Ll92YWx1ZXNbJ3RleHQtd3JpdGluZy1tb2RlJ10gPSBbJ2hvcml6b250YWwnXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIGRlZmF1bHQgdmFsdWUgZm9yICdsaW5lJyBwbGFjZW1lbnQgc3ltYm9sc1xuICAgICAgICAgICAgdGhpcy5sYXlvdXQuX3ZhbHVlc1sndGV4dC13cml0aW5nLW1vZGUnXSA9IFsnaG9yaXpvbnRhbCcsICd2ZXJ0aWNhbCddO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fc2V0UGFpbnRPdmVycmlkZXMoKTtcbiAgICB9XG5cbiAgICBnZXRWYWx1ZUFuZFJlc29sdmVUb2tlbnMobmFtZTogYW55LCBmZWF0dXJlOiBGZWF0dXJlLCBjYW5vbmljYWw6IENhbm9uaWNhbFRpbGVJRCwgYXZhaWxhYmxlSW1hZ2VzOiBBcnJheTxzdHJpbmc+KTogc3RyaW5nIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLmxheW91dC5nZXQobmFtZSkuZXZhbHVhdGUoZmVhdHVyZSwge30sIGNhbm9uaWNhbCwgYXZhaWxhYmxlSW1hZ2VzKTtcbiAgICAgICAgY29uc3QgdW5ldmFsdWF0ZWQgPSB0aGlzLl91bmV2YWx1YXRlZExheW91dC5fdmFsdWVzW25hbWVdO1xuICAgICAgICBpZiAoIXVuZXZhbHVhdGVkLmlzRGF0YURyaXZlbigpICYmICFpc0V4cHJlc3Npb24odW5ldmFsdWF0ZWQudmFsdWUpICYmIHZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzb2x2ZVRva2VucyhmZWF0dXJlLnByb3BlcnRpZXMsIHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICBjcmVhdGVCdWNrZXQocGFyYW1ldGVyczogQnVja2V0UGFyYW1ldGVyczxTeW1ib2xTdHlsZUxheWVyPik6IFN5bWJvbEJ1Y2tldCB7XG4gICAgICAgIHJldHVybiBuZXcgU3ltYm9sQnVja2V0KHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICBxdWVyeVJhZGl1cygpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgcXVlcnlJbnRlcnNlY3RzRmVhdHVyZSgpOiBib29sZWFuIHtcbiAgICAgICAgYXNzZXJ0KGZhbHNlKTsgLy8gU2hvdWxkIHRha2UgYSBkaWZmZXJlbnQgcGF0aCBpbiBGZWF0dXJlSW5kZXhcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIF9zZXRQYWludE92ZXJyaWRlcygpIHtcbiAgICAgICAgZm9yIChjb25zdCBvdmVycmlkYWJsZSBvZiBwcm9wZXJ0aWVzLnBhaW50Lm92ZXJyaWRhYmxlUHJvcGVydGllcykge1xuICAgICAgICAgICAgaWYgKCFTeW1ib2xTdHlsZUxheWVyLmhhc1BhaW50T3ZlcnJpZGUodGhpcy5sYXlvdXQsIG92ZXJyaWRhYmxlKSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qgb3ZlcnJpZGVuID0gdGhpcy5wYWludC5nZXQob3ZlcnJpZGFibGUpO1xuICAgICAgICAgICAgY29uc3Qgb3ZlcnJpZGUgPSBuZXcgRm9ybWF0U2VjdGlvbk92ZXJyaWRlKG92ZXJyaWRlbik7XG4gICAgICAgICAgICBjb25zdCBzdHlsZUV4cHJlc3Npb24gPSBuZXcgU3R5bGVFeHByZXNzaW9uKG92ZXJyaWRlLCBvdmVycmlkZW4ucHJvcGVydHkuc3BlY2lmaWNhdGlvbik7XG4gICAgICAgICAgICBsZXQgZXhwcmVzc2lvbiA9IG51bGw7XG4gICAgICAgICAgICBpZiAob3ZlcnJpZGVuLnZhbHVlLmtpbmQgPT09ICdjb25zdGFudCcgfHwgb3ZlcnJpZGVuLnZhbHVlLmtpbmQgPT09ICdzb3VyY2UnKSB7XG4gICAgICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgICAgIGV4cHJlc3Npb24gPSAobmV3IFpvb21Db25zdGFudEV4cHJlc3Npb24oJ3NvdXJjZScsIHN0eWxlRXhwcmVzc2lvbik6IFNvdXJjZUV4cHJlc3Npb24pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICAgICAgZXhwcmVzc2lvbiA9IChuZXcgWm9vbURlcGVuZGVudEV4cHJlc3Npb24oJ2NvbXBvc2l0ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGVFeHByZXNzaW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJyaWRlbi52YWx1ZS56b29tU3RvcHMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3ZlcnJpZGVuLnZhbHVlLl9pbnRlcnBvbGF0aW9uVHlwZSk6IENvbXBvc2l0ZUV4cHJlc3Npb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVtwcm9wLW1pc3NpbmddXG4gICAgICAgICAgICB0aGlzLnBhaW50Ll92YWx1ZXNbb3ZlcnJpZGFibGVdID0gbmV3IFBvc3NpYmx5RXZhbHVhdGVkUHJvcGVydHlWYWx1ZShvdmVycmlkZW4ucHJvcGVydHksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3ZlcnJpZGVuLnBhcmFtZXRlcnMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX2hhbmRsZU92ZXJyaWRhYmxlUGFpbnRQcm9wZXJ0eVVwZGF0ZTxULCBSPihuYW1lOiBzdHJpbmcsIG9sZFZhbHVlOiBQcm9wZXJ0eVZhbHVlPFQsIFI+LCBuZXdWYWx1ZTogUHJvcGVydHlWYWx1ZTxULCBSPik6IGJvb2xlYW4ge1xuICAgICAgICBpZiAoIXRoaXMubGF5b3V0IHx8IG9sZFZhbHVlLmlzRGF0YURyaXZlbigpIHx8IG5ld1ZhbHVlLmlzRGF0YURyaXZlbigpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFN5bWJvbFN0eWxlTGF5ZXIuaGFzUGFpbnRPdmVycmlkZSh0aGlzLmxheW91dCwgbmFtZSk7XG4gICAgfVxuXG4gICAgc3RhdGljIGhhc1BhaW50T3ZlcnJpZGUobGF5b3V0OiBQb3NzaWJseUV2YWx1YXRlZDxMYXlvdXRQcm9wcz4sIHByb3BlcnR5TmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IHRleHRGaWVsZCA9IGxheW91dC5nZXQoJ3RleHQtZmllbGQnKTtcbiAgICAgICAgY29uc3QgcHJvcGVydHkgPSBwcm9wZXJ0aWVzLnBhaW50LnByb3BlcnRpZXNbcHJvcGVydHlOYW1lXTtcbiAgICAgICAgbGV0IGhhc092ZXJyaWRlcyA9IGZhbHNlO1xuXG4gICAgICAgIGNvbnN0IGNoZWNrU2VjdGlvbnMgPSAoc2VjdGlvbnM6IEFycmF5PEZvcm1hdHRlZFNlY3Rpb24+IHwgQXJyYXk8Rm9ybWF0dGVkU2VjdGlvbkV4cHJlc3Npb24+KSA9PiB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHNlY3Rpb24gb2Ygc2VjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBpZiAocHJvcGVydHkub3ZlcnJpZGVzICYmIHByb3BlcnR5Lm92ZXJyaWRlcy5oYXNPdmVycmlkZShzZWN0aW9uKSkge1xuICAgICAgICAgICAgICAgICAgICBoYXNPdmVycmlkZXMgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIGlmICh0ZXh0RmllbGQudmFsdWUua2luZCA9PT0gJ2NvbnN0YW50JyAmJiB0ZXh0RmllbGQudmFsdWUudmFsdWUgaW5zdGFuY2VvZiBGb3JtYXR0ZWQpIHtcbiAgICAgICAgICAgIGNoZWNrU2VjdGlvbnModGV4dEZpZWxkLnZhbHVlLnZhbHVlLnNlY3Rpb25zKTtcbiAgICAgICAgfSBlbHNlIGlmICh0ZXh0RmllbGQudmFsdWUua2luZCA9PT0gJ3NvdXJjZScpIHtcblxuICAgICAgICAgICAgY29uc3QgY2hlY2tFeHByZXNzaW9uID0gKGV4cHJlc3Npb246IEV4cHJlc3Npb24pID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoaGFzT3ZlcnJpZGVzKSByZXR1cm47XG5cbiAgICAgICAgICAgICAgICBpZiAoZXhwcmVzc2lvbiBpbnN0YW5jZW9mIExpdGVyYWwgJiYgdHlwZU9mKGV4cHJlc3Npb24udmFsdWUpID09PSBGb3JtYXR0ZWRUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlZDogRm9ybWF0dGVkID0gKChleHByZXNzaW9uLnZhbHVlKTogYW55KTtcbiAgICAgICAgICAgICAgICAgICAgY2hlY2tTZWN0aW9ucyhmb3JtYXR0ZWQuc2VjdGlvbnMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZXhwcmVzc2lvbiBpbnN0YW5jZW9mIEZvcm1hdEV4cHJlc3Npb24pIHtcbiAgICAgICAgICAgICAgICAgICAgY2hlY2tTZWN0aW9ucyhleHByZXNzaW9uLnNlY3Rpb25zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uLmVhY2hDaGlsZChjaGVja0V4cHJlc3Npb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGV4cHI6IFpvb21Db25zdGFudEV4cHJlc3Npb248J3NvdXJjZSc+ID0gKCh0ZXh0RmllbGQudmFsdWUpOiBhbnkpO1xuICAgICAgICAgICAgaWYgKGV4cHIuX3N0eWxlRXhwcmVzc2lvbikge1xuICAgICAgICAgICAgICAgIGNoZWNrRXhwcmVzc2lvbihleHByLl9zdHlsZUV4cHJlc3Npb24uZXhwcmVzc2lvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gaGFzT3ZlcnJpZGVzO1xuICAgIH1cblxuICAgIGdldFByb2dyYW1Db25maWd1cmF0aW9uKHpvb206IG51bWJlcik6IFByb2dyYW1Db25maWd1cmF0aW9uIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9ncmFtQ29uZmlndXJhdGlvbih0aGlzLCB6b29tKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFN5bWJvbFN0eWxlTGF5ZXI7XG4iLCIvLyBUaGlzIGZpbGUgaXMgZ2VuZXJhdGVkLiBFZGl0IGJ1aWxkL2dlbmVyYXRlLXN0eWxlLWNvZGUuanMsIHRoZW4gcnVuIGB5YXJuIHJ1biBjb2RlZ2VuYC5cbi8vIEBmbG93XG4vKiBlc2xpbnQtZGlzYWJsZSAqL1xuXG5pbXBvcnQgc3R5bGVTcGVjIGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvcmVmZXJlbmNlL2xhdGVzdC5qcyc7XG5cbmltcG9ydCB7XG4gICAgUHJvcGVydGllcyxcbiAgICBEYXRhQ29uc3RhbnRQcm9wZXJ0eSxcbiAgICBEYXRhRHJpdmVuUHJvcGVydHksXG4gICAgQ29sb3JSYW1wUHJvcGVydHlcbn0gZnJvbSAnLi4vcHJvcGVydGllcy5qcyc7XG5cbmltcG9ydCB0eXBlIENvbG9yIGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvdXRpbC9jb2xvci5qcyc7XG5cbmltcG9ydCB0eXBlIEZvcm1hdHRlZCBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vdHlwZXMvZm9ybWF0dGVkLmpzJztcblxuaW1wb3J0IHR5cGUgUmVzb2x2ZWRJbWFnZSBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vdHlwZXMvcmVzb2x2ZWRfaW1hZ2UuanMnO1xuXG5cbmV4cG9ydCB0eXBlIFBhaW50UHJvcHMgPSB7fFxuICAgIFwiYmFja2dyb3VuZC1jb2xvclwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxDb2xvcj4sXG4gICAgXCJiYWNrZ3JvdW5kLXBhdHRlcm5cIjogRGF0YUNvbnN0YW50UHJvcGVydHk8P1Jlc29sdmVkSW1hZ2U+LFxuICAgIFwiYmFja2dyb3VuZC1vcGFjaXR5XCI6IERhdGFDb25zdGFudFByb3BlcnR5PG51bWJlcj4sXG58fTtcblxuY29uc3QgcGFpbnQ6IFByb3BlcnRpZXM8UGFpbnRQcm9wcz4gPSBuZXcgUHJvcGVydGllcyh7XG4gICAgXCJiYWNrZ3JvdW5kLWNvbG9yXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9iYWNrZ3JvdW5kXCJdW1wiYmFja2dyb3VuZC1jb2xvclwiXSksXG4gICAgXCJiYWNrZ3JvdW5kLXBhdHRlcm5cIjogbmV3IERhdGFDb25zdGFudFByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X2JhY2tncm91bmRcIl1bXCJiYWNrZ3JvdW5kLXBhdHRlcm5cIl0pLFxuICAgIFwiYmFja2dyb3VuZC1vcGFjaXR5XCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9iYWNrZ3JvdW5kXCJdW1wiYmFja2dyb3VuZC1vcGFjaXR5XCJdKSxcbn0pO1xuXG4vLyBOb3RlOiB3aXRob3V0IGFkZGluZyB0aGUgZXhwbGljaXQgdHlwZSBhbm5vdGF0aW9uLCBGbG93IGluZmVycyB3ZWFrZXIgdHlwZXNcbi8vIGZvciB0aGVzZSBvYmplY3RzIGZyb20gdGhlaXIgdXNlIGluIHRoZSBjb25zdHJ1Y3RvciB0byBTdHlsZUxheWVyLCBhc1xuLy8ge2xheW91dD86IFByb3BlcnRpZXM8Li4uPiwgcGFpbnQ6IFByb3BlcnRpZXM8Li4uPn1cbmV4cG9ydCBkZWZhdWx0ICh7IHBhaW50IH06ICRFeGFjdDx7XG4gIHBhaW50OiBQcm9wZXJ0aWVzPFBhaW50UHJvcHM+XG59Pik7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgU3R5bGVMYXllciBmcm9tICcuLi9zdHlsZV9sYXllci5qcyc7XG5cbmltcG9ydCBwcm9wZXJ0aWVzIGZyb20gJy4vYmFja2dyb3VuZF9zdHlsZV9sYXllcl9wcm9wZXJ0aWVzLmpzJztcbmltcG9ydCB7VHJhbnNpdGlvbmFibGUsIFRyYW5zaXRpb25pbmcsIFBvc3NpYmx5RXZhbHVhdGVkfSBmcm9tICcuLi9wcm9wZXJ0aWVzLmpzJztcblxuaW1wb3J0IHR5cGUge1BhaW50UHJvcHN9IGZyb20gJy4vYmFja2dyb3VuZF9zdHlsZV9sYXllcl9wcm9wZXJ0aWVzLmpzJztcbmltcG9ydCB0eXBlIHtMYXllclNwZWNpZmljYXRpb259IGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvdHlwZXMuanMnO1xuXG5jbGFzcyBCYWNrZ3JvdW5kU3R5bGVMYXllciBleHRlbmRzIFN0eWxlTGF5ZXIge1xuICAgIF90cmFuc2l0aW9uYWJsZVBhaW50OiBUcmFuc2l0aW9uYWJsZTxQYWludFByb3BzPjtcbiAgICBfdHJhbnNpdGlvbmluZ1BhaW50OiBUcmFuc2l0aW9uaW5nPFBhaW50UHJvcHM+O1xuICAgIHBhaW50OiBQb3NzaWJseUV2YWx1YXRlZDxQYWludFByb3BzPjtcblxuICAgIGNvbnN0cnVjdG9yKGxheWVyOiBMYXllclNwZWNpZmljYXRpb24pIHtcbiAgICAgICAgc3VwZXIobGF5ZXIsIHByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIGdldFByb2dyYW1JZHMoKTogQXJyYXk8c3RyaW5nPiB7XG4gICAgICAgIGNvbnN0IGltYWdlID0gdGhpcy5wYWludC5nZXQoJ2JhY2tncm91bmQtcGF0dGVybicpO1xuICAgICAgICByZXR1cm4gW2ltYWdlID8gJ2JhY2tncm91bmRQYXR0ZXJuJyA6ICdiYWNrZ3JvdW5kJ107XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBCYWNrZ3JvdW5kU3R5bGVMYXllcjtcbiIsIi8vIFRoaXMgZmlsZSBpcyBnZW5lcmF0ZWQuIEVkaXQgYnVpbGQvZ2VuZXJhdGUtc3R5bGUtY29kZS5qcywgdGhlbiBydW4gYHlhcm4gcnVuIGNvZGVnZW5gLlxuLy8gQGZsb3dcbi8qIGVzbGludC1kaXNhYmxlICovXG5cbmltcG9ydCBzdHlsZVNwZWMgZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy9yZWZlcmVuY2UvbGF0ZXN0LmpzJztcblxuaW1wb3J0IHtcbiAgICBQcm9wZXJ0aWVzLFxuICAgIERhdGFDb25zdGFudFByb3BlcnR5LFxuICAgIERhdGFEcml2ZW5Qcm9wZXJ0eSxcbiAgICBDb2xvclJhbXBQcm9wZXJ0eVxufSBmcm9tICcuLi9wcm9wZXJ0aWVzLmpzJztcblxuaW1wb3J0IHR5cGUgQ29sb3IgZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy91dGlsL2NvbG9yLmpzJztcblxuaW1wb3J0IHR5cGUgRm9ybWF0dGVkIGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi90eXBlcy9mb3JtYXR0ZWQuanMnO1xuXG5pbXBvcnQgdHlwZSBSZXNvbHZlZEltYWdlIGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi90eXBlcy9yZXNvbHZlZF9pbWFnZS5qcyc7XG5cblxuZXhwb3J0IHR5cGUgUGFpbnRQcm9wcyA9IHt8XG4gICAgXCJyYXN0ZXItb3BhY2l0eVwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxudW1iZXI+LFxuICAgIFwicmFzdGVyLWh1ZS1yb3RhdGVcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8bnVtYmVyPixcbiAgICBcInJhc3Rlci1icmlnaHRuZXNzLW1pblwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxudW1iZXI+LFxuICAgIFwicmFzdGVyLWJyaWdodG5lc3MtbWF4XCI6IERhdGFDb25zdGFudFByb3BlcnR5PG51bWJlcj4sXG4gICAgXCJyYXN0ZXItc2F0dXJhdGlvblwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxudW1iZXI+LFxuICAgIFwicmFzdGVyLWNvbnRyYXN0XCI6IERhdGFDb25zdGFudFByb3BlcnR5PG51bWJlcj4sXG4gICAgXCJyYXN0ZXItcmVzYW1wbGluZ1wiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxcImxpbmVhclwiIHwgXCJuZWFyZXN0XCI+LFxuICAgIFwicmFzdGVyLWZhZGUtZHVyYXRpb25cIjogRGF0YUNvbnN0YW50UHJvcGVydHk8bnVtYmVyPixcbnx9O1xuXG5jb25zdCBwYWludDogUHJvcGVydGllczxQYWludFByb3BzPiA9IG5ldyBQcm9wZXJ0aWVzKHtcbiAgICBcInJhc3Rlci1vcGFjaXR5XCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9yYXN0ZXJcIl1bXCJyYXN0ZXItb3BhY2l0eVwiXSksXG4gICAgXCJyYXN0ZXItaHVlLXJvdGF0ZVwiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjW1wicGFpbnRfcmFzdGVyXCJdW1wicmFzdGVyLWh1ZS1yb3RhdGVcIl0pLFxuICAgIFwicmFzdGVyLWJyaWdodG5lc3MtbWluXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9yYXN0ZXJcIl1bXCJyYXN0ZXItYnJpZ2h0bmVzcy1taW5cIl0pLFxuICAgIFwicmFzdGVyLWJyaWdodG5lc3MtbWF4XCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9yYXN0ZXJcIl1bXCJyYXN0ZXItYnJpZ2h0bmVzcy1tYXhcIl0pLFxuICAgIFwicmFzdGVyLXNhdHVyYXRpb25cIjogbmV3IERhdGFDb25zdGFudFByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X3Jhc3RlclwiXVtcInJhc3Rlci1zYXR1cmF0aW9uXCJdKSxcbiAgICBcInJhc3Rlci1jb250cmFzdFwiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjW1wicGFpbnRfcmFzdGVyXCJdW1wicmFzdGVyLWNvbnRyYXN0XCJdKSxcbiAgICBcInJhc3Rlci1yZXNhbXBsaW5nXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9yYXN0ZXJcIl1bXCJyYXN0ZXItcmVzYW1wbGluZ1wiXSksXG4gICAgXCJyYXN0ZXItZmFkZS1kdXJhdGlvblwiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjW1wicGFpbnRfcmFzdGVyXCJdW1wicmFzdGVyLWZhZGUtZHVyYXRpb25cIl0pLFxufSk7XG5cbi8vIE5vdGU6IHdpdGhvdXQgYWRkaW5nIHRoZSBleHBsaWNpdCB0eXBlIGFubm90YXRpb24sIEZsb3cgaW5mZXJzIHdlYWtlciB0eXBlc1xuLy8gZm9yIHRoZXNlIG9iamVjdHMgZnJvbSB0aGVpciB1c2UgaW4gdGhlIGNvbnN0cnVjdG9yIHRvIFN0eWxlTGF5ZXIsIGFzXG4vLyB7bGF5b3V0PzogUHJvcGVydGllczwuLi4+LCBwYWludDogUHJvcGVydGllczwuLi4+fVxuZXhwb3J0IGRlZmF1bHQgKHsgcGFpbnQgfTogJEV4YWN0PHtcbiAgcGFpbnQ6IFByb3BlcnRpZXM8UGFpbnRQcm9wcz5cbn0+KTtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCBTdHlsZUxheWVyIGZyb20gJy4uL3N0eWxlX2xheWVyLmpzJztcblxuaW1wb3J0IHByb3BlcnRpZXMgZnJvbSAnLi9yYXN0ZXJfc3R5bGVfbGF5ZXJfcHJvcGVydGllcy5qcyc7XG5pbXBvcnQge1RyYW5zaXRpb25hYmxlLCBUcmFuc2l0aW9uaW5nLCBQb3NzaWJseUV2YWx1YXRlZH0gZnJvbSAnLi4vcHJvcGVydGllcy5qcyc7XG5cbmltcG9ydCB0eXBlIHtQYWludFByb3BzfSBmcm9tICcuL3Jhc3Rlcl9zdHlsZV9sYXllcl9wcm9wZXJ0aWVzLmpzJztcbmltcG9ydCB0eXBlIHtMYXllclNwZWNpZmljYXRpb259IGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvdHlwZXMuanMnO1xuXG5jbGFzcyBSYXN0ZXJTdHlsZUxheWVyIGV4dGVuZHMgU3R5bGVMYXllciB7XG4gICAgX3RyYW5zaXRpb25hYmxlUGFpbnQ6IFRyYW5zaXRpb25hYmxlPFBhaW50UHJvcHM+O1xuICAgIF90cmFuc2l0aW9uaW5nUGFpbnQ6IFRyYW5zaXRpb25pbmc8UGFpbnRQcm9wcz47XG4gICAgcGFpbnQ6IFBvc3NpYmx5RXZhbHVhdGVkPFBhaW50UHJvcHM+O1xuXG4gICAgY29uc3RydWN0b3IobGF5ZXI6IExheWVyU3BlY2lmaWNhdGlvbikge1xuICAgICAgICBzdXBlcihsYXllciwgcHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgZ2V0UHJvZ3JhbUlkcygpOiBBcnJheTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIFsncmFzdGVyJ107XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBSYXN0ZXJTdHlsZUxheWVyO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IFN0eWxlTGF5ZXIgZnJvbSAnLi4vc3R5bGVfbGF5ZXIuanMnO1xuaW1wb3J0IE1lcmNhdG9yQ29vcmRpbmF0ZSBmcm9tICcuLi8uLi9nZW8vbWVyY2F0b3JfY29vcmRpbmF0ZS5qcyc7XG5pbXBvcnQgdHlwZSBNYXAgZnJvbSAnLi4vLi4vdWkvbWFwLmpzJztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCB0eXBlIHtWYWxpZGF0aW9uRXJyb3JzfSBmcm9tICcuLi92YWxpZGF0ZV9zdHlsZS5qcyc7XG5pbXBvcnQgdHlwZSB7UHJvamVjdGlvblNwZWNpZmljYXRpb259IGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvdHlwZXMuanMnO1xuXG50eXBlIEN1c3RvbVJlbmRlck1ldGhvZCA9IChnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0LCBtYXRyaXg6IEFycmF5PG51bWJlcj4sIHByb2plY3Rpb246ID9Qcm9qZWN0aW9uU3BlY2lmaWNhdGlvbiwgcHJvamVjdGlvblRvTWVyY2F0b3JNYXRyaXg6ID9BcnJheTxudW1iZXI+LCBwcm9qZWN0aW9uVG9NZXJjYXRvclRyYW5zaXRpb246ID9udW1iZXIsIGNlbnRlckluTWVyY2F0b3I6ID9BcnJheTxudW1iZXI+LCBwaXhlbHNQZXJNZXRlclJhdGlvOiA/bnVtYmVyKSA9PiB2b2lkO1xuXG4vKipcbiAqIEludGVyZmFjZSBmb3IgY3VzdG9tIHN0eWxlIGxheWVycy4gVGhpcyBpcyBhIHNwZWNpZmljYXRpb24gZm9yXG4gKiBpbXBsZW1lbnRlcnMgdG8gbW9kZWw6IGl0IGlzIG5vdCBhbiBleHBvcnRlZCBtZXRob2Qgb3IgY2xhc3MuXG4gKlxuICogQ3VzdG9tIGxheWVycyBhbGxvdyBhIHVzZXIgdG8gcmVuZGVyIGRpcmVjdGx5IGludG8gdGhlIG1hcCdzIEdMIGNvbnRleHQgdXNpbmcgdGhlIG1hcCdzIGNhbWVyYS5cbiAqIFRoZXNlIGxheWVycyBjYW4gYmUgYWRkZWQgYmV0d2VlbiBhbnkgcmVndWxhciBsYXllcnMgdXNpbmcge0BsaW5rIE1hcCNhZGRMYXllcn0uXG4gKlxuICogQ3VzdG9tIGxheWVycyBtdXN0IGhhdmUgYSB1bmlxdWUgYGlkYCBhbmQgbXVzdCBoYXZlIHRoZSBgdHlwZWAgb2YgYFwiY3VzdG9tXCJgLlxuICogVGhleSBtdXN0IGltcGxlbWVudCBgcmVuZGVyYCBhbmQgbWF5IGltcGxlbWVudCBgcHJlcmVuZGVyYCwgYG9uQWRkYCBhbmQgYG9uUmVtb3ZlYC5cbiAqIFRoZXkgY2FuIHRyaWdnZXIgcmVuZGVyaW5nIHVzaW5nIHtAbGluayBNYXAjdHJpZ2dlclJlcGFpbnR9XG4gKiBhbmQgdGhleSBzaG91bGQgYXBwcm9wcmlhdGVseSBoYW5kbGUge0BsaW5rIE1hcC5ldmVudDp3ZWJnbGNvbnRleHRsb3N0fSBhbmRcbiAqIHtAbGluayBNYXAuZXZlbnQ6d2ViZ2xjb250ZXh0cmVzdG9yZWR9LlxuICpcbiAqIFRoZSBgcmVuZGVyaW5nTW9kZWAgcHJvcGVydHkgY29udHJvbHMgd2hldGhlciB0aGUgbGF5ZXIgaXMgdHJlYXRlZCBhcyBhIGBcIjJkXCJgIG9yIGBcIjNkXCJgIG1hcCBsYXllci4gVXNlOlxuICogLSBgXCJyZW5kZXJpbmdNb2RlXCI6IFwiM2RcImAgdG8gdXNlIHRoZSBkZXB0aCBidWZmZXIgYW5kIHNoYXJlIGl0IHdpdGggb3RoZXIgbGF5ZXJzXG4gKiAtIGBcInJlbmRlcmluZ01vZGVcIjogXCIyZFwiYCB0byBhZGQgYSBsYXllciB3aXRoIG5vIGRlcHRoLiBJZiB5b3UgbmVlZCB0byB1c2UgdGhlIGRlcHRoIGJ1ZmZlciBmb3IgYSBgXCIyZFwiYCBsYXllciB5b3UgbXVzdCB1c2UgYW4gb2Zmc2NyZWVuXG4gKiAgIGZyYW1lYnVmZmVyIGFuZCB7QGxpbmsgQ3VzdG9tTGF5ZXJJbnRlcmZhY2UjcHJlcmVuZGVyfS5cbiAqXG4gKiBAaW50ZXJmYWNlIEN1c3RvbUxheWVySW50ZXJmYWNlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gaWQgQSB1bmlxdWUgbGF5ZXIgaWQuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gdHlwZSBUaGUgbGF5ZXIncyB0eXBlLiBNdXN0IGJlIGBcImN1c3RvbVwiYC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSByZW5kZXJpbmdNb2RlIEVpdGhlciBgXCIyZFwiYCBvciBgXCIzZFwiYC4gRGVmYXVsdHMgdG8gYFwiMmRcImAuXG4gKiBAZXhhbXBsZVxuICogLy8gQ3VzdG9tIGxheWVyIGltcGxlbWVudGVkIGFzIEVTNiBjbGFzc1xuICogY2xhc3MgTnVsbElzbGFuZExheWVyIHtcbiAqICAgICBjb25zdHJ1Y3RvcigpIHtcbiAqICAgICAgICAgdGhpcy5pZCA9ICdudWxsLWlzbGFuZCc7XG4gKiAgICAgICAgIHRoaXMudHlwZSA9ICdjdXN0b20nO1xuICogICAgICAgICB0aGlzLnJlbmRlcmluZ01vZGUgPSAnMmQnO1xuICogICAgIH1cbiAqXG4gKiAgICAgb25BZGQobWFwLCBnbCkge1xuICogICAgICAgICBjb25zdCB2ZXJ0ZXhTb3VyY2UgPSBgXG4gKiAgICAgICAgIHVuaWZvcm0gbWF0NCB1X21hdHJpeDtcbiAqICAgICAgICAgdm9pZCBtYWluKCkge1xuICogICAgICAgICAgICAgZ2xfUG9zaXRpb24gPSB1X21hdHJpeCAqIHZlYzQoMC41LCAwLjUsIDAuMCwgMS4wKTtcbiAqICAgICAgICAgICAgIGdsX1BvaW50U2l6ZSA9IDIwLjA7XG4gKiAgICAgICAgIH1gO1xuICpcbiAqICAgICAgICAgY29uc3QgZnJhZ21lbnRTb3VyY2UgPSBgXG4gKiAgICAgICAgIHZvaWQgbWFpbigpIHtcbiAqICAgICAgICAgICAgIGdsX0ZyYWdDb2xvciA9IHZlYzQoMS4wLCAwLjAsIDAuMCwgMS4wKTtcbiAqICAgICAgICAgfWA7XG4gKlxuICogICAgICAgICBjb25zdCB2ZXJ0ZXhTaGFkZXIgPSBnbC5jcmVhdGVTaGFkZXIoZ2wuVkVSVEVYX1NIQURFUik7XG4gKiAgICAgICAgIGdsLnNoYWRlclNvdXJjZSh2ZXJ0ZXhTaGFkZXIsIHZlcnRleFNvdXJjZSk7XG4gKiAgICAgICAgIGdsLmNvbXBpbGVTaGFkZXIodmVydGV4U2hhZGVyKTtcbiAqICAgICAgICAgY29uc3QgZnJhZ21lbnRTaGFkZXIgPSBnbC5jcmVhdGVTaGFkZXIoZ2wuRlJBR01FTlRfU0hBREVSKTtcbiAqICAgICAgICAgZ2wuc2hhZGVyU291cmNlKGZyYWdtZW50U2hhZGVyLCBmcmFnbWVudFNvdXJjZSk7XG4gKiAgICAgICAgIGdsLmNvbXBpbGVTaGFkZXIoZnJhZ21lbnRTaGFkZXIpO1xuICpcbiAqICAgICAgICAgdGhpcy5wcm9ncmFtID0gZ2wuY3JlYXRlUHJvZ3JhbSgpO1xuICogICAgICAgICBnbC5hdHRhY2hTaGFkZXIodGhpcy5wcm9ncmFtLCB2ZXJ0ZXhTaGFkZXIpO1xuICogICAgICAgICBnbC5hdHRhY2hTaGFkZXIodGhpcy5wcm9ncmFtLCBmcmFnbWVudFNoYWRlcik7XG4gKiAgICAgICAgIGdsLmxpbmtQcm9ncmFtKHRoaXMucHJvZ3JhbSk7XG4gKiAgICAgfVxuICpcbiAqICAgICByZW5kZXIoZ2wsIG1hdHJpeCkge1xuICogICAgICAgICBnbC51c2VQcm9ncmFtKHRoaXMucHJvZ3JhbSk7XG4gKiAgICAgICAgIGdsLnVuaWZvcm1NYXRyaXg0ZnYoZ2wuZ2V0VW5pZm9ybUxvY2F0aW9uKHRoaXMucHJvZ3JhbSwgXCJ1X21hdHJpeFwiKSwgZmFsc2UsIG1hdHJpeCk7XG4gKiAgICAgICAgIGdsLmRyYXdBcnJheXMoZ2wuUE9JTlRTLCAwLCAxKTtcbiAqICAgICB9XG4gKiB9XG4gKlxuICogbWFwLm9uKCdsb2FkJywgKCkgPT4ge1xuICogICAgIG1hcC5hZGRMYXllcihuZXcgTnVsbElzbGFuZExheWVyKCkpO1xuICogfSk7XG4gKiBAc2VlIFtFeGFtcGxlOiBBZGQgYSBjdXN0b20gc3R5bGUgbGF5ZXJdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2N1c3RvbS1zdHlsZS1sYXllci8pXG4gKiBAc2VlIFtFeGFtcGxlOiBBZGQgYSAzRCBtb2RlbF0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvYWRkLTNkLW1vZGVsLylcbiAqL1xuXG4vKipcbiAqIE9wdGlvbmFsIG1ldGhvZCBjYWxsZWQgd2hlbiB0aGUgbGF5ZXIgaGFzIGJlZW4gYWRkZWQgdG8gdGhlIE1hcCB3aXRoIHtAbGluayBNYXAjYWRkTGF5ZXJ9LiBUaGlzXG4gKiBnaXZlcyB0aGUgbGF5ZXIgYSBjaGFuY2UgdG8gaW5pdGlhbGl6ZSBnbCByZXNvdXJjZXMgYW5kIHJlZ2lzdGVyIGV2ZW50IGxpc3RlbmVycy5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBtZW1iZXJvZiBDdXN0b21MYXllckludGVyZmFjZVxuICogQGluc3RhbmNlXG4gKiBAbmFtZSBvbkFkZFxuICogQHBhcmFtIHtNYXB9IG1hcCBUaGUgTWFwIHRoaXMgY3VzdG9tIGxheWVyIHdhcyBqdXN0IGFkZGVkIHRvLlxuICogQHBhcmFtIHtXZWJHTFJlbmRlcmluZ0NvbnRleHR9IGdsIFRoZSBnbCBjb250ZXh0IGZvciB0aGUgbWFwLlxuICovXG5cbi8qKlxuICogT3B0aW9uYWwgbWV0aG9kIGNhbGxlZCB3aGVuIHRoZSBsYXllciBoYXMgYmVlbiByZW1vdmVkIGZyb20gdGhlIE1hcCB3aXRoIHtAbGluayBNYXAjcmVtb3ZlTGF5ZXJ9LiBUaGlzXG4gKiBnaXZlcyB0aGUgbGF5ZXIgYSBjaGFuY2UgdG8gY2xlYW4gdXAgZ2wgcmVzb3VyY2VzIGFuZCBldmVudCBsaXN0ZW5lcnMuXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAbWVtYmVyb2YgQ3VzdG9tTGF5ZXJJbnRlcmZhY2VcbiAqIEBpbnN0YW5jZVxuICogQG5hbWUgb25SZW1vdmVcbiAqIEBwYXJhbSB7TWFwfSBtYXAgVGhlIE1hcCB0aGlzIGN1c3RvbSBsYXllciB3YXMganVzdCBhZGRlZCB0by5cbiAqIEBwYXJhbSB7V2ViR0xSZW5kZXJpbmdDb250ZXh0fSBnbCBUaGUgZ2wgY29udGV4dCBmb3IgdGhlIG1hcC5cbiAqL1xuXG4vKipcbiAqIE9wdGlvbmFsIG1ldGhvZCBjYWxsZWQgZHVyaW5nIGEgcmVuZGVyIGZyYW1lIHRvIGFsbG93IGEgbGF5ZXIgdG8gcHJlcGFyZSByZXNvdXJjZXMgb3IgcmVuZGVyIGludG8gYSB0ZXh0dXJlLlxuICpcbiAqIFRoZSBsYXllciBjYW5ub3QgbWFrZSBhbnkgYXNzdW1wdGlvbnMgYWJvdXQgdGhlIGN1cnJlbnQgR0wgc3RhdGUgYW5kIG11c3QgYmluZCBhIGZyYW1lYnVmZmVyIGJlZm9yZSByZW5kZXJpbmcuXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAbWVtYmVyb2YgQ3VzdG9tTGF5ZXJJbnRlcmZhY2VcbiAqIEBpbnN0YW5jZVxuICogQG5hbWUgcHJlcmVuZGVyXG4gKiBAcGFyYW0ge1dlYkdMUmVuZGVyaW5nQ29udGV4dH0gZ2wgVGhlIG1hcCdzIGdsIGNvbnRleHQuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IG1hdHJpeCBUaGUgbWFwJ3MgY2FtZXJhIG1hdHJpeC4gSXQgcHJvamVjdHMgc3BoZXJpY2FsIG1lcmNhdG9yXG4gKiBjb29yZGluYXRlcyB0byBnbCBjb29yZGluYXRlcy4gVGhlIG1lcmNhdG9yIGNvb3JkaW5hdGUgYFswLCAwXWAgcmVwcmVzZW50cyB0aGVcbiAqIHRvcCBsZWZ0IGNvcm5lciBvZiB0aGUgbWVyY2F0b3Igd29ybGQgYW5kIGBbMSwgMV1gIHJlcHJlc2VudHMgdGhlIGJvdHRvbSByaWdodCBjb3JuZXIuIFdoZW5cbiAqIHRoZSBgcmVuZGVyaW5nTW9kZWAgaXMgYFwiM2RcImAsIHRoZSB6IGNvb3JkaW5hdGUgaXMgY29uZm9ybWFsLiBBIGJveCB3aXRoIGlkZW50aWNhbCB4LCB5LCBhbmQgelxuICogbGVuZ3RocyBpbiBtZXJjYXRvciB1bml0cyB3b3VsZCBiZSByZW5kZXJlZCBhcyBhIGN1YmUuIHtAbGluayBNZXJjYXRvckNvb3JkaW5hdGV9LmZyb21MbmdMYXRcbiAqIGNhbiBiZSB1c2VkIHRvIHByb2plY3QgYSBgTG5nTGF0YCB0byBhIG1lcmNhdG9yIGNvb3JkaW5hdGUuXG4gKi9cblxuLyoqXG4gKiBDYWxsZWQgZHVyaW5nIGEgcmVuZGVyIGZyYW1lIGFsbG93aW5nIHRoZSBsYXllciB0byBkcmF3IGludG8gdGhlIEdMIGNvbnRleHQuXG4gKlxuICogVGhlIGxheWVyIGNhbiBhc3N1bWUgYmxlbmRpbmcgYW5kIGRlcHRoIHN0YXRlIGlzIHNldCB0byBhbGxvdyB0aGUgbGF5ZXIgdG8gcHJvcGVybHlcbiAqIGJsZW5kIGFuZCBjbGlwIG90aGVyIGxheWVycy4gVGhlIGxheWVyIGNhbm5vdCBtYWtlIGFueSBvdGhlciBhc3N1bXB0aW9ucyBhYm91dCB0aGVcbiAqIGN1cnJlbnQgR0wgc3RhdGUuXG4gKlxuICogSWYgdGhlIGxheWVyIG5lZWRzIHRvIHJlbmRlciB0byBhIHRleHR1cmUsIGl0IHNob3VsZCBpbXBsZW1lbnQgdGhlIGBwcmVyZW5kZXJgIG1ldGhvZFxuICogdG8gZG8gdGhpcyBhbmQgb25seSB1c2UgdGhlIGByZW5kZXJgIG1ldGhvZCBmb3IgZHJhd2luZyBkaXJlY3RseSBpbnRvIHRoZSBtYWluIGZyYW1lYnVmZmVyLlxuICpcbiAqIFRoZSBibGVuZCBmdW5jdGlvbiBpcyBzZXQgdG8gYGdsLmJsZW5kRnVuYyhnbC5PTkUsIGdsLk9ORV9NSU5VU19TUkNfQUxQSEEpYC4gVGhpcyBleHBlY3RzXG4gKiBjb2xvcnMgdG8gYmUgcHJvdmlkZWQgaW4gcHJlbXVsdGlwbGllZCBhbHBoYSBmb3JtIHdoZXJlIHRoZSBgcmAsIGBnYCBhbmQgYGJgIHZhbHVlcyBhcmUgYWxyZWFkeVxuICogbXVsdGlwbGllZCBieSB0aGUgYGFgIHZhbHVlLiBJZiB5b3UgYXJlIHVuYWJsZSB0byBwcm92aWRlIGNvbG9ycyBpbiBwcmVtdWx0aXBsaWVkIGZvcm0geW91XG4gKiBtYXkgd2FudCB0byBjaGFuZ2UgdGhlIGJsZW5kIGZ1bmN0aW9uIHRvXG4gKiBgZ2wuYmxlbmRGdW5jU2VwYXJhdGUoZ2wuU1JDX0FMUEhBLCBnbC5PTkVfTUlOVVNfU1JDX0FMUEhBLCBnbC5PTkUsIGdsLk9ORV9NSU5VU19TUkNfQUxQSEEpYC5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBtZW1iZXJvZiBDdXN0b21MYXllckludGVyZmFjZVxuICogQGluc3RhbmNlXG4gKiBAbmFtZSByZW5kZXJcbiAqIEBwYXJhbSB7V2ViR0xSZW5kZXJpbmdDb250ZXh0fSBnbCBUaGUgbWFwJ3MgZ2wgY29udGV4dC5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gbWF0cml4IFRoZSBtYXAncyBjYW1lcmEgbWF0cml4LiBJdCBwcm9qZWN0cyBzcGhlcmljYWwgbWVyY2F0b3JcbiAqIGNvb3JkaW5hdGVzIHRvIGdsIGNvb3JkaW5hdGVzLiBUaGUgc3BoZXJpY2FsIG1lcmNhdG9yIGNvb3JkaW5hdGUgYFswLCAwXWAgcmVwcmVzZW50cyB0aGVcbiAqIHRvcCBsZWZ0IGNvcm5lciBvZiB0aGUgbWVyY2F0b3Igd29ybGQgYW5kIGBbMSwgMV1gIHJlcHJlc2VudHMgdGhlIGJvdHRvbSByaWdodCBjb3JuZXIuIFdoZW5cbiAqIHRoZSBgcmVuZGVyaW5nTW9kZWAgaXMgYFwiM2RcImAsIHRoZSB6IGNvb3JkaW5hdGUgaXMgY29uZm9ybWFsLiBBIGJveCB3aXRoIGlkZW50aWNhbCB4LCB5LCBhbmQgelxuICogbGVuZ3RocyBpbiBtZXJjYXRvciB1bml0cyB3b3VsZCBiZSByZW5kZXJlZCBhcyBhIGN1YmUuIHtAbGluayBNZXJjYXRvckNvb3JkaW5hdGV9LmZyb21MbmdMYXRcbiAqIGNhbiBiZSB1c2VkIHRvIHByb2plY3QgYSBgTG5nTGF0YCB0byBhIG1lcmNhdG9yIGNvb3JkaW5hdGUuXG4gKi9cbmV4cG9ydCB0eXBlIEN1c3RvbUxheWVySW50ZXJmYWNlID0ge1xuICAgIGlkOiBzdHJpbmcsXG4gICAgdHlwZTogXCJjdXN0b21cIixcbiAgICByZW5kZXJpbmdNb2RlOiBcIjJkXCIgfCBcIjNkXCIsXG4gICAgcmVuZGVyOiBDdXN0b21SZW5kZXJNZXRob2QsXG4gICAgcHJlcmVuZGVyOiA/Q3VzdG9tUmVuZGVyTWV0aG9kLFxuICAgIHJlbmRlclRvVGlsZTogPyhnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0LCB0aWxlSWQ6IE1lcmNhdG9yQ29vcmRpbmF0ZSkgPT4gdm9pZCxcbiAgICBzaG91bGRSZXJlbmRlclRpbGVzOiA/KCkgPT4gYm9vbGVhbixcbiAgICBvbkFkZDogPyhtYXA6IE1hcCwgZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCkgPT4gdm9pZCxcbiAgICBvblJlbW92ZTogPyhtYXA6IE1hcCwgZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCkgPT4gdm9pZFxufVxuXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVDdXN0b21TdHlsZUxheWVyKGxheWVyT2JqZWN0OiBDdXN0b21MYXllckludGVyZmFjZSk6IFZhbGlkYXRpb25FcnJvcnMge1xuICAgIGNvbnN0IGVycm9ycyA9IFtdO1xuICAgIGNvbnN0IGlkID0gbGF5ZXJPYmplY3QuaWQ7XG5cbiAgICBpZiAoaWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBlcnJvcnMucHVzaCh7XG4gICAgICAgICAgICBtZXNzYWdlOiBgbGF5ZXJzLiR7aWR9OiBtaXNzaW5nIHJlcXVpcmVkIHByb3BlcnR5IFwiaWRcImBcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKGxheWVyT2JqZWN0LnJlbmRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKHtcbiAgICAgICAgICAgIG1lc3NhZ2U6IGBsYXllcnMuJHtpZH06IG1pc3NpbmcgcmVxdWlyZWQgbWV0aG9kIFwicmVuZGVyXCJgXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChsYXllck9iamVjdC5yZW5kZXJpbmdNb2RlICYmXG4gICAgICAgIGxheWVyT2JqZWN0LnJlbmRlcmluZ01vZGUgIT09ICcyZCcgJiZcbiAgICAgICAgbGF5ZXJPYmplY3QucmVuZGVyaW5nTW9kZSAhPT0gJzNkJykge1xuICAgICAgICBlcnJvcnMucHVzaCh7XG4gICAgICAgICAgICBtZXNzYWdlOiBgbGF5ZXJzLiR7aWR9OiBwcm9wZXJ0eSBcInJlbmRlcmluZ01vZGVcIiBtdXN0IGJlIGVpdGhlciBcIjJkXCIgb3IgXCIzZFwiYFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZXJyb3JzO1xufVxuXG5jbGFzcyBDdXN0b21TdHlsZUxheWVyIGV4dGVuZHMgU3R5bGVMYXllciB7XG5cbiAgICBpbXBsZW1lbnRhdGlvbjogQ3VzdG9tTGF5ZXJJbnRlcmZhY2U7XG5cbiAgICBjb25zdHJ1Y3RvcihpbXBsZW1lbnRhdGlvbjogQ3VzdG9tTGF5ZXJJbnRlcmZhY2UpIHtcbiAgICAgICAgc3VwZXIoaW1wbGVtZW50YXRpb24sIHt9KTtcbiAgICAgICAgdGhpcy5pbXBsZW1lbnRhdGlvbiA9IGltcGxlbWVudGF0aW9uO1xuICAgIH1cblxuICAgIGlzM0QoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmltcGxlbWVudGF0aW9uLnJlbmRlcmluZ01vZGUgPT09ICczZCc7XG4gICAgfVxuXG4gICAgaGFzT2Zmc2NyZWVuUGFzcygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW1wbGVtZW50YXRpb24ucHJlcmVuZGVyICE9PSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgaXNMYXllckRyYXBlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW1wbGVtZW50YXRpb24ucmVuZGVyVG9UaWxlICE9PSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVkcmFwZSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5pbXBsZW1lbnRhdGlvbi5zaG91bGRSZXJlbmRlclRpbGVzICYmIHRoaXMuaW1wbGVtZW50YXRpb24uc2hvdWxkUmVyZW5kZXJUaWxlcygpO1xuICAgIH1cblxuICAgIHJlY2FsY3VsYXRlKCkge31cbiAgICB1cGRhdGVUcmFuc2l0aW9ucygpIHt9XG4gICAgaGFzVHJhbnNpdGlvbigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vICRGbG93Rml4TWVbaW5jb21wYXRpYmxlLWV4dGVuZF0gLSBDdXN0b21TdHlsZUxheWVyIGlzIG5vdCBzZXJpYWxpemFibGVcbiAgICBzZXJpYWxpemUoKSB7XG4gICAgICAgIGFzc2VydChmYWxzZSwgXCJDdXN0b20gbGF5ZXJzIGNhbm5vdCBiZSBzZXJpYWxpemVkXCIpO1xuICAgIH1cblxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICBvbkFkZChtYXA6IE1hcCkge1xuICAgICAgICBpZiAodGhpcy5pbXBsZW1lbnRhdGlvbi5vbkFkZCkge1xuICAgICAgICAgICAgdGhpcy5pbXBsZW1lbnRhdGlvbi5vbkFkZChtYXAsIG1hcC5wYWludGVyLmNvbnRleHQuZ2wpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIG9uUmVtb3ZlKG1hcDogTWFwKSB7XG4gICAgICAgIGlmICh0aGlzLmltcGxlbWVudGF0aW9uLm9uUmVtb3ZlKSB7XG4gICAgICAgICAgICB0aGlzLmltcGxlbWVudGF0aW9uLm9uUmVtb3ZlKG1hcCwgbWFwLnBhaW50ZXIuY29udGV4dC5nbCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEN1c3RvbVN0eWxlTGF5ZXI7XG4iLCIvLyBUaGlzIGZpbGUgaXMgZ2VuZXJhdGVkLiBFZGl0IGJ1aWxkL2dlbmVyYXRlLXN0eWxlLWNvZGUuanMsIHRoZW4gcnVuIGB5YXJuIHJ1biBjb2RlZ2VuYC5cbi8vIEBmbG93XG4vKiBlc2xpbnQtZGlzYWJsZSAqL1xuXG5pbXBvcnQgc3R5bGVTcGVjIGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvcmVmZXJlbmNlL2xhdGVzdC5qcyc7XG5cbmltcG9ydCB7XG4gICAgUHJvcGVydGllcyxcbiAgICBEYXRhQ29uc3RhbnRQcm9wZXJ0eSxcbiAgICBEYXRhRHJpdmVuUHJvcGVydHksXG4gICAgQ29sb3JSYW1wUHJvcGVydHlcbn0gZnJvbSAnLi4vcHJvcGVydGllcy5qcyc7XG5cbmltcG9ydCB0eXBlIENvbG9yIGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvdXRpbC9jb2xvci5qcyc7XG5cbmltcG9ydCB0eXBlIEZvcm1hdHRlZCBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vdHlwZXMvZm9ybWF0dGVkLmpzJztcblxuaW1wb3J0IHR5cGUgUmVzb2x2ZWRJbWFnZSBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vdHlwZXMvcmVzb2x2ZWRfaW1hZ2UuanMnO1xuXG5cbmV4cG9ydCB0eXBlIFBhaW50UHJvcHMgPSB7fFxuICAgIFwic2t5LXR5cGVcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8XCJncmFkaWVudFwiIHwgXCJhdG1vc3BoZXJlXCI+LFxuICAgIFwic2t5LWF0bW9zcGhlcmUtc3VuXCI6IERhdGFDb25zdGFudFByb3BlcnR5PFtudW1iZXIsIG51bWJlcl0+LFxuICAgIFwic2t5LWF0bW9zcGhlcmUtc3VuLWludGVuc2l0eVwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxudW1iZXI+LFxuICAgIFwic2t5LWdyYWRpZW50LWNlbnRlclwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxbbnVtYmVyLCBudW1iZXJdPixcbiAgICBcInNreS1ncmFkaWVudC1yYWRpdXNcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8bnVtYmVyPixcbiAgICBcInNreS1ncmFkaWVudFwiOiBDb2xvclJhbXBQcm9wZXJ0eSxcbiAgICBcInNreS1hdG1vc3BoZXJlLWhhbG8tY29sb3JcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8Q29sb3I+LFxuICAgIFwic2t5LWF0bW9zcGhlcmUtY29sb3JcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8Q29sb3I+LFxuICAgIFwic2t5LW9wYWNpdHlcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8bnVtYmVyPixcbnx9O1xuXG5jb25zdCBwYWludDogUHJvcGVydGllczxQYWludFByb3BzPiA9IG5ldyBQcm9wZXJ0aWVzKHtcbiAgICBcInNreS10eXBlXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9za3lcIl1bXCJza3ktdHlwZVwiXSksXG4gICAgXCJza3ktYXRtb3NwaGVyZS1zdW5cIjogbmV3IERhdGFDb25zdGFudFByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X3NreVwiXVtcInNreS1hdG1vc3BoZXJlLXN1blwiXSksXG4gICAgXCJza3ktYXRtb3NwaGVyZS1zdW4taW50ZW5zaXR5XCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9za3lcIl1bXCJza3ktYXRtb3NwaGVyZS1zdW4taW50ZW5zaXR5XCJdKSxcbiAgICBcInNreS1ncmFkaWVudC1jZW50ZXJcIjogbmV3IERhdGFDb25zdGFudFByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X3NreVwiXVtcInNreS1ncmFkaWVudC1jZW50ZXJcIl0pLFxuICAgIFwic2t5LWdyYWRpZW50LXJhZGl1c1wiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjW1wicGFpbnRfc2t5XCJdW1wic2t5LWdyYWRpZW50LXJhZGl1c1wiXSksXG4gICAgXCJza3ktZ3JhZGllbnRcIjogbmV3IENvbG9yUmFtcFByb3BlcnR5KHN0eWxlU3BlY1tcInBhaW50X3NreVwiXVtcInNreS1ncmFkaWVudFwiXSksXG4gICAgXCJza3ktYXRtb3NwaGVyZS1oYWxvLWNvbG9yXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9za3lcIl1bXCJza3ktYXRtb3NwaGVyZS1oYWxvLWNvbG9yXCJdKSxcbiAgICBcInNreS1hdG1vc3BoZXJlLWNvbG9yXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWNbXCJwYWludF9za3lcIl1bXCJza3ktYXRtb3NwaGVyZS1jb2xvclwiXSksXG4gICAgXCJza3ktb3BhY2l0eVwiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjW1wicGFpbnRfc2t5XCJdW1wic2t5LW9wYWNpdHlcIl0pLFxufSk7XG5cbi8vIE5vdGU6IHdpdGhvdXQgYWRkaW5nIHRoZSBleHBsaWNpdCB0eXBlIGFubm90YXRpb24sIEZsb3cgaW5mZXJzIHdlYWtlciB0eXBlc1xuLy8gZm9yIHRoZXNlIG9iamVjdHMgZnJvbSB0aGVpciB1c2UgaW4gdGhlIGNvbnN0cnVjdG9yIHRvIFN0eWxlTGF5ZXIsIGFzXG4vLyB7bGF5b3V0PzogUHJvcGVydGllczwuLi4+LCBwYWludDogUHJvcGVydGllczwuLi4+fVxuZXhwb3J0IGRlZmF1bHQgKHsgcGFpbnQgfTogJEV4YWN0PHtcbiAgcGFpbnQ6IFByb3BlcnRpZXM8UGFpbnRQcm9wcz5cbn0+KTtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCBTdHlsZUxheWVyIGZyb20gJy4uL3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCBwcm9wZXJ0aWVzIGZyb20gJy4vc2t5X3N0eWxlX2xheWVyX3Byb3BlcnRpZXMuanMnO1xuaW1wb3J0IHtUcmFuc2l0aW9uYWJsZSwgVHJhbnNpdGlvbmluZywgUG9zc2libHlFdmFsdWF0ZWR9IGZyb20gJy4uL3Byb3BlcnRpZXMuanMnO1xuaW1wb3J0IHtyZW5kZXJDb2xvclJhbXB9IGZyb20gJy4uLy4uL3V0aWwvY29sb3JfcmFtcC5qcyc7XG5pbXBvcnQgdHlwZSB7UGFpbnRQcm9wc30gZnJvbSAnLi9za3lfc3R5bGVfbGF5ZXJfcHJvcGVydGllcy5qcyc7XG5pbXBvcnQgdHlwZSBUZXh0dXJlIGZyb20gJy4uLy4uL3JlbmRlci90ZXh0dXJlLmpzJztcbmltcG9ydCB0eXBlIFBhaW50ZXIgZnJvbSAnLi4vLi4vcmVuZGVyL3BhaW50ZXIuanMnO1xuaW1wb3J0IHR5cGUge0xheWVyU3BlY2lmaWNhdGlvbn0gZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy90eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSBGcmFtZWJ1ZmZlciBmcm9tICcuLi8uLi9nbC9mcmFtZWJ1ZmZlci5qcyc7XG5pbXBvcnQgdHlwZSB7UkdCQUltYWdlfSBmcm9tICcuLi8uLi91dGlsL2ltYWdlLmpzJztcbmltcG9ydCB0eXBlIFNreWJveEdlb21ldHJ5IGZyb20gJy4uLy4uL3JlbmRlci9za3lib3hfZ2VvbWV0cnkuanMnO1xuaW1wb3J0IHR5cGUge0xpZ2h0UG9zaXRpb259IGZyb20gJy4uL2xpZ2h0LmpzJztcbmltcG9ydCB7d2Fybk9uY2UsIGRlZ1RvUmFkfSBmcm9tICcuLi8uLi91dGlsL3V0aWwuanMnO1xuaW1wb3J0IHt2ZWMzLCBxdWF0fSBmcm9tICdnbC1tYXRyaXgnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuXG5mdW5jdGlvbiBnZXRDZWxlc3RpYWxEaXJlY3Rpb24oYXppbXV0aDogbnVtYmVyLCBhbHRpdHVkZTogbnVtYmVyLCBsZWZ0SGFuZGVkOiBib29sZWFuKSB7XG4gICAgY29uc3QgdXAgPSBbMCwgMCwgMV07XG4gICAgY29uc3Qgcm90YXRpb24gPSBxdWF0LmlkZW50aXR5KFtdKTtcblxuICAgIHF1YXQucm90YXRlWShyb3RhdGlvbiwgcm90YXRpb24sIGxlZnRIYW5kZWQgPyAtZGVnVG9SYWQoYXppbXV0aCkgKyBNYXRoLlBJIDogZGVnVG9SYWQoYXppbXV0aCkpO1xuICAgIHF1YXQucm90YXRlWChyb3RhdGlvbiwgcm90YXRpb24sIC1kZWdUb1JhZChhbHRpdHVkZSkpO1xuICAgIHZlYzMudHJhbnNmb3JtUXVhdCh1cCwgdXAsIHJvdGF0aW9uKTtcblxuICAgIHJldHVybiB2ZWMzLm5vcm1hbGl6ZSh1cCwgdXApO1xufVxuXG5jbGFzcyBTa3lMYXllciBleHRlbmRzIFN0eWxlTGF5ZXIge1xuICAgIF90cmFuc2l0aW9uYWJsZVBhaW50OiBUcmFuc2l0aW9uYWJsZTxQYWludFByb3BzPjtcbiAgICBfdHJhbnNpdGlvbmluZ1BhaW50OiBUcmFuc2l0aW9uaW5nPFBhaW50UHJvcHM+O1xuICAgIHBhaW50OiBQb3NzaWJseUV2YWx1YXRlZDxQYWludFByb3BzPjtcbiAgICBfbGlnaHRQb3NpdGlvbjogTGlnaHRQb3NpdGlvbjtcblxuICAgIHNreWJveEZibzogP0ZyYW1lYnVmZmVyO1xuICAgIHNreWJveFRleHR1cmU6ID9XZWJHTFRleHR1cmU7XG4gICAgX3NreWJveEludmFsaWRhdGVkOiA/Ym9vbGVhbjtcblxuICAgIGNvbG9yUmFtcDogUkdCQUltYWdlO1xuICAgIGNvbG9yUmFtcFRleHR1cmU6ID9UZXh0dXJlO1xuXG4gICAgc2t5Ym94R2VvbWV0cnk6IFNreWJveEdlb21ldHJ5O1xuXG4gICAgY29uc3RydWN0b3IobGF5ZXI6IExheWVyU3BlY2lmaWNhdGlvbikge1xuICAgICAgICBzdXBlcihsYXllciwgcHJvcGVydGllcyk7XG4gICAgICAgIHRoaXMuX3VwZGF0ZUNvbG9yUmFtcCgpO1xuICAgIH1cblxuICAgIF9oYW5kbGVTcGVjaWFsUGFpbnRQcm9wZXJ0eVVwZGF0ZShuYW1lOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKG5hbWUgPT09ICdza3ktZ3JhZGllbnQnKSB7XG4gICAgICAgICAgICB0aGlzLl91cGRhdGVDb2xvclJhbXAoKTtcbiAgICAgICAgfSBlbHNlIGlmIChuYW1lID09PSAnc2t5LWF0bW9zcGhlcmUtc3VuJyB8fFxuICAgICAgICAgICAgICAgICAgIG5hbWUgPT09ICdza3ktYXRtb3NwaGVyZS1oYWxvLWNvbG9yJyB8fFxuICAgICAgICAgICAgICAgICAgIG5hbWUgPT09ICdza3ktYXRtb3NwaGVyZS1jb2xvcicgfHxcbiAgICAgICAgICAgICAgICAgICBuYW1lID09PSAnc2t5LWF0bW9zcGhlcmUtc3VuLWludGVuc2l0eScpIHtcbiAgICAgICAgICAgIHRoaXMuX3NreWJveEludmFsaWRhdGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF91cGRhdGVDb2xvclJhbXAoKSB7XG4gICAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSB0aGlzLl90cmFuc2l0aW9uYWJsZVBhaW50Ll92YWx1ZXNbJ3NreS1ncmFkaWVudCddLnZhbHVlLmV4cHJlc3Npb247XG4gICAgICAgIHRoaXMuY29sb3JSYW1wID0gcmVuZGVyQ29sb3JSYW1wKHtcbiAgICAgICAgICAgIGV4cHJlc3Npb24sXG4gICAgICAgICAgICBldmFsdWF0aW9uS2V5OiAnc2t5UmFkaWFsUHJvZ3Jlc3MnXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodGhpcy5jb2xvclJhbXBUZXh0dXJlKSB7XG4gICAgICAgICAgICB0aGlzLmNvbG9yUmFtcFRleHR1cmUuZGVzdHJveSgpO1xuICAgICAgICAgICAgdGhpcy5jb2xvclJhbXBUZXh0dXJlID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5lZWRzU2t5Ym94Q2FwdHVyZShwYWludGVyOiBQYWludGVyKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICghIXRoaXMuX3NreWJveEludmFsaWRhdGVkIHx8ICF0aGlzLnNreWJveFRleHR1cmUgfHwgIXRoaXMuc2t5Ym94R2VvbWV0cnkpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5wYWludC5nZXQoJ3NreS1hdG1vc3BoZXJlLXN1bicpKSB7XG4gICAgICAgICAgICBjb25zdCBsaWdodFBvc2l0aW9uID0gcGFpbnRlci5zdHlsZS5saWdodC5wcm9wZXJ0aWVzLmdldCgncG9zaXRpb24nKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9saWdodFBvc2l0aW9uLmF6aW11dGhhbCAhPT0gbGlnaHRQb3NpdGlvbi5hemltdXRoYWwgfHxcbiAgICAgICAgICAgICAgICAgICB0aGlzLl9saWdodFBvc2l0aW9uLnBvbGFyICE9PSBsaWdodFBvc2l0aW9uLnBvbGFyO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBnZXRDZW50ZXIocGFpbnRlcjogUGFpbnRlciwgbGVmdEhhbmRlZDogYm9vbGVhbik6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSB7XG4gICAgICAgIGNvbnN0IHR5cGUgPSB0aGlzLnBhaW50LmdldCgnc2t5LXR5cGUnKTtcbiAgICAgICAgaWYgKHR5cGUgPT09ICdhdG1vc3BoZXJlJykge1xuICAgICAgICAgICAgY29uc3Qgc3VuUG9zaXRpb24gPSB0aGlzLnBhaW50LmdldCgnc2t5LWF0bW9zcGhlcmUtc3VuJyk7XG4gICAgICAgICAgICBjb25zdCB1c2VMaWdodFBvc2l0aW9uID0gIXN1blBvc2l0aW9uO1xuICAgICAgICAgICAgY29uc3QgbGlnaHQgPSBwYWludGVyLnN0eWxlLmxpZ2h0O1xuICAgICAgICAgICAgY29uc3QgbGlnaHRQb3NpdGlvbiA9IGxpZ2h0LnByb3BlcnRpZXMuZ2V0KCdwb3NpdGlvbicpO1xuXG4gICAgICAgICAgICBpZiAodXNlTGlnaHRQb3NpdGlvbiAmJiBsaWdodC5wcm9wZXJ0aWVzLmdldCgnYW5jaG9yJykgPT09ICd2aWV3cG9ydCcpIHtcbiAgICAgICAgICAgICAgICB3YXJuT25jZSgnVGhlIHN1biBkaXJlY3Rpb24gaXMgYXR0YWNoZWQgdG8gYSBsaWdodCB3aXRoIHZpZXdwb3J0IGFuY2hvciwgbGlnaHRpbmcgbWF5IGJlaGF2ZSB1bmV4cGVjdGVkbHkuJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB1c2VMaWdodFBvc2l0aW9uID9cbiAgICAgICAgICAgICAgICBnZXRDZWxlc3RpYWxEaXJlY3Rpb24obGlnaHRQb3NpdGlvbi5hemltdXRoYWwsIC1saWdodFBvc2l0aW9uLnBvbGFyICsgOTAsIGxlZnRIYW5kZWQpIDpcbiAgICAgICAgICAgICAgICBnZXRDZWxlc3RpYWxEaXJlY3Rpb24oc3VuUG9zaXRpb25bMF0sIC1zdW5Qb3NpdGlvblsxXSArIDkwLCBsZWZ0SGFuZGVkKTtcbiAgICAgICAgfVxuICAgICAgICBhc3NlcnQodHlwZSA9PT0gJ2dyYWRpZW50Jyk7XG4gICAgICAgIGNvbnN0IGRpcmVjdGlvbiA9IHRoaXMucGFpbnQuZ2V0KCdza3ktZ3JhZGllbnQtY2VudGVyJyk7XG4gICAgICAgIHJldHVybiBnZXRDZWxlc3RpYWxEaXJlY3Rpb24oZGlyZWN0aW9uWzBdLCAtZGlyZWN0aW9uWzFdICsgOTAsIGxlZnRIYW5kZWQpO1xuICAgIH1cblxuICAgIGlzM0QoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpc1NreSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgbWFya1NreWJveFZhbGlkKHBhaW50ZXI6IFBhaW50ZXIpIHtcbiAgICAgICAgdGhpcy5fc2t5Ym94SW52YWxpZGF0ZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fbGlnaHRQb3NpdGlvbiA9IHBhaW50ZXIuc3R5bGUubGlnaHQucHJvcGVydGllcy5nZXQoJ3Bvc2l0aW9uJyk7XG4gICAgfVxuXG4gICAgaGFzT2Zmc2NyZWVuUGFzcygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgZ2V0UHJvZ3JhbUlkcygpOiBzdHJpbmdbXSB8IG51bGwge1xuICAgICAgICBjb25zdCB0eXBlID0gdGhpcy5wYWludC5nZXQoJ3NreS10eXBlJyk7XG4gICAgICAgIGlmICh0eXBlID09PSAnYXRtb3NwaGVyZScpIHtcbiAgICAgICAgICAgIHJldHVybiBbJ3NreWJveENhcHR1cmUnLCAnc2t5Ym94J107XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2dyYWRpZW50Jykge1xuICAgICAgICAgICAgcmV0dXJuIFsnc2t5Ym94R3JhZGllbnQnXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFNreUxheWVyO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHR5cGUgU3R5bGVMYXllciBmcm9tICcuL3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCBjaXJjbGUgZnJvbSAnLi9zdHlsZV9sYXllci9jaXJjbGVfc3R5bGVfbGF5ZXIuanMnO1xuaW1wb3J0IGhlYXRtYXAgZnJvbSAnLi9zdHlsZV9sYXllci9oZWF0bWFwX3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCBoaWxsc2hhZGUgZnJvbSAnLi9zdHlsZV9sYXllci9oaWxsc2hhZGVfc3R5bGVfbGF5ZXIuanMnO1xuaW1wb3J0IGZpbGwgZnJvbSAnLi9zdHlsZV9sYXllci9maWxsX3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCBmaWxsRXh0cnVzaW9uIGZyb20gJy4vc3R5bGVfbGF5ZXIvZmlsbF9leHRydXNpb25fc3R5bGVfbGF5ZXIuanMnO1xuaW1wb3J0IGxpbmUgZnJvbSAnLi9zdHlsZV9sYXllci9saW5lX3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCBzeW1ib2wgZnJvbSAnLi9zdHlsZV9sYXllci9zeW1ib2xfc3R5bGVfbGF5ZXIuanMnO1xuaW1wb3J0IGJhY2tncm91bmQgZnJvbSAnLi9zdHlsZV9sYXllci9iYWNrZ3JvdW5kX3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCByYXN0ZXIgZnJvbSAnLi9zdHlsZV9sYXllci9yYXN0ZXJfc3R5bGVfbGF5ZXIuanMnO1xuaW1wb3J0IEN1c3RvbVN0eWxlTGF5ZXIgZnJvbSAnLi9zdHlsZV9sYXllci9jdXN0b21fc3R5bGVfbGF5ZXIuanMnO1xuaW1wb3J0IHNreSBmcm9tICcuL3N0eWxlX2xheWVyL3NreV9zdHlsZV9sYXllci5qcyc7XG5pbXBvcnQgdHlwZSB7Q3VzdG9tTGF5ZXJJbnRlcmZhY2V9IGZyb20gJy4vc3R5bGVfbGF5ZXIvY3VzdG9tX3N0eWxlX2xheWVyLmpzJztcblxuaW1wb3J0IHR5cGUge0xheWVyU3BlY2lmaWNhdGlvbn0gZnJvbSAnLi4vc3R5bGUtc3BlYy90eXBlcy5qcyc7XG5cbmNvbnN0IHN1YmNsYXNzZXMgPSB7XG4gICAgY2lyY2xlLFxuICAgIGhlYXRtYXAsXG4gICAgaGlsbHNoYWRlLFxuICAgIGZpbGwsXG4gICAgJ2ZpbGwtZXh0cnVzaW9uJzogZmlsbEV4dHJ1c2lvbixcbiAgICBsaW5lLFxuICAgIHN5bWJvbCxcbiAgICBiYWNrZ3JvdW5kLFxuICAgIHJhc3RlcixcbiAgICBza3lcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGNyZWF0ZVN0eWxlTGF5ZXIobGF5ZXI6IExheWVyU3BlY2lmaWNhdGlvbiB8IEN1c3RvbUxheWVySW50ZXJmYWNlKTogU3R5bGVMYXllciB8IEN1c3RvbVN0eWxlTGF5ZXIge1xuICAgIGlmIChsYXllci50eXBlID09PSAnY3VzdG9tJykge1xuICAgICAgICByZXR1cm4gbmV3IEN1c3RvbVN0eWxlTGF5ZXIobGF5ZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBuZXcgc3ViY2xhc3Nlc1tsYXllci50eXBlXShsYXllcik7XG4gICAgfVxufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHdpbmRvdyBmcm9tICcuLi91dGlsL3dpbmRvdy5qcyc7XG5cbmltcG9ydCB0eXBlIENvbnRleHQgZnJvbSAnLi4vZ2wvY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSB7UkdCQUltYWdlLCBBbHBoYUltYWdlfSBmcm9tICcuLi91dGlsL2ltYWdlLmpzJztcblxuZXhwb3J0IHR5cGUgVGV4dHVyZUZvcm1hdCA9XG4gICAgfCAkUHJvcGVydHlUeXBlPFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgJ1JHQkEnPlxuICAgIHwgJFByb3BlcnR5VHlwZTxXZWJHTFJlbmRlcmluZ0NvbnRleHQsICdBTFBIQSc+O1xuZXhwb3J0IHR5cGUgVGV4dHVyZUZpbHRlciA9XG4gICAgfCAkUHJvcGVydHlUeXBlPFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgJ0xJTkVBUic+XG4gICAgfCAkUHJvcGVydHlUeXBlPFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgJ0xJTkVBUl9NSVBNQVBfTkVBUkVTVCc+XG4gICAgfCAkUHJvcGVydHlUeXBlPFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgJ05FQVJFU1QnPjtcbmV4cG9ydCB0eXBlIFRleHR1cmVXcmFwID1cbiAgICB8ICRQcm9wZXJ0eVR5cGU8V2ViR0xSZW5kZXJpbmdDb250ZXh0LCAnUkVQRUFUJz5cbiAgICB8ICRQcm9wZXJ0eVR5cGU8V2ViR0xSZW5kZXJpbmdDb250ZXh0LCAnQ0xBTVBfVE9fRURHRSc+XG4gICAgfCAkUHJvcGVydHlUeXBlPFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgJ01JUlJPUkVEX1JFUEVBVCc+O1xuXG50eXBlIEVtcHR5SW1hZ2UgPSB7XG4gICAgd2lkdGg6IG51bWJlcixcbiAgICBoZWlnaHQ6IG51bWJlcixcbiAgICBkYXRhOiBudWxsXG59XG5cbmV4cG9ydCB0eXBlIFRleHR1cmVJbWFnZSA9XG4gICAgfCBSR0JBSW1hZ2VcbiAgICB8IEFscGhhSW1hZ2VcbiAgICB8IEhUTUxJbWFnZUVsZW1lbnRcbiAgICB8IEhUTUxDYW52YXNFbGVtZW50XG4gICAgfCBIVE1MVmlkZW9FbGVtZW50XG4gICAgfCBJbWFnZURhdGFcbiAgICB8IEVtcHR5SW1hZ2VcbiAgICB8IEltYWdlQml0bWFwO1xuXG5jbGFzcyBUZXh0dXJlIHtcbiAgICBjb250ZXh0OiBDb250ZXh0O1xuICAgIHNpemU6IFtudW1iZXIsIG51bWJlcl07XG4gICAgdGV4dHVyZTogV2ViR0xUZXh0dXJlO1xuICAgIGZvcm1hdDogVGV4dHVyZUZvcm1hdDtcbiAgICBmaWx0ZXI6ID9UZXh0dXJlRmlsdGVyO1xuICAgIHdyYXA6ID9UZXh0dXJlV3JhcDtcbiAgICB1c2VNaXBtYXA6IGJvb2xlYW47XG5cbiAgICBjb25zdHJ1Y3Rvcihjb250ZXh0OiBDb250ZXh0LCBpbWFnZTogVGV4dHVyZUltYWdlLCBmb3JtYXQ6IFRleHR1cmVGb3JtYXQsIG9wdGlvbnM6ID97IHByZW11bHRpcGx5PzogYm9vbGVhbiwgdXNlTWlwbWFwPzogYm9vbGVhbiB9KSB7XG4gICAgICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gICAgICAgIHRoaXMuZm9ybWF0ID0gZm9ybWF0O1xuICAgICAgICB0aGlzLnRleHR1cmUgPSAoKGNvbnRleHQuZ2wuY3JlYXRlVGV4dHVyZSgpOiBhbnkpOiBXZWJHTFRleHR1cmUpO1xuICAgICAgICB0aGlzLnVwZGF0ZShpbWFnZSwgb3B0aW9ucyk7XG4gICAgfVxuXG4gICAgdXBkYXRlKGltYWdlOiBUZXh0dXJlSW1hZ2UsIG9wdGlvbnM6ID97cHJlbXVsdGlwbHk/OiBib29sZWFuLCB1c2VNaXBtYXA/OiBib29sZWFufSwgcG9zaXRpb24/OiB7IHg6IG51bWJlciwgeTogbnVtYmVyIH0pIHtcbiAgICAgICAgY29uc3Qge3dpZHRoLCBoZWlnaHR9ID0gaW1hZ2U7XG4gICAgICAgIGNvbnN0IHtjb250ZXh0fSA9IHRoaXM7XG4gICAgICAgIGNvbnN0IHtnbH0gPSBjb250ZXh0O1xuICAgICAgICBjb25zdCB7SFRNTEltYWdlRWxlbWVudCwgSFRNTENhbnZhc0VsZW1lbnQsIEhUTUxWaWRlb0VsZW1lbnQsIEltYWdlRGF0YSwgSW1hZ2VCaXRtYXB9ID0gd2luZG93O1xuXG4gICAgICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIHRoaXMudGV4dHVyZSk7XG5cbiAgICAgICAgY29udGV4dC5waXhlbFN0b3JlVW5wYWNrRmxpcFkuc2V0KGZhbHNlKTtcbiAgICAgICAgY29udGV4dC5waXhlbFN0b3JlVW5wYWNrLnNldCgxKTtcbiAgICAgICAgY29udGV4dC5waXhlbFN0b3JlVW5wYWNrUHJlbXVsdGlwbHlBbHBoYS5zZXQodGhpcy5mb3JtYXQgPT09IGdsLlJHQkEgJiYgKCFvcHRpb25zIHx8IG9wdGlvbnMucHJlbXVsdGlwbHkgIT09IGZhbHNlKSk7XG5cbiAgICAgICAgaWYgKCFwb3NpdGlvbiAmJiAoIXRoaXMuc2l6ZSB8fCB0aGlzLnNpemVbMF0gIT09IHdpZHRoIHx8IHRoaXMuc2l6ZVsxXSAhPT0gaGVpZ2h0KSkge1xuICAgICAgICAgICAgdGhpcy5zaXplID0gW3dpZHRoLCBoZWlnaHRdO1xuXG4gICAgICAgICAgICBpZiAoaW1hZ2UgaW5zdGFuY2VvZiBIVE1MSW1hZ2VFbGVtZW50IHx8IGltYWdlIGluc3RhbmNlb2YgSFRNTENhbnZhc0VsZW1lbnQgfHwgaW1hZ2UgaW5zdGFuY2VvZiBIVE1MVmlkZW9FbGVtZW50IHx8IGltYWdlIGluc3RhbmNlb2YgSW1hZ2VEYXRhIHx8IChJbWFnZUJpdG1hcCAmJiBpbWFnZSBpbnN0YW5jZW9mIEltYWdlQml0bWFwKSkge1xuICAgICAgICAgICAgICAgIGdsLnRleEltYWdlMkQoZ2wuVEVYVFVSRV8yRCwgMCwgdGhpcy5mb3JtYXQsIHRoaXMuZm9ybWF0LCBnbC5VTlNJR05FRF9CWVRFLCBpbWFnZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vICRGbG93Rml4TWUgcHJvcC1taXNzaW5nIC0gRmxvdyBjYW4ndCByZWZpbmUgaW1hZ2UgdHlwZSBoZXJlXG4gICAgICAgICAgICAgICAgZ2wudGV4SW1hZ2UyRChnbC5URVhUVVJFXzJELCAwLCB0aGlzLmZvcm1hdCwgd2lkdGgsIGhlaWdodCwgMCwgdGhpcy5mb3JtYXQsIGdsLlVOU0lHTkVEX0JZVEUsIGltYWdlLmRhdGEpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCB7eCwgeX0gPSBwb3NpdGlvbiB8fCB7eDogMCwgeTogMH07XG4gICAgICAgICAgICBpZiAoaW1hZ2UgaW5zdGFuY2VvZiBIVE1MSW1hZ2VFbGVtZW50IHx8IGltYWdlIGluc3RhbmNlb2YgSFRNTENhbnZhc0VsZW1lbnQgfHwgaW1hZ2UgaW5zdGFuY2VvZiBIVE1MVmlkZW9FbGVtZW50IHx8IGltYWdlIGluc3RhbmNlb2YgSW1hZ2VEYXRhIHx8IChJbWFnZUJpdG1hcCAmJiBpbWFnZSBpbnN0YW5jZW9mIEltYWdlQml0bWFwKSkge1xuICAgICAgICAgICAgICAgIGdsLnRleFN1YkltYWdlMkQoZ2wuVEVYVFVSRV8yRCwgMCwgeCwgeSwgZ2wuUkdCQSwgZ2wuVU5TSUdORURfQllURSwgaW1hZ2UpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyAkRmxvd0ZpeE1lIHByb3AtbWlzc2luZyAtIEZsb3cgY2FuJ3QgcmVmaW5lIGltYWdlIHR5cGUgaGVyZVxuICAgICAgICAgICAgICAgIGdsLnRleFN1YkltYWdlMkQoZ2wuVEVYVFVSRV8yRCwgMCwgeCwgeSwgd2lkdGgsIGhlaWdodCwgZ2wuUkdCQSwgZ2wuVU5TSUdORURfQllURSwgaW1hZ2UuZGF0YSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnVzZU1pcG1hcCA9IEJvb2xlYW4ob3B0aW9ucyAmJiBvcHRpb25zLnVzZU1pcG1hcCAmJiB0aGlzLmlzU2l6ZVBvd2VyT2ZUd28oKSk7XG4gICAgICAgIGlmICh0aGlzLnVzZU1pcG1hcCkge1xuICAgICAgICAgICAgZ2wuZ2VuZXJhdGVNaXBtYXAoZ2wuVEVYVFVSRV8yRCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBiaW5kKGZpbHRlcjogVGV4dHVyZUZpbHRlciwgd3JhcDogVGV4dHVyZVdyYXApIHtcbiAgICAgICAgY29uc3Qge2NvbnRleHR9ID0gdGhpcztcbiAgICAgICAgY29uc3Qge2dsfSA9IGNvbnRleHQ7XG4gICAgICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIHRoaXMudGV4dHVyZSk7XG5cbiAgICAgICAgaWYgKGZpbHRlciAhPT0gdGhpcy5maWx0ZXIpIHtcbiAgICAgICAgICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9NQUdfRklMVEVSLCBmaWx0ZXIpO1xuICAgICAgICAgICAgZ2wudGV4UGFyYW1ldGVyaShnbC5URVhUVVJFXzJELCBnbC5URVhUVVJFX01JTl9GSUxURVIsXG4gICAgICAgICAgICAgICAgdGhpcy51c2VNaXBtYXAgPyAoZmlsdGVyID09PSBnbC5ORUFSRVNUID8gZ2wuTkVBUkVTVF9NSVBNQVBfTkVBUkVTVCA6IGdsLkxJTkVBUl9NSVBNQVBfTkVBUkVTVCkgOiBmaWx0ZXJcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLmZpbHRlciA9IGZpbHRlcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh3cmFwICE9PSB0aGlzLndyYXApIHtcbiAgICAgICAgICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9XUkFQX1MsIHdyYXApO1xuICAgICAgICAgICAgZ2wudGV4UGFyYW1ldGVyaShnbC5URVhUVVJFXzJELCBnbC5URVhUVVJFX1dSQVBfVCwgd3JhcCk7XG4gICAgICAgICAgICB0aGlzLndyYXAgPSB3cmFwO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaXNTaXplUG93ZXJPZlR3bygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2l6ZVswXSA9PT0gdGhpcy5zaXplWzFdICYmIChNYXRoLmxvZyh0aGlzLnNpemVbMF0pIC8gTWF0aC5MTjIpICUgMSA9PT0gMDtcbiAgICB9XG5cbiAgICBkZXN0cm95KCkge1xuICAgICAgICBjb25zdCB7Z2x9ID0gdGhpcy5jb250ZXh0O1xuICAgICAgICBnbC5kZWxldGVUZXh0dXJlKHRoaXMudGV4dHVyZSk7XG4gICAgICAgIHRoaXMudGV4dHVyZSA9IChudWxsOiBhbnkpO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgVGV4dHVyZTtcbiIsIi8vIEBmbG93XG5cbi8qKlxuICogSW52b2tlcyB0aGUgd3JhcHBlZCBmdW5jdGlvbiBpbiBhIG5vbi1ibG9ja2luZyB3YXkgd2hlbiB0cmlnZ2VyKCkgaXMgY2FsbGVkLiBJbnZvY2F0aW9uIHJlcXVlc3RzXG4gKiBhcmUgaWdub3JlZCB1bnRpbCB0aGUgZnVuY3Rpb24gd2FzIGFjdHVhbGx5IGludm9rZWQuXG4gKlxuICogQHByaXZhdGVcbiAqL1xuY2xhc3MgVGhyb3R0bGVkSW52b2tlciB7XG4gICAgX2NoYW5uZWw6ID9NZXNzYWdlQ2hhbm5lbDtcbiAgICBfdHJpZ2dlcmVkOiBib29sZWFuO1xuICAgIF9jYWxsYmFjazogRnVuY3Rpb25cblxuICAgIGNvbnN0cnVjdG9yKGNhbGxiYWNrOiBGdW5jdGlvbikge1xuICAgICAgICB0aGlzLl9jYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgICAgICB0aGlzLl90cmlnZ2VyZWQgPSBmYWxzZTtcbiAgICAgICAgaWYgKHR5cGVvZiBNZXNzYWdlQ2hhbm5lbCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRoaXMuX2NoYW5uZWwgPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICAgICAgICAgIHRoaXMuX2NoYW5uZWwucG9ydDIub25tZXNzYWdlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX3RyaWdnZXJlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRoaXMuX2NhbGxiYWNrKCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdHJpZ2dlcigpIHtcbiAgICAgICAgaWYgKCF0aGlzLl90cmlnZ2VyZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3RyaWdnZXJlZCA9IHRydWU7XG4gICAgICAgICAgICBpZiAodGhpcy5fY2hhbm5lbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2NoYW5uZWwucG9ydDEucG9zdE1lc3NhZ2UodHJ1ZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl90cmlnZ2VyZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2FsbGJhY2soKTtcbiAgICAgICAgICAgICAgICB9LCAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJlbW92ZSgpIHtcbiAgICAgICAgdGhpcy5fY2hhbm5lbCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5fY2FsbGJhY2sgPSAoKSA9PiB7fTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFRocm90dGxlZEludm9rZXI7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgVGhyb3R0bGVkSW52b2tlciBmcm9tICcuL3Rocm90dGxlZF9pbnZva2VyLmpzJztcbmltcG9ydCB7YmluZEFsbCwgaXNXb3JrZXJ9IGZyb20gJy4vdXRpbC5qcyc7XG5pbXBvcnQge1BlcmZvcm1hbmNlVXRpbHN9IGZyb20gJy4vcGVyZm9ybWFuY2UuanMnO1xuXG5pbXBvcnQgdHlwZSB7Q2FuY2VsYWJsZX0gZnJvbSAnLi4vdHlwZXMvY2FuY2VsYWJsZS5qcyc7XG5cbnR5cGUgVGFza01ldGFkYXRhID0ge1xuICAgIHR5cGU6ICdtZXNzYWdlJyB8ICdtYXliZVByZXBhcmUnIHwgJ3BhcnNlVGlsZScsXG4gICAgaXNTeW1ib2xUaWxlOiA/Ym9vbGVhbixcbiAgICB6b29tPzogbnVtYmVyXG59O1xuXG50eXBlIFRhc2tGdW5jdGlvbiA9ICgpID0+IHZvaWQ7XG5cbnR5cGUgVGFzayA9IHtcbiAgICBmbjogVGFza0Z1bmN0aW9uLFxuICAgIG1ldGFkYXRhOiBUYXNrTWV0YWRhdGEsXG4gICAgcHJpb3JpdHk6IG51bWJlcixcbiAgICBpZDogbnVtYmVyXG59O1xuXG5jbGFzcyBTY2hlZHVsZXIge1xuXG4gICAgdGFza3M6IHsgW251bWJlcl06IFRhc2sgfTtcbiAgICB0YXNrUXVldWU6IEFycmF5PG51bWJlcj47XG4gICAgaW52b2tlcjogVGhyb3R0bGVkSW52b2tlcjtcbiAgICBuZXh0SWQ6IG51bWJlcjtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnRhc2tzID0ge307XG4gICAgICAgIHRoaXMudGFza1F1ZXVlID0gW107XG4gICAgICAgIGJpbmRBbGwoWydwcm9jZXNzJ10sIHRoaXMpO1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIHRoaXMuaW52b2tlciA9IG5ldyBUaHJvdHRsZWRJbnZva2VyKHRoaXMucHJvY2Vzcyk7XG5cbiAgICAgICAgdGhpcy5uZXh0SWQgPSAwO1xuICAgIH1cblxuICAgIGFkZChmbjogVGFza0Z1bmN0aW9uLCBtZXRhZGF0YTogVGFza01ldGFkYXRhKTogQ2FuY2VsYWJsZSB7XG4gICAgICAgIGNvbnN0IGlkID0gdGhpcy5uZXh0SWQrKztcbiAgICAgICAgY29uc3QgcHJpb3JpdHkgPSBnZXRQcmlvcml0eShtZXRhZGF0YSk7XG5cbiAgICAgICAgaWYgKHByaW9yaXR5ID09PSAwKSB7XG4gICAgICAgICAgICAvLyBQcm9jZXNzIHRhc2tzIHdpdGggcHJpb3JpdHkgMCBpbW1lZGlhdGVseS4gRG8gbm90IHlpZWxkIHRvIHRoZSBldmVudCBsb29wLlxuICAgICAgICAgICAgY29uc3QgbSA9IGlzV29ya2VyKCkgPyBQZXJmb3JtYW5jZVV0aWxzLmJlZ2luTWVhc3VyZSgnd29ya2VyVGFzaycpIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBmbigpO1xuICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICBpZiAobSkgUGVyZm9ybWFuY2VVdGlscy5lbmRNZWFzdXJlKG0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBjYW5jZWw6ICgpID0+IHt9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy50YXNrc1tpZF0gPSB7Zm4sIG1ldGFkYXRhLCBwcmlvcml0eSwgaWR9O1xuICAgICAgICB0aGlzLnRhc2tRdWV1ZS5wdXNoKGlkKTtcbiAgICAgICAgdGhpcy5pbnZva2VyLnRyaWdnZXIoKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNhbmNlbDogKCkgPT4ge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnRhc2tzW2lkXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcm9jZXNzKCkge1xuICAgICAgICBjb25zdCBtID0gaXNXb3JrZXIoKSA/IFBlcmZvcm1hbmNlVXRpbHMuYmVnaW5NZWFzdXJlKCd3b3JrZXJUYXNrJykgOiB1bmRlZmluZWQ7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzLnRhc2tRdWV1ZSA9IHRoaXMudGFza1F1ZXVlLmZpbHRlcihpZCA9PiAhIXRoaXMudGFza3NbaWRdKTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLnRhc2tRdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBpZCA9IHRoaXMucGljaygpO1xuICAgICAgICAgICAgaWYgKGlkID09PSBudWxsKSByZXR1cm47XG5cbiAgICAgICAgICAgIGNvbnN0IHRhc2sgPSB0aGlzLnRhc2tzW2lkXTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnRhc2tzW2lkXTtcbiAgICAgICAgICAgIC8vIFNjaGVkdWxlIGFub3RoZXIgcHJvY2VzcyBjYWxsIGlmIHdlIGtub3cgdGhlcmUncyBtb3JlIHRvIHByb2Nlc3MgX2JlZm9yZV8gaW52b2tpbmcgdGhlXG4gICAgICAgICAgICAvLyBjdXJyZW50IHRhc2suIFRoaXMgaXMgbmVjZXNzYXJ5IHNvIHRoYXQgcHJvY2Vzc2luZyBjb250aW51ZXMgZXZlbiBpZiB0aGUgY3VycmVudCB0YXNrXG4gICAgICAgICAgICAvLyBkb2Vzbid0IGV4ZWN1dGUgc3VjY2Vzc2Z1bGx5LlxuICAgICAgICAgICAgaWYgKHRoaXMudGFza1F1ZXVlLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHRoaXMuaW52b2tlci50cmlnZ2VyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRhc2spIHtcbiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgdGFzayBJRCBkb2Vzbid0IGhhdmUgYXNzb2NpYXRlZCB0YXNrIGRhdGEgYW55bW9yZSwgaXQgd2FzIGNhbmNlbGVkLlxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGFzay5mbigpO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgaWYgKG0pIFBlcmZvcm1hbmNlVXRpbHMuZW5kTWVhc3VyZShtKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHBpY2soKTogbnVsbCB8IG51bWJlciB7XG4gICAgICAgIGxldCBtaW5JbmRleCA9IG51bGw7XG4gICAgICAgIGxldCBtaW5Qcmlvcml0eSA9IEluZmluaXR5O1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMudGFza1F1ZXVlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBpZCA9IHRoaXMudGFza1F1ZXVlW2ldO1xuICAgICAgICAgICAgY29uc3QgdGFzayA9IHRoaXMudGFza3NbaWRdO1xuICAgICAgICAgICAgaWYgKHRhc2sucHJpb3JpdHkgPCBtaW5Qcmlvcml0eSkge1xuICAgICAgICAgICAgICAgIG1pblByaW9yaXR5ID0gdGFzay5wcmlvcml0eTtcbiAgICAgICAgICAgICAgICBtaW5JbmRleCA9IGk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1pbkluZGV4ID09PSBudWxsKSByZXR1cm4gbnVsbDtcbiAgICAgICAgY29uc3QgaWQgPSB0aGlzLnRhc2tRdWV1ZVttaW5JbmRleF07XG4gICAgICAgIHRoaXMudGFza1F1ZXVlLnNwbGljZShtaW5JbmRleCwgMSk7XG4gICAgICAgIHJldHVybiBpZDtcbiAgICB9XG5cbiAgICByZW1vdmUoKSB7XG4gICAgICAgIHRoaXMuaW52b2tlci5yZW1vdmUoKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGdldFByaW9yaXR5KHt0eXBlLCBpc1N5bWJvbFRpbGUsIHpvb219OiBUYXNrTWV0YWRhdGEpOiBudW1iZXIge1xuICAgIHpvb20gPSB6b29tIHx8IDA7XG4gICAgaWYgKHR5cGUgPT09ICdtZXNzYWdlJykgcmV0dXJuIDA7XG4gICAgaWYgKHR5cGUgPT09ICdtYXliZVByZXBhcmUnICYmICFpc1N5bWJvbFRpbGUpIHJldHVybiAxMDAgLSB6b29tO1xuICAgIGlmICh0eXBlID09PSAncGFyc2VUaWxlJyAmJiAhaXNTeW1ib2xUaWxlKSByZXR1cm4gMjAwIC0gem9vbTtcbiAgICBpZiAodHlwZSA9PT0gJ3BhcnNlVGlsZScgJiYgaXNTeW1ib2xUaWxlKSByZXR1cm4gMzAwIC0gem9vbTtcbiAgICBpZiAodHlwZSA9PT0gJ21heWJlUHJlcGFyZScgJiYgaXNTeW1ib2xUaWxlKSByZXR1cm4gNDAwIC0gem9vbTtcbiAgICByZXR1cm4gNTAwO1xufVxuXG5leHBvcnQgZGVmYXVsdCBTY2hlZHVsZXI7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge2JpbmRBbGwsIGlzV29ya2VyLCBpc1NhZmFyaX0gZnJvbSAnLi91dGlsLmpzJztcbmltcG9ydCB3aW5kb3cgZnJvbSAnLi93aW5kb3cuanMnO1xuaW1wb3J0IHtzZXJpYWxpemUsIGRlc2VyaWFsaXplfSBmcm9tICcuL3dlYl93b3JrZXJfdHJhbnNmZXIuanMnO1xuaW1wb3J0IFNjaGVkdWxlciBmcm9tICcuL3NjaGVkdWxlci5qcyc7XG5cbmltcG9ydCB0eXBlIHtUcmFuc2ZlcmFibGV9IGZyb20gJy4uL3R5cGVzL3RyYW5zZmVyYWJsZS5qcyc7XG5pbXBvcnQgdHlwZSB7Q2FuY2VsYWJsZX0gZnJvbSAnLi4vdHlwZXMvY2FuY2VsYWJsZS5qcyc7XG5cbi8qKlxuICogQW4gaW1wbGVtZW50YXRpb24gb2YgdGhlIFtBY3RvciBkZXNpZ24gcGF0dGVybl0oaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9BY3Rvcl9tb2RlbClcbiAqIHRoYXQgbWFpbnRhaW5zIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBhc3luY2hyb25vdXMgdGFza3MgYW5kIHRoZSBvYmplY3RzXG4gKiB0aGF0IHNwaW4gdGhlbSBvZmYgLSBpbiB0aGlzIGNhc2UsIHRhc2tzIGxpa2UgcGFyc2luZyBwYXJ0cyBvZiBzdHlsZXMsXG4gKiBvd25lZCBieSB0aGUgc3R5bGVzXG4gKlxuICogQHBhcmFtIHtXZWJXb3JrZXJ9IHRhcmdldFxuICogQHBhcmFtIHtXZWJXb3JrZXJ9IHBhcmVudFxuICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBtYXBJZCBBIHVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGUgTWFwIGluc3RhbmNlIHVzaW5nIHRoaXMgQWN0b3IuXG4gKiBAcHJpdmF0ZVxuICovXG5jbGFzcyBBY3RvciB7XG4gICAgdGFyZ2V0OiBhbnk7XG4gICAgcGFyZW50OiBhbnk7XG4gICAgbWFwSWQ6ID9udW1iZXI7XG4gICAgY2FsbGJhY2tzOiB7IG51bWJlcjogYW55IH07XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIGNhbmNlbENhbGxiYWNrczogeyBudW1iZXI6IENhbmNlbGFibGUgfTtcbiAgICBnbG9iYWxTY29wZTogYW55O1xuICAgIHNjaGVkdWxlcjogU2NoZWR1bGVyO1xuXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBhbnksIHBhcmVudDogYW55LCBtYXBJZDogP251bWJlcikge1xuICAgICAgICB0aGlzLnRhcmdldCA9IHRhcmdldDtcbiAgICAgICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7XG4gICAgICAgIHRoaXMubWFwSWQgPSBtYXBJZDtcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB7fTtcbiAgICAgICAgdGhpcy5jYW5jZWxDYWxsYmFja3MgPSB7fTtcbiAgICAgICAgYmluZEFsbChbJ3JlY2VpdmUnXSwgdGhpcyk7XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgdGhpcy50YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIHRoaXMucmVjZWl2ZSwgZmFsc2UpO1xuICAgICAgICB0aGlzLmdsb2JhbFNjb3BlID0gaXNXb3JrZXIoKSA/IHRhcmdldCA6IHdpbmRvdztcbiAgICAgICAgdGhpcy5zY2hlZHVsZXIgPSBuZXcgU2NoZWR1bGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VuZHMgYSBtZXNzYWdlIGZyb20gYSBtYWluLXRocmVhZCBtYXAgdG8gYSBXb3JrZXIgb3IgZnJvbSBhIFdvcmtlciBiYWNrIHRvXG4gICAgICogYSBtYWluLXRocmVhZCBtYXAgaW5zdGFuY2UuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdHlwZSBUaGUgbmFtZSBvZiB0aGUgdGFyZ2V0IG1ldGhvZCB0byBpbnZva2Ugb3IgJ1tzb3VyY2UtdHlwZV0uW3NvdXJjZS1uYW1lXS5uYW1lJyBmb3IgYSBtZXRob2Qgb24gYSBXb3JrZXJTb3VyY2UuXG4gICAgICogQHBhcmFtIHRhcmdldE1hcElkIEEgcGFydGljdWxhciBtYXBJZCB0byB3aGljaCB0byBzZW5kIHRoaXMgbWVzc2FnZS5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHNlbmQodHlwZTogc3RyaW5nLCBkYXRhOiBtaXhlZCwgY2FsbGJhY2s6ID9GdW5jdGlvbiwgdGFyZ2V0TWFwSWQ6ID9zdHJpbmcsIG11c3RRdWV1ZTogYm9vbGVhbiA9IGZhbHNlLCBjYWxsYmFja01ldGFkYXRhPzogT2JqZWN0KTogP0NhbmNlbGFibGUge1xuICAgICAgICAvLyBXZSdyZSB1c2luZyBhIHN0cmluZyBJRCBpbnN0ZWFkIG9mIG51bWJlcnMgYmVjYXVzZSB0aGV5IGFyZSBiZWluZyB1c2VkIGFzIG9iamVjdCBrZXlzXG4gICAgICAgIC8vIGFueXdheSwgYW5kIHRodXMgc3RyaW5naWZpZWQgaW1wbGljaXRseS4gV2UgdXNlIHJhbmRvbSBJRHMgYmVjYXVzZSBhbiBhY3RvciBtYXkgcmVjZWl2ZVxuICAgICAgICAvLyBtZXNzYWdlIGZyb20gbXVsdGlwbGUgb3RoZXIgYWN0b3JzIHdoaWNoIGNvdWxkIHJ1biBpbiBkaWZmZXJlbnQgZXhlY3V0aW9uIGNvbnRleHQuIEFcbiAgICAgICAgLy8gbGluZWFybHkgaW5jcmVhc2luZyBJRCBjb3VsZCBwcm9kdWNlIGNvbGxpc2lvbnMuXG4gICAgICAgIGNvbnN0IGlkID0gTWF0aC5yb3VuZCgoTWF0aC5yYW5kb20oKSAqIDFlMTgpKS50b1N0cmluZygzNikuc3Vic3RyaW5nKDAsIDEwKTtcbiAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICBjYWxsYmFjay5tZXRhZGF0YSA9IGNhbGxiYWNrTWV0YWRhdGE7XG4gICAgICAgICAgICB0aGlzLmNhbGxiYWNrc1tpZF0gPSBjYWxsYmFjaztcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBidWZmZXJzOiA/QXJyYXk8VHJhbnNmZXJhYmxlPiA9IGlzU2FmYXJpKHRoaXMuZ2xvYmFsU2NvcGUpID8gdW5kZWZpbmVkIDogW107XG4gICAgICAgIHRoaXMudGFyZ2V0LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgIGhhc0NhbGxiYWNrOiAhIWNhbGxiYWNrLFxuICAgICAgICAgICAgdGFyZ2V0TWFwSWQsXG4gICAgICAgICAgICBtdXN0UXVldWUsXG4gICAgICAgICAgICBzb3VyY2VNYXBJZDogdGhpcy5tYXBJZCxcbiAgICAgICAgICAgIGRhdGE6IHNlcmlhbGl6ZShkYXRhLCBidWZmZXJzKVxuICAgICAgICB9LCBidWZmZXJzKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNhbmNlbDogKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgICAgICAvLyBTZXQgdGhlIGNhbGxiYWNrIHRvIG51bGwgc28gdGhhdCBpdCBuZXZlciBmaXJlcyBhZnRlciB0aGUgcmVxdWVzdCBpcyBhYm9ydGVkLlxuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5jYWxsYmFja3NbaWRdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnRhcmdldC5wb3N0TWVzc2FnZSh7XG4gICAgICAgICAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiAnPGNhbmNlbD4nLFxuICAgICAgICAgICAgICAgICAgICB0YXJnZXRNYXBJZCxcbiAgICAgICAgICAgICAgICAgICAgc291cmNlTWFwSWQ6IHRoaXMubWFwSWRcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICByZWNlaXZlKG1lc3NhZ2U6IE9iamVjdCkge1xuICAgICAgICBjb25zdCBkYXRhID0gbWVzc2FnZS5kYXRhLFxuICAgICAgICAgICAgaWQgPSBkYXRhLmlkO1xuXG4gICAgICAgIGlmICghaWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkYXRhLnRhcmdldE1hcElkICYmIHRoaXMubWFwSWQgIT09IGRhdGEudGFyZ2V0TWFwSWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkYXRhLnR5cGUgPT09ICc8Y2FuY2VsPicpIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgb3JpZ2luYWwgcmVxdWVzdCBmcm9tIHRoZSBxdWV1ZS4gVGhpcyBpcyBvbmx5IHBvc3NpYmxlIGlmIGl0XG4gICAgICAgICAgICAvLyBoYXNuJ3QgYmVlbiBraWNrZWQgb2ZmIHlldC4gVGhlIGlkIHdpbGwgcmVtYWluIGluIHRoZSBxdWV1ZSwgYnV0IGJlY2F1c2VcbiAgICAgICAgICAgIC8vIHRoZXJlIGlzIG5vIGFzc29jaWF0ZWQgdGFzaywgaXQgd2lsbCBiZSBkcm9wcGVkIG9uY2UgaXQncyB0aW1lIHRvIGV4ZWN1dGUgaXQuXG4gICAgICAgICAgICBjb25zdCBjYW5jZWwgPSB0aGlzLmNhbmNlbENhbGxiYWNrc1tpZF07XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5jYW5jZWxDYWxsYmFja3NbaWRdO1xuICAgICAgICAgICAgaWYgKGNhbmNlbCkge1xuICAgICAgICAgICAgICAgIGNhbmNlbC5jYW5jZWwoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChkYXRhLm11c3RRdWV1ZSB8fCBpc1dvcmtlcigpKSB7XG4gICAgICAgICAgICAgICAgLy8gZm9yIHdvcmtlciB0YXNrcyB0aGF0IGFyZSBvZnRlbiBjYW5jZWxsZWQsIHN1Y2ggYXMgbG9hZFRpbGUsIHN0b3JlIHRoZW0gYmVmb3JlIGFjdHVhbGx5XG4gICAgICAgICAgICAgICAgLy8gcHJvY2Vzc2luZyB0aGVtLiBUaGlzIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIHdlIHdhbnQgdG8ga2VlcCByZWNlaXZpbmcgPGNhbmNlbD4gbWVzc2FnZXMuXG4gICAgICAgICAgICAgICAgLy8gU29tZSB0YXNrcyBtYXkgdGFrZSBhIHdoaWxlIGluIHRoZSB3b3JrZXIgdGhyZWFkLCBzbyBiZWZvcmUgZXhlY3V0aW5nIHRoZSBuZXh0IHRhc2tcbiAgICAgICAgICAgICAgICAvLyBpbiBvdXIgcXVldWUsIHBvc3RNZXNzYWdlIHByZWVtcHRzIHRoaXMgYW5kIDxjYW5jZWw+IG1lc3NhZ2VzIGNhbiBiZSBwcm9jZXNzZWQuXG4gICAgICAgICAgICAgICAgLy8gV2UncmUgdXNpbmcgYSBNZXNzYWdlQ2hhbm5lbCBvYmplY3QgdG8gZ2V0IHRocm90dGxlIHRoZSBwcm9jZXNzKCkgZmxvdyB0byBvbmUgYXQgYSB0aW1lLlxuICAgICAgICAgICAgICAgIGNvbnN0IGNhbGxiYWNrID0gdGhpcy5jYWxsYmFja3NbaWRdO1xuICAgICAgICAgICAgICAgIGNvbnN0IG1ldGFkYXRhID0gKGNhbGxiYWNrICYmIGNhbGxiYWNrLm1ldGFkYXRhKSB8fCB7dHlwZTogXCJtZXNzYWdlXCJ9O1xuICAgICAgICAgICAgICAgIHRoaXMuY2FuY2VsQ2FsbGJhY2tzW2lkXSA9IHRoaXMuc2NoZWR1bGVyLmFkZCgoKSA9PiB0aGlzLnByb2Nlc3NUYXNrKGlkLCBkYXRhKSwgbWV0YWRhdGEpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBJbiB0aGUgbWFpbiB0aHJlYWQsIHByb2Nlc3MgbWVzc2FnZXMgaW1tZWRpYXRlbHkgc28gdGhhdCBvdGhlciB3b3JrIGRvZXMgbm90IHNsaXAgaW5cbiAgICAgICAgICAgICAgICAvLyBiZXR3ZWVuIGdldHRpbmcgcGFydGlhbCBkYXRhIGJhY2sgZnJvbSB3b3JrZXJzLlxuICAgICAgICAgICAgICAgIHRoaXMucHJvY2Vzc1Rhc2soaWQsIGRhdGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJvY2Vzc1Rhc2soaWQ6IG51bWJlciwgdGFzazogYW55KSB7XG4gICAgICAgIGlmICh0YXNrLnR5cGUgPT09ICc8cmVzcG9uc2U+Jykge1xuICAgICAgICAgICAgLy8gVGhlIGRvbmUoKSBmdW5jdGlvbiBpbiB0aGUgY291bnRlcnBhcnQgaGFzIGJlZW4gY2FsbGVkLCBhbmQgd2UgYXJlIG5vd1xuICAgICAgICAgICAgLy8gZmlyaW5nIHRoZSBjYWxsYmFjayBpbiB0aGUgb3JpZ2luYXRpbmcgYWN0b3IsIGlmIHRoZXJlIGlzIG9uZS5cbiAgICAgICAgICAgIGNvbnN0IGNhbGxiYWNrID0gdGhpcy5jYWxsYmFja3NbaWRdO1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuY2FsbGJhY2tzW2lkXTtcbiAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgIC8vIElmIHdlIGdldCBhIHJlc3BvbnNlLCBidXQgZG9uJ3QgaGF2ZSBhIGNhbGxiYWNrLCB0aGUgcmVxdWVzdCB3YXMgY2FuY2VsZWQuXG4gICAgICAgICAgICAgICAgaWYgKHRhc2suZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soZGVzZXJpYWxpemUodGFzay5lcnJvcikpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIGRlc2VyaWFsaXplKHRhc2suZGF0YSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlcnM6ID9BcnJheTxUcmFuc2ZlcmFibGU+ID0gaXNTYWZhcmkodGhpcy5nbG9iYWxTY29wZSkgPyB1bmRlZmluZWQgOiBbXTtcbiAgICAgICAgICAgIGNvbnN0IGRvbmUgPSB0YXNrLmhhc0NhbGxiYWNrID8gKGVycjogP0Vycm9yLCBkYXRhOiBtaXhlZCkgPT4ge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmNhbmNlbENhbGxiYWNrc1tpZF07XG4gICAgICAgICAgICAgICAgdGhpcy50YXJnZXQucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgICAgICAgICAgICBpZCxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJzxyZXNwb25zZT4nLFxuICAgICAgICAgICAgICAgICAgICBzb3VyY2VNYXBJZDogdGhpcy5tYXBJZCxcbiAgICAgICAgICAgICAgICAgICAgZXJyb3I6IGVyciA/IHNlcmlhbGl6ZShlcnIpIDogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogc2VyaWFsaXplKGRhdGEsIGJ1ZmZlcnMpXG4gICAgICAgICAgICAgICAgfSwgYnVmZmVycyk7XG4gICAgICAgICAgICB9IDogKF8pID0+IHtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IChkZXNlcmlhbGl6ZSh0YXNrLmRhdGEpOiBhbnkpO1xuICAgICAgICAgICAgaWYgKHRoaXMucGFyZW50W3Rhc2sudHlwZV0pIHtcbiAgICAgICAgICAgICAgICAvLyB0YXNrLnR5cGUgPT0gJ2xvYWRUaWxlJywgJ3JlbW92ZVRpbGUnLCBldGMuXG4gICAgICAgICAgICAgICAgdGhpcy5wYXJlbnRbdGFzay50eXBlXSh0YXNrLnNvdXJjZU1hcElkLCBwYXJhbXMsIGRvbmUpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnBhcmVudC5nZXRXb3JrZXJTb3VyY2UpIHtcbiAgICAgICAgICAgICAgICAvLyB0YXNrLnR5cGUgPT0gc291cmNldHlwZS5tZXRob2RcbiAgICAgICAgICAgICAgICBjb25zdCBrZXlzID0gdGFzay50eXBlLnNwbGl0KCcuJyk7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2NvcGUgPSAodGhpcy5wYXJlbnQ6IGFueSkuZ2V0V29ya2VyU291cmNlKHRhc2suc291cmNlTWFwSWQsIGtleXNbMF0sIHBhcmFtcy5zb3VyY2UpO1xuICAgICAgICAgICAgICAgIHNjb3BlW2tleXNbMV1dKHBhcmFtcywgZG9uZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIE5vIGZ1bmN0aW9uIHdhcyBmb3VuZC5cbiAgICAgICAgICAgICAgICBkb25lKG5ldyBFcnJvcihgQ291bGQgbm90IGZpbmQgZnVuY3Rpb24gJHt0YXNrLnR5cGV9YCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmVtb3ZlKCkge1xuICAgICAgICB0aGlzLnNjaGVkdWxlci5yZW1vdmUoKTtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICB0aGlzLnRhcmdldC5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgdGhpcy5yZWNlaXZlLCBmYWxzZSk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBBY3RvcjtcbiIsIi8vIEBmbG93IHN0cmljdFxuXG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbmNsYXNzIERpY3Rpb25hcnlDb2RlciB7XG4gICAgX3N0cmluZ1RvTnVtYmVyOiB7W186IHN0cmluZ106IG51bWJlciB9O1xuICAgIF9udW1iZXJUb1N0cmluZzogQXJyYXk8c3RyaW5nPjtcblxuICAgIGNvbnN0cnVjdG9yKHN0cmluZ3M6IEFycmF5PHN0cmluZz4pIHtcbiAgICAgICAgdGhpcy5fc3RyaW5nVG9OdW1iZXIgPSB7fTtcbiAgICAgICAgdGhpcy5fbnVtYmVyVG9TdHJpbmcgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdHJpbmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBzdHJpbmcgPSBzdHJpbmdzW2ldO1xuICAgICAgICAgICAgdGhpcy5fc3RyaW5nVG9OdW1iZXJbc3RyaW5nXSA9IGk7XG4gICAgICAgICAgICB0aGlzLl9udW1iZXJUb1N0cmluZ1tpXSA9IHN0cmluZztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGVuY29kZShzdHJpbmc6IHN0cmluZyk6IG51bWJlciB7XG4gICAgICAgIGFzc2VydChzdHJpbmcgaW4gdGhpcy5fc3RyaW5nVG9OdW1iZXIpO1xuICAgICAgICByZXR1cm4gdGhpcy5fc3RyaW5nVG9OdW1iZXJbc3RyaW5nXTtcbiAgICB9XG5cbiAgICBkZWNvZGUobjogbnVtYmVyKTogc3RyaW5nIHtcbiAgICAgICAgYXNzZXJ0KG4gPCB0aGlzLl9udW1iZXJUb1N0cmluZy5sZW5ndGgpO1xuICAgICAgICByZXR1cm4gdGhpcy5fbnVtYmVyVG9TdHJpbmdbbl07XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBEaWN0aW9uYXJ5Q29kZXI7XG4iLCIvLyBAZmxvd1xuaW1wb3J0IHR5cGUge0xheWVyU3BlY2lmaWNhdGlvbiwgU291cmNlU3BlY2lmaWNhdGlvbn0gZnJvbSAnLi4vc3R5bGUtc3BlYy90eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSB7R2VvSlNPTkdlb21ldHJ5LCBHZW9KU09ORmVhdHVyZX0gZnJvbSAnQG1hcGJveC9nZW9qc29uLXR5cGVzJztcbmltcG9ydCB0eXBlIHtJVmVjdG9yVGlsZUZlYXR1cmV9IGZyb20gJ0BtYXBib3gvdmVjdG9yLXRpbGUnO1xuXG4vLyB3ZSBhdWdtZW50IEdlb0pTT04gd2l0aCBjdXN0b20gcHJvcGVydGllcyBpbiBxdWVyeSpGZWF0dXJlcyByZXN1bHRzXG5leHBvcnQgaW50ZXJmYWNlIFF1ZXJ5RmVhdHVyZSBleHRlbmRzIEdlb0pTT05GZWF0dXJlIHtcbiAgICBsYXllcj86ID9MYXllclNwZWNpZmljYXRpb247XG4gICAgc291cmNlPzogP1NvdXJjZVNwZWNpZmljYXRpb24gfCA/bWl4ZWQ7XG4gICAgc291cmNlTGF5ZXI/OiA/c3RyaW5nIHwgP21peGVkO1xuICAgIHN0YXRlOiA/bWl4ZWQ7XG4gICAgW2tleTogc3RyaW5nXTogbWl4ZWQ7XG59XG5cbmNvbnN0IGN1c3RvbVByb3BzID0gWyd0aWxlJywgJ2xheWVyJywgJ3NvdXJjZScsICdzb3VyY2VMYXllcicsICdzdGF0ZSddO1xuXG5jbGFzcyBGZWF0dXJlIHtcbiAgICB0eXBlOiAnRmVhdHVyZSc7XG4gICAgX2dlb21ldHJ5OiA/R2VvSlNPTkdlb21ldHJ5O1xuICAgIHByb3BlcnRpZXM6ID97fTtcbiAgICBpZDogbnVtYmVyIHwgc3RyaW5nIHwgdm9pZDtcbiAgICBfdmVjdG9yVGlsZUZlYXR1cmU6IElWZWN0b3JUaWxlRmVhdHVyZTtcbiAgICBfeDogbnVtYmVyO1xuICAgIF95OiBudW1iZXI7XG4gICAgX3o6IG51bWJlcjtcblxuICAgIHRpbGU6ID9taXhlZDtcbiAgICBsYXllcjogP0xheWVyU3BlY2lmaWNhdGlvbjtcbiAgICBzb3VyY2U6ID9taXhlZDtcbiAgICBzb3VyY2VMYXllcjogP21peGVkO1xuICAgIHN0YXRlOiA/bWl4ZWQ7XG5cbiAgICBjb25zdHJ1Y3Rvcih2ZWN0b3JUaWxlRmVhdHVyZTogSVZlY3RvclRpbGVGZWF0dXJlLCB6OiBudW1iZXIsIHg6IG51bWJlciwgeTogbnVtYmVyLCBpZDogc3RyaW5nIHwgbnVtYmVyIHwgdm9pZCkge1xuICAgICAgICB0aGlzLnR5cGUgPSAnRmVhdHVyZSc7XG5cbiAgICAgICAgdGhpcy5fdmVjdG9yVGlsZUZlYXR1cmUgPSB2ZWN0b3JUaWxlRmVhdHVyZTtcbiAgICAgICAgdGhpcy5feiA9IHo7XG4gICAgICAgIHRoaXMuX3ggPSB4O1xuICAgICAgICB0aGlzLl95ID0geTtcblxuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSB2ZWN0b3JUaWxlRmVhdHVyZS5wcm9wZXJ0aWVzO1xuICAgICAgICB0aGlzLmlkID0gaWQ7XG4gICAgfVxuXG4gICAgZ2V0IGdlb21ldHJ5KCk6ID9HZW9KU09OR2VvbWV0cnkge1xuICAgICAgICBpZiAodGhpcy5fZ2VvbWV0cnkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5fZ2VvbWV0cnkgPSB0aGlzLl92ZWN0b3JUaWxlRmVhdHVyZS50b0dlb0pTT04odGhpcy5feCwgdGhpcy5feSwgdGhpcy5feikuZ2VvbWV0cnk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2dlb21ldHJ5O1xuICAgIH1cblxuICAgIHNldCBnZW9tZXRyeShnOiA/R2VvSlNPTkdlb21ldHJ5KSB7XG4gICAgICAgIHRoaXMuX2dlb21ldHJ5ID0gZztcbiAgICB9XG5cbiAgICB0b0pTT04oKTogUXVlcnlGZWF0dXJlIHtcbiAgICAgICAgY29uc3QganNvbjogUXVlcnlGZWF0dXJlID0ge1xuICAgICAgICAgICAgdHlwZTogJ0ZlYXR1cmUnLFxuICAgICAgICAgICAgc3RhdGU6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGdlb21ldHJ5OiB0aGlzLmdlb21ldHJ5LFxuICAgICAgICAgICAgcHJvcGVydGllczogdGhpcy5wcm9wZXJ0aWVzXG4gICAgICAgIH07XG4gICAgICAgIGlmICh0aGlzLmlkICE9PSB1bmRlZmluZWQpIGpzb24uaWQgPSB0aGlzLmlkO1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBjdXN0b21Qcm9wcykge1xuICAgICAgICAgICAgLy8gRmxvdyBkb2Vzbid0IHN1cHBvcnQgaW5kZXhlZCBhY2Nlc3MgZm9yIGNsYXNzZXMgaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL2Zsb3cvaXNzdWVzLzEzMjNcbiAgICAgICAgICAgIGlmICgodGhpczogYW55KVtrZXldICE9PSB1bmRlZmluZWQpIGpzb25ba2V5XSA9ICh0aGlzOiBhbnkpW2tleV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGpzb247XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBGZWF0dXJlO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHR5cGUge0NvbGxpc2lvbkJveEFycmF5fSBmcm9tICcuL2FycmF5X3R5cGVzLmpzJztcbmltcG9ydCB0eXBlIFN0eWxlIGZyb20gJy4uL3N0eWxlL3N0eWxlLmpzJztcbmltcG9ydCB0eXBlIHtUeXBlZFN0eWxlTGF5ZXJ9IGZyb20gJy4uL3N0eWxlL3N0eWxlX2xheWVyL3R5cGVkX3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCB0eXBlIEZlYXR1cmVJbmRleCBmcm9tICcuL2ZlYXR1cmVfaW5kZXguanMnO1xuaW1wb3J0IHR5cGUgQ29udGV4dCBmcm9tICcuLi9nbC9jb250ZXh0LmpzJztcbmltcG9ydCB0eXBlIHtGZWF0dXJlU3RhdGVzfSBmcm9tICcuLi9zb3VyY2Uvc291cmNlX3N0YXRlLmpzJztcbmltcG9ydCB0eXBlIHtTcHJpdGVQb3NpdGlvbnN9IGZyb20gJy4uL3V0aWwvaW1hZ2UuanMnO1xuaW1wb3J0IHR5cGUgTGluZUF0bGFzIGZyb20gJy4uL3JlbmRlci9saW5lX2F0bGFzLmpzJztcbmltcG9ydCB0eXBlIHtDYW5vbmljYWxUaWxlSUR9IGZyb20gJy4uL3NvdXJjZS90aWxlX2lkLmpzJztcbmltcG9ydCB0eXBlIHtUaWxlVHJhbnNmb3JtfSBmcm9tICcuLi9nZW8vcHJvamVjdGlvbi90aWxlX3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQgdHlwZSBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCB0eXBlIHtQcm9qZWN0aW9uU3BlY2lmaWNhdGlvbn0gZnJvbSAnLi4vc3R5bGUtc3BlYy90eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSB7SVZlY3RvclRpbGVGZWF0dXJlLCBJVmVjdG9yVGlsZUxheWVyfSBmcm9tICdAbWFwYm94L3ZlY3Rvci10aWxlJztcblxuZXhwb3J0IHR5cGUgQnVja2V0UGFyYW1ldGVyczxMYXllcjogVHlwZWRTdHlsZUxheWVyPiA9IHtcbiAgICBpbmRleDogbnVtYmVyLFxuICAgIGxheWVyczogQXJyYXk8TGF5ZXI+LFxuICAgIHpvb206IG51bWJlcixcbiAgICBjYW5vbmljYWw6IENhbm9uaWNhbFRpbGVJRCxcbiAgICBwaXhlbFJhdGlvOiBudW1iZXIsXG4gICAgb3ZlcnNjYWxpbmc6IG51bWJlcixcbiAgICBjb2xsaXNpb25Cb3hBcnJheTogQ29sbGlzaW9uQm94QXJyYXksXG4gICAgc291cmNlTGF5ZXJJbmRleDogbnVtYmVyLFxuICAgIHNvdXJjZUlEOiBzdHJpbmcsXG4gICAgZW5hYmxlVGVycmFpbjogYm9vbGVhbixcbiAgICBwcm9qZWN0aW9uOiBQcm9qZWN0aW9uU3BlY2lmaWNhdGlvblxufVxuXG5leHBvcnQgdHlwZSBQb3B1bGF0ZVBhcmFtZXRlcnMgPSB7XG4gICAgZmVhdHVyZUluZGV4OiBGZWF0dXJlSW5kZXgsXG4gICAgaWNvbkRlcGVuZGVuY2llczoge30sXG4gICAgcGF0dGVybkRlcGVuZGVuY2llczoge30sXG4gICAgZ2x5cGhEZXBlbmRlbmNpZXM6IHt9LFxuICAgIGF2YWlsYWJsZUltYWdlczogQXJyYXk8c3RyaW5nPixcbiAgICBsaW5lQXRsYXM6IExpbmVBdGxhc1xufVxuXG5leHBvcnQgdHlwZSBJbmRleGVkRmVhdHVyZSA9IHtcbiAgICBmZWF0dXJlOiBJVmVjdG9yVGlsZUZlYXR1cmUsXG4gICAgaWQ6IG51bWJlciB8IHN0cmluZyB8IHZvaWQsXG4gICAgaW5kZXg6IG51bWJlcixcbiAgICBzb3VyY2VMYXllckluZGV4OiBudW1iZXIsXG59XG5cbmV4cG9ydCB0eXBlIEJ1Y2tldEZlYXR1cmUgPSB7fFxuICAgIGluZGV4OiBudW1iZXIsXG4gICAgc291cmNlTGF5ZXJJbmRleDogbnVtYmVyLFxuICAgIGdlb21ldHJ5OiBBcnJheTxBcnJheTxQb2ludD4+LFxuICAgIHByb3BlcnRpZXM6IE9iamVjdCxcbiAgICB0eXBlOiAxIHwgMiB8IDMsXG4gICAgaWQ/OiBhbnksXG4gICAgK3BhdHRlcm5zOiB7W186IHN0cmluZ106IHN0cmluZ30sXG4gICAgc29ydEtleT86IG51bWJlclxufH07XG5cbi8qKlxuICogVGhlIGBCdWNrZXRgIGludGVyZmFjZSBpcyB0aGUgc2luZ2xlIHBvaW50IG9mIGtub3dsZWRnZSBhYm91dCB0dXJuaW5nIHZlY3RvclxuICogdGlsZXMgaW50byBXZWJHTCBidWZmZXJzLlxuICpcbiAqIGBCdWNrZXRgIGlzIGFuIGFic3RyYWN0IGludGVyZmFjZS4gQW4gaW1wbGVtZW50YXRpb24gZXhpc3RzIGZvciBlYWNoIHN0eWxlIGxheWVyIHR5cGUuXG4gKiBDcmVhdGUgYSBidWNrZXQgdmlhIHRoZSBgU3R5bGVMYXllciNjcmVhdGVCdWNrZXRgIG1ldGhvZC5cbiAqXG4gKiBUaGUgY29uY3JldGUgYnVja2V0IHR5cGVzLCB1c2luZyBsYXlvdXQgb3B0aW9ucyBmcm9tIHRoZSBzdHlsZSBsYXllcixcbiAqIHRyYW5zZm9ybSBmZWF0dXJlIGdlb21ldHJpZXMgaW50byB2ZXJ0ZXggYW5kIGluZGV4IGRhdGEgZm9yIHVzZSBieSB0aGVcbiAqIHZlcnRleCBzaGFkZXIuICBUaGV5IGFsc28gKHZpYSBgUHJvZ3JhbUNvbmZpZ3VyYXRpb25gKSB1c2UgZmVhdHVyZVxuICogcHJvcGVydGllcyBhbmQgdGhlIHpvb20gbGV2ZWwgdG8gcG9wdWxhdGUgdGhlIGF0dHJpYnV0ZXMgbmVlZGVkIGZvclxuICogZGF0YS1kcml2ZW4gc3R5bGluZy5cbiAqXG4gKiBCdWNrZXRzIGFyZSBkZXNpZ25lZCB0byBiZSBidWlsdCBvbiBhIHdvcmtlciB0aHJlYWQgYW5kIHRoZW4gc2VyaWFsaXplZCBhbmRcbiAqIHRyYW5zZmVycmVkIGJhY2sgdG8gdGhlIG1haW4gdGhyZWFkIGZvciByZW5kZXJpbmcuICBPbiB0aGUgd29ya2VyIHNpZGUsIGFcbiAqIGJ1Y2tldCdzIHZlcnRleCwgaW5kZXgsIGFuZCBhdHRyaWJ1dGUgZGF0YSBpcyBzdG9yZWQgaW4gYGJ1Y2tldC5hcnJheXM6XG4gKiBBcnJheUdyb3VwYC4gIFdoZW4gYSBidWNrZXQncyBkYXRhIGlzIHNlcmlhbGl6ZWQgYW5kIHNlbnQgYmFjayB0byB0aGUgbWFpblxuICogdGhyZWFkLCBpcyBnZXRzIGRlc2VyaWFsaXplZCAodXNpbmcgYG5ldyBCdWNrZXQoc2VyaWFsaXplZEJ1Y2tldERhdGEpYCwgd2l0aFxuICogdGhlIGFycmF5IGRhdGEgbm93IHN0b3JlZCBpbiBgYnVja2V0LmJ1ZmZlcnM6IEJ1ZmZlckdyb3VwYC4gIEJ1ZmZlckdyb3Vwc1xuICogaG9sZCB0aGUgc2FtZSBkYXRhIGFzIEFycmF5R3JvdXBzLCBidXQgYXJlIHR1bmVkIGZvciBjb25zdW1wdGlvbiBieSBXZWJHTC5cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIEJ1Y2tldCB7XG4gICAgbGF5ZXJJZHM6IEFycmF5PHN0cmluZz47XG4gICAgaGFzUGF0dGVybjogYm9vbGVhbjtcbiAgICArbGF5ZXJzOiBBcnJheTxhbnk+O1xuICAgICtzdGF0ZURlcGVuZGVudExheWVyczogQXJyYXk8YW55PjtcbiAgICArc3RhdGVEZXBlbmRlbnRMYXllcklkczogQXJyYXk8c3RyaW5nPjtcbiAgICBwb3B1bGF0ZShmZWF0dXJlczogQXJyYXk8SW5kZXhlZEZlYXR1cmU+LCBvcHRpb25zOiBQb3B1bGF0ZVBhcmFtZXRlcnMsIGNhbm9uaWNhbDogQ2Fub25pY2FsVGlsZUlELCB0aWxlVHJhbnNmb3JtOiBUaWxlVHJhbnNmb3JtKTogdm9pZDtcbiAgICB1cGRhdGUoc3RhdGVzOiBGZWF0dXJlU3RhdGVzLCB2dExheWVyOiBJVmVjdG9yVGlsZUxheWVyLCBhdmFpbGFibGVJbWFnZXM6IEFycmF5PHN0cmluZz4sIGltYWdlUG9zaXRpb25zOiBTcHJpdGVQb3NpdGlvbnMpOiB2b2lkO1xuICAgIGlzRW1wdHkoKTogYm9vbGVhbjtcblxuICAgIHVwbG9hZChjb250ZXh0OiBDb250ZXh0KTogdm9pZDtcbiAgICB1cGxvYWRQZW5kaW5nKCk6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBSZWxlYXNlIHRoZSBXZWJHTCByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBidWZmZXJzLiBOb3RlIHRoYXQgYmVjYXVzZVxuICAgICAqIGJ1Y2tldHMgYXJlIHNoYXJlZCBiZXR3ZWVuIGxheWVycyBoYXZpbmcgdGhlIHNhbWUgbGF5b3V0IHByb3BlcnRpZXMsIHRoZXlcbiAgICAgKiBtdXN0IGJlIGRlc3Ryb3llZCBpbiBncm91cHMgKGFsbCBidWNrZXRzIGZvciBhIHRpbGUsIG9yIGFsbCBzeW1ib2wgYnVja2V0cykuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIGRlc3Ryb3koKTogdm9pZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlc2VyaWFsaXplKGlucHV0OiBBcnJheTxCdWNrZXQ+LCBzdHlsZTogU3R5bGUpOiB7W186IHN0cmluZ106IEJ1Y2tldH0ge1xuICAgIGNvbnN0IG91dHB1dCA9IHt9O1xuXG4gICAgLy8gR3VhcmQgYWdhaW5zdCB0aGUgY2FzZSB3aGVyZSB0aGUgbWFwJ3Mgc3R5bGUgaGFzIGJlZW4gc2V0IHRvIG51bGwgd2hpbGVcbiAgICAvLyB0aGlzIGJ1Y2tldCBoYXMgYmVlbiBwYXJzaW5nLlxuICAgIGlmICghc3R5bGUpIHJldHVybiBvdXRwdXQ7XG5cbiAgICBmb3IgKGNvbnN0IGJ1Y2tldCBvZiBpbnB1dCkge1xuICAgICAgICBjb25zdCBsYXllcnMgPSBidWNrZXQubGF5ZXJJZHNcbiAgICAgICAgICAgIC5tYXAoKGlkKSA9PiBzdHlsZS5nZXRMYXllcihpZCkpXG4gICAgICAgICAgICAuZmlsdGVyKEJvb2xlYW4pO1xuXG4gICAgICAgIGlmIChsYXllcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGxvb2sgdXAgU3R5bGVMYXllciBvYmplY3RzIGZyb20gbGF5ZXIgaWRzIChzaW5jZSB3ZSBkb24ndFxuICAgICAgICAvLyB3YW50IHRvIHdhc3RlIHRpbWUgc2VyaWFsaXppbmcvY29weWluZyB0aGVtIGZyb20gdGhlIHdvcmtlcilcbiAgICAgICAgKGJ1Y2tldDogYW55KS5sYXllcnMgPSBsYXllcnM7XG4gICAgICAgIGlmICgoYnVja2V0OiBhbnkpLnN0YXRlRGVwZW5kZW50TGF5ZXJJZHMpIHtcbiAgICAgICAgICAgIChidWNrZXQ6IGFueSkuc3RhdGVEZXBlbmRlbnRMYXllcnMgPSAoYnVja2V0OiBhbnkpLnN0YXRlRGVwZW5kZW50TGF5ZXJJZHMubWFwKChsSWQpID0+IGxheWVycy5maWx0ZXIoKGwpID0+IGwuaWQgPT09IGxJZClbMF0pO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgbGF5ZXIgb2YgbGF5ZXJzKSB7XG4gICAgICAgICAgICBvdXRwdXRbbGF5ZXIuaWRdID0gYnVja2V0O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dHB1dDtcbn1cbiIsIi8vIEBmbG93XG5pbXBvcnQge2V4dGVuZH0gZnJvbSAnLi91dGlsLmpzJztcbmltcG9ydCB3aW5kb3cgZnJvbSAnLi93aW5kb3cuanMnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHttYXQ0LCB2ZWMzfSBmcm9tICdnbC1tYXRyaXgnO1xuaW1wb3J0IHthYWJiRm9yVGlsZU9uR2xvYmV9IGZyb20gJy4uL2dlby9wcm9qZWN0aW9uL2dsb2JlX3V0aWwuanMnO1xuXG5pbXBvcnQgdHlwZSB7VmVjMiwgVmVjM30gZnJvbSAnZ2wtbWF0cml4JztcbmltcG9ydCB0eXBlIFRyYW5zZm9ybSBmcm9tICcuLi9nZW8vdHJhbnNmb3JtLmpzJztcbmltcG9ydCB0eXBlIFBhaW50ZXIgZnJvbSAnLi4vcmVuZGVyL3BhaW50ZXIuanMnO1xuaW1wb3J0IHR5cGUgU291cmNlQ2FjaGUgZnJvbSAnLi4vc291cmNlL3NvdXJjZV9jYWNoZS5qcyc7XG5pbXBvcnQgdHlwZSB7T3ZlcnNjYWxlZFRpbGVJRH0gZnJvbSAnLi4vc291cmNlL3RpbGVfaWQuanMnO1xuLyoqXG4gKiBUaGlzIGlzIGEgcHJpdmF0ZSBuYW1lc3BhY2UgZm9yIHV0aWxpdHkgZnVuY3Rpb25zIHRoYXQgd2lsbCBnZXQgYXV0b21hdGljYWxseSBzdHJpcHBlZFxuICogb3V0IGluIHByb2R1Y3Rpb24gYnVpbGRzLlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBjb25zdCBEZWJ1Zzoge1xuICAgIGRlYnVnQ2FudmFzOiA/SFRNTENhbnZhc0VsZW1lbnQsXG4gICAgYWFiYkNvcm5lcnM6IEFycmF5PFZlYzM+LFxuICAgIGV4dGVuZDogRnVuY3Rpb24sXG4gICAgcnVuOiBGdW5jdGlvbixcbiAgICBsb2dUb0VsZW1lbnQ6IEZ1bmN0aW9uLFxuICAgIGRyYXdBYWJiczogRnVuY3Rpb24sXG4gICAgY2xlYXJBYWJiczogRnVuY3Rpb24sXG4gICAgX2RyYXdCb3g6IEZ1bmN0aW9uLFxuICAgIF9kcmF3TGluZTogRnVuY3Rpb24sXG4gICAgX2RyYXdRdWFkOiBGdW5jdGlvbixcbiAgICBfaW5pdGlhbGl6ZUNhbnZhczogRnVuY3Rpb24sXG59ID1cbntcbiAgICBleHRlbmQoZGVzdDogT2JqZWN0LCAuLi5zb3VyY2VzOiBBcnJheTw/T2JqZWN0Pik6IE9iamVjdCB7XG4gICAgICAgIHJldHVybiBleHRlbmQoZGVzdCwgLi4uc291cmNlcyk7XG4gICAgfSxcblxuICAgIHJ1bihmbjogKCkgPT4gYW55KSB7XG4gICAgICAgIGZuKCk7XG4gICAgfSxcblxuICAgIGxvZ1RvRWxlbWVudChtZXNzYWdlOiBzdHJpbmcsIG92ZXJ3cml0ZTogYm9vbGVhbiA9IGZhbHNlLCBpZDogc3RyaW5nID0gXCJsb2dcIikge1xuICAgICAgICBjb25zdCBlbCA9IHdpbmRvdy5kb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCk7XG4gICAgICAgIGlmIChlbCkge1xuICAgICAgICAgICAgaWYgKG92ZXJ3cml0ZSkgZWwuaW5uZXJIVE1MID0gJyc7XG4gICAgICAgICAgICBlbC5pbm5lckhUTUwgKz0gYDxicj4ke21lc3NhZ2V9YDtcbiAgICAgICAgfVxuXG4gICAgfSxcblxuICAgIGRlYnVnQ2FudmFzOiBudWxsLFxuICAgIGFhYmJDb3JuZXJzOiBbXSxcblxuICAgIF9pbml0aWFsaXplQ2FudmFzKHRyOiBUcmFuc2Zvcm0pIHtcbiAgICAgICAgaWYgKCFEZWJ1Zy5kZWJ1Z0NhbnZhcykge1xuICAgICAgICAgICAgRGVidWcuZGVidWdDYW52YXMgPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgICAgICAgICB3aW5kb3cuZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChEZWJ1Zy5kZWJ1Z0NhbnZhcyk7XG4gICAgICAgICAgICAvLyBTdXByZXNzIEZsb3cgY2hlY2sgYmVjYXVzZSB3ZSdyZSBjaGVja2luZyBmb3IgbnVsbCBhYm92ZVxuICAgICAgICAgICAgaWYgKCFEZWJ1Zy5kZWJ1Z0NhbnZhcykgcmV0dXJuO1xuXG4gICAgICAgICAgICBEZWJ1Zy5kZWJ1Z0NhbnZhcy5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgICAgICAgICBEZWJ1Zy5kZWJ1Z0NhbnZhcy5zdHlsZS5sZWZ0ID0gJzAnO1xuICAgICAgICAgICAgRGVidWcuZGVidWdDYW52YXMuc3R5bGUudG9wID0gJzAnO1xuICAgICAgICAgICAgRGVidWcuZGVidWdDYW52YXMuc3R5bGUucG9pbnRlckV2ZW50cyA9ICdub25lJztcblxuICAgICAgICAgICAgY29uc3QgcmVzaXplID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghRGVidWcuZGVidWdDYW52YXMpIHsgcmV0dXJuOyB9XG4gICAgICAgICAgICAgICAgRGVidWcuZGVidWdDYW52YXMud2lkdGggPSB0ci53aWR0aDtcbiAgICAgICAgICAgICAgICBEZWJ1Zy5kZWJ1Z0NhbnZhcy5oZWlnaHQgPSB0ci5oZWlnaHQ7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmVzaXplKCk7XG5cbiAgICAgICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicmVzaXplXCIsIHJlc2l6ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIERlYnVnLmRlYnVnQ2FudmFzO1xuICAgIH0sXG5cbiAgICBfZHJhd0xpbmUoY3R4OiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQsIHN0YXJ0OiA/VmVjMiwgZW5kOiA/VmVjMikge1xuICAgICAgICBpZiAoIXN0YXJ0IHx8ICFlbmQpIHsgcmV0dXJuOyB9XG4gICAgICAgIGN0eC5tb3ZlVG8oLi4uc3RhcnQpO1xuICAgICAgICBjdHgubGluZVRvKC4uLmVuZCk7XG4gICAgfSxcblxuICAgIF9kcmF3UXVhZChjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCwgY29ybmVyczogQXJyYXk8P1ZlYzI+KSB7XG4gICAgICAgIERlYnVnLl9kcmF3TGluZShjdHgsIGNvcm5lcnNbMF0sIGNvcm5lcnNbMV0pO1xuICAgICAgICBEZWJ1Zy5fZHJhd0xpbmUoY3R4LCBjb3JuZXJzWzFdLCBjb3JuZXJzWzJdKTtcbiAgICAgICAgRGVidWcuX2RyYXdMaW5lKGN0eCwgY29ybmVyc1syXSwgY29ybmVyc1szXSk7XG4gICAgICAgIERlYnVnLl9kcmF3TGluZShjdHgsIGNvcm5lcnNbM10sIGNvcm5lcnNbMF0pO1xuICAgIH0sXG5cbiAgICBfZHJhd0JveChjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCwgY29ybmVyczogQXJyYXk8P1ZlYzM+KSB7XG4gICAgICAgIGFzc2VydChjb3JuZXJzLmxlbmd0aCA9PT0gOCwgYEFBQkIgbmVlZHMgOCBjb3JuZXJzLCBmb3VuZCAke2Nvcm5lcnMubGVuZ3RofWApO1xuICAgICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICAgIERlYnVnLl9kcmF3UXVhZChjdHgsIGNvcm5lcnMuc2xpY2UoMCwgNCkpO1xuICAgICAgICBEZWJ1Zy5fZHJhd1F1YWQoY3R4LCBjb3JuZXJzLnNsaWNlKDQpKTtcbiAgICAgICAgRGVidWcuX2RyYXdMaW5lKGN0eCwgY29ybmVyc1swXSwgY29ybmVyc1s0XSk7XG4gICAgICAgIERlYnVnLl9kcmF3TGluZShjdHgsIGNvcm5lcnNbMV0sIGNvcm5lcnNbNV0pO1xuICAgICAgICBEZWJ1Zy5fZHJhd0xpbmUoY3R4LCBjb3JuZXJzWzJdLCBjb3JuZXJzWzZdKTtcbiAgICAgICAgRGVidWcuX2RyYXdMaW5lKGN0eCwgY29ybmVyc1szXSwgY29ybmVyc1s3XSk7XG4gICAgICAgIGN0eC5zdHJva2UoKTtcbiAgICB9LFxuXG4gICAgZHJhd0FhYmJzKHBhaW50ZXI6IFBhaW50ZXIsIHNvdXJjZUNhY2hlOiBTb3VyY2VDYWNoZSwgY29vcmRzOiBBcnJheTxPdmVyc2NhbGVkVGlsZUlEPikge1xuICAgICAgICBjb25zdCB0ciA9IHBhaW50ZXIudHJhbnNmb3JtO1xuXG4gICAgICAgIGNvbnN0IHdvcmxkVG9FQ0VGTWF0cml4ID0gbWF0NC5pbnZlcnQobmV3IEZsb2F0NjRBcnJheSgxNiksIHRyLmdsb2JlTWF0cml4KTtcbiAgICAgICAgY29uc3QgZWNlZlRvUGl4ZWxNYXRyaXggPSBtYXQ0Lm11bHRpcGx5KFtdLCB0ci5waXhlbE1hdHJpeCwgdHIuZ2xvYmVNYXRyaXgpO1xuICAgICAgICBjb25zdCBlY2VmVG9DYW1lcmFNYXRyaXggPSBtYXQ0Lm11bHRpcGx5KFtdLCAgdHIuX2NhbWVyYS5nZXRXb3JsZFRvQ2FtZXJhKHRyLndvcmxkU2l6ZSwgMSksIHRyLmdsb2JlTWF0cml4KTtcblxuICAgICAgICBpZiAoIXRyLmZyZWV6ZVRpbGVDb3ZlcmFnZSkge1xuICAgICAgICAgICAgRGVidWcuYWFiYkNvcm5lcnMgPSBjb29yZHMubWFwKGNvb3JkID0+IHtcbiAgICAgICAgICAgICAgICAvLyBHZXQgdGlsZSBBQUJCcyBpbiB3b3JsZC9waXhlbCBzcGFjZSBzY2FsZWQgYnkgd29ybGRTaXplXG4gICAgICAgICAgICAgICAgY29uc3QgYWFiYiA9IGFhYmJGb3JUaWxlT25HbG9iZSh0ciwgdHIud29ybGRTaXplLCBjb29yZC5jYW5vbmljYWwpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvcm5lcnMgPSBhYWJiLmdldENvcm5lcnMoKTtcbiAgICAgICAgICAgICAgICAvLyBTdG9yZSBBQUJCcyBhcyByZWN0YW5ndWxhciBwcmlzbXMgaW4gRUNFRiwgdGhpcyBhbGxvd3Mgdmlld2luZyB0aGVtIGZyb20gb3RoZXIgYW5nbGVzXG4gICAgICAgICAgICAgICAgLy8gd2hlbiB0cmFuc2Zvcm0uZnJlZXplVGlsZUNvdmVyYWdlIGlzIGVuYWJsZWQuXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBwb3Mgb2YgY29ybmVycykge1xuICAgICAgICAgICAgICAgICAgICB2ZWMzLnRyYW5zZm9ybU1hdDQocG9zLCBwb3MsIHdvcmxkVG9FQ0VGTWF0cml4KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtdHlwZV1cbiAgICAgICAgICAgICAgICByZXR1cm4gY29ybmVycztcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY2FudmFzID0gRGVidWcuX2luaXRpYWxpemVDYW52YXModHIpO1xuICAgICAgICBjb25zdCBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICAgICAgY3R4LmNsZWFyUmVjdCgwLCAwLCBjYW52YXMud2lkdGgsIGNhbnZhcy5oZWlnaHQpO1xuXG4gICAgICAgIGNvbnN0IHRpbGVDb3VudCA9IERlYnVnLmFhYmJDb3JuZXJzLmxlbmd0aDtcbiAgICAgICAgY3R4LnNoYWRvd0NvbG9yID0gJyMwMDAnO1xuICAgICAgICBjdHguc2hhZG93Qmx1ciA9IDI7XG4gICAgICAgIGN0eC5saW5lV2lkdGggPSAxLjU7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCAgdGlsZUNvdW50OyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHBpeGVsQ29ybmVycyA9IERlYnVnLmFhYmJDb3JuZXJzW2ldLm1hcChlY2VmID0+IHtcbiAgICAgICAgICAgICAgICAvLyBDbGlwcGluZyB0byBwcmV2ZW50IHZpc3VhbCBhcnRpZmFjdHMuXG4gICAgICAgICAgICAgICAgLy8gV2UgZG9uJ3QgZHJhdyBhbnkgbGluZXMgaWYgb25lIG9mIHRoZWlyIHBvaW50cyBpcyBiZWhpbmQgdGhlIGNhbWVyYS5cbiAgICAgICAgICAgICAgICAvLyBUaGlzIG1lYW5zIHRoYXQgQUFCQnMgY2xvc2UgdG8gdGhlIGNhbWVyYSBtYXkgYXBwZWFyIHRvIGJlIG1pc3NpbmcuXG4gICAgICAgICAgICAgICAgLy8gKEEgbW9yZSBjb3JyZWN0IGFsZ29yaXRobSB3b3VsZCBzaG9ydGVuIHRoZSBsaW5lIHNlZ21lbnRzIGluc3RlYWQgb2YgcmVtb3ZpbmcgdGhlbSBlbnRpcmVseS4pXG4gICAgICAgICAgICAgICAgLy8gRnVsbCBBQUJCcyBjYW4gYmUgdmlld2VkIGJ5IGVuYWJsaW5nIGBtYXAudHJhbnNmb3JtLmZyZWV6ZVRpbGVDb3ZlcmFnZWAgYW5kIHBhbm5pbmcuXG4gICAgICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtY2FsbF1cbiAgICAgICAgICAgICAgICBjb25zdCBjYW1lcmFQb3MgPSB2ZWMzLnRyYW5zZm9ybU1hdDQoW10sIGVjZWYsIGVjZWZUb0NhbWVyYU1hdHJpeCk7XG5cbiAgICAgICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW2luY29tcGF0aWJsZS1jYWxsXVxuICAgICAgICAgICAgICAgIGlmIChjYW1lcmFQb3NbMl0gPiAwKSB7IHJldHVybiBudWxsOyB9XG5cbiAgICAgICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW2luY29tcGF0aWJsZS1jYWxsXVxuICAgICAgICAgICAgICAgIHJldHVybiB2ZWMzLnRyYW5zZm9ybU1hdDQoW10sIGVjZWYsIGVjZWZUb1BpeGVsTWF0cml4KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY3R4LnN0cm9rZVN0eWxlID0gYGhzbCgkezM2MCAqIGkgLyB0aWxlQ291bnR9LCAxMDAlLCA1MCUpYDtcbiAgICAgICAgICAgIERlYnVnLl9kcmF3Qm94KGN0eCwgcGl4ZWxDb3JuZXJzKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBjbGVhckFhYmJzKCkge1xuICAgICAgICBpZiAoIURlYnVnLmRlYnVnQ2FudmFzKSByZXR1cm47XG4gICAgICAgIC8vICRGbG93Rml4TWVbaW5jb21wYXRpYmxlLXVzZV0gLSBGbG93IGRvZXNuJ3Qga25vdyB0aGF0IGRlYnVnQ2FudmFzIGlzIG5vbi1udWxsIGhlcmVcbiAgICAgICAgRGVidWcuZGVidWdDYW52YXMuZ2V0Q29udGV4dCgnMmQnKS5jbGVhclJlY3QoMCwgMCwgRGVidWcuZGVidWdDYW52YXMud2lkdGgsIERlYnVnLmRlYnVnQ2FudmFzLmhlaWdodCk7XG4gICAgICAgIERlYnVnLmFhYmJDb3JuZXJzID0gW107XG4gICAgfVxufTtcbiIsIi8vIEBmbG93XG5pbXBvcnQge1Bvc0FycmF5LCBMaW5lU3RyaXBJbmRleEFycmF5fSBmcm9tIFwiLi9hcnJheV90eXBlcy5qc1wiO1xuaW1wb3J0IFNlZ21lbnRWZWN0b3IgZnJvbSBcIi4vc2VnbWVudC5qc1wiO1xuaW1wb3J0IHBvc0F0dHJpYnV0ZXMgZnJvbSAnLi9wb3NfYXR0cmlidXRlcy5qcyc7XG5pbXBvcnQgQ29sb3IgZnJvbSBcIi4uL3N0eWxlLXNwZWMvdXRpbC9jb2xvci5qc1wiO1xuXG5pbXBvcnQgdHlwZSBWZXJ0ZXhCdWZmZXIgZnJvbSBcIi4uL2dsL3ZlcnRleF9idWZmZXIuanNcIjtcbmltcG9ydCB0eXBlIEluZGV4QnVmZmVyIGZyb20gXCIuLi9nbC9pbmRleF9idWZmZXIuanNcIjtcbmltcG9ydCB0eXBlIFBvaW50IGZyb20gJ0BtYXBib3gvcG9pbnQtZ2VvbWV0cnknO1xuaW1wb3J0IHR5cGUgQ29udGV4dCBmcm9tIFwiLi4vZ2wvY29udGV4dC5qc1wiO1xuXG4vKipcbiAqIEhlbHBlciBjbGFzcyB0aGF0IGNhbiBiZSB1c2VkIHRvIGRyYXcgZGVidWcgZ2VvbWV0cnkgaW4gdGlsZS1zcGFjZVxuICpcbiAqIEBjbGFzcyBUaWxlU3BhY2VEZWJ1Z0J1ZmZlclxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGNsYXNzIFRpbGVTcGFjZURlYnVnQnVmZmVyIHtcbiAgICB2ZXJ0aWNlczogUG9zQXJyYXk7XG4gICAgaW5kaWNlczogTGluZVN0cmlwSW5kZXhBcnJheTtcbiAgICB0aWxlU2l6ZTogbnVtYmVyO1xuICAgIG5lZWRzVXBsb2FkOiBib29sZWFuO1xuICAgIGNvbG9yOiBDb2xvcjtcblxuICAgIHZlcnRleEJ1ZmZlcjogP1ZlcnRleEJ1ZmZlcjtcbiAgICBpbmRleEJ1ZmZlcjogP0luZGV4QnVmZmVyO1xuICAgIHNlZ21lbnRzOiA/U2VnbWVudFZlY3RvcjtcblxuICAgIGNvbnN0cnVjdG9yKHRpbGVTaXplOiBudW1iZXIsIGNvbG9yOiBDb2xvciA9IENvbG9yLnJlZCkge1xuICAgICAgICB0aGlzLnZlcnRpY2VzID0gbmV3IFBvc0FycmF5KCk7XG4gICAgICAgIHRoaXMuaW5kaWNlcyA9IG5ldyBMaW5lU3RyaXBJbmRleEFycmF5KCk7XG4gICAgICAgIHRoaXMudGlsZVNpemUgPSB0aWxlU2l6ZTtcbiAgICAgICAgdGhpcy5uZWVkc1VwbG9hZCA9IHRydWU7XG4gICAgICAgIHRoaXMuY29sb3IgPSBjb2xvcjtcbiAgICB9XG5cbiAgICBhZGRQb2ludHMocG9pbnRzOiBQb2ludFtdKSB7XG4gICAgICAgIHRoaXMuY2xlYXJQb2ludHMoKTtcbiAgICAgICAgZm9yIChjb25zdCBwb2ludCBvZiBwb2ludHMpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkUG9pbnQocG9pbnQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuYWRkUG9pbnQocG9pbnRzWzBdKTtcbiAgICB9XG5cbiAgICBhZGRQb2ludChwOiBQb2ludCkge1xuICAgICAgICAvLyBBZGQgYSBib3d0aWUgc2hhcGVcbiAgICAgICAgY29uc3QgY3Jvc3NoYWlyU2l6ZSA9IDgwO1xuICAgICAgICBjb25zdCBjdXJyTGluZUxpbmVMZW5ndGggPSB0aGlzLnZlcnRpY2VzLmxlbmd0aDtcbiAgICAgICAgdGhpcy52ZXJ0aWNlcy5lbXBsYWNlQmFjayhwLngsIHAueSk7XG4gICAgICAgIHRoaXMudmVydGljZXMuZW1wbGFjZUJhY2socC54ICsgY3Jvc3NoYWlyU2l6ZSAvIDIsIHAueSk7XG4gICAgICAgIHRoaXMudmVydGljZXMuZW1wbGFjZUJhY2socC54LCBwLnkgLSBjcm9zc2hhaXJTaXplIC8gMik7XG4gICAgICAgIHRoaXMudmVydGljZXMuZW1wbGFjZUJhY2socC54LCBwLnkgKyBjcm9zc2hhaXJTaXplIC8gMik7XG4gICAgICAgIHRoaXMudmVydGljZXMuZW1wbGFjZUJhY2socC54IC0gY3Jvc3NoYWlyU2l6ZSAvIDIsIHAueSk7XG4gICAgICAgIHRoaXMuaW5kaWNlcy5lbXBsYWNlQmFjayhjdXJyTGluZUxpbmVMZW5ndGgpO1xuICAgICAgICB0aGlzLmluZGljZXMuZW1wbGFjZUJhY2soY3VyckxpbmVMaW5lTGVuZ3RoICsgMSk7XG4gICAgICAgIHRoaXMuaW5kaWNlcy5lbXBsYWNlQmFjayhjdXJyTGluZUxpbmVMZW5ndGggKyAyKTtcbiAgICAgICAgdGhpcy5pbmRpY2VzLmVtcGxhY2VCYWNrKGN1cnJMaW5lTGluZUxlbmd0aCArIDMpO1xuICAgICAgICB0aGlzLmluZGljZXMuZW1wbGFjZUJhY2soY3VyckxpbmVMaW5lTGVuZ3RoICsgNCk7XG4gICAgICAgIHRoaXMuaW5kaWNlcy5lbXBsYWNlQmFjayhjdXJyTGluZUxpbmVMZW5ndGgpO1xuXG4gICAgICAgIHRoaXMubmVlZHNVcGxvYWQgPSB0cnVlO1xuICAgIH1cblxuICAgIGNsZWFyUG9pbnRzKCkge1xuICAgICAgICB0aGlzLnZlcnRpY2VzLmNsZWFyKCk7XG4gICAgICAgIHRoaXMuaW5kaWNlcy5jbGVhcigpO1xuICAgICAgICB0aGlzLm5lZWRzVXBsb2FkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBsYXp5VXBsb2FkKGNvbnRleHQ6IENvbnRleHQpIHtcbiAgICAgICAgaWYgKHRoaXMubmVlZHNVcGxvYWQgJiYgdGhpcy5oYXNWZXJ0aWNlcygpKSB7XG4gICAgICAgICAgICB0aGlzLnVubG9hZCgpO1xuXG4gICAgICAgICAgICB0aGlzLnZlcnRleEJ1ZmZlciA9IGNvbnRleHQuY3JlYXRlVmVydGV4QnVmZmVyKHRoaXMudmVydGljZXMsIHBvc0F0dHJpYnV0ZXMubWVtYmVycywgdHJ1ZSk7XG4gICAgICAgICAgICB0aGlzLmluZGV4QnVmZmVyID0gY29udGV4dC5jcmVhdGVJbmRleEJ1ZmZlcih0aGlzLmluZGljZXMsIHRydWUpO1xuICAgICAgICAgICAgdGhpcy5zZWdtZW50cyA9IFNlZ21lbnRWZWN0b3Iuc2ltcGxlU2VnbWVudCgwLCAwLCB0aGlzLnZlcnRpY2VzLmxlbmd0aCwgdGhpcy5pbmRpY2VzLmxlbmd0aCk7XG4gICAgICAgICAgICB0aGlzLm5lZWRzVXBsb2FkID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBoYXNWZXJ0aWNlcygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmVydGljZXMubGVuZ3RoID4gMTtcbiAgICB9XG5cbiAgICB1bmxvYWQoKSB7XG4gICAgICAgIGlmICh0aGlzLnZlcnRleEJ1ZmZlcikge1xuICAgICAgICAgICAgdGhpcy52ZXJ0ZXhCdWZmZXIuZGVzdHJveSgpO1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMudmVydGV4QnVmZmVyO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmluZGV4QnVmZmVyKSB7XG4gICAgICAgICAgICB0aGlzLmluZGV4QnVmZmVyLmRlc3Ryb3koKTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmluZGV4QnVmZmVyO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnNlZ21lbnRzKSB7XG4gICAgICAgICAgICB0aGlzLnNlZ21lbnRzLmRlc3Ryb3koKTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNlZ21lbnRzO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiLy8gQGZsb3dcbi8vIGxvZ2ljIGZvciBnZW5lcmF0aW5nIG5vbi1NZXJjYXRvciBhZGFwdGl2ZSByYXN0ZXIgdGlsZSByZXByb2plY3Rpb24gbWVzaGVzIHdpdGggTUFSVElOSVxuXG5pbXBvcnQgdGlsZVRyYW5zZm9ybSBmcm9tICcuLi9nZW8vcHJvamVjdGlvbi90aWxlX3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQgRVhURU5UIGZyb20gJy4uL2RhdGEvZXh0ZW50LmpzJztcbmltcG9ydCB7bG5nRnJvbU1lcmNhdG9yWCwgbGF0RnJvbU1lcmNhdG9yWX0gZnJvbSAnLi4vZ2VvL21lcmNhdG9yX2Nvb3JkaW5hdGUuanMnO1xuaW1wb3J0IHtUaWxlQm91bmRzQXJyYXksIFRyaWFuZ2xlSW5kZXhBcnJheX0gZnJvbSAnLi4vZGF0YS9hcnJheV90eXBlcy5qcyc7XG5cbmltcG9ydCB0eXBlIHtDYW5vbmljYWxUaWxlSUR9IGZyb20gJy4vdGlsZV9pZC5qcyc7XG5pbXBvcnQgdHlwZSBQcm9qZWN0aW9uIGZyb20gJy4uL2dlby9wcm9qZWN0aW9uL3Byb2plY3Rpb24uanMnO1xuXG5jb25zdCBtZXNoU2l6ZSA9IDMyO1xuY29uc3QgZ3JpZFNpemUgPSBtZXNoU2l6ZSArIDE7XG5cbmNvbnN0IG51bVRyaWFuZ2xlcyA9IG1lc2hTaXplICogbWVzaFNpemUgKiAyIC0gMjtcbmNvbnN0IG51bVBhcmVudFRyaWFuZ2xlcyA9IG51bVRyaWFuZ2xlcyAtIG1lc2hTaXplICogbWVzaFNpemU7XG5cbmNvbnN0IGNvb3JkcyA9IG5ldyBVaW50MTZBcnJheShudW1UcmlhbmdsZXMgKiA0KTtcblxuLy8gcHJlY2FsY3VsYXRlIFJUSU4gdHJpYW5nbGUgY29vcmRpbmF0ZXNcbmZvciAobGV0IGkgPSAwOyBpIDwgbnVtVHJpYW5nbGVzOyBpKyspIHtcbiAgICBsZXQgaWQgPSBpICsgMjtcbiAgICBsZXQgYXggPSAwLCBheSA9IDAsIGJ4ID0gMCwgYnkgPSAwLCBjeCA9IDAsIGN5ID0gMDtcblxuICAgIGlmIChpZCAmIDEpIHtcbiAgICAgICAgYnggPSBieSA9IGN4ID0gbWVzaFNpemU7IC8vIGJvdHRvbS1sZWZ0IHRyaWFuZ2xlXG5cbiAgICB9IGVsc2Uge1xuICAgICAgICBheCA9IGF5ID0gY3kgPSBtZXNoU2l6ZTsgLy8gdG9wLXJpZ2h0IHRyaWFuZ2xlXG4gICAgfVxuXG4gICAgd2hpbGUgKChpZCA+Pj0gMSkgPiAxKSB7XG4gICAgICAgIGNvbnN0IG14ID0gKGF4ICsgYngpID4+IDE7XG4gICAgICAgIGNvbnN0IG15ID0gKGF5ICsgYnkpID4+IDE7XG5cbiAgICAgICAgaWYgKGlkICYgMSkgeyAvLyBsZWZ0IGhhbGZcbiAgICAgICAgICAgIGJ4ID0gYXg7IGJ5ID0gYXk7XG4gICAgICAgICAgICBheCA9IGN4OyBheSA9IGN5O1xuXG4gICAgICAgIH0gZWxzZSB7IC8vIHJpZ2h0IGhhbGZcbiAgICAgICAgICAgIGF4ID0gYng7IGF5ID0gYnk7XG4gICAgICAgICAgICBieCA9IGN4OyBieSA9IGN5O1xuICAgICAgICB9XG5cbiAgICAgICAgY3ggPSBteDsgY3kgPSBteTtcbiAgICB9XG5cbiAgICBjb25zdCBrID0gaSAqIDQ7XG4gICAgY29vcmRzW2sgKyAwXSA9IGF4O1xuICAgIGNvb3Jkc1trICsgMV0gPSBheTtcbiAgICBjb29yZHNbayArIDJdID0gYng7XG4gICAgY29vcmRzW2sgKyAzXSA9IGJ5O1xufVxuXG4vLyB0ZW1wb3JhcnkgYXJyYXlzIHdlJ2xsIHJldXNlIGZvciBNQVJUSU5JIG1lc2ggY29kZVxuY29uc3QgcmVwcm9qZWN0ZWRDb29yZHMgPSBuZXcgVWludDE2QXJyYXkoZ3JpZFNpemUgKiBncmlkU2l6ZSAqIDIpO1xuY29uc3QgdXNlZCA9IG5ldyBVaW50OEFycmF5KGdyaWRTaXplICogZ3JpZFNpemUpO1xuY29uc3QgaW5kZXhNYXAgPSBuZXcgVWludDE2QXJyYXkoZ3JpZFNpemUgKiBncmlkU2l6ZSk7XG5cbnR5cGUgVGlsZU1lc2ggPSB7XG4gICAgdmVydGljZXM6IFRpbGVCb3VuZHNBcnJheSxcbiAgICBpbmRpY2VzOiBUcmlhbmdsZUluZGV4QXJyYXlcbn07XG5cbi8vIFRoZXJlIGNhbiBiZSB2aXNpYmxlIHNlYW1zIGJldHdlZW4gbmVpZ2hib3VyaW5nIHRpbGVzIGJlY2F1c2Ugb2YgcHJlY2lzaW9uIGlzc3Vlc1xuLy8gYW5kIHJlc2FtcGxpbmcgZGlmZmVyZW5jZXMuIEFkZGluZyBhIGJpdCBvZiBwYWRkaW5nIGFyb3VuZCB0aGUgZWRnZXMgb2YgdGlsZXMgaGlkZXNcbi8vIG1vc3Qgb2YgdGhlc2UgaXNzdWVzLlxuY29uc3QgY29tbW9uUmFzdGVyVGlsZVNpemUgPSAyNTY7XG5jb25zdCBwYWRkaW5nU2l6ZSA9IG1lc2hTaXplIC8gY29tbW9uUmFzdGVyVGlsZVNpemUgLyA0O1xuZnVuY3Rpb24gc2VhbVBhZGRpbmcobjogbnVtYmVyKSB7XG4gICAgaWYgKG4gPT09IDApIHJldHVybiAtcGFkZGluZ1NpemU7XG4gICAgZWxzZSBpZiAobiA9PT0gZ3JpZFNpemUgLSAxKSByZXR1cm4gcGFkZGluZ1NpemU7XG4gICAgZWxzZSByZXR1cm4gMDtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0VGlsZU1lc2goY2Fub25pY2FsOiBDYW5vbmljYWxUaWxlSUQsIHByb2plY3Rpb246IFByb2plY3Rpb24pOiBUaWxlTWVzaCB7XG4gICAgY29uc3QgY3MgPSB0aWxlVHJhbnNmb3JtKGNhbm9uaWNhbCwgcHJvamVjdGlvbik7XG4gICAgY29uc3QgejIgPSBNYXRoLnBvdygyLCBjYW5vbmljYWwueik7XG5cbiAgICBmb3IgKGxldCB5ID0gMDsgeSA8IGdyaWRTaXplOyB5KyspIHtcbiAgICAgICAgZm9yIChsZXQgeCA9IDA7IHggPCBncmlkU2l6ZTsgeCsrKSB7XG4gICAgICAgICAgICBjb25zdCBsbmcgPSBsbmdGcm9tTWVyY2F0b3JYKChjYW5vbmljYWwueCArICh4ICsgc2VhbVBhZGRpbmcoeCkpIC8gbWVzaFNpemUpIC8gejIpO1xuICAgICAgICAgICAgY29uc3QgbGF0ID0gbGF0RnJvbU1lcmNhdG9yWSgoY2Fub25pY2FsLnkgKyAoeSArIHNlYW1QYWRkaW5nKHkpKSAvIG1lc2hTaXplKSAvIHoyKTtcbiAgICAgICAgICAgIGNvbnN0IHAgPSBwcm9qZWN0aW9uLnByb2plY3QobG5nLCBsYXQpO1xuICAgICAgICAgICAgY29uc3QgayA9IHkgKiBncmlkU2l6ZSArIHg7XG4gICAgICAgICAgICByZXByb2plY3RlZENvb3Jkc1syICogayArIDBdID0gTWF0aC5yb3VuZCgocC54ICogY3Muc2NhbGUgLSBjcy54KSAqIEVYVEVOVCk7XG4gICAgICAgICAgICByZXByb2plY3RlZENvb3Jkc1syICogayArIDFdID0gTWF0aC5yb3VuZCgocC55ICogY3Muc2NhbGUgLSBjcy55KSAqIEVYVEVOVCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB1c2VkLmZpbGwoMCk7XG4gICAgaW5kZXhNYXAuZmlsbCgwKTtcblxuICAgIC8vIGl0ZXJhdGUgb3ZlciBhbGwgcG9zc2libGUgdHJpYW5nbGVzLCBzdGFydGluZyBmcm9tIHRoZSBzbWFsbGVzdCBsZXZlbFxuICAgIGZvciAobGV0IGkgPSBudW1UcmlhbmdsZXMgLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBjb25zdCBrID0gaSAqIDQ7XG4gICAgICAgIGNvbnN0IGF4ID0gY29vcmRzW2sgKyAwXTtcbiAgICAgICAgY29uc3QgYXkgPSBjb29yZHNbayArIDFdO1xuICAgICAgICBjb25zdCBieCA9IGNvb3Jkc1trICsgMl07XG4gICAgICAgIGNvbnN0IGJ5ID0gY29vcmRzW2sgKyAzXTtcbiAgICAgICAgY29uc3QgbXggPSAoYXggKyBieCkgPj4gMTtcbiAgICAgICAgY29uc3QgbXkgPSAoYXkgKyBieSkgPj4gMTtcbiAgICAgICAgY29uc3QgY3ggPSBteCArIG15IC0gYXk7XG4gICAgICAgIGNvbnN0IGN5ID0gbXkgKyBheCAtIG14O1xuXG4gICAgICAgIGNvbnN0IGFJbmRleCA9IGF5ICogZ3JpZFNpemUgKyBheDtcbiAgICAgICAgY29uc3QgYkluZGV4ID0gYnkgKiBncmlkU2l6ZSArIGJ4O1xuICAgICAgICBjb25zdCBtSW5kZXggPSBteSAqIGdyaWRTaXplICsgbXg7XG5cbiAgICAgICAgLy8gY2FsY3VsYXRlIGVycm9yIGluIHRoZSBtaWRkbGUgb2YgdGhlIGxvbmcgZWRnZSBvZiB0aGUgdHJpYW5nbGVcbiAgICAgICAgY29uc3QgcmF4ID0gcmVwcm9qZWN0ZWRDb29yZHNbMiAqIGFJbmRleCArIDBdO1xuICAgICAgICBjb25zdCByYXkgPSByZXByb2plY3RlZENvb3Jkc1syICogYUluZGV4ICsgMV07XG4gICAgICAgIGNvbnN0IHJieCA9IHJlcHJvamVjdGVkQ29vcmRzWzIgKiBiSW5kZXggKyAwXTtcbiAgICAgICAgY29uc3QgcmJ5ID0gcmVwcm9qZWN0ZWRDb29yZHNbMiAqIGJJbmRleCArIDFdO1xuICAgICAgICBjb25zdCBybXggPSByZXByb2plY3RlZENvb3Jkc1syICogbUluZGV4ICsgMF07XG4gICAgICAgIGNvbnN0IHJteSA9IHJlcHJvamVjdGVkQ29vcmRzWzIgKiBtSW5kZXggKyAxXTtcblxuICAgICAgICAvLyByYXN0ZXIgdGlsZXMgYXJlIHR5cGljYWxseSA1MTJweCwgYW5kIHdlIHVzZSAxcHggYXMgYW4gZXJyb3IgdGhyZXNob2xkOyA4MTkyIC8gNTEyID0gMTZcbiAgICAgICAgY29uc3QgaXNVc2VkID0gTWF0aC5oeXBvdCgocmF4ICsgcmJ4KSAvIDIgLSBybXgsIChyYXkgKyByYnkpIC8gMiAtIHJteSkgPj0gMTY7XG5cbiAgICAgICAgdXNlZFttSW5kZXhdID0gdXNlZFttSW5kZXhdIHx8IChpc1VzZWQgPyAxIDogMCk7XG5cbiAgICAgICAgaWYgKGkgPCBudW1QYXJlbnRUcmlhbmdsZXMpIHsgLy8gYmlnZ2VyIHRyaWFuZ2xlczsgYWNjdW11bGF0ZSBlcnJvciB3aXRoIGNoaWxkcmVuXG4gICAgICAgICAgICBjb25zdCBsZWZ0Q2hpbGRJbmRleCA9ICgoYXkgKyBjeSkgPj4gMSkgKiBncmlkU2l6ZSArICgoYXggKyBjeCkgPj4gMSk7XG4gICAgICAgICAgICBjb25zdCByaWdodENoaWxkSW5kZXggPSAoKGJ5ICsgY3kpID4+IDEpICogZ3JpZFNpemUgKyAoKGJ4ICsgY3gpID4+IDEpO1xuICAgICAgICAgICAgdXNlZFttSW5kZXhdID0gdXNlZFttSW5kZXhdIHx8IHVzZWRbbGVmdENoaWxkSW5kZXhdIHx8IHVzZWRbcmlnaHRDaGlsZEluZGV4XTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHZlcnRpY2VzID0gbmV3IFRpbGVCb3VuZHNBcnJheSgpO1xuICAgIGNvbnN0IGluZGljZXMgPSBuZXcgVHJpYW5nbGVJbmRleEFycmF5KCk7XG5cbiAgICBsZXQgbnVtVmVydGljZXMgPSAwO1xuXG4gICAgZnVuY3Rpb24gYWRkVmVydGV4KHg6IG51bWJlciwgeTogbnVtYmVyKSB7XG4gICAgICAgIGNvbnN0IGsgPSB5ICogZ3JpZFNpemUgKyB4O1xuXG4gICAgICAgIGlmIChpbmRleE1hcFtrXSA9PT0gMCkge1xuICAgICAgICAgICAgdmVydGljZXMuZW1wbGFjZUJhY2soXG4gICAgICAgICAgICAgICAgcmVwcm9qZWN0ZWRDb29yZHNbMiAqIGsgKyAwXSxcbiAgICAgICAgICAgICAgICByZXByb2plY3RlZENvb3Jkc1syICogayArIDFdLFxuICAgICAgICAgICAgICAgIHggKiBFWFRFTlQgLyBtZXNoU2l6ZSxcbiAgICAgICAgICAgICAgICB5ICogRVhURU5UIC8gbWVzaFNpemUpO1xuXG4gICAgICAgICAgICAvLyBzYXZlIG5ldyB2ZXJ0ZXggaW5kZXggc28gdGhhdCB3ZSBjYW4gcmV1c2UgaXRcbiAgICAgICAgICAgIGluZGV4TWFwW2tdID0gKytudW1WZXJ0aWNlcztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBpbmRleE1hcFtrXSAtIDE7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYWRkVHJpYW5nbGVzKGF4OiBudW1iZXIsIGF5OiBudW1iZXIsIGJ4OiBudW1iZXIsIGJ5OiBudW1iZXIsIGN4OiBudW1iZXIsIGN5OiBudW1iZXIpIHtcbiAgICAgICAgY29uc3QgbXggPSAoYXggKyBieCkgPj4gMTtcbiAgICAgICAgY29uc3QgbXkgPSAoYXkgKyBieSkgPj4gMTtcblxuICAgICAgICBpZiAoTWF0aC5hYnMoYXggLSBjeCkgKyBNYXRoLmFicyhheSAtIGN5KSA+IDEgJiYgdXNlZFtteSAqIGdyaWRTaXplICsgbXhdKSB7XG4gICAgICAgICAgICAvLyB0cmlhbmdsZSBkb2Vzbid0IGFwcHJveGltYXRlIHRoZSBzdXJmYWNlIHdlbGwgZW5vdWdoOyBkcmlsbCBkb3duIGZ1cnRoZXJcbiAgICAgICAgICAgIGFkZFRyaWFuZ2xlcyhjeCwgY3ksIGF4LCBheSwgbXgsIG15KTtcbiAgICAgICAgICAgIGFkZFRyaWFuZ2xlcyhieCwgYnksIGN4LCBjeSwgbXgsIG15KTtcblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgYWkgPSBhZGRWZXJ0ZXgoYXgsIGF5KTtcbiAgICAgICAgICAgIGNvbnN0IGJpID0gYWRkVmVydGV4KGJ4LCBieSk7XG4gICAgICAgICAgICBjb25zdCBjaSA9IGFkZFZlcnRleChjeCwgY3kpO1xuICAgICAgICAgICAgaW5kaWNlcy5lbXBsYWNlQmFjayhhaSwgYmksIGNpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFkZFRyaWFuZ2xlcygwLCAwLCBtZXNoU2l6ZSwgbWVzaFNpemUsIG1lc2hTaXplLCAwKTtcbiAgICBhZGRUcmlhbmdsZXMobWVzaFNpemUsIG1lc2hTaXplLCAwLCAwLCAwLCBtZXNoU2l6ZSk7XG5cbiAgICByZXR1cm4ge3ZlcnRpY2VzLCBpbmRpY2VzfTtcbn1cbiIsIi8vIEBmbG93XG5pbXBvcnQge2NyZWF0ZUxheW91dH0gZnJvbSAnLi4vdXRpbC9zdHJ1Y3RfYXJyYXkuanMnO1xuXG5pbXBvcnQgdHlwZSB7U3RydWN0QXJyYXlMYXlvdXR9IGZyb20gJy4uL3V0aWwvc3RydWN0X2FycmF5LmpzJztcblxuZXhwb3J0IGRlZmF1bHQgKGNyZWF0ZUxheW91dChbXG4gICAge25hbWU6ICdhX3BvcycsIHR5cGU6ICdJbnQxNicsIGNvbXBvbmVudHM6IDJ9LFxuICAgIHtuYW1lOiAnYV90ZXh0dXJlX3BvcycsIHR5cGU6ICdJbnQxNicsIGNvbXBvbmVudHM6IDJ9XG5dKTogU3RydWN0QXJyYXlMYXlvdXQpO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHt1bmlxdWVJZCwgcGFyc2VDYWNoZUNvbnRyb2x9IGZyb20gJy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQge2Rlc2VyaWFsaXplIGFzIGRlc2VyaWFsaXplQnVja2V0fSBmcm9tICcuLi9kYXRhL2J1Y2tldC5qcyc7XG5pbXBvcnQgRmVhdHVyZUluZGV4IGZyb20gJy4uL2RhdGEvZmVhdHVyZV9pbmRleC5qcyc7XG5pbXBvcnQgR2VvSlNPTkZlYXR1cmUgZnJvbSAnLi4vdXRpbC92ZWN0b3J0aWxlX3RvX2dlb2pzb24uanMnO1xuaW1wb3J0IGZlYXR1cmVGaWx0ZXIgZnJvbSAnLi4vc3R5bGUtc3BlYy9mZWF0dXJlX2ZpbHRlci9pbmRleC5qcyc7XG5pbXBvcnQgU3ltYm9sQnVja2V0IGZyb20gJy4uL2RhdGEvYnVja2V0L3N5bWJvbF9idWNrZXQuanMnO1xuaW1wb3J0IEZpbGxCdWNrZXQgZnJvbSAnLi4vZGF0YS9idWNrZXQvZmlsbF9idWNrZXQuanMnO1xuaW1wb3J0IExpbmVCdWNrZXQgZnJvbSAnLi4vZGF0YS9idWNrZXQvbGluZV9idWNrZXQuanMnO1xuaW1wb3J0IHtDb2xsaXNpb25Cb3hBcnJheSwgVGlsZUJvdW5kc0FycmF5LCBQb3NBcnJheSwgVHJpYW5nbGVJbmRleEFycmF5LCBMaW5lU3RyaXBJbmRleEFycmF5LCBQb3NHbG9iZUV4dEFycmF5fSBmcm9tICcuLi9kYXRhL2FycmF5X3R5cGVzLmpzJztcbmltcG9ydCBUZXh0dXJlIGZyb20gJy4uL3JlbmRlci90ZXh0dXJlLmpzJztcbmltcG9ydCBicm93c2VyIGZyb20gJy4uL3V0aWwvYnJvd3Nlci5qcyc7XG5pbXBvcnQge0RlYnVnfSBmcm9tICcuLi91dGlsL2RlYnVnLmpzJztcbmltcG9ydCB0b0V2YWx1YXRpb25GZWF0dXJlIGZyb20gJy4uL2RhdGEvZXZhbHVhdGlvbl9mZWF0dXJlLmpzJztcbmltcG9ydCBFdmFsdWF0aW9uUGFyYW1ldGVycyBmcm9tICcuLi9zdHlsZS9ldmFsdWF0aW9uX3BhcmFtZXRlcnMuanMnO1xuaW1wb3J0IFNvdXJjZUZlYXR1cmVTdGF0ZSBmcm9tICcuLi9zb3VyY2Uvc291cmNlX3N0YXRlLmpzJztcbmltcG9ydCB7bGF6eUxvYWRSVExUZXh0UGx1Z2lufSBmcm9tICcuL3J0bF90ZXh0X3BsdWdpbi5qcyc7XG5pbXBvcnQge1RpbGVTcGFjZURlYnVnQnVmZmVyfSBmcm9tICcuLi9kYXRhL2RlYnVnX3Zpei5qcyc7XG5pbXBvcnQgQ29sb3IgZnJvbSAnLi4vc3R5bGUtc3BlYy91dGlsL2NvbG9yLmpzJztcbmltcG9ydCBsb2FkR2VvbWV0cnkgZnJvbSAnLi4vZGF0YS9sb2FkX2dlb21ldHJ5LmpzJztcbmltcG9ydCBlYXJjdXQgZnJvbSAnZWFyY3V0JztcbmltcG9ydCBnZXRUaWxlTWVzaCBmcm9tICcuL3RpbGVfbWVzaC5qcyc7XG5pbXBvcnQgdGlsZVRyYW5zZm9ybSBmcm9tICcuLi9nZW8vcHJvamVjdGlvbi90aWxlX3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQge21lcmNhdG9yWGZyb21MbmcsIG1lcmNhdG9yWWZyb21MYXR9IGZyb20gJy4uL2dlby9tZXJjYXRvcl9jb29yZGluYXRlLmpzJztcbmltcG9ydCBib3VuZHNBdHRyaWJ1dGVzIGZyb20gJy4uL2RhdGEvYm91bmRzX2F0dHJpYnV0ZXMuanMnO1xuaW1wb3J0IHBvc0F0dHJpYnV0ZXMsIHtwb3NBdHRyaWJ1dGVzR2xvYmVFeHR9IGZyb20gJy4uL2RhdGEvcG9zX2F0dHJpYnV0ZXMuanMnO1xuaW1wb3J0IEVYVEVOVCBmcm9tICcuLi9kYXRhL2V4dGVudC5qcyc7XG5pbXBvcnQgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5pbXBvcnQgU2VnbWVudFZlY3RvciBmcm9tICcuLi9kYXRhL3NlZ21lbnQuanMnO1xuaW1wb3J0IHt0cmFuc2l0aW9uVGlsZUFBQkJpbkVDRUYsIGdsb2JlTm9ybWFsaXplRUNFRiwgdGlsZUNvb3JkVG9FQ0VGLCBnbG9iZVRvTWVyY2F0b3JUcmFuc2l0aW9uLCBpbnRlcnBvbGF0ZVZlYzN9IGZyb20gJy4uL2dlby9wcm9qZWN0aW9uL2dsb2JlX3V0aWwuanMnO1xuaW1wb3J0IHt2ZWMzLCBtYXQ0fSBmcm9tICdnbC1tYXRyaXgnO1xuXG5pbXBvcnQgdHlwZSB7QnVja2V0fSBmcm9tICcuLi9kYXRhL2J1Y2tldC5qcyc7XG5pbXBvcnQgdHlwZSBTdHlsZUxheWVyIGZyb20gJy4uL3N0eWxlL3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCB0eXBlIHtXb3JrZXJUaWxlUmVzdWx0fSBmcm9tICcuL3dvcmtlcl9zb3VyY2UuanMnO1xuaW1wb3J0IHR5cGUgQWN0b3IgZnJvbSAnLi4vdXRpbC9hY3Rvci5qcyc7XG5pbXBvcnQgdHlwZSBERU1EYXRhIGZyb20gJy4uL2RhdGEvZGVtX2RhdGEuanMnO1xuaW1wb3J0IHR5cGUge0FscGhhSW1hZ2UsIFNwcml0ZVBvc2l0aW9uc30gZnJvbSAnLi4vdXRpbC9pbWFnZS5qcyc7XG5pbXBvcnQgdHlwZSBJbWFnZUF0bGFzIGZyb20gJy4uL3JlbmRlci9pbWFnZV9hdGxhcy5qcyc7XG5pbXBvcnQgdHlwZSBMaW5lQXRsYXMgZnJvbSAnLi4vcmVuZGVyL2xpbmVfYXRsYXMuanMnO1xuaW1wb3J0IHR5cGUgSW1hZ2VNYW5hZ2VyIGZyb20gJy4uL3JlbmRlci9pbWFnZV9tYW5hZ2VyLmpzJztcbmltcG9ydCB0eXBlIENvbnRleHQgZnJvbSAnLi4vZ2wvY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSB7Q2Fub25pY2FsVGlsZUlELCBPdmVyc2NhbGVkVGlsZUlEfSBmcm9tICcuL3RpbGVfaWQuanMnO1xuaW1wb3J0IHR5cGUgRnJhbWVidWZmZXIgZnJvbSAnLi4vZ2wvZnJhbWVidWZmZXIuanMnO1xuaW1wb3J0IHR5cGUgVHJhbnNmb3JtIGZyb20gJy4uL2dlby90cmFuc2Zvcm0uanMnO1xuaW1wb3J0IHR5cGUge0xheWVyRmVhdHVyZVN0YXRlc30gZnJvbSAnLi9zb3VyY2Vfc3RhdGUuanMnO1xuaW1wb3J0IHR5cGUge0NhbmNlbGFibGV9IGZyb20gJy4uL3R5cGVzL2NhbmNlbGFibGUuanMnO1xuaW1wb3J0IHR5cGUge0ZpbHRlclNwZWNpZmljYXRpb259IGZyb20gJy4uL3N0eWxlLXNwZWMvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge1RpbGVzcGFjZVF1ZXJ5R2VvbWV0cnl9IGZyb20gJy4uL3N0eWxlL3F1ZXJ5X2dlb21ldHJ5LmpzJztcbmltcG9ydCB0eXBlIFZlcnRleEJ1ZmZlciBmcm9tICcuLi9nbC92ZXJ0ZXhfYnVmZmVyLmpzJztcbmltcG9ydCB0eXBlIEluZGV4QnVmZmVyIGZyb20gJy4uL2dsL2luZGV4X2J1ZmZlci5qcyc7XG5pbXBvcnQgdHlwZSBQcm9qZWN0aW9uIGZyb20gJy4uL2dlby9wcm9qZWN0aW9uL3Byb2plY3Rpb24uanMnO1xuaW1wb3J0IHR5cGUge1RpbGVUcmFuc2Zvcm19IGZyb20gJy4uL2dlby9wcm9qZWN0aW9uL3RpbGVfdHJhbnNmb3JtLmpzJztcbmltcG9ydCB0eXBlIHtRdWVyeVJlc3VsdH0gZnJvbSAnLi4vZGF0YS9mZWF0dXJlX2luZGV4LmpzJztcbmltcG9ydCB0eXBlIFBhaW50ZXIgZnJvbSAnLi4vcmVuZGVyL3BhaW50ZXIuanMnO1xuaW1wb3J0IHR5cGUge1F1ZXJ5RmVhdHVyZX0gZnJvbSAnLi4vdXRpbC92ZWN0b3J0aWxlX3RvX2dlb2pzb24uanMnO1xuaW1wb3J0IHR5cGUge1ZlYzN9IGZyb20gJ2dsLW1hdHJpeCc7XG5pbXBvcnQgdHlwZSB7VGV4dHVyZUltYWdlfSBmcm9tICcuLi9yZW5kZXIvdGV4dHVyZS5qcyc7XG5pbXBvcnQgdHlwZSB7VmVjdG9yVGlsZUxheWVyfSBmcm9tICdAbWFwYm94L3ZlY3Rvci10aWxlJztcblxuY29uc3QgQ0xPQ0tfU0tFV19SRVRSWV9USU1FT1VUID0gMzAwMDA7XG5leHBvcnQgdHlwZSBUaWxlU3RhdGUgPVxuICAgIHwgJ2xvYWRpbmcnICAgLy8gVGlsZSBkYXRhIGlzIGluIHRoZSBwcm9jZXNzIG9mIGxvYWRpbmcuXG4gICAgfCAnbG9hZGVkJyAgICAvLyBUaWxlIGRhdGEgaGFzIGJlZW4gbG9hZGVkLiBUaWxlIGNhbiBiZSByZW5kZXJlZC5cbiAgICB8ICdyZWxvYWRpbmcnIC8vIFRpbGUgZGF0YSBoYXMgYmVlbiBsb2FkZWQgYW5kIGlzIGJlaW5nIHVwZGF0ZWQuIFRpbGUgY2FuIGJlIHJlbmRlcmVkLlxuICAgIHwgJ3VubG9hZGVkJyAgLy8gVGlsZSBkYXRhIGhhcyBiZWVuIGRlbGV0ZWQuXG4gICAgfCAnZXJyb3JlZCcgICAvLyBUaWxlIGRhdGEgd2FzIG5vdCBsb2FkZWQgYmVjYXVzZSBvZiBhbiBlcnJvci5cbiAgICB8ICdleHBpcmVkJzsgIC8qIFRpbGUgZGF0YSB3YXMgcHJldmlvdXNseSBsb2FkZWQsIGJ1dCBoYXMgZXhwaXJlZCBwZXIgaXRzXG4gICAgICAgICAgICAgICAgICAgKiBIVFRQIGhlYWRlcnMgYW5kIGlzIGluIHRoZSBwcm9jZXNzIG9mIHJlZnJlc2hpbmcuICovXG5cbi8vIGEgdGlsZSBib3VuZHMgb3V0bGluZSB1c2VkIGZvciBnZXR0aW5nIHJlcHJvamVjdGVkIHRpbGUgZ2VvbWV0cnkgaW4gbm9uLW1lcmNhdG9yIHByb2plY3Rpb25zXG5jb25zdCBCT1VORFNfRkVBVFVSRSA9ICgoKSA9PiB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogMixcbiAgICAgICAgZXh0ZW50OiBFWFRFTlQsXG4gICAgICAgIGxvYWRHZW9tZXRyeSgpIHtcbiAgICAgICAgICAgIHJldHVybiBbW1xuICAgICAgICAgICAgICAgIG5ldyBQb2ludCgwLCAwKSxcbiAgICAgICAgICAgICAgICBuZXcgUG9pbnQoRVhURU5UICsgMSwgMCksXG4gICAgICAgICAgICAgICAgbmV3IFBvaW50KEVYVEVOVCArIDEsIEVYVEVOVCArIDEpLFxuICAgICAgICAgICAgICAgIG5ldyBQb2ludCgwLCBFWFRFTlQgKyAxKSxcbiAgICAgICAgICAgICAgICBuZXcgUG9pbnQoMCwgMClcbiAgICAgICAgICAgIF1dO1xuICAgICAgICB9XG4gICAgfTtcbn0pKCk7XG5cbi8qKlxuICogQSB0aWxlIG9iamVjdCBpcyB0aGUgY29tYmluYXRpb24gb2YgYSBDb29yZGluYXRlLCB3aGljaCBkZWZpbmVzXG4gKiBpdHMgcGxhY2UsIGFzIHdlbGwgYXMgYSB1bmlxdWUgSUQgYW5kIGRhdGEgdHJhY2tpbmcgZm9yIGl0cyBjb250ZW50XG4gKlxuICogQHByaXZhdGVcbiAqL1xuY2xhc3MgVGlsZSB7XG4gICAgdGlsZUlEOiBPdmVyc2NhbGVkVGlsZUlEO1xuICAgIHVpZDogbnVtYmVyO1xuICAgIHVzZXM6IG51bWJlcjtcbiAgICB0aWxlU2l6ZTogbnVtYmVyO1xuICAgIHRpbGVab29tOiBudW1iZXI7XG4gICAgYnVja2V0czoge1tfOiBzdHJpbmddOiBCdWNrZXR9O1xuICAgIGxhdGVzdEZlYXR1cmVJbmRleDogP0ZlYXR1cmVJbmRleDtcbiAgICBsYXRlc3RSYXdUaWxlRGF0YTogP0FycmF5QnVmZmVyO1xuICAgIGltYWdlQXRsYXM6ID9JbWFnZUF0bGFzO1xuICAgIGltYWdlQXRsYXNUZXh0dXJlOiBUZXh0dXJlO1xuICAgIGxpbmVBdGxhczogP0xpbmVBdGxhcztcbiAgICBsaW5lQXRsYXNUZXh0dXJlOiBUZXh0dXJlO1xuICAgIGdseXBoQXRsYXNJbWFnZTogP0FscGhhSW1hZ2U7XG4gICAgZ2x5cGhBdGxhc1RleHR1cmU6IFRleHR1cmU7XG4gICAgZXhwaXJhdGlvblRpbWU6IGFueTtcbiAgICBleHBpcmVkUmVxdWVzdENvdW50OiBudW1iZXI7XG4gICAgc3RhdGU6IFRpbGVTdGF0ZTtcbiAgICB0aW1lQWRkZWQ6IGFueTtcbiAgICBmYWRlRW5kVGltZTogYW55O1xuICAgIGNvbGxpc2lvbkJveEFycmF5OiA/Q29sbGlzaW9uQm94QXJyYXk7XG4gICAgcmVkb1doZW5Eb25lOiBib29sZWFuO1xuICAgIHNob3dDb2xsaXNpb25Cb3hlczogYm9vbGVhbjtcbiAgICBwbGFjZW1lbnRTb3VyY2U6IGFueTtcbiAgICBhY3RvcjogP0FjdG9yO1xuICAgIHZ0TGF5ZXJzOiB7W186IHN0cmluZ106IFZlY3RvclRpbGVMYXllcn07XG4gICAgaXNTeW1ib2xUaWxlOiA/Ym9vbGVhbjtcbiAgICBpc1Jhc3RlcjogP2Jvb2xlYW47XG4gICAgX3RpbGVUcmFuc2Zvcm06IFRpbGVUcmFuc2Zvcm07XG5cbiAgICBuZWlnaGJvcmluZ1RpbGVzOiA/T2JqZWN0O1xuICAgIGRlbTogP0RFTURhdGE7XG4gICAgYWJvcnRlZDogP2Jvb2xlYW47XG4gICAgbmVlZHNIaWxsc2hhZGVQcmVwYXJlOiA/Ym9vbGVhbjtcbiAgICBuZWVkc0RFTVRleHR1cmVVcGxvYWQ6ID9ib29sZWFuO1xuICAgIHJlcXVlc3Q6ID9DYW5jZWxhYmxlO1xuICAgIHRleHR1cmU6IGFueTtcbiAgICBmYm86ID9GcmFtZWJ1ZmZlcjtcbiAgICBkZW1UZXh0dXJlOiA/VGV4dHVyZTtcbiAgICByZWZyZXNoZWRVcG9uRXhwaXJhdGlvbjogYm9vbGVhbjtcbiAgICByZWxvYWRDYWxsYmFjazogYW55O1xuICAgIHJlc291cmNlVGltaW5nOiA/QXJyYXk8UGVyZm9ybWFuY2VSZXNvdXJjZVRpbWluZz47XG4gICAgcXVlcnlQYWRkaW5nOiBudW1iZXI7XG5cbiAgICBzeW1ib2xGYWRlSG9sZFVudGlsOiA/bnVtYmVyO1xuICAgIGhhc1N5bWJvbEJ1Y2tldHM6IGJvb2xlYW47XG4gICAgaGFzUlRMVGV4dDogYm9vbGVhbjtcbiAgICBkZXBlbmRlbmNpZXM6IE9iamVjdDtcbiAgICBwcm9qZWN0aW9uOiBQcm9qZWN0aW9uO1xuXG4gICAgcXVlcnlHZW9tZXRyeURlYnVnVml6OiA/VGlsZVNwYWNlRGVidWdCdWZmZXI7XG4gICAgcXVlcnlCb3VuZHNEZWJ1Z1ZpejogP1RpbGVTcGFjZURlYnVnQnVmZmVyO1xuXG4gICAgX3RpbGVEZWJ1Z0J1ZmZlcjogP1ZlcnRleEJ1ZmZlcjtcbiAgICBfdGlsZUJvdW5kc0J1ZmZlcjogP1ZlcnRleEJ1ZmZlcjtcbiAgICBfdGlsZURlYnVnSW5kZXhCdWZmZXI6ID9JbmRleEJ1ZmZlcjtcbiAgICBfdGlsZUJvdW5kc0luZGV4QnVmZmVyOiBJbmRleEJ1ZmZlcjtcbiAgICBfdGlsZURlYnVnU2VnbWVudHM6IFNlZ21lbnRWZWN0b3I7XG4gICAgX3RpbGVCb3VuZHNTZWdtZW50czogU2VnbWVudFZlY3RvcjtcbiAgICBfZ2xvYmVUaWxlRGVidWdCb3JkZXJCdWZmZXI6ID9WZXJ0ZXhCdWZmZXI7XG4gICAgX3RpbGVEZWJ1Z1RleHRCdWZmZXI6ID9WZXJ0ZXhCdWZmZXI7XG4gICAgX3RpbGVEZWJ1Z1RleHRTZWdtZW50czogU2VnbWVudFZlY3RvcjtcbiAgICBfdGlsZURlYnVnVGV4dEluZGV4QnVmZmVyOiBJbmRleEJ1ZmZlcjtcbiAgICBfZ2xvYmVUaWxlRGVidWdUZXh0QnVmZmVyOiA/VmVydGV4QnVmZmVyO1xuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtPdmVyc2NhbGVkVGlsZUlEfSB0aWxlSURcbiAgICAgKiBAcGFyYW0gc2l6ZVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGlsZUlEOiBPdmVyc2NhbGVkVGlsZUlELCBzaXplOiBudW1iZXIsIHRpbGVab29tOiBudW1iZXIsIHBhaW50ZXI6IGFueSwgaXNSYXN0ZXI/OiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMudGlsZUlEID0gdGlsZUlEO1xuICAgICAgICB0aGlzLnVpZCA9IHVuaXF1ZUlkKCk7XG4gICAgICAgIHRoaXMudXNlcyA9IDA7XG4gICAgICAgIHRoaXMudGlsZVNpemUgPSBzaXplO1xuICAgICAgICB0aGlzLnRpbGVab29tID0gdGlsZVpvb207XG4gICAgICAgIHRoaXMuYnVja2V0cyA9IHt9O1xuICAgICAgICB0aGlzLmV4cGlyYXRpb25UaW1lID0gbnVsbDtcbiAgICAgICAgdGhpcy5xdWVyeVBhZGRpbmcgPSAwO1xuICAgICAgICB0aGlzLmhhc1N5bWJvbEJ1Y2tldHMgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5oYXNSVExUZXh0ID0gZmFsc2U7XG4gICAgICAgIHRoaXMuZGVwZW5kZW5jaWVzID0ge307XG4gICAgICAgIHRoaXMuaXNSYXN0ZXIgPSBpc1Jhc3RlcjtcblxuICAgICAgICAvLyBDb3VudHMgdGhlIG51bWJlciBvZiB0aW1lcyBhIHJlc3BvbnNlIHdhcyBhbHJlYWR5IGV4cGlyZWQgd2hlblxuICAgICAgICAvLyByZWNlaXZlZC4gV2UncmUgdXNpbmcgdGhpcyB0byBhZGQgYSBkZWxheSB3aGVuIG1ha2luZyBhIG5ldyByZXF1ZXN0XG4gICAgICAgIC8vIHNvIHdlIGRvbid0IGhhdmUgdG8ga2VlcCByZXRyeWluZyBpbW1lZGlhdGVseSBpbiBjYXNlIG9mIGEgc2VydmVyXG4gICAgICAgIC8vIHNlcnZpbmcgZXhwaXJlZCB0aWxlcy5cbiAgICAgICAgdGhpcy5leHBpcmVkUmVxdWVzdENvdW50ID0gMDtcblxuICAgICAgICB0aGlzLnN0YXRlID0gJ2xvYWRpbmcnO1xuXG4gICAgICAgIGlmIChwYWludGVyICYmIHBhaW50ZXIudHJhbnNmb3JtKSB7XG4gICAgICAgICAgICB0aGlzLnByb2plY3Rpb24gPSBwYWludGVyLnRyYW5zZm9ybS5wcm9qZWN0aW9uO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmVnaXN0ZXJGYWRlRHVyYXRpb24oZHVyYXRpb246IG51bWJlcikge1xuICAgICAgICBjb25zdCBmYWRlRW5kVGltZSA9IGR1cmF0aW9uICsgdGhpcy50aW1lQWRkZWQ7XG4gICAgICAgIGlmIChmYWRlRW5kVGltZSA8IGJyb3dzZXIubm93KCkpIHJldHVybjtcbiAgICAgICAgaWYgKHRoaXMuZmFkZUVuZFRpbWUgJiYgZmFkZUVuZFRpbWUgPCB0aGlzLmZhZGVFbmRUaW1lKSByZXR1cm47XG5cbiAgICAgICAgdGhpcy5mYWRlRW5kVGltZSA9IGZhZGVFbmRUaW1lO1xuICAgIH1cblxuICAgIHdhc1JlcXVlc3RlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhdGUgPT09ICdlcnJvcmVkJyB8fCB0aGlzLnN0YXRlID09PSAnbG9hZGVkJyB8fCB0aGlzLnN0YXRlID09PSAncmVsb2FkaW5nJztcbiAgICB9XG5cbiAgICBnZXQgdGlsZVRyYW5zZm9ybSgpOiBUaWxlVHJhbnNmb3JtIHtcbiAgICAgICAgaWYgKCF0aGlzLl90aWxlVHJhbnNmb3JtKSB7XG4gICAgICAgICAgICB0aGlzLl90aWxlVHJhbnNmb3JtID0gdGlsZVRyYW5zZm9ybSh0aGlzLnRpbGVJRC5jYW5vbmljYWwsIHRoaXMucHJvamVjdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpbGVUcmFuc2Zvcm07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2l2ZW4gYSBkYXRhIG9iamVjdCB3aXRoIGEgJ2J1ZmZlcnMnIHByb3BlcnR5LCBsb2FkIGl0IGludG9cbiAgICAgKiB0aGlzIHRpbGUncyBlbGVtZW50R3JvdXBzIGFuZCBidWZmZXJzIHByb3BlcnRpZXMgYW5kIHNldCBsb2FkZWRcbiAgICAgKiB0byB0cnVlLiBJZiB0aGUgZGF0YSBpcyBudWxsLCBsaWtlIGluIHRoZSBjYXNlIG9mIGFuIGVtcHR5XG4gICAgICogR2VvSlNPTiB0aWxlLCBuby1vcCBidXQgc3RpbGwgc2V0IGxvYWRlZCB0byB0cnVlLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhXG4gICAgICogQHBhcmFtIHBhaW50ZXJcbiAgICAgKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgbG9hZFZlY3RvckRhdGEoZGF0YTogP1dvcmtlclRpbGVSZXN1bHQsIHBhaW50ZXI6IGFueSwganVzdFJlbG9hZGVkOiA/Ym9vbGVhbikge1xuICAgICAgICB0aGlzLnVubG9hZFZlY3RvckRhdGEoKTtcblxuICAgICAgICB0aGlzLnN0YXRlID0gJ2xvYWRlZCc7XG5cbiAgICAgICAgLy8gZW1wdHkgR2VvSlNPTiB0aWxlXG4gICAgICAgIGlmICghZGF0YSkge1xuICAgICAgICAgICAgdGhpcy5jb2xsaXNpb25Cb3hBcnJheSA9IG5ldyBDb2xsaXNpb25Cb3hBcnJheSgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRhdGEuZmVhdHVyZUluZGV4KSB7XG4gICAgICAgICAgICB0aGlzLmxhdGVzdEZlYXR1cmVJbmRleCA9IGRhdGEuZmVhdHVyZUluZGV4O1xuICAgICAgICAgICAgaWYgKGRhdGEucmF3VGlsZURhdGEpIHtcbiAgICAgICAgICAgICAgICAvLyBPbmx5IHZlY3RvciB0aWxlcyBoYXZlIHJhd1RpbGVEYXRhLCBhbmQgdGhleSB3b24ndCB1cGRhdGUgaXQgZm9yXG4gICAgICAgICAgICAgICAgLy8gJ3JlbG9hZFRpbGUnXG4gICAgICAgICAgICAgICAgdGhpcy5sYXRlc3RSYXdUaWxlRGF0YSA9IGRhdGEucmF3VGlsZURhdGE7XG4gICAgICAgICAgICAgICAgdGhpcy5sYXRlc3RGZWF0dXJlSW5kZXgucmF3VGlsZURhdGEgPSBkYXRhLnJhd1RpbGVEYXRhO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmxhdGVzdFJhd1RpbGVEYXRhKSB7XG4gICAgICAgICAgICAgICAgLy8gSWYgcmF3VGlsZURhdGEgaGFzbid0IHVwZGF0ZWQsIGhvbGQgb250byBhIHBvaW50ZXIgdG8gdGhlIGxhc3RcbiAgICAgICAgICAgICAgICAvLyBvbmUgd2UgcmVjZWl2ZWRcbiAgICAgICAgICAgICAgICB0aGlzLmxhdGVzdEZlYXR1cmVJbmRleC5yYXdUaWxlRGF0YSA9IHRoaXMubGF0ZXN0UmF3VGlsZURhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jb2xsaXNpb25Cb3hBcnJheSA9IGRhdGEuY29sbGlzaW9uQm94QXJyYXk7XG4gICAgICAgIHRoaXMuYnVja2V0cyA9IGRlc2VyaWFsaXplQnVja2V0KGRhdGEuYnVja2V0cywgcGFpbnRlci5zdHlsZSk7XG5cbiAgICAgICAgdGhpcy5oYXNTeW1ib2xCdWNrZXRzID0gZmFsc2U7XG4gICAgICAgIGZvciAoY29uc3QgaWQgaW4gdGhpcy5idWNrZXRzKSB7XG4gICAgICAgICAgICBjb25zdCBidWNrZXQgPSB0aGlzLmJ1Y2tldHNbaWRdO1xuICAgICAgICAgICAgaWYgKGJ1Y2tldCBpbnN0YW5jZW9mIFN5bWJvbEJ1Y2tldCkge1xuICAgICAgICAgICAgICAgIHRoaXMuaGFzU3ltYm9sQnVja2V0cyA9IHRydWU7XG4gICAgICAgICAgICAgICAgaWYgKGp1c3RSZWxvYWRlZCkge1xuICAgICAgICAgICAgICAgICAgICBidWNrZXQuanVzdFJlbG9hZGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmhhc1JUTFRleHQgPSBmYWxzZTtcbiAgICAgICAgaWYgKHRoaXMuaGFzU3ltYm9sQnVja2V0cykge1xuICAgICAgICAgICAgZm9yIChjb25zdCBpZCBpbiB0aGlzLmJ1Y2tldHMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBidWNrZXQgPSB0aGlzLmJ1Y2tldHNbaWRdO1xuICAgICAgICAgICAgICAgIGlmIChidWNrZXQgaW5zdGFuY2VvZiBTeW1ib2xCdWNrZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGJ1Y2tldC5oYXNSVExUZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhhc1JUTFRleHQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGF6eUxvYWRSVExUZXh0UGx1Z2luKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucXVlcnlQYWRkaW5nID0gMDtcbiAgICAgICAgZm9yIChjb25zdCBpZCBpbiB0aGlzLmJ1Y2tldHMpIHtcbiAgICAgICAgICAgIGNvbnN0IGJ1Y2tldCA9IHRoaXMuYnVja2V0c1tpZF07XG4gICAgICAgICAgICB0aGlzLnF1ZXJ5UGFkZGluZyA9IE1hdGgubWF4KHRoaXMucXVlcnlQYWRkaW5nLCBwYWludGVyLnN0eWxlLmdldExheWVyKGlkKS5xdWVyeVJhZGl1cyhidWNrZXQpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkYXRhLmltYWdlQXRsYXMpIHtcbiAgICAgICAgICAgIHRoaXMuaW1hZ2VBdGxhcyA9IGRhdGEuaW1hZ2VBdGxhcztcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGF0YS5nbHlwaEF0bGFzSW1hZ2UpIHtcbiAgICAgICAgICAgIHRoaXMuZ2x5cGhBdGxhc0ltYWdlID0gZGF0YS5nbHlwaEF0bGFzSW1hZ2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRhdGEubGluZUF0bGFzKSB7XG4gICAgICAgICAgICB0aGlzLmxpbmVBdGxhcyA9IGRhdGEubGluZUF0bGFzO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVsZWFzZSBhbnkgZGF0YSBvciBXZWJHTCByZXNvdXJjZXMgcmVmZXJlbmNlZCBieSB0aGlzIHRpbGUuXG4gICAgICogQHJldHVybnMge3VuZGVmaW5lZH1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHVubG9hZFZlY3RvckRhdGEoKSB7XG4gICAgICAgIGlmICghdGhpcy5oYXNEYXRhKCkpIHJldHVybjtcblxuICAgICAgICBmb3IgKGNvbnN0IGlkIGluIHRoaXMuYnVja2V0cykge1xuICAgICAgICAgICAgdGhpcy5idWNrZXRzW2lkXS5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5idWNrZXRzID0ge307XG5cbiAgICAgICAgaWYgKHRoaXMuaW1hZ2VBdGxhcykge1xuICAgICAgICAgICAgdGhpcy5pbWFnZUF0bGFzID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmxpbmVBdGxhcykge1xuICAgICAgICAgICAgdGhpcy5saW5lQXRsYXMgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuaW1hZ2VBdGxhc1RleHR1cmUpIHtcbiAgICAgICAgICAgIHRoaXMuaW1hZ2VBdGxhc1RleHR1cmUuZGVzdHJveSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuZ2x5cGhBdGxhc1RleHR1cmUpIHtcbiAgICAgICAgICAgIHRoaXMuZ2x5cGhBdGxhc1RleHR1cmUuZGVzdHJveSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMubGluZUF0bGFzVGV4dHVyZSkge1xuICAgICAgICAgICAgdGhpcy5saW5lQXRsYXNUZXh0dXJlLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLl90aWxlQm91bmRzQnVmZmVyKSB7XG4gICAgICAgICAgICB0aGlzLl90aWxlQm91bmRzQnVmZmVyLmRlc3Ryb3koKTtcbiAgICAgICAgICAgIHRoaXMuX3RpbGVCb3VuZHNJbmRleEJ1ZmZlci5kZXN0cm95KCk7XG4gICAgICAgICAgICB0aGlzLl90aWxlQm91bmRzU2VnbWVudHMuZGVzdHJveSgpO1xuICAgICAgICAgICAgdGhpcy5fdGlsZUJvdW5kc0J1ZmZlciA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5fdGlsZURlYnVnQnVmZmVyKSB7XG4gICAgICAgICAgICB0aGlzLl90aWxlRGVidWdCdWZmZXIuZGVzdHJveSgpO1xuICAgICAgICAgICAgdGhpcy5fdGlsZURlYnVnU2VnbWVudHMuZGVzdHJveSgpO1xuICAgICAgICAgICAgdGhpcy5fdGlsZURlYnVnQnVmZmVyID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLl90aWxlRGVidWdJbmRleEJ1ZmZlcikge1xuICAgICAgICAgICAgdGhpcy5fdGlsZURlYnVnSW5kZXhCdWZmZXIuZGVzdHJveSgpO1xuICAgICAgICAgICAgdGhpcy5fdGlsZURlYnVnSW5kZXhCdWZmZXIgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuX2dsb2JlVGlsZURlYnVnQm9yZGVyQnVmZmVyKSB7XG4gICAgICAgICAgICB0aGlzLl9nbG9iZVRpbGVEZWJ1Z0JvcmRlckJ1ZmZlci5kZXN0cm95KCk7XG4gICAgICAgICAgICB0aGlzLl9nbG9iZVRpbGVEZWJ1Z0JvcmRlckJ1ZmZlciA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5fdGlsZURlYnVnVGV4dEJ1ZmZlcikge1xuICAgICAgICAgICAgdGhpcy5fdGlsZURlYnVnVGV4dEJ1ZmZlci5kZXN0cm95KCk7XG4gICAgICAgICAgICB0aGlzLl90aWxlRGVidWdUZXh0U2VnbWVudHMuZGVzdHJveSgpO1xuICAgICAgICAgICAgdGhpcy5fdGlsZURlYnVnVGV4dEluZGV4QnVmZmVyLmRlc3Ryb3koKTtcbiAgICAgICAgICAgIHRoaXMuX3RpbGVEZWJ1Z1RleHRCdWZmZXIgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuX2dsb2JlVGlsZURlYnVnVGV4dEJ1ZmZlcikge1xuICAgICAgICAgICAgdGhpcy5fZ2xvYmVUaWxlRGVidWdUZXh0QnVmZmVyLmRlc3Ryb3koKTtcbiAgICAgICAgICAgIHRoaXMuX2dsb2JlVGlsZURlYnVnVGV4dEJ1ZmZlciA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBEZWJ1Zy5ydW4oKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMucXVlcnlHZW9tZXRyeURlYnVnVml6KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5xdWVyeUdlb21ldHJ5RGVidWdWaXoudW5sb2FkKCk7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucXVlcnlHZW9tZXRyeURlYnVnVml6O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMucXVlcnlCb3VuZHNEZWJ1Z1Zpeikge1xuICAgICAgICAgICAgICAgIHRoaXMucXVlcnlCb3VuZHNEZWJ1Z1Zpei51bmxvYWQoKTtcbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5xdWVyeUJvdW5kc0RlYnVnVml6O1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5sYXRlc3RGZWF0dXJlSW5kZXggPSBudWxsO1xuICAgICAgICB0aGlzLnN0YXRlID0gJ3VubG9hZGVkJztcbiAgICB9XG5cbiAgICBnZXRCdWNrZXQobGF5ZXI6IFN0eWxlTGF5ZXIpOiBCdWNrZXQge1xuICAgICAgICByZXR1cm4gdGhpcy5idWNrZXRzW2xheWVyLmlkXTtcbiAgICB9XG5cbiAgICB1cGxvYWQoY29udGV4dDogQ29udGV4dCkge1xuICAgICAgICBmb3IgKGNvbnN0IGlkIGluIHRoaXMuYnVja2V0cykge1xuICAgICAgICAgICAgY29uc3QgYnVja2V0ID0gdGhpcy5idWNrZXRzW2lkXTtcbiAgICAgICAgICAgIGlmIChidWNrZXQudXBsb2FkUGVuZGluZygpKSB7XG4gICAgICAgICAgICAgICAgYnVja2V0LnVwbG9hZChjb250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGdsID0gY29udGV4dC5nbDtcbiAgICAgICAgaWYgKHRoaXMuaW1hZ2VBdGxhcyAmJiAhdGhpcy5pbWFnZUF0bGFzLnVwbG9hZGVkKSB7XG4gICAgICAgICAgICB0aGlzLmltYWdlQXRsYXNUZXh0dXJlID0gbmV3IFRleHR1cmUoY29udGV4dCwgdGhpcy5pbWFnZUF0bGFzLmltYWdlLCBnbC5SR0JBKTtcbiAgICAgICAgICAgICgodGhpcy5pbWFnZUF0bGFzOiBhbnkpOiBJbWFnZUF0bGFzKS51cGxvYWRlZCA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5nbHlwaEF0bGFzSW1hZ2UpIHtcbiAgICAgICAgICAgIHRoaXMuZ2x5cGhBdGxhc1RleHR1cmUgPSBuZXcgVGV4dHVyZShjb250ZXh0LCB0aGlzLmdseXBoQXRsYXNJbWFnZSwgZ2wuQUxQSEEpO1xuICAgICAgICAgICAgdGhpcy5nbHlwaEF0bGFzSW1hZ2UgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMubGluZUF0bGFzICYmICF0aGlzLmxpbmVBdGxhcy51cGxvYWRlZCkge1xuICAgICAgICAgICAgdGhpcy5saW5lQXRsYXNUZXh0dXJlID0gbmV3IFRleHR1cmUoY29udGV4dCwgdGhpcy5saW5lQXRsYXMuaW1hZ2UsIGdsLkFMUEhBKTtcbiAgICAgICAgICAgICgodGhpcy5saW5lQXRsYXM6IGFueSk6IExpbmVBdGxhcykudXBsb2FkZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJlcGFyZShpbWFnZU1hbmFnZXI6IEltYWdlTWFuYWdlcikge1xuICAgICAgICBpZiAodGhpcy5pbWFnZUF0bGFzKSB7XG4gICAgICAgICAgICB0aGlzLmltYWdlQXRsYXMucGF0Y2hVcGRhdGVkSW1hZ2VzKGltYWdlTWFuYWdlciwgdGhpcy5pbWFnZUF0bGFzVGV4dHVyZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBRdWVyaWVzIG5vbi1zeW1ib2wgZmVhdHVyZXMgcmVuZGVyZWQgZm9yIHRoaXMgdGlsZS5cbiAgICAvLyBTeW1ib2wgZmVhdHVyZXMgYXJlIHF1ZXJpZWQgZ2xvYmFsbHlcbiAgICBxdWVyeVJlbmRlcmVkRmVhdHVyZXMobGF5ZXJzOiB7W186IHN0cmluZ106IFN0eWxlTGF5ZXJ9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICBzZXJpYWxpemVkTGF5ZXJzOiB7W3N0cmluZ106IE9iamVjdH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZUZlYXR1cmVTdGF0ZTogU291cmNlRmVhdHVyZVN0YXRlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aWxlUmVzdWx0OiBUaWxlc3BhY2VRdWVyeUdlb21ldHJ5LFxuICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXM6IHsgZmlsdGVyOiBGaWx0ZXJTcGVjaWZpY2F0aW9uLCBsYXllcnM6IEFycmF5PHN0cmluZz4sIGF2YWlsYWJsZUltYWdlczogQXJyYXk8c3RyaW5nPiB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm06IFRyYW5zZm9ybSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcGl4ZWxQb3NNYXRyaXg6IEZsb2F0MzJBcnJheSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdmlzdWFsaXplUXVlcnlHZW9tZXRyeTogYm9vbGVhbik6IFF1ZXJ5UmVzdWx0IHtcbiAgICAgICAgRGVidWcucnVuKCgpID0+IHtcbiAgICAgICAgICAgIGlmICh2aXN1YWxpemVRdWVyeUdlb21ldHJ5KSB7XG4gICAgICAgICAgICAgICAgbGV0IGdlb21ldHJ5Vml6ID0gdGhpcy5xdWVyeUdlb21ldHJ5RGVidWdWaXo7XG4gICAgICAgICAgICAgICAgbGV0IGJvdW5kc1ZpeiA9IHRoaXMucXVlcnlCb3VuZHNEZWJ1Z1ZpejtcbiAgICAgICAgICAgICAgICBpZiAoIWdlb21ldHJ5Vml6KSB7XG4gICAgICAgICAgICAgICAgICAgIGdlb21ldHJ5Vml6ID0gdGhpcy5xdWVyeUdlb21ldHJ5RGVidWdWaXogPSBuZXcgVGlsZVNwYWNlRGVidWdCdWZmZXIodGhpcy50aWxlU2l6ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghYm91bmRzVml6KSB7XG4gICAgICAgICAgICAgICAgICAgIGJvdW5kc1ZpeiA9IHRoaXMucXVlcnlCb3VuZHNEZWJ1Z1ZpeiA9IG5ldyBUaWxlU3BhY2VEZWJ1Z0J1ZmZlcih0aGlzLnRpbGVTaXplLCBDb2xvci5ibHVlKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBnZW9tZXRyeVZpei5hZGRQb2ludHModGlsZVJlc3VsdC50aWxlc3BhY2VHZW9tZXRyeSk7XG4gICAgICAgICAgICAgICAgYm91bmRzVml6LmFkZFBvaW50cyh0aWxlUmVzdWx0LmJ1ZmZlcmVkVGlsZXNwYWNlR2VvbWV0cnkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoIXRoaXMubGF0ZXN0RmVhdHVyZUluZGV4IHx8ICF0aGlzLmxhdGVzdEZlYXR1cmVJbmRleC5yYXdUaWxlRGF0YSlcbiAgICAgICAgICAgIHJldHVybiB7fTtcblxuICAgICAgICByZXR1cm4gdGhpcy5sYXRlc3RGZWF0dXJlSW5kZXgucXVlcnkoe1xuICAgICAgICAgICAgdGlsZVJlc3VsdCxcbiAgICAgICAgICAgIHBpeGVsUG9zTWF0cml4LFxuICAgICAgICAgICAgdHJhbnNmb3JtLFxuICAgICAgICAgICAgcGFyYW1zLFxuICAgICAgICAgICAgdGlsZVRyYW5zZm9ybTogdGhpcy50aWxlVHJhbnNmb3JtXG4gICAgICAgIH0sIGxheWVycywgc2VyaWFsaXplZExheWVycywgc291cmNlRmVhdHVyZVN0YXRlKTtcbiAgICB9XG5cbiAgICBxdWVyeVNvdXJjZUZlYXR1cmVzKHJlc3VsdDogQXJyYXk8UXVlcnlGZWF0dXJlPiwgcGFyYW1zOiBhbnkpIHtcbiAgICAgICAgY29uc3QgZmVhdHVyZUluZGV4ID0gdGhpcy5sYXRlc3RGZWF0dXJlSW5kZXg7XG4gICAgICAgIGlmICghZmVhdHVyZUluZGV4IHx8ICFmZWF0dXJlSW5kZXgucmF3VGlsZURhdGEpIHJldHVybjtcblxuICAgICAgICBjb25zdCB2dExheWVycyA9IGZlYXR1cmVJbmRleC5sb2FkVlRMYXllcnMoKTtcblxuICAgICAgICBjb25zdCBzb3VyY2VMYXllciA9IHBhcmFtcyA/IHBhcmFtcy5zb3VyY2VMYXllciA6ICcnO1xuICAgICAgICBjb25zdCBsYXllciA9IHZ0TGF5ZXJzLl9nZW9qc29uVGlsZUxheWVyIHx8IHZ0TGF5ZXJzW3NvdXJjZUxheWVyXTtcblxuICAgICAgICBpZiAoIWxheWVyKSByZXR1cm47XG5cbiAgICAgICAgY29uc3QgZmlsdGVyID0gZmVhdHVyZUZpbHRlcihwYXJhbXMgJiYgcGFyYW1zLmZpbHRlcik7XG4gICAgICAgIGNvbnN0IHt6LCB4LCB5fSA9IHRoaXMudGlsZUlELmNhbm9uaWNhbDtcbiAgICAgICAgY29uc3QgY29vcmQgPSB7eiwgeCwgeX07XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsYXllci5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgZmVhdHVyZSA9IGxheWVyLmZlYXR1cmUoaSk7XG4gICAgICAgICAgICBpZiAoZmlsdGVyLm5lZWRHZW9tZXRyeSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGV2YWx1YXRpb25GZWF0dXJlID0gdG9FdmFsdWF0aW9uRmVhdHVyZShmZWF0dXJlLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICAgICAgaWYgKCFmaWx0ZXIuZmlsdGVyKG5ldyBFdmFsdWF0aW9uUGFyYW1ldGVycyh0aGlzLnRpbGVJRC5vdmVyc2NhbGVkWiksIGV2YWx1YXRpb25GZWF0dXJlLCB0aGlzLnRpbGVJRC5jYW5vbmljYWwpKSBjb250aW51ZTtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIWZpbHRlci5maWx0ZXIobmV3IEV2YWx1YXRpb25QYXJhbWV0ZXJzKHRoaXMudGlsZUlELm92ZXJzY2FsZWRaKSwgZmVhdHVyZSkpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGlkID0gZmVhdHVyZUluZGV4LmdldElkKGZlYXR1cmUsIHNvdXJjZUxheWVyKTtcbiAgICAgICAgICAgIGNvbnN0IGdlb2pzb25GZWF0dXJlID0gbmV3IEdlb0pTT05GZWF0dXJlKGZlYXR1cmUsIHosIHgsIHksIGlkKTtcbiAgICAgICAgICAgIGdlb2pzb25GZWF0dXJlLnRpbGUgPSBjb29yZDtcblxuICAgICAgICAgICAgcmVzdWx0LnB1c2goZ2VvanNvbkZlYXR1cmUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaGFzRGF0YSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhdGUgPT09ICdsb2FkZWQnIHx8IHRoaXMuc3RhdGUgPT09ICdyZWxvYWRpbmcnIHx8IHRoaXMuc3RhdGUgPT09ICdleHBpcmVkJztcbiAgICB9XG5cbiAgICBwYXR0ZXJuc0xvYWRlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5pbWFnZUF0bGFzICYmICEhT2JqZWN0LmtleXModGhpcy5pbWFnZUF0bGFzLnBhdHRlcm5Qb3NpdGlvbnMpLmxlbmd0aDtcbiAgICB9XG5cbiAgICBzZXRFeHBpcnlEYXRhKGRhdGE6IGFueSkge1xuICAgICAgICBjb25zdCBwcmlvciA9IHRoaXMuZXhwaXJhdGlvblRpbWU7XG5cbiAgICAgICAgaWYgKGRhdGEuY2FjaGVDb250cm9sKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJzZWRDQyA9IHBhcnNlQ2FjaGVDb250cm9sKGRhdGEuY2FjaGVDb250cm9sKTtcbiAgICAgICAgICAgIGlmIChwYXJzZWRDQ1snbWF4LWFnZSddKSB0aGlzLmV4cGlyYXRpb25UaW1lID0gRGF0ZS5ub3coKSArIHBhcnNlZENDWydtYXgtYWdlJ10gKiAxMDAwO1xuICAgICAgICB9IGVsc2UgaWYgKGRhdGEuZXhwaXJlcykge1xuICAgICAgICAgICAgdGhpcy5leHBpcmF0aW9uVGltZSA9IG5ldyBEYXRlKGRhdGEuZXhwaXJlcykuZ2V0VGltZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuZXhwaXJhdGlvblRpbWUpIHtcbiAgICAgICAgICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgICAgICAgICBsZXQgaXNFeHBpcmVkID0gZmFsc2U7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmV4cGlyYXRpb25UaW1lID4gbm93KSB7XG4gICAgICAgICAgICAgICAgaXNFeHBpcmVkID0gZmFsc2U7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKCFwcmlvcikge1xuICAgICAgICAgICAgICAgIGlzRXhwaXJlZCA9IHRydWU7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuZXhwaXJhdGlvblRpbWUgPCBwcmlvcikge1xuICAgICAgICAgICAgICAgIC8vIEV4cGlyaW5nIGRhdGUgaXMgZ29pbmcgYmFja3dhcmRzOlxuICAgICAgICAgICAgICAgIC8vIGZhbGwgYmFjayB0byBleHBvbmVudGlhbCBiYWNrb2ZmXG4gICAgICAgICAgICAgICAgaXNFeHBpcmVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBkZWx0YSA9IHRoaXMuZXhwaXJhdGlvblRpbWUgLSBwcmlvcjtcblxuICAgICAgICAgICAgICAgIGlmICghZGVsdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU2VydmVyIGlzIHNlcnZpbmcgdGhlIHNhbWUgZXhwaXJlZCByZXNvdXJjZSBvdmVyIGFuZCBvdmVyOiBmYWxsXG4gICAgICAgICAgICAgICAgICAgIC8vIGJhY2sgdG8gZXhwb25lbnRpYWwgYmFja29mZi5cbiAgICAgICAgICAgICAgICAgICAgaXNFeHBpcmVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEFzc3VtZSB0aGF0IGVpdGhlciB0aGUgY2xpZW50IG9yIHRoZSBzZXJ2ZXIgY2xvY2sgaXMgd3JvbmcgYW5kXG4gICAgICAgICAgICAgICAgICAgIC8vIHRyeSB0byBpbnRlcnBvbGF0ZSBhIHZhbGlkIGV4cGlyYXRpb24gZGF0ZSAoZnJvbSB0aGUgY2xpZW50IFBPVilcbiAgICAgICAgICAgICAgICAgICAgLy8gb2JzZXJ2aW5nIGEgbWluaW11bSB0aW1lb3V0LlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmV4cGlyYXRpb25UaW1lID0gbm93ICsgTWF0aC5tYXgoZGVsdGEsIENMT0NLX1NLRVdfUkVUUllfVElNRU9VVCk7XG5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpc0V4cGlyZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmV4cGlyZWRSZXF1ZXN0Q291bnQrKztcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gJ2V4cGlyZWQnO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmV4cGlyZWRSZXF1ZXN0Q291bnQgPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0RXhwaXJ5VGltZW91dCgpOiB2b2lkIHwgbnVtYmVyIHtcbiAgICAgICAgaWYgKHRoaXMuZXhwaXJhdGlvblRpbWUpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmV4cGlyZWRSZXF1ZXN0Q291bnQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gMTAwMCAqICgxIDw8IE1hdGgubWluKHRoaXMuZXhwaXJlZFJlcXVlc3RDb3VudCAtIDEsIDMxKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIE1heCB2YWx1ZSBmb3IgYHNldFRpbWVvdXRgIGltcGxlbWVudGF0aW9ucyBpcyBhIDMyIGJpdCBpbnRlZ2VyOyBjYXAgdGhpcyBhY2NvcmRpbmdseVxuICAgICAgICAgICAgICAgIHJldHVybiBNYXRoLm1pbih0aGlzLmV4cGlyYXRpb25UaW1lIC0gbmV3IERhdGUoKS5nZXRUaW1lKCksIE1hdGgucG93KDIsIDMxKSAtIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0RmVhdHVyZVN0YXRlKHN0YXRlczogTGF5ZXJGZWF0dXJlU3RhdGVzLCBwYWludGVyOiA/UGFpbnRlcikge1xuICAgICAgICBpZiAoIXRoaXMubGF0ZXN0RmVhdHVyZUluZGV4IHx8XG4gICAgICAgICAgICAhdGhpcy5sYXRlc3RGZWF0dXJlSW5kZXgucmF3VGlsZURhdGEgfHxcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKHN0YXRlcykubGVuZ3RoID09PSAwIHx8XG4gICAgICAgICAgICAhcGFpbnRlcikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdnRMYXllcnMgPSB0aGlzLmxhdGVzdEZlYXR1cmVJbmRleC5sb2FkVlRMYXllcnMoKTtcbiAgICAgICAgY29uc3QgYXZhaWxhYmxlSW1hZ2VzID0gcGFpbnRlci5zdHlsZS5saXN0SW1hZ2VzKCk7XG5cbiAgICAgICAgZm9yIChjb25zdCBpZCBpbiB0aGlzLmJ1Y2tldHMpIHtcbiAgICAgICAgICAgIGlmICghcGFpbnRlci5zdHlsZS5oYXNMYXllcihpZCkpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICBjb25zdCBidWNrZXQgPSB0aGlzLmJ1Y2tldHNbaWRdO1xuICAgICAgICAgICAgLy8gQnVja2V0cyBhcmUgZ3JvdXBlZCBieSBjb21tb24gc291cmNlLWxheWVyXG4gICAgICAgICAgICBjb25zdCBzb3VyY2VMYXllcklkID0gYnVja2V0LmxheWVyc1swXVsnc291cmNlTGF5ZXInXSB8fCAnX2dlb2pzb25UaWxlTGF5ZXInO1xuICAgICAgICAgICAgY29uc3Qgc291cmNlTGF5ZXIgPSB2dExheWVyc1tzb3VyY2VMYXllcklkXTtcbiAgICAgICAgICAgIGNvbnN0IHNvdXJjZUxheWVyU3RhdGVzID0gc3RhdGVzW3NvdXJjZUxheWVySWRdO1xuICAgICAgICAgICAgaWYgKCFzb3VyY2VMYXllciB8fCAhc291cmNlTGF5ZXJTdGF0ZXMgfHwgT2JqZWN0LmtleXMoc291cmNlTGF5ZXJTdGF0ZXMpLmxlbmd0aCA9PT0gMCkgY29udGludWU7XG5cbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbaW5jb21wYXRpYmxlLXR5cGVdIEZsb3cgY2FuJ3QgaW50ZXJwcmV0IEltYWdlUG9zaXRpb24gYXMgU3ByaXRlUG9zaXRpb24gZm9yIHNvbWUgcmVhc29uIGhlcmVcbiAgICAgICAgICAgIGNvbnN0IGltYWdlUG9zaXRpb25zOiBTcHJpdGVQb3NpdGlvbnMgPSAodGhpcy5pbWFnZUF0bGFzICYmIHRoaXMuaW1hZ2VBdGxhcy5wYXR0ZXJuUG9zaXRpb25zKSB8fCB7fTtcbiAgICAgICAgICAgIGJ1Y2tldC51cGRhdGUoc291cmNlTGF5ZXJTdGF0ZXMsIHNvdXJjZUxheWVyLCBhdmFpbGFibGVJbWFnZXMsIGltYWdlUG9zaXRpb25zKTtcbiAgICAgICAgICAgIGlmIChidWNrZXQgaW5zdGFuY2VvZiBMaW5lQnVja2V0IHx8IGJ1Y2tldCBpbnN0YW5jZW9mIEZpbGxCdWNrZXQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2VDYWNoZSA9IHBhaW50ZXIuc3R5bGUuX2dldFNvdXJjZUNhY2hlKGJ1Y2tldC5sYXllcnNbMF0uc291cmNlKTtcbiAgICAgICAgICAgICAgICBpZiAocGFpbnRlci5fdGVycmFpbiAmJiBwYWludGVyLl90ZXJyYWluLmVuYWJsZWQgJiYgc291cmNlQ2FjaGUgJiYgYnVja2V0LnByb2dyYW1Db25maWd1cmF0aW9ucy5uZWVkc1VwbG9hZCkge1xuICAgICAgICAgICAgICAgICAgICBwYWludGVyLl90ZXJyYWluLl9jbGVhclJlbmRlckNhY2hlRm9yVGlsZShzb3VyY2VDYWNoZS5pZCwgdGhpcy50aWxlSUQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGxheWVyID0gcGFpbnRlciAmJiBwYWludGVyLnN0eWxlICYmIHBhaW50ZXIuc3R5bGUuZ2V0TGF5ZXIoaWQpO1xuICAgICAgICAgICAgaWYgKGxheWVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5xdWVyeVBhZGRpbmcgPSBNYXRoLm1heCh0aGlzLnF1ZXJ5UGFkZGluZywgbGF5ZXIucXVlcnlSYWRpdXMoYnVja2V0KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBob2xkaW5nRm9yRmFkZSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3ltYm9sRmFkZUhvbGRVbnRpbCAhPT0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHN5bWJvbEZhZGVGaW5pc2hlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICF0aGlzLnN5bWJvbEZhZGVIb2xkVW50aWwgfHwgdGhpcy5zeW1ib2xGYWRlSG9sZFVudGlsIDwgYnJvd3Nlci5ub3coKTtcbiAgICB9XG5cbiAgICBjbGVhckZhZGVIb2xkKCkge1xuICAgICAgICB0aGlzLnN5bWJvbEZhZGVIb2xkVW50aWwgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgc2V0SG9sZER1cmF0aW9uKGR1cmF0aW9uOiBudW1iZXIpIHtcbiAgICAgICAgdGhpcy5zeW1ib2xGYWRlSG9sZFVudGlsID0gYnJvd3Nlci5ub3coKSArIGR1cmF0aW9uO1xuICAgIH1cblxuICAgIHNldFRleHR1cmUoaW1nOiBUZXh0dXJlSW1hZ2UsIHBhaW50ZXI6IFBhaW50ZXIpIHtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IHBhaW50ZXIuY29udGV4dDtcbiAgICAgICAgY29uc3QgZ2wgPSBjb250ZXh0LmdsO1xuICAgICAgICB0aGlzLnRleHR1cmUgPSB0aGlzLnRleHR1cmUgfHwgcGFpbnRlci5nZXRUaWxlVGV4dHVyZShpbWcud2lkdGgpO1xuICAgICAgICBpZiAodGhpcy50ZXh0dXJlKSB7XG4gICAgICAgICAgICB0aGlzLnRleHR1cmUudXBkYXRlKGltZywge3VzZU1pcG1hcDogdHJ1ZX0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy50ZXh0dXJlID0gbmV3IFRleHR1cmUoY29udGV4dCwgaW1nLCBnbC5SR0JBLCB7dXNlTWlwbWFwOiB0cnVlfSk7XG4gICAgICAgICAgICB0aGlzLnRleHR1cmUuYmluZChnbC5MSU5FQVIsIGdsLkNMQU1QX1RPX0VER0UpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0RGVwZW5kZW5jaWVzKG5hbWVzcGFjZTogc3RyaW5nLCBkZXBlbmRlbmNpZXM6IEFycmF5PHN0cmluZz4pIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSB7fTtcbiAgICAgICAgZm9yIChjb25zdCBkZXAgb2YgZGVwZW5kZW5jaWVzKSB7XG4gICAgICAgICAgICBpbmRleFtkZXBdID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRlcGVuZGVuY2llc1tuYW1lc3BhY2VdID0gaW5kZXg7XG4gICAgfVxuXG4gICAgaGFzRGVwZW5kZW5jeShuYW1lc3BhY2VzOiBBcnJheTxzdHJpbmc+LCBrZXlzOiBBcnJheTxzdHJpbmc+KTogYm9vbGVhbiB7XG4gICAgICAgIGZvciAoY29uc3QgbmFtZXNwYWNlIG9mIG5hbWVzcGFjZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IGRlcGVuZGVuY2llcyA9IHRoaXMuZGVwZW5kZW5jaWVzW25hbWVzcGFjZV07XG4gICAgICAgICAgICBpZiAoZGVwZW5kZW5jaWVzKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2Yga2V5cykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZGVwZW5kZW5jaWVzW2tleV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjbGVhclF1ZXJ5RGVidWdWaXooKSB7XG4gICAgICAgIERlYnVnLnJ1bigoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5xdWVyeUdlb21ldHJ5RGVidWdWaXopIHtcbiAgICAgICAgICAgICAgICB0aGlzLnF1ZXJ5R2VvbWV0cnlEZWJ1Z1Zpei5jbGVhclBvaW50cygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMucXVlcnlCb3VuZHNEZWJ1Z1Zpeikge1xuICAgICAgICAgICAgICAgIHRoaXMucXVlcnlCb3VuZHNEZWJ1Z1Zpei5jbGVhclBvaW50cygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBfbWFrZURlYnVnVGlsZUJvdW5kc0J1ZmZlcnMoY29udGV4dDogQ29udGV4dCwgcHJvamVjdGlvbjogUHJvamVjdGlvbikge1xuICAgICAgICBpZiAoIXByb2plY3Rpb24gfHwgcHJvamVjdGlvbi5uYW1lID09PSAnbWVyY2F0b3InIHx8IHRoaXMuX3RpbGVEZWJ1Z0J1ZmZlcikgcmV0dXJuO1xuXG4gICAgICAgIC8vIHJlcHJvamVjdCB0aWxlIG91dGxpbmUgd2l0aCBhZGFwdGl2ZSByZXNhbXBsaW5nXG4gICAgICAgIGNvbnN0IGJvdW5kc0xpbmUgPSBsb2FkR2VvbWV0cnkoQk9VTkRTX0ZFQVRVUkUsIHRoaXMudGlsZUlELmNhbm9uaWNhbCwgdGhpcy50aWxlVHJhbnNmb3JtKVswXTtcblxuICAgICAgICAvLyBnZW5lcmF0ZSB2ZXJ0aWNlcyBmb3IgZGVidWdnaW5nIHRpbGUgYm91bmRhcmllc1xuICAgICAgICBjb25zdCBkZWJ1Z1ZlcnRpY2VzID0gbmV3IFBvc0FycmF5KCk7XG4gICAgICAgIGNvbnN0IGRlYnVnSW5kaWNlcyA9IG5ldyBMaW5lU3RyaXBJbmRleEFycmF5KCk7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBib3VuZHNMaW5lLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCB7eCwgeX0gPSBib3VuZHNMaW5lW2ldO1xuICAgICAgICAgICAgZGVidWdWZXJ0aWNlcy5lbXBsYWNlQmFjayh4LCB5KTtcbiAgICAgICAgICAgIGRlYnVnSW5kaWNlcy5lbXBsYWNlQmFjayhpKTtcbiAgICAgICAgfVxuICAgICAgICBkZWJ1Z0luZGljZXMuZW1wbGFjZUJhY2soMCk7XG5cbiAgICAgICAgdGhpcy5fdGlsZURlYnVnSW5kZXhCdWZmZXIgPSBjb250ZXh0LmNyZWF0ZUluZGV4QnVmZmVyKGRlYnVnSW5kaWNlcyk7XG4gICAgICAgIHRoaXMuX3RpbGVEZWJ1Z0J1ZmZlciA9IGNvbnRleHQuY3JlYXRlVmVydGV4QnVmZmVyKGRlYnVnVmVydGljZXMsIHBvc0F0dHJpYnV0ZXMubWVtYmVycyk7XG4gICAgICAgIHRoaXMuX3RpbGVEZWJ1Z1NlZ21lbnRzID0gU2VnbWVudFZlY3Rvci5zaW1wbGVTZWdtZW50KDAsIDAsIGRlYnVnVmVydGljZXMubGVuZ3RoLCBkZWJ1Z0luZGljZXMubGVuZ3RoKTtcbiAgICB9XG5cbiAgICBfbWFrZVRpbGVCb3VuZHNCdWZmZXJzKGNvbnRleHQ6IENvbnRleHQsIHByb2plY3Rpb246IFByb2plY3Rpb24pIHtcbiAgICAgICAgaWYgKHRoaXMuX3RpbGVCb3VuZHNCdWZmZXIgfHwgIXByb2plY3Rpb24gfHwgcHJvamVjdGlvbi5uYW1lID09PSAnbWVyY2F0b3InKSByZXR1cm47XG5cbiAgICAgICAgLy8gcmVwcm9qZWN0IHRpbGUgb3V0bGluZSB3aXRoIGFkYXB0aXZlIHJlc2FtcGxpbmdcbiAgICAgICAgY29uc3QgYm91bmRzTGluZSA9IGxvYWRHZW9tZXRyeShCT1VORFNfRkVBVFVSRSwgdGhpcy50aWxlSUQuY2Fub25pY2FsLCB0aGlzLnRpbGVUcmFuc2Zvcm0pWzBdO1xuXG4gICAgICAgIGxldCBib3VuZHNWZXJ0aWNlcywgYm91bmRzSW5kaWNlcztcbiAgICAgICAgaWYgKHRoaXMuaXNSYXN0ZXIpIHtcbiAgICAgICAgICAgIC8vIGZvciByYXN0ZXIgdGlsZXMsIGdlbmVyYXRlIGFuIGFkYXB0aXZlIE1BUlRJTkkgbWVzaFxuICAgICAgICAgICAgY29uc3QgbWVzaCA9IGdldFRpbGVNZXNoKHRoaXMudGlsZUlELmNhbm9uaWNhbCwgcHJvamVjdGlvbik7XG4gICAgICAgICAgICBib3VuZHNWZXJ0aWNlcyA9IG1lc2gudmVydGljZXM7XG4gICAgICAgICAgICBib3VuZHNJbmRpY2VzID0gbWVzaC5pbmRpY2VzO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBmb3IgdmVjdG9yIHRpbGVzLCBnZW5lcmF0ZSBhbiBFYXJjdXQgdHJpYW5ndWxhdGlvbiBvZiB0aGUgb3V0bGluZVxuICAgICAgICAgICAgYm91bmRzVmVydGljZXMgPSBuZXcgVGlsZUJvdW5kc0FycmF5KCk7XG4gICAgICAgICAgICBib3VuZHNJbmRpY2VzID0gbmV3IFRyaWFuZ2xlSW5kZXhBcnJheSgpO1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHt4LCB5fSBvZiBib3VuZHNMaW5lKSB7XG4gICAgICAgICAgICAgICAgYm91bmRzVmVydGljZXMuZW1wbGFjZUJhY2soeCwgeSwgMCwgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBpbmRpY2VzID0gZWFyY3V0KGJvdW5kc1ZlcnRpY2VzLmludDE2LCB1bmRlZmluZWQsIDQpO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbmRpY2VzLmxlbmd0aDsgaSArPSAzKSB7XG4gICAgICAgICAgICAgICAgYm91bmRzSW5kaWNlcy5lbXBsYWNlQmFjayhpbmRpY2VzW2ldLCBpbmRpY2VzW2kgKyAxXSwgaW5kaWNlc1tpICsgMl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3RpbGVCb3VuZHNCdWZmZXIgPSBjb250ZXh0LmNyZWF0ZVZlcnRleEJ1ZmZlcihib3VuZHNWZXJ0aWNlcywgYm91bmRzQXR0cmlidXRlcy5tZW1iZXJzKTtcbiAgICAgICAgdGhpcy5fdGlsZUJvdW5kc0luZGV4QnVmZmVyID0gY29udGV4dC5jcmVhdGVJbmRleEJ1ZmZlcihib3VuZHNJbmRpY2VzKTtcbiAgICAgICAgdGhpcy5fdGlsZUJvdW5kc1NlZ21lbnRzID0gU2VnbWVudFZlY3Rvci5zaW1wbGVTZWdtZW50KDAsIDAsIGJvdW5kc1ZlcnRpY2VzLmxlbmd0aCwgYm91bmRzSW5kaWNlcy5sZW5ndGgpO1xuICAgIH1cblxuICAgIF9tYWtlR2xvYmVUaWxlRGVidWdCdWZmZXJzKGNvbnRleHQ6IENvbnRleHQsIHRyYW5zZm9ybTogVHJhbnNmb3JtKSB7XG4gICAgICAgIGNvbnN0IHByb2plY3Rpb24gPSB0cmFuc2Zvcm0ucHJvamVjdGlvbjtcbiAgICAgICAgaWYgKCFwcm9qZWN0aW9uIHx8IHByb2plY3Rpb24ubmFtZSAhPT0gJ2dsb2JlJyB8fCB0cmFuc2Zvcm0uZnJlZXplVGlsZUNvdmVyYWdlKSByZXR1cm47XG5cbiAgICAgICAgY29uc3QgaWQgPSB0aGlzLnRpbGVJRC5jYW5vbmljYWw7XG4gICAgICAgIGNvbnN0IGJvdW5kcyA9IHRyYW5zaXRpb25UaWxlQUFCQmluRUNFRihpZCwgdHJhbnNmb3JtKTtcbiAgICAgICAgY29uc3Qgbm9ybWFsaXphdGlvbk1hdHJpeCA9IGdsb2JlTm9ybWFsaXplRUNFRihib3VuZHMpO1xuXG4gICAgICAgIGNvbnN0IHBoYXNlID0gZ2xvYmVUb01lcmNhdG9yVHJhbnNpdGlvbih0cmFuc2Zvcm0uem9vbSk7XG4gICAgICAgIGxldCB3b3JsZFRvRUNFRk1hdHJpeDtcbiAgICAgICAgaWYgKHBoYXNlID4gMC4wKSB7XG4gICAgICAgICAgICB3b3JsZFRvRUNFRk1hdHJpeCA9IG1hdDQuaW52ZXJ0KG5ldyBGbG9hdDY0QXJyYXkoMTYpLCB0cmFuc2Zvcm0uZ2xvYmVNYXRyaXgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fbWFrZUdsb2JlVGlsZURlYnVnQm9yZGVyQnVmZmVyKGNvbnRleHQsIGlkLCB0cmFuc2Zvcm0sIG5vcm1hbGl6YXRpb25NYXRyaXgsIHdvcmxkVG9FQ0VGTWF0cml4LCBwaGFzZSk7XG4gICAgICAgIHRoaXMuX21ha2VHbG9iZVRpbGVEZWJ1Z1RleHRCdWZmZXIoY29udGV4dCwgaWQsIHRyYW5zZm9ybSwgbm9ybWFsaXphdGlvbk1hdHJpeCwgd29ybGRUb0VDRUZNYXRyaXgsIHBoYXNlKTtcbiAgICB9XG5cbiAgICBfZ2xvYmVQb2ludCh4OiBudW1iZXIsIHk6IG51bWJlciwgaWQ6IENhbm9uaWNhbFRpbGVJRCwgdHI6IFRyYW5zZm9ybSwgbm9ybWFsaXphdGlvbk1hdHJpeDogRmxvYXQ2NEFycmF5LCB3b3JsZFRvRUNFRk1hdHJpeD86IEZsb2F0NjRBcnJheSwgcGhhc2U6IG51bWJlcik6IFZlYzMge1xuICAgICAgICAvLyBUaGUgZm9sbG93aW5nIGlzIGVxdWl2YWxlbnQgdG8gZG9pbmcgZ2xvYmUucHJvamVjdFRpbGVQb2ludC5cbiAgICAgICAgLy8gVGhpcyB3YXkgd2UgZG9uJ3QgcmVjb21wdXRlIHRoZSBub3JtYWxpemF0aW9uIG1hdHJpeCBldmVyeXRpbWUgc2luY2UgaXQgcmVtYWlucyB0aGUgc2FtZSBmb3IgYWxsIHBvaW50cy5cbiAgICAgICAgbGV0IGVjZWYgPSB0aWxlQ29vcmRUb0VDRUYoeCwgeSwgaWQpO1xuICAgICAgICBpZiAod29ybGRUb0VDRUZNYXRyaXgpIHtcbiAgICAgICAgICAgIC8vIFdoZW4gaW4gZ2xvYmUtdG8tTWVyY2F0b3IgdHJhbnNpdGlvbiwgaW50ZXJwb2xhdGUgYmV0d2VlbiBnbG9iZSBhbmQgTWVyY2F0b3IgcG9zaXRpb25zIGluIEVDRUZcbiAgICAgICAgICAgIGNvbnN0IHRpbGVDb3VudCA9IDEgPDwgaWQuejtcblxuICAgICAgICAgICAgLy8gV3JhcCB0aWxlcyB0byBlbnN1cmUgdGhhdCB0aGF0IE1lcmNhdG9yIGludGVycG9sYXRpb24gaXMgaW4gdGhlIHJpZ2h0IGRpcmVjdGlvblxuICAgICAgICAgICAgY29uc3QgY2FtWCA9IG1lcmNhdG9yWGZyb21MbmcodHIuY2VudGVyLmxuZyk7XG4gICAgICAgICAgICBjb25zdCBjYW1ZID0gbWVyY2F0b3JZZnJvbUxhdCh0ci5jZW50ZXIubGF0KTtcblxuICAgICAgICAgICAgY29uc3QgdGlsZUNlbnRlclggPSAoaWQueCArIC41KSAvIHRpbGVDb3VudDtcbiAgICAgICAgICAgIGNvbnN0IGR4ID0gdGlsZUNlbnRlclggLSBjYW1YO1xuICAgICAgICAgICAgbGV0IHdyYXAgPSAwO1xuICAgICAgICAgICAgaWYgKGR4ID4gLjUpIHtcbiAgICAgICAgICAgICAgICB3cmFwID0gLTE7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGR4IDwgLS41KSB7XG4gICAgICAgICAgICAgICAgd3JhcCA9IDE7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBtZXJjYXRvclggPSAoeCAvIEVYVEVOVCArIGlkLngpIC8gdGlsZUNvdW50ICsgd3JhcDtcbiAgICAgICAgICAgIGxldCBtZXJjYXRvclkgPSAoeSAvIEVYVEVOVCArIGlkLnkpIC8gdGlsZUNvdW50O1xuICAgICAgICAgICAgbWVyY2F0b3JYID0gKG1lcmNhdG9yWCAtIGNhbVgpICogdHIuX3BpeGVsc1Blck1lcmNhdG9yUGl4ZWwgKyBjYW1YO1xuICAgICAgICAgICAgbWVyY2F0b3JZID0gKG1lcmNhdG9yWSAtIGNhbVkpICogdHIuX3BpeGVsc1Blck1lcmNhdG9yUGl4ZWwgKyBjYW1ZO1xuICAgICAgICAgICAgY29uc3QgbWVyY2F0b3JQb3MgPSBbbWVyY2F0b3JYICogdHIud29ybGRTaXplLCBtZXJjYXRvclkgKiB0ci53b3JsZFNpemUsIDBdO1xuICAgICAgICAgICAgdmVjMy50cmFuc2Zvcm1NYXQ0KG1lcmNhdG9yUG9zLCBtZXJjYXRvclBvcywgd29ybGRUb0VDRUZNYXRyaXgpO1xuICAgICAgICAgICAgZWNlZiA9IGludGVycG9sYXRlVmVjMyhlY2VmLCBtZXJjYXRvclBvcywgcGhhc2UpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGdwID0gdmVjMy50cmFuc2Zvcm1NYXQ0KGVjZWYsIGVjZWYsIG5vcm1hbGl6YXRpb25NYXRyaXgpO1xuICAgICAgICByZXR1cm4gZ3A7XG4gICAgfVxuXG4gICAgX21ha2VHbG9iZVRpbGVEZWJ1Z0JvcmRlckJ1ZmZlcihjb250ZXh0OiBDb250ZXh0LCBpZDogQ2Fub25pY2FsVGlsZUlELCB0cjogVHJhbnNmb3JtLCBub3JtYWxpemF0aW9uTWF0cml4OiBGbG9hdDY0QXJyYXksIHdvcmxkVG9FQ0VGTWF0cml4PzogRmxvYXQ2NEFycmF5LCBwaGFzZTogbnVtYmVyKSB7XG4gICAgICAgIGNvbnN0IHZlcnRpY2VzID0gbmV3IFBvc0FycmF5KCk7XG4gICAgICAgIGNvbnN0IGluZGljZXMgPSBuZXcgTGluZVN0cmlwSW5kZXhBcnJheSgpO1xuICAgICAgICBjb25zdCBleHRyYUdsb2JlID0gbmV3IFBvc0dsb2JlRXh0QXJyYXkoKTtcblxuICAgICAgICBjb25zdCBhZGRMaW5lID0gKHN4OiBudW1iZXIsIHN5OiBudW1iZXIsIGV4OiBudW1iZXIsIGV5OiBudW1iZXIsIHBvaW50Q291bnQ6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RlcFggPSAoZXggLSBzeCkgLyAocG9pbnRDb3VudCAtIDEpO1xuICAgICAgICAgICAgY29uc3Qgc3RlcFkgPSAoZXkgLSBzeSkgLyAocG9pbnRDb3VudCAtIDEpO1xuXG4gICAgICAgICAgICBjb25zdCB2T2Zmc2V0ID0gdmVydGljZXMubGVuZ3RoO1xuXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBvaW50Q291bnQ7IGkrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHggPSBzeCArIGkgKiBzdGVwWDtcbiAgICAgICAgICAgICAgICBjb25zdCB5ID0gc3kgKyBpICogc3RlcFk7XG4gICAgICAgICAgICAgICAgdmVydGljZXMuZW1wbGFjZUJhY2soeCwgeSk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBncCA9IHRoaXMuX2dsb2JlUG9pbnQoeCwgeSwgaWQsIHRyLCBub3JtYWxpemF0aW9uTWF0cml4LCB3b3JsZFRvRUNFRk1hdHJpeCwgcGhhc2UpO1xuXG4gICAgICAgICAgICAgICAgZXh0cmFHbG9iZS5lbXBsYWNlQmFjayhncFswXSwgZ3BbMV0sIGdwWzJdKTtcbiAgICAgICAgICAgICAgICBpbmRpY2VzLmVtcGxhY2VCYWNrKHZPZmZzZXQgKyBpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBlID0gRVhURU5UO1xuICAgICAgICBhZGRMaW5lKDAsIDAsIGUsIDAsIDE2KTtcbiAgICAgICAgYWRkTGluZShlLCAwLCBlLCBlLCAxNik7XG4gICAgICAgIGFkZExpbmUoZSwgZSwgMCwgZSwgMTYpO1xuICAgICAgICBhZGRMaW5lKDAsIGUsIDAsIDAsIDE2KTtcblxuICAgICAgICB0aGlzLl90aWxlRGVidWdJbmRleEJ1ZmZlciA9IGNvbnRleHQuY3JlYXRlSW5kZXhCdWZmZXIoaW5kaWNlcyk7XG4gICAgICAgIHRoaXMuX3RpbGVEZWJ1Z0J1ZmZlciA9IGNvbnRleHQuY3JlYXRlVmVydGV4QnVmZmVyKHZlcnRpY2VzLCBwb3NBdHRyaWJ1dGVzLm1lbWJlcnMpO1xuICAgICAgICB0aGlzLl9nbG9iZVRpbGVEZWJ1Z0JvcmRlckJ1ZmZlciA9IGNvbnRleHQuY3JlYXRlVmVydGV4QnVmZmVyKGV4dHJhR2xvYmUsIHBvc0F0dHJpYnV0ZXNHbG9iZUV4dC5tZW1iZXJzKTtcbiAgICAgICAgdGhpcy5fdGlsZURlYnVnU2VnbWVudHMgPSBTZWdtZW50VmVjdG9yLnNpbXBsZVNlZ21lbnQoMCwgMCwgdmVydGljZXMubGVuZ3RoLCBpbmRpY2VzLmxlbmd0aCk7XG4gICAgfVxuXG4gICAgX21ha2VHbG9iZVRpbGVEZWJ1Z1RleHRCdWZmZXIoY29udGV4dDogQ29udGV4dCwgaWQ6IENhbm9uaWNhbFRpbGVJRCwgdHI6IFRyYW5zZm9ybSwgbm9ybWFsaXphdGlvbk1hdHJpeDogRmxvYXQ2NEFycmF5LCB3b3JsZFRvRUNFRk1hdHJpeD86IEZsb2F0NjRBcnJheSwgcGhhc2U6IG51bWJlcikge1xuICAgICAgICBjb25zdCBTRUdNRU5UUyA9IDQ7XG4gICAgICAgIGNvbnN0IG51bVZlcnRpY2VzID0gU0VHTUVOVFMgKyAxO1xuICAgICAgICBjb25zdCBzdGVwID0gRVhURU5UIC8gU0VHTUVOVFM7XG5cbiAgICAgICAgY29uc3QgdmVydGljZXMgPSBuZXcgUG9zQXJyYXkoKTtcbiAgICAgICAgY29uc3QgaW5kaWNlcyA9IG5ldyBUcmlhbmdsZUluZGV4QXJyYXkoKTtcbiAgICAgICAgY29uc3QgZXh0cmFHbG9iZSA9IG5ldyBQb3NHbG9iZUV4dEFycmF5KCk7XG5cbiAgICAgICAgY29uc3QgdG90YWxWZXJ0aWNlcyA9IG51bVZlcnRpY2VzICogbnVtVmVydGljZXM7XG4gICAgICAgIGNvbnN0IHRvdGFsVHJpYW5nbGVzID0gU0VHTUVOVFMgKiBTRUdNRU5UUyAqIDI7XG4gICAgICAgIGluZGljZXMucmVzZXJ2ZSh0b3RhbFRyaWFuZ2xlcyk7XG4gICAgICAgIHZlcnRpY2VzLnJlc2VydmUodG90YWxWZXJ0aWNlcyk7XG4gICAgICAgIGV4dHJhR2xvYmUucmVzZXJ2ZSh0b3RhbFZlcnRpY2VzKTtcblxuICAgICAgICBjb25zdCB0b0luZGV4ID0gKGo6IG51bWJlciwgaTogbnVtYmVyKTogbnVtYmVyID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0b3RhbFZlcnRpY2VzICogaiArIGk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gYWRkIHZlcnRpY2VzLlxuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRvdGFsVmVydGljZXM7IGorKykge1xuICAgICAgICAgICAgY29uc3QgeSA9IGogKiBzdGVwO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0b3RhbFZlcnRpY2VzOyBpKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCB4ID0gaSAqIHN0ZXA7XG4gICAgICAgICAgICAgICAgdmVydGljZXMuZW1wbGFjZUJhY2soeCwgeSk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBncCA9IHRoaXMuX2dsb2JlUG9pbnQoeCwgeSwgaWQsIHRyLCBub3JtYWxpemF0aW9uTWF0cml4LCB3b3JsZFRvRUNFRk1hdHJpeCwgcGhhc2UpO1xuICAgICAgICAgICAgICAgIGV4dHJhR2xvYmUuZW1wbGFjZUJhY2soZ3BbMF0sIGdwWzFdLCBncFsyXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBhZGQgaW5kaWNlcy5cbiAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBTRUdNRU5UUzsgaisrKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IFNFR01FTlRTOyBpKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0bCA9IHRvSW5kZXgoaiwgaSk7XG4gICAgICAgICAgICAgICAgY29uc3QgdHIgPSB0b0luZGV4KGosIGkgKyAxKTtcbiAgICAgICAgICAgICAgICBjb25zdCBibCA9IHRvSW5kZXgoaiArIDEsIGkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJyID0gdG9JbmRleChqICsgMSwgaSArIDEpO1xuXG4gICAgICAgICAgICAgICAgLy8gZmlyc3QgdHJpYW5nbGUgb2YgdGhlIHN1Yi1wYXRjaC5cbiAgICAgICAgICAgICAgICBpbmRpY2VzLmVtcGxhY2VCYWNrKHRsLCB0ciwgYmwpO1xuXG4gICAgICAgICAgICAgICAgLy8gc2Vjb25kIHRyaWFuZ2xlIG9mIHRoZSBzdWItcGF0Y2guXG4gICAgICAgICAgICAgICAgaW5kaWNlcy5lbXBsYWNlQmFjayhibCwgdHIsIGJyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3RpbGVEZWJ1Z1RleHRJbmRleEJ1ZmZlciA9IGNvbnRleHQuY3JlYXRlSW5kZXhCdWZmZXIoaW5kaWNlcyk7XG4gICAgICAgIHRoaXMuX3RpbGVEZWJ1Z1RleHRCdWZmZXIgPSBjb250ZXh0LmNyZWF0ZVZlcnRleEJ1ZmZlcih2ZXJ0aWNlcywgcG9zQXR0cmlidXRlcy5tZW1iZXJzKTtcbiAgICAgICAgdGhpcy5fZ2xvYmVUaWxlRGVidWdUZXh0QnVmZmVyID0gY29udGV4dC5jcmVhdGVWZXJ0ZXhCdWZmZXIoZXh0cmFHbG9iZSwgcG9zQXR0cmlidXRlc0dsb2JlRXh0Lm1lbWJlcnMpO1xuICAgICAgICB0aGlzLl90aWxlRGVidWdUZXh0U2VnbWVudHMgPSBTZWdtZW50VmVjdG9yLnNpbXBsZVNlZ21lbnQoMCwgMCwgdG90YWxWZXJ0aWNlcywgdG90YWxUcmlhbmdsZXMpO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgVGlsZTtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCB7ZXh0ZW5kfSBmcm9tICcuLi91dGlsL3V0aWwuanMnO1xuaW1wb3J0IFRpbGUgZnJvbSAnLi90aWxlLmpzJztcbmltcG9ydCB0eXBlIHtGZWF0dXJlU3RhdGV9IGZyb20gJy4uL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi9pbmRleC5qcyc7XG5pbXBvcnQgdHlwZSBQYWludGVyIGZyb20gJy4uL3JlbmRlci9wYWludGVyLmpzJztcblxuZXhwb3J0IHR5cGUgRmVhdHVyZVN0YXRlcyA9IHtbZmVhdHVyZV9pZDogc3RyaW5nXTogRmVhdHVyZVN0YXRlfTtcbmV4cG9ydCB0eXBlIExheWVyRmVhdHVyZVN0YXRlcyA9IHtbbGF5ZXI6IHN0cmluZ106IEZlYXR1cmVTdGF0ZXN9O1xuXG4vKipcbiAqIFNvdXJjZUZlYXR1cmVTdGF0ZSBtYW5hZ2VzIHRoZSBzdGF0ZSBhbmQgcGVuZGluZyBjaGFuZ2VzXG4gKiB0byBmZWF0dXJlcyBpbiBhIHNvdXJjZSwgc2VwYXJhdGVkIGJ5IHNvdXJjZSBsYXllci5cbiAqIHN0YXRlQ2hhbmdlcyBhbmQgZGVsZXRlZFN0YXRlcyBiYXRjaCBhbGwgY2hhbmdlcyB0byB0aGUgdGlsZSAodXBkYXRlcyBhbmQgcmVtb3ZlcywgcmVzcGVjdGl2ZWx5KVxuICogYmV0d2VlbiBjb2FsZXNjZSgpIGV2ZW50cy4gYWRkRmVhdHVyZVN0YXRlKCkgYW5kIHJlbW92ZUZlYXR1cmVTdGF0ZSgpIGFsc28gdXBkYXRlIHRoZWlyIGNvdW50ZXJwYXJ0J3NcbiAqIGxpc3Qgb2YgY2hhbmdlcywgc3VjaCB0aGF0IGNvYWxlc2NlKCkgY2FuIGFwcGx5IHRoZSBwcm9wZXIgc3RhdGUgY2hhbmdlcyB3aGlsZSBhZ25vc3RpYyB0byB0aGUgb3JkZXIgb2Ygb3BlcmF0aW9ucy5cbiAqIEluIGRlbGV0ZWRTdGF0ZXMsIGFsbCBudWxsJ3MgZGVub3RlIGNvbXBsZXRlIHJlbW92YWwgb2Ygc3RhdGUgYXQgdGhhdCBzY29wZVxuICogQHByaXZhdGVcbiovXG5jbGFzcyBTb3VyY2VGZWF0dXJlU3RhdGUge1xuICAgIHN0YXRlOiBMYXllckZlYXR1cmVTdGF0ZXM7XG4gICAgc3RhdGVDaGFuZ2VzOiBMYXllckZlYXR1cmVTdGF0ZXM7XG4gICAgZGVsZXRlZFN0YXRlczoge307XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHt9O1xuICAgICAgICB0aGlzLnN0YXRlQ2hhbmdlcyA9IHt9O1xuICAgICAgICB0aGlzLmRlbGV0ZWRTdGF0ZXMgPSB7fTtcbiAgICB9XG5cbiAgICB1cGRhdGVTdGF0ZShzb3VyY2VMYXllcjogc3RyaW5nLCBmZWF0dXJlSWQ6IG51bWJlciB8IHN0cmluZywgbmV3U3RhdGU6IE9iamVjdCkge1xuICAgICAgICBjb25zdCBmZWF0dXJlID0gU3RyaW5nKGZlYXR1cmVJZCk7XG4gICAgICAgIHRoaXMuc3RhdGVDaGFuZ2VzW3NvdXJjZUxheWVyXSA9IHRoaXMuc3RhdGVDaGFuZ2VzW3NvdXJjZUxheWVyXSB8fCB7fTtcbiAgICAgICAgdGhpcy5zdGF0ZUNoYW5nZXNbc291cmNlTGF5ZXJdW2ZlYXR1cmVdID0gdGhpcy5zdGF0ZUNoYW5nZXNbc291cmNlTGF5ZXJdW2ZlYXR1cmVdIHx8IHt9O1xuICAgICAgICBleHRlbmQodGhpcy5zdGF0ZUNoYW5nZXNbc291cmNlTGF5ZXJdW2ZlYXR1cmVdLCBuZXdTdGF0ZSk7XG5cbiAgICAgICAgaWYgKHRoaXMuZGVsZXRlZFN0YXRlc1tzb3VyY2VMYXllcl0gPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuZGVsZXRlZFN0YXRlc1tzb3VyY2VMYXllcl0gPSB7fTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgZnQgaW4gdGhpcy5zdGF0ZVtzb3VyY2VMYXllcl0pIHtcbiAgICAgICAgICAgICAgICBpZiAoZnQgIT09IGZlYXR1cmUpIHRoaXMuZGVsZXRlZFN0YXRlc1tzb3VyY2VMYXllcl1bZnRdID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGZlYXR1cmVEZWxldGlvblF1ZXVlZCA9IHRoaXMuZGVsZXRlZFN0YXRlc1tzb3VyY2VMYXllcl0gJiYgdGhpcy5kZWxldGVkU3RhdGVzW3NvdXJjZUxheWVyXVtmZWF0dXJlXSA9PT0gbnVsbDtcbiAgICAgICAgICAgIGlmIChmZWF0dXJlRGVsZXRpb25RdWV1ZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRlbGV0ZWRTdGF0ZXNbc291cmNlTGF5ZXJdW2ZlYXR1cmVdID0ge307XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBwcm9wIGluIHRoaXMuc3RhdGVbc291cmNlTGF5ZXJdW2ZlYXR1cmVdKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghbmV3U3RhdGVbcHJvcF0pIHRoaXMuZGVsZXRlZFN0YXRlc1tzb3VyY2VMYXllcl1bZmVhdHVyZV1bcHJvcF0gPSBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gbmV3U3RhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVsZXRpb25JblF1ZXVlID0gdGhpcy5kZWxldGVkU3RhdGVzW3NvdXJjZUxheWVyXSAmJiB0aGlzLmRlbGV0ZWRTdGF0ZXNbc291cmNlTGF5ZXJdW2ZlYXR1cmVdICYmIHRoaXMuZGVsZXRlZFN0YXRlc1tzb3VyY2VMYXllcl1bZmVhdHVyZV1ba2V5XSA9PT0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlbGV0aW9uSW5RdWV1ZSkgZGVsZXRlIHRoaXMuZGVsZXRlZFN0YXRlc1tzb3VyY2VMYXllcl1bZmVhdHVyZV1ba2V5XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZW1vdmVGZWF0dXJlU3RhdGUoc291cmNlTGF5ZXI6IHN0cmluZywgZmVhdHVyZUlkPzogbnVtYmVyIHwgc3RyaW5nLCBrZXk/OiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3Qgc291cmNlTGF5ZXJEZWxldGVkID0gdGhpcy5kZWxldGVkU3RhdGVzW3NvdXJjZUxheWVyXSA9PT0gbnVsbDtcbiAgICAgICAgaWYgKHNvdXJjZUxheWVyRGVsZXRlZCkgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IGZlYXR1cmUgPSBTdHJpbmcoZmVhdHVyZUlkKTtcblxuICAgICAgICB0aGlzLmRlbGV0ZWRTdGF0ZXNbc291cmNlTGF5ZXJdID0gdGhpcy5kZWxldGVkU3RhdGVzW3NvdXJjZUxheWVyXSB8fCB7fTtcblxuICAgICAgICBpZiAoa2V5ICYmIGZlYXR1cmVJZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5kZWxldGVkU3RhdGVzW3NvdXJjZUxheWVyXVtmZWF0dXJlXSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGVsZXRlZFN0YXRlc1tzb3VyY2VMYXllcl1bZmVhdHVyZV0gPSB0aGlzLmRlbGV0ZWRTdGF0ZXNbc291cmNlTGF5ZXJdW2ZlYXR1cmVdIHx8IHt9O1xuICAgICAgICAgICAgICAgIHRoaXMuZGVsZXRlZFN0YXRlc1tzb3VyY2VMYXllcl1bZmVhdHVyZV1ba2V5XSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoZmVhdHVyZUlkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGNvbnN0IHVwZGF0ZUluUXVldWUgPSB0aGlzLnN0YXRlQ2hhbmdlc1tzb3VyY2VMYXllcl0gJiYgdGhpcy5zdGF0ZUNoYW5nZXNbc291cmNlTGF5ZXJdW2ZlYXR1cmVdO1xuICAgICAgICAgICAgaWYgKHVwZGF0ZUluUXVldWUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRlbGV0ZWRTdGF0ZXNbc291cmNlTGF5ZXJdW2ZlYXR1cmVdID0ge307XG4gICAgICAgICAgICAgICAgZm9yIChrZXkgaW4gdGhpcy5zdGF0ZUNoYW5nZXNbc291cmNlTGF5ZXJdW2ZlYXR1cmVdKSB0aGlzLmRlbGV0ZWRTdGF0ZXNbc291cmNlTGF5ZXJdW2ZlYXR1cmVdW2tleV0gPSBudWxsO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuZGVsZXRlZFN0YXRlc1tzb3VyY2VMYXllcl1bZmVhdHVyZV0gPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5kZWxldGVkU3RhdGVzW3NvdXJjZUxheWVyXSA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRTdGF0ZShzb3VyY2VMYXllcjogc3RyaW5nLCBmZWF0dXJlSWQ6IG51bWJlciB8IHN0cmluZyk6IEZlYXR1cmVTdGF0ZXMge1xuICAgICAgICBjb25zdCBmZWF0dXJlID0gU3RyaW5nKGZlYXR1cmVJZCk7XG4gICAgICAgIGNvbnN0IGJhc2UgPSB0aGlzLnN0YXRlW3NvdXJjZUxheWVyXSB8fCB7fTtcbiAgICAgICAgY29uc3QgY2hhbmdlcyA9IHRoaXMuc3RhdGVDaGFuZ2VzW3NvdXJjZUxheWVyXSB8fCB7fTtcblxuICAgICAgICBjb25zdCByZWNvbmNpbGVkU3RhdGUgPSBleHRlbmQoe30sIGJhc2VbZmVhdHVyZV0sIGNoYW5nZXNbZmVhdHVyZV0pO1xuXG4gICAgICAgIC8vcmV0dXJuIGVtcHR5IG9iamVjdCBpZiB0aGUgd2hvbGUgc291cmNlIGxheWVyIGlzIGF3YWl0aW5nIGRlbGV0aW9uXG4gICAgICAgIGlmICh0aGlzLmRlbGV0ZWRTdGF0ZXNbc291cmNlTGF5ZXJdID09PSBudWxsKSByZXR1cm4ge307XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuZGVsZXRlZFN0YXRlc1tzb3VyY2VMYXllcl0pIHtcbiAgICAgICAgICAgIGNvbnN0IGZlYXR1cmVEZWxldGlvbnMgPSB0aGlzLmRlbGV0ZWRTdGF0ZXNbc291cmNlTGF5ZXJdW2ZlYXR1cmVJZF07XG4gICAgICAgICAgICBpZiAoZmVhdHVyZURlbGV0aW9ucyA9PT0gbnVsbCkgcmV0dXJuIHt9O1xuICAgICAgICAgICAgZm9yIChjb25zdCBwcm9wIGluIGZlYXR1cmVEZWxldGlvbnMpIGRlbGV0ZSByZWNvbmNpbGVkU3RhdGVbcHJvcF07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlY29uY2lsZWRTdGF0ZTtcbiAgICB9XG5cbiAgICBpbml0aWFsaXplVGlsZVN0YXRlKHRpbGU6IFRpbGUsIHBhaW50ZXI6ID9QYWludGVyKSB7XG4gICAgICAgIHRpbGUuc2V0RmVhdHVyZVN0YXRlKHRoaXMuc3RhdGUsIHBhaW50ZXIpO1xuICAgIH1cblxuICAgIGNvYWxlc2NlQ2hhbmdlcyh0aWxlczoge1tfOiBhbnldOiBUaWxlfSwgcGFpbnRlcjogYW55KSB7XG4gICAgICAgIC8vdHJhY2sgY2hhbmdlcyB3aXRoIGZ1bGwgc3RhdGUgb2JqZWN0cywgYnV0IG9ubHkgZm9yIGZlYXR1cmVzIHRoYXQgZ290IG1vZGlmaWVkXG4gICAgICAgIGNvbnN0IGZlYXR1cmVzQ2hhbmdlZDogTGF5ZXJGZWF0dXJlU3RhdGVzID0ge307XG5cbiAgICAgICAgZm9yIChjb25zdCBzb3VyY2VMYXllciBpbiB0aGlzLnN0YXRlQ2hhbmdlcykge1xuICAgICAgICAgICAgdGhpcy5zdGF0ZVtzb3VyY2VMYXllcl0gID0gdGhpcy5zdGF0ZVtzb3VyY2VMYXllcl0gfHwge307XG4gICAgICAgICAgICBjb25zdCBsYXllclN0YXRlcyA9IHt9O1xuICAgICAgICAgICAgZm9yIChjb25zdCBmZWF0dXJlIGluIHRoaXMuc3RhdGVDaGFuZ2VzW3NvdXJjZUxheWVyXSkge1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy5zdGF0ZVtzb3VyY2VMYXllcl1bZmVhdHVyZV0pIHRoaXMuc3RhdGVbc291cmNlTGF5ZXJdW2ZlYXR1cmVdID0ge307XG4gICAgICAgICAgICAgICAgZXh0ZW5kKHRoaXMuc3RhdGVbc291cmNlTGF5ZXJdW2ZlYXR1cmVdLCB0aGlzLnN0YXRlQ2hhbmdlc1tzb3VyY2VMYXllcl1bZmVhdHVyZV0pO1xuICAgICAgICAgICAgICAgIGxheWVyU3RhdGVzW2ZlYXR1cmVdID0gdGhpcy5zdGF0ZVtzb3VyY2VMYXllcl1bZmVhdHVyZV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmZWF0dXJlc0NoYW5nZWRbc291cmNlTGF5ZXJdID0gbGF5ZXJTdGF0ZXM7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGNvbnN0IHNvdXJjZUxheWVyIGluIHRoaXMuZGVsZXRlZFN0YXRlcykge1xuICAgICAgICAgICAgdGhpcy5zdGF0ZVtzb3VyY2VMYXllcl0gID0gdGhpcy5zdGF0ZVtzb3VyY2VMYXllcl0gfHwge307XG4gICAgICAgICAgICBjb25zdCBsYXllclN0YXRlcyA9IHt9O1xuXG4gICAgICAgICAgICBpZiAodGhpcy5kZWxldGVkU3RhdGVzW3NvdXJjZUxheWVyXSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgZnQgaW4gdGhpcy5zdGF0ZVtzb3VyY2VMYXllcl0pIHtcbiAgICAgICAgICAgICAgICAgICAgbGF5ZXJTdGF0ZXNbZnRdID0ge307XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGVbc291cmNlTGF5ZXJdW2Z0XSA9IHt9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBmZWF0dXJlIGluIHRoaXMuZGVsZXRlZFN0YXRlc1tzb3VyY2VMYXllcl0pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVsZXRlV2hvbGVGZWF0dXJlU3RhdGUgPSB0aGlzLmRlbGV0ZWRTdGF0ZXNbc291cmNlTGF5ZXJdW2ZlYXR1cmVdID09PSBudWxsO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZGVsZXRlV2hvbGVGZWF0dXJlU3RhdGUpIHRoaXMuc3RhdGVbc291cmNlTGF5ZXJdW2ZlYXR1cmVdID0ge307XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuc3RhdGVbc291cmNlTGF5ZXJdW2ZlYXR1cmVdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyh0aGlzLmRlbGV0ZWRTdGF0ZXNbc291cmNlTGF5ZXJdW2ZlYXR1cmVdKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnN0YXRlW3NvdXJjZUxheWVyXVtmZWF0dXJlXVtrZXldO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGxheWVyU3RhdGVzW2ZlYXR1cmVdID0gdGhpcy5zdGF0ZVtzb3VyY2VMYXllcl1bZmVhdHVyZV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmZWF0dXJlc0NoYW5nZWRbc291cmNlTGF5ZXJdID0gZmVhdHVyZXNDaGFuZ2VkW3NvdXJjZUxheWVyXSB8fCB7fTtcbiAgICAgICAgICAgIGV4dGVuZChmZWF0dXJlc0NoYW5nZWRbc291cmNlTGF5ZXJdLCBsYXllclN0YXRlcyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnN0YXRlQ2hhbmdlcyA9IHt9O1xuICAgICAgICB0aGlzLmRlbGV0ZWRTdGF0ZXMgPSB7fTtcblxuICAgICAgICBpZiAoT2JqZWN0LmtleXMoZmVhdHVyZXNDaGFuZ2VkKS5sZW5ndGggPT09IDApIHJldHVybjtcblxuICAgICAgICBmb3IgKGNvbnN0IGlkIGluIHRpbGVzKSB7XG4gICAgICAgICAgICBjb25zdCB0aWxlID0gdGlsZXNbaWRdO1xuICAgICAgICAgICAgdGlsZS5zZXRGZWF0dXJlU3RhdGUoZmVhdHVyZXNDaGFuZ2VkLCBwYWludGVyKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgU291cmNlRmVhdHVyZVN0YXRlO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IERFTURhdGEgZnJvbSBcIi4vZGVtX2RhdGEuanNcIjtcbmltcG9ydCB7dmVjM30gZnJvbSAnZ2wtbWF0cml4JztcbmltcG9ydCB7bnVtYmVyIGFzIGludGVycG9sYXRlfSBmcm9tICcuLi9zdHlsZS1zcGVjL3V0aWwvaW50ZXJwb2xhdGUuanMnO1xuaW1wb3J0IHtjbGFtcH0gZnJvbSAnLi4vdXRpbC91dGlsLmpzJztcblxuaW1wb3J0IHR5cGUge1ZlYzN9IGZyb20gJ2dsLW1hdHJpeCc7XG5cbmNsYXNzIE1pcExldmVsIHtcbiAgICBzaXplOiBudW1iZXI7XG4gICAgbWluaW11bXM6IEFycmF5PG51bWJlcj47XG4gICAgbWF4aW11bXM6IEFycmF5PG51bWJlcj47XG4gICAgbGVhdmVzOiBBcnJheTxudW1iZXI+O1xuXG4gICAgY29uc3RydWN0b3Ioc2l6ZV86IG51bWJlcikge1xuICAgICAgICB0aGlzLnNpemUgPSBzaXplXztcbiAgICAgICAgdGhpcy5taW5pbXVtcyA9IFtdO1xuICAgICAgICB0aGlzLm1heGltdW1zID0gW107XG4gICAgICAgIHRoaXMubGVhdmVzID0gW107XG4gICAgfVxuXG4gICAgZ2V0RWxldmF0aW9uKHg6IG51bWJlciwgeTogbnVtYmVyKTogeyBtaW46IG51bWJlciwgbWF4OiBudW1iZXJ9IHtcbiAgICAgICAgY29uc3QgaWR4ID0gdGhpcy50b0lkeCh4LCB5KTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG1pbjogdGhpcy5taW5pbXVtc1tpZHhdLFxuICAgICAgICAgICAgbWF4OiB0aGlzLm1heGltdW1zW2lkeF1cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBpc0xlYWYoeDogbnVtYmVyLCB5OiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5sZWF2ZXNbdGhpcy50b0lkeCh4LCB5KV07XG4gICAgfVxuXG4gICAgdG9JZHgoeDogbnVtYmVyLCB5OiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4geSAqIHRoaXMuc2l6ZSArIHg7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBhYWJiUmF5SW50ZXJzZWN0KG1pbjogVmVjMywgbWF4OiBWZWMzLCBwb3M6IFZlYzMsIGRpcjogVmVjMyk6ID9udW1iZXIge1xuICAgIGxldCB0TWluID0gMDtcbiAgICBsZXQgdE1heCA9IE51bWJlci5NQVhfVkFMVUU7XG5cbiAgICBjb25zdCBlcHNpbG9uID0gMWUtMTU7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IDM7IGkrKykge1xuICAgICAgICBpZiAoTWF0aC5hYnMoZGlyW2ldKSA8IGVwc2lsb24pIHtcbiAgICAgICAgICAgIC8vIFBhcmFsbGVsIHJheVxuICAgICAgICAgICAgaWYgKHBvc1tpXSA8IG1pbltpXSB8fCBwb3NbaV0gPiBtYXhbaV0pXG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBvb2QgPSAxLjAgLyBkaXJbaV07XG4gICAgICAgICAgICBsZXQgdDEgPSAobWluW2ldIC0gcG9zW2ldKSAqIG9vZDtcbiAgICAgICAgICAgIGxldCB0MiA9IChtYXhbaV0gLSBwb3NbaV0pICogb29kO1xuICAgICAgICAgICAgaWYgKHQxID4gdDIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0ZW1wID0gdDE7XG4gICAgICAgICAgICAgICAgdDEgPSB0MjtcbiAgICAgICAgICAgICAgICB0MiA9IHRlbXA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodDEgPiB0TWluKVxuICAgICAgICAgICAgICAgIHRNaW4gPSB0MTtcbiAgICAgICAgICAgIGlmICh0MiA8IHRNYXgpXG4gICAgICAgICAgICAgICAgdE1heCA9IHQyO1xuICAgICAgICAgICAgaWYgKHRNaW4gPiB0TWF4KVxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRNaW47XG59XG5cbmZ1bmN0aW9uIHRyaWFuZ2xlUmF5SW50ZXJzZWN0KGF4OiBudW1iZXIsIGF5OiBudW1iZXIsIGF6OiBudW1iZXIsIGJ4OiBudW1iZXIsIGJ5OiBudW1iZXIsIGJ6OiBudW1iZXIsIGN4OiBudW1iZXIsIGN5OiBudW1iZXIsIGN6OiBudW1iZXIsIHBvczogVmVjMywgZGlyOiBWZWMzKTogP251bWJlciB7XG4gICAgLy8gQ29tcHV0ZSBiYXJ5Y2VudHJpYyBjb29yZGluYXRlcyB1IGFuZCB2IHRvIGZpbmQgdGhlIGludGVyc2VjdGlvblxuICAgIGNvbnN0IGFiWCA9IGJ4IC0gYXg7XG4gICAgY29uc3QgYWJZID0gYnkgLSBheTtcbiAgICBjb25zdCBhYlogPSBieiAtIGF6O1xuXG4gICAgY29uc3QgYWNYID0gY3ggLSBheDtcbiAgICBjb25zdCBhY1kgPSBjeSAtIGF5O1xuICAgIGNvbnN0IGFjWiA9IGN6IC0gYXo7XG5cbiAgICAvLyBwdmVjID0gY3Jvc3MoZGlyLCBhKSwgZGV0ID0gZG90KGFiLCBwdmVjKVxuICAgIGNvbnN0IHB2ZWNYID0gZGlyWzFdICogYWNaIC0gZGlyWzJdICogYWNZO1xuICAgIGNvbnN0IHB2ZWNZID0gZGlyWzJdICogYWNYIC0gZGlyWzBdICogYWNaO1xuICAgIGNvbnN0IHB2ZWNaID0gZGlyWzBdICogYWNZIC0gZGlyWzFdICogYWNYO1xuICAgIGNvbnN0IGRldCA9IGFiWCAqIHB2ZWNYICsgYWJZICogcHZlY1kgKyBhYlogKiBwdmVjWjtcblxuICAgIGlmIChNYXRoLmFicyhkZXQpIDwgMWUtMTUpXG4gICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgY29uc3QgaW52RGV0ID0gMS4wIC8gZGV0O1xuICAgIGNvbnN0IHR2ZWNYID0gcG9zWzBdIC0gYXg7XG4gICAgY29uc3QgdHZlY1kgPSBwb3NbMV0gLSBheTtcbiAgICBjb25zdCB0dmVjWiA9IHBvc1syXSAtIGF6O1xuICAgIGNvbnN0IHUgPSAodHZlY1ggKiBwdmVjWCArIHR2ZWNZICogcHZlY1kgKyB0dmVjWiAqIHB2ZWNaKSAqIGludkRldDtcblxuICAgIGlmICh1IDwgMC4wIHx8IHUgPiAxLjApXG4gICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgLy8gcXZlYyA9IGNyb3NzKHR2ZWMsIGFiKVxuICAgIGNvbnN0IHF2ZWNYID0gdHZlY1kgKiBhYlogLSB0dmVjWiAqIGFiWTtcbiAgICBjb25zdCBxdmVjWSA9IHR2ZWNaICogYWJYIC0gdHZlY1ggKiBhYlo7XG4gICAgY29uc3QgcXZlY1ogPSB0dmVjWCAqIGFiWSAtIHR2ZWNZICogYWJYO1xuICAgIGNvbnN0IHYgPSAoZGlyWzBdICogcXZlY1ggKyBkaXJbMV0gKiBxdmVjWSArIGRpclsyXSAqIHF2ZWNaKSAqIGludkRldDtcblxuICAgIGlmICh2IDwgMC4wIHx8IHUgKyB2ID4gMS4wKVxuICAgICAgICByZXR1cm4gbnVsbDtcblxuICAgIHJldHVybiAoYWNYICogcXZlY1ggKyBhY1kgKiBxdmVjWSArIGFjWiAqIHF2ZWNaKSAqIGludkRldDtcbn1cblxuZnVuY3Rpb24gZnJhYyh2OiBudW1iZXIsIGxvOiBudW1iZXIsIGhpOiBudW1iZXIpIHtcbiAgICByZXR1cm4gKHYgLSBsbykgLyAoaGkgLSBsbyk7XG59XG5cbmZ1bmN0aW9uIGRlY29kZUJvdW5kcyh4OiBudW1iZXIsIHk6IG51bWJlciwgZGVwdGg6IG51bWJlciwgYm91bmRzTWlueDogbnVtYmVyLCBib3VuZHNNaW55OiBudW1iZXIsIGJvdW5kc01heHg6IG51bWJlciwgYm91bmRzTWF4eTogbnVtYmVyLCBvdXRNaW46IEFycmF5PG51bWJlcj4sIG91dE1heDogQXJyYXk8bnVtYmVyPikge1xuICAgIGNvbnN0IHNjYWxlID0gMSA8PCBkZXB0aDtcbiAgICBjb25zdCByYW5nZXggPSBib3VuZHNNYXh4IC0gYm91bmRzTWlueDtcbiAgICBjb25zdCByYW5nZXkgPSBib3VuZHNNYXh5IC0gYm91bmRzTWlueTtcblxuICAgIGNvbnN0IG1pblggPSAoeCArIDApIC8gc2NhbGUgKiByYW5nZXggKyBib3VuZHNNaW54O1xuICAgIGNvbnN0IG1heFggPSAoeCArIDEpIC8gc2NhbGUgKiByYW5nZXggKyBib3VuZHNNaW54O1xuICAgIGNvbnN0IG1pblkgPSAoeSArIDApIC8gc2NhbGUgKiByYW5nZXkgKyBib3VuZHNNaW55O1xuICAgIGNvbnN0IG1heFkgPSAoeSArIDEpIC8gc2NhbGUgKiByYW5nZXkgKyBib3VuZHNNaW55O1xuXG4gICAgb3V0TWluWzBdID0gbWluWDtcbiAgICBvdXRNaW5bMV0gPSBtaW5ZO1xuICAgIG91dE1heFswXSA9IG1heFg7XG4gICAgb3V0TWF4WzFdID0gbWF4WTtcbn1cblxuLy8gQSBzbWFsbCBwYWRkaW5nIHZhbHVlIGlzIHVzZWQgd2l0aCBib3VuZGluZyBib3hlcyB0byBleHRlbmQgdGhlIGJvdHRvbSBiZWxvdyBzZWEgbGV2ZWxcbmNvbnN0IGFhYmJTa2lydFBhZGRpbmcgPSAxMDA7XG5cbi8vIEEgc3BhcnNlIG1pbiBtYXggcXVhZCB0cmVlIGZvciBwZXJmb3JtaW5nIGFjY2VsZXJhdGVkIHF1ZXJpZXMgYWdhaW5zdCBkZW0gZWxldmF0aW9uIGRhdGEuXG4vLyBFYWNoIHRyZWUgbm9kZSBzdG9yZXMgdGhlIG1pbmltdW0gYW5kIG1heGltdW0gZWxldmF0aW9uIG9mIGl0cyBjaGlsZHJlbiBub2RlcyBhbmQgYSBmbGFnIHdoZXRoZXIgdGhlIG5vZGUgaXMgYSBsZWFmLlxuLy8gTm9kZSBkYXRhIGlzIHN0b3JlZCBpbiBub24taW50ZXJsZWF2ZWQgYXJyYXlzIHdoZXJlIHRoZSByb290IGlzIGF0IGluZGV4IDAuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEZW1NaW5NYXhRdWFkVHJlZSB7XG4gICAgbWF4aW11bXM6IEFycmF5PG51bWJlcj47XG4gICAgbWluaW11bXM6IEFycmF5PG51bWJlcj47XG4gICAgbGVhdmVzOiBBcnJheTxudW1iZXI+O1xuICAgIGNoaWxkT2Zmc2V0czogQXJyYXk8bnVtYmVyPjtcbiAgICBub2RlQ291bnQ6IG51bWJlcjtcbiAgICBkZW06IERFTURhdGE7XG4gICAgX3NpYmxpbmdPZmZzZXQ6IEFycmF5PEFycmF5PG51bWJlcj4+O1xuXG4gICAgY29uc3RydWN0b3IoZGVtXzogREVNRGF0YSkge1xuICAgICAgICB0aGlzLm1heGltdW1zID0gW107XG4gICAgICAgIHRoaXMubWluaW11bXMgPSBbXTtcbiAgICAgICAgdGhpcy5sZWF2ZXMgPSBbXTtcbiAgICAgICAgdGhpcy5jaGlsZE9mZnNldHMgPSBbXTtcbiAgICAgICAgdGhpcy5ub2RlQ291bnQgPSAwO1xuICAgICAgICB0aGlzLmRlbSA9IGRlbV87XG5cbiAgICAgICAgLy8gUHJlY29tcHV0ZSB0aGUgb3JkZXIgb2YgNCBzaWJsaW5nIG5vZGVzIGluIHRoZSBtZW1vcnkuIFRvcC1sZWZ0LCB0b3AtcmlnaHQsIGJvdHRvbS1sZWZ0LCBib3R0b20tcmlnaHRcbiAgICAgICAgdGhpcy5fc2libGluZ09mZnNldCA9IFtcbiAgICAgICAgICAgIFswLCAwXSxcbiAgICAgICAgICAgIFsxLCAwXSxcbiAgICAgICAgICAgIFswLCAxXSxcbiAgICAgICAgICAgIFsxLCAxXVxuICAgICAgICBdO1xuXG4gICAgICAgIGlmICghdGhpcy5kZW0pXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgY29uc3QgbWlwcyA9IGJ1aWxkRGVtTWlwbWFwKHRoaXMuZGVtKTtcbiAgICAgICAgY29uc3QgbWF4THZsID0gbWlwcy5sZW5ndGggLSAxO1xuXG4gICAgICAgIC8vIENyZWF0ZSB0aGUgcm9vdCBub2RlXG4gICAgICAgIGNvbnN0IHJvb3RNaXAgPSBtaXBzW21heEx2bF07XG4gICAgICAgIGNvbnN0IG1pbiA9IHJvb3RNaXAubWluaW11bXM7XG4gICAgICAgIGNvbnN0IG1heCA9IHJvb3RNaXAubWF4aW11bXM7XG4gICAgICAgIGNvbnN0IGxlYXZlcyA9IHJvb3RNaXAubGVhdmVzO1xuICAgICAgICB0aGlzLl9hZGROb2RlKG1pblswXSwgbWF4WzBdLCBsZWF2ZXNbMF0pO1xuXG4gICAgICAgIC8vIENvbnN0cnVjdCB0aGUgcmVzdCBvZiB0aGUgdHJlZSByZWN1cnNpdmVseVxuICAgICAgICB0aGlzLl9jb25zdHJ1Y3QobWlwcywgMCwgMCwgbWF4THZsLCAwKTtcbiAgICB9XG5cbiAgICAvLyBQZXJmb3JtcyByYXljYXN0IGFnYWluc3QgdGhlIHRyZWUgcm9vdCBvbmx5LiBNaW4gYW5kIG1heCBjb29yZGluYXRlcyBkZWZpbmVzIHRoZSBzaXplIG9mIHRoZSByb290IG5vZGVcbiAgICByYXljYXN0Um9vdChtaW54OiBudW1iZXIsIG1pbnk6IG51bWJlciwgbWF4eDogbnVtYmVyLCBtYXh5OiBudW1iZXIsIHA6IFZlYzMsIGQ6IFZlYzMsIGV4YWdnZXJhdGlvbjogbnVtYmVyID0gMSk6ID9udW1iZXIge1xuICAgICAgICBjb25zdCBtaW4gPSBbbWlueCwgbWlueSwgLWFhYmJTa2lydFBhZGRpbmddO1xuICAgICAgICBjb25zdCBtYXggPSBbbWF4eCwgbWF4eSwgdGhpcy5tYXhpbXVtc1swXSAqIGV4YWdnZXJhdGlvbl07XG4gICAgICAgIHJldHVybiBhYWJiUmF5SW50ZXJzZWN0KG1pbiwgbWF4LCBwLCBkKTtcbiAgICB9XG5cbiAgICByYXljYXN0KHJvb3RNaW54OiBudW1iZXIsIHJvb3RNaW55OiBudW1iZXIsIHJvb3RNYXh4OiBudW1iZXIsIHJvb3RNYXh5OiBudW1iZXIsIHA6IFZlYzMsIGQ6IFZlYzMsIGV4YWdnZXJhdGlvbjogbnVtYmVyID0gMSk6ID9udW1iZXIge1xuICAgICAgICBpZiAoIXRoaXMubm9kZUNvdW50KVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgY29uc3QgdCA9IHRoaXMucmF5Y2FzdFJvb3Qocm9vdE1pbngsIHJvb3RNaW55LCByb290TWF4eCwgcm9vdE1heHksIHAsIGQsIGV4YWdnZXJhdGlvbik7XG4gICAgICAgIGlmICh0ID09IG51bGwpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcblxuICAgICAgICBjb25zdCB0SGl0cyA9IFtdO1xuICAgICAgICBjb25zdCBzb3J0ZWRIaXRzID0gW107XG4gICAgICAgIGNvbnN0IGJvdW5kc01pbiA9IFtdO1xuICAgICAgICBjb25zdCBib3VuZHNNYXggPSBbXTtcblxuICAgICAgICBjb25zdCBzdGFjayA9IFt7XG4gICAgICAgICAgICBpZHg6IDAsXG4gICAgICAgICAgICB0LFxuICAgICAgICAgICAgbm9kZXg6IDAsXG4gICAgICAgICAgICBub2RleTogMCxcbiAgICAgICAgICAgIGRlcHRoOiAwXG4gICAgICAgIH1dO1xuXG4gICAgICAgIC8vIFRyYXZlcnNlIHRoZSB0cmVlIHVudGlsIHNvbWV0aGluZyBpcyBoaXQgb3IgdGhlIHJheSBlc2NhcGVzXG4gICAgICAgIHdoaWxlIChzdGFjay5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb25zdCB7aWR4LCB0LCBub2RleCwgbm9kZXksIGRlcHRofSA9IHN0YWNrLnBvcCgpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5sZWF2ZXNbaWR4XSkge1xuICAgICAgICAgICAgICAgIC8vIENyZWF0ZSAyIHRyaWFuZ2xlcyB0byBhcHByb3hpbWF0ZSB0aGUgc3VyZmFjZSBwbGFuZSBmb3IgbW9yZSBwcmVjaXNlIHRlc3RzXG4gICAgICAgICAgICAgICAgZGVjb2RlQm91bmRzKG5vZGV4LCBub2RleSwgZGVwdGgsIHJvb3RNaW54LCByb290TWlueSwgcm9vdE1heHgsIHJvb3RNYXh5LCBib3VuZHNNaW4sIGJvdW5kc01heCk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBzY2FsZSA9IDEgPDwgZGVwdGg7XG4gICAgICAgICAgICAgICAgY29uc3QgbWlueFV2ID0gKG5vZGV4ICsgMCkgLyBzY2FsZTtcbiAgICAgICAgICAgICAgICBjb25zdCBtYXh4VXYgPSAobm9kZXggKyAxKSAvIHNjYWxlO1xuICAgICAgICAgICAgICAgIGNvbnN0IG1pbnlVdiA9IChub2RleSArIDApIC8gc2NhbGU7XG4gICAgICAgICAgICAgICAgY29uc3QgbWF4eVV2ID0gKG5vZGV5ICsgMSkgLyBzY2FsZTtcblxuICAgICAgICAgICAgICAgIC8vIDQgY29ybmVyIHBvaW50cyBBLCBCLCBDIGFuZCBEIGRlZmluZXMgdGhlIChxdWFkKSBhcmVhIGNvdmVyZWQgYnkgdGhpcyBub2RlXG4gICAgICAgICAgICAgICAgY29uc3QgYXogPSBzYW1wbGVFbGV2YXRpb24obWlueFV2LCBtaW55VXYsIHRoaXMuZGVtKSAqIGV4YWdnZXJhdGlvbjtcbiAgICAgICAgICAgICAgICBjb25zdCBieiA9IHNhbXBsZUVsZXZhdGlvbihtYXh4VXYsIG1pbnlVdiwgdGhpcy5kZW0pICogZXhhZ2dlcmF0aW9uO1xuICAgICAgICAgICAgICAgIGNvbnN0IGN6ID0gc2FtcGxlRWxldmF0aW9uKG1heHhVdiwgbWF4eVV2LCB0aGlzLmRlbSkgKiBleGFnZ2VyYXRpb247XG4gICAgICAgICAgICAgICAgY29uc3QgZHogPSBzYW1wbGVFbGV2YXRpb24obWlueFV2LCBtYXh5VXYsIHRoaXMuZGVtKSAqIGV4YWdnZXJhdGlvbjtcblxuICAgICAgICAgICAgICAgIGNvbnN0IHQwOiBhbnkgPSB0cmlhbmdsZVJheUludGVyc2VjdChcbiAgICAgICAgICAgICAgICAgICAgYm91bmRzTWluWzBdLCBib3VuZHNNaW5bMV0sIGF6LCAgICAgLy8gQVxuICAgICAgICAgICAgICAgICAgICBib3VuZHNNYXhbMF0sIGJvdW5kc01pblsxXSwgYnosICAgICAvLyBCXG4gICAgICAgICAgICAgICAgICAgIGJvdW5kc01heFswXSwgYm91bmRzTWF4WzFdLCBjeiwgICAgIC8vIENcbiAgICAgICAgICAgICAgICAgICAgcCwgZCk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCB0MTogYW55ID0gdHJpYW5nbGVSYXlJbnRlcnNlY3QoXG4gICAgICAgICAgICAgICAgICAgIGJvdW5kc01heFswXSwgYm91bmRzTWF4WzFdLCBjeixcbiAgICAgICAgICAgICAgICAgICAgYm91bmRzTWluWzBdLCBib3VuZHNNYXhbMV0sIGR6LFxuICAgICAgICAgICAgICAgICAgICBib3VuZHNNaW5bMF0sIGJvdW5kc01pblsxXSwgYXosXG4gICAgICAgICAgICAgICAgICAgIHAsIGQpO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgdE1pbiA9IE1hdGgubWluKFxuICAgICAgICAgICAgICAgICAgICB0MCAhPT0gbnVsbCA/IHQwIDogTnVtYmVyLk1BWF9WQUxVRSxcbiAgICAgICAgICAgICAgICAgICAgdDEgIT09IG51bGwgPyB0MSA6IE51bWJlci5NQVhfVkFMVUUpO1xuXG4gICAgICAgICAgICAgICAgLy8gVGhlIHJheSBtaWdodCBnbyBiZWxvdyB0aGUgdHdvIHN1cmZhY2UgdHJpYW5nbGVzIGJ1dCBoaXQgb25lIG9mIHRoZSBzaWRlcy5cbiAgICAgICAgICAgICAgICAvLyBUaGlzIGNvdmVycyB0aGUgY2FzZSBvZiBza2lydCBnZW9tZXRyeSBiZXR3ZWVuIHR3byBkZW0gdGlsZXMgb2YgZGlmZmVyZW50IHpvb20gbGV2ZWxcbiAgICAgICAgICAgICAgICBpZiAodE1pbiA9PT0gTnVtYmVyLk1BWF9WQUxVRSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBoaXRQb3MgPSB2ZWMzLnNjYWxlQW5kQWRkKFtdLCBwLCBkLCB0KTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZnJhY3ggPSBmcmFjKGhpdFBvc1swXSwgYm91bmRzTWluWzBdLCBib3VuZHNNYXhbMF0pO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBmcmFjeSA9IGZyYWMoaGl0UG9zWzFdLCBib3VuZHNNaW5bMV0sIGJvdW5kc01heFsxXSk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGJpbGluZWFyTGVycChheiwgYnosIGR6LCBjeiwgZnJhY3gsIGZyYWN5KSA+PSBoaXRQb3NbMl0pXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdE1pbjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gUGVyZm9ybSBpbnRlcnNlY3Rpb24gdGVzdHMgYWdhaW5zIGVhY2ggb2YgdGhlIDQgY2hpbGQgbm9kZXMgYW5kIHN0b3JlIHJlc3VsdHMgZnJvbSBjbG9zZXN0IHRvIGZ1cnRoZXN0LlxuICAgICAgICAgICAgbGV0IGhpdENvdW50ID0gMDtcblxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9zaWJsaW5nT2Zmc2V0Lmxlbmd0aDsgaSsrKSB7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBjaGlsZE5vZGVYID0gKG5vZGV4IDw8IDEpICsgdGhpcy5fc2libGluZ09mZnNldFtpXVswXTtcbiAgICAgICAgICAgICAgICBjb25zdCBjaGlsZE5vZGVZID0gKG5vZGV5IDw8IDEpICsgdGhpcy5fc2libGluZ09mZnNldFtpXVsxXTtcblxuICAgICAgICAgICAgICAgIC8vIERlY29kZSBub2RlIGFhYmIgZnJvbSB0aGUgbW9ydG9uIGNvZGVcbiAgICAgICAgICAgICAgICBkZWNvZGVCb3VuZHMoY2hpbGROb2RlWCwgY2hpbGROb2RlWSwgZGVwdGggKyAxLCByb290TWlueCwgcm9vdE1pbnksIHJvb3RNYXh4LCByb290TWF4eSwgYm91bmRzTWluLCBib3VuZHNNYXgpO1xuXG4gICAgICAgICAgICAgICAgYm91bmRzTWluWzJdID0gLWFhYmJTa2lydFBhZGRpbmc7XG4gICAgICAgICAgICAgICAgYm91bmRzTWF4WzJdID0gdGhpcy5tYXhpbXVtc1t0aGlzLmNoaWxkT2Zmc2V0c1tpZHhdICsgaV0gKiBleGFnZ2VyYXRpb247XG5cbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhYWJiUmF5SW50ZXJzZWN0KGJvdW5kc01pbiwgYm91bmRzTWF4LCBwLCBkKTtcbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0ICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQnVpbGQgdGhlIHJlc3VsdCBsaXN0IGZyb20gZnVydGhlc3QgdG8gY2xvc2VzdCBoaXQuXG4gICAgICAgICAgICAgICAgICAgIC8vIFRoZSBvcmRlciB3aWxsIGJlIGludmVyc2VkIHdoZW4gYnVpbGRpbmcgdGhlIHN0YWNrXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRIaXQ6IG51bWJlciA9IHJlc3VsdDtcbiAgICAgICAgICAgICAgICAgICAgdEhpdHNbaV0gPSB0SGl0O1xuXG4gICAgICAgICAgICAgICAgICAgIGxldCBhZGRlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGhpdENvdW50ICYmICFhZGRlZDsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodEhpdCA+PSB0SGl0c1tzb3J0ZWRIaXRzW2pdXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvcnRlZEhpdHMuc3BsaWNlKGosIDAsIGkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoIWFkZGVkKVxuICAgICAgICAgICAgICAgICAgICAgICAgc29ydGVkSGl0c1toaXRDb3VudF0gPSBpO1xuICAgICAgICAgICAgICAgICAgICBoaXRDb3VudCsrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ29udGludWUgcmVjdXJzaW9uIGZyb20gY2xvc2VzdCB0byBmdXJ0aGVzdFxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBoaXRDb3VudDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaGl0SWR4ID0gc29ydGVkSGl0c1tpXTtcbiAgICAgICAgICAgICAgICBzdGFjay5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgaWR4OiB0aGlzLmNoaWxkT2Zmc2V0c1tpZHhdICsgaGl0SWR4LFxuICAgICAgICAgICAgICAgICAgICB0OiB0SGl0c1toaXRJZHhdLFxuICAgICAgICAgICAgICAgICAgICBub2RleDogKG5vZGV4IDw8IDEpICsgdGhpcy5fc2libGluZ09mZnNldFtoaXRJZHhdWzBdLFxuICAgICAgICAgICAgICAgICAgICBub2RleTogKG5vZGV5IDw8IDEpICsgdGhpcy5fc2libGluZ09mZnNldFtoaXRJZHhdWzFdLFxuICAgICAgICAgICAgICAgICAgICBkZXB0aDogZGVwdGggKyAxXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBfYWRkTm9kZShtaW46IG51bWJlciwgbWF4OiBudW1iZXIsIGxlYWY6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIHRoaXMubWluaW11bXMucHVzaChtaW4pO1xuICAgICAgICB0aGlzLm1heGltdW1zLnB1c2gobWF4KTtcbiAgICAgICAgdGhpcy5sZWF2ZXMucHVzaChsZWFmKTtcbiAgICAgICAgdGhpcy5jaGlsZE9mZnNldHMucHVzaCgwKTtcbiAgICAgICAgcmV0dXJuIHRoaXMubm9kZUNvdW50Kys7XG4gICAgfVxuXG4gICAgX2NvbnN0cnVjdChtaXBzOiBBcnJheTxNaXBMZXZlbD4sIHg6IG51bWJlciwgeTogbnVtYmVyLCBsdmw6IG51bWJlciwgcGFyZW50SWR4OiBudW1iZXIpIHtcbiAgICAgICAgaWYgKG1pcHNbbHZsXS5pc0xlYWYoeCwgeSkgPT09IDEpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFVwZGF0ZSBwYXJlbnQgb2Zmc2V0XG4gICAgICAgIGlmICghdGhpcy5jaGlsZE9mZnNldHNbcGFyZW50SWR4XSlcbiAgICAgICAgICAgIHRoaXMuY2hpbGRPZmZzZXRzW3BhcmVudElkeF0gPSB0aGlzLm5vZGVDb3VudDtcblxuICAgICAgICAvLyBDb25zdHJ1Y3QgYWxsIDQgY2hpbGRyZW4gYW5kIHBsYWNlIHRoZW0gbmV4dCB0byBlYWNoIG90aGVyIGluIG1lbW9yeVxuICAgICAgICBjb25zdCBjaGlsZEx2bCA9IGx2bCAtIDE7XG4gICAgICAgIGNvbnN0IGNoaWxkTWlwID0gbWlwc1tjaGlsZEx2bF07XG5cbiAgICAgICAgbGV0IGxlYWZNYXNrID0gMDtcbiAgICAgICAgbGV0IGZpcnN0Tm9kZUlkeCA9IDA7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9zaWJsaW5nT2Zmc2V0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBjaGlsZFggPSB4ICogMiArIHRoaXMuX3NpYmxpbmdPZmZzZXRbaV1bMF07XG4gICAgICAgICAgICBjb25zdCBjaGlsZFkgPSB5ICogMiArIHRoaXMuX3NpYmxpbmdPZmZzZXRbaV1bMV07XG5cbiAgICAgICAgICAgIGNvbnN0IGVsZXZhdGlvbiA9IGNoaWxkTWlwLmdldEVsZXZhdGlvbihjaGlsZFgsIGNoaWxkWSk7XG4gICAgICAgICAgICBjb25zdCBsZWFmID0gY2hpbGRNaXAuaXNMZWFmKGNoaWxkWCwgY2hpbGRZKTtcbiAgICAgICAgICAgIGNvbnN0IG5vZGVJZHggPSB0aGlzLl9hZGROb2RlKGVsZXZhdGlvbi5taW4sIGVsZXZhdGlvbi5tYXgsIGxlYWYpO1xuXG4gICAgICAgICAgICBpZiAobGVhZilcbiAgICAgICAgICAgICAgICBsZWFmTWFzayB8PSAxIDw8IGk7XG4gICAgICAgICAgICBpZiAoIWZpcnN0Tm9kZUlkeClcbiAgICAgICAgICAgICAgICBmaXJzdE5vZGVJZHggPSBub2RlSWR4O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ29udGludWUgY29uc3RydWN0aW9uIG9mIHRoZSB0cmVlIHJlY3Vyc2l2ZWx5IHRvIG5vbi1sZWFmIG5vZGVzLlxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX3NpYmxpbmdPZmZzZXQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICghKGxlYWZNYXNrICYgKDEgPDwgaSkpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fY29uc3RydWN0KG1pcHMsIHggKiAyICsgdGhpcy5fc2libGluZ09mZnNldFtpXVswXSwgeSAqIDIgKyB0aGlzLl9zaWJsaW5nT2Zmc2V0W2ldWzFdLCBjaGlsZEx2bCwgZmlyc3ROb2RlSWR4ICsgaSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIGJpbGluZWFyTGVycChwMDA6IGFueSwgcDEwOiBhbnksIHAwMTogYW55LCBwMTE6IGFueSwgeDogbnVtYmVyLCB5OiBudW1iZXIpOiBhbnkge1xuICAgIHJldHVybiBpbnRlcnBvbGF0ZShcbiAgICAgICAgaW50ZXJwb2xhdGUocDAwLCBwMDEsIHkpLFxuICAgICAgICBpbnRlcnBvbGF0ZShwMTAsIHAxMSwgeSksXG4gICAgICAgIHgpO1xufVxuXG4vLyBTYW1wbGUgZWxldmF0aW9uIGluIG5vcm1hbGl6ZWQgdXYtc3BhY2UgKFswLCAwXSBpcyB0aGUgdG9wIGxlZnQpXG4vLyBUaGlzIGZ1bmN0aW9uIGRvZXMgbm90IGFjY291bnQgZm9yIGV4YWdnZXJhdGlvblxuZXhwb3J0IGZ1bmN0aW9uIHNhbXBsZUVsZXZhdGlvbihmeDogbnVtYmVyLCBmeTogbnVtYmVyLCBkZW06IERFTURhdGEpOiBudW1iZXIge1xuICAgIC8vIFNhbXBsZSBwb3NpdGlvbiBpbiB0ZXhlbHNcbiAgICBjb25zdCBkZW1TaXplID0gZGVtLmRpbTtcbiAgICBjb25zdCB4ID0gY2xhbXAoZnggKiBkZW1TaXplIC0gMC41LCAwLCBkZW1TaXplIC0gMSk7XG4gICAgY29uc3QgeSA9IGNsYW1wKGZ5ICogZGVtU2l6ZSAtIDAuNSwgMCwgZGVtU2l6ZSAtIDEpO1xuXG4gICAgLy8gQ29tcHV0ZSA0IGNvcm5lciBwb2ludHMgZm9yIGJpbGluZWFyIGludGVycG9sYXRpb25cbiAgICBjb25zdCBpeE1pbiA9IE1hdGguZmxvb3IoeCk7XG4gICAgY29uc3QgaXlNaW4gPSBNYXRoLmZsb29yKHkpO1xuICAgIGNvbnN0IGl4TWF4ID0gTWF0aC5taW4oaXhNaW4gKyAxLCBkZW1TaXplIC0gMSk7XG4gICAgY29uc3QgaXlNYXggPSBNYXRoLm1pbihpeU1pbiArIDEsIGRlbVNpemUgLSAxKTtcblxuICAgIGNvbnN0IGUwMCA9IGRlbS5nZXQoaXhNaW4sIGl5TWluKTtcbiAgICBjb25zdCBlMTAgPSBkZW0uZ2V0KGl4TWF4LCBpeU1pbik7XG4gICAgY29uc3QgZTAxID0gZGVtLmdldChpeE1pbiwgaXlNYXgpO1xuICAgIGNvbnN0IGUxMSA9IGRlbS5nZXQoaXhNYXgsIGl5TWF4KTtcblxuICAgIHJldHVybiBiaWxpbmVhckxlcnAoZTAwLCBlMTAsIGUwMSwgZTExLCB4IC0gaXhNaW4sIHkgLSBpeU1pbik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZERlbU1pcG1hcChkZW06IERFTURhdGEpOiBBcnJheTxNaXBMZXZlbD4ge1xuICAgIGNvbnN0IGRlbVNpemUgPSBkZW0uZGltO1xuXG4gICAgY29uc3QgZWxldmF0aW9uRGlmZlRocmVzaG9sZCA9IDU7XG4gICAgY29uc3QgdGV4ZWxTaXplT2ZNaXAwID0gODtcbiAgICBjb25zdCBsZXZlbENvdW50ID0gTWF0aC5jZWlsKE1hdGgubG9nMihkZW1TaXplIC8gdGV4ZWxTaXplT2ZNaXAwKSk7XG4gICAgY29uc3QgbWlwczogQXJyYXk8TWlwTGV2ZWw+ID0gW107XG5cbiAgICBsZXQgYmxvY2tDb3VudCA9IE1hdGguY2VpbChNYXRoLnBvdygyLCBsZXZlbENvdW50KSk7XG4gICAgY29uc3QgYmxvY2tTaXplID0gMSAvIGJsb2NrQ291bnQ7XG5cbiAgICBjb25zdCBibG9ja1NhbXBsZXMgPSAoeDogbnVtYmVyLCB5OiBudW1iZXIsIHNpemU6IG51bWJlciwgZXhjbHVzaXZlOiBib29sZWFuLCBvdXRCb3VuZHM6IEFycmF5PG51bWJlcj4pID0+IHtcbiAgICAgICAgY29uc3QgcGFkZGluZyA9IGV4Y2x1c2l2ZSA/IDEgOiAwO1xuICAgICAgICBjb25zdCBtaW54ID0geCAqIHNpemU7XG4gICAgICAgIGNvbnN0IG1heHggPSAoeCArIDEpICogc2l6ZSAtIHBhZGRpbmc7XG4gICAgICAgIGNvbnN0IG1pbnkgPSB5ICogc2l6ZTtcbiAgICAgICAgY29uc3QgbWF4eSA9ICh5ICsgMSkgKiBzaXplIC0gcGFkZGluZztcblxuICAgICAgICBvdXRCb3VuZHNbMF0gPSBtaW54O1xuICAgICAgICBvdXRCb3VuZHNbMV0gPSBtaW55O1xuICAgICAgICBvdXRCb3VuZHNbMl0gPSBtYXh4O1xuICAgICAgICBvdXRCb3VuZHNbM10gPSBtYXh5O1xuICAgIH07XG5cbiAgICAvLyBUaGUgZmlyc3QgbWlwICgwKSBpcyBidWlsdCBieSBzYW1wbGluZyA0IGNvcm5lciBwb2ludHMgb2YgZWFjaCA4eDggdGV4ZWwgYmxvY2tcbiAgICBsZXQgbWlwID0gbmV3IE1pcExldmVsKGJsb2NrQ291bnQpO1xuICAgIGNvbnN0IGJsb2NrQm91bmRzID0gW107XG5cbiAgICBmb3IgKGxldCBpZHggPSAwOyBpZHggPCBibG9ja0NvdW50ICogYmxvY2tDb3VudDsgaWR4KyspIHtcbiAgICAgICAgY29uc3QgeSA9IE1hdGguZmxvb3IoaWR4IC8gYmxvY2tDb3VudCk7XG4gICAgICAgIGNvbnN0IHggPSBpZHggJSBibG9ja0NvdW50O1xuXG4gICAgICAgIGJsb2NrU2FtcGxlcyh4LCB5LCBibG9ja1NpemUsIGZhbHNlLCBibG9ja0JvdW5kcyk7XG5cbiAgICAgICAgY29uc3QgZTAgPSBzYW1wbGVFbGV2YXRpb24oYmxvY2tCb3VuZHNbMF0sIGJsb2NrQm91bmRzWzFdLCBkZW0pOyAgICAvLyBtaW54LCBtaW55XG4gICAgICAgIGNvbnN0IGUxID0gc2FtcGxlRWxldmF0aW9uKGJsb2NrQm91bmRzWzJdLCBibG9ja0JvdW5kc1sxXSwgZGVtKTsgICAgLy8gbWF4eCwgbWlueVxuICAgICAgICBjb25zdCBlMiA9IHNhbXBsZUVsZXZhdGlvbihibG9ja0JvdW5kc1syXSwgYmxvY2tCb3VuZHNbM10sIGRlbSk7ICAgIC8vIG1heHgsIG1heHlcbiAgICAgICAgY29uc3QgZTMgPSBzYW1wbGVFbGV2YXRpb24oYmxvY2tCb3VuZHNbMF0sIGJsb2NrQm91bmRzWzNdLCBkZW0pOyAgICAvLyBtaW54LCBtYXh5XG5cbiAgICAgICAgbWlwLm1pbmltdW1zLnB1c2goTWF0aC5taW4oZTAsIGUxLCBlMiwgZTMpKTtcbiAgICAgICAgbWlwLm1heGltdW1zLnB1c2goTWF0aC5tYXgoZTAsIGUxLCBlMiwgZTMpKTtcbiAgICAgICAgbWlwLmxlYXZlcy5wdXNoKDEpO1xuICAgIH1cblxuICAgIG1pcHMucHVzaChtaXApO1xuXG4gICAgLy8gQ29uc3RydWN0IHRoZSByZXN0IG9mIHRoZSBtaXAgbGV2ZWxzIGZyb20gYm90dG9tIHRvIHVwXG4gICAgZm9yIChibG9ja0NvdW50IC89IDI7IGJsb2NrQ291bnQgPj0gMTsgYmxvY2tDb3VudCAvPSAyKSB7XG4gICAgICAgIGNvbnN0IHByZXZNaXAgPSBtaXBzW21pcHMubGVuZ3RoIC0gMV07XG5cbiAgICAgICAgbWlwID0gbmV3IE1pcExldmVsKGJsb2NrQ291bnQpO1xuXG4gICAgICAgIGZvciAobGV0IGlkeCA9IDA7IGlkeCA8IGJsb2NrQ291bnQgKiBibG9ja0NvdW50OyBpZHgrKykge1xuICAgICAgICAgICAgY29uc3QgeSA9IE1hdGguZmxvb3IoaWR4IC8gYmxvY2tDb3VudCk7XG4gICAgICAgICAgICBjb25zdCB4ID0gaWR4ICUgYmxvY2tDb3VudDtcblxuICAgICAgICAgICAgLy8gU2FtcGxlIGVsZXZhdGlvbiBvZiBhbGwgNCBjaGlsZHJlbiBtaXAgdGV4ZWxzLiA0IGxlYWYgbm9kZXMgY2FuIGJlIGNvbmNhdGVuYXRlZCBpbnRvIGEgc2luZ2xlXG4gICAgICAgICAgICAvLyBsZWFmIGlmIHRoZSB0b3RhbCBlbGV2YXRpb24gZGlmZmVyZW5jZSBpcyBiZWxvdyB0aGUgdGhyZXNob2xkIHZhbHVlXG4gICAgICAgICAgICBibG9ja1NhbXBsZXMoeCwgeSwgMiwgdHJ1ZSwgYmxvY2tCb3VuZHMpO1xuXG4gICAgICAgICAgICBjb25zdCBlMCA9IHByZXZNaXAuZ2V0RWxldmF0aW9uKGJsb2NrQm91bmRzWzBdLCBibG9ja0JvdW5kc1sxXSk7XG4gICAgICAgICAgICBjb25zdCBlMSA9IHByZXZNaXAuZ2V0RWxldmF0aW9uKGJsb2NrQm91bmRzWzJdLCBibG9ja0JvdW5kc1sxXSk7XG4gICAgICAgICAgICBjb25zdCBlMiA9IHByZXZNaXAuZ2V0RWxldmF0aW9uKGJsb2NrQm91bmRzWzJdLCBibG9ja0JvdW5kc1szXSk7XG4gICAgICAgICAgICBjb25zdCBlMyA9IHByZXZNaXAuZ2V0RWxldmF0aW9uKGJsb2NrQm91bmRzWzBdLCBibG9ja0JvdW5kc1szXSk7XG5cbiAgICAgICAgICAgIGNvbnN0IGwwID0gcHJldk1pcC5pc0xlYWYoYmxvY2tCb3VuZHNbMF0sIGJsb2NrQm91bmRzWzFdKTtcbiAgICAgICAgICAgIGNvbnN0IGwxID0gcHJldk1pcC5pc0xlYWYoYmxvY2tCb3VuZHNbMl0sIGJsb2NrQm91bmRzWzFdKTtcbiAgICAgICAgICAgIGNvbnN0IGwyID0gcHJldk1pcC5pc0xlYWYoYmxvY2tCb3VuZHNbMl0sIGJsb2NrQm91bmRzWzNdKTtcbiAgICAgICAgICAgIGNvbnN0IGwzID0gcHJldk1pcC5pc0xlYWYoYmxvY2tCb3VuZHNbMF0sIGJsb2NrQm91bmRzWzNdKTtcblxuICAgICAgICAgICAgY29uc3QgbWluRWxldmF0aW9uID0gTWF0aC5taW4oZTAubWluLCBlMS5taW4sIGUyLm1pbiwgZTMubWluKTtcbiAgICAgICAgICAgIGNvbnN0IG1heEVsZXZhdGlvbiA9IE1hdGgubWF4KGUwLm1heCwgZTEubWF4LCBlMi5tYXgsIGUzLm1heCk7XG4gICAgICAgICAgICBjb25zdCBjYW5Db25jYXRlbmF0ZSA9IGwwICYmIGwxICYmIGwyICYmIGwzO1xuXG4gICAgICAgICAgICBtaXAubWF4aW11bXMucHVzaChtYXhFbGV2YXRpb24pO1xuICAgICAgICAgICAgbWlwLm1pbmltdW1zLnB1c2gobWluRWxldmF0aW9uKTtcblxuICAgICAgICAgICAgaWYgKG1heEVsZXZhdGlvbiAtIG1pbkVsZXZhdGlvbiA8PSBlbGV2YXRpb25EaWZmVGhyZXNob2xkICYmIGNhbkNvbmNhdGVuYXRlKSB7XG4gICAgICAgICAgICAgICAgLy8gQWxsIHNhbXBsZXMgaGF2ZSB1bmlmb3JtIGVsZXZhdGlvbi4gTWFyayB0aGlzIGFzIGEgbGVhZlxuICAgICAgICAgICAgICAgIG1pcC5sZWF2ZXMucHVzaCgxKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbWlwLmxlYXZlcy5wdXNoKDApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbWlwcy5wdXNoKG1pcCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1pcHM7XG59XG4iLCIvLyBAZmxvd1xuaW1wb3J0IHtSR0JBSW1hZ2V9IGZyb20gJy4uL3V0aWwvaW1hZ2UuanMnO1xuXG5pbXBvcnQge3dhcm5PbmNlLCBjbGFtcH0gZnJvbSAnLi4vdXRpbC91dGlsLmpzJztcbmltcG9ydCB7cmVnaXN0ZXJ9IGZyb20gJy4uL3V0aWwvd2ViX3dvcmtlcl90cmFuc2Zlci5qcyc7XG5pbXBvcnQgRGVtTWluTWF4UXVhZFRyZWUgZnJvbSAnLi9kZW1fdHJlZS5qcyc7XG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbi8vIERFTURhdGEgaXMgYSBkYXRhIHN0cnVjdHVyZSBmb3IgZGVjb2RpbmcsIGJhY2tmaWxsaW5nLCBhbmQgc3RvcmluZyBlbGV2YXRpb24gZGF0YSBmb3IgcHJvY2Vzc2luZyBpbiB0aGUgaGlsbHNoYWRlIHNoYWRlcnNcbi8vIGRhdGEgY2FuIGJlIHBvcHVsYXRlZCBlaXRoZXIgZnJvbSBhIHBuZ3JhdyBpbWFnZSB0aWxlIG9yIGZyb20gc2VybGlhemVkIGRhdGEgc2VudCBiYWNrIGZyb20gYSB3b3JrZXIuIFdoZW4gZGF0YSBpcyBpbml0aWFsbHlcbi8vIGxvYWRlZCBmcm9tIGEgaW1hZ2UgdGlsZSwgd2UgZGVjb2RlIHRoZSBwaXhlbCB2YWx1ZXMgdXNpbmcgdGhlIGFwcHJvcHJpYXRlIGRlY29kaW5nIGZvcm11bGEsIGJ1dCB3ZSBzdG9yZSB0aGVcbi8vIGVsZXZhdGlvbiBkYXRhIGFzIGFuIEludDMyIHZhbHVlLiB3ZSBhZGQgNjU1MzYgKDJeMTYpIHRvIGVsaW1pbmF0ZSBuZWdhdGl2ZSB2YWx1ZXMgYW5kIGVuYWJsZSB0aGUgdXNlIG9mXG4vLyBpbnRlZ2VyIG92ZXJmbG93IHdoZW4gY3JlYXRpbmcgdGhlIHRleHR1cmUgdXNlZCBpbiB0aGUgaGlsbHNoYWRlUHJlcGFyZSBzdGVwLlxuXG4vLyBERU1EYXRhIGFsc28gaGFuZGxlcyB0aGUgYmFja2ZpbGxpbmcgb2YgZGF0YSBmcm9tIGEgdGlsZSdzIG5laWdoYm9yaW5nIHRpbGVzLiBUaGlzIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIHdlIHVzZSBhIHBpeGVsJ3MgOFxuLy8gc3Vycm91bmRpbmcgcGl4ZWwgdmFsdWVzIHRvIGNvbXB1dGUgdGhlIHNsb3BlIGF0IHRoYXQgcGl4ZWwsIGFuZCB3ZSBjYW5ub3QgYWNjdXJhdGVseSBjYWxjdWxhdGUgdGhlIHNsb3BlIGF0IHBpeGVscyBvbiBhXG4vLyB0aWxlJ3MgZWRnZSB3aXRob3V0IGJhY2tmaWxsaW5nIGZyb20gbmVpZ2hib3JpbmcgdGlsZXMuXG5cbmV4cG9ydCB0eXBlIERFTUVuY29kaW5nID0gXCJtYXBib3hcIiB8IFwidGVycmFyaXVtXCI7XG5cbmNvbnN0IHVucGFja1ZlY3RvcnMgPSB7XG4gICAgbWFwYm94OiBbNjU1My42LCAyNS42LCAwLjEsIDEwMDAwLjBdLFxuICAgIHRlcnJhcml1bTogWzI1Ni4wLCAxLjAsIDEuMCAvIDI1Ni4wLCAzMjc2OC4wXVxufTtcblxuZnVuY3Rpb24gdW5wYWNrTWFwYm94KHI6IG51bWJlciwgZzogbnVtYmVyLCBiOiBudW1iZXIpOiBudW1iZXIge1xuICAgIC8vIHVucGFja2luZyBmb3JtdWxhIGZvciBtYXBib3gudGVycmFpbi1yZ2I6XG4gICAgLy8gaHR0cHM6Ly93d3cubWFwYm94LmNvbS9oZWxwL2FjY2Vzcy1lbGV2YXRpb24tZGF0YS8jbWFwYm94LXRlcnJhaW4tcmdiXG4gICAgcmV0dXJuICgociAqIDI1NiAqIDI1NiArIGcgKiAyNTYuMCArIGIpIC8gMTAuMCAtIDEwMDAwLjApO1xufVxuXG5mdW5jdGlvbiB1bnBhY2tUZXJyYXJpdW0ocjogbnVtYmVyLCBnOiBudW1iZXIsIGI6IG51bWJlcik6IG51bWJlciB7XG4gICAgLy8gdW5wYWNraW5nIGZvcm11bGEgZm9yIG1hcHplbiB0ZXJyYXJpdW06XG4gICAgLy8gaHR0cHM6Ly9hd3MuYW1hem9uLmNvbS9wdWJsaWMtZGF0YXNldHMvdGVycmFpbi9cbiAgICByZXR1cm4gKChyICogMjU2ICsgZyArIGIgLyAyNTYpIC0gMzI3NjguMCk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIERFTURhdGEge1xuICAgIHVpZDogbnVtYmVyO1xuICAgIHBpeGVsczogVWludDhBcnJheTtcbiAgICBzdHJpZGU6IG51bWJlcjtcbiAgICBkaW06IG51bWJlcjtcbiAgICBlbmNvZGluZzogREVNRW5jb2Rpbmc7XG4gICAgYm9yZGVyUmVhZHk6IGJvb2xlYW47XG4gICAgX3RyZWU6IERlbU1pbk1heFF1YWRUcmVlO1xuICAgIGdldCB0cmVlKCk6IERlbU1pbk1heFF1YWRUcmVlIHtcbiAgICAgICAgaWYgKCF0aGlzLl90cmVlKSB0aGlzLl9idWlsZFF1YWRUcmVlKCk7XG4gICAgICAgIHJldHVybiB0aGlzLl90cmVlO1xuICAgIH1cblxuICAgIC8vIFJHQkFJbWFnZSBkYXRhIGhhcyB1bmlmb3JtIDFweCBwYWRkaW5nIG9uIGFsbCBzaWRlczogc3F1YXJlIHRpbGUgZWRnZSBzaXplIGRlZmluZXMgc3RyaWRlXG4gICAgLy8gYW5kIGRpbSBpcyBjYWxjdWxhdGVkIGFzIHN0cmlkZSAtIDIuXG4gICAgY29uc3RydWN0b3IodWlkOiBudW1iZXIsIGRhdGE6IEltYWdlRGF0YSwgZW5jb2Rpbmc6IERFTUVuY29kaW5nLCBib3JkZXJSZWFkeTogYm9vbGVhbiA9IGZhbHNlLCBidWlsZFF1YWRUcmVlOiBib29sZWFuID0gZmFsc2UpOiB2b2lkIHtcbiAgICAgICAgdGhpcy51aWQgPSB1aWQ7XG4gICAgICAgIGlmIChkYXRhLmhlaWdodCAhPT0gZGF0YS53aWR0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0RFTSB0aWxlcyBtdXN0IGJlIHNxdWFyZScpO1xuICAgICAgICBpZiAoZW5jb2RpbmcgJiYgZW5jb2RpbmcgIT09IFwibWFwYm94XCIgJiYgZW5jb2RpbmcgIT09IFwidGVycmFyaXVtXCIpIHJldHVybiB3YXJuT25jZShcbiAgICAgICAgICAgIGBcIiR7ZW5jb2Rpbmd9XCIgaXMgbm90IGEgdmFsaWQgZW5jb2RpbmcgdHlwZS4gVmFsaWQgdHlwZXMgaW5jbHVkZSBcIm1hcGJveFwiIGFuZCBcInRlcnJhcml1bVwiLmBcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5zdHJpZGUgPSBkYXRhLmhlaWdodDtcbiAgICAgICAgY29uc3QgZGltID0gdGhpcy5kaW0gPSBkYXRhLmhlaWdodCAtIDI7XG4gICAgICAgIGNvbnN0IHZhbHVlcyA9IG5ldyBVaW50MzJBcnJheShkYXRhLmRhdGEuYnVmZmVyKTtcbiAgICAgICAgdGhpcy5waXhlbHMgPSBuZXcgVWludDhBcnJheShkYXRhLmRhdGEuYnVmZmVyKTtcbiAgICAgICAgdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nIHx8ICdtYXBib3gnO1xuICAgICAgICB0aGlzLmJvcmRlclJlYWR5ID0gYm9yZGVyUmVhZHk7XG5cbiAgICAgICAgaWYgKGJvcmRlclJlYWR5KSByZXR1cm47XG5cbiAgICAgICAgLy8gaW4gb3JkZXIgdG8gYXZvaWQgZmxhc2hpbmcgc2VhbXMgYmV0d2VlbiB0aWxlcywgaGVyZSB3ZSBhcmUgaW5pdGlhbGx5IHBvcHVsYXRpbmcgYSAxcHggYm9yZGVyIG9mIHBpeGVscyBhcm91bmQgdGhlIGltYWdlXG4gICAgICAgIC8vIHdpdGggdGhlIGRhdGEgb2YgdGhlIG5lYXJlc3QgcGl4ZWwgZnJvbSB0aGUgaW1hZ2UuIHRoaXMgZGF0YSBpcyBldmVudHVhbGx5IHJlcGxhY2VkIHdoZW4gdGhlIHRpbGUncyBuZWlnaGJvcmluZ1xuICAgICAgICAvLyB0aWxlcyBhcmUgbG9hZGVkIGFuZCB0aGUgYWNjdXJhdGUgZGF0YSBjYW4gYmUgYmFja2ZpbGxlZCB1c2luZyBERU1EYXRhI2JhY2tmaWxsQm9yZGVyXG4gICAgICAgIGZvciAobGV0IHggPSAwOyB4IDwgZGltOyB4KyspIHtcbiAgICAgICAgICAgIC8vIGxlZnQgdmVydGljYWwgYm9yZGVyXG4gICAgICAgICAgICB2YWx1ZXNbdGhpcy5faWR4KC0xLCB4KV0gPSB2YWx1ZXNbdGhpcy5faWR4KDAsIHgpXTtcbiAgICAgICAgICAgIC8vIHJpZ2h0IHZlcnRpY2FsIGJvcmRlclxuICAgICAgICAgICAgdmFsdWVzW3RoaXMuX2lkeChkaW0sIHgpXSA9IHZhbHVlc1t0aGlzLl9pZHgoZGltIC0gMSwgeCldO1xuICAgICAgICAgICAgLy8gbGVmdCBob3Jpem9udGFsIGJvcmRlclxuICAgICAgICAgICAgdmFsdWVzW3RoaXMuX2lkeCh4LCAtMSldID0gdmFsdWVzW3RoaXMuX2lkeCh4LCAwKV07XG4gICAgICAgICAgICAvLyByaWdodCBob3Jpem9udGFsIGJvcmRlclxuICAgICAgICAgICAgdmFsdWVzW3RoaXMuX2lkeCh4LCBkaW0pXSA9IHZhbHVlc1t0aGlzLl9pZHgoeCwgZGltIC0gMSldO1xuICAgICAgICB9XG4gICAgICAgIC8vIGNvcm5lcnNcbiAgICAgICAgdmFsdWVzW3RoaXMuX2lkeCgtMSwgLTEpXSA9IHZhbHVlc1t0aGlzLl9pZHgoMCwgMCldO1xuICAgICAgICB2YWx1ZXNbdGhpcy5faWR4KGRpbSwgLTEpXSA9IHZhbHVlc1t0aGlzLl9pZHgoZGltIC0gMSwgMCldO1xuICAgICAgICB2YWx1ZXNbdGhpcy5faWR4KC0xLCBkaW0pXSA9IHZhbHVlc1t0aGlzLl9pZHgoMCwgZGltIC0gMSldO1xuICAgICAgICB2YWx1ZXNbdGhpcy5faWR4KGRpbSwgZGltKV0gPSB2YWx1ZXNbdGhpcy5faWR4KGRpbSAtIDEsIGRpbSAtIDEpXTtcbiAgICAgICAgaWYgKGJ1aWxkUXVhZFRyZWUpIHRoaXMuX2J1aWxkUXVhZFRyZWUoKTtcbiAgICB9XG5cbiAgICBfYnVpbGRRdWFkVHJlZSgpIHtcbiAgICAgICAgYXNzZXJ0KCF0aGlzLl90cmVlKTtcbiAgICAgICAgLy8gQ29uc3RydWN0IHRoZSBpbXBsaWNpdCBzcGFyc2UgcXVhZCB0cmVlIGJ5IHRyYXZlcnNpbmcgbWlwcyBmcm9tIHRvcCB0byBkb3duXG4gICAgICAgIHRoaXMuX3RyZWUgPSBuZXcgRGVtTWluTWF4UXVhZFRyZWUodGhpcyk7XG4gICAgfVxuXG4gICAgZ2V0KHg6IG51bWJlciwgeTogbnVtYmVyLCBjbGFtcFRvRWRnZTogYm9vbGVhbiA9IGZhbHNlKTogbnVtYmVyIHtcbiAgICAgICAgaWYgKGNsYW1wVG9FZGdlKSB7XG4gICAgICAgICAgICB4ID0gY2xhbXAoeCwgLTEsIHRoaXMuZGltKTtcbiAgICAgICAgICAgIHkgPSBjbGFtcCh5LCAtMSwgdGhpcy5kaW0pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5faWR4KHgsIHkpICogNDtcbiAgICAgICAgY29uc3QgdW5wYWNrID0gdGhpcy5lbmNvZGluZyA9PT0gXCJ0ZXJyYXJpdW1cIiA/IHVucGFja1RlcnJhcml1bSA6IHVucGFja01hcGJveDtcbiAgICAgICAgcmV0dXJuIHVucGFjayh0aGlzLnBpeGVsc1tpbmRleF0sIHRoaXMucGl4ZWxzW2luZGV4ICsgMV0sIHRoaXMucGl4ZWxzW2luZGV4ICsgMl0pO1xuICAgIH1cblxuICAgIHN0YXRpYyBnZXRVbnBhY2tWZWN0b3IoZW5jb2Rpbmc6IERFTUVuY29kaW5nKTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0ge1xuICAgICAgICByZXR1cm4gdW5wYWNrVmVjdG9yc1tlbmNvZGluZ107XG4gICAgfVxuXG4gICAgZ2V0IHVucGFja1ZlY3RvcigpOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSB7XG4gICAgICAgIHJldHVybiB1bnBhY2tWZWN0b3JzW3RoaXMuZW5jb2RpbmddO1xuICAgIH1cblxuICAgIF9pZHgoeDogbnVtYmVyLCB5OiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBpZiAoeCA8IC0xIHx8IHggPj0gdGhpcy5kaW0gKyAxIHx8ICB5IDwgLTEgfHwgeSA+PSB0aGlzLmRpbSArIDEpIHRocm93IG5ldyBSYW5nZUVycm9yKCdvdXQgb2YgcmFuZ2Ugc291cmNlIGNvb3JkaW5hdGVzIGZvciBERU0gZGF0YScpO1xuICAgICAgICByZXR1cm4gKHkgKyAxKSAqIHRoaXMuc3RyaWRlICsgKHggKyAxKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgcGFjayhhbHRpdHVkZTogbnVtYmVyLCBlbmNvZGluZzogREVNRW5jb2RpbmcpOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSB7XG4gICAgICAgIGNvbnN0IGNvbG9yID0gWzAsIDAsIDAsIDBdO1xuICAgICAgICBjb25zdCB2ZWN0b3IgPSBERU1EYXRhLmdldFVucGFja1ZlY3RvcihlbmNvZGluZyk7XG4gICAgICAgIGxldCB2ID0gTWF0aC5mbG9vcigoYWx0aXR1ZGUgKyB2ZWN0b3JbM10pIC8gdmVjdG9yWzJdKTtcbiAgICAgICAgY29sb3JbMl0gPSB2ICUgMjU2O1xuICAgICAgICB2ID0gTWF0aC5mbG9vcih2IC8gMjU2KTtcbiAgICAgICAgY29sb3JbMV0gPSB2ICUgMjU2O1xuICAgICAgICB2ID0gTWF0aC5mbG9vcih2IC8gMjU2KTtcbiAgICAgICAgY29sb3JbMF0gPSB2O1xuICAgICAgICByZXR1cm4gY29sb3I7XG4gICAgfVxuXG4gICAgZ2V0UGl4ZWxzKCk6IFJHQkFJbWFnZSB7XG4gICAgICAgIHJldHVybiBuZXcgUkdCQUltYWdlKHt3aWR0aDogdGhpcy5zdHJpZGUsIGhlaWdodDogdGhpcy5zdHJpZGV9LCB0aGlzLnBpeGVscyk7XG4gICAgfVxuXG4gICAgYmFja2ZpbGxCb3JkZXIoYm9yZGVyVGlsZTogREVNRGF0YSwgZHg6IG51bWJlciwgZHk6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5kaW0gIT09IGJvcmRlclRpbGUuZGltKSB0aHJvdyBuZXcgRXJyb3IoJ2RlbSBkaW1lbnNpb24gbWlzbWF0Y2gnKTtcblxuICAgICAgICBsZXQgeE1pbiA9IGR4ICogdGhpcy5kaW0sXG4gICAgICAgICAgICB4TWF4ID0gZHggKiB0aGlzLmRpbSArIHRoaXMuZGltLFxuICAgICAgICAgICAgeU1pbiA9IGR5ICogdGhpcy5kaW0sXG4gICAgICAgICAgICB5TWF4ID0gZHkgKiB0aGlzLmRpbSArIHRoaXMuZGltO1xuXG4gICAgICAgIHN3aXRjaCAoZHgpIHtcbiAgICAgICAgY2FzZSAtMTpcbiAgICAgICAgICAgIHhNaW4gPSB4TWF4IC0gMTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICB4TWF4ID0geE1pbiArIDE7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIHN3aXRjaCAoZHkpIHtcbiAgICAgICAgY2FzZSAtMTpcbiAgICAgICAgICAgIHlNaW4gPSB5TWF4IC0gMTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICB5TWF4ID0geU1pbiArIDE7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG94ID0gLWR4ICogdGhpcy5kaW07XG4gICAgICAgIGNvbnN0IG95ID0gLWR5ICogdGhpcy5kaW07XG4gICAgICAgIGZvciAobGV0IHkgPSB5TWluOyB5IDwgeU1heDsgeSsrKSB7XG4gICAgICAgICAgICBmb3IgKGxldCB4ID0geE1pbjsgeCA8IHhNYXg7IHgrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGkgPSA0ICogdGhpcy5faWR4KHgsIHkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGogPSA0ICogdGhpcy5faWR4KHggKyBveCwgeSArIG95KTtcbiAgICAgICAgICAgICAgICB0aGlzLnBpeGVsc1tpICsgMF0gPSBib3JkZXJUaWxlLnBpeGVsc1tqICsgMF07XG4gICAgICAgICAgICAgICAgdGhpcy5waXhlbHNbaSArIDFdID0gYm9yZGVyVGlsZS5waXhlbHNbaiArIDFdO1xuICAgICAgICAgICAgICAgIHRoaXMucGl4ZWxzW2kgKyAyXSA9IGJvcmRlclRpbGUucGl4ZWxzW2ogKyAyXTtcbiAgICAgICAgICAgICAgICB0aGlzLnBpeGVsc1tpICsgM10gPSBib3JkZXJUaWxlLnBpeGVsc1tqICsgM107XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbkRlc2VyaWFsaXplKCkge1xuICAgICAgICBpZiAodGhpcy5fdHJlZSkgdGhpcy5fdHJlZS5kZW0gPSB0aGlzO1xuICAgIH1cbn1cblxucmVnaXN0ZXIoREVNRGF0YSwgJ0RFTURhdGEnKTtcbnJlZ2lzdGVyKERlbU1pbk1heFF1YWRUcmVlLCAnRGVtTWluTWF4UXVhZFRyZWUnLCB7b21pdDogWydkZW0nXX0pO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtPdmVyc2NhbGVkVGlsZUlEfSBmcm9tICcuL3RpbGVfaWQuanMnO1xuaW1wb3J0IHR5cGUgVGlsZSBmcm9tICcuL3RpbGUuanMnO1xuXG4vKipcbiAqIEEgW2xlYXN0LXJlY2VudGx5LXVzZWQgY2FjaGVdKGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ2FjaGVfYWxnb3JpdGhtcylcbiAqIHdpdGggaGFzaCBsb29rdXAgbWFkZSBwb3NzaWJsZSBieSBrZWVwaW5nIGEgbGlzdCBvZiBrZXlzIGluIHBhcmFsbGVsIHRvXG4gKiBhbiBhcnJheSBvZiBkaWN0aW9uYXJ5IG9mIHZhbHVlc1xuICpcbiAqIEBwcml2YXRlXG4gKi9cbmNsYXNzIFRpbGVDYWNoZSB7XG4gICAgbWF4OiBudW1iZXI7XG4gICAgZGF0YToge1trZXk6IHN0cmluZyB8IG51bWJlcl06IEFycmF5PHsgdmFsdWU6IFRpbGUsIHRpbWVvdXQ6ID9UaW1lb3V0SUR9Pn07XG4gICAgb3JkZXI6IEFycmF5PG51bWJlcj47XG4gICAgb25SZW1vdmU6IChlbGVtZW50OiBUaWxlKSA9PiB2b2lkO1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBtYXggVGhlIG1heCBudW1iZXIgb2YgcGVybWl0dGVkIHZhbHVlcy5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IG9uUmVtb3ZlIFRoZSBjYWxsYmFjayBjYWxsZWQgd2l0aCBpdGVtcyB3aGVuIHRoZXkgZXhwaXJlLlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG1heDogbnVtYmVyLCBvblJlbW92ZTogKGVsZW1lbnQ6IFRpbGUpID0+IHZvaWQpIHtcbiAgICAgICAgdGhpcy5tYXggPSBtYXg7XG4gICAgICAgIHRoaXMub25SZW1vdmUgPSBvblJlbW92ZTtcbiAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENsZWFyIHRoZSBjYWNoZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtUaWxlQ2FjaGV9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICByZXNldCgpOiB0aGlzIHtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gdGhpcy5kYXRhKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHJlbW92ZWREYXRhIG9mIHRoaXMuZGF0YVtrZXldKSB7XG4gICAgICAgICAgICAgICAgaWYgKHJlbW92ZWREYXRhLnRpbWVvdXQpIGNsZWFyVGltZW91dChyZW1vdmVkRGF0YS50aW1lb3V0KTtcbiAgICAgICAgICAgICAgICB0aGlzLm9uUmVtb3ZlKHJlbW92ZWREYXRhLnZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZGF0YSA9IHt9O1xuICAgICAgICB0aGlzLm9yZGVyID0gW107XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkIGEga2V5LCB2YWx1ZSBjb21iaW5hdGlvbiB0byB0aGUgY2FjaGUsIHRyaW1taW5nIGl0cyBzaXplIGlmIHRoaXMgcHVzaGVzXG4gICAgICogaXQgb3ZlciBtYXggbGVuZ3RoLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPdmVyc2NhbGVkVGlsZUlEfSB0aWxlSUQgbG9va3VwIGtleSBmb3IgdGhlIGl0ZW1cbiAgICAgKiBAcGFyYW0geyp9IGRhdGEgYW55IHZhbHVlXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7VGlsZUNhY2hlfSBSZXR1cm5zIGl0c2VsZiB0byBhbGxvdyBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgYWRkKHRpbGVJRDogT3ZlcnNjYWxlZFRpbGVJRCwgZGF0YTogVGlsZSwgZXhwaXJ5VGltZW91dDogbnVtYmVyIHwgdm9pZCk6IHRoaXMge1xuICAgICAgICBjb25zdCBrZXkgPSB0aWxlSUQud3JhcHBlZCgpLmtleTtcbiAgICAgICAgaWYgKHRoaXMuZGF0YVtrZXldID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YVtrZXldID0gW107XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkYXRhV3JhcHBlciA9IHtcbiAgICAgICAgICAgIHZhbHVlOiBkYXRhLFxuICAgICAgICAgICAgdGltZW91dDogdW5kZWZpbmVkXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKGV4cGlyeVRpbWVvdXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgZGF0YVdyYXBwZXIudGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlKHRpbGVJRCwgZGF0YVdyYXBwZXIpO1xuICAgICAgICAgICAgfSwgZXhwaXJ5VGltZW91dCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmRhdGFba2V5XS5wdXNoKGRhdGFXcmFwcGVyKTtcbiAgICAgICAgdGhpcy5vcmRlci5wdXNoKGtleSk7XG5cbiAgICAgICAgaWYgKHRoaXMub3JkZXIubGVuZ3RoID4gdGhpcy5tYXgpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlbW92ZWREYXRhID0gdGhpcy5fZ2V0QW5kUmVtb3ZlQnlLZXkodGhpcy5vcmRlclswXSk7XG4gICAgICAgICAgICBpZiAocmVtb3ZlZERhdGEpIHRoaXMub25SZW1vdmUocmVtb3ZlZERhdGEpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIHZhbHVlIGF0dGFjaGVkIHRvIGBrZXlgIGlzIHByZXNlbnRcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T3ZlcnNjYWxlZFRpbGVJRH0gdGlsZUlEIHRoZSBrZXkgdG8gYmUgbG9va2VkLXVwXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IHdoZXRoZXIgdGhlIGNhY2hlIGhhcyB0aGlzIHZhbHVlXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBoYXModGlsZUlEOiBPdmVyc2NhbGVkVGlsZUlEKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aWxlSUQud3JhcHBlZCgpLmtleSBpbiB0aGlzLmRhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBhdHRhY2hlZCB0byBhIHNwZWNpZmljIGtleSBhbmQgcmVtb3ZlIGRhdGEgZnJvbSBjYWNoZS5cbiAgICAgKiBJZiB0aGUga2V5IGlzIG5vdCBmb3VuZCwgcmV0dXJucyBgbnVsbGBcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T3ZlcnNjYWxlZFRpbGVJRH0gdGlsZUlEIHRoZSBrZXkgdG8gbG9vayB1cFxuICAgICAqIEByZXR1cm5zIHsqfSB0aGUgZGF0YSwgb3IgbnVsbCBpZiBpdCBpc24ndCBmb3VuZFxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgZ2V0QW5kUmVtb3ZlKHRpbGVJRDogT3ZlcnNjYWxlZFRpbGVJRCk6ID9UaWxlIHtcbiAgICAgICAgaWYgKCF0aGlzLmhhcyh0aWxlSUQpKSB7IHJldHVybiBudWxsOyB9XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRBbmRSZW1vdmVCeUtleSh0aWxlSUQud3JhcHBlZCgpLmtleSk7XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBHZXQgYW5kIHJlbW92ZSB0aGUgdmFsdWUgd2l0aCB0aGUgc3BlY2lmaWVkIGtleS5cbiAgICAgKi9cbiAgICBfZ2V0QW5kUmVtb3ZlQnlLZXkoa2V5OiBudW1iZXIpOiA/VGlsZSB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmRhdGFba2V5XS5zaGlmdCgpO1xuICAgICAgICBpZiAoZGF0YS50aW1lb3V0KSBjbGVhclRpbWVvdXQoZGF0YS50aW1lb3V0KTtcblxuICAgICAgICBpZiAodGhpcy5kYXRhW2tleV0ubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5kYXRhW2tleV07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vcmRlci5zcGxpY2UodGhpcy5vcmRlci5pbmRleE9mKGtleSksIDEpO1xuXG4gICAgICAgIHJldHVybiBkYXRhLnZhbHVlO1xuICAgIH1cblxuICAgIC8qXG4gICAgICogR2V0IHRoZSB2YWx1ZSB3aXRoIHRoZSBzcGVjaWZpZWQgKHdyYXBwZWQgdGlsZSkga2V5LlxuICAgICAqL1xuICAgIGdldEJ5S2V5KGtleTogbnVtYmVyKTogP1RpbGUge1xuICAgICAgICBjb25zdCBkYXRhID0gdGhpcy5kYXRhW2tleV07XG4gICAgICAgIHJldHVybiBkYXRhID8gZGF0YVswXS52YWx1ZSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBhdHRhY2hlZCB0byBhIHNwZWNpZmljIGtleSB3aXRob3V0IHJlbW92aW5nIGRhdGFcbiAgICAgKiBmcm9tIHRoZSBjYWNoZS4gSWYgdGhlIGtleSBpcyBub3QgZm91bmQsIHJldHVybnMgYG51bGxgXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge092ZXJzY2FsZWRUaWxlSUR9IHRpbGVJRCB0aGUga2V5IHRvIGxvb2sgdXBcbiAgICAgKiBAcmV0dXJucyB7Kn0gdGhlIGRhdGEsIG9yIG51bGwgaWYgaXQgaXNuJ3QgZm91bmRcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIGdldCh0aWxlSUQ6IE92ZXJzY2FsZWRUaWxlSUQpOiA/VGlsZSB7XG4gICAgICAgIGlmICghdGhpcy5oYXModGlsZUlEKSkgeyByZXR1cm4gbnVsbDsgfVxuXG4gICAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmRhdGFbdGlsZUlELndyYXBwZWQoKS5rZXldWzBdO1xuICAgICAgICByZXR1cm4gZGF0YS52YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBrZXkvdmFsdWUgY29tYmluYXRpb24gZnJvbSB0aGUgY2FjaGUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge092ZXJzY2FsZWRUaWxlSUR9IHRpbGVJRCB0aGUga2V5IGZvciB0aGUgcGFpciB0byBkZWxldGVcbiAgICAgKiBAcGFyYW0ge1RpbGV9IHZhbHVlIElmIGEgdmFsdWUgaXMgcHJvdmlkZWQsIHJlbW92ZSB0aGF0IGV4YWN0IHZlcnNpb24gb2YgdGhlIHZhbHVlLlxuICAgICAqIEByZXR1cm5zIHtUaWxlQ2FjaGV9IHRoaXMgY2FjaGVcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHJlbW92ZSh0aWxlSUQ6IE92ZXJzY2FsZWRUaWxlSUQsIHZhbHVlOiA/eyB2YWx1ZTogVGlsZSwgdGltZW91dDogP1RpbWVvdXRJRH0pOiB0aGlzIHtcbiAgICAgICAgaWYgKCF0aGlzLmhhcyh0aWxlSUQpKSB7IHJldHVybiB0aGlzOyB9XG4gICAgICAgIGNvbnN0IGtleSA9IHRpbGVJRC53cmFwcGVkKCkua2V5O1xuXG4gICAgICAgIGNvbnN0IGRhdGFJbmRleCA9IHZhbHVlID09PSB1bmRlZmluZWQgPyAwIDogdGhpcy5kYXRhW2tleV0uaW5kZXhPZih2YWx1ZSk7XG4gICAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmRhdGFba2V5XVtkYXRhSW5kZXhdO1xuICAgICAgICB0aGlzLmRhdGFba2V5XS5zcGxpY2UoZGF0YUluZGV4LCAxKTtcbiAgICAgICAgaWYgKGRhdGEudGltZW91dCkgY2xlYXJUaW1lb3V0KGRhdGEudGltZW91dCk7XG4gICAgICAgIGlmICh0aGlzLmRhdGFba2V5XS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmRhdGFba2V5XTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9uUmVtb3ZlKGRhdGEudmFsdWUpO1xuICAgICAgICB0aGlzLm9yZGVyLnNwbGljZSh0aGlzLm9yZGVyLmluZGV4T2Yoa2V5KSwgMSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hhbmdlIHRoZSBtYXggc2l6ZSBvZiB0aGUgY2FjaGUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbWF4IHRoZSBtYXggc2l6ZSBvZiB0aGUgY2FjaGVcbiAgICAgKiBAcmV0dXJucyB7VGlsZUNhY2hlfSB0aGlzIGNhY2hlXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzZXRNYXhTaXplKG1heDogbnVtYmVyKTogVGlsZUNhY2hlIHtcbiAgICAgICAgdGhpcy5tYXggPSBtYXg7XG5cbiAgICAgICAgd2hpbGUgKHRoaXMub3JkZXIubGVuZ3RoID4gdGhpcy5tYXgpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlbW92ZWREYXRhID0gdGhpcy5fZ2V0QW5kUmVtb3ZlQnlLZXkodGhpcy5vcmRlclswXSk7XG4gICAgICAgICAgICBpZiAocmVtb3ZlZERhdGEpIHRoaXMub25SZW1vdmUocmVtb3ZlZERhdGEpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGVudHJpZXMgdGhhdCBkbyBub3QgcGFzcyBhIGZpbHRlciBmdW5jdGlvbi4gVXNlZCBmb3IgcmVtb3ZpbmdcbiAgICAgKiBzdGFsZSB0aWxlcyBmcm9tIHRoZSBjYWNoZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gZmlsdGVyRm4gRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSB0aWxlIGlzIGZpbHRlcmVkLiBJZiB0aGUgc3VwcGxpZWQgZnVuY3Rpb24gcmV0dXJucyBmYWxzZSwgdGhlIHRpbGUgd2lsbCBiZSBmaWx0ZXJlZCBvdXQuXG4gICAgICovXG4gICAgZmlsdGVyKGZpbHRlckZuOiAodGlsZTogVGlsZSkgPT4gYm9vbGVhbikge1xuICAgICAgICBjb25zdCByZW1vdmVkID0gW107XG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIHRoaXMuZGF0YSkge1xuICAgICAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiB0aGlzLmRhdGFba2V5XSkge1xuICAgICAgICAgICAgICAgIGlmICghZmlsdGVyRm4oZW50cnkudmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlbW92ZWQucHVzaChlbnRyeSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgciBvZiByZW1vdmVkKSB7XG4gICAgICAgICAgICB0aGlzLnJlbW92ZShyLnZhbHVlLnRpbGVJRCwgcik7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFRpbGVDYWNoZTtcbiIsIi8vIEBmbG93XG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbmltcG9ydCB0eXBlIHtTdHJ1Y3RBcnJheX0gZnJvbSAnLi4vdXRpbC9zdHJ1Y3RfYXJyYXkuanMnO1xuaW1wb3J0IHR5cGUge1RyaWFuZ2xlSW5kZXhBcnJheSwgTGluZUluZGV4QXJyYXksIExpbmVTdHJpcEluZGV4QXJyYXl9IGZyb20gJy4uL2RhdGEvaW5kZXhfYXJyYXlfdHlwZS5qcyc7XG5pbXBvcnQgdHlwZSBDb250ZXh0IGZyb20gJy4uL2dsL2NvbnRleHQuanMnO1xuXG5jbGFzcyBJbmRleEJ1ZmZlciB7XG4gICAgY29udGV4dDogQ29udGV4dDtcbiAgICBidWZmZXI6ID9XZWJHTEJ1ZmZlcjtcbiAgICBkeW5hbWljRHJhdzogYm9vbGVhbjtcblxuICAgIGNvbnN0cnVjdG9yKGNvbnRleHQ6IENvbnRleHQsIGFycmF5OiBUcmlhbmdsZUluZGV4QXJyYXkgfCBMaW5lSW5kZXhBcnJheSB8IExpbmVTdHJpcEluZGV4QXJyYXksIGR5bmFtaWNEcmF3PzogYm9vbGVhbikge1xuICAgICAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICAgICAgICBjb25zdCBnbCA9IGNvbnRleHQuZ2w7XG4gICAgICAgIHRoaXMuYnVmZmVyID0gZ2wuY3JlYXRlQnVmZmVyKCk7XG4gICAgICAgIHRoaXMuZHluYW1pY0RyYXcgPSBCb29sZWFuKGR5bmFtaWNEcmF3KTtcblxuICAgICAgICAvLyBUaGUgYm91bmQgaW5kZXggYnVmZmVyIGlzIHBhcnQgb2YgdmVydGV4IGFycmF5IG9iamVjdCBzdGF0ZS4gV2UgZG9uJ3Qgd2FudCB0b1xuICAgICAgICAvLyBtb2RpZnkgd2hhdGV2ZXIgVkFPIGhhcHBlbnMgdG8gYmUgY3VycmVudGx5IGJvdW5kLCBzbyBtYWtlIHN1cmUgdGhlIGRlZmF1bHRcbiAgICAgICAgLy8gdmVydGV4IGFycmF5IHByb3ZpZGVkIGJ5IHRoZSBjb250ZXh0IGlzIGJvdW5kIGluc3RlYWQuXG4gICAgICAgIHRoaXMuY29udGV4dC51bmJpbmRWQU8oKTtcblxuICAgICAgICBjb250ZXh0LmJpbmRFbGVtZW50QnVmZmVyLnNldCh0aGlzLmJ1ZmZlcik7XG4gICAgICAgIGdsLmJ1ZmZlckRhdGEoZ2wuRUxFTUVOVF9BUlJBWV9CVUZGRVIsIGFycmF5LmFycmF5QnVmZmVyLCB0aGlzLmR5bmFtaWNEcmF3ID8gZ2wuRFlOQU1JQ19EUkFXIDogZ2wuU1RBVElDX0RSQVcpO1xuXG4gICAgICAgIGlmICghdGhpcy5keW5hbWljRHJhdykge1xuICAgICAgICAgICAgYXJyYXkuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYmluZCgpIHtcbiAgICAgICAgdGhpcy5jb250ZXh0LmJpbmRFbGVtZW50QnVmZmVyLnNldCh0aGlzLmJ1ZmZlcik7XG4gICAgfVxuXG4gICAgdXBkYXRlRGF0YShhcnJheTogU3RydWN0QXJyYXkpIHtcbiAgICAgICAgY29uc3QgZ2wgPSB0aGlzLmNvbnRleHQuZ2w7XG4gICAgICAgIGFzc2VydCh0aGlzLmR5bmFtaWNEcmF3KTtcbiAgICAgICAgLy8gVGhlIHJpZ2h0IFZBTyB3aWxsIGdldCB0aGlzIGJ1ZmZlciByZS1ib3VuZCBsYXRlciBpbiBWZXJ0ZXhBcnJheU9iamVjdCNiaW5kXG4gICAgICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vbWFwYm94L21hcGJveC1nbC1qcy9pc3N1ZXMvNTYyMFxuICAgICAgICB0aGlzLmNvbnRleHQudW5iaW5kVkFPKCk7XG4gICAgICAgIHRoaXMuYmluZCgpO1xuICAgICAgICBnbC5idWZmZXJTdWJEYXRhKGdsLkVMRU1FTlRfQVJSQVlfQlVGRkVSLCAwLCBhcnJheS5hcnJheUJ1ZmZlcik7XG4gICAgfVxuXG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgY29uc3QgZ2wgPSB0aGlzLmNvbnRleHQuZ2w7XG4gICAgICAgIGlmICh0aGlzLmJ1ZmZlcikge1xuICAgICAgICAgICAgZ2wuZGVsZXRlQnVmZmVyKHRoaXMuYnVmZmVyKTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmJ1ZmZlcjtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgSW5kZXhCdWZmZXI7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbmltcG9ydCB0eXBlIHtcbiAgICBTdHJ1Y3RBcnJheSxcbiAgICBTdHJ1Y3RBcnJheU1lbWJlclxufSBmcm9tICcuLi91dGlsL3N0cnVjdF9hcnJheS5qcyc7XG5cbmltcG9ydCB0eXBlIFByb2dyYW0gZnJvbSAnLi4vcmVuZGVyL3Byb2dyYW0uanMnO1xuaW1wb3J0IHR5cGUgQ29udGV4dCBmcm9tICcuLi9nbC9jb250ZXh0LmpzJztcblxuLyoqXG4gKiBAZW51bSB7c3RyaW5nfSBBdHRyaWJ1dGVUeXBlXG4gKiBAcHJpdmF0ZVxuICogQHJlYWRvbmx5XG4gKi9cbmNvbnN0IEF0dHJpYnV0ZVR5cGUgPSB7XG4gICAgSW50ODogICAnQllURScsXG4gICAgVWludDg6ICAnVU5TSUdORURfQllURScsXG4gICAgSW50MTY6ICAnU0hPUlQnLFxuICAgIFVpbnQxNjogJ1VOU0lHTkVEX1NIT1JUJyxcbiAgICBJbnQzMjogICdJTlQnLFxuICAgIFVpbnQzMjogJ1VOU0lHTkVEX0lOVCcsXG4gICAgRmxvYXQzMjogJ0ZMT0FUJ1xufTtcblxuLyoqXG4gKiBUaGUgYFZlcnRleEJ1ZmZlcmAgY2xhc3MgdHVybnMgYSBgU3RydWN0QXJyYXlgIGludG8gYSBXZWJHTCBidWZmZXIuIEVhY2ggbWVtYmVyIG9mIHRoZSBTdHJ1Y3RBcnJheSdzXG4gKiBTdHJ1Y3QgdHlwZSBpcyBjb252ZXJ0ZWQgdG8gYSBXZWJHTCBhdHJpYnV0ZS5cbiAqIEBwcml2YXRlXG4gKi9cbmNsYXNzIFZlcnRleEJ1ZmZlciB7XG4gICAgbGVuZ3RoOiBudW1iZXI7XG4gICAgYXR0cmlidXRlczogJFJlYWRPbmx5QXJyYXk8U3RydWN0QXJyYXlNZW1iZXI+O1xuICAgIGl0ZW1TaXplOiBudW1iZXI7XG4gICAgZHluYW1pY0RyYXc6ID9ib29sZWFuO1xuICAgIGNvbnRleHQ6IENvbnRleHQ7XG4gICAgYnVmZmVyOiA/V2ViR0xCdWZmZXI7XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZHluYW1pY0RyYXcgV2hldGhlciB0aGlzIGJ1ZmZlciB3aWxsIGJlIHJlcGVhdGVkbHkgdXBkYXRlZC5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNvbnRleHQ6IENvbnRleHQsIGFycmF5OiBTdHJ1Y3RBcnJheSwgYXR0cmlidXRlczogJFJlYWRPbmx5QXJyYXk8U3RydWN0QXJyYXlNZW1iZXI+LCBkeW5hbWljRHJhdz86IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5sZW5ndGggPSBhcnJheS5sZW5ndGg7XG4gICAgICAgIHRoaXMuYXR0cmlidXRlcyA9IGF0dHJpYnV0ZXM7XG4gICAgICAgIHRoaXMuaXRlbVNpemUgPSBhcnJheS5ieXRlc1BlckVsZW1lbnQ7XG4gICAgICAgIHRoaXMuZHluYW1pY0RyYXcgPSBkeW5hbWljRHJhdztcblxuICAgICAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICAgICAgICBjb25zdCBnbCA9IGNvbnRleHQuZ2w7XG4gICAgICAgIHRoaXMuYnVmZmVyID0gZ2wuY3JlYXRlQnVmZmVyKCk7XG4gICAgICAgIGNvbnRleHQuYmluZFZlcnRleEJ1ZmZlci5zZXQodGhpcy5idWZmZXIpO1xuICAgICAgICBnbC5idWZmZXJEYXRhKGdsLkFSUkFZX0JVRkZFUiwgYXJyYXkuYXJyYXlCdWZmZXIsIHRoaXMuZHluYW1pY0RyYXcgPyBnbC5EWU5BTUlDX0RSQVcgOiBnbC5TVEFUSUNfRFJBVyk7XG5cbiAgICAgICAgaWYgKCF0aGlzLmR5bmFtaWNEcmF3KSB7XG4gICAgICAgICAgICBhcnJheS5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBiaW5kKCkge1xuICAgICAgICB0aGlzLmNvbnRleHQuYmluZFZlcnRleEJ1ZmZlci5zZXQodGhpcy5idWZmZXIpO1xuICAgIH1cblxuICAgIHVwZGF0ZURhdGEoYXJyYXk6IFN0cnVjdEFycmF5KSB7XG4gICAgICAgIGFzc2VydChhcnJheS5sZW5ndGggPT09IHRoaXMubGVuZ3RoKTtcbiAgICAgICAgY29uc3QgZ2wgPSB0aGlzLmNvbnRleHQuZ2w7XG4gICAgICAgIHRoaXMuYmluZCgpO1xuICAgICAgICBnbC5idWZmZXJTdWJEYXRhKGdsLkFSUkFZX0JVRkZFUiwgMCwgYXJyYXkuYXJyYXlCdWZmZXIpO1xuICAgIH1cblxuICAgIGVuYWJsZUF0dHJpYnV0ZXMoZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgcHJvZ3JhbTogUHJvZ3JhbTwqPikge1xuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMuYXR0cmlidXRlcy5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgY29uc3QgbWVtYmVyID0gdGhpcy5hdHRyaWJ1dGVzW2pdO1xuICAgICAgICAgICAgY29uc3QgYXR0cmliSW5kZXg6IG51bWJlciB8IHZvaWQgPSBwcm9ncmFtLmF0dHJpYnV0ZXNbbWVtYmVyLm5hbWVdO1xuICAgICAgICAgICAgaWYgKGF0dHJpYkluZGV4ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBnbC5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheShhdHRyaWJJbmRleCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGF0dHJpYnV0ZSBwb2ludGVycyBpbiBhIFdlYkdMIGNvbnRleHQuXG4gICAgICogQHBhcmFtIGdsIFRoZSBXZWJHTCBjb250ZXh0LlxuICAgICAqIEBwYXJhbSBwcm9ncmFtIFRoZSBhY3RpdmUgV2ViR0wgcHJvZ3JhbS5cbiAgICAgKiBAcGFyYW0gdmVydGV4T2Zmc2V0IEluZGV4IG9mIHRoZSBzdGFydGluZyB2ZXJ0ZXggb2YgdGhlIHNlZ21lbnQuXG4gICAgICovXG4gICAgc2V0VmVydGV4QXR0cmliUG9pbnRlcnMoZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgcHJvZ3JhbTogUHJvZ3JhbTwqPiwgdmVydGV4T2Zmc2V0OiA/bnVtYmVyKSB7XG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5hdHRyaWJ1dGVzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICBjb25zdCBtZW1iZXIgPSB0aGlzLmF0dHJpYnV0ZXNbal07XG4gICAgICAgICAgICBjb25zdCBhdHRyaWJJbmRleDogbnVtYmVyIHwgdm9pZCA9IHByb2dyYW0uYXR0cmlidXRlc1ttZW1iZXIubmFtZV07XG5cbiAgICAgICAgICAgIGlmIChhdHRyaWJJbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgZ2wudmVydGV4QXR0cmliUG9pbnRlcihcbiAgICAgICAgICAgICAgICAgICAgYXR0cmliSW5kZXgsXG4gICAgICAgICAgICAgICAgICAgIG1lbWJlci5jb21wb25lbnRzLFxuICAgICAgICAgICAgICAgICAgICAoZ2w6IGFueSlbQXR0cmlidXRlVHlwZVttZW1iZXIudHlwZV1dLFxuICAgICAgICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pdGVtU2l6ZSxcbiAgICAgICAgICAgICAgICAgICAgbWVtYmVyLm9mZnNldCArICh0aGlzLml0ZW1TaXplICogKHZlcnRleE9mZnNldCB8fCAwKSlcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGVzdHJveSB0aGUgR0wgYnVmZmVyIGJvdW5kIHRvIHRoZSBnaXZlbiBXZWJHTCBjb250ZXh0LlxuICAgICAqL1xuICAgIGRlc3Ryb3koKSB7XG4gICAgICAgIGNvbnN0IGdsID0gdGhpcy5jb250ZXh0LmdsO1xuICAgICAgICBpZiAodGhpcy5idWZmZXIpIHtcbiAgICAgICAgICAgIGdsLmRlbGV0ZUJ1ZmZlcih0aGlzLmJ1ZmZlcik7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5idWZmZXI7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFZlcnRleEJ1ZmZlcjtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCBDb2xvciBmcm9tICcuLi9zdHlsZS1zcGVjL3V0aWwvY29sb3IuanMnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuXG5pbXBvcnQgdHlwZSBDb250ZXh0IGZyb20gJy4vY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSB7XG4gICAgQmxlbmRGdW5jVHlwZSxcbiAgICBCbGVuZEVxdWF0aW9uVHlwZSxcbiAgICBDb2xvck1hc2tUeXBlLFxuICAgIERlcHRoUmFuZ2VUeXBlLFxuICAgIERlcHRoTWFza1R5cGUsXG4gICAgU3RlbmNpbEZ1bmNUeXBlLFxuICAgIFN0ZW5jaWxPcFR5cGUsXG4gICAgRGVwdGhGdW5jVHlwZSxcbiAgICBUZXh0dXJlVW5pdFR5cGUsXG4gICAgVmlld3BvcnRUeXBlLFxuICAgIEN1bGxGYWNlTW9kZVR5cGUsXG4gICAgRnJvbnRGYWNlVHlwZSxcbn0gZnJvbSAnLi90eXBlcy5qcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVmFsdWU8VD4ge1xuICAgIGN1cnJlbnQ6IFQ7XG4gICAgZGVmYXVsdDogVDtcbiAgICBkaXJ0eTogYm9vbGVhbjtcbiAgICBnZXQoKTogVDtcbiAgICBzZXREZWZhdWx0KCk6IHZvaWQ7XG4gICAgc2V0KHZhbHVlOiBUKTogdm9pZDtcbn1cblxuY2xhc3MgQmFzZVZhbHVlPFQ+IGltcGxlbWVudHMgVmFsdWU8VD4ge1xuICAgIGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQ7XG4gICAgY3VycmVudDogVDtcbiAgICBkZWZhdWx0OiBUO1xuICAgIGRpcnR5OiBib29sZWFuO1xuXG4gICAgY29uc3RydWN0b3IoY29udGV4dDogQ29udGV4dCkge1xuICAgICAgICB0aGlzLmdsID0gY29udGV4dC5nbDtcbiAgICAgICAgdGhpcy5kZWZhdWx0ID0gdGhpcy5nZXREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuY3VycmVudCA9IHRoaXMuZGVmYXVsdDtcbiAgICAgICAgdGhpcy5kaXJ0eSA9IGZhbHNlO1xuICAgIH1cblxuICAgIGdldCgpOiBUIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY3VycmVudDtcbiAgICB9XG4gICAgc2V0KHZhbHVlOiBUKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbiAgICAgICAgLy8gb3ZlcnJpZGRlbiBpbiBjaGlsZCBjbGFzc2VzO1xuICAgIH1cblxuICAgIGdldERlZmF1bHQoKTogVCB7XG4gICAgICAgIHJldHVybiB0aGlzLmRlZmF1bHQ7IC8vIG92ZXJyaWRlbiBpbiBjaGlsZCBjbGFzc2VzXG4gICAgfVxuICAgIHNldERlZmF1bHQoKSB7XG4gICAgICAgIHRoaXMuc2V0KHRoaXMuZGVmYXVsdCk7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgQ2xlYXJDb2xvciBleHRlbmRzIEJhc2VWYWx1ZTxDb2xvcj4ge1xuICAgIGdldERlZmF1bHQoKTogQ29sb3Ige1xuICAgICAgICByZXR1cm4gQ29sb3IudHJhbnNwYXJlbnQ7XG4gICAgfVxuICAgIHNldCh2OiBDb2xvcikge1xuICAgICAgICBjb25zdCBjID0gdGhpcy5jdXJyZW50O1xuICAgICAgICBpZiAodi5yID09PSBjLnIgJiYgdi5nID09PSBjLmcgJiYgdi5iID09PSBjLmIgJiYgdi5hID09PSBjLmEgJiYgIXRoaXMuZGlydHkpIHJldHVybjtcbiAgICAgICAgdGhpcy5nbC5jbGVhckNvbG9yKHYuciwgdi5nLCB2LmIsIHYuYSk7XG4gICAgICAgIHRoaXMuY3VycmVudCA9IHY7XG4gICAgICAgIHRoaXMuZGlydHkgPSBmYWxzZTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBDbGVhckRlcHRoIGV4dGVuZHMgQmFzZVZhbHVlPG51bWJlcj4ge1xuICAgIGdldERlZmF1bHQoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICAgIHNldCh2OiBudW1iZXIpIHtcbiAgICAgICAgaWYgKHYgPT09IHRoaXMuY3VycmVudCAmJiAhdGhpcy5kaXJ0eSkgcmV0dXJuO1xuICAgICAgICB0aGlzLmdsLmNsZWFyRGVwdGgodik7XG4gICAgICAgIHRoaXMuY3VycmVudCA9IHY7XG4gICAgICAgIHRoaXMuZGlydHkgPSBmYWxzZTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBDbGVhclN0ZW5jaWwgZXh0ZW5kcyBCYXNlVmFsdWU8bnVtYmVyPiB7XG4gICAgZ2V0RGVmYXVsdCgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgc2V0KHY6IG51bWJlcikge1xuICAgICAgICBpZiAodiA9PT0gdGhpcy5jdXJyZW50ICYmICF0aGlzLmRpcnR5KSByZXR1cm47XG4gICAgICAgIHRoaXMuZ2wuY2xlYXJTdGVuY2lsKHYpO1xuICAgICAgICB0aGlzLmN1cnJlbnQgPSB2O1xuICAgICAgICB0aGlzLmRpcnR5ID0gZmFsc2U7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgQ29sb3JNYXNrIGV4dGVuZHMgQmFzZVZhbHVlPENvbG9yTWFza1R5cGU+IHtcbiAgICBnZXREZWZhdWx0KCk6IENvbG9yTWFza1R5cGUge1xuICAgICAgICByZXR1cm4gW3RydWUsIHRydWUsIHRydWUsIHRydWVdO1xuICAgIH1cbiAgICBzZXQodjogQ29sb3JNYXNrVHlwZSkge1xuICAgICAgICBjb25zdCBjID0gdGhpcy5jdXJyZW50O1xuICAgICAgICBpZiAodlswXSA9PT0gY1swXSAmJiB2WzFdID09PSBjWzFdICYmIHZbMl0gPT09IGNbMl0gJiYgdlszXSA9PT0gY1szXSAmJiAhdGhpcy5kaXJ0eSkgcmV0dXJuO1xuICAgICAgICB0aGlzLmdsLmNvbG9yTWFzayh2WzBdLCB2WzFdLCB2WzJdLCB2WzNdKTtcbiAgICAgICAgdGhpcy5jdXJyZW50ID0gdjtcbiAgICAgICAgdGhpcy5kaXJ0eSA9IGZhbHNlO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIERlcHRoTWFzayBleHRlbmRzIEJhc2VWYWx1ZTxEZXB0aE1hc2tUeXBlPiB7XG4gICAgZ2V0RGVmYXVsdCgpOiBEZXB0aE1hc2tUeXBlIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHNldCh2OiBEZXB0aE1hc2tUeXBlKTogdm9pZCB7XG4gICAgICAgIGlmICh2ID09PSB0aGlzLmN1cnJlbnQgJiYgIXRoaXMuZGlydHkpIHJldHVybjtcbiAgICAgICAgdGhpcy5nbC5kZXB0aE1hc2sodik7XG4gICAgICAgIHRoaXMuY3VycmVudCA9IHY7XG4gICAgICAgIHRoaXMuZGlydHkgPSBmYWxzZTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBTdGVuY2lsTWFzayBleHRlbmRzIEJhc2VWYWx1ZTxudW1iZXI+IHtcbiAgICBnZXREZWZhdWx0KCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiAweEZGO1xuICAgIH1cbiAgICBzZXQodjogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIGlmICh2ID09PSB0aGlzLmN1cnJlbnQgJiYgIXRoaXMuZGlydHkpIHJldHVybjtcbiAgICAgICAgdGhpcy5nbC5zdGVuY2lsTWFzayh2KTtcbiAgICAgICAgdGhpcy5jdXJyZW50ID0gdjtcbiAgICAgICAgdGhpcy5kaXJ0eSA9IGZhbHNlO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFN0ZW5jaWxGdW5jIGV4dGVuZHMgQmFzZVZhbHVlPFN0ZW5jaWxGdW5jVHlwZT4ge1xuICAgIGdldERlZmF1bHQoKTogU3RlbmNpbEZ1bmNUeXBlIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGZ1bmM6IHRoaXMuZ2wuQUxXQVlTLFxuICAgICAgICAgICAgcmVmOiAwLFxuICAgICAgICAgICAgbWFzazogMHhGRlxuICAgICAgICB9O1xuICAgIH1cbiAgICBzZXQodjogU3RlbmNpbEZ1bmNUeXBlKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGMgPSB0aGlzLmN1cnJlbnQ7XG4gICAgICAgIGlmICh2LmZ1bmMgPT09IGMuZnVuYyAmJiB2LnJlZiA9PT0gYy5yZWYgJiYgdi5tYXNrID09PSBjLm1hc2sgJiYgIXRoaXMuZGlydHkpIHJldHVybjtcbiAgICAgICAgLy8gQXNzdW1lIFVOU0lHTkVEX0lOVF8yNF84IHN0b3JhZ2UsIHdpdGggOCBiaXRzIGRlZGljYXRlZCB0byBzdGVuY2lsLlxuICAgICAgICAvLyBQbGVhc2UgcmV2aXNlIHlvdXIgc3RlbmNpbCB2YWx1ZXMgaWYgdGhpcyB0aHJlc2hvbGQgaXMgdHJpZ2dlcmVkLlxuICAgICAgICBhc3NlcnQodi5yZWYgPj0gMCAmJiB2LnJlZiA8PSAyNTUpO1xuICAgICAgICB0aGlzLmdsLnN0ZW5jaWxGdW5jKHYuZnVuYywgdi5yZWYsIHYubWFzayk7XG4gICAgICAgIHRoaXMuY3VycmVudCA9IHY7XG4gICAgICAgIHRoaXMuZGlydHkgPSBmYWxzZTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBTdGVuY2lsT3AgZXh0ZW5kcyBCYXNlVmFsdWU8U3RlbmNpbE9wVHlwZT4ge1xuICAgIGdldERlZmF1bHQoKTogU3RlbmNpbE9wVHlwZSB7XG4gICAgICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICAgICAgcmV0dXJuIFtnbC5LRUVQLCBnbC5LRUVQLCBnbC5LRUVQXTtcbiAgICB9XG4gICAgc2V0KHY6IFN0ZW5jaWxPcFR5cGUpIHtcbiAgICAgICAgY29uc3QgYyA9IHRoaXMuY3VycmVudDtcbiAgICAgICAgaWYgKHZbMF0gPT09IGNbMF0gJiYgdlsxXSA9PT0gY1sxXSAmJiB2WzJdID09PSBjWzJdICYmICF0aGlzLmRpcnR5KSByZXR1cm47XG4gICAgICAgIHRoaXMuZ2wuc3RlbmNpbE9wKHZbMF0sIHZbMV0sIHZbMl0pO1xuICAgICAgICB0aGlzLmN1cnJlbnQgPSB2O1xuICAgICAgICB0aGlzLmRpcnR5ID0gZmFsc2U7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgU3RlbmNpbFRlc3QgZXh0ZW5kcyBCYXNlVmFsdWU8Ym9vbGVhbj4ge1xuICAgIGdldERlZmF1bHQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgc2V0KHY6IGJvb2xlYW4pIHtcbiAgICAgICAgaWYgKHYgPT09IHRoaXMuY3VycmVudCAmJiAhdGhpcy5kaXJ0eSkgcmV0dXJuO1xuICAgICAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgICAgIGlmICh2KSB7XG4gICAgICAgICAgICBnbC5lbmFibGUoZ2wuU1RFTkNJTF9URVNUKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdsLmRpc2FibGUoZ2wuU1RFTkNJTF9URVNUKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmN1cnJlbnQgPSB2O1xuICAgICAgICB0aGlzLmRpcnR5ID0gZmFsc2U7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgRGVwdGhSYW5nZSBleHRlbmRzIEJhc2VWYWx1ZTxEZXB0aFJhbmdlVHlwZT4ge1xuICAgIGdldERlZmF1bHQoKTogRGVwdGhSYW5nZVR5cGUge1xuICAgICAgICByZXR1cm4gWzAsIDFdO1xuICAgIH1cbiAgICBzZXQodjogRGVwdGhSYW5nZVR5cGUpIHtcbiAgICAgICAgY29uc3QgYyA9IHRoaXMuY3VycmVudDtcbiAgICAgICAgaWYgKHZbMF0gPT09IGNbMF0gJiYgdlsxXSA9PT0gY1sxXSAmJiAhdGhpcy5kaXJ0eSkgcmV0dXJuO1xuICAgICAgICB0aGlzLmdsLmRlcHRoUmFuZ2UodlswXSwgdlsxXSk7XG4gICAgICAgIHRoaXMuY3VycmVudCA9IHY7XG4gICAgICAgIHRoaXMuZGlydHkgPSBmYWxzZTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBEZXB0aFRlc3QgZXh0ZW5kcyBCYXNlVmFsdWU8Ym9vbGVhbj4ge1xuICAgIGdldERlZmF1bHQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgc2V0KHY6IGJvb2xlYW4pIHtcbiAgICAgICAgaWYgKHYgPT09IHRoaXMuY3VycmVudCAmJiAhdGhpcy5kaXJ0eSkgcmV0dXJuO1xuICAgICAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgICAgIGlmICh2KSB7XG4gICAgICAgICAgICBnbC5lbmFibGUoZ2wuREVQVEhfVEVTVCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBnbC5kaXNhYmxlKGdsLkRFUFRIX1RFU1QpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY3VycmVudCA9IHY7XG4gICAgICAgIHRoaXMuZGlydHkgPSBmYWxzZTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBEZXB0aEZ1bmMgZXh0ZW5kcyBCYXNlVmFsdWU8RGVwdGhGdW5jVHlwZT4ge1xuICAgIGdldERlZmF1bHQoKTogRGVwdGhGdW5jVHlwZSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdsLkxFU1M7XG4gICAgfVxuICAgIHNldCh2OiBEZXB0aEZ1bmNUeXBlKSB7XG4gICAgICAgIGlmICh2ID09PSB0aGlzLmN1cnJlbnQgJiYgIXRoaXMuZGlydHkpIHJldHVybjtcbiAgICAgICAgdGhpcy5nbC5kZXB0aEZ1bmModik7XG4gICAgICAgIHRoaXMuY3VycmVudCA9IHY7XG4gICAgICAgIHRoaXMuZGlydHkgPSBmYWxzZTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBCbGVuZCBleHRlbmRzIEJhc2VWYWx1ZTxib29sZWFuPiB7XG4gICAgZ2V0RGVmYXVsdCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBzZXQodjogYm9vbGVhbikge1xuICAgICAgICBpZiAodiA9PT0gdGhpcy5jdXJyZW50ICYmICF0aGlzLmRpcnR5KSByZXR1cm47XG4gICAgICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICAgICAgaWYgKHYpIHtcbiAgICAgICAgICAgIGdsLmVuYWJsZShnbC5CTEVORCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBnbC5kaXNhYmxlKGdsLkJMRU5EKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmN1cnJlbnQgPSB2O1xuICAgICAgICB0aGlzLmRpcnR5ID0gZmFsc2U7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgQmxlbmRGdW5jIGV4dGVuZHMgQmFzZVZhbHVlPEJsZW5kRnVuY1R5cGU+IHtcbiAgICBnZXREZWZhdWx0KCk6IEJsZW5kRnVuY1R5cGUge1xuICAgICAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgICAgIHJldHVybiBbZ2wuT05FLCBnbC5aRVJPXTtcbiAgICB9XG4gICAgc2V0KHY6IEJsZW5kRnVuY1R5cGUpIHtcbiAgICAgICAgY29uc3QgYyA9IHRoaXMuY3VycmVudDtcbiAgICAgICAgaWYgKHZbMF0gPT09IGNbMF0gJiYgdlsxXSA9PT0gY1sxXSAmJiAhdGhpcy5kaXJ0eSkgcmV0dXJuO1xuICAgICAgICB0aGlzLmdsLmJsZW5kRnVuYyh2WzBdLCB2WzFdKTtcbiAgICAgICAgdGhpcy5jdXJyZW50ID0gdjtcbiAgICAgICAgdGhpcy5kaXJ0eSA9IGZhbHNlO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIEJsZW5kQ29sb3IgZXh0ZW5kcyBCYXNlVmFsdWU8Q29sb3I+IHtcbiAgICBnZXREZWZhdWx0KCk6IENvbG9yIHtcbiAgICAgICAgcmV0dXJuIENvbG9yLnRyYW5zcGFyZW50O1xuICAgIH1cbiAgICBzZXQodjogQ29sb3IpIHtcbiAgICAgICAgY29uc3QgYyA9IHRoaXMuY3VycmVudDtcbiAgICAgICAgaWYgKHYuciA9PT0gYy5yICYmIHYuZyA9PT0gYy5nICYmIHYuYiA9PT0gYy5iICYmIHYuYSA9PT0gYy5hICYmICF0aGlzLmRpcnR5KSByZXR1cm47XG4gICAgICAgIHRoaXMuZ2wuYmxlbmRDb2xvcih2LnIsIHYuZywgdi5iLCB2LmEpO1xuICAgICAgICB0aGlzLmN1cnJlbnQgPSB2O1xuICAgICAgICB0aGlzLmRpcnR5ID0gZmFsc2U7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgQmxlbmRFcXVhdGlvbiBleHRlbmRzIEJhc2VWYWx1ZTxCbGVuZEVxdWF0aW9uVHlwZT4ge1xuICAgIGdldERlZmF1bHQoKTogQmxlbmRFcXVhdGlvblR5cGUge1xuICAgICAgICByZXR1cm4gdGhpcy5nbC5GVU5DX0FERDtcbiAgICB9XG4gICAgc2V0KHY6IEJsZW5kRXF1YXRpb25UeXBlKSB7XG4gICAgICAgIGlmICh2ID09PSB0aGlzLmN1cnJlbnQgJiYgIXRoaXMuZGlydHkpIHJldHVybjtcbiAgICAgICAgdGhpcy5nbC5ibGVuZEVxdWF0aW9uKHYpO1xuICAgICAgICB0aGlzLmN1cnJlbnQgPSB2O1xuICAgICAgICB0aGlzLmRpcnR5ID0gZmFsc2U7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgQ3VsbEZhY2UgZXh0ZW5kcyBCYXNlVmFsdWU8Ym9vbGVhbj4ge1xuICAgIGdldERlZmF1bHQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgc2V0KHY6IGJvb2xlYW4pIHtcbiAgICAgICAgaWYgKHYgPT09IHRoaXMuY3VycmVudCAmJiAhdGhpcy5kaXJ0eSkgcmV0dXJuO1xuICAgICAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgICAgIGlmICh2KSB7XG4gICAgICAgICAgICBnbC5lbmFibGUoZ2wuQ1VMTF9GQUNFKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdsLmRpc2FibGUoZ2wuQ1VMTF9GQUNFKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmN1cnJlbnQgPSB2O1xuICAgICAgICB0aGlzLmRpcnR5ID0gZmFsc2U7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgQ3VsbEZhY2VTaWRlIGV4dGVuZHMgQmFzZVZhbHVlPEN1bGxGYWNlTW9kZVR5cGU+IHtcbiAgICBnZXREZWZhdWx0KCk6IEN1bGxGYWNlTW9kZVR5cGUge1xuICAgICAgICByZXR1cm4gdGhpcy5nbC5CQUNLO1xuICAgIH1cbiAgICBzZXQodjogQ3VsbEZhY2VNb2RlVHlwZSkge1xuICAgICAgICBpZiAodiA9PT0gdGhpcy5jdXJyZW50ICYmICF0aGlzLmRpcnR5KSByZXR1cm47XG4gICAgICAgIHRoaXMuZ2wuY3VsbEZhY2Uodik7XG4gICAgICAgIHRoaXMuY3VycmVudCA9IHY7XG4gICAgICAgIHRoaXMuZGlydHkgPSBmYWxzZTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBGcm9udEZhY2UgZXh0ZW5kcyBCYXNlVmFsdWU8RnJvbnRGYWNlVHlwZT4ge1xuICAgIGdldERlZmF1bHQoKTogRnJvbnRGYWNlVHlwZSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdsLkNDVztcbiAgICB9XG4gICAgc2V0KHY6IEZyb250RmFjZVR5cGUpIHtcbiAgICAgICAgaWYgKHYgPT09IHRoaXMuY3VycmVudCAmJiAhdGhpcy5kaXJ0eSkgcmV0dXJuO1xuICAgICAgICB0aGlzLmdsLmZyb250RmFjZSh2KTtcbiAgICAgICAgdGhpcy5jdXJyZW50ID0gdjtcbiAgICAgICAgdGhpcy5kaXJ0eSA9IGZhbHNlO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFByb2dyYW0gZXh0ZW5kcyBCYXNlVmFsdWU8P1dlYkdMUHJvZ3JhbT4ge1xuICAgIGdldERlZmF1bHQoKTogV2ViR0xQcm9ncmFtIHwgbnVsbCB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBzZXQodjogP1dlYkdMUHJvZ3JhbSkge1xuICAgICAgICBpZiAodiA9PT0gdGhpcy5jdXJyZW50ICYmICF0aGlzLmRpcnR5KSByZXR1cm47XG4gICAgICAgIHRoaXMuZ2wudXNlUHJvZ3JhbSh2KTtcbiAgICAgICAgdGhpcy5jdXJyZW50ID0gdjtcbiAgICAgICAgdGhpcy5kaXJ0eSA9IGZhbHNlO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIEFjdGl2ZVRleHR1cmVVbml0IGV4dGVuZHMgQmFzZVZhbHVlPFRleHR1cmVVbml0VHlwZT4ge1xuICAgIGdldERlZmF1bHQoKTogVGV4dHVyZVVuaXRUeXBlIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2wuVEVYVFVSRTA7XG4gICAgfVxuICAgIHNldCh2OiBUZXh0dXJlVW5pdFR5cGUpIHtcbiAgICAgICAgaWYgKHYgPT09IHRoaXMuY3VycmVudCAmJiAhdGhpcy5kaXJ0eSkgcmV0dXJuO1xuICAgICAgICB0aGlzLmdsLmFjdGl2ZVRleHR1cmUodik7XG4gICAgICAgIHRoaXMuY3VycmVudCA9IHY7XG4gICAgICAgIHRoaXMuZGlydHkgPSBmYWxzZTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBWaWV3cG9ydCBleHRlbmRzIEJhc2VWYWx1ZTxWaWV3cG9ydFR5cGU+IHtcbiAgICBnZXREZWZhdWx0KCk6IFZpZXdwb3J0VHlwZSB7XG4gICAgICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICAgICAgcmV0dXJuIFswLCAwLCBnbC5kcmF3aW5nQnVmZmVyV2lkdGgsIGdsLmRyYXdpbmdCdWZmZXJIZWlnaHRdO1xuICAgIH1cbiAgICBzZXQodjogVmlld3BvcnRUeXBlKSB7XG4gICAgICAgIGNvbnN0IGMgPSB0aGlzLmN1cnJlbnQ7XG4gICAgICAgIGlmICh2WzBdID09PSBjWzBdICYmIHZbMV0gPT09IGNbMV0gJiYgdlsyXSA9PT0gY1syXSAmJiB2WzNdID09PSBjWzNdICYmICF0aGlzLmRpcnR5KSByZXR1cm47XG4gICAgICAgIHRoaXMuZ2wudmlld3BvcnQodlswXSwgdlsxXSwgdlsyXSwgdlszXSk7XG4gICAgICAgIHRoaXMuY3VycmVudCA9IHY7XG4gICAgICAgIHRoaXMuZGlydHkgPSBmYWxzZTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBCaW5kRnJhbWVidWZmZXIgZXh0ZW5kcyBCYXNlVmFsdWU8P1dlYkdMRnJhbWVidWZmZXI+IHtcbiAgICBnZXREZWZhdWx0KCk6IFdlYkdMRnJhbWVidWZmZXIgfCBudWxsIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHNldCh2OiA/V2ViR0xGcmFtZWJ1ZmZlcikge1xuICAgICAgICBpZiAodiA9PT0gdGhpcy5jdXJyZW50ICYmICF0aGlzLmRpcnR5KSByZXR1cm47XG4gICAgICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICAgICAgZ2wuYmluZEZyYW1lYnVmZmVyKGdsLkZSQU1FQlVGRkVSLCB2KTtcbiAgICAgICAgdGhpcy5jdXJyZW50ID0gdjtcbiAgICAgICAgdGhpcy5kaXJ0eSA9IGZhbHNlO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIEJpbmRSZW5kZXJidWZmZXIgZXh0ZW5kcyBCYXNlVmFsdWU8P1dlYkdMUmVuZGVyYnVmZmVyPiB7XG4gICAgZ2V0RGVmYXVsdCgpOiBXZWJHTFJlbmRlcmJ1ZmZlciB8IG51bGwge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgc2V0KHY6ID9XZWJHTFJlbmRlcmJ1ZmZlcikge1xuICAgICAgICBpZiAodiA9PT0gdGhpcy5jdXJyZW50ICYmICF0aGlzLmRpcnR5KSByZXR1cm47XG4gICAgICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICAgICAgZ2wuYmluZFJlbmRlcmJ1ZmZlcihnbC5SRU5ERVJCVUZGRVIsIHYpO1xuICAgICAgICB0aGlzLmN1cnJlbnQgPSB2O1xuICAgICAgICB0aGlzLmRpcnR5ID0gZmFsc2U7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgQmluZFRleHR1cmUgZXh0ZW5kcyBCYXNlVmFsdWU8P1dlYkdMVGV4dHVyZT4ge1xuICAgIGdldERlZmF1bHQoKTogV2ViR0xUZXh0dXJlIHwgbnVsbCB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBzZXQodjogP1dlYkdMVGV4dHVyZSkge1xuICAgICAgICBpZiAodiA9PT0gdGhpcy5jdXJyZW50ICYmICF0aGlzLmRpcnR5KSByZXR1cm47XG4gICAgICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICAgICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgdik7XG4gICAgICAgIHRoaXMuY3VycmVudCA9IHY7XG4gICAgICAgIHRoaXMuZGlydHkgPSBmYWxzZTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBCaW5kVmVydGV4QnVmZmVyIGV4dGVuZHMgQmFzZVZhbHVlPD9XZWJHTEJ1ZmZlcj4ge1xuICAgIGdldERlZmF1bHQoKTogV2ViR0xCdWZmZXIgfCBudWxsIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHNldCh2OiA/V2ViR0xCdWZmZXIpIHtcbiAgICAgICAgaWYgKHYgPT09IHRoaXMuY3VycmVudCAmJiAhdGhpcy5kaXJ0eSkgcmV0dXJuO1xuICAgICAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgICAgIGdsLmJpbmRCdWZmZXIoZ2wuQVJSQVlfQlVGRkVSLCB2KTtcbiAgICAgICAgdGhpcy5jdXJyZW50ID0gdjtcbiAgICAgICAgdGhpcy5kaXJ0eSA9IGZhbHNlO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIEJpbmRFbGVtZW50QnVmZmVyIGV4dGVuZHMgQmFzZVZhbHVlPD9XZWJHTEJ1ZmZlcj4ge1xuICAgIGdldERlZmF1bHQoKTogV2ViR0xCdWZmZXIgfCBudWxsIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHNldCh2OiA/V2ViR0xCdWZmZXIpIHtcbiAgICAgICAgLy8gQWx3YXlzIHJlYmluZFxuICAgICAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgICAgIGdsLmJpbmRCdWZmZXIoZ2wuRUxFTUVOVF9BUlJBWV9CVUZGRVIsIHYpO1xuICAgICAgICB0aGlzLmN1cnJlbnQgPSB2O1xuICAgICAgICB0aGlzLmRpcnR5ID0gZmFsc2U7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgQmluZFZlcnRleEFycmF5T0VTIGV4dGVuZHMgQmFzZVZhbHVlPGFueT4ge1xuICAgIHZhbzogYW55O1xuXG4gICAgY29uc3RydWN0b3IoY29udGV4dDogQ29udGV4dCkge1xuICAgICAgICBzdXBlcihjb250ZXh0KTtcbiAgICAgICAgdGhpcy52YW8gPSBjb250ZXh0LmV4dFZlcnRleEFycmF5T2JqZWN0O1xuICAgIH1cbiAgICBnZXREZWZhdWx0KCk6IGFueSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBzZXQodjogYW55KSB7XG4gICAgICAgIGlmICghdGhpcy52YW8gfHwgKHYgPT09IHRoaXMuY3VycmVudCAmJiAhdGhpcy5kaXJ0eSkpIHJldHVybjtcbiAgICAgICAgdGhpcy52YW8uYmluZFZlcnRleEFycmF5T0VTKHYpO1xuICAgICAgICB0aGlzLmN1cnJlbnQgPSB2O1xuICAgICAgICB0aGlzLmRpcnR5ID0gZmFsc2U7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgUGl4ZWxTdG9yZVVucGFjayBleHRlbmRzIEJhc2VWYWx1ZTxudW1iZXI+IHtcbiAgICBnZXREZWZhdWx0KCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiA0O1xuICAgIH1cbiAgICBzZXQodjogbnVtYmVyKSB7XG4gICAgICAgIGlmICh2ID09PSB0aGlzLmN1cnJlbnQgJiYgIXRoaXMuZGlydHkpIHJldHVybjtcbiAgICAgICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgICAgICBnbC5waXhlbFN0b3JlaShnbC5VTlBBQ0tfQUxJR05NRU5ULCB2KTtcbiAgICAgICAgdGhpcy5jdXJyZW50ID0gdjtcbiAgICAgICAgdGhpcy5kaXJ0eSA9IGZhbHNlO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFBpeGVsU3RvcmVVbnBhY2tQcmVtdWx0aXBseUFscGhhIGV4dGVuZHMgQmFzZVZhbHVlPGJvb2xlYW4+IHtcbiAgICBnZXREZWZhdWx0KCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHNldCh2OiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh2ID09PSB0aGlzLmN1cnJlbnQgJiYgIXRoaXMuZGlydHkpIHJldHVybjtcbiAgICAgICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgICAgICBnbC5waXhlbFN0b3JlaShnbC5VTlBBQ0tfUFJFTVVMVElQTFlfQUxQSEFfV0VCR0wsICh2OiBhbnkpKTtcbiAgICAgICAgdGhpcy5jdXJyZW50ID0gdjtcbiAgICAgICAgdGhpcy5kaXJ0eSA9IGZhbHNlO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFBpeGVsU3RvcmVVbnBhY2tGbGlwWSBleHRlbmRzIEJhc2VWYWx1ZTxib29sZWFuPiB7XG4gICAgZ2V0RGVmYXVsdCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBzZXQodjogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICBpZiAodiA9PT0gdGhpcy5jdXJyZW50ICYmICF0aGlzLmRpcnR5KSByZXR1cm47XG4gICAgICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICAgICAgZ2wucGl4ZWxTdG9yZWkoZ2wuVU5QQUNLX0ZMSVBfWV9XRUJHTCwgKHY6IGFueSkpO1xuICAgICAgICB0aGlzLmN1cnJlbnQgPSB2O1xuICAgICAgICB0aGlzLmRpcnR5ID0gZmFsc2U7XG4gICAgfVxufVxuXG5jbGFzcyBGcmFtZWJ1ZmZlckF0dGFjaG1lbnQ8VD4gZXh0ZW5kcyBCYXNlVmFsdWU8P1Q+IHtcbiAgICBwYXJlbnQ6IFdlYkdMRnJhbWVidWZmZXI7XG4gICAgY29udGV4dDogQ29udGV4dDtcblxuICAgIGNvbnN0cnVjdG9yKGNvbnRleHQ6IENvbnRleHQsIHBhcmVudDogV2ViR0xGcmFtZWJ1ZmZlcikge1xuICAgICAgICBzdXBlcihjb250ZXh0KTtcbiAgICAgICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDtcbiAgICAgICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7XG4gICAgfVxuICAgIGdldERlZmF1bHQoKTogbnVsbCB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIENvbG9yQXR0YWNobWVudCBleHRlbmRzIEZyYW1lYnVmZmVyQXR0YWNobWVudDxXZWJHTFRleHR1cmU+IHtcbiAgICBzZXREaXJ0eSgpIHtcbiAgICAgICAgdGhpcy5kaXJ0eSA9IHRydWU7XG4gICAgfVxuICAgIHNldCh2OiA/V2ViR0xUZXh0dXJlKTogdm9pZCB7XG4gICAgICAgIGlmICh2ID09PSB0aGlzLmN1cnJlbnQgJiYgIXRoaXMuZGlydHkpIHJldHVybjtcbiAgICAgICAgdGhpcy5jb250ZXh0LmJpbmRGcmFtZWJ1ZmZlci5zZXQodGhpcy5wYXJlbnQpO1xuICAgICAgICAvLyBub3RlOiBpdCdzIHBvc3NpYmxlIHRvIGF0dGFjaCBhIHJlbmRlcmJ1ZmZlciB0byB0aGUgY29sb3JcbiAgICAgICAgLy8gYXR0YWNobWVudCBwb2ludCwgYnV0IHRodXMgZmFyIE1CR0wgb25seSB1c2VzIHRleHR1cmVzIGZvciBjb2xvclxuICAgICAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgICAgIGdsLmZyYW1lYnVmZmVyVGV4dHVyZTJEKGdsLkZSQU1FQlVGRkVSLCBnbC5DT0xPUl9BVFRBQ0hNRU5UMCwgZ2wuVEVYVFVSRV8yRCwgdiwgMCk7XG4gICAgICAgIHRoaXMuY3VycmVudCA9IHY7XG4gICAgICAgIHRoaXMuZGlydHkgPSBmYWxzZTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBEZXB0aEF0dGFjaG1lbnQgZXh0ZW5kcyBGcmFtZWJ1ZmZlckF0dGFjaG1lbnQ8V2ViR0xSZW5kZXJidWZmZXI+IHtcbiAgICBhdHRhY2htZW50KCk6IG51bWJlciB7IHJldHVybiB0aGlzLmdsLkRFUFRIX0FUVEFDSE1FTlQ7IH1cbiAgICBzZXQodjogP1dlYkdMUmVuZGVyYnVmZmVyKTogdm9pZCB7XG4gICAgICAgIGlmICh2ID09PSB0aGlzLmN1cnJlbnQgJiYgIXRoaXMuZGlydHkpIHJldHVybjtcbiAgICAgICAgdGhpcy5jb250ZXh0LmJpbmRGcmFtZWJ1ZmZlci5zZXQodGhpcy5wYXJlbnQpO1xuICAgICAgICAvLyBub3RlOiBpdCdzIHBvc3NpYmxlIHRvIGF0dGFjaCBhIHRleHR1cmUgdG8gdGhlIGRlcHRoIGF0dGFjaG1lbnRcbiAgICAgICAgLy8gcG9pbnQsIGJ1dCB0aHVzIGZhciBNQkdMIG9ubHkgdXNlcyByZW5kZXJidWZmZXJzIGZvciBkZXB0aFxuICAgICAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgICAgIGdsLmZyYW1lYnVmZmVyUmVuZGVyYnVmZmVyKGdsLkZSQU1FQlVGRkVSLCB0aGlzLmF0dGFjaG1lbnQoKSwgZ2wuUkVOREVSQlVGRkVSLCB2KTtcbiAgICAgICAgdGhpcy5jdXJyZW50ID0gdjtcbiAgICAgICAgdGhpcy5kaXJ0eSA9IGZhbHNlO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIERlcHRoU3RlbmNpbEF0dGFjaG1lbnQgZXh0ZW5kcyBEZXB0aEF0dGFjaG1lbnQge1xuICAgIGF0dGFjaG1lbnQoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuZ2wuREVQVEhfU1RFTkNJTF9BVFRBQ0hNRU5UOyB9XG59XG4iLCIvLyBAZmxvd1xuaW1wb3J0IHtDb2xvckF0dGFjaG1lbnQsIERlcHRoQXR0YWNobWVudH0gZnJvbSAnLi92YWx1ZS5qcyc7XG5cbmltcG9ydCB0eXBlIENvbnRleHQgZnJvbSAnLi9jb250ZXh0LmpzJztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcblxuY2xhc3MgRnJhbWVidWZmZXIge1xuICAgIGNvbnRleHQ6IENvbnRleHQ7XG4gICAgd2lkdGg6IG51bWJlcjtcbiAgICBoZWlnaHQ6IG51bWJlcjtcbiAgICBmcmFtZWJ1ZmZlcjogV2ViR0xGcmFtZWJ1ZmZlcjtcbiAgICBjb2xvckF0dGFjaG1lbnQ6IENvbG9yQXR0YWNobWVudDtcbiAgICBkZXB0aEF0dGFjaG1lbnQ6IERlcHRoQXR0YWNobWVudDtcblxuICAgIGNvbnN0cnVjdG9yKGNvbnRleHQ6IENvbnRleHQsIHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyLCBoYXNEZXB0aDogYm9vbGVhbikge1xuICAgICAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICAgICAgICB0aGlzLndpZHRoID0gd2lkdGg7XG4gICAgICAgIHRoaXMuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgICAgICBjb25zdCBnbCA9IGNvbnRleHQuZ2w7XG4gICAgICAgIGNvbnN0IGZibyA9IHRoaXMuZnJhbWVidWZmZXIgPSAoKGdsLmNyZWF0ZUZyYW1lYnVmZmVyKCk6IGFueSk6IFdlYkdMRnJhbWVidWZmZXIpO1xuXG4gICAgICAgIHRoaXMuY29sb3JBdHRhY2htZW50ID0gbmV3IENvbG9yQXR0YWNobWVudChjb250ZXh0LCBmYm8pO1xuICAgICAgICBpZiAoaGFzRGVwdGgpIHtcbiAgICAgICAgICAgIHRoaXMuZGVwdGhBdHRhY2htZW50ID0gbmV3IERlcHRoQXR0YWNobWVudChjb250ZXh0LCBmYm8pO1xuICAgICAgICB9XG4gICAgICAgIGFzc2VydChnbC5jaGVja0ZyYW1lYnVmZmVyU3RhdHVzKGdsLkZSQU1FQlVGRkVSKSA9PT0gZ2wuRlJBTUVCVUZGRVJfQ09NUExFVEUpO1xuICAgIH1cblxuICAgIGRlc3Ryb3koKSB7XG4gICAgICAgIGNvbnN0IGdsID0gdGhpcy5jb250ZXh0LmdsO1xuXG4gICAgICAgIGNvbnN0IHRleHR1cmUgPSB0aGlzLmNvbG9yQXR0YWNobWVudC5nZXQoKTtcbiAgICAgICAgaWYgKHRleHR1cmUpIGdsLmRlbGV0ZVRleHR1cmUodGV4dHVyZSk7XG5cbiAgICAgICAgaWYgKHRoaXMuZGVwdGhBdHRhY2htZW50KSB7XG4gICAgICAgICAgICBjb25zdCByZW5kZXJidWZmZXIgPSB0aGlzLmRlcHRoQXR0YWNobWVudC5nZXQoKTtcbiAgICAgICAgICAgIGlmIChyZW5kZXJidWZmZXIpIGdsLmRlbGV0ZVJlbmRlcmJ1ZmZlcihyZW5kZXJidWZmZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgZ2wuZGVsZXRlRnJhbWVidWZmZXIodGhpcy5mcmFtZWJ1ZmZlcik7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBGcmFtZWJ1ZmZlcjtcbiIsIi8vIEBmbG93XG5pbXBvcnQgdHlwZSB7RGVwdGhGdW5jVHlwZSwgRGVwdGhNYXNrVHlwZSwgRGVwdGhSYW5nZVR5cGV9IGZyb20gJy4vdHlwZXMuanMnO1xuXG5jb25zdCBBTFdBWVMgPSAweDAyMDc7XG5cbmNsYXNzIERlcHRoTW9kZSB7XG4gICAgZnVuYzogRGVwdGhGdW5jVHlwZTtcbiAgICBtYXNrOiBEZXB0aE1hc2tUeXBlO1xuICAgIHJhbmdlOiBEZXB0aFJhbmdlVHlwZTtcblxuICAgIC8vIERlcHRoTWFzayBlbnVtc1xuICAgIHN0YXRpYyBSZWFkT25seTogYm9vbGVhbjtcbiAgICBzdGF0aWMgUmVhZFdyaXRlOiBib29sZWFuO1xuXG4gICAgY29uc3RydWN0b3IoZGVwdGhGdW5jOiBEZXB0aEZ1bmNUeXBlLCBkZXB0aE1hc2s6IERlcHRoTWFza1R5cGUsIGRlcHRoUmFuZ2U6IERlcHRoUmFuZ2VUeXBlKSB7XG4gICAgICAgIHRoaXMuZnVuYyA9IGRlcHRoRnVuYztcbiAgICAgICAgdGhpcy5tYXNrID0gZGVwdGhNYXNrO1xuICAgICAgICB0aGlzLnJhbmdlID0gZGVwdGhSYW5nZTtcbiAgICB9XG5cbiAgICBzdGF0aWMgZGlzYWJsZWQ6ICRSZWFkT25seTxEZXB0aE1vZGU+O1xufVxuXG5EZXB0aE1vZGUuUmVhZE9ubHkgPSBmYWxzZTtcbkRlcHRoTW9kZS5SZWFkV3JpdGUgPSB0cnVlO1xuXG5EZXB0aE1vZGUuZGlzYWJsZWQgPSBuZXcgRGVwdGhNb2RlKEFMV0FZUywgRGVwdGhNb2RlLlJlYWRPbmx5LCBbMCwgMV0pO1xuXG5leHBvcnQgZGVmYXVsdCBEZXB0aE1vZGU7XG4iLCIvLyBAZmxvd1xuaW1wb3J0IHR5cGUge1N0ZW5jaWxPcENvbnN0YW50LCBTdGVuY2lsVGVzdH0gZnJvbSAnLi90eXBlcy5qcyc7XG5cbmNvbnN0IEFMV0FZUyA9IDB4MDIwNztcbmNvbnN0IEtFRVAgPSAweDFFMDA7XG5cbmNsYXNzIFN0ZW5jaWxNb2RlIHtcbiAgICB0ZXN0OiBTdGVuY2lsVGVzdDtcbiAgICByZWY6IG51bWJlcjtcbiAgICBtYXNrOiBudW1iZXI7XG4gICAgZmFpbDogU3RlbmNpbE9wQ29uc3RhbnQ7XG4gICAgZGVwdGhGYWlsOiBTdGVuY2lsT3BDb25zdGFudDtcbiAgICBwYXNzOiBTdGVuY2lsT3BDb25zdGFudDtcblxuICAgIGNvbnN0cnVjdG9yKHRlc3Q6IFN0ZW5jaWxUZXN0LCByZWY6IG51bWJlciwgbWFzazogbnVtYmVyLCBmYWlsOiBTdGVuY2lsT3BDb25zdGFudCxcbiAgICAgICAgZGVwdGhGYWlsOiBTdGVuY2lsT3BDb25zdGFudCwgcGFzczogU3RlbmNpbE9wQ29uc3RhbnQpIHtcbiAgICAgICAgdGhpcy50ZXN0ID0gdGVzdDtcbiAgICAgICAgdGhpcy5yZWYgPSByZWY7XG4gICAgICAgIHRoaXMubWFzayA9IG1hc2s7XG4gICAgICAgIHRoaXMuZmFpbCA9IGZhaWw7XG4gICAgICAgIHRoaXMuZGVwdGhGYWlsID0gZGVwdGhGYWlsO1xuICAgICAgICB0aGlzLnBhc3MgPSBwYXNzO1xuICAgIH1cblxuICAgIHN0YXRpYyBkaXNhYmxlZDogJFJlYWRPbmx5PFN0ZW5jaWxNb2RlPjtcbn1cblxuU3RlbmNpbE1vZGUuZGlzYWJsZWQgPSBuZXcgU3RlbmNpbE1vZGUoe2Z1bmM6IEFMV0FZUywgbWFzazogMH0sIDAsIDAsIEtFRVAsIEtFRVAsIEtFRVApO1xuXG5leHBvcnQgZGVmYXVsdCBTdGVuY2lsTW9kZTtcbiIsIi8vIEBmbG93XG5pbXBvcnQgQ29sb3IgZnJvbSAnLi4vc3R5bGUtc3BlYy91dGlsL2NvbG9yLmpzJztcblxuaW1wb3J0IHR5cGUge0JsZW5kRnVuY1R5cGUsIENvbG9yTWFza1R5cGV9IGZyb20gJy4vdHlwZXMuanMnO1xuXG5jb25zdCBaRVJPID0gMHgwMDAwO1xuY29uc3QgT05FID0gMHgwMDAxO1xuY29uc3QgT05FX01JTlVTX1NSQ19BTFBIQSA9IDB4MDMwMztcblxuY2xhc3MgQ29sb3JNb2RlIHtcbiAgICBibGVuZEZ1bmN0aW9uOiBCbGVuZEZ1bmNUeXBlO1xuICAgIGJsZW5kQ29sb3I6IENvbG9yO1xuICAgIG1hc2s6IENvbG9yTWFza1R5cGU7XG5cbiAgICBjb25zdHJ1Y3RvcihibGVuZEZ1bmN0aW9uOiBCbGVuZEZ1bmNUeXBlLCBibGVuZENvbG9yOiBDb2xvciwgbWFzazogQ29sb3JNYXNrVHlwZSkge1xuICAgICAgICB0aGlzLmJsZW5kRnVuY3Rpb24gPSBibGVuZEZ1bmN0aW9uO1xuICAgICAgICB0aGlzLmJsZW5kQ29sb3IgPSBibGVuZENvbG9yO1xuICAgICAgICB0aGlzLm1hc2sgPSBtYXNrO1xuICAgIH1cblxuICAgIHN0YXRpYyBSZXBsYWNlOiBCbGVuZEZ1bmNUeXBlO1xuXG4gICAgc3RhdGljIGRpc2FibGVkOiAkUmVhZE9ubHk8Q29sb3JNb2RlPjtcbiAgICBzdGF0aWMgdW5ibGVuZGVkOiAkUmVhZE9ubHk8Q29sb3JNb2RlPjtcbiAgICBzdGF0aWMgYWxwaGFCbGVuZGVkOiAkUmVhZE9ubHk8Q29sb3JNb2RlPjtcbn1cblxuQ29sb3JNb2RlLlJlcGxhY2UgPSBbT05FLCBaRVJPXTtcblxuQ29sb3JNb2RlLmRpc2FibGVkID0gbmV3IENvbG9yTW9kZShDb2xvck1vZGUuUmVwbGFjZSwgQ29sb3IudHJhbnNwYXJlbnQsIFtmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZV0pO1xuQ29sb3JNb2RlLnVuYmxlbmRlZCA9IG5ldyBDb2xvck1vZGUoQ29sb3JNb2RlLlJlcGxhY2UsIENvbG9yLnRyYW5zcGFyZW50LCBbdHJ1ZSwgdHJ1ZSwgdHJ1ZSwgdHJ1ZV0pO1xuQ29sb3JNb2RlLmFscGhhQmxlbmRlZCA9IG5ldyBDb2xvck1vZGUoW09ORSwgT05FX01JTlVTX1NSQ19BTFBIQV0sIENvbG9yLnRyYW5zcGFyZW50LCBbdHJ1ZSwgdHJ1ZSwgdHJ1ZSwgdHJ1ZV0pO1xuXG5leHBvcnQgZGVmYXVsdCBDb2xvck1vZGU7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgdHlwZSB7Q3VsbEZhY2VNb2RlVHlwZSwgRnJvbnRGYWNlVHlwZX0gZnJvbSAnLi90eXBlcy5qcyc7XG5cbmNvbnN0IEJBQ0sgPSAweDA0MDU7XG5jb25zdCBGUk9OVCA9IDB4MDQwNDtcbmNvbnN0IENDVyA9IDB4MDkwMTtcbmNvbnN0IENXID0gMHgwOTAwO1xuXG5jbGFzcyBDdWxsRmFjZU1vZGUge1xuICAgIGVuYWJsZTogYm9vbGVhbjtcbiAgICBtb2RlOiBDdWxsRmFjZU1vZGVUeXBlO1xuICAgIGZyb250RmFjZTogRnJvbnRGYWNlVHlwZTtcblxuICAgIGNvbnN0cnVjdG9yKGVuYWJsZTogYm9vbGVhbiwgbW9kZTogQ3VsbEZhY2VNb2RlVHlwZSwgZnJvbnRGYWNlOiBGcm9udEZhY2VUeXBlKSB7XG4gICAgICAgIHRoaXMuZW5hYmxlID0gZW5hYmxlO1xuICAgICAgICB0aGlzLm1vZGUgPSBtb2RlO1xuICAgICAgICB0aGlzLmZyb250RmFjZSA9IGZyb250RmFjZTtcbiAgICB9XG5cbiAgICBzdGF0aWMgZGlzYWJsZWQ6ICRSZWFkT25seTxDdWxsRmFjZU1vZGU+O1xuICAgIHN0YXRpYyBiYWNrQ0NXOiAkUmVhZE9ubHk8Q3VsbEZhY2VNb2RlPjtcbiAgICBzdGF0aWMgYmFja0NXOiAkUmVhZE9ubHk8Q3VsbEZhY2VNb2RlPjtcbiAgICBzdGF0aWMgZnJvbnRDVzogJFJlYWRPbmx5PEN1bGxGYWNlTW9kZT47XG4gICAgc3RhdGljIGZyb250Q0NXOiAkUmVhZE9ubHk8Q3VsbEZhY2VNb2RlPjtcbn1cblxuQ3VsbEZhY2VNb2RlLmRpc2FibGVkID0gbmV3IEN1bGxGYWNlTW9kZShmYWxzZSwgQkFDSywgQ0NXKTtcbkN1bGxGYWNlTW9kZS5iYWNrQ0NXID0gbmV3IEN1bGxGYWNlTW9kZSh0cnVlLCBCQUNLLCBDQ1cpO1xuQ3VsbEZhY2VNb2RlLmJhY2tDVyA9IG5ldyBDdWxsRmFjZU1vZGUodHJ1ZSwgQkFDSywgQ1cpO1xuQ3VsbEZhY2VNb2RlLmZyb250Q1cgPSBuZXcgQ3VsbEZhY2VNb2RlKHRydWUsIEZST05ULCBDVyk7XG5DdWxsRmFjZU1vZGUuZnJvbnRDQ1cgPSBuZXcgQ3VsbEZhY2VNb2RlKHRydWUsIEZST05ULCBDQ1cpO1xuXG5leHBvcnQgZGVmYXVsdCBDdWxsRmFjZU1vZGU7XG4iLCIvLyBAZmxvd1xuaW1wb3J0IEluZGV4QnVmZmVyIGZyb20gJy4vaW5kZXhfYnVmZmVyLmpzJztcblxuaW1wb3J0IFZlcnRleEJ1ZmZlciBmcm9tICcuL3ZlcnRleF9idWZmZXIuanMnO1xuaW1wb3J0IEZyYW1lYnVmZmVyIGZyb20gJy4vZnJhbWVidWZmZXIuanMnO1xuaW1wb3J0IERlcHRoTW9kZSBmcm9tICcuL2RlcHRoX21vZGUuanMnO1xuaW1wb3J0IFN0ZW5jaWxNb2RlIGZyb20gJy4vc3RlbmNpbF9tb2RlLmpzJztcbmltcG9ydCBDb2xvck1vZGUgZnJvbSAnLi9jb2xvcl9tb2RlLmpzJztcbmltcG9ydCBDdWxsRmFjZU1vZGUgZnJvbSAnLi9jdWxsX2ZhY2VfbW9kZS5qcyc7XG5pbXBvcnQge2RlZXBFcXVhbH0gZnJvbSAnLi4vdXRpbC91dGlsLmpzJztcbmltcG9ydCB7Q2xlYXJDb2xvciwgQ2xlYXJEZXB0aCwgQ2xlYXJTdGVuY2lsLCBDb2xvck1hc2ssIERlcHRoTWFzaywgU3RlbmNpbE1hc2ssIFN0ZW5jaWxGdW5jLCBTdGVuY2lsT3AsIFN0ZW5jaWxUZXN0LCBEZXB0aFJhbmdlLCBEZXB0aFRlc3QsIERlcHRoRnVuYywgQmxlbmQsIEJsZW5kRnVuYywgQmxlbmRDb2xvciwgQmxlbmRFcXVhdGlvbiwgQ3VsbEZhY2UsIEN1bGxGYWNlU2lkZSwgRnJvbnRGYWNlLCBQcm9ncmFtLCBBY3RpdmVUZXh0dXJlVW5pdCwgVmlld3BvcnQsIEJpbmRGcmFtZWJ1ZmZlciwgQmluZFJlbmRlcmJ1ZmZlciwgQmluZFRleHR1cmUsIEJpbmRWZXJ0ZXhCdWZmZXIsIEJpbmRFbGVtZW50QnVmZmVyLCBCaW5kVmVydGV4QXJyYXlPRVMsIFBpeGVsU3RvcmVVbnBhY2ssIFBpeGVsU3RvcmVVbnBhY2tQcmVtdWx0aXBseUFscGhhLCBQaXhlbFN0b3JlVW5wYWNrRmxpcFl9IGZyb20gJy4vdmFsdWUuanMnO1xuXG5pbXBvcnQgdHlwZSB7VHJpYW5nbGVJbmRleEFycmF5LCBMaW5lSW5kZXhBcnJheSwgTGluZVN0cmlwSW5kZXhBcnJheX0gZnJvbSAnLi4vZGF0YS9pbmRleF9hcnJheV90eXBlLmpzJztcbmltcG9ydCB0eXBlIHtcbiAgICBTdHJ1Y3RBcnJheSxcbiAgICBTdHJ1Y3RBcnJheU1lbWJlclxufSBmcm9tICcuLi91dGlsL3N0cnVjdF9hcnJheS5qcyc7XG5pbXBvcnQgdHlwZSBDb2xvciBmcm9tICcuLi9zdHlsZS1zcGVjL3V0aWwvY29sb3IuanMnO1xuXG50eXBlIENsZWFyQXJncyA9IHtcbiAgICBjb2xvcj86IENvbG9yLFxuICAgIGRlcHRoPzogbnVtYmVyLFxuICAgIHN0ZW5jaWw/OiBudW1iZXJcbn07XG5cbmNsYXNzIENvbnRleHQge1xuICAgIGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQ7XG4gICAgaXNXZWJHTDI6IGJvb2xlYW47XG4gICAgZXh0VmVydGV4QXJyYXlPYmplY3Q6IGFueTtcbiAgICBjdXJyZW50TnVtQXR0cmlidXRlczogP251bWJlcjtcbiAgICBtYXhUZXh0dXJlU2l6ZTogbnVtYmVyO1xuXG4gICAgY2xlYXJDb2xvcjogQ2xlYXJDb2xvcjtcbiAgICBjbGVhckRlcHRoOiBDbGVhckRlcHRoO1xuICAgIGNsZWFyU3RlbmNpbDogQ2xlYXJTdGVuY2lsO1xuICAgIGNvbG9yTWFzazogQ29sb3JNYXNrO1xuICAgIGRlcHRoTWFzazogRGVwdGhNYXNrO1xuICAgIHN0ZW5jaWxNYXNrOiBTdGVuY2lsTWFzaztcbiAgICBzdGVuY2lsRnVuYzogU3RlbmNpbEZ1bmM7XG4gICAgc3RlbmNpbE9wOiBTdGVuY2lsT3A7XG4gICAgc3RlbmNpbFRlc3Q6IFN0ZW5jaWxUZXN0O1xuICAgIGRlcHRoUmFuZ2U6IERlcHRoUmFuZ2U7XG4gICAgZGVwdGhUZXN0OiBEZXB0aFRlc3Q7XG4gICAgZGVwdGhGdW5jOiBEZXB0aEZ1bmM7XG4gICAgYmxlbmQ6IEJsZW5kO1xuICAgIGJsZW5kRnVuYzogQmxlbmRGdW5jO1xuICAgIGJsZW5kQ29sb3I6IEJsZW5kQ29sb3I7XG4gICAgYmxlbmRFcXVhdGlvbjogQmxlbmRFcXVhdGlvbjtcbiAgICBjdWxsRmFjZTogQ3VsbEZhY2U7XG4gICAgY3VsbEZhY2VTaWRlOiBDdWxsRmFjZVNpZGU7XG4gICAgZnJvbnRGYWNlOiBGcm9udEZhY2U7XG4gICAgcHJvZ3JhbTogUHJvZ3JhbTtcbiAgICBhY3RpdmVUZXh0dXJlOiBBY3RpdmVUZXh0dXJlVW5pdDtcbiAgICB2aWV3cG9ydDogVmlld3BvcnQ7XG4gICAgYmluZEZyYW1lYnVmZmVyOiBCaW5kRnJhbWVidWZmZXI7XG4gICAgYmluZFJlbmRlcmJ1ZmZlcjogQmluZFJlbmRlcmJ1ZmZlcjtcbiAgICBiaW5kVGV4dHVyZTogQmluZFRleHR1cmU7XG4gICAgYmluZFZlcnRleEJ1ZmZlcjogQmluZFZlcnRleEJ1ZmZlcjtcbiAgICBiaW5kRWxlbWVudEJ1ZmZlcjogQmluZEVsZW1lbnRCdWZmZXI7XG4gICAgYmluZFZlcnRleEFycmF5T0VTOiBCaW5kVmVydGV4QXJyYXlPRVM7XG4gICAgcGl4ZWxTdG9yZVVucGFjazogUGl4ZWxTdG9yZVVucGFjaztcbiAgICBwaXhlbFN0b3JlVW5wYWNrUHJlbXVsdGlwbHlBbHBoYTogUGl4ZWxTdG9yZVVucGFja1ByZW11bHRpcGx5QWxwaGE7XG4gICAgcGl4ZWxTdG9yZVVucGFja0ZsaXBZOiBQaXhlbFN0b3JlVW5wYWNrRmxpcFk7XG4gICAgcmVuZGVyZXI6ID9zdHJpbmc7XG4gICAgdmVuZG9yOiA/c3RyaW5nO1xuXG4gICAgZXh0VGV4dHVyZUZpbHRlckFuaXNvdHJvcGljOiBhbnk7XG4gICAgZXh0VGV4dHVyZUZpbHRlckFuaXNvdHJvcGljTWF4OiBhbnk7XG4gICAgZXh0VGV4dHVyZUhhbGZGbG9hdDogYW55O1xuICAgIGV4dFJlbmRlclRvVGV4dHVyZUhhbGZGbG9hdDogYW55O1xuICAgIGV4dFN0YW5kYXJkRGVyaXZhdGl2ZXM6IGFueTtcbiAgICBleHREZWJ1Z1JlbmRlcmVySW5mbzogYW55O1xuICAgIGV4dFRpbWVyUXVlcnk6IGFueTtcblxuICAgIGV4dFRleHR1cmVGaWx0ZXJBbmlzb3Ryb3BpY0ZvcmNlT2ZmOiBib29sZWFuO1xuICAgIGV4dFN0YW5kYXJkRGVyaXZhdGl2ZXNGb3JjZU9mZjogYm9vbGVhbjtcblxuICAgIGNvbnN0cnVjdG9yKGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQsIGlzV2ViR0wyOiBib29sZWFuID0gZmFsc2UpIHtcbiAgICAgICAgdGhpcy5nbCA9IGdsO1xuICAgICAgICB0aGlzLmlzV2ViR0wyID0gaXNXZWJHTDI7XG4gICAgICAgIHRoaXMuZXh0VmVydGV4QXJyYXlPYmplY3QgPSB0aGlzLmdsLmdldEV4dGVuc2lvbignT0VTX3ZlcnRleF9hcnJheV9vYmplY3QnKTtcblxuICAgICAgICBpZiAoaXNXZWJHTDIpIHtcbiAgICAgICAgICAgIC8qICRGbG93Rml4TWVbY2Fubm90LXJlc29sdmUtbmFtZV0gKi8gLy8gTm90IGFkZGluZyBkZXBlbmRlbmN5IHRvIHdlYmdsMiB5ZXQuXG4gICAgICAgICAgICBjb25zdCBnbDIgPSAoZ2w6IFdlYkdMMlJlbmRlcmluZ0NvbnRleHQpO1xuICAgICAgICAgICAgdGhpcy5leHRWZXJ0ZXhBcnJheU9iamVjdCA9IHtcbiAgICAgICAgICAgICAgICBjcmVhdGVWZXJ0ZXhBcnJheU9FUzogZ2wyLmNyZWF0ZVZlcnRleEFycmF5LmJpbmQoZ2wpLFxuICAgICAgICAgICAgICAgIGRlbGV0ZVZlcnRleEFycmF5T0VTOiBnbDIuZGVsZXRlVmVydGV4QXJyYXkuYmluZChnbCksXG4gICAgICAgICAgICAgICAgYmluZFZlcnRleEFycmF5T0VTOiBnbDIuYmluZFZlcnRleEFycmF5LmJpbmQoZ2wpXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jbGVhckNvbG9yID0gbmV3IENsZWFyQ29sb3IodGhpcyk7XG4gICAgICAgIHRoaXMuY2xlYXJEZXB0aCA9IG5ldyBDbGVhckRlcHRoKHRoaXMpO1xuICAgICAgICB0aGlzLmNsZWFyU3RlbmNpbCA9IG5ldyBDbGVhclN0ZW5jaWwodGhpcyk7XG4gICAgICAgIHRoaXMuY29sb3JNYXNrID0gbmV3IENvbG9yTWFzayh0aGlzKTtcbiAgICAgICAgdGhpcy5kZXB0aE1hc2sgPSBuZXcgRGVwdGhNYXNrKHRoaXMpO1xuICAgICAgICB0aGlzLnN0ZW5jaWxNYXNrID0gbmV3IFN0ZW5jaWxNYXNrKHRoaXMpO1xuICAgICAgICB0aGlzLnN0ZW5jaWxGdW5jID0gbmV3IFN0ZW5jaWxGdW5jKHRoaXMpO1xuICAgICAgICB0aGlzLnN0ZW5jaWxPcCA9IG5ldyBTdGVuY2lsT3AodGhpcyk7XG4gICAgICAgIHRoaXMuc3RlbmNpbFRlc3QgPSBuZXcgU3RlbmNpbFRlc3QodGhpcyk7XG4gICAgICAgIHRoaXMuZGVwdGhSYW5nZSA9IG5ldyBEZXB0aFJhbmdlKHRoaXMpO1xuICAgICAgICB0aGlzLmRlcHRoVGVzdCA9IG5ldyBEZXB0aFRlc3QodGhpcyk7XG4gICAgICAgIHRoaXMuZGVwdGhGdW5jID0gbmV3IERlcHRoRnVuYyh0aGlzKTtcbiAgICAgICAgdGhpcy5ibGVuZCA9IG5ldyBCbGVuZCh0aGlzKTtcbiAgICAgICAgdGhpcy5ibGVuZEZ1bmMgPSBuZXcgQmxlbmRGdW5jKHRoaXMpO1xuICAgICAgICB0aGlzLmJsZW5kQ29sb3IgPSBuZXcgQmxlbmRDb2xvcih0aGlzKTtcbiAgICAgICAgdGhpcy5ibGVuZEVxdWF0aW9uID0gbmV3IEJsZW5kRXF1YXRpb24odGhpcyk7XG4gICAgICAgIHRoaXMuY3VsbEZhY2UgPSBuZXcgQ3VsbEZhY2UodGhpcyk7XG4gICAgICAgIHRoaXMuY3VsbEZhY2VTaWRlID0gbmV3IEN1bGxGYWNlU2lkZSh0aGlzKTtcbiAgICAgICAgdGhpcy5mcm9udEZhY2UgPSBuZXcgRnJvbnRGYWNlKHRoaXMpO1xuICAgICAgICB0aGlzLnByb2dyYW0gPSBuZXcgUHJvZ3JhbSh0aGlzKTtcbiAgICAgICAgdGhpcy5hY3RpdmVUZXh0dXJlID0gbmV3IEFjdGl2ZVRleHR1cmVVbml0KHRoaXMpO1xuICAgICAgICB0aGlzLnZpZXdwb3J0ID0gbmV3IFZpZXdwb3J0KHRoaXMpO1xuICAgICAgICB0aGlzLmJpbmRGcmFtZWJ1ZmZlciA9IG5ldyBCaW5kRnJhbWVidWZmZXIodGhpcyk7XG4gICAgICAgIHRoaXMuYmluZFJlbmRlcmJ1ZmZlciA9IG5ldyBCaW5kUmVuZGVyYnVmZmVyKHRoaXMpO1xuICAgICAgICB0aGlzLmJpbmRUZXh0dXJlID0gbmV3IEJpbmRUZXh0dXJlKHRoaXMpO1xuICAgICAgICB0aGlzLmJpbmRWZXJ0ZXhCdWZmZXIgPSBuZXcgQmluZFZlcnRleEJ1ZmZlcih0aGlzKTtcbiAgICAgICAgdGhpcy5iaW5kRWxlbWVudEJ1ZmZlciA9IG5ldyBCaW5kRWxlbWVudEJ1ZmZlcih0aGlzKTtcbiAgICAgICAgdGhpcy5iaW5kVmVydGV4QXJyYXlPRVMgPSB0aGlzLmV4dFZlcnRleEFycmF5T2JqZWN0ICYmIG5ldyBCaW5kVmVydGV4QXJyYXlPRVModGhpcyk7XG4gICAgICAgIHRoaXMucGl4ZWxTdG9yZVVucGFjayA9IG5ldyBQaXhlbFN0b3JlVW5wYWNrKHRoaXMpO1xuICAgICAgICB0aGlzLnBpeGVsU3RvcmVVbnBhY2tQcmVtdWx0aXBseUFscGhhID0gbmV3IFBpeGVsU3RvcmVVbnBhY2tQcmVtdWx0aXBseUFscGhhKHRoaXMpO1xuICAgICAgICB0aGlzLnBpeGVsU3RvcmVVbnBhY2tGbGlwWSA9IG5ldyBQaXhlbFN0b3JlVW5wYWNrRmxpcFkodGhpcyk7XG5cbiAgICAgICAgdGhpcy5leHRUZXh0dXJlRmlsdGVyQW5pc290cm9waWMgPSAoXG4gICAgICAgICAgICBnbC5nZXRFeHRlbnNpb24oJ0VYVF90ZXh0dXJlX2ZpbHRlcl9hbmlzb3Ryb3BpYycpIHx8XG4gICAgICAgICAgICBnbC5nZXRFeHRlbnNpb24oJ01PWl9FWFRfdGV4dHVyZV9maWx0ZXJfYW5pc290cm9waWMnKSB8fFxuICAgICAgICAgICAgZ2wuZ2V0RXh0ZW5zaW9uKCdXRUJLSVRfRVhUX3RleHR1cmVfZmlsdGVyX2FuaXNvdHJvcGljJylcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKHRoaXMuZXh0VGV4dHVyZUZpbHRlckFuaXNvdHJvcGljKSB7XG4gICAgICAgICAgICB0aGlzLmV4dFRleHR1cmVGaWx0ZXJBbmlzb3Ryb3BpY01heCA9IGdsLmdldFBhcmFtZXRlcih0aGlzLmV4dFRleHR1cmVGaWx0ZXJBbmlzb3Ryb3BpYy5NQVhfVEVYVFVSRV9NQVhfQU5JU09UUk9QWV9FWFQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZXh0VGV4dHVyZUZpbHRlckFuaXNvdHJvcGljRm9yY2VPZmYgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5leHRTdGFuZGFyZERlcml2YXRpdmVzRm9yY2VPZmYgPSBmYWxzZTtcblxuICAgICAgICB0aGlzLmV4dERlYnVnUmVuZGVyZXJJbmZvID0gZ2wuZ2V0RXh0ZW5zaW9uKCdXRUJHTF9kZWJ1Z19yZW5kZXJlcl9pbmZvJyk7XG4gICAgICAgIGlmICh0aGlzLmV4dERlYnVnUmVuZGVyZXJJbmZvKSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyID0gZ2wuZ2V0UGFyYW1ldGVyKHRoaXMuZXh0RGVidWdSZW5kZXJlckluZm8uVU5NQVNLRURfUkVOREVSRVJfV0VCR0wpO1xuICAgICAgICAgICAgdGhpcy52ZW5kb3IgPSBnbC5nZXRQYXJhbWV0ZXIodGhpcy5leHREZWJ1Z1JlbmRlcmVySW5mby5VTk1BU0tFRF9WRU5ET1JfV0VCR0wpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFpc1dlYkdMMikgdGhpcy5leHRUZXh0dXJlSGFsZkZsb2F0ID0gZ2wuZ2V0RXh0ZW5zaW9uKCdPRVNfdGV4dHVyZV9oYWxmX2Zsb2F0Jyk7XG4gICAgICAgIGlmIChpc1dlYkdMMiB8fCAodGhpcy5leHRUZXh0dXJlSGFsZkZsb2F0ICYmIGdsLmdldEV4dGVuc2lvbignT0VTX3RleHR1cmVfaGFsZl9mbG9hdF9saW5lYXInKSkpIHtcbiAgICAgICAgICAgIHRoaXMuZXh0UmVuZGVyVG9UZXh0dXJlSGFsZkZsb2F0ID0gZ2wuZ2V0RXh0ZW5zaW9uKCdFWFRfY29sb3JfYnVmZmVyX2hhbGZfZmxvYXQnKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmV4dFN0YW5kYXJkRGVyaXZhdGl2ZXMgPSBpc1dlYkdMMiB8fCBnbC5nZXRFeHRlbnNpb24oJ09FU19zdGFuZGFyZF9kZXJpdmF0aXZlcycpO1xuXG4gICAgICAgIHRoaXMuZXh0VGltZXJRdWVyeSA9IGdsLmdldEV4dGVuc2lvbignRVhUX2Rpc2pvaW50X3RpbWVyX3F1ZXJ5Jyk7XG4gICAgICAgIHRoaXMubWF4VGV4dHVyZVNpemUgPSBnbC5nZXRQYXJhbWV0ZXIoZ2wuTUFYX1RFWFRVUkVfU0laRSk7XG4gICAgfVxuXG4gICAgc2V0RGVmYXVsdCgpIHtcbiAgICAgICAgdGhpcy51bmJpbmRWQU8oKTtcblxuICAgICAgICB0aGlzLmNsZWFyQ29sb3Iuc2V0RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLmNsZWFyRGVwdGguc2V0RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLmNsZWFyU3RlbmNpbC5zZXREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuY29sb3JNYXNrLnNldERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy5kZXB0aE1hc2suc2V0RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLnN0ZW5jaWxNYXNrLnNldERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy5zdGVuY2lsRnVuYy5zZXREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuc3RlbmNpbE9wLnNldERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy5zdGVuY2lsVGVzdC5zZXREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuZGVwdGhSYW5nZS5zZXREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuZGVwdGhUZXN0LnNldERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy5kZXB0aEZ1bmMuc2V0RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLmJsZW5kLnNldERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy5ibGVuZEZ1bmMuc2V0RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLmJsZW5kQ29sb3Iuc2V0RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLmJsZW5kRXF1YXRpb24uc2V0RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLmN1bGxGYWNlLnNldERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy5jdWxsRmFjZVNpZGUuc2V0RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLmZyb250RmFjZS5zZXREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMucHJvZ3JhbS5zZXREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuYWN0aXZlVGV4dHVyZS5zZXREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuYmluZEZyYW1lYnVmZmVyLnNldERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy5waXhlbFN0b3JlVW5wYWNrLnNldERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy5waXhlbFN0b3JlVW5wYWNrUHJlbXVsdGlwbHlBbHBoYS5zZXREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMucGl4ZWxTdG9yZVVucGFja0ZsaXBZLnNldERlZmF1bHQoKTtcbiAgICB9XG5cbiAgICBzZXREaXJ0eSgpIHtcbiAgICAgICAgdGhpcy5jbGVhckNvbG9yLmRpcnR5ID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5jbGVhckRlcHRoLmRpcnR5ID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5jbGVhclN0ZW5jaWwuZGlydHkgPSB0cnVlO1xuICAgICAgICB0aGlzLmNvbG9yTWFzay5kaXJ0eSA9IHRydWU7XG4gICAgICAgIHRoaXMuZGVwdGhNYXNrLmRpcnR5ID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5zdGVuY2lsTWFzay5kaXJ0eSA9IHRydWU7XG4gICAgICAgIHRoaXMuc3RlbmNpbEZ1bmMuZGlydHkgPSB0cnVlO1xuICAgICAgICB0aGlzLnN0ZW5jaWxPcC5kaXJ0eSA9IHRydWU7XG4gICAgICAgIHRoaXMuc3RlbmNpbFRlc3QuZGlydHkgPSB0cnVlO1xuICAgICAgICB0aGlzLmRlcHRoUmFuZ2UuZGlydHkgPSB0cnVlO1xuICAgICAgICB0aGlzLmRlcHRoVGVzdC5kaXJ0eSA9IHRydWU7XG4gICAgICAgIHRoaXMuZGVwdGhGdW5jLmRpcnR5ID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5ibGVuZC5kaXJ0eSA9IHRydWU7XG4gICAgICAgIHRoaXMuYmxlbmRGdW5jLmRpcnR5ID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5ibGVuZENvbG9yLmRpcnR5ID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5ibGVuZEVxdWF0aW9uLmRpcnR5ID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5jdWxsRmFjZS5kaXJ0eSA9IHRydWU7XG4gICAgICAgIHRoaXMuY3VsbEZhY2VTaWRlLmRpcnR5ID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5mcm9udEZhY2UuZGlydHkgPSB0cnVlO1xuICAgICAgICB0aGlzLnByb2dyYW0uZGlydHkgPSB0cnVlO1xuICAgICAgICB0aGlzLmFjdGl2ZVRleHR1cmUuZGlydHkgPSB0cnVlO1xuICAgICAgICB0aGlzLnZpZXdwb3J0LmRpcnR5ID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5iaW5kRnJhbWVidWZmZXIuZGlydHkgPSB0cnVlO1xuICAgICAgICB0aGlzLmJpbmRSZW5kZXJidWZmZXIuZGlydHkgPSB0cnVlO1xuICAgICAgICB0aGlzLmJpbmRUZXh0dXJlLmRpcnR5ID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5iaW5kVmVydGV4QnVmZmVyLmRpcnR5ID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5iaW5kRWxlbWVudEJ1ZmZlci5kaXJ0eSA9IHRydWU7XG4gICAgICAgIGlmICh0aGlzLmV4dFZlcnRleEFycmF5T2JqZWN0KSB7XG4gICAgICAgICAgICB0aGlzLmJpbmRWZXJ0ZXhBcnJheU9FUy5kaXJ0eSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5waXhlbFN0b3JlVW5wYWNrLmRpcnR5ID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5waXhlbFN0b3JlVW5wYWNrUHJlbXVsdGlwbHlBbHBoYS5kaXJ0eSA9IHRydWU7XG4gICAgICAgIHRoaXMucGl4ZWxTdG9yZVVucGFja0ZsaXBZLmRpcnR5ID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBjcmVhdGVJbmRleEJ1ZmZlcihhcnJheTogVHJpYW5nbGVJbmRleEFycmF5IHwgTGluZUluZGV4QXJyYXkgfCBMaW5lU3RyaXBJbmRleEFycmF5LCBkeW5hbWljRHJhdz86IGJvb2xlYW4pOiBJbmRleEJ1ZmZlciB7XG4gICAgICAgIHJldHVybiBuZXcgSW5kZXhCdWZmZXIodGhpcywgYXJyYXksIGR5bmFtaWNEcmF3KTtcbiAgICB9XG5cbiAgICBjcmVhdGVWZXJ0ZXhCdWZmZXIoYXJyYXk6IFN0cnVjdEFycmF5LCBhdHRyaWJ1dGVzOiAkUmVhZE9ubHlBcnJheTxTdHJ1Y3RBcnJheU1lbWJlcj4sIGR5bmFtaWNEcmF3PzogYm9vbGVhbik6IFZlcnRleEJ1ZmZlciB7XG4gICAgICAgIHJldHVybiBuZXcgVmVydGV4QnVmZmVyKHRoaXMsIGFycmF5LCBhdHRyaWJ1dGVzLCBkeW5hbWljRHJhdyk7XG4gICAgfVxuXG4gICAgY3JlYXRlUmVuZGVyYnVmZmVyKHN0b3JhZ2VGb3JtYXQ6IG51bWJlciwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpOiA/V2ViR0xSZW5kZXJidWZmZXIge1xuICAgICAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG5cbiAgICAgICAgY29uc3QgcmJvID0gZ2wuY3JlYXRlUmVuZGVyYnVmZmVyKCk7XG4gICAgICAgIHRoaXMuYmluZFJlbmRlcmJ1ZmZlci5zZXQocmJvKTtcbiAgICAgICAgZ2wucmVuZGVyYnVmZmVyU3RvcmFnZShnbC5SRU5ERVJCVUZGRVIsIHN0b3JhZ2VGb3JtYXQsIHdpZHRoLCBoZWlnaHQpO1xuICAgICAgICB0aGlzLmJpbmRSZW5kZXJidWZmZXIuc2V0KG51bGwpO1xuXG4gICAgICAgIHJldHVybiByYm87XG4gICAgfVxuXG4gICAgY3JlYXRlRnJhbWVidWZmZXIod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIsIGhhc0RlcHRoOiBib29sZWFuKTogRnJhbWVidWZmZXIge1xuICAgICAgICByZXR1cm4gbmV3IEZyYW1lYnVmZmVyKHRoaXMsIHdpZHRoLCBoZWlnaHQsIGhhc0RlcHRoKTtcbiAgICB9XG5cbiAgICBjbGVhcih7Y29sb3IsIGRlcHRoLCBzdGVuY2lsfTogQ2xlYXJBcmdzKSB7XG4gICAgICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICAgICAgbGV0IG1hc2sgPSAwO1xuXG4gICAgICAgIGlmIChjb2xvcikge1xuICAgICAgICAgICAgbWFzayB8PSBnbC5DT0xPUl9CVUZGRVJfQklUO1xuICAgICAgICAgICAgdGhpcy5jbGVhckNvbG9yLnNldChjb2xvcik7XG4gICAgICAgICAgICB0aGlzLmNvbG9yTWFzay5zZXQoW3RydWUsIHRydWUsIHRydWUsIHRydWVdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgZGVwdGggIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBtYXNrIHw9IGdsLkRFUFRIX0JVRkZFUl9CSVQ7XG5cbiAgICAgICAgICAgIC8vIFdvcmthcm91bmQgZm9yIHBsYXRmb3JtcyB3aGVyZSBjbGVhckRlcHRoIGRvZXNuJ3Qgc2VlbSB0byB3b3JrXG4gICAgICAgICAgICAvLyB3aXRob3V0IHJlc2V0aW5nIHRoZSBkZXB0aFJhbmdlLiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL21hcGJveC9tYXBib3gtZ2wtanMvaXNzdWVzLzM0MzdcbiAgICAgICAgICAgIHRoaXMuZGVwdGhSYW5nZS5zZXQoWzAsIDFdKTtcblxuICAgICAgICAgICAgdGhpcy5jbGVhckRlcHRoLnNldChkZXB0aCk7XG4gICAgICAgICAgICB0aGlzLmRlcHRoTWFzay5zZXQodHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHN0ZW5jaWwgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBtYXNrIHw9IGdsLlNURU5DSUxfQlVGRkVSX0JJVDtcbiAgICAgICAgICAgIHRoaXMuY2xlYXJTdGVuY2lsLnNldChzdGVuY2lsKTtcbiAgICAgICAgICAgIHRoaXMuc3RlbmNpbE1hc2suc2V0KDB4RkYpO1xuICAgICAgICB9XG5cbiAgICAgICAgZ2wuY2xlYXIobWFzayk7XG4gICAgfVxuXG4gICAgc2V0Q3VsbEZhY2UoY3VsbEZhY2VNb2RlOiAkUmVhZE9ubHk8Q3VsbEZhY2VNb2RlPikge1xuICAgICAgICBpZiAoY3VsbEZhY2VNb2RlLmVuYWJsZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHRoaXMuY3VsbEZhY2Uuc2V0KGZhbHNlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY3VsbEZhY2Uuc2V0KHRydWUpO1xuICAgICAgICAgICAgdGhpcy5jdWxsRmFjZVNpZGUuc2V0KGN1bGxGYWNlTW9kZS5tb2RlKTtcbiAgICAgICAgICAgIHRoaXMuZnJvbnRGYWNlLnNldChjdWxsRmFjZU1vZGUuZnJvbnRGYWNlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldERlcHRoTW9kZShkZXB0aE1vZGU6ICRSZWFkT25seTxEZXB0aE1vZGU+KSB7XG4gICAgICAgIGlmIChkZXB0aE1vZGUuZnVuYyA9PT0gdGhpcy5nbC5BTFdBWVMgJiYgIWRlcHRoTW9kZS5tYXNrKSB7XG4gICAgICAgICAgICB0aGlzLmRlcHRoVGVzdC5zZXQoZmFsc2UpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5kZXB0aFRlc3Quc2V0KHRydWUpO1xuICAgICAgICAgICAgdGhpcy5kZXB0aEZ1bmMuc2V0KGRlcHRoTW9kZS5mdW5jKTtcbiAgICAgICAgICAgIHRoaXMuZGVwdGhNYXNrLnNldChkZXB0aE1vZGUubWFzayk7XG4gICAgICAgICAgICB0aGlzLmRlcHRoUmFuZ2Uuc2V0KGRlcHRoTW9kZS5yYW5nZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRTdGVuY2lsTW9kZShzdGVuY2lsTW9kZTogJFJlYWRPbmx5PFN0ZW5jaWxNb2RlPikge1xuICAgICAgICBpZiAoc3RlbmNpbE1vZGUudGVzdC5mdW5jID09PSB0aGlzLmdsLkFMV0FZUyAmJiAhc3RlbmNpbE1vZGUubWFzaykge1xuICAgICAgICAgICAgdGhpcy5zdGVuY2lsVGVzdC5zZXQoZmFsc2UpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zdGVuY2lsVGVzdC5zZXQodHJ1ZSk7XG4gICAgICAgICAgICB0aGlzLnN0ZW5jaWxNYXNrLnNldChzdGVuY2lsTW9kZS5tYXNrKTtcbiAgICAgICAgICAgIHRoaXMuc3RlbmNpbE9wLnNldChbc3RlbmNpbE1vZGUuZmFpbCwgc3RlbmNpbE1vZGUuZGVwdGhGYWlsLCBzdGVuY2lsTW9kZS5wYXNzXSk7XG4gICAgICAgICAgICB0aGlzLnN0ZW5jaWxGdW5jLnNldCh7XG4gICAgICAgICAgICAgICAgZnVuYzogc3RlbmNpbE1vZGUudGVzdC5mdW5jLFxuICAgICAgICAgICAgICAgIHJlZjogc3RlbmNpbE1vZGUucmVmLFxuICAgICAgICAgICAgICAgIG1hc2s6IHN0ZW5jaWxNb2RlLnRlc3QubWFza1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRDb2xvck1vZGUoY29sb3JNb2RlOiAkUmVhZE9ubHk8Q29sb3JNb2RlPikge1xuICAgICAgICBpZiAoZGVlcEVxdWFsKGNvbG9yTW9kZS5ibGVuZEZ1bmN0aW9uLCBDb2xvck1vZGUuUmVwbGFjZSkpIHtcbiAgICAgICAgICAgIHRoaXMuYmxlbmQuc2V0KGZhbHNlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuYmxlbmQuc2V0KHRydWUpO1xuICAgICAgICAgICAgdGhpcy5ibGVuZEZ1bmMuc2V0KGNvbG9yTW9kZS5ibGVuZEZ1bmN0aW9uKTtcbiAgICAgICAgICAgIHRoaXMuYmxlbmRDb2xvci5zZXQoY29sb3JNb2RlLmJsZW5kQ29sb3IpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb2xvck1hc2suc2V0KGNvbG9yTW9kZS5tYXNrKTtcbiAgICB9XG5cbiAgICB1bmJpbmRWQU8oKSB7XG4gICAgICAgIC8vIFVuYmluZGluZyB0aGUgVkFPIHByZXZlbnRzIG90aGVyIHRoaW5ncyAoY3VzdG9tIGxheWVycywgbmV3IGJ1ZmZlciBjcmVhdGlvbikgZnJvbVxuICAgICAgICAvLyB1bmludGVudGlvbmFsbHkgY2hhbmdpbmcgdGhlIHN0YXRlIG9mIHRoZSBsYXN0IFZBTyB1c2VkLlxuICAgICAgICBpZiAodGhpcy5leHRWZXJ0ZXhBcnJheU9iamVjdCkge1xuICAgICAgICAgICAgdGhpcy5iaW5kVmVydGV4QXJyYXlPRVMuc2V0KG51bGwpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDb250ZXh0O1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IFRpbGUgZnJvbSAnLi90aWxlLmpzJztcbmltcG9ydCB7RXZlbnQsIEVycm9yRXZlbnQsIEV2ZW50ZWR9IGZyb20gJy4uL3V0aWwvZXZlbnRlZC5qcyc7XG5pbXBvcnQgVGlsZUNhY2hlIGZyb20gJy4vdGlsZV9jYWNoZS5qcyc7XG5pbXBvcnQge2FzeW5jQWxsLCBrZXlzRGlmZmVyZW5jZSwgdmFsdWVzLCBjbGFtcH0gZnJvbSAnLi4vdXRpbC91dGlsLmpzJztcbmltcG9ydCBDb250ZXh0IGZyb20gJy4uL2dsL2NvbnRleHQuanMnO1xuaW1wb3J0IFBvaW50IGZyb20gJ0BtYXBib3gvcG9pbnQtZ2VvbWV0cnknO1xuaW1wb3J0IGJyb3dzZXIgZnJvbSAnLi4vdXRpbC9icm93c2VyLmpzJztcbmltcG9ydCB7T3ZlcnNjYWxlZFRpbGVJRCwgQ2Fub25pY2FsVGlsZUlEfSBmcm9tICcuL3RpbGVfaWQuanMnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IFNvdXJjZUZlYXR1cmVTdGF0ZSBmcm9tICcuL3NvdXJjZV9zdGF0ZS5qcyc7XG5pbXBvcnQge21lcmNhdG9yWGZyb21Mbmd9IGZyb20gJy4uL2dlby9tZXJjYXRvcl9jb29yZGluYXRlLmpzJztcblxuaW1wb3J0IHR5cGUge1NvdXJjZX0gZnJvbSAnLi9zb3VyY2UuanMnO1xuaW1wb3J0IHR5cGUge1NvdXJjZVNwZWNpZmljYXRpb259IGZyb20gJy4uL3N0eWxlLXNwZWMvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge2RlZmF1bHQgYXMgTWFwYm94TWFwfSBmcm9tICcuLi91aS9tYXAuanMnO1xuaW1wb3J0IHR5cGUgU3R5bGUgZnJvbSAnLi4vc3R5bGUvc3R5bGUuanMnO1xuaW1wb3J0IHR5cGUgVHJhbnNmb3JtIGZyb20gJy4uL2dlby90cmFuc2Zvcm0uanMnO1xuaW1wb3J0IHR5cGUge1RpbGVTdGF0ZX0gZnJvbSAnLi90aWxlLmpzJztcbmltcG9ydCB0eXBlIHtDYWxsYmFja30gZnJvbSAnLi4vdHlwZXMvY2FsbGJhY2suanMnO1xuaW1wb3J0IHR5cGUge0ZlYXR1cmVTdGF0ZXN9IGZyb20gJy4vc291cmNlX3N0YXRlLmpzJztcbmltcG9ydCB0eXBlIHtRdWVyeUdlb21ldHJ5LCBUaWxlc3BhY2VRdWVyeUdlb21ldHJ5fSBmcm9tICcuLi9zdHlsZS9xdWVyeV9nZW9tZXRyeS5qcyc7XG5cbi8qKlxuICogYFNvdXJjZUNhY2hlYCBpcyByZXNwb25zaWJsZSBmb3JcbiAqXG4gKiAgLSBjcmVhdGluZyBhbiBpbnN0YW5jZSBvZiBgU291cmNlYFxuICogIC0gZm9yd2FyZGluZyBldmVudHMgZnJvbSBgU291cmNlYFxuICogIC0gY2FjaGluZyB0aWxlcyBsb2FkZWQgZnJvbSBhbiBpbnN0YW5jZSBvZiBgU291cmNlYFxuICogIC0gbG9hZGluZyB0aGUgdGlsZXMgbmVlZGVkIHRvIHJlbmRlciBhIGdpdmVuIHZpZXdwb3J0XG4gKiAgLSB1bmxvYWRpbmcgdGhlIGNhY2hlZCB0aWxlcyBub3QgbmVlZGVkIHRvIHJlbmRlciBhIGdpdmVuIHZpZXdwb3J0XG4gKlxuICogQHByaXZhdGVcbiAqL1xuY2xhc3MgU291cmNlQ2FjaGUgZXh0ZW5kcyBFdmVudGVkIHtcbiAgICBpZDogc3RyaW5nO1xuICAgIG1hcDogTWFwYm94TWFwO1xuICAgIHN0eWxlOiBTdHlsZTtcblxuICAgIF9zb3VyY2U6IFNvdXJjZTtcbiAgICBfc291cmNlTG9hZGVkOiBib29sZWFuO1xuICAgIF9zb3VyY2VFcnJvcmVkOiBib29sZWFuO1xuICAgIF90aWxlczoge1tfOiBzdHJpbmcgfCBudW1iZXJdOiBUaWxlfTtcbiAgICBfcHJldkxuZzogbnVtYmVyIHwgdm9pZDtcbiAgICBfY2FjaGU6IFRpbGVDYWNoZTtcbiAgICBfdGltZXJzOiB7W186IGFueV06IFRpbWVvdXRJRH07XG4gICAgX2NhY2hlVGltZXJzOiB7W186IGFueV06IFRpbWVvdXRJRH07XG4gICAgX21pblRpbGVDYWNoZVNpemU6ID9udW1iZXI7XG4gICAgX21heFRpbGVDYWNoZVNpemU6ID9udW1iZXI7XG4gICAgX3BhdXNlZDogYm9vbGVhbjtcbiAgICBfaXNSYXN0ZXI6IGJvb2xlYW47XG4gICAgX3Nob3VsZFJlbG9hZE9uUmVzdW1lOiBib29sZWFuO1xuICAgIF9jb3ZlcmVkVGlsZXM6IHtbXzogbnVtYmVyIHwgc3RyaW5nXTogYm9vbGVhbn07XG4gICAgdHJhbnNmb3JtOiBUcmFuc2Zvcm07XG4gICAgdXNlZDogYm9vbGVhbjtcbiAgICB1c2VkRm9yVGVycmFpbjogYm9vbGVhbjtcbiAgICBfc3RhdGU6IFNvdXJjZUZlYXR1cmVTdGF0ZTtcbiAgICBfbG9hZGVkUGFyZW50VGlsZXM6IHtbXzogbnVtYmVyIHwgc3RyaW5nXTogP1RpbGV9O1xuICAgIF9vbmx5U3ltYm9sczogP2Jvb2xlYW47XG5cbiAgICBzdGF0aWMgbWF4VW5kZXJ6b29taW5nOiBudW1iZXI7XG4gICAgc3RhdGljIG1heE92ZXJ6b29taW5nOiBudW1iZXI7XG5cbiAgICBjb25zdHJ1Y3RvcihpZDogc3RyaW5nLCBzb3VyY2U6IFNvdXJjZSwgb25seVN5bWJvbHM/OiBib29sZWFuKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuaWQgPSBpZDtcbiAgICAgICAgdGhpcy5fb25seVN5bWJvbHMgPSBvbmx5U3ltYm9scztcblxuICAgICAgICBzb3VyY2Uub24oJ2RhdGEnLCAoZSkgPT4ge1xuICAgICAgICAgICAgLy8gdGhpcy5fc291cmNlTG9hZGVkIHNpZ25pZmllcyB0aGF0IHRoZSBUaWxlSlNPTiBpcyBsb2FkZWQgaWYgYXBwbGljYWJsZS5cbiAgICAgICAgICAgIC8vIGlmIHRoZSBzb3VyY2UgdHlwZSBkb2VzIG5vdCBjb21lIHdpdGggYSBUaWxlSlNPTiwgdGhlIGZsYWcgc2lnbmlmaWVzIHRoZVxuICAgICAgICAgICAgLy8gc291cmNlIGRhdGEgaGFzIGxvYWRlZCAoaW4gb3RoZXIgd29yZHMsIEdlb0pTT04gaGFzIGJlZW4gdGlsZWQgb24gdGhlIHdvcmtlciBhbmQgaXMgcmVhZHkpXG4gICAgICAgICAgICBpZiAoZS5kYXRhVHlwZSA9PT0gJ3NvdXJjZScgJiYgZS5zb3VyY2VEYXRhVHlwZSA9PT0gJ21ldGFkYXRhJykgdGhpcy5fc291cmNlTG9hZGVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgLy8gZm9yIHNvdXJjZXMgd2l0aCBtdXRhYmxlIGRhdGEsIHRoaXMgZXZlbnQgZmlyZXMgd2hlbiB0aGUgdW5kZXJseWluZyBkYXRhXG4gICAgICAgICAgICAvLyB0byBhIHNvdXJjZSBpcyBjaGFuZ2VkIChmb3IgZXhhbXBsZSwgdXNpbmcgW0dlb0pTT05Tb3VyY2Ujc2V0RGF0YV0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2FwaS9zb3VyY2VzLyNnZW9qc29uc291cmNlI3NldGRhdGEpIG9yIFtJbWFnZVNvdXJjZSNzZXRDb29yZGluYXRlc10oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2FwaS9zb3VyY2VzLyNpbWFnZXNvdXJjZSNzZXRjb29yZGluYXRlcykpXG4gICAgICAgICAgICBpZiAodGhpcy5fc291cmNlTG9hZGVkICYmICF0aGlzLl9wYXVzZWQgJiYgZS5kYXRhVHlwZSA9PT0gXCJzb3VyY2VcIiAmJiBlLnNvdXJjZURhdGFUeXBlID09PSAnY29udGVudCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbG9hZCgpO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZSh0aGlzLnRyYW5zZm9ybSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBzb3VyY2Uub24oJ2Vycm9yJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlRXJyb3JlZCA9IHRydWU7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuX3NvdXJjZSA9IHNvdXJjZTtcbiAgICAgICAgdGhpcy5fdGlsZXMgPSB7fTtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICB0aGlzLl9jYWNoZSA9IG5ldyBUaWxlQ2FjaGUoMCwgdGhpcy5fdW5sb2FkVGlsZS5iaW5kKHRoaXMpKTtcbiAgICAgICAgdGhpcy5fdGltZXJzID0ge307XG4gICAgICAgIHRoaXMuX2NhY2hlVGltZXJzID0ge307XG4gICAgICAgIHRoaXMuX21pblRpbGVDYWNoZVNpemUgPSBzb3VyY2UubWluVGlsZUNhY2hlU2l6ZTtcbiAgICAgICAgdGhpcy5fbWF4VGlsZUNhY2hlU2l6ZSA9IHNvdXJjZS5tYXhUaWxlQ2FjaGVTaXplO1xuICAgICAgICB0aGlzLl9sb2FkZWRQYXJlbnRUaWxlcyA9IHt9O1xuXG4gICAgICAgIHRoaXMuX2NvdmVyZWRUaWxlcyA9IHt9O1xuICAgICAgICB0aGlzLl9zdGF0ZSA9IG5ldyBTb3VyY2VGZWF0dXJlU3RhdGUoKTtcbiAgICAgICAgdGhpcy5faXNSYXN0ZXIgPVxuICAgICAgICAgICAgdGhpcy5fc291cmNlLnR5cGUgPT09ICdyYXN0ZXInIHx8XG4gICAgICAgICAgICB0aGlzLl9zb3VyY2UudHlwZSA9PT0gJ3Jhc3Rlci1kZW0nIHx8XG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW3Byb3AtbWlzc2luZ11cbiAgICAgICAgICAgICh0aGlzLl9zb3VyY2UudHlwZSA9PT0gJ2N1c3RvbScgJiYgdGhpcy5fc291cmNlLl9kYXRhVHlwZSA9PT0gJ3Jhc3RlcicpO1xuICAgIH1cblxuICAgIG9uQWRkKG1hcDogTWFwYm94TWFwKSB7XG4gICAgICAgIHRoaXMubWFwID0gbWFwO1xuICAgICAgICB0aGlzLl9taW5UaWxlQ2FjaGVTaXplID0gdGhpcy5fbWluVGlsZUNhY2hlU2l6ZSA9PT0gdW5kZWZpbmVkICYmIG1hcCA/IG1hcC5fbWluVGlsZUNhY2hlU2l6ZSA6IHRoaXMuX21pblRpbGVDYWNoZVNpemU7XG4gICAgICAgIHRoaXMuX21heFRpbGVDYWNoZVNpemUgPSB0aGlzLl9tYXhUaWxlQ2FjaGVTaXplID09PSB1bmRlZmluZWQgJiYgbWFwID8gbWFwLl9tYXhUaWxlQ2FjaGVTaXplIDogdGhpcy5fbWF4VGlsZUNhY2hlU2l6ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdHJ1ZSBpZiBubyB0aWxlIGRhdGEgaXMgcGVuZGluZywgdGlsZXMgd2lsbCBub3QgY2hhbmdlIHVubGVzc1xuICAgICAqIGFuIGFkZGl0aW9uYWwgQVBJIGNhbGwgaXMgcmVjZWl2ZWQuXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBsb2FkZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICh0aGlzLl9zb3VyY2VFcnJvcmVkKSB7IHJldHVybiB0cnVlOyB9XG4gICAgICAgIGlmICghdGhpcy5fc291cmNlTG9hZGVkKSB7IHJldHVybiBmYWxzZTsgfVxuICAgICAgICBpZiAoIXRoaXMuX3NvdXJjZS5sb2FkZWQoKSkgeyByZXR1cm4gZmFsc2U7IH1cbiAgICAgICAgZm9yIChjb25zdCB0IGluIHRoaXMuX3RpbGVzKSB7XG4gICAgICAgICAgICBjb25zdCB0aWxlID0gdGhpcy5fdGlsZXNbdF07XG4gICAgICAgICAgICBpZiAodGlsZS5zdGF0ZSAhPT0gJ2xvYWRlZCcgJiYgdGlsZS5zdGF0ZSAhPT0gJ2Vycm9yZWQnKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBnZXRTb3VyY2UoKTogU291cmNlIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NvdXJjZTtcbiAgICB9XG5cbiAgICBwYXVzZSgpIHtcbiAgICAgICAgdGhpcy5fcGF1c2VkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXN1bWUoKSB7XG4gICAgICAgIGlmICghdGhpcy5fcGF1c2VkKSByZXR1cm47XG4gICAgICAgIGNvbnN0IHNob3VsZFJlbG9hZCA9IHRoaXMuX3Nob3VsZFJlbG9hZE9uUmVzdW1lO1xuICAgICAgICB0aGlzLl9wYXVzZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fc2hvdWxkUmVsb2FkT25SZXN1bWUgPSBmYWxzZTtcbiAgICAgICAgaWYgKHNob3VsZFJlbG9hZCkgdGhpcy5yZWxvYWQoKTtcbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtKSB0aGlzLnVwZGF0ZSh0aGlzLnRyYW5zZm9ybSk7XG4gICAgfVxuXG4gICAgX2xvYWRUaWxlKHRpbGU6IFRpbGUsIGNhbGxiYWNrOiBDYWxsYmFjazx2b2lkPik6IHZvaWQge1xuICAgICAgICB0aWxlLmlzU3ltYm9sVGlsZSA9IHRoaXMuX29ubHlTeW1ib2xzO1xuICAgICAgICByZXR1cm4gdGhpcy5fc291cmNlLmxvYWRUaWxlKHRpbGUsIGNhbGxiYWNrKTtcbiAgICB9XG5cbiAgICBfdW5sb2FkVGlsZSh0aWxlOiBUaWxlKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLl9zb3VyY2UudW5sb2FkVGlsZSlcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9zb3VyY2UudW5sb2FkVGlsZSh0aWxlLCAoKSA9PiB7fSk7XG4gICAgfVxuXG4gICAgX2Fib3J0VGlsZSh0aWxlOiBUaWxlKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLl9zb3VyY2UuYWJvcnRUaWxlKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NvdXJjZS5hYm9ydFRpbGUodGlsZSwgKCkgPT4ge30pO1xuICAgIH1cblxuICAgIHNlcmlhbGl6ZSgpOiBTb3VyY2VTcGVjaWZpY2F0aW9uIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NvdXJjZS5zZXJpYWxpemUoKTtcbiAgICB9XG5cbiAgICBwcmVwYXJlKGNvbnRleHQ6IENvbnRleHQpIHtcbiAgICAgICAgaWYgICh0aGlzLl9zb3VyY2UucHJlcGFyZSkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlLnByZXBhcmUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3N0YXRlLmNvYWxlc2NlQ2hhbmdlcyh0aGlzLl90aWxlcywgdGhpcy5tYXAgPyB0aGlzLm1hcC5wYWludGVyIDogbnVsbCk7XG5cbiAgICAgICAgZm9yIChjb25zdCBpIGluIHRoaXMuX3RpbGVzKSB7XG4gICAgICAgICAgICBjb25zdCB0aWxlID0gdGhpcy5fdGlsZXNbaV07XG4gICAgICAgICAgICB0aWxlLnVwbG9hZChjb250ZXh0KTtcbiAgICAgICAgICAgIHRpbGUucHJlcGFyZSh0aGlzLm1hcC5zdHlsZS5pbWFnZU1hbmFnZXIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJuIGFsbCB0aWxlIGlkcyBvcmRlcmVkIHdpdGggei1vcmRlciwgYW5kIGNhc3QgdG8gbnVtYmVyc1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgZ2V0SWRzKCk6IEFycmF5PG51bWJlcj4ge1xuICAgICAgICByZXR1cm4gdmFsdWVzKCh0aGlzLl90aWxlczogYW55KSkubWFwKCh0aWxlOiBUaWxlKSA9PiB0aWxlLnRpbGVJRCkuc29ydChjb21wYXJlVGlsZUlkKS5tYXAoaWQgPT4gaWQua2V5KTtcbiAgICB9XG5cbiAgICBnZXRSZW5kZXJhYmxlSWRzKHN5bWJvbExheWVyPzogYm9vbGVhbik6IEFycmF5PG51bWJlcj4ge1xuICAgICAgICBjb25zdCByZW5kZXJhYmxlczogQXJyYXk8VGlsZT4gPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBpZCBpbiB0aGlzLl90aWxlcykge1xuICAgICAgICAgICAgaWYgKHRoaXMuX2lzSWRSZW5kZXJhYmxlKCtpZCwgc3ltYm9sTGF5ZXIpKSByZW5kZXJhYmxlcy5wdXNoKHRoaXMuX3RpbGVzW2lkXSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN5bWJvbExheWVyKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVuZGVyYWJsZXMuc29ydCgoYV86IFRpbGUsIGJfOiBUaWxlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgYSA9IGFfLnRpbGVJRDtcbiAgICAgICAgICAgICAgICBjb25zdCBiID0gYl8udGlsZUlEO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJvdGF0ZWRBID0gKG5ldyBQb2ludChhLmNhbm9uaWNhbC54LCBhLmNhbm9uaWNhbC55KSkuX3JvdGF0ZSh0aGlzLnRyYW5zZm9ybS5hbmdsZSk7XG4gICAgICAgICAgICAgICAgY29uc3Qgcm90YXRlZEIgPSAobmV3IFBvaW50KGIuY2Fub25pY2FsLngsIGIuY2Fub25pY2FsLnkpKS5fcm90YXRlKHRoaXMudHJhbnNmb3JtLmFuZ2xlKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYS5vdmVyc2NhbGVkWiAtIGIub3ZlcnNjYWxlZFogfHwgcm90YXRlZEIueSAtIHJvdGF0ZWRBLnkgfHwgcm90YXRlZEIueCAtIHJvdGF0ZWRBLng7XG4gICAgICAgICAgICB9KS5tYXAodGlsZSA9PiB0aWxlLnRpbGVJRC5rZXkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZW5kZXJhYmxlcy5tYXAodGlsZSA9PiB0aWxlLnRpbGVJRCkuc29ydChjb21wYXJlVGlsZUlkKS5tYXAoaWQgPT4gaWQua2V5KTtcbiAgICB9XG5cbiAgICBoYXNSZW5kZXJhYmxlUGFyZW50KHRpbGVJRDogT3ZlcnNjYWxlZFRpbGVJRCk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCBwYXJlbnRUaWxlID0gdGhpcy5maW5kTG9hZGVkUGFyZW50KHRpbGVJRCwgMCk7XG4gICAgICAgIGlmIChwYXJlbnRUaWxlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5faXNJZFJlbmRlcmFibGUocGFyZW50VGlsZS50aWxlSUQua2V5KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgX2lzSWRSZW5kZXJhYmxlKGlkOiBudW1iZXIsIHN5bWJvbExheWVyPzogYm9vbGVhbik6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGlsZXNbaWRdICYmIHRoaXMuX3RpbGVzW2lkXS5oYXNEYXRhKCkgJiZcbiAgICAgICAgICAgICF0aGlzLl9jb3ZlcmVkVGlsZXNbaWRdICYmIChzeW1ib2xMYXllciB8fCAhdGhpcy5fdGlsZXNbaWRdLmhvbGRpbmdGb3JGYWRlKCkpO1xuICAgIH1cblxuICAgIHJlbG9hZCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX3BhdXNlZCkge1xuICAgICAgICAgICAgdGhpcy5fc2hvdWxkUmVsb2FkT25SZXN1bWUgPSB0cnVlO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fY2FjaGUucmVzZXQoKTtcblxuICAgICAgICBmb3IgKGNvbnN0IGkgaW4gdGhpcy5fdGlsZXMpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl90aWxlc1tpXS5zdGF0ZSAhPT0gXCJlcnJvcmVkXCIpIHRoaXMuX3JlbG9hZFRpbGUoK2ksICdyZWxvYWRpbmcnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9yZWxvYWRUaWxlKGlkOiBudW1iZXIsIHN0YXRlOiBUaWxlU3RhdGUpIHtcbiAgICAgICAgY29uc3QgdGlsZSA9IHRoaXMuX3RpbGVzW2lkXTtcblxuICAgICAgICAvLyB0aGlzIHBvdGVudGlhbGx5IGRvZXMgbm90IGFkZHJlc3MgYWxsIHVuZGVybHlpbmdcbiAgICAgICAgLy8gaXNzdWVzIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXBib3gvbWFwYm94LWdsLWpzL2lzc3Vlcy80MjUyXG4gICAgICAgIC8vIC0gaGFyZCB0byB0ZWxsIHdpdGhvdXQgcmVwcm8gc3RlcHNcbiAgICAgICAgaWYgKCF0aWxlKSByZXR1cm47XG5cbiAgICAgICAgLy8gVGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBcImxvYWRpbmdcIiB0aWxlcyBhbmQgXCJyZWxvYWRpbmdcIiBvciBcImV4cGlyZWRcIlxuICAgICAgICAvLyB0aWxlcyBpcyB0aGF0IFwicmVsb2FkaW5nXCIvXCJleHBpcmVkXCIgdGlsZXMgYXJlIFwicmVuZGVyYWJsZVwiLlxuICAgICAgICAvLyBUaGVyZWZvcmUsIGEgXCJsb2FkaW5nXCIgdGlsZSBjYW5ub3QgYmVjb21lIGEgXCJyZWxvYWRpbmdcIiB0aWxlIHdpdGhvdXRcbiAgICAgICAgLy8gZmlyc3QgYmVjb21pbmcgYSBcImxvYWRlZFwiIHRpbGUuXG4gICAgICAgIGlmICh0aWxlLnN0YXRlICE9PSAnbG9hZGluZycpIHtcbiAgICAgICAgICAgIHRpbGUuc3RhdGUgPSBzdGF0ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgdGhpcy5fbG9hZFRpbGUodGlsZSwgdGhpcy5fdGlsZUxvYWRlZC5iaW5kKHRoaXMsIHRpbGUsIGlkLCBzdGF0ZSkpO1xuICAgIH1cblxuICAgIF90aWxlTG9hZGVkKHRpbGU6IFRpbGUsIGlkOiBudW1iZXIsIHByZXZpb3VzU3RhdGU6IFRpbGVTdGF0ZSwgZXJyOiA/RXJyb3IpIHtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgdGlsZS5zdGF0ZSA9ICdlcnJvcmVkJztcbiAgICAgICAgICAgIGlmICgoZXJyOiBhbnkpLnN0YXR1cyAhPT0gNDA0KSB0aGlzLl9zb3VyY2UuZmlyZShuZXcgRXJyb3JFdmVudChlcnIsIHt0aWxlfSkpO1xuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gY29udGludWUgdG8gdHJ5IGxvYWRpbmcgcGFyZW50L2NoaWxkcmVuIHRpbGVzIGlmIGEgdGlsZSBkb2Vzbid0IGV4aXN0ICg0MDQpXG4gICAgICAgICAgICAgICAgY29uc3QgdXBkYXRlRm9yVGVycmFpbiA9IHRoaXMuX3NvdXJjZS50eXBlID09PSAncmFzdGVyLWRlbScgJiYgdGhpcy51c2VkRm9yVGVycmFpbjtcbiAgICAgICAgICAgICAgICBpZiAodXBkYXRlRm9yVGVycmFpbiAmJiB0aGlzLm1hcC5wYWludGVyLnRlcnJhaW4pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGVycmFpbiA9IHRoaXMubWFwLnBhaW50ZXIudGVycmFpbjtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGUodGhpcy50cmFuc2Zvcm0sIHRlcnJhaW4uZ2V0U2NhbGVkRGVtVGlsZVNpemUoKSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIHRlcnJhaW4ucmVzZXRUaWxlTG9va3VwQ2FjaGUodGhpcy5pZCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGUodGhpcy50cmFuc2Zvcm0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRpbGUudGltZUFkZGVkID0gYnJvd3Nlci5ub3coKTtcbiAgICAgICAgaWYgKHByZXZpb3VzU3RhdGUgPT09ICdleHBpcmVkJykgdGlsZS5yZWZyZXNoZWRVcG9uRXhwaXJhdGlvbiA9IHRydWU7XG4gICAgICAgIHRoaXMuX3NldFRpbGVSZWxvYWRUaW1lcihpZCwgdGlsZSk7XG4gICAgICAgIGlmICh0aGlzLl9zb3VyY2UudHlwZSA9PT0gJ3Jhc3Rlci1kZW0nICYmIHRpbGUuZGVtKSB0aGlzLl9iYWNrZmlsbERFTSh0aWxlKTtcbiAgICAgICAgdGhpcy5fc3RhdGUuaW5pdGlhbGl6ZVRpbGVTdGF0ZSh0aWxlLCB0aGlzLm1hcCA/IHRoaXMubWFwLnBhaW50ZXIgOiBudWxsKTtcblxuICAgICAgICB0aGlzLl9zb3VyY2UuZmlyZShuZXcgRXZlbnQoJ2RhdGEnLCB7ZGF0YVR5cGU6ICdzb3VyY2UnLCB0aWxlLCBjb29yZDogdGlsZS50aWxlSUQsICdzb3VyY2VDYWNoZUlkJzogdGhpcy5pZH0pKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEZvciByYXN0ZXIgdGVycmFpbiBzb3VyY2UsIGJhY2tmaWxsIERFTSB0byBlbGltaW5hdGUgdmlzaWJsZSB0aWxlIGJvdW5kYXJpZXNcbiAgICAqIEBwcml2YXRlXG4gICAgKi9cbiAgICBfYmFja2ZpbGxERU0odGlsZTogVGlsZSkge1xuICAgICAgICBjb25zdCByZW5kZXJhYmxlcyA9IHRoaXMuZ2V0UmVuZGVyYWJsZUlkcygpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJlbmRlcmFibGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBib3JkZXJJZCA9IHJlbmRlcmFibGVzW2ldO1xuICAgICAgICAgICAgaWYgKHRpbGUubmVpZ2hib3JpbmdUaWxlcyAmJiB0aWxlLm5laWdoYm9yaW5nVGlsZXNbYm9yZGVySWRdKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgYm9yZGVyVGlsZSA9IHRoaXMuZ2V0VGlsZUJ5SUQoYm9yZGVySWQpO1xuICAgICAgICAgICAgICAgIGZpbGxCb3JkZXIodGlsZSwgYm9yZGVyVGlsZSk7XG4gICAgICAgICAgICAgICAgZmlsbEJvcmRlcihib3JkZXJUaWxlLCB0aWxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGZpbGxCb3JkZXIodGlsZTogVGlsZSwgYm9yZGVyVGlsZTogVGlsZSkge1xuICAgICAgICAgICAgaWYgKCF0aWxlLmRlbSB8fCB0aWxlLmRlbS5ib3JkZXJSZWFkeSkgcmV0dXJuO1xuICAgICAgICAgICAgdGlsZS5uZWVkc0hpbGxzaGFkZVByZXBhcmUgPSB0cnVlO1xuICAgICAgICAgICAgdGlsZS5uZWVkc0RFTVRleHR1cmVVcGxvYWQgPSB0cnVlO1xuICAgICAgICAgICAgbGV0IGR4ID0gYm9yZGVyVGlsZS50aWxlSUQuY2Fub25pY2FsLnggLSB0aWxlLnRpbGVJRC5jYW5vbmljYWwueDtcbiAgICAgICAgICAgIGNvbnN0IGR5ID0gYm9yZGVyVGlsZS50aWxlSUQuY2Fub25pY2FsLnkgLSB0aWxlLnRpbGVJRC5jYW5vbmljYWwueTtcbiAgICAgICAgICAgIGNvbnN0IGRpbSA9IE1hdGgucG93KDIsIHRpbGUudGlsZUlELmNhbm9uaWNhbC56KTtcbiAgICAgICAgICAgIGNvbnN0IGJvcmRlcklkID0gYm9yZGVyVGlsZS50aWxlSUQua2V5O1xuICAgICAgICAgICAgaWYgKGR4ID09PSAwICYmIGR5ID09PSAwKSByZXR1cm47XG5cbiAgICAgICAgICAgIGlmIChNYXRoLmFicyhkeSkgPiAxKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKE1hdGguYWJzKGR4KSA+IDEpIHtcbiAgICAgICAgICAgICAgICAvLyBBZGp1c3QgdGhlIGRlbHRhIGNvb3JkaW5hdGUgZm9yIHdvcmxkIHdyYXBhcm91bmQuXG4gICAgICAgICAgICAgICAgaWYgKE1hdGguYWJzKGR4ICsgZGltKSA9PT0gMSkge1xuICAgICAgICAgICAgICAgICAgICBkeCArPSBkaW07XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChNYXRoLmFicyhkeCAtIGRpbSkgPT09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgZHggLT0gZGltO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghYm9yZGVyVGlsZS5kZW0gfHwgIXRpbGUuZGVtKSByZXR1cm47XG4gICAgICAgICAgICB0aWxlLmRlbS5iYWNrZmlsbEJvcmRlcihib3JkZXJUaWxlLmRlbSwgZHgsIGR5KTtcbiAgICAgICAgICAgIGlmICh0aWxlLm5laWdoYm9yaW5nVGlsZXMgJiYgdGlsZS5uZWlnaGJvcmluZ1RpbGVzW2JvcmRlcklkXSlcbiAgICAgICAgICAgICAgICB0aWxlLm5laWdoYm9yaW5nVGlsZXNbYm9yZGVySWRdLmJhY2tmaWxsZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBhIHNwZWNpZmljIHRpbGUgYnkgVGlsZUlEXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBnZXRUaWxlKHRpbGVJRDogT3ZlcnNjYWxlZFRpbGVJRCk6IFRpbGUge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRUaWxlQnlJRCh0aWxlSUQua2V5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgYSBzcGVjaWZpYyB0aWxlIGJ5IGlkXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBnZXRUaWxlQnlJRChpZDogbnVtYmVyKTogVGlsZSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90aWxlc1tpZF07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRm9yIGEgZ2l2ZW4gc2V0IG9mIHRpbGVzLCByZXRhaW4gY2hpbGRyZW4gdGhhdCBhcmUgbG9hZGVkIGFuZCBoYXZlIGEgem9vbVxuICAgICAqIGJldHdlZW4gYHpvb21gIChleGNsdXNpdmUpIGFuZCBgbWF4Q292ZXJpbmdab29tYCAoaW5jbHVzaXZlKVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgX3JldGFpbkxvYWRlZENoaWxkcmVuKFxuICAgICAgICBpZGVhbFRpbGVzOiB7W251bWJlciB8IHN0cmluZ106IE92ZXJzY2FsZWRUaWxlSUR9LFxuICAgICAgICB6b29tOiBudW1iZXIsXG4gICAgICAgIG1heENvdmVyaW5nWm9vbTogbnVtYmVyLFxuICAgICAgICByZXRhaW46IHtbbnVtYmVyIHwgc3RyaW5nXTogT3ZlcnNjYWxlZFRpbGVJRH1cbiAgICApIHtcbiAgICAgICAgZm9yIChjb25zdCBpZCBpbiB0aGlzLl90aWxlcykge1xuICAgICAgICAgICAgbGV0IHRpbGUgPSB0aGlzLl90aWxlc1tpZF07XG5cbiAgICAgICAgICAgIC8vIG9ubHkgY29uc2lkZXIgcmVuZGVyYWJsZSB0aWxlcyB1cCB0byBtYXhDb3ZlcmluZ1pvb21cbiAgICAgICAgICAgIGlmIChyZXRhaW5baWRdIHx8XG4gICAgICAgICAgICAgICAgIXRpbGUuaGFzRGF0YSgpIHx8XG4gICAgICAgICAgICAgICAgdGlsZS50aWxlSUQub3ZlcnNjYWxlZFogPD0gem9vbSB8fFxuICAgICAgICAgICAgICAgIHRpbGUudGlsZUlELm92ZXJzY2FsZWRaID4gbWF4Q292ZXJpbmdab29tXG4gICAgICAgICAgICApIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICAvLyBsb29wIHRocm91Z2ggcGFyZW50cyBhbmQgcmV0YWluIHRoZSB0b3Btb3N0IGxvYWRlZCBvbmUgaWYgZm91bmRcbiAgICAgICAgICAgIGxldCB0b3Btb3N0TG9hZGVkSUQgPSB0aWxlLnRpbGVJRDtcbiAgICAgICAgICAgIHdoaWxlICh0aWxlICYmIHRpbGUudGlsZUlELm92ZXJzY2FsZWRaID4gem9vbSArIDEpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJlbnRJRCA9IHRpbGUudGlsZUlELnNjYWxlZFRvKHRpbGUudGlsZUlELm92ZXJzY2FsZWRaIC0gMSk7XG5cbiAgICAgICAgICAgICAgICB0aWxlID0gdGhpcy5fdGlsZXNbcGFyZW50SUQua2V5XTtcblxuICAgICAgICAgICAgICAgIGlmICh0aWxlICYmIHRpbGUuaGFzRGF0YSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRvcG1vc3RMb2FkZWRJRCA9IHBhcmVudElEO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gbG9vcCB0aHJvdWdoIGFuY2VzdG9ycyBvZiB0aGUgdG9wbW9zdCBsb2FkZWQgY2hpbGQgdG8gc2VlIGlmIHRoZXJlJ3Mgb25lIHRoYXQgbmVlZGVkIGl0XG4gICAgICAgICAgICBsZXQgdGlsZUlEID0gdG9wbW9zdExvYWRlZElEO1xuICAgICAgICAgICAgd2hpbGUgKHRpbGVJRC5vdmVyc2NhbGVkWiA+IHpvb20pIHtcbiAgICAgICAgICAgICAgICB0aWxlSUQgPSB0aWxlSUQuc2NhbGVkVG8odGlsZUlELm92ZXJzY2FsZWRaIC0gMSk7XG5cbiAgICAgICAgICAgICAgICBpZiAoaWRlYWxUaWxlc1t0aWxlSUQua2V5XSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBmb3VuZCBhIHBhcmVudCB0aGF0IG5lZWRlZCBhIGxvYWRlZCBjaGlsZDsgcmV0YWluIHRoYXQgY2hpbGRcbiAgICAgICAgICAgICAgICAgICAgcmV0YWluW3RvcG1vc3RMb2FkZWRJRC5rZXldID0gdG9wbW9zdExvYWRlZElEO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGaW5kIGEgbG9hZGVkIHBhcmVudCBvZiB0aGUgZ2l2ZW4gdGlsZSAodXAgdG8gbWluQ292ZXJpbmdab29tKVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgZmluZExvYWRlZFBhcmVudCh0aWxlSUQ6IE92ZXJzY2FsZWRUaWxlSUQsIG1pbkNvdmVyaW5nWm9vbTogbnVtYmVyKTogP1RpbGUge1xuICAgICAgICBpZiAodGlsZUlELmtleSBpbiB0aGlzLl9sb2FkZWRQYXJlbnRUaWxlcykge1xuICAgICAgICAgICAgY29uc3QgcGFyZW50ID0gdGhpcy5fbG9hZGVkUGFyZW50VGlsZXNbdGlsZUlELmtleV07XG4gICAgICAgICAgICBpZiAocGFyZW50ICYmIHBhcmVudC50aWxlSUQub3ZlcnNjYWxlZFogPj0gbWluQ292ZXJpbmdab29tKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcmVudDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgeiA9IHRpbGVJRC5vdmVyc2NhbGVkWiAtIDE7IHogPj0gbWluQ292ZXJpbmdab29tOyB6LS0pIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcmVudFRpbGVJRCA9IHRpbGVJRC5zY2FsZWRUbyh6KTtcbiAgICAgICAgICAgIGNvbnN0IHRpbGUgPSB0aGlzLl9nZXRMb2FkZWRUaWxlKHBhcmVudFRpbGVJRCk7XG4gICAgICAgICAgICBpZiAodGlsZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aWxlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgX2dldExvYWRlZFRpbGUodGlsZUlEOiBPdmVyc2NhbGVkVGlsZUlEKTogP1RpbGUge1xuICAgICAgICBjb25zdCB0aWxlID0gdGhpcy5fdGlsZXNbdGlsZUlELmtleV07XG4gICAgICAgIGlmICh0aWxlICYmIHRpbGUuaGFzRGF0YSgpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGlsZTtcbiAgICAgICAgfVxuICAgICAgICAvLyBUaWxlQ2FjaGUgaWdub3JlcyB3cmFwIGluIGxvb2t1cC5cbiAgICAgICAgY29uc3QgY2FjaGVkVGlsZSA9IHRoaXMuX2NhY2hlLmdldEJ5S2V5KHRoaXMuX3NvdXJjZS5yZXBhcnNlT3ZlcnNjYWxlZCA/IHRpbGVJRC53cmFwcGVkKCkua2V5IDogdGlsZUlELmNhbm9uaWNhbC5rZXkpO1xuICAgICAgICByZXR1cm4gY2FjaGVkVGlsZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXNpemVzIHRoZSB0aWxlIGNhY2hlIGJhc2VkIG9uIHRoZSBjdXJyZW50IHZpZXdwb3J0J3Mgc2l6ZVxuICAgICAqIG9yIHRoZSBtaW5UaWxlQ2FjaGVTaXplIGFuZCBtYXhUaWxlQ2FjaGVTaXplIG9wdGlvbnMgcGFzc2VkIGR1cmluZyBtYXAgY3JlYXRpb25cbiAgICAgKlxuICAgICAqIExhcmdlciB2aWV3cG9ydHMgdXNlIG1vcmUgdGlsZXMgYW5kIG5lZWQgbGFyZ2VyIGNhY2hlcy4gTGFyZ2VyIHZpZXdwb3J0c1xuICAgICAqIGFyZSBtb3JlIGxpa2VseSB0byBiZSBmb3VuZCBvbiBkZXZpY2VzIHdpdGggbW9yZSBtZW1vcnkgYW5kIG9uIHBhZ2VzIHdoZXJlXG4gICAgICogdGhlIG1hcCBpcyBtb3JlIGltcG9ydGFudC5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHVwZGF0ZUNhY2hlU2l6ZSh0cmFuc2Zvcm06IFRyYW5zZm9ybSwgdGlsZVNpemU/OiBudW1iZXIpIHtcbiAgICAgICAgdGlsZVNpemUgPSB0aWxlU2l6ZSB8fCB0aGlzLl9zb3VyY2UudGlsZVNpemU7XG4gICAgICAgIGNvbnN0IHdpZHRoSW5UaWxlcyA9IE1hdGguY2VpbCh0cmFuc2Zvcm0ud2lkdGggLyB0aWxlU2l6ZSkgKyAxO1xuICAgICAgICBjb25zdCBoZWlnaHRJblRpbGVzID0gTWF0aC5jZWlsKHRyYW5zZm9ybS5oZWlnaHQgLyB0aWxlU2l6ZSkgKyAxO1xuICAgICAgICBjb25zdCBhcHByb3hUaWxlc0luVmlldyA9IHdpZHRoSW5UaWxlcyAqIGhlaWdodEluVGlsZXM7XG4gICAgICAgIGNvbnN0IGNvbW1vblpvb21SYW5nZSA9IDU7XG5cbiAgICAgICAgY29uc3Qgdmlld0RlcGVuZGVudE1heFNpemUgPSBNYXRoLmZsb29yKGFwcHJveFRpbGVzSW5WaWV3ICogY29tbW9uWm9vbVJhbmdlKTtcbiAgICAgICAgY29uc3QgbWluU2l6ZSA9IHR5cGVvZiB0aGlzLl9taW5UaWxlQ2FjaGVTaXplID09PSAnbnVtYmVyJyA/IE1hdGgubWF4KHRoaXMuX21pblRpbGVDYWNoZVNpemUsIHZpZXdEZXBlbmRlbnRNYXhTaXplKSA6IHZpZXdEZXBlbmRlbnRNYXhTaXplO1xuICAgICAgICBjb25zdCBtYXhTaXplID0gdHlwZW9mIHRoaXMuX21heFRpbGVDYWNoZVNpemUgPT09ICdudW1iZXInID8gTWF0aC5taW4odGhpcy5fbWF4VGlsZUNhY2hlU2l6ZSwgbWluU2l6ZSkgOiBtaW5TaXplO1xuXG4gICAgICAgIHRoaXMuX2NhY2hlLnNldE1heFNpemUobWF4U2l6ZSk7XG4gICAgfVxuXG4gICAgaGFuZGxlV3JhcEp1bXAobG5nOiBudW1iZXIpIHtcbiAgICAgICAgLy8gT24gdG9wIG9mIHRoZSByZWd1bGFyIHoveC95IHZhbHVlcywgVGlsZUlEcyBoYXZlIGEgYHdyYXBgIHZhbHVlIHRoYXQgc3BlY2lmeVxuICAgICAgICAvLyB3aGljaCBjb3B5IG9mIHRoZSB3b3JsZCB0aGUgdGlsZSBiZWxvbmdzIHRvLiBGb3IgZXhhbXBsZSwgYXQgYGxuZzogMTBgIHlvdVxuICAgICAgICAvLyBtaWdodCByZW5kZXIgei94L3kvMCB3aGlsZSBhdCBgbG5nOiAzNzBgIHlvdSB3b3VsZCByZW5kZXIgei94L3kvMS5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gV2hlbiBsbmcgdmFsdWVzIGdldCB3cmFwcGVkIChnb2luZyBmcm9tIGBsbmc6IDM3MGAgdG8gYGxvbmc6IDEwYCkgeW91IGV4cGVjdFxuICAgICAgICAvLyB0byBzZWUgdGhlIHNhbWUgdGhpbmcgb24gdGhlIHNjcmVlbiAoMzcwIGRlZ3JlZXMgYW5kIDEwIGRlZ3JlZXMgaXMgdGhlIHNhbWVcbiAgICAgICAgLy8gcGxhY2UgaW4gdGhlIHdvcmxkKSBidXQgYWxsIHRoZSBUaWxlSURzIHdpbGwgaGF2ZSBkaWZmZXJlbnQgd3JhcCB2YWx1ZXMuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIEluIG9yZGVyIHRvIG1ha2UgdGhpcyB0cmFuc2l0aW9uIHNlYW1sZXNzLCB3ZSBjYWxjdWxhdGUgdGhlIHJvdW5kZWQgZGlmZmVyZW5jZSBvZlxuICAgICAgICAvLyBcIndvcmxkc1wiIGJldHdlZW4gdGhlIGxhc3QgZnJhbWUgYW5kIHRoZSBjdXJyZW50IGZyYW1lLiBJZiB0aGUgbWFwIHBhbm5lZCBieVxuICAgICAgICAvLyBhIHdvcmxkLCB0aGVuIHdlIGNhbiBhc3NpZ24gYWxsIHRoZSB0aWxlcyBuZXcgVGlsZUlEcyB3aXRoIHVwZGF0ZWQgd3JhcCB2YWx1ZXMuXG4gICAgICAgIC8vIEZvciBleGFtcGxlLCBhc3NpZ24gei94L3kvMSBhIG5ldyBpZDogei94L3kvMC4gSXQgaXMgdGhlIHNhbWUgdGlsZSwganVzdCByZW5kZXJlZFxuICAgICAgICAvLyBpbiBhIGRpZmZlcmVudCBwb3NpdGlvbi5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gVGhpcyBlbmFibGVzIHVzIHRvIHJldXNlIHRoZSB0aWxlcyBhdCBtb3JlIGlkZWFsIGxvY2F0aW9ucyBhbmQgcHJldmVudCBmbGlja2VyaW5nLlxuICAgICAgICBjb25zdCBwcmV2TG5nID0gdGhpcy5fcHJldkxuZyA9PT0gdW5kZWZpbmVkID8gbG5nIDogdGhpcy5fcHJldkxuZztcbiAgICAgICAgY29uc3QgbG5nRGlmZmVyZW5jZSA9IGxuZyAtIHByZXZMbmc7XG4gICAgICAgIGNvbnN0IHdvcmxkRGlmZmVyZW5jZSA9IGxuZ0RpZmZlcmVuY2UgLyAzNjA7XG4gICAgICAgIGNvbnN0IHdyYXBEZWx0YSA9IE1hdGgucm91bmQod29ybGREaWZmZXJlbmNlKTtcbiAgICAgICAgdGhpcy5fcHJldkxuZyA9IGxuZztcblxuICAgICAgICBpZiAod3JhcERlbHRhKSB7XG4gICAgICAgICAgICBjb25zdCB0aWxlczoge1tfOiBzdHJpbmcgfCBudW1iZXJdOiBUaWxlfSA9IHt9O1xuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gdGhpcy5fdGlsZXMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0aWxlID0gdGhpcy5fdGlsZXNba2V5XTtcbiAgICAgICAgICAgICAgICB0aWxlLnRpbGVJRCA9IHRpbGUudGlsZUlELnVud3JhcFRvKHRpbGUudGlsZUlELndyYXAgKyB3cmFwRGVsdGEpO1xuICAgICAgICAgICAgICAgIHRpbGVzW3RpbGUudGlsZUlELmtleV0gPSB0aWxlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fdGlsZXMgPSB0aWxlcztcblxuICAgICAgICAgICAgLy8gUmVzZXQgdGlsZSByZWxvYWQgdGltZXJzXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGlkIGluIHRoaXMuX3RpbWVycykge1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLl90aW1lcnNbaWRdKTtcbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5fdGltZXJzW2lkXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAoY29uc3QgaWQgaW4gdGhpcy5fdGlsZXMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0aWxlID0gdGhpcy5fdGlsZXNbaWRdO1xuICAgICAgICAgICAgICAgIHRoaXMuX3NldFRpbGVSZWxvYWRUaW1lcigraWQsIHRpbGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyB0aWxlcyB0aGF0IGFyZSBvdXRzaWRlIHRoZSB2aWV3cG9ydCBhbmQgYWRkcyBuZXcgdGlsZXMgdGhhdFxuICAgICAqIGFyZSBpbnNpZGUgdGhlIHZpZXdwb3J0LlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtib29sZWFufSB1cGRhdGVGb3JUZXJyYWluIFNpZ25hbHMgdG8gdXBkYXRlIHRpbGVzIGV2ZW4gaWYgdGhlXG4gICAgICogc291cmNlIGlzIG5vdCB1c2VkICh0aGlzLnVzZWQpIGJ5IGxheWVyczogaXQgaXMgdXNlZCBmb3IgdGVycmFpbi5cbiAgICAgKiBAcGFyYW0ge3RpbGVTaXplfSB0aWxlU2l6ZSBJZiBuZWVkZWQgdG8gZ2V0IGxvd2VyIHJlc29sdXRpb24gaWRlYWwgY292ZXIsXG4gICAgICogb3ZlcnJpZGUgc291cmNlLnRpbGVTaXplIHVzZWQgaW4gdGlsZSBjb3ZlciBjYWxjdWxhdGlvbi5cbiAgICAgKi9cbiAgICB1cGRhdGUodHJhbnNmb3JtOiBUcmFuc2Zvcm0sIHRpbGVTaXplPzogbnVtYmVyLCB1cGRhdGVGb3JUZXJyYWluPzogYm9vbGVhbikge1xuICAgICAgICB0aGlzLnRyYW5zZm9ybSA9IHRyYW5zZm9ybTtcbiAgICAgICAgaWYgKCF0aGlzLl9zb3VyY2VMb2FkZWQgfHwgdGhpcy5fcGF1c2VkIHx8IHRoaXMudHJhbnNmb3JtLmZyZWV6ZVRpbGVDb3ZlcmFnZSkgeyByZXR1cm47IH1cbiAgICAgICAgYXNzZXJ0KCEodXBkYXRlRm9yVGVycmFpbiAmJiAhdGhpcy51c2VkRm9yVGVycmFpbikpO1xuICAgICAgICBpZiAodGhpcy51c2VkRm9yVGVycmFpbiAmJiAhdXBkYXRlRm9yVGVycmFpbikge1xuICAgICAgICAgICAgLy8gSWYgc291cmNlIGlzIHVzZWQgZm9yIGJvdGggdGVycmFpbiBhbmQgaGlsbHNoYWRlLCBkb24ndCB1cGRhdGUgaXQgdHdpY2UuXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnVwZGF0ZUNhY2hlU2l6ZSh0cmFuc2Zvcm0sIHRpbGVTaXplKTtcbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtLnByb2plY3Rpb24ubmFtZSAhPT0gJ2dsb2JlJykge1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVXcmFwSnVtcCh0aGlzLnRyYW5zZm9ybS5jZW50ZXIubG5nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENvdmVyZWQgaXMgYSBsaXN0IG9mIHJldGFpbmVkIHRpbGVzIHdobydzIGFyZWFzIGFyZSBmdWxseSBjb3ZlcmVkIGJ5IG90aGVyLFxuICAgICAgICAvLyBiZXR0ZXIsIHJldGFpbmVkIHRpbGVzLiBUaGV5IGFyZSBub3QgZHJhd24gc2VwYXJhdGVseS5cbiAgICAgICAgdGhpcy5fY292ZXJlZFRpbGVzID0ge307XG5cbiAgICAgICAgbGV0IGlkZWFsVGlsZUlEcztcbiAgICAgICAgaWYgKCF0aGlzLnVzZWQgJiYgIXRoaXMudXNlZEZvclRlcnJhaW4pIHtcbiAgICAgICAgICAgIGlkZWFsVGlsZUlEcyA9IFtdO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX3NvdXJjZS50aWxlSUQpIHtcbiAgICAgICAgICAgIGlkZWFsVGlsZUlEcyA9IHRyYW5zZm9ybS5nZXRWaXNpYmxlVW53cmFwcGVkQ29vcmRpbmF0ZXModGhpcy5fc291cmNlLnRpbGVJRClcbiAgICAgICAgICAgICAgICAubWFwKCh1bndyYXBwZWQpID0+IG5ldyBPdmVyc2NhbGVkVGlsZUlEKHVud3JhcHBlZC5jYW5vbmljYWwueiwgdW53cmFwcGVkLndyYXAsIHVud3JhcHBlZC5jYW5vbmljYWwueiwgdW53cmFwcGVkLmNhbm9uaWNhbC54LCB1bndyYXBwZWQuY2Fub25pY2FsLnkpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlkZWFsVGlsZUlEcyA9IHRyYW5zZm9ybS5jb3ZlcmluZ1RpbGVzKHtcbiAgICAgICAgICAgICAgICB0aWxlU2l6ZTogdGlsZVNpemUgfHwgdGhpcy5fc291cmNlLnRpbGVTaXplLFxuICAgICAgICAgICAgICAgIG1pbnpvb206IHRoaXMuX3NvdXJjZS5taW56b29tLFxuICAgICAgICAgICAgICAgIG1heHpvb206IHRoaXMuX3NvdXJjZS5tYXh6b29tLFxuICAgICAgICAgICAgICAgIHJvdW5kWm9vbTogdGhpcy5fc291cmNlLnJvdW5kWm9vbSAmJiAhdXBkYXRlRm9yVGVycmFpbixcbiAgICAgICAgICAgICAgICByZXBhcnNlT3ZlcnNjYWxlZDogdGhpcy5fc291cmNlLnJlcGFyc2VPdmVyc2NhbGVkLFxuICAgICAgICAgICAgICAgIGlzVGVycmFpbkRFTTogdGhpcy51c2VkRm9yVGVycmFpblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLl9zb3VyY2UuaGFzVGlsZSkge1xuICAgICAgICAgICAgICAgIGlkZWFsVGlsZUlEcyA9IGlkZWFsVGlsZUlEcy5maWx0ZXIoKGNvb3JkKSA9PiAodGhpcy5fc291cmNlLmhhc1RpbGU6IGFueSkoY29vcmQpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJldGFpbiBpcyBhIGxpc3Qgb2YgdGlsZXMgdGhhdCB3ZSBzaG91bGRuJ3QgZGVsZXRlLCBldmVuIGlmIHRoZXkgYXJlIG5vdFxuICAgICAgICAvLyB0aGUgbW9zdCBpZGVhbCB0aWxlIGZvciB0aGUgY3VycmVudCB2aWV3cG9ydC4gVGhpcyBtYXkgaW5jbHVkZSB0aWxlcyBsaWtlXG4gICAgICAgIC8vIHBhcmVudCBvciBjaGlsZCB0aWxlcyB0aGF0IGFyZSAqYWxyZWFkeSogbG9hZGVkLlxuICAgICAgICBjb25zdCByZXRhaW4gPSB0aGlzLl91cGRhdGVSZXRhaW5lZFRpbGVzKGlkZWFsVGlsZUlEcyk7XG5cbiAgICAgICAgaWYgKGlzUmFzdGVyVHlwZSh0aGlzLl9zb3VyY2UudHlwZSkgJiYgaWRlYWxUaWxlSURzLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICAgICAgY29uc3QgcGFyZW50c0ZvckZhZGluZzoge1tfOiBzdHJpbmcgfCBudW1iZXJdOiBPdmVyc2NhbGVkVGlsZUlEfSA9IHt9O1xuICAgICAgICAgICAgY29uc3QgZmFkaW5nVGlsZXMgPSB7fTtcbiAgICAgICAgICAgIGNvbnN0IGlkcyA9IE9iamVjdC5rZXlzKHJldGFpbik7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGlkIG9mIGlkcykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRpbGVJRCA9IHJldGFpbltpZF07XG4gICAgICAgICAgICAgICAgYXNzZXJ0KHRpbGVJRC5rZXkgPT09ICtpZCk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCB0aWxlID0gdGhpcy5fdGlsZXNbaWRdO1xuICAgICAgICAgICAgICAgIGlmICghdGlsZSB8fCAodGlsZS5mYWRlRW5kVGltZSAmJiB0aWxlLmZhZGVFbmRUaW1lIDw9IGJyb3dzZXIubm93KCkpKSBjb250aW51ZTtcblxuICAgICAgICAgICAgICAgIC8vIGlmIHRoZSB0aWxlIGlzIGxvYWRlZCBidXQgc3RpbGwgZmFkaW5nIGluLCBmaW5kIHBhcmVudHMgdG8gY3Jvc3MtZmFkZSB3aXRoIGl0XG4gICAgICAgICAgICAgICAgY29uc3QgcGFyZW50VGlsZSA9IHRoaXMuZmluZExvYWRlZFBhcmVudCh0aWxlSUQsIE1hdGgubWF4KHRpbGVJRC5vdmVyc2NhbGVkWiAtIFNvdXJjZUNhY2hlLm1heE92ZXJ6b29taW5nLCB0aGlzLl9zb3VyY2UubWluem9vbSkpO1xuICAgICAgICAgICAgICAgIGlmIChwYXJlbnRUaWxlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2FkZFRpbGUocGFyZW50VGlsZS50aWxlSUQpO1xuICAgICAgICAgICAgICAgICAgICBwYXJlbnRzRm9yRmFkaW5nW3BhcmVudFRpbGUudGlsZUlELmtleV0gPSBwYXJlbnRUaWxlLnRpbGVJRDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBmYWRpbmdUaWxlc1tpZF0gPSB0aWxlSUQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGZvciBjaGlsZHJlbiB0aWxlcyB3aXRoIHBhcmVudCB0aWxlcyBzdGlsbCBmYWRpbmcgaW4sXG4gICAgICAgICAgICAvLyByZXRhaW4gdGhlIGNoaWxkcmVuIHNvIHRoZSBwYXJlbnQgY2FuIGZhZGUgb24gdG9wXG4gICAgICAgICAgICBjb25zdCBtaW5ab29tID0gaWRlYWxUaWxlSURzW2lkZWFsVGlsZUlEcy5sZW5ndGggLSAxXS5vdmVyc2NhbGVkWjtcbiAgICAgICAgICAgIGZvciAoY29uc3QgaWQgaW4gdGhpcy5fdGlsZXMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjaGlsZFRpbGUgPSB0aGlzLl90aWxlc1tpZF07XG4gICAgICAgICAgICAgICAgaWYgKHJldGFpbltpZF0gfHwgIWNoaWxkVGlsZS5oYXNEYXRhKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgbGV0IHBhcmVudElEID0gY2hpbGRUaWxlLnRpbGVJRDtcbiAgICAgICAgICAgICAgICB3aGlsZSAocGFyZW50SUQub3ZlcnNjYWxlZFogPiBtaW5ab29tKSB7XG4gICAgICAgICAgICAgICAgICAgIHBhcmVudElEID0gcGFyZW50SUQuc2NhbGVkVG8ocGFyZW50SUQub3ZlcnNjYWxlZFogLSAxKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGlsZSA9IHRoaXMuX3RpbGVzW3BhcmVudElELmtleV07XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aWxlICYmIHRpbGUuaGFzRGF0YSgpICYmIGZhZGluZ1RpbGVzW3BhcmVudElELmtleV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldGFpbltpZF0gPSBjaGlsZFRpbGUudGlsZUlEO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAoY29uc3QgaWQgaW4gcGFyZW50c0ZvckZhZGluZykge1xuICAgICAgICAgICAgICAgIGlmICghcmV0YWluW2lkXSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBJZiBhIHRpbGUgaXMgb25seSBuZWVkZWQgZm9yIGZhZGluZywgbWFyayBpdCBhcyBjb3ZlcmVkIHNvIHRoYXQgaXQgaXNuJ3QgcmVuZGVyZWQgb24gaXQncyBvd24uXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2NvdmVyZWRUaWxlc1tpZF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICByZXRhaW5baWRdID0gcGFyZW50c0ZvckZhZGluZ1tpZF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChjb25zdCByZXRhaW5lZElkIGluIHJldGFpbikge1xuICAgICAgICAgICAgLy8gTWFrZSBzdXJlIHJldGFpbmVkIHRpbGVzIGFsd2F5cyBjbGVhciBhbnkgZXhpc3RpbmcgZmFkZSBob2xkc1xuICAgICAgICAgICAgLy8gc28gdGhhdCBpZiB0aGV5J3JlIHJlbW92ZWQgYWdhaW4gdGhlaXIgZmFkZSB0aW1lciBzdGFydHMgZnJlc2guXG4gICAgICAgICAgICB0aGlzLl90aWxlc1tyZXRhaW5lZElkXS5jbGVhckZhZGVIb2xkKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZW1vdmUgdGhlIHRpbGVzIHdlIGRvbid0IG5lZWQgYW55bW9yZS5cbiAgICAgICAgY29uc3QgcmVtb3ZlID0ga2V5c0RpZmZlcmVuY2UoKHRoaXMuX3RpbGVzOiBhbnkpLCAocmV0YWluOiBhbnkpKTtcbiAgICAgICAgZm9yIChjb25zdCB0aWxlSUQgb2YgcmVtb3ZlKSB7XG4gICAgICAgICAgICBjb25zdCB0aWxlID0gdGhpcy5fdGlsZXNbdGlsZUlEXTtcbiAgICAgICAgICAgIGlmICh0aWxlLmhhc1N5bWJvbEJ1Y2tldHMgJiYgIXRpbGUuaG9sZGluZ0ZvckZhZGUoKSkge1xuICAgICAgICAgICAgICAgIHRpbGUuc2V0SG9sZER1cmF0aW9uKHRoaXMubWFwLl9mYWRlRHVyYXRpb24pO1xuICAgICAgICAgICAgfSBlbHNlIGlmICghdGlsZS5oYXNTeW1ib2xCdWNrZXRzIHx8IHRpbGUuc3ltYm9sRmFkZUZpbmlzaGVkKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yZW1vdmVUaWxlKCt0aWxlSUQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ29uc3RydWN0IGEgY2FjaGUgb2YgbG9hZGVkIHBhcmVudHNcbiAgICAgICAgdGhpcy5fdXBkYXRlTG9hZGVkUGFyZW50VGlsZUNhY2hlKCk7XG5cbiAgICAgICAgaWYgKHRoaXMuX29ubHlTeW1ib2xzICYmIHRoaXMuX3NvdXJjZS5hZnRlclVwZGF0ZSkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlLmFmdGVyVXBkYXRlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZWxlYXNlU3ltYm9sRmFkZVRpbGVzKCkge1xuICAgICAgICBmb3IgKGNvbnN0IGlkIGluIHRoaXMuX3RpbGVzKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fdGlsZXNbaWRdLmhvbGRpbmdGb3JGYWRlKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yZW1vdmVUaWxlKCtpZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfdXBkYXRlUmV0YWluZWRUaWxlcyhpZGVhbFRpbGVJRHM6IEFycmF5PE92ZXJzY2FsZWRUaWxlSUQ+KToge1tfOiBudW1iZXIgfCBzdHJpbmddOiBPdmVyc2NhbGVkVGlsZUlEfSB7XG4gICAgICAgIGNvbnN0IHJldGFpbjoge1tfOiBudW1iZXIgfCBzdHJpbmddOiBPdmVyc2NhbGVkVGlsZUlEfSA9IHt9O1xuICAgICAgICBpZiAoaWRlYWxUaWxlSURzLmxlbmd0aCA9PT0gMCkgeyByZXR1cm4gcmV0YWluOyB9XG5cbiAgICAgICAgY29uc3QgY2hlY2tlZDoge1tfOiBudW1iZXIgfCBzdHJpbmddOiBib29sZWFuIH0gPSB7fTtcbiAgICAgICAgY29uc3QgbWluWm9vbSA9IGlkZWFsVGlsZUlEcy5yZWR1Y2UoKG1pbiwgaWQpID0+IE1hdGgubWluKG1pbiwgaWQub3ZlcnNjYWxlZFopLCBJbmZpbml0eSk7XG4gICAgICAgIGNvbnN0IG1heFpvb20gPSBpZGVhbFRpbGVJRHNbMF0ub3ZlcnNjYWxlZFo7XG4gICAgICAgIGFzc2VydChtaW5ab29tIDw9IG1heFpvb20pO1xuICAgICAgICBjb25zdCBtaW5Db3ZlcmluZ1pvb20gPSBNYXRoLm1heChtYXhab29tIC0gU291cmNlQ2FjaGUubWF4T3Zlcnpvb21pbmcsIHRoaXMuX3NvdXJjZS5taW56b29tKTtcbiAgICAgICAgY29uc3QgbWF4Q292ZXJpbmdab29tID0gTWF0aC5tYXgobWF4Wm9vbSArIFNvdXJjZUNhY2hlLm1heFVuZGVyem9vbWluZywgIHRoaXMuX3NvdXJjZS5taW56b29tKTtcblxuICAgICAgICBjb25zdCBtaXNzaW5nVGlsZXMgPSB7fTtcbiAgICAgICAgZm9yIChjb25zdCB0aWxlSUQgb2YgaWRlYWxUaWxlSURzKSB7XG4gICAgICAgICAgICBjb25zdCB0aWxlID0gdGhpcy5fYWRkVGlsZSh0aWxlSUQpO1xuXG4gICAgICAgICAgICAvLyByZXRhaW4gdGhlIHRpbGUgZXZlbiBpZiBpdCdzIG5vdCBsb2FkZWQgYmVjYXVzZSBpdCdzIGFuIGlkZWFsIHRpbGUuXG4gICAgICAgICAgICByZXRhaW5bdGlsZUlELmtleV0gPSB0aWxlSUQ7XG5cbiAgICAgICAgICAgIGlmICh0aWxlLmhhc0RhdGEoKSkgY29udGludWU7XG5cbiAgICAgICAgICAgIGlmIChtaW5ab29tIDwgdGhpcy5fc291cmNlLm1heHpvb20pIHtcbiAgICAgICAgICAgICAgICAvLyBzYXZlIG1pc3NpbmcgdGlsZXMgdGhhdCBwb3RlbnRpYWxseSBoYXZlIGxvYWRlZCBjaGlsZHJlblxuICAgICAgICAgICAgICAgIG1pc3NpbmdUaWxlc1t0aWxlSUQua2V5XSA9IHRpbGVJRDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHJldGFpbiBhbnkgbG9hZGVkIGNoaWxkcmVuIG9mIGlkZWFsIHRpbGVzIHVwIHRvIG1heENvdmVyaW5nWm9vbVxuICAgICAgICB0aGlzLl9yZXRhaW5Mb2FkZWRDaGlsZHJlbihtaXNzaW5nVGlsZXMsIG1pblpvb20sIG1heENvdmVyaW5nWm9vbSwgcmV0YWluKTtcblxuICAgICAgICBmb3IgKGNvbnN0IHRpbGVJRCBvZiBpZGVhbFRpbGVJRHMpIHtcbiAgICAgICAgICAgIGxldCB0aWxlID0gdGhpcy5fdGlsZXNbdGlsZUlELmtleV07XG5cbiAgICAgICAgICAgIGlmICh0aWxlLmhhc0RhdGEoKSkgY29udGludWU7XG5cbiAgICAgICAgICAgIC8vIFRoZSB0aWxlIHdlIHJlcXVpcmUgaXMgbm90IHlldCBsb2FkZWQgb3IgZG9lcyBub3QgZXhpc3Q7XG4gICAgICAgICAgICAvLyBBdHRlbXB0IHRvIGZpbmQgY2hpbGRyZW4gdGhhdCBmdWxseSBjb3ZlciBpdC5cblxuICAgICAgICAgICAgaWYgKHRpbGVJRC5jYW5vbmljYWwueiA+PSB0aGlzLl9zb3VyY2UubWF4em9vbSkge1xuICAgICAgICAgICAgICAgIC8vIFdlJ3JlIGxvb2tpbmcgZm9yIGFuIG92ZXJ6b29tZWQgY2hpbGQgdGlsZS5cbiAgICAgICAgICAgICAgICBjb25zdCBjaGlsZENvb3JkID0gdGlsZUlELmNoaWxkcmVuKHRoaXMuX3NvdXJjZS5tYXh6b29tKVswXTtcbiAgICAgICAgICAgICAgICBjb25zdCBjaGlsZFRpbGUgPSB0aGlzLmdldFRpbGUoY2hpbGRDb29yZCk7XG4gICAgICAgICAgICAgICAgaWYgKCEhY2hpbGRUaWxlICYmIGNoaWxkVGlsZS5oYXNEYXRhKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0YWluW2NoaWxkQ29vcmQua2V5XSA9IGNoaWxkQ29vcmQ7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOyAvLyB0aWxlIGlzIGNvdmVyZWQgYnkgb3Zlcnpvb21lZCBjaGlsZFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgYWxsIDQgaW1tZWRpYXRlIGNoaWxkcmVuIGFyZSBsb2FkZWQgKGluIG90aGVyIHdvcmRzLCB0aGUgbWlzc2luZyBpZGVhbCB0aWxlIGlzIGNvdmVyZWQpXG4gICAgICAgICAgICAgICAgY29uc3QgY2hpbGRyZW4gPSB0aWxlSUQuY2hpbGRyZW4odGhpcy5fc291cmNlLm1heHpvb20pO1xuXG4gICAgICAgICAgICAgICAgaWYgKHJldGFpbltjaGlsZHJlblswXS5rZXldICYmXG4gICAgICAgICAgICAgICAgICAgIHJldGFpbltjaGlsZHJlblsxXS5rZXldICYmXG4gICAgICAgICAgICAgICAgICAgIHJldGFpbltjaGlsZHJlblsyXS5rZXldICYmXG4gICAgICAgICAgICAgICAgICAgIHJldGFpbltjaGlsZHJlblszXS5rZXldKSBjb250aW51ZTsgLy8gdGlsZSBpcyBjb3ZlcmVkIGJ5IGNoaWxkcmVuXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFdlIGNvdWxkbid0IGZpbmQgY2hpbGQgdGlsZXMgdGhhdCBlbnRpcmVseSBjb3ZlciB0aGUgaWRlYWwgdGlsZTsgbG9vayBmb3IgcGFyZW50cyBub3cuXG5cbiAgICAgICAgICAgIC8vIEFzIHdlIGFzY2VuZCB1cCB0aGUgdGlsZSBweXJhbWlkIG9mIHRoZSBpZGVhbCB0aWxlLCB3ZSBjaGVjayB3aGV0aGVyIHRoZSBwYXJlbnRcbiAgICAgICAgICAgIC8vIHRpbGUgaGFzIGJlZW4gcHJldmlvdXNseSByZXF1ZXN0ZWQgKGFuZCBlcnJvcmVkIGJlY2F1c2Ugd2Ugb25seSBsb29wIG92ZXIgdGlsZXMgd2l0aCBubyBkYXRhKVxuICAgICAgICAgICAgLy8gaW4gb3JkZXIgdG8gZGV0ZXJtaW5lIGlmIHdlIG5lZWQgdG8gcmVxdWVzdCBpdHMgcGFyZW50LlxuICAgICAgICAgICAgbGV0IHBhcmVudFdhc1JlcXVlc3RlZCA9IHRpbGUud2FzUmVxdWVzdGVkKCk7XG5cbiAgICAgICAgICAgIGZvciAobGV0IG92ZXJzY2FsZWRaID0gdGlsZUlELm92ZXJzY2FsZWRaIC0gMTsgb3ZlcnNjYWxlZFogPj0gbWluQ292ZXJpbmdab29tOyAtLW92ZXJzY2FsZWRaKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFyZW50SWQgPSB0aWxlSUQuc2NhbGVkVG8ob3ZlcnNjYWxlZFopO1xuXG4gICAgICAgICAgICAgICAgLy8gQnJlYWsgcGFyZW50IHRpbGUgYXNjZW50IGlmIHRoaXMgcm91dGUgaGFzIGJlZW4gcHJldmlvdXNseSBjaGVja2VkIGJ5IGFub3RoZXIgY2hpbGQuXG4gICAgICAgICAgICAgICAgaWYgKGNoZWNrZWRbcGFyZW50SWQua2V5XSkgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2hlY2tlZFtwYXJlbnRJZC5rZXldID0gdHJ1ZTtcblxuICAgICAgICAgICAgICAgIHRpbGUgPSB0aGlzLmdldFRpbGUocGFyZW50SWQpO1xuICAgICAgICAgICAgICAgIGlmICghdGlsZSAmJiBwYXJlbnRXYXNSZXF1ZXN0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGlsZSA9IHRoaXMuX2FkZFRpbGUocGFyZW50SWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodGlsZSkge1xuICAgICAgICAgICAgICAgICAgICByZXRhaW5bcGFyZW50SWQua2V5XSA9IHBhcmVudElkO1xuICAgICAgICAgICAgICAgICAgICAvLyBTYXZlIHRoZSBjdXJyZW50IHZhbHVlcywgc2luY2UgdGhleSdyZSB0aGUgcGFyZW50IG9mIHRoZSBuZXh0IGl0ZXJhdGlvblxuICAgICAgICAgICAgICAgICAgICAvLyBvZiB0aGUgcGFyZW50IHRpbGUgYXNjZW50IGxvb3AuXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudFdhc1JlcXVlc3RlZCA9IHRpbGUud2FzUmVxdWVzdGVkKCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aWxlLmhhc0RhdGEoKSkgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJldGFpbjtcbiAgICB9XG5cbiAgICBfdXBkYXRlTG9hZGVkUGFyZW50VGlsZUNhY2hlKCkge1xuICAgICAgICB0aGlzLl9sb2FkZWRQYXJlbnRUaWxlcyA9IHt9O1xuXG4gICAgICAgIGZvciAoY29uc3QgdGlsZUtleSBpbiB0aGlzLl90aWxlcykge1xuICAgICAgICAgICAgY29uc3QgcGF0aCA9IFtdO1xuICAgICAgICAgICAgbGV0IHBhcmVudFRpbGU6ID9UaWxlO1xuICAgICAgICAgICAgbGV0IGN1cnJlbnRJZCA9IHRoaXMuX3RpbGVzW3RpbGVLZXldLnRpbGVJRDtcblxuICAgICAgICAgICAgLy8gRmluZCB0aGUgY2xvc2VzdCBsb2FkZWQgYW5jZXN0b3IgYnkgdHJhdmVyc2luZyB0aGUgdGlsZSB0cmVlIHRvd2FyZHMgdGhlIHJvb3QgYW5kXG4gICAgICAgICAgICAvLyBjYWNoaW5nIHJlc3VsdHMgYWxvbmcgdGhlIHdheVxuICAgICAgICAgICAgd2hpbGUgKGN1cnJlbnRJZC5vdmVyc2NhbGVkWiA+IDApIHtcblxuICAgICAgICAgICAgICAgIC8vIERvIHdlIGhhdmUgYSBjYWNoZWQgcmVzdWx0IGZyb20gcHJldmlvdXMgdHJhdmVyc2Fscz9cbiAgICAgICAgICAgICAgICBpZiAoY3VycmVudElkLmtleSBpbiB0aGlzLl9sb2FkZWRQYXJlbnRUaWxlcykge1xuICAgICAgICAgICAgICAgICAgICBwYXJlbnRUaWxlID0gdGhpcy5fbG9hZGVkUGFyZW50VGlsZXNbY3VycmVudElkLmtleV07XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHBhdGgucHVzaChjdXJyZW50SWQua2V5KTtcblxuICAgICAgICAgICAgICAgIC8vIElzIHRoZSBwYXJlbnQgbG9hZGVkP1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcmVudElkID0gY3VycmVudElkLnNjYWxlZFRvKGN1cnJlbnRJZC5vdmVyc2NhbGVkWiAtIDEpO1xuICAgICAgICAgICAgICAgIHBhcmVudFRpbGUgPSB0aGlzLl9nZXRMb2FkZWRUaWxlKHBhcmVudElkKTtcbiAgICAgICAgICAgICAgICBpZiAocGFyZW50VGlsZSkge1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjdXJyZW50SWQgPSBwYXJlbnRJZDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ2FjaGUgdGhlIHJlc3VsdCBvZiB0aGlzIHRyYXZlcnNhbCB0byBhbGwgbmV3bHkgdmlzaXRlZCB0aWxlc1xuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgcGF0aCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRlZFBhcmVudFRpbGVzW2tleV0gPSBwYXJlbnRUaWxlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkIGEgdGlsZSwgZ2l2ZW4gaXRzIGNvb3JkaW5hdGUsIHRvIHRoZSBweXJhbWlkLlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgX2FkZFRpbGUodGlsZUlEOiBPdmVyc2NhbGVkVGlsZUlEKTogVGlsZSB7XG4gICAgICAgIGxldCB0aWxlOiA/VGlsZSA9IHRoaXMuX3RpbGVzW3RpbGVJRC5rZXldO1xuICAgICAgICBpZiAodGlsZSkgcmV0dXJuIHRpbGU7XG5cbiAgICAgICAgdGlsZSA9IHRoaXMuX2NhY2hlLmdldEFuZFJlbW92ZSh0aWxlSUQpO1xuICAgICAgICBpZiAodGlsZSkge1xuICAgICAgICAgICAgdGhpcy5fc2V0VGlsZVJlbG9hZFRpbWVyKHRpbGVJRC5rZXksIHRpbGUpO1xuICAgICAgICAgICAgLy8gc2V0IHRoZSB0aWxlSUQgYmVjYXVzZSB0aGUgY2FjaGVkIHRpbGUgY291bGQgaGF2ZSBoYWQgYSBkaWZmZXJlbnQgd3JhcCB2YWx1ZVxuICAgICAgICAgICAgdGlsZS50aWxlSUQgPSB0aWxlSUQ7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5pbml0aWFsaXplVGlsZVN0YXRlKHRpbGUsIHRoaXMubWFwID8gdGhpcy5tYXAucGFpbnRlciA6IG51bGwpO1xuICAgICAgICAgICAgaWYgKHRoaXMuX2NhY2hlVGltZXJzW3RpbGVJRC5rZXldKSB7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuX2NhY2hlVGltZXJzW3RpbGVJRC5rZXldKTtcbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5fY2FjaGVUaW1lcnNbdGlsZUlELmtleV07XG4gICAgICAgICAgICAgICAgdGhpcy5fc2V0VGlsZVJlbG9hZFRpbWVyKHRpbGVJRC5rZXksIHRpbGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY2FjaGVkID0gQm9vbGVhbih0aWxlKTtcbiAgICAgICAgaWYgKCFjYWNoZWQpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhaW50ZXIgPSB0aGlzLm1hcCA/IHRoaXMubWFwLnBhaW50ZXIgOiBudWxsO1xuICAgICAgICAgICAgdGlsZSA9IG5ldyBUaWxlKHRpbGVJRCwgdGhpcy5fc291cmNlLnRpbGVTaXplICogdGlsZUlELm92ZXJzY2FsZUZhY3RvcigpLCB0aGlzLnRyYW5zZm9ybS50aWxlWm9vbSwgcGFpbnRlciwgdGhpcy5faXNSYXN0ZXIpO1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgdGhpcy5fbG9hZFRpbGUodGlsZSwgdGhpcy5fdGlsZUxvYWRlZC5iaW5kKHRoaXMsIHRpbGUsIHRpbGVJRC5rZXksIHRpbGUuc3RhdGUpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEltcG9zc2libGUsIGJ1dCBzaWxlbmNlIGZsb3cuXG4gICAgICAgIGlmICghdGlsZSkgcmV0dXJuIChudWxsOiBhbnkpO1xuXG4gICAgICAgIHRpbGUudXNlcysrO1xuICAgICAgICB0aGlzLl90aWxlc1t0aWxlSUQua2V5XSA9IHRpbGU7XG4gICAgICAgIGlmICghY2FjaGVkKSB0aGlzLl9zb3VyY2UuZmlyZShuZXcgRXZlbnQoJ2RhdGFsb2FkaW5nJywge3RpbGUsIGNvb3JkOiB0aWxlLnRpbGVJRCwgZGF0YVR5cGU6ICdzb3VyY2UnfSkpO1xuXG4gICAgICAgIHJldHVybiB0aWxlO1xuICAgIH1cblxuICAgIF9zZXRUaWxlUmVsb2FkVGltZXIoaWQ6IG51bWJlciwgdGlsZTogVGlsZSkge1xuICAgICAgICBpZiAoaWQgaW4gdGhpcy5fdGltZXJzKSB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5fdGltZXJzW2lkXSk7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5fdGltZXJzW2lkXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGV4cGlyeVRpbWVvdXQgPSB0aWxlLmdldEV4cGlyeVRpbWVvdXQoKTtcbiAgICAgICAgaWYgKGV4cGlyeVRpbWVvdXQpIHtcbiAgICAgICAgICAgIHRoaXMuX3RpbWVyc1tpZF0gPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yZWxvYWRUaWxlKGlkLCAnZXhwaXJlZCcpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl90aW1lcnNbaWRdO1xuICAgICAgICAgICAgfSwgZXhwaXJ5VGltZW91dCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSB0aWxlLCBnaXZlbiBpdHMgaWQsIGZyb20gdGhlIHB5cmFtaWRcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF9yZW1vdmVUaWxlKGlkOiBudW1iZXIpIHtcbiAgICAgICAgY29uc3QgdGlsZSA9IHRoaXMuX3RpbGVzW2lkXTtcbiAgICAgICAgaWYgKCF0aWxlKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIHRpbGUudXNlcy0tO1xuICAgICAgICBkZWxldGUgdGhpcy5fdGlsZXNbaWRdO1xuICAgICAgICBpZiAodGhpcy5fdGltZXJzW2lkXSkge1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVyc1tpZF0pO1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuX3RpbWVyc1tpZF07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGlsZS51c2VzID4gMClcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBpZiAodGlsZS5oYXNEYXRhKCkgJiYgdGlsZS5zdGF0ZSAhPT0gJ3JlbG9hZGluZycpIHtcbiAgICAgICAgICAgIHRoaXMuX2NhY2hlLmFkZCh0aWxlLnRpbGVJRCwgdGlsZSwgdGlsZS5nZXRFeHBpcnlUaW1lb3V0KCkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGlsZS5hYm9ydGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuX2Fib3J0VGlsZSh0aWxlKTtcbiAgICAgICAgICAgIHRoaXMuX3VubG9hZFRpbGUodGlsZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYWxsIHRpbGVzIGZyb20gdGhpcyBweXJhbWlkLlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgY2xlYXJUaWxlcygpIHtcbiAgICAgICAgdGhpcy5fc2hvdWxkUmVsb2FkT25SZXN1bWUgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fcGF1c2VkID0gZmFsc2U7XG5cbiAgICAgICAgZm9yIChjb25zdCBpZCBpbiB0aGlzLl90aWxlcylcbiAgICAgICAgICAgIHRoaXMuX3JlbW92ZVRpbGUoK2lkKTtcblxuICAgICAgICBpZiAodGhpcy5fc291cmNlLl9jbGVhcikgdGhpcy5fc291cmNlLl9jbGVhcigpO1xuXG4gICAgICAgIHRoaXMuX2NhY2hlLnJlc2V0KCk7XG5cbiAgICAgICAgaWYgKHRoaXMubWFwICYmIHRoaXMudXNlZEZvclRlcnJhaW4gJiYgdGhpcy5tYXAucGFpbnRlci50ZXJyYWluKSB7XG4gICAgICAgICAgICB0aGlzLm1hcC5wYWludGVyLnRlcnJhaW4ucmVzZXRUaWxlTG9va3VwQ2FjaGUodGhpcy5pZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWFyY2ggdGhyb3VnaCBvdXIgY3VycmVudCB0aWxlcyBhbmQgYXR0ZW1wdCB0byBmaW5kIHRoZSB0aWxlcyB0aGF0IGNvdmVyIHRoZSBnaXZlbiBgcXVlcnlHZW9tZXRyeWAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1F1ZXJ5R2VvbWV0cnl9IHF1ZXJ5R2VvbWV0cnlcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFt2aXN1YWxpemVRdWVyeUdlb21ldHJ5PWZhbHNlXVxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gdXNlM0RRdWVyeVxuICAgICAqIEByZXR1cm5zXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICB0aWxlc0luKHF1ZXJ5R2VvbWV0cnk6IFF1ZXJ5R2VvbWV0cnksIHVzZTNEUXVlcnk6IGJvb2xlYW4sIHZpc3VhbGl6ZVF1ZXJ5R2VvbWV0cnk6IGJvb2xlYW4pOiBUaWxlc3BhY2VRdWVyeUdlb21ldHJ5W10ge1xuICAgICAgICBjb25zdCB0aWxlUmVzdWx0cyA9IFtdO1xuXG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IHRoaXMudHJhbnNmb3JtO1xuICAgICAgICBpZiAoIXRyYW5zZm9ybSkgcmV0dXJuIHRpbGVSZXN1bHRzO1xuXG4gICAgICAgIGNvbnN0IGlzR2xvYmUgPSB0cmFuc2Zvcm0ucHJvamVjdGlvbi5uYW1lID09PSAnZ2xvYmUnO1xuICAgICAgICBjb25zdCBjZW50ZXJYID0gbWVyY2F0b3JYZnJvbUxuZyh0cmFuc2Zvcm0uY2VudGVyLmxuZyk7XG5cbiAgICAgICAgZm9yIChjb25zdCB0aWxlSUQgaW4gdGhpcy5fdGlsZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHRpbGUgPSB0aGlzLl90aWxlc1t0aWxlSURdO1xuICAgICAgICAgICAgaWYgKHZpc3VhbGl6ZVF1ZXJ5R2VvbWV0cnkpIHtcbiAgICAgICAgICAgICAgICB0aWxlLmNsZWFyUXVlcnlEZWJ1Z1ZpeigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRpbGUuaG9sZGluZ0ZvckZhZGUoKSkge1xuICAgICAgICAgICAgICAgIC8vIFRpbGVzIGhlbGQgZm9yIGZhZGluZyBhcmUgY292ZXJlZCBieSB0aWxlcyB0aGF0IGFyZSBjbG9zZXIgdG8gaWRlYWxcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQW4gYXJyYXkgb2Ygd3JhcCB2YWx1ZXMgZm9yIHRoZSB0aWxlIFstMSwgMCwgMV0uIFRoZSBkZWZhdWx0IHZhbHVlIGlzIDAgYnV0IC0xIG9yIDEgd3JhcHBpbmdcbiAgICAgICAgICAgIC8vIG1pZ2h0IGJlIHJlcXVpcmVkIGluIGdsb2JlIHZpZXcgZHVlIHRvIGdsb2JlJ3Mgc3VyZmFjZSBiZWluZyBjb250aW51b3VzLlxuICAgICAgICAgICAgbGV0IHRpbGVzVG9DaGVjaztcblxuICAgICAgICAgICAgaWYgKGlzR2xvYmUpIHtcbiAgICAgICAgICAgICAgICAvLyBDb21wYXJlIGRpc3RhbmNlcyB0byBjb3BpZXMgb2YgdGhlIHRpbGUgdG8gc2VlIGlmIGEgd3JhcHBlZCBvbmUgc2hvdWxkIGJlIHVzZWQuXG4gICAgICAgICAgICAgICAgY29uc3QgaWQgPSB0aWxlLnRpbGVJRC5jYW5vbmljYWw7XG4gICAgICAgICAgICAgICAgYXNzZXJ0KHRpbGUudGlsZUlELndyYXAgPT09IDApO1xuXG4gICAgICAgICAgICAgICAgaWYgKGlkLnogPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUmVuZGVyIHRoZSB6b29tIGxldmVsIDAgdGlsZSB0d2ljZSBhcyB0aGUgcXVlcnkgcG9seWdvbiBtaWdodCBzcGFuIG92ZXIgdGhlIGFudGltZXJpZGlhblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBkaXN0YW5jZXMgPSBbXG4gICAgICAgICAgICAgICAgICAgICAgICBNYXRoLmFicyhjbGFtcChjZW50ZXJYLCAuLi50aWxlQm91bmRzWChpZCwgLTEpKSAtIGNlbnRlclgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgTWF0aC5hYnMoY2xhbXAoY2VudGVyWCwgLi4udGlsZUJvdW5kc1goaWQsIDEpKSAtIGNlbnRlclgpXG4gICAgICAgICAgICAgICAgICAgIF07XG5cbiAgICAgICAgICAgICAgICAgICAgdGlsZXNUb0NoZWNrID0gWzAsIGRpc3RhbmNlcy5pbmRleE9mKE1hdGgubWluKC4uLmRpc3RhbmNlcykpICogMiAtIDFdO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGRpc3RhbmNlcyA9IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIE1hdGguYWJzKGNsYW1wKGNlbnRlclgsIC4uLnRpbGVCb3VuZHNYKGlkLCAtMSkpIC0gY2VudGVyWCksXG4gICAgICAgICAgICAgICAgICAgICAgICBNYXRoLmFicyhjbGFtcChjZW50ZXJYLCAuLi50aWxlQm91bmRzWChpZCwgMCkpIC0gY2VudGVyWCksXG4gICAgICAgICAgICAgICAgICAgICAgICBNYXRoLmFicyhjbGFtcChjZW50ZXJYLCAuLi50aWxlQm91bmRzWChpZCwgMSkpIC0gY2VudGVyWClcbiAgICAgICAgICAgICAgICAgICAgXTtcblxuICAgICAgICAgICAgICAgICAgICB0aWxlc1RvQ2hlY2sgPSBbZGlzdGFuY2VzLmluZGV4T2YoTWF0aC5taW4oLi4uZGlzdGFuY2VzKSkgLSAxXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRpbGVzVG9DaGVjayA9IFswXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9yIChjb25zdCB3cmFwIG9mIHRpbGVzVG9DaGVjaykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRpbGVSZXN1bHQgPSBxdWVyeUdlb21ldHJ5LmNvbnRhaW5zVGlsZSh0aWxlLCB0cmFuc2Zvcm0sIHVzZTNEUXVlcnksIHdyYXApO1xuICAgICAgICAgICAgICAgIGlmICh0aWxlUmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRpbGVSZXN1bHRzLnB1c2godGlsZVJlc3VsdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aWxlUmVzdWx0cztcbiAgICB9XG5cbiAgICBnZXRWaXNpYmxlQ29vcmRpbmF0ZXMoc3ltYm9sTGF5ZXI/OiBib29sZWFuKTogQXJyYXk8T3ZlcnNjYWxlZFRpbGVJRD4ge1xuICAgICAgICBjb25zdCBjb29yZHMgPSB0aGlzLmdldFJlbmRlcmFibGVJZHMoc3ltYm9sTGF5ZXIpLm1hcCgoaWQpID0+IHRoaXMuX3RpbGVzW2lkXS50aWxlSUQpO1xuICAgICAgICBmb3IgKGNvbnN0IGNvb3JkIG9mIGNvb3Jkcykge1xuICAgICAgICAgICAgY29vcmQucHJvak1hdHJpeCA9IHRoaXMudHJhbnNmb3JtLmNhbGN1bGF0ZVByb2pNYXRyaXgoY29vcmQudG9VbndyYXBwZWQoKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNvb3JkcztcbiAgICB9XG5cbiAgICBoYXNUcmFuc2l0aW9uKCk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAodGhpcy5fc291cmNlLmhhc1RyYW5zaXRpb24oKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNSYXN0ZXJUeXBlKHRoaXMuX3NvdXJjZS50eXBlKSkge1xuICAgICAgICAgICAgZm9yIChjb25zdCBpZCBpbiB0aGlzLl90aWxlcykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRpbGUgPSB0aGlzLl90aWxlc1tpZF07XG4gICAgICAgICAgICAgICAgaWYgKHRpbGUuZmFkZUVuZFRpbWUgIT09IHVuZGVmaW5lZCAmJiB0aWxlLmZhZGVFbmRUaW1lID49IGJyb3dzZXIubm93KCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgdmFsdWUgb2YgYSBwYXJ0aWN1bGFyIHN0YXRlIGZvciBhIGZlYXR1cmVcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHNldEZlYXR1cmVTdGF0ZShzb3VyY2VMYXllcj86IHN0cmluZywgZmVhdHVyZUlkOiBudW1iZXIgfCBzdHJpbmcsIHN0YXRlOiBPYmplY3QpIHtcbiAgICAgICAgc291cmNlTGF5ZXIgPSBzb3VyY2VMYXllciB8fCAnX2dlb2pzb25UaWxlTGF5ZXInO1xuICAgICAgICB0aGlzLl9zdGF0ZS51cGRhdGVTdGF0ZShzb3VyY2VMYXllciwgZmVhdHVyZUlkLCBzdGF0ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVzZXRzIHRoZSB2YWx1ZSBvZiBhIHBhcnRpY3VsYXIgc3RhdGUga2V5IGZvciBhIGZlYXR1cmVcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHJlbW92ZUZlYXR1cmVTdGF0ZShzb3VyY2VMYXllcj86IHN0cmluZywgZmVhdHVyZUlkPzogbnVtYmVyIHwgc3RyaW5nLCBrZXk/OiBzdHJpbmcpIHtcbiAgICAgICAgc291cmNlTGF5ZXIgPSBzb3VyY2VMYXllciB8fCAnX2dlb2pzb25UaWxlTGF5ZXInO1xuICAgICAgICB0aGlzLl9zdGF0ZS5yZW1vdmVGZWF0dXJlU3RhdGUoc291cmNlTGF5ZXIsIGZlYXR1cmVJZCwga2V5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGVudGlyZSBzdGF0ZSBvYmplY3QgZm9yIGEgZmVhdHVyZVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgZ2V0RmVhdHVyZVN0YXRlKHNvdXJjZUxheWVyPzogc3RyaW5nLCBmZWF0dXJlSWQ6IG51bWJlciB8IHN0cmluZyk6IEZlYXR1cmVTdGF0ZXMge1xuICAgICAgICBzb3VyY2VMYXllciA9IHNvdXJjZUxheWVyIHx8ICdfZ2VvanNvblRpbGVMYXllcic7XG4gICAgICAgIHJldHVybiB0aGlzLl9zdGF0ZS5nZXRTdGF0ZShzb3VyY2VMYXllciwgZmVhdHVyZUlkKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBzZXQgb2Yga2V5cyB0aGF0IHRoZSB0aWxlIGRlcGVuZHMgb24uIFRoaXMgYWxsb3dzIHRpbGVzIHRvXG4gICAgICogYmUgcmVsb2FkZWQgd2hlbiB0aGVpciBkZXBlbmRlbmNpZXMgY2hhbmdlLlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc2V0RGVwZW5kZW5jaWVzKHRpbGVLZXk6IG51bWJlciwgbmFtZXNwYWNlOiBzdHJpbmcsIGRlcGVuZGVuY2llczogQXJyYXk8c3RyaW5nPikge1xuICAgICAgICBjb25zdCB0aWxlID0gdGhpcy5fdGlsZXNbdGlsZUtleV07XG4gICAgICAgIGlmICh0aWxlKSB7XG4gICAgICAgICAgICB0aWxlLnNldERlcGVuZGVuY2llcyhuYW1lc3BhY2UsIGRlcGVuZGVuY2llcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZWxvYWRzIGFsbCB0aWxlcyB0aGF0IGRlcGVuZCBvbiB0aGUgZ2l2ZW4ga2V5cy5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHJlbG9hZFRpbGVzRm9yRGVwZW5kZW5jaWVzKG5hbWVzcGFjZXM6IEFycmF5PHN0cmluZz4sIGtleXM6IEFycmF5PHN0cmluZz4pIHtcbiAgICAgICAgZm9yIChjb25zdCBpZCBpbiB0aGlzLl90aWxlcykge1xuICAgICAgICAgICAgY29uc3QgdGlsZSA9IHRoaXMuX3RpbGVzW2lkXTtcbiAgICAgICAgICAgIGlmICh0aWxlLmhhc0RlcGVuZGVuY3kobmFtZXNwYWNlcywga2V5cykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yZWxvYWRUaWxlKCtpZCwgJ3JlbG9hZGluZycpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2NhY2hlLmZpbHRlcih0aWxlID0+ICF0aWxlLmhhc0RlcGVuZGVuY3kobmFtZXNwYWNlcywga2V5cykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFByZWxvYWRzIGFsbCB0aWxlcyB0aGF0IHdpbGwgYmUgcmVxdWVzdGVkIGZvciBvbmUgb3IgYSBzZXJpZXMgb2YgdHJhbnNmb3JtYXRpb25zXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYHRoaXNgIHwgUHJvbWlzZS5cbiAgICAgKi9cbiAgICBfcHJlbG9hZFRpbGVzKHRyYW5zZm9ybTogVHJhbnNmb3JtIHwgQXJyYXk8VHJhbnNmb3JtPiwgY2FsbGJhY2s6IENhbGxiYWNrPGFueT4pIHtcbiAgICAgICAgaWYgKCF0aGlzLl9zb3VyY2VMb2FkZWQpIHtcbiAgICAgICAgICAgIGNvbnN0IHdhaXRVbnRpbFNvdXJjZUxvYWRlZCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX3NvdXJjZUxvYWRlZCkgcmV0dXJuO1xuICAgICAgICAgICAgICAgIHRoaXMuX3NvdXJjZS5vZmYoJ2RhdGEnLCB3YWl0VW50aWxTb3VyY2VMb2FkZWQpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3ByZWxvYWRUaWxlcyh0cmFuc2Zvcm0sIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMuX3NvdXJjZS5vbignZGF0YScsIHdhaXRVbnRpbFNvdXJjZUxvYWRlZCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjb3ZlcmluZ1RpbGVzSURzOiBNYXA8bnVtYmVyLCBPdmVyc2NhbGVkVGlsZUlEPiA9IG5ldyBNYXAoKTtcbiAgICAgICAgY29uc3QgdHJhbnNmb3JtcyA9IEFycmF5LmlzQXJyYXkodHJhbnNmb3JtKSA/IHRyYW5zZm9ybSA6IFt0cmFuc2Zvcm1dO1xuXG4gICAgICAgIGNvbnN0IHRlcnJhaW4gPSB0aGlzLm1hcC5wYWludGVyLnRlcnJhaW47XG4gICAgICAgIGNvbnN0IHRpbGVTaXplID0gdGhpcy51c2VkRm9yVGVycmFpbiAmJiB0ZXJyYWluID8gdGVycmFpbi5nZXRTY2FsZWREZW1UaWxlU2l6ZSgpIDogdGhpcy5fc291cmNlLnRpbGVTaXplO1xuXG4gICAgICAgIGZvciAoY29uc3QgdHIgb2YgdHJhbnNmb3Jtcykge1xuICAgICAgICAgICAgY29uc3QgdGlsZUlEcyA9IHRyLmNvdmVyaW5nVGlsZXMoe1xuICAgICAgICAgICAgICAgIHRpbGVTaXplLFxuICAgICAgICAgICAgICAgIG1pbnpvb206IHRoaXMuX3NvdXJjZS5taW56b29tLFxuICAgICAgICAgICAgICAgIG1heHpvb206IHRoaXMuX3NvdXJjZS5tYXh6b29tLFxuICAgICAgICAgICAgICAgIHJvdW5kWm9vbTogdGhpcy5fc291cmNlLnJvdW5kWm9vbSAmJiAhdGhpcy51c2VkRm9yVGVycmFpbixcbiAgICAgICAgICAgICAgICByZXBhcnNlT3ZlcnNjYWxlZDogdGhpcy5fc291cmNlLnJlcGFyc2VPdmVyc2NhbGVkLFxuICAgICAgICAgICAgICAgIGlzVGVycmFpbkRFTTogdGhpcy51c2VkRm9yVGVycmFpblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGZvciAoY29uc3QgdGlsZUlEIG9mIHRpbGVJRHMpIHtcbiAgICAgICAgICAgICAgICBjb3ZlcmluZ1RpbGVzSURzLnNldCh0aWxlSUQua2V5LCB0aWxlSUQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy51c2VkRm9yVGVycmFpbikge1xuICAgICAgICAgICAgICAgIHRyLnVwZGF0ZUVsZXZhdGlvbihmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB0aWxlSURzID0gQXJyYXkuZnJvbShjb3ZlcmluZ1RpbGVzSURzLnZhbHVlcygpKTtcblxuICAgICAgICBhc3luY0FsbCh0aWxlSURzLCAodGlsZUlELCBkb25lKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0aWxlID0gbmV3IFRpbGUodGlsZUlELCB0aGlzLl9zb3VyY2UudGlsZVNpemUgKiB0aWxlSUQub3ZlcnNjYWxlRmFjdG9yKCksIHRoaXMudHJhbnNmb3JtLnRpbGVab29tLCB0aGlzLm1hcC5wYWludGVyLCB0aGlzLl9pc1Jhc3Rlcik7XG4gICAgICAgICAgICB0aGlzLl9sb2FkVGlsZSh0aWxlLCAoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX3NvdXJjZS50eXBlID09PSAncmFzdGVyLWRlbScgJiYgdGlsZS5kZW0pIHRoaXMuX2JhY2tmaWxsREVNKHRpbGUpO1xuICAgICAgICAgICAgICAgIGRvbmUoZXJyLCB0aWxlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCBjYWxsYmFjayk7XG4gICAgfVxufVxuXG5Tb3VyY2VDYWNoZS5tYXhPdmVyem9vbWluZyA9IDEwO1xuU291cmNlQ2FjaGUubWF4VW5kZXJ6b29taW5nID0gMztcblxuZnVuY3Rpb24gY29tcGFyZVRpbGVJZChhOiBPdmVyc2NhbGVkVGlsZUlELCBiOiBPdmVyc2NhbGVkVGlsZUlEKTogbnVtYmVyIHtcbiAgICAvLyBEaWZmZXJlbnQgY29waWVzIG9mIHRoZSB3b3JsZCBhcmUgc29ydGVkIGJhc2VkIG9uIHRoZWlyIGRpc3RhbmNlIHRvIHRoZSBjZW50ZXIuXG4gICAgLy8gV3JhcCB2YWx1ZXMgYXJlIGNvbnZlcnRlZCB0byB1bnNpZ25lZCBkaXN0YW5jZXMgYnkgcmVzZXJ2aW5nIG9kZCBudW1iZXIgZm9yIGNvcGllc1xuICAgIC8vIHdpdGggbmVnYXRpdmUgd3JhcCBhbmQgZXZlbiBudW1iZXJzIGZvciBjb3BpZXMgd2l0aCBwb3NpdGl2ZSB3cmFwLlxuICAgIGNvbnN0IGFXcmFwID0gTWF0aC5hYnMoYS53cmFwICogMikgLSArKGEud3JhcCA8IDApO1xuICAgIGNvbnN0IGJXcmFwID0gTWF0aC5hYnMoYi53cmFwICogMikgLSArKGIud3JhcCA8IDApO1xuICAgIHJldHVybiBhLm92ZXJzY2FsZWRaIC0gYi5vdmVyc2NhbGVkWiB8fCBiV3JhcCAtIGFXcmFwIHx8IGIuY2Fub25pY2FsLnkgLSBhLmNhbm9uaWNhbC55IHx8IGIuY2Fub25pY2FsLnggLSBhLmNhbm9uaWNhbC54O1xufVxuXG5mdW5jdGlvbiBpc1Jhc3RlclR5cGUodHlwZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHR5cGUgPT09ICdyYXN0ZXInIHx8IHR5cGUgPT09ICdpbWFnZScgfHwgdHlwZSA9PT0gJ3ZpZGVvJyB8fCB0eXBlID09PSAnY3VzdG9tJztcbn1cblxuZnVuY3Rpb24gdGlsZUJvdW5kc1goaWQ6IENhbm9uaWNhbFRpbGVJRCwgd3JhcDogbnVtYmVyKTogW251bWJlciwgbnVtYmVyXSB7XG4gICAgY29uc3QgdGlsZXMgPSAxIDw8IGlkLno7XG4gICAgcmV0dXJuIFtpZC54IC8gdGlsZXMgKyB3cmFwLCAoaWQueCArIDEpIC8gdGlsZXMgKyB3cmFwXTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgU291cmNlQ2FjaGU7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgTWVyY2F0b3JDb29yZGluYXRlLCB7bWVyY2F0b3JaZnJvbUFsdGl0dWRlfSBmcm9tICcuLi9nZW8vbWVyY2F0b3JfY29vcmRpbmF0ZS5qcyc7XG5pbXBvcnQgREVNRGF0YSBmcm9tICcuLi9kYXRhL2RlbV9kYXRhLmpzJztcbmltcG9ydCBTb3VyY2VDYWNoZSBmcm9tICcuLi9zb3VyY2Uvc291cmNlX2NhY2hlLmpzJztcbmltcG9ydCB7bnVtYmVyIGFzIGludGVycG9sYXRlfSBmcm9tICcuLi9zdHlsZS1zcGVjL3V0aWwvaW50ZXJwb2xhdGUuanMnO1xuaW1wb3J0IEVYVEVOVCBmcm9tICcuLi9kYXRhL2V4dGVudC5qcyc7XG5pbXBvcnQge3ZlYzN9IGZyb20gJ2dsLW1hdHJpeCc7XG5pbXBvcnQgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5pbXBvcnQge092ZXJzY2FsZWRUaWxlSUR9IGZyb20gJy4uL3NvdXJjZS90aWxlX2lkLmpzJztcblxuaW1wb3J0IHR5cGUgUHJvamVjdGlvbiBmcm9tICcuLi9nZW8vcHJvamVjdGlvbi9wcm9qZWN0aW9uLmpzJztcbmltcG9ydCB0eXBlIFRpbGUgZnJvbSAnLi4vc291cmNlL3RpbGUuanMnO1xuaW1wb3J0IHR5cGUge1ZlYzN9IGZyb20gJ2dsLW1hdHJpeCc7XG5cbi8qKlxuICogT3B0aW9ucyBjb21tb24gdG8ge0BsaW5rIE1hcCNxdWVyeVRlcnJhaW5FbGV2YXRpb259IGFuZCB7QGxpbmsgTWFwI3VucHJvamVjdDNkfSwgdXNlZCB0byBjb250cm9sIGhvdyBlbGV2YXRpb25cbiAqIGRhdGEgaXMgcmV0dXJuZWQuXG4gKlxuICogQHR5cGVkZWYge09iamVjdH0gRWxldmF0aW9uUXVlcnlPcHRpb25zXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGV4YWdnZXJhdGVkIFdoZW4gc2V0IHRvIGB0cnVlYCByZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgZWxldmF0aW9uIHdpdGggdGhlIHRlcnJhaW5zIGBleGFnZ2VyYXRpb25gIG9uIHRoZSBzdHlsZSBhbHJlYWR5IGFwcGxpZWQsXG4gKiB3aGVuYGZhbHNlYCBpdCByZXR1cm5zIHRoZSByYXcgdmFsdWUgb2YgdGhlIHVuZGVybHlpbmcgZGF0YSB3aXRob3V0IHN0eWxpbmcgYXBwbGllZC5cbiAqL1xuZXhwb3J0IHR5cGUgRWxldmF0aW9uUXVlcnlPcHRpb25zID0ge1xuICAgIGV4YWdnZXJhdGVkOiBib29sZWFuXG59O1xuXG4vKipcbiAqIFByb3ZpZGVzIGFjY2VzcyB0byBlbGV2YXRpb24gZGF0YSBmcm9tIHJhc3Rlci1kZW0gc291cmNlIGNhY2hlLlxuICovXG5leHBvcnQgY2xhc3MgRWxldmF0aW9uIHtcblxuICAgIC8qKlxuICAgICAqIEhlbHBlciB0aGF0IGNoZWNrcyB3aGV0aGVyIERFTSBkYXRhIGlzIGF2YWlsYWJsZSBhdCBhIGdpdmVuIG1lcmNhdG9yIGNvb3JkaW5hdGUuXG4gICAgICogQHBhcmFtIHtNZXJjYXRvckNvb3JkaW5hdGV9IHBvaW50IE1lcmNhdG9yIGNvb3JkaW5hdGUgb2YgdGhlIHBvaW50IHRvIGNoZWNrIGFnYWluc3QuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGRhdGEgaXMgYXZhaWxhYmxlIGF0IGBwb2ludGAsIGFuZCBgZmFsc2VgIG90aGVyd2lzZS5cbiAgICAgKi9cbiAgICBpc0RhdGFBdmFpbGFibGVBdFBvaW50KHBvaW50OiBNZXJjYXRvckNvb3JkaW5hdGUpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3Qgc291cmNlQ2FjaGUgPSB0aGlzLl9zb3VyY2UoKTtcbiAgICAgICAgaWYgKHRoaXMuaXNVc2luZ01vY2tTb3VyY2UoKSB8fCAhc291cmNlQ2FjaGUgfHwgcG9pbnQueSA8IDAuMCB8fCBwb2ludC55ID4gMS4wKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjYWNoZTogU291cmNlQ2FjaGUgPSBzb3VyY2VDYWNoZTtcbiAgICAgICAgY29uc3QgeiA9IGNhY2hlLmdldFNvdXJjZSgpLm1heHpvb207XG4gICAgICAgIGNvbnN0IHRpbGVzID0gMSA8PCB6O1xuICAgICAgICBjb25zdCB3cmFwID0gTWF0aC5mbG9vcihwb2ludC54KTtcbiAgICAgICAgY29uc3QgcHggPSBwb2ludC54IC0gd3JhcDtcbiAgICAgICAgY29uc3QgeCA9IE1hdGguZmxvb3IocHggKiB0aWxlcyk7XG4gICAgICAgIGNvbnN0IHkgPSBNYXRoLmZsb29yKHBvaW50LnkgKiB0aWxlcyk7XG4gICAgICAgIGNvbnN0IGRlbVRpbGUgPSB0aGlzLmZpbmRERU1UaWxlRm9yKG5ldyBPdmVyc2NhbGVkVGlsZUlEKHosIHdyYXAsIHosIHgsIHkpKTtcblxuICAgICAgICByZXR1cm4gISEoZGVtVGlsZSAmJiBkZW1UaWxlLmRlbSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGVscGVyIGFyb3VuZCBgZ2V0QXRQb2ludGAgdGhhdCBndWFyYW50ZWVzIHRoYXQgYSBudW1lcmljIHZhbHVlIGlzIHJldHVybmVkLlxuICAgICAqIEBwYXJhbSB7TWVyY2F0b3JDb29yZGluYXRlfSBwb2ludCBNZXJjYXRvciBjb29yZGluYXRlIG9mIHRoZSBwb2ludC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZGVmYXVsdElmTm90TG9hZGVkIFZhbHVlIHRoYXQgaXMgcmV0dXJuZWQgaWYgdGhlIGRlbSB0aWxlIG9mIHRoZSBwcm92aWRlZCBwb2ludCBpcyBub3QgbG9hZGVkLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IEFsdGl0dWRlIGluIG1ldGVycy5cbiAgICAgKi9cbiAgICBnZXRBdFBvaW50T3JaZXJvKHBvaW50OiBNZXJjYXRvckNvb3JkaW5hdGUsIGRlZmF1bHRJZk5vdExvYWRlZDogbnVtYmVyID0gMCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEF0UG9pbnQocG9pbnQsIGRlZmF1bHRJZk5vdExvYWRlZCkgfHwgMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBbHRpdHVkZSBhYm92ZSBzZWEgbGV2ZWwgaW4gbWV0ZXJzIGF0IHNwZWNpZmllZCBwb2ludC5cbiAgICAgKiBAcGFyYW0ge01lcmNhdG9yQ29vcmRpbmF0ZX0gcG9pbnQgTWVyY2F0b3IgY29vcmRpbmF0ZSBvZiB0aGUgcG9pbnQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGRlZmF1bHRJZk5vdExvYWRlZCBWYWx1ZSB0aGF0IGlzIHJldHVybmVkIGlmIHRoZSBERU0gdGlsZSBvZiB0aGUgcHJvdmlkZWQgcG9pbnQgaXMgbm90IGxvYWRlZC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGV4YWdnZXJhdGVkIGB0cnVlYCBpZiBzdHlsaW5nIGV4YWdnZXJhdGlvbiBzaG91bGQgYmUgYXBwbGllZCB0byB0aGUgcmVzdWx0aW5nIGVsZXZhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBBbHRpdHVkZSBpbiBtZXRlcnMuXG4gICAgICogSWYgdGhlcmUgaXMgbm8gbG9hZGVkIHRpbGUgdGhhdCBjYXJyaWVzIGluZm9ybWF0aW9uIGZvciB0aGUgcmVxdWVzdGVkXG4gICAgICogcG9pbnQgZWxldmF0aW9uLCByZXR1cm5zIGBkZWZhdWx0SWZOb3RMb2FkZWRgLlxuICAgICAqIERvZXNuJ3QgaW52b2tlIG5ldHdvcmsgcmVxdWVzdCB0byBmZXRjaCB0aGUgZGF0YS5cbiAgICAgKi9cbiAgICBnZXRBdFBvaW50KHBvaW50OiBNZXJjYXRvckNvb3JkaW5hdGUsIGRlZmF1bHRJZk5vdExvYWRlZDogP251bWJlciwgZXhhZ2dlcmF0ZWQ6IGJvb2xlYW4gPSB0cnVlKTogP251bWJlciB7XG4gICAgICAgIGlmICh0aGlzLmlzVXNpbmdNb2NrU291cmNlKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRm9yY2UgYSBjYXN0IHRvIG51bGwgZm9yIGJvdGggbnVsbCBhbmQgdW5kZWZpbmVkXG4gICAgICAgIGlmIChkZWZhdWx0SWZOb3RMb2FkZWQgPT0gbnVsbCkgZGVmYXVsdElmTm90TG9hZGVkID0gbnVsbDtcblxuICAgICAgICBjb25zdCBzcmMgPSB0aGlzLl9zb3VyY2UoKTtcbiAgICAgICAgaWYgKCFzcmMpIHJldHVybiBkZWZhdWx0SWZOb3RMb2FkZWQ7XG4gICAgICAgIGlmIChwb2ludC55IDwgMC4wIHx8IHBvaW50LnkgPiAxLjApIHtcbiAgICAgICAgICAgIHJldHVybiBkZWZhdWx0SWZOb3RMb2FkZWQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2FjaGU6IFNvdXJjZUNhY2hlID0gc3JjO1xuICAgICAgICBjb25zdCB6ID0gY2FjaGUuZ2V0U291cmNlKCkubWF4em9vbTtcbiAgICAgICAgY29uc3QgdGlsZXMgPSAxIDw8IHo7XG4gICAgICAgIGNvbnN0IHdyYXAgPSBNYXRoLmZsb29yKHBvaW50LngpO1xuICAgICAgICBjb25zdCBweCA9IHBvaW50LnggLSB3cmFwO1xuICAgICAgICBjb25zdCB0aWxlSUQgPSBuZXcgT3ZlcnNjYWxlZFRpbGVJRCh6LCB3cmFwLCB6LCBNYXRoLmZsb29yKHB4ICogdGlsZXMpLCBNYXRoLmZsb29yKHBvaW50LnkgKiB0aWxlcykpO1xuICAgICAgICBjb25zdCBkZW1UaWxlID0gdGhpcy5maW5kREVNVGlsZUZvcih0aWxlSUQpO1xuICAgICAgICBpZiAoIShkZW1UaWxlICYmIGRlbVRpbGUuZGVtKSkgeyByZXR1cm4gZGVmYXVsdElmTm90TG9hZGVkOyB9XG4gICAgICAgIGNvbnN0IGRlbTogREVNRGF0YSA9IGRlbVRpbGUuZGVtO1xuICAgICAgICBjb25zdCB0aWxlc0F0VGlsZVpvb20gPSAxIDw8IGRlbVRpbGUudGlsZUlELmNhbm9uaWNhbC56O1xuICAgICAgICBjb25zdCB4ID0gKHB4ICogdGlsZXNBdFRpbGVab29tIC0gZGVtVGlsZS50aWxlSUQuY2Fub25pY2FsLngpICogZGVtLmRpbTtcbiAgICAgICAgY29uc3QgeSA9IChwb2ludC55ICogdGlsZXNBdFRpbGVab29tIC0gZGVtVGlsZS50aWxlSUQuY2Fub25pY2FsLnkpICogZGVtLmRpbTtcbiAgICAgICAgY29uc3QgaSA9IE1hdGguZmxvb3IoeCk7XG4gICAgICAgIGNvbnN0IGogPSBNYXRoLmZsb29yKHkpO1xuICAgICAgICBjb25zdCBleGFnZ2VyYXRpb24gPSBleGFnZ2VyYXRlZCA/IHRoaXMuZXhhZ2dlcmF0aW9uKCkgOiAxO1xuXG4gICAgICAgIHJldHVybiBleGFnZ2VyYXRpb24gKiBpbnRlcnBvbGF0ZShcbiAgICAgICAgICAgIGludGVycG9sYXRlKGRlbS5nZXQoaSwgaiksIGRlbS5nZXQoaSwgaiArIDEpLCB5IC0gaiksXG4gICAgICAgICAgICBpbnRlcnBvbGF0ZShkZW0uZ2V0KGkgKyAxLCBqKSwgZGVtLmdldChpICsgMSwgaiArIDEpLCB5IC0gaiksXG4gICAgICAgICAgICB4IC0gaSk7XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiB4IGFuZCB5IGFyZSBvZmZzZXQgd2l0aGluIHRpbGUsIGluIDAgLi4gRVhURU5UIGNvb3JkaW5hdGUgc3BhY2UuXG4gICAgICovXG4gICAgZ2V0QXRUaWxlT2Zmc2V0KHRpbGVJRDogT3ZlcnNjYWxlZFRpbGVJRCwgeDogbnVtYmVyLCB5OiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCB0aWxlc0F0VGlsZVpvb20gPSAxIDw8IHRpbGVJRC5jYW5vbmljYWwuejtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXRQb2ludE9yWmVybyhuZXcgTWVyY2F0b3JDb29yZGluYXRlKFxuICAgICAgICAgICAgdGlsZUlELndyYXAgKyAodGlsZUlELmNhbm9uaWNhbC54ICsgeCAvIEVYVEVOVCkgLyB0aWxlc0F0VGlsZVpvb20sXG4gICAgICAgICAgICAodGlsZUlELmNhbm9uaWNhbC55ICsgeSAvIEVYVEVOVCkgLyB0aWxlc0F0VGlsZVpvb20pKTtcbiAgICB9XG5cbiAgICBnZXRBdFRpbGVPZmZzZXRGdW5jKHRpbGVJRDogT3ZlcnNjYWxlZFRpbGVJRCwgbGF0OiBudW1iZXIsIHdvcmxkU2l6ZTogbnVtYmVyLCBwcm9qZWN0aW9uOiBQcm9qZWN0aW9uKTogRnVuY3Rpb24ge1xuICAgICAgICByZXR1cm4gKHAgPT4ge1xuICAgICAgICAgICAgY29uc3QgZWxldmF0aW9uID0gdGhpcy5nZXRBdFRpbGVPZmZzZXQodGlsZUlELCBwLngsIHAueSk7XG4gICAgICAgICAgICBjb25zdCB1cFZlY3RvciA9IHByb2plY3Rpb24udXBWZWN0b3IodGlsZUlELmNhbm9uaWNhbCwgcC54LCBwLnkpO1xuICAgICAgICAgICAgY29uc3QgdXBWZWN0b3JTY2FsZSA9IHByb2plY3Rpb24udXBWZWN0b3JTY2FsZSh0aWxlSUQuY2Fub25pY2FsLCBsYXQsIHdvcmxkU2l6ZSkubWV0ZXJzVG9UaWxlO1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZSBjYW4ndCB5ZXQgcmVzb2x2ZSB0dXBsZSB2cyBhcnJheSBpbmNvbXBhdGliaWxpdGllc1xuICAgICAgICAgICAgdmVjMy5zY2FsZSh1cFZlY3RvciwgdXBWZWN0b3IsIGVsZXZhdGlvbiAqIHVwVmVjdG9yU2NhbGUpO1xuICAgICAgICAgICAgcmV0dXJuIHVwVmVjdG9yO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKlxuICAgICAqIEJhdGNoIGZldGNoIGZvciBtdWx0aXBsZSB0aWxlIHBvaW50czogcG9pbnRzIGhvbGRzIGlucHV0IGFuZCByZXR1cm4gdmFsdWU6XG4gICAgICogdmVjMydzIGl0ZW1zIG9uIGluZGV4IDAgYW5kIDEgZGVmaW5lIHggYW5kIHkgb2Zmc2V0IHdpdGhpbiB0aWxlLCBpbiBbMCAuLiBFWFRFTlRdXG4gICAgICogcmFuZ2UsIHJlc3BlY3RpdmVseS4gdmVjMyBpdGVtIGF0IGluZGV4IDIgaXMgb3V0cHV0IHZhbHVlLCBpbiBtZXRlcnMuXG4gICAgICogSWYgYSBERU0gdGlsZSB0aGF0IGNvdmVycyB0aWxlSUQgaXMgbG9hZGVkLCB0cnVlIGlzIHJldHVybmVkLCBvdGhlcndpc2UgZmFsc2UuXG4gICAgICogTmVhcmVzdCBmaWx0ZXIgc2FtcGxpbmcgb24gZGVtIGRhdGEgaXMgZG9uZSAobm8gaW50ZXJwb2xhdGlvbikuXG4gICAgICovXG4gICAgZ2V0Rm9yVGlsZVBvaW50cyh0aWxlSUQ6IE92ZXJzY2FsZWRUaWxlSUQsIHBvaW50czogQXJyYXk8VmVjMz4sIGludGVycG9sYXRlZDogP2Jvb2xlYW4sIHVzZURlbVRpbGU6ID9UaWxlKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICh0aGlzLmlzVXNpbmdNb2NrU291cmNlKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGhlbHBlciA9IERFTVNhbXBsZXIuY3JlYXRlKHRoaXMsIHRpbGVJRCwgdXNlRGVtVGlsZSk7XG4gICAgICAgIGlmICghaGVscGVyKSB7IHJldHVybiBmYWxzZTsgfVxuXG4gICAgICAgIHBvaW50cy5mb3JFYWNoKHAgPT4ge1xuICAgICAgICAgICAgcFsyXSA9IHRoaXMuZXhhZ2dlcmF0aW9uKCkgKiBoZWxwZXIuZ2V0RWxldmF0aW9uQXQocFswXSwgcFsxXSwgaW50ZXJwb2xhdGVkKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBlbGV2YXRpb24gbWluaW11bSBhbmQgbWF4aW11bSBmb3IgdGlsZSBpZGVudGlmaWVkIGJ5IGB0aWxlSURgLlxuICAgICAqIEBwYXJhbSB7T3ZlcnNjYWxlZFRpbGVJRH0gdGlsZUlEIFRoZSBgdGlsZUlkYCBpcyBhIHN1YiB0aWxlIChvciBjb3ZlcnMgdGhlIHNhbWUgc3BhY2UpIG9mIHRoZSBERU0gdGlsZSB3ZSByZWFkIHRoZSBpbmZvcm1hdGlvbiBmcm9tLlxuICAgICAqIEByZXR1cm5zIHs/e21pbjogbnVtYmVyLCBtYXg6IG51bWJlcn19IFRoZSBtaW4gYW5kIG1heCBlbGV2YXRpb24uXG4gICAgICovXG4gICAgZ2V0TWluTWF4Rm9yVGlsZSh0aWxlSUQ6IE92ZXJzY2FsZWRUaWxlSUQpOiA/e21pbjogbnVtYmVyLCBtYXg6IG51bWJlcn0ge1xuICAgICAgICBpZiAodGhpcy5pc1VzaW5nTW9ja1NvdXJjZSgpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGRlbVRpbGUgPSB0aGlzLmZpbmRERU1UaWxlRm9yKHRpbGVJRCk7XG5cbiAgICAgICAgaWYgKCEoZGVtVGlsZSAmJiBkZW1UaWxlLmRlbSkpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZGVtOiBERU1EYXRhID0gZGVtVGlsZS5kZW07XG4gICAgICAgIGNvbnN0IHRyZWUgPSBkZW0udHJlZTtcbiAgICAgICAgY29uc3QgZGVtVGlsZUlEID0gZGVtVGlsZS50aWxlSUQ7XG4gICAgICAgIGNvbnN0IHNjYWxlID0gMSA8PCB0aWxlSUQuY2Fub25pY2FsLnogLSBkZW1UaWxlSUQuY2Fub25pY2FsLno7XG4gICAgICAgIGxldCB4T2Zmc2V0ID0gdGlsZUlELmNhbm9uaWNhbC54IC8gc2NhbGUgLSBkZW1UaWxlSUQuY2Fub25pY2FsLng7XG4gICAgICAgIGxldCB5T2Zmc2V0ID0gdGlsZUlELmNhbm9uaWNhbC55IC8gc2NhbGUgLSBkZW1UaWxlSUQuY2Fub25pY2FsLnk7XG4gICAgICAgIGxldCBpbmRleCA9IDA7IC8vIFN0YXJ0IGZyb20gREVNIHRyZWUgcm9vdC5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aWxlSUQuY2Fub25pY2FsLnogLSBkZW1UaWxlSUQuY2Fub25pY2FsLno7IGkrKykge1xuICAgICAgICAgICAgaWYgKHRyZWUubGVhdmVzW2luZGV4XSkgYnJlYWs7XG4gICAgICAgICAgICB4T2Zmc2V0ICo9IDI7XG4gICAgICAgICAgICB5T2Zmc2V0ICo9IDI7XG4gICAgICAgICAgICBjb25zdCBjaGlsZE9mZnNldCA9IDIgKiBNYXRoLmZsb29yKHlPZmZzZXQpICsgTWF0aC5mbG9vcih4T2Zmc2V0KTtcbiAgICAgICAgICAgIGluZGV4ID0gdHJlZS5jaGlsZE9mZnNldHNbaW5kZXhdICsgY2hpbGRPZmZzZXQ7XG4gICAgICAgICAgICB4T2Zmc2V0ID0geE9mZnNldCAlIDE7XG4gICAgICAgICAgICB5T2Zmc2V0ID0geU9mZnNldCAlIDE7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHttaW46IHRoaXMuZXhhZ2dlcmF0aW9uKCkgKiB0cmVlLm1pbmltdW1zW2luZGV4XSwgbWF4OiB0aGlzLmV4YWdnZXJhdGlvbigpICogdHJlZS5tYXhpbXVtc1tpbmRleF19O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBlbGV2YXRpb24gbWluaW11bSBiZWxvdyBNU0wgZm9yIHRoZSB2aXNpYmxlIHRpbGVzLiBUaGlzIGZ1bmN0aW9uIGFjY291bnRzXG4gICAgICogZm9yIHRlcnJhaW4gZXhhZ2dlcmF0aW9uIGFuZCBpcyBjb25zZXJ2YXRpdmUgYmFzZWQgb24gdGhlIG1heGltdW0gREVNIGVycm9yLFxuICAgICAqIGRvIG5vdCBleHBlY3QgYWNjdXJhdGUgdmFsdWVzIGZyb20gdGhpcyBmdW5jdGlvbi5cbiAgICAgKiBJZiBubyBuZWdhdGl2ZSBlbGV2YXRpb24gaXMgdmlzaWJsZSwgdGhpcyBmdW5jdGlvbiByZXR1cm5zIDAuXG4gICAgICogQHJldHVybnMge251bWJlcn0gVGhlIG1pbiBlbGV2YXRpb24gYmVsb3cgc2VhIGxldmVsIG9mIGFsbCB2aXNpYmxlIHRpbGVzLlxuICAgICAqL1xuICAgIGdldE1pbkVsZXZhdGlvbkJlbG93TVNMKCk6IG51bWJlciB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignUHVyZSB2aXJ0dWFsIG1ldGhvZCBjYWxsZWQuJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGVyZm9ybXMgcmF5Y2FzdCBhZ2FpbnN0IHZpc2libGUgREVNIHRpbGVzIG9uIHRoZSBzY3JlZW4gYW5kIHJldHVybnMgdGhlIGRpc3RhbmNlIHRyYXZlbGxlZCBhbG9uZyB0aGUgcmF5LlxuICAgICAqIGB4YCAmIGB5YCBjb21wb25lbnRzIG9mIHRoZSBwb3NpdGlvbiBhcmUgZXhwZWN0ZWQgdG8gYmUgaW4gbm9ybWFsaXplZCBtZXJjYXRvciBjb29yZGluYXRlcyBbMCwgMV0gYW5kIHogaW4gbWV0ZXJzLlxuICAgICAqIEBwYXJhbSB7dmVjM30gcG9zaXRpb24gVGhlIHJheSBvcmlnaW4uXG4gICAgICogQHBhcmFtIHt2ZWMzfSBkaXIgVGhlIHJheSBkaXJlY3Rpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGV4YWdnZXJhdGlvbiBUaGUgdGVycmFpbiBleGFnZ2VyYXRpb24uXG4gICAgKi9cbiAgICByYXljYXN0KHBvc2l0aW9uOiBWZWMzLCBkaXI6IFZlYzMsIGV4YWdnZXJhdGlvbjogbnVtYmVyKTogP251bWJlciB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignUHVyZSB2aXJ0dWFsIG1ldGhvZCBjYWxsZWQuJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2l2ZW4gYSBwb2ludCBvbiBzY3JlZW4sIHJldHVybnMgM0QgTWVyY2F0b3JDb29yZGluYXRlIG9uIHRlcnJhaW4uXG4gICAgICogSGVscGVyIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYHJheWNhc3RgLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtQb2ludH0gc2NyZWVuUG9pbnQgU2NyZWVuIHBvaW50IGluIHBpeGVscyBpbiB0b3AtbGVmdCBvcmlnaW4gY29vcmRpbmF0ZSBzeXN0ZW0uXG4gICAgICogQHJldHVybnMge3ZlYzN9IElmIHRoZXJlIGlzIGludGVyc2VjdGlvbiB3aXRoIHRlcnJhaW4sIHJldHVybnMgM0QgTWVyY2F0b3JDb29yZGluYXRlJ3Mgb2ZcbiAgICAgKiBpbnRlcnNlY3Rpb24sIGFzIHZlYzMoeCwgeSwgeiksIG90aGVyd2lzZSBudWxsLlxuICAgICAqLyAvKiBlc2xpbnQgbm8tdW51c2VkLXZhcnM6IFtcImVycm9yXCIsIHsgXCJhcmdzXCI6IFwibm9uZVwiIH1dICovXG4gICAgcG9pbnRDb29yZGluYXRlKHNjcmVlblBvaW50OiBQb2ludCk6ID9WZWMzIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdQdXJlIHZpcnR1YWwgbWV0aG9kIGNhbGxlZC4nKTtcbiAgICB9XG5cbiAgICAvKlxuICAgICAqIEltcGxlbWVudGF0aW9uIHByb3ZpZGVzIFNvdXJjZUNhY2hlIG9mIHJhc3Rlci1kZW0gc291cmNlIHR5cGUgY2FjaGUsIGluXG4gICAgICogb3JkZXIgdG8gYWNjZXNzIGFscmVhZHkgbG9hZGVkIGNhY2hlZCB0aWxlcy5cbiAgICAgKi9cbiAgICBfc291cmNlKCk6ID9Tb3VyY2VDYWNoZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignUHVyZSB2aXJ0dWFsIG1ldGhvZCBjYWxsZWQuJyk7XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBXaGV0aGVyIHRoZSBTb3VyY2VDYWNoZSBpbnN0YW5jZSBpcyBhIG1vY2sgc291cmNlIGNhY2hlLlxuICAgICAqIFRoaXMgbW9jayBzb3VyY2UgY2FjaGUgaXMgdXNlZCBzb2xlbHkgZm9yIHRoZSBHbG9iZSBwcm9qZWN0aW9uIGFuZCB3aXRoIHRlcnJhaW4gZGlzYWJsZWQsXG4gICAgICogd2hlcmUgd2Ugb25seSB3YW50IHRvIGxldmVyYWdlIHRoZSBkcmFwaW5nIHJlbmRlcmluZyBwaXBlbGluZSB3aXRob3V0IGluY3VycmluZyBERU0tdGlsZVxuICAgICAqIGRvd25sb2FkIG92ZXJoZWFkLiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWZ1bCB0byBza2lwIERFTSBwcm9jZXNzaW5nIGFzIHRoZSBtb2NrIGRhdGEgc291cmNlXG4gICAgICogcGxhY2Vob2xkZXIgY29udGFpbnMgb25seSAwIGhlaWdodC5cbiAgICAgKi9cbiAgICBpc1VzaW5nTW9ja1NvdXJjZSgpOiBib29sZWFuIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdQdXJlIHZpcnR1YWwgbWV0aG9kIGNhbGxlZC4nKTtcbiAgICB9XG5cbiAgICAvKlxuICAgICAqIEEgbXVsdGlwbGllciBkZWZpbmVkIGJ5IHN0eWxlIGFzIHRlcnJhaW4gZXhhZ2dlcmF0aW9uLiBFbGV2YXRpb24gcHJvdmlkZWRcbiAgICAgKiBieSBnZXRYWFhYIG1ldGhvZHMgaXMgbXVsdGlwbGllZCBieSB0aGlzLlxuICAgICAqL1xuICAgIGV4YWdnZXJhdGlvbigpOiBudW1iZXIge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1B1cmUgdmlydHVhbCBtZXRob2QgY2FsbGVkLicpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIExvb2t1cCBERU0gdGlsZSB0aGF0IGNvcnJlc3BvbmRzIHRvIChjb3ZlcnMpIHRpbGVJRC5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIGZpbmRERU1UaWxlRm9yKF86IE92ZXJzY2FsZWRUaWxlSUQpOiA/VGlsZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignUHVyZSB2aXJ0dWFsIG1ldGhvZCBjYWxsZWQuJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IGxpc3Qgb2YgREVNIHRpbGVzIHVzZWQgdG8gcmVuZGVyIGN1cnJlbnQgZnJhbWUuXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBnZXQgdmlzaWJsZURlbVRpbGVzKCk6IEFycmF5PFRpbGU+IHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdHZXR0ZXIgbXVzdCBiZSBpbXBsZW1lbnRlZCBpbiBzdWJjbGFzcy4nKTtcbiAgICB9XG59XG5cbi8qKlxuICogSGVscGVyIGNsYXNzIGNvbXB1dGVzIGFuZCBjYWNoZXMgZGF0YSByZXF1aXJlZCB0byBsb29rdXAgZWxldmF0aW9uIG9mZnNldHMgYXQgdGhlIHRpbGUgbGV2ZWwuXG4gKi9cbmV4cG9ydCBjbGFzcyBERU1TYW1wbGVyIHtcbiAgICBfZGVtVGlsZTogVGlsZTtcbiAgICBfZGVtOiBERU1EYXRhO1xuICAgIF9zY2FsZTogbnVtYmVyO1xuICAgIF9vZmZzZXQ6IFtudW1iZXIsIG51bWJlcl07XG5cbiAgICBjb25zdHJ1Y3RvcihkZW1UaWxlOiBUaWxlLCBzY2FsZTogbnVtYmVyLCBvZmZzZXQ6IFtudW1iZXIsIG51bWJlcl0pIHtcbiAgICAgICAgdGhpcy5fZGVtVGlsZSA9IGRlbVRpbGU7XG4gICAgICAgIC8vIGRlbVRpbGUuZGVtIHdpbGwgYWx3YXlzIGV4aXN0IGJlY2F1c2UgdGhlIGZhY3RvcnkgbWV0aG9kIGBjcmVhdGVgIGRvZXMgdGhlIGNoZWNrXG4gICAgICAgIC8vIE1ha2UgZmxvdyBoYXBweSB3aXRoIGEgY2FzdCB0aHJvdWdoIGFueVxuICAgICAgICB0aGlzLl9kZW0gPSAoKCh0aGlzLl9kZW1UaWxlLmRlbSk6IGFueSk6IERFTURhdGEpO1xuICAgICAgICB0aGlzLl9zY2FsZSA9IHNjYWxlO1xuICAgICAgICB0aGlzLl9vZmZzZXQgPSBvZmZzZXQ7XG4gICAgfVxuXG4gICAgc3RhdGljIGNyZWF0ZShlbGV2YXRpb246IEVsZXZhdGlvbiwgdGlsZUlEOiBPdmVyc2NhbGVkVGlsZUlELCB1c2VEZW1UaWxlOiA/VGlsZSk6ID9ERU1TYW1wbGVyIHtcbiAgICAgICAgY29uc3QgZGVtVGlsZSA9IHVzZURlbVRpbGUgfHwgZWxldmF0aW9uLmZpbmRERU1UaWxlRm9yKHRpbGVJRCk7XG4gICAgICAgIGlmICghKGRlbVRpbGUgJiYgZGVtVGlsZS5kZW0pKSB7IHJldHVybjsgfVxuICAgICAgICBjb25zdCBkZW06IERFTURhdGEgPSBkZW1UaWxlLmRlbTtcbiAgICAgICAgY29uc3QgZGVtVGlsZUlEID0gZGVtVGlsZS50aWxlSUQ7XG4gICAgICAgIGNvbnN0IHNjYWxlID0gMSA8PCB0aWxlSUQuY2Fub25pY2FsLnogLSBkZW1UaWxlSUQuY2Fub25pY2FsLno7XG4gICAgICAgIGNvbnN0IHhPZmZzZXQgPSAodGlsZUlELmNhbm9uaWNhbC54IC8gc2NhbGUgLSBkZW1UaWxlSUQuY2Fub25pY2FsLngpICogZGVtLmRpbTtcbiAgICAgICAgY29uc3QgeU9mZnNldCA9ICh0aWxlSUQuY2Fub25pY2FsLnkgLyBzY2FsZSAtIGRlbVRpbGVJRC5jYW5vbmljYWwueSkgKiBkZW0uZGltO1xuICAgICAgICBjb25zdCBrID0gZGVtVGlsZS50aWxlU2l6ZSAvIEVYVEVOVCAvIHNjYWxlO1xuXG4gICAgICAgIHJldHVybiBuZXcgREVNU2FtcGxlcihkZW1UaWxlLCBrLCBbeE9mZnNldCwgeU9mZnNldF0pO1xuICAgIH1cblxuICAgIHRpbGVDb29yZFRvUGl4ZWwoeDogbnVtYmVyLCB5OiBudW1iZXIpOiBQb2ludCB7XG4gICAgICAgIGNvbnN0IHB4ID0geCAqIHRoaXMuX3NjYWxlICsgdGhpcy5fb2Zmc2V0WzBdO1xuICAgICAgICBjb25zdCBweSA9IHkgKiB0aGlzLl9zY2FsZSArIHRoaXMuX29mZnNldFsxXTtcbiAgICAgICAgY29uc3QgaSA9IE1hdGguZmxvb3IocHgpO1xuICAgICAgICBjb25zdCBqID0gTWF0aC5mbG9vcihweSk7XG4gICAgICAgIHJldHVybiBuZXcgUG9pbnQoaSwgaik7XG4gICAgfVxuXG4gICAgZ2V0RWxldmF0aW9uQXQoeDogbnVtYmVyLCB5OiBudW1iZXIsIGludGVycG9sYXRlZDogP2Jvb2xlYW4sIGNsYW1wVG9FZGdlOiA/Ym9vbGVhbik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IHB4ID0geCAqIHRoaXMuX3NjYWxlICsgdGhpcy5fb2Zmc2V0WzBdO1xuICAgICAgICBjb25zdCBweSA9IHkgKiB0aGlzLl9zY2FsZSArIHRoaXMuX29mZnNldFsxXTtcbiAgICAgICAgY29uc3QgaSA9IE1hdGguZmxvb3IocHgpO1xuICAgICAgICBjb25zdCBqID0gTWF0aC5mbG9vcihweSk7XG4gICAgICAgIGNvbnN0IGRlbSA9IHRoaXMuX2RlbTtcblxuICAgICAgICBjbGFtcFRvRWRnZSA9ICEhY2xhbXBUb0VkZ2U7XG5cbiAgICAgICAgcmV0dXJuIGludGVycG9sYXRlZCA/IGludGVycG9sYXRlKFxuICAgICAgICAgICAgaW50ZXJwb2xhdGUoZGVtLmdldChpLCBqLCBjbGFtcFRvRWRnZSksIGRlbS5nZXQoaSwgaiArIDEsIGNsYW1wVG9FZGdlKSwgcHkgLSBqKSxcbiAgICAgICAgICAgIGludGVycG9sYXRlKGRlbS5nZXQoaSArIDEsIGosIGNsYW1wVG9FZGdlKSwgZGVtLmdldChpICsgMSwgaiArIDEsIGNsYW1wVG9FZGdlKSwgcHkgLSBqKSxcbiAgICAgICAgICAgIHB4IC0gaSkgOlxuICAgICAgICAgICAgZGVtLmdldChpLCBqLCBjbGFtcFRvRWRnZSk7XG4gICAgfVxuXG4gICAgZ2V0RWxldmF0aW9uQXRQaXhlbCh4OiBudW1iZXIsIHk6IG51bWJlciwgY2xhbXBUb0VkZ2U6ID9ib29sZWFuKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlbS5nZXQoeCwgeSwgISFjbGFtcFRvRWRnZSk7XG4gICAgfVxuXG4gICAgZ2V0TWV0ZXJUb0RFTShsYXQ6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIHJldHVybiAoMSA8PCB0aGlzLl9kZW1UaWxlLnRpbGVJRC5jYW5vbmljYWwueikgKiBtZXJjYXRvclpmcm9tQWx0aXR1ZGUoMSwgbGF0KSAqIHRoaXMuX2RlbS5zdHJpZGU7XG4gICAgfVxufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IFBvaW50IGZyb20gJ0BtYXBib3gvcG9pbnQtZ2VvbWV0cnknO1xuXG5pbXBvcnQgbG9hZEdlb21ldHJ5IGZyb20gJy4vbG9hZF9nZW9tZXRyeS5qcyc7XG5pbXBvcnQgdG9FdmFsdWF0aW9uRmVhdHVyZSBmcm9tICcuL2V2YWx1YXRpb25fZmVhdHVyZS5qcyc7XG5pbXBvcnQgRVhURU5UIGZyb20gJy4vZXh0ZW50LmpzJztcbmltcG9ydCBmZWF0dXJlRmlsdGVyIGZyb20gJy4uL3N0eWxlLXNwZWMvZmVhdHVyZV9maWx0ZXIvaW5kZXguanMnO1xuaW1wb3J0IEdyaWQgZnJvbSAnZ3JpZC1pbmRleCc7XG5pbXBvcnQgRGljdGlvbmFyeUNvZGVyIGZyb20gJy4uL3V0aWwvZGljdGlvbmFyeV9jb2Rlci5qcyc7XG5pbXBvcnQge1ZlY3RvclRpbGV9IGZyb20gJ0BtYXBib3gvdmVjdG9yLXRpbGUnO1xuaW1wb3J0IFByb3RvYnVmIGZyb20gJ3BiZic7XG5pbXBvcnQgR2VvSlNPTkZlYXR1cmUgZnJvbSAnLi4vdXRpbC92ZWN0b3J0aWxlX3RvX2dlb2pzb24uanMnO1xuaW1wb3J0IHthcnJheXNJbnRlcnNlY3QsIG1hcE9iamVjdCwgZXh0ZW5kfSBmcm9tICcuLi91dGlsL3V0aWwuanMnO1xuaW1wb3J0IHtPdmVyc2NhbGVkVGlsZUlEfSBmcm9tICcuLi9zb3VyY2UvdGlsZV9pZC5qcyc7XG5pbXBvcnQge3JlZ2lzdGVyfSBmcm9tICcuLi91dGlsL3dlYl93b3JrZXJfdHJhbnNmZXIuanMnO1xuaW1wb3J0IEV2YWx1YXRpb25QYXJhbWV0ZXJzIGZyb20gJy4uL3N0eWxlL2V2YWx1YXRpb25fcGFyYW1ldGVycy5qcyc7XG5pbXBvcnQgU291cmNlRmVhdHVyZVN0YXRlIGZyb20gJy4uL3NvdXJjZS9zb3VyY2Vfc3RhdGUuanMnO1xuaW1wb3J0IHtwb2x5Z29uSW50ZXJzZWN0c0JveH0gZnJvbSAnLi4vdXRpbC9pbnRlcnNlY3Rpb25fdGVzdHMuanMnO1xuaW1wb3J0IHtQb3NzaWJseUV2YWx1YXRlZH0gZnJvbSAnLi4vc3R5bGUvcHJvcGVydGllcy5qcyc7XG5pbXBvcnQge0ZlYXR1cmVJbmRleEFycmF5fSBmcm9tICcuL2FycmF5X3R5cGVzLmpzJztcbmltcG9ydCB7REVNU2FtcGxlcn0gZnJvbSAnLi4vdGVycmFpbi9lbGV2YXRpb24uanMnO1xuXG5pbXBvcnQgdHlwZSBTdHlsZUxheWVyIGZyb20gJy4uL3N0eWxlL3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCB0eXBlIHtRdWVyeUZlYXR1cmV9IGZyb20gJy4uL3V0aWwvdmVjdG9ydGlsZV90b19nZW9qc29uLmpzJztcbmltcG9ydCB0eXBlIHtGZWF0dXJlU3RhdGVzfSBmcm9tIFwiLi4vc291cmNlL3NvdXJjZV9zdGF0ZVwiO1xuaW1wb3J0IHR5cGUge0ZlYXR1cmVGaWx0ZXJ9IGZyb20gJy4uL3N0eWxlLXNwZWMvZmVhdHVyZV9maWx0ZXIvaW5kZXguanMnO1xuaW1wb3J0IHR5cGUgVHJhbnNmb3JtIGZyb20gJy4uL2dlby90cmFuc2Zvcm0uanMnO1xuaW1wb3J0IHR5cGUge0ZpbHRlclNwZWNpZmljYXRpb24sIFByb21vdGVJZFNwZWNpZmljYXRpb259IGZyb20gJy4uL3N0eWxlLXNwZWMvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge1RpbGVzcGFjZVF1ZXJ5R2VvbWV0cnl9IGZyb20gJy4uL3N0eWxlL3F1ZXJ5X2dlb21ldHJ5LmpzJztcbmltcG9ydCB0eXBlIHtGZWF0dXJlSW5kZXggYXMgRmVhdHVyZUluZGV4U3RydWN0fSBmcm9tICcuL2FycmF5X3R5cGVzLmpzJztcbmltcG9ydCB0eXBlIHtUaWxlVHJhbnNmb3JtfSBmcm9tICcuLi9nZW8vcHJvamVjdGlvbi90aWxlX3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQgdHlwZSB7SVZlY3RvclRpbGVMYXllciwgSVZlY3RvclRpbGVGZWF0dXJlfSBmcm9tICdAbWFwYm94L3ZlY3Rvci10aWxlJztcblxudHlwZSBRdWVyeVBhcmFtZXRlcnMgPSB7XG4gICAgcGl4ZWxQb3NNYXRyaXg6IEZsb2F0MzJBcnJheSxcbiAgICB0cmFuc2Zvcm06IFRyYW5zZm9ybSxcbiAgICB0aWxlUmVzdWx0OiBUaWxlc3BhY2VRdWVyeUdlb21ldHJ5LFxuICAgIHRpbGVUcmFuc2Zvcm06IFRpbGVUcmFuc2Zvcm0sXG4gICAgcGFyYW1zOiB7XG4gICAgICAgIGZpbHRlcjogRmlsdGVyU3BlY2lmaWNhdGlvbixcbiAgICAgICAgbGF5ZXJzOiBBcnJheTxzdHJpbmc+LFxuICAgICAgICBhdmFpbGFibGVJbWFnZXM6IEFycmF5PHN0cmluZz5cbiAgICB9XG59XG5cbmV4cG9ydCB0eXBlIFF1ZXJ5UmVzdWx0ID0ge1tfOiBzdHJpbmddOiBBcnJheTx7IGZlYXR1cmVJbmRleDogbnVtYmVyLCBmZWF0dXJlOiBRdWVyeUZlYXR1cmUgfT59O1xuXG50eXBlIEZlYXR1cmVJbmRpY2VzID0ge1xuICAgIGJ1Y2tldEluZGV4OiBudW1iZXIsXG4gICAgc291cmNlTGF5ZXJJbmRleDogbnVtYmVyLFxuICAgIGZlYXR1cmVJbmRleDogbnVtYmVyLFxuICAgIGxheW91dFZlcnRleEFycmF5T2Zmc2V0OiBudW1iZXJcbn0gfCBGZWF0dXJlSW5kZXhTdHJ1Y3Q7XG5cbmNsYXNzIEZlYXR1cmVJbmRleCB7XG4gICAgdGlsZUlEOiBPdmVyc2NhbGVkVGlsZUlEO1xuICAgIHg6IG51bWJlcjtcbiAgICB5OiBudW1iZXI7XG4gICAgejogbnVtYmVyO1xuICAgIGdyaWQ6IEdyaWQ7XG4gICAgZmVhdHVyZUluZGV4QXJyYXk6IEZlYXR1cmVJbmRleEFycmF5O1xuICAgIHByb21vdGVJZDogP1Byb21vdGVJZFNwZWNpZmljYXRpb247XG5cbiAgICByYXdUaWxlRGF0YTogQXJyYXlCdWZmZXI7XG4gICAgYnVja2V0TGF5ZXJJRHM6IEFycmF5PEFycmF5PHN0cmluZz4+O1xuXG4gICAgdnRMYXllcnM6IHtbXzogc3RyaW5nXTogSVZlY3RvclRpbGVMYXllcn07XG4gICAgdnRGZWF0dXJlczoge1tfOiBzdHJpbmddOiBJVmVjdG9yVGlsZUZlYXR1cmVbXX07XG4gICAgc291cmNlTGF5ZXJDb2RlcjogRGljdGlvbmFyeUNvZGVyO1xuXG4gICAgY29uc3RydWN0b3IodGlsZUlEOiBPdmVyc2NhbGVkVGlsZUlELCBwcm9tb3RlSWQ/OiA/UHJvbW90ZUlkU3BlY2lmaWNhdGlvbikge1xuICAgICAgICB0aGlzLnRpbGVJRCA9IHRpbGVJRDtcbiAgICAgICAgdGhpcy54ID0gdGlsZUlELmNhbm9uaWNhbC54O1xuICAgICAgICB0aGlzLnkgPSB0aWxlSUQuY2Fub25pY2FsLnk7XG4gICAgICAgIHRoaXMueiA9IHRpbGVJRC5jYW5vbmljYWwuejtcbiAgICAgICAgdGhpcy5ncmlkID0gbmV3IEdyaWQoRVhURU5ULCAxNiwgMCk7XG4gICAgICAgIHRoaXMuZmVhdHVyZUluZGV4QXJyYXkgPSBuZXcgRmVhdHVyZUluZGV4QXJyYXkoKTtcbiAgICAgICAgdGhpcy5wcm9tb3RlSWQgPSBwcm9tb3RlSWQ7XG4gICAgfVxuXG4gICAgaW5zZXJ0KGZlYXR1cmU6IElWZWN0b3JUaWxlRmVhdHVyZSwgZ2VvbWV0cnk6IEFycmF5PEFycmF5PFBvaW50Pj4sIGZlYXR1cmVJbmRleDogbnVtYmVyLCBzb3VyY2VMYXllckluZGV4OiBudW1iZXIsIGJ1Y2tldEluZGV4OiBudW1iZXIsIGxheW91dFZlcnRleEFycmF5T2Zmc2V0OiBudW1iZXIgPSAwKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IHRoaXMuZmVhdHVyZUluZGV4QXJyYXkubGVuZ3RoO1xuICAgICAgICB0aGlzLmZlYXR1cmVJbmRleEFycmF5LmVtcGxhY2VCYWNrKGZlYXR1cmVJbmRleCwgc291cmNlTGF5ZXJJbmRleCwgYnVja2V0SW5kZXgsIGxheW91dFZlcnRleEFycmF5T2Zmc2V0KTtcblxuICAgICAgICBjb25zdCBncmlkID0gdGhpcy5ncmlkO1xuXG4gICAgICAgIGZvciAobGV0IHIgPSAwOyByIDwgZ2VvbWV0cnkubGVuZ3RoOyByKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHJpbmcgPSBnZW9tZXRyeVtyXTtcblxuICAgICAgICAgICAgY29uc3QgYmJveCA9IFtJbmZpbml0eSwgSW5maW5pdHksIC1JbmZpbml0eSwgLUluZmluaXR5XTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmluZy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHAgPSByaW5nW2ldO1xuICAgICAgICAgICAgICAgIGJib3hbMF0gPSBNYXRoLm1pbihiYm94WzBdLCBwLngpO1xuICAgICAgICAgICAgICAgIGJib3hbMV0gPSBNYXRoLm1pbihiYm94WzFdLCBwLnkpO1xuICAgICAgICAgICAgICAgIGJib3hbMl0gPSBNYXRoLm1heChiYm94WzJdLCBwLngpO1xuICAgICAgICAgICAgICAgIGJib3hbM10gPSBNYXRoLm1heChiYm94WzNdLCBwLnkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoYmJveFswXSA8IEVYVEVOVCAmJlxuICAgICAgICAgICAgICAgIGJib3hbMV0gPCBFWFRFTlQgJiZcbiAgICAgICAgICAgICAgICBiYm94WzJdID49IDAgJiZcbiAgICAgICAgICAgICAgICBiYm94WzNdID49IDApIHtcbiAgICAgICAgICAgICAgICBncmlkLmluc2VydChrZXksIGJib3hbMF0sIGJib3hbMV0sIGJib3hbMl0sIGJib3hbM10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgbG9hZFZUTGF5ZXJzKCk6IHtbXzogc3RyaW5nXTogSVZlY3RvclRpbGVMYXllcn0ge1xuICAgICAgICBpZiAoIXRoaXMudnRMYXllcnMpIHtcbiAgICAgICAgICAgIHRoaXMudnRMYXllcnMgPSBuZXcgVmVjdG9yVGlsZShuZXcgUHJvdG9idWYodGhpcy5yYXdUaWxlRGF0YSkpLmxheWVycztcbiAgICAgICAgICAgIHRoaXMuc291cmNlTGF5ZXJDb2RlciA9IG5ldyBEaWN0aW9uYXJ5Q29kZXIodGhpcy52dExheWVycyA/IE9iamVjdC5rZXlzKHRoaXMudnRMYXllcnMpLnNvcnQoKSA6IFsnX2dlb2pzb25UaWxlTGF5ZXInXSk7XG4gICAgICAgICAgICB0aGlzLnZ0RmVhdHVyZXMgPSB7fTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgbGF5ZXIgaW4gdGhpcy52dExheWVycykge1xuICAgICAgICAgICAgICAgIHRoaXMudnRGZWF0dXJlc1tsYXllcl0gPSBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy52dExheWVycztcbiAgICB9XG5cbiAgICAvLyBGaW5kcyBub24tc3ltYm9sIGZlYXR1cmVzIGluIHRoaXMgdGlsZSBhdCBhIHBhcnRpY3VsYXIgcG9zaXRpb24uXG4gICAgcXVlcnkoYXJnczogUXVlcnlQYXJhbWV0ZXJzLCBzdHlsZUxheWVyczoge1tfOiBzdHJpbmddOiBTdHlsZUxheWVyfSwgc2VyaWFsaXplZExheWVyczoge1tfOiBzdHJpbmddOiBPYmplY3R9LCBzb3VyY2VGZWF0dXJlU3RhdGU6IFNvdXJjZUZlYXR1cmVTdGF0ZSk6IFF1ZXJ5UmVzdWx0IHtcbiAgICAgICAgdGhpcy5sb2FkVlRMYXllcnMoKTtcbiAgICAgICAgY29uc3QgcGFyYW1zID0gYXJncy5wYXJhbXMgfHwge30sXG4gICAgICAgICAgICBmaWx0ZXIgPSBmZWF0dXJlRmlsdGVyKHBhcmFtcy5maWx0ZXIpO1xuICAgICAgICBjb25zdCB0aWxlc3BhY2VHZW9tZXRyeSA9IGFyZ3MudGlsZVJlc3VsdDtcbiAgICAgICAgY29uc3QgdHJhbnNmb3JtID0gYXJncy50cmFuc2Zvcm07XG5cbiAgICAgICAgY29uc3QgYm91bmRzID0gdGlsZXNwYWNlR2VvbWV0cnkuYnVmZmVyZWRUaWxlc3BhY2VCb3VuZHM7XG4gICAgICAgIGNvbnN0IHF1ZXJ5UHJlZGljYXRlID0gKGJ4MTogbnVtYmVyLCBieTE6IG51bWJlciwgYngyOiBudW1iZXIsIGJ5MjogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gcG9seWdvbkludGVyc2VjdHNCb3godGlsZXNwYWNlR2VvbWV0cnkuYnVmZmVyZWRUaWxlc3BhY2VHZW9tZXRyeSwgYngxLCBieTEsIGJ4MiwgYnkyKTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgbWF0Y2hpbmcgPSB0aGlzLmdyaWQucXVlcnkoYm91bmRzLm1pbi54LCBib3VuZHMubWluLnksIGJvdW5kcy5tYXgueCwgYm91bmRzLm1heC55LCBxdWVyeVByZWRpY2F0ZSk7XG4gICAgICAgIG1hdGNoaW5nLnNvcnQodG9wRG93bkZlYXR1cmVDb21wYXJhdG9yKTtcblxuICAgICAgICBsZXQgZWxldmF0aW9uSGVscGVyID0gbnVsbDtcbiAgICAgICAgaWYgKHRyYW5zZm9ybS5lbGV2YXRpb24gJiYgbWF0Y2hpbmcubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgZWxldmF0aW9uSGVscGVyID0gREVNU2FtcGxlci5jcmVhdGUodHJhbnNmb3JtLmVsZXZhdGlvbiwgdGhpcy50aWxlSUQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0ge307XG4gICAgICAgIGxldCBwcmV2aW91c0luZGV4O1xuICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IG1hdGNoaW5nLmxlbmd0aDsgaysrKSB7XG4gICAgICAgICAgICBjb25zdCBpbmRleCA9IG1hdGNoaW5nW2tdO1xuXG4gICAgICAgICAgICAvLyBkb24ndCBjaGVjayB0aGUgc2FtZSBmZWF0dXJlIG1vcmUgdGhhbiBvbmNlXG4gICAgICAgICAgICBpZiAoaW5kZXggPT09IHByZXZpb3VzSW5kZXgpIGNvbnRpbnVlO1xuICAgICAgICAgICAgcHJldmlvdXNJbmRleCA9IGluZGV4O1xuXG4gICAgICAgICAgICBjb25zdCBtYXRjaCA9IHRoaXMuZmVhdHVyZUluZGV4QXJyYXkuZ2V0KGluZGV4KTtcbiAgICAgICAgICAgIGxldCBmZWF0dXJlR2VvbWV0cnkgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5sb2FkTWF0Y2hpbmdGZWF0dXJlKFxuICAgICAgICAgICAgICAgIHJlc3VsdCxcbiAgICAgICAgICAgICAgICBtYXRjaCxcbiAgICAgICAgICAgICAgICBmaWx0ZXIsXG4gICAgICAgICAgICAgICAgcGFyYW1zLmxheWVycyxcbiAgICAgICAgICAgICAgICBwYXJhbXMuYXZhaWxhYmxlSW1hZ2VzLFxuICAgICAgICAgICAgICAgIHN0eWxlTGF5ZXJzLFxuICAgICAgICAgICAgICAgIHNlcmlhbGl6ZWRMYXllcnMsXG4gICAgICAgICAgICAgICAgc291cmNlRmVhdHVyZVN0YXRlLFxuICAgICAgICAgICAgICAgIChmZWF0dXJlOiBJVmVjdG9yVGlsZUZlYXR1cmUsIHN0eWxlTGF5ZXI6IFN0eWxlTGF5ZXIsIGZlYXR1cmVTdGF0ZTogT2JqZWN0LCBsYXlvdXRWZXJ0ZXhBcnJheU9mZnNldDogbnVtYmVyID0gMCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWZlYXR1cmVHZW9tZXRyeSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZmVhdHVyZUdlb21ldHJ5ID0gbG9hZEdlb21ldHJ5KGZlYXR1cmUsIHRoaXMudGlsZUlELmNhbm9uaWNhbCwgYXJncy50aWxlVHJhbnNmb3JtKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzdHlsZUxheWVyLnF1ZXJ5SW50ZXJzZWN0c0ZlYXR1cmUodGlsZXNwYWNlR2VvbWV0cnksIGZlYXR1cmUsIGZlYXR1cmVTdGF0ZSwgZmVhdHVyZUdlb21ldHJ5LCB0aGlzLnosIGFyZ3MudHJhbnNmb3JtLCBhcmdzLnBpeGVsUG9zTWF0cml4LCBlbGV2YXRpb25IZWxwZXIsIGxheW91dFZlcnRleEFycmF5T2Zmc2V0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBsb2FkTWF0Y2hpbmdGZWF0dXJlKFxuICAgICAgICByZXN1bHQ6IFF1ZXJ5UmVzdWx0LFxuICAgICAgICBmZWF0dXJlSW5kZXhEYXRhOiBGZWF0dXJlSW5kaWNlcyxcbiAgICAgICAgZmlsdGVyOiBGZWF0dXJlRmlsdGVyLFxuICAgICAgICBmaWx0ZXJMYXllcklEczogQXJyYXk8c3RyaW5nPixcbiAgICAgICAgYXZhaWxhYmxlSW1hZ2VzOiBBcnJheTxzdHJpbmc+LFxuICAgICAgICBzdHlsZUxheWVyczoge1tfOiBzdHJpbmddOiBTdHlsZUxheWVyfSxcbiAgICAgICAgc2VyaWFsaXplZExheWVyczoge1tfOiBzdHJpbmddOiBPYmplY3R9LFxuICAgICAgICBzb3VyY2VGZWF0dXJlU3RhdGU/OiBTb3VyY2VGZWF0dXJlU3RhdGUsXG4gICAgICAgIGludGVyc2VjdGlvblRlc3Q/OiAoZmVhdHVyZTogSVZlY3RvclRpbGVGZWF0dXJlLCBzdHlsZUxheWVyOiBTdHlsZUxheWVyLCBmZWF0dXJlU3RhdGU6IE9iamVjdCwgbGF5b3V0VmVydGV4QXJyYXlPZmZzZXQ6IG51bWJlcikgPT4gYm9vbGVhbiB8IG51bWJlcikge1xuXG4gICAgICAgIGNvbnN0IHtmZWF0dXJlSW5kZXgsIGJ1Y2tldEluZGV4LCBzb3VyY2VMYXllckluZGV4LCBsYXlvdXRWZXJ0ZXhBcnJheU9mZnNldH0gPSBmZWF0dXJlSW5kZXhEYXRhO1xuICAgICAgICBjb25zdCBsYXllcklEcyA9IHRoaXMuYnVja2V0TGF5ZXJJRHNbYnVja2V0SW5kZXhdO1xuICAgICAgICBpZiAoZmlsdGVyTGF5ZXJJRHMgJiYgIWFycmF5c0ludGVyc2VjdChmaWx0ZXJMYXllcklEcywgbGF5ZXJJRHMpKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IHNvdXJjZUxheWVyTmFtZSA9IHRoaXMuc291cmNlTGF5ZXJDb2Rlci5kZWNvZGUoc291cmNlTGF5ZXJJbmRleCk7XG4gICAgICAgIGNvbnN0IHNvdXJjZUxheWVyID0gdGhpcy52dExheWVyc1tzb3VyY2VMYXllck5hbWVdO1xuICAgICAgICBjb25zdCBmZWF0dXJlID0gc291cmNlTGF5ZXIuZmVhdHVyZShmZWF0dXJlSW5kZXgpO1xuXG4gICAgICAgIGlmIChmaWx0ZXIubmVlZEdlb21ldHJ5KSB7XG4gICAgICAgICAgICBjb25zdCBldmFsdWF0aW9uRmVhdHVyZSA9IHRvRXZhbHVhdGlvbkZlYXR1cmUoZmVhdHVyZSwgdHJ1ZSk7XG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICBpZiAoIWZpbHRlci5maWx0ZXIobmV3IEV2YWx1YXRpb25QYXJhbWV0ZXJzKHRoaXMudGlsZUlELm92ZXJzY2FsZWRaKSwgZXZhbHVhdGlvbkZlYXR1cmUsIHRoaXMudGlsZUlELmNhbm9uaWNhbCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgfSBlbHNlIGlmICghZmlsdGVyLmZpbHRlcihuZXcgRXZhbHVhdGlvblBhcmFtZXRlcnModGhpcy50aWxlSUQub3ZlcnNjYWxlZFopLCBmZWF0dXJlKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaWQgPSB0aGlzLmdldElkKGZlYXR1cmUsIHNvdXJjZUxheWVyTmFtZSk7XG5cbiAgICAgICAgZm9yIChsZXQgbCA9IDA7IGwgPCBsYXllcklEcy5sZW5ndGg7IGwrKykge1xuICAgICAgICAgICAgY29uc3QgbGF5ZXJJRCA9IGxheWVySURzW2xdO1xuXG4gICAgICAgICAgICBpZiAoZmlsdGVyTGF5ZXJJRHMgJiYgZmlsdGVyTGF5ZXJJRHMuaW5kZXhPZihsYXllcklEKSA8IDApIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3Qgc3R5bGVMYXllciA9IHN0eWxlTGF5ZXJzW2xheWVySURdO1xuXG4gICAgICAgICAgICBpZiAoIXN0eWxlTGF5ZXIpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICBsZXQgZmVhdHVyZVN0YXRlID0ge307XG4gICAgICAgICAgICBpZiAoaWQgIT09IHVuZGVmaW5lZCAmJiBzb3VyY2VGZWF0dXJlU3RhdGUpIHtcbiAgICAgICAgICAgICAgICAvLyBgZmVhdHVyZS1zdGF0ZWAgZXhwcmVzc2lvbiBldmFsdWF0aW9uIHJlcXVpcmVzIGZlYXR1cmUgc3RhdGUgdG8gYmUgYXZhaWxhYmxlXG4gICAgICAgICAgICAgICAgZmVhdHVyZVN0YXRlID0gc291cmNlRmVhdHVyZVN0YXRlLmdldFN0YXRlKHN0eWxlTGF5ZXIuc291cmNlTGF5ZXIgfHwgJ19nZW9qc29uVGlsZUxheWVyJywgaWQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBzZXJpYWxpemVkTGF5ZXIgPSBleHRlbmQoe30sIHNlcmlhbGl6ZWRMYXllcnNbbGF5ZXJJRF0pO1xuXG4gICAgICAgICAgICBzZXJpYWxpemVkTGF5ZXIucGFpbnQgPSBldmFsdWF0ZVByb3BlcnRpZXMoc2VyaWFsaXplZExheWVyLnBhaW50LCBzdHlsZUxheWVyLnBhaW50LCBmZWF0dXJlLCBmZWF0dXJlU3RhdGUsIGF2YWlsYWJsZUltYWdlcyk7XG4gICAgICAgICAgICBzZXJpYWxpemVkTGF5ZXIubGF5b3V0ID0gZXZhbHVhdGVQcm9wZXJ0aWVzKHNlcmlhbGl6ZWRMYXllci5sYXlvdXQsIHN0eWxlTGF5ZXIubGF5b3V0LCBmZWF0dXJlLCBmZWF0dXJlU3RhdGUsIGF2YWlsYWJsZUltYWdlcyk7XG5cbiAgICAgICAgICAgIGNvbnN0IGludGVyc2VjdGlvblogPSAhaW50ZXJzZWN0aW9uVGVzdCB8fCBpbnRlcnNlY3Rpb25UZXN0KGZlYXR1cmUsIHN0eWxlTGF5ZXIsIGZlYXR1cmVTdGF0ZSwgbGF5b3V0VmVydGV4QXJyYXlPZmZzZXQpO1xuICAgICAgICAgICAgaWYgKCFpbnRlcnNlY3Rpb25aKSB7XG4gICAgICAgICAgICAgICAgLy8gT25seSBhcHBsaWVkIGZvciBub24tc3ltYm9sIGZlYXR1cmVzXG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGdlb2pzb25GZWF0dXJlID0gbmV3IEdlb0pTT05GZWF0dXJlKGZlYXR1cmUsIHRoaXMueiwgdGhpcy54LCB0aGlzLnksIGlkKTtcbiAgICAgICAgICAgIGdlb2pzb25GZWF0dXJlLmxheWVyID0gc2VyaWFsaXplZExheWVyO1xuICAgICAgICAgICAgbGV0IGxheWVyUmVzdWx0ID0gcmVzdWx0W2xheWVySURdO1xuICAgICAgICAgICAgaWYgKGxheWVyUmVzdWx0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBsYXllclJlc3VsdCA9IHJlc3VsdFtsYXllcklEXSA9IFtdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsYXllclJlc3VsdC5wdXNoKHtmZWF0dXJlSW5kZXgsIGZlYXR1cmU6IGdlb2pzb25GZWF0dXJlLCBpbnRlcnNlY3Rpb25afSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBHaXZlbiBhIHNldCBvZiBzeW1ib2wgaW5kZXhlcyB0aGF0IGhhdmUgYWxyZWFkeSBiZWVuIGxvb2tlZCB1cCxcbiAgICAvLyByZXR1cm4gYSBtYXRjaGluZyBzZXQgb2YgR2VvSlNPTkZlYXR1cmVzXG4gICAgbG9va3VwU3ltYm9sRmVhdHVyZXMoc3ltYm9sRmVhdHVyZUluZGV4ZXM6IEFycmF5PG51bWJlcj4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgc2VyaWFsaXplZExheWVyczoge1tzdHJpbmddOiBTdHlsZUxheWVyfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICBidWNrZXRJbmRleDogbnVtYmVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZUxheWVySW5kZXg6IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXJTcGVjOiBGaWx0ZXJTcGVjaWZpY2F0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlckxheWVySURzOiBBcnJheTxzdHJpbmc+LFxuICAgICAgICAgICAgICAgICAgICAgICAgIGF2YWlsYWJsZUltYWdlczogQXJyYXk8c3RyaW5nPixcbiAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZUxheWVyczoge1tfOiBzdHJpbmddOiBTdHlsZUxheWVyfSk6IFF1ZXJ5UmVzdWx0IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0ge307XG4gICAgICAgIHRoaXMubG9hZFZUTGF5ZXJzKCk7XG5cbiAgICAgICAgY29uc3QgZmlsdGVyID0gZmVhdHVyZUZpbHRlcihmaWx0ZXJTcGVjKTtcblxuICAgICAgICBmb3IgKGNvbnN0IHN5bWJvbEZlYXR1cmVJbmRleCBvZiBzeW1ib2xGZWF0dXJlSW5kZXhlcykge1xuICAgICAgICAgICAgdGhpcy5sb2FkTWF0Y2hpbmdGZWF0dXJlKFxuICAgICAgICAgICAgICAgIHJlc3VsdCwge1xuICAgICAgICAgICAgICAgICAgICBidWNrZXRJbmRleCxcbiAgICAgICAgICAgICAgICAgICAgc291cmNlTGF5ZXJJbmRleCxcbiAgICAgICAgICAgICAgICAgICAgZmVhdHVyZUluZGV4OiBzeW1ib2xGZWF0dXJlSW5kZXgsXG4gICAgICAgICAgICAgICAgICAgIGxheW91dFZlcnRleEFycmF5T2Zmc2V0OiAwXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBmaWx0ZXIsXG4gICAgICAgICAgICAgICAgZmlsdGVyTGF5ZXJJRHMsXG4gICAgICAgICAgICAgICAgYXZhaWxhYmxlSW1hZ2VzLFxuICAgICAgICAgICAgICAgIHN0eWxlTGF5ZXJzLFxuICAgICAgICAgICAgICAgIHNlcmlhbGl6ZWRMYXllcnNcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIGxvYWRGZWF0dXJlKGZlYXR1cmVJbmRleERhdGE6IEZlYXR1cmVJbmRpY2VzKTogSVZlY3RvclRpbGVGZWF0dXJlIHtcbiAgICAgICAgY29uc3Qge2ZlYXR1cmVJbmRleCwgc291cmNlTGF5ZXJJbmRleH0gPSBmZWF0dXJlSW5kZXhEYXRhO1xuXG4gICAgICAgIHRoaXMubG9hZFZUTGF5ZXJzKCk7XG4gICAgICAgIGNvbnN0IHNvdXJjZUxheWVyTmFtZSA9IHRoaXMuc291cmNlTGF5ZXJDb2Rlci5kZWNvZGUoc291cmNlTGF5ZXJJbmRleCk7XG5cbiAgICAgICAgY29uc3QgZmVhdHVyZUNhY2hlID0gdGhpcy52dEZlYXR1cmVzW3NvdXJjZUxheWVyTmFtZV07XG4gICAgICAgIGlmIChmZWF0dXJlQ2FjaGVbZmVhdHVyZUluZGV4XSkge1xuICAgICAgICAgICAgcmV0dXJuIGZlYXR1cmVDYWNoZVtmZWF0dXJlSW5kZXhdO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNvdXJjZUxheWVyID0gdGhpcy52dExheWVyc1tzb3VyY2VMYXllck5hbWVdO1xuICAgICAgICBjb25zdCBmZWF0dXJlID0gc291cmNlTGF5ZXIuZmVhdHVyZShmZWF0dXJlSW5kZXgpO1xuICAgICAgICBmZWF0dXJlQ2FjaGVbZmVhdHVyZUluZGV4XSA9IGZlYXR1cmU7XG5cbiAgICAgICAgcmV0dXJuIGZlYXR1cmU7XG4gICAgfVxuXG4gICAgaGFzTGF5ZXIoaWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICBmb3IgKGNvbnN0IGxheWVySURzIG9mIHRoaXMuYnVja2V0TGF5ZXJJRHMpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgbGF5ZXJJRCBvZiBsYXllcklEcykge1xuICAgICAgICAgICAgICAgIGlmIChpZCA9PT0gbGF5ZXJJRCkgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgZ2V0SWQoZmVhdHVyZTogSVZlY3RvclRpbGVGZWF0dXJlLCBzb3VyY2VMYXllcklkOiBzdHJpbmcpOiBzdHJpbmcgfCBudW1iZXIgfCB2b2lkIHtcbiAgICAgICAgbGV0IGlkID0gZmVhdHVyZS5pZDtcbiAgICAgICAgaWYgKHRoaXMucHJvbW90ZUlkKSB7XG4gICAgICAgICAgICBjb25zdCBwcm9wTmFtZSA9IHR5cGVvZiB0aGlzLnByb21vdGVJZCA9PT0gJ3N0cmluZycgPyB0aGlzLnByb21vdGVJZCA6IHRoaXMucHJvbW90ZUlkW3NvdXJjZUxheWVySWRdO1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtdHlwZV0gLSBGbG93IGNhbid0IG5hcnJvdyB0aGUgaWQgdHlwZSBmcm9tIElWZWN0b3JUaWxlRmVhdHVyZS5pZFxuICAgICAgICAgICAgaWYgKHByb3BOYW1lICE9IG51bGwpIGlkID0gZmVhdHVyZS5wcm9wZXJ0aWVzW3Byb3BOYW1lXTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgaWQgPT09ICdib29sZWFuJykgaWQgPSBOdW1iZXIoaWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpZDtcbiAgICB9XG59XG5cbnJlZ2lzdGVyKEZlYXR1cmVJbmRleCwgJ0ZlYXR1cmVJbmRleCcsIHtvbWl0OiBbJ3Jhd1RpbGVEYXRhJywgJ3NvdXJjZUxheWVyQ29kZXInXX0pO1xuXG5leHBvcnQgZGVmYXVsdCBGZWF0dXJlSW5kZXg7XG5cbmZ1bmN0aW9uIGV2YWx1YXRlUHJvcGVydGllcyhzZXJpYWxpemVkUHJvcGVydGllczogbWl4ZWQsIHN0eWxlTGF5ZXJQcm9wZXJ0aWVzOiBtaXhlZCwgZmVhdHVyZTogSVZlY3RvclRpbGVGZWF0dXJlLCBmZWF0dXJlU3RhdGU6IEZlYXR1cmVTdGF0ZXMsIGF2YWlsYWJsZUltYWdlczogQXJyYXk8c3RyaW5nPikge1xuICAgIHJldHVybiBtYXBPYmplY3Qoc2VyaWFsaXplZFByb3BlcnRpZXMsIChwcm9wZXJ0eSwga2V5KSA9PiB7XG4gICAgICAgIGNvbnN0IHByb3AgPSBzdHlsZUxheWVyUHJvcGVydGllcyBpbnN0YW5jZW9mIFBvc3NpYmx5RXZhbHVhdGVkID8gc3R5bGVMYXllclByb3BlcnRpZXMuZ2V0KGtleSkgOiBudWxsO1xuICAgICAgICByZXR1cm4gcHJvcCAmJiBwcm9wLmV2YWx1YXRlID8gcHJvcC5ldmFsdWF0ZShmZWF0dXJlLCBmZWF0dXJlU3RhdGUsIGF2YWlsYWJsZUltYWdlcykgOiBwcm9wO1xuICAgIH0pO1xufVxuXG5mdW5jdGlvbiB0b3BEb3duRmVhdHVyZUNvbXBhcmF0b3IoYTogbnVtYmVyLCBiOiBudW1iZXIpIHtcbiAgICByZXR1cm4gYiAtIGE7XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge3dhcm5PbmNlLCBuZXh0UG93ZXJPZlR3b30gZnJvbSAnLi4vdXRpbC91dGlsLmpzJztcbmltcG9ydCB7QWxwaGFJbWFnZX0gZnJvbSAnLi4vdXRpbC9pbWFnZS5qcyc7XG5pbXBvcnQge3JlZ2lzdGVyfSBmcm9tICcuLi91dGlsL3dlYl93b3JrZXJfdHJhbnNmZXIuanMnO1xuXG5pbXBvcnQgdHlwZSB7U3ByaXRlUG9zaXRpb24sIFNwcml0ZVBvc2l0aW9uc30gZnJvbSAnLi4vdXRpbC9pbWFnZS5qcyc7XG5cbnR5cGUgRGFzaFJhbmdlID0ge3xcbiAgICBpc0Rhc2g6IGJvb2xlYW4sXG4gICAgbGVmdDogbnVtYmVyLFxuICAgIHJpZ2h0OiBudW1iZXIsXG4gICAgemVyb0xlbmd0aDogYm9vbGVhblxufH07XG5cbi8qKlxuICogQSBMaW5lQXRsYXMgbGV0cyB1cyByZXVzZSByZW5kZXJlZCBkYXNoZWQgbGluZXNcbiAqIGJ5IHdyaXRpbmcgbWFueSBvZiB0aGVtIHRvIGEgdGV4dHVyZSBhbmQgdGhlbiBmZXRjaGluZyB0aGVpciBwb3NpdGlvbnNcbiAqIHVzaW5nIC5nZXREYXNoLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSB3aWR0aFxuICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodFxuICogQHByaXZhdGVcbiAqL1xuY2xhc3MgTGluZUF0bGFzIHtcbiAgICB3aWR0aDogbnVtYmVyO1xuICAgIGhlaWdodDogbnVtYmVyO1xuICAgIG5leHRSb3c6IG51bWJlcjtcbiAgICBpbWFnZTogQWxwaGFJbWFnZTtcbiAgICBwb3NpdGlvbnM6IFNwcml0ZVBvc2l0aW9ucztcbiAgICB1cGxvYWRlZDogYm9vbGVhbjtcblxuICAgIGNvbnN0cnVjdG9yKHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgICAgIHRoaXMud2lkdGggPSB3aWR0aDtcbiAgICAgICAgdGhpcy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgICAgIHRoaXMubmV4dFJvdyA9IDA7XG4gICAgICAgIHRoaXMuaW1hZ2UgPSBuZXcgQWxwaGFJbWFnZSh7d2lkdGgsIGhlaWdodH0pO1xuICAgICAgICB0aGlzLnBvc2l0aW9ucyA9IHt9O1xuICAgICAgICB0aGlzLnVwbG9hZGVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IGEgZGFzaCBsaW5lIHBhdHRlcm4uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGRhc2hhcnJheVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBsaW5lQ2FwIHRoZSB0eXBlIG9mIGxpbmUgY2FwcyB0byBiZSBhZGRlZCB0byBkYXNoZXNcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBwb3NpdGlvbiBvZiBkYXNoIHRleHR1cmUgaW4geyB5LCBoZWlnaHQsIHdpZHRoIH1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIGdldERhc2goZGFzaGFycmF5OiBBcnJheTxudW1iZXI+LCBsaW5lQ2FwOiBzdHJpbmcpOiBTcHJpdGVQb3NpdGlvbiB7XG4gICAgICAgIGNvbnN0IGtleSA9IHRoaXMuZ2V0S2V5KGRhc2hhcnJheSwgbGluZUNhcCk7XG4gICAgICAgIHJldHVybiB0aGlzLnBvc2l0aW9uc1trZXldO1xuICAgIH1cblxuICAgIHRyaW0oKSB7XG4gICAgICAgIGNvbnN0IHdpZHRoID0gdGhpcy53aWR0aDtcbiAgICAgICAgY29uc3QgaGVpZ2h0ID0gdGhpcy5oZWlnaHQgPSBuZXh0UG93ZXJPZlR3byh0aGlzLm5leHRSb3cpO1xuICAgICAgICB0aGlzLmltYWdlLnJlc2l6ZSh7d2lkdGgsIGhlaWdodH0pO1xuICAgIH1cblxuICAgIGdldEtleShkYXNoYXJyYXk6IEFycmF5PG51bWJlcj4sIGxpbmVDYXA6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBkYXNoYXJyYXkuam9pbignLCcpICsgbGluZUNhcDtcbiAgICB9XG5cbiAgICBnZXREYXNoUmFuZ2VzKGRhc2hhcnJheTogQXJyYXk8bnVtYmVyPiwgbGluZUF0bGFzV2lkdGg6IG51bWJlciwgc3RyZXRjaDogbnVtYmVyKTogQXJyYXk8RGFzaFJhbmdlPiB7XG4gICAgICAgIC8vIElmIGRhc2hhcnJheSBoYXMgYW4gb2RkIGxlbmd0aCwgYm90aCB0aGUgZmlyc3QgYW5kIGxhc3QgcGFydHNcbiAgICAgICAgLy8gYXJlIGRhc2hlcyBhbmQgc2hvdWxkIGJlIGpvaW5lZCBzZWFtbGVzc2x5LlxuICAgICAgICBjb25zdCBvZGREYXNoQXJyYXkgPSBkYXNoYXJyYXkubGVuZ3RoICUgMiA9PT0gMTtcblxuICAgICAgICBjb25zdCByYW5nZXMgPSBbXTtcblxuICAgICAgICBsZXQgbGVmdCA9IG9kZERhc2hBcnJheSA/IC1kYXNoYXJyYXlbZGFzaGFycmF5Lmxlbmd0aCAtIDFdICogc3RyZXRjaCA6IDA7XG4gICAgICAgIGxldCByaWdodCA9IGRhc2hhcnJheVswXSAqIHN0cmV0Y2g7XG4gICAgICAgIGxldCBpc0Rhc2ggPSB0cnVlO1xuXG4gICAgICAgIHJhbmdlcy5wdXNoKHtsZWZ0LCByaWdodCwgaXNEYXNoLCB6ZXJvTGVuZ3RoOiBkYXNoYXJyYXlbMF0gPT09IDB9KTtcblxuICAgICAgICBsZXQgY3VycmVudERhc2hMZW5ndGggPSBkYXNoYXJyYXlbMF07XG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgZGFzaGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpc0Rhc2ggPSAhaXNEYXNoO1xuXG4gICAgICAgICAgICBjb25zdCBkYXNoTGVuZ3RoID0gZGFzaGFycmF5W2ldO1xuICAgICAgICAgICAgbGVmdCA9IGN1cnJlbnREYXNoTGVuZ3RoICogc3RyZXRjaDtcbiAgICAgICAgICAgIGN1cnJlbnREYXNoTGVuZ3RoICs9IGRhc2hMZW5ndGg7XG4gICAgICAgICAgICByaWdodCA9IGN1cnJlbnREYXNoTGVuZ3RoICogc3RyZXRjaDtcblxuICAgICAgICAgICAgcmFuZ2VzLnB1c2goe2xlZnQsIHJpZ2h0LCBpc0Rhc2gsIHplcm9MZW5ndGg6IGRhc2hMZW5ndGggPT09IDB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByYW5nZXM7XG4gICAgfVxuXG4gICAgYWRkUm91bmREYXNoKHJhbmdlczogQXJyYXk8RGFzaFJhbmdlPiwgc3RyZXRjaDogbnVtYmVyLCBuOiBudW1iZXIpIHtcbiAgICAgICAgY29uc3QgaGFsZlN0cmV0Y2ggPSBzdHJldGNoIC8gMjtcblxuICAgICAgICBmb3IgKGxldCB5ID0gLW47IHkgPD0gbjsgeSsrKSB7XG4gICAgICAgICAgICBjb25zdCByb3cgPSB0aGlzLm5leHRSb3cgKyBuICsgeTtcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy53aWR0aCAqIHJvdztcbiAgICAgICAgICAgIGxldCBjdXJySW5kZXggPSAwO1xuICAgICAgICAgICAgbGV0IHJhbmdlID0gcmFuZ2VzW2N1cnJJbmRleF07XG5cbiAgICAgICAgICAgIGZvciAobGV0IHggPSAwOyB4IDwgdGhpcy53aWR0aDsgeCsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKHggLyByYW5nZS5yaWdodCA+IDEpIHsgcmFuZ2UgPSByYW5nZXNbKytjdXJySW5kZXhdOyB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBkaXN0TGVmdCA9IE1hdGguYWJzKHggLSByYW5nZS5sZWZ0KTtcbiAgICAgICAgICAgICAgICBjb25zdCBkaXN0UmlnaHQgPSBNYXRoLmFicyh4IC0gcmFuZ2UucmlnaHQpO1xuICAgICAgICAgICAgICAgIGNvbnN0IG1pbkRpc3QgPSBNYXRoLm1pbihkaXN0TGVmdCwgZGlzdFJpZ2h0KTtcbiAgICAgICAgICAgICAgICBsZXQgc2lnbmVkRGlzdGFuY2U7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBkaXN0TWlkZGxlID0gIHkgLyBuICogKGhhbGZTdHJldGNoICsgMSk7XG4gICAgICAgICAgICAgICAgaWYgKHJhbmdlLmlzRGFzaCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkaXN0RWRnZSA9IGhhbGZTdHJldGNoIC0gTWF0aC5hYnMoZGlzdE1pZGRsZSk7XG4gICAgICAgICAgICAgICAgICAgIHNpZ25lZERpc3RhbmNlID0gTWF0aC5zcXJ0KG1pbkRpc3QgKiBtaW5EaXN0ICsgZGlzdEVkZ2UgKiBkaXN0RWRnZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgc2lnbmVkRGlzdGFuY2UgPSBoYWxmU3RyZXRjaCAtIE1hdGguc3FydChtaW5EaXN0ICogbWluRGlzdCArIGRpc3RNaWRkbGUgKiBkaXN0TWlkZGxlKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLmltYWdlLmRhdGFbaW5kZXggKyB4XSA9IE1hdGgubWF4KDAsIE1hdGgubWluKDI1NSwgc2lnbmVkRGlzdGFuY2UgKyAxMjgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFkZFJlZ3VsYXJEYXNoKHJhbmdlczogQXJyYXk8RGFzaFJhbmdlPiwgY2FwTGVuZ3RoOiBudW1iZXIpIHtcblxuICAgICAgICAvLyBDb2xsYXBzZSBhbnkgemVyby1sZW5ndGggcmFuZ2VcbiAgICAgICAgLy8gQ29sbGFwc2UgbmVpZ2hib3VyaW5nIHNhbWUtdHlwZSBwYXJ0cyBpbnRvIGEgc2luZ2xlIHBhcnRcbiAgICAgICAgZm9yIChsZXQgaSA9IHJhbmdlcy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICAgICAgY29uc3QgcGFydCA9IHJhbmdlc1tpXTtcbiAgICAgICAgICAgIGNvbnN0IG5leHQgPSByYW5nZXNbaSArIDFdO1xuICAgICAgICAgICAgaWYgKHBhcnQuemVyb0xlbmd0aCkge1xuICAgICAgICAgICAgICAgIHJhbmdlcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG5leHQgJiYgbmV4dC5pc0Rhc2ggPT09IHBhcnQuaXNEYXNoKSB7XG4gICAgICAgICAgICAgICAgbmV4dC5sZWZ0ID0gcGFydC5sZWZ0O1xuICAgICAgICAgICAgICAgIHJhbmdlcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDb21iaW5lIHRoZSBmaXJzdCBhbmQgbGFzdCBwYXJ0cyBpZiBwb3NzaWJsZVxuICAgICAgICBjb25zdCBmaXJzdCA9IHJhbmdlc1swXTtcbiAgICAgICAgY29uc3QgbGFzdCA9IHJhbmdlc1tyYW5nZXMubGVuZ3RoIC0gMV07XG4gICAgICAgIGlmIChmaXJzdC5pc0Rhc2ggPT09IGxhc3QuaXNEYXNoKSB7XG4gICAgICAgICAgICBmaXJzdC5sZWZ0ID0gbGFzdC5sZWZ0IC0gdGhpcy53aWR0aDtcbiAgICAgICAgICAgIGxhc3QucmlnaHQgPSBmaXJzdC5yaWdodCArIHRoaXMud2lkdGg7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMud2lkdGggKiB0aGlzLm5leHRSb3c7XG4gICAgICAgIGxldCBjdXJySW5kZXggPSAwO1xuICAgICAgICBsZXQgcmFuZ2UgPSByYW5nZXNbY3VyckluZGV4XTtcblxuICAgICAgICBmb3IgKGxldCB4ID0gMDsgeCA8IHRoaXMud2lkdGg7IHgrKykge1xuICAgICAgICAgICAgaWYgKHggLyByYW5nZS5yaWdodCA+IDEpIHtcbiAgICAgICAgICAgICAgICByYW5nZSA9IHJhbmdlc1srK2N1cnJJbmRleF07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGRpc3RMZWZ0ID0gTWF0aC5hYnMoeCAtIHJhbmdlLmxlZnQpO1xuICAgICAgICAgICAgY29uc3QgZGlzdFJpZ2h0ID0gTWF0aC5hYnMoeCAtIHJhbmdlLnJpZ2h0KTtcblxuICAgICAgICAgICAgY29uc3QgbWluRGlzdCA9IE1hdGgubWluKGRpc3RMZWZ0LCBkaXN0UmlnaHQpO1xuICAgICAgICAgICAgY29uc3Qgc2lnbmVkRGlzdGFuY2UgPSAocmFuZ2UuaXNEYXNoID8gbWluRGlzdCA6IC1taW5EaXN0KSArIGNhcExlbmd0aDtcblxuICAgICAgICAgICAgdGhpcy5pbWFnZS5kYXRhW2luZGV4ICsgeF0gPSBNYXRoLm1heCgwLCBNYXRoLm1pbigyNTUsIHNpZ25lZERpc3RhbmNlICsgMTI4KSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhZGREYXNoKGRhc2hhcnJheTogQXJyYXk8bnVtYmVyPiwgbGluZUNhcDogc3RyaW5nKTogbnVsbCB8IFNwcml0ZVBvc2l0aW9uIHtcbiAgICAgICAgY29uc3Qga2V5ID0gdGhpcy5nZXRLZXkoZGFzaGFycmF5LCBsaW5lQ2FwKTtcbiAgICAgICAgaWYgKHRoaXMucG9zaXRpb25zW2tleV0pIHJldHVybiB0aGlzLnBvc2l0aW9uc1trZXldO1xuXG4gICAgICAgIGNvbnN0IHJvdW5kID0gbGluZUNhcCA9PT0gJ3JvdW5kJztcbiAgICAgICAgY29uc3QgbiA9IHJvdW5kID8gNyA6IDA7XG4gICAgICAgIGNvbnN0IGhlaWdodCA9IDIgKiBuICsgMTtcblxuICAgICAgICBpZiAodGhpcy5uZXh0Um93ICsgaGVpZ2h0ID4gdGhpcy5oZWlnaHQpIHtcbiAgICAgICAgICAgIHdhcm5PbmNlKCdMaW5lQXRsYXMgb3V0IG9mIHNwYWNlJyk7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGRhc2hhcnJheSBpcyBlbXB0eSwgZHJhd3MgYSBmdWxsIGxpbmUgKG5vIGRhc2ggb3Igbm8gZ2FwIGxlbmd0aCByZXByZXNlbnRlZCwgZGVmYXVsdCBiZWhhdmlvcilcbiAgICAgICAgaWYgKGRhc2hhcnJheS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIC8vIGluc2VydCBhIHNpbmdsZSBkYXNoIHJhbmdlIGluIG9yZGVyIHRvIGRyYXcgYSBmdWxsIGxpbmVcbiAgICAgICAgICAgIGRhc2hhcnJheS5wdXNoKDEpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGxlbmd0aCA9IDA7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGFzaGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoZGFzaGFycmF5W2ldIDwgMCkge1xuICAgICAgICAgICAgICAgIHdhcm5PbmNlKCdOZWdhdGl2ZSB2YWx1ZSBpcyBmb3VuZCBpbiBsaW5lIGRhc2hhcnJheSwgcmVwbGFjaW5nIHZhbHVlcyB3aXRoIDAnKTtcbiAgICAgICAgICAgICAgICBkYXNoYXJyYXlbaV0gPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGVuZ3RoICs9IGRhc2hhcnJheVtpXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChsZW5ndGggIT09IDApIHtcbiAgICAgICAgICAgIGNvbnN0IHN0cmV0Y2ggPSB0aGlzLndpZHRoIC8gbGVuZ3RoO1xuICAgICAgICAgICAgY29uc3QgcmFuZ2VzID0gdGhpcy5nZXREYXNoUmFuZ2VzKGRhc2hhcnJheSwgdGhpcy53aWR0aCwgc3RyZXRjaCk7XG5cbiAgICAgICAgICAgIGlmIChyb3VuZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkUm91bmREYXNoKHJhbmdlcywgc3RyZXRjaCwgbik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNhcExlbmd0aCA9IGxpbmVDYXAgPT09ICdzcXVhcmUnID8gMC41ICogc3RyZXRjaCA6IDA7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRSZWd1bGFyRGFzaChyYW5nZXMsIGNhcExlbmd0aCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB5ID0gdGhpcy5uZXh0Um93ICsgbjtcblxuICAgICAgICB0aGlzLm5leHRSb3cgKz0gaGVpZ2h0O1xuXG4gICAgICAgIGNvbnN0IHBvcyA9IHtcbiAgICAgICAgICAgIHRsOiBbeSwgbl0sXG4gICAgICAgICAgICBicjogW2xlbmd0aCwgMF1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5wb3NpdGlvbnNba2V5XSA9IHBvcztcbiAgICAgICAgcmV0dXJuIHBvcztcbiAgICB9XG59XG5cbnJlZ2lzdGVyKExpbmVBdGxhcywgJ0xpbmVBdGxhcycpO1xuXG5leHBvcnQgZGVmYXVsdCBMaW5lQXRsYXM7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge1NERl9TQ0FMRX0gZnJvbSAnLi4vcmVuZGVyL2dseXBoX21hbmFnZXIuanMnO1xuaW1wb3J0IHtBbHBoYUltYWdlfSBmcm9tICcuLi91dGlsL2ltYWdlLmpzJztcbmltcG9ydCB7cmVnaXN0ZXJ9IGZyb20gJy4uL3V0aWwvd2ViX3dvcmtlcl90cmFuc2Zlci5qcyc7XG5pbXBvcnQgcG90cGFjayBmcm9tICdwb3RwYWNrJztcblxuaW1wb3J0IHR5cGUge1N0eWxlR2x5cGh9IGZyb20gJy4uL3N0eWxlL3N0eWxlX2dseXBoLmpzJztcblxuY29uc3QgZ2x5cGhQYWRkaW5nID0gMTtcbi8qXG4gICAgVGhlIGdseXBoIHBhZGRpbmcgaXMganVzdCB0byBwcmV2ZW50IHNhbXBsaW5nIGVycm9ycyBhdCB0aGUgYm91bmRhcmllcyBiZXR3ZWVuXG4gICAgZ2x5cGhzIGluIHRoZSBhdGxhcyB0ZXh0dXJlLCBhbmQgZm9yIHRoYXQgcHVycG9zZSB0aGVyZSdzIG5vIG5lZWQgdG8gbWFrZSBpdFxuICAgIGJpZ2dlciB3aXRoIGhpZ2gtcmVzIFNERnMuIEhvd2V2ZXIsIGxheW91dCBpcyBkb25lIGJhc2VkIG9uIHRoZSBnbHlwaCBzaXplXG4gICAgaW5jbHVkaW5nIHRoaXMgcGFkZGluZywgc28gc2NhbGluZyB0aGlzIHBhZGRpbmcgaXMgdGhlIGVhc2llc3Qgd2F5IHRvIGtlZXBcbiAgICBsYXlvdXQgZXhhY3RseSB0aGUgc2FtZSBhcyB0aGUgU0RGX1NDQUxFIGNoYW5nZXMuXG4qL1xuY29uc3QgbG9jYWxHbHlwaFBhZGRpbmcgPSBnbHlwaFBhZGRpbmcgKiBTREZfU0NBTEU7XG5cbmV4cG9ydCB0eXBlIEdseXBoUmVjdCA9IHtcbiAgICB4OiBudW1iZXIsXG4gICAgeTogbnVtYmVyLFxuICAgIHc6IG51bWJlcixcbiAgICBoOiBudW1iZXJcbn07XG4vLyB7Z2x5cGhJRDogZ2x5cGhSZWN0fVxuZXhwb3J0IHR5cGUgR2x5cGhQb3NpdGlvbk1hcCA9IHsgW186IG51bWJlcl06IEdseXBoUmVjdCB9O1xuXG4vLyB7Zm9udFN0YWNrOiBnbHlwaFBvaXN0aW9uTWFwfVxuZXhwb3J0IHR5cGUgR2x5cGhQb3NpdGlvbnMgPSB7IFtfOiBzdHJpbmddOiBHbHlwaFBvc2l0aW9uTWFwIH07XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEdseXBoQXRsYXMge1xuICAgIGltYWdlOiBBbHBoYUltYWdlO1xuICAgIHBvc2l0aW9uczogR2x5cGhQb3NpdGlvbnM7XG4gICAgY29uc3RydWN0b3Ioc3RhY2tzOiB7W186IHN0cmluZ106IHtnbHlwaHM6IHtbXzogbnVtYmVyXTogP1N0eWxlR2x5cGggfSwgYXNjZW5kZXI/OiBudW1iZXIsIGRlc2NlbmRlcj86IG51bWJlciB9fSkge1xuICAgICAgICBjb25zdCBwb3NpdGlvbnMgPSB7fTtcbiAgICAgICAgY29uc3QgYmlucyA9IFtdO1xuXG4gICAgICAgIGZvciAoY29uc3Qgc3RhY2sgaW4gc3RhY2tzKSB7XG4gICAgICAgICAgICBjb25zdCBnbHlwaERhdGEgPSBzdGFja3Nbc3RhY2tdO1xuICAgICAgICAgICAgY29uc3QgZ2x5cGhQb3NpdGlvbk1hcCA9IHBvc2l0aW9uc1tzdGFja10gPSB7fTtcblxuICAgICAgICAgICAgZm9yIChjb25zdCBpZCBpbiBnbHlwaERhdGEuZ2x5cGhzKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3JjID0gZ2x5cGhEYXRhLmdseXBoc1sraWRdO1xuICAgICAgICAgICAgICAgIGlmICghc3JjIHx8IHNyYy5iaXRtYXAud2lkdGggPT09IDAgfHwgc3JjLmJpdG1hcC5oZWlnaHQgPT09IDApIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgcGFkZGluZyA9IHNyYy5tZXRyaWNzLmxvY2FsR2x5cGggPyBsb2NhbEdseXBoUGFkZGluZyA6IGdseXBoUGFkZGluZztcbiAgICAgICAgICAgICAgICBjb25zdCBiaW4gPSB7XG4gICAgICAgICAgICAgICAgICAgIHg6IDAsXG4gICAgICAgICAgICAgICAgICAgIHk6IDAsXG4gICAgICAgICAgICAgICAgICAgIHc6IHNyYy5iaXRtYXAud2lkdGggKyAyICogcGFkZGluZyxcbiAgICAgICAgICAgICAgICAgICAgaDogc3JjLmJpdG1hcC5oZWlnaHQgKyAyICogcGFkZGluZ1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgYmlucy5wdXNoKGJpbik7XG4gICAgICAgICAgICAgICAgZ2x5cGhQb3NpdGlvbk1hcFtpZF0gPSBiaW47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB7dywgaH0gPSBwb3RwYWNrKGJpbnMpO1xuICAgICAgICBjb25zdCBpbWFnZSA9IG5ldyBBbHBoYUltYWdlKHt3aWR0aDogdyB8fCAxLCBoZWlnaHQ6IGggfHwgMX0pO1xuXG4gICAgICAgIGZvciAoY29uc3Qgc3RhY2sgaW4gc3RhY2tzKSB7XG4gICAgICAgICAgICBjb25zdCBnbHlwaERhdGEgPSBzdGFja3Nbc3RhY2tdO1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGlkIGluIGdseXBoRGF0YS5nbHlwaHMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzcmMgPSBnbHlwaERhdGEuZ2x5cGhzWytpZF07XG4gICAgICAgICAgICAgICAgaWYgKCFzcmMgfHwgc3JjLmJpdG1hcC53aWR0aCA9PT0gMCB8fCBzcmMuYml0bWFwLmhlaWdodCA9PT0gMCkgY29udGludWU7XG4gICAgICAgICAgICAgICAgY29uc3QgYmluID0gcG9zaXRpb25zW3N0YWNrXVtpZF07XG4gICAgICAgICAgICAgICAgY29uc3QgcGFkZGluZyA9IHNyYy5tZXRyaWNzLmxvY2FsR2x5cGggPyBsb2NhbEdseXBoUGFkZGluZyA6IGdseXBoUGFkZGluZztcbiAgICAgICAgICAgICAgICBBbHBoYUltYWdlLmNvcHkoc3JjLmJpdG1hcCwgaW1hZ2UsIHt4OiAwLCB5OiAwfSwge3g6IGJpbi54ICsgcGFkZGluZywgeTogYmluLnkgKyBwYWRkaW5nfSwgc3JjLmJpdG1hcCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmltYWdlID0gaW1hZ2U7XG4gICAgICAgIHRoaXMucG9zaXRpb25zID0gcG9zaXRpb25zO1xuICAgIH1cbn1cblxucmVnaXN0ZXIoR2x5cGhBdGxhcywgJ0dseXBoQXRsYXMnKTtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCBGZWF0dXJlSW5kZXggZnJvbSAnLi4vZGF0YS9mZWF0dXJlX2luZGV4LmpzJztcblxuaW1wb3J0IHtwZXJmb3JtU3ltYm9sTGF5b3V0fSBmcm9tICcuLi9zeW1ib2wvc3ltYm9sX2xheW91dC5qcyc7XG5pbXBvcnQge0NvbGxpc2lvbkJveEFycmF5fSBmcm9tICcuLi9kYXRhL2FycmF5X3R5cGVzLmpzJztcbmltcG9ydCBEaWN0aW9uYXJ5Q29kZXIgZnJvbSAnLi4vdXRpbC9kaWN0aW9uYXJ5X2NvZGVyLmpzJztcbmltcG9ydCBTeW1ib2xCdWNrZXQgZnJvbSAnLi4vZGF0YS9idWNrZXQvc3ltYm9sX2J1Y2tldC5qcyc7XG5pbXBvcnQgTGluZUJ1Y2tldCBmcm9tICcuLi9kYXRhL2J1Y2tldC9saW5lX2J1Y2tldC5qcyc7XG5pbXBvcnQgRmlsbEJ1Y2tldCBmcm9tICcuLi9kYXRhL2J1Y2tldC9maWxsX2J1Y2tldC5qcyc7XG5pbXBvcnQgRmlsbEV4dHJ1c2lvbkJ1Y2tldCBmcm9tICcuLi9kYXRhL2J1Y2tldC9maWxsX2V4dHJ1c2lvbl9idWNrZXQuanMnO1xuaW1wb3J0IHt3YXJuT25jZSwgbWFwT2JqZWN0LCB2YWx1ZXN9IGZyb20gJy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgTGluZUF0bGFzIGZyb20gJy4uL3JlbmRlci9saW5lX2F0bGFzLmpzJztcbmltcG9ydCBJbWFnZUF0bGFzIGZyb20gJy4uL3JlbmRlci9pbWFnZV9hdGxhcy5qcyc7XG5pbXBvcnQgR2x5cGhBdGxhcyBmcm9tICcuLi9yZW5kZXIvZ2x5cGhfYXRsYXMuanMnO1xuaW1wb3J0IEV2YWx1YXRpb25QYXJhbWV0ZXJzIGZyb20gJy4uL3N0eWxlL2V2YWx1YXRpb25fcGFyYW1ldGVycy5qcyc7XG5pbXBvcnQge0Nhbm9uaWNhbFRpbGVJRCwgT3ZlcnNjYWxlZFRpbGVJRH0gZnJvbSAnLi90aWxlX2lkLmpzJztcbmltcG9ydCB7UGVyZm9ybWFuY2VVdGlsc30gZnJvbSAnLi4vdXRpbC9wZXJmb3JtYW5jZS5qcyc7XG5pbXBvcnQgdGlsZVRyYW5zZm9ybSBmcm9tICcuLi9nZW8vcHJvamVjdGlvbi90aWxlX3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQgdHlwZSBQcm9qZWN0aW9uIGZyb20gJy4uL2dlby9wcm9qZWN0aW9uL3Byb2plY3Rpb24uanMnO1xuaW1wb3J0IHR5cGUge0J1Y2tldH0gZnJvbSAnLi4vZGF0YS9idWNrZXQuanMnO1xuaW1wb3J0IHR5cGUgQWN0b3IgZnJvbSAnLi4vdXRpbC9hY3Rvci5qcyc7XG5pbXBvcnQgdHlwZSBTdHlsZUxheWVyIGZyb20gJy4uL3N0eWxlL3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCB0eXBlIFN0eWxlTGF5ZXJJbmRleCBmcm9tICcuLi9zdHlsZS9zdHlsZV9sYXllcl9pbmRleC5qcyc7XG5pbXBvcnQgdHlwZSB7U3R5bGVJbWFnZX0gZnJvbSAnLi4vc3R5bGUvc3R5bGVfaW1hZ2UuanMnO1xuaW1wb3J0IHR5cGUge1N0eWxlR2x5cGh9IGZyb20gJy4uL3N0eWxlL3N0eWxlX2dseXBoLmpzJztcbmltcG9ydCB0eXBlIHtTcHJpdGVQb3NpdGlvbnN9IGZyb20gJy4uL3V0aWwvaW1hZ2UuanMnO1xuaW1wb3J0IHR5cGUge1xuICAgIFdvcmtlclRpbGVQYXJhbWV0ZXJzLFxuICAgIFdvcmtlclRpbGVDYWxsYmFjayxcbn0gZnJvbSAnLi4vc291cmNlL3dvcmtlcl9zb3VyY2UuanMnO1xuaW1wb3J0IHR5cGUge1Byb21vdGVJZFNwZWNpZmljYXRpb259IGZyb20gJy4uL3N0eWxlLXNwZWMvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge1RpbGVUcmFuc2Zvcm19IGZyb20gJy4uL2dlby9wcm9qZWN0aW9uL3RpbGVfdHJhbnNmb3JtLmpzJztcbmltcG9ydCB0eXBlIHtJVmVjdG9yVGlsZX0gZnJvbSAnQG1hcGJveC92ZWN0b3ItdGlsZSc7XG5cbmNsYXNzIFdvcmtlclRpbGUge1xuICAgIHRpbGVJRDogT3ZlcnNjYWxlZFRpbGVJRDtcbiAgICB1aWQ6IG51bWJlcjtcbiAgICB6b29tOiBudW1iZXI7XG4gICAgdGlsZVpvb206IG51bWJlcjtcbiAgICBjYW5vbmljYWw6IENhbm9uaWNhbFRpbGVJRDtcbiAgICBwaXhlbFJhdGlvOiBudW1iZXI7XG4gICAgdGlsZVNpemU6IG51bWJlcjtcbiAgICBzb3VyY2U6IHN0cmluZztcbiAgICBwcm9tb3RlSWQ6ID9Qcm9tb3RlSWRTcGVjaWZpY2F0aW9uO1xuICAgIG92ZXJzY2FsaW5nOiBudW1iZXI7XG4gICAgc2hvd0NvbGxpc2lvbkJveGVzOiBib29sZWFuO1xuICAgIGNvbGxlY3RSZXNvdXJjZVRpbWluZzogYm9vbGVhbjtcbiAgICByZXR1cm5EZXBlbmRlbmNpZXM6IGJvb2xlYW47XG4gICAgZW5hYmxlVGVycmFpbjogYm9vbGVhbjtcbiAgICBpc1N5bWJvbFRpbGU6ID9ib29sZWFuO1xuICAgIHByb2plY3Rpb246IFByb2plY3Rpb247XG4gICAgdGlsZVRyYW5zZm9ybTogVGlsZVRyYW5zZm9ybTtcblxuICAgIHN0YXR1czogJ3BhcnNpbmcnIHwgJ2RvbmUnO1xuICAgIGRhdGE6IElWZWN0b3JUaWxlO1xuICAgIGNvbGxpc2lvbkJveEFycmF5OiBDb2xsaXNpb25Cb3hBcnJheTtcblxuICAgIGFib3J0OiA/KCkgPT4gdm9pZDtcbiAgICByZWxvYWRDYWxsYmFjazogP1dvcmtlclRpbGVDYWxsYmFjaztcbiAgICB2ZWN0b3JUaWxlOiBJVmVjdG9yVGlsZTtcblxuICAgIGNvbnN0cnVjdG9yKHBhcmFtczogV29ya2VyVGlsZVBhcmFtZXRlcnMpIHtcbiAgICAgICAgdGhpcy50aWxlSUQgPSBuZXcgT3ZlcnNjYWxlZFRpbGVJRChwYXJhbXMudGlsZUlELm92ZXJzY2FsZWRaLCBwYXJhbXMudGlsZUlELndyYXAsIHBhcmFtcy50aWxlSUQuY2Fub25pY2FsLnosIHBhcmFtcy50aWxlSUQuY2Fub25pY2FsLngsIHBhcmFtcy50aWxlSUQuY2Fub25pY2FsLnkpO1xuICAgICAgICB0aGlzLnRpbGVab29tID0gcGFyYW1zLnRpbGVab29tO1xuICAgICAgICB0aGlzLnVpZCA9IHBhcmFtcy51aWQ7XG4gICAgICAgIHRoaXMuem9vbSA9IHBhcmFtcy56b29tO1xuICAgICAgICB0aGlzLmNhbm9uaWNhbCA9IHBhcmFtcy50aWxlSUQuY2Fub25pY2FsO1xuICAgICAgICB0aGlzLnBpeGVsUmF0aW8gPSBwYXJhbXMucGl4ZWxSYXRpbztcbiAgICAgICAgdGhpcy50aWxlU2l6ZSA9IHBhcmFtcy50aWxlU2l6ZTtcbiAgICAgICAgdGhpcy5zb3VyY2UgPSBwYXJhbXMuc291cmNlO1xuICAgICAgICB0aGlzLm92ZXJzY2FsaW5nID0gdGhpcy50aWxlSUQub3ZlcnNjYWxlRmFjdG9yKCk7XG4gICAgICAgIHRoaXMuc2hvd0NvbGxpc2lvbkJveGVzID0gcGFyYW1zLnNob3dDb2xsaXNpb25Cb3hlcztcbiAgICAgICAgdGhpcy5jb2xsZWN0UmVzb3VyY2VUaW1pbmcgPSAhIXBhcmFtcy5jb2xsZWN0UmVzb3VyY2VUaW1pbmc7XG4gICAgICAgIHRoaXMucmV0dXJuRGVwZW5kZW5jaWVzID0gISFwYXJhbXMucmV0dXJuRGVwZW5kZW5jaWVzO1xuICAgICAgICB0aGlzLnByb21vdGVJZCA9IHBhcmFtcy5wcm9tb3RlSWQ7XG4gICAgICAgIHRoaXMuZW5hYmxlVGVycmFpbiA9ICEhcGFyYW1zLmVuYWJsZVRlcnJhaW47XG4gICAgICAgIHRoaXMuaXNTeW1ib2xUaWxlID0gcGFyYW1zLmlzU3ltYm9sVGlsZTtcbiAgICAgICAgdGhpcy50aWxlVHJhbnNmb3JtID0gdGlsZVRyYW5zZm9ybShwYXJhbXMudGlsZUlELmNhbm9uaWNhbCwgcGFyYW1zLnByb2plY3Rpb24pO1xuICAgICAgICB0aGlzLnByb2plY3Rpb24gPSBwYXJhbXMucHJvamVjdGlvbjtcbiAgICB9XG5cbiAgICBwYXJzZShkYXRhOiBJVmVjdG9yVGlsZSwgbGF5ZXJJbmRleDogU3R5bGVMYXllckluZGV4LCBhdmFpbGFibGVJbWFnZXM6IEFycmF5PHN0cmluZz4sIGFjdG9yOiBBY3RvciwgY2FsbGJhY2s6IFdvcmtlclRpbGVDYWxsYmFjaykge1xuICAgICAgICBjb25zdCBtID0gUGVyZm9ybWFuY2VVdGlscy5iZWdpbk1lYXN1cmUoJ3BhcnNlVGlsZTEnKTtcbiAgICAgICAgdGhpcy5zdGF0dXMgPSAncGFyc2luZyc7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XG5cbiAgICAgICAgdGhpcy5jb2xsaXNpb25Cb3hBcnJheSA9IG5ldyBDb2xsaXNpb25Cb3hBcnJheSgpO1xuICAgICAgICBjb25zdCBzb3VyY2VMYXllckNvZGVyID0gbmV3IERpY3Rpb25hcnlDb2RlcihPYmplY3Qua2V5cyhkYXRhLmxheWVycykuc29ydCgpKTtcblxuICAgICAgICBjb25zdCBmZWF0dXJlSW5kZXggPSBuZXcgRmVhdHVyZUluZGV4KHRoaXMudGlsZUlELCB0aGlzLnByb21vdGVJZCk7XG4gICAgICAgIGZlYXR1cmVJbmRleC5idWNrZXRMYXllcklEcyA9IFtdO1xuXG4gICAgICAgIGNvbnN0IGJ1Y2tldHM6IHtbXzogc3RyaW5nXTogQnVja2V0fSA9IHt9O1xuXG4gICAgICAgIC8vIHdlIGluaXRpYWxseSByZXNlcnZlIHNwYWNlIGZvciBhIDI1NngyNTYgYXRsYXMsIGJ1dCB0cmltIGl0IGFmdGVyIHByb2Nlc3NpbmcgYWxsIGxpbmUgZmVhdHVyZXNcbiAgICAgICAgY29uc3QgbGluZUF0bGFzID0gbmV3IExpbmVBdGxhcygyNTYsIDI1Nik7XG5cbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgIGZlYXR1cmVJbmRleCxcbiAgICAgICAgICAgIGljb25EZXBlbmRlbmNpZXM6IHt9LFxuICAgICAgICAgICAgcGF0dGVybkRlcGVuZGVuY2llczoge30sXG4gICAgICAgICAgICBnbHlwaERlcGVuZGVuY2llczoge30sXG4gICAgICAgICAgICBsaW5lQXRsYXMsXG4gICAgICAgICAgICBhdmFpbGFibGVJbWFnZXNcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBsYXllckZhbWlsaWVzID0gbGF5ZXJJbmRleC5mYW1pbGllc0J5U291cmNlW3RoaXMuc291cmNlXTtcbiAgICAgICAgZm9yIChjb25zdCBzb3VyY2VMYXllcklkIGluIGxheWVyRmFtaWxpZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHNvdXJjZUxheWVyID0gZGF0YS5sYXllcnNbc291cmNlTGF5ZXJJZF07XG4gICAgICAgICAgICBpZiAoIXNvdXJjZUxheWVyKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBhbnlTeW1ib2xMYXllcnMgPSBmYWxzZTtcbiAgICAgICAgICAgIGxldCBhbnlPdGhlckxheWVycyA9IGZhbHNlO1xuICAgICAgICAgICAgZm9yIChjb25zdCBmYW1pbHkgb2YgbGF5ZXJGYW1pbGllc1tzb3VyY2VMYXllcklkXSkge1xuICAgICAgICAgICAgICAgIGlmIChmYW1pbHlbMF0udHlwZSA9PT0gJ3N5bWJvbCcpIHtcbiAgICAgICAgICAgICAgICAgICAgYW55U3ltYm9sTGF5ZXJzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBhbnlPdGhlckxheWVycyA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5pc1N5bWJvbFRpbGUgPT09IHRydWUgJiYgIWFueVN5bWJvbExheWVycykge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmlzU3ltYm9sVGlsZSA9PT0gZmFsc2UgJiYgIWFueU90aGVyTGF5ZXJzKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChzb3VyY2VMYXllci52ZXJzaW9uID09PSAxKSB7XG4gICAgICAgICAgICAgICAgd2Fybk9uY2UoYFZlY3RvciB0aWxlIHNvdXJjZSBcIiR7dGhpcy5zb3VyY2V9XCIgbGF5ZXIgXCIke3NvdXJjZUxheWVySWR9XCIgYCArXG4gICAgICAgICAgICAgICAgICAgIGBkb2VzIG5vdCB1c2UgdmVjdG9yIHRpbGUgc3BlYyB2MiBhbmQgdGhlcmVmb3JlIG1heSBoYXZlIHNvbWUgcmVuZGVyaW5nIGVycm9ycy5gKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3Qgc291cmNlTGF5ZXJJbmRleCA9IHNvdXJjZUxheWVyQ29kZXIuZW5jb2RlKHNvdXJjZUxheWVySWQpO1xuICAgICAgICAgICAgY29uc3QgZmVhdHVyZXMgPSBbXTtcbiAgICAgICAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBzb3VyY2VMYXllci5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmZWF0dXJlID0gc291cmNlTGF5ZXIuZmVhdHVyZShpbmRleCk7XG4gICAgICAgICAgICAgICAgY29uc3QgaWQgPSBmZWF0dXJlSW5kZXguZ2V0SWQoZmVhdHVyZSwgc291cmNlTGF5ZXJJZCk7XG4gICAgICAgICAgICAgICAgZmVhdHVyZXMucHVzaCh7ZmVhdHVyZSwgaWQsIGluZGV4LCBzb3VyY2VMYXllckluZGV4fSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAoY29uc3QgZmFtaWx5IG9mIGxheWVyRmFtaWxpZXNbc291cmNlTGF5ZXJJZF0pIHtcbiAgICAgICAgICAgICAgICBjb25zdCBsYXllciA9IGZhbWlseVswXTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1N5bWJvbFRpbGUgIT09IHVuZGVmaW5lZCAmJiAobGF5ZXIudHlwZSA9PT0gJ3N5bWJvbCcpICE9PSB0aGlzLmlzU3ltYm9sVGlsZSkgY29udGludWU7XG5cbiAgICAgICAgICAgICAgICBhc3NlcnQobGF5ZXIuc291cmNlID09PSB0aGlzLnNvdXJjZSk7XG4gICAgICAgICAgICAgICAgaWYgKGxheWVyLm1pbnpvb20gJiYgdGhpcy56b29tIDwgTWF0aC5mbG9vcihsYXllci5taW56b29tKSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgaWYgKGxheWVyLm1heHpvb20gJiYgdGhpcy56b29tID49IGxheWVyLm1heHpvb20pIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIGlmIChsYXllci52aXNpYmlsaXR5ID09PSAnbm9uZScpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICAgICAgcmVjYWxjdWxhdGVMYXllcnMoZmFtaWx5LCB0aGlzLnpvb20sIGF2YWlsYWJsZUltYWdlcyk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBidWNrZXQgPSBidWNrZXRzW2xheWVyLmlkXSA9IGxheWVyLmNyZWF0ZUJ1Y2tldCh7XG4gICAgICAgICAgICAgICAgICAgIGluZGV4OiBmZWF0dXJlSW5kZXguYnVja2V0TGF5ZXJJRHMubGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW2luY29tcGF0aWJsZS1jYWxsXSAtIEZsb3cgY2FuJ3QgaW5mZXIgcHJvcGVyIGBmYW1pbHlgIHR5cGUgZnJvbSBgbGF5ZXJgIGFib3ZlXG4gICAgICAgICAgICAgICAgICAgIGxheWVyczogZmFtaWx5LFxuICAgICAgICAgICAgICAgICAgICB6b29tOiB0aGlzLnpvb20sXG4gICAgICAgICAgICAgICAgICAgIGNhbm9uaWNhbDogdGhpcy5jYW5vbmljYWwsXG4gICAgICAgICAgICAgICAgICAgIHBpeGVsUmF0aW86IHRoaXMucGl4ZWxSYXRpbyxcbiAgICAgICAgICAgICAgICAgICAgb3ZlcnNjYWxpbmc6IHRoaXMub3ZlcnNjYWxpbmcsXG4gICAgICAgICAgICAgICAgICAgIGNvbGxpc2lvbkJveEFycmF5OiB0aGlzLmNvbGxpc2lvbkJveEFycmF5LFxuICAgICAgICAgICAgICAgICAgICBzb3VyY2VMYXllckluZGV4LFxuICAgICAgICAgICAgICAgICAgICBzb3VyY2VJRDogdGhpcy5zb3VyY2UsXG4gICAgICAgICAgICAgICAgICAgIGVuYWJsZVRlcnJhaW46IHRoaXMuZW5hYmxlVGVycmFpbixcbiAgICAgICAgICAgICAgICAgICAgcHJvamVjdGlvbjogdGhpcy5wcm9qZWN0aW9uLnNwZWMsXG4gICAgICAgICAgICAgICAgICAgIGF2YWlsYWJsZUltYWdlc1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgYXNzZXJ0KHRoaXMudGlsZVRyYW5zZm9ybS5wcm9qZWN0aW9uLm5hbWUgPT09IHRoaXMucHJvamVjdGlvbi5uYW1lKTtcbiAgICAgICAgICAgICAgICBidWNrZXQucG9wdWxhdGUoZmVhdHVyZXMsIG9wdGlvbnMsIHRoaXMudGlsZUlELmNhbm9uaWNhbCwgdGhpcy50aWxlVHJhbnNmb3JtKTtcbiAgICAgICAgICAgICAgICBmZWF0dXJlSW5kZXguYnVja2V0TGF5ZXJJRHMucHVzaChmYW1pbHkubWFwKChsKSA9PiBsLmlkKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBsaW5lQXRsYXMudHJpbSgpO1xuXG4gICAgICAgIGxldCBlcnJvcjogP0Vycm9yO1xuICAgICAgICBsZXQgZ2x5cGhNYXA6IHtbXzogc3RyaW5nXToge2dseXBoczoge1tfOiBudW1iZXJdOiA/U3R5bGVHbHlwaH0sIGFzY2VuZGVyPzogbnVtYmVyLCBkZXNjZW5kZXI/OiBudW1iZXJ9fTtcbiAgICAgICAgbGV0IGljb25NYXA6IHtbXzogc3RyaW5nXTogU3R5bGVJbWFnZX07XG4gICAgICAgIGxldCBwYXR0ZXJuTWFwOiB7W186IHN0cmluZ106IFN0eWxlSW1hZ2V9O1xuICAgICAgICBjb25zdCB0YXNrTWV0YWRhdGEgPSB7dHlwZTogJ21heWJlUHJlcGFyZScsIGlzU3ltYm9sVGlsZTogdGhpcy5pc1N5bWJvbFRpbGUsIHpvb206IHRoaXMuem9vbX07XG5cbiAgICAgICAgY29uc3QgbWF5YmVQcmVwYXJlID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycm9yKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZ2x5cGhNYXAgJiYgaWNvbk1hcCAmJiBwYXR0ZXJuTWFwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbSA9IFBlcmZvcm1hbmNlVXRpbHMuYmVnaW5NZWFzdXJlKCdwYXJzZVRpbGUyJyk7XG4gICAgICAgICAgICAgICAgY29uc3QgZ2x5cGhBdGxhcyA9IG5ldyBHbHlwaEF0bGFzKGdseXBoTWFwKTtcbiAgICAgICAgICAgICAgICBjb25zdCBpbWFnZUF0bGFzID0gbmV3IEltYWdlQXRsYXMoaWNvbk1hcCwgcGF0dGVybk1hcCk7XG5cbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBidWNrZXRzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGJ1Y2tldCA9IGJ1Y2tldHNba2V5XTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGJ1Y2tldCBpbnN0YW5jZW9mIFN5bWJvbEJ1Y2tldCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVjYWxjdWxhdGVMYXllcnMoYnVja2V0LmxheWVycywgdGhpcy56b29tLCBhdmFpbGFibGVJbWFnZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcGVyZm9ybVN5bWJvbExheW91dChidWNrZXQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2x5cGhNYXAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2x5cGhBdGxhcy5wb3NpdGlvbnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWNvbk1hcCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbWFnZUF0bGFzLmljb25Qb3NpdGlvbnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zaG93Q29sbGlzaW9uQm94ZXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXZhaWxhYmxlSW1hZ2VzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudGlsZUlELmNhbm9uaWNhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRpbGVab29tLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJvamVjdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYnVja2V0Lmhhc1BhdHRlcm4gJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIChidWNrZXQgaW5zdGFuY2VvZiBMaW5lQnVja2V0IHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgYnVja2V0IGluc3RhbmNlb2YgRmlsbEJ1Y2tldCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgIGJ1Y2tldCBpbnN0YW5jZW9mIEZpbGxFeHRydXNpb25CdWNrZXQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWNhbGN1bGF0ZUxheWVycyhidWNrZXQubGF5ZXJzLCB0aGlzLnpvb20sIGF2YWlsYWJsZUltYWdlcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW2luY29tcGF0aWJsZS10eXBlXSBGbG93IGNhbid0IGludGVycHJldCBJbWFnZVBvc2l0aW9uIGFzIFNwcml0ZVBvc2l0aW9uIGZvciBzb21lIHJlYXNvbiBoZXJlXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbWFnZVBvc2l0aW9uczogU3ByaXRlUG9zaXRpb25zID0gaW1hZ2VBdGxhcy5wYXR0ZXJuUG9zaXRpb25zO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnVja2V0LmFkZEZlYXR1cmVzKG9wdGlvbnMsIHRoaXMudGlsZUlELmNhbm9uaWNhbCwgaW1hZ2VQb3NpdGlvbnMsIGF2YWlsYWJsZUltYWdlcywgdGhpcy50aWxlVHJhbnNmb3JtKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMuc3RhdHVzID0gJ2RvbmUnO1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIHtcbiAgICAgICAgICAgICAgICAgICAgYnVja2V0czogdmFsdWVzKGJ1Y2tldHMpLmZpbHRlcihiID0+ICFiLmlzRW1wdHkoKSksXG4gICAgICAgICAgICAgICAgICAgIGZlYXR1cmVJbmRleCxcbiAgICAgICAgICAgICAgICAgICAgY29sbGlzaW9uQm94QXJyYXk6IHRoaXMuY29sbGlzaW9uQm94QXJyYXksXG4gICAgICAgICAgICAgICAgICAgIGdseXBoQXRsYXNJbWFnZTogZ2x5cGhBdGxhcy5pbWFnZSxcbiAgICAgICAgICAgICAgICAgICAgbGluZUF0bGFzLFxuICAgICAgICAgICAgICAgICAgICBpbWFnZUF0bGFzLFxuICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IHVzZWQgZm9yIGJlbmNobWFya2luZzpcbiAgICAgICAgICAgICAgICAgICAgZ2x5cGhNYXA6IHRoaXMucmV0dXJuRGVwZW5kZW5jaWVzID8gZ2x5cGhNYXAgOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICBpY29uTWFwOiB0aGlzLnJldHVybkRlcGVuZGVuY2llcyA/IGljb25NYXAgOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICBnbHlwaFBvc2l0aW9uczogdGhpcy5yZXR1cm5EZXBlbmRlbmNpZXMgPyBnbHlwaEF0bGFzLnBvc2l0aW9ucyA6IG51bGxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBQZXJmb3JtYW5jZVV0aWxzLmVuZE1lYXN1cmUobSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3Qgc3RhY2tzID0gbWFwT2JqZWN0KG9wdGlvbnMuZ2x5cGhEZXBlbmRlbmNpZXMsIChnbHlwaHMpID0+IE9iamVjdC5rZXlzKGdseXBocykubWFwKE51bWJlcikpO1xuICAgICAgICBpZiAoT2JqZWN0LmtleXMoc3RhY2tzKS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGFjdG9yLnNlbmQoJ2dldEdseXBocycsIHt1aWQ6IHRoaXMudWlkLCBzdGFja3N9LCAoZXJyLCByZXN1bHQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yID0gZXJyO1xuICAgICAgICAgICAgICAgICAgICBnbHlwaE1hcCA9IHJlc3VsdDtcbiAgICAgICAgICAgICAgICAgICAgbWF5YmVQcmVwYXJlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgdW5kZWZpbmVkLCBmYWxzZSwgdGFza01ldGFkYXRhKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdseXBoTWFwID0ge307XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBpY29ucyA9IE9iamVjdC5rZXlzKG9wdGlvbnMuaWNvbkRlcGVuZGVuY2llcyk7XG4gICAgICAgIGlmIChpY29ucy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGFjdG9yLnNlbmQoJ2dldEltYWdlcycsIHtpY29ucywgc291cmNlOiB0aGlzLnNvdXJjZSwgdGlsZUlEOiB0aGlzLnRpbGVJRCwgdHlwZTogJ2ljb25zJ30sIChlcnIsIHJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBlcnI7XG4gICAgICAgICAgICAgICAgICAgIGljb25NYXAgPSByZXN1bHQ7XG4gICAgICAgICAgICAgICAgICAgIG1heWJlUHJlcGFyZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sIHVuZGVmaW5lZCwgZmFsc2UsIHRhc2tNZXRhZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpY29uTWFwID0ge307XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwYXR0ZXJucyA9IE9iamVjdC5rZXlzKG9wdGlvbnMucGF0dGVybkRlcGVuZGVuY2llcyk7XG4gICAgICAgIGlmIChwYXR0ZXJucy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGFjdG9yLnNlbmQoJ2dldEltYWdlcycsIHtpY29uczogcGF0dGVybnMsIHNvdXJjZTogdGhpcy5zb3VyY2UsIHRpbGVJRDogdGhpcy50aWxlSUQsIHR5cGU6ICdwYXR0ZXJucyd9LCAoZXJyLCByZXN1bHQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yID0gZXJyO1xuICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuTWFwID0gcmVzdWx0O1xuICAgICAgICAgICAgICAgICAgICBtYXliZVByZXBhcmUoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LCB1bmRlZmluZWQsIGZhbHNlLCB0YXNrTWV0YWRhdGEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGF0dGVybk1hcCA9IHt9O1xuICAgICAgICB9XG5cbiAgICAgICAgUGVyZm9ybWFuY2VVdGlscy5lbmRNZWFzdXJlKG0pO1xuXG4gICAgICAgIG1heWJlUHJlcGFyZSgpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gcmVjYWxjdWxhdGVMYXllcnMobGF5ZXJzOiAkUmVhZE9ubHlBcnJheTxTdHlsZUxheWVyPiwgem9vbTogbnVtYmVyLCBhdmFpbGFibGVJbWFnZXM6IEFycmF5PHN0cmluZz4pIHtcbiAgICAvLyBMYXllcnMgYXJlIHNoYXJlZCBhbmQgbWF5IGhhdmUgYmVlbiB1c2VkIGJ5IGEgV29ya2VyVGlsZSB3aXRoIGEgZGlmZmVyZW50IHpvb20uXG4gICAgY29uc3QgcGFyYW1ldGVycyA9IG5ldyBFdmFsdWF0aW9uUGFyYW1ldGVycyh6b29tKTtcbiAgICBmb3IgKGNvbnN0IGxheWVyIG9mIGxheWVycykge1xuICAgICAgICBsYXllci5yZWNhbGN1bGF0ZShwYXJhbWV0ZXJzLCBhdmFpbGFibGVJbWFnZXMpO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgV29ya2VyVGlsZTtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCB7Z2V0QXJyYXlCdWZmZXJ9IGZyb20gJy4uL3V0aWwvYWpheC5qcyc7XG5cbmltcG9ydCB7VmVjdG9yVGlsZX0gZnJvbSAnQG1hcGJveC92ZWN0b3ItdGlsZSc7XG5pbXBvcnQgUHJvdG9idWYgZnJvbSAncGJmJztcbmltcG9ydCBXb3JrZXJUaWxlIGZyb20gJy4vd29ya2VyX3RpbGUuanMnO1xuaW1wb3J0IHtleHRlbmR9IGZyb20gJy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQge2dldFBlcmZvcm1hbmNlTWVhc3VyZW1lbnR9IGZyb20gJy4uL3V0aWwvcGVyZm9ybWFuY2UuanMnO1xuaW1wb3J0IHtFdmVudGVkfSBmcm9tICcuLi91dGlsL2V2ZW50ZWQuanMnO1xuaW1wb3J0IHRpbGVUcmFuc2Zvcm0gZnJvbSAnLi4vZ2VvL3Byb2plY3Rpb24vdGlsZV90cmFuc2Zvcm0uanMnO1xuXG5pbXBvcnQgdHlwZSB7XG4gICAgV29ya2VyU291cmNlLFxuICAgIFdvcmtlclRpbGVSZXN1bHQsXG4gICAgV29ya2VyVGlsZVBhcmFtZXRlcnMsXG4gICAgUmVxdWVzdGVkVGlsZVBhcmFtZXRlcnMsXG4gICAgV29ya2VyVGlsZUNhbGxiYWNrLFxuICAgIFRpbGVQYXJhbWV0ZXJzXG59IGZyb20gJy4uL3NvdXJjZS93b3JrZXJfc291cmNlLmpzJztcblxuaW1wb3J0IHR5cGUgQWN0b3IgZnJvbSAnLi4vdXRpbC9hY3Rvci5qcyc7XG5pbXBvcnQgdHlwZSBTdHlsZUxheWVySW5kZXggZnJvbSAnLi4vc3R5bGUvc3R5bGVfbGF5ZXJfaW5kZXguanMnO1xuaW1wb3J0IHR5cGUge0NhbGxiYWNrfSBmcm9tICcuLi90eXBlcy9jYWxsYmFjay5qcyc7XG5pbXBvcnQgdHlwZSBTY2hlZHVsZXIgZnJvbSAnLi4vdXRpbC9zY2hlZHVsZXIuanMnO1xuaW1wb3J0IHR5cGUge0lWZWN0b3JUaWxlfSBmcm9tICdAbWFwYm94L3ZlY3Rvci10aWxlJztcblxuZXhwb3J0IHR5cGUgTG9hZFZlY3RvclRpbGVSZXN1bHQgPSB7XG4gICAgcmF3RGF0YTogQXJyYXlCdWZmZXI7XG4gICAgdmVjdG9yVGlsZT86IElWZWN0b3JUaWxlO1xuICAgIGV4cGlyZXM/OiBhbnk7XG4gICAgY2FjaGVDb250cm9sPzogYW55O1xuICAgIHJlc291cmNlVGltaW5nPzogQXJyYXk8UGVyZm9ybWFuY2VSZXNvdXJjZVRpbWluZz47XG59O1xuXG4vKipcbiAqIEBjYWxsYmFjayBMb2FkVmVjdG9yRGF0YUNhbGxiYWNrXG4gKiBAcGFyYW0gZXJyb3JcbiAqIEBwYXJhbSB2ZWN0b3JUaWxlXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgdHlwZSBMb2FkVmVjdG9yRGF0YUNhbGxiYWNrID0gQ2FsbGJhY2s8P0xvYWRWZWN0b3JUaWxlUmVzdWx0PjtcblxuZXhwb3J0IHR5cGUgQWJvcnRWZWN0b3JEYXRhID0gKCkgPT4gdm9pZDtcbmV4cG9ydCB0eXBlIExvYWRWZWN0b3JEYXRhID0gKHBhcmFtczogUmVxdWVzdGVkVGlsZVBhcmFtZXRlcnMsIGNhbGxiYWNrOiBMb2FkVmVjdG9yRGF0YUNhbGxiYWNrKSA9PiA/QWJvcnRWZWN0b3JEYXRhO1xuZXhwb3J0IGNsYXNzIERlZHVwZWRSZXF1ZXN0IHtcbiAgICBlbnRyaWVzOiB7IFtzdHJpbmddOiBPYmplY3QgfTtcbiAgICBzY2hlZHVsZXI6ID9TY2hlZHVsZXI7XG5cbiAgICBjb25zdHJ1Y3RvcihzY2hlZHVsZXI/OiBTY2hlZHVsZXIpIHtcbiAgICAgICAgdGhpcy5lbnRyaWVzID0ge307XG4gICAgICAgIHRoaXMuc2NoZWR1bGVyID0gc2NoZWR1bGVyO1xuICAgIH1cblxuICAgIHJlcXVlc3Qoa2V5OiBzdHJpbmcsIG1ldGFkYXRhOiBPYmplY3QsIHJlcXVlc3Q6IGFueSwgY2FsbGJhY2s6IExvYWRWZWN0b3JEYXRhQ2FsbGJhY2spOiAoKCkgPT4gdm9pZCkge1xuICAgICAgICBjb25zdCBlbnRyeSA9IHRoaXMuZW50cmllc1trZXldID0gdGhpcy5lbnRyaWVzW2tleV0gfHwge2NhbGxiYWNrczogW119O1xuXG4gICAgICAgIGlmIChlbnRyeS5yZXN1bHQpIHtcbiAgICAgICAgICAgIGNvbnN0IFtlcnIsIHJlc3VsdF0gPSBlbnRyeS5yZXN1bHQ7XG4gICAgICAgICAgICBpZiAodGhpcy5zY2hlZHVsZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNjaGVkdWxlci5hZGQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnIsIHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgfSwgbWV0YWRhdGEpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnIsIHJlc3VsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gKCkgPT4ge307XG4gICAgICAgIH1cblxuICAgICAgICBlbnRyeS5jYWxsYmFja3MucHVzaChjYWxsYmFjayk7XG5cbiAgICAgICAgaWYgKCFlbnRyeS5jYW5jZWwpIHtcbiAgICAgICAgICAgIGVudHJ5LmNhbmNlbCA9IHJlcXVlc3QoKGVyciwgcmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgZW50cnkucmVzdWx0ID0gW2VyciwgcmVzdWx0XTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGNiIG9mIGVudHJ5LmNhbGxiYWNrcykge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zY2hlZHVsZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2NoZWR1bGVyLmFkZCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2IoZXJyLCByZXN1bHQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSwgbWV0YWRhdGEpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2IoZXJyLCByZXN1bHQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gZGVsZXRlIHRoaXMuZW50cmllc1trZXldLCAxMDAwICogMyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoZW50cnkucmVzdWx0KSByZXR1cm47XG4gICAgICAgICAgICBlbnRyeS5jYWxsYmFja3MgPSBlbnRyeS5jYWxsYmFja3MuZmlsdGVyKGNiID0+IGNiICE9PSBjYWxsYmFjayk7XG4gICAgICAgICAgICBpZiAoIWVudHJ5LmNhbGxiYWNrcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBlbnRyeS5jYW5jZWwoKTtcbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5lbnRyaWVzW2tleV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbi8vICRGbG93Rml4TWVbbWlzc2luZy10aGlzLWFubm90XVxuZXhwb3J0IGZ1bmN0aW9uIGxvYWRWZWN0b3JUaWxlKHBhcmFtczogUmVxdWVzdGVkVGlsZVBhcmFtZXRlcnMsIGNhbGxiYWNrOiBMb2FkVmVjdG9yRGF0YUNhbGxiYWNrLCBza2lwUGFyc2U/OiBib29sZWFuKTogKCgpID0+IHZvaWQpIHtcbiAgICBjb25zdCBrZXkgPSBKU09OLnN0cmluZ2lmeShwYXJhbXMucmVxdWVzdCk7XG5cbiAgICBjb25zdCBtYWtlUmVxdWVzdCA9IChjYWxsYmFjazogTG9hZFZlY3RvckRhdGFDYWxsYmFjaykgPT4ge1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gZ2V0QXJyYXlCdWZmZXIocGFyYW1zLnJlcXVlc3QsIChlcnI6ID9FcnJvciwgZGF0YTogP0FycmF5QnVmZmVyLCBjYWNoZUNvbnRyb2w6ID9zdHJpbmcsIGV4cGlyZXM6ID9zdHJpbmcpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnIpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwge1xuICAgICAgICAgICAgICAgICAgICB2ZWN0b3JUaWxlOiBza2lwUGFyc2UgPyB1bmRlZmluZWQgOiBuZXcgVmVjdG9yVGlsZShuZXcgUHJvdG9idWYoZGF0YSkpLFxuICAgICAgICAgICAgICAgICAgICByYXdEYXRhOiBkYXRhLFxuICAgICAgICAgICAgICAgICAgICBjYWNoZUNvbnRyb2wsXG4gICAgICAgICAgICAgICAgICAgIGV4cGlyZXNcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICByZXF1ZXN0LmNhbmNlbCgpO1xuICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgfTtcbiAgICB9O1xuXG4gICAgaWYgKHBhcmFtcy5kYXRhKSB7XG4gICAgICAgIC8vIGlmIHdlIGFscmVhZHkgZ290IHRoZSByZXN1bHQgZWFybGllciAob24gdGhlIG1haW4gdGhyZWFkKSwgcmV0dXJuIGl0IGRpcmVjdGx5XG4gICAgICAgICh0aGlzLmRlZHVwZWQ6IERlZHVwZWRSZXF1ZXN0KS5lbnRyaWVzW2tleV0gPSB7cmVzdWx0OiBbbnVsbCwgcGFyYW1zLmRhdGFdfTtcbiAgICB9XG5cbiAgICBjb25zdCBjYWxsYmFja01ldGFkYXRhID0ge3R5cGU6ICdwYXJzZVRpbGUnLCBpc1N5bWJvbFRpbGU6IHBhcmFtcy5pc1N5bWJvbFRpbGUsIHpvb206IHBhcmFtcy50aWxlWm9vbX07XG4gICAgcmV0dXJuICh0aGlzLmRlZHVwZWQ6IERlZHVwZWRSZXF1ZXN0KS5yZXF1ZXN0KGtleSwgY2FsbGJhY2tNZXRhZGF0YSwgbWFrZVJlcXVlc3QsIGNhbGxiYWNrKTtcbn1cblxuLyoqXG4gKiBUaGUge0BsaW5rIFdvcmtlclNvdXJjZX0gaW1wbGVtZW50YXRpb24gdGhhdCBzdXBwb3J0cyB7QGxpbmsgVmVjdG9yVGlsZVNvdXJjZX0uXG4gKiBUaGlzIGNsYXNzIGlzIGRlc2lnbmVkIHRvIGJlIGVhc2lseSByZXVzZWQgdG8gc3VwcG9ydCBjdXN0b20gc291cmNlIHR5cGVzXG4gKiBmb3IgZGF0YSBmb3JtYXRzIHRoYXQgY2FuIGJlIHBhcnNlZC9jb252ZXJ0ZWQgaW50byBhbiBpbi1tZW1vcnkgVmVjdG9yVGlsZVxuICogcmVwcmVzZW50YXRpb24uICBUbyBkbyBzbywgY3JlYXRlIGl0IHdpdGhcbiAqIGBuZXcgVmVjdG9yVGlsZVdvcmtlclNvdXJjZShhY3Rvciwgc3R5bGVMYXllcnMsIGN1c3RvbUxvYWRWZWN0b3JEYXRhRnVuY3Rpb24pYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5jbGFzcyBWZWN0b3JUaWxlV29ya2VyU291cmNlIGV4dGVuZHMgRXZlbnRlZCBpbXBsZW1lbnRzIFdvcmtlclNvdXJjZSB7XG4gICAgYWN0b3I6IEFjdG9yO1xuICAgIGxheWVySW5kZXg6IFN0eWxlTGF5ZXJJbmRleDtcbiAgICBhdmFpbGFibGVJbWFnZXM6IEFycmF5PHN0cmluZz47XG4gICAgbG9hZFZlY3RvckRhdGE6IExvYWRWZWN0b3JEYXRhO1xuICAgIGxvYWRpbmc6IHtbXzogbnVtYmVyXTogV29ya2VyVGlsZSB9O1xuICAgIGxvYWRlZDoge1tfOiBudW1iZXJdOiBXb3JrZXJUaWxlIH07XG4gICAgZGVkdXBlZDogRGVkdXBlZFJlcXVlc3Q7XG4gICAgaXNTcHJpdGVMb2FkZWQ6IGJvb2xlYW47XG4gICAgc2NoZWR1bGVyOiA/U2NoZWR1bGVyO1xuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIFtsb2FkVmVjdG9yRGF0YV0gT3B0aW9uYWwgbWV0aG9kIGZvciBjdXN0b20gbG9hZGluZyBvZiBhIFZlY3RvclRpbGVcbiAgICAgKiBvYmplY3QgYmFzZWQgb24gcGFyYW1ldGVycyBwYXNzZWQgZnJvbSB0aGUgbWFpbi10aHJlYWQgU291cmNlLiBTZWVcbiAgICAgKiB7QGxpbmsgVmVjdG9yVGlsZVdvcmtlclNvdXJjZSNsb2FkVGlsZX0uIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHNpbXBseVxuICAgICAqIGxvYWRzIHRoZSBwYmYgYXQgYHBhcmFtcy51cmxgLlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoYWN0b3I6IEFjdG9yLCBsYXllckluZGV4OiBTdHlsZUxheWVySW5kZXgsIGF2YWlsYWJsZUltYWdlczogQXJyYXk8c3RyaW5nPiwgaXNTcHJpdGVMb2FkZWQ6IGJvb2xlYW4sIGxvYWRWZWN0b3JEYXRhOiA/TG9hZFZlY3RvckRhdGEpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5hY3RvciA9IGFjdG9yO1xuICAgICAgICB0aGlzLmxheWVySW5kZXggPSBsYXllckluZGV4O1xuICAgICAgICB0aGlzLmF2YWlsYWJsZUltYWdlcyA9IGF2YWlsYWJsZUltYWdlcztcbiAgICAgICAgdGhpcy5sb2FkVmVjdG9yRGF0YSA9IGxvYWRWZWN0b3JEYXRhIHx8IGxvYWRWZWN0b3JUaWxlO1xuICAgICAgICB0aGlzLmxvYWRpbmcgPSB7fTtcbiAgICAgICAgdGhpcy5sb2FkZWQgPSB7fTtcbiAgICAgICAgdGhpcy5kZWR1cGVkID0gbmV3IERlZHVwZWRSZXF1ZXN0KGFjdG9yLnNjaGVkdWxlcik7XG4gICAgICAgIHRoaXMuaXNTcHJpdGVMb2FkZWQgPSBpc1Nwcml0ZUxvYWRlZDtcbiAgICAgICAgdGhpcy5zY2hlZHVsZXIgPSBhY3Rvci5zY2hlZHVsZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW1wbGVtZW50cyB7QGxpbmsgV29ya2VyU291cmNlI2xvYWRUaWxlfS4gRGVsZWdhdGVzIHRvXG4gICAgICoge0BsaW5rIFZlY3RvclRpbGVXb3JrZXJTb3VyY2UjbG9hZFZlY3RvckRhdGF9ICh3aGljaCBieSBkZWZhdWx0IGV4cGVjdHNcbiAgICAgKiBhIGBwYXJhbXMudXJsYCBwcm9wZXJ0eSkgZm9yIGZldGNoaW5nIGFuZCBwcm9kdWNpbmcgYSBWZWN0b3JUaWxlIG9iamVjdC5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIGxvYWRUaWxlKHBhcmFtczogV29ya2VyVGlsZVBhcmFtZXRlcnMsIGNhbGxiYWNrOiBXb3JrZXJUaWxlQ2FsbGJhY2spIHtcbiAgICAgICAgY29uc3QgdWlkID0gcGFyYW1zLnVpZDtcblxuICAgICAgICBjb25zdCByZXF1ZXN0UGFyYW0gPSBwYXJhbXMgJiYgcGFyYW1zLnJlcXVlc3Q7XG4gICAgICAgIGNvbnN0IHBlcmYgPSByZXF1ZXN0UGFyYW0gJiYgcmVxdWVzdFBhcmFtLmNvbGxlY3RSZXNvdXJjZVRpbWluZztcblxuICAgICAgICBjb25zdCB3b3JrZXJUaWxlID0gdGhpcy5sb2FkaW5nW3VpZF0gPSBuZXcgV29ya2VyVGlsZShwYXJhbXMpO1xuICAgICAgICB3b3JrZXJUaWxlLmFib3J0ID0gdGhpcy5sb2FkVmVjdG9yRGF0YShwYXJhbXMsIChlcnIsIHJlc3BvbnNlKSA9PiB7XG5cbiAgICAgICAgICAgIGNvbnN0IGFib3J0ZWQgPSAhdGhpcy5sb2FkaW5nW3VpZF07XG5cbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmxvYWRpbmdbdWlkXTtcblxuICAgICAgICAgICAgaWYgKGFib3J0ZWQgfHwgZXJyIHx8ICFyZXNwb25zZSkge1xuICAgICAgICAgICAgICAgIHdvcmtlclRpbGUuc3RhdHVzID0gJ2RvbmUnO1xuICAgICAgICAgICAgICAgIGlmICghYWJvcnRlZCkgdGhpcy5sb2FkZWRbdWlkXSA9IHdvcmtlclRpbGU7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHJhd1RpbGVEYXRhID0gcmVzcG9uc2UucmF3RGF0YTtcbiAgICAgICAgICAgIGNvbnN0IGNhY2hlQ29udHJvbCA9IHt9O1xuICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmV4cGlyZXMpIGNhY2hlQ29udHJvbC5leHBpcmVzID0gcmVzcG9uc2UuZXhwaXJlcztcbiAgICAgICAgICAgIGlmIChyZXNwb25zZS5jYWNoZUNvbnRyb2wpIGNhY2hlQ29udHJvbC5jYWNoZUNvbnRyb2wgPSByZXNwb25zZS5jYWNoZUNvbnRyb2w7XG5cbiAgICAgICAgICAgIC8vIHJlc3BvbnNlLnZlY3RvclRpbGUgd2lsbCBiZSBwcmVzZW50IGluIHRoZSBHZW9KU09OIHdvcmtlciBjYXNlICh3aGljaCBpbmhlcml0cyBmcm9tIHRoaXMgY2xhc3MpXG4gICAgICAgICAgICAvLyBiZWNhdXNlIHdlIHN0dWIgdGhlIHZlY3RvciB0aWxlIGludGVyZmFjZSBhcm91bmQgSlNPTiBkYXRhIGluc3RlYWQgb2YgcGFyc2luZyBpdCBkaXJlY3RseVxuICAgICAgICAgICAgd29ya2VyVGlsZS52ZWN0b3JUaWxlID0gcmVzcG9uc2UudmVjdG9yVGlsZSB8fCBuZXcgVmVjdG9yVGlsZShuZXcgUHJvdG9idWYocmF3VGlsZURhdGEpKTtcbiAgICAgICAgICAgIGNvbnN0IHBhcnNlVGlsZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICB3b3JrZXJUaWxlLnBhcnNlKHdvcmtlclRpbGUudmVjdG9yVGlsZSwgdGhpcy5sYXllckluZGV4LCB0aGlzLmF2YWlsYWJsZUltYWdlcywgdGhpcy5hY3RvciwgKGVyciwgcmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnIgfHwgIXJlc3VsdCkgcmV0dXJuIGNhbGxiYWNrKGVycik7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzb3VyY2VUaW1pbmcgPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBlcmYpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRyYW5zZmVycmluZyBhIGNvcHkgb2YgcmF3VGlsZURhdGEgYmVjYXVzZSB0aGUgd29ya2VyIG5lZWRzIHRvIHJldGFpbiBpdHMgY29weS5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc291cmNlVGltaW5nRGF0YSA9IGdldFBlcmZvcm1hbmNlTWVhc3VyZW1lbnQocmVxdWVzdFBhcmFtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGl0J3MgbmVjZXNzYXJ5IHRvIGV2YWwgdGhlIHJlc3VsdCBvZiBnZXRFbnRyaWVzQnlOYW1lKCkgaGVyZSB2aWEgcGFyc2Uvc3RyaW5naWZ5XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBsYXRlIGV2YWx1YXRpb24gaW4gdGhlIG1haW4gdGhyZWFkIGNhdXNlcyBUeXBlRXJyb3I6IGlsbGVnYWwgaW52b2NhdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc291cmNlVGltaW5nRGF0YS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb3VyY2VUaW1pbmcucmVzb3VyY2VUaW1pbmcgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHJlc291cmNlVGltaW5nRGF0YSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIGV4dGVuZCh7cmF3VGlsZURhdGE6IHJhd1RpbGVEYXRhLnNsaWNlKDApfSwgcmVzdWx0LCBjYWNoZUNvbnRyb2wsIHJlc291cmNlVGltaW5nKSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAodGhpcy5pc1Nwcml0ZUxvYWRlZCkge1xuICAgICAgICAgICAgICAgIHBhcnNlVGlsZSgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9uY2UoJ2lzU3ByaXRlTG9hZGVkJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zY2hlZHVsZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldGFkYXRhID0ge3R5cGU6ICdwYXJzZVRpbGUnLCBpc1N5bWJvbFRpbGU6IHBhcmFtcy5pc1N5bWJvbFRpbGUsIHpvb206IHBhcmFtcy50aWxlWm9vbX07XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNjaGVkdWxlci5hZGQocGFyc2VUaWxlLCBtZXRhZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJzZVRpbGUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmxvYWRlZCA9IHRoaXMubG9hZGVkIHx8IHt9O1xuICAgICAgICAgICAgdGhpcy5sb2FkZWRbdWlkXSA9IHdvcmtlclRpbGU7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEltcGxlbWVudHMge0BsaW5rIFdvcmtlclNvdXJjZSNyZWxvYWRUaWxlfS5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHJlbG9hZFRpbGUocGFyYW1zOiBXb3JrZXJUaWxlUGFyYW1ldGVycywgY2FsbGJhY2s6IFdvcmtlclRpbGVDYWxsYmFjaykge1xuICAgICAgICBjb25zdCBsb2FkZWQgPSB0aGlzLmxvYWRlZCxcbiAgICAgICAgICAgIHVpZCA9IHBhcmFtcy51aWQsXG4gICAgICAgICAgICB2dFNvdXJjZSA9IHRoaXM7XG4gICAgICAgIGlmIChsb2FkZWQgJiYgbG9hZGVkW3VpZF0pIHtcbiAgICAgICAgICAgIGNvbnN0IHdvcmtlclRpbGUgPSBsb2FkZWRbdWlkXTtcbiAgICAgICAgICAgIHdvcmtlclRpbGUuc2hvd0NvbGxpc2lvbkJveGVzID0gcGFyYW1zLnNob3dDb2xsaXNpb25Cb3hlcztcbiAgICAgICAgICAgIHdvcmtlclRpbGUuZW5hYmxlVGVycmFpbiA9ICEhcGFyYW1zLmVuYWJsZVRlcnJhaW47XG4gICAgICAgICAgICB3b3JrZXJUaWxlLnByb2plY3Rpb24gPSBwYXJhbXMucHJvamVjdGlvbjtcbiAgICAgICAgICAgIHdvcmtlclRpbGUudGlsZVRyYW5zZm9ybSA9IHRpbGVUcmFuc2Zvcm0ocGFyYW1zLnRpbGVJRC5jYW5vbmljYWwsIHBhcmFtcy5wcm9qZWN0aW9uKTtcblxuICAgICAgICAgICAgY29uc3QgZG9uZSA9IChlcnI6ID9FcnJvciwgZGF0YTogP1dvcmtlclRpbGVSZXN1bHQpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCByZWxvYWRDYWxsYmFjayA9IHdvcmtlclRpbGUucmVsb2FkQ2FsbGJhY2s7XG4gICAgICAgICAgICAgICAgaWYgKHJlbG9hZENhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB3b3JrZXJUaWxlLnJlbG9hZENhbGxiYWNrO1xuICAgICAgICAgICAgICAgICAgICB3b3JrZXJUaWxlLnBhcnNlKHdvcmtlclRpbGUudmVjdG9yVGlsZSwgdnRTb3VyY2UubGF5ZXJJbmRleCwgdGhpcy5hdmFpbGFibGVJbWFnZXMsIHZ0U291cmNlLmFjdG9yLCByZWxvYWRDYWxsYmFjayk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKGVyciwgZGF0YSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAod29ya2VyVGlsZS5zdGF0dXMgPT09ICdwYXJzaW5nJykge1xuICAgICAgICAgICAgICAgIHdvcmtlclRpbGUucmVsb2FkQ2FsbGJhY2sgPSBkb25lO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh3b3JrZXJUaWxlLnN0YXR1cyA9PT0gJ2RvbmUnKSB7XG4gICAgICAgICAgICAgICAgLy8gaWYgdGhlcmUgd2FzIG5vIHZlY3RvciB0aWxlIGRhdGEgb24gdGhlIGluaXRpYWwgbG9hZCwgZG9uJ3QgdHJ5IGFuZCByZS1wYXJzZSB0aWxlXG4gICAgICAgICAgICAgICAgaWYgKHdvcmtlclRpbGUudmVjdG9yVGlsZSkge1xuICAgICAgICAgICAgICAgICAgICB3b3JrZXJUaWxlLnBhcnNlKHdvcmtlclRpbGUudmVjdG9yVGlsZSwgdGhpcy5sYXllckluZGV4LCB0aGlzLmF2YWlsYWJsZUltYWdlcywgdGhpcy5hY3RvciwgZG9uZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEltcGxlbWVudHMge0BsaW5rIFdvcmtlclNvdXJjZSNhYm9ydFRpbGV9LlxuICAgICAqXG4gICAgICogQHBhcmFtIHBhcmFtc1xuICAgICAqIEBwYXJhbSBwYXJhbXMudWlkIFRoZSBVSUQgZm9yIHRoaXMgdGlsZS5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIGFib3J0VGlsZShwYXJhbXM6IFRpbGVQYXJhbWV0ZXJzLCBjYWxsYmFjazogV29ya2VyVGlsZUNhbGxiYWNrKSB7XG4gICAgICAgIGNvbnN0IHVpZCA9IHBhcmFtcy51aWQ7XG4gICAgICAgIGNvbnN0IHRpbGUgPSB0aGlzLmxvYWRpbmdbdWlkXTtcbiAgICAgICAgaWYgKHRpbGUpIHtcbiAgICAgICAgICAgIGlmICh0aWxlLmFib3J0KSB0aWxlLmFib3J0KCk7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5sb2FkaW5nW3VpZF07XG4gICAgICAgIH1cbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbXBsZW1lbnRzIHtAbGluayBXb3JrZXJTb3VyY2UjcmVtb3ZlVGlsZX0uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gcGFyYW1zXG4gICAgICogQHBhcmFtIHBhcmFtcy51aWQgVGhlIFVJRCBmb3IgdGhpcyB0aWxlLlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcmVtb3ZlVGlsZShwYXJhbXM6IFRpbGVQYXJhbWV0ZXJzLCBjYWxsYmFjazogV29ya2VyVGlsZUNhbGxiYWNrKSB7XG4gICAgICAgIGNvbnN0IGxvYWRlZCA9IHRoaXMubG9hZGVkLFxuICAgICAgICAgICAgdWlkID0gcGFyYW1zLnVpZDtcbiAgICAgICAgaWYgKGxvYWRlZCAmJiBsb2FkZWRbdWlkXSkge1xuICAgICAgICAgICAgZGVsZXRlIGxvYWRlZFt1aWRdO1xuICAgICAgICB9XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBWZWN0b3JUaWxlV29ya2VyU291cmNlO1xuIiwiLy8gQGZsb3dcbmV4cG9ydCBkZWZhdWx0IFsndHlwZScsICdzb3VyY2UnLCAnc291cmNlLWxheWVyJywgJ21pbnpvb20nLCAnbWF4em9vbScsICdmaWx0ZXInLCAnbGF5b3V0J107XG4iLCJcbmNvbnN0IEFSUkFZX1RZUEVTID0gW1xuICAgIEludDhBcnJheSwgVWludDhBcnJheSwgVWludDhDbGFtcGVkQXJyYXksIEludDE2QXJyYXksIFVpbnQxNkFycmF5LFxuICAgIEludDMyQXJyYXksIFVpbnQzMkFycmF5LCBGbG9hdDMyQXJyYXksIEZsb2F0NjRBcnJheVxuXTtcblxuLyoqIEB0eXBlZGVmIHtJbnQ4QXJyYXlDb25zdHJ1Y3RvciB8IFVpbnQ4QXJyYXlDb25zdHJ1Y3RvciB8IFVpbnQ4Q2xhbXBlZEFycmF5Q29uc3RydWN0b3IgfCBJbnQxNkFycmF5Q29uc3RydWN0b3IgfCBVaW50MTZBcnJheUNvbnN0cnVjdG9yIHwgSW50MzJBcnJheUNvbnN0cnVjdG9yIHwgVWludDMyQXJyYXlDb25zdHJ1Y3RvciB8IEZsb2F0MzJBcnJheUNvbnN0cnVjdG9yIHwgRmxvYXQ2NEFycmF5Q29uc3RydWN0b3J9IFR5cGVkQXJyYXlDb25zdHJ1Y3RvciAqL1xuXG5jb25zdCBWRVJTSU9OID0gMTsgLy8gc2VyaWFsaXplZCBmb3JtYXQgdmVyc2lvblxuY29uc3QgSEVBREVSX1NJWkUgPSA4O1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBLREJ1c2gge1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBpbmRleCBmcm9tIHJhdyBgQXJyYXlCdWZmZXJgIGRhdGEuXG4gICAgICogQHBhcmFtIHtBcnJheUJ1ZmZlcn0gZGF0YVxuICAgICAqL1xuICAgIHN0YXRpYyBmcm9tKGRhdGEpIHtcbiAgICAgICAgaWYgKCEoZGF0YSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdEYXRhIG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YgQXJyYXlCdWZmZXIuJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgW21hZ2ljLCB2ZXJzaW9uQW5kVHlwZV0gPSBuZXcgVWludDhBcnJheShkYXRhLCAwLCAyKTtcbiAgICAgICAgaWYgKG1hZ2ljICE9PSAweGRiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0RhdGEgZG9lcyBub3QgYXBwZWFyIHRvIGJlIGluIGEgS0RCdXNoIGZvcm1hdC4nKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB2ZXJzaW9uID0gdmVyc2lvbkFuZFR5cGUgPj4gNDtcbiAgICAgICAgaWYgKHZlcnNpb24gIT09IFZFUlNJT04pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgR290IHYke3ZlcnNpb259IGRhdGEgd2hlbiBleHBlY3RlZCB2JHtWRVJTSU9OfS5gKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBBcnJheVR5cGUgPSBBUlJBWV9UWVBFU1t2ZXJzaW9uQW5kVHlwZSAmIDB4MGZdO1xuICAgICAgICBpZiAoIUFycmF5VHlwZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnJlY29nbml6ZWQgYXJyYXkgdHlwZS4nKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBbbm9kZVNpemVdID0gbmV3IFVpbnQxNkFycmF5KGRhdGEsIDIsIDEpO1xuICAgICAgICBjb25zdCBbbnVtSXRlbXNdID0gbmV3IFVpbnQzMkFycmF5KGRhdGEsIDQsIDEpO1xuXG4gICAgICAgIHJldHVybiBuZXcgS0RCdXNoKG51bUl0ZW1zLCBub2RlU2l6ZSwgQXJyYXlUeXBlLCBkYXRhKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGluZGV4IHRoYXQgd2lsbCBob2xkIGEgZ2l2ZW4gbnVtYmVyIG9mIGl0ZW1zLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBudW1JdGVtc1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbm9kZVNpemU9NjRdIFNpemUgb2YgdGhlIEtELXRyZWUgbm9kZSAoNjQgYnkgZGVmYXVsdCkuXG4gICAgICogQHBhcmFtIHtUeXBlZEFycmF5Q29uc3RydWN0b3J9IFtBcnJheVR5cGU9RmxvYXQ2NEFycmF5XSBUaGUgYXJyYXkgdHlwZSB1c2VkIGZvciBjb29yZGluYXRlcyBzdG9yYWdlIChgRmxvYXQ2NEFycmF5YCBieSBkZWZhdWx0KS5cbiAgICAgKiBAcGFyYW0ge0FycmF5QnVmZmVyfSBbZGF0YV0gKEZvciBpbnRlcm5hbCB1c2Ugb25seSlcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihudW1JdGVtcywgbm9kZVNpemUgPSA2NCwgQXJyYXlUeXBlID0gRmxvYXQ2NEFycmF5LCBkYXRhKSB7XG4gICAgICAgIGlmIChpc05hTihudW1JdGVtcykgfHwgbnVtSXRlbXMgPCAwKSB0aHJvdyBuZXcgRXJyb3IoYFVucGV4cGVjdGVkIG51bUl0ZW1zIHZhbHVlOiAke251bUl0ZW1zfS5gKTtcblxuICAgICAgICB0aGlzLm51bUl0ZW1zID0gK251bUl0ZW1zO1xuICAgICAgICB0aGlzLm5vZGVTaXplID0gTWF0aC5taW4oTWF0aC5tYXgoK25vZGVTaXplLCAyKSwgNjU1MzUpO1xuICAgICAgICB0aGlzLkFycmF5VHlwZSA9IEFycmF5VHlwZTtcbiAgICAgICAgdGhpcy5JbmRleEFycmF5VHlwZSA9IG51bUl0ZW1zIDwgNjU1MzYgPyBVaW50MTZBcnJheSA6IFVpbnQzMkFycmF5O1xuXG4gICAgICAgIGNvbnN0IGFycmF5VHlwZUluZGV4ID0gQVJSQVlfVFlQRVMuaW5kZXhPZih0aGlzLkFycmF5VHlwZSk7XG4gICAgICAgIGNvbnN0IGNvb3Jkc0J5dGVTaXplID0gbnVtSXRlbXMgKiAyICogdGhpcy5BcnJheVR5cGUuQllURVNfUEVSX0VMRU1FTlQ7XG4gICAgICAgIGNvbnN0IGlkc0J5dGVTaXplID0gbnVtSXRlbXMgKiB0aGlzLkluZGV4QXJyYXlUeXBlLkJZVEVTX1BFUl9FTEVNRU5UO1xuICAgICAgICBjb25zdCBwYWRDb29yZHMgPSAoOCAtIGlkc0J5dGVTaXplICUgOCkgJSA4O1xuXG4gICAgICAgIGlmIChhcnJheVR5cGVJbmRleCA8IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5leHBlY3RlZCB0eXBlZCBhcnJheSBjbGFzczogJHtBcnJheVR5cGV9LmApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRhdGEgJiYgKGRhdGEgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikpIHsgLy8gcmVjb25zdHJ1Y3QgYW4gaW5kZXggZnJvbSBhIGJ1ZmZlclxuICAgICAgICAgICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgICAgICAgICAgIHRoaXMuaWRzID0gbmV3IHRoaXMuSW5kZXhBcnJheVR5cGUodGhpcy5kYXRhLCBIRUFERVJfU0laRSwgbnVtSXRlbXMpO1xuICAgICAgICAgICAgdGhpcy5jb29yZHMgPSBuZXcgdGhpcy5BcnJheVR5cGUodGhpcy5kYXRhLCBIRUFERVJfU0laRSArIGlkc0J5dGVTaXplICsgcGFkQ29vcmRzLCBudW1JdGVtcyAqIDIpO1xuICAgICAgICAgICAgdGhpcy5fcG9zID0gbnVtSXRlbXMgKiAyO1xuICAgICAgICAgICAgdGhpcy5fZmluaXNoZWQgPSB0cnVlO1xuICAgICAgICB9IGVsc2UgeyAvLyBpbml0aWFsaXplIGEgbmV3IGluZGV4XG4gICAgICAgICAgICB0aGlzLmRhdGEgPSBuZXcgQXJyYXlCdWZmZXIoSEVBREVSX1NJWkUgKyBjb29yZHNCeXRlU2l6ZSArIGlkc0J5dGVTaXplICsgcGFkQ29vcmRzKTtcbiAgICAgICAgICAgIHRoaXMuaWRzID0gbmV3IHRoaXMuSW5kZXhBcnJheVR5cGUodGhpcy5kYXRhLCBIRUFERVJfU0laRSwgbnVtSXRlbXMpO1xuICAgICAgICAgICAgdGhpcy5jb29yZHMgPSBuZXcgdGhpcy5BcnJheVR5cGUodGhpcy5kYXRhLCBIRUFERVJfU0laRSArIGlkc0J5dGVTaXplICsgcGFkQ29vcmRzLCBudW1JdGVtcyAqIDIpO1xuICAgICAgICAgICAgdGhpcy5fcG9zID0gMDtcbiAgICAgICAgICAgIHRoaXMuX2ZpbmlzaGVkID0gZmFsc2U7XG5cbiAgICAgICAgICAgIC8vIHNldCBoZWFkZXJcbiAgICAgICAgICAgIG5ldyBVaW50OEFycmF5KHRoaXMuZGF0YSwgMCwgMikuc2V0KFsweGRiLCAoVkVSU0lPTiA8PCA0KSArIGFycmF5VHlwZUluZGV4XSk7XG4gICAgICAgICAgICBuZXcgVWludDE2QXJyYXkodGhpcy5kYXRhLCAyLCAxKVswXSA9IG5vZGVTaXplO1xuICAgICAgICAgICAgbmV3IFVpbnQzMkFycmF5KHRoaXMuZGF0YSwgNCwgMSlbMF0gPSBudW1JdGVtcztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZCBhIHBvaW50IHRvIHRoZSBpbmRleC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0geFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5XG4gICAgICogQHJldHVybnMge251bWJlcn0gQW4gaW5jcmVtZW50YWwgaW5kZXggYXNzb2NpYXRlZCB3aXRoIHRoZSBhZGRlZCBpdGVtIChzdGFydGluZyBmcm9tIGAwYCkuXG4gICAgICovXG4gICAgYWRkKHgsIHkpIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl9wb3MgPj4gMTtcbiAgICAgICAgdGhpcy5pZHNbaW5kZXhdID0gaW5kZXg7XG4gICAgICAgIHRoaXMuY29vcmRzW3RoaXMuX3BvcysrXSA9IHg7XG4gICAgICAgIHRoaXMuY29vcmRzW3RoaXMuX3BvcysrXSA9IHk7XG4gICAgICAgIHJldHVybiBpbmRleDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQZXJmb3JtIGluZGV4aW5nIG9mIHRoZSBhZGRlZCBwb2ludHMuXG4gICAgICovXG4gICAgZmluaXNoKCkge1xuICAgICAgICBjb25zdCBudW1BZGRlZCA9IHRoaXMuX3BvcyA+PiAxO1xuICAgICAgICBpZiAobnVtQWRkZWQgIT09IHRoaXMubnVtSXRlbXMpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQWRkZWQgJHtudW1BZGRlZH0gaXRlbXMgd2hlbiBleHBlY3RlZCAke3RoaXMubnVtSXRlbXN9LmApO1xuICAgICAgICB9XG4gICAgICAgIC8vIGtkLXNvcnQgYm90aCBhcnJheXMgZm9yIGVmZmljaWVudCBzZWFyY2hcbiAgICAgICAgc29ydCh0aGlzLmlkcywgdGhpcy5jb29yZHMsIHRoaXMubm9kZVNpemUsIDAsIHRoaXMubnVtSXRlbXMgLSAxLCAwKTtcblxuICAgICAgICB0aGlzLl9maW5pc2hlZCA9IHRydWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlYXJjaCB0aGUgaW5kZXggZm9yIGl0ZW1zIHdpdGhpbiBhIGdpdmVuIGJvdW5kaW5nIGJveC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbWluWFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBtaW5ZXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG1heFhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbWF4WVxuICAgICAqIEByZXR1cm5zIHtudW1iZXJbXX0gQW4gYXJyYXkgb2YgaW5kaWNlcyBjb3JyZXBvbmRpbmcgdG8gdGhlIGZvdW5kIGl0ZW1zLlxuICAgICAqL1xuICAgIHJhbmdlKG1pblgsIG1pblksIG1heFgsIG1heFkpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9maW5pc2hlZCkgdGhyb3cgbmV3IEVycm9yKCdEYXRhIG5vdCB5ZXQgaW5kZXhlZCAtIGNhbGwgaW5kZXguZmluaXNoKCkuJyk7XG5cbiAgICAgICAgY29uc3Qge2lkcywgY29vcmRzLCBub2RlU2l6ZX0gPSB0aGlzO1xuICAgICAgICBjb25zdCBzdGFjayA9IFswLCBpZHMubGVuZ3RoIC0gMSwgMF07XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuXG4gICAgICAgIC8vIHJlY3Vyc2l2ZWx5IHNlYXJjaCBmb3IgaXRlbXMgaW4gcmFuZ2UgaW4gdGhlIGtkLXNvcnRlZCBhcnJheXNcbiAgICAgICAgd2hpbGUgKHN0YWNrLmxlbmd0aCkge1xuICAgICAgICAgICAgY29uc3QgYXhpcyA9IHN0YWNrLnBvcCgpIHx8IDA7XG4gICAgICAgICAgICBjb25zdCByaWdodCA9IHN0YWNrLnBvcCgpIHx8IDA7XG4gICAgICAgICAgICBjb25zdCBsZWZ0ID0gc3RhY2sucG9wKCkgfHwgMDtcblxuICAgICAgICAgICAgLy8gaWYgd2UgcmVhY2hlZCBcInRyZWUgbm9kZVwiLCBzZWFyY2ggbGluZWFybHlcbiAgICAgICAgICAgIGlmIChyaWdodCAtIGxlZnQgPD0gbm9kZVNpemUpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gbGVmdDsgaSA8PSByaWdodDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHggPSBjb29yZHNbMiAqIGldO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB5ID0gY29vcmRzWzIgKiBpICsgMV07XG4gICAgICAgICAgICAgICAgICAgIGlmICh4ID49IG1pblggJiYgeCA8PSBtYXhYICYmIHkgPj0gbWluWSAmJiB5IDw9IG1heFkpIHJlc3VsdC5wdXNoKGlkc1tpXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBvdGhlcndpc2UgZmluZCB0aGUgbWlkZGxlIGluZGV4XG4gICAgICAgICAgICBjb25zdCBtID0gKGxlZnQgKyByaWdodCkgPj4gMTtcblxuICAgICAgICAgICAgLy8gaW5jbHVkZSB0aGUgbWlkZGxlIGl0ZW0gaWYgaXQncyBpbiByYW5nZVxuICAgICAgICAgICAgY29uc3QgeCA9IGNvb3Jkc1syICogbV07XG4gICAgICAgICAgICBjb25zdCB5ID0gY29vcmRzWzIgKiBtICsgMV07XG4gICAgICAgICAgICBpZiAoeCA+PSBtaW5YICYmIHggPD0gbWF4WCAmJiB5ID49IG1pblkgJiYgeSA8PSBtYXhZKSByZXN1bHQucHVzaChpZHNbbV0pO1xuXG4gICAgICAgICAgICAvLyBxdWV1ZSBzZWFyY2ggaW4gaGFsdmVzIHRoYXQgaW50ZXJzZWN0IHRoZSBxdWVyeVxuICAgICAgICAgICAgaWYgKGF4aXMgPT09IDAgPyBtaW5YIDw9IHggOiBtaW5ZIDw9IHkpIHtcbiAgICAgICAgICAgICAgICBzdGFjay5wdXNoKGxlZnQpO1xuICAgICAgICAgICAgICAgIHN0YWNrLnB1c2gobSAtIDEpO1xuICAgICAgICAgICAgICAgIHN0YWNrLnB1c2goMSAtIGF4aXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGF4aXMgPT09IDAgPyBtYXhYID49IHggOiBtYXhZID49IHkpIHtcbiAgICAgICAgICAgICAgICBzdGFjay5wdXNoKG0gKyAxKTtcbiAgICAgICAgICAgICAgICBzdGFjay5wdXNoKHJpZ2h0KTtcbiAgICAgICAgICAgICAgICBzdGFjay5wdXNoKDEgLSBheGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VhcmNoIHRoZSBpbmRleCBmb3IgaXRlbXMgd2l0aGluIGEgZ2l2ZW4gcmFkaXVzLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBxeFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBxeVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByIFF1ZXJ5IHJhZGl1cy5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyW119IEFuIGFycmF5IG9mIGluZGljZXMgY29ycmVwb25kaW5nIHRvIHRoZSBmb3VuZCBpdGVtcy5cbiAgICAgKi9cbiAgICB3aXRoaW4ocXgsIHF5LCByKSB7XG4gICAgICAgIGlmICghdGhpcy5fZmluaXNoZWQpIHRocm93IG5ldyBFcnJvcignRGF0YSBub3QgeWV0IGluZGV4ZWQgLSBjYWxsIGluZGV4LmZpbmlzaCgpLicpO1xuXG4gICAgICAgIGNvbnN0IHtpZHMsIGNvb3Jkcywgbm9kZVNpemV9ID0gdGhpcztcbiAgICAgICAgY29uc3Qgc3RhY2sgPSBbMCwgaWRzLmxlbmd0aCAtIDEsIDBdO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBbXTtcbiAgICAgICAgY29uc3QgcjIgPSByICogcjtcblxuICAgICAgICAvLyByZWN1cnNpdmVseSBzZWFyY2ggZm9yIGl0ZW1zIHdpdGhpbiByYWRpdXMgaW4gdGhlIGtkLXNvcnRlZCBhcnJheXNcbiAgICAgICAgd2hpbGUgKHN0YWNrLmxlbmd0aCkge1xuICAgICAgICAgICAgY29uc3QgYXhpcyA9IHN0YWNrLnBvcCgpIHx8IDA7XG4gICAgICAgICAgICBjb25zdCByaWdodCA9IHN0YWNrLnBvcCgpIHx8IDA7XG4gICAgICAgICAgICBjb25zdCBsZWZ0ID0gc3RhY2sucG9wKCkgfHwgMDtcblxuICAgICAgICAgICAgLy8gaWYgd2UgcmVhY2hlZCBcInRyZWUgbm9kZVwiLCBzZWFyY2ggbGluZWFybHlcbiAgICAgICAgICAgIGlmIChyaWdodCAtIGxlZnQgPD0gbm9kZVNpemUpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gbGVmdDsgaSA8PSByaWdodDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzcURpc3QoY29vcmRzWzIgKiBpXSwgY29vcmRzWzIgKiBpICsgMV0sIHF4LCBxeSkgPD0gcjIpIHJlc3VsdC5wdXNoKGlkc1tpXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBvdGhlcndpc2UgZmluZCB0aGUgbWlkZGxlIGluZGV4XG4gICAgICAgICAgICBjb25zdCBtID0gKGxlZnQgKyByaWdodCkgPj4gMTtcblxuICAgICAgICAgICAgLy8gaW5jbHVkZSB0aGUgbWlkZGxlIGl0ZW0gaWYgaXQncyBpbiByYW5nZVxuICAgICAgICAgICAgY29uc3QgeCA9IGNvb3Jkc1syICogbV07XG4gICAgICAgICAgICBjb25zdCB5ID0gY29vcmRzWzIgKiBtICsgMV07XG4gICAgICAgICAgICBpZiAoc3FEaXN0KHgsIHksIHF4LCBxeSkgPD0gcjIpIHJlc3VsdC5wdXNoKGlkc1ttXSk7XG5cbiAgICAgICAgICAgIC8vIHF1ZXVlIHNlYXJjaCBpbiBoYWx2ZXMgdGhhdCBpbnRlcnNlY3QgdGhlIHF1ZXJ5XG4gICAgICAgICAgICBpZiAoYXhpcyA9PT0gMCA/IHF4IC0gciA8PSB4IDogcXkgLSByIDw9IHkpIHtcbiAgICAgICAgICAgICAgICBzdGFjay5wdXNoKGxlZnQpO1xuICAgICAgICAgICAgICAgIHN0YWNrLnB1c2gobSAtIDEpO1xuICAgICAgICAgICAgICAgIHN0YWNrLnB1c2goMSAtIGF4aXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGF4aXMgPT09IDAgPyBxeCArIHIgPj0geCA6IHF5ICsgciA+PSB5KSB7XG4gICAgICAgICAgICAgICAgc3RhY2sucHVzaChtICsgMSk7XG4gICAgICAgICAgICAgICAgc3RhY2sucHVzaChyaWdodCk7XG4gICAgICAgICAgICAgICAgc3RhY2sucHVzaCgxIC0gYXhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge1VpbnQxNkFycmF5IHwgVWludDMyQXJyYXl9IGlkc1xuICogQHBhcmFtIHtJbnN0YW5jZVR5cGU8VHlwZWRBcnJheUNvbnN0cnVjdG9yPn0gY29vcmRzXG4gKiBAcGFyYW0ge251bWJlcn0gbm9kZVNpemVcbiAqIEBwYXJhbSB7bnVtYmVyfSBsZWZ0XG4gKiBAcGFyYW0ge251bWJlcn0gcmlnaHRcbiAqIEBwYXJhbSB7bnVtYmVyfSBheGlzXG4gKi9cbmZ1bmN0aW9uIHNvcnQoaWRzLCBjb29yZHMsIG5vZGVTaXplLCBsZWZ0LCByaWdodCwgYXhpcykge1xuICAgIGlmIChyaWdodCAtIGxlZnQgPD0gbm9kZVNpemUpIHJldHVybjtcblxuICAgIGNvbnN0IG0gPSAobGVmdCArIHJpZ2h0KSA+PiAxOyAvLyBtaWRkbGUgaW5kZXhcblxuICAgIC8vIHNvcnQgaWRzIGFuZCBjb29yZHMgYXJvdW5kIHRoZSBtaWRkbGUgaW5kZXggc28gdGhhdCB0aGUgaGFsdmVzIGxpZVxuICAgIC8vIGVpdGhlciBsZWZ0L3JpZ2h0IG9yIHRvcC9ib3R0b20gY29ycmVzcG9uZGluZ2x5ICh0YWtpbmcgdHVybnMpXG4gICAgc2VsZWN0KGlkcywgY29vcmRzLCBtLCBsZWZ0LCByaWdodCwgYXhpcyk7XG5cbiAgICAvLyByZWN1cnNpdmVseSBrZC1zb3J0IGZpcnN0IGhhbGYgYW5kIHNlY29uZCBoYWxmIG9uIHRoZSBvcHBvc2l0ZSBheGlzXG4gICAgc29ydChpZHMsIGNvb3Jkcywgbm9kZVNpemUsIGxlZnQsIG0gLSAxLCAxIC0gYXhpcyk7XG4gICAgc29ydChpZHMsIGNvb3Jkcywgbm9kZVNpemUsIG0gKyAxLCByaWdodCwgMSAtIGF4aXMpO1xufVxuXG4vKipcbiAqIEN1c3RvbSBGbG95ZC1SaXZlc3Qgc2VsZWN0aW9uIGFsZ29yaXRobTogc29ydCBpZHMgYW5kIGNvb3JkcyBzbyB0aGF0XG4gKiBbbGVmdC4uay0xXSBpdGVtcyBhcmUgc21hbGxlciB0aGFuIGstdGggaXRlbSAob24gZWl0aGVyIHggb3IgeSBheGlzKVxuICogQHBhcmFtIHtVaW50MTZBcnJheSB8IFVpbnQzMkFycmF5fSBpZHNcbiAqIEBwYXJhbSB7SW5zdGFuY2VUeXBlPFR5cGVkQXJyYXlDb25zdHJ1Y3Rvcj59IGNvb3Jkc1xuICogQHBhcmFtIHtudW1iZXJ9IGtcbiAqIEBwYXJhbSB7bnVtYmVyfSBsZWZ0XG4gKiBAcGFyYW0ge251bWJlcn0gcmlnaHRcbiAqIEBwYXJhbSB7bnVtYmVyfSBheGlzXG4gKi9cbmZ1bmN0aW9uIHNlbGVjdChpZHMsIGNvb3JkcywgaywgbGVmdCwgcmlnaHQsIGF4aXMpIHtcblxuICAgIHdoaWxlIChyaWdodCA+IGxlZnQpIHtcbiAgICAgICAgaWYgKHJpZ2h0IC0gbGVmdCA+IDYwMCkge1xuICAgICAgICAgICAgY29uc3QgbiA9IHJpZ2h0IC0gbGVmdCArIDE7XG4gICAgICAgICAgICBjb25zdCBtID0gayAtIGxlZnQgKyAxO1xuICAgICAgICAgICAgY29uc3QgeiA9IE1hdGgubG9nKG4pO1xuICAgICAgICAgICAgY29uc3QgcyA9IDAuNSAqIE1hdGguZXhwKDIgKiB6IC8gMyk7XG4gICAgICAgICAgICBjb25zdCBzZCA9IDAuNSAqIE1hdGguc3FydCh6ICogcyAqIChuIC0gcykgLyBuKSAqIChtIC0gbiAvIDIgPCAwID8gLTEgOiAxKTtcbiAgICAgICAgICAgIGNvbnN0IG5ld0xlZnQgPSBNYXRoLm1heChsZWZ0LCBNYXRoLmZsb29yKGsgLSBtICogcyAvIG4gKyBzZCkpO1xuICAgICAgICAgICAgY29uc3QgbmV3UmlnaHQgPSBNYXRoLm1pbihyaWdodCwgTWF0aC5mbG9vcihrICsgKG4gLSBtKSAqIHMgLyBuICsgc2QpKTtcbiAgICAgICAgICAgIHNlbGVjdChpZHMsIGNvb3JkcywgaywgbmV3TGVmdCwgbmV3UmlnaHQsIGF4aXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdCA9IGNvb3Jkc1syICogayArIGF4aXNdO1xuICAgICAgICBsZXQgaSA9IGxlZnQ7XG4gICAgICAgIGxldCBqID0gcmlnaHQ7XG5cbiAgICAgICAgc3dhcEl0ZW0oaWRzLCBjb29yZHMsIGxlZnQsIGspO1xuICAgICAgICBpZiAoY29vcmRzWzIgKiByaWdodCArIGF4aXNdID4gdCkgc3dhcEl0ZW0oaWRzLCBjb29yZHMsIGxlZnQsIHJpZ2h0KTtcblxuICAgICAgICB3aGlsZSAoaSA8IGopIHtcbiAgICAgICAgICAgIHN3YXBJdGVtKGlkcywgY29vcmRzLCBpLCBqKTtcbiAgICAgICAgICAgIGkrKztcbiAgICAgICAgICAgIGotLTtcbiAgICAgICAgICAgIHdoaWxlIChjb29yZHNbMiAqIGkgKyBheGlzXSA8IHQpIGkrKztcbiAgICAgICAgICAgIHdoaWxlIChjb29yZHNbMiAqIGogKyBheGlzXSA+IHQpIGotLTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb29yZHNbMiAqIGxlZnQgKyBheGlzXSA9PT0gdCkgc3dhcEl0ZW0oaWRzLCBjb29yZHMsIGxlZnQsIGopO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGorKztcbiAgICAgICAgICAgIHN3YXBJdGVtKGlkcywgY29vcmRzLCBqLCByaWdodCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaiA8PSBrKSBsZWZ0ID0gaiArIDE7XG4gICAgICAgIGlmIChrIDw9IGopIHJpZ2h0ID0gaiAtIDE7XG4gICAgfVxufVxuXG4vKipcbiAqIEBwYXJhbSB7VWludDE2QXJyYXkgfCBVaW50MzJBcnJheX0gaWRzXG4gKiBAcGFyYW0ge0luc3RhbmNlVHlwZTxUeXBlZEFycmF5Q29uc3RydWN0b3I+fSBjb29yZHNcbiAqIEBwYXJhbSB7bnVtYmVyfSBpXG4gKiBAcGFyYW0ge251bWJlcn0galxuICovXG5mdW5jdGlvbiBzd2FwSXRlbShpZHMsIGNvb3JkcywgaSwgaikge1xuICAgIHN3YXAoaWRzLCBpLCBqKTtcbiAgICBzd2FwKGNvb3JkcywgMiAqIGksIDIgKiBqKTtcbiAgICBzd2FwKGNvb3JkcywgMiAqIGkgKyAxLCAyICogaiArIDEpO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7SW5zdGFuY2VUeXBlPFR5cGVkQXJyYXlDb25zdHJ1Y3Rvcj59IGFyclxuICogQHBhcmFtIHtudW1iZXJ9IGlcbiAqIEBwYXJhbSB7bnVtYmVyfSBqXG4gKi9cbmZ1bmN0aW9uIHN3YXAoYXJyLCBpLCBqKSB7XG4gICAgY29uc3QgdG1wID0gYXJyW2ldO1xuICAgIGFycltpXSA9IGFycltqXTtcbiAgICBhcnJbal0gPSB0bXA7XG59XG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IGF4XG4gKiBAcGFyYW0ge251bWJlcn0gYXlcbiAqIEBwYXJhbSB7bnVtYmVyfSBieFxuICogQHBhcmFtIHtudW1iZXJ9IGJ5XG4gKi9cbmZ1bmN0aW9uIHNxRGlzdChheCwgYXksIGJ4LCBieSkge1xuICAgIGNvbnN0IGR4ID0gYXggLSBieDtcbiAgICBjb25zdCBkeSA9IGF5IC0gYnk7XG4gICAgcmV0dXJuIGR4ICogZHggKyBkeSAqIGR5O1xufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHR5cGUge0xheWVyU3BlY2lmaWNhdGlvbn0gZnJvbSAnLi90eXBlcy5qcyc7XG5cbmltcG9ydCByZWZQcm9wZXJ0aWVzIGZyb20gJy4vdXRpbC9yZWZfcHJvcGVydGllcy5qcyc7XG5cbmZ1bmN0aW9uIHN0cmluZ2lmeShvYmo6IGFueSkge1xuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnbnVtYmVyJyB8fCB0eXBlb2Ygb2JqID09PSAnYm9vbGVhbicgfHwgdHlwZW9mIG9iaiA9PT0gJ3N0cmluZycgfHwgb2JqID09PSB1bmRlZmluZWQgfHwgb2JqID09PSBudWxsKVxuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkob2JqKTtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICAgICAgbGV0IHN0ciA9ICdbJztcbiAgICAgICAgZm9yIChjb25zdCB2YWwgb2Ygb2JqKSB7XG4gICAgICAgICAgICBzdHIgKz0gYCR7c3RyaW5naWZ5KHZhbCl9LGA7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGAke3N0cn1dYDtcbiAgICB9XG5cbiAgICBsZXQgc3RyID0gJ3snO1xuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKG9iaikuc29ydCgpKSB7XG4gICAgICAgIHN0ciArPSBgJHtrZXl9OiR7c3RyaW5naWZ5KChvYmo6IGFueSlba2V5XSl9LGA7XG4gICAgfVxuICAgIHJldHVybiBgJHtzdHJ9fWA7XG59XG5cbmZ1bmN0aW9uIGdldEtleShsYXllcjogTGF5ZXJTcGVjaWZpY2F0aW9uKSB7XG4gICAgbGV0IGtleSA9ICcnO1xuICAgIGZvciAoY29uc3QgayBvZiByZWZQcm9wZXJ0aWVzKSB7XG4gICAgICAgIGtleSArPSBgLyR7c3RyaW5naWZ5KChsYXllcjogYW55KVtrXSl9YDtcbiAgICB9XG4gICAgcmV0dXJuIGtleTtcbn1cblxuLyoqXG4gKiBHaXZlbiBhbiBhcnJheSBvZiBsYXllcnMsIHJldHVybiBhbiBhcnJheSBvZiBhcnJheXMgb2YgbGF5ZXJzIHdoZXJlIGFsbFxuICogbGF5ZXJzIGluIGVhY2ggZ3JvdXAgaGF2ZSBpZGVudGljYWwgbGF5b3V0LWFmZmVjdGluZyBwcm9wZXJ0aWVzLiBUaGVzZVxuICogYXJlIHRoZSBwcm9wZXJ0aWVzIHRoYXQgd2VyZSBmb3JtZXJseSB1c2VkIGJ5IGV4cGxpY2l0IGByZWZgIG1lY2hhbmlzbVxuICogZm9yIGxheWVyczogJ3R5cGUnLCAnc291cmNlJywgJ3NvdXJjZS1sYXllcicsICdtaW56b29tJywgJ21heHpvb20nLFxuICogJ2ZpbHRlcicsIGFuZCAnbGF5b3V0Jy5cbiAqXG4gKiBUaGUgaW5wdXQgaXMgbm90IG1vZGlmaWVkLiBUaGUgb3V0cHV0IGxheWVycyBhcmUgcmVmZXJlbmNlcyB0byB0aGVcbiAqIGlucHV0IGxheWVycy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheTxMYXllcj59IGxheWVyc1xuICogQHBhcmFtIHtPYmplY3R9IFtjYWNoZWRLZXlzXSAtIGFuIG9iamVjdCB0byBrZWVwIGFscmVhZHkgY2FsY3VsYXRlZCBrZXlzLlxuICogQHJldHVybnMge0FycmF5PEFycmF5PExheWVyPj59XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdyb3VwQnlMYXlvdXQobGF5ZXJzOiBBcnJheTxMYXllclNwZWNpZmljYXRpb24+LCBjYWNoZWRLZXlzOiB7W2lkOiBzdHJpbmddOiBzdHJpbmd9KTogQXJyYXk8QXJyYXk8TGF5ZXJTcGVjaWZpY2F0aW9uPj4ge1xuICAgIGNvbnN0IGdyb3VwcyA9IHt9O1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsYXllcnMubGVuZ3RoOyBpKyspIHtcblxuICAgICAgICBjb25zdCBrID0gKGNhY2hlZEtleXMgJiYgY2FjaGVkS2V5c1tsYXllcnNbaV0uaWRdKSB8fCBnZXRLZXkobGF5ZXJzW2ldKTtcbiAgICAgICAgLy8gdXBkYXRlIHRoZSBjYWNoZSBpZiB0aGVyZSBpcyBvbmVcbiAgICAgICAgaWYgKGNhY2hlZEtleXMpXG4gICAgICAgICAgICBjYWNoZWRLZXlzW2xheWVyc1tpXS5pZF0gPSBrO1xuXG4gICAgICAgIGxldCBncm91cCA9IGdyb3Vwc1trXTtcbiAgICAgICAgaWYgKCFncm91cCkge1xuICAgICAgICAgICAgZ3JvdXAgPSBncm91cHNba10gPSBbXTtcbiAgICAgICAgfVxuICAgICAgICBncm91cC5wdXNoKGxheWVyc1tpXSk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gW107XG5cbiAgICBmb3IgKGNvbnN0IGsgaW4gZ3JvdXBzKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKGdyb3Vwc1trXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBjcmVhdGVTdHlsZUxheWVyIGZyb20gJy4vY3JlYXRlX3N0eWxlX2xheWVyLmpzJztcblxuaW1wb3J0IHt2YWx1ZXN9IGZyb20gJy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQgZ3JvdXBCeUxheW91dCBmcm9tICcuLi9zdHlsZS1zcGVjL2dyb3VwX2J5X2xheW91dC5qcyc7XG5cbmltcG9ydCB0eXBlIHtUeXBlZFN0eWxlTGF5ZXJ9IGZyb20gJy4vc3R5bGVfbGF5ZXIvdHlwZWRfc3R5bGVfbGF5ZXIuanMnO1xuaW1wb3J0IHR5cGUge0xheWVyU3BlY2lmaWNhdGlvbn0gZnJvbSAnLi4vc3R5bGUtc3BlYy90eXBlcy5qcyc7XG5cbmV4cG9ydCB0eXBlIExheWVyQ29uZmlncyA9IHtbXzogc3RyaW5nXTogTGF5ZXJTcGVjaWZpY2F0aW9uIH07XG5leHBvcnQgdHlwZSBGYW1pbHk8TGF5ZXI6IFR5cGVkU3R5bGVMYXllcj4gPSBBcnJheTxMYXllcj47XG5cbmNsYXNzIFN0eWxlTGF5ZXJJbmRleCB7XG4gICAgZmFtaWxpZXNCeVNvdXJjZTogeyBbc291cmNlOiBzdHJpbmddOiB7IFtzb3VyY2VMYXllcjogc3RyaW5nXTogQXJyYXk8RmFtaWx5PFR5cGVkU3R5bGVMYXllcj4+IH0gfTtcbiAgICBrZXlDYWNoZTogeyBbc291cmNlOiBzdHJpbmddOiBzdHJpbmcgfTtcblxuICAgIF9sYXllckNvbmZpZ3M6IExheWVyQ29uZmlncztcbiAgICBfbGF5ZXJzOiB7W186IHN0cmluZ106IFR5cGVkU3R5bGVMYXllciB9O1xuXG4gICAgY29uc3RydWN0b3IobGF5ZXJDb25maWdzOiA/QXJyYXk8TGF5ZXJTcGVjaWZpY2F0aW9uPikge1xuICAgICAgICB0aGlzLmtleUNhY2hlID0ge307XG4gICAgICAgIGlmIChsYXllckNvbmZpZ3MpIHtcbiAgICAgICAgICAgIHRoaXMucmVwbGFjZShsYXllckNvbmZpZ3MpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmVwbGFjZShsYXllckNvbmZpZ3M6IEFycmF5PExheWVyU3BlY2lmaWNhdGlvbj4pIHtcbiAgICAgICAgdGhpcy5fbGF5ZXJDb25maWdzID0ge307XG4gICAgICAgIHRoaXMuX2xheWVycyA9IHt9O1xuICAgICAgICB0aGlzLnVwZGF0ZShsYXllckNvbmZpZ3MsIFtdKTtcbiAgICB9XG5cbiAgICB1cGRhdGUobGF5ZXJDb25maWdzOiBBcnJheTxMYXllclNwZWNpZmljYXRpb24+LCByZW1vdmVkSWRzOiBBcnJheTxzdHJpbmc+KSB7XG4gICAgICAgIGZvciAoY29uc3QgbGF5ZXJDb25maWcgb2YgbGF5ZXJDb25maWdzKSB7XG4gICAgICAgICAgICB0aGlzLl9sYXllckNvbmZpZ3NbbGF5ZXJDb25maWcuaWRdID0gbGF5ZXJDb25maWc7XG5cbiAgICAgICAgICAgIGNvbnN0IGxheWVyID0gdGhpcy5fbGF5ZXJzW2xheWVyQ29uZmlnLmlkXSA9ICgoY3JlYXRlU3R5bGVMYXllcihsYXllckNvbmZpZyk6IGFueSk6IFR5cGVkU3R5bGVMYXllcik7XG4gICAgICAgICAgICBsYXllci5jb21waWxlRmlsdGVyKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5rZXlDYWNoZVtsYXllckNvbmZpZy5pZF0pXG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMua2V5Q2FjaGVbbGF5ZXJDb25maWcuaWRdO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgaWQgb2YgcmVtb3ZlZElkcykge1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMua2V5Q2FjaGVbaWRdO1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuX2xheWVyQ29uZmlnc1tpZF07XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5fbGF5ZXJzW2lkXTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZmFtaWxpZXNCeVNvdXJjZSA9IHt9O1xuXG4gICAgICAgIGNvbnN0IGdyb3VwcyA9IGdyb3VwQnlMYXlvdXQodmFsdWVzKHRoaXMuX2xheWVyQ29uZmlncyksIHRoaXMua2V5Q2FjaGUpO1xuXG4gICAgICAgIGZvciAoY29uc3QgbGF5ZXJDb25maWdzIG9mIGdyb3Vwcykge1xuICAgICAgICAgICAgY29uc3QgbGF5ZXJzID0gbGF5ZXJDb25maWdzLm1hcCgobGF5ZXJDb25maWcpID0+IHRoaXMuX2xheWVyc1tsYXllckNvbmZpZy5pZF0pO1xuXG4gICAgICAgICAgICBjb25zdCBsYXllciA9IGxheWVyc1swXTtcbiAgICAgICAgICAgIGlmIChsYXllci52aXNpYmlsaXR5ID09PSAnbm9uZScpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3Qgc291cmNlSWQgPSBsYXllci5zb3VyY2UgfHwgJyc7XG4gICAgICAgICAgICBsZXQgc291cmNlR3JvdXAgPSB0aGlzLmZhbWlsaWVzQnlTb3VyY2Vbc291cmNlSWRdO1xuICAgICAgICAgICAgaWYgKCFzb3VyY2VHcm91cCkge1xuICAgICAgICAgICAgICAgIHNvdXJjZUdyb3VwID0gdGhpcy5mYW1pbGllc0J5U291cmNlW3NvdXJjZUlkXSA9IHt9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBzb3VyY2VMYXllcklkID0gbGF5ZXIuc291cmNlTGF5ZXIgfHwgJ19nZW9qc29uVGlsZUxheWVyJztcbiAgICAgICAgICAgIGxldCBzb3VyY2VMYXllckZhbWlsaWVzID0gc291cmNlR3JvdXBbc291cmNlTGF5ZXJJZF07XG4gICAgICAgICAgICBpZiAoIXNvdXJjZUxheWVyRmFtaWxpZXMpIHtcbiAgICAgICAgICAgICAgICBzb3VyY2VMYXllckZhbWlsaWVzID0gc291cmNlR3JvdXBbc291cmNlTGF5ZXJJZF0gPSBbXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc291cmNlTGF5ZXJGYW1pbGllcy5wdXNoKGxheWVycyk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFN0eWxlTGF5ZXJJbmRleDtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCBERU1EYXRhIGZyb20gJy4uL2RhdGEvZGVtX2RhdGEuanMnO1xuaW1wb3J0IHdpbmRvdyBmcm9tICcuLi91dGlsL3dpbmRvdy5qcyc7XG5cbmltcG9ydCB0eXBlIEFjdG9yIGZyb20gJy4uL3V0aWwvYWN0b3IuanMnO1xuaW1wb3J0IHR5cGUge1dvcmtlckRFTVRpbGVQYXJhbWV0ZXJzLCBXb3JrZXJERU1UaWxlQ2FsbGJhY2t9IGZyb20gJy4vd29ya2VyX3NvdXJjZS5qcyc7XG5cbmNsYXNzIFJhc3RlckRFTVRpbGVXb3JrZXJTb3VyY2Uge1xuICAgIGFjdG9yOiBBY3RvcjtcbiAgICBvZmZzY3JlZW5DYW52YXM6IE9mZnNjcmVlbkNhbnZhcztcbiAgICBvZmZzY3JlZW5DYW52YXNDb250ZXh0OiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQ7XG5cbiAgICBsb2FkVGlsZShwYXJhbXM6IFdvcmtlckRFTVRpbGVQYXJhbWV0ZXJzLCBjYWxsYmFjazogV29ya2VyREVNVGlsZUNhbGxiYWNrKSB7XG4gICAgICAgIGNvbnN0IHt1aWQsIGVuY29kaW5nLCByYXdJbWFnZURhdGEsIHBhZGRpbmcsIGJ1aWxkUXVhZFRyZWV9ID0gcGFyYW1zO1xuICAgICAgICAvLyBNYWluIHRocmVhZCB3aWxsIHRyYW5zZmVyIEltYWdlQml0bWFwIGlmIG9mZnNjcmVlbiBkZWNvZGUgd2l0aCBPZmZzY3JlZW5DYW52YXMgaXMgc3VwcG9ydGVkLCBlbHNlIGl0IHdpbGwgdHJhbnNmZXIgYW4gYWxyZWFkeSBkZWNvZGVkIGltYWdlLlxuICAgICAgICAvLyBGbG93IHN0cnVnZ2xlcyB0byByZWZpbmUgSW1hZ2VCaXRtYXAgdHlwZSwgbGlrZWx5IGR1ZSB0byB0aGUgSlNEb20gc2hpbVxuICAgICAgICBjb25zdCBpbWFnZVBpeGVscyA9IHdpbmRvdy5JbWFnZUJpdG1hcCAmJiByYXdJbWFnZURhdGEgaW5zdGFuY2VvZiB3aW5kb3cuSW1hZ2VCaXRtYXAgPyB0aGlzLmdldEltYWdlRGF0YShyYXdJbWFnZURhdGEsIHBhZGRpbmcpIDogKChyYXdJbWFnZURhdGE6IGFueSk6IEltYWdlRGF0YSk7XG4gICAgICAgIGNvbnN0IGRlbSA9IG5ldyBERU1EYXRhKHVpZCwgaW1hZ2VQaXhlbHMsIGVuY29kaW5nLCBwYWRkaW5nIDwgMSwgYnVpbGRRdWFkVHJlZSk7XG4gICAgICAgIGNhbGxiYWNrKG51bGwsIGRlbSk7XG4gICAgfVxuXG4gICAgZ2V0SW1hZ2VEYXRhKGltZ0JpdG1hcDogSW1hZ2VCaXRtYXAsIHBhZGRpbmc6IG51bWJlcik6IEltYWdlRGF0YSB7XG4gICAgICAgIC8vIExhemlseSBpbml0aWFsaXplIE9mZnNjcmVlbkNhbnZhc1xuICAgICAgICBpZiAoIXRoaXMub2Zmc2NyZWVuQ2FudmFzIHx8ICF0aGlzLm9mZnNjcmVlbkNhbnZhc0NvbnRleHQpIHtcbiAgICAgICAgICAgIC8vIERlbSB0aWxlcyBhcmUgdHlwaWNhbGx5IDI1NngyNTZcbiAgICAgICAgICAgIHRoaXMub2Zmc2NyZWVuQ2FudmFzID0gbmV3IE9mZnNjcmVlbkNhbnZhcyhpbWdCaXRtYXAud2lkdGgsIGltZ0JpdG1hcC5oZWlnaHQpO1xuICAgICAgICAgICAgLy8gJEZsb3dJc3N1ZVtleHRyYS1hcmddOiBpbnRlcm5hbCBGbG93IHR5cGVzIGRvbid0IHlldCBrbm93IGFib3V0IHdpbGxSZWFkRnJlcXVlbnRseVxuICAgICAgICAgICAgdGhpcy5vZmZzY3JlZW5DYW52YXNDb250ZXh0ID0gdGhpcy5vZmZzY3JlZW5DYW52YXMuZ2V0Q29udGV4dCgnMmQnLCB7d2lsbFJlYWRGcmVxdWVudGx5OiB0cnVlfSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm9mZnNjcmVlbkNhbnZhcy53aWR0aCA9IGltZ0JpdG1hcC53aWR0aDtcbiAgICAgICAgdGhpcy5vZmZzY3JlZW5DYW52YXMuaGVpZ2h0ID0gaW1nQml0bWFwLmhlaWdodDtcblxuICAgICAgICB0aGlzLm9mZnNjcmVlbkNhbnZhc0NvbnRleHQuZHJhd0ltYWdlKGltZ0JpdG1hcCwgMCwgMCwgaW1nQml0bWFwLndpZHRoLCBpbWdCaXRtYXAuaGVpZ2h0KTtcbiAgICAgICAgLy8gSW5zZXJ0IG9yIHJlbW92ZSBkZWZpbmVkIHBhZGRpbmcgYXJvdW5kIHRoZSBpbWFnZSB0byBhbGxvdyBiYWNrZmlsbGluZyBmb3IgbmVpZ2hib3JpbmcgZGF0YS5cbiAgICAgICAgY29uc3QgaW1nRGF0YSA9IHRoaXMub2Zmc2NyZWVuQ2FudmFzQ29udGV4dC5nZXRJbWFnZURhdGEoLXBhZGRpbmcsIC1wYWRkaW5nLCBpbWdCaXRtYXAud2lkdGggKyAyICogcGFkZGluZywgaW1nQml0bWFwLmhlaWdodCArIDIgKiBwYWRkaW5nKTtcbiAgICAgICAgdGhpcy5vZmZzY3JlZW5DYW52YXNDb250ZXh0LmNsZWFyUmVjdCgwLCAwLCB0aGlzLm9mZnNjcmVlbkNhbnZhcy53aWR0aCwgdGhpcy5vZmZzY3JlZW5DYW52YXMuaGVpZ2h0KTtcbiAgICAgICAgcmV0dXJuIGltZ0RhdGE7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBSYXN0ZXJERU1UaWxlV29ya2VyU291cmNlO1xuIiwiXG5tb2R1bGUuZXhwb3J0cyA9IHJld2luZDtcblxuZnVuY3Rpb24gcmV3aW5kKGdqLCBvdXRlcikge1xuICAgIHZhciB0eXBlID0gZ2ogJiYgZ2oudHlwZSwgaTtcblxuICAgIGlmICh0eXBlID09PSAnRmVhdHVyZUNvbGxlY3Rpb24nKSB7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBnai5mZWF0dXJlcy5sZW5ndGg7IGkrKykgcmV3aW5kKGdqLmZlYXR1cmVzW2ldLCBvdXRlcik7XG5cbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdHZW9tZXRyeUNvbGxlY3Rpb24nKSB7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBnai5nZW9tZXRyaWVzLmxlbmd0aDsgaSsrKSByZXdpbmQoZ2ouZ2VvbWV0cmllc1tpXSwgb3V0ZXIpO1xuXG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnRmVhdHVyZScpIHtcbiAgICAgICAgcmV3aW5kKGdqLmdlb21ldHJ5LCBvdXRlcik7XG5cbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdQb2x5Z29uJykge1xuICAgICAgICByZXdpbmRSaW5ncyhnai5jb29yZGluYXRlcywgb3V0ZXIpO1xuXG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnTXVsdGlQb2x5Z29uJykge1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZ2ouY29vcmRpbmF0ZXMubGVuZ3RoOyBpKyspIHJld2luZFJpbmdzKGdqLmNvb3JkaW5hdGVzW2ldLCBvdXRlcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGdqO1xufVxuXG5mdW5jdGlvbiByZXdpbmRSaW5ncyhyaW5ncywgb3V0ZXIpIHtcbiAgICBpZiAocmluZ3MubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICByZXdpbmRSaW5nKHJpbmdzWzBdLCBvdXRlcik7XG4gICAgZm9yICh2YXIgaSA9IDE7IGkgPCByaW5ncy5sZW5ndGg7IGkrKykge1xuICAgICAgICByZXdpbmRSaW5nKHJpbmdzW2ldLCAhb3V0ZXIpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gcmV3aW5kUmluZyhyaW5nLCBkaXIpIHtcbiAgICB2YXIgYXJlYSA9IDAsIGVyciA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHJpbmcubGVuZ3RoLCBqID0gbGVuIC0gMTsgaSA8IGxlbjsgaiA9IGkrKykge1xuICAgICAgICB2YXIgayA9IChyaW5nW2ldWzBdIC0gcmluZ1tqXVswXSkgKiAocmluZ1tqXVsxXSArIHJpbmdbaV1bMV0pO1xuICAgICAgICB2YXIgbSA9IGFyZWEgKyBrO1xuICAgICAgICBlcnIgKz0gTWF0aC5hYnMoYXJlYSkgPj0gTWF0aC5hYnMoaykgPyBhcmVhIC0gbSArIGsgOiBrIC0gbSArIGFyZWE7XG4gICAgICAgIGFyZWEgPSBtO1xuICAgIH1cbiAgICBpZiAoYXJlYSArIGVyciA+PSAwICE9PSAhIWRpcikgcmluZy5yZXZlcnNlKCk7XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5cbmltcG9ydCB7VmVjdG9yVGlsZUZlYXR1cmV9IGZyb20gJ0BtYXBib3gvdmVjdG9yLXRpbGUnO1xuLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuY29uc3QgdG9HZW9KU09OID0gVmVjdG9yVGlsZUZlYXR1cmUucHJvdG90eXBlLnRvR2VvSlNPTjtcbmltcG9ydCBFWFRFTlQgZnJvbSAnLi4vZGF0YS9leHRlbnQuanMnO1xuXG5pbXBvcnQgdHlwZSB7R2VvSlNPTkZlYXR1cmV9IGZyb20gJ0BtYXBib3gvZ2VvanNvbi10eXBlcyc7XG5pbXBvcnQgdHlwZSB7SVZlY3RvclRpbGUsIElWZWN0b3JUaWxlTGF5ZXIsIElWZWN0b3JUaWxlRmVhdHVyZX0gZnJvbSAnQG1hcGJveC92ZWN0b3ItdGlsZSc7XG5cbi8vIFRoZSBmZWF0dXJlIHR5cGUgdXNlZCBieSBnZW9qc29uLXZ0IGFuZCBzdXBlcmNsdXN0ZXIuIFNob3VsZCBiZSBleHRyYWN0ZWQgdG9cbi8vIGdsb2JhbCB0eXBlIGFuZCB1c2VkIGluIG1vZHVsZSBkZWZpbml0aW9ucyBmb3IgdGhvc2UgdHdvIG1vZHVsZXMuXG50eXBlIEZlYXR1cmUgPSB7XG4gICAgdHlwZTogMSxcbiAgICBpZDogbWl4ZWQsXG4gICAgdGFnczoge1tfOiBzdHJpbmddOiBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFufSxcbiAgICBnZW9tZXRyeTogQXJyYXk8W251bWJlciwgbnVtYmVyXT4sXG59IHwge1xuICAgIHR5cGU6IDIgfCAzLFxuICAgIGlkOiBtaXhlZCxcbiAgICB0YWdzOiB7W186IHN0cmluZ106IHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW59LFxuICAgIGdlb21ldHJ5OiBBcnJheTxBcnJheTxbbnVtYmVyLCBudW1iZXJdPj4sXG59XG5cbmNsYXNzIEZlYXR1cmVXcmFwcGVyIGltcGxlbWVudHMgSVZlY3RvclRpbGVGZWF0dXJlIHtcbiAgICBfZmVhdHVyZTogRmVhdHVyZTtcblxuICAgIGV4dGVudDogbnVtYmVyO1xuICAgIHR5cGU6IDEgfCAyIHwgMztcbiAgICBpZDogbnVtYmVyO1xuICAgIHByb3BlcnRpZXM6IHtbXzogc3RyaW5nXTogc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbn07XG5cbiAgICBjb25zdHJ1Y3RvcihmZWF0dXJlOiBGZWF0dXJlKSB7XG4gICAgICAgIHRoaXMuX2ZlYXR1cmUgPSBmZWF0dXJlO1xuXG4gICAgICAgIHRoaXMuZXh0ZW50ID0gRVhURU5UO1xuICAgICAgICB0aGlzLnR5cGUgPSBmZWF0dXJlLnR5cGU7XG4gICAgICAgIHRoaXMucHJvcGVydGllcyA9IGZlYXR1cmUudGFncztcblxuICAgICAgICAvLyBJZiB0aGUgZmVhdHVyZSBoYXMgYSB0b3AtbGV2ZWwgYGlkYCBwcm9wZXJ0eSwgY29weSBpdCBvdmVyLCBidXQgb25seVxuICAgICAgICAvLyBpZiBpdCBjYW4gYmUgY29lcmNlZCB0byBhbiBpbnRlZ2VyLCBiZWNhdXNlIHRoaXMgd3JhcHBlciBpcyB1c2VkIGZvclxuICAgICAgICAvLyBzZXJpYWxpemluZyBnZW9qc29uIGZlYXR1cmUgZGF0YSBpbnRvIHZlY3RvciB0aWxlIFBCRiBkYXRhLCBhbmQgdGhlXG4gICAgICAgIC8vIHZlY3RvciB0aWxlIHNwZWMgb25seSBzdXBwb3J0cyBpbnRlZ2VyIHZhbHVlcyBmb3IgZmVhdHVyZSBpZHMgLS1cbiAgICAgICAgLy8gYWxsb3dpbmcgbm9uLWludGVnZXIgdmFsdWVzIGhlcmUgcmVzdWx0cyBpbiBhIG5vbi1jb21wbGlhbnQgUEJGXG4gICAgICAgIC8vIHRoYXQgY2F1c2VzIGFuIGV4Y2VwdGlvbiB3aGVuIGl0IGlzIHBhcnNlZCB3aXRoIHZlY3Rvci10aWxlLWpzXG4gICAgICAgIGlmICgnaWQnIGluIGZlYXR1cmUgJiYgIWlzTmFOKGZlYXR1cmUuaWQpKSB7XG4gICAgICAgICAgICB0aGlzLmlkID0gcGFyc2VJbnQoZmVhdHVyZS5pZCwgMTApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbG9hZEdlb21ldHJ5KCk6IEFycmF5PEFycmF5PFBvaW50Pj4ge1xuICAgICAgICBpZiAodGhpcy5fZmVhdHVyZS50eXBlID09PSAxKSB7XG4gICAgICAgICAgICBjb25zdCBnZW9tZXRyeSA9IFtdO1xuICAgICAgICAgICAgZm9yIChjb25zdCBwb2ludCBvZiB0aGlzLl9mZWF0dXJlLmdlb21ldHJ5KSB7XG4gICAgICAgICAgICAgICAgZ2VvbWV0cnkucHVzaChbbmV3IFBvaW50KHBvaW50WzBdLCBwb2ludFsxXSldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBnZW9tZXRyeTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGdlb21ldHJ5ID0gW107XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHJpbmcgb2YgdGhpcy5fZmVhdHVyZS5nZW9tZXRyeSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1JpbmcgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHBvaW50IG9mIHJpbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3UmluZy5wdXNoKG5ldyBQb2ludChwb2ludFswXSwgcG9pbnRbMV0pKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZ2VvbWV0cnkucHVzaChuZXdSaW5nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBnZW9tZXRyeTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHRvR2VvSlNPTih4OiBudW1iZXIsIHk6IG51bWJlciwgejogbnVtYmVyKTogR2VvSlNPTkZlYXR1cmUge1xuICAgICAgICByZXR1cm4gdG9HZW9KU09OLmNhbGwodGhpcywgeCwgeSwgeik7XG4gICAgfVxufVxuXG5jbGFzcyBHZW9KU09OV3JhcHBlciBpbXBsZW1lbnRzIElWZWN0b3JUaWxlLCBJVmVjdG9yVGlsZUxheWVyIHtcbiAgICBsYXllcnM6IHtbXzogc3RyaW5nXTogSVZlY3RvclRpbGVMYXllcn07XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIGV4dGVudDogbnVtYmVyO1xuICAgIGxlbmd0aDogbnVtYmVyO1xuICAgIF9mZWF0dXJlczogQXJyYXk8RmVhdHVyZT47XG5cbiAgICBjb25zdHJ1Y3RvcihmZWF0dXJlczogQXJyYXk8RmVhdHVyZT4pIHtcbiAgICAgICAgdGhpcy5sYXllcnMgPSB7J19nZW9qc29uVGlsZUxheWVyJzogdGhpc307XG4gICAgICAgIHRoaXMubmFtZSA9ICdfZ2VvanNvblRpbGVMYXllcic7XG4gICAgICAgIHRoaXMuZXh0ZW50ID0gRVhURU5UO1xuICAgICAgICB0aGlzLmxlbmd0aCA9IGZlYXR1cmVzLmxlbmd0aDtcbiAgICAgICAgdGhpcy5fZmVhdHVyZXMgPSBmZWF0dXJlcztcbiAgICB9XG5cbiAgICBmZWF0dXJlKGk6IG51bWJlcik6IElWZWN0b3JUaWxlRmVhdHVyZSB7XG4gICAgICAgIHJldHVybiBuZXcgRmVhdHVyZVdyYXBwZXIodGhpcy5fZmVhdHVyZXNbaV0pO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgR2VvSlNPTldyYXBwZXI7XG4iLCIndXNlIHN0cmljdCdcblxudmFyIFBvaW50ID0gcmVxdWlyZSgnQG1hcGJveC9wb2ludC1nZW9tZXRyeScpXG52YXIgVmVjdG9yVGlsZUZlYXR1cmUgPSByZXF1aXJlKCdAbWFwYm94L3ZlY3Rvci10aWxlJykuVmVjdG9yVGlsZUZlYXR1cmVcblxubW9kdWxlLmV4cG9ydHMgPSBHZW9KU09OV3JhcHBlclxuXG4vLyBjb25mb3JtIHRvIHZlY3RvcnRpbGUgYXBpXG5mdW5jdGlvbiBHZW9KU09OV3JhcHBlciAoZmVhdHVyZXMsIG9wdGlvbnMpIHtcbiAgdGhpcy5vcHRpb25zID0gb3B0aW9ucyB8fCB7fVxuICB0aGlzLmZlYXR1cmVzID0gZmVhdHVyZXNcbiAgdGhpcy5sZW5ndGggPSBmZWF0dXJlcy5sZW5ndGhcbn1cblxuR2VvSlNPTldyYXBwZXIucHJvdG90eXBlLmZlYXR1cmUgPSBmdW5jdGlvbiAoaSkge1xuICByZXR1cm4gbmV3IEZlYXR1cmVXcmFwcGVyKHRoaXMuZmVhdHVyZXNbaV0sIHRoaXMub3B0aW9ucy5leHRlbnQpXG59XG5cbmZ1bmN0aW9uIEZlYXR1cmVXcmFwcGVyIChmZWF0dXJlLCBleHRlbnQpIHtcbiAgdGhpcy5pZCA9IHR5cGVvZiBmZWF0dXJlLmlkID09PSAnbnVtYmVyJyA/IGZlYXR1cmUuaWQgOiB1bmRlZmluZWRcbiAgdGhpcy50eXBlID0gZmVhdHVyZS50eXBlXG4gIHRoaXMucmF3R2VvbWV0cnkgPSBmZWF0dXJlLnR5cGUgPT09IDEgPyBbZmVhdHVyZS5nZW9tZXRyeV0gOiBmZWF0dXJlLmdlb21ldHJ5XG4gIHRoaXMucHJvcGVydGllcyA9IGZlYXR1cmUudGFnc1xuICB0aGlzLmV4dGVudCA9IGV4dGVudCB8fCA0MDk2XG59XG5cbkZlYXR1cmVXcmFwcGVyLnByb3RvdHlwZS5sb2FkR2VvbWV0cnkgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciByaW5ncyA9IHRoaXMucmF3R2VvbWV0cnlcbiAgdGhpcy5nZW9tZXRyeSA9IFtdXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCByaW5ncy5sZW5ndGg7IGkrKykge1xuICAgIHZhciByaW5nID0gcmluZ3NbaV1cbiAgICB2YXIgbmV3UmluZyA9IFtdXG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCByaW5nLmxlbmd0aDsgaisrKSB7XG4gICAgICBuZXdSaW5nLnB1c2gobmV3IFBvaW50KHJpbmdbal1bMF0sIHJpbmdbal1bMV0pKVxuICAgIH1cbiAgICB0aGlzLmdlb21ldHJ5LnB1c2gobmV3UmluZylcbiAgfVxuICByZXR1cm4gdGhpcy5nZW9tZXRyeVxufVxuXG5GZWF0dXJlV3JhcHBlci5wcm90b3R5cGUuYmJveCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCF0aGlzLmdlb21ldHJ5KSB0aGlzLmxvYWRHZW9tZXRyeSgpXG5cbiAgdmFyIHJpbmdzID0gdGhpcy5nZW9tZXRyeVxuICB2YXIgeDEgPSBJbmZpbml0eVxuICB2YXIgeDIgPSAtSW5maW5pdHlcbiAgdmFyIHkxID0gSW5maW5pdHlcbiAgdmFyIHkyID0gLUluZmluaXR5XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCByaW5ncy5sZW5ndGg7IGkrKykge1xuICAgIHZhciByaW5nID0gcmluZ3NbaV1cblxuICAgIGZvciAodmFyIGogPSAwOyBqIDwgcmluZy5sZW5ndGg7IGorKykge1xuICAgICAgdmFyIGNvb3JkID0gcmluZ1tqXVxuXG4gICAgICB4MSA9IE1hdGgubWluKHgxLCBjb29yZC54KVxuICAgICAgeDIgPSBNYXRoLm1heCh4MiwgY29vcmQueClcbiAgICAgIHkxID0gTWF0aC5taW4oeTEsIGNvb3JkLnkpXG4gICAgICB5MiA9IE1hdGgubWF4KHkyLCBjb29yZC55KVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBbeDEsIHkxLCB4MiwgeTJdXG59XG5cbkZlYXR1cmVXcmFwcGVyLnByb3RvdHlwZS50b0dlb0pTT04gPSBWZWN0b3JUaWxlRmVhdHVyZS5wcm90b3R5cGUudG9HZW9KU09OXG4iLCJ2YXIgUGJmID0gcmVxdWlyZSgncGJmJylcbnZhciBHZW9KU09OV3JhcHBlciA9IHJlcXVpcmUoJy4vbGliL2dlb2pzb25fd3JhcHBlcicpXG5cbm1vZHVsZS5leHBvcnRzID0gZnJvbVZlY3RvclRpbGVKc1xubW9kdWxlLmV4cG9ydHMuZnJvbVZlY3RvclRpbGVKcyA9IGZyb21WZWN0b3JUaWxlSnNcbm1vZHVsZS5leHBvcnRzLmZyb21HZW9qc29uVnQgPSBmcm9tR2VvanNvblZ0XG5tb2R1bGUuZXhwb3J0cy5HZW9KU09OV3JhcHBlciA9IEdlb0pTT05XcmFwcGVyXG5cbi8qKlxuICogU2VyaWFsaXplIGEgdmVjdG9yLXRpbGUtanMtY3JlYXRlZCB0aWxlIHRvIHBiZlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB0aWxlXG4gKiBAcmV0dXJuIHtCdWZmZXJ9IHVuY29tcHJlc3NlZCwgcGJmLXNlcmlhbGl6ZWQgdGlsZSBkYXRhXG4gKi9cbmZ1bmN0aW9uIGZyb21WZWN0b3JUaWxlSnMgKHRpbGUpIHtcbiAgdmFyIG91dCA9IG5ldyBQYmYoKVxuICB3cml0ZVRpbGUodGlsZSwgb3V0KVxuICByZXR1cm4gb3V0LmZpbmlzaCgpXG59XG5cbi8qKlxuICogU2VyaWFsaXplZCBhIGdlb2pzb24tdnQtY3JlYXRlZCB0aWxlIHRvIHBiZi5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gbGF5ZXJzIC0gQW4gb2JqZWN0IG1hcHBpbmcgbGF5ZXIgbmFtZXMgdG8gZ2VvanNvbi12dC1jcmVhdGVkIHZlY3RvciB0aWxlIG9iamVjdHNcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gLSBBbiBvYmplY3Qgc3BlY2lmeWluZyB0aGUgdmVjdG9yLXRpbGUgc3BlY2lmaWNhdGlvbiB2ZXJzaW9uIGFuZCBleHRlbnQgdGhhdCB3ZXJlIHVzZWQgdG8gY3JlYXRlIGBsYXllcnNgLlxuICogQHBhcmFtIHtOdW1iZXJ9IFtvcHRpb25zLnZlcnNpb249MV0gLSBWZXJzaW9uIG9mIHZlY3Rvci10aWxlIHNwZWMgdXNlZFxuICogQHBhcmFtIHtOdW1iZXJ9IFtvcHRpb25zLmV4dGVudD00MDk2XSAtIEV4dGVudCBvZiB0aGUgdmVjdG9yIHRpbGVcbiAqIEByZXR1cm4ge0J1ZmZlcn0gdW5jb21wcmVzc2VkLCBwYmYtc2VyaWFsaXplZCB0aWxlIGRhdGFcbiAqL1xuZnVuY3Rpb24gZnJvbUdlb2pzb25WdCAobGF5ZXJzLCBvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9XG4gIHZhciBsID0ge31cbiAgZm9yICh2YXIgayBpbiBsYXllcnMpIHtcbiAgICBsW2tdID0gbmV3IEdlb0pTT05XcmFwcGVyKGxheWVyc1trXS5mZWF0dXJlcywgb3B0aW9ucylcbiAgICBsW2tdLm5hbWUgPSBrXG4gICAgbFtrXS52ZXJzaW9uID0gb3B0aW9ucy52ZXJzaW9uXG4gICAgbFtrXS5leHRlbnQgPSBvcHRpb25zLmV4dGVudFxuICB9XG4gIHJldHVybiBmcm9tVmVjdG9yVGlsZUpzKHsgbGF5ZXJzOiBsIH0pXG59XG5cbmZ1bmN0aW9uIHdyaXRlVGlsZSAodGlsZSwgcGJmKSB7XG4gIGZvciAodmFyIGtleSBpbiB0aWxlLmxheWVycykge1xuICAgIHBiZi53cml0ZU1lc3NhZ2UoMywgd3JpdGVMYXllciwgdGlsZS5sYXllcnNba2V5XSlcbiAgfVxufVxuXG5mdW5jdGlvbiB3cml0ZUxheWVyIChsYXllciwgcGJmKSB7XG4gIHBiZi53cml0ZVZhcmludEZpZWxkKDE1LCBsYXllci52ZXJzaW9uIHx8IDEpXG4gIHBiZi53cml0ZVN0cmluZ0ZpZWxkKDEsIGxheWVyLm5hbWUgfHwgJycpXG4gIHBiZi53cml0ZVZhcmludEZpZWxkKDUsIGxheWVyLmV4dGVudCB8fCA0MDk2KVxuXG4gIHZhciBpXG4gIHZhciBjb250ZXh0ID0ge1xuICAgIGtleXM6IFtdLFxuICAgIHZhbHVlczogW10sXG4gICAga2V5Y2FjaGU6IHt9LFxuICAgIHZhbHVlY2FjaGU6IHt9XG4gIH1cblxuICBmb3IgKGkgPSAwOyBpIDwgbGF5ZXIubGVuZ3RoOyBpKyspIHtcbiAgICBjb250ZXh0LmZlYXR1cmUgPSBsYXllci5mZWF0dXJlKGkpXG4gICAgcGJmLndyaXRlTWVzc2FnZSgyLCB3cml0ZUZlYXR1cmUsIGNvbnRleHQpXG4gIH1cblxuICB2YXIga2V5cyA9IGNvbnRleHQua2V5c1xuICBmb3IgKGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgIHBiZi53cml0ZVN0cmluZ0ZpZWxkKDMsIGtleXNbaV0pXG4gIH1cblxuICB2YXIgdmFsdWVzID0gY29udGV4dC52YWx1ZXNcbiAgZm9yIChpID0gMDsgaSA8IHZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgIHBiZi53cml0ZU1lc3NhZ2UoNCwgd3JpdGVWYWx1ZSwgdmFsdWVzW2ldKVxuICB9XG59XG5cbmZ1bmN0aW9uIHdyaXRlRmVhdHVyZSAoY29udGV4dCwgcGJmKSB7XG4gIHZhciBmZWF0dXJlID0gY29udGV4dC5mZWF0dXJlXG5cbiAgaWYgKGZlYXR1cmUuaWQgIT09IHVuZGVmaW5lZCkge1xuICAgIHBiZi53cml0ZVZhcmludEZpZWxkKDEsIGZlYXR1cmUuaWQpXG4gIH1cblxuICBwYmYud3JpdGVNZXNzYWdlKDIsIHdyaXRlUHJvcGVydGllcywgY29udGV4dClcbiAgcGJmLndyaXRlVmFyaW50RmllbGQoMywgZmVhdHVyZS50eXBlKVxuICBwYmYud3JpdGVNZXNzYWdlKDQsIHdyaXRlR2VvbWV0cnksIGZlYXR1cmUpXG59XG5cbmZ1bmN0aW9uIHdyaXRlUHJvcGVydGllcyAoY29udGV4dCwgcGJmKSB7XG4gIHZhciBmZWF0dXJlID0gY29udGV4dC5mZWF0dXJlXG4gIHZhciBrZXlzID0gY29udGV4dC5rZXlzXG4gIHZhciB2YWx1ZXMgPSBjb250ZXh0LnZhbHVlc1xuICB2YXIga2V5Y2FjaGUgPSBjb250ZXh0LmtleWNhY2hlXG4gIHZhciB2YWx1ZWNhY2hlID0gY29udGV4dC52YWx1ZWNhY2hlXG5cbiAgZm9yICh2YXIga2V5IGluIGZlYXR1cmUucHJvcGVydGllcykge1xuICAgIHZhciB2YWx1ZSA9IGZlYXR1cmUucHJvcGVydGllc1trZXldXG5cbiAgICB2YXIga2V5SW5kZXggPSBrZXljYWNoZVtrZXldXG4gICAgaWYgKHZhbHVlID09PSBudWxsKSBjb250aW51ZSAvLyBkb24ndCBlbmNvZGUgbnVsbCB2YWx1ZSBwcm9wZXJ0aWVzXG5cbiAgICBpZiAodHlwZW9mIGtleUluZGV4ID09PSAndW5kZWZpbmVkJykge1xuICAgICAga2V5cy5wdXNoKGtleSlcbiAgICAgIGtleUluZGV4ID0ga2V5cy5sZW5ndGggLSAxXG4gICAgICBrZXljYWNoZVtrZXldID0ga2V5SW5kZXhcbiAgICB9XG4gICAgcGJmLndyaXRlVmFyaW50KGtleUluZGV4KVxuXG4gICAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWVcbiAgICBpZiAodHlwZSAhPT0gJ3N0cmluZycgJiYgdHlwZSAhPT0gJ2Jvb2xlYW4nICYmIHR5cGUgIT09ICdudW1iZXInKSB7XG4gICAgICB2YWx1ZSA9IEpTT04uc3RyaW5naWZ5KHZhbHVlKVxuICAgIH1cbiAgICB2YXIgdmFsdWVLZXkgPSB0eXBlICsgJzonICsgdmFsdWVcbiAgICB2YXIgdmFsdWVJbmRleCA9IHZhbHVlY2FjaGVbdmFsdWVLZXldXG4gICAgaWYgKHR5cGVvZiB2YWx1ZUluZGV4ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgdmFsdWVzLnB1c2godmFsdWUpXG4gICAgICB2YWx1ZUluZGV4ID0gdmFsdWVzLmxlbmd0aCAtIDFcbiAgICAgIHZhbHVlY2FjaGVbdmFsdWVLZXldID0gdmFsdWVJbmRleFxuICAgIH1cbiAgICBwYmYud3JpdGVWYXJpbnQodmFsdWVJbmRleClcbiAgfVxufVxuXG5mdW5jdGlvbiBjb21tYW5kIChjbWQsIGxlbmd0aCkge1xuICByZXR1cm4gKGxlbmd0aCA8PCAzKSArIChjbWQgJiAweDcpXG59XG5cbmZ1bmN0aW9uIHppZ3phZyAobnVtKSB7XG4gIHJldHVybiAobnVtIDw8IDEpIF4gKG51bSA+PiAzMSlcbn1cblxuZnVuY3Rpb24gd3JpdGVHZW9tZXRyeSAoZmVhdHVyZSwgcGJmKSB7XG4gIHZhciBnZW9tZXRyeSA9IGZlYXR1cmUubG9hZEdlb21ldHJ5KClcbiAgdmFyIHR5cGUgPSBmZWF0dXJlLnR5cGVcbiAgdmFyIHggPSAwXG4gIHZhciB5ID0gMFxuICB2YXIgcmluZ3MgPSBnZW9tZXRyeS5sZW5ndGhcbiAgZm9yICh2YXIgciA9IDA7IHIgPCByaW5nczsgcisrKSB7XG4gICAgdmFyIHJpbmcgPSBnZW9tZXRyeVtyXVxuICAgIHZhciBjb3VudCA9IDFcbiAgICBpZiAodHlwZSA9PT0gMSkge1xuICAgICAgY291bnQgPSByaW5nLmxlbmd0aFxuICAgIH1cbiAgICBwYmYud3JpdGVWYXJpbnQoY29tbWFuZCgxLCBjb3VudCkpIC8vIG1vdmV0b1xuICAgIC8vIGRvIG5vdCB3cml0ZSBwb2x5Z29uIGNsb3NpbmcgcGF0aCBhcyBsaW5ldG9cbiAgICB2YXIgbGluZUNvdW50ID0gdHlwZSA9PT0gMyA/IHJpbmcubGVuZ3RoIC0gMSA6IHJpbmcubGVuZ3RoXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lQ291bnQ7IGkrKykge1xuICAgICAgaWYgKGkgPT09IDEgJiYgdHlwZSAhPT0gMSkge1xuICAgICAgICBwYmYud3JpdGVWYXJpbnQoY29tbWFuZCgyLCBsaW5lQ291bnQgLSAxKSkgLy8gbGluZXRvXG4gICAgICB9XG4gICAgICB2YXIgZHggPSByaW5nW2ldLnggLSB4XG4gICAgICB2YXIgZHkgPSByaW5nW2ldLnkgLSB5XG4gICAgICBwYmYud3JpdGVWYXJpbnQoemlnemFnKGR4KSlcbiAgICAgIHBiZi53cml0ZVZhcmludCh6aWd6YWcoZHkpKVxuICAgICAgeCArPSBkeFxuICAgICAgeSArPSBkeVxuICAgIH1cbiAgICBpZiAodHlwZSA9PT0gMykge1xuICAgICAgcGJmLndyaXRlVmFyaW50KGNvbW1hbmQoNywgMSkpIC8vIGNsb3NlcGF0aFxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiB3cml0ZVZhbHVlICh2YWx1ZSwgcGJmKSB7XG4gIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlXG4gIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgIHBiZi53cml0ZVN0cmluZ0ZpZWxkKDEsIHZhbHVlKVxuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdib29sZWFuJykge1xuICAgIHBiZi53cml0ZUJvb2xlYW5GaWVsZCg3LCB2YWx1ZSlcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJykge1xuICAgIGlmICh2YWx1ZSAlIDEgIT09IDApIHtcbiAgICAgIHBiZi53cml0ZURvdWJsZUZpZWxkKDMsIHZhbHVlKVxuICAgIH0gZWxzZSBpZiAodmFsdWUgPCAwKSB7XG4gICAgICBwYmYud3JpdGVTVmFyaW50RmllbGQoNiwgdmFsdWUpXG4gICAgfSBlbHNlIHtcbiAgICAgIHBiZi53cml0ZVZhcmludEZpZWxkKDUsIHZhbHVlKVxuICAgIH1cbiAgfVxufVxuIiwiXG5pbXBvcnQgS0RCdXNoIGZyb20gJ2tkYnVzaCc7XG5cbmNvbnN0IGRlZmF1bHRPcHRpb25zID0ge1xuICAgIG1pblpvb206IDAsICAgLy8gbWluIHpvb20gdG8gZ2VuZXJhdGUgY2x1c3RlcnMgb25cbiAgICBtYXhab29tOiAxNiwgIC8vIG1heCB6b29tIGxldmVsIHRvIGNsdXN0ZXIgdGhlIHBvaW50cyBvblxuICAgIG1pblBvaW50czogMiwgLy8gbWluaW11bSBwb2ludHMgdG8gZm9ybSBhIGNsdXN0ZXJcbiAgICByYWRpdXM6IDQwLCAgIC8vIGNsdXN0ZXIgcmFkaXVzIGluIHBpeGVsc1xuICAgIGV4dGVudDogNTEyLCAgLy8gdGlsZSBleHRlbnQgKHJhZGl1cyBpcyBjYWxjdWxhdGVkIHJlbGF0aXZlIHRvIGl0KVxuICAgIG5vZGVTaXplOiA2NCwgLy8gc2l6ZSBvZiB0aGUgS0QtdHJlZSBsZWFmIG5vZGUsIGFmZmVjdHMgcGVyZm9ybWFuY2VcbiAgICBsb2c6IGZhbHNlLCAgIC8vIHdoZXRoZXIgdG8gbG9nIHRpbWluZyBpbmZvXG5cbiAgICAvLyB3aGV0aGVyIHRvIGdlbmVyYXRlIG51bWVyaWMgaWRzIGZvciBpbnB1dCBmZWF0dXJlcyAoaW4gdmVjdG9yIHRpbGVzKVxuICAgIGdlbmVyYXRlSWQ6IGZhbHNlLFxuXG4gICAgLy8gYSByZWR1Y2UgZnVuY3Rpb24gZm9yIGNhbGN1bGF0aW5nIGN1c3RvbSBjbHVzdGVyIHByb3BlcnRpZXNcbiAgICByZWR1Y2U6IG51bGwsIC8vIChhY2N1bXVsYXRlZCwgcHJvcHMpID0+IHsgYWNjdW11bGF0ZWQuc3VtICs9IHByb3BzLnN1bTsgfVxuXG4gICAgLy8gcHJvcGVydGllcyB0byB1c2UgZm9yIGluZGl2aWR1YWwgcG9pbnRzIHdoZW4gcnVubmluZyB0aGUgcmVkdWNlclxuICAgIG1hcDogcHJvcHMgPT4gcHJvcHMgLy8gcHJvcHMgPT4gKHtzdW06IHByb3BzLm15X3ZhbHVlfSlcbn07XG5cbmNvbnN0IGZyb3VuZCA9IE1hdGguZnJvdW5kIHx8ICh0bXAgPT4gKCh4KSA9PiB7IHRtcFswXSA9ICt4OyByZXR1cm4gdG1wWzBdOyB9KSkobmV3IEZsb2F0MzJBcnJheSgxKSk7XG5cbmNvbnN0IE9GRlNFVF9aT09NID0gMjtcbmNvbnN0IE9GRlNFVF9JRCA9IDM7XG5jb25zdCBPRkZTRVRfUEFSRU5UID0gNDtcbmNvbnN0IE9GRlNFVF9OVU0gPSA1O1xuY29uc3QgT0ZGU0VUX1BST1AgPSA2O1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTdXBlcmNsdXN0ZXIge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gT2JqZWN0LmFzc2lnbihPYmplY3QuY3JlYXRlKGRlZmF1bHRPcHRpb25zKSwgb3B0aW9ucyk7XG4gICAgICAgIHRoaXMudHJlZXMgPSBuZXcgQXJyYXkodGhpcy5vcHRpb25zLm1heFpvb20gKyAxKTtcbiAgICAgICAgdGhpcy5zdHJpZGUgPSB0aGlzLm9wdGlvbnMucmVkdWNlID8gNyA6IDY7XG4gICAgICAgIHRoaXMuY2x1c3RlclByb3BzID0gW107XG4gICAgfVxuXG4gICAgbG9hZChwb2ludHMpIHtcbiAgICAgICAgY29uc3Qge2xvZywgbWluWm9vbSwgbWF4Wm9vbX0gPSB0aGlzLm9wdGlvbnM7XG5cbiAgICAgICAgaWYgKGxvZykgY29uc29sZS50aW1lKCd0b3RhbCB0aW1lJyk7XG5cbiAgICAgICAgY29uc3QgdGltZXJJZCA9IGBwcmVwYXJlICR7ICBwb2ludHMubGVuZ3RoICB9IHBvaW50c2A7XG4gICAgICAgIGlmIChsb2cpIGNvbnNvbGUudGltZSh0aW1lcklkKTtcblxuICAgICAgICB0aGlzLnBvaW50cyA9IHBvaW50cztcblxuICAgICAgICAvLyBnZW5lcmF0ZSBhIGNsdXN0ZXIgb2JqZWN0IGZvciBlYWNoIHBvaW50IGFuZCBpbmRleCBpbnB1dCBwb2ludHMgaW50byBhIEtELXRyZWVcbiAgICAgICAgY29uc3QgZGF0YSA9IFtdO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBwID0gcG9pbnRzW2ldO1xuICAgICAgICAgICAgaWYgKCFwLmdlb21ldHJ5KSBjb250aW51ZTtcblxuICAgICAgICAgICAgY29uc3QgW2xuZywgbGF0XSA9IHAuZ2VvbWV0cnkuY29vcmRpbmF0ZXM7XG4gICAgICAgICAgICBjb25zdCB4ID0gZnJvdW5kKGxuZ1gobG5nKSk7XG4gICAgICAgICAgICBjb25zdCB5ID0gZnJvdW5kKGxhdFkobGF0KSk7XG4gICAgICAgICAgICAvLyBzdG9yZSBpbnRlcm5hbCBwb2ludC9jbHVzdGVyIGRhdGEgaW4gZmxhdCBudW1lcmljIGFycmF5cyBmb3IgcGVyZm9ybWFuY2VcbiAgICAgICAgICAgIGRhdGEucHVzaChcbiAgICAgICAgICAgICAgICB4LCB5LCAvLyBwcm9qZWN0ZWQgcG9pbnQgY29vcmRpbmF0ZXNcbiAgICAgICAgICAgICAgICBJbmZpbml0eSwgLy8gdGhlIGxhc3Qgem9vbSB0aGUgcG9pbnQgd2FzIHByb2Nlc3NlZCBhdFxuICAgICAgICAgICAgICAgIGksIC8vIGluZGV4IG9mIHRoZSBzb3VyY2UgZmVhdHVyZSBpbiB0aGUgb3JpZ2luYWwgaW5wdXQgYXJyYXlcbiAgICAgICAgICAgICAgICAtMSwgLy8gcGFyZW50IGNsdXN0ZXIgaWRcbiAgICAgICAgICAgICAgICAxIC8vIG51bWJlciBvZiBwb2ludHMgaW4gYSBjbHVzdGVyXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5yZWR1Y2UpIGRhdGEucHVzaCgwKTsgLy8gbm9vcFxuICAgICAgICB9XG4gICAgICAgIGxldCB0cmVlID0gdGhpcy50cmVlc1ttYXhab29tICsgMV0gPSB0aGlzLl9jcmVhdGVUcmVlKGRhdGEpO1xuXG4gICAgICAgIGlmIChsb2cpIGNvbnNvbGUudGltZUVuZCh0aW1lcklkKTtcblxuICAgICAgICAvLyBjbHVzdGVyIHBvaW50cyBvbiBtYXggem9vbSwgdGhlbiBjbHVzdGVyIHRoZSByZXN1bHRzIG9uIHByZXZpb3VzIHpvb20sIGV0Yy47XG4gICAgICAgIC8vIHJlc3VsdHMgaW4gYSBjbHVzdGVyIGhpZXJhcmNoeSBhY3Jvc3Mgem9vbSBsZXZlbHNcbiAgICAgICAgZm9yIChsZXQgeiA9IG1heFpvb207IHogPj0gbWluWm9vbTsgei0tKSB7XG4gICAgICAgICAgICBjb25zdCBub3cgPSArRGF0ZS5ub3coKTtcblxuICAgICAgICAgICAgLy8gY3JlYXRlIGEgbmV3IHNldCBvZiBjbHVzdGVycyBmb3IgdGhlIHpvb20gYW5kIGluZGV4IHRoZW0gd2l0aCBhIEtELXRyZWVcbiAgICAgICAgICAgIHRyZWUgPSB0aGlzLnRyZWVzW3pdID0gdGhpcy5fY3JlYXRlVHJlZSh0aGlzLl9jbHVzdGVyKHRyZWUsIHopKTtcblxuICAgICAgICAgICAgaWYgKGxvZykgY29uc29sZS5sb2coJ3olZDogJWQgY2x1c3RlcnMgaW4gJWRtcycsIHosIHRyZWUubnVtSXRlbXMsICtEYXRlLm5vdygpIC0gbm93KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChsb2cpIGNvbnNvbGUudGltZUVuZCgndG90YWwgdGltZScpO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIGdldENsdXN0ZXJzKGJib3gsIHpvb20pIHtcbiAgICAgICAgbGV0IG1pbkxuZyA9ICgoYmJveFswXSArIDE4MCkgJSAzNjAgKyAzNjApICUgMzYwIC0gMTgwO1xuICAgICAgICBjb25zdCBtaW5MYXQgPSBNYXRoLm1heCgtOTAsIE1hdGgubWluKDkwLCBiYm94WzFdKSk7XG4gICAgICAgIGxldCBtYXhMbmcgPSBiYm94WzJdID09PSAxODAgPyAxODAgOiAoKGJib3hbMl0gKyAxODApICUgMzYwICsgMzYwKSAlIDM2MCAtIDE4MDtcbiAgICAgICAgY29uc3QgbWF4TGF0ID0gTWF0aC5tYXgoLTkwLCBNYXRoLm1pbig5MCwgYmJveFszXSkpO1xuXG4gICAgICAgIGlmIChiYm94WzJdIC0gYmJveFswXSA+PSAzNjApIHtcbiAgICAgICAgICAgIG1pbkxuZyA9IC0xODA7XG4gICAgICAgICAgICBtYXhMbmcgPSAxODA7XG4gICAgICAgIH0gZWxzZSBpZiAobWluTG5nID4gbWF4TG5nKSB7XG4gICAgICAgICAgICBjb25zdCBlYXN0ZXJuSGVtID0gdGhpcy5nZXRDbHVzdGVycyhbbWluTG5nLCBtaW5MYXQsIDE4MCwgbWF4TGF0XSwgem9vbSk7XG4gICAgICAgICAgICBjb25zdCB3ZXN0ZXJuSGVtID0gdGhpcy5nZXRDbHVzdGVycyhbLTE4MCwgbWluTGF0LCBtYXhMbmcsIG1heExhdF0sIHpvb20pO1xuICAgICAgICAgICAgcmV0dXJuIGVhc3Rlcm5IZW0uY29uY2F0KHdlc3Rlcm5IZW0pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdHJlZSA9IHRoaXMudHJlZXNbdGhpcy5fbGltaXRab29tKHpvb20pXTtcbiAgICAgICAgY29uc3QgaWRzID0gdHJlZS5yYW5nZShsbmdYKG1pbkxuZyksIGxhdFkobWF4TGF0KSwgbG5nWChtYXhMbmcpLCBsYXRZKG1pbkxhdCkpO1xuICAgICAgICBjb25zdCBkYXRhID0gdHJlZS5kYXRhO1xuICAgICAgICBjb25zdCBjbHVzdGVycyA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IGlkIG9mIGlkcykge1xuICAgICAgICAgICAgY29uc3QgayA9IHRoaXMuc3RyaWRlICogaWQ7XG4gICAgICAgICAgICBjbHVzdGVycy5wdXNoKGRhdGFbayArIE9GRlNFVF9OVU1dID4gMSA/IGdldENsdXN0ZXJKU09OKGRhdGEsIGssIHRoaXMuY2x1c3RlclByb3BzKSA6IHRoaXMucG9pbnRzW2RhdGFbayArIE9GRlNFVF9JRF1dKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2x1c3RlcnM7XG4gICAgfVxuXG4gICAgZ2V0Q2hpbGRyZW4oY2x1c3RlcklkKSB7XG4gICAgICAgIGNvbnN0IG9yaWdpbklkID0gdGhpcy5fZ2V0T3JpZ2luSWQoY2x1c3RlcklkKTtcbiAgICAgICAgY29uc3Qgb3JpZ2luWm9vbSA9IHRoaXMuX2dldE9yaWdpblpvb20oY2x1c3RlcklkKTtcbiAgICAgICAgY29uc3QgZXJyb3JNc2cgPSAnTm8gY2x1c3RlciB3aXRoIHRoZSBzcGVjaWZpZWQgaWQuJztcblxuICAgICAgICBjb25zdCB0cmVlID0gdGhpcy50cmVlc1tvcmlnaW5ab29tXTtcbiAgICAgICAgaWYgKCF0cmVlKSB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNc2cpO1xuXG4gICAgICAgIGNvbnN0IGRhdGEgPSB0cmVlLmRhdGE7XG4gICAgICAgIGlmIChvcmlnaW5JZCAqIHRoaXMuc3RyaWRlID49IGRhdGEubGVuZ3RoKSB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNc2cpO1xuXG4gICAgICAgIGNvbnN0IHIgPSB0aGlzLm9wdGlvbnMucmFkaXVzIC8gKHRoaXMub3B0aW9ucy5leHRlbnQgKiBNYXRoLnBvdygyLCBvcmlnaW5ab29tIC0gMSkpO1xuICAgICAgICBjb25zdCB4ID0gZGF0YVtvcmlnaW5JZCAqIHRoaXMuc3RyaWRlXTtcbiAgICAgICAgY29uc3QgeSA9IGRhdGFbb3JpZ2luSWQgKiB0aGlzLnN0cmlkZSArIDFdO1xuICAgICAgICBjb25zdCBpZHMgPSB0cmVlLndpdGhpbih4LCB5LCByKTtcbiAgICAgICAgY29uc3QgY2hpbGRyZW4gPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBpZCBvZiBpZHMpIHtcbiAgICAgICAgICAgIGNvbnN0IGsgPSBpZCAqIHRoaXMuc3RyaWRlO1xuICAgICAgICAgICAgaWYgKGRhdGFbayArIE9GRlNFVF9QQVJFTlRdID09PSBjbHVzdGVySWQpIHtcbiAgICAgICAgICAgICAgICBjaGlsZHJlbi5wdXNoKGRhdGFbayArIE9GRlNFVF9OVU1dID4gMSA/IGdldENsdXN0ZXJKU09OKGRhdGEsIGssIHRoaXMuY2x1c3RlclByb3BzKSA6IHRoaXMucG9pbnRzW2RhdGFbayArIE9GRlNFVF9JRF1dKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjaGlsZHJlbi5sZW5ndGggPT09IDApIHRocm93IG5ldyBFcnJvcihlcnJvck1zZyk7XG5cbiAgICAgICAgcmV0dXJuIGNoaWxkcmVuO1xuICAgIH1cblxuICAgIGdldExlYXZlcyhjbHVzdGVySWQsIGxpbWl0LCBvZmZzZXQpIHtcbiAgICAgICAgbGltaXQgPSBsaW1pdCB8fCAxMDtcbiAgICAgICAgb2Zmc2V0ID0gb2Zmc2V0IHx8IDA7XG5cbiAgICAgICAgY29uc3QgbGVhdmVzID0gW107XG4gICAgICAgIHRoaXMuX2FwcGVuZExlYXZlcyhsZWF2ZXMsIGNsdXN0ZXJJZCwgbGltaXQsIG9mZnNldCwgMCk7XG5cbiAgICAgICAgcmV0dXJuIGxlYXZlcztcbiAgICB9XG5cbiAgICBnZXRUaWxlKHosIHgsIHkpIHtcbiAgICAgICAgY29uc3QgdHJlZSA9IHRoaXMudHJlZXNbdGhpcy5fbGltaXRab29tKHopXTtcbiAgICAgICAgY29uc3QgejIgPSBNYXRoLnBvdygyLCB6KTtcbiAgICAgICAgY29uc3Qge2V4dGVudCwgcmFkaXVzfSA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgY29uc3QgcCA9IHJhZGl1cyAvIGV4dGVudDtcbiAgICAgICAgY29uc3QgdG9wID0gKHkgLSBwKSAvIHoyO1xuICAgICAgICBjb25zdCBib3R0b20gPSAoeSArIDEgKyBwKSAvIHoyO1xuXG4gICAgICAgIGNvbnN0IHRpbGUgPSB7XG4gICAgICAgICAgICBmZWF0dXJlczogW11cbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLl9hZGRUaWxlRmVhdHVyZXMoXG4gICAgICAgICAgICB0cmVlLnJhbmdlKCh4IC0gcCkgLyB6MiwgdG9wLCAoeCArIDEgKyBwKSAvIHoyLCBib3R0b20pLFxuICAgICAgICAgICAgdHJlZS5kYXRhLCB4LCB5LCB6MiwgdGlsZSk7XG5cbiAgICAgICAgaWYgKHggPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMuX2FkZFRpbGVGZWF0dXJlcyhcbiAgICAgICAgICAgICAgICB0cmVlLnJhbmdlKDEgLSBwIC8gejIsIHRvcCwgMSwgYm90dG9tKSxcbiAgICAgICAgICAgICAgICB0cmVlLmRhdGEsIHoyLCB5LCB6MiwgdGlsZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHggPT09IHoyIC0gMSkge1xuICAgICAgICAgICAgdGhpcy5fYWRkVGlsZUZlYXR1cmVzKFxuICAgICAgICAgICAgICAgIHRyZWUucmFuZ2UoMCwgdG9wLCBwIC8gejIsIGJvdHRvbSksXG4gICAgICAgICAgICAgICAgdHJlZS5kYXRhLCAtMSwgeSwgejIsIHRpbGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRpbGUuZmVhdHVyZXMubGVuZ3RoID8gdGlsZSA6IG51bGw7XG4gICAgfVxuXG4gICAgZ2V0Q2x1c3RlckV4cGFuc2lvblpvb20oY2x1c3RlcklkKSB7XG4gICAgICAgIGxldCBleHBhbnNpb25ab29tID0gdGhpcy5fZ2V0T3JpZ2luWm9vbShjbHVzdGVySWQpIC0gMTtcbiAgICAgICAgd2hpbGUgKGV4cGFuc2lvblpvb20gPD0gdGhpcy5vcHRpb25zLm1heFpvb20pIHtcbiAgICAgICAgICAgIGNvbnN0IGNoaWxkcmVuID0gdGhpcy5nZXRDaGlsZHJlbihjbHVzdGVySWQpO1xuICAgICAgICAgICAgZXhwYW5zaW9uWm9vbSsrO1xuICAgICAgICAgICAgaWYgKGNoaWxkcmVuLmxlbmd0aCAhPT0gMSkgYnJlYWs7XG4gICAgICAgICAgICBjbHVzdGVySWQgPSBjaGlsZHJlblswXS5wcm9wZXJ0aWVzLmNsdXN0ZXJfaWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGV4cGFuc2lvblpvb207XG4gICAgfVxuXG4gICAgX2FwcGVuZExlYXZlcyhyZXN1bHQsIGNsdXN0ZXJJZCwgbGltaXQsIG9mZnNldCwgc2tpcHBlZCkge1xuICAgICAgICBjb25zdCBjaGlsZHJlbiA9IHRoaXMuZ2V0Q2hpbGRyZW4oY2x1c3RlcklkKTtcblxuICAgICAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIGNoaWxkcmVuKSB7XG4gICAgICAgICAgICBjb25zdCBwcm9wcyA9IGNoaWxkLnByb3BlcnRpZXM7XG5cbiAgICAgICAgICAgIGlmIChwcm9wcyAmJiBwcm9wcy5jbHVzdGVyKSB7XG4gICAgICAgICAgICAgICAgaWYgKHNraXBwZWQgKyBwcm9wcy5wb2ludF9jb3VudCA8PSBvZmZzZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gc2tpcCB0aGUgd2hvbGUgY2x1c3RlclxuICAgICAgICAgICAgICAgICAgICBza2lwcGVkICs9IHByb3BzLnBvaW50X2NvdW50O1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGVudGVyIHRoZSBjbHVzdGVyXG4gICAgICAgICAgICAgICAgICAgIHNraXBwZWQgPSB0aGlzLl9hcHBlbmRMZWF2ZXMocmVzdWx0LCBwcm9wcy5jbHVzdGVyX2lkLCBsaW1pdCwgb2Zmc2V0LCBza2lwcGVkKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gZXhpdCB0aGUgY2x1c3RlclxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoc2tpcHBlZCA8IG9mZnNldCkge1xuICAgICAgICAgICAgICAgIC8vIHNraXAgYSBzaW5nbGUgcG9pbnRcbiAgICAgICAgICAgICAgICBza2lwcGVkKys7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIGFkZCBhIHNpbmdsZSBwb2ludFxuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKGNoaWxkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChyZXN1bHQubGVuZ3RoID09PSBsaW1pdCkgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gc2tpcHBlZDtcbiAgICB9XG5cbiAgICBfY3JlYXRlVHJlZShkYXRhKSB7XG4gICAgICAgIGNvbnN0IHRyZWUgPSBuZXcgS0RCdXNoKGRhdGEubGVuZ3RoIC8gdGhpcy5zdHJpZGUgfCAwLCB0aGlzLm9wdGlvbnMubm9kZVNpemUsIEZsb2F0MzJBcnJheSk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkgKz0gdGhpcy5zdHJpZGUpIHRyZWUuYWRkKGRhdGFbaV0sIGRhdGFbaSArIDFdKTtcbiAgICAgICAgdHJlZS5maW5pc2goKTtcbiAgICAgICAgdHJlZS5kYXRhID0gZGF0YTtcbiAgICAgICAgcmV0dXJuIHRyZWU7XG4gICAgfVxuXG4gICAgX2FkZFRpbGVGZWF0dXJlcyhpZHMsIGRhdGEsIHgsIHksIHoyLCB0aWxlKSB7XG4gICAgICAgIGZvciAoY29uc3QgaSBvZiBpZHMpIHtcbiAgICAgICAgICAgIGNvbnN0IGsgPSBpICogdGhpcy5zdHJpZGU7XG4gICAgICAgICAgICBjb25zdCBpc0NsdXN0ZXIgPSBkYXRhW2sgKyBPRkZTRVRfTlVNXSA+IDE7XG5cbiAgICAgICAgICAgIGxldCB0YWdzLCBweCwgcHk7XG4gICAgICAgICAgICBpZiAoaXNDbHVzdGVyKSB7XG4gICAgICAgICAgICAgICAgdGFncyA9IGdldENsdXN0ZXJQcm9wZXJ0aWVzKGRhdGEsIGssIHRoaXMuY2x1c3RlclByb3BzKTtcbiAgICAgICAgICAgICAgICBweCA9IGRhdGFba107XG4gICAgICAgICAgICAgICAgcHkgPSBkYXRhW2sgKyAxXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcCA9IHRoaXMucG9pbnRzW2RhdGFbayArIE9GRlNFVF9JRF1dO1xuICAgICAgICAgICAgICAgIHRhZ3MgPSBwLnByb3BlcnRpZXM7XG4gICAgICAgICAgICAgICAgY29uc3QgW2xuZywgbGF0XSA9IHAuZ2VvbWV0cnkuY29vcmRpbmF0ZXM7XG4gICAgICAgICAgICAgICAgcHggPSBsbmdYKGxuZyk7XG4gICAgICAgICAgICAgICAgcHkgPSBsYXRZKGxhdCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGYgPSB7XG4gICAgICAgICAgICAgICAgdHlwZTogMSxcbiAgICAgICAgICAgICAgICBnZW9tZXRyeTogW1tcbiAgICAgICAgICAgICAgICAgICAgTWF0aC5yb3VuZCh0aGlzLm9wdGlvbnMuZXh0ZW50ICogKHB4ICogejIgLSB4KSksXG4gICAgICAgICAgICAgICAgICAgIE1hdGgucm91bmQodGhpcy5vcHRpb25zLmV4dGVudCAqIChweSAqIHoyIC0geSkpXG4gICAgICAgICAgICAgICAgXV0sXG4gICAgICAgICAgICAgICAgdGFnc1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLy8gYXNzaWduIGlkXG4gICAgICAgICAgICBsZXQgaWQ7XG4gICAgICAgICAgICBpZiAoaXNDbHVzdGVyIHx8IHRoaXMub3B0aW9ucy5nZW5lcmF0ZUlkKSB7XG4gICAgICAgICAgICAgICAgLy8gb3B0aW9uYWxseSBnZW5lcmF0ZSBpZCBmb3IgcG9pbnRzXG4gICAgICAgICAgICAgICAgaWQgPSBkYXRhW2sgKyBPRkZTRVRfSURdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBrZWVwIGlkIGlmIGFscmVhZHkgYXNzaWduZWRcbiAgICAgICAgICAgICAgICBpZCA9IHRoaXMucG9pbnRzW2RhdGFbayArIE9GRlNFVF9JRF1dLmlkO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoaWQgIT09IHVuZGVmaW5lZCkgZi5pZCA9IGlkO1xuXG4gICAgICAgICAgICB0aWxlLmZlYXR1cmVzLnB1c2goZik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfbGltaXRab29tKHopIHtcbiAgICAgICAgcmV0dXJuIE1hdGgubWF4KHRoaXMub3B0aW9ucy5taW5ab29tLCBNYXRoLm1pbihNYXRoLmZsb29yKCt6KSwgdGhpcy5vcHRpb25zLm1heFpvb20gKyAxKSk7XG4gICAgfVxuXG4gICAgX2NsdXN0ZXIodHJlZSwgem9vbSkge1xuICAgICAgICBjb25zdCB7cmFkaXVzLCBleHRlbnQsIHJlZHVjZSwgbWluUG9pbnRzfSA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgY29uc3QgciA9IHJhZGl1cyAvIChleHRlbnQgKiBNYXRoLnBvdygyLCB6b29tKSk7XG4gICAgICAgIGNvbnN0IGRhdGEgPSB0cmVlLmRhdGE7XG4gICAgICAgIGNvbnN0IG5leHREYXRhID0gW107XG4gICAgICAgIGNvbnN0IHN0cmlkZSA9IHRoaXMuc3RyaWRlO1xuXG4gICAgICAgIC8vIGxvb3AgdGhyb3VnaCBlYWNoIHBvaW50XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkgKz0gc3RyaWRlKSB7XG4gICAgICAgICAgICAvLyBpZiB3ZSd2ZSBhbHJlYWR5IHZpc2l0ZWQgdGhlIHBvaW50IGF0IHRoaXMgem9vbSBsZXZlbCwgc2tpcCBpdFxuICAgICAgICAgICAgaWYgKGRhdGFbaSArIE9GRlNFVF9aT09NXSA8PSB6b29tKSBjb250aW51ZTtcbiAgICAgICAgICAgIGRhdGFbaSArIE9GRlNFVF9aT09NXSA9IHpvb207XG5cbiAgICAgICAgICAgIC8vIGZpbmQgYWxsIG5lYXJieSBwb2ludHNcbiAgICAgICAgICAgIGNvbnN0IHggPSBkYXRhW2ldO1xuICAgICAgICAgICAgY29uc3QgeSA9IGRhdGFbaSArIDFdO1xuICAgICAgICAgICAgY29uc3QgbmVpZ2hib3JJZHMgPSB0cmVlLndpdGhpbihkYXRhW2ldLCBkYXRhW2kgKyAxXSwgcik7XG5cbiAgICAgICAgICAgIGNvbnN0IG51bVBvaW50c09yaWdpbiA9IGRhdGFbaSArIE9GRlNFVF9OVU1dO1xuICAgICAgICAgICAgbGV0IG51bVBvaW50cyA9IG51bVBvaW50c09yaWdpbjtcblxuICAgICAgICAgICAgLy8gY291bnQgdGhlIG51bWJlciBvZiBwb2ludHMgaW4gYSBwb3RlbnRpYWwgY2x1c3RlclxuICAgICAgICAgICAgZm9yIChjb25zdCBuZWlnaGJvcklkIG9mIG5laWdoYm9ySWRzKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgayA9IG5laWdoYm9ySWQgKiBzdHJpZGU7XG4gICAgICAgICAgICAgICAgLy8gZmlsdGVyIG91dCBuZWlnaGJvcnMgdGhhdCBhcmUgYWxyZWFkeSBwcm9jZXNzZWRcbiAgICAgICAgICAgICAgICBpZiAoZGF0YVtrICsgT0ZGU0VUX1pPT01dID4gem9vbSkgbnVtUG9pbnRzICs9IGRhdGFbayArIE9GRlNFVF9OVU1dO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBpZiB0aGVyZSB3ZXJlIG5laWdoYm9ycyB0byBtZXJnZSwgYW5kIHRoZXJlIGFyZSBlbm91Z2ggcG9pbnRzIHRvIGZvcm0gYSBjbHVzdGVyXG4gICAgICAgICAgICBpZiAobnVtUG9pbnRzID4gbnVtUG9pbnRzT3JpZ2luICYmIG51bVBvaW50cyA+PSBtaW5Qb2ludHMpIHtcbiAgICAgICAgICAgICAgICBsZXQgd3ggPSB4ICogbnVtUG9pbnRzT3JpZ2luO1xuICAgICAgICAgICAgICAgIGxldCB3eSA9IHkgKiBudW1Qb2ludHNPcmlnaW47XG5cbiAgICAgICAgICAgICAgICBsZXQgY2x1c3RlclByb3BlcnRpZXM7XG4gICAgICAgICAgICAgICAgbGV0IGNsdXN0ZXJQcm9wSW5kZXggPSAtMTtcblxuICAgICAgICAgICAgICAgIC8vIGVuY29kZSBib3RoIHpvb20gYW5kIHBvaW50IGluZGV4IG9uIHdoaWNoIHRoZSBjbHVzdGVyIG9yaWdpbmF0ZWQgLS0gb2Zmc2V0IGJ5IHRvdGFsIGxlbmd0aCBvZiBmZWF0dXJlc1xuICAgICAgICAgICAgICAgIGNvbnN0IGlkID0gKChpIC8gc3RyaWRlIHwgMCkgPDwgNSkgKyAoem9vbSArIDEpICsgdGhpcy5wb2ludHMubGVuZ3RoO1xuXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBuZWlnaGJvcklkIG9mIG5laWdoYm9ySWRzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGsgPSBuZWlnaGJvcklkICogc3RyaWRlO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhW2sgKyBPRkZTRVRfWk9PTV0gPD0gem9vbSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIGRhdGFbayArIE9GRlNFVF9aT09NXSA9IHpvb207IC8vIHNhdmUgdGhlIHpvb20gKHNvIGl0IGRvZXNuJ3QgZ2V0IHByb2Nlc3NlZCB0d2ljZSlcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBudW1Qb2ludHMyID0gZGF0YVtrICsgT0ZGU0VUX05VTV07XG4gICAgICAgICAgICAgICAgICAgIHd4ICs9IGRhdGFba10gKiBudW1Qb2ludHMyOyAvLyBhY2N1bXVsYXRlIGNvb3JkaW5hdGVzIGZvciBjYWxjdWxhdGluZyB3ZWlnaHRlZCBjZW50ZXJcbiAgICAgICAgICAgICAgICAgICAgd3kgKz0gZGF0YVtrICsgMV0gKiBudW1Qb2ludHMyO1xuXG4gICAgICAgICAgICAgICAgICAgIGRhdGFbayArIE9GRlNFVF9QQVJFTlRdID0gaWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlZHVjZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjbHVzdGVyUHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsdXN0ZXJQcm9wZXJ0aWVzID0gdGhpcy5fbWFwKGRhdGEsIGksIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsdXN0ZXJQcm9wSW5kZXggPSB0aGlzLmNsdXN0ZXJQcm9wcy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbHVzdGVyUHJvcHMucHVzaChjbHVzdGVyUHJvcGVydGllcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICByZWR1Y2UoY2x1c3RlclByb3BlcnRpZXMsIHRoaXMuX21hcChkYXRhLCBrKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBkYXRhW2kgKyBPRkZTRVRfUEFSRU5UXSA9IGlkO1xuICAgICAgICAgICAgICAgIG5leHREYXRhLnB1c2god3ggLyBudW1Qb2ludHMsIHd5IC8gbnVtUG9pbnRzLCBJbmZpbml0eSwgaWQsIC0xLCBudW1Qb2ludHMpO1xuICAgICAgICAgICAgICAgIGlmIChyZWR1Y2UpIG5leHREYXRhLnB1c2goY2x1c3RlclByb3BJbmRleCk7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7IC8vIGxlZnQgcG9pbnRzIGFzIHVuY2x1c3RlcmVkXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBzdHJpZGU7IGorKykgbmV4dERhdGEucHVzaChkYXRhW2kgKyBqXSk7XG5cbiAgICAgICAgICAgICAgICBpZiAobnVtUG9pbnRzID4gMSkge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IG5laWdoYm9ySWQgb2YgbmVpZ2hib3JJZHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGsgPSBuZWlnaGJvcklkICogc3RyaWRlO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGFbayArIE9GRlNFVF9aT09NXSA8PSB6b29tKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFbayArIE9GRlNFVF9aT09NXSA9IHpvb207XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHN0cmlkZTsgaisrKSBuZXh0RGF0YS5wdXNoKGRhdGFbayArIGpdKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXh0RGF0YTtcbiAgICB9XG5cbiAgICAvLyBnZXQgaW5kZXggb2YgdGhlIHBvaW50IGZyb20gd2hpY2ggdGhlIGNsdXN0ZXIgb3JpZ2luYXRlZFxuICAgIF9nZXRPcmlnaW5JZChjbHVzdGVySWQpIHtcbiAgICAgICAgcmV0dXJuIChjbHVzdGVySWQgLSB0aGlzLnBvaW50cy5sZW5ndGgpID4+IDU7XG4gICAgfVxuXG4gICAgLy8gZ2V0IHpvb20gb2YgdGhlIHBvaW50IGZyb20gd2hpY2ggdGhlIGNsdXN0ZXIgb3JpZ2luYXRlZFxuICAgIF9nZXRPcmlnaW5ab29tKGNsdXN0ZXJJZCkge1xuICAgICAgICByZXR1cm4gKGNsdXN0ZXJJZCAtIHRoaXMucG9pbnRzLmxlbmd0aCkgJSAzMjtcbiAgICB9XG5cbiAgICBfbWFwKGRhdGEsIGksIGNsb25lKSB7XG4gICAgICAgIGlmIChkYXRhW2kgKyBPRkZTRVRfTlVNXSA+IDEpIHtcbiAgICAgICAgICAgIGNvbnN0IHByb3BzID0gdGhpcy5jbHVzdGVyUHJvcHNbZGF0YVtpICsgT0ZGU0VUX1BST1BdXTtcbiAgICAgICAgICAgIHJldHVybiBjbG9uZSA/IE9iamVjdC5hc3NpZ24oe30sIHByb3BzKSA6IHByb3BzO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsID0gdGhpcy5wb2ludHNbZGF0YVtpICsgT0ZGU0VUX0lEXV0ucHJvcGVydGllcztcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5vcHRpb25zLm1hcChvcmlnaW5hbCk7XG4gICAgICAgIHJldHVybiBjbG9uZSAmJiByZXN1bHQgPT09IG9yaWdpbmFsID8gT2JqZWN0LmFzc2lnbih7fSwgcmVzdWx0KSA6IHJlc3VsdDtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGdldENsdXN0ZXJKU09OKGRhdGEsIGksIGNsdXN0ZXJQcm9wcykge1xuICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdGZWF0dXJlJyxcbiAgICAgICAgaWQ6IGRhdGFbaSArIE9GRlNFVF9JRF0sXG4gICAgICAgIHByb3BlcnRpZXM6IGdldENsdXN0ZXJQcm9wZXJ0aWVzKGRhdGEsIGksIGNsdXN0ZXJQcm9wcyksXG4gICAgICAgIGdlb21ldHJ5OiB7XG4gICAgICAgICAgICB0eXBlOiAnUG9pbnQnLFxuICAgICAgICAgICAgY29vcmRpbmF0ZXM6IFt4TG5nKGRhdGFbaV0pLCB5TGF0KGRhdGFbaSArIDFdKV1cbiAgICAgICAgfVxuICAgIH07XG59XG5cbmZ1bmN0aW9uIGdldENsdXN0ZXJQcm9wZXJ0aWVzKGRhdGEsIGksIGNsdXN0ZXJQcm9wcykge1xuICAgIGNvbnN0IGNvdW50ID0gZGF0YVtpICsgT0ZGU0VUX05VTV07XG4gICAgY29uc3QgYWJicmV2ID1cbiAgICAgICAgY291bnQgPj0gMTAwMDAgPyBgJHtNYXRoLnJvdW5kKGNvdW50IC8gMTAwMCkgIH1rYCA6XG4gICAgICAgIGNvdW50ID49IDEwMDAgPyBgJHtNYXRoLnJvdW5kKGNvdW50IC8gMTAwKSAvIDEwICB9a2AgOiBjb3VudDtcbiAgICBjb25zdCBwcm9wSW5kZXggPSBkYXRhW2kgKyBPRkZTRVRfUFJPUF07XG4gICAgY29uc3QgcHJvcGVydGllcyA9IHByb3BJbmRleCA9PT0gLTEgPyB7fSA6IE9iamVjdC5hc3NpZ24oe30sIGNsdXN0ZXJQcm9wc1twcm9wSW5kZXhdKTtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihwcm9wZXJ0aWVzLCB7XG4gICAgICAgIGNsdXN0ZXI6IHRydWUsXG4gICAgICAgIGNsdXN0ZXJfaWQ6IGRhdGFbaSArIE9GRlNFVF9JRF0sXG4gICAgICAgIHBvaW50X2NvdW50OiBjb3VudCxcbiAgICAgICAgcG9pbnRfY291bnRfYWJicmV2aWF0ZWQ6IGFiYnJldlxuICAgIH0pO1xufVxuXG4vLyBsb25naXR1ZGUvbGF0aXR1ZGUgdG8gc3BoZXJpY2FsIG1lcmNhdG9yIGluIFswLi4xXSByYW5nZVxuZnVuY3Rpb24gbG5nWChsbmcpIHtcbiAgICByZXR1cm4gbG5nIC8gMzYwICsgMC41O1xufVxuZnVuY3Rpb24gbGF0WShsYXQpIHtcbiAgICBjb25zdCBzaW4gPSBNYXRoLnNpbihsYXQgKiBNYXRoLlBJIC8gMTgwKTtcbiAgICBjb25zdCB5ID0gKDAuNSAtIDAuMjUgKiBNYXRoLmxvZygoMSArIHNpbikgLyAoMSAtIHNpbikpIC8gTWF0aC5QSSk7XG4gICAgcmV0dXJuIHkgPCAwID8gMCA6IHkgPiAxID8gMSA6IHk7XG59XG5cbi8vIHNwaGVyaWNhbCBtZXJjYXRvciB0byBsb25naXR1ZGUvbGF0aXR1ZGVcbmZ1bmN0aW9uIHhMbmcoeCkge1xuICAgIHJldHVybiAoeCAtIDAuNSkgKiAzNjA7XG59XG5mdW5jdGlvbiB5TGF0KHkpIHtcbiAgICBjb25zdCB5MiA9ICgxODAgLSB5ICogMzYwKSAqIE1hdGguUEkgLyAxODA7XG4gICAgcmV0dXJuIDM2MCAqIE1hdGguYXRhbihNYXRoLmV4cCh5MikpIC8gTWF0aC5QSSAtIDkwO1xufVxuIiwiXG4vLyBjYWxjdWxhdGUgc2ltcGxpZmljYXRpb24gZGF0YSB1c2luZyBvcHRpbWl6ZWQgRG91Z2xhcy1QZXVja2VyIGFsZ29yaXRobVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBzaW1wbGlmeShjb29yZHMsIGZpcnN0LCBsYXN0LCBzcVRvbGVyYW5jZSkge1xuICAgIHZhciBtYXhTcURpc3QgPSBzcVRvbGVyYW5jZTtcbiAgICB2YXIgbWlkID0gKGxhc3QgLSBmaXJzdCkgPj4gMTtcbiAgICB2YXIgbWluUG9zVG9NaWQgPSBsYXN0IC0gZmlyc3Q7XG4gICAgdmFyIGluZGV4O1xuXG4gICAgdmFyIGF4ID0gY29vcmRzW2ZpcnN0XTtcbiAgICB2YXIgYXkgPSBjb29yZHNbZmlyc3QgKyAxXTtcbiAgICB2YXIgYnggPSBjb29yZHNbbGFzdF07XG4gICAgdmFyIGJ5ID0gY29vcmRzW2xhc3QgKyAxXTtcblxuICAgIGZvciAodmFyIGkgPSBmaXJzdCArIDM7IGkgPCBsYXN0OyBpICs9IDMpIHtcbiAgICAgICAgdmFyIGQgPSBnZXRTcVNlZ0Rpc3QoY29vcmRzW2ldLCBjb29yZHNbaSArIDFdLCBheCwgYXksIGJ4LCBieSk7XG5cbiAgICAgICAgaWYgKGQgPiBtYXhTcURpc3QpIHtcbiAgICAgICAgICAgIGluZGV4ID0gaTtcbiAgICAgICAgICAgIG1heFNxRGlzdCA9IGQ7XG5cbiAgICAgICAgfSBlbHNlIGlmIChkID09PSBtYXhTcURpc3QpIHtcbiAgICAgICAgICAgIC8vIGEgd29ya2Fyb3VuZCB0byBlbnN1cmUgd2UgY2hvb3NlIGEgcGl2b3QgY2xvc2UgdG8gdGhlIG1pZGRsZSBvZiB0aGUgbGlzdCxcbiAgICAgICAgICAgIC8vIHJlZHVjaW5nIHJlY3Vyc2lvbiBkZXB0aCwgZm9yIGNlcnRhaW4gZGVnZW5lcmF0ZSBpbnB1dHNcbiAgICAgICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXBib3gvZ2VvanNvbi12dC9pc3N1ZXMvMTA0XG4gICAgICAgICAgICB2YXIgcG9zVG9NaWQgPSBNYXRoLmFicyhpIC0gbWlkKTtcbiAgICAgICAgICAgIGlmIChwb3NUb01pZCA8IG1pblBvc1RvTWlkKSB7XG4gICAgICAgICAgICAgICAgaW5kZXggPSBpO1xuICAgICAgICAgICAgICAgIG1pblBvc1RvTWlkID0gcG9zVG9NaWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobWF4U3FEaXN0ID4gc3FUb2xlcmFuY2UpIHtcbiAgICAgICAgaWYgKGluZGV4IC0gZmlyc3QgPiAzKSBzaW1wbGlmeShjb29yZHMsIGZpcnN0LCBpbmRleCwgc3FUb2xlcmFuY2UpO1xuICAgICAgICBjb29yZHNbaW5kZXggKyAyXSA9IG1heFNxRGlzdDtcbiAgICAgICAgaWYgKGxhc3QgLSBpbmRleCA+IDMpIHNpbXBsaWZ5KGNvb3JkcywgaW5kZXgsIGxhc3QsIHNxVG9sZXJhbmNlKTtcbiAgICB9XG59XG5cbi8vIHNxdWFyZSBkaXN0YW5jZSBmcm9tIGEgcG9pbnQgdG8gYSBzZWdtZW50XG5mdW5jdGlvbiBnZXRTcVNlZ0Rpc3QocHgsIHB5LCB4LCB5LCBieCwgYnkpIHtcblxuICAgIHZhciBkeCA9IGJ4IC0geDtcbiAgICB2YXIgZHkgPSBieSAtIHk7XG5cbiAgICBpZiAoZHggIT09IDAgfHwgZHkgIT09IDApIHtcblxuICAgICAgICB2YXIgdCA9ICgocHggLSB4KSAqIGR4ICsgKHB5IC0geSkgKiBkeSkgLyAoZHggKiBkeCArIGR5ICogZHkpO1xuXG4gICAgICAgIGlmICh0ID4gMSkge1xuICAgICAgICAgICAgeCA9IGJ4O1xuICAgICAgICAgICAgeSA9IGJ5O1xuXG4gICAgICAgIH0gZWxzZSBpZiAodCA+IDApIHtcbiAgICAgICAgICAgIHggKz0gZHggKiB0O1xuICAgICAgICAgICAgeSArPSBkeSAqIHQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBkeCA9IHB4IC0geDtcbiAgICBkeSA9IHB5IC0geTtcblxuICAgIHJldHVybiBkeCAqIGR4ICsgZHkgKiBkeTtcbn1cbiIsIlxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gY3JlYXRlRmVhdHVyZShpZCwgdHlwZSwgZ2VvbSwgdGFncykge1xuICAgIHZhciBmZWF0dXJlID0ge1xuICAgICAgICBpZDogdHlwZW9mIGlkID09PSAndW5kZWZpbmVkJyA/IG51bGwgOiBpZCxcbiAgICAgICAgdHlwZTogdHlwZSxcbiAgICAgICAgZ2VvbWV0cnk6IGdlb20sXG4gICAgICAgIHRhZ3M6IHRhZ3MsXG4gICAgICAgIG1pblg6IEluZmluaXR5LFxuICAgICAgICBtaW5ZOiBJbmZpbml0eSxcbiAgICAgICAgbWF4WDogLUluZmluaXR5LFxuICAgICAgICBtYXhZOiAtSW5maW5pdHlcbiAgICB9O1xuICAgIGNhbGNCQm94KGZlYXR1cmUpO1xuICAgIHJldHVybiBmZWF0dXJlO1xufVxuXG5mdW5jdGlvbiBjYWxjQkJveChmZWF0dXJlKSB7XG4gICAgdmFyIGdlb20gPSBmZWF0dXJlLmdlb21ldHJ5O1xuICAgIHZhciB0eXBlID0gZmVhdHVyZS50eXBlO1xuXG4gICAgaWYgKHR5cGUgPT09ICdQb2ludCcgfHwgdHlwZSA9PT0gJ011bHRpUG9pbnQnIHx8IHR5cGUgPT09ICdMaW5lU3RyaW5nJykge1xuICAgICAgICBjYWxjTGluZUJCb3goZmVhdHVyZSwgZ2VvbSk7XG5cbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdQb2x5Z29uJyB8fCB0eXBlID09PSAnTXVsdGlMaW5lU3RyaW5nJykge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGdlb20ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNhbGNMaW5lQkJveChmZWF0dXJlLCBnZW9tW2ldKTtcbiAgICAgICAgfVxuXG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnTXVsdGlQb2x5Z29uJykge1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZ2VvbS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBnZW9tW2ldLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgY2FsY0xpbmVCQm94KGZlYXR1cmUsIGdlb21baV1bal0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBjYWxjTGluZUJCb3goZmVhdHVyZSwgZ2VvbSkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZ2VvbS5sZW5ndGg7IGkgKz0gMykge1xuICAgICAgICBmZWF0dXJlLm1pblggPSBNYXRoLm1pbihmZWF0dXJlLm1pblgsIGdlb21baV0pO1xuICAgICAgICBmZWF0dXJlLm1pblkgPSBNYXRoLm1pbihmZWF0dXJlLm1pblksIGdlb21baSArIDFdKTtcbiAgICAgICAgZmVhdHVyZS5tYXhYID0gTWF0aC5tYXgoZmVhdHVyZS5tYXhYLCBnZW9tW2ldKTtcbiAgICAgICAgZmVhdHVyZS5tYXhZID0gTWF0aC5tYXgoZmVhdHVyZS5tYXhZLCBnZW9tW2kgKyAxXSk7XG4gICAgfVxufVxuIiwiXG5pbXBvcnQgc2ltcGxpZnkgZnJvbSAnLi9zaW1wbGlmeSc7XG5pbXBvcnQgY3JlYXRlRmVhdHVyZSBmcm9tICcuL2ZlYXR1cmUnO1xuXG4vLyBjb252ZXJ0cyBHZW9KU09OIGZlYXR1cmUgaW50byBhbiBpbnRlcm1lZGlhdGUgcHJvamVjdGVkIEpTT04gdmVjdG9yIGZvcm1hdCB3aXRoIHNpbXBsaWZpY2F0aW9uIGRhdGFcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gY29udmVydChkYXRhLCBvcHRpb25zKSB7XG4gICAgdmFyIGZlYXR1cmVzID0gW107XG4gICAgaWYgKGRhdGEudHlwZSA9PT0gJ0ZlYXR1cmVDb2xsZWN0aW9uJykge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRhdGEuZmVhdHVyZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnZlcnRGZWF0dXJlKGZlYXR1cmVzLCBkYXRhLmZlYXR1cmVzW2ldLCBvcHRpb25zLCBpKTtcbiAgICAgICAgfVxuXG4gICAgfSBlbHNlIGlmIChkYXRhLnR5cGUgPT09ICdGZWF0dXJlJykge1xuICAgICAgICBjb252ZXJ0RmVhdHVyZShmZWF0dXJlcywgZGF0YSwgb3B0aW9ucyk7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgICAvLyBzaW5nbGUgZ2VvbWV0cnkgb3IgYSBnZW9tZXRyeSBjb2xsZWN0aW9uXG4gICAgICAgIGNvbnZlcnRGZWF0dXJlKGZlYXR1cmVzLCB7Z2VvbWV0cnk6IGRhdGF9LCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmVhdHVyZXM7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRGZWF0dXJlKGZlYXR1cmVzLCBnZW9qc29uLCBvcHRpb25zLCBpbmRleCkge1xuICAgIGlmICghZ2VvanNvbi5nZW9tZXRyeSkgcmV0dXJuO1xuXG4gICAgdmFyIGNvb3JkcyA9IGdlb2pzb24uZ2VvbWV0cnkuY29vcmRpbmF0ZXM7XG4gICAgdmFyIHR5cGUgPSBnZW9qc29uLmdlb21ldHJ5LnR5cGU7XG4gICAgdmFyIHRvbGVyYW5jZSA9IE1hdGgucG93KG9wdGlvbnMudG9sZXJhbmNlIC8gKCgxIDw8IG9wdGlvbnMubWF4Wm9vbSkgKiBvcHRpb25zLmV4dGVudCksIDIpO1xuICAgIHZhciBnZW9tZXRyeSA9IFtdO1xuICAgIHZhciBpZCA9IGdlb2pzb24uaWQ7XG4gICAgaWYgKG9wdGlvbnMucHJvbW90ZUlkKSB7XG4gICAgICAgIGlkID0gZ2VvanNvbi5wcm9wZXJ0aWVzW29wdGlvbnMucHJvbW90ZUlkXTtcbiAgICB9IGVsc2UgaWYgKG9wdGlvbnMuZ2VuZXJhdGVJZCkge1xuICAgICAgICBpZCA9IGluZGV4IHx8IDA7XG4gICAgfVxuICAgIGlmICh0eXBlID09PSAnUG9pbnQnKSB7XG4gICAgICAgIGNvbnZlcnRQb2ludChjb29yZHMsIGdlb21ldHJ5KTtcblxuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ011bHRpUG9pbnQnKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY29vcmRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb252ZXJ0UG9pbnQoY29vcmRzW2ldLCBnZW9tZXRyeSk7XG4gICAgICAgIH1cblxuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ0xpbmVTdHJpbmcnKSB7XG4gICAgICAgIGNvbnZlcnRMaW5lKGNvb3JkcywgZ2VvbWV0cnksIHRvbGVyYW5jZSwgZmFsc2UpO1xuXG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnTXVsdGlMaW5lU3RyaW5nJykge1xuICAgICAgICBpZiAob3B0aW9ucy5saW5lTWV0cmljcykge1xuICAgICAgICAgICAgLy8gZXhwbG9kZSBpbnRvIGxpbmVzdHJpbmdzIHRvIGJlIGFibGUgdG8gdHJhY2sgbWV0cmljc1xuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvb3Jkcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGdlb21ldHJ5ID0gW107XG4gICAgICAgICAgICAgICAgY29udmVydExpbmUoY29vcmRzW2ldLCBnZW9tZXRyeSwgdG9sZXJhbmNlLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgZmVhdHVyZXMucHVzaChjcmVhdGVGZWF0dXJlKGlkLCAnTGluZVN0cmluZycsIGdlb21ldHJ5LCBnZW9qc29uLnByb3BlcnRpZXMpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnZlcnRMaW5lcyhjb29yZHMsIGdlb21ldHJ5LCB0b2xlcmFuY2UsIGZhbHNlKTtcbiAgICAgICAgfVxuXG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnUG9seWdvbicpIHtcbiAgICAgICAgY29udmVydExpbmVzKGNvb3JkcywgZ2VvbWV0cnksIHRvbGVyYW5jZSwgdHJ1ZSk7XG5cbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdNdWx0aVBvbHlnb24nKSB7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb29yZHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBwb2x5Z29uID0gW107XG4gICAgICAgICAgICBjb252ZXJ0TGluZXMoY29vcmRzW2ldLCBwb2x5Z29uLCB0b2xlcmFuY2UsIHRydWUpO1xuICAgICAgICAgICAgZ2VvbWV0cnkucHVzaChwb2x5Z29uKTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ0dlb21ldHJ5Q29sbGVjdGlvbicpIHtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGdlb2pzb24uZ2VvbWV0cnkuZ2VvbWV0cmllcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29udmVydEZlYXR1cmUoZmVhdHVyZXMsIHtcbiAgICAgICAgICAgICAgICBpZDogaWQsXG4gICAgICAgICAgICAgICAgZ2VvbWV0cnk6IGdlb2pzb24uZ2VvbWV0cnkuZ2VvbWV0cmllc1tpXSxcbiAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiBnZW9qc29uLnByb3BlcnRpZXNcbiAgICAgICAgICAgIH0sIG9wdGlvbnMsIGluZGV4KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBkYXRhIGlzIG5vdCBhIHZhbGlkIEdlb0pTT04gb2JqZWN0LicpO1xuICAgIH1cblxuICAgIGZlYXR1cmVzLnB1c2goY3JlYXRlRmVhdHVyZShpZCwgdHlwZSwgZ2VvbWV0cnksIGdlb2pzb24ucHJvcGVydGllcykpO1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0UG9pbnQoY29vcmRzLCBvdXQpIHtcbiAgICBvdXQucHVzaChwcm9qZWN0WChjb29yZHNbMF0pKTtcbiAgICBvdXQucHVzaChwcm9qZWN0WShjb29yZHNbMV0pKTtcbiAgICBvdXQucHVzaCgwKTtcbn1cblxuZnVuY3Rpb24gY29udmVydExpbmUocmluZywgb3V0LCB0b2xlcmFuY2UsIGlzUG9seWdvbikge1xuICAgIHZhciB4MCwgeTA7XG4gICAgdmFyIHNpemUgPSAwO1xuXG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCByaW5nLmxlbmd0aDsgaisrKSB7XG4gICAgICAgIHZhciB4ID0gcHJvamVjdFgocmluZ1tqXVswXSk7XG4gICAgICAgIHZhciB5ID0gcHJvamVjdFkocmluZ1tqXVsxXSk7XG5cbiAgICAgICAgb3V0LnB1c2goeCk7XG4gICAgICAgIG91dC5wdXNoKHkpO1xuICAgICAgICBvdXQucHVzaCgwKTtcblxuICAgICAgICBpZiAoaiA+IDApIHtcbiAgICAgICAgICAgIGlmIChpc1BvbHlnb24pIHtcbiAgICAgICAgICAgICAgICBzaXplICs9ICh4MCAqIHkgLSB4ICogeTApIC8gMjsgLy8gYXJlYVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzaXplICs9IE1hdGguc3FydChNYXRoLnBvdyh4IC0geDAsIDIpICsgTWF0aC5wb3coeSAtIHkwLCAyKSk7IC8vIGxlbmd0aFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHgwID0geDtcbiAgICAgICAgeTAgPSB5O1xuICAgIH1cblxuICAgIHZhciBsYXN0ID0gb3V0Lmxlbmd0aCAtIDM7XG4gICAgb3V0WzJdID0gMTtcbiAgICBzaW1wbGlmeShvdXQsIDAsIGxhc3QsIHRvbGVyYW5jZSk7XG4gICAgb3V0W2xhc3QgKyAyXSA9IDE7XG5cbiAgICBvdXQuc2l6ZSA9IE1hdGguYWJzKHNpemUpO1xuICAgIG91dC5zdGFydCA9IDA7XG4gICAgb3V0LmVuZCA9IG91dC5zaXplO1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0TGluZXMocmluZ3MsIG91dCwgdG9sZXJhbmNlLCBpc1BvbHlnb24pIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJpbmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBnZW9tID0gW107XG4gICAgICAgIGNvbnZlcnRMaW5lKHJpbmdzW2ldLCBnZW9tLCB0b2xlcmFuY2UsIGlzUG9seWdvbik7XG4gICAgICAgIG91dC5wdXNoKGdlb20pO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gcHJvamVjdFgoeCkge1xuICAgIHJldHVybiB4IC8gMzYwICsgMC41O1xufVxuXG5mdW5jdGlvbiBwcm9qZWN0WSh5KSB7XG4gICAgdmFyIHNpbiA9IE1hdGguc2luKHkgKiBNYXRoLlBJIC8gMTgwKTtcbiAgICB2YXIgeTIgPSAwLjUgLSAwLjI1ICogTWF0aC5sb2coKDEgKyBzaW4pIC8gKDEgLSBzaW4pKSAvIE1hdGguUEk7XG4gICAgcmV0dXJuIHkyIDwgMCA/IDAgOiB5MiA+IDEgPyAxIDogeTI7XG59XG4iLCJcbmltcG9ydCBjcmVhdGVGZWF0dXJlIGZyb20gJy4vZmVhdHVyZSc7XG5cbi8qIGNsaXAgZmVhdHVyZXMgYmV0d2VlbiB0d28gYXhpcy1wYXJhbGxlbCBsaW5lczpcbiAqICAgICB8ICAgICAgICB8XG4gKiAgX19ffF9fXyAgICAgfCAgICAgL1xuICogLyAgIHwgICBcXF9fX198X19fXy9cbiAqICAgICB8ICAgICAgICB8XG4gKi9cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gY2xpcChmZWF0dXJlcywgc2NhbGUsIGsxLCBrMiwgYXhpcywgbWluQWxsLCBtYXhBbGwsIG9wdGlvbnMpIHtcblxuICAgIGsxIC89IHNjYWxlO1xuICAgIGsyIC89IHNjYWxlO1xuXG4gICAgaWYgKG1pbkFsbCA+PSBrMSAmJiBtYXhBbGwgPCBrMikgcmV0dXJuIGZlYXR1cmVzOyAvLyB0cml2aWFsIGFjY2VwdFxuICAgIGVsc2UgaWYgKG1heEFsbCA8IGsxIHx8IG1pbkFsbCA+PSBrMikgcmV0dXJuIG51bGw7IC8vIHRyaXZpYWwgcmVqZWN0XG5cbiAgICB2YXIgY2xpcHBlZCA9IFtdO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBmZWF0dXJlcy5sZW5ndGg7IGkrKykge1xuXG4gICAgICAgIHZhciBmZWF0dXJlID0gZmVhdHVyZXNbaV07XG4gICAgICAgIHZhciBnZW9tZXRyeSA9IGZlYXR1cmUuZ2VvbWV0cnk7XG4gICAgICAgIHZhciB0eXBlID0gZmVhdHVyZS50eXBlO1xuXG4gICAgICAgIHZhciBtaW4gPSBheGlzID09PSAwID8gZmVhdHVyZS5taW5YIDogZmVhdHVyZS5taW5ZO1xuICAgICAgICB2YXIgbWF4ID0gYXhpcyA9PT0gMCA/IGZlYXR1cmUubWF4WCA6IGZlYXR1cmUubWF4WTtcblxuICAgICAgICBpZiAobWluID49IGsxICYmIG1heCA8IGsyKSB7IC8vIHRyaXZpYWwgYWNjZXB0XG4gICAgICAgICAgICBjbGlwcGVkLnB1c2goZmVhdHVyZSk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfSBlbHNlIGlmIChtYXggPCBrMSB8fCBtaW4gPj0gazIpIHsgLy8gdHJpdmlhbCByZWplY3RcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIG5ld0dlb21ldHJ5ID0gW107XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdQb2ludCcgfHwgdHlwZSA9PT0gJ011bHRpUG9pbnQnKSB7XG4gICAgICAgICAgICBjbGlwUG9pbnRzKGdlb21ldHJ5LCBuZXdHZW9tZXRyeSwgazEsIGsyLCBheGlzKTtcblxuICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdMaW5lU3RyaW5nJykge1xuICAgICAgICAgICAgY2xpcExpbmUoZ2VvbWV0cnksIG5ld0dlb21ldHJ5LCBrMSwgazIsIGF4aXMsIGZhbHNlLCBvcHRpb25zLmxpbmVNZXRyaWNzKTtcblxuICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdNdWx0aUxpbmVTdHJpbmcnKSB7XG4gICAgICAgICAgICBjbGlwTGluZXMoZ2VvbWV0cnksIG5ld0dlb21ldHJ5LCBrMSwgazIsIGF4aXMsIGZhbHNlKTtcblxuICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdQb2x5Z29uJykge1xuICAgICAgICAgICAgY2xpcExpbmVzKGdlb21ldHJ5LCBuZXdHZW9tZXRyeSwgazEsIGsyLCBheGlzLCB0cnVlKTtcblxuICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdNdWx0aVBvbHlnb24nKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGdlb21ldHJ5Lmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgdmFyIHBvbHlnb24gPSBbXTtcbiAgICAgICAgICAgICAgICBjbGlwTGluZXMoZ2VvbWV0cnlbal0sIHBvbHlnb24sIGsxLCBrMiwgYXhpcywgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgaWYgKHBvbHlnb24ubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIG5ld0dlb21ldHJ5LnB1c2gocG9seWdvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG5ld0dlb21ldHJ5Lmxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMubGluZU1ldHJpY3MgJiYgdHlwZSA9PT0gJ0xpbmVTdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IG5ld0dlb21ldHJ5Lmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgIGNsaXBwZWQucHVzaChjcmVhdGVGZWF0dXJlKGZlYXR1cmUuaWQsIHR5cGUsIG5ld0dlb21ldHJ5W2pdLCBmZWF0dXJlLnRhZ3MpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0eXBlID09PSAnTGluZVN0cmluZycgfHwgdHlwZSA9PT0gJ011bHRpTGluZVN0cmluZycpIHtcbiAgICAgICAgICAgICAgICBpZiAobmV3R2VvbWV0cnkubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGUgPSAnTGluZVN0cmluZyc7XG4gICAgICAgICAgICAgICAgICAgIG5ld0dlb21ldHJ5ID0gbmV3R2VvbWV0cnlbMF07XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZSA9ICdNdWx0aUxpbmVTdHJpbmcnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0eXBlID09PSAnUG9pbnQnIHx8IHR5cGUgPT09ICdNdWx0aVBvaW50Jykge1xuICAgICAgICAgICAgICAgIHR5cGUgPSBuZXdHZW9tZXRyeS5sZW5ndGggPT09IDMgPyAnUG9pbnQnIDogJ011bHRpUG9pbnQnO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjbGlwcGVkLnB1c2goY3JlYXRlRmVhdHVyZShmZWF0dXJlLmlkLCB0eXBlLCBuZXdHZW9tZXRyeSwgZmVhdHVyZS50YWdzKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY2xpcHBlZC5sZW5ndGggPyBjbGlwcGVkIDogbnVsbDtcbn1cblxuZnVuY3Rpb24gY2xpcFBvaW50cyhnZW9tLCBuZXdHZW9tLCBrMSwgazIsIGF4aXMpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGdlb20ubGVuZ3RoOyBpICs9IDMpIHtcbiAgICAgICAgdmFyIGEgPSBnZW9tW2kgKyBheGlzXTtcblxuICAgICAgICBpZiAoYSA+PSBrMSAmJiBhIDw9IGsyKSB7XG4gICAgICAgICAgICBuZXdHZW9tLnB1c2goZ2VvbVtpXSk7XG4gICAgICAgICAgICBuZXdHZW9tLnB1c2goZ2VvbVtpICsgMV0pO1xuICAgICAgICAgICAgbmV3R2VvbS5wdXNoKGdlb21baSArIDJdKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gY2xpcExpbmUoZ2VvbSwgbmV3R2VvbSwgazEsIGsyLCBheGlzLCBpc1BvbHlnb24sIHRyYWNrTWV0cmljcykge1xuXG4gICAgdmFyIHNsaWNlID0gbmV3U2xpY2UoZ2VvbSk7XG4gICAgdmFyIGludGVyc2VjdCA9IGF4aXMgPT09IDAgPyBpbnRlcnNlY3RYIDogaW50ZXJzZWN0WTtcbiAgICB2YXIgbGVuID0gZ2VvbS5zdGFydDtcbiAgICB2YXIgc2VnTGVuLCB0O1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBnZW9tLmxlbmd0aCAtIDM7IGkgKz0gMykge1xuICAgICAgICB2YXIgYXggPSBnZW9tW2ldO1xuICAgICAgICB2YXIgYXkgPSBnZW9tW2kgKyAxXTtcbiAgICAgICAgdmFyIGF6ID0gZ2VvbVtpICsgMl07XG4gICAgICAgIHZhciBieCA9IGdlb21baSArIDNdO1xuICAgICAgICB2YXIgYnkgPSBnZW9tW2kgKyA0XTtcbiAgICAgICAgdmFyIGEgPSBheGlzID09PSAwID8gYXggOiBheTtcbiAgICAgICAgdmFyIGIgPSBheGlzID09PSAwID8gYnggOiBieTtcbiAgICAgICAgdmFyIGV4aXRlZCA9IGZhbHNlO1xuXG4gICAgICAgIGlmICh0cmFja01ldHJpY3MpIHNlZ0xlbiA9IE1hdGguc3FydChNYXRoLnBvdyhheCAtIGJ4LCAyKSArIE1hdGgucG93KGF5IC0gYnksIDIpKTtcblxuICAgICAgICBpZiAoYSA8IGsxKSB7XG4gICAgICAgICAgICAvLyAtLS18LS0+ICB8IChsaW5lIGVudGVycyB0aGUgY2xpcCByZWdpb24gZnJvbSB0aGUgbGVmdClcbiAgICAgICAgICAgIGlmIChiID4gazEpIHtcbiAgICAgICAgICAgICAgICB0ID0gaW50ZXJzZWN0KHNsaWNlLCBheCwgYXksIGJ4LCBieSwgazEpO1xuICAgICAgICAgICAgICAgIGlmICh0cmFja01ldHJpY3MpIHNsaWNlLnN0YXJ0ID0gbGVuICsgc2VnTGVuICogdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChhID4gazIpIHtcbiAgICAgICAgICAgIC8vIHwgIDwtLXwtLS0gKGxpbmUgZW50ZXJzIHRoZSBjbGlwIHJlZ2lvbiBmcm9tIHRoZSByaWdodClcbiAgICAgICAgICAgIGlmIChiIDwgazIpIHtcbiAgICAgICAgICAgICAgICB0ID0gaW50ZXJzZWN0KHNsaWNlLCBheCwgYXksIGJ4LCBieSwgazIpO1xuICAgICAgICAgICAgICAgIGlmICh0cmFja01ldHJpY3MpIHNsaWNlLnN0YXJ0ID0gbGVuICsgc2VnTGVuICogdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFkZFBvaW50KHNsaWNlLCBheCwgYXksIGF6KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYiA8IGsxICYmIGEgPj0gazEpIHtcbiAgICAgICAgICAgIC8vIDwtLXwtLS0gIHwgb3IgPC0tfC0tLS0tfC0tLSAobGluZSBleGl0cyB0aGUgY2xpcCByZWdpb24gb24gdGhlIGxlZnQpXG4gICAgICAgICAgICB0ID0gaW50ZXJzZWN0KHNsaWNlLCBheCwgYXksIGJ4LCBieSwgazEpO1xuICAgICAgICAgICAgZXhpdGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYiA+IGsyICYmIGEgPD0gazIpIHtcbiAgICAgICAgICAgIC8vIHwgIC0tLXwtLT4gb3IgLS0tfC0tLS0tfC0tPiAobGluZSBleGl0cyB0aGUgY2xpcCByZWdpb24gb24gdGhlIHJpZ2h0KVxuICAgICAgICAgICAgdCA9IGludGVyc2VjdChzbGljZSwgYXgsIGF5LCBieCwgYnksIGsyKTtcbiAgICAgICAgICAgIGV4aXRlZCA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWlzUG9seWdvbiAmJiBleGl0ZWQpIHtcbiAgICAgICAgICAgIGlmICh0cmFja01ldHJpY3MpIHNsaWNlLmVuZCA9IGxlbiArIHNlZ0xlbiAqIHQ7XG4gICAgICAgICAgICBuZXdHZW9tLnB1c2goc2xpY2UpO1xuICAgICAgICAgICAgc2xpY2UgPSBuZXdTbGljZShnZW9tKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0cmFja01ldHJpY3MpIGxlbiArPSBzZWdMZW47XG4gICAgfVxuXG4gICAgLy8gYWRkIHRoZSBsYXN0IHBvaW50XG4gICAgdmFyIGxhc3QgPSBnZW9tLmxlbmd0aCAtIDM7XG4gICAgYXggPSBnZW9tW2xhc3RdO1xuICAgIGF5ID0gZ2VvbVtsYXN0ICsgMV07XG4gICAgYXogPSBnZW9tW2xhc3QgKyAyXTtcbiAgICBhID0gYXhpcyA9PT0gMCA/IGF4IDogYXk7XG4gICAgaWYgKGEgPj0gazEgJiYgYSA8PSBrMikgYWRkUG9pbnQoc2xpY2UsIGF4LCBheSwgYXopO1xuXG4gICAgLy8gY2xvc2UgdGhlIHBvbHlnb24gaWYgaXRzIGVuZHBvaW50cyBhcmUgbm90IHRoZSBzYW1lIGFmdGVyIGNsaXBwaW5nXG4gICAgbGFzdCA9IHNsaWNlLmxlbmd0aCAtIDM7XG4gICAgaWYgKGlzUG9seWdvbiAmJiBsYXN0ID49IDMgJiYgKHNsaWNlW2xhc3RdICE9PSBzbGljZVswXSB8fCBzbGljZVtsYXN0ICsgMV0gIT09IHNsaWNlWzFdKSkge1xuICAgICAgICBhZGRQb2ludChzbGljZSwgc2xpY2VbMF0sIHNsaWNlWzFdLCBzbGljZVsyXSk7XG4gICAgfVxuXG4gICAgLy8gYWRkIHRoZSBmaW5hbCBzbGljZVxuICAgIGlmIChzbGljZS5sZW5ndGgpIHtcbiAgICAgICAgbmV3R2VvbS5wdXNoKHNsaWNlKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIG5ld1NsaWNlKGxpbmUpIHtcbiAgICB2YXIgc2xpY2UgPSBbXTtcbiAgICBzbGljZS5zaXplID0gbGluZS5zaXplO1xuICAgIHNsaWNlLnN0YXJ0ID0gbGluZS5zdGFydDtcbiAgICBzbGljZS5lbmQgPSBsaW5lLmVuZDtcbiAgICByZXR1cm4gc2xpY2U7XG59XG5cbmZ1bmN0aW9uIGNsaXBMaW5lcyhnZW9tLCBuZXdHZW9tLCBrMSwgazIsIGF4aXMsIGlzUG9seWdvbikge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZ2VvbS5sZW5ndGg7IGkrKykge1xuICAgICAgICBjbGlwTGluZShnZW9tW2ldLCBuZXdHZW9tLCBrMSwgazIsIGF4aXMsIGlzUG9seWdvbiwgZmFsc2UpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gYWRkUG9pbnQob3V0LCB4LCB5LCB6KSB7XG4gICAgb3V0LnB1c2goeCk7XG4gICAgb3V0LnB1c2goeSk7XG4gICAgb3V0LnB1c2goeik7XG59XG5cbmZ1bmN0aW9uIGludGVyc2VjdFgob3V0LCBheCwgYXksIGJ4LCBieSwgeCkge1xuICAgIHZhciB0ID0gKHggLSBheCkgLyAoYnggLSBheCk7XG4gICAgb3V0LnB1c2goeCk7XG4gICAgb3V0LnB1c2goYXkgKyAoYnkgLSBheSkgKiB0KTtcbiAgICBvdXQucHVzaCgxKTtcbiAgICByZXR1cm4gdDtcbn1cblxuZnVuY3Rpb24gaW50ZXJzZWN0WShvdXQsIGF4LCBheSwgYngsIGJ5LCB5KSB7XG4gICAgdmFyIHQgPSAoeSAtIGF5KSAvIChieSAtIGF5KTtcbiAgICBvdXQucHVzaChheCArIChieCAtIGF4KSAqIHQpO1xuICAgIG91dC5wdXNoKHkpO1xuICAgIG91dC5wdXNoKDEpO1xuICAgIHJldHVybiB0O1xufVxuIiwiXG5pbXBvcnQgY2xpcCBmcm9tICcuL2NsaXAnO1xuaW1wb3J0IGNyZWF0ZUZlYXR1cmUgZnJvbSAnLi9mZWF0dXJlJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gd3JhcChmZWF0dXJlcywgb3B0aW9ucykge1xuICAgIHZhciBidWZmZXIgPSBvcHRpb25zLmJ1ZmZlciAvIG9wdGlvbnMuZXh0ZW50O1xuICAgIHZhciBtZXJnZWQgPSBmZWF0dXJlcztcbiAgICB2YXIgbGVmdCAgPSBjbGlwKGZlYXR1cmVzLCAxLCAtMSAtIGJ1ZmZlciwgYnVmZmVyLCAgICAgMCwgLTEsIDIsIG9wdGlvbnMpOyAvLyBsZWZ0IHdvcmxkIGNvcHlcbiAgICB2YXIgcmlnaHQgPSBjbGlwKGZlYXR1cmVzLCAxLCAgMSAtIGJ1ZmZlciwgMiArIGJ1ZmZlciwgMCwgLTEsIDIsIG9wdGlvbnMpOyAvLyByaWdodCB3b3JsZCBjb3B5XG5cbiAgICBpZiAobGVmdCB8fCByaWdodCkge1xuICAgICAgICBtZXJnZWQgPSBjbGlwKGZlYXR1cmVzLCAxLCAtYnVmZmVyLCAxICsgYnVmZmVyLCAwLCAtMSwgMiwgb3B0aW9ucykgfHwgW107IC8vIGNlbnRlciB3b3JsZCBjb3B5XG5cbiAgICAgICAgaWYgKGxlZnQpIG1lcmdlZCA9IHNoaWZ0RmVhdHVyZUNvb3JkcyhsZWZ0LCAxKS5jb25jYXQobWVyZ2VkKTsgLy8gbWVyZ2UgbGVmdCBpbnRvIGNlbnRlclxuICAgICAgICBpZiAocmlnaHQpIG1lcmdlZCA9IG1lcmdlZC5jb25jYXQoc2hpZnRGZWF0dXJlQ29vcmRzKHJpZ2h0LCAtMSkpOyAvLyBtZXJnZSByaWdodCBpbnRvIGNlbnRlclxuICAgIH1cblxuICAgIHJldHVybiBtZXJnZWQ7XG59XG5cbmZ1bmN0aW9uIHNoaWZ0RmVhdHVyZUNvb3JkcyhmZWF0dXJlcywgb2Zmc2V0KSB7XG4gICAgdmFyIG5ld0ZlYXR1cmVzID0gW107XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGZlYXR1cmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBmZWF0dXJlID0gZmVhdHVyZXNbaV0sXG4gICAgICAgICAgICB0eXBlID0gZmVhdHVyZS50eXBlO1xuXG4gICAgICAgIHZhciBuZXdHZW9tZXRyeTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ1BvaW50JyB8fCB0eXBlID09PSAnTXVsdGlQb2ludCcgfHwgdHlwZSA9PT0gJ0xpbmVTdHJpbmcnKSB7XG4gICAgICAgICAgICBuZXdHZW9tZXRyeSA9IHNoaWZ0Q29vcmRzKGZlYXR1cmUuZ2VvbWV0cnksIG9mZnNldCk7XG5cbiAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnTXVsdGlMaW5lU3RyaW5nJyB8fCB0eXBlID09PSAnUG9seWdvbicpIHtcbiAgICAgICAgICAgIG5ld0dlb21ldHJ5ID0gW107XG4gICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGZlYXR1cmUuZ2VvbWV0cnkubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICBuZXdHZW9tZXRyeS5wdXNoKHNoaWZ0Q29vcmRzKGZlYXR1cmUuZ2VvbWV0cnlbal0sIG9mZnNldCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdNdWx0aVBvbHlnb24nKSB7XG4gICAgICAgICAgICBuZXdHZW9tZXRyeSA9IFtdO1xuICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IGZlYXR1cmUuZ2VvbWV0cnkubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgbmV3UG9seWdvbiA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGsgPSAwOyBrIDwgZmVhdHVyZS5nZW9tZXRyeVtqXS5sZW5ndGg7IGsrKykge1xuICAgICAgICAgICAgICAgICAgICBuZXdQb2x5Z29uLnB1c2goc2hpZnRDb29yZHMoZmVhdHVyZS5nZW9tZXRyeVtqXVtrXSwgb2Zmc2V0KSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG5ld0dlb21ldHJ5LnB1c2gobmV3UG9seWdvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBuZXdGZWF0dXJlcy5wdXNoKGNyZWF0ZUZlYXR1cmUoZmVhdHVyZS5pZCwgdHlwZSwgbmV3R2VvbWV0cnksIGZlYXR1cmUudGFncykpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXdGZWF0dXJlcztcbn1cblxuZnVuY3Rpb24gc2hpZnRDb29yZHMocG9pbnRzLCBvZmZzZXQpIHtcbiAgICB2YXIgbmV3UG9pbnRzID0gW107XG4gICAgbmV3UG9pbnRzLnNpemUgPSBwb2ludHMuc2l6ZTtcblxuICAgIGlmIChwb2ludHMuc3RhcnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBuZXdQb2ludHMuc3RhcnQgPSBwb2ludHMuc3RhcnQ7XG4gICAgICAgIG5ld1BvaW50cy5lbmQgPSBwb2ludHMuZW5kO1xuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aDsgaSArPSAzKSB7XG4gICAgICAgIG5ld1BvaW50cy5wdXNoKHBvaW50c1tpXSArIG9mZnNldCwgcG9pbnRzW2kgKyAxXSwgcG9pbnRzW2kgKyAyXSk7XG4gICAgfVxuICAgIHJldHVybiBuZXdQb2ludHM7XG59XG4iLCJcbi8vIFRyYW5zZm9ybXMgdGhlIGNvb3JkaW5hdGVzIG9mIGVhY2ggZmVhdHVyZSBpbiB0aGUgZ2l2ZW4gdGlsZSBmcm9tXG4vLyBtZXJjYXRvci1wcm9qZWN0ZWQgc3BhY2UgaW50byAoZXh0ZW50IHggZXh0ZW50KSB0aWxlIHNwYWNlLlxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdHJhbnNmb3JtVGlsZSh0aWxlLCBleHRlbnQpIHtcbiAgICBpZiAodGlsZS50cmFuc2Zvcm1lZCkgcmV0dXJuIHRpbGU7XG5cbiAgICB2YXIgejIgPSAxIDw8IHRpbGUueixcbiAgICAgICAgdHggPSB0aWxlLngsXG4gICAgICAgIHR5ID0gdGlsZS55LFxuICAgICAgICBpLCBqLCBrO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IHRpbGUuZmVhdHVyZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGZlYXR1cmUgPSB0aWxlLmZlYXR1cmVzW2ldLFxuICAgICAgICAgICAgZ2VvbSA9IGZlYXR1cmUuZ2VvbWV0cnksXG4gICAgICAgICAgICB0eXBlID0gZmVhdHVyZS50eXBlO1xuXG4gICAgICAgIGZlYXR1cmUuZ2VvbWV0cnkgPSBbXTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gMSkge1xuICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IGdlb20ubGVuZ3RoOyBqICs9IDIpIHtcbiAgICAgICAgICAgICAgICBmZWF0dXJlLmdlb21ldHJ5LnB1c2godHJhbnNmb3JtUG9pbnQoZ2VvbVtqXSwgZ2VvbVtqICsgMV0sIGV4dGVudCwgejIsIHR4LCB0eSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IGdlb20ubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgcmluZyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAoayA9IDA7IGsgPCBnZW9tW2pdLmxlbmd0aDsgayArPSAyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJpbmcucHVzaCh0cmFuc2Zvcm1Qb2ludChnZW9tW2pdW2tdLCBnZW9tW2pdW2sgKyAxXSwgZXh0ZW50LCB6MiwgdHgsIHR5KSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZlYXR1cmUuZ2VvbWV0cnkucHVzaChyaW5nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHRpbGUudHJhbnNmb3JtZWQgPSB0cnVlO1xuXG4gICAgcmV0dXJuIHRpbGU7XG59XG5cbmZ1bmN0aW9uIHRyYW5zZm9ybVBvaW50KHgsIHksIGV4dGVudCwgejIsIHR4LCB0eSkge1xuICAgIHJldHVybiBbXG4gICAgICAgIE1hdGgucm91bmQoZXh0ZW50ICogKHggKiB6MiAtIHR4KSksXG4gICAgICAgIE1hdGgucm91bmQoZXh0ZW50ICogKHkgKiB6MiAtIHR5KSldO1xufVxuIiwiXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBjcmVhdGVUaWxlKGZlYXR1cmVzLCB6LCB0eCwgdHksIG9wdGlvbnMpIHtcbiAgICB2YXIgdG9sZXJhbmNlID0geiA9PT0gb3B0aW9ucy5tYXhab29tID8gMCA6IG9wdGlvbnMudG9sZXJhbmNlIC8gKCgxIDw8IHopICogb3B0aW9ucy5leHRlbnQpO1xuICAgIHZhciB0aWxlID0ge1xuICAgICAgICBmZWF0dXJlczogW10sXG4gICAgICAgIG51bVBvaW50czogMCxcbiAgICAgICAgbnVtU2ltcGxpZmllZDogMCxcbiAgICAgICAgbnVtRmVhdHVyZXM6IDAsXG4gICAgICAgIHNvdXJjZTogbnVsbCxcbiAgICAgICAgeDogdHgsXG4gICAgICAgIHk6IHR5LFxuICAgICAgICB6OiB6LFxuICAgICAgICB0cmFuc2Zvcm1lZDogZmFsc2UsXG4gICAgICAgIG1pblg6IDIsXG4gICAgICAgIG1pblk6IDEsXG4gICAgICAgIG1heFg6IC0xLFxuICAgICAgICBtYXhZOiAwXG4gICAgfTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGZlYXR1cmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRpbGUubnVtRmVhdHVyZXMrKztcbiAgICAgICAgYWRkRmVhdHVyZSh0aWxlLCBmZWF0dXJlc1tpXSwgdG9sZXJhbmNlLCBvcHRpb25zKTtcblxuICAgICAgICB2YXIgbWluWCA9IGZlYXR1cmVzW2ldLm1pblg7XG4gICAgICAgIHZhciBtaW5ZID0gZmVhdHVyZXNbaV0ubWluWTtcbiAgICAgICAgdmFyIG1heFggPSBmZWF0dXJlc1tpXS5tYXhYO1xuICAgICAgICB2YXIgbWF4WSA9IGZlYXR1cmVzW2ldLm1heFk7XG5cbiAgICAgICAgaWYgKG1pblggPCB0aWxlLm1pblgpIHRpbGUubWluWCA9IG1pblg7XG4gICAgICAgIGlmIChtaW5ZIDwgdGlsZS5taW5ZKSB0aWxlLm1pblkgPSBtaW5ZO1xuICAgICAgICBpZiAobWF4WCA+IHRpbGUubWF4WCkgdGlsZS5tYXhYID0gbWF4WDtcbiAgICAgICAgaWYgKG1heFkgPiB0aWxlLm1heFkpIHRpbGUubWF4WSA9IG1heFk7XG4gICAgfVxuICAgIHJldHVybiB0aWxlO1xufVxuXG5mdW5jdGlvbiBhZGRGZWF0dXJlKHRpbGUsIGZlYXR1cmUsIHRvbGVyYW5jZSwgb3B0aW9ucykge1xuXG4gICAgdmFyIGdlb20gPSBmZWF0dXJlLmdlb21ldHJ5LFxuICAgICAgICB0eXBlID0gZmVhdHVyZS50eXBlLFxuICAgICAgICBzaW1wbGlmaWVkID0gW107XG5cbiAgICBpZiAodHlwZSA9PT0gJ1BvaW50JyB8fCB0eXBlID09PSAnTXVsdGlQb2ludCcpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBnZW9tLmxlbmd0aDsgaSArPSAzKSB7XG4gICAgICAgICAgICBzaW1wbGlmaWVkLnB1c2goZ2VvbVtpXSk7XG4gICAgICAgICAgICBzaW1wbGlmaWVkLnB1c2goZ2VvbVtpICsgMV0pO1xuICAgICAgICAgICAgdGlsZS5udW1Qb2ludHMrKztcbiAgICAgICAgICAgIHRpbGUubnVtU2ltcGxpZmllZCsrO1xuICAgICAgICB9XG5cbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdMaW5lU3RyaW5nJykge1xuICAgICAgICBhZGRMaW5lKHNpbXBsaWZpZWQsIGdlb20sIHRpbGUsIHRvbGVyYW5jZSwgZmFsc2UsIGZhbHNlKTtcblxuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ011bHRpTGluZVN0cmluZycgfHwgdHlwZSA9PT0gJ1BvbHlnb24nKSB7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBnZW9tLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBhZGRMaW5lKHNpbXBsaWZpZWQsIGdlb21baV0sIHRpbGUsIHRvbGVyYW5jZSwgdHlwZSA9PT0gJ1BvbHlnb24nLCBpID09PSAwKTtcbiAgICAgICAgfVxuXG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnTXVsdGlQb2x5Z29uJykge1xuXG4gICAgICAgIGZvciAodmFyIGsgPSAwOyBrIDwgZ2VvbS5sZW5ndGg7IGsrKykge1xuICAgICAgICAgICAgdmFyIHBvbHlnb24gPSBnZW9tW2tdO1xuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IHBvbHlnb24ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBhZGRMaW5lKHNpbXBsaWZpZWQsIHBvbHlnb25baV0sIHRpbGUsIHRvbGVyYW5jZSwgdHJ1ZSwgaSA9PT0gMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc2ltcGxpZmllZC5sZW5ndGgpIHtcbiAgICAgICAgdmFyIHRhZ3MgPSBmZWF0dXJlLnRhZ3MgfHwgbnVsbDtcbiAgICAgICAgaWYgKHR5cGUgPT09ICdMaW5lU3RyaW5nJyAmJiBvcHRpb25zLmxpbmVNZXRyaWNzKSB7XG4gICAgICAgICAgICB0YWdzID0ge307XG4gICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gZmVhdHVyZS50YWdzKSB0YWdzW2tleV0gPSBmZWF0dXJlLnRhZ3Nba2V5XTtcbiAgICAgICAgICAgIHRhZ3NbJ21hcGJveF9jbGlwX3N0YXJ0J10gPSBnZW9tLnN0YXJ0IC8gZ2VvbS5zaXplO1xuICAgICAgICAgICAgdGFnc1snbWFwYm94X2NsaXBfZW5kJ10gPSBnZW9tLmVuZCAvIGdlb20uc2l6ZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdGlsZUZlYXR1cmUgPSB7XG4gICAgICAgICAgICBnZW9tZXRyeTogc2ltcGxpZmllZCxcbiAgICAgICAgICAgIHR5cGU6IHR5cGUgPT09ICdQb2x5Z29uJyB8fCB0eXBlID09PSAnTXVsdGlQb2x5Z29uJyA/IDMgOlxuICAgICAgICAgICAgICAgIHR5cGUgPT09ICdMaW5lU3RyaW5nJyB8fCB0eXBlID09PSAnTXVsdGlMaW5lU3RyaW5nJyA/IDIgOiAxLFxuICAgICAgICAgICAgdGFnczogdGFnc1xuICAgICAgICB9O1xuICAgICAgICBpZiAoZmVhdHVyZS5pZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGlsZUZlYXR1cmUuaWQgPSBmZWF0dXJlLmlkO1xuICAgICAgICB9XG4gICAgICAgIHRpbGUuZmVhdHVyZXMucHVzaCh0aWxlRmVhdHVyZSk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBhZGRMaW5lKHJlc3VsdCwgZ2VvbSwgdGlsZSwgdG9sZXJhbmNlLCBpc1BvbHlnb24sIGlzT3V0ZXIpIHtcbiAgICB2YXIgc3FUb2xlcmFuY2UgPSB0b2xlcmFuY2UgKiB0b2xlcmFuY2U7XG5cbiAgICBpZiAodG9sZXJhbmNlID4gMCAmJiAoZ2VvbS5zaXplIDwgKGlzUG9seWdvbiA/IHNxVG9sZXJhbmNlIDogdG9sZXJhbmNlKSkpIHtcbiAgICAgICAgdGlsZS5udW1Qb2ludHMgKz0gZ2VvbS5sZW5ndGggLyAzO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHJpbmcgPSBbXTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZ2VvbS5sZW5ndGg7IGkgKz0gMykge1xuICAgICAgICBpZiAodG9sZXJhbmNlID09PSAwIHx8IGdlb21baSArIDJdID4gc3FUb2xlcmFuY2UpIHtcbiAgICAgICAgICAgIHRpbGUubnVtU2ltcGxpZmllZCsrO1xuICAgICAgICAgICAgcmluZy5wdXNoKGdlb21baV0pO1xuICAgICAgICAgICAgcmluZy5wdXNoKGdlb21baSArIDFdKTtcbiAgICAgICAgfVxuICAgICAgICB0aWxlLm51bVBvaW50cysrO1xuICAgIH1cblxuICAgIGlmIChpc1BvbHlnb24pIHJld2luZChyaW5nLCBpc091dGVyKTtcblxuICAgIHJlc3VsdC5wdXNoKHJpbmcpO1xufVxuXG5mdW5jdGlvbiByZXdpbmQocmluZywgY2xvY2t3aXNlKSB7XG4gICAgdmFyIGFyZWEgPSAwO1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSByaW5nLmxlbmd0aCwgaiA9IGxlbiAtIDI7IGkgPCBsZW47IGogPSBpLCBpICs9IDIpIHtcbiAgICAgICAgYXJlYSArPSAocmluZ1tpXSAtIHJpbmdbal0pICogKHJpbmdbaSArIDFdICsgcmluZ1tqICsgMV0pO1xuICAgIH1cbiAgICBpZiAoYXJlYSA+IDAgPT09IGNsb2Nrd2lzZSkge1xuICAgICAgICBmb3IgKGkgPSAwLCBsZW4gPSByaW5nLmxlbmd0aDsgaSA8IGxlbiAvIDI7IGkgKz0gMikge1xuICAgICAgICAgICAgdmFyIHggPSByaW5nW2ldO1xuICAgICAgICAgICAgdmFyIHkgPSByaW5nW2kgKyAxXTtcbiAgICAgICAgICAgIHJpbmdbaV0gPSByaW5nW2xlbiAtIDIgLSBpXTtcbiAgICAgICAgICAgIHJpbmdbaSArIDFdID0gcmluZ1tsZW4gLSAxIC0gaV07XG4gICAgICAgICAgICByaW5nW2xlbiAtIDIgLSBpXSA9IHg7XG4gICAgICAgICAgICByaW5nW2xlbiAtIDEgLSBpXSA9IHk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJcbmltcG9ydCBjb252ZXJ0IGZyb20gJy4vY29udmVydCc7ICAgICAvLyBHZW9KU09OIGNvbnZlcnNpb24gYW5kIHByZXByb2Nlc3NpbmdcbmltcG9ydCBjbGlwIGZyb20gJy4vY2xpcCc7ICAgICAgICAgICAvLyBzdHJpcGUgY2xpcHBpbmcgYWxnb3JpdGhtXG5pbXBvcnQgd3JhcCBmcm9tICcuL3dyYXAnOyAgICAgICAgICAgLy8gZGF0ZSBsaW5lIHByb2Nlc3NpbmdcbmltcG9ydCB0cmFuc2Zvcm0gZnJvbSAnLi90cmFuc2Zvcm0nOyAvLyBjb29yZGluYXRlIHRyYW5zZm9ybWF0aW9uXG5pbXBvcnQgY3JlYXRlVGlsZSBmcm9tICcuL3RpbGUnOyAgICAgLy8gZmluYWwgc2ltcGxpZmllZCB0aWxlIGdlbmVyYXRpb25cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2VvanNvbnZ0KGRhdGEsIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gbmV3IEdlb0pTT05WVChkYXRhLCBvcHRpb25zKTtcbn1cblxuZnVuY3Rpb24gR2VvSlNPTlZUKGRhdGEsIG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gdGhpcy5vcHRpb25zID0gZXh0ZW5kKE9iamVjdC5jcmVhdGUodGhpcy5vcHRpb25zKSwgb3B0aW9ucyk7XG5cbiAgICB2YXIgZGVidWcgPSBvcHRpb25zLmRlYnVnO1xuXG4gICAgaWYgKGRlYnVnKSBjb25zb2xlLnRpbWUoJ3ByZXByb2Nlc3MgZGF0YScpO1xuXG4gICAgaWYgKG9wdGlvbnMubWF4Wm9vbSA8IDAgfHwgb3B0aW9ucy5tYXhab29tID4gMjQpIHRocm93IG5ldyBFcnJvcignbWF4Wm9vbSBzaG91bGQgYmUgaW4gdGhlIDAtMjQgcmFuZ2UnKTtcbiAgICBpZiAob3B0aW9ucy5wcm9tb3RlSWQgJiYgb3B0aW9ucy5nZW5lcmF0ZUlkKSB0aHJvdyBuZXcgRXJyb3IoJ3Byb21vdGVJZCBhbmQgZ2VuZXJhdGVJZCBjYW5ub3QgYmUgdXNlZCB0b2dldGhlci4nKTtcblxuICAgIHZhciBmZWF0dXJlcyA9IGNvbnZlcnQoZGF0YSwgb3B0aW9ucyk7XG5cbiAgICB0aGlzLnRpbGVzID0ge307XG4gICAgdGhpcy50aWxlQ29vcmRzID0gW107XG5cbiAgICBpZiAoZGVidWcpIHtcbiAgICAgICAgY29uc29sZS50aW1lRW5kKCdwcmVwcm9jZXNzIGRhdGEnKTtcbiAgICAgICAgY29uc29sZS5sb2coJ2luZGV4OiBtYXhab29tOiAlZCwgbWF4UG9pbnRzOiAlZCcsIG9wdGlvbnMuaW5kZXhNYXhab29tLCBvcHRpb25zLmluZGV4TWF4UG9pbnRzKTtcbiAgICAgICAgY29uc29sZS50aW1lKCdnZW5lcmF0ZSB0aWxlcycpO1xuICAgICAgICB0aGlzLnN0YXRzID0ge307XG4gICAgICAgIHRoaXMudG90YWwgPSAwO1xuICAgIH1cblxuICAgIGZlYXR1cmVzID0gd3JhcChmZWF0dXJlcywgb3B0aW9ucyk7XG5cbiAgICAvLyBzdGFydCBzbGljaW5nIGZyb20gdGhlIHRvcCB0aWxlIGRvd25cbiAgICBpZiAoZmVhdHVyZXMubGVuZ3RoKSB0aGlzLnNwbGl0VGlsZShmZWF0dXJlcywgMCwgMCwgMCk7XG5cbiAgICBpZiAoZGVidWcpIHtcbiAgICAgICAgaWYgKGZlYXR1cmVzLmxlbmd0aCkgY29uc29sZS5sb2coJ2ZlYXR1cmVzOiAlZCwgcG9pbnRzOiAlZCcsIHRoaXMudGlsZXNbMF0ubnVtRmVhdHVyZXMsIHRoaXMudGlsZXNbMF0ubnVtUG9pbnRzKTtcbiAgICAgICAgY29uc29sZS50aW1lRW5kKCdnZW5lcmF0ZSB0aWxlcycpO1xuICAgICAgICBjb25zb2xlLmxvZygndGlsZXMgZ2VuZXJhdGVkOicsIHRoaXMudG90YWwsIEpTT04uc3RyaW5naWZ5KHRoaXMuc3RhdHMpKTtcbiAgICB9XG59XG5cbkdlb0pTT05WVC5wcm90b3R5cGUub3B0aW9ucyA9IHtcbiAgICBtYXhab29tOiAxNCwgICAgICAgICAgICAvLyBtYXggem9vbSB0byBwcmVzZXJ2ZSBkZXRhaWwgb25cbiAgICBpbmRleE1heFpvb206IDUsICAgICAgICAvLyBtYXggem9vbSBpbiB0aGUgdGlsZSBpbmRleFxuICAgIGluZGV4TWF4UG9pbnRzOiAxMDAwMDAsIC8vIG1heCBudW1iZXIgb2YgcG9pbnRzIHBlciB0aWxlIGluIHRoZSB0aWxlIGluZGV4XG4gICAgdG9sZXJhbmNlOiAzLCAgICAgICAgICAgLy8gc2ltcGxpZmljYXRpb24gdG9sZXJhbmNlIChoaWdoZXIgbWVhbnMgc2ltcGxlcilcbiAgICBleHRlbnQ6IDQwOTYsICAgICAgICAgICAvLyB0aWxlIGV4dGVudFxuICAgIGJ1ZmZlcjogNjQsICAgICAgICAgICAgIC8vIHRpbGUgYnVmZmVyIG9uIGVhY2ggc2lkZVxuICAgIGxpbmVNZXRyaWNzOiBmYWxzZSwgICAgIC8vIHdoZXRoZXIgdG8gY2FsY3VsYXRlIGxpbmUgbWV0cmljc1xuICAgIHByb21vdGVJZDogbnVsbCwgICAgICAgIC8vIG5hbWUgb2YgYSBmZWF0dXJlIHByb3BlcnR5IHRvIGJlIHByb21vdGVkIHRvIGZlYXR1cmUuaWRcbiAgICBnZW5lcmF0ZUlkOiBmYWxzZSwgICAgICAvLyB3aGV0aGVyIHRvIGdlbmVyYXRlIGZlYXR1cmUgaWRzLiBDYW5ub3QgYmUgdXNlZCB3aXRoIHByb21vdGVJZFxuICAgIGRlYnVnOiAwICAgICAgICAgICAgICAgIC8vIGxvZ2dpbmcgbGV2ZWwgKDAsIDEgb3IgMilcbn07XG5cbkdlb0pTT05WVC5wcm90b3R5cGUuc3BsaXRUaWxlID0gZnVuY3Rpb24gKGZlYXR1cmVzLCB6LCB4LCB5LCBjeiwgY3gsIGN5KSB7XG5cbiAgICB2YXIgc3RhY2sgPSBbZmVhdHVyZXMsIHosIHgsIHldLFxuICAgICAgICBvcHRpb25zID0gdGhpcy5vcHRpb25zLFxuICAgICAgICBkZWJ1ZyA9IG9wdGlvbnMuZGVidWc7XG5cbiAgICAvLyBhdm9pZCByZWN1cnNpb24gYnkgdXNpbmcgYSBwcm9jZXNzaW5nIHF1ZXVlXG4gICAgd2hpbGUgKHN0YWNrLmxlbmd0aCkge1xuICAgICAgICB5ID0gc3RhY2sucG9wKCk7XG4gICAgICAgIHggPSBzdGFjay5wb3AoKTtcbiAgICAgICAgeiA9IHN0YWNrLnBvcCgpO1xuICAgICAgICBmZWF0dXJlcyA9IHN0YWNrLnBvcCgpO1xuXG4gICAgICAgIHZhciB6MiA9IDEgPDwgeixcbiAgICAgICAgICAgIGlkID0gdG9JRCh6LCB4LCB5KSxcbiAgICAgICAgICAgIHRpbGUgPSB0aGlzLnRpbGVzW2lkXTtcblxuICAgICAgICBpZiAoIXRpbGUpIHtcbiAgICAgICAgICAgIGlmIChkZWJ1ZyA+IDEpIGNvbnNvbGUudGltZSgnY3JlYXRpb24nKTtcblxuICAgICAgICAgICAgdGlsZSA9IHRoaXMudGlsZXNbaWRdID0gY3JlYXRlVGlsZShmZWF0dXJlcywgeiwgeCwgeSwgb3B0aW9ucyk7XG4gICAgICAgICAgICB0aGlzLnRpbGVDb29yZHMucHVzaCh7ejogeiwgeDogeCwgeTogeX0pO1xuXG4gICAgICAgICAgICBpZiAoZGVidWcpIHtcbiAgICAgICAgICAgICAgICBpZiAoZGVidWcgPiAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCd0aWxlIHolZC0lZC0lZCAoZmVhdHVyZXM6ICVkLCBwb2ludHM6ICVkLCBzaW1wbGlmaWVkOiAlZCknLFxuICAgICAgICAgICAgICAgICAgICAgICAgeiwgeCwgeSwgdGlsZS5udW1GZWF0dXJlcywgdGlsZS5udW1Qb2ludHMsIHRpbGUubnVtU2ltcGxpZmllZCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUudGltZUVuZCgnY3JlYXRpb24nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIGtleSA9ICd6JyArIHo7XG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0c1trZXldID0gKHRoaXMuc3RhdHNba2V5XSB8fCAwKSArIDE7XG4gICAgICAgICAgICAgICAgdGhpcy50b3RhbCsrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gc2F2ZSByZWZlcmVuY2UgdG8gb3JpZ2luYWwgZ2VvbWV0cnkgaW4gdGlsZSBzbyB0aGF0IHdlIGNhbiBkcmlsbCBkb3duIGxhdGVyIGlmIHdlIHN0b3Agbm93XG4gICAgICAgIHRpbGUuc291cmNlID0gZmVhdHVyZXM7XG5cbiAgICAgICAgLy8gaWYgaXQncyB0aGUgZmlyc3QtcGFzcyB0aWxpbmdcbiAgICAgICAgaWYgKCFjeikge1xuICAgICAgICAgICAgLy8gc3RvcCB0aWxpbmcgaWYgd2UgcmVhY2hlZCBtYXggem9vbSwgb3IgaWYgdGhlIHRpbGUgaXMgdG9vIHNpbXBsZVxuICAgICAgICAgICAgaWYgKHogPT09IG9wdGlvbnMuaW5kZXhNYXhab29tIHx8IHRpbGUubnVtUG9pbnRzIDw9IG9wdGlvbnMuaW5kZXhNYXhQb2ludHMpIGNvbnRpbnVlO1xuXG4gICAgICAgIC8vIGlmIGEgZHJpbGxkb3duIHRvIGEgc3BlY2lmaWMgdGlsZVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gc3RvcCB0aWxpbmcgaWYgd2UgcmVhY2hlZCBiYXNlIHpvb20gb3Igb3VyIHRhcmdldCB0aWxlIHpvb21cbiAgICAgICAgICAgIGlmICh6ID09PSBvcHRpb25zLm1heFpvb20gfHwgeiA9PT0gY3opIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICAvLyBzdG9wIHRpbGluZyBpZiBpdCdzIG5vdCBhbiBhbmNlc3RvciBvZiB0aGUgdGFyZ2V0IHRpbGVcbiAgICAgICAgICAgIHZhciBtID0gMSA8PCAoY3ogLSB6KTtcbiAgICAgICAgICAgIGlmICh4ICE9PSBNYXRoLmZsb29yKGN4IC8gbSkgfHwgeSAhPT0gTWF0aC5mbG9vcihjeSAvIG0pKSBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGlmIHdlIHNsaWNlIGZ1cnRoZXIgZG93biwgbm8gbmVlZCB0byBrZWVwIHNvdXJjZSBnZW9tZXRyeVxuICAgICAgICB0aWxlLnNvdXJjZSA9IG51bGw7XG5cbiAgICAgICAgaWYgKGZlYXR1cmVzLmxlbmd0aCA9PT0gMCkgY29udGludWU7XG5cbiAgICAgICAgaWYgKGRlYnVnID4gMSkgY29uc29sZS50aW1lKCdjbGlwcGluZycpO1xuXG4gICAgICAgIC8vIHZhbHVlcyB3ZSdsbCB1c2UgZm9yIGNsaXBwaW5nXG4gICAgICAgIHZhciBrMSA9IDAuNSAqIG9wdGlvbnMuYnVmZmVyIC8gb3B0aW9ucy5leHRlbnQsXG4gICAgICAgICAgICBrMiA9IDAuNSAtIGsxLFxuICAgICAgICAgICAgazMgPSAwLjUgKyBrMSxcbiAgICAgICAgICAgIGs0ID0gMSArIGsxLFxuICAgICAgICAgICAgdGwsIGJsLCB0ciwgYnIsIGxlZnQsIHJpZ2h0O1xuXG4gICAgICAgIHRsID0gYmwgPSB0ciA9IGJyID0gbnVsbDtcblxuICAgICAgICBsZWZ0ICA9IGNsaXAoZmVhdHVyZXMsIHoyLCB4IC0gazEsIHggKyBrMywgMCwgdGlsZS5taW5YLCB0aWxlLm1heFgsIG9wdGlvbnMpO1xuICAgICAgICByaWdodCA9IGNsaXAoZmVhdHVyZXMsIHoyLCB4ICsgazIsIHggKyBrNCwgMCwgdGlsZS5taW5YLCB0aWxlLm1heFgsIG9wdGlvbnMpO1xuICAgICAgICBmZWF0dXJlcyA9IG51bGw7XG5cbiAgICAgICAgaWYgKGxlZnQpIHtcbiAgICAgICAgICAgIHRsID0gY2xpcChsZWZ0LCB6MiwgeSAtIGsxLCB5ICsgazMsIDEsIHRpbGUubWluWSwgdGlsZS5tYXhZLCBvcHRpb25zKTtcbiAgICAgICAgICAgIGJsID0gY2xpcChsZWZ0LCB6MiwgeSArIGsyLCB5ICsgazQsIDEsIHRpbGUubWluWSwgdGlsZS5tYXhZLCBvcHRpb25zKTtcbiAgICAgICAgICAgIGxlZnQgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHJpZ2h0KSB7XG4gICAgICAgICAgICB0ciA9IGNsaXAocmlnaHQsIHoyLCB5IC0gazEsIHkgKyBrMywgMSwgdGlsZS5taW5ZLCB0aWxlLm1heFksIG9wdGlvbnMpO1xuICAgICAgICAgICAgYnIgPSBjbGlwKHJpZ2h0LCB6MiwgeSArIGsyLCB5ICsgazQsIDEsIHRpbGUubWluWSwgdGlsZS5tYXhZLCBvcHRpb25zKTtcbiAgICAgICAgICAgIHJpZ2h0ID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkZWJ1ZyA+IDEpIGNvbnNvbGUudGltZUVuZCgnY2xpcHBpbmcnKTtcblxuICAgICAgICBzdGFjay5wdXNoKHRsIHx8IFtdLCB6ICsgMSwgeCAqIDIsICAgICB5ICogMik7XG4gICAgICAgIHN0YWNrLnB1c2goYmwgfHwgW10sIHogKyAxLCB4ICogMiwgICAgIHkgKiAyICsgMSk7XG4gICAgICAgIHN0YWNrLnB1c2godHIgfHwgW10sIHogKyAxLCB4ICogMiArIDEsIHkgKiAyKTtcbiAgICAgICAgc3RhY2sucHVzaChiciB8fCBbXSwgeiArIDEsIHggKiAyICsgMSwgeSAqIDIgKyAxKTtcbiAgICB9XG59O1xuXG5HZW9KU09OVlQucHJvdG90eXBlLmdldFRpbGUgPSBmdW5jdGlvbiAoeiwgeCwgeSkge1xuICAgIHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zLFxuICAgICAgICBleHRlbnQgPSBvcHRpb25zLmV4dGVudCxcbiAgICAgICAgZGVidWcgPSBvcHRpb25zLmRlYnVnO1xuXG4gICAgaWYgKHogPCAwIHx8IHogPiAyNCkgcmV0dXJuIG51bGw7XG5cbiAgICB2YXIgejIgPSAxIDw8IHo7XG4gICAgeCA9ICgoeCAlIHoyKSArIHoyKSAlIHoyOyAvLyB3cmFwIHRpbGUgeCBjb29yZGluYXRlXG5cbiAgICB2YXIgaWQgPSB0b0lEKHosIHgsIHkpO1xuICAgIGlmICh0aGlzLnRpbGVzW2lkXSkgcmV0dXJuIHRyYW5zZm9ybSh0aGlzLnRpbGVzW2lkXSwgZXh0ZW50KTtcblxuICAgIGlmIChkZWJ1ZyA+IDEpIGNvbnNvbGUubG9nKCdkcmlsbGluZyBkb3duIHRvIHolZC0lZC0lZCcsIHosIHgsIHkpO1xuXG4gICAgdmFyIHowID0geixcbiAgICAgICAgeDAgPSB4LFxuICAgICAgICB5MCA9IHksXG4gICAgICAgIHBhcmVudDtcblxuICAgIHdoaWxlICghcGFyZW50ICYmIHowID4gMCkge1xuICAgICAgICB6MC0tO1xuICAgICAgICB4MCA9IE1hdGguZmxvb3IoeDAgLyAyKTtcbiAgICAgICAgeTAgPSBNYXRoLmZsb29yKHkwIC8gMik7XG4gICAgICAgIHBhcmVudCA9IHRoaXMudGlsZXNbdG9JRCh6MCwgeDAsIHkwKV07XG4gICAgfVxuXG4gICAgaWYgKCFwYXJlbnQgfHwgIXBhcmVudC5zb3VyY2UpIHJldHVybiBudWxsO1xuXG4gICAgLy8gaWYgd2UgZm91bmQgYSBwYXJlbnQgdGlsZSBjb250YWluaW5nIHRoZSBvcmlnaW5hbCBnZW9tZXRyeSwgd2UgY2FuIGRyaWxsIGRvd24gZnJvbSBpdFxuICAgIGlmIChkZWJ1ZyA+IDEpIGNvbnNvbGUubG9nKCdmb3VuZCBwYXJlbnQgdGlsZSB6JWQtJWQtJWQnLCB6MCwgeDAsIHkwKTtcblxuICAgIGlmIChkZWJ1ZyA+IDEpIGNvbnNvbGUudGltZSgnZHJpbGxpbmcgZG93bicpO1xuICAgIHRoaXMuc3BsaXRUaWxlKHBhcmVudC5zb3VyY2UsIHowLCB4MCwgeTAsIHosIHgsIHkpO1xuICAgIGlmIChkZWJ1ZyA+IDEpIGNvbnNvbGUudGltZUVuZCgnZHJpbGxpbmcgZG93bicpO1xuXG4gICAgcmV0dXJuIHRoaXMudGlsZXNbaWRdID8gdHJhbnNmb3JtKHRoaXMudGlsZXNbaWRdLCBleHRlbnQpIDogbnVsbDtcbn07XG5cbmZ1bmN0aW9uIHRvSUQoeiwgeCwgeSkge1xuICAgIHJldHVybiAoKCgxIDw8IHopICogeSArIHgpICogMzIpICsgejtcbn1cblxuZnVuY3Rpb24gZXh0ZW5kKGRlc3QsIHNyYykge1xuICAgIGZvciAodmFyIGkgaW4gc3JjKSBkZXN0W2ldID0gc3JjW2ldO1xuICAgIHJldHVybiBkZXN0O1xufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtnZXRKU09OfSBmcm9tICcuLi91dGlsL2FqYXguanMnO1xuXG5pbXBvcnQge2dldFBlcmZvcm1hbmNlTWVhc3VyZW1lbnR9IGZyb20gJy4uL3V0aWwvcGVyZm9ybWFuY2UuanMnO1xuaW1wb3J0IHJld2luZCBmcm9tICdAbWFwYm94L2dlb2pzb24tcmV3aW5kJztcbmltcG9ydCBHZW9KU09OV3JhcHBlciBmcm9tICcuL2dlb2pzb25fd3JhcHBlci5qcyc7XG5pbXBvcnQgdnRwYmYgZnJvbSAndnQtcGJmJztcbmltcG9ydCBTdXBlcmNsdXN0ZXIgZnJvbSAnc3VwZXJjbHVzdGVyJztcbmltcG9ydCBnZW9qc29udnQgZnJvbSAnZ2VvanNvbi12dCc7XG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgVmVjdG9yVGlsZVdvcmtlclNvdXJjZSBmcm9tICcuL3ZlY3Rvcl90aWxlX3dvcmtlcl9zb3VyY2UuanMnO1xuaW1wb3J0IHtjcmVhdGVFeHByZXNzaW9ufSBmcm9tICcuLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vaW5kZXguanMnO1xuXG5pbXBvcnQgdHlwZSB7XG4gICAgUmVxdWVzdGVkVGlsZVBhcmFtZXRlcnMsXG4gICAgV29ya2VyVGlsZVBhcmFtZXRlcnMsXG4gICAgV29ya2VyVGlsZUNhbGxiYWNrLFxufSBmcm9tICcuLi9zb3VyY2Uvd29ya2VyX3NvdXJjZS5qcyc7XG5cbmltcG9ydCB0eXBlIEFjdG9yIGZyb20gJy4uL3V0aWwvYWN0b3IuanMnO1xuaW1wb3J0IHR5cGUgU3R5bGVMYXllckluZGV4IGZyb20gJy4uL3N0eWxlL3N0eWxlX2xheWVyX2luZGV4LmpzJztcblxuaW1wb3J0IHR5cGUge0xvYWRWZWN0b3JEYXRhQ2FsbGJhY2t9IGZyb20gJy4vdmVjdG9yX3RpbGVfd29ya2VyX3NvdXJjZS5qcyc7XG5pbXBvcnQgdHlwZSB7UmVxdWVzdFBhcmFtZXRlcnMsIFJlc3BvbnNlQ2FsbGJhY2t9IGZyb20gJy4uL3V0aWwvYWpheC5qcyc7XG5pbXBvcnQgdHlwZSB7Q2FsbGJhY2t9IGZyb20gJy4uL3R5cGVzL2NhbGxiYWNrLmpzJztcbmltcG9ydCB0eXBlIHtHZW9KU09ORmVhdHVyZX0gZnJvbSAnQG1hcGJveC9nZW9qc29uLXR5cGVzJztcblxuZXhwb3J0IHR5cGUgR2VvSlNPTldvcmtlck9wdGlvbnMgPSB7XG4gICAgc291cmNlOiBzdHJpbmcsXG4gICAgY2x1c3RlcjogYm9vbGVhbixcbiAgICBzdXBlcmNsdXN0ZXJPcHRpb25zPzogT2JqZWN0LFxuICAgIGdlb2pzb25WdE9wdGlvbnM/OiBPYmplY3QsXG4gICAgY2x1c3RlclByb3BlcnRpZXM/OiBPYmplY3QsXG4gICAgZmlsdGVyPzogQXJyYXk8bWl4ZWQ+XG59O1xuXG5leHBvcnQgdHlwZSBMb2FkR2VvSlNPTlBhcmFtZXRlcnMgPSBHZW9KU09OV29ya2VyT3B0aW9ucyAmIHtcbiAgICByZXF1ZXN0PzogUmVxdWVzdFBhcmFtZXRlcnMsXG4gICAgZGF0YT86IHN0cmluZ1xufTtcblxuZXhwb3J0IHR5cGUgTG9hZEdlb0pTT04gPSAocGFyYW1zOiBMb2FkR2VvSlNPTlBhcmFtZXRlcnMsIGNhbGxiYWNrOiBSZXNwb25zZUNhbGxiYWNrPE9iamVjdD4pID0+IHZvaWQ7XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2VvSlNPTkluZGV4IHtcbiAgICBnZXRUaWxlKHo6IG51bWJlciwgeDogbnVtYmVyLCB5OiBudW1iZXIpOiBPYmplY3Q7XG5cbiAgICAvLyBzdXBlcmNsdXN0ZXIgbWV0aG9kc1xuICAgIGdldENsdXN0ZXJFeHBhbnNpb25ab29tKGNsdXN0ZXJJZDogbnVtYmVyKTogbnVtYmVyO1xuICAgIGdldENoaWxkcmVuKGNsdXN0ZXJJZDogbnVtYmVyKTogQXJyYXk8R2VvSlNPTkZlYXR1cmU+O1xuICAgIGdldExlYXZlcyhjbHVzdGVySWQ6IG51bWJlciwgbGltaXQ6IG51bWJlciwgb2Zmc2V0OiBudW1iZXIpOiBBcnJheTxHZW9KU09ORmVhdHVyZT47XG59XG5cbi8vICRGbG93Rml4TWVbbWlzc2luZy10aGlzLWFubm90XVxuZnVuY3Rpb24gbG9hZEdlb0pTT05UaWxlKHBhcmFtczogUmVxdWVzdGVkVGlsZVBhcmFtZXRlcnMsIGNhbGxiYWNrOiBMb2FkVmVjdG9yRGF0YUNhbGxiYWNrKSB7XG4gICAgY29uc3QgY2Fub25pY2FsID0gcGFyYW1zLnRpbGVJRC5jYW5vbmljYWw7XG5cbiAgICBpZiAoIXRoaXMuX2dlb0pTT05JbmRleCkge1xuICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgbnVsbCk7ICAvLyB3ZSBjb3VsZG4ndCBsb2FkIHRoZSBmaWxlXG4gICAgfVxuXG4gICAgY29uc3QgZ2VvSlNPTlRpbGUgPSB0aGlzLl9nZW9KU09OSW5kZXguZ2V0VGlsZShjYW5vbmljYWwueiwgY2Fub25pY2FsLngsIGNhbm9uaWNhbC55KTtcbiAgICBpZiAoIWdlb0pTT05UaWxlKSB7XG4gICAgICAgIHJldHVybiBjYWxsYmFjayhudWxsLCBudWxsKTsgLy8gbm90aGluZyBpbiB0aGUgZ2l2ZW4gdGlsZVxuICAgIH1cblxuICAgIGNvbnN0IGdlb2pzb25XcmFwcGVyID0gbmV3IEdlb0pTT05XcmFwcGVyKGdlb0pTT05UaWxlLmZlYXR1cmVzKTtcblxuICAgIC8vIEVuY29kZSB0aGUgZ2VvanNvbi12dCB0aWxlIGludG8gYmluYXJ5IHZlY3RvciB0aWxlIGZvcm0uICBUaGlzXG4gICAgLy8gaXMgYSBjb252ZW5pZW5jZSB0aGF0IGFsbG93cyBgRmVhdHVyZUluZGV4YCB0byBvcGVyYXRlIHRoZSBzYW1lIHdheVxuICAgIC8vIGFjcm9zcyBgVmVjdG9yVGlsZVNvdXJjZWAgYW5kIGBHZW9KU09OU291cmNlYCBkYXRhLlxuICAgIGxldCBwYmYgPSB2dHBiZihnZW9qc29uV3JhcHBlcik7XG4gICAgaWYgKHBiZi5ieXRlT2Zmc2V0ICE9PSAwIHx8IHBiZi5ieXRlTGVuZ3RoICE9PSBwYmYuYnVmZmVyLmJ5dGVMZW5ndGgpIHtcbiAgICAgICAgLy8gQ29tcGF0aWJpbGl0eSB3aXRoIG5vZGUgQnVmZmVyIChodHRwczovL2dpdGh1Yi5jb20vbWFwYm94L3BiZi9pc3N1ZXMvMzUpXG4gICAgICAgIHBiZiA9IG5ldyBVaW50OEFycmF5KHBiZik7XG4gICAgfVxuXG4gICAgY2FsbGJhY2sobnVsbCwge1xuICAgICAgICB2ZWN0b3JUaWxlOiBnZW9qc29uV3JhcHBlcixcbiAgICAgICAgcmF3RGF0YTogcGJmLmJ1ZmZlclxuICAgIH0pO1xufVxuXG4vKipcbiAqIFRoZSB7QGxpbmsgV29ya2VyU291cmNlfSBpbXBsZW1lbnRhdGlvbiB0aGF0IHN1cHBvcnRzIHtAbGluayBHZW9KU09OU291cmNlfS5cbiAqIFRoaXMgY2xhc3MgaXMgZGVzaWduZWQgdG8gYmUgZWFzaWx5IHJldXNlZCB0byBzdXBwb3J0IGN1c3RvbSBzb3VyY2UgdHlwZXNcbiAqIGZvciBkYXRhIGZvcm1hdHMgdGhhdCBjYW4gYmUgcGFyc2VkL2NvbnZlcnRlZCBpbnRvIGFuIGluLW1lbW9yeSBHZW9KU09OXG4gKiByZXByZXNlbnRhdGlvbi4gIFRvIGRvIHNvLCBjcmVhdGUgaXQgd2l0aFxuICogYG5ldyBHZW9KU09OV29ya2VyU291cmNlKGFjdG9yLCBsYXllckluZGV4LCBjdXN0b21Mb2FkR2VvSlNPTkZ1bmN0aW9uKWAuXG4gKiBGb3IgYSBmdWxsIGV4YW1wbGUsIHNlZSBbbWFwYm94LWdsLXRvcG9qc29uXShodHRwczovL2dpdGh1Yi5jb20vZGV2ZWxvcG1lbnRzZWVkL21hcGJveC1nbC10b3BvanNvbikuXG4gKlxuICogQHByaXZhdGVcbiAqL1xuY2xhc3MgR2VvSlNPTldvcmtlclNvdXJjZSBleHRlbmRzIFZlY3RvclRpbGVXb3JrZXJTb3VyY2Uge1xuICAgIGxvYWRHZW9KU09OOiBMb2FkR2VvSlNPTjtcbiAgICBfZ2VvSlNPTkluZGV4OiBHZW9KU09OSW5kZXhcblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBbbG9hZEdlb0pTT05dIE9wdGlvbmFsIG1ldGhvZCBmb3IgY3VzdG9tIGxvYWRpbmcvcGFyc2luZyBvZlxuICAgICAqIEdlb0pTT04gYmFzZWQgb24gcGFyYW1ldGVycyBwYXNzZWQgZnJvbSB0aGUgbWFpbi10aHJlYWQgU291cmNlLlxuICAgICAqIFNlZSB7QGxpbmsgR2VvSlNPTldvcmtlclNvdXJjZSNsb2FkR2VvSlNPTn0uXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihhY3RvcjogQWN0b3IsIGxheWVySW5kZXg6IFN0eWxlTGF5ZXJJbmRleCwgYXZhaWxhYmxlSW1hZ2VzOiBBcnJheTxzdHJpbmc+LCBpc1Nwcml0ZUxvYWRlZDogYm9vbGVhbiwgbG9hZEdlb0pTT046ID9Mb2FkR2VvSlNPTikge1xuICAgICAgICBzdXBlcihhY3RvciwgbGF5ZXJJbmRleCwgYXZhaWxhYmxlSW1hZ2VzLCBpc1Nwcml0ZUxvYWRlZCwgbG9hZEdlb0pTT05UaWxlKTtcbiAgICAgICAgaWYgKGxvYWRHZW9KU09OKSB7XG4gICAgICAgICAgICB0aGlzLmxvYWRHZW9KU09OID0gbG9hZEdlb0pTT047XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIChpZiBhcHByb3ByaWF0ZSksIHBhcnNlcywgYW5kIGluZGV4IGdlb2pzb24gZGF0YSBpbnRvIHRpbGVzLiBUaGlzXG4gICAgICogcHJlcGFyYXRvcnkgbWV0aG9kIG11c3QgYmUgY2FsbGVkIGJlZm9yZSB7QGxpbmsgR2VvSlNPTldvcmtlclNvdXJjZSNsb2FkVGlsZX1cbiAgICAgKiBjYW4gY29ycmVjdGx5IHNlcnZlIHVwIHRpbGVzLlxuICAgICAqXG4gICAgICogRGVmZXJzIHRvIHtAbGluayBHZW9KU09OV29ya2VyU291cmNlI2xvYWRHZW9KU09OfSBmb3IgdGhlIGZldGNoaW5nL3BhcnNpbmcsXG4gICAgICogZXhwZWN0aW5nIGBjYWxsYmFjayhlcnJvciwgZGF0YSlgIHRvIGJlIGNhbGxlZCB3aXRoIGVpdGhlciBhbiBlcnJvciBvciBhXG4gICAgICogcGFyc2VkIEdlb0pTT04gb2JqZWN0LlxuICAgICAqXG4gICAgICogV2hlbiBgbG9hZERhdGFgIHJlcXVlc3RzIGNvbWUgaW4gZmFzdGVyIHRoYW4gdGhleSBjYW4gYmUgcHJvY2Vzc2VkLFxuICAgICAqIHRoZXkgYXJlIGNvYWxlc2NlZCBpbnRvIGEgc2luZ2xlIHJlcXVlc3QgdXNpbmcgdGhlIGxhdGVzdCBkYXRhLlxuICAgICAqIFNlZSB7QGxpbmsgR2VvSlNPTldvcmtlclNvdXJjZSNjb2FsZXNjZX1cbiAgICAgKlxuICAgICAqIEBwYXJhbSBwYXJhbXNcbiAgICAgKiBAcGFyYW0gY2FsbGJhY2tcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIGxvYWREYXRhKHBhcmFtczogTG9hZEdlb0pTT05QYXJhbWV0ZXJzLCBjYWxsYmFjazogQ2FsbGJhY2s8e3Jlc291cmNlVGltaW5nPzoge1tfOiBzdHJpbmddOiBBcnJheTxQZXJmb3JtYW5jZVJlc291cmNlVGltaW5nPn19Pikge1xuICAgICAgICBjb25zdCByZXF1ZXN0UGFyYW0gPSBwYXJhbXMgJiYgcGFyYW1zLnJlcXVlc3Q7XG4gICAgICAgIGNvbnN0IHBlcmYgPSByZXF1ZXN0UGFyYW0gJiYgcmVxdWVzdFBhcmFtLmNvbGxlY3RSZXNvdXJjZVRpbWluZztcblxuICAgICAgICB0aGlzLmxvYWRHZW9KU09OKHBhcmFtcywgKGVycjogP0Vycm9yLCBkYXRhOiA/T2JqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAoZXJyIHx8ICFkYXRhKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRhICE9PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhuZXcgRXJyb3IoYElucHV0IGRhdGEgZ2l2ZW4gdG8gJyR7cGFyYW1zLnNvdXJjZX0nIGlzIG5vdCBhIHZhbGlkIEdlb0pTT04gb2JqZWN0LmApKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV3aW5kKGRhdGEsIHRydWUpO1xuXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmFtcy5maWx0ZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbXBpbGVkID0gY3JlYXRlRXhwcmVzc2lvbihwYXJhbXMuZmlsdGVyLCB7dHlwZTogJ2Jvb2xlYW4nLCAncHJvcGVydHktdHlwZSc6ICdkYXRhLWRyaXZlbicsIG92ZXJyaWRhYmxlOiBmYWxzZSwgdHJhbnNpdGlvbjogZmFsc2V9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb21waWxlZC5yZXN1bHQgPT09ICdlcnJvcicpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGNvbXBpbGVkLnZhbHVlLm1hcChlcnIgPT4gYCR7ZXJyLmtleX06ICR7ZXJyLm1lc3NhZ2V9YCkuam9pbignLCAnKSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZlYXR1cmVzID0gZGF0YS5mZWF0dXJlcy5maWx0ZXIoZmVhdHVyZSA9PiBjb21waWxlZC52YWx1ZS5ldmFsdWF0ZSh7em9vbTogMH0sIGZlYXR1cmUpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSB7dHlwZTogJ0ZlYXR1cmVDb2xsZWN0aW9uJywgZmVhdHVyZXN9O1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZ2VvSlNPTkluZGV4ID0gcGFyYW1zLmNsdXN0ZXIgP1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN1cGVyY2x1c3RlcihnZXRTdXBlcmNsdXN0ZXJPcHRpb25zKHBhcmFtcykpLmxvYWQoZGF0YS5mZWF0dXJlcykgOlxuICAgICAgICAgICAgICAgICAgICAgICAgZ2VvanNvbnZ0KGRhdGEsIHBhcmFtcy5nZW9qc29uVnRPcHRpb25zKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkZWQgPSB7fTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IHt9O1xuICAgICAgICAgICAgICAgIGlmIChwZXJmKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc291cmNlVGltaW5nRGF0YSA9IGdldFBlcmZvcm1hbmNlTWVhc3VyZW1lbnQocmVxdWVzdFBhcmFtKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gaXQncyBuZWNlc3NhcnkgdG8gZXZhbCB0aGUgcmVzdWx0IG9mIGdldEVudHJpZXNCeU5hbWUoKSBoZXJlIHZpYSBwYXJzZS9zdHJpbmdpZnlcbiAgICAgICAgICAgICAgICAgICAgLy8gbGF0ZSBldmFsdWF0aW9uIGluIHRoZSBtYWluIHRocmVhZCBjYXVzZXMgVHlwZUVycm9yOiBpbGxlZ2FsIGludm9jYXRpb25cbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc291cmNlVGltaW5nRGF0YSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnJlc291cmNlVGltaW5nID0ge307XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQucmVzb3VyY2VUaW1pbmdbcGFyYW1zLnNvdXJjZV0gPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHJlc291cmNlVGltaW5nRGF0YSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIHJlc3VsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogSW1wbGVtZW50cyB7QGxpbmsgV29ya2VyU291cmNlI3JlbG9hZFRpbGV9LlxuICAgICpcbiAgICAqIElmIHRoZSB0aWxlIGlzIGxvYWRlZCwgdXNlcyB0aGUgaW1wbGVtZW50YXRpb24gaW4gVmVjdG9yVGlsZVdvcmtlclNvdXJjZS5cbiAgICAqIE90aGVyd2lzZSwgc3VjaCBhcyBhZnRlciBhIHNldERhdGEoKSBjYWxsLCB3ZSBsb2FkIHRoZSB0aWxlIGZyZXNoLlxuICAgICpcbiAgICAqIEBwYXJhbSBwYXJhbXNcbiAgICAqIEBwYXJhbSBwYXJhbXMudWlkIFRoZSBVSUQgZm9yIHRoaXMgdGlsZS5cbiAgICAqIEBwcml2YXRlXG4gICAgKi9cbiAgICByZWxvYWRUaWxlKHBhcmFtczogV29ya2VyVGlsZVBhcmFtZXRlcnMsIGNhbGxiYWNrOiBXb3JrZXJUaWxlQ2FsbGJhY2spOiB2b2lkIHtcbiAgICAgICAgY29uc3QgbG9hZGVkID0gdGhpcy5sb2FkZWQsXG4gICAgICAgICAgICB1aWQgPSBwYXJhbXMudWlkO1xuXG4gICAgICAgIGlmIChsb2FkZWQgJiYgbG9hZGVkW3VpZF0pIHtcbiAgICAgICAgICAgIHJldHVybiBzdXBlci5yZWxvYWRUaWxlKHBhcmFtcywgY2FsbGJhY2spO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9hZFRpbGUocGFyYW1zLCBjYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaCBhbmQgcGFyc2UgR2VvSlNPTiBhY2NvcmRpbmcgdG8gdGhlIGdpdmVuIHBhcmFtcy4gIENhbGxzIGBjYWxsYmFja2BcbiAgICAgKiB3aXRoIGAoZXJyLCBkYXRhKWAsIHdoZXJlIGBkYXRhYCBpcyBhIHBhcnNlZCBHZW9KU09OIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEdlb0pTT04gaXMgbG9hZGVkIGFuZCBwYXJzZWQgZnJvbSBgcGFyYW1zLnVybGAgaWYgaXQgZXhpc3RzLCBvciBlbHNlXG4gICAgICogZXhwZWN0ZWQgYXMgYSBsaXRlcmFsIChzdHJpbmcgb3Igb2JqZWN0KSBgcGFyYW1zLmRhdGFgLlxuICAgICAqXG4gICAgICogQHBhcmFtIHBhcmFtc1xuICAgICAqIEBwYXJhbSBbcGFyYW1zLnVybF0gQSBVUkwgdG8gdGhlIHJlbW90ZSBHZW9KU09OIGRhdGEuXG4gICAgICogQHBhcmFtIFtwYXJhbXMuZGF0YV0gTGl0ZXJhbCBHZW9KU09OIGRhdGEuIE11c3QgYmUgcHJvdmlkZWQgaWYgYHBhcmFtcy51cmxgIGlzIG5vdC5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIC8vICRGbG93Rml4TWVbZHVwbGljYXRlLWNsYXNzLW1lbWJlcl1cbiAgICBsb2FkR2VvSlNPTihwYXJhbXM6IExvYWRHZW9KU09OUGFyYW1ldGVycywgY2FsbGJhY2s6IFJlc3BvbnNlQ2FsbGJhY2s8T2JqZWN0Pik6IHZvaWQge1xuICAgICAgICAvLyBCZWNhdXNlIG9mIHNhbWUgb3JpZ2luIGlzc3VlcywgdXJscyBtdXN0IGVpdGhlciBpbmNsdWRlIGFuIGV4cGxpY2l0XG4gICAgICAgIC8vIG9yaWdpbiBvciBhYnNvbHV0ZSBwYXRoLlxuICAgICAgICAvLyBpZTogL2Zvby9iYXIuanNvbiBvciBodHRwOi8vZXhhbXBsZS5jb20vYmFyLmpzb25cbiAgICAgICAgLy8gYnV0IG5vdCAuLi9mb28vYmFyLmpzb25cbiAgICAgICAgaWYgKHBhcmFtcy5yZXF1ZXN0KSB7XG4gICAgICAgICAgICBnZXRKU09OKHBhcmFtcy5yZXF1ZXN0LCBjYWxsYmFjayk7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHBhcmFtcy5kYXRhID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgSlNPTi5wYXJzZShwYXJhbXMuZGF0YSkpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhuZXcgRXJyb3IoYElucHV0IGRhdGEgZ2l2ZW4gdG8gJyR7cGFyYW1zLnNvdXJjZX0nIGlzIG5vdCBhIHZhbGlkIEdlb0pTT04gb2JqZWN0LmApKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhuZXcgRXJyb3IoYElucHV0IGRhdGEgZ2l2ZW4gdG8gJyR7cGFyYW1zLnNvdXJjZX0nIGlzIG5vdCBhIHZhbGlkIEdlb0pTT04gb2JqZWN0LmApKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldENsdXN0ZXJFeHBhbnNpb25ab29tKHBhcmFtczoge2NsdXN0ZXJJZDogbnVtYmVyfSwgY2FsbGJhY2s6IENhbGxiYWNrPG51bWJlcj4pIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIHRoaXMuX2dlb0pTT05JbmRleC5nZXRDbHVzdGVyRXhwYW5zaW9uWm9vbShwYXJhbXMuY2x1c3RlcklkKSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0Q2x1c3RlckNoaWxkcmVuKHBhcmFtczoge2NsdXN0ZXJJZDogbnVtYmVyfSwgY2FsbGJhY2s6IENhbGxiYWNrPEFycmF5PEdlb0pTT05GZWF0dXJlPj4pIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIHRoaXMuX2dlb0pTT05JbmRleC5nZXRDaGlsZHJlbihwYXJhbXMuY2x1c3RlcklkKSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0Q2x1c3RlckxlYXZlcyhwYXJhbXM6IHtjbHVzdGVySWQ6IG51bWJlciwgbGltaXQ6IG51bWJlciwgb2Zmc2V0OiBudW1iZXJ9LCBjYWxsYmFjazogQ2FsbGJhY2s8QXJyYXk8R2VvSlNPTkZlYXR1cmU+Pikge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgdGhpcy5fZ2VvSlNPTkluZGV4LmdldExlYXZlcyhwYXJhbXMuY2x1c3RlcklkLCBwYXJhbXMubGltaXQsIHBhcmFtcy5vZmZzZXQpKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY2FsbGJhY2soZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIGdldFN1cGVyY2x1c3Rlck9wdGlvbnMoe3N1cGVyY2x1c3Rlck9wdGlvbnMsIGNsdXN0ZXJQcm9wZXJ0aWVzfTogTG9hZEdlb0pTT05QYXJhbWV0ZXJzKSB7XG4gICAgaWYgKCFjbHVzdGVyUHJvcGVydGllcyB8fCAhc3VwZXJjbHVzdGVyT3B0aW9ucykgcmV0dXJuIHN1cGVyY2x1c3Rlck9wdGlvbnM7XG5cbiAgICBjb25zdCBtYXBFeHByZXNzaW9ucyA9IHt9O1xuICAgIGNvbnN0IHJlZHVjZUV4cHJlc3Npb25zID0ge307XG4gICAgY29uc3QgZ2xvYmFscyA9IHthY2N1bXVsYXRlZDogbnVsbCwgem9vbTogMH07XG4gICAgY29uc3QgZmVhdHVyZSA9IHtwcm9wZXJ0aWVzOiBudWxsfTtcbiAgICBjb25zdCBwcm9wZXJ0eU5hbWVzID0gT2JqZWN0LmtleXMoY2x1c3RlclByb3BlcnRpZXMpO1xuXG4gICAgZm9yIChjb25zdCBrZXkgb2YgcHJvcGVydHlOYW1lcykge1xuICAgICAgICBjb25zdCBbb3BlcmF0b3IsIG1hcEV4cHJlc3Npb25dID0gY2x1c3RlclByb3BlcnRpZXNba2V5XTtcblxuICAgICAgICBjb25zdCBtYXBFeHByZXNzaW9uUGFyc2VkID0gY3JlYXRlRXhwcmVzc2lvbihtYXBFeHByZXNzaW9uKTtcbiAgICAgICAgY29uc3QgcmVkdWNlRXhwcmVzc2lvblBhcnNlZCA9IGNyZWF0ZUV4cHJlc3Npb24oXG4gICAgICAgICAgICB0eXBlb2Ygb3BlcmF0b3IgPT09ICdzdHJpbmcnID8gW29wZXJhdG9yLCBbJ2FjY3VtdWxhdGVkJ10sIFsnZ2V0Jywga2V5XV0gOiBvcGVyYXRvcik7XG5cbiAgICAgICAgYXNzZXJ0KG1hcEV4cHJlc3Npb25QYXJzZWQucmVzdWx0ID09PSAnc3VjY2VzcycpO1xuICAgICAgICBhc3NlcnQocmVkdWNlRXhwcmVzc2lvblBhcnNlZC5yZXN1bHQgPT09ICdzdWNjZXNzJyk7XG5cbiAgICAgICAgbWFwRXhwcmVzc2lvbnNba2V5XSA9IG1hcEV4cHJlc3Npb25QYXJzZWQudmFsdWU7XG4gICAgICAgIHJlZHVjZUV4cHJlc3Npb25zW2tleV0gPSByZWR1Y2VFeHByZXNzaW9uUGFyc2VkLnZhbHVlO1xuICAgIH1cblxuICAgIHN1cGVyY2x1c3Rlck9wdGlvbnMubWFwID0gKHBvaW50UHJvcGVydGllcykgPT4ge1xuICAgICAgICBmZWF0dXJlLnByb3BlcnRpZXMgPSBwb2ludFByb3BlcnRpZXM7XG4gICAgICAgIGNvbnN0IHByb3BlcnRpZXMgPSB7fTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgcHJvcGVydHlOYW1lcykge1xuICAgICAgICAgICAgcHJvcGVydGllc1trZXldID0gbWFwRXhwcmVzc2lvbnNba2V5XS5ldmFsdWF0ZShnbG9iYWxzLCBmZWF0dXJlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcHJvcGVydGllcztcbiAgICB9O1xuICAgIHN1cGVyY2x1c3Rlck9wdGlvbnMucmVkdWNlID0gKGFjY3VtdWxhdGVkLCBjbHVzdGVyUHJvcGVydGllcykgPT4ge1xuICAgICAgICBmZWF0dXJlLnByb3BlcnRpZXMgPSBjbHVzdGVyUHJvcGVydGllcztcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgcHJvcGVydHlOYW1lcykge1xuICAgICAgICAgICAgZ2xvYmFscy5hY2N1bXVsYXRlZCA9IGFjY3VtdWxhdGVkW2tleV07XG4gICAgICAgICAgICBhY2N1bXVsYXRlZFtrZXldID0gcmVkdWNlRXhwcmVzc2lvbnNba2V5XS5ldmFsdWF0ZShnbG9iYWxzLCBmZWF0dXJlKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gc3VwZXJjbHVzdGVyT3B0aW9ucztcbn1cblxuZXhwb3J0IGRlZmF1bHQgR2VvSlNPTldvcmtlclNvdXJjZTtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCBBY3RvciBmcm9tICcuLi91dGlsL2FjdG9yLmpzJztcblxuaW1wb3J0IFN0eWxlTGF5ZXJJbmRleCBmcm9tICcuLi9zdHlsZS9zdHlsZV9sYXllcl9pbmRleC5qcyc7XG5pbXBvcnQgVmVjdG9yVGlsZVdvcmtlclNvdXJjZSBmcm9tICcuL3ZlY3Rvcl90aWxlX3dvcmtlcl9zb3VyY2UuanMnO1xuaW1wb3J0IFJhc3RlckRFTVRpbGVXb3JrZXJTb3VyY2UgZnJvbSAnLi9yYXN0ZXJfZGVtX3RpbGVfd29ya2VyX3NvdXJjZS5qcyc7XG5pbXBvcnQgR2VvSlNPTldvcmtlclNvdXJjZSBmcm9tICcuL2dlb2pzb25fd29ya2VyX3NvdXJjZS5qcyc7XG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQge3BsdWdpbiBhcyBnbG9iYWxSVExUZXh0UGx1Z2lufSBmcm9tICcuL3J0bF90ZXh0X3BsdWdpbi5qcyc7XG5pbXBvcnQge2VuZm9yY2VDYWNoZVNpemVMaW1pdH0gZnJvbSAnLi4vdXRpbC90aWxlX3JlcXVlc3RfY2FjaGUuanMnO1xuaW1wb3J0IHtleHRlbmR9IGZyb20gJy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQge1BlcmZvcm1hbmNlVXRpbHN9IGZyb20gJy4uL3V0aWwvcGVyZm9ybWFuY2UuanMnO1xuaW1wb3J0IHtFdmVudH0gZnJvbSAnLi4vdXRpbC9ldmVudGVkLmpzJztcbmltcG9ydCB7Z2V0UHJvamVjdGlvbn0gZnJvbSAnLi4vZ2VvL3Byb2plY3Rpb24vaW5kZXguanMnO1xuXG5pbXBvcnQgdHlwZSB7XG4gICAgV29ya2VyU291cmNlLFxuICAgIFdvcmtlclRpbGVQYXJhbWV0ZXJzLFxuICAgIFdvcmtlckRFTVRpbGVQYXJhbWV0ZXJzLFxuICAgIFdvcmtlclRpbGVDYWxsYmFjayxcbiAgICBXb3JrZXJERU1UaWxlQ2FsbGJhY2ssXG4gICAgVGlsZVBhcmFtZXRlcnNcbn0gZnJvbSAnLi4vc291cmNlL3dvcmtlcl9zb3VyY2UuanMnO1xuXG5pbXBvcnQgdHlwZSB7V29ya2VyR2xvYmFsU2NvcGVJbnRlcmZhY2V9IGZyb20gJy4uL3V0aWwvd2ViX3dvcmtlci5qcyc7XG5pbXBvcnQgdHlwZSB7Q2FsbGJhY2t9IGZyb20gJy4uL3R5cGVzL2NhbGxiYWNrLmpzJztcbmltcG9ydCB0eXBlIHtMYXllclNwZWNpZmljYXRpb24sIFByb2plY3Rpb25TcGVjaWZpY2F0aW9ufSBmcm9tICcuLi9zdHlsZS1zcGVjL3R5cGVzLmpzJztcbmltcG9ydCB0eXBlIHtQbHVnaW5TdGF0ZX0gZnJvbSAnLi9ydGxfdGV4dF9wbHVnaW4uanMnO1xuaW1wb3J0IHR5cGUgUHJvamVjdGlvbiBmcm9tICcuLi9nZW8vcHJvamVjdGlvbi9wcm9qZWN0aW9uLmpzJztcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBXb3JrZXIge1xuICAgIHNlbGY6IFdvcmtlckdsb2JhbFNjb3BlSW50ZXJmYWNlO1xuICAgIGFjdG9yOiBBY3RvcjtcbiAgICBsYXllckluZGV4ZXM6IHtbXzogc3RyaW5nXTogU3R5bGVMYXllckluZGV4IH07XG4gICAgYXZhaWxhYmxlSW1hZ2VzOiB7W186IHN0cmluZ106IEFycmF5PHN0cmluZz4gfTtcbiAgICB3b3JrZXJTb3VyY2VUeXBlczoge1tfOiBzdHJpbmddOiBDbGFzczxXb3JrZXJTb3VyY2U+IH07XG4gICAgd29ya2VyU291cmNlczoge1tfOiBzdHJpbmddOiB7W186IHN0cmluZ106IHtbXzogc3RyaW5nXTogV29ya2VyU291cmNlIH0gfSB9O1xuICAgIGRlbVdvcmtlclNvdXJjZXM6IHtbXzogc3RyaW5nXToge1tfOiBzdHJpbmddOiBSYXN0ZXJERU1UaWxlV29ya2VyU291cmNlIH0gfTtcbiAgICBwcm9qZWN0aW9uczoge1tfOiBzdHJpbmddOiBQcm9qZWN0aW9uIH07XG4gICAgZGVmYXVsdFByb2plY3Rpb246IFByb2plY3Rpb247XG4gICAgaXNTcHJpdGVMb2FkZWQ6IHtbXzogc3RyaW5nXTogYm9vbGVhbiB9O1xuICAgIHJlZmVycmVyOiA/c3RyaW5nO1xuICAgIHRlcnJhaW46ID9ib29sZWFuO1xuXG4gICAgY29uc3RydWN0b3Ioc2VsZjogV29ya2VyR2xvYmFsU2NvcGVJbnRlcmZhY2UpIHtcbiAgICAgICAgUGVyZm9ybWFuY2VVdGlscy5tZWFzdXJlKCd3b3JrZXJFdmFsdWF0ZVNjcmlwdCcpO1xuICAgICAgICB0aGlzLnNlbGYgPSBzZWxmO1xuICAgICAgICB0aGlzLmFjdG9yID0gbmV3IEFjdG9yKHNlbGYsIHRoaXMpO1xuXG4gICAgICAgIHRoaXMubGF5ZXJJbmRleGVzID0ge307XG4gICAgICAgIHRoaXMuYXZhaWxhYmxlSW1hZ2VzID0ge307XG4gICAgICAgIHRoaXMuaXNTcHJpdGVMb2FkZWQgPSB7fTtcblxuICAgICAgICB0aGlzLnByb2plY3Rpb25zID0ge307XG4gICAgICAgIHRoaXMuZGVmYXVsdFByb2plY3Rpb24gPSBnZXRQcm9qZWN0aW9uKHtuYW1lOiAnbWVyY2F0b3InfSk7XG5cbiAgICAgICAgdGhpcy53b3JrZXJTb3VyY2VUeXBlcyA9IHtcbiAgICAgICAgICAgIHZlY3RvcjogVmVjdG9yVGlsZVdvcmtlclNvdXJjZSxcbiAgICAgICAgICAgIGdlb2pzb246IEdlb0pTT05Xb3JrZXJTb3VyY2VcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBbbWFwSWRdW3NvdXJjZVR5cGVdW3NvdXJjZU5hbWVdID0+IHdvcmtlciBzb3VyY2UgaW5zdGFuY2VcbiAgICAgICAgdGhpcy53b3JrZXJTb3VyY2VzID0ge307XG4gICAgICAgIHRoaXMuZGVtV29ya2VyU291cmNlcyA9IHt9O1xuXG4gICAgICAgIHRoaXMuc2VsZi5yZWdpc3RlcldvcmtlclNvdXJjZSA9IChuYW1lOiBzdHJpbmcsIFdvcmtlclNvdXJjZTogQ2xhc3M8V29ya2VyU291cmNlPikgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMud29ya2VyU291cmNlVHlwZXNbbmFtZV0pIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFdvcmtlciBzb3VyY2Ugd2l0aCBuYW1lIFwiJHtuYW1lfVwiIGFscmVhZHkgcmVnaXN0ZXJlZC5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMud29ya2VyU291cmNlVHlwZXNbbmFtZV0gPSBXb3JrZXJTb3VyY2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gVGhpcyBpcyBpbnZva2VkIGJ5IHRoZSBSVEwgdGV4dCBwbHVnaW4gd2hlbiB0aGUgZG93bmxvYWQgdmlhIHRoZSBgaW1wb3J0U2NyaXB0c2AgY2FsbCBoYXMgZmluaXNoZWQsIGFuZCB0aGUgY29kZSBoYXMgYmVlbiBwYXJzZWQuXG4gICAgICAgIHRoaXMuc2VsZi5yZWdpc3RlclJUTFRleHRQbHVnaW4gPSAocnRsVGV4dFBsdWdpbjoge2FwcGx5QXJhYmljU2hhcGluZzogRnVuY3Rpb24sIHByb2Nlc3NCaWRpcmVjdGlvbmFsVGV4dDogRnVuY3Rpb24sIHByb2Nlc3NTdHlsZWRCaWRpcmVjdGlvbmFsVGV4dD86IEZ1bmN0aW9ufSkgPT4ge1xuICAgICAgICAgICAgaWYgKGdsb2JhbFJUTFRleHRQbHVnaW4uaXNQYXJzZWQoKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUlRMIHRleHQgcGx1Z2luIGFscmVhZHkgcmVnaXN0ZXJlZC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGdsb2JhbFJUTFRleHRQbHVnaW5bJ2FwcGx5QXJhYmljU2hhcGluZyddID0gcnRsVGV4dFBsdWdpbi5hcHBseUFyYWJpY1NoYXBpbmc7XG4gICAgICAgICAgICBnbG9iYWxSVExUZXh0UGx1Z2luWydwcm9jZXNzQmlkaXJlY3Rpb25hbFRleHQnXSA9IHJ0bFRleHRQbHVnaW4ucHJvY2Vzc0JpZGlyZWN0aW9uYWxUZXh0O1xuICAgICAgICAgICAgZ2xvYmFsUlRMVGV4dFBsdWdpblsncHJvY2Vzc1N0eWxlZEJpZGlyZWN0aW9uYWxUZXh0J10gPSBydGxUZXh0UGx1Z2luLnByb2Nlc3NTdHlsZWRCaWRpcmVjdGlvbmFsVGV4dDtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBjbGVhckNhY2hlcyhtYXBJZDogc3RyaW5nLCB1bnVzZWQ6IG1peGVkLCBjYWxsYmFjazogV29ya2VyVGlsZUNhbGxiYWNrKSB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLmxheWVySW5kZXhlc1ttYXBJZF07XG4gICAgICAgIGRlbGV0ZSB0aGlzLmF2YWlsYWJsZUltYWdlc1ttYXBJZF07XG4gICAgICAgIGRlbGV0ZSB0aGlzLndvcmtlclNvdXJjZXNbbWFwSWRdO1xuICAgICAgICBkZWxldGUgdGhpcy5kZW1Xb3JrZXJTb3VyY2VzW21hcElkXTtcbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICB9XG5cbiAgICBjaGVja0lmUmVhZHkobWFwSUQ6IHN0cmluZywgdW51c2VkOiBtaXhlZCwgY2FsbGJhY2s6IFdvcmtlclRpbGVDYWxsYmFjaykge1xuICAgICAgICAvLyBub29wLCB1c2VkIHRvIGNoZWNrIGlmIGEgd29ya2VyIGlzIGZ1bGx5IHNldCB1cCBhbmQgcmVhZHkgdG8gcmVjZWl2ZSBtZXNzYWdlc1xuICAgICAgICBjYWxsYmFjaygpO1xuICAgIH1cblxuICAgIHNldFJlZmVycmVyKG1hcElEOiBzdHJpbmcsIHJlZmVycmVyOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5yZWZlcnJlciA9IHJlZmVycmVyO1xuICAgIH1cblxuICAgIHNwcml0ZUxvYWRlZChtYXBJZDogc3RyaW5nLCBib29sOiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMuaXNTcHJpdGVMb2FkZWRbbWFwSWRdID0gYm9vbDtcbiAgICAgICAgZm9yIChjb25zdCB3b3JrZXJTb3VyY2UgaW4gdGhpcy53b3JrZXJTb3VyY2VzW21hcElkXSkge1xuICAgICAgICAgICAgY29uc3Qgd3MgPSB0aGlzLndvcmtlclNvdXJjZXNbbWFwSWRdW3dvcmtlclNvdXJjZV07XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHNvdXJjZSBpbiB3cykge1xuICAgICAgICAgICAgICAgIGlmICh3c1tzb3VyY2VdIGluc3RhbmNlb2YgVmVjdG9yVGlsZVdvcmtlclNvdXJjZSkge1xuICAgICAgICAgICAgICAgICAgICB3c1tzb3VyY2VdLmlzU3ByaXRlTG9hZGVkID0gYm9vbDtcbiAgICAgICAgICAgICAgICAgICAgd3Nbc291cmNlXS5maXJlKG5ldyBFdmVudCgnaXNTcHJpdGVMb2FkZWQnKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0SW1hZ2VzKG1hcElkOiBzdHJpbmcsIGltYWdlczogQXJyYXk8c3RyaW5nPiwgY2FsbGJhY2s6IFdvcmtlclRpbGVDYWxsYmFjaykge1xuICAgICAgICB0aGlzLmF2YWlsYWJsZUltYWdlc1ttYXBJZF0gPSBpbWFnZXM7XG4gICAgICAgIGZvciAoY29uc3Qgd29ya2VyU291cmNlIGluIHRoaXMud29ya2VyU291cmNlc1ttYXBJZF0pIHtcbiAgICAgICAgICAgIGNvbnN0IHdzID0gdGhpcy53b3JrZXJTb3VyY2VzW21hcElkXVt3b3JrZXJTb3VyY2VdO1xuICAgICAgICAgICAgZm9yIChjb25zdCBzb3VyY2UgaW4gd3MpIHtcbiAgICAgICAgICAgICAgICB3c1tzb3VyY2VdLmF2YWlsYWJsZUltYWdlcyA9IGltYWdlcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjYWxsYmFjaygpO1xuICAgIH1cblxuICAgIGVuYWJsZVRlcnJhaW4obWFwSWQ6IHN0cmluZywgZW5hYmxlOiBib29sZWFuLCBjYWxsYmFjazogV29ya2VyVGlsZUNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMudGVycmFpbiA9IGVuYWJsZTtcbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICB9XG5cbiAgICBzZXRQcm9qZWN0aW9uKG1hcElkOiBzdHJpbmcsIGNvbmZpZzogUHJvamVjdGlvblNwZWNpZmljYXRpb24pIHtcbiAgICAgICAgdGhpcy5wcm9qZWN0aW9uc1ttYXBJZF0gPSBnZXRQcm9qZWN0aW9uKGNvbmZpZyk7XG4gICAgfVxuXG4gICAgc2V0TGF5ZXJzKG1hcElkOiBzdHJpbmcsIGxheWVyczogQXJyYXk8TGF5ZXJTcGVjaWZpY2F0aW9uPiwgY2FsbGJhY2s6IFdvcmtlclRpbGVDYWxsYmFjaykge1xuICAgICAgICB0aGlzLmdldExheWVySW5kZXgobWFwSWQpLnJlcGxhY2UobGF5ZXJzKTtcbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICB9XG5cbiAgICB1cGRhdGVMYXllcnMobWFwSWQ6IHN0cmluZywgcGFyYW1zOiB7bGF5ZXJzOiBBcnJheTxMYXllclNwZWNpZmljYXRpb24+LCByZW1vdmVkSWRzOiBBcnJheTxzdHJpbmc+fSwgY2FsbGJhY2s6IFdvcmtlclRpbGVDYWxsYmFjaykge1xuICAgICAgICB0aGlzLmdldExheWVySW5kZXgobWFwSWQpLnVwZGF0ZShwYXJhbXMubGF5ZXJzLCBwYXJhbXMucmVtb3ZlZElkcyk7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgfVxuXG4gICAgbG9hZFRpbGUobWFwSWQ6IHN0cmluZywgcGFyYW1zOiBXb3JrZXJUaWxlUGFyYW1ldGVycyAmIHt0eXBlOiBzdHJpbmd9LCBjYWxsYmFjazogV29ya2VyVGlsZUNhbGxiYWNrKSB7XG4gICAgICAgIGFzc2VydChwYXJhbXMudHlwZSk7XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgY29uc3QgcCA9IHRoaXMuZW5hYmxlVGVycmFpbiA/IGV4dGVuZCh7ZW5hYmxlVGVycmFpbjogdGhpcy50ZXJyYWlufSwgcGFyYW1zKSA6IHBhcmFtcztcbiAgICAgICAgcC5wcm9qZWN0aW9uID0gdGhpcy5wcm9qZWN0aW9uc1ttYXBJZF0gfHwgdGhpcy5kZWZhdWx0UHJvamVjdGlvbjtcbiAgICAgICAgdGhpcy5nZXRXb3JrZXJTb3VyY2UobWFwSWQsIHBhcmFtcy50eXBlLCBwYXJhbXMuc291cmNlKS5sb2FkVGlsZShwLCBjYWxsYmFjayk7XG4gICAgfVxuXG4gICAgbG9hZERFTVRpbGUobWFwSWQ6IHN0cmluZywgcGFyYW1zOiBXb3JrZXJERU1UaWxlUGFyYW1ldGVycywgY2FsbGJhY2s6IFdvcmtlckRFTVRpbGVDYWxsYmFjaykge1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIGNvbnN0IHAgPSB0aGlzLmVuYWJsZVRlcnJhaW4gPyBleHRlbmQoe2J1aWxkUXVhZFRyZWU6IHRoaXMudGVycmFpbn0sIHBhcmFtcykgOiBwYXJhbXM7XG4gICAgICAgIHRoaXMuZ2V0REVNV29ya2VyU291cmNlKG1hcElkLCBwYXJhbXMuc291cmNlKS5sb2FkVGlsZShwLCBjYWxsYmFjayk7XG4gICAgfVxuXG4gICAgcmVsb2FkVGlsZShtYXBJZDogc3RyaW5nLCBwYXJhbXM6IFdvcmtlclRpbGVQYXJhbWV0ZXJzICYge3R5cGU6IHN0cmluZ30sIGNhbGxiYWNrOiBXb3JrZXJUaWxlQ2FsbGJhY2spIHtcbiAgICAgICAgYXNzZXJ0KHBhcmFtcy50eXBlKTtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICBjb25zdCBwID0gdGhpcy5lbmFibGVUZXJyYWluID8gZXh0ZW5kKHtlbmFibGVUZXJyYWluOiB0aGlzLnRlcnJhaW59LCBwYXJhbXMpIDogcGFyYW1zO1xuICAgICAgICBwLnByb2plY3Rpb24gPSB0aGlzLnByb2plY3Rpb25zW21hcElkXSB8fCB0aGlzLmRlZmF1bHRQcm9qZWN0aW9uO1xuICAgICAgICB0aGlzLmdldFdvcmtlclNvdXJjZShtYXBJZCwgcGFyYW1zLnR5cGUsIHBhcmFtcy5zb3VyY2UpLnJlbG9hZFRpbGUocCwgY2FsbGJhY2spO1xuICAgIH1cblxuICAgIGFib3J0VGlsZShtYXBJZDogc3RyaW5nLCBwYXJhbXM6IFRpbGVQYXJhbWV0ZXJzICYge3R5cGU6IHN0cmluZ30sIGNhbGxiYWNrOiBXb3JrZXJUaWxlQ2FsbGJhY2spIHtcbiAgICAgICAgYXNzZXJ0KHBhcmFtcy50eXBlKTtcbiAgICAgICAgdGhpcy5nZXRXb3JrZXJTb3VyY2UobWFwSWQsIHBhcmFtcy50eXBlLCBwYXJhbXMuc291cmNlKS5hYm9ydFRpbGUocGFyYW1zLCBjYWxsYmFjayk7XG4gICAgfVxuXG4gICAgcmVtb3ZlVGlsZShtYXBJZDogc3RyaW5nLCBwYXJhbXM6IFRpbGVQYXJhbWV0ZXJzICYge3R5cGU6IHN0cmluZ30sIGNhbGxiYWNrOiBXb3JrZXJUaWxlQ2FsbGJhY2spIHtcbiAgICAgICAgYXNzZXJ0KHBhcmFtcy50eXBlKTtcbiAgICAgICAgdGhpcy5nZXRXb3JrZXJTb3VyY2UobWFwSWQsIHBhcmFtcy50eXBlLCBwYXJhbXMuc291cmNlKS5yZW1vdmVUaWxlKHBhcmFtcywgY2FsbGJhY2spO1xuICAgIH1cblxuICAgIHJlbW92ZVNvdXJjZShtYXBJZDogc3RyaW5nLCBwYXJhbXM6IHtzb3VyY2U6IHN0cmluZ30gJiB7dHlwZTogc3RyaW5nfSwgY2FsbGJhY2s6IFdvcmtlclRpbGVDYWxsYmFjaykge1xuICAgICAgICBhc3NlcnQocGFyYW1zLnR5cGUpO1xuICAgICAgICBhc3NlcnQocGFyYW1zLnNvdXJjZSk7XG5cbiAgICAgICAgaWYgKCF0aGlzLndvcmtlclNvdXJjZXNbbWFwSWRdIHx8XG4gICAgICAgICAgICAhdGhpcy53b3JrZXJTb3VyY2VzW21hcElkXVtwYXJhbXMudHlwZV0gfHxcbiAgICAgICAgICAgICF0aGlzLndvcmtlclNvdXJjZXNbbWFwSWRdW3BhcmFtcy50eXBlXVtwYXJhbXMuc291cmNlXSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgd29ya2VyID0gdGhpcy53b3JrZXJTb3VyY2VzW21hcElkXVtwYXJhbXMudHlwZV1bcGFyYW1zLnNvdXJjZV07XG4gICAgICAgIGRlbGV0ZSB0aGlzLndvcmtlclNvdXJjZXNbbWFwSWRdW3BhcmFtcy50eXBlXVtwYXJhbXMuc291cmNlXTtcblxuICAgICAgICBpZiAod29ya2VyLnJlbW92ZVNvdXJjZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB3b3JrZXIucmVtb3ZlU291cmNlKHBhcmFtcywgY2FsbGJhY2spO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIExvYWQgYSB7QGxpbmsgV29ya2VyU291cmNlfSBzY3JpcHQgYXQgcGFyYW1zLnVybC4gIFRoZSBzY3JpcHQgaXMgcnVuXG4gICAgICogKHVzaW5nIGltcG9ydFNjcmlwdHMpIHdpdGggYHJlZ2lzdGVyV29ya2VyU291cmNlYCBpbiBzY29wZSwgd2hpY2ggaXMgYVxuICAgICAqIGZ1bmN0aW9uIHRha2luZyBgKG5hbWUsIHdvcmtlclNvdXJjZU9iamVjdClgLlxuICAgICAqICBAcHJpdmF0ZVxuICAgICAqL1xuICAgIGxvYWRXb3JrZXJTb3VyY2UobWFwOiBzdHJpbmcsIHBhcmFtczogeyB1cmw6IHN0cmluZyB9LCBjYWxsYmFjazogQ2FsbGJhY2s8dm9pZD4pIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuc2VsZi5pbXBvcnRTY3JpcHRzKHBhcmFtcy51cmwpO1xuICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY2FsbGJhY2soZS50b1N0cmluZygpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN5bmNSVExQbHVnaW5TdGF0ZShtYXA6IHN0cmluZywgc3RhdGU6IFBsdWdpblN0YXRlLCBjYWxsYmFjazogQ2FsbGJhY2s8Ym9vbGVhbj4pIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGdsb2JhbFJUTFRleHRQbHVnaW4uc2V0U3RhdGUoc3RhdGUpO1xuICAgICAgICAgICAgY29uc3QgcGx1Z2luVVJMID0gZ2xvYmFsUlRMVGV4dFBsdWdpbi5nZXRQbHVnaW5VUkwoKTtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBnbG9iYWxSVExUZXh0UGx1Z2luLmlzTG9hZGVkKCkgJiZcbiAgICAgICAgICAgICAgICAhZ2xvYmFsUlRMVGV4dFBsdWdpbi5pc1BhcnNlZCgpICYmXG4gICAgICAgICAgICAgICAgcGx1Z2luVVJMICE9IG51bGwgLy8gTm90IHBvc3NpYmxlIHdoZW4gYGlzTG9hZGVkYCBpcyB0cnVlLCBidXQga2VlcHMgZmxvdyBoYXBweVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZWxmLmltcG9ydFNjcmlwdHMocGx1Z2luVVJMKTtcbiAgICAgICAgICAgICAgICBjb25zdCBjb21wbGV0ZSA9IGdsb2JhbFJUTFRleHRQbHVnaW4uaXNQYXJzZWQoKTtcbiAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IGNvbXBsZXRlID8gdW5kZWZpbmVkIDogbmV3IEVycm9yKGBSVEwgVGV4dCBQbHVnaW4gZmFpbGVkIHRvIGltcG9ydCBzY3JpcHRzIGZyb20gJHtwbHVnaW5VUkx9YCk7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IsIGNvbXBsZXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY2FsbGJhY2soZS50b1N0cmluZygpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldEF2YWlsYWJsZUltYWdlcyhtYXBJZDogc3RyaW5nKTogQXJyYXk8c3RyaW5nPiB7XG4gICAgICAgIGxldCBhdmFpbGFibGVJbWFnZXMgPSB0aGlzLmF2YWlsYWJsZUltYWdlc1ttYXBJZF07XG5cbiAgICAgICAgaWYgKCFhdmFpbGFibGVJbWFnZXMpIHtcbiAgICAgICAgICAgIGF2YWlsYWJsZUltYWdlcyA9IFtdO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGF2YWlsYWJsZUltYWdlcztcbiAgICB9XG5cbiAgICBnZXRMYXllckluZGV4KG1hcElkOiBzdHJpbmcpOiBTdHlsZUxheWVySW5kZXgge1xuICAgICAgICBsZXQgbGF5ZXJJbmRleGVzID0gdGhpcy5sYXllckluZGV4ZXNbbWFwSWRdO1xuICAgICAgICBpZiAoIWxheWVySW5kZXhlcykge1xuICAgICAgICAgICAgbGF5ZXJJbmRleGVzID0gdGhpcy5sYXllckluZGV4ZXNbbWFwSWRdID0gbmV3IFN0eWxlTGF5ZXJJbmRleCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBsYXllckluZGV4ZXM7XG4gICAgfVxuXG4gICAgZ2V0V29ya2VyU291cmNlKG1hcElkOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgc291cmNlOiBzdHJpbmcpOiBXb3JrZXJTb3VyY2Uge1xuICAgICAgICBpZiAoIXRoaXMud29ya2VyU291cmNlc1ttYXBJZF0pXG4gICAgICAgICAgICB0aGlzLndvcmtlclNvdXJjZXNbbWFwSWRdID0ge307XG4gICAgICAgIGlmICghdGhpcy53b3JrZXJTb3VyY2VzW21hcElkXVt0eXBlXSlcbiAgICAgICAgICAgIHRoaXMud29ya2VyU291cmNlc1ttYXBJZF1bdHlwZV0gPSB7fTtcblxuICAgICAgICBpZiAoIXRoaXMud29ya2VyU291cmNlc1ttYXBJZF1bdHlwZV1bc291cmNlXSkge1xuICAgICAgICAgICAgLy8gdXNlIGEgd3JhcHBlZCBhY3RvciBzbyB0aGF0IHdlIGNhbiBhdHRhY2ggYSB0YXJnZXQgbWFwSWQgcGFyYW1cbiAgICAgICAgICAgIC8vIHRvIGFueSBtZXNzYWdlcyBpbnZva2VkIGJ5IHRoZSBXb3JrZXJTb3VyY2VcbiAgICAgICAgICAgIGNvbnN0IGFjdG9yID0ge1xuICAgICAgICAgICAgICAgIHNlbmQ6ICh0eXBlOiBzdHJpbmcsIGRhdGE6IG1peGVkLCBjYWxsYmFjazogYW55LCBfOiBhbnksIG11c3RRdWV1ZTogYm9vbGVhbiwgbWV0YWRhdGE6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFjdG9yLnNlbmQodHlwZSwgZGF0YSwgY2FsbGJhY2ssIG1hcElkLCBtdXN0UXVldWUsIG1ldGFkYXRhKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHNjaGVkdWxlcjogdGhpcy5hY3Rvci5zY2hlZHVsZXJcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLndvcmtlclNvdXJjZXNbbWFwSWRdW3R5cGVdW3NvdXJjZV0gPSBuZXcgKHRoaXMud29ya2VyU291cmNlVHlwZXNbdHlwZV06IGFueSkoKGFjdG9yOiBhbnkpLCB0aGlzLmdldExheWVySW5kZXgobWFwSWQpLCB0aGlzLmdldEF2YWlsYWJsZUltYWdlcyhtYXBJZCksIHRoaXMuaXNTcHJpdGVMb2FkZWRbbWFwSWRdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLndvcmtlclNvdXJjZXNbbWFwSWRdW3R5cGVdW3NvdXJjZV07XG4gICAgfVxuXG4gICAgZ2V0REVNV29ya2VyU291cmNlKG1hcElkOiBzdHJpbmcsIHNvdXJjZTogc3RyaW5nKTogUmFzdGVyREVNVGlsZVdvcmtlclNvdXJjZSB7XG4gICAgICAgIGlmICghdGhpcy5kZW1Xb3JrZXJTb3VyY2VzW21hcElkXSlcbiAgICAgICAgICAgIHRoaXMuZGVtV29ya2VyU291cmNlc1ttYXBJZF0gPSB7fTtcblxuICAgICAgICBpZiAoIXRoaXMuZGVtV29ya2VyU291cmNlc1ttYXBJZF1bc291cmNlXSkge1xuICAgICAgICAgICAgdGhpcy5kZW1Xb3JrZXJTb3VyY2VzW21hcElkXVtzb3VyY2VdID0gbmV3IFJhc3RlckRFTVRpbGVXb3JrZXJTb3VyY2UoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLmRlbVdvcmtlclNvdXJjZXNbbWFwSWRdW3NvdXJjZV07XG4gICAgfVxuXG4gICAgZW5mb3JjZUNhY2hlU2l6ZUxpbWl0KG1hcElkOiBzdHJpbmcsIGxpbWl0OiBudW1iZXIpIHtcbiAgICAgICAgZW5mb3JjZUNhY2hlU2l6ZUxpbWl0KGxpbWl0KTtcbiAgICB9XG5cbiAgICBnZXRXb3JrZXJQZXJmb3JtYW5jZU1ldHJpY3MobWFwSWQ6IHN0cmluZywgcGFyYW1zOiBhbnksIGNhbGxiYWNrOiAoZXJyb3I6ID9FcnJvciwgcmVzdWx0OiA/T2JqZWN0KSA9PiB2b2lkKSB7XG4gICAgICAgIGNhbGxiYWNrKHVuZGVmaW5lZCwgUGVyZm9ybWFuY2VVdGlscy5nZXRXb3JrZXJQZXJmb3JtYW5jZU1ldHJpY3MoKSk7XG4gICAgfVxufVxuXG4vKiBnbG9iYWwgc2VsZiwgV29ya2VyR2xvYmFsU2NvcGUgKi9cbmlmICh0eXBlb2YgV29ya2VyR2xvYmFsU2NvcGUgIT09ICd1bmRlZmluZWQnICYmXG4gICAgdHlwZW9mIHNlbGYgIT09ICd1bmRlZmluZWQnICYmXG4gICAgc2VsZiBpbnN0YW5jZW9mIFdvcmtlckdsb2JhbFNjb3BlKSB7XG4gICAgLy8gJEZsb3dGaXhNZVtwcm9wLW1pc3NpbmddXG4gICAgc2VsZi53b3JrZXIgPSBuZXcgV29ya2VyKHNlbGYpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLnN1cHBvcnRlZCA9IGlzU3VwcG9ydGVkO1xuZXhwb3J0cy5ub3RTdXBwb3J0ZWRSZWFzb24gPSBub3RTdXBwb3J0ZWRSZWFzb247XG5cbi8qKlxuICogVGVzdCB3aGV0aGVyIHRoZSBjdXJyZW50IGJyb3dzZXIgc3VwcG9ydHMgTWFwYm94IEdMIEpTXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5mYWlsSWZNYWpvclBlcmZvcm1hbmNlQ2F2ZWF0PWZhbHNlXSBSZXR1cm4gYGZhbHNlYFxuICogICBpZiB0aGUgcGVyZm9ybWFuY2Ugb2YgTWFwYm94IEdMIEpTIHdvdWxkIGJlIGRyYW1hdGljYWxseSB3b3JzZSB0aGFuXG4gKiAgIGV4cGVjdGVkIChpLmUuIGEgc29mdHdhcmUgcmVuZGVyZXIgaXMgd291bGQgYmUgdXNlZClcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIGlzU3VwcG9ydGVkKG9wdGlvbnMpIHtcbiAgICByZXR1cm4gIW5vdFN1cHBvcnRlZFJlYXNvbihvcHRpb25zKTtcbn1cblxuZnVuY3Rpb24gbm90U3VwcG9ydGVkUmVhc29uKG9wdGlvbnMpIHtcbiAgICBpZiAoIWlzQnJvd3NlcigpKSByZXR1cm4gJ25vdCBhIGJyb3dzZXInO1xuICAgIGlmICghaXNBcnJheVN1cHBvcnRlZCgpKSByZXR1cm4gJ2luc3VmZmljZW50IEFycmF5IHN1cHBvcnQnO1xuICAgIGlmICghaXNGdW5jdGlvblN1cHBvcnRlZCgpKSByZXR1cm4gJ2luc3VmZmljaWVudCBGdW5jdGlvbiBzdXBwb3J0JztcbiAgICBpZiAoIWlzT2JqZWN0U3VwcG9ydGVkKCkpIHJldHVybiAnaW5zdWZmaWNpZW50IE9iamVjdCBzdXBwb3J0JztcbiAgICBpZiAoIWlzSlNPTlN1cHBvcnRlZCgpKSByZXR1cm4gJ2luc3VmZmljaWVudCBKU09OIHN1cHBvcnQnO1xuICAgIGlmICghaXNXb3JrZXJTdXBwb3J0ZWQoKSkgcmV0dXJuICdpbnN1ZmZpY2llbnQgd29ya2VyIHN1cHBvcnQnO1xuICAgIGlmICghaXNVaW50OENsYW1wZWRBcnJheVN1cHBvcnRlZCgpKSByZXR1cm4gJ2luc3VmZmljaWVudCBVaW50OENsYW1wZWRBcnJheSBzdXBwb3J0JztcbiAgICBpZiAoIWlzQXJyYXlCdWZmZXJTdXBwb3J0ZWQoKSkgcmV0dXJuICdpbnN1ZmZpY2llbnQgQXJyYXlCdWZmZXIgc3VwcG9ydCc7XG4gICAgaWYgKCFpc0NhbnZhc0dldEltYWdlRGF0YVN1cHBvcnRlZCgpKSByZXR1cm4gJ2luc3VmZmljaWVudCBDYW52YXMvZ2V0SW1hZ2VEYXRhIHN1cHBvcnQnO1xuICAgIGlmICghaXNXZWJHTFN1cHBvcnRlZENhY2hlZChvcHRpb25zICYmIG9wdGlvbnMuZmFpbElmTWFqb3JQZXJmb3JtYW5jZUNhdmVhdCkpIHJldHVybiAnaW5zdWZmaWNpZW50IFdlYkdMIHN1cHBvcnQnO1xuICAgIGlmICghaXNOb3RJRSgpKSByZXR1cm4gJ2luc3VmZmljaWVudCBFQ01BU2NyaXB0IDYgc3VwcG9ydCc7XG59XG5cbmZ1bmN0aW9uIGlzQnJvd3NlcigpIHtcbiAgICByZXR1cm4gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJztcbn1cblxuZnVuY3Rpb24gaXNBcnJheVN1cHBvcnRlZCgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgICBBcnJheS5wcm90b3R5cGUgJiZcbiAgICAgICAgQXJyYXkucHJvdG90eXBlLmV2ZXJ5ICYmXG4gICAgICAgIEFycmF5LnByb3RvdHlwZS5maWx0ZXIgJiZcbiAgICAgICAgQXJyYXkucHJvdG90eXBlLmZvckVhY2ggJiZcbiAgICAgICAgQXJyYXkucHJvdG90eXBlLmluZGV4T2YgJiZcbiAgICAgICAgQXJyYXkucHJvdG90eXBlLmxhc3RJbmRleE9mICYmXG4gICAgICAgIEFycmF5LnByb3RvdHlwZS5tYXAgJiZcbiAgICAgICAgQXJyYXkucHJvdG90eXBlLnNvbWUgJiZcbiAgICAgICAgQXJyYXkucHJvdG90eXBlLnJlZHVjZSAmJlxuICAgICAgICBBcnJheS5wcm90b3R5cGUucmVkdWNlUmlnaHQgJiZcbiAgICAgICAgQXJyYXkuaXNBcnJheVxuICAgICk7XG59XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb25TdXBwb3J0ZWQoKSB7XG4gICAgcmV0dXJuIEZ1bmN0aW9uLnByb3RvdHlwZSAmJiBGdW5jdGlvbi5wcm90b3R5cGUuYmluZDtcbn1cblxuZnVuY3Rpb24gaXNPYmplY3RTdXBwb3J0ZWQoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgICAgT2JqZWN0LmtleXMgJiZcbiAgICAgICAgT2JqZWN0LmNyZWF0ZSAmJlxuICAgICAgICBPYmplY3QuZ2V0UHJvdG90eXBlT2YgJiZcbiAgICAgICAgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMgJiZcbiAgICAgICAgT2JqZWN0LmlzU2VhbGVkICYmXG4gICAgICAgIE9iamVjdC5pc0Zyb3plbiAmJlxuICAgICAgICBPYmplY3QuaXNFeHRlbnNpYmxlICYmXG4gICAgICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgJiZcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5ICYmXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzICYmXG4gICAgICAgIE9iamVjdC5zZWFsICYmXG4gICAgICAgIE9iamVjdC5mcmVlemUgJiZcbiAgICAgICAgT2JqZWN0LnByZXZlbnRFeHRlbnNpb25zXG4gICAgKTtcbn1cblxuZnVuY3Rpb24gaXNKU09OU3VwcG9ydGVkKCkge1xuICAgIHJldHVybiAnSlNPTicgaW4gd2luZG93ICYmICdwYXJzZScgaW4gSlNPTiAmJiAnc3RyaW5naWZ5JyBpbiBKU09OO1xufVxuXG5mdW5jdGlvbiBpc1dvcmtlclN1cHBvcnRlZCgpIHtcbiAgICBpZiAoISgnV29ya2VyJyBpbiB3aW5kb3cgJiYgJ0Jsb2InIGluIHdpbmRvdyAmJiAnVVJMJyBpbiB3aW5kb3cpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB2YXIgYmxvYiA9IG5ldyBCbG9iKFsnJ10sIHsgdHlwZTogJ3RleHQvamF2YXNjcmlwdCcgfSk7XG4gICAgdmFyIHdvcmtlclVSTCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgdmFyIHN1cHBvcnRlZDtcbiAgICB2YXIgd29ya2VyO1xuXG4gICAgdHJ5IHtcbiAgICAgICAgd29ya2VyID0gbmV3IFdvcmtlcih3b3JrZXJVUkwpO1xuICAgICAgICBzdXBwb3J0ZWQgPSB0cnVlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgc3VwcG9ydGVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKHdvcmtlcikge1xuICAgICAgICB3b3JrZXIudGVybWluYXRlKCk7XG4gICAgfVxuICAgIFVSTC5yZXZva2VPYmplY3RVUkwod29ya2VyVVJMKTtcblxuICAgIHJldHVybiBzdXBwb3J0ZWQ7XG59XG5cbi8vIElFMTEgb25seSBzdXBwb3J0cyBgVWludDhDbGFtcGVkQXJyYXlgIGFzIG9mIHZlcnNpb25cbi8vIFtLQjI5Mjk0MzddKGh0dHBzOi8vc3VwcG9ydC5taWNyb3NvZnQuY29tL2VuLXVzL2tiLzI5Mjk0MzcpXG5mdW5jdGlvbiBpc1VpbnQ4Q2xhbXBlZEFycmF5U3VwcG9ydGVkKCkge1xuICAgIHJldHVybiAnVWludDhDbGFtcGVkQXJyYXknIGluIHdpbmRvdztcbn1cblxuLy8gaHR0cHM6Ly9naXRodWIuY29tL21hcGJveC9tYXBib3gtZ2wtc3VwcG9ydGVkL2lzc3Vlcy8xOVxuZnVuY3Rpb24gaXNBcnJheUJ1ZmZlclN1cHBvcnRlZCgpIHtcbiAgICByZXR1cm4gQXJyYXlCdWZmZXIuaXNWaWV3O1xufVxuXG4vLyBTb21lIGJyb3dzZXJzIG9yIGJyb3dzZXIgZXh0ZW5zaW9ucyBibG9jayBhY2Nlc3MgdG8gY2FudmFzIGRhdGEgdG8gcHJldmVudCBmaW5nZXJwcmludGluZy5cbi8vIE1hcGJveCBHTCB1c2VzIHRoaXMgQVBJIHRvIGxvYWQgc3ByaXRlcyBhbmQgaW1hZ2VzIGluIGdlbmVyYWwuXG5mdW5jdGlvbiBpc0NhbnZhc0dldEltYWdlRGF0YVN1cHBvcnRlZCgpIHtcbiAgICB2YXIgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgY2FudmFzLndpZHRoID0gY2FudmFzLmhlaWdodCA9IDE7XG4gICAgdmFyIGNvbnRleHQgPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICBpZiAoIWNvbnRleHQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB2YXIgaW1hZ2VEYXRhID0gY29udGV4dC5nZXRJbWFnZURhdGEoMCwgMCwgMSwgMSk7XG4gICAgcmV0dXJuIGltYWdlRGF0YSAmJiBpbWFnZURhdGEud2lkdGggPT09IGNhbnZhcy53aWR0aDtcbn1cblxudmFyIGlzV2ViR0xTdXBwb3J0ZWRDYWNoZSA9IHt9O1xuZnVuY3Rpb24gaXNXZWJHTFN1cHBvcnRlZENhY2hlZChmYWlsSWZNYWpvclBlcmZvcm1hbmNlQ2F2ZWF0KSB7XG5cbiAgICBpZiAoaXNXZWJHTFN1cHBvcnRlZENhY2hlW2ZhaWxJZk1ham9yUGVyZm9ybWFuY2VDYXZlYXRdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaXNXZWJHTFN1cHBvcnRlZENhY2hlW2ZhaWxJZk1ham9yUGVyZm9ybWFuY2VDYXZlYXRdID0gaXNXZWJHTFN1cHBvcnRlZChmYWlsSWZNYWpvclBlcmZvcm1hbmNlQ2F2ZWF0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gaXNXZWJHTFN1cHBvcnRlZENhY2hlW2ZhaWxJZk1ham9yUGVyZm9ybWFuY2VDYXZlYXRdO1xufVxuXG5pc1N1cHBvcnRlZC53ZWJHTENvbnRleHRBdHRyaWJ1dGVzID0ge1xuICAgIGFudGlhbGlhczogZmFsc2UsXG4gICAgYWxwaGE6IHRydWUsXG4gICAgc3RlbmNpbDogdHJ1ZSxcbiAgICBkZXB0aDogdHJ1ZVxufTtcblxuZnVuY3Rpb24gZ2V0V2ViR0xDb250ZXh0KGZhaWxJZk1ham9yUGVyZm9ybWFuY2VDYXZlYXQpIHtcbiAgICB2YXIgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG5cbiAgICB2YXIgYXR0cmlidXRlcyA9IE9iamVjdC5jcmVhdGUoaXNTdXBwb3J0ZWQud2ViR0xDb250ZXh0QXR0cmlidXRlcyk7XG4gICAgYXR0cmlidXRlcy5mYWlsSWZNYWpvclBlcmZvcm1hbmNlQ2F2ZWF0ID0gZmFpbElmTWFqb3JQZXJmb3JtYW5jZUNhdmVhdDtcblxuICAgIHJldHVybiAoXG4gICAgICAgIGNhbnZhcy5nZXRDb250ZXh0KCd3ZWJnbCcsIGF0dHJpYnV0ZXMpIHx8XG4gICAgICAgIGNhbnZhcy5nZXRDb250ZXh0KCdleHBlcmltZW50YWwtd2ViZ2wnLCBhdHRyaWJ1dGVzKVxuICAgICk7XG59XG5cbmZ1bmN0aW9uIGlzV2ViR0xTdXBwb3J0ZWQoZmFpbElmTWFqb3JQZXJmb3JtYW5jZUNhdmVhdCkge1xuICAgIHZhciBnbCA9IGdldFdlYkdMQ29udGV4dChmYWlsSWZNYWpvclBlcmZvcm1hbmNlQ2F2ZWF0KTtcbiAgICBpZiAoIWdsKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBUcnkgY29tcGlsaW5nIGEgc2hhZGVyIGFuZCBnZXQgaXRzIGNvbXBpbGUgc3RhdHVzLiBTb21lIGJyb3dzZXJzIGxpa2UgQnJhdmUgYmxvY2sgdGhpcyBBUElcbiAgICAvLyB0byBwcmV2ZW50IGZpbmdlcnByaW50aW5nLiBVbmZvcnR1bmF0ZWx5LCB0aGlzIGFsc28gbWVhbnMgdGhhdCBNYXBib3ggR0wgd29uJ3Qgd29yay5cbiAgICB2YXIgc2hhZGVyO1xuICAgIHRyeSB7XG4gICAgICAgIHNoYWRlciA9IGdsLmNyZWF0ZVNoYWRlcihnbC5WRVJURVhfU0hBREVSKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIHNvbWUgb2xkZXIgYnJvd3NlcnMgdGhyb3cgYW4gZXhjZXB0aW9uIHRoYXQgYGNyZWF0ZVNoYWRlcmAgaXMgbm90IGRlZmluZWRcbiAgICAgICAgLy8gc28gaGFuZGxlIHRoaXMgc2VwYXJhdGVseSBmcm9tIHRoZSBjYXNlIHdoZXJlIGJyb3dzZXJzIGJsb2NrIGBjcmVhdGVTaGFkZXJgXG4gICAgICAgIC8vIGZvciBzZWN1cml0eSByZWFzb25zXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoIXNoYWRlciB8fCBnbC5pc0NvbnRleHRMb3N0KCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBnbC5zaGFkZXJTb3VyY2Uoc2hhZGVyLCAndm9pZCBtYWluKCkge30nKTtcbiAgICBnbC5jb21waWxlU2hhZGVyKHNoYWRlcik7XG4gICAgcmV0dXJuIGdsLmdldFNoYWRlclBhcmFtZXRlcihzaGFkZXIsIGdsLkNPTVBJTEVfU1RBVFVTKSA9PT0gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gaXNOb3RJRSgpIHtcbiAgICByZXR1cm4gIWRvY3VtZW50LmRvY3VtZW50TW9kZTtcbn1cbiIsIi8vIEBmbG93IHN0cmljdFxuXG5pbXBvcnQgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5cbmltcG9ydCB3aW5kb3cgZnJvbSAnLi93aW5kb3cuanMnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuXG4vLyByZWZpbmUgdGhlIHJldHVybiB0eXBlIGJhc2VkIG9uIHRhZ05hbWUsIGUuZy4gJ2J1dHRvbicgLT4gSFRNTEJ1dHRvbkVsZW1lbnRcbi8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGU8VDogc3RyaW5nPih0YWdOYW1lOiBULCBjbGFzc05hbWU6ID9zdHJpbmcsIGNvbnRhaW5lcj86IEhUTUxFbGVtZW50KTogJENhbGw8dHlwZW9mIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQsIFQ+IHtcbiAgICBjb25zdCBlbCA9IHdpbmRvdy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KHRhZ05hbWUpO1xuICAgIGlmIChjbGFzc05hbWUgIT09IHVuZGVmaW5lZCkgZWwuY2xhc3NOYW1lID0gY2xhc3NOYW1lO1xuICAgIGlmIChjb250YWluZXIpIGNvbnRhaW5lci5hcHBlbmRDaGlsZChlbCk7XG4gICAgcmV0dXJuIGVsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlU1ZHKHRhZ05hbWU6IHN0cmluZywgYXR0cmlidXRlczoge1tzdHJpbmddOiBzdHJpbmcgfCBudW1iZXJ9LCBjb250YWluZXI/OiBFbGVtZW50KTogRWxlbWVudCB7XG4gICAgY29uc3QgZWwgPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsIHRhZ05hbWUpO1xuICAgIGZvciAoY29uc3QgbmFtZSBvZiBPYmplY3Qua2V5cyhhdHRyaWJ1dGVzKSkge1xuICAgICAgICBlbC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBuYW1lLCBhdHRyaWJ1dGVzW25hbWVdKTtcbiAgICB9XG4gICAgaWYgKGNvbnRhaW5lcikgY29udGFpbmVyLmFwcGVuZENoaWxkKGVsKTtcbiAgICByZXR1cm4gZWw7XG59XG5cbmNvbnN0IGRvY1N0eWxlID0gd2luZG93LmRvY3VtZW50ICYmIHdpbmRvdy5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGU7XG5jb25zdCBzZWxlY3RQcm9wID0gZG9jU3R5bGUgJiYgZG9jU3R5bGUudXNlclNlbGVjdCAhPT0gdW5kZWZpbmVkID8gJ3VzZXJTZWxlY3QnIDogJ1dlYmtpdFVzZXJTZWxlY3QnO1xubGV0IHVzZXJTZWxlY3Q7XG5cbmV4cG9ydCBmdW5jdGlvbiBkaXNhYmxlRHJhZygpIHtcbiAgICBpZiAoZG9jU3R5bGUgJiYgc2VsZWN0UHJvcCkge1xuICAgICAgICB1c2VyU2VsZWN0ID0gZG9jU3R5bGVbc2VsZWN0UHJvcF07XG4gICAgICAgIGRvY1N0eWxlW3NlbGVjdFByb3BdID0gJ25vbmUnO1xuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGVuYWJsZURyYWcoKSB7XG4gICAgaWYgKGRvY1N0eWxlICYmIHNlbGVjdFByb3ApIHtcbiAgICAgICAgZG9jU3R5bGVbc2VsZWN0UHJvcF0gPSB1c2VyU2VsZWN0O1xuICAgIH1cbn1cblxuLy8gU3VwcHJlc3MgdGhlIG5leHQgY2xpY2ssIGJ1dCBvbmx5IGlmIGl0J3MgaW1tZWRpYXRlLlxuZnVuY3Rpb24gc3VwcHJlc3NDbGlja0xpc3RlbmVyKGU6IEV2ZW50KSB7XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgc3VwcHJlc3NDbGlja0xpc3RlbmVyLCB0cnVlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHN1cHByZXNzQ2xpY2soKSB7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgc3VwcHJlc3NDbGlja0xpc3RlbmVyLCB0cnVlKTtcbiAgICB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHN1cHByZXNzQ2xpY2tMaXN0ZW5lciwgdHJ1ZSk7XG4gICAgfSwgMCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtb3VzZVBvcyhlbDogSFRNTEVsZW1lbnQsIGU6IE1vdXNlRXZlbnQgfCBXaGVlbEV2ZW50KTogUG9pbnQge1xuICAgIGNvbnN0IHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICByZXR1cm4gZ2V0U2NhbGVkUG9pbnQoZWwsIHJlY3QsIGUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdG91Y2hQb3MoZWw6IEhUTUxFbGVtZW50LCB0b3VjaGVzOiBUb3VjaExpc3QpOiBBcnJheTxQb2ludD4ge1xuICAgIGNvbnN0IHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxcbiAgICAgICAgcG9pbnRzID0gW107XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRvdWNoZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcG9pbnRzLnB1c2goZ2V0U2NhbGVkUG9pbnQoZWwsIHJlY3QsIHRvdWNoZXNbaV0pKTtcbiAgICB9XG4gICAgcmV0dXJuIHBvaW50cztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1vdXNlQnV0dG9uKGU6IE1vdXNlRXZlbnQpOiBudW1iZXIge1xuICAgIGFzc2VydChlLnR5cGUgPT09ICdtb3VzZWRvd24nIHx8IGUudHlwZSA9PT0gJ21vdXNldXAnKTtcbiAgICBpZiAodHlwZW9mIHdpbmRvdy5JbnN0YWxsVHJpZ2dlciAhPT0gJ3VuZGVmaW5lZCcgJiYgZS5idXR0b24gPT09IDIgJiYgZS5jdHJsS2V5ICYmXG4gICAgICAgIHdpbmRvdy5uYXZpZ2F0b3IucGxhdGZvcm0udG9VcHBlckNhc2UoKS5pbmRleE9mKCdNQUMnKSA+PSAwKSB7XG4gICAgICAgIC8vIEZpeCBmb3IgaHR0cHM6Ly9naXRodWIuY29tL21hcGJveC9tYXBib3gtZ2wtanMvaXNzdWVzLzMxMzE6XG4gICAgICAgIC8vIEZpcmVmb3ggKGRldGVjdGVkIGJ5IEluc3RhbGxUcmlnZ2VyKSBvbiBNYWMgZGV0ZXJtaW5lcyBlLmJ1dHRvbiA9IDIgd2hlblxuICAgICAgICAvLyB1c2luZyBDb250cm9sICsgbGVmdCBjbGlja1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgcmV0dXJuIGUuYnV0dG9uO1xufVxuXG5mdW5jdGlvbiBnZXRTY2FsZWRQb2ludChlbDogSFRNTEVsZW1lbnQsIHJlY3Q6IENsaWVudFJlY3QsIGU6IE1vdXNlRXZlbnQgfCBXaGVlbEV2ZW50IHwgVG91Y2gpIHtcbiAgICAvLyBVbnRpbCB3ZSBnZXQgc3VwcG9ydCBmb3IgcG9pbnRlciBldmVudHMgKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9Qb2ludGVyRXZlbnQpXG4gICAgLy8gd2UgdXNlIHRoaXMgZGlydHkgdHJpY2sgd2hpY2ggd291bGQgbm90IHdvcmsgZm9yIHRoZSBjYXNlIG9mIHJvdGF0ZWQgdHJhbnNmb3JtcywgYnV0IHdvcmtzIHdlbGwgZm9yXG4gICAgLy8gdGhlIGNhc2Ugb2Ygc2ltcGxlIHNjYWxpbmcuXG4gICAgLy8gTm90ZTogYGVsLm9mZnNldFdpZHRoID09PSByZWN0LndpZHRoYCBlbGltaW5hdGVzIHRoZSBgMC8wYCBjYXNlLlxuICAgIGNvbnN0IHNjYWxpbmcgPSBlbC5vZmZzZXRXaWR0aCA9PT0gcmVjdC53aWR0aCA/IDEgOiBlbC5vZmZzZXRXaWR0aCAvIHJlY3Qud2lkdGg7XG4gICAgcmV0dXJuIG5ldyBQb2ludChcbiAgICAgICAgKGUuY2xpZW50WCAtIHJlY3QubGVmdCkgKiBzY2FsaW5nLFxuICAgICAgICAoZS5jbGllbnRZIC0gcmVjdC50b3ApICogc2NhbGluZ1xuICAgICk7XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge2dldEpTT04sIGdldEltYWdlLCBSZXNvdXJjZVR5cGV9IGZyb20gJy4uL3V0aWwvYWpheC5qcyc7XG5cbmltcG9ydCBicm93c2VyIGZyb20gJy4uL3V0aWwvYnJvd3Nlci5qcyc7XG5pbXBvcnQge1JHQkFJbWFnZX0gZnJvbSAnLi4vdXRpbC9pbWFnZS5qcyc7XG5cbmltcG9ydCB0eXBlIHtTdHlsZUltYWdlfSBmcm9tICcuL3N0eWxlX2ltYWdlLmpzJztcbmltcG9ydCB0eXBlIHtSZXF1ZXN0TWFuYWdlcn0gZnJvbSAnLi4vdXRpbC9tYXBib3guanMnO1xuaW1wb3J0IHR5cGUge0NhbGxiYWNrfSBmcm9tICcuLi90eXBlcy9jYWxsYmFjay5qcyc7XG5pbXBvcnQgdHlwZSB7Q2FuY2VsYWJsZX0gZnJvbSAnLi4vdHlwZXMvY2FuY2VsYWJsZS5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKGJhc2VVUkw6IHN0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdE1hbmFnZXI6IFJlcXVlc3RNYW5hZ2VyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjazogQ2FsbGJhY2s8e1tfOiBzdHJpbmddOiBTdHlsZUltYWdlfT4pOiBDYW5jZWxhYmxlIHtcbiAgICBsZXQganNvbjogYW55LCBpbWFnZSwgZXJyb3I7XG4gICAgY29uc3QgZm9ybWF0ID0gYnJvd3Nlci5kZXZpY2VQaXhlbFJhdGlvID4gMSA/ICdAMngnIDogJyc7XG5cbiAgICBsZXQganNvblJlcXVlc3Q6ID9DYW5jZWxhYmxlID0gZ2V0SlNPTihyZXF1ZXN0TWFuYWdlci50cmFuc2Zvcm1SZXF1ZXN0KHJlcXVlc3RNYW5hZ2VyLm5vcm1hbGl6ZVNwcml0ZVVSTChiYXNlVVJMLCBmb3JtYXQsICcuanNvbicpLCBSZXNvdXJjZVR5cGUuU3ByaXRlSlNPTiksIChlcnI6ID9FcnJvciwgZGF0YTogP09iamVjdCkgPT4ge1xuICAgICAgICBqc29uUmVxdWVzdCA9IG51bGw7XG4gICAgICAgIGlmICghZXJyb3IpIHtcbiAgICAgICAgICAgIGVycm9yID0gZXJyO1xuICAgICAgICAgICAganNvbiA9IGRhdGE7XG4gICAgICAgICAgICBtYXliZUNvbXBsZXRlKCk7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIGxldCBpbWFnZVJlcXVlc3Q6ID9DYW5jZWxhYmxlID0gZ2V0SW1hZ2UocmVxdWVzdE1hbmFnZXIudHJhbnNmb3JtUmVxdWVzdChyZXF1ZXN0TWFuYWdlci5ub3JtYWxpemVTcHJpdGVVUkwoYmFzZVVSTCwgZm9ybWF0LCAnLnBuZycpLCBSZXNvdXJjZVR5cGUuU3ByaXRlSW1hZ2UpLCAoZXJyLCBpbWcpID0+IHtcbiAgICAgICAgaW1hZ2VSZXF1ZXN0ID0gbnVsbDtcbiAgICAgICAgaWYgKCFlcnJvcikge1xuICAgICAgICAgICAgZXJyb3IgPSBlcnI7XG4gICAgICAgICAgICBpbWFnZSA9IGltZztcbiAgICAgICAgICAgIG1heWJlQ29tcGxldGUoKTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgZnVuY3Rpb24gbWF5YmVDb21wbGV0ZSgpIHtcbiAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICBjYWxsYmFjayhlcnJvcik7XG4gICAgICAgIH0gZWxzZSBpZiAoanNvbiAmJiBpbWFnZSkge1xuICAgICAgICAgICAgY29uc3QgaW1hZ2VEYXRhID0gYnJvd3Nlci5nZXRJbWFnZURhdGEoaW1hZ2UpO1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0ge307XG5cbiAgICAgICAgICAgIGZvciAoY29uc3QgaWQgaW4ganNvbikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHt3aWR0aCwgaGVpZ2h0LCB4LCB5LCBzZGYsIHBpeGVsUmF0aW8sIHN0cmV0Y2hYLCBzdHJldGNoWSwgY29udGVudH0gPSBqc29uW2lkXTtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gbmV3IFJHQkFJbWFnZSh7d2lkdGgsIGhlaWdodH0pO1xuICAgICAgICAgICAgICAgIFJHQkFJbWFnZS5jb3B5KGltYWdlRGF0YSwgZGF0YSwge3gsIHl9LCB7eDogMCwgeTogMH0sIHt3aWR0aCwgaGVpZ2h0fSk7XG4gICAgICAgICAgICAgICAgcmVzdWx0W2lkXSA9IHtkYXRhLCBwaXhlbFJhdGlvLCBzZGYsIHN0cmV0Y2hYLCBzdHJldGNoWSwgY29udGVudH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIHJlc3VsdCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBjYW5jZWwoKSB7XG4gICAgICAgICAgICBpZiAoanNvblJlcXVlc3QpIHtcbiAgICAgICAgICAgICAgICBqc29uUmVxdWVzdC5jYW5jZWwoKTtcbiAgICAgICAgICAgICAgICBqc29uUmVxdWVzdCA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaW1hZ2VSZXF1ZXN0KSB7XG4gICAgICAgICAgICAgICAgaW1hZ2VSZXF1ZXN0LmNhbmNlbCgpO1xuICAgICAgICAgICAgICAgIGltYWdlUmVxdWVzdCA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtSR0JBSW1hZ2V9IGZyb20gJy4uL3V0aWwvaW1hZ2UuanMnO1xuXG5pbXBvcnQgdHlwZSBNYXAgZnJvbSAnLi4vdWkvbWFwLmpzJztcblxuZXhwb3J0IHR5cGUgU3R5bGVJbWFnZURhdGEgPSB7XG4gICAgZGF0YTogUkdCQUltYWdlLFxuICAgIHZlcnNpb246IG51bWJlcixcbiAgICBoYXNSZW5kZXJDYWxsYmFjaz86IGJvb2xlYW4sXG4gICAgdXNlckltYWdlPzogU3R5bGVJbWFnZUludGVyZmFjZVxufTtcblxuZXhwb3J0IHR5cGUgU3R5bGVJbWFnZU1ldGFkYXRhID0ge1xuICAgIHBpeGVsUmF0aW86IG51bWJlcixcbiAgICBzZGY6IGJvb2xlYW4sXG4gICAgc3RyZXRjaFg/OiBBcnJheTxbbnVtYmVyLCBudW1iZXJdPixcbiAgICBzdHJldGNoWT86IEFycmF5PFtudW1iZXIsIG51bWJlcl0+LFxuICAgIGNvbnRlbnQ/OiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXVxufTtcblxuZXhwb3J0IHR5cGUgU3R5bGVJbWFnZSA9IFN0eWxlSW1hZ2VEYXRhICYgU3R5bGVJbWFnZU1ldGFkYXRhO1xuXG5leHBvcnQgdHlwZSBTdHlsZUltYWdlSW50ZXJmYWNlID0ge1xuICAgIHdpZHRoOiBudW1iZXIsXG4gICAgaGVpZ2h0OiBudW1iZXIsXG4gICAgZGF0YTogVWludDhBcnJheSB8IFVpbnQ4Q2xhbXBlZEFycmF5LFxuICAgIHJlbmRlcj86ICgpID0+IGJvb2xlYW4sXG4gICAgb25BZGQ/OiAobWFwOiBNYXAsIGlkOiBzdHJpbmcpID0+IHZvaWQsXG4gICAgb25SZW1vdmU/OiAoKSA9PiB2b2lkXG59O1xuXG5leHBvcnQgZnVuY3Rpb24gcmVuZGVyU3R5bGVJbWFnZShpbWFnZTogU3R5bGVJbWFnZSk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHt1c2VySW1hZ2V9ID0gaW1hZ2U7XG4gICAgaWYgKHVzZXJJbWFnZSAmJiB1c2VySW1hZ2UucmVuZGVyKSB7XG4gICAgICAgIGNvbnN0IHVwZGF0ZWQgPSB1c2VySW1hZ2UucmVuZGVyKCk7XG4gICAgICAgIGlmICh1cGRhdGVkKSB7XG4gICAgICAgICAgICBpbWFnZS5kYXRhLnJlcGxhY2UobmV3IFVpbnQ4QXJyYXkodXNlckltYWdlLmRhdGEuYnVmZmVyKSk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogSW50ZXJmYWNlIGZvciBkeW5hbWljYWxseSBnZW5lcmF0ZWQgc3R5bGUgaW1hZ2VzLiBUaGlzIGlzIGEgc3BlY2lmaWNhdGlvbiBmb3JcbiAqIGltcGxlbWVudGVycyB0byBtb2RlbDogaXQgaXMgbm90IGFuIGV4cG9ydGVkIG1ldGhvZCBvciBjbGFzcy5cbiAqXG4gKiBJbWFnZXMgaW1wbGVtZW50aW5nIHRoaXMgaW50ZXJmYWNlIGNhbiBiZSByZWRyYXduIGZvciBldmVyeSBmcmFtZS4gVGhleSBjYW4gYmUgdXNlZCB0byBhbmltYXRlXG4gKiBpY29ucyBhbmQgcGF0dGVybnMgb3IgbWFrZSB0aGVtIHJlc3BvbmQgdG8gdXNlciBpbnB1dC4gU3R5bGUgaW1hZ2VzIGNhbiBpbXBsZW1lbnQgYVxuICoge0BsaW5rIFN0eWxlSW1hZ2VJbnRlcmZhY2UjcmVuZGVyfSBtZXRob2QuIFRoZSBtZXRob2QgaXMgY2FsbGVkIGV2ZXJ5IGZyYW1lIGFuZFxuICogY2FuIGJlIHVzZWQgdG8gdXBkYXRlIHRoZSBpbWFnZS5cbiAqXG4gKiBAaW50ZXJmYWNlIFN0eWxlSW1hZ2VJbnRlcmZhY2VcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB3aWR0aCBXaWR0aCBpbiBwaXhlbHMuXG4gKiBAcHJvcGVydHkge251bWJlcn0gaGVpZ2h0IEhlaWdodCBpbiBwaXhlbHMuXG4gKiBAcHJvcGVydHkge1VpbnQ4QXJyYXkgfCBVaW50OENsYW1wZWRBcnJheX0gZGF0YSBCeXRlIGFycmF5IHJlcHJlc2VudGluZyB0aGUgaW1hZ2UuIFRvIGVuc3VyZSBzcGFjZSBmb3IgYWxsIGZvdXIgY2hhbm5lbHMgaW4gYW4gUkdCQSBjb2xvciwgc2l6ZSBtdXN0IGJlIHdpZHRoIMOXIGhlaWdodCDDlyA0LlxuICpcbiAqIEBzZWUgW0V4YW1wbGU6IEFkZCBhbiBhbmltYXRlZCBpY29uIHRvIHRoZSBtYXAuXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9hZGQtaW1hZ2UtYW5pbWF0ZWQvKVxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBmbGFzaGluZ1NxdWFyZSA9IHtcbiAqICAgICB3aWR0aDogNjQsXG4gKiAgICAgaGVpZ2h0OiA2NCxcbiAqICAgICBkYXRhOiBuZXcgVWludDhBcnJheSg2NCAqIDY0ICogNCksXG4gKlxuICogICAgIG9uQWRkKG1hcCkge1xuICogICAgICAgICB0aGlzLm1hcCA9IG1hcDtcbiAqICAgICB9LFxuICpcbiAqICAgICByZW5kZXIoKSB7XG4gKiAgICAgICAgIC8vIGtlZXAgcmVwYWludGluZyB3aGlsZSB0aGUgaWNvbiBpcyBvbiB0aGUgbWFwXG4gKiAgICAgICAgIHRoaXMubWFwLnRyaWdnZXJSZXBhaW50KCk7XG4gKlxuICogICAgICAgICAvLyBhbHRlcm5hdGUgYmV0d2VlbiBibGFjayBhbmQgd2hpdGUgYmFzZWQgb24gdGhlIHRpbWVcbiAqICAgICAgICAgY29uc3QgdmFsdWUgPSBNYXRoLnJvdW5kKERhdGUubm93KCkgLyAxMDAwKSAlIDIgPT09IDAgID8gMjU1IDogMDtcbiAqXG4gKiAgICAgICAgIC8vIGNoZWNrIGlmIGltYWdlIG5lZWRzIHRvIGJlIGNoYW5nZWRcbiAqICAgICAgICAgaWYgKHZhbHVlICE9PSB0aGlzLnByZXZpb3VzVmFsdWUpIHtcbiAqICAgICAgICAgICAgIHRoaXMucHJldmlvdXNWYWx1ZSA9IHZhbHVlO1xuICpcbiAqICAgICAgICAgICAgIGNvbnN0IGJ5dGVzUGVyUGl4ZWwgPSA0O1xuICogICAgICAgICAgICAgZm9yIChsZXQgeCA9IDA7IHggPCB0aGlzLndpZHRoOyB4KyspIHtcbiAqICAgICAgICAgICAgICAgICBmb3IgKGxldCB5ID0gMDsgeSA8IHRoaXMuaGVpZ2h0OyB5KyspIHtcbiAqICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2Zmc2V0ID0gKHkgKiB0aGlzLndpZHRoICsgeCkgKiBieXRlc1BlclBpeGVsO1xuICogICAgICAgICAgICAgICAgICAgICB0aGlzLmRhdGFbb2Zmc2V0ICsgMF0gPSB2YWx1ZTtcbiAqICAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXRhW29mZnNldCArIDFdID0gdmFsdWU7XG4gKiAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGF0YVtvZmZzZXQgKyAyXSA9IHZhbHVlO1xuICogICAgICAgICAgICAgICAgICAgICB0aGlzLmRhdGFbb2Zmc2V0ICsgM10gPSAyNTU7XG4gKiAgICAgICAgICAgICAgICAgfVxuICogICAgICAgICAgICAgfVxuICpcbiAqICAgICAgICAgICAgIC8vIHJldHVybiB0cnVlIHRvIGluZGljYXRlIHRoYXQgdGhlIGltYWdlIGNoYW5nZWRcbiAqICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICogICAgICAgICB9XG4gKiAgICAgfVxuICogfTtcbiAqXG4gKiBtYXAuYWRkSW1hZ2UoJ2ZsYXNoaW5nX3NxdWFyZScsIGZsYXNoaW5nU3F1YXJlKTtcbiAqL1xuXG4vKipcbiAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBvbmNlIGJlZm9yZSBldmVyeSBmcmFtZSB3aGVyZSB0aGUgaWNvbiB3aWxsIGJlIHVzZWQuXG4gKiBUaGUgbWV0aG9kIGNhbiBvcHRpb25hbGx5IHVwZGF0ZSB0aGUgaW1hZ2UncyBgZGF0YWAgbWVtYmVyIHdpdGggYSBuZXcgaW1hZ2UuXG4gKlxuICogSWYgdGhlIG1ldGhvZCB1cGRhdGVzIHRoZSBpbWFnZSBpdCBtdXN0IHJldHVybiBgdHJ1ZWAgdG8gY29tbWl0IHRoZSBjaGFuZ2UuXG4gKiBJZiB0aGUgbWV0aG9kIHJldHVybnMgYGZhbHNlYCBvciBub3RoaW5nIHRoZSBpbWFnZSBpcyBhc3N1bWVkIHRvIG5vdCBoYXZlIGNoYW5nZWQuXG4gKlxuICogSWYgdXBkYXRlcyBhcmUgaW5mcmVxdWVudCBpdCBtYXliZSBlYXNpZXIgdG8gdXNlIHtAbGluayBNYXAjdXBkYXRlSW1hZ2V9IHRvIHVwZGF0ZVxuICogdGhlIGltYWdlIGluc3RlYWQgb2YgaW1wbGVtZW50aW5nIHRoaXMgbWV0aG9kLlxuICpcbiAqIEBmdW5jdGlvblxuICogQG1lbWJlcm9mIFN0eWxlSW1hZ2VJbnRlcmZhY2VcbiAqIEBpbnN0YW5jZVxuICogQG5hbWUgcmVuZGVyXG4gKiBAcmV0dXJuIHtib29sZWFufSBgdHJ1ZWAgaWYgdGhpcyBtZXRob2QgdXBkYXRlZCB0aGUgaW1hZ2UuIGBmYWxzZWAgaWYgdGhlIGltYWdlIHdhcyBub3QgY2hhbmdlZC5cbiAqL1xuXG4vKipcbiAqIE9wdGlvbmFsIG1ldGhvZCBjYWxsZWQgd2hlbiB0aGUgbGF5ZXIgaGFzIGJlZW4gYWRkZWQgdG8gdGhlIE1hcCB3aXRoIHtAbGluayBNYXAjYWRkSW1hZ2V9LlxuICpcbiAqIEBmdW5jdGlvblxuICogQG1lbWJlcm9mIFN0eWxlSW1hZ2VJbnRlcmZhY2VcbiAqIEBpbnN0YW5jZVxuICogQG5hbWUgb25BZGRcbiAqIEBwYXJhbSB7TWFwfSBtYXAgVGhlIE1hcCB0aGlzIGN1c3RvbSBsYXllciB3YXMganVzdCBhZGRlZCB0by5cbiAqL1xuXG4vKipcbiAqIE9wdGlvbmFsIG1ldGhvZCBjYWxsZWQgd2hlbiB0aGUgaWNvbiBpcyByZW1vdmVkIGZyb20gdGhlIG1hcCB3aXRoIHtAbGluayBNYXAjcmVtb3ZlSW1hZ2V9LlxuICogVGhpcyBnaXZlcyB0aGUgaW1hZ2UgYSBjaGFuY2UgdG8gY2xlYW4gdXAgcmVzb3VyY2VzIGFuZCBldmVudCBsaXN0ZW5lcnMuXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAbWVtYmVyb2YgU3R5bGVJbWFnZUludGVyZmFjZVxuICogQGluc3RhbmNlXG4gKiBAbmFtZSBvblJlbW92ZVxuICovXG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgcG90cGFjayBmcm9tICdwb3RwYWNrJztcblxuaW1wb3J0IHtFdmVudCwgRXJyb3JFdmVudCwgRXZlbnRlZH0gZnJvbSAnLi4vdXRpbC9ldmVudGVkLmpzJztcbmltcG9ydCB7UkdCQUltYWdlfSBmcm9tICcuLi91dGlsL2ltYWdlLmpzJztcbmltcG9ydCB7SW1hZ2VQb3NpdGlvbn0gZnJvbSAnLi9pbWFnZV9hdGxhcy5qcyc7XG5pbXBvcnQgVGV4dHVyZSBmcm9tICcuL3RleHR1cmUuanMnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHtyZW5kZXJTdHlsZUltYWdlfSBmcm9tICcuLi9zdHlsZS9zdHlsZV9pbWFnZS5qcyc7XG5pbXBvcnQge3dhcm5PbmNlfSBmcm9tICcuLi91dGlsL3V0aWwuanMnO1xuXG5pbXBvcnQgdHlwZSB7U3R5bGVJbWFnZX0gZnJvbSAnLi4vc3R5bGUvc3R5bGVfaW1hZ2UuanMnO1xuaW1wb3J0IHR5cGUgQ29udGV4dCBmcm9tICcuLi9nbC9jb250ZXh0LmpzJztcbmltcG9ydCB0eXBlIHtCaW59IGZyb20gJ3BvdHBhY2snO1xuaW1wb3J0IHR5cGUge0NhbGxiYWNrfSBmcm9tICcuLi90eXBlcy9jYWxsYmFjay5qcyc7XG5pbXBvcnQgdHlwZSB7U2l6ZX0gZnJvbSAnLi4vdXRpbC9pbWFnZS5qcyc7XG5cbnR5cGUgUGF0dGVybiA9IHtcbiAgICBiaW46IEJpbixcbiAgICBwb3NpdGlvbjogSW1hZ2VQb3NpdGlvblxufTtcblxuLy8gV2hlbiBjb3BpZWQgaW50byB0aGUgYXRsYXMgdGV4dHVyZSwgaW1hZ2UgZGF0YSBpcyBwYWRkZWQgYnkgb25lIHBpeGVsIG9uIGVhY2ggc2lkZS4gSWNvblxuLy8gaW1hZ2VzIGFyZSBwYWRkZWQgd2l0aCBmdWxseSB0cmFuc3BhcmVudCBwaXhlbHMsIHdoaWxlIHBhdHRlcm4gaW1hZ2VzIGFyZSBwYWRkZWQgd2l0aCBhXG4vLyBjb3B5IG9mIHRoZSBpbWFnZSBkYXRhIHdyYXBwZWQgZnJvbSB0aGUgb3Bwb3NpdGUgc2lkZS4gSW4gYm90aCBjYXNlcywgdGhpcyBlbnN1cmVzIHRoZVxuLy8gY29ycmVjdCBiZWhhdmlvciBvZiBHTF9MSU5FQVIgdGV4dHVyZSBzYW1wbGluZyBtb2RlLlxuY29uc3QgcGFkZGluZyA9IDE7XG5cbi8qXG4gICAgSW1hZ2VNYW5hZ2VyIGRvZXMgdGhyZWUgdGhpbmdzOlxuXG4gICAgICAgIDEuIFRyYWNrcyByZXF1ZXN0cyBmb3IgaWNvbiBpbWFnZXMgZnJvbSB0aWxlIHdvcmtlcnMgYW5kIHNlbmRzIHJlc3BvbnNlcyB3aGVuIHRoZSByZXF1ZXN0cyBhcmUgZnVsZmlsbGVkLlxuICAgICAgICAyLiBCdWlsZHMgYSB0ZXh0dXJlIGF0bGFzIGZvciBwYXR0ZXJuIGltYWdlcy5cbiAgICAgICAgMy4gUmVyZW5kZXJzIHJlbmRlcmFibGUgaW1hZ2VzIG9uY2UgcGVyIGZyYW1lXG5cbiAgICBUaGVzZSBhcmUgZGlzcGFyYXRlIHJlc3BvbnNpYmlsaXRpZXMgYW5kIHNob3VsZCBldmVudHVhbGx5IGJlIGhhbmRsZWQgYnkgZGlmZmVyZW50IGNsYXNzZXMuIFdoZW4gd2UgaW1wbGVtZW50XG4gICAgZGF0YS1kcml2ZW4gc3VwcG9ydCBmb3IgYCotcGF0dGVybmAsIHdlJ2xsIGxpa2VseSB1c2UgcGVyLWJ1Y2tldCBwYXR0ZXJuIGF0bGFzZXMsIGFuZCB0aGF0IHdvdWxkIGJlIGEgZ29vZCB0aW1lXG4gICAgdG8gcmVmYWN0b3IgdGhpcy5cbiovXG5jbGFzcyBJbWFnZU1hbmFnZXIgZXh0ZW5kcyBFdmVudGVkIHtcbiAgICBpbWFnZXM6IHtbXzogc3RyaW5nXTogU3R5bGVJbWFnZX07XG4gICAgdXBkYXRlZEltYWdlczoge1tfOiBzdHJpbmddOiBib29sZWFufTtcbiAgICBjYWxsYmFja0Rpc3BhdGNoZWRUaGlzRnJhbWU6IHtbXzogc3RyaW5nXTogYm9vbGVhbn07XG4gICAgbG9hZGVkOiBib29sZWFuO1xuICAgIHJlcXVlc3RvcnM6IEFycmF5PHtpZHM6IEFycmF5PHN0cmluZz4sIGNhbGxiYWNrOiBDYWxsYmFjazx7W186IHN0cmluZ106IFN0eWxlSW1hZ2V9Pn0+O1xuXG4gICAgcGF0dGVybnM6IHtbXzogc3RyaW5nXTogUGF0dGVybn07XG4gICAgYXRsYXNJbWFnZTogUkdCQUltYWdlO1xuICAgIGF0bGFzVGV4dHVyZTogP1RleHR1cmU7XG4gICAgZGlydHk6IGJvb2xlYW47XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5pbWFnZXMgPSB7fTtcbiAgICAgICAgdGhpcy51cGRhdGVkSW1hZ2VzID0ge307XG4gICAgICAgIHRoaXMuY2FsbGJhY2tEaXNwYXRjaGVkVGhpc0ZyYW1lID0ge307XG4gICAgICAgIHRoaXMubG9hZGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMucmVxdWVzdG9ycyA9IFtdO1xuXG4gICAgICAgIHRoaXMucGF0dGVybnMgPSB7fTtcbiAgICAgICAgdGhpcy5hdGxhc0ltYWdlID0gbmV3IFJHQkFJbWFnZSh7d2lkdGg6IDEsIGhlaWdodDogMX0pO1xuICAgICAgICB0aGlzLmRpcnR5ID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpc0xvYWRlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubG9hZGVkO1xuICAgIH1cblxuICAgIHNldExvYWRlZChsb2FkZWQ6IGJvb2xlYW4pIHtcbiAgICAgICAgaWYgKHRoaXMubG9hZGVkID09PSBsb2FkZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubG9hZGVkID0gbG9hZGVkO1xuXG4gICAgICAgIGlmIChsb2FkZWQpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3Qge2lkcywgY2FsbGJhY2t9IG9mIHRoaXMucmVxdWVzdG9ycykge1xuICAgICAgICAgICAgICAgIHRoaXMuX25vdGlmeShpZHMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMucmVxdWVzdG9ycyA9IFtdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaGFzSW1hZ2UoaWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gISF0aGlzLmdldEltYWdlKGlkKTtcbiAgICB9XG5cbiAgICBnZXRJbWFnZShpZDogc3RyaW5nKTogP1N0eWxlSW1hZ2Uge1xuICAgICAgICByZXR1cm4gdGhpcy5pbWFnZXNbaWRdO1xuICAgIH1cblxuICAgIGFkZEltYWdlKGlkOiBzdHJpbmcsIGltYWdlOiBTdHlsZUltYWdlKSB7XG4gICAgICAgIGFzc2VydCghdGhpcy5pbWFnZXNbaWRdKTtcbiAgICAgICAgaWYgKHRoaXMuX3ZhbGlkYXRlKGlkLCBpbWFnZSkpIHtcbiAgICAgICAgICAgIHRoaXMuaW1hZ2VzW2lkXSA9IGltYWdlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX3ZhbGlkYXRlKGlkOiBzdHJpbmcsIGltYWdlOiBTdHlsZUltYWdlKTogYm9vbGVhbiB7XG4gICAgICAgIGxldCB2YWxpZCA9IHRydWU7XG4gICAgICAgIGlmICghdGhpcy5fdmFsaWRhdGVTdHJldGNoKGltYWdlLnN0cmV0Y2hYLCBpbWFnZS5kYXRhICYmIGltYWdlLmRhdGEud2lkdGgpKSB7XG4gICAgICAgICAgICB0aGlzLmZpcmUobmV3IEVycm9yRXZlbnQobmV3IEVycm9yKGBJbWFnZSBcIiR7aWR9XCIgaGFzIGludmFsaWQgXCJzdHJldGNoWFwiIHZhbHVlYCkpKTtcbiAgICAgICAgICAgIHZhbGlkID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLl92YWxpZGF0ZVN0cmV0Y2goaW1hZ2Uuc3RyZXRjaFksIGltYWdlLmRhdGEgJiYgaW1hZ2UuZGF0YS5oZWlnaHQpKSB7XG4gICAgICAgICAgICB0aGlzLmZpcmUobmV3IEVycm9yRXZlbnQobmV3IEVycm9yKGBJbWFnZSBcIiR7aWR9XCIgaGFzIGludmFsaWQgXCJzdHJldGNoWVwiIHZhbHVlYCkpKTtcbiAgICAgICAgICAgIHZhbGlkID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLl92YWxpZGF0ZUNvbnRlbnQoaW1hZ2UuY29udGVudCwgaW1hZ2UpKSB7XG4gICAgICAgICAgICB0aGlzLmZpcmUobmV3IEVycm9yRXZlbnQobmV3IEVycm9yKGBJbWFnZSBcIiR7aWR9XCIgaGFzIGludmFsaWQgXCJjb250ZW50XCIgdmFsdWVgKSkpO1xuICAgICAgICAgICAgdmFsaWQgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsaWQ7XG4gICAgfVxuXG4gICAgX3ZhbGlkYXRlU3RyZXRjaChzdHJldGNoOiA/QXJyYXk8W251bWJlciwgbnVtYmVyXT4gfCB2b2lkLCBzaXplOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKCFzdHJldGNoKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgbGV0IGxhc3QgPSAwO1xuICAgICAgICBmb3IgKGNvbnN0IHBhcnQgb2Ygc3RyZXRjaCkge1xuICAgICAgICAgICAgaWYgKHBhcnRbMF0gPCBsYXN0IHx8IHBhcnRbMV0gPCBwYXJ0WzBdIHx8IHNpemUgPCBwYXJ0WzFdKSByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICBsYXN0ID0gcGFydFsxXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBfdmFsaWRhdGVDb250ZW50KGNvbnRlbnQ6ID9bbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSB8IHZvaWQsIGltYWdlOiBTdHlsZUltYWdlKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICghY29udGVudCkgcmV0dXJuIHRydWU7XG4gICAgICAgIGlmIChjb250ZW50Lmxlbmd0aCAhPT0gNCkgcmV0dXJuIGZhbHNlO1xuICAgICAgICBpZiAoY29udGVudFswXSA8IDAgfHwgaW1hZ2UuZGF0YS53aWR0aCA8IGNvbnRlbnRbMF0pIHJldHVybiBmYWxzZTtcbiAgICAgICAgaWYgKGNvbnRlbnRbMV0gPCAwIHx8IGltYWdlLmRhdGEuaGVpZ2h0IDwgY29udGVudFsxXSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICBpZiAoY29udGVudFsyXSA8IDAgfHwgaW1hZ2UuZGF0YS53aWR0aCA8IGNvbnRlbnRbMl0pIHJldHVybiBmYWxzZTtcbiAgICAgICAgaWYgKGNvbnRlbnRbM10gPCAwIHx8IGltYWdlLmRhdGEuaGVpZ2h0IDwgY29udGVudFszXSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICBpZiAoY29udGVudFsyXSA8IGNvbnRlbnRbMF0pIHJldHVybiBmYWxzZTtcbiAgICAgICAgaWYgKGNvbnRlbnRbM10gPCBjb250ZW50WzFdKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHVwZGF0ZUltYWdlKGlkOiBzdHJpbmcsIGltYWdlOiBTdHlsZUltYWdlKSB7XG4gICAgICAgIGNvbnN0IG9sZEltYWdlID0gdGhpcy5pbWFnZXNbaWRdO1xuICAgICAgICBhc3NlcnQob2xkSW1hZ2UpO1xuICAgICAgICBhc3NlcnQob2xkSW1hZ2UuZGF0YS53aWR0aCA9PT0gaW1hZ2UuZGF0YS53aWR0aCk7XG4gICAgICAgIGFzc2VydChvbGRJbWFnZS5kYXRhLmhlaWdodCA9PT0gaW1hZ2UuZGF0YS5oZWlnaHQpO1xuICAgICAgICBpbWFnZS52ZXJzaW9uID0gb2xkSW1hZ2UudmVyc2lvbiArIDE7XG4gICAgICAgIHRoaXMuaW1hZ2VzW2lkXSA9IGltYWdlO1xuICAgICAgICB0aGlzLnVwZGF0ZWRJbWFnZXNbaWRdID0gdHJ1ZTtcbiAgICB9XG5cbiAgICByZW1vdmVJbWFnZShpZDogc3RyaW5nKSB7XG4gICAgICAgIGFzc2VydCh0aGlzLmltYWdlc1tpZF0pO1xuICAgICAgICBjb25zdCBpbWFnZSA9IHRoaXMuaW1hZ2VzW2lkXTtcbiAgICAgICAgZGVsZXRlIHRoaXMuaW1hZ2VzW2lkXTtcbiAgICAgICAgZGVsZXRlIHRoaXMucGF0dGVybnNbaWRdO1xuXG4gICAgICAgIGlmIChpbWFnZS51c2VySW1hZ2UgJiYgaW1hZ2UudXNlckltYWdlLm9uUmVtb3ZlKSB7XG4gICAgICAgICAgICBpbWFnZS51c2VySW1hZ2Uub25SZW1vdmUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGxpc3RJbWFnZXMoKTogQXJyYXk8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLmltYWdlcyk7XG4gICAgfVxuXG4gICAgZ2V0SW1hZ2VzKGlkczogQXJyYXk8c3RyaW5nPiwgY2FsbGJhY2s6IENhbGxiYWNrPHtbXzogc3RyaW5nXTogU3R5bGVJbWFnZX0+KSB7XG4gICAgICAgIC8vIElmIHRoZSBzcHJpdGUgaGFzIGJlZW4gbG9hZGVkLCBvciBpZiBhbGwgdGhlIGljb24gZGVwZW5kZW5jaWVzIGFyZSBhbHJlYWR5IHByZXNlbnRcbiAgICAgICAgLy8gKGkuZS4gaWYgdGhleSd2ZSBiZWVuIGFkZGVkIHZpYSBydW50aW1lIHN0eWxpbmcpLCB0aGVuIG5vdGlmeSB0aGUgcmVxdWVzdG9yIGltbWVkaWF0ZWx5LlxuICAgICAgICAvLyBPdGhlcndpc2UsIGRlbGF5IG5vdGlmaWNhdGlvbiB1bnRpbCB0aGUgc3ByaXRlIGlzIGxvYWRlZC4gQXQgdGhhdCBwb2ludCwgaWYgYW55IG9mIHRoZVxuICAgICAgICAvLyBkZXBlbmRlbmNpZXMgYXJlIHN0aWxsIHVuYXZhaWxhYmxlLCB3ZSdsbCBqdXN0IGFzc3VtZSB0aGV5IGFyZSBwZXJtYW5lbnRseSBtaXNzaW5nLlxuICAgICAgICBsZXQgaGFzQWxsRGVwZW5kZW5jaWVzID0gdHJ1ZTtcbiAgICAgICAgaWYgKCF0aGlzLmlzTG9hZGVkKCkpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgaWQgb2YgaWRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmltYWdlc1tpZF0pIHtcbiAgICAgICAgICAgICAgICAgICAgaGFzQWxsRGVwZW5kZW5jaWVzID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmlzTG9hZGVkKCkgfHwgaGFzQWxsRGVwZW5kZW5jaWVzKSB7XG4gICAgICAgICAgICB0aGlzLl9ub3RpZnkoaWRzLCBjYWxsYmFjayk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnJlcXVlc3RvcnMucHVzaCh7aWRzLCBjYWxsYmFja30pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX25vdGlmeShpZHM6IEFycmF5PHN0cmluZz4sIGNhbGxiYWNrOiBDYWxsYmFjazx7W186IHN0cmluZ106IFN0eWxlSW1hZ2V9Pikge1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IHt9O1xuXG4gICAgICAgIGZvciAoY29uc3QgaWQgb2YgaWRzKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuaW1hZ2VzW2lkXSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ3N0eWxlaW1hZ2VtaXNzaW5nJywge2lkfSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgaW1hZ2UgPSB0aGlzLmltYWdlc1tpZF07XG4gICAgICAgICAgICBpZiAoaW1hZ2UpIHtcbiAgICAgICAgICAgICAgICAvLyBDbG9uZSB0aGUgaW1hZ2Ugc28gdGhhdCBvdXIgb3duIGNvcHkgb2YgaXRzIEFycmF5QnVmZmVyIGRvZXNuJ3QgZ2V0IHRyYW5zZmVycmVkLlxuICAgICAgICAgICAgICAgIHJlc3BvbnNlW2lkXSA9IHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogaW1hZ2UuZGF0YS5jbG9uZSgpLFxuICAgICAgICAgICAgICAgICAgICBwaXhlbFJhdGlvOiBpbWFnZS5waXhlbFJhdGlvLFxuICAgICAgICAgICAgICAgICAgICBzZGY6IGltYWdlLnNkZixcbiAgICAgICAgICAgICAgICAgICAgdmVyc2lvbjogaW1hZ2UudmVyc2lvbixcbiAgICAgICAgICAgICAgICAgICAgc3RyZXRjaFg6IGltYWdlLnN0cmV0Y2hYLFxuICAgICAgICAgICAgICAgICAgICBzdHJldGNoWTogaW1hZ2Uuc3RyZXRjaFksXG4gICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ6IGltYWdlLmNvbnRlbnQsXG4gICAgICAgICAgICAgICAgICAgIGhhc1JlbmRlckNhbGxiYWNrOiBCb29sZWFuKGltYWdlLnVzZXJJbWFnZSAmJiBpbWFnZS51c2VySW1hZ2UucmVuZGVyKVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHdhcm5PbmNlKGBJbWFnZSBcIiR7aWR9XCIgY291bGQgbm90IGJlIGxvYWRlZC4gUGxlYXNlIG1ha2Ugc3VyZSB5b3UgaGF2ZSBhZGRlZCB0aGUgaW1hZ2Ugd2l0aCBtYXAuYWRkSW1hZ2UoKSBvciBhIFwic3ByaXRlXCIgcHJvcGVydHkgaW4geW91ciBzdHlsZS4gWW91IGNhbiBwcm92aWRlIG1pc3NpbmcgaW1hZ2VzIGJ5IGxpc3RlbmluZyBmb3IgdGhlIFwic3R5bGVpbWFnZW1pc3NpbmdcIiBtYXAgZXZlbnQuYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjYWxsYmFjayhudWxsLCByZXNwb25zZSk7XG4gICAgfVxuXG4gICAgLy8gUGF0dGVybiBzdHVmZlxuXG4gICAgZ2V0UGl4ZWxTaXplKCk6IFNpemUge1xuICAgICAgICBjb25zdCB7d2lkdGgsIGhlaWdodH0gPSB0aGlzLmF0bGFzSW1hZ2U7XG4gICAgICAgIHJldHVybiB7d2lkdGgsIGhlaWdodH07XG4gICAgfVxuXG4gICAgZ2V0UGF0dGVybihpZDogc3RyaW5nKTogP0ltYWdlUG9zaXRpb24ge1xuICAgICAgICBjb25zdCBwYXR0ZXJuID0gdGhpcy5wYXR0ZXJuc1tpZF07XG5cbiAgICAgICAgY29uc3QgaW1hZ2UgPSB0aGlzLmdldEltYWdlKGlkKTtcbiAgICAgICAgaWYgKCFpbWFnZSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGF0dGVybiAmJiBwYXR0ZXJuLnBvc2l0aW9uLnZlcnNpb24gPT09IGltYWdlLnZlcnNpb24pIHtcbiAgICAgICAgICAgIHJldHVybiBwYXR0ZXJuLnBvc2l0aW9uO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFwYXR0ZXJuKSB7XG4gICAgICAgICAgICBjb25zdCB3ID0gaW1hZ2UuZGF0YS53aWR0aCArIHBhZGRpbmcgKiAyO1xuICAgICAgICAgICAgY29uc3QgaCA9IGltYWdlLmRhdGEuaGVpZ2h0ICsgcGFkZGluZyAqIDI7XG4gICAgICAgICAgICBjb25zdCBiaW4gPSB7dywgaCwgeDogMCwgeTogMH07XG4gICAgICAgICAgICBjb25zdCBwb3NpdGlvbiA9IG5ldyBJbWFnZVBvc2l0aW9uKGJpbiwgaW1hZ2UpO1xuICAgICAgICAgICAgdGhpcy5wYXR0ZXJuc1tpZF0gPSB7YmluLCBwb3NpdGlvbn07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwYXR0ZXJuLnBvc2l0aW9uLnZlcnNpb24gPSBpbWFnZS52ZXJzaW9uO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fdXBkYXRlUGF0dGVybkF0bGFzKCk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMucGF0dGVybnNbaWRdLnBvc2l0aW9uO1xuICAgIH1cblxuICAgIGJpbmQoY29udGV4dDogQ29udGV4dCkge1xuICAgICAgICBjb25zdCBnbCA9IGNvbnRleHQuZ2w7XG4gICAgICAgIGlmICghdGhpcy5hdGxhc1RleHR1cmUpIHtcbiAgICAgICAgICAgIHRoaXMuYXRsYXNUZXh0dXJlID0gbmV3IFRleHR1cmUoY29udGV4dCwgdGhpcy5hdGxhc0ltYWdlLCBnbC5SR0JBKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmRpcnR5KSB7XG4gICAgICAgICAgICB0aGlzLmF0bGFzVGV4dHVyZS51cGRhdGUodGhpcy5hdGxhc0ltYWdlKTtcbiAgICAgICAgICAgIHRoaXMuZGlydHkgPSBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5hdGxhc1RleHR1cmUpIHJldHVybjsgLy8gRmxvdyBjYW4ndCBpbmZlciB0aGF0IGF0bGFzVGV4dHVyZSBpcyBkZWZpbmVkIGhlcmVcbiAgICAgICAgdGhpcy5hdGxhc1RleHR1cmUuYmluZChnbC5MSU5FQVIsIGdsLkNMQU1QX1RPX0VER0UpO1xuICAgIH1cblxuICAgIF91cGRhdGVQYXR0ZXJuQXRsYXMoKSB7XG4gICAgICAgIGNvbnN0IGJpbnMgPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBpZCBpbiB0aGlzLnBhdHRlcm5zKSB7XG4gICAgICAgICAgICBiaW5zLnB1c2godGhpcy5wYXR0ZXJuc1tpZF0uYmluKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHt3LCBofSA9IHBvdHBhY2soYmlucyk7XG5cbiAgICAgICAgY29uc3QgZHN0ID0gdGhpcy5hdGxhc0ltYWdlO1xuICAgICAgICBkc3QucmVzaXplKHt3aWR0aDogdyB8fCAxLCBoZWlnaHQ6IGggfHwgMX0pO1xuXG4gICAgICAgIGZvciAoY29uc3QgaWQgaW4gdGhpcy5wYXR0ZXJucykge1xuICAgICAgICAgICAgY29uc3Qge2Jpbn0gPSB0aGlzLnBhdHRlcm5zW2lkXTtcbiAgICAgICAgICAgIGNvbnN0IHggPSBiaW4ueCArIHBhZGRpbmc7XG4gICAgICAgICAgICBjb25zdCB5ID0gYmluLnkgKyBwYWRkaW5nO1xuICAgICAgICAgICAgY29uc3Qgc3JjID0gdGhpcy5pbWFnZXNbaWRdLmRhdGE7XG4gICAgICAgICAgICBjb25zdCB3ID0gc3JjLndpZHRoO1xuICAgICAgICAgICAgY29uc3QgaCA9IHNyYy5oZWlnaHQ7XG5cbiAgICAgICAgICAgIFJHQkFJbWFnZS5jb3B5KHNyYywgZHN0LCB7eDogMCwgeTogMH0sIHt4LCB5fSwge3dpZHRoOiB3LCBoZWlnaHQ6IGh9KTtcblxuICAgICAgICAgICAgLy8gQWRkIDEgcGl4ZWwgd3JhcHBlZCBwYWRkaW5nIG9uIGVhY2ggc2lkZSBvZiB0aGUgaW1hZ2UuXG4gICAgICAgICAgICBSR0JBSW1hZ2UuY29weShzcmMsIGRzdCwge3g6IDAsIHk6IGggLSAxfSwge3gsIHk6IHkgLSAxfSwge3dpZHRoOiB3LCBoZWlnaHQ6IDF9KTsgLy8gVFxuICAgICAgICAgICAgUkdCQUltYWdlLmNvcHkoc3JjLCBkc3QsIHt4OiAwLCB5OiAgICAgMH0sIHt4LCB5OiB5ICsgaH0sIHt3aWR0aDogdywgaGVpZ2h0OiAxfSk7IC8vIEJcbiAgICAgICAgICAgIFJHQkFJbWFnZS5jb3B5KHNyYywgZHN0LCB7eDogdyAtIDEsIHk6IDB9LCB7eDogeCAtIDEsIHl9LCB7d2lkdGg6IDEsIGhlaWdodDogaH0pOyAvLyBMXG4gICAgICAgICAgICBSR0JBSW1hZ2UuY29weShzcmMsIGRzdCwge3g6IDAsICAgICB5OiAwfSwge3g6IHggKyB3LCB5fSwge3dpZHRoOiAxLCBoZWlnaHQ6IGh9KTsgLy8gUlxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5kaXJ0eSA9IHRydWU7XG4gICAgfVxuXG4gICAgYmVnaW5GcmFtZSgpIHtcbiAgICAgICAgdGhpcy5jYWxsYmFja0Rpc3BhdGNoZWRUaGlzRnJhbWUgPSB7fTtcbiAgICB9XG5cbiAgICBkaXNwYXRjaFJlbmRlckNhbGxiYWNrcyhpZHM6IEFycmF5PHN0cmluZz4pIHtcbiAgICAgICAgZm9yIChjb25zdCBpZCBvZiBpZHMpIHtcblxuICAgICAgICAgICAgLy8gdGhlIGNhbGxiYWNrIGZvciB0aGUgaW1hZ2Ugd2FzIGFscmVhZHkgZGlzcGF0Y2hlZCBmb3IgYSBkaWZmZXJlbnQgZnJhbWVcbiAgICAgICAgICAgIGlmICh0aGlzLmNhbGxiYWNrRGlzcGF0Y2hlZFRoaXNGcmFtZVtpZF0pIGNvbnRpbnVlO1xuICAgICAgICAgICAgdGhpcy5jYWxsYmFja0Rpc3BhdGNoZWRUaGlzRnJhbWVbaWRdID0gdHJ1ZTtcblxuICAgICAgICAgICAgY29uc3QgaW1hZ2UgPSB0aGlzLmltYWdlc1tpZF07XG4gICAgICAgICAgICBhc3NlcnQoaW1hZ2UpO1xuXG4gICAgICAgICAgICBjb25zdCB1cGRhdGVkID0gcmVuZGVyU3R5bGVJbWFnZShpbWFnZSk7XG4gICAgICAgICAgICBpZiAodXBkYXRlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlSW1hZ2UoaWQsIGltYWdlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgSW1hZ2VNYW5hZ2VyO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHN0eWxlU3BlYyBmcm9tICcuLi9zdHlsZS1zcGVjL3JlZmVyZW5jZS9sYXRlc3QuanMnO1xuXG5pbXBvcnQge2VuZHNXaXRoLCBleHRlbmQsIGRlZ1RvUmFkfSBmcm9tICcuLi91dGlsL3V0aWwuanMnO1xuaW1wb3J0IHtFdmVudGVkfSBmcm9tICcuLi91dGlsL2V2ZW50ZWQuanMnO1xuaW1wb3J0IHtcbiAgICB2YWxpZGF0ZVN0eWxlLFxuICAgIHZhbGlkYXRlTGlnaHQsXG4gICAgZW1pdFZhbGlkYXRpb25FcnJvcnNcbn0gZnJvbSAnLi92YWxpZGF0ZV9zdHlsZS5qcyc7XG5pbXBvcnQgQ29sb3IgZnJvbSAnLi4vc3R5bGUtc3BlYy91dGlsL2NvbG9yLmpzJztcbmltcG9ydCB7bnVtYmVyIGFzIGludGVycG9sYXRlfSBmcm9tICcuLi9zdHlsZS1zcGVjL3V0aWwvaW50ZXJwb2xhdGUuanMnO1xuaW1wb3J0IHtQcm9wZXJ0aWVzLCBUcmFuc2l0aW9uYWJsZSwgVHJhbnNpdGlvbmluZywgUG9zc2libHlFdmFsdWF0ZWQsIERhdGFDb25zdGFudFByb3BlcnR5fSBmcm9tICcuL3Byb3BlcnRpZXMuanMnO1xuXG5pbXBvcnQgdHlwZSB7U3R5bGVQcm9wZXJ0eVNwZWNpZmljYXRpb259IGZyb20gJy4uL3N0eWxlLXNwZWMvc3R5bGUtc3BlYy5qcyc7XG5pbXBvcnQgdHlwZSBFdmFsdWF0aW9uUGFyYW1ldGVycyBmcm9tICcuL2V2YWx1YXRpb25fcGFyYW1ldGVycy5qcyc7XG5pbXBvcnQgdHlwZSB7U3R5bGVTZXR0ZXJPcHRpb25zfSBmcm9tICcuLi9zdHlsZS9zdHlsZS5qcyc7XG5pbXBvcnQgdHlwZSB7XG4gICAgUHJvcGVydHksXG4gICAgUHJvcGVydHlWYWx1ZSxcbiAgICBUcmFuc2l0aW9uUGFyYW1ldGVyc1xufSBmcm9tICcuL3Byb3BlcnRpZXMuanMnO1xuXG5pbXBvcnQgdHlwZSB7TGlnaHRTcGVjaWZpY2F0aW9ufSBmcm9tICcuLi9zdHlsZS1zcGVjL3R5cGVzLmpzJztcblxuZXhwb3J0IHR5cGUgTGlnaHRQb3NpdGlvbiA9IHtcbiAgICB4OiBudW1iZXIsXG4gICAgeTogbnVtYmVyLFxuICAgIHo6IG51bWJlcixcbiAgICBhemltdXRoYWw6IG51bWJlcixcbiAgICBwb2xhcjogbnVtYmVyLFxufTtcblxuLyoqXG4gKiBDb252ZXJ0cyBzcGhlcmljYWwgY29vcmRpbmF0ZXMgdG8gY2FydGVzaWFuIExpZ2h0UG9zaXRpb24gY29vcmRpbmF0ZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSBzcGhlcmljYWwgU3BoZXJpY2FsIGNvb3JkaW5hdGVzLCBpbiBbcmFkaWFsLCBhemltdXRoYWwsIHBvbGFyXVxuICogQHJldHVybiBMaWdodFBvc2l0aW9uIGNhcnRlc2lhbiBjb29yZGluYXRlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gc3BoZXJpY2FsVG9DYXJ0ZXNpYW4oW3IsIGF6aW11dGhhbCwgcG9sYXJdOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0pOiBMaWdodFBvc2l0aW9uIHtcbiAgICAvLyBXZSBhYnN0cmFjdCBcIm5vcnRoXCIvXCJ1cFwiIChjb21wYXNzLXdpc2UpIHRvIGJlIDDCsCB3aGVuIHJlYWxseSB0aGlzIGlzIDkwwrAgKM+ALzIpOlxuICAgIC8vIGNvcnJlY3QgZm9yIHRoYXQgaGVyZVxuICAgIGNvbnN0IGEgPSBkZWdUb1JhZChhemltdXRoYWwgKyA5MCksIHAgPSBkZWdUb1JhZChwb2xhcik7XG5cbiAgICByZXR1cm4ge1xuICAgICAgICB4OiByICogTWF0aC5jb3MoYSkgKiBNYXRoLnNpbihwKSxcbiAgICAgICAgeTogciAqIE1hdGguc2luKGEpICogTWF0aC5zaW4ocCksXG4gICAgICAgIHo6IHIgKiBNYXRoLmNvcyhwKSxcbiAgICAgICAgYXppbXV0aGFsLCBwb2xhclxuICAgIH07XG59XG5cbmNsYXNzIExpZ2h0UG9zaXRpb25Qcm9wZXJ0eSBpbXBsZW1lbnRzIFByb3BlcnR5PFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSwgTGlnaHRQb3NpdGlvbj4ge1xuICAgIHNwZWNpZmljYXRpb246IFN0eWxlUHJvcGVydHlTcGVjaWZpY2F0aW9uO1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuc3BlY2lmaWNhdGlvbiA9IHN0eWxlU3BlYy5saWdodC5wb3NpdGlvbjtcbiAgICB9XG5cbiAgICBwb3NzaWJseUV2YWx1YXRlKHZhbHVlOiBQcm9wZXJ0eVZhbHVlPFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSwgTGlnaHRQb3NpdGlvbj4sIHBhcmFtZXRlcnM6IEV2YWx1YXRpb25QYXJhbWV0ZXJzKTogTGlnaHRQb3NpdGlvbiB7XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgcmV0dXJuIHNwaGVyaWNhbFRvQ2FydGVzaWFuKHZhbHVlLmV4cHJlc3Npb24uZXZhbHVhdGUocGFyYW1ldGVycykpO1xuICAgIH1cblxuICAgIGludGVycG9sYXRlKGE6IExpZ2h0UG9zaXRpb24sIGI6IExpZ2h0UG9zaXRpb24sIHQ6IG51bWJlcik6IExpZ2h0UG9zaXRpb24ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogaW50ZXJwb2xhdGUoYS54LCBiLngsIHQpLFxuICAgICAgICAgICAgeTogaW50ZXJwb2xhdGUoYS55LCBiLnksIHQpLFxuICAgICAgICAgICAgejogaW50ZXJwb2xhdGUoYS56LCBiLnosIHQpLFxuICAgICAgICAgICAgYXppbXV0aGFsOiBpbnRlcnBvbGF0ZShhLmF6aW11dGhhbCwgYi5hemltdXRoYWwsIHQpLFxuICAgICAgICAgICAgcG9sYXI6IGludGVycG9sYXRlKGEucG9sYXIsIGIucG9sYXIsIHQpLFxuICAgICAgICB9O1xuICAgIH1cbn1cblxudHlwZSBQcm9wcyA9IHt8XG4gICAgXCJhbmNob3JcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8XCJtYXBcIiB8IFwidmlld3BvcnRcIj4sXG4gICAgXCJwb3NpdGlvblwiOiBMaWdodFBvc2l0aW9uUHJvcGVydHksXG4gICAgXCJjb2xvclwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxDb2xvcj4sXG4gICAgXCJpbnRlbnNpdHlcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8bnVtYmVyPixcbnx9O1xuXG5jb25zdCBwcm9wZXJ0aWVzOiBQcm9wZXJ0aWVzPFByb3BzPiA9IG5ldyBQcm9wZXJ0aWVzKHtcbiAgICBcImFuY2hvclwiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjLmxpZ2h0LmFuY2hvciksXG4gICAgXCJwb3NpdGlvblwiOiBuZXcgTGlnaHRQb3NpdGlvblByb3BlcnR5KCksXG4gICAgXCJjb2xvclwiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjLmxpZ2h0LmNvbG9yKSxcbiAgICBcImludGVuc2l0eVwiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjLmxpZ2h0LmludGVuc2l0eSksXG59KTtcblxuY29uc3QgVFJBTlNJVElPTl9TVUZGSVggPSAnLXRyYW5zaXRpb24nO1xuXG4vKlxuICogUmVwcmVzZW50cyB0aGUgbGlnaHQgdXNlZCB0byBsaWdodCBleHRydWRlZCBmZWF0dXJlcy5cbiAqL1xuY2xhc3MgTGlnaHQgZXh0ZW5kcyBFdmVudGVkIHtcbiAgICBfdHJhbnNpdGlvbmFibGU6IFRyYW5zaXRpb25hYmxlPFByb3BzPjtcbiAgICBfdHJhbnNpdGlvbmluZzogVHJhbnNpdGlvbmluZzxQcm9wcz47XG4gICAgcHJvcGVydGllczogUG9zc2libHlFdmFsdWF0ZWQ8UHJvcHM+O1xuXG4gICAgY29uc3RydWN0b3IobGlnaHRPcHRpb25zPzogTGlnaHRTcGVjaWZpY2F0aW9uKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuX3RyYW5zaXRpb25hYmxlID0gbmV3IFRyYW5zaXRpb25hYmxlKHByb3BlcnRpZXMpO1xuICAgICAgICB0aGlzLnNldExpZ2h0KGxpZ2h0T3B0aW9ucyk7XG4gICAgICAgIHRoaXMuX3RyYW5zaXRpb25pbmcgPSB0aGlzLl90cmFuc2l0aW9uYWJsZS51bnRyYW5zaXRpb25lZCgpO1xuICAgIH1cblxuICAgIGdldExpZ2h0KCk6IExpZ2h0U3BlY2lmaWNhdGlvbiB7XG4gICAgICAgIHJldHVybiAodGhpcy5fdHJhbnNpdGlvbmFibGUuc2VyaWFsaXplKCk6IGFueSk7XG4gICAgfVxuXG4gICAgc2V0TGlnaHQobGlnaHQ/OiBMaWdodFNwZWNpZmljYXRpb24sIG9wdGlvbnM6IFN0eWxlU2V0dGVyT3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIGlmICh0aGlzLl92YWxpZGF0ZSh2YWxpZGF0ZUxpZ2h0LCBsaWdodCwgb3B0aW9ucykpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoY29uc3QgbmFtZSBpbiBsaWdodCkge1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBsaWdodFtuYW1lXTtcbiAgICAgICAgICAgIGlmIChlbmRzV2l0aChuYW1lLCBUUkFOU0lUSU9OX1NVRkZJWCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl90cmFuc2l0aW9uYWJsZS5zZXRUcmFuc2l0aW9uKG5hbWUuc2xpY2UoMCwgLVRSQU5TSVRJT05fU1VGRklYLmxlbmd0aCksIHZhbHVlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdHJhbnNpdGlvbmFibGUuc2V0VmFsdWUobmFtZSwgdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgdXBkYXRlVHJhbnNpdGlvbnMocGFyYW1ldGVyczogVHJhbnNpdGlvblBhcmFtZXRlcnMpIHtcbiAgICAgICAgdGhpcy5fdHJhbnNpdGlvbmluZyA9IHRoaXMuX3RyYW5zaXRpb25hYmxlLnRyYW5zaXRpb25lZChwYXJhbWV0ZXJzLCB0aGlzLl90cmFuc2l0aW9uaW5nKTtcbiAgICB9XG5cbiAgICBoYXNUcmFuc2l0aW9uKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHJhbnNpdGlvbmluZy5oYXNUcmFuc2l0aW9uKCk7XG4gICAgfVxuXG4gICAgcmVjYWxjdWxhdGUocGFyYW1ldGVyczogRXZhbHVhdGlvblBhcmFtZXRlcnMpIHtcbiAgICAgICAgdGhpcy5wcm9wZXJ0aWVzID0gdGhpcy5fdHJhbnNpdGlvbmluZy5wb3NzaWJseUV2YWx1YXRlKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIF92YWxpZGF0ZSh2YWxpZGF0ZTogRnVuY3Rpb24sIHZhbHVlOiBtaXhlZCwgb3B0aW9ucz86IHt2YWxpZGF0ZT86IGJvb2xlYW59KTogYm9vbGVhbiB7XG4gICAgICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMudmFsaWRhdGUgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZW1pdFZhbGlkYXRpb25FcnJvcnModGhpcywgdmFsaWRhdGUuY2FsbCh2YWxpZGF0ZVN0eWxlLCBleHRlbmQoe1xuICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgICAvLyBXb3JrYXJvdW5kIGZvciBodHRwczovL2dpdGh1Yi5jb20vbWFwYm94L21hcGJveC1nbC1qcy9pc3N1ZXMvMjQwN1xuICAgICAgICAgICAgc3R5bGU6IHtnbHlwaHM6IHRydWUsIHNwcml0ZTogdHJ1ZX0sXG4gICAgICAgICAgICBzdHlsZVNwZWNcbiAgICAgICAgfSkpKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IExpZ2h0O1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHN0eWxlU3BlYyBmcm9tICcuLi9zdHlsZS1zcGVjL3JlZmVyZW5jZS9sYXRlc3QuanMnO1xuaW1wb3J0IHtlbmRzV2l0aH0gZnJvbSAnLi4vdXRpbC91dGlsLmpzJztcbmltcG9ydCB7RXZlbnRlZH0gZnJvbSAnLi4vdXRpbC9ldmVudGVkLmpzJztcbmltcG9ydCB7UHJvcGVydGllcywgVHJhbnNpdGlvbmFibGUsIFRyYW5zaXRpb25pbmcsIFBvc3NpYmx5RXZhbHVhdGVkLCBEYXRhQ29uc3RhbnRQcm9wZXJ0eX0gZnJvbSAnLi9wcm9wZXJ0aWVzLmpzJztcblxuaW1wb3J0IHR5cGUgRXZhbHVhdGlvblBhcmFtZXRlcnMgZnJvbSAnLi9ldmFsdWF0aW9uX3BhcmFtZXRlcnMuanMnO1xuaW1wb3J0IHR5cGUge1RyYW5zaXRpb25QYXJhbWV0ZXJzfSBmcm9tICcuL3Byb3BlcnRpZXMuanMnO1xuaW1wb3J0IHR5cGUge1RlcnJhaW5TcGVjaWZpY2F0aW9ufSBmcm9tICcuLi9zdHlsZS1zcGVjL3R5cGVzLmpzJztcblxudHlwZSBQcm9wcyA9IHt8XG4gICAgXCJzb3VyY2VcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8c3RyaW5nPixcbiAgICBcImV4YWdnZXJhdGlvblwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxudW1iZXI+LFxufH07XG5cbmV4cG9ydCBjb25zdCBEcmFwZVJlbmRlck1vZGUgPSB7XG4gICAgZGVmZXJyZWQ6IDAsXG4gICAgZWxldmF0ZWQ6IDFcbn07XG5cbmNvbnN0IHByb3BlcnRpZXM6IFByb3BlcnRpZXM8UHJvcHM+ID0gbmV3IFByb3BlcnRpZXMoe1xuICAgIFwic291cmNlXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWMudGVycmFpbi5zb3VyY2UpLFxuICAgIFwiZXhhZ2dlcmF0aW9uXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWMudGVycmFpbi5leGFnZ2VyYXRpb24pLFxufSk7XG5cbmNvbnN0IFRSQU5TSVRJT05fU1VGRklYID0gJy10cmFuc2l0aW9uJztcblxuY2xhc3MgVGVycmFpbiBleHRlbmRzIEV2ZW50ZWQge1xuICAgIF90cmFuc2l0aW9uYWJsZTogVHJhbnNpdGlvbmFibGU8UHJvcHM+O1xuICAgIF90cmFuc2l0aW9uaW5nOiBUcmFuc2l0aW9uaW5nPFByb3BzPjtcbiAgICBwcm9wZXJ0aWVzOiBQb3NzaWJseUV2YWx1YXRlZDxQcm9wcz47XG4gICAgZHJhcGVSZW5kZXJNb2RlOiBudW1iZXI7XG5cbiAgICBjb25zdHJ1Y3Rvcih0ZXJyYWluT3B0aW9uczogVGVycmFpblNwZWNpZmljYXRpb24sIGRyYXBlUmVuZGVyTW9kZTogbnVtYmVyKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuX3RyYW5zaXRpb25hYmxlID0gbmV3IFRyYW5zaXRpb25hYmxlKHByb3BlcnRpZXMpO1xuICAgICAgICB0aGlzLnNldCh0ZXJyYWluT3B0aW9ucyk7XG4gICAgICAgIHRoaXMuX3RyYW5zaXRpb25pbmcgPSB0aGlzLl90cmFuc2l0aW9uYWJsZS51bnRyYW5zaXRpb25lZCgpO1xuICAgICAgICB0aGlzLmRyYXBlUmVuZGVyTW9kZSA9IGRyYXBlUmVuZGVyTW9kZTtcbiAgICB9XG5cbiAgICBnZXQoKTogVGVycmFpblNwZWNpZmljYXRpb24ge1xuICAgICAgICByZXR1cm4gKHRoaXMuX3RyYW5zaXRpb25hYmxlLnNlcmlhbGl6ZSgpOiBhbnkpO1xuICAgIH1cblxuICAgIHNldCh0ZXJyYWluOiBUZXJyYWluU3BlY2lmaWNhdGlvbikge1xuICAgICAgICBmb3IgKGNvbnN0IG5hbWUgaW4gdGVycmFpbikge1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSB0ZXJyYWluW25hbWVdO1xuICAgICAgICAgICAgaWYgKGVuZHNXaXRoKG5hbWUsIFRSQU5TSVRJT05fU1VGRklYKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3RyYW5zaXRpb25hYmxlLnNldFRyYW5zaXRpb24obmFtZS5zbGljZSgwLCAtVFJBTlNJVElPTl9TVUZGSVgubGVuZ3RoKSwgdmFsdWUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl90cmFuc2l0aW9uYWJsZS5zZXRWYWx1ZShuYW1lLCB2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB1cGRhdGVUcmFuc2l0aW9ucyhwYXJhbWV0ZXJzOiBUcmFuc2l0aW9uUGFyYW1ldGVycykge1xuICAgICAgICB0aGlzLl90cmFuc2l0aW9uaW5nID0gdGhpcy5fdHJhbnNpdGlvbmFibGUudHJhbnNpdGlvbmVkKHBhcmFtZXRlcnMsIHRoaXMuX3RyYW5zaXRpb25pbmcpO1xuICAgIH1cblxuICAgIGhhc1RyYW5zaXRpb24oKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl90cmFuc2l0aW9uaW5nLmhhc1RyYW5zaXRpb24oKTtcbiAgICB9XG5cbiAgICByZWNhbGN1bGF0ZShwYXJhbWV0ZXJzOiBFdmFsdWF0aW9uUGFyYW1ldGVycykge1xuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSB0aGlzLl90cmFuc2l0aW9uaW5nLnBvc3NpYmx5RXZhbHVhdGUocGFyYW1ldGVycyk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBUZXJyYWluO1xuIiwiLy8gQGZsb3dcbmltcG9ydCB7dmVjM30gZnJvbSAnZ2wtbWF0cml4JztcbmltcG9ydCBNZXJjYXRvckNvb3JkaW5hdGUgZnJvbSAnLi4vZ2VvL21lcmNhdG9yX2Nvb3JkaW5hdGUuanMnO1xuaW1wb3J0IHtzbW9vdGhzdGVwfSBmcm9tICcuLi91dGlsL3V0aWwuanMnO1xuaW1wb3J0IHR5cGUgTG5nTGF0IGZyb20gJy4uL2dlby9sbmdfbGF0LmpzJztcbmltcG9ydCB0eXBlIHtVbndyYXBwZWRUaWxlSUR9IGZyb20gJy4uL3NvdXJjZS90aWxlX2lkLmpzJztcbmltcG9ydCB0eXBlIFRyYW5zZm9ybSBmcm9tICcuLi9nZW8vdHJhbnNmb3JtLmpzJztcblxuZXhwb3J0IGNvbnN0IEZPR19QSVRDSF9TVEFSVCA9IDQ1O1xuZXhwb3J0IGNvbnN0IEZPR19QSVRDSF9FTkQgPSA2NTtcbmV4cG9ydCBjb25zdCBGT0dfU1lNQk9MX0NMSVBQSU5HX1RIUkVTSE9MRCA9IDAuOTtcblxuZXhwb3J0IHR5cGUgRm9nU3RhdGUgPSB7XG4gICAgcmFuZ2U6IFtudW1iZXIsIG51bWJlcl0sXG4gICAgaG9yaXpvbkJsZW5kOiBudW1iZXIsXG4gICAgYWxwaGE6IG51bWJlclxufTtcblxuLy8gQXMgZGVmaW5lZCBpbiBfcHJlbHVkZV9mb2cuZnJhZ21lbnQuZ2xzbCNmb2dfb3BhY2l0eVxuZXhwb3J0IGZ1bmN0aW9uIGdldEZvZ09wYWNpdHkoc3RhdGU6IEZvZ1N0YXRlLCBwb3M6IEFycmF5PG51bWJlcj4sIHBpdGNoOiBudW1iZXIsIGZvdjogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBjb25zdCBmb2dQaXRjaE9wYWNpdHkgPSBzbW9vdGhzdGVwKEZPR19QSVRDSF9TVEFSVCwgRk9HX1BJVENIX0VORCwgcGl0Y2gpO1xuICAgIGNvbnN0IFtzdGFydCwgZW5kXSA9IGdldEZvdkFkanVzdGVkRm9nUmFuZ2Uoc3RhdGUsIGZvdik7XG5cbiAgICAvLyBUaGUgb3V0cHV0IG9mIHRoaXMgZnVuY3Rpb24gbXVzdCBtYXRjaCBfcHJlbHVkZV9mb2cuZnJhZ21lbnQuZ2xzbFxuICAgIC8vIEZvciBmdXJ0aGVyIGRldGFpbHMsIHJlZmVyIHRvIHRoZSBpbXBsZW1lbnRhdGlvbiBpbiB0aGUgc2hhZGVyIGNvZGVcbiAgICBjb25zdCBkZWNheSA9IDY7XG4gICAgY29uc3QgZGVwdGggPSB2ZWMzLmxlbmd0aChwb3MpO1xuICAgIGNvbnN0IGZvZ1JhbmdlID0gKGRlcHRoIC0gc3RhcnQpIC8gKGVuZCAtIHN0YXJ0KTtcbiAgICBsZXQgZmFsbG9mZiA9IDEuMCAtIE1hdGgubWluKDEsIE1hdGguZXhwKC1kZWNheSAqIGZvZ1JhbmdlKSk7XG5cbiAgICBmYWxsb2ZmICo9IGZhbGxvZmYgKiBmYWxsb2ZmO1xuICAgIGZhbGxvZmYgPSBNYXRoLm1pbigxLjAsIDEuMDA3NDcgKiBmYWxsb2ZmKTtcblxuICAgIHJldHVybiBmYWxsb2ZmICogZm9nUGl0Y2hPcGFjaXR5ICogc3RhdGUuYWxwaGE7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRGb3ZBZGp1c3RlZEZvZ1JhbmdlKHN0YXRlOiBGb2dTdGF0ZSwgZm92OiBudW1iZXIpOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgICAvLyBUaGlzIGZ1bmN0aW9uIGNvbXB1dGVzIGEgc2hpZnRlZCBmb2cgcmFuZ2Ugc28gdGhhdCB0aGUgYXBwZWFyYW5jZSBpcyB1bmNoYW5nZWRcbiAgICAvLyB3aGVuIHRoZSBmb3YgY2hhbmdlcy4gV2UgZGVmaW5lIHJhbmdlPTAgc3RhcnRpbmcgYXQgdGhlIGNhbWVyYSBwb3NpdGlvbiBnaXZlblxuICAgIC8vIHRoZSBkZWZhdWx0IGZvdi4gV2UgYXZvaWQgc3RhcnRpbmcgdGhlIGZvZyByYW5nZSBhdCB0aGUgY2FtZXJhIGNlbnRlciBzbyB0aGF0XG4gICAgLy8gcmFuZ2VzIGFyZW4ndCBnZW5lcmFsbHkgbmVnYXRpdmUgdW5sZXNzIHRoZSBGT1YgaXMgbW9kaWZpZWQuXG4gICAgY29uc3Qgc2hpZnQgPSAwLjUgLyBNYXRoLnRhbihmb3YgKiAwLjUpO1xuICAgIHJldHVybiBbc3RhdGUucmFuZ2VbMF0gKyBzaGlmdCwgc3RhdGUucmFuZ2VbMV0gKyBzaGlmdF07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRGb2dPcGFjaXR5QXRUaWxlQ29vcmQoc3RhdGU6IEZvZ1N0YXRlLCB4OiBudW1iZXIsIHk6IG51bWJlciwgejogbnVtYmVyLCB0aWxlSWQ6IFVud3JhcHBlZFRpbGVJRCwgdHJhbnNmb3JtOiBUcmFuc2Zvcm0pOiBudW1iZXIge1xuICAgIGNvbnN0IG1hdCA9IHRyYW5zZm9ybS5jYWxjdWxhdGVGb2dUaWxlTWF0cml4KHRpbGVJZCk7XG4gICAgY29uc3QgcG9zID0gW3gsIHksIHpdO1xuICAgIHZlYzMudHJhbnNmb3JtTWF0NChwb3MsIHBvcywgbWF0KTtcblxuICAgIHJldHVybiBnZXRGb2dPcGFjaXR5KHN0YXRlLCBwb3MsIHRyYW5zZm9ybS5waXRjaCwgdHJhbnNmb3JtLl9mb3YpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9nT3BhY2l0eUF0TG5nTGF0KHN0YXRlOiBGb2dTdGF0ZSwgbG5nTGF0OiBMbmdMYXQsIHRyYW5zZm9ybTogVHJhbnNmb3JtKTogbnVtYmVyIHtcbiAgICBjb25zdCBtZXRlcnMgPSBNZXJjYXRvckNvb3JkaW5hdGUuZnJvbUxuZ0xhdChsbmdMYXQpO1xuICAgIGNvbnN0IGVsZXZhdGlvbiA9IHRyYW5zZm9ybS5lbGV2YXRpb24gPyB0cmFuc2Zvcm0uZWxldmF0aW9uLmdldEF0UG9pbnRPclplcm8obWV0ZXJzKSA6IDA7XG4gICAgY29uc3QgcG9zID0gW21ldGVycy54LCBtZXRlcnMueSwgZWxldmF0aW9uXTtcbiAgICB2ZWMzLnRyYW5zZm9ybU1hdDQocG9zLCBwb3MsIHRyYW5zZm9ybS5tZXJjYXRvckZvZ01hdHJpeCk7XG5cbiAgICByZXR1cm4gZ2V0Rm9nT3BhY2l0eShzdGF0ZSwgcG9zLCB0cmFuc2Zvcm0ucGl0Y2gsIHRyYW5zZm9ybS5fZm92KTtcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBzdHlsZVNwZWMgZnJvbSAnLi4vc3R5bGUtc3BlYy9yZWZlcmVuY2UvbGF0ZXN0LmpzJztcbmltcG9ydCB7ZW5kc1dpdGgsIGV4dGVuZCwgc21vb3Roc3RlcH0gZnJvbSAnLi4vdXRpbC91dGlsLmpzJztcbmltcG9ydCB7RXZlbnRlZH0gZnJvbSAnLi4vdXRpbC9ldmVudGVkLmpzJztcbmltcG9ydCB7dmFsaWRhdGVTdHlsZSwgdmFsaWRhdGVGb2csIGVtaXRWYWxpZGF0aW9uRXJyb3JzfSBmcm9tICcuL3ZhbGlkYXRlX3N0eWxlLmpzJztcbmltcG9ydCB7UHJvcGVydGllcywgVHJhbnNpdGlvbmFibGUsIFRyYW5zaXRpb25pbmcsIFBvc3NpYmx5RXZhbHVhdGVkLCBEYXRhQ29uc3RhbnRQcm9wZXJ0eX0gZnJvbSAnLi9wcm9wZXJ0aWVzLmpzJztcbmltcG9ydCBDb2xvciBmcm9tICcuLi9zdHlsZS1zcGVjL3V0aWwvY29sb3IuanMnO1xuaW1wb3J0IHtGT0dfUElUQ0hfU1RBUlQsIEZPR19QSVRDSF9FTkQsIGdldEZvZ09wYWNpdHlBdExuZ0xhdCwgZ2V0Rm92QWRqdXN0ZWRGb2dSYW5nZX0gZnJvbSAnLi9mb2dfaGVscGVycy5qcyc7XG5pbXBvcnQgdHlwZSB7Rm9nU3BlY2lmaWNhdGlvbn0gZnJvbSAnLi4vc3R5bGUtc3BlYy90eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSBFdmFsdWF0aW9uUGFyYW1ldGVycyBmcm9tICcuL2V2YWx1YXRpb25fcGFyYW1ldGVycy5qcyc7XG5pbXBvcnQgdHlwZSB7VHJhbnNpdGlvblBhcmFtZXRlcnN9IGZyb20gJy4vcHJvcGVydGllcy5qcyc7XG5pbXBvcnQgdHlwZSBMbmdMYXQgZnJvbSAnLi4vZ2VvL2xuZ19sYXQuanMnO1xuaW1wb3J0IHR5cGUgVHJhbnNmb3JtIGZyb20gJy4uL2dlby90cmFuc2Zvcm0uanMnO1xuaW1wb3J0IHR5cGUge1N0eWxlU2V0dGVyT3B0aW9uc30gZnJvbSAnLi4vc3R5bGUvc3R5bGUuanMnO1xuaW1wb3J0IHR5cGUge0ZvZ1N0YXRlfSBmcm9tICcuL2ZvZ19oZWxwZXJzLmpzJztcbmltcG9ydCB7bnVtYmVyIGFzIGludGVycG9sYXRlfSBmcm9tICcuLi9zdHlsZS1zcGVjL3V0aWwvaW50ZXJwb2xhdGUuanMnO1xuaW1wb3J0IHtnbG9iZVRvTWVyY2F0b3JUcmFuc2l0aW9ufSBmcm9tICcuLi9nZW8vcHJvamVjdGlvbi9nbG9iZV91dGlsLmpzJztcblxudHlwZSBQcm9wcyA9IHt8XG4gICAgXCJyYW5nZVwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxbbnVtYmVyLCBudW1iZXJdPixcbiAgICBcImNvbG9yXCI6IERhdGFDb25zdGFudFByb3BlcnR5PENvbG9yPixcbiAgICBcImhpZ2gtY29sb3JcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8Q29sb3I+LFxuICAgIFwic3BhY2UtY29sb3JcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8Q29sb3I+LFxuICAgIFwiaG9yaXpvbi1ibGVuZFwiOiBEYXRhQ29uc3RhbnRQcm9wZXJ0eTxudW1iZXI+LFxuICAgIFwic3Rhci1pbnRlbnNpdHlcIjogRGF0YUNvbnN0YW50UHJvcGVydHk8bnVtYmVyPixcbnx9O1xuXG5jb25zdCBmb2dQcm9wZXJ0aWVzOiBQcm9wZXJ0aWVzPFByb3BzPiA9IG5ldyBQcm9wZXJ0aWVzKHtcbiAgICBcInJhbmdlXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWMuZm9nLnJhbmdlKSxcbiAgICBcImNvbG9yXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWMuZm9nLmNvbG9yKSxcbiAgICBcImhpZ2gtY29sb3JcIjogbmV3IERhdGFDb25zdGFudFByb3BlcnR5KHN0eWxlU3BlYy5mb2dbXCJoaWdoLWNvbG9yXCJdKSxcbiAgICBcInNwYWNlLWNvbG9yXCI6IG5ldyBEYXRhQ29uc3RhbnRQcm9wZXJ0eShzdHlsZVNwZWMuZm9nW1wic3BhY2UtY29sb3JcIl0pLFxuICAgIFwiaG9yaXpvbi1ibGVuZFwiOiBuZXcgRGF0YUNvbnN0YW50UHJvcGVydHkoc3R5bGVTcGVjLmZvZ1tcImhvcml6b24tYmxlbmRcIl0pLFxuICAgIFwic3Rhci1pbnRlbnNpdHlcIjogbmV3IERhdGFDb25zdGFudFByb3BlcnR5KHN0eWxlU3BlYy5mb2dbXCJzdGFyLWludGVuc2l0eVwiXSksXG59KTtcblxuY29uc3QgVFJBTlNJVElPTl9TVUZGSVggPSAnLXRyYW5zaXRpb24nO1xuXG5jbGFzcyBGb2cgZXh0ZW5kcyBFdmVudGVkIHtcbiAgICBfdHJhbnNpdGlvbmFibGU6IFRyYW5zaXRpb25hYmxlPFByb3BzPjtcbiAgICBfdHJhbnNpdGlvbmluZzogVHJhbnNpdGlvbmluZzxQcm9wcz47XG4gICAgcHJvcGVydGllczogUG9zc2libHlFdmFsdWF0ZWQ8UHJvcHM+O1xuXG4gICAgLy8gQWx0ZXJuYXRlIHByb2plY3Rpb25zIGRvIG5vdCB5ZXQgc3VwcG9ydCBmb2cuXG4gICAgLy8gSG9sZCBvbiB0byB0cmFuc2Zvcm0gc28gdGhhdCB3ZSBrbm93IHdoZXRoZXIgYSBwcm9qZWN0aW9uIGlzIHNldC5cbiAgICBfdHJhbnNmb3JtOiBUcmFuc2Zvcm07XG5cbiAgICBjb25zdHJ1Y3Rvcihmb2dPcHRpb25zPzogRm9nU3BlY2lmaWNhdGlvbiwgdHJhbnNmb3JtOiBUcmFuc2Zvcm0pIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5fdHJhbnNpdGlvbmFibGUgPSBuZXcgVHJhbnNpdGlvbmFibGUoZm9nUHJvcGVydGllcyk7XG4gICAgICAgIHRoaXMuc2V0KGZvZ09wdGlvbnMpO1xuICAgICAgICB0aGlzLl90cmFuc2l0aW9uaW5nID0gdGhpcy5fdHJhbnNpdGlvbmFibGUudW50cmFuc2l0aW9uZWQoKTtcbiAgICAgICAgdGhpcy5fdHJhbnNmb3JtID0gdHJhbnNmb3JtO1xuICAgIH1cblxuICAgIGdldCBzdGF0ZSgpOiBGb2dTdGF0ZSB7XG4gICAgICAgIGNvbnN0IHRyID0gdGhpcy5fdHJhbnNmb3JtO1xuICAgICAgICBjb25zdCBpc0dsb2JlID0gdHIucHJvamVjdGlvbi5uYW1lID09PSAnZ2xvYmUnO1xuICAgICAgICBjb25zdCB0cmFuc2l0aW9uVCA9IGdsb2JlVG9NZXJjYXRvclRyYW5zaXRpb24odHIuem9vbSk7XG4gICAgICAgIGNvbnN0IHJhbmdlID0gdGhpcy5wcm9wZXJ0aWVzLmdldCgncmFuZ2UnKTtcbiAgICAgICAgY29uc3QgZ2xvYmVGaXhlZEZvZ1JhbmdlID0gWzAuNSwgM107XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByYW5nZTogaXNHbG9iZSA/IFtcbiAgICAgICAgICAgICAgICBpbnRlcnBvbGF0ZShnbG9iZUZpeGVkRm9nUmFuZ2VbMF0sIHJhbmdlWzBdLCB0cmFuc2l0aW9uVCksXG4gICAgICAgICAgICAgICAgaW50ZXJwb2xhdGUoZ2xvYmVGaXhlZEZvZ1JhbmdlWzFdLCByYW5nZVsxXSwgdHJhbnNpdGlvblQpXG4gICAgICAgICAgICBdIDogcmFuZ2UsXG4gICAgICAgICAgICBob3Jpem9uQmxlbmQ6IHRoaXMucHJvcGVydGllcy5nZXQoJ2hvcml6b24tYmxlbmQnKSxcbiAgICAgICAgICAgIGFscGhhOiB0aGlzLnByb3BlcnRpZXMuZ2V0KCdjb2xvcicpLmFcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBnZXQoKTogRm9nU3BlY2lmaWNhdGlvbiB7XG4gICAgICAgIHJldHVybiAodGhpcy5fdHJhbnNpdGlvbmFibGUuc2VyaWFsaXplKCk6IGFueSk7XG4gICAgfVxuXG4gICAgc2V0KGZvZz86IEZvZ1NwZWNpZmljYXRpb24sIG9wdGlvbnM6IFN0eWxlU2V0dGVyT3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIGlmICh0aGlzLl92YWxpZGF0ZSh2YWxpZGF0ZUZvZywgZm9nLCBvcHRpb25zKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKHN0eWxlU3BlYy5mb2cpKSB7XG4gICAgICAgICAgICAvLyBGYWxsYmFjayB0byB1c2UgZGVmYXVsdCBzdHlsZSBzcGVjaWZpY2F0aW9uIHdoZW4gdGhlIHByb3BlcnRpZXMgd2Fzbid0IHNldFxuICAgICAgICAgICAgaWYgKGZvZyAmJiBmb2dbbmFtZV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXVxuICAgICAgICAgICAgICAgIGZvZ1tuYW1lXSA9IHN0eWxlU3BlYy5mb2dbbmFtZV0uZGVmYXVsdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoY29uc3QgbmFtZSBpbiBmb2cpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gZm9nW25hbWVdO1xuICAgICAgICAgICAgaWYgKGVuZHNXaXRoKG5hbWUsIFRSQU5TSVRJT05fU1VGRklYKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3RyYW5zaXRpb25hYmxlLnNldFRyYW5zaXRpb24obmFtZS5zbGljZSgwLCAtVFJBTlNJVElPTl9TVUZGSVgubGVuZ3RoKSwgdmFsdWUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl90cmFuc2l0aW9uYWJsZS5zZXRWYWx1ZShuYW1lLCB2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRPcGFjaXR5KHBpdGNoOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBpZiAoIXRoaXMuX3RyYW5zZm9ybS5wcm9qZWN0aW9uLnN1cHBvcnRzRm9nKSByZXR1cm4gMDtcblxuICAgICAgICBjb25zdCBmb2dDb2xvciA9ICh0aGlzLnByb3BlcnRpZXMgJiYgdGhpcy5wcm9wZXJ0aWVzLmdldCgnY29sb3InKSkgfHwgMS4wO1xuICAgICAgICBjb25zdCBpc0dsb2JlID0gdGhpcy5fdHJhbnNmb3JtLnByb2plY3Rpb24ubmFtZSA9PT0gJ2dsb2JlJztcbiAgICAgICAgY29uc3QgcGl0Y2hGYWN0b3IgPSBpc0dsb2JlID8gMS4wIDogc21vb3Roc3RlcChGT0dfUElUQ0hfU1RBUlQsIEZPR19QSVRDSF9FTkQsIHBpdGNoKTtcbiAgICAgICAgcmV0dXJuIHBpdGNoRmFjdG9yICogZm9nQ29sb3IuYTtcbiAgICB9XG5cbiAgICBnZXRPcGFjaXR5QXRMYXRMbmcobG5nTGF0OiBMbmdMYXQsIHRyYW5zZm9ybTogVHJhbnNmb3JtKTogbnVtYmVyIHtcbiAgICAgICAgaWYgKCF0aGlzLl90cmFuc2Zvcm0ucHJvamVjdGlvbi5zdXBwb3J0c0ZvZykgcmV0dXJuIDA7XG5cbiAgICAgICAgcmV0dXJuIGdldEZvZ09wYWNpdHlBdExuZ0xhdCh0aGlzLnN0YXRlLCBsbmdMYXQsIHRyYW5zZm9ybSk7XG4gICAgfVxuXG4gICAgZ2V0Rm92QWRqdXN0ZWRSYW5nZShmb3Y6IG51bWJlcik6IFtudW1iZXIsIG51bWJlcl0ge1xuICAgICAgICAvLyBXZSBjYW4gcmV0dXJuIGFueSBhcmJpdHJhcnkgcmFuZ2UgYmVjYXVzZSB3ZSBleHBlY3Qgb3BhY2l0eT0wIHRvIGNsZWFuIGl0IHVwXG4gICAgICAgIGlmICghdGhpcy5fdHJhbnNmb3JtLnByb2plY3Rpb24uc3VwcG9ydHNGb2cpIHJldHVybiBbMCwgMV07XG5cbiAgICAgICAgcmV0dXJuIGdldEZvdkFkanVzdGVkRm9nUmFuZ2UodGhpcy5zdGF0ZSwgZm92KTtcbiAgICB9XG5cbiAgICB1cGRhdGVUcmFuc2l0aW9ucyhwYXJhbWV0ZXJzOiBUcmFuc2l0aW9uUGFyYW1ldGVycykge1xuICAgICAgICB0aGlzLl90cmFuc2l0aW9uaW5nID0gdGhpcy5fdHJhbnNpdGlvbmFibGUudHJhbnNpdGlvbmVkKHBhcmFtZXRlcnMsIHRoaXMuX3RyYW5zaXRpb25pbmcpO1xuICAgIH1cblxuICAgIGhhc1RyYW5zaXRpb24oKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl90cmFuc2l0aW9uaW5nLmhhc1RyYW5zaXRpb24oKTtcbiAgICB9XG5cbiAgICByZWNhbGN1bGF0ZShwYXJhbWV0ZXJzOiBFdmFsdWF0aW9uUGFyYW1ldGVycykge1xuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSB0aGlzLl90cmFuc2l0aW9uaW5nLnBvc3NpYmx5RXZhbHVhdGUocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgX3ZhbGlkYXRlKHZhbGlkYXRlOiBGdW5jdGlvbiwgdmFsdWU6IG1peGVkLCBvcHRpb25zPzoge3ZhbGlkYXRlPzogYm9vbGVhbn0pOiBib29sZWFuIHtcbiAgICAgICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy52YWxpZGF0ZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBlbWl0VmFsaWRhdGlvbkVycm9ycyh0aGlzLCB2YWxpZGF0ZS5jYWxsKHZhbGlkYXRlU3R5bGUsIGV4dGVuZCh7XG4gICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgIHN0eWxlOiB7Z2x5cGhzOiB0cnVlLCBzcHJpdGU6IHRydWV9LFxuICAgICAgICAgICAgc3R5bGVTcGVjXG4gICAgICAgIH0pKSk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBGb2c7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge3VuaXF1ZUlkLCBhc3luY0FsbH0gZnJvbSAnLi91dGlsLmpzJztcbmltcG9ydCBBY3RvciBmcm9tICcuL2FjdG9yLmpzJztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcblxuaW1wb3J0IHR5cGUgV29ya2VyUG9vbCBmcm9tICcuL3dvcmtlcl9wb29sLmpzJztcblxuLyoqXG4gKiBSZXNwb25zaWJsZSBmb3Igc2VuZGluZyBtZXNzYWdlcyBmcm9tIGEge0BsaW5rIFNvdXJjZX0gdG8gYW4gYXNzb2NpYXRlZFxuICoge0BsaW5rIFdvcmtlclNvdXJjZX0uXG4gKlxuICogQHByaXZhdGVcbiAqL1xuY2xhc3MgRGlzcGF0Y2hlciB7XG4gICAgd29ya2VyUG9vbDogV29ya2VyUG9vbDtcbiAgICBhY3RvcnM6IEFycmF5PEFjdG9yPjtcbiAgICBjdXJyZW50QWN0b3I6IG51bWJlcjtcbiAgICBpZDogbnVtYmVyO1xuICAgIHJlYWR5OiBib29sZWFuO1xuXG4gICAgLy8gZXhwb3NlZCB0byBhbGxvdyBzdHViYmluZyBpbiB1bml0IHRlc3RzXG4gICAgc3RhdGljIEFjdG9yOiBDbGFzczxBY3Rvcj47XG5cbiAgICBjb25zdHJ1Y3Rvcih3b3JrZXJQb29sOiBXb3JrZXJQb29sLCBwYXJlbnQ6IGFueSkge1xuICAgICAgICB0aGlzLndvcmtlclBvb2wgPSB3b3JrZXJQb29sO1xuICAgICAgICB0aGlzLmFjdG9ycyA9IFtdO1xuICAgICAgICB0aGlzLmN1cnJlbnRBY3RvciA9IDA7XG4gICAgICAgIHRoaXMuaWQgPSB1bmlxdWVJZCgpO1xuICAgICAgICBjb25zdCB3b3JrZXJzID0gdGhpcy53b3JrZXJQb29sLmFjcXVpcmUodGhpcy5pZCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgd29ya2Vycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3Qgd29ya2VyID0gd29ya2Vyc1tpXTtcbiAgICAgICAgICAgIGNvbnN0IGFjdG9yID0gbmV3IERpc3BhdGNoZXIuQWN0b3Iod29ya2VyLCBwYXJlbnQsIHRoaXMuaWQpO1xuICAgICAgICAgICAgYWN0b3IubmFtZSA9IGBXb3JrZXIgJHtpfWA7XG4gICAgICAgICAgICB0aGlzLmFjdG9ycy5wdXNoKGFjdG9yKTtcbiAgICAgICAgfVxuICAgICAgICBhc3NlcnQodGhpcy5hY3RvcnMubGVuZ3RoKTtcblxuICAgICAgICAvLyB0cmFjayB3aGV0aGVyIGFsbCB3b3JrZXJzIGFyZSBpbnN0YW50aWF0ZWQgYW5kIHJlYWR5IHRvIHJlY2VpdmUgbWVzc2FnZXM7XG4gICAgICAgIC8vIHVzZWQgZm9yIG9wdGltaXphdGlvbnMgb24gaW5pdGlhbCBtYXAgbG9hZFxuICAgICAgICB0aGlzLnJlYWR5ID0gZmFsc2U7XG4gICAgICAgIHRoaXMuYnJvYWRjYXN0KCdjaGVja0lmUmVhZHknLCBudWxsLCAoKSA9PiB7IHRoaXMucmVhZHkgPSB0cnVlOyB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBCcm9hZGNhc3QgYSBtZXNzYWdlIHRvIGFsbCBXb3JrZXJzLlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgYnJvYWRjYXN0KHR5cGU6IHN0cmluZywgZGF0YTogbWl4ZWQsIGNiPzogRnVuY3Rpb24pIHtcbiAgICAgICAgYXNzZXJ0KHRoaXMuYWN0b3JzLmxlbmd0aCk7XG4gICAgICAgIGNiID0gY2IgfHwgZnVuY3Rpb24gKCkge307XG4gICAgICAgIGFzeW5jQWxsKHRoaXMuYWN0b3JzLCAoYWN0b3IsIGRvbmUpID0+IHtcbiAgICAgICAgICAgIGFjdG9yLnNlbmQodHlwZSwgZGF0YSwgZG9uZSk7XG4gICAgICAgIH0sIGNiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBY3F1aXJlcyBhbiBhY3RvciB0byBkaXNwYXRjaCBtZXNzYWdlcyB0by4gVGhlIGFjdG9ycyBhcmUgZGlzdHJpYnV0ZWQgaW4gcm91bmQtcm9iaW4gZmFzaGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QWN0b3J9IEFuIGFjdG9yIG9iamVjdCBiYWNrZWQgYnkgYSB3ZWIgd29ya2VyIGZvciBwcm9jZXNzaW5nIG1lc3NhZ2VzLlxuICAgICAqL1xuICAgIGdldEFjdG9yKCk6IEFjdG9yIHtcbiAgICAgICAgYXNzZXJ0KHRoaXMuYWN0b3JzLmxlbmd0aCk7XG4gICAgICAgIHRoaXMuY3VycmVudEFjdG9yID0gKHRoaXMuY3VycmVudEFjdG9yICsgMSkgJSB0aGlzLmFjdG9ycy5sZW5ndGg7XG4gICAgICAgIHJldHVybiB0aGlzLmFjdG9yc1t0aGlzLmN1cnJlbnRBY3Rvcl07XG4gICAgfVxuXG4gICAgcmVtb3ZlKCkge1xuICAgICAgICB0aGlzLmFjdG9ycy5mb3JFYWNoKChhY3RvcikgPT4geyBhY3Rvci5yZW1vdmUoKTsgfSk7XG4gICAgICAgIHRoaXMuYWN0b3JzID0gW107XG4gICAgICAgIHRoaXMud29ya2VyUG9vbC5yZWxlYXNlKHRoaXMuaWQpO1xuICAgIH1cbn1cblxuRGlzcGF0Y2hlci5BY3RvciA9IEFjdG9yO1xuXG5leHBvcnQgZGVmYXVsdCBEaXNwYXRjaGVyO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHttYXQyfSBmcm9tICdnbC1tYXRyaXgnO1xuXG5pbXBvcnQgRVhURU5UIGZyb20gJy4uL2RhdGEvZXh0ZW50LmpzJztcblxuaW1wb3J0IHR5cGUge092ZXJzY2FsZWRUaWxlSUR9IGZyb20gJy4vdGlsZV9pZC5qcyc7XG5pbXBvcnQgdHlwZSBUcmFuc2Zvcm0gZnJvbSAnLi4vZ2VvL3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQgdHlwZSB7VGlsZVRyYW5zZm9ybX0gZnJvbSAnLi4vZ2VvL3Byb2plY3Rpb24vdGlsZV90cmFuc2Zvcm0uanMnO1xuXG4vKipcbiAqIENvbnZlcnRzIGEgcGl4ZWwgdmFsdWUgYXQgYSB0aGUgZ2l2ZW4gem9vbSBsZXZlbCB0byB0aWxlIHVuaXRzLlxuICpcbiAqIFRoZSBzaGFkZXJzIG1vc3RseSBjYWxjdWxhdGUgZXZlcnl0aGluZyBpbiB0aWxlIHVuaXRzIHNvIHN0eWxlXG4gKiBwcm9wZXJ0aWVzIG5lZWQgdG8gYmUgY29udmVydGVkIGZyb20gcGl4ZWxzIHRvIHRpbGUgdW5pdHMgdXNpbmcgdGhpcy5cbiAqXG4gKiBGb3IgZXhhbXBsZSwgYSB0cmFuc2xhdGlvbiBieSAzMCBwaXhlbHMgYXQgem9vbSA2LjUgd2lsbCBiZSBhXG4gKiB0cmFuc2xhdGlvbiBieSBwaXhlbHNUb1RpbGVVbml0cygzMCwgNi41KSB0aWxlIHVuaXRzLlxuICpcbiAqIEByZXR1cm5zIHZhbHVlIGluIHRpbGUgdW5pdHNcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKHRpbGU6IGludGVyZmFjZSB7dGlsZUlEOiBPdmVyc2NhbGVkVGlsZUlELCB0aWxlU2l6ZTogbnVtYmVyfSwgcGl4ZWxWYWx1ZTogbnVtYmVyLCB6OiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiBwaXhlbFZhbHVlICogKEVYVEVOVCAvICh0aWxlLnRpbGVTaXplICogTWF0aC5wb3coMiwgeiAtIHRpbGUudGlsZUlELm92ZXJzY2FsZWRaKSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UGl4ZWxzVG9UaWxlVW5pdHNNYXRyaXgodGlsZTogaW50ZXJmYWNlIHt0aWxlSUQ6IE92ZXJzY2FsZWRUaWxlSUQsIHRpbGVTaXplOiBudW1iZXIsICt0aWxlVHJhbnNmb3JtOiBUaWxlVHJhbnNmb3JtfSwgdHJhbnNmb3JtOiBUcmFuc2Zvcm0pOiBGbG9hdDMyQXJyYXkge1xuICAgIGNvbnN0IHtzY2FsZX0gPSB0aWxlLnRpbGVUcmFuc2Zvcm07XG4gICAgY29uc3QgcyA9IHNjYWxlICogRVhURU5UIC8gKHRpbGUudGlsZVNpemUgKiBNYXRoLnBvdygyLCB0cmFuc2Zvcm0uem9vbSAtIHRpbGUudGlsZUlELm92ZXJzY2FsZWRaICsgdGlsZS50aWxlSUQuY2Fub25pY2FsLnopKTtcbiAgICByZXR1cm4gbWF0Mi5zY2FsZShuZXcgRmxvYXQzMkFycmF5KDQpLCB0cmFuc2Zvcm0uaW52ZXJzZUFkanVzdG1lbnRNYXRyaXgsIFtzLCBzXSk7XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5pbXBvcnQge2dldEJvdW5kcywgY2xhbXAsIHBvbHlnb25pemVCb3VuZHMsIGJ1ZmZlckNvbnZleFBvbHlnb259IGZyb20gJy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQge3BvbHlnb25JbnRlcnNlY3RzQm94LCBwb2x5Z29uQ29udGFpbnNQb2ludH0gZnJvbSAnLi4vdXRpbC9pbnRlcnNlY3Rpb25fdGVzdHMuanMnO1xuaW1wb3J0IEVYVEVOVCBmcm9tICcuLi9kYXRhL2V4dGVudC5qcyc7XG5pbXBvcnQgdHlwZSB7UG9pbnRMaWtlfSBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCB0eXBlIFRyYW5zZm9ybSBmcm9tICcuLi9nZW8vdHJhbnNmb3JtLmpzJztcbmltcG9ydCB0eXBlIFRpbGUgZnJvbSAnLi4vc291cmNlL3RpbGUuanMnO1xuaW1wb3J0IHBpeGVsc1RvVGlsZVVuaXRzIGZyb20gJy4uL3NvdXJjZS9waXhlbHNfdG9fdGlsZV91bml0cy5qcyc7XG5pbXBvcnQge3ZlYzMsIHZlYzQsIG1hdDR9IGZyb20gJ2dsLW1hdHJpeCc7XG5pbXBvcnQge1JheX0gZnJvbSAnLi4vdXRpbC9wcmltaXRpdmVzLmpzJztcbmltcG9ydCBNZXJjYXRvckNvb3JkaW5hdGUsIHttZXJjYXRvclhmcm9tTG5nfSBmcm9tICcuLi9nZW8vbWVyY2F0b3JfY29vcmRpbmF0ZS5qcyc7XG5pbXBvcnQgdHlwZSB7T3ZlcnNjYWxlZFRpbGVJRH0gZnJvbSAnLi4vc291cmNlL3RpbGVfaWQuanMnO1xuaW1wb3J0IHtnZXRUaWxlUG9pbnQsIGdldFRpbGVWZWMzfSBmcm9tICcuLi9nZW8vcHJvamVjdGlvbi90aWxlX3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQgcmVzYW1wbGUgZnJvbSAnLi4vZ2VvL3Byb2plY3Rpb24vcmVzYW1wbGUuanMnO1xuaW1wb3J0IHtHTE9CRV9SQURJVVN9IGZyb20gJy4uL2dlby9wcm9qZWN0aW9uL2dsb2JlX3V0aWwuanMnO1xuaW1wb3J0IHtudW1iZXIgYXMgaW50ZXJwb2xhdGV9IGZyb20gJy4uL3N0eWxlLXNwZWMvdXRpbC9pbnRlcnBvbGF0ZS5qcyc7XG5cbnR5cGUgQ2FjaGVkUG9seWdvbiA9IHtcbiAgICAvLyBRdWVyeSByZWN0YW5nbGUgcHJvamVjdGVkIG9uIHRoZSBtYXAgcGxhbmVcbiAgICBwb2x5Z29uOiBNZXJjYXRvckNvb3JkaW5hdGVbXTtcblxuICAgIC8vIEEgZmxhZyB0ZWxsaW5nd2hldGhlciB0aGUgcXVlcnkgcG9seWdvbiBtaWdodCBzcGFuIGFjcm9zcyBtZXJjYXRvciBib3VuZGFyaWVzIFswLCAxXVxuICAgIHVud3JhcHBlZDogYm9vbGVhbjtcbn07XG5cbi8qKlxuICogQSBkYXRhLWNsYXNzIHRoYXQgcmVwcmVzZW50cyBhIHNjcmVlbnNwYWNlIHF1ZXJ5IGZyb20gYE1hcCNxdWVyeVJlbmRlcmVkRmVhdHVyZXNgLlxuICogQWxsIHRoZSBpbnRlcm5hbCBnZW9tZXRyaWVzIGFuZCBkYXRhIGFyZSBpbnRlbnRlZCB0byBiZSBpbW11dGFibGUgYW5kIHJlYWQtb25seS5cbiAqIEl0cyBsaWZldGltZSBpcyBvbmx5IGZvciB0aGUgZHVyYXRpb24gb2YgdGhlIHF1ZXJ5IGFuZCBmaXhlZCBzdGF0ZSBvZiB0aGUgbWFwIHdoaWxlIHRoZSBxdWVyeSBpcyBiZWluZyBwcm9jZXNzZWQuXG4gKlxuICogQGNsYXNzIFF1ZXJ5R2VvbWV0cnlcbiAqL1xuZXhwb3J0IGNsYXNzIFF1ZXJ5R2VvbWV0cnkge1xuICAgIHNjcmVlbkJvdW5kczogUG9pbnRbXTtcbiAgICBjYW1lcmFQb2ludDogUG9pbnQ7XG4gICAgc2NyZWVuR2VvbWV0cnk6IFBvaW50W107XG4gICAgc2NyZWVuR2VvbWV0cnlNZXJjYXRvcjogQ2FjaGVkUG9seWdvbjtcblxuICAgIF9zY3JlZW5SYXljYXN0Q2FjaGU6IHsgW186IG51bWJlcl06IENhY2hlZFBvbHlnb259O1xuICAgIF9jYW1lcmFSYXljYXN0Q2FjaGU6IHsgW186IG51bWJlcl06IENhY2hlZFBvbHlnb259O1xuXG4gICAgaXNBYm92ZUhvcml6b246IGJvb2xlYW47XG5cbiAgICBjb25zdHJ1Y3RvcihzY3JlZW5Cb3VuZHM6IFBvaW50W10sIGNhbWVyYVBvaW50OiBQb2ludCwgYWJvdmVIb3Jpem9uOiBib29sZWFuLCB0cmFuc2Zvcm06IFRyYW5zZm9ybSkge1xuICAgICAgICB0aGlzLnNjcmVlbkJvdW5kcyA9IHNjcmVlbkJvdW5kcztcbiAgICAgICAgdGhpcy5jYW1lcmFQb2ludCA9IGNhbWVyYVBvaW50O1xuICAgICAgICB0aGlzLl9zY3JlZW5SYXljYXN0Q2FjaGUgPSB7fTtcbiAgICAgICAgdGhpcy5fY2FtZXJhUmF5Y2FzdENhY2hlID0ge307XG4gICAgICAgIHRoaXMuaXNBYm92ZUhvcml6b24gPSBhYm92ZUhvcml6b247XG5cbiAgICAgICAgdGhpcy5zY3JlZW5HZW9tZXRyeSA9IHRoaXMuYnVmZmVyZWRTY3JlZW5HZW9tZXRyeSgwKTtcbiAgICAgICAgdGhpcy5zY3JlZW5HZW9tZXRyeU1lcmNhdG9yID0gdGhpcy5fYnVmZmVyZWRTY3JlZW5NZXJjYXRvcigwLCB0cmFuc2Zvcm0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZhY3RvcnkgbWV0aG9kIHRvIGhlbHAgY29udHJ1Y3QgYW4gaW5zdGFuY2UgIHdoaWxlIGFjY291bnRpbmcgZm9yIGN1cnJlbnQgbWFwIHN0YXRlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7KFBvaW50TGlrZSB8IFtQb2ludExpa2UsIFBvaW50TGlrZV0pfSBnZW9tZXRyeSBUaGUgcXVlcnkgZ2VvbWV0cnkuXG4gICAgICogQHBhcmFtIHtUcmFuc2Zvcm19IHRyYW5zZm9ybSBUaGUgY3VycmVudCBtYXAgdHJhbnNmb3JtLlxuICAgICAqIEByZXR1cm5zIHtRdWVyeUdlb21ldHJ5fSBBbiBpbnN0YW5jZSBvZiB0aGUgUXVlcnlHZW9tZXRyeSBjbGFzcy5cbiAgICAgKi9cbiAgICBzdGF0aWMgY3JlYXRlRnJvbVNjcmVlblBvaW50cyhnZW9tZXRyeTogUG9pbnRMaWtlIHwgW1BvaW50TGlrZSwgUG9pbnRMaWtlXSwgdHJhbnNmb3JtOiBUcmFuc2Zvcm0pOiBRdWVyeUdlb21ldHJ5IHtcbiAgICAgICAgbGV0IHNjcmVlbkdlb21ldHJ5O1xuICAgICAgICBsZXQgYWJvdmVIb3Jpem9uO1xuXG4gICAgICAgIC8vICRGbG93Rml4TWU6IEZsb3cgY2FuJ3QgcmVmaW5lIHRoYXQgdGhpcyB3aWxsIGJlIFBvaW50TGlrZSBidXQgd2UgY2FuXG4gICAgICAgIGlmIChnZW9tZXRyeSBpbnN0YW5jZW9mIFBvaW50IHx8IHR5cGVvZiBnZW9tZXRyeVswXSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVcbiAgICAgICAgICAgIGNvbnN0IHB0ID0gUG9pbnQuY29udmVydChnZW9tZXRyeSk7XG4gICAgICAgICAgICBzY3JlZW5HZW9tZXRyeSA9IFtwdF07XG4gICAgICAgICAgICBhYm92ZUhvcml6b24gPSB0cmFuc2Zvcm0uaXNQb2ludEFib3ZlSG9yaXpvbihwdCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lXG4gICAgICAgICAgICBjb25zdCB0bCA9IFBvaW50LmNvbnZlcnQoZ2VvbWV0cnlbMF0pO1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVxuICAgICAgICAgICAgY29uc3QgYnIgPSBQb2ludC5jb252ZXJ0KGdlb21ldHJ5WzFdKTtcbiAgICAgICAgICAgIHNjcmVlbkdlb21ldHJ5ID0gW3RsLCBicl07XG4gICAgICAgICAgICBhYm92ZUhvcml6b24gPSBwb2x5Z29uaXplQm91bmRzKHRsLCBicikuZXZlcnkoKHApID0+IHRyYW5zZm9ybS5pc1BvaW50QWJvdmVIb3Jpem9uKHApKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXcgUXVlcnlHZW9tZXRyeShzY3JlZW5HZW9tZXRyeSwgdHJhbnNmb3JtLmdldENhbWVyYVBvaW50KCksIGFib3ZlSG9yaXpvbiwgdHJhbnNmb3JtKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGluaXRpYWwgcXVlcnkgYnkgdGhlIHVzZXIgd2FzIGEgc2luZ2xlIHBvaW50LlxuICAgICAqXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBpbml0aWFsIHF1ZXJ5IGdlb21ldHJ5IHdhcyBhIHNpbmdsZSBwb2ludC5cbiAgICAgKi9cbiAgICBpc1BvaW50UXVlcnkoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLnNjcmVlbkJvdW5kcy5sZW5ndGggPT09IDE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRHVlIHRvIGRhdGEtZHJpdmVuIHN0eWxpbmcgZmVhdHVyZXMgZG8gbm90IHVuaWZvcm0gc2l6ZShlZyBgY2lyY2xlLXJhZGl1c2ApIGFuZCBjYW4gYmUgb2Zmc2V0IGRpZmZlcm50bHlcbiAgICAgKiBmcm9tIHRoZWlyIG9yaWdpbmFsIGxvY2F0aW9uKGZvciBleGFtcGxlIHdpdGggYCotdHJhbnNsYXRlYCkuIFRoaXMgbWVhbnMgd2UgaGF2ZSB0byBleHBhbmQgb3VyIHF1ZXJ5IHJlZ2lvbiBmb3JcbiAgICAgKiBlYWNoIHRpbGUgdG8gYWNjb3VudCBmb3IgdmFyaWF0aW9uIGluIHRoZXNlIHByb3BlcnRpZXMuXG4gICAgICogRWFjaCB0aWxlIGNhbGN1bGF0ZXMgYSB0aWxlIGxldmVsIG1heCBwYWRkaW5nIHZhbHVlIChpbiBzY3JlZW5zcGFjZSBwaXhlbHMpIHdoZW4gaXRzIHBhcnNlZCwgdGhpcyBmdW5jdGlvblxuICAgICAqIGxldHMgdXMgY2FsY3VsYXRlIGEgYnVmZmVyZWQgdmVyc2lvbiBvZiB0aGUgc2NyZWVuc3BhY2UgcXVlcnkgZ2VvbWV0cnkgZm9yIGVhY2ggdGlsZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBidWZmZXIgVGhlIHRpbGUgcGFkZGluZyBpbiBzY3JlZW5zcGFjZSBwaXhlbHMuXG4gICAgICogQHJldHVybnMge1BvaW50W119IFRoZSBidWZmZXJlZCBxdWVyeSBnZW9tZXRyeS5cbiAgICAgKi9cbiAgICBidWZmZXJlZFNjcmVlbkdlb21ldHJ5KGJ1ZmZlcjogbnVtYmVyKTogUG9pbnRbXSB7XG4gICAgICAgIHJldHVybiBwb2x5Z29uaXplQm91bmRzKFxuICAgICAgICAgICAgdGhpcy5zY3JlZW5Cb3VuZHNbMF0sXG4gICAgICAgICAgICB0aGlzLnNjcmVlbkJvdW5kcy5sZW5ndGggPT09IDEgPyB0aGlzLnNjcmVlbkJvdW5kc1swXSA6IHRoaXMuc2NyZWVuQm91bmRzWzFdLFxuICAgICAgICAgICAgYnVmZmVyXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogV2hlbiB0aGUgbWFwIGlzIHBpdGNoZWQsIHNvbWUgb2YgdGhlIDNEIGZlYXR1cmVzIHRoYXQgaW50ZXJzZWN0IGEgcXVlcnkgd2lsbCBub3QgaW50ZXJzZWN0XG4gICAgICogdGhlIHF1ZXJ5IGF0IHRoZSBzdXJmYWNlIG9mIHRoZSBlYXJ0aC4gSW5zdGVhZCB0aGUgZmVhdHVyZSBtYXkgYmUgY2xvc2VyIGFuZCBvbmx5IGludGVyc2VjdFxuICAgICAqIHRoZSBxdWVyeSBiZWNhdXNlIGl0IGV4dHJ1ZGVzIGludG8gdGhlIGFpci5cbiAgICAgKlxuICAgICAqIFRoaXMgcmV0dXJucyBhIGdlb21ldHJ5IHRoYXQgaXMgYSBjb252ZXggcG9seWdvbiB0aGF0IGVuY29tcGFzc2VzIHRoZSBxdWVyeSBmcnVzdHVtIGFuZCB0aGUgcG9pbnQgdW5kZXJuZWF0aCB0aGUgY2FtZXJhLlxuICAgICAqIFNpbWlsYXIgdG8gYGJ1ZmZlcmVkU2NyZWVuR2VvbWV0cnlgLCBidWZmZXJpbmcgaXMgYWRkZWQgdG8gYWNjb3VudCBmb3IgdmFyaWF0aW9uIGluIHBhaW50IHByb3BlcnRpZXMuXG4gICAgICpcbiAgICAgKiBDYXNlIDE6IHBvaW50IHVuZGVybmVhdGggY2FtZXJhIGlzIGV4YWN0bHkgYmVoaW5kIHF1ZXJ5IHZvbHVtZVxuICAgICAqICAgICAgICAgICAgICArLS0tLS0tLS0tLStcbiAgICAgKiAgICAgICAgICAgICAgfCAgICAgICAgICB8XG4gICAgICogICAgICAgICAgICAgIHwgICAgICAgICAgfFxuICAgICAqICAgICAgICAgICAgICB8ICAgICAgICAgIHxcbiAgICAgKiAgICAgICAgICAgICAgKyAgICAgICAgICArXG4gICAgICogICAgICAgICAgICAgICBYICAgICAgICBYXG4gICAgICogICAgICAgICAgICAgICAgWCAgICAgIFhcbiAgICAgKiAgICAgICAgICAgICAgICAgWCAgICBYXG4gICAgICogICAgICAgICAgICAgICAgICBYICBYXG4gICAgICogICAgICAgICAgICAgICAgICAgWFguXG4gICAgICpcbiAgICAgKiBDYXNlIDI6IHBvaW50IGlzIGJlaGluZCBhbmQgdG8gdGhlIHJpZ2h0XG4gICAgICogICAgICAgICAgICAgICstLS0tLS0tLS0tK1xuICAgICAqICAgICAgICAgICAgICB8ICAgICAgICAgIFhcbiAgICAgKiAgICAgICAgICAgICAgfCAgICAgICAgICAgWFxuICAgICAqICAgICAgICAgICAgICB8ICAgICAgICAgICBYWFxuICAgICAqICAgICAgICAgICAgICArICAgICAgICAgICAgWFxuICAgICAqICAgICAgICAgICAgICBYWFggICAgICAgICAgWFhcbiAgICAgKiAgICAgICAgICAgICAgICAgWFhYWCAgICAgICBYXG4gICAgICogICAgICAgICAgICAgICAgICAgIFhYWCAgICAgWFhcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIFhYICAgWFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgWFhYLlxuICAgICAqXG4gICAgICogQ2FzZSAzOiBwb2ludCBpcyBiZWhpbmQgYW5kIHRvIHRoZSBsZWZ0XG4gICAgICogICAgICAgICAgICAgICstLS0tLS0tLS0tK1xuICAgICAqICAgICAgICAgICAgIFggICAgICAgICAgIHxcbiAgICAgKiAgICAgICAgICAgICBYICAgICAgICAgICB8XG4gICAgICogICAgICAgICAgICBYWCAgICAgICAgICAgfFxuICAgICAqICAgICAgICAgICAgWCAgICAgICAgICAgICtcbiAgICAgKiAgICAgICAgICAgWCAgICAgICAgICBYWFhYXG4gICAgICogICAgICAgICAgWFggICAgICAgWFhYXG4gICAgICogICAgICAgICAgWCAgICBYWFhYXG4gICAgICogICAgICAgICBYIFhYWFhcbiAgICAgKiAgICAgICAgIFhYWC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBidWZmZXIgVGhlIHRpbGUgcGFkZGluZyBpbiBzY3JlZW5zcGFjZSBwaXhlbHMuXG4gICAgICogQHJldHVybnMge1BvaW50W119IFRoZSBidWZmZXJlZCBxdWVyeSBnZW9tZXRyeS5cbiAgICAgKi9cbiAgICBidWZmZXJlZENhbWVyYUdlb21ldHJ5KGJ1ZmZlcjogbnVtYmVyKTogUG9pbnRbXSB7XG4gICAgICAgIGNvbnN0IG1pbiA9IHRoaXMuc2NyZWVuQm91bmRzWzBdO1xuICAgICAgICBjb25zdCBtYXggPSB0aGlzLnNjcmVlbkJvdW5kcy5sZW5ndGggPT09IDEgPyB0aGlzLnNjcmVlbkJvdW5kc1swXS5hZGQobmV3IFBvaW50KDEsIDEpKSA6IHRoaXMuc2NyZWVuQm91bmRzWzFdO1xuICAgICAgICBjb25zdCBjYW1lcmFQb2x5Z29uID0gcG9seWdvbml6ZUJvdW5kcyhtaW4sIG1heCwgMCwgZmFsc2UpO1xuXG4gICAgICAgIC8vIE9ubHkgbmVlZCB0byBhY2NvdW50IGZvciBwb2ludCB1bmRlcm5lYXRoIGNhbWVyYSBpZiBpdHMgYmVoaW5kIHF1ZXJ5IHZvbHVtZVxuICAgICAgICBpZiAodGhpcy5jYW1lcmFQb2ludC55ID4gbWF4LnkpIHtcbiAgICAgICAgICAgIC8vY2FzZSAxOiBpbnNlcnQgcG9pbnQgaW4gdGhlIG1pZGRsZVxuICAgICAgICAgICAgaWYgKHRoaXMuY2FtZXJhUG9pbnQueCA+IG1pbi54ICYmIHRoaXMuY2FtZXJhUG9pbnQueCA8IG1heC54KSB7XG4gICAgICAgICAgICAgICAgY2FtZXJhUG9seWdvbi5zcGxpY2UoMywgMCwgdGhpcy5jYW1lcmFQb2ludCk7XG4gICAgICAgICAgICAvL2Nhc2UgMjogcmVwbGFjZSBidG0gcmlnaHQgcG9pbnRcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5jYW1lcmFQb2ludC54ID49IG1heC54KSB7XG4gICAgICAgICAgICAgICAgY2FtZXJhUG9seWdvblsyXSA9IHRoaXMuY2FtZXJhUG9pbnQ7XG4gICAgICAgICAgICAvL2Nhc2UgMzogcmVwbGFjZSBidG0gbGVmdCBwb2ludFxuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmNhbWVyYVBvaW50LnggPD0gbWluLngpIHtcbiAgICAgICAgICAgICAgICBjYW1lcmFQb2x5Z29uWzNdID0gdGhpcy5jYW1lcmFQb2ludDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBidWZmZXJDb252ZXhQb2x5Z29uKGNhbWVyYVBvbHlnb24sIGJ1ZmZlcik7XG4gICAgfVxuXG4gICAgLy8gQ3JlYXRlcyBhIGNvbnZleCBwb2x5Z29uIGluIHNjcmVlbiBjb29yZGluYXRlcyB0aGF0IGVuY29tcGFzc2VzIHRoZSBxdWVyeSBmcnVzdHVtIGFuZFxuICAgIC8vIHRoZSBjYW1lcmEgbG9jYXRpb24gYXQgZ2xvYmUncyBzdXJmYWNlLiBDYW1lcmEgcG9pbnQgY2FuIGJlIGF0IGFueSBzaWRlIG9mIHRoZSBxdWVyeSBwb2x5Z29uIGFzXG4gICAgLy8gb3Bwb3NlZCB0byBgYnVmZmVyZWRDYW1lcmFHZW9tZXRyeWAgd2hpY2ggcmVzdHJpY3RzIHRoZSBsb2NhdGlvbiB0byB1bmRlcm5lYXRoIHRoZSBwb2x5Z29uLlxuICAgIGJ1ZmZlcmVkQ2FtZXJhR2VvbWV0cnlHbG9iZShidWZmZXI6IG51bWJlcik6IFBvaW50W10ge1xuICAgICAgICBjb25zdCBtaW4gPSB0aGlzLnNjcmVlbkJvdW5kc1swXTtcbiAgICAgICAgY29uc3QgbWF4ID0gdGhpcy5zY3JlZW5Cb3VuZHMubGVuZ3RoID09PSAxID8gdGhpcy5zY3JlZW5Cb3VuZHNbMF0uYWRkKG5ldyBQb2ludCgxLCAxKSkgOiB0aGlzLnNjcmVlbkJvdW5kc1sxXTtcblxuICAgICAgICAvLyBQYWRkaW5nIGlzIGFkZGVkIHRvIHRoZSBxdWVyeSBwb2x5Z29uIGJlZm9yZSBpbmNsdXNpb24gb2YgdGhlIGNhbWVyYSBsb2NhdGlvbi5cbiAgICAgICAgLy8gT3RoZXJ3aXNlIHRoZSBidWZmZXJlZCAobmFycm93KSBwb2x5Z29uIGNvdWxkIHBlbmV0cmF0ZSB0aGUgZ2xvYmUgY3JlYXRpbmcgYSBsb3Qgb2YgZmFsc2UgcG9zaXRpdmVzXG4gICAgICAgIGNvbnN0IGNhbWVyYVBvbHlnb24gPSBwb2x5Z29uaXplQm91bmRzKG1pbiwgbWF4LCBidWZmZXIpO1xuXG4gICAgICAgIGNvbnN0IGNhbVBvcyA9IHRoaXMuY2FtZXJhUG9pbnQuY2xvbmUoKTtcbiAgICAgICAgY29uc3QgY29sdW1uID0gKGNhbVBvcy54ID4gbWluLngpICsgKGNhbVBvcy54ID4gbWF4LngpO1xuICAgICAgICBjb25zdCByb3cgPSAoY2FtUG9zLnkgPiBtaW4ueSkgKyAoY2FtUG9zLnkgPiBtYXgueSk7XG4gICAgICAgIGNvbnN0IHNlY3RvciA9IHJvdyAqIDMgKyBjb2x1bW47XG5cbiAgICAgICAgc3dpdGNoIChzZWN0b3IpIHtcbiAgICAgICAgY2FzZSAwOiAgICAgLy8gcmVwbGFjZSB0b3AtbGVmdCBwb2ludCAoY2xvc2VkIHBvbHlnb24pXG4gICAgICAgICAgICBjYW1lcmFQb2x5Z29uWzBdID0gY2FtUG9zO1xuICAgICAgICAgICAgY2FtZXJhUG9seWdvbls0XSA9IGNhbVBvcy5jbG9uZSgpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMTogICAgIC8vIGluc2VydCBwb2ludCBpbiB0aGUgbWlkZGxlIG9mIHRvcC1sZWZ0IGFuZCB0b3AtcmlnaHRcbiAgICAgICAgICAgIGNhbWVyYVBvbHlnb24uc3BsaWNlKDEsIDAsIGNhbVBvcyk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAyOiAgICAgLy8gcmVwbGFjZSB0b3AtcmlnaHQgcG9pbnRcbiAgICAgICAgICAgIGNhbWVyYVBvbHlnb25bMV0gPSBjYW1Qb3M7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAzOiAgICAgLy8gaW5zZXJ0IHBvaW50IGluIHRoZSBtaWRkbGUgb2YgdG9wLWxlZnQgYW5kIGJvdHRvbS1sZWZ0XG4gICAgICAgICAgICBjYW1lcmFQb2x5Z29uLnNwbGljZSg0LCAwLCBjYW1Qb3MpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgNTogICAgIC8vIGluc2VydCBwb2ludCBpbiB0aGUgbWlkZGxlIG9mIHRvcC1yaWdodCBhbmQgYm90dG9tLXJpZ2h0XG4gICAgICAgICAgICBjYW1lcmFQb2x5Z29uLnNwbGljZSgyLCAwLCBjYW1Qb3MpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgNjogICAgIC8vIHJlcGxhY2UgYm90dG9tLWxlZnQgcG9pbnRcbiAgICAgICAgICAgIGNhbWVyYVBvbHlnb25bM10gPSBjYW1Qb3M7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSA3OiAgICAgLy8gaW5zZXJ0IHBvaW50IGluIHRoZSBtaWRkbGUgb2YgYm90dG9tLWxlZnQgYW5kIGJvdHRvbS1yaWdodFxuICAgICAgICAgICAgY2FtZXJhUG9seWdvbi5zcGxpY2UoMywgMCwgY2FtUG9zKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDg6ICAgICAvLyByZXBsYWNlIGJvdHRvbS1yaWdodCBwb2ludFxuICAgICAgICAgICAgY2FtZXJhUG9seWdvblsyXSA9IGNhbVBvcztcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNhbWVyYVBvbHlnb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGEgdGlsZSBpcyBjb250YWluZWQgd2l0aGluIHRoaXMgcXVlcnkgZ2VvbWV0cnkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1RpbGV9IHRpbGUgVGhlIHRpbGUgdG8gY2hlY2suXG4gICAgICogQHBhcmFtIHtUcmFuc2Zvcm19IHRyYW5zZm9ybSBUaGUgY3VycmVudCBtYXAgdHJhbnNmb3JtLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gdXNlM0QgQSBib29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0byBxdWVyeSAzRCBmZWF0dXJlcy5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gY2FtZXJhV3JhcCBBIHdyYXAgdmFsdWUgZm9yIG9mZnNldHRpbmcgdGhlIGNhbWVyYSBwb3NpdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7P1RpbGVzcGFjZVF1ZXJ5R2VvbWV0cnl9IFJldHVybnMgYHVuZGVmaW5lZGAgaWYgdGhlIHRpbGUgZG9lcyBub3QgaW50ZXJzZWN0LlxuICAgICAqL1xuICAgIGNvbnRhaW5zVGlsZSh0aWxlOiBUaWxlLCB0cmFuc2Zvcm06IFRyYW5zZm9ybSwgdXNlM0Q6IGJvb2xlYW4sIGNhbWVyYVdyYXA6IG51bWJlciA9IDApOiA/VGlsZXNwYWNlUXVlcnlHZW9tZXRyeSB7XG4gICAgICAgIC8vIFRoZSBidWZmZXIgYXJvdW5kIHRoZSBxdWVyeSBnZW9tZXRyeSBpcyBhcHBsaWVkIGluIHNjcmVlbi1zcGFjZS5cbiAgICAgICAgLy8gdHJhbnNmb3JtLl9waXhlbHNQZXJNZXJjYXRvclBpeGVsIGlzIHVzZWQgdG8gY29tcGVuc2F0ZSBhbnkgZXh0cmEgc2NhbGluZyBhcHBsaWVkIGZyb20gdGhlIGN1cnJlbnRseSBhY3RpdmUgcHJvamVjdGlvbi5cbiAgICAgICAgLy8gRmxvYXRpbmcgcG9pbnQgZXJyb3JzIHdoZW4gcHJvamVjdGluZyBpbnRvIHRpbGVzcGFjZSBjb3VsZCBsZWF2ZSBhIGZlYXR1cmVcbiAgICAgICAgLy8gb3V0c2lkZSB0aGUgcXVlcnkgdm9sdW1lIGV2ZW4gaWYgaXQgbG9va3MgbGlrZSBpdCBvdmVybGFwcyB2aXN1YWxseSwgYSAxcHggYmlhcyB2YWx1ZSBvdmVyY29tZXMgdGhhdC5cbiAgICAgICAgY29uc3QgYmlhcyA9IDE7XG4gICAgICAgIGNvbnN0IHBhZGRpbmcgPSB0aWxlLnF1ZXJ5UGFkZGluZyAvIHRyYW5zZm9ybS5fcGl4ZWxzUGVyTWVyY2F0b3JQaXhlbCArIGJpYXM7XG5cbiAgICAgICAgY29uc3QgY2FjaGVkUXVlcnkgPSB1c2UzRCA/XG4gICAgICAgICAgICB0aGlzLl9idWZmZXJlZENhbWVyYU1lcmNhdG9yKHBhZGRpbmcsIHRyYW5zZm9ybSkgOlxuICAgICAgICAgICAgdGhpcy5fYnVmZmVyZWRTY3JlZW5NZXJjYXRvcihwYWRkaW5nLCB0cmFuc2Zvcm0pO1xuXG4gICAgICAgIGxldCB3cmFwID0gdGlsZS50aWxlSUQud3JhcCArIChjYWNoZWRRdWVyeS51bndyYXBwZWQgPyBjYW1lcmFXcmFwIDogMCk7XG4gICAgICAgIGNvbnN0IGdlb21ldHJ5Rm9yVGlsZUNoZWNrID0gY2FjaGVkUXVlcnkucG9seWdvbi5tYXAoKHApID0+IGdldFRpbGVQb2ludCh0aWxlLnRpbGVUcmFuc2Zvcm0sIHAsIHdyYXApKTtcblxuICAgICAgICBpZiAoIXBvbHlnb25JbnRlcnNlY3RzQm94KGdlb21ldHJ5Rm9yVGlsZUNoZWNrLCAwLCAwLCBFWFRFTlQsIEVYVEVOVCkpIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICB3cmFwID0gdGlsZS50aWxlSUQud3JhcCArICh0aGlzLnNjcmVlbkdlb21ldHJ5TWVyY2F0b3IudW53cmFwcGVkID8gY2FtZXJhV3JhcCA6IDApO1xuICAgICAgICBjb25zdCB0aWxlc3BhY2VWZWMzcyA9IHRoaXMuc2NyZWVuR2VvbWV0cnlNZXJjYXRvci5wb2x5Z29uLm1hcCgocCkgPT4gZ2V0VGlsZVZlYzModGlsZS50aWxlVHJhbnNmb3JtLCBwLCB3cmFwKSk7XG4gICAgICAgIGNvbnN0IHRpbGVzcGFjZUdlb21ldHJ5ID0gdGlsZXNwYWNlVmVjM3MubWFwKCh2KSA9PiBuZXcgUG9pbnQodlswXSwgdlsxXSkpO1xuXG4gICAgICAgIGNvbnN0IGNhbWVyYU1lcmNhdG9yID0gdHJhbnNmb3JtLmdldEZyZWVDYW1lcmFPcHRpb25zKCkucG9zaXRpb24gfHwgbmV3IE1lcmNhdG9yQ29vcmRpbmF0ZSgwLCAwLCAwKTtcbiAgICAgICAgY29uc3QgdGlsZXNwYWNlQ2FtZXJhUG9zaXRpb24gPSBnZXRUaWxlVmVjMyh0aWxlLnRpbGVUcmFuc2Zvcm0sIGNhbWVyYU1lcmNhdG9yLCB3cmFwKTtcbiAgICAgICAgY29uc3QgdGlsZXNwYWNlUmF5cyA9IHRpbGVzcGFjZVZlYzNzLm1hcCgodGlsZVZlYykgPT4ge1xuICAgICAgICAgICAgY29uc3QgZGlyID0gdmVjMy5zdWIodGlsZVZlYywgdGlsZVZlYywgdGlsZXNwYWNlQ2FtZXJhUG9zaXRpb24pO1xuICAgICAgICAgICAgdmVjMy5ub3JtYWxpemUoZGlyLCBkaXIpO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBSYXkodGlsZXNwYWNlQ2FtZXJhUG9zaXRpb24sIGRpcik7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBwaXhlbFRvVGlsZVVuaXRzRmFjdG9yID0gcGl4ZWxzVG9UaWxlVW5pdHModGlsZSwgMSwgdHJhbnNmb3JtLnpvb20pICogdHJhbnNmb3JtLl9waXhlbHNQZXJNZXJjYXRvclBpeGVsO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBxdWVyeUdlb21ldHJ5OiB0aGlzLFxuICAgICAgICAgICAgdGlsZXNwYWNlR2VvbWV0cnksXG4gICAgICAgICAgICB0aWxlc3BhY2VSYXlzLFxuICAgICAgICAgICAgYnVmZmVyZWRUaWxlc3BhY2VHZW9tZXRyeTogZ2VvbWV0cnlGb3JUaWxlQ2hlY2ssXG4gICAgICAgICAgICBidWZmZXJlZFRpbGVzcGFjZUJvdW5kczogY2xhbXBCb3VuZHNUb1RpbGVFeHRlbnRzKGdldEJvdW5kcyhnZW9tZXRyeUZvclRpbGVDaGVjaykpLFxuICAgICAgICAgICAgdGlsZSxcbiAgICAgICAgICAgIHRpbGVJRDogdGlsZS50aWxlSUQsXG4gICAgICAgICAgICBwaXhlbFRvVGlsZVVuaXRzRmFjdG9yXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlc2UgbWV0aG9kcyBhZGQgY2FjaGluZyBvbiB0b3Agb2YgdGhlIHRlcnJhaW4gcmF5Y2FzdGluZyBwcm92aWRlZCBieSBgVHJhbnNmb3JtI3BvaW50Q29vcmRpbmF0ZTNkYC5cbiAgICAgKiBUaWxlcyBjb21lIHdpdGggZGlmZmVyZW50IHZhbHVlcyBvZiBwYWRkaW5nLCBob3dldmVyIGl0cyB2ZXJ5IGxpa2VseSB0aGF0IG11bHRpcGxlIHRpbGVzIHNoYXJlIHRoZSBzYW1lIHZhbHVlIG9mIHBhZGRpbmdcbiAgICAgKiBiYXNlZCBvbiB0aGUgc3R5bGUuIEluIHRoYXQgY2FzZSB3ZSB3YW50IHRvIHJldXNlIHRoZSByZXN1bHQgZnJvbSBhIHByZXZpb3VzbHkgY29tcHV0ZWQgdGVycmFpbiByYXljYXN0LlxuICAgICAqL1xuXG4gICAgX2J1ZmZlcmVkU2NyZWVuTWVyY2F0b3IocGFkZGluZzogbnVtYmVyLCB0cmFuc2Zvcm06IFRyYW5zZm9ybSk6IENhY2hlZFBvbHlnb24ge1xuICAgICAgICBjb25zdCBrZXkgPSBjYWNoZUtleShwYWRkaW5nKTtcbiAgICAgICAgaWYgKHRoaXMuX3NjcmVlblJheWNhc3RDYWNoZVtrZXldKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc2NyZWVuUmF5Y2FzdENhY2hlW2tleV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsZXQgcG9seTogQ2FjaGVkUG9seWdvbjtcblxuICAgICAgICAgICAgaWYgKHRyYW5zZm9ybS5wcm9qZWN0aW9uLm5hbWUgPT09ICdnbG9iZScpIHtcbiAgICAgICAgICAgICAgICBwb2x5ID0gdGhpcy5fcHJvamVjdEFuZFJlc2FtcGxlKHRoaXMuYnVmZmVyZWRTY3JlZW5HZW9tZXRyeShwYWRkaW5nKSwgdHJhbnNmb3JtKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcG9seSA9IHtcbiAgICAgICAgICAgICAgICAgICAgcG9seWdvbjogdGhpcy5idWZmZXJlZFNjcmVlbkdlb21ldHJ5KHBhZGRpbmcpLm1hcCgocCkgPT4gdHJhbnNmb3JtLnBvaW50Q29vcmRpbmF0ZTNEKHApKSxcbiAgICAgICAgICAgICAgICAgICAgdW53cmFwcGVkOiB0cnVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5fc2NyZWVuUmF5Y2FzdENhY2hlW2tleV0gPSBwb2x5O1xuICAgICAgICAgICAgcmV0dXJuIHBvbHk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfYnVmZmVyZWRDYW1lcmFNZXJjYXRvcihwYWRkaW5nOiBudW1iZXIsIHRyYW5zZm9ybTogVHJhbnNmb3JtKTogQ2FjaGVkUG9seWdvbiB7XG4gICAgICAgIGNvbnN0IGtleSA9IGNhY2hlS2V5KHBhZGRpbmcpO1xuICAgICAgICBpZiAodGhpcy5fY2FtZXJhUmF5Y2FzdENhY2hlW2tleV0pIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jYW1lcmFSYXljYXN0Q2FjaGVba2V5XTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxldCBwb2x5OiBDYWNoZWRQb2x5Z29uO1xuXG4gICAgICAgICAgICBpZiAodHJhbnNmb3JtLnByb2plY3Rpb24ubmFtZSA9PT0gJ2dsb2JlJykge1xuICAgICAgICAgICAgICAgIHBvbHkgPSB0aGlzLl9wcm9qZWN0QW5kUmVzYW1wbGUodGhpcy5idWZmZXJlZENhbWVyYUdlb21ldHJ5R2xvYmUocGFkZGluZyksIHRyYW5zZm9ybSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHBvbHkgPSB7XG4gICAgICAgICAgICAgICAgICAgIHBvbHlnb246IHRoaXMuYnVmZmVyZWRDYW1lcmFHZW9tZXRyeShwYWRkaW5nKS5tYXAoKHApID0+IHRyYW5zZm9ybS5wb2ludENvb3JkaW5hdGUzRChwKSksXG4gICAgICAgICAgICAgICAgICAgIHVud3JhcHBlZDogdHJ1ZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuX2NhbWVyYVJheWNhc3RDYWNoZVtrZXldID0gcG9seTtcbiAgICAgICAgICAgIHJldHVybiBwb2x5O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX3Byb2plY3RBbmRSZXNhbXBsZShwb2x5Z29uOiBQb2ludFtdLCB0cmFuc2Zvcm06IFRyYW5zZm9ybSk6IENhY2hlZFBvbHlnb24ge1xuICAgICAgICAvLyBIYW5kbGUgYSBzcGVjaWFsIGNhc2Ugd2hlcmUgZWl0aGVyIG5vcnRoIG9yIHNvdXRoIHBvbGUgaXMgaW5zaWRlIHRoZSBxdWVyeSBwb2x5Z29uXG4gICAgICAgIGNvbnN0IHBvbGVQb2x5Z29uOiA/Q2FjaGVkUG9seWdvbiA9IHByb2plY3RQb2x5Z29uQ292ZXJpbmdQb2xlcyhwb2x5Z29uLCB0cmFuc2Zvcm0pO1xuXG4gICAgICAgIGlmIChwb2xlUG9seWdvbikge1xuICAgICAgICAgICAgcmV0dXJuIHBvbGVQb2x5Z29uO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVzYW1wbGUgdGhlIHBvbHlnb24gYnkgYWRkaW5nIGludGVybWVkaWF0ZSBwb2ludHMgc28gdGhhdCBzdHJhaWdodCBsaW5lcyBvZiB0aGUgc2hhcGVcbiAgICAgICAgLy8gYXJlIGNvcnJlY3RseSBwcm9qZWN0ZWQgb24gdGhlIHN1cmZhY2Ugb2YgdGhlIGdsb2JlLlxuICAgICAgICBjb25zdCByZXNhbXBsZWQgPSB1bndyYXBRdWVyeVBvbHlnb24ocmVzYW1wbGVQb2x5Z29uKHBvbHlnb24sIHRyYW5zZm9ybSkubWFwKHAgPT4gbmV3IFBvaW50KHdyYXAocC54KSwgcC55KSksIHRyYW5zZm9ybSk7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHBvbHlnb246IHJlc2FtcGxlZC5wb2x5Z29uLm1hcChwID0+IG5ldyBNZXJjYXRvckNvb3JkaW5hdGUocC54LCBwLnkpKSxcbiAgICAgICAgICAgIHVud3JhcHBlZDogcmVzYW1wbGVkLnVud3JhcHBlZFxuICAgICAgICB9O1xuICAgIH1cbn1cblxuLy8gQ2hlY2tzIHdoZXRoZXIgdGhlIHByb3ZpZGVkIHBvbHlnb24gaXMgY3Jvc3NpbmcgdGhlIGFudGltZXJpZGlhbiBsaW5lIGFuZCB1bndyYXBzIGl0IGlmIG5lY2Vzc2FyeS5cbi8vIFRoZSByZXN1bHRpbmcgcG9seWdvbiBpcyBjb250aW51b3VzXG5leHBvcnQgZnVuY3Rpb24gdW53cmFwUXVlcnlQb2x5Z29uKHBvbHlnb246IFBvaW50W10sIHRyOiBUcmFuc2Zvcm0pOiB7cG9seWdvbjogUG9pbnRbXSwgdW53cmFwcGVkOiBib29sZWFufSB7XG4gICAgbGV0IHVud3JhcHBlZCA9IGZhbHNlO1xuXG4gICAgLy8gVHJhdmVyc2UgZWRnZXMgb2YgdGhlIHBvbHlnb24gYW5kIHVud3JhcCB2ZXJ0aWNlcyB0aGF0IGFyZSBjcm9zc2luZyB0aGUgYW50aW1lcmlkaWFuLlxuICAgIGxldCBtYXhYID0gLUluZmluaXR5O1xuICAgIGxldCBzdGFydEVkZ2UgPSAwO1xuXG4gICAgZm9yIChsZXQgZSA9IDA7IGUgPCBwb2x5Z29uLmxlbmd0aCAtIDE7IGUrKykge1xuICAgICAgICBpZiAocG9seWdvbltlXS54ID4gbWF4WCkge1xuICAgICAgICAgICAgbWF4WCA9IHBvbHlnb25bZV0ueDtcbiAgICAgICAgICAgIHN0YXJ0RWRnZSA9IGU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBvbHlnb24ubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGVkZ2UgPSAoc3RhcnRFZGdlICsgaSkgJSAocG9seWdvbi5sZW5ndGggLSAxKTtcbiAgICAgICAgY29uc3QgYSA9IHBvbHlnb25bZWRnZV07XG4gICAgICAgIGNvbnN0IGIgPSBwb2x5Z29uW2VkZ2UgKyAxXTtcblxuICAgICAgICBpZiAoTWF0aC5hYnMoYS54IC0gYi54KSA+IDAuNSkge1xuICAgICAgICAgICAgLy8gQSBzdHJhaWdodCBsaW5lIGRyYXduIG9uIHRoZSBnbG9iZSBjYW4ndCBoYXZlIGxvbmdlciBsZW5ndGggdGhhbiAwLjUgb24gdGhlIHgtYXhpc1xuICAgICAgICAgICAgLy8gd2l0aG91dCBjcm9zc2luZyB0aGUgYW50aW1lcmlkaWFuXG4gICAgICAgICAgICBpZiAoYS54IDwgYi54KSB7XG4gICAgICAgICAgICAgICAgYS54ICs9IDE7XG5cbiAgICAgICAgICAgICAgICBpZiAoZWRnZSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBGaXJzdCBhbmQgbGFzdCBwb2ludHMgYXJlIGR1cGxpY2F0ZSBmb3IgY2xvc2VkIHBvbHlnb25zXG4gICAgICAgICAgICAgICAgICAgIHBvbHlnb25bcG9seWdvbi5sZW5ndGggLSAxXS54ICs9IDE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBiLnggKz0gMTtcblxuICAgICAgICAgICAgICAgIGlmIChlZGdlICsgMSA9PT0gcG9seWdvbi5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIHBvbHlnb25bMF0ueCArPSAxO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdW53cmFwcGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGNhbWVyYVggPSBtZXJjYXRvclhmcm9tTG5nKHRyLmNlbnRlci5sbmcpO1xuICAgIGlmICh1bndyYXBwZWQgJiYgY2FtZXJhWCA8IE1hdGguYWJzKGNhbWVyYVggLSAxKSkge1xuICAgICAgICBwb2x5Z29uLmZvckVhY2gocCA9PiB7IHAueCAtPSAxOyB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBwb2x5Z29uLFxuICAgICAgICB1bndyYXBwZWRcbiAgICB9O1xufVxuXG4vLyBTcGVjaWFsIGZ1bmN0aW9uIGZvciBoYW5kbGluZyBzY2VuYXJpb3Mgd2hlcmUgb25lIG9mIHRoZSBwb2xlcyBpcyBpbnNpZGUgdGhlIHF1ZXJ5IHBvbHlnb24uXG4vLyBGaW5kaW5nIHByb2plY3Rpb24gb2YgdGhlc2Uga2luZCBvZiBwb2x5Z29ucyBpcyBtb3JlIGludm9sdmluZyBhcyBwcm9qZWN0aW5nIGp1c3QgdGhlIGNvcm5lcnMgd2lsbFxuLy8gcHJvZHVjZSBhIGRlZ2VuZXJhdGUgKHNlbGYtaW50ZXJzZWN0aW5nLCBub24tY29udGludW91cywgZXRjLikgcG9seWdvbiBpbiBtZXJjYXRvciBjb29yZGluYXRlc1xuZXhwb3J0IGZ1bmN0aW9uIHByb2plY3RQb2x5Z29uQ292ZXJpbmdQb2xlcyhwb2x5Z29uOiBQb2ludFtdLCB0cjogVHJhbnNmb3JtKTogP0NhY2hlZFBvbHlnb24ge1xuICAgIGNvbnN0IG1hdHJpeCA9IG1hdDQubXVsdGlwbHkoW10sIHRyLnBpeGVsTWF0cml4LCB0ci5nbG9iZU1hdHJpeCk7XG5cbiAgICAvLyBUcmFuc2Zvcm0gbm9ydGggYW5kIHNvdXRoIHBvbGUgY29vcmRpbmF0ZXMgdG8gdGhlIHNjcmVlbiB0byBzZWUgaWYgdGhleSdyZVxuICAgIC8vIGluc2lkZSB0aGUgcXVlcnkgcG9seWdvblxuICAgIGNvbnN0IG5vcnRoUG9sZSA9IFswLCAtR0xPQkVfUkFESVVTLCAwLCAxXTtcbiAgICBjb25zdCBzb3V0aFBvbGUgPSBbMCwgR0xPQkVfUkFESVVTLCAwLCAxXTtcbiAgICBjb25zdCBjZW50ZXIgPSBbMCwgMCwgMCwgMV07XG5cbiAgICB2ZWM0LnRyYW5zZm9ybU1hdDQobm9ydGhQb2xlLCBub3J0aFBvbGUsIG1hdHJpeCk7XG4gICAgdmVjNC50cmFuc2Zvcm1NYXQ0KHNvdXRoUG9sZSwgc291dGhQb2xlLCBtYXRyaXgpO1xuICAgIHZlYzQudHJhbnNmb3JtTWF0NChjZW50ZXIsIGNlbnRlciwgbWF0cml4KTtcblxuICAgIGNvbnN0IHNjcmVlbk5wID0gbmV3IFBvaW50KG5vcnRoUG9sZVswXSAvIG5vcnRoUG9sZVszXSwgbm9ydGhQb2xlWzFdIC8gbm9ydGhQb2xlWzNdKTtcbiAgICBjb25zdCBzY3JlZW5TcCA9IG5ldyBQb2ludChzb3V0aFBvbGVbMF0gLyBzb3V0aFBvbGVbM10sIHNvdXRoUG9sZVsxXSAvIHNvdXRoUG9sZVszXSk7XG4gICAgY29uc3QgY29udGFpbnNOcCA9IHBvbHlnb25Db250YWluc1BvaW50KHBvbHlnb24sIHNjcmVlbk5wKSAmJiBub3J0aFBvbGVbM10gPCBjZW50ZXJbM107XG4gICAgY29uc3QgY29udGFpbnNTcCA9IHBvbHlnb25Db250YWluc1BvaW50KHBvbHlnb24sIHNjcmVlblNwKSAmJiBzb3V0aFBvbGVbM10gPCBjZW50ZXJbM107XG5cbiAgICBpZiAoIWNvbnRhaW5zTnAgJiYgIWNvbnRhaW5zU3ApIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy8gUHJvamVjdCBjb3JuZXIgcG9pbnRzIG9mIHRoZSBwb2x5Z29uIGFuZCB0cmF2ZXJzZSB0aGUgcmluZyB0byBmaW5kIHRoZSBlZGdlIHRoYXQnc1xuICAgIC8vIGNyb3NzaW5nIHRoZSB6ZXJvIGxvbmdpdHVkZSBib3JkZXIuXG4gICAgY29uc3QgcmVzdWx0ID0gZmluZEVkZ2VDcm9zc2luZ0FudGltZXJpZGlhbihwb2x5Z29uLCB0ciwgY29udGFpbnNOcCA/IC0xIDogMSk7XG5cbiAgICBpZiAoIXJlc3VsdCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICAvLyBTdGFydCBjb25zdHJ1Y3RpbmcgdGhlIG5ldyBwb2x5Z29uIGJ5IHJlc2FtcGxpbmcgZWRnZXMgdW50aWwgdGhlIGNyb3NzaW5nIGVkZ2VcbiAgICBjb25zdCB7aWR4LCB0fSA9IHJlc3VsdDtcbiAgICBsZXQgcGFydEEgPSBpZHggPiAxID8gcmVzYW1wbGVQb2x5Z29uKHBvbHlnb24uc2xpY2UoMCwgaWR4KSwgdHIpIDogW107XG4gICAgbGV0IHBhcnRCID0gaWR4IDwgcG9seWdvbi5sZW5ndGggPyByZXNhbXBsZVBvbHlnb24ocG9seWdvbi5zbGljZShpZHgpLCB0cikgOiBbXTtcblxuICAgIHBhcnRBID0gcGFydEEubWFwKHAgPT4gbmV3IFBvaW50KHdyYXAocC54KSwgcC55KSk7XG4gICAgcGFydEIgPSBwYXJ0Qi5tYXAocCA9PiBuZXcgUG9pbnQod3JhcChwLngpLCBwLnkpKTtcblxuICAgIC8vIFJlc2FtcGxlIGZpcnN0IHNlY3Rpb24gb2YgdGhlIHJpbmcgKHVwIHRvIHRoZSBlZGdlIHRoYXQgY3Jvc3NlcyB0aGUgMC1saW5lKVxuICAgIGNvbnN0IHJlc2FtcGxlZCA9IFsuLi5wYXJ0QV07XG5cbiAgICBpZiAocmVzYW1wbGVkLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXNhbXBsZWQucHVzaChwYXJ0QltwYXJ0Qi5sZW5ndGggLSAxXSk7XG4gICAgfVxuXG4gICAgLy8gRmluZCBsb2NhdGlvbiBvZiB0aGUgY3Jvc3NpbmcgYnkgaW50ZXJwb2xhdGluZyBtZXJjYXRvciBjb29yZGluYXRlcy5cbiAgICAvLyBUaGlzIHdpbGwgcHJvZHVjZSBzbGlnaHRseSBvZmYgcmVzdWx0IGFzIHRoZSBjcm9zc2luZyBlZGdlIGlzIG5vdCBhY3R1YWxseVxuICAgIC8vIGxpbmVhciBvbiB0aGUgZ2xvYmUuXG4gICAgY29uc3QgYSA9IHJlc2FtcGxlZFtyZXNhbXBsZWQubGVuZ3RoIC0gMV07XG4gICAgY29uc3QgYiA9IHBhcnRCLmxlbmd0aCA9PT0gMCA/IHBhcnRBWzBdIDogcGFydEJbMF07XG4gICAgY29uc3QgaW50ZXJzZWN0aW9uWSA9IGludGVycG9sYXRlKGEueSwgYi55LCB0KTtcblxuICAgIGxldCBtaWQ7XG5cbiAgICBpZiAoY29udGFpbnNOcCkge1xuICAgICAgICBtaWQgPSBbXG4gICAgICAgICAgICBuZXcgUG9pbnQoMCwgaW50ZXJzZWN0aW9uWSksXG4gICAgICAgICAgICBuZXcgUG9pbnQoMCwgMCksXG4gICAgICAgICAgICBuZXcgUG9pbnQoMSwgMCksXG4gICAgICAgICAgICBuZXcgUG9pbnQoMSwgaW50ZXJzZWN0aW9uWSlcbiAgICAgICAgXTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBtaWQgPSBbXG4gICAgICAgICAgICBuZXcgUG9pbnQoMSwgaW50ZXJzZWN0aW9uWSksXG4gICAgICAgICAgICBuZXcgUG9pbnQoMSwgMSksXG4gICAgICAgICAgICBuZXcgUG9pbnQoMCwgMSksXG4gICAgICAgICAgICBuZXcgUG9pbnQoMCwgaW50ZXJzZWN0aW9uWSlcbiAgICAgICAgXTtcbiAgICB9XG5cbiAgICByZXNhbXBsZWQucHVzaCguLi5taWQpO1xuXG4gICAgLy8gUmVzYW1wbGUgdG8gdGhlIHNlY29uZCBzZWN0aW9uIG9mIHRoZSByaW5nXG4gICAgaWYgKHBhcnRCLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXNhbXBsZWQucHVzaChwYXJ0QVswXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmVzYW1wbGVkLnB1c2goLi4ucGFydEIpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIHBvbHlnb246IHJlc2FtcGxlZC5tYXAocCA9PiBuZXcgTWVyY2F0b3JDb29yZGluYXRlKHAueCwgcC55KSksXG4gICAgICAgIHVud3JhcHBlZDogZmFsc2VcbiAgICB9O1xufVxuXG5mdW5jdGlvbiByZXNhbXBsZVBvbHlnb24ocG9seWdvbjogUG9pbnRbXSwgdHJhbnNmb3JtOiBUcmFuc2Zvcm0pOiBQb2ludFtdIHtcbiAgICAvLyBDaG9vc2UgYSB0b2xlcmFuY2UgdmFsdWUgZm9yIHRoZSByZXNhbXBsaW5nIGxvZ2ljIHRoYXQgcHJvZHVjZXMgc3VmZmljaWVudGx5XG4gICAgLy8gYWNjdXJhdGUgcG9seWdvbnMgd2l0aG91dCBjcmVhdGluZyB0b28gbWFueSBwb2ludHMuIFRoZSB2YWx1ZSAxIC8gMjU2IHdhcyBjaG9zZW5cbiAgICAvLyBiYXNlZCBvbiBlbXBpcmljYWwgdGVzdGluZ1xuICAgIGNvbnN0IHRvbGVyYW5jZSA9IDEuMCAvIDI1Ni4wO1xuICAgIHJldHVybiByZXNhbXBsZShcbiAgICAgICAgcG9seWdvbixcbiAgICAgICAgcCA9PiB7XG4gICAgICAgICAgICBjb25zdCBtYyA9IHRyYW5zZm9ybS5wb2ludENvb3JkaW5hdGUzRChwKTtcbiAgICAgICAgICAgIHAueCA9IG1jLng7XG4gICAgICAgICAgICBwLnkgPSBtYy55O1xuICAgICAgICB9LFxuICAgICAgICB0b2xlcmFuY2UpO1xufVxuXG5mdW5jdGlvbiB3cmFwKG1lcmNhdG9yWDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gbWVyY2F0b3JYIDwgMCA/IDEgKyAobWVyY2F0b3JYICUgMSkgOiBtZXJjYXRvclggJSAxO1xufVxuXG5mdW5jdGlvbiBmaW5kRWRnZUNyb3NzaW5nQW50aW1lcmlkaWFuKHBvbHlnb246IFBvaW50W10sIHRyOiBUcmFuc2Zvcm0sIGRpcmVjdGlvbjogbnVtYmVyKTogP3tpZHg6IG51bWJlciwgdDogbnVtYmVyfSB7XG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPCBwb2x5Z29uLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGEgPSB3cmFwKHRyLnBvaW50Q29vcmRpbmF0ZTNEKHBvbHlnb25baSAtIDFdKS54KTtcbiAgICAgICAgY29uc3QgYiA9IHdyYXAodHIucG9pbnRDb29yZGluYXRlM0QocG9seWdvbltpXSkueCk7XG5cbiAgICAgICAgLy8gZGlyZWN0aW9uIDwgMDogbWVyY2F0b3IgY29vcmRpbmF0ZSAwIHdpbGwgYmUgY3Jvc3NlZCBmcm9tIGxlZnRcbiAgICAgICAgLy8gZGlyZWN0aW9uID4gMDogbWVyY2F0b3IgY29vcmRpbmF0ZSAxIHdpbGwgYmUgY3Jvc3NlZCBmcm9tIHJpZ2h0XG4gICAgICAgIGlmIChkaXJlY3Rpb24gPCAwKSB7XG4gICAgICAgICAgICBpZiAoYSA8IGIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge2lkeDogaSwgdDogLWEgLyAoYiAtIDEgLSBhKX07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoYiA8IGEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge2lkeDogaSwgdDogKDEgLSBhKSAvIChiICsgMSAtIGEpfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xufVxuXG4vL1BhZGRpbmcgaXMgaW4gc2NyZWVuIHBpeGVscyBhbmQgaXMgb25seSB1c2VkIGFzIGEgY29hcnNlIGNoZWNrLCBzbyAyIGRlY2ltYWwgcGxhY2VzIG9mIHByZWNpc2lvbiBzaG91bGQgYmUgZ29vZCBlbm91Z2ggZm9yIGEgY2FjaGUuXG5mdW5jdGlvbiBjYWNoZUtleShwYWRkaW5nOiBudW1iZXIpOiBudW1iZXIgIHtcbiAgICByZXR1cm4gKHBhZGRpbmcgKiAxMDApIHwgMDtcbn1cblxuZXhwb3J0IHR5cGUgVGlsZXNwYWNlUXVlcnlHZW9tZXRyeSA9IHtcbiAgICBxdWVyeUdlb21ldHJ5OiBRdWVyeUdlb21ldHJ5LFxuICAgIHRpbGVzcGFjZUdlb21ldHJ5OiBQb2ludFtdLFxuICAgIHRpbGVzcGFjZVJheXM6IFJheVtdLFxuICAgIGJ1ZmZlcmVkVGlsZXNwYWNlR2VvbWV0cnk6IFBvaW50W10sXG4gICAgYnVmZmVyZWRUaWxlc3BhY2VCb3VuZHM6IHsgbWluOiBQb2ludCwgbWF4OiBQb2ludH0sXG4gICAgdGlsZTogVGlsZSxcbiAgICB0aWxlSUQ6IE92ZXJzY2FsZWRUaWxlSUQsXG4gICAgcGl4ZWxUb1RpbGVVbml0c0ZhY3RvcjogbnVtYmVyXG59O1xuXG5mdW5jdGlvbiBjbGFtcEJvdW5kc1RvVGlsZUV4dGVudHMoYm91bmRzOiB7bWluOiBQb2ludCwgbWF4OiBQb2ludH0pOiB7bWluOiBQb2ludCwgbWF4OiBQb2ludH0ge1xuICAgIGJvdW5kcy5taW4ueCA9IGNsYW1wKGJvdW5kcy5taW4ueCwgMCwgRVhURU5UKTtcbiAgICBib3VuZHMubWluLnkgPSBjbGFtcChib3VuZHMubWluLnksIDAsIEVYVEVOVCk7XG5cbiAgICBib3VuZHMubWF4LnggPSBjbGFtcChib3VuZHMubWF4LngsIDAsIEVYVEVOVCk7XG4gICAgYm91bmRzLm1heC55ID0gY2xhbXAoYm91bmRzLm1heC55LCAwLCBFWFRFTlQpO1xuICAgIHJldHVybiBib3VuZHM7XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge3BpY2ssIGV4dGVuZH0gZnJvbSAnLi4vdXRpbC91dGlsLmpzJztcblxuaW1wb3J0IHtnZXRKU09OLCBSZXNvdXJjZVR5cGV9IGZyb20gJy4uL3V0aWwvYWpheC5qcyc7XG5pbXBvcnQgYnJvd3NlciBmcm9tICcuLi91dGlsL2Jyb3dzZXIuanMnO1xuXG5pbXBvcnQgdHlwZSB7UmVxdWVzdE1hbmFnZXJ9IGZyb20gJy4uL3V0aWwvbWFwYm94LmpzJztcbmltcG9ydCB0eXBlIHtDYWxsYmFja30gZnJvbSAnLi4vdHlwZXMvY2FsbGJhY2suanMnO1xuaW1wb3J0IHR5cGUge1RpbGVKU09OfSBmcm9tICcuLi90eXBlcy90aWxlanNvbi5qcyc7XG5pbXBvcnQgdHlwZSB7Q2FuY2VsYWJsZX0gZnJvbSAnLi4vdHlwZXMvY2FuY2VsYWJsZS5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKG9wdGlvbnM6IGFueSwgcmVxdWVzdE1hbmFnZXI6IFJlcXVlc3RNYW5hZ2VyLCBsYW5ndWFnZTogP3N0cmluZywgd29ybGR2aWV3OiA/c3RyaW5nLCBjYWxsYmFjazogQ2FsbGJhY2s8VGlsZUpTT04+KTogQ2FuY2VsYWJsZSB7XG4gICAgY29uc3QgbG9hZGVkID0gZnVuY3Rpb24oZXJyOiA/RXJyb3IsIHRpbGVKU09OOiA/T2JqZWN0KSB7XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICAgICAgICB9IGVsc2UgaWYgKHRpbGVKU09OKSB7XG4gICAgICAgICAgICAvLyBQcmVmZXIgVGlsZUpTT04gdGlsZXMsIGlmIGJvdGggVVJMIGFuZCB0aWxlcyBvcHRpb25zIGFyZSBzZXRcbiAgICAgICAgICAgIGlmIChvcHRpb25zLnVybCAmJiB0aWxlSlNPTi50aWxlcyAmJiBvcHRpb25zLnRpbGVzKSBkZWxldGUgb3B0aW9ucy50aWxlcztcblxuICAgICAgICAgICAgY29uc3QgcmVzdWx0OiBhbnkgPSBwaWNrKFxuICAgICAgICAgICAgICAgIC8vIGV4cGxpY2l0IHNvdXJjZSBvcHRpb25zIHRha2UgcHJlY2VkZW5jZSBvdmVyIFRpbGVKU09OXG4gICAgICAgICAgICAgICAgZXh0ZW5kKHRpbGVKU09OLCBvcHRpb25zKSxcbiAgICAgICAgICAgICAgICBbJ3RpbGVzJywgJ21pbnpvb20nLCAnbWF4em9vbScsICdhdHRyaWJ1dGlvbicsICdtYXBib3hfbG9nbycsICdib3VuZHMnLCAnc2NoZW1lJywgJ3RpbGVTaXplJywgJ2VuY29kaW5nJ11cbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGlmICh0aWxlSlNPTi52ZWN0b3JfbGF5ZXJzKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnZlY3RvckxheWVycyA9IHRpbGVKU09OLnZlY3Rvcl9sYXllcnM7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnZlY3RvckxheWVySWRzID0gcmVzdWx0LnZlY3RvckxheWVycy5tYXAoKGxheWVyKSA9PiB7IHJldHVybiBsYXllci5pZDsgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJlc3VsdC50aWxlcyA9IHJlcXVlc3RNYW5hZ2VyLmNhbm9uaWNhbGl6ZVRpbGVzZXQocmVzdWx0LCBvcHRpb25zLnVybCk7XG4gICAgICAgICAgICBjYWxsYmFjayhudWxsLCByZXN1bHQpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIGlmIChvcHRpb25zLnVybCkge1xuICAgICAgICByZXR1cm4gZ2V0SlNPTihyZXF1ZXN0TWFuYWdlci50cmFuc2Zvcm1SZXF1ZXN0KHJlcXVlc3RNYW5hZ2VyLm5vcm1hbGl6ZVNvdXJjZVVSTChvcHRpb25zLnVybCwgbnVsbCwgbGFuZ3VhZ2UsIHdvcmxkdmlldyksIFJlc291cmNlVHlwZS5Tb3VyY2UpLCBsb2FkZWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBicm93c2VyLmZyYW1lKCgpID0+IGxvYWRlZChudWxsLCBvcHRpb25zKSk7XG4gICAgfVxufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IExuZ0xhdEJvdW5kcyBmcm9tICcuLi9nZW8vbG5nX2xhdF9ib3VuZHMuanMnO1xuaW1wb3J0IHttZXJjYXRvclhmcm9tTG5nLCBtZXJjYXRvcllmcm9tTGF0fSBmcm9tICcuLi9nZW8vbWVyY2F0b3JfY29vcmRpbmF0ZS5qcyc7XG5cbmltcG9ydCB0eXBlIHtDYW5vbmljYWxUaWxlSUR9IGZyb20gJy4vdGlsZV9pZC5qcyc7XG5cbmNsYXNzIFRpbGVCb3VuZHMge1xuICAgIGJvdW5kczogTG5nTGF0Qm91bmRzO1xuICAgIG1pbnpvb206IG51bWJlcjtcbiAgICBtYXh6b29tOiBudW1iZXI7XG5cbiAgICBjb25zdHJ1Y3Rvcihib3VuZHM6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLCBtaW56b29tOiA/bnVtYmVyLCBtYXh6b29tOiA/bnVtYmVyKSB7XG4gICAgICAgIHRoaXMuYm91bmRzID0gTG5nTGF0Qm91bmRzLmNvbnZlcnQodGhpcy52YWxpZGF0ZUJvdW5kcyhib3VuZHMpKTtcbiAgICAgICAgdGhpcy5taW56b29tID0gbWluem9vbSB8fCAwO1xuICAgICAgICB0aGlzLm1heHpvb20gPSBtYXh6b29tIHx8IDI0O1xuICAgIH1cblxuICAgIHZhbGlkYXRlQm91bmRzKGJvdW5kczogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0pOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSB7XG4gICAgICAgIC8vIG1ha2Ugc3VyZSB0aGUgYm91bmRzIHByb3BlcnR5IGNvbnRhaW5zIHZhbGlkIGxvbmdpdHVkZSBhbmQgbGF0aXR1ZGVzXG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShib3VuZHMpIHx8IGJvdW5kcy5sZW5ndGggIT09IDQpIHJldHVybiBbLTE4MCwgLTkwLCAxODAsIDkwXTtcbiAgICAgICAgcmV0dXJuIFtNYXRoLm1heCgtMTgwLCBib3VuZHNbMF0pLCBNYXRoLm1heCgtOTAsIGJvdW5kc1sxXSksIE1hdGgubWluKDE4MCwgYm91bmRzWzJdKSwgTWF0aC5taW4oOTAsIGJvdW5kc1szXSldO1xuICAgIH1cblxuICAgIGNvbnRhaW5zKHRpbGVJRDogQ2Fub25pY2FsVGlsZUlEKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IHdvcmxkU2l6ZSA9IE1hdGgucG93KDIsIHRpbGVJRC56KTtcbiAgICAgICAgY29uc3QgbGV2ZWwgPSB7XG4gICAgICAgICAgICBtaW5YOiBNYXRoLmZsb29yKG1lcmNhdG9yWGZyb21MbmcodGhpcy5ib3VuZHMuZ2V0V2VzdCgpKSAqIHdvcmxkU2l6ZSksXG4gICAgICAgICAgICBtaW5ZOiBNYXRoLmZsb29yKG1lcmNhdG9yWWZyb21MYXQodGhpcy5ib3VuZHMuZ2V0Tm9ydGgoKSkgKiB3b3JsZFNpemUpLFxuICAgICAgICAgICAgbWF4WDogTWF0aC5jZWlsKG1lcmNhdG9yWGZyb21MbmcodGhpcy5ib3VuZHMuZ2V0RWFzdCgpKSAqIHdvcmxkU2l6ZSksXG4gICAgICAgICAgICBtYXhZOiBNYXRoLmNlaWwobWVyY2F0b3JZZnJvbUxhdCh0aGlzLmJvdW5kcy5nZXRTb3V0aCgpKSAqIHdvcmxkU2l6ZSlcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgaGl0ID0gdGlsZUlELnggPj0gbGV2ZWwubWluWCAmJiB0aWxlSUQueCA8IGxldmVsLm1heFggJiYgdGlsZUlELnkgPj0gbGV2ZWwubWluWSAmJiB0aWxlSUQueSA8IGxldmVsLm1heFk7XG4gICAgICAgIHJldHVybiBoaXQ7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBUaWxlQm91bmRzO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtFdmVudCwgRXJyb3JFdmVudCwgRXZlbnRlZH0gZnJvbSAnLi4vdXRpbC9ldmVudGVkLmpzJztcblxuaW1wb3J0IHtleHRlbmQsIHBpY2t9IGZyb20gJy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQgbG9hZFRpbGVKU09OIGZyb20gJy4vbG9hZF90aWxlanNvbi5qcyc7XG5pbXBvcnQge3Bvc3RUdXJuc3RpbGVFdmVudH0gZnJvbSAnLi4vdXRpbC9tYXBib3guanMnO1xuaW1wb3J0IFRpbGVCb3VuZHMgZnJvbSAnLi90aWxlX2JvdW5kcy5qcyc7XG5pbXBvcnQge1Jlc291cmNlVHlwZX0gZnJvbSAnLi4vdXRpbC9hamF4LmpzJztcbmltcG9ydCBicm93c2VyIGZyb20gJy4uL3V0aWwvYnJvd3Nlci5qcyc7XG5pbXBvcnQge2NhY2hlRW50cnlQb3NzaWJseUFkZGVkfSBmcm9tICcuLi91dGlsL3RpbGVfcmVxdWVzdF9jYWNoZS5qcyc7XG5pbXBvcnQge0RlZHVwZWRSZXF1ZXN0LCBsb2FkVmVjdG9yVGlsZX0gZnJvbSAnLi92ZWN0b3JfdGlsZV93b3JrZXJfc291cmNlLmpzJztcblxuaW1wb3J0IHR5cGUge1NvdXJjZX0gZnJvbSAnLi9zb3VyY2UuanMnO1xuaW1wb3J0IHR5cGUge092ZXJzY2FsZWRUaWxlSUR9IGZyb20gJy4vdGlsZV9pZC5qcyc7XG5pbXBvcnQgdHlwZSBNYXAgZnJvbSAnLi4vdWkvbWFwLmpzJztcbmltcG9ydCB0eXBlIERpc3BhdGNoZXIgZnJvbSAnLi4vdXRpbC9kaXNwYXRjaGVyLmpzJztcbmltcG9ydCB0eXBlIFRpbGUgZnJvbSAnLi90aWxlLmpzJztcbmltcG9ydCB0eXBlIHtDYWxsYmFja30gZnJvbSAnLi4vdHlwZXMvY2FsbGJhY2suanMnO1xuaW1wb3J0IHR5cGUge0NhbmNlbGFibGV9IGZyb20gJy4uL3R5cGVzL2NhbmNlbGFibGUuanMnO1xuaW1wb3J0IHR5cGUge1ZlY3RvclNvdXJjZVNwZWNpZmljYXRpb24sIFByb21vdGVJZFNwZWNpZmljYXRpb259IGZyb20gJy4uL3N0eWxlLXNwZWMvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUgQWN0b3IgZnJvbSAnLi4vdXRpbC9hY3Rvci5qcyc7XG5pbXBvcnQgdHlwZSB7TG9hZFZlY3RvclRpbGVSZXN1bHR9IGZyb20gJy4vdmVjdG9yX3RpbGVfd29ya2VyX3NvdXJjZS5qcyc7XG5pbXBvcnQgdHlwZSB7V29ya2VyVGlsZVJlc3VsdH0gZnJvbSAnLi93b3JrZXJfc291cmNlLmpzJztcblxuLyoqXG4gKiBBIHNvdXJjZSBjb250YWluaW5nIHZlY3RvciB0aWxlcyBpbiBbTWFwYm94IFZlY3RvciBUaWxlIGZvcm1hdF0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vdmVjdG9yLXRpbGVzL3JlZmVyZW5jZS8pLlxuICogU2VlIHRoZSBbU3R5bGUgU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL3N0eWxlLXNwZWMvc291cmNlcy8jdmVjdG9yKSBmb3IgZGV0YWlsZWQgZG9jdW1lbnRhdGlvbiBvZiBvcHRpb25zLlxuICpcbiAqIEBleGFtcGxlXG4gKiBtYXAuYWRkU291cmNlKCdzb21lIGlkJywge1xuICogICAgIHR5cGU6ICd2ZWN0b3InLFxuICogICAgIHVybDogJ21hcGJveDovL21hcGJveC5tYXBib3gtc3RyZWV0cy12OCdcbiAqIH0pO1xuICpcbiAqIEBleGFtcGxlXG4gKiBtYXAuYWRkU291cmNlKCdzb21lIGlkJywge1xuICogICAgIHR5cGU6ICd2ZWN0b3InLFxuICogICAgIHRpbGVzOiBbJ2h0dHBzOi8vZDI1dWFyaHh5d3psMWouY2xvdWRmcm9udC5uZXQvdjAuMS97en0ve3h9L3t5fS5tdnQnXSxcbiAqICAgICBtaW56b29tOiA2LFxuICogICAgIG1heHpvb206IDE0XG4gKiB9KTtcbiAqXG4gKiBAZXhhbXBsZVxuICogbWFwLmdldFNvdXJjZSgnc29tZSBpZCcpLnNldFVybChcIm1hcGJveDovL21hcGJveC5tYXBib3gtc3RyZWV0cy12OFwiKTtcbiAqXG4gKiBAZXhhbXBsZVxuICogbWFwLmdldFNvdXJjZSgnc29tZSBpZCcpLnNldFRpbGVzKFsnaHR0cHM6Ly9kMjV1YXJoeHl3emwxai5jbG91ZGZyb250Lm5ldC92MC4xL3t6fS97eH0ve3l9Lm12dCddKTtcbiAqIEBzZWUgW0V4YW1wbGU6IEFkZCBhIHZlY3RvciB0aWxlIHNvdXJjZV0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvdmVjdG9yLXNvdXJjZS8pXG4gKiBAc2VlIFtFeGFtcGxlOiBBZGQgYSB0aGlyZCBwYXJ0eSB2ZWN0b3IgdGlsZSBzb3VyY2VdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL3RoaXJkLXBhcnR5LylcbiAqL1xuY2xhc3MgVmVjdG9yVGlsZVNvdXJjZSBleHRlbmRzIEV2ZW50ZWQgaW1wbGVtZW50cyBTb3VyY2Uge1xuICAgIHR5cGU6ICd2ZWN0b3InO1xuICAgIGlkOiBzdHJpbmc7XG4gICAgbWluem9vbTogbnVtYmVyO1xuICAgIG1heHpvb206IG51bWJlcjtcbiAgICB1cmw6IHN0cmluZztcbiAgICBzY2hlbWU6IHN0cmluZztcbiAgICB0aWxlU2l6ZTogbnVtYmVyO1xuICAgIHByb21vdGVJZDogP1Byb21vdGVJZFNwZWNpZmljYXRpb247XG5cbiAgICBfb3B0aW9uczogVmVjdG9yU291cmNlU3BlY2lmaWNhdGlvbjtcbiAgICBfY29sbGVjdFJlc291cmNlVGltaW5nOiBib29sZWFuO1xuICAgIGRpc3BhdGNoZXI6IERpc3BhdGNoZXI7XG4gICAgbWFwOiBNYXA7XG4gICAgYm91bmRzOiA/W251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gICAgdGlsZXM6IEFycmF5PHN0cmluZz47XG4gICAgdGlsZUJvdW5kczogVGlsZUJvdW5kcztcbiAgICByZXBhcnNlT3ZlcnNjYWxlZDogYm9vbGVhbiB8IHZvaWQ7XG4gICAgaXNUaWxlQ2xpcHBlZDogYm9vbGVhbiB8IHZvaWQ7XG4gICAgX3RpbGVKU09OUmVxdWVzdDogP0NhbmNlbGFibGU7XG4gICAgX2xvYWRlZDogYm9vbGVhbjtcbiAgICBfdGlsZVdvcmtlcnM6IHtbc3RyaW5nXTogQWN0b3J9O1xuICAgIF9kZWR1cGVkOiBEZWR1cGVkUmVxdWVzdDtcblxuICAgIGNvbnN0cnVjdG9yKGlkOiBzdHJpbmcsIG9wdGlvbnM6IFZlY3RvclNvdXJjZVNwZWNpZmljYXRpb24gJiB7Y29sbGVjdFJlc291cmNlVGltaW5nOiBib29sZWFufSwgZGlzcGF0Y2hlcjogRGlzcGF0Y2hlciwgZXZlbnRlZFBhcmVudDogRXZlbnRlZCkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLmlkID0gaWQ7XG4gICAgICAgIHRoaXMuZGlzcGF0Y2hlciA9IGRpc3BhdGNoZXI7XG5cbiAgICAgICAgdGhpcy50eXBlID0gJ3ZlY3Rvcic7XG4gICAgICAgIHRoaXMubWluem9vbSA9IDA7XG4gICAgICAgIHRoaXMubWF4em9vbSA9IDIyO1xuICAgICAgICB0aGlzLnNjaGVtZSA9ICd4eXonO1xuICAgICAgICB0aGlzLnRpbGVTaXplID0gNTEyO1xuICAgICAgICB0aGlzLnJlcGFyc2VPdmVyc2NhbGVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5pc1RpbGVDbGlwcGVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fbG9hZGVkID0gZmFsc2U7XG5cbiAgICAgICAgZXh0ZW5kKHRoaXMsIHBpY2sob3B0aW9ucywgWyd1cmwnLCAnc2NoZW1lJywgJ3RpbGVTaXplJywgJ3Byb21vdGVJZCddKSk7XG4gICAgICAgIHRoaXMuX29wdGlvbnMgPSBleHRlbmQoe3R5cGU6ICd2ZWN0b3InfSwgb3B0aW9ucyk7XG5cbiAgICAgICAgdGhpcy5fY29sbGVjdFJlc291cmNlVGltaW5nID0gb3B0aW9ucy5jb2xsZWN0UmVzb3VyY2VUaW1pbmc7XG5cbiAgICAgICAgaWYgKHRoaXMudGlsZVNpemUgIT09IDUxMikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd2ZWN0b3IgdGlsZSBzb3VyY2VzIG11c3QgaGF2ZSBhIHRpbGVTaXplIG9mIDUxMicpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZXRFdmVudGVkUGFyZW50KGV2ZW50ZWRQYXJlbnQpO1xuXG4gICAgICAgIHRoaXMuX3RpbGVXb3JrZXJzID0ge307XG4gICAgICAgIHRoaXMuX2RlZHVwZWQgPSBuZXcgRGVkdXBlZFJlcXVlc3QoKTtcbiAgICB9XG5cbiAgICBsb2FkKGNhbGxiYWNrPzogQ2FsbGJhY2s8dm9pZD4pIHtcbiAgICAgICAgdGhpcy5fbG9hZGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ2RhdGFsb2FkaW5nJywge2RhdGFUeXBlOiAnc291cmNlJ30pKTtcbiAgICAgICAgY29uc3QgbGFuZ3VhZ2UgPSBBcnJheS5pc0FycmF5KHRoaXMubWFwLl9sYW5ndWFnZSkgPyB0aGlzLm1hcC5fbGFuZ3VhZ2Uuam9pbigpIDogdGhpcy5tYXAuX2xhbmd1YWdlO1xuICAgICAgICBjb25zdCB3b3JsZHZpZXcgPSB0aGlzLm1hcC5fd29ybGR2aWV3O1xuICAgICAgICB0aGlzLl90aWxlSlNPTlJlcXVlc3QgPSBsb2FkVGlsZUpTT04odGhpcy5fb3B0aW9ucywgdGhpcy5tYXAuX3JlcXVlc3RNYW5hZ2VyLCBsYW5ndWFnZSwgd29ybGR2aWV3LCAoZXJyLCB0aWxlSlNPTikgPT4ge1xuICAgICAgICAgICAgdGhpcy5fdGlsZUpTT05SZXF1ZXN0ID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX2xvYWRlZCA9IHRydWU7XG4gICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgaWYgKGxhbmd1YWdlKSBjb25zb2xlLndhcm4oYEVuc3VyZSB0aGF0IHlvdXIgcmVxdWVzdGVkIGxhbmd1YWdlIHN0cmluZyBpcyBhIHZhbGlkIEJDUC00NyBjb2RlIG9yIGxpc3Qgb2YgY29kZXMuIEZvdW5kOiAke2xhbmd1YWdlfWApO1xuICAgICAgICAgICAgICAgIGlmICh3b3JsZHZpZXcgJiYgd29ybGR2aWV3Lmxlbmd0aCAhPT0gMikgY29uc29sZS53YXJuKGBSZXF1ZXN0ZWQgd29ybGR2aWV3IHN0cmluZ3MgbXVzdCBiZSBhIHZhbGlkIElTTyBhbHBoYS0yIGNvZGUuIEZvdW5kOiAke3dvcmxkdmlld31gKTtcblxuICAgICAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXJyb3JFdmVudChlcnIpKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGlsZUpTT04pIHtcbiAgICAgICAgICAgICAgICBleHRlbmQodGhpcywgdGlsZUpTT04pO1xuICAgICAgICAgICAgICAgIGlmICh0aWxlSlNPTi5ib3VuZHMpIHRoaXMudGlsZUJvdW5kcyA9IG5ldyBUaWxlQm91bmRzKHRpbGVKU09OLmJvdW5kcywgdGhpcy5taW56b29tLCB0aGlzLm1heHpvb20pO1xuICAgICAgICAgICAgICAgIHBvc3RUdXJuc3RpbGVFdmVudCh0aWxlSlNPTi50aWxlcywgdGhpcy5tYXAuX3JlcXVlc3RNYW5hZ2VyLl9jdXN0b21BY2Nlc3NUb2tlbik7XG5cbiAgICAgICAgICAgICAgICAvLyBgY29udGVudGAgaXMgaW5jbHVkZWQgaGVyZSB0byBwcmV2ZW50IGEgcmFjZSBjb25kaXRpb24gd2hlcmUgYFN0eWxlI191cGRhdGVTb3VyY2VzYCBpcyBjYWxsZWRcbiAgICAgICAgICAgICAgICAvLyBiZWZvcmUgdGhlIFRpbGVKU09OIGFycml2ZXMuIHRoaXMgbWFrZXMgc3VyZSB0aGUgdGlsZXMgbmVlZGVkIGFyZSBsb2FkZWQgb25jZSBUaWxlSlNPTiBhcnJpdmVzXG4gICAgICAgICAgICAgICAgLy8gcmVmOiBodHRwczovL2dpdGh1Yi5jb20vbWFwYm94L21hcGJveC1nbC1qcy9wdWxsLzQzNDcjZGlzY3Vzc2lvbl9yMTA0NDE4MDg4XG4gICAgICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgnZGF0YScsIHtkYXRhVHlwZTogJ3NvdXJjZScsIHNvdXJjZURhdGFUeXBlOiAnbWV0YWRhdGEnfSkpO1xuICAgICAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ2RhdGEnLCB7ZGF0YVR5cGU6ICdzb3VyY2UnLCBzb3VyY2VEYXRhVHlwZTogJ2NvbnRlbnQnfSkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoY2FsbGJhY2spIGNhbGxiYWNrKGVycik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGxvYWRlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRlZDtcbiAgICB9XG5cbiAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgaGFzVGlsZSh0aWxlSUQ6IE92ZXJzY2FsZWRUaWxlSUQpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICF0aGlzLnRpbGVCb3VuZHMgfHwgdGhpcy50aWxlQm91bmRzLmNvbnRhaW5zKHRpbGVJRC5jYW5vbmljYWwpO1xuICAgIH1cblxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICBvbkFkZChtYXA6IE1hcCkge1xuICAgICAgICB0aGlzLm1hcCA9IG1hcDtcbiAgICAgICAgdGhpcy5sb2FkKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVsb2FkcyB0aGUgc291cmNlIGRhdGEgYW5kIHJlLXJlbmRlcnMgdGhlIG1hcC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogbWFwLmdldFNvdXJjZSgnc291cmNlLWlkJykucmVsb2FkKCk7XG4gICAgICovXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIHJlbG9hZCgpIHtcbiAgICAgICAgdGhpcy5jYW5jZWxUaWxlSlNPTlJlcXVlc3QoKTtcbiAgICAgICAgdGhpcy5sb2FkKCgpID0+IHRoaXMubWFwLnN0eWxlLl9jbGVhclNvdXJjZSh0aGlzLmlkKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgc291cmNlIGB0aWxlc2AgcHJvcGVydHkgYW5kIHJlLXJlbmRlcnMgdGhlIG1hcC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nW119IHRpbGVzIEFuIGFycmF5IG9mIG9uZSBvciBtb3JlIHRpbGUgc291cmNlIFVSTHMsIGFzIGluIHRoZSBUaWxlSlNPTiBzcGVjLlxuICAgICAqIEByZXR1cm5zIHtWZWN0b3JUaWxlU291cmNlfSBSZXR1cm5zIGl0c2VsZiB0byBhbGxvdyBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogbWFwLmFkZFNvdXJjZSgnc291cmNlLWlkJywge1xuICAgICAqICAgICB0eXBlOiAndmVjdG9yJyxcbiAgICAgKiAgICAgdGlsZXM6IFsnaHR0cHM6Ly9zb21lX2VuZF9wb2ludC5uZXQve3p9L3t4fS97eX0ubXZ0J10sXG4gICAgICogICAgIG1pbnpvb206IDYsXG4gICAgICogICAgIG1heHpvb206IDE0XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiAvLyBTZXQgdGhlIGVuZHBvaW50IGFzc29jaWF0ZWQgd2l0aCBhIHZlY3RvciB0aWxlIHNvdXJjZS5cbiAgICAgKiBtYXAuZ2V0U291cmNlKCdzb3VyY2UtaWQnKS5zZXRUaWxlcyhbJ2h0dHBzOi8vYW5vdGhlcl9lbmRfcG9pbnQubmV0L3t6fS97eH0ve3l9Lm12dCddKTtcbiAgICAgKi9cbiAgICBzZXRUaWxlcyh0aWxlczogQXJyYXk8c3RyaW5nPik6IHRoaXMge1xuICAgICAgICB0aGlzLl9vcHRpb25zLnRpbGVzID0gdGlsZXM7XG4gICAgICAgIHRoaXMucmVsb2FkKCk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgc291cmNlIGB1cmxgIHByb3BlcnR5IGFuZCByZS1yZW5kZXJzIHRoZSBtYXAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXJsIEEgVVJMIHRvIGEgVGlsZUpTT04gcmVzb3VyY2UuIFN1cHBvcnRlZCBwcm90b2NvbHMgYXJlIGBodHRwOmAsIGBodHRwczpgLCBhbmQgYG1hcGJveDovLzxUaWxlc2V0IElEPmAuXG4gICAgICogQHJldHVybnMge1ZlY3RvclRpbGVTb3VyY2V9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAuYWRkU291cmNlKCdzb3VyY2UtaWQnLCB7XG4gICAgICogICAgIHR5cGU6ICd2ZWN0b3InLFxuICAgICAqICAgICB1cmw6ICdtYXBib3g6Ly9tYXBib3gubWFwYm94LXN0cmVldHMtdjcnXG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiAvLyBVcGRhdGUgdmVjdG9yIHRpbGUgc291cmNlIHRvIGEgbmV3IFVSTCBlbmRwb2ludFxuICAgICAqIG1hcC5nZXRTb3VyY2UoJ3NvdXJjZS1pZCcpLnNldFVybChcIm1hcGJveDovL21hcGJveC5tYXBib3gtc3RyZWV0cy12OFwiKTtcbiAgICAgKi9cbiAgICBzZXRVcmwodXJsOiBzdHJpbmcpOiB0aGlzIHtcbiAgICAgICAgdGhpcy51cmwgPSB1cmw7XG4gICAgICAgIHRoaXMuX29wdGlvbnMudXJsID0gdXJsO1xuICAgICAgICB0aGlzLnJlbG9hZCgpO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICBvblJlbW92ZSgpIHtcbiAgICAgICAgdGhpcy5jYW5jZWxUaWxlSlNPTlJlcXVlc3QoKTtcbiAgICB9XG5cbiAgICBzZXJpYWxpemUoKTogVmVjdG9yU291cmNlU3BlY2lmaWNhdGlvbiB7XG4gICAgICAgIHJldHVybiBleHRlbmQoe30sIHRoaXMuX29wdGlvbnMpO1xuICAgIH1cblxuICAgIGxvYWRUaWxlKHRpbGU6IFRpbGUsIGNhbGxiYWNrOiBDYWxsYmFjazx2b2lkPikge1xuICAgICAgICBjb25zdCB1cmwgPSB0aGlzLm1hcC5fcmVxdWVzdE1hbmFnZXIubm9ybWFsaXplVGlsZVVSTCh0aWxlLnRpbGVJRC5jYW5vbmljYWwudXJsKHRoaXMudGlsZXMsIHRoaXMuc2NoZW1lKSk7XG4gICAgICAgIGNvbnN0IHJlcXVlc3QgPSB0aGlzLm1hcC5fcmVxdWVzdE1hbmFnZXIudHJhbnNmb3JtUmVxdWVzdCh1cmwsIFJlc291cmNlVHlwZS5UaWxlKTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgZGF0YTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgdWlkOiB0aWxlLnVpZCxcbiAgICAgICAgICAgIHRpbGVJRDogdGlsZS50aWxlSUQsXG4gICAgICAgICAgICB0aWxlWm9vbTogdGlsZS50aWxlWm9vbSxcbiAgICAgICAgICAgIHpvb206IHRpbGUudGlsZUlELm92ZXJzY2FsZWRaLFxuICAgICAgICAgICAgdGlsZVNpemU6IHRoaXMudGlsZVNpemUgKiB0aWxlLnRpbGVJRC5vdmVyc2NhbGVGYWN0b3IoKSxcbiAgICAgICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgICAgICAgIHNvdXJjZTogdGhpcy5pZCxcbiAgICAgICAgICAgIHBpeGVsUmF0aW86IGJyb3dzZXIuZGV2aWNlUGl4ZWxSYXRpbyxcbiAgICAgICAgICAgIHNob3dDb2xsaXNpb25Cb3hlczogdGhpcy5tYXAuc2hvd0NvbGxpc2lvbkJveGVzLFxuICAgICAgICAgICAgcHJvbW90ZUlkOiB0aGlzLnByb21vdGVJZCxcbiAgICAgICAgICAgIGlzU3ltYm9sVGlsZTogdGlsZS5pc1N5bWJvbFRpbGVcbiAgICAgICAgfTtcbiAgICAgICAgcGFyYW1zLnJlcXVlc3QuY29sbGVjdFJlc291cmNlVGltaW5nID0gdGhpcy5fY29sbGVjdFJlc291cmNlVGltaW5nO1xuXG4gICAgICAgIGlmICghdGlsZS5hY3RvciB8fCB0aWxlLnN0YXRlID09PSAnZXhwaXJlZCcpIHtcbiAgICAgICAgICAgIHRpbGUuYWN0b3IgPSB0aGlzLl90aWxlV29ya2Vyc1t1cmxdID0gdGhpcy5fdGlsZVdvcmtlcnNbdXJsXSB8fCB0aGlzLmRpc3BhdGNoZXIuZ2V0QWN0b3IoKTtcblxuICAgICAgICAgICAgLy8gaWYgd29ya2VycyBhcmUgbm90IHJlYWR5IHRvIHJlY2VpdmUgbWVzc2FnZXMgeWV0LCB1c2UgdGhlIGlkbGUgdGltZSB0byBwcmVlbXB0aXZlbHlcbiAgICAgICAgICAgIC8vIGxvYWQgdGlsZXMgb24gdGhlIG1haW4gdGhyZWFkIGFuZCBwYXNzIHRoZSByZXN1bHQgaW5zdGVhZCBvZiByZXF1ZXN0aW5nIGEgd29ya2VyIHRvIGRvIHNvXG4gICAgICAgICAgICBpZiAoIXRoaXMuZGlzcGF0Y2hlci5yZWFkeSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNhbmNlbCA9IGxvYWRWZWN0b3JUaWxlLmNhbGwoe2RlZHVwZWQ6IHRoaXMuX2RlZHVwZWR9LCBwYXJhbXMsIChlcnI6ID9FcnJvciwgZGF0YTogP0xvYWRWZWN0b3JUaWxlUmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnIgfHwgIWRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUuY2FsbCh0aGlzLCBlcnIpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIHdvcmtlciB3aWxsIHNraXAgdGhlIG5ldHdvcmsgcmVxdWVzdCBpZiB0aGUgZGF0YSBpcyBhbHJlYWR5IHRoZXJlXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMuZGF0YSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZUNvbnRyb2w6IGRhdGEuY2FjaGVDb250cm9sLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGlyZXM6IGRhdGEuZXhwaXJlcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdEYXRhOiBkYXRhLnJhd0RhdGEuc2xpY2UoMClcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGlsZS5hY3RvcikgdGlsZS5hY3Rvci5zZW5kKCdsb2FkVGlsZScsIHBhcmFtcywgZG9uZS5iaW5kKHRoaXMpLCB1bmRlZmluZWQsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgdGlsZS5yZXF1ZXN0ID0ge2NhbmNlbH07XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGlsZS5yZXF1ZXN0ID0gdGlsZS5hY3Rvci5zZW5kKCdsb2FkVGlsZScsIHBhcmFtcywgZG9uZS5iaW5kKHRoaXMpLCB1bmRlZmluZWQsIHRydWUpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0gZWxzZSBpZiAodGlsZS5zdGF0ZSA9PT0gJ2xvYWRpbmcnKSB7XG4gICAgICAgICAgICAvLyBzY2hlZHVsZSB0aWxlIHJlbG9hZGluZyBhZnRlciBpdCBoYXMgYmVlbiBsb2FkZWRcbiAgICAgICAgICAgIHRpbGUucmVsb2FkQ2FsbGJhY2sgPSBjYWxsYmFjaztcblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGlsZS5yZXF1ZXN0ID0gdGlsZS5hY3Rvci5zZW5kKCdyZWxvYWRUaWxlJywgcGFyYW1zLCBkb25lLmJpbmQodGhpcykpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gJEZsb3dGaXhNZVttaXNzaW5nLXRoaXMtYW5ub3RdXG4gICAgICAgIGZ1bmN0aW9uIGRvbmUoZXJyOiA/RXJyb3IsIGRhdGE6ID9Xb3JrZXJUaWxlUmVzdWx0KSB7XG4gICAgICAgICAgICBkZWxldGUgdGlsZS5yZXF1ZXN0O1xuXG4gICAgICAgICAgICBpZiAodGlsZS5hYm9ydGVkKVxuICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhudWxsKTtcblxuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVtwcm9wLW1pc3NpbmddIC0gZ2VuZXJpYyBFcnJvciB0eXBlIGRvZXNuJ3QgaGF2ZSBzdGF0dXNcbiAgICAgICAgICAgIGlmIChlcnIgJiYgZXJyLnN0YXR1cyAhPT0gNDA0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChkYXRhICYmIGRhdGEucmVzb3VyY2VUaW1pbmcpXG4gICAgICAgICAgICAgICAgdGlsZS5yZXNvdXJjZVRpbWluZyA9IGRhdGEucmVzb3VyY2VUaW1pbmc7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm1hcC5fcmVmcmVzaEV4cGlyZWRUaWxlcyAmJiBkYXRhKSB0aWxlLnNldEV4cGlyeURhdGEoZGF0YSk7XG4gICAgICAgICAgICB0aWxlLmxvYWRWZWN0b3JEYXRhKGRhdGEsIHRoaXMubWFwLnBhaW50ZXIpO1xuXG4gICAgICAgICAgICBjYWNoZUVudHJ5UG9zc2libHlBZGRlZCh0aGlzLmRpc3BhdGNoZXIpO1xuXG4gICAgICAgICAgICBjYWxsYmFjayhudWxsKTtcblxuICAgICAgICAgICAgaWYgKHRpbGUucmVsb2FkQ2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRUaWxlKHRpbGUsIHRpbGUucmVsb2FkQ2FsbGJhY2spO1xuICAgICAgICAgICAgICAgIHRpbGUucmVsb2FkQ2FsbGJhY2sgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIGFib3J0VGlsZSh0aWxlOiBUaWxlKSB7XG4gICAgICAgIGlmICh0aWxlLnJlcXVlc3QpIHtcbiAgICAgICAgICAgIHRpbGUucmVxdWVzdC5jYW5jZWwoKTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aWxlLnJlcXVlc3Q7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRpbGUuYWN0b3IpIHtcbiAgICAgICAgICAgIHRpbGUuYWN0b3Iuc2VuZCgnYWJvcnRUaWxlJywge3VpZDogdGlsZS51aWQsIHR5cGU6IHRoaXMudHlwZSwgc291cmNlOiB0aGlzLmlkfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgdW5sb2FkVGlsZSh0aWxlOiBUaWxlKSB7XG4gICAgICAgIHRpbGUudW5sb2FkVmVjdG9yRGF0YSgpO1xuICAgICAgICBpZiAodGlsZS5hY3Rvcikge1xuICAgICAgICAgICAgdGlsZS5hY3Rvci5zZW5kKCdyZW1vdmVUaWxlJywge3VpZDogdGlsZS51aWQsIHR5cGU6IHRoaXMudHlwZSwgc291cmNlOiB0aGlzLmlkfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBoYXNUcmFuc2l0aW9uKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIGFmdGVyVXBkYXRlKCkge1xuICAgICAgICB0aGlzLl90aWxlV29ya2VycyA9IHt9O1xuICAgIH1cblxuICAgIGNhbmNlbFRpbGVKU09OUmVxdWVzdCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLl90aWxlSlNPTlJlcXVlc3QpIHJldHVybjtcbiAgICAgICAgdGhpcy5fdGlsZUpTT05SZXF1ZXN0LmNhbmNlbCgpO1xuICAgICAgICB0aGlzLl90aWxlSlNPTlJlcXVlc3QgPSBudWxsO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgVmVjdG9yVGlsZVNvdXJjZTtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCB7ZXh0ZW5kLCBwaWNrfSBmcm9tICcuLi91dGlsL3V0aWwuanMnO1xuXG5pbXBvcnQge2dldEltYWdlLCBSZXNvdXJjZVR5cGV9IGZyb20gJy4uL3V0aWwvYWpheC5qcyc7XG5pbXBvcnQge0V2ZW50LCBFcnJvckV2ZW50LCBFdmVudGVkfSBmcm9tICcuLi91dGlsL2V2ZW50ZWQuanMnO1xuaW1wb3J0IGxvYWRUaWxlSlNPTiBmcm9tICcuL2xvYWRfdGlsZWpzb24uanMnO1xuaW1wb3J0IHtwb3N0VHVybnN0aWxlRXZlbnR9IGZyb20gJy4uL3V0aWwvbWFwYm94LmpzJztcbmltcG9ydCBUaWxlQm91bmRzIGZyb20gJy4vdGlsZV9ib3VuZHMuanMnO1xuaW1wb3J0IGJyb3dzZXIgZnJvbSAnLi4vdXRpbC9icm93c2VyLmpzJztcblxuaW1wb3J0IHtjYWNoZUVudHJ5UG9zc2libHlBZGRlZH0gZnJvbSAnLi4vdXRpbC90aWxlX3JlcXVlc3RfY2FjaGUuanMnO1xuXG5pbXBvcnQgdHlwZSB7U291cmNlfSBmcm9tICcuL3NvdXJjZS5qcyc7XG5pbXBvcnQgdHlwZSB7T3ZlcnNjYWxlZFRpbGVJRH0gZnJvbSAnLi90aWxlX2lkLmpzJztcbmltcG9ydCB0eXBlIE1hcCBmcm9tICcuLi91aS9tYXAuanMnO1xuaW1wb3J0IHR5cGUgUGFpbnRlciBmcm9tICcuLi9yZW5kZXIvcGFpbnRlci5qcyc7XG5pbXBvcnQgdHlwZSBEaXNwYXRjaGVyIGZyb20gJy4uL3V0aWwvZGlzcGF0Y2hlci5qcyc7XG5pbXBvcnQgdHlwZSBUaWxlIGZyb20gJy4vdGlsZS5qcyc7XG5pbXBvcnQgdHlwZSB7Q2FsbGJhY2t9IGZyb20gJy4uL3R5cGVzL2NhbGxiYWNrLmpzJztcbmltcG9ydCB0eXBlIHtDYW5jZWxhYmxlfSBmcm9tICcuLi90eXBlcy9jYW5jZWxhYmxlLmpzJztcbmltcG9ydCB0eXBlIHtUZXh0dXJlSW1hZ2V9IGZyb20gJy4uL3JlbmRlci90ZXh0dXJlLmpzJztcbmltcG9ydCB0eXBlIHtcbiAgICBSYXN0ZXJTb3VyY2VTcGVjaWZpY2F0aW9uLFxuICAgIFJhc3RlckRFTVNvdXJjZVNwZWNpZmljYXRpb25cbn0gZnJvbSAnLi4vc3R5bGUtc3BlYy90eXBlcy5qcyc7XG5cbi8qKlxuICogQSBzb3VyY2UgY29udGFpbmluZyByYXN0ZXIgdGlsZXMuXG4gKiBTZWUgdGhlIFtTdHlsZSBTcGVjaWZpY2F0aW9uXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvc3R5bGUtc3BlYy9zb3VyY2VzLyNyYXN0ZXIpIGZvciBkZXRhaWxlZCBkb2N1bWVudGF0aW9uIG9mIG9wdGlvbnMuXG4gKlxuICogQGV4YW1wbGVcbiAqIG1hcC5hZGRTb3VyY2UoJ3NvbWUgaWQnLCB7XG4gKiAgICAgdHlwZTogJ3Jhc3RlcicsXG4gKiAgICAgdXJsOiAnbWFwYm94Oi8vbWFwYm94LnNhdGVsbGl0ZScsXG4gKiAgICAgdGlsZVNpemU6IDI1NlxuICogfSk7XG4gKlxuICogQGV4YW1wbGVcbiAqIG1hcC5hZGRTb3VyY2UoJ3NvbWUgaWQnLCB7XG4gKiAgICAgdHlwZTogJ3Jhc3RlcicsXG4gKiAgICAgdGlsZXM6IFsnaHR0cHM6Ly9pbWcubmouZ292L2ltYWdlcnl3bXMvTmF0dXJhbDIwMTU/YmJveD17YmJveC1lcHNnLTM4NTd9JmZvcm1hdD1pbWFnZS9wbmcmc2VydmljZT1XTVMmdmVyc2lvbj0xLjEuMSZyZXF1ZXN0PUdldE1hcCZzcnM9RVBTRzozODU3JnRyYW5zcGFyZW50PXRydWUmd2lkdGg9MjU2JmhlaWdodD0yNTYmbGF5ZXJzPU5hdHVyYWwyMDE1J10sXG4gKiAgICAgdGlsZVNpemU6IDI1NlxuICogfSk7XG4gKlxuICogQHNlZSBbRXhhbXBsZTogQWRkIGEgcmFzdGVyIHRpbGUgc291cmNlXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9tYXAtdGlsZXMvKVxuICogQHNlZSBbRXhhbXBsZTogQWRkIGEgV01TIHNvdXJjZV0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvd21zLylcbiAqL1xuY2xhc3MgUmFzdGVyVGlsZVNvdXJjZSBleHRlbmRzIEV2ZW50ZWQgaW1wbGVtZW50cyBTb3VyY2Uge1xuICAgIHR5cGU6ICdyYXN0ZXInIHwgJ3Jhc3Rlci1kZW0nO1xuICAgIGlkOiBzdHJpbmc7XG4gICAgbWluem9vbTogbnVtYmVyO1xuICAgIG1heHpvb206IG51bWJlcjtcbiAgICB1cmw6IHN0cmluZztcbiAgICBzY2hlbWU6IHN0cmluZztcbiAgICB0aWxlU2l6ZTogbnVtYmVyO1xuXG4gICAgYm91bmRzOiA/W251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gICAgdGlsZUJvdW5kczogVGlsZUJvdW5kcztcbiAgICByb3VuZFpvb206IGJvb2xlYW4gfCB2b2lkO1xuICAgIGRpc3BhdGNoZXI6IERpc3BhdGNoZXI7XG4gICAgbWFwOiBNYXA7XG4gICAgdGlsZXM6IEFycmF5PHN0cmluZz47XG5cbiAgICBfbG9hZGVkOiBib29sZWFuO1xuICAgIF9vcHRpb25zOiBSYXN0ZXJTb3VyY2VTcGVjaWZpY2F0aW9uIHwgUmFzdGVyREVNU291cmNlU3BlY2lmaWNhdGlvbjtcbiAgICBfdGlsZUpTT05SZXF1ZXN0OiA/Q2FuY2VsYWJsZTtcblxuICAgIGNvbnN0cnVjdG9yKGlkOiBzdHJpbmcsIG9wdGlvbnM6IFJhc3RlclNvdXJjZVNwZWNpZmljYXRpb24gfCBSYXN0ZXJERU1Tb3VyY2VTcGVjaWZpY2F0aW9uLCBkaXNwYXRjaGVyOiBEaXNwYXRjaGVyLCBldmVudGVkUGFyZW50OiBFdmVudGVkKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuaWQgPSBpZDtcbiAgICAgICAgdGhpcy5kaXNwYXRjaGVyID0gZGlzcGF0Y2hlcjtcbiAgICAgICAgdGhpcy5zZXRFdmVudGVkUGFyZW50KGV2ZW50ZWRQYXJlbnQpO1xuXG4gICAgICAgIHRoaXMudHlwZSA9ICdyYXN0ZXInO1xuICAgICAgICB0aGlzLm1pbnpvb20gPSAwO1xuICAgICAgICB0aGlzLm1heHpvb20gPSAyMjtcbiAgICAgICAgdGhpcy5yb3VuZFpvb20gPSB0cnVlO1xuICAgICAgICB0aGlzLnNjaGVtZSA9ICd4eXonO1xuICAgICAgICB0aGlzLnRpbGVTaXplID0gNTEyO1xuICAgICAgICB0aGlzLl9sb2FkZWQgPSBmYWxzZTtcblxuICAgICAgICB0aGlzLl9vcHRpb25zID0gZXh0ZW5kKHt0eXBlOiAncmFzdGVyJ30sIG9wdGlvbnMpO1xuICAgICAgICBleHRlbmQodGhpcywgcGljayhvcHRpb25zLCBbJ3VybCcsICdzY2hlbWUnLCAndGlsZVNpemUnXSkpO1xuICAgIH1cblxuICAgIGxvYWQoY2FsbGJhY2s/OiBDYWxsYmFjazx2b2lkPikge1xuICAgICAgICB0aGlzLl9sb2FkZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgnZGF0YWxvYWRpbmcnLCB7ZGF0YVR5cGU6ICdzb3VyY2UnfSkpO1xuICAgICAgICB0aGlzLl90aWxlSlNPTlJlcXVlc3QgPSBsb2FkVGlsZUpTT04odGhpcy5fb3B0aW9ucywgdGhpcy5tYXAuX3JlcXVlc3RNYW5hZ2VyLCBudWxsLCBudWxsLCAoZXJyLCB0aWxlSlNPTikgPT4ge1xuICAgICAgICAgICAgdGhpcy5fdGlsZUpTT05SZXF1ZXN0ID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX2xvYWRlZCA9IHRydWU7XG4gICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFcnJvckV2ZW50KGVycikpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aWxlSlNPTikge1xuICAgICAgICAgICAgICAgIGV4dGVuZCh0aGlzLCB0aWxlSlNPTik7XG4gICAgICAgICAgICAgICAgaWYgKHRpbGVKU09OLmJvdW5kcykgdGhpcy50aWxlQm91bmRzID0gbmV3IFRpbGVCb3VuZHModGlsZUpTT04uYm91bmRzLCB0aGlzLm1pbnpvb20sIHRoaXMubWF4em9vbSk7XG5cbiAgICAgICAgICAgICAgICBwb3N0VHVybnN0aWxlRXZlbnQodGlsZUpTT04udGlsZXMpO1xuXG4gICAgICAgICAgICAgICAgLy8gYGNvbnRlbnRgIGlzIGluY2x1ZGVkIGhlcmUgdG8gcHJldmVudCBhIHJhY2UgY29uZGl0aW9uIHdoZXJlIGBTdHlsZSNfdXBkYXRlU291cmNlc2AgaXMgY2FsbGVkXG4gICAgICAgICAgICAgICAgLy8gYmVmb3JlIHRoZSBUaWxlSlNPTiBhcnJpdmVzLiB0aGlzIG1ha2VzIHN1cmUgdGhlIHRpbGVzIG5lZWRlZCBhcmUgbG9hZGVkIG9uY2UgVGlsZUpTT04gYXJyaXZlc1xuICAgICAgICAgICAgICAgIC8vIHJlZjogaHR0cHM6Ly9naXRodWIuY29tL21hcGJveC9tYXBib3gtZ2wtanMvcHVsbC80MzQ3I2Rpc2N1c3Npb25fcjEwNDQxODA4OFxuICAgICAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ2RhdGEnLCB7ZGF0YVR5cGU6ICdzb3VyY2UnLCBzb3VyY2VEYXRhVHlwZTogJ21ldGFkYXRhJ30pKTtcbiAgICAgICAgICAgICAgICB0aGlzLmZpcmUobmV3IEV2ZW50KCdkYXRhJywge2RhdGFUeXBlOiAnc291cmNlJywgc291cmNlRGF0YVR5cGU6ICdjb250ZW50J30pKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSBjYWxsYmFjayhlcnIpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBsb2FkZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb2FkZWQ7XG4gICAgfVxuXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIG9uQWRkKG1hcDogTWFwKSB7XG4gICAgICAgIHRoaXMubWFwID0gbWFwO1xuICAgICAgICB0aGlzLmxvYWQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZWxvYWRzIHRoZSBzb3VyY2UgZGF0YSBhbmQgcmUtcmVuZGVycyB0aGUgbWFwLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAuZ2V0U291cmNlKCdzb3VyY2UtaWQnKS5yZWxvYWQoKTtcbiAgICAgKi9cbiAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgcmVsb2FkKCkge1xuICAgICAgICB0aGlzLmNhbmNlbFRpbGVKU09OUmVxdWVzdCgpO1xuICAgICAgICB0aGlzLmxvYWQoKCkgPT4gdGhpcy5tYXAuc3R5bGUuX2NsZWFyU291cmNlKHRoaXMuaWQpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBzb3VyY2UgYHRpbGVzYCBwcm9wZXJ0eSBhbmQgcmUtcmVuZGVycyB0aGUgbWFwLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmdbXX0gdGlsZXMgQW4gYXJyYXkgb2Ygb25lIG9yIG1vcmUgdGlsZSBzb3VyY2UgVVJMcywgYXMgaW4gdGhlIFRpbGVKU09OIHNwZWMuXG4gICAgICogQHJldHVybnMge1Jhc3RlclRpbGVTb3VyY2V9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAuYWRkU291cmNlKCdzb3VyY2UtaWQnLCB7XG4gICAgICogICAgIHR5cGU6ICdyYXN0ZXInLFxuICAgICAqICAgICB0aWxlczogWydodHRwczovL3NvbWVfZW5kX3BvaW50Lm5ldC97en0ve3h9L3t5fS5wbmcnXSxcbiAgICAgKiAgICAgdGlsZVNpemU6IDI1NlxuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogLy8gU2V0IHRoZSBlbmRwb2ludCBhc3NvY2lhdGVkIHdpdGggYSByYXN0ZXIgdGlsZSBzb3VyY2UuXG4gICAgICogbWFwLmdldFNvdXJjZSgnc291cmNlLWlkJykuc2V0VGlsZXMoWydodHRwczovL2Fub3RoZXJfZW5kX3BvaW50Lm5ldC97en0ve3h9L3t5fS5wbmcnXSk7XG4gICAgICovXG4gICAgc2V0VGlsZXModGlsZXM6IEFycmF5PHN0cmluZz4pOiB0aGlzIHtcbiAgICAgICAgdGhpcy5fb3B0aW9ucy50aWxlcyA9IHRpbGVzO1xuICAgICAgICB0aGlzLnJlbG9hZCgpO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHNvdXJjZSBgdXJsYCBwcm9wZXJ0eSBhbmQgcmUtcmVuZGVycyB0aGUgbWFwLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHVybCBBIFVSTCB0byBhIFRpbGVKU09OIHJlc291cmNlLiBTdXBwb3J0ZWQgcHJvdG9jb2xzIGFyZSBgaHR0cDpgLCBgaHR0cHM6YCwgYW5kIGBtYXBib3g6Ly88VGlsZXNldCBJRD5gLlxuICAgICAqIEByZXR1cm5zIHtSYXN0ZXJUaWxlU291cmNlfSBSZXR1cm5zIGl0c2VsZiB0byBhbGxvdyBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogbWFwLmFkZFNvdXJjZSgnc291cmNlLWlkJywge1xuICAgICAqICAgICB0eXBlOiAncmFzdGVyJyxcbiAgICAgKiAgICAgdXJsOiAnbWFwYm94Oi8vbWFwYm94LnNhdGVsbGl0ZSdcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIC8vIFVwZGF0ZSByYXN0ZXIgdGlsZSBzb3VyY2UgdG8gYSBuZXcgVVJMIGVuZHBvaW50XG4gICAgICogbWFwLmdldFNvdXJjZSgnc291cmNlLWlkJykuc2V0VXJsKCdtYXBib3g6Ly9tYXBib3guc2F0ZWxsaXRlJyk7XG4gICAgICovXG4gICAgc2V0VXJsKHVybDogc3RyaW5nKTogdGhpcyB7XG4gICAgICAgIHRoaXMudXJsID0gdXJsO1xuICAgICAgICB0aGlzLl9vcHRpb25zLnVybCA9IHVybDtcbiAgICAgICAgdGhpcy5yZWxvYWQoKTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgb25SZW1vdmUoKSB7XG4gICAgICAgIHRoaXMuY2FuY2VsVGlsZUpTT05SZXF1ZXN0KCk7XG4gICAgfVxuXG4gICAgc2VyaWFsaXplKCk6IFJhc3RlclNvdXJjZVNwZWNpZmljYXRpb24gfCBSYXN0ZXJERU1Tb3VyY2VTcGVjaWZpY2F0aW9uIHtcbiAgICAgICAgcmV0dXJuIGV4dGVuZCh7fSwgdGhpcy5fb3B0aW9ucyk7XG4gICAgfVxuXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIGhhc1RpbGUodGlsZUlEOiBPdmVyc2NhbGVkVGlsZUlEKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAhdGhpcy50aWxlQm91bmRzIHx8IHRoaXMudGlsZUJvdW5kcy5jb250YWlucyh0aWxlSUQuY2Fub25pY2FsKTtcbiAgICB9XG5cbiAgICBsb2FkVGlsZSh0aWxlOiBUaWxlLCBjYWxsYmFjazogQ2FsbGJhY2s8dm9pZD4pIHtcbiAgICAgICAgY29uc3QgdXNlMnggPSBicm93c2VyLmRldmljZVBpeGVsUmF0aW8gPj0gMjtcbiAgICAgICAgY29uc3QgdXJsID0gdGhpcy5tYXAuX3JlcXVlc3RNYW5hZ2VyLm5vcm1hbGl6ZVRpbGVVUkwodGlsZS50aWxlSUQuY2Fub25pY2FsLnVybCh0aGlzLnRpbGVzLCB0aGlzLnNjaGVtZSksIHVzZTJ4LCB0aGlzLnRpbGVTaXplKTtcbiAgICAgICAgdGlsZS5yZXF1ZXN0ID0gZ2V0SW1hZ2UodGhpcy5tYXAuX3JlcXVlc3RNYW5hZ2VyLnRyYW5zZm9ybVJlcXVlc3QodXJsLCBSZXNvdXJjZVR5cGUuVGlsZSksIChlcnJvciwgZGF0YSwgY2FjaGVDb250cm9sLCBleHBpcmVzKSA9PiB7XG4gICAgICAgICAgICBkZWxldGUgdGlsZS5yZXF1ZXN0O1xuXG4gICAgICAgICAgICBpZiAodGlsZS5hYm9ydGVkKSB7XG4gICAgICAgICAgICAgICAgdGlsZS5zdGF0ZSA9ICd1bmxvYWRlZCc7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICB0aWxlLnN0YXRlID0gJ2Vycm9yZWQnO1xuICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnJvcik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghZGF0YSkgcmV0dXJuIGNhbGxiYWNrKG51bGwpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5tYXAuX3JlZnJlc2hFeHBpcmVkVGlsZXMpIHRpbGUuc2V0RXhwaXJ5RGF0YSh7Y2FjaGVDb250cm9sLCBleHBpcmVzfSk7XG4gICAgICAgICAgICB0aWxlLnNldFRleHR1cmUoZGF0YSwgdGhpcy5tYXAucGFpbnRlcik7XG4gICAgICAgICAgICB0aWxlLnN0YXRlID0gJ2xvYWRlZCc7XG5cbiAgICAgICAgICAgIGNhY2hlRW50cnlQb3NzaWJseUFkZGVkKHRoaXMuZGlzcGF0Y2hlcik7XG4gICAgICAgICAgICBjYWxsYmFjayhudWxsKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc3RhdGljIGxvYWRUaWxlRGF0YSh0aWxlOiBUaWxlLCBkYXRhOiBUZXh0dXJlSW1hZ2UsIHBhaW50ZXI6IFBhaW50ZXIpIHtcbiAgICAgICAgdGlsZS5zZXRUZXh0dXJlKGRhdGEsIHBhaW50ZXIpO1xuICAgIH1cblxuICAgIHN0YXRpYyB1bmxvYWRUaWxlRGF0YSh0aWxlOiBUaWxlLCBwYWludGVyOiBQYWludGVyKSB7XG4gICAgICAgIGlmICh0aWxlLnRleHR1cmUpIHtcbiAgICAgICAgICAgIHBhaW50ZXIuc2F2ZVRpbGVUZXh0dXJlKHRpbGUudGV4dHVyZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgYWJvcnRUaWxlKHRpbGU6IFRpbGUsIGNhbGxiYWNrOiBDYWxsYmFjazx2b2lkPikge1xuICAgICAgICBpZiAodGlsZS5yZXF1ZXN0KSB7XG4gICAgICAgICAgICB0aWxlLnJlcXVlc3QuY2FuY2VsKCk7XG4gICAgICAgICAgICBkZWxldGUgdGlsZS5yZXF1ZXN0O1xuICAgICAgICB9XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgfVxuXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIHVubG9hZFRpbGUodGlsZTogVGlsZSwgY2FsbGJhY2s6IENhbGxiYWNrPHZvaWQ+KSB7XG4gICAgICAgIGlmICh0aWxlLnRleHR1cmUpIHRoaXMubWFwLnBhaW50ZXIuc2F2ZVRpbGVUZXh0dXJlKHRpbGUudGV4dHVyZSk7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgfVxuXG4gICAgaGFzVHJhbnNpdGlvbigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNhbmNlbFRpbGVKU09OUmVxdWVzdCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLl90aWxlSlNPTlJlcXVlc3QpIHJldHVybjtcbiAgICAgICAgdGhpcy5fdGlsZUpTT05SZXF1ZXN0LmNhbmNlbCgpO1xuICAgICAgICB0aGlzLl90aWxlSlNPTlJlcXVlc3QgPSBudWxsO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUmFzdGVyVGlsZVNvdXJjZTtcbiIsIi8vIEBmbG93XG5pbXBvcnQgd2luZG93IGZyb20gJy4vd2luZG93LmpzJztcblxubGV0IHN1cHBvcnRzT2Zmc2NyZWVuQ2FudmFzOiA/Ym9vbGVhbjtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gb2Zmc2NyZWVuQ2FudmFzU3VwcG9ydGVkKCk6IGJvb2xlYW4ge1xuICAgIGlmIChzdXBwb3J0c09mZnNjcmVlbkNhbnZhcyA9PSBudWxsKSB7XG4gICAgICAgIHN1cHBvcnRzT2Zmc2NyZWVuQ2FudmFzID0gd2luZG93Lk9mZnNjcmVlbkNhbnZhcyAmJlxuICAgICAgICAgICAgbmV3IHdpbmRvdy5PZmZzY3JlZW5DYW52YXMoMSwgMSkuZ2V0Q29udGV4dCgnMmQnKSAmJlxuICAgICAgICAgICAgdHlwZW9mIHdpbmRvdy5jcmVhdGVJbWFnZUJpdG1hcCA9PT0gJ2Z1bmN0aW9uJztcbiAgICB9XG5cbiAgICByZXR1cm4gc3VwcG9ydHNPZmZzY3JlZW5DYW52YXM7XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge2dldEltYWdlLCBSZXNvdXJjZVR5cGV9IGZyb20gJy4uL3V0aWwvYWpheC5qcyc7XG5pbXBvcnQge2V4dGVuZCwgcHJldlBvd2VyT2ZUd299IGZyb20gJy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQge0V2ZW50ZWR9IGZyb20gJy4uL3V0aWwvZXZlbnRlZC5qcyc7XG5pbXBvcnQgYnJvd3NlciBmcm9tICcuLi91dGlsL2Jyb3dzZXIuanMnO1xuaW1wb3J0IHdpbmRvdyBmcm9tICcuLi91dGlsL3dpbmRvdy5qcyc7XG5pbXBvcnQgb2Zmc2NyZWVuQ2FudmFzU3VwcG9ydGVkIGZyb20gJy4uL3V0aWwvb2Zmc2NyZWVuX2NhbnZhc19zdXBwb3J0ZWQuanMnO1xuaW1wb3J0IHtPdmVyc2NhbGVkVGlsZUlEfSBmcm9tICcuL3RpbGVfaWQuanMnO1xuaW1wb3J0IFJhc3RlclRpbGVTb3VyY2UgZnJvbSAnLi9yYXN0ZXJfdGlsZV9zb3VyY2UuanMnO1xuLy8gZW5zdXJlIERFTURhdGEgaXMgcmVnaXN0ZXJlZCBmb3Igd29ya2VyIHRyYW5zZmVyIG9uIG1haW4gdGhyZWFkOlxuaW1wb3J0IERFTURhdGEgZnJvbSAnLi4vZGF0YS9kZW1fZGF0YS5qcyc7XG5cbmltcG9ydCB0eXBlIHtTb3VyY2V9IGZyb20gJy4vc291cmNlLmpzJztcbmltcG9ydCB0eXBlIERpc3BhdGNoZXIgZnJvbSAnLi4vdXRpbC9kaXNwYXRjaGVyLmpzJztcbmltcG9ydCB0eXBlIFRpbGUgZnJvbSAnLi90aWxlLmpzJztcbmltcG9ydCB0eXBlIHtDYWxsYmFja30gZnJvbSAnLi4vdHlwZXMvY2FsbGJhY2suanMnO1xuaW1wb3J0IHR5cGUge1RleHR1cmVJbWFnZX0gZnJvbSAnLi4vcmVuZGVyL3RleHR1cmUuanMnO1xuaW1wb3J0IHR5cGUge1Jhc3RlckRFTVNvdXJjZVNwZWNpZmljYXRpb259IGZyb20gJy4uL3N0eWxlLXNwZWMvdHlwZXMuanMnO1xuXG4vLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG5jbGFzcyBSYXN0ZXJERU1UaWxlU291cmNlIGV4dGVuZHMgUmFzdGVyVGlsZVNvdXJjZSBpbXBsZW1lbnRzIFNvdXJjZSB7XG4gICAgZW5jb2Rpbmc6IFwibWFwYm94XCIgfCBcInRlcnJhcml1bVwiO1xuXG4gICAgY29uc3RydWN0b3IoaWQ6IHN0cmluZywgb3B0aW9uczogUmFzdGVyREVNU291cmNlU3BlY2lmaWNhdGlvbiwgZGlzcGF0Y2hlcjogRGlzcGF0Y2hlciwgZXZlbnRlZFBhcmVudDogRXZlbnRlZCkge1xuICAgICAgICBzdXBlcihpZCwgb3B0aW9ucywgZGlzcGF0Y2hlciwgZXZlbnRlZFBhcmVudCk7XG4gICAgICAgIHRoaXMudHlwZSA9ICdyYXN0ZXItZGVtJztcbiAgICAgICAgdGhpcy5tYXh6b29tID0gMjI7XG4gICAgICAgIHRoaXMuX29wdGlvbnMgPSBleHRlbmQoe3R5cGU6ICdyYXN0ZXItZGVtJ30sIG9wdGlvbnMpO1xuICAgICAgICB0aGlzLmVuY29kaW5nID0gb3B0aW9ucy5lbmNvZGluZyB8fCBcIm1hcGJveFwiO1xuICAgIH1cblxuICAgIGxvYWRUaWxlKHRpbGU6IFRpbGUsIGNhbGxiYWNrOiBDYWxsYmFjazx2b2lkPikge1xuICAgICAgICBjb25zdCB1cmwgPSB0aGlzLm1hcC5fcmVxdWVzdE1hbmFnZXIubm9ybWFsaXplVGlsZVVSTCh0aWxlLnRpbGVJRC5jYW5vbmljYWwudXJsKHRoaXMudGlsZXMsIHRoaXMuc2NoZW1lKSwgZmFsc2UsIHRoaXMudGlsZVNpemUpO1xuICAgICAgICB0aWxlLnJlcXVlc3QgPSBnZXRJbWFnZSh0aGlzLm1hcC5fcmVxdWVzdE1hbmFnZXIudHJhbnNmb3JtUmVxdWVzdCh1cmwsIFJlc291cmNlVHlwZS5UaWxlKSwgaW1hZ2VMb2FkZWQuYmluZCh0aGlzKSk7XG5cbiAgICAgICAgLy8gJEZsb3dGaXhNZVttaXNzaW5nLXRoaXMtYW5ub3RdXG4gICAgICAgIGZ1bmN0aW9uIGltYWdlTG9hZGVkKGVycjogP0Vycm9yLCBpbWc6ID9UZXh0dXJlSW1hZ2UsIGNhY2hlQ29udHJvbDogP3N0cmluZywgZXhwaXJlczogP3N0cmluZykge1xuICAgICAgICAgICAgZGVsZXRlIHRpbGUucmVxdWVzdDtcbiAgICAgICAgICAgIGlmICh0aWxlLmFib3J0ZWQpIHtcbiAgICAgICAgICAgICAgICB0aWxlLnN0YXRlID0gJ3VubG9hZGVkJztcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhudWxsKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgdGlsZS5zdGF0ZSA9ICdlcnJvcmVkJztcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnIpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChpbWcpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5tYXAuX3JlZnJlc2hFeHBpcmVkVGlsZXMpIHRpbGUuc2V0RXhwaXJ5RGF0YSh7Y2FjaGVDb250cm9sLCBleHBpcmVzfSk7XG4gICAgICAgICAgICAgICAgY29uc3QgdHJhbnNmZXIgPSB3aW5kb3cuSW1hZ2VCaXRtYXAgJiYgaW1nIGluc3RhbmNlb2Ygd2luZG93LkltYWdlQml0bWFwICYmIG9mZnNjcmVlbkNhbnZhc1N1cHBvcnRlZCgpO1xuICAgICAgICAgICAgICAgIC8vIERFTURhdGEgdXNlcyAxcHggcGFkZGluZy4gSGFuZGxlIGNhc2VzIHdpdGggaW1hZ2UgYnVmZmVyIG9mIDEgYW5kIDIgcHhzLCB0aGUgcmVzdCBhc3N1bWUgZGVmYXVsdCBidWZmZXIgMFxuICAgICAgICAgICAgICAgIC8vIGluIG9yZGVyIHRvIGtlZXAgdGhlIHByZXZpb3VzIGltcGxlbWVudGF0aW9uIHdvcmtpbmcgKG5vIHZhbGlkYXRpb24gYWdhaW5zdCB0aWxlU2l6ZSkuXG4gICAgICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gKGltZy53aWR0aCAtIHByZXZQb3dlck9mVHdvKGltZy53aWR0aCkpIC8gMjtcbiAgICAgICAgICAgICAgICAvLyBwYWRkaW5nIGlzIHVzZWQgaW4gZ2V0SW1hZ2VEYXRhLiBBcyBERU1EYXRhIGhhcyAxcHggcGFkZGluZywgaWYgREVNIHRpbGUgYnVmZmVyIGlzIDJweCwgZGlzY2FyZCBvdXRlcm1vc3QgcGl4ZWxzLlxuICAgICAgICAgICAgICAgIGNvbnN0IHBhZGRpbmcgPSAxIC0gYnVmZmVyO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJvcmRlclJlYWR5ID0gcGFkZGluZyA8IDE7XG4gICAgICAgICAgICAgICAgaWYgKCFib3JkZXJSZWFkeSAmJiAhdGlsZS5uZWlnaGJvcmluZ1RpbGVzKSB7XG4gICAgICAgICAgICAgICAgICAgIHRpbGUubmVpZ2hib3JpbmdUaWxlcyA9IHRoaXMuX2dldE5laWdoYm9yaW5nVGlsZXModGlsZS50aWxlSUQpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vICRGbG93Rml4TWVbaW5jb21wYXRpYmxlLWNhbGxdXG4gICAgICAgICAgICAgICAgY29uc3QgcmF3SW1hZ2VEYXRhID0gdHJhbnNmZXIgPyBpbWcgOiBicm93c2VyLmdldEltYWdlRGF0YShpbWcsIHBhZGRpbmcpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgdWlkOiB0aWxlLnVpZCxcbiAgICAgICAgICAgICAgICAgICAgY29vcmQ6IHRpbGUudGlsZUlELFxuICAgICAgICAgICAgICAgICAgICBzb3VyY2U6IHRoaXMuaWQsXG4gICAgICAgICAgICAgICAgICAgIHJhd0ltYWdlRGF0YSxcbiAgICAgICAgICAgICAgICAgICAgZW5jb2Rpbmc6IHRoaXMuZW5jb2RpbmcsXG4gICAgICAgICAgICAgICAgICAgIHBhZGRpbmdcbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaWYgKCF0aWxlLmFjdG9yIHx8IHRpbGUuc3RhdGUgPT09ICdleHBpcmVkJykge1xuICAgICAgICAgICAgICAgICAgICB0aWxlLmFjdG9yID0gdGhpcy5kaXNwYXRjaGVyLmdldEFjdG9yKCk7XG4gICAgICAgICAgICAgICAgICAgIHRpbGUuYWN0b3Iuc2VuZCgnbG9hZERFTVRpbGUnLCBwYXJhbXMsIGRvbmUuYmluZCh0aGlzKSwgdW5kZWZpbmVkLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyAkRmxvd0ZpeE1lW21pc3NpbmctdGhpcy1hbm5vdF1cbiAgICAgICAgZnVuY3Rpb24gZG9uZShlcnI6ID9FcnJvciwgZGVtOiA/REVNRGF0YSkge1xuICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgIHRpbGUuc3RhdGUgPSAnZXJyb3JlZCc7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGRlbSkge1xuICAgICAgICAgICAgICAgIHRpbGUuZGVtID0gZGVtO1xuICAgICAgICAgICAgICAgIHRpbGUuZGVtLm9uRGVzZXJpYWxpemUoKTtcbiAgICAgICAgICAgICAgICB0aWxlLm5lZWRzSGlsbHNoYWRlUHJlcGFyZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgdGlsZS5uZWVkc0RFTVRleHR1cmVVcGxvYWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRpbGUuc3RhdGUgPSAnbG9hZGVkJztcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhudWxsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9nZXROZWlnaGJvcmluZ1RpbGVzKHRpbGVJRDogT3ZlcnNjYWxlZFRpbGVJRCk6IHtbbnVtYmVyXToge2JhY2tmaWxsZWQ6IGJvb2xlYW59fSB7XG4gICAgICAgIGNvbnN0IGNhbm9uaWNhbCA9IHRpbGVJRC5jYW5vbmljYWw7XG4gICAgICAgIGNvbnN0IGRpbSA9IE1hdGgucG93KDIsIGNhbm9uaWNhbC56KTtcblxuICAgICAgICBjb25zdCBweCA9IChjYW5vbmljYWwueCAtIDEgKyBkaW0pICUgZGltO1xuICAgICAgICBjb25zdCBweHcgPSBjYW5vbmljYWwueCA9PT0gMCA/IHRpbGVJRC53cmFwIC0gMSA6IHRpbGVJRC53cmFwO1xuICAgICAgICBjb25zdCBueCA9IChjYW5vbmljYWwueCArIDEgKyBkaW0pICUgZGltO1xuICAgICAgICBjb25zdCBueHcgPSBjYW5vbmljYWwueCArIDEgPT09IGRpbSA/IHRpbGVJRC53cmFwICsgMSA6IHRpbGVJRC53cmFwO1xuXG4gICAgICAgIGNvbnN0IG5laWdoYm9yaW5nVGlsZXMgPSB7fTtcbiAgICAgICAgLy8gYWRkIGFkamFjZW50IHRpbGVzXG4gICAgICAgIG5laWdoYm9yaW5nVGlsZXNbbmV3IE92ZXJzY2FsZWRUaWxlSUQodGlsZUlELm92ZXJzY2FsZWRaLCBweHcsIGNhbm9uaWNhbC56LCBweCwgY2Fub25pY2FsLnkpLmtleV0gPSB7YmFja2ZpbGxlZDogZmFsc2V9O1xuICAgICAgICBuZWlnaGJvcmluZ1RpbGVzW25ldyBPdmVyc2NhbGVkVGlsZUlEKHRpbGVJRC5vdmVyc2NhbGVkWiwgbnh3LCBjYW5vbmljYWwueiwgbngsIGNhbm9uaWNhbC55KS5rZXldID0ge2JhY2tmaWxsZWQ6IGZhbHNlfTtcblxuICAgICAgICAvLyBBZGQgdXBwZXIgbmVpZ2hib3JpbmdUaWxlc1xuICAgICAgICBpZiAoY2Fub25pY2FsLnkgPiAwKSB7XG4gICAgICAgICAgICBuZWlnaGJvcmluZ1RpbGVzW25ldyBPdmVyc2NhbGVkVGlsZUlEKHRpbGVJRC5vdmVyc2NhbGVkWiwgcHh3LCBjYW5vbmljYWwueiwgcHgsIGNhbm9uaWNhbC55IC0gMSkua2V5XSA9IHtiYWNrZmlsbGVkOiBmYWxzZX07XG4gICAgICAgICAgICBuZWlnaGJvcmluZ1RpbGVzW25ldyBPdmVyc2NhbGVkVGlsZUlEKHRpbGVJRC5vdmVyc2NhbGVkWiwgdGlsZUlELndyYXAsIGNhbm9uaWNhbC56LCBjYW5vbmljYWwueCwgY2Fub25pY2FsLnkgLSAxKS5rZXldID0ge2JhY2tmaWxsZWQ6IGZhbHNlfTtcbiAgICAgICAgICAgIG5laWdoYm9yaW5nVGlsZXNbbmV3IE92ZXJzY2FsZWRUaWxlSUQodGlsZUlELm92ZXJzY2FsZWRaLCBueHcsIGNhbm9uaWNhbC56LCBueCwgY2Fub25pY2FsLnkgLSAxKS5rZXldID0ge2JhY2tmaWxsZWQ6IGZhbHNlfTtcbiAgICAgICAgfVxuICAgICAgICAvLyBBZGQgbG93ZXIgbmVpZ2hib3JpbmdUaWxlc1xuICAgICAgICBpZiAoY2Fub25pY2FsLnkgKyAxIDwgZGltKSB7XG4gICAgICAgICAgICBuZWlnaGJvcmluZ1RpbGVzW25ldyBPdmVyc2NhbGVkVGlsZUlEKHRpbGVJRC5vdmVyc2NhbGVkWiwgcHh3LCBjYW5vbmljYWwueiwgcHgsIGNhbm9uaWNhbC55ICsgMSkua2V5XSA9IHtiYWNrZmlsbGVkOiBmYWxzZX07XG4gICAgICAgICAgICBuZWlnaGJvcmluZ1RpbGVzW25ldyBPdmVyc2NhbGVkVGlsZUlEKHRpbGVJRC5vdmVyc2NhbGVkWiwgdGlsZUlELndyYXAsIGNhbm9uaWNhbC56LCBjYW5vbmljYWwueCwgY2Fub25pY2FsLnkgKyAxKS5rZXldID0ge2JhY2tmaWxsZWQ6IGZhbHNlfTtcbiAgICAgICAgICAgIG5laWdoYm9yaW5nVGlsZXNbbmV3IE92ZXJzY2FsZWRUaWxlSUQodGlsZUlELm92ZXJzY2FsZWRaLCBueHcsIGNhbm9uaWNhbC56LCBueCwgY2Fub25pY2FsLnkgKyAxKS5rZXldID0ge2JhY2tmaWxsZWQ6IGZhbHNlfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZWlnaGJvcmluZ1RpbGVzO1xuICAgIH1cblxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICB1bmxvYWRUaWxlKHRpbGU6IFRpbGUpIHtcbiAgICAgICAgaWYgKHRpbGUuZGVtVGV4dHVyZSkgdGhpcy5tYXAucGFpbnRlci5zYXZlVGlsZVRleHR1cmUodGlsZS5kZW1UZXh0dXJlKTtcbiAgICAgICAgaWYgKHRpbGUuZmJvKSB7XG4gICAgICAgICAgICB0aWxlLmZiby5kZXN0cm95KCk7XG4gICAgICAgICAgICBkZWxldGUgdGlsZS5mYm87XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRpbGUuZGVtKSBkZWxldGUgdGlsZS5kZW07XG4gICAgICAgIGRlbGV0ZSB0aWxlLm5laWdoYm9yaW5nVGlsZXM7XG5cbiAgICAgICAgdGlsZS5zdGF0ZSA9ICd1bmxvYWRlZCc7XG4gICAgfVxuXG59XG5cbmV4cG9ydCBkZWZhdWx0IFJhc3RlckRFTVRpbGVTb3VyY2U7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge0V2ZW50LCBFcnJvckV2ZW50LCBFdmVudGVkfSBmcm9tICcuLi91dGlsL2V2ZW50ZWQuanMnO1xuXG5pbXBvcnQge2V4dGVuZH0gZnJvbSAnLi4vdXRpbC91dGlsLmpzJztcbmltcG9ydCBFWFRFTlQgZnJvbSAnLi4vZGF0YS9leHRlbnQuanMnO1xuaW1wb3J0IHtSZXNvdXJjZVR5cGV9IGZyb20gJy4uL3V0aWwvYWpheC5qcyc7XG5pbXBvcnQgYnJvd3NlciBmcm9tICcuLi91dGlsL2Jyb3dzZXIuanMnO1xuXG5pbXBvcnQgdHlwZSB7U291cmNlfSBmcm9tICcuL3NvdXJjZS5qcyc7XG5pbXBvcnQgdHlwZSBNYXAgZnJvbSAnLi4vdWkvbWFwLmpzJztcbmltcG9ydCB0eXBlIERpc3BhdGNoZXIgZnJvbSAnLi4vdXRpbC9kaXNwYXRjaGVyLmpzJztcbmltcG9ydCB0eXBlIFRpbGUgZnJvbSAnLi90aWxlLmpzJztcbmltcG9ydCB0eXBlIEFjdG9yIGZyb20gJy4uL3V0aWwvYWN0b3IuanMnO1xuaW1wb3J0IHR5cGUge0NhbGxiYWNrfSBmcm9tICcuLi90eXBlcy9jYWxsYmFjay5qcyc7XG5pbXBvcnQgdHlwZSB7R2VvSlNPTldvcmtlck9wdGlvbnN9IGZyb20gJy4vZ2VvanNvbl93b3JrZXJfc291cmNlLmpzJztcbmltcG9ydCB0eXBlIHtHZW9KU09OLCBHZW9KU09ORmVhdHVyZX0gZnJvbSAnQG1hcGJveC9nZW9qc29uLXR5cGVzJztcbmltcG9ydCB0eXBlIHtHZW9KU09OU291cmNlU3BlY2lmaWNhdGlvbiwgUHJvbW90ZUlkU3BlY2lmaWNhdGlvbn0gZnJvbSAnLi4vc3R5bGUtc3BlYy90eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSB7Q2FuY2VsYWJsZX0gZnJvbSAnLi4vdHlwZXMvY2FuY2VsYWJsZS5qcyc7XG5cbi8qKlxuICogQSBzb3VyY2UgY29udGFpbmluZyBHZW9KU09OLlxuICogU2VlIHRoZSBbU3R5bGUgU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtc3R5bGUtc3BlYy8jc291cmNlcy1nZW9qc29uKSBmb3IgZGV0YWlsZWQgZG9jdW1lbnRhdGlvbiBvZiBvcHRpb25zLlxuICpcbiAqIEBleGFtcGxlXG4gKiBtYXAuYWRkU291cmNlKCdzb21lIGlkJywge1xuICogICAgIHR5cGU6ICdnZW9qc29uJyxcbiAqICAgICBkYXRhOiAnaHR0cHM6Ly9kMmFkNmI0dXI3eXZwcS5jbG91ZGZyb250Lm5ldC9uYXR1cmFsZWFydGgtMy4zLjAvbmVfMTBtX3BvcnRzLmdlb2pzb24nXG4gKiB9KTtcbiAqXG4gKiBAZXhhbXBsZVxuICogbWFwLmFkZFNvdXJjZSgnc29tZSBpZCcsIHtcbiAqICAgICB0eXBlOiAnZ2VvanNvbicsXG4gKiAgICAgZGF0YToge1xuICogICAgICAgICBcInR5cGVcIjogXCJGZWF0dXJlQ29sbGVjdGlvblwiLFxuICogICAgICAgICBcImZlYXR1cmVzXCI6IFt7XG4gKiAgICAgICAgICAgICBcInR5cGVcIjogXCJGZWF0dXJlXCIsXG4gKiAgICAgICAgICAgICBcInByb3BlcnRpZXNcIjoge30sXG4gKiAgICAgICAgICAgICBcImdlb21ldHJ5XCI6IHtcbiAqICAgICAgICAgICAgICAgICBcInR5cGVcIjogXCJQb2ludFwiLFxuICogICAgICAgICAgICAgICAgIFwiY29vcmRpbmF0ZXNcIjogW1xuICogICAgICAgICAgICAgICAgICAgICAtNzYuNTMwNjMyOTcyNzE3MjksXG4gKiAgICAgICAgICAgICAgICAgICAgIDM5LjE4MTc0MDc3OTk0MTA4XG4gKiAgICAgICAgICAgICAgICAgXVxuICogICAgICAgICAgICAgfVxuICogICAgICAgICB9XVxuICogICAgIH1cbiAqIH0pO1xuICpcbiAqIEBleGFtcGxlXG4gKiBtYXAuZ2V0U291cmNlKCdzb21lIGlkJykuc2V0RGF0YSh7XG4gKiAgICAgXCJ0eXBlXCI6IFwiRmVhdHVyZUNvbGxlY3Rpb25cIixcbiAqICAgICBcImZlYXR1cmVzXCI6IFt7XG4gKiAgICAgICAgIFwidHlwZVwiOiBcIkZlYXR1cmVcIixcbiAqICAgICAgICAgXCJwcm9wZXJ0aWVzXCI6IHtcIm5hbWVcIjogXCJOdWxsIElzbGFuZFwifSxcbiAqICAgICAgICAgXCJnZW9tZXRyeVwiOiB7XG4gKiAgICAgICAgICAgICBcInR5cGVcIjogXCJQb2ludFwiLFxuICogICAgICAgICAgICAgXCJjb29yZGluYXRlc1wiOiBbIDAsIDAgXVxuICogICAgICAgICB9XG4gKiAgICAgfV1cbiAqIH0pO1xuICogQHNlZSBbRXhhbXBsZTogRHJhdyBHZW9KU09OIHBvaW50c10oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9nZW9qc29uLW1hcmtlcnMvKVxuICogQHNlZSBbRXhhbXBsZTogQWRkIGEgR2VvSlNPTiBsaW5lXShodHRwczovL3d3dy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2dlb2pzb24tbGluZS8pXG4gKiBAc2VlIFtFeGFtcGxlOiBDcmVhdGUgYSBoZWF0bWFwIGZyb20gcG9pbnRzXShodHRwczovL3d3dy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2hlYXRtYXAvKVxuICogQHNlZSBbRXhhbXBsZTogQ3JlYXRlIGFuZCBzdHlsZSBjbHVzdGVyc10oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9jbHVzdGVyLylcbiAqL1xuY2xhc3MgR2VvSlNPTlNvdXJjZSBleHRlbmRzIEV2ZW50ZWQgaW1wbGVtZW50cyBTb3VyY2Uge1xuICAgIHR5cGU6ICdnZW9qc29uJztcbiAgICBpZDogc3RyaW5nO1xuICAgIG1pbnpvb206IG51bWJlcjtcbiAgICBtYXh6b29tOiBudW1iZXI7XG4gICAgdGlsZVNpemU6IG51bWJlcjtcbiAgICBhdHRyaWJ1dGlvbjogc3RyaW5nIHwgdm9pZDtcbiAgICBwcm9tb3RlSWQ6ID9Qcm9tb3RlSWRTcGVjaWZpY2F0aW9uO1xuXG4gICAgaXNUaWxlQ2xpcHBlZDogYm9vbGVhbiB8IHZvaWQ7XG4gICAgcmVwYXJzZU92ZXJzY2FsZWQ6IGJvb2xlYW4gfCB2b2lkO1xuICAgIF9kYXRhOiBHZW9KU09OIHwgc3RyaW5nO1xuICAgIF9vcHRpb25zOiBHZW9KU09OU291cmNlU3BlY2lmaWNhdGlvbjtcbiAgICB3b3JrZXJPcHRpb25zOiBHZW9KU09OV29ya2VyT3B0aW9ucztcbiAgICBtYXA6IE1hcDtcbiAgICBhY3RvcjogQWN0b3I7XG4gICAgX2xvYWRlZDogYm9vbGVhbjtcbiAgICBfY29hbGVzY2U6ID9ib29sZWFuO1xuICAgIF9tZXRhZGF0YUZpcmVkOiA/Ym9vbGVhbjtcbiAgICBfY29sbGVjdFJlc291cmNlVGltaW5nOiBib29sZWFuO1xuICAgIF9wZW5kaW5nTG9hZDogP0NhbmNlbGFibGU7XG5cbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGlkOiBzdHJpbmcsIG9wdGlvbnM6IEdlb0pTT05Tb3VyY2VTcGVjaWZpY2F0aW9uICYge3dvcmtlck9wdGlvbnM/OiBHZW9KU09OV29ya2VyT3B0aW9ucywgY29sbGVjdFJlc291cmNlVGltaW5nOiBib29sZWFufSwgZGlzcGF0Y2hlcjogRGlzcGF0Y2hlciwgZXZlbnRlZFBhcmVudDogRXZlbnRlZCkge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIHRoaXMuaWQgPSBpZDtcblxuICAgICAgICAvLyBgdHlwZWAgaXMgYSBwcm9wZXJ0eSByYXRoZXIgdGhhbiBhIGNvbnN0YW50IHRvIG1ha2UgaXQgZWFzeSBmb3IgM3JkXG4gICAgICAgIC8vIHBhcnRpZXMgdG8gdXNlIEdlb0pTT05Tb3VyY2UgdG8gYnVpbGQgdGhlaXIgb3duIHNvdXJjZSB0eXBlcy5cbiAgICAgICAgdGhpcy50eXBlID0gJ2dlb2pzb24nO1xuXG4gICAgICAgIHRoaXMubWluem9vbSA9IDA7XG4gICAgICAgIHRoaXMubWF4em9vbSA9IDE4O1xuICAgICAgICB0aGlzLnRpbGVTaXplID0gNTEyO1xuICAgICAgICB0aGlzLmlzVGlsZUNsaXBwZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLnJlcGFyc2VPdmVyc2NhbGVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fbG9hZGVkID0gZmFsc2U7XG5cbiAgICAgICAgdGhpcy5hY3RvciA9IGRpc3BhdGNoZXIuZ2V0QWN0b3IoKTtcbiAgICAgICAgdGhpcy5zZXRFdmVudGVkUGFyZW50KGV2ZW50ZWRQYXJlbnQpO1xuXG4gICAgICAgIHRoaXMuX2RhdGEgPSAob3B0aW9ucy5kYXRhOiBhbnkpO1xuICAgICAgICB0aGlzLl9vcHRpb25zID0gZXh0ZW5kKHt9LCBvcHRpb25zKTtcblxuICAgICAgICB0aGlzLl9jb2xsZWN0UmVzb3VyY2VUaW1pbmcgPSBvcHRpb25zLmNvbGxlY3RSZXNvdXJjZVRpbWluZztcblxuICAgICAgICBpZiAob3B0aW9ucy5tYXh6b29tICE9PSB1bmRlZmluZWQpIHRoaXMubWF4em9vbSA9IG9wdGlvbnMubWF4em9vbTtcbiAgICAgICAgaWYgKG9wdGlvbnMudHlwZSkgdGhpcy50eXBlID0gb3B0aW9ucy50eXBlO1xuICAgICAgICBpZiAob3B0aW9ucy5hdHRyaWJ1dGlvbikgdGhpcy5hdHRyaWJ1dGlvbiA9IG9wdGlvbnMuYXR0cmlidXRpb247XG4gICAgICAgIHRoaXMucHJvbW90ZUlkID0gb3B0aW9ucy5wcm9tb3RlSWQ7XG5cbiAgICAgICAgY29uc3Qgc2NhbGUgPSBFWFRFTlQgLyB0aGlzLnRpbGVTaXplO1xuXG4gICAgICAgIC8vIHNlbnQgdG8gdGhlIHdvcmtlciwgYWxvbmcgd2l0aCBgdXJsOiAuLi5gIG9yIGBkYXRhOiBsaXRlcmFsIGdlb2pzb25gLFxuICAgICAgICAvLyBzbyB0aGF0IGl0IGNhbiBsb2FkL3BhcnNlL2luZGV4IHRoZSBnZW9qc29uIGRhdGFcbiAgICAgICAgLy8gZXh0ZW5kaW5nIHdpdGggYG9wdGlvbnMud29ya2VyT3B0aW9uc2AgaGVscHMgdG8gbWFrZSBpdCBlYXN5IGZvclxuICAgICAgICAvLyB0aGlyZC1wYXJ0eSBzb3VyY2VzIHRvIGhhY2svcmV1c2UgR2VvSlNPTlNvdXJjZS5cbiAgICAgICAgdGhpcy53b3JrZXJPcHRpb25zID0gZXh0ZW5kKHtcbiAgICAgICAgICAgIHNvdXJjZTogdGhpcy5pZCxcbiAgICAgICAgICAgIGNsdXN0ZXI6IG9wdGlvbnMuY2x1c3RlciB8fCBmYWxzZSxcbiAgICAgICAgICAgIGdlb2pzb25WdE9wdGlvbnM6IHtcbiAgICAgICAgICAgICAgICBidWZmZXI6IChvcHRpb25zLmJ1ZmZlciAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5idWZmZXIgOiAxMjgpICogc2NhbGUsXG4gICAgICAgICAgICAgICAgdG9sZXJhbmNlOiAob3B0aW9ucy50b2xlcmFuY2UgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMudG9sZXJhbmNlIDogMC4zNzUpICogc2NhbGUsXG4gICAgICAgICAgICAgICAgZXh0ZW50OiBFWFRFTlQsXG4gICAgICAgICAgICAgICAgbWF4Wm9vbTogdGhpcy5tYXh6b29tLFxuICAgICAgICAgICAgICAgIGxpbmVNZXRyaWNzOiBvcHRpb25zLmxpbmVNZXRyaWNzIHx8IGZhbHNlLFxuICAgICAgICAgICAgICAgIGdlbmVyYXRlSWQ6IG9wdGlvbnMuZ2VuZXJhdGVJZCB8fCBmYWxzZVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHN1cGVyY2x1c3Rlck9wdGlvbnM6IHtcbiAgICAgICAgICAgICAgICBtYXhab29tOiBvcHRpb25zLmNsdXN0ZXJNYXhab29tICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNsdXN0ZXJNYXhab29tIDogdGhpcy5tYXh6b29tIC0gMSxcbiAgICAgICAgICAgICAgICBtaW5Qb2ludHM6IE1hdGgubWF4KDIsIG9wdGlvbnMuY2x1c3Rlck1pblBvaW50cyB8fCAyKSxcbiAgICAgICAgICAgICAgICBleHRlbnQ6IEVYVEVOVCxcbiAgICAgICAgICAgICAgICByYWRpdXM6IChvcHRpb25zLmNsdXN0ZXJSYWRpdXMgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY2x1c3RlclJhZGl1cyA6IDUwKSAqIHNjYWxlLFxuICAgICAgICAgICAgICAgIGxvZzogZmFsc2UsXG4gICAgICAgICAgICAgICAgZ2VuZXJhdGVJZDogb3B0aW9ucy5nZW5lcmF0ZUlkIHx8IGZhbHNlXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY2x1c3RlclByb3BlcnRpZXM6IG9wdGlvbnMuY2x1c3RlclByb3BlcnRpZXMsXG4gICAgICAgICAgICBmaWx0ZXI6IG9wdGlvbnMuZmlsdGVyXG4gICAgICAgIH0sIG9wdGlvbnMud29ya2VyT3B0aW9ucyk7XG4gICAgfVxuXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIG9uQWRkKG1hcDogTWFwKSB7XG4gICAgICAgIHRoaXMubWFwID0gbWFwO1xuICAgICAgICB0aGlzLnNldERhdGEodGhpcy5fZGF0YSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgR2VvSlNPTiBkYXRhIGFuZCByZS1yZW5kZXJzIHRoZSBtYXAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09iamVjdCB8IHN0cmluZ30gZGF0YSBBIEdlb0pTT04gZGF0YSBvYmplY3Qgb3IgYSBVUkwgdG8gb25lLiBUaGUgbGF0dGVyIGlzIHByZWZlcmFibGUgaW4gdGhlIGNhc2Ugb2YgbGFyZ2UgR2VvSlNPTiBmaWxlcy5cbiAgICAgKiBAcmV0dXJucyB7R2VvSlNPTlNvdXJjZX0gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIG1hcC5hZGRTb3VyY2UoJ3NvdXJjZV9pZCcsIHtcbiAgICAgKiAgICAgdHlwZTogJ2dlb2pzb24nLFxuICAgICAqICAgICBkYXRhOiB7XG4gICAgICogICAgICAgICB0eXBlOiAnRmVhdHVyZUNvbGxlY3Rpb24nLFxuICAgICAqICAgICAgICAgZmVhdHVyZXM6IFtdXG4gICAgICogICAgIH1cbiAgICAgKiB9KTtcbiAgICAgKiBjb25zdCBnZW9qc29uU291cmNlID0gbWFwLmdldFNvdXJjZSgnc291cmNlX2lkJyk7XG4gICAgICogLy8gVXBkYXRlIHRoZSBkYXRhIGFmdGVyIHRoZSBHZW9KU09OIHNvdXJjZSB3YXMgY3JlYXRlZFxuICAgICAqIGdlb2pzb25Tb3VyY2Uuc2V0RGF0YSh7XG4gICAgICogICAgIFwidHlwZVwiOiBcIkZlYXR1cmVDb2xsZWN0aW9uXCIsXG4gICAgICogICAgIFwiZmVhdHVyZXNcIjogW3tcbiAgICAgKiAgICAgICAgIFwidHlwZVwiOiBcIkZlYXR1cmVcIixcbiAgICAgKiAgICAgICAgIFwicHJvcGVydGllc1wiOiB7XCJuYW1lXCI6IFwiTnVsbCBJc2xhbmRcIn0sXG4gICAgICogICAgICAgICBcImdlb21ldHJ5XCI6IHtcbiAgICAgKiAgICAgICAgICAgICBcInR5cGVcIjogXCJQb2ludFwiLFxuICAgICAqICAgICAgICAgICAgIFwiY29vcmRpbmF0ZXNcIjogWyAwLCAwIF1cbiAgICAgKiAgICAgICAgIH1cbiAgICAgKiAgICAgfV1cbiAgICAgKiB9KTtcbiAgICAgKi9cbiAgICBzZXREYXRhKGRhdGE6IEdlb0pTT04gfCBzdHJpbmcpOiB0aGlzIHtcbiAgICAgICAgdGhpcy5fZGF0YSA9IGRhdGE7XG4gICAgICAgIHRoaXMuX3VwZGF0ZVdvcmtlckRhdGEoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRm9yIGNsdXN0ZXJlZCBzb3VyY2VzLCBmZXRjaGVzIHRoZSB6b29tIGF0IHdoaWNoIHRoZSBnaXZlbiBjbHVzdGVyIGV4cGFuZHMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gY2x1c3RlcklkIFRoZSB2YWx1ZSBvZiB0aGUgY2x1c3RlcidzIGBjbHVzdGVyX2lkYCBwcm9wZXJ0eS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBBIGNhbGxiYWNrIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSB6b29tIHZhbHVlIGlzIHJldHJpZXZlZCAoYChlcnJvciwgem9vbSkgPT4geyAuLi4gfWApLlxuICAgICAqIEByZXR1cm5zIHtHZW9KU09OU291cmNlfSBSZXR1cm5zIGl0c2VsZiB0byBhbGxvdyBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gQXNzdW1pbmcgdGhlIG1hcCBoYXMgYSBsYXllciBuYW1lZCAnY2x1c3RlcnMnIGFuZCBhIHNvdXJjZSAnZWFydGhxdWFrZXMnXG4gICAgICogLy8gVGhlIGZvbGxvd2luZyBjcmVhdGVzIGEgY2FtZXJhIGFuaW1hdGlvbiBvbiBjbHVzdGVyIGZlYXR1cmUgY2xpY2tcbiAgICAgKiAvLyB0aGUgY2xpY2tlZCBsYXllciBzaG91bGQgYmUgZmlsdGVyZWQgdG8gb25seSBpbmNsdWRlIGNsdXN0ZXJzLCBlLmcuIGBmaWx0ZXI6IFsnaGFzJywgJ3BvaW50X2NvdW50J11gXG4gICAgICogbWFwLm9uKCdjbGljaycsICdjbHVzdGVycycsIChlKSA9PiB7XG4gICAgICogICAgIGNvbnN0IGZlYXR1cmVzID0gbWFwLnF1ZXJ5UmVuZGVyZWRGZWF0dXJlcyhlLnBvaW50LCB7XG4gICAgICogICAgICAgICBsYXllcnM6IFsnY2x1c3RlcnMnXVxuICAgICAqICAgICB9KTtcbiAgICAgKlxuICAgICAqICAgICBjb25zdCBjbHVzdGVySWQgPSBmZWF0dXJlc1swXS5wcm9wZXJ0aWVzLmNsdXN0ZXJfaWQ7XG4gICAgICpcbiAgICAgKiAgICAgLy8gRWFzZSB0aGUgY2FtZXJhIHRvIHRoZSBuZXh0IGNsdXN0ZXIgZXhwYW5zaW9uXG4gICAgICogICAgIG1hcC5nZXRTb3VyY2UoJ2VhcnRocXVha2VzJykuZ2V0Q2x1c3RlckV4cGFuc2lvblpvb20oXG4gICAgICogICAgICAgICBjbHVzdGVySWQsXG4gICAgICogICAgICAgICAoZXJyLCB6b29tKSA9PiB7XG4gICAgICogICAgICAgICAgICAgaWYgKCFlcnIpIHtcbiAgICAgKiAgICAgICAgICAgICAgICAgbWFwLmVhc2VUbyh7XG4gICAgICogICAgICAgICAgICAgICAgICAgICBjZW50ZXI6IGZlYXR1cmVzWzBdLmdlb21ldHJ5LmNvb3JkaW5hdGVzLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgem9vbVxuICAgICAqICAgICAgICAgICAgICAgICB9KTtcbiAgICAgKiAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICB9XG4gICAgICogICAgICk7XG4gICAgICogfSk7XG4gICAgICovXG4gICAgZ2V0Q2x1c3RlckV4cGFuc2lvblpvb20oY2x1c3RlcklkOiBudW1iZXIsIGNhbGxiYWNrOiBDYWxsYmFjazxudW1iZXI+KTogdGhpcyB7XG4gICAgICAgIHRoaXMuYWN0b3Iuc2VuZCgnZ2VvanNvbi5nZXRDbHVzdGVyRXhwYW5zaW9uWm9vbScsIHtjbHVzdGVySWQsIHNvdXJjZTogdGhpcy5pZH0sIGNhbGxiYWNrKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRm9yIGNsdXN0ZXJlZCBzb3VyY2VzLCBmZXRjaGVzIHRoZSBjaGlsZHJlbiBvZiB0aGUgZ2l2ZW4gY2x1c3RlciBvbiB0aGUgbmV4dCB6b29tIGxldmVsIChhcyBhbiBhcnJheSBvZiBHZW9KU09OIGZlYXR1cmVzKS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBjbHVzdGVySWQgVGhlIHZhbHVlIG9mIHRoZSBjbHVzdGVyJ3MgYGNsdXN0ZXJfaWRgIHByb3BlcnR5LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIEEgY2FsbGJhY2sgdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGZlYXR1cmVzIGFyZSByZXRyaWV2ZWQgKGAoZXJyb3IsIGZlYXR1cmVzKSA9PiB7IC4uLiB9YCkuXG4gICAgICogQHJldHVybnMge0dlb0pTT05Tb3VyY2V9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBSZXRyaWV2ZSBjbHVzdGVyIGNoaWxkcmVuIG9uIGNsaWNrXG4gICAgICogLy8gdGhlIGNsaWNrZWQgbGF5ZXIgc2hvdWxkIGJlIGZpbHRlcmVkIHRvIG9ubHkgaW5jbHVkZSBjbHVzdGVycywgZS5nLiBgZmlsdGVyOiBbJ2hhcycsICdwb2ludF9jb3VudCddYFxuICAgICAqIG1hcC5vbignY2xpY2snLCAnY2x1c3RlcnMnLCAoZSkgPT4ge1xuICAgICAqICAgICBjb25zdCBmZWF0dXJlcyA9IG1hcC5xdWVyeVJlbmRlcmVkRmVhdHVyZXMoZS5wb2ludCwge1xuICAgICAqICAgICAgICAgbGF5ZXJzOiBbJ2NsdXN0ZXJzJ11cbiAgICAgKiAgICAgfSk7XG4gICAgICpcbiAgICAgKiAgICAgY29uc3QgY2x1c3RlcklkID0gZmVhdHVyZXNbMF0ucHJvcGVydGllcy5jbHVzdGVyX2lkO1xuICAgICAqXG4gICAgICogICAgIGNsdXN0ZXJTb3VyY2UuZ2V0Q2x1c3RlckNoaWxkcmVuKGNsdXN0ZXJJZCwgKGVycm9yLCBmZWF0dXJlcykgPT4ge1xuICAgICAqICAgICAgICAgaWYgKCFlcnJvcikge1xuICAgICAqICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdDbHVzdGVyIGNoaWxkcmVuOicsIGZlYXR1cmVzKTtcbiAgICAgKiAgICAgICAgIH1cbiAgICAgKiAgICAgfSk7XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKi9cbiAgICBnZXRDbHVzdGVyQ2hpbGRyZW4oY2x1c3RlcklkOiBudW1iZXIsIGNhbGxiYWNrOiBDYWxsYmFjazxBcnJheTxHZW9KU09ORmVhdHVyZT4+KTogdGhpcyB7XG4gICAgICAgIHRoaXMuYWN0b3Iuc2VuZCgnZ2VvanNvbi5nZXRDbHVzdGVyQ2hpbGRyZW4nLCB7Y2x1c3RlcklkLCBzb3VyY2U6IHRoaXMuaWR9LCBjYWxsYmFjayk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZvciBjbHVzdGVyZWQgc291cmNlcywgZmV0Y2hlcyB0aGUgb3JpZ2luYWwgcG9pbnRzIHRoYXQgYmVsb25nIHRvIHRoZSBjbHVzdGVyIChhcyBhbiBhcnJheSBvZiBHZW9KU09OIGZlYXR1cmVzKS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBjbHVzdGVySWQgVGhlIHZhbHVlIG9mIHRoZSBjbHVzdGVyJ3MgYGNsdXN0ZXJfaWRgIHByb3BlcnR5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBsaW1pdCBUaGUgbWF4aW11bSBudW1iZXIgb2YgZmVhdHVyZXMgdG8gcmV0dXJuLiBEZWZhdWx0cyB0byBgMTBgIGlmIGEgZmFsc3kgdmFsdWUgaXMgZ2l2ZW4uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBUaGUgbnVtYmVyIG9mIGZlYXR1cmVzIHRvIHNraXAgKGZvciBleGFtcGxlLCBmb3IgcGFnaW5hdGlvbikuIERlZmF1bHRzIHRvIGAwYCBpZiBhIGZhbHN5IHZhbHVlIGlzIGdpdmVuLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIEEgY2FsbGJhY2sgdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGZlYXR1cmVzIGFyZSByZXRyaWV2ZWQgKGAoZXJyb3IsIGZlYXR1cmVzKSA9PiB7IC4uLiB9YCkuXG4gICAgICogQHJldHVybnMge0dlb0pTT05Tb3VyY2V9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBSZXRyaWV2ZSBjbHVzdGVyIGxlYXZlcyBvbiBjbGlja1xuICAgICAqIC8vIHRoZSBjbGlja2VkIGxheWVyIHNob3VsZCBiZSBmaWx0ZXJlZCB0byBvbmx5IGluY2x1ZGUgY2x1c3RlcnMsIGUuZy4gYGZpbHRlcjogWydoYXMnLCAncG9pbnRfY291bnQnXWBcbiAgICAgKiBtYXAub24oJ2NsaWNrJywgJ2NsdXN0ZXJzJywgKGUpID0+IHtcbiAgICAgKiAgICAgY29uc3QgZmVhdHVyZXMgPSBtYXAucXVlcnlSZW5kZXJlZEZlYXR1cmVzKGUucG9pbnQsIHtcbiAgICAgKiAgICAgICAgIGxheWVyczogWydjbHVzdGVycyddXG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogICAgIGNvbnN0IGNsdXN0ZXJJZCA9IGZlYXR1cmVzWzBdLnByb3BlcnRpZXMuY2x1c3Rlcl9pZDtcbiAgICAgKiAgICAgY29uc3QgcG9pbnRDb3VudCA9IGZlYXR1cmVzWzBdLnByb3BlcnRpZXMucG9pbnRfY291bnQ7XG4gICAgICogICAgIGNvbnN0IGNsdXN0ZXJTb3VyY2UgPSBtYXAuZ2V0U291cmNlKCdjbHVzdGVycycpO1xuICAgICAqXG4gICAgICogICAgIGNsdXN0ZXJTb3VyY2UuZ2V0Q2x1c3RlckxlYXZlcyhjbHVzdGVySWQsIHBvaW50Q291bnQsIDAsIChlcnJvciwgZmVhdHVyZXMpID0+IHtcbiAgICAgKiAgICAgLy8gUHJpbnQgY2x1c3RlciBsZWF2ZXMgaW4gdGhlIGNvbnNvbGVcbiAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKCdDbHVzdGVyIGxlYXZlczonLCBlcnJvciwgZmVhdHVyZXMpO1xuICAgICAqICAgICB9KTtcbiAgICAgKiB9KTtcbiAgICAgKi9cbiAgICBnZXRDbHVzdGVyTGVhdmVzKGNsdXN0ZXJJZDogbnVtYmVyLCBsaW1pdDogbnVtYmVyLCBvZmZzZXQ6IG51bWJlciwgY2FsbGJhY2s6IENhbGxiYWNrPEFycmF5PEdlb0pTT05GZWF0dXJlPj4pOiB0aGlzIHtcbiAgICAgICAgdGhpcy5hY3Rvci5zZW5kKCdnZW9qc29uLmdldENsdXN0ZXJMZWF2ZXMnLCB7XG4gICAgICAgICAgICBzb3VyY2U6IHRoaXMuaWQsXG4gICAgICAgICAgICBjbHVzdGVySWQsXG4gICAgICAgICAgICBsaW1pdCxcbiAgICAgICAgICAgIG9mZnNldFxuICAgICAgICB9LCBjYWxsYmFjayk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qXG4gICAgICogUmVzcG9uc2libGUgZm9yIGludm9raW5nIFdvcmtlclNvdXJjZSdzIGdlb2pzb24ubG9hZERhdGEgdGFyZ2V0LCB3aGljaFxuICAgICAqIGhhbmRsZXMgbG9hZGluZyB0aGUgZ2VvanNvbiBkYXRhIGFuZCBwcmVwYXJpbmcgdG8gc2VydmUgaXQgdXAgYXMgdGlsZXMsXG4gICAgICogdXNpbmcgZ2VvanNvbi12dCBvciBzdXBlcmNsdXN0ZXIgYXMgYXBwcm9wcmlhdGUuXG4gICAgICovXG4gICAgX3VwZGF0ZVdvcmtlckRhdGEoKSB7XG4gICAgICAgIC8vIGlmIHRoZXJlJ3MgYW4gZWFybGllciBsb2FkRGF0YSB0byBmaW5pc2gsIHdhaXQgdW50aWwgaXQgZmluaXNoZXMgYW5kIHRoZW4gZG8gYW5vdGhlciB1cGRhdGVcbiAgICAgICAgaWYgKHRoaXMuX3BlbmRpbmdMb2FkKSB7XG4gICAgICAgICAgICB0aGlzLl9jb2FsZXNjZSA9IHRydWU7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmZpcmUobmV3IEV2ZW50KCdkYXRhbG9hZGluZycsIHtkYXRhVHlwZTogJ3NvdXJjZSd9KSk7XG5cbiAgICAgICAgdGhpcy5fbG9hZGVkID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBleHRlbmQoe30sIHRoaXMud29ya2VyT3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhO1xuICAgICAgICBpZiAodHlwZW9mIGRhdGEgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBvcHRpb25zLnJlcXVlc3QgPSB0aGlzLm1hcC5fcmVxdWVzdE1hbmFnZXIudHJhbnNmb3JtUmVxdWVzdChicm93c2VyLnJlc29sdmVVUkwoZGF0YSksIFJlc291cmNlVHlwZS5Tb3VyY2UpO1xuICAgICAgICAgICAgb3B0aW9ucy5yZXF1ZXN0LmNvbGxlY3RSZXNvdXJjZVRpbWluZyA9IHRoaXMuX2NvbGxlY3RSZXNvdXJjZVRpbWluZztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG9wdGlvbnMuZGF0YSA9IEpTT04uc3RyaW5naWZ5KGRhdGEpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdGFyZ2V0IHt0aGlzLnR5cGV9LmxvYWREYXRhIHJhdGhlciB0aGFuIGxpdGVyYWxseSBnZW9qc29uLmxvYWREYXRhLFxuICAgICAgICAvLyBzbyB0aGF0IG90aGVyIGdlb2pzb24tbGlrZSBzb3VyY2UgdHlwZXMgY2FuIGVhc2lseSByZXVzZSB0aGlzXG4gICAgICAgIC8vIGltcGxlbWVudGF0aW9uXG4gICAgICAgIHRoaXMuX3BlbmRpbmdMb2FkID0gdGhpcy5hY3Rvci5zZW5kKGAke3RoaXMudHlwZX0ubG9hZERhdGFgLCBvcHRpb25zLCAoZXJyLCByZXN1bHQpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2xvYWRlZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLl9wZW5kaW5nTG9hZCA9IG51bGw7XG5cbiAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpcmUobmV3IEVycm9yRXZlbnQoZXJyKSk7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gYWx0aG91Z2ggR2VvSlNPTiBzb3VyY2VzIGNvbnRhaW4gbm8gbWV0YWRhdGEsIHdlIGZpcmUgdGhpcyBldmVudCBhdCBmaXJzdFxuICAgICAgICAgICAgICAgIC8vIHRvIGxldCB0aGUgU291cmNlQ2FjaGUga25vdyBpdHMgb2sgdG8gc3RhcnQgcmVxdWVzdGluZyB0aWxlcy5cbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhOiBPYmplY3QgPSB7ZGF0YVR5cGU6ICdzb3VyY2UnLCBzb3VyY2VEYXRhVHlwZTogdGhpcy5fbWV0YWRhdGFGaXJlZCA/ICdjb250ZW50JyA6ICdtZXRhZGF0YSd9O1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9jb2xsZWN0UmVzb3VyY2VUaW1pbmcgJiYgcmVzdWx0ICYmIHJlc3VsdC5yZXNvdXJjZVRpbWluZyAmJiByZXN1bHQucmVzb3VyY2VUaW1pbmdbdGhpcy5pZF0pIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YS5yZXNvdXJjZVRpbWluZyA9IHJlc3VsdC5yZXNvdXJjZVRpbWluZ1t0aGlzLmlkXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgnZGF0YScsIGRhdGEpKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9tZXRhZGF0YUZpcmVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMuX2NvYWxlc2NlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdXBkYXRlV29ya2VyRGF0YSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2NvYWxlc2NlID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGxvYWRlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRlZDtcbiAgICB9XG5cbiAgICBsb2FkVGlsZSh0aWxlOiBUaWxlLCBjYWxsYmFjazogQ2FsbGJhY2s8dm9pZD4pIHtcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9ICF0aWxlLmFjdG9yID8gJ2xvYWRUaWxlJyA6ICdyZWxvYWRUaWxlJztcbiAgICAgICAgdGlsZS5hY3RvciA9IHRoaXMuYWN0b3I7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgICAgICAgIHVpZDogdGlsZS51aWQsXG4gICAgICAgICAgICB0aWxlSUQ6IHRpbGUudGlsZUlELFxuICAgICAgICAgICAgdGlsZVpvb206IHRpbGUudGlsZVpvb20sXG4gICAgICAgICAgICB6b29tOiB0aWxlLnRpbGVJRC5vdmVyc2NhbGVkWixcbiAgICAgICAgICAgIG1heFpvb206IHRoaXMubWF4em9vbSxcbiAgICAgICAgICAgIHRpbGVTaXplOiB0aGlzLnRpbGVTaXplLFxuICAgICAgICAgICAgc291cmNlOiB0aGlzLmlkLFxuICAgICAgICAgICAgcGl4ZWxSYXRpbzogYnJvd3Nlci5kZXZpY2VQaXhlbFJhdGlvLFxuICAgICAgICAgICAgc2hvd0NvbGxpc2lvbkJveGVzOiB0aGlzLm1hcC5zaG93Q29sbGlzaW9uQm94ZXMsXG4gICAgICAgICAgICBwcm9tb3RlSWQ6IHRoaXMucHJvbW90ZUlkXG4gICAgICAgIH07XG5cbiAgICAgICAgdGlsZS5yZXF1ZXN0ID0gdGhpcy5hY3Rvci5zZW5kKG1lc3NhZ2UsIHBhcmFtcywgKGVyciwgZGF0YSkgPT4ge1xuICAgICAgICAgICAgZGVsZXRlIHRpbGUucmVxdWVzdDtcbiAgICAgICAgICAgIHRpbGUudW5sb2FkVmVjdG9yRGF0YSgpO1xuXG4gICAgICAgICAgICBpZiAodGlsZS5hYm9ydGVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRpbGUubG9hZFZlY3RvckRhdGEoZGF0YSwgdGhpcy5tYXAucGFpbnRlciwgbWVzc2FnZSA9PT0gJ3JlbG9hZFRpbGUnKTtcblxuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwpO1xuICAgICAgICB9LCB1bmRlZmluZWQsIG1lc3NhZ2UgPT09ICdsb2FkVGlsZScpO1xuICAgIH1cblxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICBhYm9ydFRpbGUodGlsZTogVGlsZSkge1xuICAgICAgICBpZiAodGlsZS5yZXF1ZXN0KSB7XG4gICAgICAgICAgICB0aWxlLnJlcXVlc3QuY2FuY2VsKCk7XG4gICAgICAgICAgICBkZWxldGUgdGlsZS5yZXF1ZXN0O1xuICAgICAgICB9XG4gICAgICAgIHRpbGUuYWJvcnRlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIHVubG9hZFRpbGUodGlsZTogVGlsZSkge1xuICAgICAgICB0aWxlLnVubG9hZFZlY3RvckRhdGEoKTtcbiAgICAgICAgdGhpcy5hY3Rvci5zZW5kKCdyZW1vdmVUaWxlJywge3VpZDogdGlsZS51aWQsIHR5cGU6IHRoaXMudHlwZSwgc291cmNlOiB0aGlzLmlkfSk7XG4gICAgfVxuXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIG9uUmVtb3ZlKCkge1xuICAgICAgICBpZiAodGhpcy5fcGVuZGluZ0xvYWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3BlbmRpbmdMb2FkLmNhbmNlbCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2VyaWFsaXplKCk6IEdlb0pTT05Tb3VyY2VTcGVjaWZpY2F0aW9uIHtcbiAgICAgICAgcmV0dXJuIGV4dGVuZCh7fSwgdGhpcy5fb3B0aW9ucywge1xuICAgICAgICAgICAgdHlwZTogdGhpcy50eXBlLFxuICAgICAgICAgICAgZGF0YTogdGhpcy5fZGF0YVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBoYXNUcmFuc2l0aW9uKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBHZW9KU09OU291cmNlO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtDYW5vbmljYWxUaWxlSUR9IGZyb20gJy4vdGlsZV9pZC5qcyc7XG5pbXBvcnQge0V2ZW50LCBFcnJvckV2ZW50LCBFdmVudGVkfSBmcm9tICcuLi91dGlsL2V2ZW50ZWQuanMnO1xuaW1wb3J0IHtnZXRJbWFnZSwgUmVzb3VyY2VUeXBlfSBmcm9tICcuLi91dGlsL2FqYXguanMnO1xuaW1wb3J0IEVYVEVOVCBmcm9tICcuLi9kYXRhL2V4dGVudC5qcyc7XG5pbXBvcnQge1Jhc3RlckJvdW5kc0FycmF5fSBmcm9tICcuLi9kYXRhL2FycmF5X3R5cGVzLmpzJztcbmltcG9ydCBib3VuZHNBdHRyaWJ1dGVzIGZyb20gJy4uL2RhdGEvYm91bmRzX2F0dHJpYnV0ZXMuanMnO1xuaW1wb3J0IFNlZ21lbnRWZWN0b3IgZnJvbSAnLi4vZGF0YS9zZWdtZW50LmpzJztcbmltcG9ydCBUZXh0dXJlIGZyb20gJy4uL3JlbmRlci90ZXh0dXJlLmpzJztcbmltcG9ydCBNZXJjYXRvckNvb3JkaW5hdGUgZnJvbSAnLi4vZ2VvL21lcmNhdG9yX2Nvb3JkaW5hdGUuanMnO1xuaW1wb3J0IGJyb3dzZXIgZnJvbSAnLi4vdXRpbC9icm93c2VyLmpzJztcbmltcG9ydCB0aWxlVHJhbnNmb3JtLCB7Z2V0VGlsZVBvaW50fSBmcm9tICcuLi9nZW8vcHJvamVjdGlvbi90aWxlX3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQge21hdDMsIHZlYzN9IGZyb20gJ2dsLW1hdHJpeCc7XG5pbXBvcnQgd2luZG93IGZyb20gJy4uL3V0aWwvd2luZG93LmpzJztcblxuaW1wb3J0IHR5cGUge1NvdXJjZX0gZnJvbSAnLi9zb3VyY2UuanMnO1xuaW1wb3J0IHR5cGUge0NhbnZhc1NvdXJjZVNwZWNpZmljYXRpb259IGZyb20gJy4vY2FudmFzX3NvdXJjZS5qcyc7XG5pbXBvcnQgdHlwZSBNYXAgZnJvbSAnLi4vdWkvbWFwLmpzJztcbmltcG9ydCB0eXBlIERpc3BhdGNoZXIgZnJvbSAnLi4vdXRpbC9kaXNwYXRjaGVyLmpzJztcbmltcG9ydCB0eXBlIFRpbGUgZnJvbSAnLi90aWxlLmpzJztcbmltcG9ydCB0eXBlIHtDYWxsYmFja30gZnJvbSAnLi4vdHlwZXMvY2FsbGJhY2suanMnO1xuaW1wb3J0IHR5cGUge0NhbmNlbGFibGV9IGZyb20gJy4uL3R5cGVzL2NhbmNlbGFibGUuanMnO1xuaW1wb3J0IHR5cGUgVmVydGV4QnVmZmVyIGZyb20gJy4uL2dsL3ZlcnRleF9idWZmZXIuanMnO1xuaW1wb3J0IHR5cGUge1xuICAgIEltYWdlU291cmNlU3BlY2lmaWNhdGlvbixcbiAgICBWaWRlb1NvdXJjZVNwZWNpZmljYXRpb25cbn0gZnJvbSAnLi4vc3R5bGUtc3BlYy90eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSBDb250ZXh0IGZyb20gJy4uL2dsL2NvbnRleHQuanMnO1xuXG50eXBlIENvb3JkaW5hdGVzID0gW1tudW1iZXIsIG51bWJlcl0sIFtudW1iZXIsIG51bWJlcl0sIFtudW1iZXIsIG51bWJlcl0sIFtudW1iZXIsIG51bWJlcl1dO1xuXG4vLyBwZXJzcGVjdGl2ZSBjb3JyZWN0aW9uIGZvciB0ZXh0dXJlIG1hcHBpbmcsIHNlZSBodHRwczovL2dpdGh1Yi5jb20vbWFwYm94L21hcGJveC1nbC1qcy9pc3N1ZXMvOTE1OFxuLy8gYWRhcHRlZCBmcm9tIGh0dHBzOi8vbWF0aC5zdGFja2V4Y2hhbmdlLmNvbS9hLzMzOTAzMy80ODY1M1xuXG5mdW5jdGlvbiBiYXNpc1RvUG9pbnRzKHgxOiBudW1iZXIsIHkxOiBudW1iZXIsIHgyOiBudW1iZXIsIHkyOiBudW1iZXIsIHgzOiBudW1iZXIsIHkzOiBudW1iZXIsIHg0OiBudW1iZXIsIHk0OiBudW1iZXIpIHtcbiAgICBjb25zdCBtID0gW3gxLCB4MiwgeDMsIHkxLCB5MiwgeTMsIDEsIDEsIDFdO1xuICAgIGNvbnN0IHMgPSBbeDQsIHk0LCAxXTtcbiAgICBjb25zdCBtYSA9IG1hdDMuYWRqb2ludChbXSwgbSk7XG4gICAgY29uc3QgW3N4LCBzeSwgc3pdID0gdmVjMy50cmFuc2Zvcm1NYXQzKHMsIHMsIG1hdDMudHJhbnNwb3NlKG1hLCBtYSkpO1xuICAgIHJldHVybiBtYXQzLm11bHRpcGx5KG0sIFtzeCwgMCwgMCwgMCwgc3ksIDAsIDAsIDAsIHN6XSwgbSk7XG59XG5cbmZ1bmN0aW9uIGdldFBlcnNwZWN0aXZlVHJhbnNmb3JtKHc6IG51bWJlciwgaDogbnVtYmVyLCB4MTogbnVtYmVyLCB5MTogbnVtYmVyLCB4MjogbnVtYmVyLCB5MjogbnVtYmVyLCB4MzogbnVtYmVyLCB5MzogbnVtYmVyLCB4NDogbnVtYmVyLCB5NDogbnVtYmVyKSB7XG4gICAgY29uc3QgcyA9IGJhc2lzVG9Qb2ludHMoMCwgMCwgdywgMCwgMCwgaCwgdywgaCk7XG4gICAgY29uc3QgbSA9IGJhc2lzVG9Qb2ludHMoeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgeDQsIHk0KTtcbiAgICBtYXQzLm11bHRpcGx5KG0sIG1hdDMuYWRqb2ludChzLCBzKSwgbSk7XG4gICAgcmV0dXJuIFtcbiAgICAgICAgbVs2XSAvIG1bOF0gKiB3IC8gRVhURU5ULFxuICAgICAgICBtWzddIC8gbVs4XSAqIGggLyBFWFRFTlRcbiAgICBdO1xufVxuXG4vKipcbiAqIEEgZGF0YSBzb3VyY2UgY29udGFpbmluZyBhbiBpbWFnZS5cbiAqIFNlZSB0aGUgW1N0eWxlIFNwZWNpZmljYXRpb25dKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLXN0eWxlLXNwZWMvI3NvdXJjZXMtaW1hZ2UpIGZvciBkZXRhaWxlZCBkb2N1bWVudGF0aW9uIG9mIG9wdGlvbnMuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIGFkZCB0byBtYXBcbiAqIG1hcC5hZGRTb3VyY2UoJ3NvbWUgaWQnLCB7XG4gKiAgICAgdHlwZTogJ2ltYWdlJyxcbiAqICAgICB1cmw6ICdodHRwczovL3d3dy5tYXBib3guY29tL2ltYWdlcy9mb28ucG5nJyxcbiAqICAgICBjb29yZGluYXRlczogW1xuICogICAgICAgICBbLTc2LjU0LCAzOS4xOF0sXG4gKiAgICAgICAgIFstNzYuNTIsIDM5LjE4XSxcbiAqICAgICAgICAgWy03Ni41MiwgMzkuMTddLFxuICogICAgICAgICBbLTc2LjU0LCAzOS4xN11cbiAqICAgICBdXG4gKiB9KTtcbiAqXG4gKiAvLyB1cGRhdGUgY29vcmRpbmF0ZXNcbiAqIGNvbnN0IG15U291cmNlID0gbWFwLmdldFNvdXJjZSgnc29tZSBpZCcpO1xuICogbXlTb3VyY2Uuc2V0Q29vcmRpbmF0ZXMoW1xuICogICAgIFstNzYuNTQzMzU3MzcyMjgzOTQsIDM5LjE4NTc5OTA3MjI5NzQ4XSxcbiAqICAgICBbLTc2LjUyODAzNjU5NDM5MDg3LCAzOS4xODM4MzY0ODQ3NTg3XSxcbiAqICAgICBbLTc2LjUyOTUzODYzMTQzOTIsIDM5LjE3NjgzMzkyNTA3NjA2XSxcbiAqICAgICBbLTc2LjU0NTIwMjczMjA4NjE4LCAzOS4xNzg3NjM0NDEwNjY0Ml1cbiAqIF0pO1xuICpcbiAqIC8vIHVwZGF0ZSB1cmwgYW5kIGNvb3JkaW5hdGVzIHNpbXVsdGFuZW91c2x5XG4gKiBteVNvdXJjZS51cGRhdGVJbWFnZSh7XG4gKiAgICAgdXJsOiAnaHR0cHM6Ly93d3cubWFwYm94LmNvbS9pbWFnZXMvYmFyLnBuZycsXG4gKiAgICAgY29vcmRpbmF0ZXM6IFtcbiAqICAgICAgICAgWy03Ni41NDMzNTczNzIyODM5NCwgMzkuMTg1Nzk5MDcyMjk3NDhdLFxuICogICAgICAgICBbLTc2LjUyODAzNjU5NDM5MDg3LCAzOS4xODM4MzY0ODQ3NTg3XSxcbiAqICAgICAgICAgWy03Ni41Mjk1Mzg2MzE0MzkyLCAzOS4xNzY4MzM5MjUwNzYwNl0sXG4gKiAgICAgICAgIFstNzYuNTQ1MjAyNzMyMDg2MTgsIDM5LjE3ODc2MzQ0MTA2NjQyXVxuICogICAgIF1cbiAqIH0pO1xuICpcbiAqIG1hcC5yZW1vdmVTb3VyY2UoJ3NvbWUgaWQnKTsgIC8vIHJlbW92ZVxuICogQHNlZSBbRXhhbXBsZTogQWRkIGFuIGltYWdlXShodHRwczovL3d3dy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2ltYWdlLW9uLWEtbWFwLylcbiAqIEBzZWUgW0V4YW1wbGU6IEFuaW1hdGUgYSBzZXJpZXMgb2YgaW1hZ2VzXShodHRwczovL3d3dy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2FuaW1hdGUtaW1hZ2VzLylcbiAqL1xuY2xhc3MgSW1hZ2VTb3VyY2UgZXh0ZW5kcyBFdmVudGVkIGltcGxlbWVudHMgU291cmNlIHtcbiAgICB0eXBlOiBzdHJpbmc7XG4gICAgaWQ6IHN0cmluZztcbiAgICBtaW56b29tOiBudW1iZXI7XG4gICAgbWF4em9vbTogbnVtYmVyO1xuICAgIHRpbGVTaXplOiBudW1iZXI7XG4gICAgdXJsOiBzdHJpbmc7XG4gICAgd2lkdGg6IG51bWJlcjtcbiAgICBoZWlnaHQ6IG51bWJlcjtcblxuICAgIGNvb3JkaW5hdGVzOiBDb29yZGluYXRlcztcbiAgICB0aWxlczoge1tfOiBzdHJpbmddOiBUaWxlfTtcbiAgICBvcHRpb25zOiBhbnk7XG4gICAgZGlzcGF0Y2hlcjogRGlzcGF0Y2hlcjtcbiAgICBtYXA6IE1hcDtcbiAgICB0ZXh0dXJlOiBUZXh0dXJlIHwgbnVsbDtcbiAgICBpbWFnZTogSFRNTEltYWdlRWxlbWVudCB8IEltYWdlQml0bWFwIHwgSW1hZ2VEYXRhO1xuICAgIC8vICRGbG93Rml4TWVcbiAgICB0aWxlSUQ6IENhbm9uaWNhbFRpbGVJRDtcbiAgICBfYm91bmRzQXJyYXk6ID9SYXN0ZXJCb3VuZHNBcnJheTtcbiAgICBib3VuZHNCdWZmZXI6ID9WZXJ0ZXhCdWZmZXI7XG4gICAgYm91bmRzU2VnbWVudHM6ID9TZWdtZW50VmVjdG9yO1xuICAgIF9sb2FkZWQ6IGJvb2xlYW47XG4gICAgX2RpcnR5OiBib29sZWFuO1xuICAgIF9pbWFnZVJlcXVlc3Q6ID9DYW5jZWxhYmxlO1xuICAgIHBlcnNwZWN0aXZlVHJhbnNmb3JtOiBbbnVtYmVyLCBudW1iZXJdO1xuXG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihpZDogc3RyaW5nLCBvcHRpb25zOiBJbWFnZVNvdXJjZVNwZWNpZmljYXRpb24gfCBWaWRlb1NvdXJjZVNwZWNpZmljYXRpb24gfCBDYW52YXNTb3VyY2VTcGVjaWZpY2F0aW9uLCBkaXNwYXRjaGVyOiBEaXNwYXRjaGVyLCBldmVudGVkUGFyZW50OiBFdmVudGVkKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuaWQgPSBpZDtcbiAgICAgICAgdGhpcy5kaXNwYXRjaGVyID0gZGlzcGF0Y2hlcjtcbiAgICAgICAgdGhpcy5jb29yZGluYXRlcyA9IG9wdGlvbnMuY29vcmRpbmF0ZXM7XG5cbiAgICAgICAgdGhpcy50eXBlID0gJ2ltYWdlJztcbiAgICAgICAgdGhpcy5taW56b29tID0gMDtcbiAgICAgICAgdGhpcy5tYXh6b29tID0gMjI7XG4gICAgICAgIHRoaXMudGlsZVNpemUgPSA1MTI7XG4gICAgICAgIHRoaXMudGlsZXMgPSB7fTtcbiAgICAgICAgdGhpcy5fbG9hZGVkID0gZmFsc2U7XG5cbiAgICAgICAgdGhpcy5zZXRFdmVudGVkUGFyZW50KGV2ZW50ZWRQYXJlbnQpO1xuXG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgICAgIHRoaXMuX2RpcnR5ID0gZmFsc2U7XG4gICAgfVxuXG4gICAgbG9hZChuZXdDb29yZGluYXRlcz86IENvb3JkaW5hdGVzLCBsb2FkZWQ/OiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMuX2xvYWRlZCA9IGxvYWRlZCB8fCBmYWxzZTtcbiAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgnZGF0YWxvYWRpbmcnLCB7ZGF0YVR5cGU6ICdzb3VyY2UnfSkpO1xuXG4gICAgICAgIHRoaXMudXJsID0gdGhpcy5vcHRpb25zLnVybDtcblxuICAgICAgICB0aGlzLl9pbWFnZVJlcXVlc3QgPSBnZXRJbWFnZSh0aGlzLm1hcC5fcmVxdWVzdE1hbmFnZXIudHJhbnNmb3JtUmVxdWVzdCh0aGlzLnVybCwgUmVzb3VyY2VUeXBlLkltYWdlKSwgKGVyciwgaW1hZ2UpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2ltYWdlUmVxdWVzdCA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLl9sb2FkZWQgPSB0cnVlO1xuICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXJyb3JFdmVudChlcnIpKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaW1hZ2UpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB7SFRNTEltYWdlRWxlbWVudH0gPSB3aW5kb3c7XG4gICAgICAgICAgICAgICAgaWYgKGltYWdlIGluc3RhbmNlb2YgSFRNTEltYWdlRWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmltYWdlID0gYnJvd3Nlci5nZXRJbWFnZURhdGEoaW1hZ2UpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW1hZ2UgPSBpbWFnZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5fZGlydHkgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMud2lkdGggPSB0aGlzLmltYWdlLndpZHRoO1xuICAgICAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gdGhpcy5pbWFnZS5oZWlnaHQ7XG4gICAgICAgICAgICAgICAgaWYgKG5ld0Nvb3JkaW5hdGVzKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29vcmRpbmF0ZXMgPSBuZXdDb29yZGluYXRlcztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5fZmluaXNoTG9hZGluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBsb2FkZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb2FkZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXBkYXRlcyB0aGUgaW1hZ2UgVVJMIGFuZCwgb3B0aW9uYWxseSwgdGhlIGNvb3JkaW5hdGVzLiBUbyBhdm9pZCBoYXZpbmcgdGhlIGltYWdlIGZsYXNoIGFmdGVyIGNoYW5naW5nLFxuICAgICAqIHNldCB0aGUgYHJhc3Rlci1mYWRlLWR1cmF0aW9uYCBwYWludCBwcm9wZXJ0eSBvbiB0aGUgcmFzdGVyIGxheWVyIHRvIDAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBPcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdGlvbnMudXJsXSBSZXF1aXJlZCBpbWFnZSBVUkwuXG4gICAgICogQHBhcmFtIHtBcnJheTxBcnJheTxudW1iZXI+Pn0gW29wdGlvbnMuY29vcmRpbmF0ZXNdIEZvdXIgZ2VvZ3JhcGhpY2FsIGNvb3JkaW5hdGVzLFxuICAgICAqICAgcmVwcmVzZW50ZWQgYXMgYXJyYXlzIG9mIGxvbmdpdHVkZSBhbmQgbGF0aXR1ZGUgbnVtYmVycywgd2hpY2ggZGVmaW5lIHRoZSBjb3JuZXJzIG9mIHRoZSBpbWFnZS5cbiAgICAgKiAgIFRoZSBjb29yZGluYXRlcyBzdGFydCBhdCB0aGUgdG9wIGxlZnQgY29ybmVyIG9mIHRoZSBpbWFnZSBhbmQgcHJvY2VlZCBpbiBjbG9ja3dpc2Ugb3JkZXIuXG4gICAgICogICBUaGV5IGRvIG5vdCBoYXZlIHRvIHJlcHJlc2VudCBhIHJlY3RhbmdsZS5cbiAgICAgKiBAcmV0dXJucyB7SW1hZ2VTb3VyY2V9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBBZGQgdG8gYW4gaW1hZ2Ugc291cmNlIHRvIHRoZSBtYXAgd2l0aCBzb21lIGluaXRpYWwgVVJMIGFuZCBjb29yZGluYXRlc1xuICAgICAqIG1hcC5hZGRTb3VyY2UoJ2ltYWdlX3NvdXJjZV9pZCcsIHtcbiAgICAgKiAgICAgdHlwZTogJ2ltYWdlJyxcbiAgICAgKiAgICAgdXJsOiAnaHR0cHM6Ly93d3cubWFwYm94LmNvbS9pbWFnZXMvZm9vLnBuZycsXG4gICAgICogICAgIGNvb3JkaW5hdGVzOiBbXG4gICAgICogICAgICAgICBbLTc2LjU0LCAzOS4xOF0sXG4gICAgICogICAgICAgICBbLTc2LjUyLCAzOS4xOF0sXG4gICAgICogICAgICAgICBbLTc2LjUyLCAzOS4xN10sXG4gICAgICogICAgICAgICBbLTc2LjU0LCAzOS4xN11cbiAgICAgKiAgICAgXVxuICAgICAqIH0pO1xuICAgICAqIC8vIFRoZW4gdXBkYXRlIHRoZSBpbWFnZSBVUkwgYW5kIGNvb3JkaW5hdGVzXG4gICAgICogaW1hZ2VTb3VyY2UudXBkYXRlSW1hZ2Uoe1xuICAgICAqICAgICB1cmw6ICdodHRwczovL3d3dy5tYXBib3guY29tL2ltYWdlcy9iYXIucG5nJyxcbiAgICAgKiAgICAgY29vcmRpbmF0ZXM6IFtcbiAgICAgKiAgICAgICAgIFstNzYuNTQzMywgMzkuMTg1N10sXG4gICAgICogICAgICAgICBbLTc2LjUyODAsIDM5LjE4MzhdLFxuICAgICAqICAgICAgICAgWy03Ni41Mjk1LCAzOS4xNzY4XSxcbiAgICAgKiAgICAgICAgIFstNzYuNTQ1MiwgMzkuMTc4N11cbiAgICAgKiAgICAgXVxuICAgICAqIH0pO1xuICAgICAqL1xuICAgIHVwZGF0ZUltYWdlKG9wdGlvbnM6IHt1cmw6IHN0cmluZywgY29vcmRpbmF0ZXM/OiBDb29yZGluYXRlc30pOiB0aGlzIHtcbiAgICAgICAgaWYgKCF0aGlzLmltYWdlIHx8ICFvcHRpb25zLnVybCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX2ltYWdlUmVxdWVzdCAmJiBvcHRpb25zLnVybCAhPT0gdGhpcy5vcHRpb25zLnVybCkge1xuICAgICAgICAgICAgdGhpcy5faW1hZ2VSZXF1ZXN0LmNhbmNlbCgpO1xuICAgICAgICAgICAgdGhpcy5faW1hZ2VSZXF1ZXN0ID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9wdGlvbnMudXJsID0gb3B0aW9ucy51cmw7XG4gICAgICAgIHRoaXMubG9hZChvcHRpb25zLmNvb3JkaW5hdGVzLCB0aGlzLl9sb2FkZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBfZmluaXNoTG9hZGluZygpIHtcbiAgICAgICAgaWYgKHRoaXMubWFwKSB7XG4gICAgICAgICAgICB0aGlzLnNldENvb3JkaW5hdGVzKHRoaXMuY29vcmRpbmF0ZXMpO1xuICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgnZGF0YScsIHtkYXRhVHlwZTogJ3NvdXJjZScsIHNvdXJjZURhdGFUeXBlOiAnbWV0YWRhdGEnfSkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIG9uQWRkKG1hcDogTWFwKSB7XG4gICAgICAgIHRoaXMubWFwID0gbWFwO1xuICAgICAgICB0aGlzLmxvYWQoKTtcbiAgICB9XG5cbiAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgb25SZW1vdmUoKSB7XG4gICAgICAgIGlmICh0aGlzLl9pbWFnZVJlcXVlc3QpIHtcbiAgICAgICAgICAgIHRoaXMuX2ltYWdlUmVxdWVzdC5jYW5jZWwoKTtcbiAgICAgICAgICAgIHRoaXMuX2ltYWdlUmVxdWVzdCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMudGV4dHVyZSkgdGhpcy50ZXh0dXJlLmRlc3Ryb3koKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBpbWFnZSdzIGNvb3JkaW5hdGVzIGFuZCByZS1yZW5kZXJzIHRoZSBtYXAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0FycmF5PEFycmF5PG51bWJlcj4+fSBjb29yZGluYXRlcyBGb3VyIGdlb2dyYXBoaWNhbCBjb29yZGluYXRlcyxcbiAgICAgKiAgIHJlcHJlc2VudGVkIGFzIGFycmF5cyBvZiBsb25naXR1ZGUgYW5kIGxhdGl0dWRlIG51bWJlcnMsIHdoaWNoIGRlZmluZSB0aGUgY29ybmVycyBvZiB0aGUgaW1hZ2UuXG4gICAgICogICBUaGUgY29vcmRpbmF0ZXMgc3RhcnQgYXQgdGhlIHRvcCBsZWZ0IGNvcm5lciBvZiB0aGUgaW1hZ2UgYW5kIHByb2NlZWQgaW4gY2xvY2t3aXNlIG9yZGVyLlxuICAgICAqICAgVGhleSBkbyBub3QgaGF2ZSB0byByZXByZXNlbnQgYSByZWN0YW5nbGUuXG4gICAgICogQHJldHVybnMge0ltYWdlU291cmNlfSBSZXR1cm5zIGl0c2VsZiB0byBhbGxvdyBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gQWRkIGFuIGltYWdlIHNvdXJjZSB0byB0aGUgbWFwIHdpdGggc29tZSBpbml0aWFsIGNvb3JkaW5hdGVzXG4gICAgICogbWFwLmFkZFNvdXJjZSgnaW1hZ2Vfc291cmNlX2lkJywge1xuICAgICAqICAgICB0eXBlOiAnaW1hZ2UnLFxuICAgICAqICAgICB1cmw6ICdodHRwczovL3d3dy5tYXBib3guY29tL2ltYWdlcy9mb28ucG5nJyxcbiAgICAgKiAgICAgY29vcmRpbmF0ZXM6IFtcbiAgICAgKiAgICAgICAgIFstNzYuNTQsIDM5LjE4XSxcbiAgICAgKiAgICAgICAgIFstNzYuNTIsIDM5LjE4XSxcbiAgICAgKiAgICAgICAgIFstNzYuNTIsIDM5LjE3XSxcbiAgICAgKiAgICAgICAgIFstNzYuNTQsIDM5LjE3XVxuICAgICAqICAgICBdXG4gICAgICogfSk7XG4gICAgICogLy8gVGhlbiB1cGRhdGUgdGhlIGltYWdlIGNvb3JkaW5hdGVzXG4gICAgICogaW1hZ2VTb3VyY2Uuc2V0Q29vcmRpbmF0ZXMoW1xuICAgICAqICAgICBbLTc2LjU0MzMsIDM5LjE4NTddLFxuICAgICAqICAgICBbLTc2LjUyODAsIDM5LjE4MzhdLFxuICAgICAqICAgICBbLTc2LjUyOTUsIDM5LjE3NjhdLFxuICAgICAqICAgICBbLTc2LjU0NTIsIDM5LjE3ODddXG4gICAgICogXSk7XG4gICAgICovXG4gICAgc2V0Q29vcmRpbmF0ZXMoY29vcmRpbmF0ZXM6IENvb3JkaW5hdGVzKTogdGhpcyB7XG4gICAgICAgIHRoaXMuY29vcmRpbmF0ZXMgPSBjb29yZGluYXRlcztcbiAgICAgICAgdGhpcy5fYm91bmRzQXJyYXkgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgLy8gQ2FsY3VsYXRlIHdoaWNoIG1lcmNhdG9yIHRpbGUgaXMgc3VpdGFibGUgZm9yIHJlbmRlcmluZyB0aGUgdmlkZW8gaW5cbiAgICAgICAgLy8gYW5kIGNyZWF0ZSBhIGJ1ZmZlciB3aXRoIHRoZSBjb3JuZXIgY29vcmRpbmF0ZXMuIFRoZXNlIGNvb3JkaW5hdGVzXG4gICAgICAgIC8vIG1heSBiZSBvdXRzaWRlIHRoZSB0aWxlLCBiZWNhdXNlIHJhc3RlciB0aWxlcyBhcmVuJ3QgY2xpcHBlZCB3aGVuIHJlbmRlcmluZy5cblxuICAgICAgICAvLyB0cmFuc2Zvcm0gdGhlIGdlbyBjb29yZGluYXRlcyBpbnRvICh6b29tIDApIHRpbGUgc3BhY2UgY29vcmRpbmF0ZXNcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICBjb25zdCBjb3JuZXJDb29yZHMgPSBjb29yZGluYXRlcy5tYXAoTWVyY2F0b3JDb29yZGluYXRlLmZyb21MbmdMYXQpO1xuXG4gICAgICAgIC8vIENvbXB1dGUgdGhlIGNvb3JkaW5hdGVzIG9mIHRoZSB0aWxlIHdlJ2xsIHVzZSB0byBob2xkIHRoaXMgaW1hZ2Unc1xuICAgICAgICAvLyByZW5kZXIgZGF0YVxuICAgICAgICB0aGlzLnRpbGVJRCA9IGdldENvb3JkaW5hdGVzQ2VudGVyVGlsZUlEKGNvcm5lckNvb3Jkcyk7XG5cbiAgICAgICAgLy8gQ29uc3RyYWluIG1pbi9tYXggem9vbSB0byBvdXIgdGlsZSdzIHpvb20gbGV2ZWwgaW4gb3JkZXIgdG8gZm9yY2VcbiAgICAgICAgLy8gU291cmNlQ2FjaGUgdG8gcmVxdWVzdCB0aGlzIHRpbGUgKG5vIG1hdHRlciB3aGF0IHRoZSBtYXAncyB6b29tXG4gICAgICAgIC8vIGxldmVsKVxuICAgICAgICB0aGlzLm1pbnpvb20gPSB0aGlzLm1heHpvb20gPSB0aGlzLnRpbGVJRC56O1xuXG4gICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ2RhdGEnLCB7ZGF0YVR5cGU6J3NvdXJjZScsIHNvdXJjZURhdGFUeXBlOiAnY29udGVudCd9KSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICBfY2xlYXIoKSB7XG4gICAgICAgIHRoaXMuX2JvdW5kc0FycmF5ID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIF9wcmVwYXJlRGF0YShjb250ZXh0OiBDb250ZXh0KSB7XG4gICAgICAgIGZvciAoY29uc3QgdyBpbiB0aGlzLnRpbGVzKSB7XG4gICAgICAgICAgICBjb25zdCB0aWxlID0gdGhpcy50aWxlc1t3XTtcbiAgICAgICAgICAgIGlmICh0aWxlLnN0YXRlICE9PSAnbG9hZGVkJykge1xuICAgICAgICAgICAgICAgIHRpbGUuc3RhdGUgPSAnbG9hZGVkJztcbiAgICAgICAgICAgICAgICB0aWxlLnRleHR1cmUgPSB0aGlzLnRleHR1cmU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5fYm91bmRzQXJyYXkpIHJldHVybjtcblxuICAgICAgICBjb25zdCB0aWxlVHIgPSB0aWxlVHJhbnNmb3JtKHRoaXMudGlsZUlELCB0aGlzLm1hcC50cmFuc2Zvcm0ucHJvamVjdGlvbik7XG5cbiAgICAgICAgLy8gVHJhbnNmb3JtIHRoZSBjb3JuZXIgY29vcmRpbmF0ZXMgaW50byB0aGUgY29vcmRpbmF0ZSBzcGFjZSBvZiBvdXIgdGlsZS5cbiAgICAgICAgY29uc3QgW3RsLCB0ciwgYnIsIGJsXSA9IHRoaXMuY29vcmRpbmF0ZXMubWFwKChjb29yZCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcHJvamVjdGVkQ29vcmQgPSB0aWxlVHIucHJvamVjdGlvbi5wcm9qZWN0KGNvb3JkWzBdLCBjb29yZFsxXSk7XG4gICAgICAgICAgICByZXR1cm4gZ2V0VGlsZVBvaW50KHRpbGVUciwgcHJvamVjdGVkQ29vcmQpLl9yb3VuZCgpO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLnBlcnNwZWN0aXZlVHJhbnNmb3JtID0gZ2V0UGVyc3BlY3RpdmVUcmFuc2Zvcm0oXG4gICAgICAgICAgICB0aGlzLndpZHRoLCB0aGlzLmhlaWdodCwgdGwueCwgdGwueSwgdHIueCwgdHIueSwgYmwueCwgYmwueSwgYnIueCwgYnIueSk7XG5cbiAgICAgICAgY29uc3QgYm91bmRzQXJyYXkgPSB0aGlzLl9ib3VuZHNBcnJheSA9IG5ldyBSYXN0ZXJCb3VuZHNBcnJheSgpO1xuICAgICAgICBib3VuZHNBcnJheS5lbXBsYWNlQmFjayh0bC54LCB0bC55LCAwLCAwKTtcbiAgICAgICAgYm91bmRzQXJyYXkuZW1wbGFjZUJhY2sodHIueCwgdHIueSwgRVhURU5ULCAwKTtcbiAgICAgICAgYm91bmRzQXJyYXkuZW1wbGFjZUJhY2soYmwueCwgYmwueSwgMCwgRVhURU5UKTtcbiAgICAgICAgYm91bmRzQXJyYXkuZW1wbGFjZUJhY2soYnIueCwgYnIueSwgRVhURU5ULCBFWFRFTlQpO1xuXG4gICAgICAgIGlmICh0aGlzLmJvdW5kc0J1ZmZlcikge1xuICAgICAgICAgICAgdGhpcy5ib3VuZHNCdWZmZXIuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuYm91bmRzQnVmZmVyID0gY29udGV4dC5jcmVhdGVWZXJ0ZXhCdWZmZXIoYm91bmRzQXJyYXksIGJvdW5kc0F0dHJpYnV0ZXMubWVtYmVycyk7XG4gICAgICAgIHRoaXMuYm91bmRzU2VnbWVudHMgPSBTZWdtZW50VmVjdG9yLnNpbXBsZVNlZ21lbnQoMCwgMCwgNCwgMik7XG4gICAgfVxuXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIHByZXBhcmUoKSB7XG4gICAgICAgIGlmIChPYmplY3Qua2V5cyh0aGlzLnRpbGVzKS5sZW5ndGggPT09IDAgfHwgIXRoaXMuaW1hZ2UpIHJldHVybjtcblxuICAgICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5tYXAucGFpbnRlci5jb250ZXh0O1xuICAgICAgICBjb25zdCBnbCA9IGNvbnRleHQuZ2w7XG5cbiAgICAgICAgaWYgKHRoaXMuX2RpcnR5KSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMudGV4dHVyZSkge1xuICAgICAgICAgICAgICAgIHRoaXMudGV4dHVyZSA9IG5ldyBUZXh0dXJlKGNvbnRleHQsIHRoaXMuaW1hZ2UsIGdsLlJHQkEpO1xuICAgICAgICAgICAgICAgIHRoaXMudGV4dHVyZS5iaW5kKGdsLkxJTkVBUiwgZ2wuQ0xBTVBfVE9fRURHRSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMudGV4dHVyZS51cGRhdGUodGhpcy5pbWFnZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9kaXJ0eSA9IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fcHJlcGFyZURhdGEoY29udGV4dCk7XG4gICAgfVxuXG4gICAgbG9hZFRpbGUodGlsZTogVGlsZSwgY2FsbGJhY2s6IENhbGxiYWNrPHZvaWQ+KSB7XG4gICAgICAgIC8vIFdlIGhhdmUgYSBzaW5nbGUgdGlsZSAtLSB3aG9vc2UgY29vcmRpbmF0ZXMgYXJlIHRoaXMudGlsZUlEIC0tIHRoYXRcbiAgICAgICAgLy8gY292ZXJzIHRoZSBpbWFnZSB3ZSB3YW50IHRvIHJlbmRlci4gIElmIHRoYXQncyB0aGUgb25lIGJlaW5nXG4gICAgICAgIC8vIHJlcXVlc3RlZCwgc2V0IGl0IHVwIHdpdGggdGhlIGltYWdlOyBvdGhlcndpc2UsIG1hcmsgdGhlIHRpbGUgYXNcbiAgICAgICAgLy8gYGVycm9yZWRgIHRvIGluZGljYXRlIHRoYXQgd2UgaGF2ZSBubyBkYXRhIGZvciBpdC5cbiAgICAgICAgLy8gSWYgdGhlIHdvcmxkIHdyYXBzLCB3ZSBtYXkgaGF2ZSBtdWx0aXBsZSBcIndyYXBwZWRcIiBjb3BpZXMgb2YgdGhlXG4gICAgICAgIC8vIHNpbmdsZSB0aWxlLlxuICAgICAgICBpZiAodGhpcy50aWxlSUQgJiYgdGhpcy50aWxlSUQuZXF1YWxzKHRpbGUudGlsZUlELmNhbm9uaWNhbCkpIHtcbiAgICAgICAgICAgIHRoaXMudGlsZXNbU3RyaW5nKHRpbGUudGlsZUlELndyYXApXSA9IHRpbGU7XG4gICAgICAgICAgICB0aWxlLmJ1Y2tldHMgPSB7fTtcbiAgICAgICAgICAgIGNhbGxiYWNrKG51bGwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGlsZS5zdGF0ZSA9ICdlcnJvcmVkJztcbiAgICAgICAgICAgIGNhbGxiYWNrKG51bGwpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2VyaWFsaXplKCk6IE9iamVjdCB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiAnaW1hZ2UnLFxuICAgICAgICAgICAgdXJsOiB0aGlzLm9wdGlvbnMudXJsLFxuICAgICAgICAgICAgY29vcmRpbmF0ZXM6IHRoaXMuY29vcmRpbmF0ZXNcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBoYXNUcmFuc2l0aW9uKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuXG4vKipcbiAqIEdpdmVuIGEgbGlzdCBvZiBjb29yZGluYXRlcywgZ2V0IHRoZWlyIGNlbnRlciBhcyBhIGNvb3JkaW5hdGUuXG4gKlxuICogQHJldHVybnMgY2VudGVycG9pbnRcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb29yZGluYXRlc0NlbnRlclRpbGVJRChjb29yZHM6IEFycmF5PE1lcmNhdG9yQ29vcmRpbmF0ZT4pOiBDYW5vbmljYWxUaWxlSUQge1xuICAgIGxldCBtaW5YID0gSW5maW5pdHk7XG4gICAgbGV0IG1pblkgPSBJbmZpbml0eTtcbiAgICBsZXQgbWF4WCA9IC1JbmZpbml0eTtcbiAgICBsZXQgbWF4WSA9IC1JbmZpbml0eTtcblxuICAgIGZvciAoY29uc3QgY29vcmQgb2YgY29vcmRzKSB7XG4gICAgICAgIG1pblggPSBNYXRoLm1pbihtaW5YLCBjb29yZC54KTtcbiAgICAgICAgbWluWSA9IE1hdGgubWluKG1pblksIGNvb3JkLnkpO1xuICAgICAgICBtYXhYID0gTWF0aC5tYXgobWF4WCwgY29vcmQueCk7XG4gICAgICAgIG1heFkgPSBNYXRoLm1heChtYXhZLCBjb29yZC55KTtcbiAgICB9XG5cbiAgICBjb25zdCBkeCA9IG1heFggLSBtaW5YO1xuICAgIGNvbnN0IGR5ID0gbWF4WSAtIG1pblk7XG4gICAgY29uc3QgZE1heCA9IE1hdGgubWF4KGR4LCBkeSk7XG4gICAgY29uc3Qgem9vbSA9IE1hdGgubWF4KDAsIE1hdGguZmxvb3IoLU1hdGgubG9nKGRNYXgpIC8gTWF0aC5MTjIpKTtcbiAgICBjb25zdCB0aWxlc0F0Wm9vbSA9IE1hdGgucG93KDIsIHpvb20pO1xuXG4gICAgcmV0dXJuIG5ldyBDYW5vbmljYWxUaWxlSUQoXG4gICAgICAgICAgICB6b29tLFxuICAgICAgICAgICAgTWF0aC5mbG9vcigobWluWCArIG1heFgpIC8gMiAqIHRpbGVzQXRab29tKSxcbiAgICAgICAgICAgIE1hdGguZmxvb3IoKG1pblkgKyBtYXhZKSAvIDIgKiB0aWxlc0F0Wm9vbSkpO1xufVxuXG5leHBvcnQgZGVmYXVsdCBJbWFnZVNvdXJjZTtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCB7Z2V0VmlkZW8sIFJlc291cmNlVHlwZX0gZnJvbSAnLi4vdXRpbC9hamF4LmpzJztcblxuaW1wb3J0IEltYWdlU291cmNlIGZyb20gJy4vaW1hZ2Vfc291cmNlLmpzJztcbmltcG9ydCBUZXh0dXJlIGZyb20gJy4uL3JlbmRlci90ZXh0dXJlLmpzJztcbmltcG9ydCB7RXJyb3JFdmVudH0gZnJvbSAnLi4vdXRpbC9ldmVudGVkLmpzJztcbmltcG9ydCBWYWxpZGF0aW9uRXJyb3IgZnJvbSAnLi4vc3R5bGUtc3BlYy9lcnJvci92YWxpZGF0aW9uX2Vycm9yLmpzJztcblxuaW1wb3J0IHR5cGUgTWFwIGZyb20gJy4uL3VpL21hcC5qcyc7XG5pbXBvcnQgdHlwZSBEaXNwYXRjaGVyIGZyb20gJy4uL3V0aWwvZGlzcGF0Y2hlci5qcyc7XG5pbXBvcnQgdHlwZSB7RXZlbnRlZH0gZnJvbSAnLi4vdXRpbC9ldmVudGVkLmpzJztcbmltcG9ydCB0eXBlIHtWaWRlb1NvdXJjZVNwZWNpZmljYXRpb259IGZyb20gJy4uL3N0eWxlLXNwZWMvdHlwZXMuanMnO1xuXG4vKipcbiAqIEEgZGF0YSBzb3VyY2UgY29udGFpbmluZyB2aWRlby5cbiAqIFNlZSB0aGUgW1N0eWxlIFNwZWNpZmljYXRpb25dKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLXN0eWxlLXNwZWMvI3NvdXJjZXMtdmlkZW8pIGZvciBkZXRhaWxlZCBkb2N1bWVudGF0aW9uIG9mIG9wdGlvbnMuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIGFkZCB0byBtYXBcbiAqIG1hcC5hZGRTb3VyY2UoJ3NvbWUgaWQnLCB7XG4gKiAgICAgdHlwZTogJ3ZpZGVvJyxcbiAqICAgICB1cmw6IFtcbiAqICAgICAgICAgJ2h0dHBzOi8vd3d3Lm1hcGJveC5jb20vYmxvZy9hc3NldHMvYmFsdGltb3JlLXNtb2tlLm1wNCcsXG4gKiAgICAgICAgICdodHRwczovL3d3dy5tYXBib3guY29tL2Jsb2cvYXNzZXRzL2JhbHRpbW9yZS1zbW9rZS53ZWJtJ1xuICogICAgIF0sXG4gKiAgICAgY29vcmRpbmF0ZXM6IFtcbiAqICAgICAgICAgWy03Ni41NCwgMzkuMThdLFxuICogICAgICAgICBbLTc2LjUyLCAzOS4xOF0sXG4gKiAgICAgICAgIFstNzYuNTIsIDM5LjE3XSxcbiAqICAgICAgICAgWy03Ni41NCwgMzkuMTddXG4gKiAgICAgXVxuICogfSk7XG4gKlxuICogLy8gdXBkYXRlXG4gKiBjb25zdCBteVNvdXJjZSA9IG1hcC5nZXRTb3VyY2UoJ3NvbWUgaWQnKTtcbiAqIG15U291cmNlLnNldENvb3JkaW5hdGVzKFtcbiAqICAgICBbLTc2LjU0MzM1NzM3MjI4Mzk0LCAzOS4xODU3OTkwNzIyOTc0OF0sXG4gKiAgICAgWy03Ni41MjgwMzY1OTQzOTA4NywgMzkuMTgzODM2NDg0NzU4N10sXG4gKiAgICAgWy03Ni41Mjk1Mzg2MzE0MzkyLCAzOS4xNzY4MzM5MjUwNzYwNl0sXG4gKiAgICAgWy03Ni41NDUyMDI3MzIwODYxOCwgMzkuMTc4NzYzNDQxMDY2NDJdXG4gKiBdKTtcbiAqXG4gKiBtYXAucmVtb3ZlU291cmNlKCdzb21lIGlkJyk7ICAvLyByZW1vdmVcbiAqIEBzZWUgW0V4YW1wbGU6IEFkZCBhIHZpZGVvXShodHRwczovL3d3dy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL3ZpZGVvLW9uLWEtbWFwLylcbiAqL1xuY2xhc3MgVmlkZW9Tb3VyY2UgZXh0ZW5kcyBJbWFnZVNvdXJjZSB7XG4gICAgb3B0aW9uczogVmlkZW9Tb3VyY2VTcGVjaWZpY2F0aW9uO1xuICAgIHVybHM6IEFycmF5PHN0cmluZz47XG4gICAgdmlkZW86IEhUTUxWaWRlb0VsZW1lbnQ7XG4gICAgcm91bmRab29tOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihpZDogc3RyaW5nLCBvcHRpb25zOiBWaWRlb1NvdXJjZVNwZWNpZmljYXRpb24sIGRpc3BhdGNoZXI6IERpc3BhdGNoZXIsIGV2ZW50ZWRQYXJlbnQ6IEV2ZW50ZWQpIHtcbiAgICAgICAgc3VwZXIoaWQsIG9wdGlvbnMsIGRpc3BhdGNoZXIsIGV2ZW50ZWRQYXJlbnQpO1xuICAgICAgICB0aGlzLnJvdW5kWm9vbSA9IHRydWU7XG4gICAgICAgIHRoaXMudHlwZSA9ICd2aWRlbyc7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgfVxuXG4gICAgbG9hZCgpIHtcbiAgICAgICAgdGhpcy5fbG9hZGVkID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG5cbiAgICAgICAgdGhpcy51cmxzID0gW107XG4gICAgICAgIGZvciAoY29uc3QgdXJsIG9mIG9wdGlvbnMudXJscykge1xuICAgICAgICAgICAgdGhpcy51cmxzLnB1c2godGhpcy5tYXAuX3JlcXVlc3RNYW5hZ2VyLnRyYW5zZm9ybVJlcXVlc3QodXJsLCBSZXNvdXJjZVR5cGUuU291cmNlKS51cmwpO1xuICAgICAgICB9XG5cbiAgICAgICAgZ2V0VmlkZW8odGhpcy51cmxzLCAoZXJyLCB2aWRlbykgPT4ge1xuICAgICAgICAgICAgdGhpcy5fbG9hZGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpcmUobmV3IEVycm9yRXZlbnQoZXJyKSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHZpZGVvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52aWRlbyA9IHZpZGVvO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW8ubG9vcCA9IHRydWU7XG5cbiAgICAgICAgICAgICAgICAvLyBQcmV2ZW50IHRoZSB2aWRlbyBmcm9tIHRha2luZyBvdmVyIHRoZSBzY3JlZW4gaW4gaU9TXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlby5zZXRBdHRyaWJ1dGUoJ3BsYXlzaW5saW5lJywgJycpO1xuXG4gICAgICAgICAgICAgICAgLy8gU3RhcnQgcmVwYWludGluZyB3aGVuIHZpZGVvIHN0YXJ0cyBwbGF5aW5nLiBoYXNUcmFuc2l0aW9uKCkgd2lsbCB0aGVuIHJldHVyblxuICAgICAgICAgICAgICAgIC8vIHRydWUgdG8gdHJpZ2dlciBhZGRpdGlvbmFsIGZyYW1lcyBhcyBsb25nIGFzIHRoZSB2aWRlb3MgY29udGludWVzIHBsYXlpbmcuXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlby5hZGRFdmVudExpc3RlbmVyKCdwbGF5aW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1hcC50cmlnZ2VyUmVwYWludCgpO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubWFwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW8ucGxheSgpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMuX2ZpbmlzaExvYWRpbmcoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGF1c2VzIHRoZSB2aWRlby5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gQXNzdW1pbmcgYSB2aWRlbyBzb3VyY2UgaWRlbnRpZmllZCBieSB2aWRlb19zb3VyY2VfaWQgd2FzIGFkZGVkIHRvIHRoZSBtYXBcbiAgICAgKiBjb25zdCB2aWRlb1NvdXJjZSA9IG1hcC5nZXRTb3VyY2UoJ3ZpZGVvX3NvdXJjZV9pZCcpO1xuICAgICAqXG4gICAgICogLy8gUGF1c2VzIHRoZSB2aWRlb1xuICAgICAqIHZpZGVvU291cmNlLnBhdXNlKCk7XG4gICAgICovXG4gICAgcGF1c2UoKSB7XG4gICAgICAgIGlmICh0aGlzLnZpZGVvKSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvLnBhdXNlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQbGF5cyB0aGUgdmlkZW8uXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEFzc3VtaW5nIGEgdmlkZW8gc291cmNlIGlkZW50aWZpZWQgYnkgdmlkZW9fc291cmNlX2lkIHdhcyBhZGRlZCB0byB0aGUgbWFwXG4gICAgICogY29uc3QgdmlkZW9Tb3VyY2UgPSBtYXAuZ2V0U291cmNlKCd2aWRlb19zb3VyY2VfaWQnKTtcbiAgICAgKlxuICAgICAqIC8vIFN0YXJ0cyB0aGUgdmlkZW9cbiAgICAgKiB2aWRlb1NvdXJjZS5wbGF5KCk7XG4gICAgICovXG4gICAgcGxheSgpIHtcbiAgICAgICAgaWYgKHRoaXMudmlkZW8pIHtcbiAgICAgICAgICAgIHRoaXMudmlkZW8ucGxheSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyBwbGF5YmFjayB0byBhIHRpbWVzdGFtcCwgaW4gc2Vjb25kcy5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHNlZWsoc2Vjb25kczogbnVtYmVyKSB7XG4gICAgICAgIGlmICh0aGlzLnZpZGVvKSB7XG4gICAgICAgICAgICBjb25zdCBzZWVrYWJsZVJhbmdlID0gdGhpcy52aWRlby5zZWVrYWJsZTtcbiAgICAgICAgICAgIGlmIChzZWNvbmRzIDwgc2Vla2FibGVSYW5nZS5zdGFydCgwKSB8fCBzZWNvbmRzID4gc2Vla2FibGVSYW5nZS5lbmQoMCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpcmUobmV3IEVycm9yRXZlbnQobmV3IFZhbGlkYXRpb25FcnJvcihgc291cmNlcy4ke3RoaXMuaWR9YCwgbnVsbCwgYFBsYXliYWNrIGZvciB0aGlzIHZpZGVvIGNhbiBiZSBzZXQgb25seSBiZXR3ZWVuIHRoZSAke3NlZWthYmxlUmFuZ2Uuc3RhcnQoMCl9IGFuZCAke3NlZWthYmxlUmFuZ2UuZW5kKDApfS1zZWNvbmQgbWFyay5gKSkpO1xuICAgICAgICAgICAgfSBlbHNlIHRoaXMudmlkZW8uY3VycmVudFRpbWUgPSBzZWNvbmRzO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgSFRNTCBgdmlkZW9gIGVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7SFRNTFZpZGVvRWxlbWVudH0gVGhlIEhUTUwgYHZpZGVvYCBlbGVtZW50LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gQXNzdW1pbmcgYSB2aWRlbyBzb3VyY2UgaWRlbnRpZmllZCBieSB2aWRlb19zb3VyY2VfaWQgd2FzIGFkZGVkIHRvIHRoZSBtYXBcbiAgICAgKiBjb25zdCB2aWRlb1NvdXJjZSA9IG1hcC5nZXRTb3VyY2UoJ3ZpZGVvX3NvdXJjZV9pZCcpO1xuICAgICAqXG4gICAgICogdmlkZW9Tb3VyY2UuZ2V0VmlkZW8oKTsgLy8gPHZpZGVvIGNyb3Nzb3JpZ2luPVwiQW5vbnltb3VzXCIgbG9vcD1cIlwiPi4uLjwvdmlkZW8+XG4gICAgICovXG4gICAgZ2V0VmlkZW8oKTogSFRNTFZpZGVvRWxlbWVudCB7XG4gICAgICAgIHJldHVybiB0aGlzLnZpZGVvO1xuICAgIH1cblxuICAgIG9uQWRkKG1hcDogTWFwKSB7XG4gICAgICAgIGlmICh0aGlzLm1hcCkgcmV0dXJuO1xuICAgICAgICB0aGlzLm1hcCA9IG1hcDtcbiAgICAgICAgdGhpcy5sb2FkKCk7XG4gICAgICAgIGlmICh0aGlzLnZpZGVvKSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvLnBsYXkoKTtcbiAgICAgICAgICAgIHRoaXMuc2V0Q29vcmRpbmF0ZXModGhpcy5jb29yZGluYXRlcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSB2aWRlbydzIGNvb3JkaW5hdGVzIGFuZCByZS1yZW5kZXJzIHRoZSBtYXAuXG4gICAgICpcbiAgICAgKiBAbWV0aG9kIHNldENvb3JkaW5hdGVzXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQG1lbWJlcm9mIFZpZGVvU291cmNlXG4gICAgICogQHJldHVybnMge1ZpZGVvU291cmNlfSBSZXR1cm5zIGl0c2VsZiB0byBhbGxvdyBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gQWRkIGEgdmlkZW8gc291cmNlIHRvIHRoZSBtYXAgdG8gbWFwXG4gICAgICogbWFwLmFkZFNvdXJjZSgndmlkZW9fc291cmNlX2lkJywge1xuICAgICAqICAgICB0eXBlOiAndmlkZW8nLFxuICAgICAqICAgICB1cmw6IFtcbiAgICAgKiAgICAgICAgICdodHRwczovL3d3dy5tYXBib3guY29tL2Jsb2cvYXNzZXRzL2JhbHRpbW9yZS1zbW9rZS5tcDQnLFxuICAgICAqICAgICAgICAgJ2h0dHBzOi8vd3d3Lm1hcGJveC5jb20vYmxvZy9hc3NldHMvYmFsdGltb3JlLXNtb2tlLndlYm0nXG4gICAgICogICAgIF0sXG4gICAgICogICAgIGNvb3JkaW5hdGVzOiBbXG4gICAgICogICAgICAgICBbLTc2LjU0LCAzOS4xOF0sXG4gICAgICogICAgICAgICBbLTc2LjUyLCAzOS4xOF0sXG4gICAgICogICAgICAgICBbLTc2LjUyLCAzOS4xN10sXG4gICAgICogICAgICAgICBbLTc2LjU0LCAzOS4xN11cbiAgICAgKiAgICAgXVxuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogLy8gVGhlbiB1cGRhdGUgdGhlIHZpZGVvIHNvdXJjZSBjb29yZGluYXRlcyBieSBuZXcgY29vcmRpbmF0ZXNcbiAgICAgKiBjb25zdCB2aWRlb1NvdXJjZSA9IG1hcC5nZXRTb3VyY2UoJ3ZpZGVvX3NvdXJjZV9pZCcpO1xuICAgICAqIHZpZGVvU291cmNlLnNldENvb3JkaW5hdGVzKFtcbiAgICAgKiAgICAgWy03Ni41NDMzLCAzOS4xODU3XSxcbiAgICAgKiAgICAgWy03Ni41MjgwLCAzOS4xODM4XSxcbiAgICAgKiAgICAgWy03Ni41Mjk1LCAzOS4xNzY4XSxcbiAgICAgKiAgICAgWy03Ni41NDUyLCAzOS4xNzg3XVxuICAgICAqIF0pO1xuICAgICAqL1xuICAgIC8vIHNldENvb3JkaW5hdGVzIGluaGVyaXRlZCBmcm9tIEltYWdlU291cmNlXG5cbiAgICBwcmVwYXJlKCkge1xuICAgICAgICBpZiAoT2JqZWN0LmtleXModGhpcy50aWxlcykubGVuZ3RoID09PSAwIHx8IHRoaXMudmlkZW8ucmVhZHlTdGF0ZSA8IDIpIHtcbiAgICAgICAgICAgIHJldHVybjsgLy8gbm90IGVub3VnaCBkYXRhIGZvciBjdXJyZW50IHBvc2l0aW9uXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5tYXAucGFpbnRlci5jb250ZXh0O1xuICAgICAgICBjb25zdCBnbCA9IGNvbnRleHQuZ2w7XG5cbiAgICAgICAgaWYgKCF0aGlzLnRleHR1cmUpIHtcbiAgICAgICAgICAgIHRoaXMudGV4dHVyZSA9IG5ldyBUZXh0dXJlKGNvbnRleHQsIHRoaXMudmlkZW8sIGdsLlJHQkEpO1xuICAgICAgICAgICAgdGhpcy50ZXh0dXJlLmJpbmQoZ2wuTElORUFSLCBnbC5DTEFNUF9UT19FREdFKTtcbiAgICAgICAgICAgIHRoaXMud2lkdGggPSB0aGlzLnZpZGVvLnZpZGVvV2lkdGg7XG4gICAgICAgICAgICB0aGlzLmhlaWdodCA9IHRoaXMudmlkZW8udmlkZW9IZWlnaHQ7XG5cbiAgICAgICAgfSBlbHNlIGlmICghdGhpcy52aWRlby5wYXVzZWQpIHtcbiAgICAgICAgICAgIHRoaXMudGV4dHVyZS5iaW5kKGdsLkxJTkVBUiwgZ2wuQ0xBTVBfVE9fRURHRSk7XG4gICAgICAgICAgICBnbC50ZXhTdWJJbWFnZTJEKGdsLlRFWFRVUkVfMkQsIDAsIDAsIDAsIGdsLlJHQkEsIGdsLlVOU0lHTkVEX0JZVEUsIHRoaXMudmlkZW8pO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fcHJlcGFyZURhdGEoY29udGV4dCk7XG4gICAgfVxuXG4gICAgc2VyaWFsaXplKCk6IFZpZGVvU291cmNlU3BlY2lmaWNhdGlvbiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiAndmlkZW8nLFxuICAgICAgICAgICAgdXJsczogdGhpcy51cmxzLFxuICAgICAgICAgICAgY29vcmRpbmF0ZXM6IHRoaXMuY29vcmRpbmF0ZXNcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBoYXNUcmFuc2l0aW9uKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy52aWRlbyAmJiAhdGhpcy52aWRlby5wYXVzZWQ7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBWaWRlb1NvdXJjZTtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCBJbWFnZVNvdXJjZSBmcm9tICcuL2ltYWdlX3NvdXJjZS5qcyc7XG5cbmltcG9ydCB3aW5kb3cgZnJvbSAnLi4vdXRpbC93aW5kb3cuanMnO1xuaW1wb3J0IFRleHR1cmUgZnJvbSAnLi4vcmVuZGVyL3RleHR1cmUuanMnO1xuaW1wb3J0IHtFcnJvckV2ZW50fSBmcm9tICcuLi91dGlsL2V2ZW50ZWQuanMnO1xuaW1wb3J0IFZhbGlkYXRpb25FcnJvciBmcm9tICcuLi9zdHlsZS1zcGVjL2Vycm9yL3ZhbGlkYXRpb25fZXJyb3IuanMnO1xuXG5pbXBvcnQgdHlwZSBNYXAgZnJvbSAnLi4vdWkvbWFwLmpzJztcbmltcG9ydCB0eXBlIERpc3BhdGNoZXIgZnJvbSAnLi4vdXRpbC9kaXNwYXRjaGVyLmpzJztcbmltcG9ydCB0eXBlIHtFdmVudGVkfSBmcm9tICcuLi91dGlsL2V2ZW50ZWQuanMnO1xuXG5leHBvcnQgdHlwZSBDYW52YXNTb3VyY2VTcGVjaWZpY2F0aW9uID0ge3xcbiAgICBcInR5cGVcIjogXCJjYW52YXNcIixcbiAgICBcImNvb3JkaW5hdGVzXCI6IFtbbnVtYmVyLCBudW1iZXJdLCBbbnVtYmVyLCBudW1iZXJdLCBbbnVtYmVyLCBudW1iZXJdLCBbbnVtYmVyLCBudW1iZXJdXSxcbiAgICBcImFuaW1hdGVcIj86IGJvb2xlYW4sXG4gICAgXCJjYW52YXNcIjogc3RyaW5nIHwgSFRNTENhbnZhc0VsZW1lbnRcbnx9O1xuXG4vKipcbiAqIE9wdGlvbnMgdG8gYWRkIGEgY2FudmFzIHNvdXJjZSB0eXBlIHRvIHRoZSBtYXAuXG4gKlxuICogQHR5cGVkZWYge09iamVjdH0gQ2FudmFzU291cmNlT3B0aW9uc1xuICogQHByb3BlcnR5IHtzdHJpbmd9IHR5cGUgU291cmNlIHR5cGUuIE11c3QgYmUgYFwiY2FudmFzXCJgLlxuICogQHByb3BlcnR5IHtzdHJpbmd8SFRNTENhbnZhc0VsZW1lbnR9IGNhbnZhcyBDYW52YXMgc291cmNlIGZyb20gd2hpY2ggdG8gcmVhZCBwaXhlbHMuIENhbiBiZSBhIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIElEIG9mIHRoZSBjYW52YXMgZWxlbWVudCwgb3IgdGhlIGBIVE1MQ2FudmFzRWxlbWVudGAgaXRzZWxmLlxuICogQHByb3BlcnR5IHtBcnJheTxBcnJheTxudW1iZXI+Pn0gY29vcmRpbmF0ZXMgRm91ciBnZW9ncmFwaGljYWwgY29vcmRpbmF0ZXMgZGVub3Rpbmcgd2hlcmUgdG8gcGxhY2UgdGhlIGNvcm5lcnMgb2YgdGhlIGNhbnZhcywgc3BlY2lmaWVkIGluIGBbbG9uZ2l0dWRlLCBsYXRpdHVkZV1gIHBhaXJzLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbYW5pbWF0ZT10cnVlXSBXaGV0aGVyIHRoZSBjYW52YXMgc291cmNlIGlzIGFuaW1hdGVkLiBJZiB0aGUgY2FudmFzIGlzIHN0YXRpYyAocGl4ZWxzIGRvIG5vdCBuZWVkIHRvIGJlIHJlLXJlYWQgb24gZXZlcnkgZnJhbWUpLCBgYW5pbWF0ZWAgc2hvdWxkIGJlIHNldCB0byBgZmFsc2VgIHRvIGltcHJvdmUgcGVyZm9ybWFuY2UuXG4gKi9cblxuLyoqXG4gKiBBIGRhdGEgc291cmNlIGNvbnRhaW5pbmcgdGhlIGNvbnRlbnRzIG9mIGFuIEhUTUwgY2FudmFzLiBTZWUge0BsaW5rIENhbnZhc1NvdXJjZU9wdGlvbnN9IGZvciBkZXRhaWxlZCBkb2N1bWVudGF0aW9uIG9mIG9wdGlvbnMuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIGFkZCB0byBtYXBcbiAqIG1hcC5hZGRTb3VyY2UoJ3NvbWUgaWQnLCB7XG4gKiAgICAgdHlwZTogJ2NhbnZhcycsXG4gKiAgICAgY2FudmFzOiAnaWRPZk15SFRNTENhbnZhcycsXG4gKiAgICAgYW5pbWF0ZTogdHJ1ZSxcbiAqICAgICBjb29yZGluYXRlczogW1xuICogICAgICAgICBbLTc2LjU0LCAzOS4xOF0sXG4gKiAgICAgICAgIFstNzYuNTIsIDM5LjE4XSxcbiAqICAgICAgICAgWy03Ni41MiwgMzkuMTddLFxuICogICAgICAgICBbLTc2LjU0LCAzOS4xN11cbiAqICAgICBdXG4gKiB9KTtcbiAqXG4gKiAvLyB1cGRhdGVcbiAqIGNvbnN0IG15U291cmNlID0gbWFwLmdldFNvdXJjZSgnc29tZSBpZCcpO1xuICogbXlTb3VyY2Uuc2V0Q29vcmRpbmF0ZXMoW1xuICogICAgIFstNzYuNTQzMzU3MzcyMjgzOTQsIDM5LjE4NTc5OTA3MjI5NzQ4XSxcbiAqICAgICBbLTc2LjUyODAzNjU5NDM5MDg3LCAzOS4xODM4MzY0ODQ3NTg3XSxcbiAqICAgICBbLTc2LjUyOTUzODYzMTQzOTIsIDM5LjE3NjgzMzkyNTA3NjA2XSxcbiAqICAgICBbLTc2LjU0NTIwMjczMjA4NjE4LCAzOS4xNzg3NjM0NDEwNjY0Ml1cbiAqIF0pO1xuICpcbiAqIG1hcC5yZW1vdmVTb3VyY2UoJ3NvbWUgaWQnKTsgIC8vIHJlbW92ZVxuICogQHNlZSBbRXhhbXBsZTogQWRkIGEgY2FudmFzIHNvdXJjZV0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvY2FudmFzLXNvdXJjZS8pXG4gKi9cbmNsYXNzIENhbnZhc1NvdXJjZSBleHRlbmRzIEltYWdlU291cmNlIHtcbiAgICBvcHRpb25zOiBDYW52YXNTb3VyY2VTcGVjaWZpY2F0aW9uO1xuICAgIGFuaW1hdGU6IGJvb2xlYW47XG4gICAgY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudDtcbiAgICBwbGF5OiAoKSA9PiB2b2lkO1xuICAgIHBhdXNlOiAoKSA9PiB2b2lkO1xuICAgIF9wbGF5aW5nOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihpZDogc3RyaW5nLCBvcHRpb25zOiBDYW52YXNTb3VyY2VTcGVjaWZpY2F0aW9uLCBkaXNwYXRjaGVyOiBEaXNwYXRjaGVyLCBldmVudGVkUGFyZW50OiBFdmVudGVkKSB7XG4gICAgICAgIHN1cGVyKGlkLCBvcHRpb25zLCBkaXNwYXRjaGVyLCBldmVudGVkUGFyZW50KTtcblxuICAgICAgICAvLyBXZSBidWlsZCBpbiBzb21lIHZhbGlkYXRpb24gaGVyZSwgc2luY2UgY2FudmFzIHNvdXJjZXMgYXJlbid0IGluY2x1ZGVkIGluIHRoZSBzdHlsZSBzcGVjOlxuICAgICAgICBpZiAoIW9wdGlvbnMuY29vcmRpbmF0ZXMpIHtcbiAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXJyb3JFdmVudChuZXcgVmFsaWRhdGlvbkVycm9yKGBzb3VyY2VzLiR7aWR9YCwgbnVsbCwgJ21pc3NpbmcgcmVxdWlyZWQgcHJvcGVydHkgXCJjb29yZGluYXRlc1wiJykpKTtcbiAgICAgICAgfSBlbHNlIGlmICghQXJyYXkuaXNBcnJheShvcHRpb25zLmNvb3JkaW5hdGVzKSB8fCBvcHRpb25zLmNvb3JkaW5hdGVzLmxlbmd0aCAhPT0gNCB8fFxuICAgICAgICAgICAgICAgIG9wdGlvbnMuY29vcmRpbmF0ZXMuc29tZShjID0+ICFBcnJheS5pc0FycmF5KGMpIHx8IGMubGVuZ3RoICE9PSAyIHx8IGMuc29tZShsID0+IHR5cGVvZiBsICE9PSAnbnVtYmVyJykpKSB7XG4gICAgICAgICAgICB0aGlzLmZpcmUobmV3IEVycm9yRXZlbnQobmV3IFZhbGlkYXRpb25FcnJvcihgc291cmNlcy4ke2lkfWAsIG51bGwsICdcImNvb3JkaW5hdGVzXCIgcHJvcGVydHkgbXVzdCBiZSBhbiBhcnJheSBvZiA0IGxvbmdpdHVkZS9sYXRpdHVkZSBhcnJheSBwYWlycycpKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAob3B0aW9ucy5hbmltYXRlICYmIHR5cGVvZiBvcHRpb25zLmFuaW1hdGUgIT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFcnJvckV2ZW50KG5ldyBWYWxpZGF0aW9uRXJyb3IoYHNvdXJjZXMuJHtpZH1gLCBudWxsLCAnb3B0aW9uYWwgXCJhbmltYXRlXCIgcHJvcGVydHkgbXVzdCBiZSBhIGJvb2xlYW4gdmFsdWUnKSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFvcHRpb25zLmNhbnZhcykge1xuICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFcnJvckV2ZW50KG5ldyBWYWxpZGF0aW9uRXJyb3IoYHNvdXJjZXMuJHtpZH1gLCBudWxsLCAnbWlzc2luZyByZXF1aXJlZCBwcm9wZXJ0eSBcImNhbnZhc1wiJykpKTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2Ygb3B0aW9ucy5jYW52YXMgIT09ICdzdHJpbmcnICYmICEob3B0aW9ucy5jYW52YXMgaW5zdGFuY2VvZiB3aW5kb3cuSFRNTENhbnZhc0VsZW1lbnQpKSB7XG4gICAgICAgICAgICB0aGlzLmZpcmUobmV3IEVycm9yRXZlbnQobmV3IFZhbGlkYXRpb25FcnJvcihgc291cmNlcy4ke2lkfWAsIG51bGwsICdcImNhbnZhc1wiIG11c3QgYmUgZWl0aGVyIGEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgSUQgb2YgdGhlIGNhbnZhcyBlbGVtZW50IGZyb20gd2hpY2ggdG8gcmVhZCwgb3IgYW4gSFRNTENhbnZhc0VsZW1lbnQgaW5zdGFuY2UnKSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICAgICAgdGhpcy5hbmltYXRlID0gb3B0aW9ucy5hbmltYXRlICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmFuaW1hdGUgOiB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEVuYWJsZXMgYW5pbWF0aW9uLiBUaGUgaW1hZ2Ugd2lsbCBiZSBjb3BpZWQgZnJvbSB0aGUgY2FudmFzIHRvIHRoZSBtYXAgb24gZWFjaCBmcmFtZS5cbiAgICAgKlxuICAgICAqIEBtZXRob2QgcGxheVxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEBtZW1iZXJvZiBDYW52YXNTb3VyY2VcbiAgICAgKi9cblxuICAgIC8qKlxuICAgICAqIERpc2FibGVzIGFuaW1hdGlvbi4gVGhlIG1hcCB3aWxsIGRpc3BsYXkgYSBzdGF0aWMgY29weSBvZiB0aGUgY2FudmFzIGltYWdlLlxuICAgICAqXG4gICAgICogQG1ldGhvZCBwYXVzZVxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEBtZW1iZXJvZiBDYW52YXNTb3VyY2VcbiAgICAgKi9cblxuICAgIGxvYWQoKSB7XG4gICAgICAgIHRoaXMuX2xvYWRlZCA9IHRydWU7XG4gICAgICAgIGlmICghdGhpcy5jYW52YXMpIHtcbiAgICAgICAgICAgIHRoaXMuY2FudmFzID0gKHRoaXMub3B0aW9ucy5jYW52YXMgaW5zdGFuY2VvZiB3aW5kb3cuSFRNTENhbnZhc0VsZW1lbnQpID9cbiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMuY2FudmFzIDpcbiAgICAgICAgICAgICAgICB3aW5kb3cuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5vcHRpb25zLmNhbnZhcyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy53aWR0aCA9IHRoaXMuY2FudmFzLndpZHRoO1xuICAgICAgICB0aGlzLmhlaWdodCA9IHRoaXMuY2FudmFzLmhlaWdodDtcblxuICAgICAgICBpZiAodGhpcy5faGFzSW52YWxpZERpbWVuc2lvbnMoKSkge1xuICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFcnJvckV2ZW50KG5ldyBFcnJvcignQ2FudmFzIGRpbWVuc2lvbnMgY2Fubm90IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byB6ZXJvLicpKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyAkRmxvd0ZpeE1lW21pc3NpbmctdGhpcy1hbm5vdF1cbiAgICAgICAgdGhpcy5wbGF5ID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICB0aGlzLl9wbGF5aW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMubWFwLnRyaWdnZXJSZXBhaW50KCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gJEZsb3dGaXhNZVttaXNzaW5nLXRoaXMtYW5ub3RdXG4gICAgICAgIHRoaXMucGF1c2UgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9wbGF5aW5nKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcmVwYXJlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fcGxheWluZyA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuX2ZpbmlzaExvYWRpbmcoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBIVE1MIGBjYW52YXNgIGVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7SFRNTENhbnZhc0VsZW1lbnR9IFRoZSBIVE1MIGBjYW52YXNgIGVsZW1lbnQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBBc3N1bWluZyB0aGUgZm9sbG93aW5nIGNhbnZhcyBpcyBhZGRlZCB0byB5b3VyIHBhZ2VcbiAgICAgKiAvLyA8Y2FudmFzIGlkPVwiY2FudmFzSURcIiB3aWR0aD1cIjQwMFwiIGhlaWdodD1cIjQwMFwiPjwvY2FudmFzPlxuICAgICAqIG1hcC5hZGRTb3VyY2UoJ2NhbnZhcy1zb3VyY2UnLCB7XG4gICAgICogICAgIHR5cGU6ICdjYW52YXMnLFxuICAgICAqICAgICBjYW52YXM6ICdjYW52YXNJRCcsXG4gICAgICogICAgIGNvb3JkaW5hdGVzOiBbXG4gICAgICogICAgICAgICBbOTEuNDQ2MSwgMjEuNTAwNl0sXG4gICAgICogICAgICAgICBbMTAwLjM1NDEsIDIxLjUwMDZdLFxuICAgICAqICAgICAgICAgWzEwMC4zNTQxLCAxMy45NzA2XSxcbiAgICAgKiAgICAgICAgIFs5MS40NDYxLCAxMy45NzA2XVxuICAgICAqICAgICBdXG4gICAgICogfSk7XG4gICAgICogbWFwLmdldFNvdXJjZSgnY2FudmFzLXNvdXJjZScpLmdldENhbnZhcygpOyAvLyA8Y2FudmFzIGlkPVwiY2FudmFzSURcIiB3aWR0aD1cIjQwMFwiIGhlaWdodD1cIjQwMFwiPjwvY2FudmFzPlxuICAgICAqL1xuICAgIGdldENhbnZhcygpOiBIVE1MQ2FudmFzRWxlbWVudCB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhbnZhcztcbiAgICB9XG5cbiAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgb25BZGQobWFwOiBNYXApIHtcbiAgICAgICAgdGhpcy5tYXAgPSBtYXA7XG4gICAgICAgIHRoaXMubG9hZCgpO1xuICAgICAgICBpZiAodGhpcy5jYW52YXMpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmFuaW1hdGUpIHRoaXMucGxheSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIG9uUmVtb3ZlKCkge1xuICAgICAgICB0aGlzLnBhdXNlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgY2FudmFzJ3MgY29vcmRpbmF0ZXMgYW5kIHJlLXJlbmRlcnMgdGhlIG1hcC5cbiAgICAgKlxuICAgICAqIEBtZXRob2Qgc2V0Q29vcmRpbmF0ZXNcbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAbWVtYmVyb2YgQ2FudmFzU291cmNlXG4gICAgICogQHBhcmFtIHtBcnJheTxBcnJheTxudW1iZXI+Pn0gY29vcmRpbmF0ZXMgRm91ciBnZW9ncmFwaGljYWwgY29vcmRpbmF0ZXMsXG4gICAgICogICByZXByZXNlbnRlZCBhcyBhcnJheXMgb2YgbG9uZ2l0dWRlIGFuZCBsYXRpdHVkZSBudW1iZXJzLCB3aGljaCBkZWZpbmUgdGhlIGNvcm5lcnMgb2YgdGhlIGNhbnZhcy5cbiAgICAgKiAgIFRoZSBjb29yZGluYXRlcyBzdGFydCBhdCB0aGUgdG9wIGxlZnQgY29ybmVyIG9mIHRoZSBjYW52YXMgYW5kIHByb2NlZWQgaW4gY2xvY2t3aXNlIG9yZGVyLlxuICAgICAqICAgVGhleSBkbyBub3QgaGF2ZSB0byByZXByZXNlbnQgYSByZWN0YW5nbGUuXG4gICAgICogQHJldHVybnMge0NhbnZhc1NvdXJjZX0gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKi9cblxuICAgIC8vIHNldENvb3JkaW5hdGVzIGluaGVyaXRlZCBmcm9tIEltYWdlU291cmNlXG5cbiAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgcHJlcGFyZSgpIHtcbiAgICAgICAgbGV0IHJlc2l6ZSA9IGZhbHNlO1xuICAgICAgICBpZiAodGhpcy5jYW52YXMud2lkdGggIT09IHRoaXMud2lkdGgpIHtcbiAgICAgICAgICAgIHRoaXMud2lkdGggPSB0aGlzLmNhbnZhcy53aWR0aDtcbiAgICAgICAgICAgIHJlc2l6ZSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuY2FudmFzLmhlaWdodCAhPT0gdGhpcy5oZWlnaHQpIHtcbiAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gdGhpcy5jYW52YXMuaGVpZ2h0O1xuICAgICAgICAgICAgcmVzaXplID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLl9oYXNJbnZhbGlkRGltZW5zaW9ucygpKSByZXR1cm47XG5cbiAgICAgICAgaWYgKE9iamVjdC5rZXlzKHRoaXMudGlsZXMpLmxlbmd0aCA9PT0gMCkgcmV0dXJuOyAvLyBub3QgZW5vdWdoIGRhdGEgZm9yIGN1cnJlbnQgcG9zaXRpb25cblxuICAgICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5tYXAucGFpbnRlci5jb250ZXh0O1xuXG4gICAgICAgIGlmICghdGhpcy50ZXh0dXJlKSB7XG4gICAgICAgICAgICB0aGlzLnRleHR1cmUgPSBuZXcgVGV4dHVyZShjb250ZXh0LCB0aGlzLmNhbnZhcywgY29udGV4dC5nbC5SR0JBLCB7cHJlbXVsdGlwbHk6IHRydWV9KTtcbiAgICAgICAgfSBlbHNlIGlmIChyZXNpemUgfHwgdGhpcy5fcGxheWluZykge1xuICAgICAgICAgICAgdGhpcy50ZXh0dXJlLnVwZGF0ZSh0aGlzLmNhbnZhcywge3ByZW11bHRpcGx5OiB0cnVlfSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9wcmVwYXJlRGF0YShjb250ZXh0KTtcbiAgICB9XG5cbiAgICBzZXJpYWxpemUoKTogT2JqZWN0IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6ICdjYW52YXMnLFxuICAgICAgICAgICAgY29vcmRpbmF0ZXM6IHRoaXMuY29vcmRpbmF0ZXNcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBoYXNUcmFuc2l0aW9uKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGxheWluZztcbiAgICB9XG5cbiAgICBfaGFzSW52YWxpZERpbWVuc2lvbnMoKTogYm9vbGVhbiB7XG4gICAgICAgIGZvciAoY29uc3QgeCBvZiBbdGhpcy5jYW52YXMud2lkdGgsIHRoaXMuY2FudmFzLmhlaWdodF0pIHtcbiAgICAgICAgICAgIGlmIChpc05hTih4KSB8fCB4IDw9IDApIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IENhbnZhc1NvdXJjZTtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCBUaWxlIGZyb20gJy4vdGlsZS5qcyc7XG5pbXBvcnQgd2luZG93IGZyb20gJy4uL3V0aWwvd2luZG93LmpzJztcbmltcG9ydCBUaWxlQm91bmRzIGZyb20gJy4vdGlsZV9ib3VuZHMuanMnO1xuaW1wb3J0IFJhc3RlclRpbGVTb3VyY2UgZnJvbSAnLi9yYXN0ZXJfdGlsZV9zb3VyY2UuanMnO1xuaW1wb3J0IHtleHRlbmQsIHBpY2t9IGZyb20gJy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQge0V2ZW50LCBFcnJvckV2ZW50LCBFdmVudGVkfSBmcm9tICcuLi91dGlsL2V2ZW50ZWQuanMnO1xuXG5pbXBvcnQgdHlwZSBNYXAgZnJvbSAnLi4vdWkvbWFwLmpzJztcbmltcG9ydCB0eXBlIERpc3BhdGNoZXIgZnJvbSAnLi4vdXRpbC9kaXNwYXRjaGVyLmpzJztcbmltcG9ydCB0eXBlIHtTb3VyY2V9IGZyb20gJy4vc291cmNlLmpzJztcbmltcG9ydCB0eXBlIHtDYWxsYmFja30gZnJvbSAnLi4vdHlwZXMvY2FsbGJhY2suanMnO1xuaW1wb3J0IHR5cGUge092ZXJzY2FsZWRUaWxlSUR9IGZyb20gJy4vdGlsZV9pZC5qcyc7XG5cbnR5cGUgRGF0YVR5cGUgPSAncmFzdGVyJztcblxuZnVuY3Rpb24gaXNSYXN0ZXIoZGF0YTogYW55KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGRhdGEgaW5zdGFuY2VvZiB3aW5kb3cuSW1hZ2VEYXRhIHx8XG4gICAgICAgIGRhdGEgaW5zdGFuY2VvZiB3aW5kb3cuSFRNTENhbnZhc0VsZW1lbnQgfHxcbiAgICAgICAgZGF0YSBpbnN0YW5jZW9mIHdpbmRvdy5JbWFnZUJpdG1hcCB8fFxuICAgICAgICBkYXRhIGluc3RhbmNlb2Ygd2luZG93LkhUTUxJbWFnZUVsZW1lbnQ7XG59XG5cbi8qKlxuICogSW50ZXJmYWNlIGZvciBjdXN0b20gc291cmNlcy4gVGhpcyBpcyBhIHNwZWNpZmljYXRpb24gZm9yXG4gKiBpbXBsZW1lbnRlcnMgdG8gbW9kZWw6IGl0IGlzIG5vdCBhbiBleHBvcnRlZCBtZXRob2Qgb3IgY2xhc3MuXG4gKlxuICogQ3VzdG9tIHNvdXJjZXMgYWxsb3cgYSB1c2VyIHRvIGxvYWQgYW5kIG1vZGlmeSB0aGVpciBvd24gdGlsZXMuXG4gKiBUaGVzZSBzb3VyY2VzIGNhbiBiZSBhZGRlZCBiZXR3ZWVuIGFueSByZWd1bGFyIHNvdXJjZXMgdXNpbmcge0BsaW5rIE1hcCNhZGRTb3VyY2V9LlxuICpcbiAqIEN1c3RvbSBzb3VyY2VzIG11c3QgaGF2ZSBhIHVuaXF1ZSBgaWRgIGFuZCBtdXN0IGhhdmUgdGhlIGB0eXBlYCBvZiBgXCJjdXN0b21cImAuXG4gKiBUaGV5IG11c3QgaW1wbGVtZW50IGBsb2FkVGlsZWAgYW5kIG1heSBpbXBsZW1lbnQgYHVubG9hZFRpbGVgLCBgb25BZGRgIGFuZCBgb25SZW1vdmVgLlxuICogVGhleSBjYW4gdHJpZ2dlciByZW5kZXJpbmcgdXNpbmcge0BsaW5rIE1hcCN0cmlnZ2VyUmVwYWludH0uXG4gKlxuICogQGludGVyZmFjZSBDdXN0b21Tb3VyY2VJbnRlcmZhY2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBpZCBBIHVuaXF1ZSBzb3VyY2UgaWQuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gdHlwZSBUaGUgc291cmNlJ3MgdHlwZS4gTXVzdCBiZSBgXCJjdXN0b21cImAuXG4gKiBAZXhhbXBsZVxuICogLy8gQ3VzdG9tIHNvdXJjZSBpbXBsZW1lbnRlZCBhcyBFUzYgY2xhc3NcbiAqIGNsYXNzIEN1c3RvbVNvdXJjZSB7XG4gKiAgICAgY29uc3RydWN0b3IoKSB7XG4gKiAgICAgICAgIHRoaXMuaWQgPSAnY3VzdG9tLXNvdXJjZSc7XG4gKiAgICAgICAgIHRoaXMudHlwZSA9ICdjdXN0b20nO1xuICogICAgICAgICB0aGlzLnRpbGVTaXplID0gMjU2O1xuICogICAgICAgICB0aGlzLnRpbGVzVXJsID0gJ2h0dHBzOi8vc3RhbWVuLXRpbGVzLmEuc3NsLmZhc3RseS5uZXQvd2F0ZXJjb2xvci97en0ve3h9L3t5fS5qcGcnO1xuICogICAgICAgICB0aGlzLmF0dHJpYnV0aW9uID0gJ01hcCB0aWxlcyBieSBTdGFtZW4gRGVzaWduLCB1bmRlciBDQyBCWSAzLjAnO1xuICogICAgIH1cbiAqXG4gKiAgICAgYXN5bmMgbG9hZFRpbGUodGlsZSwge3NpZ25hbH0pIHtcbiAqICAgICAgICAgY29uc3QgdXJsID0gdGhpcy50aWxlc1VybFxuICogICAgICAgICAgICAgLnJlcGxhY2UoJ3t6fScsIFN0cmluZyh0aWxlLnopKVxuICogICAgICAgICAgICAgLnJlcGxhY2UoJ3t4fScsIFN0cmluZyh0aWxlLngpKVxuICogICAgICAgICAgICAgLnJlcGxhY2UoJ3t5fScsIFN0cmluZyh0aWxlLnkpKTtcbiAqXG4gKiAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsLCB7c2lnbmFsfSk7XG4gKiAgICAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5hcnJheUJ1ZmZlcigpO1xuICpcbiAqICAgICAgICAgY29uc3QgYmxvYiA9IG5ldyB3aW5kb3cuQmxvYihbbmV3IFVpbnQ4QXJyYXkoZGF0YSldLCB7dHlwZTogJ2ltYWdlL3BuZyd9KTtcbiAqICAgICAgICAgY29uc3QgaW1hZ2VCaXRtYXAgPSBhd2FpdCB3aW5kb3cuY3JlYXRlSW1hZ2VCaXRtYXAoYmxvYik7XG4gKlxuICogICAgICAgICByZXR1cm4gaW1hZ2VCaXRtYXA7XG4gKiAgICAgfVxuICogfVxuICpcbiAqIG1hcC5vbignbG9hZCcsICgpID0+IHtcbiAqICAgICBtYXAuYWRkU291cmNlKCdjdXN0b20tc291cmNlJywgbmV3IEN1c3RvbVNvdXJjZSgpKTtcbiAqICAgICBtYXAuYWRkTGF5ZXIoe1xuICogICAgICAgICBpZDogJ2xheWVyJyxcbiAqICAgICAgICAgdHlwZTogJ3Jhc3RlcicsXG4gKiAgICAgICAgIHNvdXJjZTogJ2N1c3RvbS1zb3VyY2UnXG4gKiAgICAgfSk7XG4gKiB9KTtcbiAqL1xuXG4vKipcbiAqIE9wdGlvbmFsIG1ldGhvZCBjYWxsZWQgd2hlbiB0aGUgc291cmNlIGhhcyBiZWVuIGFkZGVkIHRvIHRoZSBNYXAgd2l0aCB7QGxpbmsgTWFwI2FkZFNvdXJjZX0uXG4gKiBUaGlzIGdpdmVzIHRoZSBzb3VyY2UgYSBjaGFuY2UgdG8gaW5pdGlhbGl6ZSByZXNvdXJjZXMgYW5kIHJlZ2lzdGVyIGV2ZW50IGxpc3RlbmVycy5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBtZW1iZXJvZiBDdXN0b21Tb3VyY2VJbnRlcmZhY2VcbiAqIEBpbnN0YW5jZVxuICogQG5hbWUgb25BZGRcbiAqIEBwYXJhbSB7TWFwfSBtYXAgVGhlIE1hcCB0aGlzIGN1c3RvbSBzb3VyY2Ugd2FzIGp1c3QgYWRkZWQgdG8uXG4gKi9cblxuLyoqXG4gKiBPcHRpb25hbCBtZXRob2QgY2FsbGVkIHdoZW4gdGhlIHNvdXJjZSBoYXMgYmVlbiByZW1vdmVkIGZyb20gdGhlIE1hcCB3aXRoIHtAbGluayBNYXAjcmVtb3ZlU291cmNlfS5cbiAqIFRoaXMgZ2l2ZXMgdGhlIHNvdXJjZSBhIGNoYW5jZSB0byBjbGVhbiB1cCByZXNvdXJjZXMgYW5kIGV2ZW50IGxpc3RlbmVycy5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBtZW1iZXJvZiBDdXN0b21Tb3VyY2VJbnRlcmZhY2VcbiAqIEBpbnN0YW5jZVxuICogQG5hbWUgb25SZW1vdmVcbiAqIEBwYXJhbSB7TWFwfSBtYXAgVGhlIE1hcCB0aGlzIGN1c3RvbSBzb3VyY2Ugd2FzIGFkZGVkIHRvLlxuICovXG5cbi8qKlxuICogT3B0aW9uYWwgbWV0aG9kIGNhbGxlZCBhZnRlciB0aGUgdGlsZSBpcyB1bmxvYWRlZCBmcm9tIHRoZSBtYXAgdmlld3BvcnQuIFRoaXNcbiAqIGdpdmVzIHRoZSBzb3VyY2UgYSBjaGFuY2UgdG8gY2xlYW4gdXAgcmVzb3VyY2VzIGFuZCBldmVudCBsaXN0ZW5lcnMuXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAbWVtYmVyb2YgQ3VzdG9tU291cmNlSW50ZXJmYWNlXG4gKiBAaW5zdGFuY2VcbiAqIEBuYW1lIHVubG9hZFRpbGVcbiAqIEBwYXJhbSB7eyB6OiBudW1iZXIsIHg6IG51bWJlciwgeTogbnVtYmVyIH19IHRpbGUgVGlsZSBuYW1lIHRvIHVubG9hZCBpbiB0aGUgWFlaIHNjaGVtZSBmb3JtYXQuXG4gKi9cblxuLyoqXG4gKiBPcHRpb25hbCBtZXRob2QgY2FsbGVkIGR1cmluZyBhIHJlbmRlciBmcmFtZSB0byBjaGVjayBpZiB0aGVyZSBpcyBhIHRpbGUgdG8gcmVuZGVyLlxuICpcbiAqIEBmdW5jdGlvblxuICogQG1lbWJlcm9mIEN1c3RvbVNvdXJjZUludGVyZmFjZVxuICogQGluc3RhbmNlXG4gKiBAbmFtZSBoYXNUaWxlXG4gKiBAcGFyYW0ge3sgejogbnVtYmVyLCB4OiBudW1iZXIsIHk6IG51bWJlciB9fSB0aWxlIFRpbGUgbmFtZSB0byBwcmVwYXJlIGluIHRoZSBYWVogc2NoZW1lIGZvcm1hdC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRpbGUgZXhpc3RzLCBvdGhlcndpc2UgZmFsc2UuXG4gKi9cblxuLyoqXG4gKiBDYWxsZWQgd2hlbiB0aGUgbWFwIHN0YXJ0cyBsb2FkaW5nIHRpbGUgZm9yIHRoZSBjdXJyZW50IGFuaW1hdGlvbiBmcmFtZS5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBtZW1iZXJvZiBDdXN0b21Tb3VyY2VJbnRlcmZhY2VcbiAqIEBpbnN0YW5jZVxuICogQG5hbWUgbG9hZFRpbGVcbiAqIEBwYXJhbSB7eyB6OiBudW1iZXIsIHg6IG51bWJlciwgeTogbnVtYmVyIH19IHRpbGUgVGlsZSBuYW1lIHRvIGxvYWQgaW4gdGhlIFhZWiBzY2hlbWUgZm9ybWF0LlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgT3B0aW9ucy5cbiAqIEBwYXJhbSB7QWJvcnRTaWduYWx9IG9wdGlvbnMuc2lnbmFsIEEgc2lnbmFsIG9iamVjdCB0aGF0IGNvbW11bmljYXRlcyB3aGVuIHRoZSBtYXAgY2FuY2VscyB0aGUgdGlsZSBsb2FkaW5nIHJlcXVlc3QuXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxUZXh0dXJlSW1hZ2UgfCB1bmRlZmluZWQgfCBudWxsPn0gVGhlIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgdGlsZSBpbWFnZSBkYXRhIGFzIGFuIGBIVE1MQ2FudmFzRWxlbWVudGAsIGBIVE1MSW1hZ2VFbGVtZW50YCwgYEltYWdlRGF0YWAsIGBJbWFnZUJpdG1hcGAgb3Igb2JqZWN0IHdpdGggYHdpZHRoYCwgYGhlaWdodGAsIGFuZCBgZGF0YWAuXG4gKiAgSWYgYGxvYWRUaWxlYCByZXNvbHZlcyB0byBgdW5kZWZpbmVkYCwgYSBtYXAgd2lsbCByZW5kZXIgYW4gb3ZlcnNjYWxlZCBwYXJlbnQgdGlsZSBpbiB0aGUgdGlsZeKAmXMgc3BhY2UuIElmIGBsb2FkVGlsZWAgcmVzb2x2ZXMgdG8gYG51bGxgLCBhIG1hcCB3aWxsIHJlbmRlciBub3RoaW5nIGluIHRoZSB0aWxl4oCZcyBzcGFjZS5cbiAqL1xuZXhwb3J0IHR5cGUgQ3VzdG9tU291cmNlSW50ZXJmYWNlPFQ+ID0ge1xuICAgIGlkOiBzdHJpbmc7XG4gICAgdHlwZTogJ2N1c3RvbScsXG4gICAgZGF0YVR5cGU6ID9EYXRhVHlwZSxcbiAgICBtaW56b29tOiA/bnVtYmVyLFxuICAgIG1heHpvb206ID9udW1iZXIsXG4gICAgc2NoZW1lOiA/c3RyaW5nO1xuICAgIHRpbGVTaXplOiA/bnVtYmVyLFxuICAgIGF0dHJpYnV0aW9uOiA/c3RyaW5nLFxuICAgIGJvdW5kczogP1tudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICAgIGhhc1RpbGU6ID8odGlsZUlEOiB7IHo6IG51bWJlciwgeDogbnVtYmVyLCB5OiBudW1iZXIgfSkgPT4gYm9vbGVhbixcbiAgICBsb2FkVGlsZTogKHRpbGVJRDogeyB6OiBudW1iZXIsIHg6IG51bWJlciwgeTogbnVtYmVyIH0sIG9wdGlvbnM6IHsgc2lnbmFsOiBBYm9ydFNpZ25hbCB9KSA9PiBQcm9taXNlPD9UPixcbiAgICB1bmxvYWRUaWxlOiA/KHRpbGVJRDogeyB6OiBudW1iZXIsIHg6IG51bWJlciwgeTogbnVtYmVyIH0pID0+IHZvaWQsXG4gICAgb25BZGQ6ID8obWFwOiBNYXApID0+IHZvaWQsXG4gICAgb25SZW1vdmU6ID8obWFwOiBNYXApID0+IHZvaWQsXG59XG5cbmNsYXNzIEN1c3RvbVNvdXJjZTxUPiBleHRlbmRzIEV2ZW50ZWQgaW1wbGVtZW50cyBTb3VyY2Uge1xuXG4gICAgaWQ6IHN0cmluZztcbiAgICB0eXBlOiAnY3VzdG9tJztcbiAgICBzY2hlbWU6IHN0cmluZztcbiAgICBtaW56b29tOiBudW1iZXI7XG4gICAgbWF4em9vbTogbnVtYmVyO1xuICAgIHRpbGVTaXplOiBudW1iZXI7XG4gICAgYXR0cmlidXRpb246IHN0cmluZyB8IHZvaWQ7XG5cbiAgICByb3VuZFpvb206IGJvb2xlYW4gfCB2b2lkO1xuICAgIHRpbGVCb3VuZHM6ID9UaWxlQm91bmRzO1xuICAgIG1pblRpbGVDYWNoZVNpemU6ID9udW1iZXI7XG4gICAgbWF4VGlsZUNhY2hlU2l6ZTogP251bWJlcjtcblxuICAgIF9tYXA6IE1hcDtcbiAgICBfbG9hZGVkOiBib29sZWFuO1xuICAgIF9kaXNwYXRjaGVyOiBEaXNwYXRjaGVyO1xuICAgIF9kYXRhVHlwZTogP0RhdGFUeXBlO1xuICAgIF9pbXBsZW1lbnRhdGlvbjogQ3VzdG9tU291cmNlSW50ZXJmYWNlPFQ+O1xuXG4gICAgY29uc3RydWN0b3IoaWQ6IHN0cmluZywgaW1wbGVtZW50YXRpb246IEN1c3RvbVNvdXJjZUludGVyZmFjZTxUPiwgZGlzcGF0Y2hlcjogRGlzcGF0Y2hlciwgZXZlbnRlZFBhcmVudDogRXZlbnRlZCkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLmlkID0gaWQ7XG4gICAgICAgIHRoaXMudHlwZSA9ICdjdXN0b20nO1xuICAgICAgICB0aGlzLl9kYXRhVHlwZSA9ICdyYXN0ZXInO1xuICAgICAgICB0aGlzLl9kaXNwYXRjaGVyID0gZGlzcGF0Y2hlcjtcbiAgICAgICAgdGhpcy5faW1wbGVtZW50YXRpb24gPSBpbXBsZW1lbnRhdGlvbjtcbiAgICAgICAgdGhpcy5zZXRFdmVudGVkUGFyZW50KGV2ZW50ZWRQYXJlbnQpO1xuXG4gICAgICAgIHRoaXMuc2NoZW1lID0gJ3h5eic7XG4gICAgICAgIHRoaXMubWluem9vbSA9IDA7XG4gICAgICAgIHRoaXMubWF4em9vbSA9IDIyO1xuICAgICAgICB0aGlzLnRpbGVTaXplID0gNTEyO1xuXG4gICAgICAgIHRoaXMuX2xvYWRlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnJvdW5kWm9vbSA9IHRydWU7XG5cbiAgICAgICAgaWYgKCF0aGlzLl9pbXBsZW1lbnRhdGlvbikge1xuICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFcnJvckV2ZW50KG5ldyBFcnJvcihgTWlzc2luZyBpbXBsZW1lbnRhdGlvbiBmb3IgJHt0aGlzLmlkfSBjdXN0b20gc291cmNlYCkpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5faW1wbGVtZW50YXRpb24ubG9hZFRpbGUpIHtcbiAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXJyb3JFdmVudChuZXcgRXJyb3IoYE1pc3NpbmcgbG9hZFRpbGUgaW1wbGVtZW50YXRpb24gZm9yICR7dGhpcy5pZH0gY3VzdG9tIHNvdXJjZWApKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5faW1wbGVtZW50YXRpb24uYm91bmRzKSB7XG4gICAgICAgICAgICB0aGlzLnRpbGVCb3VuZHMgPSBuZXcgVGlsZUJvdW5kcyh0aGlzLl9pbXBsZW1lbnRhdGlvbi5ib3VuZHMsIHRoaXMubWluem9vbSwgdGhpcy5tYXh6b29tKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXVxuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIGltcGxlbWVudGF0aW9uLnVwZGF0ZSA9IHRoaXMuX3VwZGF0ZS5iaW5kKHRoaXMpO1xuXG4gICAgICAgIC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXVxuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIGltcGxlbWVudGF0aW9uLmNsZWFyVGlsZXMgPSB0aGlzLl9jbGVhclRpbGVzLmJpbmQodGhpcyk7XG5cbiAgICAgICAgLy8gJEZsb3dGaXhNZVtwcm9wLW1pc3NpbmddXG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgaW1wbGVtZW50YXRpb24uY292ZXJpbmdUaWxlcyA9IHRoaXMuX2NvdmVyaW5nVGlsZXMuYmluZCh0aGlzKTtcblxuICAgICAgICBleHRlbmQodGhpcywgcGljayhpbXBsZW1lbnRhdGlvbiwgWydkYXRhVHlwZScsICdzY2hlbWUnLCAnbWluem9vbScsICdtYXh6b29tJywgJ3RpbGVTaXplJywgJ2F0dHJpYnV0aW9uJywgJ21pblRpbGVDYWNoZVNpemUnLCAnbWF4VGlsZUNhY2hlU2l6ZSddKSk7XG4gICAgfVxuXG4gICAgc2VyaWFsaXplKCk6IFNvdXJjZSB7XG4gICAgICAgIHJldHVybiBwaWNrKHRoaXMsIFsndHlwZScsICdzY2hlbWUnLCAnbWluem9vbScsICdtYXh6b29tJywgJ3RpbGVTaXplJywgJ2F0dHJpYnV0aW9uJ10pO1xuICAgIH1cblxuICAgIGxvYWQoKSB7XG4gICAgICAgIHRoaXMuX2xvYWRlZCA9IHRydWU7XG4gICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ2RhdGEnLCB7ZGF0YVR5cGU6ICdzb3VyY2UnLCBzb3VyY2VEYXRhVHlwZTogJ21ldGFkYXRhJ30pKTtcbiAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgnZGF0YScsIHtkYXRhVHlwZTogJ3NvdXJjZScsIHNvdXJjZURhdGFUeXBlOiAnY29udGVudCd9KSk7XG4gICAgfVxuXG4gICAgbG9hZGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9hZGVkO1xuICAgIH1cblxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICBvbkFkZChtYXA6IE1hcCk6IHZvaWQge1xuICAgICAgICB0aGlzLl9tYXAgPSBtYXA7XG4gICAgICAgIHRoaXMuX2xvYWRlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmZpcmUobmV3IEV2ZW50KCdkYXRhbG9hZGluZycsIHtkYXRhVHlwZTogJ3NvdXJjZSd9KSk7XG4gICAgICAgIGlmICh0aGlzLl9pbXBsZW1lbnRhdGlvbi5vbkFkZCkgdGhpcy5faW1wbGVtZW50YXRpb24ub25BZGQobWFwKTtcbiAgICAgICAgdGhpcy5sb2FkKCk7XG4gICAgfVxuXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIG9uUmVtb3ZlKG1hcDogTWFwKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLl9pbXBsZW1lbnRhdGlvbi5vblJlbW92ZSkge1xuICAgICAgICAgICAgdGhpcy5faW1wbGVtZW50YXRpb24ub25SZW1vdmUobWFwKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICBoYXNUaWxlKHRpbGVJRDogT3ZlcnNjYWxlZFRpbGVJRCk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAodGhpcy5faW1wbGVtZW50YXRpb24uaGFzVGlsZSkge1xuICAgICAgICAgICAgY29uc3Qge3gsIHksIHp9ID0gdGlsZUlELmNhbm9uaWNhbDtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9pbXBsZW1lbnRhdGlvbi5oYXNUaWxlKHt4LCB5LCB6fSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gIXRoaXMudGlsZUJvdW5kcyB8fCB0aGlzLnRpbGVCb3VuZHMuY29udGFpbnModGlsZUlELmNhbm9uaWNhbCk7XG4gICAgfVxuXG4gICAgbG9hZFRpbGUodGlsZTogVGlsZSwgY2FsbGJhY2s6IENhbGxiYWNrPHZvaWQ+KTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHt4LCB5LCB6fSA9IHRpbGUudGlsZUlELmNhbm9uaWNhbDtcbiAgICAgICAgY29uc3QgY29udHJvbGxlciA9IG5ldyB3aW5kb3cuQWJvcnRDb250cm9sbGVyKCk7XG4gICAgICAgIGNvbnN0IHNpZ25hbCA9IGNvbnRyb2xsZXIuc2lnbmFsO1xuXG4gICAgICAgIC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXVxuICAgICAgICB0aWxlLnJlcXVlc3QgPSBQcm9taXNlXG4gICAgICAgICAgICAucmVzb2x2ZSh0aGlzLl9pbXBsZW1lbnRhdGlvbi5sb2FkVGlsZSh7eCwgeSwgen0sIHtzaWduYWx9KSlcbiAgICAgICAgICAgIC50aGVuKHRpbGVMb2FkZWQuYmluZCh0aGlzKSlcbiAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgLy8gc2lsZW5jZSBBYm9ydEVycm9yXG4gICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDIwKSByZXR1cm47XG4gICAgICAgICAgICAgICAgdGlsZS5zdGF0ZSA9ICdlcnJvcmVkJztcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnJvcik7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAvLyAkRmxvd0ZpeE1lW3Byb3AtbWlzc2luZ11cbiAgICAgICAgdGlsZS5yZXF1ZXN0LmNhbmNlbCA9ICgpID0+IGNvbnRyb2xsZXIuYWJvcnQoKTtcblxuICAgICAgICAvLyAkRmxvd0ZpeE1lW21pc3NpbmctdGhpcy1hbm5vdF1cbiAgICAgICAgZnVuY3Rpb24gdGlsZUxvYWRlZChkYXRhOiA/VCkge1xuICAgICAgICAgICAgZGVsZXRlIHRpbGUucmVxdWVzdDtcblxuICAgICAgICAgICAgaWYgKHRpbGUuYWJvcnRlZCkge1xuICAgICAgICAgICAgICAgIHRpbGUuc3RhdGUgPSAndW5sb2FkZWQnO1xuICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhudWxsKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSWYgdGhlIGltcGxlbWVudGF0aW9uIHJldHVybmVkIGB1bmRlZmluZWRgIGFzIHRpbGUgZGF0YSxcbiAgICAgICAgICAgIC8vIG1hcmsgdGhlIHRpbGUgYXMgYGVycm9yZWRgIHRvIGluZGljYXRlIHRoYXQgd2UgaGF2ZSBubyBkYXRhIGZvciBpdC5cbiAgICAgICAgICAgIC8vIEEgbWFwIHdpbGwgcmVuZGVyIGFuIG92ZXJzY2FsZWQgcGFyZW50IHRpbGUgaW4gdGhlIHRpbGXigJlzIHNwYWNlLlxuICAgICAgICAgICAgaWYgKGRhdGEgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHRpbGUuc3RhdGUgPSAnZXJyb3JlZCc7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBJZiB0aGUgaW1wbGVtZW50YXRpb24gcmV0dXJuZWQgYG51bGxgIGFzIHRpbGUgZGF0YSxcbiAgICAgICAgICAgIC8vIG1hcmsgdGhlIHRpbGUgYXMgYGxvYWRlZGAgYW5kIHVzZSBhbiBhbiBlbXB0eSBpbWFnZSBhcyB0aWxlIGRhdGEuXG4gICAgICAgICAgICAvLyBBIG1hcCB3aWxsIHJlbmRlciBub3RoaW5nIGluIHRoZSB0aWxl4oCZcyBzcGFjZS5cbiAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZW1wdHlJbWFnZSA9IHt3aWR0aDogdGhpcy50aWxlU2l6ZSwgaGVpZ2h0OiB0aGlzLnRpbGVTaXplLCBkYXRhOiBudWxsfTtcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRUaWxlRGF0YSh0aWxlLCAoZW1wdHlJbWFnZTogYW55KSk7XG4gICAgICAgICAgICAgICAgdGlsZS5zdGF0ZSA9ICdsb2FkZWQnO1xuICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhudWxsKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFpc1Jhc3RlcihkYXRhKSkge1xuICAgICAgICAgICAgICAgIHRpbGUuc3RhdGUgPSAnZXJyb3JlZCc7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG5ldyBFcnJvcihgQ2FuJ3QgaW5mZXIgZGF0YSB0eXBlIGZvciAke3RoaXMuaWR9LCBvbmx5IHJhc3RlciBkYXRhIHN1cHBvcnRlZCBhdCB0aGUgbW9tZW50YCkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmxvYWRUaWxlRGF0YSh0aWxlLCBkYXRhKTtcbiAgICAgICAgICAgIHRpbGUuc3RhdGUgPSAnbG9hZGVkJztcbiAgICAgICAgICAgIGNhbGxiYWNrKG51bGwpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbG9hZFRpbGVEYXRhKHRpbGU6IFRpbGUsIGRhdGE6IFQpOiB2b2lkIHtcbiAgICAgICAgLy8gT25seSByYXN0ZXIgZGF0YSBzdXBwb3J0ZWQgYXQgdGhlIG1vbWVudFxuICAgICAgICBSYXN0ZXJUaWxlU291cmNlLmxvYWRUaWxlRGF0YSh0aWxlLCAoZGF0YTogYW55KSwgdGhpcy5fbWFwLnBhaW50ZXIpO1xuICAgIH1cblxuICAgIHVubG9hZFRpbGVEYXRhKHRpbGU6IFRpbGUpOiB2b2lkIHtcbiAgICAgICAgLy8gT25seSByYXN0ZXIgZGF0YSBzdXBwb3J0ZWQgYXQgdGhlIG1vbWVudFxuICAgICAgICBSYXN0ZXJUaWxlU291cmNlLnVubG9hZFRpbGVEYXRhKHRpbGUsIHRoaXMuX21hcC5wYWludGVyKTtcbiAgICB9XG5cbiAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgdW5sb2FkVGlsZSh0aWxlOiBUaWxlLCBjYWxsYmFjazogQ2FsbGJhY2s8dm9pZD4pOiB2b2lkIHtcbiAgICAgICAgdGhpcy51bmxvYWRUaWxlRGF0YSh0aWxlKTtcbiAgICAgICAgaWYgKHRoaXMuX2ltcGxlbWVudGF0aW9uLnVubG9hZFRpbGUpIHtcbiAgICAgICAgICAgIGNvbnN0IHt4LCB5LCB6fSA9IHRpbGUudGlsZUlELmNhbm9uaWNhbDtcbiAgICAgICAgICAgIHRoaXMuX2ltcGxlbWVudGF0aW9uLnVubG9hZFRpbGUoe3gsIHksIHp9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgfVxuXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIGFib3J0VGlsZSh0aWxlOiBUaWxlLCBjYWxsYmFjazogQ2FsbGJhY2s8dm9pZD4pOiB2b2lkIHtcbiAgICAgICAgaWYgKHRpbGUucmVxdWVzdCAmJiB0aWxlLnJlcXVlc3QuY2FuY2VsKSB7XG4gICAgICAgICAgICB0aWxlLnJlcXVlc3QuY2FuY2VsKCk7XG4gICAgICAgICAgICBkZWxldGUgdGlsZS5yZXF1ZXN0O1xuICAgICAgICB9XG5cbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICB9XG5cbiAgICBoYXNUcmFuc2l0aW9uKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgX2NvdmVyaW5nVGlsZXMoKTogeyB6OiBudW1iZXIsIHg6IG51bWJlciwgeTogbnVtYmVyIH1bXSB7XG4gICAgICAgIGNvbnN0IHRpbGVJRHMgPSB0aGlzLl9tYXAudHJhbnNmb3JtLmNvdmVyaW5nVGlsZXMoe1xuICAgICAgICAgICAgdGlsZVNpemU6IHRoaXMudGlsZVNpemUsXG4gICAgICAgICAgICBtaW56b29tOiB0aGlzLm1pbnpvb20sXG4gICAgICAgICAgICBtYXh6b29tOiB0aGlzLm1heHpvb20sXG4gICAgICAgICAgICByb3VuZFpvb206IHRoaXMucm91bmRab29tXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB0aWxlSURzLm1hcCh0aWxlSUQgPT4gKHt4OiB0aWxlSUQuY2Fub25pY2FsLngsIHk6IHRpbGVJRC5jYW5vbmljYWwueSwgejogdGlsZUlELmNhbm9uaWNhbC56fSkpO1xuICAgIH1cblxuICAgIF9jbGVhclRpbGVzKCkge1xuICAgICAgICB0aGlzLl9tYXAuc3R5bGUuX2NsZWFyU291cmNlKHRoaXMuaWQpO1xuICAgIH1cblxuICAgIF91cGRhdGUoKSB7XG4gICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ2RhdGEnLCB7ZGF0YVR5cGU6ICdzb3VyY2UnLCBzb3VyY2VEYXRhVHlwZTogJ2NvbnRlbnQnfSkpO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ3VzdG9tU291cmNlO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtiaW5kQWxsfSBmcm9tICcuLi91dGlsL3V0aWwuanMnO1xuXG5pbXBvcnQgdHlwZSBEaXNwYXRjaGVyIGZyb20gJy4uL3V0aWwvZGlzcGF0Y2hlci5qcyc7XG5pbXBvcnQgdHlwZSB7RXZlbnQsIEV2ZW50ZWR9IGZyb20gJy4uL3V0aWwvZXZlbnRlZC5qcyc7XG5pbXBvcnQgdHlwZSBNYXAgZnJvbSAnLi4vdWkvbWFwLmpzJztcbmltcG9ydCB0eXBlIFRpbGUgZnJvbSAnLi90aWxlLmpzJztcbmltcG9ydCB0eXBlIHtPdmVyc2NhbGVkVGlsZUlEfSBmcm9tICcuL3RpbGVfaWQuanMnO1xuaW1wb3J0IHR5cGUge0NhbGxiYWNrfSBmcm9tICcuLi90eXBlcy9jYWxsYmFjay5qcyc7XG5pbXBvcnQgdHlwZSB7TWFwRXZlbnR9IGZyb20gJy4uL3VpL2V2ZW50cy5qcyc7XG5pbXBvcnQge0Nhbm9uaWNhbFRpbGVJRH0gZnJvbSAnLi90aWxlX2lkLmpzJztcblxuLyoqXG4gKiBUaGUgYFNvdXJjZWAgaW50ZXJmYWNlIG11c3QgYmUgaW1wbGVtZW50ZWQgYnkgZWFjaCBzb3VyY2UgdHlwZSwgaW5jbHVkaW5nIFwiY29yZVwiIHR5cGVzIGxpa2UgYHZlY3RvcmAsIGByYXN0ZXJgLFxuICogb3IgYHZpZGVvYCkgYW5kIGFsbCBjdXN0b20sIHRoaXJkLXBhcnR5IHR5cGVzLlxuICpcbiAqIEBwcml2YXRlXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGlkIFRoZSBpZCBmb3IgdGhlIHNvdXJjZS4gTXVzdCBub3QgYmUgdXNlZCBieSBhbnkgZXhpc3Rpbmcgc291cmNlLlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgU291cmNlIG9wdGlvbnMsIHNwZWNpZmljIHRvIHRoZSBzb3VyY2UgdHlwZSAoZXhjZXB0IGZvciBgb3B0aW9ucy50eXBlYCwgd2hpY2ggaXMgYWx3YXlzXG4gKiByZXF1aXJlZCkuXG4gKiBAcGFyYW0ge3N0cmluZ30gb3B0aW9ucy50eXBlIFRoZSBzb3VyY2UgdHlwZSwgbWF0Y2hpbmcgdGhlIHZhbHVlIG9mIGBuYW1lYCB1c2VkIGluIHtAbGluayBTdHlsZSNhZGRTb3VyY2VUeXBlfS5cbiAqIEBwYXJhbSB7RGlzcGF0Y2hlcn0gZGlzcGF0Y2hlciBBIHtAbGluayBEaXNwYXRjaGVyfSBpbnN0YW5jZSwgd2hpY2ggY2FuIGJlIHVzZWQgdG8gc2VuZCBtZXNzYWdlcyB0byB0aGUgd29ya2Vycy5cbiAqXG4gKiBAZmlyZXMgTWFwLmV2ZW50OmRhdGEgRmlyZXMgYGRhdGFgIHdpdGggYHtkYXRhVHlwZTogJ3NvdXJjZScsIHNvdXJjZURhdGFUeXBlOiAnbWV0YWRhdGEnfWBcbiAqIHRvIGluZGljYXRlIHRoYXQgYW55IG5lY2Vzc2FyeSBtZXRhZGF0YSBoYXMgYmVlbiBsb2FkZWQgc28gdGhhdCBpdCdzIG9rYXkgdG8gY2FsbCBgbG9hZFRpbGVgO1xuICogZmlyZXMgYGRhdGFgIHdpdGggYHtkYXRhVHlwZTogJ3NvdXJjZScsIHNvdXJjZURhdGFUeXBlOiAnY29udGVudCd9YFxuICogdG8gaW5kaWNhdGUgdGhhdCB0aGUgc291cmNlIGRhdGEgaGFzIGNoYW5nZWQsIHNvIHRoYXQgYW55IGN1cnJlbnQgY2FjaGVzIHNob3VsZCBiZSBmbHVzaGVkLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IGlkIFRoZSBpZCBmb3IgdGhlIHNvdXJjZS4gIE11c3QgbWF0Y2ggdGhlIGlkIHBhc3NlZCB0byB0aGUgY29uc3RydWN0b3IuXG4gKiBAcHJvcGVydHkge251bWJlcn0gbWluem9vbVxuICogQHByb3BlcnR5IHtudW1iZXJ9IG1heHpvb21cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gaXNUaWxlQ2xpcHBlZCBgZmFsc2VgIGlmIHRpbGVzIGNhbiBiZSBkcmF3biBvdXRzaWRlIHRoZWlyIGJvdW5kYXJpZXMsIGB0cnVlYCBpZiB0aGV5IGNhbm5vdC5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gcmVwYXJzZU92ZXJzY2FsZWQgYHRydWVgIGlmIHRpbGVzIHNob3VsZCBiZSBzZW50IGJhY2sgdG8gdGhlIHdvcmtlciBmb3IgZWFjaCBvdmVyem9vbWVkIHpvb21cbiAqIGxldmVsLCBgZmFsc2VgIGlmIG5vdC5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gcm91bmRab29tIGB0cnVlYCBpZiB6b29tIGxldmVscyBhcmUgcm91bmRlZCB0byB0aGUgbmVhcmVzdCBpbnRlZ2VyIGluIHRoZSBzb3VyY2UgZGF0YSwgYGZhbHNlYFxuICogaWYgdGhleSBhcmUgZmxvb3ItZWQgdG8gdGhlIG5lYXJlc3QgaW50ZWdlci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTb3VyY2Uge1xuICAgICt0eXBlOiBzdHJpbmc7XG4gICAgaWQ6IHN0cmluZztcbiAgICBtaW56b29tOiBudW1iZXIsXG4gICAgbWF4em9vbTogbnVtYmVyLFxuICAgIHRpbGVTaXplOiBudW1iZXIsXG4gICAgYXR0cmlidXRpb24/OiBzdHJpbmcsXG5cbiAgICByb3VuZFpvb20/OiBib29sZWFuLFxuICAgIGlzVGlsZUNsaXBwZWQ/OiBib29sZWFuLFxuICAgIG1hcGJveF9sb2dvPzogYm9vbGVhbixcbiAgICB0aWxlSUQ/OiBDYW5vbmljYWxUaWxlSUQ7XG4gICAgcmVwYXJzZU92ZXJzY2FsZWQ/OiBib29sZWFuLFxuICAgIHZlY3RvckxheWVySWRzPzogQXJyYXk8c3RyaW5nPixcbiAgICBtaW5UaWxlQ2FjaGVTaXplPzogP251bWJlcjtcbiAgICBtYXhUaWxlQ2FjaGVTaXplPzogP251bWJlcjtcbiAgICBsYW5ndWFnZT86ID9zdHJpbmc7XG4gICAgd29ybGR2aWV3PzogP3N0cmluZztcblxuICAgIGhhc1RyYW5zaXRpb24oKTogYm9vbGVhbjtcbiAgICBsb2FkZWQoKTogYm9vbGVhbjtcblxuICAgIGZpcmUoZXZlbnQ6IEV2ZW50KTogbWl4ZWQ7XG4gICAgb24odHlwZTogTWFwRXZlbnQsIGxpc3RlbmVyOiAoT2JqZWN0KSA9PiBhbnkpOiBFdmVudGVkO1xuICAgIG9mZih0eXBlOiBNYXBFdmVudCwgbGlzdGVuZXI6IChPYmplY3QpID0+IGFueSk6IEV2ZW50ZWQ7XG4gICAgc2V0RXZlbnRlZFBhcmVudChwYXJlbnQ6ID9FdmVudGVkLCBkYXRhPzogT2JqZWN0IHwgKCkgPT4gT2JqZWN0KTogRXZlbnRlZDtcblxuICAgICtvbkFkZD86IChtYXA6IE1hcCkgPT4gdm9pZDtcbiAgICArb25SZW1vdmU/OiAobWFwOiBNYXApID0+IHZvaWQ7XG5cbiAgICBsb2FkVGlsZSh0aWxlOiBUaWxlLCBjYWxsYmFjazogQ2FsbGJhY2s8dm9pZD4sIHRpbGVXb3JrZXJzPzoge1tzdHJpbmddOiBBY3Rvcn0pOiB2b2lkO1xuICAgICtoYXNUaWxlPzogKHRpbGVJRDogT3ZlcnNjYWxlZFRpbGVJRCkgPT4gYm9vbGVhbjtcbiAgICArYWJvcnRUaWxlPzogKHRpbGU6IFRpbGUsIGNhbGxiYWNrOiBDYWxsYmFjazx2b2lkPikgPT4gdm9pZDtcbiAgICArdW5sb2FkVGlsZT86ICh0aWxlOiBUaWxlLCBjYWxsYmFjazogQ2FsbGJhY2s8dm9pZD4pID0+IHZvaWQ7XG4gICAgK3JlbG9hZD86ICgpID0+IHZvaWQ7XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBBIHBsYWluIChzdHJpbmdpZmlhYmxlKSBKUyBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBzb3VyY2UuXG4gICAgICogQ3JlYXRpbmcgYSBzb3VyY2UgdXNpbmcgdGhlIHJldHVybmVkIG9iamVjdCBhcyB0aGUgYG9wdGlvbnNgIHNob3VsZCByZXN1bHQgaW4gYSBTb3VyY2UgdGhhdCBpc1xuICAgICAqIGVxdWl2YWxlbnQgdG8gdGhpcyBvbmUuXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzZXJpYWxpemUoKTogT2JqZWN0O1xuXG4gICAgK3ByZXBhcmU/OiAoKSA9PiB2b2lkO1xuXG4gICAgK2FmdGVyVXBkYXRlPzogKCkgPT4gdm9pZDtcbiAgICArX2NsZWFyPzogKCkgPT4gdm9pZDtcbn1cblxudHlwZSBTb3VyY2VTdGF0aWNzID0ge1xuICAgIC8qXG4gICAgICogQW4gb3B0aW9uYWwgVVJMIHRvIGEgc2NyaXB0IHdoaWNoLCB3aGVuIHJ1biBieSBhIFdvcmtlciwgcmVnaXN0ZXJzIGEge0BsaW5rIFdvcmtlclNvdXJjZX1cbiAgICAgKiBpbXBsZW1lbnRhdGlvbiBmb3IgdGhpcyBTb3VyY2UgdHlwZSBieSBjYWxsaW5nIGBzZWxmLnJlZ2lzdGVyV29ya2VyU291cmNlKHdvcmtlclNvdXJjZTogV29ya2VyU291cmNlKWAuXG4gICAgICovXG4gICAgd29ya2VyU291cmNlVVJMPzogVVJMO1xufTtcblxuZXhwb3J0IHR5cGUgU291cmNlQ2xhc3MgPSBDbGFzczxTb3VyY2U+ICYgU291cmNlU3RhdGljcztcblxuaW1wb3J0IHZlY3RvciBmcm9tICcuLi9zb3VyY2UvdmVjdG9yX3RpbGVfc291cmNlLmpzJztcbmltcG9ydCByYXN0ZXIgZnJvbSAnLi4vc291cmNlL3Jhc3Rlcl90aWxlX3NvdXJjZS5qcyc7XG5pbXBvcnQgcmFzdGVyRGVtIGZyb20gJy4uL3NvdXJjZS9yYXN0ZXJfZGVtX3RpbGVfc291cmNlLmpzJztcbmltcG9ydCBnZW9qc29uIGZyb20gJy4uL3NvdXJjZS9nZW9qc29uX3NvdXJjZS5qcyc7XG5pbXBvcnQgdmlkZW8gZnJvbSAnLi4vc291cmNlL3ZpZGVvX3NvdXJjZS5qcyc7XG5pbXBvcnQgaW1hZ2UgZnJvbSAnLi4vc291cmNlL2ltYWdlX3NvdXJjZS5qcyc7XG5pbXBvcnQgY2FudmFzIGZyb20gJy4uL3NvdXJjZS9jYW52YXNfc291cmNlLmpzJztcbmltcG9ydCBjdXN0b20gZnJvbSAnLi4vc291cmNlL2N1c3RvbV9zb3VyY2UuanMnO1xuXG5pbXBvcnQgdHlwZSB7U291cmNlU3BlY2lmaWNhdGlvbn0gZnJvbSAnLi4vc3R5bGUtc3BlYy90eXBlcy5qcyc7XG5cbmNvbnN0IHNvdXJjZVR5cGVzOiB7W3N0cmluZ106IENsYXNzPFNvdXJjZT59ID0ge1xuICAgIHZlY3RvcixcbiAgICByYXN0ZXIsXG4gICAgJ3Jhc3Rlci1kZW0nOiByYXN0ZXJEZW0sXG4gICAgZ2VvanNvbixcbiAgICB2aWRlbyxcbiAgICBpbWFnZSxcbiAgICBjYW52YXMsXG4gICAgY3VzdG9tXG59O1xuXG4vKlxuICogQ3JlYXRlcyBhIHRpbGVkIGRhdGEgc291cmNlIGluc3RhbmNlIGdpdmVuIGFuIG9wdGlvbnMgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSBpZFxuICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBBIHNvdXJjZSBkZWZpbml0aW9uIG9iamVjdCBjb21wbGlhbnQgd2l0aFxuICogW2BtYXBib3gtZ2wtc3R5bGUtc3BlY2BdKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLXN0eWxlLXNwZWMvI3NvdXJjZXMpIG9yLCBmb3IgYSB0aGlyZC1wYXJ0eSBzb3VyY2UgdHlwZSxcbiAgKiB3aXRoIHRoYXQgdHlwZSdzIHJlcXVpcmVtZW50cy5cbiAqIEBwYXJhbSB7RGlzcGF0Y2hlcn0gZGlzcGF0Y2hlclxuICogQHJldHVybnMge1NvdXJjZX1cbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZSA9IGZ1bmN0aW9uKGlkOiBzdHJpbmcsIHNwZWNpZmljYXRpb246IFNvdXJjZVNwZWNpZmljYXRpb24sIGRpc3BhdGNoZXI6IERpc3BhdGNoZXIsIGV2ZW50ZWRQYXJlbnQ6IEV2ZW50ZWQpOiBTb3VyY2Uge1xuICAgIC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXVxuICAgIGNvbnN0IHNvdXJjZSA9IG5ldyBzb3VyY2VUeXBlc1tzcGVjaWZpY2F0aW9uLnR5cGVdKGlkLCAoc3BlY2lmaWNhdGlvbjogYW55KSwgZGlzcGF0Y2hlciwgZXZlbnRlZFBhcmVudCk7XG5cbiAgICBpZiAoc291cmNlLmlkICE9PSBpZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIFNvdXJjZSBpZCB0byBiZSAke2lkfSBpbnN0ZWFkIG9mICR7c291cmNlLmlkfWApO1xuICAgIH1cblxuICAgIGJpbmRBbGwoWydsb2FkJywgJ2Fib3J0JywgJ3VubG9hZCcsICdzZXJpYWxpemUnLCAncHJlcGFyZSddLCBzb3VyY2UpO1xuICAgIHJldHVybiBzb3VyY2U7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0VHlwZSA9IGZ1bmN0aW9uIChuYW1lOiBzdHJpbmcpOiBDbGFzczxTb3VyY2U+IHtcbiAgICByZXR1cm4gc291cmNlVHlwZXNbbmFtZV07XG59O1xuXG5leHBvcnQgY29uc3Qgc2V0VHlwZSA9IGZ1bmN0aW9uIChuYW1lOiBzdHJpbmcsIHR5cGU6IENsYXNzPFNvdXJjZT4pIHtcbiAgICBzb3VyY2VUeXBlc1tuYW1lXSA9IHR5cGU7XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIEFjdG9yIHtcbiAgICBzZW5kKHR5cGU6IHN0cmluZywgZGF0YTogT2JqZWN0LCBjYWxsYmFjazogQ2FsbGJhY2s8YW55Pik6IHZvaWQ7XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgdHlwZSB7T3ZlcnNjYWxlZFRpbGVJRH0gZnJvbSAnLi90aWxlX2lkLmpzJztcbmltcG9ydCB0eXBlIFNvdXJjZUNhY2hlIGZyb20gJy4vc291cmNlX2NhY2hlLmpzJztcbmltcG9ydCB0eXBlIFN0eWxlTGF5ZXIgZnJvbSAnLi4vc3R5bGUvc3R5bGVfbGF5ZXIuanMnO1xuaW1wb3J0IHR5cGUgQ29sbGlzaW9uSW5kZXggZnJvbSAnLi4vc3ltYm9sL2NvbGxpc2lvbl9pbmRleC5qcyc7XG5pbXBvcnQgdHlwZSBUcmFuc2Zvcm0gZnJvbSAnLi4vZ2VvL3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQgdHlwZSB7UmV0YWluZWRRdWVyeURhdGF9IGZyb20gJy4uL3N5bWJvbC9wbGFjZW1lbnQuanMnO1xuaW1wb3J0IHR5cGUge0ZpbHRlclNwZWNpZmljYXRpb259IGZyb20gJy4uL3N0eWxlLXNwZWMvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge1F1ZXJ5R2VvbWV0cnksIFRpbGVzcGFjZVF1ZXJ5R2VvbWV0cnl9IGZyb20gJy4uL3N0eWxlL3F1ZXJ5X2dlb21ldHJ5LmpzJztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCB7bWF0NH0gZnJvbSAnZ2wtbWF0cml4JztcblxuaW1wb3J0IHR5cGUgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5pbXBvcnQgdHlwZSB7UXVlcnlSZXN1bHR9IGZyb20gJy4uL2RhdGEvZmVhdHVyZV9pbmRleC5qcyc7XG5pbXBvcnQgdHlwZSB7UXVlcnlGZWF0dXJlfSBmcm9tICcuLi91dGlsL3ZlY3RvcnRpbGVfdG9fZ2VvanNvbi5qcyc7XG5cbmV4cG9ydCB0eXBlIFJlbmRlcmVkRmVhdHVyZUxheWVycyA9IEFycmF5PHtcbiAgICB3cmFwcGVkVGlsZUlEOiBudW1iZXI7XG4gICAgcXVlcnlSZXN1bHRzOiBRdWVyeVJlc3VsdFxufT47XG5cbi8qXG4gKiBSZXR1cm5zIGEgbWF0cml4IHRoYXQgY2FuIGJlIHVzZWQgdG8gY29udmVydCBmcm9tIHRpbGUgY29vcmRpbmF0ZXMgdG8gdmlld3BvcnQgcGl4ZWwgY29vcmRpbmF0ZXMuXG4gKi9cbmZ1bmN0aW9uIGdldFBpeGVsUG9zTWF0cml4KHRyYW5zZm9ybTogVHJhbnNmb3JtLCB0aWxlSUQ6IE92ZXJzY2FsZWRUaWxlSUQpIHtcbiAgICBjb25zdCB0ID0gbWF0NC5pZGVudGl0eShbXSk7XG4gICAgbWF0NC5zY2FsZSh0LCB0LCBbdHJhbnNmb3JtLndpZHRoICogMC41LCAtdHJhbnNmb3JtLmhlaWdodCAqIDAuNSwgMV0pO1xuICAgIG1hdDQudHJhbnNsYXRlKHQsIHQsIFsxLCAtMSwgMF0pO1xuICAgIG1hdDQubXVsdGlwbHkodCwgdCwgdHJhbnNmb3JtLmNhbGN1bGF0ZVByb2pNYXRyaXgodGlsZUlELnRvVW53cmFwcGVkKCkpKTtcbiAgICByZXR1cm4gRmxvYXQzMkFycmF5LmZyb20odCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBxdWVyeVJlbmRlcmVkRmVhdHVyZXMoc291cmNlQ2FjaGU6IFNvdXJjZUNhY2hlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlTGF5ZXJzOiB7W186IHN0cmluZ106IFN0eWxlTGF5ZXJ9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcmlhbGl6ZWRMYXllcnM6IHtbXzogc3RyaW5nXTogT2JqZWN0fSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBxdWVyeUdlb21ldHJ5OiBRdWVyeUdlb21ldHJ5LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtczogeyBmaWx0ZXI6IEZpbHRlclNwZWNpZmljYXRpb24sIGxheWVyczogQXJyYXk8c3RyaW5nPiwgYXZhaWxhYmxlSW1hZ2VzOiBBcnJheTxzdHJpbmc+IH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtOiBUcmFuc2Zvcm0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlM0RRdWVyeTogYm9vbGVhbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aXN1YWxpemVRdWVyeUdlb21ldHJ5OiBib29sZWFuID0gZmFsc2UpOiBRdWVyeVJlc3VsdCB7XG4gICAgY29uc3QgdGlsZVJlc3VsdHMgPSBzb3VyY2VDYWNoZS50aWxlc0luKHF1ZXJ5R2VvbWV0cnksIHVzZTNEUXVlcnksIHZpc3VhbGl6ZVF1ZXJ5R2VvbWV0cnkpO1xuICAgIHRpbGVSZXN1bHRzLnNvcnQoc29ydFRpbGVzSW4pO1xuICAgIGNvbnN0IHJlbmRlcmVkRmVhdHVyZUxheWVycyA9IFtdO1xuICAgIGZvciAoY29uc3QgdGlsZVJlc3VsdCBvZiB0aWxlUmVzdWx0cykge1xuICAgICAgICByZW5kZXJlZEZlYXR1cmVMYXllcnMucHVzaCh7XG4gICAgICAgICAgICB3cmFwcGVkVGlsZUlEOiB0aWxlUmVzdWx0LnRpbGUudGlsZUlELndyYXBwZWQoKS5rZXksXG4gICAgICAgICAgICBxdWVyeVJlc3VsdHM6IHRpbGVSZXN1bHQudGlsZS5xdWVyeVJlbmRlcmVkRmVhdHVyZXMoXG4gICAgICAgICAgICAgICAgc3R5bGVMYXllcnMsXG4gICAgICAgICAgICAgICAgc2VyaWFsaXplZExheWVycyxcbiAgICAgICAgICAgICAgICBzb3VyY2VDYWNoZS5fc3RhdGUsXG4gICAgICAgICAgICAgICAgdGlsZVJlc3VsdCxcbiAgICAgICAgICAgICAgICBwYXJhbXMsXG4gICAgICAgICAgICAgICAgdHJhbnNmb3JtLFxuICAgICAgICAgICAgICAgIGdldFBpeGVsUG9zTWF0cml4KHNvdXJjZUNhY2hlLnRyYW5zZm9ybSwgdGlsZVJlc3VsdC50aWxlLnRpbGVJRCksXG4gICAgICAgICAgICAgICAgdmlzdWFsaXplUXVlcnlHZW9tZXRyeSlcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gbWVyZ2VSZW5kZXJlZEZlYXR1cmVMYXllcnMocmVuZGVyZWRGZWF0dXJlTGF5ZXJzKTtcblxuICAgIC8vIE1lcmdlIHN0YXRlIGZyb20gU291cmNlQ2FjaGUgaW50byB0aGUgcmVzdWx0c1xuICAgIGZvciAoY29uc3QgbGF5ZXJJRCBpbiByZXN1bHQpIHtcbiAgICAgICAgcmVzdWx0W2xheWVySURdLmZvckVhY2goKGZlYXR1cmVXcmFwcGVyKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBmZWF0dXJlID0gZmVhdHVyZVdyYXBwZXIuZmVhdHVyZTtcbiAgICAgICAgICAgIGNvbnN0IGxheWVyID0gZmVhdHVyZS5sYXllcjtcblxuICAgICAgICAgICAgaWYgKCFsYXllciB8fCBsYXllci50eXBlID09PSAnYmFja2dyb3VuZCcgfHwgbGF5ZXIudHlwZSA9PT0gJ3NreScpIHJldHVybjtcblxuICAgICAgICAgICAgZmVhdHVyZS5zb3VyY2UgPSBsYXllci5zb3VyY2U7XG4gICAgICAgICAgICBpZiAobGF5ZXJbJ3NvdXJjZS1sYXllciddKSB7XG4gICAgICAgICAgICAgICAgZmVhdHVyZS5zb3VyY2VMYXllciA9IGxheWVyWydzb3VyY2UtbGF5ZXInXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZlYXR1cmUuc3RhdGUgPSBmZWF0dXJlLmlkICE9PSB1bmRlZmluZWQgPyBzb3VyY2VDYWNoZS5nZXRGZWF0dXJlU3RhdGUobGF5ZXJbJ3NvdXJjZS1sYXllciddLCBmZWF0dXJlLmlkKSA6IHt9O1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHF1ZXJ5UmVuZGVyZWRTeW1ib2xzKHN0eWxlTGF5ZXJzOiB7W186IHN0cmluZ106IFN0eWxlTGF5ZXJ9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcmlhbGl6ZWRMYXllcnM6IHtbXzogc3RyaW5nXTogU3R5bGVMYXllcn0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TGF5ZXJTb3VyY2VDYWNoZTogKGxheWVyOiBTdHlsZUxheWVyKSA9PiBTb3VyY2VDYWNoZSB8IHZvaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVlcnlHZW9tZXRyeTogQXJyYXk8UG9pbnQ+LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtczogeyBmaWx0ZXI6IEZpbHRlclNwZWNpZmljYXRpb24sIGxheWVyczogQXJyYXk8c3RyaW5nPiwgYXZhaWxhYmxlSW1hZ2VzOiBBcnJheTxzdHJpbmc+IH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sbGlzaW9uSW5kZXg6IENvbGxpc2lvbkluZGV4LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldGFpbmVkUXVlcnlEYXRhOiB7W186IG51bWJlcl06IFJldGFpbmVkUXVlcnlEYXRhfSk6IFF1ZXJ5UmVzdWx0IHtcbiAgICBjb25zdCByZXN1bHQgPSB7fTtcbiAgICBjb25zdCByZW5kZXJlZFN5bWJvbHMgPSBjb2xsaXNpb25JbmRleC5xdWVyeVJlbmRlcmVkU3ltYm9scyhxdWVyeUdlb21ldHJ5KTtcbiAgICBjb25zdCBidWNrZXRRdWVyeURhdGEgPSBbXTtcbiAgICBmb3IgKGNvbnN0IGJ1Y2tldEluc3RhbmNlSWQgb2YgT2JqZWN0LmtleXMocmVuZGVyZWRTeW1ib2xzKS5tYXAoTnVtYmVyKSkge1xuICAgICAgICBidWNrZXRRdWVyeURhdGEucHVzaChyZXRhaW5lZFF1ZXJ5RGF0YVtidWNrZXRJbnN0YW5jZUlkXSk7XG4gICAgfVxuICAgIGJ1Y2tldFF1ZXJ5RGF0YS5zb3J0KHNvcnRUaWxlc0luKTtcblxuICAgIGZvciAoY29uc3QgcXVlcnlEYXRhIG9mIGJ1Y2tldFF1ZXJ5RGF0YSkge1xuICAgICAgICBjb25zdCBidWNrZXRTeW1ib2xzID0gcXVlcnlEYXRhLmZlYXR1cmVJbmRleC5sb29rdXBTeW1ib2xGZWF0dXJlcyhcbiAgICAgICAgICAgICAgICByZW5kZXJlZFN5bWJvbHNbcXVlcnlEYXRhLmJ1Y2tldEluc3RhbmNlSWRdLFxuICAgICAgICAgICAgICAgIHNlcmlhbGl6ZWRMYXllcnMsXG4gICAgICAgICAgICAgICAgcXVlcnlEYXRhLmJ1Y2tldEluZGV4LFxuICAgICAgICAgICAgICAgIHF1ZXJ5RGF0YS5zb3VyY2VMYXllckluZGV4LFxuICAgICAgICAgICAgICAgIHBhcmFtcy5maWx0ZXIsXG4gICAgICAgICAgICAgICAgcGFyYW1zLmxheWVycyxcbiAgICAgICAgICAgICAgICBwYXJhbXMuYXZhaWxhYmxlSW1hZ2VzLFxuICAgICAgICAgICAgICAgIHN0eWxlTGF5ZXJzKTtcblxuICAgICAgICBmb3IgKGNvbnN0IGxheWVySUQgaW4gYnVja2V0U3ltYm9scykge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0RmVhdHVyZXMgPSByZXN1bHRbbGF5ZXJJRF0gPSByZXN1bHRbbGF5ZXJJRF0gfHwgW107XG4gICAgICAgICAgICBjb25zdCBsYXllclN5bWJvbHMgPSBidWNrZXRTeW1ib2xzW2xheWVySURdO1xuICAgICAgICAgICAgbGF5ZXJTeW1ib2xzLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBNYXRjaCB0b3BEb3duRmVhdHVyZUNvbXBhcmF0b3IgZnJvbSBGZWF0dXJlSW5kZXgsIGJ1dCB1c2luZ1xuICAgICAgICAgICAgICAgIC8vIG1vc3QgcmVjZW50IHNvcnRpbmcgb2YgZmVhdHVyZXMgZnJvbSBidWNrZXQuc29ydEZlYXR1cmVzXG4gICAgICAgICAgICAgICAgY29uc3QgZmVhdHVyZVNvcnRPcmRlciA9IHF1ZXJ5RGF0YS5mZWF0dXJlU29ydE9yZGVyO1xuICAgICAgICAgICAgICAgIGlmIChmZWF0dXJlU29ydE9yZGVyKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHF1ZXJ5UmVuZGVyZWRTeW1ib2xzIGRvY3VtZW50YXRpb24gc2F5cyB3ZSdsbCByZXR1cm4gZmVhdHVyZXMgaW5cbiAgICAgICAgICAgICAgICAgICAgLy8gXCJ0b3AtdG8tYm90dG9tXCIgcmVuZGVyaW5nIG9yZGVyIChha2EgbGFzdC10by1maXJzdCkuXG4gICAgICAgICAgICAgICAgICAgIC8vIEFjdHVhbGx5IHRoZXJlIGNhbiBiZSBtdWx0aXBsZSBzeW1ib2wgaW5zdGFuY2VzIHBlciBmZWF0dXJlLCBzb1xuICAgICAgICAgICAgICAgICAgICAvLyB3ZSBzb3J0IGVhY2ggZmVhdHVyZSBiYXNlZCBvbiB0aGUgZmlyc3QgbWF0Y2hpbmcgc3ltYm9sIGluc3RhbmNlLlxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzb3J0ZWRBID0gZmVhdHVyZVNvcnRPcmRlci5pbmRleE9mKGEuZmVhdHVyZUluZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc29ydGVkQiA9IGZlYXR1cmVTb3J0T3JkZXIuaW5kZXhPZihiLmZlYXR1cmVJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgIGFzc2VydChzb3J0ZWRBID49IDApO1xuICAgICAgICAgICAgICAgICAgICBhc3NlcnQoc29ydGVkQiA+PSAwKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNvcnRlZEIgLSBzb3J0ZWRBO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1Y2tldCBoYXNuJ3QgYmVlbiByZS1zb3J0ZWQgYmFzZWQgb24gYW5nbGUsIHNvIHVzZSB0aGVcbiAgICAgICAgICAgICAgICAgICAgLy8gcmV2ZXJzZSBvZiB0aGUgb3JkZXIgdGhlIGZlYXR1cmVzIGFwcGVhcmVkIGluIHRoZSBkYXRhLlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYi5mZWF0dXJlSW5kZXggLSBhLmZlYXR1cmVJbmRleDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGZvciAoY29uc3Qgc3ltYm9sRmVhdHVyZSBvZiBsYXllclN5bWJvbHMpIHtcbiAgICAgICAgICAgICAgICByZXN1bHRGZWF0dXJlcy5wdXNoKHN5bWJvbEZlYXR1cmUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gTWVyZ2Ugc3RhdGUgZnJvbSBTb3VyY2VDYWNoZSBpbnRvIHRoZSByZXN1bHRzXG4gICAgZm9yIChjb25zdCBsYXllck5hbWUgaW4gcmVzdWx0KSB7XG4gICAgICAgIHJlc3VsdFtsYXllck5hbWVdLmZvckVhY2goKGZlYXR1cmVXcmFwcGVyKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBmZWF0dXJlID0gZmVhdHVyZVdyYXBwZXIuZmVhdHVyZTtcbiAgICAgICAgICAgIGNvbnN0IGxheWVyID0gc3R5bGVMYXllcnNbbGF5ZXJOYW1lXTtcbiAgICAgICAgICAgIGNvbnN0IHNvdXJjZUNhY2hlID0gZ2V0TGF5ZXJTb3VyY2VDYWNoZShsYXllcik7XG4gICAgICAgICAgICBpZiAoIXNvdXJjZUNhY2hlKSByZXR1cm47XG5cbiAgICAgICAgICAgIGNvbnN0IHN0YXRlID0gc291cmNlQ2FjaGUuZ2V0RmVhdHVyZVN0YXRlKGZlYXR1cmUubGF5ZXJbJ3NvdXJjZS1sYXllciddLCBmZWF0dXJlLmlkKTtcbiAgICAgICAgICAgIGZlYXR1cmUuc291cmNlID0gZmVhdHVyZS5sYXllci5zb3VyY2U7XG4gICAgICAgICAgICBpZiAoZmVhdHVyZS5sYXllclsnc291cmNlLWxheWVyJ10pIHtcbiAgICAgICAgICAgICAgICBmZWF0dXJlLnNvdXJjZUxheWVyID0gZmVhdHVyZS5sYXllclsnc291cmNlLWxheWVyJ107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmZWF0dXJlLnN0YXRlID0gc3RhdGU7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcXVlcnlTb3VyY2VGZWF0dXJlcyhzb3VyY2VDYWNoZTogU291cmNlQ2FjaGUsIHBhcmFtczogYW55KTogQXJyYXk8UXVlcnlGZWF0dXJlPiB7XG4gICAgY29uc3QgdGlsZXMgPSBzb3VyY2VDYWNoZS5nZXRSZW5kZXJhYmxlSWRzKCkubWFwKChpZCkgPT4ge1xuICAgICAgICByZXR1cm4gc291cmNlQ2FjaGUuZ2V0VGlsZUJ5SUQoaWQpO1xuICAgIH0pO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gW107XG5cbiAgICBjb25zdCBkYXRhVGlsZXMgPSB7fTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRpbGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHRpbGUgPSB0aWxlc1tpXTtcbiAgICAgICAgY29uc3QgZGF0YUlEID0gdGlsZS50aWxlSUQuY2Fub25pY2FsLmtleTtcbiAgICAgICAgaWYgKCFkYXRhVGlsZXNbZGF0YUlEXSkge1xuICAgICAgICAgICAgZGF0YVRpbGVzW2RhdGFJRF0gPSB0cnVlO1xuICAgICAgICAgICAgdGlsZS5xdWVyeVNvdXJjZUZlYXR1cmVzKHJlc3VsdCwgcGFyYW1zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIHNvcnRUaWxlc0luKGE6IFRpbGVzcGFjZVF1ZXJ5R2VvbWV0cnkgfCBSZXRhaW5lZFF1ZXJ5RGF0YSwgYjogVGlsZXNwYWNlUXVlcnlHZW9tZXRyeSB8IFJldGFpbmVkUXVlcnlEYXRhKSB7XG4gICAgY29uc3QgaWRBID0gYS50aWxlSUQ7XG4gICAgY29uc3QgaWRCID0gYi50aWxlSUQ7XG4gICAgcmV0dXJuIChpZEEub3ZlcnNjYWxlZFogLSBpZEIub3ZlcnNjYWxlZFopIHx8IChpZEEuY2Fub25pY2FsLnkgLSBpZEIuY2Fub25pY2FsLnkpIHx8IChpZEEud3JhcCAtIGlkQi53cmFwKSB8fCAoaWRBLmNhbm9uaWNhbC54IC0gaWRCLmNhbm9uaWNhbC54KTtcbn1cblxuZnVuY3Rpb24gbWVyZ2VSZW5kZXJlZEZlYXR1cmVMYXllcnModGlsZXM6IFJlbmRlcmVkRmVhdHVyZUxheWVycyk6IFF1ZXJ5UmVzdWx0IHtcbiAgICAvLyBNZXJnZSByZXN1bHRzIGZyb20gYWxsIHRpbGVzLCBidXQgaWYgdHdvIHRpbGVzIHNoYXJlIHRoZSBzYW1lXG4gICAgLy8gd3JhcHBlZCBJRCwgZG9uJ3QgZHVwbGljYXRlIGZlYXR1cmVzIGJldHdlZW4gdGhlIHR3byB0aWxlc1xuICAgIGNvbnN0IHJlc3VsdCA9IHt9O1xuICAgIGNvbnN0IHdyYXBwZWRJRExheWVyTWFwID0ge307XG4gICAgZm9yIChjb25zdCB0aWxlIG9mIHRpbGVzKSB7XG4gICAgICAgIGNvbnN0IHF1ZXJ5UmVzdWx0cyA9IHRpbGUucXVlcnlSZXN1bHRzO1xuICAgICAgICBjb25zdCB3cmFwcGVkSUQgPSB0aWxlLndyYXBwZWRUaWxlSUQ7XG4gICAgICAgIGNvbnN0IHdyYXBwZWRJRExheWVycyA9IHdyYXBwZWRJRExheWVyTWFwW3dyYXBwZWRJRF0gPSB3cmFwcGVkSURMYXllck1hcFt3cmFwcGVkSURdIHx8IHt9O1xuICAgICAgICBmb3IgKGNvbnN0IGxheWVySUQgaW4gcXVlcnlSZXN1bHRzKSB7XG4gICAgICAgICAgICBjb25zdCB0aWxlRmVhdHVyZXMgPSBxdWVyeVJlc3VsdHNbbGF5ZXJJRF07XG4gICAgICAgICAgICBjb25zdCB3cmFwcGVkSURGZWF0dXJlcyA9IHdyYXBwZWRJRExheWVyc1tsYXllcklEXSA9IHdyYXBwZWRJRExheWVyc1tsYXllcklEXSB8fCB7fTtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdEZlYXR1cmVzID0gcmVzdWx0W2xheWVySURdID0gcmVzdWx0W2xheWVySURdIHx8IFtdO1xuICAgICAgICAgICAgZm9yIChjb25zdCB0aWxlRmVhdHVyZSBvZiB0aWxlRmVhdHVyZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXdyYXBwZWRJREZlYXR1cmVzW3RpbGVGZWF0dXJlLmZlYXR1cmVJbmRleF0pIHtcbiAgICAgICAgICAgICAgICAgICAgd3JhcHBlZElERmVhdHVyZXNbdGlsZUZlYXR1cmUuZmVhdHVyZUluZGV4XSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdEZlYXR1cmVzLnB1c2godGlsZUZlYXR1cmUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHdpbmRvdyBmcm9tICcuLi93aW5kb3cuanMnO1xuaW1wb3J0IG1hcGJveGdsIGZyb20gJy4uLy4uL2luZGV4LmpzJztcblxuaW1wb3J0IHR5cGUge1dvcmtlckludGVyZmFjZX0gZnJvbSAnLi4vd2ViX3dvcmtlci5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uICgpOiBXb3JrZXJJbnRlcmZhY2Uge1xuICAgIHJldHVybiAobWFwYm94Z2wud29ya2VyQ2xhc3MgIT0gbnVsbCkgPyBuZXcgbWFwYm94Z2wud29ya2VyQ2xhc3MoKSA6IChuZXcgd2luZG93LldvcmtlcihtYXBib3hnbC53b3JrZXJVcmwpOiBhbnkpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5ldy1jYXBcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBXZWJXb3JrZXIgZnJvbSAnLi93ZWJfd29ya2VyLmpzJztcbmltcG9ydCB0eXBlIHtXb3JrZXJJbnRlcmZhY2V9IGZyb20gJy4vd2ViX3dvcmtlci5qcyc7XG5cbmV4cG9ydCBjb25zdCBQUkVMT0FEX1BPT0xfSUQgPSAnbWFwYm94Z2xfcHJlbG9hZGVkX3dvcmtlcl9wb29sJztcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgd29ya2VyIHBvb2wuXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBXb3JrZXJQb29sIHtcbiAgICBzdGF0aWMgd29ya2VyQ291bnQ6IG51bWJlcjtcblxuICAgIGFjdGl2ZToge1tfOiBudW1iZXIgfCBzdHJpbmddOiBib29sZWFufTtcbiAgICB3b3JrZXJzOiBBcnJheTxXb3JrZXJJbnRlcmZhY2U+O1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuYWN0aXZlID0ge307XG4gICAgfVxuXG4gICAgYWNxdWlyZShtYXBJZDogbnVtYmVyIHwgc3RyaW5nKTogQXJyYXk8V29ya2VySW50ZXJmYWNlPiB7XG4gICAgICAgIGlmICghdGhpcy53b3JrZXJzKSB7XG4gICAgICAgICAgICAvLyBMYXppbHkgbG9vayB1cCB0aGUgdmFsdWUgb2YgbWFwYm94Z2wud29ya2VyQ291bnQgc28gdGhhdFxuICAgICAgICAgICAgLy8gY2xpZW50IGNvZGUgaGFzIGhhZCBhIGNoYW5jZSB0byBzZXQgaXQuXG4gICAgICAgICAgICB0aGlzLndvcmtlcnMgPSBbXTtcbiAgICAgICAgICAgIHdoaWxlICh0aGlzLndvcmtlcnMubGVuZ3RoIDwgV29ya2VyUG9vbC53b3JrZXJDb3VudCkge1xuICAgICAgICAgICAgICAgIC8vICRGbG93Rml4TWVbaW52YWxpZC1jb25zdHJ1Y3Rvcl1cbiAgICAgICAgICAgICAgICB0aGlzLndvcmtlcnMucHVzaChuZXcgV2ViV29ya2VyKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5hY3RpdmVbbWFwSWRdID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXMud29ya2Vycy5zbGljZSgpO1xuICAgIH1cblxuICAgIHJlbGVhc2UobWFwSWQ6IG51bWJlciB8IHN0cmluZykge1xuICAgICAgICBkZWxldGUgdGhpcy5hY3RpdmVbbWFwSWRdO1xuICAgICAgICBpZiAodGhpcy5udW1BY3RpdmUoKSA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy53b3JrZXJzLmZvckVhY2goKHcpID0+IHtcbiAgICAgICAgICAgICAgICB3LnRlcm1pbmF0ZSgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLndvcmtlcnMgPSAobnVsbDogYW55KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlzUHJlbG9hZGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gISF0aGlzLmFjdGl2ZVtQUkVMT0FEX1BPT0xfSURdO1xuICAgIH1cblxuICAgIG51bUFjdGl2ZSgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5hY3RpdmUpLmxlbmd0aDtcbiAgICB9XG59XG5cbi8vIGV4dGVuc2l2ZSBiZW5jaG1hcmtpbmcgc2hvd2VkIDIgdG8gYmUgdGhlIGJlc3QgZGVmYXVsdCBmb3IgYm90aCBkZXNrdG9wIGFuZCBtb2JpbGUgZGV2aWNlcztcbi8vIHdlIGNhbid0IHJlbHkgb24gaGFyZHdhcmVDb25jdXJyZW5jeSBiZWNhdXNlIG9mIHdpbGQgaW5jb25zaXN0ZW5jeSBvZiByZXBvcnRlZCBudW1iZXJzIGJldHdlZW4gYnJvd3NlcnNcbldvcmtlclBvb2wud29ya2VyQ291bnQgPSAyO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IFdvcmtlclBvb2wsIHtQUkVMT0FEX1BPT0xfSUR9IGZyb20gJy4vd29ya2VyX3Bvb2wuanMnO1xuXG5sZXQgZ2xvYmFsV29ya2VyUG9vbDogP1dvcmtlclBvb2w7XG5cbi8qKlxuICogQ3JlYXRlcyAoaWYgbmVjZXNzYXJ5KSBhbmQgcmV0dXJucyB0aGUgc2luZ2xlLCBnbG9iYWwgV29ya2VyUG9vbCBpbnN0YW5jZVxuICogdG8gYmUgc2hhcmVkIGFjcm9zcyBlYWNoIE1hcFxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0R2xvYmFsV29ya2VyUG9vbCAoKTogV29ya2VyUG9vbCB7XG4gICAgaWYgKCFnbG9iYWxXb3JrZXJQb29sKSB7XG4gICAgICAgIGdsb2JhbFdvcmtlclBvb2wgPSBuZXcgV29ya2VyUG9vbCgpO1xuICAgIH1cbiAgICByZXR1cm4gZ2xvYmFsV29ya2VyUG9vbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHByZXdhcm0oKSB7XG4gICAgY29uc3Qgd29ya2VyUG9vbCA9IGdldEdsb2JhbFdvcmtlclBvb2woKTtcbiAgICB3b3JrZXJQb29sLmFjcXVpcmUoUFJFTE9BRF9QT09MX0lEKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNsZWFyUHJld2FybWVkUmVzb3VyY2VzKCkge1xuICAgIGNvbnN0IHBvb2wgPSBnbG9iYWxXb3JrZXJQb29sO1xuICAgIGlmIChwb29sKSB7XG4gICAgICAgIC8vIFJlbW92ZSB0aGUgcG9vbCBvbmx5IGlmIGFsbCBtYXBzIHRoYXQgcmVmZXJlbmNlZCB0aGUgcHJlbG9hZGVkIGdsb2JhbCB3b3JrZXIgcG9vbCBoYXZlIGJlZW4gcmVtb3ZlZC5cbiAgICAgICAgaWYgKHBvb2wuaXNQcmVsb2FkZWQoKSAmJiBwb29sLm51bUFjdGl2ZSgpID09PSAxKSB7XG4gICAgICAgICAgICBwb29sLnJlbGVhc2UoUFJFTE9BRF9QT09MX0lEKTtcbiAgICAgICAgICAgIGdsb2JhbFdvcmtlclBvb2wgPSBudWxsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdDb3VsZCBub3QgY2xlYXIgV2ViV29ya2VycyBzaW5jZSB0aGVyZSBhcmUgYWN0aXZlIE1hcCBpbnN0YW5jZXMgdGhhdCBzdGlsbCByZWZlcmVuY2UgaXQuIFRoZSBwcmUtd2FybWVkIFdlYldvcmtlciBwb29sIGNhbiBvbmx5IGJlIGNsZWFyZWQgd2hlbiBhbGwgbWFwIGluc3RhbmNlcyBoYXZlIGJlZW4gcmVtb3ZlZCB3aXRoIG1hcC5yZW1vdmUoKScpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHJlZlByb3BlcnRpZXMgZnJvbSAnLi91dGlsL3JlZl9wcm9wZXJ0aWVzLmpzJztcblxuaW1wb3J0IHR5cGUge0xheWVyU3BlY2lmaWNhdGlvbn0gZnJvbSAnLi90eXBlcy5qcyc7XG5cbmZ1bmN0aW9uIGRlcmVmKGxheWVyOiBMYXllclNwZWNpZmljYXRpb24sIHBhcmVudDogTGF5ZXJTcGVjaWZpY2F0aW9uKTogTGF5ZXJTcGVjaWZpY2F0aW9uIHtcbiAgICBjb25zdCByZXN1bHQgPSB7fTtcblxuICAgIGZvciAoY29uc3QgayBpbiBsYXllcikge1xuICAgICAgICBpZiAoayAhPT0gJ3JlZicpIHtcbiAgICAgICAgICAgIHJlc3VsdFtrXSA9IGxheWVyW2tdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmVmUHJvcGVydGllcy5mb3JFYWNoKChrKSA9PiB7XG4gICAgICAgIGlmIChrIGluIHBhcmVudCkge1xuICAgICAgICAgICAgcmVzdWx0W2tdID0gKHBhcmVudDogYW55KVtrXTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuICgocmVzdWx0OiBhbnkpOiBMYXllclNwZWNpZmljYXRpb24pO1xufVxuXG4vKipcbiAqIEdpdmVuIGFuIGFycmF5IG9mIGxheWVycywgc29tZSBvZiB3aGljaCBtYXkgY29udGFpbiBgcmVmYCBwcm9wZXJ0aWVzXG4gKiB3aG9zZSB2YWx1ZSBpcyB0aGUgYGlkYCBvZiBhbm90aGVyIHByb3BlcnR5LCByZXR1cm4gYSBuZXcgYXJyYXkgd2hlcmVcbiAqIHN1Y2ggbGF5ZXJzIGhhdmUgYmVlbiBhdWdtZW50ZWQgd2l0aCB0aGUgJ3R5cGUnLCAnc291cmNlJywgZXRjLiBwcm9wZXJ0aWVzXG4gKiBmcm9tIHRoZSBwYXJlbnQgbGF5ZXIsIGFuZCB0aGUgYHJlZmAgcHJvcGVydHkgaGFzIGJlZW4gcmVtb3ZlZC5cbiAqXG4gKiBUaGUgaW5wdXQgaXMgbm90IG1vZGlmaWVkLiBUaGUgb3V0cHV0IG1heSBjb250YWluIHJlZmVyZW5jZXMgdG8gcG9ydGlvbnNcbiAqIG9mIHRoZSBpbnB1dC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheTxMYXllcj59IGxheWVyc1xuICogQHJldHVybnMge0FycmF5PExheWVyPn1cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZGVyZWZMYXllcnMobGF5ZXJzOiBBcnJheTxMYXllclNwZWNpZmljYXRpb24+KTogQXJyYXk8TGF5ZXJTcGVjaWZpY2F0aW9uPiB7XG4gICAgbGF5ZXJzID0gbGF5ZXJzLnNsaWNlKCk7XG5cbiAgICBjb25zdCBtYXA6IE9iamVjdCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsYXllcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbWFwW2xheWVyc1tpXS5pZF0gPSBsYXllcnNbaV07XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsYXllcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKCdyZWYnIGluIGxheWVyc1tpXSkge1xuICAgICAgICAgICAgbGF5ZXJzW2ldID0gZGVyZWYobGF5ZXJzW2ldLCBtYXBbKGxheWVyc1tpXTogYW55KS5yZWZdKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBsYXllcnM7XG59XG4iLCIvLyBAZmxvd1xuaW1wb3J0IHR5cGUge1N0eWxlU3BlY2lmaWNhdGlvbn0gZnJvbSAnLi90eXBlcy5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGVtcHR5U3R5bGUoKTogU3R5bGVTcGVjaWZpY2F0aW9uIHtcbiAgICByZXR1cm4ge1xuICAgICAgICB2ZXJzaW9uOiA4LFxuICAgICAgICBsYXllcnM6IFtdLFxuICAgICAgICBzb3VyY2VzOiB7fVxuICAgIH07XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgaXNFcXVhbCBmcm9tICcuL3V0aWwvZGVlcF9lcXVhbC5qcyc7XG5cbmltcG9ydCB0eXBlIHtTdHlsZVNwZWNpZmljYXRpb24sIFNvdXJjZVNwZWNpZmljYXRpb24sIExheWVyU3BlY2lmaWNhdGlvbn0gZnJvbSAnLi90eXBlcy5qcyc7XG5cbnR5cGUgU291cmNlcyA9IHsgW3N0cmluZ106IFNvdXJjZVNwZWNpZmljYXRpb24gfTtcblxudHlwZSBDb21tYW5kID0ge1xuICAgIGNvbW1hbmQ6IHN0cmluZztcbiAgICBhcmdzOiBBcnJheTxhbnk+O1xufTtcblxuZXhwb3J0IGNvbnN0IG9wZXJhdGlvbnM6IHtbXzogc3RyaW5nXTogc3RyaW5nfSA9IHtcblxuICAgIC8qXG4gICAgICogeyBjb21tYW5kOiAnc2V0U3R5bGUnLCBhcmdzOiBbc3R5bGVzaGVldF0gfVxuICAgICAqL1xuICAgIHNldFN0eWxlOiAnc2V0U3R5bGUnLFxuXG4gICAgLypcbiAgICAgKiB7IGNvbW1hbmQ6ICdhZGRMYXllcicsIGFyZ3M6IFtsYXllciwgJ2JlZm9yZUxheWVySWQnXSB9XG4gICAgICovXG4gICAgYWRkTGF5ZXI6ICdhZGRMYXllcicsXG5cbiAgICAvKlxuICAgICAqIHsgY29tbWFuZDogJ3JlbW92ZUxheWVyJywgYXJnczogWydsYXllcklkJ10gfVxuICAgICAqL1xuICAgIHJlbW92ZUxheWVyOiAncmVtb3ZlTGF5ZXInLFxuXG4gICAgLypcbiAgICAgKiB7IGNvbW1hbmQ6ICdzZXRQYWludFByb3BlcnR5JywgYXJnczogWydsYXllcklkJywgJ3Byb3AnLCB2YWx1ZV0gfVxuICAgICAqL1xuICAgIHNldFBhaW50UHJvcGVydHk6ICdzZXRQYWludFByb3BlcnR5JyxcblxuICAgIC8qXG4gICAgICogeyBjb21tYW5kOiAnc2V0TGF5b3V0UHJvcGVydHknLCBhcmdzOiBbJ2xheWVySWQnLCAncHJvcCcsIHZhbHVlXSB9XG4gICAgICovXG4gICAgc2V0TGF5b3V0UHJvcGVydHk6ICdzZXRMYXlvdXRQcm9wZXJ0eScsXG5cbiAgICAvKlxuICAgICAqIHsgY29tbWFuZDogJ3NldEZpbHRlcicsIGFyZ3M6IFsnbGF5ZXJJZCcsIGZpbHRlcl0gfVxuICAgICAqL1xuICAgIHNldEZpbHRlcjogJ3NldEZpbHRlcicsXG5cbiAgICAvKlxuICAgICAqIHsgY29tbWFuZDogJ2FkZFNvdXJjZScsIGFyZ3M6IFsnc291cmNlSWQnLCBzb3VyY2VdIH1cbiAgICAgKi9cbiAgICBhZGRTb3VyY2U6ICdhZGRTb3VyY2UnLFxuXG4gICAgLypcbiAgICAgKiB7IGNvbW1hbmQ6ICdyZW1vdmVTb3VyY2UnLCBhcmdzOiBbJ3NvdXJjZUlkJ10gfVxuICAgICAqL1xuICAgIHJlbW92ZVNvdXJjZTogJ3JlbW92ZVNvdXJjZScsXG5cbiAgICAvKlxuICAgICAqIHsgY29tbWFuZDogJ3NldEdlb0pTT05Tb3VyY2VEYXRhJywgYXJnczogWydzb3VyY2VJZCcsIGRhdGFdIH1cbiAgICAgKi9cbiAgICBzZXRHZW9KU09OU291cmNlRGF0YTogJ3NldEdlb0pTT05Tb3VyY2VEYXRhJyxcblxuICAgIC8qXG4gICAgICogeyBjb21tYW5kOiAnc2V0TGF5ZXJab29tUmFuZ2UnLCBhcmdzOiBbJ2xheWVySWQnLCAwLCAyMl0gfVxuICAgICAqL1xuICAgIHNldExheWVyWm9vbVJhbmdlOiAnc2V0TGF5ZXJab29tUmFuZ2UnLFxuXG4gICAgLypcbiAgICAgKiB7IGNvbW1hbmQ6ICdzZXRMYXllclByb3BlcnR5JywgYXJnczogWydsYXllcklkJywgJ3Byb3AnLCB2YWx1ZV0gfVxuICAgICAqL1xuICAgIHNldExheWVyUHJvcGVydHk6ICdzZXRMYXllclByb3BlcnR5JyxcblxuICAgIC8qXG4gICAgICogeyBjb21tYW5kOiAnc2V0Q2VudGVyJywgYXJnczogW1tsb24sIGxhdF1dIH1cbiAgICAgKi9cbiAgICBzZXRDZW50ZXI6ICdzZXRDZW50ZXInLFxuXG4gICAgLypcbiAgICAgKiB7IGNvbW1hbmQ6ICdzZXRab29tJywgYXJnczogW3pvb21dIH1cbiAgICAgKi9cbiAgICBzZXRab29tOiAnc2V0Wm9vbScsXG5cbiAgICAvKlxuICAgICAqIHsgY29tbWFuZDogJ3NldEJlYXJpbmcnLCBhcmdzOiBbYmVhcmluZ10gfVxuICAgICAqL1xuICAgIHNldEJlYXJpbmc6ICdzZXRCZWFyaW5nJyxcblxuICAgIC8qXG4gICAgICogeyBjb21tYW5kOiAnc2V0UGl0Y2gnLCBhcmdzOiBbcGl0Y2hdIH1cbiAgICAgKi9cbiAgICBzZXRQaXRjaDogJ3NldFBpdGNoJyxcblxuICAgIC8qXG4gICAgICogeyBjb21tYW5kOiAnc2V0U3ByaXRlJywgYXJnczogWydzcHJpdGVVcmwnXSB9XG4gICAgICovXG4gICAgc2V0U3ByaXRlOiAnc2V0U3ByaXRlJyxcblxuICAgIC8qXG4gICAgICogeyBjb21tYW5kOiAnc2V0R2x5cGhzJywgYXJnczogWydnbHlwaHNVcmwnXSB9XG4gICAgICovXG4gICAgc2V0R2x5cGhzOiAnc2V0R2x5cGhzJyxcblxuICAgIC8qXG4gICAgICogeyBjb21tYW5kOiAnc2V0VHJhbnNpdGlvbicsIGFyZ3M6IFt0cmFuc2l0aW9uXSB9XG4gICAgICovXG4gICAgc2V0VHJhbnNpdGlvbjogJ3NldFRyYW5zaXRpb24nLFxuXG4gICAgLypcbiAgICAgKiB7IGNvbW1hbmQ6ICdzZXRMaWdodGluZycsIGFyZ3M6IFtsaWdodFByb3BlcnRpZXNdIH1cbiAgICAgKi9cbiAgICBzZXRMaWdodDogJ3NldExpZ2h0JyxcblxuICAgIC8qXG4gICAgICogeyBjb21tYW5kOiAnc2V0VGVycmFpbicsIGFyZ3M6IFt0ZXJyYWluUHJvcGVydGllc10gfVxuICAgICAqL1xuICAgIHNldFRlcnJhaW46ICdzZXRUZXJyYWluJyxcblxuICAgIC8qXG4gICAgICogIHsgY29tbWFuZDogJ3NldEZvZycsIGFyZ3M6IFtmb2dQcm9wZXJ0aWVzXSB9XG4gICAgICovXG4gICAgc2V0Rm9nOiAnc2V0Rm9nJyxcblxuICAgIC8qXG4gICAgICogIHsgY29tbWFuZDogJ3NldFByb2plY3Rpb24nLCBhcmdzOiBbcHJvamVjdGlvblByb3BlcnRpZXNdIH1cbiAgICAgKi9cbiAgICBzZXRQcm9qZWN0aW9uOiAnc2V0UHJvamVjdGlvbidcbn07XG5cbmZ1bmN0aW9uIGFkZFNvdXJjZShzb3VyY2VJZDogc3RyaW5nLCBhZnRlcjogU291cmNlcywgY29tbWFuZHM6IEFycmF5PENvbW1hbmQ+KSB7XG4gICAgY29tbWFuZHMucHVzaCh7Y29tbWFuZDogb3BlcmF0aW9ucy5hZGRTb3VyY2UsIGFyZ3M6IFtzb3VyY2VJZCwgYWZ0ZXJbc291cmNlSWRdXX0pO1xufVxuXG5mdW5jdGlvbiByZW1vdmVTb3VyY2Uoc291cmNlSWQ6IHN0cmluZywgY29tbWFuZHM6IEFycmF5PENvbW1hbmQ+LCBzb3VyY2VzUmVtb3ZlZDoge1tzdHJpbmddOiB0cnVlfSkge1xuICAgIGNvbW1hbmRzLnB1c2goe2NvbW1hbmQ6IG9wZXJhdGlvbnMucmVtb3ZlU291cmNlLCBhcmdzOiBbc291cmNlSWRdfSk7XG4gICAgc291cmNlc1JlbW92ZWRbc291cmNlSWRdID0gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlU291cmNlKHNvdXJjZUlkOiBzdHJpbmcsIGFmdGVyOiBTb3VyY2VzLCBjb21tYW5kczogQXJyYXk8Q29tbWFuZD4sIHNvdXJjZXNSZW1vdmVkOiB7W3N0cmluZ106IHRydWV9KSB7XG4gICAgcmVtb3ZlU291cmNlKHNvdXJjZUlkLCBjb21tYW5kcywgc291cmNlc1JlbW92ZWQpO1xuICAgIGFkZFNvdXJjZShzb3VyY2VJZCwgYWZ0ZXIsIGNvbW1hbmRzKTtcbn1cblxuZnVuY3Rpb24gY2FuVXBkYXRlR2VvSlNPTihiZWZvcmU6IFNvdXJjZXMsIGFmdGVyOiBTb3VyY2VzLCBzb3VyY2VJZDogc3RyaW5nKSB7XG4gICAgbGV0IHByb3A7XG4gICAgZm9yIChwcm9wIGluIGJlZm9yZVtzb3VyY2VJZF0pIHtcbiAgICAgICAgaWYgKCFiZWZvcmVbc291cmNlSWRdLmhhc093blByb3BlcnR5KHByb3ApKSBjb250aW51ZTtcbiAgICAgICAgaWYgKHByb3AgIT09ICdkYXRhJyAmJiAhaXNFcXVhbChiZWZvcmVbc291cmNlSWRdW3Byb3BdLCBhZnRlcltzb3VyY2VJZF1bcHJvcF0pKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZm9yIChwcm9wIGluIGFmdGVyW3NvdXJjZUlkXSkge1xuICAgICAgICBpZiAoIWFmdGVyW3NvdXJjZUlkXS5oYXNPd25Qcm9wZXJ0eShwcm9wKSkgY29udGludWU7XG4gICAgICAgIGlmIChwcm9wICE9PSAnZGF0YScgJiYgIWlzRXF1YWwoYmVmb3JlW3NvdXJjZUlkXVtwcm9wXSwgYWZ0ZXJbc291cmNlSWRdW3Byb3BdKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBkaWZmU291cmNlcyhiZWZvcmU6IFNvdXJjZXMsIGFmdGVyOiBTb3VyY2VzLCBjb21tYW5kczogQXJyYXk8Q29tbWFuZD4sIHNvdXJjZXNSZW1vdmVkOiB7W3N0cmluZ106IHRydWV9KSB7XG4gICAgYmVmb3JlID0gYmVmb3JlIHx8IHt9O1xuICAgIGFmdGVyID0gYWZ0ZXIgfHwge307XG5cbiAgICBsZXQgc291cmNlSWQ7XG5cbiAgICAvLyBsb29rIGZvciBzb3VyY2VzIHRvIHJlbW92ZVxuICAgIGZvciAoc291cmNlSWQgaW4gYmVmb3JlKSB7XG4gICAgICAgIGlmICghYmVmb3JlLmhhc093blByb3BlcnR5KHNvdXJjZUlkKSkgY29udGludWU7XG4gICAgICAgIGlmICghYWZ0ZXIuaGFzT3duUHJvcGVydHkoc291cmNlSWQpKSB7XG4gICAgICAgICAgICByZW1vdmVTb3VyY2Uoc291cmNlSWQsIGNvbW1hbmRzLCBzb3VyY2VzUmVtb3ZlZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBsb29rIGZvciBzb3VyY2VzIHRvIGFkZC91cGRhdGVcbiAgICBmb3IgKHNvdXJjZUlkIGluIGFmdGVyKSB7XG4gICAgICAgIGlmICghYWZ0ZXIuaGFzT3duUHJvcGVydHkoc291cmNlSWQpKSBjb250aW51ZTtcbiAgICAgICAgY29uc3Qgc291cmNlID0gYWZ0ZXJbc291cmNlSWRdO1xuICAgICAgICBpZiAoIWJlZm9yZS5oYXNPd25Qcm9wZXJ0eShzb3VyY2VJZCkpIHtcbiAgICAgICAgICAgIGFkZFNvdXJjZShzb3VyY2VJZCwgYWZ0ZXIsIGNvbW1hbmRzKTtcbiAgICAgICAgfSBlbHNlIGlmICghaXNFcXVhbChiZWZvcmVbc291cmNlSWRdLCBzb3VyY2UpKSB7XG4gICAgICAgICAgICBpZiAoYmVmb3JlW3NvdXJjZUlkXS50eXBlID09PSAnZ2VvanNvbicgJiYgc291cmNlLnR5cGUgPT09ICdnZW9qc29uJyAmJiBjYW5VcGRhdGVHZW9KU09OKGJlZm9yZSwgYWZ0ZXIsIHNvdXJjZUlkKSkge1xuICAgICAgICAgICAgICAgIGNvbW1hbmRzLnB1c2goe2NvbW1hbmQ6IG9wZXJhdGlvbnMuc2V0R2VvSlNPTlNvdXJjZURhdGEsIGFyZ3M6IFtzb3VyY2VJZCwgc291cmNlLmRhdGFdfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIG5vIHVwZGF0ZSBjb21tYW5kLCBtdXN0IHJlbW92ZSB0aGVuIGFkZFxuICAgICAgICAgICAgICAgIHVwZGF0ZVNvdXJjZShzb3VyY2VJZCwgYWZ0ZXIsIGNvbW1hbmRzLCBzb3VyY2VzUmVtb3ZlZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRpZmZMYXllclByb3BlcnR5Q2hhbmdlcyhiZWZvcmU6IGFueSwgYWZ0ZXI6IGFueSwgY29tbWFuZHM6IEFycmF5PENvbW1hbmQ+LCBsYXllcklkOiBzdHJpbmcsIGtsYXNzOiA/c3RyaW5nLCBjb21tYW5kOiBzdHJpbmcpIHtcbiAgICBiZWZvcmUgPSBiZWZvcmUgfHwge307XG4gICAgYWZ0ZXIgPSBhZnRlciB8fCB7fTtcblxuICAgIGxldCBwcm9wO1xuXG4gICAgZm9yIChwcm9wIGluIGJlZm9yZSkge1xuICAgICAgICBpZiAoIWJlZm9yZS5oYXNPd25Qcm9wZXJ0eShwcm9wKSkgY29udGludWU7XG4gICAgICAgIGlmICghaXNFcXVhbChiZWZvcmVbcHJvcF0sIGFmdGVyW3Byb3BdKSkge1xuICAgICAgICAgICAgY29tbWFuZHMucHVzaCh7Y29tbWFuZCwgYXJnczogW2xheWVySWQsIHByb3AsIGFmdGVyW3Byb3BdLCBrbGFzc119KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBmb3IgKHByb3AgaW4gYWZ0ZXIpIHtcbiAgICAgICAgaWYgKCFhZnRlci5oYXNPd25Qcm9wZXJ0eShwcm9wKSB8fCBiZWZvcmUuaGFzT3duUHJvcGVydHkocHJvcCkpIGNvbnRpbnVlO1xuICAgICAgICBpZiAoIWlzRXF1YWwoYmVmb3JlW3Byb3BdLCBhZnRlcltwcm9wXSkpIHtcbiAgICAgICAgICAgIGNvbW1hbmRzLnB1c2goe2NvbW1hbmQsIGFyZ3M6IFtsYXllcklkLCBwcm9wLCBhZnRlcltwcm9wXSwga2xhc3NdfSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIHBsdWNrSWQobGF5ZXI6IExheWVyU3BlY2lmaWNhdGlvbikge1xuICAgIHJldHVybiBsYXllci5pZDtcbn1cblxuZnVuY3Rpb24gaW5kZXhCeUlkKGdyb3VwOiB7W3N0cmluZ106IExheWVyU3BlY2lmaWNhdGlvbn0sIGxheWVyOiBMYXllclNwZWNpZmljYXRpb24pIHtcbiAgICBncm91cFtsYXllci5pZF0gPSBsYXllcjtcbiAgICByZXR1cm4gZ3JvdXA7XG59XG5cbmZ1bmN0aW9uIGRpZmZMYXllcnMoYmVmb3JlOiBBcnJheTxMYXllclNwZWNpZmljYXRpb24+LCBhZnRlcjogQXJyYXk8TGF5ZXJTcGVjaWZpY2F0aW9uPiwgY29tbWFuZHM6IEFycmF5PENvbW1hbmQ+KSB7XG4gICAgYmVmb3JlID0gYmVmb3JlIHx8IFtdO1xuICAgIGFmdGVyID0gYWZ0ZXIgfHwgW107XG5cbiAgICAvLyBvcmRlciBvZiBsYXllcnMgYnkgaWRcbiAgICBjb25zdCBiZWZvcmVPcmRlciA9IGJlZm9yZS5tYXAocGx1Y2tJZCk7XG4gICAgY29uc3QgYWZ0ZXJPcmRlciA9IGFmdGVyLm1hcChwbHVja0lkKTtcblxuICAgIC8vIGluZGV4IG9mIGxheWVyIGJ5IGlkXG4gICAgY29uc3QgYmVmb3JlSW5kZXggPSBiZWZvcmUucmVkdWNlKGluZGV4QnlJZCwge30pO1xuICAgIGNvbnN0IGFmdGVySW5kZXggPSBhZnRlci5yZWR1Y2UoaW5kZXhCeUlkLCB7fSk7XG5cbiAgICAvLyB0cmFjayBvcmRlciBvZiBsYXllcnMgYXMgaWYgdGhleSBoYXZlIGJlZW4gbXV0YXRlZFxuICAgIGNvbnN0IHRyYWNrZXIgPSBiZWZvcmVPcmRlci5zbGljZSgpO1xuXG4gICAgLy8gbGF5ZXJzIHRoYXQgaGF2ZSBiZWVuIGFkZGVkIGRvIG5vdCBuZWVkIHRvIGJlIGRpZmZlZFxuICAgIGNvbnN0IGNsZWFuOiBPYmplY3QgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXG4gICAgbGV0IGksIGQsIGxheWVySWQsIGJlZm9yZUxheWVyOiBMYXllclNwZWNpZmljYXRpb24sIGFmdGVyTGF5ZXI6IExheWVyU3BlY2lmaWNhdGlvbiwgaW5zZXJ0QmVmb3JlTGF5ZXJJZCwgcHJvcDtcblxuICAgIC8vIHJlbW92ZSBsYXllcnNcbiAgICBmb3IgKGkgPSAwLCBkID0gMDsgaSA8IGJlZm9yZU9yZGVyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxheWVySWQgPSBiZWZvcmVPcmRlcltpXTtcbiAgICAgICAgaWYgKCFhZnRlckluZGV4Lmhhc093blByb3BlcnR5KGxheWVySWQpKSB7XG4gICAgICAgICAgICBjb21tYW5kcy5wdXNoKHtjb21tYW5kOiBvcGVyYXRpb25zLnJlbW92ZUxheWVyLCBhcmdzOiBbbGF5ZXJJZF19KTtcbiAgICAgICAgICAgIHRyYWNrZXIuc3BsaWNlKHRyYWNrZXIuaW5kZXhPZihsYXllcklkLCBkKSwgMSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBsaW1pdCB3aGVyZSBpbiB0cmFja2VyIHdlIG5lZWQgdG8gbG9vayBmb3IgYSBtYXRjaFxuICAgICAgICAgICAgZCsrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gYWRkL3Jlb3JkZXIgbGF5ZXJzXG4gICAgZm9yIChpID0gMCwgZCA9IDA7IGkgPCBhZnRlck9yZGVyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIC8vIHdvcmsgYmFja3dhcmRzIGFzIGluc2VydCBpcyBiZWZvcmUgYW4gZXhpc3RpbmcgbGF5ZXJcbiAgICAgICAgbGF5ZXJJZCA9IGFmdGVyT3JkZXJbYWZ0ZXJPcmRlci5sZW5ndGggLSAxIC0gaV07XG5cbiAgICAgICAgaWYgKHRyYWNrZXJbdHJhY2tlci5sZW5ndGggLSAxIC0gaV0gPT09IGxheWVySWQpIGNvbnRpbnVlO1xuXG4gICAgICAgIGlmIChiZWZvcmVJbmRleC5oYXNPd25Qcm9wZXJ0eShsYXllcklkKSkge1xuICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBsYXllciBiZWZvcmUgd2UgaW5zZXJ0IGF0IHRoZSBjb3JyZWN0IHBvc2l0aW9uXG4gICAgICAgICAgICBjb21tYW5kcy5wdXNoKHtjb21tYW5kOiBvcGVyYXRpb25zLnJlbW92ZUxheWVyLCBhcmdzOiBbbGF5ZXJJZF19KTtcbiAgICAgICAgICAgIHRyYWNrZXIuc3BsaWNlKHRyYWNrZXIubGFzdEluZGV4T2YobGF5ZXJJZCwgdHJhY2tlci5sZW5ndGggLSBkKSwgMSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBsaW1pdCB3aGVyZSBpbiB0cmFja2VyIHdlIG5lZWQgdG8gbG9vayBmb3IgYSBtYXRjaFxuICAgICAgICAgICAgZCsrO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gYWRkIGxheWVyIGF0IGNvcnJlY3QgcG9zaXRpb25cbiAgICAgICAgaW5zZXJ0QmVmb3JlTGF5ZXJJZCA9IHRyYWNrZXJbdHJhY2tlci5sZW5ndGggLSBpXTtcbiAgICAgICAgY29tbWFuZHMucHVzaCh7Y29tbWFuZDogb3BlcmF0aW9ucy5hZGRMYXllciwgYXJnczogW2FmdGVySW5kZXhbbGF5ZXJJZF0sIGluc2VydEJlZm9yZUxheWVySWRdfSk7XG4gICAgICAgIHRyYWNrZXIuc3BsaWNlKHRyYWNrZXIubGVuZ3RoIC0gaSwgMCwgbGF5ZXJJZCk7XG4gICAgICAgIGNsZWFuW2xheWVySWRdID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyB1cGRhdGUgbGF5ZXJzXG4gICAgZm9yIChpID0gMDsgaSA8IGFmdGVyT3JkZXIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbGF5ZXJJZCA9IGFmdGVyT3JkZXJbaV07XG4gICAgICAgIGJlZm9yZUxheWVyID0gYmVmb3JlSW5kZXhbbGF5ZXJJZF07XG4gICAgICAgIGFmdGVyTGF5ZXIgPSBhZnRlckluZGV4W2xheWVySWRdO1xuXG4gICAgICAgIC8vIG5vIG5lZWQgdG8gdXBkYXRlIGlmIHByZXZpb3VzbHkgYWRkZWQgKG5ldyBvciBtb3ZlZClcbiAgICAgICAgaWYgKGNsZWFuW2xheWVySWRdIHx8IGlzRXF1YWwoYmVmb3JlTGF5ZXIsIGFmdGVyTGF5ZXIpKSBjb250aW51ZTtcblxuICAgICAgICAvLyBJZiBzb3VyY2UsIHNvdXJjZS1sYXllciwgb3IgdHlwZSBoYXZlIGNoYW5nZXMsIHRoZW4gcmVtb3ZlIHRoZSBsYXllclxuICAgICAgICAvLyBhbmQgYWRkIGl0IGJhY2sgJ2Zyb20gc2NyYXRjaCcuXG4gICAgICAgIC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXSAtIHRoZXJlIGlzIG5vIGBzb3VyY2UtbGF5ZXJgIGluIGJhY2tncm91bmQgYW5kIHNreSBsYXllcnNcbiAgICAgICAgaWYgKCFpc0VxdWFsKGJlZm9yZUxheWVyLnNvdXJjZSwgYWZ0ZXJMYXllci5zb3VyY2UpIHx8ICFpc0VxdWFsKGJlZm9yZUxheWVyWydzb3VyY2UtbGF5ZXInXSwgYWZ0ZXJMYXllclsnc291cmNlLWxheWVyJ10pIHx8ICFpc0VxdWFsKGJlZm9yZUxheWVyLnR5cGUsIGFmdGVyTGF5ZXIudHlwZSkpIHtcbiAgICAgICAgICAgIGNvbW1hbmRzLnB1c2goe2NvbW1hbmQ6IG9wZXJhdGlvbnMucmVtb3ZlTGF5ZXIsIGFyZ3M6IFtsYXllcklkXX0pO1xuICAgICAgICAgICAgLy8gd2UgYWRkIHRoZSBsYXllciBiYWNrIGF0IHRoZSBzYW1lIHBvc2l0aW9uIGl0IHdhcyBhbHJlYWR5IGluLCBzb1xuICAgICAgICAgICAgLy8gdGhlcmUncyBubyBuZWVkIHRvIHVwZGF0ZSB0aGUgYHRyYWNrZXJgXG4gICAgICAgICAgICBpbnNlcnRCZWZvcmVMYXllcklkID0gdHJhY2tlclt0cmFja2VyLmxhc3RJbmRleE9mKGxheWVySWQpICsgMV07XG4gICAgICAgICAgICBjb21tYW5kcy5wdXNoKHtjb21tYW5kOiBvcGVyYXRpb25zLmFkZExheWVyLCBhcmdzOiBbYWZ0ZXJMYXllciwgaW5zZXJ0QmVmb3JlTGF5ZXJJZF19KTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gbGF5b3V0LCBwYWludCwgZmlsdGVyLCBtaW56b29tLCBtYXh6b29tXG4gICAgICAgIGRpZmZMYXllclByb3BlcnR5Q2hhbmdlcyhiZWZvcmVMYXllci5sYXlvdXQsIGFmdGVyTGF5ZXIubGF5b3V0LCBjb21tYW5kcywgbGF5ZXJJZCwgbnVsbCwgb3BlcmF0aW9ucy5zZXRMYXlvdXRQcm9wZXJ0eSk7XG4gICAgICAgIGRpZmZMYXllclByb3BlcnR5Q2hhbmdlcyhiZWZvcmVMYXllci5wYWludCwgYWZ0ZXJMYXllci5wYWludCwgY29tbWFuZHMsIGxheWVySWQsIG51bGwsIG9wZXJhdGlvbnMuc2V0UGFpbnRQcm9wZXJ0eSk7XG4gICAgICAgIGlmICghaXNFcXVhbChiZWZvcmVMYXllci5maWx0ZXIsIGFmdGVyTGF5ZXIuZmlsdGVyKSkge1xuICAgICAgICAgICAgY29tbWFuZHMucHVzaCh7Y29tbWFuZDogb3BlcmF0aW9ucy5zZXRGaWx0ZXIsIGFyZ3M6IFtsYXllcklkLCBhZnRlckxheWVyLmZpbHRlcl19KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzRXF1YWwoYmVmb3JlTGF5ZXIubWluem9vbSwgYWZ0ZXJMYXllci5taW56b29tKSB8fCAhaXNFcXVhbChiZWZvcmVMYXllci5tYXh6b29tLCBhZnRlckxheWVyLm1heHpvb20pKSB7XG4gICAgICAgICAgICBjb21tYW5kcy5wdXNoKHtjb21tYW5kOiBvcGVyYXRpb25zLnNldExheWVyWm9vbVJhbmdlLCBhcmdzOiBbbGF5ZXJJZCwgYWZ0ZXJMYXllci5taW56b29tLCBhZnRlckxheWVyLm1heHpvb21dfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBoYW5kbGUgYWxsIG90aGVyIGxheWVyIHByb3BzLCBpbmNsdWRpbmcgcGFpbnQuKlxuICAgICAgICBmb3IgKHByb3AgaW4gYmVmb3JlTGF5ZXIpIHtcbiAgICAgICAgICAgIGlmICghYmVmb3JlTGF5ZXIuaGFzT3duUHJvcGVydHkocHJvcCkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKHByb3AgPT09ICdsYXlvdXQnIHx8IHByb3AgPT09ICdwYWludCcgfHwgcHJvcCA9PT0gJ2ZpbHRlcicgfHxcbiAgICAgICAgICAgICAgICBwcm9wID09PSAnbWV0YWRhdGEnIHx8IHByb3AgPT09ICdtaW56b29tJyB8fCBwcm9wID09PSAnbWF4em9vbScpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKHByb3AuaW5kZXhPZigncGFpbnQuJykgPT09IDApIHtcbiAgICAgICAgICAgICAgICBkaWZmTGF5ZXJQcm9wZXJ0eUNoYW5nZXMoYmVmb3JlTGF5ZXJbcHJvcF0sIGFmdGVyTGF5ZXJbcHJvcF0sIGNvbW1hbmRzLCBsYXllcklkLCBwcm9wLnNsaWNlKDYpLCBvcGVyYXRpb25zLnNldFBhaW50UHJvcGVydHkpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICghaXNFcXVhbChiZWZvcmVMYXllcltwcm9wXSwgYWZ0ZXJMYXllcltwcm9wXSkpIHtcbiAgICAgICAgICAgICAgICBjb21tYW5kcy5wdXNoKHtjb21tYW5kOiBvcGVyYXRpb25zLnNldExheWVyUHJvcGVydHksIGFyZ3M6IFtsYXllcklkLCBwcm9wLCBhZnRlckxheWVyW3Byb3BdXX0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZvciAocHJvcCBpbiBhZnRlckxheWVyKSB7XG4gICAgICAgICAgICBpZiAoIWFmdGVyTGF5ZXIuaGFzT3duUHJvcGVydHkocHJvcCkgfHwgYmVmb3JlTGF5ZXIuaGFzT3duUHJvcGVydHkocHJvcCkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKHByb3AgPT09ICdsYXlvdXQnIHx8IHByb3AgPT09ICdwYWludCcgfHwgcHJvcCA9PT0gJ2ZpbHRlcicgfHxcbiAgICAgICAgICAgICAgICBwcm9wID09PSAnbWV0YWRhdGEnIHx8IHByb3AgPT09ICdtaW56b29tJyB8fCBwcm9wID09PSAnbWF4em9vbScpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKHByb3AuaW5kZXhPZigncGFpbnQuJykgPT09IDApIHtcbiAgICAgICAgICAgICAgICBkaWZmTGF5ZXJQcm9wZXJ0eUNoYW5nZXMoYmVmb3JlTGF5ZXJbcHJvcF0sIGFmdGVyTGF5ZXJbcHJvcF0sIGNvbW1hbmRzLCBsYXllcklkLCBwcm9wLnNsaWNlKDYpLCBvcGVyYXRpb25zLnNldFBhaW50UHJvcGVydHkpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICghaXNFcXVhbChiZWZvcmVMYXllcltwcm9wXSwgYWZ0ZXJMYXllcltwcm9wXSkpIHtcbiAgICAgICAgICAgICAgICBjb21tYW5kcy5wdXNoKHtjb21tYW5kOiBvcGVyYXRpb25zLnNldExheWVyUHJvcGVydHksIGFyZ3M6IFtsYXllcklkLCBwcm9wLCBhZnRlckxheWVyW3Byb3BdXX0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG4vKipcbiAqIERpZmYgdHdvIHN0eWxlc2hlZXRcbiAqXG4gKiBDcmVhdGVzIHNlbWFudGljbHkgYXdhcmUgZGlmZnMgdGhhdCBjYW4gZWFzaWx5IGJlIGFwcGxpZWQgYXQgcnVudGltZS5cbiAqIE9wZXJhdGlvbnMgcHJvZHVjZWQgYnkgdGhlIGRpZmYgY2xvc2VseSByZXNlbWJsZSB0aGUgbWFwYm94LWdsLWpzIEFQSS4gQW55XG4gKiBlcnJvciBjcmVhdGluZyB0aGUgZGlmZiB3aWxsIGZhbGwgYmFjayB0byB0aGUgJ3NldFN0eWxlJyBvcGVyYXRpb24uXG4gKlxuICogRXhhbXBsZSBkaWZmOlxuICogW1xuICogICAgIHsgY29tbWFuZDogJ3NldENvbnN0YW50JywgYXJnczogWydAd2F0ZXInLCAnIzAwMDBGRiddIH0sXG4gKiAgICAgeyBjb21tYW5kOiAnc2V0UGFpbnRQcm9wZXJ0eScsIGFyZ3M6IFsnYmFja2dyb3VuZCcsICdiYWNrZ3JvdW5kLWNvbG9yJywgJ2JsYWNrJ10gfVxuICogXVxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IFtiZWZvcmVdIHN0eWxlc2hlZXQgdG8gY29tcGFyZSBmcm9tXG4gKiBAcGFyYW0geyp9IGFmdGVyIHN0eWxlc2hlZXQgdG8gY29tcGFyZSB0b1xuICogQHJldHVybnMgQXJyYXkgbGlzdCBvZiBjaGFuZ2VzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGRpZmZTdHlsZXMoYmVmb3JlOiBTdHlsZVNwZWNpZmljYXRpb24sIGFmdGVyOiBTdHlsZVNwZWNpZmljYXRpb24pOiBBcnJheTxDb21tYW5kPiB7XG4gICAgaWYgKCFiZWZvcmUpIHJldHVybiBbe2NvbW1hbmQ6IG9wZXJhdGlvbnMuc2V0U3R5bGUsIGFyZ3M6IFthZnRlcl19XTtcblxuICAgIGxldCBjb21tYW5kcyA9IFtdO1xuXG4gICAgdHJ5IHtcbiAgICAgICAgLy8gSGFuZGxlIGNoYW5nZXMgdG8gdG9wLWxldmVsIHByb3BlcnRpZXNcbiAgICAgICAgaWYgKCFpc0VxdWFsKGJlZm9yZS52ZXJzaW9uLCBhZnRlci52ZXJzaW9uKSkge1xuICAgICAgICAgICAgcmV0dXJuIFt7Y29tbWFuZDogb3BlcmF0aW9ucy5zZXRTdHlsZSwgYXJnczogW2FmdGVyXX1dO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNFcXVhbChiZWZvcmUuY2VudGVyLCBhZnRlci5jZW50ZXIpKSB7XG4gICAgICAgICAgICBjb21tYW5kcy5wdXNoKHtjb21tYW5kOiBvcGVyYXRpb25zLnNldENlbnRlciwgYXJnczogW2FmdGVyLmNlbnRlcl19KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzRXF1YWwoYmVmb3JlLnpvb20sIGFmdGVyLnpvb20pKSB7XG4gICAgICAgICAgICBjb21tYW5kcy5wdXNoKHtjb21tYW5kOiBvcGVyYXRpb25zLnNldFpvb20sIGFyZ3M6IFthZnRlci56b29tXX0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNFcXVhbChiZWZvcmUuYmVhcmluZywgYWZ0ZXIuYmVhcmluZykpIHtcbiAgICAgICAgICAgIGNvbW1hbmRzLnB1c2goe2NvbW1hbmQ6IG9wZXJhdGlvbnMuc2V0QmVhcmluZywgYXJnczogW2FmdGVyLmJlYXJpbmddfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc0VxdWFsKGJlZm9yZS5waXRjaCwgYWZ0ZXIucGl0Y2gpKSB7XG4gICAgICAgICAgICBjb21tYW5kcy5wdXNoKHtjb21tYW5kOiBvcGVyYXRpb25zLnNldFBpdGNoLCBhcmdzOiBbYWZ0ZXIucGl0Y2hdfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc0VxdWFsKGJlZm9yZS5zcHJpdGUsIGFmdGVyLnNwcml0ZSkpIHtcbiAgICAgICAgICAgIGNvbW1hbmRzLnB1c2goe2NvbW1hbmQ6IG9wZXJhdGlvbnMuc2V0U3ByaXRlLCBhcmdzOiBbYWZ0ZXIuc3ByaXRlXX0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNFcXVhbChiZWZvcmUuZ2x5cGhzLCBhZnRlci5nbHlwaHMpKSB7XG4gICAgICAgICAgICBjb21tYW5kcy5wdXNoKHtjb21tYW5kOiBvcGVyYXRpb25zLnNldEdseXBocywgYXJnczogW2FmdGVyLmdseXBoc119KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzRXF1YWwoYmVmb3JlLnRyYW5zaXRpb24sIGFmdGVyLnRyYW5zaXRpb24pKSB7XG4gICAgICAgICAgICBjb21tYW5kcy5wdXNoKHtjb21tYW5kOiBvcGVyYXRpb25zLnNldFRyYW5zaXRpb24sIGFyZ3M6IFthZnRlci50cmFuc2l0aW9uXX0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNFcXVhbChiZWZvcmUubGlnaHQsIGFmdGVyLmxpZ2h0KSkge1xuICAgICAgICAgICAgY29tbWFuZHMucHVzaCh7Y29tbWFuZDogb3BlcmF0aW9ucy5zZXRMaWdodCwgYXJnczogW2FmdGVyLmxpZ2h0XX0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNFcXVhbChiZWZvcmUuZm9nLCBhZnRlci5mb2cpKSB7XG4gICAgICAgICAgICBjb21tYW5kcy5wdXNoKHtjb21tYW5kOiBvcGVyYXRpb25zLnNldEZvZywgYXJnczogW2FmdGVyLmZvZ119KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzRXF1YWwoYmVmb3JlLnByb2plY3Rpb24sIGFmdGVyLnByb2plY3Rpb24pKSB7XG4gICAgICAgICAgICBjb21tYW5kcy5wdXNoKHtjb21tYW5kOiBvcGVyYXRpb25zLnNldFByb2plY3Rpb24sIGFyZ3M6IFthZnRlci5wcm9qZWN0aW9uXX0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSGFuZGxlIGNoYW5nZXMgdG8gYHNvdXJjZXNgXG4gICAgICAgIC8vIElmIGEgc291cmNlIGlzIHRvIGJlIHJlbW92ZWQsIHdlIGFsc28tLWJlZm9yZSB0aGUgcmVtb3ZlU291cmNlXG4gICAgICAgIC8vIGNvbW1hbmQtLW5lZWQgdG8gcmVtb3ZlIGFsbCB0aGUgc3R5bGUgbGF5ZXJzIHRoYXQgZGVwZW5kIG9uIGl0LlxuICAgICAgICBjb25zdCBzb3VyY2VzUmVtb3ZlZCA9IHt9O1xuXG4gICAgICAgIC8vIEZpcnN0IGNvbGxlY3QgdGhlIHthZGQscmVtb3ZlfVNvdXJjZSBjb21tYW5kc1xuICAgICAgICBjb25zdCByZW1vdmVPckFkZFNvdXJjZUNvbW1hbmRzID0gW107XG4gICAgICAgIGRpZmZTb3VyY2VzKGJlZm9yZS5zb3VyY2VzLCBhZnRlci5zb3VyY2VzLCByZW1vdmVPckFkZFNvdXJjZUNvbW1hbmRzLCBzb3VyY2VzUmVtb3ZlZCk7XG5cbiAgICAgICAgLy8gUHVzaCBhIHJlbW92ZUxheWVyIGNvbW1hbmQgZm9yIGVhY2ggc3R5bGUgbGF5ZXIgdGhhdCBkZXBlbmRzIG9uIGFcbiAgICAgICAgLy8gc291cmNlIHRoYXQncyBiZWluZyByZW1vdmVkLlxuICAgICAgICAvLyBBbHNvLCBleGNsdWRlIGFueSBzdWNoIGxheWVycyB0aGVtIGZyb20gdGhlIGlucHV0IHRvIGBkaWZmTGF5ZXJzYFxuICAgICAgICAvLyBiZWxvdywgc28gdGhhdCBkaWZmTGF5ZXJzIHByb2R1Y2VzIHRoZSBhcHByb3ByaWF0ZSBgYWRkTGF5ZXJzYFxuICAgICAgICAvLyBjb21tYW5kXG4gICAgICAgIGNvbnN0IGJlZm9yZUxheWVycyA9IFtdO1xuICAgICAgICBpZiAoYmVmb3JlLmxheWVycykge1xuICAgICAgICAgICAgYmVmb3JlLmxheWVycy5mb3JFYWNoKChsYXllcikgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChsYXllci5zb3VyY2UgJiYgc291cmNlc1JlbW92ZWRbbGF5ZXIuc291cmNlXSkge1xuICAgICAgICAgICAgICAgICAgICBjb21tYW5kcy5wdXNoKHtjb21tYW5kOiBvcGVyYXRpb25zLnJlbW92ZUxheWVyLCBhcmdzOiBbbGF5ZXIuaWRdfSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYmVmb3JlTGF5ZXJzLnB1c2gobGF5ZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVtb3ZlIHRoZSB0ZXJyYWluIGlmIHRoZSBzb3VyY2UgZm9yIHRoYXQgdGVycmFpbiBpcyBiZWluZyByZW1vdmVkXG4gICAgICAgIGxldCBiZWZvcmVUZXJyYWluID0gYmVmb3JlLnRlcnJhaW47XG4gICAgICAgIGlmIChiZWZvcmVUZXJyYWluKSB7XG4gICAgICAgICAgICBpZiAoc291cmNlc1JlbW92ZWRbYmVmb3JlVGVycmFpbi5zb3VyY2VdKSB7XG4gICAgICAgICAgICAgICAgY29tbWFuZHMucHVzaCh7Y29tbWFuZDogb3BlcmF0aW9ucy5zZXRUZXJyYWluLCBhcmdzOiBbdW5kZWZpbmVkXX0pO1xuICAgICAgICAgICAgICAgIGJlZm9yZVRlcnJhaW4gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb21tYW5kcyA9IGNvbW1hbmRzLmNvbmNhdChyZW1vdmVPckFkZFNvdXJjZUNvbW1hbmRzKTtcblxuICAgICAgICAvLyBFdmVuIHRob3VnaCB0ZXJyYWluIGlzIGEgdG9wLWxldmVsIHByb3BlcnR5XG4gICAgICAgIC8vIEl0cyBsaWtlIGEgbGF5ZXIgaW4gdGhlIHNlbnNlIHRoYXQgaXQgZGVwZW5kcyBvbiBhIHNvdXJjZSBiZWluZyBwcmVzZW50LlxuICAgICAgICBpZiAoIWlzRXF1YWwoYmVmb3JlVGVycmFpbiwgYWZ0ZXIudGVycmFpbikpIHtcbiAgICAgICAgICAgIGNvbW1hbmRzLnB1c2goe2NvbW1hbmQ6IG9wZXJhdGlvbnMuc2V0VGVycmFpbiwgYXJnczogW2FmdGVyLnRlcnJhaW5dfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBIYW5kbGUgY2hhbmdlcyB0byBgbGF5ZXJzYFxuICAgICAgICBkaWZmTGF5ZXJzKGJlZm9yZUxheWVycywgYWZ0ZXIubGF5ZXJzLCBjb21tYW5kcyk7XG5cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIGZhbGwgYmFjayB0byBzZXRTdHlsZVxuICAgICAgICBjb25zb2xlLndhcm4oJ1VuYWJsZSB0byBjb21wdXRlIHN0eWxlIGRpZmY6JywgZSk7XG4gICAgICAgIGNvbW1hbmRzID0gW3tjb21tYW5kOiBvcGVyYXRpb25zLnNldFN0eWxlLCBhcmdzOiBbYWZ0ZXJdfV07XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbW1hbmRzO1xufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtjbGFtcH0gZnJvbSAnLi4vdXRpbC91dGlsLmpzJztcbmltcG9ydCBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcblxuY2xhc3MgUGF0aEludGVycG9sYXRvciB7XG4gICAgcG9pbnRzOiBBcnJheTxQb2ludD47XG4gICAgbGVuZ3RoOiBudW1iZXI7XG4gICAgcGFkZGVkTGVuZ3RoOiBudW1iZXI7XG4gICAgcGFkZGluZzogbnVtYmVyO1xuICAgIF9kaXN0YW5jZXM6IEFycmF5PG51bWJlcj47XG5cbiAgICBjb25zdHJ1Y3Rvcihwb2ludHNfOiA/QXJyYXk8UG9pbnQ+LCBwYWRkaW5nXzogP251bWJlcikge1xuICAgICAgICB0aGlzLnJlc2V0KHBvaW50c18sIHBhZGRpbmdfKTtcbiAgICB9XG5cbiAgICByZXNldChwb2ludHNfOiA/QXJyYXk8UG9pbnQ+LCBwYWRkaW5nXzogP251bWJlcikge1xuICAgICAgICB0aGlzLnBvaW50cyA9IHBvaW50c18gfHwgW107XG5cbiAgICAgICAgLy8gQ29tcHV0ZSBjdW11bGF0aXZlIGRpc3RhbmNlIGZyb20gZmlyc3QgcG9pbnQgdG8gZXZlcnkgb3RoZXIgcG9pbnQgaW4gdGhlIHNlZ21lbnQuXG4gICAgICAgIC8vIExhc3QgZW50cnkgaW4gdGhlIGFycmF5IGlzIHRvdGFsIGxlbmd0aCBvZiB0aGUgcGF0aFxuICAgICAgICB0aGlzLl9kaXN0YW5jZXMgPSBbMC4wXTtcblxuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IHRoaXMucG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB0aGlzLl9kaXN0YW5jZXNbaV0gPSB0aGlzLl9kaXN0YW5jZXNbaSAtIDFdICsgdGhpcy5wb2ludHNbaV0uZGlzdCh0aGlzLnBvaW50c1tpIC0gMV0pO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5sZW5ndGggPSB0aGlzLl9kaXN0YW5jZXNbdGhpcy5fZGlzdGFuY2VzLmxlbmd0aCAtIDFdO1xuICAgICAgICB0aGlzLnBhZGRpbmcgPSBNYXRoLm1pbihwYWRkaW5nXyB8fCAwLCB0aGlzLmxlbmd0aCAqIDAuNSk7XG4gICAgICAgIHRoaXMucGFkZGVkTGVuZ3RoID0gdGhpcy5sZW5ndGggLSB0aGlzLnBhZGRpbmcgKiAyLjA7XG4gICAgfVxuXG4gICAgbGVycCh0OiBudW1iZXIpOiBQb2ludCB7XG4gICAgICAgIGFzc2VydCh0aGlzLnBvaW50cy5sZW5ndGggPiAwKTtcbiAgICAgICAgaWYgKHRoaXMucG9pbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucG9pbnRzWzBdO1xuICAgICAgICB9XG5cbiAgICAgICAgdCA9IGNsYW1wKHQsIDAsIDEpO1xuXG4gICAgICAgIC8vIEZpbmQgdGhlIGNvcnJlY3Qgc2VnbWVudCBbcDAsIHAxXSB3aGVyZSBwMCA8PSB4IDwgcDFcbiAgICAgICAgbGV0IGN1cnJlbnRJbmRleCA9IDE7XG4gICAgICAgIGxldCBkaXN0T2ZDdXJyZW50SWR4ID0gdGhpcy5fZGlzdGFuY2VzW2N1cnJlbnRJbmRleF07XG4gICAgICAgIGNvbnN0IGRpc3RUb1RhcmdldCA9IHQgKiB0aGlzLnBhZGRlZExlbmd0aCArIHRoaXMucGFkZGluZztcblxuICAgICAgICB3aGlsZSAoZGlzdE9mQ3VycmVudElkeCA8IGRpc3RUb1RhcmdldCAmJiBjdXJyZW50SW5kZXggPCB0aGlzLl9kaXN0YW5jZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICBkaXN0T2ZDdXJyZW50SWR4ID0gdGhpcy5fZGlzdGFuY2VzWysrY3VycmVudEluZGV4XTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEludGVycG9sYXRlIGJldHdlZW4gdGhlIHR3byBwb2ludHMgb2YgdGhlIHNlZ21lbnRcbiAgICAgICAgY29uc3QgaWR4T2ZQcmV2UG9pbnQgPSBjdXJyZW50SW5kZXggLSAxO1xuICAgICAgICBjb25zdCBkaXN0T2ZQcmV2SWR4ID0gdGhpcy5fZGlzdGFuY2VzW2lkeE9mUHJldlBvaW50XTtcbiAgICAgICAgY29uc3Qgc2VnbWVudExlbmd0aCA9IGRpc3RPZkN1cnJlbnRJZHggLSBkaXN0T2ZQcmV2SWR4O1xuICAgICAgICBjb25zdCBzZWdtZW50VCA9IHNlZ21lbnRMZW5ndGggPiAwID8gKGRpc3RUb1RhcmdldCAtIGRpc3RPZlByZXZJZHgpIC8gc2VnbWVudExlbmd0aCA6IDA7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMucG9pbnRzW2lkeE9mUHJldlBvaW50XS5tdWx0KDEuMCAtIHNlZ21lbnRUKS5hZGQodGhpcy5wb2ludHNbY3VycmVudEluZGV4XS5tdWx0KHNlZ21lbnRUKSk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBQYXRoSW50ZXJwb2xhdG9yO1xuIiwiLy8gQGZsb3dcblxudHlwZSBHcmlkSXRlbSA9IHtcbiAgICBrZXk6IGFueSxcbiAgICB4MTogbnVtYmVyLFxuICAgIHkxOiBudW1iZXIsXG4gICAgeDI6IG51bWJlcixcbiAgICB5MjogbnVtYmVyXG59O1xuXG4vKipcbiAqIEdyaWRJbmRleCBpcyBhIGRhdGEgc3RydWN0dXJlIGZvciB0ZXN0aW5nIHRoZSBpbnRlcnNlY3Rpb24gb2ZcbiAqIGNpcmNsZXMgYW5kIHJlY3RhbmdsZXMgaW4gYSAyZCBwbGFuZS5cbiAqIEl0IGlzIG9wdGltaXplZCBmb3IgcmFwaWQgaW5zZXJ0aW9uIGFuZCBxdWVyeWluZy5cbiAqIEdyaWRJbmRleCBzcGxpdHMgdGhlIHBsYW5lIGludG8gYSBzZXQgb2YgXCJjZWxsc1wiIGFuZCBrZWVwcyB0cmFja1xuICogb2Ygd2hpY2ggZ2VvbWV0cmllcyBpbnRlcnNlY3Qgd2l0aCBlYWNoIGNlbGwuIEF0IHF1ZXJ5IHRpbWUsXG4gKiBmdWxsIGdlb21ldHJ5IGNvbXBhcmlzb25zIGFyZSBvbmx5IGRvbmUgZm9yIGl0ZW1zIHRoYXQgc2hhcmVcbiAqIGF0IGxlYXN0IG9uZSBjZWxsLiBBcyBsb25nIGFzIHRoZSBnZW9tZXRyaWVzIGFyZSByZWxhdGl2ZWx5XG4gKiB1bmlmb3JtbHkgZGlzdHJpYnV0ZWQgYWNyb3NzIHRoZSBwbGFuZSwgdGhpcyBncmVhdGx5IHJlZHVjZXNcbiAqIHRoZSBudW1iZXIgb2YgY29tcGFyaXNvbnMgbmVjZXNzYXJ5LlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmNsYXNzIEdyaWRJbmRleCB7XG4gICAgY2lyY2xlS2V5czogQXJyYXk8YW55PjtcbiAgICBib3hLZXlzOiBBcnJheTxhbnk+O1xuICAgIGJveENlbGxzOiBBcnJheTxBcnJheTxudW1iZXI+PjtcbiAgICBjaXJjbGVDZWxsczogQXJyYXk8QXJyYXk8bnVtYmVyPj47XG4gICAgYmJveGVzOiBBcnJheTxudW1iZXI+O1xuICAgIGNpcmNsZXM6IEFycmF5PG51bWJlcj47XG4gICAgeENlbGxDb3VudDogbnVtYmVyO1xuICAgIHlDZWxsQ291bnQ6IG51bWJlcjtcbiAgICB3aWR0aDogbnVtYmVyO1xuICAgIGhlaWdodDogbnVtYmVyO1xuICAgIHhTY2FsZTogbnVtYmVyO1xuICAgIHlTY2FsZTogbnVtYmVyO1xuICAgIGJveFVpZDogbnVtYmVyO1xuICAgIGNpcmNsZVVpZDogbnVtYmVyO1xuXG4gICAgY29uc3RydWN0b3IgKHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyLCBjZWxsU2l6ZTogbnVtYmVyKSB7XG4gICAgICAgIGNvbnN0IGJveENlbGxzID0gdGhpcy5ib3hDZWxscyA9IFtdO1xuICAgICAgICBjb25zdCBjaXJjbGVDZWxscyA9IHRoaXMuY2lyY2xlQ2VsbHMgPSBbXTtcblxuICAgICAgICAvLyBNb3JlIGNlbGxzIC0+IGZld2VyIGdlb21ldHJpZXMgdG8gY2hlY2sgcGVyIGNlbGwsIGJ1dCBpdGVtcyB0ZW5kXG4gICAgICAgIC8vIHRvIGJlIHNwbGl0IGFjcm9zcyBtb3JlIGNlbGxzLlxuICAgICAgICAvLyBTd2VldCBzcG90IGFsbG93cyBtb3N0IHNtYWxsIGl0ZW1zIHRvIGZpdCBpbiBvbmUgY2VsbFxuICAgICAgICB0aGlzLnhDZWxsQ291bnQgPSBNYXRoLmNlaWwod2lkdGggLyBjZWxsU2l6ZSk7XG4gICAgICAgIHRoaXMueUNlbGxDb3VudCA9IE1hdGguY2VpbChoZWlnaHQgLyBjZWxsU2l6ZSk7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnhDZWxsQ291bnQgKiB0aGlzLnlDZWxsQ291bnQ7IGkrKykge1xuICAgICAgICAgICAgYm94Q2VsbHMucHVzaChbXSk7XG4gICAgICAgICAgICBjaXJjbGVDZWxscy5wdXNoKFtdKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNpcmNsZUtleXMgPSBbXTtcbiAgICAgICAgdGhpcy5ib3hLZXlzID0gW107XG4gICAgICAgIHRoaXMuYmJveGVzID0gW107XG4gICAgICAgIHRoaXMuY2lyY2xlcyA9IFtdO1xuXG4gICAgICAgIHRoaXMud2lkdGggPSB3aWR0aDtcbiAgICAgICAgdGhpcy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgICAgIHRoaXMueFNjYWxlID0gdGhpcy54Q2VsbENvdW50IC8gd2lkdGg7XG4gICAgICAgIHRoaXMueVNjYWxlID0gdGhpcy55Q2VsbENvdW50IC8gaGVpZ2h0O1xuICAgICAgICB0aGlzLmJveFVpZCA9IDA7XG4gICAgICAgIHRoaXMuY2lyY2xlVWlkID0gMDtcbiAgICB9XG5cbiAgICBrZXlzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLmJveEtleXMubGVuZ3RoICsgdGhpcy5jaXJjbGVLZXlzLmxlbmd0aDtcbiAgICB9XG5cbiAgICBpbnNlcnQoa2V5OiBhbnksIHgxOiBudW1iZXIsIHkxOiBudW1iZXIsIHgyOiBudW1iZXIsIHkyOiBudW1iZXIpIHtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICB0aGlzLl9mb3JFYWNoQ2VsbCh4MSwgeTEsIHgyLCB5MiwgdGhpcy5faW5zZXJ0Qm94Q2VsbCwgdGhpcy5ib3hVaWQrKyk7XG4gICAgICAgIHRoaXMuYm94S2V5cy5wdXNoKGtleSk7XG4gICAgICAgIHRoaXMuYmJveGVzLnB1c2goeDEpO1xuICAgICAgICB0aGlzLmJib3hlcy5wdXNoKHkxKTtcbiAgICAgICAgdGhpcy5iYm94ZXMucHVzaCh4Mik7XG4gICAgICAgIHRoaXMuYmJveGVzLnB1c2goeTIpO1xuICAgIH1cblxuICAgIGluc2VydENpcmNsZShrZXk6IGFueSwgeDogbnVtYmVyLCB5OiBudW1iZXIsIHJhZGl1czogbnVtYmVyKSB7XG4gICAgICAgIC8vIEluc2VydCBjaXJjbGUgaW50byBncmlkIGZvciBhbGwgY2VsbHMgaW4gdGhlIGNpcmN1bXNjcmliaW5nIHNxdWFyZVxuICAgICAgICAvLyBJdCdzIG1vcmUgdGhhbiBuZWNlc3NhcnkgKGJ5IGEgZmFjdG9yIG9mIDQvUEkpLCBidXQgZmFzdCB0byBpbnNlcnRcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICB0aGlzLl9mb3JFYWNoQ2VsbCh4IC0gcmFkaXVzLCB5IC0gcmFkaXVzLCB4ICsgcmFkaXVzLCB5ICsgcmFkaXVzLCB0aGlzLl9pbnNlcnRDaXJjbGVDZWxsLCB0aGlzLmNpcmNsZVVpZCsrKTtcbiAgICAgICAgdGhpcy5jaXJjbGVLZXlzLnB1c2goa2V5KTtcbiAgICAgICAgdGhpcy5jaXJjbGVzLnB1c2goeCk7XG4gICAgICAgIHRoaXMuY2lyY2xlcy5wdXNoKHkpO1xuICAgICAgICB0aGlzLmNpcmNsZXMucHVzaChyYWRpdXMpO1xuICAgIH1cblxuICAgIF9pbnNlcnRCb3hDZWxsKHgxOiBudW1iZXIsIHkxOiBudW1iZXIsIHgyOiBudW1iZXIsIHkyOiBudW1iZXIsIGNlbGxJbmRleDogbnVtYmVyLCB1aWQ6IG51bWJlcikge1xuICAgICAgICB0aGlzLmJveENlbGxzW2NlbGxJbmRleF0ucHVzaCh1aWQpO1xuICAgIH1cblxuICAgIF9pbnNlcnRDaXJjbGVDZWxsKHgxOiBudW1iZXIsIHkxOiBudW1iZXIsIHgyOiBudW1iZXIsIHkyOiBudW1iZXIsIGNlbGxJbmRleDogbnVtYmVyLCB1aWQ6IG51bWJlcikgIHtcbiAgICAgICAgdGhpcy5jaXJjbGVDZWxsc1tjZWxsSW5kZXhdLnB1c2godWlkKTtcbiAgICB9XG5cbiAgICBfcXVlcnkoeDE6IG51bWJlciwgeTE6IG51bWJlciwgeDI6IG51bWJlciwgeTI6IG51bWJlciwgaGl0VGVzdDogYm9vbGVhbiwgcHJlZGljYXRlPzogYW55KTogYm9vbGVhbiB8IEFycmF5PEdyaWRJdGVtPiB7XG4gICAgICAgIGlmICh4MiA8IDAgfHwgeDEgPiB0aGlzLndpZHRoIHx8IHkyIDwgMCB8fCB5MSA+IHRoaXMuaGVpZ2h0KSB7XG4gICAgICAgICAgICByZXR1cm4gaGl0VGVzdCA/IGZhbHNlIDogW107XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gW107XG4gICAgICAgIGlmICh4MSA8PSAwICYmIHkxIDw9IDAgJiYgdGhpcy53aWR0aCA8PSB4MiAmJiB0aGlzLmhlaWdodCA8PSB5Mikge1xuICAgICAgICAgICAgaWYgKGhpdFRlc3QpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAobGV0IGJveFVpZCA9IDA7IGJveFVpZCA8IHRoaXMuYm94S2V5cy5sZW5ndGg7IGJveFVpZCsrKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBrZXk6IHRoaXMuYm94S2V5c1tib3hVaWRdLFxuICAgICAgICAgICAgICAgICAgICB4MTogdGhpcy5iYm94ZXNbYm94VWlkICogNF0sXG4gICAgICAgICAgICAgICAgICAgIHkxOiB0aGlzLmJib3hlc1tib3hVaWQgKiA0ICsgMV0sXG4gICAgICAgICAgICAgICAgICAgIHgyOiB0aGlzLmJib3hlc1tib3hVaWQgKiA0ICsgMl0sXG4gICAgICAgICAgICAgICAgICAgIHkyOiB0aGlzLmJib3hlc1tib3hVaWQgKiA0ICsgM11cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAobGV0IGNpcmNsZVVpZCA9IDA7IGNpcmNsZVVpZCA8IHRoaXMuY2lyY2xlS2V5cy5sZW5ndGg7IGNpcmNsZVVpZCsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeCA9IHRoaXMuY2lyY2xlc1tjaXJjbGVVaWQgKiAzXTtcbiAgICAgICAgICAgICAgICBjb25zdCB5ID0gdGhpcy5jaXJjbGVzW2NpcmNsZVVpZCAqIDMgKyAxXTtcbiAgICAgICAgICAgICAgICBjb25zdCByYWRpdXMgPSB0aGlzLmNpcmNsZXNbY2lyY2xlVWlkICogMyArIDJdO1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAga2V5OiB0aGlzLmNpcmNsZUtleXNbY2lyY2xlVWlkXSxcbiAgICAgICAgICAgICAgICAgICAgeDE6IHggLSByYWRpdXMsXG4gICAgICAgICAgICAgICAgICAgIHkxOiB5IC0gcmFkaXVzLFxuICAgICAgICAgICAgICAgICAgICB4MjogeCArIHJhZGl1cyxcbiAgICAgICAgICAgICAgICAgICAgeTI6IHkgKyByYWRpdXNcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBwcmVkaWNhdGUgPyByZXN1bHQuZmlsdGVyKHByZWRpY2F0ZSkgOiByZXN1bHQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBxdWVyeUFyZ3MgPSB7XG4gICAgICAgICAgICAgICAgaGl0VGVzdCxcbiAgICAgICAgICAgICAgICBzZWVuVWlkczoge2JveDoge30sIGNpcmNsZToge319XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgdGhpcy5fZm9yRWFjaENlbGwoeDEsIHkxLCB4MiwgeTIsIHRoaXMuX3F1ZXJ5Q2VsbCwgcmVzdWx0LCBxdWVyeUFyZ3MsIHByZWRpY2F0ZSk7XG4gICAgICAgICAgICByZXR1cm4gaGl0VGVzdCA/IHJlc3VsdC5sZW5ndGggPiAwIDogcmVzdWx0O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX3F1ZXJ5Q2lyY2xlKHg6IG51bWJlciwgeTogbnVtYmVyLCByYWRpdXM6IG51bWJlciwgaGl0VGVzdDogYm9vbGVhbiwgcHJlZGljYXRlPzogYW55KTogYm9vbGVhbiB8IEFycmF5PEdyaWRJdGVtPiB7XG4gICAgICAgIC8vIEluc2VydCBjaXJjbGUgaW50byBncmlkIGZvciBhbGwgY2VsbHMgaW4gdGhlIGNpcmN1bXNjcmliaW5nIHNxdWFyZVxuICAgICAgICAvLyBJdCdzIG1vcmUgdGhhbiBuZWNlc3NhcnkgKGJ5IGEgZmFjdG9yIG9mIDQvUEkpLCBidXQgZmFzdCB0byBpbnNlcnRcbiAgICAgICAgY29uc3QgeDEgPSB4IC0gcmFkaXVzO1xuICAgICAgICBjb25zdCB4MiA9IHggKyByYWRpdXM7XG4gICAgICAgIGNvbnN0IHkxID0geSAtIHJhZGl1cztcbiAgICAgICAgY29uc3QgeTIgPSB5ICsgcmFkaXVzO1xuICAgICAgICBpZiAoeDIgPCAwIHx8IHgxID4gdGhpcy53aWR0aCB8fCB5MiA8IDAgfHwgeTEgPiB0aGlzLmhlaWdodCkge1xuICAgICAgICAgICAgcmV0dXJuIGhpdFRlc3QgPyBmYWxzZSA6IFtdO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQm94IHF1ZXJ5IGVhcmx5IGV4aXRzIGlmIHRoZSBib3VuZGluZyBib3ggaXMgbGFyZ2VyIHRoYW4gdGhlIGdyaWQsIGJ1dCB3ZSBkb24ndCBkb1xuICAgICAgICAvLyB0aGUgZXF1aXZhbGVudCBjYWxjdWxhdGlvbiBmb3IgY2lyY2xlIHF1ZXJpZXMgYmVjYXVzZSBlYXJseSBleGl0IGlzIGxlc3MgbGlrZWx5XG4gICAgICAgIC8vIGFuZCB0aGUgY2FsY3VsYXRpb24gaXMgbW9yZSBleHBlbnNpdmVcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gW107XG4gICAgICAgIGNvbnN0IHF1ZXJ5QXJncyA9IHtcbiAgICAgICAgICAgIGhpdFRlc3QsXG4gICAgICAgICAgICBjaXJjbGU6IHt4LCB5LCByYWRpdXN9LFxuICAgICAgICAgICAgc2VlblVpZHM6IHtib3g6IHt9LCBjaXJjbGU6IHt9fVxuICAgICAgICB9O1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIHRoaXMuX2ZvckVhY2hDZWxsKHgxLCB5MSwgeDIsIHkyLCB0aGlzLl9xdWVyeUNlbGxDaXJjbGUsIHJlc3VsdCwgcXVlcnlBcmdzLCBwcmVkaWNhdGUpO1xuICAgICAgICByZXR1cm4gaGl0VGVzdCA/IHJlc3VsdC5sZW5ndGggPiAwIDogcmVzdWx0O1xuICAgIH1cblxuICAgIHF1ZXJ5KHgxOiBudW1iZXIsIHkxOiBudW1iZXIsIHgyOiBudW1iZXIsIHkyOiBudW1iZXIsIHByZWRpY2F0ZT86IGFueSk6IEFycmF5PEdyaWRJdGVtPiB7XG4gICAgICAgIHJldHVybiAodGhpcy5fcXVlcnkoeDEsIHkxLCB4MiwgeTIsIGZhbHNlLCBwcmVkaWNhdGUpOiBhbnkpO1xuICAgIH1cblxuICAgIGhpdFRlc3QoeDE6IG51bWJlciwgeTE6IG51bWJlciwgeDI6IG51bWJlciwgeTI6IG51bWJlciwgcHJlZGljYXRlPzogYW55KTogYm9vbGVhbiAge1xuICAgICAgICByZXR1cm4gKHRoaXMuX3F1ZXJ5KHgxLCB5MSwgeDIsIHkyLCB0cnVlLCBwcmVkaWNhdGUpOiBhbnkpO1xuICAgIH1cblxuICAgIGhpdFRlc3RDaXJjbGUoeDogbnVtYmVyLCB5OiBudW1iZXIsIHJhZGl1czogbnVtYmVyLCBwcmVkaWNhdGU/OiBhbnkpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLl9xdWVyeUNpcmNsZSh4LCB5LCByYWRpdXMsIHRydWUsIHByZWRpY2F0ZSk6IGFueSk7XG4gICAgfVxuXG4gICAgX3F1ZXJ5Q2VsbCh4MTogbnVtYmVyLCB5MTogbnVtYmVyLCB4MjogbnVtYmVyLCB5MjogbnVtYmVyLCBjZWxsSW5kZXg6IG51bWJlciwgcmVzdWx0OiBhbnksIHF1ZXJ5QXJnczogYW55LCBwcmVkaWNhdGU/OiBhbnkpOiB2b2lkIHwgYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IHNlZW5VaWRzID0gcXVlcnlBcmdzLnNlZW5VaWRzO1xuICAgICAgICBjb25zdCBib3hDZWxsID0gdGhpcy5ib3hDZWxsc1tjZWxsSW5kZXhdO1xuICAgICAgICBpZiAoYm94Q2VsbCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3QgYmJveGVzID0gdGhpcy5iYm94ZXM7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGJveFVpZCBvZiBib3hDZWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFzZWVuVWlkcy5ib3hbYm94VWlkXSkge1xuICAgICAgICAgICAgICAgICAgICBzZWVuVWlkcy5ib3hbYm94VWlkXSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9mZnNldCA9IGJveFVpZCAqIDQ7XG4gICAgICAgICAgICAgICAgICAgIGlmICgoeDEgPD0gYmJveGVzW29mZnNldCArIDJdKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgKHkxIDw9IGJib3hlc1tvZmZzZXQgKyAzXSkgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICh4MiA+PSBiYm94ZXNbb2Zmc2V0ICsgMF0pICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAoeTIgPj0gYmJveGVzW29mZnNldCArIDFdKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgKCFwcmVkaWNhdGUgfHwgcHJlZGljYXRlKHRoaXMuYm94S2V5c1tib3hVaWRdKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChxdWVyeUFyZ3MuaGl0VGVzdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleTogdGhpcy5ib3hLZXlzW2JveFVpZF0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHgxOiBiYm94ZXNbb2Zmc2V0XSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTE6IGJib3hlc1tvZmZzZXQgKyAxXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDI6IGJib3hlc1tvZmZzZXQgKyAyXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTI6IGJib3hlc1tvZmZzZXQgKyAzXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNpcmNsZUNlbGwgPSB0aGlzLmNpcmNsZUNlbGxzW2NlbGxJbmRleF07XG4gICAgICAgIGlmIChjaXJjbGVDZWxsICE9PSBudWxsKSB7XG4gICAgICAgICAgICBjb25zdCBjaXJjbGVzID0gdGhpcy5jaXJjbGVzO1xuICAgICAgICAgICAgZm9yIChjb25zdCBjaXJjbGVVaWQgb2YgY2lyY2xlQ2VsbCkge1xuICAgICAgICAgICAgICAgIGlmICghc2VlblVpZHMuY2lyY2xlW2NpcmNsZVVpZF0pIHtcbiAgICAgICAgICAgICAgICAgICAgc2VlblVpZHMuY2lyY2xlW2NpcmNsZVVpZF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvZmZzZXQgPSBjaXJjbGVVaWQgKiAzO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fY2lyY2xlQW5kUmVjdENvbGxpZGUoXG4gICAgICAgICAgICAgICAgICAgICAgICBjaXJjbGVzW29mZnNldF0sXG4gICAgICAgICAgICAgICAgICAgICAgICBjaXJjbGVzW29mZnNldCArIDFdLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2lyY2xlc1tvZmZzZXQgKyAyXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHgxLFxuICAgICAgICAgICAgICAgICAgICAgICAgeTEsXG4gICAgICAgICAgICAgICAgICAgICAgICB4MixcbiAgICAgICAgICAgICAgICAgICAgICAgIHkyKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgKCFwcmVkaWNhdGUgfHwgcHJlZGljYXRlKHRoaXMuY2lyY2xlS2V5c1tjaXJjbGVVaWRdKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChxdWVyeUFyZ3MuaGl0VGVzdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4ID0gY2lyY2xlc1tvZmZzZXRdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHkgPSBjaXJjbGVzW29mZnNldCArIDFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJhZGl1cyA9IGNpcmNsZXNbb2Zmc2V0ICsgMl07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk6IHRoaXMuY2lyY2xlS2V5c1tjaXJjbGVVaWRdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4MTogeCAtIHJhZGl1cyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTE6IHkgLSByYWRpdXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHgyOiB4ICsgcmFkaXVzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5MjogeSArIHJhZGl1c1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgX3F1ZXJ5Q2VsbENpcmNsZSh4MTogbnVtYmVyLCB5MTogbnVtYmVyLCB4MjogbnVtYmVyLCB5MjogbnVtYmVyLCBjZWxsSW5kZXg6IG51bWJlciwgcmVzdWx0OiBhbnksIHF1ZXJ5QXJnczogYW55LCBwcmVkaWNhdGU/OiBhbnkpOiB2b2lkIHwgYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IGNpcmNsZSA9IHF1ZXJ5QXJncy5jaXJjbGU7XG4gICAgICAgIGNvbnN0IHNlZW5VaWRzID0gcXVlcnlBcmdzLnNlZW5VaWRzO1xuICAgICAgICBjb25zdCBib3hDZWxsID0gdGhpcy5ib3hDZWxsc1tjZWxsSW5kZXhdO1xuICAgICAgICBpZiAoYm94Q2VsbCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3QgYmJveGVzID0gdGhpcy5iYm94ZXM7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGJveFVpZCBvZiBib3hDZWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFzZWVuVWlkcy5ib3hbYm94VWlkXSkge1xuICAgICAgICAgICAgICAgICAgICBzZWVuVWlkcy5ib3hbYm94VWlkXSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9mZnNldCA9IGJveFVpZCAqIDQ7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9jaXJjbGVBbmRSZWN0Q29sbGlkZShcbiAgICAgICAgICAgICAgICAgICAgICAgIGNpcmNsZS54LFxuICAgICAgICAgICAgICAgICAgICAgICAgY2lyY2xlLnksXG4gICAgICAgICAgICAgICAgICAgICAgICBjaXJjbGUucmFkaXVzLFxuICAgICAgICAgICAgICAgICAgICAgICAgYmJveGVzW29mZnNldCArIDBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgYmJveGVzW29mZnNldCArIDFdLFxuICAgICAgICAgICAgICAgICAgICAgICAgYmJveGVzW29mZnNldCArIDJdLFxuICAgICAgICAgICAgICAgICAgICAgICAgYmJveGVzW29mZnNldCArIDNdKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgKCFwcmVkaWNhdGUgfHwgcHJlZGljYXRlKHRoaXMuYm94S2V5c1tib3hVaWRdKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjaXJjbGVDZWxsID0gdGhpcy5jaXJjbGVDZWxsc1tjZWxsSW5kZXhdO1xuICAgICAgICBpZiAoY2lyY2xlQ2VsbCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3QgY2lyY2xlcyA9IHRoaXMuY2lyY2xlcztcbiAgICAgICAgICAgIGZvciAoY29uc3QgY2lyY2xlVWlkIG9mIGNpcmNsZUNlbGwpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXNlZW5VaWRzLmNpcmNsZVtjaXJjbGVVaWRdKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlZW5VaWRzLmNpcmNsZVtjaXJjbGVVaWRdID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2Zmc2V0ID0gY2lyY2xlVWlkICogMztcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX2NpcmNsZXNDb2xsaWRlKFxuICAgICAgICAgICAgICAgICAgICAgICAgY2lyY2xlc1tvZmZzZXRdLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2lyY2xlc1tvZmZzZXQgKyAxXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNpcmNsZXNbb2Zmc2V0ICsgMl0sXG4gICAgICAgICAgICAgICAgICAgICAgICBjaXJjbGUueCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNpcmNsZS55LFxuICAgICAgICAgICAgICAgICAgICAgICAgY2lyY2xlLnJhZGl1cykgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICghcHJlZGljYXRlIHx8IHByZWRpY2F0ZSh0aGlzLmNpcmNsZUtleXNbY2lyY2xlVWlkXSkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaCh0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgX2ZvckVhY2hDZWxsKHgxOiBudW1iZXIsIHkxOiBudW1iZXIsIHgyOiBudW1iZXIsIHkyOiBudW1iZXIsIGZuOiBhbnksIGFyZzE6IGFueSwgYXJnMj86IGFueSwgcHJlZGljYXRlPzogYW55KSB7XG4gICAgICAgIGNvbnN0IGN4MSA9IHRoaXMuX2NvbnZlcnRUb1hDZWxsQ29vcmQoeDEpO1xuICAgICAgICBjb25zdCBjeTEgPSB0aGlzLl9jb252ZXJ0VG9ZQ2VsbENvb3JkKHkxKTtcbiAgICAgICAgY29uc3QgY3gyID0gdGhpcy5fY29udmVydFRvWENlbGxDb29yZCh4Mik7XG4gICAgICAgIGNvbnN0IGN5MiA9IHRoaXMuX2NvbnZlcnRUb1lDZWxsQ29vcmQoeTIpO1xuXG4gICAgICAgIGZvciAobGV0IHggPSBjeDE7IHggPD0gY3gyOyB4KyspIHtcbiAgICAgICAgICAgIGZvciAobGV0IHkgPSBjeTE7IHkgPD0gY3kyOyB5KyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjZWxsSW5kZXggPSB0aGlzLnhDZWxsQ291bnQgKiB5ICsgeDtcbiAgICAgICAgICAgICAgICBpZiAoZm4uY2FsbCh0aGlzLCB4MSwgeTEsIHgyLCB5MiwgY2VsbEluZGV4LCBhcmcxLCBhcmcyLCBwcmVkaWNhdGUpKSByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfY29udmVydFRvWENlbGxDb29yZCh4OiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gTWF0aC5tYXgoMCwgTWF0aC5taW4odGhpcy54Q2VsbENvdW50IC0gMSwgTWF0aC5mbG9vcih4ICogdGhpcy54U2NhbGUpKSk7XG4gICAgfVxuXG4gICAgX2NvbnZlcnRUb1lDZWxsQ29vcmQoeTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIE1hdGgubWF4KDAsIE1hdGgubWluKHRoaXMueUNlbGxDb3VudCAtIDEsIE1hdGguZmxvb3IoeSAqIHRoaXMueVNjYWxlKSkpO1xuICAgIH1cblxuICAgIF9jaXJjbGVzQ29sbGlkZSh4MTogbnVtYmVyLCB5MTogbnVtYmVyLCByMTogbnVtYmVyLCB4MjogbnVtYmVyLCB5MjogbnVtYmVyLCByMjogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IGR4ID0geDIgLSB4MTtcbiAgICAgICAgY29uc3QgZHkgPSB5MiAtIHkxO1xuICAgICAgICBjb25zdCBib3RoUmFkaWkgPSByMSArIHIyO1xuICAgICAgICByZXR1cm4gKGJvdGhSYWRpaSAqIGJvdGhSYWRpaSkgPiAoZHggKiBkeCArIGR5ICogZHkpO1xuICAgIH1cblxuICAgIF9jaXJjbGVBbmRSZWN0Q29sbGlkZShjaXJjbGVYOiBudW1iZXIsIGNpcmNsZVk6IG51bWJlciwgcmFkaXVzOiBudW1iZXIsIHgxOiBudW1iZXIsIHkxOiBudW1iZXIsIHgyOiBudW1iZXIsIHkyOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgaGFsZlJlY3RXaWR0aCA9ICh4MiAtIHgxKSAvIDI7XG4gICAgICAgIGNvbnN0IGRpc3RYID0gTWF0aC5hYnMoY2lyY2xlWCAtICh4MSArIGhhbGZSZWN0V2lkdGgpKTtcbiAgICAgICAgaWYgKGRpc3RYID4gKGhhbGZSZWN0V2lkdGggKyByYWRpdXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBoYWxmUmVjdEhlaWdodCA9ICh5MiAtIHkxKSAvIDI7XG4gICAgICAgIGNvbnN0IGRpc3RZID0gTWF0aC5hYnMoY2lyY2xlWSAtICh5MSArIGhhbGZSZWN0SGVpZ2h0KSk7XG4gICAgICAgIGlmIChkaXN0WSA+IChoYWxmUmVjdEhlaWdodCArIHJhZGl1cykpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkaXN0WCA8PSBoYWxmUmVjdFdpZHRoIHx8IGRpc3RZIDw9IGhhbGZSZWN0SGVpZ2h0KSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGR4ID0gZGlzdFggLSBoYWxmUmVjdFdpZHRoO1xuICAgICAgICBjb25zdCBkeSA9IGRpc3RZIC0gaGFsZlJlY3RIZWlnaHQ7XG4gICAgICAgIHJldHVybiAoZHggKiBkeCArIGR5ICogZHkgPD0gKHJhZGl1cyAqIHJhZGl1cykpO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgR3JpZEluZGV4O1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IFBvaW50IGZyb20gJ0BtYXBib3gvcG9pbnQtZ2VvbWV0cnknO1xuXG5pbXBvcnQge21hdDIsIG1hdDQsIHZlYzMsIHZlYzR9IGZyb20gJ2dsLW1hdHJpeCc7XG5pbXBvcnQgKiBhcyBzeW1ib2xTaXplIGZyb20gJy4vc3ltYm9sX3NpemUuanMnO1xuaW1wb3J0IHthZGREeW5hbWljQXR0cmlidXRlcywgdXBkYXRlR2xvYmVWZXJ0ZXhOb3JtYWx9IGZyb20gJy4uL2RhdGEvYnVja2V0L3N5bWJvbF9idWNrZXQuanMnO1xuaW1wb3J0IHR5cGUgUHJvamVjdGlvbiBmcm9tICcuLi9nZW8vcHJvamVjdGlvbi9wcm9qZWN0aW9uLmpzJztcbmltcG9ydCB0eXBlIFBhaW50ZXIgZnJvbSAnLi4vcmVuZGVyL3BhaW50ZXIuanMnO1xuaW1wb3J0IHR5cGUgVHJhbnNmb3JtIGZyb20gJy4uL2dlby90cmFuc2Zvcm0uanMnO1xuaW1wb3J0IHR5cGUgU3ltYm9sQnVja2V0IGZyb20gJy4uL2RhdGEvYnVja2V0L3N5bWJvbF9idWNrZXQuanMnO1xuaW1wb3J0IHR5cGUge1xuICAgIEdseXBoT2Zmc2V0QXJyYXksXG4gICAgU3ltYm9sTGluZVZlcnRleEFycmF5LFxuICAgIFN5bWJvbER5bmFtaWNMYXlvdXRBcnJheSxcbiAgICBTeW1ib2xHbG9iZUV4dEFycmF5LFxuICAgIFBsYWNlZFN5bWJvbFxufSBmcm9tICcuLi9kYXRhL2FycmF5X3R5cGVzLmpzJztcbmltcG9ydCB0eXBlIHtNYXQ0LCBWZWMzLCBWZWM0fSBmcm9tICdnbC1tYXRyaXgnO1xuXG5pbXBvcnQge1dyaXRpbmdNb2RlfSBmcm9tICcuLi9zeW1ib2wvc2hhcGluZy5qcyc7XG5pbXBvcnQge0Nhbm9uaWNhbFRpbGVJRCwgT3ZlcnNjYWxlZFRpbGVJRH0gZnJvbSAnLi4vc291cmNlL3RpbGVfaWQuanMnO1xuaW1wb3J0IHtjYWxjdWxhdGVHbG9iZUxhYmVsTWF0cml4fSBmcm9tICcuLi9nZW8vcHJvamVjdGlvbi9nbG9iZV91dGlsLmpzJztcbmV4cG9ydCB7dXBkYXRlTGluZUxhYmVscywgaGlkZUdseXBocywgZ2V0TGFiZWxQbGFuZU1hdHJpeEZvclJlbmRlcmluZywgZ2V0TGFiZWxQbGFuZU1hdHJpeEZvclBsYWNlbWVudCwgZ2V0R2xDb29yZE1hdHJpeCwgcHJvamVjdCwgcHJvamVjdENsYW1wZWQsIGdldFBlcnNwZWN0aXZlUmF0aW8sIHBsYWNlRmlyc3RBbmRMYXN0R2x5cGgsIHBsYWNlR2x5cGhBbG9uZ0xpbmUsIHh5VHJhbnNmb3JtTWF0NH07XG5cbnR5cGUgUGxhY2VkR2x5cGggPSB7fFxuICAgIGFuZ2xlOiBudW1iZXIsXG4gICAgcGF0aDogQXJyYXk8VmVjMz4sXG4gICAgcG9pbnQ6IFZlYzMsXG4gICAgdGlsZVBhdGg6IEFycmF5PFBvaW50PixcbiAgICB1cDogVmVjM1xufH07XG50eXBlIFByb2plY3Rpb25DYWNoZSA9IHtbXzogbnVtYmVyXTogVmVjM307XG5cbnR5cGUgUGxhY2VtZW50U3RhdHVzID0ge1xuICAgIG5lZWRzRmxpcHBpbmc/OiBib29sZWFuLFxuICAgIG5vdEVub3VnaFJvb20/OiBib29sZWFuLFxuICAgIHVzZVZlcnRpY2FsPzogYm9vbGVhblxufTtcblxuY29uc3QgRmxpcFN0YXRlID0ge1xuICAgIHVua25vd246IDAsXG4gICAgZmxpcFJlcXVpcmVkOiAxLFxuICAgIGZsaXBOb3RSZXF1aXJlZDogMlxufTtcblxuY29uc3QgbWF4VGFuZ2VudCA9IE1hdGgudGFuKDg1ICogTWF0aC5QSSAvIDE4MCk7XG5cbi8qXG4gKiAjIE92ZXJ2aWV3IG9mIGNvb3JkaW5hdGUgc3BhY2VzXG4gKlxuICogIyMgVGlsZSBjb29yZGluYXRlIHNwYWNlc1xuICogRWFjaCBsYWJlbCBoYXMgYW4gYW5jaG9yLiBTb21lIGxhYmVscyBoYXZlIGNvcnJlc3BvbmRpbmcgbGluZSBnZW9tZXRyaWVzLlxuICogVGhlIHBvaW50cyBmb3IgYm90aCBhbmNob3JzIGFuZCBsaW5lcyBhcmUgc3RvcmVkIGluIHRpbGUgdW5pdHMuIEVhY2ggdGlsZSBoYXMgaXQncyBvd25cbiAqIGNvb3JkaW5hdGUgc3BhY2UgZ29pbmcgZnJvbSAoMCwgMCkgYXQgdGhlIHRvcCBsZWZ0IHRvIChFWFRFTlQsIEVYVEVOVCkgYXQgdGhlIGJvdHRvbSByaWdodC5cbiAqXG4gKiAjIyBHTCBjb29yZGluYXRlIHNwYWNlXG4gKiBBdCB0aGUgZW5kIG9mIGV2ZXJ5dGhpbmcsIHRoZSB2ZXJ0ZXggc2hhZGVyIG5lZWRzIHRvIHByb2R1Y2UgYSBwb3NpdGlvbiBpbiBHTCBjb29yZGluYXRlIHNwYWNlLFxuICogd2hpY2ggaXMgKC0xLCAxKSBhdCB0aGUgdG9wIGxlZnQgYW5kICgxLCAtMSkgaW4gdGhlIGJvdHRvbSByaWdodC5cbiAqXG4gKiAjIyBNYXAgcGl4ZWwgY29vcmRpbmF0ZSBzcGFjZXNcbiAqIEVhY2ggdGlsZSBoYXMgYSBwaXhlbCBjb29yZGluYXRlIHNwYWNlLiBJdCdzIGp1c3QgdGhlIHRpbGUgdW5pdHMgc2NhbGVkIHNvIHRoYXQgb25lIHVuaXQgaXNcbiAqIHdoYXRldmVyIGNvdW50cyBhcyAxIHBpeGVsIGF0IHRoZSBjdXJyZW50IHpvb20uXG4gKiBUaGlzIHNwYWNlIGlzIHVzZWQgZm9yIHBpdGNoLWFsaWdubWVudD1tYXAsIHJvdGF0aW9uLWFsaWdubWVudD1tYXBcbiAqXG4gKiAjIyBSb3RhdGVkIG1hcCBwaXhlbCBjb29yZGluYXRlIHNwYWNlc1xuICogTGlrZSB0aGUgYWJvdmUsIGJ1dCByb3RhdGVkIHNvIGF4aXMgb2YgdGhlIHNwYWNlIGFyZSBhbGlnbmVkIHdpdGggdGhlIHZpZXdwb3J0IGluc3RlYWQgb2YgdGhlIHRpbGUuXG4gKiBUaGlzIHNwYWNlIGlzIHVzZWQgZm9yIHBpdGNoLWFsaWdubWVudD1tYXAsIHJvdGF0aW9uLWFsaWdubWVudD12aWV3cG9ydFxuICpcbiAqICMjIFZpZXdwb3J0IHBpeGVsIGNvb3JkaW5hdGUgc3BhY2VcbiAqICgwLCAwKSBpcyBhdCB0aGUgdG9wIGxlZnQgb2YgdGhlIGNhbnZhcyBhbmQgKHBpeGVsV2lkdGgsIHBpeGVsSGVpZ2h0KSBpcyBhdCB0aGUgYm90dG9tIHJpZ2h0IGNvcm5lclxuICogb2YgdGhlIGNhbnZhcy4gVGhpcyBzcGFjZSBpcyB1c2VkIGZvciBwaXRjaC1hbGlnbm1lbnQ9dmlld3BvcnRcbiAqXG4gKlxuICogIyBWZXJ0ZXggcHJvamVjdGlvblxuICogSXQgZ29lcyByb3VnaGx5IGxpa2UgdGhpczpcbiAqIDEuIHByb2plY3QgdGhlIGFuY2hvciBhbmQgbGluZSBmcm9tIHRpbGUgdW5pdHMgaW50byB0aGUgY29ycmVjdCBsYWJlbCBjb29yZGluYXRlIHNwYWNlXG4gKiAgICAgIC0gbWFwIHBpeGVsIHNwYWNlICAgICAgICAgICBwaXRjaC1hbGlnbm1lbnQ9bWFwICAgICAgICAgcm90YXRpb24tYWxpZ25tZW50PW1hcFxuICogICAgICAtIHJvdGF0ZWQgbWFwIHBpeGVsIHNwYWNlICAgcGl0Y2gtYWxpZ25tZW50PW1hcCAgICAgICAgIHJvdGF0aW9uLWFsaWdubWVudD12aWV3cG9ydFxuICogICAgICAtIHZpZXdwb3J0IHBpeGVsIHNwYWNlICAgICAgcGl0Y2gtYWxpZ25tZW50PXZpZXdwb3J0ICAgIHJvdGF0aW9uLWFsaWdubWVudD0qXG4gKiAyLiBpZiB0aGUgbGFiZWwgZm9sbG93cyBhIGxpbmUsIGZpbmQgdGhlIHBvaW50IGFsb25nIHRoZSBsaW5lIHRoYXQgaXMgdGhlIGNvcnJlY3QgZGlzdGFuY2UgZnJvbSB0aGUgYW5jaG9yLlxuICogMy4gYWRkIHRoZSBnbHlwaCdzIGNvcm5lciBvZmZzZXQgdG8gdGhlIHBvaW50IGZyb20gc3RlcCAzXG4gKiA0LiBjb252ZXJ0IGZyb20gdGhlIGxhYmVsIGNvb3JkaW5hdGUgc3BhY2UgdG8gZ2wgY29vcmRpbmF0ZXNcbiAqXG4gKiBGb3IgaG9yaXpvbnRhbCBsYWJlbHMgd2Ugd2FudCB0byBkbyBzdGVwIDEgaW4gdGhlIHNoYWRlciBmb3IgcGVyZm9ybWFuY2UgcmVhc29ucyAobm8gY3B1IHdvcmspLlxuICogICAgICBUaGlzIGlzIHdoYXQgYHVfbGFiZWxfcGxhbmVfbWF0cml4YCBpcyB1c2VkIGZvci5cbiAqIEZvciBsYWJlbHMgYWxpZ25lZCB3aXRoIGxpbmVzIHdlIGhhdmUgdG8gc3RlcHMgMSBhbmQgMiBvbiB0aGUgY3B1IHNpbmNlIHdlIG5lZWQgYWNjZXNzIHRvIHRoZSBsaW5lIGdlb21ldHJ5LlxuICogICAgICBUaGlzIGlzIHdoYXQgYHVwZGF0ZUxpbmVMYWJlbHMoLi4uKWAgZG9lcy5cbiAqICAgICAgU2luY2UgdGhlIGNvbnZlcnNpb24gaXMgaGFuZGxlZCBvbiB0aGUgY3B1IHdlIGp1c3Qgc2V0IGB1X2xhYmVsX3BsYW5lX21hdHJpeGAgdG8gYW4gaWRlbnRpdHkgbWF0cml4LlxuICpcbiAqIFN0ZXBzIDMgYW5kIDQgYXJlIGRvbmUgaW4gdGhlIHNoYWRlcnMgZm9yIGFsbCBsYWJlbHMuXG4gKi9cblxuLypcbiAqIFJldHVybnMgYSBtYXRyaXggZm9yIGNvbnZlcnRpbmcgZnJvbSB0aWxlIHVuaXRzIHRvIHRoZSBjb3JyZWN0IGxhYmVsIGNvb3JkaW5hdGUgc3BhY2UuXG4gKiBUaGlzIHZhcmlhdGlvbiBvZiB0aGUgZnVuY3Rpb24gcmV0dXJucyBhIGxhYmVsIHNwYWNlIG1hdHJpeCBzcGVjaWFsaXplZCBmb3IgcmVuZGVyaW5nLlxuICogSXQgdHJhbnNmb3JtcyBjb29yZGluYXRlcyBhcy1pcyB0byB3aGF0ZXZlciB0aGUgdGFyZ2V0IHNwYWNlIGlzIChlaXRoZXIgMkQgb3IgM0QpLlxuICogU2VlIGFsc28gYGdldExhYmVsUGxhbmVNYXRyaXhGb3JQbGFjZW1lbnRgXG4gKi9cbmZ1bmN0aW9uIGdldExhYmVsUGxhbmVNYXRyaXhGb3JSZW5kZXJpbmcocG9zTWF0cml4OiBGbG9hdDMyQXJyYXksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbGVJRDogQ2Fub25pY2FsVGlsZUlELFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXRjaFdpdGhNYXA6IGJvb2xlYW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdGF0ZVdpdGhNYXA6IGJvb2xlYW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybTogVHJhbnNmb3JtLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9qZWN0aW9uOiBQcm9qZWN0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXhlbHNUb1RpbGVVbml0czogRmxvYXQzMkFycmF5KTogRmxvYXQzMkFycmF5IHtcbiAgICBjb25zdCBtID0gbWF0NC5jcmVhdGUoKTtcblxuICAgIGlmIChwaXRjaFdpdGhNYXApIHtcbiAgICAgICAgaWYgKHByb2plY3Rpb24ubmFtZSA9PT0gJ2dsb2JlJykge1xuICAgICAgICAgICAgY29uc3QgbG0gPSBjYWxjdWxhdGVHbG9iZUxhYmVsTWF0cml4KHRyYW5zZm9ybSwgdGlsZUlEKTtcbiAgICAgICAgICAgIG1hdDQubXVsdGlwbHkobSwgbSwgbG0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgcyA9IG1hdDIuaW52ZXJ0KFtdLCBwaXhlbHNUb1RpbGVVbml0cyk7XG4gICAgICAgICAgICBtWzBdID0gc1swXTtcbiAgICAgICAgICAgIG1bMV0gPSBzWzFdO1xuICAgICAgICAgICAgbVs0XSA9IHNbMl07XG4gICAgICAgICAgICBtWzVdID0gc1szXTtcbiAgICAgICAgICAgIGlmICghcm90YXRlV2l0aE1hcCkge1xuICAgICAgICAgICAgICAgIG1hdDQucm90YXRlWihtLCBtLCB0cmFuc2Zvcm0uYW5nbGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgbWF0NC5tdWx0aXBseShtLCB0cmFuc2Zvcm0ubGFiZWxQbGFuZU1hdHJpeCwgcG9zTWF0cml4KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbTtcbn1cblxuLypcbiAqIFJldHVybnMgYSBtYXRyaXggZm9yIGNvbnZlcnRpbmcgZnJvbSB0aWxlIHVuaXRzIHRvIHRoZSBjb3JyZWN0IGxhYmVsIGNvb3JkaW5hdGUgc3BhY2UuXG4gKiBUaGlzIHZhcmlhdGlvbiBvZiB0aGUgZnVuY3Rpb24gcmV0dXJucyBhIG1hdHJpeCBzcGVjaWFsaXplZCBmb3IgcGxhY2VtZW50IGxvZ2ljLlxuICogQ29vcmRpbmF0ZXMgd2lsbCBiZSBjbGFtcGVkIHRvIHgmeSAyRCBwbGFuZSB3aGljaCBpcyB1c2VkIHdpdGggdmlld3BvcnQgYW5kIG1hcCBhbGlnbmVkIHBsYWNlbWVudFxuICogbG9naWMgaW4gbW9zdCBjYXNlcy4gQ2VydGFpbiBwcm9qZWN0aW9ucyBzdWNoIGFzIGdsb2JlIHZpZXcgd2lsbCB1c2UgM0Qgc3BhY2UgZm9yIG1hcCBhbGlnbmVkXG4gKiBsYWJlbCBwbGFjZW1lbnQuXG4gKi9cbmZ1bmN0aW9uIGdldExhYmVsUGxhbmVNYXRyaXhGb3JQbGFjZW1lbnQocG9zTWF0cml4OiBGbG9hdDMyQXJyYXksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbGVJRDogQ2Fub25pY2FsVGlsZUlELFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXRjaFdpdGhNYXA6IGJvb2xlYW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdGF0ZVdpdGhNYXA6IGJvb2xlYW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybTogVHJhbnNmb3JtLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9qZWN0aW9uOiBQcm9qZWN0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXhlbHNUb1RpbGVVbml0czogRmxvYXQzMkFycmF5KTogRmxvYXQzMkFycmF5IHtcbiAgICBjb25zdCBtID0gZ2V0TGFiZWxQbGFuZU1hdHJpeEZvclJlbmRlcmluZyhwb3NNYXRyaXgsIHRpbGVJRCwgcGl0Y2hXaXRoTWFwLCByb3RhdGVXaXRoTWFwLCB0cmFuc2Zvcm0sIHByb2plY3Rpb24sIHBpeGVsc1RvVGlsZVVuaXRzKTtcblxuICAgIC8vIFN5bWJvbCBwbGFjZW1lbnQgbG9naWMgaXMgcGVyZm9ybWVkIGluIDJEIGluIG1vc3Qgc2NlbmFyaW9zLlxuICAgIC8vIEZvciB0aGlzIHJlYXNvbiBwcm9qZWN0IGFsbCBjb29yZGluYXRlcyB0byB0aGUgeHktcGxhbmUgYnkgZGlzY2FyZGluZyB0aGUgei1jb21wb25lbnRcbiAgICBpZiAocHJvamVjdGlvbi5uYW1lICE9PSAnZ2xvYmUnIHx8ICFwaXRjaFdpdGhNYXApIHtcbiAgICAgICAgLy8gUHJlLW11bHRpcGx5IGJ5IHNjYWxpbmcgeiB0byAwXG4gICAgICAgIG1bMl0gPSBtWzZdID0gbVsxMF0gPSBtWzE0XSA9IDA7XG4gICAgfVxuXG4gICAgcmV0dXJuIG07XG59XG5cbi8qXG4gKiBSZXR1cm5zIGEgbWF0cml4IGZvciBjb252ZXJ0aW5nIGZyb20gdGhlIGNvcnJlY3QgbGFiZWwgY29vcmRpbmF0ZSBzcGFjZSB0byBnbCBjb29yZHMuXG4gKi9cbmZ1bmN0aW9uIGdldEdsQ29vcmRNYXRyaXgocG9zTWF0cml4OiBGbG9hdDMyQXJyYXksXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRpbGVJRDogQ2Fub25pY2FsVGlsZUlELFxuICAgICAgICAgICAgICAgICAgICAgICAgICBwaXRjaFdpdGhNYXA6IGJvb2xlYW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJvdGF0ZVdpdGhNYXA6IGJvb2xlYW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybTogVHJhbnNmb3JtLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9qZWN0aW9uOiBQcm9qZWN0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBwaXhlbHNUb1RpbGVVbml0czogRmxvYXQzMkFycmF5KTogRmxvYXQzMkFycmF5IHtcbiAgICBpZiAocGl0Y2hXaXRoTWFwKSB7XG4gICAgICAgIGlmIChwcm9qZWN0aW9uLm5hbWUgPT09ICdnbG9iZScpIHtcbiAgICAgICAgICAgIGNvbnN0IG0gPSBnZXRMYWJlbFBsYW5lTWF0cml4Rm9yUmVuZGVyaW5nKHBvc01hdHJpeCwgdGlsZUlELCBwaXRjaFdpdGhNYXAsIHJvdGF0ZVdpdGhNYXAsIHRyYW5zZm9ybSwgcHJvamVjdGlvbiwgcGl4ZWxzVG9UaWxlVW5pdHMpO1xuICAgICAgICAgICAgbWF0NC5pbnZlcnQobSwgbSk7XG4gICAgICAgICAgICBtYXQ0Lm11bHRpcGx5KG0sIHBvc01hdHJpeCwgbSk7XG4gICAgICAgICAgICByZXR1cm4gbTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IG0gPSBtYXQ0LmNsb25lKHBvc01hdHJpeCk7XG4gICAgICAgICAgICBjb25zdCBzID0gbWF0NC5pZGVudGl0eShbXSk7XG4gICAgICAgICAgICBzWzBdID0gcGl4ZWxzVG9UaWxlVW5pdHNbMF07XG4gICAgICAgICAgICBzWzFdID0gcGl4ZWxzVG9UaWxlVW5pdHNbMV07XG4gICAgICAgICAgICBzWzRdID0gcGl4ZWxzVG9UaWxlVW5pdHNbMl07XG4gICAgICAgICAgICBzWzVdID0gcGl4ZWxzVG9UaWxlVW5pdHNbM107XG4gICAgICAgICAgICBtYXQ0Lm11bHRpcGx5KG0sIG0sIHMpO1xuICAgICAgICAgICAgaWYgKCFyb3RhdGVXaXRoTWFwKSB7XG4gICAgICAgICAgICAgICAgbWF0NC5yb3RhdGVaKG0sIG0sIC10cmFuc2Zvcm0uYW5nbGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG07XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdHJhbnNmb3JtLmdsQ29vcmRNYXRyaXg7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBwcm9qZWN0KHg6IG51bWJlciwgeTogbnVtYmVyLCB6OiBudW1iZXIsIG1hdHJpeDogTWF0NCk6IFZlYzQge1xuICAgIGNvbnN0IHBvcyA9IFt4LCB5LCB6LCAxXTtcbiAgICBpZiAoeikge1xuICAgICAgICB2ZWM0LnRyYW5zZm9ybU1hdDQocG9zLCBwb3MsIG1hdHJpeCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgeHlUcmFuc2Zvcm1NYXQ0KHBvcywgcG9zLCBtYXRyaXgpO1xuICAgIH1cbiAgICBjb25zdCB3ID0gcG9zWzNdO1xuICAgIHBvc1swXSAvPSB3O1xuICAgIHBvc1sxXSAvPSB3O1xuICAgIHBvc1syXSAvPSB3O1xuICAgIHJldHVybiBwb3M7XG59XG5cbmZ1bmN0aW9uIHByb2plY3RDbGFtcGVkKFt4LCB5LCB6XTogVmVjMywgbWF0cml4OiBNYXQ0KTogVmVjNCB7XG4gICAgY29uc3QgcG9zID0gW3gsIHksIHosIDFdO1xuICAgIHZlYzQudHJhbnNmb3JtTWF0NChwb3MsIHBvcywgbWF0cml4KTtcblxuICAgIC8vIENsYW1wIGRpc3RhbmNlIHRvIGEgcG9zaXRpdmUgdmFsdWUgc28gd2UgY2FuIGF2b2lkIHNjcmVlbiBjb29yZGluYXRlXG4gICAgLy8gYmVpbmcgZmxpcHBlZCBwb3NzaWJseSBkdWUgdG8gcGVyc3BlY3RpdmUgcHJvamVjdGlvblxuICAgIGNvbnN0IHcgPSBwb3NbM10gPSBNYXRoLm1heChwb3NbM10sIDAuMDAwMDAxKTtcbiAgICBwb3NbMF0gLz0gdztcbiAgICBwb3NbMV0gLz0gdztcbiAgICBwb3NbMl0gLz0gdztcbiAgICByZXR1cm4gcG9zO1xufVxuXG5mdW5jdGlvbiBnZXRQZXJzcGVjdGl2ZVJhdGlvKGNhbWVyYVRvQ2VudGVyRGlzdGFuY2U6IG51bWJlciwgc2lnbmVkRGlzdGFuY2VGcm9tQ2FtZXJhOiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiBNYXRoLm1pbigwLjUgKyAwLjUgKiAoY2FtZXJhVG9DZW50ZXJEaXN0YW5jZSAvIHNpZ25lZERpc3RhbmNlRnJvbUNhbWVyYSksIDEuNSk7XG59XG5cbmZ1bmN0aW9uIGlzVmlzaWJsZShhbmNob3JQb3M6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICAgICAgICAgICAgIGNsaXBwaW5nQnVmZmVyOiBbbnVtYmVyLCBudW1iZXJdKSB7XG4gICAgY29uc3QgeCA9IGFuY2hvclBvc1swXSAvIGFuY2hvclBvc1szXTtcbiAgICBjb25zdCB5ID0gYW5jaG9yUG9zWzFdIC8gYW5jaG9yUG9zWzNdO1xuICAgIGNvbnN0IGluUGFkZGVkVmlld3BvcnQgPSAoXG4gICAgICAgIHggPj0gLWNsaXBwaW5nQnVmZmVyWzBdICYmXG4gICAgICAgIHggPD0gY2xpcHBpbmdCdWZmZXJbMF0gJiZcbiAgICAgICAgeSA+PSAtY2xpcHBpbmdCdWZmZXJbMV0gJiZcbiAgICAgICAgeSA8PSBjbGlwcGluZ0J1ZmZlclsxXSk7XG4gICAgcmV0dXJuIGluUGFkZGVkVmlld3BvcnQ7XG59XG5cbi8qXG4gKiAgVXBkYXRlIHRoZSBgZHluYW1pY0xheW91dFZlcnRleEJ1ZmZlcmAgZm9yIHRoZSBidWZmZXIgd2l0aCB0aGUgY29ycmVjdCBnbHlwaCBwb3NpdGlvbnMgZm9yIHRoZSBjdXJyZW50IG1hcCB2aWV3LlxuICogIFRoaXMgaXMgb25seSBydW4gb24gbGFiZWxzIHRoYXQgYXJlIGFsaWduZWQgd2l0aCBsaW5lcy4gSG9yaXpvbnRhbCBsYWJlbHMgYXJlIGhhbmRsZWQgZW50aXJlbHkgaW4gdGhlIHNoYWRlci5cbiAqL1xuZnVuY3Rpb24gdXBkYXRlTGluZUxhYmVscyhidWNrZXQ6IFN5bWJvbEJ1Y2tldCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zTWF0cml4OiBGbG9hdDMyQXJyYXksXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHBhaW50ZXI6IFBhaW50ZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlzVGV4dDogYm9vbGVhbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxQbGFuZU1hdHJpeDogRmxvYXQzMkFycmF5LFxuICAgICAgICAgICAgICAgICAgICAgICAgICBnbENvb3JkTWF0cml4OiBGbG9hdDMyQXJyYXksXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHBpdGNoV2l0aE1hcDogYm9vbGVhbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAga2VlcFVwcmlnaHQ6IGJvb2xlYW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGdldEVsZXZhdGlvbjogPygocDogUG9pbnQpID0+IEFycmF5PG51bWJlcj4pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aWxlSUQ6IE92ZXJzY2FsZWRUaWxlSUQpIHtcblxuICAgIGNvbnN0IHRyID0gcGFpbnRlci50cmFuc2Zvcm07XG4gICAgY29uc3Qgc2l6ZURhdGEgPSBpc1RleHQgPyBidWNrZXQudGV4dFNpemVEYXRhIDogYnVja2V0Lmljb25TaXplRGF0YTtcbiAgICBjb25zdCBwYXJ0aWFsbHlFdmFsdWF0ZWRTaXplID0gc3ltYm9sU2l6ZS5ldmFsdWF0ZVNpemVGb3Jab29tKHNpemVEYXRhLCBwYWludGVyLnRyYW5zZm9ybS56b29tKTtcbiAgICBjb25zdCBpc0dsb2JlID0gdHIucHJvamVjdGlvbi5uYW1lID09PSAnZ2xvYmUnO1xuXG4gICAgY29uc3QgY2xpcHBpbmdCdWZmZXIgPSBbMjU2IC8gcGFpbnRlci53aWR0aCAqIDIgKyAxLCAyNTYgLyBwYWludGVyLmhlaWdodCAqIDIgKyAxXTtcblxuICAgIGNvbnN0IGR5bmFtaWNMYXlvdXRWZXJ0ZXhBcnJheSA9IGlzVGV4dCA/XG4gICAgICAgIGJ1Y2tldC50ZXh0LmR5bmFtaWNMYXlvdXRWZXJ0ZXhBcnJheSA6XG4gICAgICAgIGJ1Y2tldC5pY29uLmR5bmFtaWNMYXlvdXRWZXJ0ZXhBcnJheTtcbiAgICBkeW5hbWljTGF5b3V0VmVydGV4QXJyYXkuY2xlYXIoKTtcblxuICAgIGxldCBnbG9iZUV4dFZlcnRleEFycmF5OiA/U3ltYm9sR2xvYmVFeHRBcnJheSA9IG51bGw7XG4gICAgaWYgKGlzR2xvYmUpIHtcbiAgICAgICAgZ2xvYmVFeHRWZXJ0ZXhBcnJheSA9IGlzVGV4dCA/XG4gICAgICAgICAgICBidWNrZXQudGV4dC5nbG9iZUV4dFZlcnRleEFycmF5IDpcbiAgICAgICAgICAgIGJ1Y2tldC5pY29uLmdsb2JlRXh0VmVydGV4QXJyYXk7XG4gICAgfVxuXG4gICAgY29uc3QgbGluZVZlcnRleEFycmF5ID0gYnVja2V0LmxpbmVWZXJ0ZXhBcnJheTtcbiAgICBjb25zdCBwbGFjZWRTeW1ib2xzID0gaXNUZXh0ID8gYnVja2V0LnRleHQucGxhY2VkU3ltYm9sQXJyYXkgOiBidWNrZXQuaWNvbi5wbGFjZWRTeW1ib2xBcnJheTtcblxuICAgIGNvbnN0IGFzcGVjdFJhdGlvID0gcGFpbnRlci50cmFuc2Zvcm0ud2lkdGggLyBwYWludGVyLnRyYW5zZm9ybS5oZWlnaHQ7XG5cbiAgICBsZXQgdXNlVmVydGljYWw6ID9ib29sZWFuID0gZmFsc2U7XG4gICAgbGV0IHByZXZXcml0aW5nTW9kZTtcblxuICAgIGZvciAobGV0IHMgPSAwOyBzIDwgcGxhY2VkU3ltYm9scy5sZW5ndGg7IHMrKykge1xuICAgICAgICBjb25zdCBzeW1ib2wgPSBwbGFjZWRTeW1ib2xzLmdldChzKTtcbiAgICAgICAgY29uc3Qge251bUdseXBocywgd3JpdGluZ01vZGV9ID0gc3ltYm9sO1xuXG4gICAgICAgIC8vIE5vcm1hbGx5LCB0aGUgJ0hvcml6b250YWx8VmVydGljYWwnIHdyaXRpbmcgbW9kZSBpcyBmb2xsb3dlZCBieSBhICdWZXJ0aWNhbCcgY291bnRlcnBhcnQsIHRoaXNcbiAgICAgICAgLy8gaXMgbm90IHRydWUgZm9yICdWZXJ0aWNhbCcgb25seSBsaW5lIGxhYmVscy4gRm9yIHRoaXMgY2FzZSwgd2UnbGwgaGF2ZSB0byBvdmVyd3JpdGUgdGhlICd1c2VWZXJ0aWNhbCdcbiAgICAgICAgLy8gc3RhdHVzIGJlZm9yZSBmdXJ0aGVyIGNoZWNrcy5cbiAgICAgICAgaWYgKHdyaXRpbmdNb2RlID09PSBXcml0aW5nTW9kZS52ZXJ0aWNhbCAmJiAhdXNlVmVydGljYWwgJiYgcHJldldyaXRpbmdNb2RlICE9PSBXcml0aW5nTW9kZS5ob3Jpem9udGFsKSB7XG4gICAgICAgICAgICB1c2VWZXJ0aWNhbCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcHJldldyaXRpbmdNb2RlID0gd3JpdGluZ01vZGU7XG5cbiAgICAgICAgLy8gRG9uJ3QgZG8gY2FsY3VsYXRpb25zIGZvciB2ZXJ0aWNhbCBnbHlwaHMgdW5sZXNzIHRoZSBwcmV2aW91cyBzeW1ib2wgd2FzIGhvcml6b250YWxcbiAgICAgICAgLy8gYW5kIHdlIGRldGVybWluZWQgdGhhdCB2ZXJ0aWNhbCBnbHlwaHMgd2VyZSBuZWNlc3NhcnkuXG4gICAgICAgIC8vIEFsc28gZG9uJ3QgZG8gY2FsY3VsYXRpb25zIGZvciBzeW1ib2xzIHRoYXQgYXJlIGNvbGxpZGVkIGFuZCBmdWxseSBmYWRlZCBvdXRcbiAgICAgICAgaWYgKChzeW1ib2wuaGlkZGVuIHx8IHdyaXRpbmdNb2RlID09PSBXcml0aW5nTW9kZS52ZXJ0aWNhbCkgJiYgIXVzZVZlcnRpY2FsKSB7XG4gICAgICAgICAgICBoaWRlR2x5cGhzKG51bUdseXBocywgZHluYW1pY0xheW91dFZlcnRleEFycmF5KTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIC8vIEF3a3dhcmQuLi4gYnV0IHdlJ3JlIGNvdW50aW5nIG9uIHRoZSBwYWlyZWQgXCJ2ZXJ0aWNhbFwiIHN5bWJvbCBjb21pbmcgaW1tZWRpYXRlbHkgYWZ0ZXIgaXRzIGhvcml6b250YWwgY291bnRlcnBhcnRcbiAgICAgICAgdXNlVmVydGljYWwgPSBmYWxzZTtcblxuICAgICAgICAvLyBQcm9qZWN0IHRpbGUgYW5jaG9yIHRvIGdsb2JlIGFuY2hvclxuICAgICAgICBjb25zdCB0aWxlQW5jaG9yUG9pbnQgPSBuZXcgUG9pbnQoc3ltYm9sLnRpbGVBbmNob3JYLCBzeW1ib2wudGlsZUFuY2hvclkpO1xuICAgICAgICBsZXQge3gsIHksIHp9ID0gdHIucHJvamVjdGlvbi5wcm9qZWN0VGlsZVBvaW50KHRpbGVBbmNob3JQb2ludC54LCB0aWxlQW5jaG9yUG9pbnQueSwgdGlsZUlELmNhbm9uaWNhbCk7XG4gICAgICAgIGlmIChnZXRFbGV2YXRpb24pIHtcbiAgICAgICAgICAgIGNvbnN0IFtkeCwgZHksIGR6XSA9IGdldEVsZXZhdGlvbih0aWxlQW5jaG9yUG9pbnQpO1xuICAgICAgICAgICAgeCArPSBkeDtcbiAgICAgICAgICAgIHkgKz0gZHk7XG4gICAgICAgICAgICB6ICs9IGR6O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFuY2hvclBvcyA9IFt4LCB5LCB6LCAxLjBdO1xuICAgICAgICB2ZWM0LnRyYW5zZm9ybU1hdDQoYW5jaG9yUG9zLCBhbmNob3JQb3MsIHBvc01hdHJpeCk7XG5cbiAgICAgICAgLy8gRG9uJ3QgYm90aGVyIGNhbGN1bGF0aW5nIHRoZSBjb3JyZWN0IHBvaW50IGZvciBpbnZpc2libGUgbGFiZWxzLlxuICAgICAgICBpZiAoIWlzVmlzaWJsZShhbmNob3JQb3MsIGNsaXBwaW5nQnVmZmVyKSkge1xuICAgICAgICAgICAgaGlkZUdseXBocyhudW1HbHlwaHMsIGR5bmFtaWNMYXlvdXRWZXJ0ZXhBcnJheSk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjYW1lcmFUb0FuY2hvckRpc3RhbmNlID0gYW5jaG9yUG9zWzNdO1xuICAgICAgICBjb25zdCBwZXJzcGVjdGl2ZVJhdGlvID0gZ2V0UGVyc3BlY3RpdmVSYXRpbyhwYWludGVyLnRyYW5zZm9ybS5jYW1lcmFUb0NlbnRlckRpc3RhbmNlLCBjYW1lcmFUb0FuY2hvckRpc3RhbmNlKTtcblxuICAgICAgICBjb25zdCBmb250U2l6ZSA9IHN5bWJvbFNpemUuZXZhbHVhdGVTaXplRm9yRmVhdHVyZShzaXplRGF0YSwgcGFydGlhbGx5RXZhbHVhdGVkU2l6ZSwgc3ltYm9sKTtcbiAgICAgICAgY29uc3QgcGl0Y2hTY2FsZWRGb250U2l6ZSA9IHBpdGNoV2l0aE1hcCA/IGZvbnRTaXplIC8gcGVyc3BlY3RpdmVSYXRpbyA6IGZvbnRTaXplICogcGVyc3BlY3RpdmVSYXRpbztcblxuICAgICAgICBjb25zdCBsYWJlbFBsYW5lQW5jaG9yUG9pbnQgPSBwcm9qZWN0KHgsIHksIHosIGxhYmVsUGxhbmVNYXRyaXgpO1xuXG4gICAgICAgIC8vIFNraXAgbGFiZWxzIGJlaGluZCB0aGUgY2FtZXJhXG4gICAgICAgIGlmIChsYWJlbFBsYW5lQW5jaG9yUG9pbnRbM10gPD0gMC4wKSB7XG4gICAgICAgICAgICBoaWRlR2x5cGhzKG51bUdseXBocywgZHluYW1pY0xheW91dFZlcnRleEFycmF5KTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHByb2plY3Rpb25DYWNoZTogUHJvamVjdGlvbkNhY2hlID0ge307XG5cbiAgICAgICAgY29uc3QgZ2V0RWxldmF0aW9uRm9yUGxhY2VtZW50ID0gcGl0Y2hXaXRoTWFwID8gbnVsbCA6IGdldEVsZXZhdGlvbjsgLy8gV2hlbiBwaXRjaFdpdGhNYXAsIHdlJ3JlIHByb2plY3RpbmcgdG8gc2NhbGVkIHRpbGUgY29vcmRpbmF0ZSBzcGFjZTogdGhlcmUgaXMgbm8gbmVlZCB0byBnZXQgZWxldmF0aW9uIGFzIGl0IGRvZXNuJ3QgYWZmZWN0IHByb2plY3Rpb24uXG4gICAgICAgIGNvbnN0IHBsYWNlVW5mbGlwcGVkID0gcGxhY2VHbHlwaHNBbG9uZ0xpbmUoc3ltYm9sLCBwaXRjaFNjYWxlZEZvbnRTaXplLCBmYWxzZSAvKnVuZmxpcHBlZCovLCBrZWVwVXByaWdodCwgcG9zTWF0cml4LCBsYWJlbFBsYW5lTWF0cml4LCBnbENvb3JkTWF0cml4LFxuICAgICAgICAgICAgYnVja2V0LmdseXBoT2Zmc2V0QXJyYXksIGxpbmVWZXJ0ZXhBcnJheSwgZHluYW1pY0xheW91dFZlcnRleEFycmF5LCBnbG9iZUV4dFZlcnRleEFycmF5LCBsYWJlbFBsYW5lQW5jaG9yUG9pbnQsIHRpbGVBbmNob3JQb2ludCwgcHJvamVjdGlvbkNhY2hlLCBhc3BlY3RSYXRpbywgZ2V0RWxldmF0aW9uRm9yUGxhY2VtZW50LCB0ci5wcm9qZWN0aW9uLCB0aWxlSUQsIHBpdGNoV2l0aE1hcCk7XG5cbiAgICAgICAgdXNlVmVydGljYWwgPSBwbGFjZVVuZmxpcHBlZC51c2VWZXJ0aWNhbDtcblxuICAgICAgICBpZiAoZ2V0RWxldmF0aW9uRm9yUGxhY2VtZW50ICYmIHBsYWNlVW5mbGlwcGVkLm5lZWRzRmxpcHBpbmcpIHByb2plY3Rpb25DYWNoZSA9IHt9OyAvLyBUcnVuY2F0ZWQgcG9pbnRzIHNob3VsZCBiZSByZWNhbGN1bGF0ZWQuXG4gICAgICAgIGlmIChwbGFjZVVuZmxpcHBlZC5ub3RFbm91Z2hSb29tIHx8IHVzZVZlcnRpY2FsIHx8XG4gICAgICAgICAgICAocGxhY2VVbmZsaXBwZWQubmVlZHNGbGlwcGluZyAmJlxuICAgICAgICAgICAgIHBsYWNlR2x5cGhzQWxvbmdMaW5lKHN5bWJvbCwgcGl0Y2hTY2FsZWRGb250U2l6ZSwgdHJ1ZSAvKmZsaXBwZWQqLywga2VlcFVwcmlnaHQsIHBvc01hdHJpeCwgbGFiZWxQbGFuZU1hdHJpeCwgZ2xDb29yZE1hdHJpeCxcbiAgICAgICAgICAgICAgICAgYnVja2V0LmdseXBoT2Zmc2V0QXJyYXksIGxpbmVWZXJ0ZXhBcnJheSwgZHluYW1pY0xheW91dFZlcnRleEFycmF5LCBnbG9iZUV4dFZlcnRleEFycmF5LCBsYWJlbFBsYW5lQW5jaG9yUG9pbnQsIHRpbGVBbmNob3JQb2ludCwgcHJvamVjdGlvbkNhY2hlLCBhc3BlY3RSYXRpbywgZ2V0RWxldmF0aW9uRm9yUGxhY2VtZW50LCB0ci5wcm9qZWN0aW9uLCB0aWxlSUQsIHBpdGNoV2l0aE1hcCkubm90RW5vdWdoUm9vbSkpIHtcbiAgICAgICAgICAgIGhpZGVHbHlwaHMobnVtR2x5cGhzLCBkeW5hbWljTGF5b3V0VmVydGV4QXJyYXkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGlzVGV4dCkge1xuICAgICAgICBidWNrZXQudGV4dC5keW5hbWljTGF5b3V0VmVydGV4QnVmZmVyLnVwZGF0ZURhdGEoZHluYW1pY0xheW91dFZlcnRleEFycmF5KTtcbiAgICAgICAgaWYgKGdsb2JlRXh0VmVydGV4QXJyYXkpIHtcbiAgICAgICAgICAgIGJ1Y2tldC50ZXh0Lmdsb2JlRXh0VmVydGV4QnVmZmVyLnVwZGF0ZURhdGEoZ2xvYmVFeHRWZXJ0ZXhBcnJheSk7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBidWNrZXQuaWNvbi5keW5hbWljTGF5b3V0VmVydGV4QnVmZmVyLnVwZGF0ZURhdGEoZHluYW1pY0xheW91dFZlcnRleEFycmF5KTtcbiAgICAgICAgaWYgKGdsb2JlRXh0VmVydGV4QXJyYXkpIHtcbiAgICAgICAgICAgIGJ1Y2tldC5pY29uLmdsb2JlRXh0VmVydGV4QnVmZmVyLnVwZGF0ZURhdGEoZ2xvYmVFeHRWZXJ0ZXhBcnJheSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIHBsYWNlRmlyc3RBbmRMYXN0R2x5cGgoXG4gICAgZm9udFNjYWxlOiBudW1iZXIsXG4gICAgZ2x5cGhPZmZzZXRBcnJheTogR2x5cGhPZmZzZXRBcnJheSxcbiAgICBsaW5lT2Zmc2V0WDogbnVtYmVyLFxuICAgIGxpbmVPZmZzZXRZOiBudW1iZXIsXG4gICAgZmxpcDogYm9vbGVhbixcbiAgICBhbmNob3JQb2ludDogVmVjMyxcbiAgICB0aWxlQW5jaG9yUG9pbnQ6IFBvaW50LFxuICAgIHN5bWJvbDogUGxhY2VkU3ltYm9sLFxuICAgIGxpbmVWZXJ0ZXhBcnJheTogU3ltYm9sTGluZVZlcnRleEFycmF5LFxuICAgIGxhYmVsUGxhbmVNYXRyaXg6IEZsb2F0MzJBcnJheSxcbiAgICBwcm9qZWN0aW9uQ2FjaGU6IFByb2plY3Rpb25DYWNoZSxcbiAgICBnZXRFbGV2YXRpb246ID8oKHA6IFBvaW50KSA9PiBBcnJheTxudW1iZXI+KSxcbiAgICByZXR1cm5QYXRoSW5UaWxlQ29vcmRzOiA/Ym9vbGVhbixcbiAgICBwcm9qZWN0aW9uOiBQcm9qZWN0aW9uLFxuICAgIHRpbGVJRDogT3ZlcnNjYWxlZFRpbGVJRCxcbiAgICBwaXRjaFdpdGhNYXA6IGJvb2xlYW4pOiBudWxsIHwge3xmaXJzdDogUGxhY2VkR2x5cGgsIGxhc3Q6IFBsYWNlZEdseXBofH0ge1xuXG4gICAgY29uc3Qge2xpbmVTdGFydEluZGV4LCBnbHlwaFN0YXJ0SW5kZXgsIHNlZ21lbnR9ID0gc3ltYm9sO1xuICAgIGNvbnN0IGdseXBoRW5kSW5kZXggPSBnbHlwaFN0YXJ0SW5kZXggKyBzeW1ib2wubnVtR2x5cGhzO1xuICAgIGNvbnN0IGxpbmVFbmRJbmRleCA9IGxpbmVTdGFydEluZGV4ICsgc3ltYm9sLmxpbmVMZW5ndGg7XG5cbiAgICBjb25zdCBmaXJzdEdseXBoT2Zmc2V0ID0gZ2x5cGhPZmZzZXRBcnJheS5nZXRvZmZzZXRYKGdseXBoU3RhcnRJbmRleCk7XG4gICAgY29uc3QgbGFzdEdseXBoT2Zmc2V0ID0gZ2x5cGhPZmZzZXRBcnJheS5nZXRvZmZzZXRYKGdseXBoRW5kSW5kZXggLSAxKTtcblxuICAgIGNvbnN0IGZpcnN0UGxhY2VkR2x5cGggPSBwbGFjZUdseXBoQWxvbmdMaW5lKGZvbnRTY2FsZSAqIGZpcnN0R2x5cGhPZmZzZXQsIGxpbmVPZmZzZXRYLCBsaW5lT2Zmc2V0WSwgZmxpcCwgYW5jaG9yUG9pbnQsIHRpbGVBbmNob3JQb2ludCwgc2VnbWVudCxcbiAgICAgICAgbGluZVN0YXJ0SW5kZXgsIGxpbmVFbmRJbmRleCwgbGluZVZlcnRleEFycmF5LCBsYWJlbFBsYW5lTWF0cml4LCBwcm9qZWN0aW9uQ2FjaGUsIGdldEVsZXZhdGlvbiwgcmV0dXJuUGF0aEluVGlsZUNvb3JkcywgdHJ1ZSwgcHJvamVjdGlvbiwgdGlsZUlELCBwaXRjaFdpdGhNYXApO1xuICAgIGlmICghZmlyc3RQbGFjZWRHbHlwaClcbiAgICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICBjb25zdCBsYXN0UGxhY2VkR2x5cGggPSBwbGFjZUdseXBoQWxvbmdMaW5lKGZvbnRTY2FsZSAqIGxhc3RHbHlwaE9mZnNldCwgbGluZU9mZnNldFgsIGxpbmVPZmZzZXRZLCBmbGlwLCBhbmNob3JQb2ludCwgdGlsZUFuY2hvclBvaW50LCBzZWdtZW50LFxuICAgICAgICBsaW5lU3RhcnRJbmRleCwgbGluZUVuZEluZGV4LCBsaW5lVmVydGV4QXJyYXksIGxhYmVsUGxhbmVNYXRyaXgsIHByb2plY3Rpb25DYWNoZSwgZ2V0RWxldmF0aW9uLCByZXR1cm5QYXRoSW5UaWxlQ29vcmRzLCB0cnVlLCBwcm9qZWN0aW9uLCB0aWxlSUQsIHBpdGNoV2l0aE1hcCk7XG4gICAgaWYgKCFsYXN0UGxhY2VkR2x5cGgpXG4gICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgcmV0dXJuIHtmaXJzdDogZmlyc3RQbGFjZWRHbHlwaCwgbGFzdDogbGFzdFBsYWNlZEdseXBofTtcbn1cblxuLy8gQ2hlY2sgaW4gdGhlIGdsQ29vcmRpbmF0ZSBzcGFjZSwgdGhlIHJvdWdoIGVzdGltYXRpb24gb2YgYW5nbGUgYmV0d2VlbiB0aGUgdGV4dCBsaW5lIGFuZCB0aGUgWSBheGlzLlxuLy8gSWYgdGhlIGFuZ2xlIGlmIGxlc3Mgb3IgZXF1YWwgdG8gNSBkZWdyZWUsIHRoZW4ga2VlcCB0aGUgdGV4dCBnbHlwaHMgdW5mbGlwcGVkIGV2ZW4gaWYgaXQgaXMgcmVxdWlyZWQuXG5mdW5jdGlvbiBpc0luRmxpcFJldGFpblJhbmdlKGR4OiBudW1iZXIsIGR5OiBudW1iZXIpIHtcbiAgICByZXR1cm4gZHggPT09IDAgfHwgTWF0aC5hYnMoZHkgLyBkeCkgPiBtYXhUYW5nZW50O1xufVxuXG5mdW5jdGlvbiByZXF1aXJlc09yaWVudGF0aW9uQ2hhbmdlKHdyaXRpbmdNb2RlOiBudW1iZXIsIGZsaXBTdGF0ZTogbnVtYmVyLCBkeDogbnVtYmVyLCBkeTogbnVtYmVyKSB7XG4gICAgaWYgKHdyaXRpbmdNb2RlID09PSBXcml0aW5nTW9kZS5ob3Jpem9udGFsICYmIE1hdGguYWJzKGR5KSA+IE1hdGguYWJzKGR4KSkge1xuICAgICAgICAvLyBPbiB0b3Agb2YgY2hvb3Npbmcgd2hldGhlciB0byBmbGlwLCBjaG9vc2Ugd2hldGhlciB0byByZW5kZXIgdGhpcyB2ZXJzaW9uIG9mIHRoZSBnbHlwaHMgb3IgdGhlIGFsdGVybmF0ZVxuICAgICAgICAvLyB2ZXJ0aWNhbCBnbHlwaHMuIFdlIGNhbid0IGp1c3QgZmlsdGVyIG91dCB2ZXJ0aWNhbCBnbHlwaHMgaW4gdGhlIGhvcml6b250YWwgcmFuZ2UgYmVjYXVzZSB0aGUgaG9yaXpvbnRhbFxuICAgICAgICAvLyBhbmQgdmVydGljYWwgdmVyc2lvbnMgY2FuIGhhdmUgc2xpZ2h0bHkgZGlmZmVyZW50IHByb2plY3Rpb25zIHdoaWNoIGNvdWxkIGxlYWQgdG8gYW5nbGVzIHdoZXJlIGJvdGggb3JcbiAgICAgICAgLy8gbmVpdGhlciBzaG93ZWQuXG4gICAgICAgIHJldHVybiB7dXNlVmVydGljYWw6IHRydWV9O1xuICAgIH1cbiAgICAvLyBDaGVjayBpZiBmbGlwcGluZyBpcyByZXF1aXJlZCBmb3IgXCJ2ZXJ0aWNhbE9ubHlcIiBjYXNlLlxuICAgIGlmICh3cml0aW5nTW9kZSA9PT0gV3JpdGluZ01vZGUudmVydGljYWwpIHtcbiAgICAgICAgcmV0dXJuIGR5ID4gMCA/IHtuZWVkc0ZsaXBwaW5nOiB0cnVlfSA6IG51bGw7XG4gICAgfVxuXG4gICAgLy8gc3ltYm9sJ3MgZmxpcFN0YXRlIHN0b3JlcyB0aGUgZmxpcCBkZWNpc2lvbiBmcm9tIHRoZSBwcmV2aW91cyBmcmFtZSwgYW5kIHRoYXRcbiAgICAvLyBkZWNpc2lvbiBpcyByZXVzZWQgd2hlbiB0aGUgc3ltYm9sIGlzIGluIHRoZSByZXRhaW4gcmFuZ2UuXG4gICAgaWYgKGZsaXBTdGF0ZSAhPT0gRmxpcFN0YXRlLnVua25vd24gJiYgaXNJbkZsaXBSZXRhaW5SYW5nZShkeCwgZHkpKSB7XG4gICAgICAgIHJldHVybiAoZmxpcFN0YXRlID09PSBGbGlwU3RhdGUuZmxpcFJlcXVpcmVkKSA/IHtuZWVkc0ZsaXBwaW5nOiB0cnVlfSA6IG51bGw7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgZmxpcHBpbmcgaXMgcmVxdWlyZWQgZm9yIFwiaG9yaXpvbnRhbFwiIGNhc2UuXG4gICAgcmV0dXJuIGR4IDwgMCA/IHtuZWVkc0ZsaXBwaW5nOiB0cnVlfSA6IG51bGw7XG59XG5cbmZ1bmN0aW9uIHBsYWNlR2x5cGhzQWxvbmdMaW5lKHN5bWJvbDogUGxhY2VkU3ltYm9sLCBmb250U2l6ZTogbnVtYmVyLCBmbGlwOiBib29sZWFuLCBrZWVwVXByaWdodDogYm9vbGVhbiwgcG9zTWF0cml4OiBGbG9hdDMyQXJyYXksIGxhYmVsUGxhbmVNYXRyaXg6IEZsb2F0MzJBcnJheSwgZ2xDb29yZE1hdHJpeDogRmxvYXQzMkFycmF5LCBnbHlwaE9mZnNldEFycmF5OiBHbHlwaE9mZnNldEFycmF5LCBsaW5lVmVydGV4QXJyYXk6IFN5bWJvbExpbmVWZXJ0ZXhBcnJheSwgZHluYW1pY0xheW91dFZlcnRleEFycmF5OiBTeW1ib2xEeW5hbWljTGF5b3V0QXJyYXksIGdsb2JlRXh0VmVydGV4QXJyYXk6ID9TeW1ib2xHbG9iZUV4dEFycmF5LCBhbmNob3JQb2ludDogVmVjVHlwZSwgdGlsZUFuY2hvclBvaW50OiBQb2ludCwgcHJvamVjdGlvbkNhY2hlOiBQcm9qZWN0aW9uQ2FjaGUsIGFzcGVjdFJhdGlvOiBudW1iZXIsIGdldEVsZXZhdGlvbjogPygocDogUG9pbnQpID0+IEFycmF5PG51bWJlcj4pLCBwcm9qZWN0aW9uOiBQcm9qZWN0aW9uLCB0aWxlSUQ6IE92ZXJzY2FsZWRUaWxlSUQsIHBpdGNoV2l0aE1hcDogYm9vbGVhbik6IFBsYWNlbWVudFN0YXR1cyB7XG4gICAgY29uc3QgZm9udFNjYWxlID0gZm9udFNpemUgLyAyNDtcbiAgICBjb25zdCBsaW5lT2Zmc2V0WCA9IHN5bWJvbC5saW5lT2Zmc2V0WCAqIGZvbnRTY2FsZTtcbiAgICBjb25zdCBsaW5lT2Zmc2V0WSA9IHN5bWJvbC5saW5lT2Zmc2V0WSAqIGZvbnRTY2FsZTtcbiAgICBjb25zdCB7bGluZVN0YXJ0SW5kZXgsIGdseXBoU3RhcnRJbmRleCwgbnVtR2x5cGhzLCBzZWdtZW50LCB3cml0aW5nTW9kZSwgZmxpcFN0YXRlfSA9IHN5bWJvbDtcbiAgICBjb25zdCBsaW5lRW5kSW5kZXggPSBsaW5lU3RhcnRJbmRleCArIHN5bWJvbC5saW5lTGVuZ3RoO1xuXG4gICAgY29uc3QgYWRkR2x5cGggPSAoZ2x5cGg6IFBsYWNlZEdseXBoKSA9PiB7XG4gICAgICAgIGlmIChnbG9iZUV4dFZlcnRleEFycmF5KSB7XG4gICAgICAgICAgICBjb25zdCBbdXgsIHV5LCB1el0gPSBnbHlwaC51cDtcbiAgICAgICAgICAgIGNvbnN0IG9mZnNldCA9IGR5bmFtaWNMYXlvdXRWZXJ0ZXhBcnJheS5sZW5ndGg7XG4gICAgICAgICAgICB1cGRhdGVHbG9iZVZlcnRleE5vcm1hbChnbG9iZUV4dFZlcnRleEFycmF5LCBvZmZzZXQgKyAwLCB1eCwgdXksIHV6KTtcbiAgICAgICAgICAgIHVwZGF0ZUdsb2JlVmVydGV4Tm9ybWFsKGdsb2JlRXh0VmVydGV4QXJyYXksIG9mZnNldCArIDEsIHV4LCB1eSwgdXopO1xuICAgICAgICAgICAgdXBkYXRlR2xvYmVWZXJ0ZXhOb3JtYWwoZ2xvYmVFeHRWZXJ0ZXhBcnJheSwgb2Zmc2V0ICsgMiwgdXgsIHV5LCB1eik7XG4gICAgICAgICAgICB1cGRhdGVHbG9iZVZlcnRleE5vcm1hbChnbG9iZUV4dFZlcnRleEFycmF5LCBvZmZzZXQgKyAzLCB1eCwgdXksIHV6KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBbeCwgeSwgel0gPSBnbHlwaC5wb2ludDtcbiAgICAgICAgYWRkRHluYW1pY0F0dHJpYnV0ZXMoZHluYW1pY0xheW91dFZlcnRleEFycmF5LCB4LCB5LCB6LCBnbHlwaC5hbmdsZSk7XG4gICAgfTtcblxuICAgIGlmIChudW1HbHlwaHMgPiAxKSB7XG4gICAgICAgIC8vIFBsYWNlIHRoZSBmaXJzdCBhbmQgdGhlIGxhc3QgZ2x5cGggaW4gdGhlIGxhYmVsIGZpcnN0LCBzbyB3ZSBjYW4gZmlndXJlIG91dFxuICAgICAgICAvLyB0aGUgb3ZlcmFsbCBvcmllbnRhdGlvbiBvZiB0aGUgbGFiZWwgYW5kIGRldGVybWluZSB3aGV0aGVyIGl0IG5lZWRzIHRvIGJlIGZsaXBwZWQgaW4ga2VlcFVwcmlnaHQgbW9kZVxuICAgICAgICBjb25zdCBmaXJzdEFuZExhc3RHbHlwaCA9IHBsYWNlRmlyc3RBbmRMYXN0R2x5cGgoZm9udFNjYWxlLCBnbHlwaE9mZnNldEFycmF5LCBsaW5lT2Zmc2V0WCwgbGluZU9mZnNldFksIGZsaXAsIGFuY2hvclBvaW50LCB0aWxlQW5jaG9yUG9pbnQsIHN5bWJvbCwgbGluZVZlcnRleEFycmF5LCBsYWJlbFBsYW5lTWF0cml4LCBwcm9qZWN0aW9uQ2FjaGUsIGdldEVsZXZhdGlvbiwgZmFsc2UsIHByb2plY3Rpb24sIHRpbGVJRCwgcGl0Y2hXaXRoTWFwKTtcbiAgICAgICAgaWYgKCFmaXJzdEFuZExhc3RHbHlwaCkge1xuICAgICAgICAgICAgcmV0dXJuIHtub3RFbm91Z2hSb29tOiB0cnVlfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChrZWVwVXByaWdodCAmJiAhZmxpcCkge1xuICAgICAgICAgICAgbGV0IFt4MCwgeTAsIHowXSA9IGZpcnN0QW5kTGFzdEdseXBoLmZpcnN0LnBvaW50O1xuICAgICAgICAgICAgbGV0IFt4MSwgeTEsIHoxXSA9IGZpcnN0QW5kTGFzdEdseXBoLmxhc3QucG9pbnQ7XG4gICAgICAgICAgICBbeDAsIHkwXSA9IHByb2plY3QoeDAsIHkwLCB6MCwgZ2xDb29yZE1hdHJpeCk7XG4gICAgICAgICAgICBbeDEsIHkxXSA9IHByb2plY3QoeDEsIHkxLCB6MSwgZ2xDb29yZE1hdHJpeCk7XG4gICAgICAgICAgICBjb25zdCBvcmllbnRhdGlvbkNoYW5nZSA9IHJlcXVpcmVzT3JpZW50YXRpb25DaGFuZ2Uod3JpdGluZ01vZGUsIGZsaXBTdGF0ZSwgKHgxIC0geDApICogYXNwZWN0UmF0aW8sIHkxIC0geTApO1xuICAgICAgICAgICAgc3ltYm9sLmZsaXBTdGF0ZSA9IG9yaWVudGF0aW9uQ2hhbmdlICYmIG9yaWVudGF0aW9uQ2hhbmdlLm5lZWRzRmxpcHBpbmcgPyBGbGlwU3RhdGUuZmxpcFJlcXVpcmVkIDogRmxpcFN0YXRlLmZsaXBOb3RSZXF1aXJlZDtcbiAgICAgICAgICAgIGlmIChvcmllbnRhdGlvbkNoYW5nZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcmllbnRhdGlvbkNoYW5nZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGFkZEdseXBoKGZpcnN0QW5kTGFzdEdseXBoLmZpcnN0KTtcbiAgICAgICAgZm9yIChsZXQgZ2x5cGhJbmRleCA9IGdseXBoU3RhcnRJbmRleCArIDE7IGdseXBoSW5kZXggPCBnbHlwaFN0YXJ0SW5kZXggKyBudW1HbHlwaHMgLSAxOyBnbHlwaEluZGV4KyspIHtcbiAgICAgICAgICAgIC8vIFNpbmNlIGZpcnN0IGFuZCBsYXN0IGdseXBoIGZpdCBvbiB0aGUgbGluZSwgdGhlIHJlc3Qgb2YgdGhlIGdseXBocyBjYW4gYmUgcGxhY2VkIHRvbywgYnV0IGNoZWNrIHRvIG1ha2Ugc3VyZVxuICAgICAgICAgICAgY29uc3QgZ2x5cGggPSBwbGFjZUdseXBoQWxvbmdMaW5lKGZvbnRTY2FsZSAqIGdseXBoT2Zmc2V0QXJyYXkuZ2V0b2Zmc2V0WChnbHlwaEluZGV4KSwgbGluZU9mZnNldFgsIGxpbmVPZmZzZXRZLCBmbGlwLCBhbmNob3JQb2ludCwgdGlsZUFuY2hvclBvaW50LCBzZWdtZW50LFxuICAgICAgICAgICAgICAgIGxpbmVTdGFydEluZGV4LCBsaW5lRW5kSW5kZXgsIGxpbmVWZXJ0ZXhBcnJheSwgbGFiZWxQbGFuZU1hdHJpeCwgcHJvamVjdGlvbkNhY2hlLCBnZXRFbGV2YXRpb24sIGZhbHNlLCBmYWxzZSwgcHJvamVjdGlvbiwgdGlsZUlELCBwaXRjaFdpdGhNYXApO1xuICAgICAgICAgICAgaWYgKCFnbHlwaCkge1xuICAgICAgICAgICAgICAgIC8vIHVuZG8gcHJldmlvdXMgZ2x5cGhzIG9mIHRoZSBzeW1ib2wgaWYgaXQgZG9lc24ndCBmaXQ7IGl0IHdpbGwgYmUgZmlsbGVkIHdpdGggaGlkZUdseXBocyBpbnN0ZWFkXG4gICAgICAgICAgICAgICAgZHluYW1pY0xheW91dFZlcnRleEFycmF5Lmxlbmd0aCAtPSA0ICogKGdseXBoSW5kZXggLSBnbHlwaFN0YXJ0SW5kZXgpO1xuICAgICAgICAgICAgICAgIHJldHVybiB7bm90RW5vdWdoUm9vbTogdHJ1ZX07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhZGRHbHlwaChnbHlwaCk7XG4gICAgICAgIH1cbiAgICAgICAgYWRkR2x5cGgoZmlyc3RBbmRMYXN0R2x5cGgubGFzdCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gT25seSBhIHNpbmdsZSBnbHlwaCB0byBwbGFjZVxuICAgICAgICAvLyBTbywgZGV0ZXJtaW5lIHdoZXRoZXIgdG8gZmxpcCBiYXNlZCBvbiBwcm9qZWN0ZWQgYW5nbGUgb2YgdGhlIGxpbmUgc2VnbWVudCBpdCdzIG9uXG4gICAgICAgIGlmIChrZWVwVXByaWdodCAmJiAhZmxpcCkge1xuICAgICAgICAgICAgY29uc3QgYSA9IHByb2plY3QodGlsZUFuY2hvclBvaW50LngsIHRpbGVBbmNob3JQb2ludC55LCAwLCBwb3NNYXRyaXgpO1xuICAgICAgICAgICAgY29uc3QgdGlsZVZlcnRleEluZGV4ID0gbGluZVN0YXJ0SW5kZXggKyBzZWdtZW50ICsgMTtcbiAgICAgICAgICAgIGNvbnN0IHRpbGVTZWdtZW50RW5kID0gbmV3IFBvaW50KGxpbmVWZXJ0ZXhBcnJheS5nZXR4KHRpbGVWZXJ0ZXhJbmRleCksIGxpbmVWZXJ0ZXhBcnJheS5nZXR5KHRpbGVWZXJ0ZXhJbmRleCkpO1xuICAgICAgICAgICAgY29uc3QgcHJvamVjdGVkVmVydGV4ID0gcHJvamVjdCh0aWxlU2VnbWVudEVuZC54LCB0aWxlU2VnbWVudEVuZC55LCAwLCBwb3NNYXRyaXgpO1xuICAgICAgICAgICAgLy8gV2Uga25vdyB0aGUgYW5jaG9yIHdpbGwgYmUgaW4gdGhlIHZpZXdwb3J0LCBidXQgdGhlIGVuZCBvZiB0aGUgbGluZSBzZWdtZW50IG1heSBiZVxuICAgICAgICAgICAgLy8gYmVoaW5kIHRoZSBwbGFuZSBvZiB0aGUgY2FtZXJhLCBpbiB3aGljaCBjYXNlIHdlIGNhbiB1c2UgYSBwb2ludCBhdCBhbnkgYXJiaXRyYXJ5IChjbG9zZXIpXG4gICAgICAgICAgICAvLyBwb2ludCBvbiB0aGUgc2VnbWVudC5cbiAgICAgICAgICAgIGNvbnN0IGIgPSAocHJvamVjdGVkVmVydGV4WzNdID4gMCkgP1xuICAgICAgICAgICAgICAgIHByb2plY3RlZFZlcnRleCA6XG4gICAgICAgICAgICAgICAgcHJvamVjdFRydW5jYXRlZExpbmVTZWdtZW50KHRpbGVBbmNob3JQb2ludCwgdGlsZVNlZ21lbnRFbmQsIGEsIDEsIHBvc01hdHJpeCwgdW5kZWZpbmVkLCBwcm9qZWN0aW9uLCB0aWxlSUQuY2Fub25pY2FsKTtcblxuICAgICAgICAgICAgY29uc3Qgb3JpZW50YXRpb25DaGFuZ2UgPSByZXF1aXJlc09yaWVudGF0aW9uQ2hhbmdlKHdyaXRpbmdNb2RlLCBmbGlwU3RhdGUsIChiWzBdIC0gYVswXSkgKiBhc3BlY3RSYXRpbywgYlsxXSAtIGFbMV0pO1xuICAgICAgICAgICAgc3ltYm9sLmZsaXBTdGF0ZSA9IG9yaWVudGF0aW9uQ2hhbmdlICYmIG9yaWVudGF0aW9uQ2hhbmdlLm5lZWRzRmxpcHBpbmcgPyBGbGlwU3RhdGUuZmxpcFJlcXVpcmVkIDogRmxpcFN0YXRlLmZsaXBOb3RSZXF1aXJlZDtcbiAgICAgICAgICAgIGlmIChvcmllbnRhdGlvbkNoYW5nZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcmllbnRhdGlvbkNoYW5nZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzaW5nbGVHbHlwaCA9IHBsYWNlR2x5cGhBbG9uZ0xpbmUoZm9udFNjYWxlICogZ2x5cGhPZmZzZXRBcnJheS5nZXRvZmZzZXRYKGdseXBoU3RhcnRJbmRleCksIGxpbmVPZmZzZXRYLCBsaW5lT2Zmc2V0WSwgZmxpcCwgYW5jaG9yUG9pbnQsIHRpbGVBbmNob3JQb2ludCwgc2VnbWVudCxcbiAgICAgICAgICAgIGxpbmVTdGFydEluZGV4LCBsaW5lRW5kSW5kZXgsIGxpbmVWZXJ0ZXhBcnJheSwgbGFiZWxQbGFuZU1hdHJpeCwgcHJvamVjdGlvbkNhY2hlLCBnZXRFbGV2YXRpb24sIGZhbHNlLCBmYWxzZSwgcHJvamVjdGlvbiwgdGlsZUlELCBwaXRjaFdpdGhNYXApO1xuICAgICAgICBpZiAoIXNpbmdsZUdseXBoKSB7XG4gICAgICAgICAgICByZXR1cm4ge25vdEVub3VnaFJvb206IHRydWV9O1xuICAgICAgICB9XG5cbiAgICAgICAgYWRkR2x5cGgoc2luZ2xlR2x5cGgpO1xuICAgIH1cbiAgICByZXR1cm4ge307XG59XG5cbmZ1bmN0aW9uIGVsZXZhdGVQb2ludEFuZFByb2plY3QocDogUG9pbnQsIHRpbGVJRDogQ2Fub25pY2FsVGlsZUlELCBwb3NNYXRyaXg6IEZsb2F0MzJBcnJheSwgcHJvamVjdGlvbjogUHJvamVjdGlvbiwgZ2V0RWxldmF0aW9uOiA/KChwOiBQb2ludCkgPT4gQXJyYXk8bnVtYmVyPikpIHtcbiAgICBjb25zdCB7eCwgeSwgen0gPSBwcm9qZWN0aW9uLnByb2plY3RUaWxlUG9pbnQocC54LCBwLnksIHRpbGVJRCk7XG4gICAgaWYgKCFnZXRFbGV2YXRpb24pIHtcbiAgICAgICAgcmV0dXJuIHByb2plY3QoeCwgeSwgeiwgcG9zTWF0cml4KTtcbiAgICB9XG4gICAgY29uc3QgW2R4LCBkeSwgZHpdID0gZ2V0RWxldmF0aW9uKHApO1xuICAgIHJldHVybiBwcm9qZWN0KHggKyBkeCwgeSArIGR5LCB6ICsgZHosIHBvc01hdHJpeCk7XG59XG5cbmZ1bmN0aW9uIHByb2plY3RUcnVuY2F0ZWRMaW5lU2VnbWVudChwcmV2aW91c1RpbGVQb2ludDogUG9pbnQsIGN1cnJlbnRUaWxlUG9pbnQ6IFBvaW50LCBwcmV2aW91c1Byb2plY3RlZFBvaW50OiBWZWMzLCBtaW5pbXVtTGVuZ3RoOiBudW1iZXIsIHByb2plY3Rpb25NYXRyaXg6IEZsb2F0MzJBcnJheSwgZ2V0RWxldmF0aW9uOiA/KChwOiBQb2ludCkgPT4gQXJyYXk8bnVtYmVyPiksIHByb2plY3Rpb246IFByb2plY3Rpb24sIHRpbGVJRDogQ2Fub25pY2FsVGlsZUlEKTogVmVjMyB7XG4gICAgLy8gV2UgYXJlIGFzc3VtaW5nIFwicHJldmlvdXNUaWxlUG9pbnRcIiB3b24ndCBwcm9qZWN0IHRvIGEgcG9pbnQgd2l0aGluIG9uZSB1bml0IG9mIHRoZSBjYW1lcmEgcGxhbmVcbiAgICAvLyBJZiBpdCBkaWQsIHRoYXQgd291bGQgbWVhbiBvdXIgbGFiZWwgZXh0ZW5kZWQgYWxsIHRoZSB3YXkgb3V0IGZyb20gd2l0aGluIHRoZSB2aWV3cG9ydCB0byBhICh2ZXJ5IGRpc3RhbnQpXG4gICAgLy8gcG9pbnQgbmVhciB0aGUgcGxhbmUgb2YgdGhlIGNhbWVyYS4gV2Ugd291bGRuJ3QgYmUgYWJsZSB0byByZW5kZXIgdGhlIGxhYmVsIGFueXdheSBvbmNlIGl0IGNyb3NzZWQgdGhlXG4gICAgLy8gcGxhbmUgb2YgdGhlIGNhbWVyYS5cbiAgICBjb25zdCB1bml0VmVydGV4ID0gcHJldmlvdXNUaWxlUG9pbnQuc3ViKGN1cnJlbnRUaWxlUG9pbnQpLl91bml0KCkuX2FkZChwcmV2aW91c1RpbGVQb2ludCk7XG4gICAgY29uc3QgcHJvamVjdGVkVW5pdCA9IGVsZXZhdGVQb2ludEFuZFByb2plY3QodW5pdFZlcnRleCwgdGlsZUlELCBwcm9qZWN0aW9uTWF0cml4LCBwcm9qZWN0aW9uLCBnZXRFbGV2YXRpb24pO1xuICAgIHZlYzMuc3ViKHByb2plY3RlZFVuaXQsIHByZXZpb3VzUHJvamVjdGVkUG9pbnQsIHByb2plY3RlZFVuaXQpO1xuICAgIHZlYzMubm9ybWFsaXplKHByb2plY3RlZFVuaXQsIHByb2plY3RlZFVuaXQpO1xuXG4gICAgcmV0dXJuIHZlYzMuc2NhbGVBbmRBZGQocHJvamVjdGVkVW5pdCwgcHJldmlvdXNQcm9qZWN0ZWRQb2ludCwgcHJvamVjdGVkVW5pdCwgbWluaW11bUxlbmd0aCk7XG59XG5cbmZ1bmN0aW9uIHBsYWNlR2x5cGhBbG9uZ0xpbmUoXG4gICAgb2Zmc2V0WDogbnVtYmVyLFxuICAgIGxpbmVPZmZzZXRYOiBudW1iZXIsXG4gICAgbGluZU9mZnNldFk6IG51bWJlcixcbiAgICBmbGlwOiBib29sZWFuLFxuICAgIGFuY2hvclBvaW50OiBWZWMzLFxuICAgIHRpbGVBbmNob3JQb2ludDogUG9pbnQsXG4gICAgYW5jaG9yU2VnbWVudDogbnVtYmVyLFxuICAgIGxpbmVTdGFydEluZGV4OiBudW1iZXIsXG4gICAgbGluZUVuZEluZGV4OiBudW1iZXIsXG4gICAgbGluZVZlcnRleEFycmF5OiBTeW1ib2xMaW5lVmVydGV4QXJyYXksXG4gICAgbGFiZWxQbGFuZU1hdHJpeDogRmxvYXQzMkFycmF5LFxuICAgIHByb2plY3Rpb25DYWNoZTogUHJvamVjdGlvbkNhY2hlLFxuICAgIGdldEVsZXZhdGlvbjogPygocDogUG9pbnQpID0+IEFycmF5PG51bWJlcj4pLFxuICAgIHJldHVyblBhdGhJblRpbGVDb29yZHM6ID9ib29sZWFuLFxuICAgIGVuZEdseXBoOiA/Ym9vbGVhbixcbiAgICByZXByb2plY3Rpb246IFByb2plY3Rpb24sXG4gICAgdGlsZUlEOiBPdmVyc2NhbGVkVGlsZUlELFxuICAgIHBpdGNoV2l0aE1hcDogYm9vbGVhbik6IG51bGwgfCBQbGFjZWRHbHlwaCB7XG5cbiAgICBjb25zdCBjb21iaW5lZE9mZnNldFggPSBmbGlwID9cbiAgICAgICAgb2Zmc2V0WCAtIGxpbmVPZmZzZXRYIDpcbiAgICAgICAgb2Zmc2V0WCArIGxpbmVPZmZzZXRYO1xuXG4gICAgbGV0IGRpciA9IGNvbWJpbmVkT2Zmc2V0WCA+IDAgPyAxIDogLTE7XG5cbiAgICBsZXQgYW5nbGUgPSAwO1xuICAgIGlmIChmbGlwKSB7XG4gICAgICAgIC8vIFRoZSBsYWJlbCBuZWVkcyB0byBiZSBmbGlwcGVkIHRvIGtlZXAgdGV4dCB1cHJpZ2h0LlxuICAgICAgICAvLyBJdGVyYXRlIGluIHRoZSByZXZlcnNlIGRpcmVjdGlvbi5cbiAgICAgICAgZGlyICo9IC0xO1xuICAgICAgICBhbmdsZSA9IE1hdGguUEk7XG4gICAgfVxuXG4gICAgaWYgKGRpciA8IDApIGFuZ2xlICs9IE1hdGguUEk7XG5cbiAgICBsZXQgY3VycmVudEluZGV4ID0gbGluZVN0YXJ0SW5kZXggKyBhbmNob3JTZWdtZW50ICsgKGRpciA+IDAgPyAwIDogMSkgfCAwO1xuICAgIGxldCBjdXJyZW50ID0gYW5jaG9yUG9pbnQ7XG4gICAgbGV0IHByZXYgPSBhbmNob3JQb2ludDtcbiAgICBsZXQgZGlzdGFuY2VUb1ByZXYgPSAwO1xuICAgIGxldCBjdXJyZW50U2VnbWVudERpc3RhbmNlID0gMDtcbiAgICBjb25zdCBhYnNPZmZzZXRYID0gTWF0aC5hYnMoY29tYmluZWRPZmZzZXRYKTtcbiAgICBjb25zdCBwYXRoVmVydGljZXMgPSBbXTtcbiAgICBjb25zdCB0aWxlUGF0aCA9IFtdO1xuICAgIGxldCBjdXJyZW50VmVydGV4ID0gdGlsZUFuY2hvclBvaW50O1xuICAgIGxldCBwcmV2VmVydGV4ID0gY3VycmVudFZlcnRleDtcblxuICAgIGNvbnN0IGdldFRydW5jYXRlZExpbmVTZWdtZW50ID0gKCkgPT4ge1xuICAgICAgICByZXR1cm4gcHJvamVjdFRydW5jYXRlZExpbmVTZWdtZW50KHByZXZWZXJ0ZXgsIGN1cnJlbnRWZXJ0ZXgsIHByZXYsIGFic09mZnNldFggLSBkaXN0YW5jZVRvUHJldiArIDEsIGxhYmVsUGxhbmVNYXRyaXgsIGdldEVsZXZhdGlvbiwgcmVwcm9qZWN0aW9uLCB0aWxlSUQuY2Fub25pY2FsKTtcbiAgICB9O1xuXG4gICAgd2hpbGUgKGRpc3RhbmNlVG9QcmV2ICsgY3VycmVudFNlZ21lbnREaXN0YW5jZSA8PSBhYnNPZmZzZXRYKSB7XG4gICAgICAgIGN1cnJlbnRJbmRleCArPSBkaXI7XG5cbiAgICAgICAgLy8gb2Zmc2V0IGRvZXMgbm90IGZpdCBvbiB0aGUgcHJvamVjdGVkIGxpbmVcbiAgICAgICAgaWYgKGN1cnJlbnRJbmRleCA8IGxpbmVTdGFydEluZGV4IHx8IGN1cnJlbnRJbmRleCA+PSBsaW5lRW5kSW5kZXgpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcblxuICAgICAgICBwcmV2ID0gY3VycmVudDtcbiAgICAgICAgcHJldlZlcnRleCA9IGN1cnJlbnRWZXJ0ZXg7XG5cbiAgICAgICAgcGF0aFZlcnRpY2VzLnB1c2gocHJldik7XG4gICAgICAgIGlmIChyZXR1cm5QYXRoSW5UaWxlQ29vcmRzKSB0aWxlUGF0aC5wdXNoKHByZXZWZXJ0ZXgpO1xuXG4gICAgICAgIGN1cnJlbnRWZXJ0ZXggPSBuZXcgUG9pbnQobGluZVZlcnRleEFycmF5LmdldHgoY3VycmVudEluZGV4KSwgbGluZVZlcnRleEFycmF5LmdldHkoY3VycmVudEluZGV4KSk7XG4gICAgICAgIGN1cnJlbnQgPSBwcm9qZWN0aW9uQ2FjaGVbY3VycmVudEluZGV4XTtcbiAgICAgICAgaWYgKCFjdXJyZW50KSB7XG4gICAgICAgICAgICBjb25zdCBwcm9qZWN0aW9uID0gZWxldmF0ZVBvaW50QW5kUHJvamVjdChjdXJyZW50VmVydGV4LCB0aWxlSUQuY2Fub25pY2FsLCBsYWJlbFBsYW5lTWF0cml4LCByZXByb2plY3Rpb24sIGdldEVsZXZhdGlvbik7XG4gICAgICAgICAgICBpZiAocHJvamVjdGlvblszXSA+IDApIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50ID0gcHJvamVjdGlvbkNhY2hlW2N1cnJlbnRJbmRleF0gPSBwcm9qZWN0aW9uO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBUaGUgdmVydGV4IGlzIGJlaGluZCB0aGUgcGxhbmUgb2YgdGhlIGNhbWVyYSwgc28gd2UgY2FuJ3QgcHJvamVjdCBpdFxuICAgICAgICAgICAgICAgIC8vIEluc3RlYWQsIHdlJ2xsIGNyZWF0ZSBhIHZlcnRleCBhbG9uZyB0aGUgbGluZSB0aGF0J3MgZmFyIGVub3VnaCB0byBpbmNsdWRlIHRoZSBnbHlwaFxuICAgICAgICAgICAgICAgIC8vIERvbid0IGNhY2hlIGJlY2F1c2UgdGhlIG5ldyB2ZXJ0ZXggbWlnaHQgbm90IGJlIGZhciBlbm91Z2ggb3V0IGZvciBmdXR1cmUgZ2x5cGhzIG9uIHRoZSBzYW1lIHNlZ21lbnRcbiAgICAgICAgICAgICAgICBjdXJyZW50ID0gZ2V0VHJ1bmNhdGVkTGluZVNlZ21lbnQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGRpc3RhbmNlVG9QcmV2ICs9IGN1cnJlbnRTZWdtZW50RGlzdGFuY2U7XG4gICAgICAgIGN1cnJlbnRTZWdtZW50RGlzdGFuY2UgPSB2ZWMzLmRpc3RhbmNlKHByZXYsIGN1cnJlbnQpO1xuICAgIH1cblxuICAgIGlmIChlbmRHbHlwaCAmJiBnZXRFbGV2YXRpb24pIHtcbiAgICAgICAgLy8gRm9yIHRlcnJhaW4sIGFsd2F5cyB0cnVuY2F0ZSBlbmQgcG9pbnRzIGluIG9yZGVyIHRvIGhhbmRsZSB0ZXJyYWluIGN1cnZhdHVyZS5cbiAgICAgICAgLy8gSWYgcHJldmlvdXNseSB0cnVuY2F0ZWQsIG9uIHNpZ25lZERpc3RhbmNlRnJvbUNhbWVyYSA8IDAsIGRvbid0IGRvIGl0LlxuICAgICAgICAvLyBDYWNoZSBhcyBlbmQgcG9pbnQuIFRoZSBjYWNoZSBpcyBjbGVhcmVkIGlmIHRoZXJlIGlzIG5lZWQgZm9yIGZsaXBwaW5nIGluIHVwZGF0ZUxpbmVMYWJlbHMuXG4gICAgICAgIGlmIChwcm9qZWN0aW9uQ2FjaGVbY3VycmVudEluZGV4XSkge1xuICAgICAgICAgICAgY3VycmVudCA9IGdldFRydW5jYXRlZExpbmVTZWdtZW50KCk7XG4gICAgICAgICAgICBjdXJyZW50U2VnbWVudERpc3RhbmNlID0gdmVjMy5kaXN0YW5jZShwcmV2LCBjdXJyZW50KTtcbiAgICAgICAgfVxuICAgICAgICBwcm9qZWN0aW9uQ2FjaGVbY3VycmVudEluZGV4XSA9IGN1cnJlbnQ7XG4gICAgfVxuXG4gICAgLy8gVGhlIHBvaW50IGlzIG9uIHRoZSBjdXJyZW50IHNlZ21lbnQuIEludGVycG9sYXRlIHRvIGZpbmQgaXQuIENvbXB1dGUgcG9pbnRzIG9uIGJvdGggbGFiZWwgcGxhbmUgYW5kIHRpbGUgc3BhY2VcbiAgICBjb25zdCBzZWdtZW50SW50ZXJwb2xhdGlvblQgPSAoYWJzT2Zmc2V0WCAtIGRpc3RhbmNlVG9QcmV2KSAvIGN1cnJlbnRTZWdtZW50RGlzdGFuY2U7XG4gICAgY29uc3QgdGlsZVBvaW50ID0gY3VycmVudFZlcnRleC5zdWIocHJldlZlcnRleCkuX211bHQoc2VnbWVudEludGVycG9sYXRpb25UKS5fYWRkKHByZXZWZXJ0ZXgpO1xuICAgIGNvbnN0IHByZXZUb0N1cnJlbnQgPSB2ZWMzLnN1YihbXSwgY3VycmVudCwgcHJldik7XG4gICAgY29uc3QgbGFiZWxQbGFuZVBvaW50ID0gdmVjMy5zY2FsZUFuZEFkZChbXSwgcHJldiwgcHJldlRvQ3VycmVudCwgc2VnbWVudEludGVycG9sYXRpb25UKTtcblxuICAgIGxldCBheGlzWjogVmVjMyA9IFswLCAwLCAxXTtcbiAgICBsZXQgZGlmZlggPSBwcmV2VG9DdXJyZW50WzBdO1xuICAgIGxldCBkaWZmWSA9IHByZXZUb0N1cnJlbnRbMV07XG5cbiAgICBpZiAocGl0Y2hXaXRoTWFwKSB7XG4gICAgICAgIGF4aXNaID0gcmVwcm9qZWN0aW9uLnVwVmVjdG9yKHRpbGVJRC5jYW5vbmljYWwsIHRpbGVQb2ludC54LCB0aWxlUG9pbnQueSk7XG5cbiAgICAgICAgaWYgKGF4aXNaWzBdICE9PSAwIHx8IGF4aXNaWzFdICE9PSAwIHx8IGF4aXNaWzJdICE9PSAxKSB7XG4gICAgICAgICAgICAvLyBDb21wdXRlIGNvb3JkaW5hdGUgZnJhbWUgdGhhdCBpcyBhbGlnbmVkIHRvIHRoZSB0YW5nZW50IG9mIHRoZSBzdXJmYWNlXG4gICAgICAgICAgICBjb25zdCBheGlzWCA9IFtheGlzWlsyXSwgMCwgLWF4aXNaWzBdXTtcbiAgICAgICAgICAgIGNvbnN0IGF4aXNZID0gdmVjMy5jcm9zcyhbXSwgYXhpc1osIGF4aXNYKTtcbiAgICAgICAgICAgIHZlYzMubm9ybWFsaXplKGF4aXNYLCBheGlzWCk7XG4gICAgICAgICAgICB2ZWMzLm5vcm1hbGl6ZShheGlzWSwgYXhpc1kpO1xuICAgICAgICAgICAgZGlmZlggPSB2ZWMzLmRvdChwcmV2VG9DdXJyZW50LCBheGlzWCk7XG4gICAgICAgICAgICBkaWZmWSA9IHZlYzMuZG90KHByZXZUb0N1cnJlbnQsIGF4aXNZKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIG9mZnNldCB0aGUgcG9pbnQgZnJvbSB0aGUgbGluZSB0byB0ZXh0LW9mZnNldCBhbmQgaWNvbi1vZmZzZXRcbiAgICBpZiAobGluZU9mZnNldFkpIHtcbiAgICAgICAgLy8gRmluZCBhIGNvb3JkaW5hdGUgZnJhbWUgZm9yIHRoZSB2ZXJ0aWNhbCBvZmZzZXRcbiAgICAgICAgY29uc3Qgb2Zmc2V0RGlyID0gdmVjMy5jcm9zcyhbXSwgYXhpc1osIHByZXZUb0N1cnJlbnQpO1xuICAgICAgICB2ZWMzLm5vcm1hbGl6ZShvZmZzZXREaXIsIG9mZnNldERpcik7XG4gICAgICAgIHZlYzMuc2NhbGVBbmRBZGQobGFiZWxQbGFuZVBvaW50LCBsYWJlbFBsYW5lUG9pbnQsIG9mZnNldERpciwgbGluZU9mZnNldFkgKiBkaXIpO1xuICAgIH1cblxuICAgIGNvbnN0IHNlZ21lbnRBbmdsZSA9IGFuZ2xlICsgTWF0aC5hdGFuMihkaWZmWSwgZGlmZlgpO1xuXG4gICAgcGF0aFZlcnRpY2VzLnB1c2gobGFiZWxQbGFuZVBvaW50KTtcbiAgICBpZiAocmV0dXJuUGF0aEluVGlsZUNvb3Jkcykge1xuICAgICAgICB0aWxlUGF0aC5wdXNoKHRpbGVQb2ludCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgcG9pbnQ6IGxhYmVsUGxhbmVQb2ludCxcbiAgICAgICAgYW5nbGU6IHNlZ21lbnRBbmdsZSxcbiAgICAgICAgcGF0aDogcGF0aFZlcnRpY2VzLFxuICAgICAgICB0aWxlUGF0aCxcbiAgICAgICAgdXA6IGF4aXNaXG4gICAgfTtcbn1cblxuLy8gSGlkZSB0aGVtIGJ5IG1vdmluZyB0aGVtIG9mZnNjcmVlbi4gV2Ugc3RpbGwgbmVlZCB0byBhZGQgdGhlbSB0byB0aGUgYnVmZmVyXG4vLyBiZWNhdXNlIHRoZSBkeW5hbWljIGJ1ZmZlciBpcyBwYWlyZWQgd2l0aCBhIHN0YXRpYyBidWZmZXIgdGhhdCBkb2Vzbid0IGdldCB1cGRhdGVkLlxuZnVuY3Rpb24gaGlkZUdseXBocyhudW06IG51bWJlciwgZHluYW1pY0xheW91dFZlcnRleEFycmF5OiBTeW1ib2xEeW5hbWljTGF5b3V0QXJyYXkpIHtcbiAgICBjb25zdCBvZmZzZXQgPSBkeW5hbWljTGF5b3V0VmVydGV4QXJyYXkubGVuZ3RoO1xuICAgIGNvbnN0IGVuZCA9IG9mZnNldCArIDQgKiBudW07XG4gICAgZHluYW1pY0xheW91dFZlcnRleEFycmF5LnJlc2l6ZShlbmQpO1xuICAgIC8vIFNpbmNlIGFsbCBoaWRkZW4gZ2x5cGhzIGhhdmUgdGhlIHNhbWUgYXR0cmlidXRlcywgd2UgY2FuIGJ1aWxkIHVwIHRoZSBhcnJheSBmYXN0ZXIgd2l0aCBhIHNpbmdsZSBjYWxsIHRvXG4gICAgLy8gRmxvYXQzMkFycmF5LmZpbGwgZm9yIGFsbCB2ZXJ0aWNlcywgaW5zdGVhZCBvZiBjYWxsaW5nIGFkZER5bmFtaWNBdHRyaWJ1dGVzIGZvciBlYWNoIHZlcnRleC5cbiAgICBkeW5hbWljTGF5b3V0VmVydGV4QXJyYXkuZmxvYXQzMi5maWxsKC1JbmZpbml0eSwgb2Zmc2V0ICogNCwgZW5kICogNCk7XG59XG5cbi8vIEZvciBsaW5lIGxhYmVsIGxheW91dCwgd2UncmUgbm90IHVzaW5nIHogb3V0cHV0IGFuZCBvdXIgdyBpbnB1dCBpcyBhbHdheXMgMVxuLy8gVGhpcyBjdXN0b20gbWF0cml4IHRyYW5zZm9ybWF0aW9uIGlnbm9yZXMgdGhvc2UgY29tcG9uZW50cyB0byBtYWtlIHByb2plY3Rpb24gZmFzdGVyXG5mdW5jdGlvbiB4eVRyYW5zZm9ybU1hdDQob3V0OiBWZWM0LCBhOiBWZWM0LCBtOiBNYXQ0KTogVmVjNCB7XG4gICAgY29uc3QgeCA9IGFbMF0sIHkgPSBhWzFdO1xuICAgIG91dFswXSA9IG1bMF0gKiB4ICsgbVs0XSAqIHkgKyBtWzEyXTtcbiAgICBvdXRbMV0gPSBtWzFdICogeCArIG1bNV0gKiB5ICsgbVsxM107XG4gICAgb3V0WzNdID0gbVszXSAqIHggKyBtWzddICogeSArIG1bMTVdO1xuICAgIHJldHVybiBvdXQ7XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5pbXBvcnQgY2xpcExpbmUgZnJvbSAnLi9jbGlwX2xpbmUuanMnO1xuaW1wb3J0IFBhdGhJbnRlcnBvbGF0b3IgZnJvbSAnLi9wYXRoX2ludGVycG9sYXRvci5qcyc7XG5pbXBvcnQgKiBhcyBpbnRlcnNlY3Rpb25UZXN0cyBmcm9tICcuLi91dGlsL2ludGVyc2VjdGlvbl90ZXN0cy5qcyc7XG5pbXBvcnQgR3JpZCBmcm9tICcuL2dyaWRfaW5kZXguanMnO1xuaW1wb3J0IHttYXQ0LCB2ZWM0fSBmcm9tICdnbC1tYXRyaXgnO1xuaW1wb3J0IE9ORV9FTSBmcm9tICcuLi9zeW1ib2wvb25lX2VtLmpzJztcbmltcG9ydCB7Rk9HX1NZTUJPTF9DTElQUElOR19USFJFU0hPTEQsIGdldEZvZ09wYWNpdHlBdFRpbGVDb29yZH0gZnJvbSAnLi4vc3R5bGUvZm9nX2hlbHBlcnMuanMnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHtPdmVyc2NhbGVkVGlsZUlEfSBmcm9tICcuLi9zb3VyY2UvdGlsZV9pZC5qcyc7XG5pbXBvcnQgKiBhcyBzeW1ib2xQcm9qZWN0aW9uIGZyb20gJy4uL3N5bWJvbC9wcm9qZWN0aW9uLmpzJztcblxuaW1wb3J0IHR5cGUgVHJhbnNmb3JtIGZyb20gJy4uL2dlby90cmFuc2Zvcm0uanMnO1xuaW1wb3J0IHR5cGUgUHJvamVjdGlvbiBmcm9tICcuLi9nZW8vcHJvamVjdGlvbi9wcm9qZWN0aW9uLmpzJztcbmltcG9ydCB0eXBlIFN5bWJvbEJ1Y2tldCwge1NpbmdsZUNvbGxpc2lvbkJveH0gZnJvbSAnLi4vZGF0YS9idWNrZXQvc3ltYm9sX2J1Y2tldC5qcyc7XG5pbXBvcnQgdHlwZSB7R2x5cGhPZmZzZXRBcnJheSwgU3ltYm9sTGluZVZlcnRleEFycmF5LCBQbGFjZWRTeW1ib2x9IGZyb20gJy4uL2RhdGEvYXJyYXlfdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge0ZvZ1N0YXRlfSBmcm9tICcuLi9zdHlsZS9mb2dfaGVscGVycy5qcyc7XG5pbXBvcnQgdHlwZSB7VmVjMywgTWF0NH0gZnJvbSAnZ2wtbWF0cml4JztcblxuZXhwb3J0IHR5cGUgUGxhY2VkQ29sbGlzaW9uQm94ID0ge3xcbiAgICBib3g6IEFycmF5PG51bWJlcj4sXG4gICAgb2Zmc2NyZWVuOiBib29sZWFuLFxuICAgIG9jY2x1ZGVkOiBib29sZWFuXG58fTtcbnR5cGUgUGxhY2VkQ29sbGlzaW9uQ2lyY2xlcyA9IHt8XG4gICAgY2lyY2xlczogQXJyYXk8bnVtYmVyPixcbiAgICBvZmZzY3JlZW46IGJvb2xlYW4sXG4gICAgY29sbGlzaW9uRGV0ZWN0ZWQ6IGJvb2xlYW4sXG4gICAgb2NjbHVkZWQ6IGJvb2xlYW5cbnx9O1xudHlwZSBTY3JlZW5BbmNob3JQb2ludCA9IHt8XG4gIG9jY2x1ZGVkOiBib29sZWFuLFxuICBwZXJzcGVjdGl2ZVJhdGlvOiBudW1iZXIsXG4gIHBvaW50OiBQb2ludCxcbiAgc2lnbmVkRGlzdGFuY2VGcm9tQ2FtZXJhOiBudW1iZXIsXG58fTtcblxuLy8gV2hlbiBhIHN5bWJvbCBjcm9zc2VzIHRoZSBlZGdlIHRoYXQgY2F1c2VzIGl0IHRvIGJlIGluY2x1ZGVkIGluXG4vLyBjb2xsaXNpb24gZGV0ZWN0aW9uLCBpdCB3aWxsIGNhdXNlIGNoYW5nZXMgaW4gdGhlIHN5bWJvbHMgYXJvdW5kXG4vLyBpdC4gVGhpcyBjb25zdGFudCBzcGVjaWZpZXMgaG93IG1hbnkgcGl4ZWxzIHRvIHBhZCB0aGUgZWRnZSBvZlxuLy8gdGhlIHZpZXdwb3J0IGZvciBjb2xsaXNpb24gZGV0ZWN0aW9uIHNvIHRoYXQgdGhlIGJ1bGsgb2YgdGhlIGNoYW5nZXNcbi8vIG9jY3VyIG9mZnNjcmVlbi4gTWFraW5nIHRoaXMgY29uc3RhbnQgZ3JlYXRlciBpbmNyZWFzZXMgbGFiZWxcbi8vIHN0YWJpbGl0eSwgYnV0IGl0J3MgZXhwZW5zaXZlLlxuY29uc3Qgdmlld3BvcnRQYWRkaW5nID0gMTAwO1xuXG4vKipcbiAqIEEgY29sbGlzaW9uIGluZGV4IHVzZWQgdG8gcHJldmVudCBzeW1ib2xzIGZyb20gb3ZlcmxhcHBpbmcuIEl0IGtlZXAgdHJhY2tzIG9mXG4gKiB3aGVyZSBwcmV2aW91cyBzeW1ib2xzIGhhdmUgYmVlbiBwbGFjZWQgYW5kIGlzIHVzZWQgdG8gY2hlY2sgaWYgYSBuZXdcbiAqIHN5bWJvbCBvdmVybGFwcyB3aXRoIGFueSBwcmV2aW91c2x5IGFkZGVkIHN5bWJvbHMuXG4gKlxuICogVGhlcmUgYXJlIHR3byBzdGVwcyB0byBpbnNlcnRpb246IGZpcnN0IHBsYWNlQ29sbGlzaW9uQm94L0NpcmNsZXMgY2hlY2tzIGlmXG4gKiB0aGVyZSdzIHJvb20gZm9yIGEgc3ltYm9sLCB0aGVuIGluc2VydENvbGxpc2lvbkJveC9DaXJjbGVzIGFjdHVhbGx5IHB1dHMgdGhlXG4gKiBzeW1ib2wgaW4gdGhlIGluZGV4LiBUaGUgdHdvIHN0ZXAgcHJvY2VzcyBhbGxvd3MgcGFpcmVkIHN5bWJvbHMgdG8gYmUgaW5zZXJ0ZWRcbiAqIHRvZ2V0aGVyIGV2ZW4gaWYgdGhleSBvdmVybGFwLlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmNsYXNzIENvbGxpc2lvbkluZGV4IHtcbiAgICBncmlkOiBHcmlkO1xuICAgIGlnbm9yZWRHcmlkOiBHcmlkO1xuICAgIHRyYW5zZm9ybTogVHJhbnNmb3JtO1xuICAgIHBpdGNoZmFjdG9yOiBudW1iZXI7XG4gICAgc2NyZWVuUmlnaHRCb3VuZGFyeTogbnVtYmVyO1xuICAgIHNjcmVlbkJvdHRvbUJvdW5kYXJ5OiBudW1iZXI7XG4gICAgZ3JpZFJpZ2h0Qm91bmRhcnk6IG51bWJlcjtcbiAgICBncmlkQm90dG9tQm91bmRhcnk6IG51bWJlcjtcbiAgICBmb2dTdGF0ZTogP0ZvZ1N0YXRlO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHRyYW5zZm9ybTogVHJhbnNmb3JtLFxuICAgICAgICBmb2dTdGF0ZTogP0ZvZ1N0YXRlLFxuICAgICAgICBncmlkOiBHcmlkID0gbmV3IEdyaWQodHJhbnNmb3JtLndpZHRoICsgMiAqIHZpZXdwb3J0UGFkZGluZywgdHJhbnNmb3JtLmhlaWdodCArIDIgKiB2aWV3cG9ydFBhZGRpbmcsIDI1KSxcbiAgICAgICAgaWdub3JlZEdyaWQ6IEdyaWQgPSBuZXcgR3JpZCh0cmFuc2Zvcm0ud2lkdGggKyAyICogdmlld3BvcnRQYWRkaW5nLCB0cmFuc2Zvcm0uaGVpZ2h0ICsgMiAqIHZpZXdwb3J0UGFkZGluZywgMjUpXG4gICAgKSB7XG4gICAgICAgIHRoaXMudHJhbnNmb3JtID0gdHJhbnNmb3JtO1xuXG4gICAgICAgIHRoaXMuZ3JpZCA9IGdyaWQ7XG4gICAgICAgIHRoaXMuaWdub3JlZEdyaWQgPSBpZ25vcmVkR3JpZDtcbiAgICAgICAgdGhpcy5waXRjaGZhY3RvciA9IE1hdGguY29zKHRyYW5zZm9ybS5fcGl0Y2gpICogdHJhbnNmb3JtLmNhbWVyYVRvQ2VudGVyRGlzdGFuY2U7XG5cbiAgICAgICAgdGhpcy5zY3JlZW5SaWdodEJvdW5kYXJ5ID0gdHJhbnNmb3JtLndpZHRoICsgdmlld3BvcnRQYWRkaW5nO1xuICAgICAgICB0aGlzLnNjcmVlbkJvdHRvbUJvdW5kYXJ5ID0gdHJhbnNmb3JtLmhlaWdodCArIHZpZXdwb3J0UGFkZGluZztcbiAgICAgICAgdGhpcy5ncmlkUmlnaHRCb3VuZGFyeSA9IHRyYW5zZm9ybS53aWR0aCArIDIgKiB2aWV3cG9ydFBhZGRpbmc7XG4gICAgICAgIHRoaXMuZ3JpZEJvdHRvbUJvdW5kYXJ5ID0gdHJhbnNmb3JtLmhlaWdodCArIDIgKiB2aWV3cG9ydFBhZGRpbmc7XG4gICAgICAgIHRoaXMuZm9nU3RhdGUgPSBmb2dTdGF0ZTtcbiAgICB9XG5cbiAgICBwbGFjZUNvbGxpc2lvbkJveChidWNrZXQ6IFN5bWJvbEJ1Y2tldCwgc2NhbGU6IG51bWJlciwgY29sbGlzaW9uQm94OiBTaW5nbGVDb2xsaXNpb25Cb3gsIHNoaWZ0OiBQb2ludCwgYWxsb3dPdmVybGFwOiBib29sZWFuLCB0ZXh0UGl4ZWxSYXRpbzogbnVtYmVyLCBwb3NNYXRyaXg6IE1hdDQsIGNvbGxpc2lvbkdyb3VwUHJlZGljYXRlPzogYW55KTogUGxhY2VkQ29sbGlzaW9uQm94IHtcbiAgICAgICAgYXNzZXJ0KCF0aGlzLnRyYW5zZm9ybS5lbGV2YXRpb24gfHwgY29sbGlzaW9uQm94LmVsZXZhdGlvbiAhPT0gdW5kZWZpbmVkKTtcblxuICAgICAgICBsZXQgYW5jaG9yWCA9IGNvbGxpc2lvbkJveC5wcm9qZWN0ZWRBbmNob3JYO1xuICAgICAgICBsZXQgYW5jaG9yWSA9IGNvbGxpc2lvbkJveC5wcm9qZWN0ZWRBbmNob3JZO1xuICAgICAgICBsZXQgYW5jaG9yWiA9IGNvbGxpc2lvbkJveC5wcm9qZWN0ZWRBbmNob3JaO1xuXG4gICAgICAgIC8vIEFwcGx5IGVsZXZhdGlvbiB2ZWN0b3IgdG8gdGhlIGFuY2hvciBwb2ludFxuICAgICAgICBjb25zdCBlbGV2YXRpb24gPSBjb2xsaXNpb25Cb3guZWxldmF0aW9uO1xuICAgICAgICBjb25zdCB0aWxlSUQgPSBjb2xsaXNpb25Cb3gudGlsZUlEO1xuICAgICAgICBjb25zdCBwcm9qZWN0aW9uID0gYnVja2V0LmdldFByb2plY3Rpb24oKTtcbiAgICAgICAgaWYgKGVsZXZhdGlvbiAmJiB0aWxlSUQpIHtcbiAgICAgICAgICAgIGNvbnN0IFt1eCwgdXksIHV6XSA9IHByb2plY3Rpb24udXBWZWN0b3IodGlsZUlELmNhbm9uaWNhbCwgY29sbGlzaW9uQm94LnRpbGVBbmNob3JYLCBjb2xsaXNpb25Cb3gudGlsZUFuY2hvclkpO1xuICAgICAgICAgICAgY29uc3QgdXBTY2FsZSA9IHByb2plY3Rpb24udXBWZWN0b3JTY2FsZSh0aWxlSUQuY2Fub25pY2FsLCB0aGlzLnRyYW5zZm9ybS5jZW50ZXIubGF0LCB0aGlzLnRyYW5zZm9ybS53b3JsZFNpemUpLm1ldGVyc1RvVGlsZTtcblxuICAgICAgICAgICAgYW5jaG9yWCArPSB1eCAqIGVsZXZhdGlvbiAqIHVwU2NhbGU7XG4gICAgICAgICAgICBhbmNob3JZICs9IHV5ICogZWxldmF0aW9uICogdXBTY2FsZTtcbiAgICAgICAgICAgIGFuY2hvclogKz0gdXogKiBlbGV2YXRpb24gKiB1cFNjYWxlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY2hlY2tPY2NsdXNpb24gPSBwcm9qZWN0aW9uLm5hbWUgPT09ICdnbG9iZScgfHwgISFlbGV2YXRpb24gfHwgdGhpcy50cmFuc2Zvcm0ucGl0Y2ggPiAwO1xuICAgICAgICBjb25zdCBwcm9qZWN0ZWRQb2ludCA9IHRoaXMucHJvamVjdEFuZEdldFBlcnNwZWN0aXZlUmF0aW8ocG9zTWF0cml4LCBhbmNob3JYLCBhbmNob3JZLCBhbmNob3JaLCBjb2xsaXNpb25Cb3gudGlsZUlELCBjaGVja09jY2x1c2lvbiwgcHJvamVjdGlvbik7XG5cbiAgICAgICAgY29uc3QgdGlsZVRvVmlld3BvcnQgPSB0ZXh0UGl4ZWxSYXRpbyAqIHByb2plY3RlZFBvaW50LnBlcnNwZWN0aXZlUmF0aW87XG4gICAgICAgIGNvbnN0IHRsWCA9IChjb2xsaXNpb25Cb3gueDEgKiBzY2FsZSArIHNoaWZ0LnggLSBjb2xsaXNpb25Cb3gucGFkZGluZykgKiB0aWxlVG9WaWV3cG9ydCArIHByb2plY3RlZFBvaW50LnBvaW50Lng7XG4gICAgICAgIGNvbnN0IHRsWSA9IChjb2xsaXNpb25Cb3gueTEgKiBzY2FsZSArIHNoaWZ0LnkgLSBjb2xsaXNpb25Cb3gucGFkZGluZykgKiB0aWxlVG9WaWV3cG9ydCArIHByb2plY3RlZFBvaW50LnBvaW50Lnk7XG4gICAgICAgIGNvbnN0IGJyWCA9IChjb2xsaXNpb25Cb3gueDIgKiBzY2FsZSArIHNoaWZ0LnggKyBjb2xsaXNpb25Cb3gucGFkZGluZykgKiB0aWxlVG9WaWV3cG9ydCArIHByb2plY3RlZFBvaW50LnBvaW50Lng7XG4gICAgICAgIGNvbnN0IGJyWSA9IChjb2xsaXNpb25Cb3gueTIgKiBzY2FsZSArIHNoaWZ0LnkgKyBjb2xsaXNpb25Cb3gucGFkZGluZykgKiB0aWxlVG9WaWV3cG9ydCArIHByb2plY3RlZFBvaW50LnBvaW50Lnk7XG4gICAgICAgIC8vIENsaXAgYXQgMTAgdGltZXMgdGhlIGRpc3RhbmNlIG9mIHRoZSBtYXAgY2VudGVyIG9yLCBzYWlkIG90aGVyd2lzZSwgd2hlbiB0aGUgbGFiZWxcbiAgICAgICAgLy8gd291bGQgYmUgZHJhd24gYXQgMTAlIHRoZSBzaXplIG9mIHRoZSBmZWF0dXJlcyBhcm91bmQgaXQgd2l0aG91dCBzY2FsaW5nLiBSZWZlcjpcbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21hcGJveC9tYXBib3gtZ2wtbmF0aXZlL3dpa2kvVGV4dC1SZW5kZXJpbmcjcGVyc3BlY3RpdmUtc2NhbGluZ1xuICAgICAgICAvLyAwLjU1ID09PSBwcm9qZWN0aW9uLmdldFBlcnNwZWN0aXZlUmF0aW8oY2FtZXJhX3RvX2NlbnRlciwgY2FtZXJhX3RvX2NlbnRlciAqIDEwKVxuICAgICAgICBjb25zdCBtaW5QZXJzcGVjdGl2ZVJhdGlvID0gMC41NTtcbiAgICAgICAgY29uc3QgaXNDbGlwcGVkID0gcHJvamVjdGVkUG9pbnQucGVyc3BlY3RpdmVSYXRpbyA8PSBtaW5QZXJzcGVjdGl2ZVJhdGlvIHx8IHByb2plY3RlZFBvaW50Lm9jY2x1ZGVkO1xuXG4gICAgICAgIGlmICghdGhpcy5pc0luc2lkZUdyaWQodGxYLCB0bFksIGJyWCwgYnJZKSB8fFxuICAgICAgICAgICAgKCFhbGxvd092ZXJsYXAgJiYgdGhpcy5ncmlkLmhpdFRlc3QodGxYLCB0bFksIGJyWCwgYnJZLCBjb2xsaXNpb25Hcm91cFByZWRpY2F0ZSkpIHx8XG4gICAgICAgICAgICBpc0NsaXBwZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgYm94OiBbXSxcbiAgICAgICAgICAgICAgICBvZmZzY3JlZW46IGZhbHNlLFxuICAgICAgICAgICAgICAgIG9jY2x1ZGVkOiBwcm9qZWN0ZWRQb2ludC5vY2NsdWRlZFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBib3g6IFt0bFgsIHRsWSwgYnJYLCBiclldLFxuICAgICAgICAgICAgb2Zmc2NyZWVuOiB0aGlzLmlzT2Zmc2NyZWVuKHRsWCwgdGxZLCBiclgsIGJyWSksXG4gICAgICAgICAgICBvY2NsdWRlZDogZmFsc2VcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwbGFjZUNvbGxpc2lvbkNpcmNsZXMoYnVja2V0OiBTeW1ib2xCdWNrZXQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGFsbG93T3ZlcmxhcDogYm9vbGVhbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltYm9sOiBQbGFjZWRTeW1ib2wsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVWZXJ0ZXhBcnJheTogU3ltYm9sTGluZVZlcnRleEFycmF5LFxuICAgICAgICAgICAgICAgICAgICAgICAgICBnbHlwaE9mZnNldEFycmF5OiBHbHlwaE9mZnNldEFycmF5LFxuICAgICAgICAgICAgICAgICAgICAgICAgICBmb250U2l6ZTogbnVtYmVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NNYXRyaXg6IEZsb2F0MzJBcnJheSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxQbGFuZU1hdHJpeDogRmxvYXQzMkFycmF5LFxuICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbFRvU2NyZWVuTWF0cml4PzogTWF0NCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvd0NvbGxpc2lvbkNpcmNsZXM6IGJvb2xlYW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHBpdGNoV2l0aE1hcDogYm9vbGVhbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29sbGlzaW9uR3JvdXBQcmVkaWNhdGU/OiBhbnksXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNpcmNsZVBpeGVsRGlhbWV0ZXI6IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dFBpeGVsUGFkZGluZzogbnVtYmVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aWxlSUQ6IE92ZXJzY2FsZWRUaWxlSUQpOiBQbGFjZWRDb2xsaXNpb25DaXJjbGVzIHtcbiAgICAgICAgY29uc3QgcGxhY2VkQ29sbGlzaW9uQ2lyY2xlcyA9IFtdO1xuICAgICAgICBjb25zdCBlbGV2YXRpb24gPSB0aGlzLnRyYW5zZm9ybS5lbGV2YXRpb247XG4gICAgICAgIGNvbnN0IHByb2plY3Rpb24gPSBidWNrZXQuZ2V0UHJvamVjdGlvbigpO1xuICAgICAgICBjb25zdCBnZXRFbGV2YXRpb24gPSBlbGV2YXRpb24gPyBlbGV2YXRpb24uZ2V0QXRUaWxlT2Zmc2V0RnVuYyh0aWxlSUQsIHRoaXMudHJhbnNmb3JtLmNlbnRlci5sYXQsIHRoaXMudHJhbnNmb3JtLndvcmxkU2l6ZSwgcHJvamVjdGlvbikgOiBudWxsO1xuXG4gICAgICAgIGNvbnN0IHRpbGVVbml0QW5jaG9yUG9pbnQgPSBuZXcgUG9pbnQoc3ltYm9sLnRpbGVBbmNob3JYLCBzeW1ib2wudGlsZUFuY2hvclkpO1xuICAgICAgICBsZXQge3g6IGFuY2hvclgsIHk6IGFuY2hvclksIHo6IGFuY2hvclp9ID0gcHJvamVjdGlvbi5wcm9qZWN0VGlsZVBvaW50KHRpbGVVbml0QW5jaG9yUG9pbnQueCwgdGlsZVVuaXRBbmNob3JQb2ludC55LCB0aWxlSUQuY2Fub25pY2FsKTtcbiAgICAgICAgaWYgKGdldEVsZXZhdGlvbikge1xuICAgICAgICAgICAgY29uc3QgW2R4LCBkeSwgZHpdID0gZ2V0RWxldmF0aW9uKHRpbGVVbml0QW5jaG9yUG9pbnQpO1xuICAgICAgICAgICAgYW5jaG9yWCArPSBkeDtcbiAgICAgICAgICAgIGFuY2hvclkgKz0gZHk7XG4gICAgICAgICAgICBhbmNob3JaICs9IGR6O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGlzR2xvYmUgPSBwcm9qZWN0aW9uLm5hbWUgPT09ICdnbG9iZSc7XG4gICAgICAgIGNvbnN0IGNoZWNrT2NjbHVzaW9uID0gaXNHbG9iZSB8fCAhIWVsZXZhdGlvbiB8fCB0aGlzLnRyYW5zZm9ybS5waXRjaCA+IDA7XG4gICAgICAgIGNvbnN0IHNjcmVlbkFuY2hvclBvaW50ID0gdGhpcy5wcm9qZWN0QW5kR2V0UGVyc3BlY3RpdmVSYXRpbyhwb3NNYXRyaXgsIGFuY2hvclgsIGFuY2hvclksIGFuY2hvclosIHRpbGVJRCwgY2hlY2tPY2NsdXNpb24sIHByb2plY3Rpb24pO1xuICAgICAgICBjb25zdCB7cGVyc3BlY3RpdmVSYXRpb30gPSBzY3JlZW5BbmNob3JQb2ludDtcbiAgICAgICAgY29uc3QgbGFiZWxQbGFuZUZvbnRTY2FsZSA9IChwaXRjaFdpdGhNYXAgPyBmb250U2l6ZSAvIHBlcnNwZWN0aXZlUmF0aW8gOiBmb250U2l6ZSAqIHBlcnNwZWN0aXZlUmF0aW8pIC8gT05FX0VNO1xuICAgICAgICBjb25zdCBsYWJlbFBsYW5lQW5jaG9yUG9pbnQgPSBzeW1ib2xQcm9qZWN0aW9uLnByb2plY3QoYW5jaG9yWCwgYW5jaG9yWSwgYW5jaG9yWiwgbGFiZWxQbGFuZU1hdHJpeCk7XG5cbiAgICAgICAgY29uc3QgcHJvamVjdGlvbkNhY2hlID0ge307XG4gICAgICAgIGNvbnN0IGxpbmVPZmZzZXRYID0gc3ltYm9sLmxpbmVPZmZzZXRYICogbGFiZWxQbGFuZUZvbnRTY2FsZTtcbiAgICAgICAgY29uc3QgbGluZU9mZnNldFkgPSBzeW1ib2wubGluZU9mZnNldFkgKiBsYWJlbFBsYW5lRm9udFNjYWxlO1xuXG4gICAgICAgIGNvbnN0IGZpcnN0QW5kTGFzdEdseXBoID0gc2NyZWVuQW5jaG9yUG9pbnQuc2lnbmVkRGlzdGFuY2VGcm9tQ2FtZXJhID4gMCA/IHN5bWJvbFByb2plY3Rpb24ucGxhY2VGaXJzdEFuZExhc3RHbHlwaChcbiAgICAgICAgICAgIGxhYmVsUGxhbmVGb250U2NhbGUsXG4gICAgICAgICAgICBnbHlwaE9mZnNldEFycmF5LFxuICAgICAgICAgICAgbGluZU9mZnNldFgsXG4gICAgICAgICAgICBsaW5lT2Zmc2V0WSxcbiAgICAgICAgICAgIC8qZmxpcCovIGZhbHNlLFxuICAgICAgICAgICAgbGFiZWxQbGFuZUFuY2hvclBvaW50LFxuICAgICAgICAgICAgdGlsZVVuaXRBbmNob3JQb2ludCxcbiAgICAgICAgICAgIHN5bWJvbCxcbiAgICAgICAgICAgIGxpbmVWZXJ0ZXhBcnJheSxcbiAgICAgICAgICAgIGxhYmVsUGxhbmVNYXRyaXgsXG4gICAgICAgICAgICBwcm9qZWN0aW9uQ2FjaGUsXG4gICAgICAgICAgICBlbGV2YXRpb24gJiYgIXBpdGNoV2l0aE1hcCA/IGdldEVsZXZhdGlvbiA6IG51bGwsIC8vIHBpdGNoV2l0aE1hcDogbm8gbmVlZCB0byBzYW1wbGUgZWxldmF0aW9uIGFzIGl0IGhhcyBubyBlZmZlY3Qgd2hlbiBwcm9qZWN0aW5nIHVzaW5nIHNjYWxlL3JvdGF0ZSB0byB0aWxlIHNwYWNlIGxhYmVsUGxhbmVNYXRyaXguXG4gICAgICAgICAgICBwaXRjaFdpdGhNYXAgJiYgISFlbGV2YXRpb24sXG4gICAgICAgICAgICBwcm9qZWN0aW9uLFxuICAgICAgICAgICAgdGlsZUlELFxuICAgICAgICAgICAgcGl0Y2hXaXRoTWFwXG4gICAgICAgICkgOiBudWxsO1xuXG4gICAgICAgIGxldCBjb2xsaXNpb25EZXRlY3RlZCA9IGZhbHNlO1xuICAgICAgICBsZXQgaW5HcmlkID0gZmFsc2U7XG4gICAgICAgIGxldCBlbnRpcmVseU9mZnNjcmVlbiA9IHRydWU7XG5cbiAgICAgICAgaWYgKGZpcnN0QW5kTGFzdEdseXBoICYmICFzY3JlZW5BbmNob3JQb2ludC5vY2NsdWRlZCkge1xuICAgICAgICAgICAgY29uc3QgcmFkaXVzID0gY2lyY2xlUGl4ZWxEaWFtZXRlciAqIDAuNSAqIHBlcnNwZWN0aXZlUmF0aW8gKyB0ZXh0UGl4ZWxQYWRkaW5nO1xuICAgICAgICAgICAgY29uc3Qgc2NyZWVuUGxhbmVNaW4gPSBuZXcgUG9pbnQoLXZpZXdwb3J0UGFkZGluZywgLXZpZXdwb3J0UGFkZGluZyk7XG4gICAgICAgICAgICBjb25zdCBzY3JlZW5QbGFuZU1heCA9IG5ldyBQb2ludCh0aGlzLnNjcmVlblJpZ2h0Qm91bmRhcnksIHRoaXMuc2NyZWVuQm90dG9tQm91bmRhcnkpO1xuICAgICAgICAgICAgY29uc3QgaW50ZXJwb2xhdG9yID0gbmV3IFBhdGhJbnRlcnBvbGF0b3IoKTtcblxuICAgICAgICAgICAgLy8gQ29uc3RydWN0IGEgcHJvamVjdGVkIHBhdGggZnJvbSBwcm9qZWN0ZWQgbGluZSB2ZXJ0aWNlcy4gQW5jaG9yIHBvaW50cyBhcmUgaWdub3JlZCBhbmQgcmVtb3ZlZFxuICAgICAgICAgICAgY29uc3Qge2ZpcnN0LCBsYXN0fSA9IGZpcnN0QW5kTGFzdEdseXBoO1xuICAgICAgICAgICAgY29uc3QgZmlyc3RMZW4gPSBmaXJzdC5wYXRoLmxlbmd0aDtcblxuICAgICAgICAgICAgbGV0IHByb2plY3RlZFBhdGg6IFZlYzNbXSA9IFtdO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IGZpcnN0TGVuIC0gMTsgaSA+PSAxOyBpLS0pIHtcbiAgICAgICAgICAgICAgICBwcm9qZWN0ZWRQYXRoLnB1c2goZmlyc3QucGF0aFtpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IGxhc3QucGF0aC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHByb2plY3RlZFBhdGgucHVzaChsYXN0LnBhdGhbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXNzZXJ0KHByb2plY3RlZFBhdGgubGVuZ3RoID49IDIpO1xuXG4gICAgICAgICAgICAvLyBUb2xlcmF0ZSBhIHNsaWdodGx5IGxvbmdlciBkaXN0YW5jZSB0aGFuIG9uZSBkaWFtZXRlciBiZXR3ZWVuIHR3byBhZGphY2VudCBjaXJjbGVzXG4gICAgICAgICAgICBjb25zdCBjaXJjbGVEaXN0ID0gcmFkaXVzICogMi41O1xuXG4gICAgICAgICAgICAvLyBUaGUgcGF0aCBtaWdodCBuZWVkIHRvIGJlIGNvbnZlcnRlZCBpbnRvIHNjcmVlbiBzcGFjZSBpZiBhIHBpdGNoZWQgbWFwIGlzIHVzZWQgYXMgdGhlIGxhYmVsIHNwYWNlXG4gICAgICAgICAgICBpZiAobGFiZWxUb1NjcmVlbk1hdHJpeCkge1xuICAgICAgICAgICAgICAgIGFzc2VydChwaXRjaFdpdGhNYXApO1xuICAgICAgICAgICAgICAgIHByb2plY3RlZFBhdGggPSBwcm9qZWN0ZWRQYXRoLm1hcCgoW3gsIHksIHpdLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZ2V0RWxldmF0aW9uICYmICFpc0dsb2JlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB6ID0gZ2V0RWxldmF0aW9uKGluZGV4IDwgZmlyc3RMZW4gLSAxID8gZmlyc3QudGlsZVBhdGhbZmlyc3RMZW4gLSAxIC0gaW5kZXhdIDogbGFzdC50aWxlUGF0aFtpbmRleCAtIGZpcnN0TGVuICsgMl0pWzJdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1ib2xQcm9qZWN0aW9uLnByb2plY3QoeCwgeSwgeiwgbGFiZWxUb1NjcmVlbk1hdHJpeCk7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAvLyBEbyBub3QgdHJ5IHRvIHBsYWNlIGNvbGxpc2lvbiBjaXJjbGVzIGlmIGV2ZW4gb2YgdGhlIHBvaW50cyBpcyBiZWhpbmQgdGhlIGNhbWVyYS5cbiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGEgcGxhdXNpYmxlIHNjZW5hcmlvIHdpdGggYmlnIGNhbWVyYSBwaXRjaCBhbmdsZXNcbiAgICAgICAgICAgICAgICBpZiAocHJvamVjdGVkUGF0aC5zb21lKHBvaW50ID0+IHBvaW50WzNdIDw9IDApKSB7XG4gICAgICAgICAgICAgICAgICAgIHByb2plY3RlZFBhdGggPSBbXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBzZWdtZW50cyA9IFtdO1xuXG4gICAgICAgICAgICBpZiAocHJvamVjdGVkUGF0aC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgLy8gUXVpY2tseSBjaGVjayBpZiB0aGUgcGF0aCBpcyBmdWxseSBpbnNpZGUgb3Igb3V0c2lkZSBvZiB0aGUgcGFkZGVkIGNvbGxpc2lvbiByZWdpb24uXG4gICAgICAgICAgICAgICAgLy8gRm9yIG92ZXJsYXBwaW5nIHBhdGhzIHdlJ2xsIG9ubHkgY3JlYXRlIGNvbGxpc2lvbiBjaXJjbGVzIGZvciB0aGUgdmlzaWJsZSBzZWdtZW50c1xuICAgICAgICAgICAgICAgIGxldCBtaW54ID0gSW5maW5pdHk7XG4gICAgICAgICAgICAgICAgbGV0IG1heHggPSAtSW5maW5pdHk7XG4gICAgICAgICAgICAgICAgbGV0IG1pbnkgPSBJbmZpbml0eTtcbiAgICAgICAgICAgICAgICBsZXQgbWF4eSA9IC1JbmZpbml0eTtcblxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcCBvZiBwcm9qZWN0ZWRQYXRoKSB7XG4gICAgICAgICAgICAgICAgICAgIG1pbnggPSBNYXRoLm1pbihtaW54LCBwWzBdKTtcbiAgICAgICAgICAgICAgICAgICAgbWlueSA9IE1hdGgubWluKG1pbnksIHBbMV0pO1xuICAgICAgICAgICAgICAgICAgICBtYXh4ID0gTWF0aC5tYXgobWF4eCwgcFswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1heHkgPSBNYXRoLm1heChtYXh5LCBwWzFdKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBQYXRoIHZpc2libGVcbiAgICAgICAgICAgICAgICBpZiAobWF4eCA+PSBzY3JlZW5QbGFuZU1pbi54ICYmIG1pbnggPD0gc2NyZWVuUGxhbmVNYXgueCAmJlxuICAgICAgICAgICAgICAgICAgICBtYXh5ID49IHNjcmVlblBsYW5lTWluLnkgJiYgbWlueSA8PSBzY3JlZW5QbGFuZU1heC55KSB7XG5cbiAgICAgICAgICAgICAgICAgICAgc2VnbWVudHMgPSBbcHJvamVjdGVkUGF0aC5tYXAocCA9PiBuZXcgUG9pbnQocFswXSwgcFsxXSkpXTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAobWlueCA8IHNjcmVlblBsYW5lTWluLnggfHwgbWF4eCA+IHNjcmVlblBsYW5lTWF4LnggfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pbnkgPCBzY3JlZW5QbGFuZU1pbi55IHx8IG1heHkgPiBzY3JlZW5QbGFuZU1heC55KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBQYXRoIHBhcnRpYWxseSB2aXNpYmxlLCBjbGlwXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWdtZW50cyA9IGNsaXBMaW5lKHNlZ21lbnRzLCBzY3JlZW5QbGFuZU1pbi54LCBzY3JlZW5QbGFuZU1pbi55LCBzY3JlZW5QbGFuZU1heC54LCBzY3JlZW5QbGFuZU1heC55KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9yIChjb25zdCBzZWcgb2Ygc2VnbWVudHMpIHtcbiAgICAgICAgICAgICAgICAvLyBpbnRlcnBvbGF0ZSBwb3NpdGlvbnMgZm9yIGNvbGxpc2lvbiBjaXJjbGVzLiBBZGQgYSBzbWFsbCBwYWRkaW5nIHRvIGJvdGggZW5kcyBvZiB0aGUgc2VnbWVudFxuICAgICAgICAgICAgICAgIGFzc2VydChzZWcubGVuZ3RoID4gMCk7XG4gICAgICAgICAgICAgICAgaW50ZXJwb2xhdG9yLnJlc2V0KHNlZywgcmFkaXVzICogMC4yNSk7XG5cbiAgICAgICAgICAgICAgICBsZXQgbnVtQ2lyY2xlcyA9IDA7XG5cbiAgICAgICAgICAgICAgICBpZiAoaW50ZXJwb2xhdG9yLmxlbmd0aCA8PSAwLjUgKiByYWRpdXMpIHtcbiAgICAgICAgICAgICAgICAgICAgbnVtQ2lyY2xlcyA9IDE7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbnVtQ2lyY2xlcyA9IE1hdGguY2VpbChpbnRlcnBvbGF0b3IucGFkZGVkTGVuZ3RoIC8gY2lyY2xlRGlzdCkgKyAxO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtQ2lyY2xlczsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHQgPSBpIC8gTWF0aC5tYXgobnVtQ2lyY2xlcyAtIDEsIDEpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjaXJjbGVQb3NpdGlvbiA9IGludGVycG9sYXRvci5sZXJwKHQpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIGFkZCB2aWV3cG9ydCBwYWRkaW5nIHRvIHRoZSBwb3NpdGlvbiBhbmQgcGVyZm9ybSBpbml0aWFsIGNvbGxpc2lvbiBjaGVja1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjZW50ZXJYID0gY2lyY2xlUG9zaXRpb24ueCArIHZpZXdwb3J0UGFkZGluZztcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2VudGVyWSA9IGNpcmNsZVBvc2l0aW9uLnkgKyB2aWV3cG9ydFBhZGRpbmc7XG5cbiAgICAgICAgICAgICAgICAgICAgcGxhY2VkQ29sbGlzaW9uQ2lyY2xlcy5wdXNoKGNlbnRlclgsIGNlbnRlclksIHJhZGl1cywgMCk7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeDEgPSBjZW50ZXJYIC0gcmFkaXVzO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB5MSA9IGNlbnRlclkgLSByYWRpdXM7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHgyID0gY2VudGVyWCArIHJhZGl1cztcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeTIgPSBjZW50ZXJZICsgcmFkaXVzO1xuXG4gICAgICAgICAgICAgICAgICAgIGVudGlyZWx5T2Zmc2NyZWVuID0gZW50aXJlbHlPZmZzY3JlZW4gJiYgdGhpcy5pc09mZnNjcmVlbih4MSwgeTEsIHgyLCB5Mik7XG4gICAgICAgICAgICAgICAgICAgIGluR3JpZCA9IGluR3JpZCB8fCB0aGlzLmlzSW5zaWRlR3JpZCh4MSwgeTEsIHgyLCB5Mik7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFhbGxvd092ZXJsYXApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmdyaWQuaGl0VGVzdENpcmNsZShjZW50ZXJYLCBjZW50ZXJZLCByYWRpdXMsIGNvbGxpc2lvbkdyb3VwUHJlZGljYXRlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERvbid0IGVhcmx5IGV4aXQgaWYgd2UncmUgc2hvd2luZyB0aGUgZGVidWcgY2lyY2xlcyBiZWNhdXNlIHdlIHN0aWxsIHdhbnQgdG8gY2FsY3VsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2hpY2ggY2lyY2xlcyBhcmUgaW4gdXNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sbGlzaW9uRGV0ZWN0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghc2hvd0NvbGxpc2lvbkNpcmNsZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNpcmNsZXM6IFtdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2NyZWVuOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbGxpc2lvbkRldGVjdGVkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2NjbHVkZWQ6IGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNpcmNsZXM6ICgoIXNob3dDb2xsaXNpb25DaXJjbGVzICYmIGNvbGxpc2lvbkRldGVjdGVkKSB8fCAhaW5HcmlkKSA/IFtdIDogcGxhY2VkQ29sbGlzaW9uQ2lyY2xlcyxcbiAgICAgICAgICAgIG9mZnNjcmVlbjogZW50aXJlbHlPZmZzY3JlZW4sXG4gICAgICAgICAgICBjb2xsaXNpb25EZXRlY3RlZCxcbiAgICAgICAgICAgIG9jY2x1ZGVkOiBzY3JlZW5BbmNob3JQb2ludC5vY2NsdWRlZFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEJlY2F1c2UgdGhlIGdlb21ldHJpZXMgaW4gdGhlIENvbGxpc2lvbkluZGV4IGFyZSBhbiBhcHByb3hpbWF0aW9uIG9mIHRoZSBzaGFwZSBvZlxuICAgICAqIHN5bWJvbHMgb24gdGhlIG1hcCwgd2UgdXNlIHRoZSBDb2xsaXNpb25JbmRleCB0byBsb29rIHVwIHRoZSBzeW1ib2wgcGFydCBvZlxuICAgICAqIGBxdWVyeVJlbmRlcmVkRmVhdHVyZXNgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBxdWVyeVJlbmRlcmVkU3ltYm9scyh2aWV3cG9ydFF1ZXJ5R2VvbWV0cnk6IEFycmF5PFBvaW50Pik6IHtbaWQ6IG51bWJlcl06IEFycmF5PG51bWJlcj59IHtcbiAgICAgICAgaWYgKHZpZXdwb3J0UXVlcnlHZW9tZXRyeS5sZW5ndGggPT09IDAgfHwgKHRoaXMuZ3JpZC5rZXlzTGVuZ3RoKCkgPT09IDAgJiYgdGhpcy5pZ25vcmVkR3JpZC5rZXlzTGVuZ3RoKCkgPT09IDApKSB7XG4gICAgICAgICAgICByZXR1cm4ge307XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBxdWVyeSA9IFtdO1xuICAgICAgICBsZXQgbWluWCA9IEluZmluaXR5O1xuICAgICAgICBsZXQgbWluWSA9IEluZmluaXR5O1xuICAgICAgICBsZXQgbWF4WCA9IC1JbmZpbml0eTtcbiAgICAgICAgbGV0IG1heFkgPSAtSW5maW5pdHk7XG4gICAgICAgIGZvciAoY29uc3QgcG9pbnQgb2Ygdmlld3BvcnRRdWVyeUdlb21ldHJ5KSB7XG4gICAgICAgICAgICBjb25zdCBncmlkUG9pbnQgPSBuZXcgUG9pbnQocG9pbnQueCArIHZpZXdwb3J0UGFkZGluZywgcG9pbnQueSArIHZpZXdwb3J0UGFkZGluZyk7XG4gICAgICAgICAgICBtaW5YID0gTWF0aC5taW4obWluWCwgZ3JpZFBvaW50LngpO1xuICAgICAgICAgICAgbWluWSA9IE1hdGgubWluKG1pblksIGdyaWRQb2ludC55KTtcbiAgICAgICAgICAgIG1heFggPSBNYXRoLm1heChtYXhYLCBncmlkUG9pbnQueCk7XG4gICAgICAgICAgICBtYXhZID0gTWF0aC5tYXgobWF4WSwgZ3JpZFBvaW50LnkpO1xuICAgICAgICAgICAgcXVlcnkucHVzaChncmlkUG9pbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmVhdHVyZXMgPSB0aGlzLmdyaWQucXVlcnkobWluWCwgbWluWSwgbWF4WCwgbWF4WSlcbiAgICAgICAgICAgIC5jb25jYXQodGhpcy5pZ25vcmVkR3JpZC5xdWVyeShtaW5YLCBtaW5ZLCBtYXhYLCBtYXhZKSk7XG5cbiAgICAgICAgY29uc3Qgc2VlbkZlYXR1cmVzID0ge307XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHt9O1xuXG4gICAgICAgIGZvciAoY29uc3QgZmVhdHVyZSBvZiBmZWF0dXJlcykge1xuICAgICAgICAgICAgY29uc3QgZmVhdHVyZUtleSA9IGZlYXR1cmUua2V5O1xuICAgICAgICAgICAgLy8gU2tpcCBhbHJlYWR5IHNlZW4gZmVhdHVyZXMuXG4gICAgICAgICAgICBpZiAoc2VlbkZlYXR1cmVzW2ZlYXR1cmVLZXkuYnVja2V0SW5zdGFuY2VJZF0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHNlZW5GZWF0dXJlc1tmZWF0dXJlS2V5LmJ1Y2tldEluc3RhbmNlSWRdID0ge307XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoc2VlbkZlYXR1cmVzW2ZlYXR1cmVLZXkuYnVja2V0SW5zdGFuY2VJZF1bZmVhdHVyZUtleS5mZWF0dXJlSW5kZXhdKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIHF1ZXJ5IGludGVyc2VjdHMgd2l0aCB0aGUgZmVhdHVyZSBib3hcbiAgICAgICAgICAgIC8vIFwiQ29sbGlzaW9uIENpcmNsZXNcIiBmb3IgbGluZSBsYWJlbHMgYXJlIHRyZWF0ZWQgYXMgYm94ZXMgaGVyZVxuICAgICAgICAgICAgLy8gU2luY2UgdGhlcmUncyBubyBhY3R1YWwgY29sbGlzaW9uIHRha2luZyBwbGFjZSwgdGhlIGNpcmNsZSB2cy4gc3F1YXJlXG4gICAgICAgICAgICAvLyBkaXN0aW5jdGlvbiBkb2Vzbid0IG1hdHRlciBhcyBtdWNoLCBhbmQgYm94IGdlb21ldHJ5IGlzIGVhc2llclxuICAgICAgICAgICAgLy8gdG8gd29yayB3aXRoLlxuICAgICAgICAgICAgY29uc3QgYmJveCA9IFtcbiAgICAgICAgICAgICAgICBuZXcgUG9pbnQoZmVhdHVyZS54MSwgZmVhdHVyZS55MSksXG4gICAgICAgICAgICAgICAgbmV3IFBvaW50KGZlYXR1cmUueDIsIGZlYXR1cmUueTEpLFxuICAgICAgICAgICAgICAgIG5ldyBQb2ludChmZWF0dXJlLngyLCBmZWF0dXJlLnkyKSxcbiAgICAgICAgICAgICAgICBuZXcgUG9pbnQoZmVhdHVyZS54MSwgZmVhdHVyZS55MilcbiAgICAgICAgICAgIF07XG4gICAgICAgICAgICBpZiAoIWludGVyc2VjdGlvblRlc3RzLnBvbHlnb25JbnRlcnNlY3RzUG9seWdvbihxdWVyeSwgYmJveCkpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc2VlbkZlYXR1cmVzW2ZlYXR1cmVLZXkuYnVja2V0SW5zdGFuY2VJZF1bZmVhdHVyZUtleS5mZWF0dXJlSW5kZXhdID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChyZXN1bHRbZmVhdHVyZUtleS5idWNrZXRJbnN0YW5jZUlkXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0W2ZlYXR1cmVLZXkuYnVja2V0SW5zdGFuY2VJZF0gPSBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc3VsdFtmZWF0dXJlS2V5LmJ1Y2tldEluc3RhbmNlSWRdLnB1c2goZmVhdHVyZUtleS5mZWF0dXJlSW5kZXgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBpbnNlcnRDb2xsaXNpb25Cb3goY29sbGlzaW9uQm94OiBBcnJheTxudW1iZXI+LCBpZ25vcmVQbGFjZW1lbnQ6IGJvb2xlYW4sIGJ1Y2tldEluc3RhbmNlSWQ6IG51bWJlciwgZmVhdHVyZUluZGV4OiBudW1iZXIsIGNvbGxpc2lvbkdyb3VwSUQ6IG51bWJlcikge1xuICAgICAgICBjb25zdCBncmlkID0gaWdub3JlUGxhY2VtZW50ID8gdGhpcy5pZ25vcmVkR3JpZCA6IHRoaXMuZ3JpZDtcblxuICAgICAgICBjb25zdCBrZXkgPSB7YnVja2V0SW5zdGFuY2VJZCwgZmVhdHVyZUluZGV4LCBjb2xsaXNpb25Hcm91cElEfTtcbiAgICAgICAgZ3JpZC5pbnNlcnQoa2V5LCBjb2xsaXNpb25Cb3hbMF0sIGNvbGxpc2lvbkJveFsxXSwgY29sbGlzaW9uQm94WzJdLCBjb2xsaXNpb25Cb3hbM10pO1xuICAgIH1cblxuICAgIGluc2VydENvbGxpc2lvbkNpcmNsZXMoY29sbGlzaW9uQ2lyY2xlczogQXJyYXk8bnVtYmVyPiwgaWdub3JlUGxhY2VtZW50OiBib29sZWFuLCBidWNrZXRJbnN0YW5jZUlkOiBudW1iZXIsIGZlYXR1cmVJbmRleDogbnVtYmVyLCBjb2xsaXNpb25Hcm91cElEOiBudW1iZXIpIHtcbiAgICAgICAgY29uc3QgZ3JpZCA9IGlnbm9yZVBsYWNlbWVudCA/IHRoaXMuaWdub3JlZEdyaWQgOiB0aGlzLmdyaWQ7XG5cbiAgICAgICAgY29uc3Qga2V5ID0ge2J1Y2tldEluc3RhbmNlSWQsIGZlYXR1cmVJbmRleCwgY29sbGlzaW9uR3JvdXBJRH07XG4gICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgY29sbGlzaW9uQ2lyY2xlcy5sZW5ndGg7IGsgKz0gNCkge1xuICAgICAgICAgICAgZ3JpZC5pbnNlcnRDaXJjbGUoa2V5LCBjb2xsaXNpb25DaXJjbGVzW2tdLCBjb2xsaXNpb25DaXJjbGVzW2sgKyAxXSwgY29sbGlzaW9uQ2lyY2xlc1trICsgMl0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJvamVjdEFuZEdldFBlcnNwZWN0aXZlUmF0aW8ocG9zTWF0cml4OiBNYXQ0LCB4OiBudW1iZXIsIHk6IG51bWJlciwgejogbnVtYmVyLCB0aWxlSUQ6ID9PdmVyc2NhbGVkVGlsZUlELCBjaGVja09jY2x1c2lvbjogYm9vbGVhbiwgYnVja2V0UHJvamVjdGlvbjogUHJvamVjdGlvbik6IFNjcmVlbkFuY2hvclBvaW50IHtcbiAgICAgICAgY29uc3QgcCA9IFt4LCB5LCB6LCAxXTtcbiAgICAgICAgbGV0IGJlaGluZEZvZyA9IGZhbHNlO1xuICAgICAgICBpZiAoeiB8fCB0aGlzLnRyYW5zZm9ybS5waXRjaCA+IDApIHtcbiAgICAgICAgICAgIHZlYzQudHJhbnNmb3JtTWF0NChwLCBwLCBwb3NNYXRyaXgpO1xuICAgICAgICAgICAgLy8gRG8gbm90IHBlcmZvcm0gc3ltYm9sIG9jY2x1c2lvbiBvbiBnbG9iZSBkdWUgdG8gZm9nIGZpeGVkIHJhbmdlXG4gICAgICAgICAgICBjb25zdCBpc0dsb2JlID0gYnVja2V0UHJvamVjdGlvbi5uYW1lID09PSAnZ2xvYmUnO1xuICAgICAgICAgICAgaWYgKHRoaXMuZm9nU3RhdGUgJiYgdGlsZUlEICYmICFpc0dsb2JlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZm9nT3BhY2l0eSA9IGdldEZvZ09wYWNpdHlBdFRpbGVDb29yZCh0aGlzLmZvZ1N0YXRlLCB4LCB5LCB6LCB0aWxlSUQudG9VbndyYXBwZWQoKSwgdGhpcy50cmFuc2Zvcm0pO1xuICAgICAgICAgICAgICAgIGJlaGluZEZvZyA9IGZvZ09wYWNpdHkgPiBGT0dfU1lNQk9MX0NMSVBQSU5HX1RIUkVTSE9MRDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN5bWJvbFByb2plY3Rpb24ueHlUcmFuc2Zvcm1NYXQ0KHAsIHAsIHBvc01hdHJpeCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdyA9IHBbM107XG4gICAgICAgIGNvbnN0IGEgPSBuZXcgUG9pbnQoXG4gICAgICAgICAgICAoKChwWzBdIC8gdyArIDEpIC8gMikgKiB0aGlzLnRyYW5zZm9ybS53aWR0aCkgKyB2aWV3cG9ydFBhZGRpbmcsXG4gICAgICAgICAgICAoKCgtcFsxXSAvIHcgKyAxKSAvIDIpICogdGhpcy50cmFuc2Zvcm0uaGVpZ2h0KSArIHZpZXdwb3J0UGFkZGluZ1xuICAgICAgICApO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcG9pbnQ6IGEsXG4gICAgICAgICAgICAvLyBTZWUgcGVyc3BlY3RpdmUgcmF0aW8gY29tbWVudCBpbiBzeW1ib2xfc2RmLnZlcnRleFxuICAgICAgICAgICAgLy8gV2UncmUgZG9pbmcgY29sbGlzaW9uIGRldGVjdGlvbiBpbiB2aWV3cG9ydCBzcGFjZSBzbyB3ZSBuZWVkXG4gICAgICAgICAgICAvLyB0byBzY2FsZSBkb3duIGJveGVzIGluIHRoZSBkaXN0YW5jZVxuICAgICAgICAgICAgcGVyc3BlY3RpdmVSYXRpbzogTWF0aC5taW4oMC41ICsgMC41ICogKHRoaXMudHJhbnNmb3JtLmdldENhbWVyYVRvQ2VudGVyRGlzdGFuY2UoYnVja2V0UHJvamVjdGlvbikgLyB3KSwgMS41KSxcbiAgICAgICAgICAgIHNpZ25lZERpc3RhbmNlRnJvbUNhbWVyYTogdyxcbiAgICAgICAgICAgIG9jY2x1ZGVkOiAoY2hlY2tPY2NsdXNpb24gJiYgcFsyXSA+IHcpIHx8IGJlaGluZEZvZyAvLyBPY2NsdWRlZCBieSB0aGUgZmFyIHBsYW5lXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgaXNPZmZzY3JlZW4oeDE6IG51bWJlciwgeTE6IG51bWJlciwgeDI6IG51bWJlciwgeTI6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4geDIgPCB2aWV3cG9ydFBhZGRpbmcgfHwgeDEgPj0gdGhpcy5zY3JlZW5SaWdodEJvdW5kYXJ5IHx8IHkyIDwgdmlld3BvcnRQYWRkaW5nIHx8IHkxID4gdGhpcy5zY3JlZW5Cb3R0b21Cb3VuZGFyeTtcbiAgICB9XG5cbiAgICBpc0luc2lkZUdyaWQoeDE6IG51bWJlciwgeTE6IG51bWJlciwgeDI6IG51bWJlciwgeTI6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4geDIgPj0gMCAmJiB4MSA8IHRoaXMuZ3JpZFJpZ2h0Qm91bmRhcnkgJiYgeTIgPj0gMCAmJiB5MSA8IHRoaXMuZ3JpZEJvdHRvbUJvdW5kYXJ5O1xuICAgIH1cblxuICAgIC8qXG4gICAgKiBSZXR1cm5zIGEgbWF0cml4IGZvciB0cmFuc2Zvcm1pbmcgY29sbGlzaW9uIHNoYXBlcyB0byB2aWV3cG9ydCBjb29yZGluYXRlIHNwYWNlLlxuICAgICogVXNlIHRoaXMgZnVuY3Rpb24gdG8gcmVuZGVyIGUuZy4gY29sbGlzaW9uIGNpcmNsZXMgb24gdGhlIHNjcmVlbi5cbiAgICAqICAgZXhhbXBsZSB0cmFuc2Zvcm1hdGlvbjogY2xpcFBvcyA9IGdsQ29vcmRNYXRyaXggKiB2aWV3cG9ydE1hdHJpeCAqIGNpcmNsZV9wb3NcbiAgICAqL1xuICAgIGdldFZpZXdwb3J0TWF0cml4KCk6IE1hdDQge1xuICAgICAgICBjb25zdCBtID0gbWF0NC5pZGVudGl0eShbXSk7XG4gICAgICAgIG1hdDQudHJhbnNsYXRlKG0sIG0sIFstdmlld3BvcnRQYWRkaW5nLCAtdmlld3BvcnRQYWRkaW5nLCAwLjBdKTtcbiAgICAgICAgcmV0dXJuIG07XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDb2xsaXNpb25JbmRleDtcbiIsIi8vIEBmbG93XG5pbXBvcnQgdHlwZSB7T3ZlcnNjYWxlZFRpbGVJRH0gZnJvbSAnLi4vLi4vc291cmNlL3RpbGVfaWQuanMnO1xuaW1wb3J0IHR5cGUgU3ltYm9sQnVja2V0IGZyb20gJy4uLy4uL2RhdGEvYnVja2V0L3N5bWJvbF9idWNrZXQuanMnO1xuaW1wb3J0IHR5cGUgVHJhbnNmb3JtIGZyb20gJy4uLy4uL2dlby90cmFuc2Zvcm0uanMnO1xuaW1wb3J0IHR5cGUgUHJvamVjdGlvbiBmcm9tICcuL3Byb2plY3Rpb24uanMnO1xuaW1wb3J0IHttYXQ0fSBmcm9tICdnbC1tYXRyaXgnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuXG5mdW5jdGlvbiByZWNvbnN0cnVjdFRpbGVNYXRyaXgodHJhbnNmb3JtOiBUcmFuc2Zvcm0sIHByb2plY3Rpb246IFByb2plY3Rpb24sIGNvb3JkOiBPdmVyc2NhbGVkVGlsZUlEKSB7XG4gICAgLy8gQnVja2V0IGJlaW5nIHJlbmRlcmVkIGlzIGJ1aWx0IGZvciBkaWZmZXJlbnQgbWFwIHByb2plY3Rpb25cbiAgICAvLyB0aGFuIGlzIGN1cnJlbnRseSBiZWluZyB1c2VkLiBSZWNvbnN0cnVjdCBjb3JyZWN0IG1hdHJpY2VzLlxuICAgIC8vIFRoaXMgY29kZSBwYXRoIG1heSBoYXBwZW4gZHVyaW5nIGEgR2xvYmUgLSBNZXJjYXRvciB0cmFuc2l0aW9uXG4gICAgY29uc3QgdGlsZU1hdHJpeCA9IHByb2plY3Rpb24uY3JlYXRlVGlsZU1hdHJpeCh0cmFuc2Zvcm0sIHRyYW5zZm9ybS53b3JsZFNpemUsIGNvb3JkLnRvVW53cmFwcGVkKCkpO1xuICAgIHJldHVybiBtYXQ0Lm11bHRpcGx5KG5ldyBGbG9hdDMyQXJyYXkoMTYpLCB0cmFuc2Zvcm0ucHJvak1hdHJpeCwgdGlsZU1hdHJpeCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb2xsaXNpb25EZWJ1Z1RpbGVQcm9qZWN0aW9uTWF0cml4KGNvb3JkOiBPdmVyc2NhbGVkVGlsZUlELCBidWNrZXQ6IFN5bWJvbEJ1Y2tldCwgdHJhbnNmb3JtOiBUcmFuc2Zvcm0pOiBGbG9hdDMyQXJyYXkge1xuICAgIGlmIChidWNrZXQucHJvamVjdGlvbi5uYW1lID09PSB0cmFuc2Zvcm0ucHJvamVjdGlvbi5uYW1lKSB7XG4gICAgICAgIGFzc2VydChjb29yZC5wcm9qTWF0cml4KTtcbiAgICAgICAgcmV0dXJuIGNvb3JkLnByb2pNYXRyaXg7XG4gICAgfVxuICAgIGNvbnN0IHRyID0gdHJhbnNmb3JtLmNsb25lKCk7XG4gICAgdHIuc2V0UHJvamVjdGlvbihidWNrZXQucHJvamVjdGlvbik7XG4gICAgcmV0dXJuIHJlY29uc3RydWN0VGlsZU1hdHJpeCh0ciwgYnVja2V0LmdldFByb2plY3Rpb24oKSwgY29vcmQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U3ltYm9sVGlsZVByb2plY3Rpb25NYXRyaXgoY29vcmQ6IE92ZXJzY2FsZWRUaWxlSUQsIGJ1Y2tldFByb2plY3Rpb246IFByb2plY3Rpb24sIHRyYW5zZm9ybTogVHJhbnNmb3JtKTogRmxvYXQzMkFycmF5IHtcbiAgICBpZiAoYnVja2V0UHJvamVjdGlvbi5uYW1lID09PSB0cmFuc2Zvcm0ucHJvamVjdGlvbi5uYW1lKSB7XG4gICAgICAgIGFzc2VydChjb29yZC5wcm9qTWF0cml4KTtcbiAgICAgICAgcmV0dXJuIGNvb3JkLnByb2pNYXRyaXg7XG4gICAgfVxuICAgIHJldHVybiByZWNvbnN0cnVjdFRpbGVNYXRyaXgodHJhbnNmb3JtLCBidWNrZXRQcm9qZWN0aW9uLCBjb29yZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTeW1ib2xQbGFjZW1lbnRUaWxlUHJvamVjdGlvbk1hdHJpeChjb29yZDogT3ZlcnNjYWxlZFRpbGVJRCwgYnVja2V0UHJvamVjdGlvbjogUHJvamVjdGlvbiwgdHJhbnNmb3JtOiBUcmFuc2Zvcm0sIHJ1bnRpbWVQcm9qZWN0aW9uOiBzdHJpbmcpOiBGbG9hdDMyQXJyYXkge1xuICAgIGlmIChidWNrZXRQcm9qZWN0aW9uLm5hbWUgPT09IHJ1bnRpbWVQcm9qZWN0aW9uKSB7XG4gICAgICAgIHJldHVybiB0cmFuc2Zvcm0uY2FsY3VsYXRlUHJvak1hdHJpeChjb29yZC50b1Vud3JhcHBlZCgpKTtcbiAgICB9XG4gICAgYXNzZXJ0KHRyYW5zZm9ybS5wcm9qZWN0aW9uLm5hbWUgPT09IGJ1Y2tldFByb2plY3Rpb24ubmFtZSk7XG4gICAgcmV0dXJuIHJlY29uc3RydWN0VGlsZU1hdHJpeCh0cmFuc2Zvcm0sIGJ1Y2tldFByb2plY3Rpb24sIGNvb3JkKTtcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBDb2xsaXNpb25JbmRleCBmcm9tICcuL2NvbGxpc2lvbl9pbmRleC5qcyc7XG5pbXBvcnQgRVhURU5UIGZyb20gJy4uL2RhdGEvZXh0ZW50LmpzJztcbmltcG9ydCBPTkVfRU0gZnJvbSAnLi9vbmVfZW0uanMnO1xuaW1wb3J0ICogYXMgc3ltYm9sU2l6ZSBmcm9tICcuL3N5bWJvbF9zaXplLmpzJztcbmltcG9ydCAqIGFzIHByb2plY3Rpb24gZnJvbSAnLi9wcm9qZWN0aW9uLmpzJztcbmltcG9ydCB7Z2V0QW5jaG9ySnVzdGlmaWNhdGlvbiwgZXZhbHVhdGVWYXJpYWJsZU9mZnNldH0gZnJvbSAnLi9zeW1ib2xfbGF5b3V0LmpzJztcbmltcG9ydCB7Z2V0QW5jaG9yQWxpZ25tZW50LCBXcml0aW5nTW9kZX0gZnJvbSAnLi9zaGFwaW5nLmpzJztcbmltcG9ydCB7bWF0NH0gZnJvbSAnZ2wtbWF0cml4JztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCB0eXBlIFRyYW5zZm9ybSBmcm9tICcuLi9nZW8vdHJhbnNmb3JtLmpzJztcbmltcG9ydCB0eXBlIFN0eWxlTGF5ZXIgZnJvbSAnLi4vc3R5bGUvc3R5bGVfbGF5ZXIuanMnO1xuaW1wb3J0IHR5cGUgVGlsZSBmcm9tICcuLi9zb3VyY2UvdGlsZS5qcyc7XG5pbXBvcnQgdHlwZSBTeW1ib2xCdWNrZXQsIHtTeW1ib2xCdWZmZXJzLCBDb2xsaXNpb25BcnJheXMsIFNpbmdsZUNvbGxpc2lvbkJveH0gZnJvbSAnLi4vZGF0YS9idWNrZXQvc3ltYm9sX2J1Y2tldC5qcyc7XG5pbXBvcnQgdHlwZSB7Q29sbGlzaW9uQm94QXJyYXksIENvbGxpc2lvblZlcnRleEFycmF5LCBTeW1ib2xJbnN0YW5jZX0gZnJvbSAnLi4vZGF0YS9hcnJheV90eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSBGZWF0dXJlSW5kZXggZnJvbSAnLi4vZGF0YS9mZWF0dXJlX2luZGV4LmpzJztcbmltcG9ydCB7Z2V0U3ltYm9sUGxhY2VtZW50VGlsZVByb2plY3Rpb25NYXRyaXh9IGZyb20gJy4uL2dlby9wcm9qZWN0aW9uL3Byb2plY3Rpb25fdXRpbC5qcyc7XG5pbXBvcnQgdHlwZSB7T3ZlcnNjYWxlZFRpbGVJRH0gZnJvbSAnLi4vc291cmNlL3RpbGVfaWQuanMnO1xuaW1wb3J0IHR5cGUge1RleHRBbmNob3J9IGZyb20gJy4vc3ltYm9sX2xheW91dC5qcyc7XG5pbXBvcnQgdHlwZSB7Rm9nU3RhdGV9IGZyb20gJy4uL3N0eWxlL2ZvZ19oZWxwZXJzLmpzJztcbmltcG9ydCB0eXBlIHtNYXQ0fSBmcm9tICdnbC1tYXRyaXgnO1xuaW1wb3J0IHR5cGUge1BsYWNlZENvbGxpc2lvbkJveH0gZnJvbSAnLi9jb2xsaXNpb25faW5kZXguanMnO1xuXG4vLyBQbGFjZWRDb2xsaXNpb25Cb3ggd2l0aCBhbGwgZmllbGRzIG9wdGlvbmFsXG50eXBlIFBhcnRpYWxQbGFjZWRDb2xsaXNpb25Cb3ggPSAkT2JqTWFwPFBsYWNlZENvbGxpc2lvbkJveCwgPFY+KCkgPT4gP1Y+O1xuXG5jbGFzcyBPcGFjaXR5U3RhdGUge1xuICAgIG9wYWNpdHk6IG51bWJlcjtcbiAgICBwbGFjZWQ6IGJvb2xlYW47XG4gICAgY29uc3RydWN0b3IocHJldlN0YXRlOiA/T3BhY2l0eVN0YXRlLCBpbmNyZW1lbnQ6IG51bWJlciwgcGxhY2VkOiBib29sZWFuLCBza2lwRmFkZTogP2Jvb2xlYW4pIHtcbiAgICAgICAgaWYgKHByZXZTdGF0ZSkge1xuICAgICAgICAgICAgdGhpcy5vcGFjaXR5ID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oMSwgcHJldlN0YXRlLm9wYWNpdHkgKyAocHJldlN0YXRlLnBsYWNlZCA/IGluY3JlbWVudCA6IC1pbmNyZW1lbnQpKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLm9wYWNpdHkgPSAoc2tpcEZhZGUgJiYgcGxhY2VkKSA/IDEgOiAwO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucGxhY2VkID0gcGxhY2VkO1xuICAgIH1cbiAgICBpc0hpZGRlbigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMub3BhY2l0eSA9PT0gMCAmJiAhdGhpcy5wbGFjZWQ7XG4gICAgfVxufVxuXG5jbGFzcyBKb2ludE9wYWNpdHlTdGF0ZSB7XG4gICAgdGV4dDogT3BhY2l0eVN0YXRlO1xuICAgIGljb246IE9wYWNpdHlTdGF0ZTtcbiAgICBjbGlwcGVkOiBib29sZWFuO1xuICAgIGNvbnN0cnVjdG9yKHByZXZTdGF0ZTogP0pvaW50T3BhY2l0eVN0YXRlLCBpbmNyZW1lbnQ6IG51bWJlciwgcGxhY2VkVGV4dDogYm9vbGVhbiwgcGxhY2VkSWNvbjogYm9vbGVhbiwgc2tpcEZhZGU6ID9ib29sZWFuLCBjbGlwcGVkOiBib29sZWFuID0gZmFsc2UpIHtcbiAgICAgICAgdGhpcy50ZXh0ID0gbmV3IE9wYWNpdHlTdGF0ZShwcmV2U3RhdGUgPyBwcmV2U3RhdGUudGV4dCA6IG51bGwsIGluY3JlbWVudCwgcGxhY2VkVGV4dCwgc2tpcEZhZGUpO1xuICAgICAgICB0aGlzLmljb24gPSBuZXcgT3BhY2l0eVN0YXRlKHByZXZTdGF0ZSA/IHByZXZTdGF0ZS5pY29uIDogbnVsbCwgaW5jcmVtZW50LCBwbGFjZWRJY29uLCBza2lwRmFkZSk7XG5cbiAgICAgICAgdGhpcy5jbGlwcGVkID0gY2xpcHBlZDtcbiAgICB9XG4gICAgaXNIaWRkZW4oKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLnRleHQuaXNIaWRkZW4oKSAmJiB0aGlzLmljb24uaXNIaWRkZW4oKTtcbiAgICB9XG59XG5cbmNsYXNzIEpvaW50UGxhY2VtZW50IHtcbiAgICB0ZXh0OiBib29sZWFuO1xuICAgIGljb246IGJvb2xlYW47XG4gICAgLy8gc2tpcEZhZGUgPSBvdXRzaWRlIHZpZXdwb3J0LCBidXQgd2l0aGluIENvbGxpc2lvbkluZGV4Ojp2aWV3cG9ydFBhZGRpbmcgcHggb2YgdGhlIGVkZ2VcbiAgICAvLyBCZWNhdXNlIHRoZXNlIHN5bWJvbHMgYXJlbid0IG9uc2NyZWVuIHlldCwgd2UgY2FuIHNraXAgdGhlIFwiZmFkZSBpblwiIGFuaW1hdGlvbixcbiAgICAvLyBhbmQgaWYgYSBzdWJzZXF1ZW50IHZpZXdwb3J0IGNoYW5nZSBicmluZ3MgdGhlbSBpbnRvIHZpZXcsIHRoZXknbGwgYmUgZnVsbHlcbiAgICAvLyB2aXNpYmxlIHJpZ2h0IGF3YXkuXG4gICAgc2tpcEZhZGU6IGJvb2xlYW47XG5cbiAgICBjbGlwcGVkOiBib29sZWFuXG4gICAgY29uc3RydWN0b3IodGV4dDogYm9vbGVhbiwgaWNvbjogYm9vbGVhbiwgc2tpcEZhZGU6IGJvb2xlYW4sIGNsaXBwZWQ6IGJvb2xlYW4gPSBmYWxzZSkge1xuICAgICAgICB0aGlzLnRleHQgPSB0ZXh0O1xuICAgICAgICB0aGlzLmljb24gPSBpY29uO1xuICAgICAgICB0aGlzLnNraXBGYWRlID0gc2tpcEZhZGU7XG4gICAgICAgIHRoaXMuY2xpcHBlZCA9IGNsaXBwZWQ7XG4gICAgfVxufVxuXG5jbGFzcyBDb2xsaXNpb25DaXJjbGVBcnJheSB7XG4gICAgLy8gU3RvcmVzIGNvbGxpc2lvbiBjaXJjbGVzIGFuZCBwbGFjZW1lbnQgbWF0cmljZXMgb2YgYSBidWNrZXQgZm9yIGRlYnVnIHJlbmRlcmluZy5cbiAgICBpbnZQcm9qTWF0cml4OiBNYXQ0O1xuICAgIHZpZXdwb3J0TWF0cml4OiBNYXQ0O1xuICAgIGNpcmNsZXM6IEFycmF5PG51bWJlcj47XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5pbnZQcm9qTWF0cml4ID0gbWF0NC5jcmVhdGUoKTtcbiAgICAgICAgdGhpcy52aWV3cG9ydE1hdHJpeCA9IG1hdDQuY3JlYXRlKCk7XG4gICAgICAgIHRoaXMuY2lyY2xlcyA9IFtdO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFJldGFpbmVkUXVlcnlEYXRhIHtcbiAgICBidWNrZXRJbnN0YW5jZUlkOiBudW1iZXI7XG4gICAgZmVhdHVyZUluZGV4OiBGZWF0dXJlSW5kZXg7XG4gICAgc291cmNlTGF5ZXJJbmRleDogbnVtYmVyO1xuICAgIGJ1Y2tldEluZGV4OiBudW1iZXI7XG4gICAgdGlsZUlEOiBPdmVyc2NhbGVkVGlsZUlEO1xuICAgIGZlYXR1cmVTb3J0T3JkZXI6ID9BcnJheTxudW1iZXI+XG4gICAgY29uc3RydWN0b3IoYnVja2V0SW5zdGFuY2VJZDogbnVtYmVyLFxuICAgICAgICAgICAgICAgIGZlYXR1cmVJbmRleDogRmVhdHVyZUluZGV4LFxuICAgICAgICAgICAgICAgIHNvdXJjZUxheWVySW5kZXg6IG51bWJlcixcbiAgICAgICAgICAgICAgICBidWNrZXRJbmRleDogbnVtYmVyLFxuICAgICAgICAgICAgICAgIHRpbGVJRDogT3ZlcnNjYWxlZFRpbGVJRCkge1xuICAgICAgICB0aGlzLmJ1Y2tldEluc3RhbmNlSWQgPSBidWNrZXRJbnN0YW5jZUlkO1xuICAgICAgICB0aGlzLmZlYXR1cmVJbmRleCA9IGZlYXR1cmVJbmRleDtcbiAgICAgICAgdGhpcy5zb3VyY2VMYXllckluZGV4ID0gc291cmNlTGF5ZXJJbmRleDtcbiAgICAgICAgdGhpcy5idWNrZXRJbmRleCA9IGJ1Y2tldEluZGV4O1xuICAgICAgICB0aGlzLnRpbGVJRCA9IHRpbGVJRDtcbiAgICB9XG59XG5cbnR5cGUgQ29sbGlzaW9uR3JvdXAgPSB7fElEOiBudW1iZXIsIHByZWRpY2F0ZT86IGFueXx9O1xuXG5jbGFzcyBDb2xsaXNpb25Hcm91cHMge1xuICAgIGNvbGxpc2lvbkdyb3Vwczoge1tncm91cE5hbWU6IHN0cmluZ106IENvbGxpc2lvbkdyb3VwfTtcbiAgICBtYXhHcm91cElEOiBudW1iZXI7XG4gICAgY3Jvc3NTb3VyY2VDb2xsaXNpb25zOiBib29sZWFuO1xuXG4gICAgY29uc3RydWN0b3IoY3Jvc3NTb3VyY2VDb2xsaXNpb25zOiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMuY3Jvc3NTb3VyY2VDb2xsaXNpb25zID0gY3Jvc3NTb3VyY2VDb2xsaXNpb25zO1xuICAgICAgICB0aGlzLm1heEdyb3VwSUQgPSAwO1xuICAgICAgICB0aGlzLmNvbGxpc2lvbkdyb3VwcyA9IHt9O1xuICAgIH1cblxuICAgIGdldChzb3VyY2VJRDogc3RyaW5nKTogQ29sbGlzaW9uR3JvdXAge1xuICAgICAgICAvLyBUaGUgcHJlZGljYXRlL2dyb3VwSUQgbWVjaGFuaXNtIGFsbG93cyBmb3IgYXJiaXRyYXJ5IGdyb3VwaW5nLFxuICAgICAgICAvLyBidXQgdGhlIGN1cnJlbnQgaW50ZXJmYWNlIGRlZmluZXMgb25lIHNvdXJjZSA9PSBvbmUgZ3JvdXAgd2hlblxuICAgICAgICAvLyBjcm9zc1NvdXJjZUNvbGxpc2lvbnMgPT0gdHJ1ZS5cbiAgICAgICAgaWYgKCF0aGlzLmNyb3NzU291cmNlQ29sbGlzaW9ucykge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbGxpc2lvbkdyb3Vwc1tzb3VyY2VJRF0pIHtcbiAgICAgICAgICAgICAgICBjb25zdCBuZXh0R3JvdXBJRCA9ICsrdGhpcy5tYXhHcm91cElEO1xuICAgICAgICAgICAgICAgIHRoaXMuY29sbGlzaW9uR3JvdXBzW3NvdXJjZUlEXSA9IHtcbiAgICAgICAgICAgICAgICAgICAgSUQ6IG5leHRHcm91cElELFxuICAgICAgICAgICAgICAgICAgICBwcmVkaWNhdGU6IChrZXkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBrZXkuY29sbGlzaW9uR3JvdXBJRCA9PT0gbmV4dEdyb3VwSUQ7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29sbGlzaW9uR3JvdXBzW3NvdXJjZUlEXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB7SUQ6IDAsIHByZWRpY2F0ZTogbnVsbH07XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIGNhbGN1bGF0ZVZhcmlhYmxlTGF5b3V0U2hpZnQoYW5jaG9yOiBUZXh0QW5jaG9yLCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciwgdGV4dE9mZnNldDogW251bWJlciwgbnVtYmVyXSwgdGV4dFNjYWxlOiBudW1iZXIpOiBQb2ludCB7XG4gICAgY29uc3Qge2hvcml6b250YWxBbGlnbiwgdmVydGljYWxBbGlnbn0gPSBnZXRBbmNob3JBbGlnbm1lbnQoYW5jaG9yKTtcbiAgICBjb25zdCBzaGlmdFggPSAtKGhvcml6b250YWxBbGlnbiAtIDAuNSkgKiB3aWR0aDtcbiAgICBjb25zdCBzaGlmdFkgPSAtKHZlcnRpY2FsQWxpZ24gLSAwLjUpICogaGVpZ2h0O1xuICAgIGNvbnN0IG9mZnNldCA9IGV2YWx1YXRlVmFyaWFibGVPZmZzZXQoYW5jaG9yLCB0ZXh0T2Zmc2V0KTtcbiAgICByZXR1cm4gbmV3IFBvaW50KFxuICAgICAgICBzaGlmdFggKyBvZmZzZXRbMF0gKiB0ZXh0U2NhbGUsXG4gICAgICAgIHNoaWZ0WSArIG9mZnNldFsxXSAqIHRleHRTY2FsZVxuICAgICk7XG59XG5cbmZ1bmN0aW9uIG9mZnNldFNoaWZ0KHNoaWZ0WDogbnVtYmVyLCBzaGlmdFk6IG51bWJlciwgcm90YXRlV2l0aE1hcDogYm9vbGVhbiwgcGl0Y2hXaXRoTWFwOiBib29sZWFuLCBhbmdsZTogbnVtYmVyKTogUG9pbnQge1xuICAgIGNvbnN0IHNoaWZ0ID0gbmV3IFBvaW50KHNoaWZ0WCwgc2hpZnRZKTtcbiAgICBpZiAocm90YXRlV2l0aE1hcCkge1xuICAgICAgICBzaGlmdC5fcm90YXRlKHBpdGNoV2l0aE1hcCA/IGFuZ2xlIDogLWFuZ2xlKTtcbiAgICB9XG4gICAgcmV0dXJuIHNoaWZ0O1xufVxuXG5leHBvcnQgdHlwZSBWYXJpYWJsZU9mZnNldCA9IHtcbiAgICB0ZXh0T2Zmc2V0OiBbbnVtYmVyLCBudW1iZXJdLFxuICAgIHdpZHRoOiBudW1iZXIsXG4gICAgaGVpZ2h0OiBudW1iZXIsXG4gICAgYW5jaG9yOiBUZXh0QW5jaG9yLFxuICAgIHRleHRTY2FsZTogbnVtYmVyLFxuICAgIHByZXZBbmNob3I/OiBUZXh0QW5jaG9yXG59O1xuXG50eXBlIFRpbGVMYXllclBhcmFtZXRlcnMgPSB7XG4gICAgYnVja2V0OiBTeW1ib2xCdWNrZXQsXG4gICAgbGF5b3V0OiBhbnksXG4gICAgcG9zTWF0cml4OiBNYXQ0LFxuICAgIHRleHRMYWJlbFBsYW5lTWF0cml4OiBNYXQ0LFxuICAgIGxhYmVsVG9TY3JlZW5NYXRyaXg6ID9NYXQ0LFxuICAgIHNjYWxlOiBudW1iZXIsXG4gICAgdGV4dFBpeGVsUmF0aW86IG51bWJlcixcbiAgICBob2xkaW5nRm9yRmFkZTogYm9vbGVhbixcbiAgICBjb2xsaXNpb25Cb3hBcnJheTogP0NvbGxpc2lvbkJveEFycmF5LFxuICAgIHBhcnRpYWxseUV2YWx1YXRlZFRleHRTaXplOiBhbnksXG4gICAgY29sbGlzaW9uR3JvdXA6IGFueVxufTtcblxuZXhwb3J0IHR5cGUgQnVja2V0UGFydCA9IHtcbiAgICBzb3J0S2V5PzogbnVtYmVyIHwgdm9pZCxcbiAgICBzeW1ib2xJbnN0YW5jZVN0YXJ0OiBudW1iZXIsXG4gICAgc3ltYm9sSW5zdGFuY2VFbmQ6IG51bWJlcixcbiAgICBwYXJhbWV0ZXJzOiBUaWxlTGF5ZXJQYXJhbWV0ZXJzXG59O1xuXG5leHBvcnQgdHlwZSBDcm9zc1RpbGVJRCA9IHN0cmluZyB8IG51bWJlcjtcblxuZXhwb3J0IGNsYXNzIFBsYWNlbWVudCB7XG4gICAgcHJvamVjdGlvbjogc3RyaW5nO1xuICAgIHRyYW5zZm9ybTogVHJhbnNmb3JtO1xuICAgIGNvbGxpc2lvbkluZGV4OiBDb2xsaXNpb25JbmRleDtcbiAgICBwbGFjZW1lbnRzOiB7IFtfOiBDcm9zc1RpbGVJRF06IEpvaW50UGxhY2VtZW50IH07XG4gICAgb3BhY2l0aWVzOiB7IFtfOiBDcm9zc1RpbGVJRF06IEpvaW50T3BhY2l0eVN0YXRlIH07XG4gICAgdmFyaWFibGVPZmZzZXRzOiB7W186IENyb3NzVGlsZUlEXTogVmFyaWFibGVPZmZzZXQgfTtcbiAgICBwbGFjZWRPcmllbnRhdGlvbnM6IHtbXzogQ3Jvc3NUaWxlSURdOiBudW1iZXIgfTtcbiAgICBjb21taXRUaW1lOiBudW1iZXI7XG4gICAgcHJldlpvb21BZGp1c3RtZW50OiBudW1iZXI7XG4gICAgbGFzdFBsYWNlbWVudENoYW5nZVRpbWU6IG51bWJlcjtcbiAgICBzdGFsZTogYm9vbGVhbjtcbiAgICBmYWRlRHVyYXRpb246IG51bWJlcjtcbiAgICByZXRhaW5lZFF1ZXJ5RGF0YToge1tfOiBudW1iZXJdOiBSZXRhaW5lZFF1ZXJ5RGF0YX07XG4gICAgY29sbGlzaW9uR3JvdXBzOiBDb2xsaXNpb25Hcm91cHM7XG4gICAgcHJldlBsYWNlbWVudDogP1BsYWNlbWVudDtcbiAgICB6b29tQXRMYXN0UmVjZW5jeUNoZWNrOiBudW1iZXI7XG4gICAgY29sbGlzaW9uQ2lyY2xlQXJyYXlzOiB7W2FueV06IENvbGxpc2lvbkNpcmNsZUFycmF5fTtcblxuICAgIGNvbnN0cnVjdG9yKHRyYW5zZm9ybTogVHJhbnNmb3JtLCBmYWRlRHVyYXRpb246IG51bWJlciwgY3Jvc3NTb3VyY2VDb2xsaXNpb25zOiBib29sZWFuLCBwcmV2UGxhY2VtZW50PzogUGxhY2VtZW50LCBmb2dTdGF0ZTogP0ZvZ1N0YXRlKSB7XG4gICAgICAgIHRoaXMudHJhbnNmb3JtID0gdHJhbnNmb3JtLmNsb25lKCk7XG4gICAgICAgIHRoaXMucHJvamVjdGlvbiA9IHRyYW5zZm9ybS5wcm9qZWN0aW9uLm5hbWU7XG4gICAgICAgIHRoaXMuY29sbGlzaW9uSW5kZXggPSBuZXcgQ29sbGlzaW9uSW5kZXgodGhpcy50cmFuc2Zvcm0sIGZvZ1N0YXRlKTtcbiAgICAgICAgdGhpcy5wbGFjZW1lbnRzID0ge307XG4gICAgICAgIHRoaXMub3BhY2l0aWVzID0ge307XG4gICAgICAgIHRoaXMudmFyaWFibGVPZmZzZXRzID0ge307XG4gICAgICAgIHRoaXMuc3RhbGUgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5jb21taXRUaW1lID0gMDtcbiAgICAgICAgdGhpcy5mYWRlRHVyYXRpb24gPSBmYWRlRHVyYXRpb247XG4gICAgICAgIHRoaXMucmV0YWluZWRRdWVyeURhdGEgPSB7fTtcbiAgICAgICAgdGhpcy5jb2xsaXNpb25Hcm91cHMgPSBuZXcgQ29sbGlzaW9uR3JvdXBzKGNyb3NzU291cmNlQ29sbGlzaW9ucyk7XG4gICAgICAgIHRoaXMuY29sbGlzaW9uQ2lyY2xlQXJyYXlzID0ge307XG5cbiAgICAgICAgdGhpcy5wcmV2UGxhY2VtZW50ID0gcHJldlBsYWNlbWVudDtcbiAgICAgICAgaWYgKHByZXZQbGFjZW1lbnQpIHtcbiAgICAgICAgICAgIHByZXZQbGFjZW1lbnQucHJldlBsYWNlbWVudCA9IHVuZGVmaW5lZDsgLy8gT25seSBob2xkIG9uIHRvIG9uZSBwbGFjZW1lbnQgYmFja1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5wbGFjZWRPcmllbnRhdGlvbnMgPSB7fTtcbiAgICB9XG5cbiAgICBnZXRCdWNrZXRQYXJ0cyhyZXN1bHRzOiBBcnJheTxCdWNrZXRQYXJ0Piwgc3R5bGVMYXllcjogU3R5bGVMYXllciwgdGlsZTogVGlsZSwgc29ydEFjcm9zc1RpbGVzOiBib29sZWFuKSB7XG4gICAgICAgIGNvbnN0IHN5bWJvbEJ1Y2tldCA9ICgodGlsZS5nZXRCdWNrZXQoc3R5bGVMYXllcik6IGFueSk6IFN5bWJvbEJ1Y2tldCk7XG4gICAgICAgIGNvbnN0IGJ1Y2tldEZlYXR1cmVJbmRleCA9IHRpbGUubGF0ZXN0RmVhdHVyZUluZGV4O1xuXG4gICAgICAgIGlmICghc3ltYm9sQnVja2V0IHx8ICFidWNrZXRGZWF0dXJlSW5kZXggfHwgc3R5bGVMYXllci5pZCAhPT0gc3ltYm9sQnVja2V0LmxheWVySWRzWzBdKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IGxheW91dCA9IHN5bWJvbEJ1Y2tldC5sYXllcnNbMF0ubGF5b3V0O1xuXG4gICAgICAgIGNvbnN0IGNvbGxpc2lvbkJveEFycmF5ID0gdGlsZS5jb2xsaXNpb25Cb3hBcnJheTtcbiAgICAgICAgY29uc3Qgc2NhbGUgPSBNYXRoLnBvdygyLCB0aGlzLnRyYW5zZm9ybS56b29tIC0gdGlsZS50aWxlSUQub3ZlcnNjYWxlZFopO1xuICAgICAgICBjb25zdCB0ZXh0UGl4ZWxSYXRpbyA9IHRpbGUudGlsZVNpemUgLyBFWFRFTlQ7XG4gICAgICAgIGNvbnN0IHVud3JhcHBlZFRpbGVJRCA9IHRpbGUudGlsZUlELnRvVW53cmFwcGVkKCk7XG5cbiAgICAgICAgdGhpcy50cmFuc2Zvcm0uc2V0UHJvamVjdGlvbihzeW1ib2xCdWNrZXQucHJvamVjdGlvbik7XG5cbiAgICAgICAgY29uc3QgcG9zTWF0cml4ID0gZ2V0U3ltYm9sUGxhY2VtZW50VGlsZVByb2plY3Rpb25NYXRyaXgodGlsZS50aWxlSUQsIHN5bWJvbEJ1Y2tldC5nZXRQcm9qZWN0aW9uKCksIHRoaXMudHJhbnNmb3JtLCB0aGlzLnByb2plY3Rpb24pO1xuXG4gICAgICAgIGNvbnN0IHBpdGNoV2l0aE1hcCA9IGxheW91dC5nZXQoJ3RleHQtcGl0Y2gtYWxpZ25tZW50JykgPT09ICdtYXAnO1xuICAgICAgICBjb25zdCByb3RhdGVXaXRoTWFwID0gbGF5b3V0LmdldCgndGV4dC1yb3RhdGlvbi1hbGlnbm1lbnQnKSA9PT0gJ21hcCc7XG5cbiAgICAgICAgc3R5bGVMYXllci5jb21waWxlRmlsdGVyKCk7XG5cbiAgICAgICAgY29uc3QgZHluYW1pY0ZpbHRlciA9IHN0eWxlTGF5ZXIuZHluYW1pY0ZpbHRlcigpO1xuICAgICAgICBjb25zdCBkeW5hbWljRmlsdGVyTmVlZHNGZWF0dXJlID0gc3R5bGVMYXllci5keW5hbWljRmlsdGVyTmVlZHNGZWF0dXJlKCk7XG4gICAgICAgIGNvbnN0IHBpeGVsc1RvVGlsZXMgPSB0aGlzLnRyYW5zZm9ybS5jYWxjdWxhdGVQaXhlbHNUb1RpbGVVbml0c01hdHJpeCh0aWxlKTtcblxuICAgICAgICBjb25zdCB0ZXh0TGFiZWxQbGFuZU1hdHJpeCA9IHByb2plY3Rpb24uZ2V0TGFiZWxQbGFuZU1hdHJpeEZvclBsYWNlbWVudChwb3NNYXRyaXgsXG4gICAgICAgICAgICAgICAgdGlsZS50aWxlSUQuY2Fub25pY2FsLFxuICAgICAgICAgICAgICAgIHBpdGNoV2l0aE1hcCxcbiAgICAgICAgICAgICAgICByb3RhdGVXaXRoTWFwLFxuICAgICAgICAgICAgICAgIHRoaXMudHJhbnNmb3JtLFxuICAgICAgICAgICAgICAgIHN5bWJvbEJ1Y2tldC5nZXRQcm9qZWN0aW9uKCksXG4gICAgICAgICAgICAgICAgcGl4ZWxzVG9UaWxlcyk7XG5cbiAgICAgICAgbGV0IGxhYmVsVG9TY3JlZW5NYXRyaXggPSBudWxsO1xuXG4gICAgICAgIGlmIChwaXRjaFdpdGhNYXApIHtcbiAgICAgICAgICAgIGNvbnN0IGdsTWF0cml4ID0gcHJvamVjdGlvbi5nZXRHbENvb3JkTWF0cml4KFxuICAgICAgICAgICAgICAgIHBvc01hdHJpeCxcbiAgICAgICAgICAgICAgICB0aWxlLnRpbGVJRC5jYW5vbmljYWwsXG4gICAgICAgICAgICAgICAgcGl0Y2hXaXRoTWFwLFxuICAgICAgICAgICAgICAgIHJvdGF0ZVdpdGhNYXAsXG4gICAgICAgICAgICAgICAgdGhpcy50cmFuc2Zvcm0sXG4gICAgICAgICAgICAgICAgc3ltYm9sQnVja2V0LmdldFByb2plY3Rpb24oKSxcbiAgICAgICAgICAgICAgICBwaXhlbHNUb1RpbGVzKTtcblxuICAgICAgICAgICAgbGFiZWxUb1NjcmVlbk1hdHJpeCA9IG1hdDQubXVsdGlwbHkoW10sIHRoaXMudHJhbnNmb3JtLmxhYmVsUGxhbmVNYXRyaXgsIGdsTWF0cml4KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBjbGlwcGluZ0RhdGEgPSBudWxsO1xuICAgICAgICBhc3NlcnQoISF0aWxlLmxhdGVzdEZlYXR1cmVJbmRleCk7XG4gICAgICAgIGlmICghIWR5bmFtaWNGaWx0ZXIgJiYgdGlsZS5sYXRlc3RGZWF0dXJlSW5kZXgpIHtcblxuICAgICAgICAgICAgY2xpcHBpbmdEYXRhID0ge1xuICAgICAgICAgICAgICAgIHVud3JhcHBlZFRpbGVJRCxcbiAgICAgICAgICAgICAgICBkeW5hbWljRmlsdGVyLFxuICAgICAgICAgICAgICAgIGR5bmFtaWNGaWx0ZXJOZWVkc0ZlYXR1cmUsXG4gICAgICAgICAgICAgICAgZmVhdHVyZUluZGV4OiB0aWxlLmxhdGVzdEZlYXR1cmVJbmRleFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFzIGxvbmcgYXMgdGhpcyBwbGFjZW1lbnQgbGl2ZXMsIHdlIGhhdmUgdG8gaG9sZCBvbnRvIHRoaXMgYnVja2V0J3NcbiAgICAgICAgLy8gbWF0Y2hpbmcgRmVhdHVyZUluZGV4L2RhdGEgZm9yIHF1ZXJ5aW5nIHB1cnBvc2VzXG4gICAgICAgIHRoaXMucmV0YWluZWRRdWVyeURhdGFbc3ltYm9sQnVja2V0LmJ1Y2tldEluc3RhbmNlSWRdID0gbmV3IFJldGFpbmVkUXVlcnlEYXRhKFxuICAgICAgICAgICAgc3ltYm9sQnVja2V0LmJ1Y2tldEluc3RhbmNlSWQsXG4gICAgICAgICAgICBidWNrZXRGZWF0dXJlSW5kZXgsXG4gICAgICAgICAgICBzeW1ib2xCdWNrZXQuc291cmNlTGF5ZXJJbmRleCxcbiAgICAgICAgICAgIHN5bWJvbEJ1Y2tldC5pbmRleCxcbiAgICAgICAgICAgIHRpbGUudGlsZUlEXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgcGFyYW1ldGVycyA9IHtcbiAgICAgICAgICAgIGJ1Y2tldDogc3ltYm9sQnVja2V0LFxuICAgICAgICAgICAgbGF5b3V0LFxuICAgICAgICAgICAgcG9zTWF0cml4LFxuICAgICAgICAgICAgdGV4dExhYmVsUGxhbmVNYXRyaXgsXG4gICAgICAgICAgICBsYWJlbFRvU2NyZWVuTWF0cml4LFxuICAgICAgICAgICAgY2xpcHBpbmdEYXRhLFxuICAgICAgICAgICAgc2NhbGUsXG4gICAgICAgICAgICB0ZXh0UGl4ZWxSYXRpbyxcbiAgICAgICAgICAgIGhvbGRpbmdGb3JGYWRlOiB0aWxlLmhvbGRpbmdGb3JGYWRlKCksXG4gICAgICAgICAgICBjb2xsaXNpb25Cb3hBcnJheSxcbiAgICAgICAgICAgIHBhcnRpYWxseUV2YWx1YXRlZFRleHRTaXplOiBzeW1ib2xTaXplLmV2YWx1YXRlU2l6ZUZvclpvb20oc3ltYm9sQnVja2V0LnRleHRTaXplRGF0YSwgdGhpcy50cmFuc2Zvcm0uem9vbSksXG4gICAgICAgICAgICBwYXJ0aWFsbHlFdmFsdWF0ZWRJY29uU2l6ZTogc3ltYm9sU2l6ZS5ldmFsdWF0ZVNpemVGb3Jab29tKHN5bWJvbEJ1Y2tldC5pY29uU2l6ZURhdGEsIHRoaXMudHJhbnNmb3JtLnpvb20pLFxuICAgICAgICAgICAgY29sbGlzaW9uR3JvdXA6IHRoaXMuY29sbGlzaW9uR3JvdXBzLmdldChzeW1ib2xCdWNrZXQuc291cmNlSUQpXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKHNvcnRBY3Jvc3NUaWxlcykge1xuICAgICAgICAgICAgZm9yIChjb25zdCByYW5nZSBvZiBzeW1ib2xCdWNrZXQuc29ydEtleVJhbmdlcykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHtzb3J0S2V5LCBzeW1ib2xJbnN0YW5jZVN0YXJ0LCBzeW1ib2xJbnN0YW5jZUVuZH0gPSByYW5nZTtcbiAgICAgICAgICAgICAgICByZXN1bHRzLnB1c2goe3NvcnRLZXksIHN5bWJvbEluc3RhbmNlU3RhcnQsIHN5bWJvbEluc3RhbmNlRW5kLCBwYXJhbWV0ZXJzfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXN1bHRzLnB1c2goe1xuICAgICAgICAgICAgICAgIHN5bWJvbEluc3RhbmNlU3RhcnQ6IDAsXG4gICAgICAgICAgICAgICAgc3ltYm9sSW5zdGFuY2VFbmQ6IHN5bWJvbEJ1Y2tldC5zeW1ib2xJbnN0YW5jZXMubGVuZ3RoLFxuICAgICAgICAgICAgICAgIHBhcmFtZXRlcnNcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXR0ZW1wdEFuY2hvclBsYWNlbWVudChhbmNob3I6IFRleHRBbmNob3IsIHRleHRCb3g6IFNpbmdsZUNvbGxpc2lvbkJveCwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0U2NhbGU6IG51bWJlciwgcm90YXRlV2l0aE1hcDogYm9vbGVhbiwgcGl0Y2hXaXRoTWFwOiBib29sZWFuLCB0ZXh0UGl4ZWxSYXRpbzogbnVtYmVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zTWF0cml4OiBNYXQ0LCBjb2xsaXNpb25Hcm91cDogQ29sbGlzaW9uR3JvdXAsIHRleHRBbGxvd092ZXJsYXA6IGJvb2xlYW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1ib2xJbnN0YW5jZTogU3ltYm9sSW5zdGFuY2UsIGJveEluZGV4OiBudW1iZXIsIGJ1Y2tldDogU3ltYm9sQnVja2V0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb246IG51bWJlciwgaWNvbkJveDogP1NpbmdsZUNvbGxpc2lvbkJveCwgdGV4dFNpemU6IGFueSwgaWNvblNpemU6IGFueSk6ID97IHNoaWZ0OiBQb2ludCwgcGxhY2VkR2x5cGhCb3hlczogUGxhY2VkQ29sbGlzaW9uQm94IH0gIHtcblxuICAgICAgICBjb25zdCB7dGV4dE9mZnNldDAsIHRleHRPZmZzZXQxLCBjcm9zc1RpbGVJRH0gPSBzeW1ib2xJbnN0YW5jZTtcbiAgICAgICAgY29uc3QgdGV4dE9mZnNldCA9IFt0ZXh0T2Zmc2V0MCwgdGV4dE9mZnNldDFdO1xuICAgICAgICBjb25zdCBzaGlmdCA9IGNhbGN1bGF0ZVZhcmlhYmxlTGF5b3V0U2hpZnQoYW5jaG9yLCB3aWR0aCwgaGVpZ2h0LCB0ZXh0T2Zmc2V0LCB0ZXh0U2NhbGUpO1xuXG4gICAgICAgIGNvbnN0IHBsYWNlZEdseXBoQm94ZXMgPSB0aGlzLmNvbGxpc2lvbkluZGV4LnBsYWNlQ29sbGlzaW9uQm94KFxuICAgICAgICAgICAgYnVja2V0LCB0ZXh0U2NhbGUsIHRleHRCb3gsIG9mZnNldFNoaWZ0KHNoaWZ0LngsIHNoaWZ0LnksIHJvdGF0ZVdpdGhNYXAsIHBpdGNoV2l0aE1hcCwgdGhpcy50cmFuc2Zvcm0uYW5nbGUpLFxuICAgICAgICAgICAgdGV4dEFsbG93T3ZlcmxhcCwgdGV4dFBpeGVsUmF0aW8sIHBvc01hdHJpeCwgY29sbGlzaW9uR3JvdXAucHJlZGljYXRlKTtcbiAgICAgICAgaWYgKGljb25Cb3gpIHtcbiAgICAgICAgICAgIGNvbnN0IHNpemUgPSBidWNrZXQuZ2V0U3ltYm9sSW5zdGFuY2VJY29uU2l6ZShpY29uU2l6ZSwgdGhpcy50cmFuc2Zvcm0uem9vbSwgc3ltYm9sSW5zdGFuY2UucGxhY2VkSWNvblN5bWJvbEluZGV4KTtcbiAgICAgICAgICAgIGNvbnN0IHBsYWNlZEljb25Cb3hlcyA9IHRoaXMuY29sbGlzaW9uSW5kZXgucGxhY2VDb2xsaXNpb25Cb3goXG4gICAgICAgICAgICAgICAgYnVja2V0LCBzaXplLFxuICAgICAgICAgICAgICAgIGljb25Cb3gsIG9mZnNldFNoaWZ0KHNoaWZ0LngsIHNoaWZ0LnksIHJvdGF0ZVdpdGhNYXAsIHBpdGNoV2l0aE1hcCwgdGhpcy50cmFuc2Zvcm0uYW5nbGUpLFxuICAgICAgICAgICAgICAgIHRleHRBbGxvd092ZXJsYXAsIHRleHRQaXhlbFJhdGlvLCBwb3NNYXRyaXgsIGNvbGxpc2lvbkdyb3VwLnByZWRpY2F0ZSk7XG4gICAgICAgICAgICBpZiAocGxhY2VkSWNvbkJveGVzLmJveC5sZW5ndGggPT09IDApIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwbGFjZWRHbHlwaEJveGVzLmJveC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBsZXQgcHJldkFuY2hvcjtcbiAgICAgICAgICAgIC8vIElmIHRoaXMgbGFiZWwgd2FzIHBsYWNlZCBpbiB0aGUgcHJldmlvdXMgcGxhY2VtZW50LCByZWNvcmQgdGhlIGFuY2hvciBwb3NpdGlvblxuICAgICAgICAgICAgLy8gdG8gYWxsb3cgdXMgdG8gYW5pbWF0ZSB0aGUgdHJhbnNpdGlvblxuICAgICAgICAgICAgaWYgKHRoaXMucHJldlBsYWNlbWVudCAmJlxuICAgICAgICAgICAgICAgIHRoaXMucHJldlBsYWNlbWVudC52YXJpYWJsZU9mZnNldHNbY3Jvc3NUaWxlSURdICYmXG4gICAgICAgICAgICAgICAgdGhpcy5wcmV2UGxhY2VtZW50LnBsYWNlbWVudHNbY3Jvc3NUaWxlSURdICYmXG4gICAgICAgICAgICAgICAgdGhpcy5wcmV2UGxhY2VtZW50LnBsYWNlbWVudHNbY3Jvc3NUaWxlSURdLnRleHQpIHtcbiAgICAgICAgICAgICAgICBwcmV2QW5jaG9yID0gdGhpcy5wcmV2UGxhY2VtZW50LnZhcmlhYmxlT2Zmc2V0c1tjcm9zc1RpbGVJRF0uYW5jaG9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXNzZXJ0KGNyb3NzVGlsZUlEICE9PSAwKTtcbiAgICAgICAgICAgIHRoaXMudmFyaWFibGVPZmZzZXRzW2Nyb3NzVGlsZUlEXSA9IHtcbiAgICAgICAgICAgICAgICB0ZXh0T2Zmc2V0LFxuICAgICAgICAgICAgICAgIHdpZHRoLFxuICAgICAgICAgICAgICAgIGhlaWdodCxcbiAgICAgICAgICAgICAgICBhbmNob3IsXG4gICAgICAgICAgICAgICAgdGV4dFNjYWxlLFxuICAgICAgICAgICAgICAgIHByZXZBbmNob3JcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLm1hcmtVc2VkSnVzdGlmaWNhdGlvbihidWNrZXQsIGFuY2hvciwgc3ltYm9sSW5zdGFuY2UsIG9yaWVudGF0aW9uKTtcblxuICAgICAgICAgICAgaWYgKGJ1Y2tldC5hbGxvd1ZlcnRpY2FsUGxhY2VtZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5tYXJrVXNlZE9yaWVudGF0aW9uKGJ1Y2tldCwgb3JpZW50YXRpb24sIHN5bWJvbEluc3RhbmNlKTtcbiAgICAgICAgICAgICAgICB0aGlzLnBsYWNlZE9yaWVudGF0aW9uc1tjcm9zc1RpbGVJRF0gPSBvcmllbnRhdGlvbjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHtzaGlmdCwgcGxhY2VkR2x5cGhCb3hlc307XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwbGFjZUxheWVyQnVja2V0UGFydChidWNrZXRQYXJ0OiBPYmplY3QsIHNlZW5Dcm9zc1RpbGVJRHM6IFNldDxudW1iZXI+LCBzaG93Q29sbGlzaW9uQm94ZXM6IGJvb2xlYW4sIHVwZGF0ZUNvbGxpc2lvbkJveElmTmVjZXNzYXJ5OiBib29sZWFuKSB7XG5cbiAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgYnVja2V0LFxuICAgICAgICAgICAgbGF5b3V0LFxuICAgICAgICAgICAgcG9zTWF0cml4LFxuICAgICAgICAgICAgdGV4dExhYmVsUGxhbmVNYXRyaXgsXG4gICAgICAgICAgICBsYWJlbFRvU2NyZWVuTWF0cml4LFxuICAgICAgICAgICAgY2xpcHBpbmdEYXRhLFxuICAgICAgICAgICAgdGV4dFBpeGVsUmF0aW8sXG4gICAgICAgICAgICBob2xkaW5nRm9yRmFkZSxcbiAgICAgICAgICAgIGNvbGxpc2lvbkJveEFycmF5LFxuICAgICAgICAgICAgcGFydGlhbGx5RXZhbHVhdGVkVGV4dFNpemUsXG4gICAgICAgICAgICBwYXJ0aWFsbHlFdmFsdWF0ZWRJY29uU2l6ZSxcbiAgICAgICAgICAgIGNvbGxpc2lvbkdyb3VwXG4gICAgICAgIH0gPSBidWNrZXRQYXJ0LnBhcmFtZXRlcnM7XG5cbiAgICAgICAgY29uc3QgdGV4dE9wdGlvbmFsID0gbGF5b3V0LmdldCgndGV4dC1vcHRpb25hbCcpO1xuICAgICAgICBjb25zdCBpY29uT3B0aW9uYWwgPSBsYXlvdXQuZ2V0KCdpY29uLW9wdGlvbmFsJyk7XG4gICAgICAgIGNvbnN0IHRleHRBbGxvd092ZXJsYXAgPSBsYXlvdXQuZ2V0KCd0ZXh0LWFsbG93LW92ZXJsYXAnKTtcbiAgICAgICAgY29uc3QgaWNvbkFsbG93T3ZlcmxhcCA9IGxheW91dC5nZXQoJ2ljb24tYWxsb3ctb3ZlcmxhcCcpO1xuICAgICAgICBjb25zdCByb3RhdGVXaXRoTWFwID0gbGF5b3V0LmdldCgndGV4dC1yb3RhdGlvbi1hbGlnbm1lbnQnKSA9PT0gJ21hcCc7XG4gICAgICAgIGNvbnN0IHBpdGNoV2l0aE1hcCA9IGxheW91dC5nZXQoJ3RleHQtcGl0Y2gtYWxpZ25tZW50JykgPT09ICdtYXAnO1xuICAgICAgICBjb25zdCBoYXNJY29uVGV4dEZpdCA9IGxheW91dC5nZXQoJ2ljb24tdGV4dC1maXQnKSAhPT0gJ25vbmUnO1xuICAgICAgICBjb25zdCB6T3JkZXJCeVZpZXdwb3J0WSA9IGxheW91dC5nZXQoJ3N5bWJvbC16LW9yZGVyJykgPT09ICd2aWV3cG9ydC15JztcblxuICAgICAgICB0aGlzLnRyYW5zZm9ybS5zZXRQcm9qZWN0aW9uKGJ1Y2tldC5wcm9qZWN0aW9uKTtcblxuICAgICAgICAvLyBUaGlzIGxvZ2ljIGlzIHNpbWlsYXIgdG8gdGhlIFwiZGVmYXVsdE9wYWNpdHlTdGF0ZVwiIGxvZ2ljIGJlbG93IGluIHVwZGF0ZUJ1Y2tldE9wYWNpdGllc1xuICAgICAgICAvLyBJZiB3ZSBrbm93IGEgc3ltYm9sIGlzIGFsd2F5cyBzdXBwb3NlZCB0byBzaG93LCBmb3JjZSBpdCB0byBiZSBtYXJrZWQgdmlzaWJsZSBldmVuIGlmXG4gICAgICAgIC8vIGl0IHdhc24ndCBwbGFjZWQgaW50byB0aGUgY29sbGlzaW9uIGluZGV4IChiZWNhdXNlIHNvbWUgb3IgYWxsIG9mIGl0IHdhcyBvdXRzaWRlIHRoZSByYW5nZVxuICAgICAgICAvLyBvZiB0aGUgY29sbGlzaW9uIGdyaWQpLlxuICAgICAgICAvLyBUaGVyZSBpcyBhIHN1YnRsZSBlZGdlIGNhc2UgaGVyZSB3ZSdyZSBhY2NlcHRpbmc6XG4gICAgICAgIC8vICBTeW1ib2wgQSBoYXMgdGV4dC1hbGxvdy1vdmVybGFwOiB0cnVlLCBpY29uLWFsbG93LW92ZXJsYXA6IHRydWUsIGljb24tb3B0aW9uYWw6IGZhbHNlXG4gICAgICAgIC8vICBBJ3MgaWNvbiBpcyBvdXRzaWRlIHRoZSBncmlkLCBzbyBkb2Vzbid0IGdldCBwbGFjZWRcbiAgICAgICAgLy8gIEEncyB0ZXh0IHdvdWxkIGJlIGluc2lkZSBncmlkLCBidXQgZG9lc24ndCBnZXQgcGxhY2VkIGJlY2F1c2Ugb2YgaWNvbi1vcHRpb25hbDogZmFsc2VcbiAgICAgICAgLy8gIFdlIHN0aWxsIHNob3cgQSBiZWNhdXNlIG9mIHRoZSBhbGxvdy1vdmVybGFwIHNldHRpbmdzLlxuICAgICAgICAvLyAgU3ltYm9sIEIgaGFzIGFsbG93LW92ZXJsYXA6IGZhbHNlLCBhbmQgZ2V0cyBwbGFjZWQgd2hlcmUgQSdzIHRleHQgd291bGQgYmVcbiAgICAgICAgLy8gIE9uIHBhbm5pbmcgaW4sIHRoZXJlIGlzIGEgc2hvcnQgcGVyaW9kIHdoZW4gU3ltYm9sIEIgYW5kIFN5bWJvbCBBIHdpbGwgb3ZlcmxhcFxuICAgICAgICAvLyAgVGhpcyBpcyB0aGUgcmV2ZXJzZSBvZiBvdXIgbm9ybWFsIHBvbGljeSBvZiBcImZhZGUgaW4gb24gcGFuXCIsIGJ1dCBzaG91bGQgbG9vayBsaWtlIGFueSBvdGhlclxuICAgICAgICAvLyAgY29sbGlzaW9uIGFuZCBob3BlZnVsbHkgbm90IGJlIHRvbyBub3RpY2VhYmxlLlxuICAgICAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL21hcGJveC9tYXBib3gtZ2wtanMvaXNzdWVzLzcxNzJcbiAgICAgICAgbGV0IGFsd2F5c1Nob3dUZXh0ID0gdGV4dEFsbG93T3ZlcmxhcCAmJiAoaWNvbkFsbG93T3ZlcmxhcCB8fCAhYnVja2V0Lmhhc0ljb25EYXRhKCkgfHwgaWNvbk9wdGlvbmFsKTtcbiAgICAgICAgbGV0IGFsd2F5c1Nob3dJY29uID0gaWNvbkFsbG93T3ZlcmxhcCAmJiAodGV4dEFsbG93T3ZlcmxhcCB8fCAhYnVja2V0Lmhhc1RleHREYXRhKCkgfHwgdGV4dE9wdGlvbmFsKTtcblxuICAgICAgICBpZiAoIWJ1Y2tldC5jb2xsaXNpb25BcnJheXMgJiYgY29sbGlzaW9uQm94QXJyYXkpIHtcbiAgICAgICAgICAgIGJ1Y2tldC5kZXNlcmlhbGl6ZUNvbGxpc2lvbkJveGVzKGNvbGxpc2lvbkJveEFycmF5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzaG93Q29sbGlzaW9uQm94ZXMgJiYgdXBkYXRlQ29sbGlzaW9uQm94SWZOZWNlc3NhcnkpIHtcbiAgICAgICAgICAgIGJ1Y2tldC51cGRhdGVDb2xsaXNpb25EZWJ1Z0J1ZmZlcnModGhpcy50cmFuc2Zvcm0uem9vbSwgY29sbGlzaW9uQm94QXJyYXkpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcGxhY2VTeW1ib2wgPSAoc3ltYm9sSW5zdGFuY2U6IFN5bWJvbEluc3RhbmNlLCBib3hJbmRleDogbnVtYmVyLCBjb2xsaXNpb25BcnJheXM6IENvbGxpc2lvbkFycmF5cykgPT4ge1xuICAgICAgICAgICAgY29uc3Qge2Nyb3NzVGlsZUlELCBudW1WZXJ0aWNhbEdseXBoVmVydGljZXN9ID0gc3ltYm9sSW5zdGFuY2U7XG5cbiAgICAgICAgICAgIGlmIChjbGlwcGluZ0RhdGEpIHtcbiAgICAgICAgICAgICAgICAvLyBTZXR1cCBnbG9iYWxzXG4gICAgICAgICAgICAgICAgY29uc3QgZ2xvYmFscyA9IHtcbiAgICAgICAgICAgICAgICAgICAgem9vbTogdGhpcy50cmFuc2Zvcm0uem9vbSxcbiAgICAgICAgICAgICAgICAgICAgcGl0Y2g6IHRoaXMudHJhbnNmb3JtLnBpdGNoLFxuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAvLyBEZXNlcmlhbGl6ZSBmZWF0dXJlIG9ubHkgaWYgbmVjZXNzYXJ5XG4gICAgICAgICAgICAgICAgbGV0IGZlYXR1cmUgPSBudWxsO1xuICAgICAgICAgICAgICAgIGlmIChjbGlwcGluZ0RhdGEuZHluYW1pY0ZpbHRlck5lZWRzRmVhdHVyZSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBmZWF0dXJlSW5kZXggPSBjbGlwcGluZ0RhdGEuZmVhdHVyZUluZGV4O1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXRhaW5lZFF1ZXJ5RGF0YSA9IHRoaXMucmV0YWluZWRRdWVyeURhdGFbYnVja2V0LmJ1Y2tldEluc3RhbmNlSWRdO1xuICAgICAgICAgICAgICAgICAgICBmZWF0dXJlID0gZmVhdHVyZUluZGV4LmxvYWRGZWF0dXJlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZlYXR1cmVJbmRleDogc3ltYm9sSW5zdGFuY2UuZmVhdHVyZUluZGV4LFxuICAgICAgICAgICAgICAgICAgICAgICAgYnVja2V0SW5kZXg6IHJldGFpbmVkUXVlcnlEYXRhLmJ1Y2tldEluZGV4LFxuICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlTGF5ZXJJbmRleDogcmV0YWluZWRRdWVyeURhdGEuc291cmNlTGF5ZXJJbmRleCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxheW91dFZlcnRleEFycmF5T2Zmc2V0OiAwXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBjYW5vbmljYWxUaWxlSWQgPSB0aGlzLnJldGFpbmVkUXVlcnlEYXRhW2J1Y2tldC5idWNrZXRJbnN0YW5jZUlkXS50aWxlSUQuY2Fub25pY2FsO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgZmlsdGVyRnVuYyA9IGNsaXBwaW5nRGF0YS5keW5hbWljRmlsdGVyO1xuICAgICAgICAgICAgICAgIGNvbnN0IHNob3VsZENsaXAgPSAhZmlsdGVyRnVuYyhnbG9iYWxzLCBmZWF0dXJlLCBjYW5vbmljYWxUaWxlSWQsIG5ldyBQb2ludChzeW1ib2xJbnN0YW5jZS50aWxlQW5jaG9yWCwgc3ltYm9sSW5zdGFuY2UudGlsZUFuY2hvclkpLCB0aGlzLnRyYW5zZm9ybS5jYWxjdWxhdGVEaXN0YW5jZVRpbGVEYXRhKGNsaXBwaW5nRGF0YS51bndyYXBwZWRUaWxlSUQpKTtcblxuICAgICAgICAgICAgICAgIGlmIChzaG91bGRDbGlwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2VtZW50c1tjcm9zc1RpbGVJRF0gPSBuZXcgSm9pbnRQbGFjZW1lbnQoZmFsc2UsIGZhbHNlLCBmYWxzZSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIHNlZW5Dcm9zc1RpbGVJRHMuYWRkKGNyb3NzVGlsZUlEKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHNlZW5Dcm9zc1RpbGVJRHMuaGFzKGNyb3NzVGlsZUlEKSkgcmV0dXJuO1xuICAgICAgICAgICAgaWYgKGhvbGRpbmdGb3JGYWRlKSB7XG4gICAgICAgICAgICAgICAgLy8gTWFyayBhbGwgc3ltYm9scyBmcm9tIHRoaXMgdGlsZSBhcyBcIm5vdCBwbGFjZWRcIiwgYnV0IGRvbid0IGFkZCB0byBzZWVuQ3Jvc3NUaWxlSURzLCBiZWNhdXNlIHdlIGRvbid0XG4gICAgICAgICAgICAgICAgLy8ga25vdyB5ZXQgaWYgd2UgaGF2ZSBhIGR1cGxpY2F0ZSBpbiBhIHBhcmVudCB0aWxlIHRoYXQgX3Nob3VsZF8gYmUgcGxhY2VkLlxuICAgICAgICAgICAgICAgIHRoaXMucGxhY2VtZW50c1tjcm9zc1RpbGVJRF0gPSBuZXcgSm9pbnRQbGFjZW1lbnQoZmFsc2UsIGZhbHNlLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IHBsYWNlVGV4dDogP2Jvb2xlYW4gPSBmYWxzZTtcbiAgICAgICAgICAgIGxldCBwbGFjZUljb246ID9ib29sZWFuID0gZmFsc2U7XG4gICAgICAgICAgICBsZXQgb2Zmc2NyZWVuOiA/Ym9vbGVhbiA9IHRydWU7XG4gICAgICAgICAgICBsZXQgdGV4dE9jY2x1ZGVkOiA/Ym9vbGVhbiA9IGZhbHNlO1xuICAgICAgICAgICAgbGV0IGljb25PY2NsdWRlZCA9IGZhbHNlO1xuICAgICAgICAgICAgbGV0IHNoaWZ0ID0gbnVsbDtcblxuICAgICAgICAgICAgbGV0IHBsYWNlZDogUGFydGlhbFBsYWNlZENvbGxpc2lvbkJveCA9IHtib3g6IG51bGwsIG9mZnNjcmVlbjogbnVsbCwgb2NjbHVkZWQ6IG51bGx9O1xuICAgICAgICAgICAgbGV0IHBsYWNlZFZlcnRpY2FsVGV4dDogUGFydGlhbFBsYWNlZENvbGxpc2lvbkJveCA9IHtib3g6IG51bGwsIG9mZnNjcmVlbjogbnVsbCwgb2NjbHVkZWQ6IG51bGx9O1xuXG4gICAgICAgICAgICBsZXQgcGxhY2VkR2x5cGhCb3hlcyA9IG51bGw7XG4gICAgICAgICAgICBsZXQgcGxhY2VkR2x5cGhDaXJjbGVzID0gbnVsbDtcbiAgICAgICAgICAgIGxldCBwbGFjZWRJY29uQm94ZXMgPSBudWxsO1xuICAgICAgICAgICAgbGV0IHRleHRGZWF0dXJlSW5kZXggPSAwO1xuICAgICAgICAgICAgbGV0IHZlcnRpY2FsVGV4dEZlYXR1cmVJbmRleCA9IDA7XG4gICAgICAgICAgICBsZXQgaWNvbkZlYXR1cmVJbmRleCA9IDA7XG5cbiAgICAgICAgICAgIGlmIChjb2xsaXNpb25BcnJheXMudGV4dEZlYXR1cmVJbmRleCkge1xuICAgICAgICAgICAgICAgIHRleHRGZWF0dXJlSW5kZXggPSBjb2xsaXNpb25BcnJheXMudGV4dEZlYXR1cmVJbmRleDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoc3ltYm9sSW5zdGFuY2UudXNlUnVudGltZUNvbGxpc2lvbkNpcmNsZXMpIHtcbiAgICAgICAgICAgICAgICB0ZXh0RmVhdHVyZUluZGV4ID0gc3ltYm9sSW5zdGFuY2UuZmVhdHVyZUluZGV4O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNvbGxpc2lvbkFycmF5cy52ZXJ0aWNhbFRleHRGZWF0dXJlSW5kZXgpIHtcbiAgICAgICAgICAgICAgICB2ZXJ0aWNhbFRleHRGZWF0dXJlSW5kZXggPSBjb2xsaXNpb25BcnJheXMudmVydGljYWxUZXh0RmVhdHVyZUluZGV4O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCB1cGRhdGVCb3hEYXRhID0gKGJveDogU2luZ2xlQ29sbGlzaW9uQm94KSA9PiB7XG4gICAgICAgICAgICAgICAgYm94LnRpbGVJRCA9IHRoaXMucmV0YWluZWRRdWVyeURhdGFbYnVja2V0LmJ1Y2tldEluc3RhbmNlSWRdLnRpbGVJRDtcbiAgICAgICAgICAgICAgICBjb25zdCBlbGV2YXRpb24gPSB0aGlzLnRyYW5zZm9ybS5lbGV2YXRpb247XG4gICAgICAgICAgICAgICAgaWYgKCFlbGV2YXRpb24gJiYgIWJveC5lbGV2YXRpb24pIHJldHVybjtcbiAgICAgICAgICAgICAgICBib3guZWxldmF0aW9uID0gZWxldmF0aW9uID8gZWxldmF0aW9uLmdldEF0VGlsZU9mZnNldChib3gudGlsZUlELCBib3gudGlsZUFuY2hvclgsIGJveC50aWxlQW5jaG9yWSkgOiAwO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3QgdGV4dEJveCA9IGNvbGxpc2lvbkFycmF5cy50ZXh0Qm94O1xuICAgICAgICAgICAgaWYgKHRleHRCb3gpIHtcbiAgICAgICAgICAgICAgICB1cGRhdGVCb3hEYXRhKHRleHRCb3gpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHVwZGF0ZVByZXZpb3VzT3JpZW50YXRpb25JZk5vdFBsYWNlZCA9IChpc1BsYWNlZDogYm9vbGVhbikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsZXQgcHJldmlvdXNPcmllbnRhdGlvbiA9IFdyaXRpbmdNb2RlLmhvcml6b250YWw7XG4gICAgICAgICAgICAgICAgICAgIGlmIChidWNrZXQuYWxsb3dWZXJ0aWNhbFBsYWNlbWVudCAmJiAhaXNQbGFjZWQgJiYgdGhpcy5wcmV2UGxhY2VtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwcmV2UGxhY2VkT3JpZW50YXRpb24gPSB0aGlzLnByZXZQbGFjZW1lbnQucGxhY2VkT3JpZW50YXRpb25zW2Nyb3NzVGlsZUlEXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcmV2UGxhY2VkT3JpZW50YXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlZE9yaWVudGF0aW9uc1tjcm9zc1RpbGVJRF0gPSBwcmV2UGxhY2VkT3JpZW50YXRpb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJldmlvdXNPcmllbnRhdGlvbiA9IHByZXZQbGFjZWRPcmllbnRhdGlvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hcmtVc2VkT3JpZW50YXRpb24oYnVja2V0LCBwcmV2aW91c09yaWVudGF0aW9uLCBzeW1ib2xJbnN0YW5jZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHByZXZpb3VzT3JpZW50YXRpb247XG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IHBsYWNlVGV4dEZvclBsYWNlbWVudE1vZGVzID0gKHBsYWNlSG9yaXpvbnRhbEZuOiAoKSA9PiBQYXJ0aWFsUGxhY2VkQ29sbGlzaW9uQm94LCBwbGFjZVZlcnRpY2FsRm46ICgpID0+IFBhcnRpYWxQbGFjZWRDb2xsaXNpb25Cb3gpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGJ1Y2tldC5hbGxvd1ZlcnRpY2FsUGxhY2VtZW50ICYmIG51bVZlcnRpY2FsR2x5cGhWZXJ0aWNlcyA+IDAgJiYgY29sbGlzaW9uQXJyYXlzLnZlcnRpY2FsVGV4dEJveCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBwbGFjZW1lbnRNb2RlIG9mIGJ1Y2tldC53cml0aW5nTW9kZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGxhY2VtZW50TW9kZSA9PT0gV3JpdGluZ01vZGUudmVydGljYWwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2VkID0gcGxhY2VWZXJ0aWNhbEZuKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlZFZlcnRpY2FsVGV4dCA9IHBsYWNlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWQgPSBwbGFjZUhvcml6b250YWxGbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGxhY2VkICYmIHBsYWNlZC5ib3ggJiYgcGxhY2VkLmJveC5sZW5ndGgpIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2VkID0gcGxhY2VIb3Jpem9udGFsRm4oKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICBpZiAoIWxheW91dC5nZXQoJ3RleHQtdmFyaWFibGUtYW5jaG9yJykpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGxhY2VCb3ggPSAoY29sbGlzaW9uVGV4dEJveDogU2luZ2xlQ29sbGlzaW9uQm94LCBvcmllbnRhdGlvbjogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0ZXh0U2NhbGUgPSBidWNrZXQuZ2V0U3ltYm9sSW5zdGFuY2VUZXh0U2l6ZShwYXJ0aWFsbHlFdmFsdWF0ZWRUZXh0U2l6ZSwgc3ltYm9sSW5zdGFuY2UsIHRoaXMudHJhbnNmb3JtLnpvb20sIGJveEluZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBsYWNlZEZlYXR1cmUgPSB0aGlzLmNvbGxpc2lvbkluZGV4LnBsYWNlQ29sbGlzaW9uQm94KGJ1Y2tldCwgdGV4dFNjYWxlLCBjb2xsaXNpb25UZXh0Qm94LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBQb2ludCgwLCAwKSwgdGV4dEFsbG93T3ZlcmxhcCwgdGV4dFBpeGVsUmF0aW8sIHBvc01hdHJpeCwgY29sbGlzaW9uR3JvdXAucHJlZGljYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwbGFjZWRGZWF0dXJlICYmIHBsYWNlZEZlYXR1cmUuYm94ICYmIHBsYWNlZEZlYXR1cmUuYm94Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubWFya1VzZWRPcmllbnRhdGlvbihidWNrZXQsIG9yaWVudGF0aW9uLCBzeW1ib2xJbnN0YW5jZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGFjZWRPcmllbnRhdGlvbnNbY3Jvc3NUaWxlSURdID0gb3JpZW50YXRpb247XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGxhY2VkRmVhdHVyZTtcbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwbGFjZUhvcml6b250YWw6ICgpID0+IFBsYWNlZENvbGxpc2lvbkJveCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwbGFjZUJveCh0ZXh0Qm94LCBXcml0aW5nTW9kZS5ob3Jpem9udGFsKTtcbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwbGFjZVZlcnRpY2FsOiAoKSA9PiBQbGFjZWRDb2xsaXNpb25Cb3ggfCBQYXJ0aWFsUGxhY2VkQ29sbGlzaW9uQm94ID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmVydGljYWxUZXh0Qm94ID0gY29sbGlzaW9uQXJyYXlzLnZlcnRpY2FsVGV4dEJveDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChidWNrZXQuYWxsb3dWZXJ0aWNhbFBsYWNlbWVudCAmJiBudW1WZXJ0aWNhbEdseXBoVmVydGljZXMgPiAwICYmIHZlcnRpY2FsVGV4dEJveCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZUJveERhdGEodmVydGljYWxUZXh0Qm94KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGxhY2VCb3godmVydGljYWxUZXh0Qm94LCBXcml0aW5nTW9kZS52ZXJ0aWNhbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge2JveDogbnVsbCwgb2Zmc2NyZWVuOiBudWxsLCBvY2NsdWRlZDogbnVsbH07XG4gICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgcGxhY2VUZXh0Rm9yUGxhY2VtZW50TW9kZXMoXG4gICAgICAgICAgICAgICAgICAgICAgICAoKHBsYWNlSG9yaXpvbnRhbDogYW55KTogKCkgPT4gUGFydGlhbFBsYWNlZENvbGxpc2lvbkJveCksXG4gICAgICAgICAgICAgICAgICAgICAgICAoKHBsYWNlVmVydGljYWw6IGFueSk6ICgpID0+IFBhcnRpYWxQbGFjZWRDb2xsaXNpb25Cb3gpLFxuICAgICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGlzUGxhY2VkID0gcGxhY2VkICYmIHBsYWNlZC5ib3ggJiYgcGxhY2VkLmJveC5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZVByZXZpb3VzT3JpZW50YXRpb25JZk5vdFBsYWNlZCghIWlzUGxhY2VkKTtcblxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBhbmNob3JzID0gbGF5b3V0LmdldCgndGV4dC12YXJpYWJsZS1hbmNob3InKTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGlzIHN5bWJvbCB3YXMgaW4gdGhlIGxhc3QgcGxhY2VtZW50LCBzaGlmdCB0aGUgcHJldmlvdXNseSB1c2VkXG4gICAgICAgICAgICAgICAgICAgIC8vIGFuY2hvciB0byB0aGUgZnJvbnQgb2YgdGhlIGFuY2hvciBsaXN0LCBvbmx5IGlmIHRoZSBwcmV2aW91cyBhbmNob3JcbiAgICAgICAgICAgICAgICAgICAgLy8gaXMgc3RpbGwgaW4gdGhlIGFuY2hvciBsaXN0XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnByZXZQbGFjZW1lbnQgJiYgdGhpcy5wcmV2UGxhY2VtZW50LnZhcmlhYmxlT2Zmc2V0c1tjcm9zc1RpbGVJRF0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHByZXZPZmZzZXRzID0gdGhpcy5wcmV2UGxhY2VtZW50LnZhcmlhYmxlT2Zmc2V0c1tjcm9zc1RpbGVJRF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYW5jaG9ycy5pbmRleE9mKHByZXZPZmZzZXRzLmFuY2hvcikgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jaG9ycyA9IGFuY2hvcnMuZmlsdGVyKGFuY2hvciA9PiBhbmNob3IgIT09IHByZXZPZmZzZXRzLmFuY2hvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jaG9ycy51bnNoaWZ0KHByZXZPZmZzZXRzLmFuY2hvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwbGFjZUJveEZvclZhcmlhYmxlQW5jaG9ycyA9IChjb2xsaXNpb25UZXh0Qm94OiBTaW5nbGVDb2xsaXNpb25Cb3gsIGNvbGxpc2lvbkljb25Cb3g6ID9TaW5nbGVDb2xsaXNpb25Cb3gsIG9yaWVudGF0aW9uOiBudW1iZXIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRleHRTY2FsZSA9IGJ1Y2tldC5nZXRTeW1ib2xJbnN0YW5jZVRleHRTaXplKHBhcnRpYWxseUV2YWx1YXRlZFRleHRTaXplLCBzeW1ib2xJbnN0YW5jZSwgdGhpcy50cmFuc2Zvcm0uem9vbSwgYm94SW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgd2lkdGggPSAoY29sbGlzaW9uVGV4dEJveC54MiAtIGNvbGxpc2lvblRleHRCb3gueDEpICogdGV4dFNjYWxlICsgMi4wICogY29sbGlzaW9uVGV4dEJveC5wYWRkaW5nO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaGVpZ2h0ID0gKGNvbGxpc2lvblRleHRCb3gueTIgLSBjb2xsaXNpb25UZXh0Qm94LnkxKSAqIHRleHRTY2FsZSArIDIuMCAqIGNvbGxpc2lvblRleHRCb3gucGFkZGluZztcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFyaWFibGVJY29uQm94ID0gaGFzSWNvblRleHRGaXQgJiYgIWljb25BbGxvd092ZXJsYXAgPyBjb2xsaXNpb25JY29uQm94IDogbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YXJpYWJsZUljb25Cb3gpIHVwZGF0ZUJveERhdGEodmFyaWFibGVJY29uQm94KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHBsYWNlZEJveDogUGFydGlhbFBsYWNlZENvbGxpc2lvbkJveCA9IHtib3g6IFtdLCBvZmZzY3JlZW46IGZhbHNlLCBvY2NsdWRlZDogZmFsc2V9O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcGxhY2VtZW50QXR0ZW1wdHMgPSB0ZXh0QWxsb3dPdmVybGFwID8gYW5jaG9ycy5sZW5ndGggKiAyIDogYW5jaG9ycy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBsYWNlbWVudEF0dGVtcHRzOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhbmNob3IgPSBhbmNob3JzW2kgJSBhbmNob3JzLmxlbmd0aF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYWxsb3dPdmVybGFwID0gKGkgPj0gYW5jaG9ycy5sZW5ndGgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuYXR0ZW1wdEFuY2hvclBsYWNlbWVudChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jaG9yLCBjb2xsaXNpb25UZXh0Qm94LCB3aWR0aCwgaGVpZ2h0LCB0ZXh0U2NhbGUsIHJvdGF0ZVdpdGhNYXAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpdGNoV2l0aE1hcCwgdGV4dFBpeGVsUmF0aW8sIHBvc01hdHJpeCwgY29sbGlzaW9uR3JvdXAsIGFsbG93T3ZlcmxhcCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltYm9sSW5zdGFuY2UsIGJveEluZGV4LCBidWNrZXQsIG9yaWVudGF0aW9uLCB2YXJpYWJsZUljb25Cb3gsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpYWxseUV2YWx1YXRlZFRleHRTaXplLCBwYXJ0aWFsbHlFdmFsdWF0ZWRJY29uU2l6ZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlZEJveCA9ICgocmVzdWx0LnBsYWNlZEdseXBoQm94ZXM6IGFueSk6IFBhcnRpYWxQbGFjZWRDb2xsaXNpb25Cb3gpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGxhY2VkQm94ICYmIHBsYWNlZEJveC5ib3ggJiYgcGxhY2VkQm94LmJveC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlVGV4dCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaGlmdCA9IHJlc3VsdC5zaGlmdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGxhY2VkQm94O1xuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBsYWNlSG9yaXpvbnRhbCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwbGFjZUJveEZvclZhcmlhYmxlQW5jaG9ycyh0ZXh0Qm94LCBjb2xsaXNpb25BcnJheXMuaWNvbkJveCwgV3JpdGluZ01vZGUuaG9yaXpvbnRhbCk7XG4gICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGxhY2VWZXJ0aWNhbCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZlcnRpY2FsVGV4dEJveCA9IGNvbGxpc2lvbkFycmF5cy52ZXJ0aWNhbFRleHRCb3g7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodmVydGljYWxUZXh0Qm94KSB1cGRhdGVCb3hEYXRhKHZlcnRpY2FsVGV4dEJveCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB3YXNQbGFjZWQgPSBwbGFjZWQgJiYgcGxhY2VkLmJveCAmJiBwbGFjZWQuYm94Lmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChidWNrZXQuYWxsb3dWZXJ0aWNhbFBsYWNlbWVudCAmJiAhd2FzUGxhY2VkICYmIG51bVZlcnRpY2FsR2x5cGhWZXJ0aWNlcyA+IDAgJiYgdmVydGljYWxUZXh0Qm94KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBsYWNlQm94Rm9yVmFyaWFibGVBbmNob3JzKHZlcnRpY2FsVGV4dEJveCwgY29sbGlzaW9uQXJyYXlzLnZlcnRpY2FsSWNvbkJveCwgV3JpdGluZ01vZGUudmVydGljYWwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtib3g6IG51bGwsIG9mZnNjcmVlbjogbnVsbCwgb2NjbHVkZWQ6IG51bGx9O1xuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIHBsYWNlVGV4dEZvclBsYWNlbWVudE1vZGVzKHBsYWNlSG9yaXpvbnRhbCwgcGxhY2VWZXJ0aWNhbCk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHBsYWNlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2VUZXh0ID0gcGxhY2VkLmJveDtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNjcmVlbiA9IHBsYWNlZC5vZmZzY3JlZW47XG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0T2NjbHVkZWQgPSBwbGFjZWQub2NjbHVkZWQ7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpc1BsYWNlZCA9IHBsYWNlZCAmJiBwbGFjZWQuYm94O1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwcmV2T3JpZW50YXRpb24gPSB1cGRhdGVQcmV2aW91c09yaWVudGF0aW9uSWZOb3RQbGFjZWQoISFpc1BsYWNlZCk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgd2UgZGlkbid0IGdldCBwbGFjZWQsIHdlIHN0aWxsIG5lZWQgdG8gY29weSBvdXIgcG9zaXRpb24gZnJvbSB0aGUgbGFzdCBwbGFjZW1lbnQgZm9yXG4gICAgICAgICAgICAgICAgICAgIC8vIGZhZGUgYW5pbWF0aW9uc1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXBsYWNlVGV4dCAmJiB0aGlzLnByZXZQbGFjZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHByZXZPZmZzZXQgPSB0aGlzLnByZXZQbGFjZW1lbnQudmFyaWFibGVPZmZzZXRzW2Nyb3NzVGlsZUlEXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcmV2T2Zmc2V0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy52YXJpYWJsZU9mZnNldHNbY3Jvc3NUaWxlSURdID0gcHJldk9mZnNldDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hcmtVc2VkSnVzdGlmaWNhdGlvbihidWNrZXQsIHByZXZPZmZzZXQuYW5jaG9yLCBzeW1ib2xJbnN0YW5jZSwgcHJldk9yaWVudGF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBwbGFjZWRHbHlwaEJveGVzID0gcGxhY2VkO1xuXG4gICAgICAgICAgICBwbGFjZVRleHQgPSBwbGFjZWRHbHlwaEJveGVzICYmIHBsYWNlZEdseXBoQm94ZXMuYm94ICYmIHBsYWNlZEdseXBoQm94ZXMuYm94Lmxlbmd0aCA+IDA7XG4gICAgICAgICAgICBvZmZzY3JlZW4gPSBwbGFjZWRHbHlwaEJveGVzICYmIHBsYWNlZEdseXBoQm94ZXMub2Zmc2NyZWVuO1xuICAgICAgICAgICAgdGV4dE9jY2x1ZGVkID0gcGxhY2VkR2x5cGhCb3hlcyAmJiBwbGFjZWRHbHlwaEJveGVzLm9jY2x1ZGVkO1xuXG4gICAgICAgICAgICBpZiAoc3ltYm9sSW5zdGFuY2UudXNlUnVudGltZUNvbGxpc2lvbkNpcmNsZXMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwbGFjZWRTeW1ib2xJbmRleCA9IHN5bWJvbEluc3RhbmNlLmNlbnRlckp1c3RpZmllZFRleHRTeW1ib2xJbmRleCA+PSAwID8gc3ltYm9sSW5zdGFuY2UuY2VudGVySnVzdGlmaWVkVGV4dFN5bWJvbEluZGV4IDogc3ltYm9sSW5zdGFuY2UudmVydGljYWxQbGFjZWRUZXh0U3ltYm9sSW5kZXg7XG4gICAgICAgICAgICAgICAgY29uc3QgcGxhY2VkU3ltYm9sID0gYnVja2V0LnRleHQucGxhY2VkU3ltYm9sQXJyYXkuZ2V0KHBsYWNlZFN5bWJvbEluZGV4KTtcbiAgICAgICAgICAgICAgICBjb25zdCBmb250U2l6ZSA9IHN5bWJvbFNpemUuZXZhbHVhdGVTaXplRm9yRmVhdHVyZShidWNrZXQudGV4dFNpemVEYXRhLCBwYXJ0aWFsbHlFdmFsdWF0ZWRUZXh0U2l6ZSwgcGxhY2VkU3ltYm9sKTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IHRleHRQaXhlbFBhZGRpbmcgPSBsYXlvdXQuZ2V0KCd0ZXh0LXBhZGRpbmcnKTtcbiAgICAgICAgICAgICAgICAvLyBDb252ZXJ0IGNpcmNsZSBjb2xsaXNpb24gaGVpZ2h0IGludG8gcGl4ZWxzXG4gICAgICAgICAgICAgICAgY29uc3QgY2lyY2xlUGl4ZWxEaWFtZXRlciA9IHN5bWJvbEluc3RhbmNlLmNvbGxpc2lvbkNpcmNsZURpYW1ldGVyICogZm9udFNpemUgLyBPTkVfRU07XG5cbiAgICAgICAgICAgICAgICBwbGFjZWRHbHlwaENpcmNsZXMgPSB0aGlzLmNvbGxpc2lvbkluZGV4LnBsYWNlQ29sbGlzaW9uQ2lyY2xlcyhcbiAgICAgICAgICAgICAgICAgICAgICAgIGJ1Y2tldCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHRBbGxvd092ZXJsYXAsXG4gICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWRTeW1ib2wsXG4gICAgICAgICAgICAgICAgICAgICAgICBidWNrZXQubGluZVZlcnRleEFycmF5LFxuICAgICAgICAgICAgICAgICAgICAgICAgYnVja2V0LmdseXBoT2Zmc2V0QXJyYXksXG4gICAgICAgICAgICAgICAgICAgICAgICBmb250U2l6ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvc01hdHJpeCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHRMYWJlbFBsYW5lTWF0cml4LFxuICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxUb1NjcmVlbk1hdHJpeCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNob3dDb2xsaXNpb25Cb3hlcyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBpdGNoV2l0aE1hcCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbGxpc2lvbkdyb3VwLnByZWRpY2F0ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNpcmNsZVBpeGVsRGlhbWV0ZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0UGl4ZWxQYWRkaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZXRhaW5lZFF1ZXJ5RGF0YVtidWNrZXQuYnVja2V0SW5zdGFuY2VJZF0udGlsZUlEKTtcblxuICAgICAgICAgICAgICAgIGFzc2VydCghcGxhY2VkR2x5cGhDaXJjbGVzLmNpcmNsZXMubGVuZ3RoIHx8ICghcGxhY2VkR2x5cGhDaXJjbGVzLmNvbGxpc2lvbkRldGVjdGVkIHx8IHNob3dDb2xsaXNpb25Cb3hlcykpO1xuICAgICAgICAgICAgICAgIC8vIElmIHRleHQtYWxsb3ctb3ZlcmxhcCBpcyBzZXQsIGZvcmNlIFwicGxhY2VkQ2lyY2xlc1wiIHRvIHRydWVcbiAgICAgICAgICAgICAgICAvLyBJbiB0aGVvcnkgdGhlcmUgc2hvdWxkIGFsd2F5cyBiZSBhdCBsZWFzdCBvbmUgY2lyY2xlIHBsYWNlZFxuICAgICAgICAgICAgICAgIC8vIGluIHRoaXMgY2FzZSwgYnV0IGZvciBub3cgcXVpcmtzIGluIHRleHQtYW5jaG9yXG4gICAgICAgICAgICAgICAgLy8gYW5kIHRleHQtb2Zmc2V0IG1heSBwcmV2ZW50IHRoYXQgZnJvbSBiZWluZyB0cnVlLlxuICAgICAgICAgICAgICAgIHBsYWNlVGV4dCA9IHRleHRBbGxvd092ZXJsYXAgfHwgKHBsYWNlZEdseXBoQ2lyY2xlcy5jaXJjbGVzLmxlbmd0aCA+IDAgJiYgIXBsYWNlZEdseXBoQ2lyY2xlcy5jb2xsaXNpb25EZXRlY3RlZCk7XG4gICAgICAgICAgICAgICAgb2Zmc2NyZWVuID0gb2Zmc2NyZWVuICYmIHBsYWNlZEdseXBoQ2lyY2xlcy5vZmZzY3JlZW47XG4gICAgICAgICAgICAgICAgdGV4dE9jY2x1ZGVkID0gcGxhY2VkR2x5cGhDaXJjbGVzLm9jY2x1ZGVkO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoY29sbGlzaW9uQXJyYXlzLmljb25GZWF0dXJlSW5kZXgpIHtcbiAgICAgICAgICAgICAgICBpY29uRmVhdHVyZUluZGV4ID0gY29sbGlzaW9uQXJyYXlzLmljb25GZWF0dXJlSW5kZXg7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjb2xsaXNpb25BcnJheXMuaWNvbkJveCkge1xuXG4gICAgICAgICAgICAgICAgY29uc3QgcGxhY2VJY29uRmVhdHVyZSA9IChpY29uQm94OiBTaW5nbGVDb2xsaXNpb25Cb3gpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdXBkYXRlQm94RGF0YShpY29uQm94KTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2hpZnRQb2ludDogUG9pbnQgPSBoYXNJY29uVGV4dEZpdCAmJiBzaGlmdCA/XG4gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXRTaGlmdChzaGlmdC54LCBzaGlmdC55LCByb3RhdGVXaXRoTWFwLCBwaXRjaFdpdGhNYXAsIHRoaXMudHJhbnNmb3JtLmFuZ2xlKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgUG9pbnQoMCwgMCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGljb25TY2FsZSA9IGJ1Y2tldC5nZXRTeW1ib2xJbnN0YW5jZUljb25TaXplKHBhcnRpYWxseUV2YWx1YXRlZEljb25TaXplLCB0aGlzLnRyYW5zZm9ybS56b29tLCBzeW1ib2xJbnN0YW5jZS5wbGFjZWRJY29uU3ltYm9sSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jb2xsaXNpb25JbmRleC5wbGFjZUNvbGxpc2lvbkJveChidWNrZXQsIGljb25TY2FsZSwgaWNvbkJveCwgc2hpZnRQb2ludCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGljb25BbGxvd092ZXJsYXAsIHRleHRQaXhlbFJhdGlvLCBwb3NNYXRyaXgsIGNvbGxpc2lvbkdyb3VwLnByZWRpY2F0ZSk7XG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIGlmIChwbGFjZWRWZXJ0aWNhbFRleHQgJiYgcGxhY2VkVmVydGljYWxUZXh0LmJveCAmJiBwbGFjZWRWZXJ0aWNhbFRleHQuYm94Lmxlbmd0aCAmJiBjb2xsaXNpb25BcnJheXMudmVydGljYWxJY29uQm94KSB7XG4gICAgICAgICAgICAgICAgICAgIHBsYWNlZEljb25Cb3hlcyA9IHBsYWNlSWNvbkZlYXR1cmUoY29sbGlzaW9uQXJyYXlzLnZlcnRpY2FsSWNvbkJveCk7XG4gICAgICAgICAgICAgICAgICAgIHBsYWNlSWNvbiA9IHBsYWNlZEljb25Cb3hlcy5ib3gubGVuZ3RoID4gMDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBwbGFjZWRJY29uQm94ZXMgPSBwbGFjZUljb25GZWF0dXJlKGNvbGxpc2lvbkFycmF5cy5pY29uQm94KTtcbiAgICAgICAgICAgICAgICAgICAgcGxhY2VJY29uID0gcGxhY2VkSWNvbkJveGVzLmJveC5sZW5ndGggPiAwO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvZmZzY3JlZW4gPSBvZmZzY3JlZW4gJiYgcGxhY2VkSWNvbkJveGVzLm9mZnNjcmVlbjtcbiAgICAgICAgICAgICAgICBpY29uT2NjbHVkZWQgPSBwbGFjZWRJY29uQm94ZXMub2NjbHVkZWQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGljb25XaXRob3V0VGV4dCA9IHRleHRPcHRpb25hbCB8fFxuICAgICAgICAgICAgICAgIChzeW1ib2xJbnN0YW5jZS5udW1Ib3Jpem9udGFsR2x5cGhWZXJ0aWNlcyA9PT0gMCAmJiBudW1WZXJ0aWNhbEdseXBoVmVydGljZXMgPT09IDApO1xuICAgICAgICAgICAgY29uc3QgdGV4dFdpdGhvdXRJY29uID0gaWNvbk9wdGlvbmFsIHx8IHN5bWJvbEluc3RhbmNlLm51bUljb25WZXJ0aWNlcyA9PT0gMDtcblxuICAgICAgICAgICAgLy8gQ29tYmluZSB0aGUgc2NhbGVzIGZvciBpY29ucyBhbmQgdGV4dC5cbiAgICAgICAgICAgIGlmICghaWNvbldpdGhvdXRUZXh0ICYmICF0ZXh0V2l0aG91dEljb24pIHtcbiAgICAgICAgICAgICAgICBwbGFjZUljb24gPSBwbGFjZVRleHQgPSBwbGFjZUljb24gJiYgcGxhY2VUZXh0O1xuICAgICAgICAgICAgfSBlbHNlIGlmICghdGV4dFdpdGhvdXRJY29uKSB7XG4gICAgICAgICAgICAgICAgcGxhY2VUZXh0ID0gcGxhY2VJY29uICYmIHBsYWNlVGV4dDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIWljb25XaXRob3V0VGV4dCkge1xuICAgICAgICAgICAgICAgIHBsYWNlSWNvbiA9IHBsYWNlSWNvbiAmJiBwbGFjZVRleHQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChwbGFjZVRleHQgJiYgcGxhY2VkR2x5cGhCb3hlcyAmJiBwbGFjZWRHbHlwaEJveGVzLmJveCkge1xuICAgICAgICAgICAgICAgIGlmIChwbGFjZWRWZXJ0aWNhbFRleHQgJiYgcGxhY2VkVmVydGljYWxUZXh0LmJveCAmJiB2ZXJ0aWNhbFRleHRGZWF0dXJlSW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb2xsaXNpb25JbmRleC5pbnNlcnRDb2xsaXNpb25Cb3gocGxhY2VkR2x5cGhCb3hlcy5ib3gsIGxheW91dC5nZXQoJ3RleHQtaWdub3JlLXBsYWNlbWVudCcpLFxuICAgICAgICAgICAgICAgICAgICAgICAgYnVja2V0LmJ1Y2tldEluc3RhbmNlSWQsIHZlcnRpY2FsVGV4dEZlYXR1cmVJbmRleCwgY29sbGlzaW9uR3JvdXAuSUQpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29sbGlzaW9uSW5kZXguaW5zZXJ0Q29sbGlzaW9uQm94KHBsYWNlZEdseXBoQm94ZXMuYm94LCBsYXlvdXQuZ2V0KCd0ZXh0LWlnbm9yZS1wbGFjZW1lbnQnKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGJ1Y2tldC5idWNrZXRJbnN0YW5jZUlkLCB0ZXh0RmVhdHVyZUluZGV4LCBjb2xsaXNpb25Hcm91cC5JRCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocGxhY2VJY29uICYmIHBsYWNlZEljb25Cb3hlcykge1xuICAgICAgICAgICAgICAgIHRoaXMuY29sbGlzaW9uSW5kZXguaW5zZXJ0Q29sbGlzaW9uQm94KHBsYWNlZEljb25Cb3hlcy5ib3gsIGxheW91dC5nZXQoJ2ljb24taWdub3JlLXBsYWNlbWVudCcpLFxuICAgICAgICAgICAgICAgICAgICAgICAgYnVja2V0LmJ1Y2tldEluc3RhbmNlSWQsIGljb25GZWF0dXJlSW5kZXgsIGNvbGxpc2lvbkdyb3VwLklEKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwbGFjZWRHbHlwaENpcmNsZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAocGxhY2VUZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29sbGlzaW9uSW5kZXguaW5zZXJ0Q29sbGlzaW9uQ2lyY2xlcyhwbGFjZWRHbHlwaENpcmNsZXMuY2lyY2xlcywgbGF5b3V0LmdldCgndGV4dC1pZ25vcmUtcGxhY2VtZW50JyksXG4gICAgICAgICAgICAgICAgICAgICAgICBidWNrZXQuYnVja2V0SW5zdGFuY2VJZCwgdGV4dEZlYXR1cmVJbmRleCwgY29sbGlzaW9uR3JvdXAuSUQpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChzaG93Q29sbGlzaW9uQm94ZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaWQgPSBidWNrZXQuYnVja2V0SW5zdGFuY2VJZDtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNpcmNsZUFycmF5ID0gdGhpcy5jb2xsaXNpb25DaXJjbGVBcnJheXNbaWRdO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIEdyb3VwIGNvbGxpc2lvbiBjaXJjbGVzIHRvZ2V0aGVyIGJ5IGJ1Y2tldC4gQ2lyY2xlcyBjYW4ndCBiZSBwdXNoZWQgZm9yd2FyZCBmb3IgcmVuZGVyaW5nIHlldCBhcyB0aGUgc3ltYm9sIHBsYWNlbWVudFxuICAgICAgICAgICAgICAgICAgICAvLyBmb3IgYSBidWNrZXQgaXMgbm90IGd1YXJhbnRlZWQgdG8gYmUgY29tcGxldGUgYmVmb3JlIHRoZSBjb21taXQtZnVuY3Rpb24gaGFzIGJlZW4gY2FsbGVkXG4gICAgICAgICAgICAgICAgICAgIGlmIChjaXJjbGVBcnJheSA9PT0gdW5kZWZpbmVkKVxuICAgICAgICAgICAgICAgICAgICAgICAgY2lyY2xlQXJyYXkgPSB0aGlzLmNvbGxpc2lvbkNpcmNsZUFycmF5c1tpZF0gPSBuZXcgQ29sbGlzaW9uQ2lyY2xlQXJyYXkoKTtcblxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBsYWNlZEdseXBoQ2lyY2xlcy5jaXJjbGVzLmxlbmd0aDsgaSArPSA0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjaXJjbGVBcnJheS5jaXJjbGVzLnB1c2gocGxhY2VkR2x5cGhDaXJjbGVzLmNpcmNsZXNbaSArIDBdKTsgICAgICAgICAgICAgIC8vIHhcbiAgICAgICAgICAgICAgICAgICAgICAgIGNpcmNsZUFycmF5LmNpcmNsZXMucHVzaChwbGFjZWRHbHlwaENpcmNsZXMuY2lyY2xlc1tpICsgMV0pOyAgICAgICAgICAgICAgLy8geVxuICAgICAgICAgICAgICAgICAgICAgICAgY2lyY2xlQXJyYXkuY2lyY2xlcy5wdXNoKHBsYWNlZEdseXBoQ2lyY2xlcy5jaXJjbGVzW2kgKyAyXSk7ICAgICAgICAgICAgICAvLyByYWRpdXNcbiAgICAgICAgICAgICAgICAgICAgICAgIGNpcmNsZUFycmF5LmNpcmNsZXMucHVzaChwbGFjZWRHbHlwaENpcmNsZXMuY29sbGlzaW9uRGV0ZWN0ZWQgPyAxIDogMCk7ICAgLy8gY29sbGlzaW9uRGV0ZWN0ZWQtZmxhZ1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBhc3NlcnQoY3Jvc3NUaWxlSUQgIT09IDApO1xuICAgICAgICAgICAgYXNzZXJ0KGJ1Y2tldC5idWNrZXRJbnN0YW5jZUlkICE9PSAwKTtcblxuICAgICAgICAgICAgY29uc3Qgbm90R2xvYmUgPSBidWNrZXQucHJvamVjdGlvbi5uYW1lICE9PSAnZ2xvYmUnO1xuICAgICAgICAgICAgYWx3YXlzU2hvd1RleHQgPSBhbHdheXNTaG93VGV4dCAmJiAobm90R2xvYmUgfHwgIXRleHRPY2NsdWRlZCk7XG4gICAgICAgICAgICBhbHdheXNTaG93SWNvbiA9IGFsd2F5c1Nob3dJY29uICYmIChub3RHbG9iZSB8fCAhaWNvbk9jY2x1ZGVkKTtcblxuICAgICAgICAgICAgdGhpcy5wbGFjZW1lbnRzW2Nyb3NzVGlsZUlEXSA9IG5ldyBKb2ludFBsYWNlbWVudChwbGFjZVRleHQgfHwgYWx3YXlzU2hvd1RleHQsIHBsYWNlSWNvbiB8fCBhbHdheXNTaG93SWNvbiwgb2Zmc2NyZWVuIHx8IGJ1Y2tldC5qdXN0UmVsb2FkZWQpO1xuICAgICAgICAgICAgc2VlbkNyb3NzVGlsZUlEcy5hZGQoY3Jvc3NUaWxlSUQpO1xuICAgICAgICB9O1xuXG4gICAgICAgIGlmICh6T3JkZXJCeVZpZXdwb3J0WSkge1xuICAgICAgICAgICAgYXNzZXJ0KGJ1Y2tldFBhcnQuc3ltYm9sSW5zdGFuY2VTdGFydCA9PT0gMCk7XG4gICAgICAgICAgICBjb25zdCBzeW1ib2xJbmRleGVzID0gYnVja2V0LmdldFNvcnRlZFN5bWJvbEluZGV4ZXModGhpcy50cmFuc2Zvcm0uYW5nbGUpO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IHN5bWJvbEluZGV4ZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzeW1ib2xJbmRleCA9IHN5bWJvbEluZGV4ZXNbaV07XG4gICAgICAgICAgICAgICAgcGxhY2VTeW1ib2woYnVja2V0LnN5bWJvbEluc3RhbmNlcy5nZXQoc3ltYm9sSW5kZXgpLCBzeW1ib2xJbmRleCwgYnVja2V0LmNvbGxpc2lvbkFycmF5c1tzeW1ib2xJbmRleF0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IGJ1Y2tldFBhcnQuc3ltYm9sSW5zdGFuY2VTdGFydDsgaSA8IGJ1Y2tldFBhcnQuc3ltYm9sSW5zdGFuY2VFbmQ7IGkrKykge1xuICAgICAgICAgICAgICAgIHBsYWNlU3ltYm9sKGJ1Y2tldC5zeW1ib2xJbnN0YW5jZXMuZ2V0KGkpLCBpLCBidWNrZXQuY29sbGlzaW9uQXJyYXlzW2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzaG93Q29sbGlzaW9uQm94ZXMgJiYgYnVja2V0LmJ1Y2tldEluc3RhbmNlSWQgaW4gdGhpcy5jb2xsaXNpb25DaXJjbGVBcnJheXMpIHtcbiAgICAgICAgICAgIGNvbnN0IGNpcmNsZUFycmF5ID0gdGhpcy5jb2xsaXNpb25DaXJjbGVBcnJheXNbYnVja2V0LmJ1Y2tldEluc3RhbmNlSWRdO1xuXG4gICAgICAgICAgICAvLyBTdG9yZSB2aWV3cG9ydCBhbmQgaW52ZXJzZSBwcm9qZWN0aW9uIG1hdHJpY2VzIHBlciBidWNrZXRcbiAgICAgICAgICAgIG1hdDQuaW52ZXJ0KGNpcmNsZUFycmF5LmludlByb2pNYXRyaXgsIHBvc01hdHJpeCk7XG4gICAgICAgICAgICBjaXJjbGVBcnJheS52aWV3cG9ydE1hdHJpeCA9IHRoaXMuY29sbGlzaW9uSW5kZXguZ2V0Vmlld3BvcnRNYXRyaXgoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJ1Y2tldC5qdXN0UmVsb2FkZWQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBtYXJrVXNlZEp1c3RpZmljYXRpb24oYnVja2V0OiBTeW1ib2xCdWNrZXQsIHBsYWNlZEFuY2hvcjogVGV4dEFuY2hvciwgc3ltYm9sSW5zdGFuY2U6IFN5bWJvbEluc3RhbmNlLCBvcmllbnRhdGlvbjogbnVtYmVyKSB7XG4gICAgICAgIGNvbnN0IHtcbiAgICAgICAgICAgIGxlZnRKdXN0aWZpZWRUZXh0U3ltYm9sSW5kZXg6IGxlZnQsIGNlbnRlckp1c3RpZmllZFRleHRTeW1ib2xJbmRleDogY2VudGVyLFxuICAgICAgICAgICAgcmlnaHRKdXN0aWZpZWRUZXh0U3ltYm9sSW5kZXg6IHJpZ2h0LCB2ZXJ0aWNhbFBsYWNlZFRleHRTeW1ib2xJbmRleDogdmVydGljYWwsIGNyb3NzVGlsZUlEXG4gICAgICAgIH0gPSBzeW1ib2xJbnN0YW5jZTtcblxuICAgICAgICBjb25zdCBqdXN0aWZpY2F0aW9uID0gZ2V0QW5jaG9ySnVzdGlmaWNhdGlvbihwbGFjZWRBbmNob3IpO1xuICAgICAgICBjb25zdCBhdXRvSW5kZXggPVxuICAgICAgICAgICAgb3JpZW50YXRpb24gPT09IFdyaXRpbmdNb2RlLnZlcnRpY2FsID8gdmVydGljYWwgOlxuICAgICAgICAgICAganVzdGlmaWNhdGlvbiA9PT0gJ2xlZnQnID8gbGVmdCA6XG4gICAgICAgICAgICBqdXN0aWZpY2F0aW9uID09PSAnY2VudGVyJyA/IGNlbnRlciA6XG4gICAgICAgICAgICBqdXN0aWZpY2F0aW9uID09PSAncmlnaHQnID8gcmlnaHQgOiAtMTtcblxuICAgICAgICAvLyBJZiB0aGVyZSBhcmUgbXVsdGlwbGUganVzdGlmaWNhdGlvbnMgYW5kIHRoaXMgb25lIGlzbid0IGl0OiBzaGlmdCBvZmZzY3JlZW5cbiAgICAgICAgLy8gSWYgZWl0aGVyIHRoaXMgaXMgdGhlIGNob3NlbiBqdXN0aWZpY2F0aW9uIG9yIHRoZSBqdXN0aWZpY2F0aW9uIGlzIGhhcmR3aXJlZDogdXNlIGl0XG4gICAgICAgIGlmIChsZWZ0ID49IDApIGJ1Y2tldC50ZXh0LnBsYWNlZFN5bWJvbEFycmF5LmdldChsZWZ0KS5jcm9zc1RpbGVJRCA9IGF1dG9JbmRleCA+PSAwICYmIGxlZnQgIT09IGF1dG9JbmRleCA/IDAgOiBjcm9zc1RpbGVJRDtcbiAgICAgICAgaWYgKGNlbnRlciA+PSAwKSBidWNrZXQudGV4dC5wbGFjZWRTeW1ib2xBcnJheS5nZXQoY2VudGVyKS5jcm9zc1RpbGVJRCA9IGF1dG9JbmRleCA+PSAwICYmIGNlbnRlciAhPT0gYXV0b0luZGV4ID8gMCA6IGNyb3NzVGlsZUlEO1xuICAgICAgICBpZiAocmlnaHQgPj0gMCkgYnVja2V0LnRleHQucGxhY2VkU3ltYm9sQXJyYXkuZ2V0KHJpZ2h0KS5jcm9zc1RpbGVJRCA9IGF1dG9JbmRleCA+PSAwICYmIHJpZ2h0ICE9PSBhdXRvSW5kZXggPyAwIDogY3Jvc3NUaWxlSUQ7XG4gICAgICAgIGlmICh2ZXJ0aWNhbCA+PSAwKSBidWNrZXQudGV4dC5wbGFjZWRTeW1ib2xBcnJheS5nZXQodmVydGljYWwpLmNyb3NzVGlsZUlEID0gYXV0b0luZGV4ID49IDAgJiYgdmVydGljYWwgIT09IGF1dG9JbmRleCA/IDAgOiBjcm9zc1RpbGVJRDtcbiAgICB9XG5cbiAgICBtYXJrVXNlZE9yaWVudGF0aW9uKGJ1Y2tldDogU3ltYm9sQnVja2V0LCBvcmllbnRhdGlvbjogbnVtYmVyLCBzeW1ib2xJbnN0YW5jZTogU3ltYm9sSW5zdGFuY2UpIHtcbiAgICAgICAgY29uc3QgaG9yaXpvbnRhbE9yaWVudGF0aW9uID0gKG9yaWVudGF0aW9uID09PSBXcml0aW5nTW9kZS5ob3Jpem9udGFsIHx8IG9yaWVudGF0aW9uID09PSBXcml0aW5nTW9kZS5ob3Jpem9udGFsT25seSkgPyBvcmllbnRhdGlvbiA6IDA7XG4gICAgICAgIGNvbnN0IHZlcnRpY2FsT3JpZW50YXRpb24gPSBvcmllbnRhdGlvbiA9PT0gV3JpdGluZ01vZGUudmVydGljYWwgPyBvcmllbnRhdGlvbiA6IDA7XG4gICAgICAgIGNvbnN0IHtcbiAgICAgICAgICAgIGxlZnRKdXN0aWZpZWRUZXh0U3ltYm9sSW5kZXg6IGxlZnQsIGNlbnRlckp1c3RpZmllZFRleHRTeW1ib2xJbmRleDogY2VudGVyLFxuICAgICAgICAgICAgcmlnaHRKdXN0aWZpZWRUZXh0U3ltYm9sSW5kZXg6IHJpZ2h0LCB2ZXJ0aWNhbFBsYWNlZFRleHRTeW1ib2xJbmRleDogdmVydGljYWxcbiAgICAgICAgfSA9IHN5bWJvbEluc3RhbmNlO1xuICAgICAgICBjb25zdCBhcnJheSA9IGJ1Y2tldC50ZXh0LnBsYWNlZFN5bWJvbEFycmF5O1xuXG4gICAgICAgIGlmIChsZWZ0ID49IDApIGFycmF5LmdldChsZWZ0KS5wbGFjZWRPcmllbnRhdGlvbiA9IGhvcml6b250YWxPcmllbnRhdGlvbjtcbiAgICAgICAgaWYgKGNlbnRlciA+PSAwKSBhcnJheS5nZXQoY2VudGVyKS5wbGFjZWRPcmllbnRhdGlvbiA9IGhvcml6b250YWxPcmllbnRhdGlvbjtcbiAgICAgICAgaWYgKHJpZ2h0ID49IDApIGFycmF5LmdldChyaWdodCkucGxhY2VkT3JpZW50YXRpb24gPSBob3Jpem9udGFsT3JpZW50YXRpb247XG4gICAgICAgIGlmICh2ZXJ0aWNhbCA+PSAwKSBhcnJheS5nZXQodmVydGljYWwpLnBsYWNlZE9yaWVudGF0aW9uID0gdmVydGljYWxPcmllbnRhdGlvbjtcbiAgICB9XG5cbiAgICBjb21taXQobm93OiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5jb21taXRUaW1lID0gbm93O1xuICAgICAgICB0aGlzLnpvb21BdExhc3RSZWNlbmN5Q2hlY2sgPSB0aGlzLnRyYW5zZm9ybS56b29tO1xuXG4gICAgICAgIGNvbnN0IHByZXZQbGFjZW1lbnQgPSB0aGlzLnByZXZQbGFjZW1lbnQ7XG4gICAgICAgIGxldCBwbGFjZW1lbnRDaGFuZ2VkID0gZmFsc2U7XG5cbiAgICAgICAgdGhpcy5wcmV2Wm9vbUFkanVzdG1lbnQgPSBwcmV2UGxhY2VtZW50ID8gcHJldlBsYWNlbWVudC56b29tQWRqdXN0bWVudCh0aGlzLnRyYW5zZm9ybS56b29tKSA6IDA7XG4gICAgICAgIGNvbnN0IGluY3JlbWVudCA9IHByZXZQbGFjZW1lbnQgPyBwcmV2UGxhY2VtZW50LnN5bWJvbEZhZGVDaGFuZ2Uobm93KSA6IDE7XG5cbiAgICAgICAgY29uc3QgcHJldk9wYWNpdGllcyA9IHByZXZQbGFjZW1lbnQgPyBwcmV2UGxhY2VtZW50Lm9wYWNpdGllcyA6IHt9O1xuICAgICAgICBjb25zdCBwcmV2T2Zmc2V0cyA9IHByZXZQbGFjZW1lbnQgPyBwcmV2UGxhY2VtZW50LnZhcmlhYmxlT2Zmc2V0cyA6IHt9O1xuICAgICAgICBjb25zdCBwcmV2T3JpZW50YXRpb25zID0gcHJldlBsYWNlbWVudCA/IHByZXZQbGFjZW1lbnQucGxhY2VkT3JpZW50YXRpb25zIDoge307XG5cbiAgICAgICAgLy8gYWRkIHRoZSBvcGFjaXRpZXMgZnJvbSB0aGUgY3VycmVudCBwbGFjZW1lbnQsIGFuZCBjb3B5IHRoZWlyIGN1cnJlbnQgdmFsdWVzIGZyb20gdGhlIHByZXZpb3VzIHBsYWNlbWVudFxuICAgICAgICBmb3IgKGNvbnN0IGNyb3NzVGlsZUlEIGluIHRoaXMucGxhY2VtZW50cykge1xuICAgICAgICAgICAgY29uc3Qgam9pbnRQbGFjZW1lbnQgPSB0aGlzLnBsYWNlbWVudHNbY3Jvc3NUaWxlSURdO1xuICAgICAgICAgICAgY29uc3QgcHJldk9wYWNpdHkgPSBwcmV2T3BhY2l0aWVzW2Nyb3NzVGlsZUlEXTtcbiAgICAgICAgICAgIGlmIChwcmV2T3BhY2l0eSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BhY2l0aWVzW2Nyb3NzVGlsZUlEXSA9IG5ldyBKb2ludE9wYWNpdHlTdGF0ZShwcmV2T3BhY2l0eSwgaW5jcmVtZW50LCBqb2ludFBsYWNlbWVudC50ZXh0LCBqb2ludFBsYWNlbWVudC5pY29uLCBudWxsLCBqb2ludFBsYWNlbWVudC5jbGlwcGVkKTtcbiAgICAgICAgICAgICAgICBwbGFjZW1lbnRDaGFuZ2VkID0gcGxhY2VtZW50Q2hhbmdlZCB8fFxuICAgICAgICAgICAgICAgICAgICBqb2ludFBsYWNlbWVudC50ZXh0ICE9PSBwcmV2T3BhY2l0eS50ZXh0LnBsYWNlZCB8fFxuICAgICAgICAgICAgICAgICAgICBqb2ludFBsYWNlbWVudC5pY29uICE9PSBwcmV2T3BhY2l0eS5pY29uLnBsYWNlZDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGFjaXRpZXNbY3Jvc3NUaWxlSURdID0gbmV3IEpvaW50T3BhY2l0eVN0YXRlKG51bGwsIGluY3JlbWVudCwgam9pbnRQbGFjZW1lbnQudGV4dCwgam9pbnRQbGFjZW1lbnQuaWNvbiwgam9pbnRQbGFjZW1lbnQuc2tpcEZhZGUsIGpvaW50UGxhY2VtZW50LmNsaXBwZWQpO1xuICAgICAgICAgICAgICAgIHBsYWNlbWVudENoYW5nZWQgPSBwbGFjZW1lbnRDaGFuZ2VkIHx8IGpvaW50UGxhY2VtZW50LnRleHQgfHwgam9pbnRQbGFjZW1lbnQuaWNvbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNvcHkgYW5kIHVwZGF0ZSB2YWx1ZXMgZnJvbSB0aGUgcHJldmlvdXMgcGxhY2VtZW50IHRoYXQgYXJlbid0IGluIHRoZSBjdXJyZW50IHBsYWNlbWVudCBidXQgaGF2ZW4ndCBmaW5pc2hlZCBmYWRpbmdcbiAgICAgICAgZm9yIChjb25zdCBjcm9zc1RpbGVJRCBpbiBwcmV2T3BhY2l0aWVzKSB7XG4gICAgICAgICAgICBjb25zdCBwcmV2T3BhY2l0eSA9IHByZXZPcGFjaXRpZXNbY3Jvc3NUaWxlSURdO1xuICAgICAgICAgICAgaWYgKCF0aGlzLm9wYWNpdGllc1tjcm9zc1RpbGVJRF0pIHtcbiAgICAgICAgICAgICAgICBjb25zdCBqb2ludE9wYWNpdHkgPSBuZXcgSm9pbnRPcGFjaXR5U3RhdGUocHJldk9wYWNpdHksIGluY3JlbWVudCwgZmFsc2UsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICBpZiAoIWpvaW50T3BhY2l0eS5pc0hpZGRlbigpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3BhY2l0aWVzW2Nyb3NzVGlsZUlEXSA9IGpvaW50T3BhY2l0eTtcbiAgICAgICAgICAgICAgICAgICAgcGxhY2VtZW50Q2hhbmdlZCA9IHBsYWNlbWVudENoYW5nZWQgfHwgcHJldk9wYWNpdHkudGV4dC5wbGFjZWQgfHwgcHJldk9wYWNpdHkuaWNvbi5wbGFjZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgY3Jvc3NUaWxlSUQgaW4gcHJldk9mZnNldHMpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy52YXJpYWJsZU9mZnNldHNbY3Jvc3NUaWxlSURdICYmIHRoaXMub3BhY2l0aWVzW2Nyb3NzVGlsZUlEXSAmJiAhdGhpcy5vcGFjaXRpZXNbY3Jvc3NUaWxlSURdLmlzSGlkZGVuKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZhcmlhYmxlT2Zmc2V0c1tjcm9zc1RpbGVJRF0gPSBwcmV2T2Zmc2V0c1tjcm9zc1RpbGVJRF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGNvbnN0IGNyb3NzVGlsZUlEIGluIHByZXZPcmllbnRhdGlvbnMpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5wbGFjZWRPcmllbnRhdGlvbnNbY3Jvc3NUaWxlSURdICYmIHRoaXMub3BhY2l0aWVzW2Nyb3NzVGlsZUlEXSAmJiAhdGhpcy5vcGFjaXRpZXNbY3Jvc3NUaWxlSURdLmlzSGlkZGVuKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBsYWNlZE9yaWVudGF0aW9uc1tjcm9zc1RpbGVJRF0gPSBwcmV2T3JpZW50YXRpb25zW2Nyb3NzVGlsZUlEXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHRoaXMubGFzdFBsYWNlbWVudENoYW5nZVRpbWUgaXMgdGhlIHRpbWUgb2YgdGhlIGxhc3QgY29tbWl0KCkgdGhhdFxuICAgICAgICAvLyByZXN1bHRlZCBpbiBhIHBsYWNlbWVudCBjaGFuZ2UgLS0gaW4gb3RoZXIgd29yZHMsIHRoZSBzdGFydCB0aW1lIG9mXG4gICAgICAgIC8vIHRoZSBsYXN0IHN5bWJvbCBmYWRlIGFuaW1hdGlvblxuICAgICAgICBhc3NlcnQoIXByZXZQbGFjZW1lbnQgfHwgcHJldlBsYWNlbWVudC5sYXN0UGxhY2VtZW50Q2hhbmdlVGltZSAhPT0gdW5kZWZpbmVkKTtcbiAgICAgICAgaWYgKHBsYWNlbWVudENoYW5nZWQpIHtcbiAgICAgICAgICAgIHRoaXMubGFzdFBsYWNlbWVudENoYW5nZVRpbWUgPSBub3c7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMubGFzdFBsYWNlbWVudENoYW5nZVRpbWUgIT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICB0aGlzLmxhc3RQbGFjZW1lbnRDaGFuZ2VUaW1lID0gcHJldlBsYWNlbWVudCA/IHByZXZQbGFjZW1lbnQubGFzdFBsYWNlbWVudENoYW5nZVRpbWUgOiBub3c7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB1cGRhdGVMYXllck9wYWNpdGllcyhzdHlsZUxheWVyOiBTdHlsZUxheWVyLCB0aWxlczogQXJyYXk8VGlsZT4pIHtcbiAgICAgICAgY29uc3Qgc2VlbkNyb3NzVGlsZUlEcyA9IG5ldyBTZXQoKTtcbiAgICAgICAgZm9yIChjb25zdCB0aWxlIG9mIHRpbGVzKSB7XG4gICAgICAgICAgICBjb25zdCBzeW1ib2xCdWNrZXQgPSAoKHRpbGUuZ2V0QnVja2V0KHN0eWxlTGF5ZXIpOiBhbnkpOiBTeW1ib2xCdWNrZXQpO1xuICAgICAgICAgICAgaWYgKHN5bWJvbEJ1Y2tldCAmJiB0aWxlLmxhdGVzdEZlYXR1cmVJbmRleCAmJiBzdHlsZUxheWVyLmlkID09PSBzeW1ib2xCdWNrZXQubGF5ZXJJZHNbMF0pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUJ1Y2tldE9wYWNpdGllcyhzeW1ib2xCdWNrZXQsIHNlZW5Dcm9zc1RpbGVJRHMsIHRpbGUuY29sbGlzaW9uQm94QXJyYXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgdXBkYXRlQnVja2V0T3BhY2l0aWVzKGJ1Y2tldDogU3ltYm9sQnVja2V0LCBzZWVuQ3Jvc3NUaWxlSURzOiBTZXQ8bnVtYmVyPiwgY29sbGlzaW9uQm94QXJyYXk6ID9Db2xsaXNpb25Cb3hBcnJheSkge1xuICAgICAgICBpZiAoYnVja2V0Lmhhc1RleHREYXRhKCkpIGJ1Y2tldC50ZXh0Lm9wYWNpdHlWZXJ0ZXhBcnJheS5jbGVhcigpO1xuICAgICAgICBpZiAoYnVja2V0Lmhhc0ljb25EYXRhKCkpIGJ1Y2tldC5pY29uLm9wYWNpdHlWZXJ0ZXhBcnJheS5jbGVhcigpO1xuICAgICAgICBpZiAoYnVja2V0Lmhhc0ljb25Db2xsaXNpb25Cb3hEYXRhKCkpIGJ1Y2tldC5pY29uQ29sbGlzaW9uQm94LmNvbGxpc2lvblZlcnRleEFycmF5LmNsZWFyKCk7XG4gICAgICAgIGlmIChidWNrZXQuaGFzVGV4dENvbGxpc2lvbkJveERhdGEoKSkgYnVja2V0LnRleHRDb2xsaXNpb25Cb3guY29sbGlzaW9uVmVydGV4QXJyYXkuY2xlYXIoKTtcblxuICAgICAgICBjb25zdCBsYXlvdXQgPSBidWNrZXQubGF5ZXJzWzBdLmxheW91dDtcbiAgICAgICAgY29uc3QgaGFzQ2xpcHBpbmcgPSAhIWJ1Y2tldC5sYXllcnNbMF0uZHluYW1pY0ZpbHRlcigpO1xuICAgICAgICBjb25zdCBkdXBsaWNhdGVPcGFjaXR5U3RhdGUgPSBuZXcgSm9pbnRPcGFjaXR5U3RhdGUobnVsbCwgMCwgZmFsc2UsIGZhbHNlLCB0cnVlKTtcbiAgICAgICAgY29uc3QgdGV4dEFsbG93T3ZlcmxhcCA9IGxheW91dC5nZXQoJ3RleHQtYWxsb3ctb3ZlcmxhcCcpO1xuICAgICAgICBjb25zdCBpY29uQWxsb3dPdmVybGFwID0gbGF5b3V0LmdldCgnaWNvbi1hbGxvdy1vdmVybGFwJyk7XG4gICAgICAgIGNvbnN0IHZhcmlhYmxlUGxhY2VtZW50ID0gbGF5b3V0LmdldCgndGV4dC12YXJpYWJsZS1hbmNob3InKTtcbiAgICAgICAgY29uc3Qgcm90YXRlV2l0aE1hcCA9IGxheW91dC5nZXQoJ3RleHQtcm90YXRpb24tYWxpZ25tZW50JykgPT09ICdtYXAnO1xuICAgICAgICBjb25zdCBwaXRjaFdpdGhNYXAgPSBsYXlvdXQuZ2V0KCd0ZXh0LXBpdGNoLWFsaWdubWVudCcpID09PSAnbWFwJztcbiAgICAgICAgY29uc3QgaGFzSWNvblRleHRGaXQgPSBsYXlvdXQuZ2V0KCdpY29uLXRleHQtZml0JykgIT09ICdub25lJztcbiAgICAgICAgLy8gSWYgYWxsb3ctb3ZlcmxhcCBpcyB0cnVlLCB3ZSBjYW4gc2hvdyBzeW1ib2xzIGJlZm9yZSBwbGFjZW1lbnQgcnVucyBvbiB0aGVtXG4gICAgICAgIC8vIEJ1dCB3ZSBoYXZlIHRvIHdhaXQgZm9yIHBsYWNlbWVudCBpZiB3ZSBwb3RlbnRpYWxseSBkZXBlbmQgb24gYSBwYWlyZWQgaWNvbi90ZXh0XG4gICAgICAgIC8vIHdpdGggYWxsb3ctb3ZlcmxhcDogZmFsc2UuXG4gICAgICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vbWFwYm94L21hcGJveC1nbC1qcy9pc3N1ZXMvNzAzMlxuICAgICAgICBjb25zdCBkZWZhdWx0T3BhY2l0eVN0YXRlID0gbmV3IEpvaW50T3BhY2l0eVN0YXRlKG51bGwsIDAsXG4gICAgICAgICAgICAgICAgdGV4dEFsbG93T3ZlcmxhcCAmJiAoaWNvbkFsbG93T3ZlcmxhcCB8fCAhYnVja2V0Lmhhc0ljb25EYXRhKCkgfHwgbGF5b3V0LmdldCgnaWNvbi1vcHRpb25hbCcpKSxcbiAgICAgICAgICAgICAgICBpY29uQWxsb3dPdmVybGFwICYmICh0ZXh0QWxsb3dPdmVybGFwIHx8ICFidWNrZXQuaGFzVGV4dERhdGEoKSB8fCBsYXlvdXQuZ2V0KCd0ZXh0LW9wdGlvbmFsJykpLFxuICAgICAgICAgICAgICAgIHRydWUpO1xuXG4gICAgICAgIGlmICghYnVja2V0LmNvbGxpc2lvbkFycmF5cyAmJiBjb2xsaXNpb25Cb3hBcnJheSAmJiAoKGJ1Y2tldC5oYXNJY29uQ29sbGlzaW9uQm94RGF0YSgpIHx8IGJ1Y2tldC5oYXNUZXh0Q29sbGlzaW9uQm94RGF0YSgpKSkpIHtcbiAgICAgICAgICAgIGJ1Y2tldC5kZXNlcmlhbGl6ZUNvbGxpc2lvbkJveGVzKGNvbGxpc2lvbkJveEFycmF5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGFkZE9wYWNpdGllcyA9IChpY29uT3JUZXh0OiBTeW1ib2xCdWZmZXJzLCBudW1WZXJ0aWNlczogbnVtYmVyLCBvcGFjaXR5OiBudW1iZXIpID0+IHtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtVmVydGljZXMgLyA0OyBpKyspIHtcbiAgICAgICAgICAgICAgICBpY29uT3JUZXh0Lm9wYWNpdHlWZXJ0ZXhBcnJheS5lbXBsYWNlQmFjayhvcGFjaXR5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBsZXQgdmlzaWJsZUluc3RhbmNlQ291bnQgPSAwO1xuXG4gICAgICAgIGZvciAobGV0IHMgPSAwOyBzIDwgYnVja2V0LnN5bWJvbEluc3RhbmNlcy5sZW5ndGg7IHMrKykge1xuICAgICAgICAgICAgY29uc3Qgc3ltYm9sSW5zdGFuY2UgPSBidWNrZXQuc3ltYm9sSW5zdGFuY2VzLmdldChzKTtcbiAgICAgICAgICAgIGNvbnN0IHtcbiAgICAgICAgICAgICAgICBudW1Ib3Jpem9udGFsR2x5cGhWZXJ0aWNlcyxcbiAgICAgICAgICAgICAgICBudW1WZXJ0aWNhbEdseXBoVmVydGljZXMsXG4gICAgICAgICAgICAgICAgY3Jvc3NUaWxlSUQsXG4gICAgICAgICAgICAgICAgbnVtSWNvblZlcnRpY2VzXG4gICAgICAgICAgICB9ID0gc3ltYm9sSW5zdGFuY2U7XG5cbiAgICAgICAgICAgIGNvbnN0IGlzRHVwbGljYXRlID0gc2VlbkNyb3NzVGlsZUlEcy5oYXMoY3Jvc3NUaWxlSUQpO1xuXG4gICAgICAgICAgICBsZXQgb3BhY2l0eVN0YXRlID0gdGhpcy5vcGFjaXRpZXNbY3Jvc3NUaWxlSURdO1xuICAgICAgICAgICAgaWYgKGlzRHVwbGljYXRlKSB7XG4gICAgICAgICAgICAgICAgb3BhY2l0eVN0YXRlID0gZHVwbGljYXRlT3BhY2l0eVN0YXRlO1xuICAgICAgICAgICAgfSBlbHNlIGlmICghb3BhY2l0eVN0YXRlKSB7XG4gICAgICAgICAgICAgICAgb3BhY2l0eVN0YXRlID0gZGVmYXVsdE9wYWNpdHlTdGF0ZTtcbiAgICAgICAgICAgICAgICAvLyBzdG9yZSB0aGUgc3RhdGUgc28gdGhhdCBmdXR1cmUgcGxhY2VtZW50cyB1c2UgaXQgYXMgYSBzdGFydGluZyBwb2ludFxuICAgICAgICAgICAgICAgIHRoaXMub3BhY2l0aWVzW2Nyb3NzVGlsZUlEXSA9IG9wYWNpdHlTdGF0ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc2VlbkNyb3NzVGlsZUlEcy5hZGQoY3Jvc3NUaWxlSUQpO1xuXG4gICAgICAgICAgICBjb25zdCBoYXNUZXh0ID0gbnVtSG9yaXpvbnRhbEdseXBoVmVydGljZXMgPiAwIHx8IG51bVZlcnRpY2FsR2x5cGhWZXJ0aWNlcyA+IDA7XG4gICAgICAgICAgICBjb25zdCBoYXNJY29uID0gbnVtSWNvblZlcnRpY2VzID4gMDtcblxuICAgICAgICAgICAgY29uc3QgcGxhY2VkT3JpZW50YXRpb24gPSB0aGlzLnBsYWNlZE9yaWVudGF0aW9uc1tjcm9zc1RpbGVJRF07XG4gICAgICAgICAgICBjb25zdCBob3Jpem9udGFsSGlkZGVuID0gcGxhY2VkT3JpZW50YXRpb24gPT09IFdyaXRpbmdNb2RlLnZlcnRpY2FsO1xuICAgICAgICAgICAgY29uc3QgdmVydGljYWxIaWRkZW4gPSBwbGFjZWRPcmllbnRhdGlvbiA9PT0gV3JpdGluZ01vZGUuaG9yaXpvbnRhbCB8fCBwbGFjZWRPcmllbnRhdGlvbiA9PT0gV3JpdGluZ01vZGUuaG9yaXpvbnRhbE9ubHk7XG4gICAgICAgICAgICBpZiAoKGhhc1RleHQgfHwgaGFzSWNvbikgJiYgIW9wYWNpdHlTdGF0ZS5pc0hpZGRlbigpKSB2aXNpYmxlSW5zdGFuY2VDb3VudCsrO1xuXG4gICAgICAgICAgICBpZiAoaGFzVGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhY2tlZE9wYWNpdHkgPSBwYWNrT3BhY2l0eShvcGFjaXR5U3RhdGUudGV4dCk7XG4gICAgICAgICAgICAgICAgLy8gVmVydGljYWwgdGV4dCBmYWRlcyBpbi9vdXQgb24gY29sbGlzaW9uIHRoZSBzYW1lIHdheSBhcyBjb3JyZXNwb25kaW5nXG4gICAgICAgICAgICAgICAgLy8gaG9yaXpvbnRhbCB0ZXh0LiBTd2l0Y2ggYmV0d2VlbiB2ZXJ0aWNhbC9ob3Jpem9udGFsIHNob3VsZCBiZSBpbnN0YW50YW5lb3VzXG4gICAgICAgICAgICAgICAgY29uc3QgaG9yaXpvbnRhbE9wYWNpdHkgPSBob3Jpem9udGFsSGlkZGVuID8gUEFDS0VEX0hJRERFTl9PUEFDSVRZIDogcGFja2VkT3BhY2l0eTtcbiAgICAgICAgICAgICAgICBhZGRPcGFjaXRpZXMoYnVja2V0LnRleHQsIG51bUhvcml6b250YWxHbHlwaFZlcnRpY2VzLCBob3Jpem9udGFsT3BhY2l0eSk7XG4gICAgICAgICAgICAgICAgY29uc3QgdmVydGljYWxPcGFjaXR5ID0gdmVydGljYWxIaWRkZW4gPyBQQUNLRURfSElEREVOX09QQUNJVFkgOiBwYWNrZWRPcGFjaXR5O1xuICAgICAgICAgICAgICAgIGFkZE9wYWNpdGllcyhidWNrZXQudGV4dCwgbnVtVmVydGljYWxHbHlwaFZlcnRpY2VzLCB2ZXJ0aWNhbE9wYWNpdHkpO1xuXG4gICAgICAgICAgICAgICAgLy8gSWYgdGhpcyBsYWJlbCBpcyBjb21wbGV0ZWx5IGZhZGVkLCBtYXJrIGl0IHNvIHRoYXQgd2UgZG9uJ3QgaGF2ZSB0byBjYWxjdWxhdGVcbiAgICAgICAgICAgICAgICAvLyBpdHMgcG9zaXRpb24gYXQgcmVuZGVyIHRpbWUuIElmIHRoaXMgbGF5ZXIgaGFzIHZhcmlhYmxlIHBsYWNlbWVudCwgc2hpZnQgdGhlIHZhcmlvdXNcbiAgICAgICAgICAgICAgICAvLyBzeW1ib2wgaW5zdGFuY2VzIGFwcHJvcHJpYXRlbHkgc28gdGhhdCBzeW1ib2xzIGZyb20gYnVja2V0cyB0aGF0IGhhdmUgeWV0IHRvIGJlIHBsYWNlZFxuICAgICAgICAgICAgICAgIC8vIG9mZnNldCBhcHByb3ByaWF0ZWx5LlxuICAgICAgICAgICAgICAgIGNvbnN0IHN5bWJvbEhpZGRlbiA9IG9wYWNpdHlTdGF0ZS50ZXh0LmlzSGlkZGVuKCk7XG4gICAgICAgICAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgICAgICAgICBsZWZ0SnVzdGlmaWVkVGV4dFN5bWJvbEluZGV4OiBsZWZ0LCBjZW50ZXJKdXN0aWZpZWRUZXh0U3ltYm9sSW5kZXg6IGNlbnRlcixcbiAgICAgICAgICAgICAgICAgICAgcmlnaHRKdXN0aWZpZWRUZXh0U3ltYm9sSW5kZXg6IHJpZ2h0LCB2ZXJ0aWNhbFBsYWNlZFRleHRTeW1ib2xJbmRleDogdmVydGljYWxcbiAgICAgICAgICAgICAgICB9ID0gc3ltYm9sSW5zdGFuY2U7XG4gICAgICAgICAgICAgICAgY29uc3QgYXJyYXkgPSBidWNrZXQudGV4dC5wbGFjZWRTeW1ib2xBcnJheTtcbiAgICAgICAgICAgICAgICBjb25zdCBob3Jpem9udGFsSGlkZGVuVmFsdWUgPSBzeW1ib2xIaWRkZW4gfHwgaG9yaXpvbnRhbEhpZGRlbiA/IDEgOiAwO1xuXG4gICAgICAgICAgICAgICAgaWYgKGxlZnQgPj0gMCkgYXJyYXkuZ2V0KGxlZnQpLmhpZGRlbiA9IGhvcml6b250YWxIaWRkZW5WYWx1ZTtcbiAgICAgICAgICAgICAgICBpZiAoY2VudGVyID49IDApIGFycmF5LmdldChjZW50ZXIpLmhpZGRlbiA9IGhvcml6b250YWxIaWRkZW5WYWx1ZTtcbiAgICAgICAgICAgICAgICBpZiAocmlnaHQgPj0gMCkgYXJyYXkuZ2V0KHJpZ2h0KS5oaWRkZW4gPSBob3Jpem9udGFsSGlkZGVuVmFsdWU7XG4gICAgICAgICAgICAgICAgaWYgKHZlcnRpY2FsID49IDApIGFycmF5LmdldCh2ZXJ0aWNhbCkuaGlkZGVuID0gc3ltYm9sSGlkZGVuIHx8IHZlcnRpY2FsSGlkZGVuID8gMSA6IDA7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBwcmV2T2Zmc2V0ID0gdGhpcy52YXJpYWJsZU9mZnNldHNbY3Jvc3NUaWxlSURdO1xuICAgICAgICAgICAgICAgIGlmIChwcmV2T2Zmc2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWFya1VzZWRKdXN0aWZpY2F0aW9uKGJ1Y2tldCwgcHJldk9mZnNldC5hbmNob3IsIHN5bWJvbEluc3RhbmNlLCBwbGFjZWRPcmllbnRhdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3QgcHJldk9yaWVudGF0aW9uID0gdGhpcy5wbGFjZWRPcmllbnRhdGlvbnNbY3Jvc3NUaWxlSURdO1xuICAgICAgICAgICAgICAgIGlmIChwcmV2T3JpZW50YXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXJrVXNlZEp1c3RpZmljYXRpb24oYnVja2V0LCAnbGVmdCcsIHN5bWJvbEluc3RhbmNlLCBwcmV2T3JpZW50YXRpb24pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1hcmtVc2VkT3JpZW50YXRpb24oYnVja2V0LCBwcmV2T3JpZW50YXRpb24sIHN5bWJvbEluc3RhbmNlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChoYXNJY29uKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFja2VkT3BhY2l0eSA9IHBhY2tPcGFjaXR5KG9wYWNpdHlTdGF0ZS5pY29uKTtcbiAgICAgICAgICAgICAgICBjb25zdCB7cGxhY2VkSWNvblN5bWJvbEluZGV4LCB2ZXJ0aWNhbFBsYWNlZEljb25TeW1ib2xJbmRleH0gPSBzeW1ib2xJbnN0YW5jZTtcbiAgICAgICAgICAgICAgICBjb25zdCBhcnJheSA9IGJ1Y2tldC5pY29uLnBsYWNlZFN5bWJvbEFycmF5O1xuICAgICAgICAgICAgICAgIGNvbnN0IGljb25IaWRkZW4gPSBvcGFjaXR5U3RhdGUuaWNvbi5pc0hpZGRlbigpID8gMSA6IDA7XG5cbiAgICAgICAgICAgICAgICBpZiAocGxhY2VkSWNvblN5bWJvbEluZGV4ID49IDApIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaG9yaXpvbnRhbE9wYWNpdHkgPSAhaG9yaXpvbnRhbEhpZGRlbiA/IHBhY2tlZE9wYWNpdHkgOiBQQUNLRURfSElEREVOX09QQUNJVFk7XG4gICAgICAgICAgICAgICAgICAgIGFkZE9wYWNpdGllcyhidWNrZXQuaWNvbiwgbnVtSWNvblZlcnRpY2VzLCBob3Jpem9udGFsT3BhY2l0eSk7XG4gICAgICAgICAgICAgICAgICAgIGFycmF5LmdldChwbGFjZWRJY29uU3ltYm9sSW5kZXgpLmhpZGRlbiA9IGljb25IaWRkZW47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHZlcnRpY2FsUGxhY2VkSWNvblN5bWJvbEluZGV4ID49IDApIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmVydGljYWxPcGFjaXR5ID0gIXZlcnRpY2FsSGlkZGVuID8gcGFja2VkT3BhY2l0eSA6IFBBQ0tFRF9ISURERU5fT1BBQ0lUWTtcbiAgICAgICAgICAgICAgICAgICAgYWRkT3BhY2l0aWVzKGJ1Y2tldC5pY29uLCBzeW1ib2xJbnN0YW5jZS5udW1WZXJ0aWNhbEljb25WZXJ0aWNlcywgdmVydGljYWxPcGFjaXR5KTtcbiAgICAgICAgICAgICAgICAgICAgYXJyYXkuZ2V0KHZlcnRpY2FsUGxhY2VkSWNvblN5bWJvbEluZGV4KS5oaWRkZW4gPSBpY29uSGlkZGVuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGJ1Y2tldC5oYXNJY29uQ29sbGlzaW9uQm94RGF0YSgpIHx8IGJ1Y2tldC5oYXNUZXh0Q29sbGlzaW9uQm94RGF0YSgpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29sbGlzaW9uQXJyYXlzID0gYnVja2V0LmNvbGxpc2lvbkFycmF5c1tzXTtcbiAgICAgICAgICAgICAgICBpZiAoY29sbGlzaW9uQXJyYXlzKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBzaGlmdCA9IG5ldyBQb2ludCgwLCAwKTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHVzZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY29sbGlzaW9uQXJyYXlzLnRleHRCb3ggfHwgY29sbGlzaW9uQXJyYXlzLnZlcnRpY2FsVGV4dEJveCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhcmlhYmxlUGxhY2VtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFyaWFibGVPZmZzZXQgPSB0aGlzLnZhcmlhYmxlT2Zmc2V0c1tjcm9zc1RpbGVJRF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhcmlhYmxlT2Zmc2V0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgd2lsbCBzaG93IGVpdGhlciB0aGUgY3VycmVudGx5IHBsYWNlZCBwb3NpdGlvbiBvciB0aGUgbGFzdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzdWNjZXNzZnVsbHkgcGxhY2VkIHBvc2l0aW9uIChzbyB5b3UgY2FuIHZpc3VhbGl6ZSB3aGF0IGNvbGxpc2lvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBqdXN0IG1hZGUgdGhlIHN5bWJvbCBkaXNhcHBlYXIsIGFuZCB0aGUgbW9zdCBsaWtlbHkgcGxhY2UgZm9yIHRoZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzeW1ib2wgdG8gY29tZSBiYWNrKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaGlmdCA9IGNhbGN1bGF0ZVZhcmlhYmxlTGF5b3V0U2hpZnQodmFyaWFibGVPZmZzZXQuYW5jaG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZU9mZnNldC53aWR0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGVPZmZzZXQuaGVpZ2h0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZU9mZnNldC50ZXh0T2Zmc2V0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZU9mZnNldC50ZXh0U2NhbGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocm90YXRlV2l0aE1hcCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hpZnQuX3JvdGF0ZShwaXRjaFdpdGhNYXAgPyB0aGlzLnRyYW5zZm9ybS5hbmdsZSA6IC10aGlzLnRyYW5zZm9ybS5hbmdsZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBObyBvZmZzZXQgLT4gdGhpcyBzeW1ib2wgaGFzbid0IGJlZW4gcGxhY2VkIHNpbmNlIGNvbWluZyBvbi1zY3JlZW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm8gc2luZ2xlIGJveCBpcyBwYXJ0aWN1bGFybHkgbWVhbmluZ2Z1bCBhbmQgYWxsIG9mIHRoZW0gd291bGQgYmUgdG9vIG5vaXN5XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFVzZSB0aGUgY2VudGVyIGJveCBqdXN0IHRvIHNob3cgc29tZXRoaW5nJ3MgdGhlcmUsIGJ1dCBtYXJrIGl0IFwibm90IHVzZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaGFzQ2xpcHBpbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VkID0gIW9wYWNpdHlTdGF0ZS5jbGlwcGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29sbGlzaW9uQXJyYXlzLnRleHRCb3gpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVDb2xsaXNpb25WZXJ0aWNlcyhidWNrZXQudGV4dENvbGxpc2lvbkJveC5jb2xsaXNpb25WZXJ0ZXhBcnJheSwgb3BhY2l0eVN0YXRlLnRleHQucGxhY2VkLCAhdXNlZCB8fCBob3Jpem9udGFsSGlkZGVuLCBzaGlmdC54LCBzaGlmdC55KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb2xsaXNpb25BcnJheXMudmVydGljYWxUZXh0Qm94KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlQ29sbGlzaW9uVmVydGljZXMoYnVja2V0LnRleHRDb2xsaXNpb25Cb3guY29sbGlzaW9uVmVydGV4QXJyYXksIG9wYWNpdHlTdGF0ZS50ZXh0LnBsYWNlZCwgIXVzZWQgfHwgdmVydGljYWxIaWRkZW4sIHNoaWZ0LngsIHNoaWZ0LnkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmVydGljYWxJY29uVXNlZCA9IHVzZWQgJiYgQm9vbGVhbighdmVydGljYWxIaWRkZW4gJiYgY29sbGlzaW9uQXJyYXlzLnZlcnRpY2FsSWNvbkJveCk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbGxpc2lvbkFycmF5cy5pY29uQm94KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVDb2xsaXNpb25WZXJ0aWNlcyhidWNrZXQuaWNvbkNvbGxpc2lvbkJveC5jb2xsaXNpb25WZXJ0ZXhBcnJheSwgb3BhY2l0eVN0YXRlLmljb24ucGxhY2VkLCB2ZXJ0aWNhbEljb25Vc2VkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc0ljb25UZXh0Rml0ID8gc2hpZnQueCA6IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFzSWNvblRleHRGaXQgPyBzaGlmdC55IDogMCk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoY29sbGlzaW9uQXJyYXlzLnZlcnRpY2FsSWNvbkJveCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlQ29sbGlzaW9uVmVydGljZXMoYnVja2V0Lmljb25Db2xsaXNpb25Cb3guY29sbGlzaW9uVmVydGV4QXJyYXksIG9wYWNpdHlTdGF0ZS5pY29uLnBsYWNlZCwgIXZlcnRpY2FsSWNvblVzZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFzSWNvblRleHRGaXQgPyBzaGlmdC54IDogMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYXNJY29uVGV4dEZpdCA/IHNoaWZ0LnkgOiAwKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBidWNrZXQuZnVsbHlDbGlwcGVkID0gdmlzaWJsZUluc3RhbmNlQ291bnQgPT09IDA7XG4gICAgICAgIGJ1Y2tldC5zb3J0RmVhdHVyZXModGhpcy50cmFuc2Zvcm0uYW5nbGUpO1xuICAgICAgICBpZiAodGhpcy5yZXRhaW5lZFF1ZXJ5RGF0YVtidWNrZXQuYnVja2V0SW5zdGFuY2VJZF0pIHtcbiAgICAgICAgICAgIHRoaXMucmV0YWluZWRRdWVyeURhdGFbYnVja2V0LmJ1Y2tldEluc3RhbmNlSWRdLmZlYXR1cmVTb3J0T3JkZXIgPSBidWNrZXQuZmVhdHVyZVNvcnRPcmRlcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChidWNrZXQuaGFzVGV4dERhdGEoKSAmJiBidWNrZXQudGV4dC5vcGFjaXR5VmVydGV4QnVmZmVyKSB7XG4gICAgICAgICAgICBidWNrZXQudGV4dC5vcGFjaXR5VmVydGV4QnVmZmVyLnVwZGF0ZURhdGEoYnVja2V0LnRleHQub3BhY2l0eVZlcnRleEFycmF5KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYnVja2V0Lmhhc0ljb25EYXRhKCkgJiYgYnVja2V0Lmljb24ub3BhY2l0eVZlcnRleEJ1ZmZlcikge1xuICAgICAgICAgICAgYnVja2V0Lmljb24ub3BhY2l0eVZlcnRleEJ1ZmZlci51cGRhdGVEYXRhKGJ1Y2tldC5pY29uLm9wYWNpdHlWZXJ0ZXhBcnJheSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGJ1Y2tldC5oYXNJY29uQ29sbGlzaW9uQm94RGF0YSgpICYmIGJ1Y2tldC5pY29uQ29sbGlzaW9uQm94LmNvbGxpc2lvblZlcnRleEJ1ZmZlcikge1xuICAgICAgICAgICAgYnVja2V0Lmljb25Db2xsaXNpb25Cb3guY29sbGlzaW9uVmVydGV4QnVmZmVyLnVwZGF0ZURhdGEoYnVja2V0Lmljb25Db2xsaXNpb25Cb3guY29sbGlzaW9uVmVydGV4QXJyYXkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChidWNrZXQuaGFzVGV4dENvbGxpc2lvbkJveERhdGEoKSAmJiBidWNrZXQudGV4dENvbGxpc2lvbkJveC5jb2xsaXNpb25WZXJ0ZXhCdWZmZXIpIHtcbiAgICAgICAgICAgIGJ1Y2tldC50ZXh0Q29sbGlzaW9uQm94LmNvbGxpc2lvblZlcnRleEJ1ZmZlci51cGRhdGVEYXRhKGJ1Y2tldC50ZXh0Q29sbGlzaW9uQm94LmNvbGxpc2lvblZlcnRleEFycmF5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGFzc2VydChidWNrZXQudGV4dC5vcGFjaXR5VmVydGV4QXJyYXkubGVuZ3RoID09PSBidWNrZXQudGV4dC5sYXlvdXRWZXJ0ZXhBcnJheS5sZW5ndGggLyA0KTtcbiAgICAgICAgYXNzZXJ0KGJ1Y2tldC5pY29uLm9wYWNpdHlWZXJ0ZXhBcnJheS5sZW5ndGggPT09IGJ1Y2tldC5pY29uLmxheW91dFZlcnRleEFycmF5Lmxlbmd0aCAvIDQpO1xuXG4gICAgICAgIC8vIFB1c2ggZ2VuZXJhdGVkIGNvbGxpc2lvbiBjaXJjbGVzIHRvIHRoZSBidWNrZXQgZm9yIGRlYnVnIHJlbmRlcmluZ1xuICAgICAgICBpZiAoYnVja2V0LmJ1Y2tldEluc3RhbmNlSWQgaW4gdGhpcy5jb2xsaXNpb25DaXJjbGVBcnJheXMpIHtcbiAgICAgICAgICAgIGNvbnN0IGluc3RhbmNlID0gdGhpcy5jb2xsaXNpb25DaXJjbGVBcnJheXNbYnVja2V0LmJ1Y2tldEluc3RhbmNlSWRdO1xuXG4gICAgICAgICAgICBidWNrZXQucGxhY2VtZW50SW52UHJvak1hdHJpeCA9IGluc3RhbmNlLmludlByb2pNYXRyaXg7XG4gICAgICAgICAgICBidWNrZXQucGxhY2VtZW50Vmlld3BvcnRNYXRyaXggPSBpbnN0YW5jZS52aWV3cG9ydE1hdHJpeDtcbiAgICAgICAgICAgIGJ1Y2tldC5jb2xsaXNpb25DaXJjbGVBcnJheSA9IGluc3RhbmNlLmNpcmNsZXM7XG5cbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmNvbGxpc2lvbkNpcmNsZUFycmF5c1tidWNrZXQuYnVja2V0SW5zdGFuY2VJZF07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzeW1ib2xGYWRlQ2hhbmdlKG5vdzogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZmFkZUR1cmF0aW9uID09PSAwID9cbiAgICAgICAgICAgIDEgOlxuICAgICAgICAgICAgKChub3cgLSB0aGlzLmNvbW1pdFRpbWUpIC8gdGhpcy5mYWRlRHVyYXRpb24gKyB0aGlzLnByZXZab29tQWRqdXN0bWVudCk7XG4gICAgfVxuXG4gICAgem9vbUFkanVzdG1lbnQoem9vbTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgLy8gV2hlbiB6b29taW5nIG91dCBxdWlja2x5LCBsYWJlbHMgY2FuIG92ZXJsYXAgZWFjaCBvdGhlci4gVGhpc1xuICAgICAgICAvLyBhZGp1c3RtZW50IGlzIHVzZWQgdG8gcmVkdWNlIHRoZSBpbnRlcnZhbCBiZXR3ZWVuIHBsYWNlbWVudCBjYWxjdWxhdGlvbnNcbiAgICAgICAgLy8gYW5kIHRvIHJlZHVjZSB0aGUgZmFkZSBkdXJhdGlvbiB3aGVuIHpvb21pbmcgb3V0IHF1aWNrbHkuIERpc2NvdmVyaW5nIHRoZVxuICAgICAgICAvLyBjb2xsaXNpb25zIG1vcmUgcXVpY2tseSBhbmQgZmFkaW5nIHRoZW0gbW9yZSBxdWlja2x5IHJlZHVjZXMgdGhlIHVud2FudGVkIGVmZmVjdC5cbiAgICAgICAgcmV0dXJuIE1hdGgubWF4KDAsICh0aGlzLnRyYW5zZm9ybS56b29tIC0gem9vbSkgLyAxLjUpO1xuICAgIH1cblxuICAgIGhhc1RyYW5zaXRpb25zKG5vdzogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YWxlIHx8XG4gICAgICAgICAgICBub3cgLSB0aGlzLmxhc3RQbGFjZW1lbnRDaGFuZ2VUaW1lIDwgdGhpcy5mYWRlRHVyYXRpb247XG4gICAgfVxuXG4gICAgc3RpbGxSZWNlbnQobm93OiBudW1iZXIsIHpvb206IG51bWJlcik6IGJvb2xlYW4ge1xuICAgICAgICAvLyBUaGUgYWRqdXN0bWVudCBtYWtlcyBwbGFjZW1lbnQgbW9yZSBmcmVxdWVudCB3aGVuIHpvb21pbmcuXG4gICAgICAgIC8vIFRoaXMgY29uZGl0aW9uIGFwcGxpZXMgdGhlIGFkanVzdG1lbnQgb25seSBhZnRlciB0aGUgbWFwIGhhc1xuICAgICAgICAvLyBzdG9wcGVkIHpvb21pbmcuIFRoaXMgYXZvaWRzIGFkZGluZyBleHRyYSBqYW5rIHdoaWxlIHpvb21pbmcuXG4gICAgICAgIGNvbnN0IGR1cmF0aW9uQWRqdXN0bWVudCA9IHRoaXMuem9vbUF0TGFzdFJlY2VuY3lDaGVjayA9PT0gem9vbSA/XG4gICAgICAgICAgICAoMSAtIHRoaXMuem9vbUFkanVzdG1lbnQoem9vbSkpIDpcbiAgICAgICAgICAgIDE7XG4gICAgICAgIHRoaXMuem9vbUF0TGFzdFJlY2VuY3lDaGVjayA9IHpvb207XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuY29tbWl0VGltZSArIHRoaXMuZmFkZUR1cmF0aW9uICogZHVyYXRpb25BZGp1c3RtZW50ID4gbm93O1xuICAgIH1cblxuICAgIHNldFN0YWxlKCkge1xuICAgICAgICB0aGlzLnN0YWxlID0gdHJ1ZTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUNvbGxpc2lvblZlcnRpY2VzKGNvbGxpc2lvblZlcnRleEFycmF5OiBDb2xsaXNpb25WZXJ0ZXhBcnJheSwgcGxhY2VkOiBib29sZWFuLCBub3RVc2VkOiBib29sZWFuIHwgbnVtYmVyLCBzaGlmdFg/OiBudW1iZXIsIHNoaWZ0WT86IG51bWJlcikge1xuICAgIGNvbGxpc2lvblZlcnRleEFycmF5LmVtcGxhY2VCYWNrKHBsYWNlZCA/IDEgOiAwLCBub3RVc2VkID8gMSA6IDAsIHNoaWZ0WCB8fCAwLCBzaGlmdFkgfHwgMCk7XG4gICAgY29sbGlzaW9uVmVydGV4QXJyYXkuZW1wbGFjZUJhY2socGxhY2VkID8gMSA6IDAsIG5vdFVzZWQgPyAxIDogMCwgc2hpZnRYIHx8IDAsIHNoaWZ0WSB8fCAwKTtcbiAgICBjb2xsaXNpb25WZXJ0ZXhBcnJheS5lbXBsYWNlQmFjayhwbGFjZWQgPyAxIDogMCwgbm90VXNlZCA/IDEgOiAwLCBzaGlmdFggfHwgMCwgc2hpZnRZIHx8IDApO1xuICAgIGNvbGxpc2lvblZlcnRleEFycmF5LmVtcGxhY2VCYWNrKHBsYWNlZCA/IDEgOiAwLCBub3RVc2VkID8gMSA6IDAsIHNoaWZ0WCB8fCAwLCBzaGlmdFkgfHwgMCk7XG59XG5cbi8vIEFsbCBmb3VyIHZlcnRpY2VzIGZvciBhIGdseXBoIHdpbGwgaGF2ZSB0aGUgc2FtZSBvcGFjaXR5IHN0YXRlXG4vLyBTbyB3ZSBwYWNrIHRoZSBvcGFjaXR5IGludG8gYSB1aW50OCwgYW5kIHRoZW4gcmVwZWF0IGl0IGZvdXIgdGltZXNcbi8vIHRvIG1ha2UgYSBzaW5nbGUgdWludDMyIHRoYXQgd2UgY2FuIHVwbG9hZCBmb3IgZWFjaCBnbHlwaCBpbiB0aGVcbi8vIGxhYmVsLlxuY29uc3Qgc2hpZnQyNSA9IE1hdGgucG93KDIsIDI1KTtcbmNvbnN0IHNoaWZ0MjQgPSBNYXRoLnBvdygyLCAyNCk7XG5jb25zdCBzaGlmdDE3ID0gTWF0aC5wb3coMiwgMTcpO1xuY29uc3Qgc2hpZnQxNiA9IE1hdGgucG93KDIsIDE2KTtcbmNvbnN0IHNoaWZ0OSA9IE1hdGgucG93KDIsIDkpO1xuY29uc3Qgc2hpZnQ4ID0gTWF0aC5wb3coMiwgOCk7XG5jb25zdCBzaGlmdDEgPSBNYXRoLnBvdygyLCAxKTtcbmZ1bmN0aW9uIHBhY2tPcGFjaXR5KG9wYWNpdHlTdGF0ZTogT3BhY2l0eVN0YXRlKTogbnVtYmVyIHtcbiAgICBpZiAob3BhY2l0eVN0YXRlLm9wYWNpdHkgPT09IDAgJiYgIW9wYWNpdHlTdGF0ZS5wbGFjZWQpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfSBlbHNlIGlmIChvcGFjaXR5U3RhdGUub3BhY2l0eSA9PT0gMSAmJiBvcGFjaXR5U3RhdGUucGxhY2VkKSB7XG4gICAgICAgIHJldHVybiA0Mjk0OTY3Mjk1O1xuICAgIH1cbiAgICBjb25zdCB0YXJnZXRCaXQgPSBvcGFjaXR5U3RhdGUucGxhY2VkID8gMSA6IDA7XG4gICAgY29uc3Qgb3BhY2l0eUJpdHMgPSBNYXRoLmZsb29yKG9wYWNpdHlTdGF0ZS5vcGFjaXR5ICogMTI3KTtcbiAgICByZXR1cm4gb3BhY2l0eUJpdHMgKiBzaGlmdDI1ICsgdGFyZ2V0Qml0ICogc2hpZnQyNCArXG4gICAgICAgIG9wYWNpdHlCaXRzICogc2hpZnQxNyArIHRhcmdldEJpdCAqIHNoaWZ0MTYgK1xuICAgICAgICBvcGFjaXR5Qml0cyAqIHNoaWZ0OSArIHRhcmdldEJpdCAqIHNoaWZ0OCArXG4gICAgICAgIG9wYWNpdHlCaXRzICogc2hpZnQxICsgdGFyZ2V0Qml0O1xufVxuXG5jb25zdCBQQUNLRURfSElEREVOX09QQUNJVFkgPSAwO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IGJyb3dzZXIgZnJvbSAnLi4vdXRpbC9icm93c2VyLmpzJztcblxuaW1wb3J0IHtQbGFjZW1lbnR9IGZyb20gJy4uL3N5bWJvbC9wbGFjZW1lbnQuanMnO1xuaW1wb3J0IHtQZXJmb3JtYW5jZVV0aWxzfSBmcm9tICcuLi91dGlsL3BlcmZvcm1hbmNlLmpzJztcblxuaW1wb3J0IHR5cGUgVHJhbnNmb3JtIGZyb20gJy4uL2dlby90cmFuc2Zvcm0uanMnO1xuaW1wb3J0IHR5cGUgU3R5bGVMYXllciBmcm9tICcuL3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCB0eXBlIFN5bWJvbFN0eWxlTGF5ZXIgZnJvbSAnLi9zdHlsZV9sYXllci9zeW1ib2xfc3R5bGVfbGF5ZXIuanMnO1xuaW1wb3J0IHR5cGUgVGlsZSBmcm9tICcuLi9zb3VyY2UvdGlsZS5qcyc7XG5pbXBvcnQgdHlwZSB7QnVja2V0UGFydH0gZnJvbSAnLi4vc3ltYm9sL3BsYWNlbWVudC5qcyc7XG5pbXBvcnQgdHlwZSB7Rm9nU3RhdGV9IGZyb20gJy4vZm9nX2hlbHBlcnMuanMnO1xuXG5jbGFzcyBMYXllclBsYWNlbWVudCB7XG4gICAgX3NvcnRBY3Jvc3NUaWxlczogYm9vbGVhbjtcbiAgICBfY3VycmVudFRpbGVJbmRleDogbnVtYmVyO1xuICAgIF9jdXJyZW50UGFydEluZGV4OiBudW1iZXI7XG4gICAgX3NlZW5Dcm9zc1RpbGVJRHM6IFNldDxudW1iZXI+O1xuICAgIF9idWNrZXRQYXJ0czogQXJyYXk8QnVja2V0UGFydD47XG5cbiAgICBjb25zdHJ1Y3RvcihzdHlsZUxheWVyOiBTeW1ib2xTdHlsZUxheWVyKSB7XG4gICAgICAgIHRoaXMuX3NvcnRBY3Jvc3NUaWxlcyA9IHN0eWxlTGF5ZXIubGF5b3V0LmdldCgnc3ltYm9sLXotb3JkZXInKSAhPT0gJ3ZpZXdwb3J0LXknICYmXG4gICAgICAgICAgICBzdHlsZUxheWVyLmxheW91dC5nZXQoJ3N5bWJvbC1zb3J0LWtleScpLmNvbnN0YW50T3IoMSkgIT09IHVuZGVmaW5lZDtcblxuICAgICAgICB0aGlzLl9jdXJyZW50VGlsZUluZGV4ID0gMDtcbiAgICAgICAgdGhpcy5fY3VycmVudFBhcnRJbmRleCA9IDA7XG4gICAgICAgIHRoaXMuX3NlZW5Dcm9zc1RpbGVJRHMgPSBuZXcgU2V0KCk7XG4gICAgICAgIHRoaXMuX2J1Y2tldFBhcnRzID0gW107XG4gICAgfVxuXG4gICAgY29udGludWVQbGFjZW1lbnQodGlsZXM6IEFycmF5PFRpbGU+LCBwbGFjZW1lbnQ6IFBsYWNlbWVudCwgc2hvd0NvbGxpc2lvbkJveGVzOiBib29sZWFuLCBzdHlsZUxheWVyOiBTdHlsZUxheWVyLCBzaG91bGRQYXVzZVBsYWNlbWVudDogKCkgPT4gYm9vbGVhbik6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCBidWNrZXRQYXJ0cyA9IHRoaXMuX2J1Y2tldFBhcnRzO1xuXG4gICAgICAgIHdoaWxlICh0aGlzLl9jdXJyZW50VGlsZUluZGV4IDwgdGlsZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICBjb25zdCB0aWxlID0gdGlsZXNbdGhpcy5fY3VycmVudFRpbGVJbmRleF07XG4gICAgICAgICAgICBwbGFjZW1lbnQuZ2V0QnVja2V0UGFydHMoYnVja2V0UGFydHMsIHN0eWxlTGF5ZXIsIHRpbGUsIHRoaXMuX3NvcnRBY3Jvc3NUaWxlcyk7XG5cbiAgICAgICAgICAgIHRoaXMuX2N1cnJlbnRUaWxlSW5kZXgrKztcbiAgICAgICAgICAgIGlmIChzaG91bGRQYXVzZVBsYWNlbWVudCgpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5fc29ydEFjcm9zc1RpbGVzKSB7XG4gICAgICAgICAgICB0aGlzLl9zb3J0QWNyb3NzVGlsZXMgPSBmYWxzZTtcbiAgICAgICAgICAgIGJ1Y2tldFBhcnRzLnNvcnQoKGEsIGIpID0+ICgoYS5zb3J0S2V5OiBhbnkpOiBudW1iZXIpIC0gKChiLnNvcnRLZXk6IGFueSk6IG51bWJlcikpO1xuICAgICAgICB9XG5cbiAgICAgICAgd2hpbGUgKHRoaXMuX2N1cnJlbnRQYXJ0SW5kZXggPCBidWNrZXRQYXJ0cy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNvbnN0IGJ1Y2tldFBhcnQgPSBidWNrZXRQYXJ0c1t0aGlzLl9jdXJyZW50UGFydEluZGV4XTtcbiAgICAgICAgICAgIHBsYWNlbWVudC5wbGFjZUxheWVyQnVja2V0UGFydChidWNrZXRQYXJ0LCB0aGlzLl9zZWVuQ3Jvc3NUaWxlSURzLCBzaG93Q29sbGlzaW9uQm94ZXMsIGJ1Y2tldFBhcnQuc3ltYm9sSW5zdGFuY2VTdGFydCA9PT0gMCk7XG4gICAgICAgICAgICB0aGlzLl9jdXJyZW50UGFydEluZGV4Kys7XG4gICAgICAgICAgICBpZiAoc2hvdWxkUGF1c2VQbGFjZW1lbnQoKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59XG5cbmNsYXNzIFBhdXNlYWJsZVBsYWNlbWVudCB7XG4gICAgcGxhY2VtZW50OiBQbGFjZW1lbnQ7XG4gICAgX2RvbmU6IGJvb2xlYW47XG4gICAgX2N1cnJlbnRQbGFjZW1lbnRJbmRleDogbnVtYmVyO1xuICAgIF9mb3JjZUZ1bGxQbGFjZW1lbnQ6IGJvb2xlYW47XG4gICAgX3Nob3dDb2xsaXNpb25Cb3hlczogYm9vbGVhbjtcbiAgICBfaW5Qcm9ncmVzc0xheWVyOiA/TGF5ZXJQbGFjZW1lbnQ7XG5cbiAgICBjb25zdHJ1Y3Rvcih0cmFuc2Zvcm06IFRyYW5zZm9ybSwgb3JkZXI6IEFycmF5PHN0cmluZz4sXG4gICAgICAgICAgICAgICAgZm9yY2VGdWxsUGxhY2VtZW50OiBib29sZWFuLFxuICAgICAgICAgICAgICAgIHNob3dDb2xsaXNpb25Cb3hlczogYm9vbGVhbixcbiAgICAgICAgICAgICAgICBmYWRlRHVyYXRpb246IG51bWJlcixcbiAgICAgICAgICAgICAgICBjcm9zc1NvdXJjZUNvbGxpc2lvbnM6IGJvb2xlYW4sXG4gICAgICAgICAgICAgICAgcHJldlBsYWNlbWVudD86IFBsYWNlbWVudCxcbiAgICAgICAgICAgICAgICBmb2dTdGF0ZTogP0ZvZ1N0YXRlKSB7XG5cbiAgICAgICAgdGhpcy5wbGFjZW1lbnQgPSBuZXcgUGxhY2VtZW50KHRyYW5zZm9ybSwgZmFkZUR1cmF0aW9uLCBjcm9zc1NvdXJjZUNvbGxpc2lvbnMsIHByZXZQbGFjZW1lbnQsIGZvZ1N0YXRlKTtcbiAgICAgICAgdGhpcy5fY3VycmVudFBsYWNlbWVudEluZGV4ID0gb3JkZXIubGVuZ3RoIC0gMTtcbiAgICAgICAgdGhpcy5fZm9yY2VGdWxsUGxhY2VtZW50ID0gZm9yY2VGdWxsUGxhY2VtZW50O1xuICAgICAgICB0aGlzLl9zaG93Q29sbGlzaW9uQm94ZXMgPSBzaG93Q29sbGlzaW9uQm94ZXM7XG4gICAgICAgIHRoaXMuX2RvbmUgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBpc0RvbmUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kb25lO1xuICAgIH1cblxuICAgIGNvbnRpbnVlUGxhY2VtZW50KG9yZGVyOiBBcnJheTxzdHJpbmc+LCBsYXllcnM6IHtbXzogc3RyaW5nXTogU3R5bGVMYXllcn0sIGxheWVyVGlsZXM6IHtbXzogc3RyaW5nXTogQXJyYXk8VGlsZT59KSB7XG4gICAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IGJyb3dzZXIubm93KCk7XG5cbiAgICAgICAgY29uc3Qgc2hvdWxkUGF1c2VQbGFjZW1lbnQgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBlbGFwc2VkVGltZSA9IGJyb3dzZXIubm93KCkgLSBzdGFydFRpbWU7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZm9yY2VGdWxsUGxhY2VtZW50ID8gZmFsc2UgOiBlbGFwc2VkVGltZSA+IDI7XG4gICAgICAgIH07XG5cbiAgICAgICAgd2hpbGUgKHRoaXMuX2N1cnJlbnRQbGFjZW1lbnRJbmRleCA+PSAwKSB7XG4gICAgICAgICAgICBjb25zdCBsYXllcklkID0gb3JkZXJbdGhpcy5fY3VycmVudFBsYWNlbWVudEluZGV4XTtcbiAgICAgICAgICAgIGNvbnN0IGxheWVyID0gbGF5ZXJzW2xheWVySWRdO1xuICAgICAgICAgICAgY29uc3QgcGxhY2VtZW50Wm9vbSA9IHRoaXMucGxhY2VtZW50LmNvbGxpc2lvbkluZGV4LnRyYW5zZm9ybS56b29tO1xuICAgICAgICAgICAgaWYgKGxheWVyLnR5cGUgPT09ICdzeW1ib2wnICYmXG4gICAgICAgICAgICAgICAgKCFsYXllci5taW56b29tIHx8IGxheWVyLm1pbnpvb20gPD0gcGxhY2VtZW50Wm9vbSkgJiZcbiAgICAgICAgICAgICAgICAoIWxheWVyLm1heHpvb20gfHwgbGF5ZXIubWF4em9vbSA+IHBsYWNlbWVudFpvb20pKSB7XG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX2luUHJvZ3Jlc3NMYXllcikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9pblByb2dyZXNzTGF5ZXIgPSBuZXcgTGF5ZXJQbGFjZW1lbnQoKChsYXllcjogYW55KTogU3ltYm9sU3R5bGVMYXllcikpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHBhdXNlUGxhY2VtZW50ID0gdGhpcy5faW5Qcm9ncmVzc0xheWVyLmNvbnRpbnVlUGxhY2VtZW50KGxheWVyVGlsZXNbbGF5ZXIuc291cmNlXSwgdGhpcy5wbGFjZW1lbnQsIHRoaXMuX3Nob3dDb2xsaXNpb25Cb3hlcywgbGF5ZXIsIHNob3VsZFBhdXNlUGxhY2VtZW50KTtcblxuICAgICAgICAgICAgICAgIGlmIChwYXVzZVBsYWNlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICBQZXJmb3JtYW5jZVV0aWxzLnJlY29yZFBsYWNlbWVudFRpbWUoYnJvd3Nlci5ub3coKSAtIHN0YXJ0VGltZSk7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdlIGRpZG4ndCBmaW5pc2ggcGxhY2luZyBhbGwgbGF5ZXJzIHdpdGhpbiAybXMsXG4gICAgICAgICAgICAgICAgICAgIC8vIGJ1dCB3ZSBjYW4ga2VlcCByZW5kZXJpbmcgd2l0aCBhIHBhcnRpYWwgcGxhY2VtZW50XG4gICAgICAgICAgICAgICAgICAgIC8vIFdlJ2xsIHJlc3VtZSBoZXJlIG9uIHRoZSBuZXh0IGZyYW1lXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5faW5Qcm9ncmVzc0xheWVyO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLl9jdXJyZW50UGxhY2VtZW50SW5kZXgtLTtcbiAgICAgICAgfVxuICAgICAgICBQZXJmb3JtYW5jZVV0aWxzLnJlY29yZFBsYWNlbWVudFRpbWUoYnJvd3Nlci5ub3coKSAtIHN0YXJ0VGltZSk7XG4gICAgICAgIHRoaXMuX2RvbmUgPSB0cnVlO1xuICAgIH1cblxuICAgIGNvbW1pdChub3c6IG51bWJlcik6IFBsYWNlbWVudCB7XG4gICAgICAgIHRoaXMucGxhY2VtZW50LmNvbW1pdChub3cpO1xuICAgICAgICByZXR1cm4gdGhpcy5wbGFjZW1lbnQ7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBQYXVzZWFibGVQbGFjZW1lbnQ7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgRVhURU5UIGZyb20gJy4uL2RhdGEvZXh0ZW50LmpzJztcblxuaW1wb3J0IHtTeW1ib2xJbnN0YW5jZUFycmF5fSBmcm9tICcuLi9kYXRhL2FycmF5X3R5cGVzLmpzJztcbmltcG9ydCBLREJ1c2ggZnJvbSAna2RidXNoJztcblxuaW1wb3J0IHR5cGUgUHJvamVjdGlvbiBmcm9tICcuLi9nZW8vcHJvamVjdGlvbi9wcm9qZWN0aW9uLmpzJztcbmltcG9ydCB0eXBlIHtPdmVyc2NhbGVkVGlsZUlEfSBmcm9tICcuLi9zb3VyY2UvdGlsZV9pZC5qcyc7XG5pbXBvcnQgdHlwZSBTeW1ib2xCdWNrZXQgZnJvbSAnLi4vZGF0YS9idWNrZXQvc3ltYm9sX2J1Y2tldC5qcyc7XG5pbXBvcnQgdHlwZSBTdHlsZUxheWVyIGZyb20gJy4uL3N0eWxlL3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCB0eXBlIFRpbGUgZnJvbSAnLi4vc291cmNlL3RpbGUuanMnO1xuXG4vKlxuICAgIFRoZSBDcm9zc1RpbGVTeW1ib2xJbmRleCBnZW5lcmFsbHkgd29ya3Mgb24gdGhlIGFzc3VtcHRpb24gdGhhdFxuICAgIGEgY29uY2VwdHVhbCBcInVuaXF1ZSBzeW1ib2xcIiBjYW4gYmUgaWRlbnRpZmllZCBieSB0aGUgdGV4dCBvZlxuICAgIHRoZSBsYWJlbCBjb21iaW5lZCB3aXRoIHRoZSBhbmNob3IgcG9pbnQuIFRoZSBnb2FsIGlzIHRvIGFzc2lnblxuICAgIHRoZXNlIGNvbmNlcHR1YWwgXCJ1bmlxdWUgc3ltYm9sc1wiIGEgc2hhcmVkIGNyb3NzVGlsZUlEIHRoYXQgY2FuIGJlXG4gICAgdXNlZCBieSBQbGFjZW1lbnQgdG8ga2VlcCBmYWRpbmcgb3BhY2l0eSBzdGF0ZXMgY29uc2lzdGVudCBhbmQgdG9cbiAgICBkZWR1cGxpY2F0ZSBsYWJlbHMuXG5cbiAgICBUaGUgQ3Jvc3NUaWxlU3ltYm9sSW5kZXggaW5kZXhlcyBhbGwgdGhlIGN1cnJlbnQgc3ltYm9sIGluc3RhbmNlcyBhbmRcbiAgICB0aGVpciBjcm9zc1RpbGVJRHMuIFdoZW4gYSBzeW1ib2wgYnVja2V0IGdldHMgYWRkZWQgb3IgdXBkYXRlZCwgdGhlXG4gICAgaW5kZXggYXNzaWducyBhIGNyb3NzVGlsZUlEIHRvIGVhY2ggb2YgaXQncyBzeW1ib2wgaW5zdGFuY2VzIGJ5IGVpdGhlclxuICAgIG1hdGNoaW5nIGl0IHdpdGggYW4gZXhpc3RpbmcgaWQgb3IgYXNzaWduaW5nIGEgbmV3IG9uZS5cbiovXG5cbi8vIFJvdW5kIGFuY2hvciBwb3NpdGlvbnMgdG8gcm91Z2hseSA0IHBpeGVsIGdyaWRcbmNvbnN0IHJvdW5kaW5nRmFjdG9yID0gNTEyIC8gRVhURU5UIC8gMjtcblxuY2xhc3MgVGlsZUxheWVySW5kZXgge1xuICAgIHRpbGVJRDogT3ZlcnNjYWxlZFRpbGVJRDtcbiAgICBidWNrZXRJbnN0YW5jZUlkOiBudW1iZXI7XG4gICAgaW5kZXg6IEtEQnVzaDtcbiAgICBrZXlzOiBBcnJheTxudW1iZXI+O1xuICAgIGNyb3NzVGlsZUlEczogQXJyYXk8bnVtYmVyPjtcblxuICAgIGNvbnN0cnVjdG9yKHRpbGVJRDogT3ZlcnNjYWxlZFRpbGVJRCwgc3ltYm9sSW5zdGFuY2VzOiBTeW1ib2xJbnN0YW5jZUFycmF5LCBidWNrZXRJbnN0YW5jZUlkOiBudW1iZXIpIHtcbiAgICAgICAgdGhpcy50aWxlSUQgPSB0aWxlSUQ7XG4gICAgICAgIHRoaXMuYnVja2V0SW5zdGFuY2VJZCA9IGJ1Y2tldEluc3RhbmNlSWQ7XG5cbiAgICAgICAgLy8gY3JlYXRlIGEgc3BhdGlhbCBpbmRleCBmb3IgZGVkdXBsaWNhdGluZyBzeW1ib2wgaW5zdGFuY2VzO1xuICAgICAgICAvLyB1c2UgYSBsb3cgbm9kZVNpemUgYmVjYXVzZSB3ZSdyZSBvcHRpbWl6aW5nIGZvciBzZWFyY2ggcGVyZm9ybWFuY2UsIG5vdCBpbmRleGluZ1xuICAgICAgICB0aGlzLmluZGV4ID0gbmV3IEtEQnVzaChzeW1ib2xJbnN0YW5jZXMubGVuZ3RoLCAxNiwgSW50MzJBcnJheSk7XG4gICAgICAgIHRoaXMua2V5cyA9IFtdO1xuICAgICAgICB0aGlzLmNyb3NzVGlsZUlEcyA9IFtdO1xuICAgICAgICBjb25zdCB0eCA9IHRpbGVJRC5jYW5vbmljYWwueCAqIEVYVEVOVDtcbiAgICAgICAgY29uc3QgdHkgPSB0aWxlSUQuY2Fub25pY2FsLnkgKiBFWFRFTlQ7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzeW1ib2xJbnN0YW5jZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHtrZXksIGNyb3NzVGlsZUlELCB0aWxlQW5jaG9yWCwgdGlsZUFuY2hvcll9ID0gc3ltYm9sSW5zdGFuY2VzLmdldChpKTtcblxuICAgICAgICAgICAgLy8gQ29udmVydHMgdGhlIGNvb3JkaW5hdGVzIG9mIHRoZSBpbnB1dCBzeW1ib2wgaW5zdGFuY2UgaW50byBjb29yZGluYXRlcyB0aGF0IGJlIGNhbiBjb21wYXJlZFxuICAgICAgICAgICAgLy8gYWdhaW5zdCBvdGhlciBzeW1ib2xzIGluIHRoaXMgaW5kZXguIENvb3JkaW5hdGVzIGFyZTpcbiAgICAgICAgICAgIC8vICgxKSB3b3JsZC1iYXNlZCAoc28gYWZ0ZXIgY29udmVyc2lvbiB0aGUgc291cmNlIHRpbGUgaXMgaXJyZWxldmFudClcbiAgICAgICAgICAgIC8vICgyKSBjb252ZXJ0ZWQgdG8gdGhlIHotc2NhbGUgb2YgdGhpcyBUaWxlTGF5ZXJJbmRleFxuICAgICAgICAgICAgLy8gKDMpIGRvd24tc2FtcGxlZCBieSBcInJvdW5kaW5nRmFjdG9yXCIgZnJvbSB0aWxlIGNvb3JkaW5hdGUgcHJlY2lzaW9uIGluIG9yZGVyIHRvIGJlXG4gICAgICAgICAgICAvLyAgICAgbW9yZSB0b2xlcmFudCBvZiBzbWFsbCBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRpbGVzLlxuICAgICAgICAgICAgY29uc3QgeCA9IE1hdGguZmxvb3IoKHR4ICsgdGlsZUFuY2hvclgpICogcm91bmRpbmdGYWN0b3IpO1xuICAgICAgICAgICAgY29uc3QgeSA9IE1hdGguZmxvb3IoKHR5ICsgdGlsZUFuY2hvclkpICogcm91bmRpbmdGYWN0b3IpO1xuXG4gICAgICAgICAgICB0aGlzLmluZGV4LmFkZCh4LCB5KTtcbiAgICAgICAgICAgIHRoaXMua2V5cy5wdXNoKGtleSk7XG4gICAgICAgICAgICB0aGlzLmNyb3NzVGlsZUlEcy5wdXNoKGNyb3NzVGlsZUlEKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmluZGV4LmZpbmlzaCgpO1xuICAgIH1cblxuICAgIGZpbmRNYXRjaGVzKHN5bWJvbEluc3RhbmNlczogU3ltYm9sSW5zdGFuY2VBcnJheSwgbmV3VGlsZUlEOiBPdmVyc2NhbGVkVGlsZUlELCB6b29tQ3Jvc3NUaWxlSURzOiBTZXQ8bnVtYmVyPikge1xuICAgICAgICBjb25zdCB0b2xlcmFuY2UgPSB0aGlzLnRpbGVJRC5jYW5vbmljYWwueiA8IG5ld1RpbGVJRC5jYW5vbmljYWwueiA/IDEgOiBNYXRoLnBvdygyLCB0aGlzLnRpbGVJRC5jYW5vbmljYWwueiAtIG5ld1RpbGVJRC5jYW5vbmljYWwueik7XG4gICAgICAgIGNvbnN0IHNjYWxlID0gcm91bmRpbmdGYWN0b3IgLyBNYXRoLnBvdygyLCBuZXdUaWxlSUQuY2Fub25pY2FsLnogLSB0aGlzLnRpbGVJRC5jYW5vbmljYWwueik7XG4gICAgICAgIGNvbnN0IHR4ID0gbmV3VGlsZUlELmNhbm9uaWNhbC54ICogRVhURU5UO1xuICAgICAgICBjb25zdCB0eSA9IG5ld1RpbGVJRC5jYW5vbmljYWwueSAqIEVYVEVOVDtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHN5bWJvbEluc3RhbmNlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3Qgc3ltYm9sSW5zdGFuY2UgPSBzeW1ib2xJbnN0YW5jZXMuZ2V0KGkpO1xuICAgICAgICAgICAgaWYgKHN5bWJvbEluc3RhbmNlLmNyb3NzVGlsZUlEKSB7XG4gICAgICAgICAgICAgICAgLy8gYWxyZWFkeSBoYXMgYSBtYXRjaCwgc2tpcFxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qge2tleSwgdGlsZUFuY2hvclgsIHRpbGVBbmNob3JZfSA9IHN5bWJvbEluc3RhbmNlO1xuICAgICAgICAgICAgY29uc3QgeCA9IE1hdGguZmxvb3IoKHR4ICsgdGlsZUFuY2hvclgpICogc2NhbGUpO1xuICAgICAgICAgICAgY29uc3QgeSA9IE1hdGguZmxvb3IoKHR5ICsgdGlsZUFuY2hvclkpICogc2NhbGUpO1xuXG4gICAgICAgICAgICAvLyBSZXR1cm4gYW55IHN5bWJvbCB3aXRoIHRoZSBzYW1lIGtleXMgd2hvc2UgY29vcmRpbmF0ZXMgYXJlIHdpdGhpbiAxXG4gICAgICAgICAgICAvLyBncmlkIHVuaXQuICh3aXRoIGEgNHB4IGdyaWQsIHRoaXMgY292ZXJzIGEgMTJweCBieSAxMnB4IGFyZWEpXG4gICAgICAgICAgICBjb25zdCBtYXRjaGVkSWRzID0gdGhpcy5pbmRleC5yYW5nZSh4IC0gdG9sZXJhbmNlLCB5IC0gdG9sZXJhbmNlLCB4ICsgdG9sZXJhbmNlLCB5ICsgdG9sZXJhbmNlKTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgaWQgb2YgbWF0Y2hlZElkcykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNyb3NzVGlsZUlEID0gdGhpcy5jcm9zc1RpbGVJRHNbaWRdO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmtleXNbaWRdID09PSBrZXkgJiYgIXpvb21Dcm9zc1RpbGVJRHMuaGFzKGNyb3NzVGlsZUlEKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBPbmNlIHdlJ3ZlIG1hcmtlZCBvdXJzZWx2ZXMgZHVwbGljYXRlIGFnYWluc3QgdGhpcyBwYXJlbnQgc3ltYm9sLFxuICAgICAgICAgICAgICAgICAgICAvLyBkb24ndCBsZXQgYW55IG90aGVyIHN5bWJvbHMgYXQgdGhlIHNhbWUgem9vbSBsZXZlbCBkdXBsaWNhdGUgYWdhaW5zdFxuICAgICAgICAgICAgICAgICAgICAvLyB0aGUgc2FtZSBwYXJlbnQgKHNlZSBpc3N1ZSAjNTk5MylcbiAgICAgICAgICAgICAgICAgICAgem9vbUNyb3NzVGlsZUlEcy5hZGQoY3Jvc3NUaWxlSUQpO1xuICAgICAgICAgICAgICAgICAgICBzeW1ib2xJbnN0YW5jZS5jcm9zc1RpbGVJRCA9IGNyb3NzVGlsZUlEO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIENyb3NzVGlsZUlEcyB7XG4gICAgbWF4Q3Jvc3NUaWxlSUQ6IG51bWJlcjtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5tYXhDcm9zc1RpbGVJRCA9IDA7XG4gICAgfVxuICAgIGdlbmVyYXRlKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiArK3RoaXMubWF4Q3Jvc3NUaWxlSUQ7XG4gICAgfVxufVxuXG5jbGFzcyBDcm9zc1RpbGVTeW1ib2xMYXllckluZGV4IHtcbiAgICBpbmRleGVzOiB7W3pvb206IHN0cmluZyB8IG51bWJlcl06IHtbdGlsZUlkOiBzdHJpbmcgfCBudW1iZXJdOiBUaWxlTGF5ZXJJbmRleH19O1xuICAgIHVzZWRDcm9zc1RpbGVJRHM6IHtbem9vbTogc3RyaW5nIHwgbnVtYmVyXTogU2V0PG51bWJlcj59O1xuICAgIGxuZzogbnVtYmVyO1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuaW5kZXhlcyA9IHt9O1xuICAgICAgICB0aGlzLnVzZWRDcm9zc1RpbGVJRHMgPSB7fTtcbiAgICAgICAgdGhpcy5sbmcgPSAwO1xuICAgIH1cblxuICAgIC8qXG4gICAgICogU29tZXRpbWVzIHdoZW4gYSB1c2VyIHBhbnMgYWNyb3NzIHRoZSBhbnRpbWVyaWRpYW4gdGhlIGxvbmdpdHVkZSB2YWx1ZSBnZXRzIHdyYXBwZWQuXG4gICAgICogVG8gcHJldmVudCBsYWJlbHMgZnJvbSBmbGFzaGluZyBvdXQgYW5kIGluIHdlIGFkanVzdCB0aGUgdGlsZUlEIHZhbHVlcyBpbiB0aGUgaW5kZXhlc1xuICAgICAqIHNvIHRoYXQgdGhleSBtYXRjaCB0aGUgbmV3IHdyYXBwZWQgdmVyc2lvbiBvZiB0aGUgbWFwLlxuICAgICAqL1xuICAgIGhhbmRsZVdyYXBKdW1wKGxuZzogbnVtYmVyKSB7XG4gICAgICAgIGNvbnN0IHdyYXBEZWx0YSA9IE1hdGgucm91bmQoKGxuZyAtIHRoaXMubG5nKSAvIDM2MCk7XG4gICAgICAgIGlmICh3cmFwRGVsdGEgIT09IDApIHtcbiAgICAgICAgICAgIGZvciAoY29uc3Qgem9vbSBpbiB0aGlzLmluZGV4ZXMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB6b29tSW5kZXhlcyA9IHRoaXMuaW5kZXhlc1t6b29tXTtcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdab29tSW5kZXggPSB7fTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiB6b29tSW5kZXhlcykge1xuICAgICAgICAgICAgICAgICAgICAvLyBjaGFuZ2UgdGhlIHRpbGVJRCdzIHdyYXAgYW5kIGFkZCBpdCB0byBhIG5ldyBpbmRleFxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IHpvb21JbmRleGVzW2tleV07XG4gICAgICAgICAgICAgICAgICAgIGluZGV4LnRpbGVJRCA9IGluZGV4LnRpbGVJRC51bndyYXBUbyhpbmRleC50aWxlSUQud3JhcCArIHdyYXBEZWx0YSk7XG4gICAgICAgICAgICAgICAgICAgIG5ld1pvb21JbmRleFtpbmRleC50aWxlSUQua2V5XSA9IGluZGV4O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLmluZGV4ZXNbem9vbV0gPSBuZXdab29tSW5kZXg7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5sbmcgPSBsbmc7XG4gICAgfVxuXG4gICAgYWRkQnVja2V0KHRpbGVJRDogT3ZlcnNjYWxlZFRpbGVJRCwgYnVja2V0OiBTeW1ib2xCdWNrZXQsIGNyb3NzVGlsZUlEczogQ3Jvc3NUaWxlSURzKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICh0aGlzLmluZGV4ZXNbdGlsZUlELm92ZXJzY2FsZWRaXSAmJlxuICAgICAgICAgICAgdGhpcy5pbmRleGVzW3RpbGVJRC5vdmVyc2NhbGVkWl1bdGlsZUlELmtleV0pIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmluZGV4ZXNbdGlsZUlELm92ZXJzY2FsZWRaXVt0aWxlSUQua2V5XS5idWNrZXRJbnN0YW5jZUlkID09PVxuICAgICAgICAgICAgICAgIGJ1Y2tldC5idWNrZXRJbnN0YW5jZUlkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBXZSdyZSByZXBsYWNpbmcgdGhpcyBidWNrZXQgd2l0aCBhbiB1cGRhdGVkIHZlcnNpb25cbiAgICAgICAgICAgICAgICAvLyBSZW1vdmUgdGhlIG9sZCBidWNrZXQncyBcInVzZWQgY3Jvc3NUaWxlSURzXCIgbm93IHNvIHRoYXRcbiAgICAgICAgICAgICAgICAvLyB0aGUgbmV3IGJ1Y2tldCBjYW4gY2xhaW0gdGhlbS5cbiAgICAgICAgICAgICAgICAvLyBUaGUgb2xkIGluZGV4IGVudHJpZXMgdGhlbXNlbHZlcyBzdGljayBhcm91bmQgdW50aWxcbiAgICAgICAgICAgICAgICAvLyAncmVtb3ZlU3RhbGVCdWNrZXRzJyBpcyBjYWxsZWQuXG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVCdWNrZXRDcm9zc1RpbGVJRHModGlsZUlELm92ZXJzY2FsZWRaLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmluZGV4ZXNbdGlsZUlELm92ZXJzY2FsZWRaXVt0aWxlSUQua2V5XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1Y2tldC5zeW1ib2xJbnN0YW5jZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHN5bWJvbEluc3RhbmNlID0gYnVja2V0LnN5bWJvbEluc3RhbmNlcy5nZXQoaSk7XG4gICAgICAgICAgICBzeW1ib2xJbnN0YW5jZS5jcm9zc1RpbGVJRCA9IDA7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMudXNlZENyb3NzVGlsZUlEc1t0aWxlSUQub3ZlcnNjYWxlZFpdKSB7XG4gICAgICAgICAgICB0aGlzLnVzZWRDcm9zc1RpbGVJRHNbdGlsZUlELm92ZXJzY2FsZWRaXSA9IG5ldyBTZXQoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB6b29tQ3Jvc3NUaWxlSURzID0gdGhpcy51c2VkQ3Jvc3NUaWxlSURzW3RpbGVJRC5vdmVyc2NhbGVkWl07XG5cbiAgICAgICAgZm9yIChjb25zdCB6b29tIGluIHRoaXMuaW5kZXhlcykge1xuICAgICAgICAgICAgY29uc3Qgem9vbUluZGV4ZXMgPSB0aGlzLmluZGV4ZXNbem9vbV07XG4gICAgICAgICAgICBpZiAoTnVtYmVyKHpvb20pID4gdGlsZUlELm92ZXJzY2FsZWRaKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBpZCBpbiB6b29tSW5kZXhlcykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGlsZEluZGV4ID0gem9vbUluZGV4ZXNbaWRdO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGRJbmRleC50aWxlSUQuaXNDaGlsZE9mKHRpbGVJRCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkSW5kZXguZmluZE1hdGNoZXMoYnVja2V0LnN5bWJvbEluc3RhbmNlcywgdGlsZUlELCB6b29tQ3Jvc3NUaWxlSURzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFyZW50Q29vcmQgPSB0aWxlSUQuc2NhbGVkVG8oTnVtYmVyKHpvb20pKTtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJlbnRJbmRleCA9IHpvb21JbmRleGVzW3BhcmVudENvb3JkLmtleV07XG4gICAgICAgICAgICAgICAgaWYgKHBhcmVudEluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgIHBhcmVudEluZGV4LmZpbmRNYXRjaGVzKGJ1Y2tldC5zeW1ib2xJbnN0YW5jZXMsIHRpbGVJRCwgem9vbUNyb3NzVGlsZUlEcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBidWNrZXQuc3ltYm9sSW5zdGFuY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBzeW1ib2xJbnN0YW5jZSA9IGJ1Y2tldC5zeW1ib2xJbnN0YW5jZXMuZ2V0KGkpO1xuICAgICAgICAgICAgaWYgKCFzeW1ib2xJbnN0YW5jZS5jcm9zc1RpbGVJRCkge1xuICAgICAgICAgICAgICAgIC8vIHN5bWJvbCBkaWQgbm90IG1hdGNoIGFueSBrbm93biBzeW1ib2wsIGFzc2lnbiBhIG5ldyBpZFxuICAgICAgICAgICAgICAgIHN5bWJvbEluc3RhbmNlLmNyb3NzVGlsZUlEID0gY3Jvc3NUaWxlSURzLmdlbmVyYXRlKCk7XG4gICAgICAgICAgICAgICAgem9vbUNyb3NzVGlsZUlEcy5hZGQoc3ltYm9sSW5zdGFuY2UuY3Jvc3NUaWxlSUQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuaW5kZXhlc1t0aWxlSUQub3ZlcnNjYWxlZFpdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuaW5kZXhlc1t0aWxlSUQub3ZlcnNjYWxlZFpdID0ge307XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pbmRleGVzW3RpbGVJRC5vdmVyc2NhbGVkWl1bdGlsZUlELmtleV0gPSBuZXcgVGlsZUxheWVySW5kZXgodGlsZUlELCBidWNrZXQuc3ltYm9sSW5zdGFuY2VzLCBidWNrZXQuYnVja2V0SW5zdGFuY2VJZCk7XG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcmVtb3ZlQnVja2V0Q3Jvc3NUaWxlSURzKHpvb206IHN0cmluZyB8IG51bWJlciwgcmVtb3ZlZEJ1Y2tldDogVGlsZUxheWVySW5kZXgpIHtcbiAgICAgICAgZm9yIChjb25zdCBjcm9zc1RpbGVJRCBvZiByZW1vdmVkQnVja2V0LmNyb3NzVGlsZUlEcykge1xuICAgICAgICAgICAgdGhpcy51c2VkQ3Jvc3NUaWxlSURzW3pvb21dLmRlbGV0ZShjcm9zc1RpbGVJRCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZW1vdmVTdGFsZUJ1Y2tldHMoY3VycmVudElEczogeyBbc3RyaW5nIHwgbnVtYmVyXTogYm9vbGVhbiB9KTogYm9vbGVhbiB7XG4gICAgICAgIGxldCB0aWxlc0NoYW5nZWQgPSBmYWxzZTtcbiAgICAgICAgZm9yIChjb25zdCB6IGluIHRoaXMuaW5kZXhlcykge1xuICAgICAgICAgICAgY29uc3Qgem9vbUluZGV4ZXMgPSB0aGlzLmluZGV4ZXNbel07XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHRpbGVLZXkgaW4gem9vbUluZGV4ZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWN1cnJlbnRJRHNbem9vbUluZGV4ZXNbdGlsZUtleV0uYnVja2V0SW5zdGFuY2VJZF0pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVCdWNrZXRDcm9zc1RpbGVJRHMoeiwgem9vbUluZGV4ZXNbdGlsZUtleV0pO1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgem9vbUluZGV4ZXNbdGlsZUtleV07XG4gICAgICAgICAgICAgICAgICAgIHRpbGVzQ2hhbmdlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aWxlc0NoYW5nZWQ7XG4gICAgfVxufVxuXG5jbGFzcyBDcm9zc1RpbGVTeW1ib2xJbmRleCB7XG4gICAgbGF5ZXJJbmRleGVzOiB7W2xheWVySWQ6IHN0cmluZ106IENyb3NzVGlsZVN5bWJvbExheWVySW5kZXh9O1xuICAgIGNyb3NzVGlsZUlEczogQ3Jvc3NUaWxlSURzO1xuICAgIG1heEJ1Y2tldEluc3RhbmNlSWQ6IG51bWJlcjtcbiAgICBidWNrZXRzSW5DdXJyZW50UGxhY2VtZW50OiB7W186IG51bWJlcl06IGJvb2xlYW59O1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMubGF5ZXJJbmRleGVzID0ge307XG4gICAgICAgIHRoaXMuY3Jvc3NUaWxlSURzID0gbmV3IENyb3NzVGlsZUlEcygpO1xuICAgICAgICB0aGlzLm1heEJ1Y2tldEluc3RhbmNlSWQgPSAwO1xuICAgICAgICB0aGlzLmJ1Y2tldHNJbkN1cnJlbnRQbGFjZW1lbnQgPSB7fTtcbiAgICB9XG5cbiAgICBhZGRMYXllcihzdHlsZUxheWVyOiBTdHlsZUxheWVyLCB0aWxlczogQXJyYXk8VGlsZT4sIGxuZzogbnVtYmVyLCBwcm9qZWN0aW9uOiBQcm9qZWN0aW9uKTogYm9vbGVhbiB7XG4gICAgICAgIGxldCBsYXllckluZGV4ID0gdGhpcy5sYXllckluZGV4ZXNbc3R5bGVMYXllci5pZF07XG4gICAgICAgIGlmIChsYXllckluZGV4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGxheWVySW5kZXggPSB0aGlzLmxheWVySW5kZXhlc1tzdHlsZUxheWVyLmlkXSA9IG5ldyBDcm9zc1RpbGVTeW1ib2xMYXllckluZGV4KCk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgc3ltYm9sQnVja2V0c0NoYW5nZWQgPSBmYWxzZTtcbiAgICAgICAgY29uc3QgY3VycmVudEJ1Y2tldElEcyA9IHt9O1xuXG4gICAgICAgIGlmIChwcm9qZWN0aW9uLm5hbWUgIT09ICdnbG9iZScpIHtcbiAgICAgICAgICAgIGxheWVySW5kZXguaGFuZGxlV3JhcEp1bXAobG5nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoY29uc3QgdGlsZSBvZiB0aWxlcykge1xuICAgICAgICAgICAgY29uc3Qgc3ltYm9sQnVja2V0ID0gKCh0aWxlLmdldEJ1Y2tldChzdHlsZUxheWVyKTogYW55KTogU3ltYm9sQnVja2V0KTtcbiAgICAgICAgICAgIGlmICghc3ltYm9sQnVja2V0IHx8IHN0eWxlTGF5ZXIuaWQgIT09IHN5bWJvbEJ1Y2tldC5sYXllcklkc1swXSlcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcblxuICAgICAgICAgICAgaWYgKCFzeW1ib2xCdWNrZXQuYnVja2V0SW5zdGFuY2VJZCkge1xuICAgICAgICAgICAgICAgIHN5bWJvbEJ1Y2tldC5idWNrZXRJbnN0YW5jZUlkID0gKyt0aGlzLm1heEJ1Y2tldEluc3RhbmNlSWQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChsYXllckluZGV4LmFkZEJ1Y2tldCh0aWxlLnRpbGVJRCwgc3ltYm9sQnVja2V0LCB0aGlzLmNyb3NzVGlsZUlEcykpIHtcbiAgICAgICAgICAgICAgICBzeW1ib2xCdWNrZXRzQ2hhbmdlZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjdXJyZW50QnVja2V0SURzW3N5bWJvbEJ1Y2tldC5idWNrZXRJbnN0YW5jZUlkXSA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobGF5ZXJJbmRleC5yZW1vdmVTdGFsZUJ1Y2tldHMoY3VycmVudEJ1Y2tldElEcykpIHtcbiAgICAgICAgICAgIHN5bWJvbEJ1Y2tldHNDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBzeW1ib2xCdWNrZXRzQ2hhbmdlZDtcbiAgICB9XG5cbiAgICBwcnVuZVVudXNlZExheWVycyh1c2VkTGF5ZXJzOiBBcnJheTxzdHJpbmc+KSB7XG4gICAgICAgIGNvbnN0IHVzZWRMYXllck1hcCA9IHt9O1xuICAgICAgICB1c2VkTGF5ZXJzLmZvckVhY2goKHVzZWRMYXllcikgPT4ge1xuICAgICAgICAgICAgdXNlZExheWVyTWFwW3VzZWRMYXllcl0gPSB0cnVlO1xuICAgICAgICB9KTtcbiAgICAgICAgZm9yIChjb25zdCBsYXllcklkIGluIHRoaXMubGF5ZXJJbmRleGVzKSB7XG4gICAgICAgICAgICBpZiAoIXVzZWRMYXllck1hcFtsYXllcklkXSkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmxheWVySW5kZXhlc1tsYXllcklkXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ3Jvc3NUaWxlU3ltYm9sSW5kZXg7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbmltcG9ydCB7RXZlbnQsIEVycm9yRXZlbnQsIEV2ZW50ZWR9IGZyb20gJy4uL3V0aWwvZXZlbnRlZC5qcyc7XG5pbXBvcnQgU3R5bGVMYXllciBmcm9tICcuL3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCBjcmVhdGVTdHlsZUxheWVyIGZyb20gJy4vY3JlYXRlX3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCBsb2FkU3ByaXRlIGZyb20gJy4vbG9hZF9zcHJpdGUuanMnO1xuaW1wb3J0IEltYWdlTWFuYWdlciBmcm9tICcuLi9yZW5kZXIvaW1hZ2VfbWFuYWdlci5qcyc7XG5pbXBvcnQgR2x5cGhNYW5hZ2VyLCB7TG9jYWxHbHlwaE1vZGV9IGZyb20gJy4uL3JlbmRlci9nbHlwaF9tYW5hZ2VyLmpzJztcbmltcG9ydCBMaWdodCBmcm9tICcuL2xpZ2h0LmpzJztcbmltcG9ydCBUZXJyYWluLCB7RHJhcGVSZW5kZXJNb2RlfSBmcm9tICcuL3RlcnJhaW4uanMnO1xuaW1wb3J0IEZvZyBmcm9tICcuL2ZvZy5qcyc7XG5pbXBvcnQge3BpY2ssIGNsb25lLCBleHRlbmQsIGRlZXBFcXVhbCwgZmlsdGVyT2JqZWN0fSBmcm9tICcuLi91dGlsL3V0aWwuanMnO1xuaW1wb3J0IHtnZXRKU09OLCBnZXRSZWZlcnJlciwgbWFrZVJlcXVlc3QsIFJlc291cmNlVHlwZX0gZnJvbSAnLi4vdXRpbC9hamF4LmpzJztcbmltcG9ydCB7aXNNYXBib3hVUkx9IGZyb20gJy4uL3V0aWwvbWFwYm94LmpzJztcbmltcG9ydCBicm93c2VyIGZyb20gJy4uL3V0aWwvYnJvd3Nlci5qcyc7XG5pbXBvcnQgRGlzcGF0Y2hlciBmcm9tICcuLi91dGlsL2Rpc3BhdGNoZXIuanMnO1xuaW1wb3J0IHtcbiAgICB2YWxpZGF0ZVN0eWxlLFxuICAgIHZhbGlkYXRlU291cmNlLFxuICAgIHZhbGlkYXRlTGF5ZXIsXG4gICAgdmFsaWRhdGVGaWx0ZXIsXG4gICAgdmFsaWRhdGVUZXJyYWluLFxuICAgIGVtaXRWYWxpZGF0aW9uRXJyb3JzIGFzIF9lbWl0VmFsaWRhdGlvbkVycm9yc1xufSBmcm9tICcuL3ZhbGlkYXRlX3N0eWxlLmpzJztcbmltcG9ydCB7UXVlcnlHZW9tZXRyeX0gZnJvbSAnLi4vc3R5bGUvcXVlcnlfZ2VvbWV0cnkuanMnO1xuaW1wb3J0IHtcbiAgICBjcmVhdGUgYXMgY3JlYXRlU291cmNlLFxuICAgIGdldFR5cGUgYXMgZ2V0U291cmNlVHlwZSxcbiAgICBzZXRUeXBlIGFzIHNldFNvdXJjZVR5cGUsXG4gICAgdHlwZSBTb3VyY2VDbGFzc1xufSBmcm9tICcuLi9zb3VyY2Uvc291cmNlLmpzJztcbmltcG9ydCB7cXVlcnlSZW5kZXJlZEZlYXR1cmVzLCBxdWVyeVJlbmRlcmVkU3ltYm9scywgcXVlcnlTb3VyY2VGZWF0dXJlc30gZnJvbSAnLi4vc291cmNlL3F1ZXJ5X2ZlYXR1cmVzLmpzJztcbmltcG9ydCBTb3VyY2VDYWNoZSBmcm9tICcuLi9zb3VyY2Uvc291cmNlX2NhY2hlLmpzJztcbmltcG9ydCBHZW9KU09OU291cmNlIGZyb20gJy4uL3NvdXJjZS9nZW9qc29uX3NvdXJjZS5qcyc7XG5pbXBvcnQgc3R5bGVTcGVjIGZyb20gJy4uL3N0eWxlLXNwZWMvcmVmZXJlbmNlL2xhdGVzdC5qcyc7XG5pbXBvcnQgZ2V0V29ya2VyUG9vbCBmcm9tICcuLi91dGlsL2dsb2JhbF93b3JrZXJfcG9vbC5qcyc7XG5pbXBvcnQgZGVyZWYgZnJvbSAnLi4vc3R5bGUtc3BlYy9kZXJlZi5qcyc7XG5pbXBvcnQgZW1wdHlTdHlsZSBmcm9tICcuLi9zdHlsZS1zcGVjL2VtcHR5LmpzJztcbmltcG9ydCBkaWZmU3R5bGVzLCB7b3BlcmF0aW9ucyBhcyBkaWZmT3BlcmF0aW9uc30gZnJvbSAnLi4vc3R5bGUtc3BlYy9kaWZmLmpzJztcbmltcG9ydCB7XG4gICAgcmVnaXN0ZXJGb3JQbHVnaW5TdGF0ZUNoYW5nZSxcbiAgICBldmVudGVkIGFzIHJ0bFRleHRQbHVnaW5FdmVudGVkLFxuICAgIHRyaWdnZXJQbHVnaW5Db21wbGV0aW9uRXZlbnRcbn0gZnJvbSAnLi4vc291cmNlL3J0bF90ZXh0X3BsdWdpbi5qcyc7XG5pbXBvcnQgUGF1c2VhYmxlUGxhY2VtZW50IGZyb20gJy4vcGF1c2VhYmxlX3BsYWNlbWVudC5qcyc7XG5pbXBvcnQgQ3Jvc3NUaWxlU3ltYm9sSW5kZXggZnJvbSAnLi4vc3ltYm9sL2Nyb3NzX3RpbGVfc3ltYm9sX2luZGV4LmpzJztcbmltcG9ydCB7dmFsaWRhdGVDdXN0b21TdHlsZUxheWVyfSBmcm9tICcuL3N0eWxlX2xheWVyL2N1c3RvbV9zdHlsZV9sYXllci5qcyc7XG5cbi8vIFdlJ3JlIHNraXBwaW5nIHZhbGlkYXRpb24gZXJyb3JzIHdpdGggdGhlIGBzb3VyY2UuY2FudmFzYCBpZGVudGlmaWVyIGluIG9yZGVyXG4vLyB0byBjb250aW51ZSB0byBhbGxvdyBjYW52YXMgc291cmNlcyB0byBiZSBhZGRlZCBhdCBydW50aW1lL3VwZGF0ZWQgaW5cbi8vIHNtYXJ0IHNldFN0eWxlIChzZWUgaHR0cHM6Ly9naXRodWIuY29tL21hcGJveC9tYXBib3gtZ2wtanMvcHVsbC82NDI0KTpcbmNvbnN0IGVtaXRWYWxpZGF0aW9uRXJyb3JzID0gKGV2ZW50ZWQ6IEV2ZW50ZWQsIGVycm9yczogP1ZhbGlkYXRpb25FcnJvcnMpID0+XG4gICAgX2VtaXRWYWxpZGF0aW9uRXJyb3JzKGV2ZW50ZWQsIGVycm9ycyAmJiBlcnJvcnMuZmlsdGVyKGVycm9yID0+IGVycm9yLmlkZW50aWZpZXIgIT09ICdzb3VyY2UuY2FudmFzJykpO1xuXG5pbXBvcnQgdHlwZSBNYXAgZnJvbSAnLi4vdWkvbWFwLmpzJztcbmltcG9ydCB0eXBlIFRyYW5zZm9ybSBmcm9tICcuLi9nZW8vdHJhbnNmb3JtLmpzJztcbmltcG9ydCB0eXBlIHtTdHlsZUltYWdlfSBmcm9tICcuL3N0eWxlX2ltYWdlLmpzJztcbmltcG9ydCB0eXBlIHtTdHlsZUdseXBofSBmcm9tICcuL3N0eWxlX2dseXBoLmpzJztcbmltcG9ydCB0eXBlIHtDYWxsYmFja30gZnJvbSAnLi4vdHlwZXMvY2FsbGJhY2suanMnO1xuaW1wb3J0IHR5cGUgRXZhbHVhdGlvblBhcmFtZXRlcnMgZnJvbSAnLi9ldmFsdWF0aW9uX3BhcmFtZXRlcnMuanMnO1xuaW1wb3J0IHR5cGUge1BsYWNlbWVudH0gZnJvbSAnLi4vc3ltYm9sL3BsYWNlbWVudC5qcyc7XG5pbXBvcnQgdHlwZSB7Q2FuY2VsYWJsZX0gZnJvbSAnLi4vdHlwZXMvY2FuY2VsYWJsZS5qcyc7XG5pbXBvcnQgdHlwZSB7UmVxdWVzdFBhcmFtZXRlcnMsIFJlc3BvbnNlQ2FsbGJhY2t9IGZyb20gJy4uL3V0aWwvYWpheC5qcyc7XG5pbXBvcnQgdHlwZSB7R2VvSlNPTn0gZnJvbSAnQG1hcGJveC9nZW9qc29uLXR5cGVzJztcbmltcG9ydCB0eXBlIHtcbiAgICBMYXllclNwZWNpZmljYXRpb24sXG4gICAgRmlsdGVyU3BlY2lmaWNhdGlvbixcbiAgICBTdHlsZVNwZWNpZmljYXRpb24sXG4gICAgTGlnaHRTcGVjaWZpY2F0aW9uLFxuICAgIFNvdXJjZVNwZWNpZmljYXRpb24sXG4gICAgVGVycmFpblNwZWNpZmljYXRpb24sXG4gICAgRm9nU3BlY2lmaWNhdGlvbixcbiAgICBQcm9qZWN0aW9uU3BlY2lmaWNhdGlvbixcbiAgICBUcmFuc2l0aW9uU3BlY2lmaWNhdGlvbixcbiAgICBQcm9wZXJ0eVZhbHVlU3BlY2lmaWNhdGlvblxufSBmcm9tICcuLi9zdHlsZS1zcGVjL3R5cGVzLmpzJztcbmltcG9ydCB0eXBlIHtDdXN0b21MYXllckludGVyZmFjZX0gZnJvbSAnLi9zdHlsZV9sYXllci9jdXN0b21fc3R5bGVfbGF5ZXIuanMnO1xuaW1wb3J0IHR5cGUge1ZhbGlkYXRvciwgVmFsaWRhdGlvbkVycm9yc30gZnJvbSAnLi92YWxpZGF0ZV9zdHlsZS5qcyc7XG5pbXBvcnQgdHlwZSB7T3ZlcnNjYWxlZFRpbGVJRH0gZnJvbSAnLi4vc291cmNlL3RpbGVfaWQuanMnO1xuaW1wb3J0IHR5cGUge1F1ZXJ5UmVzdWx0fSBmcm9tICcuLi9kYXRhL2ZlYXR1cmVfaW5kZXguanMnO1xuaW1wb3J0IHR5cGUge1F1ZXJ5RmVhdHVyZX0gZnJvbSAnLi4vdXRpbC92ZWN0b3J0aWxlX3RvX2dlb2pzb24uanMnO1xuaW1wb3J0IHR5cGUge0ZlYXR1cmVTdGF0ZXN9IGZyb20gJy4uL3NvdXJjZS9zb3VyY2Vfc3RhdGUuanMnO1xuaW1wb3J0IHR5cGUge1BvaW50TGlrZX0gZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5pbXBvcnQgdHlwZSB7U291cmNlfSBmcm9tICcuLi9zb3VyY2Uvc291cmNlLmpzJztcbmltcG9ydCB0eXBlIHtUcmFuc2l0aW9uUGFyYW1ldGVyc30gZnJvbSAnLi9wcm9wZXJ0aWVzLmpzJztcblxuY29uc3Qgc3VwcG9ydGVkRGlmZk9wZXJhdGlvbnMgPSBwaWNrKGRpZmZPcGVyYXRpb25zLCBbXG4gICAgJ2FkZExheWVyJyxcbiAgICAncmVtb3ZlTGF5ZXInLFxuICAgICdzZXRQYWludFByb3BlcnR5JyxcbiAgICAnc2V0TGF5b3V0UHJvcGVydHknLFxuICAgICdzZXRGaWx0ZXInLFxuICAgICdhZGRTb3VyY2UnLFxuICAgICdyZW1vdmVTb3VyY2UnLFxuICAgICdzZXRMYXllclpvb21SYW5nZScsXG4gICAgJ3NldExpZ2h0JyxcbiAgICAnc2V0VHJhbnNpdGlvbicsXG4gICAgJ3NldEdlb0pTT05Tb3VyY2VEYXRhJyxcbiAgICAnc2V0VGVycmFpbicsXG4gICAgJ3NldEZvZycsXG4gICAgJ3NldFByb2plY3Rpb24nXG4gICAgLy8gJ3NldEdseXBocycsXG4gICAgLy8gJ3NldFNwcml0ZScsXG5dKTtcblxuY29uc3QgaWdub3JlZERpZmZPcGVyYXRpb25zID0gcGljayhkaWZmT3BlcmF0aW9ucywgW1xuICAgICdzZXRDZW50ZXInLFxuICAgICdzZXRab29tJyxcbiAgICAnc2V0QmVhcmluZycsXG4gICAgJ3NldFBpdGNoJ1xuXSk7XG5cbmNvbnN0IGVtcHR5ID0gZW1wdHlTdHlsZSgpO1xuXG5leHBvcnQgdHlwZSBTdHlsZU9wdGlvbnMgPSB7XG4gICAgdmFsaWRhdGU/OiBib29sZWFuLFxuICAgIGxvY2FsRm9udEZhbWlseT86IHN0cmluZyxcbiAgICBsb2NhbElkZW9ncmFwaEZvbnRGYW1pbHk/OiBzdHJpbmdcbn07XG5cbmV4cG9ydCB0eXBlIFN0eWxlU2V0dGVyT3B0aW9ucyA9IHtcbiAgICB2YWxpZGF0ZT86IGJvb2xlYW5cbn07XG5cbi8vIFN5bWJvbHMgYXJlIGRyYXBlZCBvbmx5IGZvciBzcGVjaWZpYyBjYXNlczogc2VlIGlzTGF5ZXJEcmFwZWRcbmNvbnN0IGRyYXBlZExheWVycyA9IHsnZmlsbCc6IHRydWUsICdsaW5lJzogdHJ1ZSwgJ2JhY2tncm91bmQnOiB0cnVlLCBcImhpbGxzaGFkZVwiOiB0cnVlLCBcInJhc3RlclwiOiB0cnVlfTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5jbGFzcyBTdHlsZSBleHRlbmRzIEV2ZW50ZWQge1xuICAgIG1hcDogTWFwO1xuICAgIHN0eWxlc2hlZXQ6IFN0eWxlU3BlY2lmaWNhdGlvbjtcbiAgICBkaXNwYXRjaGVyOiBEaXNwYXRjaGVyO1xuICAgIGltYWdlTWFuYWdlcjogSW1hZ2VNYW5hZ2VyO1xuICAgIGdseXBoTWFuYWdlcjogR2x5cGhNYW5hZ2VyO1xuICAgIGxpZ2h0OiBMaWdodDtcbiAgICB0ZXJyYWluOiA/VGVycmFpbjtcbiAgICBmb2c6ID9Gb2c7XG5cbiAgICBfcmVxdWVzdDogP0NhbmNlbGFibGU7XG4gICAgX3Nwcml0ZVJlcXVlc3Q6ID9DYW5jZWxhYmxlO1xuICAgIF9sYXllcnM6IHtbXzogc3RyaW5nXTogU3R5bGVMYXllcn07XG4gICAgX251bTNETGF5ZXJzOiBudW1iZXI7XG4gICAgX251bVN5bWJvbExheWVyczogbnVtYmVyO1xuICAgIF9udW1DaXJjbGVMYXllcnM6IG51bWJlcjtcbiAgICBfc2VyaWFsaXplZExheWVyczoge1tfOiBzdHJpbmddOiBPYmplY3R9O1xuICAgIF9vcmRlcjogQXJyYXk8c3RyaW5nPjtcbiAgICBfZHJhcGVkRmlyc3RPcmRlcjogQXJyYXk8c3RyaW5nPjtcbiAgICBfc291cmNlQ2FjaGVzOiB7W186IHN0cmluZ106IFNvdXJjZUNhY2hlfTtcbiAgICBfb3RoZXJTb3VyY2VDYWNoZXM6IHtbXzogc3RyaW5nXTogU291cmNlQ2FjaGV9O1xuICAgIF9zeW1ib2xTb3VyY2VDYWNoZXM6IHtbXzogc3RyaW5nXTogU291cmNlQ2FjaGV9O1xuICAgIF9sb2FkZWQ6IGJvb2xlYW47XG4gICAgX3J0bFRleHRQbHVnaW5DYWxsYmFjazogRnVuY3Rpb247XG4gICAgX2NoYW5nZWQ6IGJvb2xlYW47XG4gICAgX3VwZGF0ZWRTb3VyY2VzOiB7W186IHN0cmluZ106ICdjbGVhcicgfCAncmVsb2FkJ307XG4gICAgX3VwZGF0ZWRMYXllcnM6IHtbXzogc3RyaW5nXTogdHJ1ZX07XG4gICAgX3JlbW92ZWRMYXllcnM6IHtbXzogc3RyaW5nXTogU3R5bGVMYXllcn07XG4gICAgX2NoYW5nZWRJbWFnZXM6IHtbXzogc3RyaW5nXTogdHJ1ZX07XG4gICAgX3VwZGF0ZWRQYWludFByb3BzOiB7W2xheWVyOiBzdHJpbmddOiB0cnVlfTtcbiAgICBfbGF5ZXJPcmRlckNoYW5nZWQ6IGJvb2xlYW47XG4gICAgX2F2YWlsYWJsZUltYWdlczogQXJyYXk8c3RyaW5nPjtcbiAgICBfbWFya2Vyc05lZWRVcGRhdGU6IGJvb2xlYW47XG5cbiAgICBjcm9zc1RpbGVTeW1ib2xJbmRleDogQ3Jvc3NUaWxlU3ltYm9sSW5kZXg7XG4gICAgcGF1c2VhYmxlUGxhY2VtZW50OiBQYXVzZWFibGVQbGFjZW1lbnQ7XG4gICAgcGxhY2VtZW50OiBQbGFjZW1lbnQ7XG4gICAgejogbnVtYmVyO1xuXG4gICAgLy8gZXhwb3NlZCB0byBhbGxvdyBzdHViYmluZyBieSB1bml0IHRlc3RzXG4gICAgc3RhdGljIGdldFNvdXJjZVR5cGU6IHR5cGVvZiBnZXRTb3VyY2VUeXBlO1xuICAgIHN0YXRpYyBzZXRTb3VyY2VUeXBlOiB0eXBlb2Ygc2V0U291cmNlVHlwZTtcbiAgICBzdGF0aWMgcmVnaXN0ZXJGb3JQbHVnaW5TdGF0ZUNoYW5nZTogdHlwZW9mIHJlZ2lzdGVyRm9yUGx1Z2luU3RhdGVDaGFuZ2U7XG5cbiAgICBjb25zdHJ1Y3RvcihtYXA6IE1hcCwgb3B0aW9uczogU3R5bGVPcHRpb25zID0ge30pIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICB0aGlzLm1hcCA9IG1hcDtcbiAgICAgICAgdGhpcy5kaXNwYXRjaGVyID0gbmV3IERpc3BhdGNoZXIoZ2V0V29ya2VyUG9vbCgpLCB0aGlzKTtcbiAgICAgICAgdGhpcy5pbWFnZU1hbmFnZXIgPSBuZXcgSW1hZ2VNYW5hZ2VyKCk7XG4gICAgICAgIHRoaXMuaW1hZ2VNYW5hZ2VyLnNldEV2ZW50ZWRQYXJlbnQodGhpcyk7XG4gICAgICAgIHRoaXMuZ2x5cGhNYW5hZ2VyID0gbmV3IEdseXBoTWFuYWdlcihtYXAuX3JlcXVlc3RNYW5hZ2VyLFxuICAgICAgICAgICAgb3B0aW9ucy5sb2NhbEZvbnRGYW1pbHkgP1xuICAgICAgICAgICAgICAgIExvY2FsR2x5cGhNb2RlLmFsbCA6XG4gICAgICAgICAgICAgICAgKG9wdGlvbnMubG9jYWxJZGVvZ3JhcGhGb250RmFtaWx5ID8gTG9jYWxHbHlwaE1vZGUuaWRlb2dyYXBocyA6IExvY2FsR2x5cGhNb2RlLm5vbmUpLFxuICAgICAgICAgICAgb3B0aW9ucy5sb2NhbEZvbnRGYW1pbHkgfHwgb3B0aW9ucy5sb2NhbElkZW9ncmFwaEZvbnRGYW1pbHkpO1xuICAgICAgICB0aGlzLmNyb3NzVGlsZVN5bWJvbEluZGV4ID0gbmV3IENyb3NzVGlsZVN5bWJvbEluZGV4KCk7XG5cbiAgICAgICAgdGhpcy5fbGF5ZXJzID0ge307XG4gICAgICAgIHRoaXMuX251bTNETGF5ZXJzID0gMDtcbiAgICAgICAgdGhpcy5fbnVtU3ltYm9sTGF5ZXJzID0gMDtcbiAgICAgICAgdGhpcy5fbnVtQ2lyY2xlTGF5ZXJzID0gMDtcbiAgICAgICAgdGhpcy5fc2VyaWFsaXplZExheWVycyA9IHt9O1xuICAgICAgICB0aGlzLl9zb3VyY2VDYWNoZXMgPSB7fTtcbiAgICAgICAgdGhpcy5fb3RoZXJTb3VyY2VDYWNoZXMgPSB7fTtcbiAgICAgICAgdGhpcy5fc3ltYm9sU291cmNlQ2FjaGVzID0ge307XG4gICAgICAgIHRoaXMuX2xvYWRlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9hdmFpbGFibGVJbWFnZXMgPSBbXTtcbiAgICAgICAgdGhpcy5fb3JkZXIgID0gW107XG4gICAgICAgIHRoaXMuX2RyYXBlZEZpcnN0T3JkZXIgPSBbXTtcbiAgICAgICAgdGhpcy5fbWFya2Vyc05lZWRVcGRhdGUgPSBmYWxzZTtcblxuICAgICAgICB0aGlzLl9yZXNldFVwZGF0ZXMoKTtcblxuICAgICAgICB0aGlzLmRpc3BhdGNoZXIuYnJvYWRjYXN0KCdzZXRSZWZlcnJlcicsIGdldFJlZmVycmVyKCkpO1xuXG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgICAgICB0aGlzLl9ydGxUZXh0UGx1Z2luQ2FsbGJhY2sgPSBTdHlsZS5yZWdpc3RlckZvclBsdWdpblN0YXRlQ2hhbmdlKChldmVudCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RhdGUgPSB7XG4gICAgICAgICAgICAgICAgcGx1Z2luU3RhdHVzOiBldmVudC5wbHVnaW5TdGF0dXMsXG4gICAgICAgICAgICAgICAgcGx1Z2luVVJMOiBldmVudC5wbHVnaW5VUkxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBzZWxmLmRpc3BhdGNoZXIuYnJvYWRjYXN0KCdzeW5jUlRMUGx1Z2luU3RhdGUnLCBzdGF0ZSwgKGVyciwgcmVzdWx0cykgPT4ge1xuICAgICAgICAgICAgICAgIHRyaWdnZXJQbHVnaW5Db21wbGV0aW9uRXZlbnQoZXJyKTtcbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0cykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhbGxDb21wbGV0ZSA9IHJlc3VsdHMuZXZlcnkoKGVsZW0pID0+IGVsZW0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYWxsQ29tcGxldGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgaWQgaW4gc2VsZi5fc291cmNlQ2FjaGVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc291cmNlQ2FjaGUgPSBzZWxmLl9zb3VyY2VDYWNoZXNbaWRdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZUNhY2hlVHlwZSA9IHNvdXJjZUNhY2hlLmdldFNvdXJjZSgpLnR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNvdXJjZUNhY2hlVHlwZSA9PT0gJ3ZlY3RvcicgfHwgc291cmNlQ2FjaGVUeXBlID09PSAnZ2VvanNvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlQ2FjaGUucmVsb2FkKCk7IC8vIFNob3VsZCBiZSBhIG5vLW9wIGlmIHRoZSBwbHVnaW4gbG9hZHMgYmVmb3JlIGFueSB0aWxlcyBsb2FkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5vbignZGF0YScsIChldmVudCkgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50LmRhdGFUeXBlICE9PSAnc291cmNlJyB8fCBldmVudC5zb3VyY2VEYXRhVHlwZSAhPT0gJ21ldGFkYXRhJykge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3Qgc291cmNlID0gdGhpcy5nZXRTb3VyY2UoZXZlbnQuc291cmNlSWQpO1xuICAgICAgICAgICAgaWYgKCFzb3VyY2UgfHwgIXNvdXJjZS52ZWN0b3JMYXllcklkcykge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9yIChjb25zdCBsYXllcklkIGluIHRoaXMuX2xheWVycykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGxheWVyID0gdGhpcy5fbGF5ZXJzW2xheWVySWRdO1xuICAgICAgICAgICAgICAgIGlmIChsYXllci5zb3VyY2UgPT09IHNvdXJjZS5pZCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl92YWxpZGF0ZUxheWVyKGxheWVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGxvYWRVUkwodXJsOiBzdHJpbmcsIG9wdGlvbnM6IHtcbiAgICAgICAgdmFsaWRhdGU/OiBib29sZWFuLFxuICAgICAgICBhY2Nlc3NUb2tlbj86IHN0cmluZ1xuICAgIH0gPSB7fSkge1xuICAgICAgICB0aGlzLmZpcmUobmV3IEV2ZW50KCdkYXRhbG9hZGluZycsIHtkYXRhVHlwZTogJ3N0eWxlJ30pKTtcblxuICAgICAgICBjb25zdCB2YWxpZGF0ZSA9IHR5cGVvZiBvcHRpb25zLnZhbGlkYXRlID09PSAnYm9vbGVhbicgP1xuICAgICAgICAgICAgb3B0aW9ucy52YWxpZGF0ZSA6ICFpc01hcGJveFVSTCh1cmwpO1xuXG4gICAgICAgIHVybCA9IHRoaXMubWFwLl9yZXF1ZXN0TWFuYWdlci5ub3JtYWxpemVTdHlsZVVSTCh1cmwsIG9wdGlvbnMuYWNjZXNzVG9rZW4pO1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gdGhpcy5tYXAuX3JlcXVlc3RNYW5hZ2VyLnRyYW5zZm9ybVJlcXVlc3QodXJsLCBSZXNvdXJjZVR5cGUuU3R5bGUpO1xuICAgICAgICB0aGlzLl9yZXF1ZXN0ID0gZ2V0SlNPTihyZXF1ZXN0LCAoZXJyb3I6ID9FcnJvciwganNvbjogP09iamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fcmVxdWVzdCA9IG51bGw7XG4gICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpcmUobmV3IEVycm9yRXZlbnQoZXJyb3IpKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoanNvbikge1xuICAgICAgICAgICAgICAgIHRoaXMuX2xvYWQoanNvbiwgdmFsaWRhdGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBsb2FkSlNPTihqc29uOiBTdHlsZVNwZWNpZmljYXRpb24sIG9wdGlvbnM6IFN0eWxlU2V0dGVyT3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ2RhdGFsb2FkaW5nJywge2RhdGFUeXBlOiAnc3R5bGUnfSkpO1xuXG4gICAgICAgIHRoaXMuX3JlcXVlc3QgPSBicm93c2VyLmZyYW1lKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX3JlcXVlc3QgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5fbG9hZChqc29uLCBvcHRpb25zLnZhbGlkYXRlICE9PSBmYWxzZSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGxvYWRFbXB0eSgpIHtcbiAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgnZGF0YWxvYWRpbmcnLCB7ZGF0YVR5cGU6ICdzdHlsZSd9KSk7XG4gICAgICAgIHRoaXMuX2xvYWQoZW1wdHksIGZhbHNlKTtcbiAgICB9XG5cbiAgICBfdXBkYXRlTGF5ZXJDb3VudChsYXllcjogU3R5bGVMYXllciwgYWRkOiBib29sZWFuKSB7XG4gICAgICAgIC8vIFR5cGVkIGxheWVyIGJvb2trZWVwaW5nXG4gICAgICAgIGNvbnN0IGNvdW50ID0gYWRkID8gMSA6IC0xO1xuICAgICAgICBpZiAobGF5ZXIuaXMzRCgpKSB7XG4gICAgICAgICAgICB0aGlzLl9udW0zRExheWVycyArPSBjb3VudDtcbiAgICAgICAgfVxuICAgICAgICBpZiAobGF5ZXIudHlwZSA9PT0gJ2NpcmNsZScpIHtcbiAgICAgICAgICAgIHRoaXMuX251bUNpcmNsZUxheWVycyArPSBjb3VudDtcbiAgICAgICAgfVxuICAgICAgICBpZiAobGF5ZXIudHlwZSA9PT0gJ3N5bWJvbCcpIHtcbiAgICAgICAgICAgIHRoaXMuX251bVN5bWJvbExheWVycyArPSBjb3VudDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9sb2FkKGpzb246IFN0eWxlU3BlY2lmaWNhdGlvbiwgdmFsaWRhdGU6IGJvb2xlYW4pIHtcbiAgICAgICAgaWYgKHZhbGlkYXRlICYmIGVtaXRWYWxpZGF0aW9uRXJyb3JzKHRoaXMsIHZhbGlkYXRlU3R5bGUoanNvbikpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9sb2FkZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLnN0eWxlc2hlZXQgPSBjbG9uZShqc29uKTtcbiAgICAgICAgdGhpcy5fdXBkYXRlTWFwUHJvamVjdGlvbigpO1xuXG4gICAgICAgIGZvciAoY29uc3QgaWQgaW4ganNvbi5zb3VyY2VzKSB7XG4gICAgICAgICAgICB0aGlzLmFkZFNvdXJjZShpZCwganNvbi5zb3VyY2VzW2lkXSwge3ZhbGlkYXRlOiBmYWxzZX0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2NoYW5nZWQgPSBmYWxzZTsgLy8gYXZvaWQgdHJpZ2dlcmluZyByZWR1bmRhbnQgc3R5bGUgdXBkYXRlIGFmdGVyIGFkZGluZyBpbml0aWFsIHNvdXJjZXNcbiAgICAgICAgaWYgKGpzb24uc3ByaXRlKSB7XG4gICAgICAgICAgICB0aGlzLl9sb2FkU3ByaXRlKGpzb24uc3ByaXRlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuaW1hZ2VNYW5hZ2VyLnNldExvYWRlZCh0cnVlKTtcbiAgICAgICAgICAgIHRoaXMuZGlzcGF0Y2hlci5icm9hZGNhc3QoJ3Nwcml0ZUxvYWRlZCcsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5nbHlwaE1hbmFnZXIuc2V0VVJMKGpzb24uZ2x5cGhzKTtcblxuICAgICAgICBjb25zdCBsYXllcnM6IEFycmF5PExheWVyU3BlY2lmaWNhdGlvbj4gPSBkZXJlZih0aGlzLnN0eWxlc2hlZXQubGF5ZXJzKTtcblxuICAgICAgICB0aGlzLl9vcmRlciA9IGxheWVycy5tYXAoKGxheWVyKSA9PiBsYXllci5pZCk7XG5cbiAgICAgICAgdGhpcy5fbGF5ZXJzID0ge307XG4gICAgICAgIHRoaXMuX3NlcmlhbGl6ZWRMYXllcnMgPSB7fTtcbiAgICAgICAgZm9yIChjb25zdCBsYXllciBvZiBsYXllcnMpIHtcbiAgICAgICAgICAgIGNvbnN0IHN0eWxlTGF5ZXIgPSBjcmVhdGVTdHlsZUxheWVyKGxheWVyKTtcbiAgICAgICAgICAgIHN0eWxlTGF5ZXIuc2V0RXZlbnRlZFBhcmVudCh0aGlzLCB7bGF5ZXI6IHtpZDogc3R5bGVMYXllci5pZH19KTtcbiAgICAgICAgICAgIHRoaXMuX2xheWVyc1tzdHlsZUxheWVyLmlkXSA9IHN0eWxlTGF5ZXI7XG4gICAgICAgICAgICB0aGlzLl9zZXJpYWxpemVkTGF5ZXJzW3N0eWxlTGF5ZXIuaWRdID0gc3R5bGVMYXllci5zZXJpYWxpemUoKTtcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUxheWVyQ291bnQoc3R5bGVMYXllciwgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmRpc3BhdGNoZXIuYnJvYWRjYXN0KCdzZXRMYXllcnMnLCB0aGlzLl9zZXJpYWxpemVMYXllcnModGhpcy5fb3JkZXIpKTtcblxuICAgICAgICB0aGlzLmxpZ2h0ID0gbmV3IExpZ2h0KHRoaXMuc3R5bGVzaGVldC5saWdodCk7XG4gICAgICAgIGlmICh0aGlzLnN0eWxlc2hlZXQudGVycmFpbiAmJiAhdGhpcy50ZXJyYWluU2V0Rm9yRHJhcGluZ09ubHkoKSkge1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtY2FsbF0gLSBGbG93IGNhbid0IGluZmVyIHRoYXQgdGVycmFpbiBpcyBub3QgdW5kZWZpbmVkXG4gICAgICAgICAgICB0aGlzLl9jcmVhdGVUZXJyYWluKHRoaXMuc3R5bGVzaGVldC50ZXJyYWluLCBEcmFwZVJlbmRlck1vZGUuZWxldmF0ZWQpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnN0eWxlc2hlZXQuZm9nKSB7XG4gICAgICAgICAgICB0aGlzLl9jcmVhdGVGb2codGhpcy5zdHlsZXNoZWV0LmZvZyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fdXBkYXRlRHJhcGVGaXJzdExheWVycygpO1xuXG4gICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ2RhdGEnLCB7ZGF0YVR5cGU6ICdzdHlsZSd9KSk7XG4gICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ3N0eWxlLmxvYWQnKSk7XG4gICAgfVxuXG4gICAgdGVycmFpblNldEZvckRyYXBpbmdPbmx5KCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gISF0aGlzLnRlcnJhaW4gJiYgdGhpcy50ZXJyYWluLmRyYXBlUmVuZGVyTW9kZSA9PT0gRHJhcGVSZW5kZXJNb2RlLmRlZmVycmVkO1xuICAgIH1cblxuICAgIHNldFByb2plY3Rpb24ocHJvamVjdGlvbj86ID9Qcm9qZWN0aW9uU3BlY2lmaWNhdGlvbikge1xuICAgICAgICBpZiAocHJvamVjdGlvbikge1xuICAgICAgICAgICAgdGhpcy5zdHlsZXNoZWV0LnByb2plY3Rpb24gPSBwcm9qZWN0aW9uO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3R5bGVzaGVldC5wcm9qZWN0aW9uO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3VwZGF0ZU1hcFByb2plY3Rpb24oKTtcbiAgICB9XG5cbiAgICBhcHBseVByb2plY3Rpb25VcGRhdGUoKSB7XG4gICAgICAgIGlmICghdGhpcy5fbG9hZGVkKSByZXR1cm47XG4gICAgICAgIHRoaXMuZGlzcGF0Y2hlci5icm9hZGNhc3QoJ3NldFByb2plY3Rpb24nLCB0aGlzLm1hcC50cmFuc2Zvcm0ucHJvamVjdGlvbk9wdGlvbnMpO1xuXG4gICAgICAgIGlmICh0aGlzLm1hcC50cmFuc2Zvcm0ucHJvamVjdGlvbi5yZXF1aXJlc0RyYXBpbmcpIHtcbiAgICAgICAgICAgIGNvbnN0IGhhc1RlcnJhaW4gPSB0aGlzLmdldFRlcnJhaW4oKSB8fCB0aGlzLnN0eWxlc2hlZXQudGVycmFpbjtcbiAgICAgICAgICAgIGlmICghaGFzVGVycmFpbikge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0VGVycmFpbkZvckRyYXBpbmcoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnRlcnJhaW5TZXRGb3JEcmFwaW5nT25seSgpKSB7XG4gICAgICAgICAgICB0aGlzLnNldFRlcnJhaW4obnVsbCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfdXBkYXRlTWFwUHJvamVjdGlvbigpIHtcbiAgICAgICAgaWYgKCF0aGlzLm1hcC5fdXNlRXhwbGljaXRQcm9qZWN0aW9uKSB7IC8vIFVwZGF0ZSB0aGUgdmlzaWJsZSBwcm9qZWN0aW9uIGlmIG1hcCdzIGlzIG51bGxcbiAgICAgICAgICAgIHRoaXMubWFwLl9wcmlvcml0aXplQW5kVXBkYXRlUHJvamVjdGlvbihudWxsLCB0aGlzLnN0eWxlc2hlZXQucHJvamVjdGlvbik7XG4gICAgICAgIH0gZWxzZSB7IC8vIEVuc3VyZSB0aGF0IHN0eWxlIGlzIGNvbnNpc3RlbnQgd2l0aCBjdXJyZW50IHByb2plY3Rpb24gb24gc3R5bGUgbG9hZFxuICAgICAgICAgICAgdGhpcy5hcHBseVByb2plY3Rpb25VcGRhdGUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9sb2FkU3ByaXRlKHVybDogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuX3Nwcml0ZVJlcXVlc3QgPSBsb2FkU3ByaXRlKHVybCwgdGhpcy5tYXAuX3JlcXVlc3RNYW5hZ2VyLCAoZXJyLCBpbWFnZXMpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX3Nwcml0ZVJlcXVlc3QgPSBudWxsO1xuICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXJyb3JFdmVudChlcnIpKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaW1hZ2VzKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBpZCBpbiBpbWFnZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbWFnZU1hbmFnZXIuYWRkSW1hZ2UoaWQsIGltYWdlc1tpZF0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5pbWFnZU1hbmFnZXIuc2V0TG9hZGVkKHRydWUpO1xuICAgICAgICAgICAgdGhpcy5fYXZhaWxhYmxlSW1hZ2VzID0gdGhpcy5pbWFnZU1hbmFnZXIubGlzdEltYWdlcygpO1xuICAgICAgICAgICAgdGhpcy5kaXNwYXRjaGVyLmJyb2FkY2FzdCgnc2V0SW1hZ2VzJywgdGhpcy5fYXZhaWxhYmxlSW1hZ2VzKTtcbiAgICAgICAgICAgIHRoaXMuZGlzcGF0Y2hlci5icm9hZGNhc3QoJ3Nwcml0ZUxvYWRlZCcsIHRydWUpO1xuICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgnZGF0YScsIHtkYXRhVHlwZTogJ3N0eWxlJ30pKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgX3ZhbGlkYXRlTGF5ZXIobGF5ZXI6IFN0eWxlTGF5ZXIpIHtcbiAgICAgICAgY29uc3Qgc291cmNlID0gdGhpcy5nZXRTb3VyY2UobGF5ZXIuc291cmNlKTtcbiAgICAgICAgaWYgKCFzb3VyY2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNvdXJjZUxheWVyID0gbGF5ZXIuc291cmNlTGF5ZXI7XG4gICAgICAgIGlmICghc291cmNlTGF5ZXIpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzb3VyY2UudHlwZSA9PT0gJ2dlb2pzb24nIHx8IChzb3VyY2UudmVjdG9yTGF5ZXJJZHMgJiYgc291cmNlLnZlY3RvckxheWVySWRzLmluZGV4T2Yoc291cmNlTGF5ZXIpID09PSAtMSkpIHtcbiAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXJyb3JFdmVudChuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgYFNvdXJjZSBsYXllciBcIiR7c291cmNlTGF5ZXJ9XCIgYCArXG4gICAgICAgICAgICAgICAgYGRvZXMgbm90IGV4aXN0IG9uIHNvdXJjZSBcIiR7c291cmNlLmlkfVwiIGAgK1xuICAgICAgICAgICAgICAgIGBhcyBzcGVjaWZpZWQgYnkgc3R5bGUgbGF5ZXIgXCIke2xheWVyLmlkfVwiYFxuICAgICAgICAgICAgKSkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbG9hZGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAoIXRoaXMuX2xvYWRlZClcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcblxuICAgICAgICBpZiAoT2JqZWN0LmtleXModGhpcy5fdXBkYXRlZFNvdXJjZXMpLmxlbmd0aClcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcblxuICAgICAgICBmb3IgKGNvbnN0IGlkIGluIHRoaXMuX3NvdXJjZUNhY2hlcylcbiAgICAgICAgICAgIGlmICghdGhpcy5fc291cmNlQ2FjaGVzW2lkXS5sb2FkZWQoKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgaWYgKCF0aGlzLmltYWdlTWFuYWdlci5pc0xvYWRlZCgpKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIF9zZXJpYWxpemVMYXllcnMoaWRzOiBBcnJheTxzdHJpbmc+KTogQXJyYXk8T2JqZWN0PiB7XG4gICAgICAgIGNvbnN0IHNlcmlhbGl6ZWRMYXllcnMgPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBpZCBvZiBpZHMpIHtcbiAgICAgICAgICAgIGNvbnN0IGxheWVyID0gdGhpcy5fbGF5ZXJzW2lkXTtcbiAgICAgICAgICAgIGlmIChsYXllci50eXBlICE9PSAnY3VzdG9tJykge1xuICAgICAgICAgICAgICAgIHNlcmlhbGl6ZWRMYXllcnMucHVzaChsYXllci5zZXJpYWxpemUoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNlcmlhbGl6ZWRMYXllcnM7XG4gICAgfVxuXG4gICAgaGFzVHJhbnNpdGlvbnMoKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICh0aGlzLmxpZ2h0ICYmIHRoaXMubGlnaHQuaGFzVHJhbnNpdGlvbigpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmZvZyAmJiB0aGlzLmZvZy5oYXNUcmFuc2l0aW9uKCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChjb25zdCBpZCBpbiB0aGlzLl9zb3VyY2VDYWNoZXMpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9zb3VyY2VDYWNoZXNbaWRdLmhhc1RyYW5zaXRpb24oKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChjb25zdCBpZCBpbiB0aGlzLl9sYXllcnMpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9sYXllcnNbaWRdLmhhc1RyYW5zaXRpb24oKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGdldCBvcmRlcigpOiBBcnJheTxzdHJpbmc+IHtcbiAgICAgICAgaWYgKHRoaXMubWFwLl9vcHRpbWl6ZUZvclRlcnJhaW4gJiYgdGhpcy50ZXJyYWluKSB7XG4gICAgICAgICAgICBhc3NlcnQodGhpcy5fZHJhcGVkRmlyc3RPcmRlci5sZW5ndGggPT09IHRoaXMuX29yZGVyLmxlbmd0aCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZHJhcGVkRmlyc3RPcmRlcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fb3JkZXI7XG4gICAgfVxuXG4gICAgaXNMYXllckRyYXBlZChsYXllcjogU3R5bGVMYXllcik6IGJvb2xlYW4ge1xuICAgICAgICBpZiAoIXRoaXMudGVycmFpbikgcmV0dXJuIGZhbHNlO1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW3Byb3AtbWlzc2luZ11cbiAgICAgICAgLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtdXNlXVxuICAgICAgICBpZiAodHlwZW9mIGxheWVyLmlzTGF5ZXJEcmFwZWQgPT09ICdmdW5jdGlvbicpIHJldHVybiBsYXllci5pc0xheWVyRHJhcGVkKCk7XG4gICAgICAgIHJldHVybiBkcmFwZWRMYXllcnNbbGF5ZXIudHlwZV07XG4gICAgfVxuXG4gICAgX2NoZWNrTG9hZGVkKCk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMuX2xvYWRlZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTdHlsZSBpcyBub3QgZG9uZSBsb2FkaW5nJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBcHBseSBxdWV1ZWQgc3R5bGUgdXBkYXRlcyBpbiBhIGJhdGNoIGFuZCByZWNhbGN1bGF0ZSB6b29tLWRlcGVuZGVudCBwYWludCBwcm9wZXJ0aWVzLlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgdXBkYXRlKHBhcmFtZXRlcnM6IEV2YWx1YXRpb25QYXJhbWV0ZXJzKSB7XG4gICAgICAgIGlmICghdGhpcy5fbG9hZGVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjaGFuZ2VkID0gdGhpcy5fY2hhbmdlZDtcbiAgICAgICAgaWYgKHRoaXMuX2NoYW5nZWQpIHtcbiAgICAgICAgICAgIGNvbnN0IHVwZGF0ZWRJZHMgPSBPYmplY3Qua2V5cyh0aGlzLl91cGRhdGVkTGF5ZXJzKTtcbiAgICAgICAgICAgIGNvbnN0IHJlbW92ZWRJZHMgPSBPYmplY3Qua2V5cyh0aGlzLl9yZW1vdmVkTGF5ZXJzKTtcblxuICAgICAgICAgICAgaWYgKHVwZGF0ZWRJZHMubGVuZ3RoIHx8IHJlbW92ZWRJZHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdXBkYXRlV29ya2VyTGF5ZXJzKHVwZGF0ZWRJZHMsIHJlbW92ZWRJZHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChjb25zdCBpZCBpbiB0aGlzLl91cGRhdGVkU291cmNlcykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGFjdGlvbiA9IHRoaXMuX3VwZGF0ZWRTb3VyY2VzW2lkXTtcbiAgICAgICAgICAgICAgICBhc3NlcnQoYWN0aW9uID09PSAncmVsb2FkJyB8fCBhY3Rpb24gPT09ICdjbGVhcicpO1xuICAgICAgICAgICAgICAgIGlmIChhY3Rpb24gPT09ICdyZWxvYWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3JlbG9hZFNvdXJjZShpZCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhY3Rpb24gPT09ICdjbGVhcicpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2xlYXJTb3VyY2UoaWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5fdXBkYXRlVGlsZXNGb3JDaGFuZ2VkSW1hZ2VzKCk7XG5cbiAgICAgICAgICAgIGZvciAoY29uc3QgaWQgaW4gdGhpcy5fdXBkYXRlZFBhaW50UHJvcHMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9sYXllcnNbaWRdLnVwZGF0ZVRyYW5zaXRpb25zKHBhcmFtZXRlcnMpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmxpZ2h0LnVwZGF0ZVRyYW5zaXRpb25zKHBhcmFtZXRlcnMpO1xuICAgICAgICAgICAgaWYgKHRoaXMuZm9nKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5mb2cudXBkYXRlVHJhbnNpdGlvbnMocGFyYW1ldGVycyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuX3Jlc2V0VXBkYXRlcygpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc291cmNlc1VzZWRCZWZvcmUgPSB7fTtcblxuICAgICAgICBmb3IgKGNvbnN0IHNvdXJjZUlkIGluIHRoaXMuX3NvdXJjZUNhY2hlcykge1xuICAgICAgICAgICAgY29uc3Qgc291cmNlQ2FjaGUgPSB0aGlzLl9zb3VyY2VDYWNoZXNbc291cmNlSWRdO1xuICAgICAgICAgICAgc291cmNlc1VzZWRCZWZvcmVbc291cmNlSWRdID0gc291cmNlQ2FjaGUudXNlZDtcbiAgICAgICAgICAgIHNvdXJjZUNhY2hlLnVzZWQgPSBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoY29uc3QgbGF5ZXJJZCBvZiB0aGlzLl9vcmRlcikge1xuICAgICAgICAgICAgY29uc3QgbGF5ZXIgPSB0aGlzLl9sYXllcnNbbGF5ZXJJZF07XG5cbiAgICAgICAgICAgIGxheWVyLnJlY2FsY3VsYXRlKHBhcmFtZXRlcnMsIHRoaXMuX2F2YWlsYWJsZUltYWdlcyk7XG4gICAgICAgICAgICBpZiAoIWxheWVyLmlzSGlkZGVuKHBhcmFtZXRlcnMuem9vbSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2VDYWNoZSA9IHRoaXMuX2dldExheWVyU291cmNlQ2FjaGUobGF5ZXIpO1xuICAgICAgICAgICAgICAgIGlmIChzb3VyY2VDYWNoZSkgc291cmNlQ2FjaGUudXNlZCA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHBhaW50ZXIgPSB0aGlzLm1hcC5wYWludGVyO1xuICAgICAgICAgICAgaWYgKHBhaW50ZXIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwcm9ncmFtSWRzID0gbGF5ZXIuZ2V0UHJvZ3JhbUlkcygpO1xuICAgICAgICAgICAgICAgIGlmICghcHJvZ3JhbUlkcykgY29udGludWU7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBwcm9ncmFtQ29uZmlndXJhdGlvbiA9IGxheWVyLmdldFByb2dyYW1Db25maWd1cmF0aW9uKHBhcmFtZXRlcnMuem9vbSk7XG5cbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHByb2dyYW1JZCBvZiBwcm9ncmFtSWRzKSB7XG4gICAgICAgICAgICAgICAgICAgIHBhaW50ZXIudXNlUHJvZ3JhbShwcm9ncmFtSWQsIHByb2dyYW1Db25maWd1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGNvbnN0IHNvdXJjZUlkIGluIHNvdXJjZXNVc2VkQmVmb3JlKSB7XG4gICAgICAgICAgICBjb25zdCBzb3VyY2VDYWNoZSA9IHRoaXMuX3NvdXJjZUNhY2hlc1tzb3VyY2VJZF07XG4gICAgICAgICAgICBpZiAoc291cmNlc1VzZWRCZWZvcmVbc291cmNlSWRdICE9PSBzb3VyY2VDYWNoZS51c2VkKSB7XG4gICAgICAgICAgICAgICAgc291cmNlQ2FjaGUuZ2V0U291cmNlKCkuZmlyZShuZXcgRXZlbnQoJ2RhdGEnLCB7c291cmNlRGF0YVR5cGU6ICd2aXNpYmlsaXR5JywgZGF0YVR5cGU6J3NvdXJjZScsIHNvdXJjZUlkOiBzb3VyY2VDYWNoZS5nZXRTb3VyY2UoKS5pZH0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubGlnaHQucmVjYWxjdWxhdGUocGFyYW1ldGVycyk7XG4gICAgICAgIGlmICh0aGlzLnRlcnJhaW4pIHtcbiAgICAgICAgICAgIHRoaXMudGVycmFpbi5yZWNhbGN1bGF0ZShwYXJhbWV0ZXJzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5mb2cpIHtcbiAgICAgICAgICAgIHRoaXMuZm9nLnJlY2FsY3VsYXRlKHBhcmFtZXRlcnMpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMueiA9IHBhcmFtZXRlcnMuem9vbTtcblxuICAgICAgICBpZiAodGhpcy5fbWFya2Vyc05lZWRVcGRhdGUpIHtcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZU1hcmtlcnNPcGFjaXR5KCk7XG4gICAgICAgICAgICB0aGlzLl9tYXJrZXJzTmVlZFVwZGF0ZSA9IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNoYW5nZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ2RhdGEnLCB7ZGF0YVR5cGU6ICdzdHlsZSd9KSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKlxuICAgICAqIEFwcGx5IGFueSBxdWV1ZWQgaW1hZ2UgY2hhbmdlcy5cbiAgICAgKi9cbiAgICBfdXBkYXRlVGlsZXNGb3JDaGFuZ2VkSW1hZ2VzKCkge1xuICAgICAgICBjb25zdCBjaGFuZ2VkSW1hZ2VzID0gT2JqZWN0LmtleXModGhpcy5fY2hhbmdlZEltYWdlcyk7XG4gICAgICAgIGlmIChjaGFuZ2VkSW1hZ2VzLmxlbmd0aCkge1xuICAgICAgICAgICAgZm9yIChjb25zdCBuYW1lIGluIHRoaXMuX3NvdXJjZUNhY2hlcykge1xuICAgICAgICAgICAgICAgIHRoaXMuX3NvdXJjZUNhY2hlc1tuYW1lXS5yZWxvYWRUaWxlc0ZvckRlcGVuZGVuY2llcyhbJ2ljb25zJywgJ3BhdHRlcm5zJ10sIGNoYW5nZWRJbWFnZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fY2hhbmdlZEltYWdlcyA9IHt9O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX3VwZGF0ZVdvcmtlckxheWVycyh1cGRhdGVkSWRzOiBBcnJheTxzdHJpbmc+LCByZW1vdmVkSWRzOiBBcnJheTxzdHJpbmc+KSB7XG4gICAgICAgIHRoaXMuZGlzcGF0Y2hlci5icm9hZGNhc3QoJ3VwZGF0ZUxheWVycycsIHtcbiAgICAgICAgICAgIGxheWVyczogdGhpcy5fc2VyaWFsaXplTGF5ZXJzKHVwZGF0ZWRJZHMpLFxuICAgICAgICAgICAgcmVtb3ZlZElkc1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBfcmVzZXRVcGRhdGVzKCkge1xuICAgICAgICB0aGlzLl9jaGFuZ2VkID0gZmFsc2U7XG5cbiAgICAgICAgdGhpcy5fdXBkYXRlZExheWVycyA9IHt9O1xuICAgICAgICB0aGlzLl9yZW1vdmVkTGF5ZXJzID0ge307XG5cbiAgICAgICAgdGhpcy5fdXBkYXRlZFNvdXJjZXMgPSB7fTtcbiAgICAgICAgdGhpcy5fdXBkYXRlZFBhaW50UHJvcHMgPSB7fTtcblxuICAgICAgICB0aGlzLl9jaGFuZ2VkSW1hZ2VzID0ge307XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXBkYXRlIHRoaXMgc3R5bGUncyBzdGF0ZSB0byBtYXRjaCB0aGUgZ2l2ZW4gc3R5bGUgSlNPTiwgcGVyZm9ybWluZyBvbmx5XG4gICAgICogdGhlIG5lY2Vzc2FyeSBtdXRhdGlvbnMuXG4gICAgICpcbiAgICAgKiBNYXkgdGhyb3cgYW4gRXJyb3IgKCdVbmltcGxlbWVudGVkOiBNRVRIT0QnKSBpZiB0aGUgbWFwYm94LWdsLXN0eWxlLXNwZWNcbiAgICAgKiBkaWZmIGFsZ29yaXRobSBwcm9kdWNlcyBhbiBvcGVyYXRpb24gdGhhdCBpcyBub3Qgc3VwcG9ydGVkLlxuICAgICAqXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IHRydWUgaWYgYW55IGNoYW5nZXMgd2VyZSBtYWRlOyBmYWxzZSBvdGhlcndpc2VcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHNldFN0YXRlKG5leHRTdGF0ZTogU3R5bGVTcGVjaWZpY2F0aW9uKTogYm9vbGVhbiB7XG4gICAgICAgIHRoaXMuX2NoZWNrTG9hZGVkKCk7XG5cbiAgICAgICAgaWYgKGVtaXRWYWxpZGF0aW9uRXJyb3JzKHRoaXMsIHZhbGlkYXRlU3R5bGUobmV4dFN0YXRlKSkpIHJldHVybiBmYWxzZTtcblxuICAgICAgICBuZXh0U3RhdGUgPSBjbG9uZShuZXh0U3RhdGUpO1xuICAgICAgICBuZXh0U3RhdGUubGF5ZXJzID0gZGVyZWYobmV4dFN0YXRlLmxheWVycyk7XG5cbiAgICAgICAgY29uc3QgY2hhbmdlcyA9IGRpZmZTdHlsZXModGhpcy5zZXJpYWxpemUoKSwgbmV4dFN0YXRlKVxuICAgICAgICAgICAgLmZpbHRlcihvcCA9PiAhKG9wLmNvbW1hbmQgaW4gaWdub3JlZERpZmZPcGVyYXRpb25zKSk7XG5cbiAgICAgICAgaWYgKGNoYW5nZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB1bmltcGxlbWVudGVkT3BzID0gY2hhbmdlcy5maWx0ZXIob3AgPT4gIShvcC5jb21tYW5kIGluIHN1cHBvcnRlZERpZmZPcGVyYXRpb25zKSk7XG4gICAgICAgIGlmICh1bmltcGxlbWVudGVkT3BzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5pbXBsZW1lbnRlZDogJHt1bmltcGxlbWVudGVkT3BzLm1hcChvcCA9PiBvcC5jb21tYW5kKS5qb2luKCcsICcpfS5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNoYW5nZXMuZm9yRWFjaCgob3ApID0+IHtcbiAgICAgICAgICAgIGlmIChvcC5jb21tYW5kID09PSAnc2V0VHJhbnNpdGlvbicgfHwgb3AuY29tbWFuZCA9PT0gJ3NldFByb2plY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgLy8gYHRyYW5zaXRpb25gIGFuZCBgcHJvamVjdGlvbmAgYXJlIGFsd2F5cyByZWFkIGRpcmVjdGx5IGZyb21cbiAgICAgICAgICAgICAgICAvLyBgdGhpcy5zdHlsZXNoZWV0YCwgd2hpY2ggd2UgdXBkYXRlIGJlbG93XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgKHRoaXM6IGFueSlbb3AuY29tbWFuZF0uYXBwbHkodGhpcywgb3AuYXJncyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuc3R5bGVzaGVldCA9IG5leHRTdGF0ZTtcbiAgICAgICAgdGhpcy5fdXBkYXRlTWFwUHJvamVjdGlvbigpO1xuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGFkZEltYWdlKGlkOiBzdHJpbmcsIGltYWdlOiBTdHlsZUltYWdlKTogdGhpcyB7XG4gICAgICAgIGlmICh0aGlzLmdldEltYWdlKGlkKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZmlyZShuZXcgRXJyb3JFdmVudChuZXcgRXJyb3IoJ0FuIGltYWdlIHdpdGggdGhpcyBuYW1lIGFscmVhZHkgZXhpc3RzLicpKSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pbWFnZU1hbmFnZXIuYWRkSW1hZ2UoaWQsIGltYWdlKTtcbiAgICAgICAgdGhpcy5fYWZ0ZXJJbWFnZVVwZGF0ZWQoaWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICB1cGRhdGVJbWFnZShpZDogc3RyaW5nLCBpbWFnZTogU3R5bGVJbWFnZSkge1xuICAgICAgICB0aGlzLmltYWdlTWFuYWdlci51cGRhdGVJbWFnZShpZCwgaW1hZ2UpO1xuICAgIH1cblxuICAgIGdldEltYWdlKGlkOiBzdHJpbmcpOiA/U3R5bGVJbWFnZSB7XG4gICAgICAgIHJldHVybiB0aGlzLmltYWdlTWFuYWdlci5nZXRJbWFnZShpZCk7XG4gICAgfVxuXG4gICAgcmVtb3ZlSW1hZ2UoaWQ6IHN0cmluZyk6IHRoaXMge1xuICAgICAgICBpZiAoIXRoaXMuZ2V0SW1hZ2UoaWQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5maXJlKG5ldyBFcnJvckV2ZW50KG5ldyBFcnJvcignTm8gaW1hZ2Ugd2l0aCB0aGlzIG5hbWUgZXhpc3RzLicpKSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pbWFnZU1hbmFnZXIucmVtb3ZlSW1hZ2UoaWQpO1xuICAgICAgICB0aGlzLl9hZnRlckltYWdlVXBkYXRlZChpZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIF9hZnRlckltYWdlVXBkYXRlZChpZDogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuX2F2YWlsYWJsZUltYWdlcyA9IHRoaXMuaW1hZ2VNYW5hZ2VyLmxpc3RJbWFnZXMoKTtcbiAgICAgICAgdGhpcy5fY2hhbmdlZEltYWdlc1tpZF0gPSB0cnVlO1xuICAgICAgICB0aGlzLl9jaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5kaXNwYXRjaGVyLmJyb2FkY2FzdCgnc2V0SW1hZ2VzJywgdGhpcy5fYXZhaWxhYmxlSW1hZ2VzKTtcbiAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgnZGF0YScsIHtkYXRhVHlwZTogJ3N0eWxlJ30pKTtcbiAgICB9XG5cbiAgICBsaXN0SW1hZ2VzKCk6IEFycmF5PHN0cmluZz4ge1xuICAgICAgICB0aGlzLl9jaGVja0xvYWRlZCgpO1xuICAgICAgICByZXR1cm4gdGhpcy5fYXZhaWxhYmxlSW1hZ2VzLnNsaWNlKCk7XG4gICAgfVxuXG4gICAgYWRkU291cmNlKGlkOiBzdHJpbmcsIHNvdXJjZTogU291cmNlU3BlY2lmaWNhdGlvbiwgb3B0aW9uczogU3R5bGVTZXR0ZXJPcHRpb25zID0ge30pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fY2hlY2tMb2FkZWQoKTtcblxuICAgICAgICBpZiAodGhpcy5nZXRTb3VyY2UoaWQpICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlcmUgaXMgYWxyZWFkeSBhIHNvdXJjZSB3aXRoIHRoaXMgSUQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghc291cmNlLnR5cGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlIHR5cGUgcHJvcGVydHkgbXVzdCBiZSBkZWZpbmVkLCBidXQgb25seSB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXMgd2VyZSBnaXZlbjogJHtPYmplY3Qua2V5cyhzb3VyY2UpLmpvaW4oJywgJyl9LmApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgYnVpbHRJbnMgPSBbJ3ZlY3RvcicsICdyYXN0ZXInLCAnZ2VvanNvbicsICd2aWRlbycsICdpbWFnZSddO1xuICAgICAgICBjb25zdCBzaG91bGRWYWxpZGF0ZSA9IGJ1aWx0SW5zLmluZGV4T2Yoc291cmNlLnR5cGUpID49IDA7XG4gICAgICAgIGlmIChzaG91bGRWYWxpZGF0ZSAmJiB0aGlzLl92YWxpZGF0ZSh2YWxpZGF0ZVNvdXJjZSwgYHNvdXJjZXMuJHtpZH1gLCBzb3VyY2UsIG51bGwsIG9wdGlvbnMpKSByZXR1cm47XG5cbiAgICAgICAgaWYgKHRoaXMubWFwICYmIHRoaXMubWFwLl9jb2xsZWN0UmVzb3VyY2VUaW1pbmcpIChzb3VyY2U6IGFueSkuY29sbGVjdFJlc291cmNlVGltaW5nID0gdHJ1ZTtcblxuICAgICAgICBjb25zdCBzb3VyY2VJbnN0YW5jZSA9IGNyZWF0ZVNvdXJjZShpZCwgc291cmNlLCB0aGlzLmRpc3BhdGNoZXIsIHRoaXMpO1xuXG4gICAgICAgIHNvdXJjZUluc3RhbmNlLnNldEV2ZW50ZWRQYXJlbnQodGhpcywgKCkgPT4gKHtcbiAgICAgICAgICAgIGlzU291cmNlTG9hZGVkOiB0aGlzLl9pc1NvdXJjZUNhY2hlTG9hZGVkKGlkKSxcbiAgICAgICAgICAgIHNvdXJjZTogc291cmNlSW5zdGFuY2Uuc2VyaWFsaXplKCksXG4gICAgICAgICAgICBzb3VyY2VJZDogaWRcbiAgICAgICAgfSkpO1xuXG4gICAgICAgIGNvbnN0IGFkZFNvdXJjZUNhY2hlID0gKG9ubHlTeW1ib2xzOiBib29sZWFuKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzb3VyY2VDYWNoZUlkID0gKG9ubHlTeW1ib2xzID8gJ3N5bWJvbDonIDogJ290aGVyOicpICsgaWQ7XG4gICAgICAgICAgICBjb25zdCBzb3VyY2VDYWNoZSA9IHRoaXMuX3NvdXJjZUNhY2hlc1tzb3VyY2VDYWNoZUlkXSA9IG5ldyBTb3VyY2VDYWNoZShzb3VyY2VDYWNoZUlkLCBzb3VyY2VJbnN0YW5jZSwgb25seVN5bWJvbHMpO1xuICAgICAgICAgICAgKG9ubHlTeW1ib2xzID8gdGhpcy5fc3ltYm9sU291cmNlQ2FjaGVzIDogdGhpcy5fb3RoZXJTb3VyY2VDYWNoZXMpW2lkXSA9IHNvdXJjZUNhY2hlO1xuICAgICAgICAgICAgc291cmNlQ2FjaGUuc3R5bGUgPSB0aGlzO1xuXG4gICAgICAgICAgICBzb3VyY2VDYWNoZS5vbkFkZCh0aGlzLm1hcCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgYWRkU291cmNlQ2FjaGUoZmFsc2UpO1xuICAgICAgICBpZiAoc291cmNlLnR5cGUgPT09ICd2ZWN0b3InIHx8IHNvdXJjZS50eXBlID09PSAnZ2VvanNvbicpIHtcbiAgICAgICAgICAgIGFkZFNvdXJjZUNhY2hlKHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNvdXJjZUluc3RhbmNlLm9uQWRkKSBzb3VyY2VJbnN0YW5jZS5vbkFkZCh0aGlzLm1hcCk7XG5cbiAgICAgICAgdGhpcy5fY2hhbmdlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGEgc291cmNlIGZyb20gdGhpcyBzdHlsZXNoZWV0LCBnaXZlbiBpdHMgSUQuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGlkIElEIG9mIHRoZSBzb3VyY2UgdG8gcmVtb3ZlLlxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiBubyBzb3VyY2UgaXMgZm91bmQgd2l0aCB0aGUgZ2l2ZW4gSUQuXG4gICAgICogQHJldHVybnMge01hcH0gVGhlIHtAbGluayBNYXB9IG9iamVjdC5cbiAgICAgKi9cbiAgICByZW1vdmVTb3VyY2UoaWQ6IHN0cmluZyk6IHRoaXMge1xuICAgICAgICB0aGlzLl9jaGVja0xvYWRlZCgpO1xuXG4gICAgICAgIGNvbnN0IHNvdXJjZSA9IHRoaXMuZ2V0U291cmNlKGlkKTtcbiAgICAgICAgaWYgKCFzb3VyY2UpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlcmUgaXMgbm8gc291cmNlIHdpdGggdGhpcyBJRCcpO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgbGF5ZXJJZCBpbiB0aGlzLl9sYXllcnMpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9sYXllcnNbbGF5ZXJJZF0uc291cmNlID09PSBpZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZpcmUobmV3IEVycm9yRXZlbnQobmV3IEVycm9yKGBTb3VyY2UgXCIke2lkfVwiIGNhbm5vdCBiZSByZW1vdmVkIHdoaWxlIGxheWVyIFwiJHtsYXllcklkfVwiIGlzIHVzaW5nIGl0LmApKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMudGVycmFpbiAmJiB0aGlzLnRlcnJhaW4uZ2V0KCkuc291cmNlID09PSBpZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZmlyZShuZXcgRXJyb3JFdmVudChuZXcgRXJyb3IoYFNvdXJjZSBcIiR7aWR9XCIgY2Fubm90IGJlIHJlbW92ZWQgd2hpbGUgdGVycmFpbiBpcyB1c2luZyBpdC5gKSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc291cmNlQ2FjaGVzID0gdGhpcy5fZ2V0U291cmNlQ2FjaGVzKGlkKTtcbiAgICAgICAgZm9yIChjb25zdCBzb3VyY2VDYWNoZSBvZiBzb3VyY2VDYWNoZXMpIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9zb3VyY2VDYWNoZXNbc291cmNlQ2FjaGUuaWRdO1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuX3VwZGF0ZWRTb3VyY2VzW3NvdXJjZUNhY2hlLmlkXTtcbiAgICAgICAgICAgIHNvdXJjZUNhY2hlLmZpcmUobmV3IEV2ZW50KCdkYXRhJywge3NvdXJjZURhdGFUeXBlOiAnbWV0YWRhdGEnLCBkYXRhVHlwZTonc291cmNlJywgc291cmNlSWQ6IHNvdXJjZUNhY2hlLmdldFNvdXJjZSgpLmlkfSkpO1xuICAgICAgICAgICAgc291cmNlQ2FjaGUuc2V0RXZlbnRlZFBhcmVudChudWxsKTtcbiAgICAgICAgICAgIHNvdXJjZUNhY2hlLmNsZWFyVGlsZXMoKTtcbiAgICAgICAgfVxuICAgICAgICBkZWxldGUgdGhpcy5fb3RoZXJTb3VyY2VDYWNoZXNbaWRdO1xuICAgICAgICBkZWxldGUgdGhpcy5fc3ltYm9sU291cmNlQ2FjaGVzW2lkXTtcblxuICAgICAgICBzb3VyY2Uuc2V0RXZlbnRlZFBhcmVudChudWxsKTtcbiAgICAgICAgaWYgKHNvdXJjZS5vblJlbW92ZSkge1xuICAgICAgICAgICAgc291cmNlLm9uUmVtb3ZlKHRoaXMubWFwKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9jaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBTZXQgdGhlIGRhdGEgb2YgYSBHZW9KU09OIHNvdXJjZSwgZ2l2ZW4gaXRzIElELlxuICAgICogQHBhcmFtIHtzdHJpbmd9IGlkIElEIG9mIHRoZSBzb3VyY2UuXG4gICAgKiBAcGFyYW0ge0dlb0pTT058c3RyaW5nfSBkYXRhIEdlb0pTT04gc291cmNlLlxuICAgICovXG4gICAgc2V0R2VvSlNPTlNvdXJjZURhdGEoaWQ6IHN0cmluZywgZGF0YTogR2VvSlNPTiB8IHN0cmluZykge1xuICAgICAgICB0aGlzLl9jaGVja0xvYWRlZCgpO1xuXG4gICAgICAgIGFzc2VydCh0aGlzLmdldFNvdXJjZShpZCkgIT09IHVuZGVmaW5lZCwgJ1RoZXJlIGlzIG5vIHNvdXJjZSB3aXRoIHRoaXMgSUQnKTtcbiAgICAgICAgY29uc3QgZ2VvanNvblNvdXJjZTogR2VvSlNPTlNvdXJjZSA9ICh0aGlzLmdldFNvdXJjZShpZCk6IGFueSk7XG4gICAgICAgIGFzc2VydChnZW9qc29uU291cmNlLnR5cGUgPT09ICdnZW9qc29uJyk7XG5cbiAgICAgICAgZ2VvanNvblNvdXJjZS5zZXREYXRhKGRhdGEpO1xuICAgICAgICB0aGlzLl9jaGFuZ2VkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgYSBzb3VyY2UgYnkgSUQuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGlkIElEIG9mIHRoZSBkZXNpcmVkIHNvdXJjZS5cbiAgICAgKiBAcmV0dXJucyB7P1NvdXJjZX0gVGhlIHNvdXJjZSBvYmplY3QuXG4gICAgICovXG4gICAgZ2V0U291cmNlKGlkOiBzdHJpbmcpOiA/U291cmNlIHtcbiAgICAgICAgY29uc3Qgc291cmNlQ2FjaGUgPSB0aGlzLl9nZXRTb3VyY2VDYWNoZShpZCk7XG4gICAgICAgIHJldHVybiBzb3VyY2VDYWNoZSAmJiBzb3VyY2VDYWNoZS5nZXRTb3VyY2UoKTtcbiAgICB9XG5cbiAgICBfZ2V0U291cmNlcygpOiBTb3VyY2VbXSB7XG4gICAgICAgIGNvbnN0IHNvdXJjZXMgPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBpZCBpbiB0aGlzLl9vdGhlclNvdXJjZUNhY2hlcykge1xuICAgICAgICAgICAgY29uc3Qgc291cmNlQ2FjaGUgPSB0aGlzLl9nZXRTb3VyY2VDYWNoZShpZCk7XG4gICAgICAgICAgICBpZiAoc291cmNlQ2FjaGUpIHNvdXJjZXMucHVzaChzb3VyY2VDYWNoZS5nZXRTb3VyY2UoKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gc291cmNlcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBsYXllciB0byB0aGUgbWFwIHN0eWxlLiBUaGUgbGF5ZXIgd2lsbCBiZSBpbnNlcnRlZCBiZWZvcmUgdGhlIGxheWVyIHdpdGhcbiAgICAgKiBJRCBgYmVmb3JlYCwgb3IgYXBwZW5kZWQgaWYgYGJlZm9yZWAgaXMgb21pdHRlZC5cbiAgICAgKiBAcGFyYW0ge09iamVjdCB8IEN1c3RvbUxheWVySW50ZXJmYWNlfSBsYXllck9iamVjdCBUaGUgc3R5bGUgbGF5ZXIgdG8gYWRkLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbYmVmb3JlXSBJRCBvZiBhbiBleGlzdGluZyBsYXllciB0byBpbnNlcnQgYmVmb3JlLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIFN0eWxlIHNldHRlciBvcHRpb25zLlxuICAgICAqIEByZXR1cm5zIHtNYXB9IFRoZSB7QGxpbmsgTWFwfSBvYmplY3QuXG4gICAgICovXG4gICAgYWRkTGF5ZXIobGF5ZXJPYmplY3Q6IExheWVyU3BlY2lmaWNhdGlvbiB8IEN1c3RvbUxheWVySW50ZXJmYWNlLCBiZWZvcmU/OiBzdHJpbmcsIG9wdGlvbnM6IFN0eWxlU2V0dGVyT3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIHRoaXMuX2NoZWNrTG9hZGVkKCk7XG5cbiAgICAgICAgY29uc3QgaWQgPSBsYXllck9iamVjdC5pZDtcblxuICAgICAgICBpZiAodGhpcy5nZXRMYXllcihpZCkpIHtcbiAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXJyb3JFdmVudChuZXcgRXJyb3IoYExheWVyIHdpdGggaWQgXCIke2lkfVwiIGFscmVhZHkgZXhpc3RzIG9uIHRoaXMgbWFwYCkpKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBsYXllcjtcbiAgICAgICAgaWYgKGxheWVyT2JqZWN0LnR5cGUgPT09ICdjdXN0b20nKSB7XG5cbiAgICAgICAgICAgIGlmIChlbWl0VmFsaWRhdGlvbkVycm9ycyh0aGlzLCB2YWxpZGF0ZUN1c3RvbVN0eWxlTGF5ZXIobGF5ZXJPYmplY3QpKSkgcmV0dXJuO1xuXG4gICAgICAgICAgICBsYXllciA9IGNyZWF0ZVN0eWxlTGF5ZXIobGF5ZXJPYmplY3QpO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGxheWVyT2JqZWN0LnNvdXJjZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFkZFNvdXJjZShpZCwgbGF5ZXJPYmplY3Quc291cmNlKTtcbiAgICAgICAgICAgICAgICBsYXllck9iamVjdCA9IGNsb25lKGxheWVyT2JqZWN0KTtcbiAgICAgICAgICAgICAgICBsYXllck9iamVjdCA9IChleHRlbmQobGF5ZXJPYmplY3QsIHtzb3VyY2U6IGlkfSk6IGFueSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHRoaXMgbGF5ZXIgaXMgbm90IGluIHRoZSBzdHlsZS5sYXllcnMgYXJyYXksIHNvIHdlIHBhc3MgYW4gaW1wb3NzaWJsZSBhcnJheSBpbmRleFxuICAgICAgICAgICAgaWYgKHRoaXMuX3ZhbGlkYXRlKHZhbGlkYXRlTGF5ZXIsXG4gICAgICAgICAgICAgICAgYGxheWVycy4ke2lkfWAsIGxheWVyT2JqZWN0LCB7YXJyYXlJbmRleDogLTF9LCBvcHRpb25zKSkgcmV0dXJuO1xuXG4gICAgICAgICAgICBsYXllciA9IGNyZWF0ZVN0eWxlTGF5ZXIobGF5ZXJPYmplY3QpO1xuICAgICAgICAgICAgdGhpcy5fdmFsaWRhdGVMYXllcihsYXllcik7XG5cbiAgICAgICAgICAgIGxheWVyLnNldEV2ZW50ZWRQYXJlbnQodGhpcywge2xheWVyOiB7aWR9fSk7XG4gICAgICAgICAgICB0aGlzLl9zZXJpYWxpemVkTGF5ZXJzW2xheWVyLmlkXSA9IGxheWVyLnNlcmlhbGl6ZSgpO1xuICAgICAgICAgICAgdGhpcy5fdXBkYXRlTGF5ZXJDb3VudChsYXllciwgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBpbmRleCA9IGJlZm9yZSA/IHRoaXMuX29yZGVyLmluZGV4T2YoYmVmb3JlKSA6IHRoaXMuX29yZGVyLmxlbmd0aDtcbiAgICAgICAgaWYgKGJlZm9yZSAmJiBpbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXJyb3JFdmVudChuZXcgRXJyb3IoYExheWVyIHdpdGggaWQgXCIke2JlZm9yZX1cIiBkb2VzIG5vdCBleGlzdCBvbiB0aGlzIG1hcC5gKSkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fb3JkZXIuc3BsaWNlKGluZGV4LCAwLCBpZCk7XG4gICAgICAgIHRoaXMuX2xheWVyT3JkZXJDaGFuZ2VkID0gdHJ1ZTtcblxuICAgICAgICB0aGlzLl9sYXllcnNbaWRdID0gbGF5ZXI7XG5cbiAgICAgICAgY29uc3Qgc291cmNlQ2FjaGUgPSB0aGlzLl9nZXRMYXllclNvdXJjZUNhY2hlKGxheWVyKTtcbiAgICAgICAgaWYgKHRoaXMuX3JlbW92ZWRMYXllcnNbaWRdICYmIGxheWVyLnNvdXJjZSAmJiBzb3VyY2VDYWNoZSAmJiBsYXllci50eXBlICE9PSAnY3VzdG9tJykge1xuICAgICAgICAgICAgLy8gSWYsIGluIHRoZSBjdXJyZW50IGJhdGNoLCB3ZSBoYXZlIGFscmVhZHkgcmVtb3ZlZCB0aGlzIGxheWVyXG4gICAgICAgICAgICAvLyBhbmQgd2UgYXJlIG5vdyByZS1hZGRpbmcgaXQgd2l0aCBhIGRpZmZlcmVudCBgdHlwZWAsIHRoZW4gd2VcbiAgICAgICAgICAgIC8vIG5lZWQgdG8gY2xlYXIgKHJhdGhlciB0aGFuIGp1c3QgcmVsb2FkKSB0aGUgdW5kZXJ5bGluZyBzb3VyY2Unc1xuICAgICAgICAgICAgLy8gdGlsZXMuICBPdGhlcndpc2UsIHRpbGVzIG1hcmtlZCAncmVsb2FkaW5nJyB3aWxsIGhhdmUgYnVja2V0cyAvXG4gICAgICAgICAgICAvLyBidWZmZXJzIHRoYXQgYXJlIHNldCB1cCBmb3IgdGhlIF9wcmV2aW91c18gdmVyc2lvbiBvZiB0aGlzXG4gICAgICAgICAgICAvLyBsYXllciwgY2F1c2luZywgZS5nLjpcbiAgICAgICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXBib3gvbWFwYm94LWdsLWpzL2lzc3Vlcy8zNjMzXG4gICAgICAgICAgICBjb25zdCByZW1vdmVkID0gdGhpcy5fcmVtb3ZlZExheWVyc1tpZF07XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5fcmVtb3ZlZExheWVyc1tpZF07XG4gICAgICAgICAgICBpZiAocmVtb3ZlZC50eXBlICE9PSBsYXllci50eXBlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdXBkYXRlZFNvdXJjZXNbbGF5ZXIuc291cmNlXSA9ICdjbGVhcic7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZWRTb3VyY2VzW2xheWVyLnNvdXJjZV0gPSAncmVsb2FkJztcbiAgICAgICAgICAgICAgICBzb3VyY2VDYWNoZS5wYXVzZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3VwZGF0ZUxheWVyKGxheWVyKTtcblxuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIGlmIChsYXllci5vbkFkZCkge1xuICAgICAgICAgICAgbGF5ZXIub25BZGQodGhpcy5tYXApO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fdXBkYXRlRHJhcGVGaXJzdExheWVycygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1vdmVzIGEgbGF5ZXIgdG8gYSBkaWZmZXJlbnQgei1wb3NpdGlvbi4gVGhlIGxheWVyIHdpbGwgYmUgaW5zZXJ0ZWQgYmVmb3JlIHRoZSBsYXllciB3aXRoXG4gICAgICogSUQgYGJlZm9yZWAsIG9yIGFwcGVuZGVkIGlmIGBiZWZvcmVgIGlzIG9taXR0ZWQuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGlkICBJRCBvZiB0aGUgbGF5ZXIgdG8gbW92ZS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW2JlZm9yZV0gSUQgb2YgYW4gZXhpc3RpbmcgbGF5ZXIgdG8gaW5zZXJ0IGJlZm9yZS5cbiAgICAgKi9cbiAgICBtb3ZlTGF5ZXIoaWQ6IHN0cmluZywgYmVmb3JlPzogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuX2NoZWNrTG9hZGVkKCk7XG4gICAgICAgIHRoaXMuX2NoYW5nZWQgPSB0cnVlO1xuXG4gICAgICAgIGNvbnN0IGxheWVyID0gdGhpcy5fbGF5ZXJzW2lkXTtcbiAgICAgICAgaWYgKCFsYXllcikge1xuICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFcnJvckV2ZW50KG5ldyBFcnJvcihgVGhlIGxheWVyICcke2lkfScgZG9lcyBub3QgZXhpc3QgaW4gdGhlIG1hcCdzIHN0eWxlIGFuZCBjYW5ub3QgYmUgbW92ZWQuYCkpKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpZCA9PT0gYmVmb3JlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX29yZGVyLmluZGV4T2YoaWQpO1xuICAgICAgICB0aGlzLl9vcmRlci5zcGxpY2UoaW5kZXgsIDEpO1xuXG4gICAgICAgIGNvbnN0IG5ld0luZGV4ID0gYmVmb3JlID8gdGhpcy5fb3JkZXIuaW5kZXhPZihiZWZvcmUpIDogdGhpcy5fb3JkZXIubGVuZ3RoO1xuICAgICAgICBpZiAoYmVmb3JlICYmIG5ld0luZGV4ID09PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFcnJvckV2ZW50KG5ldyBFcnJvcihgTGF5ZXIgd2l0aCBpZCBcIiR7YmVmb3JlfVwiIGRvZXMgbm90IGV4aXN0IG9uIHRoaXMgbWFwLmApKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fb3JkZXIuc3BsaWNlKG5ld0luZGV4LCAwLCBpZCk7XG5cbiAgICAgICAgdGhpcy5fbGF5ZXJPcmRlckNoYW5nZWQgPSB0cnVlO1xuXG4gICAgICAgIHRoaXMuX3VwZGF0ZURyYXBlRmlyc3RMYXllcnMoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgdGhlIGxheWVyIHdpdGggdGhlIGdpdmVuIGlkIGZyb20gdGhlIHN0eWxlLlxuICAgICAqXG4gICAgICogSWYgbm8gc3VjaCBsYXllciBleGlzdHMsIGFuIGBlcnJvcmAgZXZlbnQgaXMgZmlyZWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgSUQgb2YgdGhlIGxheWVyIHRvIHJlbW92ZS5cbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50OmVycm9yXG4gICAgICovXG4gICAgcmVtb3ZlTGF5ZXIoaWQ6IHN0cmluZykge1xuICAgICAgICB0aGlzLl9jaGVja0xvYWRlZCgpO1xuXG4gICAgICAgIGNvbnN0IGxheWVyID0gdGhpcy5fbGF5ZXJzW2lkXTtcbiAgICAgICAgaWYgKCFsYXllcikge1xuICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFcnJvckV2ZW50KG5ldyBFcnJvcihgVGhlIGxheWVyICcke2lkfScgZG9lcyBub3QgZXhpc3QgaW4gdGhlIG1hcCdzIHN0eWxlIGFuZCBjYW5ub3QgYmUgcmVtb3ZlZC5gKSkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgbGF5ZXIuc2V0RXZlbnRlZFBhcmVudChudWxsKTtcblxuICAgICAgICB0aGlzLl91cGRhdGVMYXllckNvdW50KGxheWVyLCBmYWxzZSk7XG5cbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl9vcmRlci5pbmRleE9mKGlkKTtcbiAgICAgICAgdGhpcy5fb3JkZXIuc3BsaWNlKGluZGV4LCAxKTtcblxuICAgICAgICB0aGlzLl9sYXllck9yZGVyQ2hhbmdlZCA9IHRydWU7XG4gICAgICAgIHRoaXMuX2NoYW5nZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLl9yZW1vdmVkTGF5ZXJzW2lkXSA9IGxheWVyO1xuICAgICAgICBkZWxldGUgdGhpcy5fbGF5ZXJzW2lkXTtcbiAgICAgICAgZGVsZXRlIHRoaXMuX3NlcmlhbGl6ZWRMYXllcnNbaWRdO1xuICAgICAgICBkZWxldGUgdGhpcy5fdXBkYXRlZExheWVyc1tpZF07XG4gICAgICAgIGRlbGV0ZSB0aGlzLl91cGRhdGVkUGFpbnRQcm9wc1tpZF07XG5cbiAgICAgICAgaWYgKGxheWVyLm9uUmVtb3ZlKSB7XG4gICAgICAgICAgICBsYXllci5vblJlbW92ZSh0aGlzLm1hcCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl91cGRhdGVEcmFwZUZpcnN0TGF5ZXJzKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBzdHlsZSBsYXllciBvYmplY3Qgd2l0aCB0aGUgZ2l2ZW4gYGlkYC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBpZCBJRCBvZiB0aGUgZGVzaXJlZCBsYXllci5cbiAgICAgKiBAcmV0dXJucyB7P1N0eWxlTGF5ZXJ9IEEgbGF5ZXIsIGlmIG9uZSB3aXRoIHRoZSBnaXZlbiBgaWRgIGV4aXN0cy5cbiAgICAgKi9cbiAgICBnZXRMYXllcihpZDogc3RyaW5nKTogP1N0eWxlTGF5ZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGF5ZXJzW2lkXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYSBzcGVjaWZpYyBsYXllciBpcyBwcmVzZW50IHdpdGhpbiB0aGUgc3R5bGUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgSUQgb2YgdGhlIGRlc2lyZWQgbGF5ZXIuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IEEgYm9vbGVhbiBzcGVjaWZ5aW5nIGlmIHRoZSBnaXZlbiBsYXllciBpcyBwcmVzZW50LlxuICAgICAqL1xuICAgIGhhc0xheWVyKGlkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIGlkIGluIHRoaXMuX2xheWVycztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYSBzcGVjaWZpYyBsYXllciB0eXBlIGlzIHByZXNlbnQgd2l0aGluIHRoZSBzdHlsZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIFR5cGUgb2YgdGhlIGRlc2lyZWQgbGF5ZXIuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IEEgYm9vbGVhbiBzcGVjaWZ5aW5nIGlmIHRoZSBnaXZlbiBsYXllciB0eXBlIGlzIHByZXNlbnQuXG4gICAgICovXG4gICAgaGFzTGF5ZXJUeXBlKHR5cGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICBmb3IgKGNvbnN0IGxheWVySWQgaW4gdGhpcy5fbGF5ZXJzKSB7XG4gICAgICAgICAgICBjb25zdCBsYXllciA9IHRoaXMuX2xheWVyc1tsYXllcklkXTtcbiAgICAgICAgICAgIGlmIChsYXllci50eXBlID09PSB0eXBlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHNldExheWVyWm9vbVJhbmdlKGxheWVySWQ6IHN0cmluZywgbWluem9vbTogP251bWJlciwgbWF4em9vbTogP251bWJlcikge1xuICAgICAgICB0aGlzLl9jaGVja0xvYWRlZCgpO1xuXG4gICAgICAgIGNvbnN0IGxheWVyID0gdGhpcy5nZXRMYXllcihsYXllcklkKTtcbiAgICAgICAgaWYgKCFsYXllcikge1xuICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFcnJvckV2ZW50KG5ldyBFcnJvcihgVGhlIGxheWVyICcke2xheWVySWR9JyBkb2VzIG5vdCBleGlzdCBpbiB0aGUgbWFwJ3Mgc3R5bGUgYW5kIGNhbm5vdCBoYXZlIHpvb20gZXh0ZW50LmApKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobGF5ZXIubWluem9vbSA9PT0gbWluem9vbSAmJiBsYXllci5tYXh6b29tID09PSBtYXh6b29tKSByZXR1cm47XG5cbiAgICAgICAgaWYgKG1pbnpvb20gIT0gbnVsbCkge1xuICAgICAgICAgICAgbGF5ZXIubWluem9vbSA9IG1pbnpvb207XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1heHpvb20gIT0gbnVsbCkge1xuICAgICAgICAgICAgbGF5ZXIubWF4em9vbSA9IG1heHpvb207XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fdXBkYXRlTGF5ZXIobGF5ZXIpO1xuICAgIH1cblxuICAgIHNldEZpbHRlcihsYXllcklkOiBzdHJpbmcsIGZpbHRlcjogP0ZpbHRlclNwZWNpZmljYXRpb24sICBvcHRpb25zOiBTdHlsZVNldHRlck9wdGlvbnMgPSB7fSkge1xuICAgICAgICB0aGlzLl9jaGVja0xvYWRlZCgpO1xuXG4gICAgICAgIGNvbnN0IGxheWVyID0gdGhpcy5nZXRMYXllcihsYXllcklkKTtcbiAgICAgICAgaWYgKCFsYXllcikge1xuICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFcnJvckV2ZW50KG5ldyBFcnJvcihgVGhlIGxheWVyICcke2xheWVySWR9JyBkb2VzIG5vdCBleGlzdCBpbiB0aGUgbWFwJ3Mgc3R5bGUgYW5kIGNhbm5vdCBiZSBmaWx0ZXJlZC5gKSkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRlZXBFcXVhbChsYXllci5maWx0ZXIsIGZpbHRlcikpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmaWx0ZXIgPT09IG51bGwgfHwgZmlsdGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGxheWVyLmZpbHRlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUxheWVyKGxheWVyKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLl92YWxpZGF0ZSh2YWxpZGF0ZUZpbHRlciwgYGxheWVycy4ke2xheWVyLmlkfS5maWx0ZXJgLCBmaWx0ZXIsIHtsYXllclR5cGU6IGxheWVyLnR5cGV9LCBvcHRpb25zKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgbGF5ZXIuZmlsdGVyID0gY2xvbmUoZmlsdGVyKTtcbiAgICAgICAgdGhpcy5fdXBkYXRlTGF5ZXIobGF5ZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBhIGxheWVyJ3MgZmlsdGVyIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbGF5ZXJJZCBUaGUgbGF5ZXIgdG8gaW5zcGVjdC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gVGhlIGxheWVyJ3MgZmlsdGVyLCBpZiBhbnkuXG4gICAgICovXG4gICAgZ2V0RmlsdGVyKGxheWVySWQ6IHN0cmluZyk6ID9GaWx0ZXJTcGVjaWZpY2F0aW9uIHtcbiAgICAgICAgY29uc3QgbGF5ZXIgPSB0aGlzLmdldExheWVyKGxheWVySWQpO1xuICAgICAgICByZXR1cm4gbGF5ZXIgJiYgY2xvbmUobGF5ZXIuZmlsdGVyKTtcbiAgICB9XG5cbiAgICBzZXRMYXlvdXRQcm9wZXJ0eShsYXllcklkOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgdmFsdWU6IGFueSwgIG9wdGlvbnM6IFN0eWxlU2V0dGVyT3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIHRoaXMuX2NoZWNrTG9hZGVkKCk7XG5cbiAgICAgICAgY29uc3QgbGF5ZXIgPSB0aGlzLmdldExheWVyKGxheWVySWQpO1xuICAgICAgICBpZiAoIWxheWVyKSB7XG4gICAgICAgICAgICB0aGlzLmZpcmUobmV3IEVycm9yRXZlbnQobmV3IEVycm9yKGBUaGUgbGF5ZXIgJyR7bGF5ZXJJZH0nIGRvZXMgbm90IGV4aXN0IGluIHRoZSBtYXAncyBzdHlsZSBhbmQgY2Fubm90IGJlIHN0eWxlZC5gKSkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRlZXBFcXVhbChsYXllci5nZXRMYXlvdXRQcm9wZXJ0eShuYW1lKSwgdmFsdWUpKSByZXR1cm47XG5cbiAgICAgICAgbGF5ZXIuc2V0TGF5b3V0UHJvcGVydHkobmFtZSwgdmFsdWUsIG9wdGlvbnMpO1xuICAgICAgICB0aGlzLl91cGRhdGVMYXllcihsYXllcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IGEgbGF5b3V0IHByb3BlcnR5J3MgdmFsdWUgZnJvbSBhIGdpdmVuIGxheWVyLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBsYXllcklkIFRoZSBsYXllciB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBsYXlvdXQgcHJvcGVydHkuXG4gICAgICogQHJldHVybnMgeyp9IFRoZSBwcm9wZXJ0eSB2YWx1ZS5cbiAgICAgKi9cbiAgICBnZXRMYXlvdXRQcm9wZXJ0eShsYXllcklkOiBzdHJpbmcsIG5hbWU6IHN0cmluZyk6ID9Qcm9wZXJ0eVZhbHVlU3BlY2lmaWNhdGlvbjxtaXhlZD4ge1xuICAgICAgICBjb25zdCBsYXllciA9IHRoaXMuZ2V0TGF5ZXIobGF5ZXJJZCk7XG4gICAgICAgIGlmICghbGF5ZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXJyb3JFdmVudChuZXcgRXJyb3IoYFRoZSBsYXllciAnJHtsYXllcklkfScgZG9lcyBub3QgZXhpc3QgaW4gdGhlIG1hcCdzIHN0eWxlLmApKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbGF5ZXIuZ2V0TGF5b3V0UHJvcGVydHkobmFtZSk7XG4gICAgfVxuXG4gICAgc2V0UGFpbnRQcm9wZXJ0eShsYXllcklkOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgdmFsdWU6IGFueSwgb3B0aW9uczogU3R5bGVTZXR0ZXJPcHRpb25zID0ge30pIHtcbiAgICAgICAgdGhpcy5fY2hlY2tMb2FkZWQoKTtcblxuICAgICAgICBjb25zdCBsYXllciA9IHRoaXMuZ2V0TGF5ZXIobGF5ZXJJZCk7XG4gICAgICAgIGlmICghbGF5ZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXJyb3JFdmVudChuZXcgRXJyb3IoYFRoZSBsYXllciAnJHtsYXllcklkfScgZG9lcyBub3QgZXhpc3QgaW4gdGhlIG1hcCdzIHN0eWxlIGFuZCBjYW5ub3QgYmUgc3R5bGVkLmApKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZGVlcEVxdWFsKGxheWVyLmdldFBhaW50UHJvcGVydHkobmFtZSksIHZhbHVlKSkgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IHJlcXVpcmVzUmVsYXlvdXQgPSBsYXllci5zZXRQYWludFByb3BlcnR5KG5hbWUsIHZhbHVlLCBvcHRpb25zKTtcbiAgICAgICAgaWYgKHJlcXVpcmVzUmVsYXlvdXQpIHtcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUxheWVyKGxheWVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2NoYW5nZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLl91cGRhdGVkUGFpbnRQcm9wc1tsYXllcklkXSA9IHRydWU7XG4gICAgfVxuXG4gICAgZ2V0UGFpbnRQcm9wZXJ0eShsYXllcklkOiBzdHJpbmcsIG5hbWU6IHN0cmluZyk6IHZvaWQgfCBUcmFuc2l0aW9uU3BlY2lmaWNhdGlvbiB8IFByb3BlcnR5VmFsdWVTcGVjaWZpY2F0aW9uPG1peGVkPiB7XG4gICAgICAgIGNvbnN0IGxheWVyID0gdGhpcy5nZXRMYXllcihsYXllcklkKTtcbiAgICAgICAgcmV0dXJuIGxheWVyICYmIGxheWVyLmdldFBhaW50UHJvcGVydHkobmFtZSk7XG4gICAgfVxuXG4gICAgc2V0RmVhdHVyZVN0YXRlKHRhcmdldDogeyBzb3VyY2U6IHN0cmluZzsgc291cmNlTGF5ZXI/OiBzdHJpbmc7IGlkOiBzdHJpbmcgfCBudW1iZXI7IH0sIHN0YXRlOiBPYmplY3QpIHtcbiAgICAgICAgdGhpcy5fY2hlY2tMb2FkZWQoKTtcbiAgICAgICAgY29uc3Qgc291cmNlSWQgPSB0YXJnZXQuc291cmNlO1xuICAgICAgICBjb25zdCBzb3VyY2VMYXllciA9IHRhcmdldC5zb3VyY2VMYXllcjtcbiAgICAgICAgY29uc3Qgc291cmNlID0gdGhpcy5nZXRTb3VyY2Uoc291cmNlSWQpO1xuXG4gICAgICAgIGlmICghc291cmNlKSB7XG4gICAgICAgICAgICB0aGlzLmZpcmUobmV3IEVycm9yRXZlbnQobmV3IEVycm9yKGBUaGUgc291cmNlICcke3NvdXJjZUlkfScgZG9lcyBub3QgZXhpc3QgaW4gdGhlIG1hcCdzIHN0eWxlLmApKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc291cmNlVHlwZSA9IHNvdXJjZS50eXBlO1xuICAgICAgICBpZiAoc291cmNlVHlwZSA9PT0gJ2dlb2pzb24nICYmIHNvdXJjZUxheWVyKSB7XG4gICAgICAgICAgICB0aGlzLmZpcmUobmV3IEVycm9yRXZlbnQobmV3IEVycm9yKGBHZW9KU09OIHNvdXJjZXMgY2Fubm90IGhhdmUgYSBzb3VyY2VMYXllciBwYXJhbWV0ZXIuYCkpKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc291cmNlVHlwZSA9PT0gJ3ZlY3RvcicgJiYgIXNvdXJjZUxheWVyKSB7XG4gICAgICAgICAgICB0aGlzLmZpcmUobmV3IEVycm9yRXZlbnQobmV3IEVycm9yKGBUaGUgc291cmNlTGF5ZXIgcGFyYW1ldGVyIG11c3QgYmUgcHJvdmlkZWQgZm9yIHZlY3RvciBzb3VyY2UgdHlwZXMuYCkpKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGFyZ2V0LmlkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXJyb3JFdmVudChuZXcgRXJyb3IoYFRoZSBmZWF0dXJlIGlkIHBhcmFtZXRlciBtdXN0IGJlIHByb3ZpZGVkLmApKSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzb3VyY2VDYWNoZXMgPSB0aGlzLl9nZXRTb3VyY2VDYWNoZXMoc291cmNlSWQpO1xuICAgICAgICBmb3IgKGNvbnN0IHNvdXJjZUNhY2hlIG9mIHNvdXJjZUNhY2hlcykge1xuICAgICAgICAgICAgc291cmNlQ2FjaGUuc2V0RmVhdHVyZVN0YXRlKHNvdXJjZUxheWVyLCB0YXJnZXQuaWQsIHN0YXRlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJlbW92ZUZlYXR1cmVTdGF0ZSh0YXJnZXQ6IHsgc291cmNlOiBzdHJpbmc7IHNvdXJjZUxheWVyPzogc3RyaW5nOyBpZD86IHN0cmluZyB8IG51bWJlcjsgfSwga2V5Pzogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuX2NoZWNrTG9hZGVkKCk7XG4gICAgICAgIGNvbnN0IHNvdXJjZUlkID0gdGFyZ2V0LnNvdXJjZTtcbiAgICAgICAgY29uc3Qgc291cmNlID0gdGhpcy5nZXRTb3VyY2Uoc291cmNlSWQpO1xuXG4gICAgICAgIGlmICghc291cmNlKSB7XG4gICAgICAgICAgICB0aGlzLmZpcmUobmV3IEVycm9yRXZlbnQobmV3IEVycm9yKGBUaGUgc291cmNlICcke3NvdXJjZUlkfScgZG9lcyBub3QgZXhpc3QgaW4gdGhlIG1hcCdzIHN0eWxlLmApKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzb3VyY2VUeXBlID0gc291cmNlLnR5cGU7XG4gICAgICAgIGNvbnN0IHNvdXJjZUxheWVyID0gc291cmNlVHlwZSA9PT0gJ3ZlY3RvcicgPyB0YXJnZXQuc291cmNlTGF5ZXIgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgaWYgKHNvdXJjZVR5cGUgPT09ICd2ZWN0b3InICYmICFzb3VyY2VMYXllcikge1xuICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFcnJvckV2ZW50KG5ldyBFcnJvcihgVGhlIHNvdXJjZUxheWVyIHBhcmFtZXRlciBtdXN0IGJlIHByb3ZpZGVkIGZvciB2ZWN0b3Igc291cmNlIHR5cGVzLmApKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoa2V5ICYmICh0eXBlb2YgdGFyZ2V0LmlkICE9PSAnc3RyaW5nJyAmJiB0eXBlb2YgdGFyZ2V0LmlkICE9PSAnbnVtYmVyJykpIHtcbiAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXJyb3JFdmVudChuZXcgRXJyb3IoYEEgZmVhdHVyZSBpZCBpcyByZXF1aXJlZCB0byByZW1vdmUgaXRzIHNwZWNpZmljIHN0YXRlIHByb3BlcnR5LmApKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzb3VyY2VDYWNoZXMgPSB0aGlzLl9nZXRTb3VyY2VDYWNoZXMoc291cmNlSWQpO1xuICAgICAgICBmb3IgKGNvbnN0IHNvdXJjZUNhY2hlIG9mIHNvdXJjZUNhY2hlcykge1xuICAgICAgICAgICAgc291cmNlQ2FjaGUucmVtb3ZlRmVhdHVyZVN0YXRlKHNvdXJjZUxheWVyLCB0YXJnZXQuaWQsIGtleSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRGZWF0dXJlU3RhdGUodGFyZ2V0OiB7IHNvdXJjZTogc3RyaW5nOyBzb3VyY2VMYXllcj86IHN0cmluZzsgaWQ6IHN0cmluZyB8IG51bWJlcjsgfSk6ID9GZWF0dXJlU3RhdGVzIHtcbiAgICAgICAgdGhpcy5fY2hlY2tMb2FkZWQoKTtcbiAgICAgICAgY29uc3Qgc291cmNlSWQgPSB0YXJnZXQuc291cmNlO1xuICAgICAgICBjb25zdCBzb3VyY2VMYXllciA9IHRhcmdldC5zb3VyY2VMYXllcjtcbiAgICAgICAgY29uc3Qgc291cmNlID0gdGhpcy5nZXRTb3VyY2Uoc291cmNlSWQpO1xuXG4gICAgICAgIGlmICghc291cmNlKSB7XG4gICAgICAgICAgICB0aGlzLmZpcmUobmV3IEVycm9yRXZlbnQobmV3IEVycm9yKGBUaGUgc291cmNlICcke3NvdXJjZUlkfScgZG9lcyBub3QgZXhpc3QgaW4gdGhlIG1hcCdzIHN0eWxlLmApKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc291cmNlVHlwZSA9IHNvdXJjZS50eXBlO1xuICAgICAgICBpZiAoc291cmNlVHlwZSA9PT0gJ3ZlY3RvcicgJiYgIXNvdXJjZUxheWVyKSB7XG4gICAgICAgICAgICB0aGlzLmZpcmUobmV3IEVycm9yRXZlbnQobmV3IEVycm9yKGBUaGUgc291cmNlTGF5ZXIgcGFyYW1ldGVyIG11c3QgYmUgcHJvdmlkZWQgZm9yIHZlY3RvciBzb3VyY2UgdHlwZXMuYCkpKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGFyZ2V0LmlkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXJyb3JFdmVudChuZXcgRXJyb3IoYFRoZSBmZWF0dXJlIGlkIHBhcmFtZXRlciBtdXN0IGJlIHByb3ZpZGVkLmApKSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzb3VyY2VDYWNoZXMgPSB0aGlzLl9nZXRTb3VyY2VDYWNoZXMoc291cmNlSWQpO1xuICAgICAgICByZXR1cm4gc291cmNlQ2FjaGVzWzBdLmdldEZlYXR1cmVTdGF0ZShzb3VyY2VMYXllciwgdGFyZ2V0LmlkKTtcbiAgICB9XG5cbiAgICBnZXRUcmFuc2l0aW9uKCk6IFRyYW5zaXRpb25TcGVjaWZpY2F0aW9uIHtcbiAgICAgICAgcmV0dXJuIGV4dGVuZCh7ZHVyYXRpb246IDMwMCwgZGVsYXk6IDB9LCB0aGlzLnN0eWxlc2hlZXQgJiYgdGhpcy5zdHlsZXNoZWV0LnRyYW5zaXRpb24pO1xuICAgIH1cblxuICAgIHNlcmlhbGl6ZSgpOiBTdHlsZVNwZWNpZmljYXRpb24ge1xuICAgICAgICBjb25zdCBzb3VyY2VzID0ge307XG4gICAgICAgIGZvciAoY29uc3QgY2FjaGVJZCBpbiB0aGlzLl9zb3VyY2VDYWNoZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IHRoaXMuX3NvdXJjZUNhY2hlc1tjYWNoZUlkXS5nZXRTb3VyY2UoKTtcbiAgICAgICAgICAgIGlmICghc291cmNlc1tzb3VyY2UuaWRdKSB7XG4gICAgICAgICAgICAgICAgc291cmNlc1tzb3VyY2UuaWRdID0gc291cmNlLnNlcmlhbGl6ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZpbHRlck9iamVjdCh7XG4gICAgICAgICAgICB2ZXJzaW9uOiB0aGlzLnN0eWxlc2hlZXQudmVyc2lvbixcbiAgICAgICAgICAgIG5hbWU6IHRoaXMuc3R5bGVzaGVldC5uYW1lLFxuICAgICAgICAgICAgbWV0YWRhdGE6IHRoaXMuc3R5bGVzaGVldC5tZXRhZGF0YSxcbiAgICAgICAgICAgIGxpZ2h0OiB0aGlzLnN0eWxlc2hlZXQubGlnaHQsXG4gICAgICAgICAgICB0ZXJyYWluOiB0aGlzLmdldFRlcnJhaW4oKSB8fCB1bmRlZmluZWQsXG4gICAgICAgICAgICBmb2c6IHRoaXMuc3R5bGVzaGVldC5mb2csXG4gICAgICAgICAgICBjZW50ZXI6IHRoaXMuc3R5bGVzaGVldC5jZW50ZXIsXG4gICAgICAgICAgICB6b29tOiB0aGlzLnN0eWxlc2hlZXQuem9vbSxcbiAgICAgICAgICAgIGJlYXJpbmc6IHRoaXMuc3R5bGVzaGVldC5iZWFyaW5nLFxuICAgICAgICAgICAgcGl0Y2g6IHRoaXMuc3R5bGVzaGVldC5waXRjaCxcbiAgICAgICAgICAgIHNwcml0ZTogdGhpcy5zdHlsZXNoZWV0LnNwcml0ZSxcbiAgICAgICAgICAgIGdseXBoczogdGhpcy5zdHlsZXNoZWV0LmdseXBocyxcbiAgICAgICAgICAgIHRyYW5zaXRpb246IHRoaXMuc3R5bGVzaGVldC50cmFuc2l0aW9uLFxuICAgICAgICAgICAgcHJvamVjdGlvbjogdGhpcy5zdHlsZXNoZWV0LnByb2plY3Rpb24sXG4gICAgICAgICAgICBzb3VyY2VzLFxuICAgICAgICAgICAgbGF5ZXJzOiB0aGlzLl9zZXJpYWxpemVMYXllcnModGhpcy5fb3JkZXIpXG4gICAgICAgIH0sICh2YWx1ZSkgPT4geyByZXR1cm4gdmFsdWUgIT09IHVuZGVmaW5lZDsgfSk7XG4gICAgfVxuXG4gICAgX3VwZGF0ZUxheWVyKGxheWVyOiBTdHlsZUxheWVyKSB7XG4gICAgICAgIHRoaXMuX3VwZGF0ZWRMYXllcnNbbGF5ZXIuaWRdID0gdHJ1ZTtcbiAgICAgICAgY29uc3Qgc291cmNlQ2FjaGUgPSB0aGlzLl9nZXRMYXllclNvdXJjZUNhY2hlKGxheWVyKTtcbiAgICAgICAgaWYgKGxheWVyLnNvdXJjZSAmJiAhdGhpcy5fdXBkYXRlZFNvdXJjZXNbbGF5ZXIuc291cmNlXSAmJlxuICAgICAgICAgICAgLy9Ta2lwIGZvciByYXN0ZXIgbGF5ZXJzIChodHRwczovL2dpdGh1Yi5jb20vbWFwYm94L21hcGJveC1nbC1qcy9pc3N1ZXMvNzg2NSlcbiAgICAgICAgICAgIHNvdXJjZUNhY2hlICYmXG4gICAgICAgICAgICBzb3VyY2VDYWNoZS5nZXRTb3VyY2UoKS50eXBlICE9PSAncmFzdGVyJykge1xuICAgICAgICAgICAgdGhpcy5fdXBkYXRlZFNvdXJjZXNbbGF5ZXIuc291cmNlXSA9ICdyZWxvYWQnO1xuICAgICAgICAgICAgc291cmNlQ2FjaGUucGF1c2UoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9jaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgbGF5ZXIuaW52YWxpZGF0ZUNvbXBpbGVkRmlsdGVyKCk7XG5cbiAgICB9XG5cbiAgICBfZmxhdHRlbkFuZFNvcnRSZW5kZXJlZEZlYXR1cmVzKHNvdXJjZVJlc3VsdHM6IEFycmF5PGFueT4pOiBBcnJheTxtaXhlZD4ge1xuICAgICAgICAvLyBGZWF0dXJlIG9yZGVyIGlzIGNvbXBsaWNhdGVkLlxuICAgICAgICAvLyBUaGUgb3JkZXIgYmV0d2VlbiBmZWF0dXJlcyBpbiB0d28gMkQgbGF5ZXJzIGlzIGFsd2F5cyBkZXRlcm1pbmVkIGJ5IGxheWVyIG9yZGVyLlxuICAgICAgICAvLyBUaGUgb3JkZXIgYmV0d2VlbiBmZWF0dXJlcyBpbiB0d28gM0QgbGF5ZXJzIGlzIGFsd2F5cyBkZXRlcm1pbmVkIGJ5IGRlcHRoLlxuICAgICAgICAvLyBUaGUgb3JkZXIgYmV0d2VlbiBhIGZlYXR1cmUgaW4gYSAyRCBsYXllciBhbmQgYSAzRCBsYXllciBpcyB0cmlja3k6XG4gICAgICAgIC8vICAgICAgTW9zdCBvZnRlbiBsYXllciBvcmRlciBkZXRlcm1pbmVzIHRoZSBmZWF0dXJlIG9yZGVyIGluIHRoaXMgY2FzZS4gSWZcbiAgICAgICAgLy8gICAgICBhIGxpbmUgbGF5ZXIgaXMgYWJvdmUgYSBleHRydXNpb24gbGF5ZXIgdGhlIGxpbmUgZmVhdHVyZSB3aWxsIGJlIHJlbmRlcmVkXG4gICAgICAgIC8vICAgICAgYWJvdmUgdGhlIGV4dHJ1c2lvbi4gSWYgdGhlIGxpbmUgbGF5ZXIgaXMgYmVsb3cgdGhlIGV4dHJ1c2lvbiBsYXllcixcbiAgICAgICAgLy8gICAgICBpdCB3aWxsIGJlIHJlbmRlcmVkIGJlbG93IGl0LlxuICAgICAgICAvL1xuICAgICAgICAvLyAgICAgIFRoZXJlIGlzIGEgd2VpcmQgY2FzZSB0aG91Z2guXG4gICAgICAgIC8vICAgICAgWW91IGhhdmUgbGF5ZXJzIGluIHRoaXMgb3JkZXI6IGV4dHJ1c2lvbl9sYXllcl9hLCBsaW5lX2xheWVyLCBleHRydXNpb25fbGF5ZXJfYlxuICAgICAgICAvLyAgICAgIEVhY2ggbGF5ZXIgaGFzIGEgZmVhdHVyZSB0aGF0IG92ZXJsYXBzIHRoZSBvdGhlciBmZWF0dXJlcy5cbiAgICAgICAgLy8gICAgICBUaGUgZmVhdHVyZSBpbiBleHRydXNpb25fbGF5ZXJfYSBpcyBjbG9zZXIgdGhhbiB0aGUgZmVhdHVyZSBpbiBleHRydXNpb25fbGF5ZXJfYiBzbyBpdCBpcyByZW5kZXJlZCBhYm92ZS5cbiAgICAgICAgLy8gICAgICBUaGUgZmVhdHVyZSBpbiBsaW5lX2xheWVyIGlzIHJlbmRlcmVkIGFib3ZlIGV4dHJ1c2lvbl9sYXllcl9hLlxuICAgICAgICAvLyAgICAgIFRoaXMgbWVhbnMgdGhhdCB0aGF0IHRoZSBsaW5lX2xheWVyIGZlYXR1cmUgaXMgYWJvdmUgdGhlIGV4dHJ1c2lvbl9sYXllcl9iIGZlYXR1cmUgZGVzcGl0ZVxuICAgICAgICAvLyAgICAgIGl0IGJlaW5nIGluIGFuIGVhcmxpZXIgbGF5ZXIuXG5cbiAgICAgICAgY29uc3QgaXNMYXllcjNEID0gKGxheWVySWQ6IHN0cmluZykgPT4gdGhpcy5fbGF5ZXJzW2xheWVySWRdLnR5cGUgPT09ICdmaWxsLWV4dHJ1c2lvbic7XG5cbiAgICAgICAgY29uc3QgbGF5ZXJJbmRleCA9IHt9O1xuICAgICAgICBjb25zdCBmZWF0dXJlczNEID0gW107XG4gICAgICAgIGZvciAobGV0IGwgPSB0aGlzLl9vcmRlci5sZW5ndGggLSAxOyBsID49IDA7IGwtLSkge1xuICAgICAgICAgICAgY29uc3QgbGF5ZXJJZCA9IHRoaXMuX29yZGVyW2xdO1xuICAgICAgICAgICAgaWYgKGlzTGF5ZXIzRChsYXllcklkKSkge1xuICAgICAgICAgICAgICAgIGxheWVySW5kZXhbbGF5ZXJJZF0gPSBsO1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qgc291cmNlUmVzdWx0IG9mIHNvdXJjZVJlc3VsdHMpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbGF5ZXJGZWF0dXJlcyA9IHNvdXJjZVJlc3VsdFtsYXllcklkXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxheWVyRmVhdHVyZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgZmVhdHVyZVdyYXBwZXIgb2YgbGF5ZXJGZWF0dXJlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZlYXR1cmVzM0QucHVzaChmZWF0dXJlV3JhcHBlcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmZWF0dXJlczNELnNvcnQoKGEsIGIpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBiLmludGVyc2VjdGlvblogLSBhLmludGVyc2VjdGlvblo7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGZlYXR1cmVzID0gW107XG4gICAgICAgIGZvciAobGV0IGwgPSB0aGlzLl9vcmRlci5sZW5ndGggLSAxOyBsID49IDA7IGwtLSkge1xuICAgICAgICAgICAgY29uc3QgbGF5ZXJJZCA9IHRoaXMuX29yZGVyW2xdO1xuXG4gICAgICAgICAgICBpZiAoaXNMYXllcjNEKGxheWVySWQpKSB7XG4gICAgICAgICAgICAgICAgLy8gYWRkIGFsbCAzRCBmZWF0dXJlcyB0aGF0IGFyZSBpbiBvciBhYm92ZSB0aGUgY3VycmVudCBsYXllclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSBmZWF0dXJlczNELmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRvcG1vc3QzRCA9IGZlYXR1cmVzM0RbaV0uZmVhdHVyZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxheWVySW5kZXhbdG9wbW9zdDNELmxheWVyLmlkXSA8IGwpIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBmZWF0dXJlcy5wdXNoKHRvcG1vc3QzRCk7XG4gICAgICAgICAgICAgICAgICAgIGZlYXR1cmVzM0QucG9wKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHNvdXJjZVJlc3VsdCBvZiBzb3VyY2VSZXN1bHRzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGxheWVyRmVhdHVyZXMgPSBzb3VyY2VSZXN1bHRbbGF5ZXJJZF07XG4gICAgICAgICAgICAgICAgICAgIGlmIChsYXllckZlYXR1cmVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGZlYXR1cmVXcmFwcGVyIG9mIGxheWVyRmVhdHVyZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZWF0dXJlcy5wdXNoKGZlYXR1cmVXcmFwcGVyLmZlYXR1cmUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZlYXR1cmVzO1xuICAgIH1cblxuICAgIHF1ZXJ5UmVuZGVyZWRGZWF0dXJlcyhxdWVyeUdlb21ldHJ5OiBQb2ludExpa2UgfCBbUG9pbnRMaWtlLCBQb2ludExpa2VdLCBwYXJhbXM6IGFueSwgdHJhbnNmb3JtOiBUcmFuc2Zvcm0pOiBBcnJheTxRdWVyeVJlc3VsdD4ge1xuICAgICAgICBpZiAocGFyYW1zICYmIHBhcmFtcy5maWx0ZXIpIHtcbiAgICAgICAgICAgIHRoaXMuX3ZhbGlkYXRlKHZhbGlkYXRlRmlsdGVyLCAncXVlcnlSZW5kZXJlZEZlYXR1cmVzLmZpbHRlcicsIHBhcmFtcy5maWx0ZXIsIG51bGwsIHBhcmFtcyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBpbmNsdWRlZFNvdXJjZXMgPSB7fTtcbiAgICAgICAgaWYgKHBhcmFtcyAmJiBwYXJhbXMubGF5ZXJzKSB7XG4gICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkocGFyYW1zLmxheWVycykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpcmUobmV3IEVycm9yRXZlbnQobmV3IEVycm9yKCdwYXJhbWV0ZXJzLmxheWVycyBtdXN0IGJlIGFuIEFycmF5LicpKSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChjb25zdCBsYXllcklkIG9mIHBhcmFtcy5sYXllcnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBsYXllciA9IHRoaXMuX2xheWVyc1tsYXllcklkXTtcbiAgICAgICAgICAgICAgICBpZiAoIWxheWVyKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgbGF5ZXIgaXMgbm90IGluIHRoZSBzdHlsZS5sYXllcnMgYXJyYXlcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFcnJvckV2ZW50KG5ldyBFcnJvcihgVGhlIGxheWVyICcke2xheWVySWR9JyBkb2VzIG5vdCBleGlzdCBpbiB0aGUgbWFwJ3Mgc3R5bGUgYW5kIGNhbm5vdCBiZSBxdWVyaWVkIGZvciBmZWF0dXJlcy5gKSkpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGluY2x1ZGVkU291cmNlc1tsYXllci5zb3VyY2VdID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNvdXJjZVJlc3VsdHM6IEFycmF5PFF1ZXJ5UmVzdWx0PiA9IFtdO1xuXG4gICAgICAgIHBhcmFtcy5hdmFpbGFibGVJbWFnZXMgPSB0aGlzLl9hdmFpbGFibGVJbWFnZXM7XG5cbiAgICAgICAgY29uc3QgaGFzM0RMYXllciA9IChwYXJhbXMgJiYgcGFyYW1zLmxheWVycykgP1xuICAgICAgICAgICAgcGFyYW1zLmxheWVycy5zb21lKChsYXllcklkKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgbGF5ZXIgPSB0aGlzLmdldExheWVyKGxheWVySWQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBsYXllciAmJiBsYXllci5pczNEKCk7XG4gICAgICAgICAgICB9KSA6XG4gICAgICAgICAgICB0aGlzLmhhczNETGF5ZXJzKCk7XG4gICAgICAgIGNvbnN0IHF1ZXJ5R2VvbWV0cnlTdHJ1Y3QgPSBRdWVyeUdlb21ldHJ5LmNyZWF0ZUZyb21TY3JlZW5Qb2ludHMocXVlcnlHZW9tZXRyeSwgdHJhbnNmb3JtKTtcblxuICAgICAgICBmb3IgKGNvbnN0IGlkIGluIHRoaXMuX3NvdXJjZUNhY2hlcykge1xuICAgICAgICAgICAgY29uc3Qgc291cmNlSWQgPSB0aGlzLl9zb3VyY2VDYWNoZXNbaWRdLmdldFNvdXJjZSgpLmlkO1xuICAgICAgICAgICAgaWYgKHBhcmFtcy5sYXllcnMgJiYgIWluY2x1ZGVkU291cmNlc1tzb3VyY2VJZF0pIGNvbnRpbnVlO1xuICAgICAgICAgICAgc291cmNlUmVzdWx0cy5wdXNoKFxuICAgICAgICAgICAgICAgIHF1ZXJ5UmVuZGVyZWRGZWF0dXJlcyhcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc291cmNlQ2FjaGVzW2lkXSxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbGF5ZXJzLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zZXJpYWxpemVkTGF5ZXJzLFxuICAgICAgICAgICAgICAgICAgICBxdWVyeUdlb21ldHJ5U3RydWN0LFxuICAgICAgICAgICAgICAgICAgICBwYXJhbXMsXG4gICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybSxcbiAgICAgICAgICAgICAgICAgICAgaGFzM0RMYXllcixcbiAgICAgICAgICAgICAgICAgICAgISF0aGlzLm1hcC5fc2hvd1F1ZXJ5R2VvbWV0cnkpXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMucGxhY2VtZW50KSB7XG4gICAgICAgICAgICAvLyBJZiBhIHBsYWNlbWVudCBoYXMgcnVuLCBxdWVyeSBhZ2FpbnN0IGl0cyBDb2xsaXNpb25JbmRleFxuICAgICAgICAgICAgLy8gZm9yIHN5bWJvbCByZXN1bHRzLCBhbmQgdHJlYXQgaXQgYXMgYW4gZXh0cmEgc291cmNlIHRvIG1lcmdlXG4gICAgICAgICAgICBzb3VyY2VSZXN1bHRzLnB1c2goXG4gICAgICAgICAgICAgICAgcXVlcnlSZW5kZXJlZFN5bWJvbHMoXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2xheWVycyxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2VyaWFsaXplZExheWVycyxcbiAgICAgICAgICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9nZXRMYXllclNvdXJjZUNhY2hlLmJpbmQodGhpcyksXG4gICAgICAgICAgICAgICAgICAgIHF1ZXJ5R2VvbWV0cnlTdHJ1Y3Quc2NyZWVuR2VvbWV0cnksXG4gICAgICAgICAgICAgICAgICAgIHBhcmFtcyxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGFjZW1lbnQuY29sbGlzaW9uSW5kZXgsXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2VtZW50LnJldGFpbmVkUXVlcnlEYXRhKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAodGhpcy5fZmxhdHRlbkFuZFNvcnRSZW5kZXJlZEZlYXR1cmVzKHNvdXJjZVJlc3VsdHMpOiBhbnkpO1xuICAgIH1cblxuICAgIHF1ZXJ5U291cmNlRmVhdHVyZXMoc291cmNlSUQ6IHN0cmluZywgcGFyYW1zOiA/e3NvdXJjZUxheWVyOiA/c3RyaW5nLCBmaWx0ZXI6ID9BcnJheTxhbnk+LCB2YWxpZGF0ZT86IGJvb2xlYW59KTogQXJyYXk8UXVlcnlGZWF0dXJlPiB7XG4gICAgICAgIGlmIChwYXJhbXMgJiYgcGFyYW1zLmZpbHRlcikge1xuICAgICAgICAgICAgdGhpcy5fdmFsaWRhdGUodmFsaWRhdGVGaWx0ZXIsICdxdWVyeVNvdXJjZUZlYXR1cmVzLmZpbHRlcicsIHBhcmFtcy5maWx0ZXIsIG51bGwsIHBhcmFtcyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc291cmNlQ2FjaGVzID0gdGhpcy5fZ2V0U291cmNlQ2FjaGVzKHNvdXJjZUlEKTtcbiAgICAgICAgbGV0IHJlc3VsdHMgPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBzb3VyY2VDYWNoZSBvZiBzb3VyY2VDYWNoZXMpIHtcbiAgICAgICAgICAgIHJlc3VsdHMgPSByZXN1bHRzLmNvbmNhdChxdWVyeVNvdXJjZUZlYXR1cmVzKHNvdXJjZUNhY2hlLCBwYXJhbXMpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICB9XG5cbiAgICBhZGRTb3VyY2VUeXBlKG5hbWU6IHN0cmluZywgU291cmNlVHlwZTogU291cmNlQ2xhc3MsIGNhbGxiYWNrOiBDYWxsYmFjazx2b2lkPik6IHZvaWQge1xuICAgICAgICBpZiAoU3R5bGUuZ2V0U291cmNlVHlwZShuYW1lKSkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG5ldyBFcnJvcihgQSBzb3VyY2UgdHlwZSBjYWxsZWQgXCIke25hbWV9XCIgYWxyZWFkeSBleGlzdHMuYCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgU3R5bGUuc2V0U291cmNlVHlwZShuYW1lLCBTb3VyY2VUeXBlKTtcblxuICAgICAgICBpZiAoIVNvdXJjZVR5cGUud29ya2VyU291cmNlVVJMKSB7XG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgbnVsbCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmRpc3BhdGNoZXIuYnJvYWRjYXN0KCdsb2FkV29ya2VyU291cmNlJywge1xuICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgIHVybDogU291cmNlVHlwZS53b3JrZXJTb3VyY2VVUkxcbiAgICAgICAgfSwgY2FsbGJhY2spO1xuICAgIH1cblxuICAgIGdldExpZ2h0KCk6IExpZ2h0U3BlY2lmaWNhdGlvbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmxpZ2h0LmdldExpZ2h0KCk7XG4gICAgfVxuXG4gICAgc2V0TGlnaHQobGlnaHRPcHRpb25zOiBMaWdodFNwZWNpZmljYXRpb24sIG9wdGlvbnM6IFN0eWxlU2V0dGVyT3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIHRoaXMuX2NoZWNrTG9hZGVkKCk7XG5cbiAgICAgICAgY29uc3QgbGlnaHQgPSB0aGlzLmxpZ2h0LmdldExpZ2h0KCk7XG4gICAgICAgIGxldCBfdXBkYXRlID0gZmFsc2U7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIGxpZ2h0T3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKCFkZWVwRXF1YWwobGlnaHRPcHRpb25zW2tleV0sIGxpZ2h0W2tleV0pKSB7XG4gICAgICAgICAgICAgICAgX3VwZGF0ZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFfdXBkYXRlKSByZXR1cm47XG5cbiAgICAgICAgY29uc3QgcGFyYW1ldGVycyA9IHRoaXMuX3NldFRyYW5zaXRpb25QYXJhbWV0ZXJzKHtkdXJhdGlvbjogMzAwLCBkZWxheTogMH0pO1xuXG4gICAgICAgIHRoaXMubGlnaHQuc2V0TGlnaHQobGlnaHRPcHRpb25zLCBvcHRpb25zKTtcbiAgICAgICAgdGhpcy5saWdodC51cGRhdGVUcmFuc2l0aW9ucyhwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICBnZXRUZXJyYWluKCk6ID9UZXJyYWluU3BlY2lmaWNhdGlvbiB7XG4gICAgICAgIHJldHVybiB0aGlzLnRlcnJhaW4gJiYgdGhpcy50ZXJyYWluLmRyYXBlUmVuZGVyTW9kZSA9PT0gRHJhcGVSZW5kZXJNb2RlLmVsZXZhdGVkID8gdGhpcy50ZXJyYWluLmdldCgpIDogbnVsbDtcbiAgICB9XG5cbiAgICBzZXRUZXJyYWluRm9yRHJhcGluZygpIHtcbiAgICAgICAgY29uc3QgbW9ja1RlcnJhaW5PcHRpb25zID0ge3NvdXJjZTogJycsIGV4YWdnZXJhdGlvbjogMH07XG4gICAgICAgIHRoaXMuc2V0VGVycmFpbihtb2NrVGVycmFpbk9wdGlvbnMsIERyYXBlUmVuZGVyTW9kZS5kZWZlcnJlZCk7XG4gICAgfVxuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXdhcm5pbmctY29tbWVudHNcbiAgICAvLyBUT0RPOiBnZW5lcmljIGFwcHJvYWNoIGZvciByb290IGxldmVsIHByb3BlcnR5OiBsaWdodCwgdGVycmFpbiwgc2t5Ym94LlxuICAgIC8vIEl0IGlzIG5vdCBkb25lIGhlcmUgdG8gcHJldmVudCByZWJhc2luZyBpc3N1ZXMuXG4gICAgc2V0VGVycmFpbih0ZXJyYWluT3B0aW9uczogP1RlcnJhaW5TcGVjaWZpY2F0aW9uLCBkcmFwZVJlbmRlck1vZGU6IG51bWJlciA9IERyYXBlUmVuZGVyTW9kZS5lbGV2YXRlZCkge1xuICAgICAgICB0aGlzLl9jaGVja0xvYWRlZCgpO1xuXG4gICAgICAgIC8vIERpc2FibGluZ1xuICAgICAgICBpZiAoIXRlcnJhaW5PcHRpb25zKSB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy50ZXJyYWluO1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3R5bGVzaGVldC50ZXJyYWluO1xuICAgICAgICAgICAgdGhpcy5kaXNwYXRjaGVyLmJyb2FkY2FzdCgnZW5hYmxlVGVycmFpbicsIGZhbHNlKTtcbiAgICAgICAgICAgIHRoaXMuX2ZvcmNlM0RMYXllclVwZGF0ZSgpO1xuICAgICAgICAgICAgdGhpcy5fbWFya2Vyc05lZWRVcGRhdGUgPSB0cnVlO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IG9wdGlvbnM6IFRlcnJhaW5TcGVjaWZpY2F0aW9uID0gdGVycmFpbk9wdGlvbnM7XG4gICAgICAgIGlmIChkcmFwZVJlbmRlck1vZGUgPT09IERyYXBlUmVuZGVyTW9kZS5lbGV2YXRlZCkge1xuICAgICAgICAgICAgLy8gSW5wdXQgdmFsaWRhdGlvbiBhbmQgc291cmNlIG9iamVjdCB1bnJvbGxpbmdcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5zb3VyY2UgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaWQgPSAndGVycmFpbi1kZW0tc3JjJztcbiAgICAgICAgICAgICAgICB0aGlzLmFkZFNvdXJjZShpZCwgb3B0aW9ucy5zb3VyY2UpO1xuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBjbG9uZShvcHRpb25zKTtcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gZXh0ZW5kKG9wdGlvbnMsIHtzb3VyY2U6IGlkfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLl92YWxpZGF0ZSh2YWxpZGF0ZVRlcnJhaW4sICd0ZXJyYWluJywgb3B0aW9ucykpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBFbmFibGluZ1xuICAgICAgICBpZiAoIXRoaXMudGVycmFpbiB8fCAodGhpcy50ZXJyYWluICYmIGRyYXBlUmVuZGVyTW9kZSAhPT0gdGhpcy50ZXJyYWluLmRyYXBlUmVuZGVyTW9kZSkpIHtcbiAgICAgICAgICAgIGlmICghb3B0aW9ucykgcmV0dXJuO1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRlVGVycmFpbihvcHRpb25zLCBkcmFwZVJlbmRlck1vZGUpO1xuICAgICAgICB9IGVsc2UgeyAvLyBVcGRhdGluZ1xuICAgICAgICAgICAgY29uc3QgdGVycmFpbiA9IHRoaXMudGVycmFpbjtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJTcGVjID0gdGVycmFpbi5nZXQoKTtcblxuICAgICAgICAgICAgZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKHN0eWxlU3BlYy50ZXJyYWluKSkge1xuICAgICAgICAgICAgICAgIC8vIEZhbGxiYWNrIHRvIHVzZSBkZWZhdWx0IHN0eWxlIHNwZWNpZmljYXRpb24gd2hlbiB0aGUgcHJvcGVydGllcyB3YXNuJ3Qgc2V0XG4gICAgICAgICAgICAgICAgaWYgKCFvcHRpb25zLmhhc093blByb3BlcnR5KG5hbWUpICYmICEhc3R5bGVTcGVjLnRlcnJhaW5bbmFtZV0uZGVmYXVsdCkge1xuICAgICAgICAgICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW3Byb3AtbWlzc2luZ11cbiAgICAgICAgICAgICAgICAgICAgb3B0aW9uc1tuYW1lXSA9IHN0eWxlU3BlYy50ZXJyYWluW25hbWVdLmRlZmF1bHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gb3B0aW9ucykge1xuICAgICAgICAgICAgICAgIGlmICghZGVlcEVxdWFsKG9wdGlvbnNba2V5XSwgY3VyclNwZWNba2V5XSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGVycmFpbi5zZXQob3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3R5bGVzaGVldC50ZXJyYWluID0gb3B0aW9ucztcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFyYW1ldGVycyA9IHRoaXMuX3NldFRyYW5zaXRpb25QYXJhbWV0ZXJzKHtkdXJhdGlvbjogMH0pO1xuICAgICAgICAgICAgICAgICAgICB0ZXJyYWluLnVwZGF0ZVRyYW5zaXRpb25zKHBhcmFtZXRlcnMpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl91cGRhdGVEcmFwZUZpcnN0TGF5ZXJzKCk7XG4gICAgICAgIHRoaXMuX21hcmtlcnNOZWVkVXBkYXRlID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBfY3JlYXRlRm9nKGZvZ09wdGlvbnM6IEZvZ1NwZWNpZmljYXRpb24pIHtcbiAgICAgICAgY29uc3QgZm9nID0gdGhpcy5mb2cgPSBuZXcgRm9nKGZvZ09wdGlvbnMsIHRoaXMubWFwLnRyYW5zZm9ybSk7XG4gICAgICAgIHRoaXMuc3R5bGVzaGVldC5mb2cgPSBmb2dPcHRpb25zO1xuICAgICAgICBjb25zdCBwYXJhbWV0ZXJzID0gdGhpcy5fc2V0VHJhbnNpdGlvblBhcmFtZXRlcnMoe2R1cmF0aW9uOiAwfSk7XG4gICAgICAgIGZvZy51cGRhdGVUcmFuc2l0aW9ucyhwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICBfdXBkYXRlTWFya2Vyc09wYWNpdHkoKSB7XG4gICAgICAgIGlmICh0aGlzLm1hcC5fbWFya2Vycy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm1hcC5fcmVxdWVzdERvbVRhc2soKCkgPT4ge1xuICAgICAgICAgICAgZm9yIChjb25zdCBtYXJrZXIgb2YgdGhpcy5tYXAuX21hcmtlcnMpIHtcbiAgICAgICAgICAgICAgICBtYXJrZXIuX2V2YWx1YXRlT3BhY2l0eSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBnZXRGb2coKTogP0ZvZ1NwZWNpZmljYXRpb24ge1xuICAgICAgICByZXR1cm4gdGhpcy5mb2cgPyB0aGlzLmZvZy5nZXQoKSA6IG51bGw7XG4gICAgfVxuXG4gICAgc2V0Rm9nKGZvZ09wdGlvbnM6IEZvZ1NwZWNpZmljYXRpb24pIHtcbiAgICAgICAgdGhpcy5fY2hlY2tMb2FkZWQoKTtcblxuICAgICAgICBpZiAoIWZvZ09wdGlvbnMpIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBmb2dcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmZvZztcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnN0eWxlc2hlZXQuZm9nO1xuICAgICAgICAgICAgdGhpcy5fbWFya2Vyc05lZWRVcGRhdGUgPSB0cnVlO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLmZvZykge1xuICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSBGb2dcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZUZvZyhmb2dPcHRpb25zKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFVwZGF0aW5nIGZvZ1xuICAgICAgICAgICAgY29uc3QgZm9nID0gdGhpcy5mb2c7XG4gICAgICAgICAgICBjb25zdCBjdXJyU3BlYyA9IGZvZy5nZXQoKTtcblxuICAgICAgICAgICAgLy8gZW1wdHkgb2JqZWN0IHNob3VsZCBwYXNzIHRocm91Z2ggdG8gc2V0IGRlZmF1bHQgdmFsdWVzXG4gICAgICAgICAgICBpZiAoT2JqZWN0LmtleXMoZm9nT3B0aW9ucykubGVuZ3RoID09PSAwKSBmb2cuc2V0KGZvZ09wdGlvbnMpO1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBmb2dPcHRpb25zKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFkZWVwRXF1YWwoZm9nT3B0aW9uc1trZXldLCBjdXJyU3BlY1trZXldKSkge1xuICAgICAgICAgICAgICAgICAgICBmb2cuc2V0KGZvZ09wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0eWxlc2hlZXQuZm9nID0gZm9nT3B0aW9ucztcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFyYW1ldGVycyA9IHRoaXMuX3NldFRyYW5zaXRpb25QYXJhbWV0ZXJzKHtkdXJhdGlvbjogMH0pO1xuICAgICAgICAgICAgICAgICAgICBmb2cudXBkYXRlVHJhbnNpdGlvbnMocGFyYW1ldGVycyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX21hcmtlcnNOZWVkVXBkYXRlID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBfc2V0VHJhbnNpdGlvblBhcmFtZXRlcnModHJhbnNpdGlvbk9wdGlvbnM6IE9iamVjdCk6IFRyYW5zaXRpb25QYXJhbWV0ZXJzIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG5vdzogYnJvd3Nlci5ub3coKSxcbiAgICAgICAgICAgIHRyYW5zaXRpb246IGV4dGVuZChcbiAgICAgICAgICAgICAgICB0cmFuc2l0aW9uT3B0aW9ucyxcbiAgICAgICAgICAgICAgICB0aGlzLnN0eWxlc2hlZXQudHJhbnNpdGlvbilcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBfdXBkYXRlRHJhcGVGaXJzdExheWVycygpIHtcbiAgICAgICAgaWYgKCF0aGlzLm1hcC5fb3B0aW1pemVGb3JUZXJyYWluIHx8ICF0aGlzLnRlcnJhaW4pIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGRyYXBlZCA9IHRoaXMuX29yZGVyLmZpbHRlcigoaWQpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmlzTGF5ZXJEcmFwZWQodGhpcy5fbGF5ZXJzW2lkXSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IG5vbkRyYXBlZCA9IHRoaXMuX29yZGVyLmZpbHRlcigoaWQpID0+IHtcbiAgICAgICAgICAgIHJldHVybiAhdGhpcy5pc0xheWVyRHJhcGVkKHRoaXMuX2xheWVyc1tpZF0pO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fZHJhcGVkRmlyc3RPcmRlciA9IFtdO1xuICAgICAgICB0aGlzLl9kcmFwZWRGaXJzdE9yZGVyLnB1c2goLi4uZHJhcGVkKTtcbiAgICAgICAgdGhpcy5fZHJhcGVkRmlyc3RPcmRlci5wdXNoKC4uLm5vbkRyYXBlZCk7XG4gICAgfVxuXG4gICAgX2NyZWF0ZVRlcnJhaW4odGVycmFpbk9wdGlvbnM6IFRlcnJhaW5TcGVjaWZpY2F0aW9uLCBkcmFwZVJlbmRlck1vZGU6IG51bWJlcikge1xuICAgICAgICBjb25zdCB0ZXJyYWluID0gdGhpcy50ZXJyYWluID0gbmV3IFRlcnJhaW4odGVycmFpbk9wdGlvbnMsIGRyYXBlUmVuZGVyTW9kZSk7XG4gICAgICAgIHRoaXMuc3R5bGVzaGVldC50ZXJyYWluID0gdGVycmFpbk9wdGlvbnM7XG4gICAgICAgIHRoaXMuZGlzcGF0Y2hlci5icm9hZGNhc3QoJ2VuYWJsZVRlcnJhaW4nLCAhdGhpcy50ZXJyYWluU2V0Rm9yRHJhcGluZ09ubHkoKSk7XG4gICAgICAgIHRoaXMuX2ZvcmNlM0RMYXllclVwZGF0ZSgpO1xuICAgICAgICBjb25zdCBwYXJhbWV0ZXJzID0gdGhpcy5fc2V0VHJhbnNpdGlvblBhcmFtZXRlcnMoe2R1cmF0aW9uOiAwfSk7XG4gICAgICAgIHRlcnJhaW4udXBkYXRlVHJhbnNpdGlvbnMocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgX2ZvcmNlM0RMYXllclVwZGF0ZSgpIHtcbiAgICAgICAgZm9yIChjb25zdCBsYXllcklkIGluIHRoaXMuX2xheWVycykge1xuICAgICAgICAgICAgY29uc3QgbGF5ZXIgPSB0aGlzLl9sYXllcnNbbGF5ZXJJZF07XG4gICAgICAgICAgICBpZiAobGF5ZXIudHlwZSA9PT0gJ2ZpbGwtZXh0cnVzaW9uJykge1xuICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUxheWVyKGxheWVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9mb3JjZVN5bWJvbExheWVyVXBkYXRlKCkge1xuICAgICAgICBmb3IgKGNvbnN0IGxheWVySWQgaW4gdGhpcy5fbGF5ZXJzKSB7XG4gICAgICAgICAgICBjb25zdCBsYXllciA9IHRoaXMuX2xheWVyc1tsYXllcklkXTtcbiAgICAgICAgICAgIGlmIChsYXllci50eXBlID09PSAnc3ltYm9sJykge1xuICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUxheWVyKGxheWVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIF92YWxpZGF0ZSh2YWxpZGF0ZTogVmFsaWRhdG9yLCBrZXk6IHN0cmluZywgdmFsdWU6IGFueSwgcHJvcHM6IGFueSwgb3B0aW9uczogeyB2YWxpZGF0ZT86IGJvb2xlYW4gfSA9IHt9KTogYm9vbGVhbiB7XG4gICAgICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMudmFsaWRhdGUgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGVtaXRWYWxpZGF0aW9uRXJyb3JzKHRoaXMsIHZhbGlkYXRlLmNhbGwodmFsaWRhdGVTdHlsZSwgZXh0ZW5kKHtcbiAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgIHN0eWxlOiB0aGlzLnNlcmlhbGl6ZSgpLFxuICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgICBzdHlsZVNwZWNcbiAgICAgICAgfSwgcHJvcHMpKSk7XG4gICAgfVxuXG4gICAgX3JlbW92ZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuX3JlcXVlc3QpIHtcbiAgICAgICAgICAgIHRoaXMuX3JlcXVlc3QuY2FuY2VsKCk7XG4gICAgICAgICAgICB0aGlzLl9yZXF1ZXN0ID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fc3ByaXRlUmVxdWVzdCkge1xuICAgICAgICAgICAgdGhpcy5fc3ByaXRlUmVxdWVzdC5jYW5jZWwoKTtcbiAgICAgICAgICAgIHRoaXMuX3Nwcml0ZVJlcXVlc3QgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJ0bFRleHRQbHVnaW5FdmVudGVkLm9mZigncGx1Z2luU3RhdGVDaGFuZ2UnLCB0aGlzLl9ydGxUZXh0UGx1Z2luQ2FsbGJhY2spO1xuICAgICAgICBmb3IgKGNvbnN0IGxheWVySWQgaW4gdGhpcy5fbGF5ZXJzKSB7XG4gICAgICAgICAgICBjb25zdCBsYXllcjogU3R5bGVMYXllciA9IHRoaXMuX2xheWVyc1tsYXllcklkXTtcbiAgICAgICAgICAgIGxheWVyLnNldEV2ZW50ZWRQYXJlbnQobnVsbCk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChjb25zdCBpZCBpbiB0aGlzLl9zb3VyY2VDYWNoZXMpIHtcbiAgICAgICAgICAgIHRoaXMuX3NvdXJjZUNhY2hlc1tpZF0uY2xlYXJUaWxlcygpO1xuICAgICAgICAgICAgdGhpcy5fc291cmNlQ2FjaGVzW2lkXS5zZXRFdmVudGVkUGFyZW50KG51bGwpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaW1hZ2VNYW5hZ2VyLnNldEV2ZW50ZWRQYXJlbnQobnVsbCk7XG4gICAgICAgIHRoaXMuc2V0RXZlbnRlZFBhcmVudChudWxsKTtcbiAgICAgICAgdGhpcy5kaXNwYXRjaGVyLnJlbW92ZSgpO1xuICAgIH1cblxuICAgIF9jbGVhclNvdXJjZShpZDogc3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IHNvdXJjZUNhY2hlcyA9IHRoaXMuX2dldFNvdXJjZUNhY2hlcyhpZCk7XG4gICAgICAgIGZvciAoY29uc3Qgc291cmNlQ2FjaGUgb2Ygc291cmNlQ2FjaGVzKSB7XG4gICAgICAgICAgICBzb3VyY2VDYWNoZS5jbGVhclRpbGVzKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfcmVsb2FkU291cmNlKGlkOiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3Qgc291cmNlQ2FjaGVzID0gdGhpcy5fZ2V0U291cmNlQ2FjaGVzKGlkKTtcbiAgICAgICAgZm9yIChjb25zdCBzb3VyY2VDYWNoZSBvZiBzb3VyY2VDYWNoZXMpIHtcbiAgICAgICAgICAgIHNvdXJjZUNhY2hlLnJlc3VtZSgpO1xuICAgICAgICAgICAgc291cmNlQ2FjaGUucmVsb2FkKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfcmVsb2FkU291cmNlcygpIHtcbiAgICAgICAgZm9yIChjb25zdCBzb3VyY2Ugb2YgdGhpcy5fZ2V0U291cmNlcygpKSB7XG4gICAgICAgICAgICBpZiAoc291cmNlLnJlbG9hZCkge1xuICAgICAgICAgICAgICAgIHNvdXJjZS5yZWxvYWQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIF91cGRhdGVTb3VyY2VzKHRyYW5zZm9ybTogVHJhbnNmb3JtKSB7XG4gICAgICAgIGZvciAoY29uc3QgaWQgaW4gdGhpcy5fc291cmNlQ2FjaGVzKSB7XG4gICAgICAgICAgICB0aGlzLl9zb3VyY2VDYWNoZXNbaWRdLnVwZGF0ZSh0cmFuc2Zvcm0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX2dlbmVyYXRlQ29sbGlzaW9uQm94ZXMoKSB7XG4gICAgICAgIGZvciAoY29uc3QgaWQgaW4gdGhpcy5fc291cmNlQ2FjaGVzKSB7XG4gICAgICAgICAgICBjb25zdCBzb3VyY2VDYWNoZSA9IHRoaXMuX3NvdXJjZUNhY2hlc1tpZF07XG4gICAgICAgICAgICBzb3VyY2VDYWNoZS5yZXN1bWUoKTtcbiAgICAgICAgICAgIHNvdXJjZUNhY2hlLnJlbG9hZCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX3VwZGF0ZVBsYWNlbWVudCh0cmFuc2Zvcm06IFRyYW5zZm9ybSwgc2hvd0NvbGxpc2lvbkJveGVzOiBib29sZWFuLCBmYWRlRHVyYXRpb246IG51bWJlciwgY3Jvc3NTb3VyY2VDb2xsaXNpb25zOiBib29sZWFuLCBmb3JjZUZ1bGxQbGFjZW1lbnQ6IGJvb2xlYW4gPSBmYWxzZSk6IGJvb2xlYW4ge1xuICAgICAgICBsZXQgc3ltYm9sQnVja2V0c0NoYW5nZWQgPSBmYWxzZTtcbiAgICAgICAgbGV0IHBsYWNlbWVudENvbW1pdHRlZCA9IGZhbHNlO1xuXG4gICAgICAgIGNvbnN0IGxheWVyVGlsZXMgPSB7fTtcblxuICAgICAgICBmb3IgKGNvbnN0IGxheWVySUQgb2YgdGhpcy5fb3JkZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IHN0eWxlTGF5ZXIgPSB0aGlzLl9sYXllcnNbbGF5ZXJJRF07XG4gICAgICAgICAgICBpZiAoc3R5bGVMYXllci50eXBlICE9PSAnc3ltYm9sJykgY29udGludWU7XG5cbiAgICAgICAgICAgIGlmICghbGF5ZXJUaWxlc1tzdHlsZUxheWVyLnNvdXJjZV0pIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2VDYWNoZSA9IHRoaXMuX2dldExheWVyU291cmNlQ2FjaGUoc3R5bGVMYXllcik7XG4gICAgICAgICAgICAgICAgaWYgKCFzb3VyY2VDYWNoZSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgbGF5ZXJUaWxlc1tzdHlsZUxheWVyLnNvdXJjZV0gPSBzb3VyY2VDYWNoZS5nZXRSZW5kZXJhYmxlSWRzKHRydWUpXG4gICAgICAgICAgICAgICAgICAgIC5tYXAoKGlkKSA9PiBzb3VyY2VDYWNoZS5nZXRUaWxlQnlJRChpZCkpXG4gICAgICAgICAgICAgICAgICAgIC5zb3J0KChhLCBiKSA9PiAoYi50aWxlSUQub3ZlcnNjYWxlZFogLSBhLnRpbGVJRC5vdmVyc2NhbGVkWikgfHwgKGEudGlsZUlELmlzTGVzc1RoYW4oYi50aWxlSUQpID8gLTEgOiAxKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGxheWVyQnVja2V0c0NoYW5nZWQgPSB0aGlzLmNyb3NzVGlsZVN5bWJvbEluZGV4LmFkZExheWVyKHN0eWxlTGF5ZXIsIGxheWVyVGlsZXNbc3R5bGVMYXllci5zb3VyY2VdLCB0cmFuc2Zvcm0uY2VudGVyLmxuZywgdHJhbnNmb3JtLnByb2plY3Rpb24pO1xuICAgICAgICAgICAgc3ltYm9sQnVja2V0c0NoYW5nZWQgPSBzeW1ib2xCdWNrZXRzQ2hhbmdlZCB8fCBsYXllckJ1Y2tldHNDaGFuZ2VkO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY3Jvc3NUaWxlU3ltYm9sSW5kZXgucHJ1bmVVbnVzZWRMYXllcnModGhpcy5fb3JkZXIpO1xuXG4gICAgICAgIC8vIEFueXRoaW5nIHRoYXQgY2hhbmdlcyBvdXIgXCJpbiBwcm9ncmVzc1wiIGxheWVyIGFuZCB0aWxlIGluZGljZXMgcmVxdWlyZXMgdXNcbiAgICAgICAgLy8gdG8gc3RhcnQgb3Zlci4gV2hlbiB3ZSBzdGFydCBvdmVyLCB3ZSBkbyBhIGZ1bGwgcGxhY2VtZW50IGluc3RlYWQgb2YgaW5jcmVtZW50YWxcbiAgICAgICAgLy8gdG8gcHJldmVudCBzdGFydmF0aW9uLlxuICAgICAgICAvLyBXZSBuZWVkIHRvIHJlc3RhcnQgcGxhY2VtZW50IHRvIGtlZXAgbGF5ZXIgaW5kaWNlcyBpbiBzeW5jLlxuICAgICAgICAvLyBBbHNvIGZvcmNlIGZ1bGwgcGxhY2VtZW50IHdoZW4gZmFkZUR1cmF0aW9uID09PSAwIHRvIGVuc3VyZSB0aGF0IG5ld2x5IGxvYWRlZFxuICAgICAgICAvLyB0aWxlcyB3aWxsIGZ1bGx5IGRpc3BsYXkgc3ltYm9scyBpbiB0aGVpciBmaXJzdCBmcmFtZVxuICAgICAgICBmb3JjZUZ1bGxQbGFjZW1lbnQgPSBmb3JjZUZ1bGxQbGFjZW1lbnQgfHwgdGhpcy5fbGF5ZXJPcmRlckNoYW5nZWQgfHwgZmFkZUR1cmF0aW9uID09PSAwO1xuXG4gICAgICAgIGlmICh0aGlzLl9sYXllck9yZGVyQ2hhbmdlZCkge1xuICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgnbmV3b3JkZXInKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZm9yY2VGdWxsUGxhY2VtZW50IHx8ICF0aGlzLnBhdXNlYWJsZVBsYWNlbWVudCB8fCAodGhpcy5wYXVzZWFibGVQbGFjZW1lbnQuaXNEb25lKCkgJiYgIXRoaXMucGxhY2VtZW50LnN0aWxsUmVjZW50KGJyb3dzZXIubm93KCksIHRyYW5zZm9ybS56b29tKSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGZvZ1N0YXRlID0gdGhpcy5mb2cgJiYgdHJhbnNmb3JtLnByb2plY3Rpb24uc3VwcG9ydHNGb2cgPyB0aGlzLmZvZy5zdGF0ZSA6IG51bGw7XG4gICAgICAgICAgICB0aGlzLnBhdXNlYWJsZVBsYWNlbWVudCA9IG5ldyBQYXVzZWFibGVQbGFjZW1lbnQodHJhbnNmb3JtLCB0aGlzLl9vcmRlciwgZm9yY2VGdWxsUGxhY2VtZW50LCBzaG93Q29sbGlzaW9uQm94ZXMsIGZhZGVEdXJhdGlvbiwgY3Jvc3NTb3VyY2VDb2xsaXNpb25zLCB0aGlzLnBsYWNlbWVudCwgZm9nU3RhdGUpO1xuICAgICAgICAgICAgdGhpcy5fbGF5ZXJPcmRlckNoYW5nZWQgPSBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnBhdXNlYWJsZVBsYWNlbWVudC5pc0RvbmUoKSkge1xuICAgICAgICAgICAgLy8gdGhlIGxhc3QgcGxhY2VtZW50IGZpbmlzaGVkIHJ1bm5pbmcsIGJ1dCB0aGUgbmV4dCBvbmUgaGFzbuKAmXRcbiAgICAgICAgICAgIC8vIHN0YXJ0ZWQgeWV0IGJlY2F1c2Ugb2YgdGhlIGBzdGlsbFJlY2VudGAgY2hlY2sgaW1tZWRpYXRlbHlcbiAgICAgICAgICAgIC8vIGFib3ZlLCBzbyBtYXJrIGl0IHN0YWxlIHRvIGVuc3VyZSB0aGF0IHdlIHJlcXVlc3QgYW5vdGhlclxuICAgICAgICAgICAgLy8gcmVuZGVyIGZyYW1lXG4gICAgICAgICAgICB0aGlzLnBsYWNlbWVudC5zZXRTdGFsZSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5wYXVzZWFibGVQbGFjZW1lbnQuY29udGludWVQbGFjZW1lbnQodGhpcy5fb3JkZXIsIHRoaXMuX2xheWVycywgbGF5ZXJUaWxlcyk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnBhdXNlYWJsZVBsYWNlbWVudC5pc0RvbmUoKSkge1xuICAgICAgICAgICAgICAgIHRoaXMucGxhY2VtZW50ID0gdGhpcy5wYXVzZWFibGVQbGFjZW1lbnQuY29tbWl0KGJyb3dzZXIubm93KCkpO1xuICAgICAgICAgICAgICAgIHBsYWNlbWVudENvbW1pdHRlZCA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChzeW1ib2xCdWNrZXRzQ2hhbmdlZCkge1xuICAgICAgICAgICAgICAgIC8vIHNpbmNlIHRoZSBwbGFjZW1lbnQgZ2V0cyBzcGxpdCBvdmVyIG11bHRpcGxlIGZyYW1lcyBpdCBpcyBwb3NzaWJsZVxuICAgICAgICAgICAgICAgIC8vIHRoZXNlIGJ1Y2tldHMgd2VyZSBwcm9jZXNzZWQgYmVmb3JlIHRoZXkgd2VyZSBjaGFuZ2VkIGFuZCBzbyB0aGVcbiAgICAgICAgICAgICAgICAvLyBwbGFjZW1lbnQgaXMgYWxyZWFkeSBzdGFsZSB3aGlsZSBpdCBpcyBpbiBwcm9ncmVzc1xuICAgICAgICAgICAgICAgIHRoaXMucGF1c2VhYmxlUGxhY2VtZW50LnBsYWNlbWVudC5zZXRTdGFsZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBsYWNlbWVudENvbW1pdHRlZCB8fCBzeW1ib2xCdWNrZXRzQ2hhbmdlZCkge1xuICAgICAgICAgICAgZm9yIChjb25zdCBsYXllcklEIG9mIHRoaXMuX29yZGVyKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3R5bGVMYXllciA9IHRoaXMuX2xheWVyc1tsYXllcklEXTtcbiAgICAgICAgICAgICAgICBpZiAoc3R5bGVMYXllci50eXBlICE9PSAnc3ltYm9sJykgY29udGludWU7XG4gICAgICAgICAgICAgICAgdGhpcy5wbGFjZW1lbnQudXBkYXRlTGF5ZXJPcGFjaXRpZXMoc3R5bGVMYXllciwgbGF5ZXJUaWxlc1tzdHlsZUxheWVyLnNvdXJjZV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gbmVlZHNSZW5kZXIgaXMgZmFsc2Ugd2hlbiB3ZSBoYXZlIGp1c3QgZmluaXNoZWQgYSBwbGFjZW1lbnQgdGhhdCBkaWRuJ3QgY2hhbmdlIHRoZSB2aXNpYmlsaXR5IG9mIGFueSBzeW1ib2xzXG4gICAgICAgIGNvbnN0IG5lZWRzUmVyZW5kZXIgPSAhdGhpcy5wYXVzZWFibGVQbGFjZW1lbnQuaXNEb25lKCkgfHwgdGhpcy5wbGFjZW1lbnQuaGFzVHJhbnNpdGlvbnMoYnJvd3Nlci5ub3coKSk7XG4gICAgICAgIHJldHVybiBuZWVkc1JlcmVuZGVyO1xuICAgIH1cblxuICAgIF9yZWxlYXNlU3ltYm9sRmFkZVRpbGVzKCkge1xuICAgICAgICBmb3IgKGNvbnN0IGlkIGluIHRoaXMuX3NvdXJjZUNhY2hlcykge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlQ2FjaGVzW2lkXS5yZWxlYXNlU3ltYm9sRmFkZVRpbGVzKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDYWxsYmFja3MgZnJvbSB3ZWIgd29ya2Vyc1xuXG4gICAgZ2V0SW1hZ2VzKG1hcElkOiBzdHJpbmcsIHBhcmFtczoge2ljb25zOiBBcnJheTxzdHJpbmc+LCBzb3VyY2U6IHN0cmluZywgdGlsZUlEOiBPdmVyc2NhbGVkVGlsZUlELCB0eXBlOiBzdHJpbmd9LCBjYWxsYmFjazogQ2FsbGJhY2s8e1tfOiBzdHJpbmddOiBTdHlsZUltYWdlfT4pIHtcblxuICAgICAgICB0aGlzLmltYWdlTWFuYWdlci5nZXRJbWFnZXMocGFyYW1zLmljb25zLCBjYWxsYmFjayk7XG5cbiAgICAgICAgLy8gQXBwbHkgcXVldWVkIGltYWdlIGNoYW5nZXMgYmVmb3JlIHNldHRpbmcgdGhlIHRpbGUncyBkZXBlbmRlbmNpZXMgc28gdGhhdCB0aGUgdGlsZVxuICAgICAgICAvLyBpcyBub3QgcmVsb2FkZWQgdW5lY2Vzc2FyaWx5LiBXaXRob3V0IHRoaXMgZm9yY2VkIHVwZGF0ZSB0aGUgcmVsb2FkIGNvdWxkIGhhcHBlbiBpbiBjYXNlc1xuICAgICAgICAvLyBsaWtlIHRoaXMgb25lOlxuICAgICAgICAvLyAtIGljb25zIGNvbnRhaW5zIFwibXktaW1hZ2VcIlxuICAgICAgICAvLyAtIGltYWdlTWFuYWdlci5nZXRJbWFnZXMoLi4uKSB0cmlnZ2VycyBgb25zdHlsZWltYWdlbWlzc2luZ2BcbiAgICAgICAgLy8gLSB0aGUgdXNlciBhZGRzIFwibXktaW1hZ2VcIiB3aXRoaW4gdGhlIGNhbGxiYWNrXG4gICAgICAgIC8vIC0gYWRkSW1hZ2UgYWRkcyBcIm15LWltYWdlXCIgdG8gdGhpcy5fY2hhbmdlZEltYWdlc1xuICAgICAgICAvLyAtIHRoZSBuZXh0IGZyYW1lIHRyaWdnZXJzIGEgcmVsb2FkIG9mIHRoaXMgdGlsZSBldmVuIHRob3VnaCBpdCBhbHJlYWR5IGhhcyB0aGUgbGF0ZXN0IHZlcnNpb25cbiAgICAgICAgdGhpcy5fdXBkYXRlVGlsZXNGb3JDaGFuZ2VkSW1hZ2VzKCk7XG5cbiAgICAgICAgY29uc3Qgc2V0RGVwZW5kZW5jaWVzID0gKHNvdXJjZUNhY2hlOiBTb3VyY2VDYWNoZSkgPT4ge1xuICAgICAgICAgICAgaWYgKHNvdXJjZUNhY2hlKSB7XG4gICAgICAgICAgICAgICAgc291cmNlQ2FjaGUuc2V0RGVwZW5kZW5jaWVzKHBhcmFtcy50aWxlSUQua2V5LCBwYXJhbXMudHlwZSwgcGFyYW1zLmljb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgc2V0RGVwZW5kZW5jaWVzKHRoaXMuX290aGVyU291cmNlQ2FjaGVzW3BhcmFtcy5zb3VyY2VdKTtcbiAgICAgICAgc2V0RGVwZW5kZW5jaWVzKHRoaXMuX3N5bWJvbFNvdXJjZUNhY2hlc1twYXJhbXMuc291cmNlXSk7XG4gICAgfVxuXG4gICAgZ2V0R2x5cGhzKG1hcElkOiBzdHJpbmcsIHBhcmFtczoge3N0YWNrczoge1tfOiBzdHJpbmddOiBBcnJheTxudW1iZXI+fX0sIGNhbGxiYWNrOiBDYWxsYmFjazx7W186IHN0cmluZ106IHtnbHlwaHM6IHtbXzogbnVtYmVyXTogP1N0eWxlR2x5cGh9LCBhc2NlbmRlcj86IG51bWJlciwgZGVzY2VuZGVyPzogbnVtYmVyfX0+KSB7XG4gICAgICAgIHRoaXMuZ2x5cGhNYW5hZ2VyLmdldEdseXBocyhwYXJhbXMuc3RhY2tzLCBjYWxsYmFjayk7XG4gICAgfVxuXG4gICAgZ2V0UmVzb3VyY2UobWFwSWQ6IHN0cmluZywgcGFyYW1zOiBSZXF1ZXN0UGFyYW1ldGVycywgY2FsbGJhY2s6IFJlc3BvbnNlQ2FsbGJhY2s8YW55Pik6IENhbmNlbGFibGUge1xuICAgICAgICByZXR1cm4gbWFrZVJlcXVlc3QocGFyYW1zLCBjYWxsYmFjayk7XG4gICAgfVxuXG4gICAgX2dldFNvdXJjZUNhY2hlKHNvdXJjZTogc3RyaW5nKTogU291cmNlQ2FjaGUgfCB2b2lkIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX290aGVyU291cmNlQ2FjaGVzW3NvdXJjZV07XG4gICAgfVxuXG4gICAgX2dldExheWVyU291cmNlQ2FjaGUobGF5ZXI6IFN0eWxlTGF5ZXIpOiBTb3VyY2VDYWNoZSB8IHZvaWQge1xuICAgICAgICByZXR1cm4gbGF5ZXIudHlwZSA9PT0gJ3N5bWJvbCcgP1xuICAgICAgICAgICAgdGhpcy5fc3ltYm9sU291cmNlQ2FjaGVzW2xheWVyLnNvdXJjZV0gOlxuICAgICAgICAgICAgdGhpcy5fb3RoZXJTb3VyY2VDYWNoZXNbbGF5ZXIuc291cmNlXTtcbiAgICB9XG5cbiAgICBfZ2V0U291cmNlQ2FjaGVzKHNvdXJjZTogc3RyaW5nKTogQXJyYXk8U291cmNlQ2FjaGU+IHtcbiAgICAgICAgY29uc3Qgc291cmNlQ2FjaGVzID0gW107XG4gICAgICAgIGlmICh0aGlzLl9vdGhlclNvdXJjZUNhY2hlc1tzb3VyY2VdKSB7XG4gICAgICAgICAgICBzb3VyY2VDYWNoZXMucHVzaCh0aGlzLl9vdGhlclNvdXJjZUNhY2hlc1tzb3VyY2VdKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fc3ltYm9sU291cmNlQ2FjaGVzW3NvdXJjZV0pIHtcbiAgICAgICAgICAgIHNvdXJjZUNhY2hlcy5wdXNoKHRoaXMuX3N5bWJvbFNvdXJjZUNhY2hlc1tzb3VyY2VdKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc291cmNlQ2FjaGVzO1xuICAgIH1cblxuICAgIF9pc1NvdXJjZUNhY2hlTG9hZGVkKHNvdXJjZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IHNvdXJjZUNhY2hlcyA9IHRoaXMuX2dldFNvdXJjZUNhY2hlcyhzb3VyY2UpO1xuICAgICAgICBpZiAoc291cmNlQ2FjaGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFcnJvckV2ZW50KG5ldyBFcnJvcihgVGhlcmUgaXMgbm8gc291cmNlIHdpdGggSUQgJyR7c291cmNlfSdgKSkpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzb3VyY2VDYWNoZXMuZXZlcnkoc2MgPT4gc2MubG9hZGVkKCkpO1xuICAgIH1cblxuICAgIGhhczNETGF5ZXJzKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fbnVtM0RMYXllcnMgPiAwO1xuICAgIH1cblxuICAgIGhhc1N5bWJvbExheWVycygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX251bVN5bWJvbExheWVycyA+IDA7XG4gICAgfVxuXG4gICAgaGFzQ2lyY2xlTGF5ZXJzKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fbnVtQ2lyY2xlTGF5ZXJzID4gMDtcbiAgICB9XG5cbiAgICBfY2xlYXJXb3JrZXJDYWNoZXMoKSB7XG4gICAgICAgIHRoaXMuZGlzcGF0Y2hlci5icm9hZGNhc3QoJ2NsZWFyQ2FjaGVzJyk7XG4gICAgfVxuXG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5fY2xlYXJXb3JrZXJDYWNoZXMoKTtcbiAgICAgICAgaWYgKHRoaXMudGVycmFpblNldEZvckRyYXBpbmdPbmx5KCkpIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnRlcnJhaW47XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5zdHlsZXNoZWV0LnRlcnJhaW47XG4gICAgICAgIH1cbiAgICB9XG59XG5cblN0eWxlLmdldFNvdXJjZVR5cGUgPSBnZXRTb3VyY2VUeXBlO1xuU3R5bGUuc2V0U291cmNlVHlwZSA9IHNldFNvdXJjZVR5cGU7XG5TdHlsZS5yZWdpc3RlckZvclBsdWdpblN0YXRlQ2hhbmdlID0gcmVnaXN0ZXJGb3JQbHVnaW5TdGF0ZUNoYW5nZTtcblxuZXhwb3J0IGRlZmF1bHQgU3R5bGU7XG4iLCJcbi8vIERpc2FibGUgRmxvdyBhbm5vdGF0aW9ucyBoZXJlIGJlY2F1c2UgRmxvdyBkb2Vzbid0IHN1cHBvcnQgaW1wb3J0aW5nIEdMU0wgZmlsZXNcbi8qIGVzbGludC1kaXNhYmxlIGZsb3d0eXBlL3JlcXVpcmUtdmFsaWQtZmlsZS1hbm5vdGF0aW9uICovXG5cbmltcG9ydCBwcmVsdWRlQ29tbW9uIGZyb20gJy4vX3ByZWx1ZGUuZ2xzbCc7XG5pbXBvcnQgcHJlbHVkZUZyYWcgZnJvbSAnLi9fcHJlbHVkZS5mcmFnbWVudC5nbHNsJztcbmltcG9ydCBwcmVsdWRlVmVydCBmcm9tICcuL19wcmVsdWRlLnZlcnRleC5nbHNsJztcbmltcG9ydCBiYWNrZ3JvdW5kRnJhZyBmcm9tICcuL2JhY2tncm91bmQuZnJhZ21lbnQuZ2xzbCc7XG5pbXBvcnQgYmFja2dyb3VuZFZlcnQgZnJvbSAnLi9iYWNrZ3JvdW5kLnZlcnRleC5nbHNsJztcbmltcG9ydCBiYWNrZ3JvdW5kUGF0dGVybkZyYWcgZnJvbSAnLi9iYWNrZ3JvdW5kX3BhdHRlcm4uZnJhZ21lbnQuZ2xzbCc7XG5pbXBvcnQgYmFja2dyb3VuZFBhdHRlcm5WZXJ0IGZyb20gJy4vYmFja2dyb3VuZF9wYXR0ZXJuLnZlcnRleC5nbHNsJztcbmltcG9ydCBjaXJjbGVGcmFnIGZyb20gJy4vY2lyY2xlLmZyYWdtZW50Lmdsc2wnO1xuaW1wb3J0IGNpcmNsZVZlcnQgZnJvbSAnLi9jaXJjbGUudmVydGV4Lmdsc2wnO1xuaW1wb3J0IGNsaXBwaW5nTWFza0ZyYWcgZnJvbSAnLi9jbGlwcGluZ19tYXNrLmZyYWdtZW50Lmdsc2wnO1xuaW1wb3J0IGNsaXBwaW5nTWFza1ZlcnQgZnJvbSAnLi9jbGlwcGluZ19tYXNrLnZlcnRleC5nbHNsJztcbmltcG9ydCBoZWF0bWFwRnJhZyBmcm9tICcuL2hlYXRtYXAuZnJhZ21lbnQuZ2xzbCc7XG5pbXBvcnQgaGVhdG1hcFZlcnQgZnJvbSAnLi9oZWF0bWFwLnZlcnRleC5nbHNsJztcbmltcG9ydCBoZWF0bWFwVGV4dHVyZUZyYWcgZnJvbSAnLi9oZWF0bWFwX3RleHR1cmUuZnJhZ21lbnQuZ2xzbCc7XG5pbXBvcnQgaGVhdG1hcFRleHR1cmVWZXJ0IGZyb20gJy4vaGVhdG1hcF90ZXh0dXJlLnZlcnRleC5nbHNsJztcbmltcG9ydCBjb2xsaXNpb25Cb3hGcmFnIGZyb20gJy4vY29sbGlzaW9uX2JveC5mcmFnbWVudC5nbHNsJztcbmltcG9ydCBjb2xsaXNpb25Cb3hWZXJ0IGZyb20gJy4vY29sbGlzaW9uX2JveC52ZXJ0ZXguZ2xzbCc7XG5pbXBvcnQgY29sbGlzaW9uQ2lyY2xlRnJhZyBmcm9tICcuL2NvbGxpc2lvbl9jaXJjbGUuZnJhZ21lbnQuZ2xzbCc7XG5pbXBvcnQgY29sbGlzaW9uQ2lyY2xlVmVydCBmcm9tICcuL2NvbGxpc2lvbl9jaXJjbGUudmVydGV4Lmdsc2wnO1xuaW1wb3J0IGRlYnVnRnJhZyBmcm9tICcuL2RlYnVnLmZyYWdtZW50Lmdsc2wnO1xuaW1wb3J0IGRlYnVnVmVydCBmcm9tICcuL2RlYnVnLnZlcnRleC5nbHNsJztcbmltcG9ydCBmaWxsRnJhZyBmcm9tICcuL2ZpbGwuZnJhZ21lbnQuZ2xzbCc7XG5pbXBvcnQgZmlsbFZlcnQgZnJvbSAnLi9maWxsLnZlcnRleC5nbHNsJztcbmltcG9ydCBmaWxsT3V0bGluZUZyYWcgZnJvbSAnLi9maWxsX291dGxpbmUuZnJhZ21lbnQuZ2xzbCc7XG5pbXBvcnQgZmlsbE91dGxpbmVWZXJ0IGZyb20gJy4vZmlsbF9vdXRsaW5lLnZlcnRleC5nbHNsJztcbmltcG9ydCBmaWxsT3V0bGluZVBhdHRlcm5GcmFnIGZyb20gJy4vZmlsbF9vdXRsaW5lX3BhdHRlcm4uZnJhZ21lbnQuZ2xzbCc7XG5pbXBvcnQgZmlsbE91dGxpbmVQYXR0ZXJuVmVydCBmcm9tICcuL2ZpbGxfb3V0bGluZV9wYXR0ZXJuLnZlcnRleC5nbHNsJztcbmltcG9ydCBmaWxsUGF0dGVybkZyYWcgZnJvbSAnLi9maWxsX3BhdHRlcm4uZnJhZ21lbnQuZ2xzbCc7XG5pbXBvcnQgZmlsbFBhdHRlcm5WZXJ0IGZyb20gJy4vZmlsbF9wYXR0ZXJuLnZlcnRleC5nbHNsJztcbmltcG9ydCBmaWxsRXh0cnVzaW9uRnJhZyBmcm9tICcuL2ZpbGxfZXh0cnVzaW9uLmZyYWdtZW50Lmdsc2wnO1xuaW1wb3J0IGZpbGxFeHRydXNpb25WZXJ0IGZyb20gJy4vZmlsbF9leHRydXNpb24udmVydGV4Lmdsc2wnO1xuaW1wb3J0IGZpbGxFeHRydXNpb25QYXR0ZXJuRnJhZyBmcm9tICcuL2ZpbGxfZXh0cnVzaW9uX3BhdHRlcm4uZnJhZ21lbnQuZ2xzbCc7XG5pbXBvcnQgZmlsbEV4dHJ1c2lvblBhdHRlcm5WZXJ0IGZyb20gJy4vZmlsbF9leHRydXNpb25fcGF0dGVybi52ZXJ0ZXguZ2xzbCc7XG5pbXBvcnQgaGlsbHNoYWRlUHJlcGFyZUZyYWcgZnJvbSAnLi9oaWxsc2hhZGVfcHJlcGFyZS5mcmFnbWVudC5nbHNsJztcbmltcG9ydCBoaWxsc2hhZGVQcmVwYXJlVmVydCBmcm9tICcuL2hpbGxzaGFkZV9wcmVwYXJlLnZlcnRleC5nbHNsJztcbmltcG9ydCBoaWxsc2hhZGVGcmFnIGZyb20gJy4vaGlsbHNoYWRlLmZyYWdtZW50Lmdsc2wnO1xuaW1wb3J0IGhpbGxzaGFkZVZlcnQgZnJvbSAnLi9oaWxsc2hhZGUudmVydGV4Lmdsc2wnO1xuaW1wb3J0IGxpbmVGcmFnIGZyb20gJy4vbGluZS5mcmFnbWVudC5nbHNsJztcbmltcG9ydCBsaW5lVmVydCBmcm9tICcuL2xpbmUudmVydGV4Lmdsc2wnO1xuaW1wb3J0IGxpbmVQYXR0ZXJuRnJhZyBmcm9tICcuL2xpbmVfcGF0dGVybi5mcmFnbWVudC5nbHNsJztcbmltcG9ydCBsaW5lUGF0dGVyblZlcnQgZnJvbSAnLi9saW5lX3BhdHRlcm4udmVydGV4Lmdsc2wnO1xuaW1wb3J0IHJhc3RlckZyYWcgZnJvbSAnLi9yYXN0ZXIuZnJhZ21lbnQuZ2xzbCc7XG5pbXBvcnQgcmFzdGVyVmVydCBmcm9tICcuL3Jhc3Rlci52ZXJ0ZXguZ2xzbCc7XG5pbXBvcnQgc3ltYm9sSWNvbkZyYWcgZnJvbSAnLi9zeW1ib2xfaWNvbi5mcmFnbWVudC5nbHNsJztcbmltcG9ydCBzeW1ib2xJY29uVmVydCBmcm9tICcuL3N5bWJvbF9pY29uLnZlcnRleC5nbHNsJztcbmltcG9ydCBzeW1ib2xTREZGcmFnIGZyb20gJy4vc3ltYm9sX3NkZi5mcmFnbWVudC5nbHNsJztcbmltcG9ydCBzeW1ib2xTREZWZXJ0IGZyb20gJy4vc3ltYm9sX3NkZi52ZXJ0ZXguZ2xzbCc7XG5pbXBvcnQgc3ltYm9sVGV4dEFuZEljb25GcmFnIGZyb20gJy4vc3ltYm9sX3RleHRfYW5kX2ljb24uZnJhZ21lbnQuZ2xzbCc7XG5pbXBvcnQgc3ltYm9sVGV4dEFuZEljb25WZXJ0IGZyb20gJy4vc3ltYm9sX3RleHRfYW5kX2ljb24udmVydGV4Lmdsc2wnO1xuaW1wb3J0IHNreWJveEZyYWcgZnJvbSAnLi9za3lib3guZnJhZ21lbnQuZ2xzbCc7XG5pbXBvcnQgc2t5Ym94R3JhZGllbnRGcmFnIGZyb20gJy4vc2t5Ym94X2dyYWRpZW50LmZyYWdtZW50Lmdsc2wnO1xuaW1wb3J0IHNreWJveFZlcnQgZnJvbSAnLi9za3lib3gudmVydGV4Lmdsc2wnO1xuaW1wb3J0IHRlcnJhaW5SYXN0ZXJGcmFnIGZyb20gJy4vdGVycmFpbl9yYXN0ZXIuZnJhZ21lbnQuZ2xzbCc7XG5pbXBvcnQgdGVycmFpblJhc3RlclZlcnQgZnJvbSAnLi90ZXJyYWluX3Jhc3Rlci52ZXJ0ZXguZ2xzbCc7XG5pbXBvcnQgdGVycmFpbkRlcHRoRnJhZyBmcm9tICcuL3RlcnJhaW5fZGVwdGguZnJhZ21lbnQuZ2xzbCc7XG5pbXBvcnQgdGVycmFpbkRlcHRoVmVydCBmcm9tICcuL3RlcnJhaW5fZGVwdGgudmVydGV4Lmdsc2wnO1xuaW1wb3J0IHByZWx1ZGVUZXJyYWluVmVydCBmcm9tICcuL19wcmVsdWRlX3RlcnJhaW4udmVydGV4Lmdsc2wnO1xuaW1wb3J0IHByZWx1ZGVGb2dWZXJ0IGZyb20gJy4vX3ByZWx1ZGVfZm9nLnZlcnRleC5nbHNsJztcbmltcG9ydCBwcmVsdWRlRm9nRnJhZyBmcm9tICcuL19wcmVsdWRlX2ZvZy5mcmFnbWVudC5nbHNsJztcbmltcG9ydCBza3lib3hDYXB0dXJlRnJhZyBmcm9tICcuL3NreWJveF9jYXB0dXJlLmZyYWdtZW50Lmdsc2wnO1xuaW1wb3J0IHNreWJveENhcHR1cmVWZXJ0IGZyb20gJy4vc2t5Ym94X2NhcHR1cmUudmVydGV4Lmdsc2wnO1xuaW1wb3J0IGdsb2JlRnJhZyBmcm9tICcuL2dsb2JlX3Jhc3Rlci5mcmFnbWVudC5nbHNsJztcbmltcG9ydCBnbG9iZVZlcnQgZnJvbSAnLi9nbG9iZV9yYXN0ZXIudmVydGV4Lmdsc2wnO1xuaW1wb3J0IGF0bW9zcGhlcmVGcmFnIGZyb20gJy4vYXRtb3NwaGVyZS5mcmFnbWVudC5nbHNsJztcbmltcG9ydCBhdG1vc3BoZXJlVmVydCBmcm9tICcuL2F0bW9zcGhlcmUudmVydGV4Lmdsc2wnO1xuXG5leHBvcnQgbGV0IHByZWx1ZGVUZXJyYWluID0ge307XG5leHBvcnQgbGV0IHByZWx1ZGVGb2cgPSB7fTtcblxuY29uc3QgY29tbW9uRGVmaW5lcyA9IFtdO1xucGFyc2VVc2VkUHJlcHJvY2Vzc29yRGVmaW5lcyhwcmVsdWRlQ29tbW9uLCBjb21tb25EZWZpbmVzKTtcbnBhcnNlVXNlZFByZXByb2Nlc3NvckRlZmluZXMocHJlbHVkZVRlcnJhaW5WZXJ0LCBjb21tb25EZWZpbmVzKTtcbnBhcnNlVXNlZFByZXByb2Nlc3NvckRlZmluZXMocHJlbHVkZUZvZ1ZlcnQsIGNvbW1vbkRlZmluZXMpO1xucGFyc2VVc2VkUHJlcHJvY2Vzc29yRGVmaW5lcyhwcmVsdWRlRm9nRnJhZywgY29tbW9uRGVmaW5lcyk7XG5cbnByZWx1ZGVUZXJyYWluID0gY29tcGlsZSgnJywgcHJlbHVkZVRlcnJhaW5WZXJ0KTtcbnByZWx1ZGVGb2cgPSBjb21waWxlKHByZWx1ZGVGb2dGcmFnLCBwcmVsdWRlRm9nVmVydCk7XG4vLyBTaGFkb3cgcHJlbHVkZSBpcyBub3QgY29tcGlsZWQgdW50aWwgR0wtSlMgaW1wbGVtZW50cyBzaGFkb3dzXG5cbmV4cG9ydCBjb25zdCBwcmVsdWRlID0gY29tcGlsZShwcmVsdWRlRnJhZywgcHJlbHVkZVZlcnQpO1xuZXhwb3J0IGNvbnN0IHByZWx1ZGVDb21tb25Tb3VyY2UgPSBwcmVsdWRlQ29tbW9uO1xuXG5leHBvcnQgY29uc3QgcHJlbHVkZVZlcnRQcmVjaXNpb25RdWFsaWZpZXJzID0gYFxuI2lmZGVmIEdMX0VTXG5wcmVjaXNpb24gaGlnaHAgZmxvYXQ7XG4jZWxzZVxuXG4jaWYgIWRlZmluZWQobG93cClcbiNkZWZpbmUgbG93cFxuI2VuZGlmXG5cbiNpZiAhZGVmaW5lZChtZWRpdW1wKVxuI2RlZmluZSBtZWRpdW1wXG4jZW5kaWZcblxuI2lmICFkZWZpbmVkKGhpZ2hwKVxuI2RlZmluZSBoaWdocFxuI2VuZGlmXG5cbiNlbmRpZmA7XG5leHBvcnQgY29uc3QgcHJlbHVkZUZyYWdQcmVjaXNpb25RdWFsaWZpZXJzID0gYFxuI2lmZGVmIEdMX0VTXG5wcmVjaXNpb24gbWVkaXVtcCBmbG9hdDtcbiNlbHNlXG5cbiNpZiAhZGVmaW5lZChsb3dwKVxuI2RlZmluZSBsb3dwXG4jZW5kaWZcblxuI2lmICFkZWZpbmVkKG1lZGl1bXApXG4jZGVmaW5lIG1lZGl1bXBcbiNlbmRpZlxuXG4jaWYgIWRlZmluZWQoaGlnaHApXG4jZGVmaW5lIGhpZ2hwXG4jZW5kaWZcblxuI2VuZGlmYDtcblxuZXhwb3J0IGNvbnN0IHN0YW5kYXJkRGVyaXZhdGl2ZXNFeHQgPSAnI2V4dGVuc2lvbiBHTF9PRVNfc3RhbmRhcmRfZGVyaXZhdGl2ZXMgOiBlbmFibGVcXG4nO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gICAgYmFja2dyb3VuZDogY29tcGlsZShiYWNrZ3JvdW5kRnJhZywgYmFja2dyb3VuZFZlcnQpLFxuICAgIGJhY2tncm91bmRQYXR0ZXJuOiBjb21waWxlKGJhY2tncm91bmRQYXR0ZXJuRnJhZywgYmFja2dyb3VuZFBhdHRlcm5WZXJ0KSxcbiAgICBjaXJjbGU6IGNvbXBpbGUoY2lyY2xlRnJhZywgY2lyY2xlVmVydCksXG4gICAgY2xpcHBpbmdNYXNrOiBjb21waWxlKGNsaXBwaW5nTWFza0ZyYWcsIGNsaXBwaW5nTWFza1ZlcnQpLFxuICAgIGhlYXRtYXA6IGNvbXBpbGUoaGVhdG1hcEZyYWcsIGhlYXRtYXBWZXJ0KSxcbiAgICBoZWF0bWFwVGV4dHVyZTogY29tcGlsZShoZWF0bWFwVGV4dHVyZUZyYWcsIGhlYXRtYXBUZXh0dXJlVmVydCksXG4gICAgY29sbGlzaW9uQm94OiBjb21waWxlKGNvbGxpc2lvbkJveEZyYWcsIGNvbGxpc2lvbkJveFZlcnQpLFxuICAgIGNvbGxpc2lvbkNpcmNsZTogY29tcGlsZShjb2xsaXNpb25DaXJjbGVGcmFnLCBjb2xsaXNpb25DaXJjbGVWZXJ0KSxcbiAgICBkZWJ1ZzogY29tcGlsZShkZWJ1Z0ZyYWcsIGRlYnVnVmVydCksXG4gICAgZmlsbDogY29tcGlsZShmaWxsRnJhZywgZmlsbFZlcnQpLFxuICAgIGZpbGxPdXRsaW5lOiBjb21waWxlKGZpbGxPdXRsaW5lRnJhZywgZmlsbE91dGxpbmVWZXJ0KSxcbiAgICBmaWxsT3V0bGluZVBhdHRlcm46IGNvbXBpbGUoZmlsbE91dGxpbmVQYXR0ZXJuRnJhZywgZmlsbE91dGxpbmVQYXR0ZXJuVmVydCksXG4gICAgZmlsbFBhdHRlcm46IGNvbXBpbGUoZmlsbFBhdHRlcm5GcmFnLCBmaWxsUGF0dGVyblZlcnQpLFxuICAgIGZpbGxFeHRydXNpb246IGNvbXBpbGUoZmlsbEV4dHJ1c2lvbkZyYWcsIGZpbGxFeHRydXNpb25WZXJ0KSxcbiAgICBmaWxsRXh0cnVzaW9uUGF0dGVybjogY29tcGlsZShmaWxsRXh0cnVzaW9uUGF0dGVybkZyYWcsIGZpbGxFeHRydXNpb25QYXR0ZXJuVmVydCksXG4gICAgaGlsbHNoYWRlUHJlcGFyZTogY29tcGlsZShoaWxsc2hhZGVQcmVwYXJlRnJhZywgaGlsbHNoYWRlUHJlcGFyZVZlcnQpLFxuICAgIGhpbGxzaGFkZTogY29tcGlsZShoaWxsc2hhZGVGcmFnLCBoaWxsc2hhZGVWZXJ0KSxcbiAgICBsaW5lOiBjb21waWxlKGxpbmVGcmFnLCBsaW5lVmVydCksXG4gICAgbGluZVBhdHRlcm46IGNvbXBpbGUobGluZVBhdHRlcm5GcmFnLCBsaW5lUGF0dGVyblZlcnQpLFxuICAgIHJhc3RlcjogY29tcGlsZShyYXN0ZXJGcmFnLCByYXN0ZXJWZXJ0KSxcbiAgICBzeW1ib2xJY29uOiBjb21waWxlKHN5bWJvbEljb25GcmFnLCBzeW1ib2xJY29uVmVydCksXG4gICAgc3ltYm9sU0RGOiBjb21waWxlKHN5bWJvbFNERkZyYWcsIHN5bWJvbFNERlZlcnQpLFxuICAgIHN5bWJvbFRleHRBbmRJY29uOiBjb21waWxlKHN5bWJvbFRleHRBbmRJY29uRnJhZywgc3ltYm9sVGV4dEFuZEljb25WZXJ0KSxcbiAgICB0ZXJyYWluUmFzdGVyOiBjb21waWxlKHRlcnJhaW5SYXN0ZXJGcmFnLCB0ZXJyYWluUmFzdGVyVmVydCksXG4gICAgdGVycmFpbkRlcHRoOiBjb21waWxlKHRlcnJhaW5EZXB0aEZyYWcsIHRlcnJhaW5EZXB0aFZlcnQpLFxuICAgIHNreWJveDogY29tcGlsZShza3lib3hGcmFnLCBza3lib3hWZXJ0KSxcbiAgICBza3lib3hHcmFkaWVudDogY29tcGlsZShza3lib3hHcmFkaWVudEZyYWcsIHNreWJveFZlcnQpLFxuICAgIHNreWJveENhcHR1cmU6IGNvbXBpbGUoc2t5Ym94Q2FwdHVyZUZyYWcsIHNreWJveENhcHR1cmVWZXJ0KSxcbiAgICBnbG9iZVJhc3RlcjogY29tcGlsZShnbG9iZUZyYWcsIGdsb2JlVmVydCksXG4gICAgZ2xvYmVBdG1vc3BoZXJlOiBjb21waWxlKGF0bW9zcGhlcmVGcmFnLCBhdG1vc3BoZXJlVmVydClcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVVzZWRQcmVwcm9jZXNzb3JEZWZpbmVzKHNvdXJjZSwgZGVmaW5lcykge1xuICAgIGNvbnN0IGxpbmVzID0gc291cmNlLnJlcGxhY2UoL1xccypcXC9cXC9bXlxcbl0qXFxuL2csICdcXG4nKS5zcGxpdCgnXFxuJyk7XG4gICAgZm9yIChsZXQgbGluZSBvZiBsaW5lcykge1xuICAgICAgICBsaW5lID0gbGluZS50cmltKCk7XG4gICAgICAgIGlmIChsaW5lWzBdID09PSAnIycpIHtcbiAgICAgICAgICAgIGlmIChsaW5lLmluY2x1ZGVzKCdpZicpICYmICFsaW5lLmluY2x1ZGVzKCdlbmRpZicpKSB7XG4gICAgICAgICAgICAgICAgbGluZSA9IGxpbmUucmVwbGFjZSgnIycsICcnKVxuICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvaWZkZWZ8aWZuZGVmfGVsaWZ8aWYvZywgJycpXG4gICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8hfGRlZmluZWR8XFwofFxcKXxcXHxcXHx8JiYvZywgJycpXG4gICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXHMrL2csICcgJykudHJpbSgpO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgbmV3RGVmaW5lcyA9IGxpbmUuc3BsaXQoJyAnKTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGRlZmluZSBvZiBuZXdEZWZpbmVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghZGVmaW5lcy5pbmNsdWRlcyhkZWZpbmUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWZpbmVzLnB1c2goZGVmaW5lKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuLy8gRXhwYW5kICNwcmFnbWFzIHRvICNpZmRlZnMuXG5leHBvcnQgZnVuY3Rpb24gY29tcGlsZShmcmFnbWVudFNvdXJjZSwgdmVydGV4U291cmNlKSB7XG4gICAgY29uc3QgcHJhZ21hUmVnZXggPSAvI3ByYWdtYSBtYXBib3g6IChbXFx3XSspIChbXFx3XSspIChbXFx3XSspIChbXFx3XSspL2c7XG4gICAgY29uc3QgYXR0cmlidXRlUmVnZXggPSAvYXR0cmlidXRlIChoaWdocCB8bWVkaXVtcCB8bG93cCApPyhbXFx3XSspIChbXFx3XSspL2c7XG5cbiAgICBjb25zdCBzdGF0aWNBdHRyaWJ1dGVzID0gdmVydGV4U291cmNlLm1hdGNoKGF0dHJpYnV0ZVJlZ2V4KTtcbiAgICBjb25zdCBmcmFnbWVudFByYWdtYXMgPSB7fTtcblxuICAgIGNvbnN0IHVzZWREZWZpbmVzID0gWy4uLmNvbW1vbkRlZmluZXNdO1xuICAgIHBhcnNlVXNlZFByZXByb2Nlc3NvckRlZmluZXMoZnJhZ21lbnRTb3VyY2UsIHVzZWREZWZpbmVzKTtcbiAgICBwYXJzZVVzZWRQcmVwcm9jZXNzb3JEZWZpbmVzKHZlcnRleFNvdXJjZSwgdXNlZERlZmluZXMpO1xuXG4gICAgZnJhZ21lbnRTb3VyY2UgPSBmcmFnbWVudFNvdXJjZS5yZXBsYWNlKHByYWdtYVJlZ2V4LCAobWF0Y2gsIG9wZXJhdGlvbiwgcHJlY2lzaW9uLCB0eXBlLCBuYW1lKSA9PiB7XG4gICAgICAgIGZyYWdtZW50UHJhZ21hc1tuYW1lXSA9IHRydWU7XG4gICAgICAgIGlmIChvcGVyYXRpb24gPT09ICdkZWZpbmUnKSB7XG4gICAgICAgICAgICByZXR1cm4gYFxuI2lmbmRlZiBIQVNfVU5JRk9STV91XyR7bmFtZX1cbnZhcnlpbmcgJHtwcmVjaXNpb259ICR7dHlwZX0gJHtuYW1lfTtcbiNlbHNlXG51bmlmb3JtICR7cHJlY2lzaW9ufSAke3R5cGV9IHVfJHtuYW1lfTtcbiNlbmRpZlxuYDtcbiAgICAgICAgfSBlbHNlIC8qIGlmIChvcGVyYXRpb24gPT09ICdpbml0aWFsaXplJykgKi8ge1xuICAgICAgICAgICAgcmV0dXJuIGBcbiNpZmRlZiBIQVNfVU5JRk9STV91XyR7bmFtZX1cbiAgICAke3ByZWNpc2lvbn0gJHt0eXBlfSAke25hbWV9ID0gdV8ke25hbWV9O1xuI2VuZGlmXG5gO1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICB2ZXJ0ZXhTb3VyY2UgPSB2ZXJ0ZXhTb3VyY2UucmVwbGFjZShwcmFnbWFSZWdleCwgKG1hdGNoLCBvcGVyYXRpb24sIHByZWNpc2lvbiwgdHlwZSwgbmFtZSkgPT4ge1xuICAgICAgICBjb25zdCBhdHRyVHlwZSA9IHR5cGUgPT09ICdmbG9hdCcgPyAndmVjMicgOiAndmVjNCc7XG4gICAgICAgIGNvbnN0IHVucGFja1R5cGUgPSBuYW1lLm1hdGNoKC9jb2xvci8pID8gJ2NvbG9yJyA6IGF0dHJUeXBlO1xuXG4gICAgICAgIGlmIChmcmFnbWVudFByYWdtYXNbbmFtZV0pIHtcbiAgICAgICAgICAgIGlmIChvcGVyYXRpb24gPT09ICdkZWZpbmUnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcbiNpZm5kZWYgSEFTX1VOSUZPUk1fdV8ke25hbWV9XG51bmlmb3JtIGxvd3AgZmxvYXQgdV8ke25hbWV9X3Q7XG5hdHRyaWJ1dGUgJHtwcmVjaXNpb259ICR7YXR0clR5cGV9IGFfJHtuYW1lfTtcbnZhcnlpbmcgJHtwcmVjaXNpb259ICR7dHlwZX0gJHtuYW1lfTtcbiNlbHNlXG51bmlmb3JtICR7cHJlY2lzaW9ufSAke3R5cGV9IHVfJHtuYW1lfTtcbiNlbmRpZlxuYDtcbiAgICAgICAgICAgIH0gZWxzZSAvKiBpZiAob3BlcmF0aW9uID09PSAnaW5pdGlhbGl6ZScpICovIHtcbiAgICAgICAgICAgICAgICBpZiAodW5wYWNrVHlwZSA9PT0gJ3ZlYzQnKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHZlYzQgYXR0cmlidXRlcyBhcmUgb25seSB1c2VkIGZvciBjcm9zcy1mYWRlZCBwcm9wZXJ0aWVzLCBhbmQgYXJlIG5vdCBwYWNrZWRcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcbiNpZm5kZWYgSEFTX1VOSUZPUk1fdV8ke25hbWV9XG4gICAgJHtuYW1lfSA9IGFfJHtuYW1lfTtcbiNlbHNlXG4gICAgJHtwcmVjaXNpb259ICR7dHlwZX0gJHtuYW1lfSA9IHVfJHtuYW1lfTtcbiNlbmRpZlxuYDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFxuI2lmbmRlZiBIQVNfVU5JRk9STV91XyR7bmFtZX1cbiAgICAke25hbWV9ID0gdW5wYWNrX21peF8ke3VucGFja1R5cGV9KGFfJHtuYW1lfSwgdV8ke25hbWV9X3QpO1xuI2Vsc2VcbiAgICAke3ByZWNpc2lvbn0gJHt0eXBlfSAke25hbWV9ID0gdV8ke25hbWV9O1xuI2VuZGlmXG5gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChvcGVyYXRpb24gPT09ICdkZWZpbmUnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcbiNpZm5kZWYgSEFTX1VOSUZPUk1fdV8ke25hbWV9XG51bmlmb3JtIGxvd3AgZmxvYXQgdV8ke25hbWV9X3Q7XG5hdHRyaWJ1dGUgJHtwcmVjaXNpb259ICR7YXR0clR5cGV9IGFfJHtuYW1lfTtcbiNlbHNlXG51bmlmb3JtICR7cHJlY2lzaW9ufSAke3R5cGV9IHVfJHtuYW1lfTtcbiNlbmRpZlxuYDtcbiAgICAgICAgICAgIH0gZWxzZSAvKiBpZiAob3BlcmF0aW9uID09PSAnaW5pdGlhbGl6ZScpICovIHtcbiAgICAgICAgICAgICAgICBpZiAodW5wYWNrVHlwZSA9PT0gJ3ZlYzQnKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHZlYzQgYXR0cmlidXRlcyBhcmUgb25seSB1c2VkIGZvciBjcm9zcy1mYWRlZCBwcm9wZXJ0aWVzLCBhbmQgYXJlIG5vdCBwYWNrZWRcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcbiNpZm5kZWYgSEFTX1VOSUZPUk1fdV8ke25hbWV9XG4gICAgJHtwcmVjaXNpb259ICR7dHlwZX0gJHtuYW1lfSA9IGFfJHtuYW1lfTtcbiNlbHNlXG4gICAgJHtwcmVjaXNpb259ICR7dHlwZX0gJHtuYW1lfSA9IHVfJHtuYW1lfTtcbiNlbmRpZlxuYDtcbiAgICAgICAgICAgICAgICB9IGVsc2UgLyogKi97XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXG4jaWZuZGVmIEhBU19VTklGT1JNX3VfJHtuYW1lfVxuICAgICR7cHJlY2lzaW9ufSAke3R5cGV9ICR7bmFtZX0gPSB1bnBhY2tfbWl4XyR7dW5wYWNrVHlwZX0oYV8ke25hbWV9LCB1XyR7bmFtZX1fdCk7XG4jZWxzZVxuICAgICR7cHJlY2lzaW9ufSAke3R5cGV9ICR7bmFtZX0gPSB1XyR7bmFtZX07XG4jZW5kaWZcbmA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4ge2ZyYWdtZW50U291cmNlLCB2ZXJ0ZXhTb3VyY2UsIHN0YXRpY0F0dHJpYnV0ZXMsIHVzZWREZWZpbmVzfTtcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcblxuaW1wb3J0IHR5cGUgUHJvZ3JhbSBmcm9tICcuL3Byb2dyYW0uanMnO1xuaW1wb3J0IHR5cGUgVmVydGV4QnVmZmVyIGZyb20gJy4uL2dsL3ZlcnRleF9idWZmZXIuanMnO1xuaW1wb3J0IHR5cGUgSW5kZXhCdWZmZXIgZnJvbSAnLi4vZ2wvaW5kZXhfYnVmZmVyLmpzJztcbmltcG9ydCB0eXBlIENvbnRleHQgZnJvbSAnLi4vZ2wvY29udGV4dC5qcyc7XG5cbmNsYXNzIFZlcnRleEFycmF5T2JqZWN0IHtcbiAgICBjb250ZXh0OiBDb250ZXh0O1xuICAgIGJvdW5kUHJvZ3JhbTogP1Byb2dyYW08Kj47XG4gICAgYm91bmRMYXlvdXRWZXJ0ZXhCdWZmZXI6ID9WZXJ0ZXhCdWZmZXI7XG4gICAgYm91bmRQYWludFZlcnRleEJ1ZmZlcnM6IEFycmF5PFZlcnRleEJ1ZmZlcj47XG4gICAgYm91bmRJbmRleEJ1ZmZlcjogP0luZGV4QnVmZmVyO1xuICAgIGJvdW5kVmVydGV4T2Zmc2V0OiA/bnVtYmVyO1xuICAgIGJvdW5kRHluYW1pY1ZlcnRleEJ1ZmZlcnM6IEFycmF5PD9WZXJ0ZXhCdWZmZXI+O1xuICAgIHZhbzogYW55O1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuYm91bmRQcm9ncmFtID0gbnVsbDtcbiAgICAgICAgdGhpcy5ib3VuZExheW91dFZlcnRleEJ1ZmZlciA9IG51bGw7XG4gICAgICAgIHRoaXMuYm91bmRQYWludFZlcnRleEJ1ZmZlcnMgPSBbXTtcbiAgICAgICAgdGhpcy5ib3VuZEluZGV4QnVmZmVyID0gbnVsbDtcbiAgICAgICAgdGhpcy5ib3VuZFZlcnRleE9mZnNldCA9IG51bGw7XG4gICAgICAgIHRoaXMuYm91bmREeW5hbWljVmVydGV4QnVmZmVycyA9IFtdO1xuICAgICAgICB0aGlzLnZhbyA9IG51bGw7XG4gICAgfVxuXG4gICAgYmluZChjb250ZXh0OiBDb250ZXh0LFxuICAgICAgICAgcHJvZ3JhbTogUHJvZ3JhbTwqPixcbiAgICAgICAgIGxheW91dFZlcnRleEJ1ZmZlcjogVmVydGV4QnVmZmVyLFxuICAgICAgICAgcGFpbnRWZXJ0ZXhCdWZmZXJzOiBBcnJheTxWZXJ0ZXhCdWZmZXI+LFxuICAgICAgICAgaW5kZXhCdWZmZXI6ID9JbmRleEJ1ZmZlcixcbiAgICAgICAgIHZlcnRleE9mZnNldDogP251bWJlcixcbiAgICAgICAgIGR5bmFtaWNWZXJ0ZXhCdWZmZXJzOiBBcnJheTw/VmVydGV4QnVmZmVyPikge1xuXG4gICAgICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG5cbiAgICAgICAgbGV0IHBhaW50QnVmZmVyc0RpZmZlciA9IHRoaXMuYm91bmRQYWludFZlcnRleEJ1ZmZlcnMubGVuZ3RoICE9PSBwYWludFZlcnRleEJ1ZmZlcnMubGVuZ3RoO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgIXBhaW50QnVmZmVyc0RpZmZlciAmJiBpIDwgcGFpbnRWZXJ0ZXhCdWZmZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5ib3VuZFBhaW50VmVydGV4QnVmZmVyc1tpXSAhPT0gcGFpbnRWZXJ0ZXhCdWZmZXJzW2ldKSB7XG4gICAgICAgICAgICAgICAgcGFpbnRCdWZmZXJzRGlmZmVyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgZHluYW1pY0J1ZmZlcnNEaWZmZXIgPSB0aGlzLmJvdW5kRHluYW1pY1ZlcnRleEJ1ZmZlcnMubGVuZ3RoICE9PSBkeW5hbWljVmVydGV4QnVmZmVycy5sZW5ndGg7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyAhZHluYW1pY0J1ZmZlcnNEaWZmZXIgJiYgaSA8IGR5bmFtaWNWZXJ0ZXhCdWZmZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5ib3VuZER5bmFtaWNWZXJ0ZXhCdWZmZXJzW2ldICE9PSBkeW5hbWljVmVydGV4QnVmZmVyc1tpXSkge1xuICAgICAgICAgICAgICAgIGR5bmFtaWNCdWZmZXJzRGlmZmVyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGlzRnJlc2hCaW5kUmVxdWlyZWQgPSAoXG4gICAgICAgICAgICAhdGhpcy52YW8gfHxcbiAgICAgICAgICAgIHRoaXMuYm91bmRQcm9ncmFtICE9PSBwcm9ncmFtIHx8XG4gICAgICAgICAgICB0aGlzLmJvdW5kTGF5b3V0VmVydGV4QnVmZmVyICE9PSBsYXlvdXRWZXJ0ZXhCdWZmZXIgfHxcbiAgICAgICAgICAgIHBhaW50QnVmZmVyc0RpZmZlciB8fFxuICAgICAgICAgICAgZHluYW1pY0J1ZmZlcnNEaWZmZXIgfHxcbiAgICAgICAgICAgIHRoaXMuYm91bmRJbmRleEJ1ZmZlciAhPT0gaW5kZXhCdWZmZXIgfHxcbiAgICAgICAgICAgIHRoaXMuYm91bmRWZXJ0ZXhPZmZzZXQgIT09IHZlcnRleE9mZnNldFxuICAgICAgICApO1xuXG4gICAgICAgIGlmICghY29udGV4dC5leHRWZXJ0ZXhBcnJheU9iamVjdCB8fCBpc0ZyZXNoQmluZFJlcXVpcmVkKSB7XG4gICAgICAgICAgICB0aGlzLmZyZXNoQmluZChwcm9ncmFtLCBsYXlvdXRWZXJ0ZXhCdWZmZXIsIHBhaW50VmVydGV4QnVmZmVycywgaW5kZXhCdWZmZXIsIHZlcnRleE9mZnNldCwgZHluYW1pY1ZlcnRleEJ1ZmZlcnMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29udGV4dC5iaW5kVmVydGV4QXJyYXlPRVMuc2V0KHRoaXMudmFvKTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgZHluYW1pY0J1ZmZlciBvZiBkeW5hbWljVmVydGV4QnVmZmVycykge1xuICAgICAgICAgICAgICAgIGlmIChkeW5hbWljQnVmZmVyKSB7XG4gICAgICAgICAgICAgICAgICAgIGR5bmFtaWNCdWZmZXIuYmluZCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpbmRleEJ1ZmZlciAmJiBpbmRleEJ1ZmZlci5keW5hbWljRHJhdykge1xuICAgICAgICAgICAgICAgIGluZGV4QnVmZmVyLmJpbmQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZyZXNoQmluZChwcm9ncmFtOiBQcm9ncmFtPCo+LFxuICAgICAgICAgICAgICBsYXlvdXRWZXJ0ZXhCdWZmZXI6IFZlcnRleEJ1ZmZlcixcbiAgICAgICAgICAgICAgcGFpbnRWZXJ0ZXhCdWZmZXJzOiBBcnJheTxWZXJ0ZXhCdWZmZXI+LFxuICAgICAgICAgICAgICBpbmRleEJ1ZmZlcjogP0luZGV4QnVmZmVyLFxuICAgICAgICAgICAgICB2ZXJ0ZXhPZmZzZXQ6ID9udW1iZXIsXG4gICAgICAgICAgICAgIGR5bmFtaWNWZXJ0ZXhCdWZmZXJzOiBBcnJheTw/VmVydGV4QnVmZmVyPikge1xuICAgICAgICBsZXQgbnVtUHJldkF0dHJpYnV0ZXM7XG4gICAgICAgIGNvbnN0IG51bU5leHRBdHRyaWJ1dGVzID0gcHJvZ3JhbS5udW1BdHRyaWJ1dGVzO1xuXG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmNvbnRleHQ7XG4gICAgICAgIGNvbnN0IGdsID0gY29udGV4dC5nbDtcblxuICAgICAgICBpZiAoY29udGV4dC5leHRWZXJ0ZXhBcnJheU9iamVjdCkge1xuICAgICAgICAgICAgaWYgKHRoaXMudmFvKSB0aGlzLmRlc3Ryb3koKTtcbiAgICAgICAgICAgIHRoaXMudmFvID0gY29udGV4dC5leHRWZXJ0ZXhBcnJheU9iamVjdC5jcmVhdGVWZXJ0ZXhBcnJheU9FUygpO1xuICAgICAgICAgICAgY29udGV4dC5iaW5kVmVydGV4QXJyYXlPRVMuc2V0KHRoaXMudmFvKTtcbiAgICAgICAgICAgIG51bVByZXZBdHRyaWJ1dGVzID0gMDtcblxuICAgICAgICAgICAgLy8gc3RvcmUgdGhlIGFyZ3VtZW50cyBzbyB0aGF0IHdlIGNhbiB2ZXJpZnkgdGhlbSB3aGVuIHRoZSB2YW8gaXMgYm91bmQgYWdhaW5cbiAgICAgICAgICAgIHRoaXMuYm91bmRQcm9ncmFtID0gcHJvZ3JhbTtcbiAgICAgICAgICAgIHRoaXMuYm91bmRMYXlvdXRWZXJ0ZXhCdWZmZXIgPSBsYXlvdXRWZXJ0ZXhCdWZmZXI7XG4gICAgICAgICAgICB0aGlzLmJvdW5kUGFpbnRWZXJ0ZXhCdWZmZXJzID0gcGFpbnRWZXJ0ZXhCdWZmZXJzO1xuICAgICAgICAgICAgdGhpcy5ib3VuZEluZGV4QnVmZmVyID0gaW5kZXhCdWZmZXI7XG4gICAgICAgICAgICB0aGlzLmJvdW5kVmVydGV4T2Zmc2V0ID0gdmVydGV4T2Zmc2V0O1xuICAgICAgICAgICAgdGhpcy5ib3VuZER5bmFtaWNWZXJ0ZXhCdWZmZXJzID0gZHluYW1pY1ZlcnRleEJ1ZmZlcnM7XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG51bVByZXZBdHRyaWJ1dGVzID0gY29udGV4dC5jdXJyZW50TnVtQXR0cmlidXRlcyB8fCAwO1xuXG4gICAgICAgICAgICAvLyBEaXNhYmxlIGFsbCBhdHRyaWJ1dGVzIGZyb20gdGhlIHByZXZpb3VzIHByb2dyYW0gdGhhdCBhcmVuJ3QgdXNlZCBpblxuICAgICAgICAgICAgLy8gdGhlIG5ldyBwcm9ncmFtLiBOb3RlOiBhdHRyaWJ1dGUgaW5kaWNlcyBhcmUgKm5vdCogcHJvZ3JhbSBzcGVjaWZpYyFcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSBudW1OZXh0QXR0cmlidXRlczsgaSA8IG51bVByZXZBdHRyaWJ1dGVzOyBpKyspIHtcbiAgICAgICAgICAgICAgICAvLyBXZWJHTCBicmVha3MgaWYgeW91IGRpc2FibGUgYXR0cmlidXRlIDAuXG4gICAgICAgICAgICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8yMDMwNTIzMVxuICAgICAgICAgICAgICAgIGFzc2VydChpICE9PSAwKTtcbiAgICAgICAgICAgICAgICBnbC5kaXNhYmxlVmVydGV4QXR0cmliQXJyYXkoaSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBsYXlvdXRWZXJ0ZXhCdWZmZXIuZW5hYmxlQXR0cmlidXRlcyhnbCwgcHJvZ3JhbSk7XG4gICAgICAgIGxheW91dFZlcnRleEJ1ZmZlci5iaW5kKCk7XG4gICAgICAgIGxheW91dFZlcnRleEJ1ZmZlci5zZXRWZXJ0ZXhBdHRyaWJQb2ludGVycyhnbCwgcHJvZ3JhbSwgdmVydGV4T2Zmc2V0KTtcblxuICAgICAgICBmb3IgKGNvbnN0IHZlcnRleEJ1ZmZlciBvZiBwYWludFZlcnRleEJ1ZmZlcnMpIHtcbiAgICAgICAgICAgIHZlcnRleEJ1ZmZlci5lbmFibGVBdHRyaWJ1dGVzKGdsLCBwcm9ncmFtKTtcbiAgICAgICAgICAgIHZlcnRleEJ1ZmZlci5iaW5kKCk7XG4gICAgICAgICAgICB2ZXJ0ZXhCdWZmZXIuc2V0VmVydGV4QXR0cmliUG9pbnRlcnMoZ2wsIHByb2dyYW0sIHZlcnRleE9mZnNldCk7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGNvbnN0IGR5bmFtaWNCdWZmZXIgb2YgZHluYW1pY1ZlcnRleEJ1ZmZlcnMpIHtcbiAgICAgICAgICAgIGlmIChkeW5hbWljQnVmZmVyKSB7XG4gICAgICAgICAgICAgICAgZHluYW1pY0J1ZmZlci5lbmFibGVBdHRyaWJ1dGVzKGdsLCBwcm9ncmFtKTtcbiAgICAgICAgICAgICAgICBkeW5hbWljQnVmZmVyLmJpbmQoKTtcbiAgICAgICAgICAgICAgICBkeW5hbWljQnVmZmVyLnNldFZlcnRleEF0dHJpYlBvaW50ZXJzKGdsLCBwcm9ncmFtLCB2ZXJ0ZXhPZmZzZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGluZGV4QnVmZmVyKSB7XG4gICAgICAgICAgICBpbmRleEJ1ZmZlci5iaW5kKCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb250ZXh0LmN1cnJlbnROdW1BdHRyaWJ1dGVzID0gbnVtTmV4dEF0dHJpYnV0ZXM7XG4gICAgfVxuXG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgaWYgKHRoaXMudmFvKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQuZXh0VmVydGV4QXJyYXlPYmplY3QuZGVsZXRlVmVydGV4QXJyYXlPRVModGhpcy52YW8pO1xuICAgICAgICAgICAgdGhpcy52YW8gPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBWZXJ0ZXhBcnJheU9iamVjdDtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCB7bWF0NH0gZnJvbSAnZ2wtbWF0cml4JztcblxuaW1wb3J0IHtcbiAgICBVbmlmb3JtMWksXG4gICAgVW5pZm9ybTFmLFxuICAgIFVuaWZvcm0yZixcbiAgICBVbmlmb3JtQ29sb3IsXG4gICAgVW5pZm9ybU1hdHJpeDRmLFxuICAgIFVuaWZvcm00ZlxufSBmcm9tICcuLi91bmlmb3JtX2JpbmRpbmcuanMnO1xuaW1wb3J0IEVYVEVOVCBmcm9tICcuLi8uLi9kYXRhL2V4dGVudC5qcyc7XG5pbXBvcnQgTWVyY2F0b3JDb29yZGluYXRlIGZyb20gJy4uLy4uL2dlby9tZXJjYXRvcl9jb29yZGluYXRlLmpzJztcblxuaW1wb3J0IHR5cGUgQ29udGV4dCBmcm9tICcuLi8uLi9nbC9jb250ZXh0LmpzJztcbmltcG9ydCB0eXBlIHtVbmlmb3JtVmFsdWVzfSBmcm9tICcuLi91bmlmb3JtX2JpbmRpbmcuanMnO1xuaW1wb3J0IHR5cGUgVGlsZSBmcm9tICcuLi8uLi9zb3VyY2UvdGlsZS5qcyc7XG5pbXBvcnQgdHlwZSBQYWludGVyIGZyb20gJy4uL3BhaW50ZXIuanMnO1xuaW1wb3J0IHR5cGUgSGlsbHNoYWRlU3R5bGVMYXllciBmcm9tICcuLi8uLi9zdHlsZS9zdHlsZV9sYXllci9oaWxsc2hhZGVfc3R5bGVfbGF5ZXIuanMnO1xuaW1wb3J0IHR5cGUgREVNRGF0YSBmcm9tICcuLi8uLi9kYXRhL2RlbV9kYXRhLmpzJztcbmltcG9ydCB0eXBlIHtPdmVyc2NhbGVkVGlsZUlEfSBmcm9tICcuLi8uLi9zb3VyY2UvdGlsZV9pZC5qcyc7XG5cbmV4cG9ydCB0eXBlIEhpbGxzaGFkZVVuaWZvcm1zVHlwZSA9IHt8XG4gICAgJ3VfbWF0cml4JzogVW5pZm9ybU1hdHJpeDRmLFxuICAgICd1X2ltYWdlJzogVW5pZm9ybTFpLFxuICAgICd1X2xhdHJhbmdlJzogVW5pZm9ybTJmLFxuICAgICd1X2xpZ2h0JzogVW5pZm9ybTJmLFxuICAgICd1X3NoYWRvdyc6IFVuaWZvcm1Db2xvcixcbiAgICAndV9oaWdobGlnaHQnOiBVbmlmb3JtQ29sb3IsXG4gICAgJ3VfYWNjZW50JzogVW5pZm9ybUNvbG9yXG58fTtcblxuZXhwb3J0IHR5cGUgSGlsbHNoYWRlUHJlcGFyZVVuaWZvcm1zVHlwZSA9IHt8XG4gICAgJ3VfbWF0cml4JzogVW5pZm9ybU1hdHJpeDRmLFxuICAgICd1X2ltYWdlJzogVW5pZm9ybTFpLFxuICAgICd1X2RpbWVuc2lvbic6IFVuaWZvcm0yZixcbiAgICAndV96b29tJzogVW5pZm9ybTFmLFxuICAgICd1X3VucGFjayc6IFVuaWZvcm00ZlxufH07XG5cbmNvbnN0IGhpbGxzaGFkZVVuaWZvcm1zID0gKGNvbnRleHQ6IENvbnRleHQpOiBIaWxsc2hhZGVVbmlmb3Jtc1R5cGUgPT4gKHtcbiAgICAndV9tYXRyaXgnOiBuZXcgVW5pZm9ybU1hdHJpeDRmKGNvbnRleHQpLFxuICAgICd1X2ltYWdlJzogbmV3IFVuaWZvcm0xaShjb250ZXh0KSxcbiAgICAndV9sYXRyYW5nZSc6IG5ldyBVbmlmb3JtMmYoY29udGV4dCksXG4gICAgJ3VfbGlnaHQnOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpLFxuICAgICd1X3NoYWRvdyc6IG5ldyBVbmlmb3JtQ29sb3IoY29udGV4dCksXG4gICAgJ3VfaGlnaGxpZ2h0JzogbmV3IFVuaWZvcm1Db2xvcihjb250ZXh0KSxcbiAgICAndV9hY2NlbnQnOiBuZXcgVW5pZm9ybUNvbG9yKGNvbnRleHQpXG59KTtcblxuY29uc3QgaGlsbHNoYWRlUHJlcGFyZVVuaWZvcm1zID0gKGNvbnRleHQ6IENvbnRleHQpOiBIaWxsc2hhZGVQcmVwYXJlVW5pZm9ybXNUeXBlID0+ICh7XG4gICAgJ3VfbWF0cml4JzogbmV3IFVuaWZvcm1NYXRyaXg0Zihjb250ZXh0KSxcbiAgICAndV9pbWFnZSc6IG5ldyBVbmlmb3JtMWkoY29udGV4dCksXG4gICAgJ3VfZGltZW5zaW9uJzogbmV3IFVuaWZvcm0yZihjb250ZXh0KSxcbiAgICAndV96b29tJzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV91bnBhY2snOiBuZXcgVW5pZm9ybTRmKGNvbnRleHQpXG59KTtcblxuY29uc3QgaGlsbHNoYWRlVW5pZm9ybVZhbHVlcyA9IChcbiAgICBwYWludGVyOiBQYWludGVyLFxuICAgIHRpbGU6IFRpbGUsXG4gICAgbGF5ZXI6IEhpbGxzaGFkZVN0eWxlTGF5ZXIsXG4gICAgbWF0cml4OiA/RmxvYXQzMkFycmF5XG4pOiBVbmlmb3JtVmFsdWVzPEhpbGxzaGFkZVVuaWZvcm1zVHlwZT4gPT4ge1xuICAgIGNvbnN0IHNoYWRvdyA9IGxheWVyLnBhaW50LmdldChcImhpbGxzaGFkZS1zaGFkb3ctY29sb3JcIik7XG4gICAgY29uc3QgaGlnaGxpZ2h0ID0gbGF5ZXIucGFpbnQuZ2V0KFwiaGlsbHNoYWRlLWhpZ2hsaWdodC1jb2xvclwiKTtcbiAgICBjb25zdCBhY2NlbnQgPSBsYXllci5wYWludC5nZXQoXCJoaWxsc2hhZGUtYWNjZW50LWNvbG9yXCIpO1xuXG4gICAgbGV0IGF6aW11dGhhbCA9IGxheWVyLnBhaW50LmdldCgnaGlsbHNoYWRlLWlsbHVtaW5hdGlvbi1kaXJlY3Rpb24nKSAqIChNYXRoLlBJIC8gMTgwKTtcbiAgICAvLyBtb2RpZnkgYXppbXV0aGFsIGFuZ2xlIGJ5IG1hcCByb3RhdGlvbiBpZiBsaWdodCBpcyBhbmNob3JlZCBhdCB0aGUgdmlld3BvcnRcbiAgICBpZiAobGF5ZXIucGFpbnQuZ2V0KCdoaWxsc2hhZGUtaWxsdW1pbmF0aW9uLWFuY2hvcicpID09PSAndmlld3BvcnQnKSB7XG4gICAgICAgIGF6aW11dGhhbCAtPSBwYWludGVyLnRyYW5zZm9ybS5hbmdsZTtcbiAgICB9XG4gICAgY29uc3QgYWxpZ24gPSAhcGFpbnRlci5vcHRpb25zLm1vdmluZztcbiAgICByZXR1cm4ge1xuICAgICAgICAndV9tYXRyaXgnOiBtYXRyaXggPyBtYXRyaXggOiBwYWludGVyLnRyYW5zZm9ybS5jYWxjdWxhdGVQcm9qTWF0cml4KHRpbGUudGlsZUlELnRvVW53cmFwcGVkKCksIGFsaWduKSxcbiAgICAgICAgJ3VfaW1hZ2UnOiAwLFxuICAgICAgICAndV9sYXRyYW5nZSc6IGdldFRpbGVMYXRSYW5nZShwYWludGVyLCB0aWxlLnRpbGVJRCksXG4gICAgICAgICd1X2xpZ2h0JzogW2xheWVyLnBhaW50LmdldCgnaGlsbHNoYWRlLWV4YWdnZXJhdGlvbicpLCBhemltdXRoYWxdLFxuICAgICAgICAndV9zaGFkb3cnOiBzaGFkb3csXG4gICAgICAgICd1X2hpZ2hsaWdodCc6IGhpZ2hsaWdodCxcbiAgICAgICAgJ3VfYWNjZW50JzogYWNjZW50XG4gICAgfTtcbn07XG5cbmNvbnN0IGhpbGxzaGFkZVVuaWZvcm1QcmVwYXJlVmFsdWVzID0gKFxuICAgIHRpbGVJRDogT3ZlcnNjYWxlZFRpbGVJRCwgZGVtOiBERU1EYXRhXG4pOiBVbmlmb3JtVmFsdWVzPEhpbGxzaGFkZVByZXBhcmVVbmlmb3Jtc1R5cGU+ID0+IHtcblxuICAgIGNvbnN0IHN0cmlkZSA9IGRlbS5zdHJpZGU7XG4gICAgY29uc3QgbWF0cml4ID0gbWF0NC5jcmVhdGUoKTtcbiAgICAvLyBGbGlwIHJlbmRlcmluZyBhdCB5IGF4aXMuXG4gICAgbWF0NC5vcnRobyhtYXRyaXgsIDAsIEVYVEVOVCwgLUVYVEVOVCwgMCwgMCwgMSk7XG4gICAgbWF0NC50cmFuc2xhdGUobWF0cml4LCBtYXRyaXgsIFswLCAtRVhURU5ULCAwXSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgICAndV9tYXRyaXgnOiBtYXRyaXgsXG4gICAgICAgICd1X2ltYWdlJzogMSxcbiAgICAgICAgJ3VfZGltZW5zaW9uJzogW3N0cmlkZSwgc3RyaWRlXSxcbiAgICAgICAgJ3Vfem9vbSc6IHRpbGVJRC5vdmVyc2NhbGVkWixcbiAgICAgICAgJ3VfdW5wYWNrJzogZGVtLnVucGFja1ZlY3RvclxuICAgIH07XG59O1xuXG5mdW5jdGlvbiBnZXRUaWxlTGF0UmFuZ2UocGFpbnRlcjogUGFpbnRlciwgdGlsZUlEOiBPdmVyc2NhbGVkVGlsZUlEKSB7XG4gICAgLy8gZm9yIHNjYWxpbmcgdGhlIG1hZ25pdHVkZSBvZiBhIHBvaW50cyBzbG9wZSBieSBpdHMgbGF0aXR1ZGVcbiAgICBjb25zdCB0aWxlc0F0Wm9vbSA9IE1hdGgucG93KDIsIHRpbGVJRC5jYW5vbmljYWwueik7XG4gICAgY29uc3QgeSA9IHRpbGVJRC5jYW5vbmljYWwueTtcbiAgICByZXR1cm4gW1xuICAgICAgICBuZXcgTWVyY2F0b3JDb29yZGluYXRlKDAsIHkgLyB0aWxlc0F0Wm9vbSkudG9MbmdMYXQoKS5sYXQsXG4gICAgICAgIG5ldyBNZXJjYXRvckNvb3JkaW5hdGUoMCwgKHkgKyAxKSAvIHRpbGVzQXRab29tKS50b0xuZ0xhdCgpLmxhdF07XG59XG5cbmV4cG9ydCB7XG4gICAgaGlsbHNoYWRlVW5pZm9ybXMsXG4gICAgaGlsbHNoYWRlUHJlcGFyZVVuaWZvcm1zLFxuICAgIGhpbGxzaGFkZVVuaWZvcm1WYWx1ZXMsXG4gICAgaGlsbHNoYWRlVW5pZm9ybVByZXBhcmVWYWx1ZXNcbn07XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgVGV4dHVyZSBmcm9tICcuL3RleHR1cmUuanMnO1xuaW1wb3J0IFN0ZW5jaWxNb2RlIGZyb20gJy4uL2dsL3N0ZW5jaWxfbW9kZS5qcyc7XG5pbXBvcnQgRGVwdGhNb2RlIGZyb20gJy4uL2dsL2RlcHRoX21vZGUuanMnO1xuaW1wb3J0IEN1bGxGYWNlTW9kZSBmcm9tICcuLi9nbC9jdWxsX2ZhY2VfbW9kZS5qcyc7XG5pbXBvcnQge1xuICAgIGhpbGxzaGFkZVVuaWZvcm1WYWx1ZXMsXG4gICAgaGlsbHNoYWRlVW5pZm9ybVByZXBhcmVWYWx1ZXNcbn0gZnJvbSAnLi9wcm9ncmFtL2hpbGxzaGFkZV9wcm9ncmFtLmpzJztcblxuaW1wb3J0IHR5cGUgUGFpbnRlciBmcm9tICcuL3BhaW50ZXIuanMnO1xuaW1wb3J0IHR5cGUgU291cmNlQ2FjaGUgZnJvbSAnLi4vc291cmNlL3NvdXJjZV9jYWNoZS5qcyc7XG5pbXBvcnQgdHlwZSBUaWxlIGZyb20gJy4uL3NvdXJjZS90aWxlLmpzJztcbmltcG9ydCB0eXBlIEhpbGxzaGFkZVN0eWxlTGF5ZXIgZnJvbSAnLi4vc3R5bGUvc3R5bGVfbGF5ZXIvaGlsbHNoYWRlX3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCB0eXBlIENvbG9yTW9kZSBmcm9tICcuLi9nbC9jb2xvcl9tb2RlLmpzJztcbmltcG9ydCB0eXBlIHtPdmVyc2NhbGVkVGlsZUlEfSBmcm9tICcuLi9zb3VyY2UvdGlsZV9pZC5qcyc7XG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgREVNRGF0YSBmcm9tICcuLi9kYXRhL2RlbV9kYXRhLmpzJztcblxuZXhwb3J0IGRlZmF1bHQgZHJhd0hpbGxzaGFkZTtcblxuZnVuY3Rpb24gZHJhd0hpbGxzaGFkZShwYWludGVyOiBQYWludGVyLCBzb3VyY2VDYWNoZTogU291cmNlQ2FjaGUsIGxheWVyOiBIaWxsc2hhZGVTdHlsZUxheWVyLCB0aWxlSURzOiBBcnJheTxPdmVyc2NhbGVkVGlsZUlEPikge1xuICAgIGlmIChwYWludGVyLnJlbmRlclBhc3MgIT09ICdvZmZzY3JlZW4nICYmIHBhaW50ZXIucmVuZGVyUGFzcyAhPT0gJ3RyYW5zbHVjZW50JykgcmV0dXJuO1xuXG4gICAgY29uc3QgY29udGV4dCA9IHBhaW50ZXIuY29udGV4dDtcblxuICAgIGNvbnN0IGRlcHRoTW9kZSA9IHBhaW50ZXIuZGVwdGhNb2RlRm9yU3VibGF5ZXIoMCwgRGVwdGhNb2RlLlJlYWRPbmx5KTtcbiAgICBjb25zdCBjb2xvck1vZGUgPSBwYWludGVyLmNvbG9yTW9kZUZvclJlbmRlclBhc3MoKTtcblxuICAgIC8vIFdoZW4gcmVuZGVyaW5nIHRvIHRleHR1cmUsIGNvb3JkaW5hdGVzIGFyZSBhbHJlYWR5IHNvcnRlZDogcHJpbWFyeSBieVxuICAgIC8vIHByb3h5IGlkIGFuZCBzZWNvbmRhcnkgc29ydCBpcyBieSBaLlxuICAgIGNvbnN0IHJlbmRlcmluZ1RvVGV4dHVyZSA9IHBhaW50ZXIudGVycmFpbiAmJiBwYWludGVyLnRlcnJhaW4ucmVuZGVyaW5nVG9UZXh0dXJlO1xuICAgIGNvbnN0IFtzdGVuY2lsTW9kZXMsIGNvb3Jkc10gPSBwYWludGVyLnJlbmRlclBhc3MgPT09ICd0cmFuc2x1Y2VudCcgJiYgIXJlbmRlcmluZ1RvVGV4dHVyZSA/XG4gICAgICAgIHBhaW50ZXIuc3RlbmNpbENvbmZpZ0Zvck92ZXJsYXAodGlsZUlEcykgOiBbe30sIHRpbGVJRHNdO1xuXG4gICAgZm9yIChjb25zdCBjb29yZCBvZiBjb29yZHMpIHtcbiAgICAgICAgY29uc3QgdGlsZSA9IHNvdXJjZUNhY2hlLmdldFRpbGUoY29vcmQpO1xuICAgICAgICBpZiAodGlsZS5uZWVkc0hpbGxzaGFkZVByZXBhcmUgJiYgcGFpbnRlci5yZW5kZXJQYXNzID09PSAnb2Zmc2NyZWVuJykge1xuICAgICAgICAgICAgcHJlcGFyZUhpbGxzaGFkZShwYWludGVyLCB0aWxlLCBsYXllciwgZGVwdGhNb2RlLCBTdGVuY2lsTW9kZS5kaXNhYmxlZCwgY29sb3JNb2RlKTtcbiAgICAgICAgfSBlbHNlIGlmIChwYWludGVyLnJlbmRlclBhc3MgPT09ICd0cmFuc2x1Y2VudCcpIHtcbiAgICAgICAgICAgIGNvbnN0IHN0ZW5jaWxNb2RlID0gcmVuZGVyaW5nVG9UZXh0dXJlICYmIHBhaW50ZXIudGVycmFpbiA/XG4gICAgICAgICAgICAgICAgcGFpbnRlci50ZXJyYWluLnN0ZW5jaWxNb2RlRm9yUlRUT3ZlcmxhcChjb29yZCkgOiBzdGVuY2lsTW9kZXNbY29vcmQub3ZlcnNjYWxlZFpdO1xuICAgICAgICAgICAgcmVuZGVySGlsbHNoYWRlKHBhaW50ZXIsIGNvb3JkLCB0aWxlLCBsYXllciwgZGVwdGhNb2RlLCBzdGVuY2lsTW9kZSwgY29sb3JNb2RlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbnRleHQudmlld3BvcnQuc2V0KFswLCAwLCBwYWludGVyLndpZHRoLCBwYWludGVyLmhlaWdodF0pO1xuXG4gICAgcGFpbnRlci5yZXNldFN0ZW5jaWxDbGlwcGluZ01hc2tzKCk7XG59XG5cbmZ1bmN0aW9uIHJlbmRlckhpbGxzaGFkZShwYWludGVyOiBQYWludGVyLCBjb29yZDogT3ZlcnNjYWxlZFRpbGVJRCwgdGlsZTogVGlsZSwgbGF5ZXI6IEhpbGxzaGFkZVN0eWxlTGF5ZXIsIGRlcHRoTW9kZTogRGVwdGhNb2RlLCBzdGVuY2lsTW9kZTogU3RlbmNpbE1vZGUsIGNvbG9yTW9kZTogQ29sb3JNb2RlKSB7XG4gICAgY29uc3QgY29udGV4dCA9IHBhaW50ZXIuY29udGV4dDtcbiAgICBjb25zdCBnbCA9IGNvbnRleHQuZ2w7XG4gICAgY29uc3QgZmJvID0gdGlsZS5mYm87XG4gICAgaWYgKCFmYm8pIHJldHVybjtcbiAgICBwYWludGVyLnByZXBhcmVEcmF3VGlsZSgpO1xuXG4gICAgY29uc3QgcHJvZ3JhbSA9IHBhaW50ZXIudXNlUHJvZ3JhbSgnaGlsbHNoYWRlJyk7XG5cbiAgICBjb250ZXh0LmFjdGl2ZVRleHR1cmUuc2V0KGdsLlRFWFRVUkUwKTtcbiAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCBmYm8uY29sb3JBdHRhY2htZW50LmdldCgpKTtcblxuICAgIGNvbnN0IHVuaWZvcm1WYWx1ZXMgPSBoaWxsc2hhZGVVbmlmb3JtVmFsdWVzKHBhaW50ZXIsIHRpbGUsIGxheWVyLCBwYWludGVyLnRlcnJhaW4gPyBjb29yZC5wcm9qTWF0cml4IDogbnVsbCk7XG5cbiAgICBwYWludGVyLnByZXBhcmVEcmF3UHJvZ3JhbShjb250ZXh0LCBwcm9ncmFtLCBjb29yZC50b1Vud3JhcHBlZCgpKTtcblxuICAgIGNvbnN0IHt0aWxlQm91bmRzQnVmZmVyLCB0aWxlQm91bmRzSW5kZXhCdWZmZXIsIHRpbGVCb3VuZHNTZWdtZW50c30gPSBwYWludGVyLmdldFRpbGVCb3VuZHNCdWZmZXJzKHRpbGUpO1xuXG4gICAgcHJvZ3JhbS5kcmF3KGNvbnRleHQsIGdsLlRSSUFOR0xFUywgZGVwdGhNb2RlLCBzdGVuY2lsTW9kZSwgY29sb3JNb2RlLCBDdWxsRmFjZU1vZGUuZGlzYWJsZWQsXG4gICAgICAgIHVuaWZvcm1WYWx1ZXMsIGxheWVyLmlkLCB0aWxlQm91bmRzQnVmZmVyLFxuICAgICAgICB0aWxlQm91bmRzSW5kZXhCdWZmZXIsIHRpbGVCb3VuZHNTZWdtZW50cyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwcmVwYXJlREVNVGV4dHVyZShwYWludGVyOiBQYWludGVyLCB0aWxlOiBUaWxlLCBkZW06IERFTURhdGEpIHtcbiAgICBpZiAoIXRpbGUubmVlZHNERU1UZXh0dXJlVXBsb2FkKSByZXR1cm47XG5cbiAgICBjb25zdCBjb250ZXh0ID0gcGFpbnRlci5jb250ZXh0O1xuICAgIGNvbnN0IGdsID0gY29udGV4dC5nbDtcblxuICAgIGNvbnRleHQucGl4ZWxTdG9yZVVucGFja1ByZW11bHRpcGx5QWxwaGEuc2V0KGZhbHNlKTtcbiAgICBjb25zdCB0ZXh0dXJlU3RyaWRlID0gZGVtLnN0cmlkZTtcbiAgICB0aWxlLmRlbVRleHR1cmUgPSB0aWxlLmRlbVRleHR1cmUgfHwgcGFpbnRlci5nZXRUaWxlVGV4dHVyZSh0ZXh0dXJlU3RyaWRlKTtcbiAgICBjb25zdCBwaXhlbERhdGEgPSBkZW0uZ2V0UGl4ZWxzKCk7XG4gICAgaWYgKHRpbGUuZGVtVGV4dHVyZSkge1xuICAgICAgICB0aWxlLmRlbVRleHR1cmUudXBkYXRlKHBpeGVsRGF0YSwge3ByZW11bHRpcGx5OiBmYWxzZX0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRpbGUuZGVtVGV4dHVyZSA9IG5ldyBUZXh0dXJlKGNvbnRleHQsIHBpeGVsRGF0YSwgZ2wuUkdCQSwge3ByZW11bHRpcGx5OiBmYWxzZX0pO1xuICAgIH1cbiAgICB0aWxlLm5lZWRzREVNVGV4dHVyZVVwbG9hZCA9IGZhbHNlO1xufVxuXG4vLyBoaWxsc2hhZGUgcmVuZGVyaW5nIGlzIGRvbmUgaW4gdHdvIHN0ZXBzLiB0aGUgcHJlcGFyZSBzdGVwIGZpcnN0IGNhbGN1bGF0ZXMgdGhlIHNsb3BlIG9mIHRoZSB0ZXJyYWluIGluIHRoZSB4IGFuZCB5XG4vLyBkaXJlY3Rpb25zIGZvciBlYWNoIHBpeGVsLCBhbmQgc2F2ZXMgdGhvc2UgdmFsdWVzIHRvIGEgZnJhbWVidWZmZXIgdGV4dHVyZSBpbiB0aGUgciBhbmQgZyBjaGFubmVscy5cbmZ1bmN0aW9uIHByZXBhcmVIaWxsc2hhZGUocGFpbnRlcjogUGFpbnRlciwgdGlsZTogVGlsZSwgbGF5ZXI6IEhpbGxzaGFkZVN0eWxlTGF5ZXIsIGRlcHRoTW9kZTogRGVwdGhNb2RlLCBzdGVuY2lsTW9kZTogU3RlbmNpbE1vZGUsIGNvbG9yTW9kZTogQ29sb3JNb2RlKSB7XG4gICAgY29uc3QgY29udGV4dCA9IHBhaW50ZXIuY29udGV4dDtcbiAgICBjb25zdCBnbCA9IGNvbnRleHQuZ2w7XG4gICAgaWYgKCF0aWxlLmRlbSkgcmV0dXJuO1xuICAgIGNvbnN0IGRlbTogREVNRGF0YSA9IHRpbGUuZGVtO1xuXG4gICAgY29udGV4dC5hY3RpdmVUZXh0dXJlLnNldChnbC5URVhUVVJFMSk7XG4gICAgcHJlcGFyZURFTVRleHR1cmUocGFpbnRlciwgdGlsZSwgZGVtKTtcbiAgICBhc3NlcnQodGlsZS5kZW1UZXh0dXJlKTtcbiAgICBpZiAoIXRpbGUuZGVtVGV4dHVyZSkgcmV0dXJuOyAvLyBTaWxlbmNlIGZsb3cuXG4gICAgdGlsZS5kZW1UZXh0dXJlLmJpbmQoZ2wuTkVBUkVTVCwgZ2wuQ0xBTVBfVE9fRURHRSk7XG4gICAgY29uc3QgdGlsZVNpemUgPSBkZW0uZGltO1xuXG4gICAgY29udGV4dC5hY3RpdmVUZXh0dXJlLnNldChnbC5URVhUVVJFMCk7XG4gICAgbGV0IGZibyA9IHRpbGUuZmJvO1xuICAgIGlmICghZmJvKSB7XG4gICAgICAgIGNvbnN0IHJlbmRlclRleHR1cmUgPSBuZXcgVGV4dHVyZShjb250ZXh0LCB7d2lkdGg6IHRpbGVTaXplLCBoZWlnaHQ6IHRpbGVTaXplLCBkYXRhOiBudWxsfSwgZ2wuUkdCQSk7XG4gICAgICAgIHJlbmRlclRleHR1cmUuYmluZChnbC5MSU5FQVIsIGdsLkNMQU1QX1RPX0VER0UpO1xuXG4gICAgICAgIGZibyA9IHRpbGUuZmJvID0gY29udGV4dC5jcmVhdGVGcmFtZWJ1ZmZlcih0aWxlU2l6ZSwgdGlsZVNpemUsIHRydWUpO1xuICAgICAgICBmYm8uY29sb3JBdHRhY2htZW50LnNldChyZW5kZXJUZXh0dXJlLnRleHR1cmUpO1xuICAgIH1cblxuICAgIGNvbnRleHQuYmluZEZyYW1lYnVmZmVyLnNldChmYm8uZnJhbWVidWZmZXIpO1xuICAgIGNvbnRleHQudmlld3BvcnQuc2V0KFswLCAwLCB0aWxlU2l6ZSwgdGlsZVNpemVdKTtcblxuICAgIGNvbnN0IHt0aWxlQm91bmRzQnVmZmVyLCB0aWxlQm91bmRzSW5kZXhCdWZmZXIsIHRpbGVCb3VuZHNTZWdtZW50c30gPSBwYWludGVyLmdldE1lcmNhdG9yVGlsZUJvdW5kc0J1ZmZlcnMoKTtcblxuICAgIHBhaW50ZXIudXNlUHJvZ3JhbSgnaGlsbHNoYWRlUHJlcGFyZScpLmRyYXcoY29udGV4dCwgZ2wuVFJJQU5HTEVTLFxuICAgICAgICBkZXB0aE1vZGUsIHN0ZW5jaWxNb2RlLCBjb2xvck1vZGUsIEN1bGxGYWNlTW9kZS5kaXNhYmxlZCxcbiAgICAgICAgaGlsbHNoYWRlVW5pZm9ybVByZXBhcmVWYWx1ZXModGlsZS50aWxlSUQsIGRlbSksXG4gICAgICAgIGxheWVyLmlkLCB0aWxlQm91bmRzQnVmZmVyLFxuICAgICAgICB0aWxlQm91bmRzSW5kZXhCdWZmZXIsIHRpbGVCb3VuZHNTZWdtZW50cyk7XG5cbiAgICB0aWxlLm5lZWRzSGlsbHNoYWRlUHJlcGFyZSA9IGZhbHNlO1xufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtcbiAgICBVbmlmb3JtMWksXG4gICAgVW5pZm9ybTFmLFxuICAgIFVuaWZvcm1NYXRyaXg0ZlxufSBmcm9tICcuLi9yZW5kZXIvdW5pZm9ybV9iaW5kaW5nLmpzJztcblxuaW1wb3J0IHR5cGUgQ29udGV4dCBmcm9tICcuLi9nbC9jb250ZXh0LmpzJztcbmltcG9ydCB0eXBlIHtVbmlmb3JtVmFsdWVzfSBmcm9tICcuLi9yZW5kZXIvdW5pZm9ybV9iaW5kaW5nLmpzJztcblxuZXhwb3J0IHR5cGUgVGVycmFpblJhc3RlclVuaWZvcm1zVHlwZSA9IHt8XG4gICAgJ3VfbWF0cml4JzogVW5pZm9ybU1hdHJpeDRmLFxuICAgICd1X2ltYWdlMCc6IFVuaWZvcm0xaSxcbiAgICAndV9za2lydF9oZWlnaHQnOiBVbmlmb3JtMWZcbnx9O1xuXG5jb25zdCB0ZXJyYWluUmFzdGVyVW5pZm9ybXMgPSAoY29udGV4dDogQ29udGV4dCk6IFRlcnJhaW5SYXN0ZXJVbmlmb3Jtc1R5cGUgPT4gKHtcbiAgICAndV9tYXRyaXgnOiBuZXcgVW5pZm9ybU1hdHJpeDRmKGNvbnRleHQpLFxuICAgICd1X2ltYWdlMCc6IG5ldyBVbmlmb3JtMWkoY29udGV4dCksXG4gICAgJ3Vfc2tpcnRfaGVpZ2h0JzogbmV3IFVuaWZvcm0xZihjb250ZXh0KVxufSk7XG5cbmNvbnN0IHRlcnJhaW5SYXN0ZXJVbmlmb3JtVmFsdWVzID0gKFxuICAgIG1hdHJpeDogRmxvYXQzMkFycmF5LFxuICAgIHNraXJ0SGVpZ2h0OiBudW1iZXJcbik6IFVuaWZvcm1WYWx1ZXM8VGVycmFpblJhc3RlclVuaWZvcm1zVHlwZT4gPT4gKHtcbiAgICAndV9tYXRyaXgnOiBtYXRyaXgsXG4gICAgJ3VfaW1hZ2UwJzogMCxcbiAgICAndV9za2lydF9oZWlnaHQnOiBza2lydEhlaWdodFxufSk7XG5cbmV4cG9ydCB7dGVycmFpblJhc3RlclVuaWZvcm1zLCB0ZXJyYWluUmFzdGVyVW5pZm9ybVZhbHVlc307XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge1xuICAgIFVuaWZvcm0xaSxcbiAgICBVbmlmb3JtMmYsXG4gICAgVW5pZm9ybTNmLFxuICAgIFVuaWZvcm00ZixcbiAgICBVbmlmb3JtTWF0cml4NGYsXG4gICAgVW5pZm9ybTFmLFxuICAgIFVuaWZvcm1NYXRyaXgzZlxufSBmcm9tICcuLi9yZW5kZXIvdW5pZm9ybV9iaW5kaW5nLmpzJztcbmltcG9ydCBicm93c2VyIGZyb20gJy4uL3V0aWwvYnJvd3Nlci5qcyc7XG5cbmltcG9ydCB0eXBlIENvbnRleHQgZnJvbSAnLi4vZ2wvY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSB7VW5pZm9ybVZhbHVlc30gZnJvbSAnLi4vcmVuZGVyL3VuaWZvcm1fYmluZGluZy5qcyc7XG5pbXBvcnQgdHlwZSB7TWF0NH0gZnJvbSAnZ2wtbWF0cml4JztcblxuZXhwb3J0IHR5cGUgR2xvYmVSYXN0ZXJVbmlmb3Jtc1R5cGUgPSB7fFxuICAgICd1X3Byb2pfbWF0cml4JzogVW5pZm9ybU1hdHJpeDRmLFxuICAgICd1X2dsb2JlX21hdHJpeCc6IFVuaWZvcm1NYXRyaXg0ZixcbiAgICAndV9ub3JtYWxpemVfbWF0cml4JzogVW5pZm9ybU1hdHJpeDRmLFxuICAgICd1X21lcmNfbWF0cml4JzogVW5pZm9ybU1hdHJpeDRmLFxuICAgICd1X3pvb21fdHJhbnNpdGlvbic6IFVuaWZvcm0xZixcbiAgICAndV9tZXJjX2NlbnRlcic6IFVuaWZvcm0yZixcbiAgICAndV9pbWFnZTAnOiBVbmlmb3JtMWksXG4gICAgJ3VfZ3JpZF9tYXRyaXgnOiBVbmlmb3JtTWF0cml4M2YsXG4gICAgJ3Vfc2tpcnRfaGVpZ2h0JzogVW5pZm9ybTFmLFxuICAgICd1X2ZydXN0dW1fdGwnOiBVbmlmb3JtM2YsXG4gICAgJ3VfZnJ1c3R1bV90cic6IFVuaWZvcm0zZixcbiAgICAndV9mcnVzdHVtX2JyJzogVW5pZm9ybTNmLFxuICAgICd1X2ZydXN0dW1fYmwnOiBVbmlmb3JtM2YsXG4gICAgJ3VfZ2xvYmVfcG9zJzogVW5pZm9ybTNmLFxuICAgICd1X2dsb2JlX3JhZGl1cyc6IFVuaWZvcm0xZixcbiAgICAndV92aWV3cG9ydCc6IFVuaWZvcm0yZlxufH07XG5cbmV4cG9ydCB0eXBlIEF0bW9zcGhlcmVVbmlmb3Jtc1R5cGUgPSB7fFxuICAgICd1X2ZydXN0dW1fdGwnOiBVbmlmb3JtM2YsXG4gICAgJ3VfZnJ1c3R1bV90cic6IFVuaWZvcm0zZixcbiAgICAndV9mcnVzdHVtX2JyJzogVW5pZm9ybTNmLFxuICAgICd1X2ZydXN0dW1fYmwnOiBVbmlmb3JtM2YsXG4gICAgJ3VfaG9yaXpvbic6IFVuaWZvcm0xZixcbiAgICAndV90cmFuc2l0aW9uJzogVW5pZm9ybTFmLFxuICAgICd1X2ZhZGVvdXRfcmFuZ2UnOiBVbmlmb3JtMWYsXG4gICAgJ3VfY29sb3InOiBVbmlmb3JtNGYsXG4gICAgJ3VfaGlnaF9jb2xvcic6IFVuaWZvcm00ZixcbiAgICAndV9zcGFjZV9jb2xvcic6IFVuaWZvcm00ZixcbiAgICAndV9zdGFyX2ludGVuc2l0eSc6IFVuaWZvcm0xZixcbiAgICAndV9zdGFyX3NpemUnOiBVbmlmb3JtMWYsXG4gICAgJ3Vfc3Rhcl9kZW5zaXR5JzogVW5pZm9ybTFmLFxuICAgICd1X3RlbXBvcmFsX29mZnNldCc6IFVuaWZvcm0xZixcbiAgICAndV9ob3Jpem9uX2FuZ2xlJzogVW5pZm9ybTFmLFxuICAgICd1X3JvdGF0aW9uX21hdHJpeCc6IFVuaWZvcm1NYXRyaXg0ZlxufH07XG5cbmNvbnN0IGdsb2JlUmFzdGVyVW5pZm9ybXMgPSAoY29udGV4dDogQ29udGV4dCk6IEdsb2JlUmFzdGVyVW5pZm9ybXNUeXBlID0+ICh7XG4gICAgJ3VfcHJval9tYXRyaXgnOiBuZXcgVW5pZm9ybU1hdHJpeDRmKGNvbnRleHQpLFxuICAgICd1X2dsb2JlX21hdHJpeCc6IG5ldyBVbmlmb3JtTWF0cml4NGYoY29udGV4dCksXG4gICAgJ3Vfbm9ybWFsaXplX21hdHJpeCc6IG5ldyBVbmlmb3JtTWF0cml4NGYoY29udGV4dCksXG4gICAgJ3VfbWVyY19tYXRyaXgnOiBuZXcgVW5pZm9ybU1hdHJpeDRmKGNvbnRleHQpLFxuICAgICd1X3pvb21fdHJhbnNpdGlvbic6IG5ldyBVbmlmb3JtMWYoY29udGV4dCksXG4gICAgJ3VfbWVyY19jZW50ZXInOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpLFxuICAgICd1X2ltYWdlMCc6IG5ldyBVbmlmb3JtMWkoY29udGV4dCksXG4gICAgJ3VfZ3JpZF9tYXRyaXgnOiBuZXcgVW5pZm9ybU1hdHJpeDNmKGNvbnRleHQpLFxuICAgICd1X3NraXJ0X2hlaWdodCc6IG5ldyBVbmlmb3JtMWYoY29udGV4dCksXG4gICAgJ3VfZnJ1c3R1bV90bCc6IG5ldyBVbmlmb3JtM2YoY29udGV4dCksXG4gICAgJ3VfZnJ1c3R1bV90cic6IG5ldyBVbmlmb3JtM2YoY29udGV4dCksXG4gICAgJ3VfZnJ1c3R1bV9icic6IG5ldyBVbmlmb3JtM2YoY29udGV4dCksXG4gICAgJ3VfZnJ1c3R1bV9ibCc6IG5ldyBVbmlmb3JtM2YoY29udGV4dCksXG4gICAgJ3VfZ2xvYmVfcG9zJzogbmV3IFVuaWZvcm0zZihjb250ZXh0KSxcbiAgICAndV9nbG9iZV9yYWRpdXMnOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X3ZpZXdwb3J0JzogbmV3IFVuaWZvcm0yZihjb250ZXh0KVxufSk7XG5cbmNvbnN0IGF0bW9zcGhlcmVVbmlmb3JtcyA9IChjb250ZXh0OiBDb250ZXh0KTogQXRtb3NwaGVyZVVuaWZvcm1zVHlwZSA9PiAoe1xuICAgICd1X2ZydXN0dW1fdGwnOiBuZXcgVW5pZm9ybTNmKGNvbnRleHQpLFxuICAgICd1X2ZydXN0dW1fdHInOiBuZXcgVW5pZm9ybTNmKGNvbnRleHQpLFxuICAgICd1X2ZydXN0dW1fYnInOiBuZXcgVW5pZm9ybTNmKGNvbnRleHQpLFxuICAgICd1X2ZydXN0dW1fYmwnOiBuZXcgVW5pZm9ybTNmKGNvbnRleHQpLFxuICAgICd1X2hvcml6b24nOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X3RyYW5zaXRpb24nOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X2ZhZGVvdXRfcmFuZ2UnOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X2NvbG9yJzogbmV3IFVuaWZvcm00Zihjb250ZXh0KSxcbiAgICAndV9oaWdoX2NvbG9yJzogbmV3IFVuaWZvcm00Zihjb250ZXh0KSxcbiAgICAndV9zcGFjZV9jb2xvcic6IG5ldyBVbmlmb3JtNGYoY29udGV4dCksXG4gICAgJ3Vfc3Rhcl9pbnRlbnNpdHknOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X3N0YXJfZGVuc2l0eSc6IG5ldyBVbmlmb3JtMWYoY29udGV4dCksXG4gICAgJ3Vfc3Rhcl9zaXplJzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV90ZW1wb3JhbF9vZmZzZXQnOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X2hvcml6b25fYW5nbGUnOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X3JvdGF0aW9uX21hdHJpeCc6IG5ldyBVbmlmb3JtTWF0cml4NGYoY29udGV4dClcbn0pO1xuXG5jb25zdCBnbG9iZVJhc3RlclVuaWZvcm1WYWx1ZXMgPSAoXG4gICAgcHJvak1hdHJpeDogTWF0NCxcbiAgICBnbG9iZU1hdHJpeDogRmxvYXQzMkFycmF5LFxuICAgIGdsb2JlTWVyY2F0b3JNYXRyaXg6IEZsb2F0MzJBcnJheSxcbiAgICBub3JtYWxpemVNYXRyaXg6IEZsb2F0NjRBcnJheSxcbiAgICB6b29tVHJhbnNpdGlvbjogbnVtYmVyLFxuICAgIG1lcmNDZW50ZXI6IFtudW1iZXIsIG51bWJlcl0sXG4gICAgZnJ1c3R1bURpclRsOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgZnJ1c3R1bURpclRyOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgZnJ1c3R1bURpckJyOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgZnJ1c3R1bURpckJsOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgZ2xvYmVQb3NpdGlvbjogW251bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgIGdsb2JlUmFkaXVzOiBudW1iZXIsXG4gICAgdmlld3BvcnQ6IFtudW1iZXIsIG51bWJlcl0sXG4gICAgc2tpcnRIZWlnaHQ6IG51bWJlcixcbiAgICBncmlkTWF0cml4OiA/TWF0NFxuKTogVW5pZm9ybVZhbHVlczxHbG9iZVJhc3RlclVuaWZvcm1zVHlwZT4gPT4gKHtcbiAgICAndV9wcm9qX21hdHJpeCc6IEZsb2F0MzJBcnJheS5mcm9tKHByb2pNYXRyaXgpLFxuICAgICd1X2dsb2JlX21hdHJpeCc6IGdsb2JlTWF0cml4LFxuICAgICd1X25vcm1hbGl6ZV9tYXRyaXgnOiBGbG9hdDMyQXJyYXkuZnJvbShub3JtYWxpemVNYXRyaXgpLFxuICAgICd1X21lcmNfbWF0cml4JzogZ2xvYmVNZXJjYXRvck1hdHJpeCxcbiAgICAndV96b29tX3RyYW5zaXRpb24nOiB6b29tVHJhbnNpdGlvbixcbiAgICAndV9tZXJjX2NlbnRlcic6IG1lcmNDZW50ZXIsXG4gICAgJ3VfaW1hZ2UwJzogMCxcbiAgICAndV9mcnVzdHVtX3RsJzogZnJ1c3R1bURpclRsLFxuICAgICd1X2ZydXN0dW1fdHInOiBmcnVzdHVtRGlyVHIsXG4gICAgJ3VfZnJ1c3R1bV9icic6IGZydXN0dW1EaXJCcixcbiAgICAndV9mcnVzdHVtX2JsJzogZnJ1c3R1bURpckJsLFxuICAgICd1X2dsb2JlX3Bvcyc6IGdsb2JlUG9zaXRpb24sXG4gICAgJ3VfZ2xvYmVfcmFkaXVzJzogZ2xvYmVSYWRpdXMsXG4gICAgJ3Vfdmlld3BvcnQnOiB2aWV3cG9ydCxcbiAgICAndV9ncmlkX21hdHJpeCc6IGdyaWRNYXRyaXggPyBGbG9hdDMyQXJyYXkuZnJvbShncmlkTWF0cml4KSA6IG5ldyBGbG9hdDMyQXJyYXkoOSksXG4gICAgJ3Vfc2tpcnRfaGVpZ2h0Jzogc2tpcnRIZWlnaHRcbn0pO1xuXG5jb25zdCBhdG1vc3BoZXJlVW5pZm9ybVZhbHVlcyA9IChcbiAgICBmcnVzdHVtRGlyVGw6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICBmcnVzdHVtRGlyVHI6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICBmcnVzdHVtRGlyQnI6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICBmcnVzdHVtRGlyQmw6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICBob3Jpem9uOiBudW1iZXIsXG4gICAgdHJhbnNpdGlvblQ6IG51bWJlcixcbiAgICBmYWRlb3V0UmFuZ2U6IG51bWJlcixcbiAgICBjb2xvcjogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgaGlnaENvbG9yOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICBzcGFjZUNvbG9yOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICBzdGFySW50ZW5zaXR5OiBudW1iZXIsXG4gICAgdGVtcG9yYWxPZmZzZXQ6IG51bWJlcixcbiAgICBob3Jpem9uQW5nbGU6IG51bWJlcixcbiAgICByb3RhdGlvbk1hdHJpeDogRmxvYXQzMkFycmF5XG4pOiBVbmlmb3JtVmFsdWVzPEF0bW9zcGhlcmVVbmlmb3Jtc1R5cGU+ID0+ICh7XG4gICAgJ3VfZnJ1c3R1bV90bCc6IGZydXN0dW1EaXJUbCxcbiAgICAndV9mcnVzdHVtX3RyJzogZnJ1c3R1bURpclRyLFxuICAgICd1X2ZydXN0dW1fYnInOiBmcnVzdHVtRGlyQnIsXG4gICAgJ3VfZnJ1c3R1bV9ibCc6IGZydXN0dW1EaXJCbCxcbiAgICAndV9ob3Jpem9uJzogaG9yaXpvbixcbiAgICAndV90cmFuc2l0aW9uJzogdHJhbnNpdGlvblQsXG4gICAgJ3VfZmFkZW91dF9yYW5nZSc6IGZhZGVvdXRSYW5nZSxcbiAgICAndV9jb2xvcic6IGNvbG9yLFxuICAgICd1X2hpZ2hfY29sb3InOiBoaWdoQ29sb3IsXG4gICAgJ3Vfc3BhY2VfY29sb3InOiBzcGFjZUNvbG9yLFxuICAgICd1X3N0YXJfaW50ZW5zaXR5Jzogc3RhckludGVuc2l0eSxcbiAgICAndV9zdGFyX3NpemUnOiA1LjAgKiBicm93c2VyLmRldmljZVBpeGVsUmF0aW8sXG4gICAgJ3Vfc3Rhcl9kZW5zaXR5JzogMC4wLFxuICAgICd1X3RlbXBvcmFsX29mZnNldCc6IHRlbXBvcmFsT2Zmc2V0LFxuICAgICd1X2hvcml6b25fYW5nbGUnOiBob3Jpem9uQW5nbGUsXG4gICAgJ3Vfcm90YXRpb25fbWF0cml4Jzogcm90YXRpb25NYXRyaXhcbn0pO1xuXG5leHBvcnQge2dsb2JlUmFzdGVyVW5pZm9ybXMsIGdsb2JlUmFzdGVyVW5pZm9ybVZhbHVlcywgYXRtb3NwaGVyZVVuaWZvcm1zLCBhdG1vc3BoZXJlVW5pZm9ybVZhbHVlc307XG5cbmV4cG9ydCB0eXBlIEdsb2JlRGVmaW5lc1R5cGUgPSAnUFJPSkVDVElPTl9HTE9CRV9WSUVXJyB8ICdHTE9CRV9QT0xFUycgfCAnQ1VTVE9NX0FOVElBTElBU0lORyc7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgRGVwdGhNb2RlIGZyb20gJy4uL2dsL2RlcHRoX21vZGUuanMnO1xuaW1wb3J0IEN1bGxGYWNlTW9kZSBmcm9tICcuLi9nbC9jdWxsX2ZhY2VfbW9kZS5qcyc7XG5pbXBvcnQge3RlcnJhaW5SYXN0ZXJVbmlmb3JtVmFsdWVzfSBmcm9tICcuL3RlcnJhaW5fcmFzdGVyX3Byb2dyYW0uanMnO1xuaW1wb3J0IHtnbG9iZVJhc3RlclVuaWZvcm1WYWx1ZXN9IGZyb20gJy4vZ2xvYmVfcmFzdGVyX3Byb2dyYW0uanMnO1xuaW1wb3J0IHtUZXJyYWlufSBmcm9tICcuL3RlcnJhaW4uanMnO1xuaW1wb3J0IFRpbGUgZnJvbSAnLi4vc291cmNlL3RpbGUuanMnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHtlYXNlQ3ViaWNJbk91dH0gZnJvbSAnLi4vdXRpbC91dGlsLmpzJztcbmltcG9ydCBicm93c2VyIGZyb20gJy4uL3V0aWwvYnJvd3Nlci5qcyc7XG5pbXBvcnQge21lcmNhdG9yWGZyb21MbmcsIG1lcmNhdG9yWWZyb21MYXR9IGZyb20gJy4uL2dlby9tZXJjYXRvcl9jb29yZGluYXRlLmpzJztcbmltcG9ydCB0eXBlIFBhaW50ZXIgZnJvbSAnLi4vcmVuZGVyL3BhaW50ZXIuanMnO1xuaW1wb3J0IHR5cGUgU291cmNlQ2FjaGUgZnJvbSAnLi4vc291cmNlL3NvdXJjZV9jYWNoZS5qcyc7XG5pbXBvcnQge092ZXJzY2FsZWRUaWxlSUQsIENhbm9uaWNhbFRpbGVJRH0gZnJvbSAnLi4vc291cmNlL3RpbGVfaWQuanMnO1xuaW1wb3J0IFN0ZW5jaWxNb2RlIGZyb20gJy4uL2dsL3N0ZW5jaWxfbW9kZS5qcyc7XG5pbXBvcnQgQ29sb3JNb2RlIGZyb20gJy4uL2dsL2NvbG9yX21vZGUuanMnO1xuaW1wb3J0IHttYXQ0fSBmcm9tICdnbC1tYXRyaXgnO1xuaW1wb3J0IHtcbiAgICBjYWxjdWxhdGVHbG9iZU1lcmNhdG9yTWF0cml4LFxuICAgIGdsb2JlVG9NZXJjYXRvclRyYW5zaXRpb24sXG4gICAgZ2xvYmVQb2xlTWF0cml4Rm9yVGlsZSxcbiAgICBnZXRHcmlkTWF0cml4LFxuICAgIHRpbGVDb3JuZXJzVG9Cb3VuZHMsXG4gICAgZ2xvYmVOb3JtYWxpemVFQ0VGLFxuICAgIGdsb2JlVGlsZUJvdW5kcyxcbiAgICBnbG9iZVVzZUN1c3RvbUFudGlBbGlhc2luZyxcbiAgICBnZXRMYXRpdHVkaW5hbExvZFxufSBmcm9tICcuLi9nZW8vcHJvamVjdGlvbi9nbG9iZV91dGlsLmpzJztcbmltcG9ydCBleHRlbmQgZnJvbSAnLi4vc3R5bGUtc3BlYy91dGlsL2V4dGVuZC5qcyc7XG5pbXBvcnQgdHlwZSBQcm9ncmFtIGZyb20gJy4uL3JlbmRlci9wcm9ncmFtLmpzJztcbmltcG9ydCB0eXBlIFZlcnRleEJ1ZmZlciBmcm9tIFwiLi4vZ2wvdmVydGV4X2J1ZmZlci5qc1wiO1xuXG5leHBvcnQge1xuICAgIGRyYXdUZXJyYWluUmFzdGVyLFxuICAgIGRyYXdUZXJyYWluRGVwdGhcbn07XG5cbnR5cGUgREVNQ2hhaW4gPSB7XG4gICAgc3RhcnRUaW1lOiBudW1iZXIsXG4gICAgcGhhc2U6IG51bWJlcixcbiAgICBkdXJhdGlvbjogbnVtYmVyLCAgIC8vIEludGVycG9sYXRpb24gZHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzXG4gICAgZnJvbTogVGlsZSxcbiAgICB0bzogVGlsZSxcbiAgICBxdWV1ZWQ6ID9UaWxlXG59O1xuXG5jbGFzcyBWZXJ0ZXhNb3JwaGluZyB7XG4gICAgb3BlcmF0aW9uczoge1tzdHJpbmcgfCBudW1iZXJdOiBERU1DaGFpbiB9O1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMub3BlcmF0aW9ucyA9IHt9O1xuICAgIH1cblxuICAgIG5ld01vcnBoaW5nKGtleTogbnVtYmVyLCBmcm9tOiBUaWxlLCB0bzogVGlsZSwgbm93OiBudW1iZXIsIGR1cmF0aW9uOiBudW1iZXIpIHtcbiAgICAgICAgYXNzZXJ0KGZyb20uZGVtVGV4dHVyZSAmJiB0by5kZW1UZXh0dXJlKTtcbiAgICAgICAgYXNzZXJ0KGZyb20udGlsZUlELmtleSAhPT0gdG8udGlsZUlELmtleSk7XG5cbiAgICAgICAgaWYgKGtleSBpbiB0aGlzLm9wZXJhdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG9wID0gdGhpcy5vcGVyYXRpb25zW2tleV07XG4gICAgICAgICAgICBhc3NlcnQob3AuZnJvbSAmJiBvcC50byk7XG4gICAgICAgICAgICAvLyBRdWV1ZSB0aGUgdGFyZ2V0IHRpbGUgdW5sZXNzIGl0J3MgYmVpbmcgbW9ycGhlZCB0byBhbHJlYWR5XG4gICAgICAgICAgICBpZiAob3AudG8udGlsZUlELmtleSAhPT0gdG8udGlsZUlELmtleSlcbiAgICAgICAgICAgICAgICBvcC5xdWV1ZWQgPSB0bztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMub3BlcmF0aW9uc1trZXldID0ge1xuICAgICAgICAgICAgICAgIHN0YXJ0VGltZTogbm93LFxuICAgICAgICAgICAgICAgIHBoYXNlOiAwLjAsXG4gICAgICAgICAgICAgICAgZHVyYXRpb24sXG4gICAgICAgICAgICAgICAgZnJvbSxcbiAgICAgICAgICAgICAgICB0byxcbiAgICAgICAgICAgICAgICBxdWV1ZWQ6IG51bGxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRNb3JwaFZhbHVlc0ZvclByb3h5KGtleTogbnVtYmVyKTogP3tmcm9tOiBUaWxlLCB0bzogVGlsZSwgcGhhc2U6IG51bWJlcn0ge1xuICAgICAgICBpZiAoIShrZXkgaW4gdGhpcy5vcGVyYXRpb25zKSlcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgICAgIGNvbnN0IG9wID0gdGhpcy5vcGVyYXRpb25zW2tleV07XG4gICAgICAgIGNvbnN0IGZyb20gPSBvcC5mcm9tO1xuICAgICAgICBjb25zdCB0byA9IG9wLnRvO1xuICAgICAgICBhc3NlcnQoZnJvbSAmJiB0byk7XG5cbiAgICAgICAgcmV0dXJuIHtmcm9tLCB0bywgcGhhc2U6IG9wLnBoYXNlfTtcbiAgICB9XG5cbiAgICB1cGRhdGUobm93OiBudW1iZXIpIHtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gdGhpcy5vcGVyYXRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBvcCA9IHRoaXMub3BlcmF0aW9uc1trZXldO1xuICAgICAgICAgICAgYXNzZXJ0KG9wLmZyb20gJiYgb3AudG8pO1xuXG4gICAgICAgICAgICBvcC5waGFzZSA9IChub3cgLSBvcC5zdGFydFRpbWUpIC8gb3AuZHVyYXRpb247XG5cbiAgICAgICAgICAgIC8vIFN0YXJ0IHRoZSBxdWV1ZWQgb3BlcmF0aW9uIGlmIHRoZSBjdXJyZW50IG9uZSBpcyBmaW5pc2hlZCBvciB0aGUgZGF0YSBoYXMgZXhwaXJlZFxuICAgICAgICAgICAgd2hpbGUgKG9wLnBoYXNlID49IDEuMCB8fCAhdGhpcy5fdmFsaWRPcChvcCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX25leHRPcChvcCwgbm93KSkge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5vcGVyYXRpb25zW2tleV07XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9uZXh0T3Aob3A6IERFTUNoYWluLCBub3c6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgICAgICBpZiAoIW9wLnF1ZXVlZClcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgb3AuZnJvbSA9IG9wLnRvO1xuICAgICAgICBvcC50byA9IG9wLnF1ZXVlZDtcbiAgICAgICAgb3AucXVldWVkID0gbnVsbDtcbiAgICAgICAgb3AucGhhc2UgPSAwLjA7XG4gICAgICAgIG9wLnN0YXJ0VGltZSA9IG5vdztcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgX3ZhbGlkT3Aob3A6IERFTUNoYWluKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBvcC5mcm9tLmhhc0RhdGEoKSAmJiBvcC50by5oYXNEYXRhKCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkZW1UaWxlQ2hhbmdlZChwcmV2OiA/VGlsZSwgbmV4dDogP1RpbGUpOiBib29sZWFuIHtcbiAgICBpZiAocHJldiA9PSBudWxsIHx8IG5leHQgPT0gbnVsbClcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGlmICghcHJldi5oYXNEYXRhKCkgfHwgIW5leHQuaGFzRGF0YSgpKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgaWYgKHByZXYuZGVtVGV4dHVyZSA9PSBudWxsIHx8IG5leHQuZGVtVGV4dHVyZSA9PSBudWxsKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIHByZXYudGlsZUlELmtleSAhPT0gbmV4dC50aWxlSUQua2V5O1xufVxuXG5jb25zdCB2ZXJ0ZXhNb3JwaGluZyA9IG5ldyBWZXJ0ZXhNb3JwaGluZygpO1xuY29uc3QgU0hBREVSX0RFRkFVTFQgPSAwO1xuY29uc3QgU0hBREVSX01PUlBISU5HID0gMTtcbmNvbnN0IFNIQURFUl9URVJSQUlOX1dJUkVGUkFNRSA9IDI7XG5jb25zdCBkZWZhdWx0RHVyYXRpb24gPSAyNTA7XG5cbmNvbnN0IHNoYWRlckRlZmluZXMgPSB7XG4gICAgXCIwXCI6IG51bGwsXG4gICAgXCIxXCI6ICdURVJSQUlOX1ZFUlRFWF9NT1JQSElORycsXG4gICAgXCIyXCI6ICdURVJSQUlOX1dJUkVGUkFNRSdcbn07XG5cbmZ1bmN0aW9uIGRyYXdUZXJyYWluRm9yR2xvYmUocGFpbnRlcjogUGFpbnRlciwgdGVycmFpbjogVGVycmFpbiwgc291cmNlQ2FjaGU6IFNvdXJjZUNhY2hlLCB0aWxlSURzOiBBcnJheTxPdmVyc2NhbGVkVGlsZUlEPiwgbm93OiBudW1iZXIpIHtcbiAgICBjb25zdCBjb250ZXh0ID0gcGFpbnRlci5jb250ZXh0O1xuICAgIGNvbnN0IGdsID0gY29udGV4dC5nbDtcblxuICAgIGxldCBwcm9ncmFtLCBwcm9ncmFtTW9kZTtcbiAgICBjb25zdCBzaG93V2lyZWZyYW1lID0gcGFpbnRlci5vcHRpb25zLnNob3dUZXJyYWluV2lyZWZyYW1lID8gU0hBREVSX1RFUlJBSU5fV0lSRUZSQU1FIDogU0hBREVSX0RFRkFVTFQ7XG4gICAgY29uc3QgdHIgPSBwYWludGVyLnRyYW5zZm9ybTtcbiAgICBjb25zdCB1c2VDdXN0b21BbnRpYWxpYXNpbmcgPSBnbG9iZVVzZUN1c3RvbUFudGlBbGlhc2luZyhwYWludGVyLCBjb250ZXh0LCB0cik7XG5cbiAgICBjb25zdCBzZXRTaGFkZXJNb2RlID0gKG1vZGU6IG51bWJlciwgaXNXaXJlZnJhbWU6IGJvb2xlYW4pID0+IHtcbiAgICAgICAgaWYgKHByb2dyYW1Nb2RlID09PSBtb2RlKSByZXR1cm47XG4gICAgICAgIGNvbnN0IGRlZmluZXMgPSBbc2hhZGVyRGVmaW5lc1ttb2RlXSwgJ1BST0pFQ1RJT05fR0xPQkVfVklFVyddO1xuXG4gICAgICAgIGlmICh1c2VDdXN0b21BbnRpYWxpYXNpbmcpIGRlZmluZXMucHVzaCgnQ1VTVE9NX0FOVElBTElBU0lORycpO1xuICAgICAgICBpZiAoaXNXaXJlZnJhbWUpIGRlZmluZXMucHVzaChzaGFkZXJEZWZpbmVzW3Nob3dXaXJlZnJhbWVdKTtcblxuICAgICAgICBwcm9ncmFtID0gcGFpbnRlci51c2VQcm9ncmFtKCdnbG9iZVJhc3RlcicsIG51bGwsIGRlZmluZXMpO1xuICAgICAgICBwcm9ncmFtTW9kZSA9IG1vZGU7XG4gICAgfTtcblxuICAgIGNvbnN0IGNvbG9yTW9kZSA9IHBhaW50ZXIuY29sb3JNb2RlRm9yUmVuZGVyUGFzcygpO1xuICAgIGNvbnN0IGRlcHRoTW9kZSA9IG5ldyBEZXB0aE1vZGUoZ2wuTEVRVUFMLCBEZXB0aE1vZGUuUmVhZFdyaXRlLCBwYWludGVyLmRlcHRoUmFuZ2VGb3IzRCk7XG4gICAgdmVydGV4TW9ycGhpbmcudXBkYXRlKG5vdyk7XG4gICAgY29uc3QgZ2xvYmVNZXJjYXRvck1hdHJpeCA9IGNhbGN1bGF0ZUdsb2JlTWVyY2F0b3JNYXRyaXgodHIpO1xuICAgIGNvbnN0IG1lcmNhdG9yQ2VudGVyID0gW21lcmNhdG9yWGZyb21MbmcodHIuY2VudGVyLmxuZyksIG1lcmNhdG9yWWZyb21MYXQodHIuY2VudGVyLmxhdCldO1xuICAgIGNvbnN0IGJhdGNoZXMgPSBzaG93V2lyZWZyYW1lID8gW2ZhbHNlLCB0cnVlXSA6IFtmYWxzZV07XG4gICAgY29uc3Qgc2hhcmVkQnVmZmVycyA9IHBhaW50ZXIuZ2xvYmVTaGFyZWRCdWZmZXJzO1xuICAgIGNvbnN0IHZpZXdwb3J0ID0gW3RyLndpZHRoICogYnJvd3Nlci5kZXZpY2VQaXhlbFJhdGlvLCB0ci5oZWlnaHQgKiBicm93c2VyLmRldmljZVBpeGVsUmF0aW9dO1xuICAgIGNvbnN0IGdsb2JlTWF0cml4ID0gRmxvYXQzMkFycmF5LmZyb20odHIuZ2xvYmVNYXRyaXgpO1xuICAgIGNvbnN0IGVsZXZhdGlvbk9wdGlvbnMgPSB7dXNlRGVub3JtYWxpemVkVXBWZWN0b3JTY2FsZTogdHJ1ZX07XG5cbiAgICBiYXRjaGVzLmZvckVhY2goaXNXaXJlZnJhbWUgPT4ge1xuICAgICAgICBjb25zdCB0ciA9IHBhaW50ZXIudHJhbnNmb3JtO1xuICAgICAgICBjb25zdCBza2lydEhlaWdodFZhbHVlID0gc2tpcnRIZWlnaHQodHIuem9vbSkgKiB0ZXJyYWluLmV4YWdnZXJhdGlvbigpO1xuXG4gICAgICAgIC8vIFRoaXMgY29kZSBhc3N1bWVzIHRoZSByZW5kZXJpbmcgaXMgYmF0Y2hlZCBpbnRvIG1lc2ggdGVycmFpbiBhbmQgdGhlbiB3aXJlZnJhbWVcbiAgICAgICAgLy8gdGVycmFpbiAoaWYgYXBwbGljYWJsZSkgc28gdGhhdCB0aGlzIGlzIGVub3VnaCB0byBlbnN1cmUgdGhlIGNvcnJlY3QgcHJvZ3JhbSBpc1xuICAgICAgICAvLyBzZXQgd2hlbiB3ZSBzd2l0Y2ggZnJvbSBvbmUgdG8gdGhlIG90aGVyLlxuICAgICAgICBwcm9ncmFtTW9kZSA9IC0xO1xuXG4gICAgICAgIGNvbnN0IHByaW1pdGl2ZSA9IGlzV2lyZWZyYW1lID8gZ2wuTElORVMgOiBnbC5UUklBTkdMRVM7XG5cbiAgICAgICAgZm9yIChjb25zdCBjb29yZCBvZiB0aWxlSURzKSB7XG4gICAgICAgICAgICBjb25zdCB0aWxlID0gc291cmNlQ2FjaGUuZ2V0VGlsZShjb29yZCk7XG4gICAgICAgICAgICBjb25zdCBzdGVuY2lsTW9kZSA9IFN0ZW5jaWxNb2RlLmRpc2FibGVkO1xuXG4gICAgICAgICAgICBjb25zdCBwcmV2RGVtVGlsZSA9IHRlcnJhaW4ucHJldlRlcnJhaW5UaWxlRm9yVGlsZVtjb29yZC5rZXldO1xuICAgICAgICAgICAgY29uc3QgbmV4dERlbVRpbGUgPSB0ZXJyYWluLnRlcnJhaW5UaWxlRm9yVGlsZVtjb29yZC5rZXldO1xuXG4gICAgICAgICAgICBpZiAoZGVtVGlsZUNoYW5nZWQocHJldkRlbVRpbGUsIG5leHREZW1UaWxlKSkge1xuICAgICAgICAgICAgICAgIHZlcnRleE1vcnBoaW5nLm5ld01vcnBoaW5nKGNvb3JkLmtleSwgcHJldkRlbVRpbGUsIG5leHREZW1UaWxlLCBub3csIGRlZmF1bHREdXJhdGlvbik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEJpbmQgdGhlIG1haW4gZHJhcGVkIHRleHR1cmVcbiAgICAgICAgICAgIGNvbnRleHQuYWN0aXZlVGV4dHVyZS5zZXQoZ2wuVEVYVFVSRTApO1xuICAgICAgICAgICAgdGlsZS50ZXh0dXJlLmJpbmQoZ2wuTElORUFSLCBnbC5DTEFNUF9UT19FREdFKTtcblxuICAgICAgICAgICAgY29uc3QgbW9ycGggPSB2ZXJ0ZXhNb3JwaGluZy5nZXRNb3JwaFZhbHVlc0ZvclByb3h5KGNvb3JkLmtleSk7XG4gICAgICAgICAgICBjb25zdCBzaGFkZXJNb2RlID0gbW9ycGggPyBTSEFERVJfTU9SUEhJTkcgOiBTSEFERVJfREVGQVVMVDtcblxuICAgICAgICAgICAgaWYgKG1vcnBoKSB7XG4gICAgICAgICAgICAgICAgZXh0ZW5kKGVsZXZhdGlvbk9wdGlvbnMsIHttb3JwaGluZzoge3NyY0RlbVRpbGU6IG1vcnBoLmZyb20sIGRzdERlbVRpbGU6IG1vcnBoLnRvLCBwaGFzZTogZWFzZUN1YmljSW5PdXQobW9ycGgucGhhc2UpfX0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCB0aWxlQm91bmRzID0gdGlsZUNvcm5lcnNUb0JvdW5kcyhjb29yZC5jYW5vbmljYWwpO1xuICAgICAgICAgICAgY29uc3QgbGF0aXR1ZGluYWxMb2QgPSBnZXRMYXRpdHVkaW5hbExvZCh0aWxlQm91bmRzLmdldENlbnRlcigpLmxhdCk7XG4gICAgICAgICAgICBjb25zdCBncmlkTWF0cml4ID0gZ2V0R3JpZE1hdHJpeChjb29yZC5jYW5vbmljYWwsIHRpbGVCb3VuZHMsIGxhdGl0dWRpbmFsTG9kLCB0ci53b3JsZFNpemUgLyB0ci5fcGl4ZWxzUGVyTWVyY2F0b3JQaXhlbCk7XG4gICAgICAgICAgICBjb25zdCBub3JtYWxpemVNYXRyaXggPSBnbG9iZU5vcm1hbGl6ZUVDRUYoZ2xvYmVUaWxlQm91bmRzKGNvb3JkLmNhbm9uaWNhbCkpO1xuICAgICAgICAgICAgY29uc3QgdW5pZm9ybVZhbHVlcyA9IGdsb2JlUmFzdGVyVW5pZm9ybVZhbHVlcyhcbiAgICAgICAgICAgICAgICB0ci5wcm9qTWF0cml4LCBnbG9iZU1hdHJpeCwgZ2xvYmVNZXJjYXRvck1hdHJpeCwgbm9ybWFsaXplTWF0cml4LCBnbG9iZVRvTWVyY2F0b3JUcmFuc2l0aW9uKHRyLnpvb20pLFxuICAgICAgICAgICAgICAgIG1lcmNhdG9yQ2VudGVyLCB0ci5mcnVzdHVtQ29ybmVycy5UTCwgdHIuZnJ1c3R1bUNvcm5lcnMuVFIsIHRyLmZydXN0dW1Db3JuZXJzLkJSLFxuICAgICAgICAgICAgICAgIHRyLmZydXN0dW1Db3JuZXJzLkJMLCB0ci5nbG9iZUNlbnRlckluVmlld1NwYWNlLCB0ci5nbG9iZVJhZGl1cywgdmlld3BvcnQsIHNraXJ0SGVpZ2h0VmFsdWUsIGdyaWRNYXRyaXgpO1xuXG4gICAgICAgICAgICBzZXRTaGFkZXJNb2RlKHNoYWRlck1vZGUsIGlzV2lyZWZyYW1lKTtcblxuICAgICAgICAgICAgdGVycmFpbi5zZXR1cEVsZXZhdGlvbkRyYXcodGlsZSwgcHJvZ3JhbSwgZWxldmF0aW9uT3B0aW9ucyk7XG5cbiAgICAgICAgICAgIHBhaW50ZXIucHJlcGFyZURyYXdQcm9ncmFtKGNvbnRleHQsIHByb2dyYW0sIGNvb3JkLnRvVW53cmFwcGVkKCkpO1xuXG4gICAgICAgICAgICBpZiAoc2hhcmVkQnVmZmVycykge1xuICAgICAgICAgICAgICAgIGNvbnN0IFtidWZmZXIsIGluZGV4QnVmZmVyLCBzZWdtZW50c10gPSBpc1dpcmVmcmFtZSA/XG4gICAgICAgICAgICAgICAgICAgIHNoYXJlZEJ1ZmZlcnMuZ2V0V2lyZWZhbWVCdWZmZXJzKHBhaW50ZXIuY29udGV4dCwgbGF0aXR1ZGluYWxMb2QpIDpcbiAgICAgICAgICAgICAgICAgICAgc2hhcmVkQnVmZmVycy5nZXRHcmlkQnVmZmVycyhsYXRpdHVkaW5hbExvZCwgc2tpcnRIZWlnaHRWYWx1ZSAhPT0gMCk7XG5cbiAgICAgICAgICAgICAgICBwcm9ncmFtLmRyYXcoY29udGV4dCwgcHJpbWl0aXZlLCBkZXB0aE1vZGUsIHN0ZW5jaWxNb2RlLCBjb2xvck1vZGUsIEN1bGxGYWNlTW9kZS5iYWNrQ0NXLFxuICAgICAgICAgICAgICAgICAgICB1bmlmb3JtVmFsdWVzLCBcImdsb2JlX3Jhc3RlclwiLCBidWZmZXIsIGluZGV4QnVmZmVyLCBzZWdtZW50cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIFJlbmRlciB0aGUgcG9sZXMuXG4gICAgaWYgKHNoYXJlZEJ1ZmZlcnMpIHtcbiAgICAgICAgY29uc3QgZGVmaW5lcyA9IFsnR0xPQkVfUE9MRVMnLCAnUFJPSkVDVElPTl9HTE9CRV9WSUVXJ107XG4gICAgICAgIGlmICh1c2VDdXN0b21BbnRpYWxpYXNpbmcpIGRlZmluZXMucHVzaCgnQ1VTVE9NX0FOVElBTElBU0lORycpO1xuXG4gICAgICAgIHByb2dyYW0gPSBwYWludGVyLnVzZVByb2dyYW0oJ2dsb2JlUmFzdGVyJywgbnVsbCwgZGVmaW5lcyk7XG4gICAgICAgIGZvciAoY29uc3QgY29vcmQgb2YgdGlsZUlEcykge1xuICAgICAgICAgICAgLy8gRmlsbCBwb2xlcyBieSBleHRyYXBvbGF0aW5nIGFkamFjZW50IGJvcmRlciB0aWxlc1xuICAgICAgICAgICAgY29uc3Qge3gsIHksIHp9ID0gY29vcmQuY2Fub25pY2FsO1xuICAgICAgICAgICAgY29uc3QgdG9wQ2FwID0geSA9PT0gMDtcbiAgICAgICAgICAgIGNvbnN0IGJvdHRvbUNhcCA9IHkgPT09ICgxIDw8IHopIC0gMTtcblxuICAgICAgICAgICAgY29uc3QgW25vcnRoUG9sZUJ1ZmZlciwgc291dGhQb2xlQnVmZmVyLCBpbmRleEJ1ZmZlciwgc2VnbWVudF0gPSBzaGFyZWRCdWZmZXJzLmdldFBvbGVCdWZmZXJzKHopO1xuXG4gICAgICAgICAgICBpZiAoc2VnbWVudCAmJiAodG9wQ2FwIHx8IGJvdHRvbUNhcCkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0aWxlID0gc291cmNlQ2FjaGUuZ2V0VGlsZShjb29yZCk7XG5cbiAgICAgICAgICAgICAgICAvLyBCaW5kIHRoZSBtYWluIGRyYXBlZCB0ZXh0dXJlXG4gICAgICAgICAgICAgICAgY29udGV4dC5hY3RpdmVUZXh0dXJlLnNldChnbC5URVhUVVJFMCk7XG4gICAgICAgICAgICAgICAgdGlsZS50ZXh0dXJlLmJpbmQoZ2wuTElORUFSLCBnbC5DTEFNUF9UT19FREdFKTtcblxuICAgICAgICAgICAgICAgIGxldCBwb2xlTWF0cml4ID0gZ2xvYmVQb2xlTWF0cml4Rm9yVGlsZSh6LCB4LCB0cik7XG4gICAgICAgICAgICAgICAgY29uc3Qgbm9ybWFsaXplTWF0cml4ID0gZ2xvYmVOb3JtYWxpemVFQ0VGKGdsb2JlVGlsZUJvdW5kcyhjb29yZC5jYW5vbmljYWwpKTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IGRyYXdQb2xlID0gKHByb2dyYW06IFByb2dyYW08YW55PiwgdmVydGV4QnVmZmVyOiBWZXJ0ZXhCdWZmZXIpID0+IHByb2dyYW0uZHJhdyhcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dCwgZ2wuVFJJQU5HTEVTLCBkZXB0aE1vZGUsIFN0ZW5jaWxNb2RlLmRpc2FibGVkLCBjb2xvck1vZGUsIEN1bGxGYWNlTW9kZS5kaXNhYmxlZCxcbiAgICAgICAgICAgICAgICAgICAgZ2xvYmVSYXN0ZXJVbmlmb3JtVmFsdWVzKHRyLnByb2pNYXRyaXgsIHBvbGVNYXRyaXgsIHBvbGVNYXRyaXgsIG5vcm1hbGl6ZU1hdHJpeCwgMC4wLCBtZXJjYXRvckNlbnRlcixcbiAgICAgICAgICAgICAgICAgICAgdHIuZnJ1c3R1bUNvcm5lcnMuVEwsIHRyLmZydXN0dW1Db3JuZXJzLlRSLCB0ci5mcnVzdHVtQ29ybmVycy5CUiwgdHIuZnJ1c3R1bUNvcm5lcnMuQkwsXG4gICAgICAgICAgICAgICAgICAgIHRyLmdsb2JlQ2VudGVySW5WaWV3U3BhY2UsIHRyLmdsb2JlUmFkaXVzLCB2aWV3cG9ydCwgMCksIFwiZ2xvYmVfcG9sZV9yYXN0ZXJcIiwgdmVydGV4QnVmZmVyLFxuICAgICAgICAgICAgICAgICAgICBpbmRleEJ1ZmZlciwgc2VnbWVudCk7XG5cbiAgICAgICAgICAgICAgICB0ZXJyYWluLnNldHVwRWxldmF0aW9uRHJhdyh0aWxlLCBwcm9ncmFtLCBlbGV2YXRpb25PcHRpb25zKTtcblxuICAgICAgICAgICAgICAgIHBhaW50ZXIucHJlcGFyZURyYXdQcm9ncmFtKGNvbnRleHQsIHByb2dyYW0sIGNvb3JkLnRvVW53cmFwcGVkKCkpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHRvcENhcCkge1xuICAgICAgICAgICAgICAgICAgICBkcmF3UG9sZShwcm9ncmFtLCBub3J0aFBvbGVCdWZmZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoYm90dG9tQ2FwKSB7XG4gICAgICAgICAgICAgICAgICAgIHBvbGVNYXRyaXggPSBtYXQ0LnNjYWxlKG1hdDQuY3JlYXRlKCksIHBvbGVNYXRyaXgsIFsxLCAtMSwgMV0pO1xuICAgICAgICAgICAgICAgICAgICBkcmF3UG9sZShwcm9ncmFtLCBzb3V0aFBvbGVCdWZmZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gZHJhd1RlcnJhaW5SYXN0ZXIocGFpbnRlcjogUGFpbnRlciwgdGVycmFpbjogVGVycmFpbiwgc291cmNlQ2FjaGU6IFNvdXJjZUNhY2hlLCB0aWxlSURzOiBBcnJheTxPdmVyc2NhbGVkVGlsZUlEPiwgbm93OiBudW1iZXIpIHtcbiAgICBpZiAocGFpbnRlci50cmFuc2Zvcm0ucHJvamVjdGlvbi5uYW1lID09PSAnZ2xvYmUnKSB7XG4gICAgICAgIGRyYXdUZXJyYWluRm9yR2xvYmUocGFpbnRlciwgdGVycmFpbiwgc291cmNlQ2FjaGUsIHRpbGVJRHMsIG5vdyk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IHBhaW50ZXIuY29udGV4dDtcbiAgICAgICAgY29uc3QgZ2wgPSBjb250ZXh0LmdsO1xuXG4gICAgICAgIGxldCBwcm9ncmFtLCBwcm9ncmFtTW9kZTtcbiAgICAgICAgY29uc3Qgc2hvd1dpcmVmcmFtZSA9IHBhaW50ZXIub3B0aW9ucy5zaG93VGVycmFpbldpcmVmcmFtZSA/IFNIQURFUl9URVJSQUlOX1dJUkVGUkFNRSA6IFNIQURFUl9ERUZBVUxUO1xuXG4gICAgICAgIGNvbnN0IHNldFNoYWRlck1vZGUgPSAobW9kZTogbnVtYmVyLCBpc1dpcmVmcmFtZTogYm9vbGVhbikgPT4ge1xuICAgICAgICAgICAgaWYgKHByb2dyYW1Nb2RlID09PSBtb2RlKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIGNvbnN0IG1vZGVzID0gW3NoYWRlckRlZmluZXNbbW9kZV1dO1xuICAgICAgICAgICAgaWYgKGlzV2lyZWZyYW1lKSBtb2Rlcy5wdXNoKHNoYWRlckRlZmluZXNbc2hvd1dpcmVmcmFtZV0pO1xuICAgICAgICAgICAgcHJvZ3JhbSA9IHBhaW50ZXIudXNlUHJvZ3JhbSgndGVycmFpblJhc3RlcicsIG51bGwsIG1vZGVzKTtcbiAgICAgICAgICAgIHByb2dyYW1Nb2RlID0gbW9kZTtcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBjb2xvck1vZGUgPSBwYWludGVyLmNvbG9yTW9kZUZvclJlbmRlclBhc3MoKTtcbiAgICAgICAgY29uc3QgZGVwdGhNb2RlID0gbmV3IERlcHRoTW9kZShnbC5MRVFVQUwsIERlcHRoTW9kZS5SZWFkV3JpdGUsIHBhaW50ZXIuZGVwdGhSYW5nZUZvcjNEKTtcbiAgICAgICAgdmVydGV4TW9ycGhpbmcudXBkYXRlKG5vdyk7XG4gICAgICAgIGNvbnN0IHRyID0gcGFpbnRlci50cmFuc2Zvcm07XG4gICAgICAgIGNvbnN0IHNraXJ0ID0gc2tpcnRIZWlnaHQodHIuem9vbSkgKiB0ZXJyYWluLmV4YWdnZXJhdGlvbigpO1xuXG4gICAgICAgIGNvbnN0IGJhdGNoZXMgPSBzaG93V2lyZWZyYW1lID8gW2ZhbHNlLCB0cnVlXSA6IFtmYWxzZV07XG5cbiAgICAgICAgYmF0Y2hlcy5mb3JFYWNoKGlzV2lyZWZyYW1lID0+IHtcbiAgICAgICAgICAgIC8vIFRoaXMgY29kZSBhc3N1bWVzIHRoZSByZW5kZXJpbmcgaXMgYmF0Y2hlZCBpbnRvIG1lc2ggdGVycmFpbiBhbmQgdGhlbiB3aXJlZnJhbWVcbiAgICAgICAgICAgIC8vIHRlcnJhaW4gKGlmIGFwcGxpY2FibGUpIHNvIHRoYXQgdGhpcyBpcyBlbm91Z2ggdG8gZW5zdXJlIHRoZSBjb3JyZWN0IHByb2dyYW0gaXNcbiAgICAgICAgICAgIC8vIHNldCB3aGVuIHdlIHN3aXRjaCBmcm9tIG9uZSB0byB0aGUgb3RoZXIuXG4gICAgICAgICAgICBwcm9ncmFtTW9kZSA9IC0xO1xuXG4gICAgICAgICAgICBjb25zdCBwcmltaXRpdmUgPSBpc1dpcmVmcmFtZSA/IGdsLkxJTkVTIDogZ2wuVFJJQU5HTEVTO1xuICAgICAgICAgICAgY29uc3QgW2J1ZmZlciwgc2VnbWVudHNdID0gaXNXaXJlZnJhbWUgPyB0ZXJyYWluLmdldFdpcmVmYW1lQnVmZmVyKCkgOiBbdGVycmFpbi5ncmlkSW5kZXhCdWZmZXIsIHRlcnJhaW4uZ3JpZFNlZ21lbnRzXTtcblxuICAgICAgICAgICAgZm9yIChjb25zdCBjb29yZCBvZiB0aWxlSURzKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdGlsZSA9IHNvdXJjZUNhY2hlLmdldFRpbGUoY29vcmQpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0ZW5jaWxNb2RlID0gU3RlbmNpbE1vZGUuZGlzYWJsZWQ7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBwcmV2RGVtVGlsZSA9IHRlcnJhaW4ucHJldlRlcnJhaW5UaWxlRm9yVGlsZVtjb29yZC5rZXldO1xuICAgICAgICAgICAgICAgIGNvbnN0IG5leHREZW1UaWxlID0gdGVycmFpbi50ZXJyYWluVGlsZUZvclRpbGVbY29vcmQua2V5XTtcblxuICAgICAgICAgICAgICAgIGlmIChkZW1UaWxlQ2hhbmdlZChwcmV2RGVtVGlsZSwgbmV4dERlbVRpbGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZlcnRleE1vcnBoaW5nLm5ld01vcnBoaW5nKGNvb3JkLmtleSwgcHJldkRlbVRpbGUsIG5leHREZW1UaWxlLCBub3csIGRlZmF1bHREdXJhdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gQmluZCB0aGUgbWFpbiBkcmFwZWQgdGV4dHVyZVxuICAgICAgICAgICAgICAgIGNvbnRleHQuYWN0aXZlVGV4dHVyZS5zZXQoZ2wuVEVYVFVSRTApO1xuICAgICAgICAgICAgICAgIHRpbGUudGV4dHVyZS5iaW5kKGdsLkxJTkVBUiwgZ2wuQ0xBTVBfVE9fRURHRSwgZ2wuTElORUFSX01JUE1BUF9ORUFSRVNUKTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IG1vcnBoID0gdmVydGV4TW9ycGhpbmcuZ2V0TW9ycGhWYWx1ZXNGb3JQcm94eShjb29yZC5rZXkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHNoYWRlck1vZGUgPSBtb3JwaCA/IFNIQURFUl9NT1JQSElORyA6IFNIQURFUl9ERUZBVUxUO1xuICAgICAgICAgICAgICAgIGxldCBlbGV2YXRpb25PcHRpb25zO1xuXG4gICAgICAgICAgICAgICAgaWYgKG1vcnBoKSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZXZhdGlvbk9wdGlvbnMgPSB7bW9ycGhpbmc6IHtzcmNEZW1UaWxlOiBtb3JwaC5mcm9tLCBkc3REZW1UaWxlOiBtb3JwaC50bywgcGhhc2U6IGVhc2VDdWJpY0luT3V0KG1vcnBoLnBoYXNlKX19O1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHVuaWZvcm1WYWx1ZXMgPSB0ZXJyYWluUmFzdGVyVW5pZm9ybVZhbHVlcyhjb29yZC5wcm9qTWF0cml4LCBpc0VkZ2VUaWxlKGNvb3JkLmNhbm9uaWNhbCwgdHIucmVuZGVyV29ybGRDb3BpZXMpID8gc2tpcnQgLyAxMCA6IHNraXJ0KTtcbiAgICAgICAgICAgICAgICBzZXRTaGFkZXJNb2RlKHNoYWRlck1vZGUsIGlzV2lyZWZyYW1lKTtcblxuICAgICAgICAgICAgICAgIHRlcnJhaW4uc2V0dXBFbGV2YXRpb25EcmF3KHRpbGUsIHByb2dyYW0sIGVsZXZhdGlvbk9wdGlvbnMpO1xuXG4gICAgICAgICAgICAgICAgcGFpbnRlci5wcmVwYXJlRHJhd1Byb2dyYW0oY29udGV4dCwgcHJvZ3JhbSwgY29vcmQudG9VbndyYXBwZWQoKSk7XG5cbiAgICAgICAgICAgICAgICBwcm9ncmFtLmRyYXcoY29udGV4dCwgcHJpbWl0aXZlLCBkZXB0aE1vZGUsIHN0ZW5jaWxNb2RlLCBjb2xvck1vZGUsIEN1bGxGYWNlTW9kZS5iYWNrQ0NXLFxuICAgICAgICAgICAgICAgICAgICB1bmlmb3JtVmFsdWVzLCBcInRlcnJhaW5fcmFzdGVyXCIsIHRlcnJhaW4uZ3JpZEJ1ZmZlciwgYnVmZmVyLCBzZWdtZW50cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZHJhd1RlcnJhaW5EZXB0aChwYWludGVyOiBQYWludGVyLCB0ZXJyYWluOiBUZXJyYWluLCBzb3VyY2VDYWNoZTogU291cmNlQ2FjaGUsIHRpbGVJRHM6IEFycmF5PE92ZXJzY2FsZWRUaWxlSUQ+KSB7XG4gICAgaWYgKHBhaW50ZXIudHJhbnNmb3JtLnByb2plY3Rpb24ubmFtZSA9PT0gJ2dsb2JlJykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgYXNzZXJ0KHBhaW50ZXIucmVuZGVyUGFzcyA9PT0gJ29mZnNjcmVlbicpO1xuXG4gICAgY29uc3QgY29udGV4dCA9IHBhaW50ZXIuY29udGV4dDtcbiAgICBjb25zdCBnbCA9IGNvbnRleHQuZ2w7XG5cbiAgICBjb250ZXh0LmNsZWFyKHtkZXB0aDogMX0pO1xuICAgIGNvbnN0IHByb2dyYW0gPSBwYWludGVyLnVzZVByb2dyYW0oJ3RlcnJhaW5EZXB0aCcpO1xuICAgIGNvbnN0IGRlcHRoTW9kZSA9IG5ldyBEZXB0aE1vZGUoZ2wuTEVTUywgRGVwdGhNb2RlLlJlYWRXcml0ZSwgcGFpbnRlci5kZXB0aFJhbmdlRm9yM0QpO1xuXG4gICAgZm9yIChjb25zdCBjb29yZCBvZiB0aWxlSURzKSB7XG4gICAgICAgIGNvbnN0IHRpbGUgPSBzb3VyY2VDYWNoZS5nZXRUaWxlKGNvb3JkKTtcbiAgICAgICAgY29uc3QgdW5pZm9ybVZhbHVlcyA9IHRlcnJhaW5SYXN0ZXJVbmlmb3JtVmFsdWVzKGNvb3JkLnByb2pNYXRyaXgsIDApO1xuICAgICAgICB0ZXJyYWluLnNldHVwRWxldmF0aW9uRHJhdyh0aWxlLCBwcm9ncmFtKTtcblxuICAgICAgICBwcm9ncmFtLmRyYXcoY29udGV4dCwgZ2wuVFJJQU5HTEVTLCBkZXB0aE1vZGUsIFN0ZW5jaWxNb2RlLmRpc2FibGVkLCBDb2xvck1vZGUudW5ibGVuZGVkLCBDdWxsRmFjZU1vZGUuYmFja0NDVyxcbiAgICAgICAgICAgIHVuaWZvcm1WYWx1ZXMsIFwidGVycmFpbl9kZXB0aFwiLCB0ZXJyYWluLmdyaWRCdWZmZXIsIHRlcnJhaW4uZ3JpZEluZGV4QnVmZmVyLCB0ZXJyYWluLmdyaWROb1NraXJ0U2VnbWVudHMpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gc2tpcnRIZWlnaHQoem9vbTogbnVtYmVyKSB7XG4gICAgLy8gU2tpcnQgaGVpZ2h0IGNhbGN1bGF0aW9uIGlzIGhldXJpc3RpYzogcHJvdmlkZWQgdmFsdWUgaGlkZXNcbiAgICAvLyBzZWFtcyBiZXR3ZWVuIHRpbGVzIGFuZCBpdCBpcyBub3QgdG9vIGxhcmdlOiA5IGF0IHpvb20gMjIsIH4yMDAwMG0gYXQgem9vbSAwLlxuICAgIHJldHVybiA2ICogTWF0aC5wb3coMS41LCAyMiAtIHpvb20pO1xufVxuXG5mdW5jdGlvbiBpc0VkZ2VUaWxlKGNpZDogQ2Fub25pY2FsVGlsZUlELCByZW5kZXJXb3JsZENvcGllczogYm9vbGVhbik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IG51bVRpbGVzID0gMSA8PCBjaWQuejtcbiAgICByZXR1cm4gKCFyZW5kZXJXb3JsZENvcGllcyAmJiAoY2lkLnggPT09IDAgfHwgY2lkLnggPT09IG51bVRpbGVzIC0gMSkpIHx8IGNpZC55ID09PSAwIHx8IGNpZC55ID09PSBudW1UaWxlcyAtIDE7XG59XG5cbmV4cG9ydCB7XG4gICAgVmVydGV4TW9ycGhpbmdcbn07XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge1VuaWZvcm1NYXRyaXg0Zn0gZnJvbSAnLi4vdW5pZm9ybV9iaW5kaW5nLmpzJztcblxuaW1wb3J0IHR5cGUgQ29udGV4dCBmcm9tICcuLi8uLi9nbC9jb250ZXh0LmpzJztcbmltcG9ydCB0eXBlIHtVbmlmb3JtVmFsdWVzfSBmcm9tICcuLi91bmlmb3JtX2JpbmRpbmcuanMnO1xuXG5leHBvcnQgdHlwZSBDbGlwcGluZ01hc2tVbmlmb3Jtc1R5cGUgPSB7fFxuICAgICd1X21hdHJpeCc6IFVuaWZvcm1NYXRyaXg0ZlxufH07XG5cbmNvbnN0IGNsaXBwaW5nTWFza1VuaWZvcm1zID0gKGNvbnRleHQ6IENvbnRleHQpOiBDbGlwcGluZ01hc2tVbmlmb3Jtc1R5cGUgPT4gKHtcbiAgICAndV9tYXRyaXgnOiBuZXcgVW5pZm9ybU1hdHJpeDRmKGNvbnRleHQpXG59KTtcblxuY29uc3QgY2xpcHBpbmdNYXNrVW5pZm9ybVZhbHVlcyA9IChtYXRyaXg6IEZsb2F0MzJBcnJheSk6IFVuaWZvcm1WYWx1ZXM8Q2xpcHBpbmdNYXNrVW5pZm9ybXNUeXBlPiA9PiAoe1xuICAgICd1X21hdHJpeCc6IG1hdHJpeFxufSk7XG5cbmV4cG9ydCB7Y2xpcHBpbmdNYXNrVW5pZm9ybXMsIGNsaXBwaW5nTWFza1VuaWZvcm1WYWx1ZXN9O1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHR5cGUgU291cmNlQ2FjaGUgZnJvbSAnLi4vc291cmNlL3NvdXJjZV9jYWNoZS5qcyc7XG5pbXBvcnQge2NsYW1wfSBmcm9tICcuLi91dGlsL3V0aWwuanMnO1xuaW1wb3J0IGJyb3dzZXIgZnJvbSAnLi4vdXRpbC9icm93c2VyLmpzJztcbmltcG9ydCBUaWxlIGZyb20gJy4uL3NvdXJjZS90aWxlLmpzJztcbmltcG9ydCB0eXBlIFRyYW5zZm9ybSBmcm9tICcuLi9nZW8vdHJhbnNmb3JtLmpzJztcblxuZXhwb3J0IHR5cGUgUmFzdGVyRmFkZSA9IHt8XG4gICAgb3BhY2l0eTogbnVtYmVyLFxuICAgIG1peDogbnVtYmVyLFxufH07XG5cbmZ1bmN0aW9uIHJhc3RlckZhZGUodGlsZTogVGlsZSwgcGFyZW50VGlsZTogP1RpbGUsIHNvdXJjZUNhY2hlOiBTb3VyY2VDYWNoZSwgdHJhbnNmb3JtOiBUcmFuc2Zvcm0sIGZhZGVEdXJhdGlvbjogbnVtYmVyKTogUmFzdGVyRmFkZSB7XG4gICAgaWYgKGZhZGVEdXJhdGlvbiA+IDApIHtcbiAgICAgICAgY29uc3Qgbm93ID0gYnJvd3Nlci5ub3coKTtcbiAgICAgICAgY29uc3Qgc2luY2VUaWxlID0gKG5vdyAtIHRpbGUudGltZUFkZGVkKSAvIGZhZGVEdXJhdGlvbjtcbiAgICAgICAgY29uc3Qgc2luY2VQYXJlbnQgPSBwYXJlbnRUaWxlID8gKG5vdyAtIHBhcmVudFRpbGUudGltZUFkZGVkKSAvIGZhZGVEdXJhdGlvbiA6IC0xO1xuXG4gICAgICAgIGNvbnN0IHNvdXJjZSA9IHNvdXJjZUNhY2hlLmdldFNvdXJjZSgpO1xuICAgICAgICBjb25zdCBpZGVhbFogPSB0cmFuc2Zvcm0uY292ZXJpbmdab29tTGV2ZWwoe1xuICAgICAgICAgICAgdGlsZVNpemU6IHNvdXJjZS50aWxlU2l6ZSxcbiAgICAgICAgICAgIHJvdW5kWm9vbTogc291cmNlLnJvdW5kWm9vbVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBpZiBubyBwYXJlbnQgb3IgcGFyZW50IGlzIG9sZGVyLCBmYWRlIGluOyBpZiBwYXJlbnQgaXMgeW91bmdlciwgZmFkZSBvdXRcbiAgICAgICAgY29uc3QgZmFkZUluID0gIXBhcmVudFRpbGUgfHwgTWF0aC5hYnMocGFyZW50VGlsZS50aWxlSUQub3ZlcnNjYWxlZFogLSBpZGVhbFopID4gTWF0aC5hYnModGlsZS50aWxlSUQub3ZlcnNjYWxlZFogLSBpZGVhbFopO1xuXG4gICAgICAgIGNvbnN0IGNoaWxkT3BhY2l0eSA9IChmYWRlSW4gJiYgdGlsZS5yZWZyZXNoZWRVcG9uRXhwaXJhdGlvbikgPyAxIDogY2xhbXAoZmFkZUluID8gc2luY2VUaWxlIDogMSAtIHNpbmNlUGFyZW50LCAwLCAxKTtcblxuICAgICAgICAvLyB3ZSBkb24ndCBjcm9zc2ZhZGUgdGlsZXMgdGhhdCB3ZXJlIGp1c3QgcmVmcmVzaGVkIHVwb24gZXhwaXJpbmc6XG4gICAgICAgIC8vIG9uY2UgdGhleSdyZSBvbGQgZW5vdWdoIHRvIHBhc3MgdGhlIGNyb3NzZmFkaW5nIHRocmVzaG9sZFxuICAgICAgICAvLyAoZmFkZUR1cmF0aW9uKSwgdW5zZXQgdGhlIGByZWZyZXNoZWRVcG9uRXhwaXJhdGlvbmAgZmxhZyBzbyB3ZSBkb24ndFxuICAgICAgICAvLyBpbmNvcnJlY3RseSBmYWlsIHRvIGNyb3NzZmFkZSB0aGVtIHdoZW4gem9vbWluZ1xuICAgICAgICBpZiAodGlsZS5yZWZyZXNoZWRVcG9uRXhwaXJhdGlvbiAmJiBzaW5jZVRpbGUgPj0gMSkgdGlsZS5yZWZyZXNoZWRVcG9uRXhwaXJhdGlvbiA9IGZhbHNlO1xuXG4gICAgICAgIGlmIChwYXJlbnRUaWxlKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIG9wYWNpdHk6IDEsXG4gICAgICAgICAgICAgICAgbWl4OiAxIC0gY2hpbGRPcGFjaXR5XG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBvcGFjaXR5OiBjaGlsZE9wYWNpdHksXG4gICAgICAgICAgICAgICAgbWl4OiAwXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG9wYWNpdHk6IDEsXG4gICAgICAgICAgICBtaXg6IDBcbiAgICAgICAgfTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IHJhc3RlckZhZGU7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5pbXBvcnQgU291cmNlQ2FjaGUgZnJvbSAnLi4vc291cmNlL3NvdXJjZV9jYWNoZS5qcyc7XG5pbXBvcnQge092ZXJzY2FsZWRUaWxlSUR9IGZyb20gJy4uL3NvdXJjZS90aWxlX2lkLmpzJztcbmltcG9ydCBUaWxlIGZyb20gJy4uL3NvdXJjZS90aWxlLmpzJztcbmltcG9ydCBwb3NBdHRyaWJ1dGVzIGZyb20gJy4uL2RhdGEvcG9zX2F0dHJpYnV0ZXMuanMnO1xuaW1wb3J0IHtUcmlhbmdsZUluZGV4QXJyYXksIExpbmVJbmRleEFycmF5LCBQb3NBcnJheX0gZnJvbSAnLi4vZGF0YS9hcnJheV90eXBlcy5qcyc7XG5pbXBvcnQgU2VnbWVudFZlY3RvciBmcm9tICcuLi9kYXRhL3NlZ21lbnQuanMnO1xuaW1wb3J0IFRleHR1cmUgZnJvbSAnLi4vcmVuZGVyL3RleHR1cmUuanMnO1xuaW1wb3J0IFByb2dyYW0gZnJvbSAnLi4vcmVuZGVyL3Byb2dyYW0uanMnO1xuaW1wb3J0IHtVbmlmb3JtMWksIFVuaWZvcm0xZiwgVW5pZm9ybTJmLCBVbmlmb3JtM2YsIFVuaWZvcm00ZiwgVW5pZm9ybU1hdHJpeDRmfSBmcm9tICcuLi9yZW5kZXIvdW5pZm9ybV9iaW5kaW5nLmpzJztcbmltcG9ydCB7cHJlcGFyZURFTVRleHR1cmV9IGZyb20gJy4uL3JlbmRlci9kcmF3X2hpbGxzaGFkZS5qcyc7XG5pbXBvcnQgRVhURU5UIGZyb20gJy4uL2RhdGEvZXh0ZW50LmpzJztcbmltcG9ydCB7Y2xhbXAsIHdhcm5PbmNlfSBmcm9tICcuLi91dGlsL3V0aWwuanMnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHt2ZWMzLCBtYXQ0LCB2ZWM0fSBmcm9tICdnbC1tYXRyaXgnO1xuaW1wb3J0IGdldFdvcmtlclBvb2wgZnJvbSAnLi4vdXRpbC9nbG9iYWxfd29ya2VyX3Bvb2wuanMnO1xuaW1wb3J0IERpc3BhdGNoZXIgZnJvbSAnLi4vdXRpbC9kaXNwYXRjaGVyLmpzJztcbmltcG9ydCBHZW9KU09OU291cmNlIGZyb20gJy4uL3NvdXJjZS9nZW9qc29uX3NvdXJjZS5qcyc7XG5pbXBvcnQgSW1hZ2VTb3VyY2UgZnJvbSAnLi4vc291cmNlL2ltYWdlX3NvdXJjZS5qcyc7XG5pbXBvcnQgUmFzdGVyREVNVGlsZVNvdXJjZSBmcm9tICcuLi9zb3VyY2UvcmFzdGVyX2RlbV90aWxlX3NvdXJjZS5qcyc7XG5pbXBvcnQgUmFzdGVyVGlsZVNvdXJjZSBmcm9tICcuLi9zb3VyY2UvcmFzdGVyX3RpbGVfc291cmNlLmpzJztcbmltcG9ydCBWZWN0b3JUaWxlU291cmNlIGZyb20gJy4uL3NvdXJjZS92ZWN0b3JfdGlsZV9zb3VyY2UuanMnO1xuaW1wb3J0IENvbG9yIGZyb20gJy4uL3N0eWxlLXNwZWMvdXRpbC9jb2xvci5qcyc7XG5pbXBvcnQgdHlwZSB7Q2FsbGJhY2t9IGZyb20gJy4uL3R5cGVzL2NhbGxiYWNrLmpzJztcbmltcG9ydCBTdGVuY2lsTW9kZSBmcm9tICcuLi9nbC9zdGVuY2lsX21vZGUuanMnO1xuaW1wb3J0IHtEZXB0aFN0ZW5jaWxBdHRhY2htZW50fSBmcm9tICcuLi9nbC92YWx1ZS5qcyc7XG5pbXBvcnQge2RyYXdUZXJyYWluUmFzdGVyLCBkcmF3VGVycmFpbkRlcHRofSBmcm9tICcuL2RyYXdfdGVycmFpbl9yYXN0ZXIuanMnO1xuaW1wb3J0IHR5cGUgUmFzdGVyU3R5bGVMYXllciBmcm9tICcuLi9zdHlsZS9zdHlsZV9sYXllci9yYXN0ZXJfc3R5bGVfbGF5ZXIuanMnO1xuaW1wb3J0IHR5cGUgQ3VzdG9tU3R5bGVMYXllciBmcm9tICcuLi9zdHlsZS9zdHlsZV9sYXllci9jdXN0b21fc3R5bGVfbGF5ZXIuanMnO1xuaW1wb3J0IHR5cGUgTGluZVN0eWxlTGF5ZXIgZnJvbSAnLi4vc3R5bGUvc3R5bGVfbGF5ZXIvbGluZV9zdHlsZV9sYXllci5qcyc7XG5pbXBvcnQge0VsZXZhdGlvbn0gZnJvbSAnLi9lbGV2YXRpb24uanMnO1xuaW1wb3J0IEZyYW1lYnVmZmVyIGZyb20gJy4uL2dsL2ZyYW1lYnVmZmVyLmpzJztcbmltcG9ydCBDb2xvck1vZGUgZnJvbSAnLi4vZ2wvY29sb3JfbW9kZS5qcyc7XG5pbXBvcnQgRGVwdGhNb2RlIGZyb20gJy4uL2dsL2RlcHRoX21vZGUuanMnO1xuaW1wb3J0IEN1bGxGYWNlTW9kZSBmcm9tICcuLi9nbC9jdWxsX2ZhY2VfbW9kZS5qcyc7XG5pbXBvcnQge2NsaXBwaW5nTWFza1VuaWZvcm1WYWx1ZXN9IGZyb20gJy4uL3JlbmRlci9wcm9ncmFtL2NsaXBwaW5nX21hc2tfcHJvZ3JhbS5qcyc7XG5pbXBvcnQgTWVyY2F0b3JDb29yZGluYXRlLCB7bWVyY2F0b3JaZnJvbUFsdGl0dWRlfSBmcm9tICcuLi9nZW8vbWVyY2F0b3JfY29vcmRpbmF0ZS5qcyc7XG5pbXBvcnQgYnJvd3NlciBmcm9tICcuLi91dGlsL2Jyb3dzZXIuanMnO1xuaW1wb3J0IERFTURhdGEgZnJvbSAnLi4vZGF0YS9kZW1fZGF0YS5qcyc7XG5pbXBvcnQge0RyYXBlUmVuZGVyTW9kZX0gZnJvbSAnLi4vc3R5bGUvdGVycmFpbi5qcyc7XG5pbXBvcnQgcmFzdGVyRmFkZSBmcm9tICcuLi9yZW5kZXIvcmFzdGVyX2ZhZGUuanMnO1xuaW1wb3J0IHtjcmVhdGUgYXMgY3JlYXRlU291cmNlfSBmcm9tICcuLi9zb3VyY2Uvc291cmNlLmpzJztcbmltcG9ydCB7UkdCQUltYWdlfSBmcm9tICcuLi91dGlsL2ltYWdlLmpzJztcbmltcG9ydCB7Z2xvYmVNZXRlcnNUb0VjZWZ9IGZyb20gJy4uL2dlby9wcm9qZWN0aW9uL2dsb2JlX3V0aWwuanMnO1xuaW1wb3J0IHtab29tRGVwZW5kZW50RXhwcmVzc2lvbn0gZnJvbSAnLi4vc3R5bGUtc3BlYy9leHByZXNzaW9uL2luZGV4LmpzJztcblxuaW1wb3J0IHR5cGUgTWFwIGZyb20gJy4uL3VpL21hcC5qcyc7XG5pbXBvcnQgdHlwZSBQYWludGVyIGZyb20gJy4uL3JlbmRlci9wYWludGVyLmpzJztcbmltcG9ydCB0eXBlIFN0eWxlIGZyb20gJy4uL3N0eWxlL3N0eWxlLmpzJztcbmltcG9ydCB0eXBlIFN0eWxlTGF5ZXIgZnJvbSAnLi4vc3R5bGUvc3R5bGVfbGF5ZXIuanMnO1xuaW1wb3J0IHR5cGUgVmVydGV4QnVmZmVyIGZyb20gJy4uL2dsL3ZlcnRleF9idWZmZXIuanMnO1xuaW1wb3J0IHR5cGUgSW5kZXhCdWZmZXIgZnJvbSAnLi4vZ2wvaW5kZXhfYnVmZmVyLmpzJztcbmltcG9ydCB0eXBlIENvbnRleHQgZnJvbSAnLi4vZ2wvY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSB7VW5pZm9ybVZhbHVlc30gZnJvbSAnLi4vcmVuZGVyL3VuaWZvcm1fYmluZGluZy5qcyc7XG5pbXBvcnQgdHlwZSBUcmFuc2Zvcm0gZnJvbSAnLi4vZ2VvL3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQgdHlwZSB7REVNRW5jb2Rpbmd9IGZyb20gJy4uL2RhdGEvZGVtX2RhdGEuanMnO1xuaW1wb3J0IHR5cGUge1ZlYzMsIFZlYzR9IGZyb20gJ2dsLW1hdHJpeCc7XG5pbXBvcnQgdHlwZSB7Q2Fub25pY2FsVGlsZUlEfSBmcm9tICcuLi9zb3VyY2UvdGlsZV9pZC5qcyc7XG5cbmNvbnN0IEdSSURfRElNID0gMTI4O1xuXG5jb25zdCBGQk9fUE9PTF9TSVpFID0gNTtcbmNvbnN0IFJFTkRFUl9DQUNIRV9NQVhfU0laRSA9IDUwO1xuXG50eXBlIFJlbmRlckJhdGNoID0ge1xuICAgIHN0YXJ0OiBudW1iZXI7XG4gICAgZW5kOiBudW1iZXI7XG59XG5cbmNsYXNzIE1vY2tTb3VyY2VDYWNoZSBleHRlbmRzIFNvdXJjZUNhY2hlIHtcbiAgICBjb25zdHJ1Y3RvcihtYXA6IE1hcCkge1xuICAgICAgICBjb25zdCBzb3VyY2VTcGVjID0ge3R5cGU6ICdyYXN0ZXItZGVtJywgbWF4em9vbTogbWFwLnRyYW5zZm9ybS5tYXhab29tfTtcbiAgICAgICAgY29uc3Qgc291cmNlRGlzcGF0Y2hlciA9IG5ldyBEaXNwYXRjaGVyKGdldFdvcmtlclBvb2woKSwgbnVsbCk7XG4gICAgICAgIGNvbnN0IHNvdXJjZSA9IGNyZWF0ZVNvdXJjZSgnbW9jay1kZW0nLCBzb3VyY2VTcGVjLCBzb3VyY2VEaXNwYXRjaGVyLCBtYXAuc3R5bGUpO1xuXG4gICAgICAgIHN1cGVyKCdtb2NrLWRlbScsIHNvdXJjZSwgZmFsc2UpO1xuXG4gICAgICAgIHNvdXJjZS5zZXRFdmVudGVkUGFyZW50KHRoaXMpO1xuXG4gICAgICAgIHRoaXMuX3NvdXJjZUxvYWRlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgX2xvYWRUaWxlKHRpbGU6IFRpbGUsIGNhbGxiYWNrOiBDYWxsYmFjazx2b2lkPikge1xuICAgICAgICB0aWxlLnN0YXRlID0gJ2xvYWRlZCc7XG4gICAgICAgIGNhbGxiYWNrKG51bGwpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBQcm94eSBzb3VyY2UgY2FjaGUgZ2V0cyBpZGVhbCBzY3JlZW4gdGlsZSBjb3ZlciBjb29yZGluYXRlcy4gQWxsIHRoZSBvdGhlclxuICogc291cmNlIGNhY2hlcydzIGNvb3JkaW5hdGVzIGdldCBtYXBwZWQgdG8gc3VicmVjdHMgb2YgcHJveHkgY29vcmRpbmF0ZXMgKG9yXG4gKiB2aWNlIHZlcnNhLCBzdWJyZWN0cyBvZiBsYXJnZXIgdGlsZXMgZnJvbSBhbGwgc291cmNlIGNhY2hlcyBnZXQgbWFwcGVkIHRvXG4gKiBmdWxsIHByb3h5IHRpbGUpLiBUaGlzIGhhcHBlbnMgb24gZXZlcnkgZHJhdyBjYWxsIGluIFRlcnJhaW4udXBkYXRlVGlsZUJpbmRpbmcuXG4gKiBBcHByb2FjaCBpcyB1c2VkIGhlcmUgZm9yIHRlcnJhaW4gOiBhbGwgdGhlIHZpc2libGUgc291cmNlIHRpbGVzIG9mIGFsbCB0aGVcbiAqIHNvdXJjZSBjYWNoZXMgZ2V0IHJlbmRlcmVkIHRvIHByb3h5IHNvdXJjZSBjYWNoZSB0ZXh0dXJlcyBhbmQgdGhlbiBkcmFwZWQgb3ZlclxuICogdGVycmFpbi4gSXQgaXMgaW4gZnV0dXJlIHJldXNhYmxlIGZvciBoYW5kbGluZyBvdmVyc2NhbGxpbmcgYXMgYnVja2V0cyBjb3VsZCBiZVxuICogY29uc3RydWN0ZWQgb25seSBmb3IgcHJveHkgdGlsZSBjb250ZW50LCBub3QgZm9yIGZ1bGwgb3ZlcnNjYWxsZWQgdmVjdG9yIHRpbGUuXG4gKi9cbmNsYXNzIFByb3h5U291cmNlQ2FjaGUgZXh0ZW5kcyBTb3VyY2VDYWNoZSB7XG4gICAgcmVuZGVyQ2FjaGU6IEFycmF5PEZCTz47XG4gICAgcmVuZGVyQ2FjaGVQb29sOiBBcnJheTxudW1iZXI+O1xuICAgIHByb3h5Q2FjaGVkRkJPOiB7W3N0cmluZyB8IG51bWJlcl06IHtbc3RyaW5nIHwgbnVtYmVyXTogbnVtYmVyfX07XG5cbiAgICBjb25zdHJ1Y3RvcihtYXA6IE1hcCkge1xuXG4gICAgICAgIGNvbnN0IHNvdXJjZSA9IGNyZWF0ZVNvdXJjZSgncHJveHknLCB7XG4gICAgICAgICAgICB0eXBlOiAnZ2VvanNvbicsXG4gICAgICAgICAgICBtYXh6b29tOiBtYXAudHJhbnNmb3JtLm1heFpvb21cbiAgICAgICAgfSwgbmV3IERpc3BhdGNoZXIoZ2V0V29ya2VyUG9vbCgpLCBudWxsKSwgbWFwLnN0eWxlKTtcblxuICAgICAgICBzdXBlcigncHJveHknLCBzb3VyY2UsIGZhbHNlKTtcblxuICAgICAgICBzb3VyY2Uuc2V0RXZlbnRlZFBhcmVudCh0aGlzKTtcblxuICAgICAgICAvLyBUaGlzIHNvdXJjZSBpcyBub3QgdG8gYmUgYWRkZWQgYXMgYSBtYXAgc291cmNlOiB3ZSB1c2UgaXQncyB0aWxlIG1hbmFnZW1lbnQuXG4gICAgICAgIC8vIEZvciB0aGF0LCBpbml0aWFsaXplIGludGVybmFsIHN0cnVjdHVyZXMgdXNlZCBmb3IgdGlsZSBjb3ZlciB1cGRhdGUuXG4gICAgICAgIHRoaXMubWFwID0gKCh0aGlzLmdldFNvdXJjZSgpOiBhbnkpOiBHZW9KU09OU291cmNlKS5tYXAgPSBtYXA7XG4gICAgICAgIHRoaXMudXNlZCA9IHRoaXMuX3NvdXJjZUxvYWRlZCA9IHRydWU7XG4gICAgICAgIHRoaXMucmVuZGVyQ2FjaGUgPSBbXTtcbiAgICAgICAgdGhpcy5yZW5kZXJDYWNoZVBvb2wgPSBbXTtcbiAgICAgICAgdGhpcy5wcm94eUNhY2hlZEZCTyA9IHt9O1xuICAgIH1cblxuICAgIC8vIE92ZXJyaWRlIGZvciB0cmFuc2llbnQgbmF0dXJlIG9mIGNvdmVyIGhlcmU6IGRvbid0IGNhY2hlIGFuZCByZXRhaW4uXG4gICAgdXBkYXRlKHRyYW5zZm9ybTogVHJhbnNmb3JtLCB0aWxlU2l6ZT86IG51bWJlciwgdXBkYXRlRm9yVGVycmFpbj86IGJvb2xlYW4pIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgICAgICBpZiAodHJhbnNmb3JtLmZyZWV6ZVRpbGVDb3ZlcmFnZSkgeyByZXR1cm47IH1cbiAgICAgICAgdGhpcy50cmFuc2Zvcm0gPSB0cmFuc2Zvcm07XG4gICAgICAgIGNvbnN0IGlkZWFsVGlsZUlEcyA9IHRyYW5zZm9ybS5jb3ZlcmluZ1RpbGVzKHtcbiAgICAgICAgICAgIHRpbGVTaXplOiB0aGlzLl9zb3VyY2UudGlsZVNpemUsXG4gICAgICAgICAgICBtaW56b29tOiB0aGlzLl9zb3VyY2UubWluem9vbSxcbiAgICAgICAgICAgIG1heHpvb206IHRoaXMuX3NvdXJjZS5tYXh6b29tLFxuICAgICAgICAgICAgcm91bmRab29tOiB0aGlzLl9zb3VyY2Uucm91bmRab29tLFxuICAgICAgICAgICAgcmVwYXJzZU92ZXJzY2FsZWQ6IHRoaXMuX3NvdXJjZS5yZXBhcnNlT3ZlcnNjYWxlZFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBpbmNvbWluZzoge1tzdHJpbmddOiBzdHJpbmd9ID0gaWRlYWxUaWxlSURzLnJlZHVjZSgoYWNjLCB0aWxlSUQpID0+IHtcbiAgICAgICAgICAgIGFjY1t0aWxlSUQua2V5XSA9ICcnO1xuICAgICAgICAgICAgaWYgKCF0aGlzLl90aWxlc1t0aWxlSUQua2V5XSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRpbGUgPSBuZXcgVGlsZSh0aWxlSUQsIHRoaXMuX3NvdXJjZS50aWxlU2l6ZSAqIHRpbGVJRC5vdmVyc2NhbGVGYWN0b3IoKSwgdHJhbnNmb3JtLnRpbGVab29tKTtcbiAgICAgICAgICAgICAgICB0aWxlLnN0YXRlID0gJ2xvYWRlZCc7XG4gICAgICAgICAgICAgICAgdGhpcy5fdGlsZXNbdGlsZUlELmtleV0gPSB0aWxlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgICAgfSwge30pO1xuXG4gICAgICAgIGZvciAoY29uc3QgaWQgaW4gdGhpcy5fdGlsZXMpIHtcbiAgICAgICAgICAgIGlmICghKGlkIGluIGluY29taW5nKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZnJlZUZCTyhpZCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fdGlsZXNbaWRdLnVubG9hZFZlY3RvckRhdGEoKTtcbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5fdGlsZXNbaWRdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnJlZUZCTyhpZDogc3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IGZib3MgPSB0aGlzLnByb3h5Q2FjaGVkRkJPW2lkXTtcbiAgICAgICAgaWYgKGZib3MgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY29uc3QgZmJvSWRzID0gKChPYmplY3QudmFsdWVzKGZib3MpOiBhbnkpOiBBcnJheTxudW1iZXI+KTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyQ2FjaGVQb29sLnB1c2goLi4uZmJvSWRzKTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnByb3h5Q2FjaGVkRkJPW2lkXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRlYWxsb2NSZW5kZXJDYWNoZSgpIHtcbiAgICAgICAgdGhpcy5yZW5kZXJDYWNoZS5mb3JFYWNoKGZibyA9PiBmYm8uZmIuZGVzdHJveSgpKTtcbiAgICAgICAgdGhpcy5yZW5kZXJDYWNoZSA9IFtdO1xuICAgICAgICB0aGlzLnJlbmRlckNhY2hlUG9vbCA9IFtdO1xuICAgICAgICB0aGlzLnByb3h5Q2FjaGVkRkJPID0ge307XG4gICAgfVxufVxuXG4vKipcbiAqIENhbm9uaWNhbCwgd3JhcCBhbmQgb3ZlcnNjYWxlZFogY29udGFpbiBpbmZvcm1hdGlvbiBvZiBvcmlnaW5hbCBzb3VyY2UgY2FjaGUgdGlsZS5cbiAqIFRoaXMgdGlsZSBnZXRzIG9ydGhvLXJlbmRlcmVkIHRvIHByb3h5IHRpbGUgKGRlZmluZWQgYnkgcHJveHlUaWxlS2V5KS5cbiAqIGBwb3NNYXRyaXhgIGhvbGRzIG9ydGhvZ3JhcGhpYywgc2NhbGluZyBhbmQgdHJhbnNsYXRpb24gaW5mb3JtYXRpb24gdGhhdCBpcyB1c2VkXG4gKiBmb3IgcmVuZGVyaW5nIG9yaWdpbmFsIHRpbGUgY29udGVudCB0byBhIHByb3h5IHRpbGUuIFByb3h5IHRpbGUgY292ZXJzIHdob2xlXG4gKiBvciBzdWItcmVjdGFuZ2xlIG9mIHRoZSBvcmlnaW5hbCB0aWxlLlxuICovXG5jbGFzcyBQcm94aWVkVGlsZUlEIGV4dGVuZHMgT3ZlcnNjYWxlZFRpbGVJRCB7XG4gICAgcHJveHlUaWxlS2V5OiBudW1iZXI7XG5cbiAgICBjb25zdHJ1Y3Rvcih0aWxlSUQ6IE92ZXJzY2FsZWRUaWxlSUQsIHByb3h5VGlsZUtleTogbnVtYmVyLCBwcm9qTWF0cml4OiBGbG9hdDMyQXJyYXkpIHtcbiAgICAgICAgc3VwZXIodGlsZUlELm92ZXJzY2FsZWRaLCB0aWxlSUQud3JhcCwgdGlsZUlELmNhbm9uaWNhbC56LCB0aWxlSUQuY2Fub25pY2FsLngsIHRpbGVJRC5jYW5vbmljYWwueSk7XG4gICAgICAgIHRoaXMucHJveHlUaWxlS2V5ID0gcHJveHlUaWxlS2V5O1xuICAgICAgICB0aGlzLnByb2pNYXRyaXggPSBwcm9qTWF0cml4O1xuICAgIH1cbn1cblxudHlwZSBPdmVybGFwU3RlbmNpbFR5cGUgPSBmYWxzZSB8ICdDbGlwJyB8ICdNYXNrJztcbnR5cGUgRkJPID0ge2ZiOiBGcmFtZWJ1ZmZlciwgdGV4OiBUZXh0dXJlLCBkaXJ0eTogYm9vbGVhbn07XG5cbmV4cG9ydCBjbGFzcyBUZXJyYWluIGV4dGVuZHMgRWxldmF0aW9uIHtcbiAgICB0ZXJyYWluVGlsZUZvclRpbGU6IHtbbnVtYmVyIHwgc3RyaW5nXTogVGlsZX07XG4gICAgcHJldlRlcnJhaW5UaWxlRm9yVGlsZToge1tudW1iZXIgfCBzdHJpbmddOiBUaWxlfTtcbiAgICBwYWludGVyOiBQYWludGVyO1xuICAgIHNvdXJjZUNhY2hlOiBTb3VyY2VDYWNoZTtcbiAgICBncmlkQnVmZmVyOiBWZXJ0ZXhCdWZmZXI7XG4gICAgZ3JpZEluZGV4QnVmZmVyOiBJbmRleEJ1ZmZlcjtcbiAgICBncmlkU2VnbWVudHM6IFNlZ21lbnRWZWN0b3I7XG4gICAgZ3JpZE5vU2tpcnRTZWdtZW50czogU2VnbWVudFZlY3RvcjtcbiAgICB3aXJlZnJhbWVTZWdtZW50czogU2VnbWVudFZlY3RvcjtcbiAgICB3aXJlZnJhbWVJbmRleEJ1ZmZlcjogSW5kZXhCdWZmZXI7XG4gICAgcHJveGllZENvb3Jkczoge1tzdHJpbmddOiBBcnJheTxQcm94aWVkVGlsZUlEPn07XG4gICAgcHJveHlDb29yZHM6IEFycmF5PE92ZXJzY2FsZWRUaWxlSUQ+O1xuICAgIHByb3h5VG9Tb3VyY2U6IHtbbnVtYmVyXToge1tzdHJpbmddOiBBcnJheTxQcm94aWVkVGlsZUlEPn19O1xuICAgIHByb3h5U291cmNlQ2FjaGU6IFByb3h5U291cmNlQ2FjaGU7XG4gICAgcmVuZGVyaW5nVG9UZXh0dXJlOiBib29sZWFuO1xuICAgIF9zdHlsZTogU3R5bGU7XG4gICAgX21vY2tTb3VyY2VDYWNoZTogTW9ja1NvdXJjZUNhY2hlO1xuICAgIG9ydGhvTWF0cml4OiBGbG9hdDMyQXJyYXk7XG4gICAgZW5hYmxlZDogYm9vbGVhbjtcbiAgICByZW5kZXJNb2RlOiBudW1iZXI7XG5cbiAgICBfdmlzaWJsZURlbVRpbGVzOiBBcnJheTxUaWxlPjtcbiAgICBfc291cmNlVGlsZXNPdmVybGFwOiB7W3N0cmluZ106IGJvb2xlYW59O1xuICAgIF9vdmVybGFwU3RlbmNpbE1vZGU6IFN0ZW5jaWxNb2RlO1xuICAgIF9vdmVybGFwU3RlbmNpbFR5cGU6IE92ZXJsYXBTdGVuY2lsVHlwZTtcbiAgICBfc3RlbmNpbFJlZjogbnVtYmVyO1xuXG4gICAgX2V4YWdnZXJhdGlvbjogbnVtYmVyO1xuICAgIF9kZXB0aEZCTzogP0ZyYW1lYnVmZmVyO1xuICAgIF9kZXB0aFRleHR1cmU6ID9UZXh0dXJlO1xuICAgIF9wcmV2aW91c1pvb206IG51bWJlcjtcbiAgICBfdXBkYXRlVGltZXN0YW1wOiBudW1iZXI7XG4gICAgX3VzZVZlcnRleE1vcnBoaW5nOiBib29sZWFuO1xuICAgIHBvb2w6IEFycmF5PEZCTz47XG4gICAgcmVuZGVyZWRUb1RpbGU6IGJvb2xlYW47XG4gICAgX2RyYXBlZFJlbmRlckJhdGNoZXM6IEFycmF5PFJlbmRlckJhdGNoPjtcbiAgICBfc2hhcmVkRGVwdGhTdGVuY2lsOiA/V2ViR0xSZW5kZXJidWZmZXI7XG5cbiAgICBfZmluZENvdmVyaW5nVGlsZUNhY2hlOiB7W3N0cmluZ106IHtbbnVtYmVyXTogP251bWJlcn19O1xuXG4gICAgX3RpbGVzRGlydHk6IHtbc3RyaW5nXToge1tudW1iZXJdOiBib29sZWFufX07XG4gICAgX2ludmFsaWRhdGVSZW5kZXJDYWNoZTogYm9vbGVhbjtcblxuICAgIF9lbXB0eURlcHRoQnVmZmVyVGV4dHVyZTogP1RleHR1cmU7XG4gICAgX2VtcHR5REVNVGV4dHVyZTogP1RleHR1cmU7XG4gICAgX2luaXRpYWxpemluZzogP2Jvb2xlYW47XG4gICAgX2VtcHR5REVNVGV4dHVyZURpcnR5OiA/Ym9vbGVhbjtcblxuICAgIGNvbnN0cnVjdG9yKHBhaW50ZXI6IFBhaW50ZXIsIHN0eWxlOiBTdHlsZSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLnBhaW50ZXIgPSBwYWludGVyO1xuICAgICAgICB0aGlzLnRlcnJhaW5UaWxlRm9yVGlsZSA9IHt9O1xuICAgICAgICB0aGlzLnByZXZUZXJyYWluVGlsZUZvclRpbGUgPSB7fTtcblxuICAgICAgICAvLyBUZXJyYWluIHJlbmRlcmluZyBncmlkIGlzIDEyOXgxMjkgY2VsbCBncmlkLCBtYWRlIGJ5IDEzMHgxMzAgcG9pbnRzLlxuICAgICAgICAvLyAxMzAgdmVydGljZXMgbWFwIHRvIDEyOCBERU0gZGF0YSArIDFweCBwYWRkaW5nIG9uIGJvdGggc2lkZXMuXG4gICAgICAgIC8vIERFTSB0ZXh0dXJlIGlzIHBhZGRlZCAoMSwgMSwgMSwgMSkgYW5kIHBhZGRpbmcgcGl4ZWxzIGFyZSBiYWNrZmlsbGVkXG4gICAgICAgIC8vIGJ5IG5laWdoYm9yaW5nIHRpbGUgZWRnZXMuIFRoaXMgd2F5IHdlIGFjaGlldmUgdGlsZSBzdGl0Y2hpbmcgYXNcbiAgICAgICAgLy8gZWRnZSB2ZXJ0aWNlcyBmcm9tIG5laWdoYm9yaW5nIHRpbGVzIGV2YWx1YXRlIHRvIHRoZSBzYW1lIDNEIHBvaW50LlxuICAgICAgICBjb25zdCBbdHJpYW5nbGVHcmlkQXJyYXksIHRyaWFuZ2xlR3JpZEluZGljZXMsIHNraXJ0SW5kaWNlc09mZnNldF0gPSBjcmVhdGVHcmlkKEdSSURfRElNICsgMSk7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBwYWludGVyLmNvbnRleHQ7XG4gICAgICAgIHRoaXMuZ3JpZEJ1ZmZlciA9IGNvbnRleHQuY3JlYXRlVmVydGV4QnVmZmVyKHRyaWFuZ2xlR3JpZEFycmF5LCBwb3NBdHRyaWJ1dGVzLm1lbWJlcnMpO1xuICAgICAgICB0aGlzLmdyaWRJbmRleEJ1ZmZlciA9IGNvbnRleHQuY3JlYXRlSW5kZXhCdWZmZXIodHJpYW5nbGVHcmlkSW5kaWNlcyk7XG4gICAgICAgIHRoaXMuZ3JpZFNlZ21lbnRzID0gU2VnbWVudFZlY3Rvci5zaW1wbGVTZWdtZW50KDAsIDAsIHRyaWFuZ2xlR3JpZEFycmF5Lmxlbmd0aCwgdHJpYW5nbGVHcmlkSW5kaWNlcy5sZW5ndGgpO1xuICAgICAgICB0aGlzLmdyaWROb1NraXJ0U2VnbWVudHMgPSBTZWdtZW50VmVjdG9yLnNpbXBsZVNlZ21lbnQoMCwgMCwgdHJpYW5nbGVHcmlkQXJyYXkubGVuZ3RoLCBza2lydEluZGljZXNPZmZzZXQpO1xuICAgICAgICB0aGlzLnByb3h5Q29vcmRzID0gW107XG4gICAgICAgIHRoaXMucHJveGllZENvb3JkcyA9IHt9O1xuICAgICAgICB0aGlzLl92aXNpYmxlRGVtVGlsZXMgPSBbXTtcbiAgICAgICAgdGhpcy5fZHJhcGVkUmVuZGVyQmF0Y2hlcyA9IFtdO1xuICAgICAgICB0aGlzLl9zb3VyY2VUaWxlc092ZXJsYXAgPSB7fTtcbiAgICAgICAgdGhpcy5wcm94eVNvdXJjZUNhY2hlID0gbmV3IFByb3h5U291cmNlQ2FjaGUoc3R5bGUubWFwKTtcbiAgICAgICAgdGhpcy5vcnRob01hdHJpeCA9IG1hdDQuY3JlYXRlKCk7XG4gICAgICAgIGNvbnN0IGVwc2lsb24gPSB0aGlzLnBhaW50ZXIudHJhbnNmb3JtLnByb2plY3Rpb24ubmFtZSA9PT0gJ2dsb2JlJyA/ICAuMDE1IDogMDsgLy8gRXhwZXJpbWVudGFsbHkgdGhlIHNtYWxsZXN0IHZhbHVlIHRvIGF2b2lkIHJlbmRlcmluZyBhcnRpZmFjdHMgKGh0dHBzOi8vZ2l0aHViLmNvbS9tYXBib3gvbWFwYm94LWdsLWpzL2lzc3Vlcy8xMTk3NSlcbiAgICAgICAgbWF0NC5vcnRobyh0aGlzLm9ydGhvTWF0cml4LCBlcHNpbG9uLCBFWFRFTlQsIDAsIEVYVEVOVCwgMCwgMSk7XG4gICAgICAgIGNvbnN0IGdsID0gY29udGV4dC5nbDtcbiAgICAgICAgdGhpcy5fb3ZlcmxhcFN0ZW5jaWxNb2RlID0gbmV3IFN0ZW5jaWxNb2RlKHtmdW5jOiBnbC5HRVFVQUwsIG1hc2s6IDB4RkZ9LCAwLCAweEZGLCBnbC5LRUVQLCBnbC5LRUVQLCBnbC5SRVBMQUNFKTtcbiAgICAgICAgdGhpcy5fcHJldmlvdXNab29tID0gcGFpbnRlci50cmFuc2Zvcm0uem9vbTtcbiAgICAgICAgdGhpcy5wb29sID0gW107XG4gICAgICAgIHRoaXMuX2ZpbmRDb3ZlcmluZ1RpbGVDYWNoZSA9IHt9O1xuICAgICAgICB0aGlzLl90aWxlc0RpcnR5ID0ge307XG4gICAgICAgIHRoaXMuc3R5bGUgPSBzdHlsZTtcbiAgICAgICAgdGhpcy5fdXNlVmVydGV4TW9ycGhpbmcgPSB0cnVlO1xuICAgICAgICB0aGlzLl9leGFnZ2VyYXRpb24gPSAxO1xuICAgICAgICB0aGlzLl9tb2NrU291cmNlQ2FjaGUgPSBuZXcgTW9ja1NvdXJjZUNhY2hlKHN0eWxlLm1hcCk7XG4gICAgfVxuXG4gICAgc2V0IHN0eWxlKHN0eWxlOiBTdHlsZSkge1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIHN0eWxlLm9uKCdkYXRhJywgdGhpcy5fb25TdHlsZURhdGFFdmVudC5iaW5kKHRoaXMpKTtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICBzdHlsZS5vbignbmV3b3JkZXInLCB0aGlzLl9jaGVja1JlbmRlckNhY2hlRWZmaWNpZW5jeS5iaW5kKHRoaXMpKTtcbiAgICAgICAgdGhpcy5fc3R5bGUgPSBzdHlsZTtcbiAgICAgICAgdGhpcy5fY2hlY2tSZW5kZXJDYWNoZUVmZmljaWVuY3koKTtcbiAgICAgICAgdGhpcy5fc3R5bGUubWFwLm9uKCdtb3ZlZW5kJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fY2xlYXJMaW5lTGF5ZXJzRnJvbVJlbmRlckNhY2hlKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qXG4gICAgICogVmFsaWRhdGUgdGVycmFpbiBhbmQgdXBkYXRlIHNvdXJjZSBjYWNoZSB1c2VkIGZvciBlbGV2YXRpb24uXG4gICAgICogRXhwbGljaXRseSBwYXNzIHRyYW5zZm9ybSB0byB1cGRhdGUgZWxldmF0aW9uIChUcmFuc2Zvcm0udXBkYXRlRWxldmF0aW9uKVxuICAgICAqIGJlZm9yZSB1c2luZyB0cmFuc2Zvcm0gZm9yIHNvdXJjZSBjYWNoZSB1cGRhdGUuXG4gICAgICovXG4gICAgdXBkYXRlKHN0eWxlOiBTdHlsZSwgdHJhbnNmb3JtOiBUcmFuc2Zvcm0sIGFkYXB0Q2FtZXJhQWx0aXR1ZGU6IGJvb2xlYW4pIHtcbiAgICAgICAgaWYgKHN0eWxlICYmIHN0eWxlLnRlcnJhaW4pIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9zdHlsZSAhPT0gc3R5bGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0eWxlID0gc3R5bGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgY29uc3QgdGVycmFpblByb3BzID0gc3R5bGUudGVycmFpbi5wcm9wZXJ0aWVzO1xuICAgICAgICAgICAgY29uc3QgaXNEcmFwZU1vZGVEZWZlcnJlZCA9IHN0eWxlLnRlcnJhaW4uZHJhcGVSZW5kZXJNb2RlID09PSBEcmFwZVJlbmRlck1vZGUuZGVmZXJyZWQ7XG4gICAgICAgICAgICB0aGlzLnNvdXJjZUNhY2hlID0gaXNEcmFwZU1vZGVEZWZlcnJlZCA/IHRoaXMuX21vY2tTb3VyY2VDYWNoZSA6XG4gICAgICAgICAgICAgICAgKChzdHlsZS5fZ2V0U291cmNlQ2FjaGUodGVycmFpblByb3BzLmdldCgnc291cmNlJykpOiBhbnkpOiBTb3VyY2VDYWNoZSk7XG4gICAgICAgICAgICB0aGlzLl9leGFnZ2VyYXRpb24gPSB0ZXJyYWluUHJvcHMuZ2V0KCdleGFnZ2VyYXRpb24nKTtcblxuICAgICAgICAgICAgY29uc3QgdXBkYXRlU291cmNlQ2FjaGUgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc291cmNlQ2FjaGUudXNlZCkge1xuICAgICAgICAgICAgICAgICAgICB3YXJuT25jZShgUmFzdGVyIERFTSBzb3VyY2UgJyR7dGhpcy5zb3VyY2VDYWNoZS5pZH0nIGlzIHVzZWQgYm90aCBmb3IgdGVycmFpbiBhbmQgYXMgbGF5ZXIgc291cmNlLlxcbmAgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJ1RoaXMgbGVhZHMgdG8gbG93ZXIgcmVzb2x1dGlvbiBvZiBoaWxsc2hhZGUuIEZvciBmdWxsIGhpbGxzaGFkZSByZXNvbHV0aW9uIGJ1dCBoaWdoZXIgbWVtb3J5IGNvbnN1bXB0aW9uLCBkZWZpbmUgYW5vdGhlciByYXN0ZXIgREVNIHNvdXJjZS4nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gTG93ZXIgdGlsZSB6b29tIGlzIHN1ZmZpY2llbnQgZm9yIHRlcnJhaW4sIGdpdmVuIHRoZSBzaXplIG9mIHRlcnJhaW4gZ3JpZC5cbiAgICAgICAgICAgICAgICBjb25zdCBzY2FsZWREZW1UaWxlU2l6ZSA9IHRoaXMuZ2V0U2NhbGVkRGVtVGlsZVNpemUoKTtcbiAgICAgICAgICAgICAgICAvLyBEZW0gdGlsZSBuZWVkcyB0byBiZSBwYXJlbnQgb3IgYXQgbGVhc3Qgb2YgdGhlIHNhbWUgem9vbSBsZXZlbCBhcyBwcm94eSB0aWxlLlxuICAgICAgICAgICAgICAgIC8vIFRpbGUgY292ZXIgcm91bmRab29tIGJlaGF2aW9yIGlzIHNldCB0byB0aGUgc2FtZSBhcyBmb3IgcHJveHkgKGZhbHNlKSBpbiBTb3VyY2VDYWNoZS51cGRhdGUoKS5cbiAgICAgICAgICAgICAgICB0aGlzLnNvdXJjZUNhY2hlLnVwZGF0ZSh0cmFuc2Zvcm0sIHNjYWxlZERlbVRpbGVTaXplLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAvLyBBcyBhIHJlc3VsdCBvZiB1cGRhdGUsIHdlIGdldCBuZXcgc2V0IG9mIHRpbGVzOiByZXNldCBsb29rdXAgY2FjaGUuXG4gICAgICAgICAgICAgICAgdGhpcy5yZXNldFRpbGVMb29rdXBDYWNoZSh0aGlzLnNvdXJjZUNhY2hlLmlkKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5zb3VyY2VDYWNoZS51c2VkRm9yVGVycmFpbikge1xuICAgICAgICAgICAgICAgIC8vIEluaXQgY2FjaGUgZW50cnkuXG4gICAgICAgICAgICAgICAgdGhpcy5yZXNldFRpbGVMb29rdXBDYWNoZSh0aGlzLnNvdXJjZUNhY2hlLmlkKTtcbiAgICAgICAgICAgICAgICAvLyBXaGVuIHRvZ2dsaW5nIHRlcnJhaW4gb24vb2ZmIGxvYWQgYXZhaWxhYmxlIHRlcnJhaW4gdGlsZXMgZnJvbSBjYWNoZVxuICAgICAgICAgICAgICAgIC8vIGJlZm9yZSByZWFkaW5nIGVsZXZhdGlvbiBhdCBjZW50ZXIuXG4gICAgICAgICAgICAgICAgdGhpcy5zb3VyY2VDYWNoZS51c2VkRm9yVGVycmFpbiA9IHRydWU7XG4gICAgICAgICAgICAgICAgdXBkYXRlU291cmNlQ2FjaGUoKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9pbml0aWFsaXppbmcgPSB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB1cGRhdGVTb3VyY2VDYWNoZSgpO1xuICAgICAgICAgICAgLy8gQ2FtZXJhIGdldHMgY29uc3RyYWluZWQgb3ZlciB0ZXJyYWluLiBJc3N1ZSBjb25zdHJhaW5DYW1lcmFPdmVyVGVycmFpbiA9IHRydWVcbiAgICAgICAgICAgIC8vIGhlcmUgdG8gY292ZXIgcG90ZW50aWFsIHVuZGVyIHRlcnJhaW4gc2l0dWF0aW9uIG9uIGRhdGEsIHN0eWxlLCBvciBvdGhlciBjYW1lcmEgY2hhbmdlcy5cbiAgICAgICAgICAgIHRyYW5zZm9ybS51cGRhdGVFbGV2YXRpb24odHJ1ZSwgYWRhcHRDYW1lcmFBbHRpdHVkZSk7XG5cbiAgICAgICAgICAgIC8vIFJlc2V0IHRpbGUgbG9va3VwIGNhY2hlIGFuZCB1cGRhdGUgZHJhcGVkIHRpbGVzIGNvb3JkaW5hdGVzLlxuICAgICAgICAgICAgdGhpcy5yZXNldFRpbGVMb29rdXBDYWNoZSh0aGlzLnByb3h5U291cmNlQ2FjaGUuaWQpO1xuICAgICAgICAgICAgdGhpcy5wcm94eVNvdXJjZUNhY2hlLnVwZGF0ZSh0cmFuc2Zvcm0pO1xuXG4gICAgICAgICAgICB0aGlzLl9lbXB0eURFTVRleHR1cmVEaXJ0eSA9IHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9kaXNhYmxlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXNldFRpbGVMb29rdXBDYWNoZShzb3VyY2VDYWNoZUlEOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5fZmluZENvdmVyaW5nVGlsZUNhY2hlW3NvdXJjZUNhY2hlSURdID0ge307XG4gICAgfVxuXG4gICAgZ2V0U2NhbGVkRGVtVGlsZVNpemUoKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgZGVtU2NhbGUgPSB0aGlzLnNvdXJjZUNhY2hlLmdldFNvdXJjZSgpLnRpbGVTaXplIC8gR1JJRF9ESU07XG4gICAgICAgIGNvbnN0IHByb3h5VGlsZVNpemUgPSB0aGlzLnByb3h5U291cmNlQ2FjaGUuZ2V0U291cmNlKCkudGlsZVNpemU7XG4gICAgICAgIHJldHVybiBkZW1TY2FsZSAqIHByb3h5VGlsZVNpemU7XG4gICAgfVxuXG4gICAgX2NoZWNrUmVuZGVyQ2FjaGVFZmZpY2llbmN5KCkge1xuICAgICAgICBjb25zdCByZW5kZXJDYWNoZUluZm8gPSB0aGlzLnJlbmRlckNhY2hlRWZmaWNpZW5jeSh0aGlzLl9zdHlsZSk7XG4gICAgICAgIGlmICh0aGlzLl9zdHlsZS5tYXAuX29wdGltaXplRm9yVGVycmFpbikge1xuICAgICAgICAgICAgYXNzZXJ0KHJlbmRlckNhY2hlSW5mby5lZmZpY2llbmN5ID09PSAxMDApO1xuICAgICAgICB9IGVsc2UgaWYgKHJlbmRlckNhY2hlSW5mby5lZmZpY2llbmN5ICE9PSAxMDApIHtcbiAgICAgICAgICAgIHdhcm5PbmNlKGBUZXJyYWluIHJlbmRlciBjYWNoZSBlZmZpY2llbmN5IGlzIG5vdCBvcHRpbWFsICgke3JlbmRlckNhY2hlSW5mby5lZmZpY2llbmN5fSUpIGFuZCBwZXJmb3JtYW5jZVxuICAgICAgICAgICAgICAgIG1heSBiZSBhZmZlY3RlZCBuZWdhdGl2ZWx5LCBjb25zaWRlciBwbGFjaW5nIGFsbCBiYWNrZ3JvdW5kLCBmaWxsIGFuZCBsaW5lIGxheWVycyBiZWZvcmUgbGF5ZXJcbiAgICAgICAgICAgICAgICB3aXRoIGlkICcke3JlbmRlckNhY2hlSW5mby5maXJzdFVuZHJhcGVkTGF5ZXJ9JyBvciBjcmVhdGUgYSBtYXAgdXNpbmcgb3B0aW1pemVGb3JUZXJyYWluOiB0cnVlIG9wdGlvbi5gKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9vblN0eWxlRGF0YUV2ZW50KGV2ZW50OiBhbnkpIHtcbiAgICAgICAgaWYgKGV2ZW50LmNvb3JkICYmIGV2ZW50LmRhdGFUeXBlID09PSAnc291cmNlJykge1xuICAgICAgICAgICAgdGhpcy5fY2xlYXJSZW5kZXJDYWNoZUZvclRpbGUoZXZlbnQuc291cmNlQ2FjaGVJZCwgZXZlbnQuY29vcmQpO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmRhdGFUeXBlID09PSAnc3R5bGUnKSB7XG4gICAgICAgICAgICB0aGlzLl9pbnZhbGlkYXRlUmVuZGVyQ2FjaGUgPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gVGVycmFpblxuICAgIF9kaXNhYmxlKCkge1xuICAgICAgICBpZiAoIXRoaXMuZW5hYmxlZCkgcmV0dXJuO1xuICAgICAgICB0aGlzLmVuYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fc2hhcmVkRGVwdGhTdGVuY2lsID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLnByb3h5U291cmNlQ2FjaGUuZGVhbGxvY1JlbmRlckNhY2hlKCk7XG4gICAgICAgIGlmICh0aGlzLl9zdHlsZSkge1xuICAgICAgICAgICAgZm9yIChjb25zdCBpZCBpbiB0aGlzLl9zdHlsZS5fc291cmNlQ2FjaGVzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3R5bGUuX3NvdXJjZUNhY2hlc1tpZF0udXNlZEZvclRlcnJhaW4gPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMuX2Rpc2FibGUoKTtcbiAgICAgICAgaWYgKHRoaXMuX2VtcHR5REVNVGV4dHVyZSkgdGhpcy5fZW1wdHlERU1UZXh0dXJlLmRlc3Ryb3koKTtcbiAgICAgICAgaWYgKHRoaXMuX2VtcHR5RGVwdGhCdWZmZXJUZXh0dXJlKSB0aGlzLl9lbXB0eURlcHRoQnVmZmVyVGV4dHVyZS5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMucG9vbC5mb3JFYWNoKGZibyA9PiBmYm8uZmIuZGVzdHJveSgpKTtcbiAgICAgICAgdGhpcy5wb29sID0gW107XG4gICAgICAgIGlmICh0aGlzLl9kZXB0aEZCTykge1xuICAgICAgICAgICAgdGhpcy5fZGVwdGhGQk8uZGVzdHJveSgpO1xuICAgICAgICAgICAgdGhpcy5fZGVwdGhGQk8gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0aGlzLl9kZXB0aFRleHR1cmUgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBJbXBsZW1lbnRzIEVsZXZhdGlvbjo6X3NvdXJjZS5cbiAgICBfc291cmNlKCk6ID9Tb3VyY2VDYWNoZSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVuYWJsZWQgPyB0aGlzLnNvdXJjZUNhY2hlIDogbnVsbDtcbiAgICB9XG5cbiAgICBpc1VzaW5nTW9ja1NvdXJjZSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc291cmNlQ2FjaGUgPT09IHRoaXMuX21vY2tTb3VyY2VDYWNoZTtcbiAgICB9XG5cbiAgICAvLyBJbXBsZW1lbnRzIEVsZXZhdGlvbjo6ZXhhZ2dlcmF0aW9uLlxuICAgIGV4YWdnZXJhdGlvbigpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXhhZ2dlcmF0aW9uO1xuICAgIH1cblxuICAgIGdldCB2aXNpYmxlRGVtVGlsZXMoKTogQXJyYXk8VGlsZT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fdmlzaWJsZURlbVRpbGVzO1xuICAgIH1cblxuICAgIGdldCBkcmFwZUJ1ZmZlclNpemUoKTogW251bWJlciwgbnVtYmVyXSB7XG4gICAgICAgIGNvbnN0IGV4dGVudCA9IHRoaXMucHJveHlTb3VyY2VDYWNoZS5nZXRTb3VyY2UoKS50aWxlU2l6ZSAqIDI7IC8vICoyIGlzIHRvIGF2b2lkIHVwc2NhbGluZyBiaXRtYXAgb24gem9vbS5cbiAgICAgICAgcmV0dXJuIFtleHRlbnQsIGV4dGVudF07XG4gICAgfVxuXG4gICAgc2V0IHVzZVZlcnRleE1vcnBoaW5nKGVuYWJsZTogYm9vbGVhbikge1xuICAgICAgICB0aGlzLl91c2VWZXJ0ZXhNb3JwaGluZyA9IGVuYWJsZTtcbiAgICB9XG5cbiAgICAvLyBGb3IgZXZlcnkgcmVuZGVyYWJsZSBjb29yZGluYXRlIGluIGV2ZXJ5IHNvdXJjZSBjYWNoZSwgYXNzaWduIG9uZSBwcm94eVxuICAgIC8vIHRpbGUgKHNlZSBfc2V0dXBQcm94aWVkQ29vcmRzRm9yT3J0aG8pLiBNYXBwaW5nIG9mIHNvdXJjZSB0aWxlIHRvIHByb3h5XG4gICAgLy8gdGlsZSBpcyBtb2RlbGVkIGJ5IFByb3hpZWRUaWxlSUQuIEluIGdlbmVyYWwgY2FzZSwgc291cmNlIGFuZCBwcm94eSB0aWxlXG4gICAgLy8gYXJlIG9mIGRpZmZlcmVudCB6b29tOiBQcm94aWVkVGlsZUlELnByb2pNYXRyaXggbW9kZWxzIG9ydGhvLCBzY2FsZSBhbmRcbiAgICAvLyB0cmFuc2xhdGUgZnJvbSBzb3VyY2UgdG8gcHJveHkuIFRoaXMgbWF0cml4IGlzIHVzZWQgd2hlbiByZW5kZXJpbmcgc291cmNlXG4gICAgLy8gdGlsZSB0byBwcm94eSB0aWxlJ3MgdGV4dHVyZS5cbiAgICAvLyBPbmUgcHJveHkgdGlsZSBjYW4gaGF2ZSBtdWx0aXBsZSBzb3VyY2UgdGlsZXMsIG9yIHBpZWNlcyBvZiBzb3VyY2UgdGlsZXMsXG4gICAgLy8gdGhhdCBnZXQgcmVuZGVyZWQgdG8gaXQuXG4gICAgLy8gRm9yIGVhY2ggcHJveHkgdGlsZSB3ZSBhc3NpZ24gb25lIHRlcnJhaW4gdGlsZSAoX2Fzc2lnblRlcnJhaW5UaWxlcykuIFRoZVxuICAgIC8vIHRlcnJhaW4gdGlsZSBwcm92aWRlcyBlbGV2YXRpb24gZGF0YSB3aGVuIHJlbmRlcmluZyAoZHJhcGluZykgcHJveHkgdGlsZVxuICAgIC8vIHRleHR1cmUgb3ZlciB0ZXJyYWluIGdyaWQuXG4gICAgdXBkYXRlVGlsZUJpbmRpbmcoc291cmNlc0Nvb3Jkczoge1tzdHJpbmddOiBBcnJheTxPdmVyc2NhbGVkVGlsZUlEPn0pIHtcbiAgICAgICAgaWYgKCF0aGlzLmVuYWJsZWQpIHJldHVybjtcbiAgICAgICAgdGhpcy5wcmV2VGVycmFpblRpbGVGb3JUaWxlID0gdGhpcy50ZXJyYWluVGlsZUZvclRpbGU7XG5cbiAgICAgICAgY29uc3QgcHNjID0gdGhpcy5wcm94eVNvdXJjZUNhY2hlO1xuICAgICAgICBjb25zdCB0ciA9IHRoaXMucGFpbnRlci50cmFuc2Zvcm07XG4gICAgICAgIGlmICh0aGlzLl9pbml0aWFsaXppbmcpIHtcbiAgICAgICAgICAgIC8vIERvbid0IGFjdGl2YXRlIHRlcnJhaW4gdW50aWwgY2VudGVyIHRpbGUgZ2V0cyBsb2FkZWQuXG4gICAgICAgICAgICB0aGlzLl9pbml0aWFsaXppbmcgPSB0ci5fY2VudGVyQWx0aXR1ZGUgPT09IDAgJiYgdGhpcy5nZXRBdFBvaW50T3JaZXJvKE1lcmNhdG9yQ29vcmRpbmF0ZS5mcm9tTG5nTGF0KHRyLmNlbnRlciksIC0xKSA9PT0gLTE7XG4gICAgICAgICAgICB0aGlzLl9lbXB0eURFTVRleHR1cmVEaXJ0eSA9ICF0aGlzLl9pbml0aWFsaXppbmc7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjb29yZHMgPSB0aGlzLnByb3h5Q29vcmRzID0gcHNjLmdldElkcygpLm1hcCgoaWQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRpbGVJRCA9IHBzYy5nZXRUaWxlQnlJRChpZCkudGlsZUlEO1xuICAgICAgICAgICAgdGlsZUlELnByb2pNYXRyaXggPSB0ci5jYWxjdWxhdGVQcm9qTWF0cml4KHRpbGVJRC50b1Vud3JhcHBlZCgpKTtcbiAgICAgICAgICAgIHJldHVybiB0aWxlSUQ7XG4gICAgICAgIH0pO1xuICAgICAgICBzb3J0QnlEaXN0YW5jZVRvQ2FtZXJhKGNvb3JkcywgdGhpcy5wYWludGVyKTtcbiAgICAgICAgdGhpcy5fcHJldmlvdXNab29tID0gdHIuem9vbTtcblxuICAgICAgICBjb25zdCBwcmV2aW91c1Byb3h5VG9Tb3VyY2UgPSB0aGlzLnByb3h5VG9Tb3VyY2UgfHwge307XG4gICAgICAgIHRoaXMucHJveHlUb1NvdXJjZSA9IHt9O1xuICAgICAgICBjb29yZHMuZm9yRWFjaCgodGlsZUlEKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnByb3h5VG9Tb3VyY2VbdGlsZUlELmtleV0gPSB7fTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy50ZXJyYWluVGlsZUZvclRpbGUgPSB7fTtcbiAgICAgICAgY29uc3Qgc291cmNlQ2FjaGVzID0gdGhpcy5fc3R5bGUuX3NvdXJjZUNhY2hlcztcbiAgICAgICAgZm9yIChjb25zdCBpZCBpbiBzb3VyY2VDYWNoZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHNvdXJjZUNhY2hlID0gc291cmNlQ2FjaGVzW2lkXTtcbiAgICAgICAgICAgIGlmICghc291cmNlQ2FjaGUudXNlZCkgY29udGludWU7XG4gICAgICAgICAgICBpZiAoc291cmNlQ2FjaGUgIT09IHRoaXMuc291cmNlQ2FjaGUpIHRoaXMucmVzZXRUaWxlTG9va3VwQ2FjaGUoc291cmNlQ2FjaGUuaWQpO1xuICAgICAgICAgICAgdGhpcy5fc2V0dXBQcm94aWVkQ29vcmRzRm9yT3J0aG8oc291cmNlQ2FjaGUsIHNvdXJjZXNDb29yZHNbaWRdLCBwcmV2aW91c1Byb3h5VG9Tb3VyY2UpO1xuICAgICAgICAgICAgaWYgKHNvdXJjZUNhY2hlLnVzZWRGb3JUZXJyYWluKSBjb250aW51ZTtcbiAgICAgICAgICAgIGNvbnN0IGNvb3JkaW5hdGVzID0gc291cmNlc0Nvb3Jkc1tpZF07XG4gICAgICAgICAgICBpZiAoc291cmNlQ2FjaGUuZ2V0U291cmNlKCkucmVwYXJzZU92ZXJzY2FsZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBEbyB0aGlzIGZvciBsYXllcnMgdGhhdCBhcmUgbm90IHJhc3Rlcml6ZWQgdG8gcHJveHkgdGlsZS5cbiAgICAgICAgICAgICAgICB0aGlzLl9hc3NpZ25UZXJyYWluVGlsZXMoY29vcmRpbmF0ZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gQmFja2dyb3VuZCBoYXMgbm8gc291cmNlLiBVc2luZyBwcm94eSBjb29yZHMgd2l0aCAxLTEgb3J0aG8gKHRoaXMucHJveGllZENvb3Jkc1twc2MuaWRdKVxuICAgICAgICAvLyB3aGVuIHJlbmRlcmluZyBiYWNrZ3JvdW5kIHRvIHByb3h5IHRpbGVzLlxuICAgICAgICB0aGlzLnByb3hpZWRDb29yZHNbcHNjLmlkXSA9IGNvb3Jkcy5tYXAodGlsZUlEID0+IG5ldyBQcm94aWVkVGlsZUlEKHRpbGVJRCwgdGlsZUlELmtleSwgdGhpcy5vcnRob01hdHJpeCkpO1xuICAgICAgICB0aGlzLl9hc3NpZ25UZXJyYWluVGlsZXMoY29vcmRzKTtcbiAgICAgICAgdGhpcy5fcHJlcGFyZURFTVRleHR1cmVzKCk7XG4gICAgICAgIHRoaXMuX3NldHVwRHJhcGVkUmVuZGVyQmF0Y2hlcygpO1xuICAgICAgICB0aGlzLl9pbml0RkJPUG9vbCgpO1xuICAgICAgICB0aGlzLl9zZXR1cFJlbmRlckNhY2hlKHByZXZpb3VzUHJveHlUb1NvdXJjZSk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJpbmdUb1RleHR1cmUgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fdXBkYXRlVGltZXN0YW1wID0gYnJvd3Nlci5ub3coKTtcblxuICAgICAgICAvLyBHYXRoZXIgYWxsIGRlbSB0aWxlcyB0aGF0IGFyZSBhc3NpZ25lZCB0byBwcm94eSB0aWxlc1xuICAgICAgICBjb25zdCB2aXNpYmxlS2V5cyA9IHt9O1xuICAgICAgICB0aGlzLl92aXNpYmxlRGVtVGlsZXMgPSBbXTtcblxuICAgICAgICBmb3IgKGNvbnN0IGlkIG9mIHRoaXMucHJveHlDb29yZHMpIHtcbiAgICAgICAgICAgIGNvbnN0IGRlbVRpbGUgPSB0aGlzLnRlcnJhaW5UaWxlRm9yVGlsZVtpZC5rZXldO1xuICAgICAgICAgICAgaWYgKCFkZW1UaWxlKVxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgY29uc3Qga2V5ID0gZGVtVGlsZS50aWxlSUQua2V5O1xuICAgICAgICAgICAgaWYgKGtleSBpbiB2aXNpYmxlS2V5cylcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIHRoaXMuX3Zpc2libGVEZW1UaWxlcy5wdXNoKGRlbVRpbGUpO1xuICAgICAgICAgICAgdmlzaWJsZUtleXNba2V5XSA9IGtleTtcbiAgICAgICAgfVxuXG4gICAgfVxuXG4gICAgX2Fzc2lnblRlcnJhaW5UaWxlcyhjb29yZHM6IEFycmF5PE92ZXJzY2FsZWRUaWxlSUQ+KSB7XG4gICAgICAgIGlmICh0aGlzLl9pbml0aWFsaXppbmcpIHJldHVybjtcbiAgICAgICAgY29vcmRzLmZvckVhY2goKHRpbGVJRCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMudGVycmFpblRpbGVGb3JUaWxlW3RpbGVJRC5rZXldKSByZXR1cm47XG4gICAgICAgICAgICBjb25zdCBkZW1UaWxlID0gdGhpcy5fZmluZFRpbGVDb3ZlcmluZ1RpbGVJRCh0aWxlSUQsIHRoaXMuc291cmNlQ2FjaGUpO1xuICAgICAgICAgICAgaWYgKGRlbVRpbGUpIHRoaXMudGVycmFpblRpbGVGb3JUaWxlW3RpbGVJRC5rZXldID0gZGVtVGlsZTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgX3ByZXBhcmVERU1UZXh0dXJlcygpIHtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMucGFpbnRlci5jb250ZXh0O1xuICAgICAgICBjb25zdCBnbCA9IGNvbnRleHQuZ2w7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIHRoaXMudGVycmFpblRpbGVGb3JUaWxlKSB7XG4gICAgICAgICAgICBjb25zdCB0aWxlID0gdGhpcy50ZXJyYWluVGlsZUZvclRpbGVba2V5XTtcbiAgICAgICAgICAgIGNvbnN0IGRlbSA9IHRpbGUuZGVtO1xuICAgICAgICAgICAgaWYgKGRlbSAmJiAoIXRpbGUuZGVtVGV4dHVyZSB8fCB0aWxlLm5lZWRzREVNVGV4dHVyZVVwbG9hZCkpIHtcbiAgICAgICAgICAgICAgICBjb250ZXh0LmFjdGl2ZVRleHR1cmUuc2V0KGdsLlRFWFRVUkUxKTtcbiAgICAgICAgICAgICAgICBwcmVwYXJlREVNVGV4dHVyZSh0aGlzLnBhaW50ZXIsIHRpbGUsIGRlbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfcHJlcGFyZURlbVRpbGVVbmlmb3Jtcyhwcm94eVRpbGU6IFRpbGUsIGRlbVRpbGU6ID9UaWxlLCB1bmlmb3JtczogVW5pZm9ybVZhbHVlczxUZXJyYWluVW5pZm9ybXNUeXBlPiwgdW5pZm9ybVN1ZmZpeDogP3N0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAoIWRlbVRpbGUgfHwgZGVtVGlsZS5kZW1UZXh0dXJlID09IG51bGwpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgYXNzZXJ0KGRlbVRpbGUuZGVtKTtcbiAgICAgICAgY29uc3QgcHJveHlJZCA9IHByb3h5VGlsZS50aWxlSUQuY2Fub25pY2FsO1xuICAgICAgICBjb25zdCBkZW1JZCA9IGRlbVRpbGUudGlsZUlELmNhbm9uaWNhbDtcbiAgICAgICAgY29uc3QgZGVtU2NhbGVCeSA9IE1hdGgucG93KDIsIGRlbUlkLnogLSBwcm94eUlkLnopO1xuICAgICAgICBjb25zdCBzdWZmaXggPSB1bmlmb3JtU3VmZml4IHx8IFwiXCI7XG4gICAgICAgIC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXVxuICAgICAgICB1bmlmb3Jtc1tgdV9kZW1fdGwke3N1ZmZpeH1gXSA9IFtwcm94eUlkLnggKiBkZW1TY2FsZUJ5ICUgMSwgcHJveHlJZC55ICogZGVtU2NhbGVCeSAlIDFdO1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW3Byb3AtbWlzc2luZ11cbiAgICAgICAgdW5pZm9ybXNbYHVfZGVtX3NjYWxlJHtzdWZmaXh9YF0gPSBkZW1TY2FsZUJ5O1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBnZXQgZW1wdHlERU1UZXh0dXJlKCk6IFRleHR1cmUge1xuICAgICAgICByZXR1cm4gIXRoaXMuX2VtcHR5REVNVGV4dHVyZURpcnR5ICYmIHRoaXMuX2VtcHR5REVNVGV4dHVyZSA/XG4gICAgICAgICAgICB0aGlzLl9lbXB0eURFTVRleHR1cmUgOiB0aGlzLl91cGRhdGVFbXB0eURFTVRleHR1cmUoKTtcbiAgICB9XG5cbiAgICBnZXQgZW1wdHlEZXB0aEJ1ZmZlclRleHR1cmUoKTogVGV4dHVyZSB7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLnBhaW50ZXIuY29udGV4dDtcbiAgICAgICAgY29uc3QgZ2wgPSBjb250ZXh0LmdsO1xuICAgICAgICBpZiAoIXRoaXMuX2VtcHR5RGVwdGhCdWZmZXJUZXh0dXJlKSB7XG4gICAgICAgICAgICBjb25zdCBpbWFnZSA9IG5ldyBSR0JBSW1hZ2Uoe3dpZHRoOiAxLCBoZWlnaHQ6IDF9LCBVaW50OEFycmF5Lm9mKDI1NSwgMjU1LCAyNTUsIDI1NSkpO1xuICAgICAgICAgICAgdGhpcy5fZW1wdHlEZXB0aEJ1ZmZlclRleHR1cmUgPSBuZXcgVGV4dHVyZShjb250ZXh0LCBpbWFnZSwgZ2wuUkdCQSwge3ByZW11bHRpcGx5OiBmYWxzZX0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9lbXB0eURlcHRoQnVmZmVyVGV4dHVyZTtcbiAgICB9XG5cbiAgICBfZ2V0TG9hZGVkQXJlYU1pbmltdW0oKTogbnVtYmVyIHtcbiAgICAgICAgbGV0IG5vbnplcm8gPSAwO1xuICAgICAgICBjb25zdCBtaW4gPSB0aGlzLl92aXNpYmxlRGVtVGlsZXMucmVkdWNlKChhY2MsIHRpbGUpID0+IHtcbiAgICAgICAgICAgIGlmICghdGlsZS5kZW0pIHJldHVybiBhY2M7XG4gICAgICAgICAgICBjb25zdCBtID0gdGlsZS5kZW0udHJlZS5taW5pbXVtc1swXTtcbiAgICAgICAgICAgIGFjYyArPSBtO1xuICAgICAgICAgICAgaWYgKG0gPiAwKSBub256ZXJvKys7XG4gICAgICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgICB9LCAwKTtcbiAgICAgICAgcmV0dXJuIG5vbnplcm8gPyBtaW4gLyBub256ZXJvIDogMDtcbiAgICB9XG5cbiAgICBfdXBkYXRlRW1wdHlERU1UZXh0dXJlKCk6IFRleHR1cmUge1xuICAgICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5wYWludGVyLmNvbnRleHQ7XG4gICAgICAgIGNvbnN0IGdsID0gY29udGV4dC5nbDtcbiAgICAgICAgY29udGV4dC5hY3RpdmVUZXh0dXJlLnNldChnbC5URVhUVVJFMik7XG5cbiAgICAgICAgY29uc3QgbWluID0gdGhpcy5fZ2V0TG9hZGVkQXJlYU1pbmltdW0oKTtcbiAgICAgICAgY29uc3QgaW1hZ2UgPSBuZXcgUkdCQUltYWdlKFxuICAgICAgICAgICAge3dpZHRoOiAxLCBoZWlnaHQ6IDF9LFxuICAgICAgICAgICAgbmV3IFVpbnQ4QXJyYXkoREVNRGF0YS5wYWNrKG1pbiwgKCh0aGlzLnNvdXJjZUNhY2hlLmdldFNvdXJjZSgpOiBhbnkpOiBSYXN0ZXJERU1UaWxlU291cmNlKS5lbmNvZGluZykpXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5fZW1wdHlERU1UZXh0dXJlRGlydHkgPSBmYWxzZTtcbiAgICAgICAgbGV0IHRleHR1cmUgPSB0aGlzLl9lbXB0eURFTVRleHR1cmU7XG4gICAgICAgIGlmICghdGV4dHVyZSkge1xuICAgICAgICAgICAgdGV4dHVyZSA9IHRoaXMuX2VtcHR5REVNVGV4dHVyZSA9IG5ldyBUZXh0dXJlKGNvbnRleHQsIGltYWdlLCBnbC5SR0JBLCB7cHJlbXVsdGlwbHk6IGZhbHNlfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0ZXh0dXJlLnVwZGF0ZShpbWFnZSwge3ByZW11bHRpcGx5OiBmYWxzZX0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0ZXh0dXJlO1xuICAgIH1cblxuICAgIC8vIHVzZURlcHRoRm9yT2NjbHVzaW9uOiBQcmUtcmVuZGVyZWQgZGVwdGggdG8gdGV4dHVyZSAodGhpcy5fZGVwdGhUZXh0dXJlKSBpc1xuICAgIC8vIHVzZWQgdG8gaGlkZSAoYWN0dWFsbHkgbW92ZXMgYWxsIG9iamVjdCdzIHZlcnRpY2VzIG91dCBvZiB2aWV3cG9ydCkuXG4gICAgLy8gdXNlTWV0ZXJUb0RlbTogdV9tZXRlcl90b19kZW0gdW5pZm9ybSBpcyBub3QgdXNlZCBmb3IgYWxsIHRlcnJhaW4gcHJvZ3JhbXMsXG4gICAgLy8gb3B0aW1pemF0aW9uIHRvIGF2b2lkIHVubmVjZXNzYXJ5IGNvbXB1dGF0aW9uIGFuZCB1cGxvYWQuXG4gICAgc2V0dXBFbGV2YXRpb25EcmF3KHRpbGU6IFRpbGUsIHByb2dyYW06IFByb2dyYW08Kj4sXG4gICAgICAgIG9wdGlvbnM/OiB7XG4gICAgICAgICAgICB1c2VEZXB0aEZvck9jY2x1c2lvbj86IGJvb2xlYW4sXG4gICAgICAgICAgICB1c2VNZXRlclRvRGVtPzogYm9vbGVhbixcbiAgICAgICAgICAgIGxhYmVsUGxhbmVNYXRyaXhJbnY/OiA/RmxvYXQzMkFycmF5LFxuICAgICAgICAgICAgbW9ycGhpbmc/OiB7IHNyY0RlbVRpbGU6IFRpbGUsIGRzdERlbVRpbGU6IFRpbGUsIHBoYXNlOiBudW1iZXIgfSxcbiAgICAgICAgICAgIHVzZURlbm9ybWFsaXplZFVwVmVjdG9yU2NhbGU/OiBib29sZWFuXG4gICAgICAgIH0pIHtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMucGFpbnRlci5jb250ZXh0O1xuICAgICAgICBjb25zdCBnbCA9IGNvbnRleHQuZ2w7XG4gICAgICAgIGNvbnN0IHVuaWZvcm1zID0gZGVmYXVsdFRlcnJhaW5Vbmlmb3JtcygoKHRoaXMuc291cmNlQ2FjaGUuZ2V0U291cmNlKCk6IGFueSk6IFJhc3RlckRFTVRpbGVTb3VyY2UpLmVuY29kaW5nKTtcbiAgICAgICAgdW5pZm9ybXNbJ3VfZGVtX3NpemUnXSA9IHRoaXMuc291cmNlQ2FjaGUuZ2V0U291cmNlKCkudGlsZVNpemU7XG4gICAgICAgIHVuaWZvcm1zWyd1X2V4YWdnZXJhdGlvbiddID0gdGhpcy5leGFnZ2VyYXRpb24oKTtcblxuICAgICAgICBsZXQgZGVtVGlsZSA9IG51bGw7XG4gICAgICAgIGxldCBwcmV2RGVtVGlsZSA9IG51bGw7XG4gICAgICAgIGxldCBtb3JwaGluZ1BoYXNlID0gMS4wO1xuXG4gICAgICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMubW9ycGhpbmcgJiYgdGhpcy5fdXNlVmVydGV4TW9ycGhpbmcpIHtcbiAgICAgICAgICAgIGNvbnN0IHNyY1RpbGUgPSBvcHRpb25zLm1vcnBoaW5nLnNyY0RlbVRpbGU7XG4gICAgICAgICAgICBjb25zdCBkc3RUaWxlID0gb3B0aW9ucy5tb3JwaGluZy5kc3REZW1UaWxlO1xuICAgICAgICAgICAgbW9ycGhpbmdQaGFzZSA9IG9wdGlvbnMubW9ycGhpbmcucGhhc2U7XG5cbiAgICAgICAgICAgIGlmIChzcmNUaWxlICYmIGRzdFRpbGUpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fcHJlcGFyZURlbVRpbGVVbmlmb3Jtcyh0aWxlLCBzcmNUaWxlLCB1bmlmb3JtcywgXCJfcHJldlwiKSlcbiAgICAgICAgICAgICAgICAgICAgcHJldkRlbVRpbGUgPSBzcmNUaWxlO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9wcmVwYXJlRGVtVGlsZVVuaWZvcm1zKHRpbGUsIGRzdFRpbGUsIHVuaWZvcm1zKSlcbiAgICAgICAgICAgICAgICAgICAgZGVtVGlsZSA9IGRzdFRpbGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocHJldkRlbVRpbGUgJiYgZGVtVGlsZSkge1xuICAgICAgICAgICAgLy8gQm90aCBERU0gdGV4dHVyZXMgYXJlIGV4cGVjdGVkIHRvIGJlIGNvcnJlY3RseSBzZXQgaWYgZ2VvbW9ycGhpbmcgaXMgZW5hYmxlZFxuICAgICAgICAgICAgY29udGV4dC5hY3RpdmVUZXh0dXJlLnNldChnbC5URVhUVVJFMik7XG4gICAgICAgICAgICAoZGVtVGlsZS5kZW1UZXh0dXJlOiBhbnkpLmJpbmQoZ2wuTkVBUkVTVCwgZ2wuQ0xBTVBfVE9fRURHRSwgZ2wuTkVBUkVTVCk7XG4gICAgICAgICAgICBjb250ZXh0LmFjdGl2ZVRleHR1cmUuc2V0KGdsLlRFWFRVUkU0KTtcbiAgICAgICAgICAgIChwcmV2RGVtVGlsZS5kZW1UZXh0dXJlOiBhbnkpLmJpbmQoZ2wuTkVBUkVTVCwgZ2wuQ0xBTVBfVE9fRURHRSwgZ2wuTkVBUkVTVCk7XG5cbiAgICAgICAgICAgIHVuaWZvcm1zW1widV9kZW1fbGVycFwiXSA9IG1vcnBoaW5nUGhhc2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkZW1UaWxlID0gdGhpcy50ZXJyYWluVGlsZUZvclRpbGVbdGlsZS50aWxlSUQua2V5XTtcbiAgICAgICAgICAgIGNvbnRleHQuYWN0aXZlVGV4dHVyZS5zZXQoZ2wuVEVYVFVSRTIpO1xuICAgICAgICAgICAgY29uc3QgZGVtVGV4dHVyZSA9IHRoaXMuX3ByZXBhcmVEZW1UaWxlVW5pZm9ybXModGlsZSwgZGVtVGlsZSwgdW5pZm9ybXMpID9cbiAgICAgICAgICAgICAgICAoZGVtVGlsZS5kZW1UZXh0dXJlOiBhbnkpIDogdGhpcy5lbXB0eURFTVRleHR1cmU7XG4gICAgICAgICAgICBkZW1UZXh0dXJlLmJpbmQoZ2wuTkVBUkVTVCwgZ2wuQ0xBTVBfVE9fRURHRSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb250ZXh0LmFjdGl2ZVRleHR1cmUuc2V0KGdsLlRFWFRVUkUzKTtcbiAgICAgICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy51c2VEZXB0aEZvck9jY2x1c2lvbikge1xuICAgICAgICAgICAgaWYgKHRoaXMuX2RlcHRoVGV4dHVyZSkgdGhpcy5fZGVwdGhUZXh0dXJlLmJpbmQoZ2wuTkVBUkVTVCwgZ2wuQ0xBTVBfVE9fRURHRSk7XG4gICAgICAgICAgICBpZiAodGhpcy5fZGVwdGhGQk8pIHVuaWZvcm1zWyd1X2RlcHRoX3NpemVfaW52J10gPSBbMSAvIHRoaXMuX2RlcHRoRkJPLndpZHRoLCAxIC8gdGhpcy5fZGVwdGhGQk8uaGVpZ2h0XTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZW1wdHlEZXB0aEJ1ZmZlclRleHR1cmUuYmluZChnbC5ORUFSRVNULCBnbC5DTEFNUF9UT19FREdFKTtcbiAgICAgICAgICAgIHVuaWZvcm1zWyd1X2RlcHRoX3NpemVfaW52J10gPSBbMSwgMV07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLnVzZU1ldGVyVG9EZW0gJiYgZGVtVGlsZSkge1xuICAgICAgICAgICAgY29uc3QgbWV0ZXJUb0RFTSA9ICgxIDw8IGRlbVRpbGUudGlsZUlELmNhbm9uaWNhbC56KSAqIG1lcmNhdG9yWmZyb21BbHRpdHVkZSgxLCB0aGlzLnBhaW50ZXIudHJhbnNmb3JtLmNlbnRlci5sYXQpICogdGhpcy5zb3VyY2VDYWNoZS5nZXRTb3VyY2UoKS50aWxlU2l6ZTtcbiAgICAgICAgICAgIHVuaWZvcm1zWyd1X21ldGVyX3RvX2RlbSddID0gbWV0ZXJUb0RFTTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLmxhYmVsUGxhbmVNYXRyaXhJbnYpIHtcbiAgICAgICAgICAgIHVuaWZvcm1zWyd1X2xhYmVsX3BsYW5lX21hdHJpeF9pbnYnXSA9IG9wdGlvbnMubGFiZWxQbGFuZU1hdHJpeEludjtcbiAgICAgICAgfVxuICAgICAgICBwcm9ncmFtLnNldFRlcnJhaW5Vbmlmb3JtVmFsdWVzKGNvbnRleHQsIHVuaWZvcm1zKTtcblxuICAgICAgICBpZiAodGhpcy5wYWludGVyLnRyYW5zZm9ybS5wcm9qZWN0aW9uLm5hbWUgPT09ICdnbG9iZScpIHtcbiAgICAgICAgICAgIGNvbnN0IGdsb2JlVW5pZm9ybXMgPSB0aGlzLmdsb2JlVW5pZm9ybVZhbHVlcyh0aGlzLnBhaW50ZXIudHJhbnNmb3JtLCB0aWxlLnRpbGVJRC5jYW5vbmljYWwsIG9wdGlvbnMgJiYgb3B0aW9ucy51c2VEZW5vcm1hbGl6ZWRVcFZlY3RvclNjYWxlKTtcbiAgICAgICAgICAgIHByb2dyYW0uc2V0R2xvYmVVbmlmb3JtVmFsdWVzKGNvbnRleHQsIGdsb2JlVW5pZm9ybXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2xvYmVVbmlmb3JtVmFsdWVzKHRyOiBUcmFuc2Zvcm0sIGlkOiBDYW5vbmljYWxUaWxlSUQsIHVzZURlbm9ybWFsaXplZFVwVmVjdG9yU2NhbGU6ID9ib29sZWFuKTogVW5pZm9ybVZhbHVlczxHbG9iZVVuaWZvcm1zVHlwZT4ge1xuICAgICAgICBjb25zdCBwcm9qZWN0aW9uID0gdHIucHJvamVjdGlvbjtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICd1X3RpbGVfdGxfdXAnOiAocHJvamVjdGlvbi51cFZlY3RvcihpZCwgMCwgMCk6IGFueSksXG4gICAgICAgICAgICAndV90aWxlX3RyX3VwJzogKHByb2plY3Rpb24udXBWZWN0b3IoaWQsIEVYVEVOVCwgMCk6IGFueSksXG4gICAgICAgICAgICAndV90aWxlX2JyX3VwJzogKHByb2plY3Rpb24udXBWZWN0b3IoaWQsIEVYVEVOVCwgRVhURU5UKTogYW55KSxcbiAgICAgICAgICAgICd1X3RpbGVfYmxfdXAnOiAocHJvamVjdGlvbi51cFZlY3RvcihpZCwgMCwgRVhURU5UKTogYW55KSxcbiAgICAgICAgICAgICd1X3RpbGVfdXBfc2NhbGUnOiAodXNlRGVub3JtYWxpemVkVXBWZWN0b3JTY2FsZSA/IGdsb2JlTWV0ZXJzVG9FY2VmKDEpIDogcHJvamVjdGlvbi51cFZlY3RvclNjYWxlKGlkLCB0ci5jZW50ZXIubGF0LCB0ci53b3JsZFNpemUpLm1ldGVyc1RvVGlsZTogYW55KVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHJlbmRlclRvQmFja0J1ZmZlcihhY2N1bXVsYXRlZERyYXBlczogQXJyYXk8T3ZlcnNjYWxlZFRpbGVJRD4pIHtcbiAgICAgICAgY29uc3QgcGFpbnRlciA9IHRoaXMucGFpbnRlcjtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMucGFpbnRlci5jb250ZXh0O1xuXG4gICAgICAgIGlmIChhY2N1bXVsYXRlZERyYXBlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRleHQuYmluZEZyYW1lYnVmZmVyLnNldChudWxsKTtcbiAgICAgICAgY29udGV4dC52aWV3cG9ydC5zZXQoWzAsIDAsIHBhaW50ZXIud2lkdGgsIHBhaW50ZXIuaGVpZ2h0XSk7XG5cbiAgICAgICAgcGFpbnRlci5ncHVUaW1pbmdEZWZlcnJlZFJlbmRlclN0YXJ0KCk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJpbmdUb1RleHR1cmUgPSBmYWxzZTtcbiAgICAgICAgZHJhd1RlcnJhaW5SYXN0ZXIocGFpbnRlciwgdGhpcywgdGhpcy5wcm94eVNvdXJjZUNhY2hlLCBhY2N1bXVsYXRlZERyYXBlcywgdGhpcy5fdXBkYXRlVGltZXN0YW1wKTtcbiAgICAgICAgdGhpcy5yZW5kZXJpbmdUb1RleHR1cmUgPSB0cnVlO1xuXG4gICAgICAgIHBhaW50ZXIuZ3B1VGltaW5nRGVmZXJyZWRSZW5kZXJFbmQoKTtcblxuICAgICAgICBhY2N1bXVsYXRlZERyYXBlcy5zcGxpY2UoMCwgYWNjdW11bGF0ZWREcmFwZXMubGVuZ3RoKTtcbiAgICB9XG5cbiAgICAvLyBGb3IgZWFjaCBwcm94eSB0aWxlLCByZW5kZXIgYWxsIGxheWVycyB1bnRpbCB0aGUgbm9uLWRyYXBlZCBsYXllciAoYW5kXG4gICAgLy8gcmVuZGVyIHRoZSB0aWxlIHRvIHRoZSBzY3JlZW4pIGJlZm9yZSBhZHZhbmNpbmcgdG8gdGhlIG5leHQgcHJveHkgdGlsZS5cbiAgICAvLyBSZXR1cm5zIHRoZSBsYXN0IGRyYXduIGluZGV4IHRoYXQgaXMgdXNlZCBhcyBhIHN0YXJ0XG4gICAgLy8gbGF5ZXIgZm9yIGludGVybGVhdmVkIGRyYXBlZCByZW5kZXJpbmcuXG4gICAgLy8gQXBhcnQgdG8gbGF5ZXItYnktbGF5ZXIgcmVuZGVyaW5nIHVzZWQgaW4gMkQsIGhlcmUgd2UgaGF2ZSBwcm94eS10aWxlLWJ5LXByb3h5LXRpbGVcbiAgICAvLyByZW5kZXJpbmcuXG4gICAgcmVuZGVyQmF0Y2goc3RhcnRMYXllckluZGV4OiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBpZiAodGhpcy5fZHJhcGVkUmVuZGVyQmF0Y2hlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBzdGFydExheWVySW5kZXggKyAxO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5yZW5kZXJpbmdUb1RleHR1cmUgPSB0cnVlO1xuICAgICAgICBjb25zdCBwYWludGVyID0gdGhpcy5wYWludGVyO1xuICAgICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5wYWludGVyLmNvbnRleHQ7XG4gICAgICAgIGNvbnN0IHBzYyA9IHRoaXMucHJveHlTb3VyY2VDYWNoZTtcbiAgICAgICAgY29uc3QgcHJveGllcyA9IHRoaXMucHJveGllZENvb3Jkc1twc2MuaWRdO1xuXG4gICAgICAgIC8vIENvbnN1bWUgYmF0Y2ggb2Ygc2VxdWVudGlhbCBkcmFwZSBsYXllcnMgYW5kIG1vdmUgbmV4dFxuICAgICAgICBjb25zdCBkcmFwZWRMYXllckJhdGNoID0gdGhpcy5fZHJhcGVkUmVuZGVyQmF0Y2hlcy5zaGlmdCgpO1xuICAgICAgICBhc3NlcnQoZHJhcGVkTGF5ZXJCYXRjaC5zdGFydCA9PT0gc3RhcnRMYXllckluZGV4KTtcblxuICAgICAgICBjb25zdCBhY2N1bXVsYXRlZERyYXBlcyA9IFtdO1xuICAgICAgICBjb25zdCBsYXllcklkcyA9IHBhaW50ZXIuc3R5bGUub3JkZXI7XG5cbiAgICAgICAgbGV0IHBvb2xJbmRleCA9IDA7XG4gICAgICAgIGZvciAoY29uc3QgcHJveHkgb2YgcHJveGllcykge1xuICAgICAgICAgICAgLy8gYmluZCBmcmFtZWJ1ZmZlciBhbmQgYXNzaWduIHRleHR1cmUgdG8gdGhlIHRpbGUgKHRleHR1cmUgdXNlZCBpbiBkcmF3VGVycmFpblJhc3RlcikuXG4gICAgICAgICAgICBjb25zdCB0aWxlID0gcHNjLmdldFRpbGVCeUlEKHByb3h5LnByb3h5VGlsZUtleSk7XG4gICAgICAgICAgICBjb25zdCByZW5kZXJDYWNoZUluZGV4ID0gcHNjLnByb3h5Q2FjaGVkRkJPW3Byb3h5LmtleV0gPyBwc2MucHJveHlDYWNoZWRGQk9bcHJveHkua2V5XVtzdGFydExheWVySW5kZXhdIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgY29uc3QgZmJvID0gcmVuZGVyQ2FjaGVJbmRleCAhPT0gdW5kZWZpbmVkID8gcHNjLnJlbmRlckNhY2hlW3JlbmRlckNhY2hlSW5kZXhdIDogdGhpcy5wb29sW3Bvb2xJbmRleCsrXTtcbiAgICAgICAgICAgIGNvbnN0IHVzZVJlbmRlckNhY2hlID0gcmVuZGVyQ2FjaGVJbmRleCAhPT0gdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICB0aWxlLnRleHR1cmUgPSBmYm8udGV4O1xuXG4gICAgICAgICAgICBpZiAodXNlUmVuZGVyQ2FjaGUgJiYgIWZiby5kaXJ0eSkge1xuICAgICAgICAgICAgICAgIC8vIFVzZSBjYWNoZWQgcmVuZGVyIGZyb20gcHJldmlvdXMgcGFzcywgbm8gbmVlZCB0byByZW5kZXIgYWdhaW4uXG4gICAgICAgICAgICAgICAgYWNjdW11bGF0ZWREcmFwZXMucHVzaCh0aWxlLnRpbGVJRCk7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnRleHQuYmluZEZyYW1lYnVmZmVyLnNldChmYm8uZmIuZnJhbWVidWZmZXIpO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJlZFRvVGlsZSA9IGZhbHNlOyAvLyByZXNldCBmbGFnLlxuICAgICAgICAgICAgaWYgKGZiby5kaXJ0eSkge1xuICAgICAgICAgICAgICAgIC8vIENsZWFyIG9uIHN0YXJ0LlxuICAgICAgICAgICAgICAgIGNvbnRleHQuY2xlYXIoe2NvbG9yOiBDb2xvci50cmFuc3BhcmVudCwgc3RlbmNpbDogMH0pO1xuICAgICAgICAgICAgICAgIGZiby5kaXJ0eSA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgY3VycmVudFN0ZW5jaWxTb3VyY2U7IC8vIFRoZXJlIGlzIG5vIG5lZWQgdG8gc2V0dXAgc3RlbmNpbCBmb3IgdGhlIHNhbWUgc291cmNlIGZvciBjb25zZWN1dGl2ZSBsYXllcnMuXG4gICAgICAgICAgICBmb3IgKGxldCBqID0gZHJhcGVkTGF5ZXJCYXRjaC5zdGFydDsgaiA8PSBkcmFwZWRMYXllckJhdGNoLmVuZDsgKytqKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbGF5ZXIgPSBwYWludGVyLnN0eWxlLl9sYXllcnNbbGF5ZXJJZHNbal1dO1xuICAgICAgICAgICAgICAgIGNvbnN0IGhpZGRlbiA9IGxheWVyLmlzSGlkZGVuKHBhaW50ZXIudHJhbnNmb3JtLnpvb20pO1xuICAgICAgICAgICAgICAgIGFzc2VydCh0aGlzLl9zdHlsZS5pc0xheWVyRHJhcGVkKGxheWVyKSB8fCBoaWRkZW4pO1xuICAgICAgICAgICAgICAgIGlmIChoaWRkZW4pIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICAgICAgY29uc3Qgc291cmNlQ2FjaGUgPSBwYWludGVyLnN0eWxlLl9nZXRMYXllclNvdXJjZUNhY2hlKGxheWVyKTtcbiAgICAgICAgICAgICAgICBjb25zdCBwcm94aWVkQ29vcmRzID0gc291cmNlQ2FjaGUgPyB0aGlzLnByb3h5VG9Tb3VyY2VbcHJveHkua2V5XVtzb3VyY2VDYWNoZS5pZF0gOiBbcHJveHldO1xuICAgICAgICAgICAgICAgIGlmICghcHJveGllZENvb3JkcykgY29udGludWU7IC8vIHdoZW4gdGlsZSBpcyBub3QgbG9hZGVkIHlldCBmb3IgdGhlIHNvdXJjZSBjYWNoZS5cblxuICAgICAgICAgICAgICAgIGNvbnN0IGNvb3JkcyA9ICgocHJveGllZENvb3JkczogYW55KTogQXJyYXk8T3ZlcnNjYWxlZFRpbGVJRD4pO1xuICAgICAgICAgICAgICAgIGNvbnRleHQudmlld3BvcnQuc2V0KFswLCAwLCBmYm8uZmIud2lkdGgsIGZiby5mYi5oZWlnaHRdKTtcbiAgICAgICAgICAgICAgICBpZiAoY3VycmVudFN0ZW5jaWxTb3VyY2UgIT09IChzb3VyY2VDYWNoZSA/IHNvdXJjZUNhY2hlLmlkIDogbnVsbCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2V0dXBTdGVuY2lsKGZibywgcHJveGllZENvb3JkcywgbGF5ZXIsIHNvdXJjZUNhY2hlKTtcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudFN0ZW5jaWxTb3VyY2UgPSBzb3VyY2VDYWNoZSA/IHNvdXJjZUNhY2hlLmlkIDogbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcGFpbnRlci5yZW5kZXJMYXllcihwYWludGVyLCBzb3VyY2VDYWNoZSwgbGF5ZXIsIGNvb3Jkcyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnJlbmRlcmVkVG9UaWxlKSB7XG4gICAgICAgICAgICAgICAgZmJvLmRpcnR5ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBhY2N1bXVsYXRlZERyYXBlcy5wdXNoKHRpbGUudGlsZUlEKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIXVzZVJlbmRlckNhY2hlKSB7XG4gICAgICAgICAgICAgICAgLS1wb29sSW5kZXg7XG4gICAgICAgICAgICAgICAgYXNzZXJ0KHBvb2xJbmRleCA+PSAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwb29sSW5kZXggPT09IEZCT19QT09MX1NJWkUpIHtcbiAgICAgICAgICAgICAgICBwb29sSW5kZXggPSAwO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyVG9CYWNrQnVmZmVyKGFjY3VtdWxhdGVkRHJhcGVzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJlc2V0IHN0YXRlcyBhbmQgcmVuZGVyIGxhc3QgZHJhcGVzXG4gICAgICAgIHRoaXMucmVuZGVyVG9CYWNrQnVmZmVyKGFjY3VtdWxhdGVkRHJhcGVzKTtcbiAgICAgICAgdGhpcy5yZW5kZXJpbmdUb1RleHR1cmUgPSBmYWxzZTtcblxuICAgICAgICBjb250ZXh0LmJpbmRGcmFtZWJ1ZmZlci5zZXQobnVsbCk7XG4gICAgICAgIGNvbnRleHQudmlld3BvcnQuc2V0KFswLCAwLCBwYWludGVyLndpZHRoLCBwYWludGVyLmhlaWdodF0pO1xuXG4gICAgICAgIHJldHVybiBkcmFwZWRMYXllckJhdGNoLmVuZCArIDE7XG4gICAgfVxuXG4gICAgcG9zdFJlbmRlcigpIHtcbiAgICAgICAgLy8gTWFrZSBzdXJlIHdlIGNvbnN1bWVkIGFsbCB0aGUgZHJhcGVkIHRlcnJhaW4gYmF0Y2hlcyBhdCB0aGlzIHBvaW50XG4gICAgICAgIGFzc2VydCh0aGlzLl9kcmFwZWRSZW5kZXJCYXRjaGVzLmxlbmd0aCA9PT0gMCk7XG4gICAgfVxuXG4gICAgcmVuZGVyQ2FjaGVFZmZpY2llbmN5KHN0eWxlOiBTdHlsZSk6IE9iamVjdCB7XG4gICAgICAgIGNvbnN0IGxheWVyQ291bnQgPSBzdHlsZS5vcmRlci5sZW5ndGg7XG5cbiAgICAgICAgaWYgKGxheWVyQ291bnQgPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiB7ZWZmaWNpZW5jeTogMTAwLjB9O1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHVuY2FjaGVhYmxlTGF5ZXJDb3VudCA9IDA7XG4gICAgICAgIGxldCBkcmFwZWRMYXllckNvdW50ID0gMDtcbiAgICAgICAgbGV0IHJlYWNoZWRVbmRyYXBlZExheWVyID0gZmFsc2U7XG4gICAgICAgIGxldCBmaXJzdFVuZHJhcGVkTGF5ZXI7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsYXllckNvdW50OyArK2kpIHtcbiAgICAgICAgICAgIGNvbnN0IGxheWVyID0gc3R5bGUuX2xheWVyc1tzdHlsZS5vcmRlcltpXV07XG4gICAgICAgICAgICBpZiAoIXRoaXMuX3N0eWxlLmlzTGF5ZXJEcmFwZWQobGF5ZXIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFyZWFjaGVkVW5kcmFwZWRMYXllcikge1xuICAgICAgICAgICAgICAgICAgICByZWFjaGVkVW5kcmFwZWRMYXllciA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGZpcnN0VW5kcmFwZWRMYXllciA9IGxheWVyLmlkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKHJlYWNoZWRVbmRyYXBlZExheWVyKSB7XG4gICAgICAgICAgICAgICAgICAgICsrdW5jYWNoZWFibGVMYXllckNvdW50O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICArK2RyYXBlZExheWVyQ291bnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZHJhcGVkTGF5ZXJDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHtlZmZpY2llbmN5OiAxMDAuMH07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge2VmZmljaWVuY3k6ICgxLjAgLSB1bmNhY2hlYWJsZUxheWVyQ291bnQgLyBkcmFwZWRMYXllckNvdW50KSAqIDEwMC4wLCBmaXJzdFVuZHJhcGVkTGF5ZXJ9O1xuICAgIH1cblxuICAgIGdldE1pbkVsZXZhdGlvbkJlbG93TVNMKCk6IG51bWJlciB7XG4gICAgICAgIGxldCBtaW4gPSAwLjA7XG4gICAgICAgIC8vIFRoZSBtYXhpbXVtIERFTSBlcnJvciBpbiBtZXRlcnMgdG8gYmUgY29uc2VydmF0aXZlIChTUlRNKS5cbiAgICAgICAgY29uc3QgbWF4REVNRXJyb3IgPSAzMC4wO1xuICAgICAgICB0aGlzLl92aXNpYmxlRGVtVGlsZXMuZmlsdGVyKHRpbGUgPT4gdGlsZS5kZW0pLmZvckVhY2godGlsZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBtaW5NYXhUcmVlID0gKHRpbGUuZGVtOiBhbnkpLnRyZWU7XG4gICAgICAgICAgICBtaW4gPSBNYXRoLm1pbihtaW4sIG1pbk1heFRyZWUubWluaW11bXNbMF0pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG1pbiA9PT0gMC4wID8gbWluIDogKG1pbiAtIG1heERFTUVycm9yKSAqIHRoaXMuX2V4YWdnZXJhdGlvbjtcbiAgICB9XG5cbiAgICAvLyBQZXJmb3JtcyByYXljYXN0IGFnYWluc3QgdmlzaWJsZSBERU0gdGlsZXMgb24gdGhlIHNjcmVlbiBhbmQgcmV0dXJucyB0aGUgZGlzdGFuY2UgdHJhdmVsbGVkIGFsb25nIHRoZSByYXkuXG4gICAgLy8geCAmIHkgY29tcG9uZW50cyBvZiB0aGUgcG9zaXRpb24gYXJlIGV4cGVjdGVkIHRvIGJlIGluIG5vcm1hbGl6ZWQgbWVyY2F0b3IgY29vcmRpbmF0ZXMgWzAsIDFdIGFuZCB6IGluIG1ldGVycy5cbiAgICByYXljYXN0KHBvczogVmVjMywgZGlyOiBWZWMzLCBleGFnZ2VyYXRpb246IG51bWJlcik6ID9udW1iZXIge1xuICAgICAgICBpZiAoIXRoaXMuX3Zpc2libGVEZW1UaWxlcylcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgICAgIC8vIFBlcmZvcm0gaW5pdGlhbCByYXljYXN0cyBhZ2FpbnN0IHJvb3Qgbm9kZXMgb2YgdGhlIGF2YWlsYWJsZSBkZW0gdGlsZXNcbiAgICAgICAgLy8gYW5kIHVzZSB0aGlzIGluZm9ybWF0aW9uIHRvIHNvcnQgdGhlbSBmcm9tIGNsb3Nlc3QgdG8gZnVydGhlc3QuXG4gICAgICAgIGNvbnN0IHByZXBhcmVkVGlsZXMgPSB0aGlzLl92aXNpYmxlRGVtVGlsZXMuZmlsdGVyKHRpbGUgPT4gdGlsZS5kZW0pLm1hcCh0aWxlID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGlkID0gdGlsZS50aWxlSUQ7XG4gICAgICAgICAgICBjb25zdCB0aWxlcyA9IDEgPDwgaWQub3ZlcnNjYWxlZFo7XG4gICAgICAgICAgICBjb25zdCB7eCwgeX0gPSBpZC5jYW5vbmljYWw7XG5cbiAgICAgICAgICAgIC8vIENvbXB1dGUgdGlsZSBib3VuZGFyaWVzIGluIG1lcmNhdG9yIGNvb3JkaW5hdGVzXG4gICAgICAgICAgICBjb25zdCBtaW54ID0geCAvIHRpbGVzO1xuICAgICAgICAgICAgY29uc3QgbWF4eCA9ICh4ICsgMSkgLyB0aWxlcztcbiAgICAgICAgICAgIGNvbnN0IG1pbnkgPSB5IC8gdGlsZXM7XG4gICAgICAgICAgICBjb25zdCBtYXh5ID0gKHkgKyAxKSAvIHRpbGVzO1xuICAgICAgICAgICAgY29uc3QgdHJlZSA9ICh0aWxlLmRlbTogYW55KS50cmVlO1xuXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIG1pbngsIG1pbnksIG1heHgsIG1heHksXG4gICAgICAgICAgICAgICAgdDogdHJlZS5yYXljYXN0Um9vdChtaW54LCBtaW55LCBtYXh4LCBtYXh5LCBwb3MsIGRpciwgZXhhZ2dlcmF0aW9uKSxcbiAgICAgICAgICAgICAgICB0aWxlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcblxuICAgICAgICBwcmVwYXJlZFRpbGVzLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGF0ID0gYS50ICE9PSBudWxsID8gYS50IDogTnVtYmVyLk1BWF9WQUxVRTtcbiAgICAgICAgICAgIGNvbnN0IGJ0ID0gYi50ICE9PSBudWxsID8gYi50IDogTnVtYmVyLk1BWF9WQUxVRTtcbiAgICAgICAgICAgIHJldHVybiBhdCAtIGJ0O1xuICAgICAgICB9KTtcblxuICAgICAgICBmb3IgKGNvbnN0IG9iaiBvZiBwcmVwYXJlZFRpbGVzKSB7XG4gICAgICAgICAgICBpZiAob2JqLnQgPT0gbnVsbClcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcblxuICAgICAgICAgICAgLy8gUGVyZm9ybSBtb3JlIGFjY3VyYXRlIHJheWNhc3QgYWdhaW5zdCB0aGUgZGVtIHRyZWUuIEZpcnN0IGludGVyc2VjdGlvbiBpcyB0aGUgY2xvc2VzdCBvblxuICAgICAgICAgICAgLy8gYXMgYWxsIHRpbGVzIGFyZSBzb3J0ZWQgZnJvbSBjbG9zZXN0IHRvIGZ1cnRoZXN0XG4gICAgICAgICAgICBjb25zdCB0cmVlID0gKG9iai50aWxlLmRlbTogYW55KS50cmVlO1xuICAgICAgICAgICAgY29uc3QgdCA9IHRyZWUucmF5Y2FzdChvYmoubWlueCwgb2JqLm1pbnksIG9iai5tYXh4LCBvYmoubWF4eSwgcG9zLCBkaXIsIGV4YWdnZXJhdGlvbik7XG5cbiAgICAgICAgICAgIGlmICh0ICE9IG51bGwpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBfY3JlYXRlRkJPKCk6IEZCTyB7XG4gICAgICAgIGNvbnN0IHBhaW50ZXIgPSB0aGlzLnBhaW50ZXI7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBwYWludGVyLmNvbnRleHQ7XG4gICAgICAgIGNvbnN0IGdsID0gY29udGV4dC5nbDtcbiAgICAgICAgY29uc3QgYnVmZmVyU2l6ZSA9IHRoaXMuZHJhcGVCdWZmZXJTaXplO1xuICAgICAgICBjb250ZXh0LmFjdGl2ZVRleHR1cmUuc2V0KGdsLlRFWFRVUkUwKTtcbiAgICAgICAgY29uc3QgdGV4ID0gbmV3IFRleHR1cmUoY29udGV4dCwge3dpZHRoOiBidWZmZXJTaXplWzBdLCBoZWlnaHQ6IGJ1ZmZlclNpemVbMV0sIGRhdGE6IG51bGx9LCBnbC5SR0JBKTtcbiAgICAgICAgdGV4LmJpbmQoZ2wuTElORUFSLCBnbC5DTEFNUF9UT19FREdFKTtcbiAgICAgICAgY29uc3QgZmIgPSBjb250ZXh0LmNyZWF0ZUZyYW1lYnVmZmVyKGJ1ZmZlclNpemVbMF0sIGJ1ZmZlclNpemVbMV0sIGZhbHNlKTtcbiAgICAgICAgZmIuY29sb3JBdHRhY2htZW50LnNldCh0ZXgudGV4dHVyZSk7XG4gICAgICAgIGZiLmRlcHRoQXR0YWNobWVudCA9IG5ldyBEZXB0aFN0ZW5jaWxBdHRhY2htZW50KGNvbnRleHQsIGZiLmZyYW1lYnVmZmVyKTtcblxuICAgICAgICBpZiAodGhpcy5fc2hhcmVkRGVwdGhTdGVuY2lsID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3NoYXJlZERlcHRoU3RlbmNpbCA9IGNvbnRleHQuY3JlYXRlUmVuZGVyYnVmZmVyKGNvbnRleHQuZ2wuREVQVEhfU1RFTkNJTCwgYnVmZmVyU2l6ZVswXSwgYnVmZmVyU2l6ZVsxXSk7XG4gICAgICAgICAgICB0aGlzLl9zdGVuY2lsUmVmID0gMDtcbiAgICAgICAgICAgIGZiLmRlcHRoQXR0YWNobWVudC5zZXQodGhpcy5fc2hhcmVkRGVwdGhTdGVuY2lsKTtcbiAgICAgICAgICAgIGNvbnRleHQuY2xlYXIoe3N0ZW5jaWw6IDB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZiLmRlcHRoQXR0YWNobWVudC5zZXQodGhpcy5fc2hhcmVkRGVwdGhTdGVuY2lsKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb250ZXh0LmV4dFRleHR1cmVGaWx0ZXJBbmlzb3Ryb3BpYyAmJiAhY29udGV4dC5leHRUZXh0dXJlRmlsdGVyQW5pc290cm9waWNGb3JjZU9mZikge1xuICAgICAgICAgICAgZ2wudGV4UGFyYW1ldGVyZihnbC5URVhUVVJFXzJELFxuICAgICAgICAgICAgICAgIGNvbnRleHQuZXh0VGV4dHVyZUZpbHRlckFuaXNvdHJvcGljLlRFWFRVUkVfTUFYX0FOSVNPVFJPUFlfRVhULFxuICAgICAgICAgICAgICAgIGNvbnRleHQuZXh0VGV4dHVyZUZpbHRlckFuaXNvdHJvcGljTWF4KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7ZmIsIHRleCwgZGlydHk6IGZhbHNlfTtcbiAgICB9XG5cbiAgICBfaW5pdEZCT1Bvb2woKSB7XG4gICAgICAgIHdoaWxlICh0aGlzLnBvb2wubGVuZ3RoIDwgTWF0aC5taW4oRkJPX1BPT0xfU0laRSwgdGhpcy5wcm94eUNvb3Jkcy5sZW5ndGgpKSB7XG4gICAgICAgICAgICB0aGlzLnBvb2wucHVzaCh0aGlzLl9jcmVhdGVGQk8oKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfc2hvdWxkRGlzYWJsZVJlbmRlckNhY2hlKCk6IGJvb2xlYW4ge1xuICAgICAgICAvLyBEaXNhYmxlIHJlbmRlciBjYWNoZXMgb24gZHluYW1pYyBldmVudHMgZHVlIHRvIGZhZGluZyBvciB0cmFuc2l0aW9uaW5nLlxuICAgICAgICBpZiAodGhpcy5fc3R5bGUubGlnaHQgJiYgdGhpcy5fc3R5bGUubGlnaHQuaGFzVHJhbnNpdGlvbigpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoY29uc3QgaWQgaW4gdGhpcy5fc3R5bGUuX3NvdXJjZUNhY2hlcykge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3N0eWxlLl9zb3VyY2VDYWNoZXNbaWRdLmhhc1RyYW5zaXRpb24oKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaXNUcmFuc2l0aW9uaW5nID0gKGlkOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGxheWVyID0gdGhpcy5fc3R5bGUuX2xheWVyc1tpZF07XG4gICAgICAgICAgICBjb25zdCBpc0hpZGRlbiA9IGxheWVyLmlzSGlkZGVuKHRoaXMucGFpbnRlci50cmFuc2Zvcm0uem9vbSk7XG4gICAgICAgICAgICBpZiAobGF5ZXIudHlwZSA9PT0gJ2N1c3RvbScpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gIWlzSGlkZGVuICYmICgobGF5ZXI6IGFueSk6IEN1c3RvbVN0eWxlTGF5ZXIpLnNob3VsZFJlZHJhcGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAhaXNIaWRkZW4gJiYgbGF5ZXIuaGFzVHJhbnNpdGlvbigpO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gdGhpcy5fc3R5bGUub3JkZXIuc29tZShpc1RyYW5zaXRpb25pbmcpO1xuICAgIH1cblxuICAgIF9jbGVhckxpbmVMYXllcnNGcm9tUmVuZGVyQ2FjaGUoKSB7XG4gICAgICAgIGxldCBoYXNWZWN0b3JTb3VyY2UgPSBmYWxzZTtcbiAgICAgICAgZm9yIChjb25zdCBzb3VyY2Ugb2YgdGhpcy5fc3R5bGUuX2dldFNvdXJjZXMoKSkge1xuICAgICAgICAgICAgaWYgKHNvdXJjZSBpbnN0YW5jZW9mIFZlY3RvclRpbGVTb3VyY2UpIHtcbiAgICAgICAgICAgICAgICBoYXNWZWN0b3JTb3VyY2UgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFoYXNWZWN0b3JTb3VyY2UpIHJldHVybjtcblxuICAgICAgICBjb25zdCBjbGVhclNvdXJjZUNhY2hlcyA9IHt9O1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX3N0eWxlLm9yZGVyLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBjb25zdCBsYXllciA9IHRoaXMuX3N0eWxlLl9sYXllcnNbdGhpcy5fc3R5bGUub3JkZXJbaV1dO1xuICAgICAgICAgICAgY29uc3Qgc291cmNlQ2FjaGUgPSB0aGlzLl9zdHlsZS5fZ2V0TGF5ZXJTb3VyY2VDYWNoZShsYXllcik7XG4gICAgICAgICAgICBpZiAoIXNvdXJjZUNhY2hlIHx8IGNsZWFyU291cmNlQ2FjaGVzW3NvdXJjZUNhY2hlLmlkXSkgY29udGludWU7XG5cbiAgICAgICAgICAgIGNvbnN0IGlzSGlkZGVuID0gbGF5ZXIuaXNIaWRkZW4odGhpcy5wYWludGVyLnRyYW5zZm9ybS56b29tKTtcbiAgICAgICAgICAgIGlmIChpc0hpZGRlbiB8fCBsYXllci50eXBlICE9PSAnbGluZScpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICAvLyBDaGVjayBpZiBsYXllciBoYXMgYSB6b29tIGRlcGVuZGVudCBcImxpbmUtd2lkdGhcIiBleHByZXNzaW9uXG4gICAgICAgICAgICBjb25zdCB3aWR0aEV4cHJlc3Npb24gPSAoKGxheWVyOiBhbnkpOiBMaW5lU3R5bGVMYXllcikud2lkdGhFeHByZXNzaW9uKCk7XG4gICAgICAgICAgICBpZiAoISh3aWR0aEV4cHJlc3Npb24gaW5zdGFuY2VvZiBab29tRGVwZW5kZW50RXhwcmVzc2lvbikpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICAvLyBNYXJrIHNvdXJjZUNhY2hlIGFzIGNsZWFyZWRcbiAgICAgICAgICAgIGNsZWFyU291cmNlQ2FjaGVzW3NvdXJjZUNhY2hlLmlkXSA9IHRydWU7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHByb3h5IG9mIHRoaXMucHJveHlDb29yZHMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwcm94aWVkQ29vcmRzID0gdGhpcy5wcm94eVRvU291cmNlW3Byb3h5LmtleV1bc291cmNlQ2FjaGUuaWRdO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvb3JkcyA9ICgocHJveGllZENvb3JkczogYW55KTogQXJyYXk8T3ZlcnNjYWxlZFRpbGVJRD4pO1xuICAgICAgICAgICAgICAgIGlmICghY29vcmRzKSBjb250aW51ZTtcblxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgY29vcmQgb2YgY29vcmRzKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2NsZWFyUmVuZGVyQ2FjaGVGb3JUaWxlKHNvdXJjZUNhY2hlLmlkLCBjb29yZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgX2NsZWFyUmFzdGVyTGF5ZXJzRnJvbVJlbmRlckNhY2hlKCkge1xuICAgICAgICBsZXQgaGFzUmFzdGVyU291cmNlID0gZmFsc2U7XG4gICAgICAgIGZvciAoY29uc3QgaWQgaW4gdGhpcy5fc3R5bGUuX3NvdXJjZUNhY2hlcykge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3N0eWxlLl9zb3VyY2VDYWNoZXNbaWRdLl9zb3VyY2UgaW5zdGFuY2VvZiBSYXN0ZXJUaWxlU291cmNlKSB7XG4gICAgICAgICAgICAgICAgaGFzUmFzdGVyU291cmNlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaGFzUmFzdGVyU291cmNlKSByZXR1cm47XG5cbiAgICAgICAgY29uc3QgY2xlYXJTb3VyY2VDYWNoZXMgPSB7fTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9zdHlsZS5vcmRlci5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgY29uc3QgbGF5ZXIgPSB0aGlzLl9zdHlsZS5fbGF5ZXJzW3RoaXMuX3N0eWxlLm9yZGVyW2ldXTtcbiAgICAgICAgICAgIGNvbnN0IHNvdXJjZUNhY2hlID0gdGhpcy5fc3R5bGUuX2dldExheWVyU291cmNlQ2FjaGUobGF5ZXIpO1xuICAgICAgICAgICAgaWYgKCFzb3VyY2VDYWNoZSB8fCBjbGVhclNvdXJjZUNhY2hlc1tzb3VyY2VDYWNoZS5pZF0pIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICBjb25zdCBpc0hpZGRlbiA9IGxheWVyLmlzSGlkZGVuKHRoaXMucGFpbnRlci50cmFuc2Zvcm0uem9vbSk7XG4gICAgICAgICAgICBpZiAoaXNIaWRkZW4gfHwgbGF5ZXIudHlwZSAhPT0gJ3Jhc3RlcicpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICAvLyBDaGVjayBpZiBhbnkgcmFzdGVyIHRpbGUgaXMgaW4gYSBmYWRpbmcgc3RhdGVcbiAgICAgICAgICAgIGNvbnN0IGZhZGVEdXJhdGlvbiA9ICgobGF5ZXI6IGFueSk6IFJhc3RlclN0eWxlTGF5ZXIpLnBhaW50LmdldCgncmFzdGVyLWZhZGUtZHVyYXRpb24nKTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgcHJveHkgb2YgdGhpcy5wcm94eUNvb3Jkcykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHByb3hpZWRDb29yZHMgPSB0aGlzLnByb3h5VG9Tb3VyY2VbcHJveHkua2V5XVtzb3VyY2VDYWNoZS5pZF07XG4gICAgICAgICAgICAgICAgY29uc3QgY29vcmRzID0gKChwcm94aWVkQ29vcmRzOiBhbnkpOiBBcnJheTxPdmVyc2NhbGVkVGlsZUlEPik7XG4gICAgICAgICAgICAgICAgaWYgKCFjb29yZHMpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBjb29yZCBvZiBjb29yZHMpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGlsZSA9IHNvdXJjZUNhY2hlLmdldFRpbGUoY29vcmQpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXJlbnQgPSBzb3VyY2VDYWNoZS5maW5kTG9hZGVkUGFyZW50KGNvb3JkLCAwKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmFkZSA9IHJhc3RlckZhZGUodGlsZSwgcGFyZW50LCBzb3VyY2VDYWNoZSwgdGhpcy5wYWludGVyLnRyYW5zZm9ybSwgZmFkZUR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaXNGYWRpbmcgPSBmYWRlLm9wYWNpdHkgIT09IDEgfHwgZmFkZS5taXggIT09IDA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0ZhZGluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2xlYXJSZW5kZXJDYWNoZUZvclRpbGUoc291cmNlQ2FjaGUuaWQsIGNvb3JkKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9zZXR1cERyYXBlZFJlbmRlckJhdGNoZXMoKSB7XG4gICAgICAgIGNvbnN0IGxheWVySWRzID0gdGhpcy5fc3R5bGUub3JkZXI7XG4gICAgICAgIGNvbnN0IGxheWVyQ291bnQgPSBsYXllcklkcy5sZW5ndGg7XG4gICAgICAgIGlmIChsYXllckNvdW50ID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBiYXRjaGVzOiBBcnJheTxSZW5kZXJCYXRjaD4gPSBbXTtcblxuICAgICAgICBsZXQgY3VycmVudExheWVyID0gMDtcbiAgICAgICAgbGV0IGxheWVyID0gdGhpcy5fc3R5bGUuX2xheWVyc1tsYXllcklkc1tjdXJyZW50TGF5ZXJdXTtcbiAgICAgICAgd2hpbGUgKCF0aGlzLl9zdHlsZS5pc0xheWVyRHJhcGVkKGxheWVyKSAmJiBsYXllci5pc0hpZGRlbih0aGlzLnBhaW50ZXIudHJhbnNmb3JtLnpvb20pICYmICsrY3VycmVudExheWVyIDwgbGF5ZXJDb3VudCkge1xuICAgICAgICAgICAgbGF5ZXIgPSB0aGlzLl9zdHlsZS5fbGF5ZXJzW2xheWVySWRzW2N1cnJlbnRMYXllcl1dO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGJhdGNoU3RhcnQ6IG51bWJlciB8IHZvaWQ7XG4gICAgICAgIGZvciAoOyBjdXJyZW50TGF5ZXIgPCBsYXllckNvdW50OyArK2N1cnJlbnRMYXllcikge1xuICAgICAgICAgICAgY29uc3QgbGF5ZXIgPSB0aGlzLl9zdHlsZS5fbGF5ZXJzW2xheWVySWRzW2N1cnJlbnRMYXllcl1dO1xuICAgICAgICAgICAgaWYgKGxheWVyLmlzSGlkZGVuKHRoaXMucGFpbnRlci50cmFuc2Zvcm0uem9vbSkpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghdGhpcy5fc3R5bGUuaXNMYXllckRyYXBlZChsYXllcikpIHtcbiAgICAgICAgICAgICAgICBpZiAoYmF0Y2hTdGFydCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGJhdGNoZXMucHVzaCh7c3RhcnQ6IGJhdGNoU3RhcnQsIGVuZDogY3VycmVudExheWVyIC0gMX0pO1xuICAgICAgICAgICAgICAgICAgICBiYXRjaFN0YXJ0ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChiYXRjaFN0YXJ0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBiYXRjaFN0YXJ0ID0gY3VycmVudExheWVyO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGJhdGNoU3RhcnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgYmF0Y2hlcy5wdXNoKHtzdGFydDogYmF0Y2hTdGFydCwgZW5kOiBjdXJyZW50TGF5ZXIgLSAxfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5fc3R5bGUubWFwLl9vcHRpbWl6ZUZvclRlcnJhaW4pIHtcbiAgICAgICAgICAgIC8vIERyYXBlZCBmaXJzdCBhcHByb2FjaCBzaG91bGQgcmVzdWx0IGluIGEgc2luZ2xlIG9yIG5vIGJhdGNoXG4gICAgICAgICAgICBhc3NlcnQoYmF0Y2hlcy5sZW5ndGggPT09IDEgfHwgYmF0Y2hlcy5sZW5ndGggPT09IDApO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fZHJhcGVkUmVuZGVyQmF0Y2hlcyA9IGJhdGNoZXM7XG4gICAgfVxuXG4gICAgX3NldHVwUmVuZGVyQ2FjaGUocHJldmlvdXNQcm94eVRvU291cmNlOiB7W251bWJlcl06IHtbc3RyaW5nXTogQXJyYXk8UHJveGllZFRpbGVJRD59fSkge1xuICAgICAgICBjb25zdCBwc2MgPSB0aGlzLnByb3h5U291cmNlQ2FjaGU7XG4gICAgICAgIGlmICh0aGlzLl9zaG91bGREaXNhYmxlUmVuZGVyQ2FjaGUoKSB8fCB0aGlzLl9pbnZhbGlkYXRlUmVuZGVyQ2FjaGUpIHtcbiAgICAgICAgICAgIHRoaXMuX2ludmFsaWRhdGVSZW5kZXJDYWNoZSA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKHBzYy5yZW5kZXJDYWNoZS5sZW5ndGggPiBwc2MucmVuZGVyQ2FjaGVQb29sLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHVzZWQgPSAoKE9iamVjdC52YWx1ZXMocHNjLnByb3h5Q2FjaGVkRkJPKTogYW55KTogQXJyYXk8e1tzdHJpbmcgfCBudW1iZXJdOiBudW1iZXJ9Pik7XG4gICAgICAgICAgICAgICAgcHNjLnByb3h5Q2FjaGVkRkJPID0ge307XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB1c2VkLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGZib3MgPSAoKE9iamVjdC52YWx1ZXModXNlZFtpXSk6IGFueSk6IEFycmF5PG51bWJlcj4pO1xuICAgICAgICAgICAgICAgICAgICBwc2MucmVuZGVyQ2FjaGVQb29sLnB1c2goLi4uZmJvcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGFzc2VydChwc2MucmVuZGVyQ2FjaGUubGVuZ3RoID09PSBwc2MucmVuZGVyQ2FjaGVQb29sLmxlbmd0aCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9jbGVhclJhc3RlckxheWVyc0Zyb21SZW5kZXJDYWNoZSgpO1xuXG4gICAgICAgIGNvbnN0IGNvb3JkcyA9IHRoaXMucHJveHlDb29yZHM7XG4gICAgICAgIGNvbnN0IGRpcnR5ID0gdGhpcy5fdGlsZXNEaXJ0eTtcbiAgICAgICAgZm9yIChsZXQgaSA9IGNvb3Jkcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgY29uc3QgcHJveHkgPSBjb29yZHNbaV07XG4gICAgICAgICAgICBjb25zdCB0aWxlID0gcHNjLmdldFRpbGVCeUlEKHByb3h5LmtleSk7XG5cbiAgICAgICAgICAgIGlmIChwc2MucHJveHlDYWNoZWRGQk9bcHJveHkua2V5XSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgYXNzZXJ0KHRpbGUudGV4dHVyZSk7XG4gICAgICAgICAgICAgICAgY29uc3QgcHJldiA9IHByZXZpb3VzUHJveHlUb1NvdXJjZVtwcm94eS5rZXldO1xuICAgICAgICAgICAgICAgIGFzc2VydChwcmV2KTtcbiAgICAgICAgICAgICAgICAvLyBSZXVzZSBwcmV2aW91cyByZW5kZXIgZnJvbSBjYWNoZSBpZiB0aGVyZSB3YXMgbm8gY2hhbmdlIG9mXG4gICAgICAgICAgICAgICAgLy8gY29udGVudCB0aGF0IHdhcyB1c2VkIHRvIHJlbmRlciBwcm94eSB0aWxlLlxuICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLnByb3h5VG9Tb3VyY2VbcHJveHkua2V5XTtcbiAgICAgICAgICAgICAgICBsZXQgZXF1YWwgPSAwO1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qgc291cmNlIGluIGN1cnJlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGlsZXMgPSBjdXJyZW50W3NvdXJjZV07XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHByZXZUaWxlcyA9IHByZXZbc291cmNlXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFwcmV2VGlsZXMgfHwgcHJldlRpbGVzLmxlbmd0aCAhPT0gdGlsZXMubGVuZ3RoIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICB0aWxlcy5zb21lKCh0LCBpbmRleCkgPT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAodCAhPT0gcHJldlRpbGVzW2luZGV4XSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChkaXJ0eVtzb3VyY2VdICYmIGRpcnR5W3NvdXJjZV0uaGFzT3duUHJvcGVydHkodC5rZXkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKSkpXG4gICAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXF1YWwgPSAtMTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICsrZXF1YWw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIGRpcnR5ID09PSBmYWxzZTogZG9lc24ndCBuZWVkIHRvIGJlIHJlbmRlcmVkIHRvLCBqdXN0IHVzZSBjYWNoZWQgcmVuZGVyLlxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcHJveHlGQk8gaW4gcHNjLnByb3h5Q2FjaGVkRkJPW3Byb3h5LmtleV0pIHtcbiAgICAgICAgICAgICAgICAgICAgcHNjLnJlbmRlckNhY2hlW3BzYy5wcm94eUNhY2hlZEZCT1twcm94eS5rZXldW3Byb3h5RkJPXV0uZGlydHkgPSBlcXVhbCA8IDAgfHwgZXF1YWwgIT09IE9iamVjdC52YWx1ZXMocHJldikubGVuZ3RoO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNvcnRlZFJlbmRlckJhdGNoZXMgPSBbLi4udGhpcy5fZHJhcGVkUmVuZGVyQmF0Y2hlc107XG4gICAgICAgIHNvcnRlZFJlbmRlckJhdGNoZXMuc29ydCgoYmF0Y2hBLCBiYXRjaEIpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGJhdGNoQVNpemUgPSBiYXRjaEEuZW5kIC0gYmF0Y2hBLnN0YXJ0O1xuICAgICAgICAgICAgY29uc3QgYmF0Y2hCU2l6ZSA9IGJhdGNoQi5lbmQgLSBiYXRjaEIuc3RhcnQ7XG4gICAgICAgICAgICByZXR1cm4gYmF0Y2hCU2l6ZSAtIGJhdGNoQVNpemU7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGZvciAoY29uc3QgYmF0Y2ggb2Ygc29ydGVkUmVuZGVyQmF0Y2hlcykge1xuICAgICAgICAgICAgZm9yIChjb25zdCBpZCBvZiBjb29yZHMpIHtcbiAgICAgICAgICAgICAgICBpZiAocHNjLnByb3h5Q2FjaGVkRkJPW2lkLmtleV0pIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gQXNzaWduIHJlbmRlckNhY2hlIEZCTyBpZiB0aGVyZSBhcmUgYXZhaWxhYmxlIEZCT3MgaW4gcG9vbC5cbiAgICAgICAgICAgICAgICBsZXQgaW5kZXggPSBwc2MucmVuZGVyQ2FjaGVQb29sLnBvcCgpO1xuICAgICAgICAgICAgICAgIGlmIChpbmRleCA9PT0gdW5kZWZpbmVkICYmIHBzYy5yZW5kZXJDYWNoZS5sZW5ndGggPCBSRU5ERVJfQ0FDSEVfTUFYX1NJWkUpIHtcbiAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBwc2MucmVuZGVyQ2FjaGUubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICBwc2MucmVuZGVyQ2FjaGUucHVzaCh0aGlzLl9jcmVhdGVGQk8oKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChpbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHBzYy5wcm94eUNhY2hlZEZCT1tpZC5rZXldID0ge307XG4gICAgICAgICAgICAgICAgICAgIHBzYy5wcm94eUNhY2hlZEZCT1tpZC5rZXldW2JhdGNoLnN0YXJ0XSA9IGluZGV4O1xuICAgICAgICAgICAgICAgICAgICBwc2MucmVuZGVyQ2FjaGVbaW5kZXhdLmRpcnR5ID0gdHJ1ZTsgLy8gbmVlZHMgdG8gYmUgcmVuZGVyZWQgdG8uXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3RpbGVzRGlydHkgPSB7fTtcbiAgICB9XG5cbiAgICBfc2V0dXBTdGVuY2lsKGZibzogRkJPLCBwcm94aWVkQ29vcmRzOiBBcnJheTxQcm94aWVkVGlsZUlEPiwgbGF5ZXI6IFN0eWxlTGF5ZXIsIHNvdXJjZUNhY2hlPzogU291cmNlQ2FjaGUpIHtcbiAgICAgICAgaWYgKCFzb3VyY2VDYWNoZSB8fCAhdGhpcy5fc291cmNlVGlsZXNPdmVybGFwW3NvdXJjZUNhY2hlLmlkXSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX292ZXJsYXBTdGVuY2lsVHlwZSkgdGhpcy5fb3ZlcmxhcFN0ZW5jaWxUeXBlID0gZmFsc2U7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMucGFpbnRlci5jb250ZXh0O1xuICAgICAgICBjb25zdCBnbCA9IGNvbnRleHQuZ2w7XG5cbiAgICAgICAgLy8gSWYgbmVlZGVkLCBzZXR1cCBzdGVuY2lsbGluZy4gRG9uJ3QgYm90aGVyIHRvIHJlbW92ZSB3aGVuIHRoZXJlIGlzIG5vXG4gICAgICAgIC8vIG1vcmUgbmVlZDogaW4gc3VjaCBjYXNlLCBpZiB0aGVyZSBpcyBubyBvdmVybGFwLCBzdGVuY2lsbGluZyBpcyBkaXNhYmxlZC5cbiAgICAgICAgaWYgKHByb3hpZWRDb29yZHMubGVuZ3RoIDw9IDEpIHsgdGhpcy5fb3ZlcmxhcFN0ZW5jaWxUeXBlID0gZmFsc2U7IHJldHVybjsgfVxuXG4gICAgICAgIGxldCBzdGVuY2lsUmFuZ2U7XG4gICAgICAgIGlmIChsYXllci5pc1RpbGVDbGlwcGVkKCkpIHtcbiAgICAgICAgICAgIHN0ZW5jaWxSYW5nZSA9IHByb3hpZWRDb29yZHMubGVuZ3RoO1xuICAgICAgICAgICAgdGhpcy5fb3ZlcmxhcFN0ZW5jaWxNb2RlLnRlc3QgPSB7ZnVuYzogZ2wuRVFVQUwsIG1hc2s6IDB4RkZ9O1xuICAgICAgICAgICAgdGhpcy5fb3ZlcmxhcFN0ZW5jaWxUeXBlID0gJ0NsaXAnO1xuICAgICAgICB9IGVsc2UgaWYgKHByb3hpZWRDb29yZHNbMF0ub3ZlcnNjYWxlZFogPiBwcm94aWVkQ29vcmRzW3Byb3hpZWRDb29yZHMubGVuZ3RoIC0gMV0ub3ZlcnNjYWxlZFopIHtcbiAgICAgICAgICAgIHN0ZW5jaWxSYW5nZSA9IDE7XG4gICAgICAgICAgICB0aGlzLl9vdmVybGFwU3RlbmNpbE1vZGUudGVzdCA9IHtmdW5jOiBnbC5HUkVBVEVSLCBtYXNrOiAweEZGfTtcbiAgICAgICAgICAgIHRoaXMuX292ZXJsYXBTdGVuY2lsVHlwZSA9ICdNYXNrJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX292ZXJsYXBTdGVuY2lsVHlwZSA9IGZhbHNlO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9zdGVuY2lsUmVmICsgc3RlbmNpbFJhbmdlID4gMjU1KSB7XG4gICAgICAgICAgICBjb250ZXh0LmNsZWFyKHtzdGVuY2lsOiAwfSk7XG4gICAgICAgICAgICB0aGlzLl9zdGVuY2lsUmVmID0gMDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9zdGVuY2lsUmVmICs9IHN0ZW5jaWxSYW5nZTtcbiAgICAgICAgdGhpcy5fb3ZlcmxhcFN0ZW5jaWxNb2RlLnJlZiA9IHRoaXMuX3N0ZW5jaWxSZWY7XG4gICAgICAgIGlmIChsYXllci5pc1RpbGVDbGlwcGVkKCkpIHtcbiAgICAgICAgICAgIHRoaXMuX3JlbmRlclRpbGVDbGlwcGluZ01hc2tzKHByb3hpZWRDb29yZHMsIHRoaXMuX292ZXJsYXBTdGVuY2lsTW9kZS5yZWYpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY2xpcE9yTWFza092ZXJsYXBTdGVuY2lsVHlwZSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX292ZXJsYXBTdGVuY2lsVHlwZSA9PT0gJ0NsaXAnIHx8IHRoaXMuX292ZXJsYXBTdGVuY2lsVHlwZSA9PT0gJ01hc2snO1xuICAgIH1cblxuICAgIHN0ZW5jaWxNb2RlRm9yUlRUT3ZlcmxhcChpZDogT3ZlcnNjYWxlZFRpbGVJRCk6ICRSZWFkT25seTxTdGVuY2lsTW9kZT4ge1xuICAgICAgICBpZiAoIXRoaXMucmVuZGVyaW5nVG9UZXh0dXJlIHx8ICF0aGlzLl9vdmVybGFwU3RlbmNpbFR5cGUpIHtcbiAgICAgICAgICAgIHJldHVybiBTdGVuY2lsTW9kZS5kaXNhYmxlZDtcbiAgICAgICAgfVxuICAgICAgICAvLyBBbGwgc291cmNlIHRpbGVzIGNvbnRyaWJ1dGluZyB0byB0aGUgc2FtZSBwcm94eSBhcmUgcHJvY2Vzc2VkIGluIHNlcXVlbmNlLCBpbiB6b29tIGRlc2NlbmRpbmcgb3JkZXIuXG4gICAgICAgIC8vIEZvciByYXN0ZXIgLyBoaWxsc2hhZGUgb3ZlcmxhcCBtYXNraW5nLCByZWYgaXMgYmFzZWQgb24gem9vbSBkaWYuXG4gICAgICAgIC8vIEZvciB2ZWN0b3IgbGF5ZXIgY2xpcHBpbmcsIGV2ZXJ5IHRpbGUgZ2V0cyBkZWRpY2F0ZWQgc3RlbmNpbCByZWYuXG4gICAgICAgIGlmICh0aGlzLl9vdmVybGFwU3RlbmNpbFR5cGUgPT09ICdDbGlwJykge1xuICAgICAgICAgICAgLy8gSW4gaW1tZWRpYXRlIDJEIG1vZGUsIHdlIHJlbmRlciByZWN0cyB0byBtYXJrIGNsaXBwaW5nIGFyZWEgYW5kIGhhbmRsZSBiZWhhdmlvciBvbiB0aWxlIGJvcmRlcnMuXG4gICAgICAgICAgICAvLyBIZXJlLCB0aGVyZSBpcyBubyBuZWVkIGZvciBub3cgZm9yIHRoaXM6XG4gICAgICAgICAgICAvLyAxLiBvdmVybGFwIGlzIGhhbmRsZWQgYnkgcHJveHkgcmVuZGVyIHRvIHRleHR1cmUgdGlsZXMgKHRoZXJlIGlzIG5vIG92ZXJsYXAgdGhlcmUpXG4gICAgICAgICAgICAvLyAyLiBoZXJlIHdlIGhhbmRsZSBvbmx5IGJyaWVmIHpvb20gb3V0IHNlbWktdHJhbnNwYXJlbnQgY29sb3IgaW50ZW5zaXR5IGZsaWNrZXJpbmdcbiAgICAgICAgICAgIC8vICAgIGFuZCB0aGF0IGlzIGF2b2lkZWQgZmluZSBieSBzdGVuY2lsaW5nIHByaW1pdGl2ZXMgYXMgcGFydCBvZiBkcmF3aW5nIChpbnN0ZWFkIG9mIGFkZGl0aW9uYWwgdGlsZSBxdWFkIHN0ZXApLlxuICAgICAgICAgICAgdGhpcy5fb3ZlcmxhcFN0ZW5jaWxNb2RlLnJlZiA9IHRoaXMucGFpbnRlci5fdGlsZUNsaXBwaW5nTWFza0lEc1tpZC5rZXldO1xuICAgICAgICB9IC8vIGVsc2UgdGhpcy5fb3ZlcmxhcFN0ZW5jaWxNb2RlLnJlZiBpcyBzZXQgdG8gYSBzaW5nbGUgdmFsdWUgdXNlZCBwZXIgcHJveHkgdGlsZSwgaW4gX3NldHVwU3RlbmNpbC5cbiAgICAgICAgcmV0dXJuIHRoaXMuX292ZXJsYXBTdGVuY2lsTW9kZTtcbiAgICB9XG5cbiAgICBfcmVuZGVyVGlsZUNsaXBwaW5nTWFza3MocHJveGllZENvb3JkczogQXJyYXk8UHJveGllZFRpbGVJRD4sIHJlZjogbnVtYmVyKSB7XG4gICAgICAgIGNvbnN0IHBhaW50ZXIgPSB0aGlzLnBhaW50ZXI7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLnBhaW50ZXIuY29udGV4dDtcbiAgICAgICAgY29uc3QgZ2wgPSBjb250ZXh0LmdsO1xuICAgICAgICBwYWludGVyLl90aWxlQ2xpcHBpbmdNYXNrSURzID0ge307XG4gICAgICAgIGNvbnRleHQuc2V0Q29sb3JNb2RlKENvbG9yTW9kZS5kaXNhYmxlZCk7XG4gICAgICAgIGNvbnRleHQuc2V0RGVwdGhNb2RlKERlcHRoTW9kZS5kaXNhYmxlZCk7XG5cbiAgICAgICAgY29uc3QgcHJvZ3JhbSA9IHBhaW50ZXIudXNlUHJvZ3JhbSgnY2xpcHBpbmdNYXNrJyk7XG5cbiAgICAgICAgZm9yIChjb25zdCB0aWxlSUQgb2YgcHJveGllZENvb3Jkcykge1xuICAgICAgICAgICAgY29uc3QgaWQgPSBwYWludGVyLl90aWxlQ2xpcHBpbmdNYXNrSURzW3RpbGVJRC5rZXldID0gLS1yZWY7XG4gICAgICAgICAgICBwcm9ncmFtLmRyYXcoY29udGV4dCwgZ2wuVFJJQU5HTEVTLCBEZXB0aE1vZGUuZGlzYWJsZWQsXG4gICAgICAgICAgICAgICAgLy8gVGVzdHMgd2lsbCBhbHdheXMgcGFzcywgYW5kIHJlZiB2YWx1ZSB3aWxsIGJlIHdyaXR0ZW4gdG8gc3RlbmNpbCBidWZmZXIuXG4gICAgICAgICAgICAgICAgbmV3IFN0ZW5jaWxNb2RlKHtmdW5jOiBnbC5BTFdBWVMsIG1hc2s6IDB9LCBpZCwgMHhGRiwgZ2wuS0VFUCwgZ2wuS0VFUCwgZ2wuUkVQTEFDRSksXG4gICAgICAgICAgICAgICAgQ29sb3JNb2RlLmRpc2FibGVkLCBDdWxsRmFjZU1vZGUuZGlzYWJsZWQsIGNsaXBwaW5nTWFza1VuaWZvcm1WYWx1ZXModGlsZUlELnByb2pNYXRyaXgpLFxuICAgICAgICAgICAgICAgICckY2xpcHBpbmcnLCBwYWludGVyLnRpbGVFeHRlbnRCdWZmZXIsXG4gICAgICAgICAgICAgICAgcGFpbnRlci5xdWFkVHJpYW5nbGVJbmRleEJ1ZmZlciwgcGFpbnRlci50aWxlRXh0ZW50U2VnbWVudHMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2FzdHMgYSByYXkgZnJvbSBhIHBvaW50IG9uIHNjcmVlbiBhbmQgcmV0dXJucyB0aGUgaW50ZXJzZWN0aW9uIHBvaW50IHdpdGggdGhlIHRlcnJhaW4uXG4gICAgLy8gVGhlIHJldHVybmVkIHBvaW50IGNvbnRhaW5zIHRoZSBtZXJjYXRvciBjb29yZGluYXRlcyBpbiBpdHMgZmlyc3QgMyBjb21wb25lbnRzLCBhbmQgZWxldmF0aW9uXG4gICAgLy8gaW4gbWV0ZXIgaW4gaXRzIDR0aCBjb29yZGluYXRlLlxuICAgIHBvaW50Q29vcmRpbmF0ZShzY3JlZW5Qb2ludDogUG9pbnQpOiA/VmVjNCB7XG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IHRoaXMucGFpbnRlci50cmFuc2Zvcm07XG4gICAgICAgIGlmIChzY3JlZW5Qb2ludC54IDwgMCB8fCBzY3JlZW5Qb2ludC54ID4gdHJhbnNmb3JtLndpZHRoIHx8XG4gICAgICAgICAgICBzY3JlZW5Qb2ludC55IDwgMCB8fCBzY3JlZW5Qb2ludC55ID4gdHJhbnNmb3JtLmhlaWdodCkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmYXIgPSBbc2NyZWVuUG9pbnQueCwgc2NyZWVuUG9pbnQueSwgMSwgMV07XG4gICAgICAgIHZlYzQudHJhbnNmb3JtTWF0NChmYXIsIGZhciwgdHJhbnNmb3JtLnBpeGVsTWF0cml4SW52ZXJzZSk7XG4gICAgICAgIHZlYzQuc2NhbGUoZmFyLCBmYXIsIDEuMCAvIGZhclszXSk7XG4gICAgICAgIC8vIHggJiB5IGluIHBpeGVsIGNvb3JkaW5hdGVzLCB6IGlzIGFsdGl0dWRlIGluIG1ldGVyc1xuICAgICAgICBmYXJbMF0gLz0gdHJhbnNmb3JtLndvcmxkU2l6ZTtcbiAgICAgICAgZmFyWzFdIC89IHRyYW5zZm9ybS53b3JsZFNpemU7XG4gICAgICAgIGNvbnN0IGNhbWVyYSA9IHRyYW5zZm9ybS5fY2FtZXJhLnBvc2l0aW9uO1xuICAgICAgICBjb25zdCBtZXJjYXRvclpTY2FsZSA9IG1lcmNhdG9yWmZyb21BbHRpdHVkZSgxLCB0cmFuc2Zvcm0uY2VudGVyLmxhdCk7XG4gICAgICAgIGNvbnN0IHAgPSBbY2FtZXJhWzBdLCBjYW1lcmFbMV0sIGNhbWVyYVsyXSAvIG1lcmNhdG9yWlNjYWxlLCAwLjBdO1xuICAgICAgICBjb25zdCBkaXIgPSB2ZWMzLnN1YnRyYWN0KFtdLCBmYXIuc2xpY2UoMCwgMyksIHApO1xuICAgICAgICB2ZWMzLm5vcm1hbGl6ZShkaXIsIGRpcik7XG5cbiAgICAgICAgY29uc3QgZXhhZ2dlcmF0aW9uID0gdGhpcy5fZXhhZ2dlcmF0aW9uO1xuICAgICAgICBjb25zdCBkaXN0YW5jZUFsb25nUmF5ID0gdGhpcy5yYXljYXN0KHAsIGRpciwgZXhhZ2dlcmF0aW9uKTtcblxuICAgICAgICBpZiAoZGlzdGFuY2VBbG9uZ1JheSA9PT0gbnVsbCB8fCAhZGlzdGFuY2VBbG9uZ1JheSkgcmV0dXJuIG51bGw7XG4gICAgICAgIHZlYzMuc2NhbGVBbmRBZGQocCwgcCwgZGlyLCBkaXN0YW5jZUFsb25nUmF5KTtcbiAgICAgICAgcFszXSA9IHBbMl07XG4gICAgICAgIHBbMl0gKj0gbWVyY2F0b3JaU2NhbGU7XG4gICAgICAgIHJldHVybiBwO1xuICAgIH1cblxuICAgIGRyYXdEZXB0aCgpIHtcbiAgICAgICAgY29uc3QgcGFpbnRlciA9IHRoaXMucGFpbnRlcjtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IHBhaW50ZXIuY29udGV4dDtcbiAgICAgICAgY29uc3QgcHNjID0gdGhpcy5wcm94eVNvdXJjZUNhY2hlO1xuXG4gICAgICAgIGNvbnN0IHdpZHRoID0gTWF0aC5jZWlsKHBhaW50ZXIud2lkdGgpLCBoZWlnaHQgPSBNYXRoLmNlaWwocGFpbnRlci5oZWlnaHQpO1xuICAgICAgICBpZiAodGhpcy5fZGVwdGhGQk8gJiYgKHRoaXMuX2RlcHRoRkJPLndpZHRoICE9PSB3aWR0aCB8fCB0aGlzLl9kZXB0aEZCTy5oZWlnaHQgIT09IGhlaWdodCkpIHtcbiAgICAgICAgICAgIHRoaXMuX2RlcHRoRkJPLmRlc3Ryb3koKTtcbiAgICAgICAgICAgIHRoaXMuX2RlcHRoRkJPID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgdGhpcy5fZGVwdGhUZXh0dXJlID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5fZGVwdGhGQk8pIHtcbiAgICAgICAgICAgIGNvbnN0IGdsID0gY29udGV4dC5nbDtcbiAgICAgICAgICAgIGNvbnN0IGZibyA9IGNvbnRleHQuY3JlYXRlRnJhbWVidWZmZXIod2lkdGgsIGhlaWdodCwgdHJ1ZSk7XG4gICAgICAgICAgICBjb250ZXh0LmFjdGl2ZVRleHR1cmUuc2V0KGdsLlRFWFRVUkUwKTtcbiAgICAgICAgICAgIGNvbnN0IHRleHR1cmUgPSBuZXcgVGV4dHVyZShjb250ZXh0LCB7d2lkdGgsIGhlaWdodCwgZGF0YTogbnVsbH0sIGdsLlJHQkEpO1xuICAgICAgICAgICAgdGV4dHVyZS5iaW5kKGdsLk5FQVJFU1QsIGdsLkNMQU1QX1RPX0VER0UpO1xuICAgICAgICAgICAgZmJvLmNvbG9yQXR0YWNobWVudC5zZXQodGV4dHVyZS50ZXh0dXJlKTtcbiAgICAgICAgICAgIGNvbnN0IHJlbmRlcmJ1ZmZlciA9IGNvbnRleHQuY3JlYXRlUmVuZGVyYnVmZmVyKGNvbnRleHQuZ2wuREVQVEhfQ09NUE9ORU5UMTYsIHdpZHRoLCBoZWlnaHQpO1xuICAgICAgICAgICAgZmJvLmRlcHRoQXR0YWNobWVudC5zZXQocmVuZGVyYnVmZmVyKTtcbiAgICAgICAgICAgIHRoaXMuX2RlcHRoRkJPID0gZmJvO1xuICAgICAgICAgICAgdGhpcy5fZGVwdGhUZXh0dXJlID0gdGV4dHVyZTtcbiAgICAgICAgfVxuICAgICAgICBjb250ZXh0LmJpbmRGcmFtZWJ1ZmZlci5zZXQodGhpcy5fZGVwdGhGQk8uZnJhbWVidWZmZXIpO1xuICAgICAgICBjb250ZXh0LnZpZXdwb3J0LnNldChbMCwgMCwgd2lkdGgsIGhlaWdodF0pO1xuXG4gICAgICAgIGRyYXdUZXJyYWluRGVwdGgocGFpbnRlciwgdGhpcywgcHNjLCB0aGlzLnByb3h5Q29vcmRzKTtcbiAgICB9XG5cbiAgICBfc2V0dXBQcm94aWVkQ29vcmRzRm9yT3J0aG8oc291cmNlQ2FjaGU6IFNvdXJjZUNhY2hlLCBzb3VyY2VDb29yZHM6IEFycmF5PE92ZXJzY2FsZWRUaWxlSUQ+LCBwcmV2aW91c1Byb3h5VG9Tb3VyY2U6IHtbbnVtYmVyXToge1tzdHJpbmddOiBBcnJheTxQcm94aWVkVGlsZUlEPn19KTogdm9pZCB7XG4gICAgICAgIGlmIChzb3VyY2VDYWNoZS5nZXRTb3VyY2UoKSBpbnN0YW5jZW9mIEltYWdlU291cmNlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc2V0dXBQcm94aWVkQ29vcmRzRm9ySW1hZ2VTb3VyY2Uoc291cmNlQ2FjaGUsIHNvdXJjZUNvb3JkcywgcHJldmlvdXNQcm94eVRvU291cmNlKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9maW5kQ292ZXJpbmdUaWxlQ2FjaGVbc291cmNlQ2FjaGUuaWRdID0gdGhpcy5fZmluZENvdmVyaW5nVGlsZUNhY2hlW3NvdXJjZUNhY2hlLmlkXSB8fCB7fTtcbiAgICAgICAgY29uc3QgY29vcmRzID0gdGhpcy5wcm94aWVkQ29vcmRzW3NvdXJjZUNhY2hlLmlkXSA9IFtdO1xuICAgICAgICBjb25zdCBwcm94eXMgPSB0aGlzLnByb3h5Q29vcmRzO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByb3h5cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgcHJveHlUaWxlSUQgPSBwcm94eXNbaV07XG4gICAgICAgICAgICBjb25zdCBwcm94aWVkID0gdGhpcy5fZmluZFRpbGVDb3ZlcmluZ1RpbGVJRChwcm94eVRpbGVJRCwgc291cmNlQ2FjaGUpO1xuICAgICAgICAgICAgaWYgKHByb3hpZWQpIHtcbiAgICAgICAgICAgICAgICBhc3NlcnQocHJveGllZC5oYXNEYXRhKCkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGlkID0gdGhpcy5fY3JlYXRlUHJveGllZElkKHByb3h5VGlsZUlELCBwcm94aWVkLCBwcmV2aW91c1Byb3h5VG9Tb3VyY2VbcHJveHlUaWxlSUQua2V5XSAmJiBwcmV2aW91c1Byb3h5VG9Tb3VyY2VbcHJveHlUaWxlSUQua2V5XVtzb3VyY2VDYWNoZS5pZF0pO1xuICAgICAgICAgICAgICAgIGNvb3Jkcy5wdXNoKGlkKTtcbiAgICAgICAgICAgICAgICB0aGlzLnByb3h5VG9Tb3VyY2VbcHJveHlUaWxlSUQua2V5XVtzb3VyY2VDYWNoZS5pZF0gPSBbaWRdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxldCBoYXNPdmVybGFwID0gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc291cmNlQ29vcmRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCB0aWxlID0gc291cmNlQ2FjaGUuZ2V0VGlsZShzb3VyY2VDb29yZHNbaV0pO1xuICAgICAgICAgICAgaWYgKCF0aWxlIHx8ICF0aWxlLmhhc0RhdGEoKSkgY29udGludWU7XG4gICAgICAgICAgICBjb25zdCBwcm94eSA9IHRoaXMuX2ZpbmRUaWxlQ292ZXJpbmdUaWxlSUQodGlsZS50aWxlSUQsIHRoaXMucHJveHlTb3VyY2VDYWNoZSk7XG4gICAgICAgICAgICAvLyBEb24ndCBhZGQgdGhlIHRpbGUgaWYgYWxyZWFkeSBhZGRlZCBpbiBsb29wIGFib3ZlLlxuICAgICAgICAgICAgaWYgKHByb3h5ICYmIHByb3h5LnRpbGVJRC5jYW5vbmljYWwueiAhPT0gdGlsZS50aWxlSUQuY2Fub25pY2FsLnopIHtcbiAgICAgICAgICAgICAgICBjb25zdCBhcnJheSA9IHRoaXMucHJveHlUb1NvdXJjZVtwcm94eS50aWxlSUQua2V5XVtzb3VyY2VDYWNoZS5pZF07XG4gICAgICAgICAgICAgICAgY29uc3QgaWQgPSB0aGlzLl9jcmVhdGVQcm94aWVkSWQocHJveHkudGlsZUlELCB0aWxlLCBwcmV2aW91c1Byb3h5VG9Tb3VyY2VbcHJveHkudGlsZUlELmtleV0gJiYgcHJldmlvdXNQcm94eVRvU291cmNlW3Byb3h5LnRpbGVJRC5rZXldW3NvdXJjZUNhY2hlLmlkXSk7XG4gICAgICAgICAgICAgICAgaWYgKCFhcnJheSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3h5VG9Tb3VyY2VbcHJveHkudGlsZUlELmtleV1bc291cmNlQ2FjaGUuaWRdID0gW2lkXTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBUaGUgbGFzdCBlbGVtZW50IGlzIHBhcmVudCBhZGRlZCBpbiBsb29wIGFib3ZlLiBUaGlzIHdheSB3ZSBnZXRcbiAgICAgICAgICAgICAgICAgICAgLy8gYSBsaXN0IGluIFogZGVzY2VuZGluZyBvcmRlciB3aGljaCBpcyBuZWVkZWQgZm9yIHN0ZW5jaWwgbWFza2luZy5cbiAgICAgICAgICAgICAgICAgICAgYXJyYXkuc3BsaWNlKGFycmF5Lmxlbmd0aCAtIDEsIDAsIGlkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29vcmRzLnB1c2goaWQpO1xuICAgICAgICAgICAgICAgIGhhc092ZXJsYXAgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3NvdXJjZVRpbGVzT3ZlcmxhcFtzb3VyY2VDYWNoZS5pZF0gPSBoYXNPdmVybGFwO1xuICAgIH1cblxuICAgIF9zZXR1cFByb3hpZWRDb29yZHNGb3JJbWFnZVNvdXJjZShzb3VyY2VDYWNoZTogU291cmNlQ2FjaGUsIHNvdXJjZUNvb3JkczogQXJyYXk8T3ZlcnNjYWxlZFRpbGVJRD4sIHByZXZpb3VzUHJveHlUb1NvdXJjZToge1tudW1iZXJdOiB7W3N0cmluZ106IEFycmF5PFByb3hpZWRUaWxlSUQ+fX0pIHtcbiAgICAgICAgaWYgKCFzb3VyY2VDYWNoZS5nZXRTb3VyY2UoKS5sb2FkZWQoKSkgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IGNvb3JkcyA9IHRoaXMucHJveGllZENvb3Jkc1tzb3VyY2VDYWNoZS5pZF0gPSBbXTtcbiAgICAgICAgY29uc3QgcHJveHlzID0gdGhpcy5wcm94eUNvb3JkcztcbiAgICAgICAgY29uc3QgaW1hZ2VTb3VyY2U6IEltYWdlU291cmNlID0gKChzb3VyY2VDYWNoZS5nZXRTb3VyY2UoKTogYW55KTogSW1hZ2VTb3VyY2UpO1xuXG4gICAgICAgIGNvbnN0IGFuY2hvciA9IG5ldyBQb2ludChpbWFnZVNvdXJjZS50aWxlSUQueCwgaW1hZ2VTb3VyY2UudGlsZUlELnkpLl9kaXYoMSA8PCBpbWFnZVNvdXJjZS50aWxlSUQueik7XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgY29uc3QgYWFiYiA9IGltYWdlU291cmNlLmNvb3JkaW5hdGVzLm1hcChNZXJjYXRvckNvb3JkaW5hdGUuZnJvbUxuZ0xhdCkucmVkdWNlKChhY2MsIGNvb3JkKSA9PiB7XG4gICAgICAgICAgICBhY2MubWluLnggPSBNYXRoLm1pbihhY2MubWluLngsIGNvb3JkLnggLSBhbmNob3IueCk7XG4gICAgICAgICAgICBhY2MubWluLnkgPSBNYXRoLm1pbihhY2MubWluLnksIGNvb3JkLnkgLSBhbmNob3IueSk7XG4gICAgICAgICAgICBhY2MubWF4LnggPSBNYXRoLm1heChhY2MubWF4LngsIGNvb3JkLnggLSBhbmNob3IueCk7XG4gICAgICAgICAgICBhY2MubWF4LnkgPSBNYXRoLm1heChhY2MubWF4LnksIGNvb3JkLnkgLSBhbmNob3IueSk7XG4gICAgICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgICB9LCB7bWluOiBuZXcgUG9pbnQoTnVtYmVyLk1BWF9WQUxVRSwgTnVtYmVyLk1BWF9WQUxVRSksIG1heDogbmV3IFBvaW50KC1OdW1iZXIuTUFYX1ZBTFVFLCAtTnVtYmVyLk1BWF9WQUxVRSl9KTtcblxuICAgICAgICAvLyBGYXN0IGNvbnNlcnZhdGl2ZSBjaGVjayB1c2luZyBhYWJiOiBjb250ZW50IG91dHNpZGUgcHJveHkgdGlsZSBnZXRzIGNsaXBwZWQgb3V0IGJ5IG9uIHJlbmRlciwgYW55d2F5LlxuICAgICAgICBjb25zdCB0aWxlT3V0c2lkZUltYWdlID0gKHRpbGVJRDogT3ZlcnNjYWxlZFRpbGVJRCwgaW1hZ2VUaWxlSUQ6IE92ZXJzY2FsZWRUaWxlSUQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHggPSB0aWxlSUQud3JhcCArIHRpbGVJRC5jYW5vbmljYWwueCAvICgxIDw8IHRpbGVJRC5jYW5vbmljYWwueik7XG4gICAgICAgICAgICBjb25zdCB5ID0gdGlsZUlELmNhbm9uaWNhbC55IC8gKDEgPDwgdGlsZUlELmNhbm9uaWNhbC56KTtcbiAgICAgICAgICAgIGNvbnN0IGQgPSBFWFRFTlQgLyAoMSA8PCB0aWxlSUQuY2Fub25pY2FsLnopO1xuXG4gICAgICAgICAgICBjb25zdCBpeCA9IGltYWdlVGlsZUlELndyYXAgKyBpbWFnZVRpbGVJRC5jYW5vbmljYWwueCAvICgxIDw8IGltYWdlVGlsZUlELmNhbm9uaWNhbC56KTtcbiAgICAgICAgICAgIGNvbnN0IGl5ID0gaW1hZ2VUaWxlSUQuY2Fub25pY2FsLnkgLyAoMSA8PCBpbWFnZVRpbGVJRC5jYW5vbmljYWwueik7XG5cbiAgICAgICAgICAgIHJldHVybiB4ICsgZCA8IGl4ICsgYWFiYi5taW4ueCB8fCB4ID4gaXggKyBhYWJiLm1heC54IHx8IHkgKyBkIDwgaXkgKyBhYWJiLm1pbi55IHx8IHkgPiBpeSArIGFhYmIubWF4Lnk7XG4gICAgICAgIH07XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwcm94eXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHByb3h5VGlsZUlEID0gcHJveHlzW2ldO1xuICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBzb3VyY2VDb29yZHMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0aWxlID0gc291cmNlQ2FjaGUuZ2V0VGlsZShzb3VyY2VDb29yZHNbal0pO1xuICAgICAgICAgICAgICAgIGlmICghdGlsZSB8fCAhdGlsZS5oYXNEYXRhKCkpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICAgICAgLy8gU2V0dXAgcHJveGllZCAtPiBwcm94eSBtYXBwaW5nIG9ubHkgaWYgaW1hZ2Ugb24gZ2l2ZW4gdGlsZSB3cmFwIGludGVyc2VjdHMgdGhlIHByb3h5IHRpbGUuXG4gICAgICAgICAgICAgICAgaWYgKHRpbGVPdXRzaWRlSW1hZ2UocHJveHlUaWxlSUQsIHRpbGUudGlsZUlEKSkgY29udGludWU7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBpZCA9IHRoaXMuX2NyZWF0ZVByb3hpZWRJZChwcm94eVRpbGVJRCwgdGlsZSwgcHJldmlvdXNQcm94eVRvU291cmNlW3Byb3h5VGlsZUlELmtleV0gJiYgcHJldmlvdXNQcm94eVRvU291cmNlW3Byb3h5VGlsZUlELmtleV1bc291cmNlQ2FjaGUuaWRdKTtcbiAgICAgICAgICAgICAgICBjb25zdCBhcnJheSA9IHRoaXMucHJveHlUb1NvdXJjZVtwcm94eVRpbGVJRC5rZXldW3NvdXJjZUNhY2hlLmlkXTtcbiAgICAgICAgICAgICAgICBpZiAoIWFycmF5KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJveHlUb1NvdXJjZVtwcm94eVRpbGVJRC5rZXldW3NvdXJjZUNhY2hlLmlkXSA9IFtpZF07XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYXJyYXkucHVzaChpZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvb3Jkcy5wdXNoKGlkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIHJlY3ljbGUgaXMgcHJldmlvdXMgcGFzcyBjb250ZW50IHRoYXQgbGlrZWx5IGNvbnRhaW5zIHByb3hpZWQgSUQgY29tYmluaW5nIHByb3h5IGFuZCBzb3VyY2UgdGlsZS5cbiAgICBfY3JlYXRlUHJveGllZElkKHByb3h5VGlsZUlEOiBPdmVyc2NhbGVkVGlsZUlELCB0aWxlOiBUaWxlLCByZWN5Y2xlOiBBcnJheTxQcm94aWVkVGlsZUlEPik6IFByb3hpZWRUaWxlSUQge1xuICAgICAgICBsZXQgbWF0cml4ID0gdGhpcy5vcnRob01hdHJpeDtcbiAgICAgICAgaWYgKHJlY3ljbGUpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlY3ljbGVkID0gcmVjeWNsZS5maW5kKHByb3hpZWQgPT4gKHByb3hpZWQua2V5ID09PSB0aWxlLnRpbGVJRC5rZXkpKTtcbiAgICAgICAgICAgIGlmIChyZWN5Y2xlZCkgcmV0dXJuIHJlY3ljbGVkO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aWxlLnRpbGVJRC5rZXkgIT09IHByb3h5VGlsZUlELmtleSkge1xuICAgICAgICAgICAgY29uc3Qgc2NhbGUgPSBwcm94eVRpbGVJRC5jYW5vbmljYWwueiAtIHRpbGUudGlsZUlELmNhbm9uaWNhbC56O1xuICAgICAgICAgICAgbWF0cml4ID0gbWF0NC5jcmVhdGUoKTtcbiAgICAgICAgICAgIGxldCBzaXplLCB4T2Zmc2V0LCB5T2Zmc2V0O1xuICAgICAgICAgICAgY29uc3Qgd3JhcCA9ICh0aWxlLnRpbGVJRC53cmFwIC0gcHJveHlUaWxlSUQud3JhcCkgPDwgcHJveHlUaWxlSUQub3ZlcnNjYWxlZFo7XG4gICAgICAgICAgICBpZiAoc2NhbGUgPiAwKSB7XG4gICAgICAgICAgICAgICAgc2l6ZSA9IEVYVEVOVCA+PiBzY2FsZTtcbiAgICAgICAgICAgICAgICB4T2Zmc2V0ID0gc2l6ZSAqICgodGlsZS50aWxlSUQuY2Fub25pY2FsLnggPDwgc2NhbGUpIC0gcHJveHlUaWxlSUQuY2Fub25pY2FsLnggKyB3cmFwKTtcbiAgICAgICAgICAgICAgICB5T2Zmc2V0ID0gc2l6ZSAqICgodGlsZS50aWxlSUQuY2Fub25pY2FsLnkgPDwgc2NhbGUpIC0gcHJveHlUaWxlSUQuY2Fub25pY2FsLnkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzaXplID0gRVhURU5UIDw8IC1zY2FsZTtcbiAgICAgICAgICAgICAgICB4T2Zmc2V0ID0gRVhURU5UICogKHRpbGUudGlsZUlELmNhbm9uaWNhbC54IC0gKChwcm94eVRpbGVJRC5jYW5vbmljYWwueCArIHdyYXApIDw8IC1zY2FsZSkpO1xuICAgICAgICAgICAgICAgIHlPZmZzZXQgPSBFWFRFTlQgKiAodGlsZS50aWxlSUQuY2Fub25pY2FsLnkgLSAocHJveHlUaWxlSUQuY2Fub25pY2FsLnkgPDwgLXNjYWxlKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBtYXQ0Lm9ydGhvKG1hdHJpeCwgMCwgc2l6ZSwgMCwgc2l6ZSwgMCwgMSk7XG4gICAgICAgICAgICBtYXQ0LnRyYW5zbGF0ZShtYXRyaXgsIG1hdHJpeCwgW3hPZmZzZXQsIHlPZmZzZXQsIDBdKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFByb3hpZWRUaWxlSUQodGlsZS50aWxlSUQsIHByb3h5VGlsZUlELmtleSwgbWF0cml4KTtcbiAgICB9XG5cbiAgICAvLyBBIHZhcmlhbnQgb2YgU291cmNlQ2FjaGUuZmluZExvYWRlZFBhcmVudCB0aGF0IGNvbnNpZGVycyBvbmx5IHZpc2libGVcbiAgICAvLyB0aWxlcyAoYW5kIGRvZXNuJ3QgY2hlY2sgU291cmNlQ2FjaGUuX2NhY2hlKS4gQW5vdGhlciBkaWZmZXJlbmNlIGlzIGluXG4gICAgLy8gY2FjaGluZyBcIm5vdCBmb3VuZFwiIHJlc3VsdHMgYWxvbmcgdGhlIGxvb2t1cCwgdG8gbGVhdmUgdGhlIGxvb2t1cCBlYXJseS5cbiAgICAvLyBOb3QgZm91bmQgaXMgY2FjaGVkIGJ5IHRoaXMuX2ZpbmRDb3ZlcmluZ1RpbGVDYWNoZVtrZXldID0gbnVsbDtcbiAgICBfZmluZFRpbGVDb3ZlcmluZ1RpbGVJRCh0aWxlSUQ6IE92ZXJzY2FsZWRUaWxlSUQsIHNvdXJjZUNhY2hlOiBTb3VyY2VDYWNoZSk6ID9UaWxlIHtcbiAgICAgICAgbGV0IHRpbGU6ID9UaWxlID0gc291cmNlQ2FjaGUuZ2V0VGlsZSh0aWxlSUQpO1xuICAgICAgICBpZiAodGlsZSAmJiB0aWxlLmhhc0RhdGEoKSkgcmV0dXJuIHRpbGU7XG5cbiAgICAgICAgY29uc3QgbG9va3VwID0gdGhpcy5fZmluZENvdmVyaW5nVGlsZUNhY2hlW3NvdXJjZUNhY2hlLmlkXTtcbiAgICAgICAgY29uc3Qga2V5ID0gbG9va3VwW3RpbGVJRC5rZXldO1xuICAgICAgICB0aWxlID0ga2V5ID8gc291cmNlQ2FjaGUuZ2V0VGlsZUJ5SUQoa2V5KSA6IG51bGw7XG4gICAgICAgIGlmICgodGlsZSAmJiB0aWxlLmhhc0RhdGEoKSkgfHwga2V5ID09PSBudWxsKSByZXR1cm4gdGlsZTtcblxuICAgICAgICBhc3NlcnQoIWtleSB8fCB0aWxlKTtcblxuICAgICAgICBsZXQgc291cmNlVGlsZUlEID0gdGlsZSA/IHRpbGUudGlsZUlEIDogdGlsZUlEO1xuICAgICAgICBsZXQgeiA9IHNvdXJjZVRpbGVJRC5vdmVyc2NhbGVkWjtcbiAgICAgICAgY29uc3QgbWluem9vbSA9IHNvdXJjZUNhY2hlLmdldFNvdXJjZSgpLm1pbnpvb207XG4gICAgICAgIGNvbnN0IHBhdGggPSBbXTtcbiAgICAgICAgaWYgKCFrZXkpIHtcbiAgICAgICAgICAgIGNvbnN0IG1heHpvb20gPSBzb3VyY2VDYWNoZS5nZXRTb3VyY2UoKS5tYXh6b29tO1xuICAgICAgICAgICAgaWYgKHRpbGVJRC5jYW5vbmljYWwueiA+PSBtYXh6b29tKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZG93bnNjYWxlID0gdGlsZUlELmNhbm9uaWNhbC56IC0gbWF4em9vbTtcbiAgICAgICAgICAgICAgICBpZiAoc291cmNlQ2FjaGUuZ2V0U291cmNlKCkucmVwYXJzZU92ZXJzY2FsZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgeiA9IE1hdGgubWF4KHRpbGVJRC5jYW5vbmljYWwueiArIDIsIHNvdXJjZUNhY2hlLnRyYW5zZm9ybS50aWxlWm9vbSk7XG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZVRpbGVJRCA9IG5ldyBPdmVyc2NhbGVkVGlsZUlEKHosIHRpbGVJRC53cmFwLCBtYXh6b29tLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGlsZUlELmNhbm9uaWNhbC54ID4+IGRvd25zY2FsZSwgdGlsZUlELmNhbm9uaWNhbC55ID4+IGRvd25zY2FsZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChkb3duc2NhbGUgIT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgeiA9IG1heHpvb207XG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZVRpbGVJRCA9IG5ldyBPdmVyc2NhbGVkVGlsZUlEKHosIHRpbGVJRC53cmFwLCBtYXh6b29tLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGlsZUlELmNhbm9uaWNhbC54ID4+IGRvd25zY2FsZSwgdGlsZUlELmNhbm9uaWNhbC55ID4+IGRvd25zY2FsZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHNvdXJjZVRpbGVJRC5rZXkgIT09IHRpbGVJRC5rZXkpIHtcbiAgICAgICAgICAgICAgICBwYXRoLnB1c2goc291cmNlVGlsZUlELmtleSk7XG4gICAgICAgICAgICAgICAgdGlsZSA9IHNvdXJjZUNhY2hlLmdldFRpbGUoc291cmNlVGlsZUlEKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHBhdGhUb0xvb2t1cCA9IChrZXk6ID9udW1iZXIpID0+IHtcbiAgICAgICAgICAgIHBhdGguZm9yRWFjaChpZCA9PiB7IGxvb2t1cFtpZF0gPSBrZXk7IH0pO1xuICAgICAgICAgICAgcGF0aC5sZW5ndGggPSAwO1xuICAgICAgICB9O1xuXG4gICAgICAgIGZvciAoeiA9IHogLSAxOyB6ID49IG1pbnpvb20gJiYgISh0aWxlICYmIHRpbGUuaGFzRGF0YSgpKTsgei0tKSB7XG4gICAgICAgICAgICBpZiAodGlsZSkge1xuICAgICAgICAgICAgICAgIHBhdGhUb0xvb2t1cCh0aWxlLnRpbGVJRC5rZXkpOyAvLyBTdG9yZSBsb29rdXAgdG8gcGFyZW50cyBub3QgbG9hZGVkICh5ZXQpLlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgaWQgPSBzb3VyY2VUaWxlSUQuY2FsY3VsYXRlU2NhbGVkS2V5KHopO1xuICAgICAgICAgICAgdGlsZSA9IHNvdXJjZUNhY2hlLmdldFRpbGVCeUlEKGlkKTtcbiAgICAgICAgICAgIGlmICh0aWxlICYmIHRpbGUuaGFzRGF0YSgpKSBicmVhaztcbiAgICAgICAgICAgIGNvbnN0IGtleSA9IGxvb2t1cFtpZF07XG4gICAgICAgICAgICBpZiAoa2V5ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7IC8vIFRoZXJlJ3Mgbm8gdGlsZSBsb2FkZWQgYW5kIG5vIHBvaW50IHNlYXJjaGluZyBmdXJ0aGVyLlxuICAgICAgICAgICAgfSBlbHNlIGlmIChrZXkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHRpbGUgPSBzb3VyY2VDYWNoZS5nZXRUaWxlQnlJRChrZXkpO1xuICAgICAgICAgICAgICAgIGFzc2VydCh0aWxlKTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBhdGgucHVzaChpZCk7XG4gICAgICAgIH1cblxuICAgICAgICBwYXRoVG9Mb29rdXAodGlsZSA/IHRpbGUudGlsZUlELmtleSA6IG51bGwpO1xuICAgICAgICByZXR1cm4gdGlsZSAmJiB0aWxlLmhhc0RhdGEoKSA/IHRpbGUgOiBudWxsO1xuICAgIH1cblxuICAgIGZpbmRERU1UaWxlRm9yKHRpbGVJRDogT3ZlcnNjYWxlZFRpbGVJRCk6ID9UaWxlIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5hYmxlZCA/IHRoaXMuX2ZpbmRUaWxlQ292ZXJpbmdUaWxlSUQodGlsZUlELCB0aGlzLnNvdXJjZUNhY2hlKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBCb29ra2VlcGluZyBpZiBzb21ldGhpbmcgZ2V0cyByZW5kZXJlZCB0byB0aGUgdGlsZS5cbiAgICAgKi9cbiAgICBwcmVwYXJlRHJhd1RpbGUoKSB7XG4gICAgICAgIHRoaXMucmVuZGVyZWRUb1RpbGUgPSB0cnVlO1xuICAgIH1cblxuICAgIF9jbGVhclJlbmRlckNhY2hlRm9yVGlsZShzb3VyY2U6IHN0cmluZywgY29vcmQ6IE92ZXJzY2FsZWRUaWxlSUQpIHtcbiAgICAgICAgbGV0IHNvdXJjZVRpbGVzID0gdGhpcy5fdGlsZXNEaXJ0eVtzb3VyY2VdO1xuICAgICAgICBpZiAoIXNvdXJjZVRpbGVzKSBzb3VyY2VUaWxlcyA9IHRoaXMuX3RpbGVzRGlydHlbc291cmNlXSA9IHt9O1xuICAgICAgICBzb3VyY2VUaWxlc1tjb29yZC5rZXldID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKlxuICAgICAqIExhemlseSBpbnN0YW50aWF0ZSB0aGUgd2lyZWZyYW1lIGluZGV4IGJ1ZmZlciBhbmQgc2VnbWVudCB2ZWN0b3Igc28gdGhhdCB3ZSBkb24ndFxuICAgICAqIGFsbG9jYXRlIHRoZSBnZW9tZXRyeSBmb3IgcmVuZGVyaW5nIGEgZGVidWcgd2lyZWZyYW1lIHVudGlsIGl0J3MgbmVlZGVkLlxuICAgICAqL1xuICAgIGdldFdpcmVmYW1lQnVmZmVyKCk6IFtJbmRleEJ1ZmZlciwgU2VnbWVudFZlY3Rvcl0ge1xuICAgICAgICBpZiAoIXRoaXMud2lyZWZyYW1lU2VnbWVudHMpIHtcbiAgICAgICAgICAgIGNvbnN0IHdpcmVmcmFtZUdyaWRJbmRpY2VzID0gY3JlYXRlV2lyZWZyYW1lR3JpZChHUklEX0RJTSArIDEpO1xuICAgICAgICAgICAgdGhpcy53aXJlZnJhbWVJbmRleEJ1ZmZlciA9IHRoaXMucGFpbnRlci5jb250ZXh0LmNyZWF0ZUluZGV4QnVmZmVyKHdpcmVmcmFtZUdyaWRJbmRpY2VzKTtcbiAgICAgICAgICAgIHRoaXMud2lyZWZyYW1lU2VnbWVudHMgPSBTZWdtZW50VmVjdG9yLnNpbXBsZVNlZ21lbnQoMCwgMCwgdGhpcy5ncmlkQnVmZmVyLmxlbmd0aCwgd2lyZWZyYW1lR3JpZEluZGljZXMubGVuZ3RoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW3RoaXMud2lyZWZyYW1lSW5kZXhCdWZmZXIsIHRoaXMud2lyZWZyYW1lU2VnbWVudHNdO1xuICAgIH1cblxufVxuXG5mdW5jdGlvbiBzb3J0QnlEaXN0YW5jZVRvQ2FtZXJhKHRpbGVJRHM6IEFycmF5PE92ZXJzY2FsZWRUaWxlSUQ+LCBwYWludGVyOiBQYWludGVyKSB7XG4gICAgY29uc3QgY2FtZXJhQ29vcmRpbmF0ZSA9IHBhaW50ZXIudHJhbnNmb3JtLnBvaW50Q29vcmRpbmF0ZShwYWludGVyLnRyYW5zZm9ybS5nZXRDYW1lcmFQb2ludCgpKTtcbiAgICBjb25zdCBjYW1lcmFQb2ludCA9IG5ldyBQb2ludChjYW1lcmFDb29yZGluYXRlLngsIGNhbWVyYUNvb3JkaW5hdGUueSk7XG4gICAgdGlsZUlEcy5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgIGlmIChiLm92ZXJzY2FsZWRaIC0gYS5vdmVyc2NhbGVkWikgcmV0dXJuIGIub3ZlcnNjYWxlZFogLSBhLm92ZXJzY2FsZWRaO1xuICAgICAgICBjb25zdCBhUG9pbnQgPSBuZXcgUG9pbnQoYS5jYW5vbmljYWwueCArICgxIDw8IGEuY2Fub25pY2FsLnopICogYS53cmFwLCBhLmNhbm9uaWNhbC55KTtcbiAgICAgICAgY29uc3QgYlBvaW50ID0gbmV3IFBvaW50KGIuY2Fub25pY2FsLnggKyAoMSA8PCBiLmNhbm9uaWNhbC56KSAqIGIud3JhcCwgYi5jYW5vbmljYWwueSk7XG4gICAgICAgIGNvbnN0IGNhbWVyYVNjYWxlZCA9IGNhbWVyYVBvaW50Lm11bHQoMSA8PCBhLmNhbm9uaWNhbC56KTtcbiAgICAgICAgY2FtZXJhU2NhbGVkLnggLT0gMC41O1xuICAgICAgICBjYW1lcmFTY2FsZWQueSAtPSAwLjU7XG4gICAgICAgIHJldHVybiBjYW1lcmFTY2FsZWQuZGlzdFNxcihhUG9pbnQpIC0gY2FtZXJhU2NhbGVkLmRpc3RTcXIoYlBvaW50KTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIHVuaWZvcm0gZ3JpZCBvZiB0cmlhbmdsZXMsIGNvdmVyaW5nIEVYVEVOVCB4IEVYVEVOVCBzcXVhcmUsIHdpdGggdHdvXG4gKiBhZGp1c3RlbnQgdHJhaWdsZXMgZm9ybWluZyBhIHF1YWQsIHNvIHRoYXQgdGhlcmUgYXJlIHxjb3VudHwgY29sdW1ucyBhbmQgcm93c1xuICogb2YgdGhlc2UgcXVhZHMgaW4gRVhURU5UIHggRVhURU5UIHNxdWFyZS5cbiAqIGUuZy4gZm9yIGNvdW50IG9mIDI6XG4gKiAgLS0tLS0tLS0tLS0tLVxuICogIHwgICAgL3wgICAgL3xcbiAqICB8ICAvICB8ICAvICB8XG4gKiAgfC8gICAgfC8gICAgfFxuICogIC0tLS0tLS0tLS0tLS1cbiAqICB8ICAgIC98ICAgIC98XG4gKiAgfCAgLyAgfCAgLyAgfFxuICogIHwvICAgIHwvICAgIHxcbiAqICAtLS0tLS0tLS0tLS0tXG4gKiBAcGFyYW0ge251bWJlcn0gY291bnQgQ291bnQgb2Ygcm93cyBhbmQgY29sdW1uc1xuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gY3JlYXRlR3JpZChjb3VudDogbnVtYmVyKTogW1Bvc0FycmF5LCBUcmlhbmdsZUluZGV4QXJyYXksIG51bWJlcl0ge1xuICAgIGNvbnN0IGJvdW5kc0FycmF5ID0gbmV3IFBvc0FycmF5KCk7XG4gICAgLy8gQXJvdW5kIHRoZSBncmlkLCBhZGQgb25lIG1vcmUgcm93L2NvbHVtbiBwYWRkaW5nIGZvciBcInNraXJ0XCIuXG4gICAgY29uc3QgaW5kZXhBcnJheSA9IG5ldyBUcmlhbmdsZUluZGV4QXJyYXkoKTtcbiAgICBjb25zdCBzaXplID0gY291bnQgKyAyO1xuICAgIGJvdW5kc0FycmF5LnJlc2VydmUoc2l6ZSAqIHNpemUpO1xuICAgIGluZGV4QXJyYXkucmVzZXJ2ZSgoc2l6ZSAtIDEpICogKHNpemUgLSAxKSAqIDIpO1xuICAgIGNvbnN0IHN0ZXAgPSBFWFRFTlQgLyAoY291bnQgLSAxKTtcbiAgICBjb25zdCBncmlkQm91bmQgPSBFWFRFTlQgKyBzdGVwIC8gMjtcbiAgICBjb25zdCBib3VuZCA9IGdyaWRCb3VuZCArIHN0ZXA7XG5cbiAgICAvLyBTa2lydCBvZmZzZXQgb2YgMHg1RkZGIGlzIGNob3NlbiByYW5kb21seSB0byBlbmNvZGUgYm9vbGVhbiB2YWx1ZSAoc2tpcnRcbiAgICAvLyBvbi9vZmYpIHdpdGggeCBwb3NpdGlvbiAobWF4IHZhbHVlIEVYVEVOVCA9IDQwOTYpIHRvIDE2LWJpdCBzaWduZWQgaW50ZWdlci5cbiAgICBjb25zdCBza2lydE9mZnNldCA9IDI0NTc1OyAvLyAweDVGRkZcbiAgICBmb3IgKGxldCB5ID0gLXN0ZXA7IHkgPCBib3VuZDsgeSArPSBzdGVwKSB7XG4gICAgICAgIGZvciAobGV0IHggPSAtc3RlcDsgeCA8IGJvdW5kOyB4ICs9IHN0ZXApIHtcbiAgICAgICAgICAgIGNvbnN0IG9mZnNldCA9ICh4IDwgMCB8fCB4ID4gZ3JpZEJvdW5kIHx8IHkgPCAwIHx8IHkgPiBncmlkQm91bmQpID8gc2tpcnRPZmZzZXQgOiAwO1xuICAgICAgICAgICAgY29uc3QgeGkgPSBjbGFtcChNYXRoLnJvdW5kKHgpLCAwLCBFWFRFTlQpO1xuICAgICAgICAgICAgY29uc3QgeWkgPSBjbGFtcChNYXRoLnJvdW5kKHkpLCAwLCBFWFRFTlQpO1xuICAgICAgICAgICAgYm91bmRzQXJyYXkuZW1wbGFjZUJhY2soeGkgKyBvZmZzZXQsIHlpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIEZvciBjYXNlcyB3aGVuIHRoZXJlJ3Mgbm8gbmVlZCB0byByZW5kZXIgXCJza2lydFwiLCB0aGUgXCJpbm5lclwiIGdyaWQgaW5kaWNlc1xuICAgIC8vIGFyZSBmb2xsb3dlZCBieSBza2lydCBpbmRpY2VzLlxuICAgIGNvbnN0IHNraXJ0SW5kaWNlc09mZnNldCA9IChzaXplIC0gMykgKiAoc2l6ZSAtIDMpICogMjtcbiAgICBjb25zdCBxdWFkID0gKGk6IG51bWJlciwgajogbnVtYmVyKSA9PiB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gaiAqIHNpemUgKyBpO1xuICAgICAgICBpbmRleEFycmF5LmVtcGxhY2VCYWNrKGluZGV4ICsgMSwgaW5kZXgsIGluZGV4ICsgc2l6ZSk7XG4gICAgICAgIGluZGV4QXJyYXkuZW1wbGFjZUJhY2soaW5kZXggKyBzaXplLCBpbmRleCArIHNpemUgKyAxLCBpbmRleCArIDEpO1xuICAgIH07XG4gICAgZm9yIChsZXQgaiA9IDE7IGogPCBzaXplIC0gMjsgaisrKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgc2l6ZSAtIDI7IGkrKykge1xuICAgICAgICAgICAgcXVhZChpLCBqKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBQYWRkaW5nIChza2lydCkgaW5kaWNlczpcbiAgICBbMCwgc2l6ZSAtIDJdLmZvckVhY2goaiA9PiB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2l6ZSAtIDE7IGkrKykge1xuICAgICAgICAgICAgcXVhZChpLCBqKTtcbiAgICAgICAgICAgIHF1YWQoaiwgaSk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gW2JvdW5kc0FycmF5LCBpbmRleEFycmF5LCBza2lydEluZGljZXNPZmZzZXRdO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBncmlkIG9mIGluZGljZXMgY29ycmVzcG9uZGluZyB0byB0aGUgZ3JpZCBjb25zdHJ1Y3RlZCBieSBjcmVhdGVHcmlkXG4gKiBpbiBvcmRlciB0byByZW5kZXIgdGhhdCBncmlkIGFzIGEgd2lyZWZyYW1lIHJhdGhlciB0aGFuIGEgc29saWQgIG1lc2guIEl0IGRvZXNcbiAqIG5vdCBjcmVhdGUgYSBza2lydCBhbmQgc28gb25seSBnb2VzIGZyb20gMSB0byBjb3VudCArIDEsIGUuZy4gZm9yIGNvdW50IG9mIDI6XG4gKiAgLS0tLS0tLS0tLS0tLVxuICogIHwgICAgL3wgICAgL3xcbiAqICB8ICAvICB8ICAvICB8XG4gKiAgfC8gICAgfC8gICAgfFxuICogIC0tLS0tLS0tLS0tLS1cbiAqICB8ICAgIC98ICAgIC98XG4gKiAgfCAgLyAgfCAgLyAgfFxuICogIHwvICAgIHwvICAgIHxcbiAqICAtLS0tLS0tLS0tLS0tXG4gKiBAcGFyYW0ge251bWJlcn0gY291bnQgQ291bnQgb2Ygcm93cyBhbmQgY29sdW1uc1xuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gY3JlYXRlV2lyZWZyYW1lR3JpZChjb3VudDogbnVtYmVyKTogTGluZUluZGV4QXJyYXkge1xuICAgIGxldCBpbmRleCA9IDA7XG4gICAgY29uc3QgaW5kZXhBcnJheSA9IG5ldyBMaW5lSW5kZXhBcnJheSgpO1xuICAgIGNvbnN0IHNpemUgPSBjb3VudCArIDI7XG4gICAgLy8gRHJhdyB0d28gZWRnZXMgb2YgYSBxdWFkIGFuZCBpdHMgZGlhZ29uYWwuIFRoZSB2ZXJ5IGxhc3Qgcm93IGFuZCBjb2x1bW4gaGF2ZVxuICAgIC8vIGFuIGFkZGl0aW9uYWwgbGluZSB0byBjbG9zZSBvZmYgdGhlIGdyaWQuXG4gICAgZm9yIChsZXQgaiA9IDE7IGogPCBjb3VudDsgaisrKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgY291bnQ7IGkrKykge1xuICAgICAgICAgICAgaW5kZXggPSBqICogc2l6ZSArIGk7XG4gICAgICAgICAgICBpbmRleEFycmF5LmVtcGxhY2VCYWNrKGluZGV4LCBpbmRleCArIDEpO1xuICAgICAgICAgICAgaW5kZXhBcnJheS5lbXBsYWNlQmFjayhpbmRleCwgaW5kZXggKyBzaXplKTtcbiAgICAgICAgICAgIGluZGV4QXJyYXkuZW1wbGFjZUJhY2soaW5kZXggKyAxLCBpbmRleCArIHNpemUpO1xuXG4gICAgICAgICAgICAvLyBQbGFjZSBhbiBleHRyYSBsaW5lIGF0IHRoZSBlbmQgb2YgZWFjaCByb3dcbiAgICAgICAgICAgIGlmIChqID09PSBjb3VudCAtIDEpIGluZGV4QXJyYXkuZW1wbGFjZUJhY2soaW5kZXggKyBzaXplLCBpbmRleCArIHNpemUgKyAxKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBQbGFjZSBhbiBleHRyYSBsaW5lIGF0IHRoZSBlbmQgb2YgZWFjaCBjb2xcbiAgICAgICAgaW5kZXhBcnJheS5lbXBsYWNlQmFjayhpbmRleCArIDEsIGluZGV4ICsgMSArIHNpemUpO1xuICAgIH1cbiAgICByZXR1cm4gaW5kZXhBcnJheTtcbn1cblxuZXhwb3J0IHR5cGUgVGVycmFpblVuaWZvcm1zVHlwZSA9IHt8XG4gICAgJ3VfZGVtJzogVW5pZm9ybTFpLFxuICAgICd1X2RlbV9wcmV2JzogVW5pZm9ybTFpLFxuICAgICd1X2RlbV91bnBhY2snOiBVbmlmb3JtNGYsXG4gICAgJ3VfZGVtX3RsJzogVW5pZm9ybTJmLFxuICAgICd1X2RlbV9zY2FsZSc6IFVuaWZvcm0xZixcbiAgICAndV9kZW1fdGxfcHJldic6IFVuaWZvcm0yZixcbiAgICAndV9kZW1fc2NhbGVfcHJldic6IFVuaWZvcm0xZixcbiAgICAndV9kZW1fc2l6ZSc6IFVuaWZvcm0xZixcbiAgICAndV9kZW1fbGVycCc6IFVuaWZvcm0xZixcbiAgICBcInVfZXhhZ2dlcmF0aW9uXCI6IFVuaWZvcm0xZixcbiAgICAndV9kZXB0aCc6IFVuaWZvcm0xaSxcbiAgICAndV9kZXB0aF9zaXplX2ludic6IFVuaWZvcm0yZixcbiAgICAndV9tZXRlcl90b19kZW0nPzogVW5pZm9ybTFmLFxuICAgICd1X2xhYmVsX3BsYW5lX21hdHJpeF9pbnYnPzogVW5pZm9ybU1hdHJpeDRmLFxufH07XG5cbmV4cG9ydCBjb25zdCB0ZXJyYWluVW5pZm9ybXMgPSAoY29udGV4dDogQ29udGV4dCk6IFRlcnJhaW5Vbmlmb3Jtc1R5cGUgPT4gKHtcbiAgICAndV9kZW0nOiBuZXcgVW5pZm9ybTFpKGNvbnRleHQpLFxuICAgICd1X2RlbV9wcmV2JzogbmV3IFVuaWZvcm0xaShjb250ZXh0KSxcbiAgICAndV9kZW1fdW5wYWNrJzogbmV3IFVuaWZvcm00Zihjb250ZXh0KSxcbiAgICAndV9kZW1fdGwnOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpLFxuICAgICd1X2RlbV9zY2FsZSc6IG5ldyBVbmlmb3JtMWYoY29udGV4dCksXG4gICAgJ3VfZGVtX3RsX3ByZXYnOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpLFxuICAgICd1X2RlbV9zY2FsZV9wcmV2JzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9kZW1fc2l6ZSc6IG5ldyBVbmlmb3JtMWYoY29udGV4dCksXG4gICAgJ3VfZGVtX2xlcnAnOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X2V4YWdnZXJhdGlvbic6IG5ldyBVbmlmb3JtMWYoY29udGV4dCksXG4gICAgJ3VfZGVwdGgnOiBuZXcgVW5pZm9ybTFpKGNvbnRleHQpLFxuICAgICd1X2RlcHRoX3NpemVfaW52JzogbmV3IFVuaWZvcm0yZihjb250ZXh0KSxcbiAgICAndV9tZXRlcl90b19kZW0nOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X2xhYmVsX3BsYW5lX21hdHJpeF9pbnYnOiBuZXcgVW5pZm9ybU1hdHJpeDRmKGNvbnRleHQpLFxufSk7XG5cbmZ1bmN0aW9uIGRlZmF1bHRUZXJyYWluVW5pZm9ybXMoZW5jb2Rpbmc6IERFTUVuY29kaW5nKTogVW5pZm9ybVZhbHVlczxUZXJyYWluVW5pZm9ybXNUeXBlPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgJ3VfZGVtJzogMixcbiAgICAgICAgJ3VfZGVtX3ByZXYnOiA0LFxuICAgICAgICAndV9kZW1fdW5wYWNrJzogREVNRGF0YS5nZXRVbnBhY2tWZWN0b3IoZW5jb2RpbmcpLFxuICAgICAgICAndV9kZW1fdGwnOiBbMCwgMF0sXG4gICAgICAgICd1X2RlbV90bF9wcmV2JzogWzAsIDBdLFxuICAgICAgICAndV9kZW1fc2NhbGUnOiAwLFxuICAgICAgICAndV9kZW1fc2NhbGVfcHJldic6IDAsXG4gICAgICAgICd1X2RlbV9zaXplJzogMCxcbiAgICAgICAgJ3VfZGVtX2xlcnAnOiAxLjAsXG4gICAgICAgICd1X2RlcHRoJzogMyxcbiAgICAgICAgJ3VfZGVwdGhfc2l6ZV9pbnYnOiBbMCwgMF0sXG4gICAgICAgICd1X2V4YWdnZXJhdGlvbic6IDAsXG4gICAgfTtcbn1cblxuZXhwb3J0IHR5cGUgR2xvYmVVbmlmb3Jtc1R5cGUgPSB7fFxuICAgICd1X3RpbGVfdGxfdXAnOiBVbmlmb3JtM2YsXG4gICAgJ3VfdGlsZV90cl91cCc6IFVuaWZvcm0zZixcbiAgICAndV90aWxlX2JyX3VwJzogVW5pZm9ybTNmLFxuICAgICd1X3RpbGVfYmxfdXAnOiBVbmlmb3JtM2YsXG4gICAgJ3VfdGlsZV91cF9zY2FsZSc6IFVuaWZvcm0xZlxufH07XG5cbmV4cG9ydCBjb25zdCBnbG9iZVVuaWZvcm1zID0gKGNvbnRleHQ6IENvbnRleHQpOiBHbG9iZVVuaWZvcm1zVHlwZSA9PiAoe1xuICAgICd1X3RpbGVfdGxfdXAnOiBuZXcgVW5pZm9ybTNmKGNvbnRleHQpLFxuICAgICd1X3RpbGVfdHJfdXAnOiBuZXcgVW5pZm9ybTNmKGNvbnRleHQpLFxuICAgICd1X3RpbGVfYnJfdXAnOiBuZXcgVW5pZm9ybTNmKGNvbnRleHQpLFxuICAgICd1X3RpbGVfYmxfdXAnOiBuZXcgVW5pZm9ybTNmKGNvbnRleHQpLFxuICAgICd1X3RpbGVfdXBfc2NhbGUnOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpXG59KTtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCBDb250ZXh0IGZyb20gJy4uL2dsL2NvbnRleHQuanMnO1xuaW1wb3J0IHR5cGUge1VuaWZvcm1WYWx1ZXN9IGZyb20gJy4vdW5pZm9ybV9iaW5kaW5nLmpzJztcbmltcG9ydCB0eXBlIHtVbndyYXBwZWRUaWxlSUR9IGZyb20gJy4uL3NvdXJjZS90aWxlX2lkLmpzJztcbmltcG9ydCBQYWludGVyIGZyb20gJy4vcGFpbnRlci5qcyc7XG5pbXBvcnQgRm9nIGZyb20gJy4uL3N0eWxlL2ZvZy5qcyc7XG5pbXBvcnQge1VuaWZvcm0xZiwgVW5pZm9ybTFpLCBVbmlmb3JtMmYsIFVuaWZvcm0zZiwgVW5pZm9ybTRmLCBVbmlmb3JtTWF0cml4NGZ9IGZyb20gJy4vdW5pZm9ybV9iaW5kaW5nLmpzJztcbmltcG9ydCB7Z2xvYmVUb01lcmNhdG9yVHJhbnNpdGlvbn0gZnJvbSAnLi4vZ2VvL3Byb2plY3Rpb24vZ2xvYmVfdXRpbC5qcyc7XG5cbmV4cG9ydCB0eXBlIEZvZ1VuaWZvcm1zVHlwZSA9IHt8XG4gICAgJ3VfZm9nX21hdHJpeCc6IFVuaWZvcm1NYXRyaXg0ZixcbiAgICAndV9mb2dfcmFuZ2UnOiBVbmlmb3JtMmYsXG4gICAgJ3VfZm9nX2NvbG9yJzogVW5pZm9ybTRmLFxuICAgICd1X2ZvZ19ob3Jpem9uX2JsZW5kJzogVW5pZm9ybTFmLFxuICAgICd1X2ZvZ190ZW1wb3JhbF9vZmZzZXQnOiBVbmlmb3JtMWYsXG4gICAgJ3VfZnJ1c3R1bV90bCc6IFVuaWZvcm0zZixcbiAgICAndV9mcnVzdHVtX3RyJzogVW5pZm9ybTNmLFxuICAgICd1X2ZydXN0dW1fYnInOiBVbmlmb3JtM2YsXG4gICAgJ3VfZnJ1c3R1bV9ibCc6IFVuaWZvcm0zZixcbiAgICAndV9nbG9iZV9wb3MnOiBVbmlmb3JtM2YsXG4gICAgJ3VfZ2xvYmVfcmFkaXVzJzogVW5pZm9ybTFmLFxuICAgICd1X2dsb2JlX3RyYW5zaXRpb24nOiBVbmlmb3JtMWYsXG4gICAgJ3VfaXNfZ2xvYmUnOiBVbmlmb3JtMWksXG4gICAgJ3Vfdmlld3BvcnQnOiBVbmlmb3JtMmYsXG58fTtcblxuZXhwb3J0IGNvbnN0IGZvZ1VuaWZvcm1zID0gKGNvbnRleHQ6IENvbnRleHQpOiBGb2dVbmlmb3Jtc1R5cGUgPT4gKHtcbiAgICAndV9mb2dfbWF0cml4JzogbmV3IFVuaWZvcm1NYXRyaXg0Zihjb250ZXh0KSxcbiAgICAndV9mb2dfcmFuZ2UnOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpLFxuICAgICd1X2ZvZ19jb2xvcic6IG5ldyBVbmlmb3JtNGYoY29udGV4dCksXG4gICAgJ3VfZm9nX2hvcml6b25fYmxlbmQnOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X2ZvZ190ZW1wb3JhbF9vZmZzZXQnOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X2ZydXN0dW1fdGwnOiBuZXcgVW5pZm9ybTNmKGNvbnRleHQpLFxuICAgICd1X2ZydXN0dW1fdHInOiBuZXcgVW5pZm9ybTNmKGNvbnRleHQpLFxuICAgICd1X2ZydXN0dW1fYnInOiBuZXcgVW5pZm9ybTNmKGNvbnRleHQpLFxuICAgICd1X2ZydXN0dW1fYmwnOiBuZXcgVW5pZm9ybTNmKGNvbnRleHQpLFxuICAgICd1X2dsb2JlX3Bvcyc6IG5ldyBVbmlmb3JtM2YoY29udGV4dCksXG4gICAgJ3VfZ2xvYmVfcmFkaXVzJzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9nbG9iZV90cmFuc2l0aW9uJzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9pc19nbG9iZSc6IG5ldyBVbmlmb3JtMWkoY29udGV4dCksXG4gICAgJ3Vfdmlld3BvcnQnOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpXG59KTtcblxuZXhwb3J0IGNvbnN0IGZvZ1VuaWZvcm1WYWx1ZXMgPSAoXG4gICAgcGFpbnRlcjogUGFpbnRlcixcbiAgICBmb2c6IEZvZyxcbiAgICB0aWxlSUQ6ID9VbndyYXBwZWRUaWxlSUQsXG4gICAgZm9nT3BhY2l0eTogbnVtYmVyLFxuICAgIGZydXN0dW1EaXJUbDogW251bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgIGZydXN0dW1EaXJUcjogW251bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgIGZydXN0dW1EaXJCcjogW251bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgIGZydXN0dW1EaXJCbDogW251bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgIGdsb2JlUG9zaXRpb246IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICBnbG9iZVJhZGl1czogbnVtYmVyLFxuICAgIHZpZXdwb3J0OiBbbnVtYmVyLCBudW1iZXJdXG4pOiBVbmlmb3JtVmFsdWVzPEZvZ1VuaWZvcm1zVHlwZT4gPT4ge1xuICAgIGNvbnN0IHRyID0gcGFpbnRlci50cmFuc2Zvcm07XG4gICAgY29uc3QgZm9nQ29sb3IgPSBmb2cucHJvcGVydGllcy5nZXQoJ2NvbG9yJykudG9BcnJheTAxKCk7XG4gICAgZm9nQ29sb3JbM10gPSBmb2dPcGFjaXR5OyAvLyBVcGRhdGUgQWxwaGFcbiAgICBjb25zdCB0ZW1wb3JhbE9mZnNldCA9IChwYWludGVyLmZyYW1lQ291bnRlciAvIDEwMDAuMCkgJSAxO1xuICAgIHJldHVybiB7XG4gICAgICAgICd1X2ZvZ19tYXRyaXgnOiB0aWxlSUQgPyB0ci5jYWxjdWxhdGVGb2dUaWxlTWF0cml4KHRpbGVJRCkgOiBwYWludGVyLmlkZW50aXR5TWF0LFxuICAgICAgICAndV9mb2dfcmFuZ2UnOiBmb2cuZ2V0Rm92QWRqdXN0ZWRSYW5nZSh0ci5fZm92KSxcbiAgICAgICAgJ3VfZm9nX2NvbG9yJzogZm9nQ29sb3IsXG4gICAgICAgICd1X2ZvZ19ob3Jpem9uX2JsZW5kJzogZm9nLnByb3BlcnRpZXMuZ2V0KCdob3Jpem9uLWJsZW5kJyksXG4gICAgICAgICd1X2ZvZ190ZW1wb3JhbF9vZmZzZXQnOiB0ZW1wb3JhbE9mZnNldCxcbiAgICAgICAgJ3VfZnJ1c3R1bV90bCc6IGZydXN0dW1EaXJUbCxcbiAgICAgICAgJ3VfZnJ1c3R1bV90cic6IGZydXN0dW1EaXJUcixcbiAgICAgICAgJ3VfZnJ1c3R1bV9icic6IGZydXN0dW1EaXJCcixcbiAgICAgICAgJ3VfZnJ1c3R1bV9ibCc6IGZydXN0dW1EaXJCbCxcbiAgICAgICAgJ3VfZ2xvYmVfcG9zJzogZ2xvYmVQb3NpdGlvbixcbiAgICAgICAgJ3VfZ2xvYmVfcmFkaXVzJzogZ2xvYmVSYWRpdXMsXG4gICAgICAgICd1X3ZpZXdwb3J0Jzogdmlld3BvcnQsXG4gICAgICAgICd1X2dsb2JlX3RyYW5zaXRpb24nOiBnbG9iZVRvTWVyY2F0b3JUcmFuc2l0aW9uKHRyLnpvb20pLFxuICAgICAgICAndV9pc19nbG9iZSc6ICsodHIucHJvamVjdGlvbi5uYW1lID09PSAnZ2xvYmUnKVxuICAgIH07XG59O1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtcbiAgICBwcmVsdWRlLFxuICAgIHByZWx1ZGVGcmFnUHJlY2lzaW9uUXVhbGlmaWVycyxcbiAgICBwcmVsdWRlVmVydFByZWNpc2lvblF1YWxpZmllcnMsXG4gICAgcHJlbHVkZVRlcnJhaW4sXG4gICAgcHJlbHVkZUZvZyxcbiAgICBwcmVsdWRlQ29tbW9uU291cmNlLFxuICAgIHN0YW5kYXJkRGVyaXZhdGl2ZXNFeHRcbn0gZnJvbSAnLi4vc2hhZGVycy9zaGFkZXJzLmpzJztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCBQcm9ncmFtQ29uZmlndXJhdGlvbiBmcm9tICcuLi9kYXRhL3Byb2dyYW1fY29uZmlndXJhdGlvbi5qcyc7XG5pbXBvcnQgVmVydGV4QXJyYXlPYmplY3QgZnJvbSAnLi92ZXJ0ZXhfYXJyYXlfb2JqZWN0LmpzJztcbmltcG9ydCBDb250ZXh0IGZyb20gJy4uL2dsL2NvbnRleHQuanMnO1xuaW1wb3J0IHt0ZXJyYWluVW5pZm9ybXMsIGdsb2JlVW5pZm9ybXN9IGZyb20gJy4uL3RlcnJhaW4vdGVycmFpbi5qcyc7XG5pbXBvcnQgdHlwZSB7VGVycmFpblVuaWZvcm1zVHlwZSwgR2xvYmVVbmlmb3Jtc1R5cGV9IGZyb20gJy4uL3RlcnJhaW4vdGVycmFpbi5qcyc7XG5pbXBvcnQge2ZvZ1VuaWZvcm1zfSBmcm9tICcuL2ZvZy5qcyc7XG5pbXBvcnQgdHlwZSB7Rm9nVW5pZm9ybXNUeXBlfSBmcm9tICcuL2ZvZy5qcyc7XG5cbmltcG9ydCB0eXBlIFNlZ21lbnRWZWN0b3IgZnJvbSAnLi4vZGF0YS9zZWdtZW50LmpzJztcbmltcG9ydCB0eXBlIFZlcnRleEJ1ZmZlciBmcm9tICcuLi9nbC92ZXJ0ZXhfYnVmZmVyLmpzJztcbmltcG9ydCB0eXBlIEluZGV4QnVmZmVyIGZyb20gJy4uL2dsL2luZGV4X2J1ZmZlci5qcyc7XG5pbXBvcnQgdHlwZSBEZXB0aE1vZGUgZnJvbSAnLi4vZ2wvZGVwdGhfbW9kZS5qcyc7XG5pbXBvcnQgdHlwZSBTdGVuY2lsTW9kZSBmcm9tICcuLi9nbC9zdGVuY2lsX21vZGUuanMnO1xuaW1wb3J0IHR5cGUgQ29sb3JNb2RlIGZyb20gJy4uL2dsL2NvbG9yX21vZGUuanMnO1xuaW1wb3J0IHR5cGUgQ3VsbEZhY2VNb2RlIGZyb20gJy4uL2dsL2N1bGxfZmFjZV9tb2RlLmpzJztcbmltcG9ydCB0eXBlIHtVbmlmb3JtQmluZGluZ3MsIFVuaWZvcm1WYWx1ZXN9IGZyb20gJy4vdW5pZm9ybV9iaW5kaW5nLmpzJztcbmltcG9ydCB0eXBlIHtCaW5kZXJVbmlmb3JtfSBmcm9tICcuLi9kYXRhL3Byb2dyYW1fY29uZmlndXJhdGlvbi5qcyc7XG5cbmV4cG9ydCB0eXBlIERyYXdNb2RlID1cbiAgICB8ICRQcm9wZXJ0eVR5cGU8V2ViR0xSZW5kZXJpbmdDb250ZXh0LCAnTElORVMnPlxuICAgIHwgJFByb3BlcnR5VHlwZTxXZWJHTFJlbmRlcmluZ0NvbnRleHQsICdUUklBTkdMRVMnPlxuICAgIHwgJFByb3BlcnR5VHlwZTxXZWJHTFJlbmRlcmluZ0NvbnRleHQsICdMSU5FX1NUUklQJz47XG5cbnR5cGUgU2hhZGVyU291cmNlID0ge1xuICAgIGZyYWdtZW50U291cmNlOiBzdHJpbmcsXG4gICAgdmVydGV4U291cmNlOiBzdHJpbmcsXG4gICAgc3RhdGljQXR0cmlidXRlczogQXJyYXk8c3RyaW5nPixcbiAgICB1c2VkRGVmaW5lczogQXJyYXk8c3RyaW5nPlxufTtcblxuZnVuY3Rpb24gZ2V0VG9rZW5pemVkQXR0cmlidXRlcyhhcnJheTogQXJyYXk8c3RyaW5nPik6IEFycmF5PHN0cmluZz4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoYXJyYXlbaV0gPT09IG51bGwpIGNvbnRpbnVlO1xuICAgICAgICBjb25zdCB0b2tlbiA9IGFycmF5W2ldLnNwbGl0KCcgJyk7XG4gICAgICAgIHJlc3VsdC5wdXNoKHRva2VuLnBvcCgpKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuY2xhc3MgUHJvZ3JhbTxVczogVW5pZm9ybUJpbmRpbmdzPiB7XG4gICAgcHJvZ3JhbTogV2ViR0xQcm9ncmFtO1xuICAgIGF0dHJpYnV0ZXM6IHtbXzogc3RyaW5nXTogbnVtYmVyfTtcbiAgICBudW1BdHRyaWJ1dGVzOiBudW1iZXI7XG4gICAgZml4ZWRVbmlmb3JtczogVXM7XG4gICAgYmluZGVyVW5pZm9ybXM6IEFycmF5PEJpbmRlclVuaWZvcm0+O1xuICAgIGZhaWxlZFRvQ3JlYXRlOiBib29sZWFuO1xuICAgIHRlcnJhaW5Vbmlmb3JtczogP1RlcnJhaW5Vbmlmb3Jtc1R5cGU7XG4gICAgZm9nVW5pZm9ybXM6ID9Gb2dVbmlmb3Jtc1R5cGU7XG4gICAgZ2xvYmVVbmlmb3JtczogP0dsb2JlVW5pZm9ybXNUeXBlO1xuXG4gICAgc3RhdGljIGNhY2hlS2V5KHNvdXJjZTogU2hhZGVyU291cmNlLCBuYW1lOiBzdHJpbmcsIGRlZmluZXM6IHN0cmluZ1tdLCBwcm9ncmFtQ29uZmlndXJhdGlvbjogP1Byb2dyYW1Db25maWd1cmF0aW9uKTogc3RyaW5nIHtcbiAgICAgICAgbGV0IGtleSA9IGAke25hbWV9JHtwcm9ncmFtQ29uZmlndXJhdGlvbiA/IHByb2dyYW1Db25maWd1cmF0aW9uLmNhY2hlS2V5IDogJyd9YDtcbiAgICAgICAgZm9yIChjb25zdCBkZWZpbmUgb2YgZGVmaW5lcykge1xuICAgICAgICAgICAgaWYgKHNvdXJjZS51c2VkRGVmaW5lcy5pbmNsdWRlcyhkZWZpbmUpKSB7XG4gICAgICAgICAgICAgICAga2V5ICs9IGAvJHtkZWZpbmV9YDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ga2V5O1xuICAgIH1cblxuICAgIGNvbnN0cnVjdG9yKGNvbnRleHQ6IENvbnRleHQsXG4gICAgICAgICAgICAgICAgbmFtZTogc3RyaW5nLFxuICAgICAgICAgICAgICAgIHNvdXJjZTogU2hhZGVyU291cmNlLFxuICAgICAgICAgICAgICAgIGNvbmZpZ3VyYXRpb246ID9Qcm9ncmFtQ29uZmlndXJhdGlvbixcbiAgICAgICAgICAgICAgICBmaXhlZFVuaWZvcm1zOiAoQ29udGV4dCkgPT4gVXMsXG4gICAgICAgICAgICAgICAgZml4ZWREZWZpbmVzOiBzdHJpbmdbXSkge1xuICAgICAgICBjb25zdCBnbCA9IGNvbnRleHQuZ2w7XG4gICAgICAgIHRoaXMucHJvZ3JhbSA9ICgoZ2wuY3JlYXRlUHJvZ3JhbSgpOiBhbnkpOiBXZWJHTFByb2dyYW0pO1xuXG4gICAgICAgIGNvbnN0IHN0YXRpY0F0dHJJbmZvID0gZ2V0VG9rZW5pemVkQXR0cmlidXRlcyhzb3VyY2Uuc3RhdGljQXR0cmlidXRlcyk7XG4gICAgICAgIGNvbnN0IGR5bmFtaWNBdHRySW5mbyA9IGNvbmZpZ3VyYXRpb24gPyBjb25maWd1cmF0aW9uLmdldEJpbmRlckF0dHJpYnV0ZXMoKSA6IFtdO1xuICAgICAgICBjb25zdCBhbGxBdHRySW5mbyA9IHN0YXRpY0F0dHJJbmZvLmNvbmNhdChkeW5hbWljQXR0ckluZm8pO1xuXG4gICAgICAgIGxldCBkZWZpbmVzID0gY29uZmlndXJhdGlvbiA/IGNvbmZpZ3VyYXRpb24uZGVmaW5lcygpIDogW107XG4gICAgICAgIGRlZmluZXMgPSBkZWZpbmVzLmNvbmNhdChmaXhlZERlZmluZXMubWFwKChkZWZpbmUpID0+IGAjZGVmaW5lICR7ZGVmaW5lfWApKTtcbiAgICAgICAgY29uc3QgdmVyc2lvbiA9IGNvbnRleHQuaXNXZWJHTDIgPyAnI3ZlcnNpb24gMzAwIGVzXFxuJyA6ICcnO1xuXG4gICAgICAgIGNvbnN0IGZyYWdtZW50U291cmNlID0gdmVyc2lvbiArIGRlZmluZXMuY29uY2F0KFxuICAgICAgICAgICAgY29udGV4dC5leHRTdGFuZGFyZERlcml2YXRpdmVzICYmIHZlcnNpb24ubGVuZ3RoID09PSAwID8gc3RhbmRhcmREZXJpdmF0aXZlc0V4dC5jb25jYXQocHJlbHVkZUZyYWdQcmVjaXNpb25RdWFsaWZpZXJzKSA6IHByZWx1ZGVGcmFnUHJlY2lzaW9uUXVhbGlmaWVycyxcbiAgICAgICAgICAgIHByZWx1ZGVGcmFnUHJlY2lzaW9uUXVhbGlmaWVycyxcbiAgICAgICAgICAgIHByZWx1ZGVDb21tb25Tb3VyY2UsXG4gICAgICAgICAgICBwcmVsdWRlLmZyYWdtZW50U291cmNlLFxuICAgICAgICAgICAgcHJlbHVkZUZvZy5mcmFnbWVudFNvdXJjZSxcbiAgICAgICAgICAgIHNvdXJjZS5mcmFnbWVudFNvdXJjZSkuam9pbignXFxuJyk7XG4gICAgICAgIGNvbnN0IHZlcnRleFNvdXJjZSA9IHZlcnNpb24gKyBkZWZpbmVzLmNvbmNhdChcbiAgICAgICAgICAgIHByZWx1ZGVWZXJ0UHJlY2lzaW9uUXVhbGlmaWVycyxcbiAgICAgICAgICAgIHByZWx1ZGVDb21tb25Tb3VyY2UsXG4gICAgICAgICAgICBwcmVsdWRlLnZlcnRleFNvdXJjZSxcbiAgICAgICAgICAgIHByZWx1ZGVGb2cudmVydGV4U291cmNlLFxuICAgICAgICAgICAgcHJlbHVkZVRlcnJhaW4udmVydGV4U291cmNlLFxuICAgICAgICAgICAgc291cmNlLnZlcnRleFNvdXJjZSkuam9pbignXFxuJyk7XG5cbiAgICAgICAgY29uc3QgZnJhZ21lbnRTaGFkZXIgPSAoKGdsLmNyZWF0ZVNoYWRlcihnbC5GUkFHTUVOVF9TSEFERVIpOiBhbnkpOiBXZWJHTFNoYWRlcik7XG4gICAgICAgIGlmIChnbC5pc0NvbnRleHRMb3N0KCkpIHtcbiAgICAgICAgICAgIHRoaXMuZmFpbGVkVG9DcmVhdGUgPSB0cnVlO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGdsLnNoYWRlclNvdXJjZShmcmFnbWVudFNoYWRlciwgZnJhZ21lbnRTb3VyY2UpO1xuICAgICAgICBnbC5jb21waWxlU2hhZGVyKGZyYWdtZW50U2hhZGVyKTtcbiAgICAgICAgYXNzZXJ0KGdsLmdldFNoYWRlclBhcmFtZXRlcihmcmFnbWVudFNoYWRlciwgZ2wuQ09NUElMRV9TVEFUVVMpLCAoZ2wuZ2V0U2hhZGVySW5mb0xvZyhmcmFnbWVudFNoYWRlcik6IGFueSkpO1xuICAgICAgICBnbC5hdHRhY2hTaGFkZXIodGhpcy5wcm9ncmFtLCBmcmFnbWVudFNoYWRlcik7XG5cbiAgICAgICAgY29uc3QgdmVydGV4U2hhZGVyID0gKChnbC5jcmVhdGVTaGFkZXIoZ2wuVkVSVEVYX1NIQURFUik6IGFueSk6IFdlYkdMU2hhZGVyKTtcbiAgICAgICAgaWYgKGdsLmlzQ29udGV4dExvc3QoKSkge1xuICAgICAgICAgICAgdGhpcy5mYWlsZWRUb0NyZWF0ZSA9IHRydWU7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgZ2wuc2hhZGVyU291cmNlKHZlcnRleFNoYWRlciwgdmVydGV4U291cmNlKTtcbiAgICAgICAgZ2wuY29tcGlsZVNoYWRlcih2ZXJ0ZXhTaGFkZXIpO1xuICAgICAgICBhc3NlcnQoZ2wuZ2V0U2hhZGVyUGFyYW1ldGVyKHZlcnRleFNoYWRlciwgZ2wuQ09NUElMRV9TVEFUVVMpLCAoZ2wuZ2V0U2hhZGVySW5mb0xvZyh2ZXJ0ZXhTaGFkZXIpOiBhbnkpKTtcbiAgICAgICAgZ2wuYXR0YWNoU2hhZGVyKHRoaXMucHJvZ3JhbSwgdmVydGV4U2hhZGVyKTtcblxuICAgICAgICB0aGlzLmF0dHJpYnV0ZXMgPSB7fTtcblxuICAgICAgICB0aGlzLm51bUF0dHJpYnV0ZXMgPSBhbGxBdHRySW5mby5sZW5ndGg7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm51bUF0dHJpYnV0ZXM7IGkrKykge1xuICAgICAgICAgICAgaWYgKGFsbEF0dHJJbmZvW2ldKSB7XG4gICAgICAgICAgICAgICAgZ2wuYmluZEF0dHJpYkxvY2F0aW9uKHRoaXMucHJvZ3JhbSwgaSwgYWxsQXR0ckluZm9baV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuYXR0cmlidXRlc1thbGxBdHRySW5mb1tpXV0gPSBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZ2wubGlua1Byb2dyYW0odGhpcy5wcm9ncmFtKTtcbiAgICAgICAgYXNzZXJ0KGdsLmdldFByb2dyYW1QYXJhbWV0ZXIodGhpcy5wcm9ncmFtLCBnbC5MSU5LX1NUQVRVUyksIChnbC5nZXRQcm9ncmFtSW5mb0xvZyh0aGlzLnByb2dyYW0pOiBhbnkpKTtcblxuICAgICAgICBnbC5kZWxldGVTaGFkZXIodmVydGV4U2hhZGVyKTtcbiAgICAgICAgZ2wuZGVsZXRlU2hhZGVyKGZyYWdtZW50U2hhZGVyKTtcblxuICAgICAgICB0aGlzLmZpeGVkVW5pZm9ybXMgPSBmaXhlZFVuaWZvcm1zKGNvbnRleHQpO1xuICAgICAgICB0aGlzLmJpbmRlclVuaWZvcm1zID0gY29uZmlndXJhdGlvbiA/IGNvbmZpZ3VyYXRpb24uZ2V0VW5pZm9ybXMoY29udGV4dCkgOiBbXTtcbiAgICAgICAgaWYgKGZpeGVkRGVmaW5lcy5pbmNsdWRlcygnVEVSUkFJTicpKSB7XG4gICAgICAgICAgICB0aGlzLnRlcnJhaW5Vbmlmb3JtcyA9IHRlcnJhaW5Vbmlmb3Jtcyhjb250ZXh0KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZml4ZWREZWZpbmVzLmluY2x1ZGVzKCdHTE9CRScpKSB7XG4gICAgICAgICAgICB0aGlzLmdsb2JlVW5pZm9ybXMgPSBnbG9iZVVuaWZvcm1zKGNvbnRleHQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmaXhlZERlZmluZXMuaW5jbHVkZXMoJ0ZPRycpKSB7XG4gICAgICAgICAgICB0aGlzLmZvZ1VuaWZvcm1zID0gZm9nVW5pZm9ybXMoY29udGV4dCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRUZXJyYWluVW5pZm9ybVZhbHVlcyhjb250ZXh0OiBDb250ZXh0LCB0ZXJyYWluVW5pZm9ybVZhbHVlczogVW5pZm9ybVZhbHVlczxUZXJyYWluVW5pZm9ybXNUeXBlPikge1xuICAgICAgICBpZiAoIXRoaXMudGVycmFpblVuaWZvcm1zKSByZXR1cm47XG4gICAgICAgIGNvbnN0IHVuaWZvcm1zOiBUZXJyYWluVW5pZm9ybXNUeXBlID0gdGhpcy50ZXJyYWluVW5pZm9ybXM7XG5cbiAgICAgICAgaWYgKHRoaXMuZmFpbGVkVG9DcmVhdGUpIHJldHVybjtcbiAgICAgICAgY29udGV4dC5wcm9ncmFtLnNldCh0aGlzLnByb2dyYW0pO1xuXG4gICAgICAgIGZvciAoY29uc3QgbmFtZSBpbiB0ZXJyYWluVW5pZm9ybVZhbHVlcykge1xuICAgICAgICAgICAgaWYgKHVuaWZvcm1zW25hbWVdKSB7XG4gICAgICAgICAgICAgICAgdW5pZm9ybXNbbmFtZV0uc2V0KHRoaXMucHJvZ3JhbSwgbmFtZSwgdGVycmFpblVuaWZvcm1WYWx1ZXNbbmFtZV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0R2xvYmVVbmlmb3JtVmFsdWVzKGNvbnRleHQ6IENvbnRleHQsIGdsb2JlVW5pZm9ybVZhbHVlczogVW5pZm9ybVZhbHVlczxHbG9iZVVuaWZvcm1zVHlwZT4pIHtcbiAgICAgICAgaWYgKCF0aGlzLmdsb2JlVW5pZm9ybXMpIHJldHVybjtcbiAgICAgICAgY29uc3QgdW5pZm9ybXM6IEdsb2JlVW5pZm9ybXNUeXBlID0gdGhpcy5nbG9iZVVuaWZvcm1zO1xuXG4gICAgICAgIGlmICh0aGlzLmZhaWxlZFRvQ3JlYXRlKSByZXR1cm47XG4gICAgICAgIGNvbnRleHQucHJvZ3JhbS5zZXQodGhpcy5wcm9ncmFtKTtcblxuICAgICAgICBmb3IgKGNvbnN0IG5hbWUgaW4gZ2xvYmVVbmlmb3JtVmFsdWVzKSB7XG4gICAgICAgICAgICBpZiAodW5pZm9ybXNbbmFtZV0pIHtcbiAgICAgICAgICAgICAgICB1bmlmb3Jtc1tuYW1lXS5zZXQodGhpcy5wcm9ncmFtLCBuYW1lLCBnbG9iZVVuaWZvcm1WYWx1ZXNbbmFtZV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0Rm9nVW5pZm9ybVZhbHVlcyhjb250ZXh0OiBDb250ZXh0LCBmb2dVbmlmb3Jtc1ZhbHVlczogVW5pZm9ybVZhbHVlczxGb2dVbmlmb3Jtc1R5cGU+KSB7XG4gICAgICAgIGlmICghdGhpcy5mb2dVbmlmb3JtcykgcmV0dXJuO1xuICAgICAgICBjb25zdCB1bmlmb3JtczogRm9nVW5pZm9ybXNUeXBlID0gdGhpcy5mb2dVbmlmb3JtcztcblxuICAgICAgICBpZiAodGhpcy5mYWlsZWRUb0NyZWF0ZSkgcmV0dXJuO1xuICAgICAgICBjb250ZXh0LnByb2dyYW0uc2V0KHRoaXMucHJvZ3JhbSk7XG5cbiAgICAgICAgZm9yIChjb25zdCBuYW1lIGluIGZvZ1VuaWZvcm1zVmFsdWVzKSB7XG4gICAgICAgICAgICB1bmlmb3Jtc1tuYW1lXS5zZXQodGhpcy5wcm9ncmFtLCBuYW1lLCBmb2dVbmlmb3Jtc1ZhbHVlc1tuYW1lXSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBkcmF3KFxuICAgICAgICAgY29udGV4dDogQ29udGV4dCxcbiAgICAgICAgIGRyYXdNb2RlOiBEcmF3TW9kZSxcbiAgICAgICAgIGRlcHRoTW9kZTogJFJlYWRPbmx5PERlcHRoTW9kZT4sXG4gICAgICAgICBzdGVuY2lsTW9kZTogJFJlYWRPbmx5PFN0ZW5jaWxNb2RlPixcbiAgICAgICAgIGNvbG9yTW9kZTogJFJlYWRPbmx5PENvbG9yTW9kZT4sXG4gICAgICAgICBjdWxsRmFjZU1vZGU6ICRSZWFkT25seTxDdWxsRmFjZU1vZGU+LFxuICAgICAgICAgdW5pZm9ybVZhbHVlczogVW5pZm9ybVZhbHVlczxVcz4sXG4gICAgICAgICBsYXllcklEOiBzdHJpbmcsXG4gICAgICAgICBsYXlvdXRWZXJ0ZXhCdWZmZXI6IFZlcnRleEJ1ZmZlcixcbiAgICAgICAgIGluZGV4QnVmZmVyOiBJbmRleEJ1ZmZlcixcbiAgICAgICAgIHNlZ21lbnRzOiBTZWdtZW50VmVjdG9yLFxuICAgICAgICAgY3VycmVudFByb3BlcnRpZXM6IGFueSxcbiAgICAgICAgIHpvb206ID9udW1iZXIsXG4gICAgICAgICBjb25maWd1cmF0aW9uOiA/UHJvZ3JhbUNvbmZpZ3VyYXRpb24sXG4gICAgICAgICBkeW5hbWljTGF5b3V0QnVmZmVyczogP0FycmF5PD9WZXJ0ZXhCdWZmZXI+KSB7XG5cbiAgICAgICAgY29uc3QgZ2wgPSBjb250ZXh0LmdsO1xuXG4gICAgICAgIGlmICh0aGlzLmZhaWxlZFRvQ3JlYXRlKSByZXR1cm47XG5cbiAgICAgICAgY29udGV4dC5wcm9ncmFtLnNldCh0aGlzLnByb2dyYW0pO1xuICAgICAgICBjb250ZXh0LnNldERlcHRoTW9kZShkZXB0aE1vZGUpO1xuICAgICAgICBjb250ZXh0LnNldFN0ZW5jaWxNb2RlKHN0ZW5jaWxNb2RlKTtcbiAgICAgICAgY29udGV4dC5zZXRDb2xvck1vZGUoY29sb3JNb2RlKTtcbiAgICAgICAgY29udGV4dC5zZXRDdWxsRmFjZShjdWxsRmFjZU1vZGUpO1xuXG4gICAgICAgIGZvciAoY29uc3QgbmFtZSBvZiBPYmplY3Qua2V5cyh0aGlzLmZpeGVkVW5pZm9ybXMpKSB7XG4gICAgICAgICAgICB0aGlzLmZpeGVkVW5pZm9ybXNbbmFtZV0uc2V0KHRoaXMucHJvZ3JhbSwgbmFtZSwgdW5pZm9ybVZhbHVlc1tuYW1lXSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29uZmlndXJhdGlvbikge1xuICAgICAgICAgICAgY29uZmlndXJhdGlvbi5zZXRVbmlmb3Jtcyh0aGlzLnByb2dyYW0sIGNvbnRleHQsIHRoaXMuYmluZGVyVW5pZm9ybXMsIGN1cnJlbnRQcm9wZXJ0aWVzLCB7em9vbTogKHpvb206IGFueSl9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHByaW1pdGl2ZVNpemUgPSB7XG4gICAgICAgICAgICBbZ2wuTElORVNdOiAyLFxuICAgICAgICAgICAgW2dsLlRSSUFOR0xFU106IDMsXG4gICAgICAgICAgICBbZ2wuTElORV9TVFJJUF06IDFcbiAgICAgICAgfVtkcmF3TW9kZV07XG5cbiAgICAgICAgZm9yIChjb25zdCBzZWdtZW50IG9mIHNlZ21lbnRzLmdldCgpKSB7XG4gICAgICAgICAgICBjb25zdCB2YW9zID0gc2VnbWVudC52YW9zIHx8IChzZWdtZW50LnZhb3MgPSB7fSk7XG4gICAgICAgICAgICBjb25zdCB2YW86IFZlcnRleEFycmF5T2JqZWN0ID0gdmFvc1tsYXllcklEXSB8fCAodmFvc1tsYXllcklEXSA9IG5ldyBWZXJ0ZXhBcnJheU9iamVjdCgpKTtcblxuICAgICAgICAgICAgdmFvLmJpbmQoXG4gICAgICAgICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICAgICAgICB0aGlzLFxuICAgICAgICAgICAgICAgIGxheW91dFZlcnRleEJ1ZmZlcixcbiAgICAgICAgICAgICAgICBjb25maWd1cmF0aW9uID8gY29uZmlndXJhdGlvbi5nZXRQYWludFZlcnRleEJ1ZmZlcnMoKSA6IFtdLFxuICAgICAgICAgICAgICAgIGluZGV4QnVmZmVyLFxuICAgICAgICAgICAgICAgIHNlZ21lbnQudmVydGV4T2Zmc2V0LFxuICAgICAgICAgICAgICAgIGR5bmFtaWNMYXlvdXRCdWZmZXJzID8gZHluYW1pY0xheW91dEJ1ZmZlcnMgOiBbXVxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgZ2wuZHJhd0VsZW1lbnRzKFxuICAgICAgICAgICAgICAgIGRyYXdNb2RlLFxuICAgICAgICAgICAgICAgIHNlZ21lbnQucHJpbWl0aXZlTGVuZ3RoICogcHJpbWl0aXZlU2l6ZSxcbiAgICAgICAgICAgICAgICBnbC5VTlNJR05FRF9TSE9SVCxcbiAgICAgICAgICAgICAgICBzZWdtZW50LnByaW1pdGl2ZU9mZnNldCAqIHByaW1pdGl2ZVNpemUgKiAyKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUHJvZ3JhbTtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCB7XG4gICAgVW5pZm9ybTFpLFxuICAgIFVuaWZvcm0xZixcbiAgICBVbmlmb3JtMmZcbn0gZnJvbSAnLi4vdW5pZm9ybV9iaW5kaW5nLmpzJztcbmltcG9ydCBwaXhlbHNUb1RpbGVVbml0cyBmcm9tICcuLi8uLi9zb3VyY2UvcGl4ZWxzX3RvX3RpbGVfdW5pdHMuanMnO1xuXG5pbXBvcnQgdHlwZSBQYWludGVyIGZyb20gJy4uL3BhaW50ZXIuanMnO1xuaW1wb3J0IHR5cGUge092ZXJzY2FsZWRUaWxlSUR9IGZyb20gJy4uLy4uL3NvdXJjZS90aWxlX2lkLmpzJztcbmltcG9ydCB0eXBlIHtVbmlmb3JtVmFsdWVzfSBmcm9tICcuLi91bmlmb3JtX2JpbmRpbmcuanMnO1xuaW1wb3J0IHR5cGUgVGlsZSBmcm9tICcuLi8uLi9zb3VyY2UvdGlsZS5qcyc7XG5pbXBvcnQgdHlwZSBSZXNvbHZlZEltYWdlIGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi90eXBlcy9yZXNvbHZlZF9pbWFnZS5qcyc7XG5cbnR5cGUgQmFja2dyb3VuZFBhdHRlcm5Vbmlmb3Jtc1R5cGUgPSB7fFxuICAgICd1X2ltYWdlJzogVW5pZm9ybTFpLFxuICAgICd1X3BhdHRlcm5fdGwnOiBVbmlmb3JtMmYsXG4gICAgJ3VfcGF0dGVybl9icic6IFVuaWZvcm0yZixcbiAgICAndV90ZXhzaXplJzogVW5pZm9ybTJmLFxuICAgICd1X3BhdHRlcm5fc2l6ZSc6IFVuaWZvcm0yZixcbiAgICAndV9waXhlbF9jb29yZF91cHBlcic6IFVuaWZvcm0yZixcbiAgICAndV9waXhlbF9jb29yZF9sb3dlcic6IFVuaWZvcm0yZixcbiAgICAndV90aWxlX3VuaXRzX3RvX3BpeGVscyc6IFVuaWZvcm0xZlxufH07XG5cbmV4cG9ydCB0eXBlIFBhdHRlcm5Vbmlmb3Jtc1R5cGUgPSB7fFxuICAgICd1X2ltYWdlJzogVW5pZm9ybTFpLFxuICAgICd1X3RleHNpemUnOiBVbmlmb3JtMmYsXG4gICAgJ3VfdGlsZV91bml0c190b19waXhlbHMnOiBVbmlmb3JtMWYsXG4gICAgJ3VfcGl4ZWxfY29vcmRfdXBwZXInOiBVbmlmb3JtMmYsXG4gICAgJ3VfcGl4ZWxfY29vcmRfbG93ZXInOiBVbmlmb3JtMmZcbnx9O1xuXG5mdW5jdGlvbiBwYXR0ZXJuVW5pZm9ybVZhbHVlcyhwYWludGVyOiBQYWludGVyLCB0aWxlOiBUaWxlKTogVW5pZm9ybVZhbHVlczxQYXR0ZXJuVW5pZm9ybXNUeXBlPiB7XG5cbiAgICBjb25zdCBudW1UaWxlcyA9IE1hdGgucG93KDIsIHRpbGUudGlsZUlELm92ZXJzY2FsZWRaKTtcbiAgICBjb25zdCB0aWxlU2l6ZUF0TmVhcmVzdFpvb20gPSB0aWxlLnRpbGVTaXplICogTWF0aC5wb3coMiwgcGFpbnRlci50cmFuc2Zvcm0udGlsZVpvb20pIC8gbnVtVGlsZXM7XG5cbiAgICBjb25zdCBwaXhlbFggPSB0aWxlU2l6ZUF0TmVhcmVzdFpvb20gKiAodGlsZS50aWxlSUQuY2Fub25pY2FsLnggKyB0aWxlLnRpbGVJRC53cmFwICogbnVtVGlsZXMpO1xuICAgIGNvbnN0IHBpeGVsWSA9IHRpbGVTaXplQXROZWFyZXN0Wm9vbSAqIHRpbGUudGlsZUlELmNhbm9uaWNhbC55O1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgJ3VfaW1hZ2UnOiAwLFxuICAgICAgICAndV90ZXhzaXplJzogdGlsZS5pbWFnZUF0bGFzVGV4dHVyZS5zaXplLFxuICAgICAgICAndV90aWxlX3VuaXRzX3RvX3BpeGVscyc6IDEgLyBwaXhlbHNUb1RpbGVVbml0cyh0aWxlLCAxLCBwYWludGVyLnRyYW5zZm9ybS50aWxlWm9vbSksXG4gICAgICAgIC8vIHNwbGl0IHRoZSBwaXhlbCBjb29yZCBpbnRvIHR3byBwYWlycyBvZiAxNiBiaXQgbnVtYmVycy4gVGhlIGdsc2wgc3BlYyBvbmx5IGd1YXJhbnRlZXMgMTYgYml0cyBvZiBwcmVjaXNpb24uXG4gICAgICAgICd1X3BpeGVsX2Nvb3JkX3VwcGVyJzogW3BpeGVsWCA+PiAxNiwgcGl4ZWxZID4+IDE2XSxcbiAgICAgICAgJ3VfcGl4ZWxfY29vcmRfbG93ZXInOiBbcGl4ZWxYICYgMHhGRkZGLCBwaXhlbFkgJiAweEZGRkZdXG4gICAgfTtcbn1cblxuZnVuY3Rpb24gYmdQYXR0ZXJuVW5pZm9ybVZhbHVlcyhpbWFnZTogUmVzb2x2ZWRJbWFnZSwgcGFpbnRlcjogUGFpbnRlcixcbiAgICAgICAgdGlsZToge3RpbGVJRDogT3ZlcnNjYWxlZFRpbGVJRCwgdGlsZVNpemU6IG51bWJlcn1cbik6IFVuaWZvcm1WYWx1ZXM8QmFja2dyb3VuZFBhdHRlcm5Vbmlmb3Jtc1R5cGU+IHtcblxuICAgIGNvbnN0IGltYWdlUG9zID0gcGFpbnRlci5pbWFnZU1hbmFnZXIuZ2V0UGF0dGVybihpbWFnZS50b1N0cmluZygpKTtcbiAgICBhc3NlcnQoaW1hZ2VQb3MpO1xuICAgIGNvbnN0IHt3aWR0aCwgaGVpZ2h0fSA9IHBhaW50ZXIuaW1hZ2VNYW5hZ2VyLmdldFBpeGVsU2l6ZSgpO1xuXG4gICAgY29uc3QgbnVtVGlsZXMgPSBNYXRoLnBvdygyLCB0aWxlLnRpbGVJRC5vdmVyc2NhbGVkWik7XG4gICAgY29uc3QgdGlsZVNpemVBdE5lYXJlc3Rab29tID0gdGlsZS50aWxlU2l6ZSAqIE1hdGgucG93KDIsIHBhaW50ZXIudHJhbnNmb3JtLnRpbGVab29tKSAvIG51bVRpbGVzO1xuXG4gICAgY29uc3QgcGl4ZWxYID0gdGlsZVNpemVBdE5lYXJlc3Rab29tICogKHRpbGUudGlsZUlELmNhbm9uaWNhbC54ICsgdGlsZS50aWxlSUQud3JhcCAqIG51bVRpbGVzKTtcbiAgICBjb25zdCBwaXhlbFkgPSB0aWxlU2l6ZUF0TmVhcmVzdFpvb20gKiB0aWxlLnRpbGVJRC5jYW5vbmljYWwueTtcblxuICAgIHJldHVybiB7XG4gICAgICAgICd1X2ltYWdlJzogMCxcbiAgICAgICAgJ3VfcGF0dGVybl90bCc6IChpbWFnZVBvczogYW55KS50bCxcbiAgICAgICAgJ3VfcGF0dGVybl9icic6IChpbWFnZVBvczogYW55KS5icixcbiAgICAgICAgJ3VfdGV4c2l6ZSc6IFt3aWR0aCwgaGVpZ2h0XSxcbiAgICAgICAgJ3VfcGF0dGVybl9zaXplJzogKGltYWdlUG9zOiBhbnkpLmRpc3BsYXlTaXplLFxuICAgICAgICAndV90aWxlX3VuaXRzX3RvX3BpeGVscyc6IDEgLyBwaXhlbHNUb1RpbGVVbml0cyh0aWxlLCAxLCBwYWludGVyLnRyYW5zZm9ybS50aWxlWm9vbSksXG4gICAgICAgIC8vIHNwbGl0IHRoZSBwaXhlbCBjb29yZCBpbnRvIHR3byBwYWlycyBvZiAxNiBiaXQgbnVtYmVycy4gVGhlIGdsc2wgc3BlYyBvbmx5IGd1YXJhbnRlZXMgMTYgYml0cyBvZiBwcmVjaXNpb24uXG4gICAgICAgICd1X3BpeGVsX2Nvb3JkX3VwcGVyJzogW3BpeGVsWCA+PiAxNiwgcGl4ZWxZID4+IDE2XSxcbiAgICAgICAgJ3VfcGl4ZWxfY29vcmRfbG93ZXInOiBbcGl4ZWxYICYgMHhGRkZGLCBwaXhlbFkgJiAweEZGRkZdXG4gICAgfTtcbn1cbmV4cG9ydCB7YmdQYXR0ZXJuVW5pZm9ybVZhbHVlcywgcGF0dGVyblVuaWZvcm1WYWx1ZXN9O1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtwYXR0ZXJuVW5pZm9ybVZhbHVlc30gZnJvbSAnLi9wYXR0ZXJuLmpzJztcbmltcG9ydCB7XG4gICAgVW5pZm9ybTFpLFxuICAgIFVuaWZvcm0xZixcbiAgICBVbmlmb3JtMmYsXG4gICAgVW5pZm9ybTNmLFxuICAgIFVuaWZvcm1NYXRyaXg0ZlxufSBmcm9tICcuLi91bmlmb3JtX2JpbmRpbmcuanMnO1xuaW1wb3J0IHttYXQzLCBtYXQ0LCB2ZWMzfSBmcm9tICdnbC1tYXRyaXgnO1xuaW1wb3J0IHtleHRlbmR9IGZyb20gJy4uLy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQgdHlwZSBDb250ZXh0IGZyb20gJy4uLy4uL2dsL2NvbnRleHQuanMnO1xuaW1wb3J0IHR5cGUgUGFpbnRlciBmcm9tICcuLi9wYWludGVyLmpzJztcbmltcG9ydCB0eXBlIHtVbmlmb3JtVmFsdWVzfSBmcm9tICcuLi91bmlmb3JtX2JpbmRpbmcuanMnO1xuaW1wb3J0IHR5cGUgVGlsZSBmcm9tICcuLi8uLi9zb3VyY2UvdGlsZS5qcyc7XG5pbXBvcnQge0Nhbm9uaWNhbFRpbGVJRCwgT3ZlcnNjYWxlZFRpbGVJRH0gZnJvbSAnLi4vLi4vc291cmNlL3RpbGVfaWQuanMnO1xuaW1wb3J0IEVYVEVOVCBmcm9tICcuLi8uLi9kYXRhL2V4dGVudC5qcyc7XG5cbmV4cG9ydCB0eXBlIEZpbGxFeHRydXNpb25Vbmlmb3Jtc1R5cGUgPSB7fFxuICAgICd1X21hdHJpeCc6IFVuaWZvcm1NYXRyaXg0ZixcbiAgICAndV9saWdodHBvcyc6IFVuaWZvcm0zZixcbiAgICAndV9saWdodGludGVuc2l0eSc6IFVuaWZvcm0xZixcbiAgICAndV9saWdodGNvbG9yJzogVW5pZm9ybTNmLFxuICAgICd1X3ZlcnRpY2FsX2dyYWRpZW50JzogVW5pZm9ybTFmLFxuICAgICd1X29wYWNpdHknOiBVbmlmb3JtMWYsXG4gICAgLy8gZ2xvYmUgdW5pZm9ybXM6XG4gICAgJ3VfdGlsZV9pZCc6IFVuaWZvcm0zZixcbiAgICAndV96b29tX3RyYW5zaXRpb24nOiBVbmlmb3JtMWYsXG4gICAgJ3VfaW52X3JvdF9tYXRyaXgnOiBVbmlmb3JtTWF0cml4NGYsXG4gICAgJ3VfbWVyY19jZW50ZXInOiBVbmlmb3JtMmYsXG4gICAgJ3VfdXBfZGlyJzogVW5pZm9ybTNmLFxuICAgICd1X2hlaWdodF9saWZ0JzogVW5pZm9ybTFmLFxuICAgICd1X2FvJzogVW5pZm9ybTJmLFxuICAgICd1X2VkZ2VfcmFkaXVzJzogVW5pZm9ybTFmXG58fTtcblxuZXhwb3J0IHR5cGUgRmlsbEV4dHJ1c2lvblBhdHRlcm5Vbmlmb3Jtc1R5cGUgPSB7fFxuICAgICd1X21hdHJpeCc6IFVuaWZvcm1NYXRyaXg0ZixcbiAgICAndV9saWdodHBvcyc6IFVuaWZvcm0zZixcbiAgICAndV9saWdodGludGVuc2l0eSc6IFVuaWZvcm0xZixcbiAgICAndV9saWdodGNvbG9yJzogVW5pZm9ybTNmLFxuICAgICd1X2hlaWdodF9mYWN0b3InOiBVbmlmb3JtMWYsXG4gICAgJ3VfdmVydGljYWxfZ3JhZGllbnQnOiBVbmlmb3JtMWYsXG4gICAgJ3VfYW8nOiBVbmlmb3JtMmYsXG4gICAgJ3VfZWRnZV9yYWRpdXMnOiBVbmlmb3JtMWYsXG4gICAgLy8gZ2xvYmUgdW5pZm9ybXM6XG4gICAgJ3VfdGlsZV9pZCc6IFVuaWZvcm0zZixcbiAgICAndV96b29tX3RyYW5zaXRpb24nOiBVbmlmb3JtMWYsXG4gICAgJ3VfaW52X3JvdF9tYXRyaXgnOiBVbmlmb3JtTWF0cml4NGYsXG4gICAgJ3VfbWVyY19jZW50ZXInOiBVbmlmb3JtMmYsXG4gICAgJ3VfdXBfZGlyJzogVW5pZm9ybTNmLFxuICAgICd1X2hlaWdodF9saWZ0JzogVW5pZm9ybTFmLFxuICAgIC8vIHBhdHRlcm4gdW5pZm9ybXM6XG4gICAgJ3VfdGV4c2l6ZSc6IFVuaWZvcm0yZixcbiAgICAndV9pbWFnZSc6IFVuaWZvcm0xaSxcbiAgICAndV9waXhlbF9jb29yZF91cHBlcic6IFVuaWZvcm0yZixcbiAgICAndV9waXhlbF9jb29yZF9sb3dlcic6IFVuaWZvcm0yZixcbiAgICAndV90aWxlX3VuaXRzX3RvX3BpeGVscyc6IFVuaWZvcm0xZixcbiAgICAndV9vcGFjaXR5JzogVW5pZm9ybTFmXG58fTtcblxuY29uc3QgZmlsbEV4dHJ1c2lvblVuaWZvcm1zID0gKGNvbnRleHQ6IENvbnRleHQpOiBGaWxsRXh0cnVzaW9uVW5pZm9ybXNUeXBlID0+ICh7XG4gICAgJ3VfbWF0cml4JzogbmV3IFVuaWZvcm1NYXRyaXg0Zihjb250ZXh0KSxcbiAgICAndV9saWdodHBvcyc6IG5ldyBVbmlmb3JtM2YoY29udGV4dCksXG4gICAgJ3VfbGlnaHRpbnRlbnNpdHknOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X2xpZ2h0Y29sb3InOiBuZXcgVW5pZm9ybTNmKGNvbnRleHQpLFxuICAgICd1X3ZlcnRpY2FsX2dyYWRpZW50JzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9vcGFjaXR5JzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9lZGdlX3JhZGl1cyc6IG5ldyBVbmlmb3JtMWYoY29udGV4dCksXG4gICAgJ3VfYW8nOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpLFxuICAgIC8vIGdsb2JlIHVuaWZvcm1zOlxuICAgICd1X3RpbGVfaWQnOiBuZXcgVW5pZm9ybTNmKGNvbnRleHQpLFxuICAgICd1X3pvb21fdHJhbnNpdGlvbic6IG5ldyBVbmlmb3JtMWYoY29udGV4dCksXG4gICAgJ3VfaW52X3JvdF9tYXRyaXgnOiBuZXcgVW5pZm9ybU1hdHJpeDRmKGNvbnRleHQpLFxuICAgICd1X21lcmNfY2VudGVyJzogbmV3IFVuaWZvcm0yZihjb250ZXh0KSxcbiAgICAndV91cF9kaXInOiBuZXcgVW5pZm9ybTNmKGNvbnRleHQpLFxuICAgICd1X2hlaWdodF9saWZ0JzogbmV3IFVuaWZvcm0xZihjb250ZXh0KVxufSk7XG5cbmNvbnN0IGZpbGxFeHRydXNpb25QYXR0ZXJuVW5pZm9ybXMgPSAoY29udGV4dDogQ29udGV4dCk6IEZpbGxFeHRydXNpb25QYXR0ZXJuVW5pZm9ybXNUeXBlID0+ICh7XG4gICAgJ3VfbWF0cml4JzogbmV3IFVuaWZvcm1NYXRyaXg0Zihjb250ZXh0KSxcbiAgICAndV9saWdodHBvcyc6IG5ldyBVbmlmb3JtM2YoY29udGV4dCksXG4gICAgJ3VfbGlnaHRpbnRlbnNpdHknOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X2xpZ2h0Y29sb3InOiBuZXcgVW5pZm9ybTNmKGNvbnRleHQpLFxuICAgICd1X3ZlcnRpY2FsX2dyYWRpZW50JzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9oZWlnaHRfZmFjdG9yJzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9lZGdlX3JhZGl1cyc6IG5ldyBVbmlmb3JtMWYoY29udGV4dCksXG4gICAgJ3VfYW8nOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpLFxuICAgIC8vIGdsb2JlIHVuaWZvcm1zOlxuICAgICd1X3RpbGVfaWQnOiBuZXcgVW5pZm9ybTNmKGNvbnRleHQpLFxuICAgICd1X3pvb21fdHJhbnNpdGlvbic6IG5ldyBVbmlmb3JtMWYoY29udGV4dCksXG4gICAgJ3VfaW52X3JvdF9tYXRyaXgnOiBuZXcgVW5pZm9ybU1hdHJpeDRmKGNvbnRleHQpLFxuICAgICd1X21lcmNfY2VudGVyJzogbmV3IFVuaWZvcm0yZihjb250ZXh0KSxcbiAgICAndV91cF9kaXInOiBuZXcgVW5pZm9ybTNmKGNvbnRleHQpLFxuICAgICd1X2hlaWdodF9saWZ0JzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAvLyBwYXR0ZXJuIHVuaWZvcm1zXG4gICAgJ3VfaW1hZ2UnOiBuZXcgVW5pZm9ybTFpKGNvbnRleHQpLFxuICAgICd1X3RleHNpemUnOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpLFxuICAgICd1X3BpeGVsX2Nvb3JkX3VwcGVyJzogbmV3IFVuaWZvcm0yZihjb250ZXh0KSxcbiAgICAndV9waXhlbF9jb29yZF9sb3dlcic6IG5ldyBVbmlmb3JtMmYoY29udGV4dCksXG4gICAgJ3VfdGlsZV91bml0c190b19waXhlbHMnOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X29wYWNpdHknOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpXG59KTtcblxuY29uc3QgaWRlbnRpdHlNYXRyaXggPSBtYXQ0LmNyZWF0ZSgpO1xuXG5jb25zdCBmaWxsRXh0cnVzaW9uVW5pZm9ybVZhbHVlcyA9IChcbiAgICBtYXRyaXg6IEZsb2F0MzJBcnJheSxcbiAgICBwYWludGVyOiBQYWludGVyLFxuICAgIHNob3VsZFVzZVZlcnRpY2FsR3JhZGllbnQ6IGJvb2xlYW4sXG4gICAgb3BhY2l0eTogbnVtYmVyLFxuICAgIGFvSW50ZW5zaXR5UmFkaXVzOiBbbnVtYmVyLCBudW1iZXJdLFxuICAgIGVkZ2VSYWRpdXM6IG51bWJlcixcbiAgICBjb29yZDogT3ZlcnNjYWxlZFRpbGVJRCxcbiAgICBoZWlnaHRMaWZ0OiBudW1iZXIsXG4gICAgem9vbVRyYW5zaXRpb246IG51bWJlcixcbiAgICBtZXJjYXRvckNlbnRlcjogW251bWJlciwgbnVtYmVyXSxcbiAgICBpbnZNYXRyaXg6IEZsb2F0MzJBcnJheVxuKTogVW5pZm9ybVZhbHVlczxGaWxsRXh0cnVzaW9uVW5pZm9ybXNUeXBlPiA9PiB7XG4gICAgY29uc3QgbGlnaHQgPSBwYWludGVyLnN0eWxlLmxpZ2h0O1xuICAgIGNvbnN0IF9scCA9IGxpZ2h0LnByb3BlcnRpZXMuZ2V0KCdwb3NpdGlvbicpO1xuICAgIGNvbnN0IGxpZ2h0UG9zID0gW19scC54LCBfbHAueSwgX2xwLnpdO1xuICAgIGNvbnN0IGxpZ2h0TWF0ID0gbWF0My5jcmVhdGUoKTtcbiAgICBjb25zdCBhbmNob3IgPSBsaWdodC5wcm9wZXJ0aWVzLmdldCgnYW5jaG9yJyk7XG4gICAgaWYgKGFuY2hvciA9PT0gJ3ZpZXdwb3J0Jykge1xuICAgICAgICBtYXQzLmZyb21Sb3RhdGlvbihsaWdodE1hdCwgLXBhaW50ZXIudHJhbnNmb3JtLmFuZ2xlKTtcbiAgICAgICAgdmVjMy50cmFuc2Zvcm1NYXQzKGxpZ2h0UG9zLCBsaWdodFBvcywgbGlnaHRNYXQpO1xuICAgIH1cblxuICAgIGNvbnN0IGxpZ2h0Q29sb3IgPSBsaWdodC5wcm9wZXJ0aWVzLmdldCgnY29sb3InKTtcbiAgICBjb25zdCB0ciA9IHBhaW50ZXIudHJhbnNmb3JtO1xuXG4gICAgY29uc3QgdW5pZm9ybVZhbHVlcyA9IHtcbiAgICAgICAgJ3VfbWF0cml4JzogbWF0cml4LFxuICAgICAgICAndV9saWdodHBvcyc6IGxpZ2h0UG9zLFxuICAgICAgICAndV9saWdodGludGVuc2l0eSc6IGxpZ2h0LnByb3BlcnRpZXMuZ2V0KCdpbnRlbnNpdHknKSxcbiAgICAgICAgJ3VfbGlnaHRjb2xvcic6IFtsaWdodENvbG9yLnIsIGxpZ2h0Q29sb3IuZywgbGlnaHRDb2xvci5iXSxcbiAgICAgICAgJ3VfdmVydGljYWxfZ3JhZGllbnQnOiArc2hvdWxkVXNlVmVydGljYWxHcmFkaWVudCxcbiAgICAgICAgJ3Vfb3BhY2l0eSc6IG9wYWNpdHksXG4gICAgICAgICd1X3RpbGVfaWQnOiBbMCwgMCwgMF0sXG4gICAgICAgICd1X3pvb21fdHJhbnNpdGlvbic6IDAsXG4gICAgICAgICd1X2ludl9yb3RfbWF0cml4JzogaWRlbnRpdHlNYXRyaXgsXG4gICAgICAgICd1X21lcmNfY2VudGVyJzogWzAsIDBdLFxuICAgICAgICAndV91cF9kaXInOiBbMCwgMCwgMF0sXG4gICAgICAgICd1X2hlaWdodF9saWZ0JzogMCxcbiAgICAgICAgJ3VfYW8nOiBhb0ludGVuc2l0eVJhZGl1cyxcbiAgICAgICAgJ3VfZWRnZV9yYWRpdXMnOiBlZGdlUmFkaXVzXG4gICAgfTtcblxuICAgIGlmICh0ci5wcm9qZWN0aW9uLm5hbWUgPT09ICdnbG9iZScpIHtcbiAgICAgICAgdW5pZm9ybVZhbHVlc1sndV90aWxlX2lkJ10gPSBbY29vcmQuY2Fub25pY2FsLngsIGNvb3JkLmNhbm9uaWNhbC55LCAxIDw8IGNvb3JkLmNhbm9uaWNhbC56XTtcbiAgICAgICAgdW5pZm9ybVZhbHVlc1sndV96b29tX3RyYW5zaXRpb24nXSA9IHpvb21UcmFuc2l0aW9uO1xuICAgICAgICB1bmlmb3JtVmFsdWVzWyd1X2ludl9yb3RfbWF0cml4J10gPSBpbnZNYXRyaXg7XG4gICAgICAgIHVuaWZvcm1WYWx1ZXNbJ3VfbWVyY19jZW50ZXInXSA9IG1lcmNhdG9yQ2VudGVyO1xuICAgICAgICB1bmlmb3JtVmFsdWVzWyd1X3VwX2RpciddID0gKHRyLnByb2plY3Rpb24udXBWZWN0b3IobmV3IENhbm9uaWNhbFRpbGVJRCgwLCAwLCAwKSwgbWVyY2F0b3JDZW50ZXJbMF0gKiBFWFRFTlQsIG1lcmNhdG9yQ2VudGVyWzFdICogRVhURU5UKTogYW55KTtcbiAgICAgICAgdW5pZm9ybVZhbHVlc1sndV9oZWlnaHRfbGlmdCddID0gaGVpZ2h0TGlmdDtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5pZm9ybVZhbHVlcztcbn07XG5cbmNvbnN0IGZpbGxFeHRydXNpb25QYXR0ZXJuVW5pZm9ybVZhbHVlcyA9IChcbiAgICBtYXRyaXg6IEZsb2F0MzJBcnJheSxcbiAgICBwYWludGVyOiBQYWludGVyLFxuICAgIHNob3VsZFVzZVZlcnRpY2FsR3JhZGllbnQ6IGJvb2xlYW4sXG4gICAgb3BhY2l0eTogbnVtYmVyLFxuICAgIGFvSW50ZW5zaXR5UmFkaXVzOiBbbnVtYmVyLCBudW1iZXJdLFxuICAgIGVkZ2VSYWRpdXM6IG51bWJlcixcbiAgICBjb29yZDogT3ZlcnNjYWxlZFRpbGVJRCxcbiAgICB0aWxlOiBUaWxlLFxuICAgIGhlaWdodExpZnQ6IG51bWJlcixcbiAgICB6b29tVHJhbnNpdGlvbjogbnVtYmVyLFxuICAgIG1lcmNhdG9yQ2VudGVyOiBbbnVtYmVyLCBudW1iZXJdLFxuICAgIGludk1hdHJpeDogRmxvYXQzMkFycmF5XG4pOiBVbmlmb3JtVmFsdWVzPEZpbGxFeHRydXNpb25QYXR0ZXJuVW5pZm9ybXNUeXBlPiA9PiB7XG4gICAgY29uc3QgdW5pZm9ybVZhbHVlcyA9IGZpbGxFeHRydXNpb25Vbmlmb3JtVmFsdWVzKFxuICAgICAgICBtYXRyaXgsIHBhaW50ZXIsIHNob3VsZFVzZVZlcnRpY2FsR3JhZGllbnQsIG9wYWNpdHksIGFvSW50ZW5zaXR5UmFkaXVzLCBlZGdlUmFkaXVzLCBjb29yZCxcbiAgICAgICAgaGVpZ2h0TGlmdCwgem9vbVRyYW5zaXRpb24sIG1lcmNhdG9yQ2VudGVyLCBpbnZNYXRyaXgpO1xuICAgIGNvbnN0IGhlaWdodEZhY3RvclVuaWZvcm0gPSB7XG4gICAgICAgICd1X2hlaWdodF9mYWN0b3InOiAtTWF0aC5wb3coMiwgY29vcmQub3ZlcnNjYWxlZFopIC8gdGlsZS50aWxlU2l6ZSAvIDhcbiAgICB9O1xuICAgIHJldHVybiBleHRlbmQodW5pZm9ybVZhbHVlcywgcGF0dGVyblVuaWZvcm1WYWx1ZXMocGFpbnRlciwgdGlsZSksIGhlaWdodEZhY3RvclVuaWZvcm0pO1xufTtcblxuZXhwb3J0IHtcbiAgICBmaWxsRXh0cnVzaW9uVW5pZm9ybXMsXG4gICAgZmlsbEV4dHJ1c2lvblBhdHRlcm5Vbmlmb3JtcyxcbiAgICBmaWxsRXh0cnVzaW9uVW5pZm9ybVZhbHVlcyxcbiAgICBmaWxsRXh0cnVzaW9uUGF0dGVyblVuaWZvcm1WYWx1ZXNcbn07XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge3BhdHRlcm5Vbmlmb3JtVmFsdWVzfSBmcm9tICcuL3BhdHRlcm4uanMnO1xuaW1wb3J0IHtcbiAgICBVbmlmb3JtMWksXG4gICAgVW5pZm9ybTFmLFxuICAgIFVuaWZvcm0yZixcbiAgICBVbmlmb3JtTWF0cml4NGZcbn0gZnJvbSAnLi4vdW5pZm9ybV9iaW5kaW5nLmpzJztcbmltcG9ydCB7ZXh0ZW5kfSBmcm9tICcuLi8uLi91dGlsL3V0aWwuanMnO1xuXG5pbXBvcnQgdHlwZSBQYWludGVyIGZyb20gJy4uL3BhaW50ZXIuanMnO1xuaW1wb3J0IHR5cGUge1VuaWZvcm1WYWx1ZXN9IGZyb20gJy4uL3VuaWZvcm1fYmluZGluZy5qcyc7XG5pbXBvcnQgdHlwZSBDb250ZXh0IGZyb20gJy4uLy4uL2dsL2NvbnRleHQuanMnO1xuaW1wb3J0IHR5cGUgVGlsZSBmcm9tICcuLi8uLi9zb3VyY2UvdGlsZS5qcyc7XG5cbmV4cG9ydCB0eXBlIEZpbGxVbmlmb3Jtc1R5cGUgPSB7fFxuICAgICd1X21hdHJpeCc6IFVuaWZvcm1NYXRyaXg0ZlxufH07XG5cbmV4cG9ydCB0eXBlIEZpbGxPdXRsaW5lVW5pZm9ybXNUeXBlID0ge3xcbiAgICAndV9tYXRyaXgnOiBVbmlmb3JtTWF0cml4NGYsXG4gICAgJ3Vfd29ybGQnOiBVbmlmb3JtMmZcbnx9O1xuXG5leHBvcnQgdHlwZSBGaWxsUGF0dGVyblVuaWZvcm1zVHlwZSA9IHt8XG4gICAgJ3VfbWF0cml4JzogVW5pZm9ybU1hdHJpeDRmLFxuICAgIC8vIHBhdHRlcm4gdW5pZm9ybXM6XG4gICAgJ3VfdGV4c2l6ZSc6IFVuaWZvcm0yZixcbiAgICAndV9pbWFnZSc6IFVuaWZvcm0xaSxcbiAgICAndV9waXhlbF9jb29yZF91cHBlcic6IFVuaWZvcm0yZixcbiAgICAndV9waXhlbF9jb29yZF9sb3dlcic6IFVuaWZvcm0yZixcbiAgICAndV90aWxlX3VuaXRzX3RvX3BpeGVscyc6IFVuaWZvcm0xZlxufH07XG5cbmV4cG9ydCB0eXBlIEZpbGxPdXRsaW5lUGF0dGVyblVuaWZvcm1zVHlwZSA9IHt8XG4gICAgJ3VfbWF0cml4JzogVW5pZm9ybU1hdHJpeDRmLFxuICAgICd1X3dvcmxkJzogVW5pZm9ybTJmLFxuICAgIC8vIHBhdHRlcm4gdW5pZm9ybXM6XG4gICAgJ3VfdGV4c2l6ZSc6IFVuaWZvcm0yZixcbiAgICAndV9pbWFnZSc6IFVuaWZvcm0xaSxcbiAgICAndV9waXhlbF9jb29yZF91cHBlcic6IFVuaWZvcm0yZixcbiAgICAndV9waXhlbF9jb29yZF9sb3dlcic6IFVuaWZvcm0yZixcbiAgICAndV90aWxlX3VuaXRzX3RvX3BpeGVscyc6IFVuaWZvcm0xZlxufH07XG5cbmNvbnN0IGZpbGxVbmlmb3JtcyA9IChjb250ZXh0OiBDb250ZXh0KTogRmlsbFVuaWZvcm1zVHlwZSA9PiAoe1xuICAgICd1X21hdHJpeCc6IG5ldyBVbmlmb3JtTWF0cml4NGYoY29udGV4dClcbn0pO1xuXG5jb25zdCBmaWxsUGF0dGVyblVuaWZvcm1zID0gKGNvbnRleHQ6IENvbnRleHQpOiBGaWxsUGF0dGVyblVuaWZvcm1zVHlwZSA9PiAoe1xuICAgICd1X21hdHJpeCc6IG5ldyBVbmlmb3JtTWF0cml4NGYoY29udGV4dCksXG4gICAgJ3VfaW1hZ2UnOiBuZXcgVW5pZm9ybTFpKGNvbnRleHQpLFxuICAgICd1X3RleHNpemUnOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpLFxuICAgICd1X3BpeGVsX2Nvb3JkX3VwcGVyJzogbmV3IFVuaWZvcm0yZihjb250ZXh0KSxcbiAgICAndV9waXhlbF9jb29yZF9sb3dlcic6IG5ldyBVbmlmb3JtMmYoY29udGV4dCksXG4gICAgJ3VfdGlsZV91bml0c190b19waXhlbHMnOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpXG5cbn0pO1xuXG5jb25zdCBmaWxsT3V0bGluZVVuaWZvcm1zID0gKGNvbnRleHQ6IENvbnRleHQpOiBGaWxsT3V0bGluZVVuaWZvcm1zVHlwZSA9PiAoe1xuICAgICd1X21hdHJpeCc6IG5ldyBVbmlmb3JtTWF0cml4NGYoY29udGV4dCksXG4gICAgJ3Vfd29ybGQnOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpXG59KTtcblxuY29uc3QgZmlsbE91dGxpbmVQYXR0ZXJuVW5pZm9ybXMgPSAoY29udGV4dDogQ29udGV4dCk6IEZpbGxPdXRsaW5lUGF0dGVyblVuaWZvcm1zVHlwZSA9PiAoe1xuICAgICd1X21hdHJpeCc6IG5ldyBVbmlmb3JtTWF0cml4NGYoY29udGV4dCksXG4gICAgJ3Vfd29ybGQnOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpLFxuICAgICd1X2ltYWdlJzogbmV3IFVuaWZvcm0xaShjb250ZXh0KSxcbiAgICAndV90ZXhzaXplJzogbmV3IFVuaWZvcm0yZihjb250ZXh0KSxcbiAgICAndV9waXhlbF9jb29yZF91cHBlcic6IG5ldyBVbmlmb3JtMmYoY29udGV4dCksXG4gICAgJ3VfcGl4ZWxfY29vcmRfbG93ZXInOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpLFxuICAgICd1X3RpbGVfdW5pdHNfdG9fcGl4ZWxzJzogbmV3IFVuaWZvcm0xZihjb250ZXh0KVxufSk7XG5cbmNvbnN0IGZpbGxVbmlmb3JtVmFsdWVzID0gKG1hdHJpeDogRmxvYXQzMkFycmF5KTogVW5pZm9ybVZhbHVlczxGaWxsVW5pZm9ybXNUeXBlPiA9PiAoe1xuICAgICd1X21hdHJpeCc6IG1hdHJpeFxufSk7XG5cbmNvbnN0IGZpbGxQYXR0ZXJuVW5pZm9ybVZhbHVlcyA9IChcbiAgICBtYXRyaXg6IEZsb2F0MzJBcnJheSxcbiAgICBwYWludGVyOiBQYWludGVyLFxuICAgIHRpbGU6IFRpbGVcbik6IFVuaWZvcm1WYWx1ZXM8RmlsbFBhdHRlcm5Vbmlmb3Jtc1R5cGU+ID0+IGV4dGVuZChcbiAgICBmaWxsVW5pZm9ybVZhbHVlcyhtYXRyaXgpLFxuICAgIHBhdHRlcm5Vbmlmb3JtVmFsdWVzKHBhaW50ZXIsIHRpbGUpXG4pO1xuXG5jb25zdCBmaWxsT3V0bGluZVVuaWZvcm1WYWx1ZXMgPSAoXG4gICAgbWF0cml4OiBGbG9hdDMyQXJyYXksXG4gICAgZHJhd2luZ0J1ZmZlclNpemU6IFtudW1iZXIsIG51bWJlcl1cbik6IFVuaWZvcm1WYWx1ZXM8RmlsbE91dGxpbmVVbmlmb3Jtc1R5cGU+ID0+ICh7XG4gICAgJ3VfbWF0cml4JzogbWF0cml4LFxuICAgICd1X3dvcmxkJzogZHJhd2luZ0J1ZmZlclNpemVcbn0pO1xuXG5jb25zdCBmaWxsT3V0bGluZVBhdHRlcm5Vbmlmb3JtVmFsdWVzID0gKFxuICAgIG1hdHJpeDogRmxvYXQzMkFycmF5LFxuICAgIHBhaW50ZXI6IFBhaW50ZXIsXG4gICAgdGlsZTogVGlsZSxcbiAgICBkcmF3aW5nQnVmZmVyU2l6ZTogW251bWJlciwgbnVtYmVyXVxuKTogVW5pZm9ybVZhbHVlczxGaWxsT3V0bGluZVBhdHRlcm5Vbmlmb3Jtc1R5cGU+ID0+IGV4dGVuZChcbiAgICBmaWxsUGF0dGVyblVuaWZvcm1WYWx1ZXMobWF0cml4LCBwYWludGVyLCB0aWxlKSxcbiAgICB7XG4gICAgICAgICd1X3dvcmxkJzogZHJhd2luZ0J1ZmZlclNpemVcbiAgICB9XG4pO1xuXG5leHBvcnQge1xuICAgIGZpbGxVbmlmb3JtcyxcbiAgICBmaWxsUGF0dGVyblVuaWZvcm1zLFxuICAgIGZpbGxPdXRsaW5lVW5pZm9ybXMsXG4gICAgZmlsbE91dGxpbmVQYXR0ZXJuVW5pZm9ybXMsXG4gICAgZmlsbFVuaWZvcm1WYWx1ZXMsXG4gICAgZmlsbFBhdHRlcm5Vbmlmb3JtVmFsdWVzLFxuICAgIGZpbGxPdXRsaW5lVW5pZm9ybVZhbHVlcyxcbiAgICBmaWxsT3V0bGluZVBhdHRlcm5Vbmlmb3JtVmFsdWVzXG59O1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtcbiAgICBVbmlmb3JtMWYsXG4gICAgVW5pZm9ybTJmLFxuICAgIFVuaWZvcm0zZixcbiAgICBVbmlmb3JtTWF0cml4MmYsXG4gICAgVW5pZm9ybU1hdHJpeDRmXG59IGZyb20gJy4uL3VuaWZvcm1fYmluZGluZy5qcyc7XG5cbmltcG9ydCB0eXBlIENvbnRleHQgZnJvbSAnLi4vLi4vZ2wvY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSB7VW5pZm9ybVZhbHVlc30gZnJvbSAnLi4vdW5pZm9ybV9iaW5kaW5nLmpzJztcbmltcG9ydCB7Q2Fub25pY2FsVGlsZUlELCBPdmVyc2NhbGVkVGlsZUlEfSBmcm9tICcuLi8uLi9zb3VyY2UvdGlsZV9pZC5qcyc7XG5pbXBvcnQgdHlwZSBUaWxlIGZyb20gJy4uLy4uL3NvdXJjZS90aWxlLmpzJztcbmltcG9ydCB0eXBlIENpcmNsZVN0eWxlTGF5ZXIgZnJvbSAnLi4vLi4vc3R5bGUvc3R5bGVfbGF5ZXIvY2lyY2xlX3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCB0eXBlIFBhaW50ZXIgZnJvbSAnLi4vcGFpbnRlci5qcyc7XG5pbXBvcnQgYnJvd3NlciBmcm9tICcuLi8uLi91dGlsL2Jyb3dzZXIuanMnO1xuaW1wb3J0IHttYXQ0fSBmcm9tICdnbC1tYXRyaXgnO1xuaW1wb3J0IHtnbG9iZVRvTWVyY2F0b3JUcmFuc2l0aW9uLCBnbG9iZVBpeGVsc1RvVGlsZVVuaXRzfSBmcm9tICcuLi8uLi9nZW8vcHJvamVjdGlvbi9nbG9iZV91dGlsLmpzJztcbmltcG9ydCBFWFRFTlQgZnJvbSAnLi4vLi4vZGF0YS9leHRlbnQuanMnO1xuXG5leHBvcnQgdHlwZSBDaXJjbGVVbmlmb3Jtc1R5cGUgPSB7fFxuICAgICd1X2NhbWVyYV90b19jZW50ZXJfZGlzdGFuY2UnOiBVbmlmb3JtMWYsXG4gICAgJ3VfZXh0cnVkZV9zY2FsZSc6IFVuaWZvcm1NYXRyaXgyZixcbiAgICAndV9kZXZpY2VfcGl4ZWxfcmF0aW8nOiBVbmlmb3JtMWYsXG4gICAgJ3VfbWF0cml4JzogVW5pZm9ybU1hdHJpeDRmLFxuICAgICd1X2ludl9yb3RfbWF0cml4JzogVW5pZm9ybU1hdHJpeDRmLFxuICAgICd1X21lcmNfY2VudGVyJzogVW5pZm9ybTJmLFxuICAgICd1X3RpbGVfaWQnOiBVbmlmb3JtM2YsXG4gICAgJ3Vfem9vbV90cmFuc2l0aW9uJzogVW5pZm9ybTFmLFxuICAgICd1X3VwX2Rpcic6IFVuaWZvcm0zZixcbnx9O1xuXG5leHBvcnQgdHlwZSBDaXJjbGVEZWZpbmVzVHlwZSA9ICdQSVRDSF9XSVRIX01BUCcgfCAnU0NBTEVfV0lUSF9NQVAnIHwgJ1BST0pFQ1RJT05fR0xPQkVfVklFVyc7XG5cbmNvbnN0IGNpcmNsZVVuaWZvcm1zID0gKGNvbnRleHQ6IENvbnRleHQpOiBDaXJjbGVVbmlmb3Jtc1R5cGUgPT4gKHtcbiAgICAndV9jYW1lcmFfdG9fY2VudGVyX2Rpc3RhbmNlJzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9leHRydWRlX3NjYWxlJzogbmV3IFVuaWZvcm1NYXRyaXgyZihjb250ZXh0KSxcbiAgICAndV9kZXZpY2VfcGl4ZWxfcmF0aW8nOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X21hdHJpeCc6IG5ldyBVbmlmb3JtTWF0cml4NGYoY29udGV4dCksXG4gICAgJ3VfaW52X3JvdF9tYXRyaXgnOiBuZXcgVW5pZm9ybU1hdHJpeDRmKGNvbnRleHQpLFxuICAgICd1X21lcmNfY2VudGVyJzogbmV3IFVuaWZvcm0yZihjb250ZXh0KSxcbiAgICAndV90aWxlX2lkJzogbmV3IFVuaWZvcm0zZihjb250ZXh0KSxcbiAgICAndV96b29tX3RyYW5zaXRpb24nOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X3VwX2Rpcic6IG5ldyBVbmlmb3JtM2YoY29udGV4dCksXG59KTtcblxuY29uc3QgaWRlbnRpdHlNYXRyaXggPSBtYXQ0LmNyZWF0ZSgpO1xuXG5jb25zdCBjaXJjbGVVbmlmb3JtVmFsdWVzID0gKFxuICAgIHBhaW50ZXI6IFBhaW50ZXIsXG4gICAgY29vcmQ6IE92ZXJzY2FsZWRUaWxlSUQsXG4gICAgdGlsZTogVGlsZSxcbiAgICBpbnZNYXRyaXg6IEZsb2F0MzJBcnJheSxcbiAgICBtZXJjYXRvckNlbnRlcjogW251bWJlciwgbnVtYmVyXSxcbiAgICBsYXllcjogQ2lyY2xlU3R5bGVMYXllclxuKTogVW5pZm9ybVZhbHVlczxDaXJjbGVVbmlmb3Jtc1R5cGU+ID0+IHtcbiAgICBjb25zdCB0cmFuc2Zvcm0gPSBwYWludGVyLnRyYW5zZm9ybTtcbiAgICBjb25zdCBpc0dsb2JlID0gdHJhbnNmb3JtLnByb2plY3Rpb24ubmFtZSA9PT0gJ2dsb2JlJztcblxuICAgIGxldCBleHRydWRlU2NhbGU7XG4gICAgaWYgKGxheWVyLnBhaW50LmdldCgnY2lyY2xlLXBpdGNoLWFsaWdubWVudCcpID09PSAnbWFwJykge1xuICAgICAgICBpZiAoaXNHbG9iZSkge1xuICAgICAgICAgICAgY29uc3QgcyA9IGdsb2JlUGl4ZWxzVG9UaWxlVW5pdHModHJhbnNmb3JtLnpvb20sIGNvb3JkLmNhbm9uaWNhbCkgKiB0cmFuc2Zvcm0uX3BpeGVsc1Blck1lcmNhdG9yUGl4ZWw7XG4gICAgICAgICAgICBleHRydWRlU2NhbGUgPSBGbG9hdDMyQXJyYXkuZnJvbShbcywgMCwgMCwgc10pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZXh0cnVkZVNjYWxlID0gdHJhbnNmb3JtLmNhbGN1bGF0ZVBpeGVsc1RvVGlsZVVuaXRzTWF0cml4KHRpbGUpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgZXh0cnVkZVNjYWxlID0gbmV3IEZsb2F0MzJBcnJheShbXG4gICAgICAgICAgICB0cmFuc2Zvcm0ucGl4ZWxzVG9HTFVuaXRzWzBdLFxuICAgICAgICAgICAgMCxcbiAgICAgICAgICAgIDAsXG4gICAgICAgICAgICB0cmFuc2Zvcm0ucGl4ZWxzVG9HTFVuaXRzWzFdXSk7XG4gICAgfVxuXG4gICAgY29uc3QgdmFsdWVzID0ge1xuICAgICAgICAndV9jYW1lcmFfdG9fY2VudGVyX2Rpc3RhbmNlJzogdHJhbnNmb3JtLmNhbWVyYVRvQ2VudGVyRGlzdGFuY2UsXG4gICAgICAgICd1X21hdHJpeCc6IHBhaW50ZXIudHJhbnNsYXRlUG9zTWF0cml4KFxuICAgICAgICAgICAgY29vcmQucHJvak1hdHJpeCxcbiAgICAgICAgICAgIHRpbGUsXG4gICAgICAgICAgICBsYXllci5wYWludC5nZXQoJ2NpcmNsZS10cmFuc2xhdGUnKSxcbiAgICAgICAgICAgIGxheWVyLnBhaW50LmdldCgnY2lyY2xlLXRyYW5zbGF0ZS1hbmNob3InKSksXG4gICAgICAgICd1X2RldmljZV9waXhlbF9yYXRpbyc6IGJyb3dzZXIuZGV2aWNlUGl4ZWxSYXRpbyxcbiAgICAgICAgJ3VfZXh0cnVkZV9zY2FsZSc6IGV4dHJ1ZGVTY2FsZSxcbiAgICAgICAgJ3VfaW52X3JvdF9tYXRyaXgnOiBpZGVudGl0eU1hdHJpeCxcbiAgICAgICAgJ3VfbWVyY19jZW50ZXInOiBbMCwgMF0sXG4gICAgICAgICd1X3RpbGVfaWQnOiBbMCwgMCwgMF0sXG4gICAgICAgICd1X3pvb21fdHJhbnNpdGlvbic6IDAsXG4gICAgICAgICd1X3VwX2Rpcic6IFswLCAwLCAwXVxuICAgIH07XG5cbiAgICBpZiAoaXNHbG9iZSkge1xuICAgICAgICB2YWx1ZXNbJ3VfaW52X3JvdF9tYXRyaXgnXSA9IGludk1hdHJpeDtcbiAgICAgICAgdmFsdWVzWyd1X21lcmNfY2VudGVyJ10gPSBtZXJjYXRvckNlbnRlcjtcbiAgICAgICAgdmFsdWVzWyd1X3RpbGVfaWQnXSA9IFtjb29yZC5jYW5vbmljYWwueCwgY29vcmQuY2Fub25pY2FsLnksIDEgPDwgY29vcmQuY2Fub25pY2FsLnpdO1xuICAgICAgICB2YWx1ZXNbJ3Vfem9vbV90cmFuc2l0aW9uJ10gPSBnbG9iZVRvTWVyY2F0b3JUcmFuc2l0aW9uKHRyYW5zZm9ybS56b29tKTtcbiAgICAgICAgY29uc3QgeCA9IG1lcmNhdG9yQ2VudGVyWzBdICogRVhURU5UO1xuICAgICAgICBjb25zdCB5ID0gbWVyY2F0b3JDZW50ZXJbMV0gKiBFWFRFTlQ7XG4gICAgICAgIHZhbHVlc1sndV91cF9kaXInXSA9ICh0cmFuc2Zvcm0ucHJvamVjdGlvbi51cFZlY3RvcihuZXcgQ2Fub25pY2FsVGlsZUlEKDAsIDAsIDApLCB4LCB5KTogYW55KTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWVzO1xufTtcblxuY29uc3QgY2lyY2xlRGVmaW5lc1ZhbHVlcyA9IChsYXllcjogQ2lyY2xlU3R5bGVMYXllcik6IENpcmNsZURlZmluZXNUeXBlW10gPT4ge1xuICAgIGNvbnN0IHZhbHVlcyA9IFtdO1xuICAgIGlmIChsYXllci5wYWludC5nZXQoJ2NpcmNsZS1waXRjaC1hbGlnbm1lbnQnKSA9PT0gJ21hcCcpIHZhbHVlcy5wdXNoKCdQSVRDSF9XSVRIX01BUCcpO1xuICAgIGlmIChsYXllci5wYWludC5nZXQoJ2NpcmNsZS1waXRjaC1zY2FsZScpID09PSAnbWFwJykgdmFsdWVzLnB1c2goJ1NDQUxFX1dJVEhfTUFQJyk7XG5cbiAgICByZXR1cm4gdmFsdWVzO1xufTtcblxuZXhwb3J0IHtjaXJjbGVVbmlmb3JtcywgY2lyY2xlVW5pZm9ybVZhbHVlcywgY2lyY2xlRGVmaW5lc1ZhbHVlc307XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge1xuICAgIFVuaWZvcm0xZixcbiAgICBVbmlmb3JtMmYsXG4gICAgVW5pZm9ybU1hdHJpeDRmXG59IGZyb20gJy4uL3VuaWZvcm1fYmluZGluZy5qcyc7XG5pbXBvcnQgRVhURU5UIGZyb20gJy4uLy4uL2RhdGEvZXh0ZW50LmpzJztcbmltcG9ydCB0eXBlIENvbnRleHQgZnJvbSAnLi4vLi4vZ2wvY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSB7VW5pZm9ybVZhbHVlc30gZnJvbSAnLi4vdW5pZm9ybV9iaW5kaW5nLmpzJztcbmltcG9ydCB0eXBlIFRyYW5zZm9ybSBmcm9tICcuLi8uLi9nZW8vdHJhbnNmb3JtLmpzJztcbmltcG9ydCB0eXBlIFRpbGUgZnJvbSAnLi4vLi4vc291cmNlL3RpbGUuanMnO1xuaW1wb3J0IHR5cGUgUHJvamVjdGlvbiBmcm9tICcuLi8uLi9nZW8vcHJvamVjdGlvbi9wcm9qZWN0aW9uLmpzJztcblxuZXhwb3J0IHR5cGUgQ29sbGlzaW9uVW5pZm9ybXNUeXBlID0ge3xcbiAgICAndV9tYXRyaXgnOiBVbmlmb3JtTWF0cml4NGYsXG4gICAgJ3VfY2FtZXJhX3RvX2NlbnRlcl9kaXN0YW5jZSc6IFVuaWZvcm0xZixcbiAgICAndV9leHRydWRlX3NjYWxlJzogVW5pZm9ybTJmXG58fTtcblxuZXhwb3J0IHR5cGUgQ29sbGlzaW9uQ2lyY2xlVW5pZm9ybXNUeXBlID0ge3xcbiAgICAndV9tYXRyaXgnOiBVbmlmb3JtTWF0cml4NGYsXG4gICAgJ3VfaW52X21hdHJpeCc6IFVuaWZvcm1NYXRyaXg0ZixcbiAgICAndV9jYW1lcmFfdG9fY2VudGVyX2Rpc3RhbmNlJzogVW5pZm9ybTFmLFxuICAgICd1X3ZpZXdwb3J0X3NpemUnOiBVbmlmb3JtMmZcbnx9O1xuXG5jb25zdCBjb2xsaXNpb25Vbmlmb3JtcyA9IChjb250ZXh0OiBDb250ZXh0KTogQ29sbGlzaW9uVW5pZm9ybXNUeXBlID0+ICh7XG4gICAgJ3VfbWF0cml4JzogbmV3IFVuaWZvcm1NYXRyaXg0Zihjb250ZXh0KSxcbiAgICAndV9jYW1lcmFfdG9fY2VudGVyX2Rpc3RhbmNlJzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9leHRydWRlX3NjYWxlJzogbmV3IFVuaWZvcm0yZihjb250ZXh0KVxufSk7XG5cbmNvbnN0IGNvbGxpc2lvbkNpcmNsZVVuaWZvcm1zID0gKGNvbnRleHQ6IENvbnRleHQpOiBDb2xsaXNpb25DaXJjbGVVbmlmb3Jtc1R5cGUgPT4gKHtcbiAgICAndV9tYXRyaXgnOiBuZXcgVW5pZm9ybU1hdHJpeDRmKGNvbnRleHQpLFxuICAgICd1X2ludl9tYXRyaXgnOiBuZXcgVW5pZm9ybU1hdHJpeDRmKGNvbnRleHQpLFxuICAgICd1X2NhbWVyYV90b19jZW50ZXJfZGlzdGFuY2UnOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X3ZpZXdwb3J0X3NpemUnOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpXG59KTtcblxuY29uc3QgY29sbGlzaW9uVW5pZm9ybVZhbHVlcyA9IChcbiAgICBtYXRyaXg6IEZsb2F0MzJBcnJheSxcbiAgICB0cmFuc2Zvcm06IFRyYW5zZm9ybSxcbiAgICB0aWxlOiBUaWxlLFxuICAgIHByb2plY3Rpb246IFByb2plY3Rpb25cbik6IFVuaWZvcm1WYWx1ZXM8Q29sbGlzaW9uVW5pZm9ybXNUeXBlPiA9PiB7XG4gICAgY29uc3QgcGl4ZWxSYXRpbyA9IEVYVEVOVCAvIHRpbGUudGlsZVNpemU7XG5cbiAgICByZXR1cm4ge1xuICAgICAgICAndV9tYXRyaXgnOiBtYXRyaXgsXG4gICAgICAgICd1X2NhbWVyYV90b19jZW50ZXJfZGlzdGFuY2UnOiB0cmFuc2Zvcm0uZ2V0Q2FtZXJhVG9DZW50ZXJEaXN0YW5jZShwcm9qZWN0aW9uKSxcbiAgICAgICAgJ3VfZXh0cnVkZV9zY2FsZSc6IFt0cmFuc2Zvcm0ucGl4ZWxzVG9HTFVuaXRzWzBdIC8gcGl4ZWxSYXRpbyxcbiAgICAgICAgICAgIHRyYW5zZm9ybS5waXhlbHNUb0dMVW5pdHNbMV0gLyBwaXhlbFJhdGlvXVxuICAgIH07XG59O1xuXG5jb25zdCBjb2xsaXNpb25DaXJjbGVVbmlmb3JtVmFsdWVzID0gKFxuICAgIG1hdHJpeDogRmxvYXQzMkFycmF5LFxuICAgIGludk1hdHJpeDogRmxvYXQzMkFycmF5LFxuICAgIHRyYW5zZm9ybTogVHJhbnNmb3JtLFxuICAgIHByb2plY3Rpb246IFByb2plY3Rpb25cbik6IFVuaWZvcm1WYWx1ZXM8Q29sbGlzaW9uQ2lyY2xlVW5pZm9ybXNUeXBlPiA9PiB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgJ3VfbWF0cml4JzogbWF0cml4LFxuICAgICAgICAndV9pbnZfbWF0cml4JzogaW52TWF0cml4LFxuICAgICAgICAndV9jYW1lcmFfdG9fY2VudGVyX2Rpc3RhbmNlJzogdHJhbnNmb3JtLmdldENhbWVyYVRvQ2VudGVyRGlzdGFuY2UocHJvamVjdGlvbiksXG4gICAgICAgICd1X3ZpZXdwb3J0X3NpemUnOiBbdHJhbnNmb3JtLndpZHRoLCB0cmFuc2Zvcm0uaGVpZ2h0XVxuICAgIH07XG59O1xuXG5leHBvcnQge2NvbGxpc2lvblVuaWZvcm1zLCBjb2xsaXNpb25Vbmlmb3JtVmFsdWVzLCBjb2xsaXNpb25DaXJjbGVVbmlmb3JtcywgY29sbGlzaW9uQ2lyY2xlVW5pZm9ybVZhbHVlc307XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge1xuICAgIFVuaWZvcm1Db2xvcixcbiAgICBVbmlmb3JtTWF0cml4NGYsXG4gICAgVW5pZm9ybTFpLFxuICAgIFVuaWZvcm0xZlxufSBmcm9tICcuLi91bmlmb3JtX2JpbmRpbmcuanMnO1xuXG5pbXBvcnQgdHlwZSBDb250ZXh0IGZyb20gJy4uLy4uL2dsL2NvbnRleHQuanMnO1xuaW1wb3J0IHR5cGUge1VuaWZvcm1WYWx1ZXN9IGZyb20gJy4uL3VuaWZvcm1fYmluZGluZy5qcyc7XG5pbXBvcnQgdHlwZSBDb2xvciBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL3V0aWwvY29sb3IuanMnO1xuXG5leHBvcnQgdHlwZSBEZWJ1Z1VuaWZvcm1zVHlwZSA9IHt8XG4gICAgJ3VfY29sb3InOiBVbmlmb3JtQ29sb3IsXG4gICAgJ3VfbWF0cml4JzogVW5pZm9ybU1hdHJpeDRmLFxuICAgICd1X292ZXJsYXknOiBVbmlmb3JtMWksXG4gICAgJ3Vfb3ZlcmxheV9zY2FsZSc6IFVuaWZvcm0xZlxufH07XG5cbmNvbnN0IGRlYnVnVW5pZm9ybXMgPSAoY29udGV4dDogQ29udGV4dCk6IERlYnVnVW5pZm9ybXNUeXBlID0+ICh7XG4gICAgJ3VfY29sb3InOiBuZXcgVW5pZm9ybUNvbG9yKGNvbnRleHQpLFxuICAgICd1X21hdHJpeCc6IG5ldyBVbmlmb3JtTWF0cml4NGYoY29udGV4dCksXG4gICAgJ3Vfb3ZlcmxheSc6IG5ldyBVbmlmb3JtMWkoY29udGV4dCksXG4gICAgJ3Vfb3ZlcmxheV9zY2FsZSc6ICBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxufSk7XG5cbmNvbnN0IGRlYnVnVW5pZm9ybVZhbHVlcyA9IChtYXRyaXg6IEZsb2F0MzJBcnJheSwgY29sb3I6IENvbG9yLCBzY2FsZVJhdGlvOiBudW1iZXIgPSAxKTogVW5pZm9ybVZhbHVlczxEZWJ1Z1VuaWZvcm1zVHlwZT4gPT4gKHtcbiAgICAndV9tYXRyaXgnOiBtYXRyaXgsXG4gICAgJ3VfY29sb3InOiBjb2xvcixcbiAgICAndV9vdmVybGF5JzogMCxcbiAgICAndV9vdmVybGF5X3NjYWxlJzogc2NhbGVSYXRpb1xufSk7XG5cbmV4cG9ydCB7ZGVidWdVbmlmb3JtcywgZGVidWdVbmlmb3JtVmFsdWVzfTtcblxuZXhwb3J0IHR5cGUgRGVidWdEZWZpbmVzVHlwZSA9ICdQUk9KRUNUSU9OX0dMT0JFX1ZJRVcnO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtcbiAgICBVbmlmb3JtMWksXG4gICAgVW5pZm9ybTFmLFxuICAgIFVuaWZvcm0yZixcbiAgICBVbmlmb3JtM2YsXG4gICAgVW5pZm9ybU1hdHJpeDRmXG59IGZyb20gJy4uL3VuaWZvcm1fYmluZGluZy5qcyc7XG5pbXBvcnQgcGl4ZWxzVG9UaWxlVW5pdHMgZnJvbSAnLi4vLi4vc291cmNlL3BpeGVsc190b190aWxlX3VuaXRzLmpzJztcblxuaW1wb3J0IHR5cGUgQ29udGV4dCBmcm9tICcuLi8uLi9nbC9jb250ZXh0LmpzJztcbmltcG9ydCB0eXBlIFRpbGUgZnJvbSAnLi4vLi4vc291cmNlL3RpbGUuanMnO1xuaW1wb3J0IHR5cGUge1VuaWZvcm1WYWx1ZXN9IGZyb20gJy4uL3VuaWZvcm1fYmluZGluZy5qcyc7XG5pbXBvcnQgdHlwZSBQYWludGVyIGZyb20gJy4uL3BhaW50ZXIuanMnO1xuaW1wb3J0IHR5cGUgSGVhdG1hcFN0eWxlTGF5ZXIgZnJvbSAnLi4vLi4vc3R5bGUvc3R5bGVfbGF5ZXIvaGVhdG1hcF9zdHlsZV9sYXllci5qcyc7XG5pbXBvcnQge0Nhbm9uaWNhbFRpbGVJRCwgT3ZlcnNjYWxlZFRpbGVJRH0gZnJvbSAnLi4vLi4vc291cmNlL3RpbGVfaWQuanMnO1xuaW1wb3J0IHttYXQ0fSBmcm9tICdnbC1tYXRyaXgnO1xuaW1wb3J0IHtnbG9iZVRvTWVyY2F0b3JUcmFuc2l0aW9uLCBnbG9iZVBpeGVsc1RvVGlsZVVuaXRzfSBmcm9tICcuLi8uLi9nZW8vcHJvamVjdGlvbi9nbG9iZV91dGlsLmpzJztcbmltcG9ydCBFWFRFTlQgZnJvbSAnLi4vLi4vZGF0YS9leHRlbnQuanMnO1xuXG5leHBvcnQgdHlwZSBIZWF0bWFwVW5pZm9ybXNUeXBlID0ge3xcbiAgICAndV9leHRydWRlX3NjYWxlJzogVW5pZm9ybTFmLFxuICAgICd1X2ludGVuc2l0eSc6IFVuaWZvcm0xZixcbiAgICAndV9tYXRyaXgnOiBVbmlmb3JtTWF0cml4NGYsXG4gICAgJ3VfaW52X3JvdF9tYXRyaXgnOiBVbmlmb3JtTWF0cml4NGYsXG4gICAgJ3VfbWVyY19jZW50ZXInOiBVbmlmb3JtMmYsXG4gICAgJ3VfdGlsZV9pZCc6IFVuaWZvcm0zZixcbiAgICAndV96b29tX3RyYW5zaXRpb24nOiBVbmlmb3JtMWYsXG4gICAgJ3VfdXBfZGlyJzogVW5pZm9ybTNmLFxufH07XG5cbmV4cG9ydCB0eXBlIEhlYXRtYXBUZXh0dXJlVW5pZm9ybXNUeXBlID0ge3xcbiAgICAndV9pbWFnZSc6IFVuaWZvcm0xaSxcbiAgICAndV9jb2xvcl9yYW1wJzogVW5pZm9ybTFpLFxuICAgICd1X29wYWNpdHknOiBVbmlmb3JtMWZcbnx9O1xuXG5jb25zdCBoZWF0bWFwVW5pZm9ybXMgPSAoY29udGV4dDogQ29udGV4dCk6IEhlYXRtYXBVbmlmb3Jtc1R5cGUgPT4gKHtcbiAgICAndV9leHRydWRlX3NjYWxlJzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9pbnRlbnNpdHknOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X21hdHJpeCc6IG5ldyBVbmlmb3JtTWF0cml4NGYoY29udGV4dCksXG4gICAgJ3VfaW52X3JvdF9tYXRyaXgnOiBuZXcgVW5pZm9ybU1hdHJpeDRmKGNvbnRleHQpLFxuICAgICd1X21lcmNfY2VudGVyJzogbmV3IFVuaWZvcm0yZihjb250ZXh0KSxcbiAgICAndV90aWxlX2lkJzogbmV3IFVuaWZvcm0zZihjb250ZXh0KSxcbiAgICAndV96b29tX3RyYW5zaXRpb24nOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X3VwX2Rpcic6IG5ldyBVbmlmb3JtM2YoY29udGV4dClcbn0pO1xuXG5jb25zdCBoZWF0bWFwVGV4dHVyZVVuaWZvcm1zID0gKGNvbnRleHQ6IENvbnRleHQpOiBIZWF0bWFwVGV4dHVyZVVuaWZvcm1zVHlwZSA9PiAoe1xuICAgICd1X2ltYWdlJzogbmV3IFVuaWZvcm0xaShjb250ZXh0KSxcbiAgICAndV9jb2xvcl9yYW1wJzogbmV3IFVuaWZvcm0xaShjb250ZXh0KSxcbiAgICAndV9vcGFjaXR5JzogbmV3IFVuaWZvcm0xZihjb250ZXh0KVxufSk7XG5cbmNvbnN0IGlkZW50aXR5TWF0cml4ID0gbWF0NC5jcmVhdGUoKTtcblxuY29uc3QgaGVhdG1hcFVuaWZvcm1WYWx1ZXMgPSAoXG4gICAgcGFpbnRlcjogUGFpbnRlcixcbiAgICBjb29yZDogT3ZlcnNjYWxlZFRpbGVJRCxcbiAgICB0aWxlOiBUaWxlLFxuICAgIGludk1hdHJpeDogRmxvYXQzMkFycmF5LFxuICAgIG1lcmNhdG9yQ2VudGVyOiBbbnVtYmVyLCBudW1iZXJdLFxuICAgIHpvb206IG51bWJlcixcbiAgICBpbnRlbnNpdHk6IG51bWJlclxuKTogVW5pZm9ybVZhbHVlczxIZWF0bWFwVW5pZm9ybXNUeXBlPiA9PiB7XG4gICAgY29uc3QgdHJhbnNmb3JtID0gcGFpbnRlci50cmFuc2Zvcm07XG4gICAgY29uc3QgaXNHbG9iZSA9IHRyYW5zZm9ybS5wcm9qZWN0aW9uLm5hbWUgPT09ICdnbG9iZSc7XG4gICAgY29uc3QgZXh0cnVkZVNjYWxlID0gaXNHbG9iZSA/IGdsb2JlUGl4ZWxzVG9UaWxlVW5pdHModHJhbnNmb3JtLnpvb20sIGNvb3JkLmNhbm9uaWNhbCkgKiB0cmFuc2Zvcm0uX3BpeGVsc1Blck1lcmNhdG9yUGl4ZWwgOiBwaXhlbHNUb1RpbGVVbml0cyh0aWxlLCAxLCB6b29tKTtcblxuICAgIGNvbnN0IHZhbHVlcyA9IHtcbiAgICAgICAgJ3VfbWF0cml4JzogY29vcmQucHJvak1hdHJpeCxcbiAgICAgICAgJ3VfZXh0cnVkZV9zY2FsZSc6IGV4dHJ1ZGVTY2FsZSxcbiAgICAgICAgJ3VfaW50ZW5zaXR5JzogaW50ZW5zaXR5LFxuICAgICAgICAndV9pbnZfcm90X21hdHJpeCc6IGlkZW50aXR5TWF0cml4LFxuICAgICAgICAndV9tZXJjX2NlbnRlcic6IFswLCAwXSxcbiAgICAgICAgJ3VfdGlsZV9pZCc6IFswLCAwLCAwXSxcbiAgICAgICAgJ3Vfem9vbV90cmFuc2l0aW9uJzogMCxcbiAgICAgICAgJ3VfdXBfZGlyJzogWzAsIDAsIDBdLFxuICAgIH07XG5cbiAgICBpZiAoaXNHbG9iZSkge1xuICAgICAgICB2YWx1ZXNbJ3VfaW52X3JvdF9tYXRyaXgnXSA9IGludk1hdHJpeDtcbiAgICAgICAgdmFsdWVzWyd1X21lcmNfY2VudGVyJ10gPSBtZXJjYXRvckNlbnRlcjtcbiAgICAgICAgdmFsdWVzWyd1X3RpbGVfaWQnXSA9IFtjb29yZC5jYW5vbmljYWwueCwgY29vcmQuY2Fub25pY2FsLnksIDEgPDwgY29vcmQuY2Fub25pY2FsLnpdO1xuICAgICAgICB2YWx1ZXNbJ3Vfem9vbV90cmFuc2l0aW9uJ10gPSBnbG9iZVRvTWVyY2F0b3JUcmFuc2l0aW9uKHRyYW5zZm9ybS56b29tKTtcbiAgICAgICAgY29uc3QgeCA9IG1lcmNhdG9yQ2VudGVyWzBdICogRVhURU5UO1xuICAgICAgICBjb25zdCB5ID0gbWVyY2F0b3JDZW50ZXJbMV0gKiBFWFRFTlQ7XG4gICAgICAgIHZhbHVlc1sndV91cF9kaXInXSA9ICh0cmFuc2Zvcm0ucHJvamVjdGlvbi51cFZlY3RvcihuZXcgQ2Fub25pY2FsVGlsZUlEKDAsIDAsIDApLCB4LCB5KTogYW55KTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWVzO1xufTtcblxuY29uc3QgaGVhdG1hcFRleHR1cmVVbmlmb3JtVmFsdWVzID0gKFxuICAgIHBhaW50ZXI6IFBhaW50ZXIsXG4gICAgbGF5ZXI6IEhlYXRtYXBTdHlsZUxheWVyLFxuICAgIHRleHR1cmVVbml0OiBudW1iZXIsXG4gICAgY29sb3JSYW1wVW5pdDogbnVtYmVyXG4pOiBVbmlmb3JtVmFsdWVzPEhlYXRtYXBUZXh0dXJlVW5pZm9ybXNUeXBlPiA9PiB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgJ3VfaW1hZ2UnOiB0ZXh0dXJlVW5pdCxcbiAgICAgICAgJ3VfY29sb3JfcmFtcCc6IGNvbG9yUmFtcFVuaXQsXG4gICAgICAgICd1X29wYWNpdHknOiBsYXllci5wYWludC5nZXQoJ2hlYXRtYXAtb3BhY2l0eScpXG4gICAgfTtcbn07XG5cbmV4cG9ydCB7XG4gICAgaGVhdG1hcFVuaWZvcm1zLFxuICAgIGhlYXRtYXBUZXh0dXJlVW5pZm9ybXMsXG4gICAgaGVhdG1hcFVuaWZvcm1WYWx1ZXMsXG4gICAgaGVhdG1hcFRleHR1cmVVbmlmb3JtVmFsdWVzXG59O1xuXG5leHBvcnQgdHlwZSBIZWF0bWFwRGVmaW5lc1R5cGUgPSAnUFJPSkVDVElPTl9HTE9CRV9WSUVXJztcbiIsIi8vIEBmbG93XG5cbmltcG9ydCB7XG4gICAgVW5pZm9ybTFpLFxuICAgIFVuaWZvcm0xZixcbiAgICBVbmlmb3JtMmYsXG4gICAgVW5pZm9ybU1hdHJpeDJmLFxuICAgIFVuaWZvcm1NYXRyaXg0ZlxufSBmcm9tICcuLi91bmlmb3JtX2JpbmRpbmcuanMnO1xuaW1wb3J0IHBpeGVsc1RvVGlsZVVuaXRzIGZyb20gJy4uLy4uL3NvdXJjZS9waXhlbHNfdG9fdGlsZV91bml0cy5qcyc7XG5cbmltcG9ydCB0eXBlIENvbnRleHQgZnJvbSAnLi4vLi4vZ2wvY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSB7VW5pZm9ybVZhbHVlc30gZnJvbSAnLi4vdW5pZm9ybV9iaW5kaW5nLmpzJztcbmltcG9ydCB0eXBlIFRyYW5zZm9ybSBmcm9tICcuLi8uLi9nZW8vdHJhbnNmb3JtLmpzJztcbmltcG9ydCB0eXBlIFRpbGUgZnJvbSAnLi4vLi4vc291cmNlL3RpbGUuanMnO1xuaW1wb3J0IHR5cGUgTGluZVN0eWxlTGF5ZXIgZnJvbSAnLi4vLi4vc3R5bGUvc3R5bGVfbGF5ZXIvbGluZV9zdHlsZV9sYXllci5qcyc7XG5pbXBvcnQgdHlwZSBQYWludGVyIGZyb20gJy4uL3BhaW50ZXIuanMnO1xuXG5leHBvcnQgdHlwZSBMaW5lVW5pZm9ybXNUeXBlID0ge3xcbiAgICAndV9tYXRyaXgnOiBVbmlmb3JtTWF0cml4NGYsXG4gICAgJ3VfcGl4ZWxzX3RvX3RpbGVfdW5pdHMnOiBVbmlmb3JtTWF0cml4MmYsXG4gICAgJ3VfZGV2aWNlX3BpeGVsX3JhdGlvJzogVW5pZm9ybTFmLFxuICAgICd1X3VuaXRzX3RvX3BpeGVscyc6IFVuaWZvcm0yZixcbiAgICAndV9kYXNoX2ltYWdlJzogVW5pZm9ybTFpLFxuICAgICd1X2dyYWRpZW50X2ltYWdlJzogVW5pZm9ybTFpLFxuICAgICd1X2ltYWdlX2hlaWdodCc6IFVuaWZvcm0xZixcbiAgICAndV90ZXhzaXplJzogVW5pZm9ybTJmLFxuICAgICd1X3RpbGVfdW5pdHNfdG9fcGl4ZWxzJzogVW5pZm9ybTFmLFxuICAgICd1X2FscGhhX2Rpc2NhcmRfdGhyZXNob2xkJzogVW5pZm9ybTFmLFxuICAgICd1X3RyaW1fb2Zmc2V0JzogVW5pZm9ybTJmXG58fTtcblxuZXhwb3J0IHR5cGUgTGluZVBhdHRlcm5Vbmlmb3Jtc1R5cGUgPSB7fFxuICAgICd1X21hdHJpeCc6IFVuaWZvcm1NYXRyaXg0ZixcbiAgICAndV90ZXhzaXplJzogVW5pZm9ybTJmLFxuICAgICd1X3BpeGVsc190b190aWxlX3VuaXRzJzogVW5pZm9ybU1hdHJpeDJmLFxuICAgICd1X2RldmljZV9waXhlbF9yYXRpbyc6IFVuaWZvcm0xZixcbiAgICAndV91bml0c190b19waXhlbHMnOiBVbmlmb3JtMmYsXG4gICAgJ3VfaW1hZ2UnOiBVbmlmb3JtMWksXG4gICAgJ3VfdGlsZV91bml0c190b19waXhlbHMnOiBVbmlmb3JtMWYsXG4gICAgJ3VfYWxwaGFfZGlzY2FyZF90aHJlc2hvbGQnOiBVbmlmb3JtMWZcbnx9O1xuXG5leHBvcnQgdHlwZSBMaW5lRGVmaW5lc1R5cGUgPSAnUkVOREVSX0xJTkVfR1JBRElFTlQnIHwgJ1JFTkRFUl9MSU5FX0RBU0gnIHwgJ1JFTkRFUl9MSU5FX0FMUEhBX0RJU0NBUkQnIHwgJ1JFTkRFUl9MSU5FX1RSSU1fT0ZGU0VUJztcblxuY29uc3QgbGluZVVuaWZvcm1zID0gKGNvbnRleHQ6IENvbnRleHQpOiBMaW5lVW5pZm9ybXNUeXBlID0+ICh7XG4gICAgJ3VfbWF0cml4JzogbmV3IFVuaWZvcm1NYXRyaXg0Zihjb250ZXh0KSxcbiAgICAndV9waXhlbHNfdG9fdGlsZV91bml0cyc6IG5ldyBVbmlmb3JtTWF0cml4MmYoY29udGV4dCksXG4gICAgJ3VfZGV2aWNlX3BpeGVsX3JhdGlvJzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV91bml0c190b19waXhlbHMnOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpLFxuICAgICd1X2Rhc2hfaW1hZ2UnOiBuZXcgVW5pZm9ybTFpKGNvbnRleHQpLFxuICAgICd1X2dyYWRpZW50X2ltYWdlJzogbmV3IFVuaWZvcm0xaShjb250ZXh0KSxcbiAgICAndV9pbWFnZV9oZWlnaHQnOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X3RleHNpemUnOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpLFxuICAgICd1X3RpbGVfdW5pdHNfdG9fcGl4ZWxzJzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9hbHBoYV9kaXNjYXJkX3RocmVzaG9sZCc6IG5ldyBVbmlmb3JtMWYoY29udGV4dCksXG4gICAgJ3VfdHJpbV9vZmZzZXQnOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpXG59KTtcblxuY29uc3QgbGluZVBhdHRlcm5Vbmlmb3JtcyA9IChjb250ZXh0OiBDb250ZXh0KTogTGluZVBhdHRlcm5Vbmlmb3Jtc1R5cGUgPT4gKHtcbiAgICAndV9tYXRyaXgnOiBuZXcgVW5pZm9ybU1hdHJpeDRmKGNvbnRleHQpLFxuICAgICd1X3RleHNpemUnOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpLFxuICAgICd1X3BpeGVsc190b190aWxlX3VuaXRzJzogbmV3IFVuaWZvcm1NYXRyaXgyZihjb250ZXh0KSxcbiAgICAndV9kZXZpY2VfcGl4ZWxfcmF0aW8nOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X2ltYWdlJzogbmV3IFVuaWZvcm0xaShjb250ZXh0KSxcbiAgICAndV91bml0c190b19waXhlbHMnOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpLFxuICAgICd1X3RpbGVfdW5pdHNfdG9fcGl4ZWxzJzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9hbHBoYV9kaXNjYXJkX3RocmVzaG9sZCc6IG5ldyBVbmlmb3JtMWYoY29udGV4dClcbn0pO1xuXG5jb25zdCBsaW5lVW5pZm9ybVZhbHVlcyA9IChcbiAgICBwYWludGVyOiBQYWludGVyLFxuICAgIHRpbGU6IFRpbGUsXG4gICAgbGF5ZXI6IExpbmVTdHlsZUxheWVyLFxuICAgIG1hdHJpeDogP0Zsb2F0MzJBcnJheSxcbiAgICBpbWFnZUhlaWdodDogbnVtYmVyLFxuICAgIHBpeGVsUmF0aW86IG51bWJlcixcbiAgICB0cmltT2Zmc2V0OiBbbnVtYmVyLCBudW1iZXJdLFxuKTogVW5pZm9ybVZhbHVlczxMaW5lVW5pZm9ybXNUeXBlPiA9PiB7XG4gICAgY29uc3QgdHJhbnNmb3JtID0gcGFpbnRlci50cmFuc2Zvcm07XG4gICAgY29uc3QgcGl4ZWxzVG9UaWxlVW5pdHMgPSB0cmFuc2Zvcm0uY2FsY3VsYXRlUGl4ZWxzVG9UaWxlVW5pdHNNYXRyaXgodGlsZSk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgJ3VfbWF0cml4JzogY2FsY3VsYXRlTWF0cml4KHBhaW50ZXIsIHRpbGUsIGxheWVyLCBtYXRyaXgpLFxuICAgICAgICAndV9waXhlbHNfdG9fdGlsZV91bml0cyc6IHBpeGVsc1RvVGlsZVVuaXRzLFxuICAgICAgICAndV9kZXZpY2VfcGl4ZWxfcmF0aW8nOiBwaXhlbFJhdGlvLFxuICAgICAgICAndV91bml0c190b19waXhlbHMnOiBbXG4gICAgICAgICAgICAxIC8gdHJhbnNmb3JtLnBpeGVsc1RvR0xVbml0c1swXSxcbiAgICAgICAgICAgIDEgLyB0cmFuc2Zvcm0ucGl4ZWxzVG9HTFVuaXRzWzFdXG4gICAgICAgIF0sXG4gICAgICAgICd1X2Rhc2hfaW1hZ2UnOiAwLFxuICAgICAgICAndV9ncmFkaWVudF9pbWFnZSc6IDEsXG4gICAgICAgICd1X2ltYWdlX2hlaWdodCc6IGltYWdlSGVpZ2h0LFxuICAgICAgICAndV90ZXhzaXplJzogaGFzRGFzaChsYXllcikgPyB0aWxlLmxpbmVBdGxhc1RleHR1cmUuc2l6ZSA6IFswLCAwXSxcbiAgICAgICAgJ3VfdGlsZV91bml0c190b19waXhlbHMnOiBjYWxjdWxhdGVUaWxlUmF0aW8odGlsZSwgcGFpbnRlci50cmFuc2Zvcm0pLFxuICAgICAgICAndV9hbHBoYV9kaXNjYXJkX3RocmVzaG9sZCc6IDAuMCxcbiAgICAgICAgJ3VfdHJpbV9vZmZzZXQnOiB0cmltT2Zmc2V0XG4gICAgfTtcbn07XG5cbmNvbnN0IGxpbmVQYXR0ZXJuVW5pZm9ybVZhbHVlcyA9IChcbiAgICBwYWludGVyOiBQYWludGVyLFxuICAgIHRpbGU6IFRpbGUsXG4gICAgbGF5ZXI6IExpbmVTdHlsZUxheWVyLFxuICAgIG1hdHJpeDogP0Zsb2F0MzJBcnJheSxcbiAgICBwaXhlbFJhdGlvOiBudW1iZXJcbik6IFVuaWZvcm1WYWx1ZXM8TGluZVBhdHRlcm5Vbmlmb3Jtc1R5cGU+ID0+IHtcbiAgICBjb25zdCB0cmFuc2Zvcm0gPSBwYWludGVyLnRyYW5zZm9ybTtcbiAgICByZXR1cm4ge1xuICAgICAgICAndV9tYXRyaXgnOiBjYWxjdWxhdGVNYXRyaXgocGFpbnRlciwgdGlsZSwgbGF5ZXIsIG1hdHJpeCksXG4gICAgICAgICd1X3RleHNpemUnOiB0aWxlLmltYWdlQXRsYXNUZXh0dXJlLnNpemUsXG4gICAgICAgIC8vIGNhbWVyYSB6b29tIHJhdGlvXG4gICAgICAgICd1X3BpeGVsc190b190aWxlX3VuaXRzJzogdHJhbnNmb3JtLmNhbGN1bGF0ZVBpeGVsc1RvVGlsZVVuaXRzTWF0cml4KHRpbGUpLFxuICAgICAgICAndV9kZXZpY2VfcGl4ZWxfcmF0aW8nOiBwaXhlbFJhdGlvLFxuICAgICAgICAndV9pbWFnZSc6IDAsXG4gICAgICAgICd1X3RpbGVfdW5pdHNfdG9fcGl4ZWxzJzogY2FsY3VsYXRlVGlsZVJhdGlvKHRpbGUsIHRyYW5zZm9ybSksXG4gICAgICAgICd1X3VuaXRzX3RvX3BpeGVscyc6IFtcbiAgICAgICAgICAgIDEgLyB0cmFuc2Zvcm0ucGl4ZWxzVG9HTFVuaXRzWzBdLFxuICAgICAgICAgICAgMSAvIHRyYW5zZm9ybS5waXhlbHNUb0dMVW5pdHNbMV1cbiAgICAgICAgXSxcbiAgICAgICAgJ3VfYWxwaGFfZGlzY2FyZF90aHJlc2hvbGQnOiAwLjBcbiAgICB9O1xufTtcblxuZnVuY3Rpb24gY2FsY3VsYXRlVGlsZVJhdGlvKHRpbGU6IFRpbGUsIHRyYW5zZm9ybTogVHJhbnNmb3JtKSB7XG4gICAgcmV0dXJuIDEgLyBwaXhlbHNUb1RpbGVVbml0cyh0aWxlLCAxLCB0cmFuc2Zvcm0udGlsZVpvb20pO1xufVxuXG5mdW5jdGlvbiBjYWxjdWxhdGVNYXRyaXgocGFpbnRlcjogUGFpbnRlciwgdGlsZTogVGlsZSwgbGF5ZXI6IExpbmVTdHlsZUxheWVyLCBtYXRyaXg6ID9GbG9hdDMyQXJyYXkpIHtcbiAgICByZXR1cm4gcGFpbnRlci50cmFuc2xhdGVQb3NNYXRyaXgoXG4gICAgICAgIG1hdHJpeCA/IG1hdHJpeCA6IHRpbGUudGlsZUlELnByb2pNYXRyaXgsXG4gICAgICAgIHRpbGUsXG4gICAgICAgIGxheWVyLnBhaW50LmdldCgnbGluZS10cmFuc2xhdGUnKSxcbiAgICAgICAgbGF5ZXIucGFpbnQuZ2V0KCdsaW5lLXRyYW5zbGF0ZS1hbmNob3InKVxuICAgICk7XG59XG5cbmNvbnN0IGxpbmVEZWZpbmVzVmFsdWVzID0gKGxheWVyOiBMaW5lU3R5bGVMYXllcik6IExpbmVEZWZpbmVzVHlwZVtdID0+IHtcbiAgICBjb25zdCB2YWx1ZXMgPSBbXTtcbiAgICBpZiAoaGFzRGFzaChsYXllcikpIHZhbHVlcy5wdXNoKCdSRU5ERVJfTElORV9EQVNIJyk7XG4gICAgaWYgKGxheWVyLnBhaW50LmdldCgnbGluZS1ncmFkaWVudCcpKSB2YWx1ZXMucHVzaCgnUkVOREVSX0xJTkVfR1JBRElFTlQnKTtcblxuICAgIGNvbnN0IHRyaW1PZmZzZXQgPSBsYXllci5wYWludC5nZXQoJ2xpbmUtdHJpbS1vZmZzZXQnKTtcbiAgICBpZiAodHJpbU9mZnNldFswXSAhPT0gMCB8fCB0cmltT2Zmc2V0WzFdICE9PSAwKSB7XG4gICAgICAgIHZhbHVlcy5wdXNoKCdSRU5ERVJfTElORV9UUklNX09GRlNFVCcpO1xuICAgIH1cblxuICAgIGNvbnN0IGhhc1BhdHRlcm4gPSBsYXllci5wYWludC5nZXQoJ2xpbmUtcGF0dGVybicpLmNvbnN0YW50T3IoKDE6IGFueSkpO1xuICAgIGNvbnN0IGhhc09wYWNpdHkgPSBsYXllci5wYWludC5nZXQoJ2xpbmUtb3BhY2l0eScpLmNvbnN0YW50T3IoMS4wKSAhPT0gMS4wO1xuICAgIGlmICghaGFzUGF0dGVybiAmJiBoYXNPcGFjaXR5KSB7XG4gICAgICAgIHZhbHVlcy5wdXNoKCdSRU5ERVJfTElORV9BTFBIQV9ESVNDQVJEJyk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZXM7XG59O1xuXG5mdW5jdGlvbiBoYXNEYXNoKGxheWVyOiBMaW5lU3R5bGVMYXllcikge1xuICAgIGNvbnN0IGRhc2hQcm9wZXJ0eVZhbHVlID0gbGF5ZXIucGFpbnQuZ2V0KCdsaW5lLWRhc2hhcnJheScpLnZhbHVlO1xuICAgIHJldHVybiBkYXNoUHJvcGVydHlWYWx1ZS52YWx1ZSB8fCBkYXNoUHJvcGVydHlWYWx1ZS5raW5kICE9PSBcImNvbnN0YW50XCI7XG59XG5cbmV4cG9ydCB7XG4gICAgbGluZVVuaWZvcm1zLFxuICAgIGxpbmVQYXR0ZXJuVW5pZm9ybXMsXG4gICAgbGluZVVuaWZvcm1WYWx1ZXMsXG4gICAgbGluZVBhdHRlcm5Vbmlmb3JtVmFsdWVzLFxuICAgIGxpbmVEZWZpbmVzVmFsdWVzXG59O1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtcbiAgICBVbmlmb3JtMWksXG4gICAgVW5pZm9ybTFmLFxuICAgIFVuaWZvcm0yZixcbiAgICBVbmlmb3JtM2YsXG4gICAgVW5pZm9ybU1hdHJpeDRmXG59IGZyb20gJy4uL3VuaWZvcm1fYmluZGluZy5qcyc7XG5cbmltcG9ydCB0eXBlIENvbnRleHQgZnJvbSAnLi4vLi4vZ2wvY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSB7VW5pZm9ybVZhbHVlc30gZnJvbSAnLi4vdW5pZm9ybV9iaW5kaW5nLmpzJztcbmltcG9ydCB0eXBlIFJhc3RlclN0eWxlTGF5ZXIgZnJvbSAnLi4vLi4vc3R5bGUvc3R5bGVfbGF5ZXIvcmFzdGVyX3N0eWxlX2xheWVyLmpzJztcblxuZXhwb3J0IHR5cGUgUmFzdGVyVW5pZm9ybXNUeXBlID0ge3xcbiAgICAndV9tYXRyaXgnOiBVbmlmb3JtTWF0cml4NGYsXG4gICAgJ3VfdGxfcGFyZW50JzogVW5pZm9ybTJmLFxuICAgICd1X3NjYWxlX3BhcmVudCc6IFVuaWZvcm0xZixcbiAgICAndV9mYWRlX3QnOiBVbmlmb3JtMWYsXG4gICAgJ3Vfb3BhY2l0eSc6IFVuaWZvcm0xZixcbiAgICAndV9pbWFnZTAnOiBVbmlmb3JtMWksXG4gICAgJ3VfaW1hZ2UxJzogVW5pZm9ybTFpLFxuICAgICd1X2JyaWdodG5lc3NfbG93JzogVW5pZm9ybTFmLFxuICAgICd1X2JyaWdodG5lc3NfaGlnaCc6IFVuaWZvcm0xZixcbiAgICAndV9zYXR1cmF0aW9uX2ZhY3Rvcic6IFVuaWZvcm0xZixcbiAgICAndV9jb250cmFzdF9mYWN0b3InOiBVbmlmb3JtMWYsXG4gICAgJ3Vfc3Bpbl93ZWlnaHRzJzogVW5pZm9ybTNmLFxuICAgICd1X3BlcnNwZWN0aXZlX3RyYW5zZm9ybSc6IFVuaWZvcm0yZlxufH07XG5cbmNvbnN0IHJhc3RlclVuaWZvcm1zID0gKGNvbnRleHQ6IENvbnRleHQpOiBSYXN0ZXJVbmlmb3Jtc1R5cGUgPT4gKHtcbiAgICAndV9tYXRyaXgnOiBuZXcgVW5pZm9ybU1hdHJpeDRmKGNvbnRleHQpLFxuICAgICd1X3RsX3BhcmVudCc6IG5ldyBVbmlmb3JtMmYoY29udGV4dCksXG4gICAgJ3Vfc2NhbGVfcGFyZW50JzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9mYWRlX3QnOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X29wYWNpdHknOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X2ltYWdlMCc6IG5ldyBVbmlmb3JtMWkoY29udGV4dCksXG4gICAgJ3VfaW1hZ2UxJzogbmV3IFVuaWZvcm0xaShjb250ZXh0KSxcbiAgICAndV9icmlnaHRuZXNzX2xvdyc6IG5ldyBVbmlmb3JtMWYoY29udGV4dCksXG4gICAgJ3VfYnJpZ2h0bmVzc19oaWdoJzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9zYXR1cmF0aW9uX2ZhY3Rvcic6IG5ldyBVbmlmb3JtMWYoY29udGV4dCksXG4gICAgJ3VfY29udHJhc3RfZmFjdG9yJzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9zcGluX3dlaWdodHMnOiBuZXcgVW5pZm9ybTNmKGNvbnRleHQpLFxuICAgICd1X3BlcnNwZWN0aXZlX3RyYW5zZm9ybSc6IG5ldyBVbmlmb3JtMmYoY29udGV4dClcbn0pO1xuXG5jb25zdCByYXN0ZXJVbmlmb3JtVmFsdWVzID0gKFxuICAgIG1hdHJpeDogRmxvYXQzMkFycmF5LFxuICAgIHBhcmVudFRMOiBbbnVtYmVyLCBudW1iZXJdLFxuICAgIHBhcmVudFNjYWxlQnk6IG51bWJlcixcbiAgICBmYWRlOiB7bWl4OiBudW1iZXIsIG9wYWNpdHk6IG51bWJlcn0sXG4gICAgbGF5ZXI6IFJhc3RlclN0eWxlTGF5ZXIsXG4gICAgcGVyc3BlY3RpdmVUcmFuc2Zvcm06IFtudW1iZXIsIG51bWJlcl1cbik6IFVuaWZvcm1WYWx1ZXM8UmFzdGVyVW5pZm9ybXNUeXBlPiA9PiAoe1xuICAgICd1X21hdHJpeCc6IG1hdHJpeCxcbiAgICAndV90bF9wYXJlbnQnOiBwYXJlbnRUTCxcbiAgICAndV9zY2FsZV9wYXJlbnQnOiBwYXJlbnRTY2FsZUJ5LFxuICAgICd1X2ZhZGVfdCc6IGZhZGUubWl4LFxuICAgICd1X29wYWNpdHknOiBmYWRlLm9wYWNpdHkgKiBsYXllci5wYWludC5nZXQoJ3Jhc3Rlci1vcGFjaXR5JyksXG4gICAgJ3VfaW1hZ2UwJzogMCxcbiAgICAndV9pbWFnZTEnOiAxLFxuICAgICd1X2JyaWdodG5lc3NfbG93JzogbGF5ZXIucGFpbnQuZ2V0KCdyYXN0ZXItYnJpZ2h0bmVzcy1taW4nKSxcbiAgICAndV9icmlnaHRuZXNzX2hpZ2gnOiBsYXllci5wYWludC5nZXQoJ3Jhc3Rlci1icmlnaHRuZXNzLW1heCcpLFxuICAgICd1X3NhdHVyYXRpb25fZmFjdG9yJzogc2F0dXJhdGlvbkZhY3RvcihsYXllci5wYWludC5nZXQoJ3Jhc3Rlci1zYXR1cmF0aW9uJykpLFxuICAgICd1X2NvbnRyYXN0X2ZhY3Rvcic6IGNvbnRyYXN0RmFjdG9yKGxheWVyLnBhaW50LmdldCgncmFzdGVyLWNvbnRyYXN0JykpLFxuICAgICd1X3NwaW5fd2VpZ2h0cyc6IHNwaW5XZWlnaHRzKGxheWVyLnBhaW50LmdldCgncmFzdGVyLWh1ZS1yb3RhdGUnKSksXG4gICAgJ3VfcGVyc3BlY3RpdmVfdHJhbnNmb3JtJzogcGVyc3BlY3RpdmVUcmFuc2Zvcm1cbn0pO1xuXG5mdW5jdGlvbiBzcGluV2VpZ2h0cyhhbmdsZTogbnVtYmVyKSB7XG4gICAgYW5nbGUgKj0gTWF0aC5QSSAvIDE4MDtcbiAgICBjb25zdCBzID0gTWF0aC5zaW4oYW5nbGUpO1xuICAgIGNvbnN0IGMgPSBNYXRoLmNvcyhhbmdsZSk7XG4gICAgcmV0dXJuIFtcbiAgICAgICAgKDIgKiBjICsgMSkgLyAzLFxuICAgICAgICAoLU1hdGguc3FydCgzKSAqIHMgLSBjICsgMSkgLyAzLFxuICAgICAgICAoTWF0aC5zcXJ0KDMpICogcyAtIGMgKyAxKSAvIDNcbiAgICBdO1xufVxuXG5mdW5jdGlvbiBjb250cmFzdEZhY3Rvcihjb250cmFzdDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIGNvbnRyYXN0ID4gMCA/XG4gICAgICAgIDEgLyAoMSAtIGNvbnRyYXN0KSA6XG4gICAgICAgIDEgKyBjb250cmFzdDtcbn1cblxuZnVuY3Rpb24gc2F0dXJhdGlvbkZhY3RvcihzYXR1cmF0aW9uOiBudW1iZXIpIHtcbiAgICByZXR1cm4gc2F0dXJhdGlvbiA+IDAgP1xuICAgICAgICAxIC0gMSAvICgxLjAwMSAtIHNhdHVyYXRpb24pIDpcbiAgICAgICAgLXNhdHVyYXRpb247XG59XG5cbmV4cG9ydCB7cmFzdGVyVW5pZm9ybXMsIHJhc3RlclVuaWZvcm1WYWx1ZXN9O1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtcbiAgICBVbmlmb3JtMWksXG4gICAgVW5pZm9ybTFmLFxuICAgIFVuaWZvcm0yZixcbiAgICBVbmlmb3JtM2YsXG4gICAgVW5pZm9ybU1hdHJpeDRmXG59IGZyb20gJy4uL3VuaWZvcm1fYmluZGluZy5qcyc7XG5pbXBvcnQge21hdDR9IGZyb20gJ2dsLW1hdHJpeCc7XG5pbXBvcnQge2V4dGVuZH0gZnJvbSAnLi4vLi4vdXRpbC91dGlsLmpzJztcbmltcG9ydCBicm93c2VyIGZyb20gJy4uLy4uL3V0aWwvYnJvd3Nlci5qcyc7XG5pbXBvcnQge092ZXJzY2FsZWRUaWxlSUR9IGZyb20gJy4uLy4uL3NvdXJjZS90aWxlX2lkLmpzJztcbmltcG9ydCB0eXBlIENvbnRleHQgZnJvbSAnLi4vLi4vZ2wvY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSBQYWludGVyIGZyb20gJy4uL3BhaW50ZXIuanMnO1xuaW1wb3J0IHR5cGUge1VuaWZvcm1WYWx1ZXN9IGZyb20gJy4uL3VuaWZvcm1fYmluZGluZy5qcyc7XG5pbXBvcnQge2dsb2JlRUNFRk9yaWdpbn0gZnJvbSAnLi4vLi4vZ2VvL3Byb2plY3Rpb24vZ2xvYmVfdXRpbC5qcyc7XG5pbXBvcnQgdHlwZSBQcm9qZWN0aW9uIGZyb20gJy4uLy4uL2dlby9wcm9qZWN0aW9uL3Byb2plY3Rpb24uanMnO1xuXG5pbXBvcnQgdHlwZSB7SW50ZXJwb2xhdGVkU2l6ZX0gZnJvbSAnLi4vLi4vc3ltYm9sL3N5bWJvbF9zaXplLmpzJztcblxuZXhwb3J0IHR5cGUgU3ltYm9sSWNvblVuaWZvcm1zVHlwZSA9IHt8XG4gICAgJ3VfaXNfc2l6ZV96b29tX2NvbnN0YW50JzogVW5pZm9ybTFpLFxuICAgICd1X2lzX3NpemVfZmVhdHVyZV9jb25zdGFudCc6IFVuaWZvcm0xaSxcbiAgICAndV9zaXplX3QnOiBVbmlmb3JtMWYsXG4gICAgJ3Vfc2l6ZSc6IFVuaWZvcm0xZixcbiAgICAndV9jYW1lcmFfdG9fY2VudGVyX2Rpc3RhbmNlJzogVW5pZm9ybTFmLFxuICAgICd1X3JvdGF0ZV9zeW1ib2wnOiBVbmlmb3JtMWksXG4gICAgJ3VfYXNwZWN0X3JhdGlvJzogVW5pZm9ybTFmLFxuICAgICd1X2ZhZGVfY2hhbmdlJzogVW5pZm9ybTFmLFxuICAgICd1X21hdHJpeCc6IFVuaWZvcm1NYXRyaXg0ZixcbiAgICAndV9sYWJlbF9wbGFuZV9tYXRyaXgnOiBVbmlmb3JtTWF0cml4NGYsXG4gICAgJ3VfY29vcmRfbWF0cml4JzogVW5pZm9ybU1hdHJpeDRmLFxuICAgICd1X2lzX3RleHQnOiBVbmlmb3JtMWksXG4gICAgJ3VfcGl0Y2hfd2l0aF9tYXAnOiBVbmlmb3JtMWksXG4gICAgJ3VfdGV4c2l6ZSc6IFVuaWZvcm0yZixcbiAgICAndV90aWxlX2lkJzogVW5pZm9ybTNmLFxuICAgICd1X3pvb21fdHJhbnNpdGlvbic6IFVuaWZvcm0xZixcbiAgICAndV9pbnZfcm90X21hdHJpeCc6IFVuaWZvcm1NYXRyaXg0ZixcbiAgICAndV9tZXJjX2NlbnRlcic6IFVuaWZvcm0yZixcbiAgICAndV9jYW1lcmFfZm9yd2FyZCc6IFVuaWZvcm0zZixcbiAgICAndV90aWxlX21hdHJpeCc6IFVuaWZvcm1NYXRyaXg0ZixcbiAgICAndV91cF92ZWN0b3InOiBVbmlmb3JtM2YsXG4gICAgJ3VfZWNlZl9vcmlnaW4nOiBVbmlmb3JtM2YsXG4gICAgJ3VfdGV4dHVyZSc6IFVuaWZvcm0xaVxufH07XG5cbmV4cG9ydCB0eXBlIFN5bWJvbFNERlVuaWZvcm1zVHlwZSA9IHt8XG4gICAgJ3VfaXNfc2l6ZV96b29tX2NvbnN0YW50JzogVW5pZm9ybTFpLFxuICAgICd1X2lzX3NpemVfZmVhdHVyZV9jb25zdGFudCc6IFVuaWZvcm0xaSxcbiAgICAndV9zaXplX3QnOiBVbmlmb3JtMWYsXG4gICAgJ3Vfc2l6ZSc6IFVuaWZvcm0xZixcbiAgICAndV9jYW1lcmFfdG9fY2VudGVyX2Rpc3RhbmNlJzogVW5pZm9ybTFmLFxuICAgICd1X3JvdGF0ZV9zeW1ib2wnOiBVbmlmb3JtMWksXG4gICAgJ3VfYXNwZWN0X3JhdGlvJzogVW5pZm9ybTFmLFxuICAgICd1X2ZhZGVfY2hhbmdlJzogVW5pZm9ybTFmLFxuICAgICd1X21hdHJpeCc6IFVuaWZvcm1NYXRyaXg0ZixcbiAgICAndV9sYWJlbF9wbGFuZV9tYXRyaXgnOiBVbmlmb3JtTWF0cml4NGYsXG4gICAgJ3VfY29vcmRfbWF0cml4JzogVW5pZm9ybU1hdHJpeDRmLFxuICAgICd1X2lzX3RleHQnOiBVbmlmb3JtMWksXG4gICAgJ3VfcGl0Y2hfd2l0aF9tYXAnOiBVbmlmb3JtMWksXG4gICAgJ3VfdGV4c2l6ZSc6IFVuaWZvcm0yZixcbiAgICAndV90ZXh0dXJlJzogVW5pZm9ybTFpLFxuICAgICd1X2dhbW1hX3NjYWxlJzogVW5pZm9ybTFmLFxuICAgICd1X2RldmljZV9waXhlbF9yYXRpbyc6IFVuaWZvcm0xZixcbiAgICAndV90aWxlX2lkJzogVW5pZm9ybTNmLFxuICAgICd1X3pvb21fdHJhbnNpdGlvbic6IFVuaWZvcm0xZixcbiAgICAndV9pbnZfcm90X21hdHJpeCc6IFVuaWZvcm1NYXRyaXg0ZixcbiAgICAndV9tZXJjX2NlbnRlcic6IFVuaWZvcm0yZixcbiAgICAndV9jYW1lcmFfZm9yd2FyZCc6IFVuaWZvcm0zZixcbiAgICAndV90aWxlX21hdHJpeCc6IFVuaWZvcm1NYXRyaXg0ZixcbiAgICAndV91cF92ZWN0b3InOiBVbmlmb3JtM2YsXG4gICAgJ3VfZWNlZl9vcmlnaW4nOiBVbmlmb3JtM2YsXG4gICAgJ3VfaXNfaGFsbyc6IFVuaWZvcm0xaVxufH07XG5cbmV4cG9ydCB0eXBlIHN5bWJvbFRleHRBbmRJY29uVW5pZm9ybXNUeXBlID0ge3xcbiAgICAndV9pc19zaXplX3pvb21fY29uc3RhbnQnOiBVbmlmb3JtMWksXG4gICAgJ3VfaXNfc2l6ZV9mZWF0dXJlX2NvbnN0YW50JzogVW5pZm9ybTFpLFxuICAgICd1X3NpemVfdCc6IFVuaWZvcm0xZixcbiAgICAndV9zaXplJzogVW5pZm9ybTFmLFxuICAgICd1X2NhbWVyYV90b19jZW50ZXJfZGlzdGFuY2UnOiBVbmlmb3JtMWYsXG4gICAgJ3Vfcm90YXRlX3N5bWJvbCc6IFVuaWZvcm0xaSxcbiAgICAndV9hc3BlY3RfcmF0aW8nOiBVbmlmb3JtMWYsXG4gICAgJ3VfZmFkZV9jaGFuZ2UnOiBVbmlmb3JtMWYsXG4gICAgJ3VfbWF0cml4JzogVW5pZm9ybU1hdHJpeDRmLFxuICAgICd1X2xhYmVsX3BsYW5lX21hdHJpeCc6IFVuaWZvcm1NYXRyaXg0ZixcbiAgICAndV9jb29yZF9tYXRyaXgnOiBVbmlmb3JtTWF0cml4NGYsXG4gICAgJ3VfaXNfdGV4dCc6IFVuaWZvcm0xaSxcbiAgICAndV9waXRjaF93aXRoX21hcCc6IFVuaWZvcm0xaSxcbiAgICAndV90ZXhzaXplJzogVW5pZm9ybTJmLFxuICAgICd1X3RleHNpemVfaWNvbic6IFVuaWZvcm0yZixcbiAgICAndV90ZXh0dXJlJzogVW5pZm9ybTFpLFxuICAgICd1X3RleHR1cmVfaWNvbic6IFVuaWZvcm0xaSxcbiAgICAndV9nYW1tYV9zY2FsZSc6IFVuaWZvcm0xZixcbiAgICAndV9kZXZpY2VfcGl4ZWxfcmF0aW8nOiBVbmlmb3JtMWYsXG4gICAgJ3VfaXNfaGFsbyc6IFVuaWZvcm0xaVxufH07XG5cbmV4cG9ydCB0eXBlIFN5bWJvbERlZmluZXNUeXBlID0gJ1BJVENIX1dJVEhfTUFQX1RFUlJBSU4nO1xuXG5jb25zdCBzeW1ib2xJY29uVW5pZm9ybXMgPSAoY29udGV4dDogQ29udGV4dCk6IFN5bWJvbEljb25Vbmlmb3Jtc1R5cGUgPT4gKHtcbiAgICAndV9pc19zaXplX3pvb21fY29uc3RhbnQnOiBuZXcgVW5pZm9ybTFpKGNvbnRleHQpLFxuICAgICd1X2lzX3NpemVfZmVhdHVyZV9jb25zdGFudCc6IG5ldyBVbmlmb3JtMWkoY29udGV4dCksXG4gICAgJ3Vfc2l6ZV90JzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9zaXplJzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9jYW1lcmFfdG9fY2VudGVyX2Rpc3RhbmNlJzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9yb3RhdGVfc3ltYm9sJzogbmV3IFVuaWZvcm0xaShjb250ZXh0KSxcbiAgICAndV9hc3BlY3RfcmF0aW8nOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X2ZhZGVfY2hhbmdlJzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9tYXRyaXgnOiBuZXcgVW5pZm9ybU1hdHJpeDRmKGNvbnRleHQpLFxuICAgICd1X2xhYmVsX3BsYW5lX21hdHJpeCc6IG5ldyBVbmlmb3JtTWF0cml4NGYoY29udGV4dCksXG4gICAgJ3VfY29vcmRfbWF0cml4JzogbmV3IFVuaWZvcm1NYXRyaXg0Zihjb250ZXh0KSxcbiAgICAndV9pc190ZXh0JzogbmV3IFVuaWZvcm0xaShjb250ZXh0KSxcbiAgICAndV9waXRjaF93aXRoX21hcCc6IG5ldyBVbmlmb3JtMWkoY29udGV4dCksXG4gICAgJ3VfdGV4c2l6ZSc6IG5ldyBVbmlmb3JtMmYoY29udGV4dCksXG4gICAgJ3VfdGlsZV9pZCc6IG5ldyBVbmlmb3JtM2YoY29udGV4dCksXG4gICAgJ3Vfem9vbV90cmFuc2l0aW9uJzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9pbnZfcm90X21hdHJpeCc6IG5ldyBVbmlmb3JtTWF0cml4NGYoY29udGV4dCksXG4gICAgJ3VfbWVyY19jZW50ZXInOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpLFxuICAgICd1X2NhbWVyYV9mb3J3YXJkJzogbmV3IFVuaWZvcm0zZihjb250ZXh0KSxcbiAgICAndV90aWxlX21hdHJpeCc6IG5ldyBVbmlmb3JtTWF0cml4NGYoY29udGV4dCksXG4gICAgJ3VfdXBfdmVjdG9yJzogbmV3IFVuaWZvcm0zZihjb250ZXh0KSxcbiAgICAndV9lY2VmX29yaWdpbic6IG5ldyBVbmlmb3JtM2YoY29udGV4dCksXG4gICAgJ3VfdGV4dHVyZSc6IG5ldyBVbmlmb3JtMWkoY29udGV4dClcbn0pO1xuXG5jb25zdCBzeW1ib2xTREZVbmlmb3JtcyA9IChjb250ZXh0OiBDb250ZXh0KTogU3ltYm9sU0RGVW5pZm9ybXNUeXBlID0+ICh7XG4gICAgJ3VfaXNfc2l6ZV96b29tX2NvbnN0YW50JzogbmV3IFVuaWZvcm0xaShjb250ZXh0KSxcbiAgICAndV9pc19zaXplX2ZlYXR1cmVfY29uc3RhbnQnOiBuZXcgVW5pZm9ybTFpKGNvbnRleHQpLFxuICAgICd1X3NpemVfdCc6IG5ldyBVbmlmb3JtMWYoY29udGV4dCksXG4gICAgJ3Vfc2l6ZSc6IG5ldyBVbmlmb3JtMWYoY29udGV4dCksXG4gICAgJ3VfY2FtZXJhX3RvX2NlbnRlcl9kaXN0YW5jZSc6IG5ldyBVbmlmb3JtMWYoY29udGV4dCksXG4gICAgJ3Vfcm90YXRlX3N5bWJvbCc6IG5ldyBVbmlmb3JtMWkoY29udGV4dCksXG4gICAgJ3VfYXNwZWN0X3JhdGlvJzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9mYWRlX2NoYW5nZSc6IG5ldyBVbmlmb3JtMWYoY29udGV4dCksXG4gICAgJ3VfbWF0cml4JzogbmV3IFVuaWZvcm1NYXRyaXg0Zihjb250ZXh0KSxcbiAgICAndV9sYWJlbF9wbGFuZV9tYXRyaXgnOiBuZXcgVW5pZm9ybU1hdHJpeDRmKGNvbnRleHQpLFxuICAgICd1X2Nvb3JkX21hdHJpeCc6IG5ldyBVbmlmb3JtTWF0cml4NGYoY29udGV4dCksXG4gICAgJ3VfaXNfdGV4dCc6IG5ldyBVbmlmb3JtMWkoY29udGV4dCksXG4gICAgJ3VfcGl0Y2hfd2l0aF9tYXAnOiBuZXcgVW5pZm9ybTFpKGNvbnRleHQpLFxuICAgICd1X3RleHNpemUnOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpLFxuICAgICd1X3RleHR1cmUnOiBuZXcgVW5pZm9ybTFpKGNvbnRleHQpLFxuICAgICd1X2dhbW1hX3NjYWxlJzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9kZXZpY2VfcGl4ZWxfcmF0aW8nOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X3RpbGVfaWQnOiBuZXcgVW5pZm9ybTNmKGNvbnRleHQpLFxuICAgICd1X3pvb21fdHJhbnNpdGlvbic6IG5ldyBVbmlmb3JtMWYoY29udGV4dCksXG4gICAgJ3VfaW52X3JvdF9tYXRyaXgnOiBuZXcgVW5pZm9ybU1hdHJpeDRmKGNvbnRleHQpLFxuICAgICd1X21lcmNfY2VudGVyJzogbmV3IFVuaWZvcm0yZihjb250ZXh0KSxcbiAgICAndV9jYW1lcmFfZm9yd2FyZCc6IG5ldyBVbmlmb3JtM2YoY29udGV4dCksXG4gICAgJ3VfdGlsZV9tYXRyaXgnOiBuZXcgVW5pZm9ybU1hdHJpeDRmKGNvbnRleHQpLFxuICAgICd1X3VwX3ZlY3Rvcic6IG5ldyBVbmlmb3JtM2YoY29udGV4dCksXG4gICAgJ3VfZWNlZl9vcmlnaW4nOiBuZXcgVW5pZm9ybTNmKGNvbnRleHQpLFxuICAgICd1X2lzX2hhbG8nOiBuZXcgVW5pZm9ybTFpKGNvbnRleHQpXG59KTtcblxuY29uc3Qgc3ltYm9sVGV4dEFuZEljb25Vbmlmb3JtcyA9IChjb250ZXh0OiBDb250ZXh0KTogc3ltYm9sVGV4dEFuZEljb25Vbmlmb3Jtc1R5cGUgPT4gKHtcbiAgICAndV9pc19zaXplX3pvb21fY29uc3RhbnQnOiBuZXcgVW5pZm9ybTFpKGNvbnRleHQpLFxuICAgICd1X2lzX3NpemVfZmVhdHVyZV9jb25zdGFudCc6IG5ldyBVbmlmb3JtMWkoY29udGV4dCksXG4gICAgJ3Vfc2l6ZV90JzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9zaXplJzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9jYW1lcmFfdG9fY2VudGVyX2Rpc3RhbmNlJzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9yb3RhdGVfc3ltYm9sJzogbmV3IFVuaWZvcm0xaShjb250ZXh0KSxcbiAgICAndV9hc3BlY3RfcmF0aW8nOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X2ZhZGVfY2hhbmdlJzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9tYXRyaXgnOiBuZXcgVW5pZm9ybU1hdHJpeDRmKGNvbnRleHQpLFxuICAgICd1X2xhYmVsX3BsYW5lX21hdHJpeCc6IG5ldyBVbmlmb3JtTWF0cml4NGYoY29udGV4dCksXG4gICAgJ3VfY29vcmRfbWF0cml4JzogbmV3IFVuaWZvcm1NYXRyaXg0Zihjb250ZXh0KSxcbiAgICAndV9pc190ZXh0JzogbmV3IFVuaWZvcm0xaShjb250ZXh0KSxcbiAgICAndV9waXRjaF93aXRoX21hcCc6IG5ldyBVbmlmb3JtMWkoY29udGV4dCksXG4gICAgJ3VfdGV4c2l6ZSc6IG5ldyBVbmlmb3JtMmYoY29udGV4dCksXG4gICAgJ3VfdGV4c2l6ZV9pY29uJzogbmV3IFVuaWZvcm0yZihjb250ZXh0KSxcbiAgICAndV90ZXh0dXJlJzogbmV3IFVuaWZvcm0xaShjb250ZXh0KSxcbiAgICAndV90ZXh0dXJlX2ljb24nOiBuZXcgVW5pZm9ybTFpKGNvbnRleHQpLFxuICAgICd1X2dhbW1hX3NjYWxlJzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9kZXZpY2VfcGl4ZWxfcmF0aW8nOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X2lzX2hhbG8nOiBuZXcgVW5pZm9ybTFpKGNvbnRleHQpXG59KTtcblxuY29uc3QgaWRlbnRpdHlNYXRyaXggPSBtYXQ0LmNyZWF0ZSgpO1xuXG5jb25zdCBzeW1ib2xJY29uVW5pZm9ybVZhbHVlcyA9IChcbiAgICBmdW5jdGlvblR5cGU6IHN0cmluZyxcbiAgICBzaXplOiA/SW50ZXJwb2xhdGVkU2l6ZSxcbiAgICByb3RhdGVJblNoYWRlcjogYm9vbGVhbixcbiAgICBwaXRjaFdpdGhNYXA6IGJvb2xlYW4sXG4gICAgcGFpbnRlcjogUGFpbnRlcixcbiAgICBtYXRyaXg6IEZsb2F0MzJBcnJheSxcbiAgICBsYWJlbFBsYW5lTWF0cml4OiBGbG9hdDMyQXJyYXksXG4gICAgZ2xDb29yZE1hdHJpeDogRmxvYXQzMkFycmF5LFxuICAgIGlzVGV4dDogYm9vbGVhbixcbiAgICB0ZXhTaXplOiBbbnVtYmVyLCBudW1iZXJdLFxuICAgIGNvb3JkOiBPdmVyc2NhbGVkVGlsZUlELFxuICAgIHpvb21UcmFuc2l0aW9uOiBudW1iZXIsXG4gICAgbWVyY2F0b3JDZW50ZXI6IFtudW1iZXIsIG51bWJlcl0sXG4gICAgaW52TWF0cml4OiBGbG9hdDMyQXJyYXksXG4gICAgdXBWZWN0b3I6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICBwcm9qZWN0aW9uOiBQcm9qZWN0aW9uXG4pOiBVbmlmb3JtVmFsdWVzPFN5bWJvbEljb25Vbmlmb3Jtc1R5cGU+ID0+IHtcbiAgICBjb25zdCB0cmFuc2Zvcm0gPSBwYWludGVyLnRyYW5zZm9ybTtcblxuICAgIGNvbnN0IHZhbHVlcyA9IHtcbiAgICAgICAgJ3VfaXNfc2l6ZV96b29tX2NvbnN0YW50JzogKyhmdW5jdGlvblR5cGUgPT09ICdjb25zdGFudCcgfHwgZnVuY3Rpb25UeXBlID09PSAnc291cmNlJyksXG4gICAgICAgICd1X2lzX3NpemVfZmVhdHVyZV9jb25zdGFudCc6ICsoZnVuY3Rpb25UeXBlID09PSAnY29uc3RhbnQnIHx8IGZ1bmN0aW9uVHlwZSA9PT0gJ2NhbWVyYScpLFxuICAgICAgICAndV9zaXplX3QnOiBzaXplID8gc2l6ZS51U2l6ZVQgOiAwLFxuICAgICAgICAndV9zaXplJzogc2l6ZSA/IHNpemUudVNpemUgOiAwLFxuICAgICAgICAndV9jYW1lcmFfdG9fY2VudGVyX2Rpc3RhbmNlJzogdHJhbnNmb3JtLmNhbWVyYVRvQ2VudGVyRGlzdGFuY2UsXG4gICAgICAgICd1X3JvdGF0ZV9zeW1ib2wnOiArcm90YXRlSW5TaGFkZXIsXG4gICAgICAgICd1X2FzcGVjdF9yYXRpbyc6IHRyYW5zZm9ybS53aWR0aCAvIHRyYW5zZm9ybS5oZWlnaHQsXG4gICAgICAgICd1X2ZhZGVfY2hhbmdlJzogcGFpbnRlci5vcHRpb25zLmZhZGVEdXJhdGlvbiA/IHBhaW50ZXIuc3ltYm9sRmFkZUNoYW5nZSA6IDEsXG4gICAgICAgICd1X21hdHJpeCc6IG1hdHJpeCxcbiAgICAgICAgJ3VfbGFiZWxfcGxhbmVfbWF0cml4JzogbGFiZWxQbGFuZU1hdHJpeCxcbiAgICAgICAgJ3VfY29vcmRfbWF0cml4JzogZ2xDb29yZE1hdHJpeCxcbiAgICAgICAgJ3VfaXNfdGV4dCc6ICtpc1RleHQsXG4gICAgICAgICd1X3BpdGNoX3dpdGhfbWFwJzogK3BpdGNoV2l0aE1hcCxcbiAgICAgICAgJ3VfdGV4c2l6ZSc6IHRleFNpemUsXG4gICAgICAgICd1X3RleHR1cmUnOiAwLFxuICAgICAgICAndV90aWxlX2lkJzogWzAsIDAsIDBdLFxuICAgICAgICAndV96b29tX3RyYW5zaXRpb24nOiAwLFxuICAgICAgICAndV9pbnZfcm90X21hdHJpeCc6IGlkZW50aXR5TWF0cml4LFxuICAgICAgICAndV9tZXJjX2NlbnRlcic6IFswLCAwXSxcbiAgICAgICAgJ3VfY2FtZXJhX2ZvcndhcmQnOiBbMCwgMCwgMF0sXG4gICAgICAgICd1X2VjZWZfb3JpZ2luJzogWzAsIDAsIDBdLFxuICAgICAgICAndV90aWxlX21hdHJpeCc6IGlkZW50aXR5TWF0cml4LFxuICAgICAgICAndV91cF92ZWN0b3InOiBbMCwgLTEsIDBdXG4gICAgfTtcblxuICAgIGlmIChwcm9qZWN0aW9uLm5hbWUgPT09ICdnbG9iZScpIHtcbiAgICAgICAgdmFsdWVzWyd1X3RpbGVfaWQnXSA9IFtjb29yZC5jYW5vbmljYWwueCwgY29vcmQuY2Fub25pY2FsLnksIDEgPDwgY29vcmQuY2Fub25pY2FsLnpdO1xuICAgICAgICB2YWx1ZXNbJ3Vfem9vbV90cmFuc2l0aW9uJ10gPSB6b29tVHJhbnNpdGlvbjtcbiAgICAgICAgdmFsdWVzWyd1X2ludl9yb3RfbWF0cml4J10gPSBpbnZNYXRyaXg7XG4gICAgICAgIHZhbHVlc1sndV9tZXJjX2NlbnRlciddID0gbWVyY2F0b3JDZW50ZXI7XG4gICAgICAgIHZhbHVlc1sndV9jYW1lcmFfZm9yd2FyZCddID0gKCh0cmFuc2Zvcm0uX2NhbWVyYS5mb3J3YXJkKCk6IGFueSk6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSk7XG4gICAgICAgIHZhbHVlc1sndV9lY2VmX29yaWdpbiddID0gZ2xvYmVFQ0VGT3JpZ2luKHRyYW5zZm9ybS5nbG9iZU1hdHJpeCwgY29vcmQudG9VbndyYXBwZWQoKSk7XG4gICAgICAgIHZhbHVlc1sndV90aWxlX21hdHJpeCddID0gRmxvYXQzMkFycmF5LmZyb20odHJhbnNmb3JtLmdsb2JlTWF0cml4KTtcbiAgICAgICAgdmFsdWVzWyd1X3VwX3ZlY3RvciddID0gdXBWZWN0b3I7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlcztcbn07XG5cbmNvbnN0IHN5bWJvbFNERlVuaWZvcm1WYWx1ZXMgPSAoXG4gICAgZnVuY3Rpb25UeXBlOiBzdHJpbmcsXG4gICAgc2l6ZTogP0ludGVycG9sYXRlZFNpemUsXG4gICAgcm90YXRlSW5TaGFkZXI6IGJvb2xlYW4sXG4gICAgcGl0Y2hXaXRoTWFwOiBib29sZWFuLFxuICAgIHBhaW50ZXI6IFBhaW50ZXIsXG4gICAgbWF0cml4OiBGbG9hdDMyQXJyYXksXG4gICAgbGFiZWxQbGFuZU1hdHJpeDogRmxvYXQzMkFycmF5LFxuICAgIGdsQ29vcmRNYXRyaXg6IEZsb2F0MzJBcnJheSxcbiAgICBpc1RleHQ6IGJvb2xlYW4sXG4gICAgdGV4U2l6ZTogW251bWJlciwgbnVtYmVyXSxcbiAgICBpc0hhbG86IGJvb2xlYW4sXG4gICAgY29vcmQ6IE92ZXJzY2FsZWRUaWxlSUQsXG4gICAgem9vbVRyYW5zaXRpb246IG51bWJlcixcbiAgICBtZXJjYXRvckNlbnRlcjogW251bWJlciwgbnVtYmVyXSxcbiAgICBpbnZNYXRyaXg6IEZsb2F0MzJBcnJheSxcbiAgICB1cFZlY3RvcjogW251bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgIHByb2plY3Rpb246IFByb2plY3Rpb25cbik6IFVuaWZvcm1WYWx1ZXM8U3ltYm9sU0RGVW5pZm9ybXNUeXBlPiA9PiB7XG4gICAgcmV0dXJuIGV4dGVuZChzeW1ib2xJY29uVW5pZm9ybVZhbHVlcyhmdW5jdGlvblR5cGUsIHNpemUsIHJvdGF0ZUluU2hhZGVyLFxuICAgICAgICBwaXRjaFdpdGhNYXAsIHBhaW50ZXIsIG1hdHJpeCwgbGFiZWxQbGFuZU1hdHJpeCwgZ2xDb29yZE1hdHJpeCwgaXNUZXh0LFxuICAgICAgICB0ZXhTaXplLCBjb29yZCwgem9vbVRyYW5zaXRpb24sIG1lcmNhdG9yQ2VudGVyLCBpbnZNYXRyaXgsIHVwVmVjdG9yLCBwcm9qZWN0aW9uKSwge1xuICAgICAgICAndV9nYW1tYV9zY2FsZSc6IHBpdGNoV2l0aE1hcCA/IHBhaW50ZXIudHJhbnNmb3JtLmNhbWVyYVRvQ2VudGVyRGlzdGFuY2UgKiBNYXRoLmNvcyhwYWludGVyLnRlcnJhaW4gPyAwIDogcGFpbnRlci50cmFuc2Zvcm0uX3BpdGNoKSA6IDEsXG4gICAgICAgICd1X2RldmljZV9waXhlbF9yYXRpbyc6IGJyb3dzZXIuZGV2aWNlUGl4ZWxSYXRpbyxcbiAgICAgICAgJ3VfaXNfaGFsbyc6ICtpc0hhbG9cbiAgICB9KTtcbn07XG5cbmNvbnN0IHN5bWJvbFRleHRBbmRJY29uVW5pZm9ybVZhbHVlcyA9IChcbiAgICBmdW5jdGlvblR5cGU6IHN0cmluZyxcbiAgICBzaXplOiA/SW50ZXJwb2xhdGVkU2l6ZSxcbiAgICByb3RhdGVJblNoYWRlcjogYm9vbGVhbixcbiAgICBwaXRjaFdpdGhNYXA6IGJvb2xlYW4sXG4gICAgcGFpbnRlcjogUGFpbnRlcixcbiAgICBtYXRyaXg6IEZsb2F0MzJBcnJheSxcbiAgICBsYWJlbFBsYW5lTWF0cml4OiBGbG9hdDMyQXJyYXksXG4gICAgZ2xDb29yZE1hdHJpeDogRmxvYXQzMkFycmF5LFxuICAgIHRleFNpemVTREY6IFtudW1iZXIsIG51bWJlcl0sXG4gICAgdGV4U2l6ZUljb246IFtudW1iZXIsIG51bWJlcl0sXG4gICAgY29vcmQ6IE92ZXJzY2FsZWRUaWxlSUQsXG4gICAgem9vbVRyYW5zaXRpb246IG51bWJlcixcbiAgICBtZXJjYXRvckNlbnRlcjogW251bWJlciwgbnVtYmVyXSxcbiAgICBpbnZNYXRyaXg6IEZsb2F0MzJBcnJheSxcbiAgICB1cFZlY3RvcjogW251bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgIHByb2plY3Rpb246IFByb2plY3Rpb25cbik6IFVuaWZvcm1WYWx1ZXM8U3ltYm9sSWNvblVuaWZvcm1zVHlwZT4gPT4ge1xuICAgIHJldHVybiBleHRlbmQoc3ltYm9sU0RGVW5pZm9ybVZhbHVlcyhmdW5jdGlvblR5cGUsIHNpemUsIHJvdGF0ZUluU2hhZGVyLFxuICAgICAgICBwaXRjaFdpdGhNYXAsIHBhaW50ZXIsIG1hdHJpeCwgbGFiZWxQbGFuZU1hdHJpeCwgZ2xDb29yZE1hdHJpeCwgdHJ1ZSwgdGV4U2l6ZVNERixcbiAgICAgICAgdHJ1ZSwgY29vcmQsIHpvb21UcmFuc2l0aW9uLCBtZXJjYXRvckNlbnRlciwgaW52TWF0cml4LCB1cFZlY3RvciwgcHJvamVjdGlvbiksIHtcbiAgICAgICAgJ3VfdGV4c2l6ZV9pY29uJzogdGV4U2l6ZUljb24sXG4gICAgICAgICd1X3RleHR1cmVfaWNvbic6IDFcbiAgICB9KTtcbn07XG5cbmV4cG9ydCB7c3ltYm9sSWNvblVuaWZvcm1zLCBzeW1ib2xTREZVbmlmb3Jtcywgc3ltYm9sSWNvblVuaWZvcm1WYWx1ZXMsIHN5bWJvbFNERlVuaWZvcm1WYWx1ZXMsIHN5bWJvbFRleHRBbmRJY29uVW5pZm9ybVZhbHVlcywgc3ltYm9sVGV4dEFuZEljb25Vbmlmb3Jtc307XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge2JnUGF0dGVyblVuaWZvcm1WYWx1ZXN9IGZyb20gJy4vcGF0dGVybi5qcyc7XG5pbXBvcnQge1xuICAgIFVuaWZvcm0xaSxcbiAgICBVbmlmb3JtMWYsXG4gICAgVW5pZm9ybTJmLFxuICAgIFVuaWZvcm1Db2xvcixcbiAgICBVbmlmb3JtTWF0cml4NGZcbn0gZnJvbSAnLi4vdW5pZm9ybV9iaW5kaW5nLmpzJztcbmltcG9ydCB7ZXh0ZW5kfSBmcm9tICcuLi8uLi91dGlsL3V0aWwuanMnO1xuXG5pbXBvcnQgdHlwZSBQYWludGVyIGZyb20gJy4uL3BhaW50ZXIuanMnO1xuaW1wb3J0IHR5cGUge1VuaWZvcm1WYWx1ZXN9IGZyb20gJy4uL3VuaWZvcm1fYmluZGluZy5qcyc7XG5pbXBvcnQgdHlwZSBDb250ZXh0IGZyb20gJy4uLy4uL2dsL2NvbnRleHQuanMnO1xuaW1wb3J0IHR5cGUgQ29sb3IgZnJvbSAnLi4vLi4vc3R5bGUtc3BlYy91dGlsL2NvbG9yLmpzJztcbmltcG9ydCB0eXBlIHtPdmVyc2NhbGVkVGlsZUlEfSBmcm9tICcuLi8uLi9zb3VyY2UvdGlsZV9pZC5qcyc7XG5pbXBvcnQgdHlwZSBSZXNvbHZlZEltYWdlIGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvZXhwcmVzc2lvbi90eXBlcy9yZXNvbHZlZF9pbWFnZS5qcyc7XG5cbmV4cG9ydCB0eXBlIEJhY2tncm91bmRVbmlmb3Jtc1R5cGUgPSB7fFxuICAgICd1X21hdHJpeCc6IFVuaWZvcm1NYXRyaXg0ZixcbiAgICAndV9vcGFjaXR5JzogVW5pZm9ybTFmLFxuICAgICd1X2NvbG9yJzogVW5pZm9ybUNvbG9yXG58fTtcblxuZXhwb3J0IHR5cGUgQmFja2dyb3VuZFBhdHRlcm5Vbmlmb3Jtc1R5cGUgPSB7fFxuICAgICd1X21hdHJpeCc6IFVuaWZvcm1NYXRyaXg0ZixcbiAgICAndV9vcGFjaXR5JzogVW5pZm9ybTFmLFxuICAgIC8vIHBhdHRlcm4gdW5pZm9ybXM6XG4gICAgJ3VfaW1hZ2UnOiBVbmlmb3JtMWksXG4gICAgJ3VfcGF0dGVybl90bCc6IFVuaWZvcm0yZixcbiAgICAndV9wYXR0ZXJuX2JyJzogVW5pZm9ybTJmLFxuICAgICd1X3RleHNpemUnOiBVbmlmb3JtMmYsXG4gICAgJ3VfcGF0dGVybl9zaXplJzogVW5pZm9ybTJmLFxuICAgICd1X3BpeGVsX2Nvb3JkX3VwcGVyJzogVW5pZm9ybTJmLFxuICAgICd1X3BpeGVsX2Nvb3JkX2xvd2VyJzogVW5pZm9ybTJmLFxuICAgICd1X3RpbGVfdW5pdHNfdG9fcGl4ZWxzJzogVW5pZm9ybTFmXG58fTtcblxuY29uc3QgYmFja2dyb3VuZFVuaWZvcm1zID0gKGNvbnRleHQ6IENvbnRleHQpOiBCYWNrZ3JvdW5kVW5pZm9ybXNUeXBlID0+ICh7XG4gICAgJ3VfbWF0cml4JzogbmV3IFVuaWZvcm1NYXRyaXg0Zihjb250ZXh0KSxcbiAgICAndV9vcGFjaXR5JzogbmV3IFVuaWZvcm0xZihjb250ZXh0KSxcbiAgICAndV9jb2xvcic6IG5ldyBVbmlmb3JtQ29sb3IoY29udGV4dClcbn0pO1xuXG5jb25zdCBiYWNrZ3JvdW5kUGF0dGVyblVuaWZvcm1zID0gKGNvbnRleHQ6IENvbnRleHQpOiBCYWNrZ3JvdW5kUGF0dGVyblVuaWZvcm1zVHlwZSA9PiAoe1xuICAgICd1X21hdHJpeCc6IG5ldyBVbmlmb3JtTWF0cml4NGYoY29udGV4dCksXG4gICAgJ3Vfb3BhY2l0eSc6IG5ldyBVbmlmb3JtMWYoY29udGV4dCksXG4gICAgJ3VfaW1hZ2UnOiBuZXcgVW5pZm9ybTFpKGNvbnRleHQpLFxuICAgICd1X3BhdHRlcm5fdGwnOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpLFxuICAgICd1X3BhdHRlcm5fYnInOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpLFxuICAgICd1X3RleHNpemUnOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpLFxuICAgICd1X3BhdHRlcm5fc2l6ZSc6IG5ldyBVbmlmb3JtMmYoY29udGV4dCksXG4gICAgJ3VfcGl4ZWxfY29vcmRfdXBwZXInOiBuZXcgVW5pZm9ybTJmKGNvbnRleHQpLFxuICAgICd1X3BpeGVsX2Nvb3JkX2xvd2VyJzogbmV3IFVuaWZvcm0yZihjb250ZXh0KSxcbiAgICAndV90aWxlX3VuaXRzX3RvX3BpeGVscyc6IG5ldyBVbmlmb3JtMWYoY29udGV4dClcbn0pO1xuXG5jb25zdCBiYWNrZ3JvdW5kVW5pZm9ybVZhbHVlcyA9IChcbiAgICBtYXRyaXg6IEZsb2F0MzJBcnJheSxcbiAgICBvcGFjaXR5OiBudW1iZXIsXG4gICAgY29sb3I6IENvbG9yXG4pOiBVbmlmb3JtVmFsdWVzPEJhY2tncm91bmRVbmlmb3Jtc1R5cGU+ID0+ICh7XG4gICAgJ3VfbWF0cml4JzogbWF0cml4LFxuICAgICd1X29wYWNpdHknOiBvcGFjaXR5LFxuICAgICd1X2NvbG9yJzogY29sb3Jcbn0pO1xuXG5jb25zdCBiYWNrZ3JvdW5kUGF0dGVyblVuaWZvcm1WYWx1ZXMgPSAoXG4gICAgbWF0cml4OiBGbG9hdDMyQXJyYXksXG4gICAgb3BhY2l0eTogbnVtYmVyLFxuICAgIHBhaW50ZXI6IFBhaW50ZXIsXG4gICAgaW1hZ2U6IFJlc29sdmVkSW1hZ2UsXG4gICAgdGlsZToge3RpbGVJRDogT3ZlcnNjYWxlZFRpbGVJRCwgdGlsZVNpemU6IG51bWJlcn1cbik6IFVuaWZvcm1WYWx1ZXM8QmFja2dyb3VuZFBhdHRlcm5Vbmlmb3Jtc1R5cGU+ID0+IGV4dGVuZChcbiAgICBiZ1BhdHRlcm5Vbmlmb3JtVmFsdWVzKGltYWdlLCBwYWludGVyLCB0aWxlKSxcbiAgICB7XG4gICAgICAgICd1X21hdHJpeCc6IG1hdHJpeCxcbiAgICAgICAgJ3Vfb3BhY2l0eSc6IG9wYWNpdHlcbiAgICB9XG4pO1xuXG5leHBvcnQge1xuICAgIGJhY2tncm91bmRVbmlmb3JtcyxcbiAgICBiYWNrZ3JvdW5kUGF0dGVyblVuaWZvcm1zLFxuICAgIGJhY2tncm91bmRVbmlmb3JtVmFsdWVzLFxuICAgIGJhY2tncm91bmRQYXR0ZXJuVW5pZm9ybVZhbHVlc1xufTtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCB7XG4gICAgVW5pZm9ybU1hdHJpeDRmLFxuICAgIFVuaWZvcm0xaSxcbiAgICBVbmlmb3JtM2YsXG4gICAgVW5pZm9ybTFmXG59IGZyb20gJy4uL3VuaWZvcm1fYmluZGluZy5qcyc7XG5pbXBvcnQge2RlZ1RvUmFkfSBmcm9tICcuLi8uLi91dGlsL3V0aWwuanMnO1xuXG5pbXBvcnQgdHlwZSB7VW5pZm9ybVZhbHVlc30gZnJvbSAnLi4vdW5pZm9ybV9iaW5kaW5nLmpzJztcbmltcG9ydCB0eXBlIENvbnRleHQgZnJvbSAnLi4vLi4vZ2wvY29udGV4dC5qcyc7XG5cbmV4cG9ydCB0eXBlIFNreWJveFVuaWZvcm1zVHlwZSA9IHt8XG4gICAgJ3VfbWF0cml4JzogVW5pZm9ybU1hdHJpeDRmLFxuICAgICd1X3N1bl9kaXJlY3Rpb24nOiBVbmlmb3JtM2YsXG4gICAgJ3VfY3ViZW1hcCc6IFVuaWZvcm0xaSxcbiAgICAndV9vcGFjaXR5JzogVW5pZm9ybTFmLFxuICAgICd1X3RlbXBvcmFsX29mZnNldCc6IFVuaWZvcm0xZlxufH07XG5cbmV4cG9ydCB0eXBlIFNreWJveEdyYWRpZW50bFVuaWZvcm1zVHlwZSA9IHt8XG4gICAgJ3VfbWF0cml4JzogVW5pZm9ybU1hdHJpeDRmLFxuICAgICd1X2NvbG9yX3JhbXAnOiBVbmlmb3JtMWksXG4gICAgJ3VfY2VudGVyX2RpcmVjdGlvbic6IFVuaWZvcm0zZixcbiAgICAndV9yYWRpdXMnOiBVbmlmb3JtMWYsXG4gICAgJ3Vfb3BhY2l0eSc6IFVuaWZvcm0xZixcbiAgICAndV90ZW1wb3JhbF9vZmZzZXQnOiBVbmlmb3JtMWYsXG58fTtcblxuY29uc3Qgc2t5Ym94VW5pZm9ybXMgPSAoY29udGV4dDogQ29udGV4dCk6IFNreWJveFVuaWZvcm1zVHlwZSA9PiAoe1xuICAgICd1X21hdHJpeCc6IG5ldyBVbmlmb3JtTWF0cml4NGYoY29udGV4dCksXG4gICAgJ3Vfc3VuX2RpcmVjdGlvbic6IG5ldyBVbmlmb3JtM2YoY29udGV4dCksXG4gICAgJ3VfY3ViZW1hcCc6IG5ldyBVbmlmb3JtMWkoY29udGV4dCksXG4gICAgJ3Vfb3BhY2l0eSc6IG5ldyBVbmlmb3JtMWYoY29udGV4dCksXG4gICAgJ3VfdGVtcG9yYWxfb2Zmc2V0JzogbmV3IFVuaWZvcm0xZihjb250ZXh0KVxuXG59KTtcblxuY29uc3Qgc2t5Ym94VW5pZm9ybVZhbHVlcyA9IChcbiAgICBtYXRyaXg6IEZsb2F0MzJBcnJheSxcbiAgICBzdW5EaXJlY3Rpb246IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICBjdWJlbWFwOiBudW1iZXIsXG4gICAgb3BhY2l0eTogbnVtYmVyLFxuICAgIHRlbXBvcmFsT2Zmc2V0OiBudW1iZXJcbik6IFVuaWZvcm1WYWx1ZXM8U2t5Ym94VW5pZm9ybXNUeXBlPiA9PiAoe1xuICAgICd1X21hdHJpeCc6IG1hdHJpeCxcbiAgICAndV9zdW5fZGlyZWN0aW9uJzogc3VuRGlyZWN0aW9uLFxuICAgICd1X2N1YmVtYXAnOiBjdWJlbWFwLFxuICAgICd1X29wYWNpdHknOiBvcGFjaXR5LFxuICAgICd1X3RlbXBvcmFsX29mZnNldCc6IHRlbXBvcmFsT2Zmc2V0XG59KTtcblxuY29uc3Qgc2t5Ym94R3JhZGllbnRVbmlmb3JtcyA9IChjb250ZXh0OiBDb250ZXh0KTogU2t5Ym94R3JhZGllbnRsVW5pZm9ybXNUeXBlID0+ICh7XG4gICAgJ3VfbWF0cml4JzogbmV3IFVuaWZvcm1NYXRyaXg0Zihjb250ZXh0KSxcbiAgICAndV9jb2xvcl9yYW1wJzogbmV3IFVuaWZvcm0xaShjb250ZXh0KSxcbiAgICAvLyByYWRpYWwgZ3JhZGllbnQgdW5pZm9ybXNcbiAgICAndV9jZW50ZXJfZGlyZWN0aW9uJzogbmV3IFVuaWZvcm0zZihjb250ZXh0KSxcbiAgICAndV9yYWRpdXMnOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X29wYWNpdHknOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X3RlbXBvcmFsX29mZnNldCc6IG5ldyBVbmlmb3JtMWYoY29udGV4dClcbn0pO1xuXG5jb25zdCBza3lib3hHcmFkaWVudFVuaWZvcm1WYWx1ZXMgPSAoXG4gICAgbWF0cml4OiBGbG9hdDMyQXJyYXksXG4gICAgY2VudGVyRGlyZWN0aW9uOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgcmFkaXVzOiBudW1iZXIsIC8vZGVncmVlc1xuICAgIG9wYWNpdHk6IG51bWJlcixcbiAgICB0ZW1wb3JhbE9mZnNldDogbnVtYmVyXG4pOiBVbmlmb3JtVmFsdWVzPFNreWJveEdyYWRpZW50bFVuaWZvcm1zVHlwZT4gPT4ge1xuICAgIHJldHVybiB7XG4gICAgICAgICd1X21hdHJpeCc6IG1hdHJpeCxcbiAgICAgICAgJ3VfY29sb3JfcmFtcCc6IDAsXG4gICAgICAgICd1X2NlbnRlcl9kaXJlY3Rpb24nOiBjZW50ZXJEaXJlY3Rpb24sXG4gICAgICAgICd1X3JhZGl1cyc6IGRlZ1RvUmFkKHJhZGl1cyksXG4gICAgICAgICd1X29wYWNpdHknOiBvcGFjaXR5LFxuICAgICAgICAndV90ZW1wb3JhbF9vZmZzZXQnOiB0ZW1wb3JhbE9mZnNldFxuICAgIH07XG59O1xuXG5leHBvcnQge1xuICAgIHNreWJveFVuaWZvcm1zLFxuICAgIHNreWJveFVuaWZvcm1WYWx1ZXMsXG4gICAgc2t5Ym94R3JhZGllbnRVbmlmb3JtcyxcbiAgICBza3lib3hHcmFkaWVudFVuaWZvcm1WYWx1ZXNcbn07XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgdHlwZSBDb2xvciBmcm9tICcuLi8uLi9zdHlsZS1zcGVjL3V0aWwvY29sb3IuanMnO1xuXG5pbXBvcnQge1xuICAgIFVuaWZvcm1NYXRyaXgzZixcbiAgICBVbmlmb3JtMWYsXG4gICAgVW5pZm9ybTNmLFxuICAgIFVuaWZvcm00Zixcbn0gZnJvbSAnLi4vdW5pZm9ybV9iaW5kaW5nLmpzJztcbmltcG9ydCB0eXBlIHtVbmlmb3JtVmFsdWVzfSBmcm9tICcuLi91bmlmb3JtX2JpbmRpbmcuanMnO1xuaW1wb3J0IHR5cGUgQ29udGV4dCBmcm9tICcuLi8uLi9nbC9jb250ZXh0LmpzJztcblxuZXhwb3J0IHR5cGUgU2t5Ym94Q2FwdHVyZVVuaWZvcm1zVHlwZSA9IHt8XG4gICAgJ3VfbWF0cml4XzNmJzogVW5pZm9ybU1hdHJpeDNmLFxuICAgICd1X3N1bl9kaXJlY3Rpb24nOiBVbmlmb3JtM2YsXG4gICAgJ3Vfc3VuX2ludGVuc2l0eSc6IFVuaWZvcm0xZixcbiAgICAndV9jb2xvcl90aW50X3InOiBVbmlmb3JtNGYsXG4gICAgJ3VfY29sb3JfdGludF9tJzogVW5pZm9ybTRmLFxuICAgICd1X2x1bWluYW5jZSc6IFVuaWZvcm0xZixcbnx9O1xuXG5jb25zdCBza3lib3hDYXB0dXJlVW5pZm9ybXMgPSAoY29udGV4dDogQ29udGV4dCk6IFNreWJveENhcHR1cmVVbmlmb3Jtc1R5cGUgPT4gKHtcbiAgICAndV9tYXRyaXhfM2YnOiBuZXcgVW5pZm9ybU1hdHJpeDNmKGNvbnRleHQpLFxuICAgICd1X3N1bl9kaXJlY3Rpb24nOiBuZXcgVW5pZm9ybTNmKGNvbnRleHQpLFxuICAgICd1X3N1bl9pbnRlbnNpdHknOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxuICAgICd1X2NvbG9yX3RpbnRfcic6IG5ldyBVbmlmb3JtNGYoY29udGV4dCksXG4gICAgJ3VfY29sb3JfdGludF9tJzogbmV3IFVuaWZvcm00Zihjb250ZXh0KSxcbiAgICAndV9sdW1pbmFuY2UnOiBuZXcgVW5pZm9ybTFmKGNvbnRleHQpLFxufSk7XG5cbmNvbnN0IHNreWJveENhcHR1cmVVbmlmb3JtVmFsdWVzID0gKFxuICAgIG1hdHJpeDogRmxvYXQzMkFycmF5LFxuICAgIHN1bkRpcmVjdGlvbjogW251bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgIHN1bkludGVuc2l0eTogbnVtYmVyLFxuICAgIGF0bW9zcGhlcmVDb2xvcjogQ29sb3IsXG4gICAgYXRtb3NwaGVyZUhhbG9Db2xvcjogQ29sb3Jcbik6IFVuaWZvcm1WYWx1ZXM8U2t5Ym94Q2FwdHVyZVVuaWZvcm1zVHlwZT4gPT4gKHtcbiAgICAndV9tYXRyaXhfM2YnOiBtYXRyaXgsXG4gICAgJ3Vfc3VuX2RpcmVjdGlvbic6IHN1bkRpcmVjdGlvbixcbiAgICAndV9zdW5faW50ZW5zaXR5Jzogc3VuSW50ZW5zaXR5LFxuICAgICd1X2NvbG9yX3RpbnRfcic6IFtcbiAgICAgICAgYXRtb3NwaGVyZUNvbG9yLnIsXG4gICAgICAgIGF0bW9zcGhlcmVDb2xvci5nLFxuICAgICAgICBhdG1vc3BoZXJlQ29sb3IuYixcbiAgICAgICAgYXRtb3NwaGVyZUNvbG9yLmFcbiAgICBdLFxuICAgICd1X2NvbG9yX3RpbnRfbSc6IFtcbiAgICAgICAgYXRtb3NwaGVyZUhhbG9Db2xvci5yLFxuICAgICAgICBhdG1vc3BoZXJlSGFsb0NvbG9yLmcsXG4gICAgICAgIGF0bW9zcGhlcmVIYWxvQ29sb3IuYixcbiAgICAgICAgYXRtb3NwaGVyZUhhbG9Db2xvci5hXG4gICAgXSxcbiAgICAndV9sdW1pbmFuY2UnOiA1ZS01LFxufSk7XG5cbmV4cG9ydCB7XG4gICAgc2t5Ym94Q2FwdHVyZVVuaWZvcm1zLFxuICAgIHNreWJveENhcHR1cmVVbmlmb3JtVmFsdWVzLFxufTtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCB0eXBlIHtDaXJjbGVEZWZpbmVzVHlwZX0gZnJvbSAnLi9jaXJjbGVfcHJvZ3JhbS5qcyc7XG5pbXBvcnQgdHlwZSB7U3ltYm9sRGVmaW5lc1R5cGV9IGZyb20gJy4vc3ltYm9sX3Byb2dyYW0uanMnO1xuaW1wb3J0IHR5cGUge0xpbmVEZWZpbmVzVHlwZX0gZnJvbSAnLi9saW5lX3Byb2dyYW0uanMnO1xuaW1wb3J0IHtmaWxsRXh0cnVzaW9uVW5pZm9ybXMsIGZpbGxFeHRydXNpb25QYXR0ZXJuVW5pZm9ybXN9IGZyb20gJy4vZmlsbF9leHRydXNpb25fcHJvZ3JhbS5qcyc7XG5pbXBvcnQge2ZpbGxVbmlmb3JtcywgZmlsbFBhdHRlcm5Vbmlmb3JtcywgZmlsbE91dGxpbmVVbmlmb3JtcywgZmlsbE91dGxpbmVQYXR0ZXJuVW5pZm9ybXN9IGZyb20gJy4vZmlsbF9wcm9ncmFtLmpzJztcbmltcG9ydCB7Y2lyY2xlVW5pZm9ybXN9IGZyb20gJy4vY2lyY2xlX3Byb2dyYW0uanMnO1xuaW1wb3J0IHtjb2xsaXNpb25Vbmlmb3JtcywgY29sbGlzaW9uQ2lyY2xlVW5pZm9ybXN9IGZyb20gJy4vY29sbGlzaW9uX3Byb2dyYW0uanMnO1xuaW1wb3J0IHtkZWJ1Z1VuaWZvcm1zfSBmcm9tICcuL2RlYnVnX3Byb2dyYW0uanMnO1xuaW1wb3J0IHtjbGlwcGluZ01hc2tVbmlmb3Jtc30gZnJvbSAnLi9jbGlwcGluZ19tYXNrX3Byb2dyYW0uanMnO1xuaW1wb3J0IHtoZWF0bWFwVW5pZm9ybXMsIGhlYXRtYXBUZXh0dXJlVW5pZm9ybXN9IGZyb20gJy4vaGVhdG1hcF9wcm9ncmFtLmpzJztcbmltcG9ydCB7aGlsbHNoYWRlVW5pZm9ybXMsIGhpbGxzaGFkZVByZXBhcmVVbmlmb3Jtc30gZnJvbSAnLi9oaWxsc2hhZGVfcHJvZ3JhbS5qcyc7XG5pbXBvcnQge2xpbmVVbmlmb3JtcywgbGluZVBhdHRlcm5Vbmlmb3Jtc30gZnJvbSAnLi9saW5lX3Byb2dyYW0uanMnO1xuaW1wb3J0IHtyYXN0ZXJVbmlmb3Jtc30gZnJvbSAnLi9yYXN0ZXJfcHJvZ3JhbS5qcyc7XG5pbXBvcnQge3N5bWJvbEljb25Vbmlmb3Jtcywgc3ltYm9sU0RGVW5pZm9ybXMsIHN5bWJvbFRleHRBbmRJY29uVW5pZm9ybXN9IGZyb20gJy4vc3ltYm9sX3Byb2dyYW0uanMnO1xuaW1wb3J0IHtiYWNrZ3JvdW5kVW5pZm9ybXMsIGJhY2tncm91bmRQYXR0ZXJuVW5pZm9ybXN9IGZyb20gJy4vYmFja2dyb3VuZF9wcm9ncmFtLmpzJztcbmltcG9ydCB7dGVycmFpblJhc3RlclVuaWZvcm1zfSBmcm9tICcuLi8uLi90ZXJyYWluL3RlcnJhaW5fcmFzdGVyX3Byb2dyYW0uanMnO1xuaW1wb3J0IHtza3lib3hVbmlmb3Jtcywgc2t5Ym94R3JhZGllbnRVbmlmb3Jtc30gZnJvbSAnLi9za3lib3hfcHJvZ3JhbS5qcyc7XG5pbXBvcnQge3NreWJveENhcHR1cmVVbmlmb3Jtc30gZnJvbSAnLi9za3lib3hfY2FwdHVyZV9wcm9ncmFtLmpzJztcbmltcG9ydCB7Z2xvYmVSYXN0ZXJVbmlmb3JtcywgYXRtb3NwaGVyZVVuaWZvcm1zfSBmcm9tICcuLi8uLi90ZXJyYWluL2dsb2JlX3Jhc3Rlcl9wcm9ncmFtLmpzJztcbmltcG9ydCB0eXBlIHtIZWF0bWFwRGVmaW5lc1R5cGV9IGZyb20gJy4vaGVhdG1hcF9wcm9ncmFtLmpzJztcbmltcG9ydCB0eXBlIHtEZWJ1Z0RlZmluZXNUeXBlfSBmcm9tICcuL2RlYnVnX3Byb2dyYW0uanMnO1xuaW1wb3J0IHR5cGUge0dsb2JlRGVmaW5lc1R5cGV9IGZyb20gJy4uLy4uL3RlcnJhaW4vZ2xvYmVfcmFzdGVyX3Byb2dyYW0uanMnO1xuXG5leHBvcnQgdHlwZSBEeW5hbWljRGVmaW5lc1R5cGUgPSBDaXJjbGVEZWZpbmVzVHlwZSB8IFN5bWJvbERlZmluZXNUeXBlIHwgTGluZURlZmluZXNUeXBlIHwgSGVhdG1hcERlZmluZXNUeXBlIHwgRGVidWdEZWZpbmVzVHlwZSB8IEdsb2JlRGVmaW5lc1R5cGU7XG5cbmV4cG9ydCBjb25zdCBwcm9ncmFtVW5pZm9ybXMgPSB7XG4gICAgZmlsbEV4dHJ1c2lvbjogZmlsbEV4dHJ1c2lvblVuaWZvcm1zLFxuICAgIGZpbGxFeHRydXNpb25QYXR0ZXJuOiBmaWxsRXh0cnVzaW9uUGF0dGVyblVuaWZvcm1zLFxuICAgIGZpbGw6IGZpbGxVbmlmb3JtcyxcbiAgICBmaWxsUGF0dGVybjogZmlsbFBhdHRlcm5Vbmlmb3JtcyxcbiAgICBmaWxsT3V0bGluZTogZmlsbE91dGxpbmVVbmlmb3JtcyxcbiAgICBmaWxsT3V0bGluZVBhdHRlcm46IGZpbGxPdXRsaW5lUGF0dGVyblVuaWZvcm1zLFxuICAgIGNpcmNsZTogY2lyY2xlVW5pZm9ybXMsXG4gICAgY29sbGlzaW9uQm94OiBjb2xsaXNpb25Vbmlmb3JtcyxcbiAgICBjb2xsaXNpb25DaXJjbGU6IGNvbGxpc2lvbkNpcmNsZVVuaWZvcm1zLFxuICAgIGRlYnVnOiBkZWJ1Z1VuaWZvcm1zLFxuICAgIGNsaXBwaW5nTWFzazogY2xpcHBpbmdNYXNrVW5pZm9ybXMsXG4gICAgaGVhdG1hcDogaGVhdG1hcFVuaWZvcm1zLFxuICAgIGhlYXRtYXBUZXh0dXJlOiBoZWF0bWFwVGV4dHVyZVVuaWZvcm1zLFxuICAgIGhpbGxzaGFkZTogaGlsbHNoYWRlVW5pZm9ybXMsXG4gICAgaGlsbHNoYWRlUHJlcGFyZTogaGlsbHNoYWRlUHJlcGFyZVVuaWZvcm1zLFxuICAgIGxpbmU6IGxpbmVVbmlmb3JtcyxcbiAgICBsaW5lUGF0dGVybjogbGluZVBhdHRlcm5Vbmlmb3JtcyxcbiAgICByYXN0ZXI6IHJhc3RlclVuaWZvcm1zLFxuICAgIHN5bWJvbEljb246IHN5bWJvbEljb25Vbmlmb3JtcyxcbiAgICBzeW1ib2xTREY6IHN5bWJvbFNERlVuaWZvcm1zLFxuICAgIHN5bWJvbFRleHRBbmRJY29uOiBzeW1ib2xUZXh0QW5kSWNvblVuaWZvcm1zLFxuICAgIGJhY2tncm91bmQ6IGJhY2tncm91bmRVbmlmb3JtcyxcbiAgICBiYWNrZ3JvdW5kUGF0dGVybjogYmFja2dyb3VuZFBhdHRlcm5Vbmlmb3JtcyxcbiAgICB0ZXJyYWluUmFzdGVyOiB0ZXJyYWluUmFzdGVyVW5pZm9ybXMsXG4gICAgdGVycmFpbkRlcHRoOiB0ZXJyYWluUmFzdGVyVW5pZm9ybXMsXG4gICAgc2t5Ym94OiBza3lib3hVbmlmb3JtcyxcbiAgICBza3lib3hHcmFkaWVudDogc2t5Ym94R3JhZGllbnRVbmlmb3JtcyxcbiAgICBza3lib3hDYXB0dXJlOiBza3lib3hDYXB0dXJlVW5pZm9ybXMsXG4gICAgZ2xvYmVSYXN0ZXI6IGdsb2JlUmFzdGVyVW5pZm9ybXMsXG4gICAgZ2xvYmVBdG1vc3BoZXJlOiBhdG1vc3BoZXJlVW5pZm9ybXMsXG59O1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHR5cGUgUGFpbnRlciBmcm9tICcuL3BhaW50ZXIuanMnO1xuaW1wb3J0IHR5cGUgU291cmNlQ2FjaGUgZnJvbSAnLi4vc291cmNlL3NvdXJjZV9jYWNoZS5qcyc7XG5pbXBvcnQgdHlwZSBTdHlsZUxheWVyIGZyb20gJy4uL3N0eWxlL3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCB0eXBlIHtPdmVyc2NhbGVkVGlsZUlEfSBmcm9tICcuLi9zb3VyY2UvdGlsZV9pZC5qcyc7XG5pbXBvcnQgdHlwZSBTeW1ib2xCdWNrZXQgZnJvbSAnLi4vZGF0YS9idWNrZXQvc3ltYm9sX2J1Y2tldC5qcyc7XG5pbXBvcnQgRGVwdGhNb2RlIGZyb20gJy4uL2dsL2RlcHRoX21vZGUuanMnO1xuaW1wb3J0IFN0ZW5jaWxNb2RlIGZyb20gJy4uL2dsL3N0ZW5jaWxfbW9kZS5qcyc7XG5pbXBvcnQgQ3VsbEZhY2VNb2RlIGZyb20gJy4uL2dsL2N1bGxfZmFjZV9tb2RlLmpzJztcbmltcG9ydCB7Y29sbGlzaW9uVW5pZm9ybVZhbHVlcywgY29sbGlzaW9uQ2lyY2xlVW5pZm9ybVZhbHVlc30gZnJvbSAnLi9wcm9ncmFtL2NvbGxpc2lvbl9wcm9ncmFtLmpzJztcbmltcG9ydCB7UXVhZFRyaWFuZ2xlQXJyYXksIENvbGxpc2lvbkNpcmNsZUxheW91dEFycmF5fSBmcm9tICcuLi9kYXRhL2FycmF5X3R5cGVzLmpzJztcbmltcG9ydCB7Y29sbGlzaW9uQ2lyY2xlTGF5b3V0fSBmcm9tICcuLi9kYXRhL2J1Y2tldC9zeW1ib2xfYXR0cmlidXRlcy5qcyc7XG5pbXBvcnQgU2VnbWVudFZlY3RvciBmcm9tICcuLi9kYXRhL3NlZ21lbnQuanMnO1xuaW1wb3J0IHttYXQ0fSBmcm9tICdnbC1tYXRyaXgnO1xuaW1wb3J0IHR5cGUgUHJvamVjdGlvbiBmcm9tICcuLi9nZW8vcHJvamVjdGlvbi9wcm9qZWN0aW9uLmpzJztcbmltcG9ydCB7Z2V0Q29sbGlzaW9uRGVidWdUaWxlUHJvamVjdGlvbk1hdHJpeH0gZnJvbSAnLi4vZ2VvL3Byb2plY3Rpb24vcHJvamVjdGlvbl91dGlsLmpzJztcbmltcG9ydCBWZXJ0ZXhCdWZmZXIgZnJvbSAnLi4vZ2wvdmVydGV4X2J1ZmZlci5qcyc7XG5pbXBvcnQgSW5kZXhCdWZmZXIgZnJvbSAnLi4vZ2wvaW5kZXhfYnVmZmVyLmpzJztcblxuZXhwb3J0IGRlZmF1bHQgZHJhd0NvbGxpc2lvbkRlYnVnO1xuXG50eXBlIFRpbGVCYXRjaCA9IHtcbiAgICBjaXJjbGVBcnJheTogQXJyYXk8bnVtYmVyPixcbiAgICBjaXJjbGVPZmZzZXQ6IG51bWJlcixcbiAgICB0cmFuc2Zvcm06IEZsb2F0MzJBcnJheSxcbiAgICBpbnZUcmFuc2Zvcm06IEZsb2F0MzJBcnJheSxcbiAgICBwcm9qZWN0aW9uOiBQcm9qZWN0aW9uXG59O1xuXG5sZXQgcXVhZFRyaWFuZ2xlczogP1F1YWRUcmlhbmdsZUFycmF5O1xuXG5mdW5jdGlvbiBkcmF3Q29sbGlzaW9uRGVidWcocGFpbnRlcjogUGFpbnRlciwgc291cmNlQ2FjaGU6IFNvdXJjZUNhY2hlLCBsYXllcjogU3R5bGVMYXllciwgY29vcmRzOiBBcnJheTxPdmVyc2NhbGVkVGlsZUlEPiwgdHJhbnNsYXRlOiBbbnVtYmVyLCBudW1iZXJdLCB0cmFuc2xhdGVBbmNob3I6ICdtYXAnIHwgJ3ZpZXdwb3J0JywgaXNUZXh0OiBib29sZWFuKSB7XG4gICAgY29uc3QgY29udGV4dCA9IHBhaW50ZXIuY29udGV4dDtcbiAgICBjb25zdCBnbCA9IGNvbnRleHQuZ2w7XG4gICAgY29uc3QgdHIgPSBwYWludGVyLnRyYW5zZm9ybTtcbiAgICBjb25zdCBwcm9ncmFtID0gcGFpbnRlci51c2VQcm9ncmFtKCdjb2xsaXNpb25Cb3gnKTtcbiAgICBjb25zdCB0aWxlQmF0Y2hlczogQXJyYXk8VGlsZUJhdGNoPiA9IFtdO1xuICAgIGxldCBjaXJjbGVDb3VudCA9IDA7XG4gICAgbGV0IGNpcmNsZU9mZnNldCA9IDA7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvb3Jkcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBjb29yZCA9IGNvb3Jkc1tpXTtcbiAgICAgICAgY29uc3QgdGlsZSA9IHNvdXJjZUNhY2hlLmdldFRpbGUoY29vcmQpO1xuICAgICAgICBjb25zdCBidWNrZXQ6ID9TeW1ib2xCdWNrZXQgPSAodGlsZS5nZXRCdWNrZXQobGF5ZXIpOiBhbnkpO1xuICAgICAgICBpZiAoIWJ1Y2tldCkgY29udGludWU7XG5cbiAgICAgICAgY29uc3QgdGlsZU1hdHJpeCA9IGdldENvbGxpc2lvbkRlYnVnVGlsZVByb2plY3Rpb25NYXRyaXgoY29vcmQsIGJ1Y2tldCwgdHIpO1xuXG4gICAgICAgIGxldCBwb3NNYXRyaXggPSB0aWxlTWF0cml4O1xuICAgICAgICBpZiAodHJhbnNsYXRlWzBdICE9PSAwIHx8IHRyYW5zbGF0ZVsxXSAhPT0gMCkge1xuICAgICAgICAgICAgcG9zTWF0cml4ID0gcGFpbnRlci50cmFuc2xhdGVQb3NNYXRyaXgodGlsZU1hdHJpeCwgdGlsZSwgdHJhbnNsYXRlLCB0cmFuc2xhdGVBbmNob3IpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGJ1ZmZlcnMgPSBpc1RleHQgPyBidWNrZXQudGV4dENvbGxpc2lvbkJveCA6IGJ1Y2tldC5pY29uQ29sbGlzaW9uQm94O1xuICAgICAgICAvLyBHZXQgY29sbGlzaW9uIGNpcmNsZSBkYXRhIG9mIHRoaXMgYnVja2V0XG4gICAgICAgIGNvbnN0IGNpcmNsZUFycmF5OiBBcnJheTxudW1iZXI+ID0gYnVja2V0LmNvbGxpc2lvbkNpcmNsZUFycmF5O1xuICAgICAgICBpZiAoY2lyY2xlQXJyYXkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgLy8gV2UgbmVlZCB0byBrbm93IHRoZSBwcm9qZWN0aW9uIG1hdHJpeCB0aGF0IHdhcyB1c2VkIGZvciBwcm9qZWN0aW5nIGNvbGxpc2lvbiBjaXJjbGVzIHRvIHRoZSBzY3JlZW4uXG4gICAgICAgICAgICAvLyBUaGlzIG1pZ2h0IHZhcnkgYmV0d2VlbiBidWNrZXRzIGFzIHRoZSBzeW1ib2wgcGxhY2VtZW50IGlzIGEgY29udGlub3VzIHByb2Nlc3MuIFRoaXMgbWF0cml4IGlzXG4gICAgICAgICAgICAvLyByZXF1aXJlZCBmb3IgdHJhbnNmb3JtaW5nIHBvaW50cyBmcm9tIHByZXZpb3VzIHNjcmVlbiBzcGFjZSB0byB0aGUgY3VycmVudCBvbmVcbiAgICAgICAgICAgIGNvbnN0IGludlRyYW5zZm9ybSA9IG1hdDQuY3JlYXRlKCk7XG4gICAgICAgICAgICBjb25zdCB0cmFuc2Zvcm0gPSBwb3NNYXRyaXg7XG5cbiAgICAgICAgICAgIG1hdDQubXVsKGludlRyYW5zZm9ybSwgYnVja2V0LnBsYWNlbWVudEludlByb2pNYXRyaXgsIHRyLmdsQ29vcmRNYXRyaXgpO1xuICAgICAgICAgICAgbWF0NC5tdWwoaW52VHJhbnNmb3JtLCBpbnZUcmFuc2Zvcm0sIGJ1Y2tldC5wbGFjZW1lbnRWaWV3cG9ydE1hdHJpeCk7XG5cbiAgICAgICAgICAgIHRpbGVCYXRjaGVzLnB1c2goe1xuICAgICAgICAgICAgICAgIGNpcmNsZUFycmF5LFxuICAgICAgICAgICAgICAgIGNpcmNsZU9mZnNldCxcbiAgICAgICAgICAgICAgICB0cmFuc2Zvcm0sXG4gICAgICAgICAgICAgICAgaW52VHJhbnNmb3JtLFxuICAgICAgICAgICAgICAgIHByb2plY3Rpb246IGJ1Y2tldC5nZXRQcm9qZWN0aW9uKClcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBjaXJjbGVDb3VudCArPSBjaXJjbGVBcnJheS5sZW5ndGggLyA0OyAgLy8gNCB2YWx1ZXMgcGVyIGNpcmNsZVxuICAgICAgICAgICAgY2lyY2xlT2Zmc2V0ID0gY2lyY2xlQ291bnQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFidWZmZXJzKSBjb250aW51ZTtcbiAgICAgICAgaWYgKHBhaW50ZXIudGVycmFpbikgcGFpbnRlci50ZXJyYWluLnNldHVwRWxldmF0aW9uRHJhdyh0aWxlLCBwcm9ncmFtKTtcbiAgICAgICAgcHJvZ3JhbS5kcmF3KGNvbnRleHQsIGdsLkxJTkVTLFxuICAgICAgICAgICAgRGVwdGhNb2RlLmRpc2FibGVkLCBTdGVuY2lsTW9kZS5kaXNhYmxlZCxcbiAgICAgICAgICAgIHBhaW50ZXIuY29sb3JNb2RlRm9yUmVuZGVyUGFzcygpLFxuICAgICAgICAgICAgQ3VsbEZhY2VNb2RlLmRpc2FibGVkLFxuICAgICAgICAgICAgY29sbGlzaW9uVW5pZm9ybVZhbHVlcyhwb3NNYXRyaXgsIHRyLCB0aWxlLCBidWNrZXQuZ2V0UHJvamVjdGlvbigpKSxcbiAgICAgICAgICAgIGxheWVyLmlkLCBidWZmZXJzLmxheW91dFZlcnRleEJ1ZmZlciwgYnVmZmVycy5pbmRleEJ1ZmZlcixcbiAgICAgICAgICAgIGJ1ZmZlcnMuc2VnbWVudHMsIG51bGwsIHRyLnpvb20sIG51bGwsXG4gICAgICAgICAgICBbYnVmZmVycy5jb2xsaXNpb25WZXJ0ZXhCdWZmZXIsIGJ1ZmZlcnMuY29sbGlzaW9uVmVydGV4QnVmZmVyRXh0XSk7XG4gICAgfVxuXG4gICAgaWYgKCFpc1RleHQgfHwgIXRpbGVCYXRjaGVzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gUmVuZGVyIGNvbGxpc2lvbiBjaXJjbGVzXG4gICAgY29uc3QgY2lyY2xlUHJvZ3JhbSA9IHBhaW50ZXIudXNlUHJvZ3JhbSgnY29sbGlzaW9uQ2lyY2xlJyk7XG5cbiAgICAvLyBDb25zdHJ1Y3QgdmVydGV4IGRhdGFcbiAgICBjb25zdCB2ZXJ0ZXhEYXRhID0gbmV3IENvbGxpc2lvbkNpcmNsZUxheW91dEFycmF5KCk7XG4gICAgdmVydGV4RGF0YS5yZXNpemUoY2lyY2xlQ291bnQgKiA0KTtcbiAgICB2ZXJ0ZXhEYXRhLl90cmltKCk7XG5cbiAgICBsZXQgdmVydGV4T2Zmc2V0ID0gMDtcblxuICAgIGZvciAoY29uc3QgYmF0Y2ggb2YgdGlsZUJhdGNoZXMpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBiYXRjaC5jaXJjbGVBcnJheS5sZW5ndGggLyA0OyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IGNpcmNsZUlkeCA9IGkgKiA0O1xuICAgICAgICAgICAgY29uc3QgeCA9IGJhdGNoLmNpcmNsZUFycmF5W2NpcmNsZUlkeCArIDBdO1xuICAgICAgICAgICAgY29uc3QgeSA9IGJhdGNoLmNpcmNsZUFycmF5W2NpcmNsZUlkeCArIDFdO1xuICAgICAgICAgICAgY29uc3QgcmFkaXVzID0gYmF0Y2guY2lyY2xlQXJyYXlbY2lyY2xlSWR4ICsgMl07XG4gICAgICAgICAgICBjb25zdCBjb2xsaXNpb24gPSBiYXRjaC5jaXJjbGVBcnJheVtjaXJjbGVJZHggKyAzXTtcblxuICAgICAgICAgICAgLy8gNCBmbG9hdHMgcGVyIHZlcnRleCwgNCB2ZXJ0aWNlcyBwZXIgcXVhZFxuICAgICAgICAgICAgdmVydGV4RGF0YS5lbXBsYWNlKHZlcnRleE9mZnNldCsrLCB4LCB5LCByYWRpdXMsIGNvbGxpc2lvbiwgMCk7XG4gICAgICAgICAgICB2ZXJ0ZXhEYXRhLmVtcGxhY2UodmVydGV4T2Zmc2V0KyssIHgsIHksIHJhZGl1cywgY29sbGlzaW9uLCAxKTtcbiAgICAgICAgICAgIHZlcnRleERhdGEuZW1wbGFjZSh2ZXJ0ZXhPZmZzZXQrKywgeCwgeSwgcmFkaXVzLCBjb2xsaXNpb24sIDIpO1xuICAgICAgICAgICAgdmVydGV4RGF0YS5lbXBsYWNlKHZlcnRleE9mZnNldCsrLCB4LCB5LCByYWRpdXMsIGNvbGxpc2lvbiwgMyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKCFxdWFkVHJpYW5nbGVzIHx8IHF1YWRUcmlhbmdsZXMubGVuZ3RoIDwgY2lyY2xlQ291bnQgKiAyKSB7XG4gICAgICAgIHF1YWRUcmlhbmdsZXMgPSBjcmVhdGVRdWFkVHJpYW5nbGVzKGNpcmNsZUNvdW50KTtcbiAgICB9XG5cbiAgICBjb25zdCBpbmRleEJ1ZmZlcjogSW5kZXhCdWZmZXIgPSBjb250ZXh0LmNyZWF0ZUluZGV4QnVmZmVyKHF1YWRUcmlhbmdsZXMsIHRydWUpO1xuICAgIGNvbnN0IHZlcnRleEJ1ZmZlcjogVmVydGV4QnVmZmVyID0gY29udGV4dC5jcmVhdGVWZXJ0ZXhCdWZmZXIodmVydGV4RGF0YSwgY29sbGlzaW9uQ2lyY2xlTGF5b3V0Lm1lbWJlcnMsIHRydWUpO1xuXG4gICAgLy8gUmVuZGVyIGJhdGNoZXNcbiAgICBmb3IgKGNvbnN0IGJhdGNoIG9mIHRpbGVCYXRjaGVzKSB7XG4gICAgICAgIGNvbnN0IHVuaWZvcm1zID0gY29sbGlzaW9uQ2lyY2xlVW5pZm9ybVZhbHVlcyhiYXRjaC50cmFuc2Zvcm0sIGJhdGNoLmludlRyYW5zZm9ybSwgdHIsIGJhdGNoLnByb2plY3Rpb24pO1xuXG4gICAgICAgIGNpcmNsZVByb2dyYW0uZHJhdyhcbiAgICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgICBnbC5UUklBTkdMRVMsXG4gICAgICAgICAgICBEZXB0aE1vZGUuZGlzYWJsZWQsXG4gICAgICAgICAgICBTdGVuY2lsTW9kZS5kaXNhYmxlZCxcbiAgICAgICAgICAgIHBhaW50ZXIuY29sb3JNb2RlRm9yUmVuZGVyUGFzcygpLFxuICAgICAgICAgICAgQ3VsbEZhY2VNb2RlLmRpc2FibGVkLFxuICAgICAgICAgICAgdW5pZm9ybXMsXG4gICAgICAgICAgICBsYXllci5pZCxcbiAgICAgICAgICAgIHZlcnRleEJ1ZmZlcixcbiAgICAgICAgICAgIGluZGV4QnVmZmVyLFxuICAgICAgICAgICAgU2VnbWVudFZlY3Rvci5zaW1wbGVTZWdtZW50KDAsIGJhdGNoLmNpcmNsZU9mZnNldCAqIDIsIGJhdGNoLmNpcmNsZUFycmF5Lmxlbmd0aCwgYmF0Y2guY2lyY2xlQXJyYXkubGVuZ3RoIC8gMiksXG4gICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgdHIuem9vbSk7XG4gICAgfVxuXG4gICAgdmVydGV4QnVmZmVyLmRlc3Ryb3koKTtcbiAgICBpbmRleEJ1ZmZlci5kZXN0cm95KCk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVF1YWRUcmlhbmdsZXMocXVhZENvdW50OiBudW1iZXIpOiBRdWFkVHJpYW5nbGVBcnJheSB7XG4gICAgY29uc3QgdHJpQ291bnQgPSBxdWFkQ291bnQgKiAyO1xuICAgIGNvbnN0IGFycmF5ID0gbmV3IFF1YWRUcmlhbmdsZUFycmF5KCk7XG5cbiAgICBhcnJheS5yZXNpemUodHJpQ291bnQpO1xuICAgIGFycmF5Ll90cmltKCk7XG5cbiAgICAvLyBUd28gdHJpYW5nbGVzIGFuZCA0IHZlcnRpY2VzIHBlciBxdWFkLlxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdHJpQ291bnQ7IGkrKykge1xuICAgICAgICBjb25zdCBpZHggPSBpICogNjtcblxuICAgICAgICBhcnJheS51aW50MTZbaWR4ICsgMF0gPSBpICogNCArIDA7XG4gICAgICAgIGFycmF5LnVpbnQxNltpZHggKyAxXSA9IGkgKiA0ICsgMTtcbiAgICAgICAgYXJyYXkudWludDE2W2lkeCArIDJdID0gaSAqIDQgKyAyO1xuICAgICAgICBhcnJheS51aW50MTZbaWR4ICsgM10gPSBpICogNCArIDI7XG4gICAgICAgIGFycmF5LnVpbnQxNltpZHggKyA0XSA9IGkgKiA0ICsgMztcbiAgICAgICAgYXJyYXkudWludDE2W2lkeCArIDVdID0gaSAqIDQgKyAwO1xuICAgIH1cblxuICAgIHJldHVybiBhcnJheTtcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCBkcmF3Q29sbGlzaW9uRGVidWcgZnJvbSAnLi9kcmF3X2NvbGxpc2lvbl9kZWJ1Zy5qcyc7XG5cbmltcG9ydCBTZWdtZW50VmVjdG9yIGZyb20gJy4uL2RhdGEvc2VnbWVudC5qcyc7XG5pbXBvcnQgKiBhcyBzeW1ib2xQcm9qZWN0aW9uIGZyb20gJy4uL3N5bWJvbC9wcm9qZWN0aW9uLmpzJztcbmltcG9ydCAqIGFzIHN5bWJvbFNpemUgZnJvbSAnLi4vc3ltYm9sL3N5bWJvbF9zaXplLmpzJztcbmltcG9ydCB7bWF0NCwgdmVjMywgdmVjNH0gZnJvbSAnZ2wtbWF0cml4JztcbmNvbnN0IGlkZW50aXR5TWF0NCA9IG1hdDQuY3JlYXRlKCk7XG5pbXBvcnQgU3RlbmNpbE1vZGUgZnJvbSAnLi4vZ2wvc3RlbmNpbF9tb2RlLmpzJztcbmltcG9ydCBEZXB0aE1vZGUgZnJvbSAnLi4vZ2wvZGVwdGhfbW9kZS5qcyc7XG5pbXBvcnQgQ3VsbEZhY2VNb2RlIGZyb20gJy4uL2dsL2N1bGxfZmFjZV9tb2RlLmpzJztcbmltcG9ydCB7YWRkRHluYW1pY0F0dHJpYnV0ZXN9IGZyb20gJy4uL2RhdGEvYnVja2V0L3N5bWJvbF9idWNrZXQuanMnO1xuaW1wb3J0IHtnZXRBbmNob3JBbGlnbm1lbnQsIFdyaXRpbmdNb2RlfSBmcm9tICcuLi9zeW1ib2wvc2hhcGluZy5qcyc7XG5pbXBvcnQgT05FX0VNIGZyb20gJy4uL3N5bWJvbC9vbmVfZW0uanMnO1xuaW1wb3J0IHtldmFsdWF0ZVZhcmlhYmxlT2Zmc2V0fSBmcm9tICcuLi9zeW1ib2wvc3ltYm9sX2xheW91dC5qcyc7XG5pbXBvcnQgVGlsZSBmcm9tICcuLi9zb3VyY2UvdGlsZS5qcyc7XG5pbXBvcnQgdHlwZSBUcmFuc2Zvcm0gZnJvbSAnLi4vZ2VvL3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQge1xuICAgIG1lcmNhdG9yWGZyb21MbmcsXG4gICAgbWVyY2F0b3JZZnJvbUxhdFxufSBmcm9tICcuLi9nZW8vbWVyY2F0b3JfY29vcmRpbmF0ZS5qcyc7XG5pbXBvcnQge2dsb2JlVG9NZXJjYXRvclRyYW5zaXRpb259IGZyb20gJy4uL2dlby9wcm9qZWN0aW9uL2dsb2JlX3V0aWwuanMnO1xuXG5pbXBvcnQge1xuICAgIHN5bWJvbEljb25Vbmlmb3JtVmFsdWVzLFxuICAgIHN5bWJvbFNERlVuaWZvcm1WYWx1ZXMsXG4gICAgc3ltYm9sVGV4dEFuZEljb25Vbmlmb3JtVmFsdWVzXG59IGZyb20gJy4vcHJvZ3JhbS9zeW1ib2xfcHJvZ3JhbS5qcyc7XG5pbXBvcnQge2dldFN5bWJvbFRpbGVQcm9qZWN0aW9uTWF0cml4fSBmcm9tICcuLi9nZW8vcHJvamVjdGlvbi9wcm9qZWN0aW9uX3V0aWwuanMnO1xuaW1wb3J0IHR5cGUgUGFpbnRlciBmcm9tICcuL3BhaW50ZXIuanMnO1xuaW1wb3J0IHR5cGUgU291cmNlQ2FjaGUgZnJvbSAnLi4vc291cmNlL3NvdXJjZV9jYWNoZS5qcyc7XG5pbXBvcnQgdHlwZSBTeW1ib2xTdHlsZUxheWVyIGZyb20gJy4uL3N0eWxlL3N0eWxlX2xheWVyL3N5bWJvbF9zdHlsZV9sYXllci5qcyc7XG5pbXBvcnQgdHlwZSBTeW1ib2xCdWNrZXQsIHtTeW1ib2xCdWZmZXJzfSBmcm9tICcuLi9kYXRhL2J1Y2tldC9zeW1ib2xfYnVja2V0LmpzJztcbmltcG9ydCB0eXBlIFRleHR1cmUgZnJvbSAnLi4vcmVuZGVyL3RleHR1cmUuanMnO1xuaW1wb3J0IHR5cGUgQ29sb3JNb2RlIGZyb20gJy4uL2dsL2NvbG9yX21vZGUuanMnO1xuaW1wb3J0IHtPdmVyc2NhbGVkVGlsZUlEfSBmcm9tICcuLi9zb3VyY2UvdGlsZV9pZC5qcyc7XG5pbXBvcnQgdHlwZSB7VW5pZm9ybVZhbHVlc30gZnJvbSAnLi91bmlmb3JtX2JpbmRpbmcuanMnO1xuaW1wb3J0IHR5cGUge1N5bWJvbFNERlVuaWZvcm1zVHlwZX0gZnJvbSAnLi4vcmVuZGVyL3Byb2dyYW0vc3ltYm9sX3Byb2dyYW0uanMnO1xuaW1wb3J0IHR5cGUge0Nyb3NzVGlsZUlELCBWYXJpYWJsZU9mZnNldH0gZnJvbSAnLi4vc3ltYm9sL3BsYWNlbWVudC5qcyc7XG5pbXBvcnQgdHlwZSB7SW50ZXJwb2xhdGVkU2l6ZX0gZnJvbSAnLi4vc3ltYm9sL3N5bWJvbF9zaXplJztcblxuZXhwb3J0IGRlZmF1bHQgZHJhd1N5bWJvbHM7XG5cbnR5cGUgU3ltYm9sVGlsZVJlbmRlclN0YXRlID0ge1xuICAgIHNlZ21lbnRzOiBTZWdtZW50VmVjdG9yLFxuICAgIHNvcnRLZXk6IG51bWJlcixcbiAgICBzdGF0ZToge1xuICAgICAgICBwcm9ncmFtOiBhbnksXG4gICAgICAgIGJ1ZmZlcnM6IFN5bWJvbEJ1ZmZlcnMsXG4gICAgICAgIHVuaWZvcm1WYWx1ZXM6IGFueSxcbiAgICAgICAgYXRsYXNUZXh0dXJlOiBUZXh0dXJlLFxuICAgICAgICBhdGxhc1RleHR1cmVJY29uOiBUZXh0dXJlIHwgbnVsbCxcbiAgICAgICAgYXRsYXNJbnRlcnBvbGF0aW9uOiBhbnksXG4gICAgICAgIGF0bGFzSW50ZXJwb2xhdGlvbkljb246IGFueSxcbiAgICAgICAgaXNTREY6IGJvb2xlYW4sXG4gICAgICAgIGhhc0hhbG86IGJvb2xlYW4sXG4gICAgICAgIHRpbGU6IFRpbGUsXG4gICAgICAgIGxhYmVsUGxhbmVNYXRyaXhJbnY6ID9GbG9hdDMyQXJyYXlcbiAgICB9XG59O1xuXG50eXBlIEFsaWdubWVudCA9ICdhdXRvJyB8ICdtYXAnIHwgJ3ZpZXdwb3J0JztcblxuZnVuY3Rpb24gZHJhd1N5bWJvbHMocGFpbnRlcjogUGFpbnRlciwgc291cmNlQ2FjaGU6IFNvdXJjZUNhY2hlLCBsYXllcjogU3ltYm9sU3R5bGVMYXllciwgY29vcmRzOiBBcnJheTxPdmVyc2NhbGVkVGlsZUlEPiwgdmFyaWFibGVPZmZzZXRzOiB7W186IENyb3NzVGlsZUlEXTogVmFyaWFibGVPZmZzZXR9KSB7XG4gICAgaWYgKHBhaW50ZXIucmVuZGVyUGFzcyAhPT0gJ3RyYW5zbHVjZW50JykgcmV0dXJuO1xuXG4gICAgLy8gRGlzYWJsZSB0aGUgc3RlbmNpbCB0ZXN0IHNvIHRoYXQgbGFiZWxzIGFyZW4ndCBjbGlwcGVkIHRvIHRpbGUgYm91bmRhcmllcy5cbiAgICBjb25zdCBzdGVuY2lsTW9kZSA9IFN0ZW5jaWxNb2RlLmRpc2FibGVkO1xuICAgIGNvbnN0IGNvbG9yTW9kZSA9IHBhaW50ZXIuY29sb3JNb2RlRm9yUmVuZGVyUGFzcygpO1xuICAgIGNvbnN0IHZhcmlhYmxlUGxhY2VtZW50ID0gbGF5ZXIubGF5b3V0LmdldCgndGV4dC12YXJpYWJsZS1hbmNob3InKTtcblxuICAgIC8vQ29tcHV0ZSB2YXJpYWJsZS1vZmZzZXRzIGJlZm9yZSBwYWludGluZyBzaW5jZSBpY29ucyBhbmQgdGV4dCBkYXRhIHBvc2l0aW9uaW5nXG4gICAgLy9kZXBlbmQgb24gZWFjaCBvdGhlciBpbiB0aGlzIGNhc2UuXG4gICAgaWYgKHZhcmlhYmxlUGxhY2VtZW50KSB7XG4gICAgICAgIHVwZGF0ZVZhcmlhYmxlQW5jaG9ycyhjb29yZHMsIHBhaW50ZXIsIGxheWVyLCBzb3VyY2VDYWNoZSxcbiAgICAgICAgICAgIGxheWVyLmxheW91dC5nZXQoJ3RleHQtcm90YXRpb24tYWxpZ25tZW50JyksXG4gICAgICAgICAgICBsYXllci5sYXlvdXQuZ2V0KCd0ZXh0LXBpdGNoLWFsaWdubWVudCcpLFxuICAgICAgICAgICAgdmFyaWFibGVPZmZzZXRzXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKGxheWVyLnBhaW50LmdldCgnaWNvbi1vcGFjaXR5JykuY29uc3RhbnRPcigxKSAhPT0gMCkge1xuICAgICAgICBkcmF3TGF5ZXJTeW1ib2xzKHBhaW50ZXIsIHNvdXJjZUNhY2hlLCBsYXllciwgY29vcmRzLCBmYWxzZSxcbiAgICAgICAgICAgIGxheWVyLnBhaW50LmdldCgnaWNvbi10cmFuc2xhdGUnKSxcbiAgICAgICAgICAgIGxheWVyLnBhaW50LmdldCgnaWNvbi10cmFuc2xhdGUtYW5jaG9yJyksXG4gICAgICAgICAgICBsYXllci5sYXlvdXQuZ2V0KCdpY29uLXJvdGF0aW9uLWFsaWdubWVudCcpLFxuICAgICAgICAgICAgbGF5ZXIubGF5b3V0LmdldCgnaWNvbi1waXRjaC1hbGlnbm1lbnQnKSxcbiAgICAgICAgICAgIGxheWVyLmxheW91dC5nZXQoJ2ljb24ta2VlcC11cHJpZ2h0JyksXG4gICAgICAgICAgICBzdGVuY2lsTW9kZSwgY29sb3JNb2RlXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKGxheWVyLnBhaW50LmdldCgndGV4dC1vcGFjaXR5JykuY29uc3RhbnRPcigxKSAhPT0gMCkge1xuICAgICAgICBkcmF3TGF5ZXJTeW1ib2xzKHBhaW50ZXIsIHNvdXJjZUNhY2hlLCBsYXllciwgY29vcmRzLCB0cnVlLFxuICAgICAgICAgICAgbGF5ZXIucGFpbnQuZ2V0KCd0ZXh0LXRyYW5zbGF0ZScpLFxuICAgICAgICAgICAgbGF5ZXIucGFpbnQuZ2V0KCd0ZXh0LXRyYW5zbGF0ZS1hbmNob3InKSxcbiAgICAgICAgICAgIGxheWVyLmxheW91dC5nZXQoJ3RleHQtcm90YXRpb24tYWxpZ25tZW50JyksXG4gICAgICAgICAgICBsYXllci5sYXlvdXQuZ2V0KCd0ZXh0LXBpdGNoLWFsaWdubWVudCcpLFxuICAgICAgICAgICAgbGF5ZXIubGF5b3V0LmdldCgndGV4dC1rZWVwLXVwcmlnaHQnKSxcbiAgICAgICAgICAgIHN0ZW5jaWxNb2RlLCBjb2xvck1vZGVcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoc291cmNlQ2FjaGUubWFwLnNob3dDb2xsaXNpb25Cb3hlcykge1xuICAgICAgICBkcmF3Q29sbGlzaW9uRGVidWcocGFpbnRlciwgc291cmNlQ2FjaGUsIGxheWVyLCBjb29yZHMsIGxheWVyLnBhaW50LmdldCgndGV4dC10cmFuc2xhdGUnKSxcbiAgICAgICAgICAgIGxheWVyLnBhaW50LmdldCgndGV4dC10cmFuc2xhdGUtYW5jaG9yJyksIHRydWUpO1xuICAgICAgICBkcmF3Q29sbGlzaW9uRGVidWcocGFpbnRlciwgc291cmNlQ2FjaGUsIGxheWVyLCBjb29yZHMsIGxheWVyLnBhaW50LmdldCgnaWNvbi10cmFuc2xhdGUnKSxcbiAgICAgICAgICAgIGxheWVyLnBhaW50LmdldCgnaWNvbi10cmFuc2xhdGUtYW5jaG9yJyksIGZhbHNlKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGNvbXB1dGVHbG9iZUNhbWVyYVVwKHRyYW5zZm9ybTogVHJhbnNmb3JtKTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdIHtcbiAgICBjb25zdCB2aWV3TWF0cml4ID0gdHJhbnNmb3JtLl9jYW1lcmEuZ2V0V29ybGRUb0NhbWVyYSh0cmFuc2Zvcm0ud29ybGRTaXplLCAxKTtcbiAgICBjb25zdCB2aWV3VG9FY2VmID0gbWF0NC5tdWx0aXBseShbXSwgdmlld01hdHJpeCwgdHJhbnNmb3JtLmdsb2JlTWF0cml4KTtcbiAgICBtYXQ0LmludmVydCh2aWV3VG9FY2VmLCB2aWV3VG9FY2VmKTtcblxuICAgIGNvbnN0IGNhbWVyYVVwVmVjdG9yID0gWzAsIDAsIDBdO1xuICAgIGNvbnN0IHVwID0gWzAsIDEsIDAsIDBdO1xuICAgIHZlYzQudHJhbnNmb3JtTWF0NCh1cCwgdXAsICB2aWV3VG9FY2VmKTtcbiAgICBjYW1lcmFVcFZlY3RvclswXSA9IHVwWzBdO1xuICAgIGNhbWVyYVVwVmVjdG9yWzFdID0gdXBbMV07XG4gICAgY2FtZXJhVXBWZWN0b3JbMl0gPSB1cFsyXTtcbiAgICB2ZWMzLm5vcm1hbGl6ZShjYW1lcmFVcFZlY3RvciwgY2FtZXJhVXBWZWN0b3IpO1xuXG4gICAgcmV0dXJuIGNhbWVyYVVwVmVjdG9yO1xufVxuXG5mdW5jdGlvbiBjYWxjdWxhdGVWYXJpYWJsZVJlbmRlclNoaWZ0KHt3aWR0aCwgaGVpZ2h0LCBhbmNob3IsIHRleHRPZmZzZXQsIHRleHRTY2FsZX06IFZhcmlhYmxlT2Zmc2V0LCByZW5kZXJUZXh0U2l6ZTogbnVtYmVyKTogUG9pbnQge1xuICAgIGNvbnN0IHtob3Jpem9udGFsQWxpZ24sIHZlcnRpY2FsQWxpZ259ID0gZ2V0QW5jaG9yQWxpZ25tZW50KGFuY2hvcik7XG4gICAgY29uc3Qgc2hpZnRYID0gLShob3Jpem9udGFsQWxpZ24gLSAwLjUpICogd2lkdGg7XG4gICAgY29uc3Qgc2hpZnRZID0gLSh2ZXJ0aWNhbEFsaWduIC0gMC41KSAqIGhlaWdodDtcbiAgICBjb25zdCB2YXJpYWJsZU9mZnNldCA9IGV2YWx1YXRlVmFyaWFibGVPZmZzZXQoYW5jaG9yLCB0ZXh0T2Zmc2V0KTtcbiAgICByZXR1cm4gbmV3IFBvaW50KFxuICAgICAgICAoc2hpZnRYIC8gdGV4dFNjYWxlICsgdmFyaWFibGVPZmZzZXRbMF0pICogcmVuZGVyVGV4dFNpemUsXG4gICAgICAgIChzaGlmdFkgLyB0ZXh0U2NhbGUgKyB2YXJpYWJsZU9mZnNldFsxXSkgKiByZW5kZXJUZXh0U2l6ZVxuICAgICk7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVZhcmlhYmxlQW5jaG9ycyhjb29yZHM6IEFycmF5PE92ZXJzY2FsZWRUaWxlSUQ+LCBwYWludGVyOiBQYWludGVyLCBsYXllcjogU3ltYm9sU3R5bGVMYXllciwgc291cmNlQ2FjaGU6IFNvdXJjZUNhY2hlLCByb3RhdGlvbkFsaWdubWVudDogQWxpZ25tZW50LCBwaXRjaEFsaWdubWVudDogQWxpZ25tZW50LCB2YXJpYWJsZU9mZnNldHM6IHsgW186IENyb3NzVGlsZUlEXTogVmFyaWFibGVPZmZzZXQgfSkge1xuICAgIGNvbnN0IHRyID0gcGFpbnRlci50cmFuc2Zvcm07XG4gICAgY29uc3Qgcm90YXRlV2l0aE1hcCA9IHJvdGF0aW9uQWxpZ25tZW50ID09PSAnbWFwJztcbiAgICBjb25zdCBwaXRjaFdpdGhNYXAgPSBwaXRjaEFsaWdubWVudCA9PT0gJ21hcCc7XG5cbiAgICBmb3IgKGNvbnN0IGNvb3JkIG9mIGNvb3Jkcykge1xuICAgICAgICBjb25zdCB0aWxlID0gc291cmNlQ2FjaGUuZ2V0VGlsZShjb29yZCk7XG4gICAgICAgIGNvbnN0IGJ1Y2tldDogU3ltYm9sQnVja2V0ID0gKHRpbGUuZ2V0QnVja2V0KGxheWVyKTogYW55KTtcbiAgICAgICAgaWYgKCFidWNrZXQgfHwgIWJ1Y2tldC50ZXh0IHx8ICFidWNrZXQudGV4dC5zZWdtZW50cy5nZXQoKS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc2l6ZURhdGEgPSBidWNrZXQudGV4dFNpemVEYXRhO1xuICAgICAgICBjb25zdCBzaXplID0gc3ltYm9sU2l6ZS5ldmFsdWF0ZVNpemVGb3Jab29tKHNpemVEYXRhLCB0ci56b29tKTtcbiAgICAgICAgY29uc3QgdGlsZU1hdHJpeCA9IGdldFN5bWJvbFRpbGVQcm9qZWN0aW9uTWF0cml4KGNvb3JkLCBidWNrZXQuZ2V0UHJvamVjdGlvbigpLCB0cik7XG5cbiAgICAgICAgY29uc3QgcGl4ZWxzVG9UaWxlVW5pdHMgPSB0ci5jYWxjdWxhdGVQaXhlbHNUb1RpbGVVbml0c01hdHJpeCh0aWxlKTtcbiAgICAgICAgY29uc3QgbGFiZWxQbGFuZU1hdHJpeCA9IHN5bWJvbFByb2plY3Rpb24uZ2V0TGFiZWxQbGFuZU1hdHJpeEZvclJlbmRlcmluZyh0aWxlTWF0cml4LCB0aWxlLnRpbGVJRC5jYW5vbmljYWwsIHBpdGNoV2l0aE1hcCwgcm90YXRlV2l0aE1hcCwgdHIsIGJ1Y2tldC5nZXRQcm9qZWN0aW9uKCksIHBpeGVsc1RvVGlsZVVuaXRzKTtcbiAgICAgICAgY29uc3QgdXBkYXRlVGV4dEZpdEljb24gPSBsYXllci5sYXlvdXQuZ2V0KCdpY29uLXRleHQtZml0JykgIT09ICdub25lJyAmJiAgYnVja2V0Lmhhc0ljb25EYXRhKCk7XG5cbiAgICAgICAgaWYgKHNpemUpIHtcbiAgICAgICAgICAgIGNvbnN0IHRpbGVTY2FsZSA9IE1hdGgucG93KDIsIHRyLnpvb20gLSB0aWxlLnRpbGVJRC5vdmVyc2NhbGVkWik7XG4gICAgICAgICAgICB1cGRhdGVWYXJpYWJsZUFuY2hvcnNGb3JCdWNrZXQoYnVja2V0LCByb3RhdGVXaXRoTWFwLCBwaXRjaFdpdGhNYXAsIHZhcmlhYmxlT2Zmc2V0cywgc3ltYm9sU2l6ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ciwgbGFiZWxQbGFuZU1hdHJpeCwgY29vcmQsIHRpbGVTY2FsZSwgc2l6ZSwgdXBkYXRlVGV4dEZpdEljb24pO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiB1cGRhdGVWYXJpYWJsZUFuY2hvcnNGb3JCdWNrZXQoYnVja2V0OiBTeW1ib2xCdWNrZXQsIHJvdGF0ZVdpdGhNYXA6IGJvb2xlYW4sIHBpdGNoV2l0aE1hcDogYm9vbGVhbiwgdmFyaWFibGVPZmZzZXRzOiB7IFtfOiBDcm9zc1RpbGVJRF06IFZhcmlhYmxlT2Zmc2V0IH0sIHN5bWJvbFNpemU6IHR5cGVvZiBzeW1ib2xTaXplLCB0cmFuc2Zvcm06IFRyYW5zZm9ybSwgbGFiZWxQbGFuZU1hdHJpeDogRmxvYXQzMkFycmF5LCBjb29yZDogT3ZlcnNjYWxlZFRpbGVJRCwgdGlsZVNjYWxlOiBudW1iZXIsIHNpemU6IEludGVycG9sYXRlZFNpemUsIHVwZGF0ZVRleHRGaXRJY29uOiBib29sZWFuKSB7XG4gICAgY29uc3QgcGxhY2VkU3ltYm9scyA9IGJ1Y2tldC50ZXh0LnBsYWNlZFN5bWJvbEFycmF5O1xuICAgIGNvbnN0IGR5bmFtaWNUZXh0TGF5b3V0VmVydGV4QXJyYXkgPSBidWNrZXQudGV4dC5keW5hbWljTGF5b3V0VmVydGV4QXJyYXk7XG4gICAgY29uc3QgZHluYW1pY0ljb25MYXlvdXRWZXJ0ZXhBcnJheSA9IGJ1Y2tldC5pY29uLmR5bmFtaWNMYXlvdXRWZXJ0ZXhBcnJheTtcbiAgICBjb25zdCBwbGFjZWRUZXh0U2hpZnRzID0ge307XG4gICAgY29uc3QgcHJvamVjdGlvbiA9IGJ1Y2tldC5nZXRQcm9qZWN0aW9uKCk7XG4gICAgY29uc3QgdGlsZU1hdHJpeCA9IGdldFN5bWJvbFRpbGVQcm9qZWN0aW9uTWF0cml4KGNvb3JkLCBwcm9qZWN0aW9uLCB0cmFuc2Zvcm0pO1xuICAgIGNvbnN0IGVsZXZhdGlvbiA9IHRyYW5zZm9ybS5lbGV2YXRpb247XG4gICAgY29uc3QgbWV0ZXJzVG9UaWxlID0gcHJvamVjdGlvbi51cFZlY3RvclNjYWxlKGNvb3JkLmNhbm9uaWNhbCwgdHJhbnNmb3JtLmNlbnRlci5sYXQsIHRyYW5zZm9ybS53b3JsZFNpemUpLm1ldGVyc1RvVGlsZTtcblxuICAgIGR5bmFtaWNUZXh0TGF5b3V0VmVydGV4QXJyYXkuY2xlYXIoKTtcbiAgICBmb3IgKGxldCBzID0gMDsgcyA8IHBsYWNlZFN5bWJvbHMubGVuZ3RoOyBzKyspIHtcbiAgICAgICAgY29uc3Qgc3ltYm9sID0gcGxhY2VkU3ltYm9scy5nZXQocyk7XG4gICAgICAgIGNvbnN0IHt0aWxlQW5jaG9yWCwgdGlsZUFuY2hvclksIG51bUdseXBoc30gPSBzeW1ib2w7XG4gICAgICAgIGNvbnN0IHNraXBPcmllbnRhdGlvbiA9IGJ1Y2tldC5hbGxvd1ZlcnRpY2FsUGxhY2VtZW50ICYmICFzeW1ib2wucGxhY2VkT3JpZW50YXRpb247XG4gICAgICAgIGNvbnN0IHZhcmlhYmxlT2Zmc2V0ID0gKCFzeW1ib2wuaGlkZGVuICYmIHN5bWJvbC5jcm9zc1RpbGVJRCAmJiAhc2tpcE9yaWVudGF0aW9uKSA/IHZhcmlhYmxlT2Zmc2V0c1tzeW1ib2wuY3Jvc3NUaWxlSURdIDogbnVsbDtcblxuICAgICAgICBpZiAoIXZhcmlhYmxlT2Zmc2V0KSB7XG4gICAgICAgICAgICAvLyBUaGVzZSBzeW1ib2xzIGFyZSBmcm9tIGEganVzdGlmaWNhdGlvbiB0aGF0IGlzIG5vdCBiZWluZyB1c2VkLCBvciBhIGxhYmVsIHRoYXQgd2Fzbid0IHBsYWNlZFxuICAgICAgICAgICAgLy8gc28gd2UgZG9uJ3QgbmVlZCB0byBkbyB0aGUgZXh0cmEgbWF0aCB0byBmaWd1cmUgb3V0IHdoYXQgaW5jcmVtZW50YWwgc2hpZnQgdG8gYXBwbHkuXG4gICAgICAgICAgICBzeW1ib2xQcm9qZWN0aW9uLmhpZGVHbHlwaHMobnVtR2x5cGhzLCBkeW5hbWljVGV4dExheW91dFZlcnRleEFycmF5KTtcblxuICAgICAgICB9IGVsc2UgIHtcbiAgICAgICAgICAgIGxldCBkeCA9IDAsIGR5ID0gMCwgZHogPSAwO1xuICAgICAgICAgICAgaWYgKGVsZXZhdGlvbikge1xuICAgICAgICAgICAgICAgIGNvbnN0IGggPSBlbGV2YXRpb24gPyBlbGV2YXRpb24uZ2V0QXRUaWxlT2Zmc2V0KGNvb3JkLCB0aWxlQW5jaG9yWCwgdGlsZUFuY2hvclkpIDogMC4wO1xuICAgICAgICAgICAgICAgIGNvbnN0IFt1eCwgdXksIHV6XSA9IHByb2plY3Rpb24udXBWZWN0b3IoY29vcmQuY2Fub25pY2FsLCB0aWxlQW5jaG9yWCwgdGlsZUFuY2hvclkpO1xuICAgICAgICAgICAgICAgIGR4ID0gaCAqIHV4ICogbWV0ZXJzVG9UaWxlO1xuICAgICAgICAgICAgICAgIGR5ID0gaCAqIHV5ICogbWV0ZXJzVG9UaWxlO1xuICAgICAgICAgICAgICAgIGR6ID0gaCAqIHV6ICogbWV0ZXJzVG9UaWxlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IFt4LCB5LCB6LCB3XSA9IHN5bWJvbFByb2plY3Rpb24ucHJvamVjdChcbiAgICAgICAgICAgICAgICBzeW1ib2wucHJvamVjdGVkQW5jaG9yWCArIGR4LFxuICAgICAgICAgICAgICAgIHN5bWJvbC5wcm9qZWN0ZWRBbmNob3JZICsgZHksXG4gICAgICAgICAgICAgICAgc3ltYm9sLnByb2plY3RlZEFuY2hvclogKyBkeixcbiAgICAgICAgICAgICAgICBwaXRjaFdpdGhNYXAgPyB0aWxlTWF0cml4IDogbGFiZWxQbGFuZU1hdHJpeCk7XG5cbiAgICAgICAgICAgIGNvbnN0IHBlcnNwZWN0aXZlUmF0aW8gPSBzeW1ib2xQcm9qZWN0aW9uLmdldFBlcnNwZWN0aXZlUmF0aW8odHJhbnNmb3JtLmdldENhbWVyYVRvQ2VudGVyRGlzdGFuY2UocHJvamVjdGlvbiksIHcpO1xuICAgICAgICAgICAgbGV0IHJlbmRlclRleHRTaXplID0gc3ltYm9sU2l6ZS5ldmFsdWF0ZVNpemVGb3JGZWF0dXJlKGJ1Y2tldC50ZXh0U2l6ZURhdGEsIHNpemUsIHN5bWJvbCkgKiBwZXJzcGVjdGl2ZVJhdGlvIC8gT05FX0VNO1xuICAgICAgICAgICAgaWYgKHBpdGNoV2l0aE1hcCkge1xuICAgICAgICAgICAgICAgIC8vIEdvIGZyb20gc2l6ZSBpbiBwaXhlbHMgdG8gZXF1aXZhbGVudCBzaXplIGluIHRpbGUgdW5pdHNcbiAgICAgICAgICAgICAgICByZW5kZXJUZXh0U2l6ZSAqPSBidWNrZXQudGlsZVBpeGVsUmF0aW8gLyB0aWxlU2NhbGU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHNoaWZ0ID0gY2FsY3VsYXRlVmFyaWFibGVSZW5kZXJTaGlmdCh2YXJpYWJsZU9mZnNldCwgcmVuZGVyVGV4dFNpemUpO1xuXG4gICAgICAgICAgICAvLyBVc3VhbCBjYXNlIGlzIHRoYXQgd2UgdGFrZSB0aGUgcHJvamVjdGVkIGFuY2hvciBhbmQgYWRkIHRoZSBwaXhlbC1iYXNlZCBzaGlmdFxuICAgICAgICAgICAgLy8gY2FsY3VsYXRlZCBhYm92ZS4gSW4gdGhlIChzb21ld2hhdCB3ZWlyZCkgY2FzZSBvZiBwaXRjaC1hbGlnbmVkIHRleHQsIHdlIGFkZCBhbiBlcXVpdmFsZW50XG4gICAgICAgICAgICAvLyB0aWxlLXVuaXQgYmFzZWQgc2hpZnQgdG8gdGhlIGFuY2hvciBiZWZvcmUgcHJvamVjdGluZyB0byB0aGUgbGFiZWwgcGxhbmUuXG4gICAgICAgICAgICBpZiAocGl0Y2hXaXRoTWFwKSB7XG4gICAgICAgICAgICAgICAgKHt4LCB5LCB6fSA9IHByb2plY3Rpb24ucHJvamVjdFRpbGVQb2ludCh0aWxlQW5jaG9yWCArIHNoaWZ0LngsIHRpbGVBbmNob3JZICsgc2hpZnQueSwgY29vcmQuY2Fub25pY2FsKSk7XG4gICAgICAgICAgICAgICAgW3gsIHksIHpdID0gc3ltYm9sUHJvamVjdGlvbi5wcm9qZWN0KHggKyBkeCwgeSArIGR5LCB6ICsgZHosIGxhYmVsUGxhbmVNYXRyaXgpO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChyb3RhdGVXaXRoTWFwKSBzaGlmdC5fcm90YXRlKC10cmFuc2Zvcm0uYW5nbGUpO1xuICAgICAgICAgICAgICAgIHggKz0gc2hpZnQueDtcbiAgICAgICAgICAgICAgICB5ICs9IHNoaWZ0Lnk7XG4gICAgICAgICAgICAgICAgeiA9IDA7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGFuZ2xlID0gKGJ1Y2tldC5hbGxvd1ZlcnRpY2FsUGxhY2VtZW50ICYmIHN5bWJvbC5wbGFjZWRPcmllbnRhdGlvbiA9PT0gV3JpdGluZ01vZGUudmVydGljYWwpID8gTWF0aC5QSSAvIDIgOiAwO1xuICAgICAgICAgICAgZm9yIChsZXQgZyA9IDA7IGcgPCBudW1HbHlwaHM7IGcrKykge1xuICAgICAgICAgICAgICAgIGFkZER5bmFtaWNBdHRyaWJ1dGVzKGR5bmFtaWNUZXh0TGF5b3V0VmVydGV4QXJyYXksIHgsIHksIHosIGFuZ2xlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vT25seSBvZmZzZXQgaG9yaXpvbnRhbCB0ZXh0IGljb25zXG4gICAgICAgICAgICBpZiAodXBkYXRlVGV4dEZpdEljb24gJiYgc3ltYm9sLmFzc29jaWF0ZWRJY29uSW5kZXggPj0gMCkge1xuICAgICAgICAgICAgICAgIHBsYWNlZFRleHRTaGlmdHNbc3ltYm9sLmFzc29jaWF0ZWRJY29uSW5kZXhdID0ge3gsIHksIHosIGFuZ2xlfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmICh1cGRhdGVUZXh0Rml0SWNvbikge1xuICAgICAgICBkeW5hbWljSWNvbkxheW91dFZlcnRleEFycmF5LmNsZWFyKCk7XG4gICAgICAgIGNvbnN0IHBsYWNlZEljb25zID0gYnVja2V0Lmljb24ucGxhY2VkU3ltYm9sQXJyYXk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGxhY2VkSWNvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHBsYWNlZEljb24gPSBwbGFjZWRJY29ucy5nZXQoaSk7XG4gICAgICAgICAgICBjb25zdCB7bnVtR2x5cGhzfSA9IHBsYWNlZEljb247XG4gICAgICAgICAgICBjb25zdCBzaGlmdCA9IHBsYWNlZFRleHRTaGlmdHNbaV07XG5cbiAgICAgICAgICAgIGlmIChwbGFjZWRJY29uLmhpZGRlbiB8fCAhc2hpZnQpIHtcbiAgICAgICAgICAgICAgICBzeW1ib2xQcm9qZWN0aW9uLmhpZGVHbHlwaHMobnVtR2x5cGhzLCBkeW5hbWljSWNvbkxheW91dFZlcnRleEFycmF5KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3Qge3gsIHksIHosIGFuZ2xlfSA9IHNoaWZ0O1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGcgPSAwOyBnIDwgbnVtR2x5cGhzOyBnKyspIHtcbiAgICAgICAgICAgICAgICAgICAgYWRkRHluYW1pY0F0dHJpYnV0ZXMoZHluYW1pY0ljb25MYXlvdXRWZXJ0ZXhBcnJheSwgeCwgeSwgeiwgYW5nbGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBidWNrZXQuaWNvbi5keW5hbWljTGF5b3V0VmVydGV4QnVmZmVyLnVwZGF0ZURhdGEoZHluYW1pY0ljb25MYXlvdXRWZXJ0ZXhBcnJheSk7XG4gICAgfVxuICAgIGJ1Y2tldC50ZXh0LmR5bmFtaWNMYXlvdXRWZXJ0ZXhCdWZmZXIudXBkYXRlRGF0YShkeW5hbWljVGV4dExheW91dFZlcnRleEFycmF5KTtcbn1cblxuZnVuY3Rpb24gZ2V0U3ltYm9sUHJvZ3JhbU5hbWUoaXNTREY6IGJvb2xlYW4sIGlzVGV4dDogYm9vbGVhbiwgYnVja2V0OiBTeW1ib2xCdWNrZXQpIHtcbiAgICBpZiAoYnVja2V0Lmljb25zSW5UZXh0ICYmIGlzVGV4dCkge1xuICAgICAgICByZXR1cm4gJ3N5bWJvbFRleHRBbmRJY29uJztcbiAgICB9IGVsc2UgaWYgKGlzU0RGKSB7XG4gICAgICAgIHJldHVybiAnc3ltYm9sU0RGJztcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gJ3N5bWJvbEljb24nO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZHJhd0xheWVyU3ltYm9scyhwYWludGVyOiBQYWludGVyLCBzb3VyY2VDYWNoZTogU291cmNlQ2FjaGUsIGxheWVyOiBTeW1ib2xTdHlsZUxheWVyLCBjb29yZHM6IEFycmF5PE92ZXJzY2FsZWRUaWxlSUQ+LCBpc1RleHQ6IGJvb2xlYW4sIHRyYW5zbGF0ZTogW251bWJlciwgbnVtYmVyXSwgdHJhbnNsYXRlQW5jaG9yOiAnbWFwJyB8ICd2aWV3cG9ydCcsIHJvdGF0aW9uQWxpZ25tZW50OiBBbGlnbm1lbnQsIHBpdGNoQWxpZ25tZW50OiBBbGlnbm1lbnQsIGtlZXBVcHJpZ2h0OiBib29sZWFuLCBzdGVuY2lsTW9kZTogU3RlbmNpbE1vZGUsIGNvbG9yTW9kZTogQ29sb3JNb2RlKSB7XG4gICAgY29uc3QgY29udGV4dCA9IHBhaW50ZXIuY29udGV4dDtcbiAgICBjb25zdCBnbCA9IGNvbnRleHQuZ2w7XG4gICAgY29uc3QgdHIgPSBwYWludGVyLnRyYW5zZm9ybTtcblxuICAgIGNvbnN0IHJvdGF0ZVdpdGhNYXAgPSByb3RhdGlvbkFsaWdubWVudCA9PT0gJ21hcCc7XG4gICAgY29uc3QgcGl0Y2hXaXRoTWFwID0gcGl0Y2hBbGlnbm1lbnQgPT09ICdtYXAnO1xuICAgIGNvbnN0IGFsb25nTGluZSA9IHJvdGF0ZVdpdGhNYXAgJiYgbGF5ZXIubGF5b3V0LmdldCgnc3ltYm9sLXBsYWNlbWVudCcpICE9PSAncG9pbnQnO1xuXG4gICAgLy8gTGluZSBsYWJlbCByb3RhdGlvbiBoYXBwZW5zIGluIGB1cGRhdGVMaW5lTGFiZWxzYFxuICAgIC8vIFBpdGNoZWQgcG9pbnQgbGFiZWxzIGFyZSBhdXRvbWF0aWNhbGx5IHJvdGF0ZWQgYnkgdGhlIGxhYmVsUGxhbmVNYXRyaXggcHJvamVjdGlvblxuICAgIC8vIFVucGl0Y2hlZCBwb2ludCBsYWJlbHMgbmVlZCB0byBoYXZlIHRoZWlyIHJvdGF0aW9uIGFwcGxpZWQgYWZ0ZXIgcHJvamVjdGlvblxuICAgIGNvbnN0IHJvdGF0ZUluU2hhZGVyID0gcm90YXRlV2l0aE1hcCAmJiAhcGl0Y2hXaXRoTWFwICYmICFhbG9uZ0xpbmU7XG5cbiAgICBjb25zdCBoYXNTb3J0S2V5ID0gbGF5ZXIubGF5b3V0LmdldCgnc3ltYm9sLXNvcnQta2V5JykuY29uc3RhbnRPcigxKSAhPT0gdW5kZWZpbmVkO1xuICAgIGxldCBzb3J0RmVhdHVyZXNCeUtleSA9IGZhbHNlO1xuXG4gICAgY29uc3QgZGVwdGhNb2RlID0gcGFpbnRlci5kZXB0aE1vZGVGb3JTdWJsYXllcigwLCBEZXB0aE1vZGUuUmVhZE9ubHkpO1xuICAgIGNvbnN0IG1lcmNhdG9yQ2VudGVyID0gW1xuICAgICAgICBtZXJjYXRvclhmcm9tTG5nKHRyLmNlbnRlci5sbmcpLFxuICAgICAgICBtZXJjYXRvcllmcm9tTGF0KHRyLmNlbnRlci5sYXQpXG4gICAgXTtcbiAgICBjb25zdCB2YXJpYWJsZVBsYWNlbWVudCA9IGxheWVyLmxheW91dC5nZXQoJ3RleHQtdmFyaWFibGUtYW5jaG9yJyk7XG4gICAgY29uc3QgaXNHbG9iZVByb2plY3Rpb24gPSB0ci5wcm9qZWN0aW9uLm5hbWUgPT09ICdnbG9iZSc7XG4gICAgY29uc3QgdGlsZVJlbmRlclN0YXRlOiBBcnJheTxTeW1ib2xUaWxlUmVuZGVyU3RhdGU+ID0gW107XG5cbiAgICBjb25zdCBtZXJjYXRvckNhbWVyYVVwID0gWzAsIC0xLCAwXTtcblxuICAgIGxldCBnbG9iZUNhbWVyYVVwOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBtZXJjYXRvckNhbWVyYVVwO1xuICAgIGlmICgoaXNHbG9iZVByb2plY3Rpb24gfHwgdHIubWVyY2F0b3JGcm9tVHJhbnNpdGlvbikgJiYgIXJvdGF0ZVdpdGhNYXApIHtcbiAgICAgICAgLy8gRWFjaCBzeW1ib2wgcm90YXRpbmcgd2l0aCB0aGUgdmlld3BvcnQgcmVxdWlyZXMgcGVyLWluc3RhbmNlIGluZm9ybWF0aW9uIGFib3V0XG4gICAgICAgIC8vIGhvdyB0byBhbGlnbiB3aXRoIHRoZSB2aWV3cG9ydC4gSW4gMkQgY2FzZSByb3RhdGlvbiBpcyBzaGFyZWQgYmV0d2VlbiBhbGwgb2YgdGhlIHN5bWJvbHMgYW5kXG4gICAgICAgIC8vIGhlbmNlIGVtYmVkZGVkIGluIHRoZSBsYWJlbCBwbGFuZSBtYXRyaXggYnV0IGluIGdsb2JlIHZpZXcgdGhpcyBuZWVkcyB0byBiZSBjb21wdXRlZCBhdCBydW50aW1lLlxuICAgICAgICAvLyBDYW1lcmEgdXAgdmVjdG9yIHRvZ2V0aGVyIHdpdGggc3VyZmFjZSBub3JtYWxzIGNhbiBiZSB1c2VkIHRvIGZpbmQgdGhlIGNvcnJlY3Qgb3JpZW50YXRpb24gZm9yIGVhY2ggc3ltYm9sLlxuICAgICAgICBnbG9iZUNhbWVyYVVwID0gY29tcHV0ZUdsb2JlQ2FtZXJhVXAodHIpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgY29vcmQgb2YgY29vcmRzKSB7XG4gICAgICAgIGNvbnN0IHRpbGUgPSBzb3VyY2VDYWNoZS5nZXRUaWxlKGNvb3JkKTtcbiAgICAgICAgY29uc3QgYnVja2V0OiBTeW1ib2xCdWNrZXQgPSAodGlsZS5nZXRCdWNrZXQobGF5ZXIpOiBhbnkpO1xuICAgICAgICBpZiAoIWJ1Y2tldCkgY29udGludWU7XG4gICAgICAgIC8vIEFsbG93IHJlbmRlcmluZyBvZiBidWNrZXRzIGJ1aWx0IGZvciBnbG9iZSBwcm9qZWN0aW9uIGluIG1lcmNhdG9yIG1vZGVcbiAgICAgICAgLy8gdW50aWwgdGhlIHN1YnN0aXR1dGUgdGlsZSBoYXMgYmVlbiBsb2FkZWRcbiAgICAgICAgaWYgKGJ1Y2tldC5wcm9qZWN0aW9uLm5hbWUgPT09ICdtZXJjYXRvcicgJiYgaXNHbG9iZVByb2plY3Rpb24pIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGJ1ZmZlcnMgPSBpc1RleHQgPyBidWNrZXQudGV4dCA6IGJ1Y2tldC5pY29uO1xuICAgICAgICBpZiAoIWJ1ZmZlcnMgfHwgYnVja2V0LmZ1bGx5Q2xpcHBlZCB8fCAhYnVmZmVycy5zZWdtZW50cy5nZXQoKS5sZW5ndGgpIGNvbnRpbnVlO1xuICAgICAgICBjb25zdCBwcm9ncmFtQ29uZmlndXJhdGlvbiA9IGJ1ZmZlcnMucHJvZ3JhbUNvbmZpZ3VyYXRpb25zLmdldChsYXllci5pZCk7XG5cbiAgICAgICAgY29uc3QgaXNTREYgPSBpc1RleHQgfHwgYnVja2V0LnNkZkljb25zO1xuXG4gICAgICAgIGNvbnN0IHNpemVEYXRhID0gaXNUZXh0ID8gYnVja2V0LnRleHRTaXplRGF0YSA6IGJ1Y2tldC5pY29uU2l6ZURhdGE7XG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybWVkID0gcGl0Y2hXaXRoTWFwIHx8IHRyLnBpdGNoICE9PSAwO1xuXG4gICAgICAgIGNvbnN0IHNpemUgPSBzeW1ib2xTaXplLmV2YWx1YXRlU2l6ZUZvclpvb20oc2l6ZURhdGEsIHRyLnpvb20pO1xuXG4gICAgICAgIGxldCB0ZXhTaXplOiBbbnVtYmVyLCBudW1iZXJdO1xuICAgICAgICBsZXQgdGV4U2l6ZUljb246IFtudW1iZXIsIG51bWJlcl0gPSBbMCwgMF07XG4gICAgICAgIGxldCBhdGxhc1RleHR1cmU7XG4gICAgICAgIGxldCBhdGxhc0ludGVycG9sYXRpb247XG4gICAgICAgIGxldCBhdGxhc1RleHR1cmVJY29uID0gbnVsbDtcbiAgICAgICAgbGV0IGF0bGFzSW50ZXJwb2xhdGlvbkljb247XG4gICAgICAgIGlmIChpc1RleHQpIHtcbiAgICAgICAgICAgIGF0bGFzVGV4dHVyZSA9IHRpbGUuZ2x5cGhBdGxhc1RleHR1cmU7XG4gICAgICAgICAgICBhdGxhc0ludGVycG9sYXRpb24gPSBnbC5MSU5FQVI7XG4gICAgICAgICAgICB0ZXhTaXplID0gdGlsZS5nbHlwaEF0bGFzVGV4dHVyZS5zaXplO1xuICAgICAgICAgICAgaWYgKGJ1Y2tldC5pY29uc0luVGV4dCkge1xuICAgICAgICAgICAgICAgIHRleFNpemVJY29uID0gdGlsZS5pbWFnZUF0bGFzVGV4dHVyZS5zaXplO1xuICAgICAgICAgICAgICAgIGF0bGFzVGV4dHVyZUljb24gPSB0aWxlLmltYWdlQXRsYXNUZXh0dXJlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHpvb21EZXBlbmRlbnRTaXplID0gc2l6ZURhdGEua2luZCA9PT0gJ2NvbXBvc2l0ZScgfHwgc2l6ZURhdGEua2luZCA9PT0gJ2NhbWVyYSc7XG4gICAgICAgICAgICAgICAgYXRsYXNJbnRlcnBvbGF0aW9uSWNvbiA9IHRyYW5zZm9ybWVkIHx8IHBhaW50ZXIub3B0aW9ucy5yb3RhdGluZyB8fCBwYWludGVyLm9wdGlvbnMuem9vbWluZyB8fCB6b29tRGVwZW5kZW50U2l6ZSA/IGdsLkxJTkVBUiA6IGdsLk5FQVJFU1Q7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBpY29uU2NhbGVkID0gbGF5ZXIubGF5b3V0LmdldCgnaWNvbi1zaXplJykuY29uc3RhbnRPcigwKSAhPT0gMSB8fCBidWNrZXQuaWNvbnNOZWVkTGluZWFyO1xuICAgICAgICAgICAgYXRsYXNUZXh0dXJlID0gdGlsZS5pbWFnZUF0bGFzVGV4dHVyZTtcbiAgICAgICAgICAgIGF0bGFzSW50ZXJwb2xhdGlvbiA9IGlzU0RGIHx8IHBhaW50ZXIub3B0aW9ucy5yb3RhdGluZyB8fCBwYWludGVyLm9wdGlvbnMuem9vbWluZyB8fCBpY29uU2NhbGVkIHx8IHRyYW5zZm9ybWVkID9cbiAgICAgICAgICAgICAgICBnbC5MSU5FQVIgOlxuICAgICAgICAgICAgICAgIGdsLk5FQVJFU1Q7XG4gICAgICAgICAgICB0ZXhTaXplID0gdGlsZS5pbWFnZUF0bGFzVGV4dHVyZS5zaXplO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgYnVja2V0SXNHbG9iZVByb2plY3Rpb24gPSBidWNrZXQucHJvamVjdGlvbi5uYW1lID09PSAnZ2xvYmUnO1xuICAgICAgICBjb25zdCBjYW1lcmFVcFZlY3RvciA9IGJ1Y2tldElzR2xvYmVQcm9qZWN0aW9uID8gZ2xvYmVDYW1lcmFVcCA6IG1lcmNhdG9yQ2FtZXJhVXA7XG4gICAgICAgIGNvbnN0IGdsb2JlVG9NZXJjYXRvciA9ICBidWNrZXRJc0dsb2JlUHJvamVjdGlvbiA/IGdsb2JlVG9NZXJjYXRvclRyYW5zaXRpb24odHIuem9vbSkgOiAwLjA7XG4gICAgICAgIGNvbnN0IHRpbGVNYXRyaXggPSBnZXRTeW1ib2xUaWxlUHJvamVjdGlvbk1hdHJpeChjb29yZCwgYnVja2V0LmdldFByb2plY3Rpb24oKSwgdHIpO1xuXG4gICAgICAgIGNvbnN0IHMgPSB0ci5jYWxjdWxhdGVQaXhlbHNUb1RpbGVVbml0c01hdHJpeCh0aWxlKTtcbiAgICAgICAgY29uc3QgbGFiZWxQbGFuZU1hdHJpeFJlbmRlcmluZyA9IHN5bWJvbFByb2plY3Rpb24uZ2V0TGFiZWxQbGFuZU1hdHJpeEZvclJlbmRlcmluZyh0aWxlTWF0cml4LCB0aWxlLnRpbGVJRC5jYW5vbmljYWwsIHBpdGNoV2l0aE1hcCwgcm90YXRlV2l0aE1hcCwgdHIsIGJ1Y2tldC5nZXRQcm9qZWN0aW9uKCksIHMpO1xuICAgICAgICAvLyBsYWJlbFBsYW5lTWF0cml4SW52IGlzIHVzZWQgZm9yIGNvbnZlcnRpbmcgdmVydGV4IHBvcyB0byB0aWxlIGNvb3JkaW5hdGVzIG5lZWRlZCBmb3Igc2FtcGxpbmcgZWxldmF0aW9uLlxuICAgICAgICBjb25zdCBsYWJlbFBsYW5lTWF0cml4SW52ID0gcGFpbnRlci50ZXJyYWluICYmIHBpdGNoV2l0aE1hcCAmJiBhbG9uZ0xpbmUgPyBtYXQ0LmludmVydChtYXQ0LmNyZWF0ZSgpLCBsYWJlbFBsYW5lTWF0cml4UmVuZGVyaW5nKSA6IGlkZW50aXR5TWF0NDtcbiAgICAgICAgY29uc3QgZ2xDb29yZE1hdHJpeCA9IHN5bWJvbFByb2plY3Rpb24uZ2V0R2xDb29yZE1hdHJpeCh0aWxlTWF0cml4LCB0aWxlLnRpbGVJRC5jYW5vbmljYWwsIHBpdGNoV2l0aE1hcCwgcm90YXRlV2l0aE1hcCwgdHIsIGJ1Y2tldC5nZXRQcm9qZWN0aW9uKCksIHMpO1xuXG4gICAgICAgIGNvbnN0IGhhc1ZhcmlhYmxlQW5jaG9ycyA9IHZhcmlhYmxlUGxhY2VtZW50ICYmIGJ1Y2tldC5oYXNUZXh0RGF0YSgpO1xuICAgICAgICBjb25zdCB1cGRhdGVUZXh0Rml0SWNvbiA9IGxheWVyLmxheW91dC5nZXQoJ2ljb24tdGV4dC1maXQnKSAhPT0gJ25vbmUnICYmXG4gICAgICAgICAgICBoYXNWYXJpYWJsZUFuY2hvcnMgJiZcbiAgICAgICAgICAgIGJ1Y2tldC5oYXNJY29uRGF0YSgpO1xuXG4gICAgICAgIGlmIChhbG9uZ0xpbmUpIHtcbiAgICAgICAgICAgIGNvbnN0IGVsZXZhdGlvbiA9IHRyLmVsZXZhdGlvbjtcbiAgICAgICAgICAgIGNvbnN0IGdldEVsZXZhdGlvbiA9IGVsZXZhdGlvbiA/IGVsZXZhdGlvbi5nZXRBdFRpbGVPZmZzZXRGdW5jKGNvb3JkLCB0ci5jZW50ZXIubGF0LCB0ci53b3JsZFNpemUsIGJ1Y2tldC5nZXRQcm9qZWN0aW9uKCkpIDogbnVsbDtcbiAgICAgICAgICAgIGNvbnN0IGxhYmVsUGxhbmVNYXRyaXhQbGFjZW1lbnQgPSBzeW1ib2xQcm9qZWN0aW9uLmdldExhYmVsUGxhbmVNYXRyaXhGb3JQbGFjZW1lbnQodGlsZU1hdHJpeCwgdGlsZS50aWxlSUQuY2Fub25pY2FsLCBwaXRjaFdpdGhNYXAsIHJvdGF0ZVdpdGhNYXAsIHRyLCBidWNrZXQuZ2V0UHJvamVjdGlvbigpLCBzKTtcblxuICAgICAgICAgICAgc3ltYm9sUHJvamVjdGlvbi51cGRhdGVMaW5lTGFiZWxzKGJ1Y2tldCwgdGlsZU1hdHJpeCwgcGFpbnRlciwgaXNUZXh0LCBsYWJlbFBsYW5lTWF0cml4UGxhY2VtZW50LCBnbENvb3JkTWF0cml4LCBwaXRjaFdpdGhNYXAsIGtlZXBVcHJpZ2h0LCBnZXRFbGV2YXRpb24sIGNvb3JkKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHByb2plY3RlZFBvc09uTGFiZWxTcGFjZSA9IGFsb25nTGluZSB8fCAoaXNUZXh0ICYmIHZhcmlhYmxlUGxhY2VtZW50KSB8fCB1cGRhdGVUZXh0Rml0SWNvbjtcbiAgICAgICAgY29uc3QgbWF0cml4ID0gcGFpbnRlci50cmFuc2xhdGVQb3NNYXRyaXgodGlsZU1hdHJpeCwgdGlsZSwgdHJhbnNsYXRlLCB0cmFuc2xhdGVBbmNob3IpO1xuICAgICAgICBjb25zdCB1TGFiZWxQbGFuZU1hdHJpeCA9IHByb2plY3RlZFBvc09uTGFiZWxTcGFjZSA/IGlkZW50aXR5TWF0NCA6IGxhYmVsUGxhbmVNYXRyaXhSZW5kZXJpbmc7XG4gICAgICAgIGNvbnN0IHVnbENvb3JkTWF0cml4ID0gcGFpbnRlci50cmFuc2xhdGVQb3NNYXRyaXgoZ2xDb29yZE1hdHJpeCwgdGlsZSwgdHJhbnNsYXRlLCB0cmFuc2xhdGVBbmNob3IsIHRydWUpO1xuICAgICAgICBjb25zdCBpbnZNYXRyaXggPSBidWNrZXQuZ2V0UHJvamVjdGlvbigpLmNyZWF0ZUludmVyc2lvbk1hdHJpeCh0ciwgY29vcmQuY2Fub25pY2FsKTtcblxuICAgICAgICBjb25zdCBiYXNlRGVmaW5lcyA9IChbXTogYW55KTtcbiAgICAgICAgaWYgKHBhaW50ZXIudGVycmFpblJlbmRlck1vZGVFbGV2YXRlZCgpICYmIHBpdGNoV2l0aE1hcCkge1xuICAgICAgICAgICAgYmFzZURlZmluZXMucHVzaCgnUElUQ0hfV0lUSF9NQVBfVEVSUkFJTicpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChidWNrZXRJc0dsb2JlUHJvamVjdGlvbikge1xuICAgICAgICAgICAgYmFzZURlZmluZXMucHVzaCgnUFJPSkVDVElPTl9HTE9CRV9WSUVXJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb2plY3RlZFBvc09uTGFiZWxTcGFjZSkge1xuICAgICAgICAgICAgYmFzZURlZmluZXMucHVzaCgnUFJPSkVDVEVEX1BPU19PTl9WSUVXUE9SVCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaGFzSGFsbyA9IGlzU0RGICYmIGxheWVyLnBhaW50LmdldChpc1RleHQgPyAndGV4dC1oYWxvLXdpZHRoJyA6ICdpY29uLWhhbG8td2lkdGgnKS5jb25zdGFudE9yKDEpICE9PSAwO1xuXG4gICAgICAgIGxldCB1bmlmb3JtVmFsdWVzO1xuICAgICAgICBpZiAoaXNTREYpIHtcbiAgICAgICAgICAgIGlmICghYnVja2V0Lmljb25zSW5UZXh0KSB7XG4gICAgICAgICAgICAgICAgdW5pZm9ybVZhbHVlcyA9IHN5bWJvbFNERlVuaWZvcm1WYWx1ZXMoc2l6ZURhdGEua2luZCwgc2l6ZSwgcm90YXRlSW5TaGFkZXIsIHBpdGNoV2l0aE1hcCwgcGFpbnRlcixcbiAgICAgICAgICAgICAgICAgICAgbWF0cml4LCB1TGFiZWxQbGFuZU1hdHJpeCwgdWdsQ29vcmRNYXRyaXgsIGlzVGV4dCwgdGV4U2l6ZSwgdHJ1ZSwgY29vcmQsIGdsb2JlVG9NZXJjYXRvciwgbWVyY2F0b3JDZW50ZXIsIGludk1hdHJpeCwgY2FtZXJhVXBWZWN0b3IsIGJ1Y2tldC5nZXRQcm9qZWN0aW9uKCkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB1bmlmb3JtVmFsdWVzID0gc3ltYm9sVGV4dEFuZEljb25Vbmlmb3JtVmFsdWVzKHNpemVEYXRhLmtpbmQsIHNpemUsIHJvdGF0ZUluU2hhZGVyLCBwaXRjaFdpdGhNYXAsIHBhaW50ZXIsXG4gICAgICAgICAgICAgICAgICAgIG1hdHJpeCwgdUxhYmVsUGxhbmVNYXRyaXgsIHVnbENvb3JkTWF0cml4LCB0ZXhTaXplLCB0ZXhTaXplSWNvbiwgY29vcmQsIGdsb2JlVG9NZXJjYXRvciwgbWVyY2F0b3JDZW50ZXIsIGludk1hdHJpeCwgY2FtZXJhVXBWZWN0b3IsIGJ1Y2tldC5nZXRQcm9qZWN0aW9uKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdW5pZm9ybVZhbHVlcyA9IHN5bWJvbEljb25Vbmlmb3JtVmFsdWVzKHNpemVEYXRhLmtpbmQsIHNpemUsIHJvdGF0ZUluU2hhZGVyLCBwaXRjaFdpdGhNYXAsIHBhaW50ZXIsIG1hdHJpeCxcbiAgICAgICAgICAgICAgICB1TGFiZWxQbGFuZU1hdHJpeCwgdWdsQ29vcmRNYXRyaXgsIGlzVGV4dCwgdGV4U2l6ZSwgY29vcmQsIGdsb2JlVG9NZXJjYXRvciwgbWVyY2F0b3JDZW50ZXIsIGludk1hdHJpeCwgY2FtZXJhVXBWZWN0b3IsIGJ1Y2tldC5nZXRQcm9qZWN0aW9uKCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcHJvZ3JhbSA9IHBhaW50ZXIudXNlUHJvZ3JhbShnZXRTeW1ib2xQcm9ncmFtTmFtZShpc1NERiwgaXNUZXh0LCBidWNrZXQpLCBwcm9ncmFtQ29uZmlndXJhdGlvbiwgYmFzZURlZmluZXMpO1xuXG4gICAgICAgIGNvbnN0IHN0YXRlID0ge1xuICAgICAgICAgICAgcHJvZ3JhbSxcbiAgICAgICAgICAgIGJ1ZmZlcnMsXG4gICAgICAgICAgICB1bmlmb3JtVmFsdWVzLFxuICAgICAgICAgICAgYXRsYXNUZXh0dXJlLFxuICAgICAgICAgICAgYXRsYXNUZXh0dXJlSWNvbixcbiAgICAgICAgICAgIGF0bGFzSW50ZXJwb2xhdGlvbixcbiAgICAgICAgICAgIGF0bGFzSW50ZXJwb2xhdGlvbkljb24sXG4gICAgICAgICAgICBpc1NERixcbiAgICAgICAgICAgIGhhc0hhbG8sXG4gICAgICAgICAgICB0aWxlLFxuICAgICAgICAgICAgbGFiZWxQbGFuZU1hdHJpeEludlxuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChoYXNTb3J0S2V5ICYmIGJ1Y2tldC5jYW5PdmVybGFwKSB7XG4gICAgICAgICAgICBzb3J0RmVhdHVyZXNCeUtleSA9IHRydWU7XG4gICAgICAgICAgICBjb25zdCBvbGRTZWdtZW50cyA9IGJ1ZmZlcnMuc2VnbWVudHMuZ2V0KCk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHNlZ21lbnQgb2Ygb2xkU2VnbWVudHMpIHtcbiAgICAgICAgICAgICAgICB0aWxlUmVuZGVyU3RhdGUucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIHNlZ21lbnRzOiBuZXcgU2VnbWVudFZlY3Rvcihbc2VnbWVudF0pLFxuICAgICAgICAgICAgICAgICAgICBzb3J0S2V5OiAoKHNlZ21lbnQuc29ydEtleTogYW55KTogbnVtYmVyKSxcbiAgICAgICAgICAgICAgICAgICAgc3RhdGVcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRpbGVSZW5kZXJTdGF0ZS5wdXNoKHtcbiAgICAgICAgICAgICAgICBzZWdtZW50czogYnVmZmVycy5zZWdtZW50cyxcbiAgICAgICAgICAgICAgICBzb3J0S2V5OiAwLFxuICAgICAgICAgICAgICAgIHN0YXRlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzb3J0RmVhdHVyZXNCeUtleSkge1xuICAgICAgICB0aWxlUmVuZGVyU3RhdGUuc29ydCgoYSwgYikgPT4gYS5zb3J0S2V5IC0gYi5zb3J0S2V5KTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHNlZ21lbnRTdGF0ZSBvZiB0aWxlUmVuZGVyU3RhdGUpIHtcbiAgICAgICAgY29uc3Qgc3RhdGUgPSBzZWdtZW50U3RhdGUuc3RhdGU7XG4gICAgICAgIGlmIChwYWludGVyLnRlcnJhaW4pIHtcbiAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgdXNlRGVwdGhGb3JPY2NsdXNpb246ICFpc0dsb2JlUHJvamVjdGlvbixcbiAgICAgICAgICAgICAgICBsYWJlbFBsYW5lTWF0cml4SW52OiBzdGF0ZS5sYWJlbFBsYW5lTWF0cml4SW52XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcGFpbnRlci50ZXJyYWluLnNldHVwRWxldmF0aW9uRHJhdyhzdGF0ZS50aWxlLCBzdGF0ZS5wcm9ncmFtLCBvcHRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICBjb250ZXh0LmFjdGl2ZVRleHR1cmUuc2V0KGdsLlRFWFRVUkUwKTtcbiAgICAgICAgc3RhdGUuYXRsYXNUZXh0dXJlLmJpbmQoc3RhdGUuYXRsYXNJbnRlcnBvbGF0aW9uLCBnbC5DTEFNUF9UT19FREdFKTtcbiAgICAgICAgaWYgKHN0YXRlLmF0bGFzVGV4dHVyZUljb24pIHtcbiAgICAgICAgICAgIGNvbnRleHQuYWN0aXZlVGV4dHVyZS5zZXQoZ2wuVEVYVFVSRTEpO1xuICAgICAgICAgICAgaWYgKHN0YXRlLmF0bGFzVGV4dHVyZUljb24pIHtcbiAgICAgICAgICAgICAgICBzdGF0ZS5hdGxhc1RleHR1cmVJY29uLmJpbmQoc3RhdGUuYXRsYXNJbnRlcnBvbGF0aW9uSWNvbiwgZ2wuQ0xBTVBfVE9fRURHRSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc3RhdGUuaXNTREYpIHtcbiAgICAgICAgICAgIGNvbnN0IHVuaWZvcm1WYWx1ZXMgPSAoKHN0YXRlLnVuaWZvcm1WYWx1ZXM6IGFueSk6IFVuaWZvcm1WYWx1ZXM8U3ltYm9sU0RGVW5pZm9ybXNUeXBlPik7XG4gICAgICAgICAgICBpZiAoc3RhdGUuaGFzSGFsbykge1xuICAgICAgICAgICAgICAgIHVuaWZvcm1WYWx1ZXNbJ3VfaXNfaGFsbyddID0gMTtcbiAgICAgICAgICAgICAgICBkcmF3U3ltYm9sRWxlbWVudHMoc3RhdGUuYnVmZmVycywgc2VnbWVudFN0YXRlLnNlZ21lbnRzLCBsYXllciwgcGFpbnRlciwgc3RhdGUucHJvZ3JhbSwgZGVwdGhNb2RlLCBzdGVuY2lsTW9kZSwgY29sb3JNb2RlLCB1bmlmb3JtVmFsdWVzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHVuaWZvcm1WYWx1ZXNbJ3VfaXNfaGFsbyddID0gMDtcbiAgICAgICAgfVxuICAgICAgICBkcmF3U3ltYm9sRWxlbWVudHMoc3RhdGUuYnVmZmVycywgc2VnbWVudFN0YXRlLnNlZ21lbnRzLCBsYXllciwgcGFpbnRlciwgc3RhdGUucHJvZ3JhbSwgZGVwdGhNb2RlLCBzdGVuY2lsTW9kZSwgY29sb3JNb2RlLCBzdGF0ZS51bmlmb3JtVmFsdWVzKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRyYXdTeW1ib2xFbGVtZW50cyhidWZmZXJzOiBTeW1ib2xCdWZmZXJzLCBzZWdtZW50czogU2VnbWVudFZlY3RvciwgbGF5ZXI6IFN5bWJvbFN0eWxlTGF5ZXIsIHBhaW50ZXI6IFBhaW50ZXIsIHByb2dyYW06IGFueSwgZGVwdGhNb2RlOiBEZXB0aE1vZGUsIHN0ZW5jaWxNb2RlOiBTdGVuY2lsTW9kZSwgY29sb3JNb2RlOiBDb2xvck1vZGUsIHVuaWZvcm1WYWx1ZXM6IFVuaWZvcm1WYWx1ZXM8U3ltYm9sU0RGVW5pZm9ybXNUeXBlPikge1xuICAgIGNvbnN0IGNvbnRleHQgPSBwYWludGVyLmNvbnRleHQ7XG4gICAgY29uc3QgZ2wgPSBjb250ZXh0LmdsO1xuICAgIGNvbnN0IGR5bmFtaWNCdWZmZXJzID0gW2J1ZmZlcnMuZHluYW1pY0xheW91dFZlcnRleEJ1ZmZlciwgYnVmZmVycy5vcGFjaXR5VmVydGV4QnVmZmVyLCBidWZmZXJzLmdsb2JlRXh0VmVydGV4QnVmZmVyXTtcbiAgICBwcm9ncmFtLmRyYXcoY29udGV4dCwgZ2wuVFJJQU5HTEVTLCBkZXB0aE1vZGUsIHN0ZW5jaWxNb2RlLCBjb2xvck1vZGUsIEN1bGxGYWNlTW9kZS5kaXNhYmxlZCxcbiAgICAgICAgdW5pZm9ybVZhbHVlcywgbGF5ZXIuaWQsIGJ1ZmZlcnMubGF5b3V0VmVydGV4QnVmZmVyLFxuICAgICAgICBidWZmZXJzLmluZGV4QnVmZmVyLCBzZWdtZW50cywgbGF5ZXIucGFpbnQsXG4gICAgICAgIHBhaW50ZXIudHJhbnNmb3JtLnpvb20sIGJ1ZmZlcnMucHJvZ3JhbUNvbmZpZ3VyYXRpb25zLmdldChsYXllci5pZCksIGR5bmFtaWNCdWZmZXJzKTtcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBTdGVuY2lsTW9kZSBmcm9tICcuLi9nbC9zdGVuY2lsX21vZGUuanMnO1xuaW1wb3J0IERlcHRoTW9kZSBmcm9tICcuLi9nbC9kZXB0aF9tb2RlLmpzJztcbmltcG9ydCBDdWxsRmFjZU1vZGUgZnJvbSAnLi4vZ2wvY3VsbF9mYWNlX21vZGUuanMnO1xuaW1wb3J0IFByb2dyYW0gZnJvbSAnLi9wcm9ncmFtLmpzJztcbmltcG9ydCB7Y2lyY2xlVW5pZm9ybVZhbHVlcywgY2lyY2xlRGVmaW5lc1ZhbHVlc30gZnJvbSAnLi9wcm9ncmFtL2NpcmNsZV9wcm9ncmFtLmpzJztcbmltcG9ydCBTZWdtZW50VmVjdG9yIGZyb20gJy4uL2RhdGEvc2VnbWVudC5qcyc7XG5pbXBvcnQge092ZXJzY2FsZWRUaWxlSUR9IGZyb20gJy4uL3NvdXJjZS90aWxlX2lkLmpzJztcbmltcG9ydCB7bWVyY2F0b3JYZnJvbUxuZywgbWVyY2F0b3JZZnJvbUxhdH0gZnJvbSAnLi4vZ2VvL21lcmNhdG9yX2Nvb3JkaW5hdGUuanMnO1xuXG5pbXBvcnQgdHlwZSBQYWludGVyIGZyb20gJy4vcGFpbnRlci5qcyc7XG5pbXBvcnQgdHlwZSBTb3VyY2VDYWNoZSBmcm9tICcuLi9zb3VyY2Uvc291cmNlX2NhY2hlLmpzJztcbmltcG9ydCB0eXBlIENpcmNsZVN0eWxlTGF5ZXIgZnJvbSAnLi4vc3R5bGUvc3R5bGVfbGF5ZXIvY2lyY2xlX3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCB0eXBlIENpcmNsZUJ1Y2tldCBmcm9tICcuLi9kYXRhL2J1Y2tldC9jaXJjbGVfYnVja2V0LmpzJztcbmltcG9ydCB0eXBlIFByb2dyYW1Db25maWd1cmF0aW9uIGZyb20gJy4uL2RhdGEvcHJvZ3JhbV9jb25maWd1cmF0aW9uLmpzJztcbmltcG9ydCB0eXBlIFZlcnRleEJ1ZmZlciBmcm9tICcuLi9nbC92ZXJ0ZXhfYnVmZmVyLmpzJztcbmltcG9ydCB0eXBlIEluZGV4QnVmZmVyIGZyb20gJy4uL2dsL2luZGV4X2J1ZmZlci5qcyc7XG5pbXBvcnQgdHlwZSB7VW5pZm9ybVZhbHVlc30gZnJvbSAnLi91bmlmb3JtX2JpbmRpbmcuanMnO1xuaW1wb3J0IHR5cGUge0NpcmNsZVVuaWZvcm1zVHlwZX0gZnJvbSAnLi9wcm9ncmFtL2NpcmNsZV9wcm9ncmFtLmpzJztcbmltcG9ydCB0eXBlIFRpbGUgZnJvbSAnLi4vc291cmNlL3RpbGUuanMnO1xuaW1wb3J0IHR5cGUge0R5bmFtaWNEZWZpbmVzVHlwZX0gZnJvbSAnLi9wcm9ncmFtL3Byb2dyYW1fdW5pZm9ybXMuanMnO1xuXG5leHBvcnQgZGVmYXVsdCBkcmF3Q2lyY2xlcztcblxudHlwZSBUaWxlUmVuZGVyU3RhdGUgPSB7XG4gICAgcHJvZ3JhbUNvbmZpZ3VyYXRpb246IFByb2dyYW1Db25maWd1cmF0aW9uLFxuICAgIHByb2dyYW06IFByb2dyYW08Kj4sXG4gICAgbGF5b3V0VmVydGV4QnVmZmVyOiBWZXJ0ZXhCdWZmZXIsXG4gICAgZ2xvYmVFeHRWZXJ0ZXhCdWZmZXI6ID9WZXJ0ZXhCdWZmZXIsXG4gICAgaW5kZXhCdWZmZXI6IEluZGV4QnVmZmVyLFxuICAgIHVuaWZvcm1WYWx1ZXM6IFVuaWZvcm1WYWx1ZXM8Q2lyY2xlVW5pZm9ybXNUeXBlPixcbiAgICB0aWxlOiBUaWxlXG59O1xuXG50eXBlIFNlZ21lbnRzVGlsZVJlbmRlclN0YXRlID0ge1xuICAgIHNlZ21lbnRzOiBTZWdtZW50VmVjdG9yLFxuICAgIHNvcnRLZXk6IG51bWJlcixcbiAgICBzdGF0ZTogVGlsZVJlbmRlclN0YXRlXG59O1xuXG5mdW5jdGlvbiBkcmF3Q2lyY2xlcyhwYWludGVyOiBQYWludGVyLCBzb3VyY2VDYWNoZTogU291cmNlQ2FjaGUsIGxheWVyOiBDaXJjbGVTdHlsZUxheWVyLCBjb29yZHM6IEFycmF5PE92ZXJzY2FsZWRUaWxlSUQ+KSB7XG4gICAgaWYgKHBhaW50ZXIucmVuZGVyUGFzcyAhPT0gJ3RyYW5zbHVjZW50JykgcmV0dXJuO1xuXG4gICAgY29uc3Qgb3BhY2l0eSA9IGxheWVyLnBhaW50LmdldCgnY2lyY2xlLW9wYWNpdHknKTtcbiAgICBjb25zdCBzdHJva2VXaWR0aCA9IGxheWVyLnBhaW50LmdldCgnY2lyY2xlLXN0cm9rZS13aWR0aCcpO1xuICAgIGNvbnN0IHN0cm9rZU9wYWNpdHkgPSBsYXllci5wYWludC5nZXQoJ2NpcmNsZS1zdHJva2Utb3BhY2l0eScpO1xuICAgIGNvbnN0IHNvcnRGZWF0dXJlc0J5S2V5ID0gbGF5ZXIubGF5b3V0LmdldCgnY2lyY2xlLXNvcnQta2V5JykuY29uc3RhbnRPcigxKSAhPT0gdW5kZWZpbmVkO1xuXG4gICAgaWYgKG9wYWNpdHkuY29uc3RhbnRPcigxKSA9PT0gMCAmJiAoc3Ryb2tlV2lkdGguY29uc3RhbnRPcigxKSA9PT0gMCB8fCBzdHJva2VPcGFjaXR5LmNvbnN0YW50T3IoMSkgPT09IDApKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjb250ZXh0ID0gcGFpbnRlci5jb250ZXh0O1xuICAgIGNvbnN0IGdsID0gY29udGV4dC5nbDtcbiAgICBjb25zdCB0ciA9IHBhaW50ZXIudHJhbnNmb3JtO1xuXG4gICAgY29uc3QgZGVwdGhNb2RlID0gcGFpbnRlci5kZXB0aE1vZGVGb3JTdWJsYXllcigwLCBEZXB0aE1vZGUuUmVhZE9ubHkpO1xuICAgIC8vIFR1cm4gb2ZmIHN0ZW5jaWwgdGVzdGluZyB0byBhbGxvdyBjaXJjbGVzIHRvIGJlIGRyYXduIGFjcm9zcyBib3VuZGFyaWVzLFxuICAgIC8vIHNvIHRoYXQgbGFyZ2UgY2lyY2xlcyBhcmUgbm90IGNsaXBwZWQgdG8gdGlsZXNcbiAgICBjb25zdCBzdGVuY2lsTW9kZSA9IFN0ZW5jaWxNb2RlLmRpc2FibGVkO1xuICAgIGNvbnN0IGNvbG9yTW9kZSA9IHBhaW50ZXIuY29sb3JNb2RlRm9yUmVuZGVyUGFzcygpO1xuICAgIGNvbnN0IGlzR2xvYmVQcm9qZWN0aW9uID0gdHIucHJvamVjdGlvbi5uYW1lID09PSAnZ2xvYmUnO1xuICAgIGNvbnN0IG1lcmNhdG9yQ2VudGVyID0gW21lcmNhdG9yWGZyb21MbmcodHIuY2VudGVyLmxuZyksIG1lcmNhdG9yWWZyb21MYXQodHIuY2VudGVyLmxhdCldO1xuXG4gICAgY29uc3Qgc2VnbWVudHNSZW5kZXJTdGF0ZXM6IEFycmF5PFNlZ21lbnRzVGlsZVJlbmRlclN0YXRlPiA9IFtdO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb29yZHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgY29vcmQgPSBjb29yZHNbaV07XG5cbiAgICAgICAgY29uc3QgdGlsZSA9IHNvdXJjZUNhY2hlLmdldFRpbGUoY29vcmQpO1xuICAgICAgICBjb25zdCBidWNrZXQ6ID9DaXJjbGVCdWNrZXQ8Kj4gPSAodGlsZS5nZXRCdWNrZXQobGF5ZXIpOiBhbnkpO1xuICAgICAgICBpZiAoIWJ1Y2tldCB8fCBidWNrZXQucHJvamVjdGlvbi5uYW1lICE9PSB0ci5wcm9qZWN0aW9uLm5hbWUpIGNvbnRpbnVlO1xuXG4gICAgICAgIGNvbnN0IHByb2dyYW1Db25maWd1cmF0aW9uID0gYnVja2V0LnByb2dyYW1Db25maWd1cmF0aW9ucy5nZXQobGF5ZXIuaWQpO1xuICAgICAgICBjb25zdCBkZWZpbmVzVmFsdWVzID0gY2lyY2xlRGVmaW5lc1ZhbHVlcyhsYXllcik7XG4gICAgICAgIGlmIChpc0dsb2JlUHJvamVjdGlvbikge1xuICAgICAgICAgICAgZGVmaW5lc1ZhbHVlcy5wdXNoKCdQUk9KRUNUSU9OX0dMT0JFX1ZJRVcnKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwcm9ncmFtID0gcGFpbnRlci51c2VQcm9ncmFtKCdjaXJjbGUnLCBwcm9ncmFtQ29uZmlndXJhdGlvbiwgKChkZWZpbmVzVmFsdWVzOiBhbnkpOiBEeW5hbWljRGVmaW5lc1R5cGVbXSkpO1xuICAgICAgICBjb25zdCBsYXlvdXRWZXJ0ZXhCdWZmZXIgPSBidWNrZXQubGF5b3V0VmVydGV4QnVmZmVyO1xuICAgICAgICBjb25zdCBnbG9iZUV4dFZlcnRleEJ1ZmZlciA9IGJ1Y2tldC5nbG9iZUV4dFZlcnRleEJ1ZmZlcjtcbiAgICAgICAgY29uc3QgaW5kZXhCdWZmZXIgPSBidWNrZXQuaW5kZXhCdWZmZXI7XG4gICAgICAgIGNvbnN0IGludk1hdHJpeCA9IHRyLnByb2plY3Rpb24uY3JlYXRlSW52ZXJzaW9uTWF0cml4KHRyLCBjb29yZC5jYW5vbmljYWwpO1xuICAgICAgICBjb25zdCB1bmlmb3JtVmFsdWVzID0gY2lyY2xlVW5pZm9ybVZhbHVlcyhwYWludGVyLCBjb29yZCwgdGlsZSwgaW52TWF0cml4LCBtZXJjYXRvckNlbnRlciwgbGF5ZXIpO1xuXG4gICAgICAgIGNvbnN0IHN0YXRlOiBUaWxlUmVuZGVyU3RhdGUgPSB7XG4gICAgICAgICAgICBwcm9ncmFtQ29uZmlndXJhdGlvbixcbiAgICAgICAgICAgIHByb2dyYW0sXG4gICAgICAgICAgICBsYXlvdXRWZXJ0ZXhCdWZmZXIsXG4gICAgICAgICAgICBnbG9iZUV4dFZlcnRleEJ1ZmZlcixcbiAgICAgICAgICAgIGluZGV4QnVmZmVyLFxuICAgICAgICAgICAgdW5pZm9ybVZhbHVlcyxcbiAgICAgICAgICAgIHRpbGVcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAoc29ydEZlYXR1cmVzQnlLZXkpIHtcbiAgICAgICAgICAgIGNvbnN0IG9sZFNlZ21lbnRzID0gYnVja2V0LnNlZ21lbnRzLmdldCgpO1xuICAgICAgICAgICAgZm9yIChjb25zdCBzZWdtZW50IG9mIG9sZFNlZ21lbnRzKSB7XG4gICAgICAgICAgICAgICAgc2VnbWVudHNSZW5kZXJTdGF0ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIHNlZ21lbnRzOiBuZXcgU2VnbWVudFZlY3Rvcihbc2VnbWVudF0pLFxuICAgICAgICAgICAgICAgICAgICBzb3J0S2V5OiAoKHNlZ21lbnQuc29ydEtleTogYW55KTogbnVtYmVyKSxcbiAgICAgICAgICAgICAgICAgICAgc3RhdGVcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNlZ21lbnRzUmVuZGVyU3RhdGVzLnB1c2goe1xuICAgICAgICAgICAgICAgIHNlZ21lbnRzOiBidWNrZXQuc2VnbWVudHMsXG4gICAgICAgICAgICAgICAgc29ydEtleTogMCxcbiAgICAgICAgICAgICAgICBzdGF0ZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgIH1cblxuICAgIGlmIChzb3J0RmVhdHVyZXNCeUtleSkge1xuICAgICAgICBzZWdtZW50c1JlbmRlclN0YXRlcy5zb3J0KChhLCBiKSA9PiBhLnNvcnRLZXkgLSBiLnNvcnRLZXkpO1xuICAgIH1cblxuICAgIGNvbnN0IHRlcnJhaW5PcHRpb25zID0ge3VzZURlcHRoRm9yT2NjbHVzaW9uOiAhaXNHbG9iZVByb2plY3Rpb259O1xuXG4gICAgZm9yIChjb25zdCBzZWdtZW50c1N0YXRlIG9mIHNlZ21lbnRzUmVuZGVyU3RhdGVzKSB7XG4gICAgICAgIGNvbnN0IHtwcm9ncmFtQ29uZmlndXJhdGlvbiwgcHJvZ3JhbSwgbGF5b3V0VmVydGV4QnVmZmVyLCBnbG9iZUV4dFZlcnRleEJ1ZmZlciwgaW5kZXhCdWZmZXIsIHVuaWZvcm1WYWx1ZXMsIHRpbGV9ID0gc2VnbWVudHNTdGF0ZS5zdGF0ZTtcbiAgICAgICAgY29uc3Qgc2VnbWVudHMgPSBzZWdtZW50c1N0YXRlLnNlZ21lbnRzO1xuXG4gICAgICAgIGlmIChwYWludGVyLnRlcnJhaW4pIHBhaW50ZXIudGVycmFpbi5zZXR1cEVsZXZhdGlvbkRyYXcodGlsZSwgcHJvZ3JhbSwgdGVycmFpbk9wdGlvbnMpO1xuXG4gICAgICAgIHBhaW50ZXIucHJlcGFyZURyYXdQcm9ncmFtKGNvbnRleHQsIHByb2dyYW0sIHRpbGUudGlsZUlELnRvVW53cmFwcGVkKCkpO1xuXG4gICAgICAgIHByb2dyYW0uZHJhdyhjb250ZXh0LCBnbC5UUklBTkdMRVMsIGRlcHRoTW9kZSwgc3RlbmNpbE1vZGUsIGNvbG9yTW9kZSwgQ3VsbEZhY2VNb2RlLmRpc2FibGVkLFxuICAgICAgICAgICAgdW5pZm9ybVZhbHVlcywgbGF5ZXIuaWQsIGxheW91dFZlcnRleEJ1ZmZlciwgaW5kZXhCdWZmZXIsIHNlZ21lbnRzLFxuICAgICAgICAgICAgbGF5ZXIucGFpbnQsIHRyLnpvb20sIHByb2dyYW1Db25maWd1cmF0aW9uLCBbZ2xvYmVFeHRWZXJ0ZXhCdWZmZXJdKTtcbiAgICB9XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgVGV4dHVyZSBmcm9tICcuL3RleHR1cmUuanMnO1xuaW1wb3J0IENvbG9yIGZyb20gJy4uL3N0eWxlLXNwZWMvdXRpbC9jb2xvci5qcyc7XG5pbXBvcnQgRGVwdGhNb2RlIGZyb20gJy4uL2dsL2RlcHRoX21vZGUuanMnO1xuaW1wb3J0IFN0ZW5jaWxNb2RlIGZyb20gJy4uL2dsL3N0ZW5jaWxfbW9kZS5qcyc7XG5pbXBvcnQgQ29sb3JNb2RlIGZyb20gJy4uL2dsL2NvbG9yX21vZGUuanMnO1xuaW1wb3J0IEN1bGxGYWNlTW9kZSBmcm9tICcuLi9nbC9jdWxsX2ZhY2VfbW9kZS5qcyc7XG5pbXBvcnQge1xuICAgIGhlYXRtYXBVbmlmb3JtVmFsdWVzLFxuICAgIGhlYXRtYXBUZXh0dXJlVW5pZm9ybVZhbHVlc1xufSBmcm9tICcuL3Byb2dyYW0vaGVhdG1hcF9wcm9ncmFtLmpzJztcbmltcG9ydCB7bWVyY2F0b3JYZnJvbUxuZywgbWVyY2F0b3JZZnJvbUxhdH0gZnJvbSAnLi4vZ2VvL21lcmNhdG9yX2Nvb3JkaW5hdGUuanMnO1xuXG5pbXBvcnQgdHlwZSBQYWludGVyIGZyb20gJy4vcGFpbnRlci5qcyc7XG5pbXBvcnQgdHlwZSBDb250ZXh0IGZyb20gJy4uL2dsL2NvbnRleHQuanMnO1xuaW1wb3J0IHR5cGUgRnJhbWVidWZmZXIgZnJvbSAnLi4vZ2wvZnJhbWVidWZmZXIuanMnO1xuaW1wb3J0IHR5cGUgU291cmNlQ2FjaGUgZnJvbSAnLi4vc291cmNlL3NvdXJjZV9jYWNoZS5qcyc7XG5pbXBvcnQgdHlwZSBIZWF0bWFwU3R5bGVMYXllciBmcm9tICcuLi9zdHlsZS9zdHlsZV9sYXllci9oZWF0bWFwX3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCB0eXBlIEhlYXRtYXBCdWNrZXQgZnJvbSAnLi4vZGF0YS9idWNrZXQvaGVhdG1hcF9idWNrZXQuanMnO1xuaW1wb3J0IHR5cGUge092ZXJzY2FsZWRUaWxlSUR9IGZyb20gJy4uL3NvdXJjZS90aWxlX2lkLmpzJztcblxuZXhwb3J0IGRlZmF1bHQgZHJhd0hlYXRtYXA7XG5cbmZ1bmN0aW9uIGRyYXdIZWF0bWFwKHBhaW50ZXI6IFBhaW50ZXIsIHNvdXJjZUNhY2hlOiBTb3VyY2VDYWNoZSwgbGF5ZXI6IEhlYXRtYXBTdHlsZUxheWVyLCBjb29yZHM6IEFycmF5PE92ZXJzY2FsZWRUaWxlSUQ+KSB7XG4gICAgaWYgKGxheWVyLnBhaW50LmdldCgnaGVhdG1hcC1vcGFjaXR5JykgPT09IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChwYWludGVyLnJlbmRlclBhc3MgPT09ICdvZmZzY3JlZW4nKSB7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBwYWludGVyLmNvbnRleHQ7XG4gICAgICAgIGNvbnN0IGdsID0gY29udGV4dC5nbDtcblxuICAgICAgICAvLyBBbGxvdyBrZXJuZWxzIHRvIGJlIGRyYXduIGFjcm9zcyBib3VuZGFyaWVzLCBzbyB0aGF0XG4gICAgICAgIC8vIGxhcmdlIGtlcm5lbHMgYXJlIG5vdCBjbGlwcGVkIHRvIHRpbGVzXG4gICAgICAgIGNvbnN0IHN0ZW5jaWxNb2RlID0gU3RlbmNpbE1vZGUuZGlzYWJsZWQ7XG4gICAgICAgIC8vIFR1cm4gb24gYWRkaXRpdmUgYmxlbmRpbmcgZm9yIGtlcm5lbHMsIHdoaWNoIGlzIGEga2V5IGFzcGVjdCBvZiBrZXJuZWwgZGVuc2l0eSBlc3RpbWF0aW9uIGZvcm11bGFcbiAgICAgICAgY29uc3QgY29sb3JNb2RlID0gbmV3IENvbG9yTW9kZShbZ2wuT05FLCBnbC5PTkVdLCBDb2xvci50cmFuc3BhcmVudCwgW3RydWUsIHRydWUsIHRydWUsIHRydWVdKTtcbiAgICAgICAgY29uc3QgcmVzb2x1dGlvblNjYWxpbmcgPSBwYWludGVyLnRyYW5zZm9ybS5wcm9qZWN0aW9uLm5hbWUgPT09ICdnbG9iZScgPyAwLjUgOiAwLjI1O1xuXG4gICAgICAgIGJpbmRGcmFtZWJ1ZmZlcihjb250ZXh0LCBwYWludGVyLCBsYXllciwgcmVzb2x1dGlvblNjYWxpbmcpO1xuXG4gICAgICAgIGNvbnRleHQuY2xlYXIoe2NvbG9yOiBDb2xvci50cmFuc3BhcmVudH0pO1xuXG4gICAgICAgIGNvbnN0IHRyID0gcGFpbnRlci50cmFuc2Zvcm07XG5cbiAgICAgICAgY29uc3QgaXNHbG9iZVByb2plY3Rpb24gPSB0ci5wcm9qZWN0aW9uLm5hbWUgPT09ICdnbG9iZSc7XG5cbiAgICAgICAgY29uc3QgZGVmaW5lc1ZhbHVlcyA9IGlzR2xvYmVQcm9qZWN0aW9uID8gWydQUk9KRUNUSU9OX0dMT0JFX1ZJRVcnXSA6IG51bGw7XG4gICAgICAgIGNvbnN0IGN1bGxNb2RlID0gaXNHbG9iZVByb2plY3Rpb24gPyBDdWxsRmFjZU1vZGUuZnJvbnRDQ1cgOiBDdWxsRmFjZU1vZGUuZGlzYWJsZWQ7XG5cbiAgICAgICAgY29uc3QgbWVyY2F0b3JDZW50ZXIgPSBbbWVyY2F0b3JYZnJvbUxuZyh0ci5jZW50ZXIubG5nKSwgbWVyY2F0b3JZZnJvbUxhdCh0ci5jZW50ZXIubGF0KV07XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb29yZHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IGNvb3JkID0gY29vcmRzW2ldO1xuXG4gICAgICAgICAgICAvLyBTa2lwIHRpbGVzIHRoYXQgaGF2ZSB1bmNvdmVyZWQgcGFyZW50cyB0byBhdm9pZCBmbGlja2VyaW5nOyB3ZSBkb24ndCBuZWVkXG4gICAgICAgICAgICAvLyB0byB1c2UgY29tcGxleCB0aWxlIG1hc2tpbmcgaGVyZSBiZWNhdXNlIHRoZSBjaGFuZ2UgYmV0d2VlbiB6b29tIGxldmVscyBpcyBzdWJ0bGUsXG4gICAgICAgICAgICAvLyBzbyBpdCdzIGZpbmUgdG8gc2ltcGx5IHJlbmRlciB0aGUgcGFyZW50IHVudGlsIGFsbCBpdHMgNCBjaGlsZHJlbiBhcmUgbG9hZGVkXG4gICAgICAgICAgICBpZiAoc291cmNlQ2FjaGUuaGFzUmVuZGVyYWJsZVBhcmVudChjb29yZCkpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICBjb25zdCB0aWxlID0gc291cmNlQ2FjaGUuZ2V0VGlsZShjb29yZCk7XG4gICAgICAgICAgICBjb25zdCBidWNrZXQ6ID9IZWF0bWFwQnVja2V0ID0gKHRpbGUuZ2V0QnVja2V0KGxheWVyKTogYW55KTtcbiAgICAgICAgICAgIGlmICghYnVja2V0IHx8IGJ1Y2tldC5wcm9qZWN0aW9uLm5hbWUgIT09IHRyLnByb2plY3Rpb24ubmFtZSkgY29udGludWU7XG5cbiAgICAgICAgICAgIGNvbnN0IHByb2dyYW1Db25maWd1cmF0aW9uID0gYnVja2V0LnByb2dyYW1Db25maWd1cmF0aW9ucy5nZXQobGF5ZXIuaWQpO1xuICAgICAgICAgICAgY29uc3QgcHJvZ3JhbSA9IHBhaW50ZXIudXNlUHJvZ3JhbSgnaGVhdG1hcCcsIHByb2dyYW1Db25maWd1cmF0aW9uLCBkZWZpbmVzVmFsdWVzKTtcbiAgICAgICAgICAgIGNvbnN0IHt6b29tfSA9IHBhaW50ZXIudHJhbnNmb3JtO1xuICAgICAgICAgICAgaWYgKHBhaW50ZXIudGVycmFpbikgcGFpbnRlci50ZXJyYWluLnNldHVwRWxldmF0aW9uRHJhdyh0aWxlLCBwcm9ncmFtKTtcblxuICAgICAgICAgICAgcGFpbnRlci5wcmVwYXJlRHJhd1Byb2dyYW0oY29udGV4dCwgcHJvZ3JhbSwgY29vcmQudG9VbndyYXBwZWQoKSk7XG5cbiAgICAgICAgICAgIGNvbnN0IGludk1hdHJpeCA9IHRyLnByb2plY3Rpb24uY3JlYXRlSW52ZXJzaW9uTWF0cml4KHRyLCBjb29yZC5jYW5vbmljYWwpO1xuXG4gICAgICAgICAgICBwcm9ncmFtLmRyYXcoY29udGV4dCwgZ2wuVFJJQU5HTEVTLCBEZXB0aE1vZGUuZGlzYWJsZWQsIHN0ZW5jaWxNb2RlLCBjb2xvck1vZGUsIGN1bGxNb2RlLFxuICAgICAgICAgICAgICAgIGhlYXRtYXBVbmlmb3JtVmFsdWVzKHBhaW50ZXIsIGNvb3JkLFxuICAgICAgICAgICAgICAgICAgICB0aWxlLCBpbnZNYXRyaXgsIG1lcmNhdG9yQ2VudGVyLCB6b29tLCBsYXllci5wYWludC5nZXQoJ2hlYXRtYXAtaW50ZW5zaXR5JykpLFxuICAgICAgICAgICAgICAgIGxheWVyLmlkLCBidWNrZXQubGF5b3V0VmVydGV4QnVmZmVyLCBidWNrZXQuaW5kZXhCdWZmZXIsXG4gICAgICAgICAgICAgICAgYnVja2V0LnNlZ21lbnRzLCBsYXllci5wYWludCwgcGFpbnRlci50cmFuc2Zvcm0uem9vbSxcbiAgICAgICAgICAgICAgICBwcm9ncmFtQ29uZmlndXJhdGlvbiwgaXNHbG9iZVByb2plY3Rpb24gPyBbYnVja2V0Lmdsb2JlRXh0VmVydGV4QnVmZmVyXSA6IG51bGwpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29udGV4dC52aWV3cG9ydC5zZXQoWzAsIDAsIHBhaW50ZXIud2lkdGgsIHBhaW50ZXIuaGVpZ2h0XSk7XG5cbiAgICB9IGVsc2UgaWYgKHBhaW50ZXIucmVuZGVyUGFzcyA9PT0gJ3RyYW5zbHVjZW50Jykge1xuICAgICAgICBwYWludGVyLmNvbnRleHQuc2V0Q29sb3JNb2RlKHBhaW50ZXIuY29sb3JNb2RlRm9yUmVuZGVyUGFzcygpKTtcbiAgICAgICAgcmVuZGVyVGV4dHVyZVRvTWFwKHBhaW50ZXIsIGxheWVyKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGJpbmRGcmFtZWJ1ZmZlcihjb250ZXh0OiBDb250ZXh0LCBwYWludGVyOiBQYWludGVyLCBsYXllcjogSGVhdG1hcFN0eWxlTGF5ZXIsIHNjYWxpbmc6IG51bWJlcikge1xuICAgIGNvbnN0IGdsID0gY29udGV4dC5nbDtcbiAgICBjb25zdCB3aWR0aCA9IHBhaW50ZXIud2lkdGggKiBzY2FsaW5nO1xuICAgIGNvbnN0IGhlaWdodCA9IHBhaW50ZXIuaGVpZ2h0ICogc2NhbGluZztcblxuICAgIGNvbnRleHQuYWN0aXZlVGV4dHVyZS5zZXQoZ2wuVEVYVFVSRTEpO1xuICAgIGNvbnRleHQudmlld3BvcnQuc2V0KFswLCAwLCB3aWR0aCwgaGVpZ2h0XSk7XG5cbiAgICBsZXQgZmJvID0gbGF5ZXIuaGVhdG1hcEZibztcblxuICAgIGlmICghZmJvIHx8IChmYm8gJiYgKGZiby53aWR0aCAhPT0gd2lkdGggfHwgZmJvLmhlaWdodCAhPT0gaGVpZ2h0KSkpIHtcbiAgICAgICAgaWYgKGZibykgeyBmYm8uZGVzdHJveSgpOyB9XG5cbiAgICAgICAgY29uc3QgdGV4dHVyZSA9IGdsLmNyZWF0ZVRleHR1cmUoKTtcbiAgICAgICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSk7XG4gICAgICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9XUkFQX1MsIGdsLkNMQU1QX1RPX0VER0UpO1xuICAgICAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfV1JBUF9ULCBnbC5DTEFNUF9UT19FREdFKTtcbiAgICAgICAgZ2wudGV4UGFyYW1ldGVyaShnbC5URVhUVVJFXzJELCBnbC5URVhUVVJFX01JTl9GSUxURVIsIGdsLkxJTkVBUik7XG4gICAgICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9NQUdfRklMVEVSLCBnbC5MSU5FQVIpO1xuXG4gICAgICAgIGZibyA9IGxheWVyLmhlYXRtYXBGYm8gPSBjb250ZXh0LmNyZWF0ZUZyYW1lYnVmZmVyKHdpZHRoLCBoZWlnaHQsIGZhbHNlKTtcblxuICAgICAgICBiaW5kVGV4dHVyZVRvRnJhbWVidWZmZXIoY29udGV4dCwgcGFpbnRlciwgdGV4dHVyZSwgZmJvLCB3aWR0aCwgaGVpZ2h0KTtcblxuICAgIH0gZWxzZSB7XG4gICAgICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIGZiby5jb2xvckF0dGFjaG1lbnQuZ2V0KCkpO1xuICAgICAgICBjb250ZXh0LmJpbmRGcmFtZWJ1ZmZlci5zZXQoZmJvLmZyYW1lYnVmZmVyKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGJpbmRUZXh0dXJlVG9GcmFtZWJ1ZmZlcihjb250ZXh0OiBDb250ZXh0LCBwYWludGVyOiBQYWludGVyLCB0ZXh0dXJlOiA/V2ViR0xUZXh0dXJlLCBmYm86IEZyYW1lYnVmZmVyLCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIGNvbnN0IGdsID0gY29udGV4dC5nbDtcbiAgICAvLyBVc2UgdGhlIGhpZ2hlciBwcmVjaXNpb24gaGFsZi1mbG9hdCB0ZXh0dXJlIHdoZXJlIGF2YWlsYWJsZSAocHJvZHVjaW5nIG11Y2ggc21vb3RoZXIgbG9va2luZyBoZWF0bWFwcyk7XG4gICAgLy8gT3RoZXJ3aXNlLCBmYWxsIGJhY2sgdG8gYSBsb3cgcHJlY2lzaW9uIHRleHR1cmVcbiAgICAvKiAkRmxvd0ZpeE1lW3Byb3AtbWlzc2luZ10gV2ViR0wyICovXG4gICAgY29uc3QgdHlwZSA9IGNvbnRleHQuZXh0UmVuZGVyVG9UZXh0dXJlSGFsZkZsb2F0ID8gKGNvbnRleHQuaXNXZWJHTDIgPyBnbC5IQUxGX0ZMT0FUIDogY29udGV4dC5leHRUZXh0dXJlSGFsZkZsb2F0LkhBTEZfRkxPQVRfT0VTKSA6IGdsLlVOU0lHTkVEX0JZVEU7XG4gICAgLyogJEZsb3dGaXhNZVtwcm9wLW1pc3NpbmddIFdlYkdMMiAqL1xuICAgIGdsLnRleEltYWdlMkQoZ2wuVEVYVFVSRV8yRCwgMCwgKGNvbnRleHQuaXNXZWJHTDIgJiYgY29udGV4dC5leHRSZW5kZXJUb1RleHR1cmVIYWxmRmxvYXQpID8gZ2wuUkdCQTE2RiA6IGdsLlJHQkEsIHdpZHRoLCBoZWlnaHQsIDAsIGdsLlJHQkEsIHR5cGUsIG51bGwpO1xuICAgIGZiby5jb2xvckF0dGFjaG1lbnQuc2V0KHRleHR1cmUpO1xufVxuXG5mdW5jdGlvbiByZW5kZXJUZXh0dXJlVG9NYXAocGFpbnRlcjogUGFpbnRlciwgbGF5ZXI6IEhlYXRtYXBTdHlsZUxheWVyKSB7XG4gICAgY29uc3QgY29udGV4dCA9IHBhaW50ZXIuY29udGV4dDtcbiAgICBjb25zdCBnbCA9IGNvbnRleHQuZ2w7XG5cbiAgICAvLyBIZXJlIHdlIGJpbmQgdHdvIGRpZmZlcmVudCB0ZXh0dXJlcyBmcm9tIHdoaWNoIHdlJ2xsIHNhbXBsZSBpbiBkcmF3aW5nXG4gICAgLy8gaGVhdG1hcHM6IHRoZSBrZXJuZWwgdGV4dHVyZSwgcHJlcGFyZWQgaW4gdGhlIG9mZnNjcmVlbiBwYXNzLCBhbmQgYVxuICAgIC8vIGNvbG9yIHJhbXAgdGV4dHVyZS5cbiAgICBjb25zdCBmYm8gPSBsYXllci5oZWF0bWFwRmJvO1xuICAgIGlmICghZmJvKSByZXR1cm47XG4gICAgY29udGV4dC5hY3RpdmVUZXh0dXJlLnNldChnbC5URVhUVVJFMCk7XG4gICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgZmJvLmNvbG9yQXR0YWNobWVudC5nZXQoKSk7XG5cbiAgICBjb250ZXh0LmFjdGl2ZVRleHR1cmUuc2V0KGdsLlRFWFRVUkUxKTtcbiAgICBsZXQgY29sb3JSYW1wVGV4dHVyZSA9IGxheWVyLmNvbG9yUmFtcFRleHR1cmU7XG4gICAgaWYgKCFjb2xvclJhbXBUZXh0dXJlKSB7XG4gICAgICAgIGNvbG9yUmFtcFRleHR1cmUgPSBsYXllci5jb2xvclJhbXBUZXh0dXJlID0gbmV3IFRleHR1cmUoY29udGV4dCwgbGF5ZXIuY29sb3JSYW1wLCBnbC5SR0JBKTtcbiAgICB9XG4gICAgY29sb3JSYW1wVGV4dHVyZS5iaW5kKGdsLkxJTkVBUiwgZ2wuQ0xBTVBfVE9fRURHRSk7XG5cbiAgICBwYWludGVyLnVzZVByb2dyYW0oJ2hlYXRtYXBUZXh0dXJlJykuZHJhdyhjb250ZXh0LCBnbC5UUklBTkdMRVMsXG4gICAgICAgIERlcHRoTW9kZS5kaXNhYmxlZCwgU3RlbmNpbE1vZGUuZGlzYWJsZWQsIHBhaW50ZXIuY29sb3JNb2RlRm9yUmVuZGVyUGFzcygpLCBDdWxsRmFjZU1vZGUuZGlzYWJsZWQsXG4gICAgICAgIGhlYXRtYXBUZXh0dXJlVW5pZm9ybVZhbHVlcyhwYWludGVyLCBsYXllciwgMCwgMSksXG4gICAgICAgIGxheWVyLmlkLCBwYWludGVyLnZpZXdwb3J0QnVmZmVyLCBwYWludGVyLnF1YWRUcmlhbmdsZUluZGV4QnVmZmVyLFxuICAgICAgICBwYWludGVyLnZpZXdwb3J0U2VnbWVudHMsIGxheWVyLnBhaW50LCBwYWludGVyLnRyYW5zZm9ybS56b29tKTtcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBEZXB0aE1vZGUgZnJvbSAnLi4vZ2wvZGVwdGhfbW9kZS5qcyc7XG5pbXBvcnQgQ3VsbEZhY2VNb2RlIGZyb20gJy4uL2dsL2N1bGxfZmFjZV9tb2RlLmpzJztcbmltcG9ydCBTdGVuY2lsTW9kZSBmcm9tICcuLi9nbC9zdGVuY2lsX21vZGUuanMnO1xuaW1wb3J0IFRleHR1cmUgZnJvbSAnLi90ZXh0dXJlLmpzJztcbmltcG9ydCB7XG4gICAgbGluZVVuaWZvcm1WYWx1ZXMsXG4gICAgbGluZVBhdHRlcm5Vbmlmb3JtVmFsdWVzLFxuICAgIGxpbmVEZWZpbmVzVmFsdWVzXG59IGZyb20gJy4vcHJvZ3JhbS9saW5lX3Byb2dyYW0uanMnO1xuaW1wb3J0IGJyb3dzZXIgZnJvbSAnLi4vdXRpbC9icm93c2VyLmpzJztcblxuaW1wb3J0IHR5cGUgUGFpbnRlciBmcm9tICcuL3BhaW50ZXIuanMnO1xuaW1wb3J0IHR5cGUgU291cmNlQ2FjaGUgZnJvbSAnLi4vc291cmNlL3NvdXJjZV9jYWNoZS5qcyc7XG5pbXBvcnQgdHlwZSBMaW5lU3R5bGVMYXllciBmcm9tICcuLi9zdHlsZS9zdHlsZV9sYXllci9saW5lX3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCB0eXBlIExpbmVCdWNrZXQgZnJvbSAnLi4vZGF0YS9idWNrZXQvbGluZV9idWNrZXQuanMnO1xuaW1wb3J0IHR5cGUge092ZXJzY2FsZWRUaWxlSUR9IGZyb20gJy4uL3NvdXJjZS90aWxlX2lkLmpzJztcbmltcG9ydCB0eXBlIHtEeW5hbWljRGVmaW5lc1R5cGV9IGZyb20gJy4vcHJvZ3JhbS9wcm9ncmFtX3VuaWZvcm1zLmpzJztcbmltcG9ydCB7Y2xhbXAsIG5leHRQb3dlck9mVHdvfSBmcm9tICcuLi91dGlsL3V0aWwuanMnO1xuaW1wb3J0IHtyZW5kZXJDb2xvclJhbXB9IGZyb20gJy4uL3V0aWwvY29sb3JfcmFtcC5qcyc7XG5pbXBvcnQgRVhURU5UIGZyb20gJy4uL2RhdGEvZXh0ZW50LmpzJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZHJhd0xpbmUocGFpbnRlcjogUGFpbnRlciwgc291cmNlQ2FjaGU6IFNvdXJjZUNhY2hlLCBsYXllcjogTGluZVN0eWxlTGF5ZXIsIGNvb3JkczogQXJyYXk8T3ZlcnNjYWxlZFRpbGVJRD4pIHtcbiAgICBpZiAocGFpbnRlci5yZW5kZXJQYXNzICE9PSAndHJhbnNsdWNlbnQnKSByZXR1cm47XG5cbiAgICBjb25zdCBvcGFjaXR5ID0gbGF5ZXIucGFpbnQuZ2V0KCdsaW5lLW9wYWNpdHknKTtcbiAgICBjb25zdCB3aWR0aCA9IGxheWVyLnBhaW50LmdldCgnbGluZS13aWR0aCcpO1xuICAgIGlmIChvcGFjaXR5LmNvbnN0YW50T3IoMSkgPT09IDAgfHwgd2lkdGguY29uc3RhbnRPcigxKSA9PT0gMCkgcmV0dXJuO1xuXG4gICAgY29uc3QgZGVwdGhNb2RlID0gcGFpbnRlci5kZXB0aE1vZGVGb3JTdWJsYXllcigwLCBEZXB0aE1vZGUuUmVhZE9ubHkpO1xuICAgIGNvbnN0IGNvbG9yTW9kZSA9IHBhaW50ZXIuY29sb3JNb2RlRm9yUmVuZGVyUGFzcygpO1xuICAgIGNvbnN0IHBpeGVsUmF0aW8gPSAocGFpbnRlci50ZXJyYWluICYmIHBhaW50ZXIudGVycmFpbi5yZW5kZXJpbmdUb1RleHR1cmUpID8gMS4wIDogYnJvd3Nlci5kZXZpY2VQaXhlbFJhdGlvO1xuXG4gICAgY29uc3QgZGFzaGFycmF5UHJvcGVydHkgPSBsYXllci5wYWludC5nZXQoJ2xpbmUtZGFzaGFycmF5Jyk7XG4gICAgY29uc3QgZGFzaGFycmF5ID0gZGFzaGFycmF5UHJvcGVydHkuY29uc3RhbnRPcigoMTogYW55KSk7XG4gICAgY29uc3QgY2FwUHJvcGVydHkgPSBsYXllci5sYXlvdXQuZ2V0KCdsaW5lLWNhcCcpO1xuICAgIGNvbnN0IHBhdHRlcm5Qcm9wZXJ0eSA9IGxheWVyLnBhaW50LmdldCgnbGluZS1wYXR0ZXJuJyk7XG4gICAgY29uc3QgaW1hZ2UgPSBwYXR0ZXJuUHJvcGVydHkuY29uc3RhbnRPcigoMTogYW55KSk7XG5cbiAgICBjb25zdCBncmFkaWVudCA9IGxheWVyLnBhaW50LmdldCgnbGluZS1ncmFkaWVudCcpO1xuXG4gICAgY29uc3QgcHJvZ3JhbUlkID0gaW1hZ2UgPyAnbGluZVBhdHRlcm4nIDogJ2xpbmUnO1xuXG4gICAgY29uc3QgY29udGV4dCA9IHBhaW50ZXIuY29udGV4dDtcbiAgICBjb25zdCBnbCA9IGNvbnRleHQuZ2w7XG5cbiAgICBjb25zdCBkZWZpbmVzVmFsdWVzID0gbGluZURlZmluZXNWYWx1ZXMobGF5ZXIpO1xuICAgIGxldCB1c2VTdGVuY2lsTWFza1JlbmRlclBhc3MgPSBkZWZpbmVzVmFsdWVzLmluY2x1ZGVzKCdSRU5ERVJfTElORV9BTFBIQV9ESVNDQVJEJyk7XG4gICAgaWYgKHBhaW50ZXIudGVycmFpbiAmJiBwYWludGVyLnRlcnJhaW4uY2xpcE9yTWFza092ZXJsYXBTdGVuY2lsVHlwZSgpKSB7XG4gICAgICAgIHVzZVN0ZW5jaWxNYXNrUmVuZGVyUGFzcyA9IGZhbHNlO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgY29vcmQgb2YgY29vcmRzKSB7XG4gICAgICAgIGNvbnN0IHRpbGUgPSBzb3VyY2VDYWNoZS5nZXRUaWxlKGNvb3JkKTtcbiAgICAgICAgaWYgKGltYWdlICYmICF0aWxlLnBhdHRlcm5zTG9hZGVkKCkpIGNvbnRpbnVlO1xuXG4gICAgICAgIGNvbnN0IGJ1Y2tldDogP0xpbmVCdWNrZXQgPSAodGlsZS5nZXRCdWNrZXQobGF5ZXIpOiBhbnkpO1xuICAgICAgICBpZiAoIWJ1Y2tldCkgY29udGludWU7XG4gICAgICAgIHBhaW50ZXIucHJlcGFyZURyYXdUaWxlKCk7XG5cbiAgICAgICAgY29uc3QgcHJvZ3JhbUNvbmZpZ3VyYXRpb24gPSBidWNrZXQucHJvZ3JhbUNvbmZpZ3VyYXRpb25zLmdldChsYXllci5pZCk7XG4gICAgICAgIGNvbnN0IHByb2dyYW0gPSBwYWludGVyLnVzZVByb2dyYW0ocHJvZ3JhbUlkLCBwcm9ncmFtQ29uZmlndXJhdGlvbiwgKChkZWZpbmVzVmFsdWVzOiBhbnkpOiBEeW5hbWljRGVmaW5lc1R5cGVbXSkpO1xuXG4gICAgICAgIGNvbnN0IGNvbnN0YW50UGF0dGVybiA9IHBhdHRlcm5Qcm9wZXJ0eS5jb25zdGFudE9yKG51bGwpO1xuICAgICAgICBpZiAoY29uc3RhbnRQYXR0ZXJuICYmIHRpbGUuaW1hZ2VBdGxhcykge1xuICAgICAgICAgICAgY29uc3QgcG9zVG8gPSB0aWxlLmltYWdlQXRsYXMucGF0dGVyblBvc2l0aW9uc1tjb25zdGFudFBhdHRlcm4udG9TdHJpbmcoKV07XG4gICAgICAgICAgICBpZiAocG9zVG8pIHByb2dyYW1Db25maWd1cmF0aW9uLnNldENvbnN0YW50UGF0dGVyblBvc2l0aW9ucyhwb3NUbyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjb25zdGFudERhc2ggPSBkYXNoYXJyYXlQcm9wZXJ0eS5jb25zdGFudE9yKG51bGwpO1xuICAgICAgICBjb25zdCBjb25zdGFudENhcCA9IGNhcFByb3BlcnR5LmNvbnN0YW50T3IoKG51bGw6IGFueSkpO1xuXG4gICAgICAgIGlmICghaW1hZ2UgJiYgY29uc3RhbnREYXNoICYmIGNvbnN0YW50Q2FwICYmIHRpbGUubGluZUF0bGFzKSB7XG4gICAgICAgICAgICBjb25zdCBwb3NUbyA9IHRpbGUubGluZUF0bGFzLmdldERhc2goY29uc3RhbnREYXNoLCBjb25zdGFudENhcCk7XG4gICAgICAgICAgICBpZiAocG9zVG8pIHByb2dyYW1Db25maWd1cmF0aW9uLnNldENvbnN0YW50UGF0dGVyblBvc2l0aW9ucyhwb3NUbyk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgW3RyaW1TdGFydCwgdHJpbUVuZF0gPSBsYXllci5wYWludC5nZXQoJ2xpbmUtdHJpbS1vZmZzZXQnKTtcbiAgICAgICAgLy8gV2hlbiBsaW5lIGNhcCBpcyAncm91bmQnIG9yICdzcXVhcmUnLCB0aGUgd2hvbGUgbGluZSBwcm9ncmVzcyB3aWxsIGJleW9uZCAxLjAgb3IgbGVzcyB0aGFuIDAuMC5cbiAgICAgICAgLy8gSWYgdHJpbV9vZmZzZXQgYmVnaW4gaXMgbGluZSBiZWdpbiAoMC4wKSwgb3IgdHJpbV9vZmZzZXQgZW5kIGlzIGxpbmUgZW5kICgxLjApLCBhZGp1c3QgdGhlIHRyaW1cbiAgICAgICAgLy8gb2Zmc2V0IHdpdGggZmFrZSBvZmZzZXQgc2hpZnQgc28gdGhhdCB0aGUgbGluZV9wcm9ncmVzcyA8IDAuMCBvciBsaW5lX3Byb2dyZXNzID4gMS4wIHBhcnQgd2lsbCBiZVxuICAgICAgICAvLyBjb3JyZWN0bHkgY292ZXJlZC5cbiAgICAgICAgaWYgKGNvbnN0YW50Q2FwID09PSAncm91bmQnIHx8IGNvbnN0YW50Q2FwID09PSAnc3F1YXJlJykge1xuICAgICAgICAgICAgLy8gRmFrZSB0aGUgcGVyY2VudGFnZSBzbyB0aGF0IGl0IHdpbGwgY292ZXIgdGhlIHJvdW5kL3NxdWFyZSBjYXAgdGhhdCBpcyBiZXlvbmQgd2hvbGUgbGluZVxuICAgICAgICAgICAgY29uc3QgZmFrZU9mZnNldFNoaWZ0ID0gMS4wO1xuICAgICAgICAgICAgLy8gVG8gbWFrZSBzdXJlIHRoYXQgdGhlIHRyaW0gb2Zmc2V0IHJhbmdlIGlzIGVmZmVjaXZlXG4gICAgICAgICAgICBpZiAodHJpbVN0YXJ0ICE9PSB0cmltRW5kKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRyaW1TdGFydCA9PT0gMC4wKSB7XG4gICAgICAgICAgICAgICAgICAgIHRyaW1TdGFydCAtPSBmYWtlT2Zmc2V0U2hpZnQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0cmltRW5kID09PSAxLjApIHtcbiAgICAgICAgICAgICAgICAgICAgdHJpbUVuZCArPSBmYWtlT2Zmc2V0U2hpZnQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbWF0cml4ID0gcGFpbnRlci50ZXJyYWluID8gY29vcmQucHJvak1hdHJpeCA6IG51bGw7XG4gICAgICAgIGNvbnN0IHVuaWZvcm1WYWx1ZXMgPSBpbWFnZSA/XG4gICAgICAgICAgICBsaW5lUGF0dGVyblVuaWZvcm1WYWx1ZXMocGFpbnRlciwgdGlsZSwgbGF5ZXIsIG1hdHJpeCwgcGl4ZWxSYXRpbykgOlxuICAgICAgICAgICAgbGluZVVuaWZvcm1WYWx1ZXMocGFpbnRlciwgdGlsZSwgbGF5ZXIsIG1hdHJpeCwgYnVja2V0LmxpbmVDbGlwc0FycmF5Lmxlbmd0aCwgcGl4ZWxSYXRpbywgW3RyaW1TdGFydCwgdHJpbUVuZF0pO1xuXG4gICAgICAgIGlmIChncmFkaWVudCkge1xuICAgICAgICAgICAgY29uc3QgbGF5ZXJHcmFkaWVudCA9IGJ1Y2tldC5ncmFkaWVudHNbbGF5ZXIuaWRdO1xuICAgICAgICAgICAgbGV0IGdyYWRpZW50VGV4dHVyZSA9IGxheWVyR3JhZGllbnQudGV4dHVyZTtcbiAgICAgICAgICAgIGlmIChsYXllci5ncmFkaWVudFZlcnNpb24gIT09IGxheWVyR3JhZGllbnQudmVyc2lvbikge1xuICAgICAgICAgICAgICAgIGxldCB0ZXh0dXJlUmVzb2x1dGlvbiA9IDI1NjtcbiAgICAgICAgICAgICAgICBpZiAobGF5ZXIuc3RlcEludGVycG9sYW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZU1heFpvb20gPSBzb3VyY2VDYWNoZS5nZXRTb3VyY2UoKS5tYXh6b29tO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwb3RlbnRpYWxPdmVyem9vbSA9IGNvb3JkLmNhbm9uaWNhbC56ID09PSBzb3VyY2VNYXhab29tID9cbiAgICAgICAgICAgICAgICAgICAgICAgIE1hdGguY2VpbCgxIDw8IChwYWludGVyLnRyYW5zZm9ybS5tYXhab29tIC0gY29vcmQuY2Fub25pY2FsLnopKSA6IDE7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGxpbmVMZW5ndGggPSBidWNrZXQubWF4TGluZUxlbmd0aCAvIEVYVEVOVDtcbiAgICAgICAgICAgICAgICAgICAgLy8gTG9naWNhbCBwaXhlbCB0aWxlIHNpemUgaXMgNTEycHgsIGFuZCAxMDI0cHggcmlnaHQgYmVmb3JlIGN1cnJlbnQgem9vbSArIDFcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF4VGlsZVBpeGVsU2l6ZSA9IDEwMjQ7XG4gICAgICAgICAgICAgICAgICAgIC8vIE1heGltdW0gcG9zc2libGUgdGV4dHVyZSBjb3ZlcmFnZSBoZXVyaXN0aWMsIGJvdW5kIGJ5IGhhcmR3YXJlIG1heCB0ZXh0dXJlIHNpemVcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF4VGV4dHVyZUNvdmVyYWdlID0gbGluZUxlbmd0aCAqIG1heFRpbGVQaXhlbFNpemUgKiBwb3RlbnRpYWxPdmVyem9vbTtcbiAgICAgICAgICAgICAgICAgICAgdGV4dHVyZVJlc29sdXRpb24gPSBjbGFtcChuZXh0UG93ZXJPZlR3byhtYXhUZXh0dXJlQ292ZXJhZ2UpLCAyNTYsIGNvbnRleHQubWF4VGV4dHVyZVNpemUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsYXllckdyYWRpZW50LmdyYWRpZW50ID0gcmVuZGVyQ29sb3JSYW1wKHtcbiAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogbGF5ZXIuZ3JhZGllbnRFeHByZXNzaW9uKCksXG4gICAgICAgICAgICAgICAgICAgIGV2YWx1YXRpb25LZXk6ICdsaW5lUHJvZ3Jlc3MnLFxuICAgICAgICAgICAgICAgICAgICByZXNvbHV0aW9uOiB0ZXh0dXJlUmVzb2x1dGlvbixcbiAgICAgICAgICAgICAgICAgICAgaW1hZ2U6IGxheWVyR3JhZGllbnQuZ3JhZGllbnQgfHwgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgICBjbGlwczogYnVja2V0LmxpbmVDbGlwc0FycmF5XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKGxheWVyR3JhZGllbnQudGV4dHVyZSkge1xuICAgICAgICAgICAgICAgICAgICBsYXllckdyYWRpZW50LnRleHR1cmUudXBkYXRlKGxheWVyR3JhZGllbnQuZ3JhZGllbnQpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxheWVyR3JhZGllbnQudGV4dHVyZSA9IG5ldyBUZXh0dXJlKGNvbnRleHQsIGxheWVyR3JhZGllbnQuZ3JhZGllbnQsIGdsLlJHQkEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsYXllckdyYWRpZW50LnZlcnNpb24gPSBsYXllci5ncmFkaWVudFZlcnNpb247XG4gICAgICAgICAgICAgICAgZ3JhZGllbnRUZXh0dXJlID0gbGF5ZXJHcmFkaWVudC50ZXh0dXJlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29udGV4dC5hY3RpdmVUZXh0dXJlLnNldChnbC5URVhUVVJFMSk7XG4gICAgICAgICAgICBncmFkaWVudFRleHR1cmUuYmluZChsYXllci5zdGVwSW50ZXJwb2xhbnQgPyBnbC5ORUFSRVNUIDogZ2wuTElORUFSLCBnbC5DTEFNUF9UT19FREdFKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGFzaGFycmF5KSB7XG4gICAgICAgICAgICBjb250ZXh0LmFjdGl2ZVRleHR1cmUuc2V0KGdsLlRFWFRVUkUwKTtcbiAgICAgICAgICAgIHRpbGUubGluZUF0bGFzVGV4dHVyZS5iaW5kKGdsLkxJTkVBUiwgZ2wuUkVQRUFUKTtcbiAgICAgICAgICAgIHByb2dyYW1Db25maWd1cmF0aW9uLnVwZGF0ZVBhaW50QnVmZmVycygpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpbWFnZSkge1xuICAgICAgICAgICAgY29udGV4dC5hY3RpdmVUZXh0dXJlLnNldChnbC5URVhUVVJFMCk7XG4gICAgICAgICAgICB0aWxlLmltYWdlQXRsYXNUZXh0dXJlLmJpbmQoZ2wuTElORUFSLCBnbC5DTEFNUF9UT19FREdFKTtcbiAgICAgICAgICAgIHByb2dyYW1Db25maWd1cmF0aW9uLnVwZGF0ZVBhaW50QnVmZmVycygpO1xuICAgICAgICB9XG5cbiAgICAgICAgcGFpbnRlci5wcmVwYXJlRHJhd1Byb2dyYW0oY29udGV4dCwgcHJvZ3JhbSwgY29vcmQudG9VbndyYXBwZWQoKSk7XG5cbiAgICAgICAgY29uc3QgcmVuZGVyTGluZSA9IChzdGVuY2lsTW9kZTogU3RlbmNpbE1vZGUpID0+IHtcbiAgICAgICAgICAgIHByb2dyYW0uZHJhdyhjb250ZXh0LCBnbC5UUklBTkdMRVMsIGRlcHRoTW9kZSxcbiAgICAgICAgICAgICAgICBzdGVuY2lsTW9kZSwgY29sb3JNb2RlLCBDdWxsRmFjZU1vZGUuZGlzYWJsZWQsIHVuaWZvcm1WYWx1ZXMsXG4gICAgICAgICAgICAgICAgbGF5ZXIuaWQsIGJ1Y2tldC5sYXlvdXRWZXJ0ZXhCdWZmZXIsIGJ1Y2tldC5pbmRleEJ1ZmZlciwgYnVja2V0LnNlZ21lbnRzLFxuICAgICAgICAgICAgICAgIGxheWVyLnBhaW50LCBwYWludGVyLnRyYW5zZm9ybS56b29tLCBwcm9ncmFtQ29uZmlndXJhdGlvbiwgW2J1Y2tldC5sYXlvdXRWZXJ0ZXhCdWZmZXIyXSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKHVzZVN0ZW5jaWxNYXNrUmVuZGVyUGFzcykge1xuICAgICAgICAgICAgY29uc3Qgc3RlbmNpbElkID0gcGFpbnRlci5zdGVuY2lsTW9kZUZvckNsaXBwaW5nKGNvb3JkKS5yZWY7XG4gICAgICAgICAgICAvLyBXaGVuIHRlcnJhaW4gaXMgb24sIGVuc3VyZSB0aGF0IHRoZSBzdGVuY2lsIGJ1ZmZlciBoYXMgMCB2YWx1ZXMuXG4gICAgICAgICAgICAvLyBBcyBzdGVuY2lsIG1heSBiZSBkaXNhYmxlZCB3aGVuIGl0IGlzIG5vdCBpbiBvdmVybGFwcGluZyBzdGVuY2lsXG4gICAgICAgICAgICAvLyBtb2RlLiBSZWZlciB0byBzdGVuY2lsTW9kZUZvclJUVE92ZXJsYXAgbG9naWMuXG4gICAgICAgICAgICBpZiAoc3RlbmNpbElkID09PSAwICYmIHBhaW50ZXIudGVycmFpbikge1xuICAgICAgICAgICAgICAgIGNvbnRleHQuY2xlYXIoe3N0ZW5jaWw6IDB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHN0ZW5jaWxGdW5jID0ge2Z1bmM6IGdsLkVRVUFMLCBtYXNrOiAweEZGfTtcblxuICAgICAgICAgICAgLy8gQWxsb3cgbGluZSBnZW9tZXRyeSBmcmFnbWVudCB0byBiZSBkcmF3biBvbmx5IG9uY2U6XG4gICAgICAgICAgICAvLyAtIEludmVydCB0aGUgc3RlbmNpbCBpZGVudGlmaWVyIGxlZnQgYnkgc3RlbmNpbCBjbGlwcGluZywgdGhpc1xuICAgICAgICAgICAgLy8gZW5zdXJlcyB0aGF0IHdlIGFyZSBub3QgY29uZmxpY3Rpbmcgd2l0aCBuZWlnaGJvcmhpbmcgdGlsZXMuXG4gICAgICAgICAgICAvLyAtIERyYXcgQW50aS1BbGlhc2VkIHBpeGVscyB3aXRoIGEgdGhyZXNob2xkIHNldCB0byAwLjgsIHRoaXNcbiAgICAgICAgICAgIC8vIG1heSBkcmF3IEFudGktQWxpYXNlZCBwaXhlbHMgbW9yZSB0aGFuIG9uY2UsIGJ1dCBkdWUgdG8gdGhlaXJcbiAgICAgICAgICAgIC8vIGxvdyBvcGFjaXR5LCB0aGVzZSBwaXhlbHMgYXJlIHVzdWFsbHkgaW52aXNpYmxlIGFuZCBwb3RlbnRpYWxcbiAgICAgICAgICAgIC8vIG92ZXJsYXBwaW5nIHBpeGVsIGFydGlmYWN0cyBsb2NhbGx5IG1pbmltaXplZC5cbiAgICAgICAgICAgIHVuaWZvcm1WYWx1ZXNbJ3VfYWxwaGFfZGlzY2FyZF90aHJlc2hvbGQnXSA9IDAuODtcbiAgICAgICAgICAgIHJlbmRlckxpbmUobmV3IFN0ZW5jaWxNb2RlKHN0ZW5jaWxGdW5jLCBzdGVuY2lsSWQsIDB4RkYsIGdsLktFRVAsIGdsLktFRVAsIGdsLklOVkVSVCkpO1xuICAgICAgICAgICAgdW5pZm9ybVZhbHVlc1sndV9hbHBoYV9kaXNjYXJkX3RocmVzaG9sZCddID0gMC4wO1xuICAgICAgICAgICAgcmVuZGVyTGluZShuZXcgU3RlbmNpbE1vZGUoc3RlbmNpbEZ1bmMsIHN0ZW5jaWxJZCwgMHhGRiwgZ2wuS0VFUCwgZ2wuS0VFUCwgZ2wuS0VFUCkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmVuZGVyTGluZShwYWludGVyLnN0ZW5jaWxNb2RlRm9yQ2xpcHBpbmcoY29vcmQpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFdoZW4gcmVuZGVyaW5nIHRvIHN0ZW5jaWwsIHJlc2V0IHRoZSBtYXNrIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSB0aWxlXG4gICAgLy8gY2xpcHBpbmcgcmV2ZXJ0cyB0aGUgc3RlbmNpbCBtYXNrIHdlIG1heSBoYXZlIGRyYXduIGluIHRoZSBidWZmZXIuXG4gICAgLy8gVGhlIHN0YW1wIGNvdWxkIGJlIHJldmVydGVkIGJ5IGFuIGV4dHJhIGRyYXcgY2FsbCBvZiBsaW5lIGdlb21ldHJ5LFxuICAgIC8vIGJ1dCB0aWxlIGNsaXBwaW5nIGRyYXdpbmcgaXMgdXN1YWxseSBmYXN0ZXIgdG8gZHJhdyB0aGFuIGxpbmVzLlxuICAgIGlmICh1c2VTdGVuY2lsTWFza1JlbmRlclBhc3MpIHtcbiAgICAgICAgcGFpbnRlci5yZXNldFN0ZW5jaWxDbGlwcGluZ01hc2tzKCk7XG4gICAgICAgIGlmIChwYWludGVyLnRlcnJhaW4pIHsgY29udGV4dC5jbGVhcih7c3RlbmNpbDogMH0pOyB9XG4gICAgfVxufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IENvbG9yIGZyb20gJy4uL3N0eWxlLXNwZWMvdXRpbC9jb2xvci5qcyc7XG5pbXBvcnQgRGVwdGhNb2RlIGZyb20gJy4uL2dsL2RlcHRoX21vZGUuanMnO1xuaW1wb3J0IEN1bGxGYWNlTW9kZSBmcm9tICcuLi9nbC9jdWxsX2ZhY2VfbW9kZS5qcyc7XG5pbXBvcnQge1xuICAgIGZpbGxVbmlmb3JtVmFsdWVzLFxuICAgIGZpbGxQYXR0ZXJuVW5pZm9ybVZhbHVlcyxcbiAgICBmaWxsT3V0bGluZVVuaWZvcm1WYWx1ZXMsXG4gICAgZmlsbE91dGxpbmVQYXR0ZXJuVW5pZm9ybVZhbHVlc1xufSBmcm9tICcuL3Byb2dyYW0vZmlsbF9wcm9ncmFtLmpzJztcblxuaW1wb3J0IHR5cGUgUGFpbnRlciBmcm9tICcuL3BhaW50ZXIuanMnO1xuaW1wb3J0IHR5cGUgU291cmNlQ2FjaGUgZnJvbSAnLi4vc291cmNlL3NvdXJjZV9jYWNoZS5qcyc7XG5pbXBvcnQgdHlwZSBGaWxsU3R5bGVMYXllciBmcm9tICcuLi9zdHlsZS9zdHlsZV9sYXllci9maWxsX3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCB0eXBlIEZpbGxCdWNrZXQgZnJvbSAnLi4vZGF0YS9idWNrZXQvZmlsbF9idWNrZXQuanMnO1xuaW1wb3J0IHR5cGUgQ29sb3JNb2RlIGZyb20gJy4uL2dsL2NvbG9yX21vZGUuanMnO1xuaW1wb3J0IHR5cGUge092ZXJzY2FsZWRUaWxlSUR9IGZyb20gJy4uL3NvdXJjZS90aWxlX2lkLmpzJztcblxuZXhwb3J0IGRlZmF1bHQgZHJhd0ZpbGw7XG5cbmZ1bmN0aW9uIGRyYXdGaWxsKHBhaW50ZXI6IFBhaW50ZXIsIHNvdXJjZUNhY2hlOiBTb3VyY2VDYWNoZSwgbGF5ZXI6IEZpbGxTdHlsZUxheWVyLCBjb29yZHM6IEFycmF5PE92ZXJzY2FsZWRUaWxlSUQ+KSB7XG4gICAgY29uc3QgY29sb3IgPSBsYXllci5wYWludC5nZXQoJ2ZpbGwtY29sb3InKTtcbiAgICBjb25zdCBvcGFjaXR5ID0gbGF5ZXIucGFpbnQuZ2V0KCdmaWxsLW9wYWNpdHknKTtcblxuICAgIGlmIChvcGFjaXR5LmNvbnN0YW50T3IoMSkgPT09IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbG9yTW9kZSA9IHBhaW50ZXIuY29sb3JNb2RlRm9yUmVuZGVyUGFzcygpO1xuXG4gICAgY29uc3QgcGF0dGVybiA9IGxheWVyLnBhaW50LmdldCgnZmlsbC1wYXR0ZXJuJyk7XG4gICAgY29uc3QgcGFzcyA9IHBhaW50ZXIub3BhcXVlUGFzc0VuYWJsZWRGb3JMYXllcigpICYmXG4gICAgICAgICghcGF0dGVybi5jb25zdGFudE9yKCgxOiBhbnkpKSAmJlxuICAgICAgICBjb2xvci5jb25zdGFudE9yKENvbG9yLnRyYW5zcGFyZW50KS5hID09PSAxICYmXG4gICAgICAgIG9wYWNpdHkuY29uc3RhbnRPcigwKSA9PT0gMSkgPyAnb3BhcXVlJyA6ICd0cmFuc2x1Y2VudCc7XG5cbiAgICAvLyBEcmF3IGZpbGxcbiAgICBpZiAocGFpbnRlci5yZW5kZXJQYXNzID09PSBwYXNzKSB7XG4gICAgICAgIGNvbnN0IGRlcHRoTW9kZSA9IHBhaW50ZXIuZGVwdGhNb2RlRm9yU3VibGF5ZXIoXG4gICAgICAgICAgICAxLCBwYWludGVyLnJlbmRlclBhc3MgPT09ICdvcGFxdWUnID8gRGVwdGhNb2RlLlJlYWRXcml0ZSA6IERlcHRoTW9kZS5SZWFkT25seSk7XG4gICAgICAgIGRyYXdGaWxsVGlsZXMocGFpbnRlciwgc291cmNlQ2FjaGUsIGxheWVyLCBjb29yZHMsIGRlcHRoTW9kZSwgY29sb3JNb2RlLCBmYWxzZSk7XG4gICAgfVxuXG4gICAgLy8gRHJhdyBzdHJva2VcbiAgICBpZiAocGFpbnRlci5yZW5kZXJQYXNzID09PSAndHJhbnNsdWNlbnQnICYmIGxheWVyLnBhaW50LmdldCgnZmlsbC1hbnRpYWxpYXMnKSkge1xuXG4gICAgICAgIC8vIElmIHdlIGRlZmluZWQgYSBkaWZmZXJlbnQgY29sb3IgZm9yIHRoZSBmaWxsIG91dGxpbmUsIHdlIGFyZVxuICAgICAgICAvLyBnb2luZyB0byBpZ25vcmUgdGhlIGJpdHMgaW4gMHgwNyBhbmQganVzdCBjYXJlIGFib3V0IHRoZSBnbG9iYWxcbiAgICAgICAgLy8gY2xpcHBpbmcgbWFzay5cbiAgICAgICAgLy8gT3RoZXJ3aXNlLCB3ZSBvbmx5IHdhbnQgdG8gZHJhd0ZpbGwgdGhlIGFudGlhbGlhc2VkIHBhcnRzIHRoYXQgYXJlXG4gICAgICAgIC8vICpvdXRzaWRlKiB0aGUgY3VycmVudCBzaGFwZS4gVGhpcyBpcyBpbXBvcnRhbnQgaW4gY2FzZSB0aGUgZmlsbFxuICAgICAgICAvLyBvciBzdHJva2UgY29sb3IgaXMgdHJhbnNsdWNlbnQuIElmIHdlIHdvdWxkbid0IGNsaXAgdG8gb3V0c2lkZVxuICAgICAgICAvLyB0aGUgY3VycmVudCBzaGFwZSwgc29tZSBwaXhlbHMgZnJvbSB0aGUgb3V0bGluZSBzdHJva2Ugb3ZlcmxhcHBlZFxuICAgICAgICAvLyB0aGUgKG5vbi1hbnRpYWxpYXNlZCkgZmlsbC5cbiAgICAgICAgY29uc3QgZGVwdGhNb2RlID0gcGFpbnRlci5kZXB0aE1vZGVGb3JTdWJsYXllcihcbiAgICAgICAgICAgIGxheWVyLmdldFBhaW50UHJvcGVydHkoJ2ZpbGwtb3V0bGluZS1jb2xvcicpID8gMiA6IDAsIERlcHRoTW9kZS5SZWFkT25seSk7XG4gICAgICAgIGRyYXdGaWxsVGlsZXMocGFpbnRlciwgc291cmNlQ2FjaGUsIGxheWVyLCBjb29yZHMsIGRlcHRoTW9kZSwgY29sb3JNb2RlLCB0cnVlKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRyYXdGaWxsVGlsZXMocGFpbnRlcjogUGFpbnRlciwgc291cmNlQ2FjaGU6IFNvdXJjZUNhY2hlLCBsYXllcjogRmlsbFN0eWxlTGF5ZXIsIGNvb3JkczogQXJyYXk8T3ZlcnNjYWxlZFRpbGVJRD4sIGRlcHRoTW9kZTogRGVwdGhNb2RlLCBjb2xvck1vZGU6IENvbG9yTW9kZSwgaXNPdXRsaW5lOiBib29sZWFuKSB7XG4gICAgY29uc3QgZ2wgPSBwYWludGVyLmNvbnRleHQuZ2w7XG5cbiAgICBjb25zdCBwYXR0ZXJuUHJvcGVydHkgPSBsYXllci5wYWludC5nZXQoJ2ZpbGwtcGF0dGVybicpO1xuICAgIGNvbnN0IGltYWdlID0gcGF0dGVyblByb3BlcnR5ICYmIHBhdHRlcm5Qcm9wZXJ0eS5jb25zdGFudE9yKCgxOiBhbnkpKTtcbiAgICBsZXQgZHJhd01vZGUsIHByb2dyYW1OYW1lLCB1bmlmb3JtVmFsdWVzLCBpbmRleEJ1ZmZlciwgc2VnbWVudHM7XG5cbiAgICBpZiAoIWlzT3V0bGluZSkge1xuICAgICAgICBwcm9ncmFtTmFtZSA9IGltYWdlID8gJ2ZpbGxQYXR0ZXJuJyA6ICdmaWxsJztcbiAgICAgICAgZHJhd01vZGUgPSBnbC5UUklBTkdMRVM7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcHJvZ3JhbU5hbWUgPSBpbWFnZSAmJiAhbGF5ZXIuZ2V0UGFpbnRQcm9wZXJ0eSgnZmlsbC1vdXRsaW5lLWNvbG9yJykgPyAnZmlsbE91dGxpbmVQYXR0ZXJuJyA6ICdmaWxsT3V0bGluZSc7XG4gICAgICAgIGRyYXdNb2RlID0gZ2wuTElORVM7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBjb29yZCBvZiBjb29yZHMpIHtcbiAgICAgICAgY29uc3QgdGlsZSA9IHNvdXJjZUNhY2hlLmdldFRpbGUoY29vcmQpO1xuICAgICAgICBpZiAoaW1hZ2UgJiYgIXRpbGUucGF0dGVybnNMb2FkZWQoKSkgY29udGludWU7XG5cbiAgICAgICAgY29uc3QgYnVja2V0OiA/RmlsbEJ1Y2tldCA9ICh0aWxlLmdldEJ1Y2tldChsYXllcik6IGFueSk7XG4gICAgICAgIGlmICghYnVja2V0KSBjb250aW51ZTtcbiAgICAgICAgcGFpbnRlci5wcmVwYXJlRHJhd1RpbGUoKTtcblxuICAgICAgICBjb25zdCBwcm9ncmFtQ29uZmlndXJhdGlvbiA9IGJ1Y2tldC5wcm9ncmFtQ29uZmlndXJhdGlvbnMuZ2V0KGxheWVyLmlkKTtcbiAgICAgICAgY29uc3QgcHJvZ3JhbSA9IHBhaW50ZXIudXNlUHJvZ3JhbShwcm9ncmFtTmFtZSwgcHJvZ3JhbUNvbmZpZ3VyYXRpb24pO1xuXG4gICAgICAgIGlmIChpbWFnZSkge1xuICAgICAgICAgICAgcGFpbnRlci5jb250ZXh0LmFjdGl2ZVRleHR1cmUuc2V0KGdsLlRFWFRVUkUwKTtcbiAgICAgICAgICAgIHRpbGUuaW1hZ2VBdGxhc1RleHR1cmUuYmluZChnbC5MSU5FQVIsIGdsLkNMQU1QX1RPX0VER0UpO1xuICAgICAgICAgICAgcHJvZ3JhbUNvbmZpZ3VyYXRpb24udXBkYXRlUGFpbnRCdWZmZXJzKCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjb25zdGFudFBhdHRlcm4gPSBwYXR0ZXJuUHJvcGVydHkuY29uc3RhbnRPcihudWxsKTtcbiAgICAgICAgaWYgKGNvbnN0YW50UGF0dGVybiAmJiB0aWxlLmltYWdlQXRsYXMpIHtcbiAgICAgICAgICAgIGNvbnN0IGF0bGFzID0gdGlsZS5pbWFnZUF0bGFzO1xuICAgICAgICAgICAgY29uc3QgcG9zVG8gPSBhdGxhcy5wYXR0ZXJuUG9zaXRpb25zW2NvbnN0YW50UGF0dGVybi50b1N0cmluZygpXTtcbiAgICAgICAgICAgIGlmIChwb3NUbykgcHJvZ3JhbUNvbmZpZ3VyYXRpb24uc2V0Q29uc3RhbnRQYXR0ZXJuUG9zaXRpb25zKHBvc1RvKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRpbGVNYXRyaXggPSBwYWludGVyLnRyYW5zbGF0ZVBvc01hdHJpeChjb29yZC5wcm9qTWF0cml4LCB0aWxlLFxuICAgICAgICAgICAgbGF5ZXIucGFpbnQuZ2V0KCdmaWxsLXRyYW5zbGF0ZScpLCBsYXllci5wYWludC5nZXQoJ2ZpbGwtdHJhbnNsYXRlLWFuY2hvcicpKTtcblxuICAgICAgICBpZiAoIWlzT3V0bGluZSkge1xuICAgICAgICAgICAgaW5kZXhCdWZmZXIgPSBidWNrZXQuaW5kZXhCdWZmZXI7XG4gICAgICAgICAgICBzZWdtZW50cyA9IGJ1Y2tldC5zZWdtZW50cztcbiAgICAgICAgICAgIHVuaWZvcm1WYWx1ZXMgPSBpbWFnZSA/XG4gICAgICAgICAgICAgICAgZmlsbFBhdHRlcm5Vbmlmb3JtVmFsdWVzKHRpbGVNYXRyaXgsIHBhaW50ZXIsIHRpbGUpIDpcbiAgICAgICAgICAgICAgICBmaWxsVW5pZm9ybVZhbHVlcyh0aWxlTWF0cml4KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGluZGV4QnVmZmVyID0gYnVja2V0LmluZGV4QnVmZmVyMjtcbiAgICAgICAgICAgIHNlZ21lbnRzID0gYnVja2V0LnNlZ21lbnRzMjtcbiAgICAgICAgICAgIGNvbnN0IGRyYXdpbmdCdWZmZXJTaXplID0gKHBhaW50ZXIudGVycmFpbiAmJiBwYWludGVyLnRlcnJhaW4ucmVuZGVyaW5nVG9UZXh0dXJlKSA/IHBhaW50ZXIudGVycmFpbi5kcmFwZUJ1ZmZlclNpemUgOiBbZ2wuZHJhd2luZ0J1ZmZlcldpZHRoLCBnbC5kcmF3aW5nQnVmZmVySGVpZ2h0XTtcbiAgICAgICAgICAgIHVuaWZvcm1WYWx1ZXMgPSAocHJvZ3JhbU5hbWUgPT09ICdmaWxsT3V0bGluZVBhdHRlcm4nICYmIGltYWdlKSA/XG4gICAgICAgICAgICAgICAgZmlsbE91dGxpbmVQYXR0ZXJuVW5pZm9ybVZhbHVlcyh0aWxlTWF0cml4LCBwYWludGVyLCB0aWxlLCBkcmF3aW5nQnVmZmVyU2l6ZSkgOlxuICAgICAgICAgICAgICAgIGZpbGxPdXRsaW5lVW5pZm9ybVZhbHVlcyh0aWxlTWF0cml4LCBkcmF3aW5nQnVmZmVyU2l6ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBwYWludGVyLnByZXBhcmVEcmF3UHJvZ3JhbShwYWludGVyLmNvbnRleHQsIHByb2dyYW0sIGNvb3JkLnRvVW53cmFwcGVkKCkpO1xuXG4gICAgICAgIHByb2dyYW0uZHJhdyhwYWludGVyLmNvbnRleHQsIGRyYXdNb2RlLCBkZXB0aE1vZGUsXG4gICAgICAgICAgICBwYWludGVyLnN0ZW5jaWxNb2RlRm9yQ2xpcHBpbmcoY29vcmQpLCBjb2xvck1vZGUsIEN1bGxGYWNlTW9kZS5kaXNhYmxlZCwgdW5pZm9ybVZhbHVlcyxcbiAgICAgICAgICAgIGxheWVyLmlkLCBidWNrZXQubGF5b3V0VmVydGV4QnVmZmVyLCBpbmRleEJ1ZmZlciwgc2VnbWVudHMsXG4gICAgICAgICAgICBsYXllci5wYWludCwgcGFpbnRlci50cmFuc2Zvcm0uem9vbSwgcHJvZ3JhbUNvbmZpZ3VyYXRpb24pO1xuICAgIH1cbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBEZXB0aE1vZGUgZnJvbSAnLi4vZ2wvZGVwdGhfbW9kZS5qcyc7XG5pbXBvcnQgU3RlbmNpbE1vZGUgZnJvbSAnLi4vZ2wvc3RlbmNpbF9tb2RlLmpzJztcbmltcG9ydCBDb2xvck1vZGUgZnJvbSAnLi4vZ2wvY29sb3JfbW9kZS5qcyc7XG5pbXBvcnQgQ3VsbEZhY2VNb2RlIGZyb20gJy4uL2dsL2N1bGxfZmFjZV9tb2RlLmpzJztcbmltcG9ydCBFWFRFTlQgZnJvbSAnLi4vZGF0YS9leHRlbnQuanMnO1xuaW1wb3J0IEZpbGxFeHRydXNpb25CdWNrZXQsIHtmaWxsRXh0cnVzaW9uSGVpZ2h0TGlmdH0gZnJvbSAnLi4vZGF0YS9idWNrZXQvZmlsbF9leHRydXNpb25fYnVja2V0LmpzJztcbmltcG9ydCB7XG4gICAgZmlsbEV4dHJ1c2lvblVuaWZvcm1WYWx1ZXMsXG4gICAgZmlsbEV4dHJ1c2lvblBhdHRlcm5Vbmlmb3JtVmFsdWVzLFxufSBmcm9tICcuL3Byb2dyYW0vZmlsbF9leHRydXNpb25fcHJvZ3JhbS5qcyc7XG5pbXBvcnQgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5pbXBvcnQge092ZXJzY2FsZWRUaWxlSUR9IGZyb20gJy4uL3NvdXJjZS90aWxlX2lkLmpzJztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCB7bWVyY2F0b3JYZnJvbUxuZywgbWVyY2F0b3JZZnJvbUxhdH0gZnJvbSAnLi4vZ2VvL21lcmNhdG9yX2Nvb3JkaW5hdGUuanMnO1xuaW1wb3J0IHtnbG9iZVRvTWVyY2F0b3JUcmFuc2l0aW9ufSBmcm9tICcuLi9nZW8vcHJvamVjdGlvbi9nbG9iZV91dGlsLmpzJztcbmltcG9ydCBDb250ZXh0IGZyb20gJy4uL2dsL2NvbnRleHQuanMnO1xuaW1wb3J0IHtUZXJyYWlufSBmcm9tICcuLi90ZXJyYWluL3RlcnJhaW4uanMnO1xuXG5pbXBvcnQgdHlwZSBQYWludGVyIGZyb20gJy4vcGFpbnRlci5qcyc7XG5pbXBvcnQgdHlwZSBTb3VyY2VDYWNoZSBmcm9tICcuLi9zb3VyY2Uvc291cmNlX2NhY2hlLmpzJztcbmltcG9ydCB0eXBlIHtQYXJ0TWV0YWRhdGF9IGZyb20gJy4uL2RhdGEvYnVja2V0L2ZpbGxfZXh0cnVzaW9uX2J1Y2tldC5qcyc7XG5pbXBvcnQgdHlwZSBGaWxsRXh0cnVzaW9uU3R5bGVMYXllciBmcm9tICcuLi9zdHlsZS9zdHlsZV9sYXllci9maWxsX2V4dHJ1c2lvbl9zdHlsZV9sYXllci5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGRyYXc7XG5cbmZ1bmN0aW9uIGRyYXcocGFpbnRlcjogUGFpbnRlciwgc291cmNlOiBTb3VyY2VDYWNoZSwgbGF5ZXI6IEZpbGxFeHRydXNpb25TdHlsZUxheWVyLCBjb29yZHM6IEFycmF5PE92ZXJzY2FsZWRUaWxlSUQ+KSB7XG4gICAgY29uc3Qgb3BhY2l0eSA9IGxheWVyLnBhaW50LmdldCgnZmlsbC1leHRydXNpb24tb3BhY2l0eScpO1xuICAgIGlmIChvcGFjaXR5ID09PSAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAocGFpbnRlci5yZW5kZXJQYXNzID09PSAndHJhbnNsdWNlbnQnKSB7XG4gICAgICAgIGNvbnN0IGRlcHRoTW9kZSA9IG5ldyBEZXB0aE1vZGUocGFpbnRlci5jb250ZXh0LmdsLkxFUVVBTCwgRGVwdGhNb2RlLlJlYWRXcml0ZSwgcGFpbnRlci5kZXB0aFJhbmdlRm9yM0QpO1xuXG4gICAgICAgIGlmIChvcGFjaXR5ID09PSAxICYmICFsYXllci5wYWludC5nZXQoJ2ZpbGwtZXh0cnVzaW9uLXBhdHRlcm4nKS5jb25zdGFudE9yKCgxOiBhbnkpKSkge1xuICAgICAgICAgICAgY29uc3QgY29sb3JNb2RlID0gcGFpbnRlci5jb2xvck1vZGVGb3JSZW5kZXJQYXNzKCk7XG4gICAgICAgICAgICBkcmF3RXh0cnVzaW9uVGlsZXMocGFpbnRlciwgc291cmNlLCBsYXllciwgY29vcmRzLCBkZXB0aE1vZGUsIFN0ZW5jaWxNb2RlLmRpc2FibGVkLCBjb2xvck1vZGUpO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBEcmF3IHRyYW5zcGFyZW50IGJ1aWxkaW5ncyBpbiB0d28gcGFzc2VzIHNvIHRoYXQgb25seSB0aGUgY2xvc2VzdCBzdXJmYWNlIGlzIGRyYXduLlxuICAgICAgICAgICAgLy8gRmlyc3QgZHJhdyBhbGwgdGhlIGV4dHJ1c2lvbnMgaW50byBvbmx5IHRoZSBkZXB0aCBidWZmZXIuIE5vIGNvbG9ycyBhcmUgZHJhd24uXG4gICAgICAgICAgICBkcmF3RXh0cnVzaW9uVGlsZXMocGFpbnRlciwgc291cmNlLCBsYXllciwgY29vcmRzLCBkZXB0aE1vZGUsXG4gICAgICAgICAgICAgICAgU3RlbmNpbE1vZGUuZGlzYWJsZWQsXG4gICAgICAgICAgICAgICAgQ29sb3JNb2RlLmRpc2FibGVkKTtcblxuICAgICAgICAgICAgLy8gVGhlbiBkcmF3IGFsbCB0aGUgZXh0cnVzaW9ucyBhIHNlY29uZCB0eXBlLCBvbmx5IGNvbG9yaW5nIGZyYWdtZW50cyBpZiB0aGV5IGhhdmUgdGhlXG4gICAgICAgICAgICAvLyBzYW1lIGRlcHRoIHZhbHVlIGFzIHRoZSBjbG9zZXN0IGZyYWdtZW50IGluIHRoZSBwcmV2aW91cyBwYXNzLiBVc2UgdGhlIHN0ZW5jaWwgYnVmZmVyXG4gICAgICAgICAgICAvLyB0byBwcmV2ZW50IHRoZSBzZWNvbmQgZHJhdyBpbiBjYXNlcyB3aGVyZSB3ZSBoYXZlIGNvaW5jaWRlbnQgcG9seWdvbnMuXG4gICAgICAgICAgICBkcmF3RXh0cnVzaW9uVGlsZXMocGFpbnRlciwgc291cmNlLCBsYXllciwgY29vcmRzLCBkZXB0aE1vZGUsXG4gICAgICAgICAgICAgICAgcGFpbnRlci5zdGVuY2lsTW9kZUZvcjNEKCksXG4gICAgICAgICAgICAgICAgcGFpbnRlci5jb2xvck1vZGVGb3JSZW5kZXJQYXNzKCkpO1xuXG4gICAgICAgICAgICBwYWludGVyLnJlc2V0U3RlbmNpbENsaXBwaW5nTWFza3MoKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gZHJhd0V4dHJ1c2lvblRpbGVzKHBhaW50ZXI6IFBhaW50ZXIsIHNvdXJjZTogU291cmNlQ2FjaGUsIGxheWVyOiBGaWxsRXh0cnVzaW9uU3R5bGVMYXllciwgY29vcmRzOiBBcnJheTxPdmVyc2NhbGVkVGlsZUlEPiwgZGVwdGhNb2RlOiBEZXB0aE1vZGUsIHN0ZW5jaWxNb2RlOiBTdGVuY2lsTW9kZSwgY29sb3JNb2RlOiBDb2xvck1vZGUpIHtcbiAgICBjb25zdCBjb250ZXh0ID0gcGFpbnRlci5jb250ZXh0O1xuICAgIGNvbnN0IGdsID0gY29udGV4dC5nbDtcbiAgICBjb25zdCB0ciA9IHBhaW50ZXIudHJhbnNmb3JtO1xuICAgIGNvbnN0IHBhdHRlcm5Qcm9wZXJ0eSA9IGxheWVyLnBhaW50LmdldCgnZmlsbC1leHRydXNpb24tcGF0dGVybicpO1xuICAgIGNvbnN0IGltYWdlID0gcGF0dGVyblByb3BlcnR5LmNvbnN0YW50T3IoKDE6IGFueSkpO1xuICAgIGNvbnN0IG9wYWNpdHkgPSBsYXllci5wYWludC5nZXQoJ2ZpbGwtZXh0cnVzaW9uLW9wYWNpdHknKTtcbiAgICBjb25zdCBhbyA9IFtsYXllci5wYWludC5nZXQoJ2ZpbGwtZXh0cnVzaW9uLWFtYmllbnQtb2NjbHVzaW9uLWludGVuc2l0eScpLCBsYXllci5wYWludC5nZXQoJ2ZpbGwtZXh0cnVzaW9uLWFtYmllbnQtb2NjbHVzaW9uLXJhZGl1cycpXTtcbiAgICBjb25zdCBlZGdlUmFkaXVzID0gbGF5ZXIubGF5b3V0LmdldCgnZmlsbC1leHRydXNpb24tZWRnZS1yYWRpdXMnKTtcbiAgICBjb25zdCB6ZXJvUm9vZlJhZGl1cyA9IGVkZ2VSYWRpdXMgPiAwICYmICFsYXllci5wYWludC5nZXQoJ2ZpbGwtZXh0cnVzaW9uLXJvdW5kZWQtcm9vZicpO1xuICAgIGNvbnN0IHJvb2ZFZGdlUmFkaXVzID0gemVyb1Jvb2ZSYWRpdXMgPyAwLjAgOiBlZGdlUmFkaXVzO1xuICAgIGNvbnN0IGhlaWdodExpZnQgPSB0ci5wcm9qZWN0aW9uLm5hbWUgPT09ICdnbG9iZScgPyBmaWxsRXh0cnVzaW9uSGVpZ2h0TGlmdCgpIDogMDtcbiAgICBjb25zdCBpc0dsb2JlUHJvamVjdGlvbiA9IHRyLnByb2plY3Rpb24ubmFtZSA9PT0gJ2dsb2JlJztcbiAgICBjb25zdCBnbG9iZVRvTWVyY2F0b3IgPSBpc0dsb2JlUHJvamVjdGlvbiA/IGdsb2JlVG9NZXJjYXRvclRyYW5zaXRpb24odHIuem9vbSkgOiAwLjA7XG4gICAgY29uc3QgbWVyY2F0b3JDZW50ZXIgPSBbbWVyY2F0b3JYZnJvbUxuZyh0ci5jZW50ZXIubG5nKSwgbWVyY2F0b3JZZnJvbUxhdCh0ci5jZW50ZXIubGF0KV07XG4gICAgY29uc3QgYmFzZURlZmluZXMgPSAoW106IGFueSk7XG4gICAgaWYgKGlzR2xvYmVQcm9qZWN0aW9uKSB7XG4gICAgICAgIGJhc2VEZWZpbmVzLnB1c2goJ1BST0pFQ1RJT05fR0xPQkVfVklFVycpO1xuICAgIH1cbiAgICBpZiAoYW9bMF0gPiAwKSB7IC8vIGludGVuc2l0eVxuICAgICAgICBiYXNlRGVmaW5lcy5wdXNoKCdGQVVYX0FPJyk7XG4gICAgfVxuICAgIGlmICh6ZXJvUm9vZlJhZGl1cykge1xuICAgICAgICBiYXNlRGVmaW5lcy5wdXNoKCdaRVJPX1JPT0ZfUkFESVVTJyk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBjb29yZCBvZiBjb29yZHMpIHtcbiAgICAgICAgY29uc3QgdGlsZSA9IHNvdXJjZS5nZXRUaWxlKGNvb3JkKTtcbiAgICAgICAgY29uc3QgYnVja2V0OiA/RmlsbEV4dHJ1c2lvbkJ1Y2tldCA9ICh0aWxlLmdldEJ1Y2tldChsYXllcik6IGFueSk7XG4gICAgICAgIGlmICghYnVja2V0IHx8IGJ1Y2tldC5wcm9qZWN0aW9uLm5hbWUgIT09IHRyLnByb2plY3Rpb24ubmFtZSkgY29udGludWU7XG5cbiAgICAgICAgY29uc3QgcHJvZ3JhbUNvbmZpZ3VyYXRpb24gPSBidWNrZXQucHJvZ3JhbUNvbmZpZ3VyYXRpb25zLmdldChsYXllci5pZCk7XG4gICAgICAgIGNvbnN0IHByb2dyYW0gPSBwYWludGVyLnVzZVByb2dyYW0oaW1hZ2UgPyAnZmlsbEV4dHJ1c2lvblBhdHRlcm4nIDogJ2ZpbGxFeHRydXNpb24nLCBwcm9ncmFtQ29uZmlndXJhdGlvbiwgYmFzZURlZmluZXMpO1xuXG4gICAgICAgIGlmIChwYWludGVyLnRlcnJhaW4pIHtcbiAgICAgICAgICAgIGNvbnN0IHRlcnJhaW4gPSBwYWludGVyLnRlcnJhaW47XG4gICAgICAgICAgICBpZiAocGFpbnRlci5zdHlsZS50ZXJyYWluU2V0Rm9yRHJhcGluZ09ubHkoKSkge1xuICAgICAgICAgICAgICAgIHRlcnJhaW4uc2V0dXBFbGV2YXRpb25EcmF3KHRpbGUsIHByb2dyYW0sIHt1c2VNZXRlclRvRGVtOiB0cnVlfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICghYnVja2V0LmVuYWJsZVRlcnJhaW4pIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIHRlcnJhaW4uc2V0dXBFbGV2YXRpb25EcmF3KHRpbGUsIHByb2dyYW0sIHt1c2VNZXRlclRvRGVtOiB0cnVlfSk7XG4gICAgICAgICAgICAgICAgZmxhdFJvb2ZzVXBkYXRlKGNvbnRleHQsIHNvdXJjZSwgY29vcmQsIGJ1Y2tldCwgbGF5ZXIsIHRlcnJhaW4pO1xuICAgICAgICAgICAgICAgIGlmICghYnVja2V0LmNlbnRyb2lkVmVydGV4QnVmZmVyKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGF0dHJJbmRleDogbnVtYmVyIHwgdm9pZCA9IHByb2dyYW0uYXR0cmlidXRlc1snYV9jZW50cm9pZF9wb3MnXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGF0dHJJbmRleCAhPT0gdW5kZWZpbmVkKSBnbC52ZXJ0ZXhBdHRyaWIyZihhdHRySW5kZXgsIDAsIDApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpbWFnZSkge1xuICAgICAgICAgICAgcGFpbnRlci5jb250ZXh0LmFjdGl2ZVRleHR1cmUuc2V0KGdsLlRFWFRVUkUwKTtcbiAgICAgICAgICAgIHRpbGUuaW1hZ2VBdGxhc1RleHR1cmUuYmluZChnbC5MSU5FQVIsIGdsLkNMQU1QX1RPX0VER0UpO1xuICAgICAgICAgICAgcHJvZ3JhbUNvbmZpZ3VyYXRpb24udXBkYXRlUGFpbnRCdWZmZXJzKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY29uc3RhbnRQYXR0ZXJuID0gcGF0dGVyblByb3BlcnR5LmNvbnN0YW50T3IobnVsbCk7XG4gICAgICAgIGlmIChjb25zdGFudFBhdHRlcm4gJiYgdGlsZS5pbWFnZUF0bGFzKSB7XG4gICAgICAgICAgICBjb25zdCBhdGxhcyA9IHRpbGUuaW1hZ2VBdGxhcztcbiAgICAgICAgICAgIGNvbnN0IHBvc1RvID0gYXRsYXMucGF0dGVyblBvc2l0aW9uc1tjb25zdGFudFBhdHRlcm4udG9TdHJpbmcoKV07XG4gICAgICAgICAgICBpZiAocG9zVG8pIHByb2dyYW1Db25maWd1cmF0aW9uLnNldENvbnN0YW50UGF0dGVyblBvc2l0aW9ucyhwb3NUbyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBtYXRyaXggPSBwYWludGVyLnRyYW5zbGF0ZVBvc01hdHJpeChcbiAgICAgICAgICAgIGNvb3JkLnByb2pNYXRyaXgsXG4gICAgICAgICAgICB0aWxlLFxuICAgICAgICAgICAgbGF5ZXIucGFpbnQuZ2V0KCdmaWxsLWV4dHJ1c2lvbi10cmFuc2xhdGUnKSxcbiAgICAgICAgICAgIGxheWVyLnBhaW50LmdldCgnZmlsbC1leHRydXNpb24tdHJhbnNsYXRlLWFuY2hvcicpKTtcblxuICAgICAgICBjb25zdCBpbnZNYXRyaXggPSB0ci5wcm9qZWN0aW9uLmNyZWF0ZUludmVyc2lvbk1hdHJpeCh0ciwgY29vcmQuY2Fub25pY2FsKTtcblxuICAgICAgICBjb25zdCBzaG91bGRVc2VWZXJ0aWNhbEdyYWRpZW50ID0gbGF5ZXIucGFpbnQuZ2V0KCdmaWxsLWV4dHJ1c2lvbi12ZXJ0aWNhbC1ncmFkaWVudCcpO1xuICAgICAgICBjb25zdCB1bmlmb3JtVmFsdWVzID0gaW1hZ2UgP1xuICAgICAgICAgICAgZmlsbEV4dHJ1c2lvblBhdHRlcm5Vbmlmb3JtVmFsdWVzKG1hdHJpeCwgcGFpbnRlciwgc2hvdWxkVXNlVmVydGljYWxHcmFkaWVudCwgb3BhY2l0eSwgYW8sIHJvb2ZFZGdlUmFkaXVzLCBjb29yZCxcbiAgICAgICAgICAgICAgICB0aWxlLCBoZWlnaHRMaWZ0LCBnbG9iZVRvTWVyY2F0b3IsIG1lcmNhdG9yQ2VudGVyLCBpbnZNYXRyaXgpIDpcbiAgICAgICAgICAgIGZpbGxFeHRydXNpb25Vbmlmb3JtVmFsdWVzKG1hdHJpeCwgcGFpbnRlciwgc2hvdWxkVXNlVmVydGljYWxHcmFkaWVudCwgb3BhY2l0eSwgYW8sIHJvb2ZFZGdlUmFkaXVzLCBjb29yZCxcbiAgICAgICAgICAgICAgICBoZWlnaHRMaWZ0LCBnbG9iZVRvTWVyY2F0b3IsIG1lcmNhdG9yQ2VudGVyLCBpbnZNYXRyaXgpO1xuXG4gICAgICAgIHBhaW50ZXIucHJlcGFyZURyYXdQcm9ncmFtKGNvbnRleHQsIHByb2dyYW0sIGNvb3JkLnRvVW53cmFwcGVkKCkpO1xuXG4gICAgICAgIGFzc2VydCghaXNHbG9iZVByb2plY3Rpb24gfHwgYnVja2V0LmxheW91dFZlcnRleEV4dEJ1ZmZlcik7XG5cbiAgICAgICAgY29uc3QgZHluYW1pY0J1ZmZlcnMgPSBbXTtcbiAgICAgICAgaWYgKHBhaW50ZXIudGVycmFpbikgZHluYW1pY0J1ZmZlcnMucHVzaChidWNrZXQuY2VudHJvaWRWZXJ0ZXhCdWZmZXIpO1xuICAgICAgICBpZiAoaXNHbG9iZVByb2plY3Rpb24pIGR5bmFtaWNCdWZmZXJzLnB1c2goYnVja2V0LmxheW91dFZlcnRleEV4dEJ1ZmZlcik7XG5cbiAgICAgICAgcHJvZ3JhbS5kcmF3KGNvbnRleHQsIGNvbnRleHQuZ2wuVFJJQU5HTEVTLCBkZXB0aE1vZGUsIHN0ZW5jaWxNb2RlLCBjb2xvck1vZGUsIEN1bGxGYWNlTW9kZS5iYWNrQ0NXLFxuICAgICAgICAgICAgdW5pZm9ybVZhbHVlcywgbGF5ZXIuaWQsIGJ1Y2tldC5sYXlvdXRWZXJ0ZXhCdWZmZXIsIGJ1Y2tldC5pbmRleEJ1ZmZlcixcbiAgICAgICAgICAgIGJ1Y2tldC5zZWdtZW50cywgbGF5ZXIucGFpbnQsIHBhaW50ZXIudHJhbnNmb3JtLnpvb20sXG4gICAgICAgICAgICBwcm9ncmFtQ29uZmlndXJhdGlvbiwgZHluYW1pY0J1ZmZlcnMpO1xuICAgIH1cbn1cblxuLy8gRmxhdCByb29mcyBhcnJheSBpcyBwcmVwYXJlZCBpbiB0aGUgYnVja2V0LCBleGNlcHQgZm9yIGJ1aWxkaW5ncyB0aGF0IGFyZSBvbiB0aWxlIGJvcmRlcnMuXG4vLyBGb3IgdGhlbSwgam9pbiBwaWVjZXMsIGNhbGN1bGF0ZSBqb2luZWQgc2l6ZSBoZXJlLCBhbmQgdGhlbiB1cGxvYWQgZGF0YS5cbmZ1bmN0aW9uIGZsYXRSb29mc1VwZGF0ZShjb250ZXh0OiBDb250ZXh0LCBzb3VyY2U6IFNvdXJjZUNhY2hlLCBjb29yZDogT3ZlcnNjYWxlZFRpbGVJRCwgYnVja2V0OiBGaWxsRXh0cnVzaW9uQnVja2V0LCBsYXllcjogRmlsbEV4dHJ1c2lvblN0eWxlTGF5ZXIsIHRlcnJhaW46IFRlcnJhaW4pIHtcbiAgICAvLyBGb3IgYWxsIGZvdXIgYm9yZGVyczogMCAtIGxlZnQsIDEsIHJpZ2h0LCAyIC0gdG9wLCAzIC0gYm90dG9tXG4gICAgY29uc3QgbmVpZ2hib3JDb29yZCA9IFtcbiAgICAgICAgKGNvb3JkOiBPdmVyc2NhbGVkVGlsZUlEKSA9PiB7XG4gICAgICAgICAgICBsZXQgeCA9IGNvb3JkLmNhbm9uaWNhbC54IC0gMTtcbiAgICAgICAgICAgIGxldCB3ID0gY29vcmQud3JhcDtcbiAgICAgICAgICAgIGlmICh4IDwgMCkge1xuICAgICAgICAgICAgICAgIHggPSAoMSA8PCBjb29yZC5jYW5vbmljYWwueikgLSAxO1xuICAgICAgICAgICAgICAgIHctLTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBuZXcgT3ZlcnNjYWxlZFRpbGVJRChjb29yZC5vdmVyc2NhbGVkWiwgdywgY29vcmQuY2Fub25pY2FsLnosIHgsIGNvb3JkLmNhbm9uaWNhbC55KTtcbiAgICAgICAgfSxcbiAgICAgICAgKGNvb3JkOiBPdmVyc2NhbGVkVGlsZUlEKSA9PiB7XG4gICAgICAgICAgICBsZXQgeCA9IGNvb3JkLmNhbm9uaWNhbC54ICsgMTtcbiAgICAgICAgICAgIGxldCB3ID0gY29vcmQud3JhcDtcbiAgICAgICAgICAgIGlmICh4ID09PSAxIDw8IGNvb3JkLmNhbm9uaWNhbC56KSB7XG4gICAgICAgICAgICAgICAgeCA9IDA7XG4gICAgICAgICAgICAgICAgdysrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBPdmVyc2NhbGVkVGlsZUlEKGNvb3JkLm92ZXJzY2FsZWRaLCB3LCBjb29yZC5jYW5vbmljYWwueiwgeCwgY29vcmQuY2Fub25pY2FsLnkpO1xuICAgICAgICB9LFxuICAgICAgICAoY29vcmQ6IE92ZXJzY2FsZWRUaWxlSUQpID0+IG5ldyBPdmVyc2NhbGVkVGlsZUlEKGNvb3JkLm92ZXJzY2FsZWRaLCBjb29yZC53cmFwLCBjb29yZC5jYW5vbmljYWwueiwgY29vcmQuY2Fub25pY2FsLngsXG4gICAgICAgICAgICAoY29vcmQuY2Fub25pY2FsLnkgPT09IDAgPyAxIDw8IGNvb3JkLmNhbm9uaWNhbC56IDogY29vcmQuY2Fub25pY2FsLnkpIC0gMSksXG4gICAgICAgIChjb29yZDogT3ZlcnNjYWxlZFRpbGVJRCkgPT4gbmV3IE92ZXJzY2FsZWRUaWxlSUQoY29vcmQub3ZlcnNjYWxlZFosIGNvb3JkLndyYXAsIGNvb3JkLmNhbm9uaWNhbC56LCBjb29yZC5jYW5vbmljYWwueCxcbiAgICAgICAgICAgIGNvb3JkLmNhbm9uaWNhbC55ID09PSAoMSA8PCBjb29yZC5jYW5vbmljYWwueikgLSAxID8gMCA6IGNvb3JkLmNhbm9uaWNhbC55ICsgMSlcbiAgICBdO1xuXG4gICAgY29uc3QgZ2V0TG9hZGVkQnVja2V0ID0gKG5pZDogT3ZlcnNjYWxlZFRpbGVJRCkgPT4ge1xuICAgICAgICBjb25zdCBtaW56b29tID0gc291cmNlLmdldFNvdXJjZSgpLm1pbnpvb207XG4gICAgICAgIGNvbnN0IGdldEJ1Y2tldCA9IChrZXk6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgY29uc3QgbiA9IHNvdXJjZS5nZXRUaWxlQnlJRChrZXkpO1xuICAgICAgICAgICAgaWYgKG4gJiYgbi5oYXNEYXRhKCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbi5nZXRCdWNrZXQobGF5ZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICAvLyBMb29rIG9uZSB0aWxlIHpvb20gYWJvdmUgYW5kIHVuZGVyLiBXZSBkbyB0aGlzIHRvIGF2b2lkIGZsaWNrZXJpbmcgYW5kXG4gICAgICAgIC8vIHVzZSB0aGUgY29udGVudCBpbiBaLTEgYW5kIForMSBidWNrZXRzIHVudGlsIFogYnVja2V0IGlzIGxvYWRlZCBvciBoYW5kbGVcbiAgICAgICAgLy8gYmVoYXZpb3Igb24gYm9yZGVycyBiZXR3ZWVuIGRpZmZlcmVudCB6b29tcy5cbiAgICAgICAgY29uc3Qgem9vbUxldmVscyA9IFswLCAtMSwgMV07XG4gICAgICAgIGZvciAoY29uc3QgaSBvZiB6b29tTGV2ZWxzKSB7XG4gICAgICAgICAgICBjb25zdCB6ID0gbmlkLm92ZXJzY2FsZWRaICsgaTtcbiAgICAgICAgICAgIGlmICh6IDwgbWluem9vbSkgY29udGludWU7XG4gICAgICAgICAgICBjb25zdCBrZXkgPSBuaWQuY2FsY3VsYXRlU2NhbGVkS2V5KG5pZC5vdmVyc2NhbGVkWiArIGkpO1xuICAgICAgICAgICAgY29uc3QgYiA9IGdldEJ1Y2tldChrZXkpO1xuICAgICAgICAgICAgaWYgKGIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBjb25zdCBwcm9qZWN0ZWRUb0JvcmRlciA9IFswLCAwLCAwXTsgLy8gW21pbiwgbWF4LCBtYXhPZmZzZXRGcm9tQm9yZGVyXVxuICAgIGNvbnN0IHhqb2luID0gKGE6IFBhcnRNZXRhZGF0YSwgYjogUGFydE1ldGFkYXRhKSA9PiB7XG4gICAgICAgIHByb2plY3RlZFRvQm9yZGVyWzBdID0gTWF0aC5taW4oYS5taW4ueSwgYi5taW4ueSk7XG4gICAgICAgIHByb2plY3RlZFRvQm9yZGVyWzFdID0gTWF0aC5tYXgoYS5tYXgueSwgYi5tYXgueSk7XG4gICAgICAgIHByb2plY3RlZFRvQm9yZGVyWzJdID0gRVhURU5UIC0gYi5taW4ueCA+IGEubWF4LnggPyBiLm1pbi54IC0gRVhURU5UIDogYS5tYXgueDtcbiAgICAgICAgcmV0dXJuIHByb2plY3RlZFRvQm9yZGVyO1xuICAgIH07XG4gICAgY29uc3QgeWpvaW4gPSAoYTogUGFydE1ldGFkYXRhLCBiOiBQYXJ0TWV0YWRhdGEpID0+IHtcbiAgICAgICAgcHJvamVjdGVkVG9Cb3JkZXJbMF0gPSBNYXRoLm1pbihhLm1pbi54LCBiLm1pbi54KTtcbiAgICAgICAgcHJvamVjdGVkVG9Cb3JkZXJbMV0gPSBNYXRoLm1heChhLm1heC54LCBiLm1heC54KTtcbiAgICAgICAgcHJvamVjdGVkVG9Cb3JkZXJbMl0gPSBFWFRFTlQgLSBiLm1pbi55ID4gYS5tYXgueSA/IGIubWluLnkgLSBFWFRFTlQgOiBhLm1heC55O1xuICAgICAgICByZXR1cm4gcHJvamVjdGVkVG9Cb3JkZXI7XG4gICAgfTtcbiAgICBjb25zdCBwcm9qZWN0Q29tYmluZWRTcGFuVG9Cb3JkZXIgPSBbXG4gICAgICAgIChhOiBQYXJ0TWV0YWRhdGEsIGI6IFBhcnRNZXRhZGF0YSkgPT4geGpvaW4oYSwgYiksXG4gICAgICAgIChhOiBQYXJ0TWV0YWRhdGEsIGI6IFBhcnRNZXRhZGF0YSkgPT4geGpvaW4oYiwgYSksXG4gICAgICAgIChhOiBQYXJ0TWV0YWRhdGEsIGI6IFBhcnRNZXRhZGF0YSkgPT4geWpvaW4oYSwgYiksXG4gICAgICAgIChhOiBQYXJ0TWV0YWRhdGEsIGI6IFBhcnRNZXRhZGF0YSkgPT4geWpvaW4oYiwgYSlcbiAgICBdO1xuXG4gICAgY29uc3QgY2VudHJvaWQgPSBuZXcgUG9pbnQoMCwgMCk7XG4gICAgY29uc3QgZXJyb3IgPSAzOyAvLyBBbGxvdyBpbnRydXNpb24gb2YgYSBidWlsZGluZyB0byB0aGUgYnVpbGRpbmcgd2l0aCBhZGphY2VudCB3YWxsLlxuXG4gICAgbGV0IGRlbVRpbGUsIG5laWdoYm9yREVNVGlsZSwgbmVpZ2hib3JUaWxlSUQ7XG5cbiAgICBjb25zdCBmbGF0QmFzZSA9IChtaW46IG51bWJlciwgbWF4OiBudW1iZXIsIGVkZ2U6IG51bWJlciwgdmVydGljYWxFZGdlOiBib29sZWFuLCBtYXhPZmZzZXRGcm9tQm9yZGVyOiBudW1iZXIpID0+IHtcbiAgICAgICAgY29uc3QgcG9pbnRzID0gW1t2ZXJ0aWNhbEVkZ2UgPyBlZGdlIDogbWluLCB2ZXJ0aWNhbEVkZ2UgPyBtaW4gOiBlZGdlLCAwXSwgW3ZlcnRpY2FsRWRnZSA/IGVkZ2UgOiBtYXgsIHZlcnRpY2FsRWRnZSA/IG1heCA6IGVkZ2UsIDBdXTtcblxuICAgICAgICBjb25zdCBjb29yZDMgPSBtYXhPZmZzZXRGcm9tQm9yZGVyIDwgMCA/IEVYVEVOVCArIG1heE9mZnNldEZyb21Cb3JkZXIgOiBtYXhPZmZzZXRGcm9tQm9yZGVyO1xuICAgICAgICBjb25zdCB0aGlyZFBvaW50ID0gW3ZlcnRpY2FsRWRnZSA/IGNvb3JkMyA6IChtaW4gKyBtYXgpIC8gMiwgdmVydGljYWxFZGdlID8gKG1pbiArIG1heCkgLyAyIDogY29vcmQzLCAwXTtcbiAgICAgICAgaWYgKChlZGdlID09PSAwICYmIG1heE9mZnNldEZyb21Cb3JkZXIgPCAwKSB8fCAoZWRnZSAhPT0gMCAmJiBtYXhPZmZzZXRGcm9tQm9yZGVyID4gMCkpIHtcbiAgICAgICAgICAgIC8vIFRoaXJkIHBvaW50IGlzIGluc2lkZSBuZWlnaGJvciB0aWxlLCBub3QgaW4gdGhlIHxjb29yZHwgdGlsZS5cbiAgICAgICAgICAgIHRlcnJhaW4uZ2V0Rm9yVGlsZVBvaW50cyhuZWlnaGJvclRpbGVJRCwgW3RoaXJkUG9pbnRdLCB0cnVlLCBuZWlnaGJvckRFTVRpbGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcG9pbnRzLnB1c2godGhpcmRQb2ludCk7XG4gICAgICAgIH1cbiAgICAgICAgdGVycmFpbi5nZXRGb3JUaWxlUG9pbnRzKGNvb3JkLCBwb2ludHMsIHRydWUsIGRlbVRpbGUpO1xuICAgICAgICByZXR1cm4gTWF0aC5tYXgocG9pbnRzWzBdWzJdLCBwb2ludHNbMV1bMl0sIHRoaXJkUG9pbnRbMl0pIC8gdGVycmFpbi5leGFnZ2VyYXRpb24oKTtcbiAgICB9O1xuXG4gICAgLy8gUHJvY2VzcyBhbGwgZm91ciBib3JkZXJzOiBnZXQgbmVpZ2hib3JpbmcgdGlsZVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgICAgIC8vIGJvcmRlcnMgLyBib3JkZXJEb25lV2l0aE5laWdoYm9yWjogMCAtIGxlZnQsIDEsIHJpZ2h0LCAyIC0gdG9wLCAzIC0gYm90dG9tXG4gICAgICAgIC8vIGJ1Y2tldCdzIGJvcmRlciBpIGlzIG5laWdoYm9yaW5nIGJ1Y2tldCdzIGJvcmRlciBqOlxuICAgICAgICBjb25zdCBqID0gKGkgPCAyID8gMSA6IDUpIC0gaTtcbiAgICAgICAgLy8gU29ydCBieSBib3JkZXIgaW50ZXJzZWN0aW9uIGFyZWEgbWluaW11bXMsIGFzY2VuZGluZy5cbiAgICAgICAgY29uc3QgYSA9IGJ1Y2tldC5ib3JkZXJzW2ldO1xuICAgICAgICBpZiAoYS5sZW5ndGggPT09IDApIGNvbnRpbnVlO1xuICAgICAgICBjb25zdCBuaWQgPSBuZWlnaGJvclRpbGVJRCA9IG5laWdoYm9yQ29vcmRbaV0oY29vcmQpO1xuICAgICAgICBjb25zdCBuQnVja2V0ID0gZ2V0TG9hZGVkQnVja2V0KG5pZCk7XG4gICAgICAgIGlmICghbkJ1Y2tldCB8fCAhKG5CdWNrZXQgaW5zdGFuY2VvZiBGaWxsRXh0cnVzaW9uQnVja2V0KSB8fCAhbkJ1Y2tldC5lbmFibGVUZXJyYWluKSBjb250aW51ZTtcbiAgICAgICAgaWYgKGJ1Y2tldC5ib3JkZXJEb25lV2l0aE5laWdoYm9yWltpXSA9PT0gbkJ1Y2tldC5jYW5vbmljYWwueiAmJlxuICAgICAgICAgICAgbkJ1Y2tldC5ib3JkZXJEb25lV2l0aE5laWdoYm9yWltqXSA9PT0gYnVja2V0LmNhbm9uaWNhbC56KSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIG5laWdoYm9yREVNVGlsZSA9IHRlcnJhaW4uZmluZERFTVRpbGVGb3IobmlkKTtcbiAgICAgICAgaWYgKCFuZWlnaGJvckRFTVRpbGUgfHwgIW5laWdoYm9yREVNVGlsZS5kZW0pIGNvbnRpbnVlO1xuICAgICAgICBpZiAoIWRlbVRpbGUpIHtcbiAgICAgICAgICAgIGNvbnN0IGRlbSA9IHRlcnJhaW4uZmluZERFTVRpbGVGb3IoY29vcmQpO1xuICAgICAgICAgICAgaWYgKCEoZGVtICYmIGRlbS5kZW0pKSByZXR1cm47IC8vIGRlZmVyIHVwZGF0ZSB1bnRpbCBhbiBlbGV2YXRpb24gdGlsZSBpcyBhdmFpbGFibGUuXG4gICAgICAgICAgICBkZW1UaWxlID0gZGVtO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGIgPSBuQnVja2V0LmJvcmRlcnNbal07XG4gICAgICAgIGxldCBpYiA9IDA7XG5cbiAgICAgICAgY29uc3QgdXBkYXRlTmVpZ2hib3IgPSBuQnVja2V0LmJvcmRlckRvbmVXaXRoTmVpZ2hib3JaW2pdICE9PSBidWNrZXQuY2Fub25pY2FsLno7XG4gICAgICAgIC8vIElmIG5laWdoYm9ycyBhcmUgb2YgZGlmZmVyZW50IGNhbm9uaWNhbCB6LCB3ZSBjYW5ub3Qgam9pbiBwYXJ0cyBidXQgc2hvd1xuICAgICAgICAvLyBhbGwgd2l0aG91dCBmbGF0IHJvb2ZzLlxuICAgICAgICBpZiAoYnVja2V0LmNhbm9uaWNhbC56ICE9PSBuQnVja2V0LmNhbm9uaWNhbC56KSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGluZGV4IG9mIGEpIHtcbiAgICAgICAgICAgICAgICBidWNrZXQuZW5jb2RlQ2VudHJvaWQodW5kZWZpbmVkLCBidWNrZXQuZmVhdHVyZXNPbkJvcmRlcltpbmRleF0sIGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh1cGRhdGVOZWlnaGJvcikge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgaW5kZXggb2YgYikge1xuICAgICAgICAgICAgICAgICAgICBuQnVja2V0LmVuY29kZUNlbnRyb2lkKHVuZGVmaW5lZCwgbkJ1Y2tldC5mZWF0dXJlc09uQm9yZGVyW2luZGV4XSwgZmFsc2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBuQnVja2V0LmJvcmRlckRvbmVXaXRoTmVpZ2hib3JaW2pdID0gYnVja2V0LmNhbm9uaWNhbC56O1xuICAgICAgICAgICAgICAgIG5CdWNrZXQubmVlZHNDZW50cm9pZFVwZGF0ZSA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBidWNrZXQuYm9yZGVyRG9uZVdpdGhOZWlnaGJvclpbaV0gPSBuQnVja2V0LmNhbm9uaWNhbC56O1xuICAgICAgICAgICAgYnVja2V0Lm5lZWRzQ2VudHJvaWRVcGRhdGUgPSB0cnVlO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGxldCBpYSA9IDA7IGlhIDwgYS5sZW5ndGg7IGlhKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcnRhID0gYnVja2V0LmZlYXR1cmVzT25Cb3JkZXJbYVtpYV1dO1xuICAgICAgICAgICAgY29uc3QgcGFydEFCb3JkZXJSYW5nZSA9IHBhcnRhLmJvcmRlcnNbaV07XG4gICAgICAgICAgICAvLyBGaW5kIGFsbCBuQnVja2V0IHBhcnRzIHRoYXQgc2hhcmUgdGhlIGJvcmRlciBvdmVybGFwLlxuICAgICAgICAgICAgbGV0IHBhcnRiO1xuICAgICAgICAgICAgd2hpbGUgKGliIDwgYi5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAvLyBQYXNzIGFsbCB0aGF0IGFyZSBiZWZvcmUgdGhlIG92ZXJsYXAuXG4gICAgICAgICAgICAgICAgcGFydGIgPSBuQnVja2V0LmZlYXR1cmVzT25Cb3JkZXJbYltpYl1dO1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnRCQm9yZGVyUmFuZ2UgPSBwYXJ0Yi5ib3JkZXJzW2pdO1xuICAgICAgICAgICAgICAgIGlmIChwYXJ0QkJvcmRlclJhbmdlWzFdID4gcGFydEFCb3JkZXJSYW5nZVswXSArIGVycm9yKSBicmVhaztcbiAgICAgICAgICAgICAgICBpZiAodXBkYXRlTmVpZ2hib3IpIG5CdWNrZXQuZW5jb2RlQ2VudHJvaWQodW5kZWZpbmVkLCBwYXJ0YiwgZmFsc2UpO1xuICAgICAgICAgICAgICAgIGliKys7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocGFydGIgJiYgaWIgPCBiLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHNhdmVJYiA9IGliO1xuICAgICAgICAgICAgICAgIGxldCBjb3VudCA9IDA7XG4gICAgICAgICAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQ29sbGVjdCBhbGwgcGFydHMgb3ZlcmxhcHBpbmcgcGFydGEgb24gdGhlIGVkZ2UsIHRvIG1ha2Ugc3VyZSBpdCBpcyBvbmx5IG9uZS5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFydEJCb3JkZXJSYW5nZSA9IHBhcnRiLmJvcmRlcnNbal07XG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXJ0QkJvcmRlclJhbmdlWzBdID4gcGFydEFCb3JkZXJSYW5nZVsxXSAtIGVycm9yKSBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY291bnQrKztcbiAgICAgICAgICAgICAgICAgICAgaWYgKCsraWIgPT09IGIubGVuZ3RoKSBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgcGFydGIgPSBuQnVja2V0LmZlYXR1cmVzT25Cb3JkZXJbYltpYl1dO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwYXJ0YiA9IG5CdWNrZXQuZmVhdHVyZXNPbkJvcmRlcltiW3NhdmVJYl1dO1xuXG4gICAgICAgICAgICAgICAgLy8gSWYgYW55IG9mIGEgb3IgYiBjcm9zc2VzIG1vcmUgdGhhbiBvbmUgdGlsZSBlZGdlLCBkb24ndCBzdXBwb3J0IGZsYXQgcm9vZi5cbiAgICAgICAgICAgICAgICBpZiAocGFydGEuaW50ZXJzZWN0c0NvdW50KCkgPiAxIHx8IHBhcnRiLmludGVyc2VjdHNDb3VudCgpID4gMSB8fCBjb3VudCAhPT0gMSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY291bnQgIT09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGliID0gc2F2ZUliOyAvLyByZXdpbmQgdW5wcm9jZXNzZWQgaWIgc28gdGhhdCBpdCBpcyBwcm9jZXNzZWQgYWdhaW4gZm9yIHRoZSBuZXh0IGlhLlxuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgYnVja2V0LmVuY29kZUNlbnRyb2lkKHVuZGVmaW5lZCwgcGFydGEsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHVwZGF0ZU5laWdoYm9yKSBuQnVja2V0LmVuY29kZUNlbnRyb2lkKHVuZGVmaW5lZCwgcGFydGIsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gTm93IHdlIGhhdmUgMS0xIG1hdGNoaW5nIG9mIHBhcnRzIGluIGJvdGggdGlsZXMgdGhhdCBzaGFyZSB0aGUgZWRnZS4gQ2FsY3VsYXRlIGZsYXQgYmFzZSBlbGV2YXRpb25cbiAgICAgICAgICAgICAgICAvLyBhcyBhdmVyYWdlIG9mIHRocmVlIHBvaW50czogMiBhcmUgZWRnZSBwb2ludHMgKGNvbWJpbmVkIHNwYW4gcHJvamVjdGVkIHRvIGJvcmRlcikgYW5kIG9uZSBpcyBwb2ludCBvZlxuICAgICAgICAgICAgICAgIC8vIHNwYW4gdGhhdCBoYXMgbWF4aW11bSBvZmZzZXQgdG8gYm9yZGVyLlxuICAgICAgICAgICAgICAgIGNvbnN0IHNwYW4gPSBwcm9qZWN0Q29tYmluZWRTcGFuVG9Cb3JkZXJbaV0ocGFydGEsIHBhcnRiKTtcbiAgICAgICAgICAgICAgICBjb25zdCBlZGdlID0gKGkgJSAyKSA/IEVYVEVOVCAtIDEgOiAwO1xuICAgICAgICAgICAgICAgIGNlbnRyb2lkLnggPSBmbGF0QmFzZShzcGFuWzBdLCBNYXRoLm1pbihFWFRFTlQgLSAxLCBzcGFuWzFdKSwgZWRnZSwgaSA8IDIsIHNwYW5bMl0pO1xuICAgICAgICAgICAgICAgIGNlbnRyb2lkLnkgPSAwO1xuICAgICAgICAgICAgICAgIGFzc2VydChwYXJ0YS52ZXJ0ZXhBcnJheU9mZnNldCAhPT0gdW5kZWZpbmVkICYmIHBhcnRhLnZlcnRleEFycmF5T2Zmc2V0IDwgYnVja2V0LmxheW91dFZlcnRleEFycmF5Lmxlbmd0aCk7XG4gICAgICAgICAgICAgICAgYnVja2V0LmVuY29kZUNlbnRyb2lkKGNlbnRyb2lkLCBwYXJ0YSwgZmFsc2UpO1xuXG4gICAgICAgICAgICAgICAgYXNzZXJ0KHBhcnRiLnZlcnRleEFycmF5T2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgcGFydGIudmVydGV4QXJyYXlPZmZzZXQgPCBuQnVja2V0LmxheW91dFZlcnRleEFycmF5Lmxlbmd0aCk7XG4gICAgICAgICAgICAgICAgaWYgKHVwZGF0ZU5laWdoYm9yKSBuQnVja2V0LmVuY29kZUNlbnRyb2lkKGNlbnRyb2lkLCBwYXJ0YiwgZmFsc2UpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBhc3NlcnQocGFydGEuaW50ZXJzZWN0c0NvdW50KCkgPiAxIHx8IChwYXJ0YiAmJiBwYXJ0Yi5pbnRlcnNlY3RzQ291bnQoKSA+IDEpKTsgLy8gZXhwZWN0ZWQgYXQgdGhlIGVuZCBvZiBib3JkZXIsIHdoZW4gYnVpbGRpbmdzIGNvdmVyIGNvcm5lciAoc2hvdyBidWlsZGluZyB3L28gZmxhdCByb29mKS5cbiAgICAgICAgICAgICAgICBidWNrZXQuZW5jb2RlQ2VudHJvaWQodW5kZWZpbmVkLCBwYXJ0YSwgZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgYnVja2V0LmJvcmRlckRvbmVXaXRoTmVpZ2hib3JaW2ldID0gbkJ1Y2tldC5jYW5vbmljYWwuejtcbiAgICAgICAgYnVja2V0Lm5lZWRzQ2VudHJvaWRVcGRhdGUgPSB0cnVlO1xuICAgICAgICBpZiAodXBkYXRlTmVpZ2hib3IpIHtcbiAgICAgICAgICAgIG5CdWNrZXQuYm9yZGVyRG9uZVdpdGhOZWlnaGJvclpbal0gPSBidWNrZXQuY2Fub25pY2FsLno7XG4gICAgICAgICAgICBuQnVja2V0Lm5lZWRzQ2VudHJvaWRVcGRhdGUgPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGJ1Y2tldC5uZWVkc0NlbnRyb2lkVXBkYXRlIHx8ICghYnVja2V0LmNlbnRyb2lkVmVydGV4QnVmZmVyICYmIGJ1Y2tldC5jZW50cm9pZFZlcnRleEFycmF5Lmxlbmd0aCAhPT0gMCkpIHtcbiAgICAgICAgYnVja2V0LnVwbG9hZENlbnRyb2lkKGNvbnRleHQpO1xuICAgIH1cbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBJbWFnZVNvdXJjZSBmcm9tICcuLi9zb3VyY2UvaW1hZ2Vfc291cmNlLmpzJztcbmltcG9ydCBTdGVuY2lsTW9kZSBmcm9tICcuLi9nbC9zdGVuY2lsX21vZGUuanMnO1xuaW1wb3J0IERlcHRoTW9kZSBmcm9tICcuLi9nbC9kZXB0aF9tb2RlLmpzJztcbmltcG9ydCBDdWxsRmFjZU1vZGUgZnJvbSAnLi4vZ2wvY3VsbF9mYWNlX21vZGUuanMnO1xuaW1wb3J0IHtyYXN0ZXJVbmlmb3JtVmFsdWVzfSBmcm9tICcuL3Byb2dyYW0vcmFzdGVyX3Byb2dyYW0uanMnO1xuXG5pbXBvcnQgdHlwZSBQYWludGVyIGZyb20gJy4vcGFpbnRlci5qcyc7XG5pbXBvcnQgdHlwZSBTb3VyY2VDYWNoZSBmcm9tICcuLi9zb3VyY2Uvc291cmNlX2NhY2hlLmpzJztcbmltcG9ydCB0eXBlIFJhc3RlclN0eWxlTGF5ZXIgZnJvbSAnLi4vc3R5bGUvc3R5bGVfbGF5ZXIvcmFzdGVyX3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCB0eXBlIHtPdmVyc2NhbGVkVGlsZUlEfSBmcm9tICcuLi9zb3VyY2UvdGlsZV9pZC5qcyc7XG5pbXBvcnQgcmFzdGVyRmFkZSBmcm9tICcuL3Jhc3Rlcl9mYWRlLmpzJztcblxuZXhwb3J0IGRlZmF1bHQgZHJhd1Jhc3RlcjtcblxuZnVuY3Rpb24gZHJhd1Jhc3RlcihwYWludGVyOiBQYWludGVyLCBzb3VyY2VDYWNoZTogU291cmNlQ2FjaGUsIGxheWVyOiBSYXN0ZXJTdHlsZUxheWVyLCB0aWxlSURzOiBBcnJheTxPdmVyc2NhbGVkVGlsZUlEPiwgdmFyaWFibGVPZmZzZXRzOiBhbnksIGlzSW5pdGlhbExvYWQ6IGJvb2xlYW4pIHtcbiAgICBpZiAocGFpbnRlci5yZW5kZXJQYXNzICE9PSAndHJhbnNsdWNlbnQnKSByZXR1cm47XG4gICAgaWYgKGxheWVyLnBhaW50LmdldCgncmFzdGVyLW9wYWNpdHknKSA9PT0gMCkgcmV0dXJuO1xuICAgIGlmICghdGlsZUlEcy5sZW5ndGgpIHJldHVybjtcblxuICAgIGNvbnN0IGNvbnRleHQgPSBwYWludGVyLmNvbnRleHQ7XG4gICAgY29uc3QgZ2wgPSBjb250ZXh0LmdsO1xuICAgIGNvbnN0IHNvdXJjZSA9IHNvdXJjZUNhY2hlLmdldFNvdXJjZSgpO1xuICAgIGNvbnN0IHByb2dyYW0gPSBwYWludGVyLnVzZVByb2dyYW0oJ3Jhc3RlcicpO1xuXG4gICAgY29uc3QgY29sb3JNb2RlID0gcGFpbnRlci5jb2xvck1vZGVGb3JSZW5kZXJQYXNzKCk7XG5cbiAgICAvLyBXaGVuIHJlbmRlcmluZyB0byB0ZXh0dXJlLCBjb29yZGluYXRlcyBhcmUgYWxyZWFkeSBzb3J0ZWQ6IHByaW1hcnkgYnlcbiAgICAvLyBwcm94eSBpZCBhbmQgc2Vjb25kYXJ5IHNvcnQgaXMgYnkgWi5cbiAgICBjb25zdCByZW5kZXJpbmdUb1RleHR1cmUgPSBwYWludGVyLnRlcnJhaW4gJiYgcGFpbnRlci50ZXJyYWluLnJlbmRlcmluZ1RvVGV4dHVyZTtcblxuICAgIGNvbnN0IFtzdGVuY2lsTW9kZXMsIGNvb3Jkc10gPSBzb3VyY2UgaW5zdGFuY2VvZiBJbWFnZVNvdXJjZSB8fCByZW5kZXJpbmdUb1RleHR1cmUgPyBbe30sIHRpbGVJRHNdIDpcbiAgICAgICAgcGFpbnRlci5zdGVuY2lsQ29uZmlnRm9yT3ZlcmxhcCh0aWxlSURzKTtcblxuICAgIGNvbnN0IG1pblRpbGVaID0gY29vcmRzW2Nvb3Jkcy5sZW5ndGggLSAxXS5vdmVyc2NhbGVkWjtcblxuICAgIGNvbnN0IGFsaWduID0gIXBhaW50ZXIub3B0aW9ucy5tb3Zpbmc7XG4gICAgZm9yIChjb25zdCBjb29yZCBvZiBjb29yZHMpIHtcbiAgICAgICAgLy8gU2V0IHRoZSBsb3dlciB6b29tIGxldmVsIHRvIHN1YmxheWVyIDAsIGFuZCBoaWdoZXIgem9vbSBsZXZlbHMgdG8gaGlnaGVyIHN1YmxheWVyc1xuICAgICAgICAvLyBVc2UgZ2wuTEVTUyB0byBwcmV2ZW50IGRvdWJsZSBkcmF3aW5nIGluIGFyZWFzIHdoZXJlIHRpbGVzIG92ZXJsYXAuXG4gICAgICAgIGNvbnN0IGRlcHRoTW9kZSA9IHJlbmRlcmluZ1RvVGV4dHVyZSA/IERlcHRoTW9kZS5kaXNhYmxlZCA6IHBhaW50ZXIuZGVwdGhNb2RlRm9yU3VibGF5ZXIoY29vcmQub3ZlcnNjYWxlZFogLSBtaW5UaWxlWixcbiAgICAgICAgICAgIGxheWVyLnBhaW50LmdldCgncmFzdGVyLW9wYWNpdHknKSA9PT0gMSA/IERlcHRoTW9kZS5SZWFkV3JpdGUgOiBEZXB0aE1vZGUuUmVhZE9ubHksIGdsLkxFU1MpO1xuXG4gICAgICAgIGNvbnN0IHVud3JhcHBlZFRpbGVJRCA9IGNvb3JkLnRvVW53cmFwcGVkKCk7XG4gICAgICAgIGNvbnN0IHRpbGUgPSBzb3VyY2VDYWNoZS5nZXRUaWxlKGNvb3JkKTtcbiAgICAgICAgaWYgKHJlbmRlcmluZ1RvVGV4dHVyZSAmJiAhKHRpbGUgJiYgdGlsZS5oYXNEYXRhKCkpKSBjb250aW51ZTtcblxuICAgICAgICBjb25zdCBwcm9qTWF0cml4ID0gKHJlbmRlcmluZ1RvVGV4dHVyZSkgPyBjb29yZC5wcm9qTWF0cml4IDpcbiAgICAgICAgICAgIHBhaW50ZXIudHJhbnNmb3JtLmNhbGN1bGF0ZVByb2pNYXRyaXgodW53cmFwcGVkVGlsZUlELCBhbGlnbik7XG5cbiAgICAgICAgY29uc3Qgc3RlbmNpbE1vZGUgPSBwYWludGVyLnRlcnJhaW4gJiYgcmVuZGVyaW5nVG9UZXh0dXJlID9cbiAgICAgICAgICAgIHBhaW50ZXIudGVycmFpbi5zdGVuY2lsTW9kZUZvclJUVE92ZXJsYXAoY29vcmQpIDpcbiAgICAgICAgICAgIHN0ZW5jaWxNb2Rlc1tjb29yZC5vdmVyc2NhbGVkWl07XG5cbiAgICAgICAgY29uc3QgcmFzdGVyRmFkZUR1cmF0aW9uID0gaXNJbml0aWFsTG9hZCA/IDAgOiBsYXllci5wYWludC5nZXQoJ3Jhc3Rlci1mYWRlLWR1cmF0aW9uJyk7XG4gICAgICAgIHRpbGUucmVnaXN0ZXJGYWRlRHVyYXRpb24ocmFzdGVyRmFkZUR1cmF0aW9uKTtcblxuICAgICAgICBjb25zdCBwYXJlbnRUaWxlID0gc291cmNlQ2FjaGUuZmluZExvYWRlZFBhcmVudChjb29yZCwgMCk7XG4gICAgICAgIGNvbnN0IGZhZGUgPSByYXN0ZXJGYWRlKHRpbGUsIHBhcmVudFRpbGUsIHNvdXJjZUNhY2hlLCBwYWludGVyLnRyYW5zZm9ybSwgcmFzdGVyRmFkZUR1cmF0aW9uKTtcbiAgICAgICAgaWYgKHBhaW50ZXIudGVycmFpbikgcGFpbnRlci50ZXJyYWluLnByZXBhcmVEcmF3VGlsZSgpO1xuXG4gICAgICAgIGxldCBwYXJlbnRTY2FsZUJ5LCBwYXJlbnRUTDtcblxuICAgICAgICBjb25zdCB0ZXh0dXJlRmlsdGVyID0gbGF5ZXIucGFpbnQuZ2V0KCdyYXN0ZXItcmVzYW1wbGluZycpID09PSAnbmVhcmVzdCcgPyBnbC5ORUFSRVNUIDogZ2wuTElORUFSO1xuXG4gICAgICAgIGNvbnRleHQuYWN0aXZlVGV4dHVyZS5zZXQoZ2wuVEVYVFVSRTApO1xuICAgICAgICB0aWxlLnRleHR1cmUuYmluZCh0ZXh0dXJlRmlsdGVyLCBnbC5DTEFNUF9UT19FREdFKTtcblxuICAgICAgICBjb250ZXh0LmFjdGl2ZVRleHR1cmUuc2V0KGdsLlRFWFRVUkUxKTtcblxuICAgICAgICBpZiAocGFyZW50VGlsZSkge1xuICAgICAgICAgICAgcGFyZW50VGlsZS50ZXh0dXJlLmJpbmQodGV4dHVyZUZpbHRlciwgZ2wuQ0xBTVBfVE9fRURHRSk7XG4gICAgICAgICAgICBwYXJlbnRTY2FsZUJ5ID0gTWF0aC5wb3coMiwgcGFyZW50VGlsZS50aWxlSUQub3ZlcnNjYWxlZFogLSB0aWxlLnRpbGVJRC5vdmVyc2NhbGVkWik7XG4gICAgICAgICAgICBwYXJlbnRUTCA9IFt0aWxlLnRpbGVJRC5jYW5vbmljYWwueCAqIHBhcmVudFNjYWxlQnkgJSAxLCB0aWxlLnRpbGVJRC5jYW5vbmljYWwueSAqIHBhcmVudFNjYWxlQnkgJSAxXTtcblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGlsZS50ZXh0dXJlLmJpbmQodGV4dHVyZUZpbHRlciwgZ2wuQ0xBTVBfVE9fRURHRSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBFbmFibGUgdHJpbGluZWFyIGZpbHRlcmluZyBvbiB0aWxlcyBvbmx5IGJleW9uZCAyMCBkZWdyZWVzIHBpdGNoLFxuICAgICAgICAvLyB0byBwcmV2ZW50IGl0IGZyb20gY29tcHJvbWlzaW5nIGltYWdlIGNyaXNwbmVzcyBvbiBmbGF0IG9yIGxvdyB0aWx0ZWQgbWFwcy5cbiAgICAgICAgaWYgKHRpbGUudGV4dHVyZS51c2VNaXBtYXAgJiYgY29udGV4dC5leHRUZXh0dXJlRmlsdGVyQW5pc290cm9waWMgJiYgcGFpbnRlci50cmFuc2Zvcm0ucGl0Y2ggPiAyMCkge1xuICAgICAgICAgICAgZ2wudGV4UGFyYW1ldGVyZihnbC5URVhUVVJFXzJELCBjb250ZXh0LmV4dFRleHR1cmVGaWx0ZXJBbmlzb3Ryb3BpYy5URVhUVVJFX01BWF9BTklTT1RST1BZX0VYVCwgY29udGV4dC5leHRUZXh0dXJlRmlsdGVyQW5pc290cm9waWNNYXgpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcGVyc3BlY3RpdmVUcmFuc2Zvcm0gPSBzb3VyY2UgaW5zdGFuY2VvZiBJbWFnZVNvdXJjZSA/IHNvdXJjZS5wZXJzcGVjdGl2ZVRyYW5zZm9ybSA6IFswLCAwXTtcbiAgICAgICAgY29uc3QgdW5pZm9ybVZhbHVlcyA9IHJhc3RlclVuaWZvcm1WYWx1ZXMocHJvak1hdHJpeCwgcGFyZW50VEwgfHwgWzAsIDBdLCBwYXJlbnRTY2FsZUJ5IHx8IDEsIGZhZGUsIGxheWVyLCBwZXJzcGVjdGl2ZVRyYW5zZm9ybSk7XG5cbiAgICAgICAgcGFpbnRlci5wcmVwYXJlRHJhd1Byb2dyYW0oY29udGV4dCwgcHJvZ3JhbSwgdW53cmFwcGVkVGlsZUlEKTtcblxuICAgICAgICBpZiAoc291cmNlIGluc3RhbmNlb2YgSW1hZ2VTb3VyY2UpIHtcbiAgICAgICAgICAgIGlmIChzb3VyY2UuYm91bmRzQnVmZmVyICYmIHNvdXJjZS5ib3VuZHNTZWdtZW50cykgcHJvZ3JhbS5kcmF3KFxuICAgICAgICAgICAgICAgIGNvbnRleHQsIGdsLlRSSUFOR0xFUywgZGVwdGhNb2RlLCBTdGVuY2lsTW9kZS5kaXNhYmxlZCwgY29sb3JNb2RlLCBDdWxsRmFjZU1vZGUuZGlzYWJsZWQsXG4gICAgICAgICAgICAgICAgdW5pZm9ybVZhbHVlcywgbGF5ZXIuaWQsIHNvdXJjZS5ib3VuZHNCdWZmZXIsXG4gICAgICAgICAgICAgICAgcGFpbnRlci5xdWFkVHJpYW5nbGVJbmRleEJ1ZmZlciwgc291cmNlLmJvdW5kc1NlZ21lbnRzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHt0aWxlQm91bmRzQnVmZmVyLCB0aWxlQm91bmRzSW5kZXhCdWZmZXIsIHRpbGVCb3VuZHNTZWdtZW50c30gPSBwYWludGVyLmdldFRpbGVCb3VuZHNCdWZmZXJzKHRpbGUpO1xuXG4gICAgICAgICAgICBwcm9ncmFtLmRyYXcoY29udGV4dCwgZ2wuVFJJQU5HTEVTLCBkZXB0aE1vZGUsIHN0ZW5jaWxNb2RlLCBjb2xvck1vZGUsIEN1bGxGYWNlTW9kZS5kaXNhYmxlZCxcbiAgICAgICAgICAgICAgICB1bmlmb3JtVmFsdWVzLCBsYXllci5pZCwgdGlsZUJvdW5kc0J1ZmZlcixcbiAgICAgICAgICAgICAgICB0aWxlQm91bmRzSW5kZXhCdWZmZXIsIHRpbGVCb3VuZHNTZWdtZW50cyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwYWludGVyLnJlc2V0U3RlbmNpbENsaXBwaW5nTWFza3MoKTtcbn1cblxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IFN0ZW5jaWxNb2RlIGZyb20gJy4uL2dsL3N0ZW5jaWxfbW9kZS5qcyc7XG5pbXBvcnQgRGVwdGhNb2RlIGZyb20gJy4uL2dsL2RlcHRoX21vZGUuanMnO1xuaW1wb3J0IEN1bGxGYWNlTW9kZSBmcm9tICcuLi9nbC9jdWxsX2ZhY2VfbW9kZS5qcyc7XG5pbXBvcnQgVGlsZSBmcm9tICcuLi9zb3VyY2UvdGlsZS5qcyc7XG5pbXBvcnQge1xuICAgIGJhY2tncm91bmRVbmlmb3JtVmFsdWVzLFxuICAgIGJhY2tncm91bmRQYXR0ZXJuVW5pZm9ybVZhbHVlc1xufSBmcm9tICcuL3Byb2dyYW0vYmFja2dyb3VuZF9wcm9ncmFtLmpzJztcbmltcG9ydCB7T3ZlcnNjYWxlZFRpbGVJRH0gZnJvbSAnLi4vc291cmNlL3RpbGVfaWQuanMnO1xuXG5pbXBvcnQgdHlwZSBQYWludGVyIGZyb20gJy4vcGFpbnRlci5qcyc7XG5pbXBvcnQgdHlwZSBTb3VyY2VDYWNoZSBmcm9tICcuLi9zb3VyY2Uvc291cmNlX2NhY2hlLmpzJztcbmltcG9ydCB0eXBlIEJhY2tncm91bmRTdHlsZUxheWVyIGZyb20gJy4uL3N0eWxlL3N0eWxlX2xheWVyL2JhY2tncm91bmRfc3R5bGVfbGF5ZXIuanMnO1xuXG5leHBvcnQgZGVmYXVsdCBkcmF3QmFja2dyb3VuZDtcblxuZnVuY3Rpb24gZHJhd0JhY2tncm91bmQocGFpbnRlcjogUGFpbnRlciwgc291cmNlQ2FjaGU6IFNvdXJjZUNhY2hlLCBsYXllcjogQmFja2dyb3VuZFN0eWxlTGF5ZXIsIGNvb3JkczogQXJyYXk8T3ZlcnNjYWxlZFRpbGVJRD4pIHtcbiAgICBjb25zdCBjb2xvciA9IGxheWVyLnBhaW50LmdldCgnYmFja2dyb3VuZC1jb2xvcicpO1xuICAgIGNvbnN0IG9wYWNpdHkgPSBsYXllci5wYWludC5nZXQoJ2JhY2tncm91bmQtb3BhY2l0eScpO1xuXG4gICAgaWYgKG9wYWNpdHkgPT09IDApIHJldHVybjtcblxuICAgIGNvbnN0IGNvbnRleHQgPSBwYWludGVyLmNvbnRleHQ7XG4gICAgY29uc3QgZ2wgPSBjb250ZXh0LmdsO1xuICAgIGNvbnN0IHRyYW5zZm9ybSA9IHBhaW50ZXIudHJhbnNmb3JtO1xuICAgIGNvbnN0IHRpbGVTaXplID0gdHJhbnNmb3JtLnRpbGVTaXplO1xuICAgIGNvbnN0IGltYWdlID0gbGF5ZXIucGFpbnQuZ2V0KCdiYWNrZ3JvdW5kLXBhdHRlcm4nKTtcbiAgICBpZiAocGFpbnRlci5pc1BhdHRlcm5NaXNzaW5nKGltYWdlKSkgcmV0dXJuO1xuXG4gICAgY29uc3QgcGFzcyA9ICghaW1hZ2UgJiYgY29sb3IuYSA9PT0gMSAmJiBvcGFjaXR5ID09PSAxICYmIHBhaW50ZXIub3BhcXVlUGFzc0VuYWJsZWRGb3JMYXllcigpKSA/ICdvcGFxdWUnIDogJ3RyYW5zbHVjZW50JztcbiAgICBpZiAocGFpbnRlci5yZW5kZXJQYXNzICE9PSBwYXNzKSByZXR1cm47XG5cbiAgICBjb25zdCBzdGVuY2lsTW9kZSA9IFN0ZW5jaWxNb2RlLmRpc2FibGVkO1xuICAgIGNvbnN0IGRlcHRoTW9kZSA9IHBhaW50ZXIuZGVwdGhNb2RlRm9yU3VibGF5ZXIoMCwgcGFzcyA9PT0gJ29wYXF1ZScgPyBEZXB0aE1vZGUuUmVhZFdyaXRlIDogRGVwdGhNb2RlLlJlYWRPbmx5KTtcbiAgICBjb25zdCBjb2xvck1vZGUgPSBwYWludGVyLmNvbG9yTW9kZUZvclJlbmRlclBhc3MoKTtcblxuICAgIGNvbnN0IHByb2dyYW0gPSBwYWludGVyLnVzZVByb2dyYW0oaW1hZ2UgPyAnYmFja2dyb3VuZFBhdHRlcm4nIDogJ2JhY2tncm91bmQnKTtcblxuICAgIGxldCB0aWxlSURzID0gY29vcmRzO1xuICAgIGxldCBiYWNrZ3JvdW5kVGlsZXM7XG4gICAgaWYgKCF0aWxlSURzKSB7XG4gICAgICAgIGJhY2tncm91bmRUaWxlcyA9IHBhaW50ZXIuZ2V0QmFja2dyb3VuZFRpbGVzKCk7XG4gICAgICAgIHRpbGVJRHMgPSBPYmplY3QudmFsdWVzKGJhY2tncm91bmRUaWxlcykubWFwKHRpbGUgPT4gKHRpbGU6IGFueSkudGlsZUlEKTtcbiAgICB9XG5cbiAgICBpZiAoaW1hZ2UpIHtcbiAgICAgICAgY29udGV4dC5hY3RpdmVUZXh0dXJlLnNldChnbC5URVhUVVJFMCk7XG4gICAgICAgIHBhaW50ZXIuaW1hZ2VNYW5hZ2VyLmJpbmQocGFpbnRlci5jb250ZXh0KTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHRpbGVJRCBvZiB0aWxlSURzKSB7XG4gICAgICAgIGNvbnN0IHVud3JhcHBlZFRpbGVJRCA9IHRpbGVJRC50b1Vud3JhcHBlZCgpO1xuICAgICAgICBjb25zdCBtYXRyaXggPSBjb29yZHMgPyB0aWxlSUQucHJvak1hdHJpeCA6IHBhaW50ZXIudHJhbnNmb3JtLmNhbGN1bGF0ZVByb2pNYXRyaXgodW53cmFwcGVkVGlsZUlEKTtcbiAgICAgICAgcGFpbnRlci5wcmVwYXJlRHJhd1RpbGUoKTtcblxuICAgICAgICBjb25zdCB0aWxlID0gc291cmNlQ2FjaGUgPyBzb3VyY2VDYWNoZS5nZXRUaWxlKHRpbGVJRCkgOlxuICAgICAgICAgICAgYmFja2dyb3VuZFRpbGVzID8gYmFja2dyb3VuZFRpbGVzW3RpbGVJRC5rZXldIDogbmV3IFRpbGUodGlsZUlELCB0aWxlU2l6ZSwgdHJhbnNmb3JtLnpvb20sIHBhaW50ZXIpO1xuXG4gICAgICAgIGNvbnN0IHVuaWZvcm1WYWx1ZXMgPSBpbWFnZSA/XG4gICAgICAgICAgICBiYWNrZ3JvdW5kUGF0dGVyblVuaWZvcm1WYWx1ZXMobWF0cml4LCBvcGFjaXR5LCBwYWludGVyLCBpbWFnZSwge3RpbGVJRCwgdGlsZVNpemV9KSA6XG4gICAgICAgICAgICBiYWNrZ3JvdW5kVW5pZm9ybVZhbHVlcyhtYXRyaXgsIG9wYWNpdHksIGNvbG9yKTtcblxuICAgICAgICBwYWludGVyLnByZXBhcmVEcmF3UHJvZ3JhbShjb250ZXh0LCBwcm9ncmFtLCB1bndyYXBwZWRUaWxlSUQpO1xuXG4gICAgICAgIGNvbnN0IHt0aWxlQm91bmRzQnVmZmVyLCB0aWxlQm91bmRzSW5kZXhCdWZmZXIsIHRpbGVCb3VuZHNTZWdtZW50c30gPSBwYWludGVyLmdldFRpbGVCb3VuZHNCdWZmZXJzKHRpbGUpO1xuXG4gICAgICAgIHByb2dyYW0uZHJhdyhjb250ZXh0LCBnbC5UUklBTkdMRVMsIGRlcHRoTW9kZSwgc3RlbmNpbE1vZGUsIGNvbG9yTW9kZSwgQ3VsbEZhY2VNb2RlLmRpc2FibGVkLFxuICAgICAgICAgICAgdW5pZm9ybVZhbHVlcywgbGF5ZXIuaWQsIHRpbGVCb3VuZHNCdWZmZXIsXG4gICAgICAgICAgICAgICAgdGlsZUJvdW5kc0luZGV4QnVmZmVyLCB0aWxlQm91bmRzU2VnbWVudHMpO1xuICAgIH1cbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBEZXB0aE1vZGUgZnJvbSAnLi4vZ2wvZGVwdGhfbW9kZS5qcyc7XG5pbXBvcnQgU3RlbmNpbE1vZGUgZnJvbSAnLi4vZ2wvc3RlbmNpbF9tb2RlLmpzJztcbmltcG9ydCBDdWxsRmFjZU1vZGUgZnJvbSAnLi4vZ2wvY3VsbF9mYWNlX21vZGUuanMnO1xuaW1wb3J0IHtkZWJ1Z1VuaWZvcm1WYWx1ZXN9IGZyb20gJy4vcHJvZ3JhbS9kZWJ1Z19wcm9ncmFtLmpzJztcbmltcG9ydCBDb2xvciBmcm9tICcuLi9zdHlsZS1zcGVjL3V0aWwvY29sb3IuanMnO1xuaW1wb3J0IENvbG9yTW9kZSBmcm9tICcuLi9nbC9jb2xvcl9tb2RlLmpzJztcbmltcG9ydCBicm93c2VyIGZyb20gJy4uL3V0aWwvYnJvd3Nlci5qcyc7XG5pbXBvcnQge2dsb2JlRGVub3JtYWxpemVFQ0VGLCB0cmFuc2l0aW9uVGlsZUFBQkJpbkVDRUYsIGdsb2JlVG9NZXJjYXRvclRyYW5zaXRpb259IGZyb20gJy4uL2dlby9wcm9qZWN0aW9uL2dsb2JlX3V0aWwuanMnO1xuaW1wb3J0IHttYXQ0fSBmcm9tICdnbC1tYXRyaXgnO1xuXG5pbXBvcnQgdHlwZSBQYWludGVyIGZyb20gJy4vcGFpbnRlci5qcyc7XG5pbXBvcnQgdHlwZSBTb3VyY2VDYWNoZSBmcm9tICcuLi9zb3VyY2Uvc291cmNlX2NhY2hlLmpzJztcbmltcG9ydCB0eXBlIHtPdmVyc2NhbGVkVGlsZUlEfSBmcm9tICcuLi9zb3VyY2UvdGlsZV9pZC5qcyc7XG5cbmNvbnN0IHRvcENvbG9yID0gbmV3IENvbG9yKDEsIDAsIDAsIDEpO1xuY29uc3QgYnRtQ29sb3IgPSBuZXcgQ29sb3IoMCwgMSwgMCwgMSk7XG5jb25zdCBsZWZ0Q29sb3IgPSBuZXcgQ29sb3IoMCwgMCwgMSwgMSk7XG5jb25zdCByaWdodENvbG9yID0gbmV3IENvbG9yKDEsIDAsIDEsIDEpO1xuY29uc3QgY2VudGVyQ29sb3IgPSBuZXcgQ29sb3IoMCwgMSwgMSwgMSk7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGRyYXdEZWJ1ZyhwYWludGVyOiBQYWludGVyLCBzb3VyY2VDYWNoZTogU291cmNlQ2FjaGUsIGNvb3JkczogQXJyYXk8T3ZlcnNjYWxlZFRpbGVJRD4pIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvb3Jkcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBkcmF3RGVidWdUaWxlKHBhaW50ZXIsIHNvdXJjZUNhY2hlLCBjb29yZHNbaV0pO1xuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRyYXdEZWJ1Z1BhZGRpbmcocGFpbnRlcjogUGFpbnRlcikge1xuICAgIGNvbnN0IHBhZGRpbmcgPSBwYWludGVyLnRyYW5zZm9ybS5wYWRkaW5nO1xuICAgIGNvbnN0IGxpbmVXaWR0aCA9IDM7XG4gICAgLy8gVG9wXG4gICAgZHJhd0hvcml6b250YWxMaW5lKHBhaW50ZXIsIHBhaW50ZXIudHJhbnNmb3JtLmhlaWdodCAtIChwYWRkaW5nLnRvcCB8fCAwKSwgbGluZVdpZHRoLCB0b3BDb2xvcik7XG4gICAgLy8gQm90dG9tXG4gICAgZHJhd0hvcml6b250YWxMaW5lKHBhaW50ZXIsIHBhZGRpbmcuYm90dG9tIHx8IDAsIGxpbmVXaWR0aCwgYnRtQ29sb3IpO1xuICAgIC8vIExlZnRcbiAgICBkcmF3VmVydGljYWxMaW5lKHBhaW50ZXIsIHBhZGRpbmcubGVmdCB8fCAwLCBsaW5lV2lkdGgsIGxlZnRDb2xvcik7XG4gICAgLy8gUmlnaHRcbiAgICBkcmF3VmVydGljYWxMaW5lKHBhaW50ZXIsIHBhaW50ZXIudHJhbnNmb3JtLndpZHRoIC0gKHBhZGRpbmcucmlnaHQgfHwgMCksIGxpbmVXaWR0aCwgcmlnaHRDb2xvcik7XG4gICAgLy8gQ2VudGVyXG4gICAgY29uc3QgY2VudGVyID0gcGFpbnRlci50cmFuc2Zvcm0uY2VudGVyUG9pbnQ7XG4gICAgZHJhd0Nyb3NzaGFpcihwYWludGVyLCBjZW50ZXIueCwgcGFpbnRlci50cmFuc2Zvcm0uaGVpZ2h0IC0gY2VudGVyLnksIGNlbnRlckNvbG9yKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRyYXdEZWJ1Z1F1ZXJ5R2VvbWV0cnkocGFpbnRlcjogUGFpbnRlciwgc291cmNlQ2FjaGU6IFNvdXJjZUNhY2hlLCBjb29yZHM6IEFycmF5PE92ZXJzY2FsZWRUaWxlSUQ+KSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb29yZHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgZHJhd1RpbGVRdWVyeUdlb21ldHJ5KHBhaW50ZXIsIHNvdXJjZUNhY2hlLCBjb29yZHNbaV0pO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZHJhd0RlYnVnVGlsZShwYWludGVyOiBQYWludGVyLCBzb3VyY2VDYWNoZTogU291cmNlQ2FjaGUsIGNvb3JkOiBPdmVyc2NhbGVkVGlsZUlEKSB7XG4gICAgY29uc3QgY29udGV4dCA9IHBhaW50ZXIuY29udGV4dDtcbiAgICBjb25zdCB0ciA9IHBhaW50ZXIudHJhbnNmb3JtO1xuICAgIGNvbnN0IGdsID0gY29udGV4dC5nbDtcblxuICAgIGNvbnN0IGlzR2xvYmVQcm9qZWN0aW9uID0gdHIucHJvamVjdGlvbi5uYW1lID09PSAnZ2xvYmUnO1xuICAgIGNvbnN0IGRlZmluZXNWYWx1ZXMgPSBpc0dsb2JlUHJvamVjdGlvbiA/IFsnUFJPSkVDVElPTl9HTE9CRV9WSUVXJ10gOiBudWxsO1xuXG4gICAgbGV0IHBvc01hdHJpeCA9IGNvb3JkLnByb2pNYXRyaXg7XG5cbiAgICBpZiAoaXNHbG9iZVByb2plY3Rpb24gJiYgZ2xvYmVUb01lcmNhdG9yVHJhbnNpdGlvbih0ci56b29tKSA+IDApIHtcbiAgICAgICAgLy8gV2UgdXNlIGEgY3VzdG9tIHRpbGUgbWF0cml4IGhlcmUgaW4gb3JkZXIgdG8gaGFuZGxlIHRoZSBnbG9iZS10by1tZXJjYXRvciB0cmFuc2l0aW9uXG4gICAgICAgIC8vIHRoZSBmb2xsb3dpbmcgaXMgZXF1aXZhbGVudCB0byB0cmFuc2Zvcm0uY2FsY3VsYXRlUG9zTWF0cml4LFxuICAgICAgICAvLyBleGNlcHQgd2UgdXNlIHRyYW5zaXRpb25UaWxlQUFCQmluRUNFRiBpbnN0ZWFkIG9mIGdsb2JlVGlsZUJvdW5kcyB0byBhY2NvdW50IGZvciB0aGUgdHJhbnNpdGlvbi5cbiAgICAgICAgY29uc3QgYm91bmRzID0gdHJhbnNpdGlvblRpbGVBQUJCaW5FQ0VGKGNvb3JkLmNhbm9uaWNhbCwgdHIpO1xuICAgICAgICBjb25zdCBkZWNvZGUgPSBnbG9iZURlbm9ybWFsaXplRUNFRihib3VuZHMpO1xuICAgICAgICBwb3NNYXRyaXggPSBtYXQ0Lm11bHRpcGx5KG5ldyBGbG9hdDMyQXJyYXkoMTYpLCB0ci5nbG9iZU1hdHJpeCwgZGVjb2RlKTtcbiAgICAgICAgbWF0NC5tdWx0aXBseShwb3NNYXRyaXgsIHRyLnByb2pNYXRyaXgsIHBvc01hdHJpeCk7XG4gICAgfVxuXG4gICAgY29uc3QgcHJvZ3JhbSA9IHBhaW50ZXIudXNlUHJvZ3JhbSgnZGVidWcnLCBudWxsLCBkZWZpbmVzVmFsdWVzKTtcbiAgICBjb25zdCB0aWxlID0gc291cmNlQ2FjaGUuZ2V0VGlsZUJ5SUQoY29vcmQua2V5KTtcbiAgICBpZiAocGFpbnRlci50ZXJyYWluKSBwYWludGVyLnRlcnJhaW4uc2V0dXBFbGV2YXRpb25EcmF3KHRpbGUsIHByb2dyYW0pO1xuXG4gICAgY29uc3QgZGVwdGhNb2RlID0gRGVwdGhNb2RlLmRpc2FibGVkO1xuICAgIGNvbnN0IHN0ZW5jaWxNb2RlID0gU3RlbmNpbE1vZGUuZGlzYWJsZWQ7XG4gICAgY29uc3QgY29sb3JNb2RlID0gcGFpbnRlci5jb2xvck1vZGVGb3JSZW5kZXJQYXNzKCk7XG4gICAgY29uc3QgaWQgPSAnJGRlYnVnJztcblxuICAgIGNvbnRleHQuYWN0aXZlVGV4dHVyZS5zZXQoZ2wuVEVYVFVSRTApO1xuICAgIC8vIEJpbmQgdGhlIGVtcHR5IHRleHR1cmUgZm9yIGRyYXdpbmcgb3V0bGluZXNcbiAgICBwYWludGVyLmVtcHR5VGV4dHVyZS5iaW5kKGdsLkxJTkVBUiwgZ2wuQ0xBTVBfVE9fRURHRSk7XG5cbiAgICBpZiAoaXNHbG9iZVByb2plY3Rpb24pIHtcbiAgICAgICAgdGlsZS5fbWFrZUdsb2JlVGlsZURlYnVnQnVmZmVycyhwYWludGVyLmNvbnRleHQsIHRyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aWxlLl9tYWtlRGVidWdUaWxlQm91bmRzQnVmZmVycyhwYWludGVyLmNvbnRleHQsIHRyLnByb2plY3Rpb24pO1xuICAgIH1cblxuICAgIGNvbnN0IGRlYnVnQnVmZmVyID0gdGlsZS5fdGlsZURlYnVnQnVmZmVyIHx8IHBhaW50ZXIuZGVidWdCdWZmZXI7XG4gICAgY29uc3QgZGVidWdJbmRleEJ1ZmZlciA9IHRpbGUuX3RpbGVEZWJ1Z0luZGV4QnVmZmVyIHx8IHBhaW50ZXIuZGVidWdJbmRleEJ1ZmZlcjtcbiAgICBjb25zdCBkZWJ1Z1NlZ21lbnRzID0gdGlsZS5fdGlsZURlYnVnU2VnbWVudHMgfHwgcGFpbnRlci5kZWJ1Z1NlZ21lbnRzO1xuXG4gICAgcHJvZ3JhbS5kcmF3KGNvbnRleHQsIGdsLkxJTkVfU1RSSVAsIGRlcHRoTW9kZSwgc3RlbmNpbE1vZGUsIGNvbG9yTW9kZSwgQ3VsbEZhY2VNb2RlLmRpc2FibGVkLFxuICAgICAgICBkZWJ1Z1VuaWZvcm1WYWx1ZXMocG9zTWF0cml4LCBDb2xvci5yZWQpLCBpZCxcbiAgICAgICAgZGVidWdCdWZmZXIsIGRlYnVnSW5kZXhCdWZmZXIsIGRlYnVnU2VnbWVudHMsXG4gICAgICAgIG51bGwsIG51bGwsIG51bGwsIFt0aWxlLl9nbG9iZVRpbGVEZWJ1Z0JvcmRlckJ1ZmZlcl0pO1xuXG4gICAgY29uc3QgdGlsZVJhd0RhdGEgPSB0aWxlLmxhdGVzdFJhd1RpbGVEYXRhO1xuICAgIGNvbnN0IHRpbGVCeXRlTGVuZ3RoID0gKHRpbGVSYXdEYXRhICYmIHRpbGVSYXdEYXRhLmJ5dGVMZW5ndGgpIHx8IDA7XG4gICAgY29uc3QgdGlsZVNpemVLYiA9IE1hdGguZmxvb3IodGlsZUJ5dGVMZW5ndGggLyAxMDI0KTtcbiAgICBjb25zdCB0aWxlU2l6ZSA9IHNvdXJjZUNhY2hlLmdldFRpbGUoY29vcmQpLnRpbGVTaXplO1xuICAgIGNvbnN0IHNjYWxlUmF0aW8gPSAoNTEyIC8gTWF0aC5taW4odGlsZVNpemUsIDUxMikgKiAoY29vcmQub3ZlcnNjYWxlZFogLyB0ci56b29tKSkgKiAwLjU7XG4gICAgbGV0IHRpbGVMYWJlbCA9IGNvb3JkLmNhbm9uaWNhbC50b1N0cmluZygpO1xuICAgIGlmIChjb29yZC5vdmVyc2NhbGVkWiAhPT0gY29vcmQuY2Fub25pY2FsLnopIHtcbiAgICAgICAgdGlsZUxhYmVsICs9IGAgPT4gJHtjb29yZC5vdmVyc2NhbGVkWn1gO1xuICAgIH1cbiAgICB0aWxlTGFiZWwgKz0gYCAke3RpbGVTaXplS2J9a2JgO1xuICAgIGRyYXdUZXh0VG9PdmVybGF5KHBhaW50ZXIsIHRpbGVMYWJlbCk7XG5cbiAgICBjb25zdCBkZWJ1Z1RleHRCdWZmZXIgPSB0aWxlLl90aWxlRGVidWdUZXh0QnVmZmVyIHx8IHBhaW50ZXIuZGVidWdCdWZmZXI7XG4gICAgY29uc3QgZGVidWdUZXh0SW5kZXhCdWZmZXIgPSB0aWxlLl90aWxlRGVidWdUZXh0SW5kZXhCdWZmZXIgfHwgcGFpbnRlci5xdWFkVHJpYW5nbGVJbmRleEJ1ZmZlcjtcbiAgICBjb25zdCBkZWJ1Z1RleHRTZWdtZW50cyA9IHRpbGUuX3RpbGVEZWJ1Z1RleHRTZWdtZW50cyB8fCBwYWludGVyLmRlYnVnU2VnbWVudHM7XG5cbiAgICBwcm9ncmFtLmRyYXcoY29udGV4dCwgZ2wuVFJJQU5HTEVTLCBkZXB0aE1vZGUsIHN0ZW5jaWxNb2RlLCBDb2xvck1vZGUuYWxwaGFCbGVuZGVkLCBDdWxsRmFjZU1vZGUuZGlzYWJsZWQsXG4gICAgICAgIGRlYnVnVW5pZm9ybVZhbHVlcyhwb3NNYXRyaXgsIENvbG9yLnRyYW5zcGFyZW50LCBzY2FsZVJhdGlvKSwgaWQsXG4gICAgICAgIGRlYnVnVGV4dEJ1ZmZlciwgZGVidWdUZXh0SW5kZXhCdWZmZXIsIGRlYnVnVGV4dFNlZ21lbnRzLFxuICAgICAgICBudWxsLCBudWxsLCBudWxsLCBbdGlsZS5fZ2xvYmVUaWxlRGVidWdUZXh0QnVmZmVyXSk7XG59XG5cbmZ1bmN0aW9uIGRyYXdDcm9zc2hhaXIocGFpbnRlcjogUGFpbnRlciwgeDogbnVtYmVyLCB5OiBudW1iZXIsIGNvbG9yOiBDb2xvcikge1xuICAgIGNvbnN0IHNpemUgPSAyMDtcbiAgICBjb25zdCBsaW5lV2lkdGggPSAyO1xuICAgIC8vVmVydGljYWwgbGluZVxuICAgIGRyYXdEZWJ1Z1NTUmVjdChwYWludGVyLCB4IC0gbGluZVdpZHRoIC8gMiwgeSAtIHNpemUgLyAyLCBsaW5lV2lkdGgsIHNpemUsIGNvbG9yKTtcbiAgICAvL0hvcml6b250YWwgbGluZVxuICAgIGRyYXdEZWJ1Z1NTUmVjdChwYWludGVyLCB4IC0gc2l6ZSAvIDIsIHkgLSBsaW5lV2lkdGggLyAyLCBzaXplLCBsaW5lV2lkdGgsIGNvbG9yKTtcbn1cblxuZnVuY3Rpb24gZHJhd0hvcml6b250YWxMaW5lKHBhaW50ZXI6IFBhaW50ZXIsIHk6IG51bWJlciwgbGluZVdpZHRoOiBudW1iZXIsIGNvbG9yOiBDb2xvcikge1xuICAgIGRyYXdEZWJ1Z1NTUmVjdChwYWludGVyLCAwLCB5ICArIGxpbmVXaWR0aCAvIDIsIHBhaW50ZXIudHJhbnNmb3JtLndpZHRoLCAgbGluZVdpZHRoLCBjb2xvcik7XG59XG5cbmZ1bmN0aW9uIGRyYXdWZXJ0aWNhbExpbmUocGFpbnRlcjogUGFpbnRlciwgeDogbnVtYmVyLCBsaW5lV2lkdGg6IG51bWJlciwgY29sb3I6IENvbG9yKSB7XG4gICAgZHJhd0RlYnVnU1NSZWN0KHBhaW50ZXIsIHggLSBsaW5lV2lkdGggLyAyLCAwLCBsaW5lV2lkdGgsICBwYWludGVyLnRyYW5zZm9ybS5oZWlnaHQsIGNvbG9yKTtcbn1cblxuZnVuY3Rpb24gZHJhd0RlYnVnU1NSZWN0KHBhaW50ZXI6IFBhaW50ZXIsIHg6IG51bWJlciwgeTogbnVtYmVyLCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciwgY29sb3I6IENvbG9yKSB7XG4gICAgY29uc3QgY29udGV4dCA9IHBhaW50ZXIuY29udGV4dDtcbiAgICBjb25zdCBnbCA9IGNvbnRleHQuZ2w7XG5cbiAgICBnbC5lbmFibGUoZ2wuU0NJU1NPUl9URVNUKTtcbiAgICBnbC5zY2lzc29yKHggKiBicm93c2VyLmRldmljZVBpeGVsUmF0aW8sIHkgKiBicm93c2VyLmRldmljZVBpeGVsUmF0aW8sIHdpZHRoICogYnJvd3Nlci5kZXZpY2VQaXhlbFJhdGlvLCBoZWlnaHQgKiBicm93c2VyLmRldmljZVBpeGVsUmF0aW8pO1xuICAgIGNvbnRleHQuY2xlYXIoe2NvbG9yfSk7XG4gICAgZ2wuZGlzYWJsZShnbC5TQ0lTU09SX1RFU1QpO1xufVxuXG5mdW5jdGlvbiBkcmF3VGlsZVF1ZXJ5R2VvbWV0cnkocGFpbnRlcjogUGFpbnRlciwgc291cmNlQ2FjaGU6IFNvdXJjZUNhY2hlLCBjb29yZDogT3ZlcnNjYWxlZFRpbGVJRCkge1xuICAgIGNvbnN0IGNvbnRleHQgPSBwYWludGVyLmNvbnRleHQ7XG4gICAgY29uc3QgZ2wgPSBjb250ZXh0LmdsO1xuXG4gICAgY29uc3QgcG9zTWF0cml4ID0gY29vcmQucHJvak1hdHJpeDtcbiAgICBjb25zdCBwcm9ncmFtID0gcGFpbnRlci51c2VQcm9ncmFtKCdkZWJ1ZycpO1xuICAgIGNvbnN0IHRpbGUgPSBzb3VyY2VDYWNoZS5nZXRUaWxlQnlJRChjb29yZC5rZXkpO1xuICAgIGlmIChwYWludGVyLnRlcnJhaW4pIHBhaW50ZXIudGVycmFpbi5zZXR1cEVsZXZhdGlvbkRyYXcodGlsZSwgcHJvZ3JhbSk7XG5cbiAgICBjb25zdCBkZXB0aE1vZGUgPSBEZXB0aE1vZGUuZGlzYWJsZWQ7XG4gICAgY29uc3Qgc3RlbmNpbE1vZGUgPSBTdGVuY2lsTW9kZS5kaXNhYmxlZDtcbiAgICBjb25zdCBjb2xvck1vZGUgPSBwYWludGVyLmNvbG9yTW9kZUZvclJlbmRlclBhc3MoKTtcbiAgICBjb25zdCBpZCA9ICckZGVidWcnO1xuXG4gICAgY29udGV4dC5hY3RpdmVUZXh0dXJlLnNldChnbC5URVhUVVJFMCk7XG4gICAgLy8gQmluZCB0aGUgZW1wdHkgdGV4dHVyZSBmb3IgZHJhd2luZyBvdXRsaW5lc1xuICAgIHBhaW50ZXIuZW1wdHlUZXh0dXJlLmJpbmQoZ2wuTElORUFSLCBnbC5DTEFNUF9UT19FREdFKTtcblxuICAgIGNvbnN0IHF1ZXJ5Vml6ID0gdGlsZS5xdWVyeUdlb21ldHJ5RGVidWdWaXo7XG4gICAgY29uc3QgYm91bmRzVml6ID0gdGlsZS5xdWVyeUJvdW5kc0RlYnVnVml6O1xuXG4gICAgaWYgKHF1ZXJ5Vml6ICYmIHF1ZXJ5Vml6LnZlcnRpY2VzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcXVlcnlWaXoubGF6eVVwbG9hZChjb250ZXh0KTtcbiAgICAgICAgY29uc3QgdmVydGV4QnVmZmVyID0gcXVlcnlWaXoudmVydGV4QnVmZmVyO1xuICAgICAgICBjb25zdCBpbmRleEJ1ZmZlciA9IHF1ZXJ5Vml6LmluZGV4QnVmZmVyO1xuICAgICAgICBjb25zdCBzZWdtZW50cyA9IHF1ZXJ5Vml6LnNlZ21lbnRzO1xuICAgICAgICBpZiAodmVydGV4QnVmZmVyICE9IG51bGwgJiYgaW5kZXhCdWZmZXIgIT0gbnVsbCAmJiBzZWdtZW50cyAhPSBudWxsKSB7XG4gICAgICAgICAgICBwcm9ncmFtLmRyYXcoY29udGV4dCwgZ2wuTElORV9TVFJJUCwgZGVwdGhNb2RlLCBzdGVuY2lsTW9kZSwgY29sb3JNb2RlLCBDdWxsRmFjZU1vZGUuZGlzYWJsZWQsXG4gICAgICAgICAgICAgICAgZGVidWdVbmlmb3JtVmFsdWVzKHBvc01hdHJpeCwgcXVlcnlWaXouY29sb3IpLCBpZCxcbiAgICAgICAgICAgICAgICB2ZXJ0ZXhCdWZmZXIsIGluZGV4QnVmZmVyLCBzZWdtZW50cyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoYm91bmRzVml6ICYmIGJvdW5kc1Zpei52ZXJ0aWNlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGJvdW5kc1Zpei5sYXp5VXBsb2FkKGNvbnRleHQpO1xuICAgICAgICBjb25zdCB2ZXJ0ZXhCdWZmZXIgPSBib3VuZHNWaXoudmVydGV4QnVmZmVyO1xuICAgICAgICBjb25zdCBpbmRleEJ1ZmZlciA9IGJvdW5kc1Zpei5pbmRleEJ1ZmZlcjtcbiAgICAgICAgY29uc3Qgc2VnbWVudHMgPSBib3VuZHNWaXouc2VnbWVudHM7XG4gICAgICAgIGlmICh2ZXJ0ZXhCdWZmZXIgIT0gbnVsbCAmJiBpbmRleEJ1ZmZlciAhPSBudWxsICYmIHNlZ21lbnRzICE9IG51bGwpIHtcbiAgICAgICAgICAgIHByb2dyYW0uZHJhdyhjb250ZXh0LCBnbC5MSU5FX1NUUklQLCBkZXB0aE1vZGUsIHN0ZW5jaWxNb2RlLCBjb2xvck1vZGUsIEN1bGxGYWNlTW9kZS5kaXNhYmxlZCxcbiAgICAgICAgICAgICAgICBkZWJ1Z1VuaWZvcm1WYWx1ZXMocG9zTWF0cml4LCBib3VuZHNWaXouY29sb3IpLCBpZCxcbiAgICAgICAgICAgICAgICB2ZXJ0ZXhCdWZmZXIsIGluZGV4QnVmZmVyLCBzZWdtZW50cyk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRyYXdUZXh0VG9PdmVybGF5KHBhaW50ZXI6IFBhaW50ZXIsIHRleHQ6IHN0cmluZykge1xuICAgIHBhaW50ZXIuaW5pdERlYnVnT3ZlcmxheUNhbnZhcygpO1xuICAgIGNvbnN0IGNhbnZhcyA9IHBhaW50ZXIuZGVidWdPdmVybGF5Q2FudmFzO1xuICAgIGNvbnN0IGdsID0gcGFpbnRlci5jb250ZXh0LmdsO1xuICAgIGNvbnN0IGN0eDJkID0gcGFpbnRlci5kZWJ1Z092ZXJsYXlDYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICBjdHgyZC5jbGVhclJlY3QoMCwgMCwgY2FudmFzLndpZHRoLCBjYW52YXMuaGVpZ2h0KTtcblxuICAgIGN0eDJkLnNoYWRvd0NvbG9yID0gJ3doaXRlJztcbiAgICBjdHgyZC5zaGFkb3dCbHVyID0gMjtcbiAgICBjdHgyZC5saW5lV2lkdGggPSAxLjU7XG4gICAgY3R4MmQuc3Ryb2tlU3R5bGUgPSAnd2hpdGUnO1xuICAgIGN0eDJkLnRleHRCYXNlbGluZSA9ICd0b3AnO1xuICAgIGN0eDJkLmZvbnQgPSBgYm9sZCAkezM2fXB4IE9wZW4gU2Fucywgc2Fucy1zZXJpZmA7XG4gICAgY3R4MmQuZmlsbFRleHQodGV4dCwgNSwgNSk7XG4gICAgY3R4MmQuc3Ryb2tlVGV4dCh0ZXh0LCA1LCA1KTtcblxuICAgIHBhaW50ZXIuZGVidWdPdmVybGF5VGV4dHVyZS51cGRhdGUoY2FudmFzKTtcbiAgICBwYWludGVyLmRlYnVnT3ZlcmxheVRleHR1cmUuYmluZChnbC5MSU5FQVIsIGdsLkNMQU1QX1RPX0VER0UpO1xufVxuIiwiLy8gQGZsb3dcblxuZXhwb3J0IGRlZmF1bHQgZHJhd0N1c3RvbTtcblxuaW1wb3J0IERlcHRoTW9kZSBmcm9tICcuLi9nbC9kZXB0aF9tb2RlLmpzJztcbmltcG9ydCBTdGVuY2lsTW9kZSBmcm9tICcuLi9nbC9zdGVuY2lsX21vZGUuanMnO1xuaW1wb3J0IHt3YXJuT25jZX0gZnJvbSAnLi4vdXRpbC91dGlsLmpzJztcbmltcG9ydCB7Z2xvYmVUb01lcmNhdG9yVHJhbnNpdGlvbn0gZnJvbSAnLi8uLi9nZW8vcHJvamVjdGlvbi9nbG9iZV91dGlsLmpzJztcblxuaW1wb3J0IHR5cGUgUGFpbnRlciBmcm9tICcuL3BhaW50ZXIuanMnO1xuaW1wb3J0IHR5cGUge092ZXJzY2FsZWRUaWxlSUR9IGZyb20gJy4uL3NvdXJjZS90aWxlX2lkLmpzJztcbmltcG9ydCB0eXBlIFNvdXJjZUNhY2hlIGZyb20gJy4uL3NvdXJjZS9zb3VyY2VfY2FjaGUuanMnO1xuaW1wb3J0IHR5cGUgQ3VzdG9tU3R5bGVMYXllciBmcm9tICcuLi9zdHlsZS9zdHlsZV9sYXllci9jdXN0b21fc3R5bGVfbGF5ZXIuanMnO1xuaW1wb3J0IE1lcmNhdG9yQ29vcmRpbmF0ZSBmcm9tICcuLi9nZW8vbWVyY2F0b3JfY29vcmRpbmF0ZS5qcyc7XG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbmZ1bmN0aW9uIGRyYXdDdXN0b20ocGFpbnRlcjogUGFpbnRlciwgc291cmNlQ2FjaGU6IFNvdXJjZUNhY2hlLCBsYXllcjogQ3VzdG9tU3R5bGVMYXllciwgY29vcmRzOiBBcnJheTxPdmVyc2NhbGVkVGlsZUlEPikge1xuXG4gICAgY29uc3QgY29udGV4dCA9IHBhaW50ZXIuY29udGV4dDtcbiAgICBjb25zdCBpbXBsZW1lbnRhdGlvbiA9IGxheWVyLmltcGxlbWVudGF0aW9uO1xuXG4gICAgaWYgKHBhaW50ZXIudHJhbnNmb3JtLnByb2plY3Rpb24udW5zdXBwb3J0ZWRMYXllcnMgJiYgcGFpbnRlci50cmFuc2Zvcm0ucHJvamVjdGlvbi51bnN1cHBvcnRlZExheWVycy5pbmNsdWRlcyhcImN1c3RvbVwiKSAmJlxuICAgICAgICAhKHBhaW50ZXIudGVycmFpbiAmJiAocGFpbnRlci50ZXJyYWluLnJlbmRlcmluZ1RvVGV4dHVyZSB8fCBwYWludGVyLnJlbmRlclBhc3MgPT09ICdvZmZzY3JlZW4nKSAmJiBsYXllci5pc0xheWVyRHJhcGVkKCkpKSB7XG4gICAgICAgIHdhcm5PbmNlKCdDdXN0b20gbGF5ZXJzIGFyZSBub3QgeWV0IHN1cHBvcnRlZCB3aXRoIHRoaXMgcHJvamVjdGlvbi4gVXNlIG1lcmNhdG9yIG9yIGdsb2JlIHRvIGVuYWJsZSB1c2FnZSBvZiBjdXN0b20gbGF5ZXJzLicpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHBhaW50ZXIucmVuZGVyUGFzcyA9PT0gJ29mZnNjcmVlbicpIHtcblxuICAgICAgICBjb25zdCBwcmVyZW5kZXIgPSBpbXBsZW1lbnRhdGlvbi5wcmVyZW5kZXI7XG4gICAgICAgIGlmIChwcmVyZW5kZXIpIHtcbiAgICAgICAgICAgIHBhaW50ZXIuc2V0Q3VzdG9tTGF5ZXJEZWZhdWx0cygpO1xuICAgICAgICAgICAgY29udGV4dC5zZXRDb2xvck1vZGUocGFpbnRlci5jb2xvck1vZGVGb3JSZW5kZXJQYXNzKCkpO1xuXG4gICAgICAgICAgICBpZiAocGFpbnRlci50cmFuc2Zvcm0ucHJvamVjdGlvbi5uYW1lID09PSBcImdsb2JlXCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjZW50ZXIgPSBwYWludGVyLnRyYW5zZm9ybS5wb2ludE1lcmM7XG4gICAgICAgICAgICAgICAgcHJlcmVuZGVyLmNhbGwoaW1wbGVtZW50YXRpb24sIGNvbnRleHQuZ2wsIHBhaW50ZXIudHJhbnNmb3JtLmN1c3RvbUxheWVyTWF0cml4KCksIHBhaW50ZXIudHJhbnNmb3JtLmdldFByb2plY3Rpb24oKSwgcGFpbnRlci50cmFuc2Zvcm0uZ2xvYmVUb01lcmNhdG9yTWF0cml4KCksICBnbG9iZVRvTWVyY2F0b3JUcmFuc2l0aW9uKHBhaW50ZXIudHJhbnNmb3JtLnpvb20pLCBbY2VudGVyLngsIGNlbnRlci55XSwgcGFpbnRlci50cmFuc2Zvcm0ucGl4ZWxzUGVyTWV0ZXJSYXRpbyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHByZXJlbmRlci5jYWxsKGltcGxlbWVudGF0aW9uLCBjb250ZXh0LmdsLCBwYWludGVyLnRyYW5zZm9ybS5jdXN0b21MYXllck1hdHJpeCgpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29udGV4dC5zZXREaXJ0eSgpO1xuICAgICAgICAgICAgcGFpbnRlci5zZXRCYXNlU3RhdGUoKTtcbiAgICAgICAgfVxuXG4gICAgfSBlbHNlIGlmIChwYWludGVyLnJlbmRlclBhc3MgPT09ICd0cmFuc2x1Y2VudCcpIHtcblxuICAgICAgICBpZiAocGFpbnRlci50ZXJyYWluICYmIHBhaW50ZXIudGVycmFpbi5yZW5kZXJpbmdUb1RleHR1cmUpIHtcbiAgICAgICAgICAgIGFzc2VydChpbXBsZW1lbnRhdGlvbi5yZW5kZXJUb1RpbGUpO1xuICAgICAgICAgICAgYXNzZXJ0KGNvb3Jkcy5sZW5ndGggPT09IDEpO1xuICAgICAgICAgICAgY29uc3QgcmVuZGVyVG9UaWxlID0gaW1wbGVtZW50YXRpb24ucmVuZGVyVG9UaWxlO1xuICAgICAgICAgICAgaWYgKHJlbmRlclRvVGlsZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGMgPSBjb29yZHNbMF0uY2Fub25pY2FsO1xuICAgICAgICAgICAgICAgIGNvbnN0IHVud3JhcHBlZCA9IG5ldyBNZXJjYXRvckNvb3JkaW5hdGUoYy54ICsgY29vcmRzWzBdLndyYXAgKiAoMSA8PCBjLnopLCBjLnksIGMueik7XG5cbiAgICAgICAgICAgICAgICBjb250ZXh0LnNldERlcHRoTW9kZShEZXB0aE1vZGUuZGlzYWJsZWQpO1xuICAgICAgICAgICAgICAgIGNvbnRleHQuc2V0U3RlbmNpbE1vZGUoU3RlbmNpbE1vZGUuZGlzYWJsZWQpO1xuICAgICAgICAgICAgICAgIGNvbnRleHQuc2V0Q29sb3JNb2RlKHBhaW50ZXIuY29sb3JNb2RlRm9yUmVuZGVyUGFzcygpKTtcbiAgICAgICAgICAgICAgICBwYWludGVyLnNldEN1c3RvbUxheWVyRGVmYXVsdHMoKTtcblxuICAgICAgICAgICAgICAgIHJlbmRlclRvVGlsZS5jYWxsKGltcGxlbWVudGF0aW9uLCBjb250ZXh0LmdsLCB1bndyYXBwZWQpO1xuICAgICAgICAgICAgICAgIGNvbnRleHQuc2V0RGlydHkoKTtcbiAgICAgICAgICAgICAgICBwYWludGVyLnNldEJhc2VTdGF0ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgcGFpbnRlci5zZXRDdXN0b21MYXllckRlZmF1bHRzKCk7XG5cbiAgICAgICAgY29udGV4dC5zZXRDb2xvck1vZGUocGFpbnRlci5jb2xvck1vZGVGb3JSZW5kZXJQYXNzKCkpO1xuICAgICAgICBjb250ZXh0LnNldFN0ZW5jaWxNb2RlKFN0ZW5jaWxNb2RlLmRpc2FibGVkKTtcblxuICAgICAgICBjb25zdCBkZXB0aE1vZGUgPSBpbXBsZW1lbnRhdGlvbi5yZW5kZXJpbmdNb2RlID09PSAnM2QnID9cbiAgICAgICAgICAgIG5ldyBEZXB0aE1vZGUocGFpbnRlci5jb250ZXh0LmdsLkxFUVVBTCwgRGVwdGhNb2RlLlJlYWRXcml0ZSwgcGFpbnRlci5kZXB0aFJhbmdlRm9yM0QpIDpcbiAgICAgICAgICAgIHBhaW50ZXIuZGVwdGhNb2RlRm9yU3VibGF5ZXIoMCwgRGVwdGhNb2RlLlJlYWRPbmx5KTtcblxuICAgICAgICBjb250ZXh0LnNldERlcHRoTW9kZShkZXB0aE1vZGUpO1xuXG4gICAgICAgIGlmIChwYWludGVyLnRyYW5zZm9ybS5wcm9qZWN0aW9uLm5hbWUgPT09IFwiZ2xvYmVcIikge1xuICAgICAgICAgICAgY29uc3QgY2VudGVyID0gcGFpbnRlci50cmFuc2Zvcm0ucG9pbnRNZXJjO1xuICAgICAgICAgICAgaW1wbGVtZW50YXRpb24ucmVuZGVyKGNvbnRleHQuZ2wsIHBhaW50ZXIudHJhbnNmb3JtLmN1c3RvbUxheWVyTWF0cml4KCksIHBhaW50ZXIudHJhbnNmb3JtLmdldFByb2plY3Rpb24oKSwgcGFpbnRlci50cmFuc2Zvcm0uZ2xvYmVUb01lcmNhdG9yTWF0cml4KCksIGdsb2JlVG9NZXJjYXRvclRyYW5zaXRpb24ocGFpbnRlci50cmFuc2Zvcm0uem9vbSksIFtjZW50ZXIueCwgY2VudGVyLnldLCBwYWludGVyLnRyYW5zZm9ybS5waXhlbHNQZXJNZXRlclJhdGlvKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGltcGxlbWVudGF0aW9uLnJlbmRlcihjb250ZXh0LmdsLCBwYWludGVyLnRyYW5zZm9ybS5jdXN0b21MYXllck1hdHJpeCgpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRleHQuc2V0RGlydHkoKTtcbiAgICAgICAgcGFpbnRlci5zZXRCYXNlU3RhdGUoKTtcbiAgICAgICAgY29udGV4dC5iaW5kRnJhbWVidWZmZXIuc2V0KG51bGwpO1xuICAgIH1cbn1cbiIsIi8vIEBmbG93XG5pbXBvcnQge2NyZWF0ZUxheW91dH0gZnJvbSAnLi4vdXRpbC9zdHJ1Y3RfYXJyYXkuanMnO1xuXG5pbXBvcnQgdHlwZSB7U3RydWN0QXJyYXlMYXlvdXR9IGZyb20gJy4uL3V0aWwvc3RydWN0X2FycmF5LmpzJztcblxuZXhwb3J0IGNvbnN0IHNreWJveEF0dHJpYnV0ZXM6IFN0cnVjdEFycmF5TGF5b3V0ID0gY3JlYXRlTGF5b3V0KFtcbiAgICB7bmFtZTogJ2FfcG9zXzNmJywgIGNvbXBvbmVudHM6IDMsIHR5cGU6ICdGbG9hdDMyJ31cbl0pO1xuXG5leHBvcnQgZGVmYXVsdCBza3lib3hBdHRyaWJ1dGVzO1xuZXhwb3J0IGNvbnN0IHttZW1iZXJzLCBzaXplLCBhbGlnbm1lbnR9ID0gc2t5Ym94QXR0cmlidXRlcztcbiIsIi8vIEBmbG93XG5cbmltcG9ydCB7bWVtYmVycyBhcyBza3lib3hBdHRyaWJ1dGVzfSBmcm9tICcuL3NreWJveF9hdHRyaWJ1dGVzLmpzJztcbmltcG9ydCB7U2t5Ym94VmVydGV4QXJyYXksIFRyaWFuZ2xlSW5kZXhBcnJheX0gZnJvbSAnLi4vZGF0YS9hcnJheV90eXBlcy5qcyc7XG5pbXBvcnQgU2VnbWVudFZlY3RvciBmcm9tICcuLi9kYXRhL3NlZ21lbnQuanMnO1xuaW1wb3J0IHR5cGUgSW5kZXhCdWZmZXIgZnJvbSAnLi4vZ2wvaW5kZXhfYnVmZmVyLmpzJztcbmltcG9ydCB0eXBlIFZlcnRleEJ1ZmZlciBmcm9tICcuLi9nbC92ZXJ0ZXhfYnVmZmVyLmpzJztcbmltcG9ydCB0eXBlIENvbnRleHQgZnJvbSAnLi4vZ2wvY29udGV4dC5qcyc7XG5cbmZ1bmN0aW9uIGFkZFZlcnRleCh2ZXJ0ZXhBcnJheTogU2t5Ym94VmVydGV4QXJyYXksIHg6IG51bWJlciwgeTogbnVtYmVyLCB6OiBudW1iZXIpIHtcbiAgICB2ZXJ0ZXhBcnJheS5lbXBsYWNlQmFjayhcbiAgICAgICAgLy8gYV9wb3NcbiAgICAgICAgeCxcbiAgICAgICAgeSxcbiAgICAgICAgelxuICAgICk7XG59XG5cbmNsYXNzIFNreWJveEdlb21ldHJ5IHtcbiAgICB2ZXJ0ZXhBcnJheTogU2t5Ym94VmVydGV4QXJyYXk7XG4gICAgdmVydGV4QnVmZmVyOiBWZXJ0ZXhCdWZmZXI7XG4gICAgaW5kaWNlczogVHJpYW5nbGVJbmRleEFycmF5O1xuICAgIGluZGV4QnVmZmVyOiBJbmRleEJ1ZmZlcjtcbiAgICBzZWdtZW50OiBTZWdtZW50VmVjdG9yO1xuXG4gICAgY29uc3RydWN0b3IoY29udGV4dDogQ29udGV4dCkge1xuICAgICAgICB0aGlzLnZlcnRleEFycmF5ID0gbmV3IFNreWJveFZlcnRleEFycmF5KCk7XG4gICAgICAgIHRoaXMuaW5kaWNlcyA9IG5ldyBUcmlhbmdsZUluZGV4QXJyYXkoKTtcblxuICAgICAgICBhZGRWZXJ0ZXgodGhpcy52ZXJ0ZXhBcnJheSwgLTEuMCwgLTEuMCwgIDEuMCk7XG4gICAgICAgIGFkZFZlcnRleCh0aGlzLnZlcnRleEFycmF5LCAgMS4wLCAtMS4wLCAgMS4wKTtcbiAgICAgICAgYWRkVmVydGV4KHRoaXMudmVydGV4QXJyYXksIC0xLjAsICAxLjAsICAxLjApO1xuICAgICAgICBhZGRWZXJ0ZXgodGhpcy52ZXJ0ZXhBcnJheSwgIDEuMCwgIDEuMCwgIDEuMCk7XG4gICAgICAgIGFkZFZlcnRleCh0aGlzLnZlcnRleEFycmF5LCAtMS4wLCAtMS4wLCAtMS4wKTtcbiAgICAgICAgYWRkVmVydGV4KHRoaXMudmVydGV4QXJyYXksICAxLjAsIC0xLjAsIC0xLjApO1xuICAgICAgICBhZGRWZXJ0ZXgodGhpcy52ZXJ0ZXhBcnJheSwgLTEuMCwgIDEuMCwgLTEuMCk7XG4gICAgICAgIGFkZFZlcnRleCh0aGlzLnZlcnRleEFycmF5LCAgMS4wLCAgMS4wLCAtMS4wKTtcblxuICAgICAgICAvLyAreFxuICAgICAgICB0aGlzLmluZGljZXMuZW1wbGFjZUJhY2soNSwgMSwgMyk7XG4gICAgICAgIHRoaXMuaW5kaWNlcy5lbXBsYWNlQmFjaygzLCA3LCA1KTtcbiAgICAgICAgLy8gLXhcbiAgICAgICAgdGhpcy5pbmRpY2VzLmVtcGxhY2VCYWNrKDYsIDIsIDApO1xuICAgICAgICB0aGlzLmluZGljZXMuZW1wbGFjZUJhY2soMCwgNCwgNik7XG4gICAgICAgIC8vICt5XG4gICAgICAgIHRoaXMuaW5kaWNlcy5lbXBsYWNlQmFjaygyLCA2LCA3KTtcbiAgICAgICAgdGhpcy5pbmRpY2VzLmVtcGxhY2VCYWNrKDcsIDMsIDIpO1xuICAgICAgICAvLyAteVxuICAgICAgICB0aGlzLmluZGljZXMuZW1wbGFjZUJhY2soNSwgNCwgMCk7XG4gICAgICAgIHRoaXMuaW5kaWNlcy5lbXBsYWNlQmFjaygwLCAxLCA1KTtcbiAgICAgICAgLy8gK3pcbiAgICAgICAgdGhpcy5pbmRpY2VzLmVtcGxhY2VCYWNrKDAsIDIsIDMpO1xuICAgICAgICB0aGlzLmluZGljZXMuZW1wbGFjZUJhY2soMywgMSwgMCk7XG4gICAgICAgIC8vIC16XG4gICAgICAgIHRoaXMuaW5kaWNlcy5lbXBsYWNlQmFjayg3LCA2LCA0KTtcbiAgICAgICAgdGhpcy5pbmRpY2VzLmVtcGxhY2VCYWNrKDQsIDUsIDcpO1xuXG4gICAgICAgIHRoaXMudmVydGV4QnVmZmVyID0gY29udGV4dC5jcmVhdGVWZXJ0ZXhCdWZmZXIodGhpcy52ZXJ0ZXhBcnJheSwgc2t5Ym94QXR0cmlidXRlcyk7XG4gICAgICAgIHRoaXMuaW5kZXhCdWZmZXIgPSBjb250ZXh0LmNyZWF0ZUluZGV4QnVmZmVyKHRoaXMuaW5kaWNlcyk7XG5cbiAgICAgICAgdGhpcy5zZWdtZW50ID0gU2VnbWVudFZlY3Rvci5zaW1wbGVTZWdtZW50KDAsIDAsIDM2LCAxMik7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBTa3lib3hHZW9tZXRyeTtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCBTdGVuY2lsTW9kZSBmcm9tICcuLi9nbC9zdGVuY2lsX21vZGUuanMnO1xuaW1wb3J0IERlcHRoTW9kZSBmcm9tICcuLi9nbC9kZXB0aF9tb2RlLmpzJztcbmltcG9ydCBDb2xvck1vZGUgZnJvbSAnLi4vZ2wvY29sb3JfbW9kZS5qcyc7XG5pbXBvcnQgQ3VsbEZhY2VNb2RlIGZyb20gJy4uL2dsL2N1bGxfZmFjZV9tb2RlLmpzJztcbmltcG9ydCBDb250ZXh0IGZyb20gJy4uL2dsL2NvbnRleHQuanMnO1xuaW1wb3J0IFRleHR1cmUgZnJvbSAnLi90ZXh0dXJlLmpzJztcbmltcG9ydCBQcm9ncmFtIGZyb20gJy4vcHJvZ3JhbS5qcyc7XG5pbXBvcnQge3Ntb290aHN0ZXB9IGZyb20gJy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQgdHlwZSBTb3VyY2VDYWNoZSBmcm9tICcuLi9zb3VyY2Uvc291cmNlX2NhY2hlLmpzJztcbmltcG9ydCBTa3lib3hHZW9tZXRyeSBmcm9tICcuL3NreWJveF9nZW9tZXRyeS5qcyc7XG5pbXBvcnQge3NreWJveFVuaWZvcm1WYWx1ZXMsIHNreWJveEdyYWRpZW50VW5pZm9ybVZhbHVlc30gZnJvbSAnLi9wcm9ncmFtL3NreWJveF9wcm9ncmFtLmpzJztcbmltcG9ydCB7c2t5Ym94Q2FwdHVyZVVuaWZvcm1WYWx1ZXN9IGZyb20gJy4vcHJvZ3JhbS9za3lib3hfY2FwdHVyZV9wcm9ncmFtLmpzJztcbmltcG9ydCBTa3lMYXllciBmcm9tICcuLi9zdHlsZS9zdHlsZV9sYXllci9za3lfc3R5bGVfbGF5ZXIuanMnO1xuaW1wb3J0IHR5cGUgUGFpbnRlciBmcm9tICcuL3BhaW50ZXIuanMnO1xuaW1wb3J0IHttYXQzLCBtYXQ0fSBmcm9tICdnbC1tYXRyaXgnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuXG5pbXBvcnQgdHlwZSB7TWF0NH0gZnJvbSAnZ2wtbWF0cml4JztcblxuZXhwb3J0IGRlZmF1bHQgZHJhd1NreTtcblxuY29uc3QgVFJBTlNJVElPTl9PUEFDSVRZX1pPT01fU1RBUlQgPSA3O1xuY29uc3QgVFJBTlNJVElPTl9PUEFDSVRZX1pPT01fRU5EID0gODtcblxuZnVuY3Rpb24gZHJhd1NreShwYWludGVyOiBQYWludGVyLCBzb3VyY2VDYWNoZTogU291cmNlQ2FjaGUsIGxheWVyOiBTa3lMYXllcikge1xuICAgIGNvbnN0IHRyID0gcGFpbnRlci50cmFuc2Zvcm07XG4gICAgY29uc3QgZ2xvYmVPck1lcmNhdG9yID0gKHRyLnByb2plY3Rpb24ubmFtZSA9PT0gJ21lcmNhdG9yJyB8fCB0ci5wcm9qZWN0aW9uLm5hbWUgPT09ICdnbG9iZScpO1xuICAgIC8vIEZvciBub24tbWVyY2F0b3IgcHJvamVjdGlvbiwgdXNlIGEgZm9yY2VkIG9wYWNpdHkgdHJhbnNpdGlvbi4gVGhpcyB0cmFuc2l0aW9uIGlzIHNldCB0byBiZVxuICAgIC8vIDEuMCBhZnRlciB0aGUgc2hlZXIgYWRqdXN0bWVudCB1cHBlciBib3VuZCB3aGljaCBlbnN1cmVzIHRvIGJlIGluIHRoZSBtZXJjYXRvciBwcm9qZWN0aW9uLlxuICAgIC8vIE5vdGU6IHdlIG9ubHkgcmVuZGVyIHNreSBmb3IgZ2xvYmUgcHJvamVjdGlvbiBkdXJpbmcgdGhlIHRyYW5zaXRpb24gdG8gbWVyY2F0b3IuXG4gICAgY29uc3QgdHJhbnNpdGlvbk9wYWNpdHkgPSBnbG9iZU9yTWVyY2F0b3IgPyAxLjAgOiBzbW9vdGhzdGVwKFRSQU5TSVRJT05fT1BBQ0lUWV9aT09NX1NUQVJULCBUUkFOU0lUSU9OX09QQUNJVFlfWk9PTV9FTkQsIHRyLnpvb20pO1xuICAgIGNvbnN0IG9wYWNpdHkgPSBsYXllci5wYWludC5nZXQoJ3NreS1vcGFjaXR5JykgKiB0cmFuc2l0aW9uT3BhY2l0eTtcbiAgICBpZiAob3BhY2l0eSA9PT0gMCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY29udGV4dCA9IHBhaW50ZXIuY29udGV4dDtcbiAgICBjb25zdCB0eXBlID0gbGF5ZXIucGFpbnQuZ2V0KCdza3ktdHlwZScpO1xuICAgIGNvbnN0IGRlcHRoTW9kZSA9IG5ldyBEZXB0aE1vZGUoY29udGV4dC5nbC5MRVFVQUwsIERlcHRoTW9kZS5SZWFkT25seSwgWzAsIDFdKTtcbiAgICBjb25zdCB0ZW1wb3JhbE9mZnNldCA9IChwYWludGVyLmZyYW1lQ291bnRlciAvIDEwMDAuMCkgJSAxO1xuXG4gICAgaWYgKHR5cGUgPT09ICdhdG1vc3BoZXJlJykge1xuICAgICAgICBpZiAocGFpbnRlci5yZW5kZXJQYXNzID09PSAnb2Zmc2NyZWVuJykge1xuICAgICAgICAgICAgaWYgKGxheWVyLm5lZWRzU2t5Ym94Q2FwdHVyZShwYWludGVyKSkge1xuICAgICAgICAgICAgICAgIGNhcHR1cmVTa3lib3gocGFpbnRlciwgbGF5ZXIsIDMyLCAzMik7XG4gICAgICAgICAgICAgICAgbGF5ZXIubWFya1NreWJveFZhbGlkKHBhaW50ZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHBhaW50ZXIucmVuZGVyUGFzcyA9PT0gJ3NreScpIHtcbiAgICAgICAgICAgIGRyYXdTa3lib3hGcm9tQ2FwdHVyZShwYWludGVyLCBsYXllciwgZGVwdGhNb2RlLCBvcGFjaXR5LCB0ZW1wb3JhbE9mZnNldCk7XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdncmFkaWVudCcpIHtcbiAgICAgICAgaWYgKHBhaW50ZXIucmVuZGVyUGFzcyA9PT0gJ3NreScpIHtcbiAgICAgICAgICAgIGRyYXdTa3lib3hHcmFkaWVudChwYWludGVyLCBsYXllciwgZGVwdGhNb2RlLCBvcGFjaXR5LCB0ZW1wb3JhbE9mZnNldCk7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBhc3NlcnQoZmFsc2UsIGAke3R5cGV9IGlzIHVuc3VwcG9ydGVkIHNreS10eXBlYCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkcmF3U2t5Ym94R3JhZGllbnQocGFpbnRlcjogUGFpbnRlciwgbGF5ZXI6IFNreUxheWVyLCBkZXB0aE1vZGU6IERlcHRoTW9kZSwgb3BhY2l0eTogbnVtYmVyLCB0ZW1wb3JhbE9mZnNldDogbnVtYmVyKSB7XG4gICAgY29uc3QgY29udGV4dCA9IHBhaW50ZXIuY29udGV4dDtcbiAgICBjb25zdCBnbCA9IGNvbnRleHQuZ2w7XG4gICAgY29uc3QgdHJhbnNmb3JtID0gcGFpbnRlci50cmFuc2Zvcm07XG4gICAgY29uc3QgcHJvZ3JhbSA9IHBhaW50ZXIudXNlUHJvZ3JhbSgnc2t5Ym94R3JhZGllbnQnKTtcblxuICAgIC8vIExhemlseSBpbml0aWFsaXplIGdlb21ldHJ5IGFuZCB0ZXh0dXJlIGlmIHRoZXkgaGF2ZW50IGJlZW4gY3JlYXRlZCB5ZXQuXG4gICAgaWYgKCFsYXllci5za3lib3hHZW9tZXRyeSkge1xuICAgICAgICBsYXllci5za3lib3hHZW9tZXRyeSA9IG5ldyBTa3lib3hHZW9tZXRyeShjb250ZXh0KTtcbiAgICB9XG4gICAgY29udGV4dC5hY3RpdmVUZXh0dXJlLnNldChnbC5URVhUVVJFMCk7XG4gICAgbGV0IGNvbG9yUmFtcFRleHR1cmUgPSBsYXllci5jb2xvclJhbXBUZXh0dXJlO1xuICAgIGlmICghY29sb3JSYW1wVGV4dHVyZSkge1xuICAgICAgICBjb2xvclJhbXBUZXh0dXJlID0gbGF5ZXIuY29sb3JSYW1wVGV4dHVyZSA9IG5ldyBUZXh0dXJlKGNvbnRleHQsIGxheWVyLmNvbG9yUmFtcCwgZ2wuUkdCQSk7XG4gICAgfVxuICAgIGNvbG9yUmFtcFRleHR1cmUuYmluZChnbC5MSU5FQVIsIGdsLkNMQU1QX1RPX0VER0UpO1xuICAgIGNvbnN0IHVuaWZvcm1WYWx1ZXMgPSBza3lib3hHcmFkaWVudFVuaWZvcm1WYWx1ZXMoXG4gICAgICAgIHRyYW5zZm9ybS5za3lib3hNYXRyaXgsXG4gICAgICAgIGxheWVyLmdldENlbnRlcihwYWludGVyLCBmYWxzZSksXG4gICAgICAgIGxheWVyLnBhaW50LmdldCgnc2t5LWdyYWRpZW50LXJhZGl1cycpLFxuICAgICAgICBvcGFjaXR5LFxuICAgICAgICB0ZW1wb3JhbE9mZnNldFxuICAgICk7XG5cbiAgICBwYWludGVyLnByZXBhcmVEcmF3UHJvZ3JhbShjb250ZXh0LCBwcm9ncmFtKTtcblxuICAgIHByb2dyYW0uZHJhdyhjb250ZXh0LCBnbC5UUklBTkdMRVMsIGRlcHRoTW9kZSwgU3RlbmNpbE1vZGUuZGlzYWJsZWQsXG4gICAgICAgIHBhaW50ZXIuY29sb3JNb2RlRm9yUmVuZGVyUGFzcygpLCBDdWxsRmFjZU1vZGUuYmFja0NXLFxuICAgICAgICB1bmlmb3JtVmFsdWVzLCAnc2t5Ym94R3JhZGllbnQnLCBsYXllci5za3lib3hHZW9tZXRyeS52ZXJ0ZXhCdWZmZXIsXG4gICAgICAgIGxheWVyLnNreWJveEdlb21ldHJ5LmluZGV4QnVmZmVyLCBsYXllci5za3lib3hHZW9tZXRyeS5zZWdtZW50KTtcbn1cblxuZnVuY3Rpb24gZHJhd1NreWJveEZyb21DYXB0dXJlKHBhaW50ZXI6IFBhaW50ZXIsIGxheWVyOiBTa3lMYXllciwgZGVwdGhNb2RlOiBEZXB0aE1vZGUsIG9wYWNpdHk6IG51bWJlciwgdGVtcG9yYWxPZmZzZXQ6IG51bWJlcikge1xuICAgIGNvbnN0IGNvbnRleHQgPSBwYWludGVyLmNvbnRleHQ7XG4gICAgY29uc3QgZ2wgPSBjb250ZXh0LmdsO1xuICAgIGNvbnN0IHRyYW5zZm9ybSA9IHBhaW50ZXIudHJhbnNmb3JtO1xuICAgIGNvbnN0IHByb2dyYW0gPSBwYWludGVyLnVzZVByb2dyYW0oJ3NreWJveCcpO1xuXG4gICAgY29udGV4dC5hY3RpdmVUZXh0dXJlLnNldChnbC5URVhUVVJFMCk7XG5cbiAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFX0NVQkVfTUFQLCBsYXllci5za3lib3hUZXh0dXJlKTtcblxuICAgIGNvbnN0IHVuaWZvcm1WYWx1ZXMgPSBza3lib3hVbmlmb3JtVmFsdWVzKHRyYW5zZm9ybS5za3lib3hNYXRyaXgsIGxheWVyLmdldENlbnRlcihwYWludGVyLCBmYWxzZSksIDAsIG9wYWNpdHksIHRlbXBvcmFsT2Zmc2V0KTtcblxuICAgIHBhaW50ZXIucHJlcGFyZURyYXdQcm9ncmFtKGNvbnRleHQsIHByb2dyYW0pO1xuXG4gICAgcHJvZ3JhbS5kcmF3KGNvbnRleHQsIGdsLlRSSUFOR0xFUywgZGVwdGhNb2RlLCBTdGVuY2lsTW9kZS5kaXNhYmxlZCxcbiAgICAgICAgcGFpbnRlci5jb2xvck1vZGVGb3JSZW5kZXJQYXNzKCksIEN1bGxGYWNlTW9kZS5iYWNrQ1csXG4gICAgICAgIHVuaWZvcm1WYWx1ZXMsICdza3lib3gnLCBsYXllci5za3lib3hHZW9tZXRyeS52ZXJ0ZXhCdWZmZXIsXG4gICAgICAgIGxheWVyLnNreWJveEdlb21ldHJ5LmluZGV4QnVmZmVyLCBsYXllci5za3lib3hHZW9tZXRyeS5zZWdtZW50KTtcbn1cblxuZnVuY3Rpb24gZHJhd1NreWJveEZhY2UoY29udGV4dDogQ29udGV4dCwgbGF5ZXI6IFNreUxheWVyLCBwcm9ncmFtOiBQcm9ncmFtPGFueT4sIGZhY2VSb3RhdGU6IE1hdDQsIHN1bkRpcmVjdGlvbjogW251bWJlciwgbnVtYmVyLCBudW1iZXJdLCBpOiBudW1iZXIpIHtcbiAgICBjb25zdCBnbCA9IGNvbnRleHQuZ2w7XG5cbiAgICBjb25zdCBhdG1vc3BoZXJlQ29sb3IgPSBsYXllci5wYWludC5nZXQoJ3NreS1hdG1vc3BoZXJlLWNvbG9yJyk7XG4gICAgY29uc3QgYXRtb3NwaGVyZUhhbG9Db2xvciA9IGxheWVyLnBhaW50LmdldCgnc2t5LWF0bW9zcGhlcmUtaGFsby1jb2xvcicpO1xuICAgIGNvbnN0IHN1bkludGVuc2l0eSA9IGxheWVyLnBhaW50LmdldCgnc2t5LWF0bW9zcGhlcmUtc3VuLWludGVuc2l0eScpO1xuXG4gICAgY29uc3QgdW5pZm9ybVZhbHVlcyA9IHNreWJveENhcHR1cmVVbmlmb3JtVmFsdWVzKFxuICAgICAgICBtYXQzLmZyb21NYXQ0KG1hdDMuY3JlYXRlKCksIGZhY2VSb3RhdGUpLFxuICAgICAgICBzdW5EaXJlY3Rpb24sXG4gICAgICAgIHN1bkludGVuc2l0eSxcbiAgICAgICAgYXRtb3NwaGVyZUNvbG9yLFxuICAgICAgICBhdG1vc3BoZXJlSGFsb0NvbG9yKTtcblxuICAgIGNvbnN0IGdsRmFjZSA9IGdsLlRFWFRVUkVfQ1VCRV9NQVBfUE9TSVRJVkVfWCArIGk7XG4gICAgZ2wuZnJhbWVidWZmZXJUZXh0dXJlMkQoZ2wuRlJBTUVCVUZGRVIsIGdsLkNPTE9SX0FUVEFDSE1FTlQwLCBnbEZhY2UsIGxheWVyLnNreWJveFRleHR1cmUsIDApO1xuXG4gICAgcHJvZ3JhbS5kcmF3KGNvbnRleHQsIGdsLlRSSUFOR0xFUywgRGVwdGhNb2RlLmRpc2FibGVkLCBTdGVuY2lsTW9kZS5kaXNhYmxlZCwgQ29sb3JNb2RlLnVuYmxlbmRlZCwgQ3VsbEZhY2VNb2RlLmZyb250Q1csXG4gICAgICAgIHVuaWZvcm1WYWx1ZXMsICdza3lib3hDYXB0dXJlJywgbGF5ZXIuc2t5Ym94R2VvbWV0cnkudmVydGV4QnVmZmVyLFxuICAgICAgICBsYXllci5za3lib3hHZW9tZXRyeS5pbmRleEJ1ZmZlciwgbGF5ZXIuc2t5Ym94R2VvbWV0cnkuc2VnbWVudCk7XG59XG5cbmZ1bmN0aW9uIGNhcHR1cmVTa3lib3gocGFpbnRlcjogUGFpbnRlciwgbGF5ZXI6IFNreUxheWVyLCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIGNvbnN0IGNvbnRleHQgPSBwYWludGVyLmNvbnRleHQ7XG4gICAgY29uc3QgZ2wgPSBjb250ZXh0LmdsO1xuICAgIGxldCBmYm8gPSBsYXllci5za3lib3hGYm87XG5cbiAgICAvLyBVc2luZyBhYnNlbmNlIG9mIGZibyBhcyBhIHNpZ25hbCBmb3IgbGF6eSBpbml0aWFsaXphdGlvbiBvZiBhbGwgcmVzb3VyY2VzLCBjYWNoZSByZXNvdXJjZXMgaW4gbGF5ZXIgb2JqZWN0XG4gICAgaWYgKCFmYm8pIHtcbiAgICAgICAgZmJvID0gbGF5ZXIuc2t5Ym94RmJvID0gY29udGV4dC5jcmVhdGVGcmFtZWJ1ZmZlcih3aWR0aCwgaGVpZ2h0LCBmYWxzZSk7XG4gICAgICAgIGxheWVyLnNreWJveEdlb21ldHJ5ID0gbmV3IFNreWJveEdlb21ldHJ5KGNvbnRleHQpO1xuICAgICAgICBsYXllci5za3lib3hUZXh0dXJlID0gY29udGV4dC5nbC5jcmVhdGVUZXh0dXJlKCk7XG5cbiAgICAgICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV9DVUJFX01BUCwgbGF5ZXIuc2t5Ym94VGV4dHVyZSk7XG4gICAgICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV9DVUJFX01BUCwgZ2wuVEVYVFVSRV9XUkFQX1MsIGdsLkNMQU1QX1RPX0VER0UpO1xuICAgICAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfQ1VCRV9NQVAsIGdsLlRFWFRVUkVfV1JBUF9ULCBnbC5DTEFNUF9UT19FREdFKTtcbiAgICAgICAgZ2wudGV4UGFyYW1ldGVyaShnbC5URVhUVVJFX0NVQkVfTUFQLCBnbC5URVhUVVJFX01JTl9GSUxURVIsIGdsLkxJTkVBUik7XG4gICAgICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV9DVUJFX01BUCwgZ2wuVEVYVFVSRV9NQUdfRklMVEVSLCBnbC5MSU5FQVIpO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgNjsgKytpKSB7XG4gICAgICAgICAgICBjb25zdCBnbEZhY2UgPSBnbC5URVhUVVJFX0NVQkVfTUFQX1BPU0lUSVZFX1ggKyBpO1xuXG4gICAgICAgICAgICAvLyBUaGUgZm9ybWF0IGhlcmUgY291bGQgYmUgUkdCLCBidXQgcmVuZGVyIHRlc3RzIGFyZSBub3QgaGFwcHkgd2l0aCByZW5kZXJpbmcgdG8gc3VjaCBhIGZvcm1hdFxuICAgICAgICAgICAgZ2wudGV4SW1hZ2UyRChnbEZhY2UsIDAsIGdsLlJHQkEsIHdpZHRoLCBoZWlnaHQsIDAsIGdsLlJHQkEsIGdsLlVOU0lHTkVEX0JZVEUsIG51bGwpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY29udGV4dC5iaW5kRnJhbWVidWZmZXIuc2V0KGZiby5mcmFtZWJ1ZmZlcik7XG4gICAgY29udGV4dC52aWV3cG9ydC5zZXQoWzAsIDAsIHdpZHRoLCBoZWlnaHRdKTtcblxuICAgIGNvbnN0IHN1bkRpcmVjdGlvbiA9IGxheWVyLmdldENlbnRlcihwYWludGVyLCB0cnVlKTtcbiAgICBjb25zdCBwcm9ncmFtID0gcGFpbnRlci51c2VQcm9ncmFtKCdza3lib3hDYXB0dXJlJyk7XG4gICAgY29uc3QgZmFjZVJvdGF0ZSA9IG5ldyBGbG9hdDY0QXJyYXkoMTYpO1xuXG4gICAgLy8gK3g7XG4gICAgbWF0NC5pZGVudGl0eShmYWNlUm90YXRlKTtcbiAgICBtYXQ0LnJvdGF0ZVkoZmFjZVJvdGF0ZSwgZmFjZVJvdGF0ZSwgLU1hdGguUEkgKiAwLjUpO1xuICAgIGRyYXdTa3lib3hGYWNlKGNvbnRleHQsIGxheWVyLCBwcm9ncmFtLCBmYWNlUm90YXRlLCBzdW5EaXJlY3Rpb24sIDApO1xuICAgIC8vIC14XG4gICAgbWF0NC5pZGVudGl0eShmYWNlUm90YXRlKTtcbiAgICBtYXQ0LnJvdGF0ZVkoZmFjZVJvdGF0ZSwgZmFjZVJvdGF0ZSwgTWF0aC5QSSAqIDAuNSk7XG4gICAgZHJhd1NreWJveEZhY2UoY29udGV4dCwgbGF5ZXIsIHByb2dyYW0sIGZhY2VSb3RhdGUsIHN1bkRpcmVjdGlvbiwgMSk7XG4gICAgLy8gK3lcbiAgICBtYXQ0LmlkZW50aXR5KGZhY2VSb3RhdGUpO1xuICAgIG1hdDQucm90YXRlWChmYWNlUm90YXRlLCBmYWNlUm90YXRlLCAtTWF0aC5QSSAqIDAuNSk7XG4gICAgZHJhd1NreWJveEZhY2UoY29udGV4dCwgbGF5ZXIsIHByb2dyYW0sIGZhY2VSb3RhdGUsIHN1bkRpcmVjdGlvbiwgMik7XG4gICAgLy8gLXlcbiAgICBtYXQ0LmlkZW50aXR5KGZhY2VSb3RhdGUpO1xuICAgIG1hdDQucm90YXRlWChmYWNlUm90YXRlLCBmYWNlUm90YXRlLCBNYXRoLlBJICogMC41KTtcbiAgICBkcmF3U2t5Ym94RmFjZShjb250ZXh0LCBsYXllciwgcHJvZ3JhbSwgZmFjZVJvdGF0ZSwgc3VuRGlyZWN0aW9uLCAzKTtcbiAgICAvLyArelxuICAgIG1hdDQuaWRlbnRpdHkoZmFjZVJvdGF0ZSk7XG4gICAgZHJhd1NreWJveEZhY2UoY29udGV4dCwgbGF5ZXIsIHByb2dyYW0sIGZhY2VSb3RhdGUsIHN1bkRpcmVjdGlvbiwgNCk7XG4gICAgLy8gLXpcbiAgICBtYXQ0LmlkZW50aXR5KGZhY2VSb3RhdGUpO1xuICAgIG1hdDQucm90YXRlWShmYWNlUm90YXRlLCBmYWNlUm90YXRlLCBNYXRoLlBJKTtcbiAgICBkcmF3U2t5Ym94RmFjZShjb250ZXh0LCBsYXllciwgcHJvZ3JhbSwgZmFjZVJvdGF0ZSwgc3VuRGlyZWN0aW9uLCA1KTtcblxuICAgIGNvbnRleHQudmlld3BvcnQuc2V0KFswLCAwLCBwYWludGVyLndpZHRoLCBwYWludGVyLmhlaWdodF0pO1xufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IFN0ZW5jaWxNb2RlIGZyb20gJy4uL2dsL3N0ZW5jaWxfbW9kZS5qcyc7XG5pbXBvcnQgRGVwdGhNb2RlIGZyb20gJy4uL2dsL2RlcHRoX21vZGUuanMnO1xuaW1wb3J0IENvbG9yTW9kZSBmcm9tICcuLi9nbC9jb2xvcl9tb2RlLmpzJztcbmltcG9ydCBDdWxsRmFjZU1vZGUgZnJvbSAnLi4vZ2wvY3VsbF9mYWNlX21vZGUuanMnO1xuaW1wb3J0IHtcbiAgICBnbG9iZVRvTWVyY2F0b3JUcmFuc2l0aW9uLFxuICAgIGdsb2JlVXNlQ3VzdG9tQW50aUFsaWFzaW5nXG59IGZyb20gJy4vLi4vZ2VvL3Byb2plY3Rpb24vZ2xvYmVfdXRpbC5qcyc7XG5pbXBvcnQge2F0bW9zcGhlcmVVbmlmb3JtVmFsdWVzfSBmcm9tICcuLi90ZXJyYWluL2dsb2JlX3Jhc3Rlcl9wcm9ncmFtLmpzJztcbmltcG9ydCB0eXBlIFBhaW50ZXIgZnJvbSAnLi9wYWludGVyLmpzJztcbmltcG9ydCB0eXBlIHtEeW5hbWljRGVmaW5lc1R5cGV9IGZyb20gJy4uL3JlbmRlci9wcm9ncmFtL3Byb2dyYW1fdW5pZm9ybXMuanMnO1xuaW1wb3J0IHtkZWdUb1JhZCwgbWFwVmFsdWV9IGZyb20gJy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQge3ZlYzMsIG1hdDQsIHF1YXR9IGZyb20gJ2dsLW1hdHJpeCc7XG5pbXBvcnQgRm9nIGZyb20gJy4uL3N0eWxlL2ZvZy5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGRyYXdBdG1vc3BoZXJlO1xuXG5mdW5jdGlvbiBkcmF3QXRtb3NwaGVyZShwYWludGVyOiBQYWludGVyLCBmb2c6IEZvZykge1xuICAgIGNvbnN0IGNvbnRleHQgPSBwYWludGVyLmNvbnRleHQ7XG4gICAgY29uc3QgZ2wgPSBjb250ZXh0LmdsO1xuICAgIGNvbnN0IHRyID0gcGFpbnRlci50cmFuc2Zvcm07XG4gICAgY29uc3QgZGVwdGhNb2RlID0gbmV3IERlcHRoTW9kZShnbC5MRVFVQUwsIERlcHRoTW9kZS5SZWFkT25seSwgWzAsIDFdKTtcbiAgICBjb25zdCBkZWZpbmVzID0gdHIucHJvamVjdGlvbi5uYW1lID09PSAnZ2xvYmUnID8gWydQUk9KRUNUSU9OX0dMT0JFX1ZJRVcnLCAnRk9HJ10gOiBbJ0ZPRyddO1xuICAgIGNvbnN0IHByb2dyYW0gPSBwYWludGVyLnVzZVByb2dyYW0oJ2dsb2JlQXRtb3NwaGVyZScsIG51bGwsICgoZGVmaW5lczogYW55KTogRHluYW1pY0RlZmluZXNUeXBlW10pKTtcblxuICAgIGNvbnN0IHRyYW5zaXRpb25UID0gZ2xvYmVUb01lcmNhdG9yVHJhbnNpdGlvbih0ci56b29tKTtcblxuICAgIGNvbnN0IGZvZ0NvbG9yID0gZm9nLnByb3BlcnRpZXMuZ2V0KCdjb2xvcicpLnRvQXJyYXkwMSgpO1xuICAgIGNvbnN0IGhpZ2hDb2xvciA9IGZvZy5wcm9wZXJ0aWVzLmdldCgnaGlnaC1jb2xvcicpLnRvQXJyYXkwMSgpO1xuICAgIGNvbnN0IHNwYWNlQ29sb3IgPSBmb2cucHJvcGVydGllcy5nZXQoJ3NwYWNlLWNvbG9yJykudG9BcnJheTAxUHJlbXVsdGlwbGllZEFscGhhKCk7XG5cbiAgICBjb25zdCBvcmllbnRhdGlvbiA9IHF1YXQuaWRlbnRpdHkoW10pO1xuXG4gICAgcXVhdC5yb3RhdGVZKG9yaWVudGF0aW9uLCBvcmllbnRhdGlvbiwgLWRlZ1RvUmFkKHRyLl9jZW50ZXIubG5nKSk7XG4gICAgcXVhdC5yb3RhdGVYKG9yaWVudGF0aW9uLCBvcmllbnRhdGlvbiwgZGVnVG9SYWQodHIuX2NlbnRlci5sYXQpKTtcblxuICAgIHF1YXQucm90YXRlWihvcmllbnRhdGlvbiwgb3JpZW50YXRpb24sIHRyLmFuZ2xlKTtcbiAgICBxdWF0LnJvdGF0ZVgob3JpZW50YXRpb24sIG9yaWVudGF0aW9uLCAtdHIuX3BpdGNoKTtcblxuICAgIGNvbnN0IHJvdGF0aW9uTWF0cml4ID0gbWF0NC5mcm9tUXVhdChuZXcgRmxvYXQzMkFycmF5KDE2KSwgb3JpZW50YXRpb24pO1xuXG4gICAgY29uc3Qgc3RhckludGVuc2l0eSA9IG1hcFZhbHVlKGZvZy5wcm9wZXJ0aWVzLmdldCgnc3Rhci1pbnRlbnNpdHknKSwgMC4wLCAxLjAsIDAuMCwgMC4yNSk7XG4gICAgLy8gaHR0cHM6Ly93d3cuZGVzbW9zLmNvbS9jYWxjdWxhdG9yL29hbnZ2cHIzNmRcbiAgICAvLyBFbnN1cmUgaG9yaXpvbiBibGVuZCBpcyAwLWV4Y2x1c2l2ZSB0byBwcmV2ZW50IGRpdmlzaW9uIGJ5IDAgaW4gdGhlIHNoYWRlclxuICAgIGNvbnN0IG1pbkhvcml6b25CbGVuZCA9IDAuMDAwNTtcbiAgICBjb25zdCBob3Jpem9uQmxlbmQgPSBtYXBWYWx1ZShmb2cucHJvcGVydGllcy5nZXQoJ2hvcml6b24tYmxlbmQnKSwgMC4wLCAxLjAsIG1pbkhvcml6b25CbGVuZCwgMC4yNSk7XG5cbiAgICAvLyBVc2UgYSBzbGlnaHRseSBzbWFsbGVyIHNpemUgb2YgdGhlIGdsb2JlIHRvIGFjY291bnQgZm9yIGN1c3RvbVxuICAgIC8vIGFudGlhbGlhc2luZyB0aGF0IHJlZHVjZXMgdGhlIHNpemUgb2YgdGhlIGdsb2JlIG9mIHR3byBwaXhlbHNcbiAgICAvLyBodHRwczovL3d3dy5kZXNtb3MuY29tL2NhbGN1bGF0b3IveHBnbXpnaGMzN1xuICAgIGNvbnN0IGdsb2JlUmFkaXVzID0gZ2xvYmVVc2VDdXN0b21BbnRpQWxpYXNpbmcocGFpbnRlciwgY29udGV4dCwgdHIpICYmIGhvcml6b25CbGVuZCA9PT0gbWluSG9yaXpvbkJsZW5kID9cbiAgICAgICAgdHIud29ybGRTaXplIC8gKDIuMCAqIE1hdGguUEkgKiAxLjAyNSkgLSAxLjAgOiB0ci5nbG9iZVJhZGl1cztcblxuICAgIGNvbnN0IHRlbXBvcmFsT2Zmc2V0ID0gKHBhaW50ZXIuZnJhbWVDb3VudGVyIC8gMTAwMC4wKSAlIDE7XG4gICAgY29uc3QgZ2xvYmVDZW50ZXJJblZpZXdTcGFjZSA9ICgoKHRyLmdsb2JlQ2VudGVySW5WaWV3U3BhY2UpOiBhbnkpOiBBcnJheTxudW1iZXI+KTtcbiAgICBjb25zdCBnbG9iZUNlbnRlckRpc3RhbmNlID0gdmVjMy5sZW5ndGgoZ2xvYmVDZW50ZXJJblZpZXdTcGFjZSk7XG4gICAgY29uc3QgZGlzdGFuY2VUb0hvcml6b24gPSBNYXRoLnNxcnQoTWF0aC5wb3coZ2xvYmVDZW50ZXJEaXN0YW5jZSwgMi4wKSAtIE1hdGgucG93KGdsb2JlUmFkaXVzLCAyLjApKTtcbiAgICBjb25zdCBob3Jpem9uQW5nbGUgPSBNYXRoLmFjb3MoZGlzdGFuY2VUb0hvcml6b24gLyBnbG9iZUNlbnRlckRpc3RhbmNlKTtcblxuICAgIGNvbnN0IHVuaWZvcm1zID0gYXRtb3NwaGVyZVVuaWZvcm1WYWx1ZXMoXG4gICAgICAgIHRyLmZydXN0dW1Db3JuZXJzLlRMLFxuICAgICAgICB0ci5mcnVzdHVtQ29ybmVycy5UUixcbiAgICAgICAgdHIuZnJ1c3R1bUNvcm5lcnMuQlIsXG4gICAgICAgIHRyLmZydXN0dW1Db3JuZXJzLkJMLFxuICAgICAgICB0ci5mcnVzdHVtQ29ybmVycy5ob3Jpem9uLFxuICAgICAgICB0cmFuc2l0aW9uVCxcbiAgICAgICAgaG9yaXpvbkJsZW5kLFxuICAgICAgICBmb2dDb2xvcixcbiAgICAgICAgaGlnaENvbG9yLFxuICAgICAgICBzcGFjZUNvbG9yLFxuICAgICAgICBzdGFySW50ZW5zaXR5LFxuICAgICAgICB0ZW1wb3JhbE9mZnNldCxcbiAgICAgICAgaG9yaXpvbkFuZ2xlLFxuICAgICAgICByb3RhdGlvbk1hdHJpeCk7XG5cbiAgICBwYWludGVyLnByZXBhcmVEcmF3UHJvZ3JhbShjb250ZXh0LCBwcm9ncmFtKTtcblxuICAgIGNvbnN0IGJ1ZmZlciA9IHBhaW50ZXIuYXRtb3NwaGVyZUJ1ZmZlcjtcbiAgICBpZiAoYnVmZmVyKSB7XG4gICAgICAgIHByb2dyYW0uZHJhdyhjb250ZXh0LCBnbC5UUklBTkdMRVMsIGRlcHRoTW9kZSwgU3RlbmNpbE1vZGUuZGlzYWJsZWQsXG4gICAgICAgICAgICBDb2xvck1vZGUuYWxwaGFCbGVuZGVkLCBDdWxsRmFjZU1vZGUuYmFja0NXLCB1bmlmb3JtcywgXCJza3lib3hcIixcbiAgICAgICAgICAgIGJ1ZmZlci52ZXJ0ZXhCdWZmZXIsIGJ1ZmZlci5pbmRleEJ1ZmZlciwgYnVmZmVyLnNlZ21lbnRzKTtcbiAgICB9XG59XG4iLCIvLyBAZmxvd1xuaW1wb3J0IHtjcmVhdGVMYXlvdXR9IGZyb20gJy4uL3V0aWwvc3RydWN0X2FycmF5LmpzJztcblxuaW1wb3J0IHR5cGUge1N0cnVjdEFycmF5TGF5b3V0fSBmcm9tICcuLi91dGlsL3N0cnVjdF9hcnJheS5qcyc7XG5cbmV4cG9ydCBjb25zdCBhdG1vc3BoZXJlTGF5b3V0OiBTdHJ1Y3RBcnJheUxheW91dCA9IGNyZWF0ZUxheW91dChbXG4gICAge3R5cGU6ICdGbG9hdDMyJywgbmFtZTogJ2FfcG9zJywgY29tcG9uZW50czogM30sXG4gICAge3R5cGU6ICdGbG9hdDMyJywgbmFtZTogJ2FfdXYnLCBjb21wb25lbnRzOiAyfVxuXSk7XG4iLCIvLyBAZmxvd1xuaW1wb3J0IHR5cGUgSW5kZXhCdWZmZXIgZnJvbSAnLi4vZ2wvaW5kZXhfYnVmZmVyLmpzJztcbmltcG9ydCB0eXBlIFZlcnRleEJ1ZmZlciBmcm9tICcuLi9nbC92ZXJ0ZXhfYnVmZmVyLmpzJztcbmltcG9ydCBTZWdtZW50VmVjdG9yIGZyb20gJy4uL2RhdGEvc2VnbWVudC5qcyc7XG5pbXBvcnQgdHlwZSBDb250ZXh0IGZyb20gJy4uL2dsL2NvbnRleHQuanMnO1xuaW1wb3J0IHthdG1vc3BoZXJlTGF5b3V0fSBmcm9tICcuL2F0bW9zcGhlcmVfYXR0cmlidXRlcy5qcyc7XG5pbXBvcnQge1RyaWFuZ2xlSW5kZXhBcnJheSwgQXRtb3NwaGVyZVZlcnRleEFycmF5fSBmcm9tICcuLi9kYXRhL2FycmF5X3R5cGVzLmpzJztcblxuZXhwb3J0IGNsYXNzIEF0bW9zcGhlcmVCdWZmZXIge1xuICAgIHZlcnRleEJ1ZmZlcjogVmVydGV4QnVmZmVyO1xuICAgIGluZGV4QnVmZmVyOiBJbmRleEJ1ZmZlcjtcbiAgICBzZWdtZW50czogU2VnbWVudFZlY3RvcjtcblxuICAgIGNvbnN0cnVjdG9yKGNvbnRleHQ6IENvbnRleHQpIHtcbiAgICAgICAgY29uc3QgdmVydGljZXMgPSBuZXcgQXRtb3NwaGVyZVZlcnRleEFycmF5KCk7XG4gICAgICAgIHZlcnRpY2VzLmVtcGxhY2VCYWNrKC0xLCAxLCAxLCAwLCAwKTtcbiAgICAgICAgdmVydGljZXMuZW1wbGFjZUJhY2soMSwgMSwgMSwgMSwgMCk7XG4gICAgICAgIHZlcnRpY2VzLmVtcGxhY2VCYWNrKDEsIC0xLCAxLCAxLCAxKTtcbiAgICAgICAgdmVydGljZXMuZW1wbGFjZUJhY2soLTEsIC0xLCAxLCAwLCAxKTtcblxuICAgICAgICBjb25zdCB0cmlhbmdsZXMgPSBuZXcgVHJpYW5nbGVJbmRleEFycmF5KCk7XG4gICAgICAgIHRyaWFuZ2xlcy5lbXBsYWNlQmFjaygwLCAxLCAyKTtcbiAgICAgICAgdHJpYW5nbGVzLmVtcGxhY2VCYWNrKDIsIDMsIDApO1xuXG4gICAgICAgIHRoaXMudmVydGV4QnVmZmVyID0gY29udGV4dC5jcmVhdGVWZXJ0ZXhCdWZmZXIodmVydGljZXMsIGF0bW9zcGhlcmVMYXlvdXQubWVtYmVycyk7XG4gICAgICAgIHRoaXMuaW5kZXhCdWZmZXIgPSBjb250ZXh0LmNyZWF0ZUluZGV4QnVmZmVyKHRyaWFuZ2xlcyk7XG4gICAgICAgIHRoaXMuc2VnbWVudHMgPSBTZWdtZW50VmVjdG9yLnNpbXBsZVNlZ21lbnQoMCwgMCwgNCwgMik7XG4gICAgfVxuXG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy52ZXJ0ZXhCdWZmZXIuZGVzdHJveSgpO1xuICAgICAgICB0aGlzLmluZGV4QnVmZmVyLmRlc3Ryb3koKTtcbiAgICAgICAgdGhpcy5zZWdtZW50cy5kZXN0cm95KCk7XG4gICAgfVxufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IGJyb3dzZXIgZnJvbSAnLi4vdXRpbC9icm93c2VyLmpzJztcbmltcG9ydCB3aW5kb3cgZnJvbSAnLi4vdXRpbC93aW5kb3cuanMnO1xuXG5pbXBvcnQge21hdDR9IGZyb20gJ2dsLW1hdHJpeCc7XG5pbXBvcnQgU291cmNlQ2FjaGUgZnJvbSAnLi4vc291cmNlL3NvdXJjZV9jYWNoZS5qcyc7XG5pbXBvcnQgRVhURU5UIGZyb20gJy4uL2RhdGEvZXh0ZW50LmpzJztcbmltcG9ydCBwaXhlbHNUb1RpbGVVbml0cyBmcm9tICcuLi9zb3VyY2UvcGl4ZWxzX3RvX3RpbGVfdW5pdHMuanMnO1xuaW1wb3J0IFNlZ21lbnRWZWN0b3IgZnJvbSAnLi4vZGF0YS9zZWdtZW50LmpzJztcbmltcG9ydCB7UG9zQXJyYXksIFRpbGVCb3VuZHNBcnJheSwgVHJpYW5nbGVJbmRleEFycmF5LCBMaW5lU3RyaXBJbmRleEFycmF5fSBmcm9tICcuLi9kYXRhL2FycmF5X3R5cGVzLmpzJztcbmltcG9ydCB7dmFsdWVzfSBmcm9tICcuLi91dGlsL3V0aWwuanMnO1xuaW1wb3J0IHtpc01hcEF1dGhlbnRpY2F0ZWR9IGZyb20gJy4uL3V0aWwvbWFwYm94LmpzJztcbmltcG9ydCBwb3NBdHRyaWJ1dGVzIGZyb20gJy4uL2RhdGEvcG9zX2F0dHJpYnV0ZXMuanMnO1xuaW1wb3J0IGJvdW5kc0F0dHJpYnV0ZXMgZnJvbSAnLi4vZGF0YS9ib3VuZHNfYXR0cmlidXRlcy5qcyc7XG5pbXBvcnQgUHJvZ3JhbUNvbmZpZ3VyYXRpb24gZnJvbSAnLi4vZGF0YS9wcm9ncmFtX2NvbmZpZ3VyYXRpb24uanMnO1xuaW1wb3J0IHNoYWRlcnMgZnJvbSAnLi4vc2hhZGVycy9zaGFkZXJzLmpzJztcbmltcG9ydCBQcm9ncmFtIGZyb20gJy4vcHJvZ3JhbS5qcyc7XG5pbXBvcnQge3Byb2dyYW1Vbmlmb3Jtc30gZnJvbSAnLi9wcm9ncmFtL3Byb2dyYW1fdW5pZm9ybXMuanMnO1xuaW1wb3J0IENvbnRleHQgZnJvbSAnLi4vZ2wvY29udGV4dC5qcyc7XG5pbXBvcnQge2ZvZ1VuaWZvcm1WYWx1ZXN9IGZyb20gJy4uL3JlbmRlci9mb2cuanMnO1xuaW1wb3J0IERlcHRoTW9kZSBmcm9tICcuLi9nbC9kZXB0aF9tb2RlLmpzJztcbmltcG9ydCBTdGVuY2lsTW9kZSBmcm9tICcuLi9nbC9zdGVuY2lsX21vZGUuanMnO1xuaW1wb3J0IENvbG9yTW9kZSBmcm9tICcuLi9nbC9jb2xvcl9tb2RlLmpzJztcbmltcG9ydCBDdWxsRmFjZU1vZGUgZnJvbSAnLi4vZ2wvY3VsbF9mYWNlX21vZGUuanMnO1xuaW1wb3J0IFRleHR1cmUgZnJvbSAnLi90ZXh0dXJlLmpzJztcbmltcG9ydCB7Y2xpcHBpbmdNYXNrVW5pZm9ybVZhbHVlc30gZnJvbSAnLi9wcm9ncmFtL2NsaXBwaW5nX21hc2tfcHJvZ3JhbS5qcyc7XG5pbXBvcnQgQ29sb3IgZnJvbSAnLi4vc3R5bGUtc3BlYy91dGlsL2NvbG9yLmpzJztcbmltcG9ydCBzeW1ib2wgZnJvbSAnLi9kcmF3X3N5bWJvbC5qcyc7XG5pbXBvcnQgY2lyY2xlIGZyb20gJy4vZHJhd19jaXJjbGUuanMnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IGhlYXRtYXAgZnJvbSAnLi9kcmF3X2hlYXRtYXAuanMnO1xuaW1wb3J0IGxpbmUgZnJvbSAnLi9kcmF3X2xpbmUuanMnO1xuaW1wb3J0IGZpbGwgZnJvbSAnLi9kcmF3X2ZpbGwuanMnO1xuaW1wb3J0IGZpbGxFeHRydXNpb24gZnJvbSAnLi9kcmF3X2ZpbGxfZXh0cnVzaW9uLmpzJztcbmltcG9ydCBoaWxsc2hhZGUgZnJvbSAnLi9kcmF3X2hpbGxzaGFkZS5qcyc7XG5pbXBvcnQgcmFzdGVyIGZyb20gJy4vZHJhd19yYXN0ZXIuanMnO1xuaW1wb3J0IGJhY2tncm91bmQgZnJvbSAnLi9kcmF3X2JhY2tncm91bmQuanMnO1xuaW1wb3J0IGRlYnVnLCB7ZHJhd0RlYnVnUGFkZGluZywgZHJhd0RlYnVnUXVlcnlHZW9tZXRyeX0gZnJvbSAnLi9kcmF3X2RlYnVnLmpzJztcbmltcG9ydCBjdXN0b20gZnJvbSAnLi9kcmF3X2N1c3RvbS5qcyc7XG5pbXBvcnQgc2t5IGZyb20gJy4vZHJhd19za3kuanMnO1xuaW1wb3J0IGRyYXdBdG1vc3BoZXJlIGZyb20gJy4vZHJhd19hdG1vc3BoZXJlLmpzJztcbmltcG9ydCB7R2xvYmVTaGFyZWRCdWZmZXJzLCBnbG9iZVRvTWVyY2F0b3JUcmFuc2l0aW9ufSBmcm9tICcuLi9nZW8vcHJvamVjdGlvbi9nbG9iZV91dGlsLmpzJztcbmltcG9ydCB7QXRtb3NwaGVyZUJ1ZmZlcn0gZnJvbSAnLi4vcmVuZGVyL2F0bW9zcGhlcmVfYnVmZmVyLmpzJztcbmltcG9ydCB7VGVycmFpbn0gZnJvbSAnLi4vdGVycmFpbi90ZXJyYWluLmpzJztcbmltcG9ydCB7RGVidWd9IGZyb20gJy4uL3V0aWwvZGVidWcuanMnO1xuaW1wb3J0IFRpbGUgZnJvbSAnLi4vc291cmNlL3RpbGUuanMnO1xuaW1wb3J0IHtSR0JBSW1hZ2V9IGZyb20gJy4uL3V0aWwvaW1hZ2UuanMnO1xuXG5jb25zdCBkcmF3ID0ge1xuICAgIHN5bWJvbCxcbiAgICBjaXJjbGUsXG4gICAgaGVhdG1hcCxcbiAgICBsaW5lLFxuICAgIGZpbGwsXG4gICAgJ2ZpbGwtZXh0cnVzaW9uJzogZmlsbEV4dHJ1c2lvbixcbiAgICBoaWxsc2hhZGUsXG4gICAgcmFzdGVyLFxuICAgIGJhY2tncm91bmQsXG4gICAgc2t5LFxuICAgIGRlYnVnLFxuICAgIGN1c3RvbVxufTtcblxuaW1wb3J0IHR5cGUgVHJhbnNmb3JtIGZyb20gJy4uL2dlby90cmFuc2Zvcm0uanMnO1xuaW1wb3J0IHR5cGUge092ZXJzY2FsZWRUaWxlSUQsIFVud3JhcHBlZFRpbGVJRH0gZnJvbSAnLi4vc291cmNlL3RpbGVfaWQuanMnO1xuaW1wb3J0IHR5cGUgU3R5bGUgZnJvbSAnLi4vc3R5bGUvc3R5bGUuanMnO1xuaW1wb3J0IHR5cGUgU3R5bGVMYXllciBmcm9tICcuLi9zdHlsZS9zdHlsZV9sYXllci5qcyc7XG5pbXBvcnQgdHlwZSBJbWFnZU1hbmFnZXIgZnJvbSAnLi9pbWFnZV9tYW5hZ2VyLmpzJztcbmltcG9ydCB0eXBlIEdseXBoTWFuYWdlciBmcm9tICcuL2dseXBoX21hbmFnZXIuanMnO1xuaW1wb3J0IHR5cGUgVmVydGV4QnVmZmVyIGZyb20gJy4uL2dsL3ZlcnRleF9idWZmZXIuanMnO1xuaW1wb3J0IHR5cGUgSW5kZXhCdWZmZXIgZnJvbSAnLi4vZ2wvaW5kZXhfYnVmZmVyLmpzJztcbmltcG9ydCB0eXBlIHtEZXB0aFJhbmdlVHlwZSwgRGVwdGhNYXNrVHlwZSwgRGVwdGhGdW5jVHlwZX0gZnJvbSAnLi4vZ2wvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUgUmVzb2x2ZWRJbWFnZSBmcm9tICcuLi9zdHlsZS1zcGVjL2V4cHJlc3Npb24vdHlwZXMvcmVzb2x2ZWRfaW1hZ2UuanMnO1xuaW1wb3J0IHR5cGUge0R5bmFtaWNEZWZpbmVzVHlwZX0gZnJvbSAnLi9wcm9ncmFtL3Byb2dyYW1fdW5pZm9ybXMuanMnO1xuXG5leHBvcnQgdHlwZSBSZW5kZXJQYXNzID0gJ29mZnNjcmVlbicgfCAnb3BhcXVlJyB8ICd0cmFuc2x1Y2VudCcgfCAnc2t5JztcbmV4cG9ydCB0eXBlIENhbnZhc0NvcHlJbnN0YW5jZXMgPSB7XG4gICAgY2FudmFzQ29waWVzOiBXZWJHTFRleHR1cmVbXSxcbiAgICB0aW1lU3RhbXBzOiBudW1iZXJbXVxufVxuXG50eXBlIFBhaW50ZXJPcHRpb25zID0ge1xuICAgIHNob3dPdmVyZHJhd0luc3BlY3RvcjogYm9vbGVhbixcbiAgICBzaG93VGlsZUJvdW5kYXJpZXM6IGJvb2xlYW4sXG4gICAgc2hvd1RlcnJhaW5XaXJlZnJhbWU6IGJvb2xlYW4sXG4gICAgc2hvd1F1ZXJ5R2VvbWV0cnk6IGJvb2xlYW4sXG4gICAgc2hvd1RpbGVBQUJCczogYm9vbGVhbixcbiAgICBzaG93UGFkZGluZzogYm9vbGVhbixcbiAgICByb3RhdGluZzogYm9vbGVhbixcbiAgICB6b29taW5nOiBib29sZWFuLFxuICAgIG1vdmluZzogYm9vbGVhbixcbiAgICBncHVUaW1pbmc6IGJvb2xlYW4sXG4gICAgZ3B1VGltaW5nRGVmZXJyZWRSZW5kZXI6IGJvb2xlYW4sXG4gICAgZmFkZUR1cmF0aW9uOiBudW1iZXIsXG4gICAgaXNJbml0aWFsTG9hZDogYm9vbGVhbixcbiAgICBzcGVlZEluZGV4VGltaW5nOiBib29sZWFuXG59XG5cbnR5cGUgVGlsZUJvdW5kc0J1ZmZlcnMgPSB7fFxuICB0aWxlQm91bmRzQnVmZmVyOiBWZXJ0ZXhCdWZmZXIsXG4gIHRpbGVCb3VuZHNJbmRleEJ1ZmZlcjogSW5kZXhCdWZmZXIsXG4gIHRpbGVCb3VuZHNTZWdtZW50czogU2VnbWVudFZlY3Rvcixcbnx9O1xuXG50eXBlIEdQVVRpbWVycyA9IHtbbGF5ZXJJZDogc3RyaW5nXTogYW55fTtcblxuLyoqXG4gKiBJbml0aWFsaXplIGEgbmV3IHBhaW50ZXIgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7Q2FudmFzfSBnbCBhbiBleHBlcmltZW50YWwtd2ViZ2wgZHJhd2luZyBjb250ZXh0XG4gKiBAcHJpdmF0ZVxuICovXG5jbGFzcyBQYWludGVyIHtcbiAgICBjb250ZXh0OiBDb250ZXh0O1xuICAgIHRyYW5zZm9ybTogVHJhbnNmb3JtO1xuICAgIF90aWxlVGV4dHVyZXM6IHtbXzogbnVtYmVyXTogQXJyYXk8VGV4dHVyZT4gfTtcbiAgICBudW1TdWJsYXllcnM6IG51bWJlcjtcbiAgICBkZXB0aEVwc2lsb246IG51bWJlcjtcbiAgICBlbXB0eVByb2dyYW1Db25maWd1cmF0aW9uOiBQcm9ncmFtQ29uZmlndXJhdGlvbjtcbiAgICB3aWR0aDogbnVtYmVyO1xuICAgIGhlaWdodDogbnVtYmVyO1xuICAgIHRpbGVFeHRlbnRCdWZmZXI6IFZlcnRleEJ1ZmZlcjtcbiAgICB0aWxlRXh0ZW50U2VnbWVudHM6IFNlZ21lbnRWZWN0b3I7XG4gICAgZGVidWdCdWZmZXI6IFZlcnRleEJ1ZmZlcjtcbiAgICBkZWJ1Z0luZGV4QnVmZmVyOiBJbmRleEJ1ZmZlcjtcbiAgICBkZWJ1Z1NlZ21lbnRzOiBTZWdtZW50VmVjdG9yO1xuICAgIHZpZXdwb3J0QnVmZmVyOiBWZXJ0ZXhCdWZmZXI7XG4gICAgdmlld3BvcnRTZWdtZW50czogU2VnbWVudFZlY3RvcjtcbiAgICBxdWFkVHJpYW5nbGVJbmRleEJ1ZmZlcjogSW5kZXhCdWZmZXI7XG4gICAgbWVyY2F0b3JCb3VuZHNCdWZmZXI6IFZlcnRleEJ1ZmZlcjtcbiAgICBtZXJjYXRvckJvdW5kc1NlZ21lbnRzOiBTZWdtZW50VmVjdG9yO1xuICAgIF90aWxlQ2xpcHBpbmdNYXNrSURzOiB7W186IG51bWJlcl06IG51bWJlciB9O1xuICAgIHN0ZW5jaWxDbGVhck1vZGU6IFN0ZW5jaWxNb2RlO1xuICAgIHN0eWxlOiBTdHlsZTtcbiAgICBvcHRpb25zOiBQYWludGVyT3B0aW9ucztcbiAgICBpbWFnZU1hbmFnZXI6IEltYWdlTWFuYWdlcjtcbiAgICBnbHlwaE1hbmFnZXI6IEdseXBoTWFuYWdlcjtcbiAgICBkZXB0aFJhbmdlRm9yM0Q6IERlcHRoUmFuZ2VUeXBlO1xuICAgIG9wYXF1ZVBhc3NDdXRvZmY6IG51bWJlcjtcbiAgICBmcmFtZUNvdW50ZXI6IG51bWJlcjtcbiAgICByZW5kZXJQYXNzOiBSZW5kZXJQYXNzO1xuICAgIGN1cnJlbnRMYXllcjogbnVtYmVyO1xuICAgIGN1cnJlbnRTdGVuY2lsU291cmNlOiA/c3RyaW5nO1xuICAgIG5leHRTdGVuY2lsSUQ6IG51bWJlcjtcbiAgICBpZDogc3RyaW5nO1xuICAgIF9zaG93T3ZlcmRyYXdJbnNwZWN0b3I6IGJvb2xlYW47XG4gICAgY2FjaGU6IHtbXzogc3RyaW5nXTogUHJvZ3JhbTwqPiB9O1xuICAgIHN5bWJvbEZhZGVDaGFuZ2U6IG51bWJlcjtcbiAgICBncHVUaW1lcnM6IEdQVVRpbWVycztcbiAgICBkZWZlcnJlZFJlbmRlckdwdVRpbWVRdWVyaWVzOiBBcnJheTxhbnk+O1xuICAgIGVtcHR5VGV4dHVyZTogVGV4dHVyZTtcbiAgICBpZGVudGl0eU1hdDogRmxvYXQzMkFycmF5O1xuICAgIGRlYnVnT3ZlcmxheVRleHR1cmU6IFRleHR1cmU7XG4gICAgZGVidWdPdmVybGF5Q2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudDtcbiAgICBfdGVycmFpbjogP1RlcnJhaW47XG4gICAgZ2xvYmVTaGFyZWRCdWZmZXJzOiA/R2xvYmVTaGFyZWRCdWZmZXJzO1xuICAgIGF0bW9zcGhlcmVCdWZmZXI6IEF0bW9zcGhlcmVCdWZmZXI7XG4gICAgdGlsZUxvYWRlZDogYm9vbGVhbjtcbiAgICBmcmFtZUNvcGllczogQXJyYXk8V2ViR0xUZXh0dXJlPjtcbiAgICBsb2FkVGltZVN0YW1wczogQXJyYXk8bnVtYmVyPjtcbiAgICBfYmFja2dyb3VuZFRpbGVzOiB7W2tleTogbnVtYmVyXTogVGlsZX07XG5cbiAgICBjb25zdHJ1Y3RvcihnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0LCB0cmFuc2Zvcm06IFRyYW5zZm9ybSwgaXNXZWJHTDI6IGJvb2xlYW4gPSBmYWxzZSkge1xuICAgICAgICB0aGlzLmNvbnRleHQgPSBuZXcgQ29udGV4dChnbCwgaXNXZWJHTDIpO1xuICAgICAgICB0aGlzLnRyYW5zZm9ybSA9IHRyYW5zZm9ybTtcbiAgICAgICAgdGhpcy5fdGlsZVRleHR1cmVzID0ge307XG4gICAgICAgIHRoaXMuZnJhbWVDb3BpZXMgPSBbXTtcbiAgICAgICAgdGhpcy5sb2FkVGltZVN0YW1wcyA9IFtdO1xuXG4gICAgICAgIHRoaXMuc2V0dXAoKTtcblxuICAgICAgICAvLyBXaXRoaW4gZWFjaCBsYXllciB0aGVyZSBhcmUgbXVsdGlwbGUgZGlzdGluY3Qgei1wbGFuZXMgdGhhdCBjYW4gYmUgZHJhd24gdG8uXG4gICAgICAgIC8vIFRoaXMgaXMgaW1wbGVtZW50ZWQgdXNpbmcgdGhlIFdlYkdMIGRlcHRoIGJ1ZmZlci5cbiAgICAgICAgdGhpcy5udW1TdWJsYXllcnMgPSBTb3VyY2VDYWNoZS5tYXhVbmRlcnpvb21pbmcgKyBTb3VyY2VDYWNoZS5tYXhPdmVyem9vbWluZyArIDE7XG4gICAgICAgIHRoaXMuZGVwdGhFcHNpbG9uID0gMSAvIE1hdGgucG93KDIsIDE2KTtcblxuICAgICAgICB0aGlzLmRlZmVycmVkUmVuZGVyR3B1VGltZVF1ZXJpZXMgPSBbXTtcbiAgICAgICAgdGhpcy5ncHVUaW1lcnMgPSB7fTtcbiAgICAgICAgdGhpcy5mcmFtZUNvdW50ZXIgPSAwO1xuICAgICAgICB0aGlzLl9iYWNrZ3JvdW5kVGlsZXMgPSB7fTtcbiAgICB9XG5cbiAgICB1cGRhdGVUZXJyYWluKHN0eWxlOiBTdHlsZSwgYWRhcHRDYW1lcmFBbHRpdHVkZTogYm9vbGVhbikge1xuICAgICAgICBjb25zdCBlbmFibGVkID0gISFzdHlsZSAmJiAhIXN0eWxlLnRlcnJhaW4gJiYgdGhpcy50cmFuc2Zvcm0ucHJvamVjdGlvbi5zdXBwb3J0c1RlcnJhaW47XG4gICAgICAgIGlmICghZW5hYmxlZCAmJiAoIXRoaXMuX3RlcnJhaW4gfHwgIXRoaXMuX3RlcnJhaW4uZW5hYmxlZCkpIHJldHVybjtcbiAgICAgICAgaWYgKCF0aGlzLl90ZXJyYWluKSB7XG4gICAgICAgICAgICB0aGlzLl90ZXJyYWluID0gbmV3IFRlcnJhaW4odGhpcywgc3R5bGUpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHRlcnJhaW46IFRlcnJhaW4gPSB0aGlzLl90ZXJyYWluO1xuICAgICAgICB0aGlzLnRyYW5zZm9ybS5lbGV2YXRpb24gPSBlbmFibGVkID8gdGVycmFpbiA6IG51bGw7XG4gICAgICAgIHRlcnJhaW4udXBkYXRlKHN0eWxlLCB0aGlzLnRyYW5zZm9ybSwgYWRhcHRDYW1lcmFBbHRpdHVkZSk7XG4gICAgfVxuXG4gICAgX3VwZGF0ZUZvZyhzdHlsZTogU3R5bGUpIHtcbiAgICAgICAgLy8gR2xvYmUgbWFrZXMgdXNlIG9mIHRoaW4gZm9nIG92ZXJsYXkgd2l0aCBhIGZpeGVkIGZvZyByYW5nZSxcbiAgICAgICAgLy8gc28gd2UgY2FuIHNraXAgdXBkYXRpbmcgZm9nIHRpbGUgY3VsbGluZyBmb3IgdGhpcyBwcm9qZWN0aW9uXG4gICAgICAgIGNvbnN0IGlzR2xvYmUgPSB0aGlzLnRyYW5zZm9ybS5wcm9qZWN0aW9uLm5hbWUgPT09ICdnbG9iZSc7XG5cbiAgICAgICAgY29uc3QgZm9nID0gc3R5bGUuZm9nO1xuICAgICAgICBpZiAoIWZvZyB8fCBpc0dsb2JlIHx8IGZvZy5nZXRPcGFjaXR5KHRoaXMudHJhbnNmb3JtLnBpdGNoKSA8IDEgfHwgZm9nLnByb3BlcnRpZXMuZ2V0KCdob3Jpem9uLWJsZW5kJykgPCAwLjAzKSB7XG4gICAgICAgICAgICB0aGlzLnRyYW5zZm9ybS5mb2dDdWxsRGlzdFNxID0gbnVsbDtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFdlIHN0YXJ0IGN1bGxpbmcgd2hlcmUgdGhlIGZvZyBvcGFjaXR5IGZ1bmN0aW9uIGhpdHNcbiAgICAgICAgLy8gOTglIHdoaWNoIGxlYXZlcyBhIG5vbi1ub3RpY2VhYmxlIGNoYW5nZSB0aHJlc2hvbGQuXG4gICAgICAgIGNvbnN0IFtzdGFydCwgZW5kXSA9IGZvZy5nZXRGb3ZBZGp1c3RlZFJhbmdlKHRoaXMudHJhbnNmb3JtLl9mb3YpO1xuXG4gICAgICAgIGlmIChzdGFydCA+IGVuZCkge1xuICAgICAgICAgICAgdGhpcy50cmFuc2Zvcm0uZm9nQ3VsbERpc3RTcSA9IG51bGw7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmb2dCb3VuZEZyYWN0aW9uID0gMC43ODtcbiAgICAgICAgY29uc3QgZm9nQ3VsbERpc3QgPSBzdGFydCArIChlbmQgLSBzdGFydCkgKiBmb2dCb3VuZEZyYWN0aW9uO1xuXG4gICAgICAgIHRoaXMudHJhbnNmb3JtLmZvZ0N1bGxEaXN0U3EgPSBmb2dDdWxsRGlzdCAqIGZvZ0N1bGxEaXN0O1xuICAgIH1cblxuICAgIGdldCB0ZXJyYWluKCk6ID9UZXJyYWluIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNmb3JtLl90ZXJyYWluRW5hYmxlZCgpICYmIHRoaXMuX3RlcnJhaW4gJiYgdGhpcy5fdGVycmFpbi5lbmFibGVkID8gdGhpcy5fdGVycmFpbiA6IG51bGw7XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBVcGRhdGUgdGhlIEdMIHZpZXdwb3J0LCBwcm9qZWN0aW9uIG1hdHJpeCwgYW5kIHRyYW5zZm9ybXMgdG8gY29tcGVuc2F0ZVxuICAgICAqIGZvciBhIG5ldyB3aWR0aCBhbmQgaGVpZ2h0IHZhbHVlLlxuICAgICAqL1xuICAgIHJlc2l6ZSh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgICAgICB0aGlzLndpZHRoID0gd2lkdGggKiBicm93c2VyLmRldmljZVBpeGVsUmF0aW87XG4gICAgICAgIHRoaXMuaGVpZ2h0ID0gaGVpZ2h0ICogYnJvd3Nlci5kZXZpY2VQaXhlbFJhdGlvO1xuICAgICAgICB0aGlzLmNvbnRleHQudmlld3BvcnQuc2V0KFswLCAwLCB0aGlzLndpZHRoLCB0aGlzLmhlaWdodF0pO1xuXG4gICAgICAgIGlmICh0aGlzLnN0eWxlKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGxheWVySWQgb2YgdGhpcy5zdHlsZS5vcmRlcikge1xuICAgICAgICAgICAgICAgIHRoaXMuc3R5bGUuX2xheWVyc1tsYXllcklkXS5yZXNpemUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldHVwKCkge1xuICAgICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5jb250ZXh0O1xuXG4gICAgICAgIGNvbnN0IHRpbGVFeHRlbnRBcnJheSA9IG5ldyBQb3NBcnJheSgpO1xuICAgICAgICB0aWxlRXh0ZW50QXJyYXkuZW1wbGFjZUJhY2soMCwgMCk7XG4gICAgICAgIHRpbGVFeHRlbnRBcnJheS5lbXBsYWNlQmFjayhFWFRFTlQsIDApO1xuICAgICAgICB0aWxlRXh0ZW50QXJyYXkuZW1wbGFjZUJhY2soMCwgRVhURU5UKTtcbiAgICAgICAgdGlsZUV4dGVudEFycmF5LmVtcGxhY2VCYWNrKEVYVEVOVCwgRVhURU5UKTtcbiAgICAgICAgdGhpcy50aWxlRXh0ZW50QnVmZmVyID0gY29udGV4dC5jcmVhdGVWZXJ0ZXhCdWZmZXIodGlsZUV4dGVudEFycmF5LCBwb3NBdHRyaWJ1dGVzLm1lbWJlcnMpO1xuICAgICAgICB0aGlzLnRpbGVFeHRlbnRTZWdtZW50cyA9IFNlZ21lbnRWZWN0b3Iuc2ltcGxlU2VnbWVudCgwLCAwLCA0LCAyKTtcblxuICAgICAgICBjb25zdCBkZWJ1Z0FycmF5ID0gbmV3IFBvc0FycmF5KCk7XG4gICAgICAgIGRlYnVnQXJyYXkuZW1wbGFjZUJhY2soMCwgMCk7XG4gICAgICAgIGRlYnVnQXJyYXkuZW1wbGFjZUJhY2soRVhURU5ULCAwKTtcbiAgICAgICAgZGVidWdBcnJheS5lbXBsYWNlQmFjaygwLCBFWFRFTlQpO1xuICAgICAgICBkZWJ1Z0FycmF5LmVtcGxhY2VCYWNrKEVYVEVOVCwgRVhURU5UKTtcbiAgICAgICAgdGhpcy5kZWJ1Z0J1ZmZlciA9IGNvbnRleHQuY3JlYXRlVmVydGV4QnVmZmVyKGRlYnVnQXJyYXksIHBvc0F0dHJpYnV0ZXMubWVtYmVycyk7XG4gICAgICAgIHRoaXMuZGVidWdTZWdtZW50cyA9IFNlZ21lbnRWZWN0b3Iuc2ltcGxlU2VnbWVudCgwLCAwLCA0LCA1KTtcblxuICAgICAgICBjb25zdCB2aWV3cG9ydEFycmF5ID0gbmV3IFBvc0FycmF5KCk7XG4gICAgICAgIHZpZXdwb3J0QXJyYXkuZW1wbGFjZUJhY2soLTEsIC0xKTtcbiAgICAgICAgdmlld3BvcnRBcnJheS5lbXBsYWNlQmFjaygxLCAtMSk7XG4gICAgICAgIHZpZXdwb3J0QXJyYXkuZW1wbGFjZUJhY2soLTEsIDEpO1xuICAgICAgICB2aWV3cG9ydEFycmF5LmVtcGxhY2VCYWNrKDEsIDEpO1xuICAgICAgICB0aGlzLnZpZXdwb3J0QnVmZmVyID0gY29udGV4dC5jcmVhdGVWZXJ0ZXhCdWZmZXIodmlld3BvcnRBcnJheSwgcG9zQXR0cmlidXRlcy5tZW1iZXJzKTtcbiAgICAgICAgdGhpcy52aWV3cG9ydFNlZ21lbnRzID0gU2VnbWVudFZlY3Rvci5zaW1wbGVTZWdtZW50KDAsIDAsIDQsIDIpO1xuXG4gICAgICAgIGNvbnN0IHRpbGVCb3VuZHNBcnJheSA9IG5ldyBUaWxlQm91bmRzQXJyYXkoKTtcbiAgICAgICAgdGlsZUJvdW5kc0FycmF5LmVtcGxhY2VCYWNrKDAsIDAsIDAsIDApO1xuICAgICAgICB0aWxlQm91bmRzQXJyYXkuZW1wbGFjZUJhY2soRVhURU5ULCAwLCBFWFRFTlQsIDApO1xuICAgICAgICB0aWxlQm91bmRzQXJyYXkuZW1wbGFjZUJhY2soMCwgRVhURU5ULCAwLCBFWFRFTlQpO1xuICAgICAgICB0aWxlQm91bmRzQXJyYXkuZW1wbGFjZUJhY2soRVhURU5ULCBFWFRFTlQsIEVYVEVOVCwgRVhURU5UKTtcbiAgICAgICAgdGhpcy5tZXJjYXRvckJvdW5kc0J1ZmZlciA9IGNvbnRleHQuY3JlYXRlVmVydGV4QnVmZmVyKHRpbGVCb3VuZHNBcnJheSwgYm91bmRzQXR0cmlidXRlcy5tZW1iZXJzKTtcbiAgICAgICAgdGhpcy5tZXJjYXRvckJvdW5kc1NlZ21lbnRzID0gU2VnbWVudFZlY3Rvci5zaW1wbGVTZWdtZW50KDAsIDAsIDQsIDIpO1xuXG4gICAgICAgIGNvbnN0IHF1YWRUcmlhbmdsZUluZGljZXMgPSBuZXcgVHJpYW5nbGVJbmRleEFycmF5KCk7XG4gICAgICAgIHF1YWRUcmlhbmdsZUluZGljZXMuZW1wbGFjZUJhY2soMCwgMSwgMik7XG4gICAgICAgIHF1YWRUcmlhbmdsZUluZGljZXMuZW1wbGFjZUJhY2soMiwgMSwgMyk7XG4gICAgICAgIHRoaXMucXVhZFRyaWFuZ2xlSW5kZXhCdWZmZXIgPSBjb250ZXh0LmNyZWF0ZUluZGV4QnVmZmVyKHF1YWRUcmlhbmdsZUluZGljZXMpO1xuXG4gICAgICAgIGNvbnN0IHRpbGVMaW5lU3RyaXBJbmRpY2VzID0gbmV3IExpbmVTdHJpcEluZGV4QXJyYXkoKTtcbiAgICAgICAgZm9yIChjb25zdCBpIG9mIFswLCAxLCAzLCAyLCAwXSkgdGlsZUxpbmVTdHJpcEluZGljZXMuZW1wbGFjZUJhY2soaSk7XG4gICAgICAgIHRoaXMuZGVidWdJbmRleEJ1ZmZlciA9IGNvbnRleHQuY3JlYXRlSW5kZXhCdWZmZXIodGlsZUxpbmVTdHJpcEluZGljZXMpO1xuXG4gICAgICAgIHRoaXMuZW1wdHlUZXh0dXJlID0gbmV3IFRleHR1cmUoY29udGV4dCxcbiAgICAgICAgICAgIG5ldyBSR0JBSW1hZ2Uoe3dpZHRoOiAxLCBoZWlnaHQ6IDF9LCBVaW50OEFycmF5Lm9mKDAsIDAsIDAsIDApKSwgY29udGV4dC5nbC5SR0JBKTtcblxuICAgICAgICB0aGlzLmlkZW50aXR5TWF0ID0gbWF0NC5jcmVhdGUoKTtcblxuICAgICAgICBjb25zdCBnbCA9IHRoaXMuY29udGV4dC5nbDtcbiAgICAgICAgdGhpcy5zdGVuY2lsQ2xlYXJNb2RlID0gbmV3IFN0ZW5jaWxNb2RlKHtmdW5jOiBnbC5BTFdBWVMsIG1hc2s6IDB9LCAweDAsIDB4RkYsIGdsLlpFUk8sIGdsLlpFUk8sIGdsLlpFUk8pO1xuICAgICAgICB0aGlzLmxvYWRUaW1lU3RhbXBzLnB1c2god2luZG93LnBlcmZvcm1hbmNlLm5vdygpKTtcblxuICAgICAgICB0aGlzLmF0bW9zcGhlcmVCdWZmZXIgPSBuZXcgQXRtb3NwaGVyZUJ1ZmZlcih0aGlzLmNvbnRleHQpO1xuICAgIH1cblxuICAgIGdldE1lcmNhdG9yVGlsZUJvdW5kc0J1ZmZlcnMoKTogVGlsZUJvdW5kc0J1ZmZlcnMge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdGlsZUJvdW5kc0J1ZmZlcjogdGhpcy5tZXJjYXRvckJvdW5kc0J1ZmZlcixcbiAgICAgICAgICAgIHRpbGVCb3VuZHNJbmRleEJ1ZmZlcjogdGhpcy5xdWFkVHJpYW5nbGVJbmRleEJ1ZmZlcixcbiAgICAgICAgICAgIHRpbGVCb3VuZHNTZWdtZW50czogdGhpcy5tZXJjYXRvckJvdW5kc1NlZ21lbnRzXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZ2V0VGlsZUJvdW5kc0J1ZmZlcnModGlsZTogVGlsZSk6IFRpbGVCb3VuZHNCdWZmZXJzIHtcbiAgICAgICAgdGlsZS5fbWFrZVRpbGVCb3VuZHNCdWZmZXJzKHRoaXMuY29udGV4dCwgdGhpcy50cmFuc2Zvcm0ucHJvamVjdGlvbik7XG4gICAgICAgIGlmICh0aWxlLl90aWxlQm91bmRzQnVmZmVyKSB7XG4gICAgICAgICAgICBjb25zdCB0aWxlQm91bmRzQnVmZmVyID0gdGlsZS5fdGlsZUJvdW5kc0J1ZmZlcjtcbiAgICAgICAgICAgIGNvbnN0IHRpbGVCb3VuZHNJbmRleEJ1ZmZlciA9IHRpbGUuX3RpbGVCb3VuZHNJbmRleEJ1ZmZlcjtcbiAgICAgICAgICAgIGNvbnN0IHRpbGVCb3VuZHNTZWdtZW50cyA9IHRpbGUuX3RpbGVCb3VuZHNTZWdtZW50cztcbiAgICAgICAgICAgIHJldHVybiB7dGlsZUJvdW5kc0J1ZmZlciwgdGlsZUJvdW5kc0luZGV4QnVmZmVyLCB0aWxlQm91bmRzU2VnbWVudHN9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0TWVyY2F0b3JUaWxlQm91bmRzQnVmZmVycygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBSZXNldCB0aGUgZHJhd2luZyBjYW52YXMgYnkgY2xlYXJpbmcgdGhlIHN0ZW5jaWwgYnVmZmVyIHNvIHRoYXQgd2UgY2FuIGRyYXdcbiAgICAgKiBuZXcgdGlsZXMgYXQgdGhlIHNhbWUgbG9jYXRpb24sIHdoaWxlIHJldGFpbmluZyBwcmV2aW91c2x5IGRyYXduIHBpeGVscy5cbiAgICAgKi9cbiAgICBjbGVhclN0ZW5jaWwoKSB7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmNvbnRleHQ7XG4gICAgICAgIGNvbnN0IGdsID0gY29udGV4dC5nbDtcblxuICAgICAgICB0aGlzLm5leHRTdGVuY2lsSUQgPSAxO1xuICAgICAgICB0aGlzLmN1cnJlbnRTdGVuY2lsU291cmNlID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl90aWxlQ2xpcHBpbmdNYXNrSURzID0ge307XG5cbiAgICAgICAgLy8gQXMgYSB0ZW1wb3Jhcnkgd29ya2Fyb3VuZCBmb3IgaHR0cHM6Ly9naXRodWIuY29tL21hcGJveC9tYXBib3gtZ2wtanMvaXNzdWVzLzU0OTAsXG4gICAgICAgIC8vIHBlbmRpbmcgYW4gdXBzdHJlYW0gZml4LCB3ZSBkcmF3IGEgZnVsbHNjcmVlbiBzdGVuY2lsPTAgY2xpcHBpbmcgbWFzayBoZXJlLFxuICAgICAgICAvLyBlZmZlY3RpdmVseSBjbGVhcmluZyB0aGUgc3RlbmNpbCBidWZmZXI6IG9uY2UgYW4gdXBzdHJlYW0gcGF0Y2ggbGFuZHMsIHJlbW92ZVxuICAgICAgICAvLyB0aGlzIGZ1bmN0aW9uIGluIGZhdm9yIG9mIGNvbnRleHQuY2xlYXIoeyBzdGVuY2lsOiAweDAgfSlcbiAgICAgICAgdGhpcy51c2VQcm9ncmFtKCdjbGlwcGluZ01hc2snKS5kcmF3KGNvbnRleHQsIGdsLlRSSUFOR0xFUyxcbiAgICAgICAgICAgIERlcHRoTW9kZS5kaXNhYmxlZCwgdGhpcy5zdGVuY2lsQ2xlYXJNb2RlLCBDb2xvck1vZGUuZGlzYWJsZWQsIEN1bGxGYWNlTW9kZS5kaXNhYmxlZCxcbiAgICAgICAgICAgIGNsaXBwaW5nTWFza1VuaWZvcm1WYWx1ZXModGhpcy5pZGVudGl0eU1hdCksXG4gICAgICAgICAgICAnJGNsaXBwaW5nJywgdGhpcy52aWV3cG9ydEJ1ZmZlcixcbiAgICAgICAgICAgIHRoaXMucXVhZFRyaWFuZ2xlSW5kZXhCdWZmZXIsIHRoaXMudmlld3BvcnRTZWdtZW50cyk7XG4gICAgfVxuXG4gICAgcmVzZXRTdGVuY2lsQ2xpcHBpbmdNYXNrcygpIHtcbiAgICAgICAgaWYgKCF0aGlzLnRlcnJhaW4pIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudFN0ZW5jaWxTb3VyY2UgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0aGlzLl90aWxlQ2xpcHBpbmdNYXNrSURzID0ge307XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfcmVuZGVyVGlsZUNsaXBwaW5nTWFza3MobGF5ZXI6IFN0eWxlTGF5ZXIsIHNvdXJjZUNhY2hlPzogU291cmNlQ2FjaGUsIHRpbGVJRHM/OiBBcnJheTxPdmVyc2NhbGVkVGlsZUlEPikge1xuICAgICAgICBpZiAoIXNvdXJjZUNhY2hlIHx8IHRoaXMuY3VycmVudFN0ZW5jaWxTb3VyY2UgPT09IHNvdXJjZUNhY2hlLmlkIHx8ICFsYXllci5pc1RpbGVDbGlwcGVkKCkgfHwgIXRpbGVJRHMgfHwgdGlsZUlEcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLl90aWxlQ2xpcHBpbmdNYXNrSURzICYmICF0aGlzLnRlcnJhaW4pIHtcbiAgICAgICAgICAgIGxldCBkaXJ0eVN0ZW5jaWxDbGlwcGluZ01hc2tzID0gZmFsc2U7XG4gICAgICAgICAgICAvLyBFcXVpdmFsZW50IHRpbGUgc2V0IGlzIGFscmVhZHkgcmVuZGVyZWQgaW4gc3RlbmNpbFxuICAgICAgICAgICAgZm9yIChjb25zdCBjb29yZCBvZiB0aWxlSURzKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX3RpbGVDbGlwcGluZ01hc2tJRHNbY29vcmQua2V5XSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGRpcnR5U3RlbmNpbENsaXBwaW5nTWFza3MgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWRpcnR5U3RlbmNpbENsaXBwaW5nTWFza3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmN1cnJlbnRTdGVuY2lsU291cmNlID0gc291cmNlQ2FjaGUuaWQ7XG5cbiAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMuY29udGV4dDtcbiAgICAgICAgY29uc3QgZ2wgPSBjb250ZXh0LmdsO1xuXG4gICAgICAgIGlmICh0aGlzLm5leHRTdGVuY2lsSUQgKyB0aWxlSURzLmxlbmd0aCA+IDI1Nikge1xuICAgICAgICAgICAgLy8gd2UnbGwgcnVuIG91dCBvZiBmcmVzaCBJRHMgc28gd2UgbmVlZCB0byBjbGVhciBhbmQgc3RhcnQgZnJvbSBzY3JhdGNoXG4gICAgICAgICAgICB0aGlzLmNsZWFyU3RlbmNpbCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29udGV4dC5zZXRDb2xvck1vZGUoQ29sb3JNb2RlLmRpc2FibGVkKTtcbiAgICAgICAgY29udGV4dC5zZXREZXB0aE1vZGUoRGVwdGhNb2RlLmRpc2FibGVkKTtcblxuICAgICAgICBjb25zdCBwcm9ncmFtID0gdGhpcy51c2VQcm9ncmFtKCdjbGlwcGluZ01hc2snKTtcblxuICAgICAgICB0aGlzLl90aWxlQ2xpcHBpbmdNYXNrSURzID0ge307XG5cbiAgICAgICAgZm9yIChjb25zdCB0aWxlSUQgb2YgdGlsZUlEcykge1xuICAgICAgICAgICAgY29uc3QgdGlsZSA9IHNvdXJjZUNhY2hlLmdldFRpbGUodGlsZUlEKTtcbiAgICAgICAgICAgIGNvbnN0IGlkID0gdGhpcy5fdGlsZUNsaXBwaW5nTWFza0lEc1t0aWxlSUQua2V5XSA9IHRoaXMubmV4dFN0ZW5jaWxJRCsrO1xuICAgICAgICAgICAgY29uc3Qge3RpbGVCb3VuZHNCdWZmZXIsIHRpbGVCb3VuZHNJbmRleEJ1ZmZlciwgdGlsZUJvdW5kc1NlZ21lbnRzfSA9IHRoaXMuZ2V0VGlsZUJvdW5kc0J1ZmZlcnModGlsZSk7XG5cbiAgICAgICAgICAgIHByb2dyYW0uZHJhdyhjb250ZXh0LCBnbC5UUklBTkdMRVMsIERlcHRoTW9kZS5kaXNhYmxlZCxcbiAgICAgICAgICAgIC8vIFRlc3RzIHdpbGwgYWx3YXlzIHBhc3MsIGFuZCByZWYgdmFsdWUgd2lsbCBiZSB3cml0dGVuIHRvIHN0ZW5jaWwgYnVmZmVyLlxuICAgICAgICAgICAgbmV3IFN0ZW5jaWxNb2RlKHtmdW5jOiBnbC5BTFdBWVMsIG1hc2s6IDB9LCBpZCwgMHhGRiwgZ2wuS0VFUCwgZ2wuS0VFUCwgZ2wuUkVQTEFDRSksXG4gICAgICAgICAgICBDb2xvck1vZGUuZGlzYWJsZWQsIEN1bGxGYWNlTW9kZS5kaXNhYmxlZCwgY2xpcHBpbmdNYXNrVW5pZm9ybVZhbHVlcyh0aWxlSUQucHJvak1hdHJpeCksXG4gICAgICAgICAgICAnJGNsaXBwaW5nJywgdGlsZUJvdW5kc0J1ZmZlcixcbiAgICAgICAgICAgIHRpbGVCb3VuZHNJbmRleEJ1ZmZlciwgdGlsZUJvdW5kc1NlZ21lbnRzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0ZW5jaWxNb2RlRm9yM0QoKTogU3RlbmNpbE1vZGUge1xuICAgICAgICB0aGlzLmN1cnJlbnRTdGVuY2lsU291cmNlID0gdW5kZWZpbmVkO1xuXG4gICAgICAgIGlmICh0aGlzLm5leHRTdGVuY2lsSUQgKyAxID4gMjU2KSB7XG4gICAgICAgICAgICB0aGlzLmNsZWFyU3RlbmNpbCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaWQgPSB0aGlzLm5leHRTdGVuY2lsSUQrKztcbiAgICAgICAgY29uc3QgZ2wgPSB0aGlzLmNvbnRleHQuZ2w7XG4gICAgICAgIHJldHVybiBuZXcgU3RlbmNpbE1vZGUoe2Z1bmM6IGdsLk5PVEVRVUFMLCBtYXNrOiAweEZGfSwgaWQsIDB4RkYsIGdsLktFRVAsIGdsLktFRVAsIGdsLlJFUExBQ0UpO1xuICAgIH1cblxuICAgIHN0ZW5jaWxNb2RlRm9yQ2xpcHBpbmcodGlsZUlEOiBPdmVyc2NhbGVkVGlsZUlEKTogJFJlYWRPbmx5PFN0ZW5jaWxNb2RlPiAge1xuICAgICAgICBpZiAodGhpcy50ZXJyYWluKSByZXR1cm4gdGhpcy50ZXJyYWluLnN0ZW5jaWxNb2RlRm9yUlRUT3ZlcmxhcCh0aWxlSUQpO1xuICAgICAgICBjb25zdCBnbCA9IHRoaXMuY29udGV4dC5nbDtcbiAgICAgICAgcmV0dXJuIG5ldyBTdGVuY2lsTW9kZSh7ZnVuYzogZ2wuRVFVQUwsIG1hc2s6IDB4RkZ9LCB0aGlzLl90aWxlQ2xpcHBpbmdNYXNrSURzW3RpbGVJRC5rZXldLCAweDAwLCBnbC5LRUVQLCBnbC5LRUVQLCBnbC5SRVBMQUNFKTtcbiAgICB9XG5cbiAgICAvKlxuICAgICAqIFNvcnQgY29vcmRpbmF0ZXMgYnkgWiBhcyBkcmF3aW5nIHRpbGVzIGlzIGRvbmUgaW4gWi1kZXNjZW5kaW5nIG9yZGVyLlxuICAgICAqIEFsbCBjaGlsZHJlbiB3aXRoIHRoZSBzYW1lIFogd3JpdGUgdGhlIHNhbWUgc3RlbmNpbCB2YWx1ZS4gIENoaWxkcmVuXG4gICAgICogc3RlbmNpbCB2YWx1ZXMgYXJlIGdyZWF0ZXIgdGhhbiBwYXJlbnQncy4gIFRoaXMgaXMgdXNlZCBvbmx5IGZvciByYXN0ZXJcbiAgICAgKiBhbmQgcmFzdGVyLWRlbSB0aWxlcywgd2hpY2ggYXJlIGFscmVhZHkgY2xpcHBlZCB0byB0aWxlIGJvdW5kYXJpZXMsIHRvXG4gICAgICogbWFzayBhcmVhIG9mIHRpbGUgb3ZlcmxhcHBlZCBieSBjaGlsZHJlbiB0aWxlcy5cbiAgICAgKiBTdGVuY2lsIHJlZiB2YWx1ZXMgY29udGludWUgcmFuZ2UgdXNlZCBpbiBfdGlsZUNsaXBwaW5nTWFza0lEcy5cbiAgICAgKlxuICAgICAqIFJldHVybnMgW1N0ZW5jaWxNb2RlIGZvciB0aWxlIG92ZXJzY2FsZVogbWFwLCBzb3J0ZWRDb29yZHNdLlxuICAgICAqL1xuICAgIHN0ZW5jaWxDb25maWdGb3JPdmVybGFwKHRpbGVJRHM6IEFycmF5PE92ZXJzY2FsZWRUaWxlSUQ+KTogW3tbXzogbnVtYmVyXTogJFJlYWRPbmx5PFN0ZW5jaWxNb2RlPn0sIEFycmF5PE92ZXJzY2FsZWRUaWxlSUQ+XSB7XG4gICAgICAgIGNvbnN0IGdsID0gdGhpcy5jb250ZXh0LmdsO1xuICAgICAgICBjb25zdCBjb29yZHMgPSB0aWxlSURzLnNvcnQoKGEsIGIpID0+IGIub3ZlcnNjYWxlZFogLSBhLm92ZXJzY2FsZWRaKTtcbiAgICAgICAgY29uc3QgbWluVGlsZVogPSBjb29yZHNbY29vcmRzLmxlbmd0aCAtIDFdLm92ZXJzY2FsZWRaO1xuICAgICAgICBjb25zdCBzdGVuY2lsVmFsdWVzID0gY29vcmRzWzBdLm92ZXJzY2FsZWRaIC0gbWluVGlsZVogKyAxO1xuICAgICAgICBpZiAoc3RlbmNpbFZhbHVlcyA+IDEpIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudFN0ZW5jaWxTb3VyY2UgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICBpZiAodGhpcy5uZXh0U3RlbmNpbElEICsgc3RlbmNpbFZhbHVlcyA+IDI1Nikge1xuICAgICAgICAgICAgICAgIHRoaXMuY2xlYXJTdGVuY2lsKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCB6VG9TdGVuY2lsTW9kZSA9IHt9O1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdGVuY2lsVmFsdWVzOyBpKyspIHtcbiAgICAgICAgICAgICAgICB6VG9TdGVuY2lsTW9kZVtpICsgbWluVGlsZVpdID0gbmV3IFN0ZW5jaWxNb2RlKHtmdW5jOiBnbC5HRVFVQUwsIG1hc2s6IDB4RkZ9LCBpICsgdGhpcy5uZXh0U3RlbmNpbElELCAweEZGLCBnbC5LRUVQLCBnbC5LRUVQLCBnbC5SRVBMQUNFKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMubmV4dFN0ZW5jaWxJRCArPSBzdGVuY2lsVmFsdWVzO1xuICAgICAgICAgICAgcmV0dXJuIFt6VG9TdGVuY2lsTW9kZSwgY29vcmRzXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW3tbbWluVGlsZVpdOiBTdGVuY2lsTW9kZS5kaXNhYmxlZH0sIGNvb3Jkc107XG4gICAgfVxuXG4gICAgY29sb3JNb2RlRm9yUmVuZGVyUGFzcygpOiAkUmVhZE9ubHk8Q29sb3JNb2RlPiB7XG4gICAgICAgIGNvbnN0IGdsID0gdGhpcy5jb250ZXh0LmdsO1xuICAgICAgICBpZiAodGhpcy5fc2hvd092ZXJkcmF3SW5zcGVjdG9yKSB7XG4gICAgICAgICAgICBjb25zdCBudW1PdmVyZHJhd1N0ZXBzID0gODtcbiAgICAgICAgICAgIGNvbnN0IGEgPSAxIC8gbnVtT3ZlcmRyYXdTdGVwcztcblxuICAgICAgICAgICAgcmV0dXJuIG5ldyBDb2xvck1vZGUoW2dsLkNPTlNUQU5UX0NPTE9SLCBnbC5PTkVdLCBuZXcgQ29sb3IoYSwgYSwgYSwgMCksIFt0cnVlLCB0cnVlLCB0cnVlLCB0cnVlXSk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5yZW5kZXJQYXNzID09PSAnb3BhcXVlJykge1xuICAgICAgICAgICAgcmV0dXJuIENvbG9yTW9kZS51bmJsZW5kZWQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gQ29sb3JNb2RlLmFscGhhQmxlbmRlZDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRlcHRoTW9kZUZvclN1YmxheWVyKG46IG51bWJlciwgbWFzazogRGVwdGhNYXNrVHlwZSwgZnVuYzogP0RlcHRoRnVuY1R5cGUpOiAkUmVhZE9ubHk8RGVwdGhNb2RlPiB7XG4gICAgICAgIGlmICghdGhpcy5vcGFxdWVQYXNzRW5hYmxlZEZvckxheWVyKCkpIHJldHVybiBEZXB0aE1vZGUuZGlzYWJsZWQ7XG4gICAgICAgIGNvbnN0IGRlcHRoID0gMSAtICgoMSArIHRoaXMuY3VycmVudExheWVyKSAqIHRoaXMubnVtU3VibGF5ZXJzICsgbikgKiB0aGlzLmRlcHRoRXBzaWxvbjtcbiAgICAgICAgcmV0dXJuIG5ldyBEZXB0aE1vZGUoZnVuYyB8fCB0aGlzLmNvbnRleHQuZ2wuTEVRVUFMLCBtYXNrLCBbZGVwdGgsIGRlcHRoXSk7XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBUaGUgb3BhcXVlIHBhc3MgYW5kIDNEIGxheWVycyBib3RoIHVzZSB0aGUgZGVwdGggYnVmZmVyLlxuICAgICAqIExheWVycyBkcmF3biBhYm92ZSAzRCBsYXllcnMgbmVlZCB0byBiZSBkcmF3biB1c2luZyB0aGVcbiAgICAgKiBwYWludGVyJ3MgYWxnb3JpdGhtIHNvIHRoYXQgdGhleSBhcHBlYXIgYWJvdmUgM0QgZmVhdHVyZXMuXG4gICAgICogVGhpcyByZXR1cm5zIHRydWUgZm9yIGxheWVycyB0aGF0IGNhbiBiZSBkcmF3biB1c2luZyB0aGVcbiAgICAgKiBvcGFxdWUgcGFzcy5cbiAgICAgKi9cbiAgICBvcGFxdWVQYXNzRW5hYmxlZEZvckxheWVyKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5jdXJyZW50TGF5ZXIgPCB0aGlzLm9wYXF1ZVBhc3NDdXRvZmY7XG4gICAgfVxuXG4gICAgcmVuZGVyKHN0eWxlOiBTdHlsZSwgb3B0aW9uczogUGFpbnRlck9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy5zdHlsZSA9IHN0eWxlO1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuXG4gICAgICAgIHRoaXMuaW1hZ2VNYW5hZ2VyID0gc3R5bGUuaW1hZ2VNYW5hZ2VyO1xuICAgICAgICB0aGlzLmdseXBoTWFuYWdlciA9IHN0eWxlLmdseXBoTWFuYWdlcjtcblxuICAgICAgICB0aGlzLnN5bWJvbEZhZGVDaGFuZ2UgPSBzdHlsZS5wbGFjZW1lbnQuc3ltYm9sRmFkZUNoYW5nZShicm93c2VyLm5vdygpKTtcblxuICAgICAgICB0aGlzLmltYWdlTWFuYWdlci5iZWdpbkZyYW1lKCk7XG5cbiAgICAgICAgY29uc3QgbGF5ZXJJZHMgPSB0aGlzLnN0eWxlLm9yZGVyO1xuICAgICAgICBjb25zdCBzb3VyY2VDYWNoZXMgPSB0aGlzLnN0eWxlLl9zb3VyY2VDYWNoZXM7XG5cbiAgICAgICAgZm9yIChjb25zdCBpZCBpbiBzb3VyY2VDYWNoZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHNvdXJjZUNhY2hlID0gc291cmNlQ2FjaGVzW2lkXTtcbiAgICAgICAgICAgIGlmIChzb3VyY2VDYWNoZS51c2VkKSB7XG4gICAgICAgICAgICAgICAgc291cmNlQ2FjaGUucHJlcGFyZSh0aGlzLmNvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY29vcmRzQXNjZW5kaW5nOiB7W186IHN0cmluZ106IEFycmF5PE92ZXJzY2FsZWRUaWxlSUQ+fSA9IHt9O1xuICAgICAgICBjb25zdCBjb29yZHNEZXNjZW5kaW5nOiB7W186IHN0cmluZ106IEFycmF5PE92ZXJzY2FsZWRUaWxlSUQ+fSA9IHt9O1xuICAgICAgICBjb25zdCBjb29yZHNEZXNjZW5kaW5nU3ltYm9sOiB7W186IHN0cmluZ106IEFycmF5PE92ZXJzY2FsZWRUaWxlSUQ+fSA9IHt9O1xuXG4gICAgICAgIGZvciAoY29uc3QgaWQgaW4gc291cmNlQ2FjaGVzKSB7XG4gICAgICAgICAgICBjb25zdCBzb3VyY2VDYWNoZSA9IHNvdXJjZUNhY2hlc1tpZF07XG4gICAgICAgICAgICBjb29yZHNBc2NlbmRpbmdbaWRdID0gc291cmNlQ2FjaGUuZ2V0VmlzaWJsZUNvb3JkaW5hdGVzKCk7XG4gICAgICAgICAgICBjb29yZHNEZXNjZW5kaW5nW2lkXSA9IGNvb3Jkc0FzY2VuZGluZ1tpZF0uc2xpY2UoKS5yZXZlcnNlKCk7XG4gICAgICAgICAgICBjb29yZHNEZXNjZW5kaW5nU3ltYm9sW2lkXSA9IHNvdXJjZUNhY2hlLmdldFZpc2libGVDb29yZGluYXRlcyh0cnVlKS5yZXZlcnNlKCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm9wYXF1ZVBhc3NDdXRvZmYgPSBJbmZpbml0eTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsYXllcklkcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgbGF5ZXJJZCA9IGxheWVySWRzW2ldO1xuICAgICAgICAgICAgaWYgKHRoaXMuc3R5bGUuX2xheWVyc1tsYXllcklkXS5pczNEKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wYXF1ZVBhc3NDdXRvZmYgPSBpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMudGVycmFpbikge1xuICAgICAgICAgICAgdGhpcy50ZXJyYWluLnVwZGF0ZVRpbGVCaW5kaW5nKGNvb3Jkc0Rlc2NlbmRpbmdTeW1ib2wpO1xuICAgICAgICAgICAgLy8gQWxsIHJlbmRlciB0byB0ZXh0dXJlIGlzIGRvbmUgaW4gdHJhbnNsdWNlbnQgcGFzcyB0byByZW1vdmUgbmVlZFxuICAgICAgICAgICAgLy8gZm9yIGRlcHRoIGJ1ZmZlciBhbGxvY2F0aW9uIHBlciB0aWxlLlxuICAgICAgICAgICAgdGhpcy5vcGFxdWVQYXNzQ3V0b2ZmID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybS5wcm9qZWN0aW9uLm5hbWUgPT09ICdnbG9iZScgJiYgIXRoaXMuZ2xvYmVTaGFyZWRCdWZmZXJzKSB7XG4gICAgICAgICAgICB0aGlzLmdsb2JlU2hhcmVkQnVmZmVycyA9IG5ldyBHbG9iZVNoYXJlZEJ1ZmZlcnModGhpcy5jb250ZXh0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZvbGxvd2luZyBsaW5lIGlzIGJpbGxpbmcgcmVsYXRlZCBjb2RlLiBEbyBub3QgY2hhbmdlLiBTZWUgTElDRU5TRS50eHRcbiAgICAgICAgaWYgKCFpc01hcEF1dGhlbnRpY2F0ZWQodGhpcy5jb250ZXh0LmdsKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIE9mZnNjcmVlbiBwYXNzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgICAgIC8vIFdlIGZpcnN0IGRvIGFsbCByZW5kZXJpbmcgdGhhdCByZXF1aXJlcyByZW5kZXJpbmcgdG8gYSBzZXBhcmF0ZVxuICAgICAgICAvLyBmcmFtZWJ1ZmZlciwgYW5kIHRoZW4gc2F2ZSB0aG9zZSBmb3IgcmVuZGVyaW5nIGJhY2sgdG8gdGhlIG1hcFxuICAgICAgICAvLyBsYXRlcjogaW4gZG9pbmcgdGhpcyB3ZSBhdm9pZCBkb2luZyBleHBlbnNpdmUgZnJhbWVidWZmZXIgcmVzdG9yZXMuXG4gICAgICAgIHRoaXMucmVuZGVyUGFzcyA9ICdvZmZzY3JlZW4nO1xuXG4gICAgICAgIGZvciAoY29uc3QgbGF5ZXJJZCBvZiBsYXllcklkcykge1xuICAgICAgICAgICAgY29uc3QgbGF5ZXIgPSB0aGlzLnN0eWxlLl9sYXllcnNbbGF5ZXJJZF07XG4gICAgICAgICAgICBjb25zdCBzb3VyY2VDYWNoZSA9IHN0eWxlLl9nZXRMYXllclNvdXJjZUNhY2hlKGxheWVyKTtcbiAgICAgICAgICAgIGlmICghbGF5ZXIuaGFzT2Zmc2NyZWVuUGFzcygpIHx8IGxheWVyLmlzSGlkZGVuKHRoaXMudHJhbnNmb3JtLnpvb20pKSBjb250aW51ZTtcblxuICAgICAgICAgICAgY29uc3QgY29vcmRzID0gc291cmNlQ2FjaGUgPyBjb29yZHNEZXNjZW5kaW5nW3NvdXJjZUNhY2hlLmlkXSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGlmICghKGxheWVyLnR5cGUgPT09ICdjdXN0b20nIHx8IGxheWVyLmlzU2t5KCkpICYmICEoY29vcmRzICYmIGNvb3Jkcy5sZW5ndGgpKSBjb250aW51ZTtcblxuICAgICAgICAgICAgdGhpcy5yZW5kZXJMYXllcih0aGlzLCBzb3VyY2VDYWNoZSwgbGF5ZXIsIGNvb3Jkcyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmRlcHRoUmFuZ2VGb3IzRCA9IFswLCAxIC0gKChzdHlsZS5vcmRlci5sZW5ndGggKyAyKSAqIHRoaXMubnVtU3VibGF5ZXJzICogdGhpcy5kZXB0aEVwc2lsb24pXTtcblxuICAgICAgICAvLyBUZXJyYWluIGRlcHRoIG9mZnNjcmVlbiByZW5kZXIgcGFzcyA9PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgICAgICAvLyBXaXRoIHRlcnJhaW4gb24sIHJlbmRlcnMgdGhlIGRlcHRoIGJ1ZmZlciBpbnRvIGEgdGV4dHVyZS5cbiAgICAgICAgLy8gVGhpcyB0ZXh0dXJlIGlzIHVzZWQgZm9yIG9jY2x1c2lvbiB0ZXN0aW5nIChsYWJlbHMpXG4gICAgICAgIGNvbnN0IHRlcnJhaW4gPSB0aGlzLnRlcnJhaW47XG4gICAgICAgIGlmICh0ZXJyYWluICYmICh0aGlzLnN0eWxlLmhhc1N5bWJvbExheWVycygpIHx8IHRoaXMuc3R5bGUuaGFzQ2lyY2xlTGF5ZXJzKCkpKSB7XG4gICAgICAgICAgICB0ZXJyYWluLmRyYXdEZXB0aCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmViaW5kIHRoZSBtYWluIGZyYW1lYnVmZmVyIG5vdyB0aGF0IGFsbCBvZmZzY3JlZW4gbGF5ZXJzIGhhdmUgYmVlbiByZW5kZXJlZDpcbiAgICAgICAgdGhpcy5jb250ZXh0LmJpbmRGcmFtZWJ1ZmZlci5zZXQobnVsbCk7XG4gICAgICAgIHRoaXMuY29udGV4dC52aWV3cG9ydC5zZXQoWzAsIDAsIHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0XSk7XG5cbiAgICAgICAgLy8gQ2xlYXIgYnVmZmVycyBpbiBwcmVwYXJhdGlvbiBmb3IgZHJhd2luZyB0byB0aGUgbWFpbiBmcmFtZWJ1ZmZlclxuICAgICAgICB0aGlzLmNvbnRleHQuY2xlYXIoe2NvbG9yOiBvcHRpb25zLnNob3dPdmVyZHJhd0luc3BlY3RvciA/IENvbG9yLmJsYWNrIDogQ29sb3IudHJhbnNwYXJlbnQsIGRlcHRoOiAxfSk7XG4gICAgICAgIHRoaXMuY2xlYXJTdGVuY2lsKCk7XG5cbiAgICAgICAgdGhpcy5fc2hvd092ZXJkcmF3SW5zcGVjdG9yID0gb3B0aW9ucy5zaG93T3ZlcmRyYXdJbnNwZWN0b3I7XG5cbiAgICAgICAgLy8gT3BhcXVlIHBhc3MgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAgICAgLy8gRHJhdyBvcGFxdWUgbGF5ZXJzIHRvcC10by1ib3R0b20gZmlyc3QuXG4gICAgICAgIHRoaXMucmVuZGVyUGFzcyA9ICdvcGFxdWUnO1xuXG4gICAgICAgIGlmICghdGhpcy50ZXJyYWluKSB7XG4gICAgICAgICAgICBmb3IgKHRoaXMuY3VycmVudExheWVyID0gbGF5ZXJJZHMubGVuZ3RoIC0gMTsgdGhpcy5jdXJyZW50TGF5ZXIgPj0gMDsgdGhpcy5jdXJyZW50TGF5ZXItLSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGxheWVyID0gdGhpcy5zdHlsZS5fbGF5ZXJzW2xheWVySWRzW3RoaXMuY3VycmVudExheWVyXV07XG4gICAgICAgICAgICAgICAgY29uc3Qgc291cmNlQ2FjaGUgPSBzdHlsZS5fZ2V0TGF5ZXJTb3VyY2VDYWNoZShsYXllcik7XG4gICAgICAgICAgICAgICAgaWYgKGxheWVyLmlzU2t5KCkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvb3JkcyA9IHNvdXJjZUNhY2hlID8gY29vcmRzRGVzY2VuZGluZ1tzb3VyY2VDYWNoZS5pZF0gOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgICAgICB0aGlzLl9yZW5kZXJUaWxlQ2xpcHBpbmdNYXNrcyhsYXllciwgc291cmNlQ2FjaGUsIGNvb3Jkcyk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJMYXllcih0aGlzLCBzb3VyY2VDYWNoZSwgbGF5ZXIsIGNvb3Jkcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5zdHlsZS5mb2cgJiYgdGhpcy50cmFuc2Zvcm0ucHJvamVjdGlvbi5zdXBwb3J0c0ZvZykge1xuICAgICAgICAgICAgZHJhd0F0bW9zcGhlcmUodGhpcywgdGhpcy5zdHlsZS5mb2cpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2t5IHBhc3MgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgICAgIC8vIERyYXcgYWxsIHNreSBsYXllcnMgYm90dG9tIHRvIHRvcC5cbiAgICAgICAgLy8gVGhleSBhcmUgZHJhd24gYXQgbWF4IGRlcHRoLCB0aGV5IGFyZSBkcmF3biBhZnRlciBvcGFxdWUgYW5kIGJlZm9yZVxuICAgICAgICAvLyB0cmFuc2x1Y2VudCB0byBmYWlsIGRlcHRoIHRlc3RpbmcgYW5kIG1peCB3aXRoIHRyYW5zbHVjZW50IG9iamVjdHMuXG4gICAgICAgIHRoaXMucmVuZGVyUGFzcyA9ICdza3knO1xuICAgICAgICBjb25zdCBpc1RyYW5zaXRpb25pbmcgPSBnbG9iZVRvTWVyY2F0b3JUcmFuc2l0aW9uKHRoaXMudHJhbnNmb3JtLnpvb20pID4gMC4wO1xuICAgICAgICBpZiAoKGlzVHJhbnNpdGlvbmluZyB8fCB0aGlzLnRyYW5zZm9ybS5wcm9qZWN0aW9uLm5hbWUgIT09ICdnbG9iZScpICYmIHRoaXMudHJhbnNmb3JtLmlzSG9yaXpvblZpc2libGUoKSkge1xuICAgICAgICAgICAgZm9yICh0aGlzLmN1cnJlbnRMYXllciA9IDA7IHRoaXMuY3VycmVudExheWVyIDwgbGF5ZXJJZHMubGVuZ3RoOyB0aGlzLmN1cnJlbnRMYXllcisrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbGF5ZXIgPSB0aGlzLnN0eWxlLl9sYXllcnNbbGF5ZXJJZHNbdGhpcy5jdXJyZW50TGF5ZXJdXTtcbiAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2VDYWNoZSA9IHN0eWxlLl9nZXRMYXllclNvdXJjZUNhY2hlKGxheWVyKTtcbiAgICAgICAgICAgICAgICBpZiAoIWxheWVyLmlzU2t5KCkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvb3JkcyA9IHNvdXJjZUNhY2hlID8gY29vcmRzRGVzY2VuZGluZ1tzb3VyY2VDYWNoZS5pZF0gOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlckxheWVyKHRoaXMsIHNvdXJjZUNhY2hlLCBsYXllciwgY29vcmRzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRyYW5zbHVjZW50IHBhc3MgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAgICAgLy8gRHJhdyBhbGwgb3RoZXIgbGF5ZXJzIGJvdHRvbS10by10b3AuXG4gICAgICAgIHRoaXMucmVuZGVyUGFzcyA9ICd0cmFuc2x1Y2VudCc7XG5cbiAgICAgICAgdGhpcy5jdXJyZW50TGF5ZXIgPSAwO1xuICAgICAgICB3aGlsZSAodGhpcy5jdXJyZW50TGF5ZXIgPCBsYXllcklkcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNvbnN0IGxheWVyID0gdGhpcy5zdHlsZS5fbGF5ZXJzW2xheWVySWRzW3RoaXMuY3VycmVudExheWVyXV07XG4gICAgICAgICAgICBjb25zdCBzb3VyY2VDYWNoZSA9IHN0eWxlLl9nZXRMYXllclNvdXJjZUNhY2hlKGxheWVyKTtcblxuICAgICAgICAgICAgLy8gTm90aGluZyB0byBkcmF3IGluIHRyYW5zbHVjZW50IHBhc3MgZm9yIHNreSBsYXllcnMsIGFkdmFuY2VcbiAgICAgICAgICAgIGlmIChsYXllci5pc1NreSgpKSB7XG4gICAgICAgICAgICAgICAgKyt0aGlzLmN1cnJlbnRMYXllcjtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gV2l0aCB0ZXJyYWluIG9uIGFuZCBmb3IgZHJhcGVkIGxheWVycyBvbmx5LCBpc3N1ZSByZW5kZXJpbmcgYW5kIHByb2dyZXNzXG4gICAgICAgICAgICAvLyB0aGlzLmN1cnJlbnRMYXllciB1bnRpbCB0aGUgbmV4dCBub24tZHJhcGVkIGxheWVyLlxuICAgICAgICAgICAgLy8gT3RoZXJ3aXNlIHdlIGludGVybGVhdmUgdGVycmFpbiBkcmFwZWQgcmVuZGVyIHdpdGggbm9uLWRyYXBlZCBsYXllcnMgb24gdG9wXG4gICAgICAgICAgICBpZiAodGhpcy50ZXJyYWluICYmIHRoaXMuc3R5bGUuaXNMYXllckRyYXBlZChsYXllcikpIHtcbiAgICAgICAgICAgICAgICBpZiAobGF5ZXIuaXNIaWRkZW4odGhpcy50cmFuc2Zvcm0uem9vbSkpIHtcbiAgICAgICAgICAgICAgICAgICAgKyt0aGlzLmN1cnJlbnRMYXllcjtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHRlcnJhaW4gPSAoKCh0aGlzLnRlcnJhaW4pOiBhbnkpOiBUZXJyYWluKTtcbiAgICAgICAgICAgICAgICBjb25zdCBwcmV2TGF5ZXIgPSB0aGlzLmN1cnJlbnRMYXllcjtcbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRMYXllciA9IHRlcnJhaW4ucmVuZGVyQmF0Y2godGhpcy5jdXJyZW50TGF5ZXIpO1xuICAgICAgICAgICAgICAgIGFzc2VydCh0aGlzLmNvbnRleHQuYmluZEZyYW1lYnVmZmVyLmN1cnJlbnQgPT09IG51bGwpO1xuICAgICAgICAgICAgICAgIGFzc2VydCh0aGlzLmN1cnJlbnRMYXllciA+IHByZXZMYXllcik7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEZvciBzeW1ib2wgbGF5ZXJzIGluIHRoZSB0cmFuc2x1Y2VudCBwYXNzLCB3ZSBhZGQgZXh0cmEgdGlsZXMgdG8gdGhlIHJlbmRlcmFibGUgc2V0XG4gICAgICAgICAgICAvLyBmb3IgY3Jvc3MtdGlsZSBzeW1ib2wgZmFkaW5nLiBTeW1ib2wgbGF5ZXJzIGRvbid0IHVzZSB0aWxlIGNsaXBwaW5nLCBzbyBubyBuZWVkIHRvIHJlbmRlclxuICAgICAgICAgICAgLy8gc2VwYXJhdGUgY2xpcHBpbmcgbWFza3NcbiAgICAgICAgICAgIGNvbnN0IGNvb3JkcyA9IHNvdXJjZUNhY2hlID9cbiAgICAgICAgICAgICAgICAobGF5ZXIudHlwZSA9PT0gJ3N5bWJvbCcgPyBjb29yZHNEZXNjZW5kaW5nU3ltYm9sIDogY29vcmRzRGVzY2VuZGluZylbc291cmNlQ2FjaGUuaWRdIDpcbiAgICAgICAgICAgICAgICB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgIHRoaXMuX3JlbmRlclRpbGVDbGlwcGluZ01hc2tzKGxheWVyLCBzb3VyY2VDYWNoZSwgc291cmNlQ2FjaGUgPyBjb29yZHNBc2NlbmRpbmdbc291cmNlQ2FjaGUuaWRdIDogdW5kZWZpbmVkKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyTGF5ZXIodGhpcywgc291cmNlQ2FjaGUsIGxheWVyLCBjb29yZHMpO1xuXG4gICAgICAgICAgICArK3RoaXMuY3VycmVudExheWVyO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMudGVycmFpbikge1xuICAgICAgICAgICAgdGhpcy50ZXJyYWluLnBvc3RSZW5kZXIoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc2hvd1RpbGVCb3VuZGFyaWVzIHx8IHRoaXMub3B0aW9ucy5zaG93UXVlcnlHZW9tZXRyeSB8fCB0aGlzLm9wdGlvbnMuc2hvd1RpbGVBQUJCcykge1xuICAgICAgICAgICAgLy9Vc2Ugc291cmNlIHdpdGggaGlnaGVzdCBtYXh6b29tXG4gICAgICAgICAgICBsZXQgc2VsZWN0ZWRTb3VyY2UgPSBudWxsO1xuICAgICAgICAgICAgY29uc3QgbGF5ZXJzID0gdmFsdWVzKHRoaXMuc3R5bGUuX2xheWVycyk7XG4gICAgICAgICAgICBsYXllcnMuZm9yRWFjaCgobGF5ZXIpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2VDYWNoZSA9IHN0eWxlLl9nZXRMYXllclNvdXJjZUNhY2hlKGxheWVyKTtcbiAgICAgICAgICAgICAgICBpZiAoc291cmNlQ2FjaGUgJiYgIWxheWVyLmlzSGlkZGVuKHRoaXMudHJhbnNmb3JtLnpvb20pKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghc2VsZWN0ZWRTb3VyY2UgfHwgKHNlbGVjdGVkU291cmNlLmdldFNvdXJjZSgpLm1heHpvb20gPCBzb3VyY2VDYWNoZS5nZXRTb3VyY2UoKS5tYXh6b29tKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRTb3VyY2UgPSBzb3VyY2VDYWNoZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKHNlbGVjdGVkU291cmNlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zaG93VGlsZUJvdW5kYXJpZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgZHJhdy5kZWJ1Zyh0aGlzLCBzZWxlY3RlZFNvdXJjZSwgc2VsZWN0ZWRTb3VyY2UuZ2V0VmlzaWJsZUNvb3JkaW5hdGVzKCkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIERlYnVnLnJ1bigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghc2VsZWN0ZWRTb3VyY2UpIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zaG93UXVlcnlHZW9tZXRyeSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZHJhd0RlYnVnUXVlcnlHZW9tZXRyeSh0aGlzLCBzZWxlY3RlZFNvdXJjZSwgc2VsZWN0ZWRTb3VyY2UuZ2V0VmlzaWJsZUNvb3JkaW5hdGVzKCkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc2hvd1RpbGVBQUJCcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgRGVidWcuZHJhd0FhYmJzKHRoaXMsIHNlbGVjdGVkU291cmNlLCBzZWxlY3RlZFNvdXJjZS5nZXRWaXNpYmxlQ29vcmRpbmF0ZXMoKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc2hvd1BhZGRpbmcpIHtcbiAgICAgICAgICAgIGRyYXdEZWJ1Z1BhZGRpbmcodGhpcyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgZGVmYXVsdHMgZm9yIG1vc3QgR0wgdmFsdWVzIHNvIHRoYXQgYW55b25lIHVzaW5nIHRoZSBzdGF0ZSBhZnRlciB0aGUgcmVuZGVyXG4gICAgICAgIC8vIGVuY291bnRlcnMgbW9yZSBleHBlY3RlZCB2YWx1ZXMuXG4gICAgICAgIHRoaXMuY29udGV4dC5zZXREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuZnJhbWVDb3VudGVyID0gKHRoaXMuZnJhbWVDb3VudGVyICsgMSkgJSBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUjtcblxuICAgICAgICBpZiAodGhpcy50aWxlTG9hZGVkICYmIHRoaXMub3B0aW9ucy5zcGVlZEluZGV4VGltaW5nKSB7XG4gICAgICAgICAgICB0aGlzLmxvYWRUaW1lU3RhbXBzLnB1c2god2luZG93LnBlcmZvcm1hbmNlLm5vdygpKTtcbiAgICAgICAgICAgIHRoaXMuc2F2ZUNhbnZhc0NvcHkoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJlbmRlckxheWVyKHBhaW50ZXI6IFBhaW50ZXIsIHNvdXJjZUNhY2hlPzogU291cmNlQ2FjaGUsIGxheWVyOiBTdHlsZUxheWVyLCBjb29yZHM/OiBBcnJheTxPdmVyc2NhbGVkVGlsZUlEPikge1xuICAgICAgICBpZiAobGF5ZXIuaXNIaWRkZW4odGhpcy50cmFuc2Zvcm0uem9vbSkpIHJldHVybjtcbiAgICAgICAgaWYgKGxheWVyLnR5cGUgIT09ICdiYWNrZ3JvdW5kJyAmJiBsYXllci50eXBlICE9PSAnc2t5JyAmJiBsYXllci50eXBlICE9PSAnY3VzdG9tJyAmJiAhKGNvb3JkcyAmJiBjb29yZHMubGVuZ3RoKSkgcmV0dXJuO1xuICAgICAgICB0aGlzLmlkID0gbGF5ZXIuaWQ7XG5cbiAgICAgICAgdGhpcy5ncHVUaW1pbmdTdGFydChsYXllcik7XG4gICAgICAgIGlmICghcGFpbnRlci50cmFuc2Zvcm0ucHJvamVjdGlvbi51bnN1cHBvcnRlZExheWVycyB8fCAhcGFpbnRlci50cmFuc2Zvcm0ucHJvamVjdGlvbi51bnN1cHBvcnRlZExheWVycy5pbmNsdWRlcyhsYXllci50eXBlKSB8fFxuICAgICAgICAgICAgKHBhaW50ZXIudGVycmFpbiAmJiBsYXllci50eXBlID09PSAnY3VzdG9tJykpIHtcbiAgICAgICAgICAgIGRyYXdbbGF5ZXIudHlwZV0ocGFpbnRlciwgc291cmNlQ2FjaGUsIGxheWVyLCBjb29yZHMsIHRoaXMuc3R5bGUucGxhY2VtZW50LnZhcmlhYmxlT2Zmc2V0cywgdGhpcy5vcHRpb25zLmlzSW5pdGlhbExvYWQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZ3B1VGltaW5nRW5kKCk7XG4gICAgfVxuXG4gICAgZ3B1VGltaW5nU3RhcnQobGF5ZXI6IFN0eWxlTGF5ZXIpIHtcbiAgICAgICAgaWYgKCF0aGlzLm9wdGlvbnMuZ3B1VGltaW5nKSByZXR1cm47XG4gICAgICAgIGNvbnN0IGV4dCA9IHRoaXMuY29udGV4dC5leHRUaW1lclF1ZXJ5O1xuICAgICAgICAvLyBUaGlzIHRyaWVzIHRvIHRpbWUgdGhlIGRyYXcgY2FsbCBpdHNlbGYsIGJ1dCBub3RlIHRoYXQgdGhlIGNvc3QgZm9yIGRyYXdpbmcgYSBsYXllclxuICAgICAgICAvLyBtYXkgYmUgZG9taW5hdGVkIGJ5IHRoZSBjb3N0IG9mIHVwbG9hZGluZyB2ZXJ0aWNlcyB0byB0aGUgR1BVLlxuICAgICAgICAvLyBUbyBpbnN0cnVtZW50IHRoYXQsIHdlJ2QgbmVlZCB0byBwYXNzIHRoZSBsYXllclRpbWVycyBvYmplY3QgZG93biBpbnRvIHRoZSBidWNrZXRcbiAgICAgICAgLy8gdXBsb2FkaW5nIGxvZ2ljLlxuICAgICAgICBsZXQgbGF5ZXJUaW1lciA9IHRoaXMuZ3B1VGltZXJzW2xheWVyLmlkXTtcbiAgICAgICAgaWYgKCFsYXllclRpbWVyKSB7XG4gICAgICAgICAgICBsYXllclRpbWVyID0gdGhpcy5ncHVUaW1lcnNbbGF5ZXIuaWRdID0ge1xuICAgICAgICAgICAgICAgIGNhbGxzOiAwLFxuICAgICAgICAgICAgICAgIGNwdVRpbWU6IDAsXG4gICAgICAgICAgICAgICAgcXVlcnk6IGV4dC5jcmVhdGVRdWVyeUVYVCgpXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGxheWVyVGltZXIuY2FsbHMrKztcbiAgICAgICAgZXh0LmJlZ2luUXVlcnlFWFQoZXh0LlRJTUVfRUxBUFNFRF9FWFQsIGxheWVyVGltZXIucXVlcnkpO1xuICAgIH1cblxuICAgIGdwdVRpbWluZ0RlZmVycmVkUmVuZGVyU3RhcnQoKSB7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuZ3B1VGltaW5nRGVmZXJyZWRSZW5kZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IGV4dCA9IHRoaXMuY29udGV4dC5leHRUaW1lclF1ZXJ5O1xuICAgICAgICAgICAgY29uc3QgcXVlcnkgPSBleHQuY3JlYXRlUXVlcnlFWFQoKTtcbiAgICAgICAgICAgIHRoaXMuZGVmZXJyZWRSZW5kZXJHcHVUaW1lUXVlcmllcy5wdXNoKHF1ZXJ5KTtcbiAgICAgICAgICAgIGV4dC5iZWdpblF1ZXJ5RVhUKGV4dC5USU1FX0VMQVBTRURfRVhULCBxdWVyeSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBncHVUaW1pbmdEZWZlcnJlZFJlbmRlckVuZCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLm9wdGlvbnMuZ3B1VGltaW5nRGVmZXJyZWRSZW5kZXIpIHJldHVybjtcbiAgICAgICAgY29uc3QgZXh0ID0gdGhpcy5jb250ZXh0LmV4dFRpbWVyUXVlcnk7XG4gICAgICAgIGV4dC5lbmRRdWVyeUVYVChleHQuVElNRV9FTEFQU0VEX0VYVCk7XG4gICAgfVxuXG4gICAgZ3B1VGltaW5nRW5kKCkge1xuICAgICAgICBpZiAoIXRoaXMub3B0aW9ucy5ncHVUaW1pbmcpIHJldHVybjtcbiAgICAgICAgY29uc3QgZXh0ID0gdGhpcy5jb250ZXh0LmV4dFRpbWVyUXVlcnk7XG4gICAgICAgIGV4dC5lbmRRdWVyeUVYVChleHQuVElNRV9FTEFQU0VEX0VYVCk7XG4gICAgfVxuXG4gICAgY29sbGVjdEdwdVRpbWVycygpOiBHUFVUaW1lcnMge1xuICAgICAgICBjb25zdCBjdXJyZW50TGF5ZXJUaW1lcnMgPSB0aGlzLmdwdVRpbWVycztcbiAgICAgICAgdGhpcy5ncHVUaW1lcnMgPSB7fTtcbiAgICAgICAgcmV0dXJuIGN1cnJlbnRMYXllclRpbWVycztcbiAgICB9XG5cbiAgICBjb2xsZWN0RGVmZXJyZWRSZW5kZXJHcHVRdWVyaWVzKCk6IEFycmF5PGFueT4ge1xuICAgICAgICBjb25zdCBjdXJyZW50UXVlcmllcyA9IHRoaXMuZGVmZXJyZWRSZW5kZXJHcHVUaW1lUXVlcmllcztcbiAgICAgICAgdGhpcy5kZWZlcnJlZFJlbmRlckdwdVRpbWVRdWVyaWVzID0gW107XG4gICAgICAgIHJldHVybiBjdXJyZW50UXVlcmllcztcbiAgICB9XG5cbiAgICBxdWVyeUdwdVRpbWVycyhncHVUaW1lcnM6IEdQVVRpbWVycyk6IHtbbGF5ZXJJZDogc3RyaW5nXTogbnVtYmVyfSB7XG4gICAgICAgIGNvbnN0IGxheWVycyA9IHt9O1xuICAgICAgICBmb3IgKGNvbnN0IGxheWVySWQgaW4gZ3B1VGltZXJzKSB7XG4gICAgICAgICAgICBjb25zdCBncHVUaW1lciA9IGdwdVRpbWVyc1tsYXllcklkXTtcbiAgICAgICAgICAgIGNvbnN0IGV4dCA9IHRoaXMuY29udGV4dC5leHRUaW1lclF1ZXJ5O1xuICAgICAgICAgICAgY29uc3QgZ3B1VGltZSA9IGV4dC5nZXRRdWVyeU9iamVjdEVYVChncHVUaW1lci5xdWVyeSwgZXh0LlFVRVJZX1JFU1VMVF9FWFQpIC8gKDEwMDAgKiAxMDAwKTtcbiAgICAgICAgICAgIGV4dC5kZWxldGVRdWVyeUVYVChncHVUaW1lci5xdWVyeSk7XG4gICAgICAgICAgICBsYXllcnNbbGF5ZXJJZF0gPSAoZ3B1VGltZTogbnVtYmVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbGF5ZXJzO1xuICAgIH1cblxuICAgIHF1ZXJ5R3B1VGltZURlZmVycmVkUmVuZGVyKGdwdVF1ZXJpZXM6IEFycmF5PGFueT4pOiBudW1iZXIge1xuICAgICAgICBpZiAoIXRoaXMub3B0aW9ucy5ncHVUaW1pbmdEZWZlcnJlZFJlbmRlcikgcmV0dXJuIDA7XG4gICAgICAgIGNvbnN0IGV4dCA9IHRoaXMuY29udGV4dC5leHRUaW1lclF1ZXJ5O1xuXG4gICAgICAgIGxldCBncHVUaW1lID0gMDtcbiAgICAgICAgZm9yIChjb25zdCBxdWVyeSBvZiBncHVRdWVyaWVzKSB7XG4gICAgICAgICAgICBncHVUaW1lICs9IGV4dC5nZXRRdWVyeU9iamVjdEVYVChxdWVyeSwgZXh0LlFVRVJZX1JFU1VMVF9FWFQpIC8gKDEwMDAgKiAxMDAwKTtcbiAgICAgICAgICAgIGV4dC5kZWxldGVRdWVyeUVYVChxdWVyeSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZ3B1VGltZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmFuc2Zvcm0gYSBtYXRyaXggdG8gaW5jb3Jwb3JhdGUgdGhlICotdHJhbnNsYXRlIGFuZCAqLXRyYW5zbGF0ZS1hbmNob3IgcHJvcGVydGllcyBpbnRvIGl0LlxuICAgICAqIEBwYXJhbSBpblZpZXdwb3J0UGl4ZWxVbml0c1VuaXRzIFRydWUgd2hlbiB0aGUgdW5pdHMgYWNjZXB0ZWQgYnkgdGhlIG1hdHJpeCBhcmUgaW4gdmlld3BvcnQgcGl4ZWxzIGluc3RlYWQgb2YgdGlsZSB1bml0cy5cbiAgICAgKiBAcmV0dXJucyB7RmxvYXQzMkFycmF5fSBtYXRyaXhcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHRyYW5zbGF0ZVBvc01hdHJpeChtYXRyaXg6IEZsb2F0MzJBcnJheSwgdGlsZTogVGlsZSwgdHJhbnNsYXRlOiBbbnVtYmVyLCBudW1iZXJdLCB0cmFuc2xhdGVBbmNob3I6ICdtYXAnIHwgJ3ZpZXdwb3J0JywgaW5WaWV3cG9ydFBpeGVsVW5pdHNVbml0cz86IGJvb2xlYW4pOiBGbG9hdDMyQXJyYXkge1xuICAgICAgICBpZiAoIXRyYW5zbGF0ZVswXSAmJiAhdHJhbnNsYXRlWzFdKSByZXR1cm4gbWF0cml4O1xuXG4gICAgICAgIGNvbnN0IGFuZ2xlID0gaW5WaWV3cG9ydFBpeGVsVW5pdHNVbml0cyA/XG4gICAgICAgICAgICAodHJhbnNsYXRlQW5jaG9yID09PSAnbWFwJyA/IHRoaXMudHJhbnNmb3JtLmFuZ2xlIDogMCkgOlxuICAgICAgICAgICAgKHRyYW5zbGF0ZUFuY2hvciA9PT0gJ3ZpZXdwb3J0JyA/IC10aGlzLnRyYW5zZm9ybS5hbmdsZSA6IDApO1xuXG4gICAgICAgIGlmIChhbmdsZSkge1xuICAgICAgICAgICAgY29uc3Qgc2luQSA9IE1hdGguc2luKGFuZ2xlKTtcbiAgICAgICAgICAgIGNvbnN0IGNvc0EgPSBNYXRoLmNvcyhhbmdsZSk7XG4gICAgICAgICAgICB0cmFuc2xhdGUgPSBbXG4gICAgICAgICAgICAgICAgdHJhbnNsYXRlWzBdICogY29zQSAtIHRyYW5zbGF0ZVsxXSAqIHNpbkEsXG4gICAgICAgICAgICAgICAgdHJhbnNsYXRlWzBdICogc2luQSArIHRyYW5zbGF0ZVsxXSAqIGNvc0FcbiAgICAgICAgICAgIF07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB0cmFuc2xhdGlvbiA9IFtcbiAgICAgICAgICAgIGluVmlld3BvcnRQaXhlbFVuaXRzVW5pdHMgPyB0cmFuc2xhdGVbMF0gOiBwaXhlbHNUb1RpbGVVbml0cyh0aWxlLCB0cmFuc2xhdGVbMF0sIHRoaXMudHJhbnNmb3JtLnpvb20pLFxuICAgICAgICAgICAgaW5WaWV3cG9ydFBpeGVsVW5pdHNVbml0cyA/IHRyYW5zbGF0ZVsxXSA6IHBpeGVsc1RvVGlsZVVuaXRzKHRpbGUsIHRyYW5zbGF0ZVsxXSwgdGhpcy50cmFuc2Zvcm0uem9vbSksXG4gICAgICAgICAgICAwXG4gICAgICAgIF07XG5cbiAgICAgICAgY29uc3QgdHJhbnNsYXRlZE1hdHJpeCA9IG5ldyBGbG9hdDMyQXJyYXkoMTYpO1xuICAgICAgICBtYXQ0LnRyYW5zbGF0ZSh0cmFuc2xhdGVkTWF0cml4LCBtYXRyaXgsIHRyYW5zbGF0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRyYW5zbGF0ZWRNYXRyaXg7XG4gICAgfVxuXG4gICAgc2F2ZVRpbGVUZXh0dXJlKHRleHR1cmU6IFRleHR1cmUpIHtcbiAgICAgICAgY29uc3QgdGV4dHVyZXMgPSB0aGlzLl90aWxlVGV4dHVyZXNbdGV4dHVyZS5zaXplWzBdXTtcbiAgICAgICAgaWYgKCF0ZXh0dXJlcykge1xuICAgICAgICAgICAgdGhpcy5fdGlsZVRleHR1cmVzW3RleHR1cmUuc2l6ZVswXV0gPSBbdGV4dHVyZV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0ZXh0dXJlcy5wdXNoKHRleHR1cmUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0VGlsZVRleHR1cmUoc2l6ZTogbnVtYmVyKTogbnVsbCB8IFRleHR1cmUge1xuICAgICAgICBjb25zdCB0ZXh0dXJlcyA9IHRoaXMuX3RpbGVUZXh0dXJlc1tzaXplXTtcbiAgICAgICAgcmV0dXJuIHRleHR1cmVzICYmIHRleHR1cmVzLmxlbmd0aCA+IDAgPyB0ZXh0dXJlcy5wb3AoKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIHdoZXRoZXIgYSBwYXR0ZXJuIGltYWdlIGlzIG5lZWRlZCwgYW5kIGlmIGl0IGlzLCB3aGV0aGVyIGl0IGlzIG5vdCBsb2FkZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB0cnVlIGlmIGEgbmVlZGVkIGltYWdlIGlzIG1pc3NpbmcgYW5kIHJlbmRlcmluZyBuZWVkcyB0byBiZSBza2lwcGVkLlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgaXNQYXR0ZXJuTWlzc2luZyhpbWFnZTogP1Jlc29sdmVkSW1hZ2UpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKGltYWdlID09PSBudWxsKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgaWYgKGltYWdlID09PSB1bmRlZmluZWQpIHJldHVybiBmYWxzZTtcbiAgICAgICAgcmV0dXJuICF0aGlzLmltYWdlTWFuYWdlci5nZXRQYXR0ZXJuKGltYWdlLnRvU3RyaW5nKCkpO1xuICAgIH1cblxuICAgIHRlcnJhaW5SZW5kZXJNb2RlRWxldmF0ZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIC8vIFdoZXRoZXIgZWxldmF0aW9uIHNhbXBsaW5nIHNob3VsZCBiZSBlbmFibGVkIGluIHRoZSB2ZXJ0ZXggc2hhZGVyLlxuICAgICAgICByZXR1cm4gdGhpcy5zdHlsZSAmJiAhIXRoaXMuc3R5bGUuZ2V0VGVycmFpbigpICYmICEhdGhpcy50ZXJyYWluICYmICF0aGlzLnRlcnJhaW4ucmVuZGVyaW5nVG9UZXh0dXJlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgI2RlZmluZXMgdGhhdCB3b3VsZCBuZWVkIHRvIGJlIGluamVjdGVkIGludG8gZXZlcnkgUHJvZ3JhbVxuICAgICAqIGJhc2VkIG9uIHRoZSBjdXJyZW50IHN0YXRlIG9mIFBhaW50ZXIuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nW119XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBjdXJyZW50R2xvYmFsRGVmaW5lcygpOiBzdHJpbmdbXSB7XG4gICAgICAgIGNvbnN0IHJ0dCA9IHRoaXMudGVycmFpbiAmJiB0aGlzLnRlcnJhaW4ucmVuZGVyaW5nVG9UZXh0dXJlO1xuICAgICAgICBjb25zdCB6ZXJvRXhhZ2dlcmF0aW9uID0gdGhpcy50ZXJyYWluICYmIHRoaXMudGVycmFpbi5leGFnZ2VyYXRpb24oKSA9PT0gMC4wO1xuICAgICAgICBjb25zdCBmb2cgPSB0aGlzLnN0eWxlICYmIHRoaXMuc3R5bGUuZm9nO1xuICAgICAgICBjb25zdCBkZWZpbmVzID0gW107XG5cbiAgICAgICAgaWYgKHRoaXMudGVycmFpblJlbmRlck1vZGVFbGV2YXRlZCgpKSBkZWZpbmVzLnB1c2goJ1RFUlJBSU4nKTtcbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtLnByb2plY3Rpb24ubmFtZSA9PT0gJ2dsb2JlJykgZGVmaW5lcy5wdXNoKCdHTE9CRScpO1xuICAgICAgICBpZiAoemVyb0V4YWdnZXJhdGlvbikgZGVmaW5lcy5wdXNoKCdaRVJPX0VYQUdHRVJBVElPTicpO1xuICAgICAgICAvLyBXaGVuIHRlcnJhaW4gaXMgYWN0aXZlLCBmb2cgaXMgcmVuZGVyZWQgYXMgcGFydCBvZiBkcmFwaW5nLCBub3QgYXMgcGFydCBvZiB0aWxlXG4gICAgICAgIC8vIHJlbmRlcmluZy4gUmVtb3ZpbmcgdGhlIGZvZyBmbGFnIGR1cmluZyB0aWxlIHJlbmRlcmluZyBhdm9pZHMgYWRkaXRpb25hbCBkZWZpbmVzLlxuICAgICAgICBpZiAoZm9nICYmICFydHQgJiYgZm9nLmdldE9wYWNpdHkodGhpcy50cmFuc2Zvcm0ucGl0Y2gpICE9PSAwLjApIHtcbiAgICAgICAgICAgIGRlZmluZXMucHVzaCgnRk9HJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJ0dCkgZGVmaW5lcy5wdXNoKCdSRU5ERVJfVE9fVEVYVFVSRScpO1xuICAgICAgICBpZiAodGhpcy5fc2hvd092ZXJkcmF3SW5zcGVjdG9yKSBkZWZpbmVzLnB1c2goJ09WRVJEUkFXX0lOU1BFQ1RPUicpO1xuICAgICAgICByZXR1cm4gZGVmaW5lcztcbiAgICB9XG5cbiAgICB1c2VQcm9ncmFtKG5hbWU6IHN0cmluZywgcHJvZ3JhbUNvbmZpZ3VyYXRpb246ID9Qcm9ncmFtQ29uZmlndXJhdGlvbiwgZml4ZWREZWZpbmVzOiA/RHluYW1pY0RlZmluZXNUeXBlW10pOiBQcm9ncmFtPGFueT4ge1xuICAgICAgICB0aGlzLmNhY2hlID0gdGhpcy5jYWNoZSB8fCB7fTtcbiAgICAgICAgY29uc3QgZGVmaW5lcyA9ICgoKGZpeGVkRGVmaW5lcyB8fCBbXSk6IGFueSk6IHN0cmluZ1tdKTtcblxuICAgICAgICBjb25zdCBnbG9iYWxEZWZpbmVzID0gdGhpcy5jdXJyZW50R2xvYmFsRGVmaW5lcygpO1xuICAgICAgICBjb25zdCBhbGxEZWZpbmVzID0gZ2xvYmFsRGVmaW5lcy5jb25jYXQoZGVmaW5lcyk7XG4gICAgICAgIGNvbnN0IGtleSA9IFByb2dyYW0uY2FjaGVLZXkoc2hhZGVyc1tuYW1lXSwgbmFtZSwgYWxsRGVmaW5lcywgcHJvZ3JhbUNvbmZpZ3VyYXRpb24pO1xuXG4gICAgICAgIGlmICghdGhpcy5jYWNoZVtrZXldKSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlW2tleV0gPSBuZXcgUHJvZ3JhbSh0aGlzLmNvbnRleHQsIG5hbWUsIHNoYWRlcnNbbmFtZV0sIHByb2dyYW1Db25maWd1cmF0aW9uLCBwcm9ncmFtVW5pZm9ybXNbbmFtZV0sIGFsbERlZmluZXMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmNhY2hlW2tleV07XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBSZXNldCBzb21lIEdMIHN0YXRlIHRvIGRlZmF1bHQgdmFsdWVzIHRvIGF2b2lkIGhhcmQtdG8tZGVidWcgYnVnc1xuICAgICAqIGluIGN1c3RvbSBsYXllcnMuXG4gICAgICovXG4gICAgc2V0Q3VzdG9tTGF5ZXJEZWZhdWx0cygpIHtcbiAgICAgICAgLy8gUHJldmVudCBjdXN0b20gbGF5ZXJzIGZyb20gdW5pbnRlbnRpb25hbGx5IG1vZGlmeSB0aGUgbGFzdCBWQU8gdXNlZC5cbiAgICAgICAgLy8gQWxsIG90aGVyIHN0YXRlIGlzIHN0YXRlIGlzIHJlc3RvcmVkIG9uIGl0J3Mgb3duLCBidXQgZm9yIFZBT3MgaXQnc1xuICAgICAgICAvLyBzaW1wbGVyIHRvIHVuYmluZCBzbyB0aGF0IHdlIGRvbid0IGhhdmUgdG8gdHJhY2sgdGhlIHN0YXRlIG9mIFZBT3MuXG4gICAgICAgIHRoaXMuY29udGV4dC51bmJpbmRWQU8oKTtcblxuICAgICAgICAvLyBUaGUgZGVmYXVsdCB2YWx1ZXMgZm9yIHRoaXMgc3RhdGUgaXMgbWVhbmluZ2Z1bCBhbmQgb2Z0ZW4gZXhwZWN0ZWQuXG4gICAgICAgIC8vIExlYXZpbmcgdGhpcyBzdGF0ZSBkaXJ0eSBjb3VsZCBjYXVzZSBhIGxvdCBvZiBjb25mdXNpb24gZm9yIHVzZXJzLlxuICAgICAgICB0aGlzLmNvbnRleHQuY3VsbEZhY2Uuc2V0RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLmNvbnRleHQuZnJvbnRGYWNlLnNldERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LmN1bGxGYWNlU2lkZS5zZXREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuY29udGV4dC5hY3RpdmVUZXh0dXJlLnNldERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LnBpeGVsU3RvcmVVbnBhY2suc2V0RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLmNvbnRleHQucGl4ZWxTdG9yZVVucGFja1ByZW11bHRpcGx5QWxwaGEuc2V0RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLmNvbnRleHQucGl4ZWxTdG9yZVVucGFja0ZsaXBZLnNldERlZmF1bHQoKTtcbiAgICB9XG5cbiAgICAvKlxuICAgICAqIFNldCBHTCBzdGF0ZSB0aGF0IGlzIHNoYXJlZCBieSBhbGwgbGF5ZXJzLlxuICAgICAqL1xuICAgIHNldEJhc2VTdGF0ZSgpIHtcbiAgICAgICAgY29uc3QgZ2wgPSB0aGlzLmNvbnRleHQuZ2w7XG4gICAgICAgIHRoaXMuY29udGV4dC5jdWxsRmFjZS5zZXQoZmFsc2UpO1xuICAgICAgICB0aGlzLmNvbnRleHQudmlld3BvcnQuc2V0KFswLCAwLCB0aGlzLndpZHRoLCB0aGlzLmhlaWdodF0pO1xuICAgICAgICB0aGlzLmNvbnRleHQuYmxlbmRFcXVhdGlvbi5zZXQoZ2wuRlVOQ19BREQpO1xuICAgIH1cblxuICAgIGluaXREZWJ1Z092ZXJsYXlDYW52YXMoKSB7XG4gICAgICAgIGlmICh0aGlzLmRlYnVnT3ZlcmxheUNhbnZhcyA9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLmRlYnVnT3ZlcmxheUNhbnZhcyA9IHdpbmRvdy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICAgICAgICAgIHRoaXMuZGVidWdPdmVybGF5Q2FudmFzLndpZHRoID0gNTEyO1xuICAgICAgICAgICAgdGhpcy5kZWJ1Z092ZXJsYXlDYW52YXMuaGVpZ2h0ID0gNTEyO1xuICAgICAgICAgICAgY29uc3QgZ2wgPSB0aGlzLmNvbnRleHQuZ2w7XG4gICAgICAgICAgICB0aGlzLmRlYnVnT3ZlcmxheVRleHR1cmUgPSBuZXcgVGV4dHVyZSh0aGlzLmNvbnRleHQsIHRoaXMuZGVidWdPdmVybGF5Q2FudmFzLCBnbC5SR0JBKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRlc3Ryb3koKSB7XG4gICAgICAgIGlmICh0aGlzLl90ZXJyYWluKSB7XG4gICAgICAgICAgICB0aGlzLl90ZXJyYWluLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5nbG9iZVNoYXJlZEJ1ZmZlcnMpIHtcbiAgICAgICAgICAgIHRoaXMuZ2xvYmVTaGFyZWRCdWZmZXJzLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVtcHR5VGV4dHVyZS5kZXN0cm95KCk7XG4gICAgICAgIGlmICh0aGlzLmRlYnVnT3ZlcmxheVRleHR1cmUpIHtcbiAgICAgICAgICAgIHRoaXMuZGVidWdPdmVybGF5VGV4dHVyZS5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuYXRtb3NwaGVyZUJ1ZmZlcikge1xuICAgICAgICAgICAgdGhpcy5hdG1vc3BoZXJlQnVmZmVyLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByZXBhcmVEcmF3VGlsZSgpIHtcbiAgICAgICAgaWYgKHRoaXMudGVycmFpbikge1xuICAgICAgICAgICAgdGhpcy50ZXJyYWluLnByZXBhcmVEcmF3VGlsZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJlcGFyZURyYXdQcm9ncmFtKGNvbnRleHQ6IENvbnRleHQsIHByb2dyYW06IFByb2dyYW08Kj4sIHRpbGVJRDogP1Vud3JhcHBlZFRpbGVJRCkge1xuXG4gICAgICAgIC8vIEZvZyBpcyBub3QgZW5hYmxlZCB3aGVuIHJlbmRlcmluZyB0byB0ZXh0dXJlIHNvIHdlXG4gICAgICAgIC8vIGNhbiBzYWZlbHkgc2tpcCB1cGxvYWRpbmcgdW5pZm9ybXMgaW4gdGhhdCBjYXNlXG4gICAgICAgIGlmICh0aGlzLnRlcnJhaW4gJiYgdGhpcy50ZXJyYWluLnJlbmRlcmluZ1RvVGV4dHVyZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZm9nID0gdGhpcy5zdHlsZS5mb2c7XG5cbiAgICAgICAgaWYgKGZvZykge1xuICAgICAgICAgICAgY29uc3QgZm9nT3BhY2l0eSA9IGZvZy5nZXRPcGFjaXR5KHRoaXMudHJhbnNmb3JtLnBpdGNoKTtcbiAgICAgICAgICAgIGNvbnN0IGZvZ1VuaWZvcm1zID0gZm9nVW5pZm9ybVZhbHVlcyhcbiAgICAgICAgICAgICAgICB0aGlzLCBmb2csIHRpbGVJRCwgZm9nT3BhY2l0eSxcbiAgICAgICAgICAgICAgICB0aGlzLnRyYW5zZm9ybS5mcnVzdHVtQ29ybmVycy5UTCxcbiAgICAgICAgICAgICAgICB0aGlzLnRyYW5zZm9ybS5mcnVzdHVtQ29ybmVycy5UUixcbiAgICAgICAgICAgICAgICB0aGlzLnRyYW5zZm9ybS5mcnVzdHVtQ29ybmVycy5CUixcbiAgICAgICAgICAgICAgICB0aGlzLnRyYW5zZm9ybS5mcnVzdHVtQ29ybmVycy5CTCxcbiAgICAgICAgICAgICAgICB0aGlzLnRyYW5zZm9ybS5nbG9iZUNlbnRlckluVmlld1NwYWNlLFxuICAgICAgICAgICAgICAgIHRoaXMudHJhbnNmb3JtLmdsb2JlUmFkaXVzLFxuICAgICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50cmFuc2Zvcm0ud2lkdGggKiBicm93c2VyLmRldmljZVBpeGVsUmF0aW8sXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudHJhbnNmb3JtLmhlaWdodCAqIGJyb3dzZXIuZGV2aWNlUGl4ZWxSYXRpb1xuICAgICAgICAgICAgICAgIF0pO1xuXG4gICAgICAgICAgICBwcm9ncmFtLnNldEZvZ1VuaWZvcm1WYWx1ZXMoY29udGV4dCwgZm9nVW5pZm9ybXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0VGlsZUxvYWRlZEZsYWcoZmxhZzogYm9vbGVhbikge1xuICAgICAgICB0aGlzLnRpbGVMb2FkZWQgPSBmbGFnO1xuICAgIH1cblxuICAgIHNhdmVDYW52YXNDb3B5KCkge1xuICAgICAgICBjb25zdCBjYW52YXMgPSB0aGlzLmNhbnZhc0NvcHkoKTtcbiAgICAgICAgaWYgKCFjYW52YXMpIHJldHVybjtcbiAgICAgICAgdGhpcy5mcmFtZUNvcGllcy5wdXNoKGNhbnZhcyk7XG4gICAgICAgIHRoaXMudGlsZUxvYWRlZCA9IGZhbHNlO1xuICAgIH1cblxuICAgIGNhbnZhc0NvcHkoKTogP1dlYkdMVGV4dHVyZSB7XG4gICAgICAgIGNvbnN0IGdsID0gdGhpcy5jb250ZXh0LmdsO1xuICAgICAgICBjb25zdCB0ZXh0dXJlID0gZ2wuY3JlYXRlVGV4dHVyZSgpO1xuICAgICAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCB0ZXh0dXJlKTtcbiAgICAgICAgZ2wuY29weVRleEltYWdlMkQoZ2wuVEVYVFVSRV8yRCwgMCwgZ2wuUkdCQSwgMCwgMCwgZ2wuZHJhd2luZ0J1ZmZlcldpZHRoLCBnbC5kcmF3aW5nQnVmZmVySGVpZ2h0LCAwKTtcbiAgICAgICAgcmV0dXJuIHRleHR1cmU7XG4gICAgfVxuXG4gICAgZ2V0Q2FudmFzQ29waWVzQW5kVGltZXN0YW1wcygpOiBDYW52YXNDb3B5SW5zdGFuY2VzIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNhbnZhc0NvcGllczogdGhpcy5mcmFtZUNvcGllcyxcbiAgICAgICAgICAgIHRpbWVTdGFtcHM6IHRoaXMubG9hZFRpbWVTdGFtcHNcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBhdmVyYWdlRWxldmF0aW9uTmVlZHNFYXNpbmcoKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICghdGhpcy50cmFuc2Zvcm0uX2VsZXZhdGlvbikgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIGNvbnN0IGZvZyA9IHRoaXMuc3R5bGUgJiYgdGhpcy5zdHlsZS5mb2c7XG4gICAgICAgIGlmICghZm9nKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgY29uc3QgZm9nT3BhY2l0eSA9IGZvZy5nZXRPcGFjaXR5KHRoaXMudHJhbnNmb3JtLnBpdGNoKTtcbiAgICAgICAgaWYgKGZvZ09wYWNpdHkgPT09IDApIHJldHVybiBmYWxzZTtcblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBnZXRCYWNrZ3JvdW5kVGlsZXMoKToge1trZXk6IG51bWJlcl06IFRpbGV9IHtcbiAgICAgICAgY29uc3Qgb2xkVGlsZXMgPSB0aGlzLl9iYWNrZ3JvdW5kVGlsZXM7XG4gICAgICAgIGNvbnN0IG5ld1RpbGVzID0gdGhpcy5fYmFja2dyb3VuZFRpbGVzID0ge307XG5cbiAgICAgICAgY29uc3QgdGlsZVNpemUgPSA1MTI7XG4gICAgICAgIGNvbnN0IHRpbGVJRHMgPSB0aGlzLnRyYW5zZm9ybS5jb3ZlcmluZ1RpbGVzKHt0aWxlU2l6ZX0pO1xuICAgICAgICBmb3IgKGNvbnN0IHRpbGVJRCBvZiB0aWxlSURzKSB7XG4gICAgICAgICAgICBuZXdUaWxlc1t0aWxlSUQua2V5XSA9IG9sZFRpbGVzW3RpbGVJRC5rZXldIHx8IG5ldyBUaWxlKHRpbGVJRCwgdGlsZVNpemUsIHRoaXMudHJhbnNmb3JtLnRpbGVab29tLCB0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3VGlsZXM7XG4gICAgfVxuXG4gICAgY2xlYXJCYWNrZ3JvdW5kVGlsZXMoKSB7XG4gICAgICAgIHRoaXMuX2JhY2tncm91bmRUaWxlcyA9IHt9O1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUGFpbnRlcjtcbiIsIi8vIEBmbG93XG5pbXBvcnQge251bWJlcn0gZnJvbSBcIi4uL3N0eWxlLXNwZWMvdXRpbC9pbnRlcnBvbGF0ZS5qc1wiO1xuaW1wb3J0IFBvaW50ICBmcm9tIFwiQG1hcGJveC9wb2ludC1nZW9tZXRyeVwiO1xuaW1wb3J0IHtjbGFtcH0gZnJvbSBcIi4uL3V0aWwvdXRpbC5qc1wiO1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBBbiBgRWRnZUluc2V0YCBvYmplY3QgcmVwcmVzZW50cyBzY3JlZW4gc3BhY2UgcGFkZGluZyBhcHBsaWVkIHRvIHRoZSBlZGdlcyBvZiB0aGUgdmlld3BvcnQuXG4gKiBUaGlzIHNoaWZ0cyB0aGUgYXBwYXJlbnQgY2VudGVyIG9yIHRoZSB2YW5pc2hpbmcgcG9pbnQgb2YgdGhlIG1hcC4gVGhpcyBpcyB1c2VmdWwgZm9yIGFkZGluZyBmbG9hdGluZyBVSSBlbGVtZW50c1xuICogb24gdG9wIG9mIHRoZSBtYXAgYW5kIGhhdmluZyB0aGUgdmFuaXNoaW5nIHBvaW50IHNoaWZ0IGFzIFVJIGVsZW1lbnRzIHJlc2l6ZS5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gW3RvcD0wXVxuICogQHBhcmFtIHtudW1iZXJ9IFtib3R0b209MF1cbiAqIEBwYXJhbSB7bnVtYmVyfSBbbGVmdD0wXVxuICogQHBhcmFtIHtudW1iZXJ9IFtyaWdodD0wXVxuICovXG5jbGFzcyBFZGdlSW5zZXRzIHtcbiAgICB0b3A6IG51bWJlcjtcbiAgICBib3R0b206IG51bWJlcjtcbiAgICBsZWZ0OiBudW1iZXI7XG4gICAgcmlnaHQ6IG51bWJlcjtcblxuICAgIGNvbnN0cnVjdG9yKHRvcDogbnVtYmVyID0gMCwgYm90dG9tOiBudW1iZXIgPSAwLCBsZWZ0OiBudW1iZXIgPSAwLCByaWdodDogbnVtYmVyID0gMCkge1xuICAgICAgICBpZiAoaXNOYU4odG9wKSB8fCB0b3AgPCAwIHx8XG4gICAgICAgICAgICBpc05hTihib3R0b20pIHx8IGJvdHRvbSA8IDAgfHxcbiAgICAgICAgICAgIGlzTmFOKGxlZnQpIHx8IGxlZnQgPCAwIHx8XG4gICAgICAgICAgICBpc05hTihyaWdodCkgfHwgcmlnaHQgPCAwXG4gICAgICAgICkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHZhbHVlIGZvciBlZGdlLWluc2V0cywgdG9wLCBib3R0b20sIGxlZnQgYW5kIHJpZ2h0IG11c3QgYWxsIGJlIG51bWJlcnMnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudG9wID0gdG9wO1xuICAgICAgICB0aGlzLmJvdHRvbSA9IGJvdHRvbTtcbiAgICAgICAgdGhpcy5sZWZ0ID0gbGVmdDtcbiAgICAgICAgdGhpcy5yaWdodCA9IHJpZ2h0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEludGVycG9sYXRlcyB0aGUgaW5zZXQgaW4tcGxhY2UuXG4gICAgICogVGhpcyBtYWludGFpbnMgdGhlIGN1cnJlbnQgaW5zZXQgdmFsdWUgZm9yIGFueSBpbnNldCBub3QgcHJlc2VudCBpbiBgdGFyZ2V0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtQYWRkaW5nT3B0aW9ucyB8IEVkZ2VJbnNldHN9IHN0YXJ0IFRoZSBpbml0aWFsIHBhZGRpbmcgb3B0aW9ucy5cbiAgICAgKiBAcGFyYW0ge1BhZGRpbmdPcHRpb25zfSB0YXJnZXQgVGhlIHRhcmdldCBwYWRkaW5nIG9wdGlvbnMuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHQgVGhlIGludGVycG9sYXRpb24gdmFyaWFibGUuXG4gICAgICogQHJldHVybnMge0VkZ2VJbnNldHN9IFRoZSBpbnRlcnBvbGF0ZWQgZWRnZSBpbnNldHMuXG4gICAgICogQG1lbWJlcm9mIEVkZ2VJbnNldHNcbiAgICAgKi9cbiAgICBpbnRlcnBvbGF0ZShzdGFydDogUGFkZGluZ09wdGlvbnMgfCBFZGdlSW5zZXRzLCB0YXJnZXQ6IFBhZGRpbmdPcHRpb25zLCB0OiBudW1iZXIpOiBFZGdlSW5zZXRzIHtcbiAgICAgICAgaWYgKHRhcmdldC50b3AgIT0gbnVsbCAmJiBzdGFydC50b3AgIT0gbnVsbCkgdGhpcy50b3AgPSBudW1iZXIoc3RhcnQudG9wLCB0YXJnZXQudG9wLCB0KTtcbiAgICAgICAgaWYgKHRhcmdldC5ib3R0b20gIT0gbnVsbCAmJiBzdGFydC5ib3R0b20gIT0gbnVsbCkgdGhpcy5ib3R0b20gPSBudW1iZXIoc3RhcnQuYm90dG9tLCB0YXJnZXQuYm90dG9tLCB0KTtcbiAgICAgICAgaWYgKHRhcmdldC5sZWZ0ICE9IG51bGwgJiYgc3RhcnQubGVmdCAhPSBudWxsKSB0aGlzLmxlZnQgPSBudW1iZXIoc3RhcnQubGVmdCwgdGFyZ2V0LmxlZnQsIHQpO1xuICAgICAgICBpZiAodGFyZ2V0LnJpZ2h0ICE9IG51bGwgJiYgc3RhcnQucmlnaHQgIT0gbnVsbCkgdGhpcy5yaWdodCA9IG51bWJlcihzdGFydC5yaWdodCwgdGFyZ2V0LnJpZ2h0LCB0KTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVdGlsaXR5IG1ldGhvZCB0aGF0IGNvbXB1dGVzIHRoZSBuZXcgYXBwcmVudCBjZW50ZXIgb3IgdmFuaXNoaW5nIHBvaW50IGFmdGVyIGFwcGx5aW5nIGluc2V0cy5cbiAgICAgKiBUaGlzIGlzIGluIHBpeGVscyBhbmQgd2l0aCB0aGUgdG9wIGxlZnQgYmVpbmcgKDAuMCkgYW5kICt5IGJlaW5nIGRvd253YXJkcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoIFRoZSB3aWR0aCBvZiB0aGUgbWFwIGluIHBpeGVscy5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0IFRoZSBoZWlnaHQgb2YgdGhlIG1hcCBpbiBwaXhlbHMuXG4gICAgICogQHJldHVybnMge1BvaW50fSBUaGUgYXBwYXJlbnQgY2VudGVyIG9yIHZhbmlzaGluZyBwb2ludCBvZiB0aGUgbWFwLlxuICAgICAqIEBtZW1iZXJvZiBFZGdlSW5zZXRzXG4gICAgICovXG4gICAgZ2V0Q2VudGVyKHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKTogUG9pbnQge1xuICAgICAgICAvLyBDbGFtcCBpbnNldHMgc28gdGhleSBuZXZlciBvdmVyZmxvdyB3aWR0aC9oZWlnaHQgYW5kIGFsd2F5cyBjYWxjdWxhdGUgYSB2YWxpZCBjZW50ZXJcbiAgICAgICAgY29uc3QgeCA9IGNsYW1wKCh0aGlzLmxlZnQgKyB3aWR0aCAtIHRoaXMucmlnaHQpIC8gMiwgMCwgd2lkdGgpO1xuICAgICAgICBjb25zdCB5ID0gY2xhbXAoKHRoaXMudG9wICsgaGVpZ2h0IC0gdGhpcy5ib3R0b20pIC8gMiwgMCwgaGVpZ2h0KTtcblxuICAgICAgICByZXR1cm4gbmV3IFBvaW50KHgsIHkpO1xuICAgIH1cblxuICAgIGVxdWFscyhvdGhlcjogUGFkZGluZ09wdGlvbnMpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudG9wID09PSBvdGhlci50b3AgJiZcbiAgICAgICAgICAgIHRoaXMuYm90dG9tID09PSBvdGhlci5ib3R0b20gJiZcbiAgICAgICAgICAgIHRoaXMubGVmdCA9PT0gb3RoZXIubGVmdCAmJlxuICAgICAgICAgICAgdGhpcy5yaWdodCA9PT0gb3RoZXIucmlnaHQ7XG4gICAgfVxuXG4gICAgY2xvbmUoKTogRWRnZUluc2V0cyB7XG4gICAgICAgIHJldHVybiBuZXcgRWRnZUluc2V0cyh0aGlzLnRvcCwgdGhpcy5ib3R0b20sIHRoaXMubGVmdCwgdGhpcy5yaWdodCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgY3VycmVudCBzdGF0ZSBhcyBqc29uLCB1c2VmdWwgd2hlbiB5b3Ugd2FudCB0byBoYXZlIGFcbiAgICAgKiByZWFkLW9ubHkgcmVwcmVzZW50YXRpb24gb2YgdGhlIGluc2V0LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcmV0dXJucyB7UGFkZGluZ09wdGlvbnN9IFRoZSBjdXJyZW50IHBhZGRpbmcgb3B0aW9ucy5cbiAgICAgKiBAbWVtYmVyb2YgRWRnZUluc2V0c1xuICAgICAqL1xuICAgIHRvSlNPTigpOiBQYWRkaW5nT3B0aW9ucyB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0b3A6IHRoaXMudG9wLFxuICAgICAgICAgICAgYm90dG9tOiB0aGlzLmJvdHRvbSxcbiAgICAgICAgICAgIGxlZnQ6IHRoaXMubGVmdCxcbiAgICAgICAgICAgIHJpZ2h0OiB0aGlzLnJpZ2h0XG4gICAgICAgIH07XG4gICAgfVxufVxuXG5leHBvcnQgdHlwZSBQYWRkaW5nT3B0aW9ucyA9IHsrdG9wOiA/bnVtYmVyLCArYm90dG9tOiA/bnVtYmVyLCArcmlnaHQ6ID9udW1iZXIsICtsZWZ0OiA/bnVtYmVyfTtcblxuZXhwb3J0IGRlZmF1bHQgRWRnZUluc2V0cztcbiIsIi8vIEBmbG93XG5cbmltcG9ydCBNZXJjYXRvckNvb3JkaW5hdGUsIHttZXJjYXRvclpmcm9tQWx0aXR1ZGUsIGxhdEZyb21NZXJjYXRvcll9IGZyb20gJy4uL2dlby9tZXJjYXRvcl9jb29yZGluYXRlLmpzJztcbmltcG9ydCB7ZGVnVG9SYWQsIHdyYXAsIGdldENvbHVtbiwgc2V0Q29sdW1ufSBmcm9tICcuLi91dGlsL3V0aWwuanMnO1xuaW1wb3J0IHt2ZWMzLCBxdWF0LCBtYXQ0fSBmcm9tICdnbC1tYXRyaXgnO1xuXG5pbXBvcnQgdHlwZSB7RWxldmF0aW9ufSBmcm9tICcuLi90ZXJyYWluL2VsZXZhdGlvbi5qcyc7XG5pbXBvcnQgdHlwZSB7TG5nTGF0TGlrZX0gZnJvbSAnLi4vZ2VvL2xuZ19sYXQuanMnO1xuaW1wb3J0IHR5cGUge01hdDQsIFZlYzMsIFZlYzQsIFF1YXR9IGZyb20gJ2dsLW1hdHJpeCc7XG5cbmZ1bmN0aW9uIHVwZGF0ZVRyYW5zZm9ybU9yaWVudGF0aW9uKG1hdHJpeDogTWF0NCwgb3JpZW50YXRpb246IFF1YXQpIHtcbiAgICAvLyBUYWtlIHRlbXBvcmFyeSBjb3B5IG9mIHBvc2l0aW9uIHRvIHByZXZlbnQgaXQgZnJvbSBiZWluZyBvdmVyd3JpdHRlblxuICAgIGNvbnN0IHBvc2l0aW9uOiBWZWM0ID0gZ2V0Q29sdW1uKG1hdHJpeCwgMyk7XG5cbiAgICAvLyBDb252ZXJ0IHF1YXRlcm5pb24gdG8gcm90YXRpb24gbWF0cml4XG4gICAgbWF0NC5mcm9tUXVhdChtYXRyaXgsIG9yaWVudGF0aW9uKTtcbiAgICBzZXRDb2x1bW4obWF0cml4LCAzLCBwb3NpdGlvbik7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVRyYW5zZm9ybVBvc2l0aW9uKG1hdHJpeDogTWF0NCwgcG9zaXRpb246IFZlYzMpIHtcbiAgICBzZXRDb2x1bW4obWF0cml4LCAzLCBbcG9zaXRpb25bMF0sIHBvc2l0aW9uWzFdLCBwb3NpdGlvblsyXSwgMS4wXSk7XG59XG5cbmZ1bmN0aW9uIG9yaWVudGF0aW9uRnJvbVBpdGNoQmVhcmluZyhwaXRjaDogbnVtYmVyLCBiZWFyaW5nOiBudW1iZXIpOiBRdWF0IHtcbiAgICAvLyBCb3RoIGFuZ2xlcyBhcmUgY29uc2lkZXJlZCB0byBkZWZpbmUgQ1cgcm90YXRpb24gYXJvdW5kIHRoZWlyIHJlc3BlY3RpdmUgYXhlcy5cbiAgICAvLyBWYWx1ZXMgaGF2ZSB0byBiZSBuZWdhdGVkIHRvIGFjaGlldmUgdGhlIHByb3BlciBxdWF0ZXJuaW9uIGluIGxlZnQgaGFuZGVkIGNvb3JkaW5hdGUgc3BhY2VcbiAgICBjb25zdCBvcmllbnRhdGlvbiA9IHF1YXQuaWRlbnRpdHkoW10pO1xuICAgIHF1YXQucm90YXRlWihvcmllbnRhdGlvbiwgb3JpZW50YXRpb24sIC1iZWFyaW5nKTtcbiAgICBxdWF0LnJvdGF0ZVgob3JpZW50YXRpb24sIG9yaWVudGF0aW9uLCAtcGl0Y2gpO1xuICAgIHJldHVybiBvcmllbnRhdGlvbjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG9yaWVudGF0aW9uRnJvbUZyYW1lKGZvcndhcmQ6IFZlYzMsIHVwOiBWZWMzKTogP1F1YXQge1xuICAgIC8vIEZpbmQgcmlnaHQtdmVjdG9yIG9mIHRoZSByZXN1bHRpbmcgY29vcmRpbmF0ZSBmcmFtZS4gVXAtdmVjdG9yIGhhcyB0byBiZVxuICAgIC8vIHNhbml0aXplZCBmaXJzdCBpbiBvcmRlciB0byByZW1vdmUgdGhlIHJvbGwgY29tcG9uZW50IGZyb20gdGhlIG9yaWVudGF0aW9uXG4gICAgY29uc3QgeHlGb3J3YXJkID0gW2ZvcndhcmRbMF0sIGZvcndhcmRbMV0sIDBdO1xuICAgIGNvbnN0IHh5VXAgPSBbdXBbMF0sIHVwWzFdLCAwXTtcblxuICAgIGNvbnN0IGVwc2lsb24gPSAxZS0xNTtcblxuICAgIGlmICh2ZWMzLmxlbmd0aCh4eUZvcndhcmQpID49IGVwc2lsb24pIHtcbiAgICAgICAgLy8gUm9sbCByb3RhdGlvbiBjYW4gYmUgc2VlbiBhcyB0aGUgcmlnaHQgdmVjdG9yIG5vdCBiZWluZyBvbiB0aGUgeHktcGxhbmUsIGllLiByaWdodFsyXSAhPSAwLjAuXG4gICAgICAgIC8vIEl0IGNhbiBiZSBuZWdhdGVkIGJ5IHByb2plY3RpbmcgdGhlIHVwIHZlY3RvciBvbiB0b3Agb2YgdGhlIGZvcndhcmQgdmVjdG9yLlxuICAgICAgICBjb25zdCB4eURpciA9IHZlYzMubm9ybWFsaXplKFtdLCB4eUZvcndhcmQpO1xuICAgICAgICB2ZWMzLnNjYWxlKHh5VXAsIHh5RGlyLCB2ZWMzLmRvdCh4eVVwLCB4eURpcikpO1xuXG4gICAgICAgIHVwWzBdID0geHlVcFswXTtcbiAgICAgICAgdXBbMV0gPSB4eVVwWzFdO1xuICAgIH1cblxuICAgIGNvbnN0IHJpZ2h0ID0gdmVjMy5jcm9zcyhbXSwgdXAsIGZvcndhcmQpO1xuICAgIGlmICh2ZWMzLmxlbihyaWdodCkgPCBlcHNpbG9uKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IGJlYXJpbmcgPSBNYXRoLmF0YW4yKC1yaWdodFsxXSwgcmlnaHRbMF0pO1xuICAgIGNvbnN0IHBpdGNoID0gTWF0aC5hdGFuMihNYXRoLnNxcnQoZm9yd2FyZFswXSAqIGZvcndhcmRbMF0gKyBmb3J3YXJkWzFdICogZm9yd2FyZFsxXSksIC1mb3J3YXJkWzJdKTtcblxuICAgIHJldHVybiBvcmllbnRhdGlvbkZyb21QaXRjaEJlYXJpbmcocGl0Y2gsIGJlYXJpbmcpO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGFjY2Vzc2luZyBwaHlzaWNhbCBwcm9wZXJ0aWVzIG9mIHRoZSB1bmRlcmx5aW5nIGNhbWVyYSBlbnRpdHkuXG4gKiBEaXJlY3QgYWNjZXNzIHRvIHRoZXNlIHByb3BlcnRpZXMgYWxsb3dzIG1vcmUgZmxleGlibGUgYW5kIHByZWNpc2UgY29udHJvbGxpbmcgb2YgdGhlIGNhbWVyYS5cbiAqIFRoZXNlIG9wdGlvbnMgYXJlIGFsc28gZnVsbHkgY29tcGF0aWJsZSBhbmQgaW50ZXJjaGFuZ2VhYmxlIHdpdGggQ2FtZXJhT3B0aW9ucy4gQWxsIGZpZWxkcyBhcmUgb3B0aW9uYWwuXG4gKiBTZWUge0BsaW5rIE1hcCNzZXRGcmVlQ2FtZXJhT3B0aW9uc30gYW5kIHtAbGluayBNYXAjZ2V0RnJlZUNhbWVyYU9wdGlvbnN9LlxuICpcbiAqIEBwYXJhbSB7TWVyY2F0b3JDb29yZGluYXRlfSBwb3NpdGlvbiBQb3NpdGlvbiBvZiB0aGUgY2FtZXJhIGluIHNsaWdodGx5IG1vZGlmaWVkIHdlYiBtZXJjYXRvciBjb29yZGluYXRlcy5cbiAgICAgICAgLSBUaGUgc2l6ZSBvZiAxIHVuaXQgaXMgdGhlIHdpZHRoIG9mIHRoZSBwcm9qZWN0ZWQgd29ybGQgaW5zdGVhZCBvZiB0aGUgXCJtZXJjYXRvciBtZXRlclwiLlxuICAgICAgICAgIENvb3JkaW5hdGUgWzAsIDAsIDBdIGlzIHRoZSBub3J0aC13ZXN0IGNvcm5lciBhbmQgWzEsIDEsIDBdIGlzIHRoZSBzb3V0aC1lYXN0IGNvcm5lci5cbiAgICAgICAgLSBaIGNvb3JkaW5hdGUgaXMgY29uZm9ybWFsIGFuZCBtdXN0IHJlc3BlY3QgbWluaW11bSBhbmQgbWF4aW11bSB6b29tIHZhbHVlcy5cbiAgICAgICAgLSBab29tIGlzIGF1dG9tYXRpY2FsbHkgY29tcHV0ZWQgZnJvbSB0aGUgYWx0aXR1ZGUgKHopLlxuICogQHBhcmFtIHtxdWF0fSBvcmllbnRhdGlvbiBPcmllbnRhdGlvbiBvZiB0aGUgY2FtZXJhIHJlcHJlc2VudGVkIGFzIGEgdW5pdCBxdWF0ZXJuaW9uIFt4LCB5LCB6LCB3XSBpbiBhIGxlZnQtaGFuZGVkIGNvb3JkaW5hdGUgc3BhY2UuXG4gICAgICAgIERpcmVjdGlvbiBvZiB0aGUgcm90YXRpb24gaXMgY2xvY2t3aXNlIGFyb3VuZCB0aGUgcmVzcGVjdGl2ZSBheGlzLlxuICAgICAgICBUaGUgZGVmYXVsdCBwb3NlIG9mIHRoZSBjYW1lcmEgaXMgc3VjaCB0aGF0IHRoZSBmb3J3YXJkIHZlY3RvciBpcyBsb29raW5nIHVwIHRoZSAtWiBheGlzLlxuICAgICAgICBUaGUgdXAgdmVjdG9yIGlzIGFsaWduZWQgd2l0aCBub3J0aCBvcmllbnRhdGlvbiBvZiB0aGUgbWFwOlxuICAgICAgICAgIGZvcndhcmQ6IFswLCAwLCAtMV1cbiAgICAgICAgICB1cDogICAgICBbMCwgLTEsIDBdXG4gICAgICAgICAgcmlnaHQgICAgWzEsIDAsIDBdXG4gICAgICAgIE9yaWVudGF0aW9uIGNhbiBiZSBzZXQgZnJlZWx5IGJ1dCBjZXJ0YWluIGNvbnN0cmFpbnRzIHN0aWxsIGFwcGx5OlxuICAgICAgICAgLSBPcmllbnRhdGlvbiBtdXN0IGJlIHJlcHJlc2VudGFibGUgd2l0aCBvbmx5IHBpdGNoIGFuZCBiZWFyaW5nLlxuICAgICAgICAgLSBQaXRjaCBoYXMgYW4gdXBwZXIgbGltaXRcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBjYW1lcmEgPSBtYXAuZ2V0RnJlZUNhbWVyYU9wdGlvbnMoKTtcbiAqXG4gKiBjb25zdCBwb3NpdGlvbiA9IFsxMzguNzI2NDksIDM1LjMzOTc0XTtcbiAqIGNvbnN0IGFsdGl0dWRlID0gMzAwMDtcbiAqXG4gKiBjYW1lcmEucG9zaXRpb24gPSBtYXBib3hnbC5NZXJjYXRvckNvb3JkaW5hdGUuZnJvbUxuZ0xhdChwb3NpdGlvbiwgYWx0aXR1ZGUpO1xuICogY2FtZXJhLmxvb2tBdFBvaW50KFsxMzguNzMwMzYsIDM1LjM2MTk3XSk7XG4gKlxuICogbWFwLnNldEZyZWVDYW1lcmFPcHRpb25zKGNhbWVyYSk7XG4gKiBAc2VlIFtFeGFtcGxlOiBBbmltYXRlIHRoZSBjYW1lcmEgYXJvdW5kIGEgcG9pbnQgaW4gM0QgdGVycmFpbl0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvZnJlZS1jYW1lcmEtcG9pbnQvKVxuICogQHNlZSBbRXhhbXBsZTogQW5pbWF0ZSB0aGUgY2FtZXJhIGFsb25nIGEgcGF0aF0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvZnJlZS1jYW1lcmEtcGF0aC8pXG4qL1xuY2xhc3MgRnJlZUNhbWVyYU9wdGlvbnMge1xuICAgIG9yaWVudGF0aW9uOiA/UXVhdDtcbiAgICBfcG9zaXRpb246ID9NZXJjYXRvckNvb3JkaW5hdGU7XG4gICAgX2VsZXZhdGlvbjogP0VsZXZhdGlvbjtcbiAgICBfcmVuZGVyV29ybGRDb3BpZXM6IGJvb2xlYW47XG5cbiAgICBjb25zdHJ1Y3Rvcihwb3NpdGlvbjogP01lcmNhdG9yQ29vcmRpbmF0ZSwgb3JpZW50YXRpb246ID9RdWF0KSB7XG4gICAgICAgIHRoaXMucG9zaXRpb24gPSBwb3NpdGlvbjtcbiAgICAgICAgdGhpcy5vcmllbnRhdGlvbiA9IG9yaWVudGF0aW9uO1xuICAgIH1cblxuICAgIGdldCBwb3NpdGlvbigpOiA/TWVyY2F0b3JDb29yZGluYXRlIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Bvc2l0aW9uO1xuICAgIH1cblxuICAgIHNldCBwb3NpdGlvbihwb3NpdGlvbjogP01lcmNhdG9yQ29vcmRpbmF0ZSB8IFZlYzMpIHtcbiAgICAgICAgaWYgKCFwb3NpdGlvbikge1xuICAgICAgICAgICAgdGhpcy5fcG9zaXRpb24gPSBudWxsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgbWVyY2F0b3JDb29yZGluYXRlID0gcG9zaXRpb24gaW5zdGFuY2VvZiBNZXJjYXRvckNvb3JkaW5hdGUgPyBwb3NpdGlvbiA6IG5ldyBNZXJjYXRvckNvb3JkaW5hdGUocG9zaXRpb25bMF0sIHBvc2l0aW9uWzFdLCBwb3NpdGlvblsyXSk7XG4gICAgICAgICAgICBpZiAodGhpcy5fcmVuZGVyV29ybGRDb3BpZXMpIHtcbiAgICAgICAgICAgICAgICBtZXJjYXRvckNvb3JkaW5hdGUueCA9IHdyYXAobWVyY2F0b3JDb29yZGluYXRlLngsIDAsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fcG9zaXRpb24gPSBtZXJjYXRvckNvb3JkaW5hdGU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIZWxwZXIgZnVuY3Rpb24gZm9yIHNldHRpbmcgb3JpZW50YXRpb24gb2YgdGhlIGNhbWVyYSBieSBkZWZpbmluZyBhIGZvY3VzIHBvaW50XG4gICAgICogb24gdGhlIG1hcC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7TG5nTGF0TGlrZX0gbG9jYXRpb24gTG9jYXRpb24gb2YgdGhlIGZvY3VzIHBvaW50IG9uIHRoZSBtYXAuXG4gICAgICogQHBhcmFtIHt2ZWMzP30gdXAgVXAgdmVjdG9yIG9mIHRoZSBjYW1lcmEgaXMgbmVjZXNzYXJ5IGluIGNlcnRhaW4gc2NlbmFyaW9zIHdoZXJlIGJlYXJpbmcgY2FuJ3QgYmUgZGVkdWNlZFxuICAgICAqICAgICAgZnJvbSB0aGUgdmlld2luZyBkaXJlY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBjYW1lcmEgPSBtYXAuZ2V0RnJlZUNhbWVyYU9wdGlvbnMoKTtcbiAgICAgKlxuICAgICAqIGNvbnN0IHBvc2l0aW9uID0gWzEzOC43MjY0OSwgMzUuMzM5NzRdO1xuICAgICAqIGNvbnN0IGFsdGl0dWRlID0gMzAwMDtcbiAgICAgKlxuICAgICAqIGNhbWVyYS5wb3NpdGlvbiA9IG1hcGJveGdsLk1lcmNhdG9yQ29vcmRpbmF0ZS5mcm9tTG5nTGF0KHBvc2l0aW9uLCBhbHRpdHVkZSk7XG4gICAgICogY2FtZXJhLmxvb2tBdFBvaW50KFsxMzguNzMwMzYsIDM1LjM2MTk3XSk7XG4gICAgICogLy8gQXBwbHkgY2FtZXJhIGNoYW5nZXNcbiAgICAgKiBtYXAuc2V0RnJlZUNhbWVyYU9wdGlvbnMoY2FtZXJhKTtcbiAgICAgKi9cbiAgICBsb29rQXRQb2ludChsb2NhdGlvbjogTG5nTGF0TGlrZSwgdXA/OiBWZWMzKSB7XG4gICAgICAgIHRoaXMub3JpZW50YXRpb24gPSBudWxsO1xuICAgICAgICBpZiAoIXRoaXMucG9zaXRpb24pIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHBvczogTWVyY2F0b3JDb29yZGluYXRlID0gdGhpcy5wb3NpdGlvbjtcbiAgICAgICAgY29uc3QgYWx0aXR1ZGUgPSB0aGlzLl9lbGV2YXRpb24gPyB0aGlzLl9lbGV2YXRpb24uZ2V0QXRQb2ludE9yWmVybyhNZXJjYXRvckNvb3JkaW5hdGUuZnJvbUxuZ0xhdChsb2NhdGlvbikpIDogMDtcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gTWVyY2F0b3JDb29yZGluYXRlLmZyb21MbmdMYXQobG9jYXRpb24sIGFsdGl0dWRlKTtcbiAgICAgICAgY29uc3QgZm9yd2FyZCA9IFt0YXJnZXQueCAtIHBvcy54LCB0YXJnZXQueSAtIHBvcy55LCB0YXJnZXQueiAtIHBvcy56XTtcbiAgICAgICAgaWYgKCF1cClcbiAgICAgICAgICAgIHVwID0gWzAsIDAsIDFdO1xuXG4gICAgICAgIC8vIGZsaXAgei1jb21wb25lbnQgaWYgdGhlIHVwIHZlY3RvciBpcyBwb2ludGluZyBkb3dud2FyZHNcbiAgICAgICAgdXBbMl0gPSBNYXRoLmFicyh1cFsyXSk7XG5cbiAgICAgICAgdGhpcy5vcmllbnRhdGlvbiA9IG9yaWVudGF0aW9uRnJvbUZyYW1lKGZvcndhcmQsIHVwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIZWxwZXIgZnVuY3Rpb24gZm9yIHNldHRpbmcgdGhlIG9yaWVudGF0aW9uIG9mIHRoZSBjYW1lcmEgYXMgYSBwaXRjaCBhbmQgYSBiZWFyaW5nLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHBpdGNoIFBpdGNoIGFuZ2xlIGluIGRlZ3JlZXMuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJlYXJpbmcgQmVhcmluZyBhbmdsZSBpbiBkZWdyZWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgY2FtZXJhID0gbWFwLmdldEZyZWVDYW1lcmFPcHRpb25zKCk7XG4gICAgICpcbiAgICAgKiAvLyBVcGRhdGUgY2FtZXJhIHBpdGNoIGFuZCBiZWFyaW5nXG4gICAgICogY2FtZXJhLnNldFBpdGNoQmVhcmluZyg4MCwgOTApO1xuICAgICAqIC8vIEFwcGx5IGNoYW5nZXNcbiAgICAgKiBtYXAuc2V0RnJlZUNhbWVyYU9wdGlvbnMoY2FtZXJhKTtcbiAgICAgKi9cbiAgICBzZXRQaXRjaEJlYXJpbmcocGl0Y2g6IG51bWJlciwgYmVhcmluZzogbnVtYmVyKSB7XG4gICAgICAgIHRoaXMub3JpZW50YXRpb24gPSBvcmllbnRhdGlvbkZyb21QaXRjaEJlYXJpbmcoZGVnVG9SYWQocGl0Y2gpLCBkZWdUb1JhZCgtYmVhcmluZykpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBXaGlsZSB1c2luZyB0aGUgZnJlZSBjYW1lcmEgQVBJIHRoZSBvdXRjb21lIHZhbHVlIG9mIGlzWm9vbWluZywgaXNNb3ZpbmcgYW5kIGlzUm90YXRpbmdcbiAqIGlzIG5vdCBhIHJlc3VsdCBvZiB0aGUgZnJlZSBjYW1lcmEgQVBJLlxuICogSWYgdGhlIHVzZXIgc2V0cyB0aGUgbWFwLmludGVyYWN0aXZlIHRvIHRydWUsIHRoZXJlIHdpbGwgYmUgY29uZmxpY3RpbmcgYmVoYXZpb3JzIHdoaWxlXG4gKiBpbnRlcmFjdGluZyB3aXRoIG1hcCB2aWEgem9vbWluZyBvciBtb3ZpbmcgdXNpbmcgbW91c2Ugb3IvYW5kIGtleWJvYXJkIHdoaWNoIHdpbGwgcmVzdWx0XG4gKiBpbiBpc1pvb21pbmcsIGlzTW92aW5nIGFuZCBpc1JvdGF0aW5nIHRvIHJldHVybiB0cnVlIHdoaWxlIHVzaW5nIGZyZWUgY2FtZXJhIEFQSS4gSW4gb3JkZXJcbiAqIHRvIHByZXZlbnQgdGhlIGNvbmZpbGljdGluZyBiZWhhdmlvciBwbGVhc2Ugc2V0IG1hcC5pbnRlcmFjdGl2ZSB0byBmYWxzZSB3aGljaCB3aWxsIHJlc3VsdFxuICogaW4gbXV0aW5nIHRoZSBmb2xsb3dpbmcgZXZlbnRzOiB6b29tLCB6b29tZW5kLCB6b29tc3RhcnQsIHJvdGF0ZSwgcm90YXRlZW5kLCByb3RhdGVzdGFydCxcbiAqIG1vdmUsIG1vdmVlbmQsIG1vdmVzdGFydCwgcGl0Y2gsIHBpdGNoZW5kLCBwaXRjaHN0YXJ0LlxuICovXG5cbmNsYXNzIEZyZWVDYW1lcmEge1xuICAgIF90cmFuc2Zvcm06IE1hdDQ7XG4gICAgX29yaWVudGF0aW9uOiBRdWF0O1xuXG4gICAgY29uc3RydWN0b3IocG9zaXRpb246ID9WZWMzLCBvcmllbnRhdGlvbjogP1F1YXQpIHtcbiAgICAgICAgdGhpcy5fdHJhbnNmb3JtID0gbWF0NC5pZGVudGl0eShbXSk7XG4gICAgICAgIHRoaXMub3JpZW50YXRpb24gPSBvcmllbnRhdGlvbjtcbiAgICAgICAgdGhpcy5wb3NpdGlvbiA9IHBvc2l0aW9uO1xuICAgIH1cblxuICAgIGdldCBtZXJjYXRvclBvc2l0aW9uKCk6IE1lcmNhdG9yQ29vcmRpbmF0ZSB7XG4gICAgICAgIGNvbnN0IHBvcyA9IHRoaXMucG9zaXRpb247XG4gICAgICAgIHJldHVybiBuZXcgTWVyY2F0b3JDb29yZGluYXRlKHBvc1swXSwgcG9zWzFdLCBwb3NbMl0pO1xuICAgIH1cblxuICAgIGdldCBwb3NpdGlvbigpOiBWZWMzIHtcbiAgICAgICAgY29uc3QgY29sOiBWZWM0ID0gZ2V0Q29sdW1uKHRoaXMuX3RyYW5zZm9ybSwgMyk7XG4gICAgICAgIHJldHVybiBbY29sWzBdLCBjb2xbMV0sIGNvbFsyXV07XG4gICAgfVxuXG4gICAgc2V0IHBvc2l0aW9uKHZhbHVlOiA/VmVjMykge1xuICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICAgIHVwZGF0ZVRyYW5zZm9ybVBvc2l0aW9uKHRoaXMuX3RyYW5zZm9ybSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0IG9yaWVudGF0aW9uKCk6IFF1YXQge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3JpZW50YXRpb247XG4gICAgfVxuXG4gICAgc2V0IG9yaWVudGF0aW9uKHZhbHVlOiA/UXVhdCkge1xuICAgICAgICB0aGlzLl9vcmllbnRhdGlvbiA9IHZhbHVlIHx8IHF1YXQuaWRlbnRpdHkoW10pO1xuICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICAgIHVwZGF0ZVRyYW5zZm9ybU9yaWVudGF0aW9uKHRoaXMuX3RyYW5zZm9ybSwgdGhpcy5fb3JpZW50YXRpb24pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0UGl0Y2hCZWFyaW5nKCk6IHtwaXRjaDogbnVtYmVyLCBiZWFyaW5nOiBudW1iZXJ9IHtcbiAgICAgICAgY29uc3QgZiA9IHRoaXMuZm9yd2FyZCgpO1xuICAgICAgICBjb25zdCByID0gdGhpcy5yaWdodCgpO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBiZWFyaW5nOiBNYXRoLmF0YW4yKC1yWzFdLCByWzBdKSxcbiAgICAgICAgICAgIHBpdGNoOiBNYXRoLmF0YW4yKE1hdGguc3FydChmWzBdICogZlswXSArIGZbMV0gKiBmWzFdKSwgLWZbMl0pXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgc2V0UGl0Y2hCZWFyaW5nKHBpdGNoOiBudW1iZXIsIGJlYXJpbmc6IG51bWJlcikge1xuICAgICAgICB0aGlzLl9vcmllbnRhdGlvbiA9IG9yaWVudGF0aW9uRnJvbVBpdGNoQmVhcmluZyhwaXRjaCwgYmVhcmluZyk7XG4gICAgICAgIHVwZGF0ZVRyYW5zZm9ybU9yaWVudGF0aW9uKHRoaXMuX3RyYW5zZm9ybSwgdGhpcy5fb3JpZW50YXRpb24pO1xuICAgIH1cblxuICAgIGZvcndhcmQoKTogVmVjMyB7XG4gICAgICAgIGNvbnN0IGNvbDogVmVjNCA9IGdldENvbHVtbih0aGlzLl90cmFuc2Zvcm0sIDIpO1xuICAgICAgICAvLyBGb3J3YXJkIGRpcmVjdGlvbiBpcyB0b3dhcmRzIHRoZSBuZWdhdGl2ZSBaLWF4aXNcbiAgICAgICAgcmV0dXJuIFstY29sWzBdLCAtY29sWzFdLCAtY29sWzJdXTtcbiAgICB9XG5cbiAgICB1cCgpOiBWZWMzIHtcbiAgICAgICAgY29uc3QgY29sOiBWZWM0ID0gZ2V0Q29sdW1uKHRoaXMuX3RyYW5zZm9ybSwgMSk7XG4gICAgICAgIC8vIFVwIGRpcmVjdGlvbiBoYXMgdG8gYmUgZmxpcHBlZCB0byBwb2ludCB0b3dhcmRzIG5vcnRoXG4gICAgICAgIHJldHVybiBbLWNvbFswXSwgLWNvbFsxXSwgLWNvbFsyXV07XG4gICAgfVxuXG4gICAgcmlnaHQoKTogVmVjMyB7XG4gICAgICAgIGNvbnN0IGNvbDogVmVjNCA9IGdldENvbHVtbih0aGlzLl90cmFuc2Zvcm0sIDApO1xuICAgICAgICByZXR1cm4gW2NvbFswXSwgY29sWzFdLCBjb2xbMl1dO1xuICAgIH1cblxuICAgIGdldENhbWVyYVRvV29ybGQod29ybGRTaXplOiBudW1iZXIsIHBpeGVsc1Blck1ldGVyOiBudW1iZXIpOiBGbG9hdDY0QXJyYXkge1xuICAgICAgICBjb25zdCBjYW1lcmFUb1dvcmxkID0gbmV3IEZsb2F0NjRBcnJheSgxNik7XG4gICAgICAgIG1hdDQuaW52ZXJ0KGNhbWVyYVRvV29ybGQsIHRoaXMuZ2V0V29ybGRUb0NhbWVyYSh3b3JsZFNpemUsIHBpeGVsc1Blck1ldGVyKSk7XG4gICAgICAgIHJldHVybiBjYW1lcmFUb1dvcmxkO1xuICAgIH1cblxuICAgIGdldFdvcmxkVG9DYW1lcmFQb3NpdGlvbih3b3JsZFNpemU6IG51bWJlciwgcGl4ZWxzUGVyTWV0ZXI6IG51bWJlciwgdW5pZm9ybVNjYWxlOiBudW1iZXIpOiBGbG9hdDY0QXJyYXkge1xuICAgICAgICBjb25zdCBpbnZQb3NpdGlvbiA9IHRoaXMucG9zaXRpb247XG5cbiAgICAgICAgdmVjMy5zY2FsZShpbnZQb3NpdGlvbiwgaW52UG9zaXRpb24sIC13b3JsZFNpemUpO1xuICAgICAgICBjb25zdCBtYXRyaXggPSBuZXcgRmxvYXQ2NEFycmF5KDE2KTtcbiAgICAgICAgbWF0NC5mcm9tU2NhbGluZyhtYXRyaXgsIFt1bmlmb3JtU2NhbGUsIHVuaWZvcm1TY2FsZSwgdW5pZm9ybVNjYWxlXSk7XG4gICAgICAgIG1hdDQudHJhbnNsYXRlKG1hdHJpeCwgbWF0cml4LCBpbnZQb3NpdGlvbik7XG5cbiAgICAgICAgLy8gQWRqdXN0IHNjYWxlIG9uIHogKDNyZCBjb2x1bW4gM3JkIHJvdylcbiAgICAgICAgbWF0cml4WzEwXSAqPSBwaXhlbHNQZXJNZXRlcjtcblxuICAgICAgICByZXR1cm4gbWF0cml4O1xuICAgIH1cblxuICAgIGdldFdvcmxkVG9DYW1lcmEod29ybGRTaXplOiBudW1iZXIsIHBpeGVsc1Blck1ldGVyOiBudW1iZXIpOiBGbG9hdDY0QXJyYXkge1xuICAgICAgICAvLyB0cmFuc2Zvcm1hdGlvbiBjaGFpbiBmcm9tIHdvcmxkIHNwYWNlIHRvIGNhbWVyYSBzcGFjZTpcbiAgICAgICAgLy8gMS4gSGVpZ2h0IHZhbHVlICh6KSBvZiByZW5kZXJhYmxlcyBpcyBpbiBtZXRlcnMuIFNjYWxlIHogY29vcmRpbmF0ZSBieSBwaXhlbHNQZXJNZXRlclxuICAgICAgICAvLyAyLiBUcmFuc2Zvcm0gZnJvbSBwaXhlbCBjb29yZGluYXRlcyB0byBjYW1lcmEgc3BhY2Ugd2l0aCBjYW1lcmFNYXRyaXheLTFcbiAgICAgICAgLy8gMy4gZmxpcCBZIGlmIHJlcXVpcmVkXG5cbiAgICAgICAgLy8gd29ybGRUb0NhbWVyYTogZmxpcCAqIGNhbV4tMSAqIHpTY2FsZVxuICAgICAgICAvLyBjYW1lcmFUb1dvcmxkOiAoZmxpcCAqIGNhbV4tMSAqIHpTY2FsZSleLTEgPT4gKHpTY2FsZV4tMSAqIGNhbSAqIGZsaXBeLTEpXG4gICAgICAgIGNvbnN0IG1hdHJpeCA9IG5ldyBGbG9hdDY0QXJyYXkoMTYpO1xuXG4gICAgICAgIC8vIENvbXB1dGUgaW52ZXJzZSBvZiBjYW1lcmEgbWF0cml4IGFuZCBwb3N0LW11bHRpcGx5IG5lZ2F0ZWQgdHJhbnNsYXRpb25cbiAgICAgICAgY29uc3QgaW52T3JpZW50YXRpb24gPSBuZXcgRmxvYXQ2NEFycmF5KDQpO1xuICAgICAgICBjb25zdCBpbnZQb3NpdGlvbiA9IHRoaXMucG9zaXRpb247XG5cbiAgICAgICAgcXVhdC5jb25qdWdhdGUoaW52T3JpZW50YXRpb24sIHRoaXMuX29yaWVudGF0aW9uKTtcbiAgICAgICAgdmVjMy5zY2FsZShpbnZQb3NpdGlvbiwgaW52UG9zaXRpb24sIC13b3JsZFNpemUpO1xuXG4gICAgICAgIG1hdDQuZnJvbVF1YXQobWF0cml4LCBpbnZPcmllbnRhdGlvbik7XG5cbiAgICAgICAgbWF0NC50cmFuc2xhdGUobWF0cml4LCBtYXRyaXgsIGludlBvc2l0aW9uKTtcblxuICAgICAgICAvLyBQcmUtbXVsdGlwbHkgeSAoMm5kIHJvdylcbiAgICAgICAgbWF0cml4WzFdICo9IC0xLjA7XG4gICAgICAgIG1hdHJpeFs1XSAqPSAtMS4wO1xuICAgICAgICBtYXRyaXhbOV0gKj0gLTEuMDtcbiAgICAgICAgbWF0cml4WzEzXSAqPSAtMS4wO1xuXG4gICAgICAgIC8vIFBvc3QtbXVsdGlwbHkgeiAoM3JkIGNvbHVtbilcbiAgICAgICAgbWF0cml4WzhdICo9IHBpeGVsc1Blck1ldGVyO1xuICAgICAgICBtYXRyaXhbOV0gKj0gcGl4ZWxzUGVyTWV0ZXI7XG4gICAgICAgIG1hdHJpeFsxMF0gKj0gcGl4ZWxzUGVyTWV0ZXI7XG4gICAgICAgIG1hdHJpeFsxMV0gKj0gcGl4ZWxzUGVyTWV0ZXI7XG5cbiAgICAgICAgcmV0dXJuIG1hdHJpeDtcbiAgICB9XG5cbiAgICBnZXRDYW1lcmFUb0NsaXBQZXJzcGVjdGl2ZShmb3Z5OiBudW1iZXIsIGFzcGVjdFJhdGlvOiBudW1iZXIsIG5lYXJaOiBudW1iZXIsIGZhclo6IG51bWJlcik6IEZsb2F0NjRBcnJheSB7XG4gICAgICAgIGNvbnN0IG1hdHJpeCA9IG5ldyBGbG9hdDY0QXJyYXkoMTYpO1xuICAgICAgICBtYXQ0LnBlcnNwZWN0aXZlKG1hdHJpeCwgZm92eSwgYXNwZWN0UmF0aW8sIG5lYXJaLCBmYXJaKTtcbiAgICAgICAgcmV0dXJuIG1hdHJpeDtcbiAgICB9XG5cbiAgICAvLyBUaGUgYWRkaXRpb25hbCBwYXJhbWV0ZXIgbmVlZHMgdG8gYmUgcmVtb3ZlZC4gVGhpcyB3YXMgaW50cm9kdWNlZCBiZWNhdXNlIG9yaWdpbmFsbHlcbiAgICAvLyB0aGUgdmFsdWUgcmV0dXJuZWQgYnkgdGhpcyBmdW5jdGlvbiB3YXMgaW5jb3JyZWN0LiBGaXhpbmcgaXQgd291bGQgYnJlYWsgdGhlIGZvZyB2aXN1YWxzIGFuZCBuZWVkcyB0byBiZVxuICAgIC8vIGNvbW11bmljYXRlZCBjYXJlZnVsbHkgZmlyc3QuIEFsc28gc2VlIHRyYW5zZm9ybS5jYW1lcmFXb3JsZFNpemVGb3JGb2cuXG4gICAgZ2V0RGlzdGFuY2VUb0VsZXZhdGlvbihlbGV2YXRpb25NZXRlcnM6IG51bWJlciwgY29udmVydDogYm9vbGVhbiA9IGZhbHNlKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgejAgPSBlbGV2YXRpb25NZXRlcnMgPT09IDAgPyAwIDogbWVyY2F0b3JaZnJvbUFsdGl0dWRlKGVsZXZhdGlvbk1ldGVycywgY29udmVydCA/IGxhdEZyb21NZXJjYXRvclkodGhpcy5wb3NpdGlvblsxXSkgOiB0aGlzLnBvc2l0aW9uWzFdKTtcbiAgICAgICAgY29uc3QgZiA9IHRoaXMuZm9yd2FyZCgpO1xuICAgICAgICByZXR1cm4gKHowIC0gdGhpcy5wb3NpdGlvblsyXSkgLyBmWzJdO1xuICAgIH1cblxuICAgIGNsb25lKCk6IEZyZWVDYW1lcmEge1xuICAgICAgICByZXR1cm4gbmV3IEZyZWVDYW1lcmEoWy4uLnRoaXMucG9zaXRpb25dLCBbLi4udGhpcy5vcmllbnRhdGlvbl0pO1xuICAgIH1cbn1cblxuZXhwb3J0IHtcbiAgICBGcmVlQ2FtZXJhLFxuICAgIEZyZWVDYW1lcmFPcHRpb25zXG59O1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IExuZ0xhdCBmcm9tICcuLi9sbmdfbGF0LmpzJztcbmltcG9ydCBNZXJjYXRvckNvb3JkaW5hdGUsIHtNQVhfTUVSQ0FUT1JfTEFUSVRVREV9IGZyb20gJy4uL21lcmNhdG9yX2Nvb3JkaW5hdGUuanMnO1xuaW1wb3J0IHttYXQ0LCBtYXQyfSBmcm9tICdnbC1tYXRyaXgnO1xuaW1wb3J0IHtjbGFtcCwgc21vb3Roc3RlcH0gZnJvbSAnLi4vLi4vdXRpbC91dGlsLmpzJztcblxuaW1wb3J0IHR5cGUgUHJvamVjdGlvbiBmcm9tICcuL3Byb2plY3Rpb24uanMnO1xuaW1wb3J0IHR5cGUgVHJhbnNmb3JtIGZyb20gJy4uL3RyYW5zZm9ybS5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldFByb2plY3Rpb25BZGp1c3RtZW50cyh0cmFuc2Zvcm06IFRyYW5zZm9ybSwgd2l0aG91dFJvdGF0aW9uPzogYm9vbGVhbik6IEFycmF5PG51bWJlcj4ge1xuICAgIGNvbnN0IGludGVycFQgPSBnZXRQcm9qZWN0aW9uSW50ZXJwb2xhdGlvblQodHJhbnNmb3JtLnByb2plY3Rpb24sIHRyYW5zZm9ybS56b29tLCB0cmFuc2Zvcm0ud2lkdGgsIHRyYW5zZm9ybS5oZWlnaHQpO1xuICAgIGNvbnN0IG1hdHJpeCA9IGdldFNoZWFyQWRqdXN0bWVudCh0cmFuc2Zvcm0ucHJvamVjdGlvbiwgdHJhbnNmb3JtLnpvb20sIHRyYW5zZm9ybS5jZW50ZXIsIGludGVycFQsIHdpdGhvdXRSb3RhdGlvbik7XG5cbiAgICBjb25zdCBzY2FsZUFkanVzdG1lbnQgPSBnZXRTY2FsZUFkanVzdG1lbnQodHJhbnNmb3JtKTtcbiAgICBtYXQ0LnNjYWxlKG1hdHJpeCwgbWF0cml4LCBbc2NhbGVBZGp1c3RtZW50LCBzY2FsZUFkanVzdG1lbnQsIDFdKTtcblxuICAgIHJldHVybiBtYXRyaXg7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTY2FsZUFkanVzdG1lbnQodHJhbnNmb3JtOiBUcmFuc2Zvcm0pOiBudW1iZXIge1xuICAgIGNvbnN0IHByb2plY3Rpb24gPSB0cmFuc2Zvcm0ucHJvamVjdGlvbjtcbiAgICBjb25zdCBpbnRlcnBUID0gZ2V0UHJvamVjdGlvbkludGVycG9sYXRpb25UKHRyYW5zZm9ybS5wcm9qZWN0aW9uLCB0cmFuc2Zvcm0uem9vbSwgdHJhbnNmb3JtLndpZHRoLCB0cmFuc2Zvcm0uaGVpZ2h0KTtcbiAgICBjb25zdCB6b29tQWRqdXN0bWVudCA9IGdldFpvb21BZGp1c3RtZW50KHByb2plY3Rpb24sIHRyYW5zZm9ybS5jZW50ZXIpO1xuICAgIGNvbnN0IHpvb21BZGp1c3RtZW50T3JpZ2luID0gZ2V0Wm9vbUFkanVzdG1lbnQocHJvamVjdGlvbiwgTG5nTGF0LmNvbnZlcnQocHJvamVjdGlvbi5jZW50ZXIpKTtcbiAgICBjb25zdCBzY2FsZUFkanVzdG1lbnQgPSBNYXRoLnBvdygyLCB6b29tQWRqdXN0bWVudCAqIGludGVycFQgKyAoMSAtIGludGVycFQpICogem9vbUFkanVzdG1lbnRPcmlnaW4pO1xuICAgIHJldHVybiBzY2FsZUFkanVzdG1lbnQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQcm9qZWN0aW9uQWRqdXN0bWVudEludmVydGVkKHRyYW5zZm9ybTogVHJhbnNmb3JtKTogQXJyYXk8bnVtYmVyPiB7XG4gICAgY29uc3QgbSA9IGdldFByb2plY3Rpb25BZGp1c3RtZW50cyh0cmFuc2Zvcm0sIHRydWUpO1xuICAgIHJldHVybiBtYXQyLmludmVydChbXSwgW1xuICAgICAgICBtWzBdLCBtWzFdLFxuICAgICAgICBtWzRdLCBtWzVdXSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQcm9qZWN0aW9uSW50ZXJwb2xhdGlvblQocHJvamVjdGlvbjogUHJvamVjdGlvbiwgem9vbTogbnVtYmVyLCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciwgbWF4U2l6ZTogbnVtYmVyID0gSW5maW5pdHkpOiBudW1iZXIge1xuICAgIGNvbnN0IHJhbmdlID0gcHJvamVjdGlvbi5yYW5nZTtcbiAgICBpZiAoIXJhbmdlKSByZXR1cm4gMDtcblxuICAgIGNvbnN0IHNpemUgPSBNYXRoLm1pbihtYXhTaXplLCBNYXRoLm1heCh3aWR0aCwgaGVpZ2h0KSk7XG4gICAgLy8gVGhlIGludGVycG9sYXRpb24gcmFuZ2VzIGFyZSBtYW51YWxseSBkZWZpbmVkIGJhc2VkIG9uIHdoYXQgbWFrZXNcbiAgICAvLyBzZW5zZSBpbiBhIDEwMjRweCB3aWRlIG1hcC4gQWRqdXN0IHRoZSByYW5nZXMgdG8gdGhlIGN1cnJlbnQgc2l6ZVxuICAgIC8vIG9mIHRoZSBtYXAuIFRoZSBzbWFsbGVyIHRoZSBtYXAsIHRoZSBlYXJsaWVyIHlvdSBjYW4gc3RhcnQgdW5za2V3aW5nLlxuICAgIGNvbnN0IHJhbmdlQWRqdXN0bWVudCA9IE1hdGgubG9nKHNpemUgLyAxMDI0KSAvIE1hdGguTE4yO1xuICAgIGNvbnN0IHpvb21BID0gcmFuZ2VbMF0gKyByYW5nZUFkanVzdG1lbnQ7XG4gICAgY29uc3Qgem9vbUIgPSByYW5nZVsxXSArIHJhbmdlQWRqdXN0bWVudDtcbiAgICBjb25zdCB0ID0gc21vb3Roc3RlcCh6b29tQSwgem9vbUIsIHpvb20pO1xuICAgIHJldHVybiB0O1xufVxuXG4vLyBhcHByb3guIGtpbG9tZXRlcnMgcGVyIGxvbmdpdHVkZSBkZWdyZWUgYXQgZXF1YXRvclxuY29uc3Qgb2Zmc2V0ID0gMSAvIDQwMDAwO1xuXG4vKlxuICogQ2FsY3VsYXRlcyB0aGUgc2NhbGUgZGlmZmVyZW5jZSBiZXR3ZWVuIE1lcmNhdG9yIGFuZCB0aGUgZ2l2ZW4gcHJvamVjdGlvbiBhdCBhIGNlcnRhaW4gbG9jYXRpb24uXG4gKi9cbmZ1bmN0aW9uIGdldFpvb21BZGp1c3RtZW50KHByb2plY3Rpb246IFByb2plY3Rpb24sIGxvYzogTG5nTGF0KSB7XG4gICAgLy8gbWFrZSBzdXJlIHdlIG9wZXJhdGUgd2l0aGluIG1lcmNhdG9yIHNwYWNlIGZvciBhZGp1c3RtZW50cyAodGhleSBjYW4gZ28gb3ZlciBmb3Igb3RoZXIgcHJvamVjdGlvbnMpXG4gICAgY29uc3QgbGF0ID0gY2xhbXAobG9jLmxhdCwgLU1BWF9NRVJDQVRPUl9MQVRJVFVERSwgTUFYX01FUkNBVE9SX0xBVElUVURFKTtcblxuICAgIGNvbnN0IGxvYzEgPSBuZXcgTG5nTGF0KGxvYy5sbmcgLSAxODAgKiBvZmZzZXQsIGxhdCk7XG4gICAgY29uc3QgbG9jMiA9IG5ldyBMbmdMYXQobG9jLmxuZyArIDE4MCAqIG9mZnNldCwgbGF0KTtcblxuICAgIGNvbnN0IHAxID0gcHJvamVjdGlvbi5wcm9qZWN0KGxvYzEubG5nLCBsYXQpO1xuICAgIGNvbnN0IHAyID0gcHJvamVjdGlvbi5wcm9qZWN0KGxvYzIubG5nLCBsYXQpO1xuXG4gICAgY29uc3QgbTEgPSBNZXJjYXRvckNvb3JkaW5hdGUuZnJvbUxuZ0xhdChsb2MxKTtcbiAgICBjb25zdCBtMiA9IE1lcmNhdG9yQ29vcmRpbmF0ZS5mcm9tTG5nTGF0KGxvYzIpO1xuXG4gICAgY29uc3QgcGR4ID0gcDIueCAtIHAxLng7XG4gICAgY29uc3QgcGR5ID0gcDIueSAtIHAxLnk7XG4gICAgY29uc3QgbWR4ID0gbTIueCAtIG0xLng7XG4gICAgY29uc3QgbWR5ID0gbTIueSAtIG0xLnk7XG5cbiAgICBjb25zdCBzY2FsZSA9IE1hdGguc3FydCgobWR4ICogbWR4ICsgbWR5ICogbWR5KSAvIChwZHggKiBwZHggKyBwZHkgKiBwZHkpKTtcblxuICAgIHJldHVybiBNYXRoLmxvZyhzY2FsZSkgLyBNYXRoLkxOMjtcbn1cblxuZnVuY3Rpb24gZ2V0U2hlYXJBZGp1c3RtZW50KHByb2plY3Rpb246IFByb2plY3Rpb24sIHpvb206IG51bWJlciwgbG9jOiBMbmdMYXQsIGludGVycFQ6IG51bWJlciwgd2l0aG91dFJvdGF0aW9uPzogYm9vbGVhbikge1xuXG4gICAgLy8gY3JlYXRlIHR3byBsb2NhdGlvbnMgYSB0aW55IGFtb3VudCAofjFrbSkgZWFzdCBhbmQgd2VzdCBvZiB0aGUgZ2l2ZW4gbG9jYXRpb25cbiAgICBjb25zdCBsb2N3ID0gbmV3IExuZ0xhdChsb2MubG5nIC0gMTgwICogb2Zmc2V0LCBsb2MubGF0KTtcbiAgICBjb25zdCBsb2NlID0gbmV3IExuZ0xhdChsb2MubG5nICsgMTgwICogb2Zmc2V0LCBsb2MubGF0KTtcblxuICAgIGNvbnN0IHB3ID0gcHJvamVjdGlvbi5wcm9qZWN0KGxvY3cubG5nLCBsb2N3LmxhdCk7XG4gICAgY29uc3QgcGUgPSBwcm9qZWN0aW9uLnByb2plY3QobG9jZS5sbmcsIGxvY2UubGF0KTtcblxuICAgIGNvbnN0IHBkeCA9IHBlLnggLSBwdy54O1xuICAgIGNvbnN0IHBkeSA9IHBlLnkgLSBwdy55O1xuXG4gICAgLy8gQ2FsY3VsYXRlIGhvdyBtdWNoIHRoZSBtYXAgd291bGQgbmVlZCB0byBiZSByb3RhdGVkIHRvIG1ha2UgZWFzdC13ZXN0IGluXG4gICAgLy8gcHJvamVjdGVkIGNvb3JkaW5hdGVzIGJlIGxlZnQtcmlnaHRcbiAgICBjb25zdCBhbmdsZUFkanVzdCA9IC1NYXRoLmF0YW4yKHBkeSwgcGR4KTtcblxuICAgIC8vIFBpY2sgYSBsb2NhdGlvbiBpZGVudGljYWwgdG8gdGhlIG9yaWdpbmFsIG9uZSBleGNlcHQgZm9yIHBvbGVzIHRvIG1ha2Ugc3VyZSB3ZSdyZSB3aXRoaW4gbWVyY2F0b3IgYm91bmRzXG4gICAgY29uc3QgbWMyID0gTWVyY2F0b3JDb29yZGluYXRlLmZyb21MbmdMYXQobG9jKTtcbiAgICBtYzIueSA9IGNsYW1wKG1jMi55LCAtMSArIG9mZnNldCwgMSAtIG9mZnNldCk7XG4gICAgY29uc3QgbG9jMiA9IG1jMi50b0xuZ0xhdCgpO1xuICAgIGNvbnN0IHAyID0gcHJvamVjdGlvbi5wcm9qZWN0KGxvYzIubG5nLCBsb2MyLmxhdCk7XG5cbiAgICAvLyBGaW5kIHRoZSBwcm9qZWN0ZWQgY29vcmRpbmF0ZXMgb2YgdHdvIGxvY2F0aW9ucywgb25lIHNsaWdodGx5IHNvdXRoIGFuZCBvbmUgc2xpZ2h0bHkgZWFzdC5cbiAgICAvLyBUaGVuIGNhbGN1bGF0ZSB0aGUgdHJhbnNmb3JtIHRoYXQgd291bGQgbWFrZSB0aGUgcHJvamVjdGVkIGNvb3JkaW5hdGVzIG9mIHRoZSB0d28gbG9jYXRpb25zIGJlOlxuICAgIC8vIC0gZXF1YWwgZGlzdGFuY2VzIGZyb20gdGhlIG9yaWdpbmFsIGxvY2F0aW9uXG4gICAgLy8gLSBwZXJwZW5kaWN1bGFyIHRvIG9uZSBhbm90aGVyXG4gICAgLy9cbiAgICAvLyBPbmx5IHRoZSBwb3NpdGlvbiBvZiB0aGUgY29vcmRpbmF0ZSB0byB0aGUgbm9ydGggaXMgYWRqdXN0ZWQuXG4gICAgLy8gVGhlIGNvb3JkaW5hdGUgdG8gdGhlIGVhc3Qgc3RheXMgd2hlcmUgaXQgaXMuXG4gICAgY29uc3QgbWMzID0gTWVyY2F0b3JDb29yZGluYXRlLmZyb21MbmdMYXQobG9jMik7XG4gICAgbWMzLnggKz0gb2Zmc2V0O1xuICAgIGNvbnN0IGxvYzMgPSBtYzMudG9MbmdMYXQoKTtcbiAgICBjb25zdCBwMyA9IHByb2plY3Rpb24ucHJvamVjdChsb2MzLmxuZywgbG9jMy5sYXQpO1xuICAgIGNvbnN0IHBkeDMgPSBwMy54IC0gcDIueDtcbiAgICBjb25zdCBwZHkzID0gcDMueSAtIHAyLnk7XG4gICAgY29uc3QgZGVsdGEzID0gcm90YXRlKHBkeDMsIHBkeTMsIGFuZ2xlQWRqdXN0KTtcblxuICAgIGNvbnN0IG1jNCA9IE1lcmNhdG9yQ29vcmRpbmF0ZS5mcm9tTG5nTGF0KGxvYzIpO1xuICAgIG1jNC55ICs9IG9mZnNldDtcbiAgICBjb25zdCBsb2M0ID0gbWM0LnRvTG5nTGF0KCk7XG4gICAgY29uc3QgcDQgPSBwcm9qZWN0aW9uLnByb2plY3QobG9jNC5sbmcsIGxvYzQubGF0KTtcbiAgICBjb25zdCBwZHg0ID0gcDQueCAtIHAyLng7XG4gICAgY29uc3QgcGR5NCA9IHA0LnkgLSBwMi55O1xuICAgIGNvbnN0IGRlbHRhNCA9IHJvdGF0ZShwZHg0LCBwZHk0LCBhbmdsZUFkanVzdCk7XG5cbiAgICBjb25zdCBzY2FsZSA9IE1hdGguYWJzKGRlbHRhMy54KSAvIE1hdGguYWJzKGRlbHRhNC55KTtcblxuICAgIGNvbnN0IHVucm90YXRlID0gbWF0NC5pZGVudGl0eShbXSk7XG4gICAgbWF0NC5yb3RhdGVaKHVucm90YXRlLCB1bnJvdGF0ZSwgKC1hbmdsZUFkanVzdCkgKiAoMSAtICh3aXRob3V0Um90YXRpb24gPyAwIDogaW50ZXJwVCkpKTtcblxuICAgIC8vIHVuc2tld1xuICAgIGNvbnN0IHNoZWFyID0gbWF0NC5pZGVudGl0eShbXSk7XG4gICAgbWF0NC5zY2FsZShzaGVhciwgc2hlYXIsIFsxLCAxIC0gKDEgLSBzY2FsZSkgKiBpbnRlcnBULCAxXSk7XG4gICAgc2hlYXJbNF0gPSAtZGVsdGE0LnggLyBkZWx0YTQueSAqIGludGVycFQ7XG5cbiAgICAvLyB1bnJvdGF0ZVxuICAgIG1hdDQucm90YXRlWihzaGVhciwgc2hlYXIsIGFuZ2xlQWRqdXN0KTtcblxuICAgIG1hdDQubXVsdGlwbHkoc2hlYXIsIHVucm90YXRlLCBzaGVhcik7XG5cbiAgICByZXR1cm4gc2hlYXI7XG59XG5cbmZ1bmN0aW9uIHJvdGF0ZSh4OiBudW1iZXIsIHk6IG51bWJlciwgYW5nbGU6IG51bWJlcikge1xuICAgIGNvbnN0IGNvcyA9IE1hdGguY29zKGFuZ2xlKTtcbiAgICBjb25zdCBzaW4gPSBNYXRoLnNpbihhbmdsZSk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgeDogeCAqIGNvcyAtIHkgKiBzaW4sXG4gICAgICAgIHk6IHggKiBzaW4gKyB5ICogY29zXG4gICAgfTtcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBMbmdMYXQgZnJvbSAnLi9sbmdfbGF0LmpzJztcbmltcG9ydCBMbmdMYXRCb3VuZHMgZnJvbSAnLi9sbmdfbGF0X2JvdW5kcy5qcyc7XG5pbXBvcnQgTWVyY2F0b3JDb29yZGluYXRlLCB7bWVyY2F0b3JYZnJvbUxuZywgbWVyY2F0b3JZZnJvbUxhdCwgbWVyY2F0b3JaZnJvbUFsdGl0dWRlLCBsYXRGcm9tTWVyY2F0b3JZLCBNQVhfTUVSQ0FUT1JfTEFUSVRVREUsIGNpcmN1bWZlcmVuY2VBdExhdGl0dWRlfSBmcm9tICcuL21lcmNhdG9yX2Nvb3JkaW5hdGUuanMnO1xuaW1wb3J0IHtnZXRQcm9qZWN0aW9ufSBmcm9tICcuL3Byb2plY3Rpb24vaW5kZXguanMnO1xuaW1wb3J0IHt0aWxlQUFCQn0gZnJvbSAnLi4vZ2VvL3Byb2plY3Rpb24vdGlsZV90cmFuc2Zvcm0uanMnO1xuaW1wb3J0IFBvaW50IGZyb20gJ0BtYXBib3gvcG9pbnQtZ2VvbWV0cnknO1xuaW1wb3J0IHt3cmFwLCBjbGFtcCwgcGljaywgcmFkVG9EZWcsIGRlZ1RvUmFkLCBnZXRBQUJCUG9pbnRTcXVhcmVEaXN0LCBmdXJ0aGVzdFRpbGVDb3JuZXIsIHdhcm5PbmNlLCBkZWVwRXF1YWx9IGZyb20gJy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQge251bWJlciBhcyBpbnRlcnBvbGF0ZX0gZnJvbSAnLi4vc3R5bGUtc3BlYy91dGlsL2ludGVycG9sYXRlLmpzJztcbmltcG9ydCBFWFRFTlQgZnJvbSAnLi4vZGF0YS9leHRlbnQuanMnO1xuaW1wb3J0IHt2ZWM0LCBtYXQ0LCBtYXQyLCB2ZWMzLCBxdWF0fSBmcm9tICdnbC1tYXRyaXgnO1xuaW1wb3J0IHtGcnVzdHVtLCBGcnVzdHVtQ29ybmVycywgUmF5fSBmcm9tICcuLi91dGlsL3ByaW1pdGl2ZXMuanMnO1xuaW1wb3J0IEVkZ2VJbnNldHMgZnJvbSAnLi9lZGdlX2luc2V0cy5qcyc7XG5pbXBvcnQge0ZyZWVDYW1lcmEsIEZyZWVDYW1lcmFPcHRpb25zLCBvcmllbnRhdGlvbkZyb21GcmFtZX0gZnJvbSAnLi4vdWkvZnJlZV9jYW1lcmEuanMnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IGdldFByb2plY3Rpb25BZGp1c3RtZW50cywge2dldFByb2plY3Rpb25BZGp1c3RtZW50SW52ZXJ0ZWQsIGdldFNjYWxlQWRqdXN0bWVudCwgZ2V0UHJvamVjdGlvbkludGVycG9sYXRpb25UfSBmcm9tICcuL3Byb2plY3Rpb24vYWRqdXN0bWVudHMuanMnO1xuaW1wb3J0IHtnZXRQaXhlbHNUb1RpbGVVbml0c01hdHJpeH0gZnJvbSAnLi4vc291cmNlL3BpeGVsc190b190aWxlX3VuaXRzLmpzJztcbmltcG9ydCB7VW53cmFwcGVkVGlsZUlELCBPdmVyc2NhbGVkVGlsZUlELCBDYW5vbmljYWxUaWxlSUR9IGZyb20gJy4uL3NvdXJjZS90aWxlX2lkLmpzJztcbmltcG9ydCB7XG4gICAgY2FsY3VsYXRlR2xvYmVNYXRyaXgsXG4gICAgcG9sZXNJblZpZXdwb3J0LFxuICAgIEdMT0JFX1pPT01fVEhSRVNIT0xEX01JTixcbiAgICBHTE9CRV9aT09NX1RIUkVTSE9MRF9NQVgsXG4gICAgR0xPQkVfU0NBTEVfTUFUQ0hfTEFUSVRVREVcbn0gZnJvbSAnLi4vZ2VvL3Byb2plY3Rpb24vZ2xvYmVfdXRpbC5qcyc7XG5pbXBvcnQge3Byb2plY3RDbGFtcGVkfSBmcm9tICcuLi9zeW1ib2wvcHJvamVjdGlvbi5qcyc7XG5cbmltcG9ydCB0eXBlIFByb2plY3Rpb24gZnJvbSAnLi4vZ2VvL3Byb2plY3Rpb24vcHJvamVjdGlvbi5qcyc7XG5pbXBvcnQgdHlwZSB7RWxldmF0aW9ufSBmcm9tICcuLi90ZXJyYWluL2VsZXZhdGlvbi5qcyc7XG5pbXBvcnQgdHlwZSB7UGFkZGluZ09wdGlvbnN9IGZyb20gJy4vZWRnZV9pbnNldHMuanMnO1xuaW1wb3J0IHR5cGUgVGlsZSBmcm9tICcuLi9zb3VyY2UvdGlsZS5qcyc7XG5pbXBvcnQgdHlwZSB7UHJvamVjdGlvblNwZWNpZmljYXRpb259IGZyb20gJy4uL3N0eWxlLXNwZWMvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge0ZlYXR1cmVEaXN0YW5jZURhdGF9IGZyb20gJy4uL3N0eWxlLXNwZWMvZmVhdHVyZV9maWx0ZXIvaW5kZXguanMnO1xuaW1wb3J0IHR5cGUge01hdDQsIFZlYzMsIFZlYzQsIFF1YXR9IGZyb20gJ2dsLW1hdHJpeCc7XG5pbXBvcnQgdHlwZSB7QWFiYn0gZnJvbSAnLi4vdXRpbC9wcmltaXRpdmVzJztcblxuY29uc3QgTlVNX1dPUkxEX0NPUElFUyA9IDM7XG5jb25zdCBERUZBVUxUX01JTl9aT09NID0gMDtcblxudHlwZSBSYXlJbnRlcnNlY3Rpb25SZXN1bHQgPSB7IHAwOiBWZWM0LCBwMTogVmVjNCwgdDogbnVtYmVyfTtcbnR5cGUgRWxldmF0aW9uUmVmZXJlbmNlID0gXCJzZWFcIiB8IFwiZ3JvdW5kXCI7XG50eXBlIFJvb3RUaWxlID0ge1xuICAgIGFhYmI6IEFhYmIsXG4gICAgZnVsbHlWaXNpYmxlOiBib29sZWFuLFxuICAgIG1heFo6IG51bWJlcixcbiAgICBtaW5aOiBudW1iZXIsXG4gICAgc2hvdWxkU3BsaXQ/OiBib29sZWFuLFxuICAgIHRpbGVJRD86IE92ZXJzY2FsZWRUaWxlSUQsXG4gICAgd3JhcDogbnVtYmVyLFxuICAgIHg6IG51bWJlcixcbiAgICB5OiBudW1iZXIsXG4gICAgem9vbTogbnVtYmVyLFxufTtcblxuLyoqXG4gKiBBIHNpbmdsZSB0cmFuc2Zvcm0sIGdlbmVyYWxseSB1c2VkIGZvciBhIHNpbmdsZSB0aWxlIHRvIGJlXG4gKiBzY2FsZWQsIHJvdGF0ZWQsIGFuZCB6b29tZWQuXG4gKiBAcHJpdmF0ZVxuICovXG5jbGFzcyBUcmFuc2Zvcm0ge1xuICAgIHRpbGVTaXplOiBudW1iZXI7XG4gICAgdGlsZVpvb206IG51bWJlcjtcbiAgICBtYXhCb3VuZHM6ID9MbmdMYXRCb3VuZHM7XG5cbiAgICAvLyAyXnpvb20gKHdvcmxkU2l6ZSA9IHRpbGVTaXplICogc2NhbGUpXG4gICAgc2NhbGU6IG51bWJlcjtcblxuICAgIC8vIE1hcCB2aWV3cG9ydCBzaXplIChub3QgaW5jbHVkaW5nIHRoZSBwaXhlbCByYXRpbylcbiAgICB3aWR0aDogbnVtYmVyO1xuICAgIGhlaWdodDogbnVtYmVyO1xuXG4gICAgLy8gQmVhcmluZywgcmFkaWFucywgaW4gWy1waSwgcGldXG4gICAgYW5nbGU6IG51bWJlcjtcblxuICAgIC8vIDJEIHJvdGF0aW9uIG1hdHJpeCBpbiB0aGUgaG9yaXpvbnRhbCBwbGFuZSwgYXMgYSBmdW5jdGlvbiBvZiBiZWFyaW5nXG4gICAgcm90YXRpb25NYXRyaXg6IEZsb2F0MzJBcnJheTtcblxuICAgIC8vIFpvb20sIG1vZHVsbyAxXG4gICAgem9vbUZyYWN0aW9uOiBudW1iZXI7XG5cbiAgICAvLyBUaGUgc2NhbGUgZmFjdG9yIGNvbXBvbmVudCBvZiB0aGUgY29udmVyc2lvbiBmcm9tIHBpeGVscyAoWzAsIHddIHggW2gsIDBdKSB0byBHTFxuICAgIC8vIE5EQyAoWzEsIC0xXSB4IFsxLCAtMV0pIChub3RlIGZsaXBwZWQgeSlcbiAgICBwaXhlbHNUb0dMVW5pdHM6IFtudW1iZXIsIG51bWJlcl07XG5cbiAgICAvLyBEaXN0YW5jZSBmcm9tIGNhbWVyYSB0byB0aGUgY2VudGVyLCBpbiBzY3JlZW4gcGl4ZWwgdW5pdHMsIGluZGVwZW5kZW50IG9mIHpvb21cbiAgICBjYW1lcmFUb0NlbnRlckRpc3RhbmNlOiBudW1iZXI7XG5cbiAgICAvLyBQcm9qZWN0aW9uIGZyb20gbWVyY2F0b3IgY29vcmRpbmF0ZXMgKFswLCAwXSBudywgWzEsIDFdIHNlKSB0byBHTCBjbGlwIGNvb3JkaW5hdGVzXG4gICAgbWVyY2F0b3JNYXRyaXg6IEFycmF5PG51bWJlcj47XG5cbiAgICAvLyBUcmFuc2xhdGUgcG9pbnRzIGluIG1lcmNhdG9yIGNvb3JkaW5hdGVzIHRvIGJlIGNlbnRlcmVkIGFib3V0IHRoZSBjYW1lcmEsIHdpdGggdW5pdHMgY2hvc2VuXG4gICAgLy8gZm9yIHNjcmVlbi1oZWlnaHQtaW5kZXBlbmRlbnQgc2NhbGluZyBvZiBmb2cuIE5vdCBhZmZlY3RlZCBieSBvcmllbnRhdGlvbiBvZiBjYW1lcmEuXG4gICAgbWVyY2F0b3JGb2dNYXRyaXg6IEZsb2F0MzJBcnJheTtcblxuICAgIC8vIFByb2plY3Rpb24gZnJvbSB3b3JsZCBjb29yZGluYXRlcyAobWVyY2F0b3Igc2NhbGVkIGJ5IHdvcmxkU2l6ZSkgdG8gY2xpcCBjb29yZGluYXRlc1xuICAgIHByb2pNYXRyaXg6IEFycmF5PG51bWJlcj4gfCBGbG9hdDMyQXJyYXkgfCBGbG9hdDY0QXJyYXk7XG4gICAgaW52UHJvak1hdHJpeDogRmxvYXQ2NEFycmF5O1xuXG4gICAgLy8gU2FtZSBhcyBwcm9qTWF0cml4LCBwaXhlbC1hbGlnbmVkIHRvIGF2b2lkIGZyYWN0aW9uYWwgcGl4ZWxzIGZvciByYXN0ZXIgdGlsZXNcbiAgICBhbGlnbmVkUHJvak1hdHJpeDogRmxvYXQ2NEFycmF5O1xuXG4gICAgLy8gRnJvbSB3b3JsZCBjb29yZGluYXRlcyB0byBzY3JlZW4gcGl4ZWwgY29vcmRpbmF0ZXMgKHByb2pNYXRyaXggcHJlbXVsdGlwbGllZCBieSBsYWJlbFBsYW5lTWF0cml4KVxuICAgIHBpeGVsTWF0cml4OiBGbG9hdDY0QXJyYXk7XG4gICAgcGl4ZWxNYXRyaXhJbnZlcnNlOiBGbG9hdDY0QXJyYXk7XG5cbiAgICB3b3JsZFRvRm9nTWF0cml4OiBGbG9hdDY0QXJyYXk7XG4gICAgc2t5Ym94TWF0cml4OiBGbG9hdDMyQXJyYXk7XG5cbiAgICAvLyBUcmFuc2Zvcm0gZnJvbSBzY3JlZW4gY29vcmRpbmF0ZXMgdG8gR0wgTkRDLCBbMCwgd10geCBbaCwgMF0gLS0+IFstMSwgMV0geCBbLTEsIDFdXG4gICAgLy8gUm91Z2hseSBzcGVha2luZywgYXBwbGllcyBwaXhlbHNUb0dMVW5pdHMgc2NhbGluZyB3aXRoIGEgdHJhbnNsYXRpb25cbiAgICBnbENvb3JkTWF0cml4OiBGbG9hdDMyQXJyYXk7XG5cbiAgICAvLyBJbnZlcnNlIG9mIGdsQ29vcmRNYXRyaXgsIGZyb20gTkRDIHRvIHNjcmVlbiBjb29yZGluYXRlcywgWy0xLCAxXSB4IFstMSwgMV0gLS0+IFswLCB3XSB4IFtoLCAwXVxuICAgIGxhYmVsUGxhbmVNYXRyaXg6IEZsb2F0MzJBcnJheTtcblxuICAgIC8vIGdsb2JlIGNvb3JkaW5hdGUgdHJhbnNmb3JtYXRpb24gbWF0cml4XG4gICAgZ2xvYmVNYXRyaXg6IEZsb2F0NjRBcnJheTtcblxuICAgIGdsb2JlQ2VudGVySW5WaWV3U3BhY2U6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbiAgICBnbG9iZVJhZGl1czogbnVtYmVyO1xuXG4gICAgaW52ZXJzZUFkanVzdG1lbnRNYXRyaXg6IEFycmF5PG51bWJlcj47XG5cbiAgICBtZXJjYXRvckZyb21UcmFuc2l0aW9uOiBib29sZWFuO1xuXG4gICAgbWluTG5nOiBudW1iZXI7XG4gICAgbWF4TG5nOiBudW1iZXI7XG4gICAgbWluTGF0OiBudW1iZXI7XG4gICAgbWF4TGF0OiBudW1iZXI7XG4gICAgd29ybGRNaW5YOiBudW1iZXI7XG4gICAgd29ybGRNYXhYOiBudW1iZXI7XG4gICAgd29ybGRNaW5ZOiBudW1iZXI7XG4gICAgd29ybGRNYXhZOiBudW1iZXI7XG5cbiAgICBmcnVzdHVtQ29ybmVyczogRnJ1c3R1bUNvcm5lcnM7XG5cbiAgICBmcmVlemVUaWxlQ292ZXJhZ2U6IGJvb2xlYW47XG4gICAgY2FtZXJhRWxldmF0aW9uUmVmZXJlbmNlOiBFbGV2YXRpb25SZWZlcmVuY2U7XG4gICAgZm9nQ3VsbERpc3RTcTogP251bWJlcjtcbiAgICBfYXZlcmFnZUVsZXZhdGlvbjogbnVtYmVyO1xuICAgIHByb2plY3Rpb25PcHRpb25zOiBQcm9qZWN0aW9uU3BlY2lmaWNhdGlvbjtcbiAgICBwcm9qZWN0aW9uOiBQcm9qZWN0aW9uO1xuICAgIF9lbGV2YXRpb246ID9FbGV2YXRpb247XG4gICAgX2ZvdjogbnVtYmVyO1xuICAgIF9waXRjaDogbnVtYmVyO1xuICAgIF96b29tOiBudW1iZXI7XG4gICAgX3NlYUxldmVsWm9vbTogP251bWJlcjtcbiAgICBfdW5tb2RpZmllZDogYm9vbGVhbjtcbiAgICBfcmVuZGVyV29ybGRDb3BpZXM6IGJvb2xlYW47XG4gICAgX21pblpvb206IG51bWJlcjtcbiAgICBfbWF4Wm9vbTogbnVtYmVyO1xuICAgIF9taW5QaXRjaDogbnVtYmVyO1xuICAgIF9tYXhQaXRjaDogbnVtYmVyO1xuICAgIF9jZW50ZXI6IExuZ0xhdDtcbiAgICBfZWRnZUluc2V0czogRWRnZUluc2V0cztcbiAgICBfY29uc3RyYWluaW5nOiBib29sZWFuO1xuICAgIF9wcm9qTWF0cml4Q2FjaGU6IHtbXzogbnVtYmVyXTogRmxvYXQzMkFycmF5fTtcbiAgICBfYWxpZ25lZFByb2pNYXRyaXhDYWNoZToge1tfOiBudW1iZXJdOiBGbG9hdDMyQXJyYXl9O1xuICAgIF9waXhlbHNUb1RpbGVVbml0c0NhY2hlOiB7W186IG51bWJlcl06IEZsb2F0MzJBcnJheX07XG4gICAgX2ZvZ1RpbGVNYXRyaXhDYWNoZToge1tfOiBudW1iZXJdOiBGbG9hdDMyQXJyYXl9O1xuICAgIF9kaXN0YW5jZVRpbGVEYXRhQ2FjaGU6IHtbXzogbnVtYmVyXTogRmVhdHVyZURpc3RhbmNlRGF0YX07XG4gICAgX2NhbWVyYTogRnJlZUNhbWVyYTtcbiAgICBfY2VudGVyQWx0aXR1ZGU6IG51bWJlcjtcbiAgICBfY2VudGVyQWx0aXR1ZGVWYWxpZEZvckV4YWdnZXJhdGlvbjogP251bWJlcjtcbiAgICBfaG9yaXpvblNoaWZ0OiBudW1iZXI7XG4gICAgX3BpeGVsc1Blck1lcmNhdG9yUGl4ZWw6IG51bWJlcjtcbiAgICBfbmVhclo6IG51bWJlcjtcbiAgICBfZmFyWjogbnVtYmVyO1xuICAgIF9tZXJjYXRvclNjYWxlUmF0aW86IG51bWJlcjtcbiAgICBfaXNDYW1lcmFDb25zdHJhaW5lZDogYm9vbGVhbjtcblxuICAgIGNvbnN0cnVjdG9yKG1pblpvb206ID9udW1iZXIsIG1heFpvb206ID9udW1iZXIsIG1pblBpdGNoOiA/bnVtYmVyLCBtYXhQaXRjaDogP251bWJlciwgcmVuZGVyV29ybGRDb3BpZXM6IGJvb2xlYW4gfCB2b2lkLCBwcm9qZWN0aW9uPzogP1Byb2plY3Rpb25TcGVjaWZpY2F0aW9uLCBib3VuZHM6ID9MbmdMYXRCb3VuZHMpIHtcbiAgICAgICAgdGhpcy50aWxlU2l6ZSA9IDUxMjsgLy8gY29uc3RhbnRcblxuICAgICAgICB0aGlzLl9yZW5kZXJXb3JsZENvcGllcyA9IHJlbmRlcldvcmxkQ29waWVzID09PSB1bmRlZmluZWQgPyB0cnVlIDogcmVuZGVyV29ybGRDb3BpZXM7XG4gICAgICAgIHRoaXMuX21pblpvb20gPSBtaW5ab29tIHx8IERFRkFVTFRfTUlOX1pPT007XG4gICAgICAgIHRoaXMuX21heFpvb20gPSBtYXhab29tIHx8IDIyO1xuXG4gICAgICAgIHRoaXMuX21pblBpdGNoID0gKG1pblBpdGNoID09PSB1bmRlZmluZWQgfHwgbWluUGl0Y2ggPT09IG51bGwpID8gMCA6IG1pblBpdGNoO1xuICAgICAgICB0aGlzLl9tYXhQaXRjaCA9IChtYXhQaXRjaCA9PT0gdW5kZWZpbmVkIHx8IG1heFBpdGNoID09PSBudWxsKSA/IDYwIDogbWF4UGl0Y2g7XG5cbiAgICAgICAgdGhpcy5zZXRQcm9qZWN0aW9uKHByb2plY3Rpb24pO1xuICAgICAgICB0aGlzLnNldE1heEJvdW5kcyhib3VuZHMpO1xuXG4gICAgICAgIHRoaXMud2lkdGggPSAwO1xuICAgICAgICB0aGlzLmhlaWdodCA9IDA7XG4gICAgICAgIHRoaXMuX2NlbnRlciA9IG5ldyBMbmdMYXQoMCwgMCk7XG4gICAgICAgIHRoaXMuem9vbSA9IDA7XG4gICAgICAgIHRoaXMuYW5nbGUgPSAwO1xuICAgICAgICB0aGlzLl9mb3YgPSAwLjY0MzUwMTEwODc5MzI4NDQ7XG4gICAgICAgIHRoaXMuX3BpdGNoID0gMDtcbiAgICAgICAgdGhpcy5fbmVhclogPSAwO1xuICAgICAgICB0aGlzLl9mYXJaID0gMDtcbiAgICAgICAgdGhpcy5fdW5tb2RpZmllZCA9IHRydWU7XG4gICAgICAgIHRoaXMuX2VkZ2VJbnNldHMgPSBuZXcgRWRnZUluc2V0cygpO1xuICAgICAgICB0aGlzLl9wcm9qTWF0cml4Q2FjaGUgPSB7fTtcbiAgICAgICAgdGhpcy5fYWxpZ25lZFByb2pNYXRyaXhDYWNoZSA9IHt9O1xuICAgICAgICB0aGlzLl9mb2dUaWxlTWF0cml4Q2FjaGUgPSB7fTtcbiAgICAgICAgdGhpcy5fZGlzdGFuY2VUaWxlRGF0YUNhY2hlID0ge307XG4gICAgICAgIHRoaXMuX2NhbWVyYSA9IG5ldyBGcmVlQ2FtZXJhKCk7XG4gICAgICAgIHRoaXMuX2NlbnRlckFsdGl0dWRlID0gMDtcbiAgICAgICAgdGhpcy5fYXZlcmFnZUVsZXZhdGlvbiA9IDA7XG4gICAgICAgIHRoaXMuY2FtZXJhRWxldmF0aW9uUmVmZXJlbmNlID0gXCJncm91bmRcIjtcbiAgICAgICAgdGhpcy5fcGl4ZWxzUGVyTWVyY2F0b3JQaXhlbCA9IDEuMDtcbiAgICAgICAgdGhpcy5nbG9iZVJhZGl1cyA9IDA7XG4gICAgICAgIHRoaXMuZ2xvYmVDZW50ZXJJblZpZXdTcGFjZSA9IFswLCAwLCAwXTtcblxuICAgICAgICAvLyBNb3ZlIHRoZSBob3Jpem9uIGNsb3NlciB0byB0aGUgY2VudGVyLiAwIHdvdWxkIG5vdCBzaGlmdCB0aGUgaG9yaXpvbi4gMSB3b3VsZCBwdXQgdGhlIGhvcml6b24gYXQgdGhlIGNlbnRlci5cbiAgICAgICAgdGhpcy5faG9yaXpvblNoaWZ0ID0gMC4xO1xuICAgIH1cblxuICAgIGNsb25lKCk6IFRyYW5zZm9ybSB7XG4gICAgICAgIGNvbnN0IGNsb25lID0gbmV3IFRyYW5zZm9ybSh0aGlzLl9taW5ab29tLCB0aGlzLl9tYXhab29tLCB0aGlzLl9taW5QaXRjaCwgdGhpcy5tYXhQaXRjaCwgdGhpcy5fcmVuZGVyV29ybGRDb3BpZXMsIHRoaXMuZ2V0UHJvamVjdGlvbigpKTtcbiAgICAgICAgY2xvbmUuX2VsZXZhdGlvbiA9IHRoaXMuX2VsZXZhdGlvbjtcbiAgICAgICAgY2xvbmUuX2NlbnRlckFsdGl0dWRlID0gdGhpcy5fY2VudGVyQWx0aXR1ZGU7XG4gICAgICAgIGNsb25lLl9jZW50ZXJBbHRpdHVkZVZhbGlkRm9yRXhhZ2dlcmF0aW9uID0gdGhpcy5fY2VudGVyQWx0aXR1ZGVWYWxpZEZvckV4YWdnZXJhdGlvbjtcbiAgICAgICAgY2xvbmUudGlsZVNpemUgPSB0aGlzLnRpbGVTaXplO1xuICAgICAgICBjbG9uZS5tZXJjYXRvckZyb21UcmFuc2l0aW9uID0gdGhpcy5tZXJjYXRvckZyb21UcmFuc2l0aW9uO1xuICAgICAgICBjbG9uZS53aWR0aCA9IHRoaXMud2lkdGg7XG4gICAgICAgIGNsb25lLmhlaWdodCA9IHRoaXMuaGVpZ2h0O1xuICAgICAgICBjbG9uZS5jYW1lcmFFbGV2YXRpb25SZWZlcmVuY2UgPSB0aGlzLmNhbWVyYUVsZXZhdGlvblJlZmVyZW5jZTtcbiAgICAgICAgY2xvbmUuX2NlbnRlciA9IHRoaXMuX2NlbnRlcjtcbiAgICAgICAgY2xvbmUuX3NldFpvb20odGhpcy56b29tKTtcbiAgICAgICAgY2xvbmUuX3NlYUxldmVsWm9vbSA9IHRoaXMuX3NlYUxldmVsWm9vbTtcbiAgICAgICAgY2xvbmUuYW5nbGUgPSB0aGlzLmFuZ2xlO1xuICAgICAgICBjbG9uZS5fZm92ID0gdGhpcy5fZm92O1xuICAgICAgICBjbG9uZS5fcGl0Y2ggPSB0aGlzLl9waXRjaDtcbiAgICAgICAgY2xvbmUuX25lYXJaID0gdGhpcy5fbmVhclo7XG4gICAgICAgIGNsb25lLl9mYXJaID0gdGhpcy5fZmFyWjtcbiAgICAgICAgY2xvbmUuX2F2ZXJhZ2VFbGV2YXRpb24gPSB0aGlzLl9hdmVyYWdlRWxldmF0aW9uO1xuICAgICAgICBjbG9uZS5fdW5tb2RpZmllZCA9IHRoaXMuX3VubW9kaWZpZWQ7XG4gICAgICAgIGNsb25lLl9lZGdlSW5zZXRzID0gdGhpcy5fZWRnZUluc2V0cy5jbG9uZSgpO1xuICAgICAgICBjbG9uZS5fY2FtZXJhID0gdGhpcy5fY2FtZXJhLmNsb25lKCk7XG4gICAgICAgIGNsb25lLl9jYWxjTWF0cmljZXMoKTtcbiAgICAgICAgY2xvbmUuZnJlZXplVGlsZUNvdmVyYWdlID0gdGhpcy5mcmVlemVUaWxlQ292ZXJhZ2U7XG4gICAgICAgIGNsb25lLmZydXN0dW1Db3JuZXJzID0gdGhpcy5mcnVzdHVtQ29ybmVycztcbiAgICAgICAgcmV0dXJuIGNsb25lO1xuICAgIH1cblxuICAgIGdldCBlbGV2YXRpb24oKTogP0VsZXZhdGlvbiB7IHJldHVybiB0aGlzLl9lbGV2YXRpb247IH1cbiAgICBzZXQgZWxldmF0aW9uKGVsZXZhdGlvbjogP0VsZXZhdGlvbikge1xuICAgICAgICBpZiAodGhpcy5fZWxldmF0aW9uID09PSBlbGV2YXRpb24pIHJldHVybjtcbiAgICAgICAgdGhpcy5fZWxldmF0aW9uID0gZWxldmF0aW9uO1xuICAgICAgICB0aGlzLl91cGRhdGVDYW1lcmFPblRlcnJhaW4oKTtcbiAgICAgICAgdGhpcy5fY2FsY01hdHJpY2VzKCk7XG4gICAgfVxuXG4gICAgdXBkYXRlRWxldmF0aW9uKGNvbnN0cmFpbkNhbWVyYU92ZXJUZXJyYWluOiBib29sZWFuLCBhZGFwdENhbWVyYUFsdGl0dWRlOiBib29sZWFuID0gZmFsc2UpIHtcbiAgICAgICAgY29uc3QgY2VudGVyQWx0aXR1ZGVDaGFuZ2VkID0gdGhpcy5fZWxldmF0aW9uICYmIHRoaXMuX2VsZXZhdGlvbi5leGFnZ2VyYXRpb24oKSAhPT0gdGhpcy5fY2VudGVyQWx0aXR1ZGVWYWxpZEZvckV4YWdnZXJhdGlvbjtcbiAgICAgICAgaWYgKHRoaXMuX3NlYUxldmVsWm9vbSA9PSBudWxsIHx8IGNlbnRlckFsdGl0dWRlQ2hhbmdlZCkge1xuICAgICAgICAgICAgdGhpcy5fdXBkYXRlQ2FtZXJhT25UZXJyYWluKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbnN0cmFpbkNhbWVyYU92ZXJUZXJyYWluIHx8IGNlbnRlckFsdGl0dWRlQ2hhbmdlZCkge1xuICAgICAgICAgICAgdGhpcy5fY29uc3RyYWluQ2FtZXJhKGFkYXB0Q2FtZXJhQWx0aXR1ZGUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2NhbGNNYXRyaWNlcygpO1xuICAgIH1cblxuICAgIGdldFByb2plY3Rpb24oKTogUHJvamVjdGlvblNwZWNpZmljYXRpb24ge1xuICAgICAgICByZXR1cm4gKHBpY2sodGhpcy5wcm9qZWN0aW9uLCBbJ25hbWUnLCAnY2VudGVyJywgJ3BhcmFsbGVscyddKTogUHJvamVjdGlvblNwZWNpZmljYXRpb24pO1xuICAgIH1cblxuICAgIC8vIFJldHVybnMgd2hldGhlciB0aGUgcHJvamVjdGlvbiBjaGFuZ2VzXG4gICAgc2V0UHJvamVjdGlvbihwcm9qZWN0aW9uPzogP1Byb2plY3Rpb25TcGVjaWZpY2F0aW9uKTogYm9vbGVhbiB7XG4gICAgICAgIHRoaXMucHJvamVjdGlvbk9wdGlvbnMgPSBwcm9qZWN0aW9uIHx8IHtuYW1lOiAnbWVyY2F0b3InfTtcblxuICAgICAgICBjb25zdCBvbGRQcm9qZWN0aW9uID0gdGhpcy5wcm9qZWN0aW9uID8gdGhpcy5nZXRQcm9qZWN0aW9uKCkgOiB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMucHJvamVjdGlvbiA9IGdldFByb2plY3Rpb24odGhpcy5wcm9qZWN0aW9uT3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IG5ld1Byb2plY3Rpb24gPSB0aGlzLmdldFByb2plY3Rpb24oKTtcblxuICAgICAgICBjb25zdCBwcm9qZWN0aW9uSGFzQ2hhbmdlZCA9ICFkZWVwRXF1YWwob2xkUHJvamVjdGlvbiwgbmV3UHJvamVjdGlvbik7XG4gICAgICAgIGlmIChwcm9qZWN0aW9uSGFzQ2hhbmdlZCkge1xuICAgICAgICAgICAgdGhpcy5fY2FsY01hdHJpY2VzKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5tZXJjYXRvckZyb21UcmFuc2l0aW9uID0gZmFsc2U7XG5cbiAgICAgICAgcmV0dXJuIHByb2plY3Rpb25IYXNDaGFuZ2VkO1xuICAgIH1cblxuICAgIHNldE1lcmNhdG9yRnJvbVRyYW5zaXRpb24oKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IG9sZFByb2plY3Rpb24gPSB0aGlzLnByb2plY3Rpb24ubmFtZTtcbiAgICAgICAgdGhpcy5tZXJjYXRvckZyb21UcmFuc2l0aW9uID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5wcm9qZWN0aW9uT3B0aW9ucyA9IHtuYW1lOiAnbWVyY2F0b3InfTtcbiAgICAgICAgdGhpcy5wcm9qZWN0aW9uID0gZ2V0UHJvamVjdGlvbih7bmFtZTogJ21lcmNhdG9yJ30pO1xuICAgICAgICBjb25zdCBwcm9qZWN0aW9uSGFzQ2hhbmdlZCA9IG9sZFByb2plY3Rpb24gIT09IHRoaXMucHJvamVjdGlvbi5uYW1lO1xuICAgICAgICBpZiAocHJvamVjdGlvbkhhc0NoYW5nZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX2NhbGNNYXRyaWNlcygpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwcm9qZWN0aW9uSGFzQ2hhbmdlZDtcbiAgICB9XG5cbiAgICBnZXQgbWluWm9vbSgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fbWluWm9vbTsgfVxuICAgIHNldCBtaW5ab29tKHpvb206IG51bWJlcikge1xuICAgICAgICBpZiAodGhpcy5fbWluWm9vbSA9PT0gem9vbSkgcmV0dXJuO1xuICAgICAgICB0aGlzLl9taW5ab29tID0gem9vbTtcbiAgICAgICAgdGhpcy56b29tID0gTWF0aC5tYXgodGhpcy56b29tLCB6b29tKTtcbiAgICB9XG5cbiAgICBnZXQgbWF4Wm9vbSgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fbWF4Wm9vbTsgfVxuICAgIHNldCBtYXhab29tKHpvb206IG51bWJlcikge1xuICAgICAgICBpZiAodGhpcy5fbWF4Wm9vbSA9PT0gem9vbSkgcmV0dXJuO1xuICAgICAgICB0aGlzLl9tYXhab29tID0gem9vbTtcbiAgICAgICAgdGhpcy56b29tID0gTWF0aC5taW4odGhpcy56b29tLCB6b29tKTtcbiAgICB9XG5cbiAgICBnZXQgbWluUGl0Y2goKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX21pblBpdGNoOyB9XG4gICAgc2V0IG1pblBpdGNoKHBpdGNoOiBudW1iZXIpIHtcbiAgICAgICAgaWYgKHRoaXMuX21pblBpdGNoID09PSBwaXRjaCkgcmV0dXJuO1xuICAgICAgICB0aGlzLl9taW5QaXRjaCA9IHBpdGNoO1xuICAgICAgICB0aGlzLnBpdGNoID0gTWF0aC5tYXgodGhpcy5waXRjaCwgcGl0Y2gpO1xuICAgIH1cblxuICAgIGdldCBtYXhQaXRjaCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fbWF4UGl0Y2g7IH1cbiAgICBzZXQgbWF4UGl0Y2gocGl0Y2g6IG51bWJlcikge1xuICAgICAgICBpZiAodGhpcy5fbWF4UGl0Y2ggPT09IHBpdGNoKSByZXR1cm47XG4gICAgICAgIHRoaXMuX21heFBpdGNoID0gcGl0Y2g7XG4gICAgICAgIHRoaXMucGl0Y2ggPSBNYXRoLm1pbih0aGlzLnBpdGNoLCBwaXRjaCk7XG4gICAgfVxuXG4gICAgZ2V0IHJlbmRlcldvcmxkQ29waWVzKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fcmVuZGVyV29ybGRDb3BpZXMgJiYgdGhpcy5wcm9qZWN0aW9uLnN1cHBvcnRzV29ybGRDb3BpZXMgPT09IHRydWU7XG4gICAgfVxuICAgIHNldCByZW5kZXJXb3JsZENvcGllcyhyZW5kZXJXb3JsZENvcGllcz86ID9ib29sZWFuKSB7XG4gICAgICAgIGlmIChyZW5kZXJXb3JsZENvcGllcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZW5kZXJXb3JsZENvcGllcyA9IHRydWU7XG4gICAgICAgIH0gZWxzZSBpZiAocmVuZGVyV29ybGRDb3BpZXMgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJlbmRlcldvcmxkQ29waWVzID0gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9yZW5kZXJXb3JsZENvcGllcyA9IHJlbmRlcldvcmxkQ29waWVzO1xuICAgIH1cblxuICAgIGdldCB3b3JsZFNpemUoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGlsZVNpemUgKiB0aGlzLnNjYWxlO1xuICAgIH1cblxuICAgIC8vIFRoaXMgZ2V0dGVyIHJldHVybnMgYW4gaW5jb3JyZWN0IHZhbHVlLlxuICAgIC8vIEl0IHNob3VsZCBldmVudHVhbGx5IGJlIHJlbW92ZWQgYW5kIGNhbWVyYVdvcmxkU2l6ZSBiZSB1c2VkIGluc3RlYWQuXG4gICAgLy8gU2VlIGZyZWVfY2FtZXJhLmdldERpc3RhbmNlVG9FbGV2YXRpb24gZm9yIHRoZSByYXRpb25hbGUuXG4gICAgZ2V0IGNhbWVyYVdvcmxkU2l6ZUZvckZvZygpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBkaXN0YW5jZSA9IE1hdGgubWF4KHRoaXMuX2NhbWVyYS5nZXREaXN0YW5jZVRvRWxldmF0aW9uKHRoaXMuX2F2ZXJhZ2VFbGV2YXRpb24pLCBOdW1iZXIuRVBTSUxPTik7XG4gICAgICAgIHJldHVybiB0aGlzLl93b3JsZFNpemVGcm9tWm9vbSh0aGlzLl96b29tRnJvbU1lcmNhdG9yWihkaXN0YW5jZSkpO1xuICAgIH1cblxuICAgIGdldCBjYW1lcmFXb3JsZFNpemUoKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgZGlzdGFuY2UgPSBNYXRoLm1heCh0aGlzLl9jYW1lcmEuZ2V0RGlzdGFuY2VUb0VsZXZhdGlvbih0aGlzLl9hdmVyYWdlRWxldmF0aW9uLCB0cnVlKSwgTnVtYmVyLkVQU0lMT04pO1xuICAgICAgICByZXR1cm4gdGhpcy5fd29ybGRTaXplRnJvbVpvb20odGhpcy5fem9vbUZyb21NZXJjYXRvclooZGlzdGFuY2UpKTtcbiAgICB9XG5cbiAgICAvLyBgcGl4ZWxzUGVyTWV0ZXJgIGlzIHVzZWQgdG8gZGVzY3JpYmUgcmVsYXRpb24gYmV0d2VlbiByZWFsIHdvcmxkIGFuZCBwaXhlbCBkaXN0YW5jZXMuXG4gICAgLy8gSW4gbWVyY2F0b3IgcHJvamVjdGlvbiBpdCBpcyBkZXBlbmRhbnQgb24gbGF0aXR1ZGUgdmFsdWUgbWVhbmluZyB0aGF0IG9uZSBtZXRlciBjb3ZlcnNcbiAgICAvLyBsZXNzIHBpeGVscyBhdCB0aGUgZXF1YXRvciB0aGFuIG5lYXIgcG9sYXIgcmVnaW9ucy4gR2xvYmUgcHJvamVjdGlvbiBpbiBvdGhlciBoYW5kIHVzZXNcbiAgICAvLyBmaXhlZCByYXRpbyBldmVyeXdoZXJlLlxuXG4gICAgZ2V0IHBpeGVsc1Blck1ldGVyKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLnByb2plY3Rpb24ucGl4ZWxzUGVyTWV0ZXIodGhpcy5jZW50ZXIubGF0LCB0aGlzLndvcmxkU2l6ZSk7XG4gICAgfVxuXG4gICAgZ2V0IGNhbWVyYVBpeGVsc1Blck1ldGVyKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiBtZXJjYXRvclpmcm9tQWx0aXR1ZGUodGhpcy5jZW50ZXIubGF0LCB0aGlzLmNhbWVyYVdvcmxkU2l6ZUZvckZvZyk7XG4gICAgfVxuXG4gICAgZ2V0IGNlbnRlck9mZnNldCgpOiBQb2ludCB7XG4gICAgICAgIHJldHVybiB0aGlzLmNlbnRlclBvaW50Ll9zdWIodGhpcy5zaXplLl9kaXYoMikpO1xuICAgIH1cblxuICAgIGdldCBzaXplKCk6IFBvaW50IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQb2ludCh0aGlzLndpZHRoLCB0aGlzLmhlaWdodCk7XG4gICAgfVxuXG4gICAgZ2V0IGJlYXJpbmcoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHdyYXAodGhpcy5yb3RhdGlvbiwgLTE4MCwgMTgwKTtcbiAgICB9XG5cbiAgICBzZXQgYmVhcmluZyhiZWFyaW5nOiBudW1iZXIpIHtcbiAgICAgICAgdGhpcy5yb3RhdGlvbiA9IGJlYXJpbmc7XG4gICAgfVxuXG4gICAgZ2V0IHJvdGF0aW9uKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiAtdGhpcy5hbmdsZSAvIE1hdGguUEkgKiAxODA7XG4gICAgfVxuXG4gICAgc2V0IHJvdGF0aW9uKHJvdGF0aW9uOiBudW1iZXIpIHtcbiAgICAgICAgY29uc3QgYiA9IC1yb3RhdGlvbiAqIE1hdGguUEkgLyAxODA7XG4gICAgICAgIGlmICh0aGlzLmFuZ2xlID09PSBiKSByZXR1cm47XG4gICAgICAgIHRoaXMuX3VubW9kaWZpZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5hbmdsZSA9IGI7XG4gICAgICAgIHRoaXMuX2NhbGNNYXRyaWNlcygpO1xuXG4gICAgICAgIC8vIDJ4MiBtYXRyaXggZm9yIHJvdGF0aW5nIHBvaW50c1xuICAgICAgICB0aGlzLnJvdGF0aW9uTWF0cml4ID0gbWF0Mi5jcmVhdGUoKTtcbiAgICAgICAgbWF0Mi5yb3RhdGUodGhpcy5yb3RhdGlvbk1hdHJpeCwgdGhpcy5yb3RhdGlvbk1hdHJpeCwgdGhpcy5hbmdsZSk7XG4gICAgfVxuXG4gICAgZ2V0IHBpdGNoKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLl9waXRjaCAvIE1hdGguUEkgKiAxODA7XG4gICAgfVxuICAgIHNldCBwaXRjaChwaXRjaDogbnVtYmVyKSB7XG4gICAgICAgIGNvbnN0IHAgPSBjbGFtcChwaXRjaCwgdGhpcy5taW5QaXRjaCwgdGhpcy5tYXhQaXRjaCkgLyAxODAgKiBNYXRoLlBJO1xuICAgICAgICBpZiAodGhpcy5fcGl0Y2ggPT09IHApIHJldHVybjtcbiAgICAgICAgdGhpcy5fdW5tb2RpZmllZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9waXRjaCA9IHA7XG4gICAgICAgIHRoaXMuX2NhbGNNYXRyaWNlcygpO1xuICAgIH1cblxuICAgIGdldCBhc3BlY3QoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lkdGggLyB0aGlzLmhlaWdodDtcbiAgICB9XG5cbiAgICBnZXQgZm92KCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mb3YgLyBNYXRoLlBJICogMTgwO1xuICAgIH1cblxuICAgIGdldCBmb3ZYKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mb3Y7XG4gICAgfVxuXG4gICAgZ2V0IGZvdlkoKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgZm9jYWxMZW5ndGggPSAxLjAgLyBNYXRoLnRhbih0aGlzLmZvdlggKiAwLjUpO1xuICAgICAgICByZXR1cm4gMiAqIE1hdGguYXRhbigoMS4wIC8gdGhpcy5hc3BlY3QpIC8gZm9jYWxMZW5ndGgpO1xuICAgIH1cblxuICAgIHNldCBmb3YoZm92OiBudW1iZXIpIHtcbiAgICAgICAgZm92ID0gTWF0aC5tYXgoMC4wMSwgTWF0aC5taW4oNjAsIGZvdikpO1xuICAgICAgICBpZiAodGhpcy5fZm92ID09PSBmb3YpIHJldHVybjtcbiAgICAgICAgdGhpcy5fdW5tb2RpZmllZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9mb3YgPSBkZWdUb1JhZChmb3YpO1xuICAgICAgICB0aGlzLl9jYWxjTWF0cmljZXMoKTtcbiAgICB9XG5cbiAgICBnZXQgYXZlcmFnZUVsZXZhdGlvbigpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5fYXZlcmFnZUVsZXZhdGlvbjtcbiAgICB9XG4gICAgc2V0IGF2ZXJhZ2VFbGV2YXRpb24oYXZlcmFnZUVsZXZhdGlvbjogbnVtYmVyKSB7XG4gICAgICAgIHRoaXMuX2F2ZXJhZ2VFbGV2YXRpb24gPSBhdmVyYWdlRWxldmF0aW9uO1xuICAgICAgICB0aGlzLl9jYWxjRm9nTWF0cmljZXMoKTtcbiAgICAgICAgdGhpcy5fZGlzdGFuY2VUaWxlRGF0YUNhY2hlID0ge307XG4gICAgfVxuXG4gICAgZ2V0IHpvb20oKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3pvb207IH1cbiAgICBzZXQgem9vbSh6b29tOiBudW1iZXIpIHtcbiAgICAgICAgY29uc3QgeiA9IE1hdGgubWluKE1hdGgubWF4KHpvb20sIHRoaXMubWluWm9vbSksIHRoaXMubWF4Wm9vbSk7XG4gICAgICAgIGlmICh0aGlzLl96b29tID09PSB6KSByZXR1cm47XG4gICAgICAgIHRoaXMuX3VubW9kaWZpZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fc2V0Wm9vbSh6KTtcbiAgICAgICAgdGhpcy5fdXBkYXRlU2VhTGV2ZWxab29tKCk7XG4gICAgICAgIHRoaXMuX2NvbnN0cmFpbigpO1xuICAgICAgICB0aGlzLl9jYWxjTWF0cmljZXMoKTtcbiAgICB9XG4gICAgX3NldFpvb20oejogbnVtYmVyKSB7XG4gICAgICAgIHRoaXMuX3pvb20gPSB6O1xuICAgICAgICB0aGlzLnNjYWxlID0gdGhpcy56b29tU2NhbGUoeik7XG4gICAgICAgIHRoaXMudGlsZVpvb20gPSBNYXRoLmZsb29yKHopO1xuICAgICAgICB0aGlzLnpvb21GcmFjdGlvbiA9IHogLSB0aGlzLnRpbGVab29tO1xuICAgIH1cblxuICAgIF91cGRhdGVDYW1lcmFPblRlcnJhaW4oKSB7XG4gICAgICAgIGlmICghdGhpcy5fZWxldmF0aW9uIHx8ICF0aGlzLl9lbGV2YXRpb24uaXNEYXRhQXZhaWxhYmxlQXRQb2ludCh0aGlzLmxvY2F0aW9uQ29vcmRpbmF0ZSh0aGlzLmNlbnRlcikpKSB7XG4gICAgICAgICAgICAvLyBFbGV2YXRpb24gZGF0YSBub3QgbG9hZGVkIHlldCwgcmVzZXRcbiAgICAgICAgICAgIHRoaXMuX2NlbnRlckFsdGl0dWRlID0gMDtcbiAgICAgICAgICAgIHRoaXMuX3NlYUxldmVsWm9vbSA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLl9jZW50ZXJBbHRpdHVkZVZhbGlkRm9yRXhhZ2dlcmF0aW9uID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGVsZXZhdGlvbjogRWxldmF0aW9uID0gdGhpcy5fZWxldmF0aW9uO1xuICAgICAgICB0aGlzLl9jZW50ZXJBbHRpdHVkZSA9IGVsZXZhdGlvbi5nZXRBdFBvaW50T3JaZXJvKHRoaXMubG9jYXRpb25Db29yZGluYXRlKHRoaXMuY2VudGVyKSk7XG4gICAgICAgIHRoaXMuX2NlbnRlckFsdGl0dWRlVmFsaWRGb3JFeGFnZ2VyYXRpb24gPSBlbGV2YXRpb24uZXhhZ2dlcmF0aW9uKCk7XG4gICAgICAgIHRoaXMuX3VwZGF0ZVNlYUxldmVsWm9vbSgpO1xuICAgIH1cblxuICAgIF91cGRhdGVTZWFMZXZlbFpvb20oKSB7XG4gICAgICAgIGlmICh0aGlzLl9jZW50ZXJBbHRpdHVkZVZhbGlkRm9yRXhhZ2dlcmF0aW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBoZWlnaHQgPSB0aGlzLmNhbWVyYVRvQ2VudGVyRGlzdGFuY2U7XG4gICAgICAgIGNvbnN0IHRlcnJhaW5FbGV2YXRpb24gPSB0aGlzLnBpeGVsc1Blck1ldGVyICogdGhpcy5fY2VudGVyQWx0aXR1ZGU7XG4gICAgICAgIGNvbnN0IG1lcmNhdG9yWiA9ICh0ZXJyYWluRWxldmF0aW9uICsgaGVpZ2h0KSAvIHRoaXMud29ybGRTaXplO1xuXG4gICAgICAgIC8vIE1TTCAoTWVhbiBTZWEgTGV2ZWwpIHpvb20gZGVzY3JpYmVzIHRoZSBkaXN0YW5jZSBvZiB0aGUgY2FtZXJhIHRvIHRoZSBzZWEgbGV2ZWwgKGFsdGl0dWRlKS5cbiAgICAgICAgLy8gSXQgaXMgdXNlZCBvbmx5IGZvciBtYW5pcHVsYXRpbmcgdGhlIGNhbWVyYSBsb2NhdGlvbi4gVGhlIHN0YW5kYXJkIHpvb20gKHRoaXMuX3pvb20pXG4gICAgICAgIC8vIGRlZmluZXMgdGhlIGNhbWVyYSBkaXN0YW5jZSB0byB0aGUgdGVycmFpbiAoaGVpZ2h0KS4gSXRzIGJlaGF2aW9yIGFuZCBjb25jZXB0dWFsXG4gICAgICAgIC8vIG1lYW5pbmcgaW4gZGV0ZXJtaW5pbmcgd2hpY2ggdGlsZXMgdG8gc3RyZWFtIGlzIHNhbWUgd2l0aCBvciB3aXRob3V0IHRoZSB0ZXJyYWluLlxuICAgICAgICB0aGlzLl9zZWFMZXZlbFpvb20gPSB0aGlzLl96b29tRnJvbU1lcmNhdG9yWihtZXJjYXRvclopO1xuICAgIH1cblxuICAgIHNhbXBsZUF2ZXJhZ2VFbGV2YXRpb24oKTogbnVtYmVyIHtcbiAgICAgICAgaWYgKCF0aGlzLl9lbGV2YXRpb24pIHJldHVybiAwO1xuICAgICAgICBjb25zdCBlbGV2YXRpb246IEVsZXZhdGlvbiA9IHRoaXMuX2VsZXZhdGlvbjtcblxuICAgICAgICBjb25zdCBlbGV2YXRpb25TYW1wbGVQb2ludHMgPSBbXG4gICAgICAgICAgICBbMC41LCAwLjJdLFxuICAgICAgICAgICAgWzAuMywgMC41XSxcbiAgICAgICAgICAgIFswLjUsIDAuNV0sXG4gICAgICAgICAgICBbMC43LCAwLjVdLFxuICAgICAgICAgICAgWzAuNSwgMC44XVxuICAgICAgICBdO1xuXG4gICAgICAgIGNvbnN0IGhvcml6b24gPSB0aGlzLmhvcml6b25MaW5lRnJvbVRvcCgpO1xuXG4gICAgICAgIGxldCBlbGV2YXRpb25TdW0gPSAwLjA7XG4gICAgICAgIGxldCB3ZWlnaHRTdW0gPSAwLjA7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZWxldmF0aW9uU2FtcGxlUG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBwdCA9IG5ldyBQb2ludChcbiAgICAgICAgICAgICAgICBlbGV2YXRpb25TYW1wbGVQb2ludHNbaV1bMF0gKiB0aGlzLndpZHRoLFxuICAgICAgICAgICAgICAgIGhvcml6b24gKyBlbGV2YXRpb25TYW1wbGVQb2ludHNbaV1bMV0gKiAodGhpcy5oZWlnaHQgLSBob3Jpem9uKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IGhpdCA9IGVsZXZhdGlvbi5wb2ludENvb3JkaW5hdGUocHQpO1xuICAgICAgICAgICAgaWYgKCFoaXQpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICBjb25zdCBkaXN0YW5jZVRvSGl0ID0gTWF0aC5oeXBvdChoaXRbMF0gLSB0aGlzLl9jYW1lcmEucG9zaXRpb25bMF0sIGhpdFsxXSAtIHRoaXMuX2NhbWVyYS5wb3NpdGlvblsxXSk7XG4gICAgICAgICAgICBjb25zdCB3ZWlnaHQgPSAxIC8gZGlzdGFuY2VUb0hpdDtcbiAgICAgICAgICAgIGVsZXZhdGlvblN1bSArPSBoaXRbM10gKiB3ZWlnaHQ7XG4gICAgICAgICAgICB3ZWlnaHRTdW0gKz0gd2VpZ2h0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHdlaWdodFN1bSA9PT0gMCkgcmV0dXJuIE5hTjtcbiAgICAgICAgcmV0dXJuIGVsZXZhdGlvblN1bSAvIHdlaWdodFN1bTtcbiAgICB9XG5cbiAgICBnZXQgY2VudGVyKCk6IExuZ0xhdCB7IHJldHVybiB0aGlzLl9jZW50ZXI7IH1cbiAgICBzZXQgY2VudGVyKGNlbnRlcjogTG5nTGF0KSB7XG4gICAgICAgIGlmIChjZW50ZXIubGF0ID09PSB0aGlzLl9jZW50ZXIubGF0ICYmIGNlbnRlci5sbmcgPT09IHRoaXMuX2NlbnRlci5sbmcpIHJldHVybjtcblxuICAgICAgICB0aGlzLl91bm1vZGlmaWVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX2NlbnRlciA9IGNlbnRlcjtcbiAgICAgICAgaWYgKHRoaXMuX3RlcnJhaW5FbmFibGVkKCkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmNhbWVyYUVsZXZhdGlvblJlZmVyZW5jZSA9PT0gXCJncm91bmRcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUNhbWVyYU9uVGVycmFpbigpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl91cGRhdGVab29tRnJvbUVsZXZhdGlvbigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2NvbnN0cmFpbigpO1xuICAgICAgICB0aGlzLl9jYWxjTWF0cmljZXMoKTtcbiAgICB9XG5cbiAgICBfdXBkYXRlWm9vbUZyb21FbGV2YXRpb24oKSB7XG4gICAgICAgIGlmICh0aGlzLl9zZWFMZXZlbFpvb20gPT0gbnVsbCB8fCAhdGhpcy5fZWxldmF0aW9uKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIC8vIENvbXB1dGUgem9vbSBsZXZlbCBmcm9tIHRoZSBoZWlnaHQgb2YgdGhlIGNhbWVyYSByZWxhdGl2ZSB0byB0aGUgdGVycmFpblxuICAgICAgICBjb25zdCBzZWFMZXZlbFpvb206IG51bWJlciA9IHRoaXMuX3NlYUxldmVsWm9vbTtcbiAgICAgICAgY29uc3QgZWxldmF0aW9uQXRDZW50ZXIgPSB0aGlzLl9lbGV2YXRpb24uZ2V0QXRQb2ludE9yWmVybyh0aGlzLmxvY2F0aW9uQ29vcmRpbmF0ZSh0aGlzLmNlbnRlcikpO1xuICAgICAgICBjb25zdCBtZXJjYXRvckVsZXZhdGlvbiA9IHRoaXMucGl4ZWxzUGVyTWV0ZXIgLyB0aGlzLndvcmxkU2l6ZSAqIGVsZXZhdGlvbkF0Q2VudGVyO1xuICAgICAgICBjb25zdCBhbHRpdHVkZSAgPSB0aGlzLl9tZXJjYXRvclpmcm9tWm9vbShzZWFMZXZlbFpvb20pO1xuICAgICAgICBjb25zdCBtaW5IZWlnaHQgPSB0aGlzLl9tZXJjYXRvclpmcm9tWm9vbSh0aGlzLl9tYXhab29tKTtcbiAgICAgICAgY29uc3QgaGVpZ2h0ID0gTWF0aC5tYXgoYWx0aXR1ZGUgLSBtZXJjYXRvckVsZXZhdGlvbiwgbWluSGVpZ2h0KTtcblxuICAgICAgICB0aGlzLl9zZXRab29tKHRoaXMuX3pvb21Gcm9tTWVyY2F0b3JaKGhlaWdodCkpO1xuICAgIH1cblxuICAgIGdldCBwYWRkaW5nKCk6IFBhZGRpbmdPcHRpb25zIHsgcmV0dXJuIHRoaXMuX2VkZ2VJbnNldHMudG9KU09OKCk7IH1cbiAgICBzZXQgcGFkZGluZyhwYWRkaW5nOiBQYWRkaW5nT3B0aW9ucykge1xuICAgICAgICBpZiAodGhpcy5fZWRnZUluc2V0cy5lcXVhbHMocGFkZGluZykpIHJldHVybjtcbiAgICAgICAgdGhpcy5fdW5tb2RpZmllZCA9IGZhbHNlO1xuICAgICAgICAvL1VwZGF0ZSBlZGdlLWluc2V0cyBpbnBsYWNlXG4gICAgICAgIHRoaXMuX2VkZ2VJbnNldHMuaW50ZXJwb2xhdGUodGhpcy5fZWRnZUluc2V0cywgcGFkZGluZywgMSk7XG4gICAgICAgIHRoaXMuX2NhbGNNYXRyaWNlcygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbXB1dGVzIGEgem9vbSB2YWx1ZSByZWxhdGl2ZSB0byBhIG1hcCBwbGFuZSB0aGF0IGdvZXMgdGhyb3VnaCB0aGUgcHJvdmlkZWQgbWVyY2F0b3IgcG9zaXRpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge01lcmNhdG9yQ29vcmRpbmF0ZX0gcG9zaXRpb24gQSBwb3NpdGlvbiBkZWZpbmluZyB0aGUgYWx0aXR1ZGUgb2YgdGhlIHRoZSBtYXAgcGxhbmUuXG4gICAgICogQHJldHVybnMge251bWJlcn0gVGhlIHpvb20gdmFsdWUuXG4gICAgICovXG4gICAgY29tcHV0ZVpvb21SZWxhdGl2ZVRvKHBvc2l0aW9uOiBNZXJjYXRvckNvb3JkaW5hdGUpOiBudW1iZXIge1xuICAgICAgICAvLyBGaW5kIG1hcCBjZW50ZXIgcG9zaXRpb24gb24gdGhlIHRhcmdldCBwbGFuZSBieSBjYXN0aW5nIGEgcmF5IGZyb20gc2NyZWVuIGNlbnRlciB0b3dhcmRzIHRoZSBwbGFuZS5cbiAgICAgICAgLy8gRGlyZWN0IGRpc3RhbmNlIHRvIHRoZSB0YXJnZXQgcG9zaXRpb24gaXMgdXNlZCBpZiB0aGUgdGFyZ2V0IHBvc2l0aW9uIGlzIGFib3ZlIGNhbWVyYSBwb3NpdGlvbi5cbiAgICAgICAgY29uc3QgY2VudGVyT25UYXJnZXRBbHRpdHVkZSA9IHRoaXMucmF5SW50ZXJzZWN0aW9uQ29vcmRpbmF0ZSh0aGlzLnBvaW50UmF5SW50ZXJzZWN0aW9uKHRoaXMuY2VudGVyUG9pbnQsIHBvc2l0aW9uLnRvQWx0aXR1ZGUoKSkpO1xuXG4gICAgICAgIGxldCB0YXJnZXRQb3NpdGlvbjogP1ZlYzM7XG4gICAgICAgIGlmIChwb3NpdGlvbi56IDwgdGhpcy5fY2FtZXJhLnBvc2l0aW9uWzJdKSB7XG4gICAgICAgICAgICB0YXJnZXRQb3NpdGlvbiA9IFtjZW50ZXJPblRhcmdldEFsdGl0dWRlLngsIGNlbnRlck9uVGFyZ2V0QWx0aXR1ZGUueSwgY2VudGVyT25UYXJnZXRBbHRpdHVkZS56XTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRhcmdldFBvc2l0aW9uID0gW3Bvc2l0aW9uLngsIHBvc2l0aW9uLnksIHBvc2l0aW9uLnpdO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZGlzdFRvVGFyZ2V0ID0gdmVjMy5sZW5ndGgodmVjMy5zdWIoW10sIHRoaXMuX2NhbWVyYS5wb3NpdGlvbiwgdGFyZ2V0UG9zaXRpb24pKTtcbiAgICAgICAgcmV0dXJuIGNsYW1wKHRoaXMuX3pvb21Gcm9tTWVyY2F0b3JaKGRpc3RUb1RhcmdldCksIHRoaXMuX21pblpvb20sIHRoaXMuX21heFpvb20pO1xuICAgIH1cblxuICAgIHNldEZyZWVDYW1lcmFPcHRpb25zKG9wdGlvbnM6IEZyZWVDYW1lcmFPcHRpb25zKSB7XG4gICAgICAgIGlmICghdGhpcy5oZWlnaHQpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgaWYgKCFvcHRpb25zLnBvc2l0aW9uICYmICFvcHRpb25zLm9yaWVudGF0aW9uKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIC8vIENhbWVyYSBzdGF0ZSBtdXN0IGJlIHVwLXRvLWRhdGUgYmVmb3JlIGFjY2Vzc2luZyBpdHMgZ2V0dGVyc1xuICAgICAgICB0aGlzLl91cGRhdGVDYW1lcmFTdGF0ZSgpO1xuXG4gICAgICAgIGxldCBjaGFuZ2VkID0gZmFsc2U7XG4gICAgICAgIGlmIChvcHRpb25zLm9yaWVudGF0aW9uICYmICFxdWF0LmV4YWN0RXF1YWxzKG9wdGlvbnMub3JpZW50YXRpb24sIHRoaXMuX2NhbWVyYS5vcmllbnRhdGlvbikpIHtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbaW5jb21wYXRpYmxlLWNhbGxdIC0gRmxvdyBjYW4ndCBpbmZlciB0aGF0IG9yaWVudGF0aW9uIGlzIG5vdCBudWxsXG4gICAgICAgICAgICBjaGFuZ2VkID0gdGhpcy5fc2V0Q2FtZXJhT3JpZW50YXRpb24ob3B0aW9ucy5vcmllbnRhdGlvbik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAob3B0aW9ucy5wb3NpdGlvbikge1xuICAgICAgICAgICAgY29uc3QgbmV3UG9zaXRpb24gPSBbb3B0aW9ucy5wb3NpdGlvbi54LCBvcHRpb25zLnBvc2l0aW9uLnksIG9wdGlvbnMucG9zaXRpb24uel07XG4gICAgICAgICAgICBpZiAoIXZlYzMuZXhhY3RFcXVhbHMobmV3UG9zaXRpb24sIHRoaXMuX2NhbWVyYS5wb3NpdGlvbikpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zZXRDYW1lcmFQb3NpdGlvbihuZXdQb3NpdGlvbik7XG4gICAgICAgICAgICAgICAgY2hhbmdlZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY2hhbmdlZCkge1xuICAgICAgICAgICAgdGhpcy5fdXBkYXRlU3RhdGVGcm9tQ2FtZXJhKCk7XG4gICAgICAgICAgICB0aGlzLnJlY2VudGVyT25UZXJyYWluKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRGcmVlQ2FtZXJhT3B0aW9ucygpOiBGcmVlQ2FtZXJhT3B0aW9ucyB7XG4gICAgICAgIHRoaXMuX3VwZGF0ZUNhbWVyYVN0YXRlKCk7XG4gICAgICAgIGNvbnN0IHBvcyA9IHRoaXMuX2NhbWVyYS5wb3NpdGlvbjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG5ldyBGcmVlQ2FtZXJhT3B0aW9ucygpO1xuICAgICAgICBvcHRpb25zLnBvc2l0aW9uID0gbmV3IE1lcmNhdG9yQ29vcmRpbmF0ZShwb3NbMF0sIHBvc1sxXSwgcG9zWzJdKTtcbiAgICAgICAgb3B0aW9ucy5vcmllbnRhdGlvbiA9IHRoaXMuX2NhbWVyYS5vcmllbnRhdGlvbjtcbiAgICAgICAgb3B0aW9ucy5fZWxldmF0aW9uID0gdGhpcy5lbGV2YXRpb247XG4gICAgICAgIG9wdGlvbnMuX3JlbmRlcldvcmxkQ29waWVzID0gdGhpcy5yZW5kZXJXb3JsZENvcGllcztcblxuICAgICAgICByZXR1cm4gb3B0aW9ucztcbiAgICB9XG5cbiAgICBfc2V0Q2FtZXJhT3JpZW50YXRpb24ob3JpZW50YXRpb246IFF1YXQpOiBib29sZWFuIHtcbiAgICAgICAgLy8gemVyby1sZW5ndGggcXVhdGVybmlvbnMgYXJlIG5vdCB2YWxpZFxuICAgICAgICBpZiAoIXF1YXQubGVuZ3RoKG9yaWVudGF0aW9uKSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcblxuICAgICAgICBxdWF0Lm5vcm1hbGl6ZShvcmllbnRhdGlvbiwgb3JpZW50YXRpb24pO1xuXG4gICAgICAgIC8vIFRoZSBuZXcgb3JpZW50YXRpb24gbXVzdCBiZSBzYW5pdGl6ZWQgYnkgbWFraW5nIHN1cmUgaXQgY2FuIGJlIHJlcHJlc2VudGVkXG4gICAgICAgIC8vIHdpdGggYSBwaXRjaCBhbmQgYmVhcmluZy4gUm9sbC1jb21wb25lbnQgbXVzdCBiZSByZW1vdmVkIGFuZCB0aGUgY2FtZXJhIGNhbid0IGJlIHVwc2lkZSBkb3duXG4gICAgICAgIGNvbnN0IGZvcndhcmQgPSB2ZWMzLnRyYW5zZm9ybVF1YXQoW10sIFswLCAwLCAtMV0sIG9yaWVudGF0aW9uKTtcbiAgICAgICAgY29uc3QgdXAgPSB2ZWMzLnRyYW5zZm9ybVF1YXQoW10sIFswLCAtMSwgMF0sIG9yaWVudGF0aW9uKTtcblxuICAgICAgICBpZiAodXBbMl0gPCAwLjApXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgY29uc3QgdXBkYXRlZE9yaWVudGF0aW9uID0gb3JpZW50YXRpb25Gcm9tRnJhbWUoZm9yd2FyZCwgdXApO1xuICAgICAgICBpZiAoIXVwZGF0ZWRPcmllbnRhdGlvbilcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcblxuICAgICAgICB0aGlzLl9jYW1lcmEub3JpZW50YXRpb24gPSB1cGRhdGVkT3JpZW50YXRpb247XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIF9zZXRDYW1lcmFQb3NpdGlvbihwb3NpdGlvbjogVmVjMykge1xuICAgICAgICAvLyBBbHRpdHVkZSBtdXN0IGJlIGNsYW1wZWQgdG8gcmVzcGVjdCBtaW4gYW5kIG1heCB6b29tXG4gICAgICAgIGNvbnN0IG1pbldvcmxkU2l6ZSA9IHRoaXMuem9vbVNjYWxlKHRoaXMubWluWm9vbSkgKiB0aGlzLnRpbGVTaXplO1xuICAgICAgICBjb25zdCBtYXhXb3JsZFNpemUgPSB0aGlzLnpvb21TY2FsZSh0aGlzLm1heFpvb20pICogdGhpcy50aWxlU2l6ZTtcbiAgICAgICAgY29uc3QgZGlzdFRvQ2VudGVyID0gdGhpcy5jYW1lcmFUb0NlbnRlckRpc3RhbmNlO1xuXG4gICAgICAgIHBvc2l0aW9uWzJdID0gY2xhbXAocG9zaXRpb25bMl0sIGRpc3RUb0NlbnRlciAvIG1heFdvcmxkU2l6ZSwgZGlzdFRvQ2VudGVyIC8gbWluV29ybGRTaXplKTtcbiAgICAgICAgdGhpcy5fY2FtZXJhLnBvc2l0aW9uID0gcG9zaXRpb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGNlbnRlciBvZiB0aGUgc2NyZWVuIGluIHBpeGVscyB3aXRoIHRoZSB0b3AtbGVmdCBjb3JuZXIgYmVpbmcgKDAsMClcbiAgICAgKiBhbmQgK3kgYXhpcyBwb2ludGluZyBkb3dud2FyZHMuIFRoaXMgYWNjb3VudHMgZm9yIHBhZGRpbmcuXG4gICAgICpcbiAgICAgKiBAcmVhZG9ubHlcbiAgICAgKiBAdHlwZSB7UG9pbnR9XG4gICAgICogQG1lbWJlcm9mIFRyYW5zZm9ybVxuICAgICAqL1xuICAgIGdldCBjZW50ZXJQb2ludCgpOiBQb2ludCB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lZGdlSW5zZXRzLmdldENlbnRlcih0aGlzLndpZHRoLCB0aGlzLmhlaWdodCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdmVydGljYWwgaGFsZi1mb3YsIGFjY291bnRpbmcgZm9yIHBhZGRpbmcsIGluIHJhZGlhbnMuXG4gICAgICpcbiAgICAgKiBAcmVhZG9ubHlcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgZ2V0IGZvdkFib3ZlQ2VudGVyKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mb3YgKiAoMC41ICsgdGhpcy5jZW50ZXJPZmZzZXQueSAvIHRoaXMuaGVpZ2h0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHBhZGRpbmcgb3B0aW9ucyBhcmUgZXF1YWwuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1BhZGRpbmdPcHRpb25zfSBwYWRkaW5nIFRoZSBwYWRkaW5nIG9wdGlvbnMgdG8gY29tcGFyZS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgcGFkZGluZyBvcHRpb25zIGFyZSBlcXVhbC5cbiAgICAgKiBAbWVtYmVyb2YgVHJhbnNmb3JtXG4gICAgICovXG4gICAgaXNQYWRkaW5nRXF1YWwocGFkZGluZzogUGFkZGluZ09wdGlvbnMpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VkZ2VJbnNldHMuZXF1YWxzKHBhZGRpbmcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEhlbHBlciBtZXRob2QgdG8gdXBkYXRlIGVkZ2UtaW5zZXRzIGlucGxhY2UuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1BhZGRpbmdPcHRpb25zfSBzdGFydCBUaGUgaW5pdGlhbCBwYWRkaW5nIG9wdGlvbnMuXG4gICAgICogQHBhcmFtIHtQYWRkaW5nT3B0aW9uc30gdGFyZ2V0IFRoZSB0YXJnZXQgcGFkZGluZyBvcHRpb25zLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB0IFRoZSBpbnRlcnBvbGF0aW9uIHZhcmlhYmxlLlxuICAgICAqIEBtZW1iZXJvZiBUcmFuc2Zvcm1cbiAgICAgKi9cbiAgICBpbnRlcnBvbGF0ZVBhZGRpbmcoc3RhcnQ6IFBhZGRpbmdPcHRpb25zLCB0YXJnZXQ6IFBhZGRpbmdPcHRpb25zLCB0OiBudW1iZXIpIHtcbiAgICAgICAgdGhpcy5fdW5tb2RpZmllZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9lZGdlSW5zZXRzLmludGVycG9sYXRlKHN0YXJ0LCB0YXJnZXQsIHQpO1xuICAgICAgICB0aGlzLl9jb25zdHJhaW4oKTtcbiAgICAgICAgdGhpcy5fY2FsY01hdHJpY2VzKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBoaWdoZXN0IHpvb20gbGV2ZWwgdGhhdCBmdWxseSBpbmNsdWRlcyBhbGwgdGlsZXMgd2l0aGluIHRoZSB0cmFuc2Zvcm0ncyBib3VuZGFyaWVzLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIE9wdGlvbnMuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG9wdGlvbnMudGlsZVNpemUgVGlsZSBzaXplLCBleHByZXNzZWQgaW4gc2NyZWVuIHBpeGVscy5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IG9wdGlvbnMucm91bmRab29tIFRhcmdldCB6b29tIGxldmVsLiBJZiB0cnVlLCB0aGUgdmFsdWUgd2lsbCBiZSByb3VuZGVkIHRvIHRoZSBjbG9zZXN0IGludGVnZXIuIE90aGVyd2lzZSB0aGUgdmFsdWUgd2lsbCBiZSBmbG9vcmVkLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IEFuIGludGVnZXIgem9vbSBsZXZlbCBhdCB3aGljaCBhbGwgdGlsZXMgd2lsbCBiZSB2aXNpYmxlLlxuICAgICAqL1xuICAgIGNvdmVyaW5nWm9vbUxldmVsKG9wdGlvbnM6IHtyb3VuZFpvb20/OiBib29sZWFuLCB0aWxlU2l6ZTogbnVtYmVyfSk6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IHogPSAob3B0aW9ucy5yb3VuZFpvb20gPyBNYXRoLnJvdW5kIDogTWF0aC5mbG9vcikoXG4gICAgICAgICAgICB0aGlzLnpvb20gKyB0aGlzLnNjYWxlWm9vbSh0aGlzLnRpbGVTaXplIC8gb3B0aW9ucy50aWxlU2l6ZSlcbiAgICAgICAgKTtcbiAgICAgICAgLy8gQXQgbmVnYXRpdmUgem9vbSBsZXZlbHMgbG9hZCB0aWxlcyBmcm9tIHowIGJlY2F1c2UgbmVnYXRpdmUgdGlsZSB6b29tIGxldmVscyBkb24ndCBleGlzdC5cbiAgICAgICAgcmV0dXJuIE1hdGgubWF4KDAsIHopO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybiBhbnkgXCJ3cmFwcGVkXCIgY29waWVzIG9mIGEgZ2l2ZW4gdGlsZSBjb29yZGluYXRlIHRoYXQgYXJlIHZpc2libGVcbiAgICAgKiBpbiB0aGUgY3VycmVudCB2aWV3LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBnZXRWaXNpYmxlVW53cmFwcGVkQ29vcmRpbmF0ZXModGlsZUlEOiBDYW5vbmljYWxUaWxlSUQpOiBBcnJheTxVbndyYXBwZWRUaWxlSUQ+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gW25ldyBVbndyYXBwZWRUaWxlSUQoMCwgdGlsZUlEKV07XG4gICAgICAgIGlmICh0aGlzLnJlbmRlcldvcmxkQ29waWVzKSB7XG4gICAgICAgICAgICBjb25zdCB1dGwgPSB0aGlzLnBvaW50Q29vcmRpbmF0ZShuZXcgUG9pbnQoMCwgMCkpO1xuICAgICAgICAgICAgY29uc3QgdXRyID0gdGhpcy5wb2ludENvb3JkaW5hdGUobmV3IFBvaW50KHRoaXMud2lkdGgsIDApKTtcbiAgICAgICAgICAgIGNvbnN0IHVibCA9IHRoaXMucG9pbnRDb29yZGluYXRlKG5ldyBQb2ludCh0aGlzLndpZHRoLCB0aGlzLmhlaWdodCkpO1xuICAgICAgICAgICAgY29uc3QgdWJyID0gdGhpcy5wb2ludENvb3JkaW5hdGUobmV3IFBvaW50KDAsIHRoaXMuaGVpZ2h0KSk7XG4gICAgICAgICAgICBjb25zdCB3MCA9IE1hdGguZmxvb3IoTWF0aC5taW4odXRsLngsIHV0ci54LCB1YmwueCwgdWJyLngpKTtcbiAgICAgICAgICAgIGNvbnN0IHcxID0gTWF0aC5mbG9vcihNYXRoLm1heCh1dGwueCwgdXRyLngsIHVibC54LCB1YnIueCkpO1xuXG4gICAgICAgICAgICAvLyBBZGQgYW4gZXh0cmEgY29weSBvZiB0aGUgd29ybGQgb24gZWFjaCBzaWRlIHRvIHByb3Blcmx5IHJlbmRlciBJbWFnZVNvdXJjZXMgYW5kIENhbnZhc1NvdXJjZXMuXG4gICAgICAgICAgICAvLyBCb3RoIHNvdXJjZXMgZHJhdyBvdXRzaWRlIHRoZSB0aWxlIGJvdW5kYXJpZXMgb2YgdGhlIHRpbGUgdGhhdCBcImNvbnRhaW5zIHRoZW1cIiBzbyB3ZSBuZWVkXG4gICAgICAgICAgICAvLyB0byBhZGQgZXh0cmEgY29waWVzIG9uIGJvdGggc2lkZXMgaW4gY2FzZSBvZmZzY3JlZW4gdGlsZXMgbmVlZCB0byBkcmF3IGludG8gb24tc2NyZWVuIG9uZXMuXG4gICAgICAgICAgICBjb25zdCBleHRyYVdvcmxkQ29weSA9IDE7XG5cbiAgICAgICAgICAgIGZvciAobGV0IHcgPSB3MCAtIGV4dHJhV29ybGRDb3B5OyB3IDw9IHcxICsgZXh0cmFXb3JsZENvcHk7IHcrKykge1xuICAgICAgICAgICAgICAgIGlmICh3ID09PSAwKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaChuZXcgVW53cmFwcGVkVGlsZUlEKHcsIHRpbGVJRCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJuIGFsbCBjb29yZGluYXRlcyB0aGF0IGNvdWxkIGNvdmVyIHRoaXMgdHJhbnNmb3JtIGZvciBhIGNvdmVyaW5nXG4gICAgICogem9vbSBsZXZlbC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBvcHRpb25zLnRpbGVTaXplXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG9wdGlvbnMubWluem9vbVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBvcHRpb25zLm1heHpvb21cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IG9wdGlvbnMucm91bmRab29tXG4gICAgICogQHBhcmFtIHtib29sZWFufSBvcHRpb25zLnJlcGFyc2VPdmVyc2NhbGVkXG4gICAgICogQHJldHVybnMge0FycmF5PE92ZXJzY2FsZWRUaWxlSUQ+fSBPdmVyc2NhbGVkVGlsZUlEc1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgY292ZXJpbmdUaWxlcyhcbiAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgICAgdGlsZVNpemU6IG51bWJlcixcbiAgICAgICAgICAgIG1pbnpvb20/OiBudW1iZXIsXG4gICAgICAgICAgICBtYXh6b29tPzogbnVtYmVyLFxuICAgICAgICAgICAgcm91bmRab29tPzogYm9vbGVhbixcbiAgICAgICAgICAgIHJlcGFyc2VPdmVyc2NhbGVkPzogYm9vbGVhbixcbiAgICAgICAgICAgIHJlbmRlcldvcmxkQ29waWVzPzogYm9vbGVhbixcbiAgICAgICAgICAgIGlzVGVycmFpbkRFTT86IGJvb2xlYW5cbiAgICAgICAgfVxuICAgICk6IEFycmF5PE92ZXJzY2FsZWRUaWxlSUQ+IHtcbiAgICAgICAgbGV0IHogPSB0aGlzLmNvdmVyaW5nWm9vbUxldmVsKG9wdGlvbnMpO1xuICAgICAgICBjb25zdCBhY3R1YWxaID0gejtcblxuICAgICAgICBjb25zdCB1c2VFbGV2YXRpb25EYXRhID0gdGhpcy5lbGV2YXRpb24gJiYgIW9wdGlvbnMuaXNUZXJyYWluREVNO1xuICAgICAgICBjb25zdCBpc01lcmNhdG9yID0gdGhpcy5wcm9qZWN0aW9uLm5hbWUgPT09ICdtZXJjYXRvcic7XG5cbiAgICAgICAgaWYgKG9wdGlvbnMubWluem9vbSAhPT0gdW5kZWZpbmVkICYmIHogPCBvcHRpb25zLm1pbnpvb20pIHJldHVybiBbXTtcbiAgICAgICAgaWYgKG9wdGlvbnMubWF4em9vbSAhPT0gdW5kZWZpbmVkICYmIHogPiBvcHRpb25zLm1heHpvb20pIHogPSBvcHRpb25zLm1heHpvb207XG5cbiAgICAgICAgY29uc3QgY2VudGVyQ29vcmQgPSB0aGlzLmxvY2F0aW9uQ29vcmRpbmF0ZSh0aGlzLmNlbnRlcik7XG4gICAgICAgIGNvbnN0IGNlbnRlckxhdGl0dWRlID0gdGhpcy5jZW50ZXIubGF0O1xuICAgICAgICBjb25zdCBudW1UaWxlcyA9IDEgPDwgejtcbiAgICAgICAgY29uc3QgY2VudGVyUG9pbnQgPSBbbnVtVGlsZXMgKiBjZW50ZXJDb29yZC54LCBudW1UaWxlcyAqIGNlbnRlckNvb3JkLnksIDBdO1xuICAgICAgICBjb25zdCBpc0dsb2JlID0gdGhpcy5wcm9qZWN0aW9uLm5hbWUgPT09ICdnbG9iZSc7XG4gICAgICAgIGNvbnN0IHpJbk1ldGVycyA9ICFpc0dsb2JlO1xuICAgICAgICBjb25zdCBjYW1lcmFGcnVzdHVtID0gRnJ1c3R1bS5mcm9tSW52UHJvamVjdGlvbk1hdHJpeCh0aGlzLmludlByb2pNYXRyaXgsIHRoaXMud29ybGRTaXplLCB6LCB6SW5NZXRlcnMpO1xuICAgICAgICBjb25zdCBjYW1lcmFDb29yZCA9IGlzR2xvYmUgPyB0aGlzLl9jYW1lcmEubWVyY2F0b3JQb3NpdGlvbiA6IHRoaXMucG9pbnRDb29yZGluYXRlKHRoaXMuZ2V0Q2FtZXJhUG9pbnQoKSk7XG4gICAgICAgIGNvbnN0IG1ldGVyVG9UaWxlID0gbnVtVGlsZXMgKiBtZXJjYXRvclpmcm9tQWx0aXR1ZGUoMSwgdGhpcy5jZW50ZXIubGF0KTtcbiAgICAgICAgY29uc3QgY2FtZXJhQWx0aXR1ZGUgPSB0aGlzLl9jYW1lcmEucG9zaXRpb25bMl0gLyBtZXJjYXRvclpmcm9tQWx0aXR1ZGUoMSwgdGhpcy5jZW50ZXIubGF0KTtcbiAgICAgICAgY29uc3QgY2FtZXJhUG9pbnQgPSBbbnVtVGlsZXMgKiBjYW1lcmFDb29yZC54LCBudW1UaWxlcyAqIGNhbWVyYUNvb3JkLnksIGNhbWVyYUFsdGl0dWRlICogKHpJbk1ldGVycyA/IDEgOiBtZXRlclRvVGlsZSldO1xuICAgICAgICAvLyBMZXQncyBjb25zaWRlciBhbiBleGFtcGxlIGZvciAhcm91bmRab29tOiBlLmcuIHRpbGVab29tIDE2IGlzIHVzZWQgZnJvbSB6b29tIDE2IGFsbCB0aGUgd2F5IHRvIHpvb20gMTYuOTkuXG4gICAgICAgIC8vIFRoaXMgd291bGQgbWVhbiB0aGF0IHRoZSBtaW5pbWFsIGRpc3RhbmNlIHRvIHNwbGl0IHdvdWxkIGJlIGJhc2VkIG9uIGRpc3RhbmNlIGZyb20gY2FtZXJhIHRvIGNlbnRlciBvZiAxNi45OSB6b29tLlxuICAgICAgICAvLyBUaGUgc2FtZSBpcyBhbHJlYWR5IGluY29ycG9yYXRlZCBpbiBsb2dpYyBiZWhpbmQgcm91bmRab29tIGZvciByYXN0ZXIgKHNvIHRoZXJlIGlzIG5vIGFkanVzdG1lbnQgbmVlZGVkIGluIGZvbGxvd2luZyBsaW5lKS5cbiAgICAgICAgLy8gMC4wMiBhZGRlZCB0byBjb21wZW5zYXRlIGZvciBwcmVjaXNpb24gZXJyb3JzLCBzZWUgXCJjb3ZlcmluZ1RpbGVzIGZvciB0ZXJyYWluXCIgdGVzdCBpbiB0cmFuc2Zvcm0udGVzdC5qcy5cbiAgICAgICAgY29uc3Qgem9vbVNwbGl0RGlzdGFuY2UgPSB0aGlzLmNhbWVyYVRvQ2VudGVyRGlzdGFuY2UgLyBvcHRpb25zLnRpbGVTaXplICogKG9wdGlvbnMucm91bmRab29tID8gMSA6IDAuNTAyKTtcblxuICAgICAgICAvLyBObyBjaGFuZ2Ugb2YgTE9EIGJlaGF2aW9yIGZvciBwaXRjaCBsb3dlciB0aGFuIDYwIGFuZCB3aGVuIHRoZXJlIGlzIG5vIHRvcCBwYWRkaW5nOiByZXR1cm4gb25seSB0aWxlIGlkcyBmcm9tIHRoZSByZXF1ZXN0ZWQgem9vbSBsZXZlbFxuICAgICAgICBjb25zdCBtaW5ab29tID0gdGhpcy5waXRjaCA8PSA2MC4wICYmIHRoaXMuX2VkZ2VJbnNldHMudG9wIDw9IHRoaXMuX2VkZ2VJbnNldHMuYm90dG9tICYmICF0aGlzLl9lbGV2YXRpb24gJiYgIXRoaXMucHJvamVjdGlvbi5pc1JlcHJvamVjdGVkSW5UaWxlU3BhY2UgPyB6IDogMDtcblxuICAgICAgICAvLyBXaGVuIGNhbGN1bGF0aW5nIHRpbGUgY292ZXIgZm9yIHRlcnJhaW4sIGNyZWF0ZSBkZWVwIEFBQkIgZm9yIG5vZGVzLCB0byBlbnN1cmUgdGhleSBpbnRlcnNlY3QgZnJ1c3R1bTogZm9yIHNvdXJjZXMsXG4gICAgICAgIC8vIG90aGVyIHRoYW4gREVNLCB1c2UgbWluaW11bSBvZiB2aXNpYmxlIERFTSB0aWxlcyBhbmQgY2VudGVyIGFsdGl0dWRlIGFzIHVwcGVyIGJvdW5kIChwaXRjaCBpcyBhbHdheXMgbGVzcyB0aGFuIDkwwrApLlxuICAgICAgICBjb25zdCBtYXhSYW5nZSA9IG9wdGlvbnMuaXNUZXJyYWluREVNICYmIHRoaXMuX2VsZXZhdGlvbiA/IHRoaXMuX2VsZXZhdGlvbi5leGFnZ2VyYXRpb24oKSAqIDEwMDAwIDogdGhpcy5fY2VudGVyQWx0aXR1ZGU7XG4gICAgICAgIGNvbnN0IG1pblJhbmdlID0gb3B0aW9ucy5pc1RlcnJhaW5ERU0gPyAtbWF4UmFuZ2UgOiB0aGlzLl9lbGV2YXRpb24gPyB0aGlzLl9lbGV2YXRpb24uZ2V0TWluRWxldmF0aW9uQmVsb3dNU0woKSA6IDA7XG5cbiAgICAgICAgY29uc3Qgc2NhbGVBZGp1c3RtZW50ID0gdGhpcy5wcm9qZWN0aW9uLmlzUmVwcm9qZWN0ZWRJblRpbGVTcGFjZSA/IGdldFNjYWxlQWRqdXN0bWVudCh0aGlzKSA6IDEuMDtcblxuICAgICAgICBjb25zdCByZWxhdGl2ZVNjYWxlQXRNZXJjYXRvckNvb3JkID0gKG1jOiBNZXJjYXRvckNvb3JkaW5hdGUpID0+IHtcbiAgICAgICAgICAgIC8vIENhbGN1bGF0ZSBob3cgc2NhbGUgY29tcGFyZXMgYmV0d2VlbiBwcm9qZWN0ZWQgY29vcmRpbmF0ZXMgYW5kIG1lcmNhdG9yIGNvb3JkaW5hdGVzLlxuICAgICAgICAgICAgLy8gUmV0dXJucyBhIGxlbmd0aC4gVGhlIHVuaXRzIGRvbid0IG1hdHRlciBzaW5jZSB0aGUgcmVzdWx0IGlzIG9ubHlcbiAgICAgICAgICAgIC8vIHVzZWQgaW4gYSByYXRpbyB3aXRoIG90aGVyIHZhbHVlcyByZXR1cm5lZCBieSB0aGlzIGZ1bmN0aW9uLlxuXG4gICAgICAgICAgICAvLyBDb25zdHJ1Y3QgYSBzbWFsbCBzcXVhcmUgaW4gTWVyY2F0b3IgY29vcmRpbmF0ZXMuXG4gICAgICAgICAgICBjb25zdCBvZmZzZXQgPSAxIC8gNDAwMDA7XG4gICAgICAgICAgICBjb25zdCBtY0Vhc3QgPSBuZXcgTWVyY2F0b3JDb29yZGluYXRlKG1jLnggKyBvZmZzZXQsIG1jLnksIG1jLnopO1xuICAgICAgICAgICAgY29uc3QgbWNTb3V0aCA9IG5ldyBNZXJjYXRvckNvb3JkaW5hdGUobWMueCwgbWMueSArIG9mZnNldCwgbWMueik7XG5cbiAgICAgICAgICAgIC8vIENvbnZlcnQgdGhlIHNxdWFyZSB0byBwcm9qZWN0ZWQgY29vcmRpbmF0ZXMuXG4gICAgICAgICAgICBjb25zdCBsbCA9IG1jLnRvTG5nTGF0KCk7XG4gICAgICAgICAgICBjb25zdCBsbEVhc3QgPSBtY0Vhc3QudG9MbmdMYXQoKTtcbiAgICAgICAgICAgIGNvbnN0IGxsU291dGggPSBtY1NvdXRoLnRvTG5nTGF0KCk7XG4gICAgICAgICAgICBjb25zdCBwID0gdGhpcy5sb2NhdGlvbkNvb3JkaW5hdGUobGwpO1xuICAgICAgICAgICAgY29uc3QgcEVhc3QgPSB0aGlzLmxvY2F0aW9uQ29vcmRpbmF0ZShsbEVhc3QpO1xuICAgICAgICAgICAgY29uc3QgcFNvdXRoID0gdGhpcy5sb2NhdGlvbkNvb3JkaW5hdGUobGxTb3V0aCk7XG5cbiAgICAgICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgc2l6ZSBvZiBlYWNoIGVkZ2Ugb2YgdGhlIHJlcHJvamVjdGVkIHNxdWFyZVxuICAgICAgICAgICAgY29uc3QgZHggPSBNYXRoLmh5cG90KHBFYXN0LnggLSBwLngsIHBFYXN0LnkgLSBwLnkpO1xuICAgICAgICAgICAgY29uc3QgZHkgPSBNYXRoLmh5cG90KHBTb3V0aC54IC0gcC54LCBwU291dGgueSAtIHAueSk7XG5cbiAgICAgICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgc2l6ZSBvZiBhIHByb2plY3RlZCBzcXVhcmUgdGhhdCB3b3VsZCBoYXZlIHRoZVxuICAgICAgICAgICAgLy8gc2FtZSBhcmVhIGFzIHRoZSByZXByb2plY3RlZCBzcXVhcmUuXG4gICAgICAgICAgICByZXR1cm4gTWF0aC5zcXJ0KGR4ICogZHkpICogc2NhbGVBZGp1c3RtZW50IC8gb2Zmc2V0O1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IG5ld1Jvb3RUaWxlID0gKHdyYXA6IG51bWJlcik6IFJvb3RUaWxlID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG1heCA9IG1heFJhbmdlO1xuICAgICAgICAgICAgY29uc3QgbWluID0gbWluUmFuZ2U7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIC8vIFdpdGggZWxldmF0aW9uLCB0aGlzLl9lbGV2YXRpb24gcHJvdmlkZXMgeiBjb29yZGluYXRlIHZhbHVlcy4gRm9yIDJEOlxuICAgICAgICAgICAgICAgIC8vIEFsbCB0aWxlcyBhcmUgb24gemVybyBlbGV2YXRpb24gcGxhbmUgPT4geiBkaWZmZXJlbmNlIGlzIHplcm9cbiAgICAgICAgICAgICAgICBhYWJiOiB0aWxlQUFCQih0aGlzLCBudW1UaWxlcywgMCwgMCwgMCwgd3JhcCwgbWluLCBtYXgsIHRoaXMucHJvamVjdGlvbiksXG4gICAgICAgICAgICAgICAgem9vbTogMCxcbiAgICAgICAgICAgICAgICB4OiAwLFxuICAgICAgICAgICAgICAgIHk6IDAsXG4gICAgICAgICAgICAgICAgbWluWjogbWluLFxuICAgICAgICAgICAgICAgIG1heFo6IG1heCxcbiAgICAgICAgICAgICAgICB3cmFwLFxuICAgICAgICAgICAgICAgIGZ1bGx5VmlzaWJsZTogZmFsc2VcbiAgICAgICAgICAgIH07XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gRG8gYSBkZXB0aC1maXJzdCB0cmF2ZXJzYWwgdG8gZmluZCB2aXNpYmxlIHRpbGVzIGFuZCBwcm9wZXIgbGV2ZWxzIG9mIGRldGFpbFxuICAgICAgICBjb25zdCBzdGFjayA9IFtdO1xuICAgICAgICBsZXQgcmVzdWx0ID0gW107XG4gICAgICAgIGNvbnN0IG1heFpvb20gPSB6O1xuICAgICAgICBjb25zdCBvdmVyc2NhbGVkWiA9IG9wdGlvbnMucmVwYXJzZU92ZXJzY2FsZWQgPyBhY3R1YWxaIDogejtcbiAgICAgICAgY29uc3Qgc3F1YXJlID0gKGE6IG51bWJlcikgPT4gYSAqIGE7XG4gICAgICAgIGNvbnN0IGNhbWVyYUhlaWdodFNxciA9IHNxdWFyZSgoY2FtZXJhQWx0aXR1ZGUgLSB0aGlzLl9jZW50ZXJBbHRpdHVkZSkgKiBtZXRlclRvVGlsZSk7IC8vIGluIHRpbGUgY29vcmRpbmF0ZXMuXG5cbiAgICAgICAgY29uc3QgZ2V0QUFCQkZyb21FbGV2YXRpb24gPSAoaXQ6IFJvb3RUaWxlKSA9PiB7XG4gICAgICAgICAgICBhc3NlcnQodGhpcy5fZWxldmF0aW9uKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5fZWxldmF0aW9uIHx8ICFpdC50aWxlSUQgfHwgIWlzTWVyY2F0b3IpIHJldHVybjsgLy8gVG8gc2lsZW5jZSBmbG93LlxuICAgICAgICAgICAgY29uc3QgbWlubWF4ID0gdGhpcy5fZWxldmF0aW9uLmdldE1pbk1heEZvclRpbGUoaXQudGlsZUlEKTtcbiAgICAgICAgICAgIGNvbnN0IGFhYmIgPSBpdC5hYWJiO1xuICAgICAgICAgICAgaWYgKG1pbm1heCkge1xuICAgICAgICAgICAgICAgIGFhYmIubWluWzJdID0gbWlubWF4Lm1pbjtcbiAgICAgICAgICAgICAgICBhYWJiLm1heFsyXSA9IG1pbm1heC5tYXg7XG4gICAgICAgICAgICAgICAgYWFiYi5jZW50ZXJbMl0gPSAoYWFiYi5taW5bMl0gKyBhYWJiLm1heFsyXSkgLyAyO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpdC5zaG91bGRTcGxpdCA9IHNob3VsZFNwbGl0KGl0KTtcbiAgICAgICAgICAgICAgICBpZiAoIWl0LnNob3VsZFNwbGl0KSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEF0IGZpbmFsIHpvb20gbGV2ZWwsIHdoaWxlIGNvcnJlc3BvbmRpbmcgREVNIHRpbGUgaXMgbm90IGxvYWRlZCB5ZXQsXG4gICAgICAgICAgICAgICAgICAgIC8vIGFzc3VtZSBjZW50ZXIgZWxldmF0aW9uLiBUaGlzIGNvdmVycyBncm91bmQgdG8gaG9yaXpvbiBhbmQgcHJldmVudHNcbiAgICAgICAgICAgICAgICAgICAgLy8gbG9hZGluZyB1bm5lY2Vzc2FyeSB0aWxlcyB1bnRpbCBERU0gY292ZXIgaXMgZnVsbHkgbG9hZGVkLlxuICAgICAgICAgICAgICAgICAgICBhYWJiLm1pblsyXSA9IGFhYmIubWF4WzJdID0gYWFiYi5jZW50ZXJbMl0gPSB0aGlzLl9jZW50ZXJBbHRpdHVkZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gU2NhbGUgZGlzdGFuY2UgdG8gc3BsaXQgZm9yIGFjdXRlIGFuZ2xlcy5cbiAgICAgICAgLy8gZHpTcXI6IHogY29tcG9uZW50IG9mIGNhbWVyYSB0byB0aWxlIGRpc3RhbmNlLCBzcXVhcmUuXG4gICAgICAgIC8vIGRTcXI6IDNEIGRpc3RhbmNlIG9mIGNhbWVyYSB0byB0aWxlLCBzcXVhcmUuXG4gICAgICAgIGNvbnN0IGRpc3RUb1NwbGl0U2NhbGUgPSAoZHpTcXI6IG51bWJlciwgZFNxcjogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICAvLyBXaGVuIHRoZSBhbmdsZSBiZXR3ZWVuIGNhbWVyYSB0byB0aWxlIHJheSBhbmQgdGlsZSBwbGFuZSBpcyBzbWFsbGVyXG4gICAgICAgICAgICAvLyB0aGFuIGFjdXRlQW5nbGVUaHJlc2hvbGQsIHNjYWxlIHRoZSBkaXN0YW5jZSB0byBzcGxpdC4gU2NhbGluZyBpcyBhZGFwdGl2ZTogc21hbGxlclxuICAgICAgICAgICAgLy8gdGhlIGFuZ2xlLCB0aGUgc2NhbGUgZ2V0cyBsb3dlciB2YWx1ZS4gQWx0aG91Z2ggaXQgc2VlbXMgZWFybHkgdG8gc3RhcnQgYXQgNDUsXG4gICAgICAgICAgICAvLyBpdCBpcyBub3Q6IHNjYWxpbmcga2lja3MgaW4gYXJvdW5kIDYwIGRlZ3JlZXMgcGl0Y2guXG4gICAgICAgICAgICBjb25zdCBhY3V0ZUFuZ2xlVGhyZXNob2xkU2luID0gMC43MDc7IC8vIE1hdGguc2luKDQ1KVxuICAgICAgICAgICAgY29uc3Qgc3RyZXRjaFRpbGUgPSAxLjE7XG4gICAgICAgICAgICAvLyBEaXN0YW5jZXMgbG9uZ2VyIHRoYW4gJ2R6IC8gYWN1dGVBbmdsZVRocmVzaG9sZFNpbicgZ2V0cyBzY2FsZWRcbiAgICAgICAgICAgIC8vIGZvbGxvd2luZyBnZW9tZXRyaWMgc2VyaWVzIHN1bTogZXZlcnkgbmV4dCBkeiBsZW5ndGggaW4gZGlzdGFuY2UgY2FuIGJlXG4gICAgICAgICAgICAvLyAnc3RyZXRjaFRpbGUgdGltZXMnIGxvbmdlci4gSXQgaXMgZnVydGhlciwgdGhlIGFuZ2xlIGlzIHNoYXJwZXIuIFRvdGFsLFxuICAgICAgICAgICAgLy8gYWRqdXN0ZWQsIGRpc3RhbmNlIHdvdWxkIHRoZW4gYmU6XG4gICAgICAgICAgICAvLyA9IGR6IC8gYWN1dGVBbmdsZVRocmVzaG9sZFNpbiArIChkeiAqIHN0cmV0Y2hUaWxlICsgZHogKiBzdHJldGNoVGlsZSBeIDIgKyAuLi4gKyBkeiAqIHN0cmV0Y2hUaWxlIF4gayksXG4gICAgICAgICAgICAvLyB3aGVyZSBrID0gKGQgLSBkeiAvIGFjdXRlQW5nbGVUaHJlc2hvbGRTaW4pIC8gZHogPSBkIC8gZHogLSAxIC8gYWN1dGVBbmdsZVRocmVzaG9sZFNpbjtcbiAgICAgICAgICAgIC8vID0gZHogLyBhY3V0ZUFuZ2xlVGhyZXNob2xkU2luICsgZHogKiAoKHN0cmV0Y2hUaWxlIF4gKGsgKyAxKSAtIDEpIC8gKHN0cmV0Y2hUaWxlIC0gMSkgLSAxKVxuICAgICAgICAgICAgLy8gb3IgcHV0IGRpZmZlcmVudGx5LCBnaXZlbiB0aGF0IGsgaXMgYmFzZWQgb24gZCBhbmQgZHosIHRpbGUgb24gZGlzdGFuY2UgZCBjb3VsZCBiZSB1c2VkIG9uIGRpc3RhbmNlIHNjYWxlZCBieTpcbiAgICAgICAgICAgIC8vIDEgLyBhY3V0ZUFuZ2xlVGhyZXNob2xkU2luICsgKHN0cmV0Y2hUaWxlIF4gKGsgKyAxKSAtIDEpIC8gKHN0cmV0Y2hUaWxlIC0gMSkgLSAxXG4gICAgICAgICAgICBpZiAoZFNxciAqIHNxdWFyZShhY3V0ZUFuZ2xlVGhyZXNob2xkU2luKSA8IGR6U3FyKSByZXR1cm4gMS4wOyAvLyBFYXJseSByZXR1cm4sIG5vIHNjYWxlLlxuICAgICAgICAgICAgY29uc3QgciA9IE1hdGguc3FydChkU3FyIC8gZHpTcXIpO1xuICAgICAgICAgICAgY29uc3QgayA9ICByIC0gMSAvIGFjdXRlQW5nbGVUaHJlc2hvbGRTaW47XG4gICAgICAgICAgICByZXR1cm4gciAvICgxIC8gYWN1dGVBbmdsZVRocmVzaG9sZFNpbiArIChNYXRoLnBvdyhzdHJldGNoVGlsZSwgayArIDEpIC0gMSkgLyAoc3RyZXRjaFRpbGUgLSAxKSAtIDEpO1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHNob3VsZFNwbGl0ID0gKGl0OiBSb290VGlsZSkgPT4ge1xuICAgICAgICAgICAgaWYgKGl0Lnpvb20gPCBtaW5ab29tKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGl0Lnpvb20gPT09IG1heFpvb20pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXQuc2hvdWxkU3BsaXQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpdC5zaG91bGRTcGxpdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGR4ID0gaXQuYWFiYi5kaXN0YW5jZVgoY2FtZXJhUG9pbnQpO1xuICAgICAgICAgICAgY29uc3QgZHkgPSBpdC5hYWJiLmRpc3RhbmNlWShjYW1lcmFQb2ludCk7XG4gICAgICAgICAgICBsZXQgZHpTcXIgPSBjYW1lcmFIZWlnaHRTcXI7XG5cbiAgICAgICAgICAgIGxldCB0aWxlU2NhbGVBZGp1c3RtZW50ID0gMTtcbiAgICAgICAgICAgIGlmIChpc0dsb2JlKSB7XG4gICAgICAgICAgICAgICAgZHpTcXIgPSBzcXVhcmUoaXQuYWFiYi5kaXN0YW5jZVooY2FtZXJhUG9pbnQpKTtcbiAgICAgICAgICAgICAgICAvLyBDb21wZW5zYXRlIHBoeXNpY2FsIHNpemVzIG9mIHRoZSB0aWxlcyB3aGVuIGRldGVybWluaW5nIHdoaWNoIHpvb20gbGV2ZWwgdG8gdXNlLlxuICAgICAgICAgICAgICAgIC8vIEluIHByYWN0aWNlIHRpbGVzIGNsb3NlciB0byBwb2xlcyBzaG91bGQgdXNlIG1vcmUgYWdncmVzc2l2ZSBMT0QgYXMgdGhlaXJcbiAgICAgICAgICAgICAgICAvLyBwaHlzaWNhbCBzaXplIGlzIGFscmVhZHkgc21hbGxlciB0aGFuIHNpemUgb2YgdGlsZXMgbmVhciB0aGUgZXF1YXRvci5cbiAgICAgICAgICAgICAgICBjb25zdCB0aWxlc0F0Wm9vbSA9IE1hdGgucG93KDIsIGl0Lnpvb20pO1xuICAgICAgICAgICAgICAgIGNvbnN0IG1pbkxhdCA9IGxhdEZyb21NZXJjYXRvclkoKGl0LnkgKyAxKSAvIHRpbGVzQXRab29tKTtcbiAgICAgICAgICAgICAgICBjb25zdCBtYXhMYXQgPSBsYXRGcm9tTWVyY2F0b3JZKChpdC55KSAvIHRpbGVzQXRab29tKTtcbiAgICAgICAgICAgICAgICBjb25zdCBjbG9zZXN0TGF0ID0gTWF0aC5taW4oTWF0aC5tYXgoY2VudGVyTGF0aXR1ZGUsIG1pbkxhdCksIG1heExhdCk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCByZWxhdGl2ZVRpbGVTY2FsZSA9IGNpcmN1bWZlcmVuY2VBdExhdGl0dWRlKGNsb3Nlc3RMYXQpIC8gY2lyY3VtZmVyZW5jZUF0TGF0aXR1ZGUoY2VudGVyTGF0aXR1ZGUpO1xuXG4gICAgICAgICAgICAgICAgLy8gV2l0aCBnbG9iZSwgdGhlIHJlbmRlcmVkIHNjYWxlIGRvZXMgbm90IGV4YWN0bHkgbWF0Y2ggdGhlIG1lcmNhdG9yIHNjYWxlIGF0IGxvdyB6b29tIGxldmVscy5cbiAgICAgICAgICAgICAgICAvLyBBY2NvdW50IGZvciB0aGlzIGRpZmZlcmVuY2UgZHVyaW5nIExPRCBvZiBsb2FkaW5nIHNvIHRoYXQgeW91IGxvYWQgdGhlIGNvcnJlY3Qgc2l6ZSB0aWxlcy5cbiAgICAgICAgICAgICAgICAvLyBXZSB0cnkgdG8gY29tcHJvbWlzZSBiZXR3ZWVuIHR3byBjb25mbGljdGluZyByZXF1aXJlbWVudHM6XG4gICAgICAgICAgICAgICAgLy8gLSBsb2FkaW5nIHRpbGVzIGF0IHRoZSBjYW1lcmEncyB6b29tIGxldmVsIChmb3IgdmlzdWFsIGFuZCBzdHlsaW5nIGNvbnNpc3RlbmN5KVxuICAgICAgICAgICAgICAgIC8vIC0gbG9hZGluZyBjb3JyZWN0IHNpemUgdGlsZXMgKHRvIHJlZHVjZSB0aGUgbnVtYmVyIG9mIHRpbGVzIGxvYWRlZClcbiAgICAgICAgICAgICAgICAvLyBUaGVzZSBhcmUgYXJiaXRyYXJpbHkgYmFsYW5jZWQ6XG4gICAgICAgICAgICAgICAgaWYgKGNsb3Nlc3RMYXQgPT09IGNlbnRlckxhdGl0dWRlKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEZvciB0aWxlcyB0aGF0IGFyZSBpbiB0aGUgbWlkZGxlIG9mIHRoZSB2aWV3cG9ydCwgcHJpb3JpdGl6ZSBtYXRjaGluZyB0aGUgY2FtZXJhXG4gICAgICAgICAgICAgICAgICAgIC8vIHpvb20gYW5kIGFsbG93IGRpdmVyZ2VuY2UgZnJvbSB0aGUgdHJ1ZSBzY2FsZS5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF4RGl2ZXJnZW5jZSA9IDAuMztcbiAgICAgICAgICAgICAgICAgICAgdGlsZVNjYWxlQWRqdXN0bWVudCA9IDEgLyBNYXRoLm1heCgxLCB0aGlzLl9tZXJjYXRvclNjYWxlUmF0aW8gLSBtYXhEaXZlcmdlbmNlKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBGb3Igb3RoZXIgdGlsZXMsIHVzZSB0aGUgcmVhbCBzY2FsZSB0byByZWR1Y2UgdGlsZSBjb3VudHMgbmVhciBwb2xlcy5cbiAgICAgICAgICAgICAgICAgICAgdGlsZVNjYWxlQWRqdXN0bWVudCA9IE1hdGgubWluKDEsIHJlbGF0aXZlVGlsZVNjYWxlIC8gdGhpcy5fbWVyY2F0b3JTY2FsZVJhdGlvKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBFbnN1cmUgdGhhdCBhbGwgdGlsZXMgbmVhciB0aGUgY2VudGVyIGhhdmUgdGhlIHNhbWUgem9vbSBsZXZlbC5cbiAgICAgICAgICAgICAgICAvLyBXaXRoIExPRCB0aWxlIGxvYWRpbmcsIHRpbGUgem9vbSBsZXZlbHMgY2FuIGNoYW5nZSB3aGVuIHNjYWxlIHNsaWdodGx5IGNoYW5nZXMuXG4gICAgICAgICAgICAgICAgLy8gVGhlc2UgZGlmZmVyZW5jZXMgY2FuIGJlIHByZXR0eSBkaWZmZXJlbnQgaW4gZ2xvYmUgdmlldy4gV29yayBhcm91bmQgdGhpcyBieVxuICAgICAgICAgICAgICAgIC8vIG1ha2luZyBtb3JlIHRpbGVzIG1hdGNoIHRoZSBjZW50ZXIgdGlsZSdzIHpvb20gbGV2ZWwuIElmIHRoZSB0aWxlcyBhcmUgbmVhcmx5IGJpZyBlbm91Z2gsXG4gICAgICAgICAgICAgICAgLy8gcm91bmQgdXAuIE9ubHkgYXBwbHkgdGhpcyBhZGp1c3RtZW50IGJlZm9yZSB0aGUgdHJhbnNpdGlvbiB0byBtZXJjYXRvciByZW5kZXJpbmcgaGFzIHN0YXJ0ZWQuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuem9vbSA8PSBHTE9CRV9aT09NX1RIUkVTSE9MRF9NSU4gJiYgaXQuem9vbSA9PT0gbWF4Wm9vbSAtIDEgJiYgcmVsYXRpdmVUaWxlU2NhbGUgPj0gMC45KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYXNzZXJ0KHpJbk1ldGVycyk7XG4gICAgICAgICAgICAgICAgaWYgKHVzZUVsZXZhdGlvbkRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgZHpTcXIgPSBzcXVhcmUoaXQuYWFiYi5kaXN0YW5jZVooY2FtZXJhUG9pbnQpICogbWV0ZXJUb1RpbGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wcm9qZWN0aW9uLmlzUmVwcm9qZWN0ZWRJblRpbGVTcGFjZSAmJiBhY3R1YWxaIDw9IDUpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSW4gb3RoZXIgcHJvamVjdGlvbnMsIG5vdCBhbGwgdGlsZXMgYXJlIHRoZSBzYW1lIHNpemUuXG4gICAgICAgICAgICAgICAgICAgIC8vIEFjY291bnQgZm9yIHRoZSB0aWxlIHNpemUgZGlmZmVyZW5jZSBieSBhZGp1c3RpbmcgdGhlIGRpc3RUb1NwbGl0LlxuICAgICAgICAgICAgICAgICAgICAvLyBBZGp1c3QgYnkgdGhlIHJhdGlvIG9mIHRoZSBhcmVhIGF0IHRoZSB0aWxlIGNlbnRlciB0byB0aGUgYXJlYSBhdCB0aGUgbWFwIGNlbnRlci5cbiAgICAgICAgICAgICAgICAgICAgLy8gQWRqdXN0bWVudHMgYXJlIG9ubHkgbmVlZGVkIGF0IGxvd2VyIHpvb21zIHdoZXJlIHRpbGVzIGFyZSBub3Qgc2ltaWxhcmx5IHNpemVkLlxuICAgICAgICAgICAgICAgICAgICBjb25zdCBudW1UaWxlcyA9IE1hdGgucG93KDIsIGl0Lnpvb20pO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZWxhdGl2ZVNjYWxlID0gcmVsYXRpdmVTY2FsZUF0TWVyY2F0b3JDb29yZChuZXcgTWVyY2F0b3JDb29yZGluYXRlKChpdC54ICsgMC41KSAvIG51bVRpbGVzLCAoaXQueSArIDAuNSkgLyBudW1UaWxlcykpO1xuICAgICAgICAgICAgICAgICAgICAvLyBGdWRnZSB0aGUgcmF0aW8gc2xpZ2h0bHkgc28gdGhhdCBhbGwgdGlsZXMgbmVhciB0aGUgY2VudGVyIGhhdmUgdGhlIHNhbWUgem9vbSBsZXZlbC5cbiAgICAgICAgICAgICAgICAgICAgdGlsZVNjYWxlQWRqdXN0bWVudCA9IHJlbGF0aXZlU2NhbGUgPiAwLjg1ID8gMSA6IHJlbGF0aXZlU2NhbGU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBkaXN0YW5jZVNxciA9IGR4ICogZHggKyBkeSAqIGR5ICsgZHpTcXI7XG4gICAgICAgICAgICBjb25zdCBkaXN0VG9TcGxpdCA9ICgxIDw8IG1heFpvb20gLSBpdC56b29tKSAqIHpvb21TcGxpdERpc3RhbmNlICogdGlsZVNjYWxlQWRqdXN0bWVudDtcbiAgICAgICAgICAgIGNvbnN0IGRpc3RUb1NwbGl0U3FyID0gc3F1YXJlKGRpc3RUb1NwbGl0ICogZGlzdFRvU3BsaXRTY2FsZShNYXRoLm1heChkelNxciwgY2FtZXJhSGVpZ2h0U3FyKSwgZGlzdGFuY2VTcXIpKTtcblxuICAgICAgICAgICAgcmV0dXJuIGRpc3RhbmNlU3FyIDwgZGlzdFRvU3BsaXRTcXI7XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKHRoaXMucmVuZGVyV29ybGRDb3BpZXMpIHtcbiAgICAgICAgICAgIC8vIFJlbmRlciBjb3B5IG9mIHRoZSBnbG9iZSB0aHJpY2Ugb24gYm90aCBzaWRlc1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPD0gTlVNX1dPUkxEX0NPUElFUzsgaSsrKSB7XG4gICAgICAgICAgICAgICAgc3RhY2sucHVzaChuZXdSb290VGlsZSgtaSkpO1xuICAgICAgICAgICAgICAgIHN0YWNrLnB1c2gobmV3Um9vdFRpbGUoaSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgc3RhY2sucHVzaChuZXdSb290VGlsZSgwKSk7XG5cbiAgICAgICAgd2hpbGUgKHN0YWNrLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IGl0ID0gc3RhY2sucG9wKCk7XG4gICAgICAgICAgICBjb25zdCB4ID0gaXQueDtcbiAgICAgICAgICAgIGNvbnN0IHkgPSBpdC55O1xuICAgICAgICAgICAgbGV0IGZ1bGx5VmlzaWJsZSA9IGl0LmZ1bGx5VmlzaWJsZTtcblxuICAgICAgICAgICAgLy8gVmlzaWJpbGl0eSBvZiBhIHRpbGUgaXMgbm90IHJlcXVpcmVkIGlmIGFueSBvZiBpdHMgYW5jZXN0b3IgaXMgZnVsbHkgaW5zaWRlIHRoZSBmcnVzdHVtXG4gICAgICAgICAgICBpZiAoIWZ1bGx5VmlzaWJsZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGludGVyc2VjdFJlc3VsdCA9IGl0LmFhYmIuaW50ZXJzZWN0cyhjYW1lcmFGcnVzdHVtKTtcblxuICAgICAgICAgICAgICAgIGlmIChpbnRlcnNlY3RSZXN1bHQgPT09IDApXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICAgICAgZnVsbHlWaXNpYmxlID0gaW50ZXJzZWN0UmVzdWx0ID09PSAyO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBIYXZlIHdlIHJlYWNoZWQgdGhlIHRhcmdldCBkZXB0aCBvciBpcyB0aGUgdGlsZSB0b28gZmFyIGF3YXkgdG8gYmUgYW55IHNwbGl0IGZ1cnRoZXI/XG4gICAgICAgICAgICBpZiAoaXQuem9vbSA9PT0gbWF4Wm9vbSB8fCAhc2hvdWxkU3BsaXQoaXQpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdGlsZVpvb20gPSBpdC56b29tID09PSBtYXhab29tID8gb3ZlcnNjYWxlZFogOiBpdC56b29tO1xuICAgICAgICAgICAgICAgIGlmICghIW9wdGlvbnMubWluem9vbSAmJiBvcHRpb25zLm1pbnpvb20gPiB0aWxlWm9vbSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBOb3Qgd2l0aGluIHNvdXJjZSB0aWxlIHJhbmdlLlxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBkeCA9IGNlbnRlclBvaW50WzBdIC0gKCgwLjUgKyB4ICsgKGl0LndyYXAgPDwgaXQuem9vbSkpICogKDEgPDwgKHogLSBpdC56b29tKSkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGR5ID0gY2VudGVyUG9pbnRbMV0gLSAwLjUgLSB5O1xuICAgICAgICAgICAgICAgIGNvbnN0IGlkID0gaXQudGlsZUlEID8gaXQudGlsZUlEIDogbmV3IE92ZXJzY2FsZWRUaWxlSUQodGlsZVpvb20sIGl0LndyYXAsIGl0Lnpvb20sIHgsIHkpO1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHt0aWxlSUQ6IGlkLCBkaXN0YW5jZVNxOiBkeCAqIGR4ICsgZHkgKiBkeX0pO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoaWxkWCA9ICh4IDw8IDEpICsgKGkgJSAyKTtcbiAgICAgICAgICAgICAgICBjb25zdCBjaGlsZFkgPSAoeSA8PCAxKSArIChpID4+IDEpO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgYWFiYiA9IGlzTWVyY2F0b3IgPyBpdC5hYWJiLnF1YWRyYW50KGkpIDogdGlsZUFBQkIodGhpcywgbnVtVGlsZXMsIGl0Lnpvb20gKyAxLCBjaGlsZFgsIGNoaWxkWSwgaXQud3JhcCwgaXQubWluWiwgaXQubWF4WiwgdGhpcy5wcm9qZWN0aW9uKTtcbiAgICAgICAgICAgICAgICBjb25zdCBjaGlsZDogUm9vdFRpbGUgPSB7YWFiYiwgem9vbTogaXQuem9vbSArIDEsIHg6IGNoaWxkWCwgeTogY2hpbGRZLCB3cmFwOiBpdC53cmFwLCBmdWxseVZpc2libGUsIHRpbGVJRDogdW5kZWZpbmVkLCBzaG91bGRTcGxpdDogdW5kZWZpbmVkLCBtaW5aOiBpdC5taW5aLCBtYXhaOiBpdC5tYXhafTtcbiAgICAgICAgICAgICAgICBpZiAodXNlRWxldmF0aW9uRGF0YSAmJiAhaXNHbG9iZSkge1xuICAgICAgICAgICAgICAgICAgICBjaGlsZC50aWxlSUQgPSBuZXcgT3ZlcnNjYWxlZFRpbGVJRChpdC56b29tICsgMSA9PT0gbWF4Wm9vbSA/IG92ZXJzY2FsZWRaIDogaXQuem9vbSArIDEsIGl0LndyYXAsIGl0Lnpvb20gKyAxLCBjaGlsZFgsIGNoaWxkWSk7XG4gICAgICAgICAgICAgICAgICAgIGdldEFBQkJGcm9tRWxldmF0aW9uKGNoaWxkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc3RhY2sucHVzaChjaGlsZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5mb2dDdWxsRGlzdFNxKSB7XG4gICAgICAgICAgICBjb25zdCBmb2dDdWxsRGlzdFNxID0gdGhpcy5mb2dDdWxsRGlzdFNxO1xuICAgICAgICAgICAgY29uc3QgaG9yaXpvbkxpbmVGcm9tVG9wID0gdGhpcy5ob3Jpem9uTGluZUZyb21Ub3AoKTtcbiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5maWx0ZXIoZW50cnkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1pbiA9IFswLCAwLCAwLCAxXTtcbiAgICAgICAgICAgICAgICBjb25zdCBtYXggPSBbRVhURU5ULCBFWFRFTlQsIDAsIDFdO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgZm9nVGlsZU1hdHJpeCA9IHRoaXMuY2FsY3VsYXRlRm9nVGlsZU1hdHJpeChlbnRyeS50aWxlSUQudG9VbndyYXBwZWQoKSk7XG5cbiAgICAgICAgICAgICAgICB2ZWM0LnRyYW5zZm9ybU1hdDQobWluLCBtaW4sIGZvZ1RpbGVNYXRyaXgpO1xuICAgICAgICAgICAgICAgIHZlYzQudHJhbnNmb3JtTWF0NChtYXgsIG1heCwgZm9nVGlsZU1hdHJpeCk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBzcURpc3QgPSBnZXRBQUJCUG9pbnRTcXVhcmVEaXN0KG1pbiwgbWF4KTtcblxuICAgICAgICAgICAgICAgIGlmIChzcURpc3QgPT09IDApIHsgcmV0dXJuIHRydWU7IH1cblxuICAgICAgICAgICAgICAgIGxldCBvdmVySG9yaXpvbkxpbmUgPSBmYWxzZTtcblxuICAgICAgICAgICAgICAgIC8vIFRlcnJhaW4gbG9hZHMgYXQgb25lIHpvb20gbGV2ZWwgbG93ZXIgdGhhbiB0aGUgcmFzdGVyIGRhdGEsXG4gICAgICAgICAgICAgICAgLy8gc28gdGhlIGZvbGxvd2luZyBjaGVja3Mgd2hldGhlciB0aGUgdGVycmFpbiBzaXRzIGFib3ZlIHRoZSBob3Jpem9uIGFuZCBlbnN1cmVzIHRoYXRcbiAgICAgICAgICAgICAgICAvLyB3aGVuIG1vdW50YWlucyBzdGljayBvdXQgYWJvdmUgdGhlIGZvZyAoZHVlIHRvIGhvcml6b24tYmxlbmQpLFxuICAgICAgICAgICAgICAgIC8vIHdlIGhhdmVu4oCZdCBhY2NpZGVudGFsbHkgY3VsbGVkIHNvbWUgb2YgdGhlIHJhc3RlciB0aWxlcyB3ZSBuZWVkIHRvIGRyYXcgb24gdGhlbS5cbiAgICAgICAgICAgICAgICAvLyBJZiB3ZSBkb27igJl0IGRvIHRoaXMsIHRoZSB0ZXJyYWluIGlzIGRlZmF1bHQgYmxhY2sgY29sb3IgYW5kIG1heSBmbGFzaCBpbiBhbmQgb3V0IGFzIHdlIG1vdmUgdG93YXJkIGl0LlxuXG4gICAgICAgICAgICAgICAgY29uc3QgZWxldmF0aW9uID0gdGhpcy5fZWxldmF0aW9uO1xuXG4gICAgICAgICAgICAgICAgaWYgKGVsZXZhdGlvbiAmJiBzcURpc3QgPiBmb2dDdWxsRGlzdFNxICYmIGhvcml6b25MaW5lRnJvbVRvcCAhPT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwcm9qTWF0cml4ID0gdGhpcy5jYWxjdWxhdGVQcm9qTWF0cml4KGVudHJ5LnRpbGVJRC50b1Vud3JhcHBlZCgpKTtcblxuICAgICAgICAgICAgICAgICAgICBsZXQgbWlubWF4O1xuICAgICAgICAgICAgICAgICAgICBpZiAoIW9wdGlvbnMuaXNUZXJyYWluREVNKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtaW5tYXggPSBlbGV2YXRpb24uZ2V0TWluTWF4Rm9yVGlsZShlbnRyeS50aWxlSUQpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFtaW5tYXgpIHsgbWlubWF4ID0ge21pbjogbWluUmFuZ2UsIG1heDogbWF4UmFuZ2V9OyB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gZW5zdXJlIHRoYXQgd2Ugd2FudCBgdGhpcy5yb3RhdGlvbmAgaW5zdGVhZCBvZiBgdGhpcy5iZWFyaW5nYCBoZXJlXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvcm5lckZhciA9IGZ1cnRoZXN0VGlsZUNvcm5lcih0aGlzLnJvdGF0aW9uKTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBmYXJYID0gY29ybmVyRmFyWzBdICogRVhURU5UO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBmYXJZID0gY29ybmVyRmFyWzFdICogRVhURU5UO1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdvcmxkRmFyID0gW2ZhclgsIGZhclksIG1pbm1heC5tYXhdO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIFdvcmxkIHRvIE5EQ1xuICAgICAgICAgICAgICAgICAgICB2ZWMzLnRyYW5zZm9ybU1hdDQod29ybGRGYXIsIHdvcmxkRmFyLCBwcm9qTWF0cml4KTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBOREMgdG8gU2NyZWVuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNjcmVlbkNvb3JkWSA9ICgxIC0gd29ybGRGYXJbMV0pICogdGhpcy5oZWlnaHQgKiAwLjU7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gUHJldmVudCBjdXR0aW5nIHRpbGVzIGNyb3NzaW5nIG92ZXIgdGhlIGhvcml6b24gbGluZSB0b1xuICAgICAgICAgICAgICAgICAgICAvLyBwcmV2ZW50IHBvcC1pbiBhbmQgb3V0IHdpdGhpbiB0aGUgZm9nIGN1bGxpbmcgcmFuZ2VcbiAgICAgICAgICAgICAgICAgICAgb3Zlckhvcml6b25MaW5lID0gc2NyZWVuQ29vcmRZIDwgaG9yaXpvbkxpbmVGcm9tVG9wO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBzcURpc3QgPCBmb2dDdWxsRGlzdFNxIHx8IG92ZXJIb3Jpem9uTGluZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY292ZXIgPSByZXN1bHQuc29ydCgoYSwgYikgPT4gYS5kaXN0YW5jZVNxIC0gYi5kaXN0YW5jZVNxKS5tYXAoYSA9PiBhLnRpbGVJRCk7XG5cbiAgICAgICAgLy8gUmVsYXggdGhlIGFzc2VydGlvbiBvbiB0ZXJyYWluLCBvbiBoaWdoIHpvb20gd2UgdXNlIGRpc3RhbmNlIHRvIGNlbnRlciBvZiB0aWxlXG4gICAgICAgIC8vIHdoaWxlIGNhbWVyYSBtaWdodCBiZSBjbG9zZXIgdG8gc2VsZWN0ZWQgY2VudGVyIG9mIG1hcC5cbiAgICAgICAgYXNzZXJ0KCFjb3Zlci5sZW5ndGggfHwgdGhpcy5lbGV2YXRpb24gfHwgY292ZXJbMF0ub3ZlcnNjYWxlZFogPT09IG92ZXJzY2FsZWRaIHx8ICFpc01lcmNhdG9yKTtcbiAgICAgICAgcmV0dXJuIGNvdmVyO1xuICAgIH1cblxuICAgIHJlc2l6ZSh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgICAgICB0aGlzLndpZHRoID0gd2lkdGg7XG4gICAgICAgIHRoaXMuaGVpZ2h0ID0gaGVpZ2h0O1xuXG4gICAgICAgIHRoaXMucGl4ZWxzVG9HTFVuaXRzID0gWzIgLyB3aWR0aCwgLTIgLyBoZWlnaHRdO1xuICAgICAgICB0aGlzLl9jb25zdHJhaW4oKTtcbiAgICAgICAgdGhpcy5fY2FsY01hdHJpY2VzKCk7XG4gICAgfVxuXG4gICAgZ2V0IHVubW9kaWZpZWQoKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLl91bm1vZGlmaWVkOyB9XG5cbiAgICB6b29tU2NhbGUoem9vbTogbnVtYmVyKTogbnVtYmVyIHsgcmV0dXJuIE1hdGgucG93KDIsIHpvb20pOyB9XG4gICAgc2NhbGVab29tKHNjYWxlOiBudW1iZXIpOiBudW1iZXIgeyByZXR1cm4gTWF0aC5sb2coc2NhbGUpIC8gTWF0aC5MTjI7IH1cblxuICAgIC8vIFRyYW5zZm9ybSBmcm9tIExuZ0xhdCB0byBQb2ludCBpbiB3b3JsZCBjb29yZGluYXRlcyBbLTE4MCwgMTgwXSB4IFs5MCwgLTkwXSAtLT4gWzAsIHRoaXMud29ybGRTaXplXSB4IFswLCB0aGlzLndvcmxkU2l6ZV1cbiAgICBwcm9qZWN0KGxuZ2xhdDogTG5nTGF0KTogUG9pbnQge1xuICAgICAgICBjb25zdCBsYXQgPSBjbGFtcChsbmdsYXQubGF0LCAtTUFYX01FUkNBVE9SX0xBVElUVURFLCBNQVhfTUVSQ0FUT1JfTEFUSVRVREUpO1xuICAgICAgICBjb25zdCBwcm9qZWN0ZWRMbmdMYXQgPSB0aGlzLnByb2plY3Rpb24ucHJvamVjdChsbmdsYXQubG5nLCBsYXQpO1xuICAgICAgICByZXR1cm4gbmV3IFBvaW50KFxuICAgICAgICAgICAgICAgIHByb2plY3RlZExuZ0xhdC54ICogdGhpcy53b3JsZFNpemUsXG4gICAgICAgICAgICAgICAgcHJvamVjdGVkTG5nTGF0LnkgKiB0aGlzLndvcmxkU2l6ZSk7XG4gICAgfVxuXG4gICAgLy8gVHJhbnNmb3JtIGZyb20gUG9pbnQgaW4gd29ybGQgY29vcmRpbmF0ZXMgdG8gTG5nTGF0IFswLCB0aGlzLndvcmxkU2l6ZV0geCBbMCwgdGhpcy53b3JsZFNpemVdIC0tPiBbLTE4MCwgMTgwXSB4IFs5MCwgLTkwXVxuICAgIHVucHJvamVjdChwb2ludDogUG9pbnQpOiBMbmdMYXQge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9qZWN0aW9uLnVucHJvamVjdChwb2ludC54IC8gdGhpcy53b3JsZFNpemUsIHBvaW50LnkgLyB0aGlzLndvcmxkU2l6ZSk7XG4gICAgfVxuXG4gICAgLy8gUG9pbnQgYXQgY2VudGVyIGluIHdvcmxkIGNvb3JkaW5hdGVzLlxuICAgIGdldCBwb2ludCgpOiBQb2ludCB7IHJldHVybiB0aGlzLnByb2plY3QodGhpcy5jZW50ZXIpOyB9XG5cbiAgICAvLyBQb2ludCBhdCBjZW50ZXIgaW4gTWVyY2F0b3IgY29vcmRpbmF0ZXMuXG4gICAgZ2V0IHBvaW50TWVyYygpOiBQb2ludCB7IHJldHVybiB0aGlzLnBvaW50Ll9kaXYodGhpcy53b3JsZFNpemUpOyB9XG5cbiAgICAvLyBSYXRpbyBvZiBwaXhlbHNQZXJNZXRlciBpbiB0aGUgY3VycmVudCBwcm9qZWN0aW9uIHRvIE1lcmNhdG9yJ3MuXG4gICAgZ2V0IHBpeGVsc1Blck1ldGVyUmF0aW8oKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMucGl4ZWxzUGVyTWV0ZXIgLyBtZXJjYXRvclpmcm9tQWx0aXR1ZGUoMSwgdGhpcy5jZW50ZXIubGF0KSAvIHRoaXMud29ybGRTaXplOyB9XG5cbiAgICBzZXRMb2NhdGlvbkF0UG9pbnQobG5nbGF0OiBMbmdMYXQsIHBvaW50OiBQb2ludCkge1xuICAgICAgICBsZXQgeCwgeTtcbiAgICAgICAgY29uc3QgY2VudGVyUG9pbnQgPSB0aGlzLmNlbnRlclBvaW50O1xuXG4gICAgICAgIGlmICh0aGlzLnByb2plY3Rpb24ubmFtZSA9PT0gJ2dsb2JlJykge1xuICAgICAgICAgICAgLy8gUGl4ZWwgY29vcmRpbmF0ZXMgYXJlIGFwcGxpZWQgZGlyZWN0bHkgdG8gdGhlIGdsb2JlXG4gICAgICAgICAgICBjb25zdCB3b3JsZFNpemUgPSB0aGlzLndvcmxkU2l6ZTtcbiAgICAgICAgICAgIHggPSAocG9pbnQueCAtIGNlbnRlclBvaW50LngpIC8gd29ybGRTaXplO1xuICAgICAgICAgICAgeSA9IChwb2ludC55IC0gY2VudGVyUG9pbnQueSkgLyB3b3JsZFNpemU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBhID0gdGhpcy5wb2ludENvb3JkaW5hdGUocG9pbnQpO1xuICAgICAgICAgICAgY29uc3QgYiA9IHRoaXMucG9pbnRDb29yZGluYXRlKGNlbnRlclBvaW50KTtcbiAgICAgICAgICAgIHggPSBhLnggLSBiLng7XG4gICAgICAgICAgICB5ID0gYS55IC0gYi55O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbG9jID0gdGhpcy5sb2NhdGlvbkNvb3JkaW5hdGUobG5nbGF0KTtcbiAgICAgICAgdGhpcy5zZXRMb2NhdGlvbihuZXcgTWVyY2F0b3JDb29yZGluYXRlKGxvYy54IC0geCwgbG9jLnkgLSB5KSk7XG4gICAgfVxuXG4gICAgc2V0TG9jYXRpb24obG9jYXRpb246IE1lcmNhdG9yQ29vcmRpbmF0ZSkge1xuICAgICAgICB0aGlzLmNlbnRlciA9IHRoaXMuY29vcmRpbmF0ZUxvY2F0aW9uKGxvY2F0aW9uKTtcbiAgICAgICAgaWYgKHRoaXMucHJvamVjdGlvbi53cmFwKSB7XG4gICAgICAgICAgICB0aGlzLmNlbnRlciA9IHRoaXMuY2VudGVyLndyYXAoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdpdmVuIGEgbG9jYXRpb24sIHJldHVybiB0aGUgc2NyZWVuIHBvaW50IHRoYXQgY29ycmVzcG9uZHMgdG8gaXQuIEluIDNEIG1vZGVcbiAgICAgKiAod2l0aCB0ZXJyYWluKSB0aGlzIGJlaGF2ZXMgdGhlIHNhbWUgYXMgaW4gMkQgbW9kZS5cbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjb3VwbGVkIHdpdGgge0BzZWUgcG9pbnRMb2NhdGlvbn0gaW4gM0QgbW9kZSB0byBtb2RlbCBtYXAgbWFuaXB1bGF0aW9uXG4gICAgICogdXNpbmcgZmxhdCBwbGFuZSBhcHByb2FjaCB0byBrZWVwIGNvbnN0YW50IGVsZXZhdGlvbiBhYm92ZSBncm91bmQuXG4gICAgICogQHBhcmFtIHtMbmdMYXR9IGxuZ2xhdCBsb2NhdGlvblxuICAgICAqIEByZXR1cm5zIHtQb2ludH0gc2NyZWVuIHBvaW50XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBsb2NhdGlvblBvaW50KGxuZ2xhdDogTG5nTGF0KTogUG9pbnQge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9qZWN0aW9uLmxvY2F0aW9uUG9pbnQodGhpcywgbG5nbGF0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHaXZlbiBhIGxvY2F0aW9uLCByZXR1cm4gdGhlIHNjcmVlbiBwb2ludCB0aGF0IGNvcnJlc3BvbmRzIHRvIGl0XG4gICAgICogSW4gM0QgbW9kZSAod2hlbiB0ZXJyYWluIGlzIGVuYWJsZWQpIGVsZXZhdGlvbiBpcyBzYW1wbGVkIGZvciB0aGUgcG9pbnQgYmVmb3JlXG4gICAgICogcHJvamVjdGluZyBpdC4gSW4gMkQgbW9kZSwgYmVoYXZlcyB0aGUgc2FtZSBsb2NhdGlvblBvaW50LlxuICAgICAqIEBwYXJhbSB7TG5nTGF0fSBsbmdsYXQgbG9jYXRpb25cbiAgICAgKiBAcmV0dXJucyB7UG9pbnR9IHNjcmVlbiBwb2ludFxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgbG9jYXRpb25Qb2ludDNEKGxuZ2xhdDogTG5nTGF0KTogUG9pbnQge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9qZWN0aW9uLmxvY2F0aW9uUG9pbnQodGhpcywgbG5nbGF0LCB0cnVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHaXZlbiBhIHBvaW50IG9uIHNjcmVlbiwgcmV0dXJuIGl0cyBsbmdsYXRcbiAgICAgKiBAcGFyYW0ge1BvaW50fSBwIHNjcmVlbiBwb2ludFxuICAgICAqIEByZXR1cm5zIHtMbmdMYXR9IGxuZ2xhdCBsb2NhdGlvblxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcG9pbnRMb2NhdGlvbihwOiBQb2ludCk6IExuZ0xhdCB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvb3JkaW5hdGVMb2NhdGlvbih0aGlzLnBvaW50Q29vcmRpbmF0ZShwKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2l2ZW4gYSBwb2ludCBvbiBzY3JlZW4sIHJldHVybiBpdHMgbG5nbGF0XG4gICAgICogSW4gM0QgbW9kZSAobWFwIHdpdGggdGVycmFpbikgcmV0dXJucyBsb2NhdGlvbiBvZiB0ZXJyYWluIHJheWNhc3QgcG9pbnQuXG4gICAgICogSW4gMkQgbW9kZSwgYmVoYXZlcyB0aGUgc2FtZSBhcyB7QHNlZSBwb2ludExvY2F0aW9ufS5cbiAgICAgKiBAcGFyYW0ge1BvaW50fSBwIHNjcmVlbiBwb2ludFxuICAgICAqIEByZXR1cm5zIHtMbmdMYXR9IGxuZ2xhdCBsb2NhdGlvblxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcG9pbnRMb2NhdGlvbjNEKHA6IFBvaW50KTogTG5nTGF0IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29vcmRpbmF0ZUxvY2F0aW9uKHRoaXMucG9pbnRDb29yZGluYXRlM0QocCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdpdmVuIGEgZ2VvZ3JhcGhpY2FsIGxuZ0xhdCwgcmV0dXJuIGFuIHVucm91bmRlZFxuICAgICAqIGNvb3JkaW5hdGUgdGhhdCByZXByZXNlbnRzIGl0IGF0IHRoaXMgdHJhbnNmb3JtJ3Mgem9vbSBsZXZlbC5cbiAgICAgKiBAcGFyYW0ge0xuZ0xhdH0gbG5nTGF0XG4gICAgICogQHJldHVybnMge0Nvb3JkaW5hdGV9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBsb2NhdGlvbkNvb3JkaW5hdGUobG5nTGF0OiBMbmdMYXQsIGFsdGl0dWRlPzogbnVtYmVyKTogTWVyY2F0b3JDb29yZGluYXRlIHtcbiAgICAgICAgY29uc3QgeiA9IGFsdGl0dWRlID9cbiAgICAgICAgICAgIG1lcmNhdG9yWmZyb21BbHRpdHVkZShhbHRpdHVkZSwgbG5nTGF0LmxhdCkgOlxuICAgICAgICAgICAgdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCBwcm9qZWN0ZWRMbmdMYXQgPSB0aGlzLnByb2plY3Rpb24ucHJvamVjdChsbmdMYXQubG5nLCBsbmdMYXQubGF0KTtcbiAgICAgICAgcmV0dXJuIG5ldyBNZXJjYXRvckNvb3JkaW5hdGUoXG4gICAgICAgICAgICBwcm9qZWN0ZWRMbmdMYXQueCxcbiAgICAgICAgICAgIHByb2plY3RlZExuZ0xhdC55LFxuICAgICAgICAgICAgeik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2l2ZW4gYSBDb29yZGluYXRlLCByZXR1cm4gaXRzIGdlb2dyYXBoaWNhbCBwb3NpdGlvbi5cbiAgICAgKiBAcGFyYW0ge0Nvb3JkaW5hdGV9IGNvb3JkXG4gICAgICogQHJldHVybnMge0xuZ0xhdH0gbG5nTGF0XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBjb29yZGluYXRlTG9jYXRpb24oY29vcmQ6IE1lcmNhdG9yQ29vcmRpbmF0ZSk6IExuZ0xhdCB7XG4gICAgICAgIHJldHVybiB0aGlzLnByb2plY3Rpb24udW5wcm9qZWN0KGNvb3JkLngsIGNvb3JkLnkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhc3RzIGEgcmF5IGZyb20gYSBwb2ludCBvbiBzY3JlZW4gYW5kIHJldHVybnMgdGhlIFJheSxcbiAgICAgKiBhbmQgdGhlIGV4dGVudCBhbG9uZyBpdCwgYXQgd2hpY2ggaXQgaW50ZXJzZWN0cyB0aGUgbWFwIHBsYW5lLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtQb2ludH0gcCBWaWV3cG9ydCBwaXhlbCBjby1vcmRpbmF0ZXMuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHogT3B0aW9uYWwgYWx0aXR1ZGUgb2YgdGhlIG1hcCBwbGFuZSwgZGVmYXVsdGluZyB0byBlbGV2YXRpb24gYXQgY2VudGVyLlxuICAgICAqIEByZXR1cm5zIHt7IHAwOiBWZWM0LCBwMTogVmVjNCwgdDogbnVtYmVyIH19IHAwLHAxIGFyZSB0d28gcG9pbnRzIG9uIHRoZSByYXkuXG4gICAgICogdCBpcyB0aGUgZnJhY3Rpb25hbCBleHRlbnQgYWxvbmcgdGhlIHJheSBhdCB3aGljaCB0aGUgcmF5IGludGVyc2VjdHMgdGhlIG1hcCBwbGFuZS5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHBvaW50UmF5SW50ZXJzZWN0aW9uKHA6IFBvaW50LCB6OiA/bnVtYmVyKTogUmF5SW50ZXJzZWN0aW9uUmVzdWx0IHtcbiAgICAgICAgY29uc3QgdGFyZ2V0WiA9ICh6ICE9PSB1bmRlZmluZWQgJiYgeiAhPT0gbnVsbCkgPyB6IDogdGhpcy5fY2VudGVyQWx0aXR1ZGU7XG4gICAgICAgIC8vIFNpbmNlIHdlIGRvbid0IGtub3cgdGhlIGNvcnJlY3QgcHJvamVjdGVkIHogdmFsdWUgZm9yIHRoZSBwb2ludCxcbiAgICAgICAgLy8gdW5wcm9qZWN0IHR3byBwb2ludHMgdG8gZ2V0IGEgbGluZSBhbmQgdGhlbiBmaW5kIHRoZSBwb2ludCBvbiB0aGF0XG4gICAgICAgIC8vIGxpbmUgd2l0aCB6PTAuXG5cbiAgICAgICAgY29uc3QgcDAgPSBbcC54LCBwLnksIDAsIDFdO1xuICAgICAgICBjb25zdCBwMSA9IFtwLngsIHAueSwgMSwgMV07XG5cbiAgICAgICAgdmVjNC50cmFuc2Zvcm1NYXQ0KHAwLCBwMCwgdGhpcy5waXhlbE1hdHJpeEludmVyc2UpO1xuICAgICAgICB2ZWM0LnRyYW5zZm9ybU1hdDQocDEsIHAxLCB0aGlzLnBpeGVsTWF0cml4SW52ZXJzZSk7XG5cbiAgICAgICAgY29uc3QgdzAgPSBwMFszXTtcbiAgICAgICAgY29uc3QgdzEgPSBwMVszXTtcbiAgICAgICAgdmVjNC5zY2FsZShwMCwgcDAsIDEgLyB3MCk7XG4gICAgICAgIHZlYzQuc2NhbGUocDEsIHAxLCAxIC8gdzEpO1xuXG4gICAgICAgIGNvbnN0IHowID0gcDBbMl07XG4gICAgICAgIGNvbnN0IHoxID0gcDFbMl07XG5cbiAgICAgICAgY29uc3QgdCA9IHowID09PSB6MSA/IDAgOiAodGFyZ2V0WiAtIHowKSAvICh6MSAtIHowKTtcblxuICAgICAgICByZXR1cm4ge3AwLCBwMSwgdH07XG4gICAgfVxuXG4gICAgc2NyZWVuUG9pbnRUb01lcmNhdG9yUmF5KHA6IFBvaW50KTogUmF5IHtcbiAgICAgICAgY29uc3QgcDAgPSBbcC54LCBwLnksIDAsIDFdO1xuICAgICAgICBjb25zdCBwMSA9IFtwLngsIHAueSwgMSwgMV07XG5cbiAgICAgICAgdmVjNC50cmFuc2Zvcm1NYXQ0KHAwLCBwMCwgdGhpcy5waXhlbE1hdHJpeEludmVyc2UpO1xuICAgICAgICB2ZWM0LnRyYW5zZm9ybU1hdDQocDEsIHAxLCB0aGlzLnBpeGVsTWF0cml4SW52ZXJzZSk7XG5cbiAgICAgICAgdmVjNC5zY2FsZShwMCwgcDAsIDEgLyBwMFszXSk7XG4gICAgICAgIHZlYzQuc2NhbGUocDEsIHAxLCAxIC8gcDFbM10pO1xuXG4gICAgICAgIC8vIENvbnZlcnQgYWx0aXR1ZGUgZnJvbSBtZXRlcnMgdG8gcGl4ZWxzLlxuICAgICAgICBwMFsyXSA9IG1lcmNhdG9yWmZyb21BbHRpdHVkZShwMFsyXSwgdGhpcy5fY2VudGVyLmxhdCkgKiB0aGlzLndvcmxkU2l6ZTtcbiAgICAgICAgcDFbMl0gPSBtZXJjYXRvclpmcm9tQWx0aXR1ZGUocDFbMl0sIHRoaXMuX2NlbnRlci5sYXQpICogdGhpcy53b3JsZFNpemU7XG5cbiAgICAgICAgdmVjNC5zY2FsZShwMCwgcDAsIDEgLyB0aGlzLndvcmxkU2l6ZSk7XG4gICAgICAgIHZlYzQuc2NhbGUocDEsIHAxLCAxIC8gdGhpcy53b3JsZFNpemUpO1xuXG4gICAgICAgIHJldHVybiBuZXcgUmF5KFtwMFswXSwgcDBbMV0sIHAwWzJdXSwgdmVjMy5ub3JtYWxpemUoW10sIHZlYzMuc3ViKFtdLCBwMSwgcDApKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogIEhlbHBlciBtZXRob2QgdG8gY29udmVydCB0aGUgcmF5IGludGVyc2VjdGlvbiB3aXRoIHRoZSBtYXAgcGxhbmUgdG8gTWVyY2F0b3JDb29yZGluYXRlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtSYXlJbnRlcnNlY3Rpb25SZXN1bHR9IHJheUludGVyc2VjdGlvblxuICAgICAqIEByZXR1cm5zIHtNZXJjYXRvckNvb3JkaW5hdGV9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICByYXlJbnRlcnNlY3Rpb25Db29yZGluYXRlKHJheUludGVyc2VjdGlvbjogUmF5SW50ZXJzZWN0aW9uUmVzdWx0KTogTWVyY2F0b3JDb29yZGluYXRlIHtcbiAgICAgICAgY29uc3Qge3AwLCBwMSwgdH0gPSByYXlJbnRlcnNlY3Rpb247XG5cbiAgICAgICAgY29uc3QgejAgPSBtZXJjYXRvclpmcm9tQWx0aXR1ZGUocDBbMl0sIHRoaXMuX2NlbnRlci5sYXQpO1xuICAgICAgICBjb25zdCB6MSA9IG1lcmNhdG9yWmZyb21BbHRpdHVkZShwMVsyXSwgdGhpcy5fY2VudGVyLmxhdCk7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBNZXJjYXRvckNvb3JkaW5hdGUoXG4gICAgICAgICAgICBpbnRlcnBvbGF0ZShwMFswXSwgcDFbMF0sIHQpIC8gdGhpcy53b3JsZFNpemUsXG4gICAgICAgICAgICBpbnRlcnBvbGF0ZShwMFsxXSwgcDFbMV0sIHQpIC8gdGhpcy53b3JsZFNpemUsXG4gICAgICAgICAgICBpbnRlcnBvbGF0ZSh6MCwgejEsIHQpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHaXZlbiBhIHBvaW50IG9uIHNjcmVlbiwgcmV0dXJucyBNZXJjYXRvckNvb3JkaW5hdGUuXG4gICAgICogQHBhcmFtIHtQb2ludH0gcCBUb3AgbGVmdCBvcmlnaW4gc2NyZWVuIHBvaW50LCBpbiBwaXhlbHMuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHogT3B0aW9uYWwgYWx0aXR1ZGUgb2YgdGhlIG1hcCBwbGFuZSwgZGVmYXVsdGluZyB0byBlbGV2YXRpb24gYXQgY2VudGVyLlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcG9pbnRDb29yZGluYXRlKHA6IFBvaW50LCB6PzogbnVtYmVyID0gdGhpcy5fY2VudGVyQWx0aXR1ZGUpOiBNZXJjYXRvckNvb3JkaW5hdGUge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9qZWN0aW9uLnBvaW50Q29vcmRpbmF0ZSh0aGlzLCBwLngsIHAueSwgeik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2l2ZW4gYSBwb2ludCBvbiBzY3JlZW4sIHJldHVybnMgTWVyY2F0b3JDb29yZGluYXRlLlxuICAgICAqIEluIDNEIG1vZGUsIHJheWNhc3QgdG8gdGVycmFpbi4gSW4gMkQgbW9kZSwgYmVoYXZlcyB0aGUgc2FtZSBhcyB7QHNlZSBwb2ludENvb3JkaW5hdGV9LlxuICAgICAqIEZvciBwIGFib3ZlIHRlcnJhaW4sIGRvbid0IHJldHVybiBwb2ludCBiZWhpbmQgY2FtZXJhIGJ1dCBjbGFtcCBwLnkgYXQgdGhlIHRvcCBvZiB0ZXJyYWluLlxuICAgICAqIEBwYXJhbSB7UG9pbnR9IHAgdG9wIGxlZnQgb3JpZ2luIHNjcmVlbiBwb2ludCwgaW4gcGl4ZWxzLlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcG9pbnRDb29yZGluYXRlM0QocDogUG9pbnQpOiBNZXJjYXRvckNvb3JkaW5hdGUge1xuICAgICAgICBpZiAoIXRoaXMuZWxldmF0aW9uKSByZXR1cm4gdGhpcy5wb2ludENvb3JkaW5hdGUocCk7XG4gICAgICAgIGxldCByYXljYXN0OiA/VmVjMyA9IHRoaXMucHJvamVjdGlvbi5wb2ludENvb3JkaW5hdGUzRCh0aGlzLCBwLngsIHAueSk7XG4gICAgICAgIGlmIChyYXljYXN0KSByZXR1cm4gbmV3IE1lcmNhdG9yQ29vcmRpbmF0ZShyYXljYXN0WzBdLCByYXljYXN0WzFdLCByYXljYXN0WzJdKTtcbiAgICAgICAgbGV0IHN0YXJ0ID0gMCwgZW5kID0gdGhpcy5ob3Jpem9uTGluZUZyb21Ub3AoKTtcbiAgICAgICAgaWYgKHAueSA+IGVuZCkgcmV0dXJuIHRoaXMucG9pbnRDb29yZGluYXRlKHApOyAvLyBob2xlcyBiZXR3ZWVuIHRpbGVzIGJlbG93IGhvcml6b24gbGluZSBvciBiZWxvdyBib3R0b20uXG4gICAgICAgIGNvbnN0IHNhbXBsZXMgPSAxMDtcbiAgICAgICAgY29uc3QgdGhyZXNob2xkID0gMC4wMiAqIGVuZDtcbiAgICAgICAgY29uc3QgciA9IHAuY2xvbmUoKTtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNhbXBsZXMgJiYgZW5kIC0gc3RhcnQgPiB0aHJlc2hvbGQ7IGkrKykge1xuICAgICAgICAgICAgci55ID0gaW50ZXJwb2xhdGUoc3RhcnQsIGVuZCwgMC42Nik7IC8vIG5vbiB1bmlmb3JtIGJpbmFyeSBzZWFyY2ggZmF2b3JpbmcgcG9pbnRzIGNsb3NlciB0byBob3Jpem9uLlxuICAgICAgICAgICAgY29uc3QgckNhc3QgPSB0aGlzLnByb2plY3Rpb24ucG9pbnRDb29yZGluYXRlM0QodGhpcywgci54LCByLnkpO1xuICAgICAgICAgICAgaWYgKHJDYXN0KSB7XG4gICAgICAgICAgICAgICAgZW5kID0gci55O1xuICAgICAgICAgICAgICAgIHJheWNhc3QgPSByQ2FzdDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RhcnQgPSByLnk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJheWNhc3QgPyBuZXcgTWVyY2F0b3JDb29yZGluYXRlKHJheWNhc3RbMF0sIHJheWNhc3RbMV0sIHJheWNhc3RbMl0pIDogdGhpcy5wb2ludENvb3JkaW5hdGUocCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0cnVlIGlmIGEgc2NyZWVuc3BhY2UgUG9pbnQgcCwgaXMgYWJvdmUgdGhlIGhvcml6b24uXG4gICAgICogSW4gbm9uLWdsb2JlIHByb2plY3Rpb25zLCB0aGlzIGFwcHJveGltYXRlcyB0aGUgbWFwIGFzIGFuIGluZmluaXRlIHBsYW5lIGFuZCBkb2VzIG5vdCBhY2NvdW50IGZvciB6MC16M1xuICAgICAqIHdoZXJlaW4gdGhlIG1hcCBpcyBzbWFsbCBxdWFkIHdpdGggd2hpdGVzcGFjZSBhYm92ZSB0aGUgbm9ydGggcG9sZSBhbmQgYmVsb3cgdGhlIHNvdXRoIHBvbGUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1BvaW50fSBwXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBpc1BvaW50QWJvdmVIb3Jpem9uKHA6IFBvaW50KTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLnByb2plY3Rpb24uaXNQb2ludEFib3ZlSG9yaXpvbih0aGlzLCBwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZXRlcm1pbmVzIGlmIHRoZSBnaXZlbiBwb2ludCBpcyBsb2NhdGVkIG9uIGEgdmlzaWJsZSBtYXAgc3VyZmFjZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7UG9pbnR9IHBcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIGlzUG9pbnRPblN1cmZhY2UocDogUG9pbnQpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKHAueSA8IDAgfHwgcC55ID4gdGhpcy5oZWlnaHQgfHwgcC54IDwgMCB8fCBwLnggPiB0aGlzLndpZHRoKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmICh0aGlzLmVsZXZhdGlvbiB8fCB0aGlzLnpvb20gPj0gR0xPQkVfWk9PTV9USFJFU0hPTERfTUFYKSByZXR1cm4gIXRoaXMuaXNQb2ludEFib3ZlSG9yaXpvbihwKTtcbiAgICAgICAgY29uc3QgY29vcmQgPSB0aGlzLnBvaW50Q29vcmRpbmF0ZShwKTtcbiAgICAgICAgcmV0dXJuIGNvb3JkLnkgPj0gMCAmJiBjb29yZC55IDw9IDE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2l2ZW4gYSBjb29yZGluYXRlLCByZXR1cm4gdGhlIHNjcmVlbiBwb2ludCB0aGF0IGNvcnJlc3BvbmRzIHRvIGl0XG4gICAgICogQHBhcmFtIHtDb29yZGluYXRlfSBjb29yZFxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gc2FtcGxlVGVycmFpbkluM0QgaW4gM0QgbW9kZSAodGVycmFpbiBlbmFibGVkKSwgc2FtcGxlIGVsZXZhdGlvbiBmb3IgdGhlIHBvaW50LlxuICAgICAqIElmIGZhbHNlLCBkbyB0aGUgc2FtZSBhcyBpbiAyRCBtb2RlLCBhc3N1bWUgZmxhdCBjYW1lcmEgZWxldmF0aW9uIHBsYW5lIGZvciBhbGwgcG9pbnRzLlxuICAgICAqIEByZXR1cm5zIHtQb2ludH0gc2NyZWVuIHBvaW50XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBfY29vcmRpbmF0ZVBvaW50KGNvb3JkOiBNZXJjYXRvckNvb3JkaW5hdGUsIHNhbXBsZVRlcnJhaW5JbjNEOiBib29sZWFuKTogUG9pbnQge1xuICAgICAgICBjb25zdCBlbGV2YXRpb24gPSBzYW1wbGVUZXJyYWluSW4zRCAmJiB0aGlzLmVsZXZhdGlvbiA/IHRoaXMuZWxldmF0aW9uLmdldEF0UG9pbnRPclplcm8oY29vcmQsIHRoaXMuX2NlbnRlckFsdGl0dWRlKSA6IHRoaXMuX2NlbnRlckFsdGl0dWRlO1xuICAgICAgICBjb25zdCBwID0gW2Nvb3JkLnggKiB0aGlzLndvcmxkU2l6ZSwgY29vcmQueSAqIHRoaXMud29ybGRTaXplLCBlbGV2YXRpb24gKyBjb29yZC50b0FsdGl0dWRlKCksIDFdO1xuICAgICAgICB2ZWM0LnRyYW5zZm9ybU1hdDQocCwgcCwgdGhpcy5waXhlbE1hdHJpeCk7XG4gICAgICAgIHJldHVybiBwWzNdID4gMCA/XG4gICAgICAgICAgICBuZXcgUG9pbnQocFswXSAvIHBbM10sIHBbMV0gLyBwWzNdKSA6XG4gICAgICAgICAgICBuZXcgUG9pbnQoTnVtYmVyLk1BWF9WQUxVRSwgTnVtYmVyLk1BWF9WQUxVRSk7XG4gICAgfVxuXG4gICAgLy8gSW4gR2xvYmUsIGNvbmljIGFuZCB0aGVtYXRpYyBwcm9qZWN0aW9ucywgTG5nL0xhdCBleHRyZW1lcyBhcmUgbm90IGFsd2F5cyBhdCBjb3JuZXJzLlxuICAgIC8vIFRoaXMgZnVuY3Rpb24gYWRkaXRpb25hbGx5IGNoZWNrcyBlYWNoIHNjcmVlbiBlZGdlIG1pZHBvaW50LlxuICAgIC8vIFdoaWxlIG1pZHBvaW50cyBjb250aW51ZSB0byBiZSBleHRyZW1lcywgaXQgcmVjdXJzaXZlbHkgY2hlY2tzIG1pZHBvaW50cyBvZiBzbWFsbGVyIHNlZ21lbnRzLlxuICAgIF9nZXRCb3VuZHNOb25SZWN0YW5ndWxhcigpOiBMbmdMYXRCb3VuZHMge1xuICAgICAgICBhc3NlcnQoIXRoaXMucHJvamVjdGlvbi5zdXBwb3J0c1dvcmxkQ29waWVzLCBcIlJlY3Rhbmd1bGFyIHByb2plY3Rpb25zIHNob3VsZCB1c2UgdGhlIHNpbXBsZXIgX2dldEJvdW5kc1JlY3Rhbmd1bGFyXCIpO1xuICAgICAgICBjb25zdCB7dG9wLCBsZWZ0fSA9IHRoaXMuX2VkZ2VJbnNldHM7XG4gICAgICAgIGNvbnN0IGJvdHRvbSA9IHRoaXMuaGVpZ2h0IC0gdGhpcy5fZWRnZUluc2V0cy5ib3R0b207XG4gICAgICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy53aWR0aCAtIHRoaXMuX2VkZ2VJbnNldHMucmlnaHQ7XG5cbiAgICAgICAgY29uc3QgdGwgPSB0aGlzLnBvaW50TG9jYXRpb24zRChuZXcgUG9pbnQobGVmdCwgdG9wKSk7XG4gICAgICAgIGNvbnN0IHRyID0gdGhpcy5wb2ludExvY2F0aW9uM0QobmV3IFBvaW50KHJpZ2h0LCB0b3ApKTtcbiAgICAgICAgY29uc3QgYnIgPSB0aGlzLnBvaW50TG9jYXRpb24zRChuZXcgUG9pbnQocmlnaHQsIGJvdHRvbSkpO1xuICAgICAgICBjb25zdCBibCA9IHRoaXMucG9pbnRMb2NhdGlvbjNEKG5ldyBQb2ludChsZWZ0LCBib3R0b20pKTtcblxuICAgICAgICBsZXQgd2VzdCA9IE1hdGgubWluKHRsLmxuZywgdHIubG5nLCBici5sbmcsIGJsLmxuZyk7XG4gICAgICAgIGxldCBlYXN0ID0gTWF0aC5tYXgodGwubG5nLCB0ci5sbmcsIGJyLmxuZywgYmwubG5nKTtcbiAgICAgICAgbGV0IHNvdXRoID0gTWF0aC5taW4odGwubGF0LCB0ci5sYXQsIGJyLmxhdCwgYmwubGF0KTtcbiAgICAgICAgbGV0IG5vcnRoID0gTWF0aC5tYXgodGwubGF0LCB0ci5sYXQsIGJyLmxhdCwgYmwubGF0KTtcblxuICAgICAgICAvLyB3ZSBwaWNrIGFuIGVycm9yIHRocmVzaG9sZCBmb3IgY2FsY3VsYXRpbmcgdGhlIGJib3ggdGhhdCBiYWxhbmNlcyBiZXR3ZWVuIHBlcmZvcm1hbmNlIGFuZCBwcmVjaXNpb25cbiAgICAgICAgLy8gUm91Z2hseSBlbXVsYXRpbmcgYmVoYXZpb3Igb2YgbWF4RXJyIGluIHRpbGVfdHJhbnNmb3JtLmpzXG4gICAgICAgIGNvbnN0IHMgPSBNYXRoLnBvdygyLCAtdGhpcy56b29tKTtcbiAgICAgICAgY29uc3QgbWF4RXJyID0gcyAvIDE2ICogMjcwOyAvLyAyNzAgPSBhdmcoMTgwLCAzNjApIGkuZS4gcm91Z2ggY29udmVyc2lvbiBiZXR3ZWVuIE1lcmNhdG9yIGNvb3JkcyBhbmQgTGF0L0xuZ1xuXG4gICAgICAgIC8vIFdlIGNoZWNrIGEgbWluaW11bSBvZiAxNSBwb2ludHMgb24gZWFjaCBzaWRlIGZvciBBbGJlcnMsIGV0Yy5cbiAgICAgICAgLy8gV2UgY2hlY2sgYSBtaW5tdW0gb2Ygb25lIG1pZHBvaW50IG9uIGVhY2ggc2lkZSBwZXIgZ2xvYmUuXG4gICAgICAgIC8vIEdsb2JlIGNoZWNrcyByZXF1aXJlIHJheXRyYWNpbmcgYW5kIGFyZSBzbG93ZXJcbiAgICAgICAgLy8gYW5kIG1pc2luZyBhcmVhIG5lYXIgdGhlIGhvcml6b24gaXMgaGlnaGx5IGNvbXByZXNzZWQgc28gbm90IG5vdGljZWFibGVcbiAgICAgICAgY29uc3QgbWluUmVjdXJzaW9ucyA9IHRoaXMucHJvamVjdGlvbi5uYW1lID09PSBcImdsb2JlXCIgPyAxIDogNDtcblxuICAgICAgICBjb25zdCBwcm9jZXNzU2VnbWVudCA9IChheDogbnVtYmVyLCBheTogbnVtYmVyLCBieDogbnVtYmVyLCBieTogbnVtYmVyLCBkZXB0aDogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBteCA9IChheCArIGJ4KSAvIDI7XG4gICAgICAgICAgICBjb25zdCBteSA9IChheSArIGJ5KSAvIDI7XG5cbiAgICAgICAgICAgIGNvbnN0IHAgPSBuZXcgUG9pbnQobXgsIG15KTtcbiAgICAgICAgICAgIGNvbnN0IHtsbmcsIGxhdH0gPSB0aGlzLnBvaW50TG9jYXRpb24zRChwKTtcblxuICAgICAgICAgICAgLy8gVGhlIGVycm9yIG1ldHJpYyBpcyB0aGUgbWF4aW11bSBjaGFuZ2UgdG8gYm91bmRzIGZyb20gYSBnaXZlbiBwb2ludFxuICAgICAgICAgICAgY29uc3QgZXJyID0gTWF0aC5tYXgoMCwgd2VzdCAtIGxuZywgc291dGggLSBsYXQsIGxuZyAtIGVhc3QsIGxhdCAtIG5vcnRoKTtcblxuICAgICAgICAgICAgd2VzdCA9IE1hdGgubWluKHdlc3QsIGxuZyk7XG4gICAgICAgICAgICBlYXN0ID0gTWF0aC5tYXgoZWFzdCwgbG5nKTtcbiAgICAgICAgICAgIHNvdXRoID0gTWF0aC5taW4oc291dGgsIGxhdCk7XG4gICAgICAgICAgICBub3J0aCA9IE1hdGgubWF4KG5vcnRoLCBsYXQpO1xuXG4gICAgICAgICAgICBpZiAoZGVwdGggPCBtaW5SZWN1cnNpb25zIHx8IGVyciA+IG1heEVycikge1xuICAgICAgICAgICAgICAgIHByb2Nlc3NTZWdtZW50KGF4LCBheSwgbXgsIG15LCBkZXB0aCArIDEpO1xuICAgICAgICAgICAgICAgIHByb2Nlc3NTZWdtZW50KG14LCBteSwgYngsIGJ5LCBkZXB0aCArIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHByb2Nlc3NTZWdtZW50KGxlZnQsIHRvcCwgcmlnaHQsIHRvcCwgMSk7XG4gICAgICAgIHByb2Nlc3NTZWdtZW50KHJpZ2h0LCB0b3AsIHJpZ2h0LCBib3R0b20sIDEpO1xuICAgICAgICBwcm9jZXNzU2VnbWVudChyaWdodCwgYm90dG9tLCBsZWZ0LCBib3R0b20sIDEpO1xuICAgICAgICBwcm9jZXNzU2VnbWVudChsZWZ0LCBib3R0b20sIGxlZnQsIHRvcCwgMSk7XG5cbiAgICAgICAgaWYgKHRoaXMucHJvamVjdGlvbi5uYW1lID09PSBcImdsb2JlXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IFtub3J0aFBvbGVJc1Zpc2libGUsIHNvdXRoUG9sZUlzVmlzaWJsZV0gPSBwb2xlc0luVmlld3BvcnQodGhpcyk7XG4gICAgICAgICAgICBpZiAobm9ydGhQb2xlSXNWaXNpYmxlKSB7XG4gICAgICAgICAgICAgICAgbm9ydGggPSA5MDtcbiAgICAgICAgICAgICAgICBlYXN0ID0gMTgwO1xuICAgICAgICAgICAgICAgIHdlc3QgPSAtMTgwO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzb3V0aFBvbGVJc1Zpc2libGUpIHtcbiAgICAgICAgICAgICAgICBzb3V0aCA9IC05MDtcbiAgICAgICAgICAgICAgICBlYXN0ID0gMTgwO1xuICAgICAgICAgICAgICAgIHdlc3QgPSAtMTgwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBMbmdMYXRCb3VuZHMobmV3IExuZ0xhdCh3ZXN0LCBzb3V0aCksIG5ldyBMbmdMYXQoZWFzdCwgbm9ydGgpKTtcbiAgICB9XG5cbiAgICBfZ2V0Qm91bmRzUmVjdGFuZ3VsYXIobWluOiBudW1iZXIsIG1heDogbnVtYmVyKTogTG5nTGF0Qm91bmRzIHtcbiAgICAgICAgYXNzZXJ0KHRoaXMucHJvamVjdGlvbi5zdXBwb3J0c1dvcmxkQ29waWVzLCBcIl9nZXRCb3VuZHNSZWN0YW5ndWxhciBvbmx5IGNoZWNrcyBjb3JuZXJzIGFuZCB3b3JrcyBvbmx5IG9uIHJlY3Rhbmd1bGFyIHByb2plY3Rpb25zLiBPdGhlciBwcm9qZWN0aW9ucyBzaG91bGQgdXNlIF9nZXRCb3VuZHNOb25SZWN0YW5ndWxhclwiKTtcblxuICAgICAgICBjb25zdCB7dG9wLCBsZWZ0fSA9IHRoaXMuX2VkZ2VJbnNldHM7XG4gICAgICAgIGNvbnN0IGJvdHRvbSA9IHRoaXMuaGVpZ2h0IC0gdGhpcy5fZWRnZUluc2V0cy5ib3R0b207XG4gICAgICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy53aWR0aCAtIHRoaXMuX2VkZ2VJbnNldHMucmlnaHQ7XG5cbiAgICAgICAgY29uc3QgdG9wTGVmdCA9IG5ldyBQb2ludChsZWZ0LCB0b3ApO1xuICAgICAgICBjb25zdCB0b3BSaWdodCA9IG5ldyBQb2ludChyaWdodCwgdG9wKTtcbiAgICAgICAgY29uc3QgYm90dG9tUmlnaHQgPSBuZXcgUG9pbnQocmlnaHQsIGJvdHRvbSk7XG4gICAgICAgIGNvbnN0IGJvdHRvbUxlZnQgPSBuZXcgUG9pbnQobGVmdCwgYm90dG9tKTtcblxuICAgICAgICAvLyBDb25zaWRlciBmYXIgcG9pbnRzIGF0IHRoZSBtYXhpbXVtIHBvc3NpYmxlIGVsZXZhdGlvblxuICAgICAgICAvLyBhbmQgbmVhciBwb2ludHMgYXQgdGhlIG1pbmltdW0gdG8gZW5zdXJlIGZ1bGwgY292ZXJhZ2UuXG4gICAgICAgIGxldCB0bCA9IHRoaXMucG9pbnRDb29yZGluYXRlKHRvcExlZnQsIG1pbik7XG4gICAgICAgIGxldCB0ciA9IHRoaXMucG9pbnRDb29yZGluYXRlKHRvcFJpZ2h0LCBtaW4pO1xuICAgICAgICBjb25zdCBiciA9IHRoaXMucG9pbnRDb29yZGluYXRlKGJvdHRvbVJpZ2h0LCBtYXgpO1xuICAgICAgICBjb25zdCBibCA9IHRoaXMucG9pbnRDb29yZGluYXRlKGJvdHRvbUxlZnQsIG1heCk7XG5cbiAgICAgICAgLy8gSWYgbWFwIHBpdGNoIHBsYWNlcyB0b3AgY29ybmVycyBvZmYgbWFwIGVkZ2UgKGxhdGl0dWRlID4gOTAgb3IgPCAtOTApLFxuICAgICAgICAvLyBwbGFjZSB0aGVtIGF0IHRoZSBpbnRlcnNlY3Rpb24gYmV0d2VlbiB0aGUgbGVmdC9yaWdodCBzY3JlZW4gZWRnZSBhbmQgbWFwIGVkZ2UuXG4gICAgICAgIGNvbnN0IHNsb3BlID0gKHAxOiBNZXJjYXRvckNvb3JkaW5hdGUsIHAyOiBNZXJjYXRvckNvb3JkaW5hdGUpID0+IChwMi55IC0gcDEueSkgLyAocDIueCAtIHAxLngpO1xuXG4gICAgICAgIGlmICh0bC55ID4gMSAmJiB0ci55ID49IDApIHRsID0gbmV3IE1lcmNhdG9yQ29vcmRpbmF0ZSgoMSAtIGJsLnkpIC8gc2xvcGUoYmwsIHRsKSArIGJsLngsIDEpO1xuICAgICAgICBlbHNlIGlmICh0bC55IDwgMCAmJiB0ci55IDw9IDEpIHRsID0gbmV3IE1lcmNhdG9yQ29vcmRpbmF0ZSgtYmwueSAvIHNsb3BlKGJsLCB0bCkgKyBibC54LCAwKTtcblxuICAgICAgICBpZiAodHIueSA+IDEgJiYgdGwueSA+PSAwKSB0ciA9IG5ldyBNZXJjYXRvckNvb3JkaW5hdGUoKDEgLSBici55KSAvIHNsb3BlKGJyLCB0cikgKyBici54LCAxKTtcbiAgICAgICAgZWxzZSBpZiAodHIueSA8IDAgJiYgdGwueSA8PSAxKSB0ciA9IG5ldyBNZXJjYXRvckNvb3JkaW5hdGUoLWJyLnkgLyBzbG9wZShiciwgdHIpICsgYnIueCwgMCk7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBMbmdMYXRCb3VuZHMoKVxuICAgICAgICAgICAgLmV4dGVuZCh0aGlzLmNvb3JkaW5hdGVMb2NhdGlvbih0bCkpXG4gICAgICAgICAgICAuZXh0ZW5kKHRoaXMuY29vcmRpbmF0ZUxvY2F0aW9uKHRyKSlcbiAgICAgICAgICAgIC5leHRlbmQodGhpcy5jb29yZGluYXRlTG9jYXRpb24oYmwpKVxuICAgICAgICAgICAgLmV4dGVuZCh0aGlzLmNvb3JkaW5hdGVMb2NhdGlvbihicikpO1xuICAgIH1cblxuICAgIF9nZXRCb3VuZHNSZWN0YW5ndWxhclRlcnJhaW4oKTogTG5nTGF0Qm91bmRzIHtcbiAgICAgICAgYXNzZXJ0KHRoaXMuZWxldmF0aW9uKTtcbiAgICAgICAgY29uc3QgZWxldmF0aW9uID0gKCh0aGlzLmVsZXZhdGlvbjogYW55KTogRWxldmF0aW9uKTtcbiAgICAgICAgaWYgKCFlbGV2YXRpb24udmlzaWJsZURlbVRpbGVzLmxlbmd0aCB8fCBlbGV2YXRpb24uaXNVc2luZ01vY2tTb3VyY2UoKSkgeyByZXR1cm4gdGhpcy5fZ2V0Qm91bmRzUmVjdGFuZ3VsYXIoMCwgMCk7IH1cbiAgICAgICAgY29uc3QgbWlubWF4ID0gZWxldmF0aW9uLnZpc2libGVEZW1UaWxlcy5yZWR1Y2UoKGFjYywgdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHQuZGVtKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdHJlZSA9IHQuZGVtLnRyZWU7XG4gICAgICAgICAgICAgICAgYWNjLm1pbiA9IE1hdGgubWluKGFjYy5taW4sIHRyZWUubWluaW11bXNbMF0pO1xuICAgICAgICAgICAgICAgIGFjYy5tYXggPSBNYXRoLm1heChhY2MubWF4LCB0cmVlLm1heGltdW1zWzBdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgIH0sIHttaW46IE51bWJlci5NQVhfVkFMVUUsIG1heDogMH0pO1xuICAgICAgICBhc3NlcnQobWlubWF4Lm1pbiAhPT0gTnVtYmVyLk1BWF9WQUxVRSk7XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRCb3VuZHNSZWN0YW5ndWxhcihtaW5tYXgubWluICogZWxldmF0aW9uLmV4YWdnZXJhdGlvbigpLCBtaW5tYXgubWF4ICogZWxldmF0aW9uLmV4YWdnZXJhdGlvbigpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBtYXAncyBnZW9ncmFwaGljYWwgYm91bmRzLiBXaGVuIHRoZSBiZWFyaW5nIG9yIHBpdGNoIGlzIG5vbi16ZXJvLCB0aGUgdmlzaWJsZSByZWdpb24gaXMgbm90XG4gICAgICogYW4gYXhpcy1hbGlnbmVkIHJlY3RhbmdsZSwgYW5kIHRoZSByZXN1bHQgaXMgdGhlIHNtYWxsZXN0IGJvdW5kcyB0aGF0IGVuY29tcGFzc2VzIHRoZSB2aXNpYmxlIHJlZ2lvbi5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtMbmdMYXRCb3VuZHN9IFJldHVybnMgYSB7QGxpbmsgTG5nTGF0Qm91bmRzfSBvYmplY3QgZGVzY3JpYmluZyB0aGUgbWFwJ3MgZ2VvZ3JhcGhpY2FsIGJvdW5kcy5cbiAgICAgKi9cbiAgICBnZXRCb3VuZHMoKTogTG5nTGF0Qm91bmRzIHtcbiAgICAgICAgaWYgKHRoaXMucHJvamVjdGlvbi5uYW1lID09PSAnbWVyY2F0b3InIHx8IHRoaXMucHJvamVjdGlvbi5uYW1lID09PSAnZXF1aXJlY3Rhbmd1bGFyJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3RlcnJhaW5FbmFibGVkKCkpIHJldHVybiB0aGlzLl9nZXRCb3VuZHNSZWN0YW5ndWxhclRlcnJhaW4oKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRCb3VuZHNSZWN0YW5ndWxhcigwLCAwKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0Qm91bmRzTm9uUmVjdGFuZ3VsYXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHBvc2l0aW9uIG9mIGhvcml6b24gbGluZSBmcm9tIHRoZSB0b3Agb2YgdGhlIG1hcCBpbiBwaXhlbHMuXG4gICAgICogSWYgaG9yaXpvbiBpcyBub3QgdmlzaWJsZSwgcmV0dXJucyAwIGJ5IGRlZmF1bHQgb3IgYSBuZWdhdGl2ZSB2YWx1ZSBpZiBjYWxsZWQgd2l0aCBjbGFtcFRvVG9wID0gZmFsc2UuXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBob3Jpem9uTGluZUZyb21Ub3AoY2xhbXBUb1RvcDogYm9vbGVhbiA9IHRydWUpOiBudW1iZXIge1xuICAgICAgICAvLyBoIGlzIGhlaWdodCBvZiBzcGFjZSBhYm92ZSBtYXAgY2VudGVyIHRvIGhvcml6b24uXG4gICAgICAgIGNvbnN0IGggPSB0aGlzLmhlaWdodCAvIDIgLyBNYXRoLnRhbih0aGlzLl9mb3YgLyAyKSAvIE1hdGgudGFuKE1hdGgubWF4KHRoaXMuX3BpdGNoLCAwLjEpKSArIHRoaXMuY2VudGVyT2Zmc2V0Lnk7XG4gICAgICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuaGVpZ2h0IC8gMiAtIGggKiAoMSAtIHRoaXMuX2hvcml6b25TaGlmdCk7XG4gICAgICAgIHJldHVybiBjbGFtcFRvVG9wID8gTWF0aC5tYXgoMCwgb2Zmc2V0KSA6IG9mZnNldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBtYXhpbXVtIGdlb2dyYXBoaWNhbCBib3VuZHMgdGhlIG1hcCBpcyBjb25zdHJhaW5lZCB0bywgb3IgYG51bGxgIGlmIG5vbmUgc2V0LlxuICAgICAqIEByZXR1cm5zIHtMbmdMYXRCb3VuZHN9IHtAbGluayBMbmdMYXRCb3VuZHN9LlxuICAgICAqL1xuICAgIGdldE1heEJvdW5kcygpOiA/TG5nTGF0Qm91bmRzIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWF4Qm91bmRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgb3IgY2xlYXJzIHRoZSBtYXAncyBnZW9ncmFwaGljYWwgY29uc3RyYWludHMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0xuZ0xhdEJvdW5kc30gYm91bmRzIEEge0BsaW5rIExuZ0xhdEJvdW5kc30gb2JqZWN0IGRlc2NyaWJpbmcgdGhlIG5ldyBnZW9ncmFwaGljIGJvdW5kYXJpZXMgb2YgdGhlIG1hcC5cbiAgICAgKi9cbiAgICBzZXRNYXhCb3VuZHMoYm91bmRzOiA/TG5nTGF0Qm91bmRzKSB7XG4gICAgICAgIHRoaXMubWF4Qm91bmRzID0gYm91bmRzO1xuXG4gICAgICAgIHRoaXMubWluTGF0ID0gLU1BWF9NRVJDQVRPUl9MQVRJVFVERTtcbiAgICAgICAgdGhpcy5tYXhMYXQgPSBNQVhfTUVSQ0FUT1JfTEFUSVRVREU7XG4gICAgICAgIHRoaXMubWluTG5nID0gLTE4MDtcbiAgICAgICAgdGhpcy5tYXhMbmcgPSAxODA7XG5cbiAgICAgICAgaWYgKGJvdW5kcykge1xuICAgICAgICAgICAgdGhpcy5taW5MYXQgPSBib3VuZHMuZ2V0U291dGgoKTtcbiAgICAgICAgICAgIHRoaXMubWF4TGF0ID0gYm91bmRzLmdldE5vcnRoKCk7XG4gICAgICAgICAgICB0aGlzLm1pbkxuZyA9IGJvdW5kcy5nZXRXZXN0KCk7XG4gICAgICAgICAgICB0aGlzLm1heExuZyA9IGJvdW5kcy5nZXRFYXN0KCk7XG4gICAgICAgICAgICBpZiAodGhpcy5tYXhMbmcgPCB0aGlzLm1pbkxuZykgdGhpcy5tYXhMbmcgKz0gMzYwO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy53b3JsZE1pblggPSBtZXJjYXRvclhmcm9tTG5nKHRoaXMubWluTG5nKSAqIHRoaXMudGlsZVNpemU7XG4gICAgICAgIHRoaXMud29ybGRNYXhYID0gbWVyY2F0b3JYZnJvbUxuZyh0aGlzLm1heExuZykgKiB0aGlzLnRpbGVTaXplO1xuICAgICAgICB0aGlzLndvcmxkTWluWSA9IG1lcmNhdG9yWWZyb21MYXQodGhpcy5tYXhMYXQpICogdGhpcy50aWxlU2l6ZTtcbiAgICAgICAgdGhpcy53b3JsZE1heFkgPSBtZXJjYXRvcllmcm9tTGF0KHRoaXMubWluTGF0KSAqIHRoaXMudGlsZVNpemU7XG5cbiAgICAgICAgdGhpcy5fY29uc3RyYWluKCk7XG4gICAgfVxuXG4gICAgY2FsY3VsYXRlUG9zTWF0cml4KHVud3JhcHBlZFRpbGVJRDogVW53cmFwcGVkVGlsZUlELCB3b3JsZFNpemU6IG51bWJlcik6IEZsb2F0NjRBcnJheSB7XG4gICAgICAgIHJldHVybiB0aGlzLnByb2plY3Rpb24uY3JlYXRlVGlsZU1hdHJpeCh0aGlzLCB3b3JsZFNpemUsIHVud3JhcHBlZFRpbGVJRCk7XG4gICAgfVxuXG4gICAgY2FsY3VsYXRlRGlzdGFuY2VUaWxlRGF0YSh1bndyYXBwZWRUaWxlSUQ6IFVud3JhcHBlZFRpbGVJRCk6IEZlYXR1cmVEaXN0YW5jZURhdGEge1xuICAgICAgICBjb25zdCBkaXN0YW5jZURhdGFLZXkgPSB1bndyYXBwZWRUaWxlSUQua2V5O1xuICAgICAgICBjb25zdCBjYWNoZSA9IHRoaXMuX2Rpc3RhbmNlVGlsZURhdGFDYWNoZTtcbiAgICAgICAgaWYgKGNhY2hlW2Rpc3RhbmNlRGF0YUtleV0pIHtcbiAgICAgICAgICAgIHJldHVybiBjYWNoZVtkaXN0YW5jZURhdGFLZXldO1xuICAgICAgICB9XG5cbiAgICAgICAgLy9DYWxjdWxhdGUgdGhlIG9mZnNldCBvZiB0aGUgdGlsZVxuICAgICAgICBjb25zdCBjYW5vbmljYWwgPSB1bndyYXBwZWRUaWxlSUQuY2Fub25pY2FsO1xuICAgICAgICBjb25zdCB3aW5kb3dTY2FsZUZhY3RvciA9IDEgLyB0aGlzLmhlaWdodDtcbiAgICAgICAgY29uc3QgY3dzID0gdGhpcy5jYW1lcmFXb3JsZFNpemU7XG4gICAgICAgIGNvbnN0IHNjYWxlID0gY3dzIC8gdGhpcy56b29tU2NhbGUoY2Fub25pY2FsLnopO1xuICAgICAgICBjb25zdCB1bndyYXBwZWRYID0gY2Fub25pY2FsLnggKyBNYXRoLnBvdygyLCBjYW5vbmljYWwueikgKiB1bndyYXBwZWRUaWxlSUQud3JhcDtcbiAgICAgICAgY29uc3QgdFggPSB1bndyYXBwZWRYICogc2NhbGU7XG4gICAgICAgIGNvbnN0IHRZID0gY2Fub25pY2FsLnkgKiBzY2FsZTtcblxuICAgICAgICBjb25zdCBjZW50ZXIgPSB0aGlzLnBvaW50O1xuICAgICAgICAvLyBjZW50ZXIgaXMgaW4gd29ybGQvcGl4ZWwgY29vcmRpbmF0ZSwgZW5zdXJlIGl0J3MgaW4gdGhlIHNhbWUgY29vcmRpbmF0ZSBzcGFjZSBhcyB0WCBhbmQgdFkgY29tcHV0ZWQgZWFybGllci5cbiAgICAgICAgY2VudGVyLnggKj0gY3dzIC8gdGhpcy53b3JsZFNpemU7XG4gICAgICAgIGNlbnRlci55ICo9IGN3cyAvIHRoaXMud29ybGRTaXplO1xuXG4gICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgYmVhcmluZyB2ZWN0b3IgYnkgcm90YXRpbmcgdW5pdCB2ZWN0b3IgWzAsIC0xXSBjbG9ja3dpc2VcbiAgICAgICAgY29uc3QgYW5nbGUgPSB0aGlzLmFuZ2xlO1xuICAgICAgICBjb25zdCBiWCA9IE1hdGguc2luKC1hbmdsZSk7XG4gICAgICAgIGNvbnN0IGJZID0gLU1hdGguY29zKC1hbmdsZSk7XG5cbiAgICAgICAgY29uc3QgY1ggPSAoY2VudGVyLnggLSB0WCkgKiB3aW5kb3dTY2FsZUZhY3RvcjtcbiAgICAgICAgY29uc3QgY1kgPSAoY2VudGVyLnkgLSB0WSkgKiB3aW5kb3dTY2FsZUZhY3RvcjtcbiAgICAgICAgY2FjaGVbZGlzdGFuY2VEYXRhS2V5XSA9IHtcbiAgICAgICAgICAgIGJlYXJpbmc6IFtiWCwgYlldLFxuICAgICAgICAgICAgY2VudGVyOiBbY1gsIGNZXSxcbiAgICAgICAgICAgIHNjYWxlOiAoc2NhbGUgLyBFWFRFTlQpICogd2luZG93U2NhbGVGYWN0b3JcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4gY2FjaGVbZGlzdGFuY2VEYXRhS2V5XTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxjdWxhdGUgdGhlIGZvZ1RpbGVNYXRyaXggdGhhdCwgZ2l2ZW4gYSB0aWxlIGNvb3JkaW5hdGUsIGNhbiBiZSB1c2VkIHRvXG4gICAgICogY2FsY3VsYXRlIGl0cyBwb3NpdGlvbiByZWxhdGl2ZSB0byB0aGUgY2FtZXJhIGluIHVuaXRzIG9mIHBpeGVscyBkaXZpZGVkXG4gICAgICogYnkgdGhlIG1hcCBoZWlnaHQuIFVzZWQgd2l0aCBmb2cgZm9yIGNvbnNpc3RlbnQgY29tcHV0YXRpb24gb2YgZGlzdGFuY2VcbiAgICAgKiBmcm9tIGNhbWVyYS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7VW53cmFwcGVkVGlsZUlEfSB1bndyYXBwZWRUaWxlSUQ7XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBjYWxjdWxhdGVGb2dUaWxlTWF0cml4KHVud3JhcHBlZFRpbGVJRDogVW53cmFwcGVkVGlsZUlEKTogRmxvYXQzMkFycmF5IHtcbiAgICAgICAgY29uc3QgZm9nVGlsZU1hdHJpeEtleSA9IHVud3JhcHBlZFRpbGVJRC5rZXk7XG4gICAgICAgIGNvbnN0IGNhY2hlID0gdGhpcy5fZm9nVGlsZU1hdHJpeENhY2hlO1xuICAgICAgICBpZiAoY2FjaGVbZm9nVGlsZU1hdHJpeEtleV0pIHtcbiAgICAgICAgICAgIHJldHVybiBjYWNoZVtmb2dUaWxlTWF0cml4S2V5XTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHBvc01hdHJpeCA9IHRoaXMucHJvamVjdGlvbi5jcmVhdGVUaWxlTWF0cml4KHRoaXMsIHRoaXMuY2FtZXJhV29ybGRTaXplRm9yRm9nLCB1bndyYXBwZWRUaWxlSUQpO1xuICAgICAgICBtYXQ0Lm11bHRpcGx5KHBvc01hdHJpeCwgdGhpcy53b3JsZFRvRm9nTWF0cml4LCBwb3NNYXRyaXgpO1xuXG4gICAgICAgIGNhY2hlW2ZvZ1RpbGVNYXRyaXhLZXldID0gbmV3IEZsb2F0MzJBcnJheShwb3NNYXRyaXgpO1xuICAgICAgICByZXR1cm4gY2FjaGVbZm9nVGlsZU1hdHJpeEtleV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlIHRoZSBwcm9qTWF0cml4IHRoYXQsIGdpdmVuIGEgdGlsZSBjb29yZGluYXRlLCB3b3VsZCBiZSB1c2VkIHRvIGRpc3BsYXkgdGhlIHRpbGUgb24gdGhlIHNjcmVlbi5cbiAgICAgKiBAcGFyYW0ge1Vud3JhcHBlZFRpbGVJRH0gdW53cmFwcGVkVGlsZUlEO1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgY2FsY3VsYXRlUHJvak1hdHJpeCh1bndyYXBwZWRUaWxlSUQ6IFVud3JhcHBlZFRpbGVJRCwgYWxpZ25lZDogYm9vbGVhbiA9IGZhbHNlKTogRmxvYXQzMkFycmF5IHtcbiAgICAgICAgY29uc3QgcHJvak1hdHJpeEtleSA9IHVud3JhcHBlZFRpbGVJRC5rZXk7XG4gICAgICAgIGNvbnN0IGNhY2hlID0gYWxpZ25lZCA/IHRoaXMuX2FsaWduZWRQcm9qTWF0cml4Q2FjaGUgOiB0aGlzLl9wcm9qTWF0cml4Q2FjaGU7XG4gICAgICAgIGlmIChjYWNoZVtwcm9qTWF0cml4S2V5XSkge1xuICAgICAgICAgICAgcmV0dXJuIGNhY2hlW3Byb2pNYXRyaXhLZXldO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcG9zTWF0cml4ID0gdGhpcy5jYWxjdWxhdGVQb3NNYXRyaXgodW53cmFwcGVkVGlsZUlELCB0aGlzLndvcmxkU2l6ZSk7XG4gICAgICAgIGNvbnN0IHByb2pNYXRyaXggPSB0aGlzLnByb2plY3Rpb24uaXNSZXByb2plY3RlZEluVGlsZVNwYWNlID9cbiAgICAgICAgICAgIHRoaXMubWVyY2F0b3JNYXRyaXggOiAoYWxpZ25lZCA/IHRoaXMuYWxpZ25lZFByb2pNYXRyaXggOiB0aGlzLnByb2pNYXRyaXgpO1xuICAgICAgICBtYXQ0Lm11bHRpcGx5KHBvc01hdHJpeCwgcHJvak1hdHJpeCwgcG9zTWF0cml4KTtcblxuICAgICAgICBjYWNoZVtwcm9qTWF0cml4S2V5XSA9IG5ldyBGbG9hdDMyQXJyYXkocG9zTWF0cml4KTtcbiAgICAgICAgcmV0dXJuIGNhY2hlW3Byb2pNYXRyaXhLZXldO1xuICAgIH1cblxuICAgIGNhbGN1bGF0ZVBpeGVsc1RvVGlsZVVuaXRzTWF0cml4KHRpbGU6IFRpbGUpOiBGbG9hdDMyQXJyYXkge1xuICAgICAgICBjb25zdCBrZXkgPSB0aWxlLnRpbGVJRC5rZXk7XG4gICAgICAgIGNvbnN0IGNhY2hlID0gdGhpcy5fcGl4ZWxzVG9UaWxlVW5pdHNDYWNoZTtcbiAgICAgICAgaWYgKGNhY2hlW2tleV0pIHtcbiAgICAgICAgICAgIHJldHVybiBjYWNoZVtrZXldO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbWF0cml4ID0gZ2V0UGl4ZWxzVG9UaWxlVW5pdHNNYXRyaXgodGlsZSwgdGhpcyk7XG4gICAgICAgIGNhY2hlW2tleV0gPSBtYXRyaXg7XG4gICAgICAgIHJldHVybiBjYWNoZVtrZXldO1xuICAgIH1cblxuICAgIGN1c3RvbUxheWVyTWF0cml4KCk6IEFycmF5PG51bWJlcj4ge1xuICAgICAgICByZXR1cm4gdGhpcy5tZXJjYXRvck1hdHJpeC5zbGljZSgpO1xuICAgIH1cblxuICAgIGdsb2JlVG9NZXJjYXRvck1hdHJpeCgpOiA/QXJyYXk8bnVtYmVyPiB7XG4gICAgICAgIGlmICh0aGlzLnByb2plY3Rpb24ubmFtZSA9PT0gJ2dsb2JlJykge1xuICAgICAgICAgICAgY29uc3QgcGl4ZWxzVG9NZXJjID0gMSAvIHRoaXMud29ybGRTaXplO1xuICAgICAgICAgICAgY29uc3QgbSA9IG1hdDQuZnJvbVNjYWxpbmcoW10sIFtwaXhlbHNUb01lcmMsIHBpeGVsc1RvTWVyYywgcGl4ZWxzVG9NZXJjXSk7XG4gICAgICAgICAgICBtYXQ0Lm11bHRpcGx5KG0sIG0sIHRoaXMuZ2xvYmVNYXRyaXgpO1xuICAgICAgICAgICAgcmV0dXJuIG07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZWNlbnRlck9uVGVycmFpbigpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9lbGV2YXRpb24gfHwgdGhpcy5wcm9qZWN0aW9uLm5hbWUgPT09ICdnbG9iZScpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgY29uc3QgZWxldmF0aW9uOiBFbGV2YXRpb24gPSB0aGlzLl9lbGV2YXRpb247XG4gICAgICAgIHRoaXMuX3VwZGF0ZUNhbWVyYVN0YXRlKCk7XG5cbiAgICAgICAgLy8gQ2FzdCBhIHJheSB0b3dhcmRzIHRoZSBzZWEgbGV2ZWwgYW5kIGZpbmQgdGhlIGludGVyc2VjdGlvbiBwb2ludCB3aXRoIHRoZSB0ZXJyYWluLlxuICAgICAgICAvLyBXZSBuZWVkIHRvIHVzZSBhIGNhbWVyYSBwb3NpdGlvbiB0aGF0IGV4aXN0cyBpbiB0aGUgc2FtZSBjb29yZGluYXRlIHNwYWNlIGFzIHRoZSBkYXRhLlxuICAgICAgICAvLyBUaGUgZGVmYXVsdCBjYW1lcmEgcG9zaXRpb24gbWlnaHQgaGF2ZSBiZWVuIGNvbXBlbnNhdGVkIGJ5IHRoZSBhY3RpdmUgcHJvamVjdGlvbiBtb2RlbC5cbiAgICAgICAgY29uc3QgbWVyY1BpeGVsc1Blck1ldGVyID0gbWVyY2F0b3JaZnJvbUFsdGl0dWRlKDEsIHRoaXMuX2NlbnRlci5sYXQpICogdGhpcy53b3JsZFNpemU7XG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5fY29tcHV0ZUNhbWVyYVBvc2l0aW9uKG1lcmNQaXhlbHNQZXJNZXRlcik7XG4gICAgICAgIGNvbnN0IGRpciA9IHRoaXMuX2NhbWVyYS5mb3J3YXJkKCk7XG5cbiAgICAgICAgLy8gVGhlIHJheWNhc3QgZnVuY3Rpb24gZXhwZWN0cyB6LWNvbXBvbmVudCB0byBiZSBpbiBtZXRlcnNcbiAgICAgICAgY29uc3QgbWV0ZXJzVG9NZXJjID0gbWVyY2F0b3JaZnJvbUFsdGl0dWRlKDEuMCwgdGhpcy5fY2VudGVyLmxhdCk7XG4gICAgICAgIHN0YXJ0WzJdIC89IG1ldGVyc1RvTWVyYztcbiAgICAgICAgZGlyWzJdIC89IG1ldGVyc1RvTWVyYztcbiAgICAgICAgdmVjMy5ub3JtYWxpemUoZGlyLCBkaXIpO1xuXG4gICAgICAgIGNvbnN0IHQgPSBlbGV2YXRpb24ucmF5Y2FzdChzdGFydCwgZGlyLCBlbGV2YXRpb24uZXhhZ2dlcmF0aW9uKCkpO1xuXG4gICAgICAgIGlmICh0KSB7XG4gICAgICAgICAgICBjb25zdCBwb2ludCA9IHZlYzMuc2NhbGVBbmRBZGQoW10sIHN0YXJ0LCBkaXIsIHQpO1xuICAgICAgICAgICAgY29uc3QgbmV3Q2VudGVyID0gbmV3IE1lcmNhdG9yQ29vcmRpbmF0ZShwb2ludFswXSwgcG9pbnRbMV0sIG1lcmNhdG9yWmZyb21BbHRpdHVkZShwb2ludFsyXSwgbGF0RnJvbU1lcmNhdG9yWShwb2ludFsxXSkpKTtcblxuICAgICAgICAgICAgY29uc3QgY2FtVG9OZXcgPSBbbmV3Q2VudGVyLnggLSBzdGFydFswXSwgbmV3Q2VudGVyLnkgLSBzdGFydFsxXSwgbmV3Q2VudGVyLnogLSBzdGFydFsyXSAqIG1ldGVyc1RvTWVyY107XG4gICAgICAgICAgICBjb25zdCBtYXhBbHRpdHVkZSA9IChuZXdDZW50ZXIueiArIHZlYzMubGVuZ3RoKGNhbVRvTmV3KSkgKiB0aGlzLl9waXhlbHNQZXJNZXJjYXRvclBpeGVsO1xuICAgICAgICAgICAgdGhpcy5fc2VhTGV2ZWxab29tID0gdGhpcy5fem9vbUZyb21NZXJjYXRvcloobWF4QWx0aXR1ZGUpO1xuXG4gICAgICAgICAgICAvLyBDYW1lcmEgem9vbSBoYXMgdG8gYmUgdXBkYXRlZCBhcyB0aGUgb3JiaXQgZGlzdGFuY2UgbWlnaHQgaGF2ZSBjaGFuZ2VkXG4gICAgICAgICAgICB0aGlzLl9jZW50ZXJBbHRpdHVkZSA9IG5ld0NlbnRlci50b0FsdGl0dWRlKCk7XG4gICAgICAgICAgICB0aGlzLl9jZW50ZXIgPSB0aGlzLmNvb3JkaW5hdGVMb2NhdGlvbihuZXdDZW50ZXIpO1xuICAgICAgICAgICAgdGhpcy5fdXBkYXRlWm9vbUZyb21FbGV2YXRpb24oKTtcbiAgICAgICAgICAgIHRoaXMuX2NvbnN0cmFpbigpO1xuICAgICAgICAgICAgdGhpcy5fY2FsY01hdHJpY2VzKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfY29uc3RyYWluQ2FtZXJhKGFkYXB0Q2FtZXJhQWx0aXR1ZGU6IGJvb2xlYW4gPSBmYWxzZSkge1xuICAgICAgICBpZiAoIXRoaXMuX2VsZXZhdGlvbilcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBjb25zdCBlbGV2YXRpb246IEVsZXZhdGlvbiA9IHRoaXMuX2VsZXZhdGlvbjtcblxuICAgICAgICAvLyBGaW5kIHVuY29tcGVuc2F0ZWQgY2FtZXJhIHBvc2l0aW9uIGZvciBlbGV2YXRpb24gc2FtcGxpbmcuXG4gICAgICAgIC8vIFRoZSBkZWZhdWx0IGNhbWVyYSBwb3NpdGlvbiBtaWdodCBoYXZlIGJlZW4gY29tcGVuc2F0ZWQgYnkgdGhlIGFjdGl2ZSBwcm9qZWN0aW9uIG1vZGVsLlxuICAgICAgICBjb25zdCBtZXJjUGl4ZWxzUGVyTWV0ZXIgPSBtZXJjYXRvclpmcm9tQWx0aXR1ZGUoMSwgdGhpcy5fY2VudGVyLmxhdCkgKiB0aGlzLndvcmxkU2l6ZTtcbiAgICAgICAgY29uc3QgcG9zID0gdGhpcy5fY29tcHV0ZUNhbWVyYVBvc2l0aW9uKG1lcmNQaXhlbHNQZXJNZXRlcik7XG4gICAgICAgIGNvbnN0IGVsZXZhdGlvbkF0Q2FtZXJhID0gZWxldmF0aW9uLmdldEF0UG9pbnRPclplcm8obmV3IE1lcmNhdG9yQ29vcmRpbmF0ZSguLi5wb3MpKTtcbiAgICAgICAgY29uc3QgdGVycmFpbkVsZXZhdGlvbiA9IHRoaXMucGl4ZWxzUGVyTWV0ZXIgLyB0aGlzLndvcmxkU2l6ZSAqIGVsZXZhdGlvbkF0Q2FtZXJhO1xuICAgICAgICBjb25zdCBtaW5IZWlnaHQgPSB0aGlzLl9taW5pbXVtSGVpZ2h0T3ZlclRlcnJhaW4oKTtcbiAgICAgICAgY29uc3QgY2FtZXJhSGVpZ2h0ID0gcG9zWzJdIC0gdGVycmFpbkVsZXZhdGlvbjtcblxuICAgICAgICBpZiAoY2FtZXJhSGVpZ2h0IDw9IG1pbkhlaWdodCkge1xuICAgICAgICAgICAgaWYgKGNhbWVyYUhlaWdodCA8IDAgfHwgYWRhcHRDYW1lcmFBbHRpdHVkZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNlbnRlciA9IHRoaXMubG9jYXRpb25Db29yZGluYXRlKHRoaXMuX2NlbnRlciwgdGhpcy5fY2VudGVyQWx0aXR1ZGUpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNhbWVyYVRvQ2VudGVyID0gW3Bvc1swXSwgcG9zWzFdLCBjZW50ZXIueiAtIHBvc1syXV07XG5cbiAgICAgICAgICAgICAgICBjb25zdCBwcmV2RGlzdFRvQ2FtZXJhID0gdmVjMy5sZW5ndGgoY2FtZXJhVG9DZW50ZXIpO1xuICAgICAgICAgICAgICAgIC8vIEFkanVzdCB0aGUgY2FtZXJhIHZlY3RvciBzbyB0aGF0IHRoZSBjYW1lcmEgaXMgcGxhY2VkIGFib3ZlIHRoZSB0ZXJyYWluLlxuICAgICAgICAgICAgICAgIC8vIERpc3RhbmNlIGJldHdlZW4gdGhlIGNhbWVyYSBhbmQgdGhlIGNlbnRlciBwb2ludCBpcyBrZXB0IGNvbnN0YW50LlxuICAgICAgICAgICAgICAgIGNhbWVyYVRvQ2VudGVyWzJdIC09IChtaW5IZWlnaHQgLSBjYW1lcmFIZWlnaHQpIC8gdGhpcy5fcGl4ZWxzUGVyTWVyY2F0b3JQaXhlbDtcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdEaXN0VG9DYW1lcmEgPSB2ZWMzLmxlbmd0aChjYW1lcmFUb0NlbnRlcik7XG5cbiAgICAgICAgICAgICAgICBpZiAobmV3RGlzdFRvQ2FtZXJhID09PSAwKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgICAgICAgICB2ZWMzLnNjYWxlKGNhbWVyYVRvQ2VudGVyLCBjYW1lcmFUb0NlbnRlciwgcHJldkRpc3RUb0NhbWVyYSAvIG5ld0Rpc3RUb0NhbWVyYSAqIHRoaXMuX3BpeGVsc1Blck1lcmNhdG9yUGl4ZWwpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2NhbWVyYS5wb3NpdGlvbiA9IFtwb3NbMF0sIHBvc1sxXSwgY2VudGVyLnogKiB0aGlzLl9waXhlbHNQZXJNZXJjYXRvclBpeGVsIC0gY2FtZXJhVG9DZW50ZXJbMl1dO1xuICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZVN0YXRlRnJvbUNhbWVyYSgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9pc0NhbWVyYUNvbnN0cmFpbmVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9jb25zdHJhaW4oKSB7XG4gICAgICAgIGlmICghdGhpcy5jZW50ZXIgfHwgIXRoaXMud2lkdGggfHwgIXRoaXMuaGVpZ2h0IHx8IHRoaXMuX2NvbnN0cmFpbmluZykgcmV0dXJuO1xuXG4gICAgICAgIHRoaXMuX2NvbnN0cmFpbmluZyA9IHRydWU7XG4gICAgICAgIGNvbnN0IGlzR2xvYmUgPSB0aGlzLnByb2plY3Rpb24ubmFtZSA9PT0gJ2dsb2JlJyB8fCB0aGlzLm1lcmNhdG9yRnJvbVRyYW5zaXRpb247XG5cbiAgICAgICAgLy8gYWx0ZXJuYXRlIGNvbnN0cmFpbmluZyBmb3Igbm9uLU1lcmNhdG9yIHByb2plY3Rpb25zXG4gICAgICAgIGlmICh0aGlzLnByb2plY3Rpb24uaXNSZXByb2plY3RlZEluVGlsZVNwYWNlIHx8IGlzR2xvYmUpIHtcbiAgICAgICAgICAgIGNvbnN0IGNlbnRlciA9IHRoaXMuY2VudGVyO1xuICAgICAgICAgICAgY2VudGVyLmxhdCA9IGNsYW1wKGNlbnRlci5sYXQsIHRoaXMubWluTGF0LCB0aGlzLm1heExhdCk7XG4gICAgICAgICAgICBpZiAodGhpcy5tYXhCb3VuZHMgfHwgISh0aGlzLnJlbmRlcldvcmxkQ29waWVzIHx8IGlzR2xvYmUpKSBjZW50ZXIubG5nID0gY2xhbXAoY2VudGVyLmxuZywgdGhpcy5taW5MbmcsIHRoaXMubWF4TG5nKTtcbiAgICAgICAgICAgIHRoaXMuY2VudGVyID0gY2VudGVyO1xuICAgICAgICAgICAgdGhpcy5fY29uc3RyYWluaW5nID0gZmFsc2U7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB1bm1vZGlmaWVkID0gdGhpcy5fdW5tb2RpZmllZDtcbiAgICAgICAgY29uc3Qge3gsIHl9ID0gdGhpcy5wb2ludDtcbiAgICAgICAgbGV0IHMgPSAwO1xuICAgICAgICBsZXQgeDIgPSB4O1xuICAgICAgICBsZXQgeTIgPSB5O1xuICAgICAgICBjb25zdCB3MiA9IHRoaXMud2lkdGggLyAyO1xuICAgICAgICBjb25zdCBoMiA9IHRoaXMuaGVpZ2h0IC8gMjtcblxuICAgICAgICBjb25zdCBtaW5ZID0gdGhpcy53b3JsZE1pblkgKiB0aGlzLnNjYWxlO1xuICAgICAgICBjb25zdCBtYXhZID0gdGhpcy53b3JsZE1heFkgKiB0aGlzLnNjYWxlO1xuICAgICAgICBpZiAoeSAtIGgyIDwgbWluWSkgeTIgPSBtaW5ZICsgaDI7XG4gICAgICAgIGlmICh5ICsgaDIgPiBtYXhZKSB5MiA9IG1heFkgLSBoMjtcbiAgICAgICAgaWYgKG1heFkgLSBtaW5ZIDwgdGhpcy5oZWlnaHQpIHtcbiAgICAgICAgICAgIHMgPSBNYXRoLm1heChzLCB0aGlzLmhlaWdodCAvIChtYXhZIC0gbWluWSkpO1xuICAgICAgICAgICAgeTIgPSAobWF4WSArIG1pblkpIC8gMjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLm1heEJvdW5kcyB8fCAhdGhpcy5fcmVuZGVyV29ybGRDb3BpZXMgfHwgIXRoaXMucHJvamVjdGlvbi53cmFwKSB7XG4gICAgICAgICAgICBjb25zdCBtaW5YID0gdGhpcy53b3JsZE1pblggKiB0aGlzLnNjYWxlO1xuICAgICAgICAgICAgY29uc3QgbWF4WCA9IHRoaXMud29ybGRNYXhYICogdGhpcy5zY2FsZTtcblxuICAgICAgICAgICAgLy8gVHJhbnNsYXRlIHRvIHBvc2l0aXZlIHBvc2l0aW9ucyB3aXRoIHRoZSBtYXAgY2VudGVyIGluIHRoZSBjZW50ZXIgcG9zaXRpb24uXG4gICAgICAgICAgICAvLyBUaGlzIGVuc3VyZXMgdGhhdCB0aGUgbWFwIHNuYXBzIHRvIHRoZSBjb3JyZWN0IGVkZ2UuXG4gICAgICAgICAgICBjb25zdCBzaGlmdCA9IHRoaXMud29ybGRTaXplIC8gMiAtIChtaW5YICsgbWF4WCkgLyAyO1xuICAgICAgICAgICAgeDIgPSAoeCArIHNoaWZ0ICsgdGhpcy53b3JsZFNpemUpICUgdGhpcy53b3JsZFNpemUgLSBzaGlmdDtcblxuICAgICAgICAgICAgaWYgKHgyIC0gdzIgPCBtaW5YKSB4MiA9IG1pblggKyB3MjtcbiAgICAgICAgICAgIGlmICh4MiArIHcyID4gbWF4WCkgeDIgPSBtYXhYIC0gdzI7XG4gICAgICAgICAgICBpZiAobWF4WCAtIG1pblggPCB0aGlzLndpZHRoKSB7XG4gICAgICAgICAgICAgICAgcyA9IE1hdGgubWF4KHMsIHRoaXMud2lkdGggLyAobWF4WCAtIG1pblgpKTtcbiAgICAgICAgICAgICAgICB4MiA9IChtYXhYICsgbWluWCkgLyAyO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHgyICE9PSB4IHx8IHkyICE9PSB5KSB7IC8vIHBhbiB0aGUgbWFwIHRvIGZpdCB0aGUgcmFuZ2VcbiAgICAgICAgICAgIHRoaXMuY2VudGVyID0gdGhpcy51bnByb2plY3QobmV3IFBvaW50KHgyLCB5MikpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzKSB7IC8vIHNjYWxlIHRoZSBtYXAgdG8gZml0IHRoZSByYW5nZVxuICAgICAgICAgICAgdGhpcy56b29tICs9IHRoaXMuc2NhbGVab29tKHMpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fY29uc3RyYWluQ2FtZXJhKCk7XG4gICAgICAgIHRoaXMuX3VubW9kaWZpZWQgPSB1bm1vZGlmaWVkO1xuICAgICAgICB0aGlzLl9jb25zdHJhaW5pbmcgPSBmYWxzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBtaW5pbXVtIHpvb20gYXQgd2hpY2ggYHRoaXMud2lkdGhgIGNhbiBmaXQgbWF4IGxvbmdpdHVkZSByYW5nZVxuICAgICAqIGFuZCBgdGhpcy5oZWlnaHRgIGNhbiBmaXQgbWF4IGxhdGl0dWRlIHJhbmdlLlxuICAgICAqXG4gICAgICogQHJldHVybnMge251bWJlcn0gVGhlIHpvb20gdmFsdWUuXG4gICAgICovXG4gICAgX21pblpvb21Gb3JCb3VuZHMoKTogbnVtYmVyIHtcbiAgICAgICAgbGV0IG1pblpvb20gPSBNYXRoLm1heCgwLCB0aGlzLnNjYWxlWm9vbSh0aGlzLmhlaWdodCAvICh0aGlzLndvcmxkTWF4WSAtIHRoaXMud29ybGRNaW5ZKSkpO1xuICAgICAgICBpZiAodGhpcy5tYXhCb3VuZHMpIHtcbiAgICAgICAgICAgIG1pblpvb20gPSBNYXRoLm1heChtaW5ab29tLCB0aGlzLnNjYWxlWm9vbSh0aGlzLndpZHRoIC8gKHRoaXMud29ybGRNYXhYIC0gdGhpcy53b3JsZE1pblgpKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1pblpvb207XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgbWF4aW11bSBkaXN0YW5jZSBvZiB0aGUgY2FtZXJhIGZyb20gdGhlIGNlbnRlciBvZiB0aGUgYm91bmRzLCBzdWNoIHRoYXRcbiAgICAgKiBgdGhpcy53aWR0aGAgY2FuIGZpdCBtYXggbG9uZ2l0dWRlIHJhbmdlIGFuZCBgdGhpcy5oZWlnaHRgIGNhbiBmaXQgbWF4IGxhdGl0dWRlIHJhbmdlLlxuICAgICAqIEluIG1lcmNhdG9yIHVuaXRzLlxuICAgICAqXG4gICAgICogQHJldHVybnMge251bWJlcn0gVGhlIG1lcmNhdG9yIHogY29vcmRpbmF0ZS5cbiAgICAgKi9cbiAgICBfbWF4Q2FtZXJhQm91bmRzRGlzdGFuY2UoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21lcmNhdG9yWmZyb21ab29tKHRoaXMuX21pblpvb21Gb3JCb3VuZHMoKSk7XG4gICAgfVxuXG4gICAgX2NhbGNNYXRyaWNlcygpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLmhlaWdodCkgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuY2VudGVyT2Zmc2V0O1xuXG4gICAgICAgIC8vIFotYXhpcyB1c2VzIHBpeGVsIGNvb3JkaW5hdGVzIHdoZW4gZ2xvYmUgbW9kZSBpcyBlbmFibGVkXG4gICAgICAgIGNvbnN0IHBpeGVsc1Blck1ldGVyID0gdGhpcy5waXhlbHNQZXJNZXRlcjtcblxuICAgICAgICBpZiAodGhpcy5wcm9qZWN0aW9uLm5hbWUgPT09ICdnbG9iZScpIHtcbiAgICAgICAgICAgIHRoaXMuX21lcmNhdG9yU2NhbGVSYXRpbyA9IG1lcmNhdG9yWmZyb21BbHRpdHVkZSgxLCB0aGlzLmNlbnRlci5sYXQpIC8gbWVyY2F0b3JaZnJvbUFsdGl0dWRlKDEsIEdMT0JFX1NDQUxFX01BVENIX0xBVElUVURFKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHByb2plY3Rpb25UID0gZ2V0UHJvamVjdGlvbkludGVycG9sYXRpb25UKHRoaXMucHJvamVjdGlvbiwgdGhpcy56b29tLCB0aGlzLndpZHRoLCB0aGlzLmhlaWdodCwgMTAyNCk7XG5cbiAgICAgICAgLy8gJ3RoaXMuX3BpeGVsc1Blck1lcmNhdG9yUGl4ZWwnIGlzIHRoZSByYXRpbyBiZXR3ZWVuIHBpeGVsc1Blck1ldGVyIGluIHRoZSBjdXJyZW50IHByb2plY3Rpb24gcmVsYXRpdmUgdG8gTWVyY2F0b3IuXG4gICAgICAgIC8vIFRoaXMgaXMgdXNlZnVsIGZvciBjb252ZXJ0aW5nIGUuZy4gY2FtZXJhIHBvc2l0aW9uIGJldHdlZW4gcGl4ZWwgc3BhY2VzIGFzIHNvbWUgbG9naWNcbiAgICAgICAgLy8gc3VjaCBhcyByYXljYXN0aW5nIGV4cGVjdHMgdGhlIHNjYWxlIHRvIGJlIGluIG1lcmNhdG9yIHBpeGVsc1xuICAgICAgICB0aGlzLl9waXhlbHNQZXJNZXJjYXRvclBpeGVsID0gdGhpcy5wcm9qZWN0aW9uLnBpeGVsU3BhY2VDb252ZXJzaW9uKHRoaXMuY2VudGVyLmxhdCwgdGhpcy53b3JsZFNpemUsIHByb2plY3Rpb25UKTtcblxuICAgICAgICB0aGlzLmNhbWVyYVRvQ2VudGVyRGlzdGFuY2UgPSAwLjUgLyBNYXRoLnRhbih0aGlzLl9mb3YgKiAwLjUpICogdGhpcy5oZWlnaHQgKiB0aGlzLl9waXhlbHNQZXJNZXJjYXRvclBpeGVsO1xuXG4gICAgICAgIHRoaXMuX3VwZGF0ZUNhbWVyYVN0YXRlKCk7XG5cbiAgICAgICAgdGhpcy5fZmFyWiA9IHRoaXMucHJvamVjdGlvbi5mYXJ0aGVzdFBpeGVsRGlzdGFuY2UodGhpcyk7XG5cbiAgICAgICAgLy8gVGhlIGxhcmdlciB0aGUgdmFsdWUgb2YgbmVhclogaXNcbiAgICAgICAgLy8gLSB0aGUgbW9yZSBkZXB0aCBwcmVjaXNpb24gaXMgYXZhaWxhYmxlIGZvciBmZWF0dXJlcyAoZ29vZClcbiAgICAgICAgLy8gLSBjbGlwcGluZyBzdGFydHMgYXBwZWFyaW5nIHNvb25lciB3aGVuIHRoZSBjYW1lcmEgaXMgY2xvc2UgdG8gM2QgZmVhdHVyZXMgKGJhZClcbiAgICAgICAgLy9cbiAgICAgICAgLy8gU21hbGxlciB2YWx1ZXMgd29ya2VkIHdlbGwgZm9yIG1hcGJveC1nbC1qcyBidXQgZGVja2dsIHdhcyBlbmNvdW50ZXJpbmcgcHJlY2lzaW9uIGlzc3Vlc1xuICAgICAgICAvLyB3aGVuIHJlbmRlcmluZyBpdCdzIGxheWVycyB1c2luZyBjdXN0b20gbGF5ZXJzLiBUaGlzIHZhbHVlIHdhcyBleHBlcmltZW50YWxseSBjaG9zZW4gYW5kXG4gICAgICAgIC8vIHNlZW1zIHRvIHNvbHZlIHotZmlnaHRpbmcgaXNzdWVzIGluIGRlY2tnbCB3aGlsZSBub3QgY2xpcHBpbmcgYnVpbGRpbmdzIHRvbyBjbG9zZSB0byB0aGUgY2FtZXJhLlxuICAgICAgICB0aGlzLl9uZWFyWiA9IHRoaXMuaGVpZ2h0IC8gNTA7XG5cbiAgICAgICAgY29uc3QgelVuaXQgPSB0aGlzLnByb2plY3Rpb24uekF4aXNVbml0ID09PSBcIm1ldGVyc1wiID8gcGl4ZWxzUGVyTWV0ZXIgOiAxLjA7XG4gICAgICAgIGNvbnN0IHdvcmxkVG9DYW1lcmEgPSB0aGlzLl9jYW1lcmEuZ2V0V29ybGRUb0NhbWVyYSh0aGlzLndvcmxkU2l6ZSwgelVuaXQpO1xuICAgICAgICBjb25zdCBjYW1lcmFUb0NsaXAgPSB0aGlzLl9jYW1lcmEuZ2V0Q2FtZXJhVG9DbGlwUGVyc3BlY3RpdmUodGhpcy5fZm92LCB0aGlzLndpZHRoIC8gdGhpcy5oZWlnaHQsIHRoaXMuX25lYXJaLCB0aGlzLl9mYXJaKTtcblxuICAgICAgICAvLyBBcHBseSBjZW50ZXIgb2YgcGVyc3BlY3RpdmUgb2Zmc2V0XG4gICAgICAgIGNhbWVyYVRvQ2xpcFs4XSA9IC1vZmZzZXQueCAqIDIgLyB0aGlzLndpZHRoO1xuICAgICAgICBjYW1lcmFUb0NsaXBbOV0gPSBvZmZzZXQueSAqIDIgLyB0aGlzLmhlaWdodDtcblxuICAgICAgICBsZXQgbTogQXJyYXk8bnVtYmVyPiB8IEZsb2F0MzJBcnJheSB8IEZsb2F0NjRBcnJheSA9IG1hdDQubXVsKFtdLCBjYW1lcmFUb0NsaXAsIHdvcmxkVG9DYW1lcmEpO1xuXG4gICAgICAgIGlmICh0aGlzLnByb2plY3Rpb24uaXNSZXByb2plY3RlZEluVGlsZVNwYWNlKSB7XG4gICAgICAgICAgICAvLyBQcm9qZWN0aW9ucyB1bmRpc3RvcnQgYXMgeW91IHpvb20gaW4gKHNoZWFyLCBzY2FsZSwgcm90YXRlKS5cbiAgICAgICAgICAgIC8vIEFwcGx5IHRoZSB1bmRpc3RvcnRpb24gYXJvdW5kIHRoZSBjZW50ZXIgb2YgdGhlIG1hcC5cbiAgICAgICAgICAgIGNvbnN0IG1jID0gdGhpcy5sb2NhdGlvbkNvb3JkaW5hdGUodGhpcy5jZW50ZXIpO1xuICAgICAgICAgICAgY29uc3QgYWRqdXN0bWVudHMgPSBtYXQ0LmlkZW50aXR5KFtdKTtcbiAgICAgICAgICAgIG1hdDQudHJhbnNsYXRlKGFkanVzdG1lbnRzLCBhZGp1c3RtZW50cywgW21jLnggKiB0aGlzLndvcmxkU2l6ZSwgbWMueSAqIHRoaXMud29ybGRTaXplLCAwXSk7XG4gICAgICAgICAgICBtYXQ0Lm11bHRpcGx5KGFkanVzdG1lbnRzLCBhZGp1c3RtZW50cywgZ2V0UHJvamVjdGlvbkFkanVzdG1lbnRzKHRoaXMpKTtcbiAgICAgICAgICAgIG1hdDQudHJhbnNsYXRlKGFkanVzdG1lbnRzLCBhZGp1c3RtZW50cywgWy1tYy54ICogdGhpcy53b3JsZFNpemUsIC1tYy55ICogdGhpcy53b3JsZFNpemUsIDBdKTtcbiAgICAgICAgICAgIG1hdDQubXVsdGlwbHkobSwgbSwgYWRqdXN0bWVudHMpO1xuICAgICAgICAgICAgdGhpcy5pbnZlcnNlQWRqdXN0bWVudE1hdHJpeCA9IGdldFByb2plY3Rpb25BZGp1c3RtZW50SW52ZXJ0ZWQodGhpcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmludmVyc2VBZGp1c3RtZW50TWF0cml4ID0gWzEsIDAsIDAsIDFdO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVGhlIG1lcmNhdG9yTWF0cml4IGNhbiBiZSB1c2VkIHRvIHRyYW5zZm9ybSBwb2ludHMgZnJvbSBtZXJjYXRvciBjb29yZGluYXRlc1xuICAgICAgICAvLyAoWzAsIDBdIG53LCBbMSwgMV0gc2UpIHRvIEdMIGNvb3JkaW5hdGVzLiAvIHpVbml0IGNvbXBlbnNhdGVzIGZvciBzY2FsaW5nIGRvbmUgaW4gd29ybGRUb0NhbWVyYS5cbiAgICAgICAgdGhpcy5tZXJjYXRvck1hdHJpeCA9IG1hdDQuc2NhbGUoW10sIG0sIFt0aGlzLndvcmxkU2l6ZSwgdGhpcy53b3JsZFNpemUsIHRoaXMud29ybGRTaXplIC8gelVuaXQsIDEuMF0pO1xuXG4gICAgICAgIHRoaXMucHJvak1hdHJpeCA9IG07XG5cbiAgICAgICAgLy8gRm9yIHRpbGUgY292ZXIgY2FsY3VsYXRpb24sIHVzZSBpbnZlcnRlZCBvZiBiYXNlIChub24gZWxldmF0ZWQpIG1hdHJpeFxuICAgICAgICAvLyBhcyB0aWxlIGVsZXZhdGlvbnMgYXJlIGluIHRpbGUgY29vcmRpbmF0ZXMgYW5kIHJlbGF0aXZlIHRvIGNlbnRlciBlbGV2YXRpb24uXG4gICAgICAgIHRoaXMuaW52UHJvak1hdHJpeCA9IG1hdDQuaW52ZXJ0KG5ldyBGbG9hdDY0QXJyYXkoMTYpLCB0aGlzLnByb2pNYXRyaXgpO1xuXG4gICAgICAgIGNvbnN0IGNsaXBUb0NhbWVyYSA9IG1hdDQuaW52ZXJ0KFtdLCBjYW1lcmFUb0NsaXApO1xuICAgICAgICB0aGlzLmZydXN0dW1Db3JuZXJzID0gRnJ1c3R1bUNvcm5lcnMuZnJvbUludlByb2plY3Rpb25NYXRyaXgoY2xpcFRvQ2FtZXJhLCB0aGlzLmhvcml6b25MaW5lRnJvbVRvcCgpLCB0aGlzLmhlaWdodCk7XG5cbiAgICAgICAgY29uc3QgdmlldyA9IG5ldyBGbG9hdDMyQXJyYXkoMTYpO1xuICAgICAgICBtYXQ0LmlkZW50aXR5KHZpZXcpO1xuICAgICAgICBtYXQ0LnNjYWxlKHZpZXcsIHZpZXcsIFsxLCAtMSwgMV0pO1xuICAgICAgICBtYXQ0LnJvdGF0ZVgodmlldywgdmlldywgdGhpcy5fcGl0Y2gpO1xuICAgICAgICBtYXQ0LnJvdGF0ZVoodmlldywgdmlldywgdGhpcy5hbmdsZSk7XG5cbiAgICAgICAgY29uc3QgcHJvamVjdGlvbiA9IG1hdDQucGVyc3BlY3RpdmUobmV3IEZsb2F0MzJBcnJheSgxNiksIHRoaXMuX2ZvdiwgdGhpcy53aWR0aCAvIHRoaXMuaGVpZ2h0LCB0aGlzLl9uZWFyWiwgdGhpcy5fZmFyWik7XG4gICAgICAgIC8vIFRoZSBkaXN0YW5jZSBpbiBwaXhlbHMgdGhlIHNreWJveCBuZWVkcyB0byBiZSBzaGlmdGVkIGRvd24gYnkgdG8gbWVldCB0aGUgc2hpZnRlZCBob3Jpem9uLlxuICAgICAgICBjb25zdCBza3lib3hIb3Jpem9uU2hpZnQgPSAoTWF0aC5QSSAvIDIgLSB0aGlzLl9waXRjaCkgKiAodGhpcy5oZWlnaHQgLyB0aGlzLl9mb3YpICogdGhpcy5faG9yaXpvblNoaWZ0O1xuICAgICAgICAvLyBBcHBseSBjZW50ZXIgb2YgcGVyc3BlY3RpdmUgb2Zmc2V0IHRvIHNreWJveCBwcm9qZWN0aW9uXG4gICAgICAgIHByb2plY3Rpb25bOF0gPSAtb2Zmc2V0LnggKiAyIC8gdGhpcy53aWR0aDtcbiAgICAgICAgcHJvamVjdGlvbls5XSA9IChvZmZzZXQueSArIHNreWJveEhvcml6b25TaGlmdCkgKiAyIC8gdGhpcy5oZWlnaHQ7XG4gICAgICAgIHRoaXMuc2t5Ym94TWF0cml4ID0gbWF0NC5tdWx0aXBseSh2aWV3LCBwcm9qZWN0aW9uLCB2aWV3KTtcblxuICAgICAgICAvLyBNYWtlIGEgc2Vjb25kIHByb2plY3Rpb24gbWF0cml4IHRoYXQgaXMgYWxpZ25lZCB0byBhIHBpeGVsIGdyaWQgZm9yIHJlbmRlcmluZyByYXN0ZXIgdGlsZXMuXG4gICAgICAgIC8vIFdlJ3JlIHJvdW5kaW5nIHRoZSAoZmxvYXRpbmcgcG9pbnQpIHgveSB2YWx1ZXMgdG8gYWNoaWV2ZSB0byBhdm9pZCByZW5kZXJpbmcgcmFzdGVyIGltYWdlcyB0byBmcmFjdGlvbmFsXG4gICAgICAgIC8vIGNvb3JkaW5hdGVzLiBBZGRpdGlvbmFsbHksIHdlIGFkanVzdCBieSBoYWxmIGEgcGl4ZWwgaW4gZWl0aGVyIGRpcmVjdGlvbiBpbiBjYXNlIHRoYXQgdmlld3BvcnQgZGltZW5zaW9uXG4gICAgICAgIC8vIGlzIGFuIG9kZCBpbnRlZ2VyIHRvIHByZXNlcnZlIHJlbmRlcmluZyB0byB0aGUgcGl4ZWwgZ3JpZC4gV2UncmUgcm90YXRpbmcgdGhpcyBzaGlmdCBiYXNlZCBvbiB0aGUgYW5nbGVcbiAgICAgICAgLy8gb2YgdGhlIHRyYW5zZm9ybWF0aW9uIHNvIHRoYXQgMMKwLCA5MMKwLCAxODDCsCwgYW5kIDI3MMKwIHJhc3RlcnMgYXJlIGNyaXNwLCBhbmQgYWRqdXN0IHRoZSBzaGlmdCBzbyB0aGF0XG4gICAgICAgIC8vIGl0IGlzIGFsd2F5cyA8PSAwLjUgcGl4ZWxzLlxuICAgICAgICBjb25zdCBwb2ludCA9IHRoaXMucG9pbnQ7XG4gICAgICAgIGNvbnN0IHggPSBwb2ludC54LCB5ID0gcG9pbnQueTtcbiAgICAgICAgY29uc3QgeFNoaWZ0ID0gKHRoaXMud2lkdGggJSAyKSAvIDIsIHlTaGlmdCA9ICh0aGlzLmhlaWdodCAlIDIpIC8gMixcbiAgICAgICAgICAgIGFuZ2xlQ29zID0gTWF0aC5jb3ModGhpcy5hbmdsZSksIGFuZ2xlU2luID0gTWF0aC5zaW4odGhpcy5hbmdsZSksXG4gICAgICAgICAgICBkeCA9IHggLSBNYXRoLnJvdW5kKHgpICsgYW5nbGVDb3MgKiB4U2hpZnQgKyBhbmdsZVNpbiAqIHlTaGlmdCxcbiAgICAgICAgICAgIGR5ID0geSAtIE1hdGgucm91bmQoeSkgKyBhbmdsZUNvcyAqIHlTaGlmdCArIGFuZ2xlU2luICogeFNoaWZ0O1xuICAgICAgICBjb25zdCBhbGlnbmVkTSA9IG5ldyBGbG9hdDY0QXJyYXkobSk7XG4gICAgICAgIG1hdDQudHJhbnNsYXRlKGFsaWduZWRNLCBhbGlnbmVkTSwgWyBkeCA+IDAuNSA/IGR4IC0gMSA6IGR4LCBkeSA+IDAuNSA/IGR5IC0gMSA6IGR5LCAwIF0pO1xuICAgICAgICB0aGlzLmFsaWduZWRQcm9qTWF0cml4ID0gYWxpZ25lZE07XG5cbiAgICAgICAgbSA9IG1hdDQuY3JlYXRlKCk7XG4gICAgICAgIG1hdDQuc2NhbGUobSwgbSwgW3RoaXMud2lkdGggLyAyLCAtdGhpcy5oZWlnaHQgLyAyLCAxXSk7XG4gICAgICAgIG1hdDQudHJhbnNsYXRlKG0sIG0sIFsxLCAtMSwgMF0pO1xuICAgICAgICB0aGlzLmxhYmVsUGxhbmVNYXRyaXggPSBtO1xuXG4gICAgICAgIG0gPSBtYXQ0LmNyZWF0ZSgpO1xuICAgICAgICBtYXQ0LnNjYWxlKG0sIG0sIFsxLCAtMSwgMV0pO1xuICAgICAgICBtYXQ0LnRyYW5zbGF0ZShtLCBtLCBbLTEsIC0xLCAwXSk7XG4gICAgICAgIG1hdDQuc2NhbGUobSwgbSwgWzIgLyB0aGlzLndpZHRoLCAyIC8gdGhpcy5oZWlnaHQsIDFdKTtcbiAgICAgICAgdGhpcy5nbENvb3JkTWF0cml4ID0gbTtcblxuICAgICAgICAvLyBtYXRyaXggZm9yIGNvbnZlcnNpb24gZnJvbSBsb2NhdGlvbiB0byBzY3JlZW4gY29vcmRpbmF0ZXNcbiAgICAgICAgdGhpcy5waXhlbE1hdHJpeCA9IG1hdDQubXVsdGlwbHkobmV3IEZsb2F0NjRBcnJheSgxNiksIHRoaXMubGFiZWxQbGFuZU1hdHJpeCwgdGhpcy5wcm9qTWF0cml4KTtcblxuICAgICAgICB0aGlzLl9jYWxjRm9nTWF0cmljZXMoKTtcbiAgICAgICAgdGhpcy5fZGlzdGFuY2VUaWxlRGF0YUNhY2hlID0ge307XG5cbiAgICAgICAgLy8gaW52ZXJzZSBtYXRyaXggZm9yIGNvbnZlcnNpb24gZnJvbSBzY3JlZW4gY29vcmRpbmF0ZXMgdG8gbG9jYXRpb25cbiAgICAgICAgbSA9IG1hdDQuaW52ZXJ0KG5ldyBGbG9hdDY0QXJyYXkoMTYpLCB0aGlzLnBpeGVsTWF0cml4KTtcbiAgICAgICAgaWYgKCFtKSB0aHJvdyBuZXcgRXJyb3IoXCJmYWlsZWQgdG8gaW52ZXJ0IG1hdHJpeFwiKTtcbiAgICAgICAgdGhpcy5waXhlbE1hdHJpeEludmVyc2UgPSBtO1xuXG4gICAgICAgIGlmICh0aGlzLnByb2plY3Rpb24ubmFtZSA9PT0gJ2dsb2JlJyB8fCB0aGlzLm1lcmNhdG9yRnJvbVRyYW5zaXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuZ2xvYmVNYXRyaXggPSBjYWxjdWxhdGVHbG9iZU1hdHJpeCh0aGlzKTtcblxuICAgICAgICAgICAgY29uc3QgZ2xvYmVDZW50ZXIgPSBbdGhpcy5nbG9iZU1hdHJpeFsxMl0sIHRoaXMuZ2xvYmVNYXRyaXhbMTNdLCB0aGlzLmdsb2JlTWF0cml4WzE0XV07XG5cbiAgICAgICAgICAgIHRoaXMuZ2xvYmVDZW50ZXJJblZpZXdTcGFjZSA9IHZlYzMudHJhbnNmb3JtTWF0NChnbG9iZUNlbnRlciwgZ2xvYmVDZW50ZXIsIHdvcmxkVG9DYW1lcmEpO1xuICAgICAgICAgICAgdGhpcy5nbG9iZVJhZGl1cyA9IHRoaXMud29ybGRTaXplIC8gMi4wIC8gTWF0aC5QSSAtIDEuMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZ2xvYmVNYXRyaXggPSBtO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fcHJvak1hdHJpeENhY2hlID0ge307XG4gICAgICAgIHRoaXMuX2FsaWduZWRQcm9qTWF0cml4Q2FjaGUgPSB7fTtcbiAgICAgICAgdGhpcy5fcGl4ZWxzVG9UaWxlVW5pdHNDYWNoZSA9IHt9O1xuICAgIH1cblxuICAgIF9jYWxjRm9nTWF0cmljZXMoKSB7XG4gICAgICAgIHRoaXMuX2ZvZ1RpbGVNYXRyaXhDYWNoZSA9IHt9O1xuXG4gICAgICAgIGNvbnN0IGNhbWVyYVdvcmxkU2l6ZUZvckZvZyA9IHRoaXMuY2FtZXJhV29ybGRTaXplRm9yRm9nO1xuICAgICAgICBjb25zdCBjYW1lcmFQaXhlbHNQZXJNZXRlciA9IHRoaXMuY2FtZXJhUGl4ZWxzUGVyTWV0ZXI7XG4gICAgICAgIGNvbnN0IGNhbWVyYVBvcyA9IHRoaXMuX2NhbWVyYS5wb3NpdGlvbjtcblxuICAgICAgICAvLyBUaGUgbWVyY2F0b3IgZm9nIG1hdHJpeCBlbmNvZGVzIHRyYW5zZm9ybWF0aW9uIG5lY2Vzc2FyeSB0byB0cmFuc2Zvcm0gYSBwb3NpdGlvbiB0byBjYW1lcmEgZm9nIHNwYWNlIChpbiBtZXRlcnMpOlxuICAgICAgICAvLyB0cmFuc2xhdGVzIHAgdG8gY2FtZXJhIG9yaWdpbiBhbmQgdHJhbnNmb3JtcyBpdCBmcm9tIHBpeGVscyB0byBtZXRlcnMuIFRoZSB3aW5kb3dTY2FsZUZhY3RvciBpcyB1c2VkIHRvIGhhdmUgYVxuICAgICAgICAvLyBjb25zaXN0ZW50IHRyYW5zZm9ybWF0aW9uIGFjcm9zcyBkaWZmZXJlbnQgd2luZG93IHNpemVzLlxuICAgICAgICAvLyAtIHAgPSBwIC0gY2FtZXJhT3JpZ2luXG4gICAgICAgIC8vIC0gcC54eSA9IHAueHkgKiBjYW1lcmFXb3JsZFNpemVGb3JGb2cgKiB3aW5kb3dTY2FsZUZhY3RvclxuICAgICAgICAvLyAtIHAueiAgPSBwLnogICogY2FtZXJhUGl4ZWxzUGVyTWV0ZXIgKiB3aW5kb3dTY2FsZUZhY3RvclxuICAgICAgICBjb25zdCB3aW5kb3dTY2FsZUZhY3RvciA9IDEgLyB0aGlzLmhlaWdodCAvIHRoaXMuX3BpeGVsc1Blck1lcmNhdG9yUGl4ZWw7XG4gICAgICAgIGNvbnN0IG1ldGVyc1RvUGl4ZWwgPSBbY2FtZXJhV29ybGRTaXplRm9yRm9nLCBjYW1lcmFXb3JsZFNpemVGb3JGb2csIGNhbWVyYVBpeGVsc1Blck1ldGVyXTtcbiAgICAgICAgdmVjMy5zY2FsZShtZXRlcnNUb1BpeGVsLCBtZXRlcnNUb1BpeGVsLCB3aW5kb3dTY2FsZUZhY3Rvcik7XG4gICAgICAgIHZlYzMuc2NhbGUoY2FtZXJhUG9zLCBjYW1lcmFQb3MsIC0xKTtcbiAgICAgICAgdmVjMy5tdWx0aXBseShjYW1lcmFQb3MsIGNhbWVyYVBvcywgbWV0ZXJzVG9QaXhlbCk7XG5cbiAgICAgICAgY29uc3QgbSA9IG1hdDQuY3JlYXRlKCk7XG4gICAgICAgIG1hdDQudHJhbnNsYXRlKG0sIG0sIGNhbWVyYVBvcyk7XG4gICAgICAgIG1hdDQuc2NhbGUobSwgbSwgbWV0ZXJzVG9QaXhlbCk7XG4gICAgICAgIHRoaXMubWVyY2F0b3JGb2dNYXRyaXggPSBtO1xuXG4gICAgICAgIC8vIFRoZSB3b3JsZFRvRm9nTWF0cml4IGNhbiBiZSB1c2VkIGZvciBjb252ZXJzaW9uIGZyb20gd29ybGQgY29vcmRpbmF0ZXMgdG8gcmVsYXRpdmUgY2FtZXJhIHBvc2l0aW9uIGluXG4gICAgICAgIC8vIHVuaXRzIG9mIGZyYWN0aW9ucyBvZiB0aGUgbWFwIGhlaWdodC4gTGF0ZXIgY29tcG9zZWQgd2l0aCB0aWxlIHBvc2l0aW9uIHRvIGNvbnN0cnVjdCB0aGUgZm9nIHRpbGUgbWF0cml4LlxuICAgICAgICB0aGlzLndvcmxkVG9Gb2dNYXRyaXggPSB0aGlzLl9jYW1lcmEuZ2V0V29ybGRUb0NhbWVyYVBvc2l0aW9uKGNhbWVyYVdvcmxkU2l6ZUZvckZvZywgY2FtZXJhUGl4ZWxzUGVyTWV0ZXIsIHdpbmRvd1NjYWxlRmFjdG9yKTtcbiAgICB9XG5cbiAgICBfY29tcHV0ZUNhbWVyYVBvc2l0aW9uKHRhcmdldFBpeGVsc1Blck1ldGVyOiA/bnVtYmVyKTogVmVjMyB7XG4gICAgICAgIHRhcmdldFBpeGVsc1Blck1ldGVyID0gdGFyZ2V0UGl4ZWxzUGVyTWV0ZXIgfHwgdGhpcy5waXhlbHNQZXJNZXRlcjtcbiAgICAgICAgY29uc3QgcGl4ZWxTcGFjZUNvbnZlcnNpb24gPSB0YXJnZXRQaXhlbHNQZXJNZXRlciAvIHRoaXMucGl4ZWxzUGVyTWV0ZXI7XG5cbiAgICAgICAgY29uc3QgZGlyID0gdGhpcy5fY2FtZXJhLmZvcndhcmQoKTtcbiAgICAgICAgY29uc3QgY2VudGVyID0gdGhpcy5wb2ludDtcblxuICAgICAgICAvLyBDb21wdXRlIGNhbWVyYSBwb3NpdGlvbiB1c2luZyB0aGUgZm9sbG93aW5nIHZlY3RvciBtYXRoOiBjYW1lcmEucG9zaXRpb24gPSBtYXAuY2VudGVyIC0gY2FtZXJhLmZvcndhcmQgKiBjYW1lcmFUb0NlbnRlckRpc3RcbiAgICAgICAgLy8gQ2FtZXJhIGRpc3RhbmNlIHRvIHRoZSBjZW50ZXIgY2FuIGJlIGZvdW5kIGluIG1lcmNhdG9yIHVuaXRzIGJ5IHN1YnRyYWN0aW5nIHRoZSBjZW50ZXIgZWxldmF0aW9uIGZyb21cbiAgICAgICAgLy8gY2FtZXJhJ3MgemVuaXRoIHBvc2l0aW9uICh3aGljaCBjYW4gYmUgZGVkdWNlZCBmcm9tIHRoZSB6b29tIGxldmVsKVxuICAgICAgICBjb25zdCB6b29tID0gdGhpcy5fc2VhTGV2ZWxab29tID8gdGhpcy5fc2VhTGV2ZWxab29tIDogdGhpcy5fem9vbTtcbiAgICAgICAgY29uc3QgYWx0aXR1ZGUgPSB0aGlzLl9tZXJjYXRvclpmcm9tWm9vbSh6b29tKSAqIHBpeGVsU3BhY2VDb252ZXJzaW9uO1xuICAgICAgICBjb25zdCBkaXN0YW5jZSA9IGFsdGl0dWRlIC0gdGFyZ2V0UGl4ZWxzUGVyTWV0ZXIgLyB0aGlzLndvcmxkU2l6ZSAqIHRoaXMuX2NlbnRlckFsdGl0dWRlO1xuXG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBjZW50ZXIueCAvIHRoaXMud29ybGRTaXplIC0gZGlyWzBdICogZGlzdGFuY2UsXG4gICAgICAgICAgICBjZW50ZXIueSAvIHRoaXMud29ybGRTaXplIC0gZGlyWzFdICogZGlzdGFuY2UsXG4gICAgICAgICAgICB0YXJnZXRQaXhlbHNQZXJNZXRlciAvIHRoaXMud29ybGRTaXplICogdGhpcy5fY2VudGVyQWx0aXR1ZGUgLSBkaXJbMl0gKiBkaXN0YW5jZVxuICAgICAgICBdO1xuICAgIH1cblxuICAgIF91cGRhdGVDYW1lcmFTdGF0ZSgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmhlaWdodCkgcmV0dXJuO1xuXG4gICAgICAgIC8vIFNldCBjYW1lcmEgb3JpZW50YXRpb24gYW5kIG1vdmUgaXQgdG8gYSBwcm9wZXIgZGlzdGFuY2UgZnJvbSB0aGUgbWFwXG4gICAgICAgIHRoaXMuX2NhbWVyYS5zZXRQaXRjaEJlYXJpbmcodGhpcy5fcGl0Y2gsIHRoaXMuYW5nbGUpO1xuICAgICAgICB0aGlzLl9jYW1lcmEucG9zaXRpb24gPSB0aGlzLl9jb21wdXRlQ2FtZXJhUG9zaXRpb24oKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBcHBseSBhIDNkIHRyYW5zbGF0aW9uIHRvIHRoZSBjYW1lcmEgcG9zaXRpb24sIGJ1dCBjbGFtcGluZyBpdCBzbyB0aGF0XG4gICAgICogaXQgcmVzcGVjdHMgdGhlIG1heGltdW0gbG9uZ2l0dWRlIGFuZCBsYXRpdHVkZSByYW5nZSBzZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3ZlYzN9IHRyYW5zbGF0aW9uIFRoZSB0cmFuc2xhdGlvbiB2ZWN0b3IuXG4gICAgICovXG4gICAgX3RyYW5zbGF0ZUNhbWVyYUNvbnN0cmFpbmVkKHRyYW5zbGF0aW9uOiBWZWMzKSB7XG4gICAgICAgIGNvbnN0IG1heERpc3RhbmNlID0gdGhpcy5fbWF4Q2FtZXJhQm91bmRzRGlzdGFuY2UoKTtcbiAgICAgICAgLy8gRGVmaW5lIGEgY2VpbGluZyBpbiBtZXJjYXRvciBaXG4gICAgICAgIGNvbnN0IG1heFogPSBtYXhEaXN0YW5jZSAqIE1hdGguY29zKHRoaXMuX3BpdGNoKTtcbiAgICAgICAgY29uc3QgeiA9IHRoaXMuX2NhbWVyYS5wb3NpdGlvblsyXTtcbiAgICAgICAgY29uc3QgZGVsdGFaID0gdHJhbnNsYXRpb25bMl07XG4gICAgICAgIGxldCB0ID0gMTtcblxuICAgICAgICBpZiAodGhpcy5wcm9qZWN0aW9uLndyYXApIHRoaXMuY2VudGVyID0gdGhpcy5jZW50ZXIud3JhcCgpO1xuXG4gICAgICAgIC8vIHdlIG9ubHkgbmVlZCB0byBjbGFtcCBpZiB0aGUgY2FtZXJhIGlzIG1vdmluZyB1cHdhcmRzXG4gICAgICAgIGlmIChkZWx0YVogPiAwKSB7XG4gICAgICAgICAgICB0ID0gTWF0aC5taW4oKG1heFogLSB6KSAvIGRlbHRhWiwgMSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9jYW1lcmEucG9zaXRpb24gPSB2ZWMzLnNjYWxlQW5kQWRkKFtdLCB0aGlzLl9jYW1lcmEucG9zaXRpb24sIHRyYW5zbGF0aW9uLCB0KTtcbiAgICAgICAgdGhpcy5fdXBkYXRlU3RhdGVGcm9tQ2FtZXJhKCk7XG4gICAgfVxuXG4gICAgX3VwZGF0ZVN0YXRlRnJvbUNhbWVyYSgpIHtcbiAgICAgICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLl9jYW1lcmEucG9zaXRpb247XG4gICAgICAgIGNvbnN0IGRpciA9IHRoaXMuX2NhbWVyYS5mb3J3YXJkKCk7XG4gICAgICAgIGNvbnN0IHtwaXRjaCwgYmVhcmluZ30gPSB0aGlzLl9jYW1lcmEuZ2V0UGl0Y2hCZWFyaW5nKCk7XG5cbiAgICAgICAgLy8gQ29tcHV0ZSB6b29tIGZyb20gdGhlIGRpc3RhbmNlIGJldHdlZW4gY2FtZXJhIGFuZCB0ZXJyYWluXG4gICAgICAgIGNvbnN0IGNlbnRlckFsdGl0dWRlID0gbWVyY2F0b3JaZnJvbUFsdGl0dWRlKHRoaXMuX2NlbnRlckFsdGl0dWRlLCB0aGlzLmNlbnRlci5sYXQpICogdGhpcy5fcGl4ZWxzUGVyTWVyY2F0b3JQaXhlbDtcbiAgICAgICAgY29uc3QgbWluSGVpZ2h0ID0gdGhpcy5fbWVyY2F0b3JaZnJvbVpvb20odGhpcy5fbWF4Wm9vbSkgKiBNYXRoLmNvcyhkZWdUb1JhZCh0aGlzLl9tYXhQaXRjaCkpO1xuICAgICAgICBjb25zdCBoZWlnaHQgPSBNYXRoLm1heCgocG9zaXRpb25bMl0gLSBjZW50ZXJBbHRpdHVkZSkgLyBNYXRoLmNvcyhwaXRjaCksIG1pbkhlaWdodCk7XG4gICAgICAgIGNvbnN0IHpvb20gPSB0aGlzLl96b29tRnJvbU1lcmNhdG9yWihoZWlnaHQpO1xuXG4gICAgICAgIC8vIENhc3QgYSByYXkgdG93YXJkcyB0aGUgZ3JvdW5kIHRvIGZpbmQgdGhlIGNlbnRlciBwb2ludFxuICAgICAgICB2ZWMzLnNjYWxlQW5kQWRkKHBvc2l0aW9uLCBwb3NpdGlvbiwgZGlyLCBoZWlnaHQpO1xuXG4gICAgICAgIHRoaXMuX3BpdGNoID0gY2xhbXAocGl0Y2gsIGRlZ1RvUmFkKHRoaXMubWluUGl0Y2gpLCBkZWdUb1JhZCh0aGlzLm1heFBpdGNoKSk7XG4gICAgICAgIHRoaXMuYW5nbGUgPSB3cmFwKGJlYXJpbmcsIC1NYXRoLlBJLCBNYXRoLlBJKTtcbiAgICAgICAgdGhpcy5fc2V0Wm9vbShjbGFtcCh6b29tLCB0aGlzLl9taW5ab29tLCB0aGlzLl9tYXhab29tKSk7XG4gICAgICAgIHRoaXMuX3VwZGF0ZVNlYUxldmVsWm9vbSgpO1xuXG4gICAgICAgIHRoaXMuX2NlbnRlciA9IHRoaXMuY29vcmRpbmF0ZUxvY2F0aW9uKG5ldyBNZXJjYXRvckNvb3JkaW5hdGUocG9zaXRpb25bMF0sIHBvc2l0aW9uWzFdLCBwb3NpdGlvblsyXSkpO1xuICAgICAgICB0aGlzLl91bm1vZGlmaWVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX2NvbnN0cmFpbigpO1xuICAgICAgICB0aGlzLl9jYWxjTWF0cmljZXMoKTtcbiAgICB9XG5cbiAgICBfd29ybGRTaXplRnJvbVpvb20oem9vbTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIE1hdGgucG93KDIuMCwgem9vbSkgKiB0aGlzLnRpbGVTaXplO1xuICAgIH1cblxuICAgIF9tZXJjYXRvclpmcm9tWm9vbSh6b29tOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5jYW1lcmFUb0NlbnRlckRpc3RhbmNlIC8gdGhpcy5fd29ybGRTaXplRnJvbVpvb20oem9vbSk7XG4gICAgfVxuXG4gICAgX21pbmltdW1IZWlnaHRPdmVyVGVycmFpbigpOiBudW1iZXIge1xuICAgICAgICAvLyBEZXRlcm1pbmUgbWluaW11bSBoZWlnaHQgZm9yIHRoZSBjYW1lcmEgb3ZlciB0aGUgdGVycmFpbiByZWxhdGVkIHRvIGN1cnJlbnQgem9vbS5cbiAgICAgICAgLy8gVmFsdWVzIGFib3ZlIDQgYWxsb3cgY2FtZXJhIGNsb3NlciB0byBlLmcuIHRvcCBvZiB0aGUgaGlsbCwgZXhwb3NpbmdcbiAgICAgICAgLy8gZHJhcGUgcmFzdGVyIG92ZXJzY2FsZSBhcnRpZmFjdHMgb3IgY3V0IHRlcnJhaW4gKHNlZSB1bmRlciBpdCkgYXMgaXQgZ2V0cyBjbGlwcGVkIG9uXG4gICAgICAgIC8vIG5lYXIgcGxhbmUuIFJldHVybmVkIHZhbHVlIGlzIGluIG1lcmNhdG9yIGNvb3JkaW5hdGVzLlxuICAgICAgICBjb25zdCBNQVhfRFJBUEVfT1ZFUlpPT00gPSA0O1xuICAgICAgICBjb25zdCB6b29tID0gTWF0aC5taW4oKHRoaXMuX3NlYUxldmVsWm9vbSAhPSBudWxsID8gdGhpcy5fc2VhTGV2ZWxab29tIDogdGhpcy5fem9vbSkgKyBNQVhfRFJBUEVfT1ZFUlpPT00sIHRoaXMuX21heFpvb20pO1xuICAgICAgICByZXR1cm4gdGhpcy5fbWVyY2F0b3JaZnJvbVpvb20oem9vbSk7XG4gICAgfVxuXG4gICAgX3pvb21Gcm9tTWVyY2F0b3JaKHo6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLnNjYWxlWm9vbSh0aGlzLmNhbWVyYVRvQ2VudGVyRGlzdGFuY2UgLyAoeiAqIHRoaXMudGlsZVNpemUpKTtcbiAgICB9XG5cbiAgICAvLyBUaGlzIGZ1bmN0aW9uIGlzIGhlbHBmdWwgdG8gYXBwcm94aW1hdGUgdHJ1ZSB6b29tIGdpdmVuIGEgbWVyY2F0b3IgaGVpZ2h0IHdpdGggdmFyeWluZyBwcG0uXG4gICAgLy8gV2l0aCBHbG9iZSwgc2luY2Ugd2UgdXNlIGEgZml4ZWQgcmVmZXJlbmNlIGxhdGl0dWRlIGF0IGxvd2VyIHpvb20gbGV2ZWxzIGFuZCB0cmFuc2l0aW9uIGJldHdlZW4gdGhpc1xuICAgIC8vIGxhdGl0dWRlIGFuZCB0aGUgY2VudGVyJ3MgbGF0aXR1ZGUgYXMgeW91IHpvb20gaW4sIGNhbWVyYSB0byBjZW50ZXIgZGlzdGFuY2UgdmFyaWVzIGR5bmFtaWNhbGx5LlxuICAgIC8vIEFzIHRoZSBjYW1lcmFUb0NlbnRlckRpc3RhbmNlIGlzIGEgZnVuY3Rpb24gb2Ygem9vbSwgd2UgbmVlZCB0byBhcHByb3hpbWF0ZSB0aGUgdHJ1ZSB6b29tXG4gICAgLy8gZ2l2ZW4gYSBtZXJjYXRvciBtZXRlciB2YWx1ZSBpbiBvcmRlciB0byBlbGltaW5hdGUgdGhlIHpvb20vY2FtZXJhVG9DZW50ZXJEaXN0YW5jZSBkZXBlbmRlbmN5LlxuICAgIHpvb21Gcm9tTWVyY2F0b3JaQWRqdXN0ZWQobWVyY2F0b3JaOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBhc3NlcnQodGhpcy5wcm9qZWN0aW9uLm5hbWUgPT09ICdnbG9iZScpO1xuICAgICAgICBhc3NlcnQobWVyY2F0b3JaICE9PSAwKTtcblxuICAgICAgICBsZXQgem9vbUxvdyA9IDA7XG4gICAgICAgIGxldCB6b29tSGlnaCA9IEdMT0JFX1pPT01fVEhSRVNIT0xEX01BWDtcbiAgICAgICAgbGV0IHpvb20gPSAwO1xuICAgICAgICBsZXQgbWluWm9vbURpZmYgPSBJbmZpbml0eTtcblxuICAgICAgICBjb25zdCBlcHNpbG9uID0gMWUtNjtcblxuICAgICAgICB3aGlsZSAoem9vbUhpZ2ggLSB6b29tTG93ID4gZXBzaWxvbiAmJiB6b29tSGlnaCA+IHpvb21Mb3cpIHtcbiAgICAgICAgICAgIGNvbnN0IHpvb21NaWQgPSB6b29tTG93ICsgKHpvb21IaWdoIC0gem9vbUxvdykgKiAwLjU7XG5cbiAgICAgICAgICAgIGNvbnN0IHdvcmxkU2l6ZSA9IHRoaXMudGlsZVNpemUgKiBNYXRoLnBvdygyLCB6b29tTWlkKTtcbiAgICAgICAgICAgIGNvbnN0IGQgPSB0aGlzLmdldENhbWVyYVRvQ2VudGVyRGlzdGFuY2UodGhpcy5wcm9qZWN0aW9uLCB6b29tTWlkLCB3b3JsZFNpemUpO1xuICAgICAgICAgICAgY29uc3QgbmV3Wm9vbSA9IHRoaXMuc2NhbGVab29tKGQgLyAobWVyY2F0b3JaICogdGhpcy50aWxlU2l6ZSkpO1xuXG4gICAgICAgICAgICBjb25zdCBkaWZmID0gTWF0aC5hYnMoem9vbU1pZCAtIG5ld1pvb20pO1xuXG4gICAgICAgICAgICBpZiAoZGlmZiA8IG1pblpvb21EaWZmKSB7XG4gICAgICAgICAgICAgICAgbWluWm9vbURpZmYgPSBkaWZmO1xuICAgICAgICAgICAgICAgIHpvb20gPSB6b29tTWlkO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoem9vbU1pZCA8IG5ld1pvb20pIHtcbiAgICAgICAgICAgICAgICB6b29tTG93ID0gem9vbU1pZDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgem9vbUhpZ2ggPSB6b29tTWlkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHpvb207XG4gICAgfVxuXG4gICAgX3RlcnJhaW5FbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAoIXRoaXMuX2VsZXZhdGlvbikgcmV0dXJuIGZhbHNlO1xuICAgICAgICBpZiAoIXRoaXMucHJvamVjdGlvbi5zdXBwb3J0c1RlcnJhaW4pIHtcbiAgICAgICAgICAgIHdhcm5PbmNlKCdUZXJyYWluIGlzIG5vdCB5ZXQgc3VwcG9ydGVkIHdpdGggYWx0ZXJuYXRlIHByb2plY3Rpb25zLiBVc2UgbWVyY2F0b3Igb3IgZ2xvYmUgdG8gZW5hYmxlIHRlcnJhaW4uJyk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgYW55IG9mIHRoZSBmb3VyIGNvcm5lcnMgYXJlIG9mZiB0aGUgZWRnZSBvZiB0aGUgcmVuZGVyZWQgbWFwXG4gICAgLy8gVGhpcyBmdW5jdGlvbiB3aWxsIHJldHVybiBgZmFsc2VgIGZvciBhbGwgbm9uLW1lcmNhdG9yIHByb2plY3Rpb25cbiAgICBhbnlDb3JuZXJPZmZFZGdlKHAwOiBQb2ludCwgcDE6IFBvaW50KTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IG1pblggPSBNYXRoLm1pbihwMC54LCBwMS54KTtcbiAgICAgICAgY29uc3QgbWF4WCA9IE1hdGgubWF4KHAwLngsIHAxLngpO1xuICAgICAgICBjb25zdCBtaW5ZID0gTWF0aC5taW4ocDAueSwgcDEueSk7XG4gICAgICAgIGNvbnN0IG1heFkgPSBNYXRoLm1heChwMC55LCBwMS55KTtcblxuICAgICAgICBjb25zdCBob3Jpem9uID0gdGhpcy5ob3Jpem9uTGluZUZyb21Ub3AoZmFsc2UpO1xuICAgICAgICBpZiAobWluWSA8IGhvcml6b24pIHJldHVybiB0cnVlO1xuXG4gICAgICAgIGlmICh0aGlzLnByb2plY3Rpb24ubmFtZSAhPT0gJ21lcmNhdG9yJykge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbWluID0gbmV3IFBvaW50KG1pblgsIG1pblkpO1xuICAgICAgICBjb25zdCBtYXggPSBuZXcgUG9pbnQobWF4WCwgbWF4WSk7XG5cbiAgICAgICAgY29uc3QgY29ybmVycyA9IFtcbiAgICAgICAgICAgIG1pbiwgbWF4LFxuICAgICAgICAgICAgbmV3IFBvaW50KG1pblgsIG1heFkpLFxuICAgICAgICAgICAgbmV3IFBvaW50KG1heFgsIG1pblkpLFxuICAgICAgICBdO1xuXG4gICAgICAgIGNvbnN0IG1pbldYID0gKHRoaXMucmVuZGVyV29ybGRDb3BpZXMpID8gLU5VTV9XT1JMRF9DT1BJRVMgOiAwO1xuICAgICAgICBjb25zdCBtYXhXWCA9ICh0aGlzLnJlbmRlcldvcmxkQ29waWVzKSA/IDEgKyBOVU1fV09STERfQ09QSUVTIDogMTtcbiAgICAgICAgY29uc3QgbWluV1kgPSAwO1xuICAgICAgICBjb25zdCBtYXhXWSA9IDE7XG5cbiAgICAgICAgZm9yIChjb25zdCBjb3JuZXIgb2YgY29ybmVycykge1xuICAgICAgICAgICAgY29uc3QgcmF5SW50ZXJzZWN0aW9uID0gdGhpcy5wb2ludFJheUludGVyc2VjdGlvbihjb3JuZXIpO1xuICAgICAgICAgICAgLy8gUG9pbnQgaXMgYWJvdmUgdGhlIGhvcml6b25cbiAgICAgICAgICAgIGlmIChyYXlJbnRlcnNlY3Rpb24udCA8IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFBvaW50IGlzIG9mZiB0aGUgYm9uZGFyaWVzIG9mIHRoZSBtYXBcbiAgICAgICAgICAgIGNvbnN0IGNvb3JkaW5hdGUgPSB0aGlzLnJheUludGVyc2VjdGlvbkNvb3JkaW5hdGUocmF5SW50ZXJzZWN0aW9uKTtcbiAgICAgICAgICAgIGlmIChjb29yZGluYXRlLnggPCBtaW5XWCB8fCBjb29yZGluYXRlLnkgPCBtaW5XWSB8fFxuICAgICAgICAgICAgICAgIGNvb3JkaW5hdGUueCA+IG1heFdYIHx8IGNvb3JkaW5hdGUueSA+IG1heFdZKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2tzIHRoZSBmb3VyIGNvcm5lcnMgb2YgdGhlIGZydXN0dW0gdG8gc2VlIGlmIHRoZXkgbGllIGluIHRoZSBtYXAncyBxdWFkLlxuICAgIC8vXG4gICAgaXNIb3Jpem9uVmlzaWJsZSgpOiBib29sZWFuIHtcblxuICAgICAgICAvLyB3ZSBjb25zaWRlciB0aGUgaG9yaXpvbiBhcyB2aXNpYmxlIGlmIHRoZSBhbmdsZSBiZXR3ZWVuXG4gICAgICAgIC8vIGEgdGhlIHRvcCBwbGFuZSBvZiB0aGUgZnJ1c3R1bSBhbmQgdGhlIG1hcCBwbGFuZSBpcyBzbWFsbGVyIHRoYW4gdGhpcyB0aHJlc2hvbGQuXG4gICAgICAgIGNvbnN0IGhvcml6b25BbmdsZUVwc2lsb24gPSAyO1xuICAgICAgICBpZiAodGhpcy5waXRjaCArIHJhZFRvRGVnKHRoaXMuZm92QWJvdmVDZW50ZXIpID4gKDkwIC0gaG9yaXpvbkFuZ2xlRXBzaWxvbikpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuYW55Q29ybmVyT2ZmRWRnZShuZXcgUG9pbnQoMCwgMCksIG5ldyBQb2ludCh0aGlzLndpZHRoLCB0aGlzLmhlaWdodCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGEgem9vbSBkZWx0YSB2YWx1ZSBpbnRvIGEgcGh5c2ljYWwgZGlzdGFuY2UgdHJhdmVsbGVkIGluIHdlYiBtZXJjYXRvciBjb29yZGluYXRlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7dmVjM30gY2VudGVyIERlc3RpbmF0aW9uIG1lcmNhdG9yIHBvaW50IG9mIHRoZSBtb3ZlbWVudC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gem9vbURlbHRhIENoYW5nZSBpbiB0aGUgem9vbSB2YWx1ZS5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgZGlzdGFuY2UgaW4gbWVyY2F0b3IgY29vcmRpbmF0ZXMuXG4gICAgICovXG4gICAgem9vbURlbHRhVG9Nb3ZlbWVudChjZW50ZXI6IFZlYzMsIHpvb21EZWx0YTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgZGlzdGFuY2UgPSB2ZWMzLmxlbmd0aCh2ZWMzLnN1YihbXSwgdGhpcy5fY2FtZXJhLnBvc2l0aW9uLCBjZW50ZXIpKTtcbiAgICAgICAgY29uc3QgcmVsYXRpdmVab29tID0gdGhpcy5fem9vbUZyb21NZXJjYXRvclooZGlzdGFuY2UpICsgem9vbURlbHRhO1xuICAgICAgICByZXR1cm4gZGlzdGFuY2UgLSB0aGlzLl9tZXJjYXRvclpmcm9tWm9vbShyZWxhdGl2ZVpvb20pO1xuICAgIH1cblxuICAgIC8qXG4gICAgICogVGhlIGNhbWVyYSBsb29rcyBhdCB0aGUgbWFwIGZyb20gYSAzRCAobG5nLCBsYXQsIGFsdGl0dWRlKSBsb2NhdGlvbi4gTGV0J3MgdXNlIGBjYW1lcmFMb2NhdGlvbmBcbiAgICAgKiBhcyB0aGUgbmFtZSBmb3IgdGhlIGxvY2F0aW9uIHVuZGVyIHRoZSBjYW1lcmEgYW5kIG9uIHRoZSBzdXJmYWNlIG9mIHRoZSBlYXJ0aCAobG5nLCBsYXQsIDApLlxuICAgICAqIGBjYW1lcmFQb2ludGAgaXMgdGhlIHByb2plY3RlZCBwb3NpdGlvbiBvZiB0aGUgYGNhbWVyYUxvY2F0aW9uYC5cbiAgICAgKlxuICAgICAqIFRoaXMgcG9pbnQgaXMgdXNlZnVsIHRvIHVzIGJlY2F1c2Ugb25seSBmaWxsLWV4dHJ1c2lvbnMgdGhhdCBhcmUgYmV0d2VlbiBgY2FtZXJhUG9pbnRgIGFuZFxuICAgICAqIHRoZSBxdWVyeSBwb2ludCBvbiB0aGUgc3VyZmFjZSBvZiB0aGUgZWFydGggY2FuIGV4dGVuZCBhbmQgaW50ZXJzZWN0IHRoZSBxdWVyeS5cbiAgICAgKlxuICAgICAqIFdoZW4gdGhlIG1hcCBpcyBub3QgcGl0Y2hlZCB0aGUgYGNhbWVyYVBvaW50YCBpcyBlcXVpdmFsZW50IHRvIHRoZSBjZW50ZXIgb2YgdGhlIG1hcCBiZWNhdXNlXG4gICAgICogdGhlIGNhbWVyYSBpcyByaWdodCBhYm92ZSB0aGUgY2VudGVyIG9mIHRoZSBtYXAuXG4gICAgICovXG4gICAgZ2V0Q2FtZXJhUG9pbnQoKTogUG9pbnQge1xuICAgICAgICBpZiAodGhpcy5wcm9qZWN0aW9uLm5hbWUgPT09ICdnbG9iZScpIHtcbiAgICAgICAgICAgIC8vIEZpbmQgcHJlY2lzZSBsb2NhdGlvbiBvZiB0aGUgcHJvamVjdGVkIGNhbWVyYSBwb3NpdGlvbiBvbiB0aGUgY3VydmVkIHN1cmZhY2VcbiAgICAgICAgICAgIGNvbnN0IGNlbnRlciA9IFt0aGlzLmdsb2JlTWF0cml4WzEyXSwgdGhpcy5nbG9iZU1hdHJpeFsxM10sIHRoaXMuZ2xvYmVNYXRyaXhbMTRdXTtcbiAgICAgICAgICAgIGNvbnN0IHBvcyA9IHByb2plY3RDbGFtcGVkKGNlbnRlciwgdGhpcy5waXhlbE1hdHJpeCk7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFBvaW50KHBvc1swXSwgcG9zWzFdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHBpdGNoID0gdGhpcy5fcGl0Y2g7XG4gICAgICAgICAgICBjb25zdCB5T2Zmc2V0ID0gTWF0aC50YW4ocGl0Y2gpICogKHRoaXMuY2FtZXJhVG9DZW50ZXJEaXN0YW5jZSB8fCAxKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNlbnRlclBvaW50LmFkZChuZXcgUG9pbnQoMCwgeU9mZnNldCkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0Q2FtZXJhVG9DZW50ZXJEaXN0YW5jZShwcm9qZWN0aW9uOiBQcm9qZWN0aW9uLCB6b29tOiBudW1iZXIgPSB0aGlzLnpvb20sIHdvcmxkU2l6ZTogbnVtYmVyID0gdGhpcy53b3JsZFNpemUpOiBudW1iZXIge1xuICAgICAgICBjb25zdCB0ID0gZ2V0UHJvamVjdGlvbkludGVycG9sYXRpb25UKHByb2plY3Rpb24sIHpvb20sIHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0LCAxMDI0KTtcbiAgICAgICAgY29uc3QgcHJvamVjdGlvblNjYWxlciA9IHByb2plY3Rpb24ucGl4ZWxTcGFjZUNvbnZlcnNpb24odGhpcy5jZW50ZXIubGF0LCB3b3JsZFNpemUsIHQpO1xuICAgICAgICByZXR1cm4gMC41IC8gTWF0aC50YW4odGhpcy5fZm92ICogMC41KSAqIHRoaXMuaGVpZ2h0ICogcHJvamVjdGlvblNjYWxlcjtcbiAgICB9XG5cbiAgICBnZXRXb3JsZFRvQ2FtZXJhTWF0cml4KCk6IE1hdDQge1xuICAgICAgICBjb25zdCB6VW5pdCA9IHRoaXMucHJvamVjdGlvbi56QXhpc1VuaXQgPT09IFwibWV0ZXJzXCIgPyB0aGlzLnBpeGVsc1Blck1ldGVyIDogMS4wO1xuICAgICAgICBjb25zdCB3b3JsZFRvQ2FtZXJhID0gdGhpcy5fY2FtZXJhLmdldFdvcmxkVG9DYW1lcmEodGhpcy53b3JsZFNpemUsIHpVbml0KTtcblxuICAgICAgICBpZiAodGhpcy5wcm9qZWN0aW9uLm5hbWUgPT09ICdnbG9iZScpIHtcbiAgICAgICAgICAgIG1hdDQubXVsdGlwbHkod29ybGRUb0NhbWVyYSwgd29ybGRUb0NhbWVyYSwgdGhpcy5nbG9iZU1hdHJpeCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gd29ybGRUb0NhbWVyYTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFRyYW5zZm9ybTtcbiIsIi8vIEBmbG93IHN0cmljdFxuXG4vKipcbiAqIFRocm90dGxlIHRoZSBnaXZlbiBmdW5jdGlvbiB0byBydW4gYXQgbW9zdCBldmVyeSBgcGVyaW9kYCBtaWxsaXNlY29uZHMuXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB0aHJvdHRsZShmbjogKCkgPT4gdm9pZCwgdGltZTogbnVtYmVyKTogKCkgPT4gP1RpbWVvdXRJRCB7XG4gICAgbGV0IHBlbmRpbmcgPSBmYWxzZTtcbiAgICBsZXQgdGltZXJJZDogP1RpbWVvdXRJRCA9IG51bGw7XG5cbiAgICBjb25zdCBsYXRlciA9ICgpID0+IHtcbiAgICAgICAgdGltZXJJZCA9IG51bGw7XG4gICAgICAgIGlmIChwZW5kaW5nKSB7XG4gICAgICAgICAgICBmbigpO1xuICAgICAgICAgICAgdGltZXJJZCA9IHNldFRpbWVvdXQobGF0ZXIsIHRpbWUpO1xuICAgICAgICAgICAgcGVuZGluZyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIHBlbmRpbmcgPSB0cnVlO1xuICAgICAgICBpZiAoIXRpbWVySWQpIHtcbiAgICAgICAgICAgIGxhdGVyKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRpbWVySWQ7XG4gICAgfTtcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCB7YmluZEFsbH0gZnJvbSAnLi4vdXRpbC91dGlsLmpzJztcbmltcG9ydCB3aW5kb3cgZnJvbSAnLi4vdXRpbC93aW5kb3cuanMnO1xuaW1wb3J0IHRocm90dGxlIGZyb20gJy4uL3V0aWwvdGhyb3R0bGUuanMnO1xuXG5pbXBvcnQgdHlwZSBNYXAgZnJvbSAnLi9tYXAuanMnO1xuXG4vKlxuICogQWRkcyB0aGUgbWFwJ3MgcG9zaXRpb24gdG8gaXRzIHBhZ2UncyBsb2NhdGlvbiBoYXNoLlxuICogUGFzc2VkIGFzIGFuIG9wdGlvbiB0byB0aGUgbWFwIG9iamVjdC5cbiAqXG4gKiBAcmV0dXJucyB7SGFzaH0gYHRoaXNgXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEhhc2gge1xuICAgIF9tYXA6ID9NYXA7XG4gICAgX3VwZGF0ZUhhc2g6ICgpID0+ID9UaW1lb3V0SUQ7XG4gICAgX2hhc2hOYW1lOiA/c3RyaW5nO1xuXG4gICAgY29uc3RydWN0b3IoaGFzaE5hbWU6ID9zdHJpbmcpIHtcbiAgICAgICAgdGhpcy5faGFzaE5hbWUgPSBoYXNoTmFtZSAmJiBlbmNvZGVVUklDb21wb25lbnQoaGFzaE5hbWUpO1xuICAgICAgICBiaW5kQWxsKFtcbiAgICAgICAgICAgICdfZ2V0Q3VycmVudEhhc2gnLFxuICAgICAgICAgICAgJ19vbkhhc2hDaGFuZ2UnLFxuICAgICAgICAgICAgJ191cGRhdGVIYXNoJ1xuICAgICAgICBdLCB0aGlzKTtcblxuICAgICAgICAvLyBNb2JpbGUgU2FmYXJpIGRvZXNuJ3QgYWxsb3cgdXBkYXRpbmcgdGhlIGhhc2ggbW9yZSB0aGFuIDEwMCB0aW1lcyBwZXIgMzAgc2Vjb25kcy5cbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICB0aGlzLl91cGRhdGVIYXNoID0gdGhyb3R0bGUodGhpcy5fdXBkYXRlSGFzaFVudGhyb3R0bGVkLmJpbmQodGhpcyksIDMwICogMTAwMCAvIDEwMCk7XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBNYXAgZWxlbWVudCB0byBsaXN0ZW4gZm9yIGNvb3JkaW5hdGUgY2hhbmdlc1xuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG1hcFxuICAgICAqIEByZXR1cm5zIHtIYXNofSBgdGhpc2BcbiAgICAgKi9cbiAgICBhZGRUbyhtYXA6IE1hcCk6IHRoaXMge1xuICAgICAgICB0aGlzLl9tYXAgPSBtYXA7XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2hhc2hjaGFuZ2UnLCB0aGlzLl9vbkhhc2hDaGFuZ2UsIGZhbHNlKTtcbiAgICAgICAgbWFwLm9uKCdtb3ZlZW5kJywgdGhpcy5fdXBkYXRlSGFzaCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qXG4gICAgICogUmVtb3ZlcyBoYXNoXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7UG9wdXB9IGB0aGlzYFxuICAgICAqL1xuICAgIHJlbW92ZSgpOiB0aGlzIHtcbiAgICAgICAgaWYgKCF0aGlzLl9tYXApIHJldHVybiB0aGlzO1xuXG4gICAgICAgIHRoaXMuX21hcC5vZmYoJ21vdmVlbmQnLCB0aGlzLl91cGRhdGVIYXNoKTtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignaGFzaGNoYW5nZScsIHRoaXMuX29uSGFzaENoYW5nZSwgZmFsc2UpO1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5fdXBkYXRlSGFzaCgpKTtcblxuICAgICAgICB0aGlzLl9tYXAgPSB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIGdldEhhc2hTdHJpbmcoKTogc3RyaW5nIHtcbiAgICAgICAgY29uc3QgbWFwID0gdGhpcy5fbWFwO1xuICAgICAgICBpZiAoIW1hcCkgcmV0dXJuICcnO1xuXG4gICAgICAgIGNvbnN0IGhhc2ggPSBnZXRIYXNoU3RyaW5nKG1hcCk7XG5cbiAgICAgICAgaWYgKHRoaXMuX2hhc2hOYW1lKSB7XG4gICAgICAgICAgICBjb25zdCBoYXNoTmFtZSA9IHRoaXMuX2hhc2hOYW1lO1xuICAgICAgICAgICAgbGV0IGZvdW5kID0gZmFsc2U7XG4gICAgICAgICAgICBjb25zdCBwYXJ0cyA9IHdpbmRvdy5sb2NhdGlvbi5oYXNoLnNsaWNlKDEpLnNwbGl0KCcmJykubWFwKHBhcnQgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGtleSA9IHBhcnQuc3BsaXQoJz0nKVswXTtcbiAgICAgICAgICAgICAgICBpZiAoa2V5ID09PSBoYXNoTmFtZSkge1xuICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgJHtrZXl9PSR7aGFzaH1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcGFydDtcbiAgICAgICAgICAgIH0pLmZpbHRlcihhID0+IGEpO1xuICAgICAgICAgICAgaWYgKCFmb3VuZCkge1xuICAgICAgICAgICAgICAgIHBhcnRzLnB1c2goYCR7aGFzaE5hbWV9PSR7aGFzaH1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBgIyR7cGFydHMuam9pbignJicpfWA7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYCMke2hhc2h9YDtcbiAgICB9XG5cbiAgICBfZ2V0Q3VycmVudEhhc2goKTogQXJyYXk8c3RyaW5nPiB7XG4gICAgICAgIC8vIEdldCB0aGUgY3VycmVudCBoYXNoIGZyb20gbG9jYXRpb24sIHN0cmlwcGVkIGZyb20gaXRzIG51bWJlciBzaWduXG4gICAgICAgIGNvbnN0IGhhc2ggPSB3aW5kb3cubG9jYXRpb24uaGFzaC5yZXBsYWNlKCcjJywgJycpO1xuICAgICAgICBpZiAodGhpcy5faGFzaE5hbWUpIHtcbiAgICAgICAgICAgIC8vIFNwbGl0IHRoZSBwYXJhbWV0ZXItc3R5bGVkIGhhc2ggaW50byBwYXJ0cyBhbmQgZmluZCB0aGUgdmFsdWUgd2UgbmVlZFxuICAgICAgICAgICAgbGV0IGtleXZhbDtcbiAgICAgICAgICAgIGhhc2guc3BsaXQoJyYnKS5tYXAoXG4gICAgICAgICAgICAgICAgcGFydCA9PiBwYXJ0LnNwbGl0KCc9JylcbiAgICAgICAgICAgICkuZm9yRWFjaChwYXJ0ID0+IHtcbiAgICAgICAgICAgICAgICBpZiAocGFydFswXSA9PT0gdGhpcy5faGFzaE5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAga2V5dmFsID0gcGFydDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiAoa2V5dmFsID8ga2V5dmFsWzFdIHx8ICcnIDogJycpLnNwbGl0KCcvJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGhhc2guc3BsaXQoJy8nKTtcbiAgICB9XG5cbiAgICBfb25IYXNoQ2hhbmdlKCk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCBtYXAgPSB0aGlzLl9tYXA7XG4gICAgICAgIGlmICghbWFwKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGNvbnN0IGxvYyA9IHRoaXMuX2dldEN1cnJlbnRIYXNoKCk7XG4gICAgICAgIGlmIChsb2MubGVuZ3RoID49IDMgJiYgIWxvYy5zb21lKHYgPT4gaXNOYU4odikpKSB7XG4gICAgICAgICAgICBjb25zdCBiZWFyaW5nID0gbWFwLmRyYWdSb3RhdGUuaXNFbmFibGVkKCkgJiYgbWFwLnRvdWNoWm9vbVJvdGF0ZS5pc0VuYWJsZWQoKSA/ICsobG9jWzNdIHx8IDApIDogbWFwLmdldEJlYXJpbmcoKTtcbiAgICAgICAgICAgIG1hcC5qdW1wVG8oe1xuICAgICAgICAgICAgICAgIGNlbnRlcjogWytsb2NbMl0sICtsb2NbMV1dLFxuICAgICAgICAgICAgICAgIHpvb206ICtsb2NbMF0sXG4gICAgICAgICAgICAgICAgYmVhcmluZyxcbiAgICAgICAgICAgICAgICBwaXRjaDogKyhsb2NbNF0gfHwgMClcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIF91cGRhdGVIYXNoVW50aHJvdHRsZWQoKSB7XG4gICAgICAgIC8vIFJlcGxhY2UgaWYgYWxyZWFkeSBwcmVzZW50LCBlbHNlIGFwcGVuZCB0aGUgdXBkYXRlZCBoYXNoIHN0cmluZ1xuICAgICAgICBjb25zdCBsb2NhdGlvbiA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmLnJlcGxhY2UoLygjLispPyQvLCB0aGlzLmdldEhhc2hTdHJpbmcoKSk7XG4gICAgICAgIHdpbmRvdy5oaXN0b3J5LnJlcGxhY2VTdGF0ZSh3aW5kb3cuaGlzdG9yeS5zdGF0ZSwgbnVsbCwgbG9jYXRpb24pO1xuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEhhc2hTdHJpbmcobWFwOiBNYXAsIG1hcEZlZWRiYWNrPzogYm9vbGVhbik6IHN0cmluZyB7XG4gICAgY29uc3QgY2VudGVyID0gbWFwLmdldENlbnRlcigpLFxuICAgICAgICB6b29tID0gTWF0aC5yb3VuZChtYXAuZ2V0Wm9vbSgpICogMTAwKSAvIDEwMCxcbiAgICAgICAgLy8gZGVyaXZlZCBmcm9tIGVxdWF0aW9uOiA1MTJweCAqIDJeeiAvIDM2MCAvIDEwXmQgPCAwLjVweFxuICAgICAgICBwcmVjaXNpb24gPSBNYXRoLmNlaWwoKHpvb20gKiBNYXRoLkxOMiArIE1hdGgubG9nKDUxMiAvIDM2MCAvIDAuNSkpIC8gTWF0aC5MTjEwKSxcbiAgICAgICAgbSA9IE1hdGgucG93KDEwLCBwcmVjaXNpb24pLFxuICAgICAgICBsbmcgPSBNYXRoLnJvdW5kKGNlbnRlci5sbmcgKiBtKSAvIG0sXG4gICAgICAgIGxhdCA9IE1hdGgucm91bmQoY2VudGVyLmxhdCAqIG0pIC8gbSxcbiAgICAgICAgYmVhcmluZyA9IG1hcC5nZXRCZWFyaW5nKCksXG4gICAgICAgIHBpdGNoID0gbWFwLmdldFBpdGNoKCk7XG5cbiAgICAvLyBuZXcgbWFwIGZlZWRiYWNrIHNpdGUgaGFzIHNvbWUgY29uc3RyYWludHMgdGhhdCBkb24ndCBhbGxvd1xuICAgIC8vIHVzIHRvIHVzZSB0aGUgc2FtZSBoYXNoIGZvcm1hdCBhcyB3ZSBkbyBmb3IgdGhlIE1hcCBoYXNoIG9wdGlvbi5cbiAgICBsZXQgaGFzaCA9IG1hcEZlZWRiYWNrID8gYC8ke2xuZ30vJHtsYXR9LyR7em9vbX1gIDogYCR7em9vbX0vJHtsYXR9LyR7bG5nfWA7XG5cbiAgICBpZiAoYmVhcmluZyB8fCBwaXRjaCkgaGFzaCArPSAoYC8ke01hdGgucm91bmQoYmVhcmluZyAqIDEwKSAvIDEwfWApO1xuICAgIGlmIChwaXRjaCkgaGFzaCArPSAoYC8ke01hdGgucm91bmQocGl0Y2gpfWApO1xuXG4gICAgcmV0dXJuIGhhc2g7XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgYnJvd3NlciBmcm9tICcuLi91dGlsL2Jyb3dzZXIuanMnO1xuaW1wb3J0IHR5cGUgTWFwIGZyb20gJy4vbWFwLmpzJztcbmltcG9ydCB7YmV6aWVyLCBjbGFtcCwgZXh0ZW5kfSBmcm9tICcuLi91dGlsL3V0aWwuanMnO1xuaW1wb3J0IFBvaW50IGZyb20gJ0BtYXBib3gvcG9pbnQtZ2VvbWV0cnknO1xuXG5pbXBvcnQgdHlwZSB7RHJhZ1Bhbk9wdGlvbnN9IGZyb20gJy4vaGFuZGxlci9zaGltL2RyYWdfcGFuLmpzJztcbmltcG9ydCB0eXBlIHtFYXNpbmdPcHRpb25zfSBmcm9tICcuLi91aS9jYW1lcmEuanMnO1xuXG5jb25zdCBkZWZhdWx0SW5lcnRpYU9wdGlvbnMgPSB7XG4gICAgbGluZWFyaXR5OiAwLjMsXG4gICAgZWFzaW5nOiBiZXppZXIoMCwgMCwgMC4zLCAxKSxcbn07XG5cbmNvbnN0IGRlZmF1bHRQYW5JbmVydGlhT3B0aW9ucyA9IGV4dGVuZCh7XG4gICAgZGVjZWxlcmF0aW9uOiAyNTAwLFxuICAgIG1heFNwZWVkOiAxNDAwXG59LCBkZWZhdWx0SW5lcnRpYU9wdGlvbnMpO1xuXG5jb25zdCBkZWZhdWx0Wm9vbUluZXJ0aWFPcHRpb25zID0gZXh0ZW5kKHtcbiAgICBkZWNlbGVyYXRpb246IDIwLFxuICAgIG1heFNwZWVkOiAxNDAwXG59LCBkZWZhdWx0SW5lcnRpYU9wdGlvbnMpO1xuXG5jb25zdCBkZWZhdWx0QmVhcmluZ0luZXJ0aWFPcHRpb25zID0gZXh0ZW5kKHtcbiAgICBkZWNlbGVyYXRpb246IDEwMDAsXG4gICAgbWF4U3BlZWQ6IDM2MFxufSwgZGVmYXVsdEluZXJ0aWFPcHRpb25zKTtcblxuY29uc3QgZGVmYXVsdFBpdGNoSW5lcnRpYU9wdGlvbnMgPSBleHRlbmQoe1xuICAgIGRlY2VsZXJhdGlvbjogMTAwMCxcbiAgICBtYXhTcGVlZDogOTBcbn0sIGRlZmF1bHRJbmVydGlhT3B0aW9ucyk7XG5cbmV4cG9ydCB0eXBlIEluZXJ0aWFPcHRpb25zID0ge1xuICAgIGxpbmVhcml0eTogbnVtYmVyO1xuICAgIGVhc2luZzogKHQ6IG51bWJlcikgPT4gbnVtYmVyO1xuICAgIGRlY2VsZXJhdGlvbjogbnVtYmVyO1xuICAgIG1heFNwZWVkOiBudW1iZXI7XG59O1xuXG5leHBvcnQgdHlwZSBJbnB1dEV2ZW50ID0gTW91c2VFdmVudCB8IFRvdWNoRXZlbnQgfCBLZXlib2FyZEV2ZW50IHwgV2hlZWxFdmVudDtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSGFuZGxlckluZXJ0aWEge1xuICAgIF9tYXA6IE1hcDtcbiAgICBfaW5lcnRpYUJ1ZmZlcjogQXJyYXk8eyB0aW1lOiBudW1iZXIsIHNldHRpbmdzOiBPYmplY3QgfT47XG5cbiAgICBjb25zdHJ1Y3RvcihtYXA6IE1hcCkge1xuICAgICAgICB0aGlzLl9tYXAgPSBtYXA7XG4gICAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICB9XG5cbiAgICBjbGVhcigpIHtcbiAgICAgICAgdGhpcy5faW5lcnRpYUJ1ZmZlciA9IFtdO1xuICAgIH1cblxuICAgIHJlY29yZChzZXR0aW5nczogYW55KSB7XG4gICAgICAgIHRoaXMuX2RyYWluSW5lcnRpYUJ1ZmZlcigpO1xuICAgICAgICB0aGlzLl9pbmVydGlhQnVmZmVyLnB1c2goe3RpbWU6IGJyb3dzZXIubm93KCksIHNldHRpbmdzfSk7XG4gICAgfVxuXG4gICAgX2RyYWluSW5lcnRpYUJ1ZmZlcigpIHtcbiAgICAgICAgY29uc3QgaW5lcnRpYSA9IHRoaXMuX2luZXJ0aWFCdWZmZXIsXG4gICAgICAgICAgICBub3cgPSBicm93c2VyLm5vdygpLFxuICAgICAgICAgICAgY3V0b2ZmID0gMTYwOyAgIC8vbXNlY1xuXG4gICAgICAgIHdoaWxlIChpbmVydGlhLmxlbmd0aCA+IDAgJiYgbm93IC0gaW5lcnRpYVswXS50aW1lID4gY3V0b2ZmKVxuICAgICAgICAgICAgaW5lcnRpYS5zaGlmdCgpO1xuICAgIH1cblxuICAgIF9vbk1vdmVFbmQocGFuSW5lcnRpYU9wdGlvbnM/OiBEcmFnUGFuT3B0aW9ucyk6ID8oRWFzaW5nT3B0aW9ucyAmIHtlYXNlSWQ/OiBzdHJpbmd9KSB7XG4gICAgICAgIGlmICh0aGlzLl9tYXAuX3ByZWZlcnNSZWR1Y2VkTW90aW9uKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2RyYWluSW5lcnRpYUJ1ZmZlcigpO1xuICAgICAgICBpZiAodGhpcy5faW5lcnRpYUJ1ZmZlci5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkZWx0YXMgPSB7XG4gICAgICAgICAgICB6b29tOiAwLFxuICAgICAgICAgICAgYmVhcmluZzogMCxcbiAgICAgICAgICAgIHBpdGNoOiAwLFxuICAgICAgICAgICAgcGFuOiBuZXcgUG9pbnQoMCwgMCksXG4gICAgICAgICAgICBwaW5jaEFyb3VuZDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgYXJvdW5kOiB1bmRlZmluZWRcbiAgICAgICAgfTtcblxuICAgICAgICBmb3IgKGNvbnN0IHtzZXR0aW5nc30gb2YgdGhpcy5faW5lcnRpYUJ1ZmZlcikge1xuICAgICAgICAgICAgZGVsdGFzLnpvb20gKz0gc2V0dGluZ3Muem9vbURlbHRhIHx8IDA7XG4gICAgICAgICAgICBkZWx0YXMuYmVhcmluZyArPSBzZXR0aW5ncy5iZWFyaW5nRGVsdGEgfHwgMDtcbiAgICAgICAgICAgIGRlbHRhcy5waXRjaCArPSBzZXR0aW5ncy5waXRjaERlbHRhIHx8IDA7XG4gICAgICAgICAgICBpZiAoc2V0dGluZ3MucGFuRGVsdGEpIGRlbHRhcy5wYW4uX2FkZChzZXR0aW5ncy5wYW5EZWx0YSk7XG4gICAgICAgICAgICBpZiAoc2V0dGluZ3MuYXJvdW5kKSBkZWx0YXMuYXJvdW5kID0gc2V0dGluZ3MuYXJvdW5kO1xuICAgICAgICAgICAgaWYgKHNldHRpbmdzLnBpbmNoQXJvdW5kKSBkZWx0YXMucGluY2hBcm91bmQgPSBzZXR0aW5ncy5waW5jaEFyb3VuZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxhc3RFbnRyeSA9IHRoaXMuX2luZXJ0aWFCdWZmZXJbdGhpcy5faW5lcnRpYUJ1ZmZlci5sZW5ndGggLSAxXTtcbiAgICAgICAgY29uc3QgZHVyYXRpb24gPSAobGFzdEVudHJ5LnRpbWUgLSB0aGlzLl9pbmVydGlhQnVmZmVyWzBdLnRpbWUpO1xuXG4gICAgICAgIGNvbnN0IGVhc2VPcHRpb25zID0ge307XG5cbiAgICAgICAgaWYgKGRlbHRhcy5wYW4ubWFnKCkpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGNhbGN1bGF0ZUVhc2luZyhkZWx0YXMucGFuLm1hZygpLCBkdXJhdGlvbiwgZXh0ZW5kKHt9LCBkZWZhdWx0UGFuSW5lcnRpYU9wdGlvbnMsIHBhbkluZXJ0aWFPcHRpb25zIHx8IHt9KSk7XG4gICAgICAgICAgICBlYXNlT3B0aW9ucy5vZmZzZXQgPSBkZWx0YXMucGFuLm11bHQocmVzdWx0LmFtb3VudCAvIGRlbHRhcy5wYW4ubWFnKCkpO1xuICAgICAgICAgICAgZWFzZU9wdGlvbnMuY2VudGVyID0gdGhpcy5fbWFwLnRyYW5zZm9ybS5jZW50ZXI7XG4gICAgICAgICAgICBleHRlbmREdXJhdGlvbihlYXNlT3B0aW9ucywgcmVzdWx0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkZWx0YXMuem9vbSkge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gY2FsY3VsYXRlRWFzaW5nKGRlbHRhcy56b29tLCBkdXJhdGlvbiwgZGVmYXVsdFpvb21JbmVydGlhT3B0aW9ucyk7XG4gICAgICAgICAgICBlYXNlT3B0aW9ucy56b29tID0gdGhpcy5fbWFwLnRyYW5zZm9ybS56b29tICsgcmVzdWx0LmFtb3VudDtcbiAgICAgICAgICAgIGV4dGVuZER1cmF0aW9uKGVhc2VPcHRpb25zLCByZXN1bHQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRlbHRhcy5iZWFyaW5nKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBjYWxjdWxhdGVFYXNpbmcoZGVsdGFzLmJlYXJpbmcsIGR1cmF0aW9uLCBkZWZhdWx0QmVhcmluZ0luZXJ0aWFPcHRpb25zKTtcbiAgICAgICAgICAgIGVhc2VPcHRpb25zLmJlYXJpbmcgPSB0aGlzLl9tYXAudHJhbnNmb3JtLmJlYXJpbmcgKyBjbGFtcChyZXN1bHQuYW1vdW50LCAtMTc5LCAxNzkpO1xuICAgICAgICAgICAgZXh0ZW5kRHVyYXRpb24oZWFzZU9wdGlvbnMsIHJlc3VsdCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZGVsdGFzLnBpdGNoKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBjYWxjdWxhdGVFYXNpbmcoZGVsdGFzLnBpdGNoLCBkdXJhdGlvbiwgZGVmYXVsdFBpdGNoSW5lcnRpYU9wdGlvbnMpO1xuICAgICAgICAgICAgZWFzZU9wdGlvbnMucGl0Y2ggPSB0aGlzLl9tYXAudHJhbnNmb3JtLnBpdGNoICsgcmVzdWx0LmFtb3VudDtcbiAgICAgICAgICAgIGV4dGVuZER1cmF0aW9uKGVhc2VPcHRpb25zLCByZXN1bHQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGVhc2VPcHRpb25zLnpvb20gfHwgZWFzZU9wdGlvbnMuYmVhcmluZykge1xuICAgICAgICAgICAgY29uc3QgbGFzdCA9IGRlbHRhcy5waW5jaEFyb3VuZCA9PT0gdW5kZWZpbmVkID8gZGVsdGFzLmFyb3VuZCA6IGRlbHRhcy5waW5jaEFyb3VuZDtcbiAgICAgICAgICAgIGVhc2VPcHRpb25zLmFyb3VuZCA9IGxhc3QgPyB0aGlzLl9tYXAudW5wcm9qZWN0KGxhc3QpIDogdGhpcy5fbWFwLmdldENlbnRlcigpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jbGVhcigpO1xuICAgICAgICBlYXNlT3B0aW9ucy5ub01vdmVTdGFydCA9IHRydWU7XG4gICAgICAgIHJldHVybiBlYXNlT3B0aW9ucztcbiAgICB9XG59XG5cbi8vIFVuZm9ydHVuYXRlbHkgem9vbSwgYmVhcmluZywgZXRjIGNhbid0IGhhdmUgZGlmZmVyZW50IGR1cmF0aW9ucyBhbmQgZWFzaW5ncyBzb1xuLy8gd2UgbmVlZCB0byBjaG9vc2Ugb25lLiBXZSB1c2UgdGhlIGxvbmdlc3QgZHVyYXRpb24gYW5kIGl0J3MgY29ycmVzcG9uZGluZyBlYXNpbmcuXG5mdW5jdGlvbiBleHRlbmREdXJhdGlvbihlYXNlT3B0aW9uczogRWFzaW5nT3B0aW9ucywgcmVzdWx0OiB7fCBhbW91bnQ6IG51bWJlciwgZHVyYXRpb246IG51bWJlciwgZWFzaW5nOiAodDogbnVtYmVyKSA9PiBudW1iZXIgfH0pIHtcbiAgICBpZiAoIWVhc2VPcHRpb25zLmR1cmF0aW9uIHx8IGVhc2VPcHRpb25zLmR1cmF0aW9uIDwgcmVzdWx0LmR1cmF0aW9uKSB7XG4gICAgICAgIGVhc2VPcHRpb25zLmR1cmF0aW9uID0gcmVzdWx0LmR1cmF0aW9uO1xuICAgICAgICBlYXNlT3B0aW9ucy5lYXNpbmcgPSByZXN1bHQuZWFzaW5nO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gY2FsY3VsYXRlRWFzaW5nKGFtb3VudDogbnVtYmVyLCBpbmVydGlhRHVyYXRpb246IG51bWJlciwgaW5lcnRpYU9wdGlvbnM6IEluZXJ0aWFPcHRpb25zKSB7XG4gICAgY29uc3Qge21heFNwZWVkLCBsaW5lYXJpdHksIGRlY2VsZXJhdGlvbn0gPSBpbmVydGlhT3B0aW9ucztcbiAgICBjb25zdCBzcGVlZCA9IGNsYW1wKFxuICAgICAgICBhbW91bnQgKiBsaW5lYXJpdHkgLyAoaW5lcnRpYUR1cmF0aW9uIC8gMTAwMCksXG4gICAgICAgIC1tYXhTcGVlZCxcbiAgICAgICAgbWF4U3BlZWQpO1xuICAgIGNvbnN0IGR1cmF0aW9uID0gTWF0aC5hYnMoc3BlZWQpIC8gKGRlY2VsZXJhdGlvbiAqIGxpbmVhcml0eSk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZWFzaW5nOiBpbmVydGlhT3B0aW9ucy5lYXNpbmcsXG4gICAgICAgIGR1cmF0aW9uOiBkdXJhdGlvbiAqIDEwMDAsXG4gICAgICAgIGFtb3VudDogc3BlZWQgKiAoZHVyYXRpb24gLyAyKVxuICAgIH07XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge0V2ZW50fSBmcm9tICcuLi91dGlsL2V2ZW50ZWQuanMnO1xuXG5pbXBvcnQgKiBhcyBET00gZnJvbSAnLi4vdXRpbC9kb20uanMnO1xuaW1wb3J0IFBvaW50IGZyb20gJ0BtYXBib3gvcG9pbnQtZ2VvbWV0cnknO1xuaW1wb3J0IHtleHRlbmR9IGZyb20gJy4uL3V0aWwvdXRpbC5qcyc7XG5cbmltcG9ydCB0eXBlIE1hcCBmcm9tICcuL21hcC5qcyc7XG5pbXBvcnQgdHlwZSBMbmdMYXQgZnJvbSAnLi4vZ2VvL2xuZ19sYXQuanMnO1xuXG4vKipcbiAqIGBNYXBNb3VzZUV2ZW50YCBpcyBhIGNsYXNzIHVzZWQgYnkgb3RoZXIgY2xhc3NlcyB0byBnZW5lcmF0ZVxuICogbW91c2UgZXZlbnRzIG9mIHNwZWNpZmljIHR5cGVzIHN1Y2ggYXMgJ2NsaWNrJyBvciAnaG92ZXInLlxuICogRm9yIGEgZnVsbCBsaXN0IG9mIGF2YWlsYWJsZSBldmVudHMsIHNlZSBbYE1hcGAgZXZlbnRzXSgvbWFwYm94LWdsLWpzL2FwaS9tYXAvI21hcC1ldmVudHMpLlxuICpcbiAqIEBleHRlbmRzIHtPYmplY3R9XG4gKiBAZXhhbXBsZVxuICogLy8gRXhhbXBsZSBvZiBhIE1hcE1vdXNlRXZlbnQgb2YgdHlwZSBcImNsaWNrXCJcbiAqIG1hcC5vbignY2xpY2snLCAoZSkgPT4ge1xuICogICAgIGNvbnNvbGUubG9nKGUpO1xuICogICAgIC8vIHtcbiAqICAgICAvLyAgICAgbG5nTGF0OiB7XG4gKiAgICAgLy8gICAgICAgICBsbmc6IDQwLjIwMyxcbiAqICAgICAvLyAgICAgICAgIGxhdDogLTc0LjQ1MVxuICogICAgIC8vICAgICB9LFxuICogICAgIC8vICAgICBvcmlnaW5hbEV2ZW50OiB7Li4ufSxcbiAqICAgICAvLyAgICAgcG9pbnQ6IHtcbiAqICAgICAvLyAgICAgICAgIHg6IDI2NixcbiAqICAgICAvLyAgICAgICAgIHk6IDQ2NFxuICogICAgIC8vICAgICB9LFxuICogICAgIC8vICAgICAgdGFyZ2V0OiB7Li4ufSxcbiAqICAgICAvLyAgICAgIHR5cGU6IFwiY2xpY2tcIlxuICogICAgIC8vIH1cbiAqIH0pO1xuICogQHNlZSBbUmVmZXJlbmNlOiBgTWFwYCBldmVudHMgQVBJIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9hcGkvbWFwLyNtYXAtZXZlbnRzKVxuICogQHNlZSBbRXhhbXBsZTogRGlzcGxheSBwb3B1cCBvbiBjbGlja10oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvcG9wdXAtb24tY2xpY2svKVxuICogQHNlZSBbRXhhbXBsZTogRGlzcGxheSBwb3B1cCBvbiBob3Zlcl0oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9wb3B1cC1vbi1ob3Zlci8pXG4gKi9cbmV4cG9ydCBjbGFzcyBNYXBNb3VzZUV2ZW50IGV4dGVuZHMgRXZlbnQge1xuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIG9yaWdpbmF0aW5nIGV2ZW50LiBGb3IgYSBmdWxsIGxpc3Qgb2YgYXZhaWxhYmxlIGV2ZW50cywgc2VlIFtgTWFwYCBldmVudHNdKC9tYXBib3gtZ2wtanMvYXBpL21hcC8jbWFwLWV2ZW50cykuXG4gICAgICovXG4gICAgdHlwZTogJ21vdXNlZG93bidcbiAgICAgICAgfCAnbW91c2V1cCdcbiAgICAgICAgfCAncHJlY2xpY2snXG4gICAgICAgIHwgJ2NsaWNrJ1xuICAgICAgICB8ICdkYmxjbGljaydcbiAgICAgICAgfCAnbW91c2Vtb3ZlJ1xuICAgICAgICB8ICdtb3VzZW92ZXInXG4gICAgICAgIHwgJ21vdXNlZW50ZXInXG4gICAgICAgIHwgJ21vdXNlbGVhdmUnXG4gICAgICAgIHwgJ21vdXNlb3V0J1xuICAgICAgICB8ICdjb250ZXh0bWVudSc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYE1hcGAgb2JqZWN0IHRoYXQgZmlyZWQgdGhlIGV2ZW50LlxuICAgICAqL1xuICAgIHRhcmdldDogTWFwO1xuXG4gICAgLyoqXG4gICAgICogVGhlIERPTSBldmVudCB3aGljaCBjYXVzZWQgdGhlIG1hcCBldmVudC5cbiAgICAgKi9cbiAgICBvcmlnaW5hbEV2ZW50OiBNb3VzZUV2ZW50O1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBpeGVsIGNvb3JkaW5hdGVzIG9mIHRoZSBtb3VzZSBjdXJzb3IsIHJlbGF0aXZlIHRvIHRoZSBtYXAgYW5kIG1lYXN1cmVkIGZyb20gdGhlIHRvcCBsZWZ0IGNvcm5lci5cbiAgICAgKi9cbiAgICBwb2ludDogUG9pbnQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgZ2VvZ3JhcGhpYyBsb2NhdGlvbiBvbiB0aGUgbWFwIG9mIHRoZSBtb3VzZSBjdXJzb3IuXG4gICAgICovXG4gICAgbG5nTGF0OiBMbmdMYXQ7XG5cbiAgICAvKipcbiAgICAgKiBJZiBhIHNpbmdsZSBgbGF5ZXJJZGAoYXMgYSBzaW5nbGUgc3RyaW5nKSBvciBtdWx0aXBsZSBgbGF5ZXJJZHNgIChhcyBhbiBhcnJheSBvZiBzdHJpbmdzKSB3ZXJlIHNwZWNpZmllZCB3aGVuIGFkZGluZyB0aGUgZXZlbnQgbGlzdGVuZXIgd2l0aCB7QGxpbmsgTWFwI29ufSxcbiAgICAgKiBgZmVhdHVyZXNgIHdpbGwgYmUgYW4gYXJyYXkgb2YgW0dlb0pTT05dKGh0dHA6Ly9nZW9qc29uLm9yZy8pIFtGZWF0dXJlIG9iamVjdHNdKGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM3OTQ2I3NlY3Rpb24tMy4yKS5cbiAgICAgKiBUaGUgYXJyYXkgd2lsbCBjb250YWluIGFsbCBmZWF0dXJlcyBmcm9tIHRoYXQgbGF5ZXIgdGhhdCBhcmUgcmVuZGVyZWQgYXQgdGhlIGV2ZW50J3MgcG9pbnQsXG4gICAgICogaW4gdGhlIG9yZGVyIHRoYXQgdGhleSBhcmUgcmVuZGVyZWQgd2l0aCB0aGUgdG9wbW9zdCBmZWF0dXJlIGJlaW5nIGF0IHRoZSBzdGFydCBvZiB0aGUgYXJyYXkuXG4gICAgICogVGhlIGBmZWF0dXJlc2AgYXJlIGlkZW50aWNhbCB0byB0aG9zZSByZXR1cm5lZCBieSB7QGxpbmsgTWFwI3F1ZXJ5UmVuZGVyZWRGZWF0dXJlc30uXG4gICAgICpcbiAgICAgKiBJZiBubyBgbGF5ZXJJZGAgd2FzIHNwZWNpZmllZCB3aGVuIGFkZGluZyB0aGUgZXZlbnQgbGlzdGVuZXIsIGBmZWF0dXJlc2Agd2lsbCBiZSBgdW5kZWZpbmVkYC5cbiAgICAgKiBZb3UgY2FuIGdldCB0aGUgZmVhdHVyZXMgYXQgdGhlIHBvaW50IHdpdGggYG1hcC5xdWVyeVJlbmRlcmVkRmVhdHVyZXMoZS5wb2ludClgLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBsb2dnaW5nIGZlYXR1cmVzIGZvciBhIHNwZWNpZmljIGxheWVyICh3aXRoIGBlLmZlYXR1cmVzYClcbiAgICAgKiBtYXAub24oJ2NsaWNrJywgJ215TGF5ZXJJZCcsIChlKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKGBUaGVyZSBhcmUgJHtlLmZlYXR1cmVzLmxlbmd0aH0gZmVhdHVyZXMgYXQgcG9pbnQgJHtlLnBvaW50fWApO1xuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBsb2dnaW5nIGZlYXR1cmVzIGZvciB0d28gbGF5ZXJzICh3aXRoIGBlLmZlYXR1cmVzYClcbiAgICAgKiBtYXAub24oJ2NsaWNrJywgWydsYXllcjEnLCAnbGF5ZXIyJ10sIChlKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKGBUaGVyZSBhcmUgJHtlLmZlYXR1cmVzLmxlbmd0aH0gZmVhdHVyZXMgYXQgcG9pbnQgJHtlLnBvaW50fWApO1xuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBsb2dnaW5nIGFsbCBmZWF0dXJlcyBmb3IgYWxsIGxheWVycyAod2l0aG91dCBgZS5mZWF0dXJlc2ApXG4gICAgICogbWFwLm9uKCdjbGljaycsIChlKSA9PiB7XG4gICAgICogICAgIGNvbnN0IGZlYXR1cmVzID0gbWFwLnF1ZXJ5UmVuZGVyZWRGZWF0dXJlcyhlLnBvaW50KTtcbiAgICAgKiAgICAgY29uc29sZS5sb2coYFRoZXJlIGFyZSAke2ZlYXR1cmVzLmxlbmd0aH0gZmVhdHVyZXMgYXQgcG9pbnQgJHtlLnBvaW50fWApO1xuICAgICAqIH0pO1xuICAgICAqL1xuICAgIGZlYXR1cmVzOiBBcnJheTxPYmplY3Q+IHwgdm9pZDtcblxuICAgIC8qKlxuICAgICAqIFByZXZlbnRzIHN1YnNlcXVlbnQgZGVmYXVsdCBwcm9jZXNzaW5nIG9mIHRoZSBldmVudCBieSB0aGUgbWFwLlxuICAgICAqXG4gICAgICogQ2FsbGluZyB0aGlzIG1ldGhvZCB3aWxsIHByZXZlbnQgdGhlIGZvbGxvd2luZyBkZWZhdWx0IG1hcCBiZWhhdmlvcnM6XG4gICAgICpcbiAgICAgKiAgICogT24gYG1vdXNlZG93bmAgZXZlbnRzLCB0aGUgYmVoYXZpb3Igb2Yge0BsaW5rIERyYWdQYW5IYW5kbGVyfS5cbiAgICAgKiAgICogT24gYG1vdXNlZG93bmAgZXZlbnRzLCB0aGUgYmVoYXZpb3Igb2Yge0BsaW5rIERyYWdSb3RhdGVIYW5kbGVyfS5cbiAgICAgKiAgICogT24gYG1vdXNlZG93bmAgZXZlbnRzLCB0aGUgYmVoYXZpb3Igb2Yge0BsaW5rIEJveFpvb21IYW5kbGVyfS5cbiAgICAgKiAgICogT24gYGRibGNsaWNrYCBldmVudHMsIHRoZSBiZWhhdmlvciBvZiB7QGxpbmsgRG91YmxlQ2xpY2tab29tSGFuZGxlcn0uXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIG1hcC5vbignY2xpY2snLCAoZSkgPT4ge1xuICAgICAqICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICogfSk7XG4gICAgICovXG4gICAgcHJldmVudERlZmF1bHQoKSB7XG4gICAgICAgIHRoaXMuX2RlZmF1bHRQcmV2ZW50ZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGB0cnVlYCBpZiBgcHJldmVudERlZmF1bHRgIGhhcyBiZWVuIGNhbGxlZC5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIGdldCBkZWZhdWx0UHJldmVudGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmYXVsdFByZXZlbnRlZDtcbiAgICB9XG5cbiAgICBfZGVmYXVsdFByZXZlbnRlZDogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodHlwZTogc3RyaW5nLCBtYXA6IE1hcCwgb3JpZ2luYWxFdmVudDogTW91c2VFdmVudCwgZGF0YTogT2JqZWN0ID0ge30pIHtcbiAgICAgICAgY29uc3QgcG9pbnQgPSBET00ubW91c2VQb3MobWFwLmdldENhbnZhc0NvbnRhaW5lcigpLCBvcmlnaW5hbEV2ZW50KTtcbiAgICAgICAgY29uc3QgbG5nTGF0ID0gbWFwLnVucHJvamVjdChwb2ludCk7XG4gICAgICAgIHN1cGVyKHR5cGUsIGV4dGVuZCh7cG9pbnQsIGxuZ0xhdCwgb3JpZ2luYWxFdmVudH0sIGRhdGEpKTtcbiAgICAgICAgdGhpcy5fZGVmYXVsdFByZXZlbnRlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnRhcmdldCA9IG1hcDtcbiAgICB9XG59XG5cbi8qKlxuICogYE1hcFRvdWNoRXZlbnRgIGlzIGEgY2xhc3MgdXNlZCBieSBvdGhlciBjbGFzc2VzIHRvIGdlbmVyYXRlXG4gKiBtb3VzZSBldmVudHMgb2Ygc3BlY2lmaWMgdHlwZXMgc3VjaCBhcyAndG91Y2hzdGFydCcgb3IgJ3RvdWNoZW5kJy5cbiAqIEZvciBhIGZ1bGwgbGlzdCBvZiBhdmFpbGFibGUgZXZlbnRzLCBzZWUgW2BNYXBgIGV2ZW50c10oL21hcGJveC1nbC1qcy9hcGkvbWFwLyNtYXAtZXZlbnRzKS5cbiAqXG4gKiBAZXh0ZW5kcyB7T2JqZWN0fVxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBFeGFtcGxlIG9mIGEgTWFwVG91Y2hFdmVudCBvZiB0eXBlIFwidG91Y2hcIlxuICogbWFwLm9uKCd0b3VjaHN0YXJ0JywgKGUpID0+IHtcbiAqICAgICBjb25zb2xlLmxvZyhlKTtcbiAqICAgICAvLyB7XG4gKiAgICAgLy8gICBsbmdMYXQ6IHtcbiAqICAgICAvLyAgICAgIGxuZzogNDAuMjAzLFxuICogICAgIC8vICAgICAgbGF0OiAtNzQuNDUxXG4gKiAgICAgLy8gICB9LFxuICogICAgIC8vICAgbG5nTGF0czogW1xuICogICAgIC8vICAgICAge1xuICogICAgIC8vICAgICAgICAgbG5nOiA0MC4yMDMsXG4gKiAgICAgLy8gICAgICAgICBsYXQ6IC03NC40NTFcbiAqICAgICAvLyAgICAgIH1cbiAqICAgICAvLyAgIF0sXG4gKiAgICAgLy8gICBvcmlnaW5hbEV2ZW50OiB7Li4ufSxcbiAqICAgICAvLyAgIHBvaW50OiB7XG4gKiAgICAgLy8gICAgICB4OiAyNjYsXG4gKiAgICAgLy8gICAgICB5OiA0NjRcbiAqICAgICAvLyAgIH0sXG4gKiAgICAgLy8gICBwb2ludHM6IFtcbiAqICAgICAvLyAgICAgIHtcbiAqICAgICAvLyAgICAgICAgIHg6IDI2NixcbiAqICAgICAvLyAgICAgICAgIHk6IDQ2NFxuICogICAgIC8vICAgICAgfVxuICogICAgIC8vICAgXVxuICogICAgIC8vICAgcHJldmVudERlZmF1bHQoKSxcbiAqICAgICAvLyAgIHRhcmdldDogey4uLn0sXG4gKiAgICAgLy8gICB0eXBlOiBcInRvdWNoc3RhcnRcIlxuICogICAgIC8vIH1cbiAqIH0pO1xuICogQHNlZSBbUmVmZXJlbmNlOiBgTWFwYCBldmVudHMgQVBJIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9hcGkvbWFwLyNtYXAtZXZlbnRzKVxuICogQHNlZSBbRXhhbXBsZTogQ3JlYXRlIGEgZHJhZ2dhYmxlIHBvaW50XShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9kcmFnLWEtcG9pbnQvKVxuICovXG5leHBvcnQgY2xhc3MgTWFwVG91Y2hFdmVudCBleHRlbmRzIEV2ZW50IHtcbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiBvcmlnaW5hdGluZyBldmVudC4gRm9yIGEgZnVsbCBsaXN0IG9mIGF2YWlsYWJsZSBldmVudHMsIHNlZSBbYE1hcGAgZXZlbnRzXSgvbWFwYm94LWdsLWpzL2FwaS9tYXAvI21hcC1ldmVudHMpLlxuICAgICAqL1xuICAgIHR5cGU6ICd0b3VjaHN0YXJ0J1xuICAgICAgICB8ICd0b3VjaGVuZCdcbiAgICAgICAgfCAndG91Y2hjYW5jZWwnO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGBNYXBgIG9iamVjdCB0aGF0IGZpcmVkIHRoZSBldmVudC5cbiAgICAgKi9cbiAgICB0YXJnZXQ6IE1hcDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBET00gZXZlbnQgd2hpY2ggY2F1c2VkIHRoZSBtYXAgZXZlbnQuXG4gICAgICovXG4gICAgb3JpZ2luYWxFdmVudDogVG91Y2hFdmVudDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBnZW9ncmFwaGljIGxvY2F0aW9uIG9uIHRoZSBtYXAgb2YgdGhlIGNlbnRlciBvZiB0aGUgdG91Y2ggZXZlbnQgcG9pbnRzLlxuICAgICAqL1xuICAgIGxuZ0xhdDogTG5nTGF0O1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBpeGVsIGNvb3JkaW5hdGVzIG9mIHRoZSBjZW50ZXIgb2YgdGhlIHRvdWNoIGV2ZW50IHBvaW50cywgcmVsYXRpdmUgdG8gdGhlIG1hcCBhbmQgbWVhc3VyZWQgZnJvbSB0aGUgdG9wIGxlZnRcbiAgICAgKiBjb3JuZXIuXG4gICAgICovXG4gICAgcG9pbnQ6IFBvaW50O1xuXG4gICAgLyoqXG4gICAgICogVGhlIGFycmF5IG9mIHBpeGVsIGNvb3JkaW5hdGVzIGNvcnJlc3BvbmRpbmcgdG8gYVxuICAgICAqIFt0b3VjaCBldmVudCdzIGB0b3VjaGVzYF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1RvdWNoRXZlbnQvdG91Y2hlcykgcHJvcGVydHkuXG4gICAgICovXG4gICAgcG9pbnRzOiBBcnJheTxQb2ludD47XG5cbiAgICAvKipcbiAgICAgKiBUaGUgZ2VvZ3JhcGhpY2FsIGxvY2F0aW9ucyBvbiB0aGUgbWFwIGNvcnJlc3BvbmRpbmcgdG8gYVxuICAgICAqIFt0b3VjaCBldmVudCdzIGB0b3VjaGVzYF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1RvdWNoRXZlbnQvdG91Y2hlcykgcHJvcGVydHkuXG4gICAgICovXG4gICAgbG5nTGF0czogQXJyYXk8TG5nTGF0PjtcblxuICAgIC8qKlxuICAgICAqIElmIGEgYGxheWVySWRgIHdhcyBzcGVjaWZpZWQgd2hlbiBhZGRpbmcgdGhlIGV2ZW50IGxpc3RlbmVyIHdpdGgge0BsaW5rIE1hcCNvbn0sIGBmZWF0dXJlc2Agd2lsbCBiZSBhbiBhcnJheSBvZlxuICAgICAqIFtHZW9KU09OXShodHRwOi8vZ2VvanNvbi5vcmcvKSBbRmVhdHVyZSBvYmplY3RzXShodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNzk0NiNzZWN0aW9uLTMuMikuXG4gICAgICogVGhlIGFycmF5IHdpbGwgY29udGFpbiBhbGwgZmVhdHVyZXMgZnJvbSB0aGF0IGxheWVyIHRoYXQgYXJlIHJlbmRlcmVkIGF0IHRoZSBldmVudCdzIHBvaW50LlxuICAgICAqIFRoZSBgZmVhdHVyZXNgIGFyZSBpZGVudGljYWwgdG8gdGhvc2UgcmV0dXJuZWQgYnkge0BsaW5rIE1hcCNxdWVyeVJlbmRlcmVkRmVhdHVyZXN9LlxuICAgICAqXG4gICAgICogSWYgbm8gYGxheWVySWRgIHdhcyBzcGVjaWZpZWQgd2hlbiBhZGRpbmcgdGhlIGV2ZW50IGxpc3RlbmVyLCBgZmVhdHVyZXNgIHdpbGwgYmUgYHVuZGVmaW5lZGAuXG4gICAgICogWW91IGNhbiBnZXQgdGhlIGZlYXR1cmVzIGF0IHRoZSBwb2ludCB3aXRoIGBtYXAucXVlcnlSZW5kZXJlZEZlYXR1cmVzKGUucG9pbnQpYC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gbG9nZ2luZyBmZWF0dXJlcyBmb3IgYSBzcGVjaWZpYyBsYXllciAod2l0aCBgZS5mZWF0dXJlc2ApXG4gICAgICogbWFwLm9uKCd0b3VjaHN0YXJ0JywgJ215TGF5ZXJJZCcsIChlKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKGBUaGVyZSBhcmUgJHtlLmZlYXR1cmVzLmxlbmd0aH0gZmVhdHVyZXMgYXQgcG9pbnQgJHtlLnBvaW50fWApO1xuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBsb2dnaW5nIGFsbCBmZWF0dXJlcyBmb3IgYWxsIGxheWVycyAod2l0aG91dCBgZS5mZWF0dXJlc2ApXG4gICAgICogbWFwLm9uKCd0b3VjaHN0YXJ0JywgKGUpID0+IHtcbiAgICAgKiAgICAgY29uc3QgZmVhdHVyZXMgPSBtYXAucXVlcnlSZW5kZXJlZEZlYXR1cmVzKGUucG9pbnQpO1xuICAgICAqICAgICBjb25zb2xlLmxvZyhgVGhlcmUgYXJlICR7ZmVhdHVyZXMubGVuZ3RofSBmZWF0dXJlcyBhdCBwb2ludCAke2UucG9pbnR9YCk7XG4gICAgICogfSk7XG4gICAgICovXG4gICAgZmVhdHVyZXM6IEFycmF5PE9iamVjdD4gfCB2b2lkO1xuXG4gICAgLyoqXG4gICAgICogUHJldmVudHMgc3Vic2VxdWVudCBkZWZhdWx0IHByb2Nlc3Npbmcgb2YgdGhlIGV2ZW50IGJ5IHRoZSBtYXAuXG4gICAgICpcbiAgICAgKiBDYWxsaW5nIHRoaXMgbWV0aG9kIHdpbGwgcHJldmVudCB0aGUgZm9sbG93aW5nIGRlZmF1bHQgbWFwIGJlaGF2aW9yczpcbiAgICAgKlxuICAgICAqICAgKiBPbiBgdG91Y2hzdGFydGAgZXZlbnRzLCB0aGUgYmVoYXZpb3Igb2Yge0BsaW5rIERyYWdQYW5IYW5kbGVyfS5cbiAgICAgKiAgICogT24gYHRvdWNoc3RhcnRgIGV2ZW50cywgdGhlIGJlaGF2aW9yIG9mIHtAbGluayBUb3VjaFpvb21Sb3RhdGVIYW5kbGVyfS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogbWFwLm9uKCd0b3VjaHN0YXJ0JywgKGUpID0+IHtcbiAgICAgKiAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAqIH0pO1xuICAgICAqL1xuICAgIHByZXZlbnREZWZhdWx0KCkge1xuICAgICAgICB0aGlzLl9kZWZhdWx0UHJldmVudGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGB0cnVlYCBpZiBgcHJldmVudERlZmF1bHRgIGhhcyBiZWVuIGNhbGxlZC5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIGdldCBkZWZhdWx0UHJldmVudGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmYXVsdFByZXZlbnRlZDtcbiAgICB9XG5cbiAgICBfZGVmYXVsdFByZXZlbnRlZDogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodHlwZTogc3RyaW5nLCBtYXA6IE1hcCwgb3JpZ2luYWxFdmVudDogVG91Y2hFdmVudCkge1xuICAgICAgICBjb25zdCB0b3VjaGVzID0gdHlwZSA9PT0gXCJ0b3VjaGVuZFwiID8gb3JpZ2luYWxFdmVudC5jaGFuZ2VkVG91Y2hlcyA6IG9yaWdpbmFsRXZlbnQudG91Y2hlcztcbiAgICAgICAgY29uc3QgcG9pbnRzID0gRE9NLnRvdWNoUG9zKG1hcC5nZXRDYW52YXNDb250YWluZXIoKSwgdG91Y2hlcyk7XG4gICAgICAgIGNvbnN0IGxuZ0xhdHMgPSBwb2ludHMubWFwKCh0KSA9PiBtYXAudW5wcm9qZWN0KHQpKTtcbiAgICAgICAgY29uc3QgcG9pbnQgPSBwb2ludHMucmVkdWNlKChwcmV2LCBjdXJyLCBpLCBhcnIpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBwcmV2LmFkZChjdXJyLmRpdihhcnIubGVuZ3RoKSk7XG4gICAgICAgIH0sIG5ldyBQb2ludCgwLCAwKSk7XG4gICAgICAgIGNvbnN0IGxuZ0xhdCA9IG1hcC51bnByb2plY3QocG9pbnQpO1xuICAgICAgICBzdXBlcih0eXBlLCB7cG9pbnRzLCBwb2ludCwgbG5nTGF0cywgbG5nTGF0LCBvcmlnaW5hbEV2ZW50fSk7XG4gICAgICAgIHRoaXMuX2RlZmF1bHRQcmV2ZW50ZWQgPSBmYWxzZTtcbiAgICB9XG59XG5cbi8qKlxuICogYE1hcFdoZWVsRXZlbnRgIGlzIGEgY2xhc3MgdXNlZCBieSBvdGhlciBjbGFzc2VzIHRvIGdlbmVyYXRlXG4gKiBtb3VzZSBldmVudHMgb2Ygc3BlY2lmaWMgdHlwZXMgc3VjaCBhcyAnd2hlZWwnLlxuICogRm9yIGEgZnVsbCBsaXN0IG9mIGF2YWlsYWJsZSBldmVudHMsIHNlZSBbYE1hcGAgZXZlbnRzXSgvbWFwYm94LWdsLWpzL2FwaS9tYXAvI21hcC1ldmVudHMpLlxuICpcbiAqIEBleHRlbmRzIHtPYmplY3R9XG4gKiBAZXhhbXBsZVxuICogLy8gRXhhbXBsZSBldmVudCB0cmlnZ2VyIGZvciBhIE1hcFdoZWVsRXZlbnQgb2YgdHlwZSBcIndoZWVsXCJcbiAqIG1hcC5vbignd2hlZWwnLCAoZSkgPT4ge1xuICogICAgIGNvbnNvbGUubG9nKCdldmVudCB0eXBlOicsIGUudHlwZSk7XG4gKiAgICAgLy8gZXZlbnQgdHlwZTogd2hlZWxcbiAqIH0pO1xuICogQGV4YW1wbGVcbiAqIC8vIEV4YW1wbGUgb2YgYSBNYXBXaGVlbEV2ZW50IG9mIHR5cGUgXCJ3aGVlbFwiXG4gKiAvLyB7XG4gKiAvLyAgIG9yaWdpbmFsRXZlbnQ6IFdoZWVsRXZlbnQgey4uLn0sXG4gKiAvLyBcdCB0YXJnZXQ6IE1hcCB7Li4ufSxcbiAqIC8vIFx0IHR5cGU6IFwid2hlZWxcIlxuICogLy8gfVxuICogQHNlZSBbUmVmZXJlbmNlOiBgTWFwYCBldmVudHMgQVBJIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9hcGkvbWFwLyNtYXAtZXZlbnRzKVxuICovXG5leHBvcnQgY2xhc3MgTWFwV2hlZWxFdmVudCBleHRlbmRzIEV2ZW50IHtcbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiBvcmlnaW5hdGluZyBldmVudC4gRm9yIGEgZnVsbCBsaXN0IG9mIGF2YWlsYWJsZSBldmVudHMsIHNlZSBbYE1hcGAgZXZlbnRzXSgvbWFwYm94LWdsLWpzL2FwaS9tYXAvI21hcC1ldmVudHMpLlxuICAgICAqL1xuICAgIHR5cGU6ICd3aGVlbCc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYE1hcGAgb2JqZWN0IHRoYXQgZmlyZWQgdGhlIGV2ZW50LlxuICAgICAqL1xuICAgIHRhcmdldDogTWFwO1xuXG4gICAgLyoqXG4gICAgICogVGhlIERPTSBldmVudCB3aGljaCBjYXVzZWQgdGhlIG1hcCBldmVudC5cbiAgICAgKi9cbiAgICBvcmlnaW5hbEV2ZW50OiBXaGVlbEV2ZW50O1xuXG4gICAgLyoqXG4gICAgICogUHJldmVudHMgc3Vic2VxdWVudCBkZWZhdWx0IHByb2Nlc3Npbmcgb2YgdGhlIGV2ZW50IGJ5IHRoZSBtYXAuXG4gICAgICogQ2FsbGluZyB0aGlzIG1ldGhvZCB3aWxsIHByZXZlbnQgdGhlIHRoZSBiZWhhdmlvciBvZiB7QGxpbmsgU2Nyb2xsWm9vbUhhbmRsZXJ9LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAub24oJ3doZWVsJywgKGUpID0+IHtcbiAgICAgKiAgICAgLy8gUHJldmVudCB0aGUgZGVmYXVsdCBtYXAgc2Nyb2xsIHpvb20gYmVoYXZpb3IuXG4gICAgICogICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgKiB9KTtcbiAgICAgKi9cbiAgICBwcmV2ZW50RGVmYXVsdCgpIHtcbiAgICAgICAgdGhpcy5fZGVmYXVsdFByZXZlbnRlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogYHRydWVgIGlmIGBwcmV2ZW50RGVmYXVsdGAgaGFzIGJlZW4gY2FsbGVkLlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgZ2V0IGRlZmF1bHRQcmV2ZW50ZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWZhdWx0UHJldmVudGVkO1xuICAgIH1cblxuICAgIF9kZWZhdWx0UHJldmVudGVkOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0eXBlOiBzdHJpbmcsIG1hcDogTWFwLCBvcmlnaW5hbEV2ZW50OiBXaGVlbEV2ZW50KSB7XG4gICAgICAgIHN1cGVyKHR5cGUsIHtvcmlnaW5hbEV2ZW50fSk7XG4gICAgICAgIHRoaXMuX2RlZmF1bHRQcmV2ZW50ZWQgPSBmYWxzZTtcbiAgICB9XG59XG5cbi8qKlxuICogYE1hcEJveFpvb21FdmVudGAgaXMgYSBjbGFzcyB1c2VkIHRvIGdlbmVyYXRlXG4gKiB0aGUgZXZlbnRzICdib3h6b29tc3RhcnQnLCAnYm94em9vbWVuZCcsIGFuZCAnYm94em9vbWNhbmNlbCcuXG4gKiBGb3IgYSBmdWxsIGxpc3Qgb2YgYXZhaWxhYmxlIGV2ZW50cywgc2VlIFtgTWFwYCBldmVudHNdKC9tYXBib3gtZ2wtanMvYXBpL21hcC8jbWFwLWV2ZW50cykuXG4gKlxuICogQHR5cGVkZWYge09iamVjdH0gTWFwQm94Wm9vbUV2ZW50XG4gKiBAcHJvcGVydHkge01vdXNlRXZlbnR9IG9yaWdpbmFsRXZlbnQgVGhlIERPTSBldmVudCB0aGF0IHRyaWdnZXJlZCB0aGUgYm94em9vbSBldmVudC4gQ2FuIGJlIGEgYE1vdXNlRXZlbnRgIG9yIGBLZXlib2FyZEV2ZW50YC5cbiAqIEBwcm9wZXJ0eSB7KCdib3h6b29tc3RhcnQnIHwgJ2JveHpvb21lbmQnIHwgJ2JveHpvb21jYW5jZWwnKX0gdHlwZSBUaGUgdHlwZSBvZiBvcmlnaW5hdGluZyBldmVudC4gRm9yIGEgZnVsbCBsaXN0IG9mIGF2YWlsYWJsZSBldmVudHMsIHNlZSBbYE1hcGAgZXZlbnRzXSgvbWFwYm94LWdsLWpzL2FwaS9tYXAvI21hcC1ldmVudHMpLlxuICogQHByb3BlcnR5IHtNYXB9IHRhcmdldCBUaGUgYE1hcGAgaW5zdGFuY2UgdGhhdCB0cmlnZ2VyZWQgdGhlIGV2ZW50LlxuICogQGV4YW1wbGVcbiAqIC8vIEV4YW1wbGUgdHJpZ2dlciBvZiBhIEJveFpvb21FdmVudCBvZiB0eXBlIFwiYm94em9vbXN0YXJ0XCJcbiAqIG1hcC5vbignYm94em9vbXN0YXJ0JywgKGUpID0+IHtcbiAqICAgICBjb25zb2xlLmxvZygnZXZlbnQgdHlwZTonLCBlLnR5cGUpO1xuICogICAgIC8vIGV2ZW50IHR5cGU6IGJveHpvb21zdGFydFxuICogfSk7XG4gKiBAZXhhbXBsZVxuICogLy8gRXhhbXBsZSBvZiBhIEJveFpvb21FdmVudCBvZiB0eXBlIFwiYm94em9vbXN0YXJ0XCJcbiAqIC8vIHtcbiAqIC8vICAgb3JpZ2luYWxFdmVudDogey4uLn0sXG4gKiAvLyAgIHR5cGU6IFwiYm94em9vbXN0YXJ0XCIsXG4gKiAvLyAgIHRhcmdldDogey4uLn1cbiAqIC8vIH1cbiAqIEBzZWUgW1JlZmVyZW5jZTogYE1hcGAgZXZlbnRzIEFQSSBkb2N1bWVudGF0aW9uXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvYXBpL21hcC8jbWFwLWV2ZW50cylcbiAqIEBzZWUgW0V4YW1wbGU6IEhpZ2hsaWdodCBmZWF0dXJlcyB3aXRoaW4gYSBib3VuZGluZyBib3hdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL3VzaW5nLWJveC1xdWVyeXJlbmRlcmVkZmVhdHVyZXMvKVxuICovXG5leHBvcnQgdHlwZSBNYXBCb3hab29tRXZlbnQgPSB7XG4gICAgdHlwZTogJ2JveHpvb21zdGFydCdcbiAgICAgICAgfCAnYm94em9vbWVuZCdcbiAgICAgICAgfCAnYm94em9vbWNhbmNlbCcsXG4gICAgdGFyZ2V0OiBNYXAsXG4gICAgb3JpZ2luYWxFdmVudDogTW91c2VFdmVudFxufTtcblxuLyoqXG4gKiBgTWFwRGF0YUV2ZW50YCBpcyBhIGNsYXNzIHVzZWQgdG8gZ2VuZXJhdGVcbiAqIGV2ZW50cyByZWxhdGVkIHRvIGxvYWRpbmcgZGF0YSwgc3R5bGVzLCBhbmQgc291cmNlcy5cbiAqIEZvciBhIGZ1bGwgbGlzdCBvZiBhdmFpbGFibGUgZXZlbnRzLCBzZWUgW2BNYXBgIGV2ZW50c10oL21hcGJveC1nbC1qcy9hcGkvbWFwLyNtYXAtZXZlbnRzKS5cbiAqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBNYXBEYXRhRXZlbnRcbiAqIEBwcm9wZXJ0eSB7KCdkYXRhJyB8ICdkYXRhbG9hZGluZycgfCAnc3R5bGVkYXRhJyB8ICdzdHlsZWRhdGFsb2FkaW5nJyB8ICdzb3VyY2VkYXRhJ3wgJ3NvdXJjZWRhdGFsb2FkaW5nJyl9IHR5cGUgVGhlIHR5cGUgb2Ygb3JpZ2luYXRpbmcgZXZlbnQuIEZvciBhIGZ1bGwgbGlzdCBvZiBhdmFpbGFibGUgZXZlbnRzLCBzZWUgW2BNYXBgIGV2ZW50c10oL21hcGJveC1nbC1qcy9hcGkvbWFwLyNtYXAtZXZlbnRzKS5cbiAqIEBwcm9wZXJ0eSB7KCdzb3VyY2UnIHwgJ3N0eWxlJyl9IGRhdGFUeXBlIFRoZSB0eXBlIG9mIGRhdGEgdGhhdCBoYXMgY2hhbmdlZC4gT25lIG9mIGAnc291cmNlJ2Agb3IgYCdzdHlsZSdgLCB3aGVyZSBgJ3NvdXJjZSdgIHJlZmVycyB0byB0aGUgZGF0YSBhc3NvY2lhdGVkIHdpdGggYW55IHNvdXJjZSwgYW5kIGAnc3R5bGUnYCByZWZlcnMgdG8gdGhlIGVudGlyZSBbc3R5bGVdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL2hlbHAvZ2xvc3Nhcnkvc3R5bGUvKSB1c2VkIGJ5IHRoZSBtYXAuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtpc1NvdXJjZUxvYWRlZF0gVHJ1ZSBpZiB0aGUgZXZlbnQgaGFzIGEgYGRhdGFUeXBlYCBvZiBgc291cmNlYCBhbmQgdGhlIHNvdXJjZSBoYXMgbm8gb3V0c3RhbmRpbmcgbmV0d29yayByZXF1ZXN0cy5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBbc291cmNlXSBUaGUgW3N0eWxlIHNwZWMgcmVwcmVzZW50YXRpb24gb2YgdGhlIHNvdXJjZV0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL3N0eWxlLXNwZWMvc291cmNlcy8pIGlmIHRoZSBldmVudCBoYXMgYSBgZGF0YVR5cGVgIG9mIGBzb3VyY2VgLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtzb3VyY2VJZF0gVGhlIGBpZGAgb2YgdGhlIFtgc291cmNlYF0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL3N0eWxlLXNwZWMvc291cmNlcy8pIHRoYXQgdHJpZ2dlcmVkIHRoZSBldmVudCwgaWYgdGhlIGV2ZW50IGhhcyBhIGBkYXRhVHlwZWAgb2YgYHNvdXJjZWAuIFNhbWUgYXMgdGhlIGBpZGAgb2YgdGhlIG9iamVjdCBpbiB0aGUgYHNvdXJjZWAgcHJvcGVydHkuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW3NvdXJjZURhdGFUeXBlXSBJbmNsdWRlZCBpZiB0aGUgZXZlbnQgaGFzIGEgYGRhdGFUeXBlYCBvZiBgc291cmNlYCBhbmQgdGhlIGV2ZW50IHNpZ25hbHNcbiAqIHRoYXQgaW50ZXJuYWwgZGF0YSBoYXMgYmVlbiByZWNlaXZlZCBvciBjaGFuZ2VkLiBQb3NzaWJsZSB2YWx1ZXMgYXJlIGBtZXRhZGF0YWAsIGBjb250ZW50YCBhbmQgYHZpc2liaWxpdHlgLlxuICogQHByb3BlcnR5IHtPYmplY3R9IFt0aWxlXSBUaGUgdGlsZSBiZWluZyBsb2FkZWQgb3IgY2hhbmdlZCwgaWYgdGhlIGV2ZW50IGhhcyBhIGBkYXRhVHlwZWAgb2YgYHNvdXJjZWAgYW5kXG4gKiB0aGUgZXZlbnQgaXMgcmVsYXRlZCB0byBsb2FkaW5nIG9mIGEgdGlsZS5cbiAqIEBwcm9wZXJ0eSB7Q29vcmRpbmF0ZX0gW2Nvb3JkXSBUaGUgY29vcmRpbmF0ZSBvZiB0aGUgdGlsZSBpZiB0aGUgZXZlbnQgaGFzIGEgYGRhdGFUeXBlYCBvZiBgc291cmNlYCBhbmRcbiAqIHRoZSBldmVudCBpcyByZWxhdGVkIHRvIGxvYWRpbmcgb2YgYSB0aWxlLlxuICogQGV4YW1wbGVcbiAqIC8vIEV4YW1wbGUgb2YgYSBNYXBEYXRhRXZlbnQgb2YgdHlwZSBcInNvdXJjZWRhdGFcIlxuICogbWFwLm9uKCdzb3VyY2VkYXRhJywgKGUpID0+IHtcbiAqICAgICBjb25zb2xlLmxvZyhlKTtcbiAqICAgICAvLyB7XG4gKiAgICAgLy8gICBkYXRhVHlwZTogXCJzb3VyY2VcIixcbiAqICAgICAvLyAgIGlzU291cmNlTG9hZGVkOiBmYWxzZSxcbiAqICAgICAvLyAgIHNvdXJjZToge1xuICogICAgIC8vICAgICB0eXBlOiBcInZlY3RvclwiLFxuICogICAgIC8vICAgICB1cmw6IFwibWFwYm94Oi8vbWFwYm94Lm1hcGJveC1zdHJlZXRzLXY4LG1hcGJveC5tYXBib3gtdGVycmFpbi12MlwiXG4gKiAgICAgLy8gICB9LFxuICogICAgIC8vICAgc291cmNlRGF0YVR5cGU6IFwidmlzaWJpbGl0eVwiLFxuICogICAgIC8vICAgc291cmNlSWQ6IFwiY29tcG9zaXRlXCIsXG4gKiAgICAgLy8gICBzdHlsZTogey4uLn0sXG4gKiAgICAgLy8gICB0YXJnZXQ6IHsuLi59LFxuICogICAgIC8vICAgdHlwZTogXCJzb3VyY2VkYXRhXCJcbiAqICAgICAvLyB9XG4gKiB9KTtcbiAqIEBzZWUgW1JlZmVyZW5jZTogYE1hcGAgZXZlbnRzIEFQSSBkb2N1bWVudGF0aW9uXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvYXBpL21hcC8jbWFwLWV2ZW50cylcbiAqIEBzZWUgW0V4YW1wbGU6IENoYW5nZSBhIG1hcCdzIHN0eWxlXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9zZXRzdHlsZS8pXG4gKiBAc2VlIFtFeGFtcGxlOiBBZGQgYSBHZW9KU09OIGxpbmVdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2dlb2pzb24tbGluZS8pXG4gKi9cbmV4cG9ydCB0eXBlIE1hcERhdGFFdmVudCA9IHtcbiAgICB0eXBlOiAnZGF0YSdcbiAgICAgICAgfCAnZGF0YWxvYWRpbmcnXG4gICAgICAgIHwgJ3N0eWxlZGF0YSdcbiAgICAgICAgfCAnc3R5bGVkYXRhbG9hZGluZydcbiAgICAgICAgfCAnc291cmNlZGF0YSdcbiAgICAgICAgfCAnc291cmNlZGF0YWxvYWRpbmcnLFxuICAgIGRhdGFUeXBlOiAnc291cmNlJ1xuICAgICAgICB8ICdzdHlsZSdcbn07XG5cbmV4cG9ydCB0eXBlIE1hcENvbnRleHRFdmVudCA9IHtcbiAgICB0eXBlOiAnd2ViZ2xjb250ZXh0bG9zdCcgfCAnd2ViZ2xjb250ZXh0cmVzdG9yZWQnLFxuICAgIG9yaWdpbmFsRXZlbnQ6IFdlYkdMQ29udGV4dEV2ZW50XG59XG5cbmV4cG9ydCB0eXBlIE1hcEV2ZW50ID1cbiAgICAvKiogQHNlY3Rpb24ge0ludGVyYWN0aW9ufVxuICAgICAqIEBldmVudFxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEBtZW1iZXJvZiBNYXAgKi9cblxuICAgIC8qKlxuICAgICAqIEZpcmVkIHdoZW4gYSBwb2ludGluZyBkZXZpY2UgKHVzdWFsbHkgYSBtb3VzZSkgaXMgcHJlc3NlZCB3aXRoaW4gdGhlIG1hcC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIGV2ZW50IGlzIGNvbXBhdGlibGUgd2l0aCB0aGUgb3B0aW9uYWwgYGxheWVySWRgIHBhcmFtZXRlci5cbiAgICAgKiBJZiBgbGF5ZXJJZGAgaXMgaW5jbHVkZWQgYXMgdGhlIHNlY29uZCBhcmd1bWVudCBpbiB7QGxpbmsgTWFwI29ufSwgdGhlIGV2ZW50IGxpc3RlbmVyIHdpbGwgZmlyZSBvbmx5IHdoZW4gdGhlXG4gICAgICogdGhlIGN1cnNvciBpcyBwcmVzc2VkIHdoaWxlIGluc2lkZSBhIHZpc2libGUgcG9ydGlvbiBvZiB0aGUgc3BlY2lmZWQgbGF5ZXIuXG4gICAgICpcbiAgICAgKiBAZXZlbnQgbW91c2Vkb3duXG4gICAgICogQG1lbWJlcm9mIE1hcFxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEB0eXBlIHtNYXBNb3VzZUV2ZW50fVxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gSW5pdGlhbGl6ZSB0aGUgbWFwXG4gICAgICogY29uc3QgbWFwID0gbmV3IG1hcGJveGdsLk1hcCh7fSk7XG4gICAgICogLy8gU2V0IGFuIGV2ZW50IGxpc3RlbmVyXG4gICAgICogbWFwLm9uKCdtb3VzZWRvd24nLCAoKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdBIG1vdXNlZG93biBldmVudCBoYXMgb2NjdXJyZWQuJyk7XG4gICAgICogfSk7XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBJbml0aWFsaXplIHRoZSBtYXBcbiAgICAgKiBjb25zdCBtYXAgPSBuZXcgbWFwYm94Z2wuTWFwKHt9KTtcbiAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgZm9yIGEgc3BlY2lmaWMgbGF5ZXJcbiAgICAgKiBtYXAub24oJ21vdXNlZG93bicsICdwb2ktbGFiZWwnLCAoKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdBIG1vdXNlZG93biBldmVudCBoYXMgb2NjdXJyZWQgb24gYSB2aXNpYmxlIHBvcnRpb24gb2YgdGhlIHBvaS1sYWJlbCBsYXllci4nKTtcbiAgICAgKiB9KTtcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBIaWdobGlnaHQgZmVhdHVyZXMgd2l0aGluIGEgYm91bmRpbmcgYm94XShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS91c2luZy1ib3gtcXVlcnlyZW5kZXJlZGZlYXR1cmVzLylcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBDcmVhdGUgYSBkcmFnZ2FibGUgcG9pbnRdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2RyYWctYS1wb2ludC8pXG4gICAgICovXG4gICAgfCAnbW91c2Vkb3duJ1xuXG4gICAgLyoqXG4gICAgICogRmlyZWQgd2hlbiBhIHBvaW50aW5nIGRldmljZSAodXN1YWxseSBhIG1vdXNlKSBpcyByZWxlYXNlZCB3aXRoaW4gdGhlIG1hcC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIGV2ZW50IGlzIGNvbXBhdGlibGUgd2l0aCB0aGUgb3B0aW9uYWwgYGxheWVySWRgIHBhcmFtZXRlci5cbiAgICAgKiBJZiBgbGF5ZXJJZGAgaXMgaW5jbHVkZWQgYXMgdGhlIHNlY29uZCBhcmd1bWVudCBpbiB7QGxpbmsgTWFwI29ufSwgdGhlIGV2ZW50IGxpc3RlbmVyIHdpbGwgZmlyZSBvbmx5IHdoZW4gdGhlXG4gICAgICogdGhlIGN1cnNvciBpcyByZWxlYXNlZCB3aGlsZSBpbnNpZGUgYSB2aXNpYmxlIHBvcnRpb24gb2YgdGhlIHNwZWNpZmVkIGxheWVyLlxuICAgICAqXG4gICAgICogQGV2ZW50IG1vdXNldXBcbiAgICAgKiBAbWVtYmVyb2YgTWFwXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHR5cGUge01hcE1vdXNlRXZlbnR9XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBJbml0aWFsaXplIHRoZSBtYXBcbiAgICAgKiBjb25zdCBtYXAgPSBuZXcgbWFwYm94Z2wuTWFwKHt9KTtcbiAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXJcbiAgICAgKiBtYXAub24oJ21vdXNldXAnLCAoKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdBIG1vdXNldXAgZXZlbnQgaGFzIG9jY3VycmVkLicpO1xuICAgICAqIH0pO1xuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gSW5pdGlhbGl6ZSB0aGUgbWFwXG4gICAgICogY29uc3QgbWFwID0gbmV3IG1hcGJveGdsLk1hcCh7fSk7XG4gICAgICogLy8gU2V0IGFuIGV2ZW50IGxpc3RlbmVyIGZvciBhIHNwZWNpZmljIGxheWVyXG4gICAgICogbWFwLm9uKCdtb3VzZXVwJywgJ3BvaS1sYWJlbCcsICgpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ0EgbW91c2V1cCBldmVudCBoYXMgb2NjdXJyZWQgb24gYSB2aXNpYmxlIHBvcnRpb24gb2YgdGhlIHBvaS1sYWJlbCBsYXllci4nKTtcbiAgICAgKiB9KTtcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBIaWdobGlnaHQgZmVhdHVyZXMgd2l0aGluIGEgYm91bmRpbmcgYm94XShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS91c2luZy1ib3gtcXVlcnlyZW5kZXJlZGZlYXR1cmVzLylcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBDcmVhdGUgYSBkcmFnZ2FibGUgcG9pbnRdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2RyYWctYS1wb2ludC8pXG4gICAgICovXG4gICAgfCAnbW91c2V1cCdcblxuICAgIC8qKlxuICAgICAqIEZpcmVkIHdoZW4gYSBwb2ludGluZyBkZXZpY2UgKHVzdWFsbHkgYSBtb3VzZSkgaXMgbW92ZWQgd2l0aGluIHRoZSBtYXAuXG4gICAgICogQXMgeW91IG1vdmUgdGhlIGN1cnNvciBhY3Jvc3MgYSB3ZWIgcGFnZSBjb250YWluaW5nIGEgbWFwLFxuICAgICAqIHRoZSBldmVudCB3aWxsIGZpcmUgZWFjaCB0aW1lIGl0IGVudGVycyB0aGUgbWFwIG9yIGFueSBjaGlsZCBlbGVtZW50cy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIGV2ZW50IGlzIGNvbXBhdGlibGUgd2l0aCB0aGUgb3B0aW9uYWwgYGxheWVySWRgIHBhcmFtZXRlci5cbiAgICAgKiBJZiBgbGF5ZXJJZGAgaXMgaW5jbHVkZWQgYXMgdGhlIHNlY29uZCBhcmd1bWVudCBpbiB7QGxpbmsgTWFwI29ufSwgdGhlIGV2ZW50IGxpc3RlbmVyIHdpbGwgZmlyZSBvbmx5IHdoZW4gdGhlXG4gICAgICogdGhlIGN1cnNvciBpcyBtb3ZlZCBpbnNpZGUgYSB2aXNpYmxlIHBvcnRpb24gb2YgdGhlIHNwZWNpZmVkIGxheWVyLlxuICAgICAqXG4gICAgICogQGV2ZW50IG1vdXNlb3ZlclxuICAgICAqIEBtZW1iZXJvZiBNYXBcbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAdHlwZSB7TWFwTW91c2VFdmVudH1cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEluaXRpYWxpemUgdGhlIG1hcFxuICAgICAqIGNvbnN0IG1hcCA9IG5ldyBtYXBib3hnbC5NYXAoe30pO1xuICAgICAqIC8vIFNldCBhbiBldmVudCBsaXN0ZW5lclxuICAgICAqIG1hcC5vbignbW91c2VvdmVyJywgKCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnQSBtb3VzZW92ZXIgZXZlbnQgaGFzIG9jY3VycmVkLicpO1xuICAgICAqIH0pO1xuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gSW5pdGlhbGl6ZSB0aGUgbWFwXG4gICAgICogY29uc3QgbWFwID0gbmV3IG1hcGJveGdsLk1hcCh7fSk7XG4gICAgICogLy8gU2V0IGFuIGV2ZW50IGxpc3RlbmVyIGZvciBhIHNwZWNpZmljIGxheWVyXG4gICAgICogbWFwLm9uKCdtb3VzZW92ZXInLCAncG9pLWxhYmVsJywgKCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnQSBtb3VzZW92ZXIgZXZlbnQgaGFzIG9jY3VycmVkIG9uIGEgdmlzaWJsZSBwb3J0aW9uIG9mIHRoZSBwb2ktbGFiZWwgbGF5ZXIuJyk7XG4gICAgICogfSk7XG4gICAgICogQHNlZSBbRXhhbXBsZTogR2V0IGNvb3JkaW5hdGVzIG9mIHRoZSBtb3VzZSBwb2ludGVyXShodHRwczovL3d3dy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL21vdXNlLXBvc2l0aW9uLylcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBIaWdobGlnaHQgZmVhdHVyZXMgdW5kZXIgdGhlIG1vdXNlIHBvaW50ZXJdKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvaG92ZXItc3R5bGVzLylcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBEaXNwbGF5IGEgcG9wdXAgb24gaG92ZXJdKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvcG9wdXAtb24taG92ZXIvKVxuICAgICAqL1xuICAgIHwgJ21vdXNlb3ZlcidcblxuICAgIC8qKlxuICAgICAqIEZpcmVkIHdoZW4gYSBwb2ludGluZyBkZXZpY2UgKHVzdWFsbHkgYSBtb3VzZSkgaXMgbW92ZWQgd2hpbGUgdGhlIGN1cnNvciBpcyBpbnNpZGUgdGhlIG1hcC5cbiAgICAgKiBBcyB5b3UgbW92ZSB0aGUgY3Vyc29yIGFjcm9zcyB0aGUgbWFwLCB0aGUgZXZlbnQgd2lsbCBmaXJlIGV2ZXJ5IHRpbWUgdGhlIGN1cnNvciBjaGFuZ2VzIHBvc2l0aW9uIHdpdGhpbiB0aGUgbWFwLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgZXZlbnQgaXMgY29tcGF0aWJsZSB3aXRoIHRoZSBvcHRpb25hbCBgbGF5ZXJJZGAgcGFyYW1ldGVyLlxuICAgICAqIElmIGBsYXllcklkYCBpcyBpbmNsdWRlZCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IGluIHtAbGluayBNYXAjb259LCB0aGUgZXZlbnQgbGlzdGVuZXIgd2lsbCBmaXJlIG9ubHkgd2hlbiB0aGVcbiAgICAgKiB0aGUgY3Vyc29yIGlzIGluc2lkZSBhIHZpc2libGUgcG9ydGlvbiBvZiB0aGUgc3BlY2lmaWVkIGxheWVyLlxuICAgICAqXG4gICAgICogQGV2ZW50IG1vdXNlbW92ZVxuICAgICAqIEBtZW1iZXJvZiBNYXBcbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAdHlwZSB7TWFwTW91c2VFdmVudH1cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEluaXRpYWxpemUgdGhlIG1hcFxuICAgICAqIGNvbnN0IG1hcCA9IG5ldyBtYXBib3hnbC5NYXAoe30pO1xuICAgICAqIC8vIFNldCBhbiBldmVudCBsaXN0ZW5lclxuICAgICAqIG1hcC5vbignbW91c2Vtb3ZlJywgKCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnQSBtb3VzZW1vdmUgZXZlbnQgaGFzIG9jY3VycmVkLicpO1xuICAgICAqIH0pO1xuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gSW5pdGlhbGl6ZSB0aGUgbWFwXG4gICAgICogY29uc3QgbWFwID0gbmV3IG1hcGJveGdsLk1hcCh7fSk7XG4gICAgICogLy8gU2V0IGFuIGV2ZW50IGxpc3RlbmVyIGZvciBhIHNwZWNpZmljIGxheWVyXG4gICAgICogbWFwLm9uKCdtb3VzZW1vdmUnLCAncG9pLWxhYmVsJywgKCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnQSBtb3VzZW1vdmUgZXZlbnQgaGFzIG9jY3VycmVkIG9uIGEgdmlzaWJsZSBwb3J0aW9uIG9mIHRoZSBwb2ktbGFiZWwgbGF5ZXIuJyk7XG4gICAgICogfSk7XG4gICAgICogQHNlZSBbRXhhbXBsZTogR2V0IGNvb3JkaW5hdGVzIG9mIHRoZSBtb3VzZSBwb2ludGVyXShodHRwczovL3d3dy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL21vdXNlLXBvc2l0aW9uLylcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBIaWdobGlnaHQgZmVhdHVyZXMgdW5kZXIgdGhlIG1vdXNlIHBvaW50ZXJdKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvaG92ZXItc3R5bGVzLylcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBEaXNwbGF5IGEgcG9wdXAgb24gb3Zlcl0oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9wb3B1cC1vbi1ob3Zlci8pXG4gICAgICovXG4gICAgfCAnbW91c2Vtb3ZlJ1xuXG4gICAgLyoqXG4gICAgICogVHJpZ2dlcmVkIHdoZW4gYSBjbGljayBldmVudCBvY2N1cnMgYW5kIGlzIGZpcmVkIGJlZm9yZSB0aGUgY2xpY2sgZXZlbnQuXG4gICAgICogUHJpbWFyaWx5IGltcGxlbWVudGVkIHRvIGVuc3VyZSBjbG9zZU9uQ2xpY2sgZm9yIHBvcC11cHMgaXMgZmlyZWQgYmVmb3JlIGFueSBvdGhlciBsaXN0ZW5lcnMuXG4gICAgICpcbiAgICAgKiBAZXZlbnQgcHJlY2xpY2tcbiAgICAgKiBAbWVtYmVyb2YgTWFwXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHR5cGUge01hcE1vdXNlRXZlbnR9XG4gICAgICovXG4gICAgIHwgJ3ByZWNsaWNrJ1xuXG4gICAgLyoqXG4gICAgICogRmlyZWQgd2hlbiBhIHBvaW50aW5nIGRldmljZSAodXN1YWxseSBhIG1vdXNlKSBpcyBwcmVzc2VkIGFuZCByZWxlYXNlZCBhdCB0aGUgc2FtZSBwb2ludCBvbiB0aGUgbWFwLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgZXZlbnQgaXMgY29tcGF0aWJsZSB3aXRoIHRoZSBvcHRpb25hbCBgbGF5ZXJJZGAgcGFyYW1ldGVyLlxuICAgICAqIElmIGBsYXllcklkYCBpcyBpbmNsdWRlZCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IGluIHtAbGluayBNYXAjb259LCB0aGUgZXZlbnQgbGlzdGVuZXIgd2lsbCBmaXJlIG9ubHkgd2hlbiB0aGVcbiAgICAgKiBwb2ludCB0aGF0IGlzIHByZXNzZWQgYW5kIHJlbGVhc2VkIGNvbnRhaW5zIGEgdmlzaWJsZSBwb3J0aW9uIG9mIHRoZSBzcGVjaWZlZCBsYXllci5cbiAgICAgKlxuICAgICAqIEBldmVudCBjbGlja1xuICAgICAqIEBtZW1iZXJvZiBNYXBcbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAdHlwZSB7TWFwTW91c2VFdmVudH1cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEluaXRpYWxpemUgdGhlIG1hcFxuICAgICAqIGNvbnN0IG1hcCA9IG5ldyBtYXBib3hnbC5NYXAoe30pO1xuICAgICAqIC8vIFNldCBhbiBldmVudCBsaXN0ZW5lclxuICAgICAqIG1hcC5vbignY2xpY2snLCAoZSkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZyhgQSBjbGljayBldmVudCBoYXMgb2NjdXJyZWQgYXQgJHtlLmxuZ0xhdH1gKTtcbiAgICAgKiB9KTtcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEluaXRpYWxpemUgdGhlIG1hcFxuICAgICAqIGNvbnN0IG1hcCA9IG5ldyBtYXBib3hnbC5NYXAoe30pO1xuICAgICAqIC8vIFNldCBhbiBldmVudCBsaXN0ZW5lciBmb3IgYSBzcGVjaWZpYyBsYXllclxuICAgICAqIG1hcC5vbignY2xpY2snLCAncG9pLWxhYmVsJywgKGUpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coYEEgY2xpY2sgZXZlbnQgaGFzIG9jY3VycmVkIG9uIGEgdmlzaWJsZSBwb3J0aW9uIG9mIHRoZSBwb2ktbGFiZWwgbGF5ZXIgYXQgJHtlLmxuZ0xhdH1gKTtcbiAgICAgKiB9KTtcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBNZWFzdXJlIGRpc3RhbmNlc10oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9tZWFzdXJlLylcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBDZW50ZXIgdGhlIG1hcCBvbiBhIGNsaWNrZWQgc3ltYm9sXShodHRwczovL3d3dy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2NlbnRlci1vbi1zeW1ib2wvKVxuICAgICAqL1xuICAgIHwgJ2NsaWNrJ1xuXG4gICAgLyoqXG4gICAgICogRmlyZWQgd2hlbiBhIHBvaW50aW5nIGRldmljZSAodXN1YWxseSBhIG1vdXNlKSBpcyBwcmVzc2VkIGFuZCByZWxlYXNlZCB0d2ljZSBhdCB0aGUgc2FtZSBwb2ludCBvblxuICAgICAqIHRoZSBtYXAgaW4gcmFwaWQgc3VjY2Vzc2lvbi5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIGV2ZW50IGlzIGNvbXBhdGlibGUgd2l0aCB0aGUgb3B0aW9uYWwgYGxheWVySWRgIHBhcmFtZXRlci5cbiAgICAgKiBJZiBgbGF5ZXJJZGAgaXMgaW5jbHVkZWQgYXMgdGhlIHNlY29uZCBhcmd1bWVudCBpbiB7QGxpbmsgTWFwI29ufSwgdGhlIGV2ZW50IGxpc3RlbmVyIHdpbGwgZmlyZSBvbmx5XG4gICAgICogd2hlbiB0aGUgcG9pbnQgdGhhdCBpcyBjbGlja2VkIHR3aWNlIGNvbnRhaW5zIGEgdmlzaWJsZSBwb3J0aW9uIG9mIHRoZSBzcGVjaWZlZCBsYXllci5cbiAgICAgKlxuICAgICAqIEBldmVudCBkYmxjbGlja1xuICAgICAqIEBtZW1iZXJvZiBNYXBcbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAdHlwZSB7TWFwTW91c2VFdmVudH1cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEluaXRpYWxpemUgdGhlIG1hcFxuICAgICAqIGNvbnN0IG1hcCA9IG5ldyBtYXBib3hnbC5NYXAoe30pO1xuICAgICAqIC8vIFNldCBhbiBldmVudCBsaXN0ZW5lclxuICAgICAqIG1hcC5vbignZGJsY2xpY2snLCAoZSkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZyhgQSBkYmxjbGljayBldmVudCBoYXMgb2NjdXJyZWQgYXQgJHtlLmxuZ0xhdH1gKTtcbiAgICAgKiB9KTtcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEluaXRpYWxpemUgdGhlIG1hcFxuICAgICAqIGNvbnN0IG1hcCA9IG5ldyBtYXBib3hnbC5NYXAoe30pO1xuICAgICAqIC8vIFNldCBhbiBldmVudCBsaXN0ZW5lciBmb3IgYSBzcGVjaWZpYyBsYXllclxuICAgICAqIG1hcC5vbignZGJsY2xpY2snLCAncG9pLWxhYmVsJywgKGUpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coYEEgZGJsY2xpY2sgZXZlbnQgaGFzIG9jY3VycmVkIG9uIGEgdmlzaWJsZSBwb3J0aW9uIG9mIHRoZSBwb2ktbGFiZWwgbGF5ZXIgYXQgJHtlLmxuZ0xhdH1gKTtcbiAgICAgKiB9KTtcbiAgICAgKi9cbiAgICB8ICdkYmxjbGljaydcblxuICAgIC8qKlxuICAgICAqIEZpcmVkIHdoZW4gYSBwb2ludGluZyBkZXZpY2UgKHVzdWFsbHkgYSBtb3VzZSkgZW50ZXJzIGEgdmlzaWJsZSBwb3J0aW9uIG9mIGEgc3BlY2lmaWVkIGxheWVyIGZyb21cbiAgICAgKiBvdXRzaWRlIHRoYXQgbGF5ZXIgb3Igb3V0c2lkZSB0aGUgbWFwIGNhbnZhcy5cbiAgICAgKlxuICAgICAqICoqSW1wb3J0YW50OioqIFRoaXMgZXZlbnQgY2FuIG9ubHkgYmUgbGlzdGVuZWQgZm9yIHdoZW4ge0BsaW5rIE1hcCNvbn0gaW5jbHVkZXMgdGhyZWUgYXJndW1lbnRzLFxuICAgICAqIHdoZXJlIHRoZSBzZWNvbmQgYXJndW1lbnQgc3BlY2lmaWVzIHRoZSBkZXNpcmVkIGxheWVyLlxuICAgICAqXG4gICAgICogQGV2ZW50IG1vdXNlZW50ZXJcbiAgICAgKiBAbWVtYmVyb2YgTWFwXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHR5cGUge01hcE1vdXNlRXZlbnR9XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBJbml0aWFsaXplIHRoZSBtYXBcbiAgICAgKiBjb25zdCBtYXAgPSBuZXcgbWFwYm94Z2wuTWFwKHt9KTtcbiAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXJcbiAgICAgKiBtYXAub24oJ21vdXNlZW50ZXInLCAnd2F0ZXInLCAoKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdBIG1vdXNlZW50ZXIgZXZlbnQgb2NjdXJyZWQgb24gYSB2aXNpYmxlIHBvcnRpb24gb2YgdGhlIHdhdGVyIGxheWVyLicpO1xuICAgICAqIH0pO1xuICAgICAqIEBzZWUgW0V4YW1wbGU6IENlbnRlciB0aGUgbWFwIG9uIGEgY2xpY2tlZCBzeW1ib2xdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2NlbnRlci1vbi1zeW1ib2wvKVxuICAgICAqIEBzZWUgW0V4YW1wbGU6IERpc3BsYXkgYSBwb3B1cCBvbiBjbGlja10oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvcG9wdXAtb24tY2xpY2svKVxuICAgICAqL1xuICAgIHwgJ21vdXNlZW50ZXInXG5cbiAgICAvKipcbiAgICAgKiBGaXJlZCB3aGVuIGEgcG9pbnRpbmcgZGV2aWNlICh1c3VhbGx5IGEgbW91c2UpIGxlYXZlcyBhIHZpc2libGUgcG9ydGlvbiBvZiBhIHNwZWNpZmllZCBsYXllciBvciBtb3Zlc1xuICAgICAqIGZyb20gdGhlIHNwZWNpZmllZCBsYXllciB0byBvdXRzaWRlIHRoZSBtYXAgY2FudmFzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRvIGRldGVjdCB3aGVuIHRoZSBtb3VzZSBsZWF2ZXMgdGhlIGNhbnZhcywgaW5kZXBlbmRlbnQgb2YgbGF5ZXIsIHVzZSB7QGxpbmsgTWFwLmV2ZW50Om1vdXNlb3V0fSBpbnN0ZWFkLlxuICAgICAqXG4gICAgICogKipJbXBvcnRhbnQ6KiogVGhpcyBldmVudCBjYW4gb25seSBiZSBsaXN0ZW5lZCBmb3Igd2hlbiB7QGxpbmsgTWFwI29ufSBpbmNsdWRlcyB0aHJlZSBhcmd1bWVudHMsXG4gICAgICogd2hlcmUgdGhlIHNlY29uZCBhcmd1bWVudCBzcGVjaWZpZXMgdGhlIGRlc2lyZWQgbGF5ZXIuXG4gICAgICpcbiAgICAgKiBAZXZlbnQgbW91c2VsZWF2ZVxuICAgICAqIEBtZW1iZXJvZiBNYXBcbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAdHlwZSB7TWFwTW91c2VFdmVudH1cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEluaXRpYWxpemUgdGhlIG1hcFxuICAgICAqIGNvbnN0IG1hcCA9IG5ldyBtYXBib3hnbC5NYXAoe30pO1xuICAgICAqIC8vIFNldCBhbiBldmVudCBsaXN0ZW5lciB0aGF0IGZpcmVzXG4gICAgICogLy8gd2hlbiB0aGUgcG9pbnRpbmcgZGV2aWNlIGxlYXZlc1xuICAgICAqIC8vIGEgdmlzaWJsZSBwb3J0aW9uIG9mIHRoZSBzcGVjaWZpZWQgbGF5ZXIuXG4gICAgICogbWFwLm9uKCdtb3VzZWxlYXZlJywgJ3dhdGVyJywgKCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnQSBtb3VzZWxlYXZlIGV2ZW50IG9jY3VycmVkLicpO1xuICAgICAqIH0pO1xuICAgICAqIEBzZWUgW0V4YW1wbGU6IEhpZ2hsaWdodCBmZWF0dXJlcyB1bmRlciB0aGUgbW91c2UgcG9pbnRlcl0oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9ob3Zlci1zdHlsZXMvKVxuICAgICAqIEBzZWUgW0V4YW1wbGU6IERpc3BsYXkgYSBwb3B1cCBvbiBjbGlja10oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvcG9wdXAtb24tY2xpY2svKVxuICAgICAqL1xuICAgIHwgJ21vdXNlbGVhdmUnXG5cbiAgICAvKipcbiAgICAgKiBGaXJlZCB3aGVuIGEgcG9pbnQgZGV2aWNlICh1c3VhbGx5IGEgbW91c2UpIGxlYXZlcyB0aGUgbWFwJ3MgY2FudmFzLlxuICAgICAqXG4gICAgICogQGV2ZW50IG1vdXNlb3V0XG4gICAgICogQG1lbWJlcm9mIE1hcFxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEB0eXBlIHtNYXBNb3VzZUV2ZW50fVxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gSW5pdGlhbGl6ZSB0aGUgbWFwXG4gICAgICogY29uc3QgbWFwID0gbmV3IG1hcGJveGdsLk1hcCh7fSk7XG4gICAgICogLy8gU2V0IGFuIGV2ZW50IGxpc3RlbmVyIHRoYXQgZmlyZXNcbiAgICAgKiAvLyB3aGVuIHRoZSBwb2ludGluZyBkZXZpY2UgbGVhdmVzXG4gICAgICogLy8gdGhlIG1hcCdzIGNhbnZhcy5cbiAgICAgKiBtYXAub24oJ21vdXNlb3V0JywgKCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnQSBtb3VzZW91dCBldmVudCBvY2N1cnJlZC4nKTtcbiAgICAgKiB9KTtcbiAgICAgKi9cbiAgICB8ICdtb3VzZW91dCdcblxuICAgIC8qKlxuICAgICAqIEZpcmVkIHdoZW4gdGhlIHJpZ2h0IGJ1dHRvbiBvZiB0aGUgbW91c2UgaXMgY2xpY2tlZCBvciB0aGUgY29udGV4dCBtZW51IGtleSBpcyBwcmVzc2VkIHdpdGhpbiB0aGUgbWFwLlxuICAgICAqXG4gICAgICogQGV2ZW50IGNvbnRleHRtZW51XG4gICAgICogQG1lbWJlcm9mIE1hcFxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEB0eXBlIHtNYXBNb3VzZUV2ZW50fVxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gSW5pdGlhbGl6ZSB0aGUgbWFwXG4gICAgICogY29uc3QgbWFwID0gbmV3IG1hcGJveGdsLk1hcCh7fSk7XG4gICAgICogLy8gU2V0IGFuIGV2ZW50IGxpc3RlbmVyIHRoYXQgZmlyZXNcbiAgICAgKiAvLyB3aGVuIHRoZSByaWdodCBtb3VzZSBidXR0b24gaXNcbiAgICAgKiAvLyBwcmVzc2VkIHdpdGhpbiB0aGUgbWFwLlxuICAgICAqIG1hcC5vbignY29udGV4dG1lbnUnLCAoKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdBIGNvbnRleHRtZW51IGV2ZW50IG9jY3VycmVkLicpO1xuICAgICAqIH0pO1xuICAgICAqL1xuICAgIHwgJ2NvbnRleHRtZW51J1xuXG4gICAgLyoqXG4gICAgICogRmlyZWQgd2hlbiBhIFtgd2hlZWxgXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9FdmVudHMvd2hlZWwpIGV2ZW50IG9jY3VycyB3aXRoaW4gdGhlIG1hcC5cbiAgICAgKlxuICAgICAqIEBldmVudCB3aGVlbFxuICAgICAqIEBtZW1iZXJvZiBNYXBcbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAdHlwZSB7TWFwV2hlZWxFdmVudH1cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEluaXRpYWxpemUgdGhlIG1hcFxuICAgICAqIGNvbnN0IG1hcCA9IG5ldyBtYXBib3hnbC5NYXAoe30pO1xuICAgICAqIC8vIFNldCBhbiBldmVudCBsaXN0ZW5lciB0aGF0IGZpcmVzXG4gICAgICogLy8gd2hlbiBhIHdoZWVsIGV2ZW50IG9jY3VycyB3aXRoaW4gdGhlIG1hcC5cbiAgICAgKiBtYXAub24oJ3doZWVsJywgKCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnQSB3aGVlbCBldmVudCBvY2N1cnJlZC4nKTtcbiAgICAgKiB9KTtcbiAgICAgKi9cbiAgICB8ICd3aGVlbCdcblxuICAgIC8qKlxuICAgICAqIEZpcmVkIHdoZW4gYSBbYHRvdWNoc3RhcnRgXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9FdmVudHMvdG91Y2hzdGFydCkgZXZlbnQgb2NjdXJzIHdpdGhpbiB0aGUgbWFwLlxuICAgICAqXG4gICAgICogQGV2ZW50IHRvdWNoc3RhcnRcbiAgICAgKiBAbWVtYmVyb2YgTWFwXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHR5cGUge01hcFRvdWNoRXZlbnR9XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBJbml0aWFsaXplIHRoZSBtYXBcbiAgICAgKiBjb25zdCBtYXAgPSBuZXcgbWFwYm94Z2wuTWFwKHt9KTtcbiAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBmaXJlc1xuICAgICAqIC8vIHdoZW4gYSBgdG91Y2hzdGFydGAgZXZlbnQgb2NjdXJzIHdpdGhpbiB0aGUgbWFwLlxuICAgICAqIG1hcC5vbigndG91Y2hzdGFydCcsICgpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ0EgdG91Y2hzdGFydCBldmVudCBvY2N1cnJlZC4nKTtcbiAgICAgKiB9KTtcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBDcmVhdGUgYSBkcmFnZ2FibGUgcG9pbnRdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2RyYWctYS1wb2ludC8pXG4gICAgICovXG4gICAgfCAndG91Y2hzdGFydCdcblxuICAgIC8qKlxuICAgICAqIEZpcmVkIHdoZW4gYSBbYHRvdWNoZW5kYF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvRXZlbnRzL3RvdWNoZW5kKSBldmVudCBvY2N1cnMgd2l0aGluIHRoZSBtYXAuXG4gICAgICpcbiAgICAgKiBAZXZlbnQgdG91Y2hlbmRcbiAgICAgKiBAbWVtYmVyb2YgTWFwXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHR5cGUge01hcFRvdWNoRXZlbnR9XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBJbml0aWFsaXplIHRoZSBtYXAuXG4gICAgICogY29uc3QgbWFwID0gbmV3IG1hcGJveGdsLk1hcCh7fSk7XG4gICAgICogLy8gU2V0IGFuIGV2ZW50IGxpc3RlbmVyIHRoYXQgZmlyZXMgd2hlbiBhIGB0b3VjaHN0YXJ0YCBldmVudCBvY2N1cnMgd2l0aGluIHRoZSBtYXAuXG4gICAgICogbWFwLm9uKCd0b3VjaHN0YXJ0JywgKCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnQSB0b3VjaHN0YXJ0IGV2ZW50IG9jY3VycmVkLicpO1xuICAgICAqIH0pO1xuICAgICAqIEBzZWUgW0V4YW1wbGU6IENyZWF0ZSBhIGRyYWdnYWJsZSBwb2ludF0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvZHJhZy1hLXBvaW50LylcbiAgICAgKi9cbiAgICB8ICd0b3VjaGVuZCdcblxuICAgIC8qKlxuICAgICAqIEZpcmVkIHdoZW4gYSBbYHRvdWNobW92ZWBdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0V2ZW50cy90b3VjaG1vdmUpIGV2ZW50IG9jY3VycyB3aXRoaW4gdGhlIG1hcC5cbiAgICAgKlxuICAgICAqIEBldmVudCB0b3VjaG1vdmVcbiAgICAgKiBAbWVtYmVyb2YgTWFwXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHR5cGUge01hcFRvdWNoRXZlbnR9XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBJbml0aWFsaXplIHRoZSBtYXAuXG4gICAgICogY29uc3QgbWFwID0gbmV3IG1hcGJveGdsLk1hcCh7fSk7XG4gICAgICogLy8gU2V0IGFuIGV2ZW50IGxpc3RlbmVyIHRoYXQgZmlyZXMgd2hlbiBhIHRvdWNobW92ZSBldmVudCBvY2N1cnMgd2l0aGluIHRoZSBtYXAuXG4gICAgICogbWFwLm9uKCd0b3VjaG1vdmUnLCAoKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdBIHRvdWNobW92ZSBldmVudCBvY2N1cnJlZC4nKTtcbiAgICAgKiB9KTtcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBDcmVhdGUgYSBkcmFnZ2FibGUgcG9pbnRdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2RyYWctYS1wb2ludC8pXG4gICAgICovXG4gICAgfCAndG91Y2htb3ZlJ1xuXG4gICAgLyoqXG4gICAgICogRmlyZWQgd2hlbiBhIFtgdG91Y2hjYW5jZWxgXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9FdmVudHMvdG91Y2hjYW5jZWwpIGV2ZW50IG9jY3VycyB3aXRoaW4gdGhlIG1hcC5cbiAgICAgKlxuICAgICAqIEBldmVudCB0b3VjaGNhbmNlbFxuICAgICAqIEBtZW1iZXJvZiBNYXBcbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAdHlwZSB7TWFwVG91Y2hFdmVudH1cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEluaXRpYWxpemUgdGhlIG1hcC5cbiAgICAgKiBjb25zdCBtYXAgPSBuZXcgbWFwYm94Z2wuTWFwKHt9KTtcbiAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBmaXJlcyB3aGVuIGEgYHRvdWNoY2FuY2VsYCBldmVudCBvY2N1cnMgd2l0aGluIHRoZSBtYXAuXG4gICAgICogbWFwLm9uKCd0b3VjaGNhbmNlbCcsICgpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ0EgdG91Y2hjYW5jZWwgZXZlbnQgb2NjdXJyZWQuJyk7XG4gICAgICogfSk7XG4gICAgICovXG4gICAgfCAndG91Y2hjYW5jZWwnXG5cbiAgICAvKiogQHNlY3Rpb24ge01vdmVtZW50fVxuICAgICAqIEBldmVudFxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEBtZW1iZXJvZiBNYXAgKi9cblxuICAgIC8qKlxuICAgICAqIEZpcmVkIGp1c3QgYmVmb3JlIHRoZSBtYXAgYmVnaW5zIGEgdHJhbnNpdGlvbiBmcm9tIG9uZSB2aWV3IHRvIGFub3RoZXIsIGFzIHRoZSByZXN1bHQgb2YgZWl0aGVyIHVzZXIgaW50ZXJhY3Rpb24gb3IgbWV0aG9kcyBzdWNoIGFzIHtAbGluayBNYXAjanVtcFRvfS5cbiAgICAgKlxuICAgICAqIEBldmVudCBtb3Zlc3RhcnRcbiAgICAgKiBAbWVtYmVyb2YgTWFwXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHR5cGUge0RyYWdFdmVudH1cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEluaXRpYWxpemUgdGhlIG1hcC5cbiAgICAgKiBjb25zdCBtYXAgPSBuZXcgbWFwYm94Z2wuTWFwKHt9KTtcbiAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBmaXJlcyBqdXN0IGJlZm9yZSB0aGUgbWFwIGJlZ2lucyBhIHRyYW5zaXRpb24gZnJvbSBvbmUgdmlldyB0byBhbm90aGVyLlxuICAgICAqIG1hcC5vbignbW92ZXN0YXJ0JywgKCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnQSBtb3Zlc3RhcnRgIGV2ZW50IG9jY3VycmVkLicpO1xuICAgICAqIH0pO1xuICAgICAqL1xuICAgIHwgJ21vdmVzdGFydCdcblxuICAgIC8qKlxuICAgICAqIEZpcmVkIHJlcGVhdGVkbHkgZHVyaW5nIGFuIGFuaW1hdGVkIHRyYW5zaXRpb24gZnJvbSBvbmUgdmlldyB0byBhbm90aGVyLCBhcyB0aGUgcmVzdWx0IG9mIGVpdGhlciB1c2VyIGludGVyYWN0aW9uIG9yIG1ldGhvZHMgc3VjaCBhcyB7QGxpbmsgTWFwI2ZseVRvfS5cbiAgICAgKlxuICAgICAqIEBldmVudCBtb3ZlXG4gICAgICogQG1lbWJlcm9mIE1hcFxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEB0eXBlIHtNYXBNb3VzZUV2ZW50IHwgTWFwVG91Y2hFdmVudH1cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEluaXRpYWxpemUgdGhlIG1hcC5cbiAgICAgKiBjb25zdCBtYXAgPSBuZXcgbWFwYm94Z2wuTWFwKHt9KTtcbiAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBmaXJlcyByZXBlYXRlZGx5IGR1cmluZyBhbiBhbmltYXRlZCB0cmFuc2l0aW9uLlxuICAgICAqIG1hcC5vbignbW92ZScsICgpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ0EgbW92ZSBldmVudCBvY2N1cnJlZC4nKTtcbiAgICAgKiB9KTtcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBEaXNwbGF5IEhUTUwgY2x1c3RlcnMgd2l0aCBjdXN0b20gcHJvcGVydGllc10oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvY2x1c3Rlci1odG1sLylcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBGaWx0ZXIgZmVhdHVyZXMgd2l0aGluIG1hcCB2aWV3XShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9maWx0ZXItZmVhdHVyZXMtd2l0aGluLW1hcC12aWV3LylcbiAgICAgKi9cbiAgICB8ICdtb3ZlJ1xuXG4gICAgLyoqXG4gICAgICogRmlyZWQganVzdCBhZnRlciB0aGUgbWFwIGNvbXBsZXRlcyBhIHRyYW5zaXRpb24gZnJvbSBvbmVcbiAgICAgKiB2aWV3IHRvIGFub3RoZXIsIGFzIHRoZSByZXN1bHQgb2YgZWl0aGVyIHVzZXIgaW50ZXJhY3Rpb24gb3IgbWV0aG9kcyBzdWNoIGFzIHtAbGluayBNYXAjanVtcFRvfS5cbiAgICAgKlxuICAgICAqIEBldmVudCBtb3ZlZW5kXG4gICAgICogQG1lbWJlcm9mIE1hcFxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEB0eXBlIHtEcmFnRXZlbnR9XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBJbml0aWFsaXplIHRoZSBtYXBcbiAgICAgKiBjb25zdCBtYXAgPSBuZXcgbWFwYm94Z2wuTWFwKHt9KTtcbiAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBmaXJlc1xuICAgICAqIC8vIGp1c3QgYWZ0ZXIgdGhlIG1hcCBjb21wbGV0ZXMgYSB0cmFuc2l0aW9uLlxuICAgICAqIG1hcC5vbignbW92ZWVuZCcsICgpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ0EgbW92ZWVuZCBldmVudCBvY2N1cnJlZC4nKTtcbiAgICAgKiB9KTtcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBQbGF5IG1hcCBsb2NhdGlvbnMgYXMgYSBzbGlkZXNob3ddKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvcGxheWJhY2stbG9jYXRpb25zLylcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBGaWx0ZXIgZmVhdHVyZXMgd2l0aGluIG1hcCB2aWV3XShodHRwczovL3d3dy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2ZpbHRlci1mZWF0dXJlcy13aXRoaW4tbWFwLXZpZXcvKVxuICAgICAqIEBzZWUgW0V4YW1wbGU6IERpc3BsYXkgSFRNTCBjbHVzdGVycyB3aXRoIGN1c3RvbSBwcm9wZXJ0aWVzXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9jbHVzdGVyLWh0bWwvKVxuICAgICAqL1xuICAgIHwgJ21vdmVlbmQnXG5cbiAgICAvKipcbiAgICAgKiBGaXJlZCB3aGVuIGEgXCJkcmFnIHRvIHBhblwiIGludGVyYWN0aW9uIHN0YXJ0cy4gU2VlIHtAbGluayBEcmFnUGFuSGFuZGxlcn0uXG4gICAgICpcbiAgICAgKiBAZXZlbnQgZHJhZ3N0YXJ0XG4gICAgICogQG1lbWJlcm9mIE1hcFxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEB0eXBlIHtEcmFnRXZlbnR9XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBJbml0aWFsaXplIHRoZSBtYXBcbiAgICAgKiBjb25zdCBtYXAgPSBuZXcgbWFwYm94Z2wuTWFwKHt9KTtcbiAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBmaXJlc1xuICAgICAqIC8vIHdoZW4gYSBcImRyYWcgdG8gcGFuXCIgaW50ZXJhY3Rpb24gc3RhcnRzLlxuICAgICAqIG1hcC5vbignZHJhZ3N0YXJ0JywgKCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnQSBkcmFnc3RhcnQgZXZlbnQgb2NjdXJyZWQuJyk7XG4gICAgICogfSk7XG4gICAgICovXG4gICAgfCAnZHJhZ3N0YXJ0J1xuXG4gICAgLyoqXG4gICAgICogRmlyZWQgcmVwZWF0ZWRseSBkdXJpbmcgYSBcImRyYWcgdG8gcGFuXCIgaW50ZXJhY3Rpb24uIFNlZSB7QGxpbmsgRHJhZ1BhbkhhbmRsZXJ9LlxuICAgICAqXG4gICAgICogQGV2ZW50IGRyYWdcbiAgICAgKiBAbWVtYmVyb2YgTWFwXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHR5cGUge01hcE1vdXNlRXZlbnQgfCBNYXBUb3VjaEV2ZW50fVxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gSW5pdGlhbGl6ZSB0aGUgbWFwXG4gICAgICogY29uc3QgbWFwID0gbmV3IG1hcGJveGdsLk1hcCh7fSk7XG4gICAgICogLy8gU2V0IGFuIGV2ZW50IGxpc3RlbmVyIHRoYXQgZmlyZXNcbiAgICAgKiAvLyByZXBlYXRlZGx5IGR1cmluZyBhIFwiZHJhZyB0byBwYW5cIiBpbnRlcmFjdGlvbi5cbiAgICAgKiBtYXAub24oJ2RyYWcnLCAoKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdBIGRyYWcgZXZlbnQgb2NjdXJyZWQuJyk7XG4gICAgICogfSk7XG4gICAgICovXG4gICAgfCAnZHJhZydcblxuICAgIC8qKlxuICAgICAqIEZpcmVkIHdoZW4gYSBcImRyYWcgdG8gcGFuXCIgaW50ZXJhY3Rpb24gZW5kcy4gU2VlIHtAbGluayBEcmFnUGFuSGFuZGxlcn0uXG4gICAgICpcbiAgICAgKiBAZXZlbnQgZHJhZ2VuZFxuICAgICAqIEBtZW1iZXJvZiBNYXBcbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAdHlwZSB7RHJhZ0V2ZW50fVxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gSW5pdGlhbGl6ZSB0aGUgbWFwXG4gICAgICogY29uc3QgbWFwID0gbmV3IG1hcGJveGdsLk1hcCh7fSk7XG4gICAgICogLy8gU2V0IGFuIGV2ZW50IGxpc3RlbmVyIHRoYXQgZmlyZXNcbiAgICAgKiAvLyB3aGVuIGEgXCJkcmFnIHRvIHBhblwiIGludGVyYWN0aW9uIGVuZHMuXG4gICAgICogbWFwLm9uKCdkcmFnZW5kJywgKCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnQSBkcmFnZW5kIGV2ZW50IG9jY3VycmVkLicpO1xuICAgICAqIH0pO1xuICAgICAqIEBzZWUgW0V4YW1wbGU6IENyZWF0ZSBhIGRyYWdnYWJsZSBtYXJrZXJdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2RyYWctYS1tYXJrZXIvKVxuICAgICAqL1xuICAgIHwgJ2RyYWdlbmQnXG5cbiAgICAvKipcbiAgICAgKiBGaXJlZCBqdXN0IGJlZm9yZSB0aGUgbWFwIGJlZ2lucyBhIHRyYW5zaXRpb24gZnJvbSBvbmUgem9vbSBsZXZlbCB0byBhbm90aGVyLFxuICAgICAqIGFzIHRoZSByZXN1bHQgb2YgZWl0aGVyIHVzZXIgaW50ZXJhY3Rpb24gb3IgbWV0aG9kcyBzdWNoIGFzIHtAbGluayBNYXAjZmx5VG99LlxuICAgICAqXG4gICAgICogQGV2ZW50IHpvb21zdGFydFxuICAgICAqIEBtZW1iZXJvZiBNYXBcbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAdHlwZSB7TWFwTW91c2VFdmVudCB8IE1hcFRvdWNoRXZlbnR9XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBJbml0aWFsaXplIHRoZSBtYXBcbiAgICAgKiBjb25zdCBtYXAgPSBuZXcgbWFwYm94Z2wuTWFwKHt9KTtcbiAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBmaXJlc1xuICAgICAqIC8vIGp1c3QgYmVmb3JlIGEgem9vbSB0cmFuc2l0aW9uIHN0YXJ0cy5cbiAgICAgKiBtYXAub24oJ3pvb21zdGFydCcsICgpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ0Egem9vbXN0YXJ0IGV2ZW50IG9jY3VycmVkLicpO1xuICAgICAqIH0pO1xuICAgICAqL1xuICAgIHwgJ3pvb21zdGFydCdcblxuICAgIC8qKlxuICAgICAqIEZpcmVkIHJlcGVhdGVkbHkgZHVyaW5nIGFuIGFuaW1hdGVkIHRyYW5zaXRpb24gZnJvbSBvbmUgem9vbSBsZXZlbCB0byBhbm90aGVyLFxuICAgICAqIGFzIHRoZSByZXN1bHQgb2YgZWl0aGVyIHVzZXIgaW50ZXJhY3Rpb24gb3IgbWV0aG9kcyBzdWNoIGFzIHtAbGluayBNYXAjZmx5VG99LlxuICAgICAqXG4gICAgICogQGV2ZW50IHpvb21cbiAgICAgKiBAbWVtYmVyb2YgTWFwXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHR5cGUge01hcE1vdXNlRXZlbnQgfCBNYXBUb3VjaEV2ZW50fVxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gSW5pdGlhbGl6ZSB0aGUgbWFwXG4gICAgICogY29uc3QgbWFwID0gbmV3IG1hcGJveGdsLk1hcCh7fSk7XG4gICAgICogLy8gU2V0IGFuIGV2ZW50IGxpc3RlbmVyIHRoYXQgZmlyZXNcbiAgICAgKiAvLyByZXBlYXRlZGx5IGR1cmluZyBhIHpvb20gdHJhbnNpdGlvbi5cbiAgICAgKiBtYXAub24oJ3pvb20nLCAoKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdBIHpvb20gZXZlbnQgb2NjdXJyZWQuJyk7XG4gICAgICogfSk7XG4gICAgICogQHNlZSBbRXhhbXBsZTogVXBkYXRlIGEgY2hvcm9wbGV0aCBsYXllciBieSB6b29tIGxldmVsXShodHRwczovL3d3dy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL3VwZGF0aW5nLWNob3JvcGxldGgvKVxuICAgICAqL1xuICAgIHwgJ3pvb20nXG5cbiAgICAvKipcbiAgICAgKiBGaXJlZCBqdXN0IGFmdGVyIHRoZSBtYXAgY29tcGxldGVzIGEgdHJhbnNpdGlvbiBmcm9tIG9uZSB6b29tIGxldmVsIHRvIGFub3RoZXJcbiAgICAgKiBhcyB0aGUgcmVzdWx0IG9mIGVpdGhlciB1c2VyIGludGVyYWN0aW9uIG9yIG1ldGhvZHMgc3VjaCBhcyB7QGxpbmsgTWFwI2ZseVRvfS5cbiAgICAgKiBUaGUgem9vbSB0cmFuc2l0aW9uIHdpbGwgdXN1YWxseSBlbmQgYmVmb3JlIHJlbmRlcmluZyBpcyBmaW5pc2hlZCwgc28gaWYgeW91XG4gICAgICogbmVlZCB0byB3YWl0IGZvciByZW5kZXJpbmcgdG8gZmluaXNoLCB1c2UgdGhlIHtAbGluayBNYXAuZXZlbnQ6aWRsZX0gZXZlbnQgaW5zdGVhZC5cbiAgICAgKlxuICAgICAqIEBldmVudCB6b29tZW5kXG4gICAgICogQG1lbWJlcm9mIE1hcFxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEB0eXBlIHtNYXBNb3VzZUV2ZW50IHwgTWFwVG91Y2hFdmVudH1cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEluaXRpYWxpemUgdGhlIG1hcFxuICAgICAqIGNvbnN0IG1hcCA9IG5ldyBtYXBib3hnbC5NYXAoe30pO1xuICAgICAqIC8vIFNldCBhbiBldmVudCBsaXN0ZW5lciB0aGF0IGZpcmVzXG4gICAgICogLy8ganVzdCBhZnRlciBhIHpvb20gdHJhbnNpdGlvbiBmaW5pc2hlcy5cbiAgICAgKiBtYXAub24oJ3pvb21lbmQnLCAoKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdBIHpvb21lbmQgZXZlbnQgb2NjdXJyZWQuJyk7XG4gICAgICogfSk7XG4gICAgICovXG4gICAgfCAnem9vbWVuZCdcblxuICAgIC8qKlxuICAgICAqIEZpcmVkIHdoZW4gYSBcImRyYWcgdG8gcm90YXRlXCIgaW50ZXJhY3Rpb24gc3RhcnRzLiBTZWUge0BsaW5rIERyYWdSb3RhdGVIYW5kbGVyfS5cbiAgICAgKlxuICAgICAqIEBldmVudCByb3RhdGVzdGFydFxuICAgICAqIEBtZW1iZXJvZiBNYXBcbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAdHlwZSB7TWFwTW91c2VFdmVudCB8IE1hcFRvdWNoRXZlbnR9XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBJbml0aWFsaXplIHRoZSBtYXBcbiAgICAgKiBjb25zdCBtYXAgPSBuZXcgbWFwYm94Z2wuTWFwKHt9KTtcbiAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBmaXJlc1xuICAgICAqIC8vIGp1c3QgYmVmb3JlIGEgXCJkcmFnIHRvIHJvdGF0ZVwiIGludGVyYWN0aW9uIHN0YXJ0cy5cbiAgICAgKiBtYXAub24oJ3JvdGF0ZXN0YXJ0JywgKCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnQSByb3RhdGVzdGFydCBldmVudCBvY2N1cnJlZC4nKTtcbiAgICAgKiB9KTtcbiAgICAgKi9cbiAgICB8ICdyb3RhdGVzdGFydCdcblxuICAgIC8qKlxuICAgICAqIEZpcmVkIHJlcGVhdGVkbHkgZHVyaW5nIGEgXCJkcmFnIHRvIHJvdGF0ZVwiIGludGVyYWN0aW9uLiBTZWUge0BsaW5rIERyYWdSb3RhdGVIYW5kbGVyfS5cbiAgICAgKlxuICAgICAqIEBldmVudCByb3RhdGVcbiAgICAgKiBAbWVtYmVyb2YgTWFwXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHR5cGUge01hcE1vdXNlRXZlbnQgfCBNYXBUb3VjaEV2ZW50fVxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gSW5pdGlhbGl6ZSB0aGUgbWFwXG4gICAgICogY29uc3QgbWFwID0gbmV3IG1hcGJveGdsLk1hcCh7fSk7XG4gICAgICogLy8gU2V0IGFuIGV2ZW50IGxpc3RlbmVyIHRoYXQgZmlyZXNcbiAgICAgKiAvLyByZXBlYXRlZGx5IGR1cmluZyBcImRyYWcgdG8gcm90YXRlXCIgaW50ZXJhY3Rpb24uXG4gICAgICogbWFwLm9uKCdyb3RhdGUnLCAoKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdBIHJvdGF0ZSBldmVudCBvY2N1cnJlZC4nKTtcbiAgICAgKiB9KTtcbiAgICAgKi9cbiAgICB8ICdyb3RhdGUnXG5cbiAgICAvKipcbiAgICAgKiBGaXJlZCB3aGVuIGEgXCJkcmFnIHRvIHJvdGF0ZVwiIGludGVyYWN0aW9uIGVuZHMuIFNlZSB7QGxpbmsgRHJhZ1JvdGF0ZUhhbmRsZXJ9LlxuICAgICAqXG4gICAgICogQGV2ZW50IHJvdGF0ZWVuZFxuICAgICAqIEBtZW1iZXJvZiBNYXBcbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAdHlwZSB7TWFwTW91c2VFdmVudCB8IE1hcFRvdWNoRXZlbnR9XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBJbml0aWFsaXplIHRoZSBtYXBcbiAgICAgKiBjb25zdCBtYXAgPSBuZXcgbWFwYm94Z2wuTWFwKHt9KTtcbiAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBmaXJlc1xuICAgICAqIC8vIGp1c3QgYWZ0ZXIgYSBcImRyYWcgdG8gcm90YXRlXCIgaW50ZXJhY3Rpb24gZW5kcy5cbiAgICAgKiBtYXAub24oJ3JvdGF0ZWVuZCcsICgpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ0Egcm90YXRlZW5kIGV2ZW50IG9jY3VycmVkLicpO1xuICAgICAqIH0pO1xuICAgICAqL1xuICAgIHwgJ3JvdGF0ZWVuZCdcblxuICAgIC8qKlxuICAgICAqIEZpcmVkIHdoZW5ldmVyIHRoZSBtYXAncyBwaXRjaCAodGlsdCkgYmVnaW5zIGEgY2hhbmdlIGFzXG4gICAgICogdGhlIHJlc3VsdCBvZiBlaXRoZXIgdXNlciBpbnRlcmFjdGlvbiBvciBtZXRob2RzIHN1Y2ggYXMge0BsaW5rIE1hcCNmbHlUb30gLlxuICAgICAqXG4gICAgICogQGV2ZW50IHBpdGNoc3RhcnRcbiAgICAgKiBAbWVtYmVyb2YgTWFwXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHR5cGUge01hcERhdGFFdmVudH1cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEluaXRpYWxpemUgdGhlIG1hcFxuICAgICAqIGNvbnN0IG1hcCA9IG5ldyBtYXBib3hnbC5NYXAoe30pO1xuICAgICAqIC8vIFNldCBhbiBldmVudCBsaXN0ZW5lciB0aGF0IGZpcmVzXG4gICAgICogLy8ganVzdCBiZWZvcmUgYSBwaXRjaCAodGlsdCkgdHJhbnNpdGlvbiBzdGFydHMuXG4gICAgICogbWFwLm9uKCdwaXRjaHN0YXJ0JywgKCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnQSBwaXRjaHN0YXJ0IGV2ZW50IG9jY3VycmVkLicpO1xuICAgICAqIH0pO1xuICAgICAqL1xuICAgIHwgJ3BpdGNoc3RhcnQnXG5cbiAgICAvKipcbiAgICAgKiBGaXJlZCByZXBlYXRlZGx5IGR1cmluZyB0aGUgbWFwJ3MgcGl0Y2ggKHRpbHQpIGFuaW1hdGlvbiBiZXR3ZWVuXG4gICAgICogb25lIHN0YXRlIGFuZCBhbm90aGVyIGFzIHRoZSByZXN1bHQgb2YgZWl0aGVyIHVzZXIgaW50ZXJhY3Rpb25cbiAgICAgKiBvciBtZXRob2RzIHN1Y2ggYXMge0BsaW5rIE1hcCNmbHlUb30uXG4gICAgICpcbiAgICAgKiBAZXZlbnQgcGl0Y2hcbiAgICAgKiBAbWVtYmVyb2YgTWFwXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHR5cGUge01hcERhdGFFdmVudH1cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEluaXRpYWxpemUgdGhlIG1hcFxuICAgICAqIGNvbnN0IG1hcCA9IG5ldyBtYXBib3hnbC5NYXAoe30pO1xuICAgICAqIC8vIFNldCBhbiBldmVudCBsaXN0ZW5lciB0aGF0IGZpcmVzXG4gICAgICogLy8gcmVwZWF0ZWRseSBkdXJpbmcgYSBwaXRjaCAodGlsdCkgdHJhbnNpdGlvbi5cbiAgICAgKiBtYXAub24oJ3BpdGNoJywgKCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnQSBwaXRjaCBldmVudCBvY2N1cnJlZC4nKTtcbiAgICAgKiB9KTtcbiAgICAgKi9cbiAgICB8ICdwaXRjaCdcblxuICAgIC8qKlxuICAgICAqIEZpcmVkIGltbWVkaWF0ZWx5IGFmdGVyIHRoZSBtYXAncyBwaXRjaCAodGlsdCkgZmluaXNoZXMgY2hhbmdpbmcgYXNcbiAgICAgKiB0aGUgcmVzdWx0IG9mIGVpdGhlciB1c2VyIGludGVyYWN0aW9uIG9yIG1ldGhvZHMgc3VjaCBhcyB7QGxpbmsgTWFwI2ZseVRvfS5cbiAgICAgKlxuICAgICAqIEBldmVudCBwaXRjaGVuZFxuICAgICAqIEBtZW1iZXJvZiBNYXBcbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAdHlwZSB7TWFwRGF0YUV2ZW50fVxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gSW5pdGlhbGl6ZSB0aGUgbWFwXG4gICAgICogY29uc3QgbWFwID0gbmV3IG1hcGJveGdsLk1hcCh7fSk7XG4gICAgICogLy8gU2V0IGFuIGV2ZW50IGxpc3RlbmVyIHRoYXQgZmlyZXNcbiAgICAgKiAvLyBqdXN0IGFmdGVyIGEgcGl0Y2ggKHRpbHQpIHRyYW5zaXRpb24gZW5kcy5cbiAgICAgKiBtYXAub24oJ3BpdGNoZW5kJywgKCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnQSBwaXRjaGVuZCBldmVudCBvY2N1cnJlZC4nKTtcbiAgICAgKiB9KTtcbiAgICAgKi9cbiAgICB8ICdwaXRjaGVuZCdcblxuICAgIC8qKlxuICAgICAqIEZpcmVkIHdoZW4gYSBcImJveCB6b29tXCIgaW50ZXJhY3Rpb24gc3RhcnRzLiBTZWUge0BsaW5rIEJveFpvb21IYW5kbGVyfS5cbiAgICAgKlxuICAgICAqIEBldmVudCBib3h6b29tc3RhcnRcbiAgICAgKiBAbWVtYmVyb2YgTWFwXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHR5cGUge01hcEJveFpvb21FdmVudH1cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEluaXRpYWxpemUgdGhlIG1hcFxuICAgICAqIGNvbnN0IG1hcCA9IG5ldyBtYXBib3hnbC5NYXAoe30pO1xuICAgICAqIC8vIFNldCBhbiBldmVudCBsaXN0ZW5lciB0aGF0IGZpcmVzXG4gICAgICogLy8ganVzdCBiZWZvcmUgYSBcImJveCB6b29tXCIgaW50ZXJhY3Rpb24gc3RhcnRzLlxuICAgICAqIG1hcC5vbignYm94em9vbXN0YXJ0JywgKCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnQSBib3h6b29tc3RhcnQgZXZlbnQgb2NjdXJyZWQuJyk7XG4gICAgICogfSk7XG4gICAgICovXG4gICAgfCAnYm94em9vbXN0YXJ0J1xuXG4gICAgLyoqXG4gICAgICogRmlyZWQgd2hlbiBhIFwiYm94IHpvb21cIiBpbnRlcmFjdGlvbiBlbmRzLiAgU2VlIHtAbGluayBCb3hab29tSGFuZGxlcn0uXG4gICAgICpcbiAgICAgKiBAZXZlbnQgYm94em9vbWVuZFxuICAgICAqIEBtZW1iZXJvZiBNYXBcbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgICAqIEB0eXBlIHtNYXBCb3hab29tRXZlbnR9XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBJbml0aWFsaXplIHRoZSBtYXBcbiAgICAgKiBjb25zdCBtYXAgPSBuZXcgbWFwYm94Z2wuTWFwKHt9KTtcbiAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBmaXJlc1xuICAgICAqIC8vIGp1c3QgYWZ0ZXIgYSBcImJveCB6b29tXCIgaW50ZXJhY3Rpb24gZW5kcy5cbiAgICAgKiBtYXAub24oJ2JveHpvb21lbmQnLCAoKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdBIGJveHpvb21lbmQgZXZlbnQgb2NjdXJyZWQuJyk7XG4gICAgICogfSk7XG4gICAgICovXG4gICAgfCAnYm94em9vbWVuZCdcblxuICAgIC8qKlxuICAgICAqIEZpcmVkIHdoZW4gdGhlIHVzZXIgY2FuY2VscyBhIFwiYm94IHpvb21cIiBpbnRlcmFjdGlvbiwgb3Igd2hlbiB0aGUgYm91bmRpbmcgYm94IGRvZXMgbm90IG1lZXQgdGhlIG1pbmltdW0gc2l6ZSB0aHJlc2hvbGQuXG4gICAgICogU2VlIHtAbGluayBCb3hab29tSGFuZGxlcn0uXG4gICAgICpcbiAgICAgKiBAZXZlbnQgYm94em9vbWNhbmNlbFxuICAgICAqIEBtZW1iZXJvZiBNYXBcbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAdHlwZSB7TWFwQm94Wm9vbUV2ZW50fVxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gSW5pdGlhbGl6ZSB0aGUgbWFwXG4gICAgICogY29uc3QgbWFwID0gbmV3IG1hcGJveGdsLk1hcCh7fSk7XG4gICAgICogLy8gU2V0IGFuIGV2ZW50IGxpc3RlbmVyIHRoYXQgZmlyZXNcbiAgICAgKiAvLyB0aGUgdXNlciBjYW5jZWxzIGEgXCJib3ggem9vbVwiIGludGVyYWN0aW9uLlxuICAgICAqIG1hcC5vbignYm94em9vbWNhbmNlbCcsICgpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ0EgYm94em9vbWNhbmNlbCBldmVudCBvY2N1cnJlZC4nKTtcbiAgICAgKiB9KTtcbiAgICAgKi9cbiAgICB8ICdib3h6b29tY2FuY2VsJ1xuXG4gICAgLyoqXG4gICAgICogRmlyZWQgaW1tZWRpYXRlbHkgYWZ0ZXIgdGhlIG1hcCBoYXMgYmVlbiByZXNpemVkLlxuICAgICAqXG4gICAgICogQGV2ZW50IHJlc2l6ZVxuICAgICAqIEBtZW1iZXJvZiBNYXBcbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEluaXRpYWxpemUgdGhlIG1hcFxuICAgICAqIGNvbnN0IG1hcCA9IG5ldyBtYXBib3hnbC5NYXAoe30pO1xuICAgICAqIC8vIFNldCBhbiBldmVudCBsaXN0ZW5lciB0aGF0IGZpcmVzXG4gICAgICogLy8gaW1tZWRpYXRlbHkgYWZ0ZXIgdGhlIG1hcCBoYXMgYmVlbiByZXNpemVkLlxuICAgICAqIG1hcC5vbigncmVzaXplJywgKCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnQSByZXNpemUgZXZlbnQgb2NjdXJyZWQuJyk7XG4gICAgICogfSk7XG4gICAgICovXG4gICAgfCAncmVzaXplJ1xuXG4gICAgLyoqIEBzZWN0aW9uIHtMaWZlY3ljbGV9XG4gICAgICogQGV2ZW50XG4gICAgICogQGluc3RhbmNlXG4gICAgICogQG1lbWJlcm9mIE1hcCAqL1xuXG4gICAgLyoqXG4gICAgICogRmlyZWQgaW1tZWRpYXRlbHkgYWZ0ZXIgYWxsIG5lY2Vzc2FyeSByZXNvdXJjZXMgaGF2ZSBiZWVuIGRvd25sb2FkZWRcbiAgICAgKiBhbmQgdGhlIGZpcnN0IHZpc3VhbGx5IGNvbXBsZXRlIHJlbmRlcmluZyBvZiB0aGUgbWFwIGhhcyBvY2N1cnJlZC5cbiAgICAgKlxuICAgICAqIEBldmVudCBsb2FkXG4gICAgICogQG1lbWJlcm9mIE1hcFxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEB0eXBlIHtPYmplY3R9XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBJbml0aWFsaXplIHRoZSBtYXBcbiAgICAgKiBjb25zdCBtYXAgPSBuZXcgbWFwYm94Z2wuTWFwKHt9KTtcbiAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBmaXJlc1xuICAgICAqIC8vIHdoZW4gdGhlIG1hcCBoYXMgZmluaXNoZWQgbG9hZGluZy5cbiAgICAgKiBtYXAub24oJ2xvYWQnLCAoKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdBIGxvYWQgZXZlbnQgb2NjdXJyZWQuJyk7XG4gICAgICogfSk7XG4gICAgICogQHNlZSBbRXhhbXBsZTogRHJhdyBHZW9KU09OIHBvaW50c10oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9nZW9qc29uLW1hcmtlcnMvKVxuICAgICAqIEBzZWUgW0V4YW1wbGU6IEFkZCBsaXZlIHJlYWx0aW1lIGRhdGFdKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvbGl2ZS1nZW9qc29uLylcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBBbmltYXRlIGEgcG9pbnRdKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvYW5pbWF0ZS1wb2ludC1hbG9uZy1saW5lLylcbiAgICAgKi9cbiAgICB8ICdsb2FkJ1xuXG4gICAgLyoqXG4gICAgICogRmlyZWQgd2hlbmV2ZXIgdGhlIG1hcCBpcyBkcmF3biB0byB0aGUgc2NyZWVuLCBhcyB0aGUgcmVzdWx0IG9mOlxuICAgICAqXG4gICAgICogLSBhIGNoYW5nZSB0byB0aGUgbWFwJ3MgcG9zaXRpb24sIHpvb20sIHBpdGNoLCBvciBiZWFyaW5nXG4gICAgICogLSBhIGNoYW5nZSB0byB0aGUgbWFwJ3Mgc3R5bGVcbiAgICAgKiAtIGEgY2hhbmdlIHRvIGEgR2VvSlNPTiBzb3VyY2VcbiAgICAgKiAtIHRoZSBsb2FkaW5nIG9mIGEgdmVjdG9yIHRpbGUsIEdlb0pTT04gZmlsZSwgZ2x5cGgsIG9yIHNwcml0ZS5cbiAgICAgKlxuICAgICAqIEBldmVudCByZW5kZXJcbiAgICAgKiBAbWVtYmVyb2YgTWFwXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBJbml0aWFsaXplIHRoZSBtYXBcbiAgICAgKiBjb25zdCBtYXAgPSBuZXcgbWFwYm94Z2wuTWFwKHt9KTtcbiAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBmaXJlc1xuICAgICAqIC8vIHdoZW5ldmVyIHRoZSBtYXAgaXMgZHJhd24gdG8gdGhlIHNjcmVlbi5cbiAgICAgKiBtYXAub24oJ3JlbmRlcicsICgpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ0EgcmVuZGVyIGV2ZW50IG9jY3VycmVkLicpO1xuICAgICAqIH0pO1xuICAgICAqL1xuICAgIHwgJ3JlbmRlcidcblxuICAgIC8qKlxuICAgICAqIEZpcmVkIGFmdGVyIHRoZSBsYXN0IGZyYW1lIHJlbmRlcmVkIGJlZm9yZSB0aGUgbWFwIGVudGVycyBhblxuICAgICAqIFwiaWRsZVwiIHN0YXRlOlxuICAgICAqXG4gICAgICogLSBObyBjYW1lcmEgdHJhbnNpdGlvbnMgYXJlIGluIHByb2dyZXNzXG4gICAgICogLSBBbGwgY3VycmVudGx5IHJlcXVlc3RlZCB0aWxlcyBoYXZlIGxvYWRlZFxuICAgICAqIC0gQWxsIGZhZGUvdHJhbnNpdGlvbiBhbmltYXRpb25zIGhhdmUgY29tcGxldGVkLlxuICAgICAqXG4gICAgICogQGV2ZW50IGlkbGVcbiAgICAgKiBAbWVtYmVyb2YgTWFwXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBJbml0aWFsaXplIHRoZSBtYXBcbiAgICAgKiBjb25zdCBtYXAgPSBuZXcgbWFwYm94Z2wuTWFwKHt9KTtcbiAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBmaXJlc1xuICAgICAqIC8vIGp1c3QgYmVmb3JlIHRoZSBtYXAgZW50ZXJzIGFuIFwiaWRsZVwiIHN0YXRlLlxuICAgICAqIG1hcC5vbignaWRsZScsICgpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ0EgaWRsZSBldmVudCBvY2N1cnJlZC4nKTtcbiAgICAgKiB9KTtcbiAgICAgKi9cbiAgICB8ICdpZGxlJ1xuXG4gICAgLyoqXG4gICAgICogRmlyZWQgaW1tZWRpYXRlbHkgYWZ0ZXIgdGhlIG1hcCBoYXMgYmVlbiByZW1vdmVkIHdpdGgge0BsaW5rIE1hcC5ldmVudDpyZW1vdmV9LlxuICAgICAqXG4gICAgICogQGV2ZW50IHJlbW92ZVxuICAgICAqIEBtZW1iZXJvZiBNYXBcbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEluaXRpYWxpemUgdGhlIG1hcFxuICAgICAqIGNvbnN0IG1hcCA9IG5ldyBtYXBib3hnbC5NYXAoe30pO1xuICAgICAqIC8vIFNldCBhbiBldmVudCBsaXN0ZW5lciB0aGF0IGZpcmVzXG4gICAgICogLy8ganVzdCBhZnRlciB0aGUgbWFwIGlzIHJlbW92ZWQuXG4gICAgICogbWFwLm9uKCdyZW1vdmUnLCAoKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdBIHJlbW92ZSBldmVudCBvY2N1cnJlZC4nKTtcbiAgICAgKiB9KTtcbiAgICAgKi9cbiAgICB8ICdyZW1vdmUnXG5cbiAgICAvKipcbiAgICAgKiBGaXJlZCB3aGVuIGFuIGVycm9yIG9jY3Vycy4gVGhpcyBpcyBNYXBib3ggR0wgSlMncyBwcmltYXJ5IGVycm9yIHJlcG9ydGluZ1xuICAgICAqIG1lY2hhbmlzbS4gV2UgdXNlIGFuIGV2ZW50IGluc3RlYWQgb2YgYHRocm93YCB0byBiZXR0ZXIgYWNjb21tb2RhdGVcbiAgICAgKiBhc3luY3Jvbm91cyBvcGVyYXRpb25zLiBJZiBubyBsaXN0ZW5lcnMgYXJlIGJvdW5kIHRvIHRoZSBgZXJyb3JgIGV2ZW50LCB0aGVcbiAgICAgKiBlcnJvciB3aWxsIGJlIHByaW50ZWQgdG8gdGhlIGNvbnNvbGUuXG4gICAgICpcbiAgICAgKiBAZXZlbnQgZXJyb3JcbiAgICAgKiBAbWVtYmVyb2YgTWFwXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IG1lc3NhZ2UgRXJyb3IgbWVzc2FnZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEluaXRpYWxpemUgdGhlIG1hcFxuICAgICAqIGNvbnN0IG1hcCA9IG5ldyBtYXBib3hnbC5NYXAoe30pO1xuICAgICAqIC8vIFNldCBhbiBldmVudCBsaXN0ZW5lciB0aGF0IGZpcmVzXG4gICAgICogLy8gd2hlbiBhbiBlcnJvciBvY2N1cnMuXG4gICAgICogbWFwLm9uKCdlcnJvcicsICgpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ0EgZXJyb3IgZXZlbnQgb2NjdXJyZWQuJyk7XG4gICAgICogfSk7XG4gICAgICovXG4gICAgfCAnZXJyb3InXG5cbiAgICAvKipcbiAgICAgKiBGaXJlZCB3aGVuIHRoZSBXZWJHTCBjb250ZXh0IGlzIGxvc3QuXG4gICAgICpcbiAgICAgKiBAZXZlbnQgd2ViZ2xjb250ZXh0bG9zdFxuICAgICAqIEBtZW1iZXJvZiBNYXBcbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEluaXRpYWxpemUgdGhlIG1hcFxuICAgICAqIGNvbnN0IG1hcCA9IG5ldyBtYXBib3hnbC5NYXAoe30pO1xuICAgICAqIC8vIFNldCBhbiBldmVudCBsaXN0ZW5lciB0aGF0IGZpcmVzXG4gICAgICogLy8gd2hlbiB0aGUgV2ViR0wgY29udGV4dCBpcyBsb3N0LlxuICAgICAqIG1hcC5vbignd2ViZ2xjb250ZXh0bG9zdCcsICgpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ0Egd2ViZ2xjb250ZXh0bG9zdCBldmVudCBvY2N1cnJlZC4nKTtcbiAgICAgKiB9KTtcbiAgICAgKi9cbiAgICB8ICd3ZWJnbGNvbnRleHRsb3N0J1xuXG4gICAgLyoqXG4gICAgICogRmlyZWQgd2hlbiB0aGUgV2ViR0wgY29udGV4dCBpcyByZXN0b3JlZC5cbiAgICAgKlxuICAgICAqIEBldmVudCB3ZWJnbGNvbnRleHRyZXN0b3JlZFxuICAgICAqIEBtZW1iZXJvZiBNYXBcbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEluaXRpYWxpemUgdGhlIG1hcFxuICAgICAqIGNvbnN0IG1hcCA9IG5ldyBtYXBib3hnbC5NYXAoe30pO1xuICAgICAqIC8vIFNldCBhbiBldmVudCBsaXN0ZW5lciB0aGF0IGZpcmVzXG4gICAgICogLy8gd2hlbiB0aGUgV2ViR0wgY29udGV4dCBpcyByZXN0b3JlZC5cbiAgICAgKiBtYXAub24oJ3dlYmdsY29udGV4dHJlc3RvcmVkJywgKCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnQSB3ZWJnbGNvbnRleHRyZXN0b3JlZCBldmVudCBvY2N1cnJlZC4nKTtcbiAgICAgKiB9KTtcbiAgICAgKi9cbiAgICB8ICd3ZWJnbGNvbnRleHRyZXN0b3JlZCdcblxuICAgIC8qKiBAc2VjdGlvbiB7RGF0YSBsb2FkaW5nfVxuICAgICAqIEBldmVudFxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEBtZW1iZXJvZiBNYXAgKi9cblxuICAgIC8qKlxuICAgICAqIEZpcmVkIHdoZW4gYW55IG1hcCBkYXRhIGxvYWRzIG9yIGNoYW5nZXMuIFNlZSB7QGxpbmsgTWFwRGF0YUV2ZW50fVxuICAgICAqIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICAgICAqXG4gICAgICogQGV2ZW50IGRhdGFcbiAgICAgKiBAbWVtYmVyb2YgTWFwXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHR5cGUge01hcERhdGFFdmVudH1cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEluaXRpYWxpemUgdGhlIG1hcFxuICAgICAqIGNvbnN0IG1hcCA9IG5ldyBtYXBib3hnbC5NYXAoe30pO1xuICAgICAqIC8vIFNldCBhbiBldmVudCBsaXN0ZW5lciB0aGF0IGZpcmVzXG4gICAgICogLy8gd2hlbiBtYXAgZGF0YSBsb2FkcyBvciBjaGFuZ2VzLlxuICAgICAqIG1hcC5vbignZGF0YScsICgpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ0EgZGF0YSBldmVudCBvY2N1cnJlZC4nKTtcbiAgICAgKiB9KTtcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBEaXNwbGF5IEhUTUwgY2x1c3RlcnMgd2l0aCBjdXN0b20gcHJvcGVydGllc10oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvY2x1c3Rlci1odG1sLylcbiAgICAgKi9cbiAgICB8ICdkYXRhJ1xuXG4gICAgLyoqXG4gICAgICogRmlyZWQgd2hlbiB0aGUgbWFwJ3Mgc3R5bGUgbG9hZHMgb3IgY2hhbmdlcy4gU2VlXG4gICAgICoge0BsaW5rIE1hcERhdGFFdmVudH0gZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gICAgICpcbiAgICAgKiBAZXZlbnQgc3R5bGVkYXRhXG4gICAgICogQG1lbWJlcm9mIE1hcFxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEB0eXBlIHtNYXBEYXRhRXZlbnR9XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBJbml0aWFsaXplIHRoZSBtYXBcbiAgICAgKiBjb25zdCBtYXAgPSBuZXcgbWFwYm94Z2wuTWFwKHt9KTtcbiAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBmaXJlc1xuICAgICAqIC8vIHdoZW4gdGhlIG1hcCdzIHN0eWxlIGxvYWRzIG9yIGNoYW5nZXMuXG4gICAgICogbWFwLm9uKCdzdHlsZWRhdGEnLCAoKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdBIHN0eWxlZGF0YSBldmVudCBvY2N1cnJlZC4nKTtcbiAgICAgKiB9KTtcbiAgICAgKi9cbiAgICB8ICdzdHlsZWRhdGEnXG5cbiAgICAvKipcbiAgICAgKiBGaXJlZCB3aGVuIG9uZSBvZiB0aGUgbWFwJ3Mgc291cmNlcyBsb2FkcyBvciBjaGFuZ2VzLCBpbmNsdWRpbmcgaWYgYSB0aWxlIGJlbG9uZ2luZ1xuICAgICAqIHRvIGEgc291cmNlIGxvYWRzIG9yIGNoYW5nZXMuIFNlZSB7QGxpbmsgTWFwRGF0YUV2ZW50fSBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiAgICAgKlxuICAgICAqIEBldmVudCBzb3VyY2VkYXRhXG4gICAgICogQG1lbWJlcm9mIE1hcFxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEB0eXBlIHtNYXBEYXRhRXZlbnR9XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBJbml0aWFsaXplIHRoZSBtYXBcbiAgICAgKiBjb25zdCBtYXAgPSBuZXcgbWFwYm94Z2wuTWFwKHt9KTtcbiAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBmaXJlc1xuICAgICAqIC8vIHdoZW4gb25lIG9mIHRoZSBtYXAncyBzb3VyY2VzIGxvYWRzIG9yIGNoYW5nZXMuXG4gICAgICogbWFwLm9uKCdzb3VyY2VkYXRhJywgKCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnQSBzb3VyY2VkYXRhIGV2ZW50IG9jY3VycmVkLicpO1xuICAgICAqIH0pO1xuICAgICAqL1xuICAgIHwgJ3NvdXJjZWRhdGEnXG5cbiAgICAvKipcbiAgICAgKiBGaXJlZCB3aGVuIGFueSBtYXAgZGF0YSAoc3R5bGUsIHNvdXJjZSwgdGlsZSwgZXRjKSBiZWdpbnMgbG9hZGluZyBvclxuICAgICAqIGNoYW5naW5nIGFzeW5jaHJvbm91c2x5LiBBbGwgYGRhdGFsb2FkaW5nYCBldmVudHMgYXJlIGZvbGxvd2VkIGJ5IGEgYGRhdGFgXG4gICAgICogb3IgYGVycm9yYCBldmVudC4gU2VlIHtAbGluayBNYXBEYXRhRXZlbnR9IGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICAgICAqXG4gICAgICogQGV2ZW50IGRhdGFsb2FkaW5nXG4gICAgICogQG1lbWJlcm9mIE1hcFxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEB0eXBlIHtNYXBEYXRhRXZlbnR9XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBJbml0aWFsaXplIHRoZSBtYXBcbiAgICAgKiBjb25zdCBtYXAgPSBuZXcgbWFwYm94Z2wuTWFwKHt9KTtcbiAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBmaXJlc1xuICAgICAqIC8vIHdoZW4gYW55IG1hcCBkYXRhIGJlZ2lucyBsb2FkaW5nXG4gICAgICogLy8gb3IgY2hhbmdpbmcgYXN5bmNocm9ub3VzbHkuXG4gICAgICogbWFwLm9uKCdkYXRhbG9hZGluZycsICgpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ0EgZGF0YWxvYWRpbmcgZXZlbnQgb2NjdXJyZWQuJyk7XG4gICAgICogfSk7XG4gICAgICovXG4gICAgfCAnZGF0YWxvYWRpbmcnXG5cbiAgICAvKipcbiAgICAgKiBGaXJlZCB3aGVuIHRoZSBtYXAncyBzdHlsZSBiZWdpbnMgbG9hZGluZyBvciBjaGFuZ2luZyBhc3luY2hyb25vdXNseS5cbiAgICAgKiBBbGwgYHN0eWxlZGF0YWxvYWRpbmdgIGV2ZW50cyBhcmUgZm9sbG93ZWQgYnkgYSBgc3R5bGVkYXRhYFxuICAgICAqIG9yIGBlcnJvcmAgZXZlbnQuIFNlZSB7QGxpbmsgTWFwRGF0YUV2ZW50fSBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiAgICAgKlxuICAgICAqIEBldmVudCBzdHlsZWRhdGFsb2FkaW5nXG4gICAgICogQG1lbWJlcm9mIE1hcFxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEB0eXBlIHtNYXBEYXRhRXZlbnR9XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBJbml0aWFsaXplIHRoZSBtYXBcbiAgICAgKiBjb25zdCBtYXAgPSBuZXcgbWFwYm94Z2wuTWFwKHt9KTtcbiAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBmaXJlc1xuICAgICAqIC8vIHdoZW4gdGhlIG1hcCdzIHN0eWxlIGJlZ2lucyBsb2FkaW5nIG9yXG4gICAgICogLy8gY2hhbmdpbmcgYXN5bmNocm9ub3VzbHkuXG4gICAgICogbWFwLm9uKCdzdHlsZWRhdGFsb2FkaW5nJywgKCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnQSBzdHlsZWRhdGFsb2FkaW5nIGV2ZW50IG9jY3VycmVkLicpO1xuICAgICAqIH0pO1xuICAgICAqL1xuICAgIHwgJ3N0eWxlZGF0YWxvYWRpbmcnXG5cbiAgICAvKipcbiAgICAgKiBGaXJlZCB3aGVuIG9uZSBvZiB0aGUgbWFwJ3Mgc291cmNlcyBiZWdpbnMgbG9hZGluZyBvciBjaGFuZ2luZyBhc3luY2hyb25vdXNseS5cbiAgICAgKiBBbGwgYHNvdXJjZWRhdGFsb2FkaW5nYCBldmVudHMgYXJlIGZvbGxvd2VkIGJ5IGEgYHNvdXJjZWRhdGFgIG9yIGBlcnJvcmAgZXZlbnQuXG4gICAgICogU2VlIHtAbGluayBNYXBEYXRhRXZlbnR9IGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICAgICAqXG4gICAgICogQGV2ZW50IHNvdXJjZWRhdGFsb2FkaW5nXG4gICAgICogQG1lbWJlcm9mIE1hcFxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEB0eXBlIHtNYXBEYXRhRXZlbnR9XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBJbml0aWFsaXplIHRoZSBtYXBcbiAgICAgKiBjb25zdCBtYXAgPSBuZXcgbWFwYm94Z2wuTWFwKHt9KTtcbiAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBmaXJlc1xuICAgICAqIC8vIHdoZW4gdGhlIG1hcCdzIHNvdXJjZXMgYmVnaW4gbG9hZGluZyBvclxuICAgICAqIC8vIGNoYW5naW5nIGFzeW5jaHJvbm91c2x5LlxuICAgICAqIG1hcC5vbignc291cmNlZGF0YWxvYWRpbmcnLCAoKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdBIHNvdXJjZWRhdGFsb2FkaW5nIGV2ZW50IG9jY3VycmVkLicpO1xuICAgICAqIH0pO1xuICAgICAqL1xuICAgIHwgJ3NvdXJjZWRhdGFsb2FkaW5nJ1xuXG4gICAgLyoqXG4gICAgICogRmlyZWQgd2hlbiBhbiBpY29uIG9yIHBhdHRlcm4gbmVlZGVkIGJ5IHRoZSBzdHlsZSBpcyBtaXNzaW5nLiBUaGUgbWlzc2luZyBpbWFnZSBjYW5cbiAgICAgKiBiZSBhZGRlZCB3aXRoIHtAbGluayBNYXAjYWRkSW1hZ2V9IHdpdGhpbiB0aGlzIGV2ZW50IGxpc3RlbmVyIGNhbGxiYWNrIHRvIHByZXZlbnQgdGhlIGltYWdlIGZyb21cbiAgICAgKiBiZWluZyBza2lwcGVkLiBUaGlzIGV2ZW50IGNhbiBiZSB1c2VkIHRvIGR5bmFtaWNhbGx5IGdlbmVyYXRlIGljb25zIGFuZCBwYXR0ZXJucy5cbiAgICAgKlxuICAgICAqIEBldmVudCBzdHlsZWltYWdlbWlzc2luZ1xuICAgICAqIEBtZW1iZXJvZiBNYXBcbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gaWQgVGhlIGlkIG9mIHRoZSBtaXNzaW5nIGltYWdlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gSW5pdGlhbGl6ZSB0aGUgbWFwXG4gICAgICogY29uc3QgbWFwID0gbmV3IG1hcGJveGdsLk1hcCh7fSk7XG4gICAgICogLy8gU2V0IGFuIGV2ZW50IGxpc3RlbmVyIHRoYXQgZmlyZXNcbiAgICAgKiAvLyB3aGVuIGFuIGljb24gb3IgcGF0dGVybiBpcyBtaXNzaW5nLlxuICAgICAqIG1hcC5vbignc3R5bGVpbWFnZW1pc3NpbmcnLCAoKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdBIHN0eWxlaW1hZ2VtaXNzaW5nIGV2ZW50IG9jY3VycmVkLicpO1xuICAgICAqIH0pO1xuICAgICAqIEBzZWUgW0V4YW1wbGU6IEdlbmVyYXRlIGFuZCBhZGQgYSBtaXNzaW5nIGljb24gdG8gdGhlIG1hcF0oaHR0cHM6Ly9tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2FkZC1pbWFnZS1taXNzaW5nLWdlbmVyYXRlZC8pXG4gICAgICovXG4gICAgfCAnc3R5bGVpbWFnZW1pc3NpbmcnXG5cbiAgICAvKipcbiAgICAgKiBGaXJlZCBpbW1lZGlhdGVseSBhZnRlciBhbGwgc3R5bGUgcmVzb3VyY2VzIGhhdmUgYmVlbiBkb3dubG9hZGVkXG4gICAgICogYW5kIHRoZSBmaXJzdCB2aXN1YWxseSBjb21wbGV0ZSByZW5kZXJpbmcgb2YgdGhlIGJhc2Ugc3R5bGUgaGFzIG9jY3VycmVkLlxuICAgICAqXG4gICAgICogQGV2ZW50IHN0eWxlLmxvYWRcbiAgICAgKiBAbWVtYmVyb2YgTWFwXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBJbml0aWFsaXplIHRoZSBtYXBcbiAgICAgKiBjb25zdCBtYXAgPSBuZXcgbWFwYm94Z2wuTWFwKHt9KTtcbiAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBmaXJlc1xuICAgICAqIC8vIHdoZW4gdGhlIG1hcCBoYXMgZmluaXNoZWQgbG9hZGluZy5cbiAgICAgKiBtYXAub24oJ3N0eWxlLmxvYWQnLCAoKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdBIHN0eWxlIGxvYWQgZXZlbnQgb2NjdXJyZWQuJyk7XG4gICAgICogfSk7XG4gICAgICogQHNlZSBbRXhhbXBsZTogUGVyc2lzdCBsYXllcnMgd2hlbiBzd2l0Y2hpbmcgYmFzZSBzdHlsZV0oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9zdHlsZS1zd2l0Y2gpXG4gICAgICovXG4gICAgfCAnc3R5bGUubG9hZCdcblxuICAgIC8qKlxuICAgICAqIEZpcmVkIGFmdGVyIHNwZWVkIGluZGV4IGNhbGN1bGF0aW9uIGlzIGNvbXBsZXRlZCBpZiBgc3BlZWRJbmRleFRpbWluZ2Agb3B0aW9uIGhhcyBiZWVuIHNldCB0byBgdHJ1ZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBldmVudCBzcGVlZGluZGV4Y29tcGxldGVkXG4gICAgICogQG1lbWJlcm9mIE1hcFxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gSW5pdGlhbGl6ZSB0aGUgbWFwXG4gICAgICogdmFyIG1hcCA9IG5ldyBtYXBib3hnbC5NYXAoe30pO1xuICAgICAqIG1hcC5zcGVlZEluZGV4VGltaW5nID0gdHJ1ZTtcbiAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBmaXJlc1xuICAgICAqIC8vIGFmdGVyIHNwZWVkIGluZGV4IGNhbGN1bGF0aW9uIGlzIGNvbXBsZXRlZC5cbiAgICAgKiBtYXAub24oJ3NwZWVkaW5kZXhjb21wbGV0ZWQnLCBmdW5jdGlvbigpIHtcbiAgICAgKiAgIGNvbnNvbGUubG9nKGBzcGVlZCBpbmRleCBpcyAke21hcC5zcGVlZEluZGV4TnVtYmVyfWApO1xuICAgICAqIH0pO1xuICAgICAqL1xuICAgIHwgJ3NwZWVkaW5kZXhjb21wbGV0ZWQnXG5cbiAgICAvKipcbiAgICAgKiBGaXJlZCBhZnRlciBSVEwgdGV4dCBwbHVnaW4gc3RhdGUgY2hhbmdlcy5cbiAgICAgKlxuICAgICAqIEBldmVudCBwbHVnaW5TdGF0ZUNoYW5nZVxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgfCAncGx1Z2luU3RhdGVDaGFuZ2UnXG5cbiAgICAvKipcbiAgICAgKiBGaXJlZCBpbiB3b3JrZXIuanMgYWZ0ZXIgc3ByaXRlIGxvYWRlZC5cbiAgICAgKlxuICAgICAqIEBldmVudCBwbHVnaW5TdGF0ZUNoYW5nZVxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgfCAnaXNTcHJpdGVMb2FkZWQnXG5cbiAgICAvKipcbiAgICAgKiBGaXJlZCBpbiBzdHlsZS5qcyBhZnRlciBsYXllciBvcmRlciBjaGFuZ2VkLlxuICAgICAqXG4gICAgICogQGV2ZW50IHBsdWdpblN0YXRlQ2hhbmdlXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICB8ICduZXdvcmRlcidcbjtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCB7ZXh0ZW5kfSBmcm9tICcuLi8uLi91dGlsL3V0aWwuanMnO1xuaW1wb3J0IHtNYXBNb3VzZUV2ZW50LCBNYXBUb3VjaEV2ZW50LCBNYXBXaGVlbEV2ZW50fSBmcm9tICcuLi9ldmVudHMuanMnO1xuXG5pbXBvcnQgdHlwZSBNYXAgZnJvbSAnLi4vbWFwLmpzJztcbmltcG9ydCB0eXBlIFBvaW50IGZyb20gJ0BtYXBib3gvcG9pbnQtZ2VvbWV0cnknO1xuaW1wb3J0IHR5cGUge0hhbmRsZXJSZXN1bHR9IGZyb20gJy4uL2hhbmRsZXJfbWFuYWdlci5qcyc7XG5cbmV4cG9ydCBjbGFzcyBNYXBFdmVudEhhbmRsZXIge1xuXG4gICAgX21vdXNlZG93blBvczogP1BvaW50O1xuICAgIF9jbGlja1RvbGVyYW5jZTogbnVtYmVyO1xuICAgIF9tYXA6IE1hcDtcblxuICAgIGNvbnN0cnVjdG9yKG1hcDogTWFwLCBvcHRpb25zOiB7IGNsaWNrVG9sZXJhbmNlOiBudW1iZXIgfSkge1xuICAgICAgICB0aGlzLl9tYXAgPSBtYXA7XG4gICAgICAgIHRoaXMuX2NsaWNrVG9sZXJhbmNlID0gb3B0aW9ucy5jbGlja1RvbGVyYW5jZTtcbiAgICB9XG5cbiAgICByZXNldCgpIHtcbiAgICAgICAgdGhpcy5fbW91c2Vkb3duUG9zID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHdoZWVsKGU6IFdoZWVsRXZlbnQpOiA/SGFuZGxlclJlc3VsdCB7XG4gICAgICAgIC8vIElmIG1hcEV2ZW50LnByZXZlbnREZWZhdWx0KCkgaXMgY2FsbGVkIGJ5IHRoZSB1c2VyLCBwcmV2ZW50IGhhbmRsZXJzIHN1Y2ggYXM6XG4gICAgICAgIC8vIC0gU2Nyb2xsWm9vbVxuICAgICAgICByZXR1cm4gdGhpcy5fZmlyZVByZXZlbnRhYmxlKG5ldyBNYXBXaGVlbEV2ZW50KGUudHlwZSwgdGhpcy5fbWFwLCBlKSk7XG4gICAgfVxuXG4gICAgbW91c2Vkb3duKGU6IE1vdXNlRXZlbnQsIHBvaW50OiBQb2ludCk6ID9IYW5kbGVyUmVzdWx0IHtcbiAgICAgICAgdGhpcy5fbW91c2Vkb3duUG9zID0gcG9pbnQ7XG4gICAgICAgIC8vIElmIG1hcEV2ZW50LnByZXZlbnREZWZhdWx0KCkgaXMgY2FsbGVkIGJ5IHRoZSB1c2VyLCBwcmV2ZW50IGhhbmRsZXJzIHN1Y2ggYXM6XG4gICAgICAgIC8vIC0gTW91c2VQYW5cbiAgICAgICAgLy8gLSBNb3VzZVJvdGF0ZVxuICAgICAgICAvLyAtIE1vdXNlUGl0Y2hcbiAgICAgICAgLy8gLSBEYmxjbGlja0hhbmRsZXJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZpcmVQcmV2ZW50YWJsZShuZXcgTWFwTW91c2VFdmVudChlLnR5cGUsIHRoaXMuX21hcCwgZSkpO1xuICAgIH1cblxuICAgIG1vdXNldXAoZTogTW91c2VFdmVudCkge1xuICAgICAgICB0aGlzLl9tYXAuZmlyZShuZXcgTWFwTW91c2VFdmVudChlLnR5cGUsIHRoaXMuX21hcCwgZSkpO1xuICAgIH1cblxuICAgIHByZWNsaWNrKGU6IE1vdXNlRXZlbnQpIHtcbiAgICAgICAgY29uc3Qgc3ludGggPSBleHRlbmQoe30sIGUpO1xuICAgICAgICBzeW50aC50eXBlID0gJ3ByZWNsaWNrJztcbiAgICAgICAgdGhpcy5fbWFwLmZpcmUobmV3IE1hcE1vdXNlRXZlbnQoc3ludGgudHlwZSwgdGhpcy5fbWFwLCBzeW50aCkpO1xuICAgIH1cblxuICAgIGNsaWNrKGU6IE1vdXNlRXZlbnQsIHBvaW50OiBQb2ludCkge1xuICAgICAgICBpZiAodGhpcy5fbW91c2Vkb3duUG9zICYmIHRoaXMuX21vdXNlZG93blBvcy5kaXN0KHBvaW50KSA+PSB0aGlzLl9jbGlja1RvbGVyYW5jZSkgcmV0dXJuO1xuICAgICAgICB0aGlzLnByZWNsaWNrKGUpO1xuICAgICAgICB0aGlzLl9tYXAuZmlyZShuZXcgTWFwTW91c2VFdmVudChlLnR5cGUsIHRoaXMuX21hcCwgZSkpO1xuICAgIH1cblxuICAgIGRibGNsaWNrKGU6IE1vdXNlRXZlbnQpOiA/SGFuZGxlclJlc3VsdCB7XG4gICAgICAgIC8vIElmIG1hcEV2ZW50LnByZXZlbnREZWZhdWx0KCkgaXMgY2FsbGVkIGJ5IHRoZSB1c2VyLCBwcmV2ZW50IGhhbmRsZXJzIHN1Y2ggYXM6XG4gICAgICAgIC8vIC0gRGJsQ2xpY2tab29tXG4gICAgICAgIHJldHVybiB0aGlzLl9maXJlUHJldmVudGFibGUobmV3IE1hcE1vdXNlRXZlbnQoZS50eXBlLCB0aGlzLl9tYXAsIGUpKTtcbiAgICB9XG5cbiAgICBtb3VzZW92ZXIoZTogTW91c2VFdmVudCkge1xuICAgICAgICB0aGlzLl9tYXAuZmlyZShuZXcgTWFwTW91c2VFdmVudChlLnR5cGUsIHRoaXMuX21hcCwgZSkpO1xuICAgIH1cblxuICAgIG1vdXNlb3V0KGU6IE1vdXNlRXZlbnQpIHtcbiAgICAgICAgdGhpcy5fbWFwLmZpcmUobmV3IE1hcE1vdXNlRXZlbnQoZS50eXBlLCB0aGlzLl9tYXAsIGUpKTtcbiAgICB9XG5cbiAgICB0b3VjaHN0YXJ0KGU6IFRvdWNoRXZlbnQpOiA/SGFuZGxlclJlc3VsdCB7XG4gICAgICAgIC8vIElmIG1hcEV2ZW50LnByZXZlbnREZWZhdWx0KCkgaXMgY2FsbGVkIGJ5IHRoZSB1c2VyLCBwcmV2ZW50IGhhbmRsZXJzIHN1Y2ggYXM6XG4gICAgICAgIC8vIC0gVG91Y2hQYW5cbiAgICAgICAgLy8gLSBUb3VjaFpvb21cbiAgICAgICAgLy8gLSBUb3VjaFJvdGF0ZVxuICAgICAgICAvLyAtIFRvdWNoUGl0Y2hcbiAgICAgICAgLy8gLSBUYXBab29tXG4gICAgICAgIC8vIC0gU3dpcGVab29tXG4gICAgICAgIHJldHVybiB0aGlzLl9maXJlUHJldmVudGFibGUobmV3IE1hcFRvdWNoRXZlbnQoZS50eXBlLCB0aGlzLl9tYXAsIGUpKTtcbiAgICB9XG5cbiAgICB0b3VjaG1vdmUoZTogVG91Y2hFdmVudCkge1xuICAgICAgICB0aGlzLl9tYXAuZmlyZShuZXcgTWFwVG91Y2hFdmVudChlLnR5cGUsIHRoaXMuX21hcCwgZSkpO1xuICAgIH1cblxuICAgIHRvdWNoZW5kKGU6IFRvdWNoRXZlbnQpIHtcbiAgICAgICAgdGhpcy5fbWFwLmZpcmUobmV3IE1hcFRvdWNoRXZlbnQoZS50eXBlLCB0aGlzLl9tYXAsIGUpKTtcbiAgICB9XG5cbiAgICB0b3VjaGNhbmNlbChlOiBUb3VjaEV2ZW50KSB7XG4gICAgICAgIHRoaXMuX21hcC5maXJlKG5ldyBNYXBUb3VjaEV2ZW50KGUudHlwZSwgdGhpcy5fbWFwLCBlKSk7XG4gICAgfVxuXG4gICAgX2ZpcmVQcmV2ZW50YWJsZShtYXBFdmVudDogTWFwTW91c2VFdmVudCB8IE1hcFRvdWNoRXZlbnQgfCBNYXBXaGVlbEV2ZW50KTogP0hhbmRsZXJSZXN1bHQge1xuICAgICAgICB0aGlzLl9tYXAuZmlyZShtYXBFdmVudCk7XG4gICAgICAgIGlmIChtYXBFdmVudC5kZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICAgICAgICAvLyByZXR1cm5pbmcgYW4gb2JqZWN0IG1hcmtzIHRoZSBoYW5kbGVyIGFzIGFjdGl2ZSBhbmQgcmVzZXRzIG90aGVyIGhhbmRsZXJzXG4gICAgICAgICAgICByZXR1cm4ge307XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpc0VuYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlzQWN0aXZlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGVuYWJsZSgpIHt9XG4gICAgZGlzYWJsZSgpIHt9XG59XG5cbmV4cG9ydCBjbGFzcyBCbG9ja2FibGVNYXBFdmVudEhhbmRsZXIge1xuICAgIF9tYXA6IE1hcDtcbiAgICBfZGVsYXlDb250ZXh0TWVudTogYm9vbGVhbjtcbiAgICBfY29udGV4dE1lbnVFdmVudDogP01vdXNlRXZlbnQ7XG5cbiAgICBjb25zdHJ1Y3RvcihtYXA6IE1hcCkge1xuICAgICAgICB0aGlzLl9tYXAgPSBtYXA7XG4gICAgfVxuXG4gICAgcmVzZXQoKSB7XG4gICAgICAgIHRoaXMuX2RlbGF5Q29udGV4dE1lbnUgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fY29udGV4dE1lbnVFdmVudCA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBtb3VzZW1vdmUoZTogTW91c2VFdmVudCkge1xuICAgICAgICAvLyBtb3VzZW1vdmUgbWFwIGV2ZW50cyBzaG91bGQgbm90IGJlIGZpcmVkIHdoZW4gaW50ZXJhY3Rpb24gaGFuZGxlcnMgKHBhbiwgcm90YXRlLCBldGMpIGFyZSBhY3RpdmVcbiAgICAgICAgdGhpcy5fbWFwLmZpcmUobmV3IE1hcE1vdXNlRXZlbnQoZS50eXBlLCB0aGlzLl9tYXAsIGUpKTtcbiAgICB9XG5cbiAgICBtb3VzZWRvd24oKSB7XG4gICAgICAgIHRoaXMuX2RlbGF5Q29udGV4dE1lbnUgPSB0cnVlO1xuICAgIH1cblxuICAgIG1vdXNldXAoKSB7XG4gICAgICAgIHRoaXMuX2RlbGF5Q29udGV4dE1lbnUgPSBmYWxzZTtcbiAgICAgICAgaWYgKHRoaXMuX2NvbnRleHRNZW51RXZlbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX21hcC5maXJlKG5ldyBNYXBNb3VzZUV2ZW50KCdjb250ZXh0bWVudScsIHRoaXMuX21hcCwgdGhpcy5fY29udGV4dE1lbnVFdmVudCkpO1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuX2NvbnRleHRNZW51RXZlbnQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29udGV4dG1lbnUoZTogTW91c2VFdmVudCkge1xuICAgICAgICBpZiAodGhpcy5fZGVsYXlDb250ZXh0TWVudSkge1xuICAgICAgICAgICAgLy8gTWFjOiBjb250ZXh0bWVudSBmaXJlZCBvbiBtb3VzZWRvd247IHdlIHNhdmUgaXQgdW50aWwgbW91c2V1cCBmb3IgY29uc2lzdGVuY3kncyBzYWtlXG4gICAgICAgICAgICB0aGlzLl9jb250ZXh0TWVudUV2ZW50ID0gZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFdpbmRvd3M6IGNvbnRleHRtZW51IGZpcmVkIG9uIG1vdXNldXAsIHNvIGZpcmUgZXZlbnQgbm93XG4gICAgICAgICAgICB0aGlzLl9tYXAuZmlyZShuZXcgTWFwTW91c2VFdmVudChlLnR5cGUsIHRoaXMuX21hcCwgZSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcHJldmVudCBicm93c2VyIGNvbnRleHQgbWVudSB3aGVuIG5lY2Vzc2FyeVxuICAgICAgICBpZiAodGhpcy5fbWFwLmxpc3RlbnMoJ2NvbnRleHRtZW51JykpIHtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlzRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaXNBY3RpdmUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZW5hYmxlKCkge31cbiAgICBkaXNhYmxlKCkge31cbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCAqIGFzIERPTSBmcm9tICcuLi8uLi91dGlsL2RvbS5qcyc7XG5cbmltcG9ydCB7RXZlbnR9IGZyb20gJy4uLy4uL3V0aWwvZXZlbnRlZC5qcyc7XG5cbmltcG9ydCB0eXBlIE1hcCBmcm9tICcuLi9tYXAuanMnO1xuaW1wb3J0IHR5cGUgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5pbXBvcnQgdHlwZSB7SGFuZGxlclJlc3VsdH0gZnJvbSAnLi4vaGFuZGxlcl9tYW5hZ2VyLmpzJztcblxuLyoqXG4gKiBUaGUgYEJveFpvb21IYW5kbGVyYCBhbGxvd3MgdGhlIHVzZXIgdG8gem9vbSB0aGUgbWFwIHRvIGZpdCB3aXRoaW4gYSBib3VuZGluZyBib3guXG4gKiBUaGUgYm91bmRpbmcgYm94IGlzIGRlZmluZWQgYnkgY2xpY2tpbmcgYW5kIGhvbGRpbmcgYHNoaWZ0YCB3aGlsZSBkcmFnZ2luZyB0aGUgY3Vyc29yLlxuICpcbiAqIEBzZWUgW0V4YW1wbGU6IFRvZ2dsZSBpbnRlcmFjdGlvbnNdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL3RvZ2dsZS1pbnRlcmFjdGlvbi1oYW5kbGVycy8pXG4gKiBAc2VlIFtFeGFtcGxlOiBIaWdobGlnaHQgZmVhdHVyZXMgd2l0aGluIGEgYm91bmRpbmcgYm94XShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS91c2luZy1ib3gtcXVlcnlyZW5kZXJlZGZlYXR1cmVzLylcbiAqL1xuY2xhc3MgQm94Wm9vbUhhbmRsZXIge1xuICAgIF9tYXA6IE1hcDtcbiAgICBfZWw6IEhUTUxFbGVtZW50O1xuICAgIF9jb250YWluZXI6IEhUTUxFbGVtZW50O1xuICAgIF9lbmFibGVkOiBib29sZWFuO1xuICAgIF9hY3RpdmU6IGJvb2xlYW47XG4gICAgX3N0YXJ0UG9zOiA/UG9pbnQ7XG4gICAgX2xhc3RQb3M6ID9Qb2ludDtcbiAgICBfYm94OiBIVE1MRWxlbWVudDtcbiAgICBfY2xpY2tUb2xlcmFuY2U6IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgY29uc3RydWN0b3IobWFwOiBNYXAsIG9wdGlvbnM6IHtcbiAgICAgICAgY2xpY2tUb2xlcmFuY2U6IG51bWJlclxuICAgIH0pIHtcbiAgICAgICAgdGhpcy5fbWFwID0gbWFwO1xuICAgICAgICB0aGlzLl9lbCA9IG1hcC5nZXRDYW52YXNDb250YWluZXIoKTtcbiAgICAgICAgdGhpcy5fY29udGFpbmVyID0gbWFwLmdldENvbnRhaW5lcigpO1xuICAgICAgICB0aGlzLl9jbGlja1RvbGVyYW5jZSA9IG9wdGlvbnMuY2xpY2tUb2xlcmFuY2UgfHwgMTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgQm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIFwiYm94IHpvb21cIiBpbnRlcmFjdGlvbiBpcyBlbmFibGVkLlxuICAgICAqXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBcImJveCB6b29tXCIgaW50ZXJhY3Rpb24gaXMgZW5hYmxlZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGlzQm94Wm9vbUVuYWJsZWQgPSBtYXAuYm94Wm9vbS5pc0VuYWJsZWQoKTtcbiAgICAgKi9cbiAgICBpc0VuYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX2VuYWJsZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIEJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIHRoZSBcImJveCB6b29tXCIgaW50ZXJhY3Rpb24gaXMgYWN0aXZlIChjdXJyZW50bHkgYmVpbmcgdXNlZCkuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIFwiYm94IHpvb21cIiBpbnRlcmFjdGlvbiBpcyBhY3RpdmUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBpc0JveFpvb21BY3RpdmUgPSBtYXAuYm94Wm9vbS5pc0FjdGl2ZSgpO1xuICAgICAqL1xuICAgIGlzQWN0aXZlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9hY3RpdmU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRW5hYmxlcyB0aGUgXCJib3ggem9vbVwiIGludGVyYWN0aW9uLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAuYm94Wm9vbS5lbmFibGUoKTtcbiAgICAgKi9cbiAgICBlbmFibGUoKSB7XG4gICAgICAgIGlmICh0aGlzLmlzRW5hYmxlZCgpKSByZXR1cm47XG4gICAgICAgIHRoaXMuX2VuYWJsZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERpc2FibGVzIHRoZSBcImJveCB6b29tXCIgaW50ZXJhY3Rpb24uXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIG1hcC5ib3hab29tLmRpc2FibGUoKTtcbiAgICAgKi9cbiAgICBkaXNhYmxlKCkge1xuICAgICAgICBpZiAoIXRoaXMuaXNFbmFibGVkKCkpIHJldHVybjtcbiAgICAgICAgdGhpcy5fZW5hYmxlZCA9IGZhbHNlO1xuICAgIH1cblxuICAgIG1vdXNlZG93bihlOiBNb3VzZUV2ZW50LCBwb2ludDogUG9pbnQpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzRW5hYmxlZCgpKSByZXR1cm47XG4gICAgICAgIGlmICghKGUuc2hpZnRLZXkgJiYgZS5idXR0b24gPT09IDApKSByZXR1cm47XG5cbiAgICAgICAgRE9NLmRpc2FibGVEcmFnKCk7XG4gICAgICAgIHRoaXMuX3N0YXJ0UG9zID0gdGhpcy5fbGFzdFBvcyA9IHBvaW50O1xuICAgICAgICB0aGlzLl9hY3RpdmUgPSB0cnVlO1xuICAgIH1cblxuICAgIG1vdXNlbW92ZVdpbmRvdyhlOiBNb3VzZUV2ZW50LCBwb2ludDogUG9pbnQpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9hY3RpdmUpIHJldHVybjtcblxuICAgICAgICBjb25zdCBwb3MgPSBwb2ludDtcbiAgICAgICAgY29uc3QgcDAgPSB0aGlzLl9zdGFydFBvcztcbiAgICAgICAgY29uc3QgcDEgPSB0aGlzLl9sYXN0UG9zO1xuXG4gICAgICAgIGlmICghcDAgfHwgIXAxIHx8IHAxLmVxdWFscyhwb3MpIHx8ICghdGhpcy5fYm94ICYmIHBvcy5kaXN0KHAwKSA8IHRoaXMuX2NsaWNrVG9sZXJhbmNlKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fbGFzdFBvcyA9IHBvcztcblxuICAgICAgICBpZiAoIXRoaXMuX2JveCkge1xuICAgICAgICAgICAgdGhpcy5fYm94ID0gRE9NLmNyZWF0ZSgnZGl2JywgJ21hcGJveGdsLWJveHpvb20nLCB0aGlzLl9jb250YWluZXIpO1xuICAgICAgICAgICAgdGhpcy5fY29udGFpbmVyLmNsYXNzTGlzdC5hZGQoJ21hcGJveGdsLWNyb3NzaGFpcicpO1xuICAgICAgICAgICAgdGhpcy5fZmlyZUV2ZW50KCdib3h6b29tc3RhcnQnLCBlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG1pblggPSBNYXRoLm1pbihwMC54LCBwb3MueCksXG4gICAgICAgICAgICBtYXhYID0gTWF0aC5tYXgocDAueCwgcG9zLngpLFxuICAgICAgICAgICAgbWluWSA9IE1hdGgubWluKHAwLnksIHBvcy55KSxcbiAgICAgICAgICAgIG1heFkgPSBNYXRoLm1heChwMC55LCBwb3MueSk7XG5cbiAgICAgICAgdGhpcy5fbWFwLl9yZXF1ZXN0RG9tVGFzaygoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5fYm94KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fYm94LnN0eWxlLnRyYW5zZm9ybSA9IGB0cmFuc2xhdGUoJHttaW5YfXB4LCR7bWluWX1weClgO1xuICAgICAgICAgICAgICAgIHRoaXMuX2JveC5zdHlsZS53aWR0aCA9IGAke21heFggLSBtaW5YfXB4YDtcbiAgICAgICAgICAgICAgICB0aGlzLl9ib3guc3R5bGUuaGVpZ2h0ID0gYCR7bWF4WSAtIG1pbll9cHhgO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBtb3VzZXVwV2luZG93KGU6IE1vdXNlRXZlbnQsIHBvaW50OiBQb2ludCk6ID9IYW5kbGVyUmVzdWx0IHtcbiAgICAgICAgaWYgKCF0aGlzLl9hY3RpdmUpIHJldHVybjtcblxuICAgICAgICBjb25zdCBwMCA9IHRoaXMuX3N0YXJ0UG9zLFxuICAgICAgICAgICAgcDEgPSBwb2ludDtcblxuICAgICAgICBpZiAoIXAwIHx8IGUuYnV0dG9uICE9PSAwKSByZXR1cm47XG5cbiAgICAgICAgdGhpcy5yZXNldCgpO1xuXG4gICAgICAgIERPTS5zdXBwcmVzc0NsaWNrKCk7XG5cbiAgICAgICAgaWYgKHAwLnggPT09IHAxLnggJiYgcDAueSA9PT0gcDEueSkge1xuICAgICAgICAgICAgdGhpcy5fZmlyZUV2ZW50KCdib3h6b29tY2FuY2VsJywgZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9tYXAuZmlyZShuZXcgRXZlbnQoJ2JveHpvb21lbmQnLCB7b3JpZ2luYWxFdmVudDogZX0pKTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgY2FtZXJhQW5pbWF0aW9uOiAobWFwOiBNYXApID0+IG1hcC5maXRTY3JlZW5Db29yZGluYXRlcyhwMCwgcDEsIHRoaXMuX21hcC5nZXRCZWFyaW5nKCksIHtsaW5lYXI6IGZhbHNlfSlcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBrZXlkb3duKGU6IEtleWJvYXJkRXZlbnQpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9hY3RpdmUpIHJldHVybjtcblxuICAgICAgICBpZiAoZS5rZXlDb2RlID09PSAyNykge1xuICAgICAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgICAgICAgICAgdGhpcy5fZmlyZUV2ZW50KCdib3h6b29tY2FuY2VsJywgZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBibHVyKCkge1xuICAgICAgICB0aGlzLnJlc2V0KCk7XG4gICAgfVxuXG4gICAgcmVzZXQoKSB7XG4gICAgICAgIHRoaXMuX2FjdGl2ZSA9IGZhbHNlO1xuXG4gICAgICAgIHRoaXMuX2NvbnRhaW5lci5jbGFzc0xpc3QucmVtb3ZlKCdtYXBib3hnbC1jcm9zc2hhaXInKTtcblxuICAgICAgICBpZiAodGhpcy5fYm94KSB7XG4gICAgICAgICAgICB0aGlzLl9ib3gucmVtb3ZlKCk7XG4gICAgICAgICAgICB0aGlzLl9ib3ggPSAobnVsbDogYW55KTtcbiAgICAgICAgfVxuXG4gICAgICAgIERPTS5lbmFibGVEcmFnKCk7XG5cbiAgICAgICAgZGVsZXRlIHRoaXMuX3N0YXJ0UG9zO1xuICAgICAgICBkZWxldGUgdGhpcy5fbGFzdFBvcztcbiAgICB9XG5cbiAgICBfZmlyZUV2ZW50KHR5cGU6IHN0cmluZywgZTogYW55KTogTWFwIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21hcC5maXJlKG5ldyBFdmVudCh0eXBlLCB7b3JpZ2luYWxFdmVudDogZX0pKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEJveFpvb21IYW5kbGVyO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuXG5pbXBvcnQgdHlwZSBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcblxuZXhwb3J0IGZ1bmN0aW9uIGluZGV4VG91Y2hlcyh0b3VjaGVzOiBBcnJheTxUb3VjaD4sIHBvaW50czogQXJyYXk8UG9pbnQ+KToge1tudW1iZXIgfCBzdHJpbmddOiBQb2ludH0ge1xuICAgIGFzc2VydCh0b3VjaGVzLmxlbmd0aCA9PT0gcG9pbnRzLmxlbmd0aCk7XG4gICAgY29uc3Qgb2JqID0ge307XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0b3VjaGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIG9ialt0b3VjaGVzW2ldLmlkZW50aWZpZXJdID0gcG9pbnRzW2ldO1xuICAgIH1cbiAgICByZXR1cm4gb2JqO1xufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IFBvaW50IGZyb20gJ0BtYXBib3gvcG9pbnQtZ2VvbWV0cnknO1xuaW1wb3J0IHtpbmRleFRvdWNoZXN9IGZyb20gJy4vaGFuZGxlcl91dGlsLmpzJztcblxuZnVuY3Rpb24gZ2V0Q2VudHJvaWQocG9pbnRzOiBBcnJheTxQb2ludD4pIHtcbiAgICBjb25zdCBzdW0gPSBuZXcgUG9pbnQoMCwgMCk7XG4gICAgZm9yIChjb25zdCBwb2ludCBvZiBwb2ludHMpIHtcbiAgICAgICAgc3VtLl9hZGQocG9pbnQpO1xuICAgIH1cbiAgICByZXR1cm4gc3VtLmRpdihwb2ludHMubGVuZ3RoKTtcbn1cblxuZXhwb3J0IGNvbnN0IE1BWF9UQVBfSU5URVJWQUwgPSA1MDA7XG5jb25zdCBNQVhfVE9VQ0hfVElNRSA9IDUwMDtcbmNvbnN0IE1BWF9ESVNUID0gMzA7XG5cbmV4cG9ydCBjbGFzcyBTaW5nbGVUYXBSZWNvZ25pemVyIHtcblxuICAgIG51bVRvdWNoZXM6IG51bWJlcjtcbiAgICBjZW50cm9pZDogP1BvaW50O1xuICAgIHN0YXJ0VGltZTogbnVtYmVyO1xuICAgIGFib3J0ZWQ6IGJvb2xlYW47XG4gICAgdG91Y2hlczogeyBbbnVtYmVyIHwgc3RyaW5nXTogUG9pbnQgfTtcblxuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnM6IHsgbnVtVG91Y2hlczogbnVtYmVyIH0pIHtcbiAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgICAgICB0aGlzLm51bVRvdWNoZXMgPSBvcHRpb25zLm51bVRvdWNoZXM7XG4gICAgfVxuXG4gICAgcmVzZXQoKSB7XG4gICAgICAgIHRoaXMuY2VudHJvaWQgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuc3RhcnRUaW1lID0gMDtcbiAgICAgICAgdGhpcy50b3VjaGVzID0ge307XG4gICAgICAgIHRoaXMuYWJvcnRlZCA9IGZhbHNlO1xuICAgIH1cblxuICAgIHRvdWNoc3RhcnQoZTogVG91Y2hFdmVudCwgcG9pbnRzOiBBcnJheTxQb2ludD4sIG1hcFRvdWNoZXM6IEFycmF5PFRvdWNoPikge1xuXG4gICAgICAgIGlmICh0aGlzLmNlbnRyb2lkIHx8IG1hcFRvdWNoZXMubGVuZ3RoID4gdGhpcy5udW1Ub3VjaGVzKSB7XG4gICAgICAgICAgICB0aGlzLmFib3J0ZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmFib3J0ZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnN0YXJ0VGltZSA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy5zdGFydFRpbWUgPSBlLnRpbWVTdGFtcDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChtYXBUb3VjaGVzLmxlbmd0aCA9PT0gdGhpcy5udW1Ub3VjaGVzKSB7XG4gICAgICAgICAgICB0aGlzLmNlbnRyb2lkID0gZ2V0Q2VudHJvaWQocG9pbnRzKTtcbiAgICAgICAgICAgIHRoaXMudG91Y2hlcyA9IGluZGV4VG91Y2hlcyhtYXBUb3VjaGVzLCBwb2ludHMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdG91Y2htb3ZlKGU6IFRvdWNoRXZlbnQsIHBvaW50czogQXJyYXk8UG9pbnQ+LCBtYXBUb3VjaGVzOiBBcnJheTxUb3VjaD4pIHtcbiAgICAgICAgaWYgKHRoaXMuYWJvcnRlZCB8fCAhdGhpcy5jZW50cm9pZCkgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IG5ld1RvdWNoZXMgPSBpbmRleFRvdWNoZXMobWFwVG91Y2hlcywgcG9pbnRzKTtcbiAgICAgICAgZm9yIChjb25zdCBpZCBpbiB0aGlzLnRvdWNoZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHByZXZQb3MgPSB0aGlzLnRvdWNoZXNbaWRdO1xuICAgICAgICAgICAgY29uc3QgcG9zID0gbmV3VG91Y2hlc1tpZF07XG4gICAgICAgICAgICBpZiAoIXBvcyB8fCBwb3MuZGlzdChwcmV2UG9zKSA+IE1BWF9ESVNUKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hYm9ydGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHRvdWNoZW5kKGU6IFRvdWNoRXZlbnQsIHBvaW50czogQXJyYXk8UG9pbnQ+LCBtYXBUb3VjaGVzOiBBcnJheTxUb3VjaD4pOiA/UG9pbnQge1xuICAgICAgICBpZiAoIXRoaXMuY2VudHJvaWQgfHwgZS50aW1lU3RhbXAgLSB0aGlzLnN0YXJ0VGltZSA+IE1BWF9UT1VDSF9USU1FKSB7XG4gICAgICAgICAgICB0aGlzLmFib3J0ZWQgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1hcFRvdWNoZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBjb25zdCBjZW50cm9pZCA9ICF0aGlzLmFib3J0ZWQgJiYgdGhpcy5jZW50cm9pZDtcbiAgICAgICAgICAgIHRoaXMucmVzZXQoKTtcbiAgICAgICAgICAgIGlmIChjZW50cm9pZCkgcmV0dXJuIGNlbnRyb2lkO1xuICAgICAgICB9XG4gICAgfVxuXG59XG5cbmV4cG9ydCBjbGFzcyBUYXBSZWNvZ25pemVyIHtcblxuICAgIHNpbmdsZVRhcDogU2luZ2xlVGFwUmVjb2duaXplcjtcbiAgICBudW1UYXBzOiBudW1iZXI7XG4gICAgbGFzdFRpbWU6IG51bWJlcjtcbiAgICBsYXN0VGFwOiA/UG9pbnQ7XG4gICAgY291bnQ6IG51bWJlcjtcblxuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnM6IHsgbnVtVGFwczogbnVtYmVyLCBudW1Ub3VjaGVzOiBudW1iZXIgfSkge1xuICAgICAgICB0aGlzLnNpbmdsZVRhcCA9IG5ldyBTaW5nbGVUYXBSZWNvZ25pemVyKG9wdGlvbnMpO1xuICAgICAgICB0aGlzLm51bVRhcHMgPSBvcHRpb25zLm51bVRhcHM7XG4gICAgICAgIHRoaXMucmVzZXQoKTtcbiAgICB9XG5cbiAgICByZXNldCgpIHtcbiAgICAgICAgdGhpcy5sYXN0VGltZSA9IEluZmluaXR5O1xuICAgICAgICB0aGlzLmxhc3RUYXAgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuY291bnQgPSAwO1xuICAgICAgICB0aGlzLnNpbmdsZVRhcC5yZXNldCgpO1xuICAgIH1cblxuICAgIHRvdWNoc3RhcnQoZTogVG91Y2hFdmVudCwgcG9pbnRzOiBBcnJheTxQb2ludD4sIG1hcFRvdWNoZXM6IEFycmF5PFRvdWNoPikge1xuICAgICAgICB0aGlzLnNpbmdsZVRhcC50b3VjaHN0YXJ0KGUsIHBvaW50cywgbWFwVG91Y2hlcyk7XG4gICAgfVxuXG4gICAgdG91Y2htb3ZlKGU6IFRvdWNoRXZlbnQsIHBvaW50czogQXJyYXk8UG9pbnQ+LCBtYXBUb3VjaGVzOiBBcnJheTxUb3VjaD4pIHtcbiAgICAgICAgdGhpcy5zaW5nbGVUYXAudG91Y2htb3ZlKGUsIHBvaW50cywgbWFwVG91Y2hlcyk7XG4gICAgfVxuXG4gICAgdG91Y2hlbmQoZTogVG91Y2hFdmVudCwgcG9pbnRzOiBBcnJheTxQb2ludD4sIG1hcFRvdWNoZXM6IEFycmF5PFRvdWNoPik6ID9Qb2ludCB7XG4gICAgICAgIGNvbnN0IHRhcCA9IHRoaXMuc2luZ2xlVGFwLnRvdWNoZW5kKGUsIHBvaW50cywgbWFwVG91Y2hlcyk7XG4gICAgICAgIGlmICh0YXApIHtcbiAgICAgICAgICAgIGNvbnN0IHNvb25Fbm91Z2ggPSBlLnRpbWVTdGFtcCAtIHRoaXMubGFzdFRpbWUgPCBNQVhfVEFQX0lOVEVSVkFMO1xuICAgICAgICAgICAgY29uc3QgY2xvc2VFbm91Z2ggPSAhdGhpcy5sYXN0VGFwIHx8IHRoaXMubGFzdFRhcC5kaXN0KHRhcCkgPCBNQVhfRElTVDtcblxuICAgICAgICAgICAgaWYgKCFzb29uRW5vdWdoIHx8ICFjbG9zZUVub3VnaCkge1xuICAgICAgICAgICAgICAgIHRoaXMucmVzZXQoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5jb3VudCsrO1xuICAgICAgICAgICAgdGhpcy5sYXN0VGltZSA9IGUudGltZVN0YW1wO1xuICAgICAgICAgICAgdGhpcy5sYXN0VGFwID0gdGFwO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5jb3VudCA9PT0gdGhpcy5udW1UYXBzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0YXA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge1RhcFJlY29nbml6ZXJ9IGZyb20gJy4vdGFwX3JlY29nbml6ZXIuanMnO1xuaW1wb3J0IHR5cGUgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5pbXBvcnQgdHlwZSBNYXAgZnJvbSAnLi4vbWFwLmpzJztcbmltcG9ydCB0eXBlIHtIYW5kbGVyUmVzdWx0fSBmcm9tICcuLi9oYW5kbGVyX21hbmFnZXIuanMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUYXBab29tSGFuZGxlciB7XG5cbiAgICBfZW5hYmxlZDogYm9vbGVhbjtcbiAgICBfYWN0aXZlOiBib29sZWFuO1xuICAgIF96b29tSW46IFRhcFJlY29nbml6ZXI7XG4gICAgX3pvb21PdXQ6IFRhcFJlY29nbml6ZXI7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5fem9vbUluID0gbmV3IFRhcFJlY29nbml6ZXIoe1xuICAgICAgICAgICAgbnVtVG91Y2hlczogMSxcbiAgICAgICAgICAgIG51bVRhcHM6IDJcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5fem9vbU91dCA9IG5ldyBUYXBSZWNvZ25pemVyKHtcbiAgICAgICAgICAgIG51bVRvdWNoZXM6IDIsXG4gICAgICAgICAgICBudW1UYXBzOiAxXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMucmVzZXQoKTtcbiAgICB9XG5cbiAgICByZXNldCgpIHtcbiAgICAgICAgdGhpcy5fYWN0aXZlID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX3pvb21Jbi5yZXNldCgpO1xuICAgICAgICB0aGlzLl96b29tT3V0LnJlc2V0KCk7XG4gICAgfVxuXG4gICAgdG91Y2hzdGFydChlOiBUb3VjaEV2ZW50LCBwb2ludHM6IEFycmF5PFBvaW50PiwgbWFwVG91Y2hlczogQXJyYXk8VG91Y2g+KSB7XG4gICAgICAgIHRoaXMuX3pvb21Jbi50b3VjaHN0YXJ0KGUsIHBvaW50cywgbWFwVG91Y2hlcyk7XG4gICAgICAgIHRoaXMuX3pvb21PdXQudG91Y2hzdGFydChlLCBwb2ludHMsIG1hcFRvdWNoZXMpO1xuICAgIH1cblxuICAgIHRvdWNobW92ZShlOiBUb3VjaEV2ZW50LCBwb2ludHM6IEFycmF5PFBvaW50PiwgbWFwVG91Y2hlczogQXJyYXk8VG91Y2g+KSB7XG4gICAgICAgIHRoaXMuX3pvb21Jbi50b3VjaG1vdmUoZSwgcG9pbnRzLCBtYXBUb3VjaGVzKTtcbiAgICAgICAgdGhpcy5fem9vbU91dC50b3VjaG1vdmUoZSwgcG9pbnRzLCBtYXBUb3VjaGVzKTtcbiAgICB9XG5cbiAgICB0b3VjaGVuZChlOiBUb3VjaEV2ZW50LCBwb2ludHM6IEFycmF5PFBvaW50PiwgbWFwVG91Y2hlczogQXJyYXk8VG91Y2g+KTogP0hhbmRsZXJSZXN1bHQge1xuICAgICAgICBjb25zdCB6b29tSW5Qb2ludCA9IHRoaXMuX3pvb21Jbi50b3VjaGVuZChlLCBwb2ludHMsIG1hcFRvdWNoZXMpO1xuICAgICAgICBjb25zdCB6b29tT3V0UG9pbnQgPSB0aGlzLl96b29tT3V0LnRvdWNoZW5kKGUsIHBvaW50cywgbWFwVG91Y2hlcyk7XG5cbiAgICAgICAgaWYgKHpvb21JblBvaW50KSB7XG4gICAgICAgICAgICB0aGlzLl9hY3RpdmUgPSB0cnVlO1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLnJlc2V0KCksIDApO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBjYW1lcmFBbmltYXRpb246IChtYXA6IE1hcCkgPT4gbWFwLmVhc2VUbyh7XG4gICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uOiAzMDAsXG4gICAgICAgICAgICAgICAgICAgIHpvb206IG1hcC5nZXRab29tKCkgKyAxLFxuICAgICAgICAgICAgICAgICAgICBhcm91bmQ6IG1hcC51bnByb2plY3Qoem9vbUluUG9pbnQpXG4gICAgICAgICAgICAgICAgfSwge29yaWdpbmFsRXZlbnQ6IGV9KVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIGlmICh6b29tT3V0UG9pbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX2FjdGl2ZSA9IHRydWU7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMucmVzZXQoKSwgMCk7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGNhbWVyYUFuaW1hdGlvbjogKG1hcDogTWFwKSA9PiBtYXAuZWFzZVRvKHtcbiAgICAgICAgICAgICAgICAgICAgZHVyYXRpb246IDMwMCxcbiAgICAgICAgICAgICAgICAgICAgem9vbTogbWFwLmdldFpvb20oKSAtIDEsXG4gICAgICAgICAgICAgICAgICAgIGFyb3VuZDogbWFwLnVucHJvamVjdCh6b29tT3V0UG9pbnQpXG4gICAgICAgICAgICAgICAgfSwge29yaWdpbmFsRXZlbnQ6IGV9KVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHRvdWNoY2FuY2VsKCkge1xuICAgICAgICB0aGlzLnJlc2V0KCk7XG4gICAgfVxuXG4gICAgZW5hYmxlKCkge1xuICAgICAgICB0aGlzLl9lbmFibGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBkaXNhYmxlKCkge1xuICAgICAgICB0aGlzLl9lbmFibGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMucmVzZXQoKTtcbiAgICB9XG5cbiAgICBpc0VuYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbmFibGVkO1xuICAgIH1cblxuICAgIGlzQWN0aXZlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWN0aXZlO1xuICAgIH1cbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCAqIGFzIERPTSBmcm9tICcuLi8uLi91dGlsL2RvbS5qcyc7XG5pbXBvcnQgdHlwZSBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCB0eXBlIHtIYW5kbGVyUmVzdWx0fSBmcm9tICcuLi9oYW5kbGVyX21hbmFnZXIuanMnO1xuXG5jb25zdCBMRUZUX0JVVFRPTiA9IDA7XG5jb25zdCBSSUdIVF9CVVRUT04gPSAyO1xuXG4vLyB0aGUgdmFsdWVzIGZvciBlYWNoIGJ1dHRvbiBpbiBNb3VzZUV2ZW50LmJ1dHRvbnNcbmNvbnN0IEJVVFRPTlNfRkxBR1MgPSB7XG4gICAgW0xFRlRfQlVUVE9OXTogMSxcbiAgICBbUklHSFRfQlVUVE9OXTogMlxufTtcblxuZnVuY3Rpb24gYnV0dG9uU3RpbGxQcmVzc2VkKGU6IE1vdXNlRXZlbnQsIGJ1dHRvbjogbnVtYmVyKSB7XG4gICAgY29uc3QgZmxhZyA9IEJVVFRPTlNfRkxBR1NbYnV0dG9uXTtcbiAgICByZXR1cm4gZS5idXR0b25zID09PSB1bmRlZmluZWQgfHwgKGUuYnV0dG9ucyAmIGZsYWcpICE9PSBmbGFnO1xufVxuXG5jbGFzcyBNb3VzZUhhbmRsZXIge1xuXG4gICAgX2VuYWJsZWQ6IGJvb2xlYW47XG4gICAgX2FjdGl2ZTogYm9vbGVhbjtcbiAgICBfbGFzdFBvaW50OiA/UG9pbnQ7XG4gICAgX2V2ZW50QnV0dG9uOiA/bnVtYmVyO1xuICAgIF9tb3ZlZDogYm9vbGVhbjtcbiAgICBfY2xpY2tUb2xlcmFuY2U6IG51bWJlcjtcblxuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnM6IHsgY2xpY2tUb2xlcmFuY2U6IG51bWJlciB9KSB7XG4gICAgICAgIHRoaXMucmVzZXQoKTtcbiAgICAgICAgdGhpcy5fY2xpY2tUb2xlcmFuY2UgPSBvcHRpb25zLmNsaWNrVG9sZXJhbmNlIHx8IDE7XG4gICAgfVxuXG4gICAgYmx1cigpIHtcbiAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgIH1cblxuICAgIHJlc2V0KCkge1xuICAgICAgICB0aGlzLl9hY3RpdmUgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fbW92ZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fbGFzdFBvaW50ID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl9ldmVudEJ1dHRvbiA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBfY29ycmVjdEJ1dHRvbihlOiBNb3VzZUV2ZW50LCBidXR0b246IG51bWJlcik6IGJvb2xlYW4geyAgLy9lc2xpbnQtZGlzYWJsZS1saW5lXG4gICAgICAgIHJldHVybiBmYWxzZTsgLy8gaW1wbGVtZW50ZWQgYnkgY2hpbGRcbiAgICB9XG5cbiAgICBfbW92ZShsYXN0UG9pbnQ6IFBvaW50LCBwb2ludDogUG9pbnQpOiA/SGFuZGxlclJlc3VsdCB7ICAvL2VzbGludC1kaXNhYmxlLWxpbmVcbiAgICAgICAgcmV0dXJuIHt9OyAvLyBpbXBsZW1lbnRlZCBieSBjaGlsZFxuICAgIH1cblxuICAgIG1vdXNlZG93bihlOiBNb3VzZUV2ZW50LCBwb2ludDogUG9pbnQpIHtcbiAgICAgICAgaWYgKHRoaXMuX2xhc3RQb2ludCkgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IGV2ZW50QnV0dG9uID0gRE9NLm1vdXNlQnV0dG9uKGUpO1xuICAgICAgICBpZiAoIXRoaXMuX2NvcnJlY3RCdXR0b24oZSwgZXZlbnRCdXR0b24pKSByZXR1cm47XG5cbiAgICAgICAgdGhpcy5fbGFzdFBvaW50ID0gcG9pbnQ7XG4gICAgICAgIHRoaXMuX2V2ZW50QnV0dG9uID0gZXZlbnRCdXR0b247XG4gICAgfVxuXG4gICAgbW91c2Vtb3ZlV2luZG93KGU6IE1vdXNlRXZlbnQsIHBvaW50OiBQb2ludCk6ID9IYW5kbGVyUmVzdWx0IHtcbiAgICAgICAgY29uc3QgbGFzdFBvaW50ID0gdGhpcy5fbGFzdFBvaW50O1xuICAgICAgICBpZiAoIWxhc3RQb2ludCkgcmV0dXJuO1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgaWYgKHRoaXMuX2V2ZW50QnV0dG9uICE9IG51bGwgJiYgYnV0dG9uU3RpbGxQcmVzc2VkKGUsIHRoaXMuX2V2ZW50QnV0dG9uKSkge1xuICAgICAgICAgICAgLy8gU29tZSBicm93c2VycyBkb24ndCBmaXJlIGEgYG1vdXNldXBgIHdoZW4gdGhlIG1vdXNldXAgb2NjdXJzIG91dHNpZGVcbiAgICAgICAgICAgIC8vIHRoZSB3aW5kb3cgb3IgaWZyYW1lOlxuICAgICAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21hcGJveC9tYXBib3gtZ2wtanMvaXNzdWVzLzQ2MjJcbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBJZiB0aGUgYnV0dG9uIGlzIG5vIGxvbmdlciBwcmVzc2VkIGR1cmluZyB0aGlzIGBtb3VzZW1vdmVgIGl0IG1heSBoYXZlXG4gICAgICAgICAgICAvLyBiZWVuIHJlbGVhc2VkIG91dHNpZGUgb2YgdGhlIHdpbmRvdyBvciBpZnJhbWUuXG4gICAgICAgICAgICB0aGlzLnJlc2V0KCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuX21vdmVkICYmIHBvaW50LmRpc3QobGFzdFBvaW50KSA8IHRoaXMuX2NsaWNrVG9sZXJhbmNlKSByZXR1cm47XG4gICAgICAgIHRoaXMuX21vdmVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fbGFzdFBvaW50ID0gcG9pbnQ7XG5cbiAgICAgICAgLy8gaW1wbGVtZW50ZWQgYnkgY2hpbGQgY2xhc3NcbiAgICAgICAgcmV0dXJuIHRoaXMuX21vdmUobGFzdFBvaW50LCBwb2ludCk7XG4gICAgfVxuXG4gICAgbW91c2V1cFdpbmRvdyhlOiBNb3VzZUV2ZW50KSB7XG4gICAgICAgIGlmICghdGhpcy5fbGFzdFBvaW50KSByZXR1cm47XG4gICAgICAgIGNvbnN0IGV2ZW50QnV0dG9uID0gRE9NLm1vdXNlQnV0dG9uKGUpO1xuICAgICAgICBpZiAoZXZlbnRCdXR0b24gIT09IHRoaXMuX2V2ZW50QnV0dG9uKSByZXR1cm47XG4gICAgICAgIGlmICh0aGlzLl9tb3ZlZCkgRE9NLnN1cHByZXNzQ2xpY2soKTtcbiAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgIH1cblxuICAgIGVuYWJsZSgpIHtcbiAgICAgICAgdGhpcy5fZW5hYmxlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgZGlzYWJsZSgpIHtcbiAgICAgICAgdGhpcy5fZW5hYmxlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnJlc2V0KCk7XG4gICAgfVxuXG4gICAgaXNFbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5hYmxlZDtcbiAgICB9XG5cbiAgICBpc0FjdGl2ZSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FjdGl2ZTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBNb3VzZVBhbkhhbmRsZXIgZXh0ZW5kcyBNb3VzZUhhbmRsZXIge1xuXG4gICAgbW91c2Vkb3duKGU6IE1vdXNlRXZlbnQsIHBvaW50OiBQb2ludCkge1xuICAgICAgICBzdXBlci5tb3VzZWRvd24oZSwgcG9pbnQpO1xuICAgICAgICBpZiAodGhpcy5fbGFzdFBvaW50KSB0aGlzLl9hY3RpdmUgPSB0cnVlO1xuICAgIH1cbiAgICBfY29ycmVjdEJ1dHRvbihlOiBNb3VzZUV2ZW50LCBidXR0b246IG51bWJlcik6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gYnV0dG9uID09PSBMRUZUX0JVVFRPTiAmJiAhZS5jdHJsS2V5O1xuICAgIH1cblxuICAgIF9tb3ZlKGxhc3RQb2ludDogUG9pbnQsIHBvaW50OiBQb2ludCk6ID9IYW5kbGVyUmVzdWx0IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGFyb3VuZDogcG9pbnQsXG4gICAgICAgICAgICBwYW5EZWx0YTogcG9pbnQuc3ViKGxhc3RQb2ludClcbiAgICAgICAgfTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBNb3VzZVJvdGF0ZUhhbmRsZXIgZXh0ZW5kcyBNb3VzZUhhbmRsZXIge1xuICAgIF9jb3JyZWN0QnV0dG9uKGU6IE1vdXNlRXZlbnQsIGJ1dHRvbjogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAoYnV0dG9uID09PSBMRUZUX0JVVFRPTiAmJiBlLmN0cmxLZXkpIHx8IChidXR0b24gPT09IFJJR0hUX0JVVFRPTik7XG4gICAgfVxuXG4gICAgX21vdmUobGFzdFBvaW50OiBQb2ludCwgcG9pbnQ6IFBvaW50KTogP0hhbmRsZXJSZXN1bHQge1xuICAgICAgICBjb25zdCBkZWdyZWVzUGVyUGl4ZWxNb3ZlZCA9IDAuODtcbiAgICAgICAgY29uc3QgYmVhcmluZ0RlbHRhID0gKHBvaW50LnggLSBsYXN0UG9pbnQueCkgKiBkZWdyZWVzUGVyUGl4ZWxNb3ZlZDtcbiAgICAgICAgaWYgKGJlYXJpbmdEZWx0YSkge1xuICAgICAgICAgICAgdGhpcy5fYWN0aXZlID0gdHJ1ZTtcbiAgICAgICAgICAgIHJldHVybiB7YmVhcmluZ0RlbHRhfTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbnRleHRtZW51KGU6IE1vdXNlRXZlbnQpIHtcbiAgICAgICAgLy8gcHJldmVudCBicm93c2VyIGNvbnRleHQgbWVudSB3aGVuIG5lY2Vzc2FyeTsgd2UgZG9uJ3QgYWxsb3cgaXQgd2l0aCByb3RhdGlvblxuICAgICAgICAvLyBiZWNhdXNlIHdlIGNhbid0IGRpc2Nlcm4gcm90YXRpb24gZ2VzdHVyZSBzdGFydCBmcm9tIGNvbnRleHRtZW51IG9uIE1hY1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgTW91c2VQaXRjaEhhbmRsZXIgZXh0ZW5kcyBNb3VzZUhhbmRsZXIge1xuICAgIF9jb3JyZWN0QnV0dG9uKGU6IE1vdXNlRXZlbnQsIGJ1dHRvbjogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAoYnV0dG9uID09PSBMRUZUX0JVVFRPTiAmJiBlLmN0cmxLZXkpIHx8IChidXR0b24gPT09IFJJR0hUX0JVVFRPTik7XG4gICAgfVxuXG4gICAgX21vdmUobGFzdFBvaW50OiBQb2ludCwgcG9pbnQ6IFBvaW50KTogP0hhbmRsZXJSZXN1bHQge1xuICAgICAgICBjb25zdCBkZWdyZWVzUGVyUGl4ZWxNb3ZlZCA9IC0wLjU7XG4gICAgICAgIGNvbnN0IHBpdGNoRGVsdGEgPSAocG9pbnQueSAtIGxhc3RQb2ludC55KSAqIGRlZ3JlZXNQZXJQaXhlbE1vdmVkO1xuICAgICAgICBpZiAocGl0Y2hEZWx0YSkge1xuICAgICAgICAgICAgdGhpcy5fYWN0aXZlID0gdHJ1ZTtcbiAgICAgICAgICAgIHJldHVybiB7cGl0Y2hEZWx0YX07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb250ZXh0bWVudShlOiBNb3VzZUV2ZW50KSB7XG4gICAgICAgIC8vIHByZXZlbnQgYnJvd3NlciBjb250ZXh0IG1lbnUgd2hlbiBuZWNlc3Nhcnk7IHdlIGRvbid0IGFsbG93IGl0IHdpdGggcm90YXRpb25cbiAgICAgICAgLy8gYmVjYXVzZSB3ZSBjYW4ndCBkaXNjZXJuIHJvdGF0aW9uIGdlc3R1cmUgc3RhcnQgZnJvbSBjb250ZXh0bWVudSBvbiBNYWNcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCB0eXBlIE1hcCBmcm9tICcuLi9tYXAuanMnO1xuaW1wb3J0IHtpbmRleFRvdWNoZXN9IGZyb20gJy4vaGFuZGxlcl91dGlsLmpzJztcbmltcG9ydCB7YmluZEFsbCwgaXNGdWxsc2NyZWVufSBmcm9tICcuLi8uLi91dGlsL3V0aWwuanMnO1xuaW1wb3J0ICogYXMgRE9NIGZyb20gJy4uLy4uL3V0aWwvZG9tLmpzJztcbmltcG9ydCB0eXBlIHtIYW5kbGVyUmVzdWx0fSBmcm9tICcuLi9oYW5kbGVyX21hbmFnZXIuanMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUb3VjaFBhbkhhbmRsZXIge1xuXG4gICAgX21hcDogTWFwO1xuICAgIF9lbDogSFRNTEVsZW1lbnQ7XG4gICAgX2VuYWJsZWQ6IGJvb2xlYW47XG4gICAgX2FjdGl2ZTogYm9vbGVhbjtcbiAgICBfdG91Y2hlczogeyBbc3RyaW5nIHwgbnVtYmVyXTogUG9pbnQgfTtcbiAgICBfbWluVG91Y2hlczogbnVtYmVyO1xuICAgIF9jbGlja1RvbGVyYW5jZTogbnVtYmVyO1xuICAgIF9zdW06IFBvaW50O1xuICAgIF9hbGVydENvbnRhaW5lcjogSFRNTEVsZW1lbnQ7XG4gICAgX2FsZXJ0VGltZXI6IFRpbWVvdXRJRDtcblxuICAgIGNvbnN0cnVjdG9yKG1hcDogTWFwLCBvcHRpb25zOiB7IGNsaWNrVG9sZXJhbmNlOiBudW1iZXIgfSkge1xuICAgICAgICB0aGlzLl9tYXAgPSBtYXA7XG4gICAgICAgIHRoaXMuX2VsID0gbWFwLmdldENhbnZhc0NvbnRhaW5lcigpO1xuICAgICAgICB0aGlzLl9taW5Ub3VjaGVzID0gMTtcbiAgICAgICAgdGhpcy5fY2xpY2tUb2xlcmFuY2UgPSBvcHRpb25zLmNsaWNrVG9sZXJhbmNlIHx8IDE7XG4gICAgICAgIHRoaXMucmVzZXQoKTtcbiAgICAgICAgYmluZEFsbChbJ19hZGRUb3VjaFBhbkJsb2NrZXInLCAnX3Nob3dUb3VjaFBhbkJsb2NrZXJBbGVydCddLCB0aGlzKTtcbiAgICB9XG5cbiAgICByZXNldCgpIHtcbiAgICAgICAgdGhpcy5fYWN0aXZlID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX3RvdWNoZXMgPSB7fTtcbiAgICAgICAgdGhpcy5fc3VtID0gbmV3IFBvaW50KDAsIDApO1xuICAgIH1cblxuICAgIHRvdWNoc3RhcnQoZTogVG91Y2hFdmVudCwgcG9pbnRzOiBBcnJheTxQb2ludD4sIG1hcFRvdWNoZXM6IEFycmF5PFRvdWNoPik6ID9IYW5kbGVyUmVzdWx0IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhbGN1bGF0ZVRyYW5zZm9ybShlLCBwb2ludHMsIG1hcFRvdWNoZXMpO1xuICAgIH1cblxuICAgIHRvdWNobW92ZShlOiBUb3VjaEV2ZW50LCBwb2ludHM6IEFycmF5PFBvaW50PiwgbWFwVG91Y2hlczogQXJyYXk8VG91Y2g+KTogP0hhbmRsZXJSZXN1bHQge1xuICAgICAgICBpZiAoIXRoaXMuX2FjdGl2ZSB8fCBtYXBUb3VjaGVzLmxlbmd0aCA8IHRoaXMuX21pblRvdWNoZXMpIHJldHVybjtcblxuICAgICAgICAvLyBpZiBjb29wZXJhdGl2ZSBnZXN0dXJlIGhhbmRsaW5nIGlzIHNldCB0byB0cnVlLCByZXF1aXJlIHR3byBmaW5nZXJzIHRvIHRvdWNoIHBhblxuICAgICAgICBpZiAodGhpcy5fbWFwLl9jb29wZXJhdGl2ZUdlc3R1cmVzICYmICF0aGlzLl9tYXAuaXNNb3ZpbmcoKSkge1xuICAgICAgICAgICAgaWYgKG1hcFRvdWNoZXMubGVuZ3RoID09PSAxICYmICFpc0Z1bGxzY3JlZW4oKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3Nob3dUb3VjaFBhbkJsb2NrZXJBbGVydCgpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5fYWxlcnRDb250YWluZXIuc3R5bGUudmlzaWJpbGl0eSAhPT0gJ2hpZGRlbicpIHtcbiAgICAgICAgICAgICAgICAvLyBpbW1lZGlhdGVseSBoaWRlIGFsZXJ0IGlmIGl0IGlzIHZpc2libGUgd2hlbiB0d28gZmluZ2VycyBhcmUgdXNlZCB0byBwYW4uXG4gICAgICAgICAgICAgICAgdGhpcy5fYWxlcnRDb250YWluZXIuc3R5bGUudmlzaWJpbGl0eSA9ICdoaWRkZW4nO1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLl9hbGVydFRpbWVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlLmNhbmNlbGFibGUpIHtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLl9jYWxjdWxhdGVUcmFuc2Zvcm0oZSwgcG9pbnRzLCBtYXBUb3VjaGVzKTtcbiAgICB9XG5cbiAgICB0b3VjaGVuZChlOiBUb3VjaEV2ZW50LCBwb2ludHM6IEFycmF5PFBvaW50PiwgbWFwVG91Y2hlczogQXJyYXk8VG91Y2g+KSB7XG4gICAgICAgIHRoaXMuX2NhbGN1bGF0ZVRyYW5zZm9ybShlLCBwb2ludHMsIG1hcFRvdWNoZXMpO1xuXG4gICAgICAgIGlmICh0aGlzLl9hY3RpdmUgJiYgbWFwVG91Y2hlcy5sZW5ndGggPCB0aGlzLl9taW5Ub3VjaGVzKSB7XG4gICAgICAgICAgICB0aGlzLnJlc2V0KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB0b3VjaGNhbmNlbCgpIHtcbiAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgIH1cblxuICAgIF9jYWxjdWxhdGVUcmFuc2Zvcm0oZTogVG91Y2hFdmVudCwgcG9pbnRzOiBBcnJheTxQb2ludD4sIG1hcFRvdWNoZXM6IEFycmF5PFRvdWNoPik6ID9IYW5kbGVyUmVzdWx0IHtcbiAgICAgICAgaWYgKG1hcFRvdWNoZXMubGVuZ3RoID4gMCkgdGhpcy5fYWN0aXZlID0gdHJ1ZTtcblxuICAgICAgICBjb25zdCB0b3VjaGVzID0gaW5kZXhUb3VjaGVzKG1hcFRvdWNoZXMsIHBvaW50cyk7XG5cbiAgICAgICAgY29uc3QgdG91Y2hQb2ludFN1bSA9IG5ldyBQb2ludCgwLCAwKTtcbiAgICAgICAgY29uc3QgdG91Y2hEZWx0YVN1bSA9IG5ldyBQb2ludCgwLCAwKTtcbiAgICAgICAgbGV0IHRvdWNoRGVsdGFDb3VudCA9IDA7XG5cbiAgICAgICAgZm9yIChjb25zdCBpZGVudGlmaWVyIGluIHRvdWNoZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHBvaW50ID0gdG91Y2hlc1tpZGVudGlmaWVyXTtcbiAgICAgICAgICAgIGNvbnN0IHByZXZQb2ludCA9IHRoaXMuX3RvdWNoZXNbaWRlbnRpZmllcl07XG4gICAgICAgICAgICBpZiAocHJldlBvaW50KSB7XG4gICAgICAgICAgICAgICAgdG91Y2hQb2ludFN1bS5fYWRkKHBvaW50KTtcbiAgICAgICAgICAgICAgICB0b3VjaERlbHRhU3VtLl9hZGQocG9pbnQuc3ViKHByZXZQb2ludCkpO1xuICAgICAgICAgICAgICAgIHRvdWNoRGVsdGFDb3VudCsrO1xuICAgICAgICAgICAgICAgIHRvdWNoZXNbaWRlbnRpZmllcl0gPSBwb2ludDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3RvdWNoZXMgPSB0b3VjaGVzO1xuXG4gICAgICAgIGlmICh0b3VjaERlbHRhQ291bnQgPCB0aGlzLl9taW5Ub3VjaGVzIHx8ICF0b3VjaERlbHRhU3VtLm1hZygpKSByZXR1cm47XG5cbiAgICAgICAgY29uc3QgcGFuRGVsdGEgPSB0b3VjaERlbHRhU3VtLmRpdih0b3VjaERlbHRhQ291bnQpO1xuICAgICAgICB0aGlzLl9zdW0uX2FkZChwYW5EZWx0YSk7XG4gICAgICAgIGlmICh0aGlzLl9zdW0ubWFnKCkgPCB0aGlzLl9jbGlja1RvbGVyYW5jZSkgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IGFyb3VuZCA9IHRvdWNoUG9pbnRTdW0uZGl2KHRvdWNoRGVsdGFDb3VudCk7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGFyb3VuZCxcbiAgICAgICAgICAgIHBhbkRlbHRhXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZW5hYmxlKCkge1xuICAgICAgICB0aGlzLl9lbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgaWYgKHRoaXMuX21hcC5fY29vcGVyYXRpdmVHZXN0dXJlcykge1xuICAgICAgICAgICAgdGhpcy5fYWRkVG91Y2hQYW5CbG9ja2VyKCk7XG4gICAgICAgICAgICAvLyBvdmVycmlkZSB0b3VjaC1hY3Rpb24gY3NzIHByb3BlcnR5IHRvIGVuYWJsZSBzY3JvbGxpbmcgcGFnZSBvdmVyIG1hcFxuICAgICAgICAgICAgdGhpcy5fZWwuY2xhc3NMaXN0LmFkZCgnbWFwYm94Z2wtdG91Y2gtcGFuLWJsb2NrZXItb3ZlcnJpZGUnLCAnbWFwYm94Z2wtc2Nyb2xsYWJsZS1wYWdlJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBkaXNhYmxlKCkge1xuICAgICAgICB0aGlzLl9lbmFibGVkID0gZmFsc2U7XG4gICAgICAgIGlmICh0aGlzLl9tYXAuX2Nvb3BlcmF0aXZlR2VzdHVyZXMpIHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLl9hbGVydFRpbWVyKTtcbiAgICAgICAgICAgIHRoaXMuX2FsZXJ0Q29udGFpbmVyLnJlbW92ZSgpO1xuICAgICAgICAgICAgdGhpcy5fZWwuY2xhc3NMaXN0LnJlbW92ZSgnbWFwYm94Z2wtdG91Y2gtcGFuLWJsb2NrZXItb3ZlcnJpZGUnLCAnbWFwYm94Z2wtc2Nyb2xsYWJsZS1wYWdlJyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgIH1cblxuICAgIGlzRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5fZW5hYmxlZDtcbiAgICB9XG5cbiAgICBpc0FjdGl2ZSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5fYWN0aXZlO1xuICAgIH1cblxuICAgIF9hZGRUb3VjaFBhbkJsb2NrZXIoKSB7XG4gICAgICAgIGlmICh0aGlzLl9tYXAgJiYgIXRoaXMuX2FsZXJ0Q29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aGlzLl9hbGVydENvbnRhaW5lciA9IERPTS5jcmVhdGUoJ2RpdicsICdtYXBib3hnbC10b3VjaC1wYW4tYmxvY2tlcicsIHRoaXMuX21hcC5fY29udGFpbmVyKTtcblxuICAgICAgICAgICAgdGhpcy5fYWxlcnRDb250YWluZXIudGV4dENvbnRlbnQgPSB0aGlzLl9tYXAuX2dldFVJU3RyaW5nKCdUb3VjaFBhbkJsb2NrZXIuTWVzc2FnZScpO1xuXG4gICAgICAgICAgICAvLyBkeW5hbWljYWxseSBzZXQgdGhlIGZvbnQgc2l6ZSBvZiB0aGUgdG91Y2ggcGFuIGJsb2NrZXIgYWxlcnQgbWVzc2FnZVxuICAgICAgICAgICAgdGhpcy5fYWxlcnRDb250YWluZXIuc3R5bGUuZm9udFNpemUgPSBgJHtNYXRoLm1heCgxMCwgTWF0aC5taW4oMjQsIE1hdGguZmxvb3IodGhpcy5fZWwuY2xpZW50V2lkdGggKiAwLjA1KSkpfXB4YDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9zaG93VG91Y2hQYW5CbG9ja2VyQWxlcnQoKSB7XG4gICAgICAgIHRoaXMuX2FsZXJ0Q29udGFpbmVyLnN0eWxlLnZpc2liaWxpdHkgPSAndmlzaWJsZSc7XG4gICAgICAgIHRoaXMuX2FsZXJ0Q29udGFpbmVyLmNsYXNzTGlzdC5hZGQoJ21hcGJveGdsLXRvdWNoLXBhbi1ibG9ja2VyLXNob3cnKTtcbiAgICAgICAgdGhpcy5fYWxlcnRDb250YWluZXIuc2V0QXR0cmlidXRlKFwicm9sZVwiLCBcImFsZXJ0XCIpO1xuXG4gICAgICAgIGNsZWFyVGltZW91dCh0aGlzLl9hbGVydFRpbWVyKTtcblxuICAgICAgICB0aGlzLl9hbGVydFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9hbGVydENvbnRhaW5lci5jbGFzc0xpc3QucmVtb3ZlKCdtYXBib3hnbC10b3VjaC1wYW4tYmxvY2tlci1zaG93Jyk7XG4gICAgICAgICAgICB0aGlzLl9hbGVydENvbnRhaW5lci5zZXRBdHRyaWJ1dGUoXCJyb2xlXCIsIFwibnVsbFwiKTtcbiAgICAgICAgfSwgNTAwKTtcbiAgICB9XG5cbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCAqIGFzIERPTSBmcm9tICcuLi8uLi91dGlsL2RvbS5qcyc7XG5pbXBvcnQgdHlwZSBNYXAgZnJvbSAnLi4vbWFwLmpzJztcbmltcG9ydCB0eXBlIHtIYW5kbGVyUmVzdWx0fSBmcm9tICcuLi9oYW5kbGVyX21hbmFnZXIuanMnO1xuaW1wb3J0IHtpc0Z1bGxzY3JlZW59IGZyb20gJy4uLy4uL3V0aWwvdXRpbC5qcyc7XG5cbmNsYXNzIFR3b1RvdWNoSGFuZGxlciB7XG5cbiAgICBfZW5hYmxlZDogYm9vbGVhbjtcbiAgICBfYWN0aXZlOiBib29sZWFuO1xuICAgIF9maXJzdFR3b1RvdWNoZXM6ID9bbnVtYmVyLCBudW1iZXJdO1xuICAgIF92ZWN0b3I6ID9Qb2ludDtcbiAgICBfc3RhcnRWZWN0b3I6ID9Qb2ludDtcbiAgICBfYXJvdW5kQ2VudGVyOiBib29sZWFuO1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMucmVzZXQoKTtcbiAgICB9XG5cbiAgICByZXNldCgpIHtcbiAgICAgICAgdGhpcy5fYWN0aXZlID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX2ZpcnN0VHdvVG91Y2hlcyA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBfc3RhcnQocG9pbnRzOiBbUG9pbnQsIFBvaW50XSkge30gLy9lc2xpbnQtZGlzYWJsZS1saW5lXG4gICAgX21vdmUocG9pbnRzOiBbUG9pbnQsIFBvaW50XSwgcGluY2hBcm91bmQ6ID9Qb2ludCwgZTogVG91Y2hFdmVudCk6ID9IYW5kbGVyUmVzdWx0IHsgcmV0dXJuIHt9OyB9IC8vZXNsaW50LWRpc2FibGUtbGluZVxuXG4gICAgdG91Y2hzdGFydChlOiBUb3VjaEV2ZW50LCBwb2ludHM6IEFycmF5PFBvaW50PiwgbWFwVG91Y2hlczogQXJyYXk8VG91Y2g+KSB7XG4gICAgICAgIC8vY29uc29sZS5sb2coZS50YXJnZXQsIGUudGFyZ2V0VG91Y2hlcy5sZW5ndGggPyBlLnRhcmdldFRvdWNoZXNbMF0udGFyZ2V0IDogbnVsbCk7XG4gICAgICAgIC8vbG9nKCd0b3VjaHN0YXJ0JywgcG9pbnRzLCBlLnRhcmdldC5pbm5lckhUTUwsIGUudGFyZ2V0VG91Y2hlcy5sZW5ndGggPyBlLnRhcmdldFRvdWNoZXNbMF0udGFyZ2V0LmlubmVySFRNTDogdW5kZWZpbmVkKTtcbiAgICAgICAgaWYgKHRoaXMuX2ZpcnN0VHdvVG91Y2hlcyB8fCBtYXBUb3VjaGVzLmxlbmd0aCA8IDIpIHJldHVybjtcblxuICAgICAgICB0aGlzLl9maXJzdFR3b1RvdWNoZXMgPSBbXG4gICAgICAgICAgICBtYXBUb3VjaGVzWzBdLmlkZW50aWZpZXIsXG4gICAgICAgICAgICBtYXBUb3VjaGVzWzFdLmlkZW50aWZpZXJcbiAgICAgICAgXTtcblxuICAgICAgICAvLyBpbXBsZW1lbnRlZCBieSBjaGlsZCBjbGFzc2VzXG4gICAgICAgIHRoaXMuX3N0YXJ0KFtwb2ludHNbMF0sIHBvaW50c1sxXV0pO1xuICAgIH1cblxuICAgIHRvdWNobW92ZShlOiBUb3VjaEV2ZW50LCBwb2ludHM6IEFycmF5PFBvaW50PiwgbWFwVG91Y2hlczogQXJyYXk8VG91Y2g+KTogP0hhbmRsZXJSZXN1bHQge1xuICAgICAgICBjb25zdCBmaXJzdFRvdWNoZXMgPSB0aGlzLl9maXJzdFR3b1RvdWNoZXM7XG4gICAgICAgIGlmICghZmlyc3RUb3VjaGVzKSByZXR1cm47XG5cbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgIGNvbnN0IFtpZEEsIGlkQl0gPSBmaXJzdFRvdWNoZXM7XG4gICAgICAgIGNvbnN0IGEgPSBnZXRUb3VjaEJ5SWQobWFwVG91Y2hlcywgcG9pbnRzLCBpZEEpO1xuICAgICAgICBjb25zdCBiID0gZ2V0VG91Y2hCeUlkKG1hcFRvdWNoZXMsIHBvaW50cywgaWRCKTtcbiAgICAgICAgaWYgKCFhIHx8ICFiKSByZXR1cm47XG4gICAgICAgIGNvbnN0IHBpbmNoQXJvdW5kID0gdGhpcy5fYXJvdW5kQ2VudGVyID8gbnVsbCA6IGEuYWRkKGIpLmRpdigyKTtcblxuICAgICAgICAvLyBpbXBsZW1lbnRlZCBieSBjaGlsZCBjbGFzc2VzXG4gICAgICAgIHJldHVybiB0aGlzLl9tb3ZlKFthLCBiXSwgcGluY2hBcm91bmQsIGUpO1xuXG4gICAgfVxuXG4gICAgdG91Y2hlbmQoZTogVG91Y2hFdmVudCwgcG9pbnRzOiBBcnJheTxQb2ludD4sIG1hcFRvdWNoZXM6IEFycmF5PFRvdWNoPikge1xuICAgICAgICBpZiAoIXRoaXMuX2ZpcnN0VHdvVG91Y2hlcykgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IFtpZEEsIGlkQl0gPSB0aGlzLl9maXJzdFR3b1RvdWNoZXM7XG4gICAgICAgIGNvbnN0IGEgPSBnZXRUb3VjaEJ5SWQobWFwVG91Y2hlcywgcG9pbnRzLCBpZEEpO1xuICAgICAgICBjb25zdCBiID0gZ2V0VG91Y2hCeUlkKG1hcFRvdWNoZXMsIHBvaW50cywgaWRCKTtcbiAgICAgICAgaWYgKGEgJiYgYikgcmV0dXJuO1xuXG4gICAgICAgIGlmICh0aGlzLl9hY3RpdmUpIERPTS5zdXBwcmVzc0NsaWNrKCk7XG5cbiAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgIH1cblxuICAgIHRvdWNoY2FuY2VsKCkge1xuICAgICAgICB0aGlzLnJlc2V0KCk7XG4gICAgfVxuXG4gICAgZW5hYmxlKG9wdGlvbnM6ID97YXJvdW5kPzogJ2NlbnRlcid9KSB7XG4gICAgICAgIHRoaXMuX2VuYWJsZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLl9hcm91bmRDZW50ZXIgPSAhIW9wdGlvbnMgJiYgb3B0aW9ucy5hcm91bmQgPT09ICdjZW50ZXInO1xuICAgIH1cblxuICAgIGRpc2FibGUoKSB7XG4gICAgICAgIHRoaXMuX2VuYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgIH1cblxuICAgIGlzRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VuYWJsZWQ7XG4gICAgfVxuXG4gICAgaXNBY3RpdmUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hY3RpdmU7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBnZXRUb3VjaEJ5SWQobWFwVG91Y2hlczogQXJyYXk8VG91Y2g+LCBwb2ludHM6IEFycmF5PFBvaW50PiwgaWRlbnRpZmllcjogbnVtYmVyKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXBUb3VjaGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChtYXBUb3VjaGVzW2ldLmlkZW50aWZpZXIgPT09IGlkZW50aWZpZXIpIHJldHVybiBwb2ludHNbaV07XG4gICAgfVxufVxuXG4vKiBaT09NICovXG5cbmNvbnN0IFpPT01fVEhSRVNIT0xEID0gMC4xO1xuXG5mdW5jdGlvbiBnZXRab29tRGVsdGEoZGlzdGFuY2U6IG51bWJlciwgbGFzdERpc3RhbmNlOiBudW1iZXIpIHtcbiAgICByZXR1cm4gTWF0aC5sb2coZGlzdGFuY2UgLyBsYXN0RGlzdGFuY2UpIC8gTWF0aC5MTjI7XG59XG5cbmV4cG9ydCBjbGFzcyBUb3VjaFpvb21IYW5kbGVyIGV4dGVuZHMgVHdvVG91Y2hIYW5kbGVyIHtcblxuICAgIF9kaXN0YW5jZTogbnVtYmVyO1xuICAgIF9zdGFydERpc3RhbmNlOiBudW1iZXI7XG5cbiAgICByZXNldCgpIHtcbiAgICAgICAgc3VwZXIucmVzZXQoKTtcbiAgICAgICAgdGhpcy5fZGlzdGFuY2UgPSAwO1xuICAgICAgICB0aGlzLl9zdGFydERpc3RhbmNlID0gMDtcbiAgICB9XG5cbiAgICBfc3RhcnQocG9pbnRzOiBbUG9pbnQsIFBvaW50XSkge1xuICAgICAgICB0aGlzLl9zdGFydERpc3RhbmNlID0gdGhpcy5fZGlzdGFuY2UgPSBwb2ludHNbMF0uZGlzdChwb2ludHNbMV0pO1xuICAgIH1cblxuICAgIF9tb3ZlKHBvaW50czogW1BvaW50LCBQb2ludF0sIHBpbmNoQXJvdW5kOiA/UG9pbnQpOiA/SGFuZGxlclJlc3VsdCB7XG4gICAgICAgIGNvbnN0IGxhc3REaXN0YW5jZSA9IHRoaXMuX2Rpc3RhbmNlO1xuICAgICAgICB0aGlzLl9kaXN0YW5jZSA9IHBvaW50c1swXS5kaXN0KHBvaW50c1sxXSk7XG4gICAgICAgIGlmICghdGhpcy5fYWN0aXZlICYmIE1hdGguYWJzKGdldFpvb21EZWx0YSh0aGlzLl9kaXN0YW5jZSwgdGhpcy5fc3RhcnREaXN0YW5jZSkpIDwgWk9PTV9USFJFU0hPTEQpIHJldHVybjtcbiAgICAgICAgdGhpcy5fYWN0aXZlID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHpvb21EZWx0YTogZ2V0Wm9vbURlbHRhKHRoaXMuX2Rpc3RhbmNlLCBsYXN0RGlzdGFuY2UpLFxuICAgICAgICAgICAgcGluY2hBcm91bmRcbiAgICAgICAgfTtcbiAgICB9XG59XG5cbi8qIFJPVEFURSAqL1xuXG5jb25zdCBST1RBVElPTl9USFJFU0hPTEQgPSAyNTsgLy8gcGl4ZWxzIGFsb25nIGNpcmN1bWZlcmVuY2Ugb2YgdG91Y2ggY2lyY2xlXG5cbmZ1bmN0aW9uIGdldEJlYXJpbmdEZWx0YShhOiBQb2ludCwgYjogUG9pbnQpIHtcbiAgICByZXR1cm4gYS5hbmdsZVdpdGgoYikgKiAxODAgLyBNYXRoLlBJO1xufVxuXG5leHBvcnQgY2xhc3MgVG91Y2hSb3RhdGVIYW5kbGVyIGV4dGVuZHMgVHdvVG91Y2hIYW5kbGVyIHtcbiAgICBfbWluRGlhbWV0ZXI6IG51bWJlcjtcblxuICAgIHJlc2V0KCkge1xuICAgICAgICBzdXBlci5yZXNldCgpO1xuICAgICAgICB0aGlzLl9taW5EaWFtZXRlciA9IDA7XG4gICAgICAgIHRoaXMuX3N0YXJ0VmVjdG9yID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl92ZWN0b3IgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgX3N0YXJ0KHBvaW50czogW1BvaW50LCBQb2ludF0pIHtcbiAgICAgICAgdGhpcy5fc3RhcnRWZWN0b3IgPSB0aGlzLl92ZWN0b3IgPSBwb2ludHNbMF0uc3ViKHBvaW50c1sxXSk7XG4gICAgICAgIHRoaXMuX21pbkRpYW1ldGVyID0gcG9pbnRzWzBdLmRpc3QocG9pbnRzWzFdKTtcbiAgICB9XG5cbiAgICBfbW92ZShwb2ludHM6IFtQb2ludCwgUG9pbnRdLCBwaW5jaEFyb3VuZDogP1BvaW50KTogP0hhbmRsZXJSZXN1bHQge1xuICAgICAgICBjb25zdCBsYXN0VmVjdG9yID0gdGhpcy5fdmVjdG9yO1xuICAgICAgICB0aGlzLl92ZWN0b3IgPSBwb2ludHNbMF0uc3ViKHBvaW50c1sxXSk7XG5cbiAgICAgICAgaWYgKCFsYXN0VmVjdG9yIHx8ICghdGhpcy5fYWN0aXZlICYmIHRoaXMuX2lzQmVsb3dUaHJlc2hvbGQodGhpcy5fdmVjdG9yKSkpIHJldHVybjtcbiAgICAgICAgdGhpcy5fYWN0aXZlID0gdHJ1ZTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtY2FsbF0gLSBGbG93IGRvZXNuJ3QgaW5mZXIgdGhhdCB0aGlzLl92ZWN0b3JpcyBub3QgbnVsbFxuICAgICAgICAgICAgYmVhcmluZ0RlbHRhOiBnZXRCZWFyaW5nRGVsdGEodGhpcy5fdmVjdG9yLCBsYXN0VmVjdG9yKSxcbiAgICAgICAgICAgIHBpbmNoQXJvdW5kXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgX2lzQmVsb3dUaHJlc2hvbGQodmVjdG9yOiBQb2ludCk6IGJvb2xlYW4ge1xuICAgICAgICAvKlxuICAgICAgICAgKiBUaGUgdGhyZXNob2xkIGJlZm9yZSBhIHJvdGF0aW9uIGFjdHVhbGx5IGhhcHBlbnMgaXMgY29uZmlndXJlZCBpblxuICAgICAgICAgKiBwaXhlbHMgYWxvbmd0aCBjaXJjdW1mZXJlbmNlIG9mIHRoZSBjaXJjbGUgZm9ybWVkIGJ5IHRoZSB0d28gZmluZ2Vycy5cbiAgICAgICAgICogVGhpcyBtYWtlcyB0aGUgdGhyZXNob2xkIGluIGRlZ3JlZXMgbGFyZ2VyIHdoZW4gdGhlIGZpbmdlcnMgYXJlIGNsb3NlXG4gICAgICAgICAqIHRvZ2V0aGVyIGFuZCBzbWFsbGVyIHdoZW4gdGhlIGZpbmdlcnMgYXJlIGZhciBhcGFydC5cbiAgICAgICAgICpcbiAgICAgICAgICogVXNlIHRoZSBzbWFsbGVzdCBkaWFtZXRlciBmcm9tIHRoZSB3aG9sZSBnZXN0dXJlIHRvIHJlZHVjZSBzZW5zaXRpdml0eVxuICAgICAgICAgKiB3aGVuIHBpbmNoaW5nIGluIGFuZCBvdXQuXG4gICAgICAgICAqL1xuXG4gICAgICAgIHRoaXMuX21pbkRpYW1ldGVyID0gTWF0aC5taW4odGhpcy5fbWluRGlhbWV0ZXIsIHZlY3Rvci5tYWcoKSk7XG4gICAgICAgIGNvbnN0IGNpcmN1bWZlcmVuY2UgPSBNYXRoLlBJICogdGhpcy5fbWluRGlhbWV0ZXI7XG4gICAgICAgIGNvbnN0IHRocmVzaG9sZCA9IFJPVEFUSU9OX1RIUkVTSE9MRCAvIGNpcmN1bWZlcmVuY2UgKiAzNjA7XG5cbiAgICAgICAgY29uc3Qgc3RhcnRWZWN0b3IgPSB0aGlzLl9zdGFydFZlY3RvcjtcbiAgICAgICAgaWYgKCFzdGFydFZlY3RvcikgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIGNvbnN0IGJlYXJpbmdEZWx0YVNpbmNlU3RhcnQgPSBnZXRCZWFyaW5nRGVsdGEodmVjdG9yLCBzdGFydFZlY3Rvcik7XG4gICAgICAgIHJldHVybiBNYXRoLmFicyhiZWFyaW5nRGVsdGFTaW5jZVN0YXJ0KSA8IHRocmVzaG9sZDtcbiAgICB9XG59XG5cbi8qIFBJVENIICovXG5cbmZ1bmN0aW9uIGlzVmVydGljYWwodmVjdG9yOiBQb2ludCkge1xuICAgIHJldHVybiBNYXRoLmFicyh2ZWN0b3IueSkgPiBNYXRoLmFicyh2ZWN0b3IueCk7XG59XG5cbmNvbnN0IEFMTE9XRURfU0lOR0xFX1RPVUNIX1RJTUUgPSAxMDA7XG5cbi8qKlxuICogVGhlIGBUb3VjaFBpdGNoSGFuZGxlcmAgYWxsb3dzIHRoZSB1c2VyIHRvIHBpdGNoIHRoZSBtYXAgYnkgZHJhZ2dpbmcgdXAgYW5kIGRvd24gd2l0aCB0d28gZmluZ2Vycy5cbiAqXG4gKiBAc2VlIFtFeGFtcGxlOiBTZXQgcGl0Y2ggYW5kIGJlYXJpbmddKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL3NldC1wZXJzcGVjdGl2ZS8pXG4qL1xuZXhwb3J0IGNsYXNzIFRvdWNoUGl0Y2hIYW5kbGVyIGV4dGVuZHMgVHdvVG91Y2hIYW5kbGVyIHtcblxuICAgIF92YWxpZDogYm9vbGVhbiB8IHZvaWQ7XG4gICAgX2ZpcnN0TW92ZTogP251bWJlcjtcbiAgICBfbGFzdFBvaW50czogP1tQb2ludCwgUG9pbnRdO1xuICAgIF9tYXA6IE1hcDtcblxuICAgIGNvbnN0cnVjdG9yKG1hcDogTWFwKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuX21hcCA9IG1hcDtcbiAgICB9XG5cbiAgICByZXNldCgpIHtcbiAgICAgICAgc3VwZXIucmVzZXQoKTtcbiAgICAgICAgdGhpcy5fdmFsaWQgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuX2ZpcnN0TW92ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5fbGFzdFBvaW50cyA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBfc3RhcnQocG9pbnRzOiBbUG9pbnQsIFBvaW50XSkge1xuICAgICAgICB0aGlzLl9sYXN0UG9pbnRzID0gcG9pbnRzO1xuICAgICAgICBpZiAoaXNWZXJ0aWNhbChwb2ludHNbMF0uc3ViKHBvaW50c1sxXSkpKSB7XG4gICAgICAgICAgICAvLyBmaW5nZXJzIGFyZSBtb3JlIGhvcml6b250YWwgdGhhbiB2ZXJ0aWNhbFxuICAgICAgICAgICAgdGhpcy5fdmFsaWQgPSBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgfVxuXG4gICAgX21vdmUocG9pbnRzOiBbUG9pbnQsIFBvaW50XSwgY2VudGVyOiA/UG9pbnQsIGU6IFRvdWNoRXZlbnQpOiA/SGFuZGxlclJlc3VsdCB7XG4gICAgICAgIGNvbnN0IGxhc3RQb2ludHMgPSB0aGlzLl9sYXN0UG9pbnRzO1xuICAgICAgICBpZiAoIWxhc3RQb2ludHMpIHJldHVybjtcbiAgICAgICAgY29uc3QgdmVjdG9yQSA9IHBvaW50c1swXS5zdWIobGFzdFBvaW50c1swXSk7XG4gICAgICAgIGNvbnN0IHZlY3RvckIgPSBwb2ludHNbMV0uc3ViKGxhc3RQb2ludHNbMV0pO1xuXG4gICAgICAgIGlmICh0aGlzLl9tYXAuX2Nvb3BlcmF0aXZlR2VzdHVyZXMgJiYgIWlzRnVsbHNjcmVlbigpICYmIGUudG91Y2hlcy5sZW5ndGggPCAzKSByZXR1cm47XG5cbiAgICAgICAgdGhpcy5fdmFsaWQgPSB0aGlzLmdlc3R1cmVCZWdpbnNWZXJ0aWNhbGx5KHZlY3RvckEsIHZlY3RvckIsIGUudGltZVN0YW1wKTtcblxuICAgICAgICBpZiAoIXRoaXMuX3ZhbGlkKSByZXR1cm47XG5cbiAgICAgICAgdGhpcy5fbGFzdFBvaW50cyA9IHBvaW50cztcbiAgICAgICAgdGhpcy5fYWN0aXZlID0gdHJ1ZTtcbiAgICAgICAgY29uc3QgeURlbHRhQXZlcmFnZSA9ICh2ZWN0b3JBLnkgKyB2ZWN0b3JCLnkpIC8gMjtcbiAgICAgICAgY29uc3QgZGVncmVlc1BlclBpeGVsTW92ZWQgPSAtMC41O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcGl0Y2hEZWx0YTogeURlbHRhQXZlcmFnZSAqIGRlZ3JlZXNQZXJQaXhlbE1vdmVkXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZ2VzdHVyZUJlZ2luc1ZlcnRpY2FsbHkodmVjdG9yQTogUG9pbnQsIHZlY3RvckI6IFBvaW50LCB0aW1lU3RhbXA6IG51bWJlcik6IHZvaWQgfCBib29sZWFuIHtcbiAgICAgICAgaWYgKHRoaXMuX3ZhbGlkICE9PSB1bmRlZmluZWQpIHJldHVybiB0aGlzLl92YWxpZDtcblxuICAgICAgICBjb25zdCB0aHJlc2hvbGQgPSAyO1xuICAgICAgICBjb25zdCBtb3ZlZEEgPSB2ZWN0b3JBLm1hZygpID49IHRocmVzaG9sZDtcbiAgICAgICAgY29uc3QgbW92ZWRCID0gdmVjdG9yQi5tYWcoKSA+PSB0aHJlc2hvbGQ7XG5cbiAgICAgICAgLy8gbmVpdGhlciBmaW5nZXIgaGFzIG1vdmVkIGEgbWVhbmluZ2Z1bCBhbW91bnQsIHdhaXRcbiAgICAgICAgaWYgKCFtb3ZlZEEgJiYgIW1vdmVkQikgcmV0dXJuO1xuXG4gICAgICAgIC8vIE9uZSBmaW5nZXIgaGFzIG1vdmVkIGFuZCB0aGUgb3RoZXIgaGFzIG5vdC5cbiAgICAgICAgLy8gSWYgZW5vdWdoIHRpbWUgaGFzIHBhc3NlZCwgZGVjaWRlIGl0IGlzIG5vdCBhIHBpdGNoLlxuICAgICAgICBpZiAoIW1vdmVkQSB8fCAhbW92ZWRCKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fZmlyc3RNb3ZlID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9maXJzdE1vdmUgPSB0aW1lU3RhbXA7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aW1lU3RhbXAgLSB0aGlzLl9maXJzdE1vdmUgPCBBTExPV0VEX1NJTkdMRV9UT1VDSF9USU1FKSB7XG4gICAgICAgICAgICAgICAgLy8gc3RpbGwgd2FpdGluZyBmb3IgYSBtb3ZlbWVudCBmcm9tIHRoZSBzZWNvbmQgZmluZ2VyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaXNTYW1lRGlyZWN0aW9uID0gdmVjdG9yQS55ID4gMCA9PT0gdmVjdG9yQi55ID4gMDtcbiAgICAgICAgcmV0dXJuIGlzVmVydGljYWwodmVjdG9yQSkgJiYgaXNWZXJ0aWNhbCh2ZWN0b3JCKSAmJiBpc1NhbWVEaXJlY3Rpb247XG4gICAgfVxufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHR5cGUgTWFwIGZyb20gJy4uL21hcC5qcyc7XG5pbXBvcnQgdHlwZSB7SGFuZGxlclJlc3VsdH0gZnJvbSAnLi4vaGFuZGxlcl9tYW5hZ2VyLmpzJztcblxuY29uc3QgZGVmYXVsdE9wdGlvbnMgPSB7XG4gICAgcGFuU3RlcDogMTAwLFxuICAgIGJlYXJpbmdTdGVwOiAxNSxcbiAgICBwaXRjaFN0ZXA6IDEwXG59O1xuXG4vKipcbiAqIFRoZSBgS2V5Ym9hcmRIYW5kbGVyYCBhbGxvd3MgdGhlIHVzZXIgdG8gem9vbSwgcm90YXRlLCBhbmQgcGFuIHRoZSBtYXAgdXNpbmdcbiAqIHRoZSBmb2xsb3dpbmcga2V5Ym9hcmQgc2hvcnRjdXRzOlxuICpcbiAqIC0gYD1gIC8gYCtgOiBJbmNyZWFzZSB0aGUgem9vbSBsZXZlbCBieSAxLlxuICogLSBgU2hpZnQtPWAgLyBgU2hpZnQtK2A6IEluY3JlYXNlIHRoZSB6b29tIGxldmVsIGJ5IDIuXG4gKiAtIGAtYDogRGVjcmVhc2UgdGhlIHpvb20gbGV2ZWwgYnkgMS5cbiAqIC0gYFNoaWZ0LS1gOiBEZWNyZWFzZSB0aGUgem9vbSBsZXZlbCBieSAyLlxuICogLSBBcnJvdyBrZXlzOiBQYW4gYnkgMTAwIHBpeGVscy5cbiAqIC0gYFNoaWZ0K+KHomA6IEluY3JlYXNlIHRoZSByb3RhdGlvbiBieSAxNSBkZWdyZWVzLlxuICogLSBgU2hpZnQr4oegYDogRGVjcmVhc2UgdGhlIHJvdGF0aW9uIGJ5IDE1IGRlZ3JlZXMuXG4gKiAtIGBTaGlmdCvih6FgOiBJbmNyZWFzZSB0aGUgcGl0Y2ggYnkgMTAgZGVncmVlcy5cbiAqIC0gYFNoaWZ0K+KHo2A6IERlY3JlYXNlIHRoZSBwaXRjaCBieSAxMCBkZWdyZWVzLlxuICpcbiAqIEBzZWUgW0V4YW1wbGU6IFRvZ2dsZSBpbnRlcmFjdGlvbnNdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL3RvZ2dsZS1pbnRlcmFjdGlvbi1oYW5kbGVycy8pXG4gKiBAc2VlIFtFeGFtcGxlOiBOYXZpZ2F0ZSB0aGUgbWFwIHdpdGggZ2FtZS1saWtlIGNvbnRyb2xzXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9nYW1lLWNvbnRyb2xzLylcbiAqIEBzZWUgW0V4YW1wbGU6IERpc3BsYXkgbWFwIG5hdmlnYXRpb24gY29udHJvbHNdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL25hdmlnYXRpb24vKVxuICovXG5jbGFzcyBLZXlib2FyZEhhbmRsZXIge1xuICAgIF9lbmFibGVkOiBib29sZWFuO1xuICAgIF9hY3RpdmU6IGJvb2xlYW47XG4gICAgX3BhblN0ZXA6IG51bWJlcjtcbiAgICBfYmVhcmluZ1N0ZXA6IG51bWJlcjtcbiAgICBfcGl0Y2hTdGVwOiBudW1iZXI7XG4gICAgX3JvdGF0aW9uRGlzYWJsZWQ6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAqIEBwcml2YXRlXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgY29uc3Qgc3RlcE9wdGlvbnMgPSBkZWZhdWx0T3B0aW9ucztcbiAgICAgICAgdGhpcy5fcGFuU3RlcCA9IHN0ZXBPcHRpb25zLnBhblN0ZXA7XG4gICAgICAgIHRoaXMuX2JlYXJpbmdTdGVwID0gc3RlcE9wdGlvbnMuYmVhcmluZ1N0ZXA7XG4gICAgICAgIHRoaXMuX3BpdGNoU3RlcCA9IHN0ZXBPcHRpb25zLnBpdGNoU3RlcDtcbiAgICAgICAgdGhpcy5fcm90YXRpb25EaXNhYmxlZCA9IGZhbHNlO1xuICAgIH1cblxuICAgIGJsdXIoKSB7XG4gICAgICAgIHRoaXMucmVzZXQoKTtcbiAgICB9XG5cbiAgICByZXNldCgpIHtcbiAgICAgICAgdGhpcy5fYWN0aXZlID0gZmFsc2U7XG4gICAgfVxuXG4gICAga2V5ZG93bihlOiBLZXlib2FyZEV2ZW50KTogP0hhbmRsZXJSZXN1bHQge1xuICAgICAgICBpZiAoZS5hbHRLZXkgfHwgZS5jdHJsS2V5IHx8IGUubWV0YUtleSkgcmV0dXJuO1xuXG4gICAgICAgIGxldCB6b29tRGlyID0gMDtcbiAgICAgICAgbGV0IGJlYXJpbmdEaXIgPSAwO1xuICAgICAgICBsZXQgcGl0Y2hEaXIgPSAwO1xuICAgICAgICBsZXQgeERpciA9IDA7XG4gICAgICAgIGxldCB5RGlyID0gMDtcblxuICAgICAgICBzd2l0Y2ggKGUua2V5Q29kZSkge1xuICAgICAgICBjYXNlIDYxOlxuICAgICAgICBjYXNlIDEwNzpcbiAgICAgICAgY2FzZSAxNzE6XG4gICAgICAgIGNhc2UgMTg3OlxuICAgICAgICAgICAgem9vbURpciA9IDE7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIDE4OTpcbiAgICAgICAgY2FzZSAxMDk6XG4gICAgICAgIGNhc2UgMTczOlxuICAgICAgICAgICAgem9vbURpciA9IC0xO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAzNzpcbiAgICAgICAgICAgIGlmIChlLnNoaWZ0S2V5KSB7XG4gICAgICAgICAgICAgICAgYmVhcmluZ0RpciA9IC0xO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgeERpciA9IC0xO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAzOTpcbiAgICAgICAgICAgIGlmIChlLnNoaWZ0S2V5KSB7XG4gICAgICAgICAgICAgICAgYmVhcmluZ0RpciA9IDE7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICB4RGlyID0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgMzg6XG4gICAgICAgICAgICBpZiAoZS5zaGlmdEtleSkge1xuICAgICAgICAgICAgICAgIHBpdGNoRGlyID0gMTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIHlEaXIgPSAtMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgNDA6XG4gICAgICAgICAgICBpZiAoZS5zaGlmdEtleSkge1xuICAgICAgICAgICAgICAgIHBpdGNoRGlyID0gLTE7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICB5RGlyID0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5fcm90YXRpb25EaXNhYmxlZCkge1xuICAgICAgICAgICAgYmVhcmluZ0RpciA9IDA7XG4gICAgICAgICAgICBwaXRjaERpciA9IDA7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY2FtZXJhQW5pbWF0aW9uOiAobWFwOiBNYXApID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB6b29tID0gbWFwLmdldFpvb20oKTtcblxuICAgICAgICAgICAgICAgIG1hcC5lYXNlVG8oe1xuICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbjogMzAwLFxuICAgICAgICAgICAgICAgICAgICBlYXNlSWQ6ICdrZXlib2FyZEhhbmRsZXInLFxuICAgICAgICAgICAgICAgICAgICBlYXNpbmc6IGVhc2VPdXQsXG4gICAgICAgICAgICAgICAgICAgIHpvb206IHpvb21EaXIgPyBNYXRoLnJvdW5kKHpvb20pICsgem9vbURpciAqIChlLnNoaWZ0S2V5ID8gMiA6IDEpIDogem9vbSxcbiAgICAgICAgICAgICAgICAgICAgYmVhcmluZzogbWFwLmdldEJlYXJpbmcoKSArIGJlYXJpbmdEaXIgKiB0aGlzLl9iZWFyaW5nU3RlcCxcbiAgICAgICAgICAgICAgICAgICAgcGl0Y2g6IG1hcC5nZXRQaXRjaCgpICsgcGl0Y2hEaXIgKiB0aGlzLl9waXRjaFN0ZXAsXG4gICAgICAgICAgICAgICAgICAgIG9mZnNldDogWy14RGlyICogdGhpcy5fcGFuU3RlcCwgLXlEaXIgKiB0aGlzLl9wYW5TdGVwXSxcbiAgICAgICAgICAgICAgICAgICAgY2VudGVyOiBtYXAuZ2V0Q2VudGVyKClcbiAgICAgICAgICAgICAgICB9LCB7b3JpZ2luYWxFdmVudDogZX0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEVuYWJsZXMgdGhlIFwia2V5Ym9hcmQgcm90YXRlIGFuZCB6b29tXCIgaW50ZXJhY3Rpb24uXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIG1hcC5rZXlib2FyZC5lbmFibGUoKTtcbiAgICAgKi9cbiAgICBlbmFibGUoKSB7XG4gICAgICAgIHRoaXMuX2VuYWJsZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERpc2FibGVzIHRoZSBcImtleWJvYXJkIHJvdGF0ZSBhbmQgem9vbVwiIGludGVyYWN0aW9uLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAua2V5Ym9hcmQuZGlzYWJsZSgpO1xuICAgICAqL1xuICAgIGRpc2FibGUoKSB7XG4gICAgICAgIHRoaXMuX2VuYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBCb29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGUgXCJrZXlib2FyZCByb3RhdGUgYW5kIHpvb21cIlxuICAgICAqIGludGVyYWN0aW9uIGlzIGVuYWJsZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gYHRydWVgIGlmIHRoZSBcImtleWJvYXJkIHJvdGF0ZSBhbmQgem9vbVwiXG4gICAgICogaW50ZXJhY3Rpb24gaXMgZW5hYmxlZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGlzS2V5Ym9hcmRFbmFibGVkID0gbWFwLmtleWJvYXJkLmlzRW5hYmxlZCgpO1xuICAgICAqL1xuICAgIGlzRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VuYWJsZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBoYW5kbGVyIGlzIGVuYWJsZWQgYW5kIGhhcyBkZXRlY3RlZCB0aGUgc3RhcnQgb2YgYVxuICAgICAqIHpvb20vcm90YXRlIGdlc3R1cmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gYHRydWVgIGlmIHRoZSBoYW5kbGVyIGlzIGVuYWJsZWQgYW5kIGhhcyBkZXRlY3RlZCB0aGVcbiAgICAgKiBzdGFydCBvZiBhIHpvb20vcm90YXRlIGdlc3R1cmUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBpc0tleWJvYXJkQWN0aXZlID0gbWFwLmtleWJvYXJkLmlzQWN0aXZlKCk7XG4gICAgICovXG4gICAgaXNBY3RpdmUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hY3RpdmU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGlzYWJsZXMgdGhlIFwia2V5Ym9hcmQgcGFuL3JvdGF0ZVwiIGludGVyYWN0aW9uLCBsZWF2aW5nIHRoZVxuICAgICAqIFwia2V5Ym9hcmQgem9vbVwiIGludGVyYWN0aW9uIGVuYWJsZWQuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIG1hcC5rZXlib2FyZC5kaXNhYmxlUm90YXRpb24oKTtcbiAgICAgKi9cbiAgICBkaXNhYmxlUm90YXRpb24oKSB7XG4gICAgICAgIHRoaXMuX3JvdGF0aW9uRGlzYWJsZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEVuYWJsZXMgdGhlIFwia2V5Ym9hcmQgcGFuL3JvdGF0ZVwiIGludGVyYWN0aW9uLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAua2V5Ym9hcmQuZW5hYmxlKCk7XG4gICAgICogbWFwLmtleWJvYXJkLmVuYWJsZVJvdGF0aW9uKCk7XG4gICAgICovXG4gICAgZW5hYmxlUm90YXRpb24oKSB7XG4gICAgICAgIHRoaXMuX3JvdGF0aW9uRGlzYWJsZWQgPSBmYWxzZTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGVhc2VPdXQodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIHQgKiAoMiAtIHQpO1xufVxuXG5leHBvcnQgZGVmYXVsdCBLZXlib2FyZEhhbmRsZXI7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgKiBhcyBET00gZnJvbSAnLi4vLi4vdXRpbC9kb20uanMnO1xuXG5pbXBvcnQge2Vhc2UgYXMgX2Vhc2UsIGJpbmRBbGwsIGJlemllciwgaXNGdWxsc2NyZWVufSBmcm9tICcuLi8uLi91dGlsL3V0aWwuanMnO1xuaW1wb3J0IGJyb3dzZXIgZnJvbSAnLi4vLi4vdXRpbC9icm93c2VyLmpzJztcbmltcG9ydCB3aW5kb3cgZnJvbSAnLi4vLi4vdXRpbC93aW5kb3cuanMnO1xuaW1wb3J0IHtudW1iZXIgYXMgaW50ZXJwb2xhdGV9IGZyb20gJy4uLy4uL3N0eWxlLXNwZWMvdXRpbC9pbnRlcnBvbGF0ZS5qcyc7XG5pbXBvcnQgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5cbmltcG9ydCB0eXBlIE1hcCBmcm9tICcuLi9tYXAuanMnO1xuaW1wb3J0IHR5cGUgSGFuZGxlck1hbmFnZXIsIHtIYW5kbGVyUmVzdWx0fSBmcm9tICcuLi9oYW5kbGVyX21hbmFnZXIuanMnO1xuaW1wb3J0IE1lcmNhdG9yQ29vcmRpbmF0ZSBmcm9tICcuLi8uLi9nZW8vbWVyY2F0b3JfY29vcmRpbmF0ZS5qcyc7XG5cbi8vIGRlbHRhWSB2YWx1ZSBmb3IgbW91c2Ugc2Nyb2xsIHdoZWVsIGlkZW50aWZpY2F0aW9uXG5jb25zdCB3aGVlbFpvb21EZWx0YSA9IDQuMDAwMjQ0MTQwNjI1O1xuXG4vLyBUaGVzZSBtYWdpYyBudW1iZXJzIGNvbnRyb2wgdGhlIHJhdGUgb2Ygem9vbS4gVHJhY2twYWQgZXZlbnRzIGZpcmUgYXQgYSBncmVhdGVyXG4vLyBmcmVxdWVuY3kgdGhhbiBtb3VzZSBzY3JvbGwgd2hlZWwsIHNvIHJlZHVjZSB0aGUgem9vbSByYXRlIHBlciB3aGVlbCB0aWNrXG5jb25zdCBkZWZhdWx0Wm9vbVJhdGUgPSAxIC8gMTAwO1xuY29uc3Qgd2hlZWxab29tUmF0ZSA9IDEgLyA0NTA7XG5cbi8vIHVwcGVyIGJvdW5kIG9uIGhvdyBtdWNoIHdlIHNjYWxlIHRoZSBtYXAgaW4gYW55IHNpbmdsZSByZW5kZXIgZnJhbWU7IHRoaXNcbi8vIGlzIHVzZWQgdG8gbGltaXQgem9vbSByYXRlIGluIHRoZSBjYXNlIG9mIHZlcnkgZmFzdCBzY3JvbGxpbmdcbmNvbnN0IG1heFNjYWxlUGVyRnJhbWUgPSAyO1xuXG4vKipcbiAqIFRoZSBgU2Nyb2xsWm9vbUhhbmRsZXJgIGFsbG93cyB0aGUgdXNlciB0byB6b29tIHRoZSBtYXAgYnkgc2Nyb2xsaW5nLlxuICpcbiAqIEBzZWUgW0V4YW1wbGU6IFRvZ2dsZSBpbnRlcmFjdGlvbnNdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL3RvZ2dsZS1pbnRlcmFjdGlvbi1oYW5kbGVycy8pXG4gKiBAc2VlIFtFeGFtcGxlOiBEaXNhYmxlIHNjcm9sbCB6b29tXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9kaXNhYmxlLXNjcm9sbC16b29tLylcbiAqL1xuY2xhc3MgU2Nyb2xsWm9vbUhhbmRsZXIge1xuICAgIF9tYXA6IE1hcDtcbiAgICBfZWw6IEhUTUxFbGVtZW50O1xuICAgIF9lbmFibGVkOiBib29sZWFuO1xuICAgIF9hY3RpdmU6IGJvb2xlYW47XG4gICAgX3pvb21pbmc6IGJvb2xlYW47XG4gICAgX2Fyb3VuZENlbnRlcjogYm9vbGVhbjtcbiAgICBfYXJvdW5kUG9pbnQ6IFBvaW50O1xuICAgIF9hcm91bmRDb29yZDogTWVyY2F0b3JDb29yZGluYXRlO1xuICAgIF90eXBlOiAnd2hlZWwnIHwgJ3RyYWNrcGFkJyB8IG51bGw7XG4gICAgX2xhc3RWYWx1ZTogbnVtYmVyO1xuICAgIF90aW1lb3V0OiA/VGltZW91dElEOyAvLyB1c2VkIGZvciBkZWxheWVkLWhhbmRsaW5nIG9mIGEgc2luZ2xlIHdoZWVsIG1vdmVtZW50XG4gICAgX2ZpbmlzaFRpbWVvdXQ6ID9UaW1lb3V0SUQ7IC8vIHVzZWQgdG8gZGVsYXkgZmluYWwgJ3ttb3ZlLHpvb219ZW5kJyBldmVudHNcblxuICAgIF9sYXN0V2hlZWxFdmVudDogYW55O1xuICAgIF9sYXN0V2hlZWxFdmVudFRpbWU6IG51bWJlcjtcblxuICAgIF9zdGFydFpvb206ID9udW1iZXI7XG4gICAgX3RhcmdldFpvb206ID9udW1iZXI7XG4gICAgX2RlbHRhOiBudW1iZXI7XG4gICAgX2Vhc2luZzogPygobnVtYmVyKSA9PiBudW1iZXIpO1xuICAgIF9wcmV2RWFzZTogP3tzdGFydDogbnVtYmVyLCBkdXJhdGlvbjogbnVtYmVyLCBlYXNpbmc6IChfOiBudW1iZXIpID0+IG51bWJlcn07XG5cbiAgICBfZnJhbWVJZDogP2Jvb2xlYW47XG4gICAgX2hhbmRsZXI6IEhhbmRsZXJNYW5hZ2VyO1xuXG4gICAgX2RlZmF1bHRab29tUmF0ZTogbnVtYmVyO1xuICAgIF93aGVlbFpvb21SYXRlOiBudW1iZXI7XG5cbiAgICBfYWxlcnRDb250YWluZXI6IEhUTUxFbGVtZW50OyAvLyB1c2VkIHRvIGRpc3BsYXkgdGhlIHNjcm9sbCB6b29tIGJsb2NrZXIgYWxlcnRcbiAgICBfYWxlcnRUaW1lcjogVGltZW91dElEO1xuXG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihtYXA6IE1hcCwgaGFuZGxlcjogSGFuZGxlck1hbmFnZXIpIHtcbiAgICAgICAgdGhpcy5fbWFwID0gbWFwO1xuICAgICAgICB0aGlzLl9lbCA9IG1hcC5nZXRDYW52YXNDb250YWluZXIoKTtcbiAgICAgICAgdGhpcy5faGFuZGxlciA9IGhhbmRsZXI7XG5cbiAgICAgICAgdGhpcy5fZGVsdGEgPSAwO1xuXG4gICAgICAgIHRoaXMuX2RlZmF1bHRab29tUmF0ZSA9IGRlZmF1bHRab29tUmF0ZTtcbiAgICAgICAgdGhpcy5fd2hlZWxab29tUmF0ZSA9IHdoZWVsWm9vbVJhdGU7XG5cbiAgICAgICAgYmluZEFsbChbJ19vblRpbWVvdXQnLCAnX2FkZFNjcm9sbFpvb21CbG9ja2VyJywgJ19zaG93QmxvY2tlckFsZXJ0J10sIHRoaXMpO1xuXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgem9vbSByYXRlIG9mIGEgdHJhY2twYWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3pvb21SYXRlPTEvMTAwXSBUaGUgcmF0ZSB1c2VkIHRvIHNjYWxlIHRyYWNrcGFkIG1vdmVtZW50IHRvIGEgem9vbSB2YWx1ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIFNwZWVkIHVwIHRyYWNrcGFkIHpvb21cbiAgICAgKiBtYXAuc2Nyb2xsWm9vbS5zZXRab29tUmF0ZSgxIC8gMjUpO1xuICAgICAqL1xuICAgIHNldFpvb21SYXRlKHpvb21SYXRlOiBudW1iZXIpIHtcbiAgICAgICAgdGhpcy5fZGVmYXVsdFpvb21SYXRlID0gem9vbVJhdGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBTZXRzIHRoZSB6b29tIHJhdGUgb2YgYSBtb3VzZSB3aGVlbC5cbiAgICAgKlxuICAgICogQHBhcmFtIHtudW1iZXJ9IFt3aGVlbFpvb21SYXRlPTEvNDUwXSBUaGUgcmF0ZSB1c2VkIHRvIHNjYWxlIG1vdXNlIHdoZWVsIG1vdmVtZW50IHRvIGEgem9vbSB2YWx1ZS5cbiAgICAqIEBleGFtcGxlXG4gICAgKiAvLyBTbG93IGRvd24gem9vbSBvZiBtb3VzZSB3aGVlbFxuICAgICogbWFwLnNjcm9sbFpvb20uc2V0V2hlZWxab29tUmF0ZSgxIC8gNjAwKTtcbiAgICAqL1xuICAgIHNldFdoZWVsWm9vbVJhdGUod2hlZWxab29tUmF0ZTogbnVtYmVyKSB7XG4gICAgICAgIHRoaXMuX3doZWVsWm9vbVJhdGUgPSB3aGVlbFpvb21SYXRlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBCb29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGUgXCJzY3JvbGwgdG8gem9vbVwiIGludGVyYWN0aW9uIGlzIGVuYWJsZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gYHRydWVgIGlmIHRoZSBcInNjcm9sbCB0byB6b29tXCIgaW50ZXJhY3Rpb24gaXMgZW5hYmxlZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGlzU2Nyb2xsWm9vbUVuYWJsZWQgPSBtYXAuc2Nyb2xsWm9vbS5pc0VuYWJsZWQoKTtcbiAgICAgKi9cbiAgICBpc0VuYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX2VuYWJsZWQ7XG4gICAgfVxuXG4gICAgLypcbiAgICAqIEFjdGl2ZSBzdGF0ZSBpcyB0dXJuZWQgb24gYW5kIG9mZiB3aXRoIGV2ZXJ5IHNjcm9sbCB3aGVlbCBldmVudCBhbmQgaXMgc2V0IGJhY2sgdG8gZmFsc2UgYmVmb3JlIHRoZSBtYXBcbiAgICAqIHJlbmRlciBpcyBjYWxsZWQsIHNvIF9hY3RpdmUgaXMgbm90IGEgZ29vZCBjYW5kaWRhdGUgZm9yIGRldGVybWluaW5nIGlmIGEgc2Nyb2xsIHpvb20gYW5pbWF0aW9uIGlzIGluXG4gICAgKiBwcm9ncmVzcy5cbiAgICAqL1xuICAgIGlzQWN0aXZlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWN0aXZlIHx8IHRoaXMuX2ZpbmlzaFRpbWVvdXQgIT09IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBpc1pvb21pbmcoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX3pvb21pbmc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRW5hYmxlcyB0aGUgXCJzY3JvbGwgdG8gem9vbVwiIGludGVyYWN0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSBPcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdGlvbnMuYXJvdW5kXSBJZiBcImNlbnRlclwiIGlzIHBhc3NlZCwgbWFwIHdpbGwgem9vbSBhcm91bmQgY2VudGVyIG9mIG1hcC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogbWFwLnNjcm9sbFpvb20uZW5hYmxlKCk7XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAuc2Nyb2xsWm9vbS5lbmFibGUoe2Fyb3VuZDogJ2NlbnRlcid9KTtcbiAgICAgKi9cbiAgICBlbmFibGUob3B0aW9uczogP3thcm91bmQ/OiAnY2VudGVyJ30pIHtcbiAgICAgICAgaWYgKHRoaXMuaXNFbmFibGVkKCkpIHJldHVybjtcbiAgICAgICAgdGhpcy5fZW5hYmxlZCA9IHRydWU7XG4gICAgICAgIHRoaXMuX2Fyb3VuZENlbnRlciA9ICEhb3B0aW9ucyAmJiBvcHRpb25zLmFyb3VuZCA9PT0gJ2NlbnRlcic7XG4gICAgICAgIGlmICh0aGlzLl9tYXAuX2Nvb3BlcmF0aXZlR2VzdHVyZXMpIHRoaXMuX2FkZFNjcm9sbFpvb21CbG9ja2VyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGlzYWJsZXMgdGhlIFwic2Nyb2xsIHRvIHpvb21cIiBpbnRlcmFjdGlvbi5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogbWFwLnNjcm9sbFpvb20uZGlzYWJsZSgpO1xuICAgICAqL1xuICAgIGRpc2FibGUoKSB7XG4gICAgICAgIGlmICghdGhpcy5pc0VuYWJsZWQoKSkgcmV0dXJuO1xuICAgICAgICB0aGlzLl9lbmFibGVkID0gZmFsc2U7XG4gICAgICAgIGlmICh0aGlzLl9tYXAuX2Nvb3BlcmF0aXZlR2VzdHVyZXMpIHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLl9hbGVydFRpbWVyKTtcbiAgICAgICAgICAgIHRoaXMuX2FsZXJ0Q29udGFpbmVyLnJlbW92ZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgd2hlZWwoZTogV2hlZWxFdmVudCkge1xuICAgICAgICBpZiAoIXRoaXMuaXNFbmFibGVkKCkpIHJldHVybjtcblxuICAgICAgICBpZiAodGhpcy5fbWFwLl9jb29wZXJhdGl2ZUdlc3R1cmVzKSB7XG4gICAgICAgICAgICBpZiAoIWUuY3RybEtleSAmJiAhZS5tZXRhS2V5ICYmICF0aGlzLmlzWm9vbWluZygpICYmICFpc0Z1bGxzY3JlZW4oKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3Nob3dCbG9ja2VyQWxlcnQoKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX2FsZXJ0Q29udGFpbmVyLnN0eWxlLnZpc2liaWxpdHkgIT09ICdoaWRkZW4nKSB7XG4gICAgICAgICAgICAgICAgLy8gaW1tZWRpYXRlbHkgaGlkZSBhbGVydCBpZiBpdCBpcyB2aXNpYmxlIHdoZW4gY3RybCBvciDijJggaXMgcHJlc3NlZCB3aGlsZSBzY3JvbGwgem9vbWluZy5cbiAgICAgICAgICAgICAgICB0aGlzLl9hbGVydENvbnRhaW5lci5zdHlsZS52aXNpYmlsaXR5ID0gJ2hpZGRlbic7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuX2FsZXJ0VGltZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVtb3ZlIGBhbnlgIGNhc3Qgd2hlbiBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svZmxvdy9pc3N1ZXMvNDg3OSBpcyBmaXhlZC5cbiAgICAgICAgbGV0IHZhbHVlID0gZS5kZWx0YU1vZGUgPT09ICh3aW5kb3cuV2hlZWxFdmVudDogYW55KS5ET01fREVMVEFfTElORSA/IGUuZGVsdGFZICogNDAgOiBlLmRlbHRhWTtcbiAgICAgICAgY29uc3Qgbm93ID0gYnJvd3Nlci5ub3coKSxcbiAgICAgICAgICAgIHRpbWVEZWx0YSA9IG5vdyAtICh0aGlzLl9sYXN0V2hlZWxFdmVudFRpbWUgfHwgMCk7XG5cbiAgICAgICAgdGhpcy5fbGFzdFdoZWVsRXZlbnRUaW1lID0gbm93O1xuXG4gICAgICAgIGlmICh2YWx1ZSAhPT0gMCAmJiAodmFsdWUgJSB3aGVlbFpvb21EZWx0YSkgPT09IDApIHtcbiAgICAgICAgICAgIC8vIFRoaXMgb25lIGlzIGRlZmluaXRlbHkgYSBtb3VzZSB3aGVlbCBldmVudC5cbiAgICAgICAgICAgIHRoaXMuX3R5cGUgPSAnd2hlZWwnO1xuXG4gICAgICAgIH0gZWxzZSBpZiAodmFsdWUgIT09IDAgJiYgTWF0aC5hYnModmFsdWUpIDwgNCkge1xuICAgICAgICAgICAgLy8gVGhpcyBvbmUgaXMgZGVmaW5pdGVseSBhIHRyYWNrcGFkIGV2ZW50IGJlY2F1c2UgaXQgaXMgc28gc21hbGwuXG4gICAgICAgICAgICB0aGlzLl90eXBlID0gJ3RyYWNrcGFkJztcblxuICAgICAgICB9IGVsc2UgaWYgKHRpbWVEZWx0YSA+IDQwMCkge1xuICAgICAgICAgICAgLy8gVGhpcyBpcyBsaWtlbHkgYSBuZXcgc2Nyb2xsIGFjdGlvbi5cbiAgICAgICAgICAgIHRoaXMuX3R5cGUgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5fbGFzdFZhbHVlID0gdmFsdWU7XG5cbiAgICAgICAgICAgIC8vIFN0YXJ0IGEgdGltZW91dCBpbiBjYXNlIHRoaXMgd2FzIGEgc2luZ3VsYXIgZXZlbnQsIGFuZCBkZWxheSBpdCBieSB1cCB0byA0MG1zLlxuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgdGhpcy5fdGltZW91dCA9IHNldFRpbWVvdXQodGhpcy5fb25UaW1lb3V0LCA0MCwgZSk7XG5cbiAgICAgICAgfSBlbHNlIGlmICghdGhpcy5fdHlwZSkge1xuICAgICAgICAgICAgLy8gVGhpcyBpcyBhIHJlcGVhdGluZyBldmVudCwgYnV0IHdlIGRvbid0IGtub3cgdGhlIHR5cGUgb2YgZXZlbnQganVzdCB5ZXQuXG4gICAgICAgICAgICAvLyBJZiB0aGUgZGVsdGEgcGVyIHRpbWUgaXMgc21hbGwsIHdlIGFzc3VtZSBpdCdzIGEgZmFzdCB0cmFja3BhZDsgb3RoZXJ3aXNlIHdlIHN3aXRjaCBpbnRvIHdoZWVsIG1vZGUuXG4gICAgICAgICAgICB0aGlzLl90eXBlID0gKE1hdGguYWJzKHRpbWVEZWx0YSAqIHZhbHVlKSA8IDIwMCkgPyAndHJhY2twYWQnIDogJ3doZWVsJztcblxuICAgICAgICAgICAgLy8gTWFrZSBzdXJlIG91ciBkZWxheWVkIGV2ZW50IGlzbid0IGZpcmVkIGFnYWluLCBiZWNhdXNlIHdlIGFjY3VtdWxhdGVcbiAgICAgICAgICAgIC8vIHRoZSBwcmV2aW91cyBldmVudCAod2hpY2ggd2FzIGxlc3MgdGhhbiA0MG1zIGFnbykgaW50byB0aGlzIGV2ZW50LlxuICAgICAgICAgICAgaWYgKHRoaXMuX3RpbWVvdXQpIHtcbiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5fdGltZW91dCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fdGltZW91dCA9IG51bGw7XG4gICAgICAgICAgICAgICAgdmFsdWUgKz0gdGhpcy5fbGFzdFZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2xvdyBkb3duIHpvb20gaWYgc2hpZnQga2V5IGlzIGhlbGQgZm9yIG1vcmUgcHJlY2lzZSB6b29taW5nXG4gICAgICAgIGlmIChlLnNoaWZ0S2V5ICYmIHZhbHVlKSB2YWx1ZSA9IHZhbHVlIC8gNDtcblxuICAgICAgICAvLyBPbmx5IGZpcmUgdGhlIGNhbGxiYWNrIGlmIHdlIGFjdHVhbGx5IGtub3cgd2hhdCB0eXBlIG9mIHNjcm9sbGluZyBkZXZpY2UgdGhlIHVzZXIgdXNlcy5cbiAgICAgICAgaWYgKHRoaXMuX3R5cGUpIHtcbiAgICAgICAgICAgIHRoaXMuX2xhc3RXaGVlbEV2ZW50ID0gZTtcbiAgICAgICAgICAgIHRoaXMuX2RlbHRhIC09IHZhbHVlO1xuICAgICAgICAgICAgaWYgKCF0aGlzLl9hY3RpdmUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGFydChlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG5cbiAgICBfb25UaW1lb3V0KGluaXRpYWxFdmVudDogV2hlZWxFdmVudCkge1xuICAgICAgICB0aGlzLl90eXBlID0gJ3doZWVsJztcbiAgICAgICAgdGhpcy5fZGVsdGEgLT0gdGhpcy5fbGFzdFZhbHVlO1xuICAgICAgICBpZiAoIXRoaXMuX2FjdGl2ZSkge1xuICAgICAgICAgICAgdGhpcy5fc3RhcnQoaW5pdGlhbEV2ZW50KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9zdGFydChlOiBXaGVlbEV2ZW50KSB7XG4gICAgICAgIGlmICghdGhpcy5fZGVsdGEpIHJldHVybjtcblxuICAgICAgICBpZiAodGhpcy5fZnJhbWVJZCkge1xuICAgICAgICAgICAgdGhpcy5fZnJhbWVJZCA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9hY3RpdmUgPSB0cnVlO1xuICAgICAgICBpZiAoIXRoaXMuaXNab29taW5nKCkpIHtcbiAgICAgICAgICAgIHRoaXMuX3pvb21pbmcgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuX2ZpbmlzaFRpbWVvdXQpIHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLl9maW5pc2hUaW1lb3V0KTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9maW5pc2hUaW1lb3V0O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcG9zID0gRE9NLm1vdXNlUG9zKHRoaXMuX2VsLCBlKTtcbiAgICAgICAgdGhpcy5fYXJvdW5kUG9pbnQgPSB0aGlzLl9hcm91bmRDZW50ZXIgPyB0aGlzLl9tYXAudHJhbnNmb3JtLmNlbnRlclBvaW50IDogcG9zO1xuICAgICAgICB0aGlzLl9hcm91bmRDb29yZCA9IHRoaXMuX21hcC50cmFuc2Zvcm0ucG9pbnRDb29yZGluYXRlM0QodGhpcy5fYXJvdW5kUG9pbnQpO1xuICAgICAgICB0aGlzLl90YXJnZXRab29tID0gdW5kZWZpbmVkO1xuXG4gICAgICAgIGlmICghdGhpcy5fZnJhbWVJZCkge1xuICAgICAgICAgICAgdGhpcy5fZnJhbWVJZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLl9oYW5kbGVyLl90cmlnZ2VyUmVuZGVyRnJhbWUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJlbmRlckZyYW1lKCk6ID9IYW5kbGVyUmVzdWx0IHtcbiAgICAgICAgaWYgKCF0aGlzLl9mcmFtZUlkKSByZXR1cm47XG4gICAgICAgIHRoaXMuX2ZyYW1lSWQgPSBudWxsO1xuXG4gICAgICAgIGlmICghdGhpcy5pc0FjdGl2ZSgpKSByZXR1cm47XG5cbiAgICAgICAgY29uc3QgdHIgPSB0aGlzLl9tYXAudHJhbnNmb3JtO1xuXG4gICAgICAgIC8vIElmIHByb2plY3Rpb24gd3JhcHMgYW5kIGNlbnRlciBjcm9zc2VzIHRoZSBhbnRpbWVyaWRpYW4sIHJlc2V0IHByZXZpb3VzIG1vdXNlIHNjcm9sbCBlYXNpbmcgc2V0dGluZ3MgdG8gcmVzb2x2ZSBodHRwczovL2dpdGh1Yi5jb20vbWFwYm94L21hcGJveC1nbC1qcy9pc3N1ZXMvMTE5MTBcbiAgICAgICAgaWYgKHRoaXMuX3R5cGUgPT09ICd3aGVlbCcgJiYgdHIucHJvamVjdGlvbi53cmFwICYmICh0ci5fY2VudGVyLmxuZyA+PSAxODAgfHwgdHIuX2NlbnRlci5sbmcgPD0gLTE4MCkpIHtcbiAgICAgICAgICAgIHRoaXMuX3ByZXZFYXNlID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX2Vhc2luZyA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLl9sYXN0V2hlZWxFdmVudCA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLl9sYXN0V2hlZWxFdmVudFRpbWUgPSAwO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc3RhcnRpbmdab29tID0gKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuICh0ci5fdGVycmFpbkVuYWJsZWQoKSAmJiB0aGlzLl9hcm91bmRDb29yZCkgPyB0ci5jb21wdXRlWm9vbVJlbGF0aXZlVG8odGhpcy5fYXJvdW5kQ29vcmQpIDogdHIuem9vbTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBpZiB3ZSd2ZSBoYWQgc2Nyb2xsIGV2ZW50cyBzaW5jZSB0aGUgbGFzdCByZW5kZXIgZnJhbWUsIGNvbnN1bWUgdGhlXG4gICAgICAgIC8vIGFjY3VtdWxhdGVkIGRlbHRhLCBhbmQgdXBkYXRlIHRoZSB0YXJnZXQgem9vbSBsZXZlbCBhY2NvcmRpbmdseVxuICAgICAgICBpZiAodGhpcy5fZGVsdGEgIT09IDApIHtcbiAgICAgICAgICAgIC8vIEZvciB0cmFja3BhZCBldmVudHMgYW5kIHNpbmdsZSBtb3VzZSB3aGVlbCB0aWNrcywgdXNlIHRoZSBkZWZhdWx0IHpvb20gcmF0ZVxuICAgICAgICAgICAgY29uc3Qgem9vbVJhdGUgPSAodGhpcy5fdHlwZSA9PT0gJ3doZWVsJyAmJiBNYXRoLmFicyh0aGlzLl9kZWx0YSkgPiB3aGVlbFpvb21EZWx0YSkgPyB0aGlzLl93aGVlbFpvb21SYXRlIDogdGhpcy5fZGVmYXVsdFpvb21SYXRlO1xuICAgICAgICAgICAgLy8gU2NhbGUgYnkgc2lnbW9pZCBvZiBzY3JvbGwgd2hlZWwgZGVsdGEuXG4gICAgICAgICAgICBsZXQgc2NhbGUgPSBtYXhTY2FsZVBlckZyYW1lIC8gKDEgKyBNYXRoLmV4cCgtTWF0aC5hYnModGhpcy5fZGVsdGEgKiB6b29tUmF0ZSkpKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuX2RlbHRhIDwgMCAmJiBzY2FsZSAhPT0gMCkge1xuICAgICAgICAgICAgICAgIHNjYWxlID0gMSAvIHNjYWxlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBzdGFydFpvb20gPSBzdGFydGluZ1pvb20oKTtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0U2NhbGUgPSBNYXRoLnBvdygyLjAsIHN0YXJ0Wm9vbSk7XG5cbiAgICAgICAgICAgIGNvbnN0IGZyb21TY2FsZSA9IHR5cGVvZiB0aGlzLl90YXJnZXRab29tID09PSAnbnVtYmVyJyA/IHRyLnpvb21TY2FsZSh0aGlzLl90YXJnZXRab29tKSA6IHN0YXJ0U2NhbGU7XG4gICAgICAgICAgICB0aGlzLl90YXJnZXRab29tID0gTWF0aC5taW4odHIubWF4Wm9vbSwgTWF0aC5tYXgodHIubWluWm9vbSwgdHIuc2NhbGVab29tKGZyb21TY2FsZSAqIHNjYWxlKSkpO1xuXG4gICAgICAgICAgICAvLyBpZiB0aGlzIGlzIGEgbW91c2Ugd2hlZWwsIHJlZnJlc2ggdGhlIHN0YXJ0aW5nIHpvb20gYW5kIGVhc2luZ1xuICAgICAgICAgICAgLy8gZnVuY3Rpb24gd2UncmUgdXNpbmcgdG8gc21vb3RoIG91dCB0aGUgem9vbWluZyBiZXR3ZWVuIHdoZWVsXG4gICAgICAgICAgICAvLyBldmVudHNcbiAgICAgICAgICAgIGlmICh0aGlzLl90eXBlID09PSAnd2hlZWwnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhcnRab29tID0gc3RhcnRab29tO1xuICAgICAgICAgICAgICAgIHRoaXMuX2Vhc2luZyA9IHRoaXMuX3Ntb290aE91dEVhc2luZygyMDApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLl9kZWx0YSA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGFyZ2V0Wm9vbSA9IHR5cGVvZiB0aGlzLl90YXJnZXRab29tID09PSAnbnVtYmVyJyA/XG4gICAgICAgICAgICB0aGlzLl90YXJnZXRab29tIDogc3RhcnRpbmdab29tKCk7XG4gICAgICAgIGNvbnN0IHN0YXJ0Wm9vbSA9IHRoaXMuX3N0YXJ0Wm9vbTtcbiAgICAgICAgY29uc3QgZWFzaW5nID0gdGhpcy5fZWFzaW5nO1xuXG4gICAgICAgIGxldCBmaW5pc2hlZCA9IGZhbHNlO1xuICAgICAgICBsZXQgem9vbTtcbiAgICAgICAgaWYgKHRoaXMuX3R5cGUgPT09ICd3aGVlbCcgJiYgc3RhcnRab29tICYmIGVhc2luZykge1xuICAgICAgICAgICAgYXNzZXJ0KGVhc2luZyAmJiB0eXBlb2Ygc3RhcnRab29tID09PSAnbnVtYmVyJyk7XG5cbiAgICAgICAgICAgIGNvbnN0IHQgPSBNYXRoLm1pbigoYnJvd3Nlci5ub3coKSAtIHRoaXMuX2xhc3RXaGVlbEV2ZW50VGltZSkgLyAyMDAsIDEpO1xuICAgICAgICAgICAgY29uc3QgayA9IGVhc2luZyh0KTtcbiAgICAgICAgICAgIHpvb20gPSBpbnRlcnBvbGF0ZShzdGFydFpvb20sIHRhcmdldFpvb20sIGspO1xuICAgICAgICAgICAgaWYgKHQgPCAxKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLl9mcmFtZUlkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2ZyYW1lSWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZmluaXNoZWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgem9vbSA9IHRhcmdldFpvb207XG4gICAgICAgICAgICBmaW5pc2hlZCA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9hY3RpdmUgPSB0cnVlO1xuXG4gICAgICAgIGlmIChmaW5pc2hlZCkge1xuICAgICAgICAgICAgdGhpcy5fYWN0aXZlID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLl9maW5pc2hUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fem9vbWluZyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZXIuX3RyaWdnZXJSZW5kZXJGcmFtZSgpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl90YXJnZXRab29tO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9maW5pc2hUaW1lb3V0O1xuICAgICAgICAgICAgfSwgMjAwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBub0luZXJ0aWE6IHRydWUsXG4gICAgICAgICAgICBuZWVkc1JlbmRlckZyYW1lOiAhZmluaXNoZWQsXG4gICAgICAgICAgICB6b29tRGVsdGE6IHpvb20gLSBzdGFydGluZ1pvb20oKSxcbiAgICAgICAgICAgIGFyb3VuZDogdGhpcy5fYXJvdW5kUG9pbnQsXG4gICAgICAgICAgICBhcm91bmRDb29yZDogdGhpcy5fYXJvdW5kQ29vcmQsXG4gICAgICAgICAgICBvcmlnaW5hbEV2ZW50OiB0aGlzLl9sYXN0V2hlZWxFdmVudFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIF9zbW9vdGhPdXRFYXNpbmcoZHVyYXRpb246IG51bWJlcik6IChudW1iZXIpID0+IG51bWJlciB7XG4gICAgICAgIGxldCBlYXNpbmcgPSBfZWFzZTtcblxuICAgICAgICBpZiAodGhpcy5fcHJldkVhc2UpIHtcbiAgICAgICAgICAgIGNvbnN0IGVhc2UgPSB0aGlzLl9wcmV2RWFzZSxcbiAgICAgICAgICAgICAgICB0ID0gKGJyb3dzZXIubm93KCkgLSBlYXNlLnN0YXJ0KSAvIGVhc2UuZHVyYXRpb24sXG4gICAgICAgICAgICAgICAgc3BlZWQgPSBlYXNlLmVhc2luZyh0ICsgMC4wMSkgLSBlYXNlLmVhc2luZyh0KSxcblxuICAgICAgICAgICAgICAgIC8vIFF1aWNrIGhhY2sgdG8gbWFrZSBuZXcgYmV6aWVyIHRoYXQgaXMgY29udGludW91cyB3aXRoIGxhc3RcbiAgICAgICAgICAgICAgICB4ID0gMC4yNyAvIE1hdGguc3FydChzcGVlZCAqIHNwZWVkICsgMC4wMDAxKSAqIDAuMDEsXG4gICAgICAgICAgICAgICAgeSA9IE1hdGguc3FydCgwLjI3ICogMC4yNyAtIHggKiB4KTtcblxuICAgICAgICAgICAgZWFzaW5nID0gYmV6aWVyKHgsIHksIDAuMjUsIDEpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fcHJldkVhc2UgPSB7XG4gICAgICAgICAgICBzdGFydDogYnJvd3Nlci5ub3coKSxcbiAgICAgICAgICAgIGR1cmF0aW9uLFxuICAgICAgICAgICAgZWFzaW5nXG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIGVhc2luZztcbiAgICB9XG5cbiAgICBibHVyKCkge1xuICAgICAgICB0aGlzLnJlc2V0KCk7XG4gICAgfVxuXG4gICAgcmVzZXQoKSB7XG4gICAgICAgIHRoaXMuX2FjdGl2ZSA9IGZhbHNlO1xuICAgIH1cblxuICAgIF9hZGRTY3JvbGxab29tQmxvY2tlcigpIHtcbiAgICAgICAgaWYgKHRoaXMuX21hcCAmJiAhdGhpcy5fYWxlcnRDb250YWluZXIpIHtcbiAgICAgICAgICAgIHRoaXMuX2FsZXJ0Q29udGFpbmVyID0gRE9NLmNyZWF0ZSgnZGl2JywgJ21hcGJveGdsLXNjcm9sbC16b29tLWJsb2NrZXInLCB0aGlzLl9tYXAuX2NvbnRhaW5lcik7XG5cbiAgICAgICAgICAgIGlmICgvKE1hY3xpUGFkKS9pLnRlc3Qod2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fYWxlcnRDb250YWluZXIudGV4dENvbnRlbnQgPSB0aGlzLl9tYXAuX2dldFVJU3RyaW5nKCdTY3JvbGxab29tQmxvY2tlci5DbWRNZXNzYWdlJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX2FsZXJ0Q29udGFpbmVyLnRleHRDb250ZW50ID0gdGhpcy5fbWFwLl9nZXRVSVN0cmluZygnU2Nyb2xsWm9vbUJsb2NrZXIuQ3RybE1lc3NhZ2UnKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gZHluYW1pY2FsbHkgc2V0IHRoZSBmb250IHNpemUgb2YgdGhlIHNjcm9sbCB6b29tIGJsb2NrZXIgYWxlcnQgbWVzc2FnZVxuICAgICAgICAgICAgdGhpcy5fYWxlcnRDb250YWluZXIuc3R5bGUuZm9udFNpemUgPSBgJHtNYXRoLm1heCgxMCwgTWF0aC5taW4oMjQsIE1hdGguZmxvb3IodGhpcy5fZWwuY2xpZW50V2lkdGggKiAwLjA1KSkpfXB4YDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9zaG93QmxvY2tlckFsZXJ0KCkge1xuICAgICAgICB0aGlzLl9hbGVydENvbnRhaW5lci5zdHlsZS52aXNpYmlsaXR5ID0gJ3Zpc2libGUnO1xuICAgICAgICB0aGlzLl9hbGVydENvbnRhaW5lci5jbGFzc0xpc3QuYWRkKCdtYXBib3hnbC1zY3JvbGwtem9vbS1ibG9ja2VyLXNob3cnKTtcbiAgICAgICAgdGhpcy5fYWxlcnRDb250YWluZXIuc2V0QXR0cmlidXRlKFwicm9sZVwiLCBcImFsZXJ0XCIpO1xuXG4gICAgICAgIGNsZWFyVGltZW91dCh0aGlzLl9hbGVydFRpbWVyKTtcblxuICAgICAgICB0aGlzLl9hbGVydFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9hbGVydENvbnRhaW5lci5jbGFzc0xpc3QucmVtb3ZlKCdtYXBib3hnbC1zY3JvbGwtem9vbS1ibG9ja2VyLXNob3cnKTtcbiAgICAgICAgICAgIHRoaXMuX2FsZXJ0Q29udGFpbmVyLnNldEF0dHJpYnV0ZShcInJvbGVcIiwgXCJudWxsXCIpO1xuICAgICAgICB9LCAyMDApO1xuICAgIH1cblxufVxuXG5leHBvcnQgZGVmYXVsdCBTY3JvbGxab29tSGFuZGxlcjtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCB0eXBlIENsaWNrWm9vbUhhbmRsZXIgZnJvbSAnLi4vY2xpY2tfem9vbS5qcyc7XG5pbXBvcnQgdHlwZSBUYXBab29tSGFuZGxlciBmcm9tICcuLy4uL3RhcF96b29tLmpzJztcblxuLyoqXG4gKiBUaGUgYERvdWJsZUNsaWNrWm9vbUhhbmRsZXJgIGFsbG93cyB0aGUgdXNlciB0byB6b29tIHRoZSBtYXAgYXQgYSBwb2ludCBieVxuICogZG91YmxlIGNsaWNraW5nIG9yIGRvdWJsZSB0YXBwaW5nLlxuICpcbiAqIEBzZWUgW0V4YW1wbGU6IFRvZ2dsZSBpbnRlcmFjdGlvbnNdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL3RvZ2dsZS1pbnRlcmFjdGlvbi1oYW5kbGVycy8pXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIERvdWJsZUNsaWNrWm9vbUhhbmRsZXIge1xuXG4gICAgX2NsaWNrWm9vbTogQ2xpY2tab29tSGFuZGxlcjtcbiAgICBfdGFwWm9vbTogVGFwWm9vbUhhbmRsZXI7XG5cbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICovXG4gICAgY29uc3RydWN0b3IoY2xpY2tab29tOiBDbGlja1pvb21IYW5kbGVyLCBUYXBab29tOiBUYXBab29tSGFuZGxlcikge1xuICAgICAgICB0aGlzLl9jbGlja1pvb20gPSBjbGlja1pvb207XG4gICAgICAgIHRoaXMuX3RhcFpvb20gPSBUYXBab29tO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEVuYWJsZXMgdGhlIFwiZG91YmxlIGNsaWNrIHRvIHpvb21cIiBpbnRlcmFjdGlvbi5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogbWFwLmRvdWJsZUNsaWNrWm9vbS5lbmFibGUoKTtcbiAgICAgKi9cbiAgICBlbmFibGUoKSB7XG4gICAgICAgIHRoaXMuX2NsaWNrWm9vbS5lbmFibGUoKTtcbiAgICAgICAgdGhpcy5fdGFwWm9vbS5lbmFibGUoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEaXNhYmxlcyB0aGUgXCJkb3VibGUgY2xpY2sgdG8gem9vbVwiIGludGVyYWN0aW9uLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAuZG91YmxlQ2xpY2tab29tLmRpc2FibGUoKTtcbiAgICAgKi9cbiAgICBkaXNhYmxlKCkge1xuICAgICAgICB0aGlzLl9jbGlja1pvb20uZGlzYWJsZSgpO1xuICAgICAgICB0aGlzLl90YXBab29tLmRpc2FibGUoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgQm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIFwiZG91YmxlIGNsaWNrIHRvIHpvb21cIiBpbnRlcmFjdGlvbiBpcyBlbmFibGVkLlxuICAgICAqXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBcImRvdWJsZSBjbGljayB0byB6b29tXCIgaW50ZXJhY3Rpb24gaXMgZW5hYmxlZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGlzRG91YmxlQ2xpY2tab29tRW5hYmxlZCA9IG1hcC5kb3VibGVDbGlja1pvb20uaXNFbmFibGVkKCk7XG4gICAgICovXG4gICAgaXNFbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2xpY2tab29tLmlzRW5hYmxlZCgpICYmIHRoaXMuX3RhcFpvb20uaXNFbmFibGVkKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIEJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIHRoZSBcImRvdWJsZSBjbGljayB0byB6b29tXCIgaW50ZXJhY3Rpb24gaXMgYWN0aXZlIChjdXJyZW50bHkgYmVpbmcgdXNlZCkuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIFwiZG91YmxlIGNsaWNrIHRvIHpvb21cIiBpbnRlcmFjdGlvbiBpcyBhY3RpdmUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBpc0RvdWJsZUNsaWNrWm9vbUFjdGl2ZSA9IG1hcC5kb3VibGVDbGlja1pvb20uaXNBY3RpdmUoKTtcbiAgICAgKi9cbiAgICBpc0FjdGl2ZSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NsaWNrWm9vbS5pc0FjdGl2ZSgpIHx8IHRoaXMuX3RhcFpvb20uaXNBY3RpdmUoKTtcbiAgICB9XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgdHlwZSBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCB0eXBlIE1hcCBmcm9tICcuLi9tYXAuanMnO1xuaW1wb3J0IHR5cGUge0hhbmRsZXJSZXN1bHR9IGZyb20gJy4uL2hhbmRsZXJfbWFuYWdlci5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIENsaWNrWm9vbUhhbmRsZXIge1xuXG4gICAgX2VuYWJsZWQ6IGJvb2xlYW47XG4gICAgX2FjdGl2ZTogYm9vbGVhbjtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnJlc2V0KCk7XG4gICAgfVxuXG4gICAgcmVzZXQoKSB7XG4gICAgICAgIHRoaXMuX2FjdGl2ZSA9IGZhbHNlO1xuICAgIH1cblxuICAgIGJsdXIoKSB7XG4gICAgICAgIHRoaXMucmVzZXQoKTtcbiAgICB9XG5cbiAgICBkYmxjbGljayhlOiBNb3VzZUV2ZW50LCBwb2ludDogUG9pbnQpOiBIYW5kbGVyUmVzdWx0IHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY2FtZXJhQW5pbWF0aW9uOiAobWFwOiBNYXApID0+IHtcbiAgICAgICAgICAgICAgICBtYXAuZWFzZVRvKHtcbiAgICAgICAgICAgICAgICAgICAgZHVyYXRpb246IDMwMCxcbiAgICAgICAgICAgICAgICAgICAgem9vbTogbWFwLmdldFpvb20oKSArIChlLnNoaWZ0S2V5ID8gLTEgOiAxKSxcbiAgICAgICAgICAgICAgICAgICAgYXJvdW5kOiBtYXAudW5wcm9qZWN0KHBvaW50KVxuICAgICAgICAgICAgICAgIH0sIHtvcmlnaW5hbEV2ZW50OiBlfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZW5hYmxlKCkge1xuICAgICAgICB0aGlzLl9lbmFibGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBkaXNhYmxlKCkge1xuICAgICAgICB0aGlzLl9lbmFibGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMucmVzZXQoKTtcbiAgICB9XG5cbiAgICBpc0VuYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbmFibGVkO1xuICAgIH1cblxuICAgIGlzQWN0aXZlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWN0aXZlO1xuICAgIH1cbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCB7VGFwUmVjb2duaXplciwgTUFYX1RBUF9JTlRFUlZBTH0gZnJvbSAnLi90YXBfcmVjb2duaXplci5qcyc7XG5pbXBvcnQgdHlwZSBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCB0eXBlIHtIYW5kbGVyUmVzdWx0fSBmcm9tICcuLi9oYW5kbGVyX21hbmFnZXIuanMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUYXBEcmFnWm9vbUhhbmRsZXIge1xuXG4gICAgX2VuYWJsZWQ6IGJvb2xlYW47XG4gICAgX2FjdGl2ZTogYm9vbGVhbjtcbiAgICBfc3dpcGVQb2ludDogP1BvaW50O1xuICAgIF9zd2lwZVRvdWNoOiBudW1iZXI7XG4gICAgX3RhcFRpbWU6IG51bWJlcjtcbiAgICBfdGFwOiBUYXBSZWNvZ25pemVyO1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG5cbiAgICAgICAgdGhpcy5fdGFwID0gbmV3IFRhcFJlY29nbml6ZXIoe1xuICAgICAgICAgICAgbnVtVG91Y2hlczogMSxcbiAgICAgICAgICAgIG51bVRhcHM6IDFcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgIH1cblxuICAgIHJlc2V0KCkge1xuICAgICAgICB0aGlzLl9hY3RpdmUgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fc3dpcGVQb2ludCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5fc3dpcGVUb3VjaCA9IDA7XG4gICAgICAgIHRoaXMuX3RhcFRpbWUgPSAwO1xuICAgICAgICB0aGlzLl90YXAucmVzZXQoKTtcbiAgICB9XG5cbiAgICB0b3VjaHN0YXJ0KGU6IFRvdWNoRXZlbnQsIHBvaW50czogQXJyYXk8UG9pbnQ+LCBtYXBUb3VjaGVzOiBBcnJheTxUb3VjaD4pIHtcbiAgICAgICAgaWYgKHRoaXMuX3N3aXBlUG9pbnQpIHJldHVybjtcblxuICAgICAgICBpZiAodGhpcy5fdGFwVGltZSAmJiBlLnRpbWVTdGFtcCAtIHRoaXMuX3RhcFRpbWUgPiBNQVhfVEFQX0lOVEVSVkFMKSB7XG4gICAgICAgICAgICB0aGlzLnJlc2V0KCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuX3RhcFRpbWUpIHtcbiAgICAgICAgICAgIHRoaXMuX3RhcC50b3VjaHN0YXJ0KGUsIHBvaW50cywgbWFwVG91Y2hlcyk7XG4gICAgICAgIH0gZWxzZSBpZiAobWFwVG91Y2hlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLl9zd2lwZVBvaW50ID0gcG9pbnRzWzBdO1xuICAgICAgICAgICAgdGhpcy5fc3dpcGVUb3VjaCA9IG1hcFRvdWNoZXNbMF0uaWRlbnRpZmllcjtcbiAgICAgICAgfVxuXG4gICAgfVxuXG4gICAgdG91Y2htb3ZlKGU6IFRvdWNoRXZlbnQsIHBvaW50czogQXJyYXk8UG9pbnQ+LCBtYXBUb3VjaGVzOiBBcnJheTxUb3VjaD4pOiA/SGFuZGxlclJlc3VsdCB7XG4gICAgICAgIGlmICghdGhpcy5fdGFwVGltZSkge1xuICAgICAgICAgICAgdGhpcy5fdGFwLnRvdWNobW92ZShlLCBwb2ludHMsIG1hcFRvdWNoZXMpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX3N3aXBlUG9pbnQpIHtcbiAgICAgICAgICAgIGlmIChtYXBUb3VjaGVzWzBdLmlkZW50aWZpZXIgIT09IHRoaXMuX3N3aXBlVG91Y2gpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IG5ld1N3aXBlUG9pbnQgPSBwb2ludHNbMF07XG4gICAgICAgICAgICBjb25zdCBkaXN0ID0gbmV3U3dpcGVQb2ludC55IC0gdGhpcy5fc3dpcGVQb2ludC55O1xuICAgICAgICAgICAgdGhpcy5fc3dpcGVQb2ludCA9IG5ld1N3aXBlUG9pbnQ7XG5cbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIHRoaXMuX2FjdGl2ZSA9IHRydWU7XG5cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgem9vbURlbHRhOiBkaXN0IC8gMTI4XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdG91Y2hlbmQoZTogVG91Y2hFdmVudCwgcG9pbnRzOiBBcnJheTxQb2ludD4sIG1hcFRvdWNoZXM6IEFycmF5PFRvdWNoPikge1xuICAgICAgICBpZiAoIXRoaXMuX3RhcFRpbWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHBvaW50ID0gdGhpcy5fdGFwLnRvdWNoZW5kKGUsIHBvaW50cywgbWFwVG91Y2hlcyk7XG4gICAgICAgICAgICBpZiAocG9pbnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl90YXBUaW1lID0gZS50aW1lU3RhbXA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5fc3dpcGVQb2ludCkge1xuICAgICAgICAgICAgaWYgKG1hcFRvdWNoZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgdG91Y2hjYW5jZWwoKSB7XG4gICAgICAgIHRoaXMucmVzZXQoKTtcbiAgICB9XG5cbiAgICBlbmFibGUoKSB7XG4gICAgICAgIHRoaXMuX2VuYWJsZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIGRpc2FibGUoKSB7XG4gICAgICAgIHRoaXMuX2VuYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgIH1cblxuICAgIGlzRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VuYWJsZWQ7XG4gICAgfVxuXG4gICAgaXNBY3RpdmUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hY3RpdmU7XG4gICAgfVxufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHR5cGUge01vdXNlUGFuSGFuZGxlcn0gZnJvbSAnLi4vbW91c2UuanMnO1xuaW1wb3J0IHR5cGUgVG91Y2hQYW5IYW5kbGVyIGZyb20gJy4vLi4vdG91Y2hfcGFuLmpzJztcblxuZXhwb3J0IHR5cGUgRHJhZ1Bhbk9wdGlvbnMgPSB7XG4gICAgbGluZWFyaXR5PzogbnVtYmVyO1xuICAgIGVhc2luZz86ICh0OiBudW1iZXIpID0+IG51bWJlcjtcbiAgICBkZWNlbGVyYXRpb24/OiBudW1iZXI7XG4gICAgbWF4U3BlZWQ/OiBudW1iZXI7XG59O1xuXG4vKipcbiAqIFRoZSBgRHJhZ1BhbkhhbmRsZXJgIGFsbG93cyB0aGUgdXNlciB0byBwYW4gdGhlIG1hcCBieSBjbGlja2luZyBhbmQgZHJhZ2dpbmdcbiAqIHRoZSBjdXJzb3IuXG4gKlxuICogQHNlZSBbRXhhbXBsZTogVG9nZ2xlIGludGVyYWN0aW9uc10oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvdG9nZ2xlLWludGVyYWN0aW9uLWhhbmRsZXJzLylcbiAqIEBzZWUgW0V4YW1wbGU6IEhpZ2hsaWdodCBmZWF0dXJlcyB3aXRoaW4gYSBib3VuZGluZyBib3hdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL3VzaW5nLWJveC1xdWVyeXJlbmRlcmVkZmVhdHVyZXMvKVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEcmFnUGFuSGFuZGxlciB7XG5cbiAgICBfZWw6IEhUTUxFbGVtZW50O1xuICAgIF9tb3VzZVBhbjogTW91c2VQYW5IYW5kbGVyO1xuICAgIF90b3VjaFBhbjogVG91Y2hQYW5IYW5kbGVyO1xuICAgIF9pbmVydGlhT3B0aW9uczogRHJhZ1Bhbk9wdGlvbnNcblxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihlbDogSFRNTEVsZW1lbnQsIG1vdXNlUGFuOiBNb3VzZVBhbkhhbmRsZXIsIHRvdWNoUGFuOiBUb3VjaFBhbkhhbmRsZXIpIHtcbiAgICAgICAgdGhpcy5fZWwgPSBlbDtcbiAgICAgICAgdGhpcy5fbW91c2VQYW4gPSBtb3VzZVBhbjtcbiAgICAgICAgdGhpcy5fdG91Y2hQYW4gPSB0b3VjaFBhbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFbmFibGVzIHRoZSBcImRyYWcgdG8gcGFuXCIgaW50ZXJhY3Rpb24gYW5kIGFjY2VwdHMgb3B0aW9ucyB0byBjb250cm9sIHRoZSBiZWhhdmlvciBvZiB0aGUgcGFubmluZyBpbmVydGlhLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSBPcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMubGluZWFyaXR5PTBdIEZhY3RvciB1c2VkIHRvIHNjYWxlIHRoZSBkcmFnIHZlbG9jaXR5LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLmVhc2luZ10gT3B0aW9uYWwgZWFzaW5nIGZ1bmN0aW9uIGFwcGxpZWQgdG8ge0BsaW5rIE1hcCNwYW5Ub30gd2hlbiBhcHBseWluZyB0aGUgZHJhZy4gRGVmYXVsdHMgdG8gYmV6aWVyIGZ1bmN0aW9uIHVzaW5nIFtAbWFwYm94L3VuaXRiZXppZXJdKGh0dHBzOi8vZ2l0aHViLmNvbS9tYXBib3gvdW5pdGJlemllcikuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLm1heFNwZWVkPTE0MDBdIFRoZSBtYXhpbXVtIHZhbHVlIG9mIHRoZSBkcmFnIHZlbG9jaXR5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5kZWNlbGVyYXRpb249MjUwMF0gVGhlIHJhdGUgYXQgd2hpY2ggdGhlIHNwZWVkIHJlZHVjZXMgYWZ0ZXIgdGhlIHBhbiBlbmRzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAuZHJhZ1Bhbi5lbmFibGUoKTtcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIG1hcC5kcmFnUGFuLmVuYWJsZSh7XG4gICAgICogICAgIGxpbmVhcml0eTogMC4zLFxuICAgICAqICAgICBlYXNpbmc6IHQgPT4gdCxcbiAgICAgKiAgICAgbWF4U3BlZWQ6IDE0MDAsXG4gICAgICogICAgIGRlY2VsZXJhdGlvbjogMjUwMFxuICAgICAqIH0pO1xuICAgICAqIEBzZWUgW0V4YW1wbGU6IEhpZ2hsaWdodCBmZWF0dXJlcyB3aXRoaW4gYSBib3VuZGluZyBib3hdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL3VzaW5nLWJveC1xdWVyeXJlbmRlcmVkZmVhdHVyZXMvKVxuICAgICAqL1xuICAgIGVuYWJsZShvcHRpb25zPzogRHJhZ1Bhbk9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy5faW5lcnRpYU9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICAgICAgICB0aGlzLl9tb3VzZVBhbi5lbmFibGUoKTtcbiAgICAgICAgdGhpcy5fdG91Y2hQYW4uZW5hYmxlKCk7XG4gICAgICAgIHRoaXMuX2VsLmNsYXNzTGlzdC5hZGQoJ21hcGJveGdsLXRvdWNoLWRyYWctcGFuJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGlzYWJsZXMgdGhlIFwiZHJhZyB0byBwYW5cIiBpbnRlcmFjdGlvbi5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogbWFwLmRyYWdQYW4uZGlzYWJsZSgpO1xuICAgICAqL1xuICAgIGRpc2FibGUoKSB7XG4gICAgICAgIHRoaXMuX21vdXNlUGFuLmRpc2FibGUoKTtcbiAgICAgICAgdGhpcy5fdG91Y2hQYW4uZGlzYWJsZSgpO1xuICAgICAgICB0aGlzLl9lbC5jbGFzc0xpc3QucmVtb3ZlKCdtYXBib3hnbC10b3VjaC1kcmFnLXBhbicpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBCb29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGUgXCJkcmFnIHRvIHBhblwiIGludGVyYWN0aW9uIGlzIGVuYWJsZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIFwiZHJhZyB0byBwYW5cIiBpbnRlcmFjdGlvbiBpcyBlbmFibGVkLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgaXNEcmFnUGFuRW5hYmxlZCA9IG1hcC5kcmFnUGFuLmlzRW5hYmxlZCgpO1xuICAgICAqL1xuICAgIGlzRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21vdXNlUGFuLmlzRW5hYmxlZCgpICYmIHRoaXMuX3RvdWNoUGFuLmlzRW5hYmxlZCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBCb29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGUgXCJkcmFnIHRvIHBhblwiIGludGVyYWN0aW9uIGlzIGFjdGl2ZSAoY3VycmVudGx5IGJlaW5nIHVzZWQpLlxuICAgICAqXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBcImRyYWcgdG8gcGFuXCIgaW50ZXJhY3Rpb24gaXMgYWN0aXZlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgaXNEcmFnUGFuQWN0aXZlID0gbWFwLmRyYWdQYW4uaXNBY3RpdmUoKTtcbiAgICAgKi9cbiAgICBpc0FjdGl2ZSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21vdXNlUGFuLmlzQWN0aXZlKCkgfHwgdGhpcy5fdG91Y2hQYW4uaXNBY3RpdmUoKTtcbiAgICB9XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgdHlwZSB7TW91c2VSb3RhdGVIYW5kbGVyLCBNb3VzZVBpdGNoSGFuZGxlcn0gZnJvbSAnLi4vbW91c2UuanMnO1xuXG4vKipcbiAqIFRoZSBgRHJhZ1JvdGF0ZUhhbmRsZXJgIGFsbG93cyB0aGUgdXNlciB0byByb3RhdGUgdGhlIG1hcCBieSBjbGlja2luZyBhbmRcbiAqIGRyYWdnaW5nIHRoZSBjdXJzb3Igd2hpbGUgaG9sZGluZyB0aGUgcmlnaHQgbW91c2UgYnV0dG9uIG9yIGBjdHJsYCBrZXkuXG4gKlxuICogQHNlZSBbRXhhbXBsZTogVG9nZ2xlIGludGVyYWN0aW9uc10oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvdG9nZ2xlLWludGVyYWN0aW9uLWhhbmRsZXJzLylcbiAqIEBzZWUgW0V4YW1wbGU6IERpc2FibGUgbWFwIHJvdGF0aW9uXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9kaXNhYmxlLXJvdGF0aW9uLylcbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRHJhZ1JvdGF0ZUhhbmRsZXIge1xuXG4gICAgX21vdXNlUm90YXRlOiBNb3VzZVJvdGF0ZUhhbmRsZXI7XG4gICAgX21vdXNlUGl0Y2g6IE1vdXNlUGl0Y2hIYW5kbGVyO1xuICAgIF9waXRjaFdpdGhSb3RhdGU6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLmJlYXJpbmdTbmFwXSBUaGUgdGhyZXNob2xkLCBtZWFzdXJlZCBpbiBkZWdyZWVzLCB0aGF0IGRldGVybWluZXMgd2hlbiB0aGUgbWFwJ3NcbiAgICAgKiAgIGJlYXJpbmcgd2lsbCBzbmFwIHRvIG5vcnRoLlxuICAgICAqIEBwYXJhbSB7Ym9vbH0gW29wdGlvbnMucGl0Y2hXaXRoUm90YXRlPXRydWVdIENvbnRyb2wgdGhlIG1hcCBwaXRjaCBpbiBhZGRpdGlvbiB0byB0aGUgYmVhcmluZ1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3B0aW9uczoge3BpdGNoV2l0aFJvdGF0ZTogYm9vbGVhbn0sIG1vdXNlUm90YXRlOiBNb3VzZVJvdGF0ZUhhbmRsZXIsIG1vdXNlUGl0Y2g6IE1vdXNlUGl0Y2hIYW5kbGVyKSB7XG4gICAgICAgIHRoaXMuX3BpdGNoV2l0aFJvdGF0ZSA9IG9wdGlvbnMucGl0Y2hXaXRoUm90YXRlO1xuICAgICAgICB0aGlzLl9tb3VzZVJvdGF0ZSA9IG1vdXNlUm90YXRlO1xuICAgICAgICB0aGlzLl9tb3VzZVBpdGNoID0gbW91c2VQaXRjaDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFbmFibGVzIHRoZSBcImRyYWcgdG8gcm90YXRlXCIgaW50ZXJhY3Rpb24uXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIG1hcC5kcmFnUm90YXRlLmVuYWJsZSgpO1xuICAgICAqL1xuICAgIGVuYWJsZSgpIHtcbiAgICAgICAgdGhpcy5fbW91c2VSb3RhdGUuZW5hYmxlKCk7XG4gICAgICAgIGlmICh0aGlzLl9waXRjaFdpdGhSb3RhdGUpIHRoaXMuX21vdXNlUGl0Y2guZW5hYmxlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGlzYWJsZXMgdGhlIFwiZHJhZyB0byByb3RhdGVcIiBpbnRlcmFjdGlvbi5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogbWFwLmRyYWdSb3RhdGUuZGlzYWJsZSgpO1xuICAgICAqL1xuICAgIGRpc2FibGUoKSB7XG4gICAgICAgIHRoaXMuX21vdXNlUm90YXRlLmRpc2FibGUoKTtcbiAgICAgICAgdGhpcy5fbW91c2VQaXRjaC5kaXNhYmxlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIEJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIHRoZSBcImRyYWcgdG8gcm90YXRlXCIgaW50ZXJhY3Rpb24gaXMgZW5hYmxlZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgdGhlIFwiZHJhZyB0byByb3RhdGVcIiBpbnRlcmFjdGlvbiBpcyBlbmFibGVkLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgaXNEcmFnUm90YXRlRW5hYmxlZCA9IG1hcC5kcmFnUm90YXRlLmlzRW5hYmxlZCgpO1xuICAgICAqL1xuICAgIGlzRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21vdXNlUm90YXRlLmlzRW5hYmxlZCgpICYmICghdGhpcy5fcGl0Y2hXaXRoUm90YXRlIHx8IHRoaXMuX21vdXNlUGl0Y2guaXNFbmFibGVkKCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBCb29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGUgXCJkcmFnIHRvIHJvdGF0ZVwiIGludGVyYWN0aW9uIGlzIGFjdGl2ZSAoY3VycmVudGx5IGJlaW5nIHVzZWQpLlxuICAgICAqXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBcImRyYWcgdG8gcm90YXRlXCIgaW50ZXJhY3Rpb24gaXMgYWN0aXZlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgaXNEcmFnUm90YXRlQWN0aXZlID0gbWFwLmRyYWdSb3RhdGUuaXNBY3RpdmUoKTtcbiAgICAgKi9cbiAgICBpc0FjdGl2ZSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21vdXNlUm90YXRlLmlzQWN0aXZlKCkgfHwgdGhpcy5fbW91c2VQaXRjaC5pc0FjdGl2ZSgpO1xuICAgIH1cbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCB0eXBlIHtUb3VjaFpvb21IYW5kbGVyLCBUb3VjaFJvdGF0ZUhhbmRsZXJ9IGZyb20gJy4uL3RvdWNoX3pvb21fcm90YXRlLmpzJztcbmltcG9ydCB0eXBlIFRhcERyYWdab29tSGFuZGxlciBmcm9tICcuLi90YXBfZHJhZ196b29tLmpzJztcblxuLyoqXG4gKiBUaGUgYFRvdWNoWm9vbVJvdGF0ZUhhbmRsZXJgIGFsbG93cyB0aGUgdXNlciB0byB6b29tIGFuZCByb3RhdGUgdGhlIG1hcCBieVxuICogcGluY2hpbmcgb24gYSB0b3VjaHNjcmVlbi5cbiAqXG4gKiBUaGV5IGNhbiB6b29tIHdpdGggb25lIGZpbmdlciBieSBkb3VibGUgdGFwcGluZyBhbmQgZHJhZ2dpbmcuIE9uIHRoZSBzZWNvbmQgdGFwLFxuICogaG9sZCB0aGUgZmluZ2VyIGRvd24gYW5kIGRyYWcgdXAgb3IgZG93biB0byB6b29tIGluIG9yIG91dC5cbiAqXG4gKiBAc2VlIFtFeGFtcGxlOiBUb2dnbGUgaW50ZXJhY3Rpb25zXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS90b2dnbGUtaW50ZXJhY3Rpb24taGFuZGxlcnMvKVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUb3VjaFpvb21Sb3RhdGVIYW5kbGVyIHtcblxuICAgIF9lbDogSFRNTEVsZW1lbnQ7XG4gICAgX3RvdWNoWm9vbTogVG91Y2hab29tSGFuZGxlcjtcbiAgICBfdG91Y2hSb3RhdGU6IFRvdWNoUm90YXRlSGFuZGxlcjtcbiAgICBfdGFwRHJhZ1pvb206IFRhcERyYWdab29tSGFuZGxlcjtcbiAgICBfcm90YXRpb25EaXNhYmxlZDogYm9vbGVhbjtcbiAgICBfZW5hYmxlZDogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihlbDogSFRNTEVsZW1lbnQsIHRvdWNoWm9vbTogVG91Y2hab29tSGFuZGxlciwgdG91Y2hSb3RhdGU6IFRvdWNoUm90YXRlSGFuZGxlciwgdGFwRHJhZ1pvb206IFRhcERyYWdab29tSGFuZGxlcikge1xuICAgICAgICB0aGlzLl9lbCA9IGVsO1xuICAgICAgICB0aGlzLl90b3VjaFpvb20gPSB0b3VjaFpvb207XG4gICAgICAgIHRoaXMuX3RvdWNoUm90YXRlID0gdG91Y2hSb3RhdGU7XG4gICAgICAgIHRoaXMuX3RhcERyYWdab29tID0gdGFwRHJhZ1pvb207XG4gICAgICAgIHRoaXMuX3JvdGF0aW9uRGlzYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fZW5hYmxlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRW5hYmxlcyB0aGUgXCJwaW5jaCB0byByb3RhdGUgYW5kIHpvb21cIiBpbnRlcmFjdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gT3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLmFyb3VuZF0gSWYgXCJjZW50ZXJcIiBpcyBwYXNzZWQsIG1hcCB3aWxsIHpvb20gYXJvdW5kIHRoZSBjZW50ZXIuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIG1hcC50b3VjaFpvb21Sb3RhdGUuZW5hYmxlKCk7XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAudG91Y2hab29tUm90YXRlLmVuYWJsZSh7YXJvdW5kOiAnY2VudGVyJ30pO1xuICAgICAqL1xuICAgIGVuYWJsZShvcHRpb25zOiA/e2Fyb3VuZD86ICdjZW50ZXInfSkge1xuICAgICAgICB0aGlzLl90b3VjaFpvb20uZW5hYmxlKG9wdGlvbnMpO1xuICAgICAgICBpZiAoIXRoaXMuX3JvdGF0aW9uRGlzYWJsZWQpIHRoaXMuX3RvdWNoUm90YXRlLmVuYWJsZShvcHRpb25zKTtcbiAgICAgICAgdGhpcy5fdGFwRHJhZ1pvb20uZW5hYmxlKCk7XG4gICAgICAgIHRoaXMuX2VsLmNsYXNzTGlzdC5hZGQoJ21hcGJveGdsLXRvdWNoLXpvb20tcm90YXRlJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGlzYWJsZXMgdGhlIFwicGluY2ggdG8gcm90YXRlIGFuZCB6b29tXCIgaW50ZXJhY3Rpb24uXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIG1hcC50b3VjaFpvb21Sb3RhdGUuZGlzYWJsZSgpO1xuICAgICAqL1xuICAgIGRpc2FibGUoKSB7XG4gICAgICAgIHRoaXMuX3RvdWNoWm9vbS5kaXNhYmxlKCk7XG4gICAgICAgIHRoaXMuX3RvdWNoUm90YXRlLmRpc2FibGUoKTtcbiAgICAgICAgdGhpcy5fdGFwRHJhZ1pvb20uZGlzYWJsZSgpO1xuICAgICAgICB0aGlzLl9lbC5jbGFzc0xpc3QucmVtb3ZlKCdtYXBib3hnbC10b3VjaC16b29tLXJvdGF0ZScpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBCb29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGUgXCJwaW5jaCB0byByb3RhdGUgYW5kIHpvb21cIiBpbnRlcmFjdGlvbiBpcyBlbmFibGVkLlxuICAgICAqXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgXCJwaW5jaCB0byByb3RhdGUgYW5kIHpvb21cIiBpbnRlcmFjdGlvbiBpcyBlbmFibGVkLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgaXNUb3VjaFpvb21Sb3RhdGVFbmFibGVkID0gbWFwLnRvdWNoWm9vbVJvdGF0ZS5pc0VuYWJsZWQoKTtcbiAgICAgKi9cbiAgICBpc0VuYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl90b3VjaFpvb20uaXNFbmFibGVkKCkgJiZcbiAgICAgICAgICAgICh0aGlzLl9yb3RhdGlvbkRpc2FibGVkIHx8IHRoaXMuX3RvdWNoUm90YXRlLmlzRW5hYmxlZCgpKSAmJlxuICAgICAgICAgICAgdGhpcy5fdGFwRHJhZ1pvb20uaXNFbmFibGVkKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBoYW5kbGVyIGlzIGVuYWJsZWQgYW5kIGhhcyBkZXRlY3RlZCB0aGUgc3RhcnQgb2YgYSB6b29tL3JvdGF0ZSBnZXN0dXJlLlxuICAgICAqXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiBlbmFibGVkIGFuZCBhIHpvb20vcm90YXRlIGdlc3R1cmUgd2FzIGRldGVjdGVkLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgaXNUb3VjaFpvb21Sb3RhdGVBY3RpdmUgPSBtYXAudG91Y2hab29tUm90YXRlLmlzQWN0aXZlKCk7XG4gICAgICovXG4gICAgaXNBY3RpdmUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl90b3VjaFpvb20uaXNBY3RpdmUoKSB8fCB0aGlzLl90b3VjaFJvdGF0ZS5pc0FjdGl2ZSgpIHx8IHRoaXMuX3RhcERyYWdab29tLmlzQWN0aXZlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGlzYWJsZXMgdGhlIFwicGluY2ggdG8gcm90YXRlXCIgaW50ZXJhY3Rpb24sIGxlYXZpbmcgdGhlIFwicGluY2ggdG8gem9vbVwiXG4gICAgICogaW50ZXJhY3Rpb24gZW5hYmxlZC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogbWFwLnRvdWNoWm9vbVJvdGF0ZS5kaXNhYmxlUm90YXRpb24oKTtcbiAgICAgKi9cbiAgICBkaXNhYmxlUm90YXRpb24oKSB7XG4gICAgICAgIHRoaXMuX3JvdGF0aW9uRGlzYWJsZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLl90b3VjaFJvdGF0ZS5kaXNhYmxlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRW5hYmxlcyB0aGUgXCJwaW5jaCB0byByb3RhdGVcIiBpbnRlcmFjdGlvbi5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogbWFwLnRvdWNoWm9vbVJvdGF0ZS5lbmFibGUoKTtcbiAgICAgKiBtYXAudG91Y2hab29tUm90YXRlLmVuYWJsZVJvdGF0aW9uKCk7XG4gICAgICovXG4gICAgZW5hYmxlUm90YXRpb24oKSB7XG4gICAgICAgIHRoaXMuX3JvdGF0aW9uRGlzYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgaWYgKHRoaXMuX3RvdWNoWm9vbS5pc0VuYWJsZWQoKSkgdGhpcy5fdG91Y2hSb3RhdGUuZW5hYmxlKCk7XG4gICAgfVxufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtFdmVudH0gZnJvbSAnLi4vdXRpbC9ldmVudGVkLmpzJztcbmltcG9ydCAqIGFzIERPTSBmcm9tICcuLi91dGlsL2RvbS5qcyc7XG5pbXBvcnQgdHlwZSBNYXAgZnJvbSAnLi9tYXAuanMnO1xuaW1wb3J0IEhhbmRsZXJJbmVydGlhIGZyb20gJy4vaGFuZGxlcl9pbmVydGlhLmpzJztcbmltcG9ydCB7TWFwRXZlbnRIYW5kbGVyLCBCbG9ja2FibGVNYXBFdmVudEhhbmRsZXJ9IGZyb20gJy4vaGFuZGxlci9tYXBfZXZlbnQuanMnO1xuaW1wb3J0IEJveFpvb21IYW5kbGVyIGZyb20gJy4vaGFuZGxlci9ib3hfem9vbS5qcyc7XG5pbXBvcnQgVGFwWm9vbUhhbmRsZXIgZnJvbSAnLi9oYW5kbGVyL3RhcF96b29tLmpzJztcbmltcG9ydCB7TW91c2VQYW5IYW5kbGVyLCBNb3VzZVJvdGF0ZUhhbmRsZXIsIE1vdXNlUGl0Y2hIYW5kbGVyfSBmcm9tICcuL2hhbmRsZXIvbW91c2UuanMnO1xuaW1wb3J0IFRvdWNoUGFuSGFuZGxlciBmcm9tICcuL2hhbmRsZXIvdG91Y2hfcGFuLmpzJztcbmltcG9ydCB7VG91Y2hab29tSGFuZGxlciwgVG91Y2hSb3RhdGVIYW5kbGVyLCBUb3VjaFBpdGNoSGFuZGxlcn0gZnJvbSAnLi9oYW5kbGVyL3RvdWNoX3pvb21fcm90YXRlLmpzJztcbmltcG9ydCBLZXlib2FyZEhhbmRsZXIgZnJvbSAnLi9oYW5kbGVyL2tleWJvYXJkLmpzJztcbmltcG9ydCBTY3JvbGxab29tSGFuZGxlciBmcm9tICcuL2hhbmRsZXIvc2Nyb2xsX3pvb20uanMnO1xuaW1wb3J0IERvdWJsZUNsaWNrWm9vbUhhbmRsZXIgZnJvbSAnLi9oYW5kbGVyL3NoaW0vZGJsY2xpY2tfem9vbS5qcyc7XG5pbXBvcnQgQ2xpY2tab29tSGFuZGxlciBmcm9tICcuL2hhbmRsZXIvY2xpY2tfem9vbS5qcyc7XG5pbXBvcnQgVGFwRHJhZ1pvb21IYW5kbGVyIGZyb20gJy4vaGFuZGxlci90YXBfZHJhZ196b29tLmpzJztcbmltcG9ydCBEcmFnUGFuSGFuZGxlciBmcm9tICcuL2hhbmRsZXIvc2hpbS9kcmFnX3Bhbi5qcyc7XG5pbXBvcnQgRHJhZ1JvdGF0ZUhhbmRsZXIgZnJvbSAnLi9oYW5kbGVyL3NoaW0vZHJhZ19yb3RhdGUuanMnO1xuaW1wb3J0IFRvdWNoWm9vbVJvdGF0ZUhhbmRsZXIgZnJvbSAnLi9oYW5kbGVyL3NoaW0vdG91Y2hfem9vbV9yb3RhdGUuanMnO1xuaW1wb3J0IHtiaW5kQWxsLCBleHRlbmR9IGZyb20gJy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQgd2luZG93IGZyb20gJy4uL3V0aWwvd2luZG93LmpzJztcbmltcG9ydCBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCB7dmVjM30gZnJvbSAnZ2wtbWF0cml4JztcbmltcG9ydCBNZXJjYXRvckNvb3JkaW5hdGUsIHtsYXRGcm9tTWVyY2F0b3JZLCBtZXJjYXRvclNjYWxlfSBmcm9tICcuLi9nZW8vbWVyY2F0b3JfY29vcmRpbmF0ZS5qcyc7XG5cbmltcG9ydCB0eXBlIHtWZWMzfSBmcm9tICdnbC1tYXRyaXgnO1xuXG5leHBvcnQgdHlwZSBJbnB1dEV2ZW50ID0gTW91c2VFdmVudCB8IFRvdWNoRXZlbnQgfCBLZXlib2FyZEV2ZW50IHwgV2hlZWxFdmVudDtcblxuY29uc3QgaXNNb3ZpbmcgPSAocDogeyBbc3RyaW5nXTogYW55IH0pID0+IHAuem9vbSB8fCBwLmRyYWcgfHwgcC5waXRjaCB8fCBwLnJvdGF0ZTtcblxuY2xhc3MgUmVuZGVyRnJhbWVFdmVudCBleHRlbmRzIEV2ZW50IHtcbiAgICB0eXBlOiAncmVuZGVyRnJhbWUnO1xuICAgIHRpbWVTdGFtcDogbnVtYmVyO1xufVxuXG5jbGFzcyBUcmFja2luZ0VsbGlwc29pZCB7XG4gICAgY29uc3RhbnRzOiBBcnJheTxudW1iZXI+O1xuICAgIHJhZGl1czogbnVtYmVyO1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIC8vIGEsIGIsIGMgaW4gdGhlIGVxdWF0aW9uIHjCsi9hwrIgKyB5wrIvYsKyICsgesKyL2PCsiA9IDFcbiAgICAgICAgdGhpcy5jb25zdGFudHMgPSBbMSwgMSwgMC4wMV07XG4gICAgICAgIHRoaXMucmFkaXVzID0gMDtcbiAgICB9XG5cbiAgICBzZXR1cChjZW50ZXI6IFZlYzMsIHBvaW50T25TdXJmYWNlOiBWZWMzKSB7XG4gICAgICAgIGNvbnN0IGNlbnRlclRvU3VyZmFjZSA9IHZlYzMuc3ViKFtdLCBwb2ludE9uU3VyZmFjZSwgY2VudGVyKTtcbiAgICAgICAgaWYgKGNlbnRlclRvU3VyZmFjZVsyXSA8IDApIHtcbiAgICAgICAgICAgIHRoaXMucmFkaXVzID0gdmVjMy5sZW5ndGgodmVjMy5kaXYoW10sIGNlbnRlclRvU3VyZmFjZSwgdGhpcy5jb25zdGFudHMpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFRoZSBwb2ludCBvbiBzdXJmYWNlIGlzIGFib3ZlIHRoZSBjZW50ZXIuIFRoaXMgY2FuIGhhcHBlbiBmb3IgZXhhbXBsZSB3aGVuIHRoZSBjYW1lcmEgaXNcbiAgICAgICAgICAgIC8vIGJlbG93IHRoZSBjbGlja2VkIHBvaW50IChsaWtlIGEgbW91bnRhaW4pIFVzZSBzbGlnaHRseSBzaG9ydGVyIHJhZGl1cyBmb3IgbGVzcyBhZ2dyZXNzaXZlIG1vdmVtZW50XG4gICAgICAgICAgICB0aGlzLnJhZGl1cyA9IHZlYzMubGVuZ3RoKFtjZW50ZXJUb1N1cmZhY2VbMF0sIGNlbnRlclRvU3VyZmFjZVsxXSwgMF0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2FzdCBhIHJheSBmcm9tIHRoZSBjZW50ZXIgb2YgdGhlIGVsbGlwc29pZCBhbmQgdGhlIGludGVyc2VjdGlvbiBwb2ludC5cbiAgICBwcm9qZWN0UmF5KGRpcjogVmVjMyk6IFZlYzMge1xuICAgICAgICAvLyBQZXJmb3JtIHRoZSBpbnRlcnNlY3Rpb24gdGVzdCBhZ2FpbnN0IGEgdW5pdCBzcGhlcmVcbiAgICAgICAgdmVjMy5kaXYoZGlyLCBkaXIsIHRoaXMuY29uc3RhbnRzKTtcbiAgICAgICAgdmVjMy5ub3JtYWxpemUoZGlyLCBkaXIpO1xuICAgICAgICB2ZWMzLm11bChkaXIsIGRpciwgdGhpcy5jb25zdGFudHMpO1xuXG4gICAgICAgIGNvbnN0IGludGVyc2VjdGlvbiA9IHZlYzMuc2NhbGUoW10sIGRpciwgdGhpcy5yYWRpdXMpO1xuXG4gICAgICAgIGlmIChpbnRlcnNlY3Rpb25bMl0gPiAwKSB7XG4gICAgICAgICAgICAvLyBUaGUgaW50ZXJzZWN0aW9uIHBvaW50IGlzIGFib3ZlIGhvcml6b24gc28gc3BlY2lhbCBoYW5kbGluZyBpcyByZXF1aXJlZC5cbiAgICAgICAgICAgIC8vIE90aGVyd2lzZSBkaXJlY3Rpb24gb2YgdGhlIG1vdmVtZW50IHdvdWxkIGJlIGludmVydGVkIGR1ZSB0byB0aGUgZWxsaXBzb2lkIHNoYXBlXG4gICAgICAgICAgICBjb25zdCBoID0gdmVjMy5zY2FsZShbXSwgWzAsIDAsIDFdLCB2ZWMzLmRvdChpbnRlcnNlY3Rpb24sIFswLCAwLCAxXSkpO1xuICAgICAgICAgICAgY29uc3QgciA9IHZlYzMuc2NhbGUoW10sIHZlYzMubm9ybWFsaXplKFtdLCBbaW50ZXJzZWN0aW9uWzBdLCBpbnRlcnNlY3Rpb25bMV0sIDBdKSwgdGhpcy5yYWRpdXMpO1xuICAgICAgICAgICAgY29uc3QgcCA9IHZlYzMuYWRkKFtdLCBpbnRlcnNlY3Rpb24sIHZlYzMuc2NhbGUoW10sIHZlYzMuc3ViKFtdLCB2ZWMzLmFkZChbXSwgciwgaCksIGludGVyc2VjdGlvbiksIDIpKTtcblxuICAgICAgICAgICAgaW50ZXJzZWN0aW9uWzBdID0gcFswXTtcbiAgICAgICAgICAgIGludGVyc2VjdGlvblsxXSA9IHBbMV07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gaW50ZXJzZWN0aW9uO1xuICAgIH1cbn1cblxuLy8gSGFuZGxlcnMgaW50ZXJwcmV0IGRvbSBldmVudHMgYW5kIHJldHVybiBjYW1lcmEgY2hhbmdlcyB0aGF0IHNob3VsZCBiZVxuLy8gYXBwbGllZCB0byB0aGUgbWFwIChgSGFuZGxlclJlc3VsdGBzKS4gVGhlIGNhbWVyYSBjaGFuZ2VzIGFyZSBhbGwgZGVsdGFzLlxuLy8gVGhlIGhhbmRsZXIgaXRzZWxmIHNob3VsZCBoYXZlIG5vIGtub3dsZWRnZSBvZiB0aGUgbWFwJ3MgY3VycmVudCBzdGF0ZS5cbi8vIFRoaXMgbWFrZXMgaXQgZWFzaWVyIHRvIG1lcmdlIG11bHRpcGxlIHJlc3VsdHMgYW5kIGtlZXBzIGhhbmRsZXJzIHNpbXBsZXIuXG4vLyBGb3IgZXhhbXBsZSwgaWYgdGhlcmUgaXMgYSBtb3VzZWRvd24gYW5kIG1vdXNlbW92ZSwgdGhlIG1vdXNlUGFuIGhhbmRsZXJcbi8vIHdvdWxkIHJldHVybiBhIGBwYW5EZWx0YWAgb24gdGhlIG1vdXNlbW92ZS5cbmV4cG9ydCBpbnRlcmZhY2UgSGFuZGxlciB7XG4gICAgZW5hYmxlKCk6IHZvaWQ7XG4gICAgZGlzYWJsZSgpOiB2b2lkO1xuICAgIGlzRW5hYmxlZCgpOiBib29sZWFuO1xuICAgIGlzQWN0aXZlKCk6IGJvb2xlYW47XG5cbiAgICAvLyBgcmVzZXRgIGNhbiBiZSBjYWxsZWQgYnkgdGhlIG1hbmFnZXIgYXQgYW55IHRpbWUgYW5kIG11c3QgcmVzZXQgZXZlcnl0aGluZyB0byBpdCdzIG9yaWdpbmFsIHN0YXRlXG4gICAgcmVzZXQoKTogdm9pZDtcblxuICAgIC8vIEhhbmRsZXJzIGNhbiBvcHRpb25hbGx5IGltcGxlbWVudCB0aGVzZSBtZXRob2RzLlxuICAgIC8vIFRoZXkgYXJlIGNhbGxlZCB3aXRoIGRvbSBldmVudHMgd2hlbmV2ZXIgdGhvc2UgZG9tIGV2ZW5zIGFyZSByZWNlaXZlZC5cbiAgICArdG91Y2hzdGFydD86IChlOiBUb3VjaEV2ZW50LCBwb2ludHM6IEFycmF5PFBvaW50PiwgbWFwVG91Y2hlczogQXJyYXk8VG91Y2g+KSA9PiA/SGFuZGxlclJlc3VsdDtcbiAgICArdG91Y2htb3ZlPzogKGU6IFRvdWNoRXZlbnQsIHBvaW50czogQXJyYXk8UG9pbnQ+LCBtYXBUb3VjaGVzOiBBcnJheTxUb3VjaD4pID0+ID9IYW5kbGVyUmVzdWx0O1xuICAgICt0b3VjaGVuZD86IChlOiBUb3VjaEV2ZW50LCBwb2ludHM6IEFycmF5PFBvaW50PiwgbWFwVG91Y2hlczogQXJyYXk8VG91Y2g+KSA9PiA/SGFuZGxlclJlc3VsdDtcbiAgICArdG91Y2hjYW5jZWw/OiAoZTogVG91Y2hFdmVudCwgcG9pbnRzOiBBcnJheTxQb2ludD4sIG1hcFRvdWNoZXM6IEFycmF5PFRvdWNoPikgPT4gP0hhbmRsZXJSZXN1bHQ7XG4gICAgK21vdXNlZG93bj86IChlOiBNb3VzZUV2ZW50LCBwb2ludDogUG9pbnQpID0+ID9IYW5kbGVyUmVzdWx0O1xuICAgICttb3VzZW1vdmU/OiAoZTogTW91c2VFdmVudCwgcG9pbnQ6IFBvaW50KSA9PiA/SGFuZGxlclJlc3VsdDtcbiAgICArbW91c2V1cD86IChlOiBNb3VzZUV2ZW50LCBwb2ludDogUG9pbnQpID0+ID9IYW5kbGVyUmVzdWx0O1xuICAgICtkYmxjbGljaz86IChlOiBNb3VzZUV2ZW50LCBwb2ludDogUG9pbnQpID0+ID9IYW5kbGVyUmVzdWx0O1xuICAgICt3aGVlbD86IChlOiBXaGVlbEV2ZW50LCBwb2ludDogUG9pbnQpID0+ID9IYW5kbGVyUmVzdWx0O1xuICAgICtrZXlkb3duPzogKGU6IEtleWJvYXJkRXZlbnQpID0+ID9IYW5kbGVyUmVzdWx0O1xuICAgICtrZXl1cD86IChlOiBLZXlib2FyZEV2ZW50KSA9PiA/SGFuZGxlclJlc3VsdDtcblxuICAgIC8vIGByZW5kZXJGcmFtZWAgaXMgdGhlIG9ubHkgbm9uLWRvbSBldmVudC4gSXQgaXMgY2FsbGVkIGR1cmluZyByZW5kZXJcbiAgICAvLyBmcmFtZXMgYW5kIGNhbiBiZSB1c2VkIHRvIHNtb290aCBjYW1lcmEgY2hhbmdlcyAoc2VlIHNjcm9sbCBoYW5kbGVyKS5cbiAgICArcmVuZGVyRnJhbWU/OiAoKSA9PiA/SGFuZGxlclJlc3VsdDtcbn1cblxuLy8gQWxsIGhhbmRsZXIgbWV0aG9kcyB0aGF0IGFyZSBjYWxsZWQgd2l0aCBldmVudHMgY2FuIG9wdGlvbmFsbHkgcmV0dXJuIGEgYEhhbmRsZXJSZXN1bHRgLlxuZXhwb3J0IHR5cGUgSGFuZGxlclJlc3VsdCA9IHtcbiAgICBwYW5EZWx0YT86IFBvaW50LFxuICAgIHpvb21EZWx0YT86IG51bWJlcixcbiAgICBiZWFyaW5nRGVsdGE/OiBudW1iZXIsXG4gICAgcGl0Y2hEZWx0YT86IG51bWJlcixcbiAgICAvLyB0aGUgcG9pbnQgdG8gbm90IG1vdmUgd2hlbiBjaGFuZ2luZyB0aGUgY2FtZXJhXG4gICAgYXJvdW5kPzogUG9pbnQgfCBudWxsLFxuICAgIC8vIHNhbWUgYXMgYWJvdmUsIGV4Y2VwdCBmb3IgcGluY2ggYWN0aW9ucywgd2hpY2ggYXJlIGdpdmVuIGhpZ2hlciBwcmlvcml0eVxuICAgIHBpbmNoQXJvdW5kPzogUG9pbnQgfCBudWxsLFxuICAgIC8vIHRoZSBwb2ludCB0byBub3QgbW92ZSB3aGVuIGNoYW5naW5nIHRoZSBjYW1lcmEgaW4gbWVyY2F0b3IgY29vcmRpbmF0ZXNcbiAgICBhcm91bmRDb29yZD86IE1lcmNhdG9yQ29vcmRpbmF0ZSB8IG51bGwsXG4gICAgLy8gQSBtZXRob2QgdGhhdCBjYW4gZmlyZSBhIG9uZS1vZmYgZWFzaW5nIGJ5IGRpcmVjdGx5IGNoYW5naW5nIHRoZSBtYXAncyBjYW1lcmEuXG4gICAgY2FtZXJhQW5pbWF0aW9uPzogKG1hcDogTWFwKSA9PiBhbnk7XG5cbiAgICAvLyBUaGUgbGFzdCB0aHJlZSBwcm9wZXJ0aWVzIGFyZSBuZWVkZWQgYnkgb25seSBvbmUgaGFuZGxlcjogc2Nyb2xsem9vbS5cbiAgICAvLyBUaGUgRE9NIGV2ZW50IHRvIGJlIHVzZWQgYXMgdGhlIGBvcmlnaW5hbEV2ZW50YCBvbiBhbnkgY2FtZXJhIGNoYW5nZSBldmVudHMuXG4gICAgb3JpZ2luYWxFdmVudD86IGFueSxcbiAgICAvLyBNYWtlcyB0aGUgbWFuYWdlciB0cmlnZ2VyIGEgZnJhbWUsIGFsbG93aW5nIHRoZSBoYW5kbGVyIHRvIHJldHVybiBtdWx0aXBsZSByZXN1bHRzIG92ZXIgdGltZSAoc2VlIHNjcm9sbHpvb20pLlxuICAgIG5lZWRzUmVuZGVyRnJhbWU/OiBib29sZWFuLFxuICAgIC8vIFRoZSBjYW1lcmEgY2hhbmdlcyB3b24ndCBnZXQgcmVjb3JkZWQgZm9yIGluZXJ0aWFsIHpvb21pbmcuXG4gICAgbm9JbmVydGlhPzogYm9vbGVhblxufTtcblxuZnVuY3Rpb24gaGFzQ2hhbmdlKHJlc3VsdDogSGFuZGxlclJlc3VsdCkge1xuICAgIHJldHVybiAocmVzdWx0LnBhbkRlbHRhICYmIHJlc3VsdC5wYW5EZWx0YS5tYWcoKSkgfHwgcmVzdWx0Lnpvb21EZWx0YSB8fCByZXN1bHQuYmVhcmluZ0RlbHRhIHx8IHJlc3VsdC5waXRjaERlbHRhO1xufVxuXG5jbGFzcyBIYW5kbGVyTWFuYWdlciB7XG4gICAgX21hcDogTWFwO1xuICAgIF9lbDogSFRNTEVsZW1lbnQ7XG4gICAgX2hhbmRsZXJzOiBBcnJheTx7IGhhbmRsZXJOYW1lOiBzdHJpbmcsIGhhbmRsZXI6IEhhbmRsZXIsIGFsbG93ZWQ6IGFueSB9PjtcbiAgICBfZXZlbnRzSW5Qcm9ncmVzczogT2JqZWN0O1xuICAgIF9mcmFtZUlkOiA/bnVtYmVyO1xuICAgIF9pbmVydGlhOiBIYW5kbGVySW5lcnRpYTtcbiAgICBfYmVhcmluZ1NuYXA6IG51bWJlcjtcbiAgICBfaGFuZGxlcnNCeUlkOiB7IFtzdHJpbmddOiBIYW5kbGVyIH07XG4gICAgX3VwZGF0aW5nQ2FtZXJhOiBib29sZWFuO1xuICAgIF9jaGFuZ2VzOiBBcnJheTxbSGFuZGxlclJlc3VsdCwgT2JqZWN0LCBhbnldPjtcbiAgICBfcHJldmlvdXNBY3RpdmVIYW5kbGVyczogeyBbc3RyaW5nXTogSGFuZGxlciB9O1xuICAgIF9saXN0ZW5lcnM6IEFycmF5PFtIVE1MRWxlbWVudCwgc3RyaW5nLCB2b2lkIHwgRXZlbnRMaXN0ZW5lck9wdGlvbnNPclVzZUNhcHR1cmVdPjtcbiAgICBfdHJhY2tpbmdFbGxpcHNvaWQ6IFRyYWNraW5nRWxsaXBzb2lkO1xuICAgIF9kcmFnT3JpZ2luOiA/VmVjMztcblxuICAgIGNvbnN0cnVjdG9yKG1hcDogTWFwLCBvcHRpb25zOiB7IGludGVyYWN0aXZlOiBib29sZWFuLCBwaXRjaFdpdGhSb3RhdGU6IGJvb2xlYW4sIGNsaWNrVG9sZXJhbmNlOiBudW1iZXIsIGJlYXJpbmdTbmFwOiBudW1iZXJ9KSB7XG4gICAgICAgIHRoaXMuX21hcCA9IG1hcDtcbiAgICAgICAgdGhpcy5fZWwgPSB0aGlzLl9tYXAuZ2V0Q2FudmFzQ29udGFpbmVyKCk7XG4gICAgICAgIHRoaXMuX2hhbmRsZXJzID0gW107XG4gICAgICAgIHRoaXMuX2hhbmRsZXJzQnlJZCA9IHt9O1xuICAgICAgICB0aGlzLl9jaGFuZ2VzID0gW107XG5cbiAgICAgICAgdGhpcy5faW5lcnRpYSA9IG5ldyBIYW5kbGVySW5lcnRpYShtYXApO1xuICAgICAgICB0aGlzLl9iZWFyaW5nU25hcCA9IG9wdGlvbnMuYmVhcmluZ1NuYXA7XG4gICAgICAgIHRoaXMuX3ByZXZpb3VzQWN0aXZlSGFuZGxlcnMgPSB7fTtcbiAgICAgICAgdGhpcy5fdHJhY2tpbmdFbGxpcHNvaWQgPSBuZXcgVHJhY2tpbmdFbGxpcHNvaWQoKTtcbiAgICAgICAgdGhpcy5fZHJhZ09yaWdpbiA9IG51bGw7XG5cbiAgICAgICAgLy8gVHJhY2sgd2hldGhlciBtYXAgaXMgY3VycmVudGx5IG1vdmluZywgdG8gY29tcHV0ZSBzdGFydC9tb3ZlL2VuZCBldmVudHNcbiAgICAgICAgdGhpcy5fZXZlbnRzSW5Qcm9ncmVzcyA9IHt9O1xuXG4gICAgICAgIHRoaXMuX2FkZERlZmF1bHRIYW5kbGVycyhvcHRpb25zKTtcblxuICAgICAgICBiaW5kQWxsKFsnaGFuZGxlRXZlbnQnLCAnaGFuZGxlV2luZG93RXZlbnQnXSwgdGhpcyk7XG5cbiAgICAgICAgY29uc3QgZWwgPSB0aGlzLl9lbDtcblxuICAgICAgICB0aGlzLl9saXN0ZW5lcnMgPSBbXG4gICAgICAgICAgICAvLyBUaGlzIG5lZWRzIHRvIGJlIGBwYXNzaXZlOiB0cnVlYCBzbyB0aGF0IGEgZG91YmxlIHRhcCBmaXJlcyB0d29cbiAgICAgICAgICAgIC8vIHBhaXJzIG9mIHRvdWNoc3RhcnQvZW5kIGV2ZW50cyBpbiBpT1MgU2FmYXJpIDEzLiBJZiB0aGlzIGlzIHNldCB0b1xuICAgICAgICAgICAgLy8gYHBhc3NpdmU6IGZhbHNlYCB0aGVuIHRoZSBzZWNvbmQgcGFpciBvZiBldmVudHMgaXMgb25seSBmaXJlZCBpZlxuICAgICAgICAgICAgLy8gcHJldmVudERlZmF1bHQoKSBpcyBjYWxsZWQgb24gdGhlIGZpcnN0IHRvdWNoc3RhcnQuIENhbGxpbmcgcHJldmVudERlZmF1bHQoKVxuICAgICAgICAgICAgLy8gdW5kZXNpcmFibHkgcHJldmVudHMgY2xpY2sgZXZlbnRzLlxuICAgICAgICAgICAgW2VsLCAndG91Y2hzdGFydCcsIHtwYXNzaXZlOiB0cnVlfV0sXG4gICAgICAgICAgICAvLyBUaGlzIG5lZWRzIHRvIGJlIGBwYXNzaXZlOiBmYWxzZWAgc28gdGhhdCBzY3JvbGxzIGFuZCBwaW5jaGVzIGNhbiBiZVxuICAgICAgICAgICAgLy8gcHJldmVudGVkIGluIGJyb3dzZXJzIHRoYXQgZG9uJ3Qgc3VwcG9ydCBgdG91Y2gtYWN0aW9uczogbm9uZWAsIGZvciBleGFtcGxlIGlPUyBTYWZhcmkgMTIuXG4gICAgICAgICAgICBbZWwsICd0b3VjaG1vdmUnLCB7cGFzc2l2ZTogZmFsc2V9XSxcbiAgICAgICAgICAgIFtlbCwgJ3RvdWNoZW5kJywgdW5kZWZpbmVkXSxcbiAgICAgICAgICAgIFtlbCwgJ3RvdWNoY2FuY2VsJywgdW5kZWZpbmVkXSxcblxuICAgICAgICAgICAgW2VsLCAnbW91c2Vkb3duJywgdW5kZWZpbmVkXSxcbiAgICAgICAgICAgIFtlbCwgJ21vdXNlbW92ZScsIHVuZGVmaW5lZF0sXG4gICAgICAgICAgICBbZWwsICdtb3VzZXVwJywgdW5kZWZpbmVkXSxcblxuICAgICAgICAgICAgLy8gQmluZCB3aW5kb3ctbGV2ZWwgZXZlbnQgbGlzdGVuZXJzIGZvciBtb3ZlIGFuZCB1cC9lbmQgZXZlbnRzLiBJbiB0aGUgYWJzZW5jZSBvZlxuICAgICAgICAgICAgLy8gdGhlIHBvaW50ZXIgY2FwdHVyZSBBUEksIHdoaWNoIGlzIG5vdCBzdXBwb3J0ZWQgYnkgYWxsIG5lY2Vzc2FyeSBwbGF0Zm9ybXMsXG4gICAgICAgICAgICAvLyB3aW5kb3ctbGV2ZWwgZXZlbnQgbGlzdGVuZXJzIGdpdmUgdXMgdGhlIGJlc3Qgc2hvdCBhdCBjYXB0dXJpbmcgZXZlbnRzIHRoYXRcbiAgICAgICAgICAgIC8vIGZhbGwgb3V0c2lkZSB0aGUgbWFwIGNhbnZhcyBlbGVtZW50LiBVc2UgYHtjYXB0dXJlOiB0cnVlfWAgZm9yIHRoZSBtb3ZlIGV2ZW50XG4gICAgICAgICAgICAvLyB0byBwcmV2ZW50IG1hcCBtb3ZlIGV2ZW50cyBmcm9tIGJlaW5nIGZpcmVkIGR1cmluZyBhIGRyYWcuXG4gICAgICAgICAgICBbd2luZG93LmRvY3VtZW50LCAnbW91c2Vtb3ZlJywge2NhcHR1cmU6IHRydWV9XSxcbiAgICAgICAgICAgIFt3aW5kb3cuZG9jdW1lbnQsICdtb3VzZXVwJywgdW5kZWZpbmVkXSxcblxuICAgICAgICAgICAgW2VsLCAnbW91c2VvdmVyJywgdW5kZWZpbmVkXSxcbiAgICAgICAgICAgIFtlbCwgJ21vdXNlb3V0JywgdW5kZWZpbmVkXSxcbiAgICAgICAgICAgIFtlbCwgJ2RibGNsaWNrJywgdW5kZWZpbmVkXSxcbiAgICAgICAgICAgIFtlbCwgJ2NsaWNrJywgdW5kZWZpbmVkXSxcblxuICAgICAgICAgICAgW2VsLCAna2V5ZG93bicsIHtjYXB0dXJlOiBmYWxzZX1dLFxuICAgICAgICAgICAgW2VsLCAna2V5dXAnLCB1bmRlZmluZWRdLFxuXG4gICAgICAgICAgICBbZWwsICd3aGVlbCcsIHtwYXNzaXZlOiBmYWxzZX1dLFxuICAgICAgICAgICAgW2VsLCAnY29udGV4dG1lbnUnLCB1bmRlZmluZWRdLFxuXG4gICAgICAgICAgICBbd2luZG93LCAnYmx1cicsIHVuZGVmaW5lZF1cbiAgICAgICAgXTtcblxuICAgICAgICBmb3IgKGNvbnN0IFt0YXJnZXQsIHR5cGUsIGxpc3RlbmVyT3B0aW9uc10gb2YgdGhpcy5fbGlzdGVuZXJzKSB7XG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICBjb25zdCBsaXN0ZW5lciA9IHRhcmdldCA9PT0gd2luZG93LmRvY3VtZW50ID8gdGhpcy5oYW5kbGVXaW5kb3dFdmVudCA6IHRoaXMuaGFuZGxlRXZlbnQ7XG4gICAgICAgICAgICB0YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcigodHlwZTogYW55KSwgKGxpc3RlbmVyOiBhbnkpLCBsaXN0ZW5lck9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgZm9yIChjb25zdCBbdGFyZ2V0LCB0eXBlLCBsaXN0ZW5lck9wdGlvbnNdIG9mIHRoaXMuX2xpc3RlbmVycykge1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgY29uc3QgbGlzdGVuZXIgPSB0YXJnZXQgPT09IHdpbmRvdy5kb2N1bWVudCA/IHRoaXMuaGFuZGxlV2luZG93RXZlbnQgOiB0aGlzLmhhbmRsZUV2ZW50O1xuICAgICAgICAgICAgdGFyZ2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIoKHR5cGU6IGFueSksIChsaXN0ZW5lcjogYW55KSwgbGlzdGVuZXJPcHRpb25zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9hZGREZWZhdWx0SGFuZGxlcnMob3B0aW9uczogeyBpbnRlcmFjdGl2ZTogYm9vbGVhbiwgcGl0Y2hXaXRoUm90YXRlOiBib29sZWFuLCBjbGlja1RvbGVyYW5jZTogbnVtYmVyIH0pIHtcbiAgICAgICAgY29uc3QgbWFwID0gdGhpcy5fbWFwO1xuICAgICAgICBjb25zdCBlbCA9IG1hcC5nZXRDYW52YXNDb250YWluZXIoKTtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICB0aGlzLl9hZGQoJ21hcEV2ZW50JywgbmV3IE1hcEV2ZW50SGFuZGxlcihtYXAsIG9wdGlvbnMpKTtcblxuICAgICAgICBjb25zdCBib3hab29tID0gbWFwLmJveFpvb20gPSBuZXcgQm94Wm9vbUhhbmRsZXIobWFwLCBvcHRpb25zKTtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICB0aGlzLl9hZGQoJ2JveFpvb20nLCBib3hab29tKTtcblxuICAgICAgICBjb25zdCB0YXBab29tID0gbmV3IFRhcFpvb21IYW5kbGVyKCk7XG4gICAgICAgIGNvbnN0IGNsaWNrWm9vbSA9IG5ldyBDbGlja1pvb21IYW5kbGVyKCk7XG4gICAgICAgIG1hcC5kb3VibGVDbGlja1pvb20gPSBuZXcgRG91YmxlQ2xpY2tab29tSGFuZGxlcihjbGlja1pvb20sIHRhcFpvb20pO1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIHRoaXMuX2FkZCgndGFwWm9vbScsIHRhcFpvb20pO1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIHRoaXMuX2FkZCgnY2xpY2tab29tJywgY2xpY2tab29tKTtcblxuICAgICAgICBjb25zdCB0YXBEcmFnWm9vbSA9IG5ldyBUYXBEcmFnWm9vbUhhbmRsZXIoKTtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICB0aGlzLl9hZGQoJ3RhcERyYWdab29tJywgdGFwRHJhZ1pvb20pO1xuXG4gICAgICAgIGNvbnN0IHRvdWNoUGl0Y2ggPSBtYXAudG91Y2hQaXRjaCA9IG5ldyBUb3VjaFBpdGNoSGFuZGxlcihtYXApO1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIHRoaXMuX2FkZCgndG91Y2hQaXRjaCcsIHRvdWNoUGl0Y2gpO1xuXG4gICAgICAgIGNvbnN0IG1vdXNlUm90YXRlID0gbmV3IE1vdXNlUm90YXRlSGFuZGxlcihvcHRpb25zKTtcbiAgICAgICAgY29uc3QgbW91c2VQaXRjaCA9IG5ldyBNb3VzZVBpdGNoSGFuZGxlcihvcHRpb25zKTtcbiAgICAgICAgbWFwLmRyYWdSb3RhdGUgPSBuZXcgRHJhZ1JvdGF0ZUhhbmRsZXIob3B0aW9ucywgbW91c2VSb3RhdGUsIG1vdXNlUGl0Y2gpO1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIHRoaXMuX2FkZCgnbW91c2VSb3RhdGUnLCBtb3VzZVJvdGF0ZSwgWydtb3VzZVBpdGNoJ10pO1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIHRoaXMuX2FkZCgnbW91c2VQaXRjaCcsIG1vdXNlUGl0Y2gsIFsnbW91c2VSb3RhdGUnXSk7XG5cbiAgICAgICAgY29uc3QgbW91c2VQYW4gPSBuZXcgTW91c2VQYW5IYW5kbGVyKG9wdGlvbnMpO1xuICAgICAgICBjb25zdCB0b3VjaFBhbiA9IG5ldyBUb3VjaFBhbkhhbmRsZXIobWFwLCBvcHRpb25zKTtcbiAgICAgICAgbWFwLmRyYWdQYW4gPSBuZXcgRHJhZ1BhbkhhbmRsZXIoZWwsIG1vdXNlUGFuLCB0b3VjaFBhbik7XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgdGhpcy5fYWRkKCdtb3VzZVBhbicsIG1vdXNlUGFuKTtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICB0aGlzLl9hZGQoJ3RvdWNoUGFuJywgdG91Y2hQYW4sIFsndG91Y2hab29tJywgJ3RvdWNoUm90YXRlJ10pO1xuXG4gICAgICAgIGNvbnN0IHRvdWNoUm90YXRlID0gbmV3IFRvdWNoUm90YXRlSGFuZGxlcigpO1xuICAgICAgICBjb25zdCB0b3VjaFpvb20gPSBuZXcgVG91Y2hab29tSGFuZGxlcigpO1xuICAgICAgICBtYXAudG91Y2hab29tUm90YXRlID0gbmV3IFRvdWNoWm9vbVJvdGF0ZUhhbmRsZXIoZWwsIHRvdWNoWm9vbSwgdG91Y2hSb3RhdGUsIHRhcERyYWdab29tKTtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICB0aGlzLl9hZGQoJ3RvdWNoUm90YXRlJywgdG91Y2hSb3RhdGUsIFsndG91Y2hQYW4nLCAndG91Y2hab29tJ10pO1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIHRoaXMuX2FkZCgndG91Y2hab29tJywgdG91Y2hab29tLCBbJ3RvdWNoUGFuJywgJ3RvdWNoUm90YXRlJ10pO1xuXG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgdGhpcy5fYWRkKCdibG9ja2FibGVNYXBFdmVudCcsIG5ldyBCbG9ja2FibGVNYXBFdmVudEhhbmRsZXIobWFwKSk7XG5cbiAgICAgICAgY29uc3Qgc2Nyb2xsWm9vbSA9IG1hcC5zY3JvbGxab29tID0gbmV3IFNjcm9sbFpvb21IYW5kbGVyKG1hcCwgdGhpcyk7XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgdGhpcy5fYWRkKCdzY3JvbGxab29tJywgc2Nyb2xsWm9vbSwgWydtb3VzZVBhbiddKTtcblxuICAgICAgICBjb25zdCBrZXlib2FyZCA9IG1hcC5rZXlib2FyZCA9IG5ldyBLZXlib2FyZEhhbmRsZXIoKTtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICB0aGlzLl9hZGQoJ2tleWJvYXJkJywga2V5Ym9hcmQpO1xuXG4gICAgICAgIGZvciAoY29uc3QgbmFtZSBvZiBbJ2JveFpvb20nLCAnZG91YmxlQ2xpY2tab29tJywgJ3RhcERyYWdab29tJywgJ3RvdWNoUGl0Y2gnLCAnZHJhZ1JvdGF0ZScsICdkcmFnUGFuJywgJ3RvdWNoWm9vbVJvdGF0ZScsICdzY3JvbGxab29tJywgJ2tleWJvYXJkJ10pIHtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLmludGVyYWN0aXZlICYmIChvcHRpb25zOiBhbnkpW25hbWVdKSB7XG4gICAgICAgICAgICAgICAgKG1hcDogYW55KVtuYW1lXS5lbmFibGUoKG9wdGlvbnM6IGFueSlbbmFtZV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgX2FkZChoYW5kbGVyTmFtZTogc3RyaW5nLCBoYW5kbGVyOiBIYW5kbGVyLCBhbGxvd2VkPzogQXJyYXk8c3RyaW5nPikge1xuICAgICAgICB0aGlzLl9oYW5kbGVycy5wdXNoKHtoYW5kbGVyTmFtZSwgaGFuZGxlciwgYWxsb3dlZH0pO1xuICAgICAgICB0aGlzLl9oYW5kbGVyc0J5SWRbaGFuZGxlck5hbWVdID0gaGFuZGxlcjtcbiAgICB9XG5cbiAgICBzdG9wKGFsbG93RW5kQW5pbWF0aW9uOiBib29sZWFuKSB7XG4gICAgICAgIC8vIGRvIG5vdGhpbmcgaWYgdGhpcyBtZXRob2Qgd2FzIHRyaWdnZXJlZCBieSBhIGdlc3R1cmUgdXBkYXRlXG4gICAgICAgIGlmICh0aGlzLl91cGRhdGluZ0NhbWVyYSkgcmV0dXJuO1xuXG4gICAgICAgIGZvciAoY29uc3Qge2hhbmRsZXJ9IG9mIHRoaXMuX2hhbmRsZXJzKSB7XG4gICAgICAgICAgICBoYW5kbGVyLnJlc2V0KCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5faW5lcnRpYS5jbGVhcigpO1xuICAgICAgICB0aGlzLl9maXJlRXZlbnRzKHt9LCB7fSwgYWxsb3dFbmRBbmltYXRpb24pO1xuICAgICAgICB0aGlzLl9jaGFuZ2VzID0gW107XG4gICAgfVxuXG4gICAgaXNBY3RpdmUoKTogYm9vbGVhbiB7XG4gICAgICAgIGZvciAoY29uc3Qge2hhbmRsZXJ9IG9mIHRoaXMuX2hhbmRsZXJzKSB7XG4gICAgICAgICAgICBpZiAoaGFuZGxlci5pc0FjdGl2ZSgpKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaXNab29taW5nKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9ldmVudHNJblByb2dyZXNzLnpvb20gfHwgdGhpcy5fbWFwLnNjcm9sbFpvb20uaXNab29taW5nKCk7XG4gICAgfVxuXG4gICAgaXNSb3RhdGluZygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5fZXZlbnRzSW5Qcm9ncmVzcy5yb3RhdGU7XG4gICAgfVxuXG4gICAgaXNNb3ZpbmcoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAhIWlzTW92aW5nKHRoaXMuX2V2ZW50c0luUHJvZ3Jlc3MpIHx8IHRoaXMuaXNab29taW5nKCk7XG4gICAgfVxuXG4gICAgX2lzRHJhZ2dpbmcoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX2V2ZW50c0luUHJvZ3Jlc3MuZHJhZztcbiAgICB9XG5cbiAgICBfYmxvY2tlZEJ5QWN0aXZlKGFjdGl2ZUhhbmRsZXJzOiB7IFtzdHJpbmddOiBIYW5kbGVyIH0sIGFsbG93ZWQ6IEFycmF5PHN0cmluZz4sIG15TmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIGZvciAoY29uc3QgbmFtZSBpbiBhY3RpdmVIYW5kbGVycykge1xuICAgICAgICAgICAgaWYgKG5hbWUgPT09IG15TmFtZSkgY29udGludWU7XG4gICAgICAgICAgICBpZiAoIWFsbG93ZWQgfHwgYWxsb3dlZC5pbmRleE9mKG5hbWUpIDwgMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBoYW5kbGVXaW5kb3dFdmVudChlOiBJbnB1dEV2ZW50KSB7XG4gICAgICAgIHRoaXMuaGFuZGxlRXZlbnQoZSwgYCR7ZS50eXBlfVdpbmRvd2ApO1xuICAgIH1cblxuICAgIF9nZXRNYXBUb3VjaGVzKHRvdWNoZXM6IFRvdWNoTGlzdCk6IFRvdWNoTGlzdCB7XG4gICAgICAgIGNvbnN0IG1hcFRvdWNoZXMgPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCB0IG9mIHRvdWNoZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9ICgodC50YXJnZXQ6IGFueSk6IE5vZGUpO1xuICAgICAgICAgICAgaWYgKHRoaXMuX2VsLmNvbnRhaW5zKHRhcmdldCkpIHtcbiAgICAgICAgICAgICAgICBtYXBUb3VjaGVzLnB1c2godCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICgobWFwVG91Y2hlczogYW55KTogVG91Y2hMaXN0KTtcbiAgICB9XG5cbiAgICBoYW5kbGVFdmVudChlOiBJbnB1dEV2ZW50IHwgUmVuZGVyRnJhbWVFdmVudCwgZXZlbnROYW1lPzogc3RyaW5nKSB7XG5cbiAgICAgICAgdGhpcy5fdXBkYXRpbmdDYW1lcmEgPSB0cnVlO1xuICAgICAgICBhc3NlcnQoZS50aW1lU3RhbXAgIT09IHVuZGVmaW5lZCk7XG5cbiAgICAgICAgY29uc3QgaXNSZW5kZXJGcmFtZSA9IGUudHlwZSA9PT0gJ3JlbmRlckZyYW1lJztcbiAgICAgICAgY29uc3QgaW5wdXRFdmVudCA9IGlzUmVuZGVyRnJhbWUgPyB1bmRlZmluZWQgOiAoKGU6IGFueSk6IElucHV0RXZlbnQpO1xuXG4gICAgICAgIC8qXG4gICAgICAgICAqIFdlIGRvbid0IGNhbGwgZS5wcmV2ZW50RGVmYXVsdCgpIGZvciBhbnkgZXZlbnRzIGJ5IGRlZmF1bHQuXG4gICAgICAgICAqIEhhbmRsZXJzIGFyZSByZXNwb25zaWJsZSBmb3IgY2FsbGluZyBpdCB3aGVyZSBuZWNlc3NhcnkuXG4gICAgICAgICAqL1xuXG4gICAgICAgIGNvbnN0IG1lcmdlZEhhbmRsZXJSZXN1bHQ6IEhhbmRsZXJSZXN1bHQgPSB7bmVlZHNSZW5kZXJGcmFtZTogZmFsc2V9O1xuICAgICAgICBjb25zdCBldmVudHNJblByb2dyZXNzID0ge307XG4gICAgICAgIGNvbnN0IGFjdGl2ZUhhbmRsZXJzID0ge307XG5cbiAgICAgICAgY29uc3QgbWFwVG91Y2hlcyA9IGUudG91Y2hlcyA/IHRoaXMuX2dldE1hcFRvdWNoZXMoKChlOiBhbnkpOiBUb3VjaEV2ZW50KS50b3VjaGVzKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgY29uc3QgcG9pbnRzID0gbWFwVG91Y2hlcyA/IERPTS50b3VjaFBvcyh0aGlzLl9lbCwgbWFwVG91Y2hlcykgOlxuICAgICAgICAgICAgaXNSZW5kZXJGcmFtZSA/IHVuZGVmaW5lZCA6IC8vIHJlbmRlckZyYW1lIGV2ZW50IGRvZXNuJ3QgaGF2ZSBhbnkgcG9pbnRzXG4gICAgICAgICAgICBET00ubW91c2VQb3ModGhpcy5fZWwsICgoZTogYW55KTogTW91c2VFdmVudCkpO1xuXG4gICAgICAgIGZvciAoY29uc3Qge2hhbmRsZXJOYW1lLCBoYW5kbGVyLCBhbGxvd2VkfSBvZiB0aGlzLl9oYW5kbGVycykge1xuICAgICAgICAgICAgaWYgKCFoYW5kbGVyLmlzRW5hYmxlZCgpKSBjb250aW51ZTtcblxuICAgICAgICAgICAgbGV0IGRhdGE6ID9IYW5kbGVyUmVzdWx0O1xuICAgICAgICAgICAgaWYgKHRoaXMuX2Jsb2NrZWRCeUFjdGl2ZShhY3RpdmVIYW5kbGVycywgYWxsb3dlZCwgaGFuZGxlck5hbWUpKSB7XG4gICAgICAgICAgICAgICAgaGFuZGxlci5yZXNldCgpO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICgoaGFuZGxlcjogYW55KVtldmVudE5hbWUgfHwgZS50eXBlXSkge1xuICAgICAgICAgICAgICAgICAgICBkYXRhID0gKGhhbmRsZXI6IGFueSlbZXZlbnROYW1lIHx8IGUudHlwZV0oZSwgcG9pbnRzLCBtYXBUb3VjaGVzKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tZXJnZUhhbmRsZXJSZXN1bHQobWVyZ2VkSGFuZGxlclJlc3VsdCwgZXZlbnRzSW5Qcm9ncmVzcywgZGF0YSwgaGFuZGxlck5hbWUsIGlucHV0RXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSAmJiBkYXRhLm5lZWRzUmVuZGVyRnJhbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3RyaWdnZXJSZW5kZXJGcmFtZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZGF0YSB8fCBoYW5kbGVyLmlzQWN0aXZlKCkpIHtcbiAgICAgICAgICAgICAgICBhY3RpdmVIYW5kbGVyc1toYW5kbGVyTmFtZV0gPSBoYW5kbGVyO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZGVhY3RpdmF0ZWRIYW5kbGVycyA9IHt9O1xuICAgICAgICBmb3IgKGNvbnN0IG5hbWUgaW4gdGhpcy5fcHJldmlvdXNBY3RpdmVIYW5kbGVycykge1xuICAgICAgICAgICAgaWYgKCFhY3RpdmVIYW5kbGVyc1tuYW1lXSkge1xuICAgICAgICAgICAgICAgIGRlYWN0aXZhdGVkSGFuZGxlcnNbbmFtZV0gPSBpbnB1dEV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3ByZXZpb3VzQWN0aXZlSGFuZGxlcnMgPSBhY3RpdmVIYW5kbGVycztcblxuICAgICAgICBpZiAoT2JqZWN0LmtleXMoZGVhY3RpdmF0ZWRIYW5kbGVycykubGVuZ3RoIHx8IGhhc0NoYW5nZShtZXJnZWRIYW5kbGVyUmVzdWx0KSkge1xuICAgICAgICAgICAgdGhpcy5fY2hhbmdlcy5wdXNoKFttZXJnZWRIYW5kbGVyUmVzdWx0LCBldmVudHNJblByb2dyZXNzLCBkZWFjdGl2YXRlZEhhbmRsZXJzXSk7XG4gICAgICAgICAgICB0aGlzLl90cmlnZ2VyUmVuZGVyRnJhbWUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChPYmplY3Qua2V5cyhhY3RpdmVIYW5kbGVycykubGVuZ3RoIHx8IGhhc0NoYW5nZShtZXJnZWRIYW5kbGVyUmVzdWx0KSkge1xuICAgICAgICAgICAgdGhpcy5fbWFwLl9zdG9wKHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fdXBkYXRpbmdDYW1lcmEgPSBmYWxzZTtcblxuICAgICAgICBjb25zdCB7Y2FtZXJhQW5pbWF0aW9ufSA9IG1lcmdlZEhhbmRsZXJSZXN1bHQ7XG4gICAgICAgIGlmIChjYW1lcmFBbmltYXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuX2luZXJ0aWEuY2xlYXIoKTtcbiAgICAgICAgICAgIHRoaXMuX2ZpcmVFdmVudHMoe30sIHt9LCB0cnVlKTtcbiAgICAgICAgICAgIHRoaXMuX2NoYW5nZXMgPSBbXTtcbiAgICAgICAgICAgIGNhbWVyYUFuaW1hdGlvbih0aGlzLl9tYXApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbWVyZ2VIYW5kbGVyUmVzdWx0KG1lcmdlZEhhbmRsZXJSZXN1bHQ6IEhhbmRsZXJSZXN1bHQsIGV2ZW50c0luUHJvZ3Jlc3M6IE9iamVjdCwgaGFuZGxlclJlc3VsdDogSGFuZGxlclJlc3VsdCwgbmFtZTogc3RyaW5nLCBlPzogSW5wdXRFdmVudCkge1xuICAgICAgICBpZiAoIWhhbmRsZXJSZXN1bHQpIHJldHVybjtcblxuICAgICAgICBleHRlbmQobWVyZ2VkSGFuZGxlclJlc3VsdCwgaGFuZGxlclJlc3VsdCk7XG5cbiAgICAgICAgY29uc3QgZXZlbnREYXRhID0ge2hhbmRsZXJOYW1lOiBuYW1lLCBvcmlnaW5hbEV2ZW50OiBoYW5kbGVyUmVzdWx0Lm9yaWdpbmFsRXZlbnQgfHwgZX07XG5cbiAgICAgICAgLy8gdHJhY2sgd2hpY2ggaGFuZGxlciBjaGFuZ2VkIHdoaWNoIGNhbWVyYSBwcm9wZXJ0eVxuICAgICAgICBpZiAoaGFuZGxlclJlc3VsdC56b29tRGVsdGEgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgZXZlbnRzSW5Qcm9ncmVzcy56b29tID0gZXZlbnREYXRhO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoYW5kbGVyUmVzdWx0LnBhbkRlbHRhICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGV2ZW50c0luUHJvZ3Jlc3MuZHJhZyA9IGV2ZW50RGF0YTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaGFuZGxlclJlc3VsdC5waXRjaERlbHRhICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGV2ZW50c0luUHJvZ3Jlc3MucGl0Y2ggPSBldmVudERhdGE7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhhbmRsZXJSZXN1bHQuYmVhcmluZ0RlbHRhICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGV2ZW50c0luUHJvZ3Jlc3Mucm90YXRlID0gZXZlbnREYXRhO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX2FwcGx5Q2hhbmdlcygpIHtcbiAgICAgICAgY29uc3QgY29tYmluZWQgPSB7fTtcbiAgICAgICAgY29uc3QgY29tYmluZWRFdmVudHNJblByb2dyZXNzID0ge307XG4gICAgICAgIGNvbnN0IGNvbWJpbmVkRGVhY3RpdmF0ZWRIYW5kbGVycyA9IHt9O1xuXG4gICAgICAgIGZvciAoY29uc3QgW2NoYW5nZSwgZXZlbnRzSW5Qcm9ncmVzcywgZGVhY3RpdmF0ZWRIYW5kbGVyc10gb2YgdGhpcy5fY2hhbmdlcykge1xuXG4gICAgICAgICAgICBpZiAoY2hhbmdlLnBhbkRlbHRhKSBjb21iaW5lZC5wYW5EZWx0YSA9IChjb21iaW5lZC5wYW5EZWx0YSB8fCBuZXcgUG9pbnQoMCwgMCkpLl9hZGQoY2hhbmdlLnBhbkRlbHRhKTtcbiAgICAgICAgICAgIGlmIChjaGFuZ2Uuem9vbURlbHRhKSBjb21iaW5lZC56b29tRGVsdGEgPSAoY29tYmluZWQuem9vbURlbHRhIHx8IDApICsgY2hhbmdlLnpvb21EZWx0YTtcbiAgICAgICAgICAgIGlmIChjaGFuZ2UuYmVhcmluZ0RlbHRhKSBjb21iaW5lZC5iZWFyaW5nRGVsdGEgPSAoY29tYmluZWQuYmVhcmluZ0RlbHRhIHx8IDApICsgY2hhbmdlLmJlYXJpbmdEZWx0YTtcbiAgICAgICAgICAgIGlmIChjaGFuZ2UucGl0Y2hEZWx0YSkgY29tYmluZWQucGl0Y2hEZWx0YSA9IChjb21iaW5lZC5waXRjaERlbHRhIHx8IDApICsgY2hhbmdlLnBpdGNoRGVsdGE7XG4gICAgICAgICAgICBpZiAoY2hhbmdlLmFyb3VuZCAhPT0gdW5kZWZpbmVkKSBjb21iaW5lZC5hcm91bmQgPSBjaGFuZ2UuYXJvdW5kO1xuICAgICAgICAgICAgaWYgKGNoYW5nZS5hcm91bmRDb29yZCAhPT0gdW5kZWZpbmVkKSBjb21iaW5lZC5hcm91bmRDb29yZCA9IGNoYW5nZS5hcm91bmRDb29yZDtcbiAgICAgICAgICAgIGlmIChjaGFuZ2UucGluY2hBcm91bmQgIT09IHVuZGVmaW5lZCkgY29tYmluZWQucGluY2hBcm91bmQgPSBjaGFuZ2UucGluY2hBcm91bmQ7XG4gICAgICAgICAgICBpZiAoY2hhbmdlLm5vSW5lcnRpYSkgY29tYmluZWQubm9JbmVydGlhID0gY2hhbmdlLm5vSW5lcnRpYTtcblxuICAgICAgICAgICAgZXh0ZW5kKGNvbWJpbmVkRXZlbnRzSW5Qcm9ncmVzcywgZXZlbnRzSW5Qcm9ncmVzcyk7XG4gICAgICAgICAgICBleHRlbmQoY29tYmluZWREZWFjdGl2YXRlZEhhbmRsZXJzLCBkZWFjdGl2YXRlZEhhbmRsZXJzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3VwZGF0ZU1hcFRyYW5zZm9ybShjb21iaW5lZCwgY29tYmluZWRFdmVudHNJblByb2dyZXNzLCBjb21iaW5lZERlYWN0aXZhdGVkSGFuZGxlcnMpO1xuICAgICAgICB0aGlzLl9jaGFuZ2VzID0gW107XG4gICAgfVxuXG4gICAgX3VwZGF0ZU1hcFRyYW5zZm9ybShjb21iaW5lZFJlc3VsdDogYW55LCBjb21iaW5lZEV2ZW50c0luUHJvZ3Jlc3M6IE9iamVjdCwgZGVhY3RpdmF0ZWRIYW5kbGVyczogT2JqZWN0KSB7XG5cbiAgICAgICAgY29uc3QgbWFwID0gdGhpcy5fbWFwO1xuICAgICAgICBjb25zdCB0ciA9IG1hcC50cmFuc2Zvcm07XG5cbiAgICAgICAgY29uc3QgZXZlbnRTdGFydGVkID0gKHR5cGU6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgY29uc3QgbmV3RXZlbnQgPSBjb21iaW5lZEV2ZW50c0luUHJvZ3Jlc3NbdHlwZV07XG4gICAgICAgICAgICByZXR1cm4gbmV3RXZlbnQgJiYgIXRoaXMuX2V2ZW50c0luUHJvZ3Jlc3NbdHlwZV07XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgZXZlbnRFbmRlZCA9ICh0eXBlOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fZXZlbnRzSW5Qcm9ncmVzc1t0eXBlXTtcbiAgICAgICAgICAgIHJldHVybiBldmVudCAmJiAhdGhpcy5faGFuZGxlcnNCeUlkW2V2ZW50LmhhbmRsZXJOYW1lXS5pc0FjdGl2ZSgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHRvVmVjMyA9IChwOiBNZXJjYXRvckNvb3JkaW5hdGUpOiBWZWMzID0+IFtwLngsIHAueSwgcC56XTtcblxuICAgICAgICBpZiAoZXZlbnRFbmRlZChcImRyYWdcIikgJiYgIWhhc0NoYW5nZShjb21iaW5lZFJlc3VsdCkpIHtcbiAgICAgICAgICAgIGNvbnN0IHByZVpvb20gPSB0ci56b29tO1xuICAgICAgICAgICAgdHIuY2FtZXJhRWxldmF0aW9uUmVmZXJlbmNlID0gXCJzZWFcIjtcbiAgICAgICAgICAgIHRyLnJlY2VudGVyT25UZXJyYWluKCk7XG4gICAgICAgICAgICB0ci5jYW1lcmFFbGV2YXRpb25SZWZlcmVuY2UgPSBcImdyb3VuZFwiO1xuICAgICAgICAgICAgLy8gTWFwIHpvb20gbWlnaHQgY2hhbmdlIGR1cmluZyB0aGUgcGFuIG9wZXJhdGlvbiBkdWUgdG8gdGVycmFpbiBlbGV2YXRpb24uXG4gICAgICAgICAgICBpZiAocHJlWm9vbSAhPT0gdHIuem9vbSkgdGhpcy5fbWFwLl91cGRhdGUodHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDYXRjaGVzIGRvdWJsZSBjbGljayBhbmQgZG91YmxlIHRhcCB6b29tcyB3aGVuIGNhbWVyYSBpcyBjb25zdHJhaW5lZCBvdmVyIHRlcnJhaW5cbiAgICAgICAgaWYgKHRyLl9pc0NhbWVyYUNvbnN0cmFpbmVkKSBtYXAuX3N0b3AodHJ1ZSk7XG5cbiAgICAgICAgaWYgKCFoYXNDaGFuZ2UoY29tYmluZWRSZXN1bHQpKSB7XG4gICAgICAgICAgICB0aGlzLl9maXJlRXZlbnRzKGNvbWJpbmVkRXZlbnRzSW5Qcm9ncmVzcywgZGVhY3RpdmF0ZWRIYW5kbGVycywgdHJ1ZSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBsZXQge3BhbkRlbHRhLCB6b29tRGVsdGEsIGJlYXJpbmdEZWx0YSwgcGl0Y2hEZWx0YSwgYXJvdW5kLCBhcm91bmRDb29yZCwgcGluY2hBcm91bmR9ID0gY29tYmluZWRSZXN1bHQ7XG5cbiAgICAgICAgaWYgKHRyLl9pc0NhbWVyYUNvbnN0cmFpbmVkKSB7XG4gICAgICAgICAgICAvLyBDYXRjaGVzIHdoZWVsIHpvb20gZXZlbnRzIHdoZW4gY2FtZXJhIGlzIGNvbnN0cmFpbmVkIG92ZXIgdGVycmFpblxuICAgICAgICAgICAgaWYgKHpvb21EZWx0YSA+IDApIHpvb21EZWx0YSA9IDA7XG4gICAgICAgICAgICB0ci5faXNDYW1lcmFDb25zdHJhaW5lZCA9IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBpbmNoQXJvdW5kICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGFyb3VuZCA9IHBpbmNoQXJvdW5kO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCh6b29tRGVsdGEgfHwgZXZlbnRTdGFydGVkKFwiZHJhZ1wiKSkgJiYgYXJvdW5kKSB7XG4gICAgICAgICAgICB0aGlzLl9kcmFnT3JpZ2luID0gdG9WZWMzKHRyLnBvaW50Q29vcmRpbmF0ZTNEKGFyb3VuZCkpO1xuICAgICAgICAgICAgLy8gQ29uc3RydWN0IHRoZSB0cmFja2luZyBlbGxpcHNvaWQgZXZlcnkgdGltZSB1c2VyIGNoYW5nZXMgdGhlIHpvb20gb3IgZHJhZyBvcmlnaW4uXG4gICAgICAgICAgICAvLyBEaXJlY3Rpb24gb2YgdGhlIHJheSB3aWxsIGRlZmluZSBzaXplIG9mIHRoZSBzaGFwZSBhbmQgaGVuY2UgZGVmaW5pbmcgdGhlIGF2YWlsYWJsZSByYW5nZSBvZiBtb3ZlbWVudFxuICAgICAgICAgICAgdGhpcy5fdHJhY2tpbmdFbGxpcHNvaWQuc2V0dXAodHIuX2NhbWVyYS5wb3NpdGlvbiwgdGhpcy5fZHJhZ09yaWdpbik7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBbGwgbW92ZW1lbnQgb2YgdGhlIGNhbWVyYSBpcyBkb25lIHJlbGF0aXZlIHRvIHRoZSBzZWEgbGV2ZWxcbiAgICAgICAgdHIuY2FtZXJhRWxldmF0aW9uUmVmZXJlbmNlID0gXCJzZWFcIjtcblxuICAgICAgICAvLyBzdG9wIGFueSBvbmdvaW5nIGNhbWVyYSBhbmltYXRpb25zIChlYXNlVG8sIGZseVRvKVxuICAgICAgICBtYXAuX3N0b3AodHJ1ZSk7XG5cbiAgICAgICAgYXJvdW5kID0gYXJvdW5kIHx8IG1hcC50cmFuc2Zvcm0uY2VudGVyUG9pbnQ7XG4gICAgICAgIGlmIChiZWFyaW5nRGVsdGEpIHRyLmJlYXJpbmcgKz0gYmVhcmluZ0RlbHRhO1xuICAgICAgICBpZiAocGl0Y2hEZWx0YSkgdHIucGl0Y2ggKz0gcGl0Y2hEZWx0YTtcbiAgICAgICAgdHIuX3VwZGF0ZUNhbWVyYVN0YXRlKCk7XG5cbiAgICAgICAgLy8gQ29tcHV0ZSBNZXJjYXRvciAzRCBjYW1lcmEgb2Zmc2V0IGJhc2VkIG9uIHNjcmVlbnNwYWNlIHBhbkRlbHRhXG4gICAgICAgIGNvbnN0IHBhblZlYyA9IFswLCAwLCAwXTtcbiAgICAgICAgaWYgKHBhbkRlbHRhKSB7XG4gICAgICAgICAgICBpZiAodHIucHJvamVjdGlvbi5uYW1lID09PSAnbWVyY2F0b3InKSB7XG4gICAgICAgICAgICAgICAgYXNzZXJ0KHRoaXMuX2RyYWdPcmlnaW4sICdfZHJhZ09yaWdpbiBzaG91bGQgaGF2ZSBiZWVuIHNldHVwIHdpdGggYSBwcmV2aW91cyBkcmFnc3RhcnQnKTtcbiAgICAgICAgICAgICAgICBjb25zdCBzdGFydFBvaW50ID0gdGhpcy5fdHJhY2tpbmdFbGxpcHNvaWQucHJvamVjdFJheSh0ci5zY3JlZW5Qb2ludFRvTWVyY2F0b3JSYXkoYXJvdW5kKS5kaXIpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGVuZFBvaW50ID0gdGhpcy5fdHJhY2tpbmdFbGxpcHNvaWQucHJvamVjdFJheSh0ci5zY3JlZW5Qb2ludFRvTWVyY2F0b3JSYXkoYXJvdW5kLnN1YihwYW5EZWx0YSkpLmRpcik7XG4gICAgICAgICAgICAgICAgcGFuVmVjWzBdID0gZW5kUG9pbnRbMF0gLSBzdGFydFBvaW50WzBdO1xuICAgICAgICAgICAgICAgIHBhblZlY1sxXSA9IGVuZFBvaW50WzFdIC0gc3RhcnRQb2ludFsxXTtcblxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdGFydFBvaW50ID0gdHIucG9pbnRDb29yZGluYXRlKGFyb3VuZCk7XG4gICAgICAgICAgICAgICAgaWYgKHRyLnByb2plY3Rpb24ubmFtZSA9PT0gJ2dsb2JlJykge1xuICAgICAgICAgICAgICAgICAgICAvLyBDb21wdXRlIHBhbiB2ZWN0b3IgZGlyZWN0bHkgaW4gcGl4ZWwgY29vcmRpbmF0ZXMgZm9yIHRoZSBnbG9iZS5cbiAgICAgICAgICAgICAgICAgICAgLy8gUm90YXRlIHRoZSBnbG9iZSBhIGJpdCBmYXN0ZXIgd2hlbiBkcmFnZ2luZyBuZWFyIHBvbGVzIHRvIGNvbXBlbnNhdGVcbiAgICAgICAgICAgICAgICAgICAgLy8gZGlmZmVyZW50IHBpeGVsLXBlci1tZXRlciByYXRpb3MgKGllLiBwaXhlbC10by1waHlzaWNhbC1yb3RhdGlvbiBpcyBsb3dlcilcbiAgICAgICAgICAgICAgICAgICAgcGFuRGVsdGEgPSBwYW5EZWx0YS5yb3RhdGUoLXRyLmFuZ2xlKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2NhbGUgPSB0ci5fcGl4ZWxzUGVyTWVyY2F0b3JQaXhlbCAvIHRyLndvcmxkU2l6ZTtcbiAgICAgICAgICAgICAgICAgICAgcGFuVmVjWzBdID0gLXBhbkRlbHRhLnggKiBtZXJjYXRvclNjYWxlKGxhdEZyb21NZXJjYXRvclkoc3RhcnRQb2ludC55KSkgKiBzY2FsZTtcbiAgICAgICAgICAgICAgICAgICAgcGFuVmVjWzFdID0gLXBhbkRlbHRhLnkgKiBtZXJjYXRvclNjYWxlKHRyLmNlbnRlci5sYXQpICogc2NhbGU7XG5cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbmRQb2ludCA9IHRyLnBvaW50Q29vcmRpbmF0ZShhcm91bmQuc3ViKHBhbkRlbHRhKSk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXJ0UG9pbnQgJiYgZW5kUG9pbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhblZlY1swXSA9IGVuZFBvaW50LnggLSBzdGFydFBvaW50Lng7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYW5WZWNbMV0gPSBlbmRQb2ludC55IC0gc3RhcnRQb2ludC55O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgb3JpZ2luYWxab29tID0gdHIuem9vbTtcbiAgICAgICAgLy8gQ29tcHV0ZSBNZXJjYXRvciAzRCBjYW1lcmEgb2Zmc2V0IGJhc2VkIG9uIHNjcmVlbnNwYWNlIHJlcXVlc3RlZCBab29tRGVsdGFcbiAgICAgICAgY29uc3Qgem9vbVZlYyA9IFswLCAwLCAwXTtcbiAgICAgICAgaWYgKHpvb21EZWx0YSkge1xuICAgICAgICAgICAgLy8gWm9vbSB2YWx1ZSBoYXMgdG8gYmUgY29tcHV0ZWQgcmVsYXRpdmUgdG8gYSBzZWNvbmRhcnkgbWFwIHBsYW5lIHRoYXQgaXMgY3JlYXRlZCBmcm9tIHRoZSB0ZXJyYWluIHBvc2l0aW9uIGJlbG93IHRoZSBjdXJzb3IuXG4gICAgICAgICAgICAvLyBUaGlzIHdheSB0aGUgem9vbSBpbnRlcnBvbGF0aW9uIGNhbiBiZSBrZXB0IGxpbmVhciBhbmQgaW5kZXBlbmRlbnQgb2YgdGhlIChwb3NzaWJsZSkgdGVycmFpbiBlbGV2YXRpb25cbiAgICAgICAgICAgIGNvbnN0IHBpY2tlZFBvc2l0aW9uOiBWZWMzID0gYXJvdW5kQ29vcmQgPyB0b1ZlYzMoYXJvdW5kQ29vcmQpIDogdG9WZWMzKHRyLnBvaW50Q29vcmRpbmF0ZTNEKGFyb3VuZCkpO1xuXG4gICAgICAgICAgICBjb25zdCBhcm91bmRSYXkgPSB7ZGlyOiB2ZWMzLm5vcm1hbGl6ZShbXSwgdmVjMy5zdWIoW10sIHBpY2tlZFBvc2l0aW9uLCB0ci5fY2FtZXJhLnBvc2l0aW9uKSl9O1xuICAgICAgICAgICAgaWYgKGFyb3VuZFJheS5kaXJbMl0gPCAwKSB7XG4gICAgICAgICAgICAgICAgLy8gU3BlY2lhbCBoYW5kbGluZyBpcyByZXF1aXJlZCBpZiB0aGUgcmF5IGNyZWF0ZWQgZnJvbSB0aGUgY3Vyc29yIGlzIGhlYWRpbmcgdXAuXG4gICAgICAgICAgICAgICAgLy8gVGhpcyBzY2VuYXJpbyBpcyBwb3NzaWJsZSBpZiB1c2VyIGlzIHRyeWluZyB0byB6b29tIHRvd2FyZHMgYSBmZWF0dXJlIGxpa2UgYSBoaWxsIG9yIGEgbW91bnRhaW4uXG4gICAgICAgICAgICAgICAgLy8gQ29udmVydCB6b29tRGVsdGEgdG8gYSBtb3ZlbWVudCB2ZWN0b3IgYXMgaWYgdGhlIGNhbWVyYSB3b3VsZCBiZSBvcmJpdGluZyBhcm91bmQgdGhlIHBpY2tlZCBwb2ludFxuICAgICAgICAgICAgICAgIGNvbnN0IG1vdmVtZW50ID0gdHIuem9vbURlbHRhVG9Nb3ZlbWVudChwaWNrZWRQb3NpdGlvbiwgem9vbURlbHRhKTtcbiAgICAgICAgICAgICAgICB2ZWMzLnNjYWxlKHpvb21WZWMsIGFyb3VuZFJheS5kaXIsIG1vdmVtZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIE11dGF0ZSBjYW1lcmEgc3RhdGUgdmlhIENhbWVyYUFQSVxuICAgICAgICBjb25zdCB0cmFuc2xhdGlvbiA9IHZlYzMuYWRkKHBhblZlYywgcGFuVmVjLCB6b29tVmVjKTtcbiAgICAgICAgdHIuX3RyYW5zbGF0ZUNhbWVyYUNvbnN0cmFpbmVkKHRyYW5zbGF0aW9uKTtcblxuICAgICAgICBpZiAoem9vbURlbHRhICYmIE1hdGguYWJzKHRyLnpvb20gLSBvcmlnaW5hbFpvb20pID4gMC4wMDAxKSB7XG4gICAgICAgICAgICB0ci5yZWNlbnRlck9uVGVycmFpbigpO1xuICAgICAgICB9XG5cbiAgICAgICAgdHIuY2FtZXJhRWxldmF0aW9uUmVmZXJlbmNlID0gXCJncm91bmRcIjtcblxuICAgICAgICB0aGlzLl9tYXAuX3VwZGF0ZSgpO1xuICAgICAgICBpZiAoIWNvbWJpbmVkUmVzdWx0Lm5vSW5lcnRpYSkgdGhpcy5faW5lcnRpYS5yZWNvcmQoY29tYmluZWRSZXN1bHQpO1xuICAgICAgICB0aGlzLl9maXJlRXZlbnRzKGNvbWJpbmVkRXZlbnRzSW5Qcm9ncmVzcywgZGVhY3RpdmF0ZWRIYW5kbGVycywgdHJ1ZSk7XG4gICAgfVxuXG4gICAgX2ZpcmVFdmVudHMobmV3RXZlbnRzSW5Qcm9ncmVzczogeyBbc3RyaW5nXTogT2JqZWN0IH0sIGRlYWN0aXZhdGVkSGFuZGxlcnM6IE9iamVjdCwgYWxsb3dFbmRBbmltYXRpb246IGJvb2xlYW4pIHtcblxuICAgICAgICBjb25zdCB3YXNNb3ZpbmcgPSBpc01vdmluZyh0aGlzLl9ldmVudHNJblByb2dyZXNzKTtcbiAgICAgICAgY29uc3Qgbm93TW92aW5nID0gaXNNb3ZpbmcobmV3RXZlbnRzSW5Qcm9ncmVzcyk7XG5cbiAgICAgICAgY29uc3Qgc3RhcnRFdmVudHMgPSB7fTtcblxuICAgICAgICBmb3IgKGNvbnN0IGV2ZW50TmFtZSBpbiBuZXdFdmVudHNJblByb2dyZXNzKSB7XG4gICAgICAgICAgICBjb25zdCB7b3JpZ2luYWxFdmVudH0gPSBuZXdFdmVudHNJblByb2dyZXNzW2V2ZW50TmFtZV07XG4gICAgICAgICAgICBpZiAoIXRoaXMuX2V2ZW50c0luUHJvZ3Jlc3NbZXZlbnROYW1lXSkge1xuICAgICAgICAgICAgICAgIHN0YXJ0RXZlbnRzW2Ake2V2ZW50TmFtZX1zdGFydGBdID0gb3JpZ2luYWxFdmVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX2V2ZW50c0luUHJvZ3Jlc3NbZXZlbnROYW1lXSA9IG5ld0V2ZW50c0luUHJvZ3Jlc3NbZXZlbnROYW1lXTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGZpcmUgc3RhcnQgZXZlbnRzIG9ubHkgYWZ0ZXIgdGhpcy5fZXZlbnRzSW5Qcm9ncmVzcyBoYXMgYmVlbiB1cGRhdGVkXG4gICAgICAgIGlmICghd2FzTW92aW5nICYmIG5vd01vdmluZykge1xuICAgICAgICAgICAgdGhpcy5fZmlyZUV2ZW50KCdtb3Zlc3RhcnQnLCBub3dNb3Zpbmcub3JpZ2luYWxFdmVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGNvbnN0IG5hbWUgaW4gc3RhcnRFdmVudHMpIHtcbiAgICAgICAgICAgIHRoaXMuX2ZpcmVFdmVudChuYW1lLCBzdGFydEV2ZW50c1tuYW1lXSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobm93TW92aW5nKSB7XG4gICAgICAgICAgICB0aGlzLl9maXJlRXZlbnQoJ21vdmUnLCBub3dNb3Zpbmcub3JpZ2luYWxFdmVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGNvbnN0IGV2ZW50TmFtZSBpbiBuZXdFdmVudHNJblByb2dyZXNzKSB7XG4gICAgICAgICAgICBjb25zdCB7b3JpZ2luYWxFdmVudH0gPSBuZXdFdmVudHNJblByb2dyZXNzW2V2ZW50TmFtZV07XG4gICAgICAgICAgICB0aGlzLl9maXJlRXZlbnQoZXZlbnROYW1lLCBvcmlnaW5hbEV2ZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGVuZEV2ZW50cyA9IHt9O1xuXG4gICAgICAgIGxldCBvcmlnaW5hbEVuZEV2ZW50O1xuICAgICAgICBmb3IgKGNvbnN0IGV2ZW50TmFtZSBpbiB0aGlzLl9ldmVudHNJblByb2dyZXNzKSB7XG4gICAgICAgICAgICBjb25zdCB7aGFuZGxlck5hbWUsIG9yaWdpbmFsRXZlbnR9ID0gdGhpcy5fZXZlbnRzSW5Qcm9ncmVzc1tldmVudE5hbWVdO1xuICAgICAgICAgICAgaWYgKCF0aGlzLl9oYW5kbGVyc0J5SWRbaGFuZGxlck5hbWVdLmlzQWN0aXZlKCkpIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5fZXZlbnRzSW5Qcm9ncmVzc1tldmVudE5hbWVdO1xuICAgICAgICAgICAgICAgIG9yaWdpbmFsRW5kRXZlbnQgPSBkZWFjdGl2YXRlZEhhbmRsZXJzW2hhbmRsZXJOYW1lXSB8fCBvcmlnaW5hbEV2ZW50O1xuICAgICAgICAgICAgICAgIGVuZEV2ZW50c1tgJHtldmVudE5hbWV9ZW5kYF0gPSBvcmlnaW5hbEVuZEV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChjb25zdCBuYW1lIGluIGVuZEV2ZW50cykge1xuICAgICAgICAgICAgdGhpcy5fZmlyZUV2ZW50KG5hbWUsIGVuZEV2ZW50c1tuYW1lXSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdGlsbE1vdmluZyA9IGlzTW92aW5nKHRoaXMuX2V2ZW50c0luUHJvZ3Jlc3MpO1xuICAgICAgICBpZiAoYWxsb3dFbmRBbmltYXRpb24gJiYgKHdhc01vdmluZyB8fCBub3dNb3ZpbmcpICYmICFzdGlsbE1vdmluZykge1xuICAgICAgICAgICAgdGhpcy5fdXBkYXRpbmdDYW1lcmEgPSB0cnVlO1xuICAgICAgICAgICAgY29uc3QgaW5lcnRpYWxFYXNlID0gdGhpcy5faW5lcnRpYS5fb25Nb3ZlRW5kKHRoaXMuX21hcC5kcmFnUGFuLl9pbmVydGlhT3B0aW9ucyk7XG5cbiAgICAgICAgICAgIGNvbnN0IHNob3VsZFNuYXBUb05vcnRoID0gKGJlYXJpbmc6IG51bWJlcikgPT4gYmVhcmluZyAhPT0gMCAmJiAtdGhpcy5fYmVhcmluZ1NuYXAgPCBiZWFyaW5nICYmIGJlYXJpbmcgPCB0aGlzLl9iZWFyaW5nU25hcDtcblxuICAgICAgICAgICAgaWYgKGluZXJ0aWFsRWFzZSkge1xuICAgICAgICAgICAgICAgIGlmIChzaG91bGRTbmFwVG9Ob3J0aChpbmVydGlhbEVhc2UuYmVhcmluZyB8fCB0aGlzLl9tYXAuZ2V0QmVhcmluZygpKSkge1xuICAgICAgICAgICAgICAgICAgICBpbmVydGlhbEVhc2UuYmVhcmluZyA9IDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX21hcC5lYXNlVG8oaW5lcnRpYWxFYXNlLCB7b3JpZ2luYWxFdmVudDogb3JpZ2luYWxFbmRFdmVudH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9tYXAuZmlyZShuZXcgRXZlbnQoJ21vdmVlbmQnLCB7b3JpZ2luYWxFdmVudDogb3JpZ2luYWxFbmRFdmVudH0pKTtcbiAgICAgICAgICAgICAgICBpZiAoc2hvdWxkU25hcFRvTm9ydGgodGhpcy5fbWFwLmdldEJlYXJpbmcoKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWFwLnJlc2V0Tm9ydGgoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl91cGRhdGluZ0NhbWVyYSA9IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICB9XG5cbiAgICBfZmlyZUV2ZW50KHR5cGU6IHN0cmluZywgZTogYW55KSB7XG4gICAgICAgIHRoaXMuX21hcC5maXJlKG5ldyBFdmVudCh0eXBlLCBlID8ge29yaWdpbmFsRXZlbnQ6IGV9IDoge30pKTtcbiAgICB9XG5cbiAgICBfcmVxdWVzdEZyYW1lKCk6IG51bWJlciB7XG4gICAgICAgIHRoaXMuX21hcC50cmlnZ2VyUmVwYWludCgpO1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFwLl9yZW5kZXJUYXNrUXVldWUuYWRkKHRpbWVTdGFtcCA9PiB7XG4gICAgICAgICAgICB0aGlzLl9mcmFtZUlkID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVFdmVudChuZXcgUmVuZGVyRnJhbWVFdmVudCgncmVuZGVyRnJhbWUnLCB7dGltZVN0YW1wfSkpO1xuICAgICAgICAgICAgdGhpcy5fYXBwbHlDaGFuZ2VzKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIF90cmlnZ2VyUmVuZGVyRnJhbWUoKSB7XG4gICAgICAgIGlmICh0aGlzLl9mcmFtZUlkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX2ZyYW1lSWQgPSB0aGlzLl9yZXF1ZXN0RnJhbWUoKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgSGFuZGxlck1hbmFnZXI7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge1xuICAgIGJpbmRBbGwsXG4gICAgZXh0ZW5kLFxuICAgIHdhcm5PbmNlLFxuICAgIGNsYW1wLFxuICAgIHdyYXAsXG4gICAgZWFzZSBhcyBkZWZhdWx0RWFzaW5nLFxuICAgIHBpY2ssXG4gICAgZGVnVG9SYWRcbn0gZnJvbSAnLi4vdXRpbC91dGlsLmpzJztcbmltcG9ydCB7bnVtYmVyIGFzIGludGVycG9sYXRlfSBmcm9tICcuLi9zdHlsZS1zcGVjL3V0aWwvaW50ZXJwb2xhdGUuanMnO1xuaW1wb3J0IGJyb3dzZXIgZnJvbSAnLi4vdXRpbC9icm93c2VyLmpzJztcbmltcG9ydCBMbmdMYXQsIHtlYXJ0aFJhZGl1c30gZnJvbSAnLi4vZ2VvL2xuZ19sYXQuanMnO1xuaW1wb3J0IExuZ0xhdEJvdW5kcyBmcm9tICcuLi9nZW8vbG5nX2xhdF9ib3VuZHMuanMnO1xuaW1wb3J0IFBvaW50IGZyb20gJ0BtYXBib3gvcG9pbnQtZ2VvbWV0cnknO1xuaW1wb3J0IHtFdmVudCwgRXZlbnRlZH0gZnJvbSAnLi4vdXRpbC9ldmVudGVkLmpzJztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCB7RGVidWd9IGZyb20gJy4uL3V0aWwvZGVidWcuanMnO1xuaW1wb3J0IE1lcmNhdG9yQ29vcmRpbmF0ZSwge1xuICAgIG1lcmNhdG9yWmZyb21BbHRpdHVkZSxcbiAgICBtZXJjYXRvclhmcm9tTG5nLFxuICAgIG1lcmNhdG9yWWZyb21MYXQsXG4gICAgbGF0RnJvbU1lcmNhdG9yWSxcbiAgICBsbmdGcm9tTWVyY2F0b3JYXG59IGZyb20gJy4uL2dlby9tZXJjYXRvcl9jb29yZGluYXRlLmpzJztcbmltcG9ydCB7XG4gICAgbGF0TG5nVG9FQ0VGLFxuICAgIGVjZWZUb0xhdExuZyxcbiAgICBHTE9CRV9SQURJVVMsXG4gICAgR0xPQkVfWk9PTV9USFJFU0hPTERfTUFYLFxuICAgIEdMT0JFX1pPT01fVEhSRVNIT0xEX01JTlxufSBmcm9tICcuLi9nZW8vcHJvamVjdGlvbi9nbG9iZV91dGlsLmpzJztcbmltcG9ydCB7dmVjMywgdmVjNCwgbWF0NH0gZnJvbSAnZ2wtbWF0cml4JztcbmltcG9ydCB0eXBlIHtGcmVlQ2FtZXJhT3B0aW9uc30gZnJvbSAnLi9mcmVlX2NhbWVyYS5qcyc7XG5pbXBvcnQgdHlwZSBUcmFuc2Zvcm0gZnJvbSAnLi4vZ2VvL3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQgdHlwZSB7TG5nTGF0TGlrZX0gZnJvbSAnLi4vZ2VvL2xuZ19sYXQuanMnO1xuaW1wb3J0IHR5cGUge0xuZ0xhdEJvdW5kc0xpa2V9IGZyb20gJy4uL2dlby9sbmdfbGF0X2JvdW5kcy5qcyc7XG5pbXBvcnQgdHlwZSB7RWxldmF0aW9uUXVlcnlPcHRpb25zfSBmcm9tICcuLi90ZXJyYWluL2VsZXZhdGlvbi5qcyc7XG5pbXBvcnQgdHlwZSB7VGFza0lEfSBmcm9tICcuLi91dGlsL3Rhc2tfcXVldWUuanMnO1xuaW1wb3J0IHR5cGUge0NhbGxiYWNrfSBmcm9tICcuLi90eXBlcy9jYWxsYmFjay5qcyc7XG5pbXBvcnQgdHlwZSB7UG9pbnRMaWtlfSBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCB7QWFiYn0gZnJvbSAnLi4vdXRpbC9wcmltaXRpdmVzLmpzJztcbmltcG9ydCB0eXBlIHtQYWRkaW5nT3B0aW9uc30gZnJvbSAnLi4vZ2VvL2VkZ2VfaW5zZXRzLmpzJztcbmltcG9ydCB0eXBlIHtNYXBFdmVudH0gZnJvbSAnLi9ldmVudHMuanMnO1xuXG4vKipcbiAqIEEgaGVscGVyIHR5cGU6IGNvbnZlcnRzIGFsbCBPYmplY3QgdHlwZSB2YWx1ZXMgdG8gbm9uLW1heWJlIHR5cGVzLlxuICovXG50eXBlIFJlcXVpcmVkPFQ+ID0gJE9iak1hcDxULCA8Vj4odjogVikgPT4gJE5vbk1heWJlVHlwZTxWPj47XG5cbi8qKlxuICogT3B0aW9ucyBjb21tb24gdG8ge0BsaW5rIE1hcCNqdW1wVG99LCB7QGxpbmsgTWFwI2Vhc2VUb30sIGFuZCB7QGxpbmsgTWFwI2ZseVRvfSwgY29udHJvbGxpbmcgdGhlIGRlc2lyZWQgbG9jYXRpb24sXG4gKiB6b29tLCBiZWFyaW5nLCBhbmQgcGl0Y2ggb2YgdGhlIGNhbWVyYS4gQWxsIHByb3BlcnRpZXMgYXJlIG9wdGlvbmFsLCBhbmQgd2hlbiBhIHByb3BlcnR5IGlzIG9taXR0ZWQsIHRoZSBjdXJyZW50XG4gKiBjYW1lcmEgdmFsdWUgZm9yIHRoYXQgcHJvcGVydHkgd2lsbCByZW1haW4gdW5jaGFuZ2VkLlxuICpcbiAqIEB0eXBlZGVmIHtPYmplY3R9IENhbWVyYU9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7TG5nTGF0TGlrZX0gY2VudGVyIFRoZSBsb2NhdGlvbiB0byBwbGFjZSBhdCB0aGUgc2NyZWVuIGNlbnRlci5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB6b29tIFRoZSBkZXNpcmVkIHpvb20gbGV2ZWwuXG4gKiBAcHJvcGVydHkge251bWJlcn0gYmVhcmluZyBUaGUgZGVzaXJlZCBiZWFyaW5nIGluIGRlZ3JlZXMuIFRoZSBiZWFyaW5nIGlzIHRoZSBjb21wYXNzIGRpcmVjdGlvbiB0aGF0XG4gKiBpcyBcInVwXCIuIEZvciBleGFtcGxlLCBgYmVhcmluZzogOTBgIG9yaWVudHMgdGhlIG1hcCBzbyB0aGF0IGVhc3QgaXMgdXAuXG4gKiBAcHJvcGVydHkge251bWJlcn0gcGl0Y2ggVGhlIGRlc2lyZWQgcGl0Y2ggaW4gZGVncmVlcy4gVGhlIHBpdGNoIGlzIHRoZSBhbmdsZSB0b3dhcmRzIHRoZSBob3Jpem9uXG4gKiBtZWFzdXJlZCBpbiBkZWdyZWVzIHdpdGggYSByYW5nZSBiZXR3ZWVuIDAgYW5kIDg1IGRlZ3JlZXMuIEZvciBleGFtcGxlLCBwaXRjaDogMCBwcm92aWRlcyB0aGUgYXBwZWFyYW5jZVxuICogb2YgbG9va2luZyBzdHJhaWdodCBkb3duIGF0IHRoZSBtYXAsIHdoaWxlIHBpdGNoOiA2MCB0aWx0cyB0aGUgdXNlcidzIHBlcnNwZWN0aXZlIHRvd2FyZHMgdGhlIGhvcml6b24uXG4gKiBJbmNyZWFzaW5nIHRoZSBwaXRjaCB2YWx1ZSBpcyBvZnRlbiB1c2VkIHRvIGRpc3BsYXkgM0Qgb2JqZWN0cy5cbiAqIEBwcm9wZXJ0eSB7TG5nTGF0TGlrZX0gYXJvdW5kIFRoZSBsb2NhdGlvbiBzZXJ2aW5nIGFzIHRoZSBvcmlnaW4gZm9yIGEgY2hhbmdlIGluIGB6b29tYCwgYHBpdGNoYCBhbmQvb3IgYGJlYXJpbmdgLlxuICogVGhpcyBsb2NhdGlvbiB3aWxsIHJlbWFpbiBhdCB0aGUgc2FtZSBzY3JlZW4gcG9zaXRpb24gZm9sbG93aW5nIHRoZSB0cmFuc2Zvcm0uXG4gKiBUaGlzIGlzIHVzZWZ1bCBmb3IgZHJhd2luZyBhdHRlbnRpb24gdG8gYSBsb2NhdGlvbiB0aGF0IGlzIG5vdCBpbiB0aGUgc2NyZWVuIGNlbnRlci5cbiAqIGBjZW50ZXJgIGlzIGlnbm9yZWQgaWYgYGFyb3VuZGAgaXMgaW5jbHVkZWQuXG4gKiBAcHJvcGVydHkge1BhZGRpbmdPcHRpb25zfSBwYWRkaW5nIERpbWVuc2lvbnMgaW4gcGl4ZWxzIGFwcGxpZWQgb24gZWFjaCBzaWRlIG9mIHRoZSB2aWV3cG9ydCBmb3Igc2hpZnRpbmcgdGhlIHZhbmlzaGluZyBwb2ludC5cbiAqIEBleGFtcGxlXG4gKiAvLyBzZXQgdGhlIG1hcCdzIGluaXRpYWwgcGVyc3BlY3RpdmUgd2l0aCBDYW1lcmFPcHRpb25zXG4gKiBjb25zdCBtYXAgPSBuZXcgbWFwYm94Z2wuTWFwKHtcbiAqICAgICBjb250YWluZXI6ICdtYXAnLFxuICogICAgIHN0eWxlOiAnbWFwYm94Oi8vc3R5bGVzL21hcGJveC9zdHJlZXRzLXYxMScsXG4gKiAgICAgY2VudGVyOiBbLTczLjU4MDQsIDQ1LjUzNDgzXSxcbiAqICAgICBwaXRjaDogNjAsXG4gKiAgICAgYmVhcmluZzogLTYwLFxuICogICAgIHpvb206IDEwXG4gKiB9KTtcbiAqIEBzZWUgW0V4YW1wbGU6IFNldCBwaXRjaCBhbmQgYmVhcmluZ10oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvc2V0LXBlcnNwZWN0aXZlLylcbiAqIEBzZWUgW0V4YW1wbGU6IEp1bXAgdG8gYSBzZXJpZXMgb2YgbG9jYXRpb25zXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9qdW1wLXRvLylcbiAqIEBzZWUgW0V4YW1wbGU6IEZseSB0byBhIGxvY2F0aW9uXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9mbHl0by8pXG4gKiBAc2VlIFtFeGFtcGxlOiBEaXNwbGF5IGJ1aWxkaW5ncyBpbiAzRF0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvM2QtYnVpbGRpbmdzLylcbiAqL1xuZXhwb3J0IHR5cGUgQ2FtZXJhT3B0aW9ucyA9IHtcbiAgICBjZW50ZXI/OiBMbmdMYXRMaWtlLFxuICAgIHpvb20/OiBudW1iZXIsXG4gICAgYmVhcmluZz86IG51bWJlcixcbiAgICBwaXRjaD86IG51bWJlcixcbiAgICBhcm91bmQ/OiBMbmdMYXRMaWtlLFxuICAgIHBhZGRpbmc/OiBQYWRkaW5nT3B0aW9uc1xufTtcblxuZXhwb3J0IHR5cGUgRnVsbENhbWVyYU9wdGlvbnMgPSB7XG4gICAgbWF4Wm9vbTogbnVtYmVyLFxuICAgIG9mZnNldDogUG9pbnRMaWtlLFxuICAgIHBhZGRpbmc6IFJlcXVpcmVkPFBhZGRpbmdPcHRpb25zPlxufSAmIENhbWVyYU9wdGlvbnNcblxuLyoqXG4gKiBPcHRpb25zIGNvbW1vbiB0byBtYXAgbW92ZW1lbnQgbWV0aG9kcyB0aGF0IGludm9sdmUgYW5pbWF0aW9uLCBzdWNoIGFzIHtAbGluayBNYXAjcGFuQnl9IGFuZFxuICoge0BsaW5rIE1hcCNlYXNlVG99LCBjb250cm9sbGluZyB0aGUgZHVyYXRpb24gYW5kIGVhc2luZyBmdW5jdGlvbiBvZiB0aGUgYW5pbWF0aW9uLiBBbGwgcHJvcGVydGllc1xuICogYXJlIG9wdGlvbmFsLlxuICpcbiAqIEB0eXBlZGVmIHtPYmplY3R9IEFuaW1hdGlvbk9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBkdXJhdGlvbiBUaGUgYW5pbWF0aW9uJ3MgZHVyYXRpb24sIG1lYXN1cmVkIGluIG1pbGxpc2Vjb25kcy5cbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IGVhc2luZyBBIGZ1bmN0aW9uIHRha2luZyBhIHRpbWUgaW4gdGhlIHJhbmdlIDAuLjEgYW5kIHJldHVybmluZyBhIG51bWJlciB3aGVyZSAwIGlzXG4gKiAgIHRoZSBpbml0aWFsIHN0YXRlIGFuZCAxIGlzIHRoZSBmaW5hbCBzdGF0ZS5cbiAqIEBwcm9wZXJ0eSB7UG9pbnRMaWtlfSBvZmZzZXQgVGhlIHRhcmdldCBjZW50ZXIncyBvZmZzZXQgcmVsYXRpdmUgdG8gcmVhbCBtYXAgY29udGFpbmVyIGNlbnRlciBhdCB0aGUgZW5kIG9mIGFuaW1hdGlvbi5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gYW5pbWF0ZSBJZiBgZmFsc2VgLCBubyBhbmltYXRpb24gd2lsbCBvY2N1ci5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gZXNzZW50aWFsIElmIGB0cnVlYCwgdGhlbiB0aGUgYW5pbWF0aW9uIGlzIGNvbnNpZGVyZWQgZXNzZW50aWFsIGFuZCB3aWxsIG5vdCBiZSBhZmZlY3RlZCBieVxuICogICBbYHByZWZlcnMtcmVkdWNlZC1tb3Rpb25gXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9DU1MvQG1lZGlhL3ByZWZlcnMtcmVkdWNlZC1tb3Rpb24pLlxuICogQHByb3BlcnR5IHtib29sZWFufSBwcmVsb2FkT25seSBJZiBgdHJ1ZWAsIGl0IHdpbGwgdHJpZ2dlciB0aWxlcyBsb2FkaW5nIGFjcm9zcyB0aGUgYW5pbWF0aW9uIHBhdGgsIGJ1dCBubyBhbmltYXRpb24gd2lsbCBvY2N1ci5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBjdXJ2ZSBUaGUgem9vbWluZyBcImN1cnZlXCIgdGhhdCB3aWxsIG9jY3VyIGFsb25nIHRoZVxuICogICAgIGZsaWdodCBwYXRoLiBBIGhpZ2ggdmFsdWUgbWF4aW1pemVzIHpvb21pbmcgZm9yIGFuIGV4YWdnZXJhdGVkIGFuaW1hdGlvbiwgd2hpbGUgYSBsb3dcbiAqICAgICB2YWx1ZSBtaW5pbWl6ZXMgem9vbWluZyBmb3IgYW4gZWZmZWN0IGNsb3NlciB0byB7QGxpbmsgTWFwI2Vhc2VUb30uIDEuNDIgaXMgdGhlIGF2ZXJhZ2VcbiAqICAgICB2YWx1ZSBzZWxlY3RlZCBieSBwYXJ0aWNpcGFudHMgaW4gdGhlIHVzZXIgc3R1ZHkgZGlzY3Vzc2VkIGluXG4gKiAgICAgW3ZhbiBXaWprICgyMDAzKV0oaHR0cHM6Ly93d3cud2luLnR1ZS5ubC9+dmFud2lqay96b29tcGFuLnBkZikuIEEgdmFsdWUgb2ZcbiAqICAgICBgTWF0aC5wb3coNiwgMC4yNSlgIHdvdWxkIGJlIGVxdWl2YWxlbnQgdG8gdGhlIHJvb3QgbWVhbiBzcXVhcmVkIGF2ZXJhZ2UgdmVsb2NpdHkuIEFcbiAqICAgICB2YWx1ZSBvZiAxIHdvdWxkIHByb2R1Y2UgYSBjaXJjdWxhciBtb3Rpb24uIElmIGBtaW5ab29tYCBpcyBzcGVjaWZpZWQsIHRoaXMgb3B0aW9uIHdpbGwgYmUgaWdub3JlZC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBtaW5ab29tIFRoZSB6ZXJvLWJhc2VkIHpvb20gbGV2ZWwgYXQgdGhlIHBlYWsgb2YgdGhlIGZsaWdodCBwYXRoLiBJZlxuICogICAgIHRoaXMgb3B0aW9uIGlzIHNwZWNpZmllZCwgYGN1cnZlYCB3aWxsIGJlIGlnbm9yZWQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gc3BlZWQgVGhlIGF2ZXJhZ2Ugc3BlZWQgb2YgdGhlIGFuaW1hdGlvbiBkZWZpbmVkIGluIHJlbGF0aW9uIHRvXG4gKiAgICAgYGN1cnZlYC4gQSBzcGVlZCBvZiAxLjIgbWVhbnMgdGhhdCB0aGUgbWFwIGFwcGVhcnMgdG8gbW92ZSBhbG9uZyB0aGUgZmxpZ2h0IHBhdGhcbiAqICAgICBieSAxLjIgdGltZXMgYGN1cnZlYCBzY3JlZW5mdWxzIGV2ZXJ5IHNlY29uZC4gQSBfc2NyZWVuZnVsXyBpcyB0aGUgbWFwJ3MgdmlzaWJsZSBzcGFuLlxuICogICAgIEl0IGRvZXMgbm90IGNvcnJlc3BvbmQgdG8gYSBmaXhlZCBwaHlzaWNhbCBkaXN0YW5jZSwgYnV0IHZhcmllcyBieSB6b29tIGxldmVsLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IHNjcmVlblNwZWVkIFRoZSBhdmVyYWdlIHNwZWVkIG9mIHRoZSBhbmltYXRpb24gbWVhc3VyZWQgaW4gc2NyZWVuZnVsc1xuICogICAgIHBlciBzZWNvbmQsIGFzc3VtaW5nIGEgbGluZWFyIHRpbWluZyBjdXJ2ZS4gSWYgYHNwZWVkYCBpcyBzcGVjaWZpZWQsIHRoaXMgb3B0aW9uIGlzIGlnbm9yZWQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gbWF4RHVyYXRpb24gVGhlIGFuaW1hdGlvbidzIG1heGltdW0gZHVyYXRpb24sIG1lYXN1cmVkIGluIG1pbGxpc2Vjb25kcy5cbiAqICAgICBJZiBkdXJhdGlvbiBleGNlZWRzIG1heGltdW0gZHVyYXRpb24sIGl0IHJlc2V0cyB0byAwLlxuICogQHNlZSBbRXhhbXBsZTogU2xvd2x5IGZseSB0byBhIGxvY2F0aW9uXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9mbHl0by1vcHRpb25zLylcbiAqIEBzZWUgW0V4YW1wbGU6IEN1c3RvbWl6ZSBjYW1lcmEgYW5pbWF0aW9uc10oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvY2FtZXJhLWFuaW1hdGlvbi8pXG4gKiBAc2VlIFtFeGFtcGxlOiBOYXZpZ2F0ZSB0aGUgbWFwIHdpdGggZ2FtZS1saWtlIGNvbnRyb2xzXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9nYW1lLWNvbnRyb2xzLylcbiovXG5leHBvcnQgdHlwZSBBbmltYXRpb25PcHRpb25zID0ge1xuICAgIGR1cmF0aW9uPzogbnVtYmVyLFxuICAgIGVhc2luZz86IChfOiBudW1iZXIpID0+IG51bWJlcixcbiAgICBvZmZzZXQ/OiBQb2ludExpa2UsXG4gICAgYW5pbWF0ZT86IGJvb2xlYW4sXG4gICAgZXNzZW50aWFsPzogYm9vbGVhbixcbiAgICBwcmVsb2FkT25seT86IGJvb2xlYW5cbn07XG5cbmV4cG9ydCB0eXBlIEVhc2luZ09wdGlvbnMgPSBDYW1lcmFPcHRpb25zICYgQW5pbWF0aW9uT3B0aW9ucztcblxuZXhwb3J0IHR5cGUgRWxldmF0aW9uQm94UmF5Y2FzdCA9IHtcbiAgICBtaW5MbmdMYXQ6IExuZ0xhdCxcbiAgICBtYXhMbmdMYXQ6IExuZ0xhdCxcbiAgICBtaW5BbHRpdHVkZTogbnVtYmVyLFxuICAgIG1heEFsdGl0dWRlOiBudW1iZXJcbn07XG5cbmNvbnN0IGZyZWVDYW1lcmFOb3RTdXBwb3J0ZWRXYXJuaW5nID0gJ21hcC5zZXRGcmVlQ2FtZXJhT3B0aW9ucyguLi4pIGFuZCBtYXAuZ2V0RnJlZUNhbWVyYU9wdGlvbnMoKSBhcmUgbm90IHlldCBzdXBwb3J0ZWQgZm9yIG5vbi1tZXJjYXRvciBwcm9qZWN0aW9ucy4nO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHNldHRpbmcgcGFkZGluZyBvbiBjYWxscyB0byBtZXRob2RzIHN1Y2ggYXMge0BsaW5rIE1hcCNmaXRCb3VuZHN9LCB7QGxpbmsgTWFwI2ZpdFNjcmVlbkNvb3JkaW5hdGVzfSwgYW5kIHtAbGluayBNYXAjc2V0UGFkZGluZ30uIEFkanVzdCB0aGVzZSBvcHRpb25zIHRvIHNldCB0aGUgYW1vdW50IG9mIHBhZGRpbmcgaW4gcGl4ZWxzIGFkZGVkIHRvIHRoZSBlZGdlcyBvZiB0aGUgY2FudmFzLiBTZXQgYSB1bmlmb3JtIHBhZGRpbmcgb24gYWxsIGVkZ2VzIG9yIGluZGl2aWR1YWwgdmFsdWVzIGZvciBlYWNoIGVkZ2UuIEFsbCBwcm9wZXJ0aWVzIG9mIHRoaXMgb2JqZWN0IG11c3QgYmVcbiAqIG5vbi1uZWdhdGl2ZSBpbnRlZ2Vycy5cbiAqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBQYWRkaW5nT3B0aW9uc1xuICogQHByb3BlcnR5IHtudW1iZXJ9IHRvcCBQYWRkaW5nIGluIHBpeGVscyBmcm9tIHRoZSB0b3Agb2YgdGhlIG1hcCBjYW52YXMuXG4gKiBAcHJvcGVydHkge251bWJlcn0gYm90dG9tIFBhZGRpbmcgaW4gcGl4ZWxzIGZyb20gdGhlIGJvdHRvbSBvZiB0aGUgbWFwIGNhbnZhcy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBsZWZ0IFBhZGRpbmcgaW4gcGl4ZWxzIGZyb20gdGhlIGxlZnQgb2YgdGhlIG1hcCBjYW52YXMuXG4gKiBAcHJvcGVydHkge251bWJlcn0gcmlnaHQgUGFkZGluZyBpbiBwaXhlbHMgZnJvbSB0aGUgcmlnaHQgb2YgdGhlIG1hcCBjYW52YXMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGJib3ggPSBbWy03OSwgNDNdLCBbLTczLCA0NV1dO1xuICogbWFwLmZpdEJvdW5kcyhiYm94LCB7XG4gKiAgICAgcGFkZGluZzoge3RvcDogMTAsIGJvdHRvbToyNSwgbGVmdDogMTUsIHJpZ2h0OiA1fVxuICogfSk7XG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGJib3ggPSBbWy03OSwgNDNdLCBbLTczLCA0NV1dO1xuICogbWFwLmZpdEJvdW5kcyhiYm94LCB7XG4gKiAgICAgcGFkZGluZzogMjBcbiAqIH0pO1xuICogQHNlZSBbRXhhbXBsZTogRml0IHRvIHRoZSBib3VuZHMgb2YgYSBMaW5lU3RyaW5nXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS96b29tdG8tbGluZXN0cmluZy8pXG4gKiBAc2VlIFtFeGFtcGxlOiBGaXQgYSBtYXAgdG8gYSBib3VuZGluZyBib3hdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2ZpdGJvdW5kcy8pXG4gKi9cblxuY2xhc3MgQ2FtZXJhIGV4dGVuZHMgRXZlbnRlZCB7XG4gICAgdHJhbnNmb3JtOiBUcmFuc2Zvcm07XG4gICAgX21vdmluZzogYm9vbGVhbjtcbiAgICBfem9vbWluZzogYm9vbGVhbjtcbiAgICBfcm90YXRpbmc6IGJvb2xlYW47XG4gICAgX3BpdGNoaW5nOiBib29sZWFuO1xuICAgIF9wYWRkaW5nOiBib29sZWFuO1xuXG4gICAgX2JlYXJpbmdTbmFwOiBudW1iZXI7XG4gICAgX2Vhc2VTdGFydDogbnVtYmVyO1xuICAgIF9lYXNlT3B0aW9uczoge2R1cmF0aW9uOiBudW1iZXIsIGVhc2luZzogKF86IG51bWJlcikgPT4gbnVtYmVyfTtcbiAgICBfZWFzZUlkOiBzdHJpbmcgfCB2b2lkO1xuICAgIF9yZXNwZWN0UHJlZmVyc1JlZHVjZWRNb3Rpb246IGJvb2xlYW47XG5cbiAgICBfb25FYXNlRnJhbWU6ID8oXzogbnVtYmVyKSA9PiBUcmFuc2Zvcm0gfCB2b2lkO1xuICAgIF9vbkVhc2VFbmQ6ID8oZWFzZUlkPzogc3RyaW5nKSA9PiB2b2lkO1xuICAgIF9lYXNlRnJhbWVJZDogP1Rhc2tJRDtcblxuICAgICtfcmVxdWVzdFJlbmRlckZyYW1lOiAoKCkgPT4gdm9pZCkgPT4gVGFza0lEO1xuICAgICtfY2FuY2VsUmVuZGVyRnJhbWU6IChfOiBUYXNrSUQpID0+IHZvaWQ7XG5cbiAgICArX3ByZWxvYWRUaWxlczogKHRyYW5zZm9ybTogVHJhbnNmb3JtIHwgQXJyYXk8VHJhbnNmb3JtPiwgY2FsbGJhY2s/OiBDYWxsYmFjazxhbnk+KSA9PiBhbnk7XG5cbiAgICBjb25zdHJ1Y3Rvcih0cmFuc2Zvcm06IFRyYW5zZm9ybSwgb3B0aW9uczoge2JlYXJpbmdTbmFwOiBudW1iZXIsIHJlc3BlY3RQcmVmZXJzUmVkdWNlZE1vdGlvbjogP2Jvb2xlYW59KSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuX21vdmluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLl96b29taW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMudHJhbnNmb3JtID0gdHJhbnNmb3JtO1xuICAgICAgICB0aGlzLl9iZWFyaW5nU25hcCA9IG9wdGlvbnMuYmVhcmluZ1NuYXA7XG4gICAgICAgIHRoaXMuX3Jlc3BlY3RQcmVmZXJzUmVkdWNlZE1vdGlvbiA9IG9wdGlvbnMucmVzcGVjdFByZWZlcnNSZWR1Y2VkTW90aW9uICE9PSBmYWxzZTtcblxuICAgICAgICBiaW5kQWxsKFsnX3JlbmRlckZyYW1lQ2FsbGJhY2snXSwgdGhpcyk7XG5cbiAgICAgICAgLy9hZGRBc3NlcnRpb25zKHRoaXMpO1xuICAgIH1cblxuICAgIC8qKiBAc2VjdGlvbiB7Q2FtZXJhfVxuICAgICAqIEBtZXRob2RcbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAbWVtYmVyb2YgTWFwICovXG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBtYXAncyBnZW9ncmFwaGljYWwgY2VudGVycG9pbnQuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YgTWFwI1xuICAgICAqIEByZXR1cm5zIHtMbmdMYXR9IFRoZSBtYXAncyBnZW9ncmFwaGljYWwgY2VudGVycG9pbnQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBSZXR1cm4gYSBMbmdMYXQgb2JqZWN0IHN1Y2ggYXMge2xuZzogMCwgbGF0OiAwfS5cbiAgICAgKiBjb25zdCBjZW50ZXIgPSBtYXAuZ2V0Q2VudGVyKCk7XG4gICAgICogLy8gQWNjZXNzIGxvbmdpdHVkZSBhbmQgbGF0aXR1ZGUgdmFsdWVzIGRpcmVjdGx5LlxuICAgICAqIGNvbnN0IHtsbmcsIGxhdH0gPSBtYXAuZ2V0Q2VudGVyKCk7XG4gICAgICogQHNlZSBbVHV0b3JpYWw6IFVzZSBNYXBib3ggR0wgSlMgaW4gYSBSZWFjdCBhcHBdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL2hlbHAvdHV0b3JpYWxzL3VzZS1tYXBib3gtZ2wtanMtd2l0aC1yZWFjdC8jc3RvcmUtdGhlLW5ldy1jb29yZGluYXRlcylcbiAgICAgKi9cbiAgICBnZXRDZW50ZXIoKTogTG5nTGF0IHsgcmV0dXJuIG5ldyBMbmdMYXQodGhpcy50cmFuc2Zvcm0uY2VudGVyLmxuZywgdGhpcy50cmFuc2Zvcm0uY2VudGVyLmxhdCk7IH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIG1hcCdzIGdlb2dyYXBoaWNhbCBjZW50ZXJwb2ludC4gRXF1aXZhbGVudCB0byBganVtcFRvKHtjZW50ZXI6IGNlbnRlcn0pYC5cbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiBNYXAjXG4gICAgICogQHBhcmFtIHtMbmdMYXRMaWtlfSBjZW50ZXIgVGhlIGNlbnRlcnBvaW50IHRvIHNldC5cbiAgICAgKiBAcGFyYW0ge09iamVjdCB8IG51bGx9IGV2ZW50RGF0YSBBZGRpdGlvbmFsIHByb3BlcnRpZXMgdG8gYmUgYWRkZWQgdG8gZXZlbnQgb2JqZWN0cyBvZiBldmVudHMgdHJpZ2dlcmVkIGJ5IHRoaXMgbWV0aG9kLlxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6bW92ZXN0YXJ0XG4gICAgICogQGZpcmVzIE1hcC5ldmVudDptb3ZlZW5kXG4gICAgICogQHJldHVybnMge01hcH0gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIG1hcC5zZXRDZW50ZXIoWy03NCwgMzhdKTtcbiAgICAgKi9cbiAgICBzZXRDZW50ZXIoY2VudGVyOiBMbmdMYXRMaWtlLCBldmVudERhdGE/OiBPYmplY3QpOiB0aGlzIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuanVtcFRvKHtjZW50ZXJ9LCBldmVudERhdGEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhbnMgdGhlIG1hcCBieSB0aGUgc3BlY2lmaWVkIG9mZnNldC5cbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiBNYXAjXG4gICAgICogQHBhcmFtIHtQb2ludExpa2V9IG9mZnNldCBUaGUgYHhgIGFuZCBgeWAgY29vcmRpbmF0ZXMgYnkgd2hpY2ggdG8gcGFuIHRoZSBtYXAuXG4gICAgICogQHBhcmFtIHtBbmltYXRpb25PcHRpb25zIHwgbnVsbH0gb3B0aW9ucyBBbiBvcHRpb25zIG9iamVjdCBkZXNjcmliaW5nIHRoZSBkZXN0aW5hdGlvbiBhbmQgYW5pbWF0aW9uIG9mIHRoZSB0cmFuc2l0aW9uLiBXZSBkbyBub3QgcmVjb21tZW5kIHVzaW5nIGBvcHRpb25zLm9mZnNldGAgc2luY2UgdGhpcyB2YWx1ZSB3aWxsIG92ZXJyaWRlIHRoZSB2YWx1ZSBvZiB0aGUgYG9mZnNldGAgcGFyYW1ldGVyLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0IHwgbnVsbH0gZXZlbnREYXRhIEFkZGl0aW9uYWwgcHJvcGVydGllcyB0byBiZSBhZGRlZCB0byBldmVudCBvYmplY3RzIG9mIGV2ZW50cyB0cmlnZ2VyZWQgYnkgdGhpcyBtZXRob2QuXG4gICAgICogQGZpcmVzIE1hcC5ldmVudDptb3Zlc3RhcnRcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Om1vdmVlbmRcbiAgICAgKiBAcmV0dXJucyB7TWFwfSBgdGhpc2AgUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIG1hcC5wYW5CeShbLTc0LCAzOF0pO1xuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gcGFuQnkgd2l0aCBhbiBhbmltYXRpb24gb2YgNSBzZWNvbmRzLlxuICAgICAqIG1hcC5wYW5CeShbLTc0LCAzOF0sIHtkdXJhdGlvbjogNTAwMH0pO1xuICAgICAqIEBzZWUgW0V4YW1wbGU6IE5hdmlnYXRlIHRoZSBtYXAgd2l0aCBnYW1lLWxpa2UgY29udHJvbHNdKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvZ2FtZS1jb250cm9scy8pXG4gICAgICovXG4gICAgcGFuQnkob2Zmc2V0OiBQb2ludExpa2UsIG9wdGlvbnM/OiBBbmltYXRpb25PcHRpb25zLCBldmVudERhdGE/OiBPYmplY3QpOiB0aGlzIHtcbiAgICAgICAgb2Zmc2V0ID0gUG9pbnQuY29udmVydChvZmZzZXQpLm11bHQoLTEpO1xuICAgICAgICByZXR1cm4gdGhpcy5wYW5Ubyh0aGlzLnRyYW5zZm9ybS5jZW50ZXIsIGV4dGVuZCh7b2Zmc2V0fSwgb3B0aW9ucyksIGV2ZW50RGF0YSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFucyB0aGUgbWFwIHRvIHRoZSBzcGVjaWZpZWQgbG9jYXRpb24gd2l0aCBhbiBhbmltYXRlZCB0cmFuc2l0aW9uLlxuICAgICAqXG4gICAgICogQG1lbWJlcm9mIE1hcCNcbiAgICAgKiBAcGFyYW0ge0xuZ0xhdExpa2V9IGxuZ2xhdCBUaGUgbG9jYXRpb24gdG8gcGFuIHRoZSBtYXAgdG8uXG4gICAgICogQHBhcmFtIHtBbmltYXRpb25PcHRpb25zIHwgbnVsbH0gb3B0aW9ucyBPcHRpb25zIGRlc2NyaWJpbmcgdGhlIGRlc3RpbmF0aW9uIGFuZCBhbmltYXRpb24gb2YgdGhlIHRyYW5zaXRpb24uXG4gICAgICogQHBhcmFtIHtPYmplY3QgfCBudWxsfSBldmVudERhdGEgQWRkaXRpb25hbCBwcm9wZXJ0aWVzIHRvIGJlIGFkZGVkIHRvIGV2ZW50IG9iamVjdHMgb2YgZXZlbnRzIHRyaWdnZXJlZCBieSB0aGlzIG1ldGhvZC5cbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Om1vdmVzdGFydFxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6bW92ZWVuZFxuICAgICAqIEByZXR1cm5zIHtNYXB9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAucGFuVG8oWy03NCwgMzhdKTtcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIFNwZWNpZnkgdGhhdCB0aGUgcGFuVG8gYW5pbWF0aW9uIHNob3VsZCBsYXN0IDUwMDAgbWlsbGlzZWNvbmRzLlxuICAgICAqIG1hcC5wYW5UbyhbLTc0LCAzOF0sIHtkdXJhdGlvbjogNTAwMH0pO1xuICAgICAqIEBzZWUgW0V4YW1wbGU6IFVwZGF0ZSBhIGZlYXR1cmUgaW4gcmVhbHRpbWVdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2xpdmUtdXBkYXRlLWZlYXR1cmUvKVxuICAgICAqL1xuICAgIHBhblRvKGxuZ2xhdDogTG5nTGF0TGlrZSwgb3B0aW9ucz86IEFuaW1hdGlvbk9wdGlvbnMsIGV2ZW50RGF0YT86IE9iamVjdCk6IHRoaXMge1xuICAgICAgICByZXR1cm4gdGhpcy5lYXNlVG8oZXh0ZW5kKHtcbiAgICAgICAgICAgIGNlbnRlcjogbG5nbGF0XG4gICAgICAgIH0sIG9wdGlvbnMpLCBldmVudERhdGEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIG1hcCdzIGN1cnJlbnQgem9vbSBsZXZlbC5cbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiBNYXAjXG4gICAgICogQHJldHVybnMge251bWJlcn0gVGhlIG1hcCdzIGN1cnJlbnQgem9vbSBsZXZlbC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIG1hcC5nZXRab29tKCk7XG4gICAgICovXG4gICAgZ2V0Wm9vbSgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy50cmFuc2Zvcm0uem9vbTsgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgbWFwJ3Mgem9vbSBsZXZlbC4gRXF1aXZhbGVudCB0byBganVtcFRvKHt6b29tOiB6b29tfSlgLlxuICAgICAqXG4gICAgICogQG1lbWJlcm9mIE1hcCNcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gem9vbSBUaGUgem9vbSBsZXZlbCB0byBzZXQgKDAtMjApLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0IHwgbnVsbH0gZXZlbnREYXRhIEFkZGl0aW9uYWwgcHJvcGVydGllcyB0byBiZSBhZGRlZCB0byBldmVudCBvYmplY3RzIG9mIGV2ZW50cyB0cmlnZ2VyZWQgYnkgdGhpcyBtZXRob2QuXG4gICAgICogQGZpcmVzIE1hcC5ldmVudDptb3Zlc3RhcnRcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Onpvb21zdGFydFxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6bW92ZVxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6em9vbVxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6bW92ZWVuZFxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6em9vbWVuZFxuICAgICAqIEByZXR1cm5zIHtNYXB9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBab29tIHRvIHRoZSB6b29tIGxldmVsIDUgd2l0aG91dCBhbiBhbmltYXRlZCB0cmFuc2l0aW9uXG4gICAgICogbWFwLnNldFpvb20oNSk7XG4gICAgICovXG4gICAgc2V0Wm9vbSh6b29tOiBudW1iZXIsIGV2ZW50RGF0YT86IE9iamVjdCk6IHRoaXMge1xuICAgICAgICB0aGlzLmp1bXBUbyh7em9vbX0sIGV2ZW50RGF0YSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFpvb21zIHRoZSBtYXAgdG8gdGhlIHNwZWNpZmllZCB6b29tIGxldmVsLCB3aXRoIGFuIGFuaW1hdGVkIHRyYW5zaXRpb24uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YgTWFwI1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB6b29tIFRoZSB6b29tIGxldmVsIHRvIHRyYW5zaXRpb24gdG8uXG4gICAgICogQHBhcmFtIHtBbmltYXRpb25PcHRpb25zIHwgbnVsbH0gb3B0aW9ucyBPcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge09iamVjdCB8IG51bGx9IGV2ZW50RGF0YSBBZGRpdGlvbmFsIHByb3BlcnRpZXMgdG8gYmUgYWRkZWQgdG8gZXZlbnQgb2JqZWN0cyBvZiBldmVudHMgdHJpZ2dlcmVkIGJ5IHRoaXMgbWV0aG9kLlxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6bW92ZXN0YXJ0XG4gICAgICogQGZpcmVzIE1hcC5ldmVudDp6b29tc3RhcnRcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Om1vdmVcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Onpvb21cbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Om1vdmVlbmRcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Onpvb21lbmRcbiAgICAgKiBAcmV0dXJucyB7TWFwfSBSZXR1cm5zIGl0c2VsZiB0byBhbGxvdyBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gWm9vbSB0byB0aGUgem9vbSBsZXZlbCA1IHdpdGhvdXQgYW4gYW5pbWF0ZWQgdHJhbnNpdGlvblxuICAgICAqIG1hcC56b29tVG8oNSk7XG4gICAgICogLy8gWm9vbSB0byB0aGUgem9vbSBsZXZlbCA4IHdpdGggYW4gYW5pbWF0ZWQgdHJhbnNpdGlvblxuICAgICAqIG1hcC56b29tVG8oOCwge1xuICAgICAqICAgICBkdXJhdGlvbjogMjAwMCxcbiAgICAgKiAgICAgb2Zmc2V0OiBbMTAwLCA1MF1cbiAgICAgKiB9KTtcbiAgICAgKi9cbiAgICB6b29tVG8oem9vbTogbnVtYmVyLCBvcHRpb25zOiA/IEFuaW1hdGlvbk9wdGlvbnMsIGV2ZW50RGF0YT86IE9iamVjdCk6IHRoaXMge1xuICAgICAgICByZXR1cm4gdGhpcy5lYXNlVG8oZXh0ZW5kKHtcbiAgICAgICAgICAgIHpvb21cbiAgICAgICAgfSwgb3B0aW9ucyksIGV2ZW50RGF0YSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW5jcmVhc2VzIHRoZSBtYXAncyB6b29tIGxldmVsIGJ5IDEuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YgTWFwI1xuICAgICAqIEBwYXJhbSB7QW5pbWF0aW9uT3B0aW9ucyB8IG51bGx9IG9wdGlvbnMgT3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtIHtPYmplY3QgfCBudWxsfSBldmVudERhdGEgQWRkaXRpb25hbCBwcm9wZXJ0aWVzIHRvIGJlIGFkZGVkIHRvIGV2ZW50IG9iamVjdHMgb2YgZXZlbnRzIHRyaWdnZXJlZCBieSB0aGlzIG1ldGhvZC5cbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Om1vdmVzdGFydFxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6em9vbXN0YXJ0XG4gICAgICogQGZpcmVzIE1hcC5ldmVudDptb3ZlXG4gICAgICogQGZpcmVzIE1hcC5ldmVudDp6b29tXG4gICAgICogQGZpcmVzIE1hcC5ldmVudDptb3ZlZW5kXG4gICAgICogQGZpcmVzIE1hcC5ldmVudDp6b29tZW5kXG4gICAgICogQHJldHVybnMge01hcH0gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIHpvb20gdGhlIG1hcCBpbiBvbmUgbGV2ZWwgd2l0aCBhIGN1c3RvbSBhbmltYXRpb24gZHVyYXRpb25cbiAgICAgKiBtYXAuem9vbUluKHtkdXJhdGlvbjogMTAwMH0pO1xuICAgICAqL1xuICAgIHpvb21JbihvcHRpb25zPzogQW5pbWF0aW9uT3B0aW9ucywgZXZlbnREYXRhPzogT2JqZWN0KTogdGhpcyB7XG4gICAgICAgIHRoaXMuem9vbVRvKHRoaXMuZ2V0Wm9vbSgpICsgMSwgb3B0aW9ucywgZXZlbnREYXRhKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGVjcmVhc2VzIHRoZSBtYXAncyB6b29tIGxldmVsIGJ5IDEuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YgTWFwI1xuICAgICAqIEBwYXJhbSB7QW5pbWF0aW9uT3B0aW9ucyB8IG51bGx9IG9wdGlvbnMgT3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtIHtPYmplY3QgfCBudWxsfSBldmVudERhdGEgQWRkaXRpb25hbCBwcm9wZXJ0aWVzIHRvIGJlIGFkZGVkIHRvIGV2ZW50IG9iamVjdHMgb2YgZXZlbnRzIHRyaWdnZXJlZCBieSB0aGlzIG1ldGhvZC5cbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Om1vdmVzdGFydFxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6em9vbXN0YXJ0XG4gICAgICogQGZpcmVzIE1hcC5ldmVudDptb3ZlXG4gICAgICogQGZpcmVzIE1hcC5ldmVudDp6b29tXG4gICAgICogQGZpcmVzIE1hcC5ldmVudDptb3ZlZW5kXG4gICAgICogQGZpcmVzIE1hcC5ldmVudDp6b29tZW5kXG4gICAgICogQHJldHVybnMge01hcH0gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIHpvb20gdGhlIG1hcCBvdXQgb25lIGxldmVsIHdpdGggYSBjdXN0b20gYW5pbWF0aW9uIG9mZnNldFxuICAgICAqIG1hcC56b29tT3V0KHtvZmZzZXQ6IFs4MCwgNjBdfSk7XG4gICAgICovXG4gICAgem9vbU91dChvcHRpb25zPzogQW5pbWF0aW9uT3B0aW9ucywgZXZlbnREYXRhPzogT2JqZWN0KTogdGhpcyB7XG4gICAgICAgIHRoaXMuem9vbVRvKHRoaXMuZ2V0Wm9vbSgpIC0gMSwgb3B0aW9ucywgZXZlbnREYXRhKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgbWFwJ3MgY3VycmVudCBiZWFyaW5nLiBUaGUgYmVhcmluZyBpcyB0aGUgY29tcGFzcyBkaXJlY3Rpb24gdGhhdCBpcyBcInVwXCI7IGZvciBleGFtcGxlLCBhIGJlYXJpbmdcbiAgICAgKiBvZiA5MMKwIG9yaWVudHMgdGhlIG1hcCBzbyB0aGF0IGVhc3QgaXMgdXAuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YgTWFwI1xuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFRoZSBtYXAncyBjdXJyZW50IGJlYXJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBiZWFyaW5nID0gbWFwLmdldEJlYXJpbmcoKTtcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBOYXZpZ2F0ZSB0aGUgbWFwIHdpdGggZ2FtZS1saWtlIGNvbnRyb2xzXShodHRwczovL3d3dy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2dhbWUtY29udHJvbHMvKVxuICAgICAqL1xuICAgIGdldEJlYXJpbmcoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNmb3JtLmJlYXJpbmc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgbWFwJ3MgYmVhcmluZyAocm90YXRpb24pLiBUaGUgYmVhcmluZyBpcyB0aGUgY29tcGFzcyBkaXJlY3Rpb24gdGhhdCBpcyBcInVwXCI7IGZvciBleGFtcGxlLCBhIGJlYXJpbmdcbiAgICAgKiBvZiA5MMKwIG9yaWVudHMgdGhlIG1hcCBzbyB0aGF0IGVhc3QgaXMgdXAuXG4gICAgICpcbiAgICAgKiBFcXVpdmFsZW50IHRvIGBqdW1wVG8oe2JlYXJpbmc6IGJlYXJpbmd9KWAuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YgTWFwI1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiZWFyaW5nIFRoZSBkZXNpcmVkIGJlYXJpbmcuXG4gICAgICogQHBhcmFtIHtPYmplY3QgfCBudWxsfSBldmVudERhdGEgQWRkaXRpb25hbCBwcm9wZXJ0aWVzIHRvIGJlIGFkZGVkIHRvIGV2ZW50IG9iamVjdHMgb2YgZXZlbnRzIHRyaWdnZXJlZCBieSB0aGlzIG1ldGhvZC5cbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Om1vdmVzdGFydFxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6bW92ZWVuZFxuICAgICAqIEByZXR1cm5zIHtNYXB9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBSb3RhdGUgdGhlIG1hcCB0byA5MCBkZWdyZWVzLlxuICAgICAqIG1hcC5zZXRCZWFyaW5nKDkwKTtcbiAgICAgKi9cbiAgICBzZXRCZWFyaW5nKGJlYXJpbmc6IG51bWJlciwgZXZlbnREYXRhPzogT2JqZWN0KTogdGhpcyB7XG4gICAgICAgIHRoaXMuanVtcFRvKHtiZWFyaW5nfSwgZXZlbnREYXRhKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgY3VycmVudCBwYWRkaW5nIGFwcGxpZWQgYXJvdW5kIHRoZSBtYXAgdmlld3BvcnQuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YgTWFwI1xuICAgICAqIEByZXR1cm5zIHtQYWRkaW5nT3B0aW9uc30gVGhlIGN1cnJlbnQgcGFkZGluZyBhcm91bmQgdGhlIG1hcCB2aWV3cG9ydC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBhZGRpbmcgPSBtYXAuZ2V0UGFkZGluZygpO1xuICAgICAqL1xuICAgIGdldFBhZGRpbmcoKTogUGFkZGluZ09wdGlvbnMgeyByZXR1cm4gdGhpcy50cmFuc2Zvcm0ucGFkZGluZzsgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgcGFkZGluZyBpbiBwaXhlbHMgYXJvdW5kIHRoZSB2aWV3cG9ydC5cbiAgICAgKlxuICAgICAqIEVxdWl2YWxlbnQgdG8gYGp1bXBUbyh7cGFkZGluZzogcGFkZGluZ30pYC5cbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiBNYXAjXG4gICAgICogQHBhcmFtIHtQYWRkaW5nT3B0aW9uc30gcGFkZGluZyBUaGUgZGVzaXJlZCBwYWRkaW5nLiBGb3JtYXQ6IHtsZWZ0OiBudW1iZXIsIHJpZ2h0OiBudW1iZXIsIHRvcDogbnVtYmVyLCBib3R0b206IG51bWJlcn0uXG4gICAgICogQHBhcmFtIHtPYmplY3QgfCBudWxsfSBldmVudERhdGEgQWRkaXRpb25hbCBwcm9wZXJ0aWVzIHRvIGJlIGFkZGVkIHRvIGV2ZW50IG9iamVjdHMgb2YgZXZlbnRzIHRyaWdnZXJlZCBieSB0aGlzIG1ldGhvZC5cbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Om1vdmVzdGFydFxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6bW92ZWVuZFxuICAgICAqIEByZXR1cm5zIHtNYXB9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBTZXRzIGEgbGVmdCBwYWRkaW5nIG9mIDMwMHB4LCBhbmQgYSB0b3AgcGFkZGluZyBvZiA1MHB4XG4gICAgICogbWFwLnNldFBhZGRpbmcoe2xlZnQ6IDMwMCwgdG9wOiA1MH0pO1xuICAgICAqL1xuICAgIHNldFBhZGRpbmcocGFkZGluZzogUGFkZGluZ09wdGlvbnMsIGV2ZW50RGF0YT86IE9iamVjdCk6IHRoaXMge1xuICAgICAgICB0aGlzLmp1bXBUbyh7cGFkZGluZ30sIGV2ZW50RGF0YSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJvdGF0ZXMgdGhlIG1hcCB0byB0aGUgc3BlY2lmaWVkIGJlYXJpbmcsIHdpdGggYW4gYW5pbWF0ZWQgdHJhbnNpdGlvbi4gVGhlIGJlYXJpbmcgaXMgdGhlIGNvbXBhc3MgZGlyZWN0aW9uXG4gICAgICogdGhhdCBpcyBcXFwidXBcXFwiOyBmb3IgZXhhbXBsZSwgYSBiZWFyaW5nIG9mIDkwwrAgb3JpZW50cyB0aGUgbWFwIHNvIHRoYXQgZWFzdCBpcyB1cC5cbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiBNYXAjXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJlYXJpbmcgVGhlIGRlc2lyZWQgYmVhcmluZy5cbiAgICAgKiBAcGFyYW0ge0Vhc2luZ09wdGlvbnMgfCBudWxsfSBvcHRpb25zIE9wdGlvbnMgZGVzY3JpYmluZyB0aGUgZGVzdGluYXRpb24gYW5kIGFuaW1hdGlvbiBvZiB0aGUgdHJhbnNpdGlvbi5cbiAgICAgKiAgICAgICAgICAgIEFjY2VwdHMge0BsaW5rIENhbWVyYU9wdGlvbnN9IGFuZCB7QGxpbmsgQW5pbWF0aW9uT3B0aW9uc30uXG4gICAgICogQHBhcmFtIHtPYmplY3QgfCBudWxsfSBldmVudERhdGEgQWRkaXRpb25hbCBwcm9wZXJ0aWVzIHRvIGJlIGFkZGVkIHRvIGV2ZW50IG9iamVjdHMgb2YgZXZlbnRzIHRyaWdnZXJlZCBieSB0aGlzIG1ldGhvZC5cbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Om1vdmVzdGFydFxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6bW92ZWVuZFxuICAgICAqIEByZXR1cm5zIHtNYXB9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAucm90YXRlVG8oMzApO1xuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gcm90YXRlVG8gd2l0aCBhbiBhbmltYXRpb24gb2YgMiBzZWNvbmRzLlxuICAgICAqIG1hcC5yb3RhdGVUbygzMCwge2R1cmF0aW9uOiAyMDAwfSk7XG4gICAgICovXG4gICAgcm90YXRlVG8oYmVhcmluZzogbnVtYmVyLCBvcHRpb25zPzogRWFzaW5nT3B0aW9ucywgZXZlbnREYXRhPzogT2JqZWN0KTogdGhpcyB7XG4gICAgICAgIHJldHVybiB0aGlzLmVhc2VUbyhleHRlbmQoe1xuICAgICAgICAgICAgYmVhcmluZ1xuICAgICAgICB9LCBvcHRpb25zKSwgZXZlbnREYXRhKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSb3RhdGVzIHRoZSBtYXAgc28gdGhhdCBub3J0aCBpcyB1cCAoMMKwIGJlYXJpbmcpLCB3aXRoIGFuIGFuaW1hdGVkIHRyYW5zaXRpb24uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YgTWFwI1xuICAgICAqIEBwYXJhbSB7RWFzaW5nT3B0aW9ucyB8IG51bGx9IG9wdGlvbnMgT3B0aW9ucyBkZXNjcmliaW5nIHRoZSBkZXN0aW5hdGlvbiBhbmQgYW5pbWF0aW9uIG9mIHRoZSB0cmFuc2l0aW9uLlxuICAgICAqICAgICAgICAgICAgQWNjZXB0cyB7QGxpbmsgQ2FtZXJhT3B0aW9uc30gYW5kIHtAbGluayBBbmltYXRpb25PcHRpb25zfS5cbiAgICAgKiBAcGFyYW0ge09iamVjdCB8IG51bGx9IGV2ZW50RGF0YSBBZGRpdGlvbmFsIHByb3BlcnRpZXMgdG8gYmUgYWRkZWQgdG8gZXZlbnQgb2JqZWN0cyBvZiBldmVudHMgdHJpZ2dlcmVkIGJ5IHRoaXMgbWV0aG9kLlxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6bW92ZXN0YXJ0XG4gICAgICogQGZpcmVzIE1hcC5ldmVudDptb3ZlZW5kXG4gICAgICogQHJldHVybnMge01hcH0gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIHJlc2V0Tm9ydGggd2l0aCBhbiBhbmltYXRpb24gb2YgMiBzZWNvbmRzLlxuICAgICAqIG1hcC5yZXNldE5vcnRoKHtkdXJhdGlvbjogMjAwMH0pO1xuICAgICAqL1xuICAgIHJlc2V0Tm9ydGgob3B0aW9ucz86IEVhc2luZ09wdGlvbnMsIGV2ZW50RGF0YT86IE9iamVjdCk6IHRoaXMge1xuICAgICAgICB0aGlzLnJvdGF0ZVRvKDAsIGV4dGVuZCh7ZHVyYXRpb246IDEwMDB9LCBvcHRpb25zKSwgZXZlbnREYXRhKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUm90YXRlcyBhbmQgcGl0Y2hlcyB0aGUgbWFwIHNvIHRoYXQgbm9ydGggaXMgdXAgKDDCsCBiZWFyaW5nKSBhbmQgcGl0Y2ggaXMgMMKwLCB3aXRoIGFuIGFuaW1hdGVkIHRyYW5zaXRpb24uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YgTWFwI1xuICAgICAqIEBwYXJhbSB7RWFzaW5nT3B0aW9ucyB8IG51bGx9IG9wdGlvbnMgT3B0aW9ucyBkZXNjcmliaW5nIHRoZSBkZXN0aW5hdGlvbiBhbmQgYW5pbWF0aW9uIG9mIHRoZSB0cmFuc2l0aW9uLlxuICAgICAqICAgICAgICAgICAgQWNjZXB0cyB7QGxpbmsgQ2FtZXJhT3B0aW9uc30gYW5kIHtAbGluayBBbmltYXRpb25PcHRpb25zfS5cbiAgICAgKiBAcGFyYW0ge09iamVjdCB8IG51bGx9IGV2ZW50RGF0YSBBZGRpdGlvbmFsIHByb3BlcnRpZXMgdG8gYmUgYWRkZWQgdG8gZXZlbnQgb2JqZWN0cyBvZiBldmVudHMgdHJpZ2dlcmVkIGJ5IHRoaXMgbWV0aG9kLlxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6bW92ZXN0YXJ0XG4gICAgICogQGZpcmVzIE1hcC5ldmVudDptb3ZlZW5kXG4gICAgICogQHJldHVybnMge01hcH0gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIHJlc2V0Tm9ydGhQaXRjaCB3aXRoIGFuIGFuaW1hdGlvbiBvZiAyIHNlY29uZHMuXG4gICAgICogbWFwLnJlc2V0Tm9ydGhQaXRjaCh7ZHVyYXRpb246IDIwMDB9KTtcbiAgICAgKi9cbiAgICByZXNldE5vcnRoUGl0Y2gob3B0aW9ucz86IEVhc2luZ09wdGlvbnMsIGV2ZW50RGF0YT86IE9iamVjdCk6IHRoaXMge1xuICAgICAgICB0aGlzLmVhc2VUbyhleHRlbmQoe1xuICAgICAgICAgICAgYmVhcmluZzogMCxcbiAgICAgICAgICAgIHBpdGNoOiAwLFxuICAgICAgICAgICAgZHVyYXRpb246IDEwMDBcbiAgICAgICAgfSwgb3B0aW9ucyksIGV2ZW50RGF0YSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNuYXBzIHRoZSBtYXAgc28gdGhhdCBub3J0aCBpcyB1cCAoMMKwIGJlYXJpbmcpLCBpZiB0aGUgY3VycmVudCBiZWFyaW5nIGlzXG4gICAgICogY2xvc2UgZW5vdWdoIHRvIGl0ICh3aXRoaW4gdGhlIGBiZWFyaW5nU25hcGAgdGhyZXNob2xkKS5cbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiBNYXAjXG4gICAgICogQHBhcmFtIHtFYXNpbmdPcHRpb25zIHwgbnVsbH0gb3B0aW9ucyBPcHRpb25zIGRlc2NyaWJpbmcgdGhlIGRlc3RpbmF0aW9uIGFuZCBhbmltYXRpb24gb2YgdGhlIHRyYW5zaXRpb24uXG4gICAgICogICAgICAgICAgICBBY2NlcHRzIHtAbGluayBDYW1lcmFPcHRpb25zfSBhbmQge0BsaW5rIEFuaW1hdGlvbk9wdGlvbnN9LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0IHwgbnVsbH0gZXZlbnREYXRhIEFkZGl0aW9uYWwgcHJvcGVydGllcyB0byBiZSBhZGRlZCB0byBldmVudCBvYmplY3RzIG9mIGV2ZW50cyB0cmlnZ2VyZWQgYnkgdGhpcyBtZXRob2QuXG4gICAgICogQGZpcmVzIE1hcC5ldmVudDptb3Zlc3RhcnRcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Om1vdmVlbmRcbiAgICAgKiBAcmV0dXJucyB7TWFwfSBSZXR1cm5zIGl0c2VsZiB0byBhbGxvdyBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gc25hcFRvTm9ydGggd2l0aCBhbiBhbmltYXRpb24gb2YgMiBzZWNvbmRzLlxuICAgICAqIG1hcC5zbmFwVG9Ob3J0aCh7ZHVyYXRpb246IDIwMDB9KTtcbiAgICAgKi9cbiAgICBzbmFwVG9Ob3J0aChvcHRpb25zPzogRWFzaW5nT3B0aW9ucywgZXZlbnREYXRhPzogT2JqZWN0KTogdGhpcyB7XG4gICAgICAgIGlmIChNYXRoLmFicyh0aGlzLmdldEJlYXJpbmcoKSkgPCB0aGlzLl9iZWFyaW5nU25hcCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVzZXROb3J0aChvcHRpb25zLCBldmVudERhdGEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIG1hcCdzIGN1cnJlbnQgW3BpdGNoXShodHRwczovL2RvY3MubWFwYm94LmNvbS9oZWxwL2dsb3NzYXJ5L2NhbWVyYS8pICh0aWx0KS5cbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiBNYXAjXG4gICAgICogQHJldHVybnMge251bWJlcn0gVGhlIG1hcCdzIGN1cnJlbnQgcGl0Y2gsIG1lYXN1cmVkIGluIGRlZ3JlZXMgYXdheSBmcm9tIHRoZSBwbGFuZSBvZiB0aGUgc2NyZWVuLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcGl0Y2ggPSBtYXAuZ2V0UGl0Y2goKTtcbiAgICAgKi9cbiAgICBnZXRQaXRjaCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy50cmFuc2Zvcm0ucGl0Y2g7IH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIG1hcCdzIFtwaXRjaF0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vaGVscC9nbG9zc2FyeS9jYW1lcmEvKSAodGlsdCkuIEVxdWl2YWxlbnQgdG8gYGp1bXBUbyh7cGl0Y2g6IHBpdGNofSlgLlxuICAgICAqXG4gICAgICogQG1lbWJlcm9mIE1hcCNcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcGl0Y2ggVGhlIHBpdGNoIHRvIHNldCwgbWVhc3VyZWQgaW4gZGVncmVlcyBhd2F5IGZyb20gdGhlIHBsYW5lIG9mIHRoZSBzY3JlZW4gKDAtNjApLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0IHwgbnVsbH0gZXZlbnREYXRhIEFkZGl0aW9uYWwgcHJvcGVydGllcyB0byBiZSBhZGRlZCB0byBldmVudCBvYmplY3RzIG9mIGV2ZW50cyB0cmlnZ2VyZWQgYnkgdGhpcyBtZXRob2QuXG4gICAgICogQGZpcmVzIE1hcC5ldmVudDpwaXRjaHN0YXJ0XG4gICAgICogQGZpcmVzIE1hcC5ldmVudDptb3Zlc3RhcnRcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Om1vdmVlbmRcbiAgICAgKiBAcmV0dXJucyB7TWFwfSBSZXR1cm5zIGl0c2VsZiB0byBhbGxvdyBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gc2V0UGl0Y2ggd2l0aCBhbiBhbmltYXRpb24gb2YgMiBzZWNvbmRzLlxuICAgICAqIG1hcC5zZXRQaXRjaCg4MCwge2R1cmF0aW9uOiAyMDAwfSk7XG4gICAgICovXG4gICAgc2V0UGl0Y2gocGl0Y2g6IG51bWJlciwgZXZlbnREYXRhPzogT2JqZWN0KTogdGhpcyB7XG4gICAgICAgIHRoaXMuanVtcFRvKHtwaXRjaH0sIGV2ZW50RGF0YSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSB7QGxpbmsgQ2FtZXJhT3B0aW9uc30gb2JqZWN0IGZvciB0aGUgaGlnaGVzdCB6b29tIGxldmVsXG4gICAgICogdXAgdG8gYW5kIGluY2x1ZGluZyBgTWFwI2dldE1heFpvb20oKWAgdGhhdCBmaXRzIHRoZSBib3VuZHNcbiAgICAgKiBpbiB0aGUgdmlld3BvcnQgYXQgdGhlIHNwZWNpZmllZCBiZWFyaW5nLlxuICAgICAqXG4gICAgICogQG1lbWJlcm9mIE1hcCNcbiAgICAgKiBAcGFyYW0ge0xuZ0xhdEJvdW5kc0xpa2V9IGJvdW5kcyBDYWxjdWxhdGUgdGhlIGNlbnRlciBmb3IgdGhlc2UgYm91bmRzIGluIHRoZSB2aWV3cG9ydCBhbmQgdXNlXG4gICAgICogICAgICB0aGUgaGlnaGVzdCB6b29tIGxldmVsIHVwIHRvIGFuZCBpbmNsdWRpbmcgYE1hcCNnZXRNYXhab29tKClgIHRoYXQgZml0c1xuICAgICAqICAgICAgaW4gdGhlIHZpZXdwb3J0LiBMbmdMYXRCb3VuZHMgcmVwcmVzZW50IGEgYm94IHRoYXQgaXMgYWx3YXlzIGF4aXMtYWxpZ25lZCB3aXRoIGJlYXJpbmcgMC5cbiAgICAgKiBAcGFyYW0ge0NhbWVyYU9wdGlvbnMgfCBudWxsfSBvcHRpb25zIE9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyIHwgUGFkZGluZ09wdGlvbnN9IFtvcHRpb25zLnBhZGRpbmddIFRoZSBhbW91bnQgb2YgcGFkZGluZyBpbiBwaXhlbHMgdG8gYWRkIHRvIHRoZSBnaXZlbiBib3VuZHMuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLmJlYXJpbmc9MF0gRGVzaXJlZCBtYXAgYmVhcmluZyBhdCBlbmQgb2YgYW5pbWF0aW9uLCBpbiBkZWdyZWVzLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5waXRjaD0wXSBEZXNpcmVkIG1hcCBwaXRjaCBhdCBlbmQgb2YgYW5pbWF0aW9uLCBpbiBkZWdyZWVzLlxuICAgICAqIEBwYXJhbSB7UG9pbnRMaWtlfSBbb3B0aW9ucy5vZmZzZXQ9WzAsIDBdXSBUaGUgY2VudGVyIG9mIHRoZSBnaXZlbiBib3VuZHMgcmVsYXRpdmUgdG8gdGhlIG1hcCdzIGNlbnRlciwgbWVhc3VyZWQgaW4gcGl4ZWxzLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5tYXhab29tXSBUaGUgbWF4aW11bSB6b29tIGxldmVsIHRvIGFsbG93IHdoZW4gdGhlIGNhbWVyYSB3b3VsZCB0cmFuc2l0aW9uIHRvIHRoZSBzcGVjaWZpZWQgYm91bmRzLlxuICAgICAqIEByZXR1cm5zIHtDYW1lcmFPcHRpb25zIHwgdm9pZH0gSWYgbWFwIGlzIGFibGUgdG8gZml0IHRvIHByb3ZpZGVkIGJvdW5kcywgcmV0dXJucyBgQ2FtZXJhT3B0aW9uc2Agd2l0aFxuICAgICAqICAgICAgYGNlbnRlcmAsIGB6b29tYCwgYW5kIGBiZWFyaW5nYC4gSWYgbWFwIGlzIHVuYWJsZSB0byBmaXQsIG1ldGhvZCB3aWxsIHdhcm4gYW5kIHJldHVybiB1bmRlZmluZWQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBiYm94ID0gW1stNzksIDQzXSwgWy03MywgNDVdXTtcbiAgICAgKiBjb25zdCBuZXdDYW1lcmFUcmFuc2Zvcm0gPSBtYXAuY2FtZXJhRm9yQm91bmRzKGJib3gsIHtcbiAgICAgKiAgICAgcGFkZGluZzoge3RvcDogMTAsIGJvdHRvbToyNSwgbGVmdDogMTUsIHJpZ2h0OiA1fVxuICAgICAqIH0pO1xuICAgICAqL1xuICAgIGNhbWVyYUZvckJvdW5kcyhib3VuZHM6IExuZ0xhdEJvdW5kc0xpa2UsIG9wdGlvbnM/OiBDYW1lcmFPcHRpb25zKTogP0Vhc2luZ09wdGlvbnMge1xuICAgICAgICBib3VuZHMgPSBMbmdMYXRCb3VuZHMuY29udmVydChib3VuZHMpO1xuICAgICAgICBjb25zdCBiZWFyaW5nID0gKG9wdGlvbnMgJiYgb3B0aW9ucy5iZWFyaW5nKSB8fCAwO1xuICAgICAgICBjb25zdCBwaXRjaCA9IChvcHRpb25zICYmIG9wdGlvbnMucGl0Y2gpIHx8IDA7XG4gICAgICAgIGNvbnN0IGxuZ2xhdDAgPSBib3VuZHMuZ2V0Tm9ydGhXZXN0KCk7XG4gICAgICAgIGNvbnN0IGxuZ2xhdDEgPSBib3VuZHMuZ2V0U291dGhFYXN0KCk7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYW1lcmFGb3JCb3VuZHModGhpcy50cmFuc2Zvcm0sIGxuZ2xhdDAsIGxuZ2xhdDEsIGJlYXJpbmcsIHBpdGNoLCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICBfZXh0ZW5kQ2FtZXJhT3B0aW9ucyhvcHRpb25zPzogQ2FtZXJhT3B0aW9ucyk6IEZ1bGxDYW1lcmFPcHRpb25zIHtcbiAgICAgICAgY29uc3QgZGVmYXVsdFBhZGRpbmcgPSB7XG4gICAgICAgICAgICB0b3A6IDAsXG4gICAgICAgICAgICBib3R0b206IDAsXG4gICAgICAgICAgICByaWdodDogMCxcbiAgICAgICAgICAgIGxlZnQ6IDBcbiAgICAgICAgfTtcbiAgICAgICAgb3B0aW9ucyA9IGV4dGVuZCh7XG4gICAgICAgICAgICBwYWRkaW5nOiBkZWZhdWx0UGFkZGluZyxcbiAgICAgICAgICAgIG9mZnNldDogWzAsIDBdLFxuICAgICAgICAgICAgbWF4Wm9vbTogdGhpcy50cmFuc2Zvcm0ubWF4Wm9vbVxuICAgICAgICB9LCBvcHRpb25zKTtcblxuICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMucGFkZGluZyA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIGNvbnN0IHAgPSBvcHRpb25zLnBhZGRpbmc7XG4gICAgICAgICAgICBvcHRpb25zLnBhZGRpbmcgPSB7XG4gICAgICAgICAgICAgICAgdG9wOiBwLFxuICAgICAgICAgICAgICAgIGJvdHRvbTogcCxcbiAgICAgICAgICAgICAgICByaWdodDogcCxcbiAgICAgICAgICAgICAgICBsZWZ0OiBwXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFkZGluZyA9IGV4dGVuZChkZWZhdWx0UGFkZGluZywgb3B0aW9ucy5wYWRkaW5nKTtcbiAgICAgICAgcmV0dXJuIG9wdGlvbnM7XG4gICAgfVxuXG4gICAgX21pbmltdW1BQUJCRnJ1c3R1bURpc3RhbmNlKHRyOiBUcmFuc2Zvcm0sIGFhYmI6IEFhYmIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBhYWJiVyA9IGFhYmIubWF4WzBdIC0gYWFiYi5taW5bMF07XG4gICAgICAgIGNvbnN0IGFhYmJIID0gYWFiYi5tYXhbMV0gLSBhYWJiLm1pblsxXTtcbiAgICAgICAgY29uc3QgYWFiYkFzcGVjdFJhdGlvID0gYWFiYlcgLyBhYWJiSDtcbiAgICAgICAgY29uc3Qgc2VsZWN0WEF4aXMgPSBhYWJiQXNwZWN0UmF0aW8gPiB0ci5hc3BlY3Q7XG5cbiAgICAgICAgY29uc3QgbWluaW11bURpc3RhbmNlID0gc2VsZWN0WEF4aXMgP1xuICAgICAgICAgICAgYWFiYlcgLyAoMiAqIE1hdGgudGFuKHRyLmZvdlggKiAwLjUpICogdHIuYXNwZWN0KSA6XG4gICAgICAgICAgICBhYWJiSCAvICgyICogTWF0aC50YW4odHIuZm92WSAqIDAuNSkgKiB0ci5hc3BlY3QpO1xuXG4gICAgICAgIHJldHVybiBtaW5pbXVtRGlzdGFuY2U7XG4gICAgfVxuXG4gICAgX2NhbWVyYUZvckJvdW5kc09uR2xvYmUodHJhbnNmb3JtOiBUcmFuc2Zvcm0sIHAwOiBMbmdMYXRMaWtlLCBwMTogTG5nTGF0TGlrZSwgYmVhcmluZzogbnVtYmVyLCBwaXRjaDogbnVtYmVyLCBvcHRpb25zPzogQ2FtZXJhT3B0aW9ucyk6ID9FYXNpbmdPcHRpb25zIHtcbiAgICAgICAgY29uc3QgdHIgPSB0cmFuc2Zvcm0uY2xvbmUoKTtcbiAgICAgICAgY29uc3QgZU9wdGlvbnMgPSB0aGlzLl9leHRlbmRDYW1lcmFPcHRpb25zKG9wdGlvbnMpO1xuXG4gICAgICAgIHRyLmJlYXJpbmcgPSBiZWFyaW5nO1xuICAgICAgICB0ci5waXRjaCA9IHBpdGNoO1xuXG4gICAgICAgIGNvbnN0IGNvb3JkMCA9IExuZ0xhdC5jb252ZXJ0KHAwKTtcbiAgICAgICAgY29uc3QgY29vcmQxID0gTG5nTGF0LmNvbnZlcnQocDEpO1xuXG4gICAgICAgIGNvbnN0IG1pZExhdCA9IChjb29yZDAubGF0ICsgY29vcmQxLmxhdCkgKiAwLjU7XG4gICAgICAgIGNvbnN0IG1pZExuZyA9IChjb29yZDAubG5nICsgY29vcmQxLmxuZykgKiAwLjU7XG5cbiAgICAgICAgY29uc3Qgb3JpZ2luID0gbGF0TG5nVG9FQ0VGKG1pZExhdCwgbWlkTG5nKTtcblxuICAgICAgICBjb25zdCB6QXhpcyA9IHZlYzMubm9ybWFsaXplKFtdLCBvcmlnaW4pO1xuICAgICAgICBjb25zdCB4QXhpcyA9IHZlYzMubm9ybWFsaXplKFtdLCB2ZWMzLmNyb3NzKFtdLCB6QXhpcywgWzAsIDEsIDBdKSk7XG4gICAgICAgIGNvbnN0IHlBeGlzID0gdmVjMy5jcm9zcyhbXSwgeEF4aXMsIHpBeGlzKTtcblxuICAgICAgICBjb25zdCBhYWJiT3JpZW50YXRpb24gPSBbXG4gICAgICAgICAgICB4QXhpc1swXSwgeEF4aXNbMV0sIHhBeGlzWzJdLCAwLFxuICAgICAgICAgICAgeUF4aXNbMF0sIHlBeGlzWzFdLCB5QXhpc1syXSwgMCxcbiAgICAgICAgICAgIHpBeGlzWzBdLCB6QXhpc1sxXSwgekF4aXNbMl0sIDAsXG4gICAgICAgICAgICAwLCAwLCAwLCAxXG4gICAgICAgIF07XG5cbiAgICAgICAgY29uc3QgZWNlZkNvb3JkcyA9IFtcbiAgICAgICAgICAgIG9yaWdpbixcblxuICAgICAgICAgICAgbGF0TG5nVG9FQ0VGKGNvb3JkMC5sYXQsIGNvb3JkMC5sbmcpLFxuICAgICAgICAgICAgbGF0TG5nVG9FQ0VGKGNvb3JkMS5sYXQsIGNvb3JkMC5sbmcpLFxuICAgICAgICAgICAgbGF0TG5nVG9FQ0VGKGNvb3JkMS5sYXQsIGNvb3JkMS5sbmcpLFxuICAgICAgICAgICAgbGF0TG5nVG9FQ0VGKGNvb3JkMC5sYXQsIGNvb3JkMS5sbmcpLFxuXG4gICAgICAgICAgICBsYXRMbmdUb0VDRUYobWlkTGF0LCBjb29yZDAubG5nKSxcbiAgICAgICAgICAgIGxhdExuZ1RvRUNFRihtaWRMYXQsIGNvb3JkMS5sbmcpLFxuICAgICAgICAgICAgbGF0TG5nVG9FQ0VGKGNvb3JkMC5sYXQsIG1pZExuZyksXG4gICAgICAgICAgICBsYXRMbmdUb0VDRUYoY29vcmQxLmxhdCwgbWlkTG5nKSxcbiAgICAgICAgXTtcblxuICAgICAgICBsZXQgYWFiYiA9IEFhYmIuZnJvbVBvaW50cyhlY2VmQ29vcmRzLm1hcChwID0+IFt2ZWMzLmRvdCh4QXhpcywgcCksIHZlYzMuZG90KHlBeGlzLCBwKSwgdmVjMy5kb3QoekF4aXMsIHApXSkpO1xuXG4gICAgICAgIGNvbnN0IGNlbnRlciA9IHZlYzMudHJhbnNmb3JtTWF0NChbXSwgYWFiYi5jZW50ZXIsIGFhYmJPcmllbnRhdGlvbik7XG5cbiAgICAgICAgaWYgKHZlYzMuc3F1YXJlZExlbmd0aChjZW50ZXIpID09PSAwKSB7XG4gICAgICAgICAgICB2ZWMzLnNldChjZW50ZXIsIDAsIDAsIDEpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmVjMy5ub3JtYWxpemUoY2VudGVyLCBjZW50ZXIpO1xuICAgICAgICB2ZWMzLnNjYWxlKGNlbnRlciwgY2VudGVyLCBHTE9CRV9SQURJVVMpO1xuICAgICAgICB0ci5jZW50ZXIgPSBlY2VmVG9MYXRMbmcoY2VudGVyKTtcblxuICAgICAgICBjb25zdCB3b3JsZFRvQ2FtZXJhID0gdHIuZ2V0V29ybGRUb0NhbWVyYU1hdHJpeCgpO1xuICAgICAgICBjb25zdCBjYW1lcmFUb1dvcmxkID0gbWF0NC5pbnZlcnQobmV3IEZsb2F0NjRBcnJheSgxNiksIHdvcmxkVG9DYW1lcmEpO1xuXG4gICAgICAgIGFhYmIgPSBBYWJiLmFwcGx5VHJhbnNmb3JtKGFhYmIsIG1hdDQubXVsdGlwbHkoW10sIHdvcmxkVG9DYW1lcmEsIGFhYmJPcmllbnRhdGlvbikpO1xuXG4gICAgICAgIHZlYzMudHJhbnNmb3JtTWF0NChjZW50ZXIsIGNlbnRlciwgd29ybGRUb0NhbWVyYSk7XG5cbiAgICAgICAgY29uc3QgYWFiYkhhbGZFeHRlbnRaID0gKGFhYmIubWF4WzJdIC0gYWFiYi5taW5bMl0pICogMC41O1xuICAgICAgICBjb25zdCBmcnVzdHVtRGlzdGFuY2UgPSB0aGlzLl9taW5pbXVtQUFCQkZydXN0dW1EaXN0YW5jZSh0ciwgYWFiYik7XG5cbiAgICAgICAgY29uc3Qgb2Zmc2V0WiA9IHZlYzMuc2NhbGUoW10sIFswLCAwLCAxXSwgYWFiYkhhbGZFeHRlbnRaKTtcbiAgICAgICAgY29uc3QgYWFiYkNsb3Nlc3RQb2ludCA9IHZlYzMuYWRkKG9mZnNldFosIGNlbnRlciwgb2Zmc2V0Wik7XG4gICAgICAgIGNvbnN0IG9mZnNldERpc3RhbmNlID0gZnJ1c3R1bURpc3RhbmNlICsgKHRyLnBpdGNoID09PSAwID8gMCA6IHZlYzMuZGlzdGFuY2UoY2VudGVyLCBhYWJiQ2xvc2VzdFBvaW50KSk7XG5cbiAgICAgICAgY29uc3QgZ2xvYmVDZW50ZXIgPSB0ci5nbG9iZUNlbnRlckluVmlld1NwYWNlO1xuICAgICAgICBjb25zdCBub3JtYWwgPSB2ZWMzLnN1YihbXSwgY2VudGVyLCBbZ2xvYmVDZW50ZXJbMF0sIGdsb2JlQ2VudGVyWzFdLCBnbG9iZUNlbnRlclsyXV0pO1xuICAgICAgICB2ZWMzLm5vcm1hbGl6ZShub3JtYWwsIG5vcm1hbCk7XG4gICAgICAgIHZlYzMuc2NhbGUobm9ybWFsLCBub3JtYWwsIG9mZnNldERpc3RhbmNlKTtcblxuICAgICAgICBjb25zdCBjYW1lcmFQb3NpdGlvbiA9IHZlYzMuYWRkKFtdLCBjZW50ZXIsIG5vcm1hbCk7XG5cbiAgICAgICAgdmVjMy50cmFuc2Zvcm1NYXQ0KGNhbWVyYVBvc2l0aW9uLCBjYW1lcmFQb3NpdGlvbiwgY2FtZXJhVG9Xb3JsZCk7XG5cbiAgICAgICAgY29uc3QgbWV0ZXJQZXJFQ0VGID0gZWFydGhSYWRpdXMgLyBHTE9CRV9SQURJVVM7XG4gICAgICAgIGNvbnN0IGFsdGl0dWRlRUNFRiA9IHZlYzMubGVuZ3RoKGNhbWVyYVBvc2l0aW9uKTtcbiAgICAgICAgY29uc3QgYWx0aXR1ZGVNZXRlciA9IGFsdGl0dWRlRUNFRiAqIG1ldGVyUGVyRUNFRiAtIGVhcnRoUmFkaXVzO1xuICAgICAgICBjb25zdCBtZXJjYXRvclogPSBtZXJjYXRvclpmcm9tQWx0aXR1ZGUoTWF0aC5tYXgoYWx0aXR1ZGVNZXRlciwgTnVtYmVyLkVQU0lMT04pLCAwKTtcblxuICAgICAgICBjb25zdCB6b29tID0gTWF0aC5taW4odHIuem9vbUZyb21NZXJjYXRvclpBZGp1c3RlZChtZXJjYXRvclopLCBlT3B0aW9ucy5tYXhab29tKTtcblxuICAgICAgICBjb25zdCBoYWxmWm9vbVRyYW5zaXRpb24gPSAoR0xPQkVfWk9PTV9USFJFU0hPTERfTUlOICsgR0xPQkVfWk9PTV9USFJFU0hPTERfTUFYKSAqIDAuNTtcbiAgICAgICAgaWYgKHpvb20gPiBoYWxmWm9vbVRyYW5zaXRpb24pIHtcbiAgICAgICAgICAgIHRyLnNldFByb2plY3Rpb24oe25hbWU6ICdtZXJjYXRvcid9KTtcbiAgICAgICAgICAgIHRyLnpvb20gPSB6b29tO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NhbWVyYUZvckJvdW5kcyh0ciwgcDAsIHAxLCBiZWFyaW5nLCBwaXRjaCwgb3B0aW9ucyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge2NlbnRlcjogdHIuY2VudGVyLCB6b29tLCBiZWFyaW5nLCBwaXRjaH07XG4gICAgfVxuXG4gICAgLyoqIEBzZWN0aW9uIHtRdWVyeWluZyBmZWF0dXJlc30gKi9cblxuICAgIC8qKlxuICAgICAqIFF1ZXJpZXMgdGhlIGN1cnJlbnRseSBsb2FkZWQgZGF0YSBmb3IgZWxldmF0aW9uIGF0IGEgZ2VvZ3JhcGhpY2FsIGxvY2F0aW9uLiBUaGUgZWxldmF0aW9uIGlzIHJldHVybmVkIGluIGBtZXRlcnNgIHJlbGF0aXZlIHRvIG1lYW4gc2VhLWxldmVsLlxuICAgICAqIFJldHVybnMgYG51bGxgIGlmIGB0ZXJyYWluYCBpcyBkaXNhYmxlZCBvciBpZiB0ZXJyYWluIGRhdGEgZm9yIHRoZSBsb2NhdGlvbiBoYXNuJ3QgYmVlbiBsb2FkZWQgeWV0LlxuICAgICAqXG4gICAgICogSW4gb3JkZXIgdG8gZ3VhcmFudGVlIHRoYXQgdGhlIHRlcnJhaW4gZGF0YSBpcyBsb2FkZWQgZW5zdXJlIHRoYXQgdGhlIGdlb2dyYXBoaWNhbCBsb2NhdGlvbiBpcyB2aXNpYmxlIGFuZCB3YWl0IGZvciB0aGUgYGlkbGVgIGV2ZW50IHRvIG9jY3VyLlxuICAgICAqXG4gICAgICogQG1lbWJlcm9mIE1hcCNcbiAgICAgKiBAcGFyYW0ge0xuZ0xhdExpa2V9IGxuZ2xhdCBUaGUgZ2VvZ3JhcGhpY2FsIGxvY2F0aW9uIGF0IHdoaWNoIHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7RWxldmF0aW9uUXVlcnlPcHRpb25zfSBbb3B0aW9uc10gT3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5leGFnZ2VyYXRlZD10cnVlXSBXaGVuIGB0cnVlYCByZXR1cm5zIHRoZSB0ZXJyYWluIGVsZXZhdGlvbiB3aXRoIHRoZSB2YWx1ZSBvZiBgZXhhZ2dlcmF0aW9uYCBmcm9tIHRoZSBzdHlsZSBhbHJlYWR5IGFwcGxpZWQuXG4gICAgICogV2hlbiBgZmFsc2VgLCByZXR1cm5zIHRoZSByYXcgdmFsdWUgb2YgdGhlIHVuZGVybHlpbmcgZGF0YSB3aXRob3V0IHN0eWxpbmcgYXBwbGllZC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyIHwgbnVsbH0gVGhlIGVsZXZhdGlvbiBpbiBtZXRlcnMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBjb29yZGluYXRlID0gWy0xMjIuNDIwNjc5LCAzNy43NzI1MzddO1xuICAgICAqIGNvbnN0IGVsZXZhdGlvbiA9IG1hcC5xdWVyeVRlcnJhaW5FbGV2YXRpb24oY29vcmRpbmF0ZSk7XG4gICAgICogQHNlZSBbRXhhbXBsZTogUXVlcnkgdGVycmFpbiBlbGV2YXRpb25dKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL3F1ZXJ5LXRlcnJhaW4tZWxldmF0aW9uLylcbiAgICAgKi9cbiAgICBxdWVyeVRlcnJhaW5FbGV2YXRpb24obG5nbGF0OiBMbmdMYXRMaWtlLCBvcHRpb25zOiA/RWxldmF0aW9uUXVlcnlPcHRpb25zKTogP251bWJlciB7XG4gICAgICAgIGNvbnN0IGVsZXZhdGlvbiA9IHRoaXMudHJhbnNmb3JtLmVsZXZhdGlvbjtcbiAgICAgICAgaWYgKGVsZXZhdGlvbikge1xuICAgICAgICAgICAgb3B0aW9ucyA9IGV4dGVuZCh7fSwge2V4YWdnZXJhdGVkOiB0cnVlfSwgb3B0aW9ucyk7XG4gICAgICAgICAgICByZXR1cm4gZWxldmF0aW9uLmdldEF0UG9pbnQoTWVyY2F0b3JDb29yZGluYXRlLmZyb21MbmdMYXQobG5nbGF0KSwgbnVsbCwgb3B0aW9ucy5leGFnZ2VyYXRlZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlIHRoZSBjZW50ZXIgb2YgdGhlc2UgdHdvIHBvaW50cyBpbiB0aGUgdmlld3BvcnQgYW5kIHVzZVxuICAgICAqIHRoZSBoaWdoZXN0IHpvb20gbGV2ZWwgdXAgdG8gYW5kIGluY2x1ZGluZyBgTWFwI2dldE1heFpvb20oKWAgdGhhdCBmaXRzXG4gICAgICogdGhlIHBvaW50cyBpbiB0aGUgdmlld3BvcnQgYXQgdGhlIHNwZWNpZmllZCBiZWFyaW5nLlxuICAgICAqIEBtZW1iZXJvZiBNYXAjXG4gICAgICogQHBhcmFtIHtMbmdMYXRMaWtlfSBwMCBGaXJzdCBwb2ludFxuICAgICAqIEBwYXJhbSB7TG5nTGF0TGlrZX0gcDEgU2Vjb25kIHBvaW50XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJlYXJpbmcgRGVzaXJlZCBtYXAgYmVhcmluZyBhdCBlbmQgb2YgYW5pbWF0aW9uLCBpbiBkZWdyZWVzXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHBpdGNoIERlc2lyZWQgbWFwIHBpdGNoIGF0IGVuZCBvZiBhbmltYXRpb24sIGluIGRlZ3JlZXNcbiAgICAgKiBAcGFyYW0ge0NhbWVyYU9wdGlvbnMgfCBudWxsfSBvcHRpb25zXG4gICAgICogQHBhcmFtIHtudW1iZXIgfCBQYWRkaW5nT3B0aW9uc30gW29wdGlvbnMucGFkZGluZ10gVGhlIGFtb3VudCBvZiBwYWRkaW5nIGluIHBpeGVscyB0byBhZGQgdG8gdGhlIGdpdmVuIGJvdW5kcy5cbiAgICAgKiBAcGFyYW0ge1BvaW50TGlrZX0gW29wdGlvbnMub2Zmc2V0PVswLCAwXV0gVGhlIGNlbnRlciBvZiB0aGUgZ2l2ZW4gYm91bmRzIHJlbGF0aXZlIHRvIHRoZSBtYXAncyBjZW50ZXIsIG1lYXN1cmVkIGluIHBpeGVscy5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMubWF4Wm9vbV0gVGhlIG1heGltdW0gem9vbSBsZXZlbCB0byBhbGxvdyB3aGVuIHRoZSBjYW1lcmEgd291bGQgdHJhbnNpdGlvbiB0byB0aGUgc3BlY2lmaWVkIGJvdW5kcy5cbiAgICAgKiBAcmV0dXJucyB7Q2FtZXJhT3B0aW9ucyB8IHZvaWR9IElmIG1hcCBpcyBhYmxlIHRvIGZpdCB0byBwcm92aWRlZCBib3VuZHMsIHJldHVybnMgYENhbWVyYU9wdGlvbnNgIHdpdGhcbiAgICAgKiAgICAgIGBjZW50ZXJgLCBgem9vbWAsIGFuZCBgYmVhcmluZ2AuIElmIG1hcCBpcyB1bmFibGUgdG8gZml0LCBtZXRob2Qgd2lsbCB3YXJuIGFuZCByZXR1cm4gdW5kZWZpbmVkLlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiB2YXIgcDAgPSBbLTc5LCA0M107XG4gICAgICogdmFyIHAxID0gWy03MywgNDVdO1xuICAgICAqIHZhciBiZWFyaW5nID0gOTA7XG4gICAgICogdmFyIG5ld0NhbWVyYVRyYW5zZm9ybSA9IG1hcC5fY2FtZXJhRm9yQm91bmRzKHAwLCBwMSwgYmVhcmluZywgcGl0Y2gsIHtcbiAgICAgKiAgIHBhZGRpbmc6IHt0b3A6IDEwLCBib3R0b206MjUsIGxlZnQ6IDE1LCByaWdodDogNX1cbiAgICAgKiB9KTtcbiAgICAgKi9cbiAgICBfY2FtZXJhRm9yQm91bmRzKHRyYW5zZm9ybTogVHJhbnNmb3JtLCBwMDogTG5nTGF0TGlrZSwgcDE6IExuZ0xhdExpa2UsIGJlYXJpbmc6IG51bWJlciwgcGl0Y2g6IG51bWJlciwgb3B0aW9ucz86IENhbWVyYU9wdGlvbnMpOiA/RWFzaW5nT3B0aW9ucyB7XG4gICAgICAgIGlmICh0cmFuc2Zvcm0ucHJvamVjdGlvbi5uYW1lID09PSAnZ2xvYmUnKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY2FtZXJhRm9yQm91bmRzT25HbG9iZSh0cmFuc2Zvcm0sIHAwLCBwMSwgYmVhcmluZywgcGl0Y2gsIG9wdGlvbnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdHIgPSB0cmFuc2Zvcm0uY2xvbmUoKTtcbiAgICAgICAgY29uc3QgZU9wdGlvbnMgPSB0aGlzLl9leHRlbmRDYW1lcmFPcHRpb25zKG9wdGlvbnMpO1xuICAgICAgICBjb25zdCBlZGdlUGFkZGluZyA9IHRyLnBhZGRpbmc7XG5cbiAgICAgICAgdHIuYmVhcmluZyA9IGJlYXJpbmc7XG4gICAgICAgIHRyLnBpdGNoID0gcGl0Y2g7XG5cbiAgICAgICAgY29uc3QgY29vcmQwID0gTG5nTGF0LmNvbnZlcnQocDApO1xuICAgICAgICBjb25zdCBjb29yZDEgPSBMbmdMYXQuY29udmVydChwMSk7XG4gICAgICAgIGNvbnN0IGNvb3JkMiA9IG5ldyBMbmdMYXQoY29vcmQwLmxuZywgY29vcmQxLmxhdCk7XG4gICAgICAgIGNvbnN0IGNvb3JkMyA9IG5ldyBMbmdMYXQoY29vcmQxLmxuZywgY29vcmQwLmxhdCk7XG5cbiAgICAgICAgY29uc3QgcDB3b3JsZCA9IHRyLnByb2plY3QoY29vcmQwKTtcbiAgICAgICAgY29uc3QgcDF3b3JsZCA9IHRyLnByb2plY3QoY29vcmQxKTtcblxuICAgICAgICBjb25zdCB6MCA9IHRoaXMucXVlcnlUZXJyYWluRWxldmF0aW9uKGNvb3JkMCk7XG4gICAgICAgIGNvbnN0IHoxID0gdGhpcy5xdWVyeVRlcnJhaW5FbGV2YXRpb24oY29vcmQxKTtcbiAgICAgICAgY29uc3QgejIgPSB0aGlzLnF1ZXJ5VGVycmFpbkVsZXZhdGlvbihjb29yZDIpO1xuICAgICAgICBjb25zdCB6MyA9IHRoaXMucXVlcnlUZXJyYWluRWxldmF0aW9uKGNvb3JkMyk7XG5cbiAgICAgICAgY29uc3Qgd29ybGRDb29yZHMgPSBbXG4gICAgICAgICAgICBbcDB3b3JsZC54LCBwMHdvcmxkLnksIE1hdGgubWluKHowIHx8IDAsIHoxIHx8IDAsIHoyIHx8IDAsIHozIHx8IDApXSxcbiAgICAgICAgICAgIFtwMXdvcmxkLngsIHAxd29ybGQueSwgTWF0aC5tYXgoejAgfHwgMCwgejEgfHwgMCwgejIgfHwgMCwgejMgfHwgMCldXG4gICAgICAgIF07XG5cbiAgICAgICAgbGV0IGFhYmIgPSBBYWJiLmZyb21Qb2ludHMod29ybGRDb29yZHMpO1xuXG4gICAgICAgIGNvbnN0IHdvcmxkVG9DYW1lcmEgPSB0ci5nZXRXb3JsZFRvQ2FtZXJhTWF0cml4KCk7XG4gICAgICAgIGNvbnN0IGNhbWVyYVRvV29ybGQgPSBtYXQ0LmludmVydChuZXcgRmxvYXQ2NEFycmF5KDE2KSwgd29ybGRUb0NhbWVyYSk7XG5cbiAgICAgICAgYWFiYiA9IEFhYmIuYXBwbHlUcmFuc2Zvcm0oYWFiYiwgd29ybGRUb0NhbWVyYSk7XG5cbiAgICAgICAgY29uc3Qgc2l6ZSA9IHZlYzMuc3ViKFtdLCBhYWJiLm1heCwgYWFiYi5taW4pO1xuXG4gICAgICAgIGNvbnN0IHNjcmVlblBhZEwgPSBlZGdlUGFkZGluZy5sZWZ0IHx8IDA7XG4gICAgICAgIGNvbnN0IHNjcmVlblBhZFIgPSBlZGdlUGFkZGluZy5yaWdodCB8fCAwO1xuICAgICAgICBjb25zdCBzY3JlZW5QYWRCID0gZWRnZVBhZGRpbmcuYm90dG9tIHx8IDA7XG4gICAgICAgIGNvbnN0IHNjcmVlblBhZFQgPSBlZGdlUGFkZGluZy50b3AgfHwgMDtcblxuICAgICAgICBjb25zdCB7bGVmdDogcGFkTCwgcmlnaHQ6IHBhZFIsIHRvcDogcGFkVCwgYm90dG9tOiBwYWRCfSA9IGVPcHRpb25zLnBhZGRpbmc7XG5cbiAgICAgICAgY29uc3QgaGFsZlNjcmVlblBhZFggPSAoc2NyZWVuUGFkTCArIHNjcmVlblBhZFIpICogMC41O1xuICAgICAgICBjb25zdCBoYWxmU2NyZWVuUGFkWSA9IChzY3JlZW5QYWRUICsgc2NyZWVuUGFkQikgKiAwLjU7XG5cbiAgICAgICAgY29uc3Qgc2NhbGVYID0gKHRyLndpZHRoIC0gKHNjcmVlblBhZEwgKyBzY3JlZW5QYWRSICsgcGFkTCArIHBhZFIpKSAvIHNpemVbMF07XG4gICAgICAgIGNvbnN0IHNjYWxlWSA9ICh0ci5oZWlnaHQgLSAoc2NyZWVuUGFkQiArIHNjcmVlblBhZFQgKyBwYWRCICsgcGFkVCkpIC8gc2l6ZVsxXTtcblxuICAgICAgICBjb25zdCB6b29tUmVmID0gTWF0aC5taW4odHIuc2NhbGVab29tKHRyLnNjYWxlICogTWF0aC5taW4oc2NhbGVYLCBzY2FsZVkpKSwgZU9wdGlvbnMubWF4Wm9vbSk7XG5cbiAgICAgICAgY29uc3Qgc2NhbGVSYXRpbyA9IHRyLnNjYWxlIC8gdHIuem9vbVNjYWxlKHpvb21SZWYpO1xuXG4gICAgICAgIGFhYmIgPSBuZXcgQWFiYihcbiAgICAgICAgICAgIFthYWJiLm1pblswXSAtIChwYWRMICsgaGFsZlNjcmVlblBhZFgpICogc2NhbGVSYXRpbywgYWFiYi5taW5bMV0gLSAocGFkQiArIGhhbGZTY3JlZW5QYWRZKSAqIHNjYWxlUmF0aW8sIGFhYmIubWluWzJdXSxcbiAgICAgICAgICAgIFthYWJiLm1heFswXSArIChwYWRSICsgaGFsZlNjcmVlblBhZFgpICogc2NhbGVSYXRpbywgYWFiYi5tYXhbMV0gKyAocGFkVCArIGhhbGZTY3JlZW5QYWRZKSAqIHNjYWxlUmF0aW8sIGFhYmIubWF4WzJdXSk7XG5cbiAgICAgICAgY29uc3QgYWFiYkhhbGZFeHRlbnRaID0gc2l6ZVsyXSAqIDAuNTtcbiAgICAgICAgY29uc3QgZnJ1c3R1bURpc3RhbmNlID0gdGhpcy5fbWluaW11bUFBQkJGcnVzdHVtRGlzdGFuY2UodHIsIGFhYmIpO1xuXG4gICAgICAgIGNvbnN0IG5vcm1hbFogPSBbMCwgMCwgMSwgMF07XG5cbiAgICAgICAgdmVjNC50cmFuc2Zvcm1NYXQ0KG5vcm1hbFosIG5vcm1hbFosIHdvcmxkVG9DYW1lcmEpO1xuICAgICAgICB2ZWM0Lm5vcm1hbGl6ZShub3JtYWxaLCBub3JtYWxaKTtcblxuICAgICAgICBjb25zdCBvZmZzZXQgPSB2ZWMzLnNjYWxlKFtdLCBub3JtYWxaLCBmcnVzdHVtRGlzdGFuY2UgKyBhYWJiSGFsZkV4dGVudFopO1xuICAgICAgICBjb25zdCBjYW1lcmFQb3NpdGlvbiA9IHZlYzMuYWRkKFtdLCBhYWJiLmNlbnRlciwgb2Zmc2V0KTtcblxuICAgICAgICBjb25zdCBjZW50ZXJPZmZzZXQgPSAodHlwZW9mIGVPcHRpb25zLm9mZnNldC54ID09PSAnbnVtYmVyJyAmJiB0eXBlb2YgZU9wdGlvbnMub2Zmc2V0LnkgPT09ICdudW1iZXInKSA/XG4gICAgICAgICAgICBuZXcgUG9pbnQoZU9wdGlvbnMub2Zmc2V0LngsIGVPcHRpb25zLm9mZnNldC55KSA6XG4gICAgICAgICAgICBQb2ludC5jb252ZXJ0KGVPcHRpb25zLm9mZnNldCk7XG5cbiAgICAgICAgY29uc3Qgcm90YXRlZE9mZnNldCA9IGNlbnRlck9mZnNldC5yb3RhdGUoLWRlZ1RvUmFkKGJlYXJpbmcpKTtcblxuICAgICAgICBhYWJiLmNlbnRlclswXSAtPSByb3RhdGVkT2Zmc2V0LnggKiBzY2FsZVJhdGlvO1xuICAgICAgICBhYWJiLmNlbnRlclsxXSArPSByb3RhdGVkT2Zmc2V0LnkgKiBzY2FsZVJhdGlvO1xuXG4gICAgICAgIHZlYzMudHJhbnNmb3JtTWF0NChhYWJiLmNlbnRlciwgYWFiYi5jZW50ZXIsIGNhbWVyYVRvV29ybGQpO1xuICAgICAgICB2ZWMzLnRyYW5zZm9ybU1hdDQoY2FtZXJhUG9zaXRpb24sIGNhbWVyYVBvc2l0aW9uLCBjYW1lcmFUb1dvcmxkKTtcblxuICAgICAgICBjb25zdCBtZXJjYXRvciA9IFthYWJiLmNlbnRlclswXSwgYWFiYi5jZW50ZXJbMV0sIGNhbWVyYVBvc2l0aW9uWzJdICogdHIucGl4ZWxzUGVyTWV0ZXJdO1xuICAgICAgICB2ZWMzLnNjYWxlKG1lcmNhdG9yLCBtZXJjYXRvciwgMS4wIC8gdHIud29ybGRTaXplKTtcblxuICAgICAgICBjb25zdCBsbmcgPSBsbmdGcm9tTWVyY2F0b3JYKG1lcmNhdG9yWzBdKTtcbiAgICAgICAgY29uc3QgbGF0ID0gbGF0RnJvbU1lcmNhdG9yWShtZXJjYXRvclsxXSk7XG5cbiAgICAgICAgY29uc3Qgem9vbSA9IE1hdGgubWluKHRyLl96b29tRnJvbU1lcmNhdG9yWihtZXJjYXRvclsyXSksIGVPcHRpb25zLm1heFpvb20pO1xuICAgICAgICBjb25zdCBjZW50ZXIgPSBuZXcgTG5nTGF0KGxuZywgbGF0KTtcblxuICAgICAgICBjb25zdCBoYWxmWm9vbVRyYW5zaXRpb24gPSAoR0xPQkVfWk9PTV9USFJFU0hPTERfTUlOICsgR0xPQkVfWk9PTV9USFJFU0hPTERfTUFYKSAqIDAuNTtcblxuICAgICAgICBpZiAodHIubWVyY2F0b3JGcm9tVHJhbnNpdGlvbiAmJiB6b29tIDwgaGFsZlpvb21UcmFuc2l0aW9uKSB7XG4gICAgICAgICAgICB0ci5zZXRQcm9qZWN0aW9uKHtuYW1lOiAnZ2xvYmUnfSk7XG4gICAgICAgICAgICB0ci56b29tID0gem9vbTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jYW1lcmFGb3JCb3VuZHModHIsIHAwLCBwMSwgYmVhcmluZywgcGl0Y2gsIG9wdGlvbnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtjZW50ZXIsIHpvb20sIGJlYXJpbmcsIHBpdGNofTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYW5zIGFuZCB6b29tcyB0aGUgbWFwIHRvIGNvbnRhaW4gaXRzIHZpc2libGUgYXJlYSB3aXRoaW4gdGhlIHNwZWNpZmllZCBnZW9ncmFwaGljYWwgYm91bmRzLlxuICAgICAqIElmIGEgcGFkZGluZyBpcyBzZXQgb24gdGhlIG1hcCwgdGhlIGJvdW5kcyBhcmUgZml0IHRvIHRoZSBpbnNldC5cbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiBNYXAjXG4gICAgICogQHBhcmFtIHtMbmdMYXRCb3VuZHNMaWtlfSBib3VuZHMgQ2VudGVyIHRoZXNlIGJvdW5kcyBpbiB0aGUgdmlld3BvcnQgYW5kIHVzZSB0aGUgaGlnaGVzdFxuICAgICAqICAgICAgem9vbSBsZXZlbCB1cCB0byBhbmQgaW5jbHVkaW5nIGBNYXAjZ2V0TWF4Wm9vbSgpYCB0aGF0IGZpdHMgdGhlbSBpbiB0aGUgdmlld3BvcnQuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSBPcHRpb25zIHN1cHBvcnRzIGFsbCBwcm9wZXJ0aWVzIGZyb20ge0BsaW5rIEFuaW1hdGlvbk9wdGlvbnN9IGFuZCB7QGxpbmsgQ2FtZXJhT3B0aW9uc30gaW4gYWRkaXRpb24gdG8gdGhlIGZpZWxkcyBiZWxvdy5cbiAgICAgKiBAcGFyYW0ge251bWJlciB8IFBhZGRpbmdPcHRpb25zfSBbb3B0aW9ucy5wYWRkaW5nXSBUaGUgYW1vdW50IG9mIHBhZGRpbmcgaW4gcGl4ZWxzIHRvIGFkZCB0byB0aGUgZ2l2ZW4gYm91bmRzLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5waXRjaD0wXSBEZXNpcmVkIG1hcCBwaXRjaCBhdCBlbmQgb2YgYW5pbWF0aW9uLCBpbiBkZWdyZWVzLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5iZWFyaW5nPTBdIERlc2lyZWQgbWFwIGJlYXJpbmcgYXQgZW5kIG9mIGFuaW1hdGlvbiwgaW4gZGVncmVlcy5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmxpbmVhcj1mYWxzZV0gSWYgYHRydWVgLCB0aGUgbWFwIHRyYW5zaXRpb25zIHVzaW5nXG4gICAgICogICAgIHtAbGluayBNYXAjZWFzZVRvfS4gSWYgYGZhbHNlYCwgdGhlIG1hcCB0cmFuc2l0aW9ucyB1c2luZyB7QGxpbmsgTWFwI2ZseVRvfS4gU2VlXG4gICAgICogICAgIHRob3NlIGZ1bmN0aW9ucyBhbmQge0BsaW5rIEFuaW1hdGlvbk9wdGlvbnN9IGZvciBpbmZvcm1hdGlvbiBhYm91dCBvcHRpb25zIGF2YWlsYWJsZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0aW9ucy5lYXNpbmddIEFuIGVhc2luZyBmdW5jdGlvbiBmb3IgdGhlIGFuaW1hdGVkIHRyYW5zaXRpb24uIFNlZSB7QGxpbmsgQW5pbWF0aW9uT3B0aW9uc30uXG4gICAgICogQHBhcmFtIHtQb2ludExpa2V9IFtvcHRpb25zLm9mZnNldD1bMCwgMF1dIFRoZSBjZW50ZXIgb2YgdGhlIGdpdmVuIGJvdW5kcyByZWxhdGl2ZSB0byB0aGUgbWFwJ3MgY2VudGVyLCBtZWFzdXJlZCBpbiBwaXhlbHMuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLm1heFpvb21dIFRoZSBtYXhpbXVtIHpvb20gbGV2ZWwgdG8gYWxsb3cgd2hlbiB0aGUgbWFwIHZpZXcgdHJhbnNpdGlvbnMgdG8gdGhlIHNwZWNpZmllZCBib3VuZHMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtldmVudERhdGFdIEFkZGl0aW9uYWwgcHJvcGVydGllcyB0byBiZSBhZGRlZCB0byBldmVudCBvYmplY3RzIG9mIGV2ZW50cyB0cmlnZ2VyZWQgYnkgdGhpcyBtZXRob2QuXG4gICAgICogQGZpcmVzIE1hcC5ldmVudDptb3Zlc3RhcnRcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Om1vdmVlbmRcbiAgICAgKiBAcmV0dXJucyB7TWFwfSBSZXR1cm5zIGl0c2VsZiB0byBhbGxvdyBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgYmJveCA9IFtbLTc5LCA0M10sIFstNzMsIDQ1XV07XG4gICAgICogbWFwLmZpdEJvdW5kcyhiYm94LCB7XG4gICAgICogICAgIHBhZGRpbmc6IHt0b3A6IDEwLCBib3R0b206MjUsIGxlZnQ6IDE1LCByaWdodDogNX1cbiAgICAgKiB9KTtcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBGaXQgYSBtYXAgdG8gYSBib3VuZGluZyBib3hdKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvZml0Ym91bmRzLylcbiAgICAgKi9cbiAgICBmaXRCb3VuZHMoYm91bmRzOiBMbmdMYXRCb3VuZHNMaWtlLCBvcHRpb25zPzogRWFzaW5nT3B0aW9ucywgZXZlbnREYXRhPzogT2JqZWN0KTogdGhpcyB7XG4gICAgICAgIGNvbnN0IGNhbWVyYVBsYWNlbWVudCA9IHRoaXMuY2FtZXJhRm9yQm91bmRzKGJvdW5kcywgb3B0aW9ucyk7XG4gICAgICAgIHJldHVybiB0aGlzLl9maXRJbnRlcm5hbChjYW1lcmFQbGFjZW1lbnQsIG9wdGlvbnMsIGV2ZW50RGF0YSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFucywgcm90YXRlcyBhbmQgem9vbXMgdGhlIG1hcCB0byB0byBmaXQgdGhlIGJveCBtYWRlIGJ5IHBvaW50cyBwMCBhbmQgcDFcbiAgICAgKiBvbmNlIHRoZSBtYXAgaXMgcm90YXRlZCB0byB0aGUgc3BlY2lmaWVkIGJlYXJpbmcuIFRvIHpvb20gd2l0aG91dCByb3RhdGluZyxcbiAgICAgKiBwYXNzIGluIHRoZSBjdXJyZW50IG1hcCBiZWFyaW5nLlxuICAgICAqXG4gICAgICogQG1lbWJlcm9mIE1hcCNcbiAgICAgKiBAcGFyYW0ge1BvaW50TGlrZX0gcDAgRmlyc3QgcG9pbnQgb24gc2NyZWVuLCBpbiBwaXhlbCBjb29yZGluYXRlcy5cbiAgICAgKiBAcGFyYW0ge1BvaW50TGlrZX0gcDEgU2Vjb25kIHBvaW50IG9uIHNjcmVlbiwgaW4gcGl4ZWwgY29vcmRpbmF0ZXMuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJlYXJpbmcgRGVzaXJlZCBtYXAgYmVhcmluZyBhdCBlbmQgb2YgYW5pbWF0aW9uLCBpbiBkZWdyZWVzLlxuICAgICAqIEBwYXJhbSB7RWFzaW5nT3B0aW9ucyB8IG51bGx9IG9wdGlvbnMgT3B0aW9ucyBvYmplY3QuXG4gICAgICogICAgIEFjY2VwdHMge0BsaW5rIENhbWVyYU9wdGlvbnN9IGFuZCB7QGxpbmsgQW5pbWF0aW9uT3B0aW9uc30uXG4gICAgICogQHBhcmFtIHtudW1iZXIgfCBQYWRkaW5nT3B0aW9uc30gW29wdGlvbnMucGFkZGluZ10gVGhlIGFtb3VudCBvZiBwYWRkaW5nIGluIHBpeGVscyB0byBhZGQgdG8gdGhlIGdpdmVuIGJvdW5kcy5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmxpbmVhcj1mYWxzZV0gSWYgYHRydWVgLCB0aGUgbWFwIHRyYW5zaXRpb25zIHVzaW5nXG4gICAgICogICAgIHtAbGluayBNYXAjZWFzZVRvfS4gSWYgYGZhbHNlYCwgdGhlIG1hcCB0cmFuc2l0aW9ucyB1c2luZyB7QGxpbmsgTWFwI2ZseVRvfS4gU2VlXG4gICAgICogICAgIHRob3NlIGZ1bmN0aW9ucyBhbmQge0BsaW5rIEFuaW1hdGlvbk9wdGlvbnN9IGZvciBpbmZvcm1hdGlvbiBhYm91dCBvcHRpb25zIGF2YWlsYWJsZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMucGl0Y2g9MF0gRGVzaXJlZCBtYXAgcGl0Y2ggYXQgZW5kIG9mIGFuaW1hdGlvbiwgaW4gZGVncmVlcy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0aW9ucy5lYXNpbmddIEFuIGVhc2luZyBmdW5jdGlvbiBmb3IgdGhlIGFuaW1hdGVkIHRyYW5zaXRpb24uIFNlZSB7QGxpbmsgQW5pbWF0aW9uT3B0aW9uc30uXG4gICAgICogQHBhcmFtIHtQb2ludExpa2V9IFtvcHRpb25zLm9mZnNldD1bMCwgMF1dIFRoZSBjZW50ZXIgb2YgdGhlIGdpdmVuIGJvdW5kcyByZWxhdGl2ZSB0byB0aGUgbWFwJ3MgY2VudGVyLCBtZWFzdXJlZCBpbiBwaXhlbHMuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLm1heFpvb21dIFRoZSBtYXhpbXVtIHpvb20gbGV2ZWwgdG8gYWxsb3cgd2hlbiB0aGUgbWFwIHZpZXcgdHJhbnNpdGlvbnMgdG8gdGhlIHNwZWNpZmllZCBib3VuZHMuXG4gICAgICogQHBhcmFtIHtPYmplY3QgfCBudWxsfSBldmVudERhdGEgQWRkaXRpb25hbCBwcm9wZXJ0aWVzIHRvIGJlIGFkZGVkIHRvIGV2ZW50IG9iamVjdHMgb2YgZXZlbnRzIHRyaWdnZXJlZCBieSB0aGlzIG1ldGhvZC5cbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Om1vdmVzdGFydFxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6bW92ZWVuZFxuICAgICAqIEByZXR1cm5zIHtNYXB9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwMCA9IFsyMjAsIDQwMF07XG4gICAgICogY29uc3QgcDEgPSBbNTAwLCA5MDBdO1xuICAgICAqIG1hcC5maXRTY3JlZW5Db29yZGluYXRlcyhwMCwgcDEsIG1hcC5nZXRCZWFyaW5nKCksIHtcbiAgICAgKiAgICAgcGFkZGluZzoge3RvcDogMTAsIGJvdHRvbToyNSwgbGVmdDogMTUsIHJpZ2h0OiA1fVxuICAgICAqIH0pO1xuICAgICAqIEBzZWUgVXNlZCBieSB7QGxpbmsgQm94Wm9vbUhhbmRsZXJ9XG4gICAgICovXG4gICAgZml0U2NyZWVuQ29vcmRpbmF0ZXMocDA6IFBvaW50TGlrZSwgcDE6IFBvaW50TGlrZSwgYmVhcmluZzogbnVtYmVyLCBvcHRpb25zPzogRWFzaW5nT3B0aW9ucywgZXZlbnREYXRhPzogT2JqZWN0KTogdGhpcyB7XG4gICAgICAgIGNvbnN0IHNjcmVlbjAgPSBQb2ludC5jb252ZXJ0KHAwKTtcbiAgICAgICAgY29uc3Qgc2NyZWVuMSA9IFBvaW50LmNvbnZlcnQocDEpO1xuXG4gICAgICAgIGNvbnN0IG1pbiA9IG5ldyBQb2ludChNYXRoLm1pbihzY3JlZW4wLngsIHNjcmVlbjEueCksIE1hdGgubWluKHNjcmVlbjAueSwgc2NyZWVuMS55KSk7XG4gICAgICAgIGNvbnN0IG1heCA9IG5ldyBQb2ludChNYXRoLm1heChzY3JlZW4wLngsIHNjcmVlbjEueCksIE1hdGgubWF4KHNjcmVlbjAueSwgc2NyZWVuMS55KSk7XG5cbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtLnByb2plY3Rpb24ubmFtZSA9PT0gJ21lcmNhdG9yJyAmJiB0aGlzLnRyYW5zZm9ybS5hbnlDb3JuZXJPZmZFZGdlKHNjcmVlbjAsIHNjcmVlbjEpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxuZ2xhdDAgPSB0aGlzLnRyYW5zZm9ybS5wb2ludExvY2F0aW9uM0QobWluKTtcbiAgICAgICAgY29uc3QgbG5nbGF0MSA9IHRoaXMudHJhbnNmb3JtLnBvaW50TG9jYXRpb24zRChtYXgpO1xuICAgICAgICBjb25zdCBsbmdsYXQyID0gdGhpcy50cmFuc2Zvcm0ucG9pbnRMb2NhdGlvbjNEKG5ldyBQb2ludChtaW4ueCwgbWF4LnkpKTtcbiAgICAgICAgY29uc3QgbG5nbGF0MyA9IHRoaXMudHJhbnNmb3JtLnBvaW50TG9jYXRpb24zRChuZXcgUG9pbnQobWF4LngsIG1pbi55KSk7XG5cbiAgICAgICAgY29uc3QgcDBjb29yZCA9IFtcbiAgICAgICAgICAgIE1hdGgubWluKGxuZ2xhdDAubG5nLCBsbmdsYXQxLmxuZywgbG5nbGF0Mi5sbmcsIGxuZ2xhdDMubG5nKSxcbiAgICAgICAgICAgIE1hdGgubWluKGxuZ2xhdDAubGF0LCBsbmdsYXQxLmxhdCwgbG5nbGF0Mi5sYXQsIGxuZ2xhdDMubGF0KSxcbiAgICAgICAgXTtcbiAgICAgICAgY29uc3QgcDFjb29yZCA9ICBbXG4gICAgICAgICAgICBNYXRoLm1heChsbmdsYXQwLmxuZywgbG5nbGF0MS5sbmcsIGxuZ2xhdDIubG5nLCBsbmdsYXQzLmxuZyksXG4gICAgICAgICAgICBNYXRoLm1heChsbmdsYXQwLmxhdCwgbG5nbGF0MS5sYXQsIGxuZ2xhdDIubGF0LCBsbmdsYXQzLmxhdCksXG4gICAgICAgIF07XG5cbiAgICAgICAgY29uc3QgcGl0Y2ggPSBvcHRpb25zICYmIG9wdGlvbnMucGl0Y2ggPyBvcHRpb25zLnBpdGNoIDogdGhpcy5nZXRQaXRjaCgpO1xuXG4gICAgICAgIGNvbnN0IGNhbWVyYVBsYWNlbWVudCA9IHRoaXMuX2NhbWVyYUZvckJvdW5kcyh0aGlzLnRyYW5zZm9ybSwgcDBjb29yZCwgcDFjb29yZCwgYmVhcmluZywgcGl0Y2gsIG9wdGlvbnMpO1xuICAgICAgICByZXR1cm4gdGhpcy5fZml0SW50ZXJuYWwoY2FtZXJhUGxhY2VtZW50LCBvcHRpb25zLCBldmVudERhdGEpO1xuICAgIH1cblxuICAgIF9maXRJbnRlcm5hbChjYWxjdWxhdGVkT3B0aW9ucz86ID9FYXNpbmdPcHRpb25zLCBvcHRpb25zPzogRWFzaW5nT3B0aW9ucywgZXZlbnREYXRhPzogT2JqZWN0KTogdGhpcyB7XG4gICAgICAgIC8vIGNhbWVyYUZvckJvdW5kcyB3YXJucyArIHJldHVybnMgdW5kZWZpbmVkIGlmIHVuYWJsZSB0byBmaXQ6XG4gICAgICAgIGlmICghY2FsY3VsYXRlZE9wdGlvbnMpIHJldHVybiB0aGlzO1xuXG4gICAgICAgIG9wdGlvbnMgPSBleHRlbmQoY2FsY3VsYXRlZE9wdGlvbnMsIG9wdGlvbnMpO1xuICAgICAgICAvLyBFeHBsaWNpdGx5IHJlbW92ZSB0aGUgcGFkZGluZyBmaWVsZCBiZWNhdXNlLCBjYWxjdWxhdGVkT3B0aW9ucyBhbHJlYWR5IGFjY291bnRzIGZvciBwYWRkaW5nIGJ5IHNldHRpbmcgem9vbSBhbmQgY2VudGVyIGFjY29yZGluZ2x5LlxuICAgICAgICBkZWxldGUgb3B0aW9ucy5wYWRkaW5nO1xuXG4gICAgICAgIHJldHVybiBvcHRpb25zLmxpbmVhciA/XG4gICAgICAgICAgICB0aGlzLmVhc2VUbyhvcHRpb25zLCBldmVudERhdGEpIDpcbiAgICAgICAgICAgIHRoaXMuZmx5VG8ob3B0aW9ucywgZXZlbnREYXRhKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGFuZ2VzIGFueSBjb21iaW5hdGlvbiBvZiBjZW50ZXIsIHpvb20sIGJlYXJpbmcsIGFuZCBwaXRjaCwgd2l0aG91dFxuICAgICAqIGFuIGFuaW1hdGVkIHRyYW5zaXRpb24uIFRoZSBtYXAgd2lsbCByZXRhaW4gaXRzIGN1cnJlbnQgdmFsdWVzIGZvciBhbnlcbiAgICAgKiBkZXRhaWxzIG5vdCBzcGVjaWZpZWQgaW4gYG9wdGlvbnNgLlxuICAgICAqXG4gICAgICogQG1lbWJlcm9mIE1hcCNcbiAgICAgKiBAcGFyYW0ge0NhbWVyYU9wdGlvbnN9IG9wdGlvbnMgT3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtIHtPYmplY3QgfCBudWxsfSBldmVudERhdGEgQWRkaXRpb25hbCBwcm9wZXJ0aWVzIHRvIGJlIGFkZGVkIHRvIGV2ZW50IG9iamVjdHMgb2YgZXZlbnRzIHRyaWdnZXJlZCBieSB0aGlzIG1ldGhvZC5cbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Om1vdmVzdGFydFxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6em9vbXN0YXJ0XG4gICAgICogQGZpcmVzIE1hcC5ldmVudDpwaXRjaHN0YXJ0XG4gICAgICogQGZpcmVzIE1hcC5ldmVudDpyb3RhdGVcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Om1vdmVcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Onpvb21cbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50OnBpdGNoXG4gICAgICogQGZpcmVzIE1hcC5ldmVudDptb3ZlZW5kXG4gICAgICogQGZpcmVzIE1hcC5ldmVudDp6b29tZW5kXG4gICAgICogQGZpcmVzIE1hcC5ldmVudDpwaXRjaGVuZFxuICAgICAqIEByZXR1cm5zIHtNYXB9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBqdW1wIHRvIGNvb3JkaW5hdGVzIGF0IGN1cnJlbnQgem9vbVxuICAgICAqIG1hcC5qdW1wVG8oe2NlbnRlcjogWzAsIDBdfSk7XG4gICAgICogLy8ganVtcCB3aXRoIHpvb20sIHBpdGNoLCBhbmQgYmVhcmluZyBvcHRpb25zXG4gICAgICogbWFwLmp1bXBUbyh7XG4gICAgICogICAgIGNlbnRlcjogWzAsIDBdLFxuICAgICAqICAgICB6b29tOiA4LFxuICAgICAqICAgICBwaXRjaDogNDUsXG4gICAgICogICAgIGJlYXJpbmc6IDkwXG4gICAgICogfSk7XG4gICAgICogQHNlZSBbRXhhbXBsZTogSnVtcCB0byBhIHNlcmllcyBvZiBsb2NhdGlvbnNdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2p1bXAtdG8vKVxuICAgICAqIEBzZWUgW0V4YW1wbGU6IFVwZGF0ZSBhIGZlYXR1cmUgaW4gcmVhbHRpbWVdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2xpdmUtdXBkYXRlLWZlYXR1cmUvKVxuICAgICAqL1xuICAgIGp1bXBUbyhvcHRpb25zOiBDYW1lcmFPcHRpb25zICYge3ByZWxvYWRPbmx5PzogJFByb3BlcnR5VHlwZTxBbmltYXRpb25PcHRpb25zLCAncHJlbG9hZE9ubHknPn0sIGV2ZW50RGF0YT86IE9iamVjdCk6IHRoaXMge1xuICAgICAgICB0aGlzLnN0b3AoKTtcblxuICAgICAgICBjb25zdCB0ciA9IG9wdGlvbnMucHJlbG9hZE9ubHkgPyB0aGlzLnRyYW5zZm9ybS5jbG9uZSgpIDogdGhpcy50cmFuc2Zvcm07XG4gICAgICAgIGxldCB6b29tQ2hhbmdlZCA9IGZhbHNlLFxuICAgICAgICAgICAgYmVhcmluZ0NoYW5nZWQgPSBmYWxzZSxcbiAgICAgICAgICAgIHBpdGNoQ2hhbmdlZCA9IGZhbHNlO1xuXG4gICAgICAgIGlmICgnem9vbScgaW4gb3B0aW9ucyAmJiB0ci56b29tICE9PSArb3B0aW9ucy56b29tKSB7XG4gICAgICAgICAgICB6b29tQ2hhbmdlZCA9IHRydWU7XG4gICAgICAgICAgICB0ci56b29tID0gK29wdGlvbnMuem9vbTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChvcHRpb25zLmNlbnRlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0ci5jZW50ZXIgPSBMbmdMYXQuY29udmVydChvcHRpb25zLmNlbnRlcik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoJ2JlYXJpbmcnIGluIG9wdGlvbnMgJiYgdHIuYmVhcmluZyAhPT0gK29wdGlvbnMuYmVhcmluZykge1xuICAgICAgICAgICAgYmVhcmluZ0NoYW5nZWQgPSB0cnVlO1xuICAgICAgICAgICAgdHIuYmVhcmluZyA9ICtvcHRpb25zLmJlYXJpbmc7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoJ3BpdGNoJyBpbiBvcHRpb25zICYmIHRyLnBpdGNoICE9PSArb3B0aW9ucy5waXRjaCkge1xuICAgICAgICAgICAgcGl0Y2hDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRyLnBpdGNoID0gK29wdGlvbnMucGl0Y2g7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAob3B0aW9ucy5wYWRkaW5nICE9IG51bGwgJiYgIXRyLmlzUGFkZGluZ0VxdWFsKG9wdGlvbnMucGFkZGluZykpIHtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbaW5jb21wYXRpYmxlLXR5cGVdIC0gRmxvdyBjYW4ndCBpbmZlciB0aGF0IHBhZGRpbmcgaXMgbm90IG51bGwgaGVyZVxuICAgICAgICAgICAgdHIucGFkZGluZyA9IG9wdGlvbnMucGFkZGluZztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChvcHRpb25zLnByZWxvYWRPbmx5KSB7XG4gICAgICAgICAgICB0aGlzLl9wcmVsb2FkVGlsZXModHIpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmZpcmUobmV3IEV2ZW50KCdtb3Zlc3RhcnQnLCBldmVudERhdGEpKVxuICAgICAgICAgICAgLmZpcmUobmV3IEV2ZW50KCdtb3ZlJywgZXZlbnREYXRhKSk7XG5cbiAgICAgICAgaWYgKHpvb21DaGFuZ2VkKSB7XG4gICAgICAgICAgICB0aGlzLmZpcmUobmV3IEV2ZW50KCd6b29tc3RhcnQnLCBldmVudERhdGEpKVxuICAgICAgICAgICAgICAgIC5maXJlKG5ldyBFdmVudCgnem9vbScsIGV2ZW50RGF0YSkpXG4gICAgICAgICAgICAgICAgLmZpcmUobmV3IEV2ZW50KCd6b29tZW5kJywgZXZlbnREYXRhKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYmVhcmluZ0NoYW5nZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ3JvdGF0ZXN0YXJ0JywgZXZlbnREYXRhKSlcbiAgICAgICAgICAgICAgICAuZmlyZShuZXcgRXZlbnQoJ3JvdGF0ZScsIGV2ZW50RGF0YSkpXG4gICAgICAgICAgICAgICAgLmZpcmUobmV3IEV2ZW50KCdyb3RhdGVlbmQnLCBldmVudERhdGEpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwaXRjaENoYW5nZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ3BpdGNoc3RhcnQnLCBldmVudERhdGEpKVxuICAgICAgICAgICAgICAgIC5maXJlKG5ldyBFdmVudCgncGl0Y2gnLCBldmVudERhdGEpKVxuICAgICAgICAgICAgICAgIC5maXJlKG5ldyBFdmVudCgncGl0Y2hlbmQnLCBldmVudERhdGEpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLmZpcmUobmV3IEV2ZW50KCdtb3ZlZW5kJywgZXZlbnREYXRhKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBwb3NpdGlvbiBhbmQgb3JpZW50YXRpb24gb2YgdGhlIGNhbWVyYSBlbnRpdHkuXG4gICAgICpcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBub3Qgc3VwcG9ydGVkIGZvciBwcm9qZWN0aW9ucyBvdGhlciB0aGFuIG1lcmNhdG9yLlxuICAgICAqXG4gICAgICogQG1lbWJlcm9mIE1hcCNcbiAgICAgKiBAcmV0dXJucyB7RnJlZUNhbWVyYU9wdGlvbnN9IFRoZSBjYW1lcmEgc3RhdGUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBjYW1lcmEgPSBtYXAuZ2V0RnJlZUNhbWVyYU9wdGlvbnMoKTtcbiAgICAgKlxuICAgICAqIGNvbnN0IHBvc2l0aW9uID0gWzEzOC43MjY0OSwgMzUuMzM5NzRdO1xuICAgICAqIGNvbnN0IGFsdGl0dWRlID0gMzAwMDtcbiAgICAgKlxuICAgICAqIGNhbWVyYS5wb3NpdGlvbiA9IG1hcGJveGdsLk1lcmNhdG9yQ29vcmRpbmF0ZS5mcm9tTG5nTGF0KHBvc2l0aW9uLCBhbHRpdHVkZSk7XG4gICAgICogY2FtZXJhLmxvb2tBdFBvaW50KFsxMzguNzMwMzYsIDM1LjM2MTk3XSk7XG4gICAgICpcbiAgICAgKiBtYXAuc2V0RnJlZUNhbWVyYU9wdGlvbnMoY2FtZXJhKTtcbiAgICAgKi9cbiAgICBnZXRGcmVlQ2FtZXJhT3B0aW9ucygpOiBGcmVlQ2FtZXJhT3B0aW9ucyB7XG4gICAgICAgIGlmICghdGhpcy50cmFuc2Zvcm0ucHJvamVjdGlvbi5zdXBwb3J0c0ZyZWVDYW1lcmEpIHtcbiAgICAgICAgICAgIHdhcm5PbmNlKGZyZWVDYW1lcmFOb3RTdXBwb3J0ZWRXYXJuaW5nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm0uZ2V0RnJlZUNhbWVyYU9wdGlvbnMoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBgRnJlZUNhbWVyYU9wdGlvbnNgIHByb3ZpZGVzIG1vcmUgZGlyZWN0IGFjY2VzcyB0byB0aGUgdW5kZXJseWluZyBjYW1lcmEgZW50aXR5LlxuICAgICAqIEZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSB0aGUgc3RhdGUgc2V0IHVzaW5nIHRoaXMgQVBJIG11c3QgYmUgcmVwcmVzZW50YWJsZSB3aXRoXG4gICAgICogYENhbWVyYU9wdGlvbnNgIGFzIHdlbGwuIFBhcmFtZXRlcnMgYXJlIGNsYW1wZWQgaW50byBhIHZhbGlkIHJhbmdlIG9yIGRpc2NhcmRlZCBhcyBpbnZhbGlkXG4gICAgICogaWYgdGhlIGNvbnZlcnNpb24gdG8gdGhlIHBpdGNoIGFuZCBiZWFyaW5nIHByZXNlbnRhdGlvbiBpcyBhbWJpZ3VvdXMuIEZvciBleGFtcGxlIG9yaWVudGF0aW9uXG4gICAgICogY2FuIGJlIGludmFsaWQgaWYgaXQgbGVhZHMgdG8gdGhlIGNhbWVyYSBiZWluZyB1cHNpZGUgZG93biwgdGhlIHF1YXRlcm5pb24gaGFzIHplcm8gbGVuZ3RoLFxuICAgICAqIG9yIHRoZSBwaXRjaCBpcyBvdmVyIHRoZSBtYXhpbXVtIHBpdGNoIGxpbWl0LlxuICAgICAqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbm90IHN1cHBvcnRlZCBmb3IgcHJvamVjdGlvbnMgb3RoZXIgdGhhbiBtZXJjYXRvci5cbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiBNYXAjXG4gICAgICogQHBhcmFtIHtGcmVlQ2FtZXJhT3B0aW9uc30gb3B0aW9ucyBgRnJlZUNhbWVyYU9wdGlvbnNgIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge09iamVjdCB8IG51bGx9IGV2ZW50RGF0YSBBZGRpdGlvbmFsIHByb3BlcnRpZXMgdG8gYmUgYWRkZWQgdG8gZXZlbnQgb2JqZWN0cyBvZiBldmVudHMgdHJpZ2dlcmVkIGJ5IHRoaXMgbWV0aG9kLlxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6bW92ZXN0YXJ0XG4gICAgICogQGZpcmVzIE1hcC5ldmVudDp6b29tc3RhcnRcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50OnBpdGNoc3RhcnRcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50OnJvdGF0ZVxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6bW92ZVxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6em9vbVxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6cGl0Y2hcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Om1vdmVlbmRcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Onpvb21lbmRcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50OnBpdGNoZW5kXG4gICAgICogQHJldHVybnMge01hcH0gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGNhbWVyYSA9IG1hcC5nZXRGcmVlQ2FtZXJhT3B0aW9ucygpO1xuICAgICAqXG4gICAgICogY29uc3QgcG9zaXRpb24gPSBbMTM4LjcyNjQ5LCAzNS4zMzk3NF07XG4gICAgICogY29uc3QgYWx0aXR1ZGUgPSAzMDAwO1xuICAgICAqXG4gICAgICogY2FtZXJhLnBvc2l0aW9uID0gbWFwYm94Z2wuTWVyY2F0b3JDb29yZGluYXRlLmZyb21MbmdMYXQocG9zaXRpb24sIGFsdGl0dWRlKTtcbiAgICAgKiBjYW1lcmEubG9va0F0UG9pbnQoWzEzOC43MzAzNiwgMzUuMzYxOTddKTtcbiAgICAgKlxuICAgICAqIG1hcC5zZXRGcmVlQ2FtZXJhT3B0aW9ucyhjYW1lcmEpO1xuICAgICAqL1xuICAgIHNldEZyZWVDYW1lcmFPcHRpb25zKG9wdGlvbnM6IEZyZWVDYW1lcmFPcHRpb25zLCBldmVudERhdGE/OiBPYmplY3QpOiB0aGlzIHtcbiAgICAgICAgY29uc3QgdHIgPSB0aGlzLnRyYW5zZm9ybTtcblxuICAgICAgICBpZiAoIXRyLnByb2plY3Rpb24uc3VwcG9ydHNGcmVlQ2FtZXJhKSB7XG4gICAgICAgICAgICB3YXJuT25jZShmcmVlQ2FtZXJhTm90U3VwcG9ydGVkV2FybmluZyk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc3RvcCgpO1xuXG4gICAgICAgIGNvbnN0IHByZXZab29tID0gdHIuem9vbTtcbiAgICAgICAgY29uc3QgcHJldlBpdGNoID0gdHIucGl0Y2g7XG4gICAgICAgIGNvbnN0IHByZXZCZWFyaW5nID0gdHIuYmVhcmluZztcblxuICAgICAgICB0ci5zZXRGcmVlQ2FtZXJhT3B0aW9ucyhvcHRpb25zKTtcblxuICAgICAgICBjb25zdCB6b29tQ2hhbmdlZCA9IHByZXZab29tICE9PSB0ci56b29tO1xuICAgICAgICBjb25zdCBwaXRjaENoYW5nZWQgPSBwcmV2UGl0Y2ggIT09IHRyLnBpdGNoO1xuICAgICAgICBjb25zdCBiZWFyaW5nQ2hhbmdlZCA9IHByZXZCZWFyaW5nICE9PSB0ci5iZWFyaW5nO1xuXG4gICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ21vdmVzdGFydCcsIGV2ZW50RGF0YSkpXG4gICAgICAgICAgICAuZmlyZShuZXcgRXZlbnQoJ21vdmUnLCBldmVudERhdGEpKTtcblxuICAgICAgICBpZiAoem9vbUNoYW5nZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ3pvb21zdGFydCcsIGV2ZW50RGF0YSkpXG4gICAgICAgICAgICAgICAgLmZpcmUobmV3IEV2ZW50KCd6b29tJywgZXZlbnREYXRhKSlcbiAgICAgICAgICAgICAgICAuZmlyZShuZXcgRXZlbnQoJ3pvb21lbmQnLCBldmVudERhdGEpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChiZWFyaW5nQ2hhbmdlZCkge1xuICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgncm90YXRlc3RhcnQnLCBldmVudERhdGEpKVxuICAgICAgICAgICAgICAgIC5maXJlKG5ldyBFdmVudCgncm90YXRlJywgZXZlbnREYXRhKSlcbiAgICAgICAgICAgICAgICAuZmlyZShuZXcgRXZlbnQoJ3JvdGF0ZWVuZCcsIGV2ZW50RGF0YSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBpdGNoQ2hhbmdlZCkge1xuICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgncGl0Y2hzdGFydCcsIGV2ZW50RGF0YSkpXG4gICAgICAgICAgICAgICAgLmZpcmUobmV3IEV2ZW50KCdwaXRjaCcsIGV2ZW50RGF0YSkpXG4gICAgICAgICAgICAgICAgLmZpcmUobmV3IEV2ZW50KCdwaXRjaGVuZCcsIGV2ZW50RGF0YSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgnbW92ZWVuZCcsIGV2ZW50RGF0YSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGFuZ2VzIGFueSBjb21iaW5hdGlvbiBvZiBgY2VudGVyYCwgYHpvb21gLCBgYmVhcmluZ2AsIGBwaXRjaGAsIGFuZCBgcGFkZGluZ2Agd2l0aCBhbiBhbmltYXRlZCB0cmFuc2l0aW9uXG4gICAgICogYmV0d2VlbiBvbGQgYW5kIG5ldyB2YWx1ZXMuIFRoZSBtYXAgd2lsbCByZXRhaW4gaXRzIGN1cnJlbnQgdmFsdWVzIGZvciBhbnlcbiAgICAgKiBkZXRhaWxzIG5vdCBzcGVjaWZpZWQgaW4gYG9wdGlvbnNgLlxuICAgICAqXG4gICAgICogTm90ZTogVGhlIHRyYW5zaXRpb24gd2lsbCBoYXBwZW4gaW5zdGFudGx5IGlmIHRoZSB1c2VyIGhhcyBlbmFibGVkXG4gICAgICogdGhlIGByZWR1Y2VkIG1vdGlvbmAgYWNjZXNzaWJpbGl0eSBmZWF0dXJlIGVuYWJsZWQgaW4gdGhlaXIgb3BlcmF0aW5nIHN5c3RlbSxcbiAgICAgKiB1bmxlc3MgYG9wdGlvbnNgIGluY2x1ZGVzIGBlc3NlbnRpYWw6IHRydWVgLlxuICAgICAqXG4gICAgICogQG1lbWJlcm9mIE1hcCNcbiAgICAgKiBAcGFyYW0ge0Vhc2luZ09wdGlvbnN9IG9wdGlvbnMgT3B0aW9ucyBkZXNjcmliaW5nIHRoZSBkZXN0aW5hdGlvbiBhbmQgYW5pbWF0aW9uIG9mIHRoZSB0cmFuc2l0aW9uLlxuICAgICAqICAgICAgICAgICAgQWNjZXB0cyB7QGxpbmsgQ2FtZXJhT3B0aW9uc30gYW5kIHtAbGluayBBbmltYXRpb25PcHRpb25zfS5cbiAgICAgKiBAcGFyYW0ge09iamVjdCB8IG51bGx9IGV2ZW50RGF0YSBBZGRpdGlvbmFsIHByb3BlcnRpZXMgdG8gYmUgYWRkZWQgdG8gZXZlbnQgb2JqZWN0cyBvZiBldmVudHMgdHJpZ2dlcmVkIGJ5IHRoaXMgbWV0aG9kLlxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6bW92ZXN0YXJ0XG4gICAgICogQGZpcmVzIE1hcC5ldmVudDp6b29tc3RhcnRcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50OnBpdGNoc3RhcnRcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50OnJvdGF0ZVxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6bW92ZVxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6em9vbVxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6cGl0Y2hcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Om1vdmVlbmRcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Onpvb21lbmRcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50OnBpdGNoZW5kXG4gICAgICogQHJldHVybnMge01hcH0gYHRoaXNgIFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBFYXNlIHdpdGggZGVmYXVsdCBvcHRpb25zIHRvIG51bGwgaXNsYW5kIGZvciA1IHNlY29uZHMuXG4gICAgICogbWFwLmVhc2VUbyh7Y2VudGVyOiBbMCwgMF0sIHpvb206IDksIGR1cmF0aW9uOiA1MDAwfSk7XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBVc2luZyBlYXNlVG8gb3B0aW9ucy5cbiAgICAgKiBtYXAuZWFzZVRvKHtcbiAgICAgKiAgICAgY2VudGVyOiBbMCwgMF0sXG4gICAgICogICAgIHpvb206IDksXG4gICAgICogICAgIHNwZWVkOiAwLjIsXG4gICAgICogICAgIGN1cnZlOiAxLFxuICAgICAqICAgICBkdXJhdGlvbjogNTAwMCxcbiAgICAgKiAgICAgZWFzaW5nKHQpIHtcbiAgICAgKiAgICAgICAgIHJldHVybiB0O1xuICAgICAqICAgICB9XG4gICAgICogfSk7XG4gICAgICogQHNlZSBbRXhhbXBsZTogTmF2aWdhdGUgdGhlIG1hcCB3aXRoIGdhbWUtbGlrZSBjb250cm9sc10oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9nYW1lLWNvbnRyb2xzLylcbiAgICAgKi9cbiAgICBlYXNlVG8ob3B0aW9uczogRWFzaW5nT3B0aW9ucyAmIHtlYXNlSWQ/OiBzdHJpbmd9LCBldmVudERhdGE/OiBPYmplY3QpOiB0aGlzIHtcbiAgICAgICAgdGhpcy5fc3RvcChmYWxzZSwgb3B0aW9ucy5lYXNlSWQpO1xuXG4gICAgICAgIG9wdGlvbnMgPSBleHRlbmQoe1xuICAgICAgICAgICAgb2Zmc2V0OiBbMCwgMF0sXG4gICAgICAgICAgICBkdXJhdGlvbjogNTAwLFxuICAgICAgICAgICAgZWFzaW5nOiBkZWZhdWx0RWFzaW5nXG4gICAgICAgIH0sIG9wdGlvbnMpO1xuXG4gICAgICAgIGlmIChvcHRpb25zLmFuaW1hdGUgPT09IGZhbHNlIHx8IHRoaXMuX3ByZWZlcnNSZWR1Y2VkTW90aW9uKG9wdGlvbnMpKSBvcHRpb25zLmR1cmF0aW9uID0gMDtcblxuICAgICAgICBjb25zdCB0ciA9IHRoaXMudHJhbnNmb3JtLFxuICAgICAgICAgICAgc3RhcnRab29tID0gdGhpcy5nZXRab29tKCksXG4gICAgICAgICAgICBzdGFydEJlYXJpbmcgPSB0aGlzLmdldEJlYXJpbmcoKSxcbiAgICAgICAgICAgIHN0YXJ0UGl0Y2ggPSB0aGlzLmdldFBpdGNoKCksXG4gICAgICAgICAgICBzdGFydFBhZGRpbmcgPSB0aGlzLmdldFBhZGRpbmcoKSxcblxuICAgICAgICAgICAgem9vbSA9ICd6b29tJyBpbiBvcHRpb25zID8gK29wdGlvbnMuem9vbSA6IHN0YXJ0Wm9vbSxcbiAgICAgICAgICAgIGJlYXJpbmcgPSAnYmVhcmluZycgaW4gb3B0aW9ucyA/IHRoaXMuX25vcm1hbGl6ZUJlYXJpbmcob3B0aW9ucy5iZWFyaW5nLCBzdGFydEJlYXJpbmcpIDogc3RhcnRCZWFyaW5nLFxuICAgICAgICAgICAgcGl0Y2ggPSAncGl0Y2gnIGluIG9wdGlvbnMgPyArb3B0aW9ucy5waXRjaCA6IHN0YXJ0UGl0Y2gsXG4gICAgICAgICAgICBwYWRkaW5nID0gJ3BhZGRpbmcnIGluIG9wdGlvbnMgPyBvcHRpb25zLnBhZGRpbmcgOiB0ci5wYWRkaW5nO1xuXG4gICAgICAgIGNvbnN0IG9mZnNldEFzUG9pbnQgPSBQb2ludC5jb252ZXJ0KG9wdGlvbnMub2Zmc2V0KTtcblxuICAgICAgICBsZXQgcG9pbnRBdE9mZnNldDtcbiAgICAgICAgbGV0IGZyb207XG4gICAgICAgIGxldCBkZWx0YTtcblxuICAgICAgICBpZiAodHIucHJvamVjdGlvbi5uYW1lID09PSAnZ2xvYmUnKSB7XG4gICAgICAgICAgICAvLyBQaXhlbCBjb29yZGluYXRlcyB3aWxsIGJlIGFwcGxpZWQgZGlyZWN0bHkgdG8gdHJhbnNsYXRlIHRoZSBnbG9iZVxuICAgICAgICAgICAgY29uc3QgY2VudGVyQ29vcmQgPSBNZXJjYXRvckNvb3JkaW5hdGUuZnJvbUxuZ0xhdCh0ci5jZW50ZXIpO1xuXG4gICAgICAgICAgICBjb25zdCByb3RhdGVkT2Zmc2V0ID0gb2Zmc2V0QXNQb2ludC5yb3RhdGUoLXRyLmFuZ2xlKTtcbiAgICAgICAgICAgIGNlbnRlckNvb3JkLnggKz0gcm90YXRlZE9mZnNldC54IC8gdHIud29ybGRTaXplO1xuICAgICAgICAgICAgY2VudGVyQ29vcmQueSArPSByb3RhdGVkT2Zmc2V0LnkgLyB0ci53b3JsZFNpemU7XG5cbiAgICAgICAgICAgIGNvbnN0IGxvY2F0aW9uQXRPZmZzZXQgPSBjZW50ZXJDb29yZC50b0xuZ0xhdCgpO1xuICAgICAgICAgICAgY29uc3QgY2VudGVyID0gTG5nTGF0LmNvbnZlcnQob3B0aW9ucy5jZW50ZXIgfHwgbG9jYXRpb25BdE9mZnNldCk7XG4gICAgICAgICAgICB0aGlzLl9ub3JtYWxpemVDZW50ZXIoY2VudGVyKTtcblxuICAgICAgICAgICAgcG9pbnRBdE9mZnNldCA9IHRyLmNlbnRlclBvaW50LmFkZChyb3RhdGVkT2Zmc2V0KTtcbiAgICAgICAgICAgIGZyb20gPSBuZXcgUG9pbnQoY2VudGVyQ29vcmQueCwgY2VudGVyQ29vcmQueSkubXVsdCh0ci53b3JsZFNpemUpO1xuICAgICAgICAgICAgZGVsdGEgPSBuZXcgUG9pbnQobWVyY2F0b3JYZnJvbUxuZyhjZW50ZXIubG5nKSwgbWVyY2F0b3JZZnJvbUxhdChjZW50ZXIubGF0KSkubXVsdCh0ci53b3JsZFNpemUpLnN1Yihmcm9tKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBvaW50QXRPZmZzZXQgPSB0ci5jZW50ZXJQb2ludC5hZGQob2Zmc2V0QXNQb2ludCk7XG4gICAgICAgICAgICBjb25zdCBsb2NhdGlvbkF0T2Zmc2V0ID0gdHIucG9pbnRMb2NhdGlvbihwb2ludEF0T2Zmc2V0KTtcbiAgICAgICAgICAgIGNvbnN0IGNlbnRlciA9IExuZ0xhdC5jb252ZXJ0KG9wdGlvbnMuY2VudGVyIHx8IGxvY2F0aW9uQXRPZmZzZXQpO1xuICAgICAgICAgICAgdGhpcy5fbm9ybWFsaXplQ2VudGVyKGNlbnRlcik7XG5cbiAgICAgICAgICAgIGZyb20gPSB0ci5wcm9qZWN0KGxvY2F0aW9uQXRPZmZzZXQpO1xuICAgICAgICAgICAgZGVsdGEgPSB0ci5wcm9qZWN0KGNlbnRlcikuc3ViKGZyb20pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGZpbmFsU2NhbGUgPSB0ci56b29tU2NhbGUoem9vbSAtIHN0YXJ0Wm9vbSk7XG5cbiAgICAgICAgbGV0IGFyb3VuZCwgYXJvdW5kUG9pbnQ7XG5cbiAgICAgICAgaWYgKG9wdGlvbnMuYXJvdW5kKSB7XG4gICAgICAgICAgICBhcm91bmQgPSBMbmdMYXQuY29udmVydChvcHRpb25zLmFyb3VuZCk7XG4gICAgICAgICAgICBhcm91bmRQb2ludCA9IHRyLmxvY2F0aW9uUG9pbnQoYXJvdW5kKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHpvb21DaGFuZ2VkID0gdGhpcy5fem9vbWluZyB8fCAoem9vbSAhPT0gc3RhcnRab29tKTtcbiAgICAgICAgY29uc3QgYmVhcmluZ0NoYW5nZWQgPSB0aGlzLl9yb3RhdGluZyB8fCAoc3RhcnRCZWFyaW5nICE9PSBiZWFyaW5nKTtcbiAgICAgICAgY29uc3QgcGl0Y2hDaGFuZ2VkID0gdGhpcy5fcGl0Y2hpbmcgfHwgKHBpdGNoICE9PSBzdGFydFBpdGNoKTtcbiAgICAgICAgY29uc3QgcGFkZGluZ0NoYW5nZWQgPSAhdHIuaXNQYWRkaW5nRXF1YWwocGFkZGluZyk7XG5cbiAgICAgICAgY29uc3QgZnJhbWUgPSAodHI6IFRyYW5zZm9ybSkgPT4gKGs6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgaWYgKHpvb21DaGFuZ2VkKSB7XG4gICAgICAgICAgICAgICAgdHIuem9vbSA9IGludGVycG9sYXRlKHN0YXJ0Wm9vbSwgem9vbSwgayk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYmVhcmluZ0NoYW5nZWQpIHtcbiAgICAgICAgICAgICAgICB0ci5iZWFyaW5nID0gaW50ZXJwb2xhdGUoc3RhcnRCZWFyaW5nLCBiZWFyaW5nLCBrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwaXRjaENoYW5nZWQpIHtcbiAgICAgICAgICAgICAgICB0ci5waXRjaCA9IGludGVycG9sYXRlKHN0YXJ0UGl0Y2gsIHBpdGNoLCBrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwYWRkaW5nQ2hhbmdlZCkge1xuICAgICAgICAgICAgICAgIHRyLmludGVycG9sYXRlUGFkZGluZyhzdGFydFBhZGRpbmcsIHBhZGRpbmcsIGspO1xuICAgICAgICAgICAgICAgIC8vIFdoZW4gcGFkZGluZyBpcyBiZWluZyBhcHBsaWVkLCBUcmFuc2Zvcm0jY2VudGVyUG9pbnQgaXMgY2hhbmdpbmcgY29udGludW91c2x5LFxuICAgICAgICAgICAgICAgIC8vIHRodXMgd2UgbmVlZCB0byByZWNhbGN1bGF0ZSBvZmZzZXRQb2ludCBldmVyeSBmcmEsZVxuICAgICAgICAgICAgICAgIHBvaW50QXRPZmZzZXQgPSB0ci5jZW50ZXJQb2ludC5hZGQob2Zmc2V0QXNQb2ludCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChhcm91bmQpIHtcbiAgICAgICAgICAgICAgICB0ci5zZXRMb2NhdGlvbkF0UG9pbnQoYXJvdW5kLCBhcm91bmRQb2ludCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IHNjYWxlID0gdHIuem9vbVNjYWxlKHRyLnpvb20gLSBzdGFydFpvb20pO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJhc2UgPSB6b29tID4gc3RhcnRab29tID9cbiAgICAgICAgICAgICAgICAgICAgTWF0aC5taW4oMiwgZmluYWxTY2FsZSkgOlxuICAgICAgICAgICAgICAgICAgICBNYXRoLm1heCgwLjUsIGZpbmFsU2NhbGUpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHNwZWVkdXAgPSBNYXRoLnBvdyhiYXNlLCAxIC0gayk7XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3Q2VudGVyID0gdHIudW5wcm9qZWN0KGZyb20uYWRkKGRlbHRhLm11bHQoayAqIHNwZWVkdXApKS5tdWx0KHNjYWxlKSk7XG4gICAgICAgICAgICAgICAgdHIuc2V0TG9jYXRpb25BdFBvaW50KHRyLnJlbmRlcldvcmxkQ29waWVzID8gbmV3Q2VudGVyLndyYXAoKSA6IG5ld0NlbnRlciwgcG9pbnRBdE9mZnNldCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghb3B0aW9ucy5wcmVsb2FkT25seSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2ZpcmVNb3ZlRXZlbnRzKGV2ZW50RGF0YSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0cjtcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAob3B0aW9ucy5wcmVsb2FkT25seSkge1xuICAgICAgICAgICAgY29uc3QgcHJlZGljdGVkVHJhbnNmb3JtcyA9IHRoaXMuX2VtdWxhdGUoZnJhbWUsIG9wdGlvbnMuZHVyYXRpb24sIHRyKTtcbiAgICAgICAgICAgIHRoaXMuX3ByZWxvYWRUaWxlcyhwcmVkaWN0ZWRUcmFuc2Zvcm1zKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY3VycmVudGx5ID0ge1xuICAgICAgICAgICAgbW92aW5nOiB0aGlzLl9tb3ZpbmcsXG4gICAgICAgICAgICB6b29taW5nOiB0aGlzLl96b29taW5nLFxuICAgICAgICAgICAgcm90YXRpbmc6IHRoaXMuX3JvdGF0aW5nLFxuICAgICAgICAgICAgcGl0Y2hpbmc6IHRoaXMuX3BpdGNoaW5nXG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5fem9vbWluZyA9IHpvb21DaGFuZ2VkO1xuICAgICAgICB0aGlzLl9yb3RhdGluZyA9IGJlYXJpbmdDaGFuZ2VkO1xuICAgICAgICB0aGlzLl9waXRjaGluZyA9IHBpdGNoQ2hhbmdlZDtcbiAgICAgICAgdGhpcy5fcGFkZGluZyA9IHBhZGRpbmdDaGFuZ2VkO1xuXG4gICAgICAgIHRoaXMuX2Vhc2VJZCA9IG9wdGlvbnMuZWFzZUlkO1xuICAgICAgICB0aGlzLl9wcmVwYXJlRWFzZShldmVudERhdGEsIG9wdGlvbnMubm9Nb3ZlU3RhcnQsIGN1cnJlbnRseSk7XG5cbiAgICAgICAgdGhpcy5fZWFzZShmcmFtZSh0ciksIChpbnRlcnJ1cHRpbmdFYXNlSWQ/OiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIHRyLnJlY2VudGVyT25UZXJyYWluKCk7XG4gICAgICAgICAgICB0aGlzLl9hZnRlckVhc2UoZXZlbnREYXRhLCBpbnRlcnJ1cHRpbmdFYXNlSWQpO1xuICAgICAgICB9LCBvcHRpb25zKTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBfcHJlcGFyZUVhc2UoZXZlbnREYXRhPzogT2JqZWN0LCBub01vdmVTdGFydDogYm9vbGVhbiwgY3VycmVudGx5OiBPYmplY3QgPSB7fSkge1xuICAgICAgICB0aGlzLl9tb3ZpbmcgPSB0cnVlO1xuICAgICAgICB0aGlzLnRyYW5zZm9ybS5jYW1lcmFFbGV2YXRpb25SZWZlcmVuY2UgPSBcInNlYVwiO1xuXG4gICAgICAgIGlmICghbm9Nb3ZlU3RhcnQgJiYgIWN1cnJlbnRseS5tb3ZpbmcpIHtcbiAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ21vdmVzdGFydCcsIGV2ZW50RGF0YSkpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl96b29taW5nICYmICFjdXJyZW50bHkuem9vbWluZykge1xuICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgnem9vbXN0YXJ0JywgZXZlbnREYXRhKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX3JvdGF0aW5nICYmICFjdXJyZW50bHkucm90YXRpbmcpIHtcbiAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ3JvdGF0ZXN0YXJ0JywgZXZlbnREYXRhKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX3BpdGNoaW5nICYmICFjdXJyZW50bHkucGl0Y2hpbmcpIHtcbiAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ3BpdGNoc3RhcnQnLCBldmVudERhdGEpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9maXJlTW92ZUV2ZW50cyhldmVudERhdGE/OiBPYmplY3QpIHtcbiAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgnbW92ZScsIGV2ZW50RGF0YSkpO1xuICAgICAgICBpZiAodGhpcy5fem9vbWluZykge1xuICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgnem9vbScsIGV2ZW50RGF0YSkpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9yb3RhdGluZykge1xuICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgncm90YXRlJywgZXZlbnREYXRhKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX3BpdGNoaW5nKSB7XG4gICAgICAgICAgICB0aGlzLmZpcmUobmV3IEV2ZW50KCdwaXRjaCcsIGV2ZW50RGF0YSkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX2FmdGVyRWFzZShldmVudERhdGE/OiBPYmplY3QsIGVhc2VJZD86IHN0cmluZykge1xuICAgICAgICAvLyBpZiB0aGlzIGVhc2luZyBpcyBiZWluZyBzdG9wcGVkIHRvIHN0YXJ0IGFub3RoZXIgZWFzaW5nIHdpdGhcbiAgICAgICAgLy8gdGhlIHNhbWUgaWQgdGhlbiBkb24ndCBmaXJlIGFueSBldmVudHMgdG8gYXZvaWQgZXh0cmEgc3RhcnQvc3RvcCBldmVudHNcbiAgICAgICAgaWYgKHRoaXMuX2Vhc2VJZCAmJiBlYXNlSWQgJiYgdGhpcy5fZWFzZUlkID09PSBlYXNlSWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9lYXNlSWQgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMudHJhbnNmb3JtLmNhbWVyYUVsZXZhdGlvblJlZmVyZW5jZSA9IFwiZ3JvdW5kXCI7XG5cbiAgICAgICAgY29uc3Qgd2FzWm9vbWluZyA9IHRoaXMuX3pvb21pbmc7XG4gICAgICAgIGNvbnN0IHdhc1JvdGF0aW5nID0gdGhpcy5fcm90YXRpbmc7XG4gICAgICAgIGNvbnN0IHdhc1BpdGNoaW5nID0gdGhpcy5fcGl0Y2hpbmc7XG4gICAgICAgIHRoaXMuX21vdmluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLl96b29taW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX3JvdGF0aW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX3BpdGNoaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX3BhZGRpbmcgPSBmYWxzZTtcblxuICAgICAgICBpZiAod2FzWm9vbWluZykge1xuICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgnem9vbWVuZCcsIGV2ZW50RGF0YSkpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh3YXNSb3RhdGluZykge1xuICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgncm90YXRlZW5kJywgZXZlbnREYXRhKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHdhc1BpdGNoaW5nKSB7XG4gICAgICAgICAgICB0aGlzLmZpcmUobmV3IEV2ZW50KCdwaXRjaGVuZCcsIGV2ZW50RGF0YSkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ21vdmVlbmQnLCBldmVudERhdGEpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGFuZ2VzIGFueSBjb21iaW5hdGlvbiBvZiBjZW50ZXIsIHpvb20sIGJlYXJpbmcsIGFuZCBwaXRjaCwgYW5pbWF0aW5nIHRoZSB0cmFuc2l0aW9uIGFsb25nIGEgY3VydmUgdGhhdFxuICAgICAqIGV2b2tlcyBmbGlnaHQuIFRoZSBhbmltYXRpb24gc2VhbWxlc3NseSBpbmNvcnBvcmF0ZXMgem9vbWluZyBhbmQgcGFubmluZyB0byBoZWxwXG4gICAgICogdGhlIHVzZXIgbWFpbnRhaW4gdGhlaXIgYmVhcmluZ3MgZXZlbiBhZnRlciB0cmF2ZXJzaW5nIGEgZ3JlYXQgZGlzdGFuY2UuXG4gICAgICpcbiAgICAgKiBJZiBhIHVzZXIgaGFzIHRoZSBgcmVkdWNlZCBtb3Rpb25gIGFjY2Vzc2liaWxpdHkgZmVhdHVyZSBlbmFibGVkIGluIHRoZWlyXG4gICAgICogb3BlcmF0aW5nIHN5c3RlbSwgdGhlIGFuaW1hdGlvbiB3aWxsIGJlIHNraXBwZWQgYW5kIHRoaXMgd2lsbCBiZWhhdmVcbiAgICAgKiBlcXVpdmFsZW50bHkgdG8gYGp1bXBUb2AsIHVubGVzcyAnb3B0aW9ucycgaW5jbHVkZXMgYGVzc2VudGlhbDogdHJ1ZWAuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YgTWFwI1xuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIE9wdGlvbnMgZGVzY3JpYmluZyB0aGUgZGVzdGluYXRpb24gYW5kIGFuaW1hdGlvbiBvZiB0aGUgdHJhbnNpdGlvbi5cbiAgICAgKiAgICAgQWNjZXB0cyB7QGxpbmsgQ2FtZXJhT3B0aW9uc30sIHtAbGluayBBbmltYXRpb25PcHRpb25zfSxcbiAgICAgKiAgICAgYW5kIHRoZSBmb2xsb3dpbmcgYWRkaXRpb25hbCBvcHRpb25zLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5jdXJ2ZT0xLjQyXSBUaGUgem9vbWluZyBcImN1cnZlXCIgdGhhdCB3aWxsIG9jY3VyIGFsb25nIHRoZVxuICAgICAqICAgICBmbGlnaHQgcGF0aC4gQSBoaWdoIHZhbHVlIG1heGltaXplcyB6b29taW5nIGZvciBhbiBleGFnZ2VyYXRlZCBhbmltYXRpb24sIHdoaWxlIGEgbG93XG4gICAgICogICAgIHZhbHVlIG1pbmltaXplcyB6b29taW5nIGZvciBhbiBlZmZlY3QgY2xvc2VyIHRvIHtAbGluayBNYXAjZWFzZVRvfS4gMS40MiBpcyB0aGUgYXZlcmFnZVxuICAgICAqICAgICB2YWx1ZSBzZWxlY3RlZCBieSBwYXJ0aWNpcGFudHMgaW4gdGhlIHVzZXIgc3R1ZHkgZGlzY3Vzc2VkIGluXG4gICAgICogICAgIFt2YW4gV2lqayAoMjAwMyldKGh0dHBzOi8vd3d3Lndpbi50dWUubmwvfnZhbndpamsvem9vbXBhbi5wZGYpLiBBIHZhbHVlIG9mXG4gICAgICogICAgIGBNYXRoLnBvdyg2LCAwLjI1KWAgd291bGQgYmUgZXF1aXZhbGVudCB0byB0aGUgcm9vdCBtZWFuIHNxdWFyZWQgYXZlcmFnZSB2ZWxvY2l0eS4gQVxuICAgICAqICAgICB2YWx1ZSBvZiAxIHdvdWxkIHByb2R1Y2UgYSBjaXJjdWxhciBtb3Rpb24uIElmIGBvcHRpb25zLm1pblpvb21gIGlzIHNwZWNpZmllZCwgdGhpcyBvcHRpb24gd2lsbCBiZSBpZ25vcmVkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5taW5ab29tXSBUaGUgemVyby1iYXNlZCB6b29tIGxldmVsIGF0IHRoZSBwZWFrIG9mIHRoZSBmbGlnaHQgcGF0aC4gSWZcbiAgICAgKiAgICAgdGhpcyBvcHRpb24gaXMgc3BlY2lmaWVkLCBgb3B0aW9ucy5jdXJ2ZWAgd2lsbCBiZSBpZ25vcmVkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5zcGVlZD0xLjJdIFRoZSBhdmVyYWdlIHNwZWVkIG9mIHRoZSBhbmltYXRpb24gZGVmaW5lZCBpbiByZWxhdGlvbiB0b1xuICAgICAqICAgICBgb3B0aW9ucy5jdXJ2ZWAuIEEgc3BlZWQgb2YgMS4yIG1lYW5zIHRoYXQgdGhlIG1hcCBhcHBlYXJzIHRvIG1vdmUgYWxvbmcgdGhlIGZsaWdodCBwYXRoXG4gICAgICogICAgIGJ5IDEuMiB0aW1lcyBgb3B0aW9ucy5jdXJ2ZWAgc2NyZWVuZnVscyBldmVyeSBzZWNvbmQuIEEgX3NjcmVlbmZ1bF8gaXMgdGhlIG1hcCdzIHZpc2libGUgc3Bhbi5cbiAgICAgKiAgICAgSXQgZG9lcyBub3QgY29ycmVzcG9uZCB0byBhIGZpeGVkIHBoeXNpY2FsIGRpc3RhbmNlLCBidXQgdmFyaWVzIGJ5IHpvb20gbGV2ZWwuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLnNjcmVlblNwZWVkXSBUaGUgYXZlcmFnZSBzcGVlZCBvZiB0aGUgYW5pbWF0aW9uIG1lYXN1cmVkIGluIHNjcmVlbmZ1bHNcbiAgICAgKiAgICAgcGVyIHNlY29uZCwgYXNzdW1pbmcgYSBsaW5lYXIgdGltaW5nIGN1cnZlLiBJZiBgb3B0aW9ucy5zcGVlZGAgaXMgc3BlY2lmaWVkLCB0aGlzIG9wdGlvbiBpcyBpZ25vcmVkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5tYXhEdXJhdGlvbl0gVGhlIGFuaW1hdGlvbidzIG1heGltdW0gZHVyYXRpb24sIG1lYXN1cmVkIGluIG1pbGxpc2Vjb25kcy5cbiAgICAgKiAgICAgSWYgZHVyYXRpb24gZXhjZWVkcyBtYXhpbXVtIGR1cmF0aW9uLCBpdCByZXNldHMgdG8gMC5cbiAgICAgKiBAcGFyYW0ge09iamVjdCB8IG51bGx9IGV2ZW50RGF0YSBBZGRpdGlvbmFsIHByb3BlcnRpZXMgdG8gYmUgYWRkZWQgdG8gZXZlbnQgb2JqZWN0cyBvZiBldmVudHMgdHJpZ2dlcmVkIGJ5IHRoaXMgbWV0aG9kLlxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6bW92ZXN0YXJ0XG4gICAgICogQGZpcmVzIE1hcC5ldmVudDp6b29tc3RhcnRcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50OnBpdGNoc3RhcnRcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Om1vdmVcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Onpvb21cbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50OnJvdGF0ZVxuICAgICAqIEBmaXJlcyBNYXAuZXZlbnQ6cGl0Y2hcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Om1vdmVlbmRcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50Onpvb21lbmRcbiAgICAgKiBAZmlyZXMgTWFwLmV2ZW50OnBpdGNoZW5kXG4gICAgICogQHJldHVybnMge01hcH0gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIGZseSB3aXRoIGRlZmF1bHQgb3B0aW9ucyB0byBudWxsIGlzbGFuZFxuICAgICAqIG1hcC5mbHlUbyh7Y2VudGVyOiBbMCwgMF0sIHpvb206IDl9KTtcbiAgICAgKiAvLyB1c2luZyBmbHlUbyBvcHRpb25zXG4gICAgICogbWFwLmZseVRvKHtcbiAgICAgKiAgICAgY2VudGVyOiBbMCwgMF0sXG4gICAgICogICAgIHpvb206IDksXG4gICAgICogICAgIHNwZWVkOiAwLjIsXG4gICAgICogICAgIGN1cnZlOiAxLFxuICAgICAqICAgICBlYXNpbmcodCkge1xuICAgICAqICAgICAgICAgcmV0dXJuIHQ7XG4gICAgICogICAgIH1cbiAgICAgKiB9KTtcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBGbHkgdG8gYSBsb2NhdGlvbl0oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9mbHl0by8pXG4gICAgICogQHNlZSBbRXhhbXBsZTogU2xvd2x5IGZseSB0byBhIGxvY2F0aW9uXShodHRwczovL3d3dy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2ZseXRvLW9wdGlvbnMvKVxuICAgICAqIEBzZWUgW0V4YW1wbGU6IEZseSB0byBhIGxvY2F0aW9uIGJhc2VkIG9uIHNjcm9sbCBwb3NpdGlvbl0oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9zY3JvbGwtZmx5LXRvLylcbiAgICAgKi9cbiAgICBmbHlUbyhvcHRpb25zOiBFYXNpbmdPcHRpb25zLCBldmVudERhdGE/OiBPYmplY3QpOiB0aGlzIHtcbiAgICAgICAgLy8gRmFsbCB0aHJvdWdoIHRvIGp1bXBUbyBpZiB1c2VyIGhhcyBzZXQgcHJlZmVycy1yZWR1Y2VkLW1vdGlvblxuICAgICAgICBpZiAodGhpcy5fcHJlZmVyc1JlZHVjZWRNb3Rpb24ob3B0aW9ucykpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvZXJjZWRPcHRpb25zID0gcGljayhvcHRpb25zLCBbJ2NlbnRlcicsICd6b29tJywgJ2JlYXJpbmcnLCAncGl0Y2gnLCAnYXJvdW5kJ10pO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuanVtcFRvKGNvZXJjZWRPcHRpb25zLCBldmVudERhdGEpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVGhpcyBtZXRob2QgaW1wbGVtZW50cyBhbiDigJxvcHRpbWFsIHBhdGjigJ0gYW5pbWF0aW9uLCBhcyBkZXRhaWxlZCBpbjpcbiAgICAgICAgLy9cbiAgICAgICAgLy8gVmFuIFdpamssIEphcmtlIEouOyBOdWlqLCBXaW0gQS4gQS4g4oCcU21vb3RoIGFuZCBlZmZpY2llbnQgem9vbWluZyBhbmQgcGFubmluZy7igJ0gSU5GT1ZJU1xuICAgICAgICAvLyAgIOKAmTAzLiBwcC4gMTXigJMyMi4gPGh0dHBzOi8vd3d3Lndpbi50dWUubmwvfnZhbndpamsvem9vbXBhbi5wZGYjcGFnZT01Pi5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gV2hlcmUgYXBwbGljYWJsZSwgbG9jYWwgdmFyaWFibGUgZG9jdW1lbnRhdGlvbiBiZWdpbnMgd2l0aCB0aGUgYXNzb2NpYXRlZCB2YXJpYWJsZSBvclxuICAgICAgICAvLyBmdW5jdGlvbiBpbiB2YW4gV2lqayAoMjAwMykuXG5cbiAgICAgICAgdGhpcy5zdG9wKCk7XG5cbiAgICAgICAgb3B0aW9ucyA9IGV4dGVuZCh7XG4gICAgICAgICAgICBvZmZzZXQ6IFswLCAwXSxcbiAgICAgICAgICAgIHNwZWVkOiAxLjIsXG4gICAgICAgICAgICBjdXJ2ZTogMS40MixcbiAgICAgICAgICAgIGVhc2luZzogZGVmYXVsdEVhc2luZ1xuICAgICAgICB9LCBvcHRpb25zKTtcblxuICAgICAgICBjb25zdCB0ciA9IHRoaXMudHJhbnNmb3JtLFxuICAgICAgICAgICAgc3RhcnRab29tID0gdGhpcy5nZXRab29tKCksXG4gICAgICAgICAgICBzdGFydEJlYXJpbmcgPSB0aGlzLmdldEJlYXJpbmcoKSxcbiAgICAgICAgICAgIHN0YXJ0UGl0Y2ggPSB0aGlzLmdldFBpdGNoKCksXG4gICAgICAgICAgICBzdGFydFBhZGRpbmcgPSB0aGlzLmdldFBhZGRpbmcoKTtcblxuICAgICAgICBjb25zdCB6b29tID0gJ3pvb20nIGluIG9wdGlvbnMgPyBjbGFtcCgrb3B0aW9ucy56b29tLCB0ci5taW5ab29tLCB0ci5tYXhab29tKSA6IHN0YXJ0Wm9vbTtcbiAgICAgICAgY29uc3QgYmVhcmluZyA9ICdiZWFyaW5nJyBpbiBvcHRpb25zID8gdGhpcy5fbm9ybWFsaXplQmVhcmluZyhvcHRpb25zLmJlYXJpbmcsIHN0YXJ0QmVhcmluZykgOiBzdGFydEJlYXJpbmc7XG4gICAgICAgIGNvbnN0IHBpdGNoID0gJ3BpdGNoJyBpbiBvcHRpb25zID8gK29wdGlvbnMucGl0Y2ggOiBzdGFydFBpdGNoO1xuICAgICAgICBjb25zdCBwYWRkaW5nID0gJ3BhZGRpbmcnIGluIG9wdGlvbnMgPyBvcHRpb25zLnBhZGRpbmcgOiB0ci5wYWRkaW5nO1xuXG4gICAgICAgIGNvbnN0IHNjYWxlID0gdHIuem9vbVNjYWxlKHpvb20gLSBzdGFydFpvb20pO1xuICAgICAgICBjb25zdCBvZmZzZXRBc1BvaW50ID0gUG9pbnQuY29udmVydChvcHRpb25zLm9mZnNldCk7XG4gICAgICAgIGxldCBwb2ludEF0T2Zmc2V0ID0gdHIuY2VudGVyUG9pbnQuYWRkKG9mZnNldEFzUG9pbnQpO1xuICAgICAgICBjb25zdCBsb2NhdGlvbkF0T2Zmc2V0ID0gdHIucG9pbnRMb2NhdGlvbihwb2ludEF0T2Zmc2V0KTtcbiAgICAgICAgY29uc3QgY2VudGVyID0gTG5nTGF0LmNvbnZlcnQob3B0aW9ucy5jZW50ZXIgfHwgbG9jYXRpb25BdE9mZnNldCk7XG4gICAgICAgIHRoaXMuX25vcm1hbGl6ZUNlbnRlcihjZW50ZXIpO1xuXG4gICAgICAgIGNvbnN0IGZyb20gPSB0ci5wcm9qZWN0KGxvY2F0aW9uQXRPZmZzZXQpO1xuICAgICAgICBjb25zdCBkZWx0YSA9IHRyLnByb2plY3QoY2VudGVyKS5zdWIoZnJvbSk7XG5cbiAgICAgICAgbGV0IHJobyA9IG9wdGlvbnMuY3VydmU7XG5cbiAgICAgICAgLy8gd+KCgDogSW5pdGlhbCB2aXNpYmxlIHNwYW4sIG1lYXN1cmVkIGluIHBpeGVscyBhdCB0aGUgaW5pdGlhbCBzY2FsZS5cbiAgICAgICAgY29uc3QgdzAgPSBNYXRoLm1heCh0ci53aWR0aCwgdHIuaGVpZ2h0KSxcbiAgICAgICAgICAgIC8vIHfigoE6IEZpbmFsIHZpc2libGUgc3BhbiwgbWVhc3VyZWQgaW4gcGl4ZWxzIHdpdGggcmVzcGVjdCB0byB0aGUgaW5pdGlhbCBzY2FsZS5cbiAgICAgICAgICAgIHcxID0gdzAgLyBzY2FsZSxcbiAgICAgICAgICAgIC8vIExlbmd0aCBvZiB0aGUgZmxpZ2h0IHBhdGggYXMgcHJvamVjdGVkIG9udG8gdGhlIGdyb3VuZCBwbGFuZSwgbWVhc3VyZWQgaW4gcGl4ZWxzIGZyb21cbiAgICAgICAgICAgIC8vIHRoZSB3b3JsZCBpbWFnZSBvcmlnaW4gYXQgdGhlIGluaXRpYWwgc2NhbGUuXG4gICAgICAgICAgICB1MSA9IGRlbHRhLm1hZygpO1xuXG4gICAgICAgIGlmICgnbWluWm9vbScgaW4gb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbWluWm9vbSA9IGNsYW1wKE1hdGgubWluKG9wdGlvbnMubWluWm9vbSwgc3RhcnRab29tLCB6b29tKSwgdHIubWluWm9vbSwgdHIubWF4Wm9vbSk7XG4gICAgICAgICAgICAvLyB3PHN1Yj5tPC9zdWI+OiBNYXhpbXVtIHZpc2libGUgc3BhbiwgbWVhc3VyZWQgaW4gcGl4ZWxzIHdpdGggcmVzcGVjdCB0byB0aGUgaW5pdGlhbFxuICAgICAgICAgICAgLy8gc2NhbGUuXG4gICAgICAgICAgICBjb25zdCB3TWF4ID0gdzAgLyB0ci56b29tU2NhbGUobWluWm9vbSAtIHN0YXJ0Wm9vbSk7XG4gICAgICAgICAgICByaG8gPSBNYXRoLnNxcnQod01heCAvIHUxICogMik7XG4gICAgICAgIH1cblxuICAgICAgICAvLyDPgcKyXG4gICAgICAgIGNvbnN0IHJobzIgPSByaG8gKiByaG87XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIHLhtaI6IFJldHVybnMgdGhlIHpvb20tb3V0IGZhY3RvciBhdCBvbmUgZW5kIG9mIHRoZSBhbmltYXRpb24uXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSBpIDAgZm9yIHRoZSBhc2NlbnQgb3IgMSBmb3IgdGhlIGRlc2NlbnQuXG4gICAgICAgICAqIEBwcml2YXRlXG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiByKGk6IG51bWJlcikge1xuICAgICAgICAgICAgY29uc3QgYiA9ICh3MSAqIHcxIC0gdzAgKiB3MCArIChpID8gLTEgOiAxKSAqIHJobzIgKiByaG8yICogdTEgKiB1MSkgLyAoMiAqIChpID8gdzEgOiB3MCkgKiByaG8yICogdTEpO1xuICAgICAgICAgICAgcmV0dXJuIE1hdGgubG9nKE1hdGguc3FydChiICogYiArIDEpIC0gYik7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBzaW5oKG46IG51bWJlcikgeyByZXR1cm4gKE1hdGguZXhwKG4pIC0gTWF0aC5leHAoLW4pKSAvIDI7IH1cbiAgICAgICAgZnVuY3Rpb24gY29zaChuOiBudW1iZXIpIHsgcmV0dXJuIChNYXRoLmV4cChuKSArIE1hdGguZXhwKC1uKSkgLyAyOyB9XG4gICAgICAgIGZ1bmN0aW9uIHRhbmgobjogbnVtYmVyKSB7IHJldHVybiBzaW5oKG4pIC8gY29zaChuKTsgfVxuXG4gICAgICAgIC8vIHLigoA6IFpvb20tb3V0IGZhY3RvciBkdXJpbmcgYXNjZW50LlxuICAgICAgICBjb25zdCByMCA9IHIoMCk7XG5cbiAgICAgICAgLy8gdyhzKTogUmV0dXJucyB0aGUgdmlzaWJsZSBzcGFuIG9uIHRoZSBncm91bmQsIG1lYXN1cmVkIGluIHBpeGVscyB3aXRoIHJlc3BlY3QgdG8gdGhlXG4gICAgICAgIC8vIGluaXRpYWwgc2NhbGUuIEFzc3VtZXMgYW4gYW5ndWxhciBmaWVsZCBvZiB2aWV3IG9mIDIgYXJjdGFuIMK9IOKJiCA1M8KwLlxuICAgICAgICBsZXQgdzogKF86IG51bWJlcikgPT4gbnVtYmVyID0gZnVuY3Rpb24gKHMpIHtcbiAgICAgICAgICAgIHJldHVybiAoY29zaChyMCkgLyBjb3NoKHIwICsgcmhvICogcykpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIHUocyk6IFJldHVybnMgdGhlIGRpc3RhbmNlIGFsb25nIHRoZSBmbGlnaHQgcGF0aCBhcyBwcm9qZWN0ZWQgb250byB0aGUgZ3JvdW5kIHBsYW5lLFxuICAgICAgICAvLyBtZWFzdXJlZCBpbiBwaXhlbHMgZnJvbSB0aGUgd29ybGQgaW1hZ2Ugb3JpZ2luIGF0IHRoZSBpbml0aWFsIHNjYWxlLlxuICAgICAgICBsZXQgdTogKF86IG51bWJlcikgPT4gbnVtYmVyID0gZnVuY3Rpb24gKHMpIHtcbiAgICAgICAgICAgIHJldHVybiB3MCAqICgoY29zaChyMCkgKiB0YW5oKHIwICsgcmhvICogcykgLSBzaW5oKHIwKSkgLyByaG8yKSAvIHUxO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFM6IFRvdGFsIGxlbmd0aCBvZiB0aGUgZmxpZ2h0IHBhdGgsIG1lYXN1cmVkIGluIM+BLXNjcmVlbmZ1bHMuXG4gICAgICAgIGxldCBTID0gKHIoMSkgLSByMCkgLyByaG87XG5cbiAgICAgICAgLy8gV2hlbiB14oKAID0gdeKCgSwgdGhlIG9wdGltYWwgcGF0aCBkb2VzbuKAmXQgcmVxdWlyZSBib3RoIGFzY2VudCBhbmQgZGVzY2VudC5cbiAgICAgICAgaWYgKE1hdGguYWJzKHUxKSA8IDAuMDAwMDAxIHx8ICFpc0Zpbml0ZShTKSkge1xuICAgICAgICAgICAgLy8gUGVyZm9ybSBhIG1vcmUgb3IgbGVzcyBpbnN0YW50YW5lb3VzIHRyYW5zaXRpb24gaWYgdGhlIHBhdGggaXMgdG9vIHNob3J0LlxuICAgICAgICAgICAgaWYgKE1hdGguYWJzKHcwIC0gdzEpIDwgMC4wMDAwMDEpIHJldHVybiB0aGlzLmVhc2VUbyhvcHRpb25zLCBldmVudERhdGEpO1xuXG4gICAgICAgICAgICBjb25zdCBrID0gdzEgPCB3MCA/IC0xIDogMTtcbiAgICAgICAgICAgIFMgPSBNYXRoLmFicyhNYXRoLmxvZyh3MSAvIHcwKSkgLyByaG87XG5cbiAgICAgICAgICAgIHUgPSBmdW5jdGlvbigpIHsgcmV0dXJuIDA7IH07XG4gICAgICAgICAgICB3ID0gZnVuY3Rpb24ocykgeyByZXR1cm4gTWF0aC5leHAoayAqIHJobyAqIHMpOyB9O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCdkdXJhdGlvbicgaW4gb3B0aW9ucykge1xuICAgICAgICAgICAgb3B0aW9ucy5kdXJhdGlvbiA9ICtvcHRpb25zLmR1cmF0aW9uO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgViA9ICdzY3JlZW5TcGVlZCcgaW4gb3B0aW9ucyA/ICtvcHRpb25zLnNjcmVlblNwZWVkIC8gcmhvIDogK29wdGlvbnMuc3BlZWQ7XG4gICAgICAgICAgICBvcHRpb25zLmR1cmF0aW9uID0gMTAwMCAqIFMgLyBWO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG9wdGlvbnMubWF4RHVyYXRpb24gJiYgb3B0aW9ucy5kdXJhdGlvbiA+IG9wdGlvbnMubWF4RHVyYXRpb24pIHtcbiAgICAgICAgICAgIG9wdGlvbnMuZHVyYXRpb24gPSAwO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgem9vbUNoYW5nZWQgPSB0cnVlO1xuICAgICAgICBjb25zdCBiZWFyaW5nQ2hhbmdlZCA9IChzdGFydEJlYXJpbmcgIT09IGJlYXJpbmcpO1xuICAgICAgICBjb25zdCBwaXRjaENoYW5nZWQgPSAocGl0Y2ggIT09IHN0YXJ0UGl0Y2gpO1xuICAgICAgICBjb25zdCBwYWRkaW5nQ2hhbmdlZCA9ICF0ci5pc1BhZGRpbmdFcXVhbChwYWRkaW5nKTtcblxuICAgICAgICBjb25zdCBmcmFtZSA9ICh0cjogVHJhbnNmb3JtKSA9PiAoazogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICAvLyBzOiBUaGUgZGlzdGFuY2UgdHJhdmVsZWQgYWxvbmcgdGhlIGZsaWdodCBwYXRoLCBtZWFzdXJlZCBpbiDPgS1zY3JlZW5mdWxzLlxuICAgICAgICAgICAgY29uc3QgcyA9IGsgKiBTO1xuICAgICAgICAgICAgY29uc3Qgc2NhbGUgPSAxIC8gdyhzKTtcbiAgICAgICAgICAgIHRyLnpvb20gPSBrID09PSAxID8gem9vbSA6IHN0YXJ0Wm9vbSArIHRyLnNjYWxlWm9vbShzY2FsZSk7XG5cbiAgICAgICAgICAgIGlmIChiZWFyaW5nQ2hhbmdlZCkge1xuICAgICAgICAgICAgICAgIHRyLmJlYXJpbmcgPSBpbnRlcnBvbGF0ZShzdGFydEJlYXJpbmcsIGJlYXJpbmcsIGspO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHBpdGNoQ2hhbmdlZCkge1xuICAgICAgICAgICAgICAgIHRyLnBpdGNoID0gaW50ZXJwb2xhdGUoc3RhcnRQaXRjaCwgcGl0Y2gsIGspO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHBhZGRpbmdDaGFuZ2VkKSB7XG4gICAgICAgICAgICAgICAgdHIuaW50ZXJwb2xhdGVQYWRkaW5nKHN0YXJ0UGFkZGluZywgcGFkZGluZywgayk7XG4gICAgICAgICAgICAgICAgLy8gV2hlbiBwYWRkaW5nIGlzIGJlaW5nIGFwcGxpZWQsIFRyYW5zZm9ybSNjZW50ZXJQb2ludCBpcyBjaGFuZ2luZyBjb250aW51b3VzbHksXG4gICAgICAgICAgICAgICAgLy8gdGh1cyB3ZSBuZWVkIHRvIHJlY2FsY3VsYXRlIG9mZnNldFBvaW50IGV2ZXJ5IGZyYW1lXG4gICAgICAgICAgICAgICAgcG9pbnRBdE9mZnNldCA9IHRyLmNlbnRlclBvaW50LmFkZChvZmZzZXRBc1BvaW50KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgbmV3Q2VudGVyID0gayA9PT0gMSA/IGNlbnRlciA6IHRyLnVucHJvamVjdChmcm9tLmFkZChkZWx0YS5tdWx0KHUocykpKS5tdWx0KHNjYWxlKSk7XG4gICAgICAgICAgICB0ci5zZXRMb2NhdGlvbkF0UG9pbnQodHIucmVuZGVyV29ybGRDb3BpZXMgPyBuZXdDZW50ZXIud3JhcCgpIDogbmV3Q2VudGVyLCBwb2ludEF0T2Zmc2V0KTtcbiAgICAgICAgICAgIHRyLl91cGRhdGVDYW1lcmFPblRlcnJhaW4oKTtcblxuICAgICAgICAgICAgaWYgKCFvcHRpb25zLnByZWxvYWRPbmx5KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZmlyZU1vdmVFdmVudHMoZXZlbnREYXRhKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRyO1xuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChvcHRpb25zLnByZWxvYWRPbmx5KSB7XG4gICAgICAgICAgICBjb25zdCBwcmVkaWN0ZWRUcmFuc2Zvcm1zID0gdGhpcy5fZW11bGF0ZShmcmFtZSwgb3B0aW9ucy5kdXJhdGlvbiwgdHIpO1xuICAgICAgICAgICAgdGhpcy5fcHJlbG9hZFRpbGVzKHByZWRpY3RlZFRyYW5zZm9ybXMpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl96b29taW5nID0gem9vbUNoYW5nZWQ7XG4gICAgICAgIHRoaXMuX3JvdGF0aW5nID0gYmVhcmluZ0NoYW5nZWQ7XG4gICAgICAgIHRoaXMuX3BpdGNoaW5nID0gcGl0Y2hDaGFuZ2VkO1xuICAgICAgICB0aGlzLl9wYWRkaW5nID0gcGFkZGluZ0NoYW5nZWQ7XG5cbiAgICAgICAgdGhpcy5fcHJlcGFyZUVhc2UoZXZlbnREYXRhLCBmYWxzZSk7XG4gICAgICAgIHRoaXMuX2Vhc2UoZnJhbWUodHIpLCAoKSA9PiB0aGlzLl9hZnRlckVhc2UoZXZlbnREYXRhKSwgb3B0aW9ucyk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgaXNFYXNpbmcoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX2Vhc2VGcmFtZUlkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN0b3BzIGFueSBhbmltYXRlZCB0cmFuc2l0aW9uIHVuZGVyd2F5LlxuICAgICAqXG4gICAgICogQG1lbWJlcm9mIE1hcCNcbiAgICAgKiBAcmV0dXJucyB7TWFwfSBSZXR1cm5zIGl0c2VsZiB0byBhbGxvdyBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogbWFwLnN0b3AoKTtcbiAgICAgKi9cbiAgICBzdG9wKCk6IHRoaXMge1xuICAgICAgICByZXR1cm4gdGhpcy5fc3RvcCgpO1xuICAgIH1cblxuICAgIF9zdG9wKGFsbG93R2VzdHVyZXM/OiBib29sZWFuLCBlYXNlSWQ/OiBzdHJpbmcpOiB0aGlzIHtcbiAgICAgICAgaWYgKHRoaXMuX2Vhc2VGcmFtZUlkKSB7XG4gICAgICAgICAgICB0aGlzLl9jYW5jZWxSZW5kZXJGcmFtZSh0aGlzLl9lYXNlRnJhbWVJZCk7XG4gICAgICAgICAgICB0aGlzLl9lYXNlRnJhbWVJZCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHRoaXMuX29uRWFzZUZyYW1lID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuX29uRWFzZUVuZCkge1xuICAgICAgICAgICAgLy8gVGhlIF9vbkVhc2VFbmQgZnVuY3Rpb24gbWlnaHQgZW1pdCBldmVudHMgd2hpY2ggdHJpZ2dlciBuZXdcbiAgICAgICAgICAgIC8vIGFuaW1hdGlvbiwgd2hpY2ggc2V0cyBhIG5ldyBfb25FYXNlRW5kLiBFbnN1cmUgd2UgZG9uJ3QgZGVsZXRlXG4gICAgICAgICAgICAvLyBpdCB1bmludGVudGlvbmFsbHkuXG4gICAgICAgICAgICBjb25zdCBvbkVhc2VFbmQgPSB0aGlzLl9vbkVhc2VFbmQ7XG4gICAgICAgICAgICB0aGlzLl9vbkVhc2VFbmQgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICBvbkVhc2VFbmQuY2FsbCh0aGlzLCBlYXNlSWQpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghYWxsb3dHZXN0dXJlcykge1xuICAgICAgICAgICAgY29uc3QgaGFuZGxlcnMgPSAodGhpczogYW55KS5oYW5kbGVycztcbiAgICAgICAgICAgIGlmIChoYW5kbGVycykgaGFuZGxlcnMuc3RvcChmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgX2Vhc2UoZnJhbWU6IChfOiBudW1iZXIpID0+IFRyYW5zZm9ybSB8IHZvaWQsXG4gICAgICAgICAgZmluaXNoOiAoKSA9PiB2b2lkLFxuICAgICAgICAgIG9wdGlvbnM6IHthbmltYXRlOiBib29sZWFuLCBkdXJhdGlvbjogbnVtYmVyLCBlYXNpbmc6IChfOiBudW1iZXIpID0+IG51bWJlcn0pIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuYW5pbWF0ZSA9PT0gZmFsc2UgfHwgb3B0aW9ucy5kdXJhdGlvbiA9PT0gMCkge1xuICAgICAgICAgICAgZnJhbWUoMSk7XG4gICAgICAgICAgICBmaW5pc2goKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2Vhc2VTdGFydCA9IGJyb3dzZXIubm93KCk7XG4gICAgICAgICAgICB0aGlzLl9lYXNlT3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgICAgICAgICB0aGlzLl9vbkVhc2VGcmFtZSA9IGZyYW1lO1xuICAgICAgICAgICAgdGhpcy5fb25FYXNlRW5kID0gZmluaXNoO1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgdGhpcy5fZWFzZUZyYW1lSWQgPSB0aGlzLl9yZXF1ZXN0UmVuZGVyRnJhbWUodGhpcy5fcmVuZGVyRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDYWxsYmFjayBmb3IgbWFwLl9yZXF1ZXN0UmVuZGVyRnJhbWVcbiAgICBfcmVuZGVyRnJhbWVDYWxsYmFjaygpIHtcbiAgICAgICAgY29uc3QgdCA9IE1hdGgubWluKChicm93c2VyLm5vdygpIC0gdGhpcy5fZWFzZVN0YXJ0KSAvIHRoaXMuX2Vhc2VPcHRpb25zLmR1cmF0aW9uLCAxKTtcbiAgICAgICAgY29uc3QgZnJhbWUgPSB0aGlzLl9vbkVhc2VGcmFtZTtcbiAgICAgICAgaWYgKGZyYW1lKSBmcmFtZSh0aGlzLl9lYXNlT3B0aW9ucy5lYXNpbmcodCkpO1xuICAgICAgICBpZiAodCA8IDEpIHtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIHRoaXMuX2Vhc2VGcmFtZUlkID0gdGhpcy5fcmVxdWVzdFJlbmRlckZyYW1lKHRoaXMuX3JlbmRlckZyYW1lQ2FsbGJhY2spO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zdG9wKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBjb252ZXJ0IGJlYXJpbmcgc28gdGhhdCBpdCdzIG51bWVyaWNhbGx5IGNsb3NlIHRvIHRoZSBjdXJyZW50IG9uZSBzbyB0aGF0IGl0IGludGVycG9sYXRlcyBwcm9wZXJseVxuICAgIF9ub3JtYWxpemVCZWFyaW5nKGJlYXJpbmc6IG51bWJlciwgY3VycmVudEJlYXJpbmc6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGJlYXJpbmcgPSB3cmFwKGJlYXJpbmcsIC0xODAsIDE4MCk7XG4gICAgICAgIGNvbnN0IGRpZmYgPSBNYXRoLmFicyhiZWFyaW5nIC0gY3VycmVudEJlYXJpbmcpO1xuICAgICAgICBpZiAoTWF0aC5hYnMoYmVhcmluZyAtIDM2MCAtIGN1cnJlbnRCZWFyaW5nKSA8IGRpZmYpIGJlYXJpbmcgLT0gMzYwO1xuICAgICAgICBpZiAoTWF0aC5hYnMoYmVhcmluZyArIDM2MCAtIGN1cnJlbnRCZWFyaW5nKSA8IGRpZmYpIGJlYXJpbmcgKz0gMzYwO1xuICAgICAgICByZXR1cm4gYmVhcmluZztcbiAgICB9XG5cbiAgICAvLyBJZiBhIHBhdGggY3Jvc3NpbmcgdGhlIGFudGltZXJpZGlhbiB3b3VsZCBiZSBzaG9ydGVyLCBleHRlbmQgdGhlIGZpbmFsIGNvb3JkaW5hdGUgc28gdGhhdFxuICAgIC8vIGludGVycG9sYXRpbmcgYmV0d2VlbiB0aGUgdHdvIGVuZHBvaW50cyB3aWxsIGNyb3NzIGl0LlxuICAgIF9ub3JtYWxpemVDZW50ZXIoY2VudGVyOiBMbmdMYXQpIHtcbiAgICAgICAgY29uc3QgdHIgPSB0aGlzLnRyYW5zZm9ybTtcbiAgICAgICAgaWYgKCF0ci5yZW5kZXJXb3JsZENvcGllcyB8fCB0ci5tYXhCb3VuZHMpIHJldHVybjtcblxuICAgICAgICBjb25zdCBkZWx0YSA9IGNlbnRlci5sbmcgLSB0ci5jZW50ZXIubG5nO1xuICAgICAgICBjZW50ZXIubG5nICs9XG4gICAgICAgICAgICBkZWx0YSA+IDE4MCA/IC0zNjAgOlxuICAgICAgICAgICAgZGVsdGEgPCAtMTgwID8gMzYwIDogMDtcbiAgICB9XG5cbiAgICBfcHJlZmVyc1JlZHVjZWRNb3Rpb24ob3B0aW9uczogP0FuaW1hdGlvbk9wdGlvbnMpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgZXNzZW50aWFsID0gb3B0aW9ucyAmJiBvcHRpb25zLmVzc2VudGlhbDtcbiAgICAgICAgY29uc3QgcHJlZmVyc1JlZHVjZWRNb3Rpb24gPSB0aGlzLl9yZXNwZWN0UHJlZmVyc1JlZHVjZWRNb3Rpb24gJiYgYnJvd3Nlci5wcmVmZXJzUmVkdWNlZE1vdGlvbjtcbiAgICAgICAgcmV0dXJuIHByZWZlcnNSZWR1Y2VkTW90aW9uICYmICFlc3NlbnRpYWw7XG4gICAgfVxuXG4gICAgLy8gZW11bGF0ZXMgZnJhbWUgZnVuY3Rpb24gZm9yIHNvbWUgdHJhbnNmb3JtXG4gICAgX2VtdWxhdGUoZnJhbWU6IEZ1bmN0aW9uLCBkdXJhdGlvbjogbnVtYmVyLCBpbml0aWFsVHJhbnNmb3JtOiBUcmFuc2Zvcm0pOiBBcnJheTxUcmFuc2Zvcm0+IHtcbiAgICAgICAgY29uc3QgZnJhbWVSYXRlID0gMTU7XG4gICAgICAgIGNvbnN0IG51bUZyYW1lcyA9IE1hdGguY2VpbChkdXJhdGlvbiAqIGZyYW1lUmF0ZSAvIDEwMDApO1xuXG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybXMgPSBbXTtcbiAgICAgICAgY29uc3QgZW11bGF0ZUZyYW1lID0gZnJhbWUoaW5pdGlhbFRyYW5zZm9ybS5jbG9uZSgpKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPD0gbnVtRnJhbWVzOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IGVtdWxhdGVGcmFtZShpIC8gbnVtRnJhbWVzKTtcbiAgICAgICAgICAgIHRyYW5zZm9ybXMucHVzaCh0cmFuc2Zvcm0uY2xvbmUoKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJhbnNmb3JtcztcbiAgICB9XG59XG5cbi8vIEluIGRlYnVnIGJ1aWxkcywgY2hlY2sgdGhhdCBjYW1lcmEgY2hhbmdlIGV2ZW50cyBhcmUgZmlyZWQgaW4gdGhlIGNvcnJlY3Qgb3JkZXIuXG4vLyAtIF9fX3N0YXJ0IGV2ZW50cyBuZWVkcyB0byBiZSBmaXJlZCBiZWZvcmUgX19fIGFuZCBfX19lbmQgZXZlbnRzXG4vLyAtIGFub3RoZXIgX19fc3RhcnQgZXZlbnQgY2FuJ3QgYmUgZmlyZWQgYmVmb3JlIGEgX19fZW5kIGV2ZW50IGhhcyBiZWVuIGZpcmVkIGZvciB0aGUgcHJldmlvdXMgb25lXG5mdW5jdGlvbiBhZGRBc3NlcnRpb25zKGNhbWVyYTogQ2FtZXJhKSB7IC8vZXNsaW50LWRpc2FibGUtbGluZVxuICAgIERlYnVnLnJ1bigoKSA9PiB7XG4gICAgICAgIGNvbnN0IGluUHJvZ3Jlc3MgPSB7fTtcblxuICAgICAgICBbJ2RyYWcnLCAnem9vbScsICdyb3RhdGUnLCAncGl0Y2gnLCAnbW92ZSddLmZvckVhY2gobmFtZSA9PiB7XG4gICAgICAgICAgICBpblByb2dyZXNzW25hbWVdID0gZmFsc2U7XG5cbiAgICAgICAgICAgIGNhbWVyYS5vbigoKGAke25hbWV9c3RhcnRgOiBhbnkpOiBNYXBFdmVudCksICgpID0+IHtcbiAgICAgICAgICAgICAgICBhc3NlcnQoIWluUHJvZ3Jlc3NbbmFtZV0sIGBcIiR7bmFtZX1zdGFydFwiIGZpcmVkIHR3aWNlIHdpdGhvdXQgYSBcIiR7bmFtZX1lbmRcImApO1xuICAgICAgICAgICAgICAgIGluUHJvZ3Jlc3NbbmFtZV0gPSB0cnVlO1xuICAgICAgICAgICAgICAgIGFzc2VydChpblByb2dyZXNzLm1vdmUpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNhbWVyYS5vbihuYW1lLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgYXNzZXJ0KGluUHJvZ3Jlc3NbbmFtZV0pO1xuICAgICAgICAgICAgICAgIGFzc2VydChpblByb2dyZXNzLm1vdmUpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNhbWVyYS5vbigoKGAke25hbWV9ZW5kYDogYW55KTogTWFwRXZlbnQpLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgYXNzZXJ0KGluUHJvZ3Jlc3MubW92ZSk7XG4gICAgICAgICAgICAgICAgYXNzZXJ0KGluUHJvZ3Jlc3NbbmFtZV0pO1xuICAgICAgICAgICAgICAgIGluUHJvZ3Jlc3NbbmFtZV0gPSBmYWxzZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBDYW5hcnkgdXNlZCB0byB0ZXN0IHdoZXRoZXIgdGhpcyBmdW5jdGlvbiBpcyBzdHJpcHBlZCBpbiBwcm9kIGJ1aWxkXG4gICAgICAgIGNhbmFyeSA9ICdjYW5hcnkgZGVidWcgcnVuJzsgLy9lc2xpbnQtZGlzYWJsZS1saW5lXG4gICAgfSk7XG59XG5cbmxldCBjYW5hcnk7IC8vZXNsaW50LWRpc2FibGUtbGluZVxuXG5leHBvcnQgZGVmYXVsdCBDYW1lcmE7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgKiBhcyBET00gZnJvbSAnLi4vLi4vdXRpbC9kb20uanMnO1xuaW1wb3J0IHtiaW5kQWxsfSBmcm9tICcuLi8uLi91dGlsL3V0aWwuanMnO1xuaW1wb3J0IGNvbmZpZyBmcm9tICcuLi8uLi91dGlsL2NvbmZpZy5qcyc7XG5pbXBvcnQge2dldEhhc2hTdHJpbmd9IGZyb20gJy4uL2hhc2guanMnO1xuXG5pbXBvcnQgdHlwZSBNYXAsIHtDb250cm9sUG9zaXRpb259IGZyb20gJy4uL21hcC5qcyc7XG5cbnR5cGUgT3B0aW9ucyA9IHtcbiAgICBjb21wYWN0PzogYm9vbGVhbixcbiAgICBjdXN0b21BdHRyaWJ1dGlvbj86IHN0cmluZyB8IEFycmF5PHN0cmluZz5cbn07XG5cbi8qKlxuICogQW4gYEF0dHJpYnV0aW9uQ29udHJvbGAgY29udHJvbCBwcmVzZW50cyB0aGUgbWFwJ3MgW2F0dHJpYnV0aW9uIGluZm9ybWF0aW9uXShodHRwczovL2RvY3MubWFwYm94LmNvbS9oZWxwL2hvdy1tYXBib3gtd29ya3MvYXR0cmlidXRpb24vKS5cbiAqIEFkZCB0aGlzIGNvbnRyb2wgdG8gYSBtYXAgdXNpbmcge0BsaW5rIE1hcCNhZGRDb250cm9sfS5cbiAqXG4gKiBAaW1wbGVtZW50cyB7SUNvbnRyb2x9XG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmNvbXBhY3RdIElmIGB0cnVlYCwgZm9yY2UgYSBjb21wYWN0IGF0dHJpYnV0aW9uIHRoYXQgc2hvd3MgdGhlIGZ1bGwgYXR0cmlidXRpb24gb24gbW91c2UgaG92ZXIuIElmIGBmYWxzZWAsIGZvcmNlIHRoZSBmdWxsIGF0dHJpYnV0aW9uIGNvbnRyb2wuIFRoZSBkZWZhdWx0IGlzIGEgcmVzcG9uc2l2ZSBhdHRyaWJ1dGlvbiB0aGF0IGNvbGxhcHNlcyB3aGVuIHRoZSBtYXAgaXMgbGVzcyB0aGFuIDY0MCBwaXhlbHMgd2lkZS4gKipBdHRyaWJ1dGlvbiBzaG91bGQgbm90IGJlIGNvbGxhcHNlZCBpZiBpdCBjYW4gY29tZm9ydGFibHkgZml0IG9uIHRoZSBtYXAuIGBjb21wYWN0YCBzaG91bGQgb25seSBiZSB1c2VkIHRvIG1vZGlmeSBkZWZhdWx0IGF0dHJpYnV0aW9uIHdoZW4gbWFwIHNpemUgbWFrZXMgaXQgaW1wb3NzaWJsZSB0byBmaXQgW2RlZmF1bHQgYXR0cmlidXRpb25dKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL2hlbHAvaG93LW1hcGJveC13b3Jrcy9hdHRyaWJ1dGlvbi8pIGFuZCB3aGVuIHRoZSBhdXRvbWF0aWMgY29tcGFjdCByZXNpemluZyBmb3IgZGVmYXVsdCBzZXR0aW5ncyBhcmUgbm90IHN1ZmZpY2llbnQqKi5cbiAqIEBwYXJhbSB7c3RyaW5nIHwgQXJyYXk8c3RyaW5nPn0gW29wdGlvbnMuY3VzdG9tQXR0cmlidXRpb25dIFN0cmluZyBvciBzdHJpbmdzIHRvIHNob3cgaW4gYWRkaXRpb24gdG8gYW55IG90aGVyIGF0dHJpYnV0aW9ucy4gWW91IGNhbiBhbHNvIHNldCBhIGN1c3RvbSBhdHRyaWJ1dGlvbiB3aGVuIGluaXRpYWxpemluZyB5b3VyIG1hcCB3aXRoIHtAbGluayBodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvYXBpL21hcC8jbWFwLXBhcmFtZXRlcnMgdGhlIGN1c3RvbUF0dHJpYnV0aW9uIG9wdGlvbn0uXG4gKiBAZXhhbXBsZVxuICogY29uc3QgbWFwID0gbmV3IG1hcGJveGdsLk1hcCh7YXR0cmlidXRpb25Db250cm9sOiBmYWxzZX0pXG4gKiAgICAgLmFkZENvbnRyb2wobmV3IG1hcGJveGdsLkF0dHJpYnV0aW9uQ29udHJvbCh7XG4gKiAgICAgICAgIGN1c3RvbUF0dHJpYnV0aW9uOiAnTWFwIGRlc2lnbiBieSBtZSdcbiAqICAgICB9KSk7XG4gKi9cbmNsYXNzIEF0dHJpYnV0aW9uQ29udHJvbCB7XG4gICAgb3B0aW9uczogT3B0aW9ucztcbiAgICBfbWFwOiBNYXA7XG4gICAgX2NvbnRhaW5lcjogSFRNTEVsZW1lbnQ7XG4gICAgX2lubmVyQ29udGFpbmVyOiBIVE1MRWxlbWVudDtcbiAgICBfY29tcGFjdEJ1dHRvbjogSFRNTEJ1dHRvbkVsZW1lbnQ7XG4gICAgX2VkaXRMaW5rOiA/SFRNTEFuY2hvckVsZW1lbnQ7XG4gICAgX2F0dHJpYkhUTUw6IHN0cmluZztcbiAgICBzdHlsZUlkOiBzdHJpbmc7XG4gICAgc3R5bGVPd25lcjogc3RyaW5nO1xuXG4gICAgY29uc3RydWN0b3Iob3B0aW9uczogT3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG5cbiAgICAgICAgYmluZEFsbChbXG4gICAgICAgICAgICAnX3RvZ2dsZUF0dHJpYnV0aW9uJyxcbiAgICAgICAgICAgICdfdXBkYXRlRWRpdExpbmsnLFxuICAgICAgICAgICAgJ191cGRhdGVEYXRhJyxcbiAgICAgICAgICAgICdfdXBkYXRlQ29tcGFjdCdcbiAgICAgICAgXSwgdGhpcyk7XG4gICAgfVxuXG4gICAgZ2V0RGVmYXVsdFBvc2l0aW9uKCk6IENvbnRyb2xQb3NpdGlvbiB7XG4gICAgICAgIHJldHVybiAnYm90dG9tLXJpZ2h0JztcbiAgICB9XG5cbiAgICBvbkFkZChtYXA6IE1hcCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgY29uc3QgY29tcGFjdCA9IHRoaXMub3B0aW9ucyAmJiB0aGlzLm9wdGlvbnMuY29tcGFjdDtcblxuICAgICAgICB0aGlzLl9tYXAgPSBtYXA7XG4gICAgICAgIHRoaXMuX2NvbnRhaW5lciA9IERPTS5jcmVhdGUoJ2RpdicsICdtYXBib3hnbC1jdHJsIG1hcGJveGdsLWN0cmwtYXR0cmliJyk7XG4gICAgICAgIHRoaXMuX2NvbXBhY3RCdXR0b24gPSBET00uY3JlYXRlKCdidXR0b24nLCAnbWFwYm94Z2wtY3RybC1hdHRyaWItYnV0dG9uJywgdGhpcy5fY29udGFpbmVyKTtcbiAgICAgICAgRE9NLmNyZWF0ZSgnc3BhbicsIGBtYXBib3hnbC1jdHJsLWljb25gLCB0aGlzLl9jb21wYWN0QnV0dG9uKS5zZXRBdHRyaWJ1dGUoJ2FyaWEtaGlkZGVuJywgJ3RydWUnKTtcbiAgICAgICAgdGhpcy5fY29tcGFjdEJ1dHRvbi50eXBlID0gJ2J1dHRvbic7XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgdGhpcy5fY29tcGFjdEJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuX3RvZ2dsZUF0dHJpYnV0aW9uKTtcbiAgICAgICAgdGhpcy5fc2V0RWxlbWVudFRpdGxlKHRoaXMuX2NvbXBhY3RCdXR0b24sICdUb2dnbGVBdHRyaWJ1dGlvbicpO1xuICAgICAgICB0aGlzLl9pbm5lckNvbnRhaW5lciA9IERPTS5jcmVhdGUoJ2RpdicsICdtYXBib3hnbC1jdHJsLWF0dHJpYi1pbm5lcicsIHRoaXMuX2NvbnRhaW5lcik7XG4gICAgICAgIHRoaXMuX2lubmVyQ29udGFpbmVyLnNldEF0dHJpYnV0ZSgncm9sZScsICdsaXN0Jyk7XG5cbiAgICAgICAgaWYgKGNvbXBhY3QpIHtcbiAgICAgICAgICAgIHRoaXMuX2NvbnRhaW5lci5jbGFzc0xpc3QuYWRkKCdtYXBib3hnbC1jb21wYWN0Jyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl91cGRhdGVBdHRyaWJ1dGlvbnMoKTtcbiAgICAgICAgdGhpcy5fdXBkYXRlRWRpdExpbmsoKTtcblxuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIHRoaXMuX21hcC5vbignc3R5bGVkYXRhJywgdGhpcy5fdXBkYXRlRGF0YSk7XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgdGhpcy5fbWFwLm9uKCdzb3VyY2VkYXRhJywgdGhpcy5fdXBkYXRlRGF0YSk7XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgdGhpcy5fbWFwLm9uKCdtb3ZlZW5kJywgdGhpcy5fdXBkYXRlRWRpdExpbmspO1xuXG4gICAgICAgIGlmIChjb21wYWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIHRoaXMuX21hcC5vbigncmVzaXplJywgdGhpcy5fdXBkYXRlQ29tcGFjdCk7XG4gICAgICAgICAgICB0aGlzLl91cGRhdGVDb21wYWN0KCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5fY29udGFpbmVyO1xuICAgIH1cblxuICAgIG9uUmVtb3ZlKCkge1xuICAgICAgICB0aGlzLl9jb250YWluZXIucmVtb3ZlKCk7XG5cbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICB0aGlzLl9tYXAub2ZmKCdzdHlsZWRhdGEnLCB0aGlzLl91cGRhdGVEYXRhKTtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICB0aGlzLl9tYXAub2ZmKCdzb3VyY2VkYXRhJywgdGhpcy5fdXBkYXRlRGF0YSk7XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgdGhpcy5fbWFwLm9mZignbW92ZWVuZCcsIHRoaXMuX3VwZGF0ZUVkaXRMaW5rKTtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICB0aGlzLl9tYXAub2ZmKCdyZXNpemUnLCB0aGlzLl91cGRhdGVDb21wYWN0KTtcblxuICAgICAgICB0aGlzLl9tYXAgPSAodW5kZWZpbmVkOiBhbnkpO1xuICAgICAgICB0aGlzLl9hdHRyaWJIVE1MID0gKHVuZGVmaW5lZDogYW55KTtcbiAgICB9XG5cbiAgICBfc2V0RWxlbWVudFRpdGxlKGVsZW1lbnQ6IEhUTUxFbGVtZW50LCB0aXRsZTogc3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IHN0ciA9IHRoaXMuX21hcC5fZ2V0VUlTdHJpbmcoYEF0dHJpYnV0aW9uQ29udHJvbC4ke3RpdGxlfWApO1xuICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnYXJpYS1sYWJlbCcsIHN0cik7XG4gICAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKCd0aXRsZScpO1xuICAgICAgICBpZiAoZWxlbWVudC5maXJzdEVsZW1lbnRDaGlsZCkgZWxlbWVudC5maXJzdEVsZW1lbnRDaGlsZC5zZXRBdHRyaWJ1dGUoJ3RpdGxlJywgc3RyKTtcbiAgICB9XG5cbiAgICBfdG9nZ2xlQXR0cmlidXRpb24oKSB7XG4gICAgICAgIGlmICh0aGlzLl9jb250YWluZXIuY2xhc3NMaXN0LmNvbnRhaW5zKCdtYXBib3hnbC1jb21wYWN0LXNob3cnKSkge1xuICAgICAgICAgICAgdGhpcy5fY29udGFpbmVyLmNsYXNzTGlzdC5yZW1vdmUoJ21hcGJveGdsLWNvbXBhY3Qtc2hvdycpO1xuICAgICAgICAgICAgdGhpcy5fY29tcGFjdEJ1dHRvbi5zZXRBdHRyaWJ1dGUoJ2FyaWEtZXhwYW5kZWQnLCAnZmFsc2UnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2NvbnRhaW5lci5jbGFzc0xpc3QuYWRkKCdtYXBib3hnbC1jb21wYWN0LXNob3cnKTtcbiAgICAgICAgICAgIHRoaXMuX2NvbXBhY3RCdXR0b24uc2V0QXR0cmlidXRlKCdhcmlhLWV4cGFuZGVkJywgJ3RydWUnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF91cGRhdGVFZGl0TGluaygpIHtcbiAgICAgICAgbGV0IGVkaXRMaW5rID0gdGhpcy5fZWRpdExpbms7XG4gICAgICAgIGlmICghZWRpdExpbmspIHtcbiAgICAgICAgICAgIGVkaXRMaW5rID0gdGhpcy5fZWRpdExpbmsgPSAodGhpcy5fY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJy5tYXBib3gtaW1wcm92ZS1tYXAnKTogYW55KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IFtcbiAgICAgICAgICAgIHtrZXk6ICdvd25lcicsIHZhbHVlOiB0aGlzLnN0eWxlT3duZXJ9LFxuICAgICAgICAgICAge2tleTogJ2lkJywgdmFsdWU6IHRoaXMuc3R5bGVJZH0sXG4gICAgICAgICAgICB7a2V5OiAnYWNjZXNzX3Rva2VuJywgdmFsdWU6IHRoaXMuX21hcC5fcmVxdWVzdE1hbmFnZXIuX2N1c3RvbUFjY2Vzc1Rva2VuIHx8IGNvbmZpZy5BQ0NFU1NfVE9LRU59XG4gICAgICAgIF07XG5cbiAgICAgICAgaWYgKGVkaXRMaW5rKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJhbVN0cmluZyA9IHBhcmFtcy5yZWR1Y2UoKGFjYywgbmV4dCwgaSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChuZXh0LnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIGFjYyArPSBgJHtuZXh0LmtleX09JHtuZXh0LnZhbHVlfSR7aSA8IHBhcmFtcy5sZW5ndGggLSAxID8gJyYnIDogJyd9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgICAgICAgIH0sIGA/YCk7XG4gICAgICAgICAgICBlZGl0TGluay5ocmVmID0gYCR7Y29uZmlnLkZFRURCQUNLX1VSTH0vJHtwYXJhbVN0cmluZ30jJHtnZXRIYXNoU3RyaW5nKHRoaXMuX21hcCwgdHJ1ZSl9YDtcbiAgICAgICAgICAgIGVkaXRMaW5rLnJlbCA9ICdub29wZW5lciBub2ZvbGxvdyc7XG4gICAgICAgICAgICB0aGlzLl9zZXRFbGVtZW50VGl0bGUoZWRpdExpbmssICdNYXBGZWVkYmFjaycpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX3VwZGF0ZURhdGEoZTogYW55KSB7XG4gICAgICAgIGlmIChlICYmIChlLnNvdXJjZURhdGFUeXBlID09PSAnbWV0YWRhdGEnIHx8IGUuc291cmNlRGF0YVR5cGUgPT09ICd2aXNpYmlsaXR5JyB8fCBlLmRhdGFUeXBlID09PSAnc3R5bGUnKSkge1xuICAgICAgICAgICAgdGhpcy5fdXBkYXRlQXR0cmlidXRpb25zKCk7XG4gICAgICAgICAgICB0aGlzLl91cGRhdGVFZGl0TGluaygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX3VwZGF0ZUF0dHJpYnV0aW9ucygpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9tYXAuc3R5bGUpIHJldHVybjtcbiAgICAgICAgbGV0IGF0dHJpYnV0aW9uczogQXJyYXk8c3RyaW5nPiA9IFtdO1xuXG4gICAgICAgIGlmICh0aGlzLl9tYXAuc3R5bGUuc3R5bGVzaGVldCkge1xuICAgICAgICAgICAgY29uc3Qgc3R5bGVzaGVldDogYW55ID0gdGhpcy5fbWFwLnN0eWxlLnN0eWxlc2hlZXQ7XG4gICAgICAgICAgICB0aGlzLnN0eWxlT3duZXIgPSBzdHlsZXNoZWV0Lm93bmVyO1xuICAgICAgICAgICAgdGhpcy5zdHlsZUlkID0gc3R5bGVzaGVldC5pZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNvdXJjZUNhY2hlcyA9IHRoaXMuX21hcC5zdHlsZS5fc291cmNlQ2FjaGVzO1xuICAgICAgICBmb3IgKGNvbnN0IGlkIGluIHNvdXJjZUNhY2hlcykge1xuICAgICAgICAgICAgY29uc3Qgc291cmNlQ2FjaGUgPSBzb3VyY2VDYWNoZXNbaWRdO1xuICAgICAgICAgICAgaWYgKHNvdXJjZUNhY2hlLnVzZWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2UgPSBzb3VyY2VDYWNoZS5nZXRTb3VyY2UoKTtcbiAgICAgICAgICAgICAgICBpZiAoc291cmNlLmF0dHJpYnV0aW9uICYmIGF0dHJpYnV0aW9ucy5pbmRleE9mKHNvdXJjZS5hdHRyaWJ1dGlvbikgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vICRGbG93Rml4TWVbaW5jb21wYXRpYmxlLWNhbGxdIC0gRmxvdyBjYW4ndCBpbmZlciB0aGF0IGF0dHJpYnV0aW9uIGlzIGEgc3RyaW5nXG4gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0aW9ucy5wdXNoKHNvdXJjZS5hdHRyaWJ1dGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gcmVtb3ZlIGFueSBlbnRyaWVzIHRoYXQgYXJlIHN1YnN0cmluZ3Mgb2YgYW5vdGhlciBlbnRyeS5cbiAgICAgICAgLy8gZmlyc3Qgc29ydCBieSBsZW5ndGggc28gdGhhdCBzdWJzdHJpbmdzIGNvbWUgZmlyc3RcbiAgICAgICAgYXR0cmlidXRpb25zLnNvcnQoKGEsIGIpID0+IGEubGVuZ3RoIC0gYi5sZW5ndGgpO1xuICAgICAgICBhdHRyaWJ1dGlvbnMgPSBhdHRyaWJ1dGlvbnMuZmlsdGVyKChhdHRyaWIsIGkpID0+IHtcbiAgICAgICAgICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IGF0dHJpYnV0aW9ucy5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgIGlmIChhdHRyaWJ1dGlvbnNbal0uaW5kZXhPZihhdHRyaWIpID49IDApIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5jdXN0b21BdHRyaWJ1dGlvbikge1xuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodGhpcy5vcHRpb25zLmN1c3RvbUF0dHJpYnV0aW9uKSkge1xuICAgICAgICAgICAgICAgIGF0dHJpYnV0aW9ucyA9IFsuLi50aGlzLm9wdGlvbnMuY3VzdG9tQXR0cmlidXRpb24sIC4uLmF0dHJpYnV0aW9uc107XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGF0dHJpYnV0aW9ucy51bnNoaWZ0KHRoaXMub3B0aW9ucy5jdXN0b21BdHRyaWJ1dGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBjaGVjayBpZiBhdHRyaWJ1dGlvbiBzdHJpbmcgaXMgZGlmZmVyZW50IHRvIG1pbmltaXplIERPTSBjaGFuZ2VzXG4gICAgICAgIGNvbnN0IGF0dHJpYkhUTUwgPSBhdHRyaWJ1dGlvbnMuam9pbignIHwgJyk7XG4gICAgICAgIGlmIChhdHRyaWJIVE1MID09PSB0aGlzLl9hdHRyaWJIVE1MKSByZXR1cm47XG5cbiAgICAgICAgdGhpcy5fYXR0cmliSFRNTCA9IGF0dHJpYkhUTUw7XG5cbiAgICAgICAgaWYgKGF0dHJpYnV0aW9ucy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMuX2lubmVyQ29udGFpbmVyLmlubmVySFRNTCA9IGF0dHJpYkhUTUw7XG4gICAgICAgICAgICB0aGlzLl9jb250YWluZXIuY2xhc3NMaXN0LnJlbW92ZSgnbWFwYm94Z2wtYXR0cmliLWVtcHR5Jyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9jb250YWluZXIuY2xhc3NMaXN0LmFkZCgnbWFwYm94Z2wtYXR0cmliLWVtcHR5Jyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gcmVtb3ZlIG9sZCBET00gbm9kZSBmcm9tIF9lZGl0TGlua1xuICAgICAgICB0aGlzLl9lZGl0TGluayA9IG51bGw7XG4gICAgfVxuXG4gICAgX3VwZGF0ZUNvbXBhY3QoKSB7XG4gICAgICAgIGlmICh0aGlzLl9tYXAuZ2V0Q2FudmFzQ29udGFpbmVyKCkub2Zmc2V0V2lkdGggPD0gNjQwKSB7XG4gICAgICAgICAgICB0aGlzLl9jb250YWluZXIuY2xhc3NMaXN0LmFkZCgnbWFwYm94Z2wtY29tcGFjdCcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fY29udGFpbmVyLmNsYXNzTGlzdC5yZW1vdmUoJ21hcGJveGdsLWNvbXBhY3QnLCAnbWFwYm94Z2wtY29tcGFjdC1zaG93Jyk7XG4gICAgICAgIH1cbiAgICB9XG5cbn1cblxuZXhwb3J0IGRlZmF1bHQgQXR0cmlidXRpb25Db250cm9sO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0ICogYXMgRE9NIGZyb20gJy4uLy4uL3V0aWwvZG9tLmpzJztcbmltcG9ydCB7YmluZEFsbH0gZnJvbSAnLi4vLi4vdXRpbC91dGlsLmpzJztcblxuaW1wb3J0IHR5cGUgTWFwLCB7Q29udHJvbFBvc2l0aW9ufSBmcm9tICcuLi9tYXAuanMnO1xuXG4vKipcbiAqIEEgYExvZ29Db250cm9sYCBpcyBhIGNvbnRyb2wgdGhhdCBhZGRzIHRoZSBNYXBib3ggd2F0ZXJtYXJrXG4gKiB0byB0aGUgbWFwIGFzIHJlcXVpcmVkIGJ5IHRoZSBbdGVybXMgb2Ygc2VydmljZV0oaHR0cHM6Ly93d3cubWFwYm94LmNvbS90b3MvKSBmb3IgTWFwYm94XG4gKiB2ZWN0b3IgdGlsZXMgYW5kIGNvcmUgc3R5bGVzLlxuICogQWRkIHRoaXMgY29udHJvbCB0byBhIG1hcCB1c2luZyB7QGxpbmsgTWFwI2FkZENvbnRyb2x9LlxuICpcbiAqIEBpbXBsZW1lbnRzIHtJQ29udHJvbH1cbiAqIEBwcml2YXRlXG4qKi9cblxuY2xhc3MgTG9nb0NvbnRyb2wge1xuICAgIF9tYXA6IE1hcDtcbiAgICBfY29udGFpbmVyOiBIVE1MRWxlbWVudDtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBiaW5kQWxsKFsnX3VwZGF0ZUxvZ28nLCAnX3VwZGF0ZUNvbXBhY3QnXSwgdGhpcyk7XG4gICAgfVxuXG4gICAgb25BZGQobWFwOiBNYXApOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIHRoaXMuX21hcCA9IG1hcDtcbiAgICAgICAgdGhpcy5fY29udGFpbmVyID0gRE9NLmNyZWF0ZSgnZGl2JywgJ21hcGJveGdsLWN0cmwnKTtcbiAgICAgICAgY29uc3QgYW5jaG9yID0gRE9NLmNyZWF0ZSgnYScsICdtYXBib3hnbC1jdHJsLWxvZ28nKTtcbiAgICAgICAgYW5jaG9yLnRhcmdldCA9IFwiX2JsYW5rXCI7XG4gICAgICAgIGFuY2hvci5yZWwgPSBcIm5vb3BlbmVyIG5vZm9sbG93XCI7XG4gICAgICAgIGFuY2hvci5ocmVmID0gXCJodHRwczovL3d3dy5tYXBib3guY29tL1wiO1xuICAgICAgICBhbmNob3Iuc2V0QXR0cmlidXRlKFwiYXJpYS1sYWJlbFwiLCB0aGlzLl9tYXAuX2dldFVJU3RyaW5nKCdMb2dvQ29udHJvbC5UaXRsZScpKTtcbiAgICAgICAgYW5jaG9yLnNldEF0dHJpYnV0ZShcInJlbFwiLCBcIm5vb3BlbmVyIG5vZm9sbG93XCIpO1xuICAgICAgICB0aGlzLl9jb250YWluZXIuYXBwZW5kQ2hpbGQoYW5jaG9yKTtcbiAgICAgICAgdGhpcy5fY29udGFpbmVyLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG5cbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICB0aGlzLl9tYXAub24oJ3NvdXJjZWRhdGEnLCB0aGlzLl91cGRhdGVMb2dvKTtcbiAgICAgICAgdGhpcy5fdXBkYXRlTG9nbygpO1xuXG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgdGhpcy5fbWFwLm9uKCdyZXNpemUnLCB0aGlzLl91cGRhdGVDb21wYWN0KTtcbiAgICAgICAgdGhpcy5fdXBkYXRlQ29tcGFjdCgpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLl9jb250YWluZXI7XG4gICAgfVxuXG4gICAgb25SZW1vdmUoKSB7XG4gICAgICAgIHRoaXMuX2NvbnRhaW5lci5yZW1vdmUoKTtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICB0aGlzLl9tYXAub2ZmKCdzb3VyY2VkYXRhJywgdGhpcy5fdXBkYXRlTG9nbyk7XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgdGhpcy5fbWFwLm9mZigncmVzaXplJywgdGhpcy5fdXBkYXRlQ29tcGFjdCk7XG4gICAgfVxuXG4gICAgZ2V0RGVmYXVsdFBvc2l0aW9uKCk6IENvbnRyb2xQb3NpdGlvbiB7XG4gICAgICAgIHJldHVybiAnYm90dG9tLWxlZnQnO1xuICAgIH1cblxuICAgIF91cGRhdGVMb2dvKGU6IGFueSkge1xuICAgICAgICBpZiAoIWUgfHwgZS5zb3VyY2VEYXRhVHlwZSA9PT0gJ21ldGFkYXRhJykge1xuICAgICAgICAgICAgdGhpcy5fY29udGFpbmVyLnN0eWxlLmRpc3BsYXkgPSB0aGlzLl9sb2dvUmVxdWlyZWQoKSA/ICdibG9jaycgOiAnbm9uZSc7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfbG9nb1JlcXVpcmVkKCk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAoIXRoaXMuX21hcC5zdHlsZSkgcmV0dXJuIHRydWU7XG4gICAgICAgIGNvbnN0IHNvdXJjZUNhY2hlcyA9IHRoaXMuX21hcC5zdHlsZS5fc291cmNlQ2FjaGVzO1xuICAgICAgICBpZiAoT2JqZWN0LmVudHJpZXMoc291cmNlQ2FjaGVzKS5sZW5ndGggPT09IDApIHJldHVybiB0cnVlO1xuICAgICAgICBmb3IgKGNvbnN0IGlkIGluIHNvdXJjZUNhY2hlcykge1xuICAgICAgICAgICAgY29uc3Qgc291cmNlID0gc291cmNlQ2FjaGVzW2lkXS5nZXRTb3VyY2UoKTtcbiAgICAgICAgICAgIGlmIChzb3VyY2UuaGFzT3duUHJvcGVydHkoJ21hcGJveF9sb2dvJykgJiYgIXNvdXJjZS5tYXBib3hfbG9nbykge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIF91cGRhdGVDb21wYWN0KCkge1xuICAgICAgICBjb25zdCBjb250YWluZXJDaGlsZHJlbiA9IHRoaXMuX2NvbnRhaW5lci5jaGlsZHJlbjtcbiAgICAgICAgaWYgKGNvbnRhaW5lckNoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgICAgICAgY29uc3QgYW5jaG9yID0gY29udGFpbmVyQ2hpbGRyZW5bMF07XG4gICAgICAgICAgICBpZiAodGhpcy5fbWFwLmdldENhbnZhc0NvbnRhaW5lcigpLm9mZnNldFdpZHRoIDwgMjUwKSB7XG4gICAgICAgICAgICAgICAgYW5jaG9yLmNsYXNzTGlzdC5hZGQoJ21hcGJveGdsLWNvbXBhY3QnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYW5jaG9yLmNsYXNzTGlzdC5yZW1vdmUoJ21hcGJveGdsLWNvbXBhY3QnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxufVxuXG5leHBvcnQgZGVmYXVsdCBMb2dvQ29udHJvbDtcbiIsIi8vIEBmbG93IHN0cmljdFxuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuXG5leHBvcnQgdHlwZSBUYXNrSUQgPSBudW1iZXI7IC8vIGNhbid0IG1hcmsgb3BhcXVlIGR1ZSB0byBodHRwczovL2dpdGh1Yi5jb20vZmxvd3R5cGUvZmxvdy1yZW1vdmUtdHlwZXMvcHVsbC82MVxudHlwZSBUYXNrID0ge1xuICAgIGNhbGxiYWNrOiAodGltZVN0YW1wOiBudW1iZXIpID0+IHZvaWQ7XG4gICAgaWQ6IFRhc2tJRDtcbiAgICBjYW5jZWxsZWQ6IGJvb2xlYW47XG59O1xuXG5jbGFzcyBUYXNrUXVldWUge1xuICAgIF9xdWV1ZTogQXJyYXk8VGFzaz47XG4gICAgX2lkOiBUYXNrSUQ7XG4gICAgX2NsZWFyZWQ6IGJvb2xlYW47XG4gICAgX2N1cnJlbnRseVJ1bm5pbmc6IEFycmF5PFRhc2s+IHwgZmFsc2U7XG5cbiAgICBjb25zdHJ1Y3RvcigpICB7XG4gICAgICAgIHRoaXMuX3F1ZXVlID0gW107XG4gICAgICAgIHRoaXMuX2lkID0gMDtcbiAgICAgICAgdGhpcy5fY2xlYXJlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9jdXJyZW50bHlSdW5uaW5nID0gZmFsc2U7XG4gICAgfVxuXG4gICAgYWRkKGNhbGxiYWNrOiAodGltZVN0YW1wOiBudW1iZXIpID0+IHZvaWQpOiBUYXNrSUQge1xuICAgICAgICBjb25zdCBpZCA9ICsrdGhpcy5faWQ7XG4gICAgICAgIGNvbnN0IHF1ZXVlID0gdGhpcy5fcXVldWU7XG4gICAgICAgIHF1ZXVlLnB1c2goe2NhbGxiYWNrLCBpZCwgY2FuY2VsbGVkOiBmYWxzZX0pO1xuICAgICAgICByZXR1cm4gaWQ7XG4gICAgfVxuXG4gICAgcmVtb3ZlKGlkOiBUYXNrSUQpIHtcbiAgICAgICAgY29uc3QgcnVubmluZyA9IHRoaXMuX2N1cnJlbnRseVJ1bm5pbmc7XG4gICAgICAgIGNvbnN0IHF1ZXVlID0gcnVubmluZyA/IHRoaXMuX3F1ZXVlLmNvbmNhdChydW5uaW5nKSA6IHRoaXMuX3F1ZXVlO1xuICAgICAgICBmb3IgKGNvbnN0IHRhc2sgb2YgcXVldWUpIHtcbiAgICAgICAgICAgIGlmICh0YXNrLmlkID09PSBpZCkge1xuICAgICAgICAgICAgICAgIHRhc2suY2FuY2VsbGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBydW4odGltZVN0YW1wOiBudW1iZXIgPSAwKSB7XG4gICAgICAgIGFzc2VydCghdGhpcy5fY3VycmVudGx5UnVubmluZyk7XG4gICAgICAgIGNvbnN0IHF1ZXVlID0gdGhpcy5fY3VycmVudGx5UnVubmluZyA9IHRoaXMuX3F1ZXVlO1xuXG4gICAgICAgIC8vIFRhc2tzIHF1ZXVlZCBieSBjYWxsYmFja3MgaW4gdGhlIGN1cnJlbnQgcXVldWUgc2hvdWxkIGJlIGV4ZWN1dGVkXG4gICAgICAgIC8vIG9uIHRoZSBuZXh0IHJ1biwgbm90IHRoZSBjdXJyZW50IHJ1bi5cbiAgICAgICAgdGhpcy5fcXVldWUgPSBbXTtcblxuICAgICAgICBmb3IgKGNvbnN0IHRhc2sgb2YgcXVldWUpIHtcbiAgICAgICAgICAgIGlmICh0YXNrLmNhbmNlbGxlZCkgY29udGludWU7XG4gICAgICAgICAgICB0YXNrLmNhbGxiYWNrKHRpbWVTdGFtcCk7XG4gICAgICAgICAgICBpZiAodGhpcy5fY2xlYXJlZCkgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9jbGVhcmVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX2N1cnJlbnRseVJ1bm5pbmcgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBjbGVhcigpIHtcbiAgICAgICAgaWYgKHRoaXMuX2N1cnJlbnRseVJ1bm5pbmcpIHtcbiAgICAgICAgICAgIHRoaXMuX2NsZWFyZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3F1ZXVlID0gW107XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBUYXNrUXVldWU7XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgTG5nTGF0IGZyb20gJy4uL2dlby9sbmdfbGF0LmpzJztcblxuaW1wb3J0IHR5cGUgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5pbXBvcnQgdHlwZSBUcmFuc2Zvcm0gZnJvbSAnLi4vZ2VvL3RyYW5zZm9ybS5qcyc7XG5cbi8qKlxuICogR2l2ZW4gYSBMbmdMYXQsIHByaW9yIHByb2plY3RlZCBwb3NpdGlvbiwgYW5kIGEgdHJhbnNmb3JtLCByZXR1cm4gYSBuZXcgTG5nTGF0IHNoaWZ0ZWRcbiAqIG4gw5cgMzYwwrAgZWFzdCBvciB3ZXN0IGZvciBzb21lIG4g4omlIDAgc3VjaCB0aGF0OlxuICpcbiAqICogdGhlIHByb2plY3RlZCBsb2NhdGlvbiBvZiB0aGUgcmVzdWx0IGlzIG9uIHNjcmVlbiwgaWYgcG9zc2libGUsIGFuZCBzZWNvbmRhcmlseTpcbiAqICogdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgcHJvamVjdGVkIGxvY2F0aW9uIG9mIHRoZSByZXN1bHQgYW5kIHRoZSBwcmlvciBwb3NpdGlvblxuICogICBpcyBtaW5pbWl6ZWQuXG4gKlxuICogVGhlIG9iamVjdCBpcyB0byBwcmVzZXJ2ZSBwZXJjZWl2ZWQgb2JqZWN0IGNvbnN0YW5jeSBmb3IgUG9wdXBzIGFuZCBNYXJrZXJzIGFzIG11Y2ggYXNcbiAqIHBvc3NpYmxlOyB0aGV5IHNob3VsZCBhdm9pZCBzaGlmdGluZyBsYXJnZSBkaXN0YW5jZXMgYWNyb3NzIHRoZSBzY3JlZW4sIGV2ZW4gd2hlbiB0aGVcbiAqIG1hcCBjZW50ZXIgY2hhbmdlcyBieSDCsTM2MMKwIGR1ZSB0byBhdXRvbWF0aWMgd3JhcHBpbmcsIGFuZCB3aGVuIGFib3V0IHRvIGdvIG9mZiBzY3JlZW4sXG4gKiBzaG91bGQgd3JhcCBqdXN0IGVub3VnaCB0byBhdm9pZCBkb2luZyBzby5cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbihsbmdMYXQ6IExuZ0xhdCwgcHJpb3JQb3M6ID9Qb2ludCwgdHJhbnNmb3JtOiBUcmFuc2Zvcm0pOiBMbmdMYXQge1xuICAgIGxuZ0xhdCA9IG5ldyBMbmdMYXQobG5nTGF0LmxuZywgbG5nTGF0LmxhdCk7XG5cbiAgICAvLyBGaXJzdCwgdHJ5IHNoaWZ0aW5nIG9uZSB3b3JsZCBpbiBlaXRoZXIgZGlyZWN0aW9uLCBhbmQgc2VlIGlmIGVpdGhlciBpcyBjbG9zZXIgdG8gdGhlXG4gICAgLy8gcHJpb3IgcG9zaXRpb24uIERvbid0IHNoaWZ0IGF3YXkgaWYgaXQgbmV3IHBvc2l0aW9uIGlzIGZ1cnRoZXIgZnJvbSBjZW50ZXIuXG4gICAgLy8gVGhpcyBwcmVzZXJ2ZXMgb2JqZWN0IGNvbnN0YW5jeSB3aGVuIHRoZSBtYXAgY2VudGVyIGlzIGF1dG8td3JhcHBlZCBkdXJpbmcgYW5pbWF0aW9ucyxcbiAgICAvLyBidXQgZG9uJ3QgYWxsb3cgaXQgdG8gcnVuIGF3YXkgb24gaG9yaXpvbiAocG9pbnRzIHRvd2FyZHMgaG9yaXpvbiBnZXQgY2xvc2VyIGFuZCBjbG9zZXIpLlxuICAgIGlmIChwcmlvclBvcykge1xuICAgICAgICBjb25zdCBsZWZ0ICA9IG5ldyBMbmdMYXQobG5nTGF0LmxuZyAtIDM2MCwgbG5nTGF0LmxhdCk7XG4gICAgICAgIGNvbnN0IHJpZ2h0ID0gbmV3IExuZ0xhdChsbmdMYXQubG5nICsgMzYwLCBsbmdMYXQubGF0KTtcbiAgICAgICAgLy8gVW5sZXNzIG9mZnNjcmVlbiwga2VlcCB0aGUgbWFya2VyIHdpdGhpbiBzYW1lIHdyYXAgZGlzdGFuY2UgdG8gY2VudGVyLiBUaGlzIGlzIHRvIHByZXZlbnRcbiAgICAgICAgLy8gcnVubmluZyBpdCB0byBpbmZpbml0eSBgbG5nYCBuZWFyIGhvcml6b24gd2hlbiBiZWFyaW5nIGlzIH45MMKwLlxuICAgICAgICBjb25zdCB3aXRoaW5XcmFwID0gIE1hdGguY2VpbChNYXRoLmFicyhsbmdMYXQubG5nIC0gdHJhbnNmb3JtLmNlbnRlci5sbmcpIC8gMzYwKSAqIDM2MDtcbiAgICAgICAgY29uc3QgZGVsdGEgPSB0cmFuc2Zvcm0ubG9jYXRpb25Qb2ludChsbmdMYXQpLmRpc3RTcXIocHJpb3JQb3MpO1xuICAgICAgICBjb25zdCBvZmZzY3JlZW4gPSBwcmlvclBvcy54IDwgMCB8fCBwcmlvclBvcy55IDwgMCB8fCBwcmlvclBvcy54ID4gdHJhbnNmb3JtLndpZHRoIHx8IHByaW9yUG9zLnkgPiB0cmFuc2Zvcm0uaGVpZ2h0O1xuICAgICAgICBpZiAodHJhbnNmb3JtLmxvY2F0aW9uUG9pbnQobGVmdCkuZGlzdFNxcihwcmlvclBvcykgPCBkZWx0YSAmJiAob2Zmc2NyZWVuIHx8IE1hdGguYWJzKGxlZnQubG5nIC0gdHJhbnNmb3JtLmNlbnRlci5sbmcpIDwgd2l0aGluV3JhcCkpIHtcbiAgICAgICAgICAgIGxuZ0xhdCA9IGxlZnQ7XG4gICAgICAgIH0gZWxzZSBpZiAodHJhbnNmb3JtLmxvY2F0aW9uUG9pbnQocmlnaHQpLmRpc3RTcXIocHJpb3JQb3MpIDwgZGVsdGEgJiYgKG9mZnNjcmVlbiB8fCBNYXRoLmFicyhyaWdodC5sbmcgLSB0cmFuc2Zvcm0uY2VudGVyLmxuZykgPCB3aXRoaW5XcmFwKSkge1xuICAgICAgICAgICAgbG5nTGF0ID0gcmlnaHQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBTZWNvbmQsIHdyYXAgdG93YXJkIHRoZSBjZW50ZXIgdW50aWwgdGhlIG5ldyBwb3NpdGlvbiBpcyBvbiBzY3JlZW4sIG9yIHdlIGNhbid0IGdldFxuICAgIC8vIGFueSBjbG9zZXIuXG4gICAgd2hpbGUgKE1hdGguYWJzKGxuZ0xhdC5sbmcgLSB0cmFuc2Zvcm0uY2VudGVyLmxuZykgPiAxODApIHtcbiAgICAgICAgY29uc3QgcG9zID0gdHJhbnNmb3JtLmxvY2F0aW9uUG9pbnQobG5nTGF0KTtcbiAgICAgICAgaWYgKHBvcy54ID49IDAgJiYgcG9zLnkgPj0gMCAmJiBwb3MueCA8PSB0cmFuc2Zvcm0ud2lkdGggJiYgcG9zLnkgPD0gdHJhbnNmb3JtLmhlaWdodCkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxuZ0xhdC5sbmcgPiB0cmFuc2Zvcm0uY2VudGVyLmxuZykge1xuICAgICAgICAgICAgbG5nTGF0LmxuZyAtPSAzNjA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsbmdMYXQubG5nICs9IDM2MDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBsbmdMYXQ7XG59XG4iLCIvLyBAZmxvd1xuXG5leHBvcnQgdHlwZSBBbmNob3IgPVxuICAgIHwgJ2NlbnRlcidcbiAgICB8ICd0b3AnXG4gICAgfCAnYm90dG9tJ1xuICAgIHwgJ2xlZnQnXG4gICAgfCAncmlnaHQnXG4gICAgfCAndG9wLWxlZnQnXG4gICAgfCAndG9wLXJpZ2h0J1xuICAgIHwgJ2JvdHRvbS1sZWZ0J1xuICAgIHwgJ2JvdHRvbS1yaWdodCc7XG5cbmV4cG9ydCBjb25zdCBhbmNob3JUcmFuc2xhdGU6IHtbXzogQW5jaG9yXTogc3RyaW5nfSA9IHtcbiAgICAnY2VudGVyJzogJ3RyYW5zbGF0ZSgtNTAlLC01MCUpJyxcbiAgICAndG9wJzogJ3RyYW5zbGF0ZSgtNTAlLDApJyxcbiAgICAndG9wLWxlZnQnOiAndHJhbnNsYXRlKDAsMCknLFxuICAgICd0b3AtcmlnaHQnOiAndHJhbnNsYXRlKC0xMDAlLDApJyxcbiAgICAnYm90dG9tJzogJ3RyYW5zbGF0ZSgtNTAlLC0xMDAlKScsXG4gICAgJ2JvdHRvbS1sZWZ0JzogJ3RyYW5zbGF0ZSgwLC0xMDAlKScsXG4gICAgJ2JvdHRvbS1yaWdodCc6ICd0cmFuc2xhdGUoLTEwMCUsLTEwMCUpJyxcbiAgICAnbGVmdCc6ICd0cmFuc2xhdGUoMCwtNTAlKScsXG4gICAgJ3JpZ2h0JzogJ3RyYW5zbGF0ZSgtMTAwJSwtNTAlKSdcbn07XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgKiBhcyBET00gZnJvbSAnLi4vdXRpbC9kb20uanMnO1xuaW1wb3J0IHdpbmRvdyBmcm9tICcuLi91dGlsL3dpbmRvdy5qcyc7XG5pbXBvcnQgTG5nTGF0IGZyb20gJy4uL2dlby9sbmdfbGF0LmpzJztcbmltcG9ydCBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCBzbWFydFdyYXAgZnJvbSAnLi4vdXRpbC9zbWFydF93cmFwLmpzJztcbmltcG9ydCB7YmluZEFsbCwgZXh0ZW5kLCByYWRUb0RlZywgc21vb3Roc3RlcH0gZnJvbSAnLi4vdXRpbC91dGlsLmpzJztcbmltcG9ydCB7dHlwZSBBbmNob3IsIGFuY2hvclRyYW5zbGF0ZX0gZnJvbSAnLi9hbmNob3IuanMnO1xuaW1wb3J0IHtFdmVudCwgRXZlbnRlZH0gZnJvbSAnLi4vdXRpbC9ldmVudGVkLmpzJztcbmltcG9ydCB0eXBlIE1hcCBmcm9tICcuL21hcC5qcyc7XG5pbXBvcnQgdHlwZSBQb3B1cCBmcm9tICcuL3BvcHVwLmpzJztcbmltcG9ydCB0eXBlIHtMbmdMYXRMaWtlfSBmcm9tIFwiLi4vZ2VvL2xuZ19sYXQuanNcIjtcbmltcG9ydCB0eXBlIHtNYXBNb3VzZUV2ZW50LCBNYXBUb3VjaEV2ZW50fSBmcm9tICcuL2V2ZW50cy5qcyc7XG5pbXBvcnQgdHlwZSB7UG9pbnRMaWtlfSBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCB7Z2xvYmVUaWx0QXRMbmdMYXQsIGdsb2JlQ2VudGVyVG9TY3JlZW5Qb2ludCwgaXNMbmdMYXRCZWhpbmRHbG9iZSwgR0xPQkVfWk9PTV9USFJFU0hPTERfTUFYfSBmcm9tICcuLi9nZW8vcHJvamVjdGlvbi9nbG9iZV91dGlsLmpzJztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcblxudHlwZSBPcHRpb25zID0ge1xuICAgIGVsZW1lbnQ/OiBIVE1MRWxlbWVudCxcbiAgICBvZmZzZXQ/OiBQb2ludExpa2UsXG4gICAgYW5jaG9yPzogQW5jaG9yLFxuICAgIGNvbG9yPzogc3RyaW5nLFxuICAgIHNjYWxlPzogbnVtYmVyLFxuICAgIGRyYWdnYWJsZT86IGJvb2xlYW4sXG4gICAgY2xpY2tUb2xlcmFuY2U/OiBudW1iZXIsXG4gICAgcm90YXRpb24/OiBudW1iZXIsXG4gICAgcm90YXRpb25BbGlnbm1lbnQ/OiBzdHJpbmcsXG4gICAgcGl0Y2hBbGlnbm1lbnQ/OiBzdHJpbmcsXG4gICAgb2NjbHVkZWRPcGFjaXR5PzogbnVtYmVyXG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBtYXJrZXIgY29tcG9uZW50LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IFtvcHRpb25zLmVsZW1lbnRdIERPTSBlbGVtZW50IHRvIHVzZSBhcyBhIG1hcmtlci4gVGhlIGRlZmF1bHQgaXMgYSBsaWdodCBibHVlLCBkcm9wbGV0LXNoYXBlZCBTVkcgbWFya2VyLlxuICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLmFuY2hvcj0nY2VudGVyJ10gQSBzdHJpbmcgaW5kaWNhdGluZyB0aGUgcGFydCBvZiB0aGUgTWFya2VyIHRoYXQgc2hvdWxkIGJlIHBvc2l0aW9uZWQgY2xvc2VzdCB0byB0aGUgY29vcmRpbmF0ZSBzZXQgdmlhIHtAbGluayBNYXJrZXIjc2V0TG5nTGF0fS5cbiAqICAgT3B0aW9ucyBhcmUgYCdjZW50ZXInYCwgYCd0b3AnYCwgYCdib3R0b20nYCwgYCdsZWZ0J2AsIGAncmlnaHQnYCwgYCd0b3AtbGVmdCdgLCBgJ3RvcC1yaWdodCdgLCBgJ2JvdHRvbS1sZWZ0J2AsIGFuZCBgJ2JvdHRvbS1yaWdodCdgLlxuICogQHBhcmFtIHtQb2ludExpa2V9IFtvcHRpb25zLm9mZnNldF0gVGhlIG9mZnNldCBpbiBwaXhlbHMgYXMgYSB7QGxpbmsgUG9pbnRMaWtlfSBvYmplY3QgdG8gYXBwbHkgcmVsYXRpdmUgdG8gdGhlIGVsZW1lbnQncyBjZW50ZXIuIE5lZ2F0aXZlcyBpbmRpY2F0ZSBsZWZ0IGFuZCB1cC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0aW9ucy5jb2xvcj0nIzNGQjFDRSddIFRoZSBjb2xvciB0byB1c2UgZm9yIHRoZSBkZWZhdWx0IG1hcmtlciBpZiBgb3B0aW9ucy5lbGVtZW50YCBpcyBub3QgcHJvdmlkZWQuIFRoZSBkZWZhdWx0IGlzIGxpZ2h0IGJsdWUuXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMuc2NhbGU9MV0gVGhlIHNjYWxlIHRvIHVzZSBmb3IgdGhlIGRlZmF1bHQgbWFya2VyIGlmIGBvcHRpb25zLmVsZW1lbnRgIGlzIG5vdCBwcm92aWRlZC4gVGhlIGRlZmF1bHQgc2NhbGUgY29ycmVzcG9uZHMgdG8gYSBoZWlnaHQgb2YgYDQxcHhgIGFuZCBhIHdpZHRoIG9mIGAyN3B4YC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMuZHJhZ2dhYmxlPWZhbHNlXSBBIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIG9yIG5vdCBhIG1hcmtlciBpcyBhYmxlIHRvIGJlIGRyYWdnZWQgdG8gYSBuZXcgcG9zaXRpb24gb24gdGhlIG1hcC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5jbGlja1RvbGVyYW5jZT0wXSBUaGUgbWF4IG51bWJlciBvZiBwaXhlbHMgYSB1c2VyIGNhbiBzaGlmdCB0aGUgbW91c2UgcG9pbnRlciBkdXJpbmcgYSBjbGljayBvbiB0aGUgbWFya2VyIGZvciBpdCB0byBiZSBjb25zaWRlcmVkIGEgdmFsaWQgY2xpY2sgKGFzIG9wcG9zZWQgdG8gYSBtYXJrZXIgZHJhZykuIFRoZSBkZWZhdWx0IGlzIHRvIGluaGVyaXQgbWFwJ3MgYGNsaWNrVG9sZXJhbmNlYC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5yb3RhdGlvbj0wXSBUaGUgcm90YXRpb24gYW5nbGUgb2YgdGhlIG1hcmtlciBpbiBkZWdyZWVzLCByZWxhdGl2ZSB0byBpdHMgcmVzcGVjdGl2ZSBgcm90YXRpb25BbGlnbm1lbnRgIHNldHRpbmcuIEEgcG9zaXRpdmUgdmFsdWUgd2lsbCByb3RhdGUgdGhlIG1hcmtlciBjbG9ja3dpc2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gW29wdGlvbnMucGl0Y2hBbGlnbm1lbnQ9J2F1dG8nXSBgJ21hcCdgIGFsaWducyB0aGUgYE1hcmtlcmAgdG8gdGhlIHBsYW5lIG9mIHRoZSBtYXAuIGAndmlld3BvcnQnYCBhbGlnbnMgdGhlIGBNYXJrZXJgIHRvIHRoZSBwbGFuZSBvZiB0aGUgdmlld3BvcnQuIGAnYXV0bydgIGF1dG9tYXRpY2FsbHkgbWF0Y2hlcyB0aGUgdmFsdWUgb2YgYHJvdGF0aW9uQWxpZ25tZW50YC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0aW9ucy5yb3RhdGlvbkFsaWdubWVudD0nYXV0byddIFRoZSBhbGlnbm1lbnQgb2YgdGhlIG1hcmtlcidzIHJvdGF0aW9uLmAnbWFwJ2AgaXMgYWxpZ25lZCB3aXRoIHRoZSBtYXAgcGxhbmUsIGNvbnNpc3RlbnQgd2l0aCB0aGUgY2FyZGluYWwgZGlyZWN0aW9ucyBhcyB0aGUgbWFwIHJvdGF0ZXMuIGAndmlld3BvcnQnYCBpcyBzY3JlZW5zcGFjZS1hbGlnbmVkLiBgJ2hvcml6b24nYCBpcyBhbGlnbmVkIGFjY29yZGluZyB0byB0aGUgbmVhcmVzdCBob3Jpem9uLCBvbiBub24tZ2xvYmUgcHJvamVjdGlvbnMgaXQgaXMgZXF1aXZhbGVudCB0byBgJ3ZpZXdwb3J0J2AuIGAnYXV0bydgIGlzIGVxdWl2YWxlbnQgdG8gYCd2aWV3cG9ydCdgLlxuICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLm9jY2x1ZGVkT3BhY2l0eT0wLjJdIFRoZSBvcGFjaXR5IG9mIGEgbWFya2VyIHRoYXQncyBvY2NsdWRlZCBieSAzRCB0ZXJyYWluLlxuICogQGV4YW1wbGVcbiAqIC8vIENyZWF0ZSBhIG5ldyBtYXJrZXIuXG4gKiBjb25zdCBtYXJrZXIgPSBuZXcgbWFwYm94Z2wuTWFya2VyKClcbiAqICAgICAuc2V0TG5nTGF0KFszMC41LCA1MC41XSlcbiAqICAgICAuYWRkVG8obWFwKTtcbiAqIEBleGFtcGxlXG4gKiAvLyBTZXQgbWFya2VyIG9wdGlvbnMuXG4gKiBjb25zdCBtYXJrZXIgPSBuZXcgbWFwYm94Z2wuTWFya2VyKHtcbiAqICAgICBjb2xvcjogXCIjRkZGRkZGXCIsXG4gKiAgICAgZHJhZ2dhYmxlOiB0cnVlXG4gKiB9KS5zZXRMbmdMYXQoWzMwLjUsIDUwLjVdKVxuICogICAgIC5hZGRUbyhtYXApO1xuICogQHNlZSBbRXhhbXBsZTogQWRkIGN1c3RvbSBpY29ucyB3aXRoIE1hcmtlcnNdKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvY3VzdG9tLW1hcmtlci1pY29ucy8pXG4gKiBAc2VlIFtFeGFtcGxlOiBDcmVhdGUgYSBkcmFnZ2FibGUgTWFya2VyXShodHRwczovL3d3dy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2RyYWctYS1tYXJrZXIvKVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNYXJrZXIgZXh0ZW5kcyBFdmVudGVkIHtcbiAgICBfbWFwOiA/TWFwO1xuICAgIF9hbmNob3I6IEFuY2hvcjtcbiAgICBfb2Zmc2V0OiBQb2ludDtcbiAgICBfZWxlbWVudDogSFRNTEVsZW1lbnQ7XG4gICAgX3BvcHVwOiA/UG9wdXA7XG4gICAgX2xuZ0xhdDogTG5nTGF0O1xuICAgIF9wb3M6ID9Qb2ludDtcbiAgICBfY29sb3I6IHN0cmluZztcbiAgICBfc2NhbGU6IG51bWJlcjtcbiAgICBfZGVmYXVsdE1hcmtlcjogYm9vbGVhbjtcbiAgICBfZHJhZ2dhYmxlOiBib29sZWFuO1xuICAgIF9jbGlja1RvbGVyYW5jZTogbnVtYmVyO1xuICAgIF9pc0RyYWdnaW5nOiBib29sZWFuO1xuICAgIF9zdGF0ZTogJ2luYWN0aXZlJyB8ICdwZW5kaW5nJyB8ICdhY3RpdmUnOyAvLyB1c2VkIGZvciBoYW5kbGluZyBkcmFnIGV2ZW50c1xuICAgIF9wb3NpdGlvbkRlbHRhOiA/UG9pbnQ7XG4gICAgX3BvaW50ZXJkb3duUG9zOiA/UG9pbnQ7XG4gICAgX3JvdGF0aW9uOiBudW1iZXI7XG4gICAgX3BpdGNoQWxpZ25tZW50OiBzdHJpbmc7XG4gICAgX3JvdGF0aW9uQWxpZ25tZW50OiBzdHJpbmc7XG4gICAgX29yaWdpbmFsVGFiSW5kZXg6ID9zdHJpbmc7IC8vIG9yaWdpbmFsIHRhYmluZGV4IG9mIF9lbGVtZW50XG4gICAgX2ZhZGVUaW1lcjogP1RpbWVvdXRJRDtcbiAgICBfdXBkYXRlRnJhbWVJZDogbnVtYmVyO1xuICAgIF91cGRhdGVNb3Zpbmc6ICgpID0+IHZvaWQ7XG4gICAgX29jY2x1ZGVkT3BhY2l0eTogbnVtYmVyO1xuXG4gICAgY29uc3RydWN0b3Iob3B0aW9ucz86IE9wdGlvbnMsIGxlZ2FjeU9wdGlvbnM/OiBPcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIC8vIEZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5IC0tIHRoZSBjb25zdHJ1Y3RvciB1c2VkIHRvIGFjY2VwdCB0aGUgZWxlbWVudCBhcyBhXG4gICAgICAgIC8vIHJlcXVpcmVkIGZpcnN0IGFyZ3VtZW50LCBiZWZvcmUgaXQgd2FzIG1hZGUgb3B0aW9uYWwuXG4gICAgICAgIGlmIChvcHRpb25zIGluc3RhbmNlb2Ygd2luZG93LkhUTUxFbGVtZW50IHx8IGxlZ2FjeU9wdGlvbnMpIHtcbiAgICAgICAgICAgIG9wdGlvbnMgPSBleHRlbmQoe2VsZW1lbnQ6IG9wdGlvbnN9LCBsZWdhY3lPcHRpb25zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJpbmRBbGwoW1xuICAgICAgICAgICAgJ191cGRhdGUnLFxuICAgICAgICAgICAgJ19vbk1vdmUnLFxuICAgICAgICAgICAgJ19vblVwJyxcbiAgICAgICAgICAgICdfYWRkRHJhZ0hhbmRsZXInLFxuICAgICAgICAgICAgJ19vbk1hcENsaWNrJyxcbiAgICAgICAgICAgICdfb25LZXlQcmVzcycsXG4gICAgICAgICAgICAnX2NsZWFyRmFkZVRpbWVyJ1xuICAgICAgICBdLCB0aGlzKTtcblxuICAgICAgICB0aGlzLl9hbmNob3IgPSAob3B0aW9ucyAmJiBvcHRpb25zLmFuY2hvcikgfHwgJ2NlbnRlcic7XG4gICAgICAgIHRoaXMuX2NvbG9yID0gKG9wdGlvbnMgJiYgb3B0aW9ucy5jb2xvcikgfHwgJyMzRkIxQ0UnO1xuICAgICAgICB0aGlzLl9zY2FsZSA9IChvcHRpb25zICYmIG9wdGlvbnMuc2NhbGUpIHx8IDE7XG4gICAgICAgIHRoaXMuX2RyYWdnYWJsZSA9IChvcHRpb25zICYmIG9wdGlvbnMuZHJhZ2dhYmxlKSB8fCBmYWxzZTtcbiAgICAgICAgdGhpcy5fY2xpY2tUb2xlcmFuY2UgPSAob3B0aW9ucyAmJiBvcHRpb25zLmNsaWNrVG9sZXJhbmNlKSB8fCAwO1xuICAgICAgICB0aGlzLl9pc0RyYWdnaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX3N0YXRlID0gJ2luYWN0aXZlJztcbiAgICAgICAgdGhpcy5fcm90YXRpb24gPSAob3B0aW9ucyAmJiBvcHRpb25zLnJvdGF0aW9uKSB8fCAwO1xuICAgICAgICB0aGlzLl9yb3RhdGlvbkFsaWdubWVudCA9IChvcHRpb25zICYmIG9wdGlvbnMucm90YXRpb25BbGlnbm1lbnQpIHx8ICdhdXRvJztcbiAgICAgICAgdGhpcy5fcGl0Y2hBbGlnbm1lbnQgPSAob3B0aW9ucyAmJiBvcHRpb25zLnBpdGNoQWxpZ25tZW50ICYmIG9wdGlvbnMucGl0Y2hBbGlnbm1lbnQpIHx8ICdhdXRvJztcbiAgICAgICAgdGhpcy5fdXBkYXRlTW92aW5nID0gKCkgPT4gdGhpcy5fdXBkYXRlKHRydWUpO1xuICAgICAgICB0aGlzLl9vY2NsdWRlZE9wYWNpdHkgPSAob3B0aW9ucyAmJiBvcHRpb25zLm9jY2x1ZGVkT3BhY2l0eSkgfHwgMC4yO1xuXG4gICAgICAgIGlmICghb3B0aW9ucyB8fCAhb3B0aW9ucy5lbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLl9kZWZhdWx0TWFya2VyID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuX2VsZW1lbnQgPSBET00uY3JlYXRlKCdkaXYnKTtcblxuICAgICAgICAgICAgLy8gY3JlYXRlIGRlZmF1bHQgbWFwIG1hcmtlciBTVkdcblxuICAgICAgICAgICAgY29uc3QgREVGQVVMVF9IRUlHSFQgPSA0MTtcbiAgICAgICAgICAgIGNvbnN0IERFRkFVTFRfV0lEVEggPSAyNztcblxuICAgICAgICAgICAgY29uc3Qgc3ZnID0gRE9NLmNyZWF0ZVNWRygnc3ZnJywge1xuICAgICAgICAgICAgICAgIGRpc3BsYXk6ICdibG9jaycsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiBgJHtERUZBVUxUX0hFSUdIVCAqIHRoaXMuX3NjYWxlfXB4YCxcbiAgICAgICAgICAgICAgICB3aWR0aDogYCR7REVGQVVMVF9XSURUSCAqIHRoaXMuX3NjYWxlfXB4YCxcbiAgICAgICAgICAgICAgICB2aWV3Qm94OiBgMCAwICR7REVGQVVMVF9XSURUSH0gJHtERUZBVUxUX0hFSUdIVH1gXG4gICAgICAgICAgICB9LCB0aGlzLl9lbGVtZW50KTtcblxuICAgICAgICAgICAgY29uc3QgZ3JhZGllbnQgPSBET00uY3JlYXRlU1ZHKCdyYWRpYWxHcmFkaWVudCcsIHtpZDogJ3NoYWRvd0dyYWRpZW50J30sIERPTS5jcmVhdGVTVkcoJ2RlZnMnLCB7fSwgc3ZnKSk7XG4gICAgICAgICAgICBET00uY3JlYXRlU1ZHKCdzdG9wJywge29mZnNldDogJzEwJScsICdzdG9wLW9wYWNpdHknOiAwLjR9LCBncmFkaWVudCk7XG4gICAgICAgICAgICBET00uY3JlYXRlU1ZHKCdzdG9wJywge29mZnNldDogJzEwMCUnLCAnc3RvcC1vcGFjaXR5JzogMC4wNX0sIGdyYWRpZW50KTtcbiAgICAgICAgICAgIERPTS5jcmVhdGVTVkcoJ2VsbGlwc2UnLCB7Y3g6IDEzLjUsIGN5OiAzNC44LCByeDogMTAuNSwgcnk6IDUuMjUsIGZpbGw6ICd1cmwoI3NoYWRvd0dyYWRpZW50KSd9LCBzdmcpOyAvLyBzaGFkb3dcblxuICAgICAgICAgICAgRE9NLmNyZWF0ZVNWRygncGF0aCcsIHsgLy8gbWFya2VyIHNoYXBlXG4gICAgICAgICAgICAgICAgZmlsbDogdGhpcy5fY29sb3IsXG4gICAgICAgICAgICAgICAgZDogJ00yNywxMy41QzI3LDE5LjA3IDIwLjI1LDI3IDE0Ljc1LDM0LjVDMTQuMDIsMzUuNSAxMi45OCwzNS41IDEyLjI1LDM0LjVDNi43NSwyNyAwLDE5LjIyIDAsMTMuNUMwLDYuMDQgNi4wNCwwIDEzLjUsMEMyMC45NiwwIDI3LDYuMDQgMjcsMTMuNVonXG4gICAgICAgICAgICB9LCBzdmcpO1xuICAgICAgICAgICAgRE9NLmNyZWF0ZVNWRygncGF0aCcsIHsgLy8gYm9yZGVyXG4gICAgICAgICAgICAgICAgb3BhY2l0eTogMC4yNSxcbiAgICAgICAgICAgICAgICBkOiAnTTEzLjUsMEM2LjA0LDAgMCw2LjA0IDAsMTMuNUMwLDE5LjIyIDYuNzUsMjcgMTIuMjUsMzQuNUMxMywzNS41MiAxNC4wMiwzNS41IDE0Ljc1LDM0LjVDMjAuMjUsMjcgMjcsMTkuMDcgMjcsMTMuNUMyNyw2LjA0IDIwLjk2LDAgMTMuNSwwWk0xMy41LDFDMjAuNDIsMSAyNiw2LjU4IDI2LDEzLjVDMjYsMTUuOSAyNC41LDE5LjE4IDIyLjIyLDIyLjc0QzE5Ljk1LDI2LjMgMTYuNzEsMzAuMTQgMTMuOTQsMzMuOTFDMTMuNzQsMzQuMTggMTMuNjEsMzQuMzIgMTMuNSwzNC40NEMxMy4zOSwzNC4zMiAxMy4yNiwzNC4xOCAxMy4wNiwzMy45MUMxMC4yOCwzMC4xMyA3LjQxLDI2LjMxIDUuMDIsMjIuNzdDMi42MiwxOS4yMyAxLDE1Ljk1IDEsMTMuNUMxLDYuNTggNi41OCwxIDEzLjUsMVonXG4gICAgICAgICAgICB9LCBzdmcpO1xuXG4gICAgICAgICAgICBET00uY3JlYXRlU1ZHKCdjaXJjbGUnLCB7ZmlsbDogJ3doaXRlJywgY3g6IDEzLjUsIGN5OiAxMy41LCByOiA1LjV9LCBzdmcpOyAvLyBjaXJjbGVcblxuICAgICAgICAgICAgLy8gaWYgbm8gZWxlbWVudCBhbmQgbm8gb2Zmc2V0IG9wdGlvbiBnaXZlbiBhcHBseSBhbiBvZmZzZXQgZm9yIHRoZSBkZWZhdWx0IG1hcmtlclxuICAgICAgICAgICAgLy8gdGhlIC0xNCBhcyB0aGUgeSB2YWx1ZSBvZiB0aGUgZGVmYXVsdCBtYXJrZXIgb2Zmc2V0IHdhcyBkZXRlcm1pbmVkIGFzIGZvbGxvd3NcbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyB0aGUgbWFya2VyIHRpcCBpcyBhdCB0aGUgY2VudGVyIG9mIHRoZSBzaGFkb3cgZWxsaXBzZSBmcm9tIHRoZSBkZWZhdWx0IHN2Z1xuICAgICAgICAgICAgLy8gdGhlIHkgdmFsdWUgb2YgdGhlIGNlbnRlciBvZiB0aGUgc2hhZG93IGVsbGlwc2UgcmVsYXRpdmUgdG8gdGhlIHN2ZyB0b3AgbGVmdCBpcyAzNC44XG4gICAgICAgICAgICAvLyBvZmZzZXQgdG8gdGhlIHN2ZyBjZW50ZXIgXCJoZWlnaHQgKDQxIC8gMilcIiBnaXZlcyAzNC44IC0gKDQxIC8gMikgYW5kIHJvdW5kZWQgZm9yIGFuIGludGVnZXIgcGl4ZWwgb2Zmc2V0IGdpdmVzIDE0XG4gICAgICAgICAgICAvLyBuZWdhdGl2ZSBpcyB1c2VkIHRvIG1vdmUgdGhlIG1hcmtlciB1cCBmcm9tIHRoZSBjZW50ZXIgc28gdGhlIHRpcCBpcyBhdCB0aGUgTWFya2VyIGxuZ0xhdFxuICAgICAgICAgICAgdGhpcy5fb2Zmc2V0ID0gUG9pbnQuY29udmVydCgob3B0aW9ucyAmJiBvcHRpb25zLm9mZnNldCkgfHwgWzAsIC0xNF0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fZWxlbWVudCA9IG9wdGlvbnMuZWxlbWVudDtcbiAgICAgICAgICAgIHRoaXMuX29mZnNldCA9IFBvaW50LmNvbnZlcnQoKG9wdGlvbnMgJiYgb3B0aW9ucy5vZmZzZXQpIHx8IFswLCAwXSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuX2VsZW1lbnQuaGFzQXR0cmlidXRlKCdhcmlhLWxhYmVsJykpIHRoaXMuX2VsZW1lbnQuc2V0QXR0cmlidXRlKCdhcmlhLWxhYmVsJywgJ01hcCBtYXJrZXInKTtcbiAgICAgICAgdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QuYWRkKCdtYXBib3hnbC1tYXJrZXInKTtcbiAgICAgICAgdGhpcy5fZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdkcmFnc3RhcnQnLCAoZTogRHJhZ0V2ZW50KSA9PiB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIChlOiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICAgICAgICAvLyBwcmV2ZW50IGZvY3VzaW5nIG9uIGNsaWNrXG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjbGFzc0xpc3QgPSB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdDtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gYW5jaG9yVHJhbnNsYXRlKSB7XG4gICAgICAgICAgICBjbGFzc0xpc3QucmVtb3ZlKGBtYXBib3hnbC1tYXJrZXItYW5jaG9yLSR7a2V5fWApO1xuICAgICAgICB9XG4gICAgICAgIGNsYXNzTGlzdC5hZGQoYG1hcGJveGdsLW1hcmtlci1hbmNob3ItJHt0aGlzLl9hbmNob3J9YCk7XG5cbiAgICAgICAgdGhpcy5fcG9wdXAgPSBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEF0dGFjaGVzIHRoZSBgTWFya2VyYCB0byBhIGBNYXBgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7TWFwfSBtYXAgVGhlIE1hcGJveCBHTCBKUyBtYXAgdG8gYWRkIHRoZSBtYXJrZXIgdG8uXG4gICAgICogQHJldHVybnMge01hcmtlcn0gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG1hcmtlciA9IG5ldyBtYXBib3hnbC5NYXJrZXIoKVxuICAgICAqICAgICAuc2V0TG5nTGF0KFszMC41LCA1MC41XSlcbiAgICAgKiAgICAgLmFkZFRvKG1hcCk7IC8vIGFkZCB0aGUgbWFya2VyIHRvIHRoZSBtYXBcbiAgICAgKi9cbiAgICBhZGRUbyhtYXA6IE1hcCk6IHRoaXMge1xuICAgICAgICBpZiAobWFwID09PSB0aGlzLl9tYXApIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVtb3ZlKCk7XG4gICAgICAgIHRoaXMuX21hcCA9IG1hcDtcbiAgICAgICAgbWFwLmdldENhbnZhc0NvbnRhaW5lcigpLmFwcGVuZENoaWxkKHRoaXMuX2VsZW1lbnQpO1xuICAgICAgICBtYXAub24oJ21vdmUnLCB0aGlzLl91cGRhdGVNb3ZpbmcpO1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIG1hcC5vbignbW92ZWVuZCcsIHRoaXMuX3VwZGF0ZSk7XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgbWFwLm9uKCdyZW1vdmUnLCB0aGlzLl9jbGVhckZhZGVUaW1lcik7XG4gICAgICAgIG1hcC5fYWRkTWFya2VyKHRoaXMpO1xuICAgICAgICB0aGlzLnNldERyYWdnYWJsZSh0aGlzLl9kcmFnZ2FibGUpO1xuICAgICAgICB0aGlzLl91cGRhdGUoKTtcblxuICAgICAgICAvLyBJZiB3ZSBhdHRhY2hlZCB0aGUgYGNsaWNrYCBsaXN0ZW5lciB0byB0aGUgbWFya2VyIGVsZW1lbnQsIHRoZSBwb3B1cFxuICAgICAgICAvLyB3b3VsZCBjbG9zZSBvbmNlIHRoZSBldmVudCBwcm9wb2dhdGVkIHRvIGBtYXBgIGR1ZSB0byB0aGVcbiAgICAgICAgLy8gYFBvcHVwI19vbkNsaWNrQ2xvc2VgIGxpc3RlbmVyLlxuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIG1hcC5vbignY2xpY2snLCB0aGlzLl9vbk1hcENsaWNrKTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIHRoZSBtYXJrZXIgZnJvbSBhIG1hcC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgbWFya2VyID0gbmV3IG1hcGJveGdsLk1hcmtlcigpLmFkZFRvKG1hcCk7XG4gICAgICogbWFya2VyLnJlbW92ZSgpO1xuICAgICAqIEByZXR1cm5zIHtNYXJrZXJ9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcmVtb3ZlKCk6IHRoaXMge1xuICAgICAgICBjb25zdCBtYXAgPSB0aGlzLl9tYXA7XG4gICAgICAgIGlmIChtYXApIHtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIG1hcC5vZmYoJ2NsaWNrJywgdGhpcy5fb25NYXBDbGljayk7XG4gICAgICAgICAgICBtYXAub2ZmKCdtb3ZlJywgdGhpcy5fdXBkYXRlTW92aW5nKTtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIG1hcC5vZmYoJ21vdmVlbmQnLCB0aGlzLl91cGRhdGUpO1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgbWFwLm9mZignbW91c2Vkb3duJywgdGhpcy5fYWRkRHJhZ0hhbmRsZXIpO1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgbWFwLm9mZigndG91Y2hzdGFydCcsIHRoaXMuX2FkZERyYWdIYW5kbGVyKTtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIG1hcC5vZmYoJ21vdXNldXAnLCB0aGlzLl9vblVwKTtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIG1hcC5vZmYoJ3RvdWNoZW5kJywgdGhpcy5fb25VcCk7XG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICBtYXAub2ZmKCdtb3VzZW1vdmUnLCB0aGlzLl9vbk1vdmUpO1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgbWFwLm9mZigndG91Y2htb3ZlJywgdGhpcy5fb25Nb3ZlKTtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIG1hcC5vZmYoJ3JlbW92ZScsIHRoaXMuX2NsZWFyRmFkZVRpbWVyKTtcbiAgICAgICAgICAgIG1hcC5fcmVtb3ZlTWFya2VyKHRoaXMpO1xuICAgICAgICAgICAgdGhpcy5fbWFwID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2NsZWFyRmFkZVRpbWVyKCk7XG4gICAgICAgIHRoaXMuX2VsZW1lbnQucmVtb3ZlKCk7XG4gICAgICAgIGlmICh0aGlzLl9wb3B1cCkgdGhpcy5fcG9wdXAucmVtb3ZlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgbWFya2VyJ3MgZ2VvZ3JhcGhpY2FsIGxvY2F0aW9uLlxuICAgICAqXG4gICAgICogVGhlIGxvbmdpdHVkZSBvZiB0aGUgcmVzdWx0IG1heSBkaWZmZXIgYnkgYSBtdWx0aXBsZSBvZiAzNjAgZGVncmVlcyBmcm9tIHRoZSBsb25naXR1ZGUgcHJldmlvdXNseVxuICAgICAqIHNldCBieSBgc2V0TG5nTGF0YCBiZWNhdXNlIGBNYXJrZXJgIHdyYXBzIHRoZSBhbmNob3IgbG9uZ2l0dWRlIGFjcm9zcyBjb3BpZXMgb2YgdGhlIHdvcmxkIHRvIGtlZXBcbiAgICAgKiB0aGUgbWFya2VyIG9uIHNjcmVlbi5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtMbmdMYXR9IEEge0BsaW5rIExuZ0xhdH0gZGVzY3JpYmluZyB0aGUgbWFya2VyJ3MgbG9jYXRpb24uXG4gICAgKiBAZXhhbXBsZVxuICAgICogLy8gU3RvcmUgdGhlIG1hcmtlcidzIGxvbmdpdHVkZSBhbmQgbGF0aXR1ZGUgY29vcmRpbmF0ZXMgaW4gYSB2YXJpYWJsZVxuICAgICogY29uc3QgbG5nTGF0ID0gbWFya2VyLmdldExuZ0xhdCgpO1xuICAgICogLy8gUHJpbnQgdGhlIG1hcmtlcidzIGxvbmdpdHVkZSBhbmQgbGF0aXR1ZGUgdmFsdWVzIGluIHRoZSBjb25zb2xlXG4gICAgKiBjb25zb2xlLmxvZyhgTG9uZ2l0dWRlOiAke2xuZ0xhdC5sbmd9LCBMYXRpdHVkZTogJHtsbmdMYXQubGF0fWApO1xuICAgICogQHNlZSBbRXhhbXBsZTogQ3JlYXRlIGEgZHJhZ2dhYmxlIE1hcmtlcl0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvZHJhZy1hLW1hcmtlci8pXG4gICAgKi9cbiAgICBnZXRMbmdMYXQoKTogTG5nTGF0IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xuZ0xhdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIFNldCB0aGUgbWFya2VyJ3MgZ2VvZ3JhcGhpY2FsIHBvc2l0aW9uIGFuZCBtb3ZlIGl0LlxuICAgICAqXG4gICAgKiBAcGFyYW0ge0xuZ0xhdH0gbG5nbGF0IEEge0BsaW5rIExuZ0xhdH0gZGVzY3JpYmluZyB3aGVyZSB0aGUgbWFya2VyIHNob3VsZCBiZSBsb2NhdGVkLlxuICAgICogQHJldHVybnMge01hcmtlcn0gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAqIEBleGFtcGxlXG4gICAgKiAvLyBDcmVhdGUgYSBuZXcgbWFya2VyLCBzZXQgdGhlIGxvbmdpdHVkZSBhbmQgbGF0aXR1ZGUsIGFuZCBhZGQgaXQgdG8gdGhlIG1hcC5cbiAgICAqIG5ldyBtYXBib3hnbC5NYXJrZXIoKVxuICAgICogICAgIC5zZXRMbmdMYXQoWy02NS4wMTcsIC0xNi40NTddKVxuICAgICogICAgIC5hZGRUbyhtYXApO1xuICAgICogQHNlZSBbRXhhbXBsZTogQWRkIGN1c3RvbSBpY29ucyB3aXRoIE1hcmtlcnNdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2N1c3RvbS1tYXJrZXItaWNvbnMvKVxuICAgICogQHNlZSBbRXhhbXBsZTogQ3JlYXRlIGEgZHJhZ2dhYmxlIE1hcmtlcl0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvZHJhZy1hLW1hcmtlci8pXG4gICAgKiBAc2VlIFtFeGFtcGxlOiBBZGQgYSBtYXJrZXIgdXNpbmcgYSBwbGFjZSBuYW1lXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9tYXJrZXItZnJvbS1nZW9jb2RlLylcbiAgICAqL1xuICAgIHNldExuZ0xhdChsbmdsYXQ6IExuZ0xhdExpa2UpOiB0aGlzIHtcbiAgICAgICAgdGhpcy5fbG5nTGF0ID0gTG5nTGF0LmNvbnZlcnQobG5nbGF0KTtcbiAgICAgICAgdGhpcy5fcG9zID0gbnVsbDtcbiAgICAgICAgaWYgKHRoaXMuX3BvcHVwKSB0aGlzLl9wb3B1cC5zZXRMbmdMYXQodGhpcy5fbG5nTGF0KTtcbiAgICAgICAgdGhpcy5fdXBkYXRlKHRydWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBgTWFya2VyYCdzIEhUTUwgZWxlbWVudC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtIVE1MRWxlbWVudH0gUmV0dXJucyB0aGUgbWFya2VyIGVsZW1lbnQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBlbGVtZW50ID0gbWFya2VyLmdldEVsZW1lbnQoKTtcbiAgICAgKi9cbiAgICBnZXRFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VsZW1lbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQmluZHMgYSB7QGxpbmsgUG9wdXB9IHRvIHRoZSB7QGxpbmsgTWFya2VyfS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7UG9wdXAgfCBudWxsfSBwb3B1cCBBbiBpbnN0YW5jZSBvZiB0aGUge0BsaW5rIFBvcHVwfSBjbGFzcy4gSWYgdW5kZWZpbmVkIG9yIG51bGwsIGFueSBwb3B1cFxuICAgICAqIHNldCBvbiB0aGlzIHtAbGluayBNYXJrZXJ9IGluc3RhbmNlIGlzIHVuc2V0LlxuICAgICAqIEByZXR1cm5zIHtNYXJrZXJ9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBtYXJrZXIgPSBuZXcgbWFwYm94Z2wuTWFya2VyKClcbiAgICAgKiAgICAgLnNldExuZ0xhdChbMCwgMF0pXG4gICAgICogICAgIC5zZXRQb3B1cChuZXcgbWFwYm94Z2wuUG9wdXAoKS5zZXRIVE1MKFwiPGgxPkhlbGxvIFdvcmxkITwvaDE+XCIpKSAvLyBhZGQgcG9wdXBcbiAgICAgKiAgICAgLmFkZFRvKG1hcCk7XG4gICAgICogQHNlZSBbRXhhbXBsZTogQXR0YWNoIGEgcG9wdXAgdG8gYSBtYXJrZXIgaW5zdGFuY2VdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL3NldC1wb3B1cC8pXG4gICAgICovXG4gICAgc2V0UG9wdXAocG9wdXA6ID9Qb3B1cCk6IHRoaXMge1xuICAgICAgICBpZiAodGhpcy5fcG9wdXApIHtcbiAgICAgICAgICAgIHRoaXMuX3BvcHVwLnJlbW92ZSgpO1xuICAgICAgICAgICAgdGhpcy5fcG9wdXAgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5fZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoJ3JvbGUnKTtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIHRoaXMuX2VsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5cHJlc3MnLCB0aGlzLl9vbktleVByZXNzKTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLl9vcmlnaW5hbFRhYkluZGV4KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoJ3RhYmluZGV4Jyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocG9wdXApIHtcbiAgICAgICAgICAgIGlmICghKCdvZmZzZXQnIGluIHBvcHVwLm9wdGlvbnMpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbWFya2VySGVpZ2h0ID0gNDEgLSAoNS44IC8gMik7XG4gICAgICAgICAgICAgICAgY29uc3QgbWFya2VyUmFkaXVzID0gMTMuNTtcbiAgICAgICAgICAgICAgICBjb25zdCBsaW5lYXJPZmZzZXQgPSBNYXRoLnNxcnQoTWF0aC5wb3cobWFya2VyUmFkaXVzLCAyKSAvIDIpO1xuICAgICAgICAgICAgICAgIHBvcHVwLm9wdGlvbnMub2Zmc2V0ID0gdGhpcy5fZGVmYXVsdE1hcmtlciA/IHtcbiAgICAgICAgICAgICAgICAgICAgJ3RvcCc6IFswLCAwXSxcbiAgICAgICAgICAgICAgICAgICAgJ3RvcC1sZWZ0JzogWzAsIDBdLFxuICAgICAgICAgICAgICAgICAgICAndG9wLXJpZ2h0JzogWzAsIDBdLFxuICAgICAgICAgICAgICAgICAgICAnYm90dG9tJzogWzAsIC1tYXJrZXJIZWlnaHRdLFxuICAgICAgICAgICAgICAgICAgICAnYm90dG9tLWxlZnQnOiBbbGluZWFyT2Zmc2V0LCAobWFya2VySGVpZ2h0IC0gbWFya2VyUmFkaXVzICsgbGluZWFyT2Zmc2V0KSAqIC0xXSxcbiAgICAgICAgICAgICAgICAgICAgJ2JvdHRvbS1yaWdodCc6IFstbGluZWFyT2Zmc2V0LCAobWFya2VySGVpZ2h0IC0gbWFya2VyUmFkaXVzICsgbGluZWFyT2Zmc2V0KSAqIC0xXSxcbiAgICAgICAgICAgICAgICAgICAgJ2xlZnQnOiBbbWFya2VyUmFkaXVzLCAobWFya2VySGVpZ2h0IC0gbWFya2VyUmFkaXVzKSAqIC0xXSxcbiAgICAgICAgICAgICAgICAgICAgJ3JpZ2h0JzogWy1tYXJrZXJSYWRpdXMsIChtYXJrZXJIZWlnaHQgLSBtYXJrZXJSYWRpdXMpICogLTFdXG4gICAgICAgICAgICAgICAgfSA6IHRoaXMuX29mZnNldDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX3BvcHVwID0gcG9wdXA7XG4gICAgICAgICAgICBwb3B1cC5fbWFya2VyID0gdGhpcztcbiAgICAgICAgICAgIGlmICh0aGlzLl9sbmdMYXQpIHRoaXMuX3BvcHVwLnNldExuZ0xhdCh0aGlzLl9sbmdMYXQpO1xuXG4gICAgICAgICAgICB0aGlzLl9lbGVtZW50LnNldEF0dHJpYnV0ZSgncm9sZScsICdidXR0b24nKTtcbiAgICAgICAgICAgIHRoaXMuX29yaWdpbmFsVGFiSW5kZXggPSB0aGlzLl9lbGVtZW50LmdldEF0dHJpYnV0ZSgndGFiaW5kZXgnKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5fb3JpZ2luYWxUYWJJbmRleCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2VsZW1lbnQuc2V0QXR0cmlidXRlKCd0YWJpbmRleCcsICcwJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICB0aGlzLl9lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2tleXByZXNzJywgdGhpcy5fb25LZXlQcmVzcyk7XG4gICAgICAgICAgICB0aGlzLl9lbGVtZW50LnNldEF0dHJpYnV0ZSgnYXJpYS1leHBhbmRlZCcsICdmYWxzZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgX29uS2V5UHJlc3MoZTogS2V5Ym9hcmRFdmVudCkge1xuICAgICAgICBjb25zdCBjb2RlID0gZS5jb2RlO1xuICAgICAgICBjb25zdCBsZWdhY3lDb2RlID0gZS5jaGFyQ29kZSB8fCBlLmtleUNvZGU7XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgKGNvZGUgPT09ICdTcGFjZScpIHx8IChjb2RlID09PSAnRW50ZXInKSB8fFxuICAgICAgICAgICAgKGxlZ2FjeUNvZGUgPT09IDMyKSB8fCAobGVnYWN5Q29kZSA9PT0gMTMpIC8vIHNwYWNlIG9yIGVudGVyXG4gICAgICAgICkge1xuICAgICAgICAgICAgdGhpcy50b2dnbGVQb3B1cCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX29uTWFwQ2xpY2soZTogTWFwTW91c2VFdmVudCkge1xuICAgICAgICBjb25zdCB0YXJnZXRFbGVtZW50ID0gZS5vcmlnaW5hbEV2ZW50LnRhcmdldDtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX2VsZW1lbnQ7XG5cbiAgICAgICAgaWYgKHRoaXMuX3BvcHVwICYmICh0YXJnZXRFbGVtZW50ID09PSBlbGVtZW50IHx8IGVsZW1lbnQuY29udGFpbnMoKHRhcmdldEVsZW1lbnQ6IGFueSkpKSkge1xuICAgICAgICAgICAgdGhpcy50b2dnbGVQb3B1cCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUge0BsaW5rIFBvcHVwfSBpbnN0YW5jZSB0aGF0IGlzIGJvdW5kIHRvIHRoZSB7QGxpbmsgTWFya2VyfS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtQb3B1cH0gUmV0dXJucyB0aGUgcG9wdXAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBtYXJrZXIgPSBuZXcgbWFwYm94Z2wuTWFya2VyKClcbiAgICAgKiAgICAgLnNldExuZ0xhdChbMCwgMF0pXG4gICAgICogICAgIC5zZXRQb3B1cChuZXcgbWFwYm94Z2wuUG9wdXAoKS5zZXRIVE1MKFwiPGgxPkhlbGxvIFdvcmxkITwvaDE+XCIpKVxuICAgICAqICAgICAuYWRkVG8obWFwKTtcbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKG1hcmtlci5nZXRQb3B1cCgpKTsgLy8gcmV0dXJuIHRoZSBwb3B1cCBpbnN0YW5jZVxuICAgICAqL1xuICAgIGdldFBvcHVwKCk6ID9Qb3B1cCB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wb3B1cDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPcGVucyBvciBjbG9zZXMgdGhlIHtAbGluayBQb3B1cH0gaW5zdGFuY2UgdGhhdCBpcyBib3VuZCB0byB0aGUge0BsaW5rIE1hcmtlcn0sIGRlcGVuZGluZyBvbiB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUge0BsaW5rIFBvcHVwfS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtNYXJrZXJ9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBtYXJrZXIgPSBuZXcgbWFwYm94Z2wuTWFya2VyKClcbiAgICAgKiAgICAgLnNldExuZ0xhdChbMCwgMF0pXG4gICAgICogICAgIC5zZXRQb3B1cChuZXcgbWFwYm94Z2wuUG9wdXAoKS5zZXRIVE1MKFwiPGgxPkhlbGxvIFdvcmxkITwvaDE+XCIpKVxuICAgICAqICAgICAuYWRkVG8obWFwKTtcbiAgICAgKlxuICAgICAqIG1hcmtlci50b2dnbGVQb3B1cCgpOyAvLyB0b2dnbGUgcG9wdXAgb3BlbiBvciBjbG9zZWRcbiAgICAgKi9cbiAgICB0b2dnbGVQb3B1cCgpOiB0aGlzIHtcbiAgICAgICAgY29uc3QgcG9wdXAgPSB0aGlzLl9wb3B1cDtcbiAgICAgICAgaWYgKCFwb3B1cCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0gZWxzZSBpZiAocG9wdXAuaXNPcGVuKCkpIHtcbiAgICAgICAgICAgIHBvcHVwLnJlbW92ZSgpO1xuICAgICAgICAgICAgdGhpcy5fZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2FyaWEtZXhwYW5kZWQnLCAnZmFsc2UnKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9tYXApIHtcbiAgICAgICAgICAgIHBvcHVwLmFkZFRvKHRoaXMuX21hcCk7XG4gICAgICAgICAgICB0aGlzLl9lbGVtZW50LnNldEF0dHJpYnV0ZSgnYXJpYS1leHBhbmRlZCcsICd0cnVlJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgX2JlaGluZFRlcnJhaW4oKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IG1hcCA9IHRoaXMuX21hcDtcbiAgICAgICAgY29uc3QgcG9zID0gdGhpcy5fcG9zO1xuICAgICAgICBpZiAoIW1hcCB8fCAhcG9zKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGNvbnN0IHVucHJvamVjdGVkID0gbWFwLnVucHJvamVjdChwb3MpO1xuICAgICAgICBjb25zdCBjYW1lcmEgPSBtYXAuZ2V0RnJlZUNhbWVyYU9wdGlvbnMoKTtcbiAgICAgICAgaWYgKCFjYW1lcmEucG9zaXRpb24pIHJldHVybiBmYWxzZTtcbiAgICAgICAgY29uc3QgY2FtZXJhTG5nTGF0ID0gY2FtZXJhLnBvc2l0aW9uLnRvTG5nTGF0KCk7XG4gICAgICAgIGNvbnN0IHRvQ2xvc2VzdFN1cmZhY2UgPSBjYW1lcmFMbmdMYXQuZGlzdGFuY2VUbyh1bnByb2plY3RlZCk7XG4gICAgICAgIGNvbnN0IHRvTWFya2VyID0gY2FtZXJhTG5nTGF0LmRpc3RhbmNlVG8odGhpcy5fbG5nTGF0KTtcbiAgICAgICAgcmV0dXJuIHRvQ2xvc2VzdFN1cmZhY2UgPCB0b01hcmtlciAqIDAuOTtcblxuICAgIH1cblxuICAgIF9ldmFsdWF0ZU9wYWNpdHkoKSB7XG4gICAgICAgIGNvbnN0IG1hcCA9IHRoaXMuX21hcDtcbiAgICAgICAgaWYgKCFtYXApIHJldHVybjtcblxuICAgICAgICBjb25zdCBwb3MgPSB0aGlzLl9wb3M7XG5cbiAgICAgICAgaWYgKCFwb3MgfHwgcG9zLnggPCAwIHx8IHBvcy54ID4gbWFwLnRyYW5zZm9ybS53aWR0aCB8fCBwb3MueSA8IDAgfHwgcG9zLnkgPiBtYXAudHJhbnNmb3JtLmhlaWdodCkge1xuICAgICAgICAgICAgdGhpcy5fY2xlYXJGYWRlVGltZXIoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBtYXBMb2NhdGlvbiA9IG1hcC51bnByb2plY3QocG9zKTtcbiAgICAgICAgbGV0IG9wYWNpdHk7XG4gICAgICAgIGlmIChtYXAuX3Nob3dpbmdHbG9iZSgpICYmIGlzTG5nTGF0QmVoaW5kR2xvYmUobWFwLnRyYW5zZm9ybSwgdGhpcy5fbG5nTGF0KSkge1xuICAgICAgICAgICAgb3BhY2l0eSA9IDA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBvcGFjaXR5ID0gMSAtIG1hcC5fcXVlcnlGb2dPcGFjaXR5KG1hcExvY2F0aW9uKTtcbiAgICAgICAgICAgIGlmIChtYXAudHJhbnNmb3JtLl90ZXJyYWluRW5hYmxlZCgpICYmIG1hcC5nZXRUZXJyYWluKCkgJiYgdGhpcy5fYmVoaW5kVGVycmFpbigpKSB7XG4gICAgICAgICAgICAgICAgb3BhY2l0eSAqPSB0aGlzLl9vY2NsdWRlZE9wYWNpdHk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9lbGVtZW50LnN0eWxlLm9wYWNpdHkgPSBgJHtvcGFjaXR5fWA7XG4gICAgICAgIHRoaXMuX2VsZW1lbnQuc3R5bGUucG9pbnRlckV2ZW50cyA9IG9wYWNpdHkgPiAwID8gJ2F1dG8nIDogJ25vbmUnO1xuICAgICAgICBpZiAodGhpcy5fcG9wdXApIHtcbiAgICAgICAgICAgIHRoaXMuX3BvcHVwLl9zZXRPcGFjaXR5KG9wYWNpdHkpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fZmFkZVRpbWVyID0gbnVsbDtcbiAgICB9XG5cbiAgICBfY2xlYXJGYWRlVGltZXIoKSB7XG4gICAgICAgIGlmICh0aGlzLl9mYWRlVGltZXIpIHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLl9mYWRlVGltZXIpO1xuICAgICAgICAgICAgdGhpcy5fZmFkZVRpbWVyID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF91cGRhdGVET00oKSB7XG4gICAgICAgIGNvbnN0IHBvcyA9IHRoaXMuX3BvcztcbiAgICAgICAgY29uc3QgbWFwID0gdGhpcy5fbWFwO1xuICAgICAgICBpZiAoIXBvcyB8fCAhbWFwKSB7IHJldHVybjsgfVxuXG4gICAgICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuX29mZnNldC5tdWx0KHRoaXMuX3NjYWxlKTtcblxuICAgICAgICB0aGlzLl9lbGVtZW50LnN0eWxlLnRyYW5zZm9ybSA9IGBcbiAgICAgICAgICAgIHRyYW5zbGF0ZSgke3Bvcy54fXB4LCR7cG9zLnl9cHgpXG4gICAgICAgICAgICAke2FuY2hvclRyYW5zbGF0ZVt0aGlzLl9hbmNob3JdfVxuICAgICAgICAgICAgJHt0aGlzLl9jYWxjdWxhdGVYWVRyYW5zZm9ybSgpfSAke3RoaXMuX2NhbGN1bGF0ZVpUcmFuc2Zvcm0oKX1cbiAgICAgICAgICAgIHRyYW5zbGF0ZSgke29mZnNldC54fXB4LCR7b2Zmc2V0Lnl9cHgpXG4gICAgICAgIGA7XG4gICAgfVxuXG4gICAgX2NhbGN1bGF0ZVhZVHJhbnNmb3JtKCk6IHN0cmluZyB7XG4gICAgICAgIGNvbnN0IHBvcyA9IHRoaXMuX3BvcztcbiAgICAgICAgY29uc3QgbWFwID0gdGhpcy5fbWFwO1xuICAgICAgICBjb25zdCBhbGlnbm1lbnQgPSB0aGlzLmdldFBpdGNoQWxpZ25tZW50KCk7XG5cbiAgICAgICAgLy8gYHZpZXdwb3J0JywgJ2F1dG8nIGFuZCBpbnZhbGlkIGFydWdtZW50cyBkbyBubyBwaXRjaCB0cmFuc2Zvcm1hdGlvbi5cbiAgICAgICAgaWYgKCFtYXAgfHwgIXBvcyB8fCBhbGlnbm1lbnQgIT09ICdtYXAnKSB7XG4gICAgICAgICAgICByZXR1cm4gYGA7XG4gICAgICAgIH1cbiAgICAgICAgLy8gJ21hcCcgYWxpZ25tZW50IG9uIGEgZmxhdCBtYXBcbiAgICAgICAgaWYgKCFtYXAuX3Nob3dpbmdHbG9iZSgpKSB7XG4gICAgICAgICAgICBjb25zdCBwaXRjaCA9IG1hcC5nZXRQaXRjaCgpO1xuICAgICAgICAgICAgcmV0dXJuIHBpdGNoID8gYHJvdGF0ZVgoJHtwaXRjaH1kZWcpYCA6ICcnO1xuICAgICAgICB9XG4gICAgICAgIC8vICdtYXAnIGFsaWdubWVudCBvbiBnbG9iZVxuICAgICAgICBjb25zdCB0aWx0ID0gcmFkVG9EZWcoZ2xvYmVUaWx0QXRMbmdMYXQobWFwLnRyYW5zZm9ybSwgdGhpcy5fbG5nTGF0KSk7XG4gICAgICAgIGNvbnN0IHBvc0Zyb21DZW50ZXIgPSBwb3Muc3ViKGdsb2JlQ2VudGVyVG9TY3JlZW5Qb2ludChtYXAudHJhbnNmb3JtKSk7XG4gICAgICAgIGNvbnN0IG1hbmhhdHRhbkRpc3RhbmNlID0gKE1hdGguYWJzKHBvc0Zyb21DZW50ZXIueCkgKyBNYXRoLmFicyhwb3NGcm9tQ2VudGVyLnkpKTtcbiAgICAgICAgaWYgKG1hbmhhdHRhbkRpc3RhbmNlID09PSAwKSB7IHJldHVybiAnJzsgfVxuXG4gICAgICAgIGNvbnN0IHRpbHRPdmVyRGlzdCA9ICB0aWx0IC8gbWFuaGF0dGFuRGlzdGFuY2U7XG4gICAgICAgIGNvbnN0IHlUaWx0ID0gcG9zRnJvbUNlbnRlci54ICogdGlsdE92ZXJEaXN0O1xuICAgICAgICBjb25zdCB4VGlsdCA9IC1wb3NGcm9tQ2VudGVyLnkgKiB0aWx0T3ZlckRpc3Q7XG4gICAgICAgIHJldHVybiBgcm90YXRlWCgke3hUaWx0fWRlZykgcm90YXRlWSgke3lUaWx0fWRlZylgO1xuXG4gICAgfVxuXG4gICAgX2NhbGN1bGF0ZVpUcmFuc2Zvcm0oKTogc3RyaW5nIHtcblxuICAgICAgICBjb25zdCBwb3MgPSB0aGlzLl9wb3M7XG4gICAgICAgIGNvbnN0IG1hcCA9IHRoaXMuX21hcDtcbiAgICAgICAgaWYgKCFtYXAgfHwgIXBvcykgeyByZXR1cm4gJyc7IH1cblxuICAgICAgICBsZXQgcm90YXRpb24gPSAwO1xuICAgICAgICBjb25zdCBhbGlnbm1lbnQgPSB0aGlzLmdldFJvdGF0aW9uQWxpZ25tZW50KCk7XG4gICAgICAgIGlmIChhbGlnbm1lbnQgPT09ICdtYXAnKSB7XG4gICAgICAgICAgICBpZiAobWFwLl9zaG93aW5nR2xvYmUoKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5vcnRoID0gbWFwLnByb2plY3QobmV3IExuZ0xhdCh0aGlzLl9sbmdMYXQubG5nLCB0aGlzLl9sbmdMYXQubGF0ICsgLjAwMSkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHNvdXRoID0gbWFwLnByb2plY3QobmV3IExuZ0xhdCh0aGlzLl9sbmdMYXQubG5nLCB0aGlzLl9sbmdMYXQubGF0IC0gLjAwMSkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGRpZmYgPSBzb3V0aC5zdWIobm9ydGgpO1xuICAgICAgICAgICAgICAgIHJvdGF0aW9uID0gcmFkVG9EZWcoTWF0aC5hdGFuMihkaWZmLnksIGRpZmYueCkpIC0gOTA7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJvdGF0aW9uID0gLW1hcC5nZXRCZWFyaW5nKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoYWxpZ25tZW50ID09PSAnaG9yaXpvbicpIHtcbiAgICAgICAgICAgIGNvbnN0IEFMSUdOX1RPX0hPUklaT05fQkVMT1dfWk9PTSA9IDQ7XG4gICAgICAgICAgICBjb25zdCBBTElHTl9UT19TQ1JFRU5fQUJPVkVfWk9PTSA9IDY7XG4gICAgICAgICAgICBhc3NlcnQoQUxJR05fVE9fU0NSRUVOX0FCT1ZFX1pPT00gPD0gR0xPQkVfWk9PTV9USFJFU0hPTERfTUFYLCAnSG9yaXpvbi1vcmllbnRlZCBtYXJrZXIgdHJhbnNpdGlvbiBzaG91bGQgYmUgY29tcGxldGUgd2hlbiBnbG9iZSBzd2l0Y2hlcyB0byBNZXJjYXRvcicpO1xuICAgICAgICAgICAgYXNzZXJ0KEFMSUdOX1RPX0hPUklaT05fQkVMT1dfWk9PTSA8PSBBTElHTl9UT19TQ1JFRU5fQUJPVkVfWk9PTSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHNtb290aCA9IHNtb290aHN0ZXAoQUxJR05fVE9fSE9SSVpPTl9CRUxPV19aT09NLCBBTElHTl9UT19TQ1JFRU5fQUJPVkVfWk9PTSwgbWFwLmdldFpvb20oKSk7XG5cbiAgICAgICAgICAgIGNvbnN0IGNlbnRlclBvaW50ID0gZ2xvYmVDZW50ZXJUb1NjcmVlblBvaW50KG1hcC50cmFuc2Zvcm0pO1xuICAgICAgICAgICAgY2VudGVyUG9pbnQueSArPSBzbW9vdGggKiBtYXAudHJhbnNmb3JtLmhlaWdodDtcbiAgICAgICAgICAgIGNvbnN0IHJlbCA9IHBvcy5zdWIoY2VudGVyUG9pbnQpO1xuICAgICAgICAgICAgY29uc3QgYW5nbGUgPSByYWRUb0RlZyhNYXRoLmF0YW4yKHJlbC55LCByZWwueCkpO1xuICAgICAgICAgICAgY29uc3QgdXAgPSBhbmdsZSA+IDkwID8gYW5nbGUgLSAyNzAgOiBhbmdsZSArIDkwO1xuICAgICAgICAgICAgcm90YXRpb24gPSB1cCAqICgxIC0gc21vb3RoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJvdGF0aW9uICs9IHRoaXMuX3JvdGF0aW9uO1xuICAgICAgICByZXR1cm4gcm90YXRpb24gPyBgcm90YXRlWigke3JvdGF0aW9ufWRlZylgIDogJyc7XG4gICAgfVxuXG4gICAgX3VwZGF0ZShkZWxheVNuYXA/OiBib29sZWFuKSB7XG4gICAgICAgIHdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLl91cGRhdGVGcmFtZUlkKTtcbiAgICAgICAgY29uc3QgbWFwID0gdGhpcy5fbWFwO1xuICAgICAgICBpZiAoIW1hcCkgcmV0dXJuO1xuXG4gICAgICAgIGlmIChtYXAudHJhbnNmb3JtLnJlbmRlcldvcmxkQ29waWVzKSB7XG4gICAgICAgICAgICB0aGlzLl9sbmdMYXQgPSBzbWFydFdyYXAodGhpcy5fbG5nTGF0LCB0aGlzLl9wb3MsIG1hcC50cmFuc2Zvcm0pO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fcG9zID0gbWFwLnByb2plY3QodGhpcy5fbG5nTGF0KTtcblxuICAgICAgICAvLyBiZWNhdXNlIHJvdW5kaW5nIHRoZSBjb29yZGluYXRlcyBhdCBldmVyeSBgbW92ZWAgZXZlbnQgY2F1c2VzIHN0dXR0ZXJlZCB6b29taW5nXG4gICAgICAgIC8vIHdlIG9ubHkgcm91bmQgdGhlbSB3aGVuIF91cGRhdGUgaXMgY2FsbGVkIHdpdGggYG1vdmVlbmRgIG9yIHdoZW4gaXRzIGNhbGxlZCB3aXRoXG4gICAgICAgIC8vIG5vIGFyZ3VtZW50cyAod2hlbiB0aGUgTWFya2VyIGlzIGluaXRpYWxpemVkIG9yIE1hcmtlciNzZXRMbmdMYXQgaXMgaW52b2tlZCkuXG4gICAgICAgIGlmIChkZWxheVNuYXAgPT09IHRydWUpIHtcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUZyYW1lSWQgPSB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fZWxlbWVudCAmJiB0aGlzLl9wb3MgJiYgdGhpcy5fYW5jaG9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3BvcyA9IHRoaXMuX3Bvcy5yb3VuZCgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl91cGRhdGVET00oKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3BvcyA9IHRoaXMuX3Bvcy5yb3VuZCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgbWFwLl9yZXF1ZXN0RG9tVGFzaygoKSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuX21hcCkgcmV0dXJuO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5fZWxlbWVudCAmJiB0aGlzLl9wb3MgJiYgdGhpcy5fYW5jaG9yKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdXBkYXRlRE9NKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICgobWFwLl9zaG93aW5nR2xvYmUoKSB8fCBtYXAuZ2V0VGVycmFpbigpIHx8IG1hcC5nZXRGb2coKSkgJiYgIXRoaXMuX2ZhZGVUaW1lcikge1xuICAgICAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgICAgICB0aGlzLl9mYWRlVGltZXIgPSBzZXRUaW1lb3V0KHRoaXMuX2V2YWx1YXRlT3BhY2l0eS5iaW5kKHRoaXMpLCA2MCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgbWFya2VyJ3Mgb2Zmc2V0LlxuICAgICAqXG4gICAgICogQHJldHVybnMge1BvaW50fSBUaGUgbWFya2VyJ3Mgc2NyZWVuIGNvb3JkaW5hdGVzIGluIHBpeGVscy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9mZnNldCA9IG1hcmtlci5nZXRPZmZzZXQoKTtcbiAgICAgKi9cbiAgICBnZXRPZmZzZXQoKTogUG9pbnQge1xuICAgICAgICByZXR1cm4gdGhpcy5fb2Zmc2V0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIG9mZnNldCBvZiB0aGUgbWFya2VyLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtQb2ludExpa2V9IG9mZnNldCBUaGUgb2Zmc2V0IGluIHBpeGVscyBhcyBhIHtAbGluayBQb2ludExpa2V9IG9iamVjdCB0byBhcHBseSByZWxhdGl2ZSB0byB0aGUgZWxlbWVudCdzIGNlbnRlci4gTmVnYXRpdmVzIGluZGljYXRlIGxlZnQgYW5kIHVwLlxuICAgICAqIEByZXR1cm5zIHtNYXJrZXJ9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXJrZXIuc2V0T2Zmc2V0KFswLCAxXSk7XG4gICAgICovXG4gICAgc2V0T2Zmc2V0KG9mZnNldDogUG9pbnRMaWtlKTogdGhpcyB7XG4gICAgICAgIHRoaXMuX29mZnNldCA9IFBvaW50LmNvbnZlcnQob2Zmc2V0KTtcbiAgICAgICAgdGhpcy5fdXBkYXRlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIF9vbk1vdmUoZTogTWFwTW91c2VFdmVudCB8IE1hcFRvdWNoRXZlbnQpIHtcbiAgICAgICAgY29uc3QgbWFwID0gdGhpcy5fbWFwO1xuICAgICAgICBpZiAoIW1hcCkgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IHN0YXJ0UG9zID0gdGhpcy5fcG9pbnRlcmRvd25Qb3M7XG4gICAgICAgIGNvbnN0IHBvc0RlbHRhID0gdGhpcy5fcG9zaXRpb25EZWx0YTtcbiAgICAgICAgaWYgKCFzdGFydFBvcyB8fCAhcG9zRGVsdGEpIHJldHVybjtcblxuICAgICAgICBpZiAoIXRoaXMuX2lzRHJhZ2dpbmcpIHtcbiAgICAgICAgICAgIGNvbnN0IGNsaWNrVG9sZXJhbmNlID0gdGhpcy5fY2xpY2tUb2xlcmFuY2UgfHwgbWFwLl9jbGlja1RvbGVyYW5jZTtcbiAgICAgICAgICAgIGlmIChlLnBvaW50LmRpc3Qoc3RhcnRQb3MpIDwgY2xpY2tUb2xlcmFuY2UpIHJldHVybjtcbiAgICAgICAgICAgIHRoaXMuX2lzRHJhZ2dpbmcgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fcG9zID0gZS5wb2ludC5zdWIocG9zRGVsdGEpO1xuICAgICAgICB0aGlzLl9sbmdMYXQgPSBtYXAudW5wcm9qZWN0KHRoaXMuX3Bvcyk7XG4gICAgICAgIHRoaXMuc2V0TG5nTGF0KHRoaXMuX2xuZ0xhdCk7XG4gICAgICAgIC8vIHN1cHByZXNzIGNsaWNrIGV2ZW50IHNvIHRoYXQgcG9wdXBzIGRvbid0IHRvZ2dsZSBvbiBkcmFnXG4gICAgICAgIHRoaXMuX2VsZW1lbnQuc3R5bGUucG9pbnRlckV2ZW50cyA9ICdub25lJztcblxuICAgICAgICAvLyBtYWtlIHN1cmUgZHJhZ3N0YXJ0IG9ubHkgZmlyZXMgb24gdGhlIGZpcnN0IG1vdmUgZXZlbnQgYWZ0ZXIgbW91c2Vkb3duLlxuICAgICAgICAvLyB0aGlzIGNhbid0IGJlIG9uIG1vdXNlZG93biBiZWNhdXNlIHRoYXQgZXZlbnQgZG9lc24ndCBuZWNlc3NhcmlseVxuICAgICAgICAvLyBpbXBseSB0aGF0IGEgZHJhZyBpcyBhYm91dCB0byBoYXBwZW4uXG4gICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3BlbmRpbmcnKSB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZSA9ICdhY3RpdmUnO1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIEZpcmVkIHdoZW4gZHJhZ2dpbmcgc3RhcnRzLlxuICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAqIEBldmVudCBkcmFnc3RhcnRcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBNYXJrZXJcbiAgICAgICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgICAgICogQHR5cGUge09iamVjdH1cbiAgICAgICAgICAgICAqIEBwcm9wZXJ0eSB7TWFya2VyfSBtYXJrZXIgVGhlIG9iamVjdCB0aGF0IGlzIGJlaW5nIGRyYWdnZWQuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ2RyYWdzdGFydCcpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBGaXJlZCB3aGlsZSBkcmFnZ2luZy5cbiAgICAgICAgICpcbiAgICAgICAgICogQGV2ZW50IGRyYWdcbiAgICAgICAgICogQG1lbWJlcm9mIE1hcmtlclxuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICogQHR5cGUge09iamVjdH1cbiAgICAgICAgICogQHByb3BlcnR5IHtNYXJrZXJ9IG1hcmtlciBUaGUgb2JqZWN0IHRoYXQgaXMgYmVpbmcgZHJhZ2dlZC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ2RyYWcnKSk7XG4gICAgfVxuXG4gICAgX29uVXAoKSB7XG4gICAgICAgIC8vIHJldmVydCB0byBub3JtYWwgcG9pbnRlciBldmVudCBoYW5kbGluZ1xuICAgICAgICB0aGlzLl9lbGVtZW50LnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnYXV0byc7XG4gICAgICAgIHRoaXMuX3Bvc2l0aW9uRGVsdGEgPSBudWxsO1xuICAgICAgICB0aGlzLl9wb2ludGVyZG93blBvcyA9IG51bGw7XG4gICAgICAgIHRoaXMuX2lzRHJhZ2dpbmcgPSBmYWxzZTtcblxuICAgICAgICBjb25zdCBtYXAgPSB0aGlzLl9tYXA7XG4gICAgICAgIGlmIChtYXApIHtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIG1hcC5vZmYoJ21vdXNlbW92ZScsIHRoaXMuX29uTW92ZSk7XG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICBtYXAub2ZmKCd0b3VjaG1vdmUnLCB0aGlzLl9vbk1vdmUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gb25seSBmaXJlIGRyYWdlbmQgaWYgaXQgd2FzIHByZWNlZGVkIGJ5IGF0IGxlYXN0IG9uZSBkcmFnIGV2ZW50XG4gICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ2FjdGl2ZScpIHtcbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgKiBGaXJlZCB3aGVuIHRoZSBtYXJrZXIgaXMgZmluaXNoZWQgYmVpbmcgZHJhZ2dlZC5cbiAgICAgICAgICAgICpcbiAgICAgICAgICAgICogQGV2ZW50IGRyYWdlbmRcbiAgICAgICAgICAgICogQG1lbWJlcm9mIE1hcmtlclxuICAgICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICAgICogQHR5cGUge09iamVjdH1cbiAgICAgICAgICAgICogQHByb3BlcnR5IHtNYXJrZXJ9IG1hcmtlciBUaGUgb2JqZWN0IHRoYXQgd2FzIGRyYWdnZWQuXG4gICAgICAgICAgICAqL1xuICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgnZHJhZ2VuZCcpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3N0YXRlID0gJ2luYWN0aXZlJztcbiAgICB9XG5cbiAgICBfYWRkRHJhZ0hhbmRsZXIoZTogTWFwTW91c2VFdmVudCB8IE1hcFRvdWNoRXZlbnQpIHtcbiAgICAgICAgY29uc3QgbWFwID0gdGhpcy5fbWFwO1xuICAgICAgICBjb25zdCBwb3MgPSB0aGlzLl9wb3M7XG4gICAgICAgIGlmICghbWFwIHx8ICFwb3MpIHJldHVybjtcblxuICAgICAgICBpZiAodGhpcy5fZWxlbWVudC5jb250YWlucygoZS5vcmlnaW5hbEV2ZW50LnRhcmdldDogYW55KSkpIHtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICAgICAgLy8gV2UgbmVlZCB0byBjYWxjdWxhdGUgdGhlIHBpeGVsIGRpc3RhbmNlIGJldHdlZW4gdGhlIGNsaWNrIHBvaW50XG4gICAgICAgICAgICAvLyBhbmQgdGhlIG1hcmtlciBwb3NpdGlvbiwgd2l0aCB0aGUgb2Zmc2V0IGFjY291bnRlZCBmb3IuIFRoZW4gd2VcbiAgICAgICAgICAgIC8vIGNhbiBzdWJ0cmFjdCB0aGlzIGRpc3RhbmNlIGZyb20gdGhlIG1vdXNlbW92ZSBldmVudCdzIHBvc2l0aW9uXG4gICAgICAgICAgICAvLyB0byBjYWxjdWxhdGUgdGhlIG5ldyBtYXJrZXIgcG9zaXRpb24uXG4gICAgICAgICAgICAvLyBJZiB3ZSBkb24ndCBkbyB0aGlzLCB0aGUgbWFya2VyICdqdW1wcycgdG8gdGhlIGNsaWNrIHBvc2l0aW9uXG4gICAgICAgICAgICAvLyBjcmVhdGluZyBhIGphcnJpbmcgVVggZWZmZWN0LlxuICAgICAgICAgICAgdGhpcy5fcG9zaXRpb25EZWx0YSA9IGUucG9pbnQuc3ViKHBvcyk7XG4gICAgICAgICAgICB0aGlzLl9wb2ludGVyZG93blBvcyA9IGUucG9pbnQ7XG5cbiAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gJ3BlbmRpbmcnO1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgbWFwLm9uKCdtb3VzZW1vdmUnLCB0aGlzLl9vbk1vdmUpO1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgbWFwLm9uKCd0b3VjaG1vdmUnLCB0aGlzLl9vbk1vdmUpO1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgbWFwLm9uY2UoJ21vdXNldXAnLCB0aGlzLl9vblVwKTtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIG1hcC5vbmNlKCd0b3VjaGVuZCcsIHRoaXMuX29uVXApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgYGRyYWdnYWJsZWAgcHJvcGVydHkgYW5kIGZ1bmN0aW9uYWxpdHkgb2YgdGhlIG1hcmtlci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW3Nob3VsZEJlRHJhZ2dhYmxlPWZhbHNlXSBUdXJucyBkcmFnIGZ1bmN0aW9uYWxpdHkgb24vb2ZmLlxuICAgICAqIEByZXR1cm5zIHtNYXJrZXJ9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXJrZXIuc2V0RHJhZ2dhYmxlKHRydWUpO1xuICAgICAqL1xuICAgIHNldERyYWdnYWJsZShzaG91bGRCZURyYWdnYWJsZTogYm9vbGVhbik6IHRoaXMge1xuICAgICAgICB0aGlzLl9kcmFnZ2FibGUgPSAhIXNob3VsZEJlRHJhZ2dhYmxlOyAvLyBjb252ZXJ0IHBvc3NpYmxlIHVuZGVmaW5lZCB2YWx1ZSB0byBmYWxzZVxuXG4gICAgICAgIC8vIGhhbmRsZSBjYXNlIHdoZXJlIG1hcCBtYXkgbm90IGV4aXN0IHlldFxuICAgICAgICAvLyBmb3IgZXhhbXBsZSwgd2hlbiBzZXREcmFnZ2FibGUgaXMgY2FsbGVkIGJlZm9yZSBhZGRUb1xuICAgICAgICBjb25zdCBtYXAgPSB0aGlzLl9tYXA7XG4gICAgICAgIGlmIChtYXApIHtcbiAgICAgICAgICAgIGlmIChzaG91bGRCZURyYWdnYWJsZSkge1xuICAgICAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgICAgICBtYXAub24oJ21vdXNlZG93bicsIHRoaXMuX2FkZERyYWdIYW5kbGVyKTtcbiAgICAgICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICAgICAgbWFwLm9uKCd0b3VjaHN0YXJ0JywgdGhpcy5fYWRkRHJhZ0hhbmRsZXIpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICAgICAgbWFwLm9mZignbW91c2Vkb3duJywgdGhpcy5fYWRkRHJhZ0hhbmRsZXIpO1xuICAgICAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgICAgICBtYXAub2ZmKCd0b3VjaHN0YXJ0JywgdGhpcy5fYWRkRHJhZ0hhbmRsZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBtYXJrZXIgY2FuIGJlIGRyYWdnZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgbWFya2VyIGlzIGRyYWdnYWJsZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGlzTWFya2VyRHJhZ2dhYmxlID0gbWFya2VyLmlzRHJhZ2dhYmxlKCk7XG4gICAgICovXG4gICAgaXNEcmFnZ2FibGUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kcmFnZ2FibGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgYHJvdGF0aW9uYCBwcm9wZXJ0eSBvZiB0aGUgbWFya2VyLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtyb3RhdGlvbj0wXSBUaGUgcm90YXRpb24gYW5nbGUgb2YgdGhlIG1hcmtlciAoY2xvY2t3aXNlLCBpbiBkZWdyZWVzKSwgcmVsYXRpdmUgdG8gaXRzIHJlc3BlY3RpdmUge0BsaW5rIE1hcmtlciNzZXRSb3RhdGlvbkFsaWdubWVudH0gc2V0dGluZy5cbiAgICAgKiBAcmV0dXJucyB7TWFya2VyfSBSZXR1cm5zIGl0c2VsZiB0byBhbGxvdyBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogbWFya2VyLnNldFJvdGF0aW9uKDQ1KTtcbiAgICAgKi9cbiAgICBzZXRSb3RhdGlvbihyb3RhdGlvbjogbnVtYmVyKTogdGhpcyB7XG4gICAgICAgIHRoaXMuX3JvdGF0aW9uID0gcm90YXRpb24gfHwgMDtcbiAgICAgICAgdGhpcy5fdXBkYXRlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgcm90YXRpb24gYW5nbGUgb2YgdGhlIG1hcmtlciAoaW4gZGVncmVlcykuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgY3VycmVudCByb3RhdGlvbiBhbmdsZSBvZiB0aGUgbWFya2VyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgcm90YXRpb24gPSBtYXJrZXIuZ2V0Um90YXRpb24oKTtcbiAgICAgKi9cbiAgICBnZXRSb3RhdGlvbigpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5fcm90YXRpb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgYHJvdGF0aW9uQWxpZ25tZW50YCBwcm9wZXJ0eSBvZiB0aGUgbWFya2VyLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFthbGlnbm1lbnQ9J2F1dG8nXSBTZXRzIHRoZSBgcm90YXRpb25BbGlnbm1lbnRgIHByb3BlcnR5IG9mIHRoZSBtYXJrZXIuXG4gICAgICogQHJldHVybnMge01hcmtlcn0gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIG1hcmtlci5zZXRSb3RhdGlvbkFsaWdubWVudCgndmlld3BvcnQnKTtcbiAgICAgKi9cbiAgICBzZXRSb3RhdGlvbkFsaWdubWVudChhbGlnbm1lbnQ6IHN0cmluZyk6IHRoaXMge1xuICAgICAgICB0aGlzLl9yb3RhdGlvbkFsaWdubWVudCA9IGFsaWdubWVudCB8fCAnYXV0byc7XG4gICAgICAgIHRoaXMuX3VwZGF0ZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IGByb3RhdGlvbkFsaWdubWVudGAgcHJvcGVydHkgb2YgdGhlIG1hcmtlci5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjdXJyZW50IHJvdGF0aW9uYWwgYWxpZ25tZW50IG9mIHRoZSBtYXJrZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBhbGlnbm1lbnQgPSBtYXJrZXIuZ2V0Um90YXRpb25BbGlnbm1lbnQoKTtcbiAgICAgKi9cbiAgICBnZXRSb3RhdGlvbkFsaWdubWVudCgpOiBzdHJpbmcge1xuICAgICAgICBpZiAodGhpcy5fcm90YXRpb25BbGlnbm1lbnQgPT09ICdhdXRvJylcbiAgICAgICAgICAgIHJldHVybiAndmlld3BvcnQnO1xuICAgICAgICBpZiAodGhpcy5fcm90YXRpb25BbGlnbm1lbnQgPT09ICdob3Jpem9uJyAmJiB0aGlzLl9tYXAgJiYgIXRoaXMuX21hcC5fc2hvd2luZ0dsb2JlKCkpXG4gICAgICAgICAgICByZXR1cm4gJ3ZpZXdwb3J0JztcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JvdGF0aW9uQWxpZ25tZW50O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGBwaXRjaEFsaWdubWVudGAgcHJvcGVydHkgb2YgdGhlIG1hcmtlci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbYWxpZ25tZW50XSBTZXRzIHRoZSBgcGl0Y2hBbGlnbm1lbnRgIHByb3BlcnR5IG9mIHRoZSBtYXJrZXIuIElmIGFsaWdubWVudCBpcyAnYXV0bycsIGl0IHdpbGwgYXV0b21hdGljYWxseSBtYXRjaCBgcm90YXRpb25BbGlnbm1lbnRgLlxuICAgICAqIEByZXR1cm5zIHtNYXJrZXJ9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXJrZXIuc2V0UGl0Y2hBbGlnbm1lbnQoJ21hcCcpO1xuICAgICAqL1xuICAgIHNldFBpdGNoQWxpZ25tZW50KGFsaWdubWVudDogc3RyaW5nKTogdGhpcyB7XG4gICAgICAgIHRoaXMuX3BpdGNoQWxpZ25tZW50ID0gYWxpZ25tZW50IHx8ICdhdXRvJztcbiAgICAgICAgdGhpcy5fdXBkYXRlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgYHBpdGNoQWxpZ25tZW50YCBiZWhhdmlvciBvZiB0aGUgbWFya2VyLlxuICAgICAqXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGN1cnJlbnQgcGl0Y2ggYWxpZ25tZW50IG9mIHRoZSBtYXJrZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBhbGlnbm1lbnQgPSBtYXJrZXIuZ2V0UGl0Y2hBbGlnbm1lbnQoKTtcbiAgICAgKi9cbiAgICBnZXRQaXRjaEFsaWdubWVudCgpOiBzdHJpbmcge1xuICAgICAgICBpZiAodGhpcy5fcGl0Y2hBbGlnbm1lbnQgPT09ICdhdXRvJykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0Um90YXRpb25BbGlnbm1lbnQoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fcGl0Y2hBbGlnbm1lbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgYG9jY2x1ZGVkT3BhY2l0eWAgcHJvcGVydHkgb2YgdGhlIG1hcmtlci5cbiAgICAgKiBUaGlzIG9wYWNpdHkgaXMgdXNlZCBvbiB0aGUgbWFya2VyIHdoZW4gdGhlIG1hcmtlciBpcyBvY2NsdWRlZCBieSB0ZXJyYWluLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcGFjaXR5PTAuMl0gU2V0cyB0aGUgYG9jY2x1ZGVkT3BhY2l0eWAgcHJvcGVydHkgb2YgdGhlIG1hcmtlci5cbiAgICAgKiBAcmV0dXJucyB7TWFya2VyfSBSZXR1cm5zIGl0c2VsZiB0byBhbGxvdyBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogbWFya2VyLnNldE9jY2x1ZGVkT3BhY2l0eSgwLjMpO1xuICAgICAqL1xuICAgIHNldE9jY2x1ZGVkT3BhY2l0eShvcGFjaXR5OiBudW1iZXIpOiB0aGlzIHtcbiAgICAgICAgdGhpcy5fb2NjbHVkZWRPcGFjaXR5ID0gb3BhY2l0eSB8fCAwLjI7XG4gICAgICAgIHRoaXMuX3VwZGF0ZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IGBvY2NsdWRlZE9wYWNpdHlgIG9mIHRoZSBtYXJrZXIuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgb3BhY2l0eSBvZiBhIHRlcnJhaW4gb2NjbHVkZWQgbWFya2VyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb3BhY2l0eSA9IG1hcmtlci5nZXRPY2NsdWRlZE9wYWNpdHkoKTtcbiAgICAgKi9cbiAgICBnZXRPY2NsdWRlZE9wYWNpdHkoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29jY2x1ZGVkT3BhY2l0eTtcbiAgICB9XG59XG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQge2V4dGVuZCwgYmluZEFsbH0gZnJvbSAnLi4vdXRpbC91dGlsLmpzJztcbmltcG9ydCB7RXZlbnQsIEV2ZW50ZWR9IGZyb20gJy4uL3V0aWwvZXZlbnRlZC5qcyc7XG5pbXBvcnQge01hcE1vdXNlRXZlbnR9IGZyb20gJy4uL3VpL2V2ZW50cy5qcyc7XG5pbXBvcnQgKiBhcyBET00gZnJvbSAnLi4vdXRpbC9kb20uanMnO1xuaW1wb3J0IExuZ0xhdCBmcm9tICcuLi9nZW8vbG5nX2xhdC5qcyc7XG5pbXBvcnQgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5pbXBvcnQgd2luZG93IGZyb20gJy4uL3V0aWwvd2luZG93LmpzJztcbmltcG9ydCBzbWFydFdyYXAgZnJvbSAnLi4vdXRpbC9zbWFydF93cmFwLmpzJztcbmltcG9ydCB7dHlwZSBBbmNob3IsIGFuY2hvclRyYW5zbGF0ZX0gZnJvbSAnLi9hbmNob3IuanMnO1xuaW1wb3J0IHtpc0xuZ0xhdEJlaGluZEdsb2JlfSBmcm9tICcuLi9nZW8vcHJvamVjdGlvbi9nbG9iZV91dGlsLmpzJztcblxuaW1wb3J0IHR5cGUgTWFwIGZyb20gJy4vbWFwLmpzJztcbmltcG9ydCB0eXBlIHtMbmdMYXRMaWtlfSBmcm9tICcuLi9nZW8vbG5nX2xhdC5qcyc7XG5pbXBvcnQgdHlwZSB7UG9pbnRMaWtlfSBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCB0eXBlIE1hcmtlciBmcm9tICcuL21hcmtlci5qcyc7XG5cbmNvbnN0IGRlZmF1bHRPcHRpb25zID0ge1xuICAgIGNsb3NlQnV0dG9uOiB0cnVlLFxuICAgIGNsb3NlT25DbGljazogdHJ1ZSxcbiAgICBmb2N1c0FmdGVyT3BlbjogdHJ1ZSxcbiAgICBjbGFzc05hbWU6ICcnLFxuICAgIG1heFdpZHRoOiBcIjI0MHB4XCJcbn07XG5cbmV4cG9ydCB0eXBlIE9mZnNldCA9IG51bWJlciB8IFBvaW50TGlrZSB8IHtbXzogQW5jaG9yXTogUG9pbnRMaWtlfTtcblxuZXhwb3J0IHR5cGUgUG9wdXBPcHRpb25zID0ge1xuICAgIGNsb3NlQnV0dG9uPzogYm9vbGVhbixcbiAgICBjbG9zZU9uQ2xpY2s/OiBib29sZWFuLFxuICAgIGNsb3NlT25Nb3ZlPzogYm9vbGVhbixcbiAgICBmb2N1c0FmdGVyT3Blbj86IGJvb2xlYW4sXG4gICAgYW5jaG9yPzogQW5jaG9yLFxuICAgIG9mZnNldD86IE9mZnNldCxcbiAgICBjbGFzc05hbWU/OiBzdHJpbmcsXG4gICAgbWF4V2lkdGg/OiBzdHJpbmdcbn07XG5cbmNvbnN0IGZvY3VzUXVlcnlTZWxlY3RvciA9IFtcbiAgICBcImFbaHJlZl1cIixcbiAgICBcIlt0YWJpbmRleF06bm90KFt0YWJpbmRleD0nLTEnXSlcIixcbiAgICBcIltjb250ZW50ZWRpdGFibGVdOm5vdChbY29udGVudGVkaXRhYmxlPSdmYWxzZSddKVwiLFxuICAgIFwiYnV0dG9uOm5vdChbZGlzYWJsZWRdKVwiLFxuICAgIFwiaW5wdXQ6bm90KFtkaXNhYmxlZF0pXCIsXG4gICAgXCJzZWxlY3Q6bm90KFtkaXNhYmxlZF0pXCIsXG4gICAgXCJ0ZXh0YXJlYTpub3QoW2Rpc2FibGVkXSlcIixcbl0uam9pbihcIiwgXCIpO1xuXG4vKipcbiAqIEEgcG9wdXAgY29tcG9uZW50LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMuY2xvc2VCdXR0b249dHJ1ZV0gSWYgYHRydWVgLCBhIGNsb3NlIGJ1dHRvbiB3aWxsIGFwcGVhciBpbiB0aGVcbiAqICAgdG9wIHJpZ2h0IGNvcm5lciBvZiB0aGUgcG9wdXAuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmNsb3NlT25DbGljaz10cnVlXSBJZiBgdHJ1ZWAsIHRoZSBwb3B1cCB3aWxsIGNsb3NlIHdoZW4gdGhlXG4gKiAgIG1hcCBpcyBjbGlja2VkLlxuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5jbG9zZU9uTW92ZT1mYWxzZV0gSWYgYHRydWVgLCB0aGUgcG9wdXAgd2lsbCBjbG9zZSB3aGVuIHRoZVxuICogICBtYXAgbW92ZXMuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmZvY3VzQWZ0ZXJPcGVuPXRydWVdIElmIGB0cnVlYCwgdGhlIHBvcHVwIHdpbGwgdHJ5IHRvIGZvY3VzIHRoZVxuICogICBmaXJzdCBmb2N1c2FibGUgZWxlbWVudCBpbnNpZGUgdGhlIHBvcHVwLlxuICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLmFuY2hvcl0gLSBBIHN0cmluZyBpbmRpY2F0aW5nIHRoZSBwYXJ0IG9mIHRoZSBwb3B1cCB0aGF0IHNob3VsZFxuICogICBiZSBwb3NpdGlvbmVkIGNsb3Nlc3QgdG8gdGhlIGNvb3JkaW5hdGUsIHNldCB2aWEge0BsaW5rIFBvcHVwI3NldExuZ0xhdH0uXG4gKiAgIE9wdGlvbnMgYXJlIGAnY2VudGVyJ2AsIGAndG9wJ2AsIGAnYm90dG9tJ2AsIGAnbGVmdCdgLCBgJ3JpZ2h0J2AsIGAndG9wLWxlZnQnYCxcbiAqICAgYCd0b3AtcmlnaHQnYCwgYCdib3R0b20tbGVmdCdgLCBhbmQgYCdib3R0b20tcmlnaHQnYC4gSWYgdW5zZXQsIHRoZSBhbmNob3Igd2lsbCBiZVxuICogICBkeW5hbWljYWxseSBzZXQgdG8gZW5zdXJlIHRoZSBwb3B1cCBmYWxscyB3aXRoaW4gdGhlIG1hcCBjb250YWluZXIgd2l0aCBhIHByZWZlcmVuY2VcbiAqICAgZm9yIGAnYm90dG9tJ2AuXG4gKiBAcGFyYW0ge251bWJlciB8IFBvaW50TGlrZSB8IE9iamVjdH0gW29wdGlvbnMub2Zmc2V0XSAtXG4gKiAgQSBwaXhlbCBvZmZzZXQgYXBwbGllZCB0byB0aGUgcG9wdXAncyBsb2NhdGlvbiBzcGVjaWZpZWQgYXM6XG4gKiAgIC0gYSBzaW5nbGUgbnVtYmVyIHNwZWNpZnlpbmcgYSBkaXN0YW5jZSBmcm9tIHRoZSBwb3B1cCdzIGxvY2F0aW9uXG4gKiAgIC0gYSB7QGxpbmsgUG9pbnRMaWtlfSBzcGVjaWZ5aW5nIGEgY29uc3RhbnQgb2Zmc2V0XG4gKiAgIC0gYW4gb2JqZWN0IG9mIHtAbGluayBQb2ludH1zIHNwZWNpZmluZyBhbiBvZmZzZXQgZm9yIGVhY2ggYW5jaG9yIHBvc2l0aW9uLlxuICpcbiAqICBOZWdhdGl2ZSBvZmZzZXRzIGluZGljYXRlIGxlZnQgYW5kIHVwLlxuICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLmNsYXNzTmFtZV0gU3BhY2Utc2VwYXJhdGVkIENTUyBjbGFzcyBuYW1lcyB0byBhZGQgdG8gcG9wdXAgY29udGFpbmVyLlxuICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLm1heFdpZHRoPScyNDBweCddIC1cbiAqICBBIHN0cmluZyB0aGF0IHNldHMgdGhlIENTUyBwcm9wZXJ0eSBvZiB0aGUgcG9wdXAncyBtYXhpbXVtIHdpZHRoIChmb3IgZXhhbXBsZSwgYCczMDBweCdgKS5cbiAqICBUbyBlbnN1cmUgdGhlIHBvcHVwIHJlc2l6ZXMgdG8gZml0IGl0cyBjb250ZW50LCBzZXQgdGhpcyBwcm9wZXJ0eSB0byBgJ25vbmUnYC5cbiAqICBTZWUgdGhlIE1ETiBkb2N1bWVudGF0aW9uIGZvciB0aGUgbGlzdCBvZiBbYXZhaWxhYmxlIHZhbHVlc10oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL21heC13aWR0aCkuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgbWFya2VySGVpZ2h0ID0gNTA7XG4gKiBjb25zdCBtYXJrZXJSYWRpdXMgPSAxMDtcbiAqIGNvbnN0IGxpbmVhck9mZnNldCA9IDI1O1xuICogY29uc3QgcG9wdXBPZmZzZXRzID0ge1xuICogICAgICd0b3AnOiBbMCwgMF0sXG4gKiAgICAgJ3RvcC1sZWZ0JzogWzAsIDBdLFxuICogICAgICd0b3AtcmlnaHQnOiBbMCwgMF0sXG4gKiAgICAgJ2JvdHRvbSc6IFswLCAtbWFya2VySGVpZ2h0XSxcbiAqICAgICAnYm90dG9tLWxlZnQnOiBbbGluZWFyT2Zmc2V0LCAobWFya2VySGVpZ2h0IC0gbWFya2VyUmFkaXVzICsgbGluZWFyT2Zmc2V0KSAqIC0xXSxcbiAqICAgICAnYm90dG9tLXJpZ2h0JzogWy1saW5lYXJPZmZzZXQsIChtYXJrZXJIZWlnaHQgLSBtYXJrZXJSYWRpdXMgKyBsaW5lYXJPZmZzZXQpICogLTFdLFxuICogICAgICdsZWZ0JzogW21hcmtlclJhZGl1cywgKG1hcmtlckhlaWdodCAtIG1hcmtlclJhZGl1cykgKiAtMV0sXG4gKiAgICAgJ3JpZ2h0JzogWy1tYXJrZXJSYWRpdXMsIChtYXJrZXJIZWlnaHQgLSBtYXJrZXJSYWRpdXMpICogLTFdXG4gKiB9O1xuICogY29uc3QgcG9wdXAgPSBuZXcgbWFwYm94Z2wuUG9wdXAoe29mZnNldDogcG9wdXBPZmZzZXRzLCBjbGFzc05hbWU6ICdteS1jbGFzcyd9KVxuICogICAgIC5zZXRMbmdMYXQoZS5sbmdMYXQpXG4gKiAgICAgLnNldEhUTUwoXCI8aDE+SGVsbG8gV29ybGQhPC9oMT5cIilcbiAqICAgICAuc2V0TWF4V2lkdGgoXCIzMDBweFwiKVxuICogICAgIC5hZGRUbyhtYXApO1xuICogQHNlZSBbRXhhbXBsZTogRGlzcGxheSBhIHBvcHVwXShodHRwczovL3d3dy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL3BvcHVwLylcbiAqIEBzZWUgW0V4YW1wbGU6IERpc3BsYXkgYSBwb3B1cCBvbiBob3Zlcl0oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9wb3B1cC1vbi1ob3Zlci8pXG4gKiBAc2VlIFtFeGFtcGxlOiBEaXNwbGF5IGEgcG9wdXAgb24gY2xpY2tdKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvcG9wdXAtb24tY2xpY2svKVxuICogQHNlZSBbRXhhbXBsZTogQXR0YWNoIGEgcG9wdXAgdG8gYSBtYXJrZXIgaW5zdGFuY2VdKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvc2V0LXBvcHVwLylcbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUG9wdXAgZXh0ZW5kcyBFdmVudGVkIHtcbiAgICBfbWFwOiA/TWFwO1xuICAgIG9wdGlvbnM6IFBvcHVwT3B0aW9ucztcbiAgICBfY29udGVudDogP0hUTUxFbGVtZW50O1xuICAgIF9jb250YWluZXI6ID9IVE1MRWxlbWVudDtcbiAgICBfY2xvc2VCdXR0b246ID9IVE1MRWxlbWVudDtcbiAgICBfdGlwOiA/SFRNTEVsZW1lbnQ7XG4gICAgX2xuZ0xhdDogTG5nTGF0O1xuICAgIF90cmFja1BvaW50ZXI6IGJvb2xlYW47XG4gICAgX3BvczogP1BvaW50O1xuICAgIF9hbmNob3I6IEFuY2hvcjtcbiAgICBfY2xhc3NMaXN0OiBTZXQ8c3RyaW5nPjtcbiAgICBfbWFya2VyOiA/TWFya2VyO1xuXG4gICAgY29uc3RydWN0b3Iob3B0aW9uczogUG9wdXBPcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IGV4dGVuZChPYmplY3QuY3JlYXRlKGRlZmF1bHRPcHRpb25zKSwgb3B0aW9ucyk7XG4gICAgICAgIGJpbmRBbGwoWydfdXBkYXRlJywgJ19vbkNsb3NlJywgJ3JlbW92ZScsICdfb25Nb3VzZUV2ZW50J10sIHRoaXMpO1xuICAgICAgICB0aGlzLl9jbGFzc0xpc3QgPSBuZXcgU2V0KG9wdGlvbnMgJiYgb3B0aW9ucy5jbGFzc05hbWUgP1xuICAgICAgICAgICAgb3B0aW9ucy5jbGFzc05hbWUudHJpbSgpLnNwbGl0KC9cXHMrLykgOiBbXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkcyB0aGUgcG9wdXAgdG8gYSBtYXAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge01hcH0gbWFwIFRoZSBNYXBib3ggR0wgSlMgbWFwIHRvIGFkZCB0aGUgcG9wdXAgdG8uXG4gICAgICogQHJldHVybnMge1BvcHVwfSBSZXR1cm5zIGl0c2VsZiB0byBhbGxvdyBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogbmV3IG1hcGJveGdsLlBvcHVwKClcbiAgICAgKiAgICAgLnNldExuZ0xhdChbMCwgMF0pXG4gICAgICogICAgIC5zZXRIVE1MKFwiPGgxPk51bGwgSXNsYW5kPC9oMT5cIilcbiAgICAgKiAgICAgLmFkZFRvKG1hcCk7XG4gICAgICogQHNlZSBbRXhhbXBsZTogRGlzcGxheSBhIHBvcHVwXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9wb3B1cC8pXG4gICAgICogQHNlZSBbRXhhbXBsZTogRGlzcGxheSBhIHBvcHVwIG9uIGhvdmVyXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9wb3B1cC1vbi1ob3Zlci8pXG4gICAgICogQHNlZSBbRXhhbXBsZTogRGlzcGxheSBhIHBvcHVwIG9uIGNsaWNrXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9wb3B1cC1vbi1jbGljay8pXG4gICAgICogQHNlZSBbRXhhbXBsZTogU2hvdyBwb2x5Z29uIGluZm9ybWF0aW9uIG9uIGNsaWNrXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9wb2x5Z29uLXBvcHVwLW9uLWNsaWNrLylcbiAgICAgKi9cbiAgICBhZGRUbyhtYXA6IE1hcCk6IHRoaXMge1xuICAgICAgICBpZiAodGhpcy5fbWFwKSB0aGlzLnJlbW92ZSgpO1xuXG4gICAgICAgIHRoaXMuX21hcCA9IG1hcDtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5jbG9zZU9uQ2xpY2spIHtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIG1hcC5vbigncHJlY2xpY2snLCB0aGlzLl9vbkNsb3NlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuY2xvc2VPbk1vdmUpIHtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIG1hcC5vbignbW92ZScsIHRoaXMuX29uQ2xvc2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICBtYXAub24oJ3JlbW92ZScsIHRoaXMucmVtb3ZlKTtcbiAgICAgICAgdGhpcy5fdXBkYXRlKCk7XG4gICAgICAgIG1hcC5fYWRkUG9wdXAodGhpcyk7XG4gICAgICAgIHRoaXMuX2ZvY3VzRmlyc3RFbGVtZW50KCk7XG5cbiAgICAgICAgaWYgKHRoaXMuX3RyYWNrUG9pbnRlcikge1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgbWFwLm9uKCdtb3VzZW1vdmUnLCB0aGlzLl9vbk1vdXNlRXZlbnQpO1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgbWFwLm9uKCdtb3VzZXVwJywgdGhpcy5fb25Nb3VzZUV2ZW50KTtcbiAgICAgICAgICAgIG1hcC5fY2FudmFzQ29udGFpbmVyLmNsYXNzTGlzdC5hZGQoJ21hcGJveGdsLXRyYWNrLXBvaW50ZXInKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIG1hcC5vbignbW92ZScsIHRoaXMuX3VwZGF0ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogRmlyZWQgd2hlbiB0aGUgcG9wdXAgaXMgb3BlbmVkIG1hbnVhbGx5IG9yIHByb2dyYW1hdGljYWxseS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGV2ZW50IG9wZW5cbiAgICAgICAgICogQG1lbWJlcm9mIFBvcHVwXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgICAgICAgKiBAcHJvcGVydHkge1BvcHVwfSBwb3B1cCBPYmplY3QgdGhhdCB3YXMgb3BlbmVkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKiAvLyBDcmVhdGUgYSBwb3B1cFxuICAgICAgICAgKiBjb25zdCBwb3B1cCA9IG5ldyBtYXBib3hnbC5Qb3B1cCgpO1xuICAgICAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCB3aWxsIGZpcmVcbiAgICAgICAgICogLy8gYW55IHRpbWUgdGhlIHBvcHVwIGlzIG9wZW5lZFxuICAgICAgICAgKiBwb3B1cC5vbignb3BlbicsICgpID0+IHtcbiAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdwb3B1cCB3YXMgb3BlbmVkJyk7XG4gICAgICAgICAqIH0pO1xuICAgICAgICAgKlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgnb3BlbicpKTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYSBwb3B1cCBpcyBvcGVuLlxuICAgICAqXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgcG9wdXAgaXMgb3BlbiwgYGZhbHNlYCBpZiBpdCBpcyBjbG9zZWQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBpc1BvcHVwT3BlbiA9IHBvcHVwLmlzT3BlbigpO1xuICAgICAqL1xuICAgIGlzT3BlbigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5fbWFwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgdGhlIHBvcHVwIGZyb20gdGhlIG1hcCBpdCBoYXMgYmVlbiBhZGRlZCB0by5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcG9wdXAgPSBuZXcgbWFwYm94Z2wuUG9wdXAoKS5hZGRUbyhtYXApO1xuICAgICAqIHBvcHVwLnJlbW92ZSgpO1xuICAgICAqIEByZXR1cm5zIHtQb3B1cH0gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKi9cbiAgICByZW1vdmUoKTogdGhpcyB7XG4gICAgICAgIGlmICh0aGlzLl9jb250ZW50KSB7XG4gICAgICAgICAgICB0aGlzLl9jb250ZW50LnJlbW92ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuX2NvbnRhaW5lcikge1xuICAgICAgICAgICAgdGhpcy5fY29udGFpbmVyLnJlbW92ZSgpO1xuICAgICAgICAgICAgdGhpcy5fY29udGFpbmVyID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbWFwID0gdGhpcy5fbWFwO1xuICAgICAgICBpZiAobWFwKSB7XG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICBtYXAub2ZmKCdtb3ZlJywgdGhpcy5fdXBkYXRlKTtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIG1hcC5vZmYoJ21vdmUnLCB0aGlzLl9vbkNsb3NlKTtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIG1hcC5vZmYoJ3ByZWNsaWNrJywgdGhpcy5fb25DbG9zZSk7XG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICBtYXAub2ZmKCdjbGljaycsIHRoaXMuX29uQ2xvc2UpO1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgbWFwLm9mZigncmVtb3ZlJywgdGhpcy5yZW1vdmUpO1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgbWFwLm9mZignbW91c2Vtb3ZlJywgdGhpcy5fb25Nb3VzZUV2ZW50KTtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIG1hcC5vZmYoJ21vdXNldXAnLCB0aGlzLl9vbk1vdXNlRXZlbnQpO1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgbWFwLm9mZignZHJhZycsIHRoaXMuX29uTW91c2VFdmVudCk7XG4gICAgICAgICAgICBpZiAobWFwLl9jYW52YXNDb250YWluZXIpIHtcbiAgICAgICAgICAgICAgICBtYXAuX2NhbnZhc0NvbnRhaW5lci5jbGFzc0xpc3QucmVtb3ZlKCdtYXBib3hnbC10cmFjay1wb2ludGVyJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBtYXAuX3JlbW92ZVBvcHVwKHRoaXMpO1xuICAgICAgICAgICAgdGhpcy5fbWFwID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEZpcmVkIHdoZW4gdGhlIHBvcHVwIGlzIGNsb3NlZCBtYW51YWxseSBvciBwcm9ncmFtYXRpY2FsbHkuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBldmVudCBjbG9zZVxuICAgICAgICAgKiBAbWVtYmVyb2YgUG9wdXBcbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqIEB0eXBlIHtPYmplY3R9XG4gICAgICAgICAqIEBwcm9wZXJ0eSB7UG9wdXB9IHBvcHVwIE9iamVjdCB0aGF0IHdhcyBjbG9zZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqIC8vIENyZWF0ZSBhIHBvcHVwXG4gICAgICAgICAqIGNvbnN0IHBvcHVwID0gbmV3IG1hcGJveGdsLlBvcHVwKCk7XG4gICAgICAgICAqIC8vIFNldCBhbiBldmVudCBsaXN0ZW5lciB0aGF0IHdpbGwgZmlyZVxuICAgICAgICAgKiAvLyBhbnkgdGltZSB0aGUgcG9wdXAgaXMgY2xvc2VkXG4gICAgICAgICAqIHBvcHVwLm9uKCdjbG9zZScsICgpID0+IHtcbiAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdwb3B1cCB3YXMgY2xvc2VkJyk7XG4gICAgICAgICAqIH0pO1xuICAgICAgICAgKlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgnY2xvc2UnKSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgZ2VvZ3JhcGhpY2FsIGxvY2F0aW9uIG9mIHRoZSBwb3B1cCdzIGFuY2hvci5cbiAgICAgKlxuICAgICAqIFRoZSBsb25naXR1ZGUgb2YgdGhlIHJlc3VsdCBtYXkgZGlmZmVyIGJ5IGEgbXVsdGlwbGUgb2YgMzYwIGRlZ3JlZXMgZnJvbSB0aGUgbG9uZ2l0dWRlIHByZXZpb3VzbHlcbiAgICAgKiBzZXQgYnkgYHNldExuZ0xhdGAgYmVjYXVzZSBgUG9wdXBgIHdyYXBzIHRoZSBhbmNob3IgbG9uZ2l0dWRlIGFjcm9zcyBjb3BpZXMgb2YgdGhlIHdvcmxkIHRvIGtlZXBcbiAgICAgKiB0aGUgcG9wdXAgb24gc2NyZWVuLlxuICAgICAqXG4gICAgICogQHJldHVybnMge0xuZ0xhdH0gVGhlIGdlb2dyYXBoaWNhbCBsb2NhdGlvbiBvZiB0aGUgcG9wdXAncyBhbmNob3IuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBsbmdMYXQgPSBwb3B1cC5nZXRMbmdMYXQoKTtcbiAgICAgKi9cbiAgICBnZXRMbmdMYXQoKTogTG5nTGF0IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xuZ0xhdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBnZW9ncmFwaGljYWwgbG9jYXRpb24gb2YgdGhlIHBvcHVwJ3MgYW5jaG9yLCBhbmQgbW92ZXMgdGhlIHBvcHVwIHRvIGl0LiBSZXBsYWNlcyB0cmFja1BvaW50ZXIoKSBiZWhhdmlvci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7TG5nTGF0TGlrZX0gbG5nbGF0IFRoZSBnZW9ncmFwaGljYWwgbG9jYXRpb24gdG8gc2V0IGFzIHRoZSBwb3B1cCdzIGFuY2hvci5cbiAgICAgKiBAcmV0dXJucyB7UG9wdXB9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBwb3B1cC5zZXRMbmdMYXQoWy0xMjIuNDE5NCwgMzcuNzc0OV0pO1xuICAgICAqL1xuICAgIHNldExuZ0xhdChsbmdsYXQ6IExuZ0xhdExpa2UpOiB0aGlzIHtcbiAgICAgICAgdGhpcy5fbG5nTGF0ID0gTG5nTGF0LmNvbnZlcnQobG5nbGF0KTtcbiAgICAgICAgdGhpcy5fcG9zID0gbnVsbDtcblxuICAgICAgICB0aGlzLl90cmFja1BvaW50ZXIgPSBmYWxzZTtcblxuICAgICAgICB0aGlzLl91cGRhdGUoKTtcblxuICAgICAgICBjb25zdCBtYXAgPSB0aGlzLl9tYXA7XG4gICAgICAgIGlmIChtYXApIHtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIG1hcC5vbignbW92ZScsIHRoaXMuX3VwZGF0ZSk7XG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICBtYXAub2ZmKCdtb3VzZW1vdmUnLCB0aGlzLl9vbk1vdXNlRXZlbnQpO1xuICAgICAgICAgICAgbWFwLl9jYW52YXNDb250YWluZXIuY2xhc3NMaXN0LnJlbW92ZSgnbWFwYm94Z2wtdHJhY2stcG9pbnRlcicpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJhY2tzIHRoZSBwb3B1cCBhbmNob3IgdG8gdGhlIGN1cnNvciBwb3NpdGlvbiBvbiBzY3JlZW5zIHdpdGggYSBwb2ludGVyIGRldmljZSAoaXQgd2lsbCBiZSBoaWRkZW4gb24gdG91Y2hzY3JlZW5zKS4gUmVwbGFjZXMgdGhlIGBzZXRMbmdMYXRgIGJlaGF2aW9yLlxuICAgICAqIEZvciBtb3N0IHVzZSBjYXNlcywgc2V0IGBjbG9zZU9uQ2xpY2tgIGFuZCBgY2xvc2VCdXR0b25gIHRvIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBvcHVwID0gbmV3IG1hcGJveGdsLlBvcHVwKHtjbG9zZU9uQ2xpY2s6IGZhbHNlLCBjbG9zZUJ1dHRvbjogZmFsc2V9KVxuICAgICAqICAgICAuc2V0SFRNTChcIjxoMT5IZWxsbyBXb3JsZCE8L2gxPlwiKVxuICAgICAqICAgICAudHJhY2tQb2ludGVyKClcbiAgICAgKiAgICAgLmFkZFRvKG1hcCk7XG4gICAgICogQHJldHVybnMge1BvcHVwfSBSZXR1cm5zIGl0c2VsZiB0byBhbGxvdyBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHRyYWNrUG9pbnRlcigpOiB0aGlzIHtcbiAgICAgICAgdGhpcy5fdHJhY2tQb2ludGVyID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fcG9zID0gbnVsbDtcbiAgICAgICAgdGhpcy5fdXBkYXRlKCk7XG4gICAgICAgIGNvbnN0IG1hcCA9IHRoaXMuX21hcDtcbiAgICAgICAgaWYgKG1hcCkge1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgbWFwLm9mZignbW92ZScsIHRoaXMuX3VwZGF0ZSk7XG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICBtYXAub24oJ21vdXNlbW92ZScsIHRoaXMuX29uTW91c2VFdmVudCk7XG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICBtYXAub24oJ2RyYWcnLCB0aGlzLl9vbk1vdXNlRXZlbnQpO1xuICAgICAgICAgICAgbWFwLl9jYW52YXNDb250YWluZXIuY2xhc3NMaXN0LmFkZCgnbWFwYm94Z2wtdHJhY2stcG9pbnRlcicpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBgUG9wdXBgJ3MgSFRNTCBlbGVtZW50LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBDaGFuZ2UgdGhlIGBQb3B1cGAgZWxlbWVudCdzIGZvbnQgc2l6ZVxuICAgICAqIGNvbnN0IHBvcHVwID0gbmV3IG1hcGJveGdsLlBvcHVwKClcbiAgICAgKiAgICAgLnNldExuZ0xhdChbLTk2LCAzNy44XSlcbiAgICAgKiAgICAgLnNldEhUTUwoXCI8cD5IZWxsbyBXb3JsZCE8L3A+XCIpXG4gICAgICogICAgIC5hZGRUbyhtYXApO1xuICAgICAqIGNvbnN0IHBvcHVwRWxlbSA9IHBvcHVwLmdldEVsZW1lbnQoKTtcbiAgICAgKiBwb3B1cEVsZW0uc3R5bGUuZm9udFNpemUgPSBcIjI1cHhcIjtcbiAgICAgKiBAcmV0dXJucyB7SFRNTEVsZW1lbnR9IFJldHVybnMgY29udGFpbmVyIGVsZW1lbnQuXG4gICAgICovXG4gICAgZ2V0RWxlbWVudCgpOiA/SFRNTEVsZW1lbnQge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGFpbmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHBvcHVwJ3MgY29udGVudCB0byBhIHN0cmluZyBvZiB0ZXh0LlxuICAgICAqXG4gICAgICogVGhpcyBmdW5jdGlvbiBjcmVhdGVzIGEgW1RleHRdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9UZXh0KSBub2RlIGluIHRoZSBET00sXG4gICAgICogc28gaXQgY2Fubm90IGluc2VydCByYXcgSFRNTC4gVXNlIHRoaXMgbWV0aG9kIGZvciBzZWN1cml0eSBhZ2FpbnN0IFhTU1xuICAgICAqIGlmIHRoZSBwb3B1cCBjb250ZW50IGlzIHVzZXItcHJvdmlkZWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCBUZXh0dWFsIGNvbnRlbnQgZm9yIHRoZSBwb3B1cC5cbiAgICAgKiBAcmV0dXJucyB7UG9wdXB9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwb3B1cCA9IG5ldyBtYXBib3hnbC5Qb3B1cCgpXG4gICAgICogICAgIC5zZXRMbmdMYXQoZS5sbmdMYXQpXG4gICAgICogICAgIC5zZXRUZXh0KCdIZWxsbywgd29ybGQhJylcbiAgICAgKiAgICAgLmFkZFRvKG1hcCk7XG4gICAgICovXG4gICAgc2V0VGV4dCh0ZXh0OiBzdHJpbmcpOiB0aGlzIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2V0RE9NQ29udGVudCh3aW5kb3cuZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUodGV4dCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHBvcHVwJ3MgY29udGVudCB0byB0aGUgSFRNTCBwcm92aWRlZCBhcyBhIHN0cmluZy5cbiAgICAgKlxuICAgICAqIFRoaXMgbWV0aG9kIGRvZXMgbm90IHBlcmZvcm0gSFRNTCBmaWx0ZXJpbmcgb3Igc2FuaXRpemF0aW9uLCBhbmQgbXVzdCBiZVxuICAgICAqIHVzZWQgb25seSB3aXRoIHRydXN0ZWQgY29udGVudC4gQ29uc2lkZXIge0BsaW5rIFBvcHVwI3NldFRleHR9IGlmXG4gICAgICogdGhlIGNvbnRlbnQgaXMgYW4gdW50cnVzdGVkIHRleHQgc3RyaW5nLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGh0bWwgQSBzdHJpbmcgcmVwcmVzZW50aW5nIEhUTUwgY29udGVudCBmb3IgdGhlIHBvcHVwLlxuICAgICAqIEByZXR1cm5zIHtQb3B1cH0gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBvcHVwID0gbmV3IG1hcGJveGdsLlBvcHVwKClcbiAgICAgKiAgICAgLnNldExuZ0xhdChlLmxuZ0xhdClcbiAgICAgKiAgICAgLnNldEhUTUwoXCI8aDE+SGVsbG8gV29ybGQhPC9oMT5cIilcbiAgICAgKiAgICAgLmFkZFRvKG1hcCk7XG4gICAgICogQHNlZSBbRXhhbXBsZTogRGlzcGxheSBhIHBvcHVwXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9wb3B1cC8pXG4gICAgICogQHNlZSBbRXhhbXBsZTogRGlzcGxheSBhIHBvcHVwIG9uIGhvdmVyXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9wb3B1cC1vbi1ob3Zlci8pXG4gICAgICogQHNlZSBbRXhhbXBsZTogRGlzcGxheSBhIHBvcHVwIG9uIGNsaWNrXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9wb3B1cC1vbi1jbGljay8pXG4gICAgICogQHNlZSBbRXhhbXBsZTogQXR0YWNoIGEgcG9wdXAgdG8gYSBtYXJrZXIgaW5zdGFuY2VdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL3NldC1wb3B1cC8pXG4gICAgICovXG4gICAgc2V0SFRNTChodG1sOiBzdHJpbmcpOiB0aGlzIHtcbiAgICAgICAgY29uc3QgZnJhZyA9IHdpbmRvdy5kb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XG4gICAgICAgIGNvbnN0IHRlbXAgPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYm9keScpO1xuICAgICAgICBsZXQgY2hpbGQ7XG4gICAgICAgIHRlbXAuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgIGNoaWxkID0gdGVtcC5maXJzdENoaWxkO1xuICAgICAgICAgICAgaWYgKCFjaGlsZCkgYnJlYWs7XG4gICAgICAgICAgICBmcmFnLmFwcGVuZENoaWxkKGNoaWxkKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLnNldERPTUNvbnRlbnQoZnJhZyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcG9wdXAncyBtYXhpbXVtIHdpZHRoLlxuICAgICAqXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIG1heGltdW0gd2lkdGggb2YgdGhlIHBvcHVwLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgbWF4V2lkdGggPSBwb3B1cC5nZXRNYXhXaWR0aCgpO1xuICAgICAqL1xuICAgIGdldE1heFdpZHRoKCk6ID9zdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGFpbmVyICYmIHRoaXMuX2NvbnRhaW5lci5zdHlsZS5tYXhXaWR0aDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBwb3B1cCdzIG1heGltdW0gd2lkdGguIFRoaXMgaXMgc2V0dGluZyB0aGUgQ1NTIHByb3BlcnR5IGBtYXgtd2lkdGhgLlxuICAgICAqIEF2YWlsYWJsZSB2YWx1ZXMgY2FuIGJlIGZvdW5kIGhlcmU6IGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0NTUy9tYXgtd2lkdGguXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbWF4V2lkdGggQSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSB2YWx1ZSBmb3IgdGhlIG1heGltdW0gd2lkdGguXG4gICAgICogQHJldHVybnMge1BvcHVwfSBSZXR1cm5zIGl0c2VsZiB0byBhbGxvdyBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogcG9wdXAuc2V0TWF4V2lkdGgoJzUwJyk7XG4gICAgICovXG4gICAgc2V0TWF4V2lkdGgobWF4V2lkdGg6IHN0cmluZyk6IHRoaXMge1xuICAgICAgICB0aGlzLm9wdGlvbnMubWF4V2lkdGggPSBtYXhXaWR0aDtcbiAgICAgICAgdGhpcy5fdXBkYXRlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHBvcHVwJ3MgY29udGVudCB0byB0aGUgZWxlbWVudCBwcm92aWRlZCBhcyBhIERPTSBub2RlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtFbGVtZW50fSBodG1sTm9kZSBBIERPTSBub2RlIHRvIGJlIHVzZWQgYXMgY29udGVudCBmb3IgdGhlIHBvcHVwLlxuICAgICAqIEByZXR1cm5zIHtQb3B1cH0gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIGNyZWF0ZSBhbiBlbGVtZW50IHdpdGggdGhlIHBvcHVwIGNvbnRlbnRcbiAgICAgKiBjb25zdCBkaXYgPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICogZGl2LmlubmVySFRNTCA9ICdIZWxsbywgd29ybGQhJztcbiAgICAgKiBjb25zdCBwb3B1cCA9IG5ldyBtYXBib3hnbC5Qb3B1cCgpXG4gICAgICogICAgIC5zZXRMbmdMYXQoZS5sbmdMYXQpXG4gICAgICogICAgIC5zZXRET01Db250ZW50KGRpdilcbiAgICAgKiAgICAgLmFkZFRvKG1hcCk7XG4gICAgICovXG4gICAgc2V0RE9NQ29udGVudChodG1sTm9kZTogTm9kZSk6IHRoaXMge1xuICAgICAgICBsZXQgY29udGVudCA9IHRoaXMuX2NvbnRlbnQ7XG4gICAgICAgIGlmIChjb250ZW50KSB7XG4gICAgICAgICAgICAvLyBDbGVhciBvdXQgY2hpbGRyZW4gZmlyc3QuXG4gICAgICAgICAgICB3aGlsZSAoY29udGVudC5oYXNDaGlsZE5vZGVzKCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoY29udGVudC5maXJzdENoaWxkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucmVtb3ZlQ2hpbGQoY29udGVudC5maXJzdENoaWxkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb250ZW50ID0gdGhpcy5fY29udGVudCA9IERPTS5jcmVhdGUoJ2RpdicsICdtYXBib3hnbC1wb3B1cC1jb250ZW50JywgdGhpcy5fY29udGFpbmVyIHx8IHVuZGVmaW5lZCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBUaGUgY2xvc2UgYnV0dG9uIHNob3VsZCBiZSB0aGUgbGFzdCB0YWJiYWJsZSBlbGVtZW50IGluc2lkZSB0aGUgcG9wdXAgZm9yIGEgZ29vZCBrZXlib2FyZCBVWC5cbiAgICAgICAgY29udGVudC5hcHBlbmRDaGlsZChodG1sTm9kZSk7XG5cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5jbG9zZUJ1dHRvbikge1xuICAgICAgICAgICAgY29uc3QgYnV0dG9uID0gdGhpcy5fY2xvc2VCdXR0b24gPSBET00uY3JlYXRlKCdidXR0b24nLCAnbWFwYm94Z2wtcG9wdXAtY2xvc2UtYnV0dG9uJywgY29udGVudCk7XG4gICAgICAgICAgICBidXR0b24udHlwZSA9ICdidXR0b24nO1xuICAgICAgICAgICAgYnV0dG9uLnNldEF0dHJpYnV0ZSgnYXJpYS1sYWJlbCcsICdDbG9zZSBwb3B1cCcpO1xuICAgICAgICAgICAgYnV0dG9uLnNldEF0dHJpYnV0ZSgnYXJpYS1oaWRkZW4nLCAndHJ1ZScpO1xuICAgICAgICAgICAgYnV0dG9uLmlubmVySFRNTCA9ICcmIzIxNTsnO1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fb25DbG9zZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fdXBkYXRlKCk7XG4gICAgICAgIHRoaXMuX2ZvY3VzRmlyc3RFbGVtZW50KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZHMgYSBDU1MgY2xhc3MgdG8gdGhlIHBvcHVwIGNvbnRhaW5lciBlbGVtZW50LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGNsYXNzTmFtZSBOb24tZW1wdHkgc3RyaW5nIHdpdGggQ1NTIGNsYXNzIG5hbWUgdG8gYWRkIHRvIHBvcHVwIGNvbnRhaW5lci5cbiAgICAgKiBAcmV0dXJucyB7UG9wdXB9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBvcHVwID0gbmV3IG1hcGJveGdsLlBvcHVwKCk7XG4gICAgICogcG9wdXAuYWRkQ2xhc3NOYW1lKCdzb21lLWNsYXNzJyk7XG4gICAgICovXG4gICAgYWRkQ2xhc3NOYW1lKGNsYXNzTmFtZTogc3RyaW5nKTogdGhpcyB7XG4gICAgICAgIHRoaXMuX2NsYXNzTGlzdC5hZGQoY2xhc3NOYW1lKTtcbiAgICAgICAgdGhpcy5fdXBkYXRlQ2xhc3NMaXN0KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYSBDU1MgY2xhc3MgZnJvbSB0aGUgcG9wdXAgY29udGFpbmVyIGVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NOYW1lIE5vbi1lbXB0eSBzdHJpbmcgd2l0aCBDU1MgY2xhc3MgbmFtZSB0byByZW1vdmUgZnJvbSBwb3B1cCBjb250YWluZXIuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7UG9wdXB9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwb3B1cCA9IG5ldyBtYXBib3hnbC5Qb3B1cCh7Y2xhc3NOYW1lOiAnc29tZSBjbGFzc2VzJ30pO1xuICAgICAqIHBvcHVwLnJlbW92ZUNsYXNzTmFtZSgnc29tZScpO1xuICAgICAqL1xuICAgIHJlbW92ZUNsYXNzTmFtZShjbGFzc05hbWU6IHN0cmluZyk6IHRoaXMge1xuICAgICAgICB0aGlzLl9jbGFzc0xpc3QuZGVsZXRlKGNsYXNzTmFtZSk7XG4gICAgICAgIHRoaXMuX3VwZGF0ZUNsYXNzTGlzdCgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBwb3B1cCdzIG9mZnNldC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7bnVtYmVyIHwgUG9pbnRMaWtlIHwgT2JqZWN0fSBvZmZzZXQgU2V0cyB0aGUgcG9wdXAncyBvZmZzZXQuIFRoZSBgT2JqZWN0YCBpcyBvZiB0aGUgZm9sbG93aW5nIHN0cnVjdHVyZVxuICAgICAqIHtcbiAgICAgKiAgICAnY2VudGVyJzogP1BvaW50TGlrZSxcbiAgICAgKiAgICAndG9wJzogP1BvaW50TGlrZSxcbiAgICAgKiAgICAnYm90dG9tJzogP1BvaW50TGlrZSxcbiAgICAgKiAgICAnbGVmdCc6ID9Qb2ludExpa2UsXG4gICAgICogICAgJ3JpZ2h0JzogP1BvaW50TGlrZSxcbiAgICAgKiAgICAndG9wLWxlZnQnOiA/UG9pbnRMaWtlLFxuICAgICAqICAgICd0b3AtcmlnaHQnOiA/UG9pbnRMaWtlLFxuICAgICAqICAgICdib3R0b20tbGVmdCc6ID9Qb2ludExpa2UsXG4gICAgICogICAgJ2JvdHRvbS1yaWdodCc6ID9Qb2ludExpa2VcbiAgICAgKiB9LlxuICAgICAqXG4gICAgICogQHJldHVybnMge1BvcHVwfSBgdGhpc2AuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBwb3B1cC5zZXRPZmZzZXQoMTApO1xuICAgICAqL1xuICAgIHNldE9mZnNldCAob2Zmc2V0PzogT2Zmc2V0KTogdGhpcyB7XG4gICAgICAgIHRoaXMub3B0aW9ucy5vZmZzZXQgPSBvZmZzZXQ7XG4gICAgICAgIHRoaXMuX3VwZGF0ZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGQgb3IgcmVtb3ZlIHRoZSBnaXZlbiBDU1MgY2xhc3Mgb24gdGhlIHBvcHVwIGNvbnRhaW5lciwgZGVwZW5kaW5nIG9uIHdoZXRoZXIgdGhlIGNvbnRhaW5lciBjdXJyZW50bHkgaGFzIHRoYXQgY2xhc3MuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NOYW1lIE5vbi1lbXB0eSBzdHJpbmcgd2l0aCBDU1MgY2xhc3MgbmFtZSB0byBhZGQvcmVtb3ZlLlxuICAgICAqXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IElmIHRoZSBjbGFzcyB3YXMgcmVtb3ZlZCByZXR1cm4gYGZhbHNlYC4gSWYgdGhlIGNsYXNzIHdhcyBhZGRlZCwgdGhlbiByZXR1cm4gYHRydWVgLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwb3B1cCA9IG5ldyBtYXBib3hnbC5Qb3B1cCgpO1xuICAgICAqIHBvcHVwLnRvZ2dsZUNsYXNzTmFtZSgnaGlnaGxpZ2h0ZWQnKTtcbiAgICAgKi9cbiAgICB0b2dnbGVDbGFzc05hbWUoY2xhc3NOYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgICAgbGV0IGZpbmFsU3RhdGU6IGJvb2xlYW47XG4gICAgICAgIGlmICh0aGlzLl9jbGFzc0xpc3QuZGVsZXRlKGNsYXNzTmFtZSkpIHtcbiAgICAgICAgICAgIGZpbmFsU3RhdGUgPSBmYWxzZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2NsYXNzTGlzdC5hZGQoY2xhc3NOYW1lKTtcbiAgICAgICAgICAgIGZpbmFsU3RhdGUgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3VwZGF0ZUNsYXNzTGlzdCgpO1xuICAgICAgICByZXR1cm4gZmluYWxTdGF0ZTtcbiAgICB9XG5cbiAgICBfb25Nb3VzZUV2ZW50KGV2ZW50OiBNYXBNb3VzZUV2ZW50KSB7XG4gICAgICAgIHRoaXMuX3VwZGF0ZShldmVudC5wb2ludCk7XG4gICAgfVxuXG4gICAgX2dldEFuY2hvcihib3R0b21ZOiBudW1iZXIpOiBBbmNob3Ige1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLmFuY2hvcikgeyByZXR1cm4gdGhpcy5vcHRpb25zLmFuY2hvcjsgfVxuXG4gICAgICAgIGNvbnN0IG1hcCA9IHRoaXMuX21hcDtcbiAgICAgICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5fY29udGFpbmVyO1xuICAgICAgICBjb25zdCBwb3MgPSB0aGlzLl9wb3M7XG5cbiAgICAgICAgaWYgKCFtYXAgfHwgIWNvbnRhaW5lciB8fCAhcG9zKSByZXR1cm4gJ2JvdHRvbSc7XG5cbiAgICAgICAgY29uc3Qgd2lkdGggPSBjb250YWluZXIub2Zmc2V0V2lkdGg7XG4gICAgICAgIGNvbnN0IGhlaWdodCA9IGNvbnRhaW5lci5vZmZzZXRIZWlnaHQ7XG5cbiAgICAgICAgY29uc3QgaXNUb3AgPSBwb3MueSArIGJvdHRvbVkgPCBoZWlnaHQ7XG4gICAgICAgIGNvbnN0IGlzQm90dG9tID0gcG9zLnkgPiBtYXAudHJhbnNmb3JtLmhlaWdodCAtIGhlaWdodDtcbiAgICAgICAgY29uc3QgaXNMZWZ0ID0gcG9zLnggPCB3aWR0aCAvIDI7XG4gICAgICAgIGNvbnN0IGlzUmlnaHQgPSBwb3MueCA+IG1hcC50cmFuc2Zvcm0ud2lkdGggLSB3aWR0aCAvIDI7XG5cbiAgICAgICAgaWYgKGlzVG9wKSB7XG4gICAgICAgICAgICBpZiAoaXNMZWZ0KSByZXR1cm4gJ3RvcC1sZWZ0JztcbiAgICAgICAgICAgIGlmIChpc1JpZ2h0KSByZXR1cm4gJ3RvcC1yaWdodCc7XG4gICAgICAgICAgICByZXR1cm4gJ3RvcCc7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzQm90dG9tKSB7XG4gICAgICAgICAgICBpZiAoaXNMZWZ0KSByZXR1cm4gJ2JvdHRvbS1sZWZ0JztcbiAgICAgICAgICAgIGlmIChpc1JpZ2h0KSByZXR1cm4gJ2JvdHRvbS1yaWdodCc7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzTGVmdCkgcmV0dXJuICdsZWZ0JztcbiAgICAgICAgaWYgKGlzUmlnaHQpIHJldHVybiAncmlnaHQnO1xuXG4gICAgICAgIHJldHVybiAnYm90dG9tJztcbiAgICB9XG5cbiAgICBfdXBkYXRlQ2xhc3NMaXN0KCkge1xuICAgICAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLl9jb250YWluZXI7XG4gICAgICAgIGlmICghY29udGFpbmVyKSByZXR1cm47XG5cbiAgICAgICAgY29uc3QgY2xhc3NlcyA9IFsuLi50aGlzLl9jbGFzc0xpc3RdO1xuICAgICAgICBjbGFzc2VzLnB1c2goJ21hcGJveGdsLXBvcHVwJyk7XG4gICAgICAgIGlmICh0aGlzLl9hbmNob3IpIHtcbiAgICAgICAgICAgIGNsYXNzZXMucHVzaChgbWFwYm94Z2wtcG9wdXAtYW5jaG9yLSR7dGhpcy5fYW5jaG9yfWApO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl90cmFja1BvaW50ZXIpIHtcbiAgICAgICAgICAgIGNsYXNzZXMucHVzaCgnbWFwYm94Z2wtcG9wdXAtdHJhY2stcG9pbnRlcicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRhaW5lci5jbGFzc05hbWUgPSBjbGFzc2VzLmpvaW4oJyAnKTtcbiAgICB9XG5cbiAgICBfdXBkYXRlKGN1cnNvcj86IFBvaW50KSB7XG4gICAgICAgIGNvbnN0IGhhc1Bvc2l0aW9uID0gdGhpcy5fbG5nTGF0IHx8IHRoaXMuX3RyYWNrUG9pbnRlcjtcbiAgICAgICAgY29uc3QgbWFwID0gdGhpcy5fbWFwO1xuICAgICAgICBjb25zdCBjb250ZW50ID0gdGhpcy5fY29udGVudDtcblxuICAgICAgICBpZiAoIW1hcCB8fCAhaGFzUG9zaXRpb24gfHwgIWNvbnRlbnQpIHsgcmV0dXJuOyB9XG5cbiAgICAgICAgbGV0IGNvbnRhaW5lciA9IHRoaXMuX2NvbnRhaW5lcjtcblxuICAgICAgICBpZiAoIWNvbnRhaW5lcikge1xuICAgICAgICAgICAgY29udGFpbmVyID0gdGhpcy5fY29udGFpbmVyID0gRE9NLmNyZWF0ZSgnZGl2JywgJ21hcGJveGdsLXBvcHVwJywgbWFwLmdldENvbnRhaW5lcigpKTtcbiAgICAgICAgICAgIHRoaXMuX3RpcCA9IERPTS5jcmVhdGUoJ2RpdicsICdtYXBib3hnbC1wb3B1cC10aXAnLCBjb250YWluZXIpO1xuICAgICAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGNvbnRlbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5tYXhXaWR0aCAmJiBjb250YWluZXIuc3R5bGUubWF4V2lkdGggIT09IHRoaXMub3B0aW9ucy5tYXhXaWR0aCkge1xuICAgICAgICAgICAgY29udGFpbmVyLnN0eWxlLm1heFdpZHRoID0gdGhpcy5vcHRpb25zLm1heFdpZHRoO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1hcC50cmFuc2Zvcm0ucmVuZGVyV29ybGRDb3BpZXMgJiYgIXRoaXMuX3RyYWNrUG9pbnRlcikge1xuICAgICAgICAgICAgdGhpcy5fbG5nTGF0ID0gc21hcnRXcmFwKHRoaXMuX2xuZ0xhdCwgdGhpcy5fcG9zLCBtYXAudHJhbnNmb3JtKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5fdHJhY2tQb2ludGVyIHx8IGN1cnNvcikge1xuICAgICAgICAgICAgY29uc3QgcG9zID0gdGhpcy5fcG9zID0gdGhpcy5fdHJhY2tQb2ludGVyICYmIGN1cnNvciA/IGN1cnNvciA6IG1hcC5wcm9qZWN0KHRoaXMuX2xuZ0xhdCk7XG5cbiAgICAgICAgICAgIGNvbnN0IG9mZnNldEJvdHRvbSA9IG5vcm1hbGl6ZU9mZnNldCh0aGlzLm9wdGlvbnMub2Zmc2V0KTtcbiAgICAgICAgICAgIGNvbnN0IGFuY2hvciA9IHRoaXMuX2FuY2hvciA9IHRoaXMuX2dldEFuY2hvcihvZmZzZXRCb3R0b20ueSk7XG4gICAgICAgICAgICBjb25zdCBvZmZzZXQgPSBub3JtYWxpemVPZmZzZXQodGhpcy5vcHRpb25zLm9mZnNldCwgYW5jaG9yKTtcblxuICAgICAgICAgICAgY29uc3Qgb2Zmc2V0ZWRQb3MgPSBwb3MuYWRkKG9mZnNldCkucm91bmQoKTtcbiAgICAgICAgICAgIG1hcC5fcmVxdWVzdERvbVRhc2soKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9jb250YWluZXIgJiYgYW5jaG9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2NvbnRhaW5lci5zdHlsZS50cmFuc2Zvcm0gPSBgJHthbmNob3JUcmFuc2xhdGVbYW5jaG9yXX0gdHJhbnNsYXRlKCR7b2Zmc2V0ZWRQb3MueH1weCwke29mZnNldGVkUG9zLnl9cHgpYDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5fbWFya2VyICYmIG1hcC5fc2hvd2luZ0dsb2JlKCkpIHtcbiAgICAgICAgICAgIGNvbnN0IG9wYWNpdHkgPSBpc0xuZ0xhdEJlaGluZEdsb2JlKG1hcC50cmFuc2Zvcm0sIHRoaXMuX2xuZ0xhdCkgPyAwIDogMTtcbiAgICAgICAgICAgIHRoaXMuX3NldE9wYWNpdHkob3BhY2l0eSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl91cGRhdGVDbGFzc0xpc3QoKTtcbiAgICB9XG5cbiAgICBfZm9jdXNGaXJzdEVsZW1lbnQoKSB7XG4gICAgICAgIGlmICghdGhpcy5vcHRpb25zLmZvY3VzQWZ0ZXJPcGVuIHx8ICF0aGlzLl9jb250YWluZXIpIHJldHVybjtcblxuICAgICAgICBjb25zdCBmaXJzdEZvY3VzYWJsZSA9IHRoaXMuX2NvbnRhaW5lci5xdWVyeVNlbGVjdG9yKGZvY3VzUXVlcnlTZWxlY3Rvcik7XG5cbiAgICAgICAgaWYgKGZpcnN0Rm9jdXNhYmxlKSBmaXJzdEZvY3VzYWJsZS5mb2N1cygpO1xuICAgIH1cblxuICAgIF9vbkNsb3NlKCkge1xuICAgICAgICB0aGlzLnJlbW92ZSgpO1xuICAgIH1cblxuICAgIF9zZXRPcGFjaXR5KG9wYWNpdHk6IG51bWJlcikge1xuICAgICAgICBpZiAodGhpcy5fY29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aGlzLl9jb250YWluZXIuc3R5bGUub3BhY2l0eSA9IGAke29wYWNpdHl9YDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fY29udGVudCkge1xuICAgICAgICAgICAgdGhpcy5fY29udGVudC5zdHlsZS5wb2ludGVyRXZlbnRzID0gb3BhY2l0eSA/ICdhdXRvJyA6ICdub25lJztcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLy8gcmV0dXJucyBhIG5vcm1hbGl6ZWQgb2Zmc2V0IGZvciBhIGdpdmVuIGFuY2hvclxuZnVuY3Rpb24gbm9ybWFsaXplT2Zmc2V0KG9mZnNldDogT2Zmc2V0ID0gbmV3IFBvaW50KDAsIDApLCBhbmNob3I6IEFuY2hvciA9ICdib3R0b20nKTogUG9pbnQge1xuICAgIGlmICh0eXBlb2Ygb2Zmc2V0ID09PSAnbnVtYmVyJykge1xuICAgICAgICAvLyBpbnB1dCBzcGVjaWZpZXMgYSByYWRpdXMgZnJvbSB3aGljaCB0byBjYWxjdWxhdGUgb2Zmc2V0cyBhdCBhbGwgcG9zaXRpb25zXG4gICAgICAgIGNvbnN0IGNvcm5lck9mZnNldCA9IE1hdGgucm91bmQoTWF0aC5zcXJ0KDAuNSAqIE1hdGgucG93KG9mZnNldCwgMikpKTtcbiAgICAgICAgc3dpdGNoIChhbmNob3IpIHtcbiAgICAgICAgY2FzZSAndG9wJzogcmV0dXJuIG5ldyBQb2ludCgwLCBvZmZzZXQpO1xuICAgICAgICBjYXNlICd0b3AtbGVmdCc6IHJldHVybiBuZXcgUG9pbnQoY29ybmVyT2Zmc2V0LCBjb3JuZXJPZmZzZXQpO1xuICAgICAgICBjYXNlICd0b3AtcmlnaHQnOiByZXR1cm4gbmV3IFBvaW50KC1jb3JuZXJPZmZzZXQsIGNvcm5lck9mZnNldCk7XG4gICAgICAgIGNhc2UgJ2JvdHRvbSc6IHJldHVybiBuZXcgUG9pbnQoMCwgLW9mZnNldCk7XG4gICAgICAgIGNhc2UgJ2JvdHRvbS1sZWZ0JzogcmV0dXJuIG5ldyBQb2ludChjb3JuZXJPZmZzZXQsIC1jb3JuZXJPZmZzZXQpO1xuICAgICAgICBjYXNlICdib3R0b20tcmlnaHQnOiByZXR1cm4gbmV3IFBvaW50KC1jb3JuZXJPZmZzZXQsIC1jb3JuZXJPZmZzZXQpO1xuICAgICAgICBjYXNlICdsZWZ0JzogcmV0dXJuIG5ldyBQb2ludChvZmZzZXQsIDApO1xuICAgICAgICBjYXNlICdyaWdodCc6IHJldHVybiBuZXcgUG9pbnQoLW9mZnNldCwgMCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBQb2ludCgwLCAwKTtcbiAgICB9XG5cbiAgICBpZiAob2Zmc2V0IGluc3RhbmNlb2YgUG9pbnQgfHwgQXJyYXkuaXNBcnJheShvZmZzZXQpKSB7XG4gICAgICAgIC8vIGlucHV0IHNwZWNpZmllcyBhIHNpbmdsZSBvZmZzZXQgdG8gYmUgYXBwbGllZCB0byBhbGwgcG9zaXRpb25zXG4gICAgICAgIHJldHVybiBQb2ludC5jb252ZXJ0KG9mZnNldCk7XG4gICAgfVxuXG4gICAgLy8gaW5wdXQgc3BlY2lmaWVzIGFuIG9mZnNldCBwZXIgcG9zaXRpb25cbiAgICAvLyAkRmxvd0ZpeE1lIHdlIGtub3cgb2Zmc2V0IGlzIGFuIG9iamVjdCBhdCB0aGlzIHBvaW50IGJ1dCBGbG93IGNhbid0IHJlZmluZSBpdCBmb3Igc29tZSByZWFzb25cbiAgICByZXR1cm4gUG9pbnQuY29udmVydChvZmZzZXRbYW5jaG9yXSB8fCBbMCwgMF0pO1xufVxuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtlYXNlQ3ViaWNJbk91dH0gZnJvbSAnLi91dGlsLmpzJztcblxuLyoqXG4gKiBBbiBvYmplY3QgZm9yIG1haW50YWluaW5nIGp1c3QgZW5vdWdoIHN0YXRlIHRvIGVhc2UgYSB2YXJpYWJsZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5jbGFzcyBFYXNlZFZhcmlhYmxlIHtcbiAgICBfc3RhcnQ6IG51bWJlcjtcbiAgICBfZW5kOiBudW1iZXI7XG4gICAgX3N0YXJ0VGltZTogbnVtYmVyO1xuICAgIF9lbmRUaW1lOiBudW1iZXI7XG5cbiAgICBjb25zdHJ1Y3Rvcihpbml0aWFsVmFsdWU6IG51bWJlcikge1xuICAgICAgICB0aGlzLmp1bXBUbyhpbml0aWFsVmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV2YWx1YXRlIHRoZSBjdXJyZW50IHZhbHVlLCBnaXZlbiBhIHRpbWVzdGFtcC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0aW1lU3RhbXAge251bWJlcn0gVGltZSBhdCB3aGljaCB0byBldmFsdWF0ZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IEV2YWx1YXRlZCB2YWx1ZS5cbiAgICAgKi9cbiAgICBnZXRWYWx1ZSh0aW1lU3RhbXA6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGlmICh0aW1lU3RhbXAgPD0gdGhpcy5fc3RhcnRUaW1lKSByZXR1cm4gdGhpcy5fc3RhcnQ7XG4gICAgICAgIGlmICh0aW1lU3RhbXAgPj0gdGhpcy5fZW5kVGltZSkgcmV0dXJuIHRoaXMuX2VuZDtcblxuICAgICAgICBjb25zdCB0ID0gZWFzZUN1YmljSW5PdXQoKHRpbWVTdGFtcCAtIHRoaXMuX3N0YXJ0VGltZSkgLyAodGhpcy5fZW5kVGltZSAtIHRoaXMuX3N0YXJ0VGltZSkpO1xuICAgICAgICByZXR1cm4gdGhpcy5fc3RhcnQgKiAoMSAtIHQpICsgdGhpcy5fZW5kICogdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVjayBpZiBhbiBlYXNlIGlzIGluIHByb2dyZXNzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHRpbWVTdGFtcCB7bnVtYmVyfSBDdXJyZW50IHRpbWUgc3RhbXAuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgZWFzZSBpcyBpbiBwcm9ncmVzcy5cbiAgICAgKi9cbiAgICBpc0Vhc2luZyh0aW1lU3RhbXA6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGltZVN0YW1wID49IHRoaXMuX3N0YXJ0VGltZSAmJiB0aW1lU3RhbXAgPD0gdGhpcy5fZW5kVGltZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIHZhbHVlIHdpdGhvdXQgZWFzaW5nIGFuZCBjYW5jZWwgYW55IGluIHByb2dyZXNzIGVhc2UuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWUge251bWJlcn0gTmV3IHZhbHVlLlxuICAgICAqL1xuICAgIGp1bXBUbyh2YWx1ZTogbnVtYmVyKSB7XG4gICAgICAgIHRoaXMuX3N0YXJ0VGltZSA9IC1JbmZpbml0eTtcbiAgICAgICAgdGhpcy5fZW5kVGltZSA9IC1JbmZpbml0eTtcblxuICAgICAgICB0aGlzLl9zdGFydCA9IHZhbHVlO1xuICAgICAgICB0aGlzLl9lbmQgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYW5jZWwgYW55IGluLXByb2dyZXNzIGVhc2UgYW5kIGJlZ2luIGEgbmV3IGVhc2UuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWUge251bWJlcn0gTmV3IHZhbHVlIHRvIHdoaWNoIHRvIGVhc2UuXG4gICAgICogQHBhcmFtIHRpbWVTdGFtcCB7bnVtYmVyfSBDdXJyZW50IHRpbWUgc3RhbXAuXG4gICAgICogQHBhcmFtIGR1cmF0aW9uIHtudW1iZXJ9IEVhc2UgZHVyYXRpb24sIGluIHNhbWUgdW5pdHMgYXMgdGltZVN0YW1wLlxuICAgICAqL1xuICAgIGVhc2VUbyh2YWx1ZTogbnVtYmVyLCB0aW1lU3RhbXA6IG51bWJlciwgZHVyYXRpb246IG51bWJlcikge1xuICAgICAgICB0aGlzLl9zdGFydCA9IHRoaXMuZ2V0VmFsdWUodGltZVN0YW1wKTtcbiAgICAgICAgdGhpcy5fZW5kID0gdmFsdWU7XG5cbiAgICAgICAgdGhpcy5fc3RhcnRUaW1lID0gdGltZVN0YW1wO1xuICAgICAgICB0aGlzLl9lbmRUaW1lID0gdGltZVN0YW1wICsgZHVyYXRpb247XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBFYXNlZFZhcmlhYmxlO1xuIiwiLy8gQGZsb3dcblxuY29uc3QgZGVmYXVsdExvY2FsZSA9IHtcbiAgICAnQXR0cmlidXRpb25Db250cm9sLlRvZ2dsZUF0dHJpYnV0aW9uJzogJ1RvZ2dsZSBhdHRyaWJ1dGlvbicsXG4gICAgJ0F0dHJpYnV0aW9uQ29udHJvbC5NYXBGZWVkYmFjayc6ICdNYXAgZmVlZGJhY2snLFxuICAgICdGdWxsc2NyZWVuQ29udHJvbC5FbnRlcic6ICdFbnRlciBmdWxsc2NyZWVuJyxcbiAgICAnRnVsbHNjcmVlbkNvbnRyb2wuRXhpdCc6ICdFeGl0IGZ1bGxzY3JlZW4nLFxuICAgICdHZW9sb2NhdGVDb250cm9sLkZpbmRNeUxvY2F0aW9uJzogJ0ZpbmQgbXkgbG9jYXRpb24nLFxuICAgICdHZW9sb2NhdGVDb250cm9sLkxvY2F0aW9uTm90QXZhaWxhYmxlJzogJ0xvY2F0aW9uIG5vdCBhdmFpbGFibGUnLFxuICAgICdMb2dvQ29udHJvbC5UaXRsZSc6ICdNYXBib3ggbG9nbycsXG4gICAgJ01hcC5UaXRsZSc6ICdNYXAnLFxuICAgICdOYXZpZ2F0aW9uQ29udHJvbC5SZXNldEJlYXJpbmcnOiAnUmVzZXQgYmVhcmluZyB0byBub3J0aCcsXG4gICAgJ05hdmlnYXRpb25Db250cm9sLlpvb21Jbic6ICdab29tIGluJyxcbiAgICAnTmF2aWdhdGlvbkNvbnRyb2wuWm9vbU91dCc6ICdab29tIG91dCcsXG4gICAgJ1Njcm9sbFpvb21CbG9ja2VyLkN0cmxNZXNzYWdlJzogJ1VzZSBjdHJsICsgc2Nyb2xsIHRvIHpvb20gdGhlIG1hcCcsXG4gICAgJ1Njcm9sbFpvb21CbG9ja2VyLkNtZE1lc3NhZ2UnOiAnVXNlIOKMmCArIHNjcm9sbCB0byB6b29tIHRoZSBtYXAnLFxuICAgICdUb3VjaFBhbkJsb2NrZXIuTWVzc2FnZSc6ICdVc2UgdHdvIGZpbmdlcnMgdG8gbW92ZSB0aGUgbWFwJ1xufTtcblxuZXhwb3J0IGRlZmF1bHQgZGVmYXVsdExvY2FsZTtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCB7dmVyc2lvbn0gZnJvbSAnLi4vLi4vcGFja2FnZS5qc29uJztcbmltcG9ydCB7YXN5bmNBbGwsIGV4dGVuZCwgYmluZEFsbCwgd2Fybk9uY2UsIHVuaXF1ZUlkLCBpc1NhZmFyaVdpdGhBbnRpYWxpYXNpbmdCdWd9IGZyb20gJy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQgYnJvd3NlciBmcm9tICcuLi91dGlsL2Jyb3dzZXIuanMnO1xuaW1wb3J0IHdpbmRvdyBmcm9tICcuLi91dGlsL3dpbmRvdy5qcyc7XG5pbXBvcnQgKiBhcyBET00gZnJvbSAnLi4vdXRpbC9kb20uanMnO1xuaW1wb3J0IHtnZXRJbWFnZSwgZ2V0SlNPTiwgUmVzb3VyY2VUeXBlfSBmcm9tICcuLi91dGlsL2FqYXguanMnO1xuaW1wb3J0IHtSZXF1ZXN0TWFuYWdlciwgZ2V0TWFwU2Vzc2lvbkFQSSwgcG9zdFBlcmZvcm1hbmNlRXZlbnQsIHBvc3RNYXBMb2FkRXZlbnQsIEFVVEhfRVJSX01TRywgc3RvcmVBdXRoU3RhdGUsIHJlbW92ZUF1dGhTdGF0ZX0gZnJvbSAnLi4vdXRpbC9tYXBib3guanMnO1xuaW1wb3J0IFN0eWxlIGZyb20gJy4uL3N0eWxlL3N0eWxlLmpzJztcbmltcG9ydCBFdmFsdWF0aW9uUGFyYW1ldGVycyBmcm9tICcuLi9zdHlsZS9ldmFsdWF0aW9uX3BhcmFtZXRlcnMuanMnO1xuaW1wb3J0IFBhaW50ZXIgZnJvbSAnLi4vcmVuZGVyL3BhaW50ZXIuanMnO1xuaW1wb3J0IFRyYW5zZm9ybSBmcm9tICcuLi9nZW8vdHJhbnNmb3JtLmpzJztcbmltcG9ydCBIYXNoIGZyb20gJy4vaGFzaC5qcyc7XG5pbXBvcnQgSGFuZGxlck1hbmFnZXIgZnJvbSAnLi9oYW5kbGVyX21hbmFnZXIuanMnO1xuaW1wb3J0IENhbWVyYSBmcm9tICcuL2NhbWVyYS5qcyc7XG5pbXBvcnQgTG5nTGF0IGZyb20gJy4uL2dlby9sbmdfbGF0LmpzJztcbmltcG9ydCBMbmdMYXRCb3VuZHMgZnJvbSAnLi4vZ2VvL2xuZ19sYXRfYm91bmRzLmpzJztcbmltcG9ydCBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCBBdHRyaWJ1dGlvbkNvbnRyb2wgZnJvbSAnLi9jb250cm9sL2F0dHJpYnV0aW9uX2NvbnRyb2wuanMnO1xuaW1wb3J0IExvZ29Db250cm9sIGZyb20gJy4vY29udHJvbC9sb2dvX2NvbnRyb2wuanMnO1xuaW1wb3J0IHtzdXBwb3J0ZWR9IGZyb20gJ0BtYXBib3gvbWFwYm94LWdsLXN1cHBvcnRlZCc7XG5pbXBvcnQge1JHQkFJbWFnZX0gZnJvbSAnLi4vdXRpbC9pbWFnZS5qcyc7XG5pbXBvcnQge0V2ZW50LCBFcnJvckV2ZW50fSBmcm9tICcuLi91dGlsL2V2ZW50ZWQuanMnO1xuaW1wb3J0IHtNYXBNb3VzZUV2ZW50fSBmcm9tICcuL2V2ZW50cy5qcyc7XG5pbXBvcnQgVGFza1F1ZXVlIGZyb20gJy4uL3V0aWwvdGFza19xdWV1ZS5qcyc7XG5pbXBvcnQgd2VicFN1cHBvcnRlZCBmcm9tICcuLi91dGlsL3dlYnBfc3VwcG9ydGVkLmpzJztcbmltcG9ydCB7UGVyZm9ybWFuY2VVdGlsc30gZnJvbSAnLi4vdXRpbC9wZXJmb3JtYW5jZS5qcyc7XG5pbXBvcnQge1BlcmZvcm1hbmNlTWFya2VycywgTGl2ZVBlcmZvcm1hbmNlVXRpbHN9IGZyb20gJy4uL3V0aWwvbGl2ZV9wZXJmb3JtYW5jZS5qcyc7XG5pbXBvcnQgTWFya2VyIGZyb20gJy4uL3VpL21hcmtlci5qcyc7XG5pbXBvcnQgUG9wdXAgZnJvbSAnLi4vdWkvcG9wdXAuanMnO1xuaW1wb3J0IEVhc2VkVmFyaWFibGUgZnJvbSAnLi4vdXRpbC9lYXNlZF92YXJpYWJsZS5qcyc7XG5pbXBvcnQgU291cmNlQ2FjaGUgZnJvbSAnLi4vc291cmNlL3NvdXJjZV9jYWNoZS5qcyc7XG5pbXBvcnQge0dMT0JFX1pPT01fVEhSRVNIT0xEX01BWH0gZnJvbSAnLi4vZ2VvL3Byb2plY3Rpb24vZ2xvYmVfdXRpbC5qcyc7XG5pbXBvcnQge3NldENhY2hlTGltaXRzfSBmcm9tICcuLi91dGlsL3RpbGVfcmVxdWVzdF9jYWNoZS5qcyc7XG5pbXBvcnQge0RlYnVnfSBmcm9tICcuLi91dGlsL2RlYnVnLmpzJztcblxuaW1wb3J0IHR5cGUge1BvaW50TGlrZX0gZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5pbXBvcnQgdHlwZSB7UmVxdWVzdFRyYW5zZm9ybUZ1bmN0aW9ufSBmcm9tICcuLi91dGlsL21hcGJveC5qcyc7XG5pbXBvcnQgdHlwZSB7TG5nTGF0TGlrZX0gZnJvbSAnLi4vZ2VvL2xuZ19sYXQuanMnO1xuaW1wb3J0IHR5cGUge0xuZ0xhdEJvdW5kc0xpa2V9IGZyb20gJy4uL2dlby9sbmdfbGF0X2JvdW5kcy5qcyc7XG5pbXBvcnQgdHlwZSB7U3R5bGVPcHRpb25zLCBTdHlsZVNldHRlck9wdGlvbnN9IGZyb20gJy4uL3N0eWxlL3N0eWxlLmpzJztcbmltcG9ydCB0eXBlIHtNYXBFdmVudCwgTWFwRGF0YUV2ZW50fSBmcm9tICcuL2V2ZW50cy5qcyc7XG5pbXBvcnQgdHlwZSB7Q3VzdG9tTGF5ZXJJbnRlcmZhY2V9IGZyb20gJy4uL3N0eWxlL3N0eWxlX2xheWVyL2N1c3RvbV9zdHlsZV9sYXllci5qcyc7XG5pbXBvcnQgdHlwZSB7U3R5bGVJbWFnZUludGVyZmFjZSwgU3R5bGVJbWFnZU1ldGFkYXRhfSBmcm9tICcuLi9zdHlsZS9zdHlsZV9pbWFnZS5qcyc7XG5cbmltcG9ydCB0eXBlIFNjcm9sbFpvb21IYW5kbGVyIGZyb20gJy4vaGFuZGxlci9zY3JvbGxfem9vbS5qcyc7XG5pbXBvcnQgdHlwZSBCb3hab29tSGFuZGxlciBmcm9tICcuL2hhbmRsZXIvYm94X3pvb20uanMnO1xuaW1wb3J0IHR5cGUge1RvdWNoUGl0Y2hIYW5kbGVyfSBmcm9tICcuL2hhbmRsZXIvdG91Y2hfem9vbV9yb3RhdGUuanMnO1xuaW1wb3J0IHR5cGUgRHJhZ1JvdGF0ZUhhbmRsZXIgZnJvbSAnLi9oYW5kbGVyL3NoaW0vZHJhZ19yb3RhdGUuanMnO1xuaW1wb3J0IHR5cGUgRHJhZ1BhbkhhbmRsZXIsIHtEcmFnUGFuT3B0aW9uc30gZnJvbSAnLi9oYW5kbGVyL3NoaW0vZHJhZ19wYW4uanMnO1xuaW1wb3J0IHR5cGUgS2V5Ym9hcmRIYW5kbGVyIGZyb20gJy4vaGFuZGxlci9rZXlib2FyZC5qcyc7XG5pbXBvcnQgdHlwZSBEb3VibGVDbGlja1pvb21IYW5kbGVyIGZyb20gJy4vaGFuZGxlci9zaGltL2RibGNsaWNrX3pvb20uanMnO1xuaW1wb3J0IHR5cGUgVG91Y2hab29tUm90YXRlSGFuZGxlciBmcm9tICcuL2hhbmRsZXIvc2hpbS90b3VjaF96b29tX3JvdGF0ZS5qcyc7XG5pbXBvcnQgZGVmYXVsdExvY2FsZSBmcm9tICcuL2RlZmF1bHRfbG9jYWxlLmpzJztcbmltcG9ydCB0eXBlIHtUYXNrSUR9IGZyb20gJy4uL3V0aWwvdGFza19xdWV1ZS5qcyc7XG5pbXBvcnQgdHlwZSB7Q2FuY2VsYWJsZX0gZnJvbSAnLi4vdHlwZXMvY2FuY2VsYWJsZS5qcyc7XG5pbXBvcnQgdHlwZSB7XG4gICAgTGF5ZXJTcGVjaWZpY2F0aW9uLFxuICAgIEZpbHRlclNwZWNpZmljYXRpb24sXG4gICAgU3R5bGVTcGVjaWZpY2F0aW9uLFxuICAgIExpZ2h0U3BlY2lmaWNhdGlvbixcbiAgICBUZXJyYWluU3BlY2lmaWNhdGlvbixcbiAgICBGb2dTcGVjaWZpY2F0aW9uLFxuICAgIFNvdXJjZVNwZWNpZmljYXRpb24sXG4gICAgUHJvamVjdGlvblNwZWNpZmljYXRpb24sXG4gICAgUHJvcGVydHlWYWx1ZVNwZWNpZmljYXRpb24sXG4gICAgVHJhbnNpdGlvblNwZWNpZmljYXRpb25cbn0gZnJvbSAnLi4vc3R5bGUtc3BlYy90eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSBTdHlsZUxheWVyIGZyb20gJy4uL3N0eWxlL3N0eWxlX2xheWVyLmpzJztcbmltcG9ydCB0eXBlIHtTb3VyY2V9IGZyb20gJy4uL3NvdXJjZS9zb3VyY2UuanMnO1xuaW1wb3J0IHR5cGUge1F1ZXJ5RmVhdHVyZX0gZnJvbSAnLi4vdXRpbC92ZWN0b3J0aWxlX3RvX2dlb2pzb24uanMnO1xuaW1wb3J0IHR5cGUge1F1ZXJ5UmVzdWx0fSBmcm9tICcuLi9kYXRhL2ZlYXR1cmVfaW5kZXguanMnO1xuXG5leHBvcnQgdHlwZSBDb250cm9sUG9zaXRpb24gPSAndG9wLWxlZnQnIHwgJ3RvcC1yaWdodCcgfCAnYm90dG9tLWxlZnQnIHwgJ2JvdHRvbS1yaWdodCc7XG4vKiBlc2xpbnQtZGlzYWJsZSBuby11c2UtYmVmb3JlLWRlZmluZSAqL1xuaW50ZXJmYWNlIElDb250cm9sIHtcbiAgICArb25BZGQ6IChtYXA6IE1hcCkgPT4gSFRNTEVsZW1lbnQ7XG4gICAgK29uUmVtb3ZlOiAobWFwOiBNYXApID0+IHZvaWQ7XG5cbiAgICArZ2V0RGVmYXVsdFBvc2l0aW9uPzogKCkgPT4gQ29udHJvbFBvc2l0aW9uO1xuICAgICtfc2V0TGFuZ3VhZ2U/OiAobGFuZ3VhZ2U6ID9zdHJpbmcgfCA/c3RyaW5nW10pID0+IHZvaWQ7XG59XG4vKiBlc2xpbnQtZW5hYmxlIG5vLXVzZS1iZWZvcmUtZGVmaW5lICovXG5cbmV4cG9ydCBjb25zdCBBVkVSQUdFX0VMRVZBVElPTl9TQU1QTElOR19JTlRFUlZBTCA9IDUwMDsgLy8gbXNcbmV4cG9ydCBjb25zdCBBVkVSQUdFX0VMRVZBVElPTl9FQVNFX1RJTUUgPSAzMDA7IC8vIG1zXG5leHBvcnQgY29uc3QgQVZFUkFHRV9FTEVWQVRJT05fRUFTRV9USFJFU0hPTEQgPSAxOyAvLyBtZXRlcnNcbmV4cG9ydCBjb25zdCBBVkVSQUdFX0VMRVZBVElPTl9DSEFOR0VfVEhSRVNIT0xEID0gMWUtNDsgLy8gbWV0ZXJzXG5cbnR5cGUgTWFwT3B0aW9ucyA9IHtcbiAgICBoYXNoPzogYm9vbGVhbiB8IHN0cmluZyxcbiAgICBpbnRlcmFjdGl2ZT86IGJvb2xlYW4sXG4gICAgY29udGFpbmVyOiBIVE1MRWxlbWVudCB8IHN0cmluZyxcbiAgICBiZWFyaW5nU25hcD86IG51bWJlcixcbiAgICBhdHRyaWJ1dGlvbkNvbnRyb2w/OiBib29sZWFuLFxuICAgIGN1c3RvbUF0dHJpYnV0aW9uPzogc3RyaW5nIHwgQXJyYXk8c3RyaW5nPixcbiAgICBsb2dvUG9zaXRpb24/OiBDb250cm9sUG9zaXRpb24sXG4gICAgZmFpbElmTWFqb3JQZXJmb3JtYW5jZUNhdmVhdD86IGJvb2xlYW4sXG4gICAgcHJlc2VydmVEcmF3aW5nQnVmZmVyPzogYm9vbGVhbixcbiAgICBhbnRpYWxpYXM/OiBib29sZWFuLFxuICAgIHJlZnJlc2hFeHBpcmVkVGlsZXM/OiBib29sZWFuLFxuICAgIG1heEJvdW5kcz86IExuZ0xhdEJvdW5kc0xpa2UsXG4gICAgc2Nyb2xsWm9vbT86IGJvb2xlYW4sXG4gICAgbWluWm9vbT86ID9udW1iZXIsXG4gICAgbWF4Wm9vbT86ID9udW1iZXIsXG4gICAgbWluUGl0Y2g/OiA/bnVtYmVyLFxuICAgIG1heFBpdGNoPzogP251bWJlcixcbiAgICBib3hab29tPzogYm9vbGVhbixcbiAgICBkcmFnUm90YXRlPzogYm9vbGVhbixcbiAgICBkcmFnUGFuPzogRHJhZ1Bhbk9wdGlvbnMsXG4gICAga2V5Ym9hcmQ/OiBib29sZWFuLFxuICAgIGRvdWJsZUNsaWNrWm9vbT86IGJvb2xlYW4sXG4gICAgdG91Y2hab29tUm90YXRlPzogYm9vbGVhbixcbiAgICB0b3VjaFBpdGNoPzogYm9vbGVhbixcbiAgICBjb29wZXJhdGl2ZUdlc3R1cmVzPzogYm9vbGVhbixcbiAgICB0cmFja1Jlc2l6ZT86IGJvb2xlYW4sXG4gICAgY2VudGVyPzogTG5nTGF0TGlrZSxcbiAgICB6b29tPzogbnVtYmVyLFxuICAgIGJlYXJpbmc/OiBudW1iZXIsXG4gICAgcGl0Y2g/OiBudW1iZXIsXG4gICAgb3B0aW1pemVGb3JUZXJyYWluPzogYm9vbGVhbixcbiAgICByZW5kZXJXb3JsZENvcGllcz86IGJvb2xlYW4sXG4gICAgbWluVGlsZUNhY2hlU2l6ZT86IG51bWJlcixcbiAgICBtYXhUaWxlQ2FjaGVTaXplPzogbnVtYmVyLFxuICAgIHRyYW5zZm9ybVJlcXVlc3Q/OiBSZXF1ZXN0VHJhbnNmb3JtRnVuY3Rpb24sXG4gICAgYWNjZXNzVG9rZW46IHN0cmluZyxcbiAgICB0ZXN0TW9kZTogP2Jvb2xlYW4sXG4gICAgbG9jYWxlPzogT2JqZWN0LFxuICAgIHByb2plY3Rpb24/OiBQcm9qZWN0aW9uU3BlY2lmaWNhdGlvbiB8IHN0cmluZyxcbiAgICBsYW5ndWFnZT86IHN0cmluZyxcbiAgICB3b3JsZHZpZXc/OiBzdHJpbmdcbn07XG5cbmNvbnN0IGRlZmF1bHRNaW5ab29tID0gLTI7XG5jb25zdCBkZWZhdWx0TWF4Wm9vbSA9IDIyO1xuXG4vLyB0aGUgZGVmYXVsdCB2YWx1ZXMsIGJ1dCBhbHNvIHRoZSB2YWxpZCByYW5nZVxuY29uc3QgZGVmYXVsdE1pblBpdGNoID0gMDtcbmNvbnN0IGRlZmF1bHRNYXhQaXRjaCA9IDg1O1xuXG5jb25zdCBkZWZhdWx0T3B0aW9ucyA9IHtcbiAgICBjZW50ZXI6IFswLCAwXSxcbiAgICB6b29tOiAwLFxuICAgIGJlYXJpbmc6IDAsXG4gICAgcGl0Y2g6IDAsXG5cbiAgICBtaW5ab29tOiBkZWZhdWx0TWluWm9vbSxcbiAgICBtYXhab29tOiBkZWZhdWx0TWF4Wm9vbSxcblxuICAgIG1pblBpdGNoOiBkZWZhdWx0TWluUGl0Y2gsXG4gICAgbWF4UGl0Y2g6IGRlZmF1bHRNYXhQaXRjaCxcblxuICAgIGludGVyYWN0aXZlOiB0cnVlLFxuICAgIHNjcm9sbFpvb206IHRydWUsXG4gICAgYm94Wm9vbTogdHJ1ZSxcbiAgICBkcmFnUm90YXRlOiB0cnVlLFxuICAgIGRyYWdQYW46IHRydWUsXG4gICAga2V5Ym9hcmQ6IHRydWUsXG4gICAgZG91YmxlQ2xpY2tab29tOiB0cnVlLFxuICAgIHRvdWNoWm9vbVJvdGF0ZTogdHJ1ZSxcbiAgICB0b3VjaFBpdGNoOiB0cnVlLFxuICAgIGNvb3BlcmF0aXZlR2VzdHVyZXM6IGZhbHNlLFxuICAgIHBlcmZvcm1hbmNlTWV0cmljc0NvbGxlY3Rpb246IHRydWUsXG5cbiAgICBiZWFyaW5nU25hcDogNyxcbiAgICBjbGlja1RvbGVyYW5jZTogMyxcbiAgICBwaXRjaFdpdGhSb3RhdGU6IHRydWUsXG5cbiAgICBoYXNoOiBmYWxzZSxcbiAgICBhdHRyaWJ1dGlvbkNvbnRyb2w6IHRydWUsXG5cbiAgICBmYWlsSWZNYWpvclBlcmZvcm1hbmNlQ2F2ZWF0OiBmYWxzZSxcbiAgICBwcmVzZXJ2ZURyYXdpbmdCdWZmZXI6IGZhbHNlLFxuICAgIHRyYWNrUmVzaXplOiB0cnVlLFxuICAgIG9wdGltaXplRm9yVGVycmFpbjogdHJ1ZSxcbiAgICByZW5kZXJXb3JsZENvcGllczogdHJ1ZSxcbiAgICByZWZyZXNoRXhwaXJlZFRpbGVzOiB0cnVlLFxuICAgIG1pblRpbGVDYWNoZVNpemU6IG51bGwsXG4gICAgbWF4VGlsZUNhY2hlU2l6ZTogbnVsbCxcbiAgICBsb2NhbElkZW9ncmFwaEZvbnRGYW1pbHk6ICdzYW5zLXNlcmlmJyxcbiAgICBsb2NhbEZvbnRGYW1pbHk6IG51bGwsXG4gICAgdHJhbnNmb3JtUmVxdWVzdDogbnVsbCxcbiAgICBhY2Nlc3NUb2tlbjogbnVsbCxcbiAgICBmYWRlRHVyYXRpb246IDMwMCxcbiAgICByZXNwZWN0UHJlZmVyc1JlZHVjZWRNb3Rpb246IHRydWUsXG4gICAgY3Jvc3NTb3VyY2VDb2xsaXNpb25zOiB0cnVlXG59O1xuXG4vKipcbiAqIFRoZSBgTWFwYCBvYmplY3QgcmVwcmVzZW50cyB0aGUgbWFwIG9uIHlvdXIgcGFnZS4gSXQgZXhwb3NlcyBtZXRob2RzXG4gKiBhbmQgcHJvcGVydGllcyB0aGF0IGVuYWJsZSB5b3UgdG8gcHJvZ3JhbW1hdGljYWxseSBjaGFuZ2UgdGhlIG1hcCxcbiAqIGFuZCBmaXJlcyBldmVudHMgYXMgdXNlcnMgaW50ZXJhY3Qgd2l0aCBpdC5cbiAqXG4gKiBZb3UgY3JlYXRlIGEgYE1hcGAgYnkgc3BlY2lmeWluZyBhIGBjb250YWluZXJgIGFuZCBvdGhlciBvcHRpb25zLlxuICogVGhlbiBNYXBib3ggR0wgSlMgaW5pdGlhbGl6ZXMgdGhlIG1hcCBvbiB0aGUgcGFnZSBhbmQgcmV0dXJucyB5b3VyIGBNYXBgXG4gKiBvYmplY3QuXG4gKlxuICogQGV4dGVuZHMgRXZlbnRlZFxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR8c3RyaW5nfSBvcHRpb25zLmNvbnRhaW5lciBUaGUgSFRNTCBlbGVtZW50IGluIHdoaWNoIE1hcGJveCBHTCBKUyB3aWxsIHJlbmRlciB0aGUgbWFwLCBvciB0aGUgZWxlbWVudCdzIHN0cmluZyBgaWRgLiBUaGUgc3BlY2lmaWVkIGVsZW1lbnQgbXVzdCBoYXZlIG5vIGNoaWxkcmVuLlxuICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLm1pblpvb209MF0gVGhlIG1pbmltdW0gem9vbSBsZXZlbCBvZiB0aGUgbWFwICgwLTI0KS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5tYXhab29tPTIyXSBUaGUgbWF4aW11bSB6b29tIGxldmVsIG9mIHRoZSBtYXAgKDAtMjQpLlxuICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLm1pblBpdGNoPTBdIFRoZSBtaW5pbXVtIHBpdGNoIG9mIHRoZSBtYXAgKDAtODUpLlxuICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLm1heFBpdGNoPTg1XSBUaGUgbWF4aW11bSBwaXRjaCBvZiB0aGUgbWFwICgwLTg1KS5cbiAqIEBwYXJhbSB7T2JqZWN0IHwgc3RyaW5nfSBvcHRpb25zLnN0eWxlIFRoZSBtYXAncyBNYXBib3ggc3R5bGUuIFRoaXMgbXVzdCBiZSBhbiBhIEpTT04gb2JqZWN0IGNvbmZvcm1pbmcgdG9cbiAqIHRoZSBzY2hlbWEgZGVzY3JpYmVkIGluIHRoZSBbTWFwYm94IFN0eWxlIFNwZWNpZmljYXRpb25dKGh0dHBzOi8vbWFwYm94LmNvbS9tYXBib3gtZ2wtc3R5bGUtc3BlYy8pLCBvciBhIFVSTFxuICogdG8gc3VjaCBKU09OLiBDYW4gYWNjZXB0IGEgbnVsbCB2YWx1ZSB0byBhbGxvdyBhZGRpbmcgYSBzdHlsZSBtYW51YWxseS5cbiAqXG4gKiBUbyBsb2FkIGEgc3R5bGUgZnJvbSB0aGUgTWFwYm94IEFQSSwgeW91IGNhbiB1c2UgYSBVUkwgb2YgdGhlIGZvcm0gYG1hcGJveDovL3N0eWxlcy86b3duZXIvOnN0eWxlYCxcbiAqIHdoZXJlIGA6b3duZXJgIGlzIHlvdXIgTWFwYm94IGFjY291bnQgbmFtZSBhbmQgYDpzdHlsZWAgaXMgdGhlIHN0eWxlIElELiBZb3UgY2FuIGFsc28gdXNlIGFcbiAqIFtNYXBib3gtb3duZWQgc3R5bGVdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL2FwaS9tYXBzL3N0eWxlcy8jbWFwYm94LXN0eWxlcyk6XG4gKlxuICogICogYG1hcGJveDovL3N0eWxlcy9tYXBib3gvc3RyZWV0cy12MTFgXG4gKiAgKiBgbWFwYm94Oi8vc3R5bGVzL21hcGJveC9vdXRkb29ycy12MTFgXG4gKiAgKiBgbWFwYm94Oi8vc3R5bGVzL21hcGJveC9saWdodC12MTBgXG4gKiAgKiBgbWFwYm94Oi8vc3R5bGVzL21hcGJveC9kYXJrLXYxMGBcbiAqICAqIGBtYXBib3g6Ly9zdHlsZXMvbWFwYm94L3NhdGVsbGl0ZS12OWBcbiAqICAqIGBtYXBib3g6Ly9zdHlsZXMvbWFwYm94L3NhdGVsbGl0ZS1zdHJlZXRzLXYxMWBcbiAqICAqIGBtYXBib3g6Ly9zdHlsZXMvbWFwYm94L25hdmlnYXRpb24tZGF5LXYxYFxuICogICogYG1hcGJveDovL3N0eWxlcy9tYXBib3gvbmF2aWdhdGlvbi1uaWdodC12MWAuXG4gKlxuICogVGlsZXNldHMgaG9zdGVkIHdpdGggTWFwYm94IGNhbiBiZSBzdHlsZS1vcHRpbWl6ZWQgaWYgeW91IGFwcGVuZCBgP29wdGltaXplPXRydWVgIHRvIHRoZSBlbmQgb2YgeW91ciBzdHlsZSBVUkwsIGxpa2UgYG1hcGJveDovL3N0eWxlcy9tYXBib3gvc3RyZWV0cy12MTE/b3B0aW1pemU9dHJ1ZWAuXG4gKiBMZWFybiBtb3JlIGFib3V0IHN0eWxlLW9wdGltaXplZCB2ZWN0b3IgdGlsZXMgaW4gb3VyIFtBUEkgZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9hcGktZG9jdW1lbnRhdGlvbi9tYXBzLyNyZXRyaWV2ZS10aWxlcykuXG4gKlxuICogQHBhcmFtIHsoYm9vbGVhbnxzdHJpbmcpfSBbb3B0aW9ucy5oYXNoPWZhbHNlXSBJZiBgdHJ1ZWAsIHRoZSBtYXAncyBbcG9zaXRpb25dKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL2hlbHAvZ2xvc3NhcnkvY2FtZXJhKSAoem9vbSwgY2VudGVyIGxhdGl0dWRlLCBjZW50ZXIgbG9uZ2l0dWRlLCBiZWFyaW5nLCBhbmQgcGl0Y2gpIHdpbGwgYmUgc3luY2VkIHdpdGggdGhlIGhhc2ggZnJhZ21lbnQgb2YgdGhlIHBhZ2UncyBVUkwuXG4gKiAgIEZvciBleGFtcGxlLCBgaHR0cDovL3BhdGgvdG8vbXkvcGFnZS5odG1sIzIuNTkvMzkuMjYvNTMuMDcvLTI0LjEvNjBgLlxuICogICBBbiBhZGRpdGlvbmFsIHN0cmluZyBtYXkgb3B0aW9uYWxseSBiZSBwcm92aWRlZCB0byBpbmRpY2F0ZSBhIHBhcmFtZXRlci1zdHlsZWQgaGFzaCxcbiAqICAgZm9yIGV4YW1wbGUgaHR0cDovL3BhdGgvdG8vbXkvcGFnZS5odG1sI21hcD0yLjU5LzM5LjI2LzUzLjA3Ly0yNC4xLzYwJmZvbz1iYXIsIHdoZXJlIGBmb29gXG4gKiAgIGlzIGEgY3VzdG9tIHBhcmFtZXRlciBhbmQgYGJhcmAgaXMgYW4gYXJiaXRyYXJ5IGhhc2ggZGlzdGluY3QgZnJvbSB0aGUgbWFwIGhhc2guXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmludGVyYWN0aXZlPXRydWVdIElmIGBmYWxzZWAsIG5vIG1vdXNlLCB0b3VjaCwgb3Iga2V5Ym9hcmQgbGlzdGVuZXJzIHdpbGwgYmUgYXR0YWNoZWQgdG8gdGhlIG1hcCwgc28gaXQgd2lsbCBub3QgcmVzcG9uZCB0byBpbnRlcmFjdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5iZWFyaW5nU25hcD03XSBUaGUgdGhyZXNob2xkLCBtZWFzdXJlZCBpbiBkZWdyZWVzLCB0aGF0IGRldGVybWluZXMgd2hlbiB0aGUgbWFwJ3NcbiAqICAgYmVhcmluZyB3aWxsIHNuYXAgdG8gbm9ydGguIEZvciBleGFtcGxlLCB3aXRoIGEgYGJlYXJpbmdTbmFwYCBvZiA3LCBpZiB0aGUgdXNlciByb3RhdGVzXG4gKiAgIHRoZSBtYXAgd2l0aGluIDcgZGVncmVlcyBvZiBub3J0aCwgdGhlIG1hcCB3aWxsIGF1dG9tYXRpY2FsbHkgc25hcCB0byBleGFjdCBub3J0aC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMucGl0Y2hXaXRoUm90YXRlPXRydWVdIElmIGBmYWxzZWAsIHRoZSBtYXAncyBwaXRjaCAodGlsdCkgY29udHJvbCB3aXRoIFwiZHJhZyB0byByb3RhdGVcIiBpbnRlcmFjdGlvbiB3aWxsIGJlIGRpc2FibGVkLlxuICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLmNsaWNrVG9sZXJhbmNlPTNdIFRoZSBtYXggbnVtYmVyIG9mIHBpeGVscyBhIHVzZXIgY2FuIHNoaWZ0IHRoZSBtb3VzZSBwb2ludGVyIGR1cmluZyBhIGNsaWNrIGZvciBpdCB0byBiZSBjb25zaWRlcmVkIGEgdmFsaWQgY2xpY2sgKGFzIG9wcG9zZWQgdG8gYSBtb3VzZSBkcmFnKS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMuYXR0cmlidXRpb25Db250cm9sPXRydWVdIElmIGB0cnVlYCwgYW4ge0BsaW5rIEF0dHJpYnV0aW9uQ29udHJvbH0gd2lsbCBiZSBhZGRlZCB0byB0aGUgbWFwLlxuICogQHBhcmFtIHtzdHJpbmcgfCBBcnJheTxzdHJpbmc+fSBbb3B0aW9ucy5jdXN0b21BdHRyaWJ1dGlvbj1udWxsXSBTdHJpbmcgb3Igc3RyaW5ncyB0byBzaG93IGluIGFuIHtAbGluayBBdHRyaWJ1dGlvbkNvbnRyb2x9LiBPbmx5IGFwcGxpY2FibGUgaWYgYG9wdGlvbnMuYXR0cmlidXRpb25Db250cm9sYCBpcyBgdHJ1ZWAuXG4gKiBAcGFyYW0ge3N0cmluZ30gW29wdGlvbnMubG9nb1Bvc2l0aW9uPSdib3R0b20tbGVmdCddIEEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgcG9zaXRpb24gb2YgdGhlIE1hcGJveCB3b3JkbWFyayBvbiB0aGUgbWFwLiBWYWxpZCBvcHRpb25zIGFyZSBgdG9wLWxlZnRgLGB0b3AtcmlnaHRgLCBgYm90dG9tLWxlZnRgLCBgYm90dG9tLXJpZ2h0YC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMuZmFpbElmTWFqb3JQZXJmb3JtYW5jZUNhdmVhdD1mYWxzZV0gSWYgYHRydWVgLCBtYXAgY3JlYXRpb24gd2lsbCBmYWlsIGlmIHRoZSBwZXJmb3JtYW5jZSBvZiBNYXBib3ggR0wgSlMgd291bGQgYmUgZHJhbWF0aWNhbGx5IHdvcnNlIHRoYW4gZXhwZWN0ZWQgKGEgc29mdHdhcmUgcmVuZGVyZXIgd291bGQgYmUgdXNlZCkuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLnByZXNlcnZlRHJhd2luZ0J1ZmZlcj1mYWxzZV0gSWYgYHRydWVgLCB0aGUgbWFwJ3MgY2FudmFzIGNhbiBiZSBleHBvcnRlZCB0byBhIFBORyB1c2luZyBgbWFwLmdldENhbnZhcygpLnRvRGF0YVVSTCgpYC4gVGhpcyBpcyBgZmFsc2VgIGJ5IGRlZmF1bHQgYXMgYSBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb24uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmFudGlhbGlhcz1mYWxzZV0gSWYgYHRydWVgLCB0aGUgZ2wgY29udGV4dCB3aWxsIGJlIGNyZWF0ZWQgd2l0aCBbTVNBQSBhbnRpYWxpYXNpbmddKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL011bHRpc2FtcGxlX2FudGktYWxpYXNpbmcpLCB3aGljaCBjYW4gYmUgdXNlZnVsIGZvciBhbnRpYWxpYXNpbmcgY3VzdG9tIGxheWVycy4gVGhpcyBpcyBgZmFsc2VgIGJ5IGRlZmF1bHQgYXMgYSBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb24uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLnVzZVdlYkdMMj1mYWxzZV0gVGhpcyBpcyBhbiBleHBlcmltZW50YWwgZmVhdHVyZS4gSWYgdHJ1ZSBhbmQgZGV2aWNlJ3MgY2FwYWJpbGl0aWVzIHN1cHBvcnQgaXQsIFdlYkdMIDIgY29udGV4dCB3aWxsIGJlIGNyZWF0ZWQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLnJlZnJlc2hFeHBpcmVkVGlsZXM9dHJ1ZV0gSWYgYGZhbHNlYCwgdGhlIG1hcCB3b24ndCBhdHRlbXB0IHRvIHJlLXJlcXVlc3QgdGlsZXMgb25jZSB0aGV5IGV4cGlyZSBwZXIgdGhlaXIgSFRUUCBgY2FjaGVDb250cm9sYC9gZXhwaXJlc2AgaGVhZGVycy5cbiAqIEBwYXJhbSB7TG5nTGF0Qm91bmRzTGlrZX0gW29wdGlvbnMubWF4Qm91bmRzPW51bGxdIElmIHNldCwgdGhlIG1hcCB3aWxsIGJlIGNvbnN0cmFpbmVkIHRvIHRoZSBnaXZlbiBib3VuZHMuXG4gKiBAcGFyYW0ge2Jvb2xlYW58T2JqZWN0fSBbb3B0aW9ucy5zY3JvbGxab29tPXRydWVdIElmIGB0cnVlYCwgdGhlIFwic2Nyb2xsIHRvIHpvb21cIiBpbnRlcmFjdGlvbiBpcyBlbmFibGVkLiBBbiBgT2JqZWN0YCB2YWx1ZSBpcyBwYXNzZWQgYXMgb3B0aW9ucyB0byB7QGxpbmsgU2Nyb2xsWm9vbUhhbmRsZXIjZW5hYmxlfS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMuYm94Wm9vbT10cnVlXSBJZiBgdHJ1ZWAsIHRoZSBcImJveCB6b29tXCIgaW50ZXJhY3Rpb24gaXMgZW5hYmxlZCAoc2VlIHtAbGluayBCb3hab29tSGFuZGxlcn0pLlxuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5kcmFnUm90YXRlPXRydWVdIElmIGB0cnVlYCwgdGhlIFwiZHJhZyB0byByb3RhdGVcIiBpbnRlcmFjdGlvbiBpcyBlbmFibGVkIChzZWUge0BsaW5rIERyYWdSb3RhdGVIYW5kbGVyfSkuXG4gKiBAcGFyYW0ge2Jvb2xlYW4gfCBPYmplY3R9IFtvcHRpb25zLmRyYWdQYW49dHJ1ZV0gSWYgYHRydWVgLCB0aGUgXCJkcmFnIHRvIHBhblwiIGludGVyYWN0aW9uIGlzIGVuYWJsZWQuIEFuIGBPYmplY3RgIHZhbHVlIGlzIHBhc3NlZCBhcyBvcHRpb25zIHRvIHtAbGluayBEcmFnUGFuSGFuZGxlciNlbmFibGV9LlxuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5rZXlib2FyZD10cnVlXSBJZiBgdHJ1ZWAsIGtleWJvYXJkIHNob3J0Y3V0cyBhcmUgZW5hYmxlZCAoc2VlIHtAbGluayBLZXlib2FyZEhhbmRsZXJ9KS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMuZG91YmxlQ2xpY2tab29tPXRydWVdIElmIGB0cnVlYCwgdGhlIFwiZG91YmxlIGNsaWNrIHRvIHpvb21cIiBpbnRlcmFjdGlvbiBpcyBlbmFibGVkIChzZWUge0BsaW5rIERvdWJsZUNsaWNrWm9vbUhhbmRsZXJ9KS5cbiAqIEBwYXJhbSB7Ym9vbGVhbiB8IE9iamVjdH0gW29wdGlvbnMudG91Y2hab29tUm90YXRlPXRydWVdIElmIGB0cnVlYCwgdGhlIFwicGluY2ggdG8gcm90YXRlIGFuZCB6b29tXCIgaW50ZXJhY3Rpb24gaXMgZW5hYmxlZC4gQW4gYE9iamVjdGAgdmFsdWUgaXMgcGFzc2VkIGFzIG9wdGlvbnMgdG8ge0BsaW5rIFRvdWNoWm9vbVJvdGF0ZUhhbmRsZXIjZW5hYmxlfS5cbiAqIEBwYXJhbSB7Ym9vbGVhbiB8IE9iamVjdH0gW29wdGlvbnMudG91Y2hQaXRjaD10cnVlXSBJZiBgdHJ1ZWAsIHRoZSBcImRyYWcgdG8gcGl0Y2hcIiBpbnRlcmFjdGlvbiBpcyBlbmFibGVkLiBBbiBgT2JqZWN0YCB2YWx1ZSBpcyBwYXNzZWQgYXMgb3B0aW9ucyB0byB7QGxpbmsgVG91Y2hQaXRjaEhhbmRsZXJ9LlxuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5jb29wZXJhdGl2ZUdlc3R1cmVzXSBJZiBgdHJ1ZWAsIHNjcm9sbCB6b29tIHdpbGwgcmVxdWlyZSBwcmVzc2luZyB0aGUgY3RybCBvciDijJgga2V5IHdoaWxlIHNjcm9sbGluZyB0byB6b29tIG1hcCwgYW5kIHRvdWNoIHBhbiB3aWxsIHJlcXVpcmUgdXNpbmcgdHdvIGZpbmdlcnMgd2hpbGUgcGFubmluZyB0byBtb3ZlIHRoZSBtYXAuIFRvdWNoIHBpdGNoIHdpbGwgcmVxdWlyZSB0aHJlZSBmaW5nZXJzIHRvIGFjdGl2YXRlIGlmIGVuYWJsZWQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLnRyYWNrUmVzaXplPXRydWVdIElmIGB0cnVlYCwgdGhlIG1hcCB3aWxsIGF1dG9tYXRpY2FsbHkgcmVzaXplIHdoZW4gdGhlIGJyb3dzZXIgd2luZG93IHJlc2l6ZXMuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLnBlcmZvcm1hbmNlTWV0cmljc0NvbGxlY3Rpb249dHJ1ZV0gSWYgYHRydWVgLCBtYXBib3gtZ2wgd2lsbCBjb2xsZWN0IGFuZCBzZW5kIHBlcmZvcm1hbmNlIG1ldHJpY3MuXG4gKiBAcGFyYW0ge0xuZ0xhdExpa2V9IFtvcHRpb25zLmNlbnRlcj1bMCwgMF1dIFRoZSBpbml0aWFsIGdlb2dyYXBoaWNhbCBbY2VudGVycG9pbnRdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL2hlbHAvZ2xvc3NhcnkvY2FtZXJhI2NlbnRlcikgb2YgdGhlIG1hcC4gSWYgYGNlbnRlcmAgaXMgbm90IHNwZWNpZmllZCBpbiB0aGUgY29uc3RydWN0b3Igb3B0aW9ucywgTWFwYm94IEdMIEpTIHdpbGwgbG9vayBmb3IgaXQgaW4gdGhlIG1hcCdzIHN0eWxlIG9iamVjdC4gSWYgaXQgaXMgbm90IHNwZWNpZmllZCBpbiB0aGUgc3R5bGUsIGVpdGhlciwgaXQgd2lsbCBkZWZhdWx0IHRvIGBbMCwgMF1gIE5vdGU6IE1hcGJveCBHTCB1c2VzIGxvbmdpdHVkZSwgbGF0aXR1ZGUgY29vcmRpbmF0ZSBvcmRlciAoYXMgb3Bwb3NlZCB0byBsYXRpdHVkZSwgbG9uZ2l0dWRlKSB0byBtYXRjaCBHZW9KU09OLlxuICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLnpvb209MF0gVGhlIGluaXRpYWwgW3pvb21dKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL2hlbHAvZ2xvc3NhcnkvY2FtZXJhI3pvb20pIGxldmVsIG9mIHRoZSBtYXAuIElmIGB6b29tYCBpcyBub3Qgc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3RvciBvcHRpb25zLCBNYXBib3ggR0wgSlMgd2lsbCBsb29rIGZvciBpdCBpbiB0aGUgbWFwJ3Mgc3R5bGUgb2JqZWN0LiBJZiBpdCBpcyBub3Qgc3BlY2lmaWVkIGluIHRoZSBzdHlsZSwgZWl0aGVyLCBpdCB3aWxsIGRlZmF1bHQgdG8gYDBgLlxuICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLmJlYXJpbmc9MF0gVGhlIGluaXRpYWwgW2JlYXJpbmddKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL2hlbHAvZ2xvc3NhcnkvY2FtZXJhI2JlYXJpbmcpIChyb3RhdGlvbikgb2YgdGhlIG1hcCwgbWVhc3VyZWQgaW4gZGVncmVlcyBjb3VudGVyLWNsb2Nrd2lzZSBmcm9tIG5vcnRoLiBJZiBgYmVhcmluZ2AgaXMgbm90IHNwZWNpZmllZCBpbiB0aGUgY29uc3RydWN0b3Igb3B0aW9ucywgTWFwYm94IEdMIEpTIHdpbGwgbG9vayBmb3IgaXQgaW4gdGhlIG1hcCdzIHN0eWxlIG9iamVjdC4gSWYgaXQgaXMgbm90IHNwZWNpZmllZCBpbiB0aGUgc3R5bGUsIGVpdGhlciwgaXQgd2lsbCBkZWZhdWx0IHRvIGAwYC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5waXRjaD0wXSBUaGUgaW5pdGlhbCBbcGl0Y2hdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL2hlbHAvZ2xvc3NhcnkvY2FtZXJhI3BpdGNoKSAodGlsdCkgb2YgdGhlIG1hcCwgbWVhc3VyZWQgaW4gZGVncmVlcyBhd2F5IGZyb20gdGhlIHBsYW5lIG9mIHRoZSBzY3JlZW4gKDAtODUpLiBJZiBgcGl0Y2hgIGlzIG5vdCBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yIG9wdGlvbnMsIE1hcGJveCBHTCBKUyB3aWxsIGxvb2sgZm9yIGl0IGluIHRoZSBtYXAncyBzdHlsZSBvYmplY3QuIElmIGl0IGlzIG5vdCBzcGVjaWZpZWQgaW4gdGhlIHN0eWxlLCBlaXRoZXIsIGl0IHdpbGwgZGVmYXVsdCB0byBgMGAuXG4gKiBAcGFyYW0ge0xuZ0xhdEJvdW5kc0xpa2V9IFtvcHRpb25zLmJvdW5kcz1udWxsXSBUaGUgaW5pdGlhbCBib3VuZHMgb2YgdGhlIG1hcC4gSWYgYGJvdW5kc2AgaXMgc3BlY2lmaWVkLCBpdCBvdmVycmlkZXMgYGNlbnRlcmAgYW5kIGB6b29tYCBjb25zdHJ1Y3RvciBvcHRpb25zLlxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLmZpdEJvdW5kc09wdGlvbnNdIEEge0BsaW5rIE1hcCNmaXRCb3VuZHN9IG9wdGlvbnMgb2JqZWN0IHRvIHVzZSBfb25seV8gd2hlbiBmaXR0aW5nIHRoZSBpbml0aWFsIGBib3VuZHNgIHByb3ZpZGVkIGFib3ZlLlxuICogQHBhcmFtIHsnYXV0bycgfCBzdHJpbmcgfCBzdHJpbmdbXX0gW29wdGlvbnMubGFuZ3VhZ2U9bnVsbF0gQSBzdHJpbmcgd2l0aCBhIEJDUCA0NyBsYW5ndWFnZSB0YWcsIG9yIGFuIGFycmF5IG9mIHN1Y2ggc3RyaW5ncyByZXByZXNlbnRpbmcgdGhlIGRlc2lyZWQgbGFuZ3VhZ2VzIHVzZWQgZm9yIHRoZSBtYXAncyBsYWJlbHMgYW5kIFVJIGNvbXBvbmVudHMuIExhbmd1YWdlcyBjYW4gb25seSBiZSBzZXQgb24gTWFwYm94IHZlY3RvciB0aWxlIHNvdXJjZXMuXG4gKiAgIEJ5IGRlZmF1bHQsIEdMIEpTIHdpbGwgbm90IHNldCBhIGxhbmd1YWdlIHNvIHRoYXQgdGhlIGxhbmd1YWdlIG9mIE1hcGJveCB0aWxlcyB3aWxsIGJlIGRldGVybWluZWQgYnkgdGhlIHZlY3RvciB0aWxlIHNvdXJjZSdzIFRpbGVKU09OLlxuICogICBWYWxpZCBsYW5ndWFnZSBzdHJpbmdzIG11c3QgYmUgYSBbQkNQLTQ3IGxhbmd1YWdlIGNvZGVdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0lFVEZfbGFuZ3VhZ2VfdGFnI0xpc3Rfb2Zfc3VidGFncykuIFVuc3VwcG9ydGVkIEJDUC00NyBjb2RlcyB3aWxsIG5vdCBpbmNsdWRlIGFueSB0cmFuc2xhdGlvbnMuIEludmFsaWQgY29kZXMgd2lsbCByZXN1bHQgaW4gYW4gcmVjb3ZlcmFibGUgZXJyb3IuXG4gKiAgIElmIGEgbGFiZWwgaGFzIG5vIHRyYW5zbGF0aW9uIGZvciB0aGUgc2VsZWN0ZWQgbGFuZ3VhZ2UsIGl0IHdpbGwgZGlzcGxheSBpbiB0aGUgbGFiZWwncyBsb2NhbCBsYW5ndWFnZS5cbiAqICAgSWYgb3B0aW9uIGlzIHNldCB0byBgYXV0b2AsIEdMIEpTIHdpbGwgc2VsZWN0IGEgdXNlcidzIHByZWZlcnJlZCBsYW5ndWFnZSBhcyBkZXRlcm1pbmVkIGJ5IHRoZSBicm93c2VyJ3MgW2B3aW5kb3cubmF2aWdhdG9yLmxhbmd1YWdlYF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL05hdmlnYXRvci9sYW5ndWFnZSkgcHJvcGVydHkuXG4gKiAgIElmIHRoZSBgbG9jYWxlYCBwcm9wZXJ0eSBpcyBub3Qgc2V0IHNlcGFyYXRlbHksIHRoaXMgbGFuZ3VhZ2Ugd2lsbCBhbHNvIGJlIHVzZWQgdG8gbG9jYWxpemUgdGhlIFVJIGZvciBzdXBwb3J0ZWQgbGFuZ3VhZ2VzLlxuICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLndvcmxkdmlldz1udWxsXSBTZXRzIHRoZSBtYXAncyB3b3JsZHZpZXcuIEEgd29ybGR2aWV3IGRldGVybWluZXMgdGhlIHdheSB0aGF0IGNlcnRhaW4gZGlzcHV0ZWQgYm91bmRhcmllc1xuICAgICAqIGFyZSByZW5kZXJlZC4gQnkgZGVmYXVsdCwgR0wgSlMgd2lsbCBub3Qgc2V0IGEgd29ybGR2aWV3IHNvIHRoYXQgdGhlIHdvcmxkdmlldyBvZiBNYXBib3ggdGlsZXMgd2lsbCBiZSBkZXRlcm1pbmVkIGJ5IHRoZSB2ZWN0b3IgdGlsZSBzb3VyY2UncyBUaWxlSlNPTi5cbiAgICAgKiBWYWxpZCB3b3JsZHZpZXcgc3RyaW5ncyBtdXN0IGJlIGFuIFtJU08gYWxwaGEtMiBjb3VudHJ5IGNvZGVdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0lTT18zMTY2LTEjQ3VycmVudF9jb2RlcykuIFVuc3VwcG9ydGVkXG4gICAgICogSVNPIGFscGhhLTIgY29kZXMgd2lsbCBmYWxsIGJhY2sgdG8gdGhlIFRpbGVKU09OJ3MgZGVmYXVsdCB3b3JsZHZpZXcuIEludmFsaWQgY29kZXMgd2lsbCByZXN1bHQgaW4gYSByZWNvdmVyYWJsZSBlcnJvci5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMub3B0aW1pemVGb3JUZXJyYWluPXRydWVdIFdpdGggdGVycmFpbiBvbiwgaWYgYHRydWVgLCB0aGUgbWFwIHdpbGwgcmVuZGVyIGZvciBwZXJmb3JtYW5jZSBwcmlvcml0eSwgd2hpY2ggbWF5IGxlYWQgdG8gbGF5ZXIgcmVvcmRlcmluZyBhbGxvd2luZyB0byBtYXhpbWl6ZSBwZXJmb3JtYW5jZSAobGF5ZXJzIHRoYXQgYXJlIGRyYXBlZCBvdmVyIHRlcnJhaW4gd2lsbCBiZSBkcmF3biBmaXJzdCwgaW5jbHVkaW5nIGZpbGwsIGxpbmUsIGJhY2tncm91bmQsIGhpbGxzaGFkZSBhbmQgcmFzdGVyKS4gT3RoZXJ3aXNlLCBpZiBzZXQgdG8gYGZhbHNlYCwgdGhlIG1hcCB3aWxsIGFsd2F5cyBiZSBkcmF3biBmb3IgbGF5ZXIgb3JkZXIgcHJpb3JpdHkuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLnJlbmRlcldvcmxkQ29waWVzPXRydWVdIElmIGB0cnVlYCwgbXVsdGlwbGUgY29waWVzIG9mIHRoZSB3b3JsZCB3aWxsIGJlIHJlbmRlcmVkIHNpZGUgYnkgc2lkZSBiZXlvbmQgLTE4MCBhbmQgMTgwIGRlZ3JlZXMgbG9uZ2l0dWRlLiBJZiBzZXQgdG8gYGZhbHNlYDpcbiAqIC0gV2hlbiB0aGUgbWFwIGlzIHpvb21lZCBvdXQgZmFyIGVub3VnaCB0aGF0IGEgc2luZ2xlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB3b3JsZCBkb2VzIG5vdCBmaWxsIHRoZSBtYXAncyBlbnRpcmVcbiAqIGNvbnRhaW5lciwgdGhlcmUgd2lsbCBiZSBibGFuayBzcGFjZSBiZXlvbmQgMTgwIGFuZCAtMTgwIGRlZ3JlZXMgbG9uZ2l0dWRlLlxuICogLSBGZWF0dXJlcyB0aGF0IGNyb3NzIDE4MCBhbmQgLTE4MCBkZWdyZWVzIGxvbmdpdHVkZSB3aWxsIGJlIGN1dCBpbiB0d28gKHdpdGggb25lIHBvcnRpb24gb24gdGhlIHJpZ2h0IGVkZ2Ugb2YgdGhlXG4gKiBtYXAgYW5kIHRoZSBvdGhlciBvbiB0aGUgbGVmdCBlZGdlIG9mIHRoZSBtYXApIGF0IGV2ZXJ5IHpvb20gbGV2ZWwuXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMubWluVGlsZUNhY2hlU2l6ZT1udWxsXSBUaGUgbWluaW11bSBudW1iZXIgb2YgdGlsZXMgc3RvcmVkIGluIHRoZSB0aWxlIGNhY2hlIGZvciBhIGdpdmVuIHNvdXJjZS4gTGFyZ2VyIHZpZXdwb3J0cyB1c2UgbW9yZSB0aWxlcyBhbmQgbmVlZCBsYXJnZXIgY2FjaGVzLiBMYXJnZXIgdmlld3BvcnRzIGFyZSBtb3JlIGxpa2VseSB0byBiZSBmb3VuZCBvbiBkZXZpY2VzIHdpdGggbW9yZSBtZW1vcnkgYW5kIG9uIHBhZ2VzIHdoZXJlIHRoZSBtYXAgaXMgbW9yZSBpbXBvcnRhbnQuIElmIG9taXR0ZWQsIHRoZSBjYWNoZSB3aWxsIGJlIGR5bmFtaWNhbGx5IHNpemVkIGJhc2VkIG9uIHRoZSBjdXJyZW50IHZpZXdwb3J0LlxuICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLm1heFRpbGVDYWNoZVNpemU9bnVsbF0gVGhlIG1heGltdW0gbnVtYmVyIG9mIHRpbGVzIHN0b3JlZCBpbiB0aGUgdGlsZSBjYWNoZSBmb3IgYSBnaXZlbiBzb3VyY2UuIElmIG9taXR0ZWQsIHRoZSBjYWNoZSB3aWxsIGJlIGR5bmFtaWNhbGx5IHNpemVkIGJhc2VkIG9uIHRoZSBjdXJyZW50IHZpZXdwb3J0LlxuICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLmxvY2FsSWRlb2dyYXBoRm9udEZhbWlseT0nc2Fucy1zZXJpZiddIERlZmluZXMgYSBDU1MgZm9udC1mYW1pbHkgZm9yIGxvY2FsbHkgb3ZlcnJpZGluZyBnZW5lcmF0aW9uIG9mIGdseXBocyBpbiB0aGUgJ0NKSyBVbmlmaWVkIElkZW9ncmFwaHMnLCAnSGlyYWdhbmEnLCAnS2F0YWthbmEnLCAnSGFuZ3VsIFN5bGxhYmxlcycgYW5kICdDSksgU3ltYm9scyBhbmQgUHVuY3R1YXRpb24nIHJhbmdlcy5cbiAqICAgSW4gdGhlc2UgcmFuZ2VzLCBmb250IHNldHRpbmdzIGZyb20gdGhlIG1hcCdzIHN0eWxlIHdpbGwgYmUgaWdub3JlZCwgZXhjZXB0IGZvciBmb250LXdlaWdodCBrZXl3b3JkcyAobGlnaHQvcmVndWxhci9tZWRpdW0vYm9sZCkuXG4gKiAgIFNldCB0byBgZmFsc2VgLCB0byBlbmFibGUgZm9udCBzZXR0aW5ncyBmcm9tIHRoZSBtYXAncyBzdHlsZSBmb3IgdGhlc2UgZ2x5cGggcmFuZ2VzLiBOb3RlIHRoYXQgW01hcGJveCBTdHVkaW9dKGh0dHBzOi8vc3R1ZGlvLm1hcGJveC5jb20vKSBzZXRzIHRoaXMgdmFsdWUgdG8gYGZhbHNlYCBieSBkZWZhdWx0LlxuICogICBUaGUgcHVycG9zZSBvZiB0aGlzIG9wdGlvbiBpcyB0byBhdm9pZCBiYW5kd2lkdGgtaW50ZW5zaXZlIGdseXBoIHNlcnZlciByZXF1ZXN0cy4gRm9yIGFuIGV4YW1wbGUgb2YgdGhpcyBvcHRpb24gaW4gdXNlLCBzZWUgW1VzZSBsb2NhbGx5IGdlbmVyYXRlZCBpZGVvZ3JhcGhzXShodHRwczovL3d3dy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2xvY2FsLWlkZW9ncmFwaHMpLlxuICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLmxvY2FsRm9udEZhbWlseT1mYWxzZV0gRGVmaW5lcyBhIENTU1xuICogICBmb250LWZhbWlseSBmb3IgbG9jYWxseSBvdmVycmlkaW5nIGdlbmVyYXRpb24gb2YgYWxsIGdseXBocy4gRm9udCBzZXR0aW5ncyBmcm9tIHRoZSBtYXAncyBzdHlsZSB3aWxsIGJlIGlnbm9yZWQsIGV4Y2VwdCBmb3IgZm9udC13ZWlnaHQga2V5d29yZHMgKGxpZ2h0L3JlZ3VsYXIvbWVkaXVtL2JvbGQpLlxuICogICBJZiBzZXQsIHRoaXMgb3B0aW9uIG92ZXJyaWRlcyB0aGUgc2V0dGluZyBpbiBsb2NhbElkZW9ncmFwaEZvbnRGYW1pbHkuXG4gKiBAcGFyYW0ge1JlcXVlc3RUcmFuc2Zvcm1GdW5jdGlvbn0gW29wdGlvbnMudHJhbnNmb3JtUmVxdWVzdD1udWxsXSBBIGNhbGxiYWNrIHJ1biBiZWZvcmUgdGhlIE1hcCBtYWtlcyBhIHJlcXVlc3QgZm9yIGFuIGV4dGVybmFsIFVSTC4gVGhlIGNhbGxiYWNrIGNhbiBiZSB1c2VkIHRvIG1vZGlmeSB0aGUgdXJsLCBzZXQgaGVhZGVycywgb3Igc2V0IHRoZSBjcmVkZW50aWFscyBwcm9wZXJ0eSBmb3IgY3Jvc3Mtb3JpZ2luIHJlcXVlc3RzLlxuICogICBFeHBlY3RlZCB0byByZXR1cm4gYSB7QGxpbmsgUmVxdWVzdFBhcmFtZXRlcnN9IG9iamVjdCB3aXRoIGEgYHVybGAgcHJvcGVydHkgYW5kIG9wdGlvbmFsbHkgYGhlYWRlcnNgIGFuZCBgY3JlZGVudGlhbHNgIHByb3BlcnRpZXMuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmNvbGxlY3RSZXNvdXJjZVRpbWluZz1mYWxzZV0gSWYgYHRydWVgLCBSZXNvdXJjZSBUaW1pbmcgQVBJIGluZm9ybWF0aW9uIHdpbGwgYmUgY29sbGVjdGVkIGZvciByZXF1ZXN0cyBtYWRlIGJ5IEdlb0pTT04gYW5kIFZlY3RvciBUaWxlIHdlYiB3b3JrZXJzICh0aGlzIGluZm9ybWF0aW9uIGlzIG5vcm1hbGx5IGluYWNjZXNzaWJsZSBmcm9tIHRoZSBtYWluIEphdmFzY3JpcHQgdGhyZWFkKS4gSW5mb3JtYXRpb24gd2lsbCBiZSByZXR1cm5lZCBpbiBhIGByZXNvdXJjZVRpbWluZ2AgcHJvcGVydHkgb2YgcmVsZXZhbnQgYGRhdGFgIGV2ZW50cy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5mYWRlRHVyYXRpb249MzAwXSBDb250cm9scyB0aGUgZHVyYXRpb24gb2YgdGhlIGZhZGUtaW4vZmFkZS1vdXQgYW5pbWF0aW9uIGZvciBsYWJlbCBjb2xsaXNpb25zLCBpbiBtaWxsaXNlY29uZHMuIFRoaXMgc2V0dGluZyBhZmZlY3RzIGFsbCBzeW1ib2wgbGF5ZXJzLiBUaGlzIHNldHRpbmcgZG9lcyBub3QgYWZmZWN0IHRoZSBkdXJhdGlvbiBvZiBydW50aW1lIHN0eWxpbmcgdHJhbnNpdGlvbnMgb3IgcmFzdGVyIHRpbGUgY3Jvc3MtZmFkaW5nLlxuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5yZXNwZWN0UHJlZmVyc1JlZHVjZWRNb3Rpb249dHJ1ZV0gSWYgc2V0IHRvIGB0cnVlYCwgdGhlIG1hcCB3aWxsIHJlc3BlY3QgdGhlIHVzZXIncyBgcHJlZmVycy1yZWR1Y2VkLW1vdGlvbmAgYnJvd3NlciBzZXR0aW5nIGFuZCBhcHBseSBhIHJlZHVjZWQgbW90aW9uIG1vZGUsIG1pbmltaXppbmcgYW5pbWF0aW9ucyBhbmQgdHJhbnNpdGlvbnMuIFdoZW4gc2V0IHRvIGBmYWxzZWAsIHRoZSBtYXAgd2lsbCBhbHdheXMgaWdub3JlIHRoZSBgcHJlZmVycy1yZWR1Y2VkLW1vdGlvbmAgc2V0dGluZ3MsIHJlZ2FyZGxlc3Mgb2YgdGhlIHVzZXIncyBwcmVmZXJlbmNlLCBtYWtpbmcgYWxsIGFuaW1hdGlvbnMgZXNzZW50aWFsLlxuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5jcm9zc1NvdXJjZUNvbGxpc2lvbnM9dHJ1ZV0gSWYgYHRydWVgLCBzeW1ib2xzIGZyb20gbXVsdGlwbGUgc291cmNlcyBjYW4gY29sbGlkZSB3aXRoIGVhY2ggb3RoZXIgZHVyaW5nIGNvbGxpc2lvbiBkZXRlY3Rpb24uIElmIGBmYWxzZWAsIGNvbGxpc2lvbiBkZXRlY3Rpb24gaXMgcnVuIHNlcGFyYXRlbHkgZm9yIHRoZSBzeW1ib2xzIGluIGVhY2ggc291cmNlLlxuICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLmFjY2Vzc1Rva2VuPW51bGxdIElmIHNwZWNpZmllZCwgbWFwIHdpbGwgdXNlIHRoaXMgW3Rva2VuXShodHRwczovL2RvY3MubWFwYm94LmNvbS9oZWxwL2dsb3NzYXJ5L2FjY2Vzcy10b2tlbi8pIGluc3RlYWQgb2YgdGhlIG9uZSBkZWZpbmVkIGluIGBtYXBib3hnbC5hY2Nlc3NUb2tlbmAuXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMubG9jYWxlPW51bGxdIEEgcGF0Y2ggdG8gYXBwbHkgdG8gdGhlIGRlZmF1bHQgbG9jYWxpemF0aW9uIHRhYmxlIGZvciBVSSBzdHJpbmdzIHN1Y2ggYXMgY29udHJvbCB0b29sdGlwcy4gVGhlIGBsb2NhbGVgIG9iamVjdCBtYXBzIG5hbWVzcGFjZWQgVUkgc3RyaW5nIElEcyB0byB0cmFuc2xhdGVkIHN0cmluZ3MgaW4gdGhlIHRhcmdldCBsYW5ndWFnZTtcbiAqICBzZWUgW2BzcmMvdWkvZGVmYXVsdF9sb2NhbGUuanNgXShodHRwczovL2dpdGh1Yi5jb20vbWFwYm94L21hcGJveC1nbC1qcy9ibG9iL21haW4vc3JjL3VpL2RlZmF1bHRfbG9jYWxlLmpzKSBmb3IgYW4gZXhhbXBsZSB3aXRoIGFsbCBzdXBwb3J0ZWQgc3RyaW5nIElEcy4gVGhlIG9iamVjdCBtYXkgc3BlY2lmeSBhbGwgVUkgc3RyaW5ncyAodGhlcmVieSBhZGRpbmcgc3VwcG9ydCBmb3IgYSBuZXcgdHJhbnNsYXRpb24pIG9yIG9ubHkgYSBzdWJzZXQgb2Ygc3RyaW5ncyAodGhlcmVieSBwYXRjaGluZyB0aGUgZGVmYXVsdCB0cmFuc2xhdGlvbiB0YWJsZSkuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLnRlc3RNb2RlPWZhbHNlXSBTaWxlbmNlcyBlcnJvcnMgYW5kIHdhcm5pbmdzIGdlbmVyYXRlZCBkdWUgdG8gYW4gaW52YWxpZCBhY2Nlc3NUb2tlbiwgdXNlZnVsIHdoZW4gdXNpbmcgdGhlIGxpYnJhcnkgdG8gd3JpdGUgdW5pdCB0ZXN0cy5cbiAqIEBwYXJhbSB7UHJvamVjdGlvblNwZWNpZmljYXRpb259IFtvcHRpb25zLnByb2plY3Rpb249J21lcmNhdG9yJ10gVGhlIFtwcm9qZWN0aW9uXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvc3R5bGUtc3BlYy9wcm9qZWN0aW9uLykgdGhlIG1hcCBzaG91bGQgYmUgcmVuZGVyZWQgaW4uXG4gKiBTdXBwb3J0ZWQgcHJvamVjdGlvbnMgYXJlOlxuICogICogW0FsYmVyc10oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQWxiZXJzX3Byb2plY3Rpb24pIGVxdWFsLWFyZWEgY29uaWMgcHJvamVjdGlvbiBhcyBgYWxiZXJzYFxuICogICogW0VxdWFsIEVhcnRoXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9FcXVhbF9FYXJ0aF9wcm9qZWN0aW9uKSBlcXVhbC1hcmVhIHBzZXVkb2N5bGluZHJpY2FsIHByb2plY3Rpb24gYXMgYGVxdWFsRWFydGhgXG4gKiAgKiBbRXF1aXJlY3Rhbmd1bGFyXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9FcXVpcmVjdGFuZ3VsYXJfcHJvamVjdGlvbikgKFBsYXRlIENhcnLDqWUvV0dTODQpIGFzIGBlcXVpcmVjdGFuZ3VsYXJgXG4gKiAgKiAzZCBHbG9iZSBhcyBgZ2xvYmVgXG4gKiAgKiBbTGFtYmVydCBDb25mb3JtYWwgQ29uaWNdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0xhbWJlcnRfY29uZm9ybWFsX2NvbmljX3Byb2plY3Rpb24pIGFzIGBsYW1iZXJ0Q29uZm9ybWFsQ29uaWNgXG4gKiAgKiBbTWVyY2F0b3JdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL01lcmNhdG9yX3Byb2plY3Rpb24pIGN5bGluZHJpY2FsIG1hcCBwcm9qZWN0aW9uIGFzIGBtZXJjYXRvcmBcbiAqICAqIFtOYXR1cmFsIEVhcnRoXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9OYXR1cmFsX0VhcnRoX3Byb2plY3Rpb24pIHBzZXVkb2N5bGluZHJpY2FsIG1hcCBwcm9qZWN0aW9uIGFzIGBuYXR1cmFsRWFydGhgXG4gKiAgKiBbV2lua2VsIFRyaXBlbF0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvV2lua2VsX3RyaXBlbF9wcm9qZWN0aW9uKSBhemltdXRoYWwgbWFwIHByb2plY3Rpb24gYXMgYHdpbmtlbFRyaXBlbGBcbiAqICBDb25pYyBwcm9qZWN0aW9ucyBzdWNoIGFzIEFsYmVycyBhbmQgTGFtYmVydCBoYXZlIGNvbmZpZ3VyYWJsZSBgY2VudGVyYCBhbmQgYHBhcmFsbGVsc2AgcHJvcGVydGllcyB0aGF0IGFsbG93IGRldmVsb3BlcnMgdG8gZGVmaW5lIHRoZSByZWdpb24gaW4gd2hpY2ggdGhlIHByb2plY3Rpb24gaGFzIG1pbmltYWwgZGlzdG9ydGlvbjsgc2VlIHRoZSBleGFtcGxlIGZvciBob3cgdG8gY29uZmlndXJlIHRoZXNlIHByb3BlcnRpZXMuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgbWFwID0gbmV3IG1hcGJveGdsLk1hcCh7XG4gKiAgICAgY29udGFpbmVyOiAnbWFwJywgLy8gY29udGFpbmVyIElEXG4gKiAgICAgY2VudGVyOiBbLTEyMi40MjA2NzksIDM3Ljc3MjUzN10sIC8vIHN0YXJ0aW5nIHBvc2l0aW9uIFtsbmcsIGxhdF1cbiAqICAgICB6b29tOiAxMywgLy8gc3RhcnRpbmcgem9vbVxuICogICAgIHN0eWxlOiAnbWFwYm94Oi8vc3R5bGVzL21hcGJveC9zdHJlZXRzLXYxMScsIC8vIHN0eWxlIFVSTCBvciBzdHlsZSBvYmplY3RcbiAqICAgICBoYXNoOiB0cnVlLCAvLyBzeW5jIGBjZW50ZXJgLCBgem9vbWAsIGBwaXRjaGAsIGFuZCBgYmVhcmluZ2Agd2l0aCBVUkxcbiAqICAgICAvLyBVc2UgYHRyYW5zZm9ybVJlcXVlc3RgIHRvIG1vZGlmeSByZXF1ZXN0cyB0aGF0IGJlZ2luIHdpdGggYGh0dHA6Ly9teUhvc3RgLlxuICogICAgIHRyYW5zZm9ybVJlcXVlc3Q6ICh1cmwsIHJlc291cmNlVHlwZSkgPT4ge1xuICogICAgICAgICBpZiAocmVzb3VyY2VUeXBlID09PSAnU291cmNlJyAmJiB1cmwuc3RhcnRzV2l0aCgnaHR0cDovL215SG9zdCcpKSB7XG4gKiAgICAgICAgICAgICByZXR1cm4ge1xuICogICAgICAgICAgICAgICAgIHVybDogdXJsLnJlcGxhY2UoJ2h0dHAnLCAnaHR0cHMnKSxcbiAqICAgICAgICAgICAgICAgICBoZWFkZXJzOiB7J215LWN1c3RvbS1oZWFkZXInOiB0cnVlfSxcbiAqICAgICAgICAgICAgICAgICBjcmVkZW50aWFsczogJ2luY2x1ZGUnICAvLyBJbmNsdWRlIGNvb2tpZXMgZm9yIGNyb3NzLW9yaWdpbiByZXF1ZXN0c1xuICogICAgICAgICAgICAgfTtcbiAqICAgICAgICAgfVxuICogICAgIH1cbiAqIH0pO1xuICogQHNlZSBbRXhhbXBsZTogRGlzcGxheSBhIG1hcCBvbiBhIHdlYnBhZ2VdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL3NpbXBsZS1tYXAvKVxuICogQHNlZSBbRXhhbXBsZTogRGlzcGxheSBhIG1hcCB3aXRoIGEgY3VzdG9tIHN0eWxlXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9jdXN0b20tc3R5bGUtaWQvKVxuICogQHNlZSBbRXhhbXBsZTogQ2hlY2sgaWYgTWFwYm94IEdMIEpTIGlzIHN1cHBvcnRlZF0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvY2hlY2stZm9yLXN1cHBvcnQvKVxuICovXG5jbGFzcyBNYXAgZXh0ZW5kcyBDYW1lcmEge1xuICAgIHN0eWxlOiBTdHlsZTtcbiAgICBwYWludGVyOiBQYWludGVyO1xuICAgIGhhbmRsZXJzOiA/SGFuZGxlck1hbmFnZXI7XG5cbiAgICBfY29udGFpbmVyOiBIVE1MRWxlbWVudDtcbiAgICBfbWlzc2luZ0NTU0NhbmFyeTogSFRNTEVsZW1lbnQ7XG4gICAgX2NhbnZhc0NvbnRhaW5lcjogSFRNTEVsZW1lbnQ7XG4gICAgX2NvbnRyb2xDb250YWluZXI6IEhUTUxFbGVtZW50O1xuICAgIF9jb250cm9sUG9zaXRpb25zOiB7W186IHN0cmluZ106IEhUTUxFbGVtZW50fTtcbiAgICBfaW50ZXJhY3RpdmU6ID9ib29sZWFuO1xuICAgIF9zaG93VGlsZUJvdW5kYXJpZXM6ID9ib29sZWFuO1xuICAgIF9zaG93VGVycmFpbldpcmVmcmFtZTogP2Jvb2xlYW47XG4gICAgX3Nob3dRdWVyeUdlb21ldHJ5OiA/Ym9vbGVhbjtcbiAgICBfc2hvd0NvbGxpc2lvbkJveGVzOiA/Ym9vbGVhbjtcbiAgICBfc2hvd1BhZGRpbmc6ID9ib29sZWFuO1xuICAgIF9zaG93VGlsZUFBQkJzOiA/Ym9vbGVhbjtcbiAgICBfc2hvd092ZXJkcmF3SW5zcGVjdG9yOiBib29sZWFuO1xuICAgIF9yZXBhaW50OiA/Ym9vbGVhbjtcbiAgICBfdmVydGljZXM6ID9ib29sZWFuO1xuICAgIF9jYW52YXM6IEhUTUxDYW52YXNFbGVtZW50O1xuICAgIF9taW5UaWxlQ2FjaGVTaXplOiBudW1iZXI7XG4gICAgX21heFRpbGVDYWNoZVNpemU6IG51bWJlcjtcbiAgICBfZnJhbWU6ID9DYW5jZWxhYmxlO1xuICAgIF9yZW5kZXJOZXh0RnJhbWU6ID9ib29sZWFuO1xuICAgIF9zdHlsZURpcnR5OiA/Ym9vbGVhbjtcbiAgICBfc291cmNlc0RpcnR5OiA/Ym9vbGVhbjtcbiAgICBfcGxhY2VtZW50RGlydHk6ID9ib29sZWFuO1xuICAgIF9sb2FkZWQ6IGJvb2xlYW47XG4gICAgX2Z1bGx5TG9hZGVkOiBib29sZWFuOyAvLyBhY2NvdW50cyBmb3IgcGxhY2VtZW50IGZpbmlzaGluZyBhcyB3ZWxsXG4gICAgX3RyYWNrUmVzaXplOiBib29sZWFuO1xuICAgIF9wcmVzZXJ2ZURyYXdpbmdCdWZmZXI6IGJvb2xlYW47XG4gICAgX2ZhaWxJZk1ham9yUGVyZm9ybWFuY2VDYXZlYXQ6IGJvb2xlYW47XG4gICAgX2FudGlhbGlhczogYm9vbGVhbjtcbiAgICBfdXNlV2ViR0wyOiBib29sZWFuO1xuICAgIF9yZWZyZXNoRXhwaXJlZFRpbGVzOiBib29sZWFuO1xuICAgIF9oYXNoOiBIYXNoO1xuICAgIF9kZWxlZ2F0ZWRMaXN0ZW5lcnM6IGFueTtcbiAgICBfaXNJbml0aWFsTG9hZDogYm9vbGVhbjtcbiAgICBfc2hvdWxkQ2hlY2tBY2Nlc3M6IGJvb2xlYW47XG4gICAgX2ZhZGVEdXJhdGlvbjogbnVtYmVyO1xuICAgIF9jcm9zc1NvdXJjZUNvbGxpc2lvbnM6IGJvb2xlYW47XG4gICAgX2NvbGxlY3RSZXNvdXJjZVRpbWluZzogYm9vbGVhbjtcbiAgICBfb3B0aW1pemVGb3JUZXJyYWluOiBib29sZWFuO1xuICAgIF9yZW5kZXJUYXNrUXVldWU6IFRhc2tRdWV1ZTtcbiAgICBfZG9tUmVuZGVyVGFza1F1ZXVlOiBUYXNrUXVldWU7XG4gICAgX2NvbnRyb2xzOiBBcnJheTxJQ29udHJvbD47XG4gICAgX21hcmtlcnM6IEFycmF5PE1hcmtlcj47XG4gICAgX3BvcHVwczogQXJyYXk8UG9wdXA+O1xuICAgIF9sb2dvQ29udHJvbDogSUNvbnRyb2w7XG4gICAgX21hcElkOiBudW1iZXI7XG4gICAgX2xvY2FsSWRlb2dyYXBoRm9udEZhbWlseTogc3RyaW5nO1xuICAgIF9sb2NhbEZvbnRGYW1pbHk6IHN0cmluZztcbiAgICBfcmVxdWVzdE1hbmFnZXI6IFJlcXVlc3RNYW5hZ2VyO1xuICAgIF9sb2NhbGU6IE9iamVjdDtcbiAgICBfcmVtb3ZlZDogYm9vbGVhbjtcbiAgICBfc3BlZWRJbmRleFRpbWluZzogYm9vbGVhbjtcbiAgICBfY2xpY2tUb2xlcmFuY2U6IG51bWJlcjtcbiAgICBfY29vcGVyYXRpdmVHZXN0dXJlczogYm9vbGVhbjtcbiAgICBfc2lsZW5jZUF1dGhFcnJvcnM6IGJvb2xlYW47XG4gICAgX2F2ZXJhZ2VFbGV2YXRpb25MYXN0U2FtcGxlZEF0OiBudW1iZXI7XG4gICAgX2F2ZXJhZ2VFbGV2YXRpb25FeGFnZ2VyYXRpb246IG51bWJlcjtcbiAgICBfYXZlcmFnZUVsZXZhdGlvbjogRWFzZWRWYXJpYWJsZTtcbiAgICBfY29udGFpbmVyV2lkdGg6IG51bWJlcjtcbiAgICBfY29udGFpbmVySGVpZ2h0OiBudW1iZXI7XG4gICAgX2xhbmd1YWdlOiA/c3RyaW5nIHwgP3N0cmluZ1tdO1xuICAgIF93b3JsZHZpZXc6ID9zdHJpbmc7XG4gICAgX2ludGVyYWN0aW9uUmFuZ2U6IFtudW1iZXIsIG51bWJlcl07XG4gICAgX3Zpc2liaWxpdHlIaWRkZW46IG51bWJlcjtcbiAgICBfcGVyZm9ybWFuY2VNZXRyaWNzQ29sbGVjdGlvbjogYm9vbGVhbjtcblxuICAgIC8vIGBfdXNlRXhwbGljaXRQcm9qZWN0aW9uYCBpbmRpY2F0ZXMgdGhhdCBhIHByb2plY3Rpb24gaXMgc2V0IGJ5IGEgY2FsbCB0byBtYXAuc2V0UHJvamVjdGlvbigpXG4gICAgX3VzZUV4cGxpY2l0UHJvamVjdGlvbjogYm9vbGVhbjtcblxuICAgIC8qKiBAc2VjdGlvbiB7SW50ZXJhY3Rpb24gaGFuZGxlcnN9ICovXG5cbiAgICAvKipcbiAgICAgKiBUaGUgbWFwJ3Mge0BsaW5rIFNjcm9sbFpvb21IYW5kbGVyfSwgd2hpY2ggaW1wbGVtZW50cyB6b29taW5nIGluIGFuZCBvdXQgd2l0aCBhIHNjcm9sbCB3aGVlbCBvciB0cmFja3BhZC5cbiAgICAgKiBGaW5kIG1vcmUgZGV0YWlscyBhbmQgZXhhbXBsZXMgdXNpbmcgYHNjcm9sbFpvb21gIGluIHRoZSB7QGxpbmsgU2Nyb2xsWm9vbUhhbmRsZXJ9IHNlY3Rpb24uXG4gICAgICovXG4gICAgc2Nyb2xsWm9vbTogU2Nyb2xsWm9vbUhhbmRsZXI7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbWFwJ3Mge0BsaW5rIEJveFpvb21IYW5kbGVyfSwgd2hpY2ggaW1wbGVtZW50cyB6b29taW5nIHVzaW5nIGEgZHJhZyBnZXN0dXJlIHdpdGggdGhlIFNoaWZ0IGtleSBwcmVzc2VkLlxuICAgICAqIEZpbmQgbW9yZSBkZXRhaWxzIGFuZCBleGFtcGxlcyB1c2luZyBgYm94Wm9vbWAgaW4gdGhlIHtAbGluayBCb3hab29tSGFuZGxlcn0gc2VjdGlvbi5cbiAgICAgKi9cbiAgICBib3hab29tOiBCb3hab29tSGFuZGxlcjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBtYXAncyB7QGxpbmsgRHJhZ1JvdGF0ZUhhbmRsZXJ9LCB3aGljaCBpbXBsZW1lbnRzIHJvdGF0aW5nIHRoZSBtYXAgd2hpbGUgZHJhZ2dpbmcgd2l0aCB0aGUgcmlnaHRcbiAgICAgKiBtb3VzZSBidXR0b24gb3Igd2l0aCB0aGUgQ29udHJvbCBrZXkgcHJlc3NlZC4gRmluZCBtb3JlIGRldGFpbHMgYW5kIGV4YW1wbGVzIHVzaW5nIGBkcmFnUm90YXRlYFxuICAgICAqIGluIHRoZSB7QGxpbmsgRHJhZ1JvdGF0ZUhhbmRsZXJ9IHNlY3Rpb24uXG4gICAgICovXG4gICAgZHJhZ1JvdGF0ZTogRHJhZ1JvdGF0ZUhhbmRsZXI7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbWFwJ3Mge0BsaW5rIERyYWdQYW5IYW5kbGVyfSwgd2hpY2ggaW1wbGVtZW50cyBkcmFnZ2luZyB0aGUgbWFwIHdpdGggYSBtb3VzZSBvciB0b3VjaCBnZXN0dXJlLlxuICAgICAqIEZpbmQgbW9yZSBkZXRhaWxzIGFuZCBleGFtcGxlcyB1c2luZyBgZHJhZ1BhbmAgaW4gdGhlIHtAbGluayBEcmFnUGFuSGFuZGxlcn0gc2VjdGlvbi5cbiAgICAgKi9cbiAgICBkcmFnUGFuOiBEcmFnUGFuSGFuZGxlcjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBtYXAncyB7QGxpbmsgS2V5Ym9hcmRIYW5kbGVyfSwgd2hpY2ggYWxsb3dzIHRoZSB1c2VyIHRvIHpvb20sIHJvdGF0ZSwgYW5kIHBhbiB0aGUgbWFwIHVzaW5nIGtleWJvYXJkXG4gICAgICogc2hvcnRjdXRzLiBGaW5kIG1vcmUgZGV0YWlscyBhbmQgZXhhbXBsZXMgdXNpbmcgYGtleWJvYXJkYCBpbiB0aGUge0BsaW5rIEtleWJvYXJkSGFuZGxlcn0gc2VjdGlvbi5cbiAgICAgKi9cbiAgICBrZXlib2FyZDogS2V5Ym9hcmRIYW5kbGVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG1hcCdzIHtAbGluayBEb3VibGVDbGlja1pvb21IYW5kbGVyfSwgd2hpY2ggYWxsb3dzIHRoZSB1c2VyIHRvIHpvb20gYnkgZG91YmxlIGNsaWNraW5nLlxuICAgICAqIEZpbmQgbW9yZSBkZXRhaWxzIGFuZCBleGFtcGxlcyB1c2luZyBgZG91YmxlQ2xpY2tab29tYCBpbiB0aGUge0BsaW5rIERvdWJsZUNsaWNrWm9vbUhhbmRsZXJ9IHNlY3Rpb24uXG4gICAgICovXG4gICAgZG91YmxlQ2xpY2tab29tOiBEb3VibGVDbGlja1pvb21IYW5kbGVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG1hcCdzIHtAbGluayBUb3VjaFpvb21Sb3RhdGVIYW5kbGVyfSwgd2hpY2ggYWxsb3dzIHRoZSB1c2VyIHRvIHpvb20gb3Igcm90YXRlIHRoZSBtYXAgd2l0aCB0b3VjaCBnZXN0dXJlcy5cbiAgICAgKiBGaW5kIG1vcmUgZGV0YWlscyBhbmQgZXhhbXBsZXMgdXNpbmcgYHRvdWNoWm9vbVJvdGF0ZWAgaW4gdGhlIHtAbGluayBUb3VjaFpvb21Sb3RhdGVIYW5kbGVyfSBzZWN0aW9uLlxuICAgICAqL1xuICAgIHRvdWNoWm9vbVJvdGF0ZTogVG91Y2hab29tUm90YXRlSGFuZGxlcjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBtYXAncyB7QGxpbmsgVG91Y2hQaXRjaEhhbmRsZXJ9LCB3aGljaCBhbGxvd3MgdGhlIHVzZXIgdG8gcGl0Y2ggdGhlIG1hcCB3aXRoIHRvdWNoIGdlc3R1cmVzLlxuICAgICAqIEZpbmQgbW9yZSBkZXRhaWxzIGFuZCBleGFtcGxlcyB1c2luZyBgdG91Y2hQaXRjaGAgaW4gdGhlIHtAbGluayBUb3VjaFBpdGNoSGFuZGxlcn0gc2VjdGlvbi5cbiAgICAgKi9cbiAgICB0b3VjaFBpdGNoOiBUb3VjaFBpdGNoSGFuZGxlcjtcblxuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnM6IE1hcE9wdGlvbnMpIHtcbiAgICAgICAgTGl2ZVBlcmZvcm1hbmNlVXRpbHMubWFyayhQZXJmb3JtYW5jZU1hcmtlcnMuY3JlYXRlKTtcblxuICAgICAgICBvcHRpb25zID0gZXh0ZW5kKHt9LCBkZWZhdWx0T3B0aW9ucywgb3B0aW9ucyk7XG5cbiAgICAgICAgaWYgKG9wdGlvbnMubWluWm9vbSAhPSBudWxsICYmIG9wdGlvbnMubWF4Wm9vbSAhPSBudWxsICYmIG9wdGlvbnMubWluWm9vbSA+IG9wdGlvbnMubWF4Wm9vbSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBtYXhab29tIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIG1pblpvb21gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChvcHRpb25zLm1pblBpdGNoICE9IG51bGwgJiYgb3B0aW9ucy5tYXhQaXRjaCAhPSBudWxsICYmIG9wdGlvbnMubWluUGl0Y2ggPiBvcHRpb25zLm1heFBpdGNoKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYG1heFBpdGNoIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIG1pblBpdGNoYCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAob3B0aW9ucy5taW5QaXRjaCAhPSBudWxsICYmIG9wdGlvbnMubWluUGl0Y2ggPCBkZWZhdWx0TWluUGl0Y2gpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgbWluUGl0Y2ggbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJHtkZWZhdWx0TWluUGl0Y2h9YCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAob3B0aW9ucy5tYXhQaXRjaCAhPSBudWxsICYmIG9wdGlvbnMubWF4UGl0Y2ggPiBkZWZhdWx0TWF4UGl0Y2gpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgbWF4UGl0Y2ggbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJHtkZWZhdWx0TWF4UGl0Y2h9YCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBkaXNhYmxlIGFudGlhbGlhcyB3aXRoIE9TL2lPUyAxNS40IGFuZCAxNS41IGR1ZSB0byByZW5kZXJpbmcgYnVnXG4gICAgICAgIGlmIChvcHRpb25zLmFudGlhbGlhcyAmJiBpc1NhZmFyaVdpdGhBbnRpYWxpYXNpbmdCdWcod2luZG93KSkge1xuICAgICAgICAgICAgb3B0aW9ucy5hbnRpYWxpYXMgPSBmYWxzZTtcbiAgICAgICAgICAgIHdhcm5PbmNlKCdBbnRpYWxpYXNpbmcgaXMgZGlzYWJsZWQgZm9yIHRoaXMgV2ViR0wgY29udGV4dCB0byBhdm9pZCBicm93c2VyIGJ1ZzogaHR0cHM6Ly9naXRodWIuY29tL21hcGJveC9tYXBib3gtZ2wtanMvaXNzdWVzLzExNjA5Jyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB0cmFuc2Zvcm0gPSBuZXcgVHJhbnNmb3JtKG9wdGlvbnMubWluWm9vbSwgb3B0aW9ucy5tYXhab29tLCBvcHRpb25zLm1pblBpdGNoLCBvcHRpb25zLm1heFBpdGNoLCBvcHRpb25zLnJlbmRlcldvcmxkQ29waWVzKTtcbiAgICAgICAgc3VwZXIodHJhbnNmb3JtLCBvcHRpb25zKTtcblxuICAgICAgICB0aGlzLl9pbnRlcmFjdGl2ZSA9IG9wdGlvbnMuaW50ZXJhY3RpdmU7XG4gICAgICAgIHRoaXMuX21pblRpbGVDYWNoZVNpemUgPSBvcHRpb25zLm1pblRpbGVDYWNoZVNpemU7XG4gICAgICAgIHRoaXMuX21heFRpbGVDYWNoZVNpemUgPSBvcHRpb25zLm1heFRpbGVDYWNoZVNpemU7XG4gICAgICAgIHRoaXMuX2ZhaWxJZk1ham9yUGVyZm9ybWFuY2VDYXZlYXQgPSBvcHRpb25zLmZhaWxJZk1ham9yUGVyZm9ybWFuY2VDYXZlYXQ7XG4gICAgICAgIHRoaXMuX3ByZXNlcnZlRHJhd2luZ0J1ZmZlciA9IG9wdGlvbnMucHJlc2VydmVEcmF3aW5nQnVmZmVyO1xuICAgICAgICB0aGlzLl9hbnRpYWxpYXMgPSBvcHRpb25zLmFudGlhbGlhcztcbiAgICAgICAgdGhpcy5fdXNlV2ViR0wyID0gb3B0aW9ucy51c2VXZWJHTDI7XG4gICAgICAgIHRoaXMuX3RyYWNrUmVzaXplID0gb3B0aW9ucy50cmFja1Jlc2l6ZTtcbiAgICAgICAgdGhpcy5fYmVhcmluZ1NuYXAgPSBvcHRpb25zLmJlYXJpbmdTbmFwO1xuICAgICAgICB0aGlzLl9yZWZyZXNoRXhwaXJlZFRpbGVzID0gb3B0aW9ucy5yZWZyZXNoRXhwaXJlZFRpbGVzO1xuICAgICAgICB0aGlzLl9mYWRlRHVyYXRpb24gPSBvcHRpb25zLmZhZGVEdXJhdGlvbjtcbiAgICAgICAgdGhpcy5faXNJbml0aWFsTG9hZCA9IHRydWU7XG4gICAgICAgIHRoaXMuX2Nyb3NzU291cmNlQ29sbGlzaW9ucyA9IG9wdGlvbnMuY3Jvc3NTb3VyY2VDb2xsaXNpb25zO1xuICAgICAgICB0aGlzLl9jb2xsZWN0UmVzb3VyY2VUaW1pbmcgPSBvcHRpb25zLmNvbGxlY3RSZXNvdXJjZVRpbWluZztcbiAgICAgICAgdGhpcy5fb3B0aW1pemVGb3JUZXJyYWluID0gb3B0aW9ucy5vcHRpbWl6ZUZvclRlcnJhaW47XG4gICAgICAgIHRoaXMuX2xhbmd1YWdlID0gdGhpcy5fcGFyc2VMYW5ndWFnZShvcHRpb25zLmxhbmd1YWdlKTtcbiAgICAgICAgdGhpcy5fd29ybGR2aWV3ID0gb3B0aW9ucy53b3JsZHZpZXc7XG4gICAgICAgIHRoaXMuX3JlbmRlclRhc2tRdWV1ZSA9IG5ldyBUYXNrUXVldWUoKTtcbiAgICAgICAgdGhpcy5fZG9tUmVuZGVyVGFza1F1ZXVlID0gbmV3IFRhc2tRdWV1ZSgpO1xuICAgICAgICB0aGlzLl9jb250cm9scyA9IFtdO1xuICAgICAgICB0aGlzLl9tYXJrZXJzID0gW107XG4gICAgICAgIHRoaXMuX3BvcHVwcyA9IFtdO1xuICAgICAgICB0aGlzLl9tYXBJZCA9IHVuaXF1ZUlkKCk7XG4gICAgICAgIHRoaXMuX2xvY2FsZSA9IGV4dGVuZCh7fSwgZGVmYXVsdExvY2FsZSwgb3B0aW9ucy5sb2NhbGUpO1xuICAgICAgICB0aGlzLl9jbGlja1RvbGVyYW5jZSA9IG9wdGlvbnMuY2xpY2tUb2xlcmFuY2U7XG4gICAgICAgIHRoaXMuX2Nvb3BlcmF0aXZlR2VzdHVyZXMgPSBvcHRpb25zLmNvb3BlcmF0aXZlR2VzdHVyZXM7XG4gICAgICAgIHRoaXMuX3BlcmZvcm1hbmNlTWV0cmljc0NvbGxlY3Rpb24gPSBvcHRpb25zLnBlcmZvcm1hbmNlTWV0cmljc0NvbGxlY3Rpb247XG4gICAgICAgIHRoaXMuX2NvbnRhaW5lcldpZHRoID0gMDtcbiAgICAgICAgdGhpcy5fY29udGFpbmVySGVpZ2h0ID0gMDtcblxuICAgICAgICB0aGlzLl9hdmVyYWdlRWxldmF0aW9uTGFzdFNhbXBsZWRBdCA9IC1JbmZpbml0eTtcbiAgICAgICAgdGhpcy5fYXZlcmFnZUVsZXZhdGlvbkV4YWdnZXJhdGlvbiA9IDA7XG4gICAgICAgIHRoaXMuX2F2ZXJhZ2VFbGV2YXRpb24gPSBuZXcgRWFzZWRWYXJpYWJsZSgwKTtcblxuICAgICAgICB0aGlzLl9pbnRlcmFjdGlvblJhbmdlID0gWytJbmZpbml0eSwgLUluZmluaXR5XTtcbiAgICAgICAgdGhpcy5fdmlzaWJpbGl0eUhpZGRlbiA9IDA7XG5cbiAgICAgICAgdGhpcy5fdXNlRXhwbGljaXRQcm9qZWN0aW9uID0gZmFsc2U7IC8vIEZhbGxiYWNrIHRvIHN0eWxlc2hlZXQgYnkgZGVmYXVsdFxuXG4gICAgICAgIHRoaXMuX3JlcXVlc3RNYW5hZ2VyID0gbmV3IFJlcXVlc3RNYW5hZ2VyKG9wdGlvbnMudHJhbnNmb3JtUmVxdWVzdCwgb3B0aW9ucy5hY2Nlc3NUb2tlbiwgb3B0aW9ucy50ZXN0TW9kZSk7XG4gICAgICAgIHRoaXMuX3NpbGVuY2VBdXRoRXJyb3JzID0gISFvcHRpb25zLnRlc3RNb2RlO1xuXG4gICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5jb250YWluZXIgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0aGlzLl9jb250YWluZXIgPSB3aW5kb3cuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQob3B0aW9ucy5jb250YWluZXIpO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMuX2NvbnRhaW5lcikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ29udGFpbmVyICcke29wdGlvbnMuY29udGFpbmVyfScgbm90IGZvdW5kLmApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKG9wdGlvbnMuY29udGFpbmVyIGluc3RhbmNlb2Ygd2luZG93LkhUTUxFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLl9jb250YWluZXIgPSBvcHRpb25zLmNvbnRhaW5lcjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCB0eXBlOiAnY29udGFpbmVyJyBtdXN0IGJlIGEgU3RyaW5nIG9yIEhUTUxFbGVtZW50LmApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuX2NvbnRhaW5lci5jaGlsZE5vZGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHdhcm5PbmNlKGBUaGUgbWFwIGNvbnRhaW5lciBlbGVtZW50IHNob3VsZCBiZSBlbXB0eSwgb3RoZXJ3aXNlIHRoZSBtYXAncyBpbnRlcmFjdGl2aXR5IHdpbGwgYmUgbmVnYXRpdmVseSBpbXBhY3RlZC4gSWYgeW91IHdhbnQgdG8gZGlzcGxheSBhIG1lc3NhZ2Ugd2hlbiBXZWJHTCBpcyBub3Qgc3VwcG9ydGVkLCB1c2UgdGhlIE1hcGJveCBHTCBTdXBwb3J0ZWQgcGx1Z2luIGluc3RlYWQuYCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAob3B0aW9ucy5tYXhCb3VuZHMpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0TWF4Qm91bmRzKG9wdGlvbnMubWF4Qm91bmRzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJpbmRBbGwoW1xuICAgICAgICAgICAgJ19vbldpbmRvd09ubGluZScsXG4gICAgICAgICAgICAnX29uV2luZG93UmVzaXplJyxcbiAgICAgICAgICAgICdfb25WaXNpYmlsaXR5Q2hhbmdlJyxcbiAgICAgICAgICAgICdfb25NYXBTY3JvbGwnLFxuICAgICAgICAgICAgJ19jb250ZXh0TG9zdCcsXG4gICAgICAgICAgICAnX2NvbnRleHRSZXN0b3JlZCdcbiAgICAgICAgXSwgdGhpcyk7XG5cbiAgICAgICAgdGhpcy5fc2V0dXBDb250YWluZXIoKTtcbiAgICAgICAgdGhpcy5fc2V0dXBQYWludGVyKCk7XG4gICAgICAgIGlmICh0aGlzLnBhaW50ZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gaW5pdGlhbGl6ZSBXZWJHTC5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMub24oJ21vdmUnLCAoKSA9PiB0aGlzLl91cGRhdGUoZmFsc2UpKTtcbiAgICAgICAgdGhpcy5vbignbW92ZWVuZCcsICgpID0+IHRoaXMuX3VwZGF0ZShmYWxzZSkpO1xuICAgICAgICB0aGlzLm9uKCd6b29tJywgKCkgPT4gdGhpcy5fdXBkYXRlKHRydWUpKTtcblxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdvbmxpbmUnLCB0aGlzLl9vbldpbmRvd09ubGluZSwgZmFsc2UpO1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHRoaXMuX29uV2luZG93UmVzaXplLCBmYWxzZSk7XG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignb3JpZW50YXRpb25jaGFuZ2UnLCB0aGlzLl9vbldpbmRvd1Jlc2l6ZSwgZmFsc2UpO1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3dlYmtpdGZ1bGxzY3JlZW5jaGFuZ2UnLCB0aGlzLl9vbldpbmRvd1Jlc2l6ZSwgZmFsc2UpO1xuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Zpc2liaWxpdHljaGFuZ2UnLCB0aGlzLl9vblZpc2liaWxpdHlDaGFuZ2UsIGZhbHNlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuaGFuZGxlcnMgPSBuZXcgSGFuZGxlck1hbmFnZXIodGhpcywgb3B0aW9ucyk7XG5cbiAgICAgICAgdGhpcy5fbG9jYWxGb250RmFtaWx5ID0gb3B0aW9ucy5sb2NhbEZvbnRGYW1pbHk7XG4gICAgICAgIHRoaXMuX2xvY2FsSWRlb2dyYXBoRm9udEZhbWlseSA9IG9wdGlvbnMubG9jYWxJZGVvZ3JhcGhGb250RmFtaWx5O1xuXG4gICAgICAgIGlmIChvcHRpb25zLnN0eWxlKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0eWxlKG9wdGlvbnMuc3R5bGUsIHtsb2NhbEZvbnRGYW1pbHk6IHRoaXMuX2xvY2FsRm9udEZhbWlseSwgbG9jYWxJZGVvZ3JhcGhGb250RmFtaWx5OiB0aGlzLl9sb2NhbElkZW9ncmFwaEZvbnRGYW1pbHl9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChvcHRpb25zLnByb2plY3Rpb24pIHtcbiAgICAgICAgICAgIHRoaXMuc2V0UHJvamVjdGlvbihvcHRpb25zLnByb2plY3Rpb24pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaGFzaE5hbWUgPSAodHlwZW9mIG9wdGlvbnMuaGFzaCA9PT0gJ3N0cmluZycgJiYgb3B0aW9ucy5oYXNoKSB8fCB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuX2hhc2ggPSBvcHRpb25zLmhhc2ggJiYgKG5ldyBIYXNoKGhhc2hOYW1lKSkuYWRkVG8odGhpcyk7XG4gICAgICAgIC8vIGRvbid0IHNldCBwb3NpdGlvbiBmcm9tIG9wdGlvbnMgaWYgc2V0IHRocm91Z2ggaGFzaFxuICAgICAgICBpZiAoIXRoaXMuX2hhc2ggfHwgIXRoaXMuX2hhc2guX29uSGFzaENoYW5nZSgpKSB7XG4gICAgICAgICAgICB0aGlzLmp1bXBUbyh7XG4gICAgICAgICAgICAgICAgY2VudGVyOiBvcHRpb25zLmNlbnRlcixcbiAgICAgICAgICAgICAgICB6b29tOiBvcHRpb25zLnpvb20sXG4gICAgICAgICAgICAgICAgYmVhcmluZzogb3B0aW9ucy5iZWFyaW5nLFxuICAgICAgICAgICAgICAgIHBpdGNoOiBvcHRpb25zLnBpdGNoXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuYm91bmRzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXNpemUoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmZpdEJvdW5kcyhvcHRpb25zLmJvdW5kcywgZXh0ZW5kKHt9LCBvcHRpb25zLmZpdEJvdW5kc09wdGlvbnMsIHtkdXJhdGlvbjogMH0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucmVzaXplKCk7XG5cbiAgICAgICAgaWYgKG9wdGlvbnMuYXR0cmlidXRpb25Db250cm9sKVxuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgdGhpcy5hZGRDb250cm9sKG5ldyBBdHRyaWJ1dGlvbkNvbnRyb2woe2N1c3RvbUF0dHJpYnV0aW9uOiBvcHRpb25zLmN1c3RvbUF0dHJpYnV0aW9ufSkpO1xuXG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgdGhpcy5fbG9nb0NvbnRyb2wgPSBuZXcgTG9nb0NvbnRyb2woKTtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICB0aGlzLmFkZENvbnRyb2wodGhpcy5fbG9nb0NvbnRyb2wsIG9wdGlvbnMubG9nb1Bvc2l0aW9uKTtcblxuICAgICAgICB0aGlzLm9uKCdzdHlsZS5sb2FkJywgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtLnVubW9kaWZpZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmp1bXBUbygodGhpcy5zdHlsZS5zdHlsZXNoZWV0OiBhbnkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMub24oJ2RhdGEnLCAoZXZlbnQ6IE1hcERhdGFFdmVudCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fdXBkYXRlKGV2ZW50LmRhdGFUeXBlID09PSAnc3R5bGUnKTtcbiAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoYCR7ZXZlbnQuZGF0YVR5cGV9ZGF0YWAsIGV2ZW50KSk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm9uKCdkYXRhbG9hZGluZycsIChldmVudDogTWFwRGF0YUV2ZW50KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmZpcmUobmV3IEV2ZW50KGAke2V2ZW50LmRhdGFUeXBlfWRhdGFsb2FkaW5nYCwgZXZlbnQpKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLypcbiAgICAqIFJldHVybnMgYSB1bmlxdWUgbnVtYmVyIGZvciB0aGlzIG1hcCBpbnN0YW5jZSB3aGljaCBpcyB1c2VkIGZvciB0aGUgTWFwTG9hZEV2ZW50XG4gICAgKiB0byBtYWtlIHN1cmUgd2Ugb25seSBmaXJlIG9uZSBldmVudCBwZXIgaW5zdGFudGlhdGVkIG1hcCBvYmplY3QuXG4gICAgKiBAcHJpdmF0ZVxuICAgICogQHJldHVybnMge251bWJlcn1cbiAgICAqL1xuICAgIF9nZXRNYXBJZCgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFwSWQ7XG4gICAgfVxuXG4gICAgLyoqIEBzZWN0aW9uIHtDb250cm9sc30gKi9cblxuICAgIC8qKlxuICAgICAqIEFkZHMgYW4ge0BsaW5rIElDb250cm9sfSB0byB0aGUgbWFwLCBjYWxsaW5nIGBjb250cm9sLm9uQWRkKHRoaXMpYC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7SUNvbnRyb2x9IGNvbnRyb2wgVGhlIHtAbGluayBJQ29udHJvbH0gdG8gYWRkLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbcG9zaXRpb25dIFBvc2l0aW9uIG9uIHRoZSBtYXAgdG8gd2hpY2ggdGhlIGNvbnRyb2wgd2lsbCBiZSBhZGRlZC5cbiAgICAgKiBWYWxpZCB2YWx1ZXMgYXJlIGAndG9wLWxlZnQnYCwgYCd0b3AtcmlnaHQnYCwgYCdib3R0b20tbGVmdCdgLCBhbmQgYCdib3R0b20tcmlnaHQnYC4gRGVmYXVsdHMgdG8gYCd0b3AtcmlnaHQnYC5cbiAgICAgKiBAcmV0dXJucyB7TWFwfSBSZXR1cm5zIGl0c2VsZiB0byBhbGxvdyBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gQWRkIHpvb20gYW5kIHJvdGF0aW9uIGNvbnRyb2xzIHRvIHRoZSBtYXAuXG4gICAgICogbWFwLmFkZENvbnRyb2wobmV3IG1hcGJveGdsLk5hdmlnYXRpb25Db250cm9sKCkpO1xuICAgICAqIEBzZWUgW0V4YW1wbGU6IERpc3BsYXkgbWFwIG5hdmlnYXRpb24gY29udHJvbHNdKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvbmF2aWdhdGlvbi8pXG4gICAgICovXG4gICAgYWRkQ29udHJvbChjb250cm9sOiBJQ29udHJvbCwgcG9zaXRpb24/OiBDb250cm9sUG9zaXRpb24pOiB0aGlzIHtcbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGlmIChjb250cm9sLmdldERlZmF1bHRQb3NpdGlvbikge1xuICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gY29udHJvbC5nZXREZWZhdWx0UG9zaXRpb24oKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcG9zaXRpb24gPSAndG9wLXJpZ2h0JztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoIWNvbnRyb2wgfHwgIWNvbnRyb2wub25BZGQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmZpcmUobmV3IEVycm9yRXZlbnQobmV3IEVycm9yKFxuICAgICAgICAgICAgICAgICdJbnZhbGlkIGFyZ3VtZW50IHRvIG1hcC5hZGRDb250cm9sKCkuIEFyZ3VtZW50IG11c3QgYmUgYSBjb250cm9sIHdpdGggb25BZGQgYW5kIG9uUmVtb3ZlIG1ldGhvZHMuJykpKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjb250cm9sRWxlbWVudCA9IGNvbnRyb2wub25BZGQodGhpcyk7XG4gICAgICAgIHRoaXMuX2NvbnRyb2xzLnB1c2goY29udHJvbCk7XG5cbiAgICAgICAgY29uc3QgcG9zaXRpb25Db250YWluZXIgPSB0aGlzLl9jb250cm9sUG9zaXRpb25zW3Bvc2l0aW9uXTtcbiAgICAgICAgaWYgKHBvc2l0aW9uLmluZGV4T2YoJ2JvdHRvbScpICE9PSAtMSkge1xuICAgICAgICAgICAgcG9zaXRpb25Db250YWluZXIuaW5zZXJ0QmVmb3JlKGNvbnRyb2xFbGVtZW50LCBwb3NpdGlvbkNvbnRhaW5lci5maXJzdENoaWxkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBvc2l0aW9uQ29udGFpbmVyLmFwcGVuZENoaWxkKGNvbnRyb2xFbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIHRoZSBjb250cm9sIGZyb20gdGhlIG1hcC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7SUNvbnRyb2x9IGNvbnRyb2wgVGhlIHtAbGluayBJQ29udHJvbH0gdG8gcmVtb3ZlLlxuICAgICAqIEByZXR1cm5zIHtNYXB9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBEZWZpbmUgYSBuZXcgbmF2aWdhdGlvbiBjb250cm9sLlxuICAgICAqIGNvbnN0IG5hdmlnYXRpb24gPSBuZXcgbWFwYm94Z2wuTmF2aWdhdGlvbkNvbnRyb2woKTtcbiAgICAgKiAvLyBBZGQgem9vbSBhbmQgcm90YXRpb24gY29udHJvbHMgdG8gdGhlIG1hcC5cbiAgICAgKiBtYXAuYWRkQ29udHJvbChuYXZpZ2F0aW9uKTtcbiAgICAgKiAvLyBSZW1vdmUgem9vbSBhbmQgcm90YXRpb24gY29udHJvbHMgZnJvbSB0aGUgbWFwLlxuICAgICAqIG1hcC5yZW1vdmVDb250cm9sKG5hdmlnYXRpb24pO1xuICAgICAqL1xuICAgIHJlbW92ZUNvbnRyb2woY29udHJvbDogSUNvbnRyb2wpOiB0aGlzIHtcbiAgICAgICAgaWYgKCFjb250cm9sIHx8ICFjb250cm9sLm9uUmVtb3ZlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5maXJlKG5ldyBFcnJvckV2ZW50KG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICAnSW52YWxpZCBhcmd1bWVudCB0byBtYXAucmVtb3ZlQ29udHJvbCgpLiBBcmd1bWVudCBtdXN0IGJlIGEgY29udHJvbCB3aXRoIG9uQWRkIGFuZCBvblJlbW92ZSBtZXRob2RzLicpKSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2kgPSB0aGlzLl9jb250cm9scy5pbmRleE9mKGNvbnRyb2wpO1xuICAgICAgICBpZiAoY2kgPiAtMSkgdGhpcy5fY29udHJvbHMuc3BsaWNlKGNpLCAxKTtcbiAgICAgICAgY29udHJvbC5vblJlbW92ZSh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGEgY29udHJvbCBpcyBvbiB0aGUgbWFwLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtJQ29udHJvbH0gY29udHJvbCBUaGUge0BsaW5rIElDb250cm9sfSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBtYXAgY29udGFpbnMgY29udHJvbC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIERlZmluZSBhIG5ldyBuYXZpZ2F0aW9uIGNvbnRyb2wuXG4gICAgICogY29uc3QgbmF2aWdhdGlvbiA9IG5ldyBtYXBib3hnbC5OYXZpZ2F0aW9uQ29udHJvbCgpO1xuICAgICAqIC8vIEFkZCB6b29tIGFuZCByb3RhdGlvbiBjb250cm9scyB0byB0aGUgbWFwLlxuICAgICAqIG1hcC5hZGRDb250cm9sKG5hdmlnYXRpb24pO1xuICAgICAqIC8vIENoZWNrIHRoYXQgdGhlIG5hdmlnYXRpb24gY29udHJvbCBleGlzdHMgb24gdGhlIG1hcC5cbiAgICAgKiBjb25zdCBhZGRlZCA9IG1hcC5oYXNDb250cm9sKG5hdmlnYXRpb24pO1xuICAgICAqIC8vIGFkZGVkID09PSB0cnVlXG4gICAgICovXG4gICAgaGFzQ29udHJvbChjb250cm9sOiBJQ29udHJvbCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udHJvbHMuaW5kZXhPZihjb250cm9sKSA+IC0xO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIG1hcCdzIGNvbnRhaW5pbmcgSFRNTCBlbGVtZW50LlxuICAgICAqXG4gICAgICogQHJldHVybnMge0hUTUxFbGVtZW50fSBUaGUgbWFwJ3MgY29udGFpbmVyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgY29udGFpbmVyID0gbWFwLmdldENvbnRhaW5lcigpO1xuICAgICAqL1xuICAgIGdldENvbnRhaW5lcigpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250YWluZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgSFRNTCBlbGVtZW50IGNvbnRhaW5pbmcgdGhlIG1hcCdzIGA8Y2FudmFzPmAgZWxlbWVudC5cbiAgICAgKlxuICAgICAqIElmIHlvdSB3YW50IHRvIGFkZCBub24tR0wgb3ZlcmxheXMgdG8gdGhlIG1hcCwgeW91IHNob3VsZCBhcHBlbmQgdGhlbSB0byB0aGlzIGVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBUaGlzIGlzIHRoZSBlbGVtZW50IHRvIHdoaWNoIGV2ZW50IGJpbmRpbmdzIGZvciBtYXAgaW50ZXJhY3Rpdml0eSAoc3VjaCBhcyBwYW5uaW5nIGFuZCB6b29taW5nKSBhcmVcbiAgICAgKiBhdHRhY2hlZC4gSXQgd2lsbCByZWNlaXZlIGJ1YmJsZWQgZXZlbnRzIGZyb20gY2hpbGQgZWxlbWVudHMgc3VjaCBhcyB0aGUgYDxjYW52YXM+YCwgYnV0IG5vdCBmcm9tXG4gICAgICogbWFwIGNvbnRyb2xzLlxuICAgICAqXG4gICAgICogQHJldHVybnMge0hUTUxFbGVtZW50fSBUaGUgY29udGFpbmVyIG9mIHRoZSBtYXAncyBgPGNhbnZhcz5gLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgY2FudmFzQ29udGFpbmVyID0gbWFwLmdldENhbnZhc0NvbnRhaW5lcigpO1xuICAgICAqIEBzZWUgW0V4YW1wbGU6IENyZWF0ZSBhIGRyYWdnYWJsZSBwb2ludF0oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9kcmFnLWEtcG9pbnQvKVxuICAgICAqIEBzZWUgW0V4YW1wbGU6IEhpZ2hsaWdodCBmZWF0dXJlcyB3aXRoaW4gYSBib3VuZGluZyBib3hdKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvdXNpbmctYm94LXF1ZXJ5cmVuZGVyZWRmZWF0dXJlcy8pXG4gICAgICovXG4gICAgZ2V0Q2FudmFzQ29udGFpbmVyKCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhbnZhc0NvbnRhaW5lcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBtYXAncyBgPGNhbnZhcz5gIGVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7SFRNTENhbnZhc0VsZW1lbnR9IFRoZSBtYXAncyBgPGNhbnZhcz5gIGVsZW1lbnQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBjYW52YXMgPSBtYXAuZ2V0Q2FudmFzKCk7XG4gICAgICogQHNlZSBbRXhhbXBsZTogTWVhc3VyZSBkaXN0YW5jZXNdKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvbWVhc3VyZS8pXG4gICAgICogQHNlZSBbRXhhbXBsZTogRGlzcGxheSBhIHBvcHVwIG9uIGhvdmVyXShodHRwczovL3d3dy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL3BvcHVwLW9uLWhvdmVyLylcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBDZW50ZXIgdGhlIG1hcCBvbiBhIGNsaWNrZWQgc3ltYm9sXShodHRwczovL3d3dy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2NlbnRlci1vbi1zeW1ib2wvKVxuICAgICAqL1xuICAgIGdldENhbnZhcygpOiBIVE1MQ2FudmFzRWxlbWVudCB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYW52YXM7XG4gICAgfVxuXG4gICAgLyoqIEBzZWN0aW9uIHtNYXAgY29uc3RyYWludHN9ICovXG5cbiAgICAvKipcbiAgICAgKiBSZXNpemVzIHRoZSBtYXAgYWNjb3JkaW5nIHRvIHRoZSBkaW1lbnNpb25zIG9mIGl0c1xuICAgICAqIGBjb250YWluZXJgIGVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBDaGVja3MgaWYgdGhlIG1hcCBjb250YWluZXIgc2l6ZSBjaGFuZ2VkIGFuZCB1cGRhdGVzIHRoZSBtYXAgaWYgaXQgaGFzIGNoYW5nZWQuXG4gICAgICogVGhpcyBtZXRob2QgbXVzdCBiZSBjYWxsZWQgYWZ0ZXIgdGhlIG1hcCdzIGBjb250YWluZXJgIGlzIHJlc2l6ZWQgcHJvZ3JhbW1hdGljYWxseVxuICAgICAqIG9yIHdoZW4gdGhlIG1hcCBpcyBzaG93biBhZnRlciBiZWluZyBpbml0aWFsbHkgaGlkZGVuIHdpdGggQ1NTLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3QgfCBudWxsfSBldmVudERhdGEgQWRkaXRpb25hbCBwcm9wZXJ0aWVzIHRvIGJlIHBhc3NlZCB0byBgbW92ZXN0YXJ0YCwgYG1vdmVgLCBgcmVzaXplYCwgYW5kIGBtb3ZlZW5kYFxuICAgICAqICAgZXZlbnRzIHRoYXQgZ2V0IHRyaWdnZXJlZCBhcyBhIHJlc3VsdCBvZiByZXNpemUuIFRoaXMgY2FuIGJlIHVzZWZ1bCBmb3IgZGlmZmVyZW50aWF0aW5nIHRoZVxuICAgICAqICAgc291cmNlIG9mIGFuIGV2ZW50IChmb3IgZXhhbXBsZSwgdXNlci1pbml0aWF0ZWQgb3IgcHJvZ3JhbW1hdGljYWxseS10cmlnZ2VyZWQgZXZlbnRzKS5cbiAgICAgKiBAcmV0dXJucyB7TWFwfSBSZXR1cm5zIGl0c2VsZiB0byBhbGxvdyBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gUmVzaXplIHRoZSBtYXAgd2hlbiB0aGUgbWFwIGNvbnRhaW5lciBpcyBzaG93blxuICAgICAqIC8vIGFmdGVyIGJlaW5nIGluaXRpYWxseSBoaWRkZW4gd2l0aCBDU1MuXG4gICAgICogY29uc3QgbWFwRGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21hcCcpO1xuICAgICAqIGlmIChtYXBEaXYuc3R5bGUudmlzaWJpbGl0eSA9PT0gdHJ1ZSkgbWFwLnJlc2l6ZSgpO1xuICAgICAqL1xuICAgIHJlc2l6ZShldmVudERhdGE/OiBPYmplY3QpOiB0aGlzIHtcbiAgICAgICAgdGhpcy5fdXBkYXRlQ29udGFpbmVyRGltZW5zaW9ucygpO1xuXG4gICAgICAgIC8vIGRvIG5vdGhpbmcgaWYgY29udGFpbmVyIHJlbWFpbmVkIHRoZSBzYW1lIHNpemVcbiAgICAgICAgaWYgKHRoaXMuX2NvbnRhaW5lcldpZHRoID09PSB0aGlzLnRyYW5zZm9ybS53aWR0aCAmJiB0aGlzLl9jb250YWluZXJIZWlnaHQgPT09IHRoaXMudHJhbnNmb3JtLmhlaWdodCkgcmV0dXJuIHRoaXM7XG5cbiAgICAgICAgdGhpcy5fcmVzaXplQ2FudmFzKHRoaXMuX2NvbnRhaW5lcldpZHRoLCB0aGlzLl9jb250YWluZXJIZWlnaHQpO1xuXG4gICAgICAgIHRoaXMudHJhbnNmb3JtLnJlc2l6ZSh0aGlzLl9jb250YWluZXJXaWR0aCwgdGhpcy5fY29udGFpbmVySGVpZ2h0KTtcbiAgICAgICAgdGhpcy5wYWludGVyLnJlc2l6ZShNYXRoLmNlaWwodGhpcy5fY29udGFpbmVyV2lkdGgpLCBNYXRoLmNlaWwodGhpcy5fY29udGFpbmVySGVpZ2h0KSk7XG5cbiAgICAgICAgY29uc3QgZmlyZU1vdmluZyA9ICF0aGlzLl9tb3Zpbmc7XG4gICAgICAgIGlmIChmaXJlTW92aW5nKSB7XG4gICAgICAgICAgICB0aGlzLmZpcmUobmV3IEV2ZW50KCdtb3Zlc3RhcnQnLCBldmVudERhdGEpKVxuICAgICAgICAgICAgICAgIC5maXJlKG5ldyBFdmVudCgnbW92ZScsIGV2ZW50RGF0YSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgncmVzaXplJywgZXZlbnREYXRhKSk7XG5cbiAgICAgICAgaWYgKGZpcmVNb3ZpbmcpIHRoaXMuZmlyZShuZXcgRXZlbnQoJ21vdmVlbmQnLCBldmVudERhdGEpKTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBtYXAncyBnZW9ncmFwaGljYWwgYm91bmRzLiBXaGVuIHRoZSBiZWFyaW5nIG9yIHBpdGNoIGlzIG5vbi16ZXJvLCB0aGUgdmlzaWJsZSByZWdpb24gaXMgbm90XG4gICAgICogYW4gYXhpcy1hbGlnbmVkIHJlY3RhbmdsZSwgYW5kIHRoZSByZXN1bHQgaXMgdGhlIHNtYWxsZXN0IGJvdW5kcyB0aGF0IGVuY29tcGFzc2VzIHRoZSB2aXNpYmxlIHJlZ2lvbi5cbiAgICAgKiBJZiBhIHBhZGRpbmcgaXMgc2V0IG9uIHRoZSBtYXAsIHRoZSBib3VuZHMgcmV0dXJuZWQgYXJlIGZvciB0aGUgaW5zZXQuXG4gICAgICogV2l0aCBnbG9iZSBwcm9qZWN0aW9uLCB0aGUgc21hbGxlc3QgYm91bmRzIGVuY29tcGFzc2luZyB0aGUgdmlzaWJsZSByZWdpb25cbiAgICAgKiBtYXkgbm90IHByZWNpc2VseSByZXByZXNlbnQgdGhlIHZpc2libGUgcmVnaW9uIGR1ZSB0byB0aGUgZWFydGgncyBjdXJ2YXR1cmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7TG5nTGF0Qm91bmRzfSBUaGUgZ2VvZ3JhcGhpY2FsIGJvdW5kcyBvZiB0aGUgbWFwIGFzIHtAbGluayBMbmdMYXRCb3VuZHN9LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgYm91bmRzID0gbWFwLmdldEJvdW5kcygpO1xuICAgICAqL1xuICAgIGdldEJvdW5kcygpOiBMbmdMYXRCb3VuZHMgfCBudWxsIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNmb3JtLmdldEJvdW5kcygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIG1heGltdW0gZ2VvZ3JhcGhpY2FsIGJvdW5kcyB0aGUgbWFwIGlzIGNvbnN0cmFpbmVkIHRvLCBvciBgbnVsbGAgaWYgbm9uZSBzZXQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7TWFwfSBUaGUgbWFwIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgbWF4Qm91bmRzID0gbWFwLmdldE1heEJvdW5kcygpO1xuICAgICAqL1xuICAgIGdldE1heEJvdW5kcygpOiBMbmdMYXRCb3VuZHMgfCBudWxsIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNmb3JtLmdldE1heEJvdW5kcygpIHx8IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyBvciBjbGVhcnMgdGhlIG1hcCdzIGdlb2dyYXBoaWNhbCBib3VuZHMuXG4gICAgICpcbiAgICAgKiBQYW4gYW5kIHpvb20gb3BlcmF0aW9ucyBhcmUgY29uc3RyYWluZWQgd2l0aGluIHRoZXNlIGJvdW5kcy5cbiAgICAgKiBJZiBhIHBhbiBvciB6b29tIGlzIHBlcmZvcm1lZCB0aGF0IHdvdWxkXG4gICAgICogZGlzcGxheSByZWdpb25zIG91dHNpZGUgdGhlc2UgYm91bmRzLCB0aGUgbWFwIHdpbGxcbiAgICAgKiBpbnN0ZWFkIGRpc3BsYXkgYSBwb3NpdGlvbiBhbmQgem9vbSBsZXZlbFxuICAgICAqIGFzIGNsb3NlIGFzIHBvc3NpYmxlIHRvIHRoZSBvcGVyYXRpb24ncyByZXF1ZXN0IHdoaWxlIHN0aWxsXG4gICAgICogcmVtYWluaW5nIHdpdGhpbiB0aGUgYm91bmRzLlxuICAgICAqXG4gICAgICogRm9yIGBtZXJjYXRvcmAgcHJvamVjdGlvbiwgdGhlIHZpZXdwb3J0IHdpbGwgYmUgY29uc3RyYWluZWQgdG8gdGhlIGJvdW5kcy5cbiAgICAgKiBGb3Igb3RoZXIgcHJvamVjdGlvbnMgc3VjaCBhcyBgZ2xvYmVgLCBvbmx5IHRoZSBtYXAgY2VudGVyIHdpbGwgYmUgY29uc3RyYWluZWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0xuZ0xhdEJvdW5kc0xpa2UgfCBudWxsIHwgdW5kZWZpbmVkfSBib3VuZHMgVGhlIG1heGltdW0gYm91bmRzIHRvIHNldC4gSWYgYG51bGxgIG9yIGB1bmRlZmluZWRgIGlzIHByb3ZpZGVkLCB0aGUgZnVuY3Rpb24gcmVtb3ZlcyB0aGUgbWFwJ3MgbWF4aW11bSBib3VuZHMuXG4gICAgICogQHJldHVybnMge01hcH0gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIERlZmluZSBib3VuZHMgdGhhdCBjb25mb3JtIHRvIHRoZSBgTG5nTGF0Qm91bmRzTGlrZWAgb2JqZWN0LlxuICAgICAqIGNvbnN0IGJvdW5kcyA9IFtcbiAgICAgKiAgICAgWy03NC4wNDcyOCwgNDAuNjgzOTJdLCAvLyBbd2VzdCwgc291dGhdXG4gICAgICogICAgIFstNzMuOTEwNTgsIDQwLjg3NzY0XSAgLy8gW2Vhc3QsIG5vcnRoXVxuICAgICAqIF07XG4gICAgICogLy8gU2V0IHRoZSBtYXAncyBtYXggYm91bmRzLlxuICAgICAqIG1hcC5zZXRNYXhCb3VuZHMoYm91bmRzKTtcbiAgICAgKi9cbiAgICBzZXRNYXhCb3VuZHMoYm91bmRzOiBMbmdMYXRCb3VuZHNMaWtlKTogdGhpcyB7XG4gICAgICAgIHRoaXMudHJhbnNmb3JtLnNldE1heEJvdW5kcyhMbmdMYXRCb3VuZHMuY29udmVydChib3VuZHMpKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3VwZGF0ZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgb3IgY2xlYXJzIHRoZSBtYXAncyBtaW5pbXVtIHpvb20gbGV2ZWwuXG4gICAgICogSWYgdGhlIG1hcCdzIGN1cnJlbnQgem9vbSBsZXZlbCBpcyBsb3dlciB0aGFuIHRoZSBuZXcgbWluaW11bSxcbiAgICAgKiB0aGUgbWFwIHdpbGwgem9vbSB0byB0aGUgbmV3IG1pbmltdW0uXG4gICAgICpcbiAgICAgKiBJdCBpcyBub3QgYWx3YXlzIHBvc3NpYmxlIHRvIHpvb20gb3V0IGFuZCByZWFjaCB0aGUgc2V0IGBtaW5ab29tYC5cbiAgICAgKiBPdGhlciBmYWN0b3JzIHN1Y2ggYXMgbWFwIGhlaWdodCBtYXkgcmVzdHJpY3Qgem9vbWluZy4gRm9yIGV4YW1wbGUsXG4gICAgICogaWYgdGhlIG1hcCBpcyA1MTJweCB0YWxsIGl0IHdpbGwgbm90IGJlIHBvc3NpYmxlIHRvIHpvb20gYmVsb3cgem9vbSAwXG4gICAgICogbm8gbWF0dGVyIHdoYXQgdGhlIGBtaW5ab29tYCBpcyBzZXQgdG8uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge251bWJlciB8IG51bGwgfCB1bmRlZmluZWR9IG1pblpvb20gVGhlIG1pbmltdW0gem9vbSBsZXZlbCB0byBzZXQgKC0yIC0gMjQpLlxuICAgICAqICAgSWYgYG51bGxgIG9yIGB1bmRlZmluZWRgIGlzIHByb3ZpZGVkLCB0aGUgZnVuY3Rpb24gcmVtb3ZlcyB0aGUgY3VycmVudCBtaW5pbXVtIHpvb20gYW5kIGl0IHdpbGwgYmUgcmVzZXQgdG8gLTIuXG4gICAgICogQHJldHVybnMge01hcH0gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIG1hcC5zZXRNaW5ab29tKDEyLjI1KTtcbiAgICAgKi9cbiAgICBzZXRNaW5ab29tKG1pblpvb20/OiA/bnVtYmVyKTogdGhpcyB7XG5cbiAgICAgICAgbWluWm9vbSA9IG1pblpvb20gPT09IG51bGwgfHwgbWluWm9vbSA9PT0gdW5kZWZpbmVkID8gZGVmYXVsdE1pblpvb20gOiBtaW5ab29tO1xuXG4gICAgICAgIGlmIChtaW5ab29tID49IGRlZmF1bHRNaW5ab29tICYmIG1pblpvb20gPD0gdGhpcy50cmFuc2Zvcm0ubWF4Wm9vbSkge1xuICAgICAgICAgICAgdGhpcy50cmFuc2Zvcm0ubWluWm9vbSA9IG1pblpvb207XG4gICAgICAgICAgICB0aGlzLl91cGRhdGUoKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuZ2V0Wm9vbSgpIDwgbWluWm9vbSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0Wm9vbShtaW5ab29tKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgnem9vbXN0YXJ0JykpXG4gICAgICAgICAgICAgICAgICAgIC5maXJlKG5ldyBFdmVudCgnem9vbScpKVxuICAgICAgICAgICAgICAgICAgICAuZmlyZShuZXcgRXZlbnQoJ3pvb21lbmQnKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAgIH0gZWxzZSB0aHJvdyBuZXcgRXJyb3IoYG1pblpvb20gbXVzdCBiZSBiZXR3ZWVuICR7ZGVmYXVsdE1pblpvb219IGFuZCB0aGUgY3VycmVudCBtYXhab29tLCBpbmNsdXNpdmVgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBtYXAncyBtaW5pbXVtIGFsbG93YWJsZSB6b29tIGxldmVsLlxuICAgICAqXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyBgbWluWm9vbWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBtaW5ab29tID0gbWFwLmdldE1pblpvb20oKTtcbiAgICAgKi9cbiAgICBnZXRNaW5ab29tKCk6IG51bWJlciB7IHJldHVybiB0aGlzLnRyYW5zZm9ybS5taW5ab29tOyB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIG9yIGNsZWFycyB0aGUgbWFwJ3MgbWF4aW11bSB6b29tIGxldmVsLlxuICAgICAqIElmIHRoZSBtYXAncyBjdXJyZW50IHpvb20gbGV2ZWwgaXMgaGlnaGVyIHRoYW4gdGhlIG5ldyBtYXhpbXVtLFxuICAgICAqIHRoZSBtYXAgd2lsbCB6b29tIHRvIHRoZSBuZXcgbWF4aW11bS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7bnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZH0gbWF4Wm9vbSBUaGUgbWF4aW11bSB6b29tIGxldmVsIHRvIHNldC5cbiAgICAgKiAgIElmIGBudWxsYCBvciBgdW5kZWZpbmVkYCBpcyBwcm92aWRlZCwgdGhlIGZ1bmN0aW9uIHJlbW92ZXMgdGhlIGN1cnJlbnQgbWF4aW11bSB6b29tIChzZXRzIGl0IHRvIDIyKS5cbiAgICAgKiBAcmV0dXJucyB7TWFwfSBSZXR1cm5zIGl0c2VsZiB0byBhbGxvdyBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogbWFwLnNldE1heFpvb20oMTguNzUpO1xuICAgICAqL1xuICAgIHNldE1heFpvb20obWF4Wm9vbT86ID9udW1iZXIpOiB0aGlzIHtcblxuICAgICAgICBtYXhab29tID0gbWF4Wm9vbSA9PT0gbnVsbCB8fCBtYXhab29tID09PSB1bmRlZmluZWQgPyBkZWZhdWx0TWF4Wm9vbSA6IG1heFpvb207XG5cbiAgICAgICAgaWYgKG1heFpvb20gPj0gdGhpcy50cmFuc2Zvcm0ubWluWm9vbSkge1xuICAgICAgICAgICAgdGhpcy50cmFuc2Zvcm0ubWF4Wm9vbSA9IG1heFpvb207XG4gICAgICAgICAgICB0aGlzLl91cGRhdGUoKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuZ2V0Wm9vbSgpID4gbWF4Wm9vbSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0Wm9vbShtYXhab29tKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgnem9vbXN0YXJ0JykpXG4gICAgICAgICAgICAgICAgICAgIC5maXJlKG5ldyBFdmVudCgnem9vbScpKVxuICAgICAgICAgICAgICAgICAgICAuZmlyZShuZXcgRXZlbnQoJ3pvb21lbmQnKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAgIH0gZWxzZSB0aHJvdyBuZXcgRXJyb3IoYG1heFpvb20gbXVzdCBiZSBncmVhdGVyIHRoYW4gdGhlIGN1cnJlbnQgbWluWm9vbWApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIG1hcCdzIG1heGltdW0gYWxsb3dhYmxlIHpvb20gbGV2ZWwuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIGBtYXhab29tYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG1heFpvb20gPSBtYXAuZ2V0TWF4Wm9vbSgpO1xuICAgICAqL1xuICAgIGdldE1heFpvb20oKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMudHJhbnNmb3JtLm1heFpvb207IH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgb3IgY2xlYXJzIHRoZSBtYXAncyBtaW5pbXVtIHBpdGNoLlxuICAgICAqIElmIHRoZSBtYXAncyBjdXJyZW50IHBpdGNoIGlzIGxvd2VyIHRoYW4gdGhlIG5ldyBtaW5pbXVtLFxuICAgICAqIHRoZSBtYXAgd2lsbCBwaXRjaCB0byB0aGUgbmV3IG1pbmltdW0uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge251bWJlciB8IG51bGwgfCB1bmRlZmluZWR9IG1pblBpdGNoIFRoZSBtaW5pbXVtIHBpdGNoIHRvIHNldCAoMC04NSkuIElmIGBudWxsYCBvciBgdW5kZWZpbmVkYCBpcyBwcm92aWRlZCwgdGhlIGZ1bmN0aW9uIHJlbW92ZXMgdGhlIGN1cnJlbnQgbWluaW11bSBwaXRjaCBhbmQgcmVzZXRzIGl0IHRvIDAuXG4gICAgICogQHJldHVybnMge01hcH0gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIG1hcC5zZXRNaW5QaXRjaCg1KTtcbiAgICAgKi9cbiAgICBzZXRNaW5QaXRjaChtaW5QaXRjaD86ID9udW1iZXIpOiB0aGlzIHtcblxuICAgICAgICBtaW5QaXRjaCA9IG1pblBpdGNoID09PSBudWxsIHx8IG1pblBpdGNoID09PSB1bmRlZmluZWQgPyBkZWZhdWx0TWluUGl0Y2ggOiBtaW5QaXRjaDtcblxuICAgICAgICBpZiAobWluUGl0Y2ggPCBkZWZhdWx0TWluUGl0Y2gpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgbWluUGl0Y2ggbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJHtkZWZhdWx0TWluUGl0Y2h9YCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobWluUGl0Y2ggPj0gZGVmYXVsdE1pblBpdGNoICYmIG1pblBpdGNoIDw9IHRoaXMudHJhbnNmb3JtLm1heFBpdGNoKSB7XG4gICAgICAgICAgICB0aGlzLnRyYW5zZm9ybS5taW5QaXRjaCA9IG1pblBpdGNoO1xuICAgICAgICAgICAgdGhpcy5fdXBkYXRlKCk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmdldFBpdGNoKCkgPCBtaW5QaXRjaCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0UGl0Y2gobWluUGl0Y2gpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpcmUobmV3IEV2ZW50KCdwaXRjaHN0YXJ0JykpXG4gICAgICAgICAgICAgICAgICAgIC5maXJlKG5ldyBFdmVudCgncGl0Y2gnKSlcbiAgICAgICAgICAgICAgICAgICAgLmZpcmUobmV3IEV2ZW50KCdwaXRjaGVuZCcpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgICAgfSBlbHNlIHRocm93IG5ldyBFcnJvcihgbWluUGl0Y2ggbXVzdCBiZSBiZXR3ZWVuICR7ZGVmYXVsdE1pblBpdGNofSBhbmQgdGhlIGN1cnJlbnQgbWF4UGl0Y2gsIGluY2x1c2l2ZWApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIG1hcCdzIG1pbmltdW0gYWxsb3dhYmxlIHBpdGNoLlxuICAgICAqXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyBgbWluUGl0Y2hgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgbWluUGl0Y2ggPSBtYXAuZ2V0TWluUGl0Y2goKTtcbiAgICAgKi9cbiAgICBnZXRNaW5QaXRjaCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy50cmFuc2Zvcm0ubWluUGl0Y2g7IH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgb3IgY2xlYXJzIHRoZSBtYXAncyBtYXhpbXVtIHBpdGNoLlxuICAgICAqIElmIHRoZSBtYXAncyBjdXJyZW50IHBpdGNoIGlzIGhpZ2hlciB0aGFuIHRoZSBuZXcgbWF4aW11bSxcbiAgICAgKiB0aGUgbWFwIHdpbGwgcGl0Y2ggdG8gdGhlIG5ldyBtYXhpbXVtLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtudW1iZXIgfCBudWxsIHwgdW5kZWZpbmVkfSBtYXhQaXRjaCBUaGUgbWF4aW11bSBwaXRjaCB0byBzZXQuXG4gICAgICogICBJZiBgbnVsbGAgb3IgYHVuZGVmaW5lZGAgaXMgcHJvdmlkZWQsIHRoZSBmdW5jdGlvbiByZW1vdmVzIHRoZSBjdXJyZW50IG1heGltdW0gcGl0Y2ggKHNldHMgaXQgdG8gODUpLlxuICAgICAqIEByZXR1cm5zIHtNYXB9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAuc2V0TWF4UGl0Y2goNzApO1xuICAgICAqL1xuICAgIHNldE1heFBpdGNoKG1heFBpdGNoPzogP251bWJlcik6IHRoaXMge1xuXG4gICAgICAgIG1heFBpdGNoID0gbWF4UGl0Y2ggPT09IG51bGwgfHwgbWF4UGl0Y2ggPT09IHVuZGVmaW5lZCA/IGRlZmF1bHRNYXhQaXRjaCA6IG1heFBpdGNoO1xuXG4gICAgICAgIGlmIChtYXhQaXRjaCA+IGRlZmF1bHRNYXhQaXRjaCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBtYXhQaXRjaCBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAke2RlZmF1bHRNYXhQaXRjaH1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChtYXhQaXRjaCA+PSB0aGlzLnRyYW5zZm9ybS5taW5QaXRjaCkge1xuICAgICAgICAgICAgdGhpcy50cmFuc2Zvcm0ubWF4UGl0Y2ggPSBtYXhQaXRjaDtcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZSgpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5nZXRQaXRjaCgpID4gbWF4UGl0Y2gpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFBpdGNoKG1heFBpdGNoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgncGl0Y2hzdGFydCcpKVxuICAgICAgICAgICAgICAgICAgICAuZmlyZShuZXcgRXZlbnQoJ3BpdGNoJykpXG4gICAgICAgICAgICAgICAgICAgIC5maXJlKG5ldyBFdmVudCgncGl0Y2hlbmQnKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAgIH0gZWxzZSB0aHJvdyBuZXcgRXJyb3IoYG1heFBpdGNoIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIG1pblBpdGNoYCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgbWFwJ3MgbWF4aW11bSBhbGxvd2FibGUgcGl0Y2guXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIGBtYXhQaXRjaGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBtYXhQaXRjaCA9IG1hcC5nZXRNYXhQaXRjaCgpO1xuICAgICAqL1xuICAgIGdldE1heFBpdGNoKCk6IG51bWJlciB7IHJldHVybiB0aGlzLnRyYW5zZm9ybS5tYXhQaXRjaDsgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgc3RhdGUgb2YgYHJlbmRlcldvcmxkQ29waWVzYC4gSWYgYHRydWVgLCBtdWx0aXBsZSBjb3BpZXMgb2YgdGhlIHdvcmxkIHdpbGwgYmUgcmVuZGVyZWQgc2lkZSBieSBzaWRlIGJleW9uZCAtMTgwIGFuZCAxODAgZGVncmVlcyBsb25naXR1ZGUuIElmIHNldCB0byBgZmFsc2VgOlxuICAgICAqIC0gV2hlbiB0aGUgbWFwIGlzIHpvb21lZCBvdXQgZmFyIGVub3VnaCB0aGF0IGEgc2luZ2xlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB3b3JsZCBkb2VzIG5vdCBmaWxsIHRoZSBtYXAncyBlbnRpcmVcbiAgICAgKiBjb250YWluZXIsIHRoZXJlIHdpbGwgYmUgYmxhbmsgc3BhY2UgYmV5b25kIDE4MCBhbmQgLTE4MCBkZWdyZWVzIGxvbmdpdHVkZS5cbiAgICAgKiAtIEZlYXR1cmVzIHRoYXQgY3Jvc3MgMTgwIGFuZCAtMTgwIGRlZ3JlZXMgbG9uZ2l0dWRlIHdpbGwgYmUgY3V0IGluIHR3byAod2l0aCBvbmUgcG9ydGlvbiBvbiB0aGUgcmlnaHQgZWRnZSBvZiB0aGVcbiAgICAgKiBtYXAgYW5kIHRoZSBvdGhlciBvbiB0aGUgbGVmdCBlZGdlIG9mIHRoZSBtYXApIGF0IGV2ZXJ5IHpvb20gbGV2ZWwuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgcmVuZGVyV29ybGRDb3BpZXNgIGJvb2xlYW4uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCB3b3JsZENvcGllc1JlbmRlcmVkID0gbWFwLmdldFJlbmRlcldvcmxkQ29waWVzKCk7XG4gICAgICogQHNlZSBbRXhhbXBsZTogUmVuZGVyIHdvcmxkIGNvcGllc10oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvcmVuZGVyLXdvcmxkLWNvcGllcy8pXG4gICAgICovXG4gICAgZ2V0UmVuZGVyV29ybGRDb3BpZXMoKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLnRyYW5zZm9ybS5yZW5kZXJXb3JsZENvcGllczsgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgc3RhdGUgb2YgYHJlbmRlcldvcmxkQ29waWVzYC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gcmVuZGVyV29ybGRDb3BpZXMgSWYgYHRydWVgLCBtdWx0aXBsZSBjb3BpZXMgb2YgdGhlIHdvcmxkIHdpbGwgYmUgcmVuZGVyZWQgc2lkZSBieSBzaWRlIGJleW9uZCAtMTgwIGFuZCAxODAgZGVncmVlcyBsb25naXR1ZGUuIElmIHNldCB0byBgZmFsc2VgOlxuICAgICAqIC0gV2hlbiB0aGUgbWFwIGlzIHpvb21lZCBvdXQgZmFyIGVub3VnaCB0aGF0IGEgc2luZ2xlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB3b3JsZCBkb2VzIG5vdCBmaWxsIHRoZSBtYXAncyBlbnRpcmVcbiAgICAgKiBjb250YWluZXIsIHRoZXJlIHdpbGwgYmUgYmxhbmsgc3BhY2UgYmV5b25kIDE4MCBhbmQgLTE4MCBkZWdyZWVzIGxvbmdpdHVkZS5cbiAgICAgKiAtIEZlYXR1cmVzIHRoYXQgY3Jvc3MgMTgwIGFuZCAtMTgwIGRlZ3JlZXMgbG9uZ2l0dWRlIHdpbGwgYmUgY3V0IGluIHR3byAod2l0aCBvbmUgcG9ydGlvbiBvbiB0aGUgcmlnaHQgZWRnZSBvZiB0aGVcbiAgICAgKiBtYXAgYW5kIHRoZSBvdGhlciBvbiB0aGUgbGVmdCBlZGdlIG9mIHRoZSBtYXApIGF0IGV2ZXJ5IHpvb20gbGV2ZWwuXG4gICAgICpcbiAgICAgKiBgdW5kZWZpbmVkYCBpcyB0cmVhdGVkIGFzIGB0cnVlYCwgYG51bGxgIGlzIHRyZWF0ZWQgYXMgYGZhbHNlYC5cbiAgICAgKiBAcmV0dXJucyB7TWFwfSBSZXR1cm5zIGl0c2VsZiB0byBhbGxvdyBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogbWFwLnNldFJlbmRlcldvcmxkQ29waWVzKHRydWUpO1xuICAgICAqIEBzZWUgW0V4YW1wbGU6IFJlbmRlciB3b3JsZCBjb3BpZXNdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL3JlbmRlci13b3JsZC1jb3BpZXMvKVxuICAgICAqL1xuICAgIHNldFJlbmRlcldvcmxkQ29waWVzKHJlbmRlcldvcmxkQ29waWVzPzogP2Jvb2xlYW4pOiB0aGlzIHtcbiAgICAgICAgdGhpcy50cmFuc2Zvcm0ucmVuZGVyV29ybGRDb3BpZXMgPSByZW5kZXJXb3JsZENvcGllcztcbiAgICAgICAgaWYgKCF0aGlzLnRyYW5zZm9ybS5yZW5kZXJXb3JsZENvcGllcykge1xuICAgICAgICAgICAgdGhpcy5fZm9yY2VNYXJrZXJBbmRQb3B1cFVwZGF0ZSh0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fdXBkYXRlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgbWFwJ3MgbGFuZ3VhZ2UsIHdoaWNoIGlzIHVzZWQgZm9yIHRyYW5zbGF0aW5nIG1hcCBsYWJlbHMgYW5kIFVJIGNvbXBvbmVudHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEByZXR1cm5zIHt1bmRlZmluZWQgfCBzdHJpbmcgfCBzdHJpbmdbXX0gUmV0dXJucyB0aGUgbWFwJ3MgbGFuZ3VhZ2UgY29kZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGxhbmd1YWdlID0gbWFwLmdldExhbmd1YWdlKCk7XG4gICAgICovXG4gICAgZ2V0TGFuZ3VhZ2UoKTogP3N0cmluZyB8ID9zdHJpbmdbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sYW5ndWFnZTtcbiAgICB9XG5cbiAgICBfcGFyc2VMYW5ndWFnZShsYW5ndWFnZT86ICdhdXRvJyB8ID9zdHJpbmcgfCA/c3RyaW5nW10pOiA/c3RyaW5nIHwgP3N0cmluZ1tdIHtcbiAgICAgICAgaWYgKGxhbmd1YWdlID09PSAnYXV0bycpIHJldHVybiB3aW5kb3cubmF2aWdhdG9yLmxhbmd1YWdlO1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShsYW5ndWFnZSkpIHJldHVybiBsYW5ndWFnZS5sZW5ndGggPT09IDAgP1xuICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgIGxhbmd1YWdlLm1hcChsID0+IGwgPT09ICdhdXRvJyA/IHdpbmRvdy5uYXZpZ2F0b3IubGFuZ3VhZ2UgOiBsKTtcblxuICAgICAgICByZXR1cm4gbGFuZ3VhZ2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgbWFwJ3MgbGFuZ3VhZ2UsIHdoaWNoIGlzIHVzZWQgZm9yIHRyYW5zbGF0aW5nIG1hcCBsYWJlbHMgYW5kIFVJIGNvbXBvbmVudHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7J2F1dG8nIHwgc3RyaW5nIHwgc3RyaW5nW119IFtsYW5ndWFnZV0gQSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBkZXNpcmVkIGxhbmd1YWdlIHVzZWQgZm9yIHRoZSBtYXAncyBsYWJlbHMgYW5kIFVJIGNvbXBvbmVudHMuIExhbmd1YWdlcyBjYW4gb25seSBiZSBzZXQgb24gTWFwYm94IHZlY3RvciB0aWxlIHNvdXJjZXMuXG4gICAgICogIFZhbGlkIGxhbmd1YWdlIHN0cmluZ3MgbXVzdCBiZSBhIFtCQ1AtNDcgbGFuZ3VhZ2UgY29kZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSUVURl9sYW5ndWFnZV90YWcjTGlzdF9vZl9zdWJ0YWdzKS4gVW5zdXBwb3J0ZWQgQkNQLTQ3IGNvZGVzIHdpbGwgbm90IGluY2x1ZGUgYW55IHRyYW5zbGF0aW9ucy4gSW52YWxpZCBjb2RlcyB3aWxsIHJlc3VsdCBpbiBhbiByZWNvdmVyYWJsZSBlcnJvci5cbiAgICAgKiAgSWYgYSBsYWJlbCBoYXMgbm8gdHJhbnNsYXRpb24gZm9yIHRoZSBzZWxlY3RlZCBsYW5ndWFnZSwgaXQgd2lsbCBkaXNwbGF5IGluIHRoZSBsYWJlbCdzIGxvY2FsIGxhbmd1YWdlLlxuICAgICAqICBJZiBwYXJhbSBpcyBzZXQgdG8gYGF1dG9gLCBHTCBKUyB3aWxsIHNlbGVjdCBhIHVzZXIncyBwcmVmZXJyZWQgbGFuZ3VhZ2UgYXMgZGV0ZXJtaW5lZCBieSB0aGUgYnJvd3NlcidzIFtgd2luZG93Lm5hdmlnYXRvci5sYW5ndWFnZWBdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9OYXZpZ2F0b3IvbGFuZ3VhZ2UpIHByb3BlcnR5LlxuICAgICAqICBJZiB0aGUgYGxvY2FsZWAgcHJvcGVydHkgaXMgbm90IHNldCBzZXBhcmF0ZWx5LCB0aGlzIGxhbmd1YWdlIHdpbGwgYWxzbyBiZSB1c2VkIHRvIGxvY2FsaXplIHRoZSBVSSBmb3Igc3VwcG9ydGVkIGxhbmd1YWdlcy5cbiAgICAgKiAgSWYgcGFyYW0gaXMgc2V0IHRvIGB1bmRlZmluZWRgIG9yIGBudWxsYCwgaXQgd2lsbCByZW1vdmUgdGhlIGN1cnJlbnQgbWFwIGxhbmd1YWdlIGFuZCByZXNldCB0aGUgbGFuZ3VhZ2UgdXNlZCBmb3IgdHJhbnNsYXRpbmcgbWFwIGxhYmVscyBhbmQgVUkgY29tcG9uZW50cy5cbiAgICAgKiBAcmV0dXJucyB7TWFwfSBSZXR1cm5zIGl0c2VsZiB0byBhbGxvdyBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogbWFwLnNldExhbmd1YWdlKCdlcycpO1xuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAuc2V0TGFuZ3VhZ2UoWydlbi1HQicsICdlbi1VUyddKTtcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogbWFwLnNldExhbmd1YWdlKCdhdXRvJyk7XG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIG1hcC5zZXRMYW5ndWFnZSgpO1xuICAgICAqL1xuICAgIHNldExhbmd1YWdlKGxhbmd1YWdlPzogJ2F1dG8nIHwgP3N0cmluZyB8ID9zdHJpbmdbXSk6IHRoaXMge1xuICAgICAgICBjb25zdCBuZXdMYW5ndWFnZSA9IHRoaXMuX3BhcnNlTGFuZ3VhZ2UobGFuZ3VhZ2UpO1xuICAgICAgICBpZiAoIXRoaXMuc3R5bGUgfHwgbmV3TGFuZ3VhZ2UgPT09IHRoaXMuX2xhbmd1YWdlKSByZXR1cm4gdGhpcztcbiAgICAgICAgdGhpcy5fbGFuZ3VhZ2UgPSBuZXdMYW5ndWFnZTtcblxuICAgICAgICB0aGlzLnN0eWxlLl9yZWxvYWRTb3VyY2VzKCk7XG5cbiAgICAgICAgZm9yIChjb25zdCBjb250cm9sIG9mIHRoaXMuX2NvbnRyb2xzKSB7XG4gICAgICAgICAgICBpZiAoY29udHJvbC5fc2V0TGFuZ3VhZ2UpIHtcbiAgICAgICAgICAgICAgICBjb250cm9sLl9zZXRMYW5ndWFnZSh0aGlzLl9sYW5ndWFnZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBjb2RlIGZvciB0aGUgbWFwJ3Mgd29ybGR2aWV3LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBtYXAncyB3b3JsZHZpZXcgY29kZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHdvcmxkdmlldyA9IG1hcC5nZXRXb3JsZHZpZXcoKTtcbiAgICAgKi9cbiAgICBnZXRXb3JsZHZpZXcoKTogP3N0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLl93b3JsZHZpZXc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgbWFwJ3Mgd29ybGR2aWV3LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3dvcmxkdmlld10gQSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBkZXNpcmVkIHdvcmxkdmlldy5cbiAgICAgKiAgQSB3b3JsZHZpZXcgZGV0ZXJtaW5lcyB0aGUgd2F5IHRoYXQgY2VydGFpbiBkaXNwdXRlZCBib3VuZGFyaWVzIGFyZSByZW5kZXJlZC5cbiAgICAgKiAgVmFsaWQgd29ybGR2aWV3IHN0cmluZ3MgbXVzdCBiZSBhbiBbSVNPIGFscGhhLTIgY291bnRyeSBjb2RlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fMzE2Ni0xI0N1cnJlbnRfY29kZXMpLlxuICAgICAqICBVbnN1cHBvcnRlZCBJU08gYWxwaGEtMiBjb2RlcyB3aWxsIGZhbGwgYmFjayB0byB0aGUgVGlsZUpTT04ncyBkZWZhdWx0IHdvcmxkdmlldy4gSW52YWxpZCBjb2RlcyB3aWxsIHJlc3VsdCBpbiBhIHJlY292ZXJhYmxlIGVycm9yLlxuICAgICAqICBJZiBwYXJhbSBpcyBzZXQgdG8gYHVuZGVmaW5lZGAgb3IgYG51bGxgLCBpdCB3aWxsIGNhdXNlIHRoZSBtYXAgdG8gZmFsbCBiYWNrIHRvIHRoZSBUaWxlSlNPTidzIGRlZmF1bHQgd29ybGR2aWV3LlxuICAgICAqIEByZXR1cm5zIHtNYXB9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAuc2V0V29ybGRWaWV3KCdKUCcpO1xuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAuc2V0V29ybGRWaWV3KCk7XG4gICAgICovXG4gICAgc2V0V29ybGR2aWV3KHdvcmxkdmlldz86ID9zdHJpbmcpOiB0aGlzIHtcbiAgICAgICAgaWYgKCF0aGlzLnN0eWxlIHx8IHdvcmxkdmlldyA9PT0gdGhpcy5fd29ybGR2aWV3KSByZXR1cm4gdGhpcztcblxuICAgICAgICB0aGlzLl93b3JsZHZpZXcgPSB3b3JsZHZpZXc7XG4gICAgICAgIHRoaXMuc3R5bGUuX3JlbG9hZFNvdXJjZXMoKTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKiogQHNlY3Rpb24ge1BvaW50IGNvbnZlcnNpb259ICovXG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgW3Byb2plY3Rpb25dKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9zdHlsZS1zcGVjL3Byb2plY3Rpb24vKSBvYmplY3QgdGhhdCBkZWZpbmVzIHRoZSBjdXJyZW50IG1hcCBwcm9qZWN0aW9uLlxuICAgICAqXG4gICAgICogQHJldHVybnMge1Byb2plY3Rpb25TcGVjaWZpY2F0aW9ufSBUaGUgW3Byb2plY3Rpb25dKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9zdHlsZS1zcGVjL3Byb2plY3Rpb24vKSBkZWZpbmluZyB0aGUgY3VycmVudCBtYXAgcHJvamVjdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHByb2plY3Rpb24gPSBtYXAuZ2V0UHJvamVjdGlvbigpO1xuICAgICAqL1xuICAgIGdldFByb2plY3Rpb24oKTogUHJvamVjdGlvblNwZWNpZmljYXRpb24ge1xuICAgICAgICBpZiAodGhpcy50cmFuc2Zvcm0ubWVyY2F0b3JGcm9tVHJhbnNpdGlvbikge1xuICAgICAgICAgICAgcmV0dXJuIHtuYW1lOiBcImdsb2JlXCIsIGNlbnRlcjogWzAsIDBdfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm0uZ2V0UHJvamVjdGlvbigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdHJ1ZSBpZiBtYXAgW3Byb2plY3Rpb25dKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9zdHlsZS1zcGVjL3Byb2plY3Rpb24vKSBoYXMgYmVlbiBzZXQgdG8gZ2xvYmUgQU5EIHRoZSBtYXAgaXMgYXQgYSBsb3cgZW5vdWdoIHpvb20gbGV2ZWwgdGhhdCBnbG9iZSB2aWV3IGlzIGVuYWJsZWQuXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgZ2xvYmUtaXMtYWN0aXZlYCBib29sZWFuLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogaWYgKG1hcC5fc2hvd2luZ0dsb2JlKCkpIHtcbiAgICAgKiAgICAgLy8gZG8gZ2xvYmUgdGhpbmdzIGhlcmVcbiAgICAgKiB9XG4gICAgICovXG4gICAgX3Nob3dpbmdHbG9iZSgpOiBib29sZWFuIHsgcmV0dXJuIHRoaXMudHJhbnNmb3JtLnByb2plY3Rpb24ubmFtZSA9PT0gJ2dsb2JlJzsgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgbWFwJ3MgcHJvamVjdGlvbi4gSWYgY2FsbGVkIHdpdGggYG51bGxgIG9yIGB1bmRlZmluZWRgLCB0aGUgbWFwIHdpbGwgcmVzZXQgdG8gTWVyY2F0b3IuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1Byb2plY3Rpb25TcGVjaWZpY2F0aW9uIHwgc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZH0gcHJvamVjdGlvbiBUaGUgcHJvamVjdGlvbiB0aGF0IHRoZSBtYXAgc2hvdWxkIGJlIHJlbmRlcmVkIGluLlxuICAgICAqIFRoaXMgY2FuIGJlIGEgW3Byb2plY3Rpb25dKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9zdHlsZS1zcGVjL3Byb2plY3Rpb24vKSBvYmplY3Qgb3IgYSBzdHJpbmcgb2YgdGhlIHByb2plY3Rpb24ncyBuYW1lLlxuICAgICAqIEByZXR1cm5zIHtNYXB9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAuc2V0UHJvamVjdGlvbignYWxiZXJzJyk7XG4gICAgICogbWFwLnNldFByb2plY3Rpb24oe1xuICAgICAqICAgICBuYW1lOiAnYWxiZXJzJyxcbiAgICAgKiAgICAgY2VudGVyOiBbMzUsIDU1XSxcbiAgICAgKiAgICAgcGFyYWxsZWxzOiBbMjAsIDYwXVxuICAgICAqIH0pO1xuICAgICAqIEBzZWUgW0V4YW1wbGU6IERpc3BsYXkgYSB3ZWIgbWFwIHVzaW5nIGFuIGFsdGVybmF0ZSBwcm9qZWN0aW9uXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9tYXAtcHJvamVjdGlvbi8pXG4gICAgICogQHNlZSBbRXhhbXBsZTogVXNlIGRpZmZlcmVudCBtYXAgcHJvamVjdGlvbnMgZm9yIHdlYiBtYXBzXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9wcm9qZWN0aW9ucy8pXG4gICAgICovXG4gICAgc2V0UHJvamVjdGlvbihwcm9qZWN0aW9uPzogP1Byb2plY3Rpb25TcGVjaWZpY2F0aW9uIHwgc3RyaW5nKTogdGhpcyB7XG4gICAgICAgIHRoaXMuX2xhenlJbml0RW1wdHlTdHlsZSgpO1xuXG4gICAgICAgIGlmICghcHJvamVjdGlvbikge1xuICAgICAgICAgICAgcHJvamVjdGlvbiA9IG51bGw7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHByb2plY3Rpb24gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBwcm9qZWN0aW9uID0gKCh7bmFtZTogcHJvamVjdGlvbn06IGFueSk6IFByb2plY3Rpb25TcGVjaWZpY2F0aW9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3VzZUV4cGxpY2l0UHJvamVjdGlvbiA9ICEhcHJvamVjdGlvbjtcbiAgICAgICAgY29uc3Qgc3R5bGVzaGVldFByb2plY3Rpb24gPSB0aGlzLnN0eWxlLnN0eWxlc2hlZXQgPyB0aGlzLnN0eWxlLnN0eWxlc2hlZXQucHJvamVjdGlvbiA6IG51bGw7XG4gICAgICAgIHJldHVybiB0aGlzLl9wcmlvcml0aXplQW5kVXBkYXRlUHJvamVjdGlvbihwcm9qZWN0aW9uLCBzdHlsZXNoZWV0UHJvamVjdGlvbik7XG4gICAgfVxuXG4gICAgX3VwZGF0ZVByb2plY3Rpb25UcmFuc2l0aW9uKCkge1xuICAgICAgICAvLyBUaGUgcHJvamVjdGlvbiBpc24ndCBnbG9iZSwgd2UgY2FuIHNraXAgdXBkYXRpbmcgdGhlIHRyYW5zaXRpb25cbiAgICAgICAgaWYgKHRoaXMuZ2V0UHJvamVjdGlvbigpLm5hbWUgIT09ICdnbG9iZScpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRyID0gdGhpcy50cmFuc2Zvcm07XG4gICAgICAgIGNvbnN0IHByb2plY3Rpb24gPSB0ci5wcm9qZWN0aW9uLm5hbWU7XG4gICAgICAgIGxldCBwcm9qZWN0aW9uSGFzQ2hhbmdlZDtcblxuICAgICAgICBpZiAocHJvamVjdGlvbiA9PT0gJ2dsb2JlJyAmJiB0ci56b29tID49IEdMT0JFX1pPT01fVEhSRVNIT0xEX01BWCkge1xuICAgICAgICAgICAgdHIuc2V0TWVyY2F0b3JGcm9tVHJhbnNpdGlvbigpO1xuICAgICAgICAgICAgcHJvamVjdGlvbkhhc0NoYW5nZWQgPSB0cnVlO1xuICAgICAgICB9IGVsc2UgaWYgKHByb2plY3Rpb24gPT09ICdtZXJjYXRvcicgJiYgdHIuem9vbSA8IEdMT0JFX1pPT01fVEhSRVNIT0xEX01BWCkge1xuICAgICAgICAgICAgdHIuc2V0UHJvamVjdGlvbih7bmFtZTogJ2dsb2JlJ30pO1xuICAgICAgICAgICAgcHJvamVjdGlvbkhhc0NoYW5nZWQgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHByb2plY3Rpb25IYXNDaGFuZ2VkKSB7XG4gICAgICAgICAgICB0aGlzLnN0eWxlLmFwcGx5UHJvamVjdGlvblVwZGF0ZSgpO1xuICAgICAgICAgICAgdGhpcy5zdHlsZS5fZm9yY2VTeW1ib2xMYXllclVwZGF0ZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX3ByaW9yaXRpemVBbmRVcGRhdGVQcm9qZWN0aW9uKGV4cGxpY2l0UHJvamVjdGlvbjogP1Byb2plY3Rpb25TcGVjaWZpY2F0aW9uLCBzdHlsZVByb2plY3Rpb246ID9Qcm9qZWN0aW9uU3BlY2lmaWNhdGlvbik6IHRoaXMge1xuICAgICAgICAvLyBHaXZlbiBhIHN0eWxlc2hlZXQgYW5kIGV2ZW50dWFsIHJ1bnRpbWUgcHJvamVjdGlvbiwgaW4gb3JkZXIgb2YgcHJpb3JpdHksIHdlIHNlbGVjdDpcbiAgICAgICAgLy8gIDEuIHRoZSBleHBsaWNpdCBwcm9qZWN0aW9uXG4gICAgICAgIC8vICAyLiB0aGUgc3R5bGVzaGVldCBwcm9qZWN0aW9uXG4gICAgICAgIC8vICAzLiBtZXJjYXRvciAoZmFsbGJhY2spXG4gICAgICAgIGNvbnN0IHByaW9yaXRpemVkUHJvamVjdGlvbiA9IGV4cGxpY2l0UHJvamVjdGlvbiB8fCBzdHlsZVByb2plY3Rpb24gfHwge25hbWU6IFwibWVyY2F0b3JcIn07XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX3VwZGF0ZVByb2plY3Rpb24ocHJpb3JpdGl6ZWRQcm9qZWN0aW9uKTtcbiAgICB9XG5cbiAgICBfdXBkYXRlUHJvamVjdGlvbihwcm9qZWN0aW9uOiBQcm9qZWN0aW9uU3BlY2lmaWNhdGlvbik6IHRoaXMge1xuICAgICAgICBsZXQgcHJvamVjdGlvbkhhc0NoYW5nZWQ7XG5cbiAgICAgICAgaWYgKHByb2plY3Rpb24ubmFtZSA9PT0gJ2dsb2JlJyAmJiB0aGlzLnRyYW5zZm9ybS56b29tID49IEdMT0JFX1pPT01fVEhSRVNIT0xEX01BWCkge1xuICAgICAgICAgICAgcHJvamVjdGlvbkhhc0NoYW5nZWQgPSB0aGlzLnRyYW5zZm9ybS5zZXRNZXJjYXRvckZyb21UcmFuc2l0aW9uKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwcm9qZWN0aW9uSGFzQ2hhbmdlZCA9IHRoaXMudHJhbnNmb3JtLnNldFByb2plY3Rpb24ocHJvamVjdGlvbik7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnN0eWxlLmFwcGx5UHJvamVjdGlvblVwZGF0ZSgpO1xuXG4gICAgICAgIGlmIChwcm9qZWN0aW9uSGFzQ2hhbmdlZCkge1xuICAgICAgICAgICAgdGhpcy5wYWludGVyLmNsZWFyQmFja2dyb3VuZFRpbGVzKCk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGlkIGluIHRoaXMuc3R5bGUuX3NvdXJjZUNhY2hlcykge1xuICAgICAgICAgICAgICAgIHRoaXMuc3R5bGUuX3NvdXJjZUNhY2hlc1tpZF0uY2xlYXJUaWxlcygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fdXBkYXRlKHRydWUpO1xuICAgICAgICAgICAgdGhpcy5fZm9yY2VNYXJrZXJBbmRQb3B1cFVwZGF0ZSh0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSB7QGxpbmsgUG9pbnR9IHJlcHJlc2VudGluZyBwaXhlbCBjb29yZGluYXRlcywgcmVsYXRpdmUgdG8gdGhlIG1hcCdzIGBjb250YWluZXJgLFxuICAgICAqIHRoYXQgY29ycmVzcG9uZCB0byB0aGUgc3BlY2lmaWVkIGdlb2dyYXBoaWNhbCBsb2NhdGlvbi5cbiAgICAgKlxuICAgICAqIFdoZW4gdGhlIG1hcCBpcyBwaXRjaGVkIGFuZCBgbG5nbGF0YCBpcyBjb21wbGV0ZWx5IGJlaGluZCB0aGUgY2FtZXJhLCB0aGVyZSBhcmUgbm8gcGl4ZWxcbiAgICAgKiBjb29yZGluYXRlcyBjb3JyZXNwb25kaW5nIHRvIHRoYXQgbG9jYXRpb24uIEluIHRoYXQgY2FzZSxcbiAgICAgKiB0aGUgYHhgIGFuZCBgeWAgY29tcG9uZW50cyBvZiB0aGUgcmV0dXJuZWQge0BsaW5rIFBvaW50fSBhcmUgc2V0IHRvIE51bWJlci5NQVhfVkFMVUUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0xuZ0xhdExpa2V9IGxuZ2xhdCBUaGUgZ2VvZ3JhcGhpY2FsIGxvY2F0aW9uIHRvIHByb2plY3QuXG4gICAgICogQHJldHVybnMge1BvaW50fSBUaGUge0BsaW5rIFBvaW50fSBjb3JyZXNwb25kaW5nIHRvIGBsbmdsYXRgLCByZWxhdGl2ZSB0byB0aGUgbWFwJ3MgYGNvbnRhaW5lcmAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBjb29yZGluYXRlID0gWy0xMjIuNDIwNjc5LCAzNy43NzI1MzddO1xuICAgICAqIGNvbnN0IHBvaW50ID0gbWFwLnByb2plY3QoY29vcmRpbmF0ZSk7XG4gICAgICovXG4gICAgcHJvamVjdChsbmdsYXQ6IExuZ0xhdExpa2UpOiBQb2ludCB7XG4gICAgICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybS5sb2NhdGlvblBvaW50M0QoTG5nTGF0LmNvbnZlcnQobG5nbGF0KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHtAbGluayBMbmdMYXR9IHJlcHJlc2VudGluZyBnZW9ncmFwaGljYWwgY29vcmRpbmF0ZXMgdGhhdCBjb3JyZXNwb25kXG4gICAgICogdG8gdGhlIHNwZWNpZmllZCBwaXhlbCBjb29yZGluYXRlcy4gSWYgaG9yaXpvbiBpcyB2aXNpYmxlLCBhbmQgc3BlY2lmaWVkIHBpeGVsIGlzXG4gICAgICogYWJvdmUgaG9yaXpvbiwgcmV0dXJucyBhIHtAbGluayBMbmdMYXR9IGNvcnJlc3BvbmRpbmcgdG8gcG9pbnQgb24gaG9yaXpvbiwgbmVhcmVzdFxuICAgICAqIHRvIHRoZSBwb2ludC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7UG9pbnRMaWtlfSBwb2ludCBUaGUgcGl4ZWwgY29vcmRpbmF0ZXMgdG8gdW5wcm9qZWN0LlxuICAgICAqIEByZXR1cm5zIHtMbmdMYXR9IFRoZSB7QGxpbmsgTG5nTGF0fSBjb3JyZXNwb25kaW5nIHRvIGBwb2ludGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAub24oJ2NsaWNrJywgKGUpID0+IHtcbiAgICAgKiAgICAgLy8gV2hlbiB0aGUgbWFwIGlzIGNsaWNrZWQsIGdldCB0aGUgZ2VvZ3JhcGhpYyBjb29yZGluYXRlLlxuICAgICAqICAgICBjb25zdCBjb29yZGluYXRlID0gbWFwLnVucHJvamVjdChlLnBvaW50KTtcbiAgICAgKiB9KTtcbiAgICAgKi9cbiAgICB1bnByb2plY3QocG9pbnQ6IFBvaW50TGlrZSk6IExuZ0xhdCB7XG4gICAgICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybS5wb2ludExvY2F0aW9uM0QoUG9pbnQuY29udmVydChwb2ludCkpO1xuICAgIH1cblxuICAgIC8qKiBAc2VjdGlvbiB7TW92ZW1lbnQgc3RhdGV9ICovXG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIG1hcCBpcyBwYW5uaW5nLCB6b29taW5nLCByb3RhdGluZywgb3IgcGl0Y2hpbmcgZHVlIHRvIGEgY2FtZXJhIGFuaW1hdGlvbiBvciB1c2VyIGdlc3R1cmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgbWFwIGlzIG1vdmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGlzTW92aW5nID0gbWFwLmlzTW92aW5nKCk7XG4gICAgICovXG4gICAgaXNNb3ZpbmcoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tb3ZpbmcgfHwgKHRoaXMuaGFuZGxlcnMgJiYgdGhpcy5oYW5kbGVycy5pc01vdmluZygpKSB8fCBmYWxzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIG1hcCBpcyB6b29taW5nIGR1ZSB0byBhIGNhbWVyYSBhbmltYXRpb24gb3IgdXNlciBnZXN0dXJlLlxuICAgICAqXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIG1hcCBpcyB6b29taW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgaXNab29taW5nID0gbWFwLmlzWm9vbWluZygpO1xuICAgICAqL1xuICAgIGlzWm9vbWluZygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3pvb21pbmcgfHwgKHRoaXMuaGFuZGxlcnMgJiYgdGhpcy5oYW5kbGVycy5pc1pvb21pbmcoKSkgfHwgZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBtYXAgaXMgcm90YXRpbmcgZHVlIHRvIGEgY2FtZXJhIGFuaW1hdGlvbiBvciB1c2VyIGdlc3R1cmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgbWFwIGlzIHJvdGF0aW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogbWFwLmlzUm90YXRpbmcoKTtcbiAgICAgKi9cbiAgICBpc1JvdGF0aW5nKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fcm90YXRpbmcgfHwgKHRoaXMuaGFuZGxlcnMgJiYgdGhpcy5oYW5kbGVycy5pc1JvdGF0aW5nKCkpIHx8IGZhbHNlO1xuICAgIH1cblxuICAgIF9pc0RyYWdnaW5nKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKHRoaXMuaGFuZGxlcnMgJiYgdGhpcy5oYW5kbGVycy5faXNEcmFnZ2luZygpKSB8fCBmYWxzZTtcbiAgICB9XG5cbiAgICBfY3JlYXRlRGVsZWdhdGVkTGlzdGVuZXIodHlwZTogTWFwRXZlbnQsIGxheWVyczogQXJyYXk8YW55PiwgbGlzdGVuZXI6IGFueSk6IGFueSB7XG4gICAgICAgIGlmICh0eXBlID09PSAnbW91c2VlbnRlcicgfHwgdHlwZSA9PT0gJ21vdXNlb3ZlcicpIHtcbiAgICAgICAgICAgIGxldCBtb3VzZWluID0gZmFsc2U7XG4gICAgICAgICAgICBjb25zdCBtb3VzZW1vdmUgPSAoZTogTWFwTW91c2VFdmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZpbHRlcmVkTGF5ZXJzID0gbGF5ZXJzLmZpbHRlcihsYXllcklkID0+IHRoaXMuZ2V0TGF5ZXIobGF5ZXJJZCkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGZlYXR1cmVzID0gZmlsdGVyZWRMYXllcnMubGVuZ3RoID8gdGhpcy5xdWVyeVJlbmRlcmVkRmVhdHVyZXMoZS5wb2ludCwge2xheWVyczogZmlsdGVyZWRMYXllcnN9KSA6IFtdO1xuICAgICAgICAgICAgICAgIGlmICghZmVhdHVyZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIG1vdXNlaW4gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFtb3VzZWluKSB7XG4gICAgICAgICAgICAgICAgICAgIG1vdXNlaW4gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lci5jYWxsKHRoaXMsIG5ldyBNYXBNb3VzZUV2ZW50KHR5cGUsIHRoaXMsIGUub3JpZ2luYWxFdmVudCwge2ZlYXR1cmVzfSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBtb3VzZW91dCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBtb3VzZWluID0gZmFsc2U7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICByZXR1cm4ge2xheWVyczogbmV3IFNldChsYXllcnMpLCBsaXN0ZW5lciwgZGVsZWdhdGVzOiB7bW91c2Vtb3ZlLCBtb3VzZW91dH19O1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdtb3VzZWxlYXZlJyB8fCB0eXBlID09PSAnbW91c2VvdXQnKSB7XG4gICAgICAgICAgICBsZXQgbW91c2VpbiA9IGZhbHNlO1xuICAgICAgICAgICAgY29uc3QgbW91c2Vtb3ZlID0gKGU6IE1hcE1vdXNlRXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBmaWx0ZXJlZExheWVycyA9IGxheWVycy5maWx0ZXIobGF5ZXJJZCA9PiB0aGlzLmdldExheWVyKGxheWVySWQpKTtcbiAgICAgICAgICAgICAgICBjb25zdCBmZWF0dXJlcyA9IGZpbHRlcmVkTGF5ZXJzLmxlbmd0aCA/IHRoaXMucXVlcnlSZW5kZXJlZEZlYXR1cmVzKGUucG9pbnQsIHtsYXllcnM6IGZpbHRlcmVkTGF5ZXJzfSkgOiBbXTtcbiAgICAgICAgICAgICAgICBpZiAoZmVhdHVyZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIG1vdXNlaW4gPSB0cnVlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobW91c2Vpbikge1xuICAgICAgICAgICAgICAgICAgICBtb3VzZWluID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyLmNhbGwodGhpcywgbmV3IE1hcE1vdXNlRXZlbnQodHlwZSwgdGhpcywgZS5vcmlnaW5hbEV2ZW50KSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IG1vdXNlb3V0ID0gKGU6IE1hcE1vdXNlRXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAobW91c2Vpbikge1xuICAgICAgICAgICAgICAgICAgICBtb3VzZWluID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyLmNhbGwodGhpcywgbmV3IE1hcE1vdXNlRXZlbnQodHlwZSwgdGhpcywgZS5vcmlnaW5hbEV2ZW50KSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgcmV0dXJuIHtsYXllcnM6IG5ldyBTZXQobGF5ZXJzKSwgbGlzdGVuZXIsIGRlbGVnYXRlczoge21vdXNlbW92ZSwgbW91c2VvdXR9fTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGRlbGVnYXRlID0gKGU6IE1hcE1vdXNlRXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBmaWx0ZXJlZExheWVycyA9IGxheWVycy5maWx0ZXIobGF5ZXJJZCA9PiB0aGlzLmdldExheWVyKGxheWVySWQpKTtcbiAgICAgICAgICAgICAgICBjb25zdCBmZWF0dXJlcyA9IGZpbHRlcmVkTGF5ZXJzLmxlbmd0aCA/IHRoaXMucXVlcnlSZW5kZXJlZEZlYXR1cmVzKGUucG9pbnQsIHtsYXllcnM6IGZpbHRlcmVkTGF5ZXJzfSkgOiBbXTtcbiAgICAgICAgICAgICAgICBpZiAoZmVhdHVyZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEhlcmUgd2UgbmVlZCB0byBtdXRhdGUgdGhlIG9yaWdpbmFsIGV2ZW50LCBzbyB0aGF0IHByZXZlbnREZWZhdWx0IHdvcmtzIGFzIGV4cGVjdGVkLlxuICAgICAgICAgICAgICAgICAgICBlLmZlYXR1cmVzID0gZmVhdHVyZXM7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyLmNhbGwodGhpcywgZSk7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBlLmZlYXR1cmVzO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHJldHVybiB7bGF5ZXJzOiBuZXcgU2V0KGxheWVycyksIGxpc3RlbmVyLCBkZWxlZ2F0ZXM6IHtbKHR5cGU6IHN0cmluZyldOiBkZWxlZ2F0ZX19O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIEBzZWN0aW9uIHtXb3JraW5nIHdpdGggZXZlbnRzfSAqL1xuXG4gICAgLyoqXG4gICAgICogQWRkcyBhIGxpc3RlbmVyIGZvciBldmVudHMgb2YgYSBzcGVjaWZpZWQgdHlwZSxcbiAgICAgKiBvcHRpb25hbGx5IGxpbWl0ZWQgdG8gZmVhdHVyZXMgaW4gYSBzcGVjaWZpZWQgc3R5bGUgbGF5ZXIuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBUaGUgZXZlbnQgdHlwZSB0byBsaXN0ZW4gZm9yLiBFdmVudHMgY29tcGF0aWJsZSB3aXRoIHRoZSBvcHRpb25hbCBgbGF5ZXJJZGAgcGFyYW1ldGVyIGFyZSB0cmlnZ2VyZWRcbiAgICAgKiB3aGVuIHRoZSBjdXJzb3IgZW50ZXJzIGEgdmlzaWJsZSBwb3J0aW9uIG9mIHRoZSBzcGVjaWZpZWQgbGF5ZXIgZnJvbSBvdXRzaWRlIHRoYXQgbGF5ZXIgb3Igb3V0c2lkZSB0aGUgbWFwIGNhbnZhcy5cbiAgICAgKlxuICAgICAqIHwgRXZlbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQ29tcGF0aWJsZSB3aXRoIGBsYXllcklkYCB8XG4gICAgICogfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXxcbiAgICAgKiB8IFtgbW91c2Vkb3duYF0oI21hcC5ldmVudDptb3VzZWRvd24pICAgICAgICAgICAgICAgICAgICAgICB8IHllcyAgICAgICAgICAgICAgICAgICAgICAgfFxuICAgICAqIHwgW2Btb3VzZXVwYF0oI21hcC5ldmVudDptb3VzZXVwKSAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgeWVzICAgICAgICAgICAgICAgICAgICAgICB8XG4gICAgICogfCBbYG1vdXNlb3ZlcmBdKCNtYXAuZXZlbnQ6bW91c2VvdmVyKSAgICAgICAgICAgICAgICAgICAgICAgfCB5ZXMgICAgICAgICAgICAgICAgICAgICAgIHxcbiAgICAgKiB8IFtgbW91c2VvdXRgXSgjbWFwLmV2ZW50Om1vdXNlb3V0KSAgICAgICAgICAgICAgICAgICAgICAgICB8IHllcyAgICAgICAgICAgICAgICAgICAgICAgfFxuICAgICAqIHwgW2Btb3VzZW1vdmVgXSgjbWFwLmV2ZW50Om1vdXNlbW92ZSkgICAgICAgICAgICAgICAgICAgICAgIHwgeWVzICAgICAgICAgICAgICAgICAgICAgICB8XG4gICAgICogfCBbYG1vdXNlZW50ZXJgXSgjbWFwLmV2ZW50Om1vdXNlZW50ZXIpICAgICAgICAgICAgICAgICAgICAgfCB5ZXMgKHJlcXVpcmVkKSAgICAgICAgICAgIHxcbiAgICAgKiB8IFtgbW91c2VsZWF2ZWBdKCNtYXAuZXZlbnQ6bW91c2VsZWF2ZSkgICAgICAgICAgICAgICAgICAgICB8IHllcyAocmVxdWlyZWQpICAgICAgICAgICAgfFxuICAgICAqIHwgW2BwcmVjbGlja2BdKCNtYXAuZXZlbnQ6cHJlY2xpY2spICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gICAgICogfCBbYGNsaWNrYF0oI21hcC5ldmVudDpjbGljaykgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCB5ZXMgICAgICAgICAgICAgICAgICAgICAgIHxcbiAgICAgKiB8IFtgZGJsY2xpY2tgXSgjbWFwLmV2ZW50OmRibGNsaWNrKSAgICAgICAgICAgICAgICAgICAgICAgICB8IHllcyAgICAgICAgICAgICAgICAgICAgICAgfFxuICAgICAqIHwgW2Bjb250ZXh0bWVudWBdKCNtYXAuZXZlbnQ6Y29udGV4dG1lbnUpICAgICAgICAgICAgICAgICAgIHwgeWVzICAgICAgICAgICAgICAgICAgICAgICB8XG4gICAgICogfCBbYHRvdWNoc3RhcnRgXSgjbWFwLmV2ZW50OnRvdWNoc3RhcnQpICAgICAgICAgICAgICAgICAgICAgfCB5ZXMgICAgICAgICAgICAgICAgICAgICAgIHxcbiAgICAgKiB8IFtgdG91Y2hlbmRgXSgjbWFwLmV2ZW50OnRvdWNoZW5kKSAgICAgICAgICAgICAgICAgICAgICAgICB8IHllcyAgICAgICAgICAgICAgICAgICAgICAgfFxuICAgICAqIHwgW2B0b3VjaGNhbmNlbGBdKCNtYXAuZXZlbnQ6dG91Y2hjYW5jZWwpICAgICAgICAgICAgICAgICAgIHwgeWVzICAgICAgICAgICAgICAgICAgICAgICB8XG4gICAgICogfCBbYHdoZWVsYF0oI21hcC5ldmVudDp3aGVlbCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAgICAgKiB8IFtgcmVzaXplYF0oI21hcC5ldmVudDpyZXNpemUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICAgICAqIHwgW2ByZW1vdmVgXSgjbWFwLmV2ZW50OnJlbW92ZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gICAgICogfCBbYHRvdWNobW92ZWBdKCNtYXAuZXZlbnQ6dG91Y2htb3ZlKSAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAgICAgKiB8IFtgbW92ZXN0YXJ0YF0oI21hcC5ldmVudDptb3Zlc3RhcnQpICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICAgICAqIHwgW2Btb3ZlYF0oI21hcC5ldmVudDptb3ZlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gICAgICogfCBbYG1vdmVlbmRgXSgjbWFwLmV2ZW50Om1vdmVlbmQpICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAgICAgKiB8IFtgZHJhZ3N0YXJ0YF0oI21hcC5ldmVudDpkcmFnc3RhcnQpICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICAgICAqIHwgW2BkcmFnYF0oI21hcC5ldmVudDpkcmFnKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gICAgICogfCBbYGRyYWdlbmRgXSgjbWFwLmV2ZW50OmRyYWdlbmQpICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAgICAgKiB8IFtgem9vbXN0YXJ0YF0oI21hcC5ldmVudDp6b29tc3RhcnQpICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICAgICAqIHwgW2B6b29tYF0oI21hcC5ldmVudDp6b29tKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gICAgICogfCBbYHpvb21lbmRgXSgjbWFwLmV2ZW50Onpvb21lbmQpICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAgICAgKiB8IFtgcm90YXRlc3RhcnRgXSgjbWFwLmV2ZW50OnJvdGF0ZXN0YXJ0KSAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICAgICAqIHwgW2Byb3RhdGVgXSgjbWFwLmV2ZW50OnJvdGF0ZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gICAgICogfCBbYHJvdGF0ZWVuZGBdKCNtYXAuZXZlbnQ6cm90YXRlZW5kKSAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAgICAgKiB8IFtgcGl0Y2hzdGFydGBdKCNtYXAuZXZlbnQ6cGl0Y2hzdGFydCkgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICAgICAqIHwgW2BwaXRjaGBdKCNtYXAuZXZlbnQ6cGl0Y2gpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gICAgICogfCBbYHBpdGNoZW5kYF0oI21hcC5ldmVudDpwaXRjaGVuZCkgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAgICAgKiB8IFtgYm94em9vbXN0YXJ0YF0oI21hcC5ldmVudDpib3h6b29tc3RhcnQpICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICAgICAqIHwgW2Bib3h6b29tZW5kYF0oI21hcC5ldmVudDpib3h6b29tZW5kKSAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gICAgICogfCBbYGJveHpvb21jYW5jZWxgXSgjbWFwLmV2ZW50OmJveHpvb21jYW5jZWwpICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAgICAgKiB8IFtgd2ViZ2xjb250ZXh0bG9zdGBdKCNtYXAuZXZlbnQ6d2ViZ2xjb250ZXh0bG9zdCkgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICAgICAqIHwgW2B3ZWJnbGNvbnRleHRyZXN0b3JlZGBdKCNtYXAuZXZlbnQ6d2ViZ2xjb250ZXh0cmVzdG9yZWQpIHwgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gICAgICogfCBbYGxvYWRgXSgjbWFwLmV2ZW50OmxvYWQpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAgICAgKiB8IFtgcmVuZGVyYF0oI21hcC5ldmVudDpyZW5kZXIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICAgICAqIHwgW2BpZGxlYF0oI21hcC5ldmVudDppZGxlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gICAgICogfCBbYGVycm9yYF0oI21hcC5ldmVudDplcnJvcikgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAgICAgKiB8IFtgZGF0YWBdKCNtYXAuZXZlbnQ6ZGF0YSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICAgICAqIHwgW2BzdHlsZWRhdGFgXSgjbWFwLmV2ZW50OnN0eWxlZGF0YSkgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gICAgICogfCBbYHNvdXJjZWRhdGFgXSgjbWFwLmV2ZW50OnNvdXJjZWRhdGEpICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAgICAgKiB8IFtgZGF0YWxvYWRpbmdgXSgjbWFwLmV2ZW50OmRhdGFsb2FkaW5nKSAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICAgICAqIHwgW2BzdHlsZWRhdGFsb2FkaW5nYF0oI21hcC5ldmVudDpzdHlsZWRhdGFsb2FkaW5nKSAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gICAgICogfCBbYHNvdXJjZWRhdGFsb2FkaW5nYF0oI21hcC5ldmVudDpzb3VyY2VkYXRhbG9hZGluZykgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAgICAgKiB8IFtgc3R5bGVpbWFnZW1pc3NpbmdgXSgjbWFwLmV2ZW50OnN0eWxlaW1hZ2VtaXNzaW5nKSAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICAgICAqIHwgW2BzdHlsZS5sb2FkYF0oI21hcC5ldmVudDpzdHlsZS5sb2FkKSAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZyB8IEFycmF5PHN0cmluZz59IGxheWVySWRzIChvcHRpb25hbCkgVGhlIElEKHMpIG9mIGEgc3R5bGUgbGF5ZXIocykuIElmIHlvdSBwcm92aWRlIGEgYGxheWVySWRgLFxuICAgICAqIHRoZSBsaXN0ZW5lciB3aWxsIGJlIHRyaWdnZXJlZCBvbmx5IGlmIGl0cyBsb2NhdGlvbiBpcyB3aXRoaW4gYSB2aXNpYmxlIGZlYXR1cmUgaW4gdGhlc2UgbGF5ZXJzLFxuICAgICAqIGFuZCB0aGUgZXZlbnQgd2lsbCBoYXZlIGEgYGZlYXR1cmVzYCBwcm9wZXJ0eSBjb250YWluaW5nIGFuIGFycmF5IG9mIHRoZSBtYXRjaGluZyBmZWF0dXJlcy5cbiAgICAgKiBJZiB5b3UgZG8gbm90IHByb3ZpZGUgYGxheWVySWRzYCwgdGhlIGxpc3RlbmVyIHdpbGwgYmUgdHJpZ2dlcmVkIGJ5IGEgY29ycmVzcG9uZGluZyBldmVudFxuICAgICAqIGhhcHBlbmluZyBhbnl3aGVyZSBvbiB0aGUgbWFwLCBhbmQgdGhlIGV2ZW50IHdpbGwgbm90IGhhdmUgYSBgZmVhdHVyZXNgIHByb3BlcnR5LlxuICAgICAqIE5vdGUgdGhhdCBtYW55IGV2ZW50IHR5cGVzIGFyZSBub3QgY29tcGF0aWJsZSB3aXRoIHRoZSBvcHRpb25hbCBgbGF5ZXJJZHNgIHBhcmFtZXRlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBUaGUgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzIGZpcmVkLlxuICAgICAqIEByZXR1cm5zIHtNYXB9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCB3aWxsIGZpcmVcbiAgICAgKiAvLyB3aGVuIHRoZSBtYXAgaGFzIGZpbmlzaGVkIGxvYWRpbmcuXG4gICAgICogbWFwLm9uKCdsb2FkJywgKCkgPT4ge1xuICAgICAqICAgICAvLyBBZGQgYSBuZXcgbGF5ZXIuXG4gICAgICogICAgIG1hcC5hZGRMYXllcih7XG4gICAgICogICAgICAgICBpZDogJ3BvaW50cy1vZi1pbnRlcmVzdCcsXG4gICAgICogICAgICAgICBzb3VyY2U6IHtcbiAgICAgKiAgICAgICAgICAgICB0eXBlOiAndmVjdG9yJyxcbiAgICAgKiAgICAgICAgICAgICB1cmw6ICdtYXBib3g6Ly9tYXBib3gubWFwYm94LXN0cmVldHMtdjgnXG4gICAgICogICAgICAgICB9LFxuICAgICAqICAgICAgICAgJ3NvdXJjZS1sYXllcic6ICdwb2lfbGFiZWwnLFxuICAgICAqICAgICAgICAgdHlwZTogJ2NpcmNsZScsXG4gICAgICogICAgICAgICBwYWludDoge1xuICAgICAqICAgICAgICAgICAgIC8vIE1hcGJveCBTdHlsZSBTcGVjaWZpY2F0aW9uIHBhaW50IHByb3BlcnRpZXNcbiAgICAgKiAgICAgICAgIH0sXG4gICAgICogICAgICAgICBsYXlvdXQ6IHtcbiAgICAgKiAgICAgICAgICAgICAvLyBNYXBib3ggU3R5bGUgU3BlY2lmaWNhdGlvbiBsYXlvdXQgcHJvcGVydGllc1xuICAgICAqICAgICAgICAgfVxuICAgICAqICAgICB9KTtcbiAgICAgKiB9KTtcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIFNldCBhbiBldmVudCBsaXN0ZW5lciB0aGF0IHdpbGwgZmlyZVxuICAgICAqIC8vIHdoZW4gYSBmZWF0dXJlIG9uIHRoZSBjb3VudHJpZXMgbGF5ZXIgb2YgdGhlIG1hcCBpcyBjbGlja2VkLlxuICAgICAqIG1hcC5vbignY2xpY2snLCAnY291bnRyaWVzJywgKGUpID0+IHtcbiAgICAgKiAgICAgbmV3IG1hcGJveGdsLlBvcHVwKClcbiAgICAgKiAgICAgICAgIC5zZXRMbmdMYXQoZS5sbmdMYXQpXG4gICAgICogICAgICAgICAuc2V0SFRNTChgQ291bnRyeSBuYW1lOiAke2UuZmVhdHVyZXNbMF0ucHJvcGVydGllcy5uYW1lfWApXG4gICAgICogICAgICAgICAuYWRkVG8obWFwKTtcbiAgICAgKiB9KTtcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIFNldCBhbiBldmVudCBsaXN0ZW5lciB0aGF0IHdpbGwgZmlyZVxuICAgICAqIC8vIHdoZW4gYSBmZWF0dXJlIG9uIHRoZSBjb3VudHJpZXMgb3IgYmFja2dyb3VuZCBsYXllcnMgb2YgdGhlIG1hcCBpcyBjbGlja2VkLlxuICAgICAqIG1hcC5vbignY2xpY2snLCBbJ2NvdW50cmllcycsICdiYWNrZ3JvdW5kJ10sIChlKSA9PiB7XG4gICAgICogICAgIG5ldyBtYXBib3hnbC5Qb3B1cCgpXG4gICAgICogICAgICAgICAuc2V0TG5nTGF0KGUubG5nTGF0KVxuICAgICAqICAgICAgICAgLnNldEhUTUwoYENvdW50cnkgbmFtZTogJHtlLmZlYXR1cmVzWzBdLnByb3BlcnRpZXMubmFtZX1gKVxuICAgICAqICAgICAgICAgLmFkZFRvKG1hcCk7XG4gICAgICogfSk7XG4gICAgICogQHNlZSBbRXhhbXBsZTogQWRkIDNEIHRlcnJhaW4gdG8gYSBtYXBdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2FkZC10ZXJyYWluLylcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBDZW50ZXIgdGhlIG1hcCBvbiBhIGNsaWNrZWQgc3ltYm9sXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9jZW50ZXItb24tc3ltYm9sLylcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBDcmVhdGUgYSBkcmFnZ2FibGUgbWFya2VyXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9kcmFnLWEtcG9pbnQvKVxuICAgICAqIEBzZWUgW0V4YW1wbGU6IENyZWF0ZSBhIGhvdmVyIGVmZmVjdF0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvaG92ZXItc3R5bGVzLylcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBEaXNwbGF5IHBvcHVwIG9uIGNsaWNrXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9wb3B1cC1vbi1jbGljay8pXG4gICAgICovXG4gICAgb24odHlwZTogTWFwRXZlbnQsIGxheWVySWRzOiBhbnksIGxpc3RlbmVyOiBhbnkpOiB0aGlzIHtcbiAgICAgICAgaWYgKGxpc3RlbmVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBzdXBlci5vbih0eXBlLCBsYXllcklkcyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobGF5ZXJJZHMpKSB7XG4gICAgICAgICAgICBsYXllcklkcyA9IFtsYXllcklkc107XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGVsZWdhdGVkTGlzdGVuZXIgPSB0aGlzLl9jcmVhdGVEZWxlZ2F0ZWRMaXN0ZW5lcih0eXBlLCBsYXllcklkcywgbGlzdGVuZXIpO1xuXG4gICAgICAgIHRoaXMuX2RlbGVnYXRlZExpc3RlbmVycyA9IHRoaXMuX2RlbGVnYXRlZExpc3RlbmVycyB8fCB7fTtcbiAgICAgICAgdGhpcy5fZGVsZWdhdGVkTGlzdGVuZXJzW3R5cGVdID0gdGhpcy5fZGVsZWdhdGVkTGlzdGVuZXJzW3R5cGVdIHx8IFtdO1xuICAgICAgICB0aGlzLl9kZWxlZ2F0ZWRMaXN0ZW5lcnNbdHlwZV0ucHVzaChkZWxlZ2F0ZWRMaXN0ZW5lcik7XG5cbiAgICAgICAgZm9yIChjb25zdCBldmVudCBpbiBkZWxlZ2F0ZWRMaXN0ZW5lci5kZWxlZ2F0ZXMpIHtcbiAgICAgICAgICAgIHRoaXMub24oKGV2ZW50OiBhbnkpLCBkZWxlZ2F0ZWRMaXN0ZW5lci5kZWxlZ2F0ZXNbZXZlbnRdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZHMgYSBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgY2FsbGVkIG9ubHkgb25jZSB0byBhIHNwZWNpZmllZCBldmVudCB0eXBlLFxuICAgICAqIG9wdGlvbmFsbHkgbGltaXRlZCB0byBldmVudHMgb2NjdXJyaW5nIG9uIGZlYXR1cmVzIGluIGEgc3BlY2lmaWVkIHN0eWxlIGxheWVyLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgVGhlIGV2ZW50IHR5cGUgdG8gbGlzdGVuIGZvcjsgb25lIG9mIGAnbW91c2Vkb3duJ2AsIGAnbW91c2V1cCdgLCBgJ3ByZWNsaWNrJ2AsIGAnY2xpY2snYCwgYCdkYmxjbGljaydgLFxuICAgICAqIGAnbW91c2Vtb3ZlJ2AsIGAnbW91c2VlbnRlcidgLCBgJ21vdXNlbGVhdmUnYCwgYCdtb3VzZW92ZXInYCwgYCdtb3VzZW91dCdgLCBgJ2NvbnRleHRtZW51J2AsIGAndG91Y2hzdGFydCdgLFxuICAgICAqIGAndG91Y2hlbmQnYCwgb3IgYCd0b3VjaGNhbmNlbCdgLiBgbW91c2VlbnRlcmAgYW5kIGBtb3VzZW92ZXJgIGV2ZW50cyBhcmUgdHJpZ2dlcmVkIHdoZW4gdGhlIGN1cnNvciBlbnRlcnNcbiAgICAgKiBhIHZpc2libGUgcG9ydGlvbiBvZiB0aGUgc3BlY2lmaWVkIGxheWVyIGZyb20gb3V0c2lkZSB0aGF0IGxheWVyIG9yIG91dHNpZGUgdGhlIG1hcCBjYW52YXMuIGBtb3VzZWxlYXZlYFxuICAgICAqIGFuZCBgbW91c2VvdXRgIGV2ZW50cyBhcmUgdHJpZ2dlcmVkIHdoZW4gdGhlIGN1cnNvciBsZWF2ZXMgYSB2aXNpYmxlIHBvcnRpb24gb2YgdGhlIHNwZWNpZmllZCBsYXllciwgb3IgbGVhdmVzXG4gICAgICogdGhlIG1hcCBjYW52YXMuXG4gICAgICogQHBhcmFtIHtzdHJpbmcgfCBBcnJheTxzdHJpbmc+fSBsYXllcklkcyAob3B0aW9uYWwpIFRoZSBJRChzKSBvZiBhIHN0eWxlIGxheWVyKHMpLiBJZiB5b3UgcHJvdmlkZSBgbGF5ZXJJZHNgLFxuICAgICAqIHRoZSBsaXN0ZW5lciB3aWxsIGJlIHRyaWdnZXJlZCBvbmx5IGlmIGl0cyBsb2NhdGlvbiBpcyB3aXRoaW4gYSB2aXNpYmxlIGZlYXR1cmUgaW4gdGhlc2UgbGF5ZXJzLFxuICAgICAqIGFuZCB0aGUgZXZlbnQgd2lsbCBoYXZlIGEgYGZlYXR1cmVzYCBwcm9wZXJ0eSBjb250YWluaW5nIGFuIGFycmF5IG9mIHRoZSBtYXRjaGluZyBmZWF0dXJlcy5cbiAgICAgKiBJZiB5b3UgZG8gbm90IHByb3ZpZGUgYGxheWVySWRzYCwgdGhlIGxpc3RlbmVyIHdpbGwgYmUgdHJpZ2dlcmVkIGJ5IGEgY29ycmVzcG9uZGluZyBldmVudFxuICAgICAqIGhhcHBlbmluZyBhbnl3aGVyZSBvbiB0aGUgbWFwLCBhbmQgdGhlIGV2ZW50IHdpbGwgbm90IGhhdmUgYSBgZmVhdHVyZXNgIHByb3BlcnR5LlxuICAgICAqIE5vdGUgdGhhdCBtYW55IGV2ZW50IHR5cGVzIGFyZSBub3QgY29tcGF0aWJsZSB3aXRoIHRoZSBvcHRpb25hbCBgbGF5ZXJJZHNgIHBhcmFtZXRlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBUaGUgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzIGZpcmVkLlxuICAgICAqIEByZXR1cm5zIHtNYXB9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBMb2cgdGhlIGNvb3JkaW5hdGVzIG9mIGEgdXNlcidzIGZpcnN0IG1hcCB0b3VjaC5cbiAgICAgKiBtYXAub25jZSgndG91Y2hzdGFydCcsIChlKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKGBUaGUgZmlyc3QgbWFwIHRvdWNoIHdhcyBhdDogJHtlLmxuZ2xhdH1gKTtcbiAgICAgKiB9KTtcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIExvZyB0aGUgY29vcmRpbmF0ZXMgb2YgYSB1c2VyJ3MgZmlyc3QgbWFwIHRvdWNoXG4gICAgICogLy8gb24gYSBzcGVjaWZpYyBsYXllci5cbiAgICAgKiBtYXAub25jZSgndG91Y2hzdGFydCcsICdteS1wb2ludC1sYXllcicsIChlKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKGBUaGUgZmlyc3QgbWFwIHRvdWNoIG9uIHRoZSBwb2ludCBsYXllciB3YXMgYXQ6ICR7ZS5sbmdsYXR9YCk7XG4gICAgICogfSk7XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBMb2cgdGhlIGNvb3JkaW5hdGVzIG9mIGEgdXNlcidzIGZpcnN0IG1hcCB0b3VjaFxuICAgICAqIC8vIG9uIHNwZWNpZmljIGxheWVycy5cbiAgICAgKiBtYXAub25jZSgndG91Y2hzdGFydCcsIFsnbXktcG9pbnQtbGF5ZXInLCAnbXktcG9pbnQtbGF5ZXItMiddLCAoZSkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZyhgVGhlIGZpcnN0IG1hcCB0b3VjaCBvbiB0aGUgcG9pbnQgbGF5ZXIgd2FzIGF0OiAke2UubG5nbGF0fWApO1xuICAgICAqIH0pO1xuICAgICAqIEBzZWUgW0V4YW1wbGU6IENyZWF0ZSBhIGRyYWdnYWJsZSBwb2ludF0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvZHJhZy1hLXBvaW50LylcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBBbmltYXRlIHRoZSBjYW1lcmEgYXJvdW5kIGEgcG9pbnQgd2l0aCAzRCB0ZXJyYWluXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9mcmVlLWNhbWVyYS1wb2ludC8pXG4gICAgICogQHNlZSBbRXhhbXBsZTogUGxheSBtYXAgbG9jYXRpb25zIGFzIGEgc2xpZGVzaG93XShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9wbGF5YmFjay1sb2NhdGlvbnMvKVxuICAgICAqL1xuICAgIG9uY2UodHlwZTogTWFwRXZlbnQsIGxheWVySWRzOiBhbnksIGxpc3RlbmVyOiBhbnkpOiB0aGlzIHwgUHJvbWlzZTxFdmVudD4ge1xuXG4gICAgICAgIGlmIChsaXN0ZW5lciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gc3VwZXIub25jZSh0eXBlLCBsYXllcklkcyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobGF5ZXJJZHMpKSB7XG4gICAgICAgICAgICBsYXllcklkcyA9IFtsYXllcklkc107XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGVsZWdhdGVkTGlzdGVuZXIgPSB0aGlzLl9jcmVhdGVEZWxlZ2F0ZWRMaXN0ZW5lcih0eXBlLCBsYXllcklkcywgbGlzdGVuZXIpO1xuXG4gICAgICAgIGZvciAoY29uc3QgZXZlbnQgaW4gZGVsZWdhdGVkTGlzdGVuZXIuZGVsZWdhdGVzKSB7XG4gICAgICAgICAgICB0aGlzLm9uY2UoKGV2ZW50OiBhbnkpLCBkZWxlZ2F0ZWRMaXN0ZW5lci5kZWxlZ2F0ZXNbZXZlbnRdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYW4gZXZlbnQgbGlzdGVuZXIgcHJldmlvdXNseSBhZGRlZCB3aXRoIHtAbGluayBNYXAjb259LFxuICAgICAqIG9wdGlvbmFsbHkgbGltaXRlZCB0byBsYXllci1zcGVjaWZpYyBldmVudHMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBUaGUgZXZlbnQgdHlwZSBwcmV2aW91c2x5IHVzZWQgdG8gaW5zdGFsbCB0aGUgbGlzdGVuZXIuXG4gICAgICogQHBhcmFtIHtzdHJpbmcgfCBBcnJheTxzdHJpbmc+fSBsYXllcklkcyAob3B0aW9uYWwpIFRoZSBsYXllciBJRChzKSBwcmV2aW91c2x5IHVzZWQgdG8gaW5zdGFsbCB0aGUgbGlzdGVuZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgVGhlIGZ1bmN0aW9uIHByZXZpb3VzbHkgaW5zdGFsbGVkIGFzIGEgbGlzdGVuZXIuXG4gICAgICogQHJldHVybnMge01hcH0gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIENyZWF0ZSBhIGZ1bmN0aW9uIHRvIHByaW50IGNvb3JkaW5hdGVzIHdoaWxlIGEgbW91c2UgaXMgbW92aW5nLlxuICAgICAqIGZ1bmN0aW9uIG9uTW92ZShlKSB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKGBUaGUgbW91c2UgaXMgbW92aW5nOiAke2UubG5nTGF0fWApO1xuICAgICAqIH1cbiAgICAgKiAvLyBDcmVhdGUgYSBmdW5jdGlvbiB0byB1bmJpbmQgdGhlIGBtb3VzZW1vdmVgIGV2ZW50LlxuICAgICAqIGZ1bmN0aW9uIG9uVXAoZSkge1xuICAgICAqICAgICBjb25zb2xlLmxvZyhgVGhlIGZpbmFsIGNvb3JkaW5hdGVzIGFyZTogJHtlLmxuZ0xhdH1gKTtcbiAgICAgKiAgICAgbWFwLm9mZignbW91c2Vtb3ZlJywgb25Nb3ZlKTtcbiAgICAgKiB9XG4gICAgICogLy8gV2hlbiBhIGNsaWNrIG9jY3VycywgYmluZCBib3RoIGZ1bmN0aW9ucyB0byBtb3VzZSBldmVudHMuXG4gICAgICogbWFwLm9uKCdtb3VzZWRvd24nLCAoZSkgPT4ge1xuICAgICAqICAgICBtYXAub24oJ21vdXNlbW92ZScsIG9uTW92ZSk7XG4gICAgICogICAgIG1hcC5vbmNlKCdtb3VzZXVwJywgb25VcCk7XG4gICAgICogfSk7XG4gICAgICogQHNlZSBbRXhhbXBsZTogQ3JlYXRlIGEgZHJhZ2dhYmxlIHBvaW50XShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9kcmFnLWEtcG9pbnQvKVxuICAgICAqL1xuICAgIG9mZih0eXBlOiBNYXBFdmVudCwgbGF5ZXJJZHM6IGFueSwgbGlzdGVuZXI6IGFueSk6IHRoaXMge1xuICAgICAgICBpZiAobGlzdGVuZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHN1cGVyLm9mZih0eXBlLCBsYXllcklkcyk7XG4gICAgICAgIH1cblxuICAgICAgICBsYXllcklkcyA9IG5ldyBTZXQoQXJyYXkuaXNBcnJheShsYXllcklkcykgPyBsYXllcklkcyA6IFtsYXllcklkc10pO1xuICAgICAgICBjb25zdCBhcmVMYXllckFycmF5c0VxdWFsID0gKGhhc2gxOiBTZXQ8c3RyaW5nPiwgaGFzaDI6IFNldDxzdHJpbmc+KSA9PiB7XG4gICAgICAgICAgICBpZiAoaGFzaDEuc2l6ZSAhPT0gaGFzaDIuc2l6ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gYXQtbGVhc3QgMSBhcnIgaGFzIGR1cGxpY2F0ZSB2YWx1ZShzKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBjb21wYXJpbmcgdmFsdWVzXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIGhhc2gxKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFoYXNoMi5oYXModmFsdWUpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCByZW1vdmVEZWxlZ2F0ZWRMaXN0ZW5lcnMgPSAobGlzdGVuZXJzOiBBcnJheTxhbnk+KSA9PiB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRlbGVnYXRlZExpc3RlbmVyID0gbGlzdGVuZXJzW2ldO1xuICAgICAgICAgICAgICAgIGlmIChkZWxlZ2F0ZWRMaXN0ZW5lci5saXN0ZW5lciA9PT0gbGlzdGVuZXIgJiYgYXJlTGF5ZXJBcnJheXNFcXVhbChkZWxlZ2F0ZWRMaXN0ZW5lci5sYXllcnMsIGxheWVySWRzKSkge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGV2ZW50IGluIGRlbGVnYXRlZExpc3RlbmVyLmRlbGVnYXRlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vZmYoKGV2ZW50OiBhbnkpLCBkZWxlZ2F0ZWRMaXN0ZW5lci5kZWxlZ2F0ZXNbZXZlbnRdKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgZGVsZWdhdGVkTGlzdGVuZXJzID0gdGhpcy5fZGVsZWdhdGVkTGlzdGVuZXJzID8gdGhpcy5fZGVsZWdhdGVkTGlzdGVuZXJzW3R5cGVdIDogdW5kZWZpbmVkO1xuICAgICAgICBpZiAoZGVsZWdhdGVkTGlzdGVuZXJzKSB7XG4gICAgICAgICAgICByZW1vdmVEZWxlZ2F0ZWRMaXN0ZW5lcnMoZGVsZWdhdGVkTGlzdGVuZXJzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKiBAc2VjdGlvbiB7UXVlcnlpbmcgZmVhdHVyZXN9ICovXG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIFtHZW9KU09OXShodHRwOi8vZ2VvanNvbi5vcmcvKVxuICAgICAqIFtGZWF0dXJlIG9iamVjdHNdKGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM3OTQ2I3NlY3Rpb24tMy4yKVxuICAgICAqIHJlcHJlc2VudGluZyB2aXNpYmxlIGZlYXR1cmVzIHRoYXQgc2F0aXNmeSB0aGUgcXVlcnkgcGFyYW1ldGVycy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7UG9pbnRMaWtlfEFycmF5PFBvaW50TGlrZT59IFtnZW9tZXRyeV0gLSBUaGUgZ2VvbWV0cnkgb2YgdGhlIHF1ZXJ5IHJlZ2lvbiBpbiBwaXhlbHM6XG4gICAgICogZWl0aGVyIGEgc2luZ2xlIHBvaW50IG9yIGJvdHRvbSBsZWZ0IGFuZCB0b3AgcmlnaHQgcG9pbnRzIGRlc2NyaWJpbmcgYSBib3VuZGluZyBib3gsIHdoZXJlIHRoZSBvcmlnaW4gaXMgYXQgdGhlIHRvcCBsZWZ0LlxuICAgICAqIE9taXR0aW5nIHRoaXMgcGFyYW1ldGVyIChieSBjYWxsaW5nIHtAbGluayBNYXAjcXVlcnlSZW5kZXJlZEZlYXR1cmVzfSB3aXRoIHplcm8gYXJndW1lbnRzLFxuICAgICAqIG9yIHdpdGggb25seSBhbiBgb3B0aW9uc2AgYXJndW1lbnQpIGlzIGVxdWl2YWxlbnQgdG8gcGFzc2luZyBhIGJvdW5kaW5nIGJveCBlbmNvbXBhc3NpbmcgdGhlIGVudGlyZVxuICAgICAqIG1hcCB2aWV3cG9ydC5cbiAgICAgKiBPbmx5IHZhbHVlcyB3aXRoaW4gdGhlIGV4aXN0aW5nIHZpZXdwb3J0IGFyZSBzdXBwb3J0ZWQuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSBPcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge0FycmF5PHN0cmluZz59IFtvcHRpb25zLmxheWVyc10gQW4gYXJyYXkgb2YgW3N0eWxlIGxheWVyIElEc10oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL3N0eWxlLXNwZWMvI2xheWVyLWlkKSBmb3IgdGhlIHF1ZXJ5IHRvIGluc3BlY3QuXG4gICAgICogICBPbmx5IGZlYXR1cmVzIHdpdGhpbiB0aGVzZSBsYXllcnMgd2lsbCBiZSByZXR1cm5lZC4gSWYgdGhpcyBwYXJhbWV0ZXIgaXMgdW5kZWZpbmVkLCBhbGwgbGF5ZXJzIHdpbGwgYmUgY2hlY2tlZC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbb3B0aW9ucy5maWx0ZXJdIEEgW2ZpbHRlcl0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL3N0eWxlLXNwZWMvbGF5ZXJzLyNmaWx0ZXIpXG4gICAgICogICB0byBsaW1pdCBxdWVyeSByZXN1bHRzLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMudmFsaWRhdGU9dHJ1ZV0gV2hldGhlciB0byBjaGVjayBpZiB0aGUgW29wdGlvbnMuZmlsdGVyXSBjb25mb3JtcyB0byB0aGUgTWFwYm94IEdMIFN0eWxlIFNwZWNpZmljYXRpb24uIERpc2FibGluZyB2YWxpZGF0aW9uIGlzIGEgcGVyZm9ybWFuY2Ugb3B0aW1pemF0aW9uIHRoYXQgc2hvdWxkIG9ubHkgYmUgdXNlZCBpZiB5b3UgaGF2ZSBwcmV2aW91c2x5IHZhbGlkYXRlZCB0aGUgdmFsdWVzIHlvdSB3aWxsIGJlIHBhc3NpbmcgdG8gdGhpcyBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtBcnJheTxPYmplY3Q+fSBBbiBhcnJheSBvZiBbR2VvSlNPTl0oaHR0cDovL2dlb2pzb24ub3JnLylcbiAgICAgKiBbZmVhdHVyZSBvYmplY3RzXShodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNzk0NiNzZWN0aW9uLTMuMikuXG4gICAgICpcbiAgICAgKiBUaGUgYHByb3BlcnRpZXNgIHZhbHVlIG9mIGVhY2ggcmV0dXJuZWQgZmVhdHVyZSBvYmplY3QgY29udGFpbnMgdGhlIHByb3BlcnRpZXMgb2YgaXRzIHNvdXJjZSBmZWF0dXJlLiBGb3IgR2VvSlNPTiBzb3VyY2VzLCBvbmx5XG4gICAgICogc3RyaW5nIGFuZCBudW1lcmljIHByb3BlcnR5IHZhbHVlcyBhcmUgc3VwcG9ydGVkLiBgbnVsbGAsIGBBcnJheWAsIGFuZCBgT2JqZWN0YCB2YWx1ZXMgYXJlIG5vdCBzdXBwb3J0ZWQuXG4gICAgICpcbiAgICAgKiBFYWNoIGZlYXR1cmUgaW5jbHVkZXMgdG9wLWxldmVsIGBsYXllcmAsIGBzb3VyY2VgLCBhbmQgYHNvdXJjZUxheWVyYCBwcm9wZXJ0aWVzLiBUaGUgYGxheWVyYCBwcm9wZXJ0eSBpcyBhbiBvYmplY3RcbiAgICAgKiByZXByZXNlbnRpbmcgdGhlIHN0eWxlIGxheWVyIHRvICB3aGljaCB0aGUgZmVhdHVyZSBiZWxvbmdzLiBMYXlvdXQgYW5kIHBhaW50IHByb3BlcnRpZXMgaW4gdGhpcyBvYmplY3QgY29udGFpbiB2YWx1ZXNcbiAgICAgKiB3aGljaCBhcmUgZnVsbHkgZXZhbHVhdGVkIGZvciB0aGUgZ2l2ZW4gem9vbSBsZXZlbCBhbmQgZmVhdHVyZS5cbiAgICAgKlxuICAgICAqIE9ubHkgZmVhdHVyZXMgdGhhdCBhcmUgY3VycmVudGx5IHJlbmRlcmVkIGFyZSBpbmNsdWRlZC4gU29tZSBmZWF0dXJlcyB3aWxsICoqbm90KiogYmUgaW5jbHVkZWQsIGxpa2U6XG4gICAgICpcbiAgICAgKiAtIEZlYXR1cmVzIGZyb20gbGF5ZXJzIHdob3NlIGB2aXNpYmlsaXR5YCBwcm9wZXJ0eSBpcyBgXCJub25lXCJgLlxuICAgICAqIC0gRmVhdHVyZXMgZnJvbSBsYXllcnMgd2hvc2Ugem9vbSByYW5nZSBleGNsdWRlcyB0aGUgY3VycmVudCB6b29tIGxldmVsLlxuICAgICAqIC0gU3ltYm9sIGZlYXR1cmVzIHRoYXQgaGF2ZSBiZWVuIGhpZGRlbiBkdWUgdG8gdGV4dCBvciBpY29uIGNvbGxpc2lvbi5cbiAgICAgKlxuICAgICAqIEZlYXR1cmVzIGZyb20gYWxsIG90aGVyIGxheWVycyBhcmUgaW5jbHVkZWQsIGluY2x1ZGluZyBmZWF0dXJlcyB0aGF0IG1heSBoYXZlIG5vIHZpc2libGVcbiAgICAgKiBjb250cmlidXRpb24gdG8gdGhlIHJlbmRlcmVkIHJlc3VsdDsgZm9yIGV4YW1wbGUsIGJlY2F1c2UgdGhlIGxheWVyJ3Mgb3BhY2l0eSBvciBjb2xvciBhbHBoYSBjb21wb25lbnQgaXMgc2V0IHRvXG4gICAgICogMC5cbiAgICAgKlxuICAgICAqIFRoZSB0b3Btb3N0IHJlbmRlcmVkIGZlYXR1cmUgYXBwZWFycyBmaXJzdCBpbiB0aGUgcmV0dXJuZWQgYXJyYXksIGFuZCBzdWJzZXF1ZW50IGZlYXR1cmVzIGFyZSBzb3J0ZWQgYnlcbiAgICAgKiBkZXNjZW5kaW5nIHotb3JkZXIuIEZlYXR1cmVzIHRoYXQgYXJlIHJlbmRlcmVkIG11bHRpcGxlIHRpbWVzIChkdWUgdG8gd3JhcHBpbmcgYWNyb3NzIHRoZSBhbnRpbWVyaWRpYW4gYXQgbG93XG4gICAgICogem9vbSBsZXZlbHMpIGFyZSByZXR1cm5lZCBvbmx5IG9uY2UgKHRob3VnaCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY2F2ZWF0KS5cbiAgICAgKlxuICAgICAqIEJlY2F1c2UgZmVhdHVyZXMgY29tZSBmcm9tIHRpbGVkIHZlY3RvciBkYXRhIG9yIEdlb0pTT04gZGF0YSB0aGF0IGlzIGNvbnZlcnRlZCB0byB0aWxlcyBpbnRlcm5hbGx5LCBmZWF0dXJlXG4gICAgICogZ2VvbWV0cmllcyBtYXkgYmUgc3BsaXQgb3IgZHVwbGljYXRlZCBhY3Jvc3MgdGlsZSBib3VuZGFyaWVzIGFuZCwgYXMgYSByZXN1bHQsIGZlYXR1cmVzIG1heSBhcHBlYXIgbXVsdGlwbGVcbiAgICAgKiB0aW1lcyBpbiBxdWVyeSByZXN1bHRzLiBGb3IgZXhhbXBsZSwgc3VwcG9zZSB0aGVyZSBpcyBhIGhpZ2h3YXkgcnVubmluZyB0aHJvdWdoIHRoZSBib3VuZGluZyByZWN0YW5nbGUgb2YgYSBxdWVyeS5cbiAgICAgKiBUaGUgcmVzdWx0cyBvZiB0aGUgcXVlcnkgd2lsbCBiZSB0aG9zZSBwYXJ0cyBvZiB0aGUgaGlnaHdheSB0aGF0IGxpZSB3aXRoaW4gdGhlIG1hcCB0aWxlcyBjb3ZlcmluZyB0aGUgYm91bmRpbmdcbiAgICAgKiByZWN0YW5nbGUsIGV2ZW4gaWYgdGhlIGhpZ2h3YXkgZXh0ZW5kcyBpbnRvIG90aGVyIHRpbGVzLCBhbmQgdGhlIHBvcnRpb24gb2YgdGhlIGhpZ2h3YXkgd2l0aGluIGVhY2ggbWFwIHRpbGVcbiAgICAgKiB3aWxsIGJlIHJldHVybmVkIGFzIGEgc2VwYXJhdGUgZmVhdHVyZS4gU2ltaWxhcmx5LCBhIHBvaW50IGZlYXR1cmUgbmVhciBhIHRpbGUgYm91bmRhcnkgbWF5IGFwcGVhciBpbiBtdWx0aXBsZVxuICAgICAqIHRpbGVzIGR1ZSB0byB0aWxlIGJ1ZmZlcmluZy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gRmluZCBhbGwgZmVhdHVyZXMgYXQgYSBwb2ludFxuICAgICAqIGNvbnN0IGZlYXR1cmVzID0gbWFwLnF1ZXJ5UmVuZGVyZWRGZWF0dXJlcyhcbiAgICAgKiAgIFsyMCwgMzVdLFxuICAgICAqICAge2xheWVyczogWydteS1sYXllci1uYW1lJ119XG4gICAgICogKTtcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gRmluZCBhbGwgZmVhdHVyZXMgd2l0aGluIGEgc3RhdGljIGJvdW5kaW5nIGJveFxuICAgICAqIGNvbnN0IGZlYXR1cmVzID0gbWFwLnF1ZXJ5UmVuZGVyZWRGZWF0dXJlcyhcbiAgICAgKiAgIFtbMTAsIDIwXSwgWzMwLCA1MF1dLFxuICAgICAqICAge2xheWVyczogWydteS1sYXllci1uYW1lJ119XG4gICAgICogKTtcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gRmluZCBhbGwgZmVhdHVyZXMgd2l0aGluIGEgYm91bmRpbmcgYm94IGFyb3VuZCBhIHBvaW50XG4gICAgICogY29uc3Qgd2lkdGggPSAxMDtcbiAgICAgKiBjb25zdCBoZWlnaHQgPSAyMDtcbiAgICAgKiBjb25zdCBmZWF0dXJlcyA9IG1hcC5xdWVyeVJlbmRlcmVkRmVhdHVyZXMoW1xuICAgICAqICAgICBbcG9pbnQueCAtIHdpZHRoIC8gMiwgcG9pbnQueSAtIGhlaWdodCAvIDJdLFxuICAgICAqICAgICBbcG9pbnQueCArIHdpZHRoIC8gMiwgcG9pbnQueSArIGhlaWdodCAvIDJdXG4gICAgICogXSwge2xheWVyczogWydteS1sYXllci1uYW1lJ119KTtcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gUXVlcnkgYWxsIHJlbmRlcmVkIGZlYXR1cmVzIGZyb20gYSBzaW5nbGUgbGF5ZXJcbiAgICAgKiBjb25zdCBmZWF0dXJlcyA9IG1hcC5xdWVyeVJlbmRlcmVkRmVhdHVyZXMoe2xheWVyczogWydteS1sYXllci1uYW1lJ119KTtcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBHZXQgZmVhdHVyZXMgdW5kZXIgdGhlIG1vdXNlIHBvaW50ZXJdKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvcXVlcnlyZW5kZXJlZGZlYXR1cmVzLylcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBIaWdobGlnaHQgZmVhdHVyZXMgd2l0aGluIGEgYm91bmRpbmcgYm94XShodHRwczovL3d3dy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL3VzaW5nLWJveC1xdWVyeXJlbmRlcmVkZmVhdHVyZXMvKVxuICAgICAqIEBzZWUgW0V4YW1wbGU6IEZpbHRlciBmZWF0dXJlcyB3aXRoaW4gbWFwIHZpZXddKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvZmlsdGVyLWZlYXR1cmVzLXdpdGhpbi1tYXAtdmlldy8pXG4gICAgICovXG4gICAgcXVlcnlSZW5kZXJlZEZlYXR1cmVzKGdlb21ldHJ5PzogUG9pbnRMaWtlIHwgW1BvaW50TGlrZSwgUG9pbnRMaWtlXSwgb3B0aW9ucz86IE9iamVjdCk6IEFycmF5PFF1ZXJ5UmVzdWx0PiB7XG4gICAgICAgIC8vIFRoZSBmaXJzdCBwYXJhbWV0ZXIgY2FuIGJlIG9taXR0ZWQgZW50aXJlbHksIG1ha2luZyB0aGlzIGVmZmVjdGl2ZWx5IGFuIG92ZXJsb2FkZWQgbWV0aG9kXG4gICAgICAgIC8vIHdpdGggdHdvIHNpZ25hdHVyZXM6XG4gICAgICAgIC8vXG4gICAgICAgIC8vICAgICBxdWVyeVJlbmRlcmVkRmVhdHVyZXMoZ2VvbWV0cnk6IFBvaW50TGlrZSB8IFtQb2ludExpa2UsIFBvaW50TGlrZV0sIG9wdGlvbnM/OiBPYmplY3QpXG4gICAgICAgIC8vICAgICBxdWVyeVJlbmRlcmVkRmVhdHVyZXMob3B0aW9ucz86IE9iamVjdClcbiAgICAgICAgLy9cbiAgICAgICAgLy8gVGhlcmUgbm8gd2F5IHRvIGV4cHJlc3MgdGhhdCBpbiBhIHdheSB0aGF0J3MgY29tcGF0aWJsZSB3aXRoIGJvdGggZmxvdyBhbmQgZG9jdW1lbnRhdGlvbi5qcy5cbiAgICAgICAgLy8gUmVsYXRlZDogaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL2Zsb3cvaXNzdWVzLzE1NTZcblxuICAgICAgICBpZiAoIXRoaXMuc3R5bGUpIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChvcHRpb25zID09PSB1bmRlZmluZWQgJiYgZ2VvbWV0cnkgIT09IHVuZGVmaW5lZCAmJiAhKGdlb21ldHJ5IGluc3RhbmNlb2YgUG9pbnQpICYmICFBcnJheS5pc0FycmF5KGdlb21ldHJ5KSkge1xuICAgICAgICAgICAgb3B0aW9ucyA9IChnZW9tZXRyeTogT2JqZWN0KTtcbiAgICAgICAgICAgIGdlb21ldHJ5ID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG5cbiAgICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gICAgICAgIGdlb21ldHJ5ID0gZ2VvbWV0cnkgfHwgWyhbMCwgMF06IFBvaW50TGlrZSksIChbdGhpcy50cmFuc2Zvcm0ud2lkdGgsIHRoaXMudHJhbnNmb3JtLmhlaWdodF06IFBvaW50TGlrZSldO1xuXG4gICAgICAgIHJldHVybiB0aGlzLnN0eWxlLnF1ZXJ5UmVuZGVyZWRGZWF0dXJlcyhnZW9tZXRyeSwgb3B0aW9ucywgdGhpcy50cmFuc2Zvcm0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgW0dlb0pTT05dKGh0dHA6Ly9nZW9qc29uLm9yZy8pXG4gICAgICogW0ZlYXR1cmUgb2JqZWN0c10oaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzc5NDYjc2VjdGlvbi0zLjIpXG4gICAgICogcmVwcmVzZW50aW5nIGZlYXR1cmVzIHdpdGhpbiB0aGUgc3BlY2lmaWVkIHZlY3RvciB0aWxlIG9yIEdlb0pTT04gc291cmNlIHRoYXQgc2F0aXNmeSB0aGUgcXVlcnkgcGFyYW1ldGVycy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2VJZCBUaGUgSUQgb2YgdGhlIHZlY3RvciB0aWxlIG9yIEdlb0pTT04gc291cmNlIHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbcGFyYW1ldGVyc10gT3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtwYXJhbWV0ZXJzLnNvdXJjZUxheWVyXSBUaGUgbmFtZSBvZiB0aGUgW3NvdXJjZSBsYXllcl0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vaGVscC9nbG9zc2FyeS9zb3VyY2UtbGF5ZXIvKVxuICAgICAqICAgdG8gcXVlcnkuICpGb3IgdmVjdG9yIHRpbGUgc291cmNlcywgdGhpcyBwYXJhbWV0ZXIgaXMgcmVxdWlyZWQuKiBGb3IgR2VvSlNPTiBzb3VyY2VzLCBpdCBpcyBpZ25vcmVkLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtwYXJhbWV0ZXJzLmZpbHRlcl0gQSBbZmlsdGVyXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvc3R5bGUtc3BlYy9sYXllcnMvI2ZpbHRlcilcbiAgICAgKiAgIHRvIGxpbWl0IHF1ZXJ5IHJlc3VsdHMuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbcGFyYW1ldGVycy52YWxpZGF0ZT10cnVlXSBXaGV0aGVyIHRvIGNoZWNrIGlmIHRoZSBbcGFyYW1ldGVycy5maWx0ZXJdIGNvbmZvcm1zIHRvIHRoZSBNYXBib3ggR0wgU3R5bGUgU3BlY2lmaWNhdGlvbi4gRGlzYWJsaW5nIHZhbGlkYXRpb24gaXMgYSBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb24gdGhhdCBzaG91bGQgb25seSBiZSB1c2VkIGlmIHlvdSBoYXZlIHByZXZpb3VzbHkgdmFsaWRhdGVkIHRoZSB2YWx1ZXMgeW91IHdpbGwgYmUgcGFzc2luZyB0byB0aGlzIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogQHJldHVybnMge0FycmF5PE9iamVjdD59IEFuIGFycmF5IG9mIFtHZW9KU09OXShodHRwOi8vZ2VvanNvbi5vcmcvKVxuICAgICAqIFtGZWF0dXJlIG9iamVjdHNdKGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM3OTQ2I3NlY3Rpb24tMy4yKS5cbiAgICAgKlxuICAgICAqIEluIGNvbnRyYXN0IHRvIHtAbGluayBNYXAjcXVlcnlSZW5kZXJlZEZlYXR1cmVzfSwgdGhpcyBmdW5jdGlvbiByZXR1cm5zIGFsbCBmZWF0dXJlcyBtYXRjaGluZyB0aGUgcXVlcnkgcGFyYW1ldGVycyxcbiAgICAgKiB3aGV0aGVyIG9yIG5vdCB0aGV5IGFyZSByZW5kZXJlZCBieSB0aGUgY3VycmVudCBzdHlsZSAoaW4gb3RoZXIgd29yZHMsIGFyZSB2aXNpYmxlKS4gVGhlIGRvbWFpbiBvZiB0aGUgcXVlcnkgaW5jbHVkZXMgYWxsIGN1cnJlbnRseS1sb2FkZWRcbiAgICAgKiB2ZWN0b3IgdGlsZXMgYW5kIEdlb0pTT04gc291cmNlIHRpbGVzOiB0aGlzIGZ1bmN0aW9uIGRvZXMgbm90IGNoZWNrIHRpbGVzIG91dHNpZGUgdGhlIGN1cnJlbnRseVxuICAgICAqIHZpc2libGUgdmlld3BvcnQuXG4gICAgICpcbiAgICAgKiBCZWNhdXNlIGZlYXR1cmVzIGNvbWUgZnJvbSB0aWxlZCB2ZWN0b3IgZGF0YSBvciBHZW9KU09OIGRhdGEgdGhhdCBpcyBjb252ZXJ0ZWQgdG8gdGlsZXMgaW50ZXJuYWxseSwgZmVhdHVyZVxuICAgICAqIGdlb21ldHJpZXMgbWF5IGJlIHNwbGl0IG9yIGR1cGxpY2F0ZWQgYWNyb3NzIHRpbGUgYm91bmRhcmllcyBhbmQsIGFzIGEgcmVzdWx0LCBmZWF0dXJlcyBtYXkgYXBwZWFyIG11bHRpcGxlXG4gICAgICogdGltZXMgaW4gcXVlcnkgcmVzdWx0cy4gRm9yIGV4YW1wbGUsIHN1cHBvc2UgdGhlcmUgaXMgYSBoaWdod2F5IHJ1bm5pbmcgdGhyb3VnaCB0aGUgYm91bmRpbmcgcmVjdGFuZ2xlIG9mIGEgcXVlcnkuXG4gICAgICogVGhlIHJlc3VsdHMgb2YgdGhlIHF1ZXJ5IHdpbGwgYmUgdGhvc2UgcGFydHMgb2YgdGhlIGhpZ2h3YXkgdGhhdCBsaWUgd2l0aGluIHRoZSBtYXAgdGlsZXMgY292ZXJpbmcgdGhlIGJvdW5kaW5nXG4gICAgICogcmVjdGFuZ2xlLCBldmVuIGlmIHRoZSBoaWdod2F5IGV4dGVuZHMgaW50byBvdGhlciB0aWxlcywgYW5kIHRoZSBwb3J0aW9uIG9mIHRoZSBoaWdod2F5IHdpdGhpbiBlYWNoIG1hcCB0aWxlXG4gICAgICogd2lsbCBiZSByZXR1cm5lZCBhcyBhIHNlcGFyYXRlIGZlYXR1cmUuIFNpbWlsYXJseSwgYSBwb2ludCBmZWF0dXJlIG5lYXIgYSB0aWxlIGJvdW5kYXJ5IG1heSBhcHBlYXIgaW4gbXVsdGlwbGVcbiAgICAgKiB0aWxlcyBkdWUgdG8gdGlsZSBidWZmZXJpbmcuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEZpbmQgYWxsIGZlYXR1cmVzIGluIG9uZSBzb3VyY2UgbGF5ZXIgaW4gYSB2ZWN0b3Igc291cmNlXG4gICAgICogY29uc3QgZmVhdHVyZXMgPSBtYXAucXVlcnlTb3VyY2VGZWF0dXJlcygneW91ci1zb3VyY2UtaWQnLCB7XG4gICAgICogICAgIHNvdXJjZUxheWVyOiAneW91ci1zb3VyY2UtbGF5ZXInXG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBIaWdobGlnaHQgZmVhdHVyZXMgY29udGFpbmluZyBzaW1pbGFyIGRhdGFdKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvcXVlcnktc2ltaWxhci1mZWF0dXJlcy8pXG4gICAgICovXG4gICAgcXVlcnlTb3VyY2VGZWF0dXJlcyhzb3VyY2VJZDogc3RyaW5nLCBwYXJhbWV0ZXJzOiA/e3NvdXJjZUxheWVyOiA/c3RyaW5nLCBmaWx0ZXI6ID9BcnJheTxhbnk+LCB2YWxpZGF0ZT86IGJvb2xlYW59KTogQXJyYXk8UXVlcnlGZWF0dXJlPiB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0eWxlLnF1ZXJ5U291cmNlRmVhdHVyZXMoc291cmNlSWQsIHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERldGVybWluZXMgaWYgdGhlIGdpdmVuIHBvaW50IGlzIGxvY2F0ZWQgb24gYSB2aXNpYmxlIG1hcCBzdXJmYWNlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtQb2ludExpa2V9IHBvaW50IC0gVGhlIHBvaW50IHRvIGJlIGNoZWNrZWQsIHNwZWNpZmllZCBhcyBhbiBhcnJheSBvZiB0d28gbnVtYmVycyByZXByZXNlbnRpbmcgdGhlIHggYW5kIHkgY29vcmRpbmF0ZXMsIG9yIGFzIGEge0BsaW5rIGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9hcGkvZ2VvZ3JhcGh5LyNwb2ludHxQb2ludH0gb2JqZWN0LlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgcG9pbnQgaXMgb24gdGhlIHZpc2libGUgbWFwIHN1cmZhY2UsIG90aGVyd2lzZSByZXR1cm5zIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwb2ludE9uU3VyZmFjZSA9IG1hcC5pc1BvaW50T25TdXJmYWNlKFsxMDAsIDIwMF0pO1xuICAgICAqL1xuICAgIGlzUG9pbnRPblN1cmZhY2UocG9pbnQ6IFBvaW50TGlrZSk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCB7bmFtZX0gPSB0aGlzLnRyYW5zZm9ybS5wcm9qZWN0aW9uO1xuICAgICAgICBpZiAobmFtZSAhPT0gJ2dsb2JlJyAmJiBuYW1lICE9PSAnbWVyY2F0b3InKSB7XG4gICAgICAgICAgICB3YXJuT25jZShgJHtuYW1lfSBwcm9qZWN0aW9uIGRvZXMgbm90IHN1cHBvcnQgaXNQb2ludE9uU3VyZmFjZSwgdGhpcyBBUEkgbWF5IGJlaGF2ZSB1bmV4cGVjdGVkbHkuYCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm0uaXNQb2ludE9uU3VyZmFjZShQb2ludC5jb252ZXJ0KHBvaW50KSk7XG4gICAgfVxuXG4gICAgLyoqIEBzZWN0aW9uIHtXb3JraW5nIHdpdGggc3R5bGVzfSAqL1xuXG4gICAgLyoqXG4gICAgICogVXBkYXRlcyB0aGUgbWFwJ3MgTWFwYm94IHN0eWxlIG9iamVjdCB3aXRoIGEgbmV3IHZhbHVlLlxuICAgICAqXG4gICAgICogSWYgYSBzdHlsZSBpcyBhbHJlYWR5IHNldCB3aGVuIHRoaXMgaXMgdXNlZCBhbmQgdGhlIGBkaWZmYCBvcHRpb24gaXMgc2V0IHRvIGB0cnVlYCwgdGhlIG1hcCByZW5kZXJlciB3aWxsIGF0dGVtcHQgdG8gY29tcGFyZSB0aGUgZ2l2ZW4gc3R5bGVcbiAgICAgKiBhZ2FpbnN0IHRoZSBtYXAncyBjdXJyZW50IHN0YXRlIGFuZCBwZXJmb3JtIG9ubHkgdGhlIGNoYW5nZXMgbmVjZXNzYXJ5IHRvIG1ha2UgdGhlIG1hcCBzdHlsZSBtYXRjaCB0aGUgZGVzaXJlZCBzdGF0ZS4gQ2hhbmdlcyBpbiBzcHJpdGVzXG4gICAgICogKGltYWdlcyB1c2VkIGZvciBpY29ucyBhbmQgcGF0dGVybnMpIGFuZCBnbHlwaHMgKGZvbnRzIGZvciBsYWJlbCB0ZXh0KSAqKmNhbm5vdCoqIGJlIGRpZmZlZC4gSWYgdGhlIHNwcml0ZXMgb3IgZm9udHMgdXNlZCBpbiB0aGUgY3VycmVudFxuICAgICAqIHN0eWxlIGFuZCB0aGUgZ2l2ZW4gc3R5bGUgYXJlIGRpZmZlcmVudCBpbiBhbnkgd2F5LCB0aGUgbWFwIHJlbmRlcmVyIHdpbGwgZm9yY2UgYSBmdWxsIHVwZGF0ZSwgcmVtb3ZpbmcgdGhlIGN1cnJlbnQgc3R5bGUgYW5kIGJ1aWxkaW5nXG4gICAgICogdGhlIGdpdmVuIG9uZSBmcm9tIHNjcmF0Y2guXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09iamVjdCB8IHN0cmluZ3wgbnVsbH0gc3R5bGUgQSBKU09OIG9iamVjdCBjb25mb3JtaW5nIHRvIHRoZSBzY2hlbWEgZGVzY3JpYmVkIGluIHRoZVxuICAgICAqICAgW01hcGJveCBTdHlsZSBTcGVjaWZpY2F0aW9uXShodHRwczovL21hcGJveC5jb20vbWFwYm94LWdsLXN0eWxlLXNwZWMvKSwgb3IgYSBVUkwgdG8gc3VjaCBKU09OLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gT3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5kaWZmPXRydWVdIElmIGZhbHNlLCBmb3JjZSBhICdmdWxsJyB1cGRhdGUsIHJlbW92aW5nIHRoZSBjdXJyZW50IHN0eWxlXG4gICAgICogICBhbmQgYnVpbGRpbmcgdGhlIGdpdmVuIG9uZSBpbnN0ZWFkIG9mIGF0dGVtcHRpbmcgYSBkaWZmLWJhc2VkIHVwZGF0ZS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdGlvbnMubG9jYWxJZGVvZ3JhcGhGb250RmFtaWx5PSdzYW5zLXNlcmlmJ10gRGVmaW5lcyBhIENTU1xuICAgICAqICAgZm9udC1mYW1pbHkgZm9yIGxvY2FsbHkgb3ZlcnJpZGluZyBnZW5lcmF0aW9uIG9mIGdseXBocyBpbiB0aGUgJ0NKSyBVbmlmaWVkIElkZW9ncmFwaHMnLCAnSGlyYWdhbmEnLCAnS2F0YWthbmEnIGFuZCAnSGFuZ3VsIFN5bGxhYmxlcycgcmFuZ2VzLlxuICAgICAqICAgSW4gdGhlc2UgcmFuZ2VzLCBmb250IHNldHRpbmdzIGZyb20gdGhlIG1hcCdzIHN0eWxlIHdpbGwgYmUgaWdub3JlZCwgZXhjZXB0IGZvciBmb250LXdlaWdodCBrZXl3b3JkcyAobGlnaHQvcmVndWxhci9tZWRpdW0vYm9sZCkuXG4gICAgICogICBTZXQgdG8gYGZhbHNlYCwgdG8gZW5hYmxlIGZvbnQgc2V0dGluZ3MgZnJvbSB0aGUgbWFwJ3Mgc3R5bGUgZm9yIHRoZXNlIGdseXBoIHJhbmdlcy5cbiAgICAgKiAgIEZvcmNlcyBhIGZ1bGwgdXBkYXRlLlxuICAgICAqIEByZXR1cm5zIHtNYXB9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIG1hcC5zZXRTdHlsZShcIm1hcGJveDovL3N0eWxlcy9tYXBib3gvc3RyZWV0cy12MTFcIik7XG4gICAgICpcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBDaGFuZ2UgYSBtYXAncyBzdHlsZV0oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9zZXRzdHlsZS8pXG4gICAgICovXG4gICAgc2V0U3R5bGUoc3R5bGU6IFN0eWxlU3BlY2lmaWNhdGlvbiB8IHN0cmluZyB8IG51bGwsIG9wdGlvbnM/OiB7ZGlmZj86IGJvb2xlYW59ICYgU3R5bGVPcHRpb25zKTogdGhpcyB7XG4gICAgICAgIG9wdGlvbnMgPSBleHRlbmQoe30sIHtsb2NhbElkZW9ncmFwaEZvbnRGYW1pbHk6IHRoaXMuX2xvY2FsSWRlb2dyYXBoRm9udEZhbWlseSwgbG9jYWxGb250RmFtaWx5OiB0aGlzLl9sb2NhbEZvbnRGYW1pbHl9LCBvcHRpb25zKTtcblxuICAgICAgICBpZiAoKG9wdGlvbnMuZGlmZiAhPT0gZmFsc2UgJiZcbiAgICAgICAgICAgIG9wdGlvbnMubG9jYWxJZGVvZ3JhcGhGb250RmFtaWx5ID09PSB0aGlzLl9sb2NhbElkZW9ncmFwaEZvbnRGYW1pbHkgJiZcbiAgICAgICAgICAgIG9wdGlvbnMubG9jYWxGb250RmFtaWx5ID09PSB0aGlzLl9sb2NhbEZvbnRGYW1pbHkpICYmIHRoaXMuc3R5bGUgJiYgc3R5bGUpIHtcbiAgICAgICAgICAgIHRoaXMuX2RpZmZTdHlsZShzdHlsZSwgb3B0aW9ucyk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2xvY2FsSWRlb2dyYXBoRm9udEZhbWlseSA9IG9wdGlvbnMubG9jYWxJZGVvZ3JhcGhGb250RmFtaWx5O1xuICAgICAgICAgICAgdGhpcy5fbG9jYWxGb250RmFtaWx5ID0gb3B0aW9ucy5sb2NhbEZvbnRGYW1pbHk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdXBkYXRlU3R5bGUoc3R5bGUsIG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX2dldFVJU3RyaW5nKGtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgY29uc3Qgc3RyID0gdGhpcy5fbG9jYWxlW2tleV07XG4gICAgICAgIGlmIChzdHIgPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBNaXNzaW5nIFVJIHN0cmluZyAnJHtrZXl9J2ApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG5cbiAgICBfdXBkYXRlU3R5bGUoc3R5bGU6IFN0eWxlU3BlY2lmaWNhdGlvbiB8IHN0cmluZyB8IG51bGwsICBvcHRpb25zPzoge2RpZmY/OiBib29sZWFufSAmIFN0eWxlT3B0aW9ucyk6IHRoaXMge1xuICAgICAgICBpZiAodGhpcy5zdHlsZSkge1xuICAgICAgICAgICAgdGhpcy5zdHlsZS5zZXRFdmVudGVkUGFyZW50KG51bGwpO1xuICAgICAgICAgICAgdGhpcy5zdHlsZS5fcmVtb3ZlKCk7XG4gICAgICAgICAgICB0aGlzLnN0eWxlID0gKHVuZGVmaW5lZDogYW55KTsgLy8gd2UgbGF6eS1pbml0IGl0IHNvIGl0J3MgbmV2ZXIgdW5kZWZpbmVkIHdoZW4gYWNjZXNzZWRcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzdHlsZSkge1xuICAgICAgICAgICAgdGhpcy5zdHlsZSA9IG5ldyBTdHlsZSh0aGlzLCBvcHRpb25zIHx8IHt9KTtcbiAgICAgICAgICAgIHRoaXMuc3R5bGUuc2V0RXZlbnRlZFBhcmVudCh0aGlzLCB7c3R5bGU6IHRoaXMuc3R5bGV9KTtcblxuICAgICAgICAgICAgaWYgKHR5cGVvZiBzdHlsZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0eWxlLmxvYWRVUkwoc3R5bGUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0eWxlLmxvYWRKU09OKHN0eWxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLl91cGRhdGVUZXJyYWluKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIF9sYXp5SW5pdEVtcHR5U3R5bGUoKSB7XG4gICAgICAgIGlmICghdGhpcy5zdHlsZSkge1xuICAgICAgICAgICAgdGhpcy5zdHlsZSA9IG5ldyBTdHlsZSh0aGlzLCB7fSk7XG4gICAgICAgICAgICB0aGlzLnN0eWxlLnNldEV2ZW50ZWRQYXJlbnQodGhpcywge3N0eWxlOiB0aGlzLnN0eWxlfSk7XG4gICAgICAgICAgICB0aGlzLnN0eWxlLmxvYWRFbXB0eSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX2RpZmZTdHlsZShzdHlsZTogU3R5bGVTcGVjaWZpY2F0aW9uIHwgc3RyaW5nLCAgb3B0aW9ucz86IHtkaWZmPzogYm9vbGVhbn0gJiBTdHlsZU9wdGlvbnMpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBzdHlsZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHRoaXMuX3JlcXVlc3RNYW5hZ2VyLm5vcm1hbGl6ZVN0eWxlVVJMKHN0eWxlKTtcbiAgICAgICAgICAgIGNvbnN0IHJlcXVlc3QgPSB0aGlzLl9yZXF1ZXN0TWFuYWdlci50cmFuc2Zvcm1SZXF1ZXN0KHVybCwgUmVzb3VyY2VUeXBlLlN0eWxlKTtcbiAgICAgICAgICAgIGdldEpTT04ocmVxdWVzdCwgKGVycm9yOiA/RXJyb3IsIGpzb246ID9PYmplY3QpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFcnJvckV2ZW50KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChqc29uKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZURpZmYoanNvbiwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHN0eWxlID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgdGhpcy5fdXBkYXRlRGlmZihzdHlsZSwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfdXBkYXRlRGlmZihzdHlsZTogU3R5bGVTcGVjaWZpY2F0aW9uLCAgb3B0aW9ucz86IHtkaWZmPzogYm9vbGVhbn0gJiBTdHlsZU9wdGlvbnMpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0eWxlLnNldFN0YXRlKHN0eWxlKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZSh0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgd2Fybk9uY2UoXG4gICAgICAgICAgICAgICAgYFVuYWJsZSB0byBwZXJmb3JtIHN0eWxlIGRpZmY6ICR7ZS5tZXNzYWdlIHx8IGUuZXJyb3IgfHwgZX0uICBSZWJ1aWxkaW5nIHRoZSBzdHlsZSBmcm9tIHNjcmF0Y2guYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZVN0eWxlKHN0eWxlLCBvcHRpb25zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIG1hcCdzIE1hcGJveCBbc3R5bGVdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL2hlbHAvZ2xvc3Nhcnkvc3R5bGUvKSBvYmplY3QsIGEgSlNPTiBvYmplY3Qgd2hpY2ggY2FuIGJlIHVzZWQgdG8gcmVjcmVhdGUgdGhlIG1hcCdzIHN0eWxlLlxuICAgICAqXG4gICAgICogQHJldHVybnMge09iamVjdH0gVGhlIG1hcCdzIHN0eWxlIEpTT04gb2JqZWN0LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAub24oJ2xvYWQnLCAoKSA9PiB7XG4gICAgICogICAgIGNvbnN0IHN0eWxlSnNvbiA9IG1hcC5nZXRTdHlsZSgpO1xuICAgICAqIH0pO1xuICAgICAqXG4gICAgICovXG4gICAgZ2V0U3R5bGUoKTogP1N0eWxlU3BlY2lmaWNhdGlvbiB7XG4gICAgICAgIGlmICh0aGlzLnN0eWxlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zdHlsZS5zZXJpYWxpemUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBCb29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGUgbWFwJ3Mgc3R5bGUgaXMgZnVsbHkgbG9hZGVkLlxuICAgICAqXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IEEgQm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIHN0eWxlIGlzIGZ1bGx5IGxvYWRlZC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgc3R5bGVMb2FkU3RhdHVzID0gbWFwLmlzU3R5bGVMb2FkZWQoKTtcbiAgICAgKi9cbiAgICBpc1N0eWxlTG9hZGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAoIXRoaXMuc3R5bGUpIHtcbiAgICAgICAgICAgIHdhcm5PbmNlKCdUaGVyZSBpcyBubyBzdHlsZSBhZGRlZCB0byB0aGUgbWFwLicpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnN0eWxlLmxvYWRlZCgpO1xuICAgIH1cblxuICAgIC8qKiBAc2VjdGlvbiB7U291cmNlc30gKi9cblxuICAgIC8qKlxuICAgICAqIEFkZHMgYSBzb3VyY2UgdG8gdGhlIG1hcCdzIHN0eWxlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGlkIFRoZSBJRCBvZiB0aGUgc291cmNlIHRvIGFkZC4gTXVzdCBub3QgY29uZmxpY3Qgd2l0aCBleGlzdGluZyBzb3VyY2VzLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIHNvdXJjZSBvYmplY3QsIGNvbmZvcm1pbmcgdG8gdGhlXG4gICAgICogTWFwYm94IFN0eWxlIFNwZWNpZmljYXRpb24ncyBbc291cmNlIGRlZmluaXRpb25dKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLXN0eWxlLXNwZWMvI3NvdXJjZXMpIG9yXG4gICAgICoge0BsaW5rIENhbnZhc1NvdXJjZU9wdGlvbnN9LlxuICAgICAqIEByZXR1cm5zIHtNYXB9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAuYWRkU291cmNlKCdteS1kYXRhJywge1xuICAgICAqICAgICB0eXBlOiAndmVjdG9yJyxcbiAgICAgKiAgICAgdXJsOiAnbWFwYm94Oi8vbXl1c2VybmFtZS50aWxlc2V0aWQnXG4gICAgICogfSk7XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAuYWRkU291cmNlKCdteS1kYXRhJywge1xuICAgICAqICAgICBcInR5cGVcIjogXCJnZW9qc29uXCIsXG4gICAgICogICAgIFwiZGF0YVwiOiB7XG4gICAgICogICAgICAgICBcInR5cGVcIjogXCJGZWF0dXJlXCIsXG4gICAgICogICAgICAgICBcImdlb21ldHJ5XCI6IHtcbiAgICAgKiAgICAgICAgICAgICBcInR5cGVcIjogXCJQb2ludFwiLFxuICAgICAqICAgICAgICAgICAgIFwiY29vcmRpbmF0ZXNcIjogWy03Ny4wMzIzLCAzOC45MTMxXVxuICAgICAqICAgICAgICAgfSxcbiAgICAgKiAgICAgICAgIFwicHJvcGVydGllc1wiOiB7XG4gICAgICogICAgICAgICAgICAgXCJ0aXRsZVwiOiBcIk1hcGJveCBEQ1wiLFxuICAgICAqICAgICAgICAgICAgIFwibWFya2VyLXN5bWJvbFwiOiBcIm1vbnVtZW50XCJcbiAgICAgKiAgICAgICAgIH1cbiAgICAgKiAgICAgfVxuICAgICAqIH0pO1xuICAgICAqIEBzZWUgRXhhbXBsZTogVmVjdG9yIHNvdXJjZTogW1Nob3cgYW5kIGhpZGUgbGF5ZXJzXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS90b2dnbGUtbGF5ZXJzLylcbiAgICAgKiBAc2VlIEV4YW1wbGU6IEdlb0pTT04gc291cmNlOiBbQWRkIGxpdmUgcmVhbHRpbWUgZGF0YV0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvbGl2ZS1nZW9qc29uLylcbiAgICAgKiBAc2VlIEV4YW1wbGU6IFJhc3RlciBERU0gc291cmNlOiBbQWRkIGhpbGxzaGFkaW5nXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9oaWxsc2hhZGUvKVxuICAgICAqL1xuICAgIGFkZFNvdXJjZShpZDogc3RyaW5nLCBzb3VyY2U6IFNvdXJjZVNwZWNpZmljYXRpb24pOiB0aGlzIHtcbiAgICAgICAgdGhpcy5fbGF6eUluaXRFbXB0eVN0eWxlKCk7XG4gICAgICAgIHRoaXMuc3R5bGUuYWRkU291cmNlKGlkLCBzb3VyY2UpO1xuICAgICAgICByZXR1cm4gdGhpcy5fdXBkYXRlKHRydWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBCb29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGUgc291cmNlIGlzIGxvYWRlZC4gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHNvdXJjZSB3aXRoXG4gICAgICogdGhlIGdpdmVuIElEIGluIHRoZSBtYXAncyBzdHlsZSBoYXMgbm8gb3V0c3RhbmRpbmcgbmV0d29yayByZXF1ZXN0cywgb3RoZXJ3aXNlIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgVGhlIElEIG9mIHRoZSBzb3VyY2UgdG8gYmUgY2hlY2tlZC5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gQSBCb29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGUgc291cmNlIGlzIGxvYWRlZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHNvdXJjZUxvYWRlZCA9IG1hcC5pc1NvdXJjZUxvYWRlZCgnYmF0aHltZXRyeS1kYXRhJyk7XG4gICAgICovXG4gICAgaXNTb3VyY2VMb2FkZWQoaWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gISF0aGlzLnN0eWxlICYmIHRoaXMuc3R5bGUuX2lzU291cmNlQ2FjaGVMb2FkZWQoaWQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBCb29sZWFuIGluZGljYXRpbmcgd2hldGhlciBhbGwgdGlsZXMgaW4gdGhlIHZpZXdwb3J0IGZyb20gYWxsIHNvdXJjZXMgb25cbiAgICAgKiB0aGUgc3R5bGUgYXJlIGxvYWRlZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBBIEJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIGFsbCB0aWxlcyBhcmUgbG9hZGVkLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgdGlsZXNMb2FkZWQgPSBtYXAuYXJlVGlsZXNMb2FkZWQoKTtcbiAgICAgKi9cblxuICAgIGFyZVRpbGVzTG9hZGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCBzb3VyY2VzID0gdGhpcy5zdHlsZSAmJiB0aGlzLnN0eWxlLl9zb3VyY2VDYWNoZXM7XG4gICAgICAgIGZvciAoY29uc3QgaWQgaW4gc291cmNlcykge1xuICAgICAgICAgICAgY29uc3Qgc291cmNlID0gc291cmNlc1tpZF07XG4gICAgICAgICAgICBjb25zdCB0aWxlcyA9IHNvdXJjZS5fdGlsZXM7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHQgaW4gdGlsZXMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0aWxlID0gdGlsZXNbdF07XG4gICAgICAgICAgICAgICAgaWYgKCEodGlsZS5zdGF0ZSA9PT0gJ2xvYWRlZCcgfHwgdGlsZS5zdGF0ZSA9PT0gJ2Vycm9yZWQnKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZHMgYSBbY3VzdG9tIHNvdXJjZSB0eXBlXSgjQ3VzdG9tIFNvdXJjZXMpLCBtYWtpbmcgaXQgYXZhaWxhYmxlIGZvciB1c2Ugd2l0aFxuICAgICAqIHtAbGluayBNYXAjYWRkU291cmNlfS5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBzb3VyY2UgdHlwZTsgc291cmNlIGRlZmluaXRpb24gb2JqZWN0cyB1c2UgdGhpcyBuYW1lIGluIHRoZSBge3R5cGU6IC4uLn1gIGZpZWxkLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFNvdXJjZVR5cGUgQSB7QGxpbmsgU291cmNlfSBjb25zdHJ1Y3Rvci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBDYWxsZWQgd2hlbiB0aGUgc291cmNlIHR5cGUgaXMgcmVhZHkgb3Igd2l0aCBhbiBlcnJvciBhcmd1bWVudCBpZiB0aGVyZSBpcyBhbiBlcnJvci5cbiAgICAgKi9cbiAgICBhZGRTb3VyY2VUeXBlKG5hbWU6IHN0cmluZywgU291cmNlVHlwZTogYW55LCBjYWxsYmFjazogRnVuY3Rpb24pIHtcbiAgICAgICAgdGhpcy5fbGF6eUluaXRFbXB0eVN0eWxlKCk7XG4gICAgICAgIHRoaXMuc3R5bGUuYWRkU291cmNlVHlwZShuYW1lLCBTb3VyY2VUeXBlLCBjYWxsYmFjayk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhIHNvdXJjZSBmcm9tIHRoZSBtYXAncyBzdHlsZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBpZCBUaGUgSUQgb2YgdGhlIHNvdXJjZSB0byByZW1vdmUuXG4gICAgICogQHJldHVybnMge01hcH0gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIG1hcC5yZW1vdmVTb3VyY2UoJ2JhdGh5bWV0cnktZGF0YScpO1xuICAgICAqL1xuICAgIHJlbW92ZVNvdXJjZShpZDogc3RyaW5nKTogdGhpcyB7XG4gICAgICAgIHRoaXMuc3R5bGUucmVtb3ZlU291cmNlKGlkKTtcbiAgICAgICAgdGhpcy5fdXBkYXRlVGVycmFpbigpO1xuICAgICAgICByZXR1cm4gdGhpcy5fdXBkYXRlKHRydWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHNvdXJjZSB3aXRoIHRoZSBzcGVjaWZpZWQgSUQgaW4gdGhlIG1hcCdzIHN0eWxlLlxuICAgICAqXG4gICAgICogVGhpcyBtZXRob2QgaXMgb2Z0ZW4gdXNlZCB0byB1cGRhdGUgYSBzb3VyY2UgdXNpbmcgdGhlIGluc3RhbmNlIG1lbWJlcnMgZm9yIHRoZSByZWxldmFudFxuICAgICAqIHNvdXJjZSB0eXBlIGFzIGRlZmluZWQgaW4gW1NvdXJjZXNdKCNzb3VyY2VzKS5cbiAgICAgKiBGb3IgZXhhbXBsZSwgc2V0dGluZyB0aGUgYGRhdGFgIGZvciBhIEdlb0pTT04gc291cmNlIG9yIHVwZGF0aW5nIHRoZSBgdXJsYCBhbmQgYGNvb3JkaW5hdGVzYFxuICAgICAqIG9mIGFuIGltYWdlIHNvdXJjZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBpZCBUaGUgSUQgb2YgdGhlIHNvdXJjZSB0byBnZXQuXG4gICAgICogQHJldHVybnMgez9PYmplY3R9IFRoZSBzdHlsZSBzb3VyY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIElEIG9yIGB1bmRlZmluZWRgIGlmIHRoZSBJRFxuICAgICAqIGNvcnJlc3BvbmRzIHRvIG5vIGV4aXN0aW5nIHNvdXJjZXMuXG4gICAgICogVGhlIHNoYXBlIG9mIHRoZSBvYmplY3QgdmFyaWVzIGJ5IHNvdXJjZSB0eXBlLlxuICAgICAqIEEgbGlzdCBvZiBvcHRpb25zIGZvciBlYWNoIHNvdXJjZSB0eXBlIGlzIGF2YWlsYWJsZSBvbiB0aGUgTWFwYm94IFN0eWxlIFNwZWNpZmljYXRpb24nc1xuICAgICAqIFtTb3VyY2VzXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvc3R5bGUtc3BlYy9zb3VyY2VzLykgcGFnZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHNvdXJjZU9iamVjdCA9IG1hcC5nZXRTb3VyY2UoJ3BvaW50cycpO1xuICAgICAqIEBzZWUgW0V4YW1wbGU6IENyZWF0ZSBhIGRyYWdnYWJsZSBwb2ludF0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvZHJhZy1hLXBvaW50LylcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBBbmltYXRlIGEgcG9pbnRdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2FuaW1hdGUtcG9pbnQtYWxvbmctbGluZS8pXG4gICAgICogQHNlZSBbRXhhbXBsZTogQWRkIGxpdmUgcmVhbHRpbWUgZGF0YV0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvbGl2ZS1nZW9qc29uLylcbiAgICAgKi9cbiAgICBnZXRTb3VyY2UoaWQ6IHN0cmluZyk6ID9Tb3VyY2Uge1xuICAgICAgICByZXR1cm4gdGhpcy5zdHlsZS5nZXRTb3VyY2UoaWQpO1xuICAgIH1cblxuICAgIC8qKiBAc2VjdGlvbiB7SW1hZ2VzfSAqL1xuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtcmV0dXJuc1xuICAgIC8qKlxuICAgICAqIEFkZCBhbiBpbWFnZSB0byB0aGUgc3R5bGUuIFRoaXMgaW1hZ2UgY2FuIGJlIGRpc3BsYXllZCBvbiB0aGUgbWFwIGxpa2UgYW55IG90aGVyIGljb24gaW4gdGhlIHN0eWxlJ3NcbiAgICAgKiBbc3ByaXRlXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvc3R5bGUtc3BlYy9zcHJpdGUvKSB1c2luZyB0aGUgaW1hZ2UncyBJRCB3aXRoXG4gICAgICogW2BpY29uLWltYWdlYF0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL3N0eWxlLXNwZWMvI2xheW91dC1zeW1ib2wtaWNvbi1pbWFnZSksXG4gICAgICogW2BiYWNrZ3JvdW5kLXBhdHRlcm5gXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvc3R5bGUtc3BlYy8jcGFpbnQtYmFja2dyb3VuZC1iYWNrZ3JvdW5kLXBhdHRlcm4pLFxuICAgICAqIFtgZmlsbC1wYXR0ZXJuYF0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL3N0eWxlLXNwZWMvI3BhaW50LWZpbGwtZmlsbC1wYXR0ZXJuKSxcbiAgICAgKiBvciBbYGxpbmUtcGF0dGVybmBdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9zdHlsZS1zcGVjLyNwYWludC1saW5lLWxpbmUtcGF0dGVybikuXG4gICAgICogQSB7QGxpbmsgTWFwLmV2ZW50OmVycm9yfSBldmVudCB3aWxsIGJlIGZpcmVkIGlmIHRoZXJlIGlzIG5vdCBlbm91Z2ggc3BhY2UgaW4gdGhlIHNwcml0ZSB0byBhZGQgdGhpcyBpbWFnZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBpZCBUaGUgSUQgb2YgdGhlIGltYWdlLlxuICAgICAqIEBwYXJhbSB7SFRNTEltYWdlRWxlbWVudCB8IEltYWdlQml0bWFwIHwgSW1hZ2VEYXRhIHwge3dpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyLCBkYXRhOiAoVWludDhBcnJheSB8IFVpbnQ4Q2xhbXBlZEFycmF5KX0gfCBTdHlsZUltYWdlSW50ZXJmYWNlfSBpbWFnZSBUaGUgaW1hZ2UgYXMgYW4gYEhUTUxJbWFnZUVsZW1lbnRgLCBgSW1hZ2VEYXRhYCwgYEltYWdlQml0bWFwYCBvciBvYmplY3Qgd2l0aCBgd2lkdGhgLCBgaGVpZ2h0YCwgYW5kIGBkYXRhYFxuICAgICAqIHByb3BlcnRpZXMgd2l0aCB0aGUgc2FtZSBmb3JtYXQgYXMgYEltYWdlRGF0YWAuXG4gICAgICogQHBhcmFtIHtPYmplY3QgfCBudWxsfSBvcHRpb25zIE9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBvcHRpb25zLnBpeGVsUmF0aW8gVGhlIHJhdGlvIG9mIHBpeGVscyBpbiB0aGUgaW1hZ2UgdG8gcGh5c2ljYWwgcGl4ZWxzIG9uIHRoZSBzY3JlZW4uXG4gICAgICogQHBhcmFtIHtib29sZWFufSBvcHRpb25zLnNkZiBXaGV0aGVyIHRoZSBpbWFnZSBzaG91bGQgYmUgaW50ZXJwcmV0ZWQgYXMgYW4gU0RGIGltYWdlLlxuICAgICAqIEBwYXJhbSB7W251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl19IG9wdGlvbnMuY29udGVudCBgW3gxLCB5MSwgeDIsIHkyXWAgIElmIGBpY29uLXRleHQtZml0YCBpcyB1c2VkIGluIGEgbGF5ZXIgd2l0aCB0aGlzIGltYWdlLCB0aGlzIG9wdGlvbiBkZWZpbmVzIHRoZSBwYXJ0IG9mIHRoZSBpbWFnZSB0aGF0IGNhbiBiZSBjb3ZlcmVkIGJ5IHRoZSBjb250ZW50IGluIGB0ZXh0LWZpZWxkYC5cbiAgICAgKiBAcGFyYW0ge0FycmF5PFtudW1iZXIsIG51bWJlcl0+fSBvcHRpb25zLnN0cmV0Y2hYIGBbW3gxLCB4Ml0sIC4uLl1gIElmIGBpY29uLXRleHQtZml0YCBpcyB1c2VkIGluIGEgbGF5ZXIgd2l0aCB0aGlzIGltYWdlLCB0aGlzIG9wdGlvbiBkZWZpbmVzIHRoZSBwYXJ0KHMpIG9mIHRoZSBpbWFnZSB0aGF0IGNhbiBiZSBzdHJldGNoZWQgaG9yaXpvbnRhbGx5LlxuICAgICAqIEBwYXJhbSB7QXJyYXk8W251bWJlciwgbnVtYmVyXT59IG9wdGlvbnMuc3RyZXRjaFkgYFtbeTEsIHkyXSwgLi4uXWAgSWYgYGljb24tdGV4dC1maXRgIGlzIHVzZWQgaW4gYSBsYXllciB3aXRoIHRoaXMgaW1hZ2UsIHRoaXMgb3B0aW9uIGRlZmluZXMgdGhlIHBhcnQocykgb2YgdGhlIGltYWdlIHRoYXQgY2FuIGJlIHN0cmV0Y2hlZCB2ZXJ0aWNhbGx5LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBJZiB0aGUgc3R5bGUncyBzcHJpdGUgZG9lcyBub3QgYWxyZWFkeSBjb250YWluIGFuIGltYWdlIHdpdGggSUQgJ2NhdCcsXG4gICAgICogLy8gYWRkIHRoZSBpbWFnZSAnY2F0LWljb24ucG5nJyB0byB0aGUgc3R5bGUncyBzcHJpdGUgd2l0aCB0aGUgSUQgJ2NhdCcuXG4gICAgICogbWFwLmxvYWRJbWFnZSgnaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy90aHVtYi82LzYwL0NhdF9zaWxob3VldHRlLnN2Zy80MDBweC1DYXRfc2lsaG91ZXR0ZS5zdmcucG5nJywgKGVycm9yLCBpbWFnZSkgPT4ge1xuICAgICAqICAgICBpZiAoZXJyb3IpIHRocm93IGVycm9yO1xuICAgICAqICAgICBpZiAoIW1hcC5oYXNJbWFnZSgnY2F0JykpIG1hcC5hZGRJbWFnZSgnY2F0JywgaW1hZ2UpO1xuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogLy8gQWRkIGEgc3RyZXRjaGFibGUgaW1hZ2UgdGhhdCBjYW4gYmUgdXNlZCB3aXRoIGBpY29uLXRleHQtZml0YFxuICAgICAqIC8vIEluIHRoaXMgZXhhbXBsZSwgdGhlIGltYWdlIGlzIDYwMHB4IHdpZGUgYnkgNDAwcHggaGlnaC5cbiAgICAgKiBtYXAubG9hZEltYWdlKCdodHRwczovL3VwbG9hZC53aWtpbWVkaWEub3JnL3dpa2lwZWRpYS9jb21tb25zLzgvODkvQmxhY2tfYW5kX1doaXRlX0JveGVkXyUyOGJvcmRlcmVkJTI5LnBuZycsIChlcnJvciwgaW1hZ2UpID0+IHtcbiAgICAgKiAgICAgaWYgKGVycm9yKSB0aHJvdyBlcnJvcjtcbiAgICAgKiAgICAgaWYgKCFtYXAuaGFzSW1hZ2UoJ2JvcmRlci1pbWFnZScpKSB7XG4gICAgICogICAgICAgICBtYXAuYWRkSW1hZ2UoJ2JvcmRlci1pbWFnZScsIGltYWdlLCB7XG4gICAgICogICAgICAgICAgICAgY29udGVudDogWzE2LCAxNiwgMzAwLCAzODRdLCAvLyBwbGFjZSB0ZXh0IG92ZXIgbGVmdCBoYWxmIG9mIGltYWdlLCBhdm9pZGluZyB0aGUgMTZweCBib3JkZXJcbiAgICAgKiAgICAgICAgICAgICBzdHJldGNoWDogW1sxNiwgNTg0XV0sIC8vIHN0cmV0Y2ggZXZlcnl0aGluZyBob3Jpem9udGFsbHkgZXhjZXB0IHRoZSAxNnB4IGJvcmRlclxuICAgICAqICAgICAgICAgICAgIHN0cmV0Y2hZOiBbWzE2LCAzODRdXSwgLy8gc3RyZXRjaCBldmVyeXRoaW5nIHZlcnRpY2FsbHkgZXhjZXB0IHRoZSAxNnB4IGJvcmRlclxuICAgICAqICAgICAgICAgfSk7XG4gICAgICogICAgIH1cbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqXG4gICAgICogQHNlZSBFeGFtcGxlOiBVc2UgYEhUTUxJbWFnZUVsZW1lbnRgOiBbQWRkIGFuIGljb24gdG8gdGhlIG1hcF0oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9hZGQtaW1hZ2UvKVxuICAgICAqIEBzZWUgRXhhbXBsZTogVXNlIGBJbWFnZURhdGFgOiBbQWRkIGEgZ2VuZXJhdGVkIGljb24gdG8gdGhlIG1hcF0oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9hZGQtaW1hZ2UtZ2VuZXJhdGVkLylcbiAgICAgKi9cbiAgICBhZGRJbWFnZShpZDogc3RyaW5nLFxuICAgICAgICAgICAgIGltYWdlOiBIVE1MSW1hZ2VFbGVtZW50IHwgSW1hZ2VCaXRtYXAgfCBJbWFnZURhdGEgfCB7d2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIsIGRhdGE6IFVpbnQ4QXJyYXkgfCBVaW50OENsYW1wZWRBcnJheX0gfCBTdHlsZUltYWdlSW50ZXJmYWNlLFxuICAgICAgICAgICAgIHtwaXhlbFJhdGlvID0gMSwgc2RmID0gZmFsc2UsIHN0cmV0Y2hYLCBzdHJldGNoWSwgY29udGVudH06ICRTaGFwZTxTdHlsZUltYWdlTWV0YWRhdGE+ID0ge30pIHtcbiAgICAgICAgdGhpcy5fbGF6eUluaXRFbXB0eVN0eWxlKCk7XG4gICAgICAgIGNvbnN0IHZlcnNpb24gPSAwO1xuXG4gICAgICAgIGlmIChpbWFnZSBpbnN0YW5jZW9mIHdpbmRvdy5IVE1MSW1hZ2VFbGVtZW50IHx8ICh3aW5kb3cuSW1hZ2VCaXRtYXAgJiYgaW1hZ2UgaW5zdGFuY2VvZiB3aW5kb3cuSW1hZ2VCaXRtYXApKSB7XG4gICAgICAgICAgICBjb25zdCB7d2lkdGgsIGhlaWdodCwgZGF0YX0gPSBicm93c2VyLmdldEltYWdlRGF0YShpbWFnZSk7XG4gICAgICAgICAgICB0aGlzLnN0eWxlLmFkZEltYWdlKGlkLCB7ZGF0YTogbmV3IFJHQkFJbWFnZSh7d2lkdGgsIGhlaWdodH0sIGRhdGEpLCBwaXhlbFJhdGlvLCBzdHJldGNoWCwgc3RyZXRjaFksIGNvbnRlbnQsIHNkZiwgdmVyc2lvbn0pO1xuICAgICAgICB9IGVsc2UgaWYgKGltYWdlLndpZHRoID09PSB1bmRlZmluZWQgfHwgaW1hZ2UuaGVpZ2h0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXJyb3JFdmVudChuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgJ0ludmFsaWQgYXJndW1lbnRzIHRvIG1hcC5hZGRJbWFnZSgpLiBUaGUgc2Vjb25kIGFyZ3VtZW50IG11c3QgYmUgYW4gYEhUTUxJbWFnZUVsZW1lbnRgLCBgSW1hZ2VEYXRhYCwgYEltYWdlQml0bWFwYCwgJyArXG4gICAgICAgICAgICAgICAgJ29yIG9iamVjdCB3aXRoIGB3aWR0aGAsIGBoZWlnaHRgLCBhbmQgYGRhdGFgIHByb3BlcnRpZXMgd2l0aCB0aGUgc2FtZSBmb3JtYXQgYXMgYEltYWdlRGF0YWAnKSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qge3dpZHRoLCBoZWlnaHR9ID0gaW1hZ2U7XG4gICAgICAgICAgICBjb25zdCB1c2VySW1hZ2UgPSAoKGltYWdlOiBhbnkpOiBTdHlsZUltYWdlSW50ZXJmYWNlKTtcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgPSB1c2VySW1hZ2UuZGF0YTtcblxuICAgICAgICAgICAgdGhpcy5zdHlsZS5hZGRJbWFnZShpZCwge1xuICAgICAgICAgICAgICAgIGRhdGE6IG5ldyBSR0JBSW1hZ2Uoe3dpZHRoLCBoZWlnaHR9LCBuZXcgVWludDhBcnJheShkYXRhKSksXG4gICAgICAgICAgICAgICAgcGl4ZWxSYXRpbyxcbiAgICAgICAgICAgICAgICBzdHJldGNoWCxcbiAgICAgICAgICAgICAgICBzdHJldGNoWSxcbiAgICAgICAgICAgICAgICBjb250ZW50LFxuICAgICAgICAgICAgICAgIHNkZixcbiAgICAgICAgICAgICAgICB2ZXJzaW9uLFxuICAgICAgICAgICAgICAgIHVzZXJJbWFnZVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmICh1c2VySW1hZ2Uub25BZGQpIHtcbiAgICAgICAgICAgICAgICB1c2VySW1hZ2Uub25BZGQodGhpcywgaWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtcmV0dXJuc1xuICAgIC8qKlxuICAgICAqIFVwZGF0ZSBhbiBleGlzdGluZyBpbWFnZSBpbiBhIHN0eWxlLiBUaGlzIGltYWdlIGNhbiBiZSBkaXNwbGF5ZWQgb24gdGhlIG1hcCBsaWtlIGFueSBvdGhlciBpY29uIGluIHRoZSBzdHlsZSdzXG4gICAgICogW3Nwcml0ZV0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vaGVscC9nbG9zc2FyeS9zcHJpdGUvKSB1c2luZyB0aGUgaW1hZ2UncyBJRCB3aXRoXG4gICAgICogW2BpY29uLWltYWdlYF0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL3N0eWxlLXNwZWMvI2xheW91dC1zeW1ib2wtaWNvbi1pbWFnZSksXG4gICAgICogW2BiYWNrZ3JvdW5kLXBhdHRlcm5gXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvc3R5bGUtc3BlYy8jcGFpbnQtYmFja2dyb3VuZC1iYWNrZ3JvdW5kLXBhdHRlcm4pLFxuICAgICAqIFtgZmlsbC1wYXR0ZXJuYF0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL3N0eWxlLXNwZWMvI3BhaW50LWZpbGwtZmlsbC1wYXR0ZXJuKSxcbiAgICAgKiBvciBbYGxpbmUtcGF0dGVybmBdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9zdHlsZS1zcGVjLyNwYWludC1saW5lLWxpbmUtcGF0dGVybikuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgVGhlIElEIG9mIHRoZSBpbWFnZS5cbiAgICAgKiBAcGFyYW0ge0hUTUxJbWFnZUVsZW1lbnQgfCBJbWFnZUJpdG1hcCB8IEltYWdlRGF0YSB8IFN0eWxlSW1hZ2VJbnRlcmZhY2V9IGltYWdlIFRoZSBpbWFnZSBhcyBhbiBgSFRNTEltYWdlRWxlbWVudGAsIFtgSW1hZ2VEYXRhYF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0ltYWdlRGF0YSksIFtgSW1hZ2VCaXRtYXBgXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvSW1hZ2VCaXRtYXApIG9yIG9iamVjdCB3aXRoIGB3aWR0aGAsIGBoZWlnaHRgLCBhbmQgYGRhdGFgXG4gICAgICogcHJvcGVydGllcyB3aXRoIHRoZSBzYW1lIGZvcm1hdCBhcyBgSW1hZ2VEYXRhYC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgKiAvLyBMb2FkIGFuIGltYWdlIGZyb20gYW4gZXh0ZXJuYWwgVVJMLlxuICAgICAqIG1hcC5sb2FkSW1hZ2UoJ2h0dHA6Ly9wbGFjZWtpdHRlbi5jb20vNTAvNTAnLCAoZXJyb3IsIGltYWdlKSA9PiB7XG4gICAgICogICAgIGlmIChlcnJvcikgdGhyb3cgZXJyb3I7XG4gICAgICogICAgIC8vIElmIGFuIGltYWdlIHdpdGggdGhlIElEICdjYXQnIGFscmVhZHkgZXhpc3RzIGluIHRoZSBzdHlsZSdzIHNwcml0ZSxcbiAgICAgKiAgICAgLy8gcmVwbGFjZSB0aGF0IGltYWdlIHdpdGggYSBuZXcgaW1hZ2UsICdvdGhlci1jYXQtaWNvbi5wbmcnLlxuICAgICAqICAgICBpZiAobWFwLmhhc0ltYWdlKCdjYXQnKSkgbWFwLnVwZGF0ZUltYWdlKCdjYXQnLCBpbWFnZSk7XG4gICAgICogfSk7XG4gICAgICovXG4gICAgdXBkYXRlSW1hZ2UoaWQ6IHN0cmluZyxcbiAgICAgICAgaW1hZ2U6IEhUTUxJbWFnZUVsZW1lbnQgfCBJbWFnZUJpdG1hcCB8IEltYWdlRGF0YSB8IHt3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciwgZGF0YTogVWludDhBcnJheSB8IFVpbnQ4Q2xhbXBlZEFycmF5fSB8IFN0eWxlSW1hZ2VJbnRlcmZhY2UpIHtcblxuICAgICAgICBjb25zdCBleGlzdGluZ0ltYWdlID0gdGhpcy5zdHlsZS5nZXRJbWFnZShpZCk7XG4gICAgICAgIGlmICghZXhpc3RpbmdJbWFnZSkge1xuICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFcnJvckV2ZW50KG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICAnVGhlIG1hcCBoYXMgbm8gaW1hZ2Ugd2l0aCB0aGF0IGlkLiBJZiB5b3UgYXJlIGFkZGluZyBhIG5ldyBpbWFnZSB1c2UgYG1hcC5hZGRJbWFnZSguLi4pYCBpbnN0ZWFkLicpKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaW1hZ2VEYXRhID0gKGltYWdlIGluc3RhbmNlb2Ygd2luZG93LkhUTUxJbWFnZUVsZW1lbnQgfHwgKHdpbmRvdy5JbWFnZUJpdG1hcCAmJiBpbWFnZSBpbnN0YW5jZW9mIHdpbmRvdy5JbWFnZUJpdG1hcCkpID8gYnJvd3Nlci5nZXRJbWFnZURhdGEoaW1hZ2UpIDogaW1hZ2U7XG4gICAgICAgIGNvbnN0IHt3aWR0aCwgaGVpZ2h0fSA9IGltYWdlRGF0YTtcbiAgICAgICAgLy8gRmxvdyBjYW4ndCByZWZpbmUgdGhlIHR5cGUgZW5vdWdoIHRvIGV4Y2x1ZGUgSW1hZ2VCaXRtYXBcbiAgICAgICAgY29uc3QgZGF0YSA9ICgoaW1hZ2VEYXRhOiBhbnkpLmRhdGE6IFVpbnQ4QXJyYXkgfCBVaW50OENsYW1wZWRBcnJheSk7XG5cbiAgICAgICAgaWYgKHdpZHRoID09PSB1bmRlZmluZWQgfHwgaGVpZ2h0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXJyb3JFdmVudChuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgJ0ludmFsaWQgYXJndW1lbnRzIHRvIG1hcC51cGRhdGVJbWFnZSgpLiBUaGUgc2Vjb25kIGFyZ3VtZW50IG11c3QgYmUgYW4gYEhUTUxJbWFnZUVsZW1lbnRgLCBgSW1hZ2VEYXRhYCwgYEltYWdlQml0bWFwYCwgJyArXG4gICAgICAgICAgICAgICAgJ29yIG9iamVjdCB3aXRoIGB3aWR0aGAsIGBoZWlnaHRgLCBhbmQgYGRhdGFgIHByb3BlcnRpZXMgd2l0aCB0aGUgc2FtZSBmb3JtYXQgYXMgYEltYWdlRGF0YWAnKSkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHdpZHRoICE9PSBleGlzdGluZ0ltYWdlLmRhdGEud2lkdGggfHwgaGVpZ2h0ICE9PSBleGlzdGluZ0ltYWdlLmRhdGEuaGVpZ2h0KSB7XG4gICAgICAgICAgICB0aGlzLmZpcmUobmV3IEVycm9yRXZlbnQobmV3IEVycm9yKFxuICAgICAgICAgICAgICAgIGBUaGUgd2lkdGggYW5kIGhlaWdodCBvZiB0aGUgdXBkYXRlZCBpbWFnZSAoJHt3aWR0aH0sICR7aGVpZ2h0fSlcbiAgICAgICAgICAgICAgICBtdXN0IGJlIHRoYXQgc2FtZSBhcyB0aGUgcHJldmlvdXMgdmVyc2lvbiBvZiB0aGUgaW1hZ2VcbiAgICAgICAgICAgICAgICAoJHtleGlzdGluZ0ltYWdlLmRhdGEud2lkdGh9LCAke2V4aXN0aW5nSW1hZ2UuZGF0YS5oZWlnaHR9KWApKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjb3B5ID0gIShpbWFnZSBpbnN0YW5jZW9mIHdpbmRvdy5IVE1MSW1hZ2VFbGVtZW50IHx8ICh3aW5kb3cuSW1hZ2VCaXRtYXAgJiYgaW1hZ2UgaW5zdGFuY2VvZiB3aW5kb3cuSW1hZ2VCaXRtYXApKTtcbiAgICAgICAgZXhpc3RpbmdJbWFnZS5kYXRhLnJlcGxhY2UoZGF0YSwgY29weSk7XG5cbiAgICAgICAgdGhpcy5zdHlsZS51cGRhdGVJbWFnZShpZCwgZXhpc3RpbmdJbWFnZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2sgd2hldGhlciBvciBub3QgYW4gaW1hZ2Ugd2l0aCBhIHNwZWNpZmljIElEIGV4aXN0cyBpbiB0aGUgc3R5bGUuIFRoaXMgY2hlY2tzIGJvdGggaW1hZ2VzXG4gICAgICogaW4gdGhlIHN0eWxlJ3Mgb3JpZ2luYWwgW3Nwcml0ZV0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vaGVscC9nbG9zc2FyeS9zcHJpdGUvKSBhbmQgYW55IGltYWdlc1xuICAgICAqIHRoYXQgaGF2ZSBiZWVuIGFkZGVkIGF0IHJ1bnRpbWUgdXNpbmcge0BsaW5rIE1hcCNhZGRJbWFnZX0uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgVGhlIElEIG9mIHRoZSBpbWFnZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBBIEJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIHRoZSBpbWFnZSBleGlzdHMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBDaGVjayBpZiBhbiBpbWFnZSB3aXRoIHRoZSBJRCAnY2F0JyBleGlzdHMgaW5cbiAgICAgKiAvLyB0aGUgc3R5bGUncyBzcHJpdGUuXG4gICAgICogY29uc3QgY2F0SWNvbkV4aXN0cyA9IG1hcC5oYXNJbWFnZSgnY2F0Jyk7XG4gICAgICovXG4gICAgaGFzSW1hZ2UoaWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAoIWlkKSB7XG4gICAgICAgICAgICB0aGlzLmZpcmUobmV3IEVycm9yRXZlbnQobmV3IEVycm9yKCdNaXNzaW5nIHJlcXVpcmVkIGltYWdlIGlkJykpKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAhIXRoaXMuc3R5bGUuZ2V0SW1hZ2UoaWQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBhbiBpbWFnZSBmcm9tIGEgc3R5bGUuIFRoaXMgY2FuIGJlIGFuIGltYWdlIGZyb20gdGhlIHN0eWxlJ3Mgb3JpZ2luYWxcbiAgICAgKiBbc3ByaXRlXShodHRwczovL2RvY3MubWFwYm94LmNvbS9oZWxwL2dsb3NzYXJ5L3Nwcml0ZS8pIG9yIGFueSBpbWFnZXNcbiAgICAgKiB0aGF0IGhhdmUgYmVlbiBhZGRlZCBhdCBydW50aW1lIHVzaW5nIHtAbGluayBNYXAjYWRkSW1hZ2V9LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGlkIFRoZSBJRCBvZiB0aGUgaW1hZ2UuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIElmIGFuIGltYWdlIHdpdGggdGhlIElEICdjYXQnIGV4aXN0cyBpblxuICAgICAqIC8vIHRoZSBzdHlsZSdzIHNwcml0ZSwgcmVtb3ZlIGl0LlxuICAgICAqIGlmIChtYXAuaGFzSW1hZ2UoJ2NhdCcpKSBtYXAucmVtb3ZlSW1hZ2UoJ2NhdCcpO1xuICAgICAqL1xuICAgIHJlbW92ZUltYWdlKGlkOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5zdHlsZS5yZW1vdmVJbWFnZShpZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTG9hZCBhbiBpbWFnZSBmcm9tIGFuIGV4dGVybmFsIFVSTCB0byBiZSB1c2VkIHdpdGgge0BsaW5rIE1hcCNhZGRJbWFnZX0uIEV4dGVybmFsXG4gICAgICogZG9tYWlucyBtdXN0IHN1cHBvcnQgW0NPUlNdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUVFAvQWNjZXNzX2NvbnRyb2xfQ09SUykuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXJsIFRoZSBVUkwgb2YgdGhlIGltYWdlIGZpbGUuIEltYWdlIGZpbGUgbXVzdCBiZSBpbiBwbmcsIHdlYnAsIG9yIGpwZyBmb3JtYXQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgRXhwZWN0aW5nIGBjYWxsYmFjayhlcnJvciwgZGF0YSlgLiBDYWxsZWQgd2hlbiB0aGUgaW1hZ2UgaGFzIGxvYWRlZCBvciB3aXRoIGFuIGVycm9yIGFyZ3VtZW50IGlmIHRoZXJlIGlzIGFuIGVycm9yLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBMb2FkIGFuIGltYWdlIGZyb20gYW4gZXh0ZXJuYWwgVVJMLlxuICAgICAqIG1hcC5sb2FkSW1hZ2UoJ2h0dHA6Ly9wbGFjZWtpdHRlbi5jb20vNTAvNTAnLCAoZXJyb3IsIGltYWdlKSA9PiB7XG4gICAgICogICAgIGlmIChlcnJvcikgdGhyb3cgZXJyb3I7XG4gICAgICogICAgIC8vIEFkZCB0aGUgbG9hZGVkIGltYWdlIHRvIHRoZSBzdHlsZSdzIHNwcml0ZSB3aXRoIHRoZSBJRCAna2l0dGVuJy5cbiAgICAgKiAgICAgbWFwLmFkZEltYWdlKCdraXR0ZW4nLCBpbWFnZSk7XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBBZGQgYW4gaWNvbiB0byB0aGUgbWFwXShodHRwczovL3d3dy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2FkZC1pbWFnZS8pXG4gICAgICovXG4gICAgbG9hZEltYWdlKHVybDogc3RyaW5nLCBjYWxsYmFjazogRnVuY3Rpb24pIHtcbiAgICAgICAgZ2V0SW1hZ2UodGhpcy5fcmVxdWVzdE1hbmFnZXIudHJhbnNmb3JtUmVxdWVzdCh1cmwsIFJlc291cmNlVHlwZS5JbWFnZSksIChlcnIsIGltZykgPT4ge1xuICAgICAgICAgICAgY2FsbGJhY2soZXJyLCBpbWcgaW5zdGFuY2VvZiB3aW5kb3cuSFRNTEltYWdlRWxlbWVudCA/IGJyb3dzZXIuZ2V0SW1hZ2VEYXRhKGltZykgOiBpbWcpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIFJldHVybnMgYW4gQXJyYXkgb2Ygc3RyaW5ncyBjb250YWluaW5nIHRoZSBJRHMgb2YgYWxsIGltYWdlcyBjdXJyZW50bHkgYXZhaWxhYmxlIGluIHRoZSBtYXAuXG4gICAgKiBUaGlzIGluY2x1ZGVzIGJvdGggaW1hZ2VzIGZyb20gdGhlIHN0eWxlJ3Mgb3JpZ2luYWwgW3Nwcml0ZV0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vaGVscC9nbG9zc2FyeS9zcHJpdGUvKVxuICAgICogYW5kIGFueSBpbWFnZXMgdGhhdCBoYXZlIGJlZW4gYWRkZWQgYXQgcnVudGltZSB1c2luZyB7QGxpbmsgTWFwI2FkZEltYWdlfS5cbiAgICAqXG4gICAgKiBAcmV0dXJucyB7QXJyYXk8c3RyaW5nPn0gQW4gQXJyYXkgb2Ygc3RyaW5ncyBjb250YWluaW5nIHRoZSBuYW1lcyBvZiBhbGwgc3ByaXRlcy9pbWFnZXMgY3VycmVudGx5IGF2YWlsYWJsZSBpbiB0aGUgbWFwLlxuICAgICpcbiAgICAqIEBleGFtcGxlXG4gICAgKiBjb25zdCBhbGxJbWFnZXMgPSBtYXAubGlzdEltYWdlcygpO1xuICAgICpcbiAgICAqL1xuICAgIGxpc3RJbWFnZXMoKTogQXJyYXk8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0eWxlLmxpc3RJbWFnZXMoKTtcbiAgICB9XG5cbiAgICAvKiogQHNlY3Rpb24ge0xheWVyc30gKi9cblxuICAgIC8qKlxuICAgICAqIEFkZHMgYSBbTWFwYm94IHN0eWxlIGxheWVyXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvc3R5bGUtc3BlYy8jbGF5ZXJzKVxuICAgICAqIHRvIHRoZSBtYXAncyBzdHlsZS5cbiAgICAgKlxuICAgICAqIEEgbGF5ZXIgZGVmaW5lcyBob3cgZGF0YSBmcm9tIGEgc3BlY2lmaWVkIHNvdXJjZSB3aWxsIGJlIHN0eWxlZC4gUmVhZCBtb3JlIGFib3V0IGxheWVyIHR5cGVzXG4gICAgICogYW5kIGF2YWlsYWJsZSBwYWludCBhbmQgbGF5b3V0IHByb3BlcnRpZXMgaW4gdGhlIFtNYXBib3ggU3R5bGUgU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL3N0eWxlLXNwZWMvI2xheWVycykuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09iamVjdCB8IEN1c3RvbUxheWVySW50ZXJmYWNlfSBsYXllciBUaGUgbGF5ZXIgdG8gYWRkLCBjb25mb3JtaW5nIHRvIGVpdGhlciB0aGUgTWFwYm94IFN0eWxlIFNwZWNpZmljYXRpb24ncyBbbGF5ZXIgZGVmaW5pdGlvbl0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL3N0eWxlLXNwZWMvI2xheWVycykgb3IsIGxlc3MgY29tbW9ubHksIHRoZSB7QGxpbmsgQ3VzdG9tTGF5ZXJJbnRlcmZhY2V9IHNwZWNpZmljYXRpb24uXG4gICAgICogVGhlIE1hcGJveCBTdHlsZSBTcGVjaWZpY2F0aW9uJ3MgbGF5ZXIgZGVmaW5pdGlvbiBpcyBhcHByb3ByaWF0ZSBmb3IgbW9zdCBsYXllcnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbGF5ZXIuaWQgQSB1bmlxdWUgaWRlbnRpZmllciB0aGF0IHlvdSBkZWZpbmUuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGxheWVyLnR5cGUgVGhlIHR5cGUgb2YgbGF5ZXIgKGZvciBleGFtcGxlIGBmaWxsYCBvciBgc3ltYm9sYCkuXG4gICAgICogQSBsaXN0IG9mIGxheWVyIHR5cGVzIGlzIGF2YWlsYWJsZSBpbiB0aGUgW01hcGJveCBTdHlsZSBTcGVjaWZpY2F0aW9uXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvc3R5bGUtc3BlYy9sYXllcnMvI3R5cGUpLlxuICAgICAqXG4gICAgICogVGhpcyBjYW4gYWxzbyBiZSBgY3VzdG9tYC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSB7QGxpbmsgQ3VzdG9tTGF5ZXJJbnRlcmZhY2V9LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nIHwgT2JqZWN0fSBbbGF5ZXIuc291cmNlXSBUaGUgZGF0YSBzb3VyY2UgZm9yIHRoZSBsYXllci5cbiAgICAgKiBSZWZlcmVuY2UgYSBzb3VyY2UgdGhhdCBoYXMgX2FscmVhZHkgYmVlbiBkZWZpbmVkXyB1c2luZyB0aGUgc291cmNlJ3MgdW5pcXVlIGlkLlxuICAgICAqIFJlZmVyZW5jZSBhIF9uZXcgc291cmNlXyB1c2luZyBhIHNvdXJjZSBvYmplY3QgKGFzIGRlZmluZWQgaW4gdGhlIFtNYXBib3ggU3R5bGUgU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL3N0eWxlLXNwZWMvc291cmNlcy8pKSBkaXJlY3RseS5cbiAgICAgKiBUaGlzIGlzICoqcmVxdWlyZWQqKiBmb3IgYWxsIGBsYXllci50eXBlYCBvcHRpb25zIF9leGNlcHRfIGZvciBgY3VzdG9tYCBhbmQgYGJhY2tncm91bmRgLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbbGF5ZXIuc291cmNlTGF5ZXJdIChvcHRpb25hbCkgVGhlIG5hbWUgb2YgdGhlIFtzb3VyY2UgbGF5ZXJdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL2hlbHAvZ2xvc3Nhcnkvc291cmNlLWxheWVyLykgd2l0aGluIHRoZSBzcGVjaWZpZWQgYGxheWVyLnNvdXJjZWAgdG8gdXNlIGZvciB0aGlzIHN0eWxlIGxheWVyLlxuICAgICAqIFRoaXMgaXMgb25seSBhcHBsaWNhYmxlIGZvciB2ZWN0b3IgdGlsZSBzb3VyY2VzIGFuZCBpcyAqKnJlcXVpcmVkKiogd2hlbiBgbGF5ZXIuc291cmNlYCBpcyBvZiB0aGUgdHlwZSBgdmVjdG9yYC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbbGF5ZXIuZmlsdGVyXSAob3B0aW9uYWwpIEFuIGV4cHJlc3Npb24gc3BlY2lmeWluZyBjb25kaXRpb25zIG9uIHNvdXJjZSBmZWF0dXJlcy5cbiAgICAgKiBPbmx5IGZlYXR1cmVzIHRoYXQgbWF0Y2ggdGhlIGZpbHRlciBhcmUgZGlzcGxheWVkLlxuICAgICAqIFRoZSBNYXBib3ggU3R5bGUgU3BlY2lmaWNhdGlvbiBpbmNsdWRlcyBtb3JlIGluZm9ybWF0aW9uIG9uIHRoZSBsaW1pdGF0aW9ucyBvZiB0aGUgW2BmaWx0ZXJgXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvc3R5bGUtc3BlYy9sYXllcnMvI2ZpbHRlcikgcGFyYW1ldGVyXG4gICAgICogYW5kIGEgY29tcGxldGUgbGlzdCBvZiBhdmFpbGFibGUgW2V4cHJlc3Npb25zXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvc3R5bGUtc3BlYy9leHByZXNzaW9ucy8pLlxuICAgICAqIElmIG5vIGZpbHRlciBpcyBwcm92aWRlZCwgYWxsIGZlYXR1cmVzIGluIHRoZSBzb3VyY2UgKG9yIHNvdXJjZSBsYXllciBmb3IgdmVjdG9yIHRpbGVzZXRzKSB3aWxsIGJlIGRpc3BsYXllZC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW2xheWVyLnBhaW50XSAob3B0aW9uYWwpIFBhaW50IHByb3BlcnRpZXMgZm9yIHRoZSBsYXllci5cbiAgICAgKiBBdmFpbGFibGUgcGFpbnQgcHJvcGVydGllcyB2YXJ5IGJ5IGBsYXllci50eXBlYC5cbiAgICAgKiBBIGZ1bGwgbGlzdCBvZiBwYWludCBwcm9wZXJ0aWVzIGZvciBlYWNoIGxheWVyIHR5cGUgaXMgYXZhaWxhYmxlIGluIHRoZSBbTWFwYm94IFN0eWxlIFNwZWNpZmljYXRpb25dKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9zdHlsZS1zcGVjL2xheWVycy8pLlxuICAgICAqIElmIG5vIHBhaW50IHByb3BlcnRpZXMgYXJlIHNwZWNpZmllZCwgZGVmYXVsdCB2YWx1ZXMgd2lsbCBiZSB1c2VkLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbbGF5ZXIubGF5b3V0XSAob3B0aW9uYWwpIExheW91dCBwcm9wZXJ0aWVzIGZvciB0aGUgbGF5ZXIuXG4gICAgICogQXZhaWxhYmxlIGxheW91dCBwcm9wZXJ0aWVzIHZhcnkgYnkgYGxheWVyLnR5cGVgLlxuICAgICAqIEEgZnVsbCBsaXN0IG9mIGxheW91dCBwcm9wZXJ0aWVzIGZvciBlYWNoIGxheWVyIHR5cGUgaXMgYXZhaWxhYmxlIGluIHRoZSBbTWFwYm94IFN0eWxlIFNwZWNpZmljYXRpb25dKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9zdHlsZS1zcGVjL2xheWVycy8pLlxuICAgICAqIElmIG5vIGxheW91dCBwcm9wZXJ0aWVzIGFyZSBzcGVjaWZpZWQsIGRlZmF1bHQgdmFsdWVzIHdpbGwgYmUgdXNlZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xheWVyLm1heHpvb21dIChvcHRpb25hbCkgVGhlIG1heGltdW0gem9vbSBsZXZlbCBmb3IgdGhlIGxheWVyLlxuICAgICAqIEF0IHpvb20gbGV2ZWxzIGVxdWFsIHRvIG9yIGdyZWF0ZXIgdGhhbiB0aGUgbWF4em9vbSwgdGhlIGxheWVyIHdpbGwgYmUgaGlkZGVuLlxuICAgICAqIFRoZSB2YWx1ZSBjYW4gYmUgYW55IG51bWJlciBiZXR3ZWVuIGAwYCBhbmQgYDI0YCAoaW5jbHVzaXZlKS5cbiAgICAgKiBJZiBubyBtYXh6b29tIGlzIHByb3ZpZGVkLCB0aGUgbGF5ZXIgd2lsbCBiZSB2aXNpYmxlIGF0IGFsbCB6b29tIGxldmVscyBmb3Igd2hpY2ggdGhlcmUgYXJlIHRpbGVzIGF2YWlsYWJsZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xheWVyLm1pbnpvb21dIChvcHRpb25hbCkgVGhlIG1pbmltdW0gem9vbSBsZXZlbCBmb3IgdGhlIGxheWVyLlxuICAgICAqIEF0IHpvb20gbGV2ZWxzIGxlc3MgdGhhbiB0aGUgbWluem9vbSwgdGhlIGxheWVyIHdpbGwgYmUgaGlkZGVuLlxuICAgICAqIFRoZSB2YWx1ZSBjYW4gYmUgYW55IG51bWJlciBiZXR3ZWVuIGAwYCBhbmQgYDI0YCAoaW5jbHVzaXZlKS5cbiAgICAgKiBJZiBubyBtaW56b29tIGlzIHByb3ZpZGVkLCB0aGUgbGF5ZXIgd2lsbCBiZSB2aXNpYmxlIGF0IGFsbCB6b29tIGxldmVscyBmb3Igd2hpY2ggdGhlcmUgYXJlIHRpbGVzIGF2YWlsYWJsZS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW2xheWVyLm1ldGFkYXRhXSAob3B0aW9uYWwpIEFyYml0cmFyeSBwcm9wZXJ0aWVzIHVzZWZ1bCB0byB0cmFjayB3aXRoIHRoZSBsYXllciwgYnV0IGRvIG5vdCBpbmZsdWVuY2UgcmVuZGVyaW5nLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbbGF5ZXIucmVuZGVyaW5nTW9kZV0gVGhpcyBpcyBvbmx5IGFwcGxpY2FibGUgZm9yIGxheWVycyB3aXRoIHRoZSB0eXBlIGBjdXN0b21gLlxuICAgICAqIFNlZSB7QGxpbmsgQ3VzdG9tTGF5ZXJJbnRlcmZhY2V9IGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbYmVmb3JlSWRdIFRoZSBJRCBvZiBhbiBleGlzdGluZyBsYXllciB0byBpbnNlcnQgdGhlIG5ldyBsYXllciBiZWZvcmUsXG4gICAgICogcmVzdWx0aW5nIGluIHRoZSBuZXcgbGF5ZXIgYXBwZWFyaW5nIHZpc3VhbGx5IGJlbmVhdGggdGhlIGV4aXN0aW5nIGxheWVyLlxuICAgICAqIElmIHRoaXMgYXJndW1lbnQgaXMgbm90IHNwZWNpZmllZCwgdGhlIGxheWVyIHdpbGwgYmUgYXBwZW5kZWQgdG8gdGhlIGVuZCBvZiB0aGUgbGF5ZXJzIGFycmF5XG4gICAgICogYW5kIGFwcGVhciB2aXN1YWxseSBhYm92ZSBhbGwgb3RoZXIgbGF5ZXJzLlxuICAgICAqXG4gICAgICogQHJldHVybnMge01hcH0gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gQWRkIGEgY2lyY2xlIGxheWVyIHdpdGggYSB2ZWN0b3Igc291cmNlXG4gICAgICogbWFwLmFkZExheWVyKHtcbiAgICAgKiAgICAgaWQ6ICdwb2ludHMtb2YtaW50ZXJlc3QnLFxuICAgICAqICAgICBzb3VyY2U6IHtcbiAgICAgKiAgICAgICAgIHR5cGU6ICd2ZWN0b3InLFxuICAgICAqICAgICAgICAgdXJsOiAnbWFwYm94Oi8vbWFwYm94Lm1hcGJveC1zdHJlZXRzLXY4J1xuICAgICAqICAgICB9LFxuICAgICAqICAgICAnc291cmNlLWxheWVyJzogJ3BvaV9sYWJlbCcsXG4gICAgICogICAgIHR5cGU6ICdjaXJjbGUnLFxuICAgICAqICAgICBwYWludDoge1xuICAgICAqICAgICAvLyBNYXBib3ggU3R5bGUgU3BlY2lmaWNhdGlvbiBwYWludCBwcm9wZXJ0aWVzXG4gICAgICogICAgIH0sXG4gICAgICogICAgIGxheW91dDoge1xuICAgICAqICAgICAvLyBNYXBib3ggU3R5bGUgU3BlY2lmaWNhdGlvbiBsYXlvdXQgcHJvcGVydGllc1xuICAgICAqICAgICB9XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIERlZmluZSBhIHNvdXJjZSBiZWZvcmUgdXNpbmcgaXQgdG8gY3JlYXRlIGEgbmV3IGxheWVyXG4gICAgICogbWFwLmFkZFNvdXJjZSgnc3RhdGUtZGF0YScsIHtcbiAgICAgKiAgICAgdHlwZTogJ2dlb2pzb24nLFxuICAgICAqICAgICBkYXRhOiAncGF0aC90by9kYXRhLmdlb2pzb24nXG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBtYXAuYWRkTGF5ZXIoe1xuICAgICAqICAgICBpZDogJ3N0YXRlcycsXG4gICAgICogICAgIC8vIFJlZmVyZW5jZXMgdGhlIEdlb0pTT04gc291cmNlIGRlZmluZWQgYWJvdmVcbiAgICAgKiAgICAgLy8gYW5kIGRvZXMgbm90IHJlcXVpcmUgYSBgc291cmNlLWxheWVyYFxuICAgICAqICAgICBzb3VyY2U6ICdzdGF0ZS1kYXRhJyxcbiAgICAgKiAgICAgdHlwZTogJ3N5bWJvbCcsXG4gICAgICogICAgIGxheW91dDoge1xuICAgICAqICAgICAgICAgLy8gU2V0IHRoZSBsYWJlbCBjb250ZW50IHRvIHRoZVxuICAgICAqICAgICAgICAgLy8gZmVhdHVyZSdzIGBuYW1lYCBwcm9wZXJ0eVxuICAgICAqICAgICAgICAgJ3RleHQtZmllbGQnOiBbJ2dldCcsICduYW1lJ11cbiAgICAgKiAgICAgfVxuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBBZGQgYSBuZXcgc3ltYm9sIGxheWVyIGJlZm9yZSBhbiBleGlzdGluZyBsYXllclxuICAgICAqIG1hcC5hZGRMYXllcih7XG4gICAgICogICAgIGlkOiAnc3RhdGVzJyxcbiAgICAgKiAgICAgLy8gUmVmZXJlbmNlcyBhIHNvdXJjZSB0aGF0J3MgYWxyZWFkeSBiZWVuIGRlZmluZWRcbiAgICAgKiAgICAgc291cmNlOiAnc3RhdGUtZGF0YScsXG4gICAgICogICAgIHR5cGU6ICdzeW1ib2wnLFxuICAgICAqICAgICBsYXlvdXQ6IHtcbiAgICAgKiAgICAgICAgIC8vIFNldCB0aGUgbGFiZWwgY29udGVudCB0byB0aGVcbiAgICAgKiAgICAgICAgIC8vIGZlYXR1cmUncyBgbmFtZWAgcHJvcGVydHlcbiAgICAgKiAgICAgICAgICd0ZXh0LWZpZWxkJzogWydnZXQnLCAnbmFtZSddXG4gICAgICogICAgIH1cbiAgICAgKiAvLyBBZGQgdGhlIGxheWVyIGJlZm9yZSB0aGUgZXhpc3RpbmcgYGNpdGllc2AgbGF5ZXJcbiAgICAgKiB9LCAnY2l0aWVzJyk7XG4gICAgICpcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBTZWxlY3QgZmVhdHVyZXMgYXJvdW5kIGEgY2xpY2tlZCBwb2ludF0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvcXVlcnlyZW5kZXJlZGZlYXR1cmVzLWFyb3VuZC1wb2ludC8pIChmaWxsIGxheWVyKVxuICAgICAqIEBzZWUgW0V4YW1wbGU6IEFkZCBhIG5ldyBsYXllciBiZWxvdyBsYWJlbHNdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2dlb2pzb24tbGF5ZXItaW4tc3RhY2svKVxuICAgICAqIEBzZWUgW0V4YW1wbGU6IENyZWF0ZSBhbmQgc3R5bGUgY2x1c3RlcnNdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2NsdXN0ZXIvKSAoY2lyY2xlIGxheWVyKVxuICAgICAqIEBzZWUgW0V4YW1wbGU6IEFkZCBhIHZlY3RvciB0aWxlIHNvdXJjZV0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvdmVjdG9yLXNvdXJjZS8pIChsaW5lIGxheWVyKVxuICAgICAqIEBzZWUgW0V4YW1wbGU6IEFkZCBhIFdNUyBsYXllcl0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvd21zLykgKHJhc3RlciBsYXllcilcbiAgICAgKi9cbiAgICBhZGRMYXllcihsYXllcjogTGF5ZXJTcGVjaWZpY2F0aW9uIHwgQ3VzdG9tTGF5ZXJJbnRlcmZhY2UsIGJlZm9yZUlkPzogc3RyaW5nKTogdGhpcyB7XG4gICAgICAgIHRoaXMuX2xhenlJbml0RW1wdHlTdHlsZSgpO1xuICAgICAgICB0aGlzLnN0eWxlLmFkZExheWVyKGxheWVyLCBiZWZvcmVJZCk7XG4gICAgICAgIHJldHVybiB0aGlzLl91cGRhdGUodHJ1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTW92ZXMgYSBsYXllciB0byBhIGRpZmZlcmVudCB6LXBvc2l0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGlkIFRoZSBJRCBvZiB0aGUgbGF5ZXIgdG8gbW92ZS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW2JlZm9yZUlkXSBUaGUgSUQgb2YgYW4gZXhpc3RpbmcgbGF5ZXIgdG8gaW5zZXJ0IHRoZSBuZXcgbGF5ZXIgYmVmb3JlLiBXaGVuIHZpZXdpbmcgdGhlIG1hcCwgdGhlIGBpZGAgbGF5ZXIgd2lsbCBhcHBlYXIgYmVuZWF0aCB0aGUgYGJlZm9yZUlkYCBsYXllci4gSWYgYGJlZm9yZUlkYCBpcyBvbWl0dGVkLCB0aGUgbGF5ZXIgd2lsbCBiZSBhcHBlbmRlZCB0byB0aGUgZW5kIG9mIHRoZSBsYXllcnMgYXJyYXkgYW5kIGFwcGVhciBhYm92ZSBhbGwgb3RoZXIgbGF5ZXJzIG9uIHRoZSBtYXAuXG4gICAgICogQHJldHVybnMge01hcH0gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gTW92ZSBhIGxheWVyIHdpdGggSUQgJ3BvbHlnb24nIGJlZm9yZSB0aGUgbGF5ZXIgd2l0aCBJRCAnY291bnRyeS1sYWJlbCcuIFRoZSBgcG9seWdvbmAgbGF5ZXIgd2lsbCBhcHBlYXIgYmVuZWF0aCB0aGUgYGNvdW50cnktbGFiZWxgIGxheWVyIG9uIHRoZSBtYXAuXG4gICAgICogbWFwLm1vdmVMYXllcigncG9seWdvbicsICdjb3VudHJ5LWxhYmVsJyk7XG4gICAgICovXG4gICAgbW92ZUxheWVyKGlkOiBzdHJpbmcsIGJlZm9yZUlkPzogc3RyaW5nKTogdGhpcyB7XG4gICAgICAgIHRoaXMuc3R5bGUubW92ZUxheWVyKGlkLCBiZWZvcmVJZCk7XG4gICAgICAgIHJldHVybiB0aGlzLl91cGRhdGUodHJ1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyB0aGUgbGF5ZXIgd2l0aCB0aGUgZ2l2ZW4gSUQgZnJvbSB0aGUgbWFwJ3Mgc3R5bGUuXG4gICAgICpcbiAgICAgKiBJZiBubyBzdWNoIGxheWVyIGV4aXN0cywgYW4gYGVycm9yYCBldmVudCBpcyBmaXJlZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBpZCBJRCBvZiB0aGUgbGF5ZXIgdG8gcmVtb3ZlLlxuICAgICAqIEByZXR1cm5zIHtNYXB9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGZpcmVzIE1hcC5ldmVudDplcnJvclxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBJZiBhIGxheWVyIHdpdGggSUQgJ3N0YXRlLWRhdGEnIGV4aXN0cywgcmVtb3ZlIGl0LlxuICAgICAqIGlmIChtYXAuZ2V0TGF5ZXIoJ3N0YXRlLWRhdGEnKSkgbWFwLnJlbW92ZUxheWVyKCdzdGF0ZS1kYXRhJyk7XG4gICAgICovXG4gICAgcmVtb3ZlTGF5ZXIoaWQ6IHN0cmluZyk6IHRoaXMge1xuICAgICAgICB0aGlzLnN0eWxlLnJlbW92ZUxheWVyKGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3VwZGF0ZSh0cnVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBsYXllciB3aXRoIHRoZSBzcGVjaWZpZWQgSUQgaW4gdGhlIG1hcCdzIHN0eWxlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGlkIFRoZSBJRCBvZiB0aGUgbGF5ZXIgdG8gZ2V0LlxuICAgICAqIEByZXR1cm5zIHs/T2JqZWN0fSBUaGUgbGF5ZXIgd2l0aCB0aGUgc3BlY2lmaWVkIElELCBvciBgdW5kZWZpbmVkYFxuICAgICAqICAgaWYgdGhlIElEIGNvcnJlc3BvbmRzIHRvIG5vIGV4aXN0aW5nIGxheWVycy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgc3RhdGVEYXRhTGF5ZXIgPSBtYXAuZ2V0TGF5ZXIoJ3N0YXRlLWRhdGEnKTtcbiAgICAgKlxuICAgICAqIEBzZWUgW0V4YW1wbGU6IEZpbHRlciBzeW1ib2xzIGJ5IHRvZ2dsaW5nIGEgbGlzdF0oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9maWx0ZXItbWFya2Vycy8pXG4gICAgICogQHNlZSBbRXhhbXBsZTogRmlsdGVyIHN5bWJvbHMgYnkgdGV4dCBpbnB1dF0oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9maWx0ZXItbWFya2Vycy1ieS1pbnB1dC8pXG4gICAgICovXG4gICAgZ2V0TGF5ZXIoaWQ6IHN0cmluZyk6ID9TdHlsZUxheWVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3R5bGUuZ2V0TGF5ZXIoaWQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHpvb20gZXh0ZW50IGZvciB0aGUgc3BlY2lmaWVkIHN0eWxlIGxheWVyLiBUaGUgem9vbSBleHRlbnQgaW5jbHVkZXMgdGhlXG4gICAgICogW21pbmltdW0gem9vbSBsZXZlbF0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL3N0eWxlLXNwZWMvI2xheWVyLW1pbnpvb20pXG4gICAgICogYW5kIFttYXhpbXVtIHpvb20gbGV2ZWxdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9zdHlsZS1zcGVjLyNsYXllci1tYXh6b29tKSlcbiAgICAgKiBhdCB3aGljaCB0aGUgbGF5ZXIgd2lsbCBiZSByZW5kZXJlZC5cbiAgICAgKlxuICAgICAqIE5vdGU6IEZvciBzdHlsZSBsYXllcnMgdXNpbmcgdmVjdG9yIHNvdXJjZXMsIHN0eWxlIGxheWVycyBjYW5ub3QgYmUgcmVuZGVyZWQgYXQgem9vbSBsZXZlbHMgbG93ZXIgdGhhbiB0aGVcbiAgICAgKiBtaW5pbXVtIHpvb20gbGV2ZWwgb2YgdGhlIF9zb3VyY2UgbGF5ZXJfIGJlY2F1c2UgdGhlIGRhdGEgZG9lcyBub3QgZXhpc3QgYXQgdGhvc2Ugem9vbSBsZXZlbHMuIElmIHRoZSBtaW5pbXVtXG4gICAgICogem9vbSBsZXZlbCBvZiB0aGUgc291cmNlIGxheWVyIGlzIGhpZ2hlciB0aGFuIHRoZSBtaW5pbXVtIHpvb20gbGV2ZWwgZGVmaW5lZCBpbiB0aGUgc3R5bGUgbGF5ZXIsIHRoZSBzdHlsZVxuICAgICAqIGxheWVyIHdpbGwgbm90IGJlIHJlbmRlcmVkIGF0IGFsbCB6b29tIGxldmVscyBpbiB0aGUgem9vbSByYW5nZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBsYXllcklkIFRoZSBJRCBvZiB0aGUgbGF5ZXIgdG8gd2hpY2ggdGhlIHpvb20gZXh0ZW50IHdpbGwgYmUgYXBwbGllZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbWluem9vbSBUaGUgbWluaW11bSB6b29tIHRvIHNldCAoMC0yNCkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG1heHpvb20gVGhlIG1heGltdW0gem9vbSB0byBzZXQgKDAtMjQpLlxuICAgICAqIEByZXR1cm5zIHtNYXB9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIG1hcC5zZXRMYXllclpvb21SYW5nZSgnbXktbGF5ZXInLCAyLCA1KTtcbiAgICAgKlxuICAgICAqL1xuICAgIHNldExheWVyWm9vbVJhbmdlKGxheWVySWQ6IHN0cmluZywgbWluem9vbTogbnVtYmVyLCBtYXh6b29tOiBudW1iZXIpOiB0aGlzIHtcbiAgICAgICAgdGhpcy5zdHlsZS5zZXRMYXllclpvb21SYW5nZShsYXllcklkLCBtaW56b29tLCBtYXh6b29tKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3VwZGF0ZSh0cnVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBmaWx0ZXIgZm9yIHRoZSBzcGVjaWZpZWQgc3R5bGUgbGF5ZXIuXG4gICAgICpcbiAgICAgKiBGaWx0ZXJzIGNvbnRyb2wgd2hpY2ggZmVhdHVyZXMgYSBzdHlsZSBsYXllciByZW5kZXJzIGZyb20gaXRzIHNvdXJjZS5cbiAgICAgKiBBbnkgZmVhdHVyZSBmb3Igd2hpY2ggdGhlIGZpbHRlciBleHByZXNzaW9uIGV2YWx1YXRlcyB0byBgdHJ1ZWAgd2lsbCBiZVxuICAgICAqIHJlbmRlcmVkIG9uIHRoZSBtYXAuIFRob3NlIHRoYXQgYXJlIGZhbHNlIHdpbGwgYmUgaGlkZGVuLlxuICAgICAqXG4gICAgICogVXNlIGBzZXRGaWx0ZXJgIHRvIHNob3cgYSBzdWJzZXQgb2YgeW91ciBzb3VyY2UgZGF0YS5cbiAgICAgKlxuICAgICAqIFRvIGNsZWFyIHRoZSBmaWx0ZXIsIHBhc3MgYG51bGxgIG9yIGB1bmRlZmluZWRgIGFzIHRoZSBzZWNvbmQgcGFyYW1ldGVyLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGxheWVySWQgVGhlIElEIG9mIHRoZSBsYXllciB0byB3aGljaCB0aGUgZmlsdGVyIHdpbGwgYmUgYXBwbGllZC5cbiAgICAgKiBAcGFyYW0ge0FycmF5IHwgbnVsbCB8IHVuZGVmaW5lZH0gZmlsdGVyIFRoZSBmaWx0ZXIsIGNvbmZvcm1pbmcgdG8gdGhlIE1hcGJveCBTdHlsZSBTcGVjaWZpY2F0aW9uJ3NcbiAgICAgKiAgIFtmaWx0ZXIgZGVmaW5pdGlvbl0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL3N0eWxlLXNwZWMvbGF5ZXJzLyNmaWx0ZXIpLiAgSWYgYG51bGxgIG9yIGB1bmRlZmluZWRgIGlzIHByb3ZpZGVkLCB0aGUgZnVuY3Rpb24gcmVtb3ZlcyBhbnkgZXhpc3RpbmcgZmlsdGVyIGZyb20gdGhlIGxheWVyLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gT3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy52YWxpZGF0ZT10cnVlXSBXaGV0aGVyIHRvIGNoZWNrIGlmIHRoZSBmaWx0ZXIgY29uZm9ybXMgdG8gdGhlIE1hcGJveCBHTCBTdHlsZSBTcGVjaWZpY2F0aW9uLiBEaXNhYmxpbmcgdmFsaWRhdGlvbiBpcyBhIHBlcmZvcm1hbmNlIG9wdGltaXphdGlvbiB0aGF0IHNob3VsZCBvbmx5IGJlIHVzZWQgaWYgeW91IGhhdmUgcHJldmlvdXNseSB2YWxpZGF0ZWQgdGhlIHZhbHVlcyB5b3Ugd2lsbCBiZSBwYXNzaW5nIHRvIHRoaXMgZnVuY3Rpb24uXG4gICAgICogQHJldHVybnMge01hcH0gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gZGlzcGxheSBvbmx5IGZlYXR1cmVzIHdpdGggdGhlICduYW1lJyBwcm9wZXJ0eSAnVVNBJ1xuICAgICAqIG1hcC5zZXRGaWx0ZXIoJ215LWxheWVyJywgWyc9PScsIFsnZ2V0JywgJ25hbWUnXSwgJ1VTQSddKTtcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIGRpc3BsYXkgb25seSBmZWF0dXJlcyB3aXRoIGZpdmUgb3IgbW9yZSAnYXZhaWxhYmxlLXNwb3RzJ1xuICAgICAqIG1hcC5zZXRGaWx0ZXIoJ2Jpa2UtZG9ja3MnLCBbJz49JywgWydnZXQnLCAnYXZhaWxhYmxlLXNwb3RzJ10sIDVdKTtcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIHJlbW92ZSB0aGUgZmlsdGVyIGZvciB0aGUgJ2Jpa2UtZG9ja3MnIHN0eWxlIGxheWVyXG4gICAgICogbWFwLnNldEZpbHRlcignYmlrZS1kb2NrcycsIG51bGwpO1xuICAgICAqXG4gICAgICogQHNlZSBbRXhhbXBsZTogRmlsdGVyIGZlYXR1cmVzIHdpdGhpbiBtYXAgdmlld10oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9maWx0ZXItZmVhdHVyZXMtd2l0aGluLW1hcC12aWV3LylcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBIaWdobGlnaHQgZmVhdHVyZXMgY29udGFpbmluZyBzaW1pbGFyIGRhdGFdKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvcXVlcnktc2ltaWxhci1mZWF0dXJlcy8pXG4gICAgICogQHNlZSBbRXhhbXBsZTogQ3JlYXRlIGEgdGltZWxpbmUgYW5pbWF0aW9uXShodHRwczovL3d3dy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL3RpbWVsaW5lLWFuaW1hdGlvbi8pXG4gICAgICogQHNlZSBbVHV0b3JpYWw6IFNob3cgY2hhbmdlcyBvdmVyIHRpbWVdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL2hlbHAvdHV0b3JpYWxzL3Nob3ctY2hhbmdlcy1vdmVyLXRpbWUvKVxuICAgICAqL1xuICAgIHNldEZpbHRlcihsYXllcklkOiBzdHJpbmcsIGZpbHRlcjogP0ZpbHRlclNwZWNpZmljYXRpb24sICBvcHRpb25zOiBTdHlsZVNldHRlck9wdGlvbnMgPSB7fSk6IHRoaXMge1xuICAgICAgICB0aGlzLnN0eWxlLnNldEZpbHRlcihsYXllcklkLCBmaWx0ZXIsIG9wdGlvbnMpO1xuICAgICAgICByZXR1cm4gdGhpcy5fdXBkYXRlKHRydWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGZpbHRlciBhcHBsaWVkIHRvIHRoZSBzcGVjaWZpZWQgc3R5bGUgbGF5ZXIuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbGF5ZXJJZCBUaGUgSUQgb2YgdGhlIHN0eWxlIGxheWVyIHdob3NlIGZpbHRlciB0byBnZXQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBUaGUgbGF5ZXIncyBmaWx0ZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBmaWx0ZXIgPSBtYXAuZ2V0RmlsdGVyKCdteUxheWVyJyk7XG4gICAgICovXG4gICAgZ2V0RmlsdGVyKGxheWVySWQ6IHN0cmluZyk6ID9GaWx0ZXJTcGVjaWZpY2F0aW9uIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3R5bGUuZ2V0RmlsdGVyKGxheWVySWQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIGEgcGFpbnQgcHJvcGVydHkgaW4gdGhlIHNwZWNpZmllZCBzdHlsZSBsYXllci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBsYXllcklkIFRoZSBJRCBvZiB0aGUgbGF5ZXIgdG8gc2V0IHRoZSBwYWludCBwcm9wZXJ0eSBpbi5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSBUaGUgbmFtZSBvZiB0aGUgcGFpbnQgcHJvcGVydHkgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIG9mIHRoZSBwYWludCBwcm9wZXJ0eSB0byBzZXQuXG4gICAgICogICBNdXN0IGJlIG9mIGEgdHlwZSBhcHByb3ByaWF0ZSBmb3IgdGhlIHByb3BlcnR5LCBhcyBkZWZpbmVkIGluIHRoZSBbTWFwYm94IFN0eWxlIFNwZWNpZmljYXRpb25dKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLXN0eWxlLXNwZWMvKS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIE9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMudmFsaWRhdGU9dHJ1ZV0gV2hldGhlciB0byBjaGVjayBpZiBgdmFsdWVgIGNvbmZvcm1zIHRvIHRoZSBNYXBib3ggR0wgU3R5bGUgU3BlY2lmaWNhdGlvbi4gRGlzYWJsaW5nIHZhbGlkYXRpb24gaXMgYSBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb24gdGhhdCBzaG91bGQgb25seSBiZSB1c2VkIGlmIHlvdSBoYXZlIHByZXZpb3VzbHkgdmFsaWRhdGVkIHRoZSB2YWx1ZXMgeW91IHdpbGwgYmUgcGFzc2luZyB0byB0aGlzIGZ1bmN0aW9uLlxuICAgICAqIEByZXR1cm5zIHtNYXB9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAuc2V0UGFpbnRQcm9wZXJ0eSgnbXktbGF5ZXInLCAnZmlsbC1jb2xvcicsICcjZmFhZmVlJyk7XG4gICAgICogQHNlZSBbRXhhbXBsZTogQ2hhbmdlIGEgbGF5ZXIncyBjb2xvciB3aXRoIGJ1dHRvbnNdKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvY29sb3Itc3dpdGNoZXIvKVxuICAgICAqIEBzZWUgW0V4YW1wbGU6IEFkanVzdCBhIGxheWVyJ3Mgb3BhY2l0eV0oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9hZGp1c3QtbGF5ZXItb3BhY2l0eS8pXG4gICAgICogQHNlZSBbRXhhbXBsZTogQ3JlYXRlIGEgZHJhZ2dhYmxlIHBvaW50XShodHRwczovL3d3dy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2RyYWctYS1wb2ludC8pXG4gICAgICovXG4gICAgc2V0UGFpbnRQcm9wZXJ0eShsYXllcklkOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgdmFsdWU6IGFueSwgb3B0aW9uczogU3R5bGVTZXR0ZXJPcHRpb25zID0ge30pOiB0aGlzIHtcbiAgICAgICAgdGhpcy5zdHlsZS5zZXRQYWludFByb3BlcnR5KGxheWVySWQsIG5hbWUsIHZhbHVlLCBvcHRpb25zKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3VwZGF0ZSh0cnVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHBhaW50IHByb3BlcnR5IGluIHRoZSBzcGVjaWZpZWQgc3R5bGUgbGF5ZXIuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbGF5ZXJJZCBUaGUgSUQgb2YgdGhlIGxheWVyIHRvIGdldCB0aGUgcGFpbnQgcHJvcGVydHkgZnJvbS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSBUaGUgbmFtZSBvZiBhIHBhaW50IHByb3BlcnR5IHRvIGdldC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gVGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcGFpbnQgcHJvcGVydHkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwYWludFByb3BlcnR5ID0gbWFwLmdldFBhaW50UHJvcGVydHkoJ215U3ltYm9sTGF5ZXInLCAnaWNvbi1jb2xvcicpO1xuICAgICAqL1xuICAgIGdldFBhaW50UHJvcGVydHkobGF5ZXJJZDogc3RyaW5nLCBuYW1lOiBzdHJpbmcpOiB2b2lkIHwgVHJhbnNpdGlvblNwZWNpZmljYXRpb24gfCBQcm9wZXJ0eVZhbHVlU3BlY2lmaWNhdGlvbjxtaXhlZD4ge1xuICAgICAgICByZXR1cm4gdGhpcy5zdHlsZS5nZXRQYWludFByb3BlcnR5KGxheWVySWQsIG5hbWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIGEgbGF5b3V0IHByb3BlcnR5IGluIHRoZSBzcGVjaWZpZWQgc3R5bGUgbGF5ZXIuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbGF5ZXJJZCBUaGUgSUQgb2YgdGhlIGxheWVyIHRvIHNldCB0aGUgbGF5b3V0IHByb3BlcnR5IGluLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBsYXlvdXQgcHJvcGVydHkgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIG9mIHRoZSBsYXlvdXQgcHJvcGVydHkuIE11c3QgYmUgb2YgYSB0eXBlIGFwcHJvcHJpYXRlIGZvciB0aGUgcHJvcGVydHksIGFzIGRlZmluZWQgaW4gdGhlIFtNYXBib3ggU3R5bGUgU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtc3R5bGUtc3BlYy8pLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gT3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy52YWxpZGF0ZT10cnVlXSBXaGV0aGVyIHRvIGNoZWNrIGlmIGB2YWx1ZWAgY29uZm9ybXMgdG8gdGhlIE1hcGJveCBHTCBTdHlsZSBTcGVjaWZpY2F0aW9uLiBEaXNhYmxpbmcgdmFsaWRhdGlvbiBpcyBhIHBlcmZvcm1hbmNlIG9wdGltaXphdGlvbiB0aGF0IHNob3VsZCBvbmx5IGJlIHVzZWQgaWYgeW91IGhhdmUgcHJldmlvdXNseSB2YWxpZGF0ZWQgdGhlIHZhbHVlcyB5b3Ugd2lsbCBiZSBwYXNzaW5nIHRvIHRoaXMgZnVuY3Rpb24uXG4gICAgICogQHJldHVybnMge01hcH0gUmV0dXJucyBpdHNlbGYgdG8gYWxsb3cgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIG1hcC5zZXRMYXlvdXRQcm9wZXJ0eSgnbXktbGF5ZXInLCAndmlzaWJpbGl0eScsICdub25lJyk7XG4gICAgICogQHNlZSBbRXhhbXBsZTogU2hvdyBhbmQgaGlkZSBsYXllcnNdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL3RvZ2dsZS1sYXllcnMvKVxuICAgICAqL1xuICAgIHNldExheW91dFByb3BlcnR5KGxheWVySWQ6IHN0cmluZywgbmFtZTogc3RyaW5nLCB2YWx1ZTogYW55LCBvcHRpb25zOiBTdHlsZVNldHRlck9wdGlvbnMgPSB7fSk6IHRoaXMge1xuICAgICAgICB0aGlzLnN0eWxlLnNldExheW91dFByb3BlcnR5KGxheWVySWQsIG5hbWUsIHZhbHVlLCBvcHRpb25zKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3VwZGF0ZSh0cnVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIGxheW91dCBwcm9wZXJ0eSBpbiB0aGUgc3BlY2lmaWVkIHN0eWxlIGxheWVyLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGxheWVySWQgVGhlIElEIG9mIHRoZSBsYXllciB0byBnZXQgdGhlIGxheW91dCBwcm9wZXJ0eSBmcm9tLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBsYXlvdXQgcHJvcGVydHkgdG8gZ2V0LlxuICAgICAqIEByZXR1cm5zIHsqfSBUaGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBsYXlvdXQgcHJvcGVydHkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBsYXlvdXRQcm9wZXJ0eSA9IG1hcC5nZXRMYXlvdXRQcm9wZXJ0eSgnbXlTeW1ib2xMYXllcicsICdpY29uLWFuY2hvcicpO1xuICAgICAqL1xuICAgIGdldExheW91dFByb3BlcnR5KGxheWVySWQ6IHN0cmluZywgbmFtZTogc3RyaW5nKTogP1Byb3BlcnR5VmFsdWVTcGVjaWZpY2F0aW9uPG1peGVkPiB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0eWxlLmdldExheW91dFByb3BlcnR5KGxheWVySWQsIG5hbWUpO1xuICAgIH1cblxuICAgIC8qKiBAc2VjdGlvbiB7U3R5bGUgcHJvcGVydGllc30gKi9cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGFueSBjb21iaW5hdGlvbiBvZiBsaWdodCB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0xpZ2h0U3BlY2lmaWNhdGlvbn0gbGlnaHQgTGlnaHQgcHJvcGVydGllcyB0byBzZXQuIE11c3QgY29uZm9ybSB0byB0aGUgW0xpZ2h0IFN0eWxlIFNwZWNpZmljYXRpb25dKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLXN0eWxlLXNwZWMvI2xpZ2h0KS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIE9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMudmFsaWRhdGU9dHJ1ZV0gV2hldGhlciB0byBjaGVjayBpZiB0aGUgZmlsdGVyIGNvbmZvcm1zIHRvIHRoZSBNYXBib3ggR0wgU3R5bGUgU3BlY2lmaWNhdGlvbi4gRGlzYWJsaW5nIHZhbGlkYXRpb24gaXMgYSBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb24gdGhhdCBzaG91bGQgb25seSBiZSB1c2VkIGlmIHlvdSBoYXZlIHByZXZpb3VzbHkgdmFsaWRhdGVkIHRoZSB2YWx1ZXMgeW91IHdpbGwgYmUgcGFzc2luZyB0byB0aGlzIGZ1bmN0aW9uLlxuICAgICAqIEByZXR1cm5zIHtNYXB9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAuc2V0TGlnaHQoe1xuICAgICAqICAgICBcImFuY2hvclwiOiBcInZpZXdwb3J0XCIsXG4gICAgICogICAgIFwiY29sb3JcIjogXCJibHVlXCIsXG4gICAgICogICAgIFwiaW50ZW5zaXR5XCI6IDAuNVxuICAgICAqIH0pO1xuICAgICAqL1xuICAgIHNldExpZ2h0KGxpZ2h0OiBMaWdodFNwZWNpZmljYXRpb24sIG9wdGlvbnM6IFN0eWxlU2V0dGVyT3B0aW9ucyA9IHt9KTogdGhpcyB7XG4gICAgICAgIHRoaXMuX2xhenlJbml0RW1wdHlTdHlsZSgpO1xuICAgICAgICB0aGlzLnN0eWxlLnNldExpZ2h0KGxpZ2h0LCBvcHRpb25zKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3VwZGF0ZSh0cnVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgbGlnaHQgb2JqZWN0LlxuICAgICAqXG4gICAgICogQHJldHVybnMge0xpZ2h0U3BlY2lmaWNhdGlvbn0gTGlnaHQgcHJvcGVydGllcyBvZiB0aGUgc3R5bGUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBsaWdodCA9IG1hcC5nZXRMaWdodCgpO1xuICAgICAqL1xuICAgIGdldExpZ2h0KCk6IExpZ2h0U3BlY2lmaWNhdGlvbiB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0eWxlLmdldExpZ2h0KCk7XG4gICAgfVxuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtcmV0dXJuc1xuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHRlcnJhaW4gcHJvcGVydHkgb2YgdGhlIHN0eWxlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtUZXJyYWluU3BlY2lmaWNhdGlvbn0gdGVycmFpbiBUZXJyYWluIHByb3BlcnRpZXMgdG8gc2V0LiBNdXN0IGNvbmZvcm0gdG8gdGhlIFtUZXJyYWluIFN0eWxlIFNwZWNpZmljYXRpb25dKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9zdHlsZS1zcGVjL3RlcnJhaW4vKS5cbiAgICAgKiBJZiBgbnVsbGAgb3IgYHVuZGVmaW5lZGAgaXMgcHJvdmlkZWQsIGZ1bmN0aW9uIHJlbW92ZXMgdGVycmFpbi5cbiAgICAgKiBAcmV0dXJucyB7TWFwfSBSZXR1cm5zIGl0c2VsZiB0byBhbGxvdyBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogbWFwLmFkZFNvdXJjZSgnbWFwYm94LWRlbScsIHtcbiAgICAgKiAgICAgJ3R5cGUnOiAncmFzdGVyLWRlbScsXG4gICAgICogICAgICd1cmwnOiAnbWFwYm94Oi8vbWFwYm94Lm1hcGJveC10ZXJyYWluLWRlbS12MScsXG4gICAgICogICAgICd0aWxlU2l6ZSc6IDUxMixcbiAgICAgKiAgICAgJ21heHpvb20nOiAxNFxuICAgICAqIH0pO1xuICAgICAqIC8vIGFkZCB0aGUgREVNIHNvdXJjZSBhcyBhIHRlcnJhaW4gbGF5ZXIgd2l0aCBleGFnZ2VyYXRlZCBoZWlnaHRcbiAgICAgKiBtYXAuc2V0VGVycmFpbih7J3NvdXJjZSc6ICdtYXBib3gtZGVtJywgJ2V4YWdnZXJhdGlvbic6IDEuNX0pO1xuICAgICAqL1xuICAgIHNldFRlcnJhaW4odGVycmFpbjogVGVycmFpblNwZWNpZmljYXRpb24pOiB0aGlzIHtcbiAgICAgICAgdGhpcy5fbGF6eUluaXRFbXB0eVN0eWxlKCk7XG4gICAgICAgIGlmICghdGVycmFpbiAmJiB0aGlzLnRyYW5zZm9ybS5wcm9qZWN0aW9uLnJlcXVpcmVzRHJhcGluZykge1xuICAgICAgICAgICAgdGhpcy5zdHlsZS5zZXRUZXJyYWluRm9yRHJhcGluZygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zdHlsZS5zZXRUZXJyYWluKHRlcnJhaW4pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2F2ZXJhZ2VFbGV2YXRpb25MYXN0U2FtcGxlZEF0ID0gLUluZmluaXR5O1xuICAgICAgICByZXR1cm4gdGhpcy5fdXBkYXRlKHRydWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHRlcnJhaW4gc3BlY2lmaWNhdGlvbiBvciBgbnVsbGAgaWYgdGVycmFpbiBpc24ndCBzZXQgb24gdGhlIG1hcC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtUZXJyYWluU3BlY2lmaWNhdGlvbiB8IG51bGx9IFRlcnJhaW4gc3BlY2lmaWNhdGlvbiBwcm9wZXJ0aWVzIG9mIHRoZSBzdHlsZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHRlcnJhaW4gPSBtYXAuZ2V0VGVycmFpbigpO1xuICAgICAqL1xuICAgIGdldFRlcnJhaW4oKTogP1RlcnJhaW5TcGVjaWZpY2F0aW9uIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3R5bGUgPyB0aGlzLnN0eWxlLmdldFRlcnJhaW4oKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgZm9nIHByb3BlcnR5IG9mIHRoZSBzdHlsZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Rm9nU3BlY2lmaWNhdGlvbn0gZm9nIFRoZSBmb2cgcHJvcGVydGllcyB0byBzZXQuIE11c3QgY29uZm9ybSB0byB0aGUgW0ZvZyBTdHlsZSBTcGVjaWZpY2F0aW9uXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvc3R5bGUtc3BlYy9mb2cvKS5cbiAgICAgKiBJZiBgbnVsbGAgb3IgYHVuZGVmaW5lZGAgaXMgcHJvdmlkZWQsIHRoaXMgZnVuY3Rpb24gY2FsbCByZW1vdmVzIHRoZSBmb2cgZnJvbSB0aGUgbWFwLlxuICAgICAqIEByZXR1cm5zIHtNYXB9IFJldHVybnMgaXRzZWxmIHRvIGFsbG93IGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAuc2V0Rm9nKHtcbiAgICAgKiAgICAgXCJyYW5nZVwiOiBbMC44LCA4XSxcbiAgICAgKiAgICAgXCJjb2xvclwiOiBcIiNkYzlmOWZcIixcbiAgICAgKiAgICAgXCJob3Jpem9uLWJsZW5kXCI6IDAuNSxcbiAgICAgKiAgICAgXCJoaWdoLWNvbG9yXCI6IFwiIzI0NWJkZVwiLFxuICAgICAqICAgICBcInNwYWNlLWNvbG9yXCI6IFwiIzAwMDAwMFwiLFxuICAgICAqICAgICBcInN0YXItaW50ZW5zaXR5XCI6IDAuMTVcbiAgICAgKiB9KTtcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBBZGQgZm9nIHRvIGEgbWFwXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9hZGQtZm9nLylcbiAgICAgKi9cbiAgICBzZXRGb2coZm9nOiBGb2dTcGVjaWZpY2F0aW9uKTogdGhpcyB7XG4gICAgICAgIHRoaXMuX2xhenlJbml0RW1wdHlTdHlsZSgpO1xuICAgICAgICB0aGlzLnN0eWxlLnNldEZvZyhmb2cpO1xuICAgICAgICByZXR1cm4gdGhpcy5fdXBkYXRlKHRydWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGZvZyBzcGVjaWZpY2F0aW9uIG9yIGBudWxsYCBpZiBmb2cgaXMgbm90IHNldCBvbiB0aGUgbWFwLlxuICAgICAqXG4gICAgICogQHJldHVybnMge0ZvZ1NwZWNpZmljYXRpb259IEZvZyBzcGVjaWZpY2F0aW9uIHByb3BlcnRpZXMgb2YgdGhlIHN0eWxlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgZm9nID0gbWFwLmdldEZvZygpO1xuICAgICAqL1xuICAgIGdldEZvZygpOiA/Rm9nU3BlY2lmaWNhdGlvbiB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0eWxlID8gdGhpcy5zdHlsZS5nZXRGb2coKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgZm9nIG9wYWNpdHkgZm9yIGEgZ2l2ZW4gbG9jYXRpb24uXG4gICAgICpcbiAgICAgKiBBbiBvcGFjaXR5IG9mIDAgbWVhbnMgdGhhdCB0aGVyZSBpcyBubyBmb2cgY29udHJpYnV0aW9uIGZvciB0aGUgZ2l2ZW4gbG9jYXRpb25cbiAgICAgKiB3aGlsZSBhIGZvZyBvcGFjaXR5IG9mIDEuMCBtZWFucyB0aGUgbG9jYXRpb24gaXMgZnVsbHkgb2JzY3VyZWQgYnkgdGhlIGZvZyBlZmZlY3QuXG4gICAgICpcbiAgICAgKiBJZiB0aGVyZSBpcyBubyBmb2cgc2V0IG9uIHRoZSBtYXAsIHRoaXMgZnVuY3Rpb24gd2lsbCByZXR1cm4gMC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7TG5nTGF0TGlrZX0gbG5nbGF0IFRoZSBnZW9ncmFwaGljYWwgbG9jYXRpb24gdG8gZXZhbHVhdGUgdGhlIGZvZyBvbi5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBBIHZhbHVlIGJldHdlZW4gMCBhbmQgMSByZXByZXNlbnRpbmcgdGhlIGZvZyBvcGFjaXR5LCB3aGVyZSAxIG1lYW5zIGZ1bGx5IHdpdGhpbiwgYW5kIDAgbWVhbnMgbm90IGFmZmVjdGVkIGJ5IHRoZSBmb2cgZWZmZWN0LlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgX3F1ZXJ5Rm9nT3BhY2l0eShsbmdsYXQ6IExuZ0xhdExpa2UpOiBudW1iZXIge1xuICAgICAgICBpZiAoIXRoaXMuc3R5bGUgfHwgIXRoaXMuc3R5bGUuZm9nKSByZXR1cm4gMC4wO1xuICAgICAgICByZXR1cm4gdGhpcy5zdHlsZS5mb2cuZ2V0T3BhY2l0eUF0TGF0TG5nKExuZ0xhdC5jb252ZXJ0KGxuZ2xhdCksIHRoaXMudHJhbnNmb3JtKTtcbiAgICB9XG5cbiAgICAvKiogQHNlY3Rpb24ge0ZlYXR1cmUgc3RhdGV9ICovXG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBgc3RhdGVgIG9mIGEgZmVhdHVyZS5cbiAgICAgKiBBIGZlYXR1cmUncyBgc3RhdGVgIGlzIGEgc2V0IG9mIHVzZXItZGVmaW5lZCBrZXktdmFsdWUgcGFpcnMgdGhhdCBhcmUgYXNzaWduZWQgdG8gYSBmZWF0dXJlIGF0IHJ1bnRpbWUuXG4gICAgICogV2hlbiB1c2luZyB0aGlzIG1ldGhvZCwgdGhlIGBzdGF0ZWAgb2JqZWN0IGlzIG1lcmdlZCB3aXRoIGFueSBleGlzdGluZyBrZXktdmFsdWUgcGFpcnMgaW4gdGhlIGZlYXR1cmUncyBzdGF0ZS5cbiAgICAgKiBGZWF0dXJlcyBhcmUgaWRlbnRpZmllZCBieSB0aGVpciBgaWRgIGF0dHJpYnV0ZSwgd2hpY2ggY2FuIGJlIGFueSBudW1iZXIgb3Igc3RyaW5nLlxuICAgICAqXG4gICAgICogVGhpcyBtZXRob2QgY2FuIG9ubHkgYmUgdXNlZCB3aXRoIHNvdXJjZXMgdGhhdCBoYXZlIGEgYGlkYCBhdHRyaWJ1dGUuIFRoZSBgaWRgIGF0dHJpYnV0ZSBjYW4gYmUgZGVmaW5lZCBpbiB0aHJlZSB3YXlzOlxuICAgICAqIC0gRm9yIHZlY3RvciBvciBHZW9KU09OIHNvdXJjZXMsIGluY2x1ZGluZyBhbiBgaWRgIGF0dHJpYnV0ZSBpbiB0aGUgb3JpZ2luYWwgZGF0YSBmaWxlLlxuICAgICAqIC0gRm9yIHZlY3RvciBvciBHZW9KU09OIHNvdXJjZXMsIHVzaW5nIHRoZSBbYHByb21vdGVJZGBdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9zdHlsZS1zcGVjL3NvdXJjZXMvI3ZlY3Rvci1wcm9tb3RlSWQpIG9wdGlvbiBhdCB0aGUgdGltZSB0aGUgc291cmNlIGlzIGRlZmluZWQuXG4gICAgICogLSBGb3IgR2VvSlNPTiBzb3VyY2VzLCB1c2luZyB0aGUgW2BnZW5lcmF0ZUlkYF0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL3N0eWxlLXNwZWMvc291cmNlcy8jZ2VvanNvbi1nZW5lcmF0ZUlkKSBvcHRpb24gdG8gYXV0by1hc3NpZ24gYW4gYGlkYCBiYXNlZCBvbiB0aGUgZmVhdHVyZSdzIGluZGV4IGluIHRoZSBzb3VyY2UgZGF0YS4gSWYgeW91IGNoYW5nZSBmZWF0dXJlIGRhdGEgdXNpbmcgYG1hcC5nZXRTb3VyY2UoJ3NvbWUgaWQnKS5zZXREYXRhKC4uLilgLCB5b3UgbWF5IG5lZWQgdG8gcmUtYXBwbHkgc3RhdGUgdGFraW5nIGludG8gYWNjb3VudCB1cGRhdGVkIGBpZGAgdmFsdWVzLlxuICAgICAqXG4gICAgICogX05vdGU6IFlvdSBjYW4gdXNlIHRoZSBbYGZlYXR1cmUtc3RhdGVgIGV4cHJlc3Npb25dKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9zdHlsZS1zcGVjL2V4cHJlc3Npb25zLyNmZWF0dXJlLXN0YXRlKSB0byBhY2Nlc3MgdGhlIHZhbHVlcyBpbiBhIGZlYXR1cmUncyBzdGF0ZSBvYmplY3QgZm9yIHRoZSBwdXJwb3NlcyBvZiBzdHlsaW5nXy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBmZWF0dXJlIEZlYXR1cmUgaWRlbnRpZmllci4gRmVhdHVyZSBvYmplY3RzIHJldHVybmVkIGZyb21cbiAgICAgKiB7QGxpbmsgTWFwI3F1ZXJ5UmVuZGVyZWRGZWF0dXJlc30gb3IgZXZlbnQgaGFuZGxlcnMgY2FuIGJlIHVzZWQgYXMgZmVhdHVyZSBpZGVudGlmaWVycy5cbiAgICAgKiBAcGFyYW0ge251bWJlciB8IHN0cmluZ30gZmVhdHVyZS5pZCBVbmlxdWUgaWQgb2YgdGhlIGZlYXR1cmUuIENhbiBiZSBhbiBpbnRlZ2VyIG9yIGEgc3RyaW5nLCBidXQgc3VwcG9ydHMgc3RyaW5nIHZhbHVlcyBvbmx5IHdoZW4gdGhlIFtgcHJvbW90ZUlkYF0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL3N0eWxlLXNwZWMvc291cmNlcy8jdmVjdG9yLXByb21vdGVJZCkgb3B0aW9uIGhhcyBiZWVuIGFwcGxpZWQgdG8gdGhlIHNvdXJjZSBvciB0aGUgc3RyaW5nIGNhbiBiZSBjYXN0IHRvIGFuIGludGVnZXIuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGZlYXR1cmUuc291cmNlIFRoZSBpZCBvZiB0aGUgdmVjdG9yIG9yIEdlb0pTT04gc291cmNlIGZvciB0aGUgZmVhdHVyZS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW2ZlYXR1cmUuc291cmNlTGF5ZXJdIChvcHRpb25hbCkgKkZvciB2ZWN0b3IgdGlsZSBzb3VyY2VzLCBgc291cmNlTGF5ZXJgIGlzIHJlcXVpcmVkKi5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc3RhdGUgQSBzZXQgb2Yga2V5LXZhbHVlIHBhaXJzLiBUaGUgdmFsdWVzIHNob3VsZCBiZSB2YWxpZCBKU09OIHR5cGVzLlxuICAgICAqIEByZXR1cm5zIHtNYXB9IFRoZSBtYXAgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gV2hlbiB0aGUgbW91c2UgbW92ZXMgb3ZlciB0aGUgYG15LWxheWVyYCBsYXllciwgdXBkYXRlXG4gICAgICogLy8gdGhlIGZlYXR1cmUgc3RhdGUgZm9yIHRoZSBmZWF0dXJlIHVuZGVyIHRoZSBtb3VzZVxuICAgICAqIG1hcC5vbignbW91c2Vtb3ZlJywgJ215LWxheWVyJywgKGUpID0+IHtcbiAgICAgKiAgICAgaWYgKGUuZmVhdHVyZXMubGVuZ3RoID4gMCkge1xuICAgICAqICAgICAgICAgbWFwLnNldEZlYXR1cmVTdGF0ZSh7XG4gICAgICogICAgICAgICAgICAgc291cmNlOiAnbXktc291cmNlJyxcbiAgICAgKiAgICAgICAgICAgICBzb3VyY2VMYXllcjogJ215LXNvdXJjZS1sYXllcicsXG4gICAgICogICAgICAgICAgICAgaWQ6IGUuZmVhdHVyZXNbMF0uaWQsXG4gICAgICogICAgICAgICB9LCB7XG4gICAgICogICAgICAgICAgICAgaG92ZXI6IHRydWVcbiAgICAgKiAgICAgICAgIH0pO1xuICAgICAqICAgICB9XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBAc2VlIFtFeGFtcGxlOiBDcmVhdGUgYSBob3ZlciBlZmZlY3RdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2hvdmVyLXN0eWxlcy8pXG4gICAgICogQHNlZSBbVHV0b3JpYWw6IENyZWF0ZSBpbnRlcmFjdGl2ZSBob3ZlciBlZmZlY3RzIHdpdGggTWFwYm94IEdMIEpTXShodHRwczovL2RvY3MubWFwYm94LmNvbS9oZWxwL3R1dG9yaWFscy9jcmVhdGUtaW50ZXJhY3RpdmUtaG92ZXItZWZmZWN0cy13aXRoLW1hcGJveC1nbC1qcy8pXG4gICAgICovXG4gICAgc2V0RmVhdHVyZVN0YXRlKGZlYXR1cmU6IHsgc291cmNlOiBzdHJpbmc7IHNvdXJjZUxheWVyPzogc3RyaW5nOyBpZDogc3RyaW5nIHwgbnVtYmVyOyB9LCBzdGF0ZTogT2JqZWN0KTogdGhpcyB7XG4gICAgICAgIHRoaXMuc3R5bGUuc2V0RmVhdHVyZVN0YXRlKGZlYXR1cmUsIHN0YXRlKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3VwZGF0ZSgpO1xuICAgIH1cblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLXJldHVybnNcbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIHRoZSBgc3RhdGVgIG9mIGEgZmVhdHVyZSwgc2V0dGluZyBpdCBiYWNrIHRvIHRoZSBkZWZhdWx0IGJlaGF2aW9yLlxuICAgICAqIElmIG9ubHkgYSBgZmVhdHVyZS5zb3VyY2VgIGlzIHNwZWNpZmllZCwgaXQgd2lsbCByZW1vdmUgdGhlIHN0YXRlIGZvciBhbGwgZmVhdHVyZXMgZnJvbSB0aGF0IHNvdXJjZS5cbiAgICAgKiBJZiBgZmVhdHVyZS5pZGAgaXMgYWxzbyBzcGVjaWZpZWQsIGl0IHdpbGwgcmVtb3ZlIGFsbCBrZXlzIGZvciB0aGF0IGZlYXR1cmUncyBzdGF0ZS5cbiAgICAgKiBJZiBga2V5YCBpcyBhbHNvIHNwZWNpZmllZCwgaXQgcmVtb3ZlcyBvbmx5IHRoYXQga2V5IGZyb20gdGhhdCBmZWF0dXJlJ3Mgc3RhdGUuXG4gICAgICogRmVhdHVyZXMgYXJlIGlkZW50aWZpZWQgYnkgdGhlaXIgYGZlYXR1cmUuaWRgIGF0dHJpYnV0ZSwgd2hpY2ggY2FuIGJlIGFueSBudW1iZXIgb3Igc3RyaW5nLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGZlYXR1cmUgSWRlbnRpZmllciBvZiB3aGVyZSB0byByZW1vdmUgc3RhdGUuIEl0IGNhbiBiZSBhIHNvdXJjZSwgYSBmZWF0dXJlLCBvciBhIHNwZWNpZmljIGtleSBvZiBmZWF0dXJlLlxuICAgICAqIEZlYXR1cmUgb2JqZWN0cyByZXR1cm5lZCBmcm9tIHtAbGluayBNYXAjcXVlcnlSZW5kZXJlZEZlYXR1cmVzfSBvciBldmVudCBoYW5kbGVycyBjYW4gYmUgdXNlZCBhcyBmZWF0dXJlIGlkZW50aWZpZXJzLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyIHwgc3RyaW5nfSBbZmVhdHVyZS5pZF0gKG9wdGlvbmFsKSBVbmlxdWUgaWQgb2YgdGhlIGZlYXR1cmUuIENhbiBiZSBhbiBpbnRlZ2VyIG9yIGEgc3RyaW5nLCBidXQgc3VwcG9ydHMgc3RyaW5nIHZhbHVlcyBvbmx5IHdoZW4gdGhlIFtgcHJvbW90ZUlkYF0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL3N0eWxlLXNwZWMvc291cmNlcy8jdmVjdG9yLXByb21vdGVJZCkgb3B0aW9uIGhhcyBiZWVuIGFwcGxpZWQgdG8gdGhlIHNvdXJjZSBvciB0aGUgc3RyaW5nIGNhbiBiZSBjYXN0IHRvIGFuIGludGVnZXIuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGZlYXR1cmUuc291cmNlIFRoZSBpZCBvZiB0aGUgdmVjdG9yIG9yIEdlb0pTT04gc291cmNlIGZvciB0aGUgZmVhdHVyZS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW2ZlYXR1cmUuc291cmNlTGF5ZXJdIChvcHRpb25hbCkgRm9yIHZlY3RvciB0aWxlIHNvdXJjZXMsIGBzb3VyY2VMYXllcmAgaXMgcmVxdWlyZWQuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtrZXldIChvcHRpb25hbCkgVGhlIGtleSBpbiB0aGUgZmVhdHVyZSBzdGF0ZSB0byByZXNldC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gUmVzZXQgdGhlIGVudGlyZSBzdGF0ZSBvYmplY3QgZm9yIGFsbCBmZWF0dXJlc1xuICAgICAqIC8vIGluIHRoZSBgbXktc291cmNlYCBzb3VyY2VcbiAgICAgKiBtYXAucmVtb3ZlRmVhdHVyZVN0YXRlKHtcbiAgICAgKiAgICAgc291cmNlOiAnbXktc291cmNlJ1xuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBXaGVuIHRoZSBtb3VzZSBsZWF2ZXMgdGhlIGBteS1sYXllcmAgbGF5ZXIsXG4gICAgICogLy8gcmVzZXQgdGhlIGVudGlyZSBzdGF0ZSBvYmplY3QgZm9yIHRoZVxuICAgICAqIC8vIGZlYXR1cmUgdW5kZXIgdGhlIG1vdXNlXG4gICAgICogbWFwLm9uKCdtb3VzZWxlYXZlJywgJ215LWxheWVyJywgKGUpID0+IHtcbiAgICAgKiAgICAgbWFwLnJlbW92ZUZlYXR1cmVTdGF0ZSh7XG4gICAgICogICAgICAgICBzb3VyY2U6ICdteS1zb3VyY2UnLFxuICAgICAqICAgICAgICAgc291cmNlTGF5ZXI6ICdteS1zb3VyY2UtbGF5ZXInLFxuICAgICAqICAgICAgICAgaWQ6IGUuZmVhdHVyZXNbMF0uaWRcbiAgICAgKiAgICAgfSk7XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIFdoZW4gdGhlIG1vdXNlIGxlYXZlcyB0aGUgYG15LWxheWVyYCBsYXllcixcbiAgICAgKiAvLyByZXNldCBvbmx5IHRoZSBgaG92ZXJgIGtleS12YWx1ZSBwYWlyIGluIHRoZVxuICAgICAqIC8vIHN0YXRlIGZvciB0aGUgZmVhdHVyZSB1bmRlciB0aGUgbW91c2VcbiAgICAgKiBtYXAub24oJ21vdXNlbGVhdmUnLCAnbXktbGF5ZXInLCAoZSkgPT4ge1xuICAgICAqICAgICBtYXAucmVtb3ZlRmVhdHVyZVN0YXRlKHtcbiAgICAgKiAgICAgICAgIHNvdXJjZTogJ215LXNvdXJjZScsXG4gICAgICogICAgICAgICBzb3VyY2VMYXllcjogJ215LXNvdXJjZS1sYXllcicsXG4gICAgICogICAgICAgICBpZDogZS5mZWF0dXJlc1swXS5pZFxuICAgICAqICAgICB9LCAnaG92ZXInKTtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqL1xuICAgIHJlbW92ZUZlYXR1cmVTdGF0ZShmZWF0dXJlOiB7IHNvdXJjZTogc3RyaW5nOyBzb3VyY2VMYXllcj86IHN0cmluZzsgaWQ/OiBzdHJpbmcgfCBudW1iZXI7IH0sIGtleT86IHN0cmluZyk6IHRoaXMge1xuICAgICAgICB0aGlzLnN0eWxlLnJlbW92ZUZlYXR1cmVTdGF0ZShmZWF0dXJlLCBrZXkpO1xuICAgICAgICByZXR1cm4gdGhpcy5fdXBkYXRlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgYHN0YXRlYCBvZiBhIGZlYXR1cmUuXG4gICAgICogQSBmZWF0dXJlJ3MgYHN0YXRlYCBpcyBhIHNldCBvZiB1c2VyLWRlZmluZWQga2V5LXZhbHVlIHBhaXJzIHRoYXQgYXJlIGFzc2lnbmVkIHRvIGEgZmVhdHVyZSBhdCBydW50aW1lLlxuICAgICAqIEZlYXR1cmVzIGFyZSBpZGVudGlmaWVkIGJ5IHRoZWlyIGBpZGAgYXR0cmlidXRlLCB3aGljaCBjYW4gYmUgYW55IG51bWJlciBvciBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBfTm90ZTogVG8gYWNjZXNzIHRoZSB2YWx1ZXMgaW4gYSBmZWF0dXJlJ3Mgc3RhdGUgb2JqZWN0IGZvciB0aGUgcHVycG9zZXMgb2Ygc3R5bGluZyB0aGUgZmVhdHVyZSwgdXNlIHRoZSBbYGZlYXR1cmUtc3RhdGVgIGV4cHJlc3Npb25dKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9zdHlsZS1zcGVjL2V4cHJlc3Npb25zLyNmZWF0dXJlLXN0YXRlKV8uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gZmVhdHVyZSBGZWF0dXJlIGlkZW50aWZpZXIuIEZlYXR1cmUgb2JqZWN0cyByZXR1cm5lZCBmcm9tXG4gICAgICoge0BsaW5rIE1hcCNxdWVyeVJlbmRlcmVkRmVhdHVyZXN9IG9yIGV2ZW50IGhhbmRsZXJzIGNhbiBiZSB1c2VkIGFzIGZlYXR1cmUgaWRlbnRpZmllcnMuXG4gICAgICogQHBhcmFtIHtudW1iZXIgfCBzdHJpbmd9IGZlYXR1cmUuaWQgVW5pcXVlIGlkIG9mIHRoZSBmZWF0dXJlLiBDYW4gYmUgYW4gaW50ZWdlciBvciBhIHN0cmluZywgYnV0IHN1cHBvcnRzIHN0cmluZyB2YWx1ZXMgb25seSB3aGVuIHRoZSBbYHByb21vdGVJZGBdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9zdHlsZS1zcGVjL3NvdXJjZXMvI3ZlY3Rvci1wcm9tb3RlSWQpIG9wdGlvbiBoYXMgYmVlbiBhcHBsaWVkIHRvIHRoZSBzb3VyY2Ugb3IgdGhlIHN0cmluZyBjYW4gYmUgY2FzdCB0byBhbiBpbnRlZ2VyLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBmZWF0dXJlLnNvdXJjZSBUaGUgaWQgb2YgdGhlIHZlY3RvciBvciBHZW9KU09OIHNvdXJjZSBmb3IgdGhlIGZlYXR1cmUuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtmZWF0dXJlLnNvdXJjZUxheWVyXSAob3B0aW9uYWwpICpGb3IgdmVjdG9yIHRpbGUgc291cmNlcywgYHNvdXJjZUxheWVyYCBpcyByZXF1aXJlZCouXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBUaGUgc3RhdGUgb2YgdGhlIGZlYXR1cmU6IGEgc2V0IG9mIGtleS12YWx1ZSBwYWlycyB0aGF0IHdhcyBhc3NpZ25lZCB0byB0aGUgZmVhdHVyZSBhdCBydW50aW1lLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBXaGVuIHRoZSBtb3VzZSBtb3ZlcyBvdmVyIHRoZSBgbXktbGF5ZXJgIGxheWVyLFxuICAgICAqIC8vIGdldCB0aGUgZmVhdHVyZSBzdGF0ZSBmb3IgdGhlIGZlYXR1cmUgdW5kZXIgdGhlIG1vdXNlXG4gICAgICogbWFwLm9uKCdtb3VzZW1vdmUnLCAnbXktbGF5ZXInLCAoZSkgPT4ge1xuICAgICAqICAgICBpZiAoZS5mZWF0dXJlcy5sZW5ndGggPiAwKSB7XG4gICAgICogICAgICAgICBtYXAuZ2V0RmVhdHVyZVN0YXRlKHtcbiAgICAgKiAgICAgICAgICAgICBzb3VyY2U6ICdteS1zb3VyY2UnLFxuICAgICAqICAgICAgICAgICAgIHNvdXJjZUxheWVyOiAnbXktc291cmNlLWxheWVyJyxcbiAgICAgKiAgICAgICAgICAgICBpZDogZS5mZWF0dXJlc1swXS5pZFxuICAgICAqICAgICAgICAgfSk7XG4gICAgICogICAgIH1cbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqL1xuICAgIGdldEZlYXR1cmVTdGF0ZShmZWF0dXJlOiB7IHNvdXJjZTogc3RyaW5nOyBzb3VyY2VMYXllcj86IHN0cmluZzsgaWQ6IHN0cmluZyB8IG51bWJlcjsgfSk6IGFueSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0eWxlLmdldEZlYXR1cmVTdGF0ZShmZWF0dXJlKTtcbiAgICB9XG5cbiAgICBfdXBkYXRlQ29udGFpbmVyRGltZW5zaW9ucygpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9jb250YWluZXIpIHJldHVybjtcblxuICAgICAgICBjb25zdCB3aWR0aCA9IHRoaXMuX2NvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCB8fCA0MDA7XG4gICAgICAgIGNvbnN0IGhlaWdodCA9IHRoaXMuX2NvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5oZWlnaHQgfHwgMzAwO1xuXG4gICAgICAgIGxldCB0cmFuc2Zvcm1WYWx1ZXM7XG4gICAgICAgIGxldCB0cmFuc2Zvcm1TY2FsZVdpZHRoO1xuICAgICAgICBsZXQgdHJhbnNmb3JtU2NhbGVIZWlnaHQ7XG4gICAgICAgIGxldCBlbDogP0VsZW1lbnQgPSB0aGlzLl9jb250YWluZXI7XG4gICAgICAgIHdoaWxlIChlbCAmJiAoIXRyYW5zZm9ybVNjYWxlV2lkdGggfHwgIXRyYW5zZm9ybVNjYWxlSGVpZ2h0KSkge1xuICAgICAgICAgICAgY29uc3QgdHJhbnNmb3JtTWF0cml4ID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWwpLnRyYW5zZm9ybTtcbiAgICAgICAgICAgIGlmICh0cmFuc2Zvcm1NYXRyaXggJiYgdHJhbnNmb3JtTWF0cml4ICE9PSAnbm9uZScpIHtcbiAgICAgICAgICAgICAgICB0cmFuc2Zvcm1WYWx1ZXMgPSB0cmFuc2Zvcm1NYXRyaXgubWF0Y2goL21hdHJpeC4qXFwoKC4rKVxcKS8pWzFdLnNwbGl0KCcsICcpO1xuICAgICAgICAgICAgICAgIGlmICh0cmFuc2Zvcm1WYWx1ZXNbMF0gJiYgdHJhbnNmb3JtVmFsdWVzWzBdICE9PSAnMCcgJiYgdHJhbnNmb3JtVmFsdWVzWzBdICE9PSAnMScpIHRyYW5zZm9ybVNjYWxlV2lkdGggPSB0cmFuc2Zvcm1WYWx1ZXNbMF07XG4gICAgICAgICAgICAgICAgaWYgKHRyYW5zZm9ybVZhbHVlc1szXSAmJiB0cmFuc2Zvcm1WYWx1ZXNbM10gIT09ICcwJyAmJiB0cmFuc2Zvcm1WYWx1ZXNbM10gIT09ICcxJykgdHJhbnNmb3JtU2NhbGVIZWlnaHQgPSB0cmFuc2Zvcm1WYWx1ZXNbM107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbCA9IGVsLnBhcmVudEVsZW1lbnQ7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9jb250YWluZXJXaWR0aCA9IHRyYW5zZm9ybVNjYWxlV2lkdGggPyBNYXRoLmFicyh3aWR0aCAvIHRyYW5zZm9ybVNjYWxlV2lkdGgpIDogd2lkdGg7XG4gICAgICAgIHRoaXMuX2NvbnRhaW5lckhlaWdodCA9IHRyYW5zZm9ybVNjYWxlSGVpZ2h0ID8gTWF0aC5hYnMoaGVpZ2h0IC8gdHJhbnNmb3JtU2NhbGVIZWlnaHQpIDogaGVpZ2h0O1xuICAgIH1cblxuICAgIF9kZXRlY3RNaXNzaW5nQ1NTKCk6IHZvaWQge1xuICAgICAgICBjb25zdCBjb21wdXRlZENvbG9yID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy5fbWlzc2luZ0NTU0NhbmFyeSkuZ2V0UHJvcGVydHlWYWx1ZSgnYmFja2dyb3VuZC1jb2xvcicpO1xuICAgICAgICBpZiAoY29tcHV0ZWRDb2xvciAhPT0gJ3JnYigyNTAsIDEyOCwgMTE0KScpIHtcbiAgICAgICAgICAgIHdhcm5PbmNlKCdUaGlzIHBhZ2UgYXBwZWFycyB0byBiZSBtaXNzaW5nIENTUyBkZWNsYXJhdGlvbnMgZm9yICcgK1xuICAgICAgICAgICAgICAgICdNYXBib3ggR0wgSlMsIHdoaWNoIG1heSBjYXVzZSB0aGUgbWFwIHRvIGRpc3BsYXkgaW5jb3JyZWN0bHkuICcgK1xuICAgICAgICAgICAgICAgICdQbGVhc2UgZW5zdXJlIHlvdXIgcGFnZSBpbmNsdWRlcyBtYXBib3gtZ2wuY3NzLCBhcyBkZXNjcmliZWQgJyArXG4gICAgICAgICAgICAgICAgJ2luIGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2FwaS8uJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfc2V0dXBDb250YWluZXIoKSB7XG4gICAgICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMuX2NvbnRhaW5lcjtcbiAgICAgICAgY29udGFpbmVyLmNsYXNzTGlzdC5hZGQoJ21hcGJveGdsLW1hcCcpO1xuXG4gICAgICAgIGNvbnN0IG1pc3NpbmdDU1NDYW5hcnkgPSB0aGlzLl9taXNzaW5nQ1NTQ2FuYXJ5ID0gRE9NLmNyZWF0ZSgnZGl2JywgJ21hcGJveGdsLWNhbmFyeScsIGNvbnRhaW5lcik7XG4gICAgICAgIG1pc3NpbmdDU1NDYW5hcnkuc3R5bGUudmlzaWJpbGl0eSA9ICdoaWRkZW4nO1xuICAgICAgICB0aGlzLl9kZXRlY3RNaXNzaW5nQ1NTKCk7XG5cbiAgICAgICAgY29uc3QgY2FudmFzQ29udGFpbmVyID0gdGhpcy5fY2FudmFzQ29udGFpbmVyID0gRE9NLmNyZWF0ZSgnZGl2JywgJ21hcGJveGdsLWNhbnZhcy1jb250YWluZXInLCBjb250YWluZXIpO1xuICAgICAgICBpZiAodGhpcy5faW50ZXJhY3RpdmUpIHtcbiAgICAgICAgICAgIGNhbnZhc0NvbnRhaW5lci5jbGFzc0xpc3QuYWRkKCdtYXBib3hnbC1pbnRlcmFjdGl2ZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fY2FudmFzID0gRE9NLmNyZWF0ZSgnY2FudmFzJywgJ21hcGJveGdsLWNhbnZhcycsIGNhbnZhc0NvbnRhaW5lcik7XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgdGhpcy5fY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoJ3dlYmdsY29udGV4dGxvc3QnLCB0aGlzLl9jb250ZXh0TG9zdCwgZmFsc2UpO1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIHRoaXMuX2NhbnZhcy5hZGRFdmVudExpc3RlbmVyKCd3ZWJnbGNvbnRleHRyZXN0b3JlZCcsIHRoaXMuX2NvbnRleHRSZXN0b3JlZCwgZmFsc2UpO1xuICAgICAgICB0aGlzLl9jYW52YXMuc2V0QXR0cmlidXRlKCd0YWJpbmRleCcsICcwJyk7XG4gICAgICAgIHRoaXMuX2NhbnZhcy5zZXRBdHRyaWJ1dGUoJ2FyaWEtbGFiZWwnLCB0aGlzLl9nZXRVSVN0cmluZygnTWFwLlRpdGxlJykpO1xuICAgICAgICB0aGlzLl9jYW52YXMuc2V0QXR0cmlidXRlKCdyb2xlJywgJ3JlZ2lvbicpO1xuXG4gICAgICAgIHRoaXMuX3VwZGF0ZUNvbnRhaW5lckRpbWVuc2lvbnMoKTtcbiAgICAgICAgdGhpcy5fcmVzaXplQ2FudmFzKHRoaXMuX2NvbnRhaW5lcldpZHRoLCB0aGlzLl9jb250YWluZXJIZWlnaHQpO1xuXG4gICAgICAgIGNvbnN0IGNvbnRyb2xDb250YWluZXIgPSB0aGlzLl9jb250cm9sQ29udGFpbmVyID0gRE9NLmNyZWF0ZSgnZGl2JywgJ21hcGJveGdsLWNvbnRyb2wtY29udGFpbmVyJywgY29udGFpbmVyKTtcbiAgICAgICAgY29uc3QgcG9zaXRpb25zID0gdGhpcy5fY29udHJvbFBvc2l0aW9ucyA9IHt9O1xuICAgICAgICBbJ3RvcC1sZWZ0JywgJ3RvcC1yaWdodCcsICdib3R0b20tbGVmdCcsICdib3R0b20tcmlnaHQnXS5mb3JFYWNoKChwb3NpdGlvbk5hbWUpID0+IHtcbiAgICAgICAgICAgIHBvc2l0aW9uc1twb3NpdGlvbk5hbWVdID0gRE9NLmNyZWF0ZSgnZGl2JywgYG1hcGJveGdsLWN0cmwtJHtwb3NpdGlvbk5hbWV9YCwgY29udHJvbENvbnRhaW5lcik7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgdGhpcy5fY29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHRoaXMuX29uTWFwU2Nyb2xsLCBmYWxzZSk7XG4gICAgfVxuXG4gICAgX3Jlc2l6ZUNhbnZhcyh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgICAgICBjb25zdCBwaXhlbFJhdGlvID0gYnJvd3Nlci5kZXZpY2VQaXhlbFJhdGlvIHx8IDE7XG5cbiAgICAgICAgLy8gUmVxdWVzdCB0aGUgcmVxdWlyZWQgY2FudmFzIHNpemUgKHJvdW5kZWQgdXApIHRha2luZyB0aGUgcGl4ZWxyYXRpbyBpbnRvIGFjY291bnQuXG4gICAgICAgIHRoaXMuX2NhbnZhcy53aWR0aCA9IHBpeGVsUmF0aW8gKiBNYXRoLmNlaWwod2lkdGgpO1xuICAgICAgICB0aGlzLl9jYW52YXMuaGVpZ2h0ID0gcGl4ZWxSYXRpbyAqIE1hdGguY2VpbChoZWlnaHQpO1xuXG4gICAgICAgIC8vIE1haW50YWluIHRoZSBzYW1lIGNhbnZhcyBzaXplLCBwb3RlbnRpYWxseSBkb3duc2NhbGluZyBpdCBmb3IgSGlEUEkgZGlzcGxheXNcbiAgICAgICAgdGhpcy5fY2FudmFzLnN0eWxlLndpZHRoID0gYCR7d2lkdGh9cHhgO1xuICAgICAgICB0aGlzLl9jYW52YXMuc3R5bGUuaGVpZ2h0ID0gYCR7aGVpZ2h0fXB4YDtcbiAgICB9XG5cbiAgICBfYWRkTWFya2VyKG1hcmtlcjogTWFya2VyKSB7XG4gICAgICAgIHRoaXMuX21hcmtlcnMucHVzaChtYXJrZXIpO1xuICAgIH1cblxuICAgIF9yZW1vdmVNYXJrZXIobWFya2VyOiBNYXJrZXIpIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl9tYXJrZXJzLmluZGV4T2YobWFya2VyKTtcbiAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5fbWFya2Vycy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX2FkZFBvcHVwKHBvcHVwOiBQb3B1cCkge1xuICAgICAgICB0aGlzLl9wb3B1cHMucHVzaChwb3B1cCk7XG4gICAgfVxuXG4gICAgX3JlbW92ZVBvcHVwKHBvcHVwOiBQb3B1cCkge1xuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3BvcHVwcy5pbmRleE9mKHBvcHVwKTtcbiAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5fcG9wdXBzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfc2V0dXBQYWludGVyKCkge1xuICAgICAgICBjb25zdCBhdHRyaWJ1dGVzID0gZXh0ZW5kKHt9LCBzdXBwb3J0ZWQud2ViR0xDb250ZXh0QXR0cmlidXRlcywge1xuICAgICAgICAgICAgZmFpbElmTWFqb3JQZXJmb3JtYW5jZUNhdmVhdDogdGhpcy5fZmFpbElmTWFqb3JQZXJmb3JtYW5jZUNhdmVhdCxcbiAgICAgICAgICAgIHByZXNlcnZlRHJhd2luZ0J1ZmZlcjogdGhpcy5fcHJlc2VydmVEcmF3aW5nQnVmZmVyLFxuICAgICAgICAgICAgYW50aWFsaWFzOiB0aGlzLl9hbnRpYWxpYXMgfHwgZmFsc2VcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgZ2wyID0gdGhpcy5fdXNlV2ViR0wyICYmICgodGhpcy5fY2FudmFzLmdldENvbnRleHQoXCJ3ZWJnbDJcIiwgYXR0cmlidXRlcyk6IGFueSk6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCk7XG4gICAgICAgIGNvbnN0IGdsID0gZ2wyIHx8XG4gICAgICAgICAgICB0aGlzLl9jYW52YXMuZ2V0Q29udGV4dCgnd2ViZ2wnLCBhdHRyaWJ1dGVzKSB8fFxuICAgICAgICAgICAgdGhpcy5fY2FudmFzLmdldENvbnRleHQoJ2V4cGVyaW1lbnRhbC13ZWJnbCcsIGF0dHJpYnV0ZXMpO1xuXG4gICAgICAgIGlmICghZ2wpIHtcbiAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXJyb3JFdmVudChuZXcgRXJyb3IoJ0ZhaWxlZCB0byBpbml0aWFsaXplIFdlYkdMJykpKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLl91c2VXZWJHTDIgJiYgIWdsMikge1xuICAgICAgICAgICAgd2Fybk9uY2UoJ0ZhaWxlZCB0byBjcmVhdGUgV2ViR0wgMiBjb250ZXh0LiBVc2luZyBXZWJHTCAxLicpO1xuICAgICAgICB9XG4gICAgICAgIHN0b3JlQXV0aFN0YXRlKGdsLCB0cnVlKTtcblxuICAgICAgICB0aGlzLnBhaW50ZXIgPSBuZXcgUGFpbnRlcihnbCwgdGhpcy50cmFuc2Zvcm0sICEhZ2wyKTtcbiAgICAgICAgdGhpcy5vbignZGF0YScsIChldmVudDogTWFwRGF0YUV2ZW50KSA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQuZGF0YVR5cGUgPT09ICdzb3VyY2UnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wYWludGVyLnNldFRpbGVMb2FkZWRGbGFnKHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICB3ZWJwU3VwcG9ydGVkLnRlc3RTdXBwb3J0KGdsKTtcbiAgICB9XG5cbiAgICBfY29udGV4dExvc3QoZXZlbnQ6IGFueSkge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBpZiAodGhpcy5fZnJhbWUpIHtcbiAgICAgICAgICAgIHRoaXMuX2ZyYW1lLmNhbmNlbCgpO1xuICAgICAgICAgICAgdGhpcy5fZnJhbWUgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ3dlYmdsY29udGV4dGxvc3QnLCB7b3JpZ2luYWxFdmVudDogZXZlbnR9KSk7XG4gICAgfVxuXG4gICAgX2NvbnRleHRSZXN0b3JlZChldmVudDogYW55KSB7XG4gICAgICAgIHRoaXMuX3NldHVwUGFpbnRlcigpO1xuICAgICAgICB0aGlzLnJlc2l6ZSgpO1xuICAgICAgICB0aGlzLl91cGRhdGUoKTtcbiAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgnd2ViZ2xjb250ZXh0cmVzdG9yZWQnLCB7b3JpZ2luYWxFdmVudDogZXZlbnR9KSk7XG4gICAgfVxuXG4gICAgX29uTWFwU2Nyb2xsKGV2ZW50OiBhbnkpOiA/Ym9vbGVhbiB7XG4gICAgICAgIGlmIChldmVudC50YXJnZXQgIT09IHRoaXMuX2NvbnRhaW5lcikgcmV0dXJuO1xuXG4gICAgICAgIC8vIFJldmVydCBhbnkgc2Nyb2xsIHdoaWNoIHdvdWxkIG1vdmUgdGhlIGNhbnZhcyBvdXRzaWRlIG9mIHRoZSB2aWV3XG4gICAgICAgIHRoaXMuX2NvbnRhaW5lci5zY3JvbGxUb3AgPSAwO1xuICAgICAgICB0aGlzLl9jb250YWluZXIuc2Nyb2xsTGVmdCA9IDA7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvKiogQHNlY3Rpb24ge0xpZmVjeWNsZX0gKi9cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBCb29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGUgbWFwIGlzIGZ1bGx5IGxvYWRlZC5cbiAgICAgKlxuICAgICAqIFJldHVybnMgYGZhbHNlYCBpZiB0aGUgc3R5bGUgaXMgbm90IHlldCBmdWxseSBsb2FkZWQsXG4gICAgICogb3IgaWYgdGhlcmUgaGFzIGJlZW4gYSBjaGFuZ2UgdG8gdGhlIHNvdXJjZXMgb3Igc3R5bGUgdGhhdFxuICAgICAqIGhhcyBub3QgeWV0IGZ1bGx5IGxvYWRlZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBBIEJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIHRoZSBtYXAgaXMgZnVsbHkgbG9hZGVkLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgaXNMb2FkZWQgPSBtYXAubG9hZGVkKCk7XG4gICAgICovXG4gICAgbG9hZGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gIXRoaXMuX3N0eWxlRGlydHkgJiYgIXRoaXMuX3NvdXJjZXNEaXJ0eSAmJiAhIXRoaXMuc3R5bGUgJiYgdGhpcy5zdHlsZS5sb2FkZWQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGhpcyBtYXAncyBzdHlsZSBhbmQgc291cmNlcywgYW5kIHJlLXJlbmRlciB0aGUgbWFwLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtib29sZWFufSB1cGRhdGVTdHlsZSBtYXJrIHRoZSBtYXAncyBzdHlsZSBmb3IgcmVwcm9jZXNzaW5nIGFzXG4gICAgICogd2VsbCBhcyBpdHMgc291cmNlc1xuICAgICAqIEByZXR1cm5zIHtNYXB9IHRoaXNcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF91cGRhdGUodXBkYXRlU3R5bGU/OiBib29sZWFuKTogdGhpcyB7XG4gICAgICAgIGlmICghdGhpcy5zdHlsZSkgcmV0dXJuIHRoaXM7XG5cbiAgICAgICAgdGhpcy5fc3R5bGVEaXJ0eSA9IHRoaXMuX3N0eWxlRGlydHkgfHwgdXBkYXRlU3R5bGU7XG4gICAgICAgIHRoaXMuX3NvdXJjZXNEaXJ0eSA9IHRydWU7XG4gICAgICAgIHRoaXMudHJpZ2dlclJlcGFpbnQoKTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXF1ZXN0IHRoYXQgdGhlIGdpdmVuIGNhbGxiYWNrIGJlIGV4ZWN1dGVkIGR1cmluZyB0aGUgbmV4dCByZW5kZXJcbiAgICAgKiBmcmFtZS4gIFNjaGVkdWxlIGEgcmVuZGVyIGZyYW1lIGlmIG9uZSBpcyBub3QgYWxyZWFkeSBzY2hlZHVsZWQuXG4gICAgICogQHJldHVybnMgQW4gaWQgdGhhdCBjYW4gYmUgdXNlZCB0byBjYW5jZWwgdGhlIGNhbGxiYWNrXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgX3JlcXVlc3RSZW5kZXJGcmFtZShjYWxsYmFjazogKCkgPT4gdm9pZCk6IFRhc2tJRCB7XG4gICAgICAgIHRoaXMuX3VwZGF0ZSgpO1xuICAgICAgICByZXR1cm4gdGhpcy5fcmVuZGVyVGFza1F1ZXVlLmFkZChjYWxsYmFjayk7XG4gICAgfVxuXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIF9jYW5jZWxSZW5kZXJGcmFtZShpZDogVGFza0lEKSB7XG4gICAgICAgIHRoaXMuX3JlbmRlclRhc2tRdWV1ZS5yZW1vdmUoaWQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlcXVlc3QgdGhhdCB0aGUgZ2l2ZW4gY2FsbGJhY2sgYmUgZXhlY3V0ZWQgZHVyaW5nIHRoZSBuZXh0IHJlbmRlciBmcmFtZSBpZiB0aGUgbWFwIGlzIG5vdFxuICAgICAqIGlkbGUuIE90aGVyd2lzZSBpdCBpcyBleGVjdXRlZCBpbW1lZGlhdGVseSwgdG8gYXZvaWQgdHJpZ2dlcmluZyBhIG5ldyByZW5kZXIuXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBfcmVxdWVzdERvbVRhc2soY2FsbGJhY2s6ICgpID0+IHZvaWQpIHtcbiAgICAgICAgLy8gVGhpcyBjb25kaXRpb24gbWVhbnMgdGhhdCB0aGUgbWFwIGlzIGlkbGU6IHRoZSBjYWxsYmFjayBuZWVkcyB0byBiZSBjYWxsZWQgcmlnaHQgbm93IGFzXG4gICAgICAgIC8vIHRoZXJlIHdvbid0IGJlIGEgdHJpZ2dlcmVkIHJlbmRlciB0byBydW4gdGhlIHF1ZXVlLlxuICAgICAgICBpZiAoIXRoaXMubG9hZGVkKCkgfHwgKHRoaXMubG9hZGVkKCkgJiYgIXRoaXMuaXNNb3ZpbmcoKSkpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9kb21SZW5kZXJUYXNrUXVldWUuYWRkKGNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGwgd2hlbiBhIChyZS0pcmVuZGVyIG9mIHRoZSBtYXAgaXMgcmVxdWlyZWQ6XG4gICAgICogLSBUaGUgc3R5bGUgaGFzIGNoYW5nZWQgKGBzZXRQYWludFByb3BlcnR5KClgLCBldGMuKVxuICAgICAqIC0gU291cmNlIGRhdGEgaGFzIGNoYW5nZWQgKGZvciBleGFtcGxlLCB0aWxlcyBoYXZlIGZpbmlzaGVkIGxvYWRpbmcpXG4gICAgICogLSBUaGUgbWFwIGhhcyBpcyBtb3ZpbmcgKG9yIGp1c3QgZmluaXNoZWQgbW92aW5nKVxuICAgICAqIC0gQSB0cmFuc2l0aW9uIGlzIGluIHByb2dyZXNzXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcGFpbnRTdGFydFRpbWVTdGFtcCAgVGhlIHRpbWUgd2hlbiB0aGUgYW5pbWF0aW9uIGZyYW1lIGJlZ2FuIGV4ZWN1dGluZy5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtNYXB9IHRoaXNcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF9yZW5kZXIocGFpbnRTdGFydFRpbWVTdGFtcDogbnVtYmVyKSB7XG4gICAgICAgIGNvbnN0IG0gPSBQZXJmb3JtYW5jZVV0aWxzLmJlZ2luTWVhc3VyZSgncmVuZGVyJyk7XG5cbiAgICAgICAgbGV0IGdwdVRpbWVyO1xuICAgICAgICBjb25zdCBleHRUaW1lclF1ZXJ5ID0gdGhpcy5wYWludGVyLmNvbnRleHQuZXh0VGltZXJRdWVyeTtcbiAgICAgICAgY29uc3QgZnJhbWVTdGFydFRpbWUgPSBicm93c2VyLm5vdygpO1xuICAgICAgICBpZiAodGhpcy5saXN0ZW5zKCdncHUtdGltaW5nLWZyYW1lJykpIHtcbiAgICAgICAgICAgIGdwdVRpbWVyID0gZXh0VGltZXJRdWVyeS5jcmVhdGVRdWVyeUVYVCgpO1xuICAgICAgICAgICAgZXh0VGltZXJRdWVyeS5iZWdpblF1ZXJ5RVhUKGV4dFRpbWVyUXVlcnkuVElNRV9FTEFQU0VEX0VYVCwgZ3B1VGltZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQSBjdXN0b20gbGF5ZXIgbWF5IGhhdmUgdXNlZCB0aGUgY29udGV4dCBhc3luY2hyb25vdXNseS4gTWFyayB0aGUgc3RhdGUgYXMgZGlydHkuXG4gICAgICAgIHRoaXMucGFpbnRlci5jb250ZXh0LnNldERpcnR5KCk7XG4gICAgICAgIHRoaXMucGFpbnRlci5zZXRCYXNlU3RhdGUoKTtcblxuICAgICAgICBpZiAodGhpcy5pc01vdmluZygpIHx8IHRoaXMuaXNSb3RhdGluZygpIHx8IHRoaXMuaXNab29taW5nKCkpIHtcbiAgICAgICAgICAgIHRoaXMuX2ludGVyYWN0aW9uUmFuZ2VbMF0gPSBNYXRoLm1pbih0aGlzLl9pbnRlcmFjdGlvblJhbmdlWzBdLCB3aW5kb3cucGVyZm9ybWFuY2Uubm93KCkpO1xuICAgICAgICAgICAgdGhpcy5faW50ZXJhY3Rpb25SYW5nZVsxXSA9IE1hdGgubWF4KHRoaXMuX2ludGVyYWN0aW9uUmFuZ2VbMV0sIHdpbmRvdy5wZXJmb3JtYW5jZS5ub3coKSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9yZW5kZXJUYXNrUXVldWUucnVuKHBhaW50U3RhcnRUaW1lU3RhbXApO1xuICAgICAgICB0aGlzLl9kb21SZW5kZXJUYXNrUXVldWUucnVuKHBhaW50U3RhcnRUaW1lU3RhbXApO1xuICAgICAgICAvLyBBIHRhc2sgcXVldWUgY2FsbGJhY2sgbWF5IGhhdmUgZmlyZWQgYSB1c2VyIGV2ZW50IHdoaWNoIG1heSBoYXZlIHJlbW92ZWQgdGhlIG1hcFxuICAgICAgICBpZiAodGhpcy5fcmVtb3ZlZCkgcmV0dXJuO1xuXG4gICAgICAgIHRoaXMuX3VwZGF0ZVByb2plY3Rpb25UcmFuc2l0aW9uKCk7XG5cbiAgICAgICAgY29uc3QgZmFkZUR1cmF0aW9uID0gdGhpcy5faXNJbml0aWFsTG9hZCA/IDAgOiB0aGlzLl9mYWRlRHVyYXRpb247XG5cbiAgICAgICAgLy8gSWYgdGhlIHN0eWxlIGhhcyBjaGFuZ2VkLCB0aGUgbWFwIGlzIGJlaW5nIHpvb21lZCwgb3IgYSB0cmFuc2l0aW9uIG9yIGZhZGUgaXMgaW4gcHJvZ3Jlc3M6XG4gICAgICAgIC8vICAtIEFwcGx5IHN0eWxlIGNoYW5nZXMgKGluIGEgYmF0Y2gpXG4gICAgICAgIC8vICAtIFJlY2FsY3VsYXRlIHBhaW50IHByb3BlcnRpZXMuXG4gICAgICAgIGlmICh0aGlzLnN0eWxlICYmIHRoaXMuX3N0eWxlRGlydHkpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0eWxlRGlydHkgPSBmYWxzZTtcblxuICAgICAgICAgICAgY29uc3Qgem9vbSA9IHRoaXMudHJhbnNmb3JtLnpvb207XG4gICAgICAgICAgICBjb25zdCBwaXRjaCA9IHRoaXMudHJhbnNmb3JtLnBpdGNoO1xuICAgICAgICAgICAgY29uc3Qgbm93ID0gYnJvd3Nlci5ub3coKTtcblxuICAgICAgICAgICAgY29uc3QgcGFyYW1ldGVycyA9IG5ldyBFdmFsdWF0aW9uUGFyYW1ldGVycyh6b29tLCB7XG4gICAgICAgICAgICAgICAgbm93LFxuICAgICAgICAgICAgICAgIGZhZGVEdXJhdGlvbixcbiAgICAgICAgICAgICAgICBwaXRjaCxcbiAgICAgICAgICAgICAgICB0cmFuc2l0aW9uOiB0aGlzLnN0eWxlLmdldFRyYW5zaXRpb24oKVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHRoaXMuc3R5bGUudXBkYXRlKHBhcmFtZXRlcnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZm9nSXNUcmFuc2l0aW9uaW5nID0gdGhpcy5zdHlsZSAmJiB0aGlzLnN0eWxlLmZvZyAmJiB0aGlzLnN0eWxlLmZvZy5oYXNUcmFuc2l0aW9uKCk7XG5cbiAgICAgICAgaWYgKGZvZ0lzVHJhbnNpdGlvbmluZykge1xuICAgICAgICAgICAgdGhpcy5zdHlsZS5fbWFya2Vyc05lZWRVcGRhdGUgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5fc291cmNlc0RpcnR5ID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIHdlIGFyZSBpbiBfcmVuZGVyIGZvciBhbnkgcmVhc29uIG90aGVyIHRoYW4gYW4gaW4tcHJvZ3Jlc3MgcGFpbnRcbiAgICAgICAgLy8gdHJhbnNpdGlvbiwgdXBkYXRlIHNvdXJjZSBjYWNoZXMgdG8gY2hlY2sgZm9yIGFuZCBsb2FkIGFueSB0aWxlcyB3ZVxuICAgICAgICAvLyBuZWVkIGZvciB0aGUgY3VycmVudCB0cmFuc2Zvcm1cbiAgICAgICAgbGV0IGF2ZXJhZ2VFbGV2YXRpb25DaGFuZ2VkID0gZmFsc2U7XG4gICAgICAgIGlmICh0aGlzLnN0eWxlICYmIHRoaXMuX3NvdXJjZXNEaXJ0eSkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlc0RpcnR5ID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLnBhaW50ZXIuX3VwZGF0ZUZvZyh0aGlzLnN0eWxlKTtcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZVRlcnJhaW4oKTsgLy8gVGVycmFpbiBERU0gc291cmNlIHVwZGF0ZXMgaGVyZSBhbmQgc2tpcHMgdXBkYXRlIGluIHN0eWxlLl91cGRhdGVTb3VyY2VzLlxuICAgICAgICAgICAgYXZlcmFnZUVsZXZhdGlvbkNoYW5nZWQgPSB0aGlzLl91cGRhdGVBdmVyYWdlRWxldmF0aW9uKGZyYW1lU3RhcnRUaW1lKTtcbiAgICAgICAgICAgIHRoaXMuc3R5bGUuX3VwZGF0ZVNvdXJjZXModGhpcy50cmFuc2Zvcm0pO1xuICAgICAgICAgICAgLy8gVXBkYXRlIHBvc2l0aW9ucyBvZiBtYXJrZXJzIGFuZCBwb3B1cHMgb24gZW5hYmxpbmcvZGlzYWJsaW5nIHRlcnJhaW5cbiAgICAgICAgICAgIHRoaXMuX2ZvcmNlTWFya2VyQW5kUG9wdXBVcGRhdGUoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGF2ZXJhZ2VFbGV2YXRpb25DaGFuZ2VkID0gdGhpcy5fdXBkYXRlQXZlcmFnZUVsZXZhdGlvbihmcmFtZVN0YXJ0VGltZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9wbGFjZW1lbnREaXJ0eSA9IHRoaXMuc3R5bGUgJiYgdGhpcy5zdHlsZS5fdXBkYXRlUGxhY2VtZW50KHRoaXMucGFpbnRlci50cmFuc2Zvcm0sIHRoaXMuc2hvd0NvbGxpc2lvbkJveGVzLCBmYWRlRHVyYXRpb24sIHRoaXMuX2Nyb3NzU291cmNlQ29sbGlzaW9ucyk7XG5cbiAgICAgICAgLy8gQWN0dWFsbHkgZHJhd1xuICAgICAgICBpZiAodGhpcy5zdHlsZSkge1xuICAgICAgICAgICAgdGhpcy5wYWludGVyLnJlbmRlcih0aGlzLnN0eWxlLCB7XG4gICAgICAgICAgICAgICAgc2hvd1RpbGVCb3VuZGFyaWVzOiB0aGlzLnNob3dUaWxlQm91bmRhcmllcyxcbiAgICAgICAgICAgICAgICBzaG93VGVycmFpbldpcmVmcmFtZTogdGhpcy5zaG93VGVycmFpbldpcmVmcmFtZSxcbiAgICAgICAgICAgICAgICBzaG93T3ZlcmRyYXdJbnNwZWN0b3I6IHRoaXMuX3Nob3dPdmVyZHJhd0luc3BlY3RvcixcbiAgICAgICAgICAgICAgICBzaG93UXVlcnlHZW9tZXRyeTogISF0aGlzLl9zaG93UXVlcnlHZW9tZXRyeSxcbiAgICAgICAgICAgICAgICBzaG93VGlsZUFBQkJzOiB0aGlzLnNob3dUaWxlQUFCQnMsXG4gICAgICAgICAgICAgICAgcm90YXRpbmc6IHRoaXMuaXNSb3RhdGluZygpLFxuICAgICAgICAgICAgICAgIHpvb21pbmc6IHRoaXMuaXNab29taW5nKCksXG4gICAgICAgICAgICAgICAgbW92aW5nOiB0aGlzLmlzTW92aW5nKCksXG4gICAgICAgICAgICAgICAgZmFkZUR1cmF0aW9uLFxuICAgICAgICAgICAgICAgIGlzSW5pdGlhbExvYWQ6IHRoaXMuX2lzSW5pdGlhbExvYWQsXG4gICAgICAgICAgICAgICAgc2hvd1BhZGRpbmc6IHRoaXMuc2hvd1BhZGRpbmcsXG4gICAgICAgICAgICAgICAgZ3B1VGltaW5nOiAhIXRoaXMubGlzdGVucygnZ3B1LXRpbWluZy1sYXllcicpLFxuICAgICAgICAgICAgICAgIGdwdVRpbWluZ0RlZmVycmVkUmVuZGVyOiAhIXRoaXMubGlzdGVucygnZ3B1LXRpbWluZy1kZWZlcnJlZC1yZW5kZXInKSxcbiAgICAgICAgICAgICAgICBzcGVlZEluZGV4VGltaW5nOiB0aGlzLnNwZWVkSW5kZXhUaW1pbmcsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ3JlbmRlcicpKTtcblxuICAgICAgICBpZiAodGhpcy5sb2FkZWQoKSAmJiAhdGhpcy5fbG9hZGVkKSB7XG4gICAgICAgICAgICB0aGlzLl9sb2FkZWQgPSB0cnVlO1xuICAgICAgICAgICAgUGVyZm9ybWFuY2VVdGlscy5tYXJrKFBlcmZvcm1hbmNlTWFya2Vycy5sb2FkKTtcbiAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ2xvYWQnKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5zdHlsZSAmJiAodGhpcy5zdHlsZS5oYXNUcmFuc2l0aW9ucygpKSkge1xuICAgICAgICAgICAgdGhpcy5fc3R5bGVEaXJ0eSA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5zdHlsZSAmJiAhdGhpcy5fcGxhY2VtZW50RGlydHkpIHtcbiAgICAgICAgICAgIC8vIFNpbmNlIG5vIGZhZGUgb3BlcmF0aW9ucyBhcmUgaW4gcHJvZ3Jlc3MsIHdlIGNhbiByZWxlYXNlXG4gICAgICAgICAgICAvLyBhbGwgdGlsZXMgaGVsZCBmb3IgZmFkaW5nLiBJZiB3ZSBkaWRuJ3QgZG8gdGhpcywgdGhlIHRpbGVzXG4gICAgICAgICAgICAvLyB3b3VsZCBqdXN0IHNpdCBpbiB0aGUgU291cmNlQ2FjaGVzIHVudGlsIHRoZSBuZXh0IHJlbmRlclxuICAgICAgICAgICAgdGhpcy5zdHlsZS5fcmVsZWFzZVN5bWJvbEZhZGVUaWxlcygpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGdwdVRpbWVyKSB7XG4gICAgICAgICAgICBjb25zdCByZW5kZXJDUFVUaW1lID0gYnJvd3Nlci5ub3coKSAtIGZyYW1lU3RhcnRUaW1lO1xuICAgICAgICAgICAgZXh0VGltZXJRdWVyeS5lbmRRdWVyeUVYVChleHRUaW1lclF1ZXJ5LlRJTUVfRUxBUFNFRF9FWFQsIGdwdVRpbWVyKTtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlckdQVVRpbWUgPSBleHRUaW1lclF1ZXJ5LmdldFF1ZXJ5T2JqZWN0RVhUKGdwdVRpbWVyLCBleHRUaW1lclF1ZXJ5LlFVRVJZX1JFU1VMVF9FWFQpIC8gKDEwMDAgKiAxMDAwKTtcbiAgICAgICAgICAgICAgICBleHRUaW1lclF1ZXJ5LmRlbGV0ZVF1ZXJ5RVhUKGdwdVRpbWVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLmZpcmUobmV3IEV2ZW50KCdncHUtdGltaW5nLWZyYW1lJywge1xuICAgICAgICAgICAgICAgICAgICBjcHVUaW1lOiByZW5kZXJDUFVUaW1lLFxuICAgICAgICAgICAgICAgICAgICBncHVUaW1lOiByZW5kZXJHUFVUaW1lXG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgIHdpbmRvdy5wZXJmb3JtYW5jZS5tYXJrKCdmcmFtZS1ncHUnLCB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0VGltZTogZnJhbWVTdGFydFRpbWUsXG4gICAgICAgICAgICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgZ3B1VGltZTogcmVuZGVyR1BVVGltZVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9LCA1MCk7IC8vIFdhaXQgNTBtcyB0byBnaXZlIHRpbWUgZm9yIGFsbCBHUFUgY2FsbHMgdG8gZmluaXNoIGJlZm9yZSBxdWVyeWluZ1xuICAgICAgICB9XG5cbiAgICAgICAgUGVyZm9ybWFuY2VVdGlscy5lbmRNZWFzdXJlKG0pO1xuXG4gICAgICAgIGlmICh0aGlzLmxpc3RlbnMoJ2dwdS10aW1pbmctbGF5ZXInKSkge1xuICAgICAgICAgICAgLy8gUmVzZXR0aW5nIHRoZSBQYWludGVyJ3MgcGVyLWxheWVyIHRpbWluZyBxdWVyaWVzIGhlcmUgYWxsb3dzIHVzIHRvIGlzb2xhdGVcbiAgICAgICAgICAgIC8vIHRoZSBxdWVyaWVzIHRvIGluZGl2aWR1YWwgZnJhbWVzLlxuICAgICAgICAgICAgY29uc3QgZnJhbWVMYXllclF1ZXJpZXMgPSB0aGlzLnBhaW50ZXIuY29sbGVjdEdwdVRpbWVycygpO1xuXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZExheWVyVGltZXMgPSB0aGlzLnBhaW50ZXIucXVlcnlHcHVUaW1lcnMoZnJhbWVMYXllclF1ZXJpZXMpO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgnZ3B1LXRpbWluZy1sYXllcicsIHtcbiAgICAgICAgICAgICAgICAgICAgbGF5ZXJUaW1lczogcmVuZGVyZWRMYXllclRpbWVzXG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgfSwgNTApOyAvLyBXYWl0IDUwbXMgdG8gZ2l2ZSB0aW1lIGZvciBhbGwgR1BVIGNhbGxzIHRvIGZpbmlzaCBiZWZvcmUgcXVlcnlpbmdcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmxpc3RlbnMoJ2dwdS10aW1pbmctZGVmZXJyZWQtcmVuZGVyJykpIHtcbiAgICAgICAgICAgIGNvbnN0IGRlZmVycmVkUmVuZGVyUXVlcmllcyA9IHRoaXMucGFpbnRlci5jb2xsZWN0RGVmZXJyZWRSZW5kZXJHcHVRdWVyaWVzKCk7XG5cbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGdwdVRpbWUgPSB0aGlzLnBhaW50ZXIucXVlcnlHcHVUaW1lRGVmZXJyZWRSZW5kZXIoZGVmZXJyZWRSZW5kZXJRdWVyaWVzKTtcbiAgICAgICAgICAgICAgICB0aGlzLmZpcmUobmV3IEV2ZW50KCdncHUtdGltaW5nLWRlZmVycmVkLXJlbmRlcicsIHtncHVUaW1lfSkpO1xuICAgICAgICAgICAgfSwgNTApOyAvLyBXYWl0IDUwbXMgdG8gZ2l2ZSB0aW1lIGZvciBhbGwgR1BVIGNhbGxzIHRvIGZpbmlzaCBiZWZvcmUgcXVlcnlpbmdcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNjaGVkdWxlIGFub3RoZXIgcmVuZGVyIGZyYW1lIGlmIGl0J3MgbmVlZGVkLlxuICAgICAgICAvL1xuICAgICAgICAvLyBFdmVuIHRob3VnaCBgX3N0eWxlRGlydHlgIGFuZCBgX3NvdXJjZXNEaXJ0eWAgYXJlIHJlc2V0IGluIHRoaXNcbiAgICAgICAgLy8gbWV0aG9kLCBzeW5jaHJvbm91cyBldmVudHMgZmlyZWQgZHVyaW5nIFN0eWxlI3VwZGF0ZSBvclxuICAgICAgICAvLyBTdHlsZSNfdXBkYXRlU291cmNlcyBjb3VsZCBoYXZlIGNhdXNlZCB0aGVtIHRvIGJlIHNldCBhZ2Fpbi5cbiAgICAgICAgY29uc3Qgc29tZXRoaW5nRGlydHkgPSB0aGlzLl9zb3VyY2VzRGlydHkgfHwgdGhpcy5fc3R5bGVEaXJ0eSB8fCB0aGlzLl9wbGFjZW1lbnREaXJ0eSB8fCBhdmVyYWdlRWxldmF0aW9uQ2hhbmdlZDtcbiAgICAgICAgaWYgKHNvbWV0aGluZ0RpcnR5IHx8IHRoaXMuX3JlcGFpbnQpIHtcbiAgICAgICAgICAgIHRoaXMudHJpZ2dlclJlcGFpbnQoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHdpbGxJZGxlID0gIXRoaXMuaXNNb3ZpbmcoKSAmJiB0aGlzLmxvYWRlZCgpO1xuICAgICAgICAgICAgaWYgKHdpbGxJZGxlKSB7XG4gICAgICAgICAgICAgICAgLy8gQmVmb3JlIGlkbGluZywgd2UgcGVyZm9ybSBvbmUgbGFzdCBzYW1wbGUgc28gdGhhdCBpZiB0aGUgYXZlcmFnZSBlbGV2YXRpb25cbiAgICAgICAgICAgICAgICAvLyBkb2VzIG5vdCBleGFjdGx5IG1hdGNoIHRoZSB0ZXJyYWluLCB3ZSBza2lwIGlkbGUgYW5kIGVhc2UgaXQgdG8gaXRzIGZpbmFsIHN0YXRlLlxuICAgICAgICAgICAgICAgIGF2ZXJhZ2VFbGV2YXRpb25DaGFuZ2VkID0gdGhpcy5fdXBkYXRlQXZlcmFnZUVsZXZhdGlvbihmcmFtZVN0YXJ0VGltZSwgdHJ1ZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChhdmVyYWdlRWxldmF0aW9uQ2hhbmdlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlclJlcGFpbnQoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdHJpZ2dlckZyYW1lKGZhbHNlKTtcbiAgICAgICAgICAgICAgICBpZiAod2lsbElkbGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgnaWRsZScpKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5faXNJbml0aWFsTG9hZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGUgb3B0aW9ucyB0byBzZWUgaWYgbmVlZCB0byBjYWxjdWxhdGUgdGhlIHNwZWVkIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnNwZWVkSW5kZXhUaW1pbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNwZWVkSW5kZXhOdW1iZXIgPSB0aGlzLl9jYWxjdWxhdGVTcGVlZEluZGV4KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZpcmUobmV3IEV2ZW50KCdzcGVlZGluZGV4Y29tcGxldGVkJywge3NwZWVkSW5kZXg6IHNwZWVkSW5kZXhOdW1iZXJ9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNwZWVkSW5kZXhUaW1pbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLl9sb2FkZWQgJiYgIXRoaXMuX2Z1bGx5TG9hZGVkICYmICFzb21ldGhpbmdEaXJ0eSkge1xuICAgICAgICAgICAgdGhpcy5fZnVsbHlMb2FkZWQgPSB0cnVlO1xuICAgICAgICAgICAgTGl2ZVBlcmZvcm1hbmNlVXRpbHMubWFyayhQZXJmb3JtYW5jZU1hcmtlcnMuZnVsbExvYWQpO1xuICAgICAgICAgICAgLy8gRm9sbG93aW5nIGxpbmVzIGFyZSBiaWxsaW5nIGFuZCBtZXRyaWNzIHJlbGF0ZWQgY29kZS4gRG8gbm90IGNoYW5nZS4gU2VlIExJQ0VOU0UudHh0XG4gICAgICAgICAgICBpZiAodGhpcy5fcGVyZm9ybWFuY2VNZXRyaWNzQ29sbGVjdGlvbikge1xuICAgICAgICAgICAgICAgIHBvc3RQZXJmb3JtYW5jZUV2ZW50KHRoaXMuX3JlcXVlc3RNYW5hZ2VyLl9jdXN0b21BY2Nlc3NUb2tlbiwge1xuICAgICAgICAgICAgICAgICAgICB3aWR0aDogdGhpcy5wYWludGVyLndpZHRoLFxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IHRoaXMucGFpbnRlci5oZWlnaHQsXG4gICAgICAgICAgICAgICAgICAgIGludGVyYWN0aW9uUmFuZ2U6IHRoaXMuX2ludGVyYWN0aW9uUmFuZ2UsXG4gICAgICAgICAgICAgICAgICAgIHZpc2liaWxpdHlIaWRkZW46IHRoaXMuX3Zpc2liaWxpdHlIaWRkZW4sXG4gICAgICAgICAgICAgICAgICAgIHRlcnJhaW5FbmFibGVkOiAhIXRoaXMucGFpbnRlci5zdHlsZS5nZXRUZXJyYWluKCksXG4gICAgICAgICAgICAgICAgICAgIGZvZ0VuYWJsZWQ6ICEhdGhpcy5wYWludGVyLnN0eWxlLmdldEZvZygpLFxuICAgICAgICAgICAgICAgICAgICBwcm9qZWN0aW9uOiB0aGlzLmdldFByb2plY3Rpb24oKS5uYW1lLFxuICAgICAgICAgICAgICAgICAgICB6b29tOiB0aGlzLnRyYW5zZm9ybS56b29tLFxuICAgICAgICAgICAgICAgICAgICByZW5kZXJlcjogdGhpcy5wYWludGVyLmNvbnRleHQucmVuZGVyZXIsXG4gICAgICAgICAgICAgICAgICAgIHZlbmRvcjogdGhpcy5wYWludGVyLmNvbnRleHQudmVuZG9yXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9hdXRoZW50aWNhdGUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9mb3JjZU1hcmtlckFuZFBvcHVwVXBkYXRlKHNob3VsZFdyYXA/OiBib29sZWFuKSB7XG4gICAgICAgIGZvciAoY29uc3QgbWFya2VyIG9mIHRoaXMuX21hcmtlcnMpIHtcbiAgICAgICAgICAgIC8vIFdyYXAgbWFya2VyIGxvY2F0aW9uIHdoZW4gdG9nZ2xpbmcgdG8gYSBwcm9qZWN0aW9uIHdpdGhvdXQgd29ybGQgY29waWVzXG4gICAgICAgICAgICBpZiAoc2hvdWxkV3JhcCAmJiAhdGhpcy5nZXRSZW5kZXJXb3JsZENvcGllcygpKSB7XG4gICAgICAgICAgICAgICAgbWFya2VyLl9sbmdMYXQgPSBtYXJrZXIuX2xuZ0xhdC53cmFwKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBtYXJrZXIuX3VwZGF0ZSgpO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgcG9wdXAgb2YgdGhpcy5fcG9wdXBzKSB7XG4gICAgICAgICAgICAvLyBXcmFwIHBvcHVwIGxvY2F0aW9uIHdoZW4gdG9nZ2xpbmcgdG8gYSBwcm9qZWN0aW9uIHdpdGhvdXQgd29ybGQgY29waWVzIGFuZCB0cmFjayBwb2ludGVyIHNldCB0byBmYWxzZVxuICAgICAgICAgICAgaWYgKHNob3VsZFdyYXAgJiYgIXRoaXMuZ2V0UmVuZGVyV29ybGRDb3BpZXMoKSAmJiAhcG9wdXAuX3RyYWNrUG9pbnRlcikge1xuICAgICAgICAgICAgICAgIHBvcHVwLl9sbmdMYXQgPSBwb3B1cC5fbG5nTGF0LndyYXAoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBvcHVwLl91cGRhdGUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSB0aGUgYXZlcmFnZSB2aXNpYmxlIGVsZXZhdGlvbiBieSBzYW1wbGluZyB0ZXJyYWluXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSBpZiBlbGV2YXRpb24gaGFzIGNoYW5nZWQgZnJvbSB0aGUgbGFzdCBzYW1wbGluZ1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgX3VwZGF0ZUF2ZXJhZ2VFbGV2YXRpb24odGltZVN0YW1wOiBudW1iZXIsIGlnbm9yZVRpbWVvdXQ6IGJvb2xlYW4gPSBmYWxzZSk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCBhcHBseVVwZGF0ZSA9ICh2YWx1ZTogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnRyYW5zZm9ybS5hdmVyYWdlRWxldmF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgICB0aGlzLl91cGRhdGUoZmFsc2UpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKCF0aGlzLnBhaW50ZXIuYXZlcmFnZUVsZXZhdGlvbk5lZWRzRWFzaW5nKCkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybS5hdmVyYWdlRWxldmF0aW9uICE9PSAwKSByZXR1cm4gYXBwbHlVcGRhdGUoMCk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB0aW1lb3V0RWxhcHNlZCA9IGlnbm9yZVRpbWVvdXQgfHwgdGltZVN0YW1wIC0gdGhpcy5fYXZlcmFnZUVsZXZhdGlvbkxhc3RTYW1wbGVkQXQgPiBBVkVSQUdFX0VMRVZBVElPTl9TQU1QTElOR19JTlRFUlZBTDtcblxuICAgICAgICBpZiAodGltZW91dEVsYXBzZWQgJiYgIXRoaXMuX2F2ZXJhZ2VFbGV2YXRpb24uaXNFYXNpbmcodGltZVN0YW1wKSkge1xuICAgICAgICAgICAgY29uc3QgY3VycmVudEVsZXZhdGlvbiA9IHRoaXMudHJhbnNmb3JtLmF2ZXJhZ2VFbGV2YXRpb247XG4gICAgICAgICAgICBsZXQgbmV3RWxldmF0aW9uID0gdGhpcy50cmFuc2Zvcm0uc2FtcGxlQXZlcmFnZUVsZXZhdGlvbigpO1xuICAgICAgICAgICAgbGV0IGV4YWdnZXJhdGlvbkNoYW5nZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybS5lbGV2YXRpb24pIHtcbiAgICAgICAgICAgICAgICBleGFnZ2VyYXRpb25DaGFuZ2VkID0gdGhpcy50cmFuc2Zvcm0uZWxldmF0aW9uLmV4YWdnZXJhdGlvbigpICE9PSB0aGlzLl9hdmVyYWdlRWxldmF0aW9uRXhhZ2dlcmF0aW9uO1xuICAgICAgICAgICAgICAgIC8vICRGbG93SWdub3JlW2luY29tcGF0aWJsZS11c2VdXG4gICAgICAgICAgICAgICAgdGhpcy5fYXZlcmFnZUVsZXZhdGlvbkV4YWdnZXJhdGlvbiA9IHRoaXMudHJhbnNmb3JtLmVsZXZhdGlvbi5leGFnZ2VyYXRpb24oKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gTmV3IGVsZXZhdGlvbiBpcyBOYU4gaWYgbm8gdGVycmFpbiB0aWxlcyB3ZXJlIGF2YWlsYWJsZVxuICAgICAgICAgICAgaWYgKGlzTmFOKG5ld0VsZXZhdGlvbikpIHtcbiAgICAgICAgICAgICAgICBuZXdFbGV2YXRpb24gPSAwO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBEb24ndCBhY3RpdmF0ZSB0aGUgdGltZW91dCBpZiBubyBkYXRhIHdhcyBhdmFpbGFibGVcbiAgICAgICAgICAgICAgICB0aGlzLl9hdmVyYWdlRWxldmF0aW9uTGFzdFNhbXBsZWRBdCA9IHRpbWVTdGFtcDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGVsZXZhdGlvbkNoYW5nZSA9IE1hdGguYWJzKGN1cnJlbnRFbGV2YXRpb24gLSBuZXdFbGV2YXRpb24pO1xuXG4gICAgICAgICAgICBpZiAoZWxldmF0aW9uQ2hhbmdlID4gQVZFUkFHRV9FTEVWQVRJT05fRUFTRV9USFJFU0hPTEQpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5faXNJbml0aWFsTG9hZCB8fCBleGFnZ2VyYXRpb25DaGFuZ2VkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2F2ZXJhZ2VFbGV2YXRpb24uanVtcFRvKG5ld0VsZXZhdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhcHBseVVwZGF0ZShuZXdFbGV2YXRpb24pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2F2ZXJhZ2VFbGV2YXRpb24uZWFzZVRvKG5ld0VsZXZhdGlvbiwgdGltZVN0YW1wLCBBVkVSQUdFX0VMRVZBVElPTl9FQVNFX1RJTUUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZWxldmF0aW9uQ2hhbmdlID4gQVZFUkFHRV9FTEVWQVRJT05fQ0hBTkdFX1RIUkVTSE9MRCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2F2ZXJhZ2VFbGV2YXRpb24uanVtcFRvKG5ld0VsZXZhdGlvbik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFwcGx5VXBkYXRlKG5ld0VsZXZhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5fYXZlcmFnZUVsZXZhdGlvbi5pc0Vhc2luZyh0aW1lU3RhbXApKSB7XG4gICAgICAgICAgICByZXR1cm4gYXBwbHlVcGRhdGUodGhpcy5fYXZlcmFnZUVsZXZhdGlvbi5nZXRWYWx1ZSh0aW1lU3RhbXApKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvKioqKiogU1RBUlQgV0FSTklORyAtIFJFTU9WQUwgT1IgTU9ESUZJQ0FUSU9OIE9GIFRIRVxuICAgICogRk9MTE9XSU5HIENPREUgVklPTEFURVMgVEhFIE1BUEJPWCBURVJNUyBPRiBTRVJWSUNFICAqKioqKipcbiAgICAqIFRoZSBmb2xsb3dpbmcgY29kZSBpcyB1c2VkIHRvIGFjY2VzcyBNYXBib3gncyBBUElzLiBSZW1vdmFsIG9yIG1vZGlmaWNhdGlvblxuICAgICogb2YgdGhpcyBjb2RlIGNhbiByZXN1bHQgaW4gaGlnaGVyIGZlZXMgYW5kL29yXG4gICAgKiB0ZXJtaW5hdGlvbiBvZiB5b3VyIGFjY291bnQgd2l0aCBNYXBib3guXG4gICAgKlxuICAgICogVW5kZXIgdGhlIE1hcGJveCBUZXJtcyBvZiBTZXJ2aWNlLCB5b3UgbWF5IG5vdCB1c2UgdGhpcyBjb2RlIHRvIGFjY2VzcyBNYXBib3hcbiAgICAqIE1hcHBpbmcgQVBJcyBvdGhlciB0aGFuIHRocm91Z2ggTWFwYm94IFNES3MuXG4gICAgKlxuICAgICogVGhlIE1hcHBpbmcgQVBJcyBkb2N1bWVudGF0aW9uIGlzIGF2YWlsYWJsZSBhdCBodHRwczovL2RvY3MubWFwYm94LmNvbS9hcGkvbWFwcy8jbWFwc1xuICAgICogYW5kIHRoZSBNYXBib3ggVGVybXMgb2YgU2VydmljZSBhcmUgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vdG9zL1xuICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuICAgIF9hdXRoZW50aWNhdGUoKSB7XG4gICAgICAgIGdldE1hcFNlc3Npb25BUEkodGhpcy5fZ2V0TWFwSWQoKSwgdGhpcy5fcmVxdWVzdE1hbmFnZXIuX3NrdVRva2VuLCB0aGlzLl9yZXF1ZXN0TWFuYWdlci5fY3VzdG9tQWNjZXNzVG9rZW4sIChlcnIpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICAvLyB0aHJvd2luZyBhbiBlcnJvciBoZXJlIHdpbGwgY2F1c2UgdGhlIGNhbGxiYWNrIHRvIGJlIGNhbGxlZCBhZ2FpbiB1bm5lY2Vzc2FyaWx5XG4gICAgICAgICAgICAgICAgaWYgKGVyci5tZXNzYWdlID09PSBBVVRIX0VSUl9NU0cgfHwgKGVycjogYW55KS5zdGF0dXMgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBnbCA9IHRoaXMucGFpbnRlci5jb250ZXh0LmdsO1xuICAgICAgICAgICAgICAgICAgICBzdG9yZUF1dGhTdGF0ZShnbCwgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fbG9nb0NvbnRyb2wgaW5zdGFuY2VvZiBMb2dvQ29udHJvbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9nb0NvbnRyb2wuX3VwZGF0ZUxvZ28oKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZ2wpIGdsLmNsZWFyKGdsLkRFUFRIX0JVRkZFUl9CSVQgfCBnbC5DT0xPUl9CVUZGRVJfQklUIHwgZ2wuU1RFTkNJTF9CVUZGRVJfQklUKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX3NpbGVuY2VBdXRoRXJyb3JzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZpcmUobmV3IEVycm9yRXZlbnQobmV3IEVycm9yKCdBIHZhbGlkIE1hcGJveCBhY2Nlc3MgdG9rZW4gaXMgcmVxdWlyZWQgdG8gdXNlIE1hcGJveCBHTCBKUy4gVG8gY3JlYXRlIGFuIGFjY291bnQgb3IgYSBuZXcgYWNjZXNzIHRva2VuLCB2aXNpdCBodHRwczovL2FjY291bnQubWFwYm94LmNvbS8nKSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcG9zdE1hcExvYWRFdmVudCh0aGlzLl9nZXRNYXBJZCgpLCB0aGlzLl9yZXF1ZXN0TWFuYWdlci5fc2t1VG9rZW4sIHRoaXMuX3JlcXVlc3RNYW5hZ2VyLl9jdXN0b21BY2Nlc3NUb2tlbiwgKCkgPT4ge30pO1xuICAgIH1cblxuICAgIC8qKioqKiBFTkQgV0FSTklORyAtIFJFTU9WQUwgT1IgTU9ESUZJQ0FUSU9OIE9GIFRIRVxuICAgIFBSRUNFRElORyBDT0RFIFZJT0xBVEVTIFRIRSBNQVBCT1ggVEVSTVMgT0YgU0VSVklDRSAgKioqKioqL1xuXG4gICAgX3VwZGF0ZVRlcnJhaW4oKSB7XG4gICAgICAgIC8vIFJlY2FsY3VsYXRlIGlmIGVuYWJsZWQvZGlzYWJsZWQgYW5kIGNhbGN1bGF0ZSBlbGV2YXRpb24gY292ZXIuIEFzIGNhbWVyYSBpcyB1c2luZyBlbGV2YXRpb24gdGlsZXMgYmVmb3JlXG4gICAgICAgIC8vIHJlbmRlciAoYW5kIGRlZmVycmVkIHVwZGF0ZSBhZnRlciB6b29tIHJlY2FsY3VsYXRpb24pLCB0aGlzIG5lZWRzIHRvIGJlIGNhbGxlZCB3aGVuIHJlbW92aW5nIHRlcnJhaW4gc291cmNlLlxuICAgICAgICBjb25zdCBhZGFwdENhbWVyYUFsdGl0dWRlID0gdGhpcy5faXNEcmFnZ2luZygpO1xuICAgICAgICB0aGlzLnBhaW50ZXIudXBkYXRlVGVycmFpbih0aGlzLnN0eWxlLCBhZGFwdENhbWVyYUFsdGl0dWRlKTtcbiAgICB9XG5cbiAgICBfY2FsY3VsYXRlU3BlZWRJbmRleCgpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBmaW5hbEZyYW1lID0gdGhpcy5wYWludGVyLmNhbnZhc0NvcHkoKTtcbiAgICAgICAgY29uc3QgY2FudmFzQ29weUluc3RhbmNlcyA9IHRoaXMucGFpbnRlci5nZXRDYW52YXNDb3BpZXNBbmRUaW1lc3RhbXBzKCk7XG4gICAgICAgIGNhbnZhc0NvcHlJbnN0YW5jZXMudGltZVN0YW1wcy5wdXNoKHBlcmZvcm1hbmNlLm5vdygpKTtcblxuICAgICAgICBjb25zdCBnbCA9IHRoaXMucGFpbnRlci5jb250ZXh0LmdsO1xuICAgICAgICBjb25zdCBmcmFtZWJ1ZmZlciA9IGdsLmNyZWF0ZUZyYW1lYnVmZmVyKCk7XG4gICAgICAgIGdsLmJpbmRGcmFtZWJ1ZmZlcihnbC5GUkFNRUJVRkZFUiwgZnJhbWVidWZmZXIpO1xuXG4gICAgICAgIGZ1bmN0aW9uIHJlYWQodGV4dHVyZTogP1dlYkdMVGV4dHVyZSkge1xuICAgICAgICAgICAgZ2wuZnJhbWVidWZmZXJUZXh0dXJlMkQoZ2wuRlJBTUVCVUZGRVIsIGdsLkNPTE9SX0FUVEFDSE1FTlQwLCBnbC5URVhUVVJFXzJELCB0ZXh0dXJlLCAwKTtcbiAgICAgICAgICAgIGNvbnN0IHBpeGVscyA9IG5ldyBVaW50OEFycmF5KGdsLmRyYXdpbmdCdWZmZXJXaWR0aCAqIGdsLmRyYXdpbmdCdWZmZXJIZWlnaHQgKiA0KTtcbiAgICAgICAgICAgIGdsLnJlYWRQaXhlbHMoMCwgMCwgZ2wuZHJhd2luZ0J1ZmZlcldpZHRoLCBnbC5kcmF3aW5nQnVmZmVySGVpZ2h0LCBnbC5SR0JBLCBnbC5VTlNJR05FRF9CWVRFLCBwaXhlbHMpO1xuICAgICAgICAgICAgcmV0dXJuIHBpeGVscztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLl9jYW52YXNQaXhlbENvbXBhcmlzb24ocmVhZChmaW5hbEZyYW1lKSwgY2FudmFzQ29weUluc3RhbmNlcy5jYW52YXNDb3BpZXMubWFwKHJlYWQpLCBjYW52YXNDb3B5SW5zdGFuY2VzLnRpbWVTdGFtcHMpO1xuICAgIH1cblxuICAgIF9jYW52YXNQaXhlbENvbXBhcmlzb24oZmluYWxGcmFtZTogVWludDhBcnJheSwgYWxsRnJhbWVzOiBVaW50OEFycmF5W10sIHRpbWVTdGFtcHM6IG51bWJlcltdKTogbnVtYmVyIHtcbiAgICAgICAgbGV0IGZpbmFsU2NvcmUgPSB0aW1lU3RhbXBzWzFdIC0gdGltZVN0YW1wc1swXTtcbiAgICAgICAgY29uc3QgbnVtUGl4ZWxzID0gZmluYWxGcmFtZS5sZW5ndGggLyA0O1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYWxsRnJhbWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBmcmFtZSA9IGFsbEZyYW1lc1tpXTtcbiAgICAgICAgICAgIGxldCBjbnQgPSAwO1xuICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBmcmFtZS5sZW5ndGg7IGogKz0gNCkge1xuICAgICAgICAgICAgICAgIGlmIChmcmFtZVtqXSA9PT0gZmluYWxGcmFtZVtqXSAmJlxuICAgICAgICAgICAgICAgICAgICBmcmFtZVtqICsgMV0gPT09IGZpbmFsRnJhbWVbaiArIDFdICYmXG4gICAgICAgICAgICAgICAgICAgIGZyYW1lW2ogKyAyXSA9PT0gZmluYWxGcmFtZVtqICsgMl0gJiZcbiAgICAgICAgICAgICAgICAgICAgZnJhbWVbaiArIDNdID09PSBmaW5hbEZyYW1lW2ogKyAzXSkge1xuICAgICAgICAgICAgICAgICAgICBjbnQgPSBjbnQgKyAxO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vY2FsY3VsYXRlIHRoZSAlIHZpc3VhbCBjb21wbGV0ZW5lc3NcbiAgICAgICAgICAgIGNvbnN0IGludGVydmFsID0gdGltZVN0YW1wc1tpICsgMl0gLSB0aW1lU3RhbXBzW2kgKyAxXTtcbiAgICAgICAgICAgIGNvbnN0IHZpc3VhbENvbXBsZXRuZXNzID0gY250IC8gbnVtUGl4ZWxzO1xuICAgICAgICAgICAgZmluYWxTY29yZSArPSAgaW50ZXJ2YWwgKiAoMSAtIHZpc3VhbENvbXBsZXRuZXNzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmluYWxTY29yZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cCBhbmQgcmVsZWFzZSBhbGwgaW50ZXJuYWwgcmVzb3VyY2VzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIG1hcC5cbiAgICAgKlxuICAgICAqIFRoaXMgaW5jbHVkZXMgRE9NIGVsZW1lbnRzLCBldmVudCBiaW5kaW5ncywgd2ViIHdvcmtlcnMsIGFuZCBXZWJHTCByZXNvdXJjZXMuXG4gICAgICpcbiAgICAgKiBVc2UgdGhpcyBtZXRob2Qgd2hlbiB5b3UgYXJlIGRvbmUgdXNpbmcgdGhlIG1hcCBhbmQgd2lzaCB0byBlbnN1cmUgdGhhdCBpdCBub1xuICAgICAqIGxvbmdlciBjb25zdW1lcyBicm93c2VyIHJlc291cmNlcy4gQWZ0ZXJ3YXJkcywgeW91IG11c3Qgbm90IGNhbGwgYW55IG90aGVyXG4gICAgICogbWV0aG9kcyBvbiB0aGUgbWFwLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAucmVtb3ZlKCk7XG4gICAgICovXG4gICAgcmVtb3ZlKCkge1xuICAgICAgICBpZiAodGhpcy5faGFzaCkgdGhpcy5faGFzaC5yZW1vdmUoKTtcblxuICAgICAgICBmb3IgKGNvbnN0IGNvbnRyb2wgb2YgdGhpcy5fY29udHJvbHMpIGNvbnRyb2wub25SZW1vdmUodGhpcyk7XG4gICAgICAgIHRoaXMuX2NvbnRyb2xzID0gW107XG5cbiAgICAgICAgaWYgKHRoaXMuX2ZyYW1lKSB7XG4gICAgICAgICAgICB0aGlzLl9mcmFtZS5jYW5jZWwoKTtcbiAgICAgICAgICAgIHRoaXMuX2ZyYW1lID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9yZW5kZXJUYXNrUXVldWUuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5fZG9tUmVuZGVyVGFza1F1ZXVlLmNsZWFyKCk7XG4gICAgICAgIGlmICh0aGlzLnN0eWxlKSB7XG4gICAgICAgICAgICB0aGlzLnN0eWxlLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnBhaW50ZXIuZGVzdHJveSgpO1xuICAgICAgICBpZiAodGhpcy5oYW5kbGVycykgdGhpcy5oYW5kbGVycy5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMuaGFuZGxlcnMgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuc2V0U3R5bGUobnVsbCk7XG5cbiAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdGhpcy5fb25XaW5kb3dSZXNpemUsIGZhbHNlKTtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsIHRoaXMuX29uV2luZG93UmVzaXplLCBmYWxzZSk7XG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignd2Via2l0ZnVsbHNjcmVlbmNoYW5nZScsIHRoaXMuX29uV2luZG93UmVzaXplLCBmYWxzZSk7XG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignb25saW5lJywgdGhpcy5fb25XaW5kb3dPbmxpbmUsIGZhbHNlKTtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCd2aXNpYmlsaXR5Y2hhbmdlJywgdGhpcy5fb25WaXNpYmlsaXR5Q2hhbmdlLCBmYWxzZSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBleHRlbnNpb24gPSB0aGlzLnBhaW50ZXIuY29udGV4dC5nbC5nZXRFeHRlbnNpb24oJ1dFQkdMX2xvc2VfY29udGV4dCcpO1xuICAgICAgICBpZiAoZXh0ZW5zaW9uKSBleHRlbnNpb24ubG9zZUNvbnRleHQoKTtcblxuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIHRoaXMuX2NhbnZhcy5yZW1vdmVFdmVudExpc3RlbmVyKCd3ZWJnbGNvbnRleHRsb3N0JywgdGhpcy5fY29udGV4dExvc3QsIGZhbHNlKTtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICB0aGlzLl9jYW52YXMucmVtb3ZlRXZlbnRMaXN0ZW5lcignd2ViZ2xjb250ZXh0cmVzdG9yZWQnLCB0aGlzLl9jb250ZXh0UmVzdG9yZWQsIGZhbHNlKTtcblxuICAgICAgICB0aGlzLl9jYW52YXNDb250YWluZXIucmVtb3ZlKCk7XG4gICAgICAgIHRoaXMuX2NvbnRyb2xDb250YWluZXIucmVtb3ZlKCk7XG4gICAgICAgIHRoaXMuX21pc3NpbmdDU1NDYW5hcnkucmVtb3ZlKCk7XG5cbiAgICAgICAgdGhpcy5fY2FudmFzID0gKHVuZGVmaW5lZDogYW55KTtcbiAgICAgICAgdGhpcy5fY2FudmFzQ29udGFpbmVyID0gKHVuZGVmaW5lZDogYW55KTtcbiAgICAgICAgdGhpcy5fY29udHJvbENvbnRhaW5lciA9ICh1bmRlZmluZWQ6IGFueSk7XG4gICAgICAgIHRoaXMuX21pc3NpbmdDU1NDYW5hcnkgPSAodW5kZWZpbmVkOiBhbnkpO1xuXG4gICAgICAgIHRoaXMuX2NvbnRhaW5lci5jbGFzc0xpc3QucmVtb3ZlKCdtYXBib3hnbC1tYXAnKTtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICB0aGlzLl9jb250YWluZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgdGhpcy5fb25NYXBTY3JvbGwsIGZhbHNlKTtcblxuICAgICAgICBQZXJmb3JtYW5jZVV0aWxzLmNsZWFyTWV0cmljcygpO1xuICAgICAgICByZW1vdmVBdXRoU3RhdGUodGhpcy5wYWludGVyLmNvbnRleHQuZ2wpO1xuICAgICAgICB0aGlzLl9yZW1vdmVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgncmVtb3ZlJykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIHJlbmRlcmluZyBvZiBhIHNpbmdsZSBmcmFtZS4gVXNlIHRoaXMgbWV0aG9kIHdpdGggY3VzdG9tIGxheWVycyB0b1xuICAgICAqIHJlcGFpbnQgdGhlIG1hcCB3aGVuIHRoZSBsYXllcidzIHByb3BlcnRpZXMgb3IgcHJvcGVydGllcyBhc3NvY2lhdGVkIHdpdGggdGhlXG4gICAgICogbGF5ZXIncyBzb3VyY2UgY2hhbmdlLiBDYWxsaW5nIHRoaXMgbXVsdGlwbGUgdGltZXMgYmVmb3JlIHRoZVxuICAgICAqIG5leHQgZnJhbWUgaXMgcmVuZGVyZWQgd2lsbCBzdGlsbCByZXN1bHQgaW4gb25seSBhIHNpbmdsZSBmcmFtZSBiZWluZyByZW5kZXJlZC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogbWFwLnRyaWdnZXJSZXBhaW50KCk7XG4gICAgICogQHNlZSBbRXhhbXBsZTogQWRkIGEgM0QgbW9kZWxdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9leGFtcGxlL2FkZC0zZC1tb2RlbC8pXG4gICAgICogQHNlZSBbRXhhbXBsZTogQWRkIGFuIGFuaW1hdGVkIGljb24gdG8gdGhlIG1hcF0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvYWRkLWltYWdlLWFuaW1hdGVkLylcbiAgICAgKi9cbiAgICB0cmlnZ2VyUmVwYWludCgpIHtcbiAgICAgICAgdGhpcy5fdHJpZ2dlckZyYW1lKHRydWUpO1xuICAgIH1cblxuICAgIF90cmlnZ2VyRnJhbWUocmVuZGVyOiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMuX3JlbmRlck5leHRGcmFtZSA9IHRoaXMuX3JlbmRlck5leHRGcmFtZSB8fCByZW5kZXI7XG4gICAgICAgIGlmICh0aGlzLnN0eWxlICYmICF0aGlzLl9mcmFtZSkge1xuICAgICAgICAgICAgdGhpcy5fZnJhbWUgPSBicm93c2VyLmZyYW1lKChwYWludFN0YXJ0VGltZVN0YW1wOiBudW1iZXIpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBpc1JlbmRlckZyYW1lID0gISF0aGlzLl9yZW5kZXJOZXh0RnJhbWU7XG4gICAgICAgICAgICAgICAgUGVyZm9ybWFuY2VVdGlscy5mcmFtZShwYWludFN0YXJ0VGltZVN0YW1wLCBpc1JlbmRlckZyYW1lKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9mcmFtZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgdGhpcy5fcmVuZGVyTmV4dEZyYW1lID0gbnVsbDtcbiAgICAgICAgICAgICAgICBpZiAoaXNSZW5kZXJGcmFtZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9yZW5kZXIocGFpbnRTdGFydFRpbWVTdGFtcCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcmVsb2FkcyBhbGwgdGlsZXMgdGhhdCB3aWxsIGJlIHJlcXVlc3RlZCBmb3Igb25lIG9yIGEgc2VyaWVzIG9mIHRyYW5zZm9ybWF0aW9uc1xuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGB0aGlzYCB8IFByb21pc2UuXG4gICAgICovXG4gICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgIF9wcmVsb2FkVGlsZXModHJhbnNmb3JtOiBUcmFuc2Zvcm0gfCBBcnJheTxUcmFuc2Zvcm0+KTogdGhpcyB7XG4gICAgICAgIGNvbnN0IHNvdXJjZXM6IEFycmF5PFNvdXJjZUNhY2hlPiA9IHRoaXMuc3R5bGUgPyAoT2JqZWN0LnZhbHVlcyh0aGlzLnN0eWxlLl9zb3VyY2VDYWNoZXMpOiBhbnkpIDogW107XG4gICAgICAgIGFzeW5jQWxsKHNvdXJjZXMsIChzb3VyY2UsIGRvbmUpID0+IHNvdXJjZS5fcHJlbG9hZFRpbGVzKHRyYW5zZm9ybSwgZG9uZSksICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMudHJpZ2dlclJlcGFpbnQoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgX29uV2luZG93T25saW5lKCkge1xuICAgICAgICB0aGlzLl91cGRhdGUoKTtcbiAgICB9XG5cbiAgICBfb25XaW5kb3dSZXNpemUoZXZlbnQ6IEV2ZW50KSB7XG4gICAgICAgIGlmICh0aGlzLl90cmFja1Jlc2l6ZSkge1xuICAgICAgICAgICAgdGhpcy5yZXNpemUoe29yaWdpbmFsRXZlbnQ6IGV2ZW50fSkuX3VwZGF0ZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX29uVmlzaWJpbGl0eUNoYW5nZSgpIHtcbiAgICAgICAgaWYgKHdpbmRvdy5kb2N1bWVudC52aXNpYmlsaXR5U3RhdGUgPT09ICdoaWRkZW4nKSB7XG4gICAgICAgICAgICB0aGlzLl92aXNpYmlsaXR5SGlkZGVuKys7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQHNlY3Rpb24ge0RlYnVnIGZlYXR1cmVzfSAqL1xuXG4gICAgLyoqXG4gICAgICogR2V0cyBhbmQgc2V0cyBhIEJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIHRoZSBtYXAgd2lsbCByZW5kZXIgYW4gb3V0bGluZVxuICAgICAqIGFyb3VuZCBlYWNoIHRpbGUgYW5kIHRoZSB0aWxlIElELiBUaGVzZSB0aWxlIGJvdW5kYXJpZXMgYXJlIHVzZWZ1bCBmb3JcbiAgICAgKiBkZWJ1Z2dpbmcuXG4gICAgICpcbiAgICAgKiBUaGUgdW5jb21wcmVzc2VkIGZpbGUgc2l6ZSBvZiB0aGUgZmlyc3QgdmVjdG9yIHNvdXJjZSBpcyBkcmF3biBpbiB0aGUgdG9wIGxlZnRcbiAgICAgKiBjb3JuZXIgb2YgZWFjaCB0aWxlLCBuZXh0IHRvIHRoZSB0aWxlIElELlxuICAgICAqXG4gICAgICogQG5hbWUgc2hvd1RpbGVCb3VuZGFyaWVzXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICogQGluc3RhbmNlXG4gICAgICogQG1lbWJlcm9mIE1hcFxuICAgICAqIEBleGFtcGxlXG4gICAgICogbWFwLnNob3dUaWxlQm91bmRhcmllcyA9IHRydWU7XG4gICAgICovXG4gICAgZ2V0IHNob3dUaWxlQm91bmRhcmllcygpOiBib29sZWFuIHsgcmV0dXJuICEhdGhpcy5fc2hvd1RpbGVCb3VuZGFyaWVzOyB9XG4gICAgc2V0IHNob3dUaWxlQm91bmRhcmllcyh2YWx1ZTogYm9vbGVhbikge1xuICAgICAgICBpZiAodGhpcy5fc2hvd1RpbGVCb3VuZGFyaWVzID09PSB2YWx1ZSkgcmV0dXJuO1xuICAgICAgICB0aGlzLl9zaG93VGlsZUJvdW5kYXJpZXMgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5fdXBkYXRlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBhbmQgc2V0cyBhIEJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIHRoZSBtYXAgd2lsbCByZW5kZXIgYSB3aXJlZnJhbWVcbiAgICAgKiBvbiB0b3Agb2YgdGhlIGRpc3BsYXllZCB0ZXJyYWluLiBVc2VmdWwgZm9yIGRlYnVnZ2luZy5cbiAgICAgKlxuICAgICAqIFRoZSB3aXJlZnJhbWUgaXMgYWx3YXlzIHJlZCBhbmQgaXMgZHJhd24gb25seSB3aGVuIHRlcnJhaW4gaXMgYWN0aXZlLlxuICAgICAqXG4gICAgICogQG5hbWUgc2hvd1RlcnJhaW5XaXJlZnJhbWVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAbWVtYmVyb2YgTWFwXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXAuc2hvd1RlcnJhaW5XaXJlZnJhbWUgPSB0cnVlO1xuICAgICAqL1xuICAgIGdldCBzaG93VGVycmFpbldpcmVmcmFtZSgpOiBib29sZWFuIHsgcmV0dXJuICEhdGhpcy5fc2hvd1RlcnJhaW5XaXJlZnJhbWU7IH1cbiAgICBzZXQgc2hvd1RlcnJhaW5XaXJlZnJhbWUodmFsdWU6IGJvb2xlYW4pIHtcbiAgICAgICAgaWYgKHRoaXMuX3Nob3dUZXJyYWluV2lyZWZyYW1lID09PSB2YWx1ZSkgcmV0dXJuO1xuICAgICAgICB0aGlzLl9zaG93VGVycmFpbldpcmVmcmFtZSA9IHZhbHVlO1xuICAgICAgICB0aGlzLl91cGRhdGUoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGFuZCBzZXRzIGEgQm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIHNwZWVkaW5kZXggbWV0cmljIGNhbGN1bGF0aW9uIGlzIG9uIG9yIG9mZlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBzcGVlZEluZGV4VGltaW5nXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICogQGluc3RhbmNlXG4gICAgICogQG1lbWJlcm9mIE1hcFxuICAgICAqIEBleGFtcGxlXG4gICAgICogbWFwLnNwZWVkSW5kZXhUaW1pbmcgPSB0cnVlO1xuICAgICAqL1xuICAgIGdldCBzcGVlZEluZGV4VGltaW5nKCk6IGJvb2xlYW4geyByZXR1cm4gISF0aGlzLl9zcGVlZEluZGV4VGltaW5nOyB9XG4gICAgc2V0IHNwZWVkSW5kZXhUaW1pbmcodmFsdWU6IGJvb2xlYW4pIHtcbiAgICAgICAgaWYgKHRoaXMuX3NwZWVkSW5kZXhUaW1pbmcgPT09IHZhbHVlKSByZXR1cm47XG4gICAgICAgIHRoaXMuX3NwZWVkSW5kZXhUaW1pbmcgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5fdXBkYXRlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBhbmQgc2V0cyBhIEJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIHRoZSBtYXAgd2lsbCB2aXN1YWxpemVcbiAgICAgKiB0aGUgcGFkZGluZyBvZmZzZXRzLlxuICAgICAqXG4gICAgICogQG5hbWUgc2hvd1BhZGRpbmdcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAbWVtYmVyb2YgTWFwXG4gICAgICovXG4gICAgZ2V0IHNob3dQYWRkaW5nKCk6IGJvb2xlYW4geyByZXR1cm4gISF0aGlzLl9zaG93UGFkZGluZzsgfVxuICAgIHNldCBzaG93UGFkZGluZyh2YWx1ZTogYm9vbGVhbikge1xuICAgICAgICBpZiAodGhpcy5fc2hvd1BhZGRpbmcgPT09IHZhbHVlKSByZXR1cm47XG4gICAgICAgIHRoaXMuX3Nob3dQYWRkaW5nID0gdmFsdWU7XG4gICAgICAgIHRoaXMuX3VwZGF0ZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgYW5kIHNldHMgYSBCb29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGUgbWFwIHdpbGwgcmVuZGVyIGJveGVzXG4gICAgICogYXJvdW5kIGFsbCBzeW1ib2xzIGluIHRoZSBkYXRhIHNvdXJjZSwgcmV2ZWFsaW5nIHdoaWNoIHN5bWJvbHNcbiAgICAgKiB3ZXJlIHJlbmRlcmVkIG9yIHdoaWNoIHdlcmUgaGlkZGVuIGR1ZSB0byBjb2xsaXNpb25zLlxuICAgICAqIFRoaXMgaW5mb3JtYXRpb24gaXMgdXNlZnVsIGZvciBkZWJ1Z2dpbmcuXG4gICAgICpcbiAgICAgKiBAbmFtZSBzaG93Q29sbGlzaW9uQm94ZXNcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAbWVtYmVyb2YgTWFwXG4gICAgICovXG4gICAgZ2V0IHNob3dDb2xsaXNpb25Cb3hlcygpOiBib29sZWFuIHsgcmV0dXJuICEhdGhpcy5fc2hvd0NvbGxpc2lvbkJveGVzOyB9XG4gICAgc2V0IHNob3dDb2xsaXNpb25Cb3hlcyh2YWx1ZTogYm9vbGVhbikge1xuICAgICAgICBpZiAodGhpcy5fc2hvd0NvbGxpc2lvbkJveGVzID09PSB2YWx1ZSkgcmV0dXJuO1xuICAgICAgICB0aGlzLl9zaG93Q29sbGlzaW9uQm94ZXMgPSB2YWx1ZTtcbiAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIHR1cm4gY29sbGlzaW9uIGJveGVzIG9uIHdlIGhhdmUgdG8gZ2VuZXJhdGUgdGhlbSBmb3IgZXhpc3RpbmcgdGlsZXNcbiAgICAgICAgICAgIC8vIFdoZW4gd2UgdHVybiB0aGVtIG9mZiwgdGhlcmUncyBubyBjb3N0IHRvIGxlYXZpbmcgZXhpc3RpbmcgYm94ZXMgaW4gcGxhY2VcbiAgICAgICAgICAgIHRoaXMuc3R5bGUuX2dlbmVyYXRlQ29sbGlzaW9uQm94ZXMoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIE90aGVyd2lzZSwgY2FsbCBhbiB1cGRhdGUgdG8gcmVtb3ZlIGNvbGxpc2lvbiBib3hlc1xuICAgICAgICAgICAgdGhpcy5fdXBkYXRlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGFuZCBzZXRzIGEgQm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIG1hcCBzaG91bGQgY29sb3ItY29kZVxuICAgICAqIGVhY2ggZnJhZ21lbnQgdG8gc2hvdyBob3cgbWFueSB0aW1lcyBpdCBoYXMgYmVlbiBzaGFkZWQuXG4gICAgICogV2hpdGUgZnJhZ21lbnRzIGhhdmUgYmVlbiBzaGFkZWQgOCBvciBtb3JlIHRpbWVzLlxuICAgICAqIEJsYWNrIGZyYWdtZW50cyBoYXZlIGJlZW4gc2hhZGVkIDAgdGltZXMuXG4gICAgICogVGhpcyBpbmZvcm1hdGlvbiBpcyB1c2VmdWwgZm9yIGRlYnVnZ2luZy5cbiAgICAgKlxuICAgICAqIEBuYW1lIHNob3dPdmVyZHJhd1xuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEBtZW1iZXJvZiBNYXBcbiAgICAgKi9cbiAgICBnZXQgc2hvd092ZXJkcmF3SW5zcGVjdG9yKCk6IGJvb2xlYW4geyByZXR1cm4gISF0aGlzLl9zaG93T3ZlcmRyYXdJbnNwZWN0b3I7IH1cbiAgICBzZXQgc2hvd092ZXJkcmF3SW5zcGVjdG9yKHZhbHVlOiBib29sZWFuKSB7XG4gICAgICAgIGlmICh0aGlzLl9zaG93T3ZlcmRyYXdJbnNwZWN0b3IgPT09IHZhbHVlKSByZXR1cm47XG4gICAgICAgIHRoaXMuX3Nob3dPdmVyZHJhd0luc3BlY3RvciA9IHZhbHVlO1xuICAgICAgICB0aGlzLl91cGRhdGUoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGFuZCBzZXRzIGEgQm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIG1hcCB3aWxsXG4gICAgICogY29udGludW91c2x5IHJlcGFpbnQuIFRoaXMgaW5mb3JtYXRpb24gaXMgdXNlZnVsIGZvciBhbmFseXppbmcgcGVyZm9ybWFuY2UuXG4gICAgICpcbiAgICAgKiBAbmFtZSByZXBhaW50XG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICogQGluc3RhbmNlXG4gICAgICogQG1lbWJlcm9mIE1hcFxuICAgICAqL1xuICAgIGdldCByZXBhaW50KCk6IGJvb2xlYW4geyByZXR1cm4gISF0aGlzLl9yZXBhaW50OyB9XG4gICAgc2V0IHJlcGFpbnQodmFsdWU6IGJvb2xlYW4pIHtcbiAgICAgICAgaWYgKHRoaXMuX3JlcGFpbnQgIT09IHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9yZXBhaW50ID0gdmFsdWU7XG4gICAgICAgICAgICB0aGlzLnRyaWdnZXJSZXBhaW50KCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gc2hvdyB2ZXJ0aWNlc1xuICAgIGdldCB2ZXJ0aWNlcygpOiBib29sZWFuIHsgcmV0dXJuICEhdGhpcy5fdmVydGljZXM7IH1cbiAgICBzZXQgdmVydGljZXModmFsdWU6IGJvb2xlYW4pIHsgdGhpcy5fdmVydGljZXMgPSB2YWx1ZTsgdGhpcy5fdXBkYXRlKCk7IH1cblxuICAgIC8qKlxuICAgICogRGlzcGxheSB0aWxlIEFBQkJzIGZvciBkZWJ1Z2dpbmdcbiAgICAqXG4gICAgKiBAcHJpdmF0ZVxuICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgKi9cbiAgICBnZXQgc2hvd1RpbGVBQUJCcygpOiBib29sZWFuIHsgcmV0dXJuICEhdGhpcy5fc2hvd1RpbGVBQUJCczsgfVxuICAgIHNldCBzaG93VGlsZUFBQkJzKHZhbHVlOiBib29sZWFuKSB7XG4gICAgICAgIGlmICh0aGlzLl9zaG93VGlsZUFBQkJzID09PSB2YWx1ZSkgcmV0dXJuO1xuICAgICAgICB0aGlzLl9zaG93VGlsZUFBQkJzID0gdmFsdWU7XG4gICAgICAgIGlmICghdmFsdWUpIHsgRGVidWcuY2xlYXJBYWJicygpOyByZXR1cm47IH1cbiAgICAgICAgdGhpcy5fdXBkYXRlKCk7XG4gICAgfVxuXG4gICAgLy8gZm9yIGNhY2hlIGJyb3dzZXIgdGVzdHNcbiAgICBfc2V0Q2FjaGVMaW1pdHMobGltaXQ6IG51bWJlciwgY2hlY2tUaHJlc2hvbGQ6IG51bWJlcikge1xuICAgICAgICBzZXRDYWNoZUxpbWl0cyhsaW1pdCwgY2hlY2tUaHJlc2hvbGQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSB2ZXJzaW9uIG9mIE1hcGJveCBHTCBKUyBpbiB1c2UgYXMgc3BlY2lmaWVkIGluIHBhY2thZ2UuanNvbiwgQ0hBTkdFTE9HLm1kLCBhbmQgdGhlIEdpdEh1YiByZWxlYXNlLlxuICAgICAqXG4gICAgICogQG5hbWUgdmVyc2lvblxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEBtZW1iZXJvZiBNYXBcbiAgICAgKiBAdmFyIHtzdHJpbmd9IHZlcnNpb25cbiAgICAgKi9cblxuICAgIGdldCB2ZXJzaW9uKCk6IHN0cmluZyB7IHJldHVybiB2ZXJzaW9uOyB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IE1hcDtcblxuLyoqXG4gKiBJbnRlcmZhY2UgZm9yIGludGVyYWN0aXZlIGNvbnRyb2xzIGFkZGVkIHRvIHRoZSBtYXAuIFRoaXMgaXMgYVxuICogc3BlY2lmaWNhdGlvbiBmb3IgaW1wbGVtZW50ZXJzIHRvIG1vZGVsOiBpdCBpcyBub3RcbiAqIGFuIGV4cG9ydGVkIG1ldGhvZCBvciBjbGFzcy5cbiAqXG4gKiBDb250cm9scyBtdXN0IGltcGxlbWVudCBgb25BZGRgIGFuZCBgb25SZW1vdmVgLCBhbmQgbXVzdCBvd24gYW5cbiAqIGVsZW1lbnQsIHdoaWNoIGlzIG9mdGVuIGEgYGRpdmAgZWxlbWVudC4gVG8gdXNlIE1hcGJveCBHTCBKUydzXG4gKiBkZWZhdWx0IGNvbnRyb2wgc3R5bGluZywgYWRkIHRoZSBgbWFwYm94Z2wtY3RybGAgY2xhc3MgdG8geW91ciBjb250cm9sJ3NcbiAqIG5vZGUuXG4gKlxuICogQGludGVyZmFjZSBJQ29udHJvbFxuICogQGV4YW1wbGVcbiAqIC8vIENvbnRyb2wgaW1wbGVtZW50ZWQgYXMgRVM2IGNsYXNzXG4gKiBjbGFzcyBIZWxsb1dvcmxkQ29udHJvbCB7XG4gKiAgICAgb25BZGQobWFwKSB7XG4gKiAgICAgICAgIHRoaXMuX21hcCA9IG1hcDtcbiAqICAgICAgICAgdGhpcy5fY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gKiAgICAgICAgIHRoaXMuX2NvbnRhaW5lci5jbGFzc05hbWUgPSAnbWFwYm94Z2wtY3RybCc7XG4gKiAgICAgICAgIHRoaXMuX2NvbnRhaW5lci50ZXh0Q29udGVudCA9ICdIZWxsbywgd29ybGQnO1xuICogICAgICAgICByZXR1cm4gdGhpcy5fY29udGFpbmVyO1xuICogICAgIH1cbiAqXG4gKiAgICAgb25SZW1vdmUoKSB7XG4gKiAgICAgICAgIHRoaXMuX2NvbnRhaW5lci5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRoaXMuX2NvbnRhaW5lcik7XG4gKiAgICAgICAgIHRoaXMuX21hcCA9IHVuZGVmaW5lZDtcbiAqICAgICB9XG4gKiB9XG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIENvbnRyb2wgaW1wbGVtZW50ZWQgYXMgRVM1IHByb3RvdHlwaWNhbCBjbGFzc1xuICogZnVuY3Rpb24gSGVsbG9Xb3JsZENvbnRyb2woKSB7IH1cbiAqXG4gKiBIZWxsb1dvcmxkQ29udHJvbC5wcm90b3R5cGUub25BZGQgPSBmdW5jdGlvbihtYXApIHtcbiAqICAgICB0aGlzLl9tYXAgPSBtYXA7XG4gKiAgICAgdGhpcy5fY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gKiAgICAgdGhpcy5fY29udGFpbmVyLmNsYXNzTmFtZSA9ICdtYXBib3hnbC1jdHJsJztcbiAqICAgICB0aGlzLl9jb250YWluZXIudGV4dENvbnRlbnQgPSAnSGVsbG8sIHdvcmxkJztcbiAqICAgICByZXR1cm4gdGhpcy5fY29udGFpbmVyO1xuICogfTtcbiAqXG4gKiBIZWxsb1dvcmxkQ29udHJvbC5wcm90b3R5cGUub25SZW1vdmUgPSBmdW5jdGlvbiAoKSB7XG4gKiAgICAgdGhpcy5fY29udGFpbmVyLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5fY29udGFpbmVyKTtcbiAqICAgICB0aGlzLl9tYXAgPSB1bmRlZmluZWQ7XG4gKiB9O1xuICovXG5cbi8qKlxuICogUmVnaXN0ZXIgYSBjb250cm9sIG9uIHRoZSBtYXAgYW5kIGdpdmUgaXQgYSBjaGFuY2UgdG8gcmVnaXN0ZXIgZXZlbnQgbGlzdGVuZXJzXG4gKiBhbmQgcmVzb3VyY2VzLiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkge0BsaW5rIE1hcCNhZGRDb250cm9sfVxuICogaW50ZXJuYWxseS5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBtZW1iZXJvZiBJQ29udHJvbFxuICogQGluc3RhbmNlXG4gKiBAbmFtZSBvbkFkZFxuICogQHBhcmFtIHtNYXB9IG1hcCBUaGUgTWFwIHRoaXMgY29udHJvbCB3aWxsIGJlIGFkZGVkIHRvLlxuICogQHJldHVybnMge0hUTUxFbGVtZW50fSBUaGUgY29udHJvbCdzIGNvbnRhaW5lciBlbGVtZW50LiBUaGlzIHNob3VsZFxuICogYmUgY3JlYXRlZCBieSB0aGUgY29udHJvbCBhbmQgcmV0dXJuZWQgYnkgb25BZGQgd2l0aG91dCBiZWluZyBhdHRhY2hlZFxuICogdG8gdGhlIERPTTogdGhlIG1hcCB3aWxsIGluc2VydCB0aGUgY29udHJvbCdzIGVsZW1lbnQgaW50byB0aGUgRE9NXG4gKiBhcyBuZWNlc3NhcnkuXG4gKi9cblxuLyoqXG4gKiBVbnJlZ2lzdGVyIGEgY29udHJvbCBvbiB0aGUgbWFwIGFuZCBnaXZlIGl0IGEgY2hhbmNlIHRvIGRldGFjaCBldmVudCBsaXN0ZW5lcnNcbiAqIGFuZCByZXNvdXJjZXMuIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB7QGxpbmsgTWFwI3JlbW92ZUNvbnRyb2x9XG4gKiBpbnRlcm5hbGx5LlxuICpcbiAqIEBmdW5jdGlvblxuICogQG1lbWJlcm9mIElDb250cm9sXG4gKiBAaW5zdGFuY2VcbiAqIEBuYW1lIG9uUmVtb3ZlXG4gKiBAcGFyYW0ge01hcH0gbWFwIFRoZSBNYXAgdGhpcyBjb250cm9sIHdpbGwgYmUgcmVtb3ZlZCBmcm9tLlxuICogQHJldHVybnMge3VuZGVmaW5lZH0gVGhlcmUgaXMgbm8gcmVxdWlyZWQgcmV0dXJuIHZhbHVlIGZvciB0aGlzIG1ldGhvZC5cbiAqL1xuXG4vKipcbiAqIE9wdGlvbmFsbHkgcHJvdmlkZSBhIGRlZmF1bHQgcG9zaXRpb24gZm9yIHRoaXMgY29udHJvbC4gSWYgdGhpcyBtZXRob2RcbiAqIGlzIGltcGxlbWVudGVkIGFuZCB7QGxpbmsgTWFwI2FkZENvbnRyb2x9IGlzIGNhbGxlZCB3aXRob3V0IHRoZSBgcG9zaXRpb25gXG4gKiBwYXJhbWV0ZXIsIHRoZSB2YWx1ZSByZXR1cm5lZCBieSBnZXREZWZhdWx0UG9zaXRpb24gd2lsbCBiZSB1c2VkIGFzIHRoZVxuICogY29udHJvbCdzIHBvc2l0aW9uLlxuICpcbiAqIEBmdW5jdGlvblxuICogQG1lbWJlcm9mIElDb250cm9sXG4gKiBAaW5zdGFuY2VcbiAqIEBuYW1lIGdldERlZmF1bHRQb3NpdGlvblxuICogQHJldHVybnMge3N0cmluZ30gQSBjb250cm9sIHBvc2l0aW9uLCBvbmUgb2YgdGhlIHZhbHVlcyB2YWxpZCBpbiBhZGRDb250cm9sLlxuICovXG5cbi8qKlxuICogQSBbYFBvaW50YCBnZW9tZXRyeV0oaHR0cHM6Ly9naXRodWIuY29tL21hcGJveC9wb2ludC1nZW9tZXRyeSkgb2JqZWN0LCB3aGljaCBoYXNcbiAqIGB4YCBhbmQgYHlgIHByb3BlcnRpZXMgcmVwcmVzZW50aW5nIHNjcmVlbiBjb29yZGluYXRlcyBpbiBwaXhlbHMuXG4gKlxuICogQHR5cGVkZWYge1BvaW50fSBQb2ludFxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHBvaW50ID0gbmV3IG1hcGJveGdsLlBvaW50KC03NywgMzgpO1xuICovXG5cbi8qKlxuICogQSB7QGxpbmsgUG9pbnR9IG9yIGFuIGFycmF5IG9mIHR3byBudW1iZXJzIHJlcHJlc2VudGluZyBgeGAgYW5kIGB5YCBzY3JlZW4gY29vcmRpbmF0ZXMgaW4gcGl4ZWxzLlxuICpcbiAqIEB0eXBlZGVmIHsoUG9pbnQgfCBBcnJheTxudW1iZXI+KX0gUG9pbnRMaWtlXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcDEgPSBuZXcgbWFwYm94Z2wuUG9pbnQoLTc3LCAzOCk7IC8vIGEgUG9pbnRMaWtlIHdoaWNoIGlzIGEgUG9pbnRcbiAqIGNvbnN0IHAyID0gWy03NywgMzhdOyAvLyBhIFBvaW50TGlrZSB3aGljaCBpcyBhbiBhcnJheSBvZiB0d28gbnVtYmVyc1xuICovXG4iLCIvLyBAZmxvd1xuXG5pbXBvcnQgKiBhcyBET00gZnJvbSAnLi4vLi4vdXRpbC9kb20uanMnO1xuaW1wb3J0IHtleHRlbmQsIGJpbmRBbGx9IGZyb20gJy4uLy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQge01vdXNlUm90YXRlSGFuZGxlciwgTW91c2VQaXRjaEhhbmRsZXJ9IGZyb20gJy4uL2hhbmRsZXIvbW91c2UuanMnO1xuaW1wb3J0IHdpbmRvdyBmcm9tICcuLi8uLi91dGlsL3dpbmRvdy5qcyc7XG5cbmltcG9ydCB0eXBlIE1hcCBmcm9tICcuLi9tYXAuanMnO1xuaW1wb3J0IHR5cGUgUG9pbnQgZnJvbSAnQG1hcGJveC9wb2ludC1nZW9tZXRyeSc7XG5cbnR5cGUgT3B0aW9ucyA9IHtcbiAgICBzaG93Q29tcGFzcz86IGJvb2xlYW4sXG4gICAgc2hvd1pvb20/OiBib29sZWFuLFxuICAgIHZpc3VhbGl6ZVBpdGNoPzogYm9vbGVhblxufTtcblxuY29uc3QgZGVmYXVsdE9wdGlvbnM6IE9wdGlvbnMgPSB7XG4gICAgc2hvd0NvbXBhc3M6IHRydWUsXG4gICAgc2hvd1pvb206IHRydWUsXG4gICAgdmlzdWFsaXplUGl0Y2g6IGZhbHNlXG59O1xuXG4vKipcbiAqIEEgYE5hdmlnYXRpb25Db250cm9sYCBjb250cm9sIGNvbnRhaW5zIHpvb20gYnV0dG9ucyBhbmQgYSBjb21wYXNzLlxuICogQWRkIHRoaXMgY29udHJvbCB0byBhIG1hcCB1c2luZyB7QGxpbmsgTWFwI2FkZENvbnRyb2x9LlxuICpcbiAqIEBpbXBsZW1lbnRzIHtJQ29udHJvbH1cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMuc2hvd0NvbXBhc3M9dHJ1ZV0gSWYgYHRydWVgIHRoZSBjb21wYXNzIGJ1dHRvbiBpcyBpbmNsdWRlZC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMuc2hvd1pvb209dHJ1ZV0gSWYgYHRydWVgIHRoZSB6b29tLWluIGFuZCB6b29tLW91dCBidXR0b25zIGFyZSBpbmNsdWRlZC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMudmlzdWFsaXplUGl0Y2g9ZmFsc2VdIElmIGB0cnVlYCB0aGUgcGl0Y2ggaXMgdmlzdWFsaXplZCBieSByb3RhdGluZyBYLWF4aXMgb2YgY29tcGFzcy5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBuYXYgPSBuZXcgbWFwYm94Z2wuTmF2aWdhdGlvbkNvbnRyb2woKTtcbiAqIG1hcC5hZGRDb250cm9sKG5hdiwgJ3RvcC1sZWZ0Jyk7XG4gKiBAZXhhbXBsZVxuICogY29uc3QgbmF2ID0gbmV3IG1hcGJveGdsLk5hdmlnYXRpb25Db250cm9sKHtcbiAqICAgICB2aXN1YWxpemVQaXRjaDogdHJ1ZVxuICogfSk7XG4gKiBtYXAuYWRkQ29udHJvbChuYXYsICdib3R0b20tcmlnaHQnKTtcbiAqIEBzZWUgW0V4YW1wbGU6IERpc3BsYXkgbWFwIG5hdmlnYXRpb24gY29udHJvbHNdKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvbmF2aWdhdGlvbi8pXG4gKiBAc2VlIFtFeGFtcGxlOiBBZGQgYSB0aGlyZCBwYXJ0eSB2ZWN0b3IgdGlsZSBzb3VyY2VdKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2V4YW1wbGUvdGhpcmQtcGFydHkvKVxuICovXG5jbGFzcyBOYXZpZ2F0aW9uQ29udHJvbCB7XG4gICAgX21hcDogP01hcDtcbiAgICBvcHRpb25zOiBPcHRpb25zO1xuICAgIF9jb250YWluZXI6IEhUTUxFbGVtZW50O1xuICAgIF96b29tSW5CdXR0b246IEhUTUxCdXR0b25FbGVtZW50O1xuICAgIF96b29tT3V0QnV0dG9uOiBIVE1MQnV0dG9uRWxlbWVudDtcbiAgICBfY29tcGFzczogSFRNTEJ1dHRvbkVsZW1lbnQ7XG4gICAgX2NvbXBhc3NJY29uOiBIVE1MRWxlbWVudDtcbiAgICBfaGFuZGxlcjogP01vdXNlUm90YXRlV3JhcHBlcjtcblxuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnM6IE9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gZXh0ZW5kKHt9LCBkZWZhdWx0T3B0aW9ucywgb3B0aW9ucyk7XG5cbiAgICAgICAgdGhpcy5fY29udGFpbmVyID0gRE9NLmNyZWF0ZSgnZGl2JywgJ21hcGJveGdsLWN0cmwgbWFwYm94Z2wtY3RybC1ncm91cCcpO1xuICAgICAgICB0aGlzLl9jb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcignY29udGV4dG1lbnUnLCAoZTogTW91c2VFdmVudCkgPT4gZS5wcmV2ZW50RGVmYXVsdCgpKTtcblxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnNob3dab29tKSB7XG4gICAgICAgICAgICBiaW5kQWxsKFtcbiAgICAgICAgICAgICAgICAnX3NldEJ1dHRvblRpdGxlJyxcbiAgICAgICAgICAgICAgICAnX3VwZGF0ZVpvb21CdXR0b25zJ1xuICAgICAgICAgICAgXSwgdGhpcyk7XG4gICAgICAgICAgICB0aGlzLl96b29tSW5CdXR0b24gPSB0aGlzLl9jcmVhdGVCdXR0b24oJ21hcGJveGdsLWN0cmwtem9vbS1pbicsIChlKSA9PiB7IGlmICh0aGlzLl9tYXApIHRoaXMuX21hcC56b29tSW4oe30sIHtvcmlnaW5hbEV2ZW50OiBlfSk7IH0pO1xuICAgICAgICAgICAgRE9NLmNyZWF0ZSgnc3BhbicsIGBtYXBib3hnbC1jdHJsLWljb25gLCB0aGlzLl96b29tSW5CdXR0b24pLnNldEF0dHJpYnV0ZSgnYXJpYS1oaWRkZW4nLCAndHJ1ZScpO1xuICAgICAgICAgICAgdGhpcy5fem9vbU91dEJ1dHRvbiA9IHRoaXMuX2NyZWF0ZUJ1dHRvbignbWFwYm94Z2wtY3RybC16b29tLW91dCcsIChlKSA9PiB7IGlmICh0aGlzLl9tYXApIHRoaXMuX21hcC56b29tT3V0KHt9LCB7b3JpZ2luYWxFdmVudDogZX0pOyB9KTtcbiAgICAgICAgICAgIERPTS5jcmVhdGUoJ3NwYW4nLCBgbWFwYm94Z2wtY3RybC1pY29uYCwgdGhpcy5fem9vbU91dEJ1dHRvbikuc2V0QXR0cmlidXRlKCdhcmlhLWhpZGRlbicsICd0cnVlJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zaG93Q29tcGFzcykge1xuICAgICAgICAgICAgYmluZEFsbChbXG4gICAgICAgICAgICAgICAgJ19yb3RhdGVDb21wYXNzQXJyb3cnXG4gICAgICAgICAgICBdLCB0aGlzKTtcbiAgICAgICAgICAgIHRoaXMuX2NvbXBhc3MgPSB0aGlzLl9jcmVhdGVCdXR0b24oJ21hcGJveGdsLWN0cmwtY29tcGFzcycsIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgbWFwID0gdGhpcy5fbWFwO1xuICAgICAgICAgICAgICAgIGlmICghbWFwKSByZXR1cm47XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy52aXN1YWxpemVQaXRjaCkge1xuICAgICAgICAgICAgICAgICAgICBtYXAucmVzZXROb3J0aFBpdGNoKHt9LCB7b3JpZ2luYWxFdmVudDogZX0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIG1hcC5yZXNldE5vcnRoKHt9LCB7b3JpZ2luYWxFdmVudDogZX0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5fY29tcGFzc0ljb24gPSBET00uY3JlYXRlKCdzcGFuJywgJ21hcGJveGdsLWN0cmwtaWNvbicsIHRoaXMuX2NvbXBhc3MpO1xuICAgICAgICAgICAgdGhpcy5fY29tcGFzc0ljb24uc2V0QXR0cmlidXRlKCdhcmlhLWhpZGRlbicsICd0cnVlJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfdXBkYXRlWm9vbUJ1dHRvbnMoKSB7XG4gICAgICAgIGNvbnN0IG1hcCA9IHRoaXMuX21hcDtcbiAgICAgICAgaWYgKCFtYXApIHJldHVybjtcblxuICAgICAgICBjb25zdCB6b29tID0gbWFwLmdldFpvb20oKTtcbiAgICAgICAgY29uc3QgaXNNYXggPSB6b29tID09PSBtYXAuZ2V0TWF4Wm9vbSgpO1xuICAgICAgICBjb25zdCBpc01pbiA9IHpvb20gPT09IG1hcC5nZXRNaW5ab29tKCk7XG4gICAgICAgIHRoaXMuX3pvb21JbkJ1dHRvbi5kaXNhYmxlZCA9IGlzTWF4O1xuICAgICAgICB0aGlzLl96b29tT3V0QnV0dG9uLmRpc2FibGVkID0gaXNNaW47XG4gICAgICAgIHRoaXMuX3pvb21JbkJ1dHRvbi5zZXRBdHRyaWJ1dGUoJ2FyaWEtZGlzYWJsZWQnLCBpc01heC50b1N0cmluZygpKTtcbiAgICAgICAgdGhpcy5fem9vbU91dEJ1dHRvbi5zZXRBdHRyaWJ1dGUoJ2FyaWEtZGlzYWJsZWQnLCBpc01pbi50b1N0cmluZygpKTtcbiAgICB9XG5cbiAgICBfcm90YXRlQ29tcGFzc0Fycm93KCkge1xuICAgICAgICBjb25zdCBtYXAgPSB0aGlzLl9tYXA7XG4gICAgICAgIGlmICghbWFwKSByZXR1cm47XG5cbiAgICAgICAgY29uc3Qgcm90YXRlID0gdGhpcy5vcHRpb25zLnZpc3VhbGl6ZVBpdGNoID9cbiAgICAgICAgICAgIGBzY2FsZSgkezEgLyBNYXRoLnBvdyhNYXRoLmNvcyhtYXAudHJhbnNmb3JtLnBpdGNoICogKE1hdGguUEkgLyAxODApKSwgMC41KX0pIHJvdGF0ZVgoJHttYXAudHJhbnNmb3JtLnBpdGNofWRlZykgcm90YXRlWigke21hcC50cmFuc2Zvcm0uYW5nbGUgKiAoMTgwIC8gTWF0aC5QSSl9ZGVnKWAgOlxuICAgICAgICAgICAgYHJvdGF0ZSgke21hcC50cmFuc2Zvcm0uYW5nbGUgKiAoMTgwIC8gTWF0aC5QSSl9ZGVnKWA7XG5cbiAgICAgICAgbWFwLl9yZXF1ZXN0RG9tVGFzaygoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5fY29tcGFzc0ljb24pIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9jb21wYXNzSWNvbi5zdHlsZS50cmFuc2Zvcm0gPSByb3RhdGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG9uQWRkKG1hcDogTWFwKTogSFRNTEVsZW1lbnQge1xuICAgICAgICB0aGlzLl9tYXAgPSBtYXA7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc2hvd1pvb20pIHtcbiAgICAgICAgICAgIHRoaXMuX3NldEJ1dHRvblRpdGxlKHRoaXMuX3pvb21JbkJ1dHRvbiwgJ1pvb21JbicpO1xuICAgICAgICAgICAgdGhpcy5fc2V0QnV0dG9uVGl0bGUodGhpcy5fem9vbU91dEJ1dHRvbiwgJ1pvb21PdXQnKTtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIG1hcC5vbignem9vbScsIHRoaXMuX3VwZGF0ZVpvb21CdXR0b25zKTtcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZVpvb21CdXR0b25zKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zaG93Q29tcGFzcykge1xuICAgICAgICAgICAgdGhpcy5fc2V0QnV0dG9uVGl0bGUodGhpcy5fY29tcGFzcywgJ1Jlc2V0QmVhcmluZycpO1xuICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy52aXN1YWxpemVQaXRjaCkge1xuICAgICAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgICAgICBtYXAub24oJ3BpdGNoJywgdGhpcy5fcm90YXRlQ29tcGFzc0Fycm93KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgIG1hcC5vbigncm90YXRlJywgdGhpcy5fcm90YXRlQ29tcGFzc0Fycm93KTtcbiAgICAgICAgICAgIHRoaXMuX3JvdGF0ZUNvbXBhc3NBcnJvdygpO1xuICAgICAgICAgICAgdGhpcy5faGFuZGxlciA9IG5ldyBNb3VzZVJvdGF0ZVdyYXBwZXIobWFwLCB0aGlzLl9jb21wYXNzLCB0aGlzLm9wdGlvbnMudmlzdWFsaXplUGl0Y2gpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250YWluZXI7XG4gICAgfVxuXG4gICAgb25SZW1vdmUoKSB7XG4gICAgICAgIGNvbnN0IG1hcCA9IHRoaXMuX21hcDtcbiAgICAgICAgaWYgKCFtYXApIHJldHVybjtcbiAgICAgICAgdGhpcy5fY29udGFpbmVyLnJlbW92ZSgpO1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnNob3dab29tKSB7XG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICBtYXAub2ZmKCd6b29tJywgdGhpcy5fdXBkYXRlWm9vbUJ1dHRvbnMpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc2hvd0NvbXBhc3MpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMudmlzdWFsaXplUGl0Y2gpIHtcbiAgICAgICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICAgICAgbWFwLm9mZigncGl0Y2gnLCB0aGlzLl9yb3RhdGVDb21wYXNzQXJyb3cpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgbWFwLm9mZigncm90YXRlJywgdGhpcy5fcm90YXRlQ29tcGFzc0Fycm93KTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9oYW5kbGVyKSB0aGlzLl9oYW5kbGVyLm9mZigpO1xuICAgICAgICAgICAgdGhpcy5faGFuZGxlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9tYXAgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgX2NyZWF0ZUJ1dHRvbihjbGFzc05hbWU6IHN0cmluZywgZm46ICgpID0+IG1peGVkKTogSFRNTEJ1dHRvbkVsZW1lbnQge1xuICAgICAgICBjb25zdCBhID0gRE9NLmNyZWF0ZSgnYnV0dG9uJywgY2xhc3NOYW1lLCB0aGlzLl9jb250YWluZXIpO1xuICAgICAgICBhLnR5cGUgPSAnYnV0dG9uJztcbiAgICAgICAgYS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZuKTtcbiAgICAgICAgcmV0dXJuIGE7XG4gICAgfVxuXG4gICAgX3NldEJ1dHRvblRpdGxlKGJ1dHRvbjogSFRNTEJ1dHRvbkVsZW1lbnQsIHRpdGxlOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9tYXApIHJldHVybjtcbiAgICAgICAgY29uc3Qgc3RyID0gdGhpcy5fbWFwLl9nZXRVSVN0cmluZyhgTmF2aWdhdGlvbkNvbnRyb2wuJHt0aXRsZX1gKTtcbiAgICAgICAgYnV0dG9uLnNldEF0dHJpYnV0ZSgnYXJpYS1sYWJlbCcsIHN0cik7XG4gICAgICAgIGlmIChidXR0b24uZmlyc3RFbGVtZW50Q2hpbGQpIGJ1dHRvbi5maXJzdEVsZW1lbnRDaGlsZC5zZXRBdHRyaWJ1dGUoJ3RpdGxlJywgc3RyKTtcbiAgICB9XG59XG5cbmNsYXNzIE1vdXNlUm90YXRlV3JhcHBlciB7XG5cbiAgICBtYXA6IE1hcDtcbiAgICBfY2xpY2tUb2xlcmFuY2U6IG51bWJlcjtcbiAgICBlbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgICBtb3VzZVJvdGF0ZTogTW91c2VSb3RhdGVIYW5kbGVyO1xuICAgIG1vdXNlUGl0Y2g6IE1vdXNlUGl0Y2hIYW5kbGVyO1xuICAgIF9zdGFydFBvczogP1BvaW50O1xuICAgIF9sYXN0UG9zOiA/UG9pbnQ7XG5cbiAgICBjb25zdHJ1Y3RvcihtYXA6IE1hcCwgZWxlbWVudDogSFRNTEVsZW1lbnQsIHBpdGNoPzogYm9vbGVhbiA9IGZhbHNlKSB7XG4gICAgICAgIHRoaXMuX2NsaWNrVG9sZXJhbmNlID0gMTA7XG4gICAgICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgICAgIHRoaXMubW91c2VSb3RhdGUgPSBuZXcgTW91c2VSb3RhdGVIYW5kbGVyKHtjbGlja1RvbGVyYW5jZTogbWFwLmRyYWdSb3RhdGUuX21vdXNlUm90YXRlLl9jbGlja1RvbGVyYW5jZX0pO1xuICAgICAgICB0aGlzLm1hcCA9IG1hcDtcbiAgICAgICAgaWYgKHBpdGNoKSB0aGlzLm1vdXNlUGl0Y2ggPSBuZXcgTW91c2VQaXRjaEhhbmRsZXIoe2NsaWNrVG9sZXJhbmNlOiBtYXAuZHJhZ1JvdGF0ZS5fbW91c2VQaXRjaC5fY2xpY2tUb2xlcmFuY2V9KTtcblxuICAgICAgICBiaW5kQWxsKFsnbW91c2Vkb3duJywgJ21vdXNlbW92ZScsICdtb3VzZXVwJywgJ3RvdWNoc3RhcnQnLCAndG91Y2htb3ZlJywgJ3RvdWNoZW5kJywgJ3Jlc2V0J10sIHRoaXMpO1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5tb3VzZWRvd24pO1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIHRoaXMudG91Y2hzdGFydCwge3Bhc3NpdmU6IGZhbHNlfSk7XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCB0aGlzLnRvdWNobW92ZSk7XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGVuZCcsIHRoaXMudG91Y2hlbmQpO1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hjYW5jZWwnLCB0aGlzLnJlc2V0KTtcbiAgICB9XG5cbiAgICBkb3duKGU6IE1vdXNlRXZlbnQsIHBvaW50OiBQb2ludCkge1xuICAgICAgICB0aGlzLm1vdXNlUm90YXRlLm1vdXNlZG93bihlLCBwb2ludCk7XG4gICAgICAgIGlmICh0aGlzLm1vdXNlUGl0Y2gpIHRoaXMubW91c2VQaXRjaC5tb3VzZWRvd24oZSwgcG9pbnQpO1xuICAgICAgICBET00uZGlzYWJsZURyYWcoKTtcbiAgICB9XG5cbiAgICBtb3ZlKGU6IE1vdXNlRXZlbnQsIHBvaW50OiBQb2ludCkge1xuICAgICAgICBjb25zdCBtYXAgPSB0aGlzLm1hcDtcbiAgICAgICAgY29uc3QgciA9IHRoaXMubW91c2VSb3RhdGUubW91c2Vtb3ZlV2luZG93KGUsIHBvaW50KTtcbiAgICAgICAgY29uc3QgZGVsdGEgPSByICYmIHIuYmVhcmluZ0RlbHRhO1xuICAgICAgICBpZiAoZGVsdGEpIG1hcC5zZXRCZWFyaW5nKG1hcC5nZXRCZWFyaW5nKCkgKyBkZWx0YSk7XG4gICAgICAgIGlmICh0aGlzLm1vdXNlUGl0Y2gpIHtcbiAgICAgICAgICAgIGNvbnN0IHAgPSB0aGlzLm1vdXNlUGl0Y2gubW91c2Vtb3ZlV2luZG93KGUsIHBvaW50KTtcbiAgICAgICAgICAgIGNvbnN0IGRlbHRhID0gcCAmJiBwLnBpdGNoRGVsdGE7XG4gICAgICAgICAgICBpZiAoZGVsdGEpIG1hcC5zZXRQaXRjaChtYXAuZ2V0UGl0Y2goKSArIGRlbHRhKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9mZigpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuZWxlbWVudDtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIHRoaXMubW91c2Vkb3duKTtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCB0aGlzLnRvdWNoc3RhcnQsIHtwYXNzaXZlOiBmYWxzZX0pO1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgdGhpcy50b3VjaG1vdmUpO1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCB0aGlzLnRvdWNoZW5kKTtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoY2FuY2VsJywgdGhpcy5yZXNldCk7XG4gICAgICAgIHRoaXMub2ZmVGVtcCgpO1xuICAgIH1cblxuICAgIG9mZlRlbXAoKSB7XG4gICAgICAgIERPTS5lbmFibGVEcmFnKCk7XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHRoaXMubW91c2Vtb3ZlKTtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMubW91c2V1cCk7XG4gICAgfVxuXG4gICAgbW91c2Vkb3duKGU6IE1vdXNlRXZlbnQpIHtcbiAgICAgICAgdGhpcy5kb3duKGV4dGVuZCh7fSwgZSwge2N0cmxLZXk6IHRydWUsIHByZXZlbnREZWZhdWx0OiAoKSA9PiBlLnByZXZlbnREZWZhdWx0KCl9KSwgRE9NLm1vdXNlUG9zKHRoaXMuZWxlbWVudCwgZSkpO1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB0aGlzLm1vdXNlbW92ZSk7XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLm1vdXNldXApO1xuICAgIH1cblxuICAgIG1vdXNlbW92ZShlOiBNb3VzZUV2ZW50KSB7XG4gICAgICAgIHRoaXMubW92ZShlLCBET00ubW91c2VQb3ModGhpcy5lbGVtZW50LCBlKSk7XG4gICAgfVxuXG4gICAgbW91c2V1cChlOiBNb3VzZUV2ZW50KSB7XG4gICAgICAgIHRoaXMubW91c2VSb3RhdGUubW91c2V1cFdpbmRvdyhlKTtcbiAgICAgICAgaWYgKHRoaXMubW91c2VQaXRjaCkgdGhpcy5tb3VzZVBpdGNoLm1vdXNldXBXaW5kb3coZSk7XG4gICAgICAgIHRoaXMub2ZmVGVtcCgpO1xuICAgIH1cblxuICAgIHRvdWNoc3RhcnQoZTogVG91Y2hFdmVudCkge1xuICAgICAgICBpZiAoZS50YXJnZXRUb3VjaGVzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fc3RhcnRQb3MgPSB0aGlzLl9sYXN0UG9zID0gRE9NLnRvdWNoUG9zKHRoaXMuZWxlbWVudCwgZS50YXJnZXRUb3VjaGVzKVswXTtcbiAgICAgICAgICAgIHRoaXMuZG93bigoKHt0eXBlOiAnbW91c2Vkb3duJywgYnV0dG9uOiAwLCBjdHJsS2V5OiB0cnVlLCBwcmV2ZW50RGVmYXVsdDogKCkgPT4gZS5wcmV2ZW50RGVmYXVsdCgpfTogYW55KTogTW91c2VFdmVudCksIHRoaXMuX3N0YXJ0UG9zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHRvdWNobW92ZShlOiBUb3VjaEV2ZW50KSB7XG4gICAgICAgIGlmIChlLnRhcmdldFRvdWNoZXMubGVuZ3RoICE9PSAxKSB7XG4gICAgICAgICAgICB0aGlzLnJlc2V0KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9sYXN0UG9zID0gRE9NLnRvdWNoUG9zKHRoaXMuZWxlbWVudCwgZS50YXJnZXRUb3VjaGVzKVswXTtcbiAgICAgICAgICAgIHRoaXMubW92ZSgoKHtwcmV2ZW50RGVmYXVsdDogKCkgPT4gZS5wcmV2ZW50RGVmYXVsdCgpfTogYW55KTogTW91c2VFdmVudCksIHRoaXMuX2xhc3RQb3MpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdG91Y2hlbmQoZTogVG91Y2hFdmVudCkge1xuICAgICAgICBpZiAoZS50YXJnZXRUb3VjaGVzLmxlbmd0aCA9PT0gMCAmJlxuICAgICAgICAgICAgdGhpcy5fc3RhcnRQb3MgJiZcbiAgICAgICAgICAgIHRoaXMuX2xhc3RQb3MgJiZcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0UG9zLmRpc3QodGhpcy5fbGFzdFBvcykgPCB0aGlzLl9jbGlja1RvbGVyYW5jZSkge1xuICAgICAgICAgICAgdGhpcy5lbGVtZW50LmNsaWNrKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgIH1cblxuICAgIHJlc2V0KCkge1xuICAgICAgICB0aGlzLm1vdXNlUm90YXRlLnJlc2V0KCk7XG4gICAgICAgIGlmICh0aGlzLm1vdXNlUGl0Y2gpIHRoaXMubW91c2VQaXRjaC5yZXNldCgpO1xuICAgICAgICBkZWxldGUgdGhpcy5fc3RhcnRQb3M7XG4gICAgICAgIGRlbGV0ZSB0aGlzLl9sYXN0UG9zO1xuICAgICAgICB0aGlzLm9mZlRlbXAoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IE5hdmlnYXRpb25Db250cm9sO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHtFdmVudCwgRXZlbnRlZH0gZnJvbSAnLi4vLi4vdXRpbC9ldmVudGVkLmpzJztcbmltcG9ydCAqIGFzIERPTSBmcm9tICcuLi8uLi91dGlsL2RvbS5qcyc7XG5pbXBvcnQgd2luZG93IGZyb20gJy4uLy4uL3V0aWwvd2luZG93LmpzJztcbmltcG9ydCB7ZXh0ZW5kLCBiaW5kQWxsLCB3YXJuT25jZX0gZnJvbSAnLi4vLi4vdXRpbC91dGlsLmpzJztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCBNYXJrZXIgZnJvbSAnLi4vbWFya2VyLmpzJztcbmltcG9ydCBMbmdMYXQgZnJvbSAnLi4vLi4vZ2VvL2xuZ19sYXQuanMnO1xuaW1wb3J0IHRocm90dGxlIGZyb20gJy4uLy4uL3V0aWwvdGhyb3R0bGUuanMnO1xuaW1wb3J0IHttZXJjYXRvclpmcm9tQWx0aXR1ZGV9IGZyb20gJy4uLy4uL2dlby9tZXJjYXRvcl9jb29yZGluYXRlLmpzJztcblxuaW1wb3J0IHR5cGUgTWFwIGZyb20gJy4uL21hcC5qcyc7XG5pbXBvcnQgdHlwZSB7QW5pbWF0aW9uT3B0aW9ucywgQ2FtZXJhT3B0aW9uc30gZnJvbSAnLi4vY2FtZXJhLmpzJztcblxudHlwZSBPcHRpb25zID0ge1xuICAgIHBvc2l0aW9uT3B0aW9uczogUG9zaXRpb25PcHRpb25zLFxuICAgIGZpdEJvdW5kc09wdGlvbnM6IEFuaW1hdGlvbk9wdGlvbnMgJiBDYW1lcmFPcHRpb25zLFxuICAgIHRyYWNrVXNlckxvY2F0aW9uOiBib29sZWFuLFxuICAgIHNob3dBY2N1cmFjeUNpcmNsZTogYm9vbGVhbixcbiAgICBzaG93VXNlckxvY2F0aW9uOiBib29sZWFuLFxuICAgIHNob3dVc2VySGVhZGluZzogYm9vbGVhbixcbiAgICBnZW9sb2NhdGlvbjogR2VvbG9jYXRpb24sXG59O1xuXG50eXBlIERldmljZU9yaWVudGF0aW9uRXZlbnQgPSB7XG4gICAgYWJzb2x1dGU6IGJvb2xlYW4sXG4gICAgYWxwaGE6IG51bWJlcixcbiAgICBiZXRhOiBudW1iZXIsXG4gICAgZ2FtbWE6IG51bWJlcixcbiAgICByZXF1ZXN0UGVybWlzc2lvbjogUHJvbWlzZTxTdHJpbmc+LFxuICAgIHdlYmtpdENvbXBhc3NIZWFkaW5nPzogbnVtYmVyLFxufVxuXG5jb25zdCBkZWZhdWx0T3B0aW9ucyA9IHtcbiAgICBwb3NpdGlvbk9wdGlvbnM6IHtcbiAgICAgICAgZW5hYmxlSGlnaEFjY3VyYWN5OiBmYWxzZSxcbiAgICAgICAgbWF4aW11bUFnZTogMCxcbiAgICAgICAgdGltZW91dDogNjAwMCAvKiA2IHNlYyAqL1xuICAgIH0sXG4gICAgZml0Qm91bmRzT3B0aW9uczoge1xuICAgICAgICBtYXhab29tOiAxNVxuICAgIH0sXG4gICAgdHJhY2tVc2VyTG9jYXRpb246IGZhbHNlLFxuICAgIHNob3dBY2N1cmFjeUNpcmNsZTogdHJ1ZSxcbiAgICBzaG93VXNlckxvY2F0aW9uOiB0cnVlLFxuICAgIHNob3dVc2VySGVhZGluZzogZmFsc2Vcbn07XG5cbi8qKlxuICogQSBgR2VvbG9jYXRlQ29udHJvbGAgY29udHJvbCBwcm92aWRlcyBhIGJ1dHRvbiB0aGF0IHVzZXMgdGhlIGJyb3dzZXIncyBnZW9sb2NhdGlvblxuICogQVBJIHRvIGxvY2F0ZSB0aGUgdXNlciBvbiB0aGUgbWFwLlxuICogQWRkIHRoaXMgY29udHJvbCB0byBhIG1hcCB1c2luZyB7QGxpbmsgTWFwI2FkZENvbnRyb2x9LlxuICpcbiAqIE5vdCBhbGwgYnJvd3NlcnMgc3VwcG9ydCBnZW9sb2NhdGlvbixcbiAqIGFuZCBzb21lIHVzZXJzIG1heSBkaXNhYmxlIHRoZSBmZWF0dXJlLiBHZW9sb2NhdGlvbiBzdXBwb3J0IGZvciBtb2Rlcm5cbiAqIGJyb3dzZXJzIGluY2x1ZGluZyBDaHJvbWUgcmVxdWlyZXMgc2l0ZXMgdG8gYmUgc2VydmVkIG92ZXIgSFRUUFMuIElmXG4gKiBnZW9sb2NhdGlvbiBzdXBwb3J0IGlzIG5vdCBhdmFpbGFibGUsIHRoZSBHZW9sb2NhdGVDb250cm9sIHdpbGwgc2hvd1xuICogYXMgZGlzYWJsZWQuXG4gKlxuICogVGhlIFt6b29tIGxldmVsXShodHRwczovL2RvY3MubWFwYm94LmNvbS9oZWxwL2dsb3NzYXJ5L3pvb20tbGV2ZWwvKSBhcHBsaWVkIGRlcGVuZHMgb24gdGhlIGFjY3VyYWN5IG9mIHRoZSBnZW9sb2NhdGlvbiBwcm92aWRlZCBieSB0aGUgZGV2aWNlLlxuICpcbiAqIFRoZSBHZW9sb2NhdGVDb250cm9sIGhhcyB0d28gbW9kZXMuIElmIGB0cmFja1VzZXJMb2NhdGlvbmAgaXMgYGZhbHNlYCAoZGVmYXVsdCkgdGhlIGNvbnRyb2wgYWN0cyBhcyBhIGJ1dHRvbiwgd2hpY2ggd2hlbiBwcmVzc2VkIHdpbGwgc2V0IHRoZSBtYXAncyBjYW1lcmEgdG8gdGFyZ2V0IHRoZSB1c2VyIGxvY2F0aW9uLiBJZiB0aGUgdXNlciBtb3ZlcywgdGhlIG1hcCB3b24ndCB1cGRhdGUuIFRoaXMgaXMgbW9zdCBzdWl0ZWQgZm9yIHRoZSBkZXNrdG9wLiBJZiBgdHJhY2tVc2VyTG9jYXRpb25gIGlzIGB0cnVlYCB0aGUgY29udHJvbCBhY3RzIGFzIGEgdG9nZ2xlIGJ1dHRvbiB0aGF0IHdoZW4gYWN0aXZlIHRoZSB1c2VyJ3MgbG9jYXRpb24gaXMgYWN0aXZlbHkgbW9uaXRvcmVkIGZvciBjaGFuZ2VzLiBJbiB0aGlzIG1vZGUgdGhlIEdlb2xvY2F0ZUNvbnRyb2wgaGFzIHRocmVlIGludGVyYWN0aW9uIHN0YXRlczpcbiAqICogYWN0aXZlIC0gVGhlIG1hcCdzIGNhbWVyYSBhdXRvbWF0aWNhbGx5IHVwZGF0ZXMgYXMgdGhlIHVzZXIncyBsb2NhdGlvbiBjaGFuZ2VzLCBrZWVwaW5nIHRoZSBsb2NhdGlvbiBkb3QgaW4gdGhlIGNlbnRlci4gVGhpcyBpcyB0aGUgaW5pdGlhbCBzdGF0ZSwgYW5kIHRoZSBzdGF0ZSB1cG9uIGNsaWNraW5nIHRoZSBgR2VvbG9jYXRlQ29udHJvbGAgYnV0dG9uLlxuICogKiBwYXNzaXZlIC0gVGhlIHVzZXIncyBsb2NhdGlvbiBkb3QgYXV0b21hdGljYWxseSB1cGRhdGVzLCBidXQgdGhlIG1hcCdzIGNhbWVyYSBkb2VzIG5vdC4gT2NjdXJzIHVwb24gdGhlIHVzZXIgaW5pdGlhdGluZyBhIG1hcCBtb3ZlbWVudC5cbiAqICogZGlzYWJsZWQgLSBPY2N1cnMgaWYgZ2VvbG9jYXRpb24gaXMgbm90IGF2YWlsYWJsZSwgZGlzYWJsZWQsIG9yIGRlbmllZC5cbiAqXG4gKiBUaGVzZSBpbnRlcmFjdGlvbiBzdGF0ZXMgY2FuJ3QgYmUgY29udHJvbGxlZCBwcm9ncmFtbWF0aWNhbGx5LiBJbnN0ZWFkLCB0aGV5IGFyZSBzZXQgYmFzZWQgb24gdXNlciBpbnRlcmFjdGlvbnMuXG4gKlxuICogQGltcGxlbWVudHMge0lDb250cm9sfVxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLnBvc2l0aW9uT3B0aW9ucz17ZW5hYmxlSGlnaEFjY3VyYWN5OiBmYWxzZSwgdGltZW91dDogNjAwMH1dIEEgR2VvbG9jYXRpb24gQVBJIFtQb3NpdGlvbk9wdGlvbnNdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9Qb3NpdGlvbk9wdGlvbnMpIG9iamVjdC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5maXRCb3VuZHNPcHRpb25zPXttYXhab29tOiAxNX1dIEEge0BsaW5rIE1hcCNmaXRCb3VuZHN9IG9wdGlvbnMgb2JqZWN0IHRvIHVzZSB3aGVuIHRoZSBtYXAgaXMgcGFubmVkIGFuZCB6b29tZWQgdG8gdGhlIHVzZXIncyBsb2NhdGlvbi4gVGhlIGRlZmF1bHQgaXMgdG8gdXNlIGEgYG1heFpvb21gIG9mIDE1IHRvIGxpbWl0IGhvdyBmYXIgdGhlIG1hcCB3aWxsIHpvb20gaW4gZm9yIHZlcnkgYWNjdXJhdGUgbG9jYXRpb25zLlxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLnRyYWNrVXNlckxvY2F0aW9uPWZhbHNlXSBJZiBgdHJ1ZWAgdGhlIEdlb2xvY2F0ZUNvbnRyb2wgYmVjb21lcyBhIHRvZ2dsZSBidXR0b24gYW5kIHdoZW4gYWN0aXZlIHRoZSBtYXAgd2lsbCByZWNlaXZlIHVwZGF0ZXMgdG8gdGhlIHVzZXIncyBsb2NhdGlvbiBhcyBpdCBjaGFuZ2VzLlxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLnNob3dBY2N1cmFjeUNpcmNsZT10cnVlXSBCeSBkZWZhdWx0LCBpZiBgc2hvd1VzZXJMb2NhdGlvbmAgaXMgYHRydWVgLCBhIHRyYW5zcGFyZW50IGNpcmNsZSB3aWxsIGJlIGRyYXduIGFyb3VuZCB0aGUgdXNlciBsb2NhdGlvbiBpbmRpY2F0aW5nIHRoZSBhY2N1cmFjeSAoOTUlIGNvbmZpZGVuY2UgbGV2ZWwpIG9mIHRoZSB1c2VyJ3MgbG9jYXRpb24uIFNldCB0byBgZmFsc2VgIHRvIGRpc2FibGUuIEFsd2F5cyBkaXNhYmxlZCB3aGVuIGBzaG93VXNlckxvY2F0aW9uYCBpcyBgZmFsc2VgLlxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLnNob3dVc2VyTG9jYXRpb249dHJ1ZV0gQnkgZGVmYXVsdCBhIGRvdCB3aWxsIGJlIHNob3duIG9uIHRoZSBtYXAgYXQgdGhlIHVzZXIncyBsb2NhdGlvbi4gU2V0IHRvIGBmYWxzZWAgdG8gZGlzYWJsZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5zaG93VXNlckhlYWRpbmc9ZmFsc2VdIElmIGB0cnVlYCBhbiBhcnJvdyB3aWxsIGJlIGRyYXduIG5leHQgdG8gdGhlIHVzZXIgbG9jYXRpb24gZG90IGluZGljYXRpbmcgdGhlIGRldmljZSdzIGhlYWRpbmcuIFRoaXMgb25seSBoYXMgYWZmZWN0IHdoZW4gYHRyYWNrVXNlckxvY2F0aW9uYCBpcyBgdHJ1ZWAuXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMuZ2VvbG9jYXRpb249d2luZG93Lm5hdmlnYXRvci5nZW9sb2NhdGlvbl0gYHdpbmRvdy5uYXZpZ2F0b3IuZ2VvbG9jYXRpb25gIGJ5IGRlZmF1bHQ7IHlvdSBjYW4gcHJvdmlkZSBhbiBvYmplY3Qgd2l0aCB0aGUgc2FtZSBzaGFwZSB0byBjdXN0b21pemUgZ2VvbG9jYXRpb24gaGFuZGxpbmcuXG4gKlxuICogQGV4YW1wbGVcbiAqIG1hcC5hZGRDb250cm9sKG5ldyBtYXBib3hnbC5HZW9sb2NhdGVDb250cm9sKHtcbiAqICAgICBwb3NpdGlvbk9wdGlvbnM6IHtcbiAqICAgICAgICAgZW5hYmxlSGlnaEFjY3VyYWN5OiB0cnVlXG4gKiAgICAgfSxcbiAqICAgICB0cmFja1VzZXJMb2NhdGlvbjogdHJ1ZSxcbiAqICAgICBzaG93VXNlckhlYWRpbmc6IHRydWVcbiAqIH0pKTtcbiAqIEBzZWUgW0V4YW1wbGU6IExvY2F0ZSB0aGUgdXNlcl0oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9sb2NhdGUtdXNlci8pXG4gKi9cbmNsYXNzIEdlb2xvY2F0ZUNvbnRyb2wgZXh0ZW5kcyBFdmVudGVkIHtcbiAgICBfbWFwOiBNYXA7XG4gICAgb3B0aW9uczogT3B0aW9ucztcbiAgICBfY29udGFpbmVyOiBIVE1MRWxlbWVudDtcbiAgICBfZG90RWxlbWVudDogSFRNTEVsZW1lbnQ7XG4gICAgX2NpcmNsZUVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuICAgIF9nZW9sb2NhdGVCdXR0b246IEhUTUxCdXR0b25FbGVtZW50O1xuICAgIF9nZW9sb2NhdGlvbldhdGNoSUQ6IG51bWJlcjtcbiAgICBfdGltZW91dElkOiA/VGltZW91dElEO1xuICAgIF93YXRjaFN0YXRlOiAnT0ZGJyB8ICdBQ1RJVkVfTE9DSycgfCAnV0FJVElOR19BQ1RJVkUnIHwgJ0FDVElWRV9FUlJPUicgfCAnQkFDS0dST1VORCcgfCAnQkFDS0dST1VORF9FUlJPUic7XG4gICAgX2xhc3RLbm93blBvc2l0aW9uOiBhbnk7XG4gICAgX3VzZXJMb2NhdGlvbkRvdE1hcmtlcjogTWFya2VyO1xuICAgIF9hY2N1cmFjeUNpcmNsZU1hcmtlcjogTWFya2VyO1xuICAgIF9hY2N1cmFjeTogbnVtYmVyO1xuICAgIF9zZXR1cDogYm9vbGVhbjsgLy8gc2V0IHRvIHRydWUgb25jZSB0aGUgY29udHJvbCBoYXMgYmVlbiBzZXR1cFxuICAgIF9oZWFkaW5nOiA/bnVtYmVyO1xuICAgIF91cGRhdGVNYXJrZXJSb3RhdGlvblRocm90dGxlZDogRnVuY3Rpb247XG5cbiAgICBfbnVtYmVyT2ZXYXRjaGVzOiBudW1iZXI7XG4gICAgX25vVGltZW91dDogYm9vbGVhbjtcbiAgICBfc3VwcG9ydHNHZW9sb2NhdGlvbjogYm9vbGVhbjtcblxuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnM6ICRTaGFwZTxPcHRpb25zPikge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICBjb25zdCBnZW9sb2NhdGlvbiA9IHdpbmRvdy5uYXZpZ2F0b3IuZ2VvbG9jYXRpb247XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IGV4dGVuZCh7Z2VvbG9jYXRpb259LCBkZWZhdWx0T3B0aW9ucywgb3B0aW9ucyk7XG5cbiAgICAgICAgYmluZEFsbChbXG4gICAgICAgICAgICAnX29uU3VjY2VzcycsXG4gICAgICAgICAgICAnX29uRXJyb3InLFxuICAgICAgICAgICAgJ19vblpvb20nLFxuICAgICAgICAgICAgJ19maW5pc2gnLFxuICAgICAgICAgICAgJ19zZXR1cFVJJyxcbiAgICAgICAgICAgICdfdXBkYXRlQ2FtZXJhJyxcbiAgICAgICAgICAgICdfdXBkYXRlTWFya2VyJyxcbiAgICAgICAgICAgICdfdXBkYXRlTWFya2VyUm90YXRpb24nLFxuICAgICAgICAgICAgJ19vbkRldmljZU9yaWVudGF0aW9uJ1xuICAgICAgICBdLCB0aGlzKTtcblxuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIHRoaXMuX3VwZGF0ZU1hcmtlclJvdGF0aW9uVGhyb3R0bGVkID0gdGhyb3R0bGUodGhpcy5fdXBkYXRlTWFya2VyUm90YXRpb24sIDIwKTtcbiAgICAgICAgdGhpcy5fbnVtYmVyT2ZXYXRjaGVzID0gMDtcbiAgICB9XG5cbiAgICBvbkFkZChtYXA6IE1hcCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgdGhpcy5fbWFwID0gbWFwO1xuICAgICAgICB0aGlzLl9jb250YWluZXIgPSBET00uY3JlYXRlKCdkaXYnLCBgbWFwYm94Z2wtY3RybCBtYXBib3hnbC1jdHJsLWdyb3VwYCk7XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgdGhpcy5fY2hlY2tHZW9sb2NhdGlvblN1cHBvcnQodGhpcy5fc2V0dXBVSSk7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250YWluZXI7XG4gICAgfVxuXG4gICAgb25SZW1vdmUoKSB7XG4gICAgICAgIC8vIGNsZWFyIHRoZSBnZW9sb2NhdGlvbiB3YXRjaCBpZiBleGlzdHNcbiAgICAgICAgaWYgKHRoaXMuX2dlb2xvY2F0aW9uV2F0Y2hJRCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLm9wdGlvbnMuZ2VvbG9jYXRpb24uY2xlYXJXYXRjaCh0aGlzLl9nZW9sb2NhdGlvbldhdGNoSUQpO1xuICAgICAgICAgICAgdGhpcy5fZ2VvbG9jYXRpb25XYXRjaElEID0gKHVuZGVmaW5lZDogYW55KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNsZWFyIHRoZSBtYXJrZXJzIGZyb20gdGhlIG1hcFxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnNob3dVc2VyTG9jYXRpb24gJiYgdGhpcy5fdXNlckxvY2F0aW9uRG90TWFya2VyKSB7XG4gICAgICAgICAgICB0aGlzLl91c2VyTG9jYXRpb25Eb3RNYXJrZXIucmVtb3ZlKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zaG93QWNjdXJhY3lDaXJjbGUgJiYgdGhpcy5fYWNjdXJhY3lDaXJjbGVNYXJrZXIpIHtcbiAgICAgICAgICAgIHRoaXMuX2FjY3VyYWN5Q2lyY2xlTWFya2VyLnJlbW92ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fY29udGFpbmVyLnJlbW92ZSgpO1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIHRoaXMuX21hcC5vZmYoJ3pvb20nLCB0aGlzLl9vblpvb20pO1xuICAgICAgICB0aGlzLl9tYXAgPSAodW5kZWZpbmVkOiBhbnkpO1xuICAgICAgICB0aGlzLl9udW1iZXJPZldhdGNoZXMgPSAwO1xuICAgICAgICB0aGlzLl9ub1RpbWVvdXQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBfY2hlY2tHZW9sb2NhdGlvblN1cHBvcnQoY2FsbGJhY2s6IGJvb2xlYW4gPT4gdm9pZCkge1xuICAgICAgICBjb25zdCB1cGRhdGVTdXBwb3J0ID0gKHN1cHBvcnRlZDogYm9vbGVhbiA9ICEhdGhpcy5vcHRpb25zLmdlb2xvY2F0aW9uKSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9zdXBwb3J0c0dlb2xvY2F0aW9uID0gc3VwcG9ydGVkO1xuICAgICAgICAgICAgY2FsbGJhY2soc3VwcG9ydGVkKTtcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAodGhpcy5fc3VwcG9ydHNHZW9sb2NhdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBjYWxsYmFjayh0aGlzLl9zdXBwb3J0c0dlb2xvY2F0aW9uKTtcblxuICAgICAgICB9IGVsc2UgaWYgKHdpbmRvdy5uYXZpZ2F0b3IucGVybWlzc2lvbnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgLy8gbmF2aWdhdG9yLnBlcm1pc3Npb25zIGhhcyBpbmNvbXBsZXRlIGJyb3dzZXIgc3VwcG9ydCBodHRwOi8vY2FuaXVzZS5jb20vI2ZlYXQ9cGVybWlzc2lvbnMtYXBpXG4gICAgICAgICAgICAvLyBUZXN0IGZvciB0aGUgY2FzZSB3aGVyZSBhIGJyb3dzZXIgZGlzYWJsZXMgR2VvbG9jYXRpb24gYmVjYXVzZSBvZiBhbiBpbnNlY3VyZSBvcmlnaW47XG4gICAgICAgICAgICAvLyBpbiBzb21lIGVudmlyb25tZW50cyBsaWtlIGlPUzE2IFdlYlZpZXcsIHBlcm1pc3Npb25zIHJlamVjdCBxdWVyaWVzIGJ1dCBzdGlsbCBzdXBwb3J0IGdlb2xvY2F0aW9uXG4gICAgICAgICAgICB3aW5kb3cubmF2aWdhdG9yLnBlcm1pc3Npb25zLnF1ZXJ5KHtuYW1lOiAnZ2VvbG9jYXRpb24nfSlcbiAgICAgICAgICAgICAgICAudGhlbihwID0+IHVwZGF0ZVN1cHBvcnQocC5zdGF0ZSAhPT0gJ2RlbmllZCcpKVxuICAgICAgICAgICAgICAgIC5jYXRjaCgoKSA9PiB1cGRhdGVTdXBwb3J0KCkpO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB1cGRhdGVTdXBwb3J0KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVjayBpZiB0aGUgR2VvbG9jYXRpb24gQVBJIFBvc2l0aW9uIGlzIG91dHNpZGUgdGhlIG1hcCdzIG1heGJvdW5kcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7UG9zaXRpb259IHBvc2l0aW9uIHRoZSBHZW9sb2NhdGlvbiBBUEkgUG9zaXRpb25cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgcG9zaXRpb24gaXMgb3V0c2lkZSB0aGUgbWFwJ3MgbWF4Ym91bmRzLCBvdGhlcndpc2UgcmV0dXJucyBgZmFsc2VgLlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgX2lzT3V0T2ZNYXBNYXhCb3VuZHMocG9zaXRpb246IFBvc2l0aW9uKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IGJvdW5kcyA9IHRoaXMuX21hcC5nZXRNYXhCb3VuZHMoKTtcbiAgICAgICAgY29uc3QgY29vcmRpbmF0ZXMgPSBwb3NpdGlvbi5jb29yZHM7XG5cbiAgICAgICAgcmV0dXJuICEhYm91bmRzICYmIChcbiAgICAgICAgICAgIGNvb3JkaW5hdGVzLmxvbmdpdHVkZSA8IGJvdW5kcy5nZXRXZXN0KCkgfHxcbiAgICAgICAgICAgIGNvb3JkaW5hdGVzLmxvbmdpdHVkZSA+IGJvdW5kcy5nZXRFYXN0KCkgfHxcbiAgICAgICAgICAgIGNvb3JkaW5hdGVzLmxhdGl0dWRlIDwgYm91bmRzLmdldFNvdXRoKCkgfHxcbiAgICAgICAgICAgIGNvb3JkaW5hdGVzLmxhdGl0dWRlID4gYm91bmRzLmdldE5vcnRoKClcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBfc2V0RXJyb3JTdGF0ZSgpIHtcbiAgICAgICAgc3dpdGNoICh0aGlzLl93YXRjaFN0YXRlKSB7XG4gICAgICAgIGNhc2UgJ1dBSVRJTkdfQUNUSVZFJzpcbiAgICAgICAgICAgIHRoaXMuX3dhdGNoU3RhdGUgPSAnQUNUSVZFX0VSUk9SJztcbiAgICAgICAgICAgIHRoaXMuX2dlb2xvY2F0ZUJ1dHRvbi5jbGFzc0xpc3QucmVtb3ZlKCdtYXBib3hnbC1jdHJsLWdlb2xvY2F0ZS1hY3RpdmUnKTtcbiAgICAgICAgICAgIHRoaXMuX2dlb2xvY2F0ZUJ1dHRvbi5jbGFzc0xpc3QuYWRkKCdtYXBib3hnbC1jdHJsLWdlb2xvY2F0ZS1hY3RpdmUtZXJyb3InKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdBQ1RJVkVfTE9DSyc6XG4gICAgICAgICAgICB0aGlzLl93YXRjaFN0YXRlID0gJ0FDVElWRV9FUlJPUic7XG4gICAgICAgICAgICB0aGlzLl9nZW9sb2NhdGVCdXR0b24uY2xhc3NMaXN0LnJlbW92ZSgnbWFwYm94Z2wtY3RybC1nZW9sb2NhdGUtYWN0aXZlJyk7XG4gICAgICAgICAgICB0aGlzLl9nZW9sb2NhdGVCdXR0b24uY2xhc3NMaXN0LmFkZCgnbWFwYm94Z2wtY3RybC1nZW9sb2NhdGUtYWN0aXZlLWVycm9yJyk7XG4gICAgICAgICAgICB0aGlzLl9nZW9sb2NhdGVCdXR0b24uY2xhc3NMaXN0LmFkZCgnbWFwYm94Z2wtY3RybC1nZW9sb2NhdGUtd2FpdGluZycpO1xuICAgICAgICAgICAgLy8gdHVybiBtYXJrZXIgZ3JleVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0JBQ0tHUk9VTkQnOlxuICAgICAgICAgICAgdGhpcy5fd2F0Y2hTdGF0ZSA9ICdCQUNLR1JPVU5EX0VSUk9SJztcbiAgICAgICAgICAgIHRoaXMuX2dlb2xvY2F0ZUJ1dHRvbi5jbGFzc0xpc3QucmVtb3ZlKCdtYXBib3hnbC1jdHJsLWdlb2xvY2F0ZS1iYWNrZ3JvdW5kJyk7XG4gICAgICAgICAgICB0aGlzLl9nZW9sb2NhdGVCdXR0b24uY2xhc3NMaXN0LmFkZCgnbWFwYm94Z2wtY3RybC1nZW9sb2NhdGUtYmFja2dyb3VuZC1lcnJvcicpO1xuICAgICAgICAgICAgdGhpcy5fZ2VvbG9jYXRlQnV0dG9uLmNsYXNzTGlzdC5hZGQoJ21hcGJveGdsLWN0cmwtZ2VvbG9jYXRlLXdhaXRpbmcnKTtcbiAgICAgICAgICAgIC8vIHR1cm4gbWFya2VyIGdyZXlcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdBQ1RJVkVfRVJST1InOlxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBhc3NlcnQoZmFsc2UsIGBVbmV4cGVjdGVkIHdhdGNoU3RhdGUgJHt0aGlzLl93YXRjaFN0YXRlfWApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogV2hlbiB0aGUgR2VvbG9jYXRpb24gQVBJIHJldHVybnMgYSBuZXcgbG9jYXRpb24sIHVwZGF0ZSB0aGUgR2VvbG9jYXRlQ29udHJvbC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7UG9zaXRpb259IHBvc2l0aW9uIHRoZSBHZW9sb2NhdGlvbiBBUEkgUG9zaXRpb25cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF9vblN1Y2Nlc3MocG9zaXRpb246IFBvc2l0aW9uKSB7XG4gICAgICAgIGlmICghdGhpcy5fbWFwKSB7XG4gICAgICAgICAgICAvLyBjb250cm9sIGhhcyBzaW5jZSBiZWVuIHJlbW92ZWRcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLl9pc091dE9mTWFwTWF4Qm91bmRzKHBvc2l0aW9uKSkge1xuICAgICAgICAgICAgdGhpcy5fc2V0RXJyb3JTdGF0ZSgpO1xuXG4gICAgICAgICAgICB0aGlzLmZpcmUobmV3IEV2ZW50KCdvdXRvZm1heGJvdW5kcycsIHBvc2l0aW9uKSk7XG4gICAgICAgICAgICB0aGlzLl91cGRhdGVNYXJrZXIoKTtcbiAgICAgICAgICAgIHRoaXMuX2ZpbmlzaCgpO1xuXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnRyYWNrVXNlckxvY2F0aW9uKSB7XG4gICAgICAgICAgICAvLyBrZWVwIGEgcmVjb3JkIG9mIHRoZSBwb3NpdGlvbiBzbyB0aGF0IGlmIHRoZSBzdGF0ZSBpcyBCQUNLR1JPVU5EIGFuZCB0aGUgdXNlclxuICAgICAgICAgICAgLy8gY2xpY2tzIHRoZSBidXR0b24sIHdlIGNhbiBtb3ZlIHRvIEFDVElWRV9MT0NLIGltbWVkaWF0ZWx5IHdpdGhvdXQgd2FpdGluZyBmb3JcbiAgICAgICAgICAgIC8vIHdhdGNoUG9zaXRpb24gdG8gdHJpZ2dlciBfb25TdWNjZXNzXG4gICAgICAgICAgICB0aGlzLl9sYXN0S25vd25Qb3NpdGlvbiA9IHBvc2l0aW9uO1xuXG4gICAgICAgICAgICBzd2l0Y2ggKHRoaXMuX3dhdGNoU3RhdGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ1dBSVRJTkdfQUNUSVZFJzpcbiAgICAgICAgICAgIGNhc2UgJ0FDVElWRV9MT0NLJzpcbiAgICAgICAgICAgIGNhc2UgJ0FDVElWRV9FUlJPUic6XG4gICAgICAgICAgICAgICAgdGhpcy5fd2F0Y2hTdGF0ZSA9ICdBQ1RJVkVfTE9DSyc7XG4gICAgICAgICAgICAgICAgdGhpcy5fZ2VvbG9jYXRlQnV0dG9uLmNsYXNzTGlzdC5yZW1vdmUoJ21hcGJveGdsLWN0cmwtZ2VvbG9jYXRlLXdhaXRpbmcnKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9nZW9sb2NhdGVCdXR0b24uY2xhc3NMaXN0LnJlbW92ZSgnbWFwYm94Z2wtY3RybC1nZW9sb2NhdGUtYWN0aXZlLWVycm9yJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fZ2VvbG9jYXRlQnV0dG9uLmNsYXNzTGlzdC5hZGQoJ21hcGJveGdsLWN0cmwtZ2VvbG9jYXRlLWFjdGl2ZScpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnQkFDS0dST1VORCc6XG4gICAgICAgICAgICBjYXNlICdCQUNLR1JPVU5EX0VSUk9SJzpcbiAgICAgICAgICAgICAgICB0aGlzLl93YXRjaFN0YXRlID0gJ0JBQ0tHUk9VTkQnO1xuICAgICAgICAgICAgICAgIHRoaXMuX2dlb2xvY2F0ZUJ1dHRvbi5jbGFzc0xpc3QucmVtb3ZlKCdtYXBib3hnbC1jdHJsLWdlb2xvY2F0ZS13YWl0aW5nJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fZ2VvbG9jYXRlQnV0dG9uLmNsYXNzTGlzdC5yZW1vdmUoJ21hcGJveGdsLWN0cmwtZ2VvbG9jYXRlLWJhY2tncm91bmQtZXJyb3InKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9nZW9sb2NhdGVCdXR0b24uY2xhc3NMaXN0LmFkZCgnbWFwYm94Z2wtY3RybC1nZW9sb2NhdGUtYmFja2dyb3VuZCcpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBhc3NlcnQoZmFsc2UsIGBVbmV4cGVjdGVkIHdhdGNoU3RhdGUgJHt0aGlzLl93YXRjaFN0YXRlfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gaWYgc2hvd1VzZXJMb2NhdGlvbiBhbmQgdGhlIHdhdGNoIHN0YXRlIGlzbid0IG9mZiB0aGVuIHVwZGF0ZSB0aGUgbWFya2VyIGxvY2F0aW9uXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc2hvd1VzZXJMb2NhdGlvbiAmJiB0aGlzLl93YXRjaFN0YXRlICE9PSAnT0ZGJykge1xuICAgICAgICAgICAgdGhpcy5fdXBkYXRlTWFya2VyKHBvc2l0aW9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGlmIGluIG5vcm1hbCBtb2RlIChub3Qgd2F0Y2ggbW9kZSksIG9yIGlmIGluIHdhdGNoIG1vZGUgYW5kIHRoZSBzdGF0ZSBpcyBhY3RpdmUgd2F0Y2hcbiAgICAgICAgLy8gdGhlbiB1cGRhdGUgdGhlIGNhbWVyYVxuICAgICAgICBpZiAoIXRoaXMub3B0aW9ucy50cmFja1VzZXJMb2NhdGlvbiB8fCB0aGlzLl93YXRjaFN0YXRlID09PSAnQUNUSVZFX0xPQ0snKSB7XG4gICAgICAgICAgICB0aGlzLl91cGRhdGVDYW1lcmEocG9zaXRpb24pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zaG93VXNlckxvY2F0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLl9kb3RFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ21hcGJveGdsLXVzZXItbG9jYXRpb24tZG90LXN0YWxlJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmZpcmUobmV3IEV2ZW50KCdnZW9sb2NhdGUnLCBwb3NpdGlvbikpO1xuICAgICAgICB0aGlzLl9maW5pc2goKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGhlIGNhbWVyYSBsb2NhdGlvbiB0byBjZW50ZXIgb24gdGhlIGN1cnJlbnQgcG9zaXRpb25cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7UG9zaXRpb259IHBvc2l0aW9uIHRoZSBHZW9sb2NhdGlvbiBBUEkgUG9zaXRpb25cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF91cGRhdGVDYW1lcmEocG9zaXRpb246IFBvc2l0aW9uKSB7XG4gICAgICAgIGNvbnN0IGNlbnRlciA9IG5ldyBMbmdMYXQocG9zaXRpb24uY29vcmRzLmxvbmdpdHVkZSwgcG9zaXRpb24uY29vcmRzLmxhdGl0dWRlKTtcbiAgICAgICAgY29uc3QgcmFkaXVzID0gcG9zaXRpb24uY29vcmRzLmFjY3VyYWN5O1xuICAgICAgICBjb25zdCBiZWFyaW5nID0gdGhpcy5fbWFwLmdldEJlYXJpbmcoKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IGV4dGVuZCh7YmVhcmluZ30sIHRoaXMub3B0aW9ucy5maXRCb3VuZHNPcHRpb25zKTtcblxuICAgICAgICB0aGlzLl9tYXAuZml0Qm91bmRzKGNlbnRlci50b0JvdW5kcyhyYWRpdXMpLCBvcHRpb25zLCB7XG4gICAgICAgICAgICBnZW9sb2NhdGVTb3VyY2U6IHRydWUgLy8gdGFnIHRoaXMgY2FtZXJhIGNoYW5nZSBzbyBpdCB3b24ndCBjYXVzZSB0aGUgY29udHJvbCB0byBjaGFuZ2UgdG8gYmFja2dyb3VuZCBzdGF0ZVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGhlIHVzZXIgbG9jYXRpb24gZG90IE1hcmtlciB0byB0aGUgY3VycmVudCBwb3NpdGlvblxuICAgICAqXG4gICAgICogQHBhcmFtIHtQb3NpdGlvbn0gW3Bvc2l0aW9uXSB0aGUgR2VvbG9jYXRpb24gQVBJIFBvc2l0aW9uXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBfdXBkYXRlTWFya2VyKHBvc2l0aW9uOiA/UG9zaXRpb24pIHtcbiAgICAgICAgaWYgKHBvc2l0aW9uKSB7XG4gICAgICAgICAgICBjb25zdCBjZW50ZXIgPSBuZXcgTG5nTGF0KHBvc2l0aW9uLmNvb3Jkcy5sb25naXR1ZGUsIHBvc2l0aW9uLmNvb3Jkcy5sYXRpdHVkZSk7XG4gICAgICAgICAgICB0aGlzLl9hY2N1cmFjeUNpcmNsZU1hcmtlci5zZXRMbmdMYXQoY2VudGVyKS5hZGRUbyh0aGlzLl9tYXApO1xuICAgICAgICAgICAgdGhpcy5fdXNlckxvY2F0aW9uRG90TWFya2VyLnNldExuZ0xhdChjZW50ZXIpLmFkZFRvKHRoaXMuX21hcCk7XG4gICAgICAgICAgICB0aGlzLl9hY2N1cmFjeSA9IHBvc2l0aW9uLmNvb3Jkcy5hY2N1cmFjeTtcbiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc2hvd1VzZXJMb2NhdGlvbiAmJiB0aGlzLm9wdGlvbnMuc2hvd0FjY3VyYWN5Q2lyY2xlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdXBkYXRlQ2lyY2xlUmFkaXVzKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl91c2VyTG9jYXRpb25Eb3RNYXJrZXIucmVtb3ZlKCk7XG4gICAgICAgICAgICB0aGlzLl9hY2N1cmFjeUNpcmNsZU1hcmtlci5yZW1vdmUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF91cGRhdGVDaXJjbGVSYWRpdXMoKSB7XG4gICAgICAgIGFzc2VydCh0aGlzLl9jaXJjbGVFbGVtZW50KTtcbiAgICAgICAgY29uc3QgbWFwID0gdGhpcy5fbWFwO1xuICAgICAgICBjb25zdCB0ciA9IG1hcC50cmFuc2Zvcm07XG5cbiAgICAgICAgY29uc3QgcGl4ZWxzUGVyTWV0ZXIgPSBtZXJjYXRvclpmcm9tQWx0aXR1ZGUoMS4wLCB0ci5fY2VudGVyLmxhdCkgKiB0ci53b3JsZFNpemU7XG4gICAgICAgIGFzc2VydChwaXhlbHNQZXJNZXRlciAhPT0gMC4wKTtcbiAgICAgICAgY29uc3QgY2lyY2xlRGlhbWV0ZXIgPSBNYXRoLmNlaWwoMi4wICogdGhpcy5fYWNjdXJhY3kgKiBwaXhlbHNQZXJNZXRlcik7XG5cbiAgICAgICAgdGhpcy5fY2lyY2xlRWxlbWVudC5zdHlsZS53aWR0aCA9IGAke2NpcmNsZURpYW1ldGVyfXB4YDtcbiAgICAgICAgdGhpcy5fY2lyY2xlRWxlbWVudC5zdHlsZS5oZWlnaHQgPSBgJHtjaXJjbGVEaWFtZXRlcn1weGA7XG4gICAgfVxuXG4gICAgX29uWm9vbSgpIHtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zaG93VXNlckxvY2F0aW9uICYmIHRoaXMub3B0aW9ucy5zaG93QWNjdXJhY3lDaXJjbGUpIHtcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUNpcmNsZVJhZGl1cygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXBkYXRlIHRoZSB1c2VyIGxvY2F0aW9uIGRvdCBNYXJrZXIgcm90YXRpb24gdG8gdGhlIGN1cnJlbnQgaGVhZGluZ1xuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBfdXBkYXRlTWFya2VyUm90YXRpb24oKSB7XG4gICAgICAgIGlmICh0aGlzLl91c2VyTG9jYXRpb25Eb3RNYXJrZXIgJiYgdHlwZW9mIHRoaXMuX2hlYWRpbmcgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICB0aGlzLl91c2VyTG9jYXRpb25Eb3RNYXJrZXIuc2V0Um90YXRpb24odGhpcy5faGVhZGluZyk7XG4gICAgICAgICAgICB0aGlzLl9kb3RFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ21hcGJveGdsLXVzZXItbG9jYXRpb24tc2hvdy1oZWFkaW5nJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9kb3RFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ21hcGJveGdsLXVzZXItbG9jYXRpb24tc2hvdy1oZWFkaW5nJyk7XG4gICAgICAgICAgICB0aGlzLl91c2VyTG9jYXRpb25Eb3RNYXJrZXIuc2V0Um90YXRpb24oMCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfb25FcnJvcihlcnJvcjogUG9zaXRpb25FcnJvcikge1xuICAgICAgICBpZiAoIXRoaXMuX21hcCkge1xuICAgICAgICAgICAgLy8gY29udHJvbCBoYXMgc2luY2UgYmVlbiByZW1vdmVkXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnRyYWNrVXNlckxvY2F0aW9uKSB7XG4gICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gMSkge1xuICAgICAgICAgICAgICAgIC8vIFBFUk1JU1NJT05fREVOSUVEXG4gICAgICAgICAgICAgICAgdGhpcy5fd2F0Y2hTdGF0ZSA9ICdPRkYnO1xuICAgICAgICAgICAgICAgIHRoaXMuX2dlb2xvY2F0ZUJ1dHRvbi5jbGFzc0xpc3QucmVtb3ZlKCdtYXBib3hnbC1jdHJsLWdlb2xvY2F0ZS13YWl0aW5nJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fZ2VvbG9jYXRlQnV0dG9uLmNsYXNzTGlzdC5yZW1vdmUoJ21hcGJveGdsLWN0cmwtZ2VvbG9jYXRlLWFjdGl2ZScpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2dlb2xvY2F0ZUJ1dHRvbi5jbGFzc0xpc3QucmVtb3ZlKCdtYXBib3hnbC1jdHJsLWdlb2xvY2F0ZS1hY3RpdmUtZXJyb3InKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9nZW9sb2NhdGVCdXR0b24uY2xhc3NMaXN0LnJlbW92ZSgnbWFwYm94Z2wtY3RybC1nZW9sb2NhdGUtYmFja2dyb3VuZCcpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2dlb2xvY2F0ZUJ1dHRvbi5jbGFzc0xpc3QucmVtb3ZlKCdtYXBib3hnbC1jdHJsLWdlb2xvY2F0ZS1iYWNrZ3JvdW5kLWVycm9yJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fZ2VvbG9jYXRlQnV0dG9uLmRpc2FibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjb25zdCB0aXRsZSA9IHRoaXMuX21hcC5fZ2V0VUlTdHJpbmcoJ0dlb2xvY2F0ZUNvbnRyb2wuTG9jYXRpb25Ob3RBdmFpbGFibGUnKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9nZW9sb2NhdGVCdXR0b24uc2V0QXR0cmlidXRlKCdhcmlhLWxhYmVsJywgdGl0bGUpO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9nZW9sb2NhdGVCdXR0b24uZmlyc3RFbGVtZW50Q2hpbGQpIHRoaXMuX2dlb2xvY2F0ZUJ1dHRvbi5maXJzdEVsZW1lbnRDaGlsZC5zZXRBdHRyaWJ1dGUoJ3RpdGxlJywgdGl0bGUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2dlb2xvY2F0aW9uV2F0Y2hJRCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2NsZWFyV2F0Y2goKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yLmNvZGUgPT09IDMgJiYgdGhpcy5fbm9UaW1lb3V0KSB7XG4gICAgICAgICAgICAgICAgLy8gdGhpcyByZXByZXNlbnRzIGEgZm9yY2VkIGVycm9yIHN0YXRlXG4gICAgICAgICAgICAgICAgLy8gdGhpcyB3YXMgdHJpZ2dlcmVkIHRvIGZvcmNlIGltbWVkaWF0ZSBnZW9sb2NhdGlvbiB3aGVuIGEgd2F0Y2ggaXMgYWxyZWFkeSBwcmVzZW50XG4gICAgICAgICAgICAgICAgLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXBib3gvbWFwYm94LWdsLWpzL2lzc3Vlcy84MjE0XG4gICAgICAgICAgICAgICAgLy8gYW5kIGh0dHBzOi8vdzNjLmdpdGh1Yi5pby9nZW9sb2NhdGlvbi1hcGkvI2V4YW1wbGUtNS1mb3JjaW5nLXRoZS11c2VyLWFnZW50LXRvLXJldHVybi1hLWZyZXNoLWNhY2hlZC1wb3NpdGlvblxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2V0RXJyb3JTdGF0ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuX3dhdGNoU3RhdGUgIT09ICdPRkYnICYmIHRoaXMub3B0aW9ucy5zaG93VXNlckxvY2F0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLl9kb3RFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ21hcGJveGdsLXVzZXItbG9jYXRpb24tZG90LXN0YWxlJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmZpcmUobmV3IEV2ZW50KCdlcnJvcicsIGVycm9yKSk7XG5cbiAgICAgICAgdGhpcy5fZmluaXNoKCk7XG4gICAgfVxuXG4gICAgX2ZpbmlzaCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX3RpbWVvdXRJZCkgeyBjbGVhclRpbWVvdXQodGhpcy5fdGltZW91dElkKTsgfVxuICAgICAgICB0aGlzLl90aW1lb3V0SWQgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgX3NldHVwVUkoc3VwcG9ydGVkOiBib29sZWFuKSB7XG4gICAgICAgIGlmICh0aGlzLl9tYXAgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgLy8gVGhpcyBjb250cm9sIHdhcyByZW1vdmVkIGZyb20gdGhlIG1hcCBiZWZvcmUgZ2VvbG9jYXRpb25cbiAgICAgICAgICAgIC8vIHN1cHBvcnQgd2FzIGRldGVybWluZWQuXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fY29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoJ2NvbnRleHRtZW51JywgKGU6IE1vdXNlRXZlbnQpID0+IGUucHJldmVudERlZmF1bHQoKSk7XG4gICAgICAgIHRoaXMuX2dlb2xvY2F0ZUJ1dHRvbiA9IERPTS5jcmVhdGUoJ2J1dHRvbicsIGBtYXBib3hnbC1jdHJsLWdlb2xvY2F0ZWAsIHRoaXMuX2NvbnRhaW5lcik7XG4gICAgICAgIERPTS5jcmVhdGUoJ3NwYW4nLCBgbWFwYm94Z2wtY3RybC1pY29uYCwgdGhpcy5fZ2VvbG9jYXRlQnV0dG9uKS5zZXRBdHRyaWJ1dGUoJ2FyaWEtaGlkZGVuJywgJ3RydWUnKTtcblxuICAgICAgICB0aGlzLl9nZW9sb2NhdGVCdXR0b24udHlwZSA9ICdidXR0b24nO1xuXG4gICAgICAgIGlmIChzdXBwb3J0ZWQgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICB3YXJuT25jZSgnR2VvbG9jYXRpb24gc3VwcG9ydCBpcyBub3QgYXZhaWxhYmxlIHNvIHRoZSBHZW9sb2NhdGVDb250cm9sIHdpbGwgYmUgZGlzYWJsZWQuJyk7XG4gICAgICAgICAgICBjb25zdCB0aXRsZSA9IHRoaXMuX21hcC5fZ2V0VUlTdHJpbmcoJ0dlb2xvY2F0ZUNvbnRyb2wuTG9jYXRpb25Ob3RBdmFpbGFibGUnKTtcbiAgICAgICAgICAgIHRoaXMuX2dlb2xvY2F0ZUJ1dHRvbi5kaXNhYmxlZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLl9nZW9sb2NhdGVCdXR0b24uc2V0QXR0cmlidXRlKCdhcmlhLWxhYmVsJywgdGl0bGUpO1xuICAgICAgICAgICAgaWYgKHRoaXMuX2dlb2xvY2F0ZUJ1dHRvbi5maXJzdEVsZW1lbnRDaGlsZCkgdGhpcy5fZ2VvbG9jYXRlQnV0dG9uLmZpcnN0RWxlbWVudENoaWxkLnNldEF0dHJpYnV0ZSgndGl0bGUnLCB0aXRsZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCB0aXRsZSA9IHRoaXMuX21hcC5fZ2V0VUlTdHJpbmcoJ0dlb2xvY2F0ZUNvbnRyb2wuRmluZE15TG9jYXRpb24nKTtcbiAgICAgICAgICAgIHRoaXMuX2dlb2xvY2F0ZUJ1dHRvbi5zZXRBdHRyaWJ1dGUoJ2FyaWEtbGFiZWwnLCB0aXRsZSk7XG4gICAgICAgICAgICBpZiAodGhpcy5fZ2VvbG9jYXRlQnV0dG9uLmZpcnN0RWxlbWVudENoaWxkKSB0aGlzLl9nZW9sb2NhdGVCdXR0b24uZmlyc3RFbGVtZW50Q2hpbGQuc2V0QXR0cmlidXRlKCd0aXRsZScsIHRpdGxlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMudHJhY2tVc2VyTG9jYXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuX2dlb2xvY2F0ZUJ1dHRvbi5zZXRBdHRyaWJ1dGUoJ2FyaWEtcHJlc3NlZCcsICdmYWxzZScpO1xuICAgICAgICAgICAgdGhpcy5fd2F0Y2hTdGF0ZSA9ICdPRkYnO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gd2hlbiBzaG93VXNlckxvY2F0aW9uIGlzIGVuYWJsZWQsIGtlZXAgdGhlIEdlb2xvY2F0ZSBidXR0b24gZGlzYWJsZWQgdW50aWwgdGhlIGRldmljZSBsb2NhdGlvbiBtYXJrZXIgaXMgc2V0dXAgb24gdGhlIG1hcFxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnNob3dVc2VyTG9jYXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuX2RvdEVsZW1lbnQgPSBET00uY3JlYXRlKCdkaXYnLCAnbWFwYm94Z2wtdXNlci1sb2NhdGlvbicpO1xuICAgICAgICAgICAgdGhpcy5fZG90RWxlbWVudC5hcHBlbmRDaGlsZChET00uY3JlYXRlKCdkaXYnLCAnbWFwYm94Z2wtdXNlci1sb2NhdGlvbi1kb3QnKSk7XG4gICAgICAgICAgICB0aGlzLl9kb3RFbGVtZW50LmFwcGVuZENoaWxkKERPTS5jcmVhdGUoJ2RpdicsICdtYXBib3hnbC11c2VyLWxvY2F0aW9uLWhlYWRpbmcnKSk7XG5cbiAgICAgICAgICAgIHRoaXMuX3VzZXJMb2NhdGlvbkRvdE1hcmtlciA9IG5ldyBNYXJrZXIoe1xuICAgICAgICAgICAgICAgIGVsZW1lbnQ6IHRoaXMuX2RvdEVsZW1lbnQsXG4gICAgICAgICAgICAgICAgcm90YXRpb25BbGlnbm1lbnQ6ICdtYXAnLFxuICAgICAgICAgICAgICAgIHBpdGNoQWxpZ25tZW50OiAnbWFwJ1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHRoaXMuX2NpcmNsZUVsZW1lbnQgPSBET00uY3JlYXRlKCdkaXYnLCAnbWFwYm94Z2wtdXNlci1sb2NhdGlvbi1hY2N1cmFjeS1jaXJjbGUnKTtcbiAgICAgICAgICAgIHRoaXMuX2FjY3VyYWN5Q2lyY2xlTWFya2VyID0gbmV3IE1hcmtlcih7ZWxlbWVudDogdGhpcy5fY2lyY2xlRWxlbWVudCwgcGl0Y2hBbGlnbm1lbnQ6ICdtYXAnfSk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMudHJhY2tVc2VyTG9jYXRpb24pIHRoaXMuX3dhdGNoU3RhdGUgPSAnT0ZGJztcblxuICAgICAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICAgICAgdGhpcy5fbWFwLm9uKCd6b29tJywgdGhpcy5fb25ab29tKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgdGhpcy5fZ2VvbG9jYXRlQnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy50cmlnZ2VyLmJpbmQodGhpcykpO1xuXG4gICAgICAgIHRoaXMuX3NldHVwID0gdHJ1ZTtcblxuICAgICAgICAvLyB3aGVuIHRoZSBjYW1lcmEgaXMgY2hhbmdlZCAoYW5kIGl0J3Mgbm90IGFzIGEgcmVzdWx0IG9mIHRoZSBHZW9sb2NhdGlvbiBDb250cm9sKSBjaGFuZ2VcbiAgICAgICAgLy8gdGhlIHdhdGNoIG1vZGUgdG8gYmFja2dyb3VuZCB3YXRjaCwgc28gdGhhdCB0aGUgbWFya2VyIGlzIHVwZGF0ZWQgYnV0IG5vdCB0aGUgY2FtZXJhLlxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnRyYWNrVXNlckxvY2F0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLl9tYXAub24oJ21vdmVzdGFydCcsIChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZyb21SZXNpemUgPSBldmVudC5vcmlnaW5hbEV2ZW50ICYmIGV2ZW50Lm9yaWdpbmFsRXZlbnQudHlwZSA9PT0gJ3Jlc2l6ZSc7XG4gICAgICAgICAgICAgICAgaWYgKCFldmVudC5nZW9sb2NhdGVTb3VyY2UgJiYgdGhpcy5fd2F0Y2hTdGF0ZSA9PT0gJ0FDVElWRV9MT0NLJyAmJiAhZnJvbVJlc2l6ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl93YXRjaFN0YXRlID0gJ0JBQ0tHUk9VTkQnO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9nZW9sb2NhdGVCdXR0b24uY2xhc3NMaXN0LmFkZCgnbWFwYm94Z2wtY3RybC1nZW9sb2NhdGUtYmFja2dyb3VuZCcpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9nZW9sb2NhdGVCdXR0b24uY2xhc3NMaXN0LnJlbW92ZSgnbWFwYm94Z2wtY3RybC1nZW9sb2NhdGUtYWN0aXZlJyk7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgndHJhY2t1c2VybG9jYXRpb25lbmQnKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAqIFByb2dyYW1tYXRpY2FsbHkgcmVxdWVzdCBhbmQgbW92ZSB0aGUgbWFwIHRvIHRoZSB1c2VyJ3MgbG9jYXRpb24uXG4gICAgKlxuICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYGZhbHNlYCBpZiBjYWxsZWQgYmVmb3JlIGNvbnRyb2wgd2FzIGFkZGVkIHRvIGEgbWFwLCBvdGhlcndpc2UgcmV0dXJucyBgdHJ1ZWAuXG4gICAgKiBDYWxsZWQgb24gYSBkZXZpY2VvcmllbnRhdGlvbiBldmVudC5cbiAgICAqXG4gICAgKiBAcGFyYW0gZGV2aWNlT3JpZW50YXRpb25FdmVudCB7RGV2aWNlT3JpZW50YXRpb25FdmVudH1cbiAgICAqIEBwcml2YXRlXG4gICAgKiBAZXhhbXBsZVxuICAgICogLy8gSW5pdGlhbGl6ZSB0aGUgR2VvbG9jYXRlQ29udHJvbC5cbiAgICAqIHZhciBnZW9sb2NhdGUgPSBuZXcgbWFwYm94Z2wuR2VvbG9jYXRlQ29udHJvbCh7XG4gICAgKiAgcG9zaXRpb25PcHRpb25zOiB7XG4gICAgKiAgICBlbmFibGVIaWdoQWNjdXJhY3k6IHRydWVcbiAgICAqICB9LFxuICAgICogIHRyYWNrVXNlckxvY2F0aW9uOiB0cnVlXG4gICAgKiB9KTtcbiAgICAqIC8vIEFkZCB0aGUgY29udHJvbCB0byB0aGUgbWFwLlxuICAgICogbWFwLmFkZENvbnRyb2woZ2VvbG9jYXRlKTtcbiAgICAqIG1hcC5vbignbG9hZCcsIGZ1bmN0aW9uKCkge1xuICAgICogICBnZW9sb2NhdGUudHJpZ2dlcigpO1xuICAgICogfSk7XG4gICAgKi9cbiAgICBfb25EZXZpY2VPcmllbnRhdGlvbihkZXZpY2VPcmllbnRhdGlvbkV2ZW50OiBEZXZpY2VPcmllbnRhdGlvbkV2ZW50KSB7XG4gICAgICAgIC8vIGFic29sdXRlIGlzIHRydWUgaWYgdGhlIG9yaWVudGF0aW9uIGRhdGEgaXMgcHJvdmlkZWQgYXMgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgRWFydGgncyBjb29yZGluYXRlIGZyYW1lIGFuZCB0aGUgZGV2aWNlJ3MgY29vcmRpbmF0ZSBmcmFtZSwgb3IgZmFsc2UgaWYgdGhlIG9yaWVudGF0aW9uIGRhdGEgaXMgYmVpbmcgcHJvdmlkZWQgaW4gcmVmZXJlbmNlIHRvIHNvbWUgYXJiaXRyYXJ5LCBkZXZpY2UtZGV0ZXJtaW5lZCBjb29yZGluYXRlIGZyYW1lLlxuICAgICAgICBpZiAodGhpcy5fdXNlckxvY2F0aW9uRG90TWFya2VyKSB7XG4gICAgICAgICAgICBpZiAoZGV2aWNlT3JpZW50YXRpb25FdmVudC53ZWJraXRDb21wYXNzSGVhZGluZykge1xuICAgICAgICAgICAgICAgIC8vIFNhZmFyaVxuICAgICAgICAgICAgICAgIHRoaXMuX2hlYWRpbmcgPSBkZXZpY2VPcmllbnRhdGlvbkV2ZW50LndlYmtpdENvbXBhc3NIZWFkaW5nO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChkZXZpY2VPcmllbnRhdGlvbkV2ZW50LmFic29sdXRlID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgLy8gbm9uLVNhZmFyaSBhbHBoYSBpbmNyZWFzZXMgY291bnRlciBjbG9ja3dpc2UgYXJvdW5kIHRoZSB6IGF4aXNcbiAgICAgICAgICAgICAgICB0aGlzLl9oZWFkaW5nID0gZGV2aWNlT3JpZW50YXRpb25FdmVudC5hbHBoYSAqIC0xO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fdXBkYXRlTWFya2VyUm90YXRpb25UaHJvdHRsZWQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgYSBnZW9sb2NhdGlvbiBldmVudC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gSW5pdGlhbGl6ZSB0aGUgZ2VvbG9jYXRlIGNvbnRyb2wuXG4gICAgICogY29uc3QgZ2VvbG9jYXRlID0gbmV3IG1hcGJveGdsLkdlb2xvY2F0ZUNvbnRyb2woe1xuICAgICAqICAgICBwb3NpdGlvbk9wdGlvbnM6IHtcbiAgICAgKiAgICAgICAgIGVuYWJsZUhpZ2hBY2N1cmFjeTogdHJ1ZVxuICAgICAqICAgICB9LFxuICAgICAqICAgICB0cmFja1VzZXJMb2NhdGlvbjogdHJ1ZVxuICAgICAqIH0pO1xuICAgICAqIC8vIEFkZCB0aGUgY29udHJvbCB0byB0aGUgbWFwLlxuICAgICAqIG1hcC5hZGRDb250cm9sKGdlb2xvY2F0ZSk7XG4gICAgICogbWFwLm9uKCdsb2FkJywgKCkgPT4ge1xuICAgICAqICAgICBnZW9sb2NhdGUudHJpZ2dlcigpO1xuICAgICAqIH0pO1xuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGBmYWxzZWAgaWYgY2FsbGVkIGJlZm9yZSBjb250cm9sIHdhcyBhZGRlZCB0byBhIG1hcCwgb3RoZXJ3aXNlIHJldHVybnMgYHRydWVgLlxuICAgICAqL1xuICAgIHRyaWdnZXIoKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICghdGhpcy5fc2V0dXApIHtcbiAgICAgICAgICAgIHdhcm5PbmNlKCdHZW9sb2NhdGUgY29udHJvbCB0cmlnZ2VyZWQgYmVmb3JlIGFkZGVkIHRvIGEgbWFwJyk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy50cmFja1VzZXJMb2NhdGlvbikge1xuICAgICAgICAgICAgLy8gdXBkYXRlIHdhdGNoU3RhdGUgYW5kIGRvIGFueSBvdXRnb2luZyBzdGF0ZSBjbGVhbnVwXG4gICAgICAgICAgICBzd2l0Y2ggKHRoaXMuX3dhdGNoU3RhdGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ09GRic6XG4gICAgICAgICAgICAgICAgLy8gdHVybiBvbiB0aGUgR2VvbG9jYXRlQ29udHJvbFxuICAgICAgICAgICAgICAgIHRoaXMuX3dhdGNoU3RhdGUgPSAnV0FJVElOR19BQ1RJVkUnO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5maXJlKG5ldyBFdmVudCgndHJhY2t1c2VybG9jYXRpb25zdGFydCcpKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ1dBSVRJTkdfQUNUSVZFJzpcbiAgICAgICAgICAgIGNhc2UgJ0FDVElWRV9MT0NLJzpcbiAgICAgICAgICAgIGNhc2UgJ0FDVElWRV9FUlJPUic6XG4gICAgICAgICAgICBjYXNlICdCQUNLR1JPVU5EX0VSUk9SJzpcbiAgICAgICAgICAgICAgICAvLyB0dXJuIG9mZiB0aGUgR2VvbG9jYXRlIENvbnRyb2xcbiAgICAgICAgICAgICAgICB0aGlzLl9udW1iZXJPZldhdGNoZXMtLTtcbiAgICAgICAgICAgICAgICB0aGlzLl9ub1RpbWVvdXQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB0aGlzLl93YXRjaFN0YXRlID0gJ09GRic7XG4gICAgICAgICAgICAgICAgdGhpcy5fZ2VvbG9jYXRlQnV0dG9uLmNsYXNzTGlzdC5yZW1vdmUoJ21hcGJveGdsLWN0cmwtZ2VvbG9jYXRlLXdhaXRpbmcnKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9nZW9sb2NhdGVCdXR0b24uY2xhc3NMaXN0LnJlbW92ZSgnbWFwYm94Z2wtY3RybC1nZW9sb2NhdGUtYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fZ2VvbG9jYXRlQnV0dG9uLmNsYXNzTGlzdC5yZW1vdmUoJ21hcGJveGdsLWN0cmwtZ2VvbG9jYXRlLWFjdGl2ZS1lcnJvcicpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2dlb2xvY2F0ZUJ1dHRvbi5jbGFzc0xpc3QucmVtb3ZlKCdtYXBib3hnbC1jdHJsLWdlb2xvY2F0ZS1iYWNrZ3JvdW5kJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fZ2VvbG9jYXRlQnV0dG9uLmNsYXNzTGlzdC5yZW1vdmUoJ21hcGJveGdsLWN0cmwtZ2VvbG9jYXRlLWJhY2tncm91bmQtZXJyb3InKTtcblxuICAgICAgICAgICAgICAgIHRoaXMuZmlyZShuZXcgRXZlbnQoJ3RyYWNrdXNlcmxvY2F0aW9uZW5kJykpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnQkFDS0dST1VORCc6XG4gICAgICAgICAgICAgICAgdGhpcy5fd2F0Y2hTdGF0ZSA9ICdBQ1RJVkVfTE9DSyc7XG4gICAgICAgICAgICAgICAgdGhpcy5fZ2VvbG9jYXRlQnV0dG9uLmNsYXNzTGlzdC5yZW1vdmUoJ21hcGJveGdsLWN0cmwtZ2VvbG9jYXRlLWJhY2tncm91bmQnKTtcbiAgICAgICAgICAgICAgICAvLyBzZXQgY2FtZXJhIHRvIGxhc3Qga25vd24gbG9jYXRpb25cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fbGFzdEtub3duUG9zaXRpb24pIHRoaXMuX3VwZGF0ZUNhbWVyYSh0aGlzLl9sYXN0S25vd25Qb3NpdGlvbik7XG5cbiAgICAgICAgICAgICAgICB0aGlzLmZpcmUobmV3IEV2ZW50KCd0cmFja3VzZXJsb2NhdGlvbnN0YXJ0JykpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBhc3NlcnQoZmFsc2UsIGBVbmV4cGVjdGVkIHdhdGNoU3RhdGUgJHt0aGlzLl93YXRjaFN0YXRlfWApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBpbmNvbWluZyBzdGF0ZSBzZXR1cFxuICAgICAgICAgICAgc3dpdGNoICh0aGlzLl93YXRjaFN0YXRlKSB7XG4gICAgICAgICAgICBjYXNlICdXQUlUSU5HX0FDVElWRSc6XG4gICAgICAgICAgICAgICAgdGhpcy5fZ2VvbG9jYXRlQnV0dG9uLmNsYXNzTGlzdC5hZGQoJ21hcGJveGdsLWN0cmwtZ2VvbG9jYXRlLXdhaXRpbmcnKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9nZW9sb2NhdGVCdXR0b24uY2xhc3NMaXN0LmFkZCgnbWFwYm94Z2wtY3RybC1nZW9sb2NhdGUtYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdBQ1RJVkVfTE9DSyc6XG4gICAgICAgICAgICAgICAgdGhpcy5fZ2VvbG9jYXRlQnV0dG9uLmNsYXNzTGlzdC5hZGQoJ21hcGJveGdsLWN0cmwtZ2VvbG9jYXRlLWFjdGl2ZScpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnQUNUSVZFX0VSUk9SJzpcbiAgICAgICAgICAgICAgICB0aGlzLl9nZW9sb2NhdGVCdXR0b24uY2xhc3NMaXN0LmFkZCgnbWFwYm94Z2wtY3RybC1nZW9sb2NhdGUtd2FpdGluZycpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2dlb2xvY2F0ZUJ1dHRvbi5jbGFzc0xpc3QuYWRkKCdtYXBib3hnbC1jdHJsLWdlb2xvY2F0ZS1hY3RpdmUtZXJyb3InKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ0JBQ0tHUk9VTkQnOlxuICAgICAgICAgICAgICAgIHRoaXMuX2dlb2xvY2F0ZUJ1dHRvbi5jbGFzc0xpc3QuYWRkKCdtYXBib3hnbC1jdHJsLWdlb2xvY2F0ZS1iYWNrZ3JvdW5kJyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdCQUNLR1JPVU5EX0VSUk9SJzpcbiAgICAgICAgICAgICAgICB0aGlzLl9nZW9sb2NhdGVCdXR0b24uY2xhc3NMaXN0LmFkZCgnbWFwYm94Z2wtY3RybC1nZW9sb2NhdGUtd2FpdGluZycpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2dlb2xvY2F0ZUJ1dHRvbi5jbGFzc0xpc3QuYWRkKCdtYXBib3hnbC1jdHJsLWdlb2xvY2F0ZS1iYWNrZ3JvdW5kLWVycm9yJyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdPRkYnOlxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBhc3NlcnQoZmFsc2UsIGBVbmV4cGVjdGVkIHdhdGNoU3RhdGUgJHt0aGlzLl93YXRjaFN0YXRlfWApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBtYW5hZ2UgZ2VvbG9jYXRpb24ud2F0Y2hQb3NpdGlvbiAvIGdlb2xvY2F0aW9uLmNsZWFyV2F0Y2hcbiAgICAgICAgICAgIGlmICh0aGlzLl93YXRjaFN0YXRlID09PSAnT0ZGJyAmJiB0aGlzLl9nZW9sb2NhdGlvbldhdGNoSUQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIC8vIGNsZWFyIHdhdGNoUG9zaXRpb24gYXMgd2UndmUgY2hhbmdlZCB0byBhbiBPRkYgc3RhdGVcbiAgICAgICAgICAgICAgICB0aGlzLl9jbGVhcldhdGNoKCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX2dlb2xvY2F0aW9uV2F0Y2hJRCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgLy8gZW5hYmxlIHdhdGNoUG9zaXRpb24gc2luY2Ugd2F0Y2hTdGF0ZSBpcyBub3QgT0ZGIGFuZCB0aGVyZSBpcyBubyB3YXRjaFBvc2l0aW9uIGFscmVhZHkgcnVubmluZ1xuXG4gICAgICAgICAgICAgICAgdGhpcy5fZ2VvbG9jYXRlQnV0dG9uLmNsYXNzTGlzdC5hZGQoJ21hcGJveGdsLWN0cmwtZ2VvbG9jYXRlLXdhaXRpbmcnKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9nZW9sb2NhdGVCdXR0b24uc2V0QXR0cmlidXRlKCdhcmlhLXByZXNzZWQnLCAndHJ1ZScpO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5fbnVtYmVyT2ZXYXRjaGVzKys7XG4gICAgICAgICAgICAgICAgbGV0IHBvc2l0aW9uT3B0aW9ucztcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fbnVtYmVyT2ZXYXRjaGVzID4gMSkge1xuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbk9wdGlvbnMgPSB7bWF4aW11bUFnZTo2MDAwMDAsIHRpbWVvdXQ6MH07XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25vVGltZW91dCA9IHRydWU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25PcHRpb25zID0gdGhpcy5vcHRpb25zLnBvc2l0aW9uT3B0aW9ucztcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbm9UaW1lb3V0ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5fZ2VvbG9jYXRpb25XYXRjaElEID0gdGhpcy5vcHRpb25zLmdlb2xvY2F0aW9uLndhdGNoUG9zaXRpb24oXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX29uU3VjY2VzcywgdGhpcy5fb25FcnJvciwgcG9zaXRpb25PcHRpb25zKTtcblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc2hvd1VzZXJIZWFkaW5nKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2FkZERldmljZU9yaWVudGF0aW9uTGlzdGVuZXIoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICB0aGlzLm9wdGlvbnMuZ2VvbG9jYXRpb24uZ2V0Q3VycmVudFBvc2l0aW9uKHRoaXMuX29uU3VjY2VzcywgdGhpcy5fb25FcnJvciwgdGhpcy5vcHRpb25zLnBvc2l0aW9uT3B0aW9ucyk7XG5cbiAgICAgICAgICAgIC8vIFRoaXMgdGltZW91dCBlbnN1cmVzIHRoYXQgd2Ugc3RpbGwgY2FsbCBmaW5pc2goKSBldmVuIGlmXG4gICAgICAgICAgICAvLyB0aGUgdXNlciBkZWNsaW5lcyB0byBzaGFyZSB0aGVpciBsb2NhdGlvbiBpbiBGaXJlZm94XG4gICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICB0aGlzLl90aW1lb3V0SWQgPSBzZXRUaW1lb3V0KHRoaXMuX2ZpbmlzaCwgMTAwMDAgLyogMTBzZWMgKi8pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgX2FkZERldmljZU9yaWVudGF0aW9uTGlzdGVuZXIoKSB7XG4gICAgICAgIGNvbnN0IGFkZExpc3RlbmVyID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKCdvbmRldmljZW9yaWVudGF0aW9uYWJzb2x1dGUnIGluIHdpbmRvdykge1xuICAgICAgICAgICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignZGV2aWNlb3JpZW50YXRpb25hYnNvbHV0ZScsIHRoaXMuX29uRGV2aWNlT3JpZW50YXRpb24pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2RldmljZW9yaWVudGF0aW9uJywgdGhpcy5fb25EZXZpY2VPcmllbnRhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cuRGV2aWNlTW90aW9uRXZlbnQgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgIHR5cGVvZiB3aW5kb3cuRGV2aWNlTW90aW9uRXZlbnQucmVxdWVzdFBlcm1pc3Npb24gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWVcbiAgICAgICAgICAgIERldmljZU9yaWVudGF0aW9uRXZlbnQucmVxdWVzdFBlcm1pc3Npb24oKVxuICAgICAgICAgICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlID09PSAnZ3JhbnRlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZExpc3RlbmVyKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaChjb25zb2xlLmVycm9yKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFkZExpc3RlbmVyKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfY2xlYXJXYXRjaCgpIHtcbiAgICAgICAgdGhpcy5vcHRpb25zLmdlb2xvY2F0aW9uLmNsZWFyV2F0Y2godGhpcy5fZ2VvbG9jYXRpb25XYXRjaElEKTtcblxuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdkZXZpY2VvcmllbnRhdGlvbicsIHRoaXMuX29uRGV2aWNlT3JpZW50YXRpb24pO1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdkZXZpY2VvcmllbnRhdGlvbmFic29sdXRlJywgdGhpcy5fb25EZXZpY2VPcmllbnRhdGlvbik7XG5cbiAgICAgICAgdGhpcy5fZ2VvbG9jYXRpb25XYXRjaElEID0gKHVuZGVmaW5lZDogYW55KTtcbiAgICAgICAgdGhpcy5fZ2VvbG9jYXRlQnV0dG9uLmNsYXNzTGlzdC5yZW1vdmUoJ21hcGJveGdsLWN0cmwtZ2VvbG9jYXRlLXdhaXRpbmcnKTtcbiAgICAgICAgdGhpcy5fZ2VvbG9jYXRlQnV0dG9uLnNldEF0dHJpYnV0ZSgnYXJpYS1wcmVzc2VkJywgJ2ZhbHNlJyk7XG5cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zaG93VXNlckxvY2F0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLl91cGRhdGVNYXJrZXIobnVsbCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEdlb2xvY2F0ZUNvbnRyb2w7XG5cbi8qIEdlb2xvY2F0ZUNvbnRyb2wgV2F0Y2ggU3RhdGVzXG4gKiBUaGlzIGlzIHRoZSBwcml2YXRlIHN0YXRlIG9mIHRoZSBjb250cm9sLlxuICpcbiAqIE9GRlxuICogICAgb2ZmL2luYWN0aXZlXG4gKiBXQUlUSU5HX0FDVElWRVxuICogICAgR2VvbG9jYXRlQ29udHJvbCB3YXMgY2xpY2tlZCBidXQgc3RpbGwgd2FpdGluZyBmb3IgR2VvbG9jYXRpb24gQVBJIHJlc3BvbnNlIHdpdGggdXNlciBsb2NhdGlvblxuICogQUNUSVZFX0xPQ0tcbiAqICAgIFNob3dpbmcgdGhlIHVzZXIgbG9jYXRpb24gYXMgYSBkb3QgQU5EIHRyYWNraW5nIHRoZSBjYW1lcmEgdG8gYmUgZml4ZWQgdG8gdGhlaXIgbG9jYXRpb24uIElmIHRoZWlyIGxvY2F0aW9uIGNoYW5nZXMgdGhlIG1hcCBtb3ZlcyB0byBmb2xsb3cuXG4gKiBBQ1RJVkVfRVJST1JcbiAqICAgIFRoZXJlIHdhcyBlbiBlcnJvciBmcm9tIHRoZSBHZW9sb2NhdGlvbiBBUEkgd2hpbGUgdHJ5aW5nIHRvIHNob3cgYW5kIHRyYWNrIHRoZSB1c2VyIGxvY2F0aW9uLlxuICogQkFDS0dST1VORFxuICogICAgU2hvd2luZyB0aGUgdXNlciBsb2NhdGlvbiBhcyBhIGRvdCBidXQgdGhlIGNhbWVyYSBkb2Vzbid0IGZvbGxvdyB0aGVpciBsb2NhdGlvbiBhcyBpdCBjaGFuZ2VzLlxuICogQkFDS0dST1VORF9FUlJPUlxuICogICAgVGhlcmUgd2FzIGFuIGVycm9yIGZyb20gdGhlIEdlb2xvY2F0aW9uIEFQSSB3aGlsZSB0cnlpbmcgdG8gc2hvdyAoYnV0IG5vdCB0cmFjaykgdGhlIHVzZXIgbG9jYXRpb24uXG4gKi9cblxuLyoqXG4gKiBGaXJlZCBvbiBlYWNoIEdlb2xvY2F0aW9uIEFQSSBwb3NpdGlvbiB1cGRhdGUgdGhhdCByZXR1cm5lZCBhcyBzdWNjZXNzLlxuICpcbiAqIEBldmVudCBnZW9sb2NhdGVcbiAqIEBtZW1iZXJvZiBHZW9sb2NhdGVDb250cm9sXG4gKiBAaW5zdGFuY2VcbiAqIEBwcm9wZXJ0eSB7UG9zaXRpb259IGRhdGEgVGhlIHJldHVybmVkIFtQb3NpdGlvbl0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1Bvc2l0aW9uKSBvYmplY3QgZnJvbSB0aGUgY2FsbGJhY2sgaW4gW0dlb2xvY2F0aW9uLmdldEN1cnJlbnRQb3NpdGlvbigpXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvR2VvbG9jYXRpb24vZ2V0Q3VycmVudFBvc2l0aW9uKSBvciBbR2VvbG9jYXRpb24ud2F0Y2hQb3NpdGlvbigpXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvR2VvbG9jYXRpb24vd2F0Y2hQb3NpdGlvbikuXG4gKiBAZXhhbXBsZVxuICogLy8gSW5pdGlhbGl6ZSB0aGUgR2VvbG9jYXRlQ29udHJvbC5cbiAqIGNvbnN0IGdlb2xvY2F0ZSA9IG5ldyBtYXBib3hnbC5HZW9sb2NhdGVDb250cm9sKHtcbiAqICAgICBwb3NpdGlvbk9wdGlvbnM6IHtcbiAqICAgICAgICAgZW5hYmxlSGlnaEFjY3VyYWN5OiB0cnVlXG4gKiAgICAgfSxcbiAqICAgICB0cmFja1VzZXJMb2NhdGlvbjogdHJ1ZVxuICogfSk7XG4gKiAvLyBBZGQgdGhlIGNvbnRyb2wgdG8gdGhlIG1hcC5cbiAqIG1hcC5hZGRDb250cm9sKGdlb2xvY2F0ZSk7XG4gKiAvLyBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBmaXJlc1xuICogLy8gd2hlbiBhIGdlb2xvY2F0ZSBldmVudCBvY2N1cnMuXG4gKiBnZW9sb2NhdGUub24oJ2dlb2xvY2F0ZScsICgpID0+IHtcbiAqICAgICBjb25zb2xlLmxvZygnQSBnZW9sb2NhdGUgZXZlbnQgaGFzIG9jY3VycmVkLicpO1xuICogfSk7XG4gKlxuICovXG5cbi8qKlxuICogRmlyZWQgb24gZWFjaCBHZW9sb2NhdGlvbiBBUEkgcG9zaXRpb24gdXBkYXRlIHRoYXQgcmV0dXJuZWQgYXMgYW4gZXJyb3IuXG4gKlxuICogQGV2ZW50IGVycm9yXG4gKiBAbWVtYmVyb2YgR2VvbG9jYXRlQ29udHJvbFxuICogQGluc3RhbmNlXG4gKiBAcHJvcGVydHkge1Bvc2l0aW9uRXJyb3J9IGRhdGEgVGhlIHJldHVybmVkIFtQb3NpdGlvbkVycm9yXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvUG9zaXRpb25FcnJvcikgb2JqZWN0IGZyb20gdGhlIGNhbGxiYWNrIGluIFtHZW9sb2NhdGlvbi5nZXRDdXJyZW50UG9zaXRpb24oKV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0dlb2xvY2F0aW9uL2dldEN1cnJlbnRQb3NpdGlvbikgb3IgW0dlb2xvY2F0aW9uLndhdGNoUG9zaXRpb24oKV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0dlb2xvY2F0aW9uL3dhdGNoUG9zaXRpb24pLlxuICogQGV4YW1wbGVcbiAqIC8vIEluaXRpYWxpemUgdGhlIEdlb2xvY2F0ZUNvbnRyb2wuXG4gKiBjb25zdCBnZW9sb2NhdGUgPSBuZXcgbWFwYm94Z2wuR2VvbG9jYXRlQ29udHJvbCh7XG4gKiAgICAgcG9zaXRpb25PcHRpb25zOiB7XG4gKiAgICAgICAgIGVuYWJsZUhpZ2hBY2N1cmFjeTogdHJ1ZVxuICogICAgIH0sXG4gKiAgICAgdHJhY2tVc2VyTG9jYXRpb246IHRydWVcbiAqIH0pO1xuICogLy8gQWRkIHRoZSBjb250cm9sIHRvIHRoZSBtYXAuXG4gKiBtYXAuYWRkQ29udHJvbChnZW9sb2NhdGUpO1xuICogLy8gU2V0IGFuIGV2ZW50IGxpc3RlbmVyIHRoYXQgZmlyZXNcbiAqIC8vIHdoZW4gYW4gZXJyb3IgZXZlbnQgb2NjdXJzLlxuICogZ2VvbG9jYXRlLm9uKCdlcnJvcicsICgpID0+IHtcbiAqICAgICBjb25zb2xlLmxvZygnQW4gZXJyb3IgZXZlbnQgaGFzIG9jY3VycmVkLicpO1xuICogfSk7XG4gKlxuICovXG5cbi8qKlxuICogRmlyZWQgb24gZWFjaCBHZW9sb2NhdGlvbiBBUEkgcG9zaXRpb24gdXBkYXRlIHRoYXQgcmV0dXJuZWQgYXMgc3VjY2VzcyBidXQgdXNlciBwb3NpdGlvbiBpcyBvdXQgb2YgbWFwIGBtYXhCb3VuZHNgLlxuICpcbiAqIEBldmVudCBvdXRvZm1heGJvdW5kc1xuICogQG1lbWJlcm9mIEdlb2xvY2F0ZUNvbnRyb2xcbiAqIEBpbnN0YW5jZVxuICogQHByb3BlcnR5IHtQb3NpdGlvbn0gZGF0YSBUaGUgcmV0dXJuZWQgW1Bvc2l0aW9uXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvUG9zaXRpb24pIG9iamVjdCBmcm9tIHRoZSBjYWxsYmFjayBpbiBbR2VvbG9jYXRpb24uZ2V0Q3VycmVudFBvc2l0aW9uKCldKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9HZW9sb2NhdGlvbi9nZXRDdXJyZW50UG9zaXRpb24pIG9yIFtHZW9sb2NhdGlvbi53YXRjaFBvc2l0aW9uKCldKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9HZW9sb2NhdGlvbi93YXRjaFBvc2l0aW9uKS5cbiAqIEBleGFtcGxlXG4gKiAvLyBJbml0aWFsaXplIHRoZSBHZW9sb2NhdGVDb250cm9sLlxuICogY29uc3QgZ2VvbG9jYXRlID0gbmV3IG1hcGJveGdsLkdlb2xvY2F0ZUNvbnRyb2woe1xuICogICAgIHBvc2l0aW9uT3B0aW9uczoge1xuICogICAgICAgICBlbmFibGVIaWdoQWNjdXJhY3k6IHRydWVcbiAqICAgICB9LFxuICogICAgIHRyYWNrVXNlckxvY2F0aW9uOiB0cnVlXG4gKiB9KTtcbiAqIC8vIEFkZCB0aGUgY29udHJvbCB0byB0aGUgbWFwLlxuICogbWFwLmFkZENvbnRyb2woZ2VvbG9jYXRlKTtcbiAqIC8vIFNldCBhbiBldmVudCBsaXN0ZW5lciB0aGF0IGZpcmVzXG4gKiAvLyB3aGVuIGFuIG91dG9mbWF4Ym91bmRzIGV2ZW50IG9jY3Vycy5cbiAqIGdlb2xvY2F0ZS5vbignb3V0b2ZtYXhib3VuZHMnLCAoKSA9PiB7XG4gKiAgICAgY29uc29sZS5sb2coJ0FuIG91dG9mbWF4Ym91bmRzIGV2ZW50IGhhcyBvY2N1cnJlZC4nKTtcbiAqIH0pO1xuICpcbiAqL1xuXG4vKipcbiAqIEZpcmVkIHdoZW4gdGhlIEdlb2xvY2F0ZUNvbnRyb2wgY2hhbmdlcyB0byB0aGUgYWN0aXZlIGxvY2sgc3RhdGUsIHdoaWNoIGhhcHBlbnMgZWl0aGVyIHVwb24gZmlyc3Qgb2J0YWluaW5nIGEgc3VjY2Vzc2Z1bCBHZW9sb2NhdGlvbiBBUEkgcG9zaXRpb24gZm9yIHRoZSB1c2VyIChhIGdlb2xvY2F0ZSBldmVudCB3aWxsIGZvbGxvdyksIG9yIHdoZW4gdGhlIHVzZXIgY2xpY2tzIHRoZSBnZW9sb2NhdGUgYnV0dG9uIHdoZW4gaW4gdGhlIGJhY2tncm91bmQgc3RhdGUsIHdoaWNoIHVzZXMgdGhlIGxhc3Qga25vd24gcG9zaXRpb24gdG8gcmVjZW50ZXIgdGhlIG1hcCBhbmQgZW50ZXIgYWN0aXZlIGxvY2sgc3RhdGUgKG5vIGdlb2xvY2F0ZSBldmVudCB3aWxsIGZvbGxvdyB1bmxlc3MgdGhlIHVzZXJzJ3MgbG9jYXRpb24gY2hhbmdlcykuXG4gKlxuICogQGV2ZW50IHRyYWNrdXNlcmxvY2F0aW9uc3RhcnRcbiAqIEBtZW1iZXJvZiBHZW9sb2NhdGVDb250cm9sXG4gKiBAaW5zdGFuY2VcbiAqIEBleGFtcGxlXG4gKiAvLyBJbml0aWFsaXplIHRoZSBHZW9sb2NhdGVDb250cm9sLlxuICogY29uc3QgZ2VvbG9jYXRlID0gbmV3IG1hcGJveGdsLkdlb2xvY2F0ZUNvbnRyb2woe1xuICogICAgIHBvc2l0aW9uT3B0aW9uczoge1xuICogICAgICAgICBlbmFibGVIaWdoQWNjdXJhY3k6IHRydWVcbiAqICAgICB9LFxuICogICAgIHRyYWNrVXNlckxvY2F0aW9uOiB0cnVlXG4gKiB9KTtcbiAqIC8vIEFkZCB0aGUgY29udHJvbCB0byB0aGUgbWFwLlxuICogbWFwLmFkZENvbnRyb2woZ2VvbG9jYXRlKTtcbiAqIC8vIFNldCBhbiBldmVudCBsaXN0ZW5lciB0aGF0IGZpcmVzXG4gKiAvLyB3aGVuIGEgdHJhY2t1c2VybG9jYXRpb25zdGFydCBldmVudCBvY2N1cnMuXG4gKiBnZW9sb2NhdGUub24oJ3RyYWNrdXNlcmxvY2F0aW9uc3RhcnQnLCAoKSA9PiB7XG4gKiAgICAgY29uc29sZS5sb2coJ0EgdHJhY2t1c2VybG9jYXRpb25zdGFydCBldmVudCBoYXMgb2NjdXJyZWQuJyk7XG4gKiB9KTtcbiAqXG4gKi9cblxuLyoqXG4gKiBGaXJlZCB3aGVuIHRoZSBHZW9sb2NhdGVDb250cm9sIGNoYW5nZXMgdG8gdGhlIGJhY2tncm91bmQgc3RhdGUsIHdoaWNoIGhhcHBlbnMgd2hlbiBhIHVzZXIgY2hhbmdlcyB0aGUgY2FtZXJhIGR1cmluZyBhbiBhY3RpdmUgcG9zaXRpb24gbG9jay4gVGhpcyBvbmx5IGFwcGxpZXMgd2hlbiB0cmFja1VzZXJMb2NhdGlvbiBpcyB0cnVlLiBJbiB0aGUgYmFja2dyb3VuZCBzdGF0ZSwgdGhlIGRvdCBvbiB0aGUgbWFwIHdpbGwgdXBkYXRlIHdpdGggbG9jYXRpb24gdXBkYXRlcyBidXQgdGhlIGNhbWVyYSB3aWxsIG5vdC5cbiAqXG4gKiBAZXZlbnQgdHJhY2t1c2VybG9jYXRpb25lbmRcbiAqIEBtZW1iZXJvZiBHZW9sb2NhdGVDb250cm9sXG4gKiBAaW5zdGFuY2VcbiAqIEBleGFtcGxlXG4gKiAvLyBJbml0aWFsaXplIHRoZSBHZW9sb2NhdGVDb250cm9sLlxuICogY29uc3QgZ2VvbG9jYXRlID0gbmV3IG1hcGJveGdsLkdlb2xvY2F0ZUNvbnRyb2woe1xuICogICAgIHBvc2l0aW9uT3B0aW9uczoge1xuICogICAgICAgICBlbmFibGVIaWdoQWNjdXJhY3k6IHRydWVcbiAqICAgICB9LFxuICogICAgIHRyYWNrVXNlckxvY2F0aW9uOiB0cnVlXG4gKiB9KTtcbiAqIC8vIEFkZCB0aGUgY29udHJvbCB0byB0aGUgbWFwLlxuICogbWFwLmFkZENvbnRyb2woZ2VvbG9jYXRlKTtcbiAqIC8vIFNldCBhbiBldmVudCBsaXN0ZW5lciB0aGF0IGZpcmVzXG4gKiAvLyB3aGVuIGEgdHJhY2t1c2VybG9jYXRpb25lbmQgZXZlbnQgb2NjdXJzLlxuICogZ2VvbG9jYXRlLm9uKCd0cmFja3VzZXJsb2NhdGlvbmVuZCcsICgpID0+IHtcbiAqICAgICBjb25zb2xlLmxvZygnQSB0cmFja3VzZXJsb2NhdGlvbmVuZCBldmVudCBoYXMgb2NjdXJyZWQuJyk7XG4gKiB9KTtcbiAqXG4gKi9cbiIsIi8vIEBmbG93XG5cbmltcG9ydCAqIGFzIERPTSBmcm9tICcuLi8uLi91dGlsL2RvbS5qcyc7XG5pbXBvcnQge2V4dGVuZCwgYmluZEFsbH0gZnJvbSAnLi4vLi4vdXRpbC91dGlsLmpzJztcblxuaW1wb3J0IHR5cGUgTWFwLCB7Q29udHJvbFBvc2l0aW9ufSBmcm9tICcuLi9tYXAuanMnO1xuXG50eXBlIFVuaXQgPSAnaW1wZXJpYWwnIHwgJ21ldHJpYycgfCAnbmF1dGljYWwnO1xuXG50eXBlIE9wdGlvbnMgPSB7XG4gICAgbWF4V2lkdGg/OiBudW1iZXIsXG4gICAgdW5pdD86IFVuaXQ7XG59O1xuXG5jb25zdCBkZWZhdWx0T3B0aW9uczogT3B0aW9ucyA9IHtcbiAgICBtYXhXaWR0aDogMTAwLFxuICAgIHVuaXQ6ICdtZXRyaWMnXG59O1xuXG5jb25zdCB1bml0QWJiciA9IHtcbiAgICBraWxvbWV0ZXI6ICdrbScsXG4gICAgbWV0ZXI6ICdtJyxcbiAgICBtaWxlOiAnbWknLFxuICAgIGZvb3Q6ICdmdCcsXG4gICAgJ25hdXRpY2FsLW1pbGUnOiAnbm0nLFxufTtcblxuLyoqXG4gKiBBIGBTY2FsZUNvbnRyb2xgIGNvbnRyb2wgZGlzcGxheXMgdGhlIHJhdGlvIG9mIGEgZGlzdGFuY2Ugb24gdGhlIG1hcCB0byB0aGUgY29ycmVzcG9uZGluZyBkaXN0YW5jZSBvbiB0aGUgZ3JvdW5kLlxuICogQWRkIHRoaXMgY29udHJvbCB0byBhIG1hcCB1c2luZyB7QGxpbmsgTWFwI2FkZENvbnRyb2x9LlxuICpcbiAqIEBpbXBsZW1lbnRzIHtJQ29udHJvbH1cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5tYXhXaWR0aD0nMTAwJ10gVGhlIG1heGltdW0gbGVuZ3RoIG9mIHRoZSBzY2FsZSBjb250cm9sIGluIHBpeGVscy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0aW9ucy51bml0PSdtZXRyaWMnXSBVbml0IG9mIHRoZSBkaXN0YW5jZSAoYCdpbXBlcmlhbCdgLCBgJ21ldHJpYydgIG9yIGAnbmF1dGljYWwnYCkuXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc2NhbGUgPSBuZXcgbWFwYm94Z2wuU2NhbGVDb250cm9sKHtcbiAqICAgICBtYXhXaWR0aDogODAsXG4gKiAgICAgdW5pdDogJ2ltcGVyaWFsJ1xuICogfSk7XG4gKiBtYXAuYWRkQ29udHJvbChzY2FsZSk7XG4gKlxuICogc2NhbGUuc2V0VW5pdCgnbWV0cmljJyk7XG4gKi9cbmNsYXNzIFNjYWxlQ29udHJvbCB7XG4gICAgX21hcDogTWFwO1xuICAgIF9jb250YWluZXI6IEhUTUxFbGVtZW50O1xuICAgIF9sYW5ndWFnZTogP3N0cmluZyB8ID9zdHJpbmdbXTtcbiAgICBfaXNOdW1iZXJGb3JtYXRTdXBwb3J0ZWQ6IGJvb2xlYW47XG4gICAgb3B0aW9uczogT3B0aW9ucztcblxuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnM6IE9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gZXh0ZW5kKHt9LCBkZWZhdWx0T3B0aW9ucywgb3B0aW9ucyk7XG5cbiAgICAgICAgLy8gU29tZSBvbGQgYnJvd3NlcnMgKGUuZy4sIFNhZmFyaSA8IDE0LjEpIGRvbid0IHN1cHBvcnQgdGhlIFwidW5pdFwiIHN0eWxlIGluIE51bWJlckZvcm1hdC5cbiAgICAgICAgLy8gVGhpcyBpcyBhIHdvcmthcm91bmQgdG8gZGlzcGxheSB0aGUgc2NhbGUgd2l0aG91dCBwcm9wZXIgaW50ZXJuYXRpb25hbGl6YXRpb24gc3VwcG9ydC5cbiAgICAgICAgdGhpcy5faXNOdW1iZXJGb3JtYXRTdXBwb3J0ZWQgPSBpc051bWJlckZvcm1hdFN1cHBvcnRlZCgpO1xuXG4gICAgICAgIGJpbmRBbGwoW1xuICAgICAgICAgICAgJ191cGRhdGUnLFxuICAgICAgICAgICAgJ19zZXRTY2FsZScsXG4gICAgICAgICAgICAnc2V0VW5pdCdcbiAgICAgICAgXSwgdGhpcyk7XG4gICAgfVxuXG4gICAgZ2V0RGVmYXVsdFBvc2l0aW9uKCk6IENvbnRyb2xQb3NpdGlvbiB7XG4gICAgICAgIHJldHVybiAnYm90dG9tLWxlZnQnO1xuICAgIH1cblxuICAgIF91cGRhdGUoKSB7XG4gICAgICAgIC8vIEEgaG9yaXpvbnRhbCBzY2FsZSBpcyBpbWFnaW5lZCB0byBiZSBwcmVzZW50IGF0IGNlbnRlciBvZiB0aGUgbWFwXG4gICAgICAgIC8vIGNvbnRhaW5lciB3aXRoIG1heGltdW0gbGVuZ3RoIChEZWZhdWx0KSBhcyAxMDBweC5cbiAgICAgICAgLy8gVXNpbmcgc3BoZXJpY2FsIGxhdyBvZiBjb3NpbmVzIGFwcHJveGltYXRpb24sIHRoZSByZWFsIGRpc3RhbmNlIGlzXG4gICAgICAgIC8vIGZvdW5kIGJldHdlZW4gdGhlIHR3byBjb29yZGluYXRlcy5cbiAgICAgICAgY29uc3QgbWF4V2lkdGggPSB0aGlzLm9wdGlvbnMubWF4V2lkdGggfHwgMTAwO1xuXG4gICAgICAgIGNvbnN0IG1hcCA9IHRoaXMuX21hcDtcbiAgICAgICAgY29uc3QgeSA9IG1hcC5fY29udGFpbmVySGVpZ2h0IC8gMjtcbiAgICAgICAgY29uc3QgeCA9IChtYXAuX2NvbnRhaW5lcldpZHRoIC8gMikgLSBtYXhXaWR0aCAvIDI7XG4gICAgICAgIGNvbnN0IGxlZnQgPSBtYXAudW5wcm9qZWN0KFt4LCB5XSk7XG4gICAgICAgIGNvbnN0IHJpZ2h0ID0gbWFwLnVucHJvamVjdChbeCArIG1heFdpZHRoLCB5XSk7XG4gICAgICAgIGNvbnN0IG1heE1ldGVycyA9IGxlZnQuZGlzdGFuY2VUbyhyaWdodCk7XG4gICAgICAgIC8vIFRoZSByZWFsIGRpc3RhbmNlIGNvcnJlc3BvbmRpbmcgdG8gMTAwcHggc2NhbGUgbGVuZ3RoIGlzIHJvdW5kZWQgb2ZmIHRvXG4gICAgICAgIC8vIG5lYXIgcHJldHR5IG51bWJlciBhbmQgdGhlIHNjYWxlIGxlbmd0aCBmb3IgdGhlIHNhbWUgaXMgZm91bmQgb3V0LlxuICAgICAgICAvLyBEZWZhdWx0IHVuaXQgb2YgdGhlIHNjYWxlIGlzIGJhc2VkIG9uIFVzZXIncyBsb2NhbGUuXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMudW5pdCA9PT0gJ2ltcGVyaWFsJykge1xuICAgICAgICAgICAgY29uc3QgbWF4RmVldCA9IDMuMjgwOCAqIG1heE1ldGVycztcbiAgICAgICAgICAgIGlmIChtYXhGZWV0ID4gNTI4MCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1heE1pbGVzID0gbWF4RmVldCAvIDUyODA7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2V0U2NhbGUobWF4V2lkdGgsIG1heE1pbGVzLCAnbWlsZScpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zZXRTY2FsZShtYXhXaWR0aCwgbWF4RmVldCwgJ2Zvb3QnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLm9wdGlvbnMudW5pdCA9PT0gJ25hdXRpY2FsJykge1xuICAgICAgICAgICAgY29uc3QgbWF4TmF1dGljYWxzID0gbWF4TWV0ZXJzIC8gMTg1MjtcbiAgICAgICAgICAgIHRoaXMuX3NldFNjYWxlKG1heFdpZHRoLCBtYXhOYXV0aWNhbHMsICduYXV0aWNhbC1taWxlJyk7XG4gICAgICAgIH0gZWxzZSBpZiAobWF4TWV0ZXJzID49IDEwMDApIHtcbiAgICAgICAgICAgIHRoaXMuX3NldFNjYWxlKG1heFdpZHRoLCBtYXhNZXRlcnMgLyAxMDAwLCAna2lsb21ldGVyJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9zZXRTY2FsZShtYXhXaWR0aCwgbWF4TWV0ZXJzLCAnbWV0ZXInKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9zZXRTY2FsZShtYXhXaWR0aDogbnVtYmVyLCBtYXhEaXN0YW5jZTogbnVtYmVyLCB1bml0OiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5fbWFwLl9yZXF1ZXN0RG9tVGFzaygoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBkaXN0YW5jZSA9IGdldFJvdW5kTnVtKG1heERpc3RhbmNlKTtcbiAgICAgICAgICAgIGNvbnN0IHJhdGlvID0gZGlzdGFuY2UgLyBtYXhEaXN0YW5jZTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuX2lzTnVtYmVyRm9ybWF0U3VwcG9ydGVkICYmIHVuaXQgIT09ICduYXV0aWNhbC1taWxlJykge1xuICAgICAgICAgICAgICAgIC8vICRGbG93Rml4TWVbaW5jb21wYXRpYmxlLWNhbGxdIOKAlCBmbG93IHYwLjE5MC4xIGRvZXNuJ3Qgc3VwcG9ydCBvcHRpb25hbCBgbG9jYWxlc2AgYXJndW1lbnQgYW5kIGB1bml0YCBzdHlsZSBvcHRpb25cbiAgICAgICAgICAgICAgICB0aGlzLl9jb250YWluZXIuaW5uZXJIVE1MID0gbmV3IEludGwuTnVtYmVyRm9ybWF0KHRoaXMuX2xhbmd1YWdlLCB7c3R5bGU6ICd1bml0JywgdW5pdERpc3BsYXk6ICdzaG9ydCcsIHVuaXR9KS5mb3JtYXQoZGlzdGFuY2UpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9jb250YWluZXIuaW5uZXJIVE1MID0gYCR7ZGlzdGFuY2V9Jm5ic3A7JHt1bml0QWJiclt1bml0XX1gO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLl9jb250YWluZXIuc3R5bGUud2lkdGggPSBgJHttYXhXaWR0aCAqIHJhdGlvfXB4YDtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgb25BZGQobWFwOiBNYXApOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIHRoaXMuX21hcCA9IG1hcDtcbiAgICAgICAgdGhpcy5fbGFuZ3VhZ2UgPSBtYXAuZ2V0TGFuZ3VhZ2UoKTtcbiAgICAgICAgdGhpcy5fY29udGFpbmVyID0gRE9NLmNyZWF0ZSgnZGl2JywgJ21hcGJveGdsLWN0cmwgbWFwYm94Z2wtY3RybC1zY2FsZScsIG1hcC5nZXRDb250YWluZXIoKSk7XG4gICAgICAgIHRoaXMuX2NvbnRhaW5lci5kaXIgPSAnYXV0byc7XG5cbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICB0aGlzLl9tYXAub24oJ21vdmUnLCB0aGlzLl91cGRhdGUpO1xuICAgICAgICB0aGlzLl91cGRhdGUoKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5fY29udGFpbmVyO1xuICAgIH1cblxuICAgIG9uUmVtb3ZlKCkge1xuICAgICAgICB0aGlzLl9jb250YWluZXIucmVtb3ZlKCk7XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgdGhpcy5fbWFwLm9mZignbW92ZScsIHRoaXMuX3VwZGF0ZSk7XG4gICAgICAgIHRoaXMuX21hcCA9ICh1bmRlZmluZWQ6IGFueSk7XG4gICAgfVxuXG4gICAgX3NldExhbmd1YWdlKGxhbmd1YWdlOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5fbGFuZ3VhZ2UgPSBsYW5ndWFnZTtcbiAgICAgICAgdGhpcy5fdXBkYXRlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBzY2FsZSdzIHVuaXQgb2YgdGhlIGRpc3RhbmNlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHsnaW1wZXJpYWwnIHwgJ21ldHJpYycgfCAnbmF1dGljYWwnfSB1bml0IFVuaXQgb2YgdGhlIGRpc3RhbmNlIChgJ2ltcGVyaWFsJ2AsIGAnbWV0cmljJ2Agb3IgYCduYXV0aWNhbCdgKS5cbiAgICAgKi9cbiAgICBzZXRVbml0KHVuaXQ6IFVuaXQpIHtcbiAgICAgICAgdGhpcy5vcHRpb25zLnVuaXQgPSB1bml0O1xuICAgICAgICB0aGlzLl91cGRhdGUoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFNjYWxlQ29udHJvbDtcblxuZnVuY3Rpb24gaXNOdW1iZXJGb3JtYXRTdXBwb3J0ZWQoKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gJEZsb3dJZ25vcmVcbiAgICAgICAgbmV3IEludGwuTnVtYmVyRm9ybWF0KCdlbicsIHtzdHlsZTogJ3VuaXQnLCB1bml0RGlzcGxheTogJ3Nob3J0JywgdW5pdDogJ21ldGVyJ30pO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChfKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGdldERlY2ltYWxSb3VuZE51bShkOiBudW1iZXIpIHtcbiAgICBjb25zdCBtdWx0aXBsaWVyID0gTWF0aC5wb3coMTAsIE1hdGguY2VpbCgtTWF0aC5sb2coZCkgLyBNYXRoLkxOMTApKTtcbiAgICByZXR1cm4gTWF0aC5yb3VuZChkICogbXVsdGlwbGllcikgLyBtdWx0aXBsaWVyO1xufVxuXG5mdW5jdGlvbiBnZXRSb3VuZE51bShudW06IG51bWJlcikge1xuICAgIGNvbnN0IHBvdzEwID0gTWF0aC5wb3coMTAsIChgJHtNYXRoLmZsb29yKG51bSl9YCkubGVuZ3RoIC0gMSk7XG4gICAgbGV0IGQgPSBudW0gLyBwb3cxMDtcblxuICAgIGQgPSBkID49IDEwID8gMTAgOlxuICAgICAgICBkID49IDUgPyA1IDpcbiAgICAgICAgZCA+PSAzID8gMyA6XG4gICAgICAgIGQgPj0gMiA/IDIgOlxuICAgICAgICBkID49IDEgPyAxIDogZ2V0RGVjaW1hbFJvdW5kTnVtKGQpO1xuXG4gICAgcmV0dXJuIHBvdzEwICogZDtcbn1cbiIsIi8vIEBmbG93XG5cbmltcG9ydCAqIGFzIERPTSBmcm9tICcuLi8uLi91dGlsL2RvbS5qcyc7XG5cbmltcG9ydCB7YmluZEFsbCwgd2Fybk9uY2V9IGZyb20gJy4uLy4uL3V0aWwvdXRpbC5qcyc7XG5pbXBvcnQgd2luZG93IGZyb20gJy4uLy4uL3V0aWwvd2luZG93LmpzJztcblxuaW1wb3J0IHR5cGUgTWFwIGZyb20gJy4uL21hcC5qcyc7XG5cbnR5cGUgT3B0aW9ucyA9IHtcbiAgICBjb250YWluZXI/OiBIVE1MRWxlbWVudFxufTtcblxuLyoqXG4gKiBBIGBGdWxsc2NyZWVuQ29udHJvbGAgY29udHJvbCBjb250YWlucyBhIGJ1dHRvbiBmb3IgdG9nZ2xpbmcgdGhlIG1hcCBpbiBhbmQgb3V0IG9mIGZ1bGxzY3JlZW4gbW9kZS4gU2VlIHRoZSBgcmVxdWVzdEZ1bGxTY3JlZW5gIFtjb21wYXRpYmlsaXR5IHRhYmxlXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRWxlbWVudC9yZXF1ZXN0RnVsbFNjcmVlbiNicm93c2VyX2NvbXBhdGliaWxpdHkpIGZvciBzdXBwb3J0ZWQgYnJvd3NlcnMuXG4gKiBBZGQgdGhpcyBjb250cm9sIHRvIGEgbWFwIHVzaW5nIHtAbGluayBNYXAjYWRkQ29udHJvbH0uXG4gKlxuICogQGltcGxlbWVudHMge0lDb250cm9sfVxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gW29wdGlvbnMuY29udGFpbmVyXSBgY29udGFpbmVyYCBpcyB0aGUgW2NvbXBhdGlibGUgRE9NIGVsZW1lbnRdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50L3JlcXVlc3RGdWxsU2NyZWVuI0NvbXBhdGlibGVfZWxlbWVudHMpIHdoaWNoIHNob3VsZCBiZSBtYWRlIGZ1bGwgc2NyZWVuLiBCeSBkZWZhdWx0LCB0aGUgbWFwIGNvbnRhaW5lciBlbGVtZW50IHdpbGwgYmUgbWFkZSBmdWxsIHNjcmVlbi5cbiAqXG4gKiBAZXhhbXBsZVxuICogbWFwLmFkZENvbnRyb2wobmV3IG1hcGJveGdsLkZ1bGxzY3JlZW5Db250cm9sKHtjb250YWluZXI6IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKX0pKTtcbiAqIEBzZWUgW0V4YW1wbGU6IFZpZXcgYSBmdWxsc2NyZWVuIG1hcF0oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9mdWxsc2NyZWVuLylcbiAqL1xuXG5jbGFzcyBGdWxsc2NyZWVuQ29udHJvbCB7XG4gICAgX21hcDogTWFwO1xuICAgIF9jb250cm9sQ29udGFpbmVyOiBIVE1MRWxlbWVudDtcbiAgICBfZnVsbHNjcmVlbjogYm9vbGVhbjtcbiAgICBfZnVsbHNjcmVlbmNoYW5nZTogc3RyaW5nO1xuICAgIF9mdWxsc2NyZWVuQnV0dG9uOiBIVE1MRWxlbWVudDtcbiAgICBfY29udGFpbmVyOiBIVE1MRWxlbWVudDtcblxuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnM6IE9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy5fZnVsbHNjcmVlbiA9IGZhbHNlO1xuICAgICAgICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLmNvbnRhaW5lcikge1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuY29udGFpbmVyIGluc3RhbmNlb2Ygd2luZG93LkhUTUxFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fY29udGFpbmVyID0gb3B0aW9ucy5jb250YWluZXI7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHdhcm5PbmNlKCdGdWxsIHNjcmVlbiBjb250cm9sIFxcJ2NvbnRhaW5lclxcJyBtdXN0IGJlIGEgRE9NIGVsZW1lbnQuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYmluZEFsbChbXG4gICAgICAgICAgICAnX29uQ2xpY2tGdWxsc2NyZWVuJyxcbiAgICAgICAgICAgICdfY2hhbmdlSWNvbidcbiAgICAgICAgXSwgdGhpcyk7XG4gICAgICAgIGlmICgnb25mdWxsc2NyZWVuY2hhbmdlJyBpbiB3aW5kb3cuZG9jdW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX2Z1bGxzY3JlZW5jaGFuZ2UgPSAnZnVsbHNjcmVlbmNoYW5nZSc7XG4gICAgICAgIH0gZWxzZSBpZiAoJ29ud2Via2l0ZnVsbHNjcmVlbmNoYW5nZScgaW4gd2luZG93LmRvY3VtZW50KSB7XG4gICAgICAgICAgICB0aGlzLl9mdWxsc2NyZWVuY2hhbmdlID0gJ3dlYmtpdGZ1bGxzY3JlZW5jaGFuZ2UnO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25BZGQobWFwOiBNYXApOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIHRoaXMuX21hcCA9IG1hcDtcbiAgICAgICAgaWYgKCF0aGlzLl9jb250YWluZXIpIHRoaXMuX2NvbnRhaW5lciA9IHRoaXMuX21hcC5nZXRDb250YWluZXIoKTtcbiAgICAgICAgdGhpcy5fY29udHJvbENvbnRhaW5lciA9IERPTS5jcmVhdGUoJ2RpdicsIGBtYXBib3hnbC1jdHJsIG1hcGJveGdsLWN0cmwtZ3JvdXBgKTtcbiAgICAgICAgaWYgKHRoaXMuX2NoZWNrRnVsbHNjcmVlblN1cHBvcnQoKSkge1xuICAgICAgICAgICAgdGhpcy5fc2V0dXBVSSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fY29udHJvbENvbnRhaW5lci5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICAgICAgd2Fybk9uY2UoJ1RoaXMgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgZnVsbHNjcmVlbiBtb2RlLicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250cm9sQ29udGFpbmVyO1xuICAgIH1cblxuICAgIG9uUmVtb3ZlKCkge1xuICAgICAgICB0aGlzLl9jb250cm9sQ29udGFpbmVyLnJlbW92ZSgpO1xuICAgICAgICB0aGlzLl9tYXAgPSAobnVsbDogYW55KTtcbiAgICAgICAgLy8gJEZsb3dGaXhNZVttZXRob2QtdW5iaW5kaW5nXVxuICAgICAgICB3aW5kb3cuZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcih0aGlzLl9mdWxsc2NyZWVuY2hhbmdlLCB0aGlzLl9jaGFuZ2VJY29uKTtcbiAgICB9XG5cbiAgICBfY2hlY2tGdWxsc2NyZWVuU3VwcG9ydCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICEhKFxuICAgICAgICAgICAgd2luZG93LmRvY3VtZW50LmZ1bGxzY3JlZW5FbmFibGVkIHx8XG4gICAgICAgICAgICAod2luZG93LmRvY3VtZW50OiBhbnkpLndlYmtpdEZ1bGxzY3JlZW5FbmFibGVkXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgX3NldHVwVUkoKSB7XG4gICAgICAgIGNvbnN0IGJ1dHRvbiA9IHRoaXMuX2Z1bGxzY3JlZW5CdXR0b24gPSBET00uY3JlYXRlKCdidXR0b24nLCAoYG1hcGJveGdsLWN0cmwtZnVsbHNjcmVlbmApLCB0aGlzLl9jb250cm9sQ29udGFpbmVyKTtcbiAgICAgICAgRE9NLmNyZWF0ZSgnc3BhbicsIGBtYXBib3hnbC1jdHJsLWljb25gLCBidXR0b24pLnNldEF0dHJpYnV0ZSgnYXJpYS1oaWRkZW4nLCAndHJ1ZScpO1xuICAgICAgICBidXR0b24udHlwZSA9ICdidXR0b24nO1xuICAgICAgICB0aGlzLl91cGRhdGVUaXRsZSgpO1xuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIHRoaXMuX2Z1bGxzY3JlZW5CdXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9vbkNsaWNrRnVsbHNjcmVlbik7XG4gICAgICAgIC8vICRGbG93Rml4TWVbbWV0aG9kLXVuYmluZGluZ11cbiAgICAgICAgd2luZG93LmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIodGhpcy5fZnVsbHNjcmVlbmNoYW5nZSwgdGhpcy5fY2hhbmdlSWNvbik7XG4gICAgfVxuXG4gICAgX3VwZGF0ZVRpdGxlKCkge1xuICAgICAgICBjb25zdCB0aXRsZSA9IHRoaXMuX2dldFRpdGxlKCk7XG4gICAgICAgIHRoaXMuX2Z1bGxzY3JlZW5CdXR0b24uc2V0QXR0cmlidXRlKFwiYXJpYS1sYWJlbFwiLCB0aXRsZSk7XG4gICAgICAgIGlmICh0aGlzLl9mdWxsc2NyZWVuQnV0dG9uLmZpcnN0RWxlbWVudENoaWxkKSB0aGlzLl9mdWxsc2NyZWVuQnV0dG9uLmZpcnN0RWxlbWVudENoaWxkLnNldEF0dHJpYnV0ZSgndGl0bGUnLCB0aXRsZSk7XG4gICAgfVxuXG4gICAgX2dldFRpdGxlKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXAuX2dldFVJU3RyaW5nKHRoaXMuX2lzRnVsbHNjcmVlbigpID8gJ0Z1bGxzY3JlZW5Db250cm9sLkV4aXQnIDogJ0Z1bGxzY3JlZW5Db250cm9sLkVudGVyJyk7XG4gICAgfVxuXG4gICAgX2lzRnVsbHNjcmVlbigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Z1bGxzY3JlZW47XG4gICAgfVxuXG4gICAgX2NoYW5nZUljb24oKSB7XG4gICAgICAgIGNvbnN0IGZ1bGxzY3JlZW5FbGVtZW50ID1cbiAgICAgICAgICAgIHdpbmRvdy5kb2N1bWVudC5mdWxsc2NyZWVuRWxlbWVudCB8fFxuICAgICAgICAgICAgKHdpbmRvdy5kb2N1bWVudDogYW55KS53ZWJraXRGdWxsc2NyZWVuRWxlbWVudDtcblxuICAgICAgICBpZiAoKGZ1bGxzY3JlZW5FbGVtZW50ID09PSB0aGlzLl9jb250YWluZXIpICE9PSB0aGlzLl9mdWxsc2NyZWVuKSB7XG4gICAgICAgICAgICB0aGlzLl9mdWxsc2NyZWVuID0gIXRoaXMuX2Z1bGxzY3JlZW47XG4gICAgICAgICAgICB0aGlzLl9mdWxsc2NyZWVuQnV0dG9uLmNsYXNzTGlzdC50b2dnbGUoYG1hcGJveGdsLWN0cmwtc2hyaW5rYCk7XG4gICAgICAgICAgICB0aGlzLl9mdWxsc2NyZWVuQnV0dG9uLmNsYXNzTGlzdC50b2dnbGUoYG1hcGJveGdsLWN0cmwtZnVsbHNjcmVlbmApO1xuICAgICAgICAgICAgdGhpcy5fdXBkYXRlVGl0bGUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9vbkNsaWNrRnVsbHNjcmVlbigpIHtcbiAgICAgICAgaWYgKHRoaXMuX2lzRnVsbHNjcmVlbigpKSB7XG4gICAgICAgICAgICBpZiAod2luZG93LmRvY3VtZW50LmV4aXRGdWxsc2NyZWVuKSB7XG4gICAgICAgICAgICAgICAgKHdpbmRvdy5kb2N1bWVudDogYW55KS5leGl0RnVsbHNjcmVlbigpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh3aW5kb3cuZG9jdW1lbnQud2Via2l0Q2FuY2VsRnVsbFNjcmVlbikge1xuICAgICAgICAgICAgICAgICh3aW5kb3cuZG9jdW1lbnQ6IGFueSkud2Via2l0Q2FuY2VsRnVsbFNjcmVlbigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAvLyAkRmxvd0ZpeE1lW21ldGhvZC11bmJpbmRpbmddXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5fY29udGFpbmVyLnJlcXVlc3RGdWxsc2NyZWVuKSB7XG4gICAgICAgICAgICB0aGlzLl9jb250YWluZXIucmVxdWVzdEZ1bGxzY3JlZW4oKTtcbiAgICAgICAgfSBlbHNlIGlmICgodGhpcy5fY29udGFpbmVyOiBhbnkpLndlYmtpdFJlcXVlc3RGdWxsc2NyZWVuKSB7XG4gICAgICAgICAgICAodGhpcy5fY29udGFpbmVyOiBhbnkpLndlYmtpdFJlcXVlc3RGdWxsc2NyZWVuKCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEZ1bGxzY3JlZW5Db250cm9sO1xuIiwiLy8gQGZsb3dcblxuaW1wb3J0IHdpbmRvdyBmcm9tICcuLi91dGlsL3dpbmRvdy5qcyc7XG5cbmltcG9ydCBEaXNwYXRjaGVyIGZyb20gJy4vZGlzcGF0Y2hlci5qcyc7XG5pbXBvcnQgZ2V0V29ya2VyUG9vbCBmcm9tICcuL2dsb2JhbF93b3JrZXJfcG9vbC5qcyc7XG5pbXBvcnQge1BlcmZvcm1hbmNlVXRpbHN9IGZyb20gJy4vcGVyZm9ybWFuY2UuanMnO1xuXG5jb25zdCBwZXJmb3JtYW5jZSA9IHdpbmRvdy5wZXJmb3JtYW5jZTtcblxuLy8gc2VwYXJhdGUgZnJvbSBQZXJmb3JtYW5jZVV0aWxzIHRvIGF2b2lkIGNpcmN1bGFyIGRlcGVuZGVuY3lcblxuZXhwb3J0IGNvbnN0IFdvcmtlclBlcmZvcm1hbmNlVXRpbHMgPSB7XG5cbiAgICBnZXRQZXJmb3JtYW5jZU1ldHJpY3NBc3luYyhjYWxsYmFjazogKGVycm9yOiA/RXJyb3IsIHJlc3VsdDogP09iamVjdCkgPT4gdm9pZCkge1xuICAgICAgICBjb25zdCBtZXRyaWNzID0gUGVyZm9ybWFuY2VVdGlscy5nZXRQZXJmb3JtYW5jZU1ldHJpY3MoKTtcbiAgICAgICAgY29uc3QgZGlzcGF0Y2hlciA9IG5ldyBEaXNwYXRjaGVyKGdldFdvcmtlclBvb2woKSwgV29ya2VyUGVyZm9ybWFuY2VVdGlscyk7XG5cbiAgICAgICAgY29uc3QgY3JlYXRlVGltZSA9IHBlcmZvcm1hbmNlLmdldEVudHJpZXNCeU5hbWUoJ2NyZWF0ZScsICdtYXJrJylbMF0uc3RhcnRUaW1lO1xuXG4gICAgICAgIGRpc3BhdGNoZXIuYnJvYWRjYXN0KCdnZXRXb3JrZXJQZXJmb3JtYW5jZU1ldHJpY3MnLCB7fSwgKGVyciwgcmVzdWx0cykgPT4ge1xuICAgICAgICAgICAgZGlzcGF0Y2hlci5yZW1vdmUoKTtcbiAgICAgICAgICAgIGlmIChlcnIpIHJldHVybiBjYWxsYmFjayhlcnIpO1xuXG4gICAgICAgICAgICBjb25zdCBzdW1zID0ge307XG5cbiAgICAgICAgICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIHJlc3VsdHMpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IG1lYXN1cmUgb2YgcmVzdWx0LmVudHJpZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1lYXN1cmUuZW50cnlUeXBlICE9PSAnbWVhc3VyZScpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICBzdW1zW21lYXN1cmUubmFtZV0gPSAoc3Vtc1ttZWFzdXJlLm5hbWVdIHx8IDApICsgbWVhc3VyZS5kdXJhdGlvbjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBzdW1zLndvcmtlckluaXRpYWxpemF0aW9uID0gcmVzdWx0LnRpbWVPcmlnaW4gLSBwZXJmb3JtYW5jZS50aW1lT3JpZ2luIC0gY3JlYXRlVGltZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9yIChjb25zdCBuYW1lIGluIHN1bXMpIHtcbiAgICAgICAgICAgICAgICBtZXRyaWNzW25hbWVdID0gc3Vtc1tuYW1lXSAvIHJlc3VsdHMubGVuZ3RoO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBtZXRyaWNzLndvcmtlcklkbGUgPSBtZXRyaWNzLmxvYWRUaW1lIC0gbWV0cmljcy53b3JrZXJJbml0aWFsaXphdGlvbiAtIG1ldHJpY3Mud29ya2VyRXZhbHVhdGVTY3JpcHQgLSBtZXRyaWNzLndvcmtlclRhc2s7XG4gICAgICAgICAgICBtZXRyaWNzLndvcmtlcklkbGVQZXJjZW50ID0gbWV0cmljcy53b3JrZXJJZGxlIC8gbWV0cmljcy5sb2FkVGltZTtcblxuICAgICAgICAgICAgbWV0cmljcy5wYXJzZVRpbGUgPSBtZXRyaWNzLnBhcnNlVGlsZTEgKyBtZXRyaWNzLnBhcnNlVGlsZTI7XG5cbiAgICAgICAgICAgIG1ldHJpY3MudGltZWxpbmVzID0gW1BlcmZvcm1hbmNlVXRpbHMuZ2V0V29ya2VyUGVyZm9ybWFuY2VNZXRyaWNzKCksIC4uLnJlc3VsdHNdO1xuXG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2sodW5kZWZpbmVkLCBtZXRyaWNzKTtcbiAgICAgICAgfSk7XG4gICAgfVxufTtcbiIsIi8vIEBmbG93XG5cbmltcG9ydCB7UGVyZm9ybWFuY2VVdGlsc30gZnJvbSAnLi91dGlsL3BlcmZvcm1hbmNlLmpzJztcblxuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHtzdXBwb3J0ZWR9IGZyb20gJ0BtYXBib3gvbWFwYm94LWdsLXN1cHBvcnRlZCc7XG5cbmltcG9ydCB7dmVyc2lvbn0gZnJvbSAnLi4vcGFja2FnZS5qc29uJztcbmltcG9ydCBNYXAgZnJvbSAnLi91aS9tYXAuanMnO1xuaW1wb3J0IE5hdmlnYXRpb25Db250cm9sIGZyb20gJy4vdWkvY29udHJvbC9uYXZpZ2F0aW9uX2NvbnRyb2wuanMnO1xuaW1wb3J0IEdlb2xvY2F0ZUNvbnRyb2wgZnJvbSAnLi91aS9jb250cm9sL2dlb2xvY2F0ZV9jb250cm9sLmpzJztcbmltcG9ydCBBdHRyaWJ1dGlvbkNvbnRyb2wgZnJvbSAnLi91aS9jb250cm9sL2F0dHJpYnV0aW9uX2NvbnRyb2wuanMnO1xuaW1wb3J0IFNjYWxlQ29udHJvbCBmcm9tICcuL3VpL2NvbnRyb2wvc2NhbGVfY29udHJvbC5qcyc7XG5pbXBvcnQgRnVsbHNjcmVlbkNvbnRyb2wgZnJvbSAnLi91aS9jb250cm9sL2Z1bGxzY3JlZW5fY29udHJvbC5qcyc7XG5pbXBvcnQgUG9wdXAgZnJvbSAnLi91aS9wb3B1cC5qcyc7XG5pbXBvcnQgTWFya2VyIGZyb20gJy4vdWkvbWFya2VyLmpzJztcbmltcG9ydCBTdHlsZSBmcm9tICcuL3N0eWxlL3N0eWxlLmpzJztcbmltcG9ydCBMbmdMYXQgZnJvbSAnLi9nZW8vbG5nX2xhdC5qcyc7XG5pbXBvcnQgTG5nTGF0Qm91bmRzIGZyb20gJy4vZ2VvL2xuZ19sYXRfYm91bmRzLmpzJztcbmltcG9ydCBQb2ludCBmcm9tICdAbWFwYm94L3BvaW50LWdlb21ldHJ5JztcbmltcG9ydCBNZXJjYXRvckNvb3JkaW5hdGUgZnJvbSAnLi9nZW8vbWVyY2F0b3JfY29vcmRpbmF0ZS5qcyc7XG5pbXBvcnQge0V2ZW50ZWR9IGZyb20gJy4vdXRpbC9ldmVudGVkLmpzJztcbmltcG9ydCBjb25maWcgZnJvbSAnLi91dGlsL2NvbmZpZy5qcyc7XG5pbXBvcnQge0RlYnVnfSBmcm9tICcuL3V0aWwvZGVidWcuanMnO1xuaW1wb3J0IHtpc1NhZmFyaX0gZnJvbSAnLi91dGlsL3V0aWwuanMnO1xuaW1wb3J0IHtzZXRSVExUZXh0UGx1Z2luLCBnZXRSVExUZXh0UGx1Z2luU3RhdHVzfSBmcm9tICcuL3NvdXJjZS9ydGxfdGV4dF9wbHVnaW4uanMnO1xuaW1wb3J0IFdvcmtlclBvb2wgZnJvbSAnLi91dGlsL3dvcmtlcl9wb29sLmpzJztcbmltcG9ydCB7cHJld2FybSwgY2xlYXJQcmV3YXJtZWRSZXNvdXJjZXN9IGZyb20gJy4vdXRpbC9nbG9iYWxfd29ya2VyX3Bvb2wuanMnO1xuaW1wb3J0IHtjbGVhclRpbGVDYWNoZX0gZnJvbSAnLi91dGlsL3RpbGVfcmVxdWVzdF9jYWNoZS5qcyc7XG5pbXBvcnQge1dvcmtlclBlcmZvcm1hbmNlVXRpbHN9IGZyb20gJy4vdXRpbC93b3JrZXJfcGVyZm9ybWFuY2VfdXRpbHMuanMnO1xuaW1wb3J0IHtGcmVlQ2FtZXJhT3B0aW9uc30gZnJvbSAnLi91aS9mcmVlX2NhbWVyYS5qcyc7XG5pbXBvcnQgYnJvd3NlciBmcm9tICcuL3V0aWwvYnJvd3Nlci5qcyc7XG5cbmNvbnN0IGV4cG9ydGVkID0ge1xuICAgIHZlcnNpb24sXG4gICAgc3VwcG9ydGVkLFxuICAgIHNldFJUTFRleHRQbHVnaW4sXG4gICAgZ2V0UlRMVGV4dFBsdWdpblN0YXR1cyxcbiAgICBNYXAsXG4gICAgTmF2aWdhdGlvbkNvbnRyb2wsXG4gICAgR2VvbG9jYXRlQ29udHJvbCxcbiAgICBBdHRyaWJ1dGlvbkNvbnRyb2wsXG4gICAgU2NhbGVDb250cm9sLFxuICAgIEZ1bGxzY3JlZW5Db250cm9sLFxuICAgIFBvcHVwLFxuICAgIE1hcmtlcixcbiAgICBTdHlsZSxcbiAgICBMbmdMYXQsXG4gICAgTG5nTGF0Qm91bmRzLFxuICAgIFBvaW50LFxuICAgIE1lcmNhdG9yQ29vcmRpbmF0ZSxcbiAgICBGcmVlQ2FtZXJhT3B0aW9ucyxcbiAgICBFdmVudGVkLFxuICAgIGNvbmZpZyxcbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplcyByZXNvdXJjZXMgbGlrZSBXZWJXb3JrZXJzIHRoYXQgY2FuIGJlIHNoYXJlZCBhY3Jvc3MgbWFwcyB0byBsb3dlciBsb2FkXG4gICAgICogdGltZXMgaW4gc29tZSBzaXR1YXRpb25zLiBbYG1hcGJveGdsLndvcmtlclVybGBdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9hcGkvcHJvcGVydGllcy8jd29ya2VydXJsKVxuICAgICAqIGFuZCBbYG1hcGJveGdsLndvcmtlckNvdW50YF0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2FwaS9wcm9wZXJ0aWVzLyN3b3JrZXJjb3VudCksIGlmIGJlaW5nXG4gICAgICogdXNlZCwgbXVzdCBiZSBzZXQgYmVmb3JlIGBwcmV3YXJtKClgIGlzIGNhbGxlZCB0byBoYXZlIGFuIGVmZmVjdC5cbiAgICAgKlxuICAgICAqIEJ5IGRlZmF1bHQsIHRoZSBsaWZlY3ljbGUgb2YgdGhlc2UgcmVzb3VyY2VzIGlzIG1hbmFnZWQgYXV0b21hdGljYWxseSwgYW5kIHRoZXkgYXJlXG4gICAgICogbGF6aWx5IGluaXRpYWxpemVkIHdoZW4gYSBgTWFwYCBpcyBmaXJzdCBjcmVhdGVkLiBJbnZva2luZyBgcHJld2FybSgpYCBjcmVhdGVzIHRoZXNlXG4gICAgICogcmVzb3VyY2VzIGFoZWFkIG9mIHRpbWUgYW5kIGVuc3VyZXMgdGhleSBhcmUgbm90IGNsZWFyZWQgd2hlbiB0aGUgbGFzdCBgTWFwYFxuICAgICAqIGlzIHJlbW92ZWQgZnJvbSB0aGUgcGFnZS4gVGhpcyBhbGxvd3MgdGhlbSB0byBiZSByZS11c2VkIGJ5IG5ldyBgTWFwYCBpbnN0YW5jZXMgdGhhdFxuICAgICAqIGFyZSBjcmVhdGVkIGxhdGVyLiBUaGV5IGNhbiBiZSBtYW51YWxseSBjbGVhcmVkIGJ5IGNhbGxpbmdcbiAgICAgKiBbYG1hcGJveGdsLmNsZWFyUHJld2FybWVkUmVzb3VyY2VzKClgXShodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvYXBpL3Byb3BlcnRpZXMvI2NsZWFycHJld2FybWVkcmVzb3VyY2VzKS5cbiAgICAgKiBUaGlzIGlzIG9ubHkgbmVjZXNzYXJ5IGlmIHlvdXIgd2ViIHBhZ2UgcmVtYWlucyBhY3RpdmUgYnV0IHN0b3BzIHVzaW5nIG1hcHMgYWx0b2dldGhlci5cbiAgICAgKiBgcHJld2FybSgpYCBpcyBpZGVtcG90ZW50IGFuZCBoYXMgZ3VhcmRzIGFnYWluc3QgYmVpbmcgZXhlY3V0ZWQgbXVsdGlwbGUgdGltZXMsXG4gICAgICogYW5kIGFueSByZXNvdXJjZXMgYWxsb2NhdGVkIGJ5IGBwcmV3YXJtKClgIGFyZSBjcmVhdGVkIHN5bmNocm9ub3VzbHkuXG4gICAgICpcbiAgICAgKiBUaGlzIGlzIHByaW1hcmlseSB1c2VmdWwgd2hlbiB1c2luZyBNYXBib3ggR0wgSlMgbWFwcyBpbiBhIHNpbmdsZSBwYWdlIGFwcCxcbiAgICAgKiBpbiB3aGljaCBhIHVzZXIgbmF2aWdhdGVzIGJldHdlZW4gdmFyaW91cyB2aWV3cywgcmVzdWx0aW5nIGluXG4gICAgICogY29uc3RhbnQgY3JlYXRpb24gYW5kIGRlc3RydWN0aW9uIG9mIGBNYXBgIGluc3RhbmNlcy5cbiAgICAgKlxuICAgICAqIEBmdW5jdGlvbiBwcmV3YXJtXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXBib3hnbC5wcmV3YXJtKCk7XG4gICAgICovXG4gICAgcHJld2FybSxcbiAgICAvKipcbiAgICAgKiBDbGVhcnMgdXAgcmVzb3VyY2VzIHRoYXQgaGF2ZSBwcmV2aW91c2x5IGJlZW4gY3JlYXRlZCBieSBbYG1hcGJveGdsLnByZXdhcm0oKV0oaHR0cHM6Ly9kb2NzLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL2FwaS9wcm9wZXJ0aWVzLyNwcmV3YXJtKWAuXG4gICAgICogTm90ZSB0aGF0IHRoaXMgaXMgdHlwaWNhbGx5IG5vdCBuZWNlc3NhcnkuIFlvdSBzaG91bGQgb25seSBjYWxsIHRoaXMgZnVuY3Rpb25cbiAgICAgKiBpZiB5b3UgZXhwZWN0IHRoZSB1c2VyIG9mIHlvdXIgYXBwIHRvIG5vdCByZXR1cm4gdG8gYSBNYXAgdmlldyBhdCBhbnkgcG9pbnRcbiAgICAgKiBpbiB5b3VyIGFwcGxpY2F0aW9uLlxuICAgICAqXG4gICAgICogQGZ1bmN0aW9uIGNsZWFyUHJld2FybWVkUmVzb3VyY2VzXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXBib3hnbC5jbGVhclByZXdhcm1lZFJlc291cmNlcygpO1xuICAgICAqL1xuICAgIGNsZWFyUHJld2FybWVkUmVzb3VyY2VzLFxuXG4gICAgLyoqXG4gICAgICogR2V0cyBhbmQgc2V0cyB0aGUgbWFwJ3MgW2FjY2VzcyB0b2tlbl0oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9oZWxwL2RlZmluZS1hY2Nlc3MtdG9rZW4vKS5cbiAgICAgKlxuICAgICAqIEB2YXIge3N0cmluZ30gYWNjZXNzVG9rZW5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgY3VycmVudGx5IHNldCBhY2Nlc3MgdG9rZW4uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXBib3hnbC5hY2Nlc3NUb2tlbiA9IG15QWNjZXNzVG9rZW47XG4gICAgICogQHNlZSBbRXhhbXBsZTogRGlzcGxheSBhIG1hcF0oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9zaW1wbGUtbWFwLylcbiAgICAgKi9cbiAgICBnZXQgYWNjZXNzVG9rZW4oKTogP3N0cmluZyB7XG4gICAgICAgIHJldHVybiBjb25maWcuQUNDRVNTX1RPS0VOO1xuICAgIH0sXG5cbiAgICBzZXQgYWNjZXNzVG9rZW4odG9rZW46IHN0cmluZykge1xuICAgICAgICBjb25maWcuQUNDRVNTX1RPS0VOID0gdG9rZW47XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldHMgYW5kIHNldHMgdGhlIG1hcCdzIGRlZmF1bHQgQVBJIFVSTCBmb3IgcmVxdWVzdGluZyB0aWxlcywgc3R5bGVzLCBzcHJpdGVzLCBhbmQgZ2x5cGhzLlxuICAgICAqXG4gICAgICogQHZhciB7c3RyaW5nfSBiYXNlQXBpVXJsXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGN1cnJlbnQgYmFzZSBBUEkgVVJMLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogbWFwYm94Z2wuYmFzZUFwaVVybCA9ICdodHRwczovL2FwaS5tYXBib3guY29tJztcbiAgICAgKi9cbiAgICBnZXQgYmFzZUFwaVVybCgpOiA/c3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIGNvbmZpZy5BUElfVVJMO1xuICAgIH0sXG5cbiAgICBzZXQgYmFzZUFwaVVybCh1cmw6IHN0cmluZykge1xuICAgICAgICBjb25maWcuQVBJX1VSTCA9IHVybDtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0cyBhbmQgc2V0cyB0aGUgbnVtYmVyIG9mIHdlYiB3b3JrZXJzIGluc3RhbnRpYXRlZCBvbiBhIHBhZ2Ugd2l0aCBNYXBib3ggR0wgSlMgbWFwcy5cbiAgICAgKiBCeSBkZWZhdWx0LCBpdCBpcyBzZXQgdG8gMi5cbiAgICAgKiBNYWtlIHN1cmUgdG8gc2V0IHRoaXMgcHJvcGVydHkgYmVmb3JlIGNyZWF0aW5nIGFueSBtYXAgaW5zdGFuY2VzIGZvciBpdCB0byBoYXZlIGVmZmVjdC5cbiAgICAgKlxuICAgICAqIEB2YXIge3N0cmluZ30gd29ya2VyQ291bnRcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBOdW1iZXIgb2Ygd29ya2VycyBjdXJyZW50bHkgY29uZmlndXJlZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIG1hcGJveGdsLndvcmtlckNvdW50ID0gNDtcbiAgICAgKi9cbiAgICBnZXQgd29ya2VyQ291bnQoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIFdvcmtlclBvb2wud29ya2VyQ291bnQ7XG4gICAgfSxcblxuICAgIHNldCB3b3JrZXJDb3VudChjb3VudDogbnVtYmVyKSB7XG4gICAgICAgIFdvcmtlclBvb2wud29ya2VyQ291bnQgPSBjb3VudDtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0cyBhbmQgc2V0cyB0aGUgbWF4aW11bSBudW1iZXIgb2YgaW1hZ2VzIChyYXN0ZXIgdGlsZXMsIHNwcml0ZXMsIGljb25zKSB0byBsb2FkIGluIHBhcmFsbGVsLlxuICAgICAqIDE2IGJ5IGRlZmF1bHQuIFRoZXJlIGlzIG5vIG1heGltdW0gdmFsdWUsIGJ1dCB0aGUgbnVtYmVyIG9mIGltYWdlcyBhZmZlY3RzIHBlcmZvcm1hbmNlIGluIHJhc3Rlci1oZWF2eSBtYXBzLlxuICAgICAqXG4gICAgICogQHZhciB7c3RyaW5nfSBtYXhQYXJhbGxlbEltYWdlUmVxdWVzdHNcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBOdW1iZXIgb2YgcGFyYWxsZWwgcmVxdWVzdHMgY3VycmVudGx5IGNvbmZpZ3VyZWQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXBib3hnbC5tYXhQYXJhbGxlbEltYWdlUmVxdWVzdHMgPSAxMDtcbiAgICAgKi9cbiAgICBnZXQgbWF4UGFyYWxsZWxJbWFnZVJlcXVlc3RzKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiBjb25maWcuTUFYX1BBUkFMTEVMX0lNQUdFX1JFUVVFU1RTO1xuICAgIH0sXG5cbiAgICBzZXQgbWF4UGFyYWxsZWxJbWFnZVJlcXVlc3RzKG51bVJlcXVlc3RzOiBudW1iZXIpIHtcbiAgICAgICAgY29uZmlnLk1BWF9QQVJBTExFTF9JTUFHRV9SRVFVRVNUUyA9IG51bVJlcXVlc3RzO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDbGVhcnMgYnJvd3NlciBzdG9yYWdlIHVzZWQgYnkgdGhpcyBsaWJyYXJ5LiBVc2luZyB0aGlzIG1ldGhvZCBmbHVzaGVzIHRoZSBNYXBib3ggdGlsZVxuICAgICAqIGNhY2hlIHRoYXQgaXMgbWFuYWdlZCBieSB0aGlzIGxpYnJhcnkuIFRpbGVzIG1heSBzdGlsbCBiZSBjYWNoZWQgYnkgdGhlIGJyb3dzZXJcbiAgICAgKiBpbiBzb21lIGNhc2VzLlxuICAgICAqXG4gICAgICogVGhpcyBBUEkgaXMgc3VwcG9ydGVkIG9uIGJyb3dzZXJzIHdoZXJlIHRoZSBbYENhY2hlYCBBUEldKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9DYWNoZSlcbiAgICAgKiBpcyBzdXBwb3J0ZWQgYW5kIGVuYWJsZWQuIFRoaXMgaW5jbHVkZXMgYWxsIG1ham9yIGJyb3dzZXJzIHdoZW4gcGFnZXMgYXJlIHNlcnZlZCBvdmVyXG4gICAgICogYGh0dHBzOi8vYCwgZXhjZXB0IEludGVybmV0IEV4cGxvcmVyIGFuZCBFZGdlIE1vYmlsZS5cbiAgICAgKlxuICAgICAqIFdoZW4gY2FsbGVkIGluIHVuc3VwcG9ydGVkIGJyb3dzZXJzIG9yIGVudmlyb25tZW50cyAocHJpdmF0ZSBvciBpbmNvZ25pdG8gbW9kZSksIHRoZVxuICAgICAqIGNhbGxiYWNrIHdpbGwgYmUgY2FsbGVkIHdpdGggYW4gZXJyb3IgYXJndW1lbnQuXG4gICAgICpcbiAgICAgKiBAZnVuY3Rpb24gY2xlYXJTdG9yYWdlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgQ2FsbGVkIHdpdGggYW4gZXJyb3IgYXJndW1lbnQgaWYgdGhlcmUgaXMgYW4gZXJyb3IuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBtYXBib3hnbC5jbGVhclN0b3JhZ2UoKTtcbiAgICAgKi9cbiAgICBjbGVhclN0b3JhZ2UoY2FsbGJhY2s/OiAoZXJyOiA/RXJyb3IpID0+IHZvaWQpIHtcbiAgICAgICAgY2xlYXJUaWxlQ2FjaGUoY2FsbGJhY2spO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogUHJvdmlkZXMgYW4gaW50ZXJmYWNlIGZvciBsb2FkaW5nIG1hcGJveC1nbCdzIFdlYldvcmtlciBidW5kbGUgZnJvbSBhIHNlbGYtaG9zdGVkIFVSTC5cbiAgICAgKiBUaGlzIG5lZWRzIHRvIGJlIHNldCBvbmx5IG9uY2UsIGFuZCBiZWZvcmUgYW55IGNhbGwgdG8gYG5ldyBtYXBib3hnbC5NYXAoLi4pYCB0YWtlcyBwbGFjZS5cbiAgICAgKiBUaGlzIGlzIHVzZWZ1bCBpZiB5b3VyIHNpdGUgbmVlZHMgdG8gb3BlcmF0ZSBpbiBhIHN0cmljdCBDU1AgKENvbnRlbnQgU2VjdXJpdHkgUG9saWN5KSBlbnZpcm9ubWVudFxuICAgICAqIHdoZXJlaW4geW91IGFyZSBub3QgYWxsb3dlZCB0byBsb2FkIEphdmFTY3JpcHQgY29kZSBmcm9tIGEgW2BCbG9iYCBVUkxdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9VUkwvY3JlYXRlT2JqZWN0VVJMKSwgd2hpY2ggaXMgZGVmYXVsdCBiZWhhdmlvci5cbiAgICAgKlxuICAgICAqIFNlZSBvdXIgZG9jdW1lbnRhdGlvbiBvbiBbQ1NQIERpcmVjdGl2ZXNdKGh0dHBzOi8vZG9jcy5tYXBib3guY29tL21hcGJveC1nbC1qcy9hcGkvI2NzcC1kaXJlY3RpdmVzKSBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqXG4gICAgICogQHZhciB7c3RyaW5nfSB3b3JrZXJVcmxcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBBIFVSTCBob3N0aW5nIGEgSmF2YVNjcmlwdCBidW5kbGUgZm9yIG1hcGJveC1nbCdzIFdlYldvcmtlci5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIDxzY3JpcHQgc3JjPSdodHRwczovL2FwaS5tYXBib3guY29tL21hcGJveC1nbC1qcy92Mi4zLjEvbWFwYm94LWdsLWNzcC5qcyc+PC9zY3JpcHQ+XG4gICAgICogPHNjcmlwdD5cbiAgICAgKiBtYXBib3hnbC53b3JrZXJVcmwgPSBcImh0dHBzOi8vYXBpLm1hcGJveC5jb20vbWFwYm94LWdsLWpzL3YyLjMuMS9tYXBib3gtZ2wtY3NwLXdvcmtlci5qc1wiO1xuICAgICAqIC4uLlxuICAgICAqIDwvc2NyaXB0PlxuICAgICAqL1xuICAgIHdvcmtlclVybDogJycsXG5cbiAgICAvKipcbiAgICAgKiBQcm92aWRlcyBhbiBpbnRlcmZhY2UgZm9yIGV4dGVybmFsIG1vZHVsZSBidW5kbGVycyBzdWNoIGFzIFdlYnBhY2sgb3IgUm9sbHVwIHRvIHBhY2thZ2VcbiAgICAgKiBtYXBib3gtZ2wncyBXZWJXb3JrZXIgaW50byBhIHNlcGFyYXRlIGNsYXNzIGFuZCBpbnRlZ3JhdGUgaXQgd2l0aCB0aGUgbGlicmFyeS5cbiAgICAgKlxuICAgICAqIFRha2VzIHByZWNlZGVuY2Ugb3ZlciBgbWFwYm94Z2wud29ya2VyVXJsYC5cbiAgICAgKlxuICAgICAqIEB2YXIge09iamVjdH0gd29ya2VyQ2xhc3NcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0IHwgbnVsbH0gQSBjbGFzcyB0aGF0IGltcGxlbWVudHMgdGhlIGBXb3JrZXJgIGludGVyZmFjZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGltcG9ydCBtYXBib3hnbCBmcm9tICdtYXBib3gtZ2wvZGlzdC9tYXBib3gtZ2wtY3NwLmpzJztcbiAgICAgKiBpbXBvcnQgTWFwYm94R0xXb3JrZXIgZnJvbSAnbWFwYm94LWdsL2Rpc3QvbWFwYm94LWdsLWNzcC13b3JrZXIuanMnO1xuICAgICAqXG4gICAgICogbWFwYm94Z2wud29ya2VyQ2xhc3MgPSBNYXBib3hHTFdvcmtlcjtcbiAgICAgKi9cbiAgICB3b3JrZXJDbGFzczogbnVsbCxcblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHRpbWUgdXNlZCBieSBNYXBib3ggR0wgSlMgaW50ZXJuYWxseSBmb3IgYWxsIGFuaW1hdGlvbnMuIFVzZWZ1bCBmb3IgZ2VuZXJhdGluZyB2aWRlb3MgZnJvbSBNYXBib3ggR0wgSlMuXG4gICAgICpcbiAgICAgKiBAdmFyIHtudW1iZXJ9IHRpbWVcbiAgICAgKi9cbiAgICBzZXROb3c6IGJyb3dzZXIuc2V0Tm93LFxuXG4gICAgLyoqXG4gICAgICogUmVzdG9yZXMgdGhlIGludGVybmFsIGFuaW1hdGlvbiB0aW1pbmcgdG8gZm9sbG93IHJlZ3VsYXIgY29tcHV0ZXIgdGltZSAoYHBlcmZvcm1hbmNlLm5vdygpYCkuXG4gICAgICovXG4gICAgcmVzdG9yZU5vdzogYnJvd3Nlci5yZXN0b3JlTm93XG59O1xuXG4vL1RoaXMgZ2V0cyBhdXRvbWF0aWNhbGx5IHN0cmlwcGVkIG91dCBpbiBwcm9kdWN0aW9uIGJ1aWxkcy5cbkRlYnVnLmV4dGVuZChleHBvcnRlZCwge2lzU2FmYXJpLCBnZXRQZXJmb3JtYW5jZU1ldHJpY3M6IFBlcmZvcm1hbmNlVXRpbHMuZ2V0UGVyZm9ybWFuY2VNZXRyaWNzLCBnZXRQZXJmb3JtYW5jZU1ldHJpY3NBc3luYzogV29ya2VyUGVyZm9ybWFuY2VVdGlscy5nZXRQZXJmb3JtYW5jZU1ldHJpY3NBc3luY30pO1xuXG4vKipcbiAqIEdldHMgdGhlIHZlcnNpb24gb2YgTWFwYm94IEdMIEpTIGluIHVzZSBhcyBzcGVjaWZpZWQgaW4gYHBhY2thZ2UuanNvbmAsXG4gKiBgQ0hBTkdFTE9HLm1kYCwgYW5kIHRoZSBHaXRIdWIgcmVsZWFzZS5cbiAqXG4gKiBAdmFyIHtzdHJpbmd9IHZlcnNpb25cbiAqIEBleGFtcGxlXG4gKiBjb25zb2xlLmxvZyhgTWFwYm94IEdMIEpTIHYke21hcGJveGdsLnZlcnNpb259YCk7XG4gKi9cblxuLyoqXG4gKiBUZXN0IHdoZXRoZXIgdGhlIGJyb3dzZXIgW3N1cHBvcnRzIE1hcGJveCBHTCBKU10oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9oZWxwL21hcGJveC1icm93c2VyLXN1cHBvcnQvI21hcGJveC1nbC1qcykuXG4gKlxuICogQGZ1bmN0aW9uIHN1cHBvcnRlZFxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5mYWlsSWZNYWpvclBlcmZvcm1hbmNlQ2F2ZWF0PWZhbHNlXSBJZiBgdHJ1ZWAsXG4gKiAgIHRoZSBmdW5jdGlvbiB3aWxsIHJldHVybiBgZmFsc2VgIGlmIHRoZSBwZXJmb3JtYW5jZSBvZiBNYXBib3ggR0wgSlMgd291bGRcbiAqICAgYmUgZHJhbWF0aWNhbGx5IHdvcnNlIHRoYW4gZXhwZWN0ZWQgKGZvciBleGFtcGxlLCBhIHNvZnR3YXJlIFdlYkdMIHJlbmRlcmVyXG4gKiAgIHdvdWxkIGJlIHVzZWQpLlxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqIEBleGFtcGxlXG4gKiAvLyBTaG93IGFuIGFsZXJ0IGlmIHRoZSBicm93c2VyIGRvZXMgbm90IHN1cHBvcnQgTWFwYm94IEdMXG4gKiBpZiAoIW1hcGJveGdsLnN1cHBvcnRlZCgpKSB7XG4gKiAgICAgYWxlcnQoJ1lvdXIgYnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IE1hcGJveCBHTCcpO1xuICogfVxuICogQHNlZSBbRXhhbXBsZTogQ2hlY2sgZm9yIGJyb3dzZXIgc3VwcG9ydF0oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9jaGVjay1mb3Itc3VwcG9ydC8pXG4gKi9cblxuLyoqXG4gKiBTZXRzIHRoZSBtYXAncyBbUlRMIHRleHQgcGx1Z2luXShodHRwczovL3d3dy5tYXBib3guY29tL21hcGJveC1nbC1qcy9wbHVnaW5zLyNtYXBib3gtZ2wtcnRsLXRleHQpLlxuICogTmVjZXNzYXJ5IGZvciBzdXBwb3J0aW5nIHRoZSBBcmFiaWMgYW5kIEhlYnJldyBsYW5ndWFnZXMsIHdoaWNoIGFyZSB3cml0dGVuIHJpZ2h0LXRvLWxlZnQuIE1hcGJveCBTdHVkaW8gbG9hZHMgdGhpcyBwbHVnaW4gYnkgZGVmYXVsdC5cbiAqXG4gKiBAZnVuY3Rpb24gc2V0UlRMVGV4dFBsdWdpblxuICogQHBhcmFtIHtzdHJpbmd9IHBsdWdpblVSTCBVUkwgcG9pbnRpbmcgdG8gdGhlIE1hcGJveCBSVEwgdGV4dCBwbHVnaW4gc291cmNlLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgQ2FsbGVkIHdpdGggYW4gZXJyb3IgYXJndW1lbnQgaWYgdGhlcmUgaXMgYW4gZXJyb3IsIG9yIG5vIGFyZ3VtZW50cyBpZiB0aGUgcGx1Z2luIGxvYWRzIHN1Y2Nlc3NmdWxseS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gbGF6eSBJZiBzZXQgdG8gYHRydWVgLCBNYXBib3hHTCB3aWxsIGRlZmVyIGxvYWRpbmcgdGhlIHBsdWdpbiB1bnRpbCByaWdodC10by1sZWZ0IHRleHQgaXMgZW5jb3VudGVyZWQsIGFuZFxuICogICAgcmlnaHQtdG8tbGVmdCB0ZXh0IHdpbGwgYmUgcmVuZGVyZWQgb25seSBhZnRlciB0aGUgcGx1Z2luIGZpbmlzaGVzIGxvYWRpbmcuXG4gKiBAZXhhbXBsZVxuICogbWFwYm94Z2wuc2V0UlRMVGV4dFBsdWdpbignaHR0cHM6Ly9hcGkubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvcGx1Z2lucy9tYXBib3gtZ2wtcnRsLXRleHQvdjAuMi4wL21hcGJveC1nbC1ydGwtdGV4dC5qcycpO1xuICogQHNlZSBbRXhhbXBsZTogQWRkIHN1cHBvcnQgZm9yIHJpZ2h0LXRvLWxlZnQgc2NyaXB0c10oaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9tYXBib3gtZ2wtcnRsLXRleHQvKVxuICovXG5cbi8qKlxuICAqIEdldHMgdGhlIG1hcCdzIFtSVEwgdGV4dCBwbHVnaW5dKGh0dHBzOi8vd3d3Lm1hcGJveC5jb20vbWFwYm94LWdsLWpzL3BsdWdpbnMvI21hcGJveC1nbC1ydGwtdGV4dCkgc3RhdHVzLlxuICAqIFRoZSBzdGF0dXMgY2FuIGJlIGB1bmF2YWlsYWJsZWAgKG5vdCByZXF1ZXN0ZWQgb3IgcmVtb3ZlZCksIGBsb2FkaW5nYCwgYGxvYWRlZGAsIG9yIGBlcnJvcmAuXG4gICogSWYgdGhlIHN0YXR1cyBpcyBgbG9hZGVkYCBhbmQgdGhlIHBsdWdpbiBpcyByZXF1ZXN0ZWQgYWdhaW4sIGFuIGVycm9yIHdpbGwgYmUgdGhyb3duLlxuICAqXG4gICogQGZ1bmN0aW9uIGdldFJUTFRleHRQbHVnaW5TdGF0dXNcbiAgKiBAZXhhbXBsZVxuICAqIGNvbnN0IHBsdWdpblN0YXR1cyA9IG1hcGJveGdsLmdldFJUTFRleHRQbHVnaW5TdGF0dXMoKTtcbiAgKi9cblxuZXhwb3J0IGRlZmF1bHQgZXhwb3J0ZWQ7XG5cbi8vIGNhbmFyeSBhc3NlcnQ6IHVzZWQgdG8gY29uZmlybSB0aGF0IGFzc2VydHMgaGF2ZSBiZWVuIHJlbW92ZWQgZnJvbSBwcm9kdWN0aW9uIGJ1aWxkXG5hc3NlcnQodHJ1ZSwgJ2NhbmFyeSBhc3NlcnQnKTtcbiIsIi8vXG4vLyBPdXIgY3VzdG9tIGludHJvIHByb3ZpZGVzIGEgc3BlY2lhbGl6ZWQgXCJkZWZpbmUoKVwiIGZ1bmN0aW9uLCBjYWxsZWQgYnkgdGhlXG4vLyBBTUQgbW9kdWxlcyBiZWxvdywgdGhhdCBzZXRzIHVwIHRoZSB3b3JrZXIgYmxvYiBVUkwgYW5kIHRoZW4gZXhlY3V0ZXMgdGhlXG4vLyBtYWluIG1vZHVsZSwgc3RvcmluZyBpdHMgZXhwb3J0ZWQgdmFsdWUgYXMgJ21hcGJveGdsJ1xuXG4vLyBUaGUgdGhyZWUgXCJjaHVua3NcIiBpbXBvcnRlZCBoZXJlIGFyZSBwcm9kdWNlZCBieSBhIGZpcnN0IFJvbGx1cCBwYXNzLFxuLy8gd2hpY2ggb3V0cHV0cyB0aGVtIGFzIEFNRCBtb2R1bGVzLlxuXG4vLyBTaGFyZWQgZGVwZW5kZW5jaWVzLCBpLmUuOlxuLypcbmRlZmluZShbJ2V4cG9ydHMnXSwgZnVuY3Rpb24gKGV4cG9ydHMpIHtcbiAgICAvLyBDb2RlIGZvciBhbGwgY29tbW9uIGRlcGVuZGVuY2llc1xuICAgIC8vIEVhY2ggbW9kdWxlJ3MgZXhwb3J0cyBhcmUgYXR0YWNoZWQgYXR0YWNoZWQgdG8gJ2V4cG9ydHMnICh3aXRoXG4gICAgLy8gbmFtZXMgcmV3cml0dGVuIHRvIGF2b2lkIGNvbGxpc2lvbnMsIGV0Yy4pXG59KVxuKi9cbmltcG9ydCAnLi9idWlsZC9tYXBib3hnbC9zaGFyZWQnO1xuXG4vLyBXb3JrZXIgYW5kIGl0cyB1bmlxdWUgZGVwZW5kZW5jaWVzLCBpLmUuOlxuLypcbmRlZmluZShbJy4vc2hhcmVkLmpzJ10sIGZ1bmN0aW9uIChfX3NoYXJlZF9fanMpIHtcbiAgICAvLyAgQ29kZSBmb3Igd29ya2VyIHNjcmlwdCBhbmQgaXRzIHVuaXF1ZSBkZXBlbmRlbmNpZXMuXG4gICAgLy8gIEV4cGVjdHMgdGhlIG91dHB1dCBvZiAnc2hhcmVkJyBtb2R1bGUgdG8gYmUgcGFzc2VkIGluIGFzIGFuIGFyZ3VtZW50LFxuICAgIC8vICBzaW5jZSBhbGwgcmVmZXJlbmNlcyB0byBjb21tb24gZGVwcyBsb29rIGxpa2UsIGUuZy4sXG4gICAgLy8gIF9fc2hhcmVkX19qcy5zaGFwZVRleHQoKS5cbn0pO1xuKi9cbi8vIFdoZW4gdGhpcyB3cmFwcGVyIGZ1bmN0aW9uIGlzIHBhc3NlZCB0byBvdXIgY3VzdG9tIGRlZmluZSgpIGFib3ZlLFxuLy8gaXQgZ2V0cyBzdHJpbmdpZmllZCwgdG9nZXRoZXIgd2l0aCB0aGUgc2hhcmVkIHdyYXBwZXIgKHVzaW5nXG4vLyBGdW5jdGlvbi50b1N0cmluZygpKSwgYW5kIHRoZSByZXN1bHRpbmcgc3RyaW5nIG9mIGNvZGUgaXMgbWFkZSBpbnRvIGFcbi8vIEJsb2IgVVJMIHRoYXQgZ2V0cyB1c2VkIGJ5IHRoZSBtYWluIG1vZHVsZSB0byBjcmVhdGUgdGhlIHdlYiB3b3JrZXJzLlxuaW1wb3J0ICcuL2J1aWxkL21hcGJveGdsL3dvcmtlcic7XG5cbi8vIE1haW4gbW9kdWxlIGFuZCBpdHMgdW5pcXVlIGRlcGVuZGVuY2llc1xuLypcbmRlZmluZShbJy4vc2hhcmVkLmpzJ10sIGZ1bmN0aW9uIChfX3NoYXJlZF9fanMpIHtcbiAgICAvLyAgQ29kZSBmb3IgbWFpbiBHTCBKUyBtb2R1bGUgYW5kIGl0cyB1bmlxdWUgZGVwZW5kZW5jaWVzLlxuICAgIC8vICBFeHBlY3RzIHRoZSBvdXRwdXQgb2YgJ3NoYXJlZCcgbW9kdWxlIHRvIGJlIHBhc3NlZCBpbiBhcyBhbiBhcmd1bWVudCxcbiAgICAvLyAgc2luY2UgYWxsIHJlZmVyZW5jZXMgdG8gY29tbW9uIGRlcHMgbG9vayBsaWtlLCBlLmcuLFxuICAgIC8vICBfX3NoYXJlZF9fanMuc2hhcGVUZXh0KCkuXG4gICAgLy9cbiAgICAvLyAgUmV0dXJucyB0aGUgYWN0dWFsIG1hcGJveGdsIChpLmUuIHNyYy9pbmRleC5qcylcbn0pO1xuKi9cbmltcG9ydCAnLi9idWlsZC9tYXBib3hnbC9pbmRleCc7XG5cbmV4cG9ydCBkZWZhdWx0IG1hcGJveGdsO1xuIl0sIm5hbWVzIjpbImV4cG9ydGVkIiwid2luZG93IiwiUG9pbnQiLCJvYmplY3RBc3NpZ24iLCJpbmhlcml0c19icm93c2VyTW9kdWxlIiwicmVxdWlyZSQkMCIsInJlcXVpcmUkJDEiLCJjb21wYXJlIiwiYXNzZXJ0TW9kdWxlIiwiYXNzZXJ0IiwiYmV6aWVyIiwiVW5pdEJlemllciIsImV4dGVuZCIsImNsb25lIiwid2VicFN1cHBvcnRlZCIsInNka1ZlcnNpb24iLCJhcnJheSIsInRvU3RyaW5nIiwicGFyc2VDU1NDb2xvciIsInR5cGVzIiwidmFsdWVUb1N0cmluZyIsIlBhcnNpbmdDb250ZXh0IiwiRVhURU5UIiwibWVyY2F0b3JYZnJvbUxuZyIsIm1lcmNhdG9yWWZyb21MYXQiLCJpbnRlcnBvbGF0ZU51bWJlciIsInR5cGVUb1N0cmluZyIsImRlZmluaXRpb25zIiwiaXNDb25zdGFudC5pc1N0YXRlQ29uc3RhbnQiLCJpc0ZlYXR1cmVDb25zdGFudCIsImlzQ29uc3RhbnQuaXNGZWF0dXJlQ29uc3RhbnQiLCJpc0NvbnN0YW50LmlzR2xvYmFsUHJvcGVydHlDb25zdGFudCIsInZhbGlkYXRlU3BlYyIsImxhdGVzdCIsInZhbGlkYXRlRmlsdGVyIiwidmFsaWRhdGVQYWludFByb3BlcnR5IiwidmFsaWRhdGVMYXlvdXRQcm9wZXJ0eSIsInZhbGlkYXRlTGF5ZXIiLCJ2YWxpZGF0ZVNvdXJjZSIsInZhbGlkYXRlTGlnaHQiLCJ2YWxpZGF0ZVRlcnJhaW4iLCJ2YWxpZGF0ZUZvZyIsImxhdGVzdFN0eWxlU3BlYyIsIl92YWxpZGF0ZVNvdXJjZSIsIl92YWxpZGF0ZUxpZ2h0IiwiX3ZhbGlkYXRlVGVycmFpbiIsIl92YWxpZGF0ZUZvZyIsIl92YWxpZGF0ZUxheWVyIiwiX3ZhbGlkYXRlRmlsdGVyIiwiX3ZhbGlkYXRlUGFpbnRQcm9wZXJ0eSIsIl92YWxpZGF0ZUxheW91dFByb3BlcnR5IiwiZGVzZXJpYWxpemUiLCJpc0NoYXIiLCJicm93c2VyIiwicnRsVGV4dFBsdWdpbiIsImFsaWduIiwibXVybXVyaGFzaEpzTW9kdWxlIiwic29ydCIsIm11cm11cjMiLCJzd2FwIiwiUGF0dGVybkxheW91dEFycmF5IiwiRGFzaExheW91dEFycmF5Iiwic3R5bGVTcGVjIiwiZmVhdHVyZUZpbHRlciIsIm1lbWJlcnMiLCJzaXplIiwiYWxpZ25tZW50IiwiTG5nTGF0IiwiZXF1YWxzIiwiY3JlYXRlIiwiZ2xNYXRyaXguQVJSQVlfVFlQRSIsImNvcHkiLCJpZGVudGl0eSIsImZyb21WYWx1ZXMiLCJzZXQiLCJ0cmFuc3Bvc2UiLCJpbnZlcnQiLCJhZGpvaW50IiwiZGV0ZXJtaW5hbnQiLCJtdWx0aXBseSIsInJvdGF0ZSIsInNjYWxlIiwiZnJvbVJvdGF0aW9uIiwiZnJvbVNjYWxpbmciLCJzdHIiLCJmcm9iIiwiYWRkIiwic3VidHJhY3QiLCJleGFjdEVxdWFscyIsImdsTWF0cml4LkVQU0lMT04iLCJtdWx0aXBseVNjYWxhciIsIm11bHRpcGx5U2NhbGFyQW5kQWRkIiwibXVsIiwic3ViIiwidHJhbnNsYXRlIiwiZnJvbVRyYW5zbGF0aW9uIiwiZnJvbU1hdDQiLCJmcm9tUXVhdCIsInJvdGF0ZVgiLCJyb3RhdGVZIiwicm90YXRlWiIsImZyb21Sb3RhdGlvblRyYW5zbGF0aW9uIiwiZ2V0VHJhbnNsYXRpb24iLCJsZW5ndGgiLCJkaXZpZGUiLCJjZWlsIiwiZmxvb3IiLCJtaW4iLCJtYXgiLCJyb3VuZCIsInNjYWxlQW5kQWRkIiwiZGlzdGFuY2UiLCJzcXVhcmVkRGlzdGFuY2UiLCJzcXVhcmVkTGVuZ3RoIiwibmVnYXRlIiwiaW52ZXJzZSIsIm5vcm1hbGl6ZSIsImRvdCIsImNyb3NzIiwibGVycCIsInJhbmRvbSIsImdsTWF0cml4LlJBTkRPTSIsInRyYW5zZm9ybU1hdDQiLCJ0cmFuc2Zvcm1NYXQzIiwidHJhbnNmb3JtUXVhdCIsImFuZ2xlIiwiemVybyIsImRpdiIsImRpc3QiLCJzcXJEaXN0IiwibGVuIiwic3FyTGVuIiwiZm9yRWFjaCIsInNsZXJwIiwiY29uanVnYXRlIiwidmVjNC5jbG9uZSIsInZlYzQuZnJvbVZhbHVlcyIsInZlYzQuY29weSIsInZlYzQuc2V0IiwidmVjNC5hZGQiLCJ2ZWM0LnNjYWxlIiwidmVjNC5kb3QiLCJ2ZWM0LmxlcnAiLCJ2ZWM0Lmxlbmd0aCIsInZlYzQuc3F1YXJlZExlbmd0aCIsInZlYzQubm9ybWFsaXplIiwidmVjNC5leGFjdEVxdWFscyIsInZlYzQuZXF1YWxzIiwidmVjMy5jcmVhdGUiLCJ2ZWMzLmZyb21WYWx1ZXMiLCJ2ZWMzLmRvdCIsInZlYzMuY3Jvc3MiLCJ2ZWMzLmxlbiIsInZlYzMubm9ybWFsaXplIiwibWF0My5jcmVhdGUiLCJxdWF0LmNyZWF0ZSIsIm1hdDQuZ2V0Um90YXRpb24iLCJtYXQ0LmdldFRyYW5zbGF0aW9uIiwicXVhdC5jb3B5IiwicXVhdC5yb3RhdGVYIiwicXVhdC5yb3RhdGVZIiwicXVhdC5yb3RhdGVaIiwicXVhdC5kb3QiLCJxdWF0Lmxlbmd0aCIsInF1YXQuc3F1YXJlZExlbmd0aCIsImxheW91dCIsInZlYzMuc3F1YXJlZExlbmd0aCIsInZlYzMuZXF1YWxzIiwidmVjMy50cmFuc2Zvcm1NYXQ0IiwidmVjNC50cmFuc2Zvcm1NYXQ0IiwidmVjNC5tdWwiLCJ2ZWMzLnN1YiIsInZlYzMubWluIiwidmVjMy5tYXgiLCJ2ZWMzLnNjYWxlIiwidmVjMy5hZGQiLCJ2ZWMzLmNsb25lIiwidmVjMy5sZW5ndGgiLCJNZXJjYXRvckNvb3JkaW5hdGUiLCJ2ZWMzLnNjYWxlQW5kQWRkIiwibWF0NC5pbnZlcnQiLCJtYXQ0LmZyb21TY2FsaW5nIiwibWF0NC50cmFuc2xhdGUiLCJ2ZWMzLm5lZ2F0ZSIsIm1hdDQuZnJvbVRyYW5zbGF0aW9uIiwibWF0NC5zY2FsZSIsIm1hdDQuaWRlbnRpdHkiLCJtYXQ0LnJvdGF0ZVgiLCJtYXQ0LnJvdGF0ZVkiLCJtYXQ0Lm11bHRpcGx5IiwibWF0NC5tdWwiLCJtYXQ0LmNyZWF0ZSIsIm1hdDMubXVsdGlwbHkiLCJtYXQ0LmZyb21Sb3RhdGlvbiIsInZlYzMuc3VidHJhY3QiLCJ2ZWMzLmFuZ2xlIiwiUG9zQXJyYXkiLCJUcmlhbmdsZUluZGV4QXJyYXkiLCJHbG9iZVZlcnRleEFycmF5IiwiaW50ZXJwb2xhdGUiLCJnbG9iZUxheW91dEF0dHJpYnV0ZXMiLCJMaW5lSW5kZXhBcnJheSIsInJlc2FtcGxlIiwiYWRkR2xvYmVFeHRWZXJ0ZXgiLCJDaXJjbGVMYXlvdXRBcnJheSIsIkNpcmNsZUdsb2JlRXh0QXJyYXkiLCJwYWludCIsInByb3BlcnRpZXMiLCJlYXJjdXRNb2R1bGUiLCJzaWduZWRBcmVhIiwiZGVmYXVsdENvbXBhcmUiLCJjbGFzc2lmeVJpbmdzIiwiRUFSQ1VUX01BWF9SSU5HUyIsIkZpbGxMYXlvdXRBcnJheSIsImxheW91dEF0dHJpYnV0ZXMiLCJlYXJjdXQiLCJWZWN0b3JUaWxlRmVhdHVyZSIsIlZlY3RvclRpbGVMYXllciIsIlZlY3RvclRpbGUiLCJyZXF1aXJlJCQyIiwidmVjdG9yVGlsZUZlYXR1cmVUeXBlcyIsImFkZFZlcnRleCIsIkZpbGxFeHRydXNpb25MYXlvdXRBcnJheSIsIkZpbGxFeHRydXNpb25FeHRBcnJheSIsIkxpbmVMYXlvdXRBcnJheSIsIkxpbmVFeHRMYXlvdXRBcnJheSIsImxheW91dEF0dHJpYnV0ZXNFeHQiLCJpZWVlNzU0IiwiYm9yZGVyIiwiUXVldWUiLCJTeW1ib2xCdWNrZXQiLCJtYXhQaGkiLCJTeW1ib2xMYXlvdXRBcnJheSIsIlN5bWJvbER5bmFtaWNMYXlvdXRBcnJheSIsIlN5bWJvbE9wYWNpdHlBcnJheSIsIlN5bWJvbEdsb2JlRXh0QXJyYXkiLCJDb2xsaXNpb25WZXJ0ZXhBcnJheSIsIkNvbGxpc2lvblZlcnRleEV4dEFycmF5IiwiZ2xvYmFsUlRMVGV4dFBsdWdpbiIsInRyYW5zZm9ybVRleHQiLCJDb2xsaXNpb25Cb3hMYXlvdXRBcnJheSIsInN5bWJvbFNpemUuZXZhbHVhdGVTaXplRm9yWm9vbSIsInN5bWJvbFNpemUuZXZhbHVhdGVTaXplRm9yRmVhdHVyZSIsInF1YXQuaWRlbnRpdHkiLCJ2ZWMzLnRyYW5zZm9ybVF1YXQiLCJjaXJjbGUiLCJoZWF0bWFwIiwiaGlsbHNoYWRlIiwiZmlsbCIsImZpbGxFeHRydXNpb24iLCJsaW5lIiwic3ltYm9sIiwiYmFja2dyb3VuZCIsInJhc3RlciIsInNreSIsIkxpbmVTdHJpcEluZGV4QXJyYXkiLCJUaWxlQm91bmRzQXJyYXkiLCJkZXNlcmlhbGl6ZUJ1Y2tldCIsIkdlb0pTT05GZWF0dXJlIiwiUG9zR2xvYmVFeHRBcnJheSIsIkFMV0FZUyIsInJlZlByb3BlcnRpZXMiLCJjcmVhdGVTdHlsZUxheWVyIiwidmFsdWVzIiwiREVNRGF0YSIsInJld2luZCIsIkZlYXR1cmVXcmFwcGVyIiwiR2VvSlNPTldyYXBwZXIiLCJ2dFBiZk1vZHVsZSIsIktEQnVzaCIsInRyYW5zZm9ybSIsIlZlY3RvclRpbGVXb3JrZXJTb3VyY2UiLCJjcmVhdGVFeHByZXNzaW9uIiwiZ2V0UGVyZm9ybWFuY2VNZWFzdXJlbWVudCIsImdldEpTT04iLCJQZXJmb3JtYW5jZVV0aWxzIiwiQWN0b3IiLCJnZXRQcm9qZWN0aW9uIiwiRXZlbnQiLCJlbmZvcmNlQ2FjaGVTaXplTGltaXQiLCJSZXNvdXJjZVR5cGUiLCJnZXRJbWFnZSIsIlJHQkFJbWFnZSIsIkV2ZW50ZWQiLCJFcnJvckV2ZW50Iiwid2Fybk9uY2UiLCJJbWFnZVBvc2l0aW9uIiwiVGV4dHVyZSIsInBvdHBhY2siLCJkZWdUb1JhZCIsIlByb3BlcnRpZXMiLCJEYXRhQ29uc3RhbnRQcm9wZXJ0eSIsIlRSQU5TSVRJT05fU1VGRklYIiwiVHJhbnNpdGlvbmFibGUiLCJlbmRzV2l0aCIsImVtaXRWYWxpZGF0aW9uRXJyb3JzIiwidmFsaWRhdGVTdHlsZSIsInNtb290aHN0ZXAiLCJnbG9iZVRvTWVyY2F0b3JUcmFuc2l0aW9uIiwidW5pcXVlSWQiLCJhc3luY0FsbCIsIm1hdDIuc2NhbGUiLCJwb2x5Z29uaXplQm91bmRzIiwiYnVmZmVyQ29udmV4UG9seWdvbiIsImdldFRpbGVQb2ludCIsInBvbHlnb25JbnRlcnNlY3RzQm94IiwiZ2V0VGlsZVZlYzMiLCJSYXkiLCJnZXRCb3VuZHMiLCJHTE9CRV9SQURJVVMiLCJwb2x5Z29uQ29udGFpbnNQb2ludCIsImNsYW1wIiwicGljayIsIkxuZ0xhdEJvdW5kcyIsIkRlZHVwZWRSZXF1ZXN0IiwicG9zdFR1cm5zdGlsZUV2ZW50IiwibG9hZFZlY3RvclRpbGUiLCJjYWNoZUVudHJ5UG9zc2libHlBZGRlZCIsInByZXZQb3dlck9mVHdvIiwiT3ZlcnNjYWxlZFRpbGVJRCIsIm1hdDMuYWRqb2ludCIsInZlYzMudHJhbnNmb3JtTWF0MyIsIm1hdDMudHJhbnNwb3NlIiwidGlsZVRyYW5zZm9ybSIsIlJhc3RlckJvdW5kc0FycmF5IiwiYm91bmRzQXR0cmlidXRlcyIsIlNlZ21lbnRWZWN0b3IiLCJDYW5vbmljYWxUaWxlSUQiLCJnZXRWaWRlbyIsIlZhbGlkYXRpb25FcnJvciIsInZlY3RvciIsInJhc3RlckRlbSIsImdlb2pzb24iLCJ2aWRlbyIsImltYWdlIiwiY2FudmFzIiwiY3VzdG9tIiwiYmluZEFsbCIsImlzRXF1YWwiLCJjYWxjdWxhdGVHbG9iZUxhYmVsTWF0cml4IiwibWF0Mi5pbnZlcnQiLCJtYXQ0LnJvdGF0ZVoiLCJtYXQ0LmNsb25lIiwiV3JpdGluZ01vZGUiLCJ1cGRhdGVHbG9iZVZlcnRleE5vcm1hbCIsImFkZER5bmFtaWNBdHRyaWJ1dGVzIiwidmVjMy5kaXN0YW5jZSIsIkdyaWQiLCJPTkVfRU0iLCJzeW1ib2xQcm9qZWN0aW9uLnByb2plY3QiLCJzeW1ib2xQcm9qZWN0aW9uLnBsYWNlRmlyc3RBbmRMYXN0R2x5cGgiLCJjbGlwTGluZSIsImludGVyc2VjdGlvblRlc3RzLnBvbHlnb25JbnRlcnNlY3RzUG9seWdvbiIsInN5bWJvbFByb2plY3Rpb24ueHlUcmFuc2Zvcm1NYXQ0IiwiZ2V0QW5jaG9yQWxpZ25tZW50IiwiZXZhbHVhdGVWYXJpYWJsZU9mZnNldCIsInByb2plY3Rpb24uZ2V0TGFiZWxQbGFuZU1hdHJpeEZvclBsYWNlbWVudCIsInByb2plY3Rpb24uZ2V0R2xDb29yZE1hdHJpeCIsImdldEFuY2hvckp1c3RpZmljYXRpb24iLCJfZW1pdFZhbGlkYXRpb25FcnJvcnMiLCJkaWZmT3BlcmF0aW9ucyIsImdldFdvcmtlclBvb2wiLCJHbHlwaE1hbmFnZXIiLCJMb2NhbEdseXBoTW9kZSIsImdldFJlZmVycmVyIiwidHJpZ2dlclBsdWdpbkNvbXBsZXRpb25FdmVudCIsImlzTWFwYm94VVJMIiwiZGVyZWYiLCJjcmVhdGVTb3VyY2UiLCJTb3VyY2VDYWNoZSIsInZhbGlkYXRlQ3VzdG9tU3R5bGVMYXllciIsImluZGV4IiwiZGVlcEVxdWFsIiwiZmlsdGVyT2JqZWN0IiwiVGVycmFpbiIsInJ0bFRleHRQbHVnaW5FdmVudGVkIiwibWFrZVJlcXVlc3QiLCJnZXRTb3VyY2VUeXBlIiwic2V0U291cmNlVHlwZSIsInJlZ2lzdGVyRm9yUGx1Z2luU3RhdGVDaGFuZ2UiLCJVbmlmb3JtTWF0cml4NGYiLCJVbmlmb3JtMWkiLCJVbmlmb3JtMmYiLCJVbmlmb3JtQ29sb3IiLCJVbmlmb3JtMWYiLCJVbmlmb3JtNGYiLCJtYXQ0Lm9ydGhvIiwiRGVwdGhNb2RlIiwiU3RlbmNpbE1vZGUiLCJDdWxsRmFjZU1vZGUiLCJVbmlmb3JtTWF0cml4M2YiLCJVbmlmb3JtM2YiLCJnbG9iZVVzZUN1c3RvbUFudGlBbGlhc2luZyIsImNhbGN1bGF0ZUdsb2JlTWVyY2F0b3JNYXRyaXgiLCJlYXNlQ3ViaWNJbk91dCIsInRpbGVDb3JuZXJzVG9Cb3VuZHMiLCJnZXRMYXRpdHVkaW5hbExvZCIsImdldEdyaWRNYXRyaXgiLCJnbG9iZU5vcm1hbGl6ZUVDRUYiLCJnbG9iZVRpbGVCb3VuZHMiLCJnbG9iZVBvbGVNYXRyaXhGb3JUaWxlIiwiQ29sb3JNb2RlIiwiVGlsZSIsIkVsZXZhdGlvbiIsInBvc0F0dHJpYnV0ZXMiLCJtZXJjYXRvclpmcm9tQWx0aXR1ZGUiLCJnbG9iZU1ldGVyc1RvRWNlZiIsIkNvbG9yIiwiRGVwdGhTdGVuY2lsQXR0YWNobWVudCIsIlpvb21EZXBlbmRlbnRFeHByZXNzaW9uIiwiaWRlbnRpdHlNYXRyaXgiLCJtYXQzLmZyb21Sb3RhdGlvbiIsIlVuaWZvcm1NYXRyaXgyZiIsImdsb2JlUGl4ZWxzVG9UaWxlVW5pdHMiLCJnbG9iZUVDRUZPcmlnaW4iLCJDb2xsaXNpb25DaXJjbGVMYXlvdXRBcnJheSIsImNvbGxpc2lvbkNpcmNsZUxheW91dCIsIlF1YWRUcmlhbmdsZUFycmF5Iiwic3ltYm9sUHJvamVjdGlvbi5nZXRMYWJlbFBsYW5lTWF0cml4Rm9yUmVuZGVyaW5nIiwic3ltYm9sU2l6ZSIsInN5bWJvbFByb2plY3Rpb24uaGlkZUdseXBocyIsInN5bWJvbFByb2plY3Rpb24uZ2V0UGVyc3BlY3RpdmVSYXRpbyIsInN5bWJvbFByb2plY3Rpb24uZ2V0R2xDb29yZE1hdHJpeCIsInN5bWJvbFByb2plY3Rpb24uZ2V0TGFiZWxQbGFuZU1hdHJpeEZvclBsYWNlbWVudCIsInN5bWJvbFByb2plY3Rpb24udXBkYXRlTGluZUxhYmVscyIsIm5leHRQb3dlck9mVHdvIiwicmVuZGVyQ29sb3JSYW1wIiwiZHJhdyIsImZpbGxFeHRydXNpb25IZWlnaHRMaWZ0IiwiRmlsbEV4dHJ1c2lvbkJ1Y2tldCIsInRyYW5zaXRpb25UaWxlQUFCQmluRUNFRiIsImdsb2JlRGVub3JtYWxpemVFQ0VGIiwiY3JlYXRlTGF5b3V0IiwiU2t5Ym94VmVydGV4QXJyYXkiLCJza3lib3hBdHRyaWJ1dGVzIiwibWF0My5mcm9tTWF0NCIsIm1hdDQuZnJvbVF1YXQiLCJtYXBWYWx1ZSIsIkF0bW9zcGhlcmVWZXJ0ZXhBcnJheSIsImRlYnVnIiwiQ29udGV4dCIsIkdsb2JlU2hhcmVkQnVmZmVycyIsImlzTWFwQXV0aGVudGljYXRlZCIsIkRlYnVnIiwibnVtYmVyIiwiZ2V0Q29sdW1uIiwic2V0Q29sdW1uIiwid3JhcCIsInF1YXQuY29uanVnYXRlIiwibWF0NC5wZXJzcGVjdGl2ZSIsImxhdEZyb21NZXJjYXRvclkiLCJNQVhfTUVSQ0FUT1JfTEFUSVRVREUiLCJtYXQyLmNyZWF0ZSIsIm1hdDIucm90YXRlIiwicXVhdC5leGFjdEVxdWFscyIsInZlYzMuZXhhY3RFcXVhbHMiLCJxdWF0Lm5vcm1hbGl6ZSIsIlVud3JhcHBlZFRpbGVJRCIsIkZydXN0dW0iLCJ0aWxlQUFCQiIsImNpcmN1bWZlcmVuY2VBdExhdGl0dWRlIiwiR0xPQkVfWk9PTV9USFJFU0hPTERfTUlOIiwiZ2V0QUFCQlBvaW50U3F1YXJlRGlzdCIsImZ1cnRoZXN0VGlsZUNvcm5lciIsIkdMT0JFX1pPT01fVEhSRVNIT0xEX01BWCIsInBvbGVzSW5WaWV3cG9ydCIsIkdMT0JFX1NDQUxFX01BVENIX0xBVElUVURFIiwiRnJ1c3R1bUNvcm5lcnMiLCJjYWxjdWxhdGVHbG9iZU1hdHJpeCIsInZlYzMubXVsdGlwbHkiLCJyYWRUb0RlZyIsIkRPTS5tb3VzZVBvcyIsIkRPTS50b3VjaFBvcyIsIkRPTS5kaXNhYmxlRHJhZyIsIkRPTS5jcmVhdGUiLCJET00uc3VwcHJlc3NDbGljayIsIkRPTS5lbmFibGVEcmFnIiwiRE9NLm1vdXNlQnV0dG9uIiwiaXNGdWxsc2NyZWVuIiwiZGVmYXVsdE9wdGlvbnMiLCJfZWFzZSIsInZlYzMuZGl2IiwidmVjMy5tdWwiLCJtZXJjYXRvclNjYWxlIiwibGF0TG5nVG9FQ0VGIiwiQWFiYiIsInZlYzMuc2V0IiwiZWNlZlRvTGF0TG5nIiwiZWFydGhSYWRpdXMiLCJsbmdGcm9tTWVyY2F0b3JYIiwiZGVmYXVsdEVhc2luZyIsImNvbmZpZyIsIkRPTS5jcmVhdGVTVkciLCJpc0xuZ0xhdEJlaGluZEdsb2JlIiwiZ2xvYmVUaWx0QXRMbmdMYXQiLCJnbG9iZUNlbnRlclRvU2NyZWVuUG9pbnQiLCJMaXZlUGVyZm9ybWFuY2VVdGlscyIsIlBlcmZvcm1hbmNlTWFya2VycyIsImlzU2FmYXJpV2l0aEFudGlhbGlhc2luZ0J1ZyIsIlJlcXVlc3RNYW5hZ2VyIiwic3RvcmVBdXRoU3RhdGUiLCJFdmFsdWF0aW9uUGFyYW1ldGVycyIsInBvc3RQZXJmb3JtYW5jZUV2ZW50IiwiZ2V0TWFwU2Vzc2lvbkFQSSIsIkFVVEhfRVJSX01TRyIsInBvc3RNYXBMb2FkRXZlbnQiLCJyZW1vdmVBdXRoU3RhdGUiLCJzZXRDYWNoZUxpbWl0cyIsInZlcnNpb24iLCJwZXJmb3JtYW5jZSIsInNldFJUTFRleHRQbHVnaW4iLCJnZXRSVExUZXh0UGx1Z2luU3RhdHVzIiwiY2xlYXJUaWxlQ2FjaGUiLCJpc1NhZmFyaSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBZSxRQUFBLEtBQUUsT0FBTyxJQUFJLEtBQUssV0FBVyxHQUFHLElBQUksSUFBSSxFQUFFLE1BQU0sVUFBQSxDQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDTC9EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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QTtBQUNBO0FBQ0E7QUFDQSxJQUFJLFdBQVcsS0FBSyxTQUFTLENBQUMsRUFBRSxFQUFFLE9BQU8sSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO0FBQ3hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxVQUFVLE1BQU0sU0FBUyxDQUFDLEVBQUUsRUFBRSxPQUFPLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTtBQUN2RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksSUFBSSxLQUFLLFNBQVMsQ0FBQyxFQUFFLEVBQUUsT0FBTyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7QUFDMUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLEdBQUcsTUFBTSxTQUFTLENBQUMsRUFBRSxFQUFFLE9BQU8sSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxNQUFNLEdBQUcsU0FBUyxDQUFDLEVBQUUsRUFBRSxPQUFPLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTtBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxZQUFZLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsT0FBTyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO0FBQzVFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksT0FBTyxFQUFFLFNBQVMsQ0FBQyxFQUFFLEVBQUUsT0FBTyxJQUFJLENB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TDtBQUNBLElBQUksS0FBSyxFQUFFLFNBQVMsQ0FBQyxFQUFFO0FBQ3ZCLFFBQVEsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDcEIsUUFBUSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNwQixRQUFRLE9BQU8sSUFBSSxDQUFDO0FBQ3BCLEtBQUs7QUFDTDtBQUNBLElBQUksSUFBSSxFQUFFLFNBQVMsQ0FBQyxFQUFFO0FBQ3RCLFFBQVEsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDcEIsUUFBUSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNwQixRQUFRLE9BQU8sSUFBSSxDQUFDO0FBQ3BCLEtBQUs7QUFDTDtBQUNBLElBQUksWUFBWSxFQUFFLFNBQVMsQ0FBQyxFQUFFO0FBQzlCLFFBQVEsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLFFBQVEsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLFFBQVEsT0FBTyxJQUFJLENBQUM7QUFDcEIsS0FBSztBQUNMO0FBQ0EsSUFBSSxXQUFXLEVBQUUsU0FBUyxDQUFDLEVBQUU7QUFDN0IsUUFBUSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEIsUUFBUSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEIsUUFBUSxPQUFPLElBQUksQ0FBQztBQUNwQixLQUFLO0FBQ0w7QUFDQSxJQUFJLEtBQUssRUFBRSxXQUFXO0FBQ3RCLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQztBQUM5QixRQUFRLE9BQU8sSUFBSSxDQUFDO0FBQ3BCLEtBQUs7QUFDTDtBQUNBLElBQUksS0FBSyxFQUFFLFdBQVc7QUFDdEIsUUFBUSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLFFBQVEsSUFBSSxDQUFDLENB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USxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUU7QUFDMUQsUUFBUSxNQUFNLElBQUksS0FBSyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxDQUFDO0FBQ3ZELEtBQUs7QUFDTDtBQUNBLElBQUksR0FBRyxDQUFDLElBQUksbUJBQW1CO0FBQy9CLFFBQVEsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sSUFBSSxDQUFDO0FBQzdDLFFBQVEsT0FBTyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUMzRCxLQUFLO0FBQ0wsQ0FBQTs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0sUUFBUSxHQUFHLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ2hDLE1BQU0sVUFBVSxHQUFHLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQ3BDLE1BQU0sVUFBVSxHQUFHLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQ3BDLE1BQU0sV0FBVyxHQUFHLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQ3RDLE1BQU0sU0FBUyxHQUFHLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQ2xDLE1BQU0sVUFBVSxHQUFHLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQ3BDLE1BQU0sU0FBUyxH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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksY0FBYyxHQUFHO0FBQ3JCLEVBQUUsYUFBYSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsV0FBVyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3hELEVBQUUsY0FBYyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3hELEVBQUUsWUFBWSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3pELEVBQUUsT0FBTyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3JELEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDdkQsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxZQUFZLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDbkQsRUFBRSxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFXLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDdEQsRUFBRSxXQUFXLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxZQUFZLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDMUQsRUFBRSxXQUFXLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDdEQsRUFBRSxnQkFBZ0IsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLFVBQVUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNoRSxFQUFFLFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNqRCxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNwRCxFQUFFLGVBQWUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLFVBQVUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUM5RCxFQUFFLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLFVBQVUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUN2RCxFQUFFLFdBQVcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLGFBQWEsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUM1RCxFQUFFLGdCQUFnQixFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsWUFBWSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzlELEVBQUUsWUFBWSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RELEVBQUUsWUFBWSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsY0FBYyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ2hFLEVBQUUsZUFBZSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsZUFBZSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQy9ELEVBQUUsZUFBZSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsZUFBZSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQy9ELEVBQUUsWUFBWSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsVUFBVSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3pELEVBQUUsYUFBYSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzFELEVBQUUsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsWUFBWSxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzFELEVBQUUsV0FBVyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsYUFBYSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzVELEVBQUUsYUFBYSxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3hELEVBQUUsV0FBVyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsWUFBWSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzdELEVBQUUsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsV0FBVyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ3BELEVBQUUsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQy9DLEVBQUUsYUFBYSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3hELEVBQUUsVUFBVSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3pELEVBQUUsV0FBVyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3BELEVBQUUsT0FBTyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3BELEVBQUUsVUFBVSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsZUFBZSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQy9ELEVBQUUsV0FBVyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsY0FBYyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzdELEVBQUUsV0FBVyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsWUFBWSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzdELEVBQUUsV0FBVyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsc0JBQXNCLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDdkUsRUFBRSxXQUFXLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxZQUFZLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDN0QsRUFBRSxXQUFXLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFXLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDNUQsRUFBRSxhQUFhLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxlQUFlLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDakUsRUFBRSxjQUFjLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxnQkFBZ0IsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNwRSxFQUFFLGdCQUFnQixFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDdEUsRUFBRSxhQUFhLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDckQsRUFBRSxXQUFXLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDdEQsRUFBRSxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakQsRUFBRSxrQkFBa0IsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNoRSxFQUFFLGNBQWMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLGNBQWMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNqRSxFQUFFLGdCQUFnQixFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsaUJBQWlCLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDdEUsRUFBRSxtQkFBbUIsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLGlCQUFpQixFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3ZFLEVBQUUsaUJBQWlCLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxjQUFjLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDbEUsRUFBRSxXQUFXLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFXLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDNUQsRUFBRSxVQUFVLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxhQUFhLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDN0QsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDakQsRUFBRSxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFXLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDckQsRUFBRSxRQUFRLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFXLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDcEQsRUFBRSxRQUFRLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxlQUFlLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDN0QsRUFBRSxXQUFXLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxlQUFlLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDaEUsRUFBRSxlQUFlLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxZQUFZLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDakUsRUFBRSxXQUFXLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDdEQsRUFBRSxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDbEQsRUFBRSxZQUFZLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDeEQsRUFBRSxlQUFlLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDakMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFXLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDbEQsRUFBRSxXQUFXLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxhQUFhLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDM0QsRUFBRSxRQUFRLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxZQUFZLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDekQsRUFBRSxVQUFVLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxVQUFVLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDeEQsRUFBRSxRQUFRLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDcEQsRUFBRSxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFXLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDekQsRUFBRSxXQUFXLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFXLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDNUQsRUFBRSxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxhQUFhLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDdkQsRUFBRSxXQUFXLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDckQsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDbkQsRUFBRSxRQUFRLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUs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QUFJLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDNUIsSUFBSSxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzVCLElBQUksTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM1QixJQUFJLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDNUIsSUFBSSxPQUFPLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxLQUFLLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDekUsQ0FBQztBQUNEO0FBQ0EsU0FBUyxZQUFZLENBQUMsQ0FBQyxtQkFBbUIsRUFBRSxtQkFBbUIsRUFBRSxtQkFBbUI7QUFDcEYsSUFBSSxPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEgsQ0FBQztBQUNEO0FBQ0E7QUFDQSxTQUFTLGtCQUFrQixDQUFDLEtBQUssbUJBQW1CLEtBQUssaUNBQWlDO0FBQzFGLElBQUksSUFBSSxNQUFNLEdBQUcsS0FBSyxDQUFDO0FBQ3ZCLElBQUksS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUN0RCxRQUFRLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM5QixRQUFRLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO0FBQy9ELFlBQVksSUFBSSxVQUFVLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxLQUFLLENBQUM7QUFDdEUsWUFBWSxJQUFJLFlBQVksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLEdBQUcsQ0FBQyxNQUFNLENBQUM7QUFDNUUsU0FBUztBQUNULEtBQUs7QUFDTCxJQUFJLE9BQU8sTUFBTSxDQUFDO0FBQ2xCLENBQUM7QUFDRDtBQUNBLFNBQVMsbUJBQW1CLENBQUMsS0FBSyxtQkFBbUIsUUFBUSx3Q0FBd0M7QUFDckcsSUFBSSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUM5QyxRQUFRLElBQUksa0JBQWtCLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sSUFBSSxDQUFDO0FBQ2hFLEtBQUs7QUFDTCxJQUFJLE9BQU8sS0FBSyxDQUFDO0FBQ2pCLENBQUM7QUFDRDtBQUNBLFNBQVMsSUFBSSxDQUFDLEVBQUUsbUJBQW1CLEVBQUUsbUJBQW1CO0FBQ3hELElBQUksUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUU7QUFDM0MsQ0FBQztBQUNEO0FBQ0E7QUFDQSxVQUFVLFFBQVEsQ0FBQyxFQUFFLG1CQUFtQixFQUFFLG1CQUFtQixFQUFFLG1CQUFtQixFQUFFLG1CQUFtQjtBQUN2RztBQUNBLElBQUksTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM3QixJQUFJLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDN0IsSUFBSSxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzdCLElBQUksTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM3QixJQUFJLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDN0IsSUFBSSxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzdCLElBQUksTUFBTSxJQUFJLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7QUFDckMsSUFBSSxNQUFNLElBQUksS0FBSyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztBQUN0QyxJQUFJLElBQUksQ0FBQyxJQUFJLEdBQUcsQ0FBQyxJQUFJ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SUFBSSxNQUFNLElBQUksSUFBSSxJQUFJLE1BQU07QUFDckUsSUFBSSw2QkFBNkIsRUFBRSxDQUFDLElBQUksS0FBSyxJQUFJLElBQUksTUFBTSxJQUFJLElBQUksSUFBSSxNQUFNO0FBQzdFLElBQUksK0JBQStCLEVBQUUsQ0FBQyxJQUFJLEtBQUssSUFBSSxJQUFJLE1BQU0sSUFBSSxJQUFJLElBQUksTUFBTTtBQUMvRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLENBQUE7O0FDcFREO0FBQ0E7QUFJQTtB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QUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxrQkFBa0I7QUFDaEcsUUFBUSxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO0FBQzlCLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDM0IsUUFBUSxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDdkQsS0FBSztBQUNMO0FBQ0EsSUFBSSxPQUFPLENBQUMsQ0FBQyxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxrQkFBa0I7QUFDdkcsUUFBUSxNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3pCLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2hDLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2hDLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2hDLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2hDLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2hDLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2hDLFFBQVEsT0FBTyxDQUFDLENBQUM7QUFDakIsS0FBSztBQUNMLENBQUM7QUFDRDtBQUNBLHFCQUFxQixDQUFDLFNBQVMsQ0FBQyxlQUFlLEdBQUcsRUFBRSxDQUFDO0FBQ3JELFFBQVEsQ0FBQyxxQkFBcUIsRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU0sMEJBQTBCLFNBQVMsV0FBVyxDQUFDO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxhQUFhLEdBQUc7QUFDcEIsUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUN0RCxRQUFRLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxVQUFVLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQ3RELFFBQVEsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLFdBQVcsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDeEQsS0FBSztBQUNMO0FBQ0EsSUFBSSxXQUFXLENBQUMsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEdBQUcsVUFBVSxHQUFHLGtCQUFrQjtBQUMxSyxRQUFRLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7QUFDOUIsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUMzQixRQUFRLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztBQUNqRixLQUFLO0FBQ0w7QUFDQSxJQUFJLE9BQU8sQ0FBQyxDQUFDLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEdBQUcsVUFBVSxHQUFHLGtCQUFrQjtBQUNqTCxRQUFRLE1BQU0sRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDMUIsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDaEMsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDaEMsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDaEMsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDaEMsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDakMsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDakMsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDakMsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDakMsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDaEMsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDaEMsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDbEMsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFH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LEtBQUssQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2hDLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2hDLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2hDLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2hDLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2xDLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2xDLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2xDLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2xDLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2pDLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2xDLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ25DLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ25DLFFBQVEsT0FBTyxDQUFDLENBQUM7QUFDakIsS0FBSztBQUNMLENBQUM7QUFDRDtBQUNBLCtCQUErQixDQUFDLFNBQVMsQ0FBQyxlQUFlLEdBQUcsRUFBRSxDQUFDO0FBQy9ELFFBQVEsQ0FBQywrQkFBK0IsRUFBRSxp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LEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsR0FBRyxVQUFVLEdBQUcsVUFBVSxHQUFHLFVBQVUsR0FBRyxVQUFVLEdBQUcsVUFBVSxHQUFHLFVBQVUsR0FBRyxVQUFVLEdBQUcsVUFBVSxHQUFHLFVBQVUsR0FBRyxVQUFVLEdBQUcsa0JBQWtCO0FBQy9SLFFBQVEsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztBQUM5QixRQUFRLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzNCLFFBQVEsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQzlILEtBQUs7QUFDTDtBQUNBLElBQUksT0FBTyxDQUFDLENBQUMsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsR0FBRyxVQUFVLEdBQUcsVUFBVSxHQUFHLFVBQVUsR0FBRyxVQUFVLEdBQUcsVUFBVSxHQUFHLFVBQVUsR0FBRyxVQUFVLEdBQUcsVUFBVSxHQUFHLFVBQVUsR0FBRyxVQUFVLEdBQUcsa0JBQWtCO0FBQ3RTLFFBQVEsTUFBTSxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUMxQixRQUFRLE1BQU0sRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDMUIsUUFBUSxNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQzFCLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2hDLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2hDLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2hDLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2xDLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2xDLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2pDLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2pDLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2pDLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2pDLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2pDLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ25DLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ25DLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ25DLFFBQVEsSUFBSSxDQUFD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RyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQzNLLEtBQUs7QUFDTDtBQUNBLElBQUksT0FBTyxDQUFDLENBQUMsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsR0FBRyxVQUFVLEdBQUcsVUFBVSxHQUFHLFVBQVUsR0FBRyxVQUFVLEdBQUcsVUFBVSxHQUFHLFVBQVUsR0FBRyxVQUFVLEdBQUcsVUFBVSxHQUFHLFVBQVUsR0FBRyxVQUFVLEdBQUcsVUFBVSxHQUFHLFVBQVUsR0FBRyxVQUFVLEdBQUcsVUFBVSxHQUFHLFVBQVUsR0FBRyxVQUFVLEdBQUcsVUFBVSxHQUFHLFVBQVUsR0FBRyxVQUFVLEdBQUcsa0JBQWtCO0FBQzNaLFFBQVEsTUFBTSxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUMxQixRQUFRLE1BQU0sRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDMUIsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDaEMsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDaEMsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDaEMsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDbEMsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDbEMsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDaEMsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDaEMsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDakMsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDakMsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDakMsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDbEMsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDbkMsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDbkMsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDbkMsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDbkMsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDbkMsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDbkMsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDbkMsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDbkMsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDbkMsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDbkMsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDbkMsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDbkMsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDbkMsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDbkMsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDbkMsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDbkMsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDcEMsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDcEMsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDcEMsUUFBUSxPQUFPLENBQUMsQ0FBQztBQUNqQixLQUFLO0FBQ0wsQ0FBQztBQUNEO0FBQ0Esa0NBQWtDLENBQUMsU0FBUyxDQUFDLGVBQWUsR0FBRyxFQUFFLENBQUM7QUFDbEUsUUFBUSxDQUFDLGtDQUFrQyxFQUFFLG9DQUFvQyxDQUFDLENBQUM7QUFDbkY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNLG9CQUFvQixTQUFTLFdBQVcsQ0FBQztBQUMvQztBQUNBO0FBQ0E7QUFDQSxJQUFJLGFBQWEsR0FBRztBQUNwQixRQUFRLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxVQUFVLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQ3RELFFBQVEsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLFlBQVksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsS0FBSztBQUNMO0FBQ0EsSUFBSSxXQUFXLENBQUMsRUFBRSxrQkFBa0I7QUFDcEMsUUFBUSxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO0FBQzlCLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDM0IsUUFBUSxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ25DLEtBQUs7QUFDTDtBQUNBLElBQUksT0FBTyxDQUFDLENBQUMsVUFBVSxFQUFFLGtCQUFrQjtBQUMzQyxRQUFRLE1BQU0sRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDekIsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDbEMsUUFBUSxPQUFPLENBQUMsQ0FBQztBQUNqQixLQUFLO0FBQ0wsQ0FBQztBQUNEO0FBQ0Esb0JBQW9CLENBQUMsU0FBUyxDQUFDLGVBQWUsR0FBRyxDQUFDLENBQUM7QUFDbkQsUUFBUSxDQUFDLG9CQUFvQixFQUFFLHNCQUFzQixDQUFDLENBQUM7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNLHFCQUFxQixTQUFTLFdBQVcsQ0FBQztBQUNoRDtBQUNBO0FBQ0E7QUFDQSxJQUFJLGFBQWEsR0FBRztBQUNwQixRQUFRLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxVQUFVLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQ3RELFFBQVEsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLFlBQVksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDMUQsS0FBSztBQUNMO0FBQ0EsSUFBSSxXQUFXLENBQUMsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsa0JBQWtCO0FBQ3BGLFFBQVEsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztBQUM5QixRQUFRLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzNCLFFBQVEsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDbkQsS0FBSztBQUNMO0FBQ0EsSUFBSSxPQUFPLENBQUMsQ0FBQyxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLGtCQUFrQjtBQUMzRixRQUFRLE1BQU0sRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDekIsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDbEMsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDbEMsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDbEMsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDbEMsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDbEMsUUFBUSxPQUFPLENBQUMsQ0FBQztBQUNqQixLQUFLO0FBQ0wsQ0FBQztBQUNEO0FBQ0EscUJBQXFCLENBQUMsU0FBUyxDQUFDLGVBQWUsR0FBRyxFQUFFLENBQUM7QUFDckQsUUFBUSxDQUFDLHFCQUFxQixFQUFFLHVCQUF1QixDQUFDLENBQUM7QUFDekQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU0seUJBQXlCLFNBQVMsV0FBVyxDQUFDO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxhQUFhLEdBQUc7QUFDcEIsUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUN0RCxRQUFRLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxXQUFXLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQ3hELFFBQVEsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLFdBQVcsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDeEQsS0FBSztBQUNMO0FBQ0EsSUFBSSxXQUFXLENBQUMsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxrQkFBa0I7QUFDeEUsUUFBUSxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO0FBQzlCLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDM0IsUUFBUSxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQy9DLEtBQUs7QUFDTDtBQUNBLElBQUksT0FBTyxDQUFDLENBQUMsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLGtCQUFrQjtBQUMvRSxRQUFRLE1BQU0sRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDekIsUUFBUSxNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3pCLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2pDLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2pDLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2pDLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2pDLFFBQVEsT0FBTyxDQUFDLENBQUM7QUFDakIsS0FBSztBQUNMLENBQUM7QUFDRDtBQUNBLHlCQUF5QixDQUFDLFNBQVMsQ0FBQyxlQUFlLEdBQUcsRUFBRSxDQUFDO0FBQ3pELFFBQVEsQ0FBQyx5QkFBeUIsRUFBRSwyQkFBMkIsQ0FBQyxDQUFDO0FBQ2pFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTSxxQkFBcUIsU0FBUyxXQUFXLENBQUM7QUFDaEQ7QUFDQTtBQUNBO0FBQ0EsSUFBSSxhQUFhLEdBQUc7QUFDcEIsUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUN0RCxRQUFRLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxXQUFXLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQ3hELEtBQUs7QUFDTDtBQUNBLElBQUksV0FBVyxDQUFDLEVBQUUsVUFBVSxFQUFFLGtCQUFrQjtBQUNoRCxRQUFRLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7QUFDOUIsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUMzQixRQUFRLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ3ZDLEtBQUs7QUFDTDtBQUNBLElBQUksT0FBTyxDQUFDLENBQUMsVUFBVSxFQUFFLFVBQVUsRUFBRSxrQkFBa0I7QUFDdkQsUUFBUSxNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3pCLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2pDLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2pDLFFBQVEsT0FBTyxDQUFDLENBQUM7QUFDakIsS0FBSztBQUNMLENBQUM7QUFDRDtBQUNBLHFCQUFxQixDQUFDLFNBQVMsQ0FBQyxlQUFlLEdBQUcsQ0FBQyxDQUFDO0FBQ3BELFFBQVEsQ0FBQyxxQkFBcUIsRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTSxxQkFBcUIsU0FBUyxXQUFXLENBQUM7QUFDaEQ7QUFDQTtBQUNBO0FBQ0EsSUFBSSxhQUFhLEdBQUc7QUFDcEIsUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUN0RCxRQUFRLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxXQUFXLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQ3hELEtBQUs7QUFDTDtBQUNBLElBQUksV0FBVyxDQUFDLEVBQUUsa0JBQWtCO0FBQ3BDLFFBQVEsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztBQUM5QixRQUFRLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzNCLFFBQVEsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNuQyxLQUFLO0FBQ0w7QUFDQSxJQUFJLE9BQU8sQ0FBQyxDQUFDLFVBQVUsRUFBRSxrQkFBa0I7QUFDM0MsUUFBUSxNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3pCLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2pDLFFBQVEsT0FBTyxDQUFDLENBQUM7QUFDakIsS0FBSztBQUNMLENBQUM7QUFDRDtBQUNBLHFCQUFxQixDQUFDLFNBQVMsQ0FBQyxlQUFlLEdBQUcsQ0FBQyxDQUFDO0FBQ3BELFFBQVEsQ0FBQyxxQkFBcUIsRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTSxvQkFBb0IsU0FBUyxXQUFXLENBQUM7QUFDL0M7QUFDQTtBQUNBO0FBQ0EsSUFBSSxhQUFhLEdBQUc7QUFDcEIsUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUN0RCxRQUFRLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxZQUFZLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQzFELEtBQUs7QUFDTDtBQUNBLElBQUksV0FBVyxDQUFDLEVBQUUsVUFBVSxFQUFFLGtCQUFrQjtBQUNoRCxRQUFRLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7QUFDOUIsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUMzQixRQUFRLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ3ZDLEtBQUs7QUFDTDtBQUNBLElBQUksT0FBTyxDQUFDLENBQUMsVUFBVSxFQUFFLFVBQVUsRUFBRSxrQkFBa0I7QUFDdkQsUUFBUSxNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3pCLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2xDLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2xDLFFBQVEsT0FBTyxDQUFDLENBQUM7QUFDakIsS0FBSztBQUNMLENBQUM7QUFDRDtBQUNBLG9CQUFvQixDQUFDLFNBQVMsQ0FBQyxlQUFlLEdBQUcsQ0FBQyxDQUFDO0FBQ25ELFFBQVEsQ0FBQyxvQkFBb0IsRUFBRSxzQkFBc0IsQ0FBQyxDQUFDO0FBQ3ZEO0FBQ0EsTUFBTSxrQkFBa0IsU0FBUyxNQUFNLENBQUM7QUFDeEM7QUFDQSxJQUFJLElBQUksZ0JBQWdCLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtBQUN0RixJQUFJLElBQUksZ0JBQWdCLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtBQUN0RixJQUFJLElBQUksZ0JBQWdCLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtBQUN0RixJQUFJLElBQUksV0FBVyxXQUFXLEVBQUUsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7QUFDakYsSUFBSSxJQUFJLFdBQVcsV0FBVyxFQUFFLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO0FBQ2pGLElBQUksSUFBSSxFQUFFLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtBQUMxRSxJQUFJLElBQUksRUFBRSxXQUFXLEVBQUUsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7QUFDMUUsSUFBSSxJQUFJLEVBQUUsV0FBVyxFQUFFLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO0FBQzFFLElBQUksSUFBSSxFQUFFLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtBQUMxRSxJQUFJLElBQUksT0FBTyxXQUFXLEVBQUUsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUU7QUFDOUUsSUFBSSxJQUFJLFlBQVksV0FBVyxFQUFFLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO0FBQ25GLElBQUksSUFBSSxnQkFBZ0IsV0FBVyxFQUFFLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFO0FBQ3hGLElBQUksSUFBSSxXQUFXLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRTtBQUNuRixDQUFDO0FBQ0Q7QUFDQSxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsSUFBSSxHQUFHLEVBQUUsQ0FBQztBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNLGlCQUFpQixTQUFTLCtCQUErQixDQUFDO0FBQ3ZFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLEdBQUcsQ0FBQyxLQUFLLDhCQUE4QjtBQUMzQyxRQUFROUMsUUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0FBQ3BDLFFBQVFBLFFBQU0sQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDM0IsUUFBUUEsUUFBTSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDcEMsUUFBUSxPQUFPLElBQUksa0JBQWtCLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ25ELEtBQUs7QUFDTCxDQUFDO0FBQ0Q7QUFDQSxRQUFRLENBQUMsaUJBQWlCLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztBQUNqRDtBQUNBLE1BQU0sa0JBQWtCLFNBQVMsTUFBTSxDQUFDO0FBQ3hDO0FBQ0EsSUFBSSxJQUFJLGdCQUFnQixXQUFXLEVBQUUsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7QUFDdEYsSUFBSSxJQUFJLGdCQUFnQixXQUFXLEVBQUUsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7QUFDdEYsSUFBSSxJQUFJLGdCQUFnQixXQUFXLEVBQUUsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7QUFDdEYsSUFBSSxJQUFJLFdBQVcsV0FBVyxFQUFFLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO0FBQ25GLElBQUksSUFBSSxXQUFXLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtBQUNuRixJQUFJLElBQUksZUFBZSxXQUFXLEVBQUUsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7QUFDdEYsSUFBSSxJQUFJLFNBQVMsV0FBVyxFQUFFLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO0FBQ2hGLElBQUksSUFBSSxnQkFBZ0IsV0FBVyxFQUFFLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO0FBQ3ZGLElBQUksSUFBSSxjQUFjLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtBQUNyRixJQUFJLElBQUksVUFBVSxXQUFXLEVBQUUsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7QUFDakYsSUFBSSxJQUFJLE9BQU8sV0FBVyxFQUFFLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFO0FBQy9FLElBQUksSUFBSSxTQUFTLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRTtBQUNqRixJQUFJLElBQUksU0FBUyxXQUFXLEVBQUUsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUU7QUFDakYsSUFBSSxJQUFJLFdBQVcsV0FBVyxFQUFFLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFO0FBQ3BGLElBQUksSUFBSSxXQUFXLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRTtBQUNwRixJQUFJLElBQUksV0FBVyxXQUFXLEVBQUUsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUU7QUFDbEYsSUFBSSxJQUFJLGlCQUFpQixXQUFXLEVBQUUsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUU7QUFDeEYsSUFBSSxJQUFJLGlCQUFpQixDQUFDLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUU7QUFDdEYsSUFBSSxJQUFJLE1BQU0sV0FBVyxFQUFFLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFO0FBQzdFLElBQUksSUFBSSxNQUFNLENBQUMsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRTtBQUMzRSxJQUFJLElBQUksV0FBVyxXQUFXLEVBQUUsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUU7QUFDbkYsSUFBSSxJQUFJLFdBQVcsQ0FBQyxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFO0FBQ2pGLElBQUksSUFBSSxtQkFBbUIsV0FBVyxFQUFFLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFO0FBQzFGLElBQUksSUFBSSxTQUFTLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRTtBQUNoRixJQUFJLElBQUksU0FBUyxDQUFDLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUU7QUFDOUUsQ0FBQztBQUNEO0FBQ0Esa0JBQWtCLENBQUMsU0FBUyxDQUFDLElBQUksR0FBRyxFQUFFLENBQUM7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sTUFBTSxpQkFBaUIsU0FBUyw2Q0FBNkMsQ0FBQztBQUNyRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxHQUFHLENBQUMsS0FBSyw4QkFBOEI7QUFDM0MsUUFBUUEsUUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0FBQ3BDLFFBQVFBLFFBQU0sQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDM0IsUUFBUUEsUUFBTSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDcEMsUUFBUSxPQUFPLElBQUksa0JBQWtCLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ25ELEtBQUs7QUFDTCxDQUFDO0FBQ0Q7QUFDQSxRQUFRLENBQUMsaUJBQWlCLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztBQUNqRDtBQUNBLE1BQU0sb0JBQW9CLFNBQVMsTUFBTSxDQUFDO0FBQzFDO0FBQ0EsSUFBSSxJQUFJLGdCQUFnQixXQUFXLEVBQUUsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7QUFDdEYsSUFBSSxJQUFJLGdCQUFnQixXQUFXLEVBQUUsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7QUFDdEYsSUFBSSxJQUFJLGdCQUFnQixXQUFXLEVBQUUsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7QUFDdEYsSUFBSSxJQUFJLFdBQVcsV0FBVyxFQUFFLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO0FBQ25GLElBQUksSUFBSSxXQUFXLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtBQUNuRixJQUFJLElBQUksNkJBQTZCLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtBQUNuRyxJQUFJLElBQUksOEJBQThCLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtBQUNwRyxJQUFJLElBQUksNEJBQTRCLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRTtBQUNuRyxJQUFJLElBQUksNkJBQTZCLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRTtBQUNwRyxJQUFJLElBQUkscUJBQXFCLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRTtBQUM1RixJQUFJLElBQUksNkJBQTZCLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRTtBQUNwRyxJQUFJLElBQUksR0FBRyxXQUFXLEVBQUUsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUU7QUFDM0UsSUFBSSxJQUFJLGlCQUFpQixXQUFXLEVBQUUsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUU7QUFDekYsSUFBSSxJQUFJLGVBQWUsV0FBVyxFQUFFLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFO0FBQ3ZGLElBQUksSUFBSSx5QkFBeUIsV0FBVyxFQUFFLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFO0FBQ2pHLElBQUksSUFBSSx1QkFBdUIsV0FBVyxFQUFFLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFO0FBQy9GLElBQUksSUFBSSxpQkFBaUIsV0FBVyxFQUFFLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFO0FBQ3pGLElBQUksSUFBSSxlQUFlLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRTtBQUN2RixJQUFJLElBQUkseUJBQXlCLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRTtBQUNqRyxJQUFJLElBQUksdUJBQXVCLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRTtBQUMvRixJQUFJLElBQUksWUFBWSxXQUFXLEVBQUUsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUU7QUFDcEYsSUFBSSxJQUFJLDBCQUEwQixXQUFXLEVBQUUsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUU7QUFDbEcsSUFBSSxJQUFJLHdCQUF3QixXQUFXLEVBQUUsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUU7QUFDaEcsSUFBSSxJQUFJLGVBQWUsV0FBVyxFQUFFLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFO0FBQ3ZGLElBQUksSUFBSSx1QkFBdUIsV0FBVyxFQUFFLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFO0FBQy9GLElBQUksSUFBSSwwQkFBMEIsV0FBVyxFQUFFLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFO0FBQ2xHLElBQUksSUFBSSxXQUFXLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRTtBQUNuRixJQUFJLElBQUksV0FBVyxDQUFDLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUU7QUFDakYsSUFBSSxJQUFJLFdBQVcsV0FBVyxFQUFFLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFO0FBQ3BGLElBQUksSUFBSSxXQUFXLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRTtBQUNwRixJQUFJLElBQUksdUJBQXVCLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRTtBQUNoRyxDQUFDO0FBQ0Q7QUFDQSxvQkFBb0IsQ0FBQyxTQUFTLENBQUMsSUFBSSxHQUFHLEVBQUUsQ0FBQztBQUN6QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNLG1CQUFtQixTQUFTLGtDQUFrQyxDQUFDO0FBQzVFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLEdBQUcsQ0FBQyxLQUFLLGdDQUFnQztBQUM3QyxRQUFRQSxRQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7QUFDcEMsUUFBUUEsUUFBTSxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQztBQUMzQixRQUFRQSxRQUFNLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUNwQyxRQUFRLE9BQU8sSUFBSSxvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDckQsS0FBSztBQUNMLENBQUM7QUFDRDtBQUNBLFFBQVEsQ0FBQyxtQkFBbUIsRUFBRSxxQkFBcUIsQ0FBQyxDQUFDO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ08sTUFBTSxnQkFBZ0IsU0FBUyxvQkFBb0IsQ0FBQztBQUMzRCxJQUFJLFVBQVUsQ0FBQyxLQUFLLGtCQUFrQixFQUFFLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7QUFDN0UsQ0FBQztBQUNEO0FBQ0EsUUFBUSxDQUFDLGdCQUFnQixFQUFFLGtCQUFrQixDQUFDLENBQUM7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNLHFCQUFxQixTQUFTLG9CQUFvQixDQUFDO0FBQ2hFLElBQUksSUFBSSxDQUFDLEtBQUssa0JBQWtCLEVBQUUsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtBQUNyRSxJQUFJLElBQUksQ0FBQyxLQUFLLGtCQUFrQixFQUFFLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7QUFDckUsQ0FBQztBQUNEO0FBQ0EsUUFBUSxDQUFDLHFCQUFxQixFQUFFLHVCQUF1QixDQUFDLENBQUM7QUFDekQ7QUFDQSxNQUFNLGtCQUFrQixTQUFTLE1BQU0sQ0FBQztBQUN4QztBQUNBLElBQUksSUFBSSxZQUFZLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtBQUNuRixJQUFJLElBQUksZ0JBQWdCLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtBQUN2RixJQUFJLElBQUksV0FBVyxXQUFXLEVBQUUsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7QUFDbEYsSUFBSSxJQUFJLHVCQUF1QixXQUFXLEVBQUUsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7QUFDOUYsQ0FBQztBQUNEO0FBQ0Esa0JBQWtCLENBQUMsU0FBUyxDQUFDLElBQUksR0FBRyxFQUFFLENBQUM7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sTUFBTSxpQkFBaUIsU0FBUyx5QkFBeUIsQ0FBQztBQUNqRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxHQUFHLENBQUMsS0FBSyw4QkFBOEI7QUFDM0MsUUFBUUEsUUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0FBQ3BDLFFBQVFBLFFBQU0sQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDM0IsUUFBUUEsUUFBTSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDcEMsUUFBUSxPQUFPLElBQUksa0JBQWtCLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ25ELEtBQUs7QUFDTCxDQUFDO0FBQ0Q7QUFDQSxRQUFRLENBQUMsaUJBQWlCLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0sMEJBQTBCLFNBQVMscUJBQXFCLENBQUM7QUFDdEUsSUFBSSxrQkFBa0IsQ0FBQyxLQUFLLGtCQUFrQixFQUFFLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7QUFDcEYsSUFBSSxrQkFBa0IsQ0FBQyxLQUFLLGtCQUFrQixFQUFFLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7QUFDcEYsQ0FBQztBQUNEO0FBQ0EsUUFBUSxDQUFDLDBCQUEwQixFQUFFLDRCQUE0QixDQUFDLENBQUE7O0FDeHFDbEU7QUFFQTtBQUNBO0FBQ0E7QUFDQSxNQUFNLGlCQUFpQixzQkFBc0IsWUFBWSxDQUFDO0FBQzFEO0FBQ0EsSUFBSSxDQUFDLElBQUksRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsUUFBUSxDQUFDO0FBQ3RELElBQUksQ0FBQyxJQUFJLEVBQUUsZUFBZSxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLFNBQVMsQ0FBQztBQUMzRCxDQUFDLENBQUMsQ0FBQTs7QUNURjtBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQU0sY0FBYyxzQkFBc0IsWUFBWSxDQUFDO0FBQ3ZELElBQUksQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLFFBQVEsQ0FBQztBQUNuRCxDQUFDLENBQUMsQ0FBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDTUYsQ0FBQSxTQUFTLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUU7QUFDckMsRUFBQSxJQUFJLFNBQVMsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUN4RDtBQUNBLEVBQUMsU0FBUyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0FBQzVCLEVBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDO0VBQy9CLEVBQUUsR0FBRyxJQUFJLENBQUM7RUFDVixFQUFFLEdBQUcsVUFBVSxDQUFDO0VBQ2hCLEVBQUUsR0FBRyxVQUFVLENBQUM7RUFDaEIsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNQO0FBQ0EsRUFBQyxPQUFPLENBQUMsR0FBRyxLQUFLLEVBQUU7QUFDbkIsS0FBSSxFQUFFO0FBQ0EsT0FBQSxFQUFFLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSTtBQUNoQyxRQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLElBQUksS0FBSyxDQUFDLENBQUM7QUFDekMsUUFBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFDO0FBQzFDLFFBQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0FBQ3pDLEdBQUEsRUFBRSxDQUFDLENBQUM7QUFDTjtHQUNFLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsTUFBTSxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxNQUFNLEtBQUssRUFBRSxDQUFDLEtBQUssVUFBVSxDQUFDO0dBQ25GLEVBQUUsR0FBRyxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0dBQzlCLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsTUFBTSxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxNQUFNLEtBQUssRUFBRSxDQUFDLEtBQUssVUFBVSxDQUFDO0FBQ3JGO0dBQ0UsRUFBRSxJQUFJLEVBQUUsQ0FBQztTQUNILEVBQUUsR0FBRyxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0dBQ3BDLEdBQUcsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsSUFBSSxNQUFNLEtBQUssRUFBRSxDQUFDLEtBQUssVUFBVSxDQUFDO0dBQ2xGLEVBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxHQUFHLE1BQU0sSUFBSSxNQUFNLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLEVBQUUsSUFBSSxNQUFNLElBQUksTUFBTSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDOUUsR0FBQTtBQUNGO0VBQ0MsRUFBRSxHQUFHLENBQUMsQ0FBQztBQUNSO0FBQ0EsRUFBQyxRQUFRLFNBQVM7QUFDbEIsR0FBRSxLQUFLLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFDO0FBQ3JELEdBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxLQUFLLENBQUMsQ0FBQztBQUNwRCxHQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsS0FBSyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO0FBQzNDO0dBQ0UsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxNQUFNLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxJQUFJLE1BQU0sS0FBSyxFQUFFLENBQUMsSUFBSSxVQUFVLENBQUM7R0FDakYsRUFBRSxHQUFHLENBQUMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7R0FDOUIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUs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QUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQyxNQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRTtBQUM3QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLFVBQVEsQ0FBQyxHQUFHLEVBQUU7QUFDOUIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLFlBQVUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUU7QUFDL0MsRUFBRSxJQUFJLEdBQUcsR0FBRyxJQUFJSCxVQUFtQixDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNmLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNmLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNmLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNmLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNJLEtBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFO0FBQzdDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNmLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNmLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNmLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNmLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLFdBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFO0FBQ2xDO0FBQ0E7QUFDQSxFQUFFLElBQUksR0FBRyxLQUFLLENBQUMsRUFBRTtBQUNqQixJQUFJLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEIsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2hCLEdBQUcsTUFBTTtBQUNULElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEIsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsQixHQUFHO0FBQ0g7QUFDQSxFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQyxRQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRTtBQUMvQixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQjtBQUNBLEVBQUUsSUFBSSxHQUFHLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQzlCO0FBQ0EsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFO0FBQ1osSUFBSSxPQUFPLElBQUksQ0FBQztBQUNoQixHQUFHO0FBQ0g7QUFDQSxFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDO0FBQ2xCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxHQUFHLENBQUM7QUFDcEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDO0FBQ3JCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQztBQUNyQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsR0FBRyxDQUFDO0FBQ3BCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLFNBQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFO0FBQ2hDO0FBQ0EsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNkLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQyxhQUFXLENBQUMsQ0FBQyxFQUFFO0FBQy9CLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbkMsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLFVBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNwQyxFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDN0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQzdCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUM3QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDN0IsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQyxRQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUU7QUFDcEMsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3hCLEVBQUUsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN4QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDM0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQzNCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQzVCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQzVCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsT0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ2pDLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ25CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDbkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUNuQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ25CLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsY0FBWSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUU7QUFDdkMsRUFBRSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3hCLEVBQUUsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN4QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsYUFBVyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUU7QUFDcEMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsS0FBRyxDQUFDLENBQUMsRUFBRTtBQUN2QixFQUFFLE9BQU8sT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDeEUsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsTUFBSSxDQUFDLENBQUMsRUFBRTtBQUN4QixFQUFFLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM1QyxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNoQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3JCLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNkLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNkLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzVCLEVBQUUsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDbkIsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLEtBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUMvQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsVUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ3BDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsYUFBVyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDbEMsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDMUUsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTcEIsUUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDN0IsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJcUIsT0FBZ0IsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSUEsT0FBZ0IsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSUEsT0FBZ0IsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSUEsT0FBZ0IsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUMxVixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsZ0JBQWMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUMxQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDcEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNwQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQyxzQkFBb0IsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUU7QUFDdkQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUM7QUFDL0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUM7QUFDL0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUM7QUFDL0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUM7QUFDL0IsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sSUFBSUMsS0FBRyxHQUFHYixVQUFRLENBQUM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLElBQUljLEtBQUcsR0FBR04sVUFBUSxDQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQzlhekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTbEIsUUFBTSxHQUFHO0FBQ3pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsSUFBSUMsVUFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QztBQUNBLEVBQUUsSUFBSUEsVUFBbUIsSUFBSSxZQUFZLEVBQUU7QUFDM0MsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2YsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2YsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2YsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2YsR0FBRztBQUNIO0FBQ0EsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVN6RCxPQUFLLENBQUMsQ0FBQyxFQUFFO0FBQ3pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsSUFBSXlELFVBQW1CLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsTUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUU7QUFDN0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLFVBQVEsQ0FBQyxHQUFHLEVBQUU7QUFDOUIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQyxZQUFVLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUU7QUFDL0MsRUFBRSxJQUFJLEdBQUcsR0FBRyxJQUFJSCxVQUFtQixDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNkLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTSSxLQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFO0FBQzdDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLENB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QUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUM3QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDN0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQzdCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUM3QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ2xDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDbEMsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQyxRQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUU7QUFDcEMsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLElB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LENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLFVBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNwQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNHLGdCQUFjLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDMUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNwQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDcEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNwQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDcEIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLHNCQUFvQixDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRTtBQUN2RCxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUMvQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUMvQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUMvQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUMvQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUMvQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUMvQixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTSCxhQUFXLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNsQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDNUcsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTcEIsUUFB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QUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQyxNQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRTtBQUM3QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNFLFlBQVUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRTtBQUN4RSxFQUFFLElBQUksR0FBRyxHQUFHLElBQUlILFVBQW1CLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNJLEtBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUU7QUFDdEUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNGLFVBQVEsQ0FBQyxHQUFHLEVBQUU7QUFDOUIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0csV0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUU7QUFDbEM7QUFDQSxFQUFFLElBQUksR0FBRyxLQUFLLENBQUMsRUFBRTtBQUNqQixJQUFJLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEIsUUFBUSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsQixRQUFRLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbkIsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDakIsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNqQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDakIsR0FBRyxNQUFNO0FBQ1QsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEIsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEIsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEIsR0FBRztBQUNIO0FBQ0EsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsUUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUU7QUFDL0IsRUFBRSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQixFQUFFLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakIsRUFBRSxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDbEMsRUFBRSxJQUFJLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNuQyxFQUFFLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNsQztBQUNBLEVBQUUsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDOUM7QUFDQSxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUU7QUFDWixJQUFJLE9BQU8sSUFBSSxDQUFDO0FBQ2hCLEdBQUc7QUFDSDtBQUNBLEVBQUUsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDbEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNyQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQztBQUMxQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7QUFDekMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNyQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7QUFDekMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7QUFDMUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNyQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQztBQUMxQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7QUFDekMsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsU0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUU7QUFDaEMsRUFBRSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQixFQUFFLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDO0FBQ2pDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNqQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDakMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDO0FBQ2pDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNqQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDakMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDO0FBQ2pDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNqQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDakMsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLGFBQVcsQ0FBQyxDQUFDLEVBQUU7QUFDL0IsRUFBRSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQixFQUFFLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakIsRUFBRSxPQUFPLEdBQUcsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUM7QUFDeEcsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLFVBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNwQyxFQUFFLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakIsRUFBRSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQixFQUFFLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakIsRUFBRSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUM3QyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUM3QyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUM3QyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUM3QyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUM3QyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUM3QyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUM3QyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUM3QyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUM3QyxFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNlLFdBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNyQyxFQUFFLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDZixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDZixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDZixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDZixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDZixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDZixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDO0FBQ25DLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDbkMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNuQyxFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNkLFFBQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRTtBQUNwQyxFQUFFLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDO0FBQ3ZCLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDeEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQzdCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUM3QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDN0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQzdCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUM3QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDN0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQyxPQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDakMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2QsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNwQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDcEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNwQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDcEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTYyxpQkFBZSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUU7QUFDeEMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNiLGNBQVksQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFO0FBQ3ZDLEVBQUUsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUM7QUFDdkIsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN4QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsYUFBVyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUU7QUFDcEMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFO0FBQ2xDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENB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LENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakIsRUFBRSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakIsRUFBRSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUNqQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDbEIsRUFBRSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO0FBQ2pCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDakIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUNqQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDbEIsRUFBRSxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDbEMsRUFBRSxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDbEMsRUFBRSxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDbEMsRUFBRSxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDbEMsRUFBRSxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDbEMsRUFBRSxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDbEMsRUFBRSxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDbEMsRUFBRSxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDbEMsRUFBRSxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDbEMsRUFBRSxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDbEMsRUFBRSxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDbEMsRUFBRSxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDbEM7QUFDQSxFQUFFLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDO0FBQ2xGO0FBQ0EsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFO0FBQ1osSUFBSSxPQUFPLElBQUksQ0FBQztBQUNoQixHQUFHO0FBQ0g7QUFDQSxFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDO0FBQ2xCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDO0FBQ3JELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDO0FBQ3JELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDO0FBQ3JELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDO0FBQ3JELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDO0FBQ3JELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDO0FBQ3JELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDO0FBQ3JELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDO0FBQ3JELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDO0FBQ3JELEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyxVQUFVLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUU7QUFDL0MsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUNyQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDZCxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU2IsS0FBRyxDQUFDLENBQUMsRUFBRTtBQUN2QixFQUFFLE9BQU8sT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQzlJLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLE1BQUksQ0FBQyxDQUFDLEVBQUU7QUFDeEIsRUFBRSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMxRSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsS0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQy9CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsVUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ3BDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0csZ0JBQWMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUMxQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDcEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNwQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDcEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNwQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDcEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNwQixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0Msc0JBQW9CLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFO0FBQ3ZELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO0FBQy9CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO0FBQy9CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO0FBQy9CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO0FBQy9CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO0FBQy9CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO0FBQy9CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO0FBQy9CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO0FBQy9CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO0FBQy9CLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNILGFBQVcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ2xDLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvSixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNwQixRQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUM3QixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJcUIsT0FBZ0IsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSUEsT0FBZ0IsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSUEsT0FBZ0IsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSUEsT0FBZ0IsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSUEsT0FBZ0IsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSUEsT0FBZ0IsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSUEsT0FBZ0IsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSUEsT0FBZ0IsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSUEsT0FBZ0IsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNud0IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxJQUFJRyxLQUFHLEdBQUdiLFVBQVEsQ0FBQztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sSUFBSWMsS0FBRyxHQUFHTixVQUFRLENBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDeHdCekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNsQixRQUFNLEdBQUc7QUFDekIsRUFBRSxJQUFJLEdBQUcsR0FBRyxJQUFJQyxVQUFtQixDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3hDO0FBQ0EsRUFBRSxJQUFJQSxVQUFtQixJQUFJLFlBQVksRUFBRTtBQUMzQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZixJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDaEIsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2hCLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNoQixJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDaEIsR0FBRztBQUNIO0FBQ0EsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVN6RCxPQUFLLENBQUMsQ0FBQyxFQUFFO0FBQ3pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsSUFBSXlELFVBQW1CLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDeEMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNsQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDbEIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2xCLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNsQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDbEIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2xCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLE1BQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFO0FBQzdCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDbEIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2xCLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNsQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDbEIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2xCLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNsQixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0UsWUFBVSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRTtBQUMzRyxFQUFFLElBQUksR0FBRyxHQUFHLElBQUlILFVBQW1CLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDeEMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDaEIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0ksS0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUU7QUFDekcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDaEIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNGLFVBQVEsQ0FBQyxHQUFHLEVBQUU7QUFDOUIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRTtBQUNsQztBQUNBLEVBQUUsSUFBSSxHQUFHLEtBQUssQ0FBQyxFQUFFO0FBQ2pCLElBQUksSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsQixRQUFRLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLFFBQVEsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNuQixJQUFJLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEIsUUFBUSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ25CLElBQUksSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3BCLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEIsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ25CLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNqQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEIsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ25CLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNqQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDakIsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3BCLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNsQixJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDbEIsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2xCLEdBQUcsTUFBTTtBQUNULElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEIsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNuQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEIsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDbkIsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsQixJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDcEIsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3BCLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNuQixJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbkIsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3BCLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNwQixHQUFHO0FBQ0g7QUFDQSxFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTSSxRQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRTtBQUMvQixFQUFFLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQixFQUFFLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQixFQUFFLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO0FBQ2pCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNsQixFQUFFLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDakIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUNqQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO0FBQ2pCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNsQixFQUFFLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNsQyxFQUFFLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNsQyxFQUFFLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNsQyxFQUFFLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNsQyxFQUFFLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNsQyxFQUFFLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNsQyxFQUFFLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNsQyxFQUFFLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNsQyxFQUFFLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNsQyxFQUFFLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNsQyxFQUFFLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNsQyxFQUFFLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNsQztBQUNBLEVBQUUsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDbEY7QUFDQSxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUU7QUFDWixJQUFJLE9BQU8sSUFBSSxDQUFDO0FBQ2hCLEdBQUc7QUFDSDtBQUNBLEVBQUUsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDbEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7QUFDckQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7QUFDckQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7QUFDckQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7QUFDckQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7QUFDckQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7QUFDckQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7QUFDckQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7QUFDckQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7QUFDckQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7QUFDckQsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7QUFDdEQsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7QUFDdEQsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7QUFDdEQsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7QUFDdEQsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7QUFDdEQsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7QUFDdEQsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRTtBQUNoQyxFQUFFLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQixFQUFFLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQixFQUFFLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO0FBQ2pCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNsQixFQUFFLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDakIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUNqQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO0FBQ2pCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNsQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUN6RyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDNUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUM7QUFDekcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzVHLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUM1RyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUN6RyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDNUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUM7QUFDekcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUM7QUFDekcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzVHLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQzFHLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUM3RyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDN0csRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUM7QUFDMUcsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzdHLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQzFHLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLFdBQVcsQ0FBQyxDQUFDLEVBQUU7QUFDL0IsRUFBRSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakIsRUFBRSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakIsRUFBRSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUNqQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDbEIsRUFBRSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO0FBQ2pCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDakIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUNqQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDbEIsRUFBRSxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDbEMsRUFBRSxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDbEMsRUFBRSxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDbEMsRUFBRSxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDbEMsRUFBRSxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDbEMsRUFBRSxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDbEMsRUFBRSxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFH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QUFFLEdBQUcsR0FBRyxDQUFDO0FBQ3JELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLENBQUM7QUFDckQsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ1osRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ1osRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ1osRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ1osRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQztBQUNyRCxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxDQUFDO0FBQ3JELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLENBQUM7QUFDckQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQztBQUNyRCxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDWixFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDWixFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDYixFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxDQUFDO0FBQ3JELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLENBQUM7QUFDckQsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQztBQUN0RCxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxDQUFDO0FBQ3RELEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNiLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNiLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNiLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLENBQUM7QUFDdEQsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQztBQUN0RCxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxDQUFDO0FBQ3RELEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLENBQUM7QUFDdEQsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTZSxXQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDckMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2QsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNkLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLEVBQUUsSUFBSSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUM7QUFDekIsRUFBRSxJQUFJLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQztBQUN6QixFQUFFLElBQUksR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDO0FBQ3pCO0FBQ0EsRUFBRSxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUU7QUFDakIsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3JELElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNyRCxJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDdEQsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3RELEdBQUcsTUFBTTtBQUNULElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNoQixJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDaEIsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2pCLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNqQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDakIsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2pCLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNqQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDakIsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2pCLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNqQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDakIsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2pCLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNsQixJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDbEIsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2xELElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNsRCxJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDbEQsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2xELEdBQUc7QUFDSDtBQUNBLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU2IsT0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ2pDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNkLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDcEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNwQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDcEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNwQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDcEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNwQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDdEIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN0QixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDbEIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2xCLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNsQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDbEIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNELFFBQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUU7QUFDMUMsRUFBRSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDakIsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLEVBQUUsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNkLEVBQUUsSUFBSSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUM7QUFDekIsRUFBRSxJQUFJLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQztBQUN6QixFQUFFLElBQUksR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDO0FBQ3pCLEVBQUUsSUFBSSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQztBQUNwQixFQUFFLElBQUksR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUM7QUFDcEIsRUFBRSxJQUFJLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDO0FBQ3BCO0FBQ0EsRUFBRSxJQUFJLEdBQUcsR0FBR1MsT0FBZ0IsRUFBRTtBQUM5QixJQUFJLE9BQU8sSUFBSSxDQUFDO0FBQ2hCLEdBQUc7QUFDSDtBQUNBLEVBQUUsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDaEIsRUFBRSxDQUFDLElBQUksR0FBRyxDQUFDO0FBQ1gsRUFBRSxDQUFDLElBQUksR0FBRyxDQUFDO0FBQ1gsRUFBRSxDQUFDLElBQUksR0FBRyxDQUFDO0FBQ1gsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNwQixFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDWixFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDZCxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDZDtBQUNBLEVBQUUsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN0QixFQUFFLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzFCLEVBQUUsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDMUIsRUFBRSxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUMxQixFQUFFLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDdEIsRUFBRSxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUMxQixFQUFFLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzFCLEVBQUUsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDMUIsRUFBRSxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3RCO0FBQ0EsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDN0MsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDN0MsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDN0MsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDN0MsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDN0MsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDN0MsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDN0MsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDN0MsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDN0MsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDN0MsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDOUMsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDOUM7QUFDQSxFQUFFLElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRTtBQUNqQjtBQUNBLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNwQixJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDcEIsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3BCLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNwQixHQUFHO0FBQ0g7QUFDQSxFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNTLFNBQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRTtBQUNyQyxFQUFFLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDeEIsRUFBRSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3hCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2xCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2xCO0FBQ0EsRUFBRSxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUU7QUFDakI7QUFDQSxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEIsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEIsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3BCLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNwQixJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDcEIsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3BCLEdBQUc7QUFDSDtBQUNBO0FBQ0EsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQzdCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUM3QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUM7QUFDN0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQzdCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUM3QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUM7QUFDN0IsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQzlCLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUM5QixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLFNBQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRTtBQUNyQyxFQUFFLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDeEIsRUFBRSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3hCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2xCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2xCO0FBQ0EsRUFBRSxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUU7QUFDakI7QUFDQSxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEIsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEIsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3BCLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNwQixJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDcEIsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3BCLEdBQUc7QUFDSDtBQUNBO0FBQ0EsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQzdCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUM3QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUM7QUFDN0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQzdCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUM3QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUM7QUFDN0IsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQzlCLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUM5QixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLFNBQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRTtBQUNyQyxFQUFFLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDeEIsRUFBRSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3hCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCO0FBQ0EsRUFBRSxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUU7QUFDakI7QUFDQSxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEIsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNwQixJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDcEIsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3BCLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNwQixJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDcEIsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3BCLEdBQUc7QUFDSDtBQUNBO0FBQ0EsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQzdCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUM3QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUM7QUFDN0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQzdCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUM3QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUM7QUFDN0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQzdCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUM3QixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNMLGlCQUFlLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRTtBQUN4QyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVMsV0FBVyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUU7QUFDcEMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNiLGNBQVksQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRTtBQUM3QyxFQUFFLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDakIsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztBQUNqQixNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEIsRUFBRSxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDaEMsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2Q7QUFDQSxFQUFFLElBQUksR0FBRyxHQUFHTyxPQUFnQixFQUFFO0FBQzlCLElBQUksT0FBTyxJQUFJLENBQUM7QUFDaEIsR0FBRztBQUNIO0FBQ0EsRUFBRSxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNoQixFQUFFLENBQUMsSUFBSSxHQUFHLENBQUM7QUFDWCxFQUFFLENBQUMsSUFBSSxHQUFHLENBQUM7QUFDWCxFQUFFLENBQUMsSUFBSSxHQUFHLENBQUM7QUFDWCxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDcEIsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNaO0FBQ0EsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3pCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDN0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUM3QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzdCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN6QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzdCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDN0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUM3QixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDMUIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLGFBQWEsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFO0FBQ3hDLEVBQUUsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN4QixFQUFFLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDeEI7QUFDQSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNkLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyxhQUFhLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRTtBQUN4QyxFQUFFLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDeEIsRUFBRSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3hCO0FBQ0EsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDZCxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVMsYUFBYSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUU7QUFDeEMsRUFBRSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3hCLEVBQUUsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN4QjtBQUNBLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNZLHlCQUF1QixDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ25EO0FBQ0EsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2QsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNkLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDakIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNqQixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDbEIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2xCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNsQixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDbEIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2xCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNsQixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDbEIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2xCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNsQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0FBQ3pCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDbkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUNuQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ25CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7QUFDekIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUNuQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ25CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDbkIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztBQUMxQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFO0FBQ2xDLEVBQUUsSUFBSSxXQUFXLEdBQUcsSUFBSS9CLFVBQW1CLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0MsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsSUFBSSxTQUFTLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUN4RDtBQUNBLEVBQUUsSUFBSSxTQUFTLEdBQUcsQ0FBQyxFQUFFO0FBQ3JCLElBQUksV0FBVyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsU0FBUyxDQUFDO0FBQzdFLElBQUksV0FBVyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsU0FBUyxDQUFDO0FBQzdFLElBQUksV0FBVyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsU0FBUyxDQUFDO0FBQzdFLEdBQUcsTUFBTTtBQUNULElBQUksV0FBVyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDakUsSUFBSSxXQUFXLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUNqRSxJQUFJLFdBQVcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ2pFLEdBQUc7QUFDSDtBQUNBLEVBQUUrQix5QkFBdUIsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxDQUFDO0FBQy9DLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQyxnQkFBYyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUU7QUFDekMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ25CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNuQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDbkIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyxVQUFVLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRTtBQUNyQyxFQUFFLElBQUksR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNuQixFQUFFLElBQUksR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNuQixFQUFFLElBQUksR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNuQixFQUFFLElBQUksR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNuQixFQUFFLElBQUksR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNuQixFQUFFLElBQUksR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNuQixFQUFFLElBQUksR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNuQixFQUFFLElBQUksR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNuQixFQUFFLElBQUksR0FBRyxHQUFHLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNwQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDckMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ3JDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztBQUNyQyxFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyxXQUFXLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRTtBQUN0QyxFQUFFLElBQUksT0FBTyxHQUFHLElBQUloQyxVQUFtQixDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNDLEVBQUUsVUFBVSxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQztBQUMzQixFQUFFLElBQUksR0FBRyxHQUFHLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDM0IsRUFBRSxJQUFJLEdBQUcsR0FBRyxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMzQixFQUFFLElBQUksSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDMUIsRUFBRSxJQUFJLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQzFCLEVBQUUsSUFBSSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUMxQixFQUFFLElBQUksSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDMUIsRUFBRSxJQUFJLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQzFCLEVBQUUsSUFBSSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUMxQixFQUFFLElBQUksSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDMUIsRUFBRSxJQUFJLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQzFCLEVBQUUsSUFBSSxJQUFJLEdBQUcsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUMzQixFQUFFLElBQUksS0FBSyxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ2pDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ1o7QUFDQSxFQUFFLElBQUksS0FBSyxHQUFHLENBQUMsRUFBRTtBQUNqQixJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDbkMsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQztBQUN0QixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDO0FBQy9CLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUM7QUFDL0IsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsQ0FBQztBQUMvQixHQUFHLE1BQU0sSUFBSSxJQUFJLEdBQUcsSUFBSSxJQUFJLElBQUksR0FBRyxJQUFJLEVBQUU7QUFDekMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDaEQsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsQ0FBQztBQUMvQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDO0FBQ3RCLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUM7QUFDL0IsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsQ0FBQztBQUMvQixHQUFHLE1BQU0sSUFBSSxJQUFJLEdBQUcsSUFBSSxFQUFFO0FBQzFCLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2hELElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUM7QUFDL0IsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsQ0FBQztBQUMvQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDO0FBQ3RCLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUM7QUFDL0IsR0FBRyxNQUFNO0FBQ1QsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDaEQsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsQ0FBQztBQUMvQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDO0FBQy9CLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUM7QUFDL0IsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQztBQUN0QixHQUFHO0FBQ0g7QUFDQSxFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVMsNEJBQTRCLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQzNEO0FBQ0EsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2QsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNkLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDakIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNqQixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDbEIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2xCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNsQixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDbEIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2xCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNsQixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDbEIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2xCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNsQixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO0FBQ2hDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLENBQUM7QUFDMUIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsQ0FBQztBQUMxQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxDQUFDO0FBQzFCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7QUFDaEMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsQ0FBQztBQUMxQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxDQUFDO0FBQzFCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLENBQUM7QUFDMUIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUNqQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVMsa0NBQWtDLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNwRTtBQUNBLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNkLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2QsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNqQixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDakIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2xCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNsQixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDbEIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2xCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNsQixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDbEIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2xCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNsQixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDbEIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxJQUFJLElBQUksR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO0FBQ2xDLEVBQUUsSUFBSSxJQUFJLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsQ0FBQztBQUM1QixFQUFFLElBQUksSUFBSSxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLENBQUM7QUFDNUIsRUFBRSxJQUFJLElBQUksR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxDQUFDO0FBQzVCLEVBQUUsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUNsQyxFQUFFLElBQUksSUFBSSxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLENBQUM7QUFDNUIsRUFBRSxJQUFJLElBQUksR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxDQUFDO0FBQzVCLEVBQUUsSUFBSSxJQUFJLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsQ0FBQztBQUM1QixFQUFFLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7QUFDbkMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUM7QUFDbEIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxJQUFJLEdBQUcsRUFBRSxHQUFHLElBQUksR0FBRyxFQUFFLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0FBQzVELEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLElBQUksSUFBSSxHQUFHLEVBQUUsR0FBRyxJQUFJLEdBQUcsRUFBRSxHQUFHLElBQUksR0FBRyxFQUFFLENBQUMsQ0FBQztBQUM1RCxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxJQUFJLElBQUksR0FBRyxFQUFFLEdBQUcsSUFBSSxHQUFHLEVBQUUsR0FBRyxLQUFLLEdBQUcsRUFBRSxDQUFDLENBQUM7QUFDN0QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFO0FBQ2pDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNkLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2QsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNqQixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDakIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2xCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNsQixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDbEIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2xCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNsQixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDbEIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2xCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNsQixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDbEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUNuQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ25CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDbkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUNuQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ25CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDbkIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDeEIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVMsT0FBTyxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRTtBQUNsRSxFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUM7QUFDOUIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLElBQUksR0FBRyxHQUFHLE1BQU0sQ0FBQyxDQUFDO0FBQzlCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQztBQUM1QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUN6QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUN6QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEtBQUssR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO0FBQy9CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLE1BQU0sSUFBSSxFQUFFLENBQUM7QUFDL0IsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztBQUM5QixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNmLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNoQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLGFBQWEsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFO0FBQzVELEVBQUUsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQztBQUNsQyxNQUFNLEVBQUUsQ0FBQztBQUNULEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUM7QUFDdEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZDtBQUNBLEVBQUUsSUFBSSxHQUFHLElBQUksSUFBSSxJQUFJLEdBQUcsS0FBSyxRQUFRLEVBQUU7QUFDdkMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQztBQUMxQixJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO0FBQ2hDLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztBQUNsQyxHQUFHLE1BQU07QUFDVCxJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNqQixJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUM7QUFDeEIsR0FBRztBQUNIO0FBQ0EsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ1UsSUFBQyxXQUFXLEdBQUcsYUFBYyxDQUFBO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLGFBQWEsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFO0FBQzVELEVBQUUsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQztBQUNsQyxNQUFNLEVBQUUsQ0FBQztBQUNULEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUM7QUFDdEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZDtBQUNBLEVBQUUsSUFBSSxHQUFHLElBQUksSUFBSSxJQUFJLEdBQUcsS0FBSyxRQUFRLEVBQUU7QUFDdkMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQztBQUMxQixJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLEdBQUcsRUFBRSxDQUFDO0FBQ3ZCLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsR0FBRyxJQUFJLEdB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QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLE9BQU8sQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUU7QUFDbEUsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLElBQUksSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDO0FBQzlCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQztBQUM5QixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUM7QUFDNUIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ25CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNuQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ25CLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FB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O0FBQ1osRUFBRSxFQUFFLElBQUksR0FBRyxDQUFDO0FBQ1osRUFBRSxFQUFFLElBQUksR0FBRyxDQUFDO0FBQ1osRUFBRSxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxDQUFDO0FBQzNCLEVBQUUsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsQ0FBQztBQUMzQixFQUFFLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLENBQUM7QUFDM0IsRUFBRSxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQy9CO0FBQ0EsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFO0FBQ1osSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ1gsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ1gsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ1gsR0FBRyxNQUFNO0FBQ1QsSUFBSSxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNsQixJQUFJLEVBQUUsSUFBSSxHQUFHLENBQUM7QUFDZCxJQUFJLEVBQUUsSUFBSSxHQUFHLENBQUM7QUFDZCxJQUFJLEVBQUUsSUFBSSxHQUFHLENBQUM7QUFDZCxHQUFHO0FBQ0g7QUFDQSxFQUFFLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDekIsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ3pCLEVBQUUsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUN6QixFQUFFLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDL0I7QUFDQSxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUU7QUFDWixJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDWCxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDWCxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDWCxHQUFHLE1BQU07QUFDVCxJQUFJLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2xCLElBQUksRUFBRSxJQUFJLEdBQUcsQ0FBQztBQUNkLElBQUksRUFBRSxJQUFJLEdBQUcsQ0FBQztBQUNkLElBQUksRUFBRSxJQUFJLEdBQUcsQ0FBQztBQUNkLEdBQUc7QUFDSDtBQUNBLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNmLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxHQUFHLElBQUksR0FBRyxFQUFFLEdBQUcsSUFBSSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQztBQUNqRCxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsR0FBRyxJQUFJLEdBQUcsRUFBRSxHQUFHLElBQUksR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7QUFDakQsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLEdBQUcsSUFBSSxHQUFHLEVBQUUsR0FBRyxJQUFJLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDO0FBQ2pELEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNkLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLFFBQVEsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUU7QUFDL0MsRUFBRSxJQUFJLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ25CLE1BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDbkIsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNuQixNQUFNLEdBQUcsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDakIsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLEVBQUUsSUFBSSxFQUFFLEdBQUcsSUFBSSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFDM0IsTUFBTSxFQUFFLEdBQUcsSUFBSSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFDM0IsTUFBTSxFQUFFLEdBQUcsSUFBSSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM1QixFQUFFLElBQUksR0FBRyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ3hDO0FBQ0EsRUFBRSxJQUFJLEdBQUcsR0FBRyxDQUFDLEVBQUU7QUFDZixJQUFJLEdBQUcsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUM3QixJQUFJLEVBQUUsSUFBSSxHQUFHLENBQUM7QUFDZCxJQUFJLEVBQUUsSUFBSSxHQUFHLENBQUM7QUFDZCxJQUFJLEVBQUUsSUFBSSxHQUFHLENBQUM7QUFDZCxHQUFHO0FBQ0g7QUFDQSxFQUFFLElBQUksRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUU7QUFDOUIsTUFBTSxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRTtBQUM5QixNQUFNLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLENBQUM7QUFDL0IsRUFBRSxHQUFHLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDcEM7QUFDQSxFQUFFLElBQUksR0FBRyxHQUFHLENBQUMsRUFBRTtBQUNmLElBQUksR0FBRyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzdCLElBQUksRUFBRSxJQUFJLEdBQUcsQ0FBQztBQUNkLElBQUksRUFBRSxJQUFJLEdBQUcsQ0FBQztBQUNkLElBQUksRUFBRSxJQUFJLEdBQUcsQ0FBQztBQUNkLEdBQUc7QUFDSDtBQUNBLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUM3QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDN0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQzdCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNmLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQztBQUNqQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUM7QUFDakIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDO0FBQ2pCLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNkLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTWSxLQUFHLENBQUMsQ0FBQyxFQUFFO0FBQ3ZCLEVBQUUsT0FBTyxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUN0UCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLElBQUksQ0FBQyxDQUFDLEVBQUU7QUFDeEIsRUFBRSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDMUgsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNFLEtBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUMvQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDMUIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUMxQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQzFCLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDMUIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUMxQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQzFCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsVUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ3BDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUMxQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQzFCLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDMUIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUMxQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQzFCLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDMUIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLGNBQWMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUMxQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDcEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNwQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDcEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNwQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDcEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNwQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDdEIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN0QixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3RCLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDdEIsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN0QixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3RCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLG9CQUFvQixDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRTtBQUN2RCxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUMvQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUMvQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUMvQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUMvQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUMvQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUMvQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUMvQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUMvQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUMvQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUMvQixFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUNsQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUNsQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUNsQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUNsQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUNsQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUNsQyxFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQyxhQUFXLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNsQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNsUyxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNwQixRQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUM3QixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUNqQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDbEIsRUFBRSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO0FBQ2pCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDakIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUNqQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDbEIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDakIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2xCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUNqQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO0FBQ2pCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDakIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2xCLEVBQUUsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSXFCLE9BQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUlBLE9BQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUlBLE9BQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUlBLE9BQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUlBLE9BQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUlBLE9BQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUlBLE9BQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUlBLE9BQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUlBLE9BQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUlBLE9BQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLElBQUlBLE9BQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLElBQUlBLE9BQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLElBQUlBLE9BQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLElBQUlBLE9BQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLElBQUlBLE9BQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLElBQUlBLE9BQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDOTJDLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ1UsSUFBQ0csS0FBRyxHQUFHYixVQUFTLENBQUE7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLElBQUljLEtBQUcsR0FBR04sVUFBUSxDQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNwM0R6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU2xCLFFBQU0sR0FBRztBQUN6QixFQUFFLElBQUksR0FBRyxHQUFHLElBQUlDLFVBQW1CLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkM7QUFDQSxFQUFFLElBQUlBLFVBQW1CLElBQUksWUFBWSxFQUFFO0FBQzNDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNmLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNmLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNmLEdBQUc7QUFDSDtBQUNBLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTekQsT0FBSyxDQUFDLENBQUMsRUFBRTtBQUN6QixFQUFFLElBQUksR0FBRyxHQUFHLElBQUl5RCxVQUFtQixDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTaUMsUUFBTSxDQUFDLENBQUMsRUFBRTtBQUMxQixFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzdCLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTOUIsWUFBVSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ3BDLEVBQUUsSUFBSSxHQUFHLEdBQUcsSUFBSUgsVUFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQyxNQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRTtBQUM3QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0csS0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNsQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNZLEtBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUMvQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLFVBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNwQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNSLFVBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNwQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVN5QixRQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDbEMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsTUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUU7QUFDN0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMzQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDM0IsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsT0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUU7QUFDOUIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM1QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzVCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDNUIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQyxLQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDL0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEMsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQyxLQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDL0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEMsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsT0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUU7QUFDOUIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM1QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzVCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDNUIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTNUIsT0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ2pDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDcEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNwQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTNkIsYUFBVyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRTtBQUM5QyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUMvQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUMvQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUMvQixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQyxVQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUMvQixFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEIsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixFQUFFLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzdCLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsaUJBQWUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ3RDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEIsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUMvQixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQyxlQUFhLENBQUMsQ0FBQyxFQUFFO0FBQ2pDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUMvQixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLFFBQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFO0FBQy9CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLFNBQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFO0FBQ2hDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLFdBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFO0FBQ2xDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDbEM7QUFDQSxFQUFFLElBQUksR0FBRyxHQUFHLENBQUMsRUFBRTtBQUNmO0FBQ0EsSUFBSSxHQUFHLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDN0IsR0FBRztBQUNIO0FBQ0EsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUN0QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ3RCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDdEIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsS0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDMUIsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pELENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQyxPQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDakMsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUM3QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDN0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQzdCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQyxNQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ25DLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO0FBQ2hDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO0FBQ2hDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO0FBQ2hDLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDNUMsRUFBRSxJQUFJLFlBQVksR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzNCLEVBQUUsSUFBSSxPQUFPLEdBQUcsWUFBWSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQy9DLEVBQUUsSUFBSSxPQUFPLEdBQUcsWUFBWSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDM0MsRUFBRSxJQUFJLE9BQU8sR0FBRyxZQUFZLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3ZDLEVBQUUsSUFBSSxPQUFPLEdBQUcsWUFBWSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDM0MsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQztBQUM3RSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDO0FBQzdFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUM7QUFDN0UsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxD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QUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDbEQsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsQ0FBQztBQUNmLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUN4RCxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDeEQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3pELEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsZUFBYSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ3pDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNkLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMxQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMxQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMxQyxFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsZUFBYSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ3pDO0FBQ0EsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2QsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNkLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmO0FBQ0E7QUFDQSxFQUFFLElBQUksR0FBRyxHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUM7QUFDM0IsTUFBTSxHQUFHLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQztBQUMzQixNQUFNLEdBQUcsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDNUI7QUFDQSxFQUFFLElBQUksSUFBSSxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUc7QUFDaEMsTUFBTSxJQUFJLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRztBQUNoQyxNQUFNLElBQUksR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLENBQUM7QUFDakM7QUFDQSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDbEIsRUFBRSxHQUFHLElBQUksRUFBRSxDQUFDO0FBQ1osRUFBRSxHQUFHLElBQUksRUFBRSxDQUFDO0FBQ1osRUFBRSxHQUFHLElBQUksRUFBRSxDQUFDO0FBQ1o7QUFDQSxFQUFFLElBQUksSUFBSSxDQUFDLENBQUM7QUFDWixFQUFFLElBQUksSUFBSSxDQUFDLENBQUM7QUFDWixFQUFFLElBQUksSUFBSSxDQUFDLENBQUM7QUFDWjtBQUNBLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDO0FBQzFCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDO0FBQzFCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDO0FBQzFCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUzFCLFNBQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUU7QUFDeEMsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFO0FBQ1osTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2I7QUFDQSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3JCLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDckIsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNyQjtBQUNBLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNkLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3JELEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3JEO0FBQ0EsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQyxTQUFPLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFO0FBQ3hDLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRTtBQUNaLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNiO0FBQ0EsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNyQixFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3JCLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDckI7QUFDQSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNyRCxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZCxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNyRDtBQUNBLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsU0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRTtBQUN4QyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUU7QUFDWixNQUFNLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDYjtBQUNBLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDckIsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNyQixFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3JCO0FBQ0EsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDckQsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDckQsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2Q7QUFDQSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU3lCLE9BQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQzVCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUNuRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ25ELE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxJQUFJO0FBQ3ZCLE1BQU0sTUFBTSxHQUFHLEdBQUcsSUFBSVIsS0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDdEMsRUFBRSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEQsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU1MsTUFBSSxDQUFDLEdBQUcsRUFBRTtBQUMxQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDZixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDZixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDZixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUzFDLEtBQUcsQ0FBQyxDQUFDLEVBQUU7QUFDdkIsRUFBRSxPQUFPLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUMxRCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNJLGFBQVcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ2xDLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN6RCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNwQixRQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUM3QixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJcUIsT0FBZ0IsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSUEsT0FBZ0IsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSUEsT0FBZ0IsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNyUSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNVLElBQUNJLEtBQUcsR0FBR04sVUFBUyxDQUFBO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDVSxJQUFDSyxLQUFHLEdBQUdiLFVBQVMsQ0FBQTtBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ1UsSUFBQ2dELEtBQUcsR0FBR3ZCLFFBQU8sQ0FBQTtBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sSUFBSXdCLE1BQUksR0FBR2pCLFVBQVEsQ0FBQztBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sSUFBSWtCLFNBQU8sR0FBR2pCLGlCQUFlLENBQUM7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNVLElBQUNrQixLQUFHLEdBQUczQixRQUFPLENBQUE7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLElBQUk0QixRQUFNLEdBQUdsQixlQUFhLENBQUM7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxJQUFJbUIsU0FBTyxHQUFHLFlBQVk7QUFDakMsRUFBRSxJQUFJLEdBQUcsR0FBRy9ELFFBQU0sRUFBRSxDQUFDO0FBQ3JCLEVBQUUsT0FBTyxVQUFVLENBQUMsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFO0FBQ3RELElBQUksSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2I7QUFDQSxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7QUFDakIsTUFBTSxNQUFNLEdBQUcsQ0FBQyxDQUFDO0FBQ2pCLEtBQUs7QUFDTDtBQUNBLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtBQUNqQixNQUFNLE1BQU0sR0FBRyxDQUFDLENBQUM7QUFDakIsS0FBSztBQUNMO0FBQ0EsSUFBSSxJQUFJLEtBQUssRUFBRTtBQUNmLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxHQUFHLE1BQU0sR0FBRyxNQUFNLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ3RELEtBQUssTUFBTTtBQUNYLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUM7QUFDbkIsS0FBSztBQUNMO0FBQ0EsSUFBSSxLQUFLLENBQUMsR0FBRyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksTUFBTSxFQUFFO0FBQ3pDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNwQixNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDeEIsTUFBTSxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztBQUN4QixNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDcEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN4QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLEtBQUs7QUFDTDtBQUNBLElBQUksT0FBTyxDQUFDLENBQUM7QUFDYixHQUFHLENBQUM7QUFDSixDQUFDLEVBQUUsQ0FBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDanhCSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0EsUUFBTSxHQUFHO0FBQ3pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsSUFBSUMsVUFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QztBQUNBLEVBQUUsSUFBSUEsVUFBbUIsSUFBSSxZQUFZLEVBQUU7QUFDM0MsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2YsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2YsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2YsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2YsR0FBRztBQUNIO0FBQ0EsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVN6RCxPQUFLLENBQUMsQ0FBQyxFQUFFO0FBQ3pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsSUFBSXlELFVBQW1CLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTRyxZQUFVLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ3ZDLEVBQUUsSUFBSSxHQUFHLEdBQUcsSUFBSUgsVUFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQyxNQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRTtBQUM3QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0csS0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDckMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTWSxLQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDL0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLFVBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNwQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU1IsVUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ3BDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTeUIsUUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ2xDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsTUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUU7QUFDN0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMzQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDM0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMzQixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQyxPQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRTtBQUM5QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzVCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDNUIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM1QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzVCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsS0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQy9CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsS0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQy9CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLE9BQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFO0FBQzlCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDNUIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM1QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzVCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDNUIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTNUIsT0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ2pDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDcEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNwQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDcEIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVM2QixhQUFXLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFO0FBQzlDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO0FBQy9CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO0FBQy9CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO0FBQy9CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO0FBQy9CLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLFVBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQy9CLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEIsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixFQUFFLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNoQyxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLGlCQUFlLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUN0QyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEIsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEIsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDdkMsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU1QsUUFBTSxDQUFDLENBQUMsRUFBRTtBQUMxQixFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLEVBQUUsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNVLGVBQWEsQ0FBQyxDQUFDLEVBQUU7QUFDakMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN2QyxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLFFBQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFO0FBQy9CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLFNBQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFO0FBQ2hDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsV0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUU7QUFDbEMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLElBQUksR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDMUM7QUFDQSxFQUFFLElBQUksR0FBRyxHQUFHLENBQUMsRUFBRTtBQUNmLElBQUksR0FBRyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzdCLEdBQUc7QUFDSDtBQUNBLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDbkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNuQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ25CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDbkIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsS0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDMUIsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0QsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MsT0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNwQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbkMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNuQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ25DLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbkMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNuQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDcEMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNqQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDcEMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDakMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BDLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQyxNQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ25DLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO0FBQ2hDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO0FBQ2hDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO0FBQ2hDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO0FBQ2hDLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLFFBQU0sQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFO0FBQ25DLEVBQUUsS0FBSyxHQUFHLEtBQUssSUFBSSxHQUFHLENBQUM7QUFDdkI7QUFDQTtBQUNBO0FBQ0EsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQztBQUNyQixFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQztBQUNiO0FBQ0EsRUFBRSxHQUFHO0FBQ0wsSUFBSSxFQUFFLEdBQUdDLE1BQWUsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDbkMsSUFBSSxFQUFFLEdBQUdBLE1BQWUsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDbkMsSUFBSSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQzNCLEdBQUcsUUFBUSxFQUFFLElBQUksQ0FBQyxFQUFFO0FBQ3BCO0FBQ0EsRUFBRSxHQUFHO0FBQ0wsSUFBSSxFQUFFLEdBQUdBLE1BQWUsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDbkMsSUFBSSxFQUFFLEdBQUdBLE1BQWUsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDbkMsSUFBSSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQzNCLEdBQUcsUUFBUSxFQUFFLElBQUksQ0FBQyxFQUFFO0FBQ3BCO0FBQ0EsRUFBRSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztBQUNuQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLEdBQUcsRUFBRSxDQUFDO0FBQ3RCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssR0FBRyxFQUFFLENBQUM7QUFDdEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDMUIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDMUIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQyxlQUFhLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDekMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2QsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNkLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3RELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDdEQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN2RCxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3ZELEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyxhQUFhLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDekMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2QsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNkLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCO0FBQ0EsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztBQUNwQyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ3BDLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDcEMsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ3JDO0FBQ0EsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQztBQUNwRCxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDO0FBQ3BELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUM7QUFDcEQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTSSxNQUFJLENBQUMsR0FBRyxFQUFFO0FBQzFCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNmLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNmLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNmLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNmLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTMUMsS0FBRyxDQUFDLENBQUMsRUFBRTtBQUN2QixFQUFFLE9BQU8sT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDeEUsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTSSxhQUFXLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNsQyxFQUFFLE9B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LEdBQUcsRUFBRTtBQUM5QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyxZQUFZLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUU7QUFDN0MsRUFBRSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNsQixFQUFFLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDeEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN6QixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLFlBQVksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxFQUFFO0FBQzFDLEVBQUUsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDbEMsRUFBRSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUM5QjtBQUNBLEVBQUUsSUFBSSxDQUFDLEdBQUdpQixPQUFnQixFQUFFO0FBQzVCLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDM0IsSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUMzQixJQUFJLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzNCLEdBQUcsTUFBTTtBQUNUO0FBQ0EsSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNwQixJQUFJLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDcEIsR0FBRztBQUNIO0FBQ0EsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUMvQixFQUFFLElBQUksVUFBVSxHQUFHNEIsS0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUM3QixFQUFFLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsVUFBVSxHQUFHLFVBQVUsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNwRCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU3RDLFVBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNwQyxFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ2pELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDakQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUNqRCxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ2pELEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QUcsQ0FBQztBQUN4QixNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3pCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUM3QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDN0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQzdCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUM3QixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRTtBQUNuQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2QsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDNUQsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRTtBQUM1QixFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2QsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNkLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLEVBQUUsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzNDLEVBQUUsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUMzQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDakIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNqQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM1QixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFO0FBQzNCLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNkLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2QsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsRUFBRSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDM0MsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDM0MsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNqQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDakIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3pELEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDL0IsRUFB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Q25DLEdBQUcsTUFBTTtBQUNUO0FBQ0EsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzNCLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNuQyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDeEIsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3hCLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7QUFDeEUsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEtBQUssQ0FBQztBQUN6QixJQUFJLEtBQUssR0FBRyxHQUFHLEdBQUcsS0FBSyxDQUFDO0FBQ3hCLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDO0FBQ25ELElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FB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QUUsR0FBRyxJQUFJeUQsVUFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLE9BQU8sRUFBRSxDQUFDO0FBQ1osQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNHLFlBQVUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFO0FBQzNELEVBQUUsSUFBSSxFQUFFLEdBQUcsSUFBSUgsVUFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDYixFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDYixFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDYixFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDYixFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDYixFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDYixFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDYixFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDYixFQUFFLE9BQU8sRUFBRSxDQUFDO0FBQ1osQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLDZCQUE2QixDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRTtBQUMxRSxFQUFFLElBQUksRUFBRSxHQUFHLElBQUlBLFVBQW1CLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2IsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2IsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2IsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2IsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUcsR0FBRztBQUNuQixNQUFNLEVBQUUsR0FBRyxFQUFFLEdBQUcsR0FBRztBQUNuQixNQUFNLEVBQUUsR0FBRyxFQUFFLEdBQUcsR0FBRyxDQUFDO0FBQ3BCLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ3RDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ3RDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ3RDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDdkMsRUFBRSxPQUFPLEVBQUUsQ0FBQztBQUNaLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVMsdUJBQXVCLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDbkQsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRztBQUNyQixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRztBQUNyQixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRztBQUNyQixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDdkMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDdkMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDdkMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUN4QyxFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVMsZUFBZSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUU7QUFDeEMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUN0QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ3RCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxH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QyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTRSxLQUFHLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUU7QUFDekQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2QsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLElBQUksT0FBTyxHQUFHb0YsTUFBUyxDQUFDO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRTtBQUNoQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxJQUFJLE9BQU8sR0FBR0EsTUFBUyxDQUFDO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVMsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUU7QUFDaEMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLGNBQWMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFO0FBQ3ZDLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ3ZELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDdkQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUN2RCxFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNoRSxXQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDckMsRUFBRSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHO0FBQ3RCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHO0FBQ3RCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHO0FBQ3RCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDZixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDZixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDZixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDZixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDbkQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDO0FBQ25ELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNuRCxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNwRCxFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVMsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFO0FBQ3JDLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEdBQUcsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRTtBQUNqRCxNQUFNLEdBQUcsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRTtBQUNqRCxNQUFNLEdBQUcsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRTtBQUNqRCxNQUFNLEdBQUcsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ2xELEVBQUVpRSxTQUFZLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztBQUM1QixFQUFFLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZCxFQUFFLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZCxFQUFFLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZCxFQUFFLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZCxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxDQUFDO0FBQ3JELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLENBQUM7QUFDckQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsQ0FBQztBQUNyRCxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxDQUFDO0FBQ3JELEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUU7QUFDckMsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sR0FBRyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFO0FBQ2pELE1BQU0sR0FBRyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFO0FBQ2pELE1BQU0sR0FBRyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFO0FBQ2pELE1BQU0sR0FBRyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDbEQsRUFBRUMsU0FBWSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDNUIsRUFBRSxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2QsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsQ0FBQztBQUNyRCxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxDQUFDO0FBQ3JELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLENBQUM7QUFDckQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsQ0FBQztBQUNyRCxFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVMsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFO0FBQ3JDLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEdBQUcsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRTtBQUNqRCxNQUFNLEdBQUcsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRTtBQUNqRCxNQUFNLEdBQUcsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRTtBQUNqRCxNQUFNLEdBQUcsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ2xELEVBQUVDLFNBQVksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQzVCLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNkLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNkLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNkLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNkLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLENBQUM7QUFDckQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsQ0FBQztBQUNyRCxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxDQUFDO0FBQ3JELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLENBQUM7QUFDckQsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLGtCQUFrQixDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQzlDLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ2pELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDakQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUNqRCxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ2pELEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNaLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNaLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNaLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNaLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDakQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUNqRCxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ2pELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDakQsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLG1CQUFtQixDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQy9DLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ2pELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDakQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUNqRCxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ2pELEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNaLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNaLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNaLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNaLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDakQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUNqRCxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ2pELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDakQsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVMsZ0JBQWdCLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFO0FBQ3BEO0FBQ0EsRUFBRSxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUd4RSxPQUFnQixFQUFFO0FBQ3hDLElBQUksT0FBT2xCLE1BQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDeEIsR0FBRztBQUNIO0FBQ0EsRUFBRSxJQUFJLFVBQVUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDekQsRUFBRSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNsQixFQUFFLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDeEIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLFVBQVUsQ0FBQztBQUNwQyxFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDO0FBQ3BDLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxVQUFVLENBQUM7QUFDcEMsRUFBRSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3pCLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLENBQUM7QUFDckQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsQ0FBQztBQUNyRCxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxDQUFDO0FBQ3JELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLENBQUM7QUFDckQsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUNqRCxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ2pELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDakQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUNqRCxFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU2UsS0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQy9CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNQLFVBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNwQyxFQUFFLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDO0FBQ3pELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDekQsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUN6RCxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDO0FBQ3pELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUN6RyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDekcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDO0FBQ3pHLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUN6RyxFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxJQUFJYSxLQUFHLEdBQUdiLFVBQVEsQ0FBQztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNFLE9BQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNqQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDcEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNwQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDcEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNwQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDcEIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxJQUFJb0MsS0FBRyxHQUFHNkMsS0FBUSxDQUFDO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTM0MsTUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNuQyxFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDakIsRUFBRSxJQUFJRixLQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDNUIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2hDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNoQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDaEMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2hDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNoQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDaEMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2hDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNoQyxFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFO0FBQy9CLEVBQUUsSUFBSSxLQUFLLEdBQUdKLGVBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUM7QUFDekIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO0FBQ3pCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUN6QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO0FBQ3hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUN6QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUM7QUFDekIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO0FBQ3pCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUM7QUFDeEIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFO0FBQ2xDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sSUFBSVYsUUFBTSxHQUFHNEQsUUFBVyxDQUFDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxJQUFJakMsS0FBRyxHQUFHM0IsUUFBTSxDQUFDO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxJQUFJVSxlQUFhLEdBQUdtRCxlQUFrQixDQUFDO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxJQUFJakMsUUFBTSxHQUFHbEIsZUFBYSxDQUFDO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNHLFdBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFO0FBQ2xDLEVBQUUsSUFBSSxTQUFTLEdBQUdILGVBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNuQztBQUNBLEVBQUUsSUFBSSxTQUFTLEdBQUcsQ0FBQyxFQUFFO0FBQ3JCLElBQUksU0FBUyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDckMsSUFBSSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDO0FBQzlCLElBQUksSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQztBQUM5QixJQUFJLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUM7QUFDOUIsSUFBSSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDO0FBQzlCLElBQUksSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLElBQUksSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLElBQUksSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLElBQUksSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLElBQUksSUFBSSxPQUFPLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUN4RCxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDaEIsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2hCLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNoQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDaEIsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLE9BQU8sSUFBSSxTQUFTLENBQUM7QUFDN0MsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLE9BQU8sSUFBSSxTQUFTLENBQUM7QUFDN0MsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLE9BQU8sSUFBSSxTQUFTLENBQUM7QUFDN0MsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLE9BQU8sSUFBSSxTQUFTLENBQUM7QUFDN0MsR0FBRztBQUNIO0FBQ0EsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVM3QixLQUFHLENBQUMsQ0FBQyxFQUFFO0FBQ3ZCLEVBQUUsT0FBTyxRQUFRLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2pJLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0ksYUFBVyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDbEMsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM5SSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNwQixRQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUM3QixFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSXFCLE9BQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUlBLE9BQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUlBLE9BQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUlBLE9BQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUlBLE9BQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUlBLE9BQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUlBLE9B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QyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNwQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNwQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNsQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRTtBQUM3QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDM0IsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRTtBQUM5QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzVCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDNUIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUMvQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQyxFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQy9CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVMsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUU7QUFDOUIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM1QixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzVCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDakMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNwQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUU7QUFDOUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUM7QUFDL0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUM7QUFDL0IsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUMvQixFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3JCLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEIsRUFBRSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzFCLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyxlQUFlLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUN0QyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3JCLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEIsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN2QixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLE1BQU0sQ0FBQyxDQUFDLEVBQUU7QUFDMUIsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2QsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsRUFBRSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzFCLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVMsYUFBYSxDQUFDLENBQUMsRUFBRTtBQUNqQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3ZCLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRTtBQUMvQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFO0FBQ2hDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFO0FBQ2xDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNkLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLEVBQUUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzFCO0FBQ0EsRUFBRSxJQUFJLEdBQUcsR0FBRyxDQUFDLEVBQUU7QUFDZjtBQUNBLElBQUksR0FBRyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzdCLEdBQUc7QUFDSDtBQUNBLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDdEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUN0QixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTK0MsS0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDMUIsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNuQyxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNqQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNwQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3RCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDbkMsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO0FBQ2hDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO0FBQ2hDLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVMsTUFBTSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUU7QUFDbkMsRUFBRSxLQUFLLEdBQUcsS0FBSyxJQUFJLEdBQUcsQ0FBQztBQUN2QixFQUFFLElBQUksQ0FBQyxHQUFHSSxNQUFlLEVBQUUsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQztBQUM1QyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUMvQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUMvQixFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVMsYUFBYSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ3pDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNkLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUMvQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDL0IsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLGNBQWMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUMxQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEMsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVMsYUFBYSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ3pDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNkLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNmLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FB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RSxXQUFXLEVBQUUsR0FBRyxFQUFFO0FBQ3hDO0FBQ0EsSUFBSSxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQztBQUNuQjtBQUNBLElBQUksSUFBSSxRQUFRLEdBQUcsV0FBVyxJQUFJLFdBQVcsQ0FBQyxNQUFNO0FBQ3BELFFBQVEsUUFBUSxHQUFHLFFBQVEsR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNO0FBQ2hFLFFBQVEsU0FBUyxHQUFHLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDO0FBQzVELFFBQVEsU0FBUyxHQUFHLEVBQUUsQ0FBQztBQUN2QjtBQUNBLElBQUksSUFBSSxDQUFDLFNBQVMsSUFBSSxTQUFTLENBQUMsSUFBSSxLQUFLLFNBQVMsQ0FBQyxJQUFJLEVBQUUsT0FBTyxTQUFTLENBQUM7QUFDMUU7QUFDQSxJQUFJLElBQUksSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDO0FBQzlDO0FBQ0EsSUFBSSxJQUFJLFFBQVEsRUFBRSxTQUFTLEdBQUcsY0FBYyxDQUFDLElBQUksRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ2hGO0FBQ0E7QUFDQSxJQUFJLElBQUksSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLEdBQUcsR0FBRyxFQUFFO0FBQ2hDLFFBQVEsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDOUIsUUFBUSxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM5QjtBQUNBLFFBQVEsS0FBSyxJQUFJLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxHQUFHLFFBQVEsRUFBRSxDQUFDLElBQUksR0FBRyxFQUFFO0FBQ2xELFlBQVksQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMs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QUFDcEIsUUFBUSxDQUFDLEdBQUcsR0FBRztBQUNmLFFBQVEsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUM7QUFDckI7QUFDQSxJQUFJLElBQUksSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sS0FBSyxDQUFDO0FBQ3pDO0FBQ0EsSUFBSSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ25FO0FBQ0E7QUFDQSxJQUFJLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUNoRSxRQUFRLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDaEUsUUFBUSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ2hFLFFBQVEsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0FBQ2pFO0FBQ0E7QUFDQSxJQUFJLElBQUksSUFBSSxHQUFHLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDO0FBQ2xELFFBQVEsSUFBSSxHQUFHLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDbkQ7QUFDQSxJQUFJLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxLQUFLO0FBQ3JCLFFBQVEsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUM7QUFDdEI7QUFDQTtBQUNBLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxFQUFFO0FBQ2pELFFBQVEsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO0FBQ2xGLFlBQVksZUFBZSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sS0FBSyxDQUFDO0FBQzVHLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUM7QUFDcEI7QUFDQSxRQUFRLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztBQUNsRixZQUFZLGVBQWUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEtBQUssQ0FBQztBQUM1RyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDO0FBQ3BCLEtBQUs7QUFDTDtBQUNBO0FBQ0EsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksRUFBRTtBQUM3QixRQUFRLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztBQUNsRixZQUFZLGVBQWUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEtBQUssQ0FBQztBQUM1RyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDO0FBQ3BCLEtBQUs7QUFDTDtBQUNBO0FBQ0EsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksRUFBRTtBQUM3QixRQUFRLElBQUksQ0FBQyxD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LE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFO0FBQzNDO0FBQ0EsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxJQUFJLE9BQU8sR0FBRyxDQUFDLENBQUM7QUFDakMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxJQUFJLE9BQU8sR0FBRyxDQUFDLENBQUM7QUFDakM7QUFDQSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksVUFBVSxDQUFDO0FBQ3BDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxVQUFVLENBQUM7QUFDcEMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLFVBQVUsQ0FBQztBQUNwQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksVUFBVSxDQUFDO0FBQ3BDO0FBQ0EsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLFVBQVUsQ0FBQztBQUNwQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksVUFBVSxDQUFDO0FBQ3BDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxVQUFVLENBQUM7QUFDcEMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLFVBQVUsQ0FBQztBQUNwQztBQUNBLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLENBQUM7QUFDRDtBQUNBO0FBQ0EsU0FBUyxXQUFXLENBQUMsS0FBSyxFQUFFO0FBQzVCLElBQUksSUFBSSxD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QUFFLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztBQUMxQyxDQUFDO0FBQ0Q7QUFDQTtBQUNBLFNBQVMsVUFBVSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRTtBQUNwQyxJQUFJLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ3BDLElBQUksSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDcEMsSUFBSSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNwQyxJQUFJLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ3BDO0FBQ0EsSUFBSSxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxPQUFPLElBQUksQ0FBQztBQUM1QztBQUNBLElBQUksSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLFNBQVMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLE9BQU8sSUFBSSxDQUFDO0FBQ3ZELElBQUksSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLFNBQVMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLE9BQU8sSUFBSSxDQUFDO0FBQ3ZELElBQUksSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLFNBQVMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLE9BQU8sSUFBSSxDQUFDO0FBQ3ZELElBQUksSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLFNBQVMsQ0FBQyxF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Q0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ3ZDLFFBQVEsSUFBSSxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDdkMsUUFBUSxhQUFhLElBQUksSUFBSSxDQUFDLEdBQUc7QUFDakMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzdELFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0QsS0FBSztBQUNMO0FBQ0EsSUFBSSxPQUFPLFdBQVcsS0FBSyxDQUFDLElBQUksYUFBYSxLQUFLLENBQUMsR0FBRyxDQUFDO0FBQ3ZELFFBQVEsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLGFBQWEsR0FBRyxXQUFXLElBQUksV0FBVyxDQUFDLENBQUM7QUFDOUQsQ0FBQyxDQUFDO0FBQ0Y7QUFDQSxTQUFTQSxZQUFVLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFO0FBQzNDLElBQUksSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQ2hCLElBQUksS0FBSyxJQUFJLENBQUMsR0FBRyxLQUFLLEVBQUUsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDLElBQUksR0FBRyxFQUFFO0FBQzFELFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxHQUFH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Q0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ25DLFlBQVksTUFBTSxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUM1QyxZQUFZLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RELFlBQVksSUFBSSxDQUFDLHFCQUFxQixDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbkQsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBLElBQUksUUFBUSxVQUFVO0FBQ3RCLFFBQVEsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzFFLFFBQVEsT0FBTyxLQUFLLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sRUFBRSxHQUFHLElBQUlQLE9BQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDNUUsS0FBSztBQUNMO0FBQ0EsSUFBSSxJQUFJLFVBQVU7QUFDbEIsUUFBUSxPQUFPLElBQUlBLE9BQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNFLEtBQUs7QUFDTDtBQUNBLElBQUksZUFBZSxXQUFXO0FBQzlCLFFBQVEsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssR0FBRyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFL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QUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUM7QUFDMUMsWUFBWSxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUM7QUFDMUMsWUFBWSxNQUFNLFlBQVksR0FBRyxzQkFBc0IsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDcEg7QUFDQSxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDckIsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3JCLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUM7QUFDckMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3JCLFlBQVlDLGVBQWtCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUN4QyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUMzQyxZQUFZLE1BQU0sSUFBSSxHQUFHLElBQUksT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDNUU7QUFDQSxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDckIsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3JCLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxH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RSxHQUFHO0FBQ1osSUFBSSxHQUFHLEVBQUUsR0FBRztBQUNaLElBQUksR0FBRyxFQUFFLEdBQUc7QUFDWixJQUFJLEdBQUcsRUFBRSxHQUFHO0FBQ1osSUFBSSxHQUFHLEVBQUUsR0FBRztBQUNaLElBQUksR0FBRyxFQUFFLEdBQUc7QUFDWixJQUFJLEdBQUcsRUFBRSxHQUFHO0FBQ1osSUFBSSxHQUFHLEVBQUUsR0FBRztBQUNaLElBQUksR0FBRyxFQUFFLEdBQUc7QUFDWixJQUFJLEdBQUcsRUFBRSxHQUFHO0FBQ1osSUFBSSxHQUFHLEVBQUUsR0FBRztBQUNaLElBQUksR0FBRyxFQUFFLEdBQUc7QUFDWixJQUFJLEdBQUcsRUFBRSxHQUFHO0FBQ1osSUFBSSxHQUFHLEVBQUUsR0FBRztBQUNaLElBQUksR0FBRyxFQUFFLEdBQUc7QUFDWixJQUFJLEdBQUcsRUFBRSxHQUFHO0FBQ1osSUFBSSxHQUFHLEVBQUUsR0FBRztBQUNaLElBQUksR0FBRyxFQUFFLEdBQUc7QUFDWixJQUFJLEdBQUcsRUFBRSxHQUFHO0FBQ1osSUFBSSxHQUFHLEVBQUUsR0FBRztBQUNaLElBQUksR0FBRyxFQUFFLEdBQUc7QUFDWixJQUFJLEdBQUcsRUFBRSxHQUFHO0FBQ1osSUFBSSxHQUFHLEVBQUUsR0FBRztBQUNaLElBQUksR0FBRyxFQUFFLEdBQUc7QUFDWixJQUFJLEdBQUcsRUFBRSxHQUFHO0FBQ1osSUFBSSxHQUFHLEVBQUUsR0FBRztBQUNaLElBQUksR0FBRyxFQUFFLEdBQUc7QUFDWixJQUFJLEdBQUcsRUFBRSxHQUFHO0FBQ1osSUFBSSxHQUFHLEVBQUUsR0FBRztBQUNaLElBQUksR0FBRyxFQUFFLEdBQUc7QUFDWixJQUFJLEdBQUcsRUFBRSxHQUFHO0FBQ1osSUFBSSxHQUFHLEVBQUUsR0FBRztBQUNaLElBQUksR0FBRyxFQUFFLEdBQUc7QUFDWixJQUFJLEdBQUcsRUFBRSxHQUFHO0FBQ1osSUFBSSxHQUFHLEVBQUUsR0FBRztBQUNaLElBQUksR0FBRyxFQUFFLEdBQUc7QUFDWixJQUFJLEdBQUcsRUFBRSxHQUFHO0FBQ1osSUFBSSxHQUFHLEVBQUUsR0FBRztBQUNaLElBQUksR0FBRyxFQUFFLEdBQUc7QUFDWixJQUFJLEdBQUcsRUFBRSxHQUFHO0FBQ1osSUFBSSxHQUFHLEVBQUUsR0FBRztBQUNaLElBQUksR0FBRyxFQUFFLEdBQUc7QUFDWixJQUFJLEdBQUcsRUFBRSxHQUFHO0FBQ1osSUFBSSxHQUFHLEVBQUUsR0FBRztBQUNaLElBQUksR0FBRyxFQUFFLEdBQUc7QUFDWixJQUFJLEdBQUcsRUFBRSxHQUFHO0FBQ1osSUFBSSxHQUFHLEVBQUUsR0FBRztBQUNaLElBQUksR0FBRyxFQUFFLEdBQUc7QUFDWixJQUFJLEdBQUcsRUFBRSxHQUFHO0FBQ1osSUFBSSxHQUFHLEVBQUUsR0FBRztBQUNaLElBQUksR0FBRyxFQUFFLEdBQUc7QUFDWixJQUFJLEdBQUcsRUFBRSxHQUFHO0FBQ1osSUFBSSxHQUFHLEVBQUUsR0FBRztBQUNaLElBQUksR0FBRyxFQUFFLEdBQUc7QUFDWixJQUFJLEdBQUcsRUFBRSxHQUFHO0FBQ1osSUFBSSxHQUFHLEVBQUUsR0FBRztBQUNaLElBQUksR0FBRyxFQUFFLEdBQUc7QUFDWixJQUFJLEdBQUcsRUFBRSxHQUFHO0FBQ1osSUFBSSxHQUFHLEVBQUUsR0FBRztBQUNaLElBQUksR0FBRyxFQUFFLEdBQUc7QUFDWixDQUFDLENBQUM7QUFDRjtBQUNlLFNBQVMsc0JBQXNCLENBQUMsS0FBSyxVQUFVLG1CQUFtQixtQkFBbUI7QUFDcEcsSUFBSSxJQUFJLE1BQU0sR0FBRyxFQUFFLENBQUM7QUFDcEI7QUFDQSxJQUFJLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO0FBQzNDLFFBQVEsTUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDO0FBQzdELFFBQVEsTUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FB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QUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFBO0FBQzdCLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUE7QUFDakIsR0FBRztBQUNILEVBQUUsT0FBTyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUM7QUFDakQsQ0FBQyxDQUFBO0FBQ0Q7QUFDQSxJQUFBLEtBQUEsR0FBQUEsU0FBQSxDQUFBLEtBQWEsR0FBRyxVQUFVLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFO0FBQ3JFLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQTtBQUNiLEVBQUUsSUFBSSxJQUFJLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLElBQUksR0FBRyxDQUFDLENBQUE7QUFDcEMsRUFBRSxJQUFJLElBQUksR0FBRyxDQUFDLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxDQUFBO0FBQzVCLEVBQUUsSUFBSSxLQUFLLEdBQUcsSUFBSSxJQUFJLENBQUMsQ0FBQTtBQUN2QixFQUFFLElBQUksRUFBRSxJQUFJLElBQUksS0FBSyxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO0FBQ2xFLEVBQUUsSUFBSSxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUE7QUFDakMsRUFBRSxJQUFJLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO0FBQ3ZCLEVBQUUsSUFBSSxDQUFDLEdBQUcsS0FBSyxHQUFHLENBQUMsS0FBSyxLQUFLLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQTtBQUM3RDtBQUNBLEVBQUUsS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUE7QUFDekI7QUFDQSxFQUFFLElBQUksS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssS0FBSyxRQUFRLEVBQUU7QUFDMUMsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUE7QUFDNUIsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFBO0FBQ1osR0FBRyxNQUFNO0FBQ1QsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtBQUM5QyxJQUFJLElBQUksS0FBSyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFO0FBQzNDLE1BQU0sQ0FBQyxFQUFFLENBQUE7QUFDVCxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUE7QUFDWixLQUFLO0FBQ0wsSUFBSSxJQUFJLENBQUMsR0FBRyxLQUFLLElBQUksQ0FBQyxFQUFFO0FBQ3hCLE1BQU0sS0FBSyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUE7QUFDckIsS0FBSyxNQUFNO0FBQ1gsTUFBTSxLQUFLLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQTtBQUMxQyxLQUFLO0FBQ0wsSUFBSSxJQUFJLEtBQUssR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFO0FBQ3hCLE1BQU0sQ0FBQyxFQUFFLENBQUE7QUFDVCxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUE7QUFDWixLQUFLO0FBQ0w7QUFDQSxJQUFJLElBQUksQ0FBQyxHQUFHLEtBQUssSUFBSSxJQUFJLEVBQUU7QUFDM0IsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFBO0FBQ1gsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFBO0FBQ2QsS0FBSyxNQUFNLElBQUksQ0FBQyxHQUFHLEtBQUssSUFBSSxDQUFDLEVBQUU7QUFDL0IsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFBO0FBQy9DLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUE7QUFDbkIsS0FBSyxNQUFNO0FBQ1gsTUFBTSxDQUFDLEdBQUcsS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEtBQUssR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQTtBQUM1RCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUE7QUFDWCxLQUFLO0FBQ0wsR0FBRztBQUNIO0FBQ0EsRUFBRSxPQUFPLElBQUksSUFBSSxDQUFDLEVBQUUsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEdBQUcsRUFBRSxJQUFJLElBQUksQ0FBQyxFQUFFLEVBQUU7QUFDbEY7QUFDQSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxDQUFBO0FBQ3JCLEVBQUUsSUFBSSxJQUFJLElBQUksQ0FBQTtBQUNkLEVBQUUsT0FBTyxJQUFJLEdBQUcsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxHQUFHLEVBQUUsSUFBSSxJQUFJ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LFFBQVEsSUFBSSxHQUFHLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNoRSxRQUFRLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO0FBQ3RCLFFBQVEsT0FBTyxHQUFHLENBQUM7QUFDbkIsS0FBSztBQUNMO0FBQ0EsSUFBSSxVQUFVLEVBQUUsV0FBVztBQUMzQixRQUFRLElBQUksR0FBRyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDaEUsUUFBUSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQztBQUN0QixRQUFRLE9BQU8sR0FBRyxDQUFDO0FBQ25CLEtBQUs7QUFDTDtBQUNBLElBQUksVUFBVSxFQUFFLFNBQVMsUUFBUSxFQUFFO0FBQ25DLFFBQVEsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUc7QUFDMUIsWUFBWSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0FBQ25CO0FBQ0EsUUFBUSxDQUFDLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsR0FBRyxJQUFJLENBQUMsUUFBUSxJQUFJLENBQUMsR0FBRyxJQUFJLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDL0UsUUFBUSxDQUFDLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksS0FBSyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxJQUFJLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDL0UsUUFBUSxDQUFDLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENB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LEVBQUUsT0FBTztBQUN0RixJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQztBQUN0QyxDQUFDO0FBQ0Q7QUFDQSxTQUFTLHNCQUFzQixDQUFDLFFBQVEsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFO0FBQ3BELElBQUksSUFBSSxRQUFRO0FBQ2hCLFFBQVEsR0FBRyxJQUFJLE1BQU0sR0FBRyxDQUFDO0FBQ3pCLFFBQVEsR0FBRyxJQUFJLFFBQVEsR0FBRyxDQUFDO0FBQzNCLFFBQVEsR0FBRyxJQUFJLFNBQVMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMxRTtBQUNBO0FBQ0EsSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQzFCLElBQUksS0FBSyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksUUFBUSxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDckYsQ0FBQztBQUNEO0FBQ0EsU0FBUyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLEVBQUUsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJO0FBQzFHLFNBQVMsa0JBQWtCLENBQUMsR0FBRyxFQUFFLEdBQUcsR0FBRyxFQUFFLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRztBQUMxRyxTQUFTLGdCQUFnQixDQUFDLEdBQUcsRUFBRSxHQUFHLEtBQUssRUFBRSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUs7QUFDMUcsU0FBUyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLEVBQUUsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJO0FBQzFHLFNBQVMsa0JBQWtCLENBQUMsR0FBRyxFQUFFLEdBQUcsR0FBRyxFQUFFLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRztBQUMxRyxTQUFTLGtCQUFrQixDQUFDLEdBQUcsRUFBRSxHQUFHLEdBQUcsRUFBRSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUc7QUFDMUcsU0FBUyxtQkFBbUIsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FB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UUFBUSxRQUFRLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzdDLEtBQUs7QUFDTDtBQUNBO0FBQ0EsSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNwQztBQUNBO0FBQ0E7QUFDQSxJQUFJLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQzdFO0FBQ0E7QUFDQSxJQUFJLE1BQU0sTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQztBQUM5RDtBQUNBLElBQUksSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO0FBQ2xCLElBQUksSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO0FBQ25CO0FBQ0EsSUFBSSxLQUFLLE1BQU0sR0FBRyxJQUFJLEtBQUssRUFBRTtBQUM3QjtBQUNBLFFBQVEsS0FBSyxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO0FBQ3JELFlBQVksTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3BDO0FBQ0E7QUFDQSxZQUFZLElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsRUFBRSxTQUFTO0FBQzdEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Es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QyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDeEUsWUFBWSxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0FBQzlFLFNBQVM7QUFDVDtBQUNBLFFBQVEsT0FBTyxLQUFLLENBQUM7QUFDckIsS0FBSztBQUNMLENBQUM7QUFDRDtBQUNBO0FBQ0EsU0FBUyxHQUFHLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDN0QsSUFBSSxLQUFLLElBQUksQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLEVBQUUsR0FBRyxRQUFRLEdBQUcsQ0FBQyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNwRyxJQUFJLEtBQUssSUFBSSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxHQUFHLFFBQVEsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzdGLENBQUM7QUFDRDtBQUNBO0FBQ0EsU0FBUyxLQUFLLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ3RELElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDO0FBQ2hCLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNmLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUN4QjtBQUNBLElBQUksS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7QUFDbkQsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUM7QUFDekMsUUFBUSxNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3pCLFFBQVEsR0FBRztBQUNYLFlBQVksTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNCLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3pELFNBQVMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFO0FBQ3hDO0FBQ0EsUUFBUSxDQUFDLEVBQUUsQ0FBQztBQUNaLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNqQixRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDakIsUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUN2QixLQUFLO0FBQ0w7QUFDQSxJQUFJLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUM1QyxRQUFRLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7QUFDakMsUUFBUSxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsUUFBUSxNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3pCLFFBQVEsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDbkQsS0FBSztBQUNMLENBQUE7O0FDN0lBO0FBQ0E7QUFPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sTUFBTSxTQUFTLEdBQUcsQ0FBQyxDQUFDO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDWSxNQUFDLGNBQWMsR0FBRztBQUM5QixJQUFJLElBQUksRUFBRSxDQUFDO0FBQ1gsSUFBSSxVQUFVLEVBQUUsQ0FBQztBQUNqQixJQUFJLEdBQUcsRUFBRSxDQUFDO0FBQ1YsQ0FBRSxDQUFBO0FBQ0Y7QUFDQSxNQUFNLFlBQVksQ0FBQztBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksV0FBVyxDQUFDLGNBQWMsa0JBQWtCLGNBQWMsVUFBVSxlQUFlLFdBQVc7QUFDbEcsUUFBUSxJQUFJLENBQUMsY0FBYyxHQUFHLGNBQWMsQ0FBQztBQUM3QyxRQUFRLElBQUksQ0FBQyxjQUFjLEdBQUcsY0FBYyxDQUFDO0FBQzdDLFFBQVEsSUFBSSxDQUFDLGVBQWUsR0FBRyxlQUFlLENBQUM7QUFDL0MsUUFBUSxJQUFJLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztBQUMxQixRQUFRLElBQUksQ0FBQyxXQUFXLEdBQUc7QUFDM0I7QUFDQSxZQUFZLEtBQUssRUFBRSxFQUFFO0FBQ3JCLFlBQVksS0FBSyxFQUFFLEVBQUU7QUFDckIsWUFBWSxLQUFLLEVBQUUsRUFBRTtBQUNyQixZQUFZLEtBQUssRUFBRSxFQUFFO0FBQ3JCLFNBQVMsQ0FBQztBQUNWLEtBQUs7QUFDTDtBQUNBLElBQUksTUFBTSxDQUFDLEdBQUcsV0FBVztBQUN6QixRQUFRLElBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDO0FBQ3ZCLEtBQUs7QUFDTDtBQUNBLElBQUksU0FBUyxDQUFDLE1BQU0sb0NBQW9DLFFBQVEsNEdBQTRHO0FBQzVLLFFBQVEsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDO0FBQ3ZCO0FBQ0EsUUFBUSxLQUFLLE1BQU0sS0FBSyxJQUFJLE1BQU0sRUFBRTtBQUNwQyxZQUFZLEtBQUssTUFBTSxFQUFFLElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFO0FBQzVDLGdCQUFnQixHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDdEMsYUFBYTtBQUNiLFNBQVM7QUFDVDtBQUNBLFFBQVEsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxFQUFFLFVBQVUsZ0VBQWdFO0FBQzlHLFlBQVksSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUM1QyxZQUFZLElBQUksQ0FBQyxLQUFLLEVBQUU7QUFDeEIsZ0JBQWdCLEtBQUssR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHO0FBQzlDLG9CQUFvQixNQUFNLEVBQUUsRUFBRTtBQUM5QixvQkFBb0IsUUFBUSxFQUFFLEVBQUU7QUFDaEMsb0JBQW9CLE1BQU0sRUFBRSxFQUFFO0FBQzlCLG9CQUFvQixRQUFRLEVBQUUsU0FBUztBQUN2QyxvQkFBb0IsU0FBUyxFQUFFLFNBQVM7QUFDeEMsaUJBQWlCLENBQUM7QUFDbEIsYUFBYTtBQUNiO0FBQ0EsWUFBWSxJQUFJLEtBQUssR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3pDLFlBQVksSUFBSSxLQUFLLEtBQUssU0FBUyxFQUFFO0FBQ3JDLGdCQUFnQixVQUFVLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ3JELGdCQUFnQixPQUFPO0FBQ3ZCLGFBQWE7QUFDYjtBQUNBLFlBQVksS0FBSyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNwRCxZQUFZLElBQUksS0FBSyxFQUFFO0FBQ3ZCLGdCQUFnQixLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUN6QyxnQkFBZ0IsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNyRCxnQkFBZ0IsT0FBTztBQUN2QixhQUFhO0FBQ2I7QUFDQSxZQUFZLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQy9DLFlBQVksSUFBSSxLQUFLLEdBQUcsR0FBRyxHQUFHLEtBQUssRUFBRTtBQUNyQyxnQkFBZ0IsVUFBVSxDQUFDLElBQUksS0FBSyxDQUFDLDhCQUE4QixDQUFDLENBQUMsQ0FBQztBQUN0RSxnQkFBZ0IsT0FBTztBQUN2QixhQUFhO0FBQ2I7QUFDQSxZQUFZLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRTtBQUNyQyxnQkFBZ0IsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNyRCxnQkFBZ0IsT0FBTztBQUN2QixhQUFhO0FBQ2I7QUFDQSxZQUFZLElBQUksUUFBUSxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDakQsWUFBWSxJQUFJLENBQUMsUUFBUSxFQUFFO0FBQzNCLGdCQUFnQixRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDdEQsZ0JBQWdCLFlBQVksQ0FBQyxjQUFjLENBQUMsS0FBSyxFQUFFLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxRQUFRLElBQUksQ0FBQyxjQUFjO0FBQzlGLG9CQUFvQixDQUFDLEdBQUcsRUFBRSxRQUFRLHlGQUF5RjtBQUMzSCx3QkFBd0IsSUFBSSxRQUFRLEVBQUU7QUFDdEMsNEJBQTRCLEtBQUssQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQztBQUMvRCw0QkFBNEIsS0FBSyxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDO0FBQ2pFLDRCQUE0QixLQUFLLE1BQU0sRUFBRSxJQUFJLFFBQVEsQ0FBQyxNQUFNLEVBQUU7QUFDOUQsZ0NBQWdDLElBQUksQ0FBQyxJQUFJLENBQUMsMEJBQTBCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUMzRSxvQ0FBb0MsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUM3RSxpQ0FBaUM7QUFDakMsNkJBQTZCO0FBQzdCLDRCQUE0QixLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQztBQUN2RCx5QkFBeUI7QUFDekIsd0JBQXdCLEtBQUssTUFBTSxFQUFFLElBQUksUUFBUSxFQUFFO0FBQ25ELDRCQUE0QixFQUFFLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQzlDLHlCQUF5QjtBQUN6Qix3QkFBd0IsT0FBTyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3JELHFCQUFxQixDQUFDLENBQUM7QUFDdkIsYUFBYTtBQUNiO0FBQ0EsWUFBWSxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLE1BQU0seUZBQXlGO0FBQy9ILGdCQUFnQixJQUFJLEdBQUcsRUFBRTtBQUN6QixvQkFBb0IsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BDLGlCQUFpQixNQUFNLElBQUksTUFBTSxFQUFFO0FBQ25DLG9CQUFvQixVQUFVLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ3BGLGlCQUFpQjtBQUNqQixhQUFhLENBQUMsQ0FBQztBQUNmLFNBQVMsRUFBRSxDQUFDLEdBQUcsRUFBRSxNQUFNLDhEQUE4RDtBQUNyRixZQUFZLElBQUksR0FBRyxFQUFFO0FBQ3JCLGdCQUFnQixRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDOUIsYUFBYSxNQUFNLElBQUksTUFBTSxFQUFFO0FBQy9CLGdCQUFnQixNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUM7QUFDbEM7QUFDQSxnQkFBZ0IsS0FBSyxNQUFNLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsSUFBSSxNQUFNLEVBQUU7QUFDekQ7QUFDQSxvQkFBb0IsSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssU0FBUyxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDeEUsb0JBQW9CLElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sS0FBSyxTQUFTLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUM7QUFDdEYsb0JBQW9CLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxJQUFJO0FBQ3hELHdCQUF3QixFQUFFLEVBQUUsS0FBSyxDQUFDLEVBQUU7QUFDcEMsd0JBQXdCLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRTtBQUNwRCx3QkFBd0IsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPO0FBQzlDLHFCQUFxQixDQUFDO0FBQ3RCLG9CQUFvQixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsUUFBUSxDQUFDO0FBQzFFLG9CQUFvQixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQzVFLGlCQUFpQjtBQUNqQjtBQUNBLGdCQUFnQixRQUFRLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ3ZDLGFBQWE7QUFDYixTQUFTLENBQUMsQ0FBQztBQUNYLEtBQUs7QUFDTDtBQUNBLElBQUksMEJBQTBCLENBQUMsRUFBRSxtQkFBbUI7QUFDcEQsUUFBUSxJQUFJLElBQUksQ0FBQyxjQUFjLEtBQUssY0FBYyxDQUFDLElBQUksRUFBRTtBQUN6RCxZQUFZLE9BQU8sS0FBSyxDQUFDO0FBQ3pCLFNBQVMsTUFBTSxJQUFJLElBQUksQ0FBQyxjQUFjLEtBQUssY0FBYyxDQUFDLEdBQUcsRUFBRTtBQUMvRCxZQUFZLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUM7QUFDMUMsU0FBUyxNQUFNO0FBQ2Y7QUFDQSxZQUFZLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxlQUFlO0FBQ3pDLGFBQWEsQ0FBQ2tELGtCQUFNLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDbEQsZ0JBQWdCQSxrQkFBTSxDQUFDLGtCQUFrQixDQUFDLENBQUMsRUFBRSxDQUFDO0FBQzlDLGdCQUFnQkEsa0JBQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDdEMsZ0JBQWdCQSxrQkFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUN0QztBQUNBLGdCQUFnQkEsa0JBQU0sQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDM0Q7QUFDQSxTQUFTO0FBQ1QsS0FBSztBQUNMO0FBQ0EsSUFBSSxRQUFRLENBQUMsS0FBSyxTQUFTLEtBQUssVUFBVSxFQUFFLHVCQUF1QjtBQUNuRSxRQUFRLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7QUFDaEQsUUFBUSxJQUFJLENBQUMsVUFBVSxJQUFJLENBQUMsSUFBSSxDQUFDLDBCQUEwQixDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU87QUFDeEU7QUFDQSxRQUFRLElBQUksT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7QUFDcEMsUUFBUSxJQUFJLENBQUMsT0FBTyxFQUFFO0FBQ3RCLFlBQVksSUFBSSxVQUFVLEdBQUcsS0FBSyxDQUFDO0FBQ25DLFlBQVksSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFO0FBQ3JDLGdCQUFnQixVQUFVLEdBQUcsS0FBSyxDQUFDO0FBQ25DLGFBQWEsTUFBTSxJQUFJLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUU7QUFDOUMsZ0JBQWdCLFVBQVUsR0FBRyxLQUFLLENBQUM7QUFDbkMsYUFBYSxNQUFNLElBQUksUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRTtBQUM3QyxnQkFBZ0IsVUFBVSxHQUFHLEtBQUssQ0FBQztBQUNuQyxhQUFhO0FBQ2I7QUFDQSxZQUFZLE1BQU0sUUFBUSxHQUFHLEVBQUUsR0FBRyxTQUFTLENBQUM7QUFDNUMsWUFBWSxNQUFNLE1BQU0sR0FBRyxDQUFDLEdBQUcsU0FBUyxDQUFDO0FBQ3pDLFlBQVksTUFBTSxNQUFNLEdBQUcsQ0FBQyxHQUFHLFNBQVMsQ0FBQztBQUN6QyxZQUFZLE9BQU8sR0FBRyxLQUFLLENBQUMsT0FBTyxHQUFHLElBQUksWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLFVBQVUsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO0FBQ25ILFlBQVksT0FBTyxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7QUFDNUMsU0FBUztBQUNUO0FBQ0EsUUFBUSxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ3RELFlBQVksT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUM1RCxTQUFTO0FBQ1Q7QUFDQSxRQUFRLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDN0MsUUFBUSxNQUFNLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLFlBQVksQ0FBQyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDckg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsTUFBTSxrQkFBa0IsR0FBRyxFQUFFLENBQUM7QUFDdEM7QUFDQSxRQUFRLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHO0FBQ2pFLFlBQVksRUFBRTtBQUNkLFlBQVksTUFBTSxFQUFFLElBQUksVUFBVSxDQUFDLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxFQUFFLElBQUksQ0FBQztBQUN6RCxZQUFZLE9BQU8sRUFBRTtBQUNyQixnQkFBZ0IsS0FBSyxFQUFFLFVBQVUsR0FBRyxTQUFTO0FBQzdDLGdCQUFnQixNQUFNLEVBQUUsV0FBVyxHQUFHLFNBQVM7QUFDL0MsZ0JBQWdCLElBQUksRUFBRSxTQUFTLEdBQUcsU0FBUztBQUMzQyxnQkFBZ0IsR0FBRyxFQUFFLFFBQVEsR0FBRyxTQUFTLEdBQUcsa0JBQWtCO0FBQzlELGdCQUFnQixPQUFPLEVBQUUsWUFBWSxHQUFHLFNBQVM7QUFDakQsZ0JBQWdCLFVBQVUsRUFBRSxJQUFJO0FBQ2hDLGFBQWE7QUFDYixTQUFTLENBQUM7QUFDVixRQUFRLE9BQU8sS0FBSyxDQUFDO0FBQ3JCLEtBQUs7QUFDTCxDQUFDO0FBQ0Q7QUFDQSxZQUFZLENBQUMsY0FBYyxHQUFHLGNBQWMsQ0FBQztBQUM3QyxZQUFZLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQTs7QUN4UTlCO0FBQ0E7QUFlQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU0sTUFBTSxHQUFHLGFBQWEsQ0FBQztBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyxZQUFZO0FBQzVCLHNCQUFzQixVQUFVO0FBQ2hDLHNCQUFzQixVQUFVO0FBQ2hDLHNCQUFzQixTQUFTO0FBQy9CLHNCQUFzQixjQUFjLDhCQUE4QjtBQUNsRSxJQUFJLE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQztBQUNyQjtBQUNBLElBQUksTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQztBQUNuQyxJQUFJLE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxVQUFVLENBQUM7QUFDeEMsSUFBSSxNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFDO0FBQ3ZELElBQUksTUFBTSxXQUFXLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLE1BQU0sQ0FBQztBQUN4RDtBQUNBLElBQUksTUFBTSxTQUFTLEdBQUcsVUFBVSxDQUFDLEtBQUssR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDO0FBQ3pELElBQUksTUFBTSxVQUFVLEdBQUcsVUFBVSxDQUFDLE1BQU0sR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDO0FBQzFEO0FBQ0EsSUFBSSxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsUUFBUSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQztBQUN6RCxJQUFJLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxRQUFRLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDO0FBQzFEO0FBQ0EsSUFBSSxNQUFNLFlBQVksR0FBRyxDQUFDLEdBQUcsVUFBVSxLQUFLLHVCQUF1QixHQUFHLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM3RixJQUFJLE1BQU0sWUFBWSxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzFELElBQUksTUFBTSxhQUFhLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDM0QsSUFBSSxNQUFNLFVBQVUsR0FBRyxVQUFVLEdBQUcsWUFBWSxDQUFDO0FBQ2pELElBQUksTUFBTSxXQUFXLEdBQUcsV0FBVyxHQUFHLGFBQWEsQ0FBQztBQUNwRDtBQUNBLElBQUksSUFBSSxjQUFjLEdBQUcsQ0FBQyxDQUFDO0FBQzNCLElBQUksSUFBSSxtQkFBbUIsR0FBRyxZQUFZLENBQUM7QUFDM0MsSUFBSSxJQUFJLGNBQWMsR0FBRyxDQUFDLENBQUM7QUFDM0IsSUFBSSxJQUFJLG9CQUFvQixHQUFHLGFBQWEsQ0FBQztBQUM3QyxJQUFJLElBQUksWUFBWSxHQUFHLENBQUMsQ0FBQztBQUN6QixJQUFJLElBQUksaUJBQWlCLEdBQUcsVUFBVSxDQUFDO0FBQ3ZDLElBQUksSUFBSSxZQUFZLEdBQUcsQ0FBQyxDQUFDO0FBQ3pCLElBQUksSUFBSSxrQkFBa0IsR0FBRyxXQUFXLENBQUM7QUFDekM7QUFDQSxJQUFJLElBQUksS0FBSyxDQUFDLE9BQU8sSUFBSSxjQUFjLEVBQUU7QUFDekMsUUFBUSxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO0FBQ3RDLFFBQVEsY0FBYyxHQUFHLGNBQWMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pFLFFBQVEsY0FBYyxHQUFHLGNBQWMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pFLFFBQVEsbUJBQW1CLEdBQUcsY0FBYyxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0UsUUFBUSxvQkFBb0IsR0FBRyxjQUFjLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoRixRQUFRLFlBQVksR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsY0FBYyxDQUFDO0FBQ25ELFFBQVEsWUFBWSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxjQUFjLENBQUM7QUFDbkQsUUFBUSxpQkFBaUIsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLG1CQUFtQixDQUFDO0FBQzFFLFFBQVEsa0JBQWtCLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxvQkFBb0IsQ0FBQztBQUM1RSxLQUFLO0FBQ0w7QUFDQSxJQUFJLE1BQU0sT0FBTyxHQUFHLENBQUMsSUFBSSxRQUFRLEdBQUcsUUFBUSxLQUFLLFFBQVEsTUFBTSxXQUFXO0FBQzFFO0FBQ0EsUUFBUSxNQUFNLE1BQU0sR0FBRyxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sR0FBRyxjQUFjLEVBQUUsbUJBQW1CLEVBQUUsU0FBUyxFQUFFLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNuSCxRQUFRLE1BQU0sTUFBTSxHQUFHLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLFlBQVksRUFBRSxpQkFBaUIsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLFlBQVksQ0FBQyxDQUFDO0FBQzdHO0FBQ0EsUUFBUSxNQUFNLEtBQUssR0FBRyxXQUFXLENBQUMsR0FBRyxDQUFDLE9BQU8sR0FBRyxjQUFjLEVBQUUsb0JBQW9CLEVBQUUsVUFBVSxFQUFFLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNsSCxRQUFRLE1BQU0sS0FBSyxHQUFHLFdBQVcsQ0FBQyxHQUFHLENBQUMsS0FBSyxHQUFHLFlBQVksRUFBRSxrQkFBa0IsRUFBRSxHQUFHLENBQUMsT0FBTyxFQUFFLGFBQWEsQ0FBQyxDQUFDO0FBQzVHO0FBQ0EsUUFBUSxNQUFNLE9BQU8sR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxjQUFjLEVBQUUsbUJBQW1CLEVBQUUsU0FBUyxFQUFFLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNySCxRQUFRLE1BQU0sT0FBTyxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLFlBQVksRUFBRSxpQkFBaUIsRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLFlBQVksQ0FBQyxDQUFDO0FBQ2hIO0FBQ0EsUUFBUSxNQUFNLFFBQVEsR0FBRyxXQUFXLENBQUMsTUFBTSxDQUFDLE9BQU8sR0FBRyxjQUFjLEVBQUUsb0JBQW9CLEVBQUUsVUFBVSxFQUFFLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN4SCxRQUFRLE1BQU0sUUFBUSxHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUMsS0FBSyxHQUFHLFlBQVksRUFBRSxrQkFBa0IsRUFBRSxNQUFNLENBQUMsT0FBTyxFQUFFLGFBQWEsQ0FBQyxDQUFDO0FBQ3JIO0FBQ0EsUUFBUSxNQUFNLEVBQUUsR0FBRyxJQUFJbEQsT0FBSyxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQztBQUM1QyxRQUFRLE1BQU0sRUFBRSxHQUFHLElBQUlBLE9BQUssQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDN0MsUUFBUSxNQUFNLEVBQUUsR0FBRyxJQUFJQSxPQUFLLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQ2hELFFBQVEsTUFBTSxFQUFFLEdBQUcsSUFBSUEsT0FBSyxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQztBQUMvQyxRQUFRLE1BQU0sYUFBYSxHQUFHLElBQUlBLE9BQUssQ0FBQyxNQUFNLEdBQUcsVUFBVSxFQUFFLEtBQUssR0FBRyxVQUFVLENBQUMsQ0FBQztBQUNqRixRQUFRLE1BQU0sYUFBYSxHQUFHLElBQUlBLE9BQUssQ0FBQyxPQUFPLEdBQUcsVUFBVSxFQUFFLFFBQVEsR0FBRyxVQUFVLENBQUMsQ0FBQztBQUNyRjtBQUNBLFFBQVEsTUFBTSxLQUFLLEdBQUcsVUFBVSxHQUFHLElBQUksQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDO0FBQ2pEO0FBQ0EsUUFBUSxJQUFJLEtBQUssRUFBRTtBQUNuQixZQUFZLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDO0FBQ3ZDLGdCQUFnQixHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUM7QUFDckMsZ0JBQWdCLE1BQU0sR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDL0M7QUFDQSxZQUFZLEVBQUUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDaEMsWUFBWSxFQUFFLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ2hDLFlBQVksRUFBRSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUNoQyxZQUFZLEVBQUUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDaEMsU0FBUztBQUNUO0FBQ0EsUUFBUSxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7QUFDN0MsUUFBUSxNQUFNLEVBQUUsR0FBRyxLQUFLLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUM7QUFDL0MsUUFBUSxNQUFNLEVBQUUsR0FBRyxHQUFHLENBQUMsT0FBTyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUM7QUFDM0MsUUFBUSxNQUFNLEVBQUUsR0FBRyxNQUFNLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUM7QUFDakQ7QUFDQSxRQUFRLE1BQU0sT0FBTyxHQUFHO0FBQ3hCLFlBQVksQ0FBQyxFQUFFLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQyxHQUFHLE1BQU0sR0FBRyxFQUFFO0FBQy9DLFlBQVksQ0FBQyxFQUFFLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQyxHQUFHLE1BQU0sR0FBRyxFQUFFO0FBQy9DLFlBQVksQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFO0FBQ3RCLFlBQVksQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFO0FBQ3RCLFNBQVMsQ0FBQztBQUNWO0FBQ0EsUUFBUSxNQUFNLGFBQWEsR0FBRyxpQkFBaUIsR0FBRyxVQUFVLEdBQUcsU0FBUyxDQUFDO0FBQ3pFLFFBQVEsTUFBTSxhQUFhLEdBQUcsa0JBQWtCLEdBQUcsVUFBVSxHQUFHLFVBQVUsQ0FBQztBQUMzRTtBQUNBO0FBQ0EsUUFBUSxPQUFPLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsWUFBWSxFQUFFLENBQUMsRUFBRSxhQUFhLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQzFMLEtBQUssQ0FBQztBQUNOO0FBQ0EsSUFBSSxJQUFJLENBQUMsY0FBYyxLQUFLLENBQUMsS0FBSyxDQUFDLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsRUFBRTtBQUNqRSxRQUFRLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTztBQUMxQixZQUFZLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDbkMsWUFBWSxDQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ25DLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxVQUFVLEdBQUcsQ0FBQyxDQUFDO0FBQy9DLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxXQUFXLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ25ELEtBQUssTUFBTTtBQUNYLFFBQVEsTUFBTSxLQUFLLEdBQUcsa0JBQWtCLENBQUMsUUFBUSxFQUFFLFVBQVUsRUFBRSxZQUFZLENBQUMsQ0FBQztBQUM3RSxRQUFRLE1BQU0sS0FBSyxHQUFHLGtCQUFrQixDQUFDLFFBQVEsRUFBRSxXQUFXLEVBQUUsYUFBYSxDQUFDLENBQUM7QUFDL0U7QUFDQSxRQUFRLEtBQUssSUFBSSxFQUFFLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRTtBQUN0RCxZQUFZLE1BQU0sRUFBRSxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNqQyxZQUFZLE1BQU0sRUFBRSxHQUFHLEtBQUssQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDckMsWUFBWSxLQUFLLElBQUksRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUU7QUFDMUQsZ0JBQWdCLE1BQU0sRUFBRSxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNyQyxnQkFBZ0IsTUFBTSxFQUFFLEdBQUcsS0FBSyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUN6QyxnQkFBZ0IsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNwRCxhQUFhO0FBQ2IsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBLElBQUksT0FBTyxLQUFLLENBQUM7QUFDakIsQ0FBQztBQUNEO0FBQ0EsU0FBUyxjQUFjLENBQUMsTUFBTSwyQkFBMkIsR0FBRyxVQUFVLEdBQUcsVUFBVTtBQUNuRixJQUFJLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQztBQUNoQixJQUFJLEtBQUssTUFBTSxLQUFLLElBQUksTUFBTSxFQUFFO0FBQ2hDLFFBQVEsR0FBRyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvRixLQUFLO0FBQ0wsSUFBSSxPQUFPLEdBQUcsQ0FBQztBQUNmLENBQUM7QUFDRDtBQUNBLFNBQVMsa0JBQWtCLENBQUMsWUFBWSwyQkFBMkIsU0FBUyxVQUFVLFdBQVcsVUFBVTtBQUMzRyxJQUFJLE1BQU0sSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEQ7QUFDQSxJQUFJLEtBQUssTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsSUFBSSxZQUFZLEVBQUU7QUFDekMsUUFBUSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztBQUMzQyxRQUFRLElBQUksQ0FBQyxJQUFJLENBQUM7QUFDbEIsWUFBWSxLQUFLLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxPQUFPO0FBQ3BDLFlBQVksT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO0FBQ2pDLFNBQVMsQ0FBQyxDQUFDO0FBQ1gsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDO0FBQ2xCLFlBQVksS0FBSyxFQUFFLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTztBQUNwQyxZQUFZLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTyxJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDN0MsU0FBUyxDQUFDLENBQUM7QUFDWCxLQUFLO0FBQ0wsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDO0FBQ2QsUUFBUSxLQUFLLEVBQUUsU0FBUyxHQUFHLE1BQU07QUFDakMsUUFBUSxPQUFPLEVBQUUsV0FBVztBQUM1QixLQUFLLENBQUMsQ0FBQztBQUNQLElBQUksT0FBTyxJQUFJLENBQUM7QUFDaEIsQ0FBQztBQUNEO0FBQ0EsU0FBUyxXQUFXLENBQUMsYUFBYSxVQUFVLFdBQVcsVUFBVSxRQUFRLFVBQVUsVUFBVSxVQUFVO0FBQ3ZHLElBQUksT0FBTyxhQUFhLEdBQUcsV0FBVyxHQUFHLFFBQVEsR0FBRyxVQUFVLENBQUM7QUFDL0QsQ0FBQztBQUNEO0FBQ0EsU0FBUyxXQUFXLENBQUMsV0FBVyxVQUFVLFNBQVMsVUFBVSxhQUFhLFVBQVUsV0FBVyxVQUFVO0FBQ3pHLElBQUksT0FBTyxXQUFXLEdBQUcsU0FBUyxHQUFHLGFBQWEsR0FBRyxXQUFXLENBQUM7QUFDakUsQ0FBQztBQUNEO0FBQ0EsU0FBUyxlQUFlLENBQUMsVUFBVSxvQkFBb0I7QUFDdkQsSUFBSSxNQUFNLENBQUMsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvQyxJQUFJLE1BQU0sT0FBTyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDMUIsSUFBSSxJQUFJLE9BQU8sR0FBRyxDQUFDLEVBQUU7QUFDckIsUUFBUSxPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsS0FBSyxNQUFNLElBQUksT0FBTyxHQUFHLENBQUMsRUFBRTtBQUM1QixRQUFRLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUN2QixLQUFLLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFO0FBQ3hCLFFBQVEsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUN0QixLQUFLLE1BQU07QUFDWCxRQUFRLE9BQU8sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QixLQUFLO0FBQ0wsQ0FBQztBQUNEO0FBQ0EsU0FBUyxnQkFBZ0IsQ0FBQyxPQUFPLFdBQVcsVUFBVSxVQUFVLGNBQWMsVUFBVSxTQUFTLFVBQVU7QUFDM0csSUFBSSxNQUFNLGlCQUFpQixJQUFJLFVBQVUsR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQzNGLElBQUksSUFBSSxTQUFTLEtBQUssQ0FBQyxFQUFFO0FBQ3pCLFFBQVEsT0FBTyxjQUFjLEdBQUcsaUJBQWlCLEdBQUcsR0FBRyxDQUFDO0FBQ3hELEtBQUs7QUFDTCxJQUFJLE1BQU0sZUFBZSxJQUFJLFVBQVUsR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUM3RixJQUFJLE9BQU8sY0FBYyxHQUFHLENBQUMsaUJBQWlCLEdBQUcsZUFBZSxJQUFJLEdBQUcsQ0FBQztBQUN4RSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVMsYUFBYSxDQUFDLE1BQU07QUFDcEMsdUJBQXVCLE9BQU87QUFDOUIsdUJBQXVCLFVBQVU7QUFDakMsdUJBQXVCLEtBQUs7QUFDNUIsdUJBQXVCLFNBQVM7QUFDaEMsdUJBQXVCLE9BQU87QUFDOUIsdUJBQXVCLFFBQVE7QUFDL0IsdUJBQXVCLHNCQUFzQiw4QkFBOEI7QUFDM0UsSUFBSSxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUM7QUFDckIsSUFBSSxJQUFJLE9BQU8sQ0FBQyxlQUFlLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxPQUFPLEtBQUssQ0FBQztBQUMzRDtBQUNBLElBQUksTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQztBQUM3RixJQUFJLE1BQU0sWUFBWSxHQUFHLGVBQWUsQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUNyRDtBQUNBLElBQUksSUFBSSxhQUFhLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsR0FBRyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUMvRCxJQUFJLEtBQUssTUFBTSxJQUFJLElBQUksT0FBTyxDQUFDLGVBQWUsRUFBRTtBQUNoRCxRQUFRLGFBQWEsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDO0FBQ3pDLEtBQUs7QUFDTCxJQUFJLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDO0FBQ3RELElBQUksTUFBTSxVQUFVLEdBQUcsYUFBYSxHQUFHLFVBQVUsQ0FBQztBQUNsRCxJQUFJLElBQUksYUFBYSxHQUFHLE9BQU8sQ0FBQyxHQUFHLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3BELElBQUksS0FBSyxJQUFJLFNBQVMsR0FBRyxDQUFDLEVBQUUsU0FBUyxHQUFHLFVBQVUsRUFBRSxFQUFFLFNBQVMsRUFBRTtBQUNqRSxRQUFRLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDeEQsUUFBUSxhQUFhLEdBQUcsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxhQUFhLEVBQUUsU0FBUyxDQUFDLENBQUM7QUFDeEYsUUFBUSxLQUFLLE1BQU0sZUFBZSxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtBQUM3RCxZQUFZLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLFNBQVM7QUFDaEQsWUFBWSxNQUFNLFdBQVcsR0FBRyxlQUFlLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQztBQUMzRDtBQUNBO0FBQ0EsWUFBWSxNQUFNLFlBQVksR0FBRyxHQUFHLENBQUM7QUFDckMsWUFBWSxJQUFJLFVBQVUsR0FBRyxnQkFBZ0IsR0FBRyxZQUFZLENBQUM7QUFDN0QsWUFBWSxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUM7QUFDN0IsWUFBWSxJQUFJLFVBQVUsR0FBRyxHQUFHLENBQUM7QUFDakMsWUFBWSxJQUFJLFVBQVUsR0FBRyxHQUFHLENBQUM7QUFDakMsWUFBWSxJQUFJLGVBQWUsQ0FBQyxTQUFTLEVBQUU7QUFDM0MsZ0JBQWdCLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDbEUsZ0JBQWdCLElBQUksQ0FBQyxLQUFLLEVBQUUsU0FBUztBQUNyQyxnQkFBZ0IsSUFBSSxLQUFLLENBQUMsR0FBRyxFQUFFO0FBQy9CLG9CQUFvQixRQUFRLENBQUMscUVBQXFFLENBQUMsQ0FBQztBQUNwRyxvQkFBb0IsU0FBUztBQUM3QixpQkFBaUI7QUFDakIsZ0JBQWdCLEtBQUssR0FBRyxLQUFLLENBQUM7QUFDOUIsZ0JBQWdCLFVBQVUsR0FBRyxLQUFLLENBQUMsVUFBVSxDQUFDO0FBQzlDLGdCQUFnQixVQUFVLEdBQUcsYUFBYSxHQUFHLFVBQVUsQ0FBQztBQUN4RCxhQUFhO0FBQ2I7QUFDQSxZQUFZLE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxTQUFTLElBQUksc0JBQXNCLEtBQUssZUFBZSxDQUFDLFFBQVEsQ0FBQztBQUMxRyxZQUFZLE1BQU0sV0FBVyxHQUFHLGVBQWUsQ0FBQyxPQUFPLENBQUMsT0FBTyxHQUFHLGVBQWUsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDO0FBQzVGLFlBQVksTUFBTSxPQUFPLEdBQUcsZUFBZSxDQUFDLE9BQU8sQ0FBQztBQUNwRCxZQUFZLE1BQU0sSUFBSSxHQUFHLGVBQWUsQ0FBQyxJQUFJLENBQUM7QUFDOUMsWUFBWSxJQUFJLElBQUksS0FBSyxJQUFJLEVBQUUsU0FBUztBQUN4QztBQUNBO0FBQ0EsWUFBWSxJQUFJLHNCQUFzQixJQUFJLE9BQU8sQ0FBQyxjQUFjLEVBQUU7QUFDbEU7QUFDQTtBQUNBLGdCQUFnQixVQUFVLEdBQUcsZUFBZSxDQUFDLFNBQVMsR0FBRyxXQUFXLEdBQUcsZUFBZSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEdBQUcsZUFBZSxDQUFDLEtBQUssR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQ3ZJLGFBQWE7QUFDYjtBQUNBLFlBQVksTUFBTSxXQUFXLEdBQUcsU0FBUztBQUN6QyxnQkFBZ0IsQ0FBQyxlQUFlLENBQUMsQ0FBQyxHQUFHLFdBQVcsRUFBRSxlQUFlLENBQUMsQ0FBQyxDQUFDO0FBQ3BFLGdCQUFnQixDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUN2QjtBQUNBLFlBQVksSUFBSSxhQUFhLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDdkMsWUFBWSxJQUFJLHVCQUF1QixHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2pELFlBQVksSUFBSSxlQUFlLEdBQUcsS0FBSyxDQUFDO0FBQ3hDLFlBQVksSUFBSSxDQUFDLFNBQVMsRUFBRTtBQUM1QixnQkFBZ0IsSUFBSSxtQkFBbUIsRUFBRTtBQUN6QztBQUNBO0FBQ0Esb0JBQW9CLHVCQUF1QjtBQUMzQyx3QkFBd0IsQ0FBQyxlQUFlLENBQUMsQ0FBQyxHQUFHLFdBQVcsR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDLEVBQUUsZUFBZSxDQUFDLENBQUMsR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLENBQUM7QUFDOUgsb0JBQW9CLGVBQWUsR0FBRyxJQUFJLENBQUM7QUFDM0MsaUJBQWlCLE1BQU07QUFDdkIsb0JBQW9CLGFBQWEsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLEdBQUcsV0FBVyxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRSxlQUFlLENBQUMsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUMsR0FBRyxVQUFVLENBQUMsQ0FBQztBQUN2SSxpQkFBaUI7QUFDakIsYUFBYTtBQUNiO0FBQ0EsWUFBWSxNQUFNLFdBQVc7QUFDN0IsZ0JBQWdCLElBQUksQ0FBQyxDQUFDLEdBQUcsZUFBZSxDQUFDLEtBQUssSUFBSSxVQUFVLElBQUksZUFBZSxDQUFDLFVBQVUsR0FBRyxTQUFTLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM3RyxZQUFZLE9BQU8sWUFBWTtBQUMvQixnQkFBZ0IsSUFBSSxDQUFDLENBQUMsR0FBRyxlQUFlLENBQUMsS0FBSyxJQUFJLFVBQVUsSUFBSSxlQUFlLENBQUMsVUFBVSxHQUFHLFNBQVMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzdHO0FBQ0EsWUFBWSxJQUFJLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQztBQUMvQixZQUFZLElBQUksQ0FBQyxtQkFBbUIsRUFBRTtBQUN0QyxnQkFBZ0IsTUFBTSxFQUFFLEdBQUcsQ0FBQyxPQUFPLENBQUMsSUFBSSxHQUFHLFVBQVUsSUFBSSxlQUFlLENBQUMsS0FBSyxHQUFHLFdBQVcsR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEgsZ0JBQWdCLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxHQUFHLFVBQVUsSUFBSSxlQUFlLENBQUMsS0FBSyxHQUFHLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsRyxnQkFBZ0IsTUFBTSxFQUFFLEdBQUcsRUFBRSxHQUFHLFdBQVcsQ0FBQztBQUM1QyxnQkFBZ0IsTUFBTSxFQUFFLEdBQUcsRUFBRSxHQUFHLFlBQVksQ0FBQztBQUM3QztBQUNBLGdCQUFnQixFQUFFLEdBQUcsSUFBSUEsT0FBSyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUN2QyxnQkFBZ0IsRUFBRSxHQUFHLElBQUlBLE9BQUssQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDdkMsZ0JBQWdCLEVBQUUsR0FBRyxJQUFJQSxPQUFLLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ3ZDLGdCQUFnQixFQUFFLEdBQUcsSUFBSUEsT0FBSyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUN2QyxhQUFhLE1BQU07QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLE1BQU0sTUFBTSxJQUFJLGVBQWUsQ0FBQyxDQUFDLEdBQUcsYUFBYSxDQUFDLENBQUM7QUFDbkUsZ0JBQWdCLE1BQU0sTUFBTSxHQUFHLElBQUlBLE9BQUssQ0FBQyxDQUFDLFdBQVcsRUFBRSxXQUFXLEdBQUcsTUFBTSxDQUFDLENBQUM7QUFDN0UsZ0JBQWdCLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztBQUN0RCxnQkFBZ0IsTUFBTSx3QkFBd0IsR0FBRyxJQUFJQSxPQUFLLENBQUMsR0FBRyx1QkFBdUIsQ0FBQyxDQUFDO0FBQ3ZGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsRUFBRSxHQUFHLElBQUlBLE9BQUssQ0FBQyxDQUFDLFdBQVcsR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEYsZ0JBQWdCLEVBQUUsQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLENBQUM7QUFDMUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLFdBQVcsQ0FBQztBQUM5QztBQUNBO0FBQ0EsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxHQUFHLFVBQVUsSUFBSSxlQUFlLENBQUMsS0FBSyxDQUFDO0FBQzVFO0FBQ0E7QUFDQSxnQkFBZ0IsTUFBTSxlQUFlLEdBQUcsZUFBZSxDQUFDLFNBQVMsR0FBRyxPQUFPLENBQUMsT0FBTyxHQUFHLGVBQWUsQ0FBQyxLQUFLO0FBQzNHLG9CQUFvQixNQUFNLEdBQUcsZUFBZSxDQUFDLEtBQUssQ0FBQztBQUNuRDtBQUNBLGdCQUFnQixNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUN2RSxnQkFBZ0IsSUFBSSwwQkFBMEIsQ0FBQyxHQUFHLENBQUMsRUFBRTtBQUNyRDtBQUNBLG9CQUFvQixFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxJQUFJLGVBQWUsQ0FBQyxLQUFLLENBQUM7QUFDdEUsaUJBQWlCLE1BQU0sSUFBSSx5QkFBeUIsQ0FBQyxHQUFHLENBQUMsRUFBRTtBQUMzRCxvQkFBb0IsTUFBTSxPQUFPLEdBQUcsZUFBZSxHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUcsZUFBZSxDQUFDLEtBQUssQ0FBQztBQUM3RjtBQUNBLG9CQUFvQixFQUFFLENBQUMsQ0FBQyxJQUFJLE9BQU8sR0FBRyxDQUFDLENBQUMsVUFBVSxHQUFHLENBQUMsSUFBSSxlQUFlLENBQUMsS0FBSyxDQUFDO0FBQ2hGLGlCQUFpQixNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsU0FBUztBQUNyRCw0QkFBNEIsQ0FBQyxPQUFPLENBQUMsS0FBSyxHQUFHLFVBQVUsR0FBRyxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsSUFBSSxPQUFPLENBQUMsTUFBTSxHQUFHLFVBQVUsR0FBRyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFO0FBQ3hIO0FBQ0E7QUFDQSxvQkFBb0IsTUFBTSxtQkFBbUIsR0FBRyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsVUFBVSxHQUFHLENBQUMsSUFBSSxlQUFlLENBQUMsS0FBSyxDQUFDO0FBQzFHLG9CQUFvQixNQUFNLEtBQUssR0FBRyxlQUFlLEdBQUcsbUJBQW1CLENBQUM7QUFDeEUsb0JBQW9CLEVBQUUsQ0FBQyxDQUFDLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQztBQUN0QyxpQkFBaUIsTUFBTTtBQUN2QjtBQUNBLG9CQUFvQixNQUFNLEtBQUssR0FBRyxlQUFlLEdBQUcsWUFBWSxDQUFDO0FBQ2pFLG9CQUFvQixFQUFFLENBQUMsQ0FBQyxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7QUFDdEMsaUJBQWlCO0FBQ2pCO0FBQ0EsZ0JBQWdCLEVBQUUsR0FBRyxJQUFJQSxPQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxDQUFDO0FBQ3pELGdCQUFnQixFQUFFLEdBQUcsSUFBSUEsT0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsWUFBWSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMxRCxnQkFBZ0IsRUFBRSxHQUFHLElBQUlBLE9BQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLFlBQVksRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxDQUFDO0FBQ3hFLGFBQWE7QUFDYjtBQUNBLFlBQVksSUFBSSxVQUFVLEVBQUU7QUFDNUIsZ0JBQWdCLElBQUksTUFBTSxDQUFDO0FBQzNCLGdCQUFnQixJQUFJLENBQUMsU0FBUyxFQUFFO0FBQ2hDLG9CQUFvQixJQUFJLGVBQWUsRUFBRTtBQUN6Qyx3QkFBd0IsTUFBTSxHQUFHLElBQUlBLE9BQUssQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDN0UscUJBQXFCLE1BQU07QUFDM0Isd0JBQXdCLE1BQU0sR0FBRyxJQUFJQSxPQUFLLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3pFLHFCQUFxQjtBQUNyQixpQkFBaUIsTUFBTTtBQUN2QixvQkFBb0IsTUFBTSxHQUFHLElBQUlBLE9BQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDN0MsaUJBQWlCO0FBQ2pCLGdCQUFnQixFQUFFLENBQUMsYUFBYSxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQztBQUNyRCxnQkFBZ0IsRUFBRSxDQUFDLGFBQWEsQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDckQsZ0JBQWdCLEVBQUUsQ0FBQyxhQUFhLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ3JELGdCQUFnQixFQUFFLENBQUMsYUFBYSxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQztBQUNyRCxhQUFhO0FBQ2I7QUFDQSxZQUFZLE1BQU0sYUFBYSxHQUFHLElBQUlBLE9BQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDbEQsWUFBWSxNQUFNLGFBQWEsR0FBRyxJQUFJQSxPQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2xELFlBQVksTUFBTSxhQUFhLEdBQUcsQ0FBQyxDQUFDO0FBQ3BDLFlBQVksTUFBTSxhQUFhLEdBQUcsQ0FBQyxDQUFDO0FBQ3BDLFlBQVksS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxPQUFPLENBQUMsV0FBVyxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsZUFBZSxDQUFDLFlBQVksRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFBRSxhQUFhLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQztBQUN6TixTQUFTO0FBQ1QsS0FBSztBQUNMO0FBQ0EsSUFBSSxPQUFPLEtBQUssQ0FBQztBQUNqQixDQUFBOztBQ3JiZSxNQUFNLFNBQVMsQ0FBQztBQUMvQixJQUFJLFdBQVcsQ0FBQyxJQUFJLEdBQUcsRUFBRSxFQUFFLE9BQU8sR0FBRyxjQUFjLEVBQUU7QUFDckQsUUFBUSxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztBQUN6QixRQUFRLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7QUFDdkMsUUFBUSxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztBQUMvQjtBQUNBLFFBQVEsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtBQUM3QixZQUFZLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzVFLFNBQVM7QUFDVCxLQUFLO0FBQ0w7QUFDQSxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUU7QUFDZixRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQzdCLFFBQVEsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0FBQ3RCLFFBQVEsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ2xDLEtBQUs7QUFDTDtBQUNBLElBQUksR0FBRyxHQUFHO0FBQ1YsUUFBUSxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLE9BQU8sU0FBUyxDQUFDO0FBQ2hEO0FBQ0EsUUFBUSxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pDLFFBQVEsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUN2QyxRQUFRLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUN0QjtBQUNBLFFBQVEsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtBQUM3QixZQUFZLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO0FBQ2xDLFlBQVksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMxQixTQUFTO0FBQ1Q7QUFDQSxRQUFRLE9BQU8sR0FBRyxDQUFDO0FBQ25CLEtBQUs7QUFDTDtBQUNBLElBQUksSUFBSSxHQUFHO0FBQ1gsUUFBUSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDNUIsS0FBSztBQUNMO0FBQ0EsSUFBSSxHQUFHLENBQUMsR0FBRyxFQUFFO0FBQ2IsUUFBUSxNQUFNLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxHQUFHLElBQUksQ0FBQztBQUNyQyxRQUFRLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUMvQjtBQUNBLFFBQVEsT0FBTyxHQUFHLEdBQUcsQ0FBQyxFQUFFO0FBQ3hCLFlBQVksTUFBTSxNQUFNLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUMxQyxZQUFZLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUN6QyxZQUFZLElBQUksT0FBTyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsTUFBTTtBQUNuRCxZQUFZLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxPQUFPLENBQUM7QUFDaEMsWUFBWSxHQUFHLEdBQUcsTUFBTSxDQUFDO0FBQ3pCLFNBQVM7QUFDVDtBQUNBLFFBQVEsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQztBQUN6QixLQUFLO0FBQ0w7QUFDQSxJQUFJLEtBQUssQ0FBQyxHQUFHLEVBQUU7QUFDZixRQUFRLE1BQU0sQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLEdBQUcsSUFBSSxDQUFDO0FBQ3JDLFFBQVEsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUM7QUFDNUMsUUFBUSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDL0I7QUFDQSxRQUFRLE9BQU8sR0FBRyxHQUFHLFVBQVUsRUFBRTtBQUNqQyxZQUFZLElBQUksSUFBSSxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDdEMsWUFBWSxJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDbEMsWUFBWSxNQUFNLEtBQUssR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDO0FBQ25DO0FBQ0EsWUFBWSxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFO0FBQ3ZFLGdCQUFnQixJQUFJLEdBQUcsS0FBSyxDQUFDO0FBQzdCLGdCQUFnQixJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ25DLGFBQWE7QUFDYixZQUFZLElBQUksT0FBTyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsTUFBTTtBQUNoRDtBQUNBLFlBQVksSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQztBQUM3QixZQUFZLEdBQUcsR0FBRyxJQUFJLENBQUM7QUFDdkIsU0FBUztBQUNUO0FBQ0EsUUFBUSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDO0FBQ3pCLEtBQUs7QUFDTCxDQUFDO0FBQ0Q7QUFDQSxTQUFTLGNBQWMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQzlCLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN0QyxDQUFBOztBQzlFQTtBQUNBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNlLFNBQVEseUJBQUEsRUFBRSxZQUFZLHVCQUF1QixTQUFTLFlBQVksQ0FBQyxFQUFFLEtBQUssYUFBYSxLQUFLLFNBQVM7QUFDcEg7QUFDQSxJQUFJLElBQUksSUFBSSxHQUFHLFFBQVEsRUFBRSxJQUFJLEdBQUcsUUFBUSxFQUFFLElBQUksR0FBRyxDQUFDLFFBQVEsRUFBRSxJQUFJLEdBQUcsQ0FBQyxRQUFRLENBQUM7QUFDN0UsSUFBSSxNQUFNLFNBQVMsR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEMsSUFBSSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUMvQyxRQUFRLE1BQU0sQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvQixRQUFRLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLEVBQUUsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDekMsUUFBUSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxFQUFFLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3pDLFFBQVEsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksRUFBRSxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN6QyxRQUFRLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLEVBQUUsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDekMsS0FBSztBQUNMO0FBQ0EsSUFBSSxNQUFNLEtBQUssR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQzlCLElBQUksTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztBQUMvQixJQUFJLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQzdDLElBQUksSUFBSSxDQUFDLEdBQUcsUUFBUSxHQUFHLENBQUMsQ0FBQztBQUN6QjtBQUNBO0FBQ0EsSUFBSSxNQUFNLFNBQVMsR0FBRyxJQUFJbU8sU0FBSyxDQUFDLEVBQUUsRUFBRSxVQUFVLENBQUMsQ0FBQztBQUNoRDtBQUNBLElBQUksSUFBSSxRQUFRLEtBQUssQ0FBQyxFQUFFLE9BQU8sSUFBSW5PLE9BQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDckQ7QUFDQTtBQUNBLElBQUksS0FBSyxJQUFJLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDLElBQUksUUFBUSxFQUFFO0FBQ2hELFFBQVEsS0FBSyxJQUFJLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDLElBQUksUUFBUSxFQUFFO0FBQ3BELFlBQVksU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7QUFDcEUsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBO0FBQ0EsSUFBSSxJQUFJLFFBQVEsR0FBRyxlQUFlLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDakQsSUFBSSxJQUFJLFNBQVMsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDO0FBQ3JDO0FBQ0EsSUFBSSxPQUFPLFNBQVMsQ0FBQyxNQUFNLEVBQUU7QUFDN0I7QUFDQSxRQUFRLE1BQU0sSUFBSSxHQUFHLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNyQztBQUNBO0FBQ0EsUUFBUSxJQUFJLElBQUksQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUU7QUFDaEQsWUFBWSxRQUFRLEdBQUcsSUFBSSxDQUFDO0FBQzVCLFlBQVksSUFBSSxLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQywrQkFBK0IsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQy9HLFNBQVM7QUFDVDtBQUNBO0FBQ0EsUUFBUSxJQUFJLElBQUksQ0FBQyxHQUFHLEdBQUcsUUFBUSxDQUFDLENBQUMsSUFBSSxTQUFTLEVBQUUsU0FBUztBQUN6RDtBQUNBO0FBQ0EsUUFBUSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDdkIsUUFBUSxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7QUFDOUUsUUFBUSxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7QUFDOUUsUUFBUSxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMs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UUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzVCLFFBQVEsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDcEQsUUFBUSxNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDLFNBQVMsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztBQUNoRjtBQUNBLFFBQVEsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztBQUM3QyxRQUFRLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDdEQsUUFBUSxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7QUFDOUMsUUFBUSxJQUFJLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDN0MsS0FBSztBQUNMO0FBQ0EsSUFBSSxPQUFPLENBQUMsR0FBRyxVQUFVLEdBQUcsMEJBQTBCO0FBQ3RELFFBQVEsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDO0FBQ2hDLFFBQVEsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEQsUUFBUSxNQUFNLEdBQUcsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDbEM7QUFDQSxRQUFRLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUMzRCxRQUFRLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztBQUMzQyxRQUFRLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDaEQsUUFBUSxPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDNUIsS0FBSztBQUNMO0FBQ0EsSUFBSSxTQUFTLENBQUMsQ0FBQyxVQUFVLENBQUMsa0JBQWtCO0FBQzVDLFFBQVEsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDO0FBQ2hDLFFBQVEsTUFBTSxHQUFHLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztBQUMzQixRQUFRLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzlELFFBQVEsSUFBSSxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRTtBQUN6QixZQUFZLENBQUMsSUFBSSxJQUFJLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN6RCxTQUFTO0FBQ1QsUUFBUSxNQUFNLEVBQUUsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNoRCxRQUFRLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztBQUNqRDtBQUNBLFFBQVEsTUFBTSxHQUFHLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztBQUN2RSxRQUFRLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDekYsUUFBUSxNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMscUJBQXFCLEVBQUUscUJBQXFCLENBQUMsQ0FBQztBQUN4RjtBQUNBLFFBQVEsT0FBTyxJQUFJdEgsUUFBTSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztBQUNwQyxLQUFLO0FBQ0wsQ0FBQTs7QUN0REE7QUFLQTtBQUNBO0FBQ0E7QUFDQSxNQUFNLEVBQUUsR0FBRyxRQUFRLENBQUM7QUFDcEIsTUFBTSxFQUFFLEdBQUcsQ0FBQyxRQUFRLENBQUM7QUFDckIsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDO0FBQ3BCLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQztBQUNwQixNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUMzQjtBQUNlLE1BQU0sVUFBVSxTQUFTLFVBQVUsQ0FBQztBQUNuRDtBQUNBLElBQUksT0FBTyxDQUFDLEdBQUcsVUFBVSxHQUFHLDBCQUEwQjtBQUN0RDtBQUNBLFFBQVEsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQztBQUNsQyxRQUFRLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUM7QUFDbEMsUUFBUSxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDbkQsUUFBUSxNQUFNLE1BQU0sR0FBRyxLQUFLLEdBQUcsS0FBSyxDQUFDO0FBQ3JDLFFBQVEsTUFBTSxNQUFNLEdBQUcsTUFBTSxHQUFHLE1BQU0sR0FBRyxNQUFNLENBQUM7QUFDaEQsUUFBUSxNQUFNLENBQUMsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzdHLFFBQVEsTUFBTSxDQUFDLEdBQUcsS0FBSyxJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUcsTUFBTSxHQUFHLE1BQU0sSUFBSSxFQUFFLEdBQUcsRUFBRSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFDM0U7QUFDQSxRQUFRLE9BQU87QUFDZixZQUFZLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBRSxHQUFHLEdBQUcsSUFBSSxHQUFHO0FBQ3hDLFlBQVksQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBRSxHQUFHLENBQUMsSUFBSSxHQUFHO0FBQzFDLFlBQVksQ0FBQyxFQUFFLENBQUM7QUFDaEIsU0FBUyxDQUFDO0FBQ1YsS0FBSztBQUNMO0FBQ0EsSUFBSSxTQUFTLENBQUMsQ0FBQyxVQUFVLENBQUMsa0JBQWtCO0FBQzVDO0FBQ0EsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxJQUFJLENBQUMsRUFBRSxDQUFDO0FBQ3BDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLEVBQUUsQ0FBQztBQUN4QyxRQUFRLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQztBQUN0QixRQUFRLElBQUksTUFBTSxHQUFHLEtBQUssR0FBRyxLQUFLLENBQUM7QUFDbkMsUUFBUSxJQUFJLE1BQU0sR0FBRyxNQUFNLEdBQUcsTUFBTSxHQUFHLE1BQU0sQ0FBQztBQUM5QztBQUNBLFFBQVEsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRTtBQUNyRCxZQUFZLEVBQUUsR0FBRyxLQUFLLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRyxNQUFNLEdBQUcsTUFBTSxJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDOUUsWUFBWSxHQUFHLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUM7QUFDN0UsWUFBWSxLQUFLLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQztBQUM3QixZQUFZLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxHQUFHLEtBQUssRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDcEUsWUFBWSxNQUFN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TUFBTSxNQUFNLEdBQUcsQ0FBQyxJQUFJLE1BQU0sR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxJQUFJLFFBQVEsR0FBRyxRQUFRLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEk7QUFDQSxRQUFRLE1BQU0sR0FBRyxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDdkQsUUFBUSxNQUFNLEdBQUcsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDbEM7QUFDQSxRQUFRLE9BQU8sSUFBSXBLLFFBQU0sQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDcEMsS0FBSztBQUNMLENBQUE7O0FDdkRBO0FBS0E7QUFDQTtBQUNBO0FBQ0EsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLHFCQUFxQixDQUFDLENBQUM7QUFDL0M7QUFDZSxNQUFNLFlBQVksU0FBUyxVQUFVLENBQUM7QUFDckQ7QUFDQSxJQUFJLE9BQU8sQ0FBQyxHQUFHLFVBQVUsR0FBRywwQkFBMEI7QUFDdEQsUUFBUSxHQUFHLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzVCLFFBQVEsR0FBRyxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUM1QixRQUFRLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDckMsUUFBUSxNQUFNLFNBQVMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQztBQUN0QyxRQUFRLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDNUQsUUFBUSxNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyx3QkFBd0IsQ0FBQyxXQUFXLDBDQUEwQztBQUM5RixJQUFJLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQztBQUN0QixJQUFJLE1BQU0sRUFBRSxHQUFHLFdBQVcsQ0FBQyxFQUFFLENBQUM7QUFDOUI7QUFDQSxJQUFJLElBQUksRUFBRSxLQUFLLFNBQVMsRUFBRTtBQUMxQixRQUFRLE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDcEIsWUFBWSxPQUFPLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLGdDQUFnQyxDQUFDO0FB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QUUsR0FBRyxRQUFRLEdBQUcsRUFBRSxDQUFDO0FBQzFDLFFBQVEsTUFBTSxNQUFNLEdBQUcsRUFBRSxHQUFHLFFBQVEsR0FBRyxFQUFFLENBQUM7QUFDMUM7QUFDQTtBQUNBLFFBQVEsTUFBTSxHQUFHLEdBQUcsaUJBQWlCLENBQUMsQ0FBQyxHQUFHLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztBQUN0RCxRQUFRLE1BQU0sR0FBRyxHQUFHLGlCQUFpQixDQUFDLENBQUMsR0FBRyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDdEQsUUFBUSxNQUFNLEdBQUcsR0FBRyxpQkFBaUIsQ0FBQyxDQUFDLEdBQUcsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3RELFFBQVEsTUFBTSxHQUFHLEdBQUcsaUJBQWlCLENBQUMsQ0FBQyxHQUFHLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztBQUN0RCxRQUFRLE1BQU0sR0FBRyxHQUFHLGlCQUFpQixDQUFDLENBQUMsR0FBRyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDdEQsUUFBUSxNQUFNLEdBQUcsR0FBRyxpQkFBaUIsQ0FBQyxDQUFDLEdBQUcsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3REO0FBQ0E7QUFDQSxRQUFRLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7QUFDdEY7QUFDQSxRQUFRLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssTUFBTSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUN4RDtBQUNBLFFBQVEsSUFBSSxDQUFDLEdBQUcsa0JBQWtCLEVBQUU7QUFDcEMsWUFBWSxNQUFNLGNBQWMsR0FBRyxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsS0FBSyxDQUFDLElB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RyxLQUFLLENBQUM7QUFDeEQ7QUFDQSxJQUFJLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxLQUFLO0FBQzdCLFFBQVEsT0FBTyxJQUFJLENBQUM7QUFDcEI7QUFDQSxJQUFJLE1BQU0sTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDN0IsSUFBSSxNQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQzlCLElBQUksTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUM5QixJQUFJLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDOUIsSUFBSSxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssR0FBRyxLQUFLLEdBQUcsS0FBSyxHQUFHLEtBQUssR0FBRyxLQUFLLEdBQUcsS0FBSyxJQUFJLE1BQU0sQ0FBQztBQUN2RTtBQUNBLElBQUksSUFBSSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxHQUFHO0FBQzFCLFFBQVEsT0FBTyxJQUFJLENBQUM7QUFDcEI7QUFDQTtBQUNBLElBQUksTUFBTSxLQUFLLEdBQUcsS0FBSyxHQUFHLEdBQUcsR0FBRyxLQUFLLEdBQUcsR0FBRyxDQUFDO0FBQzVDLElBQUksTUFBTSxLQUFLLEdBQUcsS0FBSyxHQUFHLEdBQUcsR0FBRyxLQUFLLEdBQUcsR0FBRyxDQUFDO0FBQzVDLElBQUksTUFBTSxLQUFLLEdBQUcsS0FBSyxHQUFHLEdBQUcsR0FBRyxLQUFLLEdBQUcsR0FBRyxDQUFDO0FBQzVDLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssSUFBSSxNQUFNLENBQUM7QUFDMUU7QUFDQSxJQUFJLElBQUksQ0FBQyxHQUFH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LFlBQVksWUFBWSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxXQUFXLENBQUMsQ0FBQztBQUNyRDtBQUNBLFlBQVksTUFBTSxFQUFFLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDNUUsWUFBWSxNQUFNLEVBQUUsR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM1RSxZQUFZLE1BQU0sRUFBRSxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzVFLFlBQVksTUFBTSxFQUFFLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDNUU7QUFDQSxZQUFZLE1BQU0sRUFBRSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RFLFlBQVksTUFBTSxFQUFFLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEUsWUFBWSxNQUFNLEVBQUUsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0RSxZQUFZLE1BQU0sRUFBRSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RFO0FBQ0Es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QUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEU7QUFDQSxZQUFZLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0Q7QUFDQSxZQUFZLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0RSxTQUFTO0FBQ1Q7QUFDQSxRQUFRLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM1RCxRQUFRLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ25FLFFBQVEsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbkUsUUFBUSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMs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RUFBRSxDQUFDO0FBQzNELFFBQVEsSUFBSSxDQUFDLHFCQUFxQixDQUFDLFVBQVUsRUFBRSxDQUFDO0FBQ2hELEtBQUs7QUFDTDtBQUNBLElBQUksUUFBUSxHQUFHO0FBQ2YsUUFBUSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7QUFDckMsUUFBUSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7QUFDckMsUUFBUSxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7QUFDdkMsUUFBUSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7QUFDcEMsUUFBUSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7QUFDcEMsUUFBUSxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7QUFDdEMsUUFBUSxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7QUFDdEMsUUFBUSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7QUFDcEMsUUFBUSxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7QUFDdEMsUUFBUSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7QUFDckMsUUFBUSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7QUFDcEMsUUFBUSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7QUFDcEMsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7QUFDaEMsUUFBUSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7QUFDcEMsUUFBUSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7QUFDckMsUUFBUSxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssR0FBRyxJ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SSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUM5RCxnQkFBZ0IsVUFBVSxDQUFDLElBQUksRUFBRSxVQUFVLENBQUMsQ0FBQztBQUM3QyxnQkFBZ0IsVUFBVSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUM3QyxhQUFhO0FBQ2IsU0FBUztBQUNUO0FBQ0EsUUFBUSxTQUFTLFVBQVUsQ0FBQyxJQUFJLFFBQVEsVUFBVSxRQUFRO0FBQzFELFlBQVksSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsT0FBTztBQUMxRCxZQUFZLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLENBQUM7QUFDOUMsWUFBWSxJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxDQUFDO0FBQzlDLFlBQVksSUFBSSxFQUFFLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUM3RSxZQUFZLE1BQU0sRUFBRSxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7QUFDL0UsWUFBWSxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM3RCxZQUFZLE1BQU0sUUFBUSxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDO0FBQ25ELFlBQVksSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLEVBQUUsT0FBTztBQUM3QztBQUNBLFlBQVksSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRTtBQUNsQyxnQkFBZ0IsT0FBTztBQUN2QixhQUFhO0FBQ2IsWUFBWSxJQUFJ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O0FBQ2hELFlBQVksTUFBTSxFQUFFLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3ZGLFlBQVksTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUMzRSxZQUFZLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDbkYsWUFBWSxNQUFNLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUM1RCxTQUFTO0FBQ1Q7QUFDQSxRQUFRLE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO0FBQ3ZDLFFBQVEsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDO0FBQ3JCLFFBQVEsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDO0FBQ3RCO0FBQ0EsUUFBUSxRQUFRLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDdkMsUUFBUSxJQUFJLE1BQU0sQ0FBQyxDQUFDLEdBQUcsS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxRQUFRLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDN0U7QUFDQSxRQUFRLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRTtBQUN0QixZQUFZLFFBQVEsQ0FBQyxHQUFHLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUN4QyxZQUFZLENBQUMsRUFBRSxDQUFDO0FBQ2hCLFlBQVksQ0FBQyxFQUFFLENBQUM7QUFDaEIsWUFBWSxPQUFPLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztBQUNqRCxZQUFZLE9BQU8sTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0FBQ2pELFNBQVM7QUFDVDtBQUNBLFFBQVEsSUFBSSxNQUFNLENBQUMsQ0FBQyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsUUFBUSxDQUFDLEdBQUcsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzFFLGFBQWE7QUFDYixZQUFZLENBQUMsRUFBRSxDQUFDO0FBQ2hCLFlBQVksUUFBUSxDQUFDLEdBQUcsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQzVDLFNBQVM7QUFDVDtBQUNBLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2pDLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2xDLEtBQUs7QUFDTCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTLFFBQVEsQ0FBQyxHQUFHLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDckMsSUFBSSxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNwQixJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDL0IsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDdkMsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ3pCLElBQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNwQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDakIsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFO0FBQ2hDLElBQUksTUFBTSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUN2QixJQUFJLE1BQU0sRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDdkIsSUFBSSxPQUFPLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUM3QixDQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7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QUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUNsRyxTQUFTO0FBQ1Q7QUFDQSxRQUFRLElBQUksR0FBRyxFQUFFLE9BQU8sQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDL0M7QUFDQSxRQUFRLE9BQU8sSUFBSSxDQUFDO0FBQ3BCLEtBQUs7QUFDTDtBQUNBLElBQUksV0FBVyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUU7QUFDNUIsUUFBUSxJQUFJLE1BQU0sR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLEdBQUcsR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDL0QsUUFBUSxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDNUQsUUFBUSxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLEdBQUcsR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDdkYsUUFBUSxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDNUQ7QUFDQSxRQUFRLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLEVBQUU7QUFDdEMsWUFBWSxNQUFNLEdBQUcsQ0FBQyxHQUFHLENBQUM7QUFDMUIsWUFBWSxNQUFNLEdBQUcsR0FBRyxDQUFDO0FBQ3pCLFNBQVMsTUFBTSxJQUFJLE1BQU0sR0FBRyxNQUFNLEVBQUU7QUFDcEMsWUFBWSxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDckYsWUFBWSxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUN0RixZQUFZLE9BQU8sVUFBVSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUNqRCxTQUFTO0FBQ1Q7QUFDQSxRQUFRLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ3ZELFFBQVEsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztBQUN2RixRQUFRLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7QUFDL0IsUUFBUSxNQUFNLFFBQVEsR0FBRyxFQUFFLENBQUM7QUFDNUIsUUFBUSxLQUFLLE1BQU0sRUFBRSxJQUFJLEdBQUcsRUFBRTtBQUM5QixZQUFZLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFDO0FBQ3ZDLFlBQVksUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxjQUFjLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNwSSxTQUFTO0FBQ1QsUUFBUSxPQUFPLFFBQVEsQ0FBQztBQUN4QixLQUFLO0FBQ0w7QUFDQSxJQUFJLFdBQVcsQ0FBQyxTQUFTLEVBQUU7QUFDM0IsUUFBUSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQ3RELFFBQVEsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUMxRCxRQUFRLE1BQU0sUUFBUSxHQUFHLG1DQUFtQyxDQUFDO0FBQzdEO0FBQ0EsUUFBUSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQzVDLFFBQVEsSUFBSSxDQUFDLElBQUksRUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQzdDO0FBQ0EsUUFBUSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO0FBQy9CLFFBQVEsSUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDN0U7QUFDQSxRQUFRLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLFVBQVUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzVGLFFBQVEsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDL0MsUUFBUSxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDbkQsUUFBUSxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMs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QUM7QUFDRDtBQUNBLFNBQVMsWUFBWSxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUU7QUFDckMsSUFBSSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFO0FBQzdDLFFBQVEsT0FBTyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkQsUUFBUSxPQUFPLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDM0QsUUFBUSxPQUFPLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2RCxRQUFRLE9BQU8sQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMzRCxLQUFLO0FBQ0wsQ0FBQTs7QUN4Q0E7QUFDQTtBQUNlLFNBQVMsT0FBTyxDQUFDLElBQUksRUFBRSxPQUFPLEVBQUU7QUFDL0MsSUFBSSxJQUFJLFFBQVEsR0FBRyxFQUFFLENBQUM7QUFDdEIsSUFBSSxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssbUJBQW1CLEVBQUU7QUFDM0MsUUFBUSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7QUFDdkQsWUFBWSxjQUFjLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FB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SyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUU7QUFDakQsUUFBUSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDekIsUUFBUSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzdCLFFBQVEsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUM3QixRQUFRLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDN0IsUUFBUSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzdCLFFBQVEsSUFBSSxDQUFDLEdBQUcsSUFBSSxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ3JDLFFBQVEsSUFBSSxDQUFDLEdBQUcsSUFBSSxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ3JDLFFBQVEsSUFBSSxNQUFNLEdBQUcsS0FBSyxDQUFDO0FBQzNCO0FBQ0EsUUFBUSxJQUFJLFlBQVksRUFBRSxNQUFNLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDMUY7QUFDQSxRQUFRLElBQUksQ0FBQyxHQUFHLEVBQUUsRUFBRTtBQUNwQjtBQUNBLFlBQVksSUFBSSxDQUFDLEdBQUcsRUFBRSxFQUFFO0FBQ3hCLGdCQUFnQixDQUFDLEdBQUcsU0FBUyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFD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QyxDQUFDO0FBQ2hCLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixDQUFDO0FBQ0Q7QUFDQSxTQUFTLFVBQVUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRTtBQUM1QyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7QUFDakMsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ2pDLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixJQUFJLE9BQU8sQ0FBQyxDQUFDO0FBQ2IsQ0FBQztBQUNEO0FBQ0EsU0FBUyxVQUFVLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUU7QUFDNUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0FBQ2pDLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ2pDLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQixJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEIsSUFBSSxPQUFPLENBQUMsQ0FBQztBQUNiLENBQUE7O0FDM01lLFNBQVMsSUFBSSxDQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUU7QUFDaEQsSUFBSSxJQUFJLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FB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QUMsSUFBSSxDQUFDLENBQUM7QUFDdEIsQ0FBQztBQUNEO0FBQ0EsU0FBUyxNQUFNLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRTtBQUNqQyxJQUFJLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQztBQUNqQixJQUFJLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFO0FBQzVFLFFBQVEsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsRSxLQUFLO0FBQ0wsSUFBSSxJQUFJLElBQUksR0FBRyxDQUFDLEtBQUssU0FBUyxFQUFFO0FBQ2hDLFFBQVEsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUU7QUFDNUQsWUFBWSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDNUIsWUFBWSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLFlBQVksSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3hDLFlBQVksSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUM1QyxZQUFZLElBQUksQ0FBQyxH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O0FBQ3hDO0FBQ0EsUUFBUSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBQ2pDO0FBQ0EsUUFBUSxJQUFJLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRSxFQUFFLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDckYsUUFBUSxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRSxFQUFFLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDckYsUUFBUSxRQUFRLEdBQUcsSUFBSSxDQUFDO0FBQ3hCO0FBQ0EsUUFBUSxJQUFJLElBQUksRUFBRTtBQUNsQixZQUFZLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztBQUNsRixZQUFZLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztBQUNsRixZQUFZLElBQUksR0FBRyxJQUFJLENBQUM7QUFDeEIsU0FBUztBQUNUO0FBQ0EsUUFBUSxJQUFJLEtBQUssRUFBRTtBQUNuQixZQUFZLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztBQUNuRixZQUFZLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztBQUNuRixZQUFZLEtBQUssR0FBRyxJQUFJLENBQUM7QUFDekIsU0FBUztBQUNUO0FBQ0EsUUFBUSxJQUFJLEtBQUssR0FBRyxDQUFDLEVBQUUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUNuRDtBQUNBLFFBQVEsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDdEQsUUFBUSxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDMUQsUUFBUSxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDdEQsUUFBUSxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzFELEtBQUs7QUFDTCxDQUFDLENBQUM7QUFDRjtB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Q0FBQztBQUN0QyxZQUFZLE1BQU0sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDO0FBQ3RDLFlBQVksTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUM7QUFDN0MsWUFBWSxNQUFNLENBQUMsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDO0FBQ2hDLFlBQVksTUFBTSxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQztBQUNqQztBQUNBLFlBQVlOLEtBQVMsQ0FBQSxTQUFBLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEY7QUFDQTtBQUNBLFlBQVlBLGVBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM3RixZQUFZQSxlQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM3RixZQUFZQSxlQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFB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QUFNLEVBQUUsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7QUFDakQsUUFBUSxNQUFNLEdBQUcsR0FBRyxTQUFTLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDO0FBQ3RFLFFBQVEsTUFBTSxFQUFFLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDO0FBQ2pELFFBQVEsTUFBTSxHQUFHLEdBQUcsU0FBUyxDQUFDLENBQUMsR0FBRyxDQUFDLEtBQUssR0FBRyxHQUFHLE1BQU0sQ0FBQyxJQUFJLEdBQUcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDNUU7QUFDQSxRQUFRLE1BQU0sZ0JBQWdCLEdBQUcsRUFBRSxDQUFDO0FBQ3BDO0FBQ0EsUUFBUSxnQkFBZ0IsQ0FBQyxJQUFJMFEsS0FBQUEsQ0FBQUEsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxHQUFHLEVBQUUsU0FBUyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ2hJLFFBQVEsZ0JBQWdCLENBQUMsSUFBSUEsS0FBQUEsQ0FBQUEsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxHQUFHLEVBQUUsU0FBUyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ2hJO0FBQ0E7QUFDQSxRQUFRLElBQUksU0FBUyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUU7QUFDN0IsWUFBWSxnQkFBZ0IsQ0FBQyxJQUFJQSxLQUFBQSxDQUFBQSxnQkFBZ0IsQ0FBQyxNQUFN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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUyxhQUFhLENBQUMsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVTtBQUN2SCxJQUFJLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNoRCxJQUFJLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUMxQixJQUFJLE1BQU0sRUFBRSxHQUFHb1QsS0FBQUEsQ0FBQUEsT0FBWSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNuQyxJQUFJLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxHQUFHQyxLQUFrQixDQUFBLGFBQUEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFQyxLQUFjLENBQUEsU0FBQSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzFFLElBQUksT0FBT2xJLEtBQWEsQ0FBQSxVQUFBLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUMvRCxDQUFDO0FBQ0Q7QUFDQSxTQUFTLHVCQUF1QixDQUFDLENBQUMsVUFBVSxDQUFDLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVTtBQUN2SixJQUFJLE1BQU0sQ0FBQyxHQUFHLGFBQWEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDcEQsSUFBSSxNQUFNLENBQUMsR0FBRyxhQUFhLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQzVELElBQUlBLEtBQWEsQ0FBQSxVQUFBLENBQUMsQ0FBQyxFQUFFZ0ksS0FBWSxDQUFBLE9BQUEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDNUMsSUFBSSxPQUFPO0FBQ1gsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRzFTLEtBQU0sQ0FBQSxNQUFBO0FBQ2hDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUdBLEtBQU0sQ0FBQSxNQUFBO0FBQ2hDLEtBQUssQ0FBQztBQUNOLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNLFdBQVcsU0FBU3FRLEtBQUFBLENBQUFBLE9BQU8sbUJBQW1CO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QVksTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxPQUFPLENBQUMsQ0FBQyxDQUFDO0FBQ3pDLFNBQVM7QUFDVCxLQUFLLENBQUMsQ0FBQztBQUNQO0FBQ0EsSUFBSSxTQUFTLE1BQU0sNEJBQTRCO0FBQy9DLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ2UsU0FBUyxXQUFXLENBQUMsTUFBTSx3REFBd0Q7QUFDbEcsSUFBSSxNQUFNLEdBQUcsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO0FBQzVCO0FBQ0EsSUFBSSxNQUFNLEdBQUcsV0FBVyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQzVDLElBQUksS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7QUFDNUMsUUFBUSxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QyxLQUFLO0FBQ0w7QUFDQSxJQUFJLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO0FBQzVDLFFBQVEsSUFBSSxLQUFLLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFO0FBQ2hDLFlBQVksTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDcEUsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBLElBQUksT0FBTyxNQUFNLENBQUM7QUFDbEIsQ0FBQTs7QUNwREE7QUFDQTtBQUNBO0FBQ2UsU0FBUyxVQUFVLHVCQUF1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QUFJLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbkUsU0FBUztBQUNULFFBQVEsSUFBSSxDQUFDQSxLQUFPLENBQUEsU0FBQSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFO0FBQ25ELFlBQVksUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakYsU0FBUztBQUNULFFBQVEsSUFBSSxDQUFDQSxLQUFPLENBQUEsU0FBQSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFO0FBQy9DLFlBQVksUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDN0UsU0FBUztBQUNULFFBQVEsSUFBSSxDQUFDQSxLQUFPLENBQUEsU0FBQSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFO0FBQ3JELFlBQVksUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsVUFBVSxFQUFFLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbkYsU0FBUztBQUNULFFBQVEsSUFBSSxDQUFDQSxLQUFPLENBQUEsU0FBQSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFFO0FBQ2pELFlBQVksUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0UsU0FBUztBQUNULFFBQVEsSUFBSSxDQUFDQSxLQUFPLENBQUEsU0FBQSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFO0FBQ25ELFlBQVksUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakYsU0FBUztBQUNULFFBQVEsSUFBSSxDQUFDQSxLQUFPLENBQUEsU0FBQSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFO0FBQ25ELFlBQVksUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakYsU0FBUztBQUNULFFBQVEsSUFBSSxDQUFDQSxLQUFPLENBQUEsU0FBQSxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLFVBQVUsQ0FBQyxFQUFFO0FBQzNELFlBQVksUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsYUFBYSxFQUFFLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDekYsU0FBUztBQUNULFFBQVEsSUFBSSxDQUFDQSxLQUFPLENBQUEsU0FBQSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFFO0FBQ2pELFlBQVksUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0UsU0FBUztBQUNULFFBQVEsSUFBSSxDQUFDQSxLQUFPLENBQUEsU0FBQSxDQUFDLE1BQU0s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QW9CLE1BQU0sV0FBVyxNQUFNLFdBQVc7QUFDM0osSUFBSSxvQkFBb0IsQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsT0FBTyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsTUFBTSxJQUFJLENBQUMsRUFBRSxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDaEcsSUFBSSxvQkFBb0IsQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsT0FBTyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsTUFBTSxJQUFJLENBQUMsRUFBRSxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDaEcsSUFBSSxvQkFBb0IsQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsT0FBTyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsTUFBTSxJQUFJLENBQUMsRUFBRSxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDaEcsSUFBSSxvQkFBb0IsQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsT0FBTyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsTUFBTSxJQUFJLENBQUMsRUFBRSxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDaEcsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNoQyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNoQyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNoQyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNoQyxNQUFNLE1BQU0sR0FBRyxJQUFJ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Q0FBQztBQUN2RCxZQUFZLFdBQVcsQ0FBQyxXQUFXLENBQUMsRUFBRSxHQUFHLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNyRCxTQUFTO0FBQ1QsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLElBQUksTUFBTSxrQkFBa0IsR0FBRyxDQUFDLElBQUksR0FBRyxDQUFDLEtBQUssSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUMzRCxJQUFJLE1BQU0sSUFBSSxHQUFHLENBQUMsQ0FBQyxVQUFVLENBQUMsYUFBYTtBQUMzQyxRQUFRLE1BQU0sS0FBSyxHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDO0FBQ25DLFFBQVEsVUFBVSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUM7QUFDL0QsUUFBUSxVQUFVLENBQUMsV0FBVyxDQUFDLEtBQUssR0FBRyxJQUFJLEVBQUUsS0FBSyxHQUFHLElBQUksR0FBRyxDQUFDLEVBQUUsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzFFLEtBQUssQ0FBQztBQUNOLElBQUksS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7QUFDdkMsUUFBUSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUMzQyxZQUFZLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDdkIsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBLElBQUksQ0FBQyxDQUFDLEVBQUUsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUk7QUFDL0IsUUFBUSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDLEVB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QUcsS0FBSyxDQUFDLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO0FBQy9ELFlBQVksTUFBTSxTQUFTLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNwQyxZQUFZLE1BQU0sQ0FBQyxHQUFHLEtBQUssQ0FBQyxXQUFXLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3ZELFlBQVksTUFBTSxDQUFDLEdBQUcsS0FBSyxDQUFDLFdBQVcsQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDdkQsWUFBWSxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsV0FBVyxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUM1RCxZQUFZLE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxXQUFXLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQy9EO0FBQ0E7QUFDQSxZQUFZLFVBQVUsQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzNFLFlBQVksVUFBVSxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDM0UsWUFBWSxVQUFVLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUMzRSxZQUFZLFVBQVUsQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzNFLFNBQVM7QUFDVCxLQUFLO0FBQ0wsSUFBSSxJQUFJLENBQUMsYUFBYSxJQUFJLGFBQWEsQ0FBQyxNQUFNLEdBQUcsV0FBVyxHQUFHLENBQUMsRUFBRTtBQUNsRSxR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LHFCQUFrQixFQUFFLENBQUM7QUFDaEQ7QUFDQSxRQUFRLFNBQVMsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQ3RELFFBQVEsU0FBUyxDQUFDLElBQUksQ0FBQyxXQUFXLEdBQUcsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQ3RELFFBQVEsU0FBUyxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQ3RELFFBQVEsU0FBUyxDQUFDLElBQUksQ0FBQyxXQUFXLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUN0RCxRQUFRLFNBQVMsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDdEQsUUFBUSxTQUFTLENBQUMsSUFBSSxDQUFDLFdBQVcsR0FBRyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN0RCxRQUFRLFNBQVMsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsR0FBRyxHQUFHLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3RELFFBQVEsU0FBUyxDQUFDLElBQUksQ0FBQyxXQUFXLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3REO0FBQ0E7QUFDQSxRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDMUMsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzFDO0FBQ0EsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxD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QUFDQSxJQUFJLGFBQWEsQ0FBQyxLQUFLLFNBQVMsbUJBQW1CLFdBQVc7QUFDOUQsUUFBUSxNQUFNLE9BQU8sR0FBRyxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLGVBQWUsQ0FBQztBQUNoRyxRQUFRLElBQUksQ0FBQyxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRSxPQUFPO0FBQzNFLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUU7QUFDNUIsWUFBWSxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksT0FBTyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztBQUNyRCxTQUFTO0FBQ1QsUUFBUSxNQUFNLE9BQU8sWUFBWSxJQUFJLENBQUMsUUFBUSxDQUFDO0FBQy9DLFFBQVEsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEdBQUcsT0FBTyxHQUFHLE9BQU8sR0FBRyxJQUFJLENBQUM7QUFDNUQsUUFBUSxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLG1CQUFtQixDQUFDLENBQUM7QUFDbkUsS0FBSztBQUNMO0FBQ0EsSUFBSSxVQUFVLENBQUMsS0FBSyxTQUFTO0FBQzdCO0FBQ0E7QUFDQSxRQUFRLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxPQUFPLENBQUM7QUFDbkU7QUFDQSxRQUFRLE1BQU0sR0FBRyxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUM7QUFDOUIsUUFBUSxJQUFJLENBQUMsR0FBRyxJQUFJLE9BQU8sSUFBSSxHQUFHLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLGVBQWUs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QUksTUFBTSxDQUFDLEtBQUssSUFBSSxJQUFJLElBQUksS0FBSyxDQUFDLEtBQUssSUFBSSxJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssR0FBR0EsS0FBQUEsQ0FBQUEsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztBQUMzRztBQUNBLFFBQVEsT0FBTyxJQUFJLENBQUM7QUFDcEIsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLFNBQVMsQ0FBQyxLQUFLLFVBQVUsTUFBTSxpQkFBaUI7QUFDcEQ7QUFDQSxRQUFRLE1BQU0sQ0FBQyxHQUFHckksS0FBQUEsQ0FBQUEsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ3hFLFFBQVEsTUFBTSxDQUFDLEdBQUdBLEtBQUFBLENBQUFBLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQztBQUMxRTtBQUNBLFFBQVEsT0FBTyxJQUFJclQsS0FBSyxDQUFBLEtBQUEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDL0IsS0FBSztBQUNMO0FBQ0EsSUFBSSxNQUFNLENBQUMsS0FBSywyQkFBMkI7QUFDM0MsUUFBUSxPQUFPLElBQUksQ0FBQyxHQUFHLEtBQUssS0FBSyxDQUFDLEdBQUc7QUFDckMsWUFBWSxJQUFJLENBQUMsTUFBTSxLQUFLLEtBQUssQ0FBQyxNQUFNO0FBQ3hDLFlBQVksSUFBSSxDQUFDLElBQUksS0FBSyxLQUFLLENBQUMsSUFBSTtBQUNwQyxZQUFZLElBQUksQ0FBQyxLQUFLLEtBQUssS0FBSyxDQUFDLEtBQUssQ0FBQztBQUN2QyxLQUFLO0FBQ0w7QUFDQSxJQUFJLEtBQUssZUFBZTtBQUN4QixRQUFRLE9BQU8sSUFBSSxVQUFVLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzVFLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLE1BQU0sbUJBQW1CO0FBQzdCLFFBQVEsT0FBTztBQUNmLFlBQVksR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHO0FBQ3pCLFlBQVksTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO0FBQy9CLFlBQVksSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO0FBQzNCLFlBQVksS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO0FBQzdCLFNBQVMsQ0FBQztBQUNWLEtBQUs7QUFDTCxDQUFBOztBQ3RHQTtBQUNBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVMsMEJBQTBCLENBQUMsTUFBTSxRQUFRLFdBQVcsUUFBUTtBQUNyRTtBQUNBLElBQUksTUFBTSxRQUFRLFNBQVMyYixLQUFBQSxDQUFBQSxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2hEO0FBQ0E7QUFDQSxJQUFJVCxjQUFhLENBQUMsTUFBTSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0FBQ3ZDLElBQUlVLEtBQUFBLENBQUFBLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQ25DLENBQUM7QUFDRDtBQUNBLFNBQVMsdUJBQXVCLENBQUMsTUFBTSxRQUFRLFFBQVEsUUFBUTtBQUMvRCxJQUFJQSxLQUFBQSxDQUFBQSxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDdkUsQ0FBQztBQUNEO0FBQ0EsU0FBUywyQkFBMkIsQ0FBQyxLQUFLLFVBQVUsT0FBTyxnQkFBZ0I7QUFDM0U7QUFDQTtBQUNBLElBQUksTUFBTSxXQUFXLEdBQUczTSxnQkFBYSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQzFDLElBQUlsRixLQUFBQSxDQUFBQSxTQUFZLENBQUMsV0FBVyxFQUFFLFdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3JELElBQUlGLEtBQUFBLENBQUFBLFNBQVksQ0FBQyxXQUFXLEVBQUUsV0FBVyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDbkQsSUFBSSxPQUFPLFdBQVcsQ0FBQztBQUN2QixDQUFDO0FBQ0Q7QUFDTyxTQUFTLG9CQUFvQixDQUFDLE9BQU8sUUFBUSxFQUFFLGVBQWU7QUFDckU7QUFDQTtBQUNBLElBQUksTUFBTSxTQUFTLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2xELElBQUksTUFBTSxJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ25DO0FBQ0EsSUFBSSxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUM7QUFDMUI7QUFDQSxJQUFJLElBQUlrQixLQUFXLENBQUEsTUFBQSxDQUFDLFNBQVMsQ0FBQyxJQUFJLE9BQU8sRUFBRTtBQUMzQztBQUNBO0FBQ0EsUUFBUSxNQUFNLEtBQUssR0FBR3hCLEtBQUFBLENBQUFBLFNBQWMsQ0FBQyxFQUFFLEVBQUUsU0FBUyxDQUFDLENBQUM7QUFDcEQsUUFBUXFCLEtBQVUsQ0FBQSxPQUFBLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRXhCLEtBQVEsQ0FBQSxHQUFBLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDdkQ7QUFDQSxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDeEIsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLEtBQUs7QUFDTDtBQUNBLElBQUksTUFBTSxLQUFLLEdBQUdDLEtBQVUsQ0FBQSxLQUFBLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUM5QyxJQUFJLElBQUlDLEtBQVEsQ0FBQSxHQUFBLENBQUMsS0FBSyxDQUFDLEdBQUcsT0FBTyxFQUFFO0FBQ25DLFFBQVEsT0FBTyxJQUFJLENBQUM7QUFDcEIsS0FBSztBQUNMO0FBQ0EsSUFBSSxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3BELElBQUksTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDeEc7QUFDQSxJQUFJLE9BQU8sMkJBQTJCLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQ3ZELENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTSxpQkFBaUIsQ0FBQztBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxXQUFXLENBQUMsUUFBUSx1QkFBdUIsV0FBVyxTQUFTO0FBQ25FLFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7QUFDakMsUUFBUSxJQUFJLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQztBQUN2QyxLQUFLO0FBQ0w7QUFDQSxJQUFJLElBQUksUUFBUSx3QkFBd0I7QUFDeEMsUUFBUSxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUM7QUFDOUIsS0FBSztBQUNMO0FBQ0EsSUFBSSxJQUFJLFFBQVEsQ0FBQyxRQUFRLDhCQUE4QjtBQUN2RCxRQUFRLElBQUksQ0FBQyxRQUFRLEVBQUU7QUFDdkIsWUFBWSxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztBQUNsQyxTQUFTLE1BQU07QUFDZixZQUFZLE1BQU0sa0JBQWtCLEdBQUcsUUFBUSxZQUFZMEIsS0FBa0IsQ0FBQSxrQkFBQSxHQUFHLFFBQVEsR0FBRyxJQUFJQSxLQUFBQSxDQUFBQSxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3pKLFlBQVksSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUU7QUFDekMsZ0JBQWdCLGtCQUFrQixDQUFDLENBQUMsR0FBRzZRLFVBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ3hFLGFBQWE7QUFDYixZQUFZLElBQUksQ0FBQyxTQUFTLEdBQUcsa0JBQWtCLENBQUM7QUFDaEQsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksV0FBVyxDQUFDLFFBQVEsY0FBYyxFQUFFLFNBQVM7QUFDakQsUUFBUSxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztBQUNoQyxRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFO0FBQzVCLFlBQVksT0FBTztBQUNuQixTQUFTO0FBQ1Q7QUFDQSxRQUFRLE1BQU0sR0FBRyx1QkFBdUIsSUFBSSxDQUFDLFFBQVEsQ0FBQztBQUN0RCxRQUFRLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQzdRLEtBQUFBLENBQUFBLGtCQUFrQixDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN6SCxRQUFRLE1BQU0sTUFBTSxHQUFHQSxLQUFrQixDQUFBLGtCQUFBLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQztBQUN6RSxRQUFRLE1BQU0sT0FBTyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvRSxRQUFRLElBQUksQ0FBQyxFQUFFO0FBQ2YsWUFBWSxFQUFFLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzNCO0FBQ0E7QUFDQSxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hDO0FBQ0EsUUFBUSxJQUFJLENBQUMsV0FBVyxHQUFHLG9CQUFvQixDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQztBQUM3RCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksZUFBZSxDQUFDLEtBQUssVUFBVSxPQUFPLFVBQVU7QUFDcEQsUUFBUSxJQUFJLENBQUMsV0FBVyxHQUFHLDJCQUEyQixDQUFDK0csS0FBUSxDQUFBLFFBQUEsQ0FBQyxLQUFLLENBQUMsRUFBRUEsS0FBUSxDQUFBLFFBQUEsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7QUFDNUYsS0FBSztBQUNMLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNLFVBQVUsQ0FBQztBQUNqQjtBQUNBO0FBQ0E7QUFDQSxJQUFJLFdBQVcsQ0FBQyxRQUFRLFNBQVMsV0FBVyxTQUFTO0FBQ3JELFFBQVEsSUFBSSxDQUFDLFVBQVUsR0FBR3ZHLGNBQWEsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUM1QyxRQUFRLElBQUksQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDO0FBQ3ZDLFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7QUFDakMsS0FBSztBQUNMO0FBQ0EsSUFBSSxJQUFJLGdCQUFnQix1QkFBdUI7QUFDL0MsUUFBUSxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO0FBQ2xDLFFBQVEsT0FBTyxJQUFJUixLQUFBQSxDQUFBQSxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzlELEtBQUs7QUFDTDtBQUNBLElBQUksSUFBSSxRQUFRLFNBQVM7QUFDekIsUUFBUSxNQUFNLEdBQUcsU0FBUzJRLEtBQVMsQ0FBQSxTQUFBLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUN4RCxRQUFRLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hDLEtBQUs7QUFDTDtBQUNBLElBQUksSUFBSSxRQUFRLENBQUMsS0FBSyxTQUFTO0FBQy9CLFFBQVEsSUFBSSxLQUFLLEVBQUU7QUFDbkIsWUFBWSx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQzVELFNBQVM7QUFDVCxLQUFLO0FBQ0w7QUFDQSxJQUFJLElBQUksV0FBVyxTQUFTO0FBQzVCLFFBQVEsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDO0FBQ2pDLEtBQUs7QUFDTDtBQUNBLElBQUksSUFBSSxXQUFXLENBQUMsS0FBSyxTQUFTO0FBQ2xDLFFBQVEsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLElBQUkxTSxLQUFhLENBQUEsVUFBQSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3ZELFFBQVEsSUFBSSxLQUFLLEVBQUU7QUFDbkIsWUFBWSwwQkFBMEIsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUMzRSxTQUFTO0FBQ1QsS0FBSztBQUNMO0FBQ0EsSUFBSSxlQUFlLHFDQUFxQztBQUN4RCxRQUFRLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztBQUNqQyxRQUFRLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztBQUMvQjtBQUNBLFFBQVEsT0FBTztBQUNmLFlBQVksT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzVDLFlBQVksS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMxRSxTQUFTLENBQUM7QUFDVixLQUFLO0FBQ0w7QUFDQSxJQUFJLGVBQWUsQ0FBQyxLQUFLLFVBQVUsT0FBTyxVQUFVO0FBQ3BELFFBQVEsSUFBSSxDQUFDLFlBQVksR0FBRywyQkFBMkIsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDeEUsUUFBUSwwQkFBMEIsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUN2RSxLQUFLO0FBQ0w7QUFDQSxJQUFJLE9BQU8sU0FBUztBQUNwQixRQUFRLE1BQU0sR0FBRyxTQUFTME0sS0FBUyxDQUFBLFNBQUEsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ3hEO0FBQ0EsUUFBUSxPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMzQyxLQUFLO0FBQ0w7QUFDQSxJQUFJLEVBQUUsU0FBUztBQUNmLFFBQVEsTUFBTSxHQUFHLFNBQVNBLEtBQVMsQ0FBQSxTQUFBLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUN4RDtBQUNBLFFBQVEsT0FBTyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDM0MsS0FBSztBQUNMO0FBQ0EsSUFBSSxLQUFLLFNBQVM7QUFDbEIsUUFBUSxNQUFNLEdBQUcsU0FBU0EsS0FBUyxDQUFBLFNBQUEsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ3hELFFBQVEsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDeEMsS0FBSztBQUNMO0FBQ0EsSUFBSSxnQkFBZ0IsQ0FBQyxTQUFTLFVBQVUsY0FBYyx3QkFBd0I7QUFDOUUsUUFBUSxNQUFNLGFBQWEsR0FBRyxJQUFJLFlBQVksQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNuRCxRQUFRelEsS0FBVyxDQUFBLFFBQUEsQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxjQUFjLENBQUMsQ0FBQyxDQUFDO0FBQ3JGLFFBQVEsT0FBTyxhQUFhLENBQUM7QUFDN0IsS0FBSztBQUNMO0FBQ0EsSUFBSSx3QkFBd0IsQ0FBQyxTQUFTLFVBQVUsY0FBYyxVQUFVLFlBQVksd0JBQXdCO0FBQzVHLFFBQVEsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztBQUMxQztBQUNBLFFBQVFOLEtBQUFBLENBQUFBLE9BQVUsQ0FBQyxXQUFXLEVBQUUsV0FBVyxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDekQsUUFBUSxNQUFNLE1BQU0sR0FBRyxJQUFJLFlBQVksQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUM1QyxRQUFRTyxLQUFnQixDQUFBLFdBQUEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxZQUFZLEVBQUUsWUFBWSxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7QUFDN0UsUUFBUUMsS0FBQUEsQ0FBQUEsU0FBYyxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsV0FBVyxDQUFDLENBQUM7QUFDcEQ7QUFDQTtBQUNBLFFBQVEsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLGNBQWMsQ0FBQztBQUNyQztBQUNBLFFBQVEsT0FBTyxNQUFNLENBQUM7QUFDdEIsS0FBSztBQUNMO0FBQ0EsSUFBSSxnQkFBZ0IsQ0FBQyxTQUFTLFVBQVUsY0FBYyx3QkFBd0I7QUFDOUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLE1BQU0sTUFBTSxHQUFHLElBQUksWUFBWSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQzVDO0FBQ0E7QUFDQSxRQUFRLE1BQU0sY0FBYyxHQUFHLElBQUksWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ25ELFFBQVEsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztBQUMxQztBQUNBLFFBQVEwUSxLQUFBQSxDQUFBQSxTQUFjLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUMxRCxRQUFRbFIsS0FBQUEsQ0FBQUEsT0FBVSxDQUFDLFdBQVcsRUFBRSxXQUFXLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUN6RDtBQUNBLFFBQVFzUSxjQUFhLENBQUMsTUFBTSxFQUFFLGNBQWMsQ0FBQyxDQUFDO0FBQzlDO0FBQ0EsUUFBUTlQLEtBQUFBLENBQUFBLFNBQWMsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0FBQ3BEO0FBQ0E7QUFDQSxRQUFRLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztBQUMxQixRQUFRLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztBQUMxQixRQUFRLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztBQUMxQixRQUFRLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztBQUMzQjtBQUNBO0FBQ0EsUUFBUSxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksY0FBYyxDQUFDO0FBQ3BDLFFBQVEsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLGNBQWMsQ0FBQztBQUNwQyxRQUFRLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxjQUFjLENBQUM7QUFDckMsUUFBUSxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksY0FBYyxDQUFDO0FBQ3JDO0FBQ0EsUUFBUSxPQUFPLE1BQU0sQ0FBQztBQUN0QixLQUFLO0FBQ0w7QUFDQSxJQUFJLDBCQUEwQixDQUFDLElBQUksVUFBVSxXQUFXLFVBQVUsS0FBSyxVQUFVLElBQUksd0JBQXdCO0FBQzdHLFFBQVEsTUFBTSxNQUFNLEdBQUcsSUFBSSxZQUFZLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDNUMsUUFBUTJRLEtBQWdCLENBQUEsV0FBQSxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztBQUNqRSxRQUFRLE9BQU8sTUFBTSxDQUFDO0FBQ3RCLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksc0JBQXNCLENBQUMsZUFBZSxVQUFVLE9BQU8sWUFBWSxLQUFLLFVBQVU7QUFDdEYsUUFBUSxNQUFNLEVBQUUsR0FBRyxlQUFlLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRzVDLEtBQXFCLENBQUEscUJBQUEsQ0FBQyxlQUFlLEVBQUUsT0FBTyxHQUFHNkMsS0FBQUEsQ0FBQUEsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2SixRQUFRLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztBQUNqQyxRQUFRLE9BQU8sQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDOUMsS0FBSztBQUNMO0FBQ0EsSUFBSSxLQUFLLGVBQWU7QUFDeEIsUUFBUSxPQUFPLElBQUksVUFBVSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO0FBQ3pFLEtBQUs7QUFDTCxDQUFBOztBQzNVQTtBQUNBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDZSxTQUFTLHdCQUF3QixDQUFDLFNBQVMsYUFBYSxlQUFlLDJCQUEyQjtBQUNqSCxJQUFJLE1BQU0sT0FBTyxHQUFHLDJCQUEyQixDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUN6SCxJQUFJLE1BQU0sTUFBTSxHQUFHLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsTUFBTSxFQUFFLE9BQU8sRUFBRSxlQUFlLENBQUMsQ0FBQztBQUN4SDtBQUNBLElBQUksTUFBTSxlQUFlLEdBQUcsa0JBQWtCLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDMUQsSUFBSXpRLEtBQVUsQ0FBQSxPQUFBLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxDQUFDLGVBQWUsRUFBRSxlQUFlLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0RTtBQUNBLElBQUksT0FBTyxNQUFNLENBQUM7QUFDbEIsQ0FBQztBQUNEO0FBQ08sU0FBUyxrQkFBa0IsQ0FBQyxTQUFTLHFCQUFxQjtBQUNqRSxJQUFJLE1BQU0sVUFBVSxHQUFHLFNBQVMsQ0FBQyxVQUFVLENBQUM7QUFDNUMsSUFBSSxNQUFNLE9BQU8sR0FBRywyQkFBMkIsQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLEtBQUssRUFBRSxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDekgsSUFBSSxNQUFNLGNBQWMsR0FBRyxpQkFBaUIsQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQzNFLElBQUksTUFBTSxvQkFBb0IsR0FBRyxpQkFBaUIsQ0FBQyxVQUFVLEVBQUV0SCxLQUFBQSxDQUFBQSxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0FBQ2xHLElBQUksTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsY0FBYyxHQUFHLE9BQU8sR0FBRyxDQUFDLENBQUMsR0FBRyxPQUFPLElBQUksb0JBQW9CLENBQUMsQ0FBQztBQUN6RyxJQUFJLE9BQU8sZUFBZSxDQUFDO0FBQzNCLENBQUM7QUFDRDtBQUNPLFNBQVMsK0JBQStCLENBQUMsU0FBUyw0QkFBNEI7QUFDckYsSUFBSSxNQUFNLENBQUMsR0FBRyx3QkFBd0IsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDeEQsSUFBSSxPQUFPaVIsS0FBQUEsQ0FBQUEsTUFBVyxDQUFDLEVBQUUsRUFBRTtBQUMzQixRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDckIsQ0FBQztBQUNEO0FBQ08sU0FBUywyQkFBMkIsQ0FBQyxVQUFVLGNBQWMsSUFBSSxVQUFVLEtBQUssVUFBVSxNQUFNLFVBQVUsT0FBTyxXQUFXLFFBQVEsVUFBVTtBQUNySixJQUFJLE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUM7QUFDbkMsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQ3pCO0FBQ0EsSUFBSSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO0FBQzVEO0FBQ0E7QUFDQTtBQUNBLElBQUksTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQztBQUM3RCxJQUFJLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxlQUFlLENBQUM7QUFDN0MsSUFBSSxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsZUFBZSxDQUFDO0FBQzdDLElBQUksTUFBTSxDQUFDLEdBQUczQyxLQUFVLENBQUEsVUFBQSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDN0MsSUFBSSxPQUFPLENBQUMsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBO0FBQ0EsTUFBTSxNQUFNLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVMsaUJBQWlCLENBQUMsVUFBVSxjQUFjLEdBQUcsVUFBVTtBQUNoRTtBQUNBLElBQUksTUFBTSxHQUFHLEdBQUdjLEtBQUFBLENBQUFBLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM0SSxLQUFBQSxDQUFBQSxxQkFBcUIsRUFBRUEsS0FBQUEsQ0FBQUEscUJBQXFCLENBQUMsQ0FBQztBQUM5RTtBQUNBLElBQUksTUFBTSxJQUFJLEdBQUcsSUFBSWhZLEtBQUFBLENBQUFBLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDekQsSUFBSSxNQUFNLElBQUksR0FBRyxJQUFJQSxLQUFBQSxDQUFBQSxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ3pEO0FBQ0EsSUFBSSxNQUFNLEVBQUUsR0FBRyxVQUFVLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDakQsSUFBSSxNQUFNLEVBQUUsR0FBRyxVQUFVLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDakQ7QUFDQSxJQUFJLE1BQU0sRUFBRSxHQUFHK0csS0FBQUEsQ0FBQUEsa0JBQWtCLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ25ELElBQUksTUFBTSxFQUFFLEdBQUdBLEtBQUFBLENBQUFBLGtCQUFrQixDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNuRDtBQUNBLElBQUksTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzVCLElBQUksTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzVCLElBQUksTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzVCLElBQUksTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzVCO0FBQ0EsSUFBSSxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxLQUFLLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDL0U7QUFDQSxJQUFJLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDO0FBQ3RDLENBQUM7QUFDRDtBQUNBLFNBQVMsa0JBQWtCLENBQUMsVUFBVSxjQUFjLElBQUksVUFBVSxHQUFHLFVBQVUsT0FBTyxVQUFVLGVBQWUsWUFBWTtBQUMzSDtBQUNBO0FBQ0EsSUFBSSxNQUFNLElBQUksR0FBRyxJQUFJL0csS0FBTSxDQUFBLE1BQUEsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzdELElBQUksTUFBTSxJQUFJLEdBQUcsSUFBSUEsS0FBTSxDQUFBLE1BQUEsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzdEO0FBQ0EsSUFBSSxNQUFNLEVBQUUsR0FBRyxVQUFVLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3RELElBQUksTUFBTSxFQUFFLEdBQUcsVUFBVSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMs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Q04sQ0FBQTs7QUN0SkE7QUFDQTtBQTBCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO0FBQzNCLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU0sU0FBUyxDQUFDO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksV0FBVyxDQUFDLE9BQU8sV0FBVyxPQUFPLFdBQVcsUUFBUSxXQUFXLFFBQVEsV0FBVyxpQkFBaUIsa0JBQWtCLFVBQVUsNkJB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ZSxDQUFDLElBQUlBLEtBQUFBLENBQUFBLEtBQUssQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztBQUNqRTtBQUNBLFFBQVEsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDNUQsUUFBUSxJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUM1RCxRQUFRLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzdELFFBQVEsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDN0Q7QUFDQTtBQUNBO0FBQ0EsUUFBUSxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUMxQyxRQUFRLE1BQU0sTUFBTSxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsR0FBRyxDQUFDO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxLQUFLLE9BQU8sR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3ZFO0FBQ0EsUUFBUSxNQUFNLGNBQWMsR0FBRyxDQUFDLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxLQUFLLGFBQWE7QUFDbEcsWUFBWSxNQUFNLEVBQUUsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ3JDLFlBQVksTUFBTSxFQUFFLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUNyQztBQUNBLFlBQVksTUFBTSxDQUFDLEdBQUcsSUFBSUEsS0FBQUEsQ0FBQUEsS0FBSyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUN4QyxZQUFZLE1BQU0sQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2RDtBQUNBO0FBQ0EsWUFBWSxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLEdBQUcsR0FBRyxFQUFFLEtBQUssR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLElBQUksRUFBRSxHQUFHLEdBQUcsS0FBSyxDQUFDLENBQUM7QUFDdEY7QUFDQSxZQUFZLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQztBQUN2QyxZQUFZLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQztBQUN2QyxZQUFZLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztBQUN6QyxZQUFZLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztBQUN6QztBQUNBLFlBQVksSUFBSSxLQUFLLEdBQUcsYUFBYSxJQUFJLEdBQUcsR0FBRyxNQUFNLEVBQUU7QUFDdkQsZ0JBQWdCLGNBQWMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsS0FBSyxHQUFHLENBQUMsQ0FBQyxD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QUFDQTtBQUNBLFFBQVEsTUFBTSxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsU0FBUyxDQUFDLENBQUMsQ0FBQyxVQUFVO0FBQzlCLFlBQVksTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLElBQUksR0FBRyxJQUFJLEdBQUcsRUFBRSxHQUFHLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDLENBQUM7QUFDbkgsWUFBWSxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3RELFNBQVM7QUFDVDtBQUNBLFFBQVEsU0FBUyxJQUFJLENBQUMsQ0FBQyxVQUFVLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFO0FBQzdFLFFBQVEsU0FBUyxJQUFJLENBQUMsQ0FBQyxVQUFVLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFO0FBQzdFLFFBQVEsU0FBUyxJQUFJLENBQUMsQ0FBQyxVQUFVLEVBQUUsT0FBTyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7QUFDOUQ7QUFDQTtBQUNBLFFBQVEsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FB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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNLEdBQUcsU0FBUyxNQUFNLENBQUM7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLFdBQVcsQ0FBQyxPQUFPLGNBQWM7QUFDckMsUUFBUWlCLEtBQUFBLENBQUFBLG9CQUFvQixDQUFDLElB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LElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsQ0FBQyxFQUFFLElBQUksWUFBWSxRQUFRLENBQUMsQ0FBQyxDQUFDO0FBQ2hHLFNBQVM7QUFDVCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksRUFBRSxDQUFDLElBQUksWUFBWSxRQUFRLE9BQU8sUUFBUSxhQUFhO0FBQzNELFFBQVEsSUFBSSxRQUFRLEtBQUssU0FBUyxFQUFFO0FBQ3BDLFlBQVksT0FBTyxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQztBQUM1QyxTQUFTO0FBQ1Q7QUFDQSxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFO0FBQ3RDLFlBQVksUUFBUSxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDbEMsU0FBUztBQUNULFFBQVEsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsd0JBQXdCLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQztBQUMxRjtBQUNBLFFBQVEsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxtQkFBbUIsSUFBSSxFQUFFLENBQUM7QUFDbEUsUUFBUSxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUM5RSxRQUFRLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztBQUMvRDtBQUNBLFFBQVEsS0FBSyxNQUFNLEtBQUssSUFBSSxpQkFBaUIsQ0FBQyxTQUFTLEVBQUU7QUFDekQsWUFBWSxJQUFJLENBQUMsRUFBRSxFQUFFLEtBQUssUUFBUSxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUN0RSxTQUFTO0FBQ1Q7QUFDQSxRQUFRLE9BQU8sSUFBSSxDQUFDO0FBQ3BCLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksSUFBSSxDQUFDLElBQUksWUFBWSxRQUFRLE9BQU8sUUFBUSw4QkFBOEI7QUFDOUU7QUFDQSxRQUFRLElBQUksUUFBUSxLQUFLLFNBQVMsRUFBRTtBQUNwQyxZQUFZLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDOUMsU0FBUztBQUNUO0FBQ0EsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRTtBQUN0QyxZQUFZLFFBQVEsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ2xDLFNBQVM7QUFDVCxRQUFRLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDMUY7QUFDQSxRQUFRLEtBQUssTUFBTSxLQUFLLElBQUksaUJBQWlCLENBQUMsU0FBUyxFQUFFO0FBQ3pELFlBQVksSUFBSSxDQUFDLElBQUksRUFBRSxLQUFLLFFBQVEsaUJBQWlCLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDeEUsU0FBUztBQUNUO0FBQ0EsUUFBUSxPQUFPLElBQUksQ0FBQztBQUNwQixLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksR0FBRyxDQUFDLElBQUksWUFBWSxRQUFRLE9BQU8sUUFBUSxhQUFhO0FBQzVELFFBQVEsSUFBSSxRQUFRLEtBQUssU0FBUyxFQUFFO0FBQ3BDLFlBQVksT0FBTyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQztBQUM3QyxTQUFTO0FBQ1Q7QUFDQSxRQUFRLFFBQVEsR0FBRyxJQUFJLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLFFBQVEsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7QUFDNUUsUUFBUSxNQUFNLG1CQUFtQixHQUFHLENBQUMsS0FBSyxlQUFlLEtBQUssa0JBQWtCO0FBQ2hGLFlBQVksSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLEtBQUssQ0FBQyxJQUFJLEVBQUU7QUFDM0MsZ0JBQWdCLE9BQU8sS0FBSyxDQUFDO0FBQzdCLGFBQWE7QUFDYjtBQUNBO0FBQ0EsWUFBWSxLQUFLLE1BQU0sS0FBSyxJQUFJLEtBQUssRUFBRTtBQUN2QyxnQkFBZ0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsT0FBTyxLQUFLLENBQUM7QUFDcEQsYUFBYTtBQUNiLFlBQVksT0FBTyxJQUFJLENBQUM7QUFDeEIsU0FBUyxDQUFDO0FBQ1Y7QUFDQSxRQUFRLE1BQU0sd0JBQXdCLEdBQUcsQ0FBQyxTQUFTLGlCQUFpQjtBQUNwRSxZQUFZLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO0FBQ3ZELGdCQUFnQixNQUFNLGlCQUFpQixHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2RCxnQkFBZ0IsSUFBSSxpQkFBaUIsQ0FBQyxRQUFRLEtBQUssUUFBUSxJQUFJLG1CQUFtQixDQUFDLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsRUFBRTtBQUN4SCxvQkFBb0IsS0FBSyxNQUFNLEtBQUssSUFBSSxpQkFBaUIsQ0FBQyxTQUFTLEVBQUU7QUFDckUsd0JBQXdCLElBQUksQ0FBQyxHQUFHLEVBQUUsS0FBSyxRQUFRLGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ25GLHFCQUFxQjtBQUNyQixvQkFBb0IsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDM0Msb0JBQW9CLE9BQU8sSUFBSSxDQUFDO0FBQ2hDLGlCQUFpQjtBQUNqQixhQUFhO0FBQ2IsU0FBUyxDQUFDO0FBQ1Y7QUFDQSxRQUFRLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsR0FBRyxTQUFTLENBQUM7QUFDekcsUUFBUSxJQUFJLGtCQUFrQixFQUFFO0FBQ2hDLFlBQVksd0JBQXdCLENBQUMsa0JBQWtCLENBQUMsQ0FBQztBQUN6RCxTQUFTO0FBQ1Q7QUFDQSxRQUFRLE9BQU8sSUFBSSxDQUFDO0FBQ3BCLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxxQkFBcUIsQ0FBQyxRQUFRLHVDQUF1QyxPQUFPLCtCQUErQjtBQUMvRztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFO0FBQ3pCLFlBQVksT0FBTyxFQUFFLENBQUM7QUFDdEIsU0FBUztBQUNUO0FBQ0EsUUFBUSxJQUFJLE9BQU8sS0FBSyxTQUFTLElBQUksUUFBUSxLQUFLLFNBQVMsSUFBSSxFQUFFLFFBQVEsWUFBWUEsS0FBSyxDQUFBLEtBQUEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRTtBQUN6SCxZQUFZLE9BQU8sSUFBSSxRQUFRLFNBQVMsQ0FBQztBQUN6QyxZQUFZLFFBQVEsR0FBRyxTQUFTLENBQUM7QUFDakMsU0FBUztBQUNUO0FBQ0EsUUFBUSxPQUFPLEdBQUcsT0FBTyxJQUFJLEVBQUUsQ0FBQztBQUNoQyxRQUFRLFFBQVEsR0FBRyxRQUFRLElBQUksRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQztBQUNqSDtBQUNBLFFBQVEsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixDQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQ25GLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxtQkFBbUIsQ0FBQyxRQUFRLFVBQVUsVUFBVSx5RkFBeUY7QUFDN0ksUUFBUSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0FBQ3BFLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLGdCQUFnQixDQUFDLEtBQUssc0JBQXNCO0FBQ2hELFFBQVEsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDO0FBQ2pELFFBQVEsSUFBSSxJQUFJLEtBQUssT0FBTyxJQUFJLElBQUksS0FBSyxVQUFVLEVBQUU7QUFDckQsWUFBWTJSLEtBQUFBLENBQUFBLFFBQVEsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLGdGQUFnRixDQUFDLENBQUMsQ0FBQztBQUNoSCxTQUFTO0FBQ1Q7QUFDQSxRQUFRLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQzNSLEtBQUssQ0FBQSxLQUFBLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDckUsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLFFBQVEsQ0FBQyxLQUFLLHNDQUFzQyxPQUFPLDBDQUEwQztBQUN6RyxRQUFRLE9BQU8sR0FBR1UsS0FBTSxDQUFBLE1BQUEsQ0FBQyxFQUFFLEVBQUUsQ0FBQyx3QkFBd0IsRUFBRSxJQUFJLENBQUMseUJBQXlCLEVBQUUsZUFBZSxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQzFJO0FBQ0EsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksS0FBSyxLQUFLO0FBQ25DLFlBQVksT0FBTyxDQUFDLHdCQUF3QixLQUFLLElBQUksQ0FBQyx5QkFBeUI7QUFDL0UsWUFBWSxPQUFPLENBQUMsZUFBZSxLQUFLLElBQUksQ0FBQyxnQkFBZ0IsS0FBSyxJQUFJLENBQUMsS0FBSyxJQUFJLEtBQUssRUFBRTtBQUN2RixZQUFZLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQzVDLFlBQVksT0FBTyxJQUFJLENBQUM7QUFDeEIsU0FBUyxNQUFNO0FBQ2YsWUFBWSxJQUFJLENBQUMseUJBQXlCLEdBQUcsT0FBTyxDQUFDLHdCQUF3QixDQUFDO0FBQzlFLFlBQVksSUFBSSxDQUFDLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUM7QUFDNUQsWUFBWSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQ3JELFNBQVM7QUFDVCxLQUFLO0FBQ0w7QUFDQSxJQUFJLFlBQVksQ0FBQyxHQUFHLGtCQUFrQjtBQUN0QyxRQUFRLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDdEMsUUFBUSxJQUFJLEdBQUcsSUFBSSxJQUFJLEVBQUU7QUFDekIsWUFBWSxNQUFNLElBQUksS0FBSyxDQUFDLENBQUMsbUJBQW1CLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDMUQsU0FBUztBQUNUO0FBQ0EsUUFBUSxPQUFPLEdBQUcsQ0FBQztBQUNuQixLQUFLO0FBQ0w7QUFDQSxJQUFJLFlBQVksQ0FBQyxLQUFLLHVDQUF1QyxPQUFPLDBDQUEwQztBQUM5RyxRQUFRLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRTtBQUN4QixZQUFZLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDOUMsWUFBWSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBQ2pDLFlBQVksSUFBSSxDQUFDLEtBQUssSUFBSSxTQUFTLE1BQU0sQ0FBQztBQUMxQyxTQUFTO0FBQ1Q7QUFDQSxRQUFRLElBQUksS0FBSyxFQUFFO0FBQ25CLFlBQVksSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxJQUFJLEVBQUUsT0FBTyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0FBQ3hELFlBQVksSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDbkU7QUFDQSxZQUFZLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFO0FBQzNDLGdCQUFnQixJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUMxQyxhQUFhLE1BQU07QUFDbkIsZ0JBQWdCLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzNDLGFBQWE7QUFDYixTQUFTO0FBQ1QsUUFBUSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7QUFDOUIsUUFBUSxPQUFPLElBQUksQ0FBQztBQUNwQixLQUFLO0FBQ0w7QUFDQSxJQUFJLG1CQUFtQixHQUFHO0FBQzFCLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUU7QUFDekIsWUFBWSxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksS0FBSyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztBQUM3QyxZQUFZLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ25FLFlBQVksSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUsQ0FBQztBQUNuQyxTQUFTO0FBQ1QsS0FBSztBQUNMO0FBQ0EsSUFBSSxVQUFVLENBQUMsS0FBSyxnQ0FBZ0MsT0FBTyxvQ0FBb0M7QUFDL0YsUUFBUSxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRTtBQUN2QyxZQUFZLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDdEUsWUFBWSxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsRUFBRTRRLEtBQUFBLENBQUFBLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUMzRixZQUFZTixLQUFBQSxDQUFBQSxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsS0FBSyxVQUFVLElBQUksY0FBYztBQUMvRCxnQkFBZ0IsSUFBSSxLQUFLLEVBQUU7QUFDM0Isb0JBQW9CLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSVUsZ0JBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ3JELGlCQUFpQixNQUFNLElBQUksSUFBSSxFQUFFO0FBQ2pDLG9CQUFvQixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztBQUNwRCxpQkFBaUI7QUFDakIsYUFBYSxDQUFDLENBQUM7QUFDZixTQUFTLE1BQU0sSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUU7QUFDOUMsWUFBWSxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztBQUM3QyxTQUFTO0FBQ1QsS0FBSztBQUNMO0FBQ0EsSUFBSSxXQUFXLENBQUMsS0FBSyx1QkFBdUIsT0FBTyxvQ0FBb0M7QUFDdkYsUUFBUSxJQUFJO0FBQ1osWUFBWSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFO0FBQzVDLGdCQUFnQixJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ25DLGFBQWE7QUFDYixTQUFTLENBQUMsT0FBTyxDQUFDLEVBQUU7QUFDcEIsWUFBWUMsS0FBUSxDQUFBLFFBQUE7QUFDcEIsZ0JBQWdCLENBQUMsOEJBQThCLEVBQUUsQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxxQ0FBcUMsQ0FBQztBQUNqSCxhQUFhLENBQUM7QUFDZCxZQUFZLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQzlDLFNBQVM7QUFDVCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxRQUFRLHdCQUF3QjtBQUNwQyxRQUFRLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRTtBQUN4QixZQUFZLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUsQ0FBQztBQUMxQyxTQUFTO0FBQ1QsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksYUFBYSxZQUFZO0FBQzdCLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUU7QUFDekIsWUFBWUEsS0FBUSxDQUFBLFFBQUEsQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO0FBQzVELFlBQVksT0FBTyxLQUFLLENBQUM7QUFDekIsU0FBUztBQUNULFFBQVEsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO0FBQ25DLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxTQUFTLENBQUMsRUFBRSxVQUFVLE1BQU0sNkJBQTZCO0FBQzdELFFBQVEsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7QUFDbkMsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDekMsUUFBUSxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDbEMsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxjQUFjLENBQUMsRUFBRSxtQkFBbUI7QUFDeEMsUUFBUSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDbkUsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxjQUFjLFlBQVk7QUFDOUIsUUFBUSxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDO0FBQy9ELFFBQVEsS0FBSyxNQUFNLEVBQUUsSUFBSSxPQUFPLEVBQUU7QUFDbEMsWUFBWSxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDdkMsWUFBWSxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0FBQ3hDLFlBQVksS0FBSyxNQUFNLENBQUMsSUFBSSxLQUFLLEVBQUU7QUFDbkMsZ0JBQWdCLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QyxnQkFBZ0IsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLEtBQUssUUFBUSxJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssU0FBUyxDQUFDLEVBQUUsT0FBTyxLQUFLLENBQUM7QUFDekYsYUFBYTtBQUNiLFNBQVM7QUFDVCxRQUFRLE9BQU8sSUFBSSxDQUFDO0FBQ3BCLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLGFBQWEsQ0FBQyxJQUFJLFVBQVUsVUFBVSxPQUFPLFFBQVEsWUFBWTtBQUNyRSxRQUFRLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO0FBQ25DLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLFVBQVUsRUFBRSxRQUFRLENBQUMsQ0FBQztBQUM3RCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxZQUFZLENBQUMsRUFBRSxnQkFBZ0I7QUFDbkMsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNwQyxRQUFRLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztBQUM5QixRQUFRLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNsQyxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxTQUFTLENBQUMsRUFBRSxtQkFBbUI7QUFDbkMsUUFBUSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3hDLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLFFBQVEsQ0FBQyxFQUFFO0FBQ2YsYUFBYSxLQUFLO0FBQ2xCLGFBQWEsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxFQUFFLEdBQUcsR0FBRyxLQUFLLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxPQUFPLENBQUMsK0JBQStCLEVBQUUsRUFBRTtBQUMxRyxRQUFRLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO0FBQ25DLFFBQVEsTUFBTSxPQUFPLEdBQUcsQ0FBQyxDQUFDO0FBQzFCO0FBQ0EsUUFBUSxJQUFJLEtBQUssWUFBWTVSLEtBQU0sQ0FBQSxNQUFBLENBQUMsZ0JBQWdCLEtBQUtBLEtBQUFBLENBQUFBLE1BQU0sQ0FBQyxXQUFXLElBQUksS0FBSyxZQUFZQSxZQUFNLENBQUMsV0FBVyxDQUFDLEVBQUU7QUFDckgsWUFBWSxNQUFNLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsR0FBR29ELGNBQU8sQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDdEUsWUFBWSxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLEVBQUUsSUFBSXFPLEtBQUFBLENBQUFBLFNBQVMsQ0FBQyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsRUFBRSxJQUFJLENBQUMsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7QUFDekksU0FBUyxNQUFNLElBQUksS0FBSyxDQUFDLEtBQUssS0FBSyxTQUFTLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxTQUFTLEVBQUU7QUFDNUUsWUFBWSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUlFLEtBQVUsQ0FBQSxVQUFBLENBQUMsSUFBSSxLQUFLO0FBQzlDLGdCQUFnQixzSEFBc0g7QUFDdEksZ0JBQWdCLDZGQUE2RixDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pILFNBQVMsTUFBTTtBQUNmLFlBQVksTUFBTSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsR0FBRyxLQUFLLENBQUM7QUFDMUMsWUFBWSxNQUFNLFNBQVMsS0FBSyxLQUFLLDRCQUE0QixDQUFDO0FBQ2xFLFlBQVksTUFBTSxJQUFJLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQztBQUN4QztBQUNBLFlBQVksSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFO0FBQ3BDLGdCQUFnQixJQUFJLEVBQUUsSUFBSUYsS0FBUyxDQUFBLFNBQUEsQ0FBQyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsRUFBRSxJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUMxRSxnQkFBZ0IsVUFBVTtBQUMxQixnQkFBZ0IsUUFBUTtBQUN4QixnQkFBZ0IsUUFBUTtBQUN4QixnQkFBZ0IsT0FBTztBQUN2QixnQkFBZ0IsR0FBRztBQUNuQixnQkFBZ0IsT0FBTztBQUN2QixnQkFBZ0IsU0FBUztBQUN6QixhQUFhLENBQUMsQ0FBQztBQUNmO0FBQ0EsWUFBWSxJQUFJLFNBQVMsQ0FBQyxLQUFLLEVBQUU7QUFDakMsZ0JBQWdCLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQzFDLGFBQWE7QUFDYixTQUFTO0FBQ1QsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLFdBQVcsQ0FBQyxFQUFFO0FBQ2xCLFFBQVEsS0FBSyw0SUFBNEk7QUFDeko7QUFDQSxRQUFRLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3RELFFBQVEsSUFBSSxDQUFDLGFBQWEsRUFBRTtBQUM1QixZQUFZLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSUUsS0FBVSxDQUFBLFVBQUEsQ0FBQyxJQUFJLEtBQUs7QUFDOUMsZ0JBQWdCLG1HQUFtRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZILFlBQVksT0FBTztBQUNuQixTQUFTO0FBQ1QsUUFBUSxNQUFNLFNBQVMsR0FBRyxDQUFDLEtBQUssWUFBWTNSLEtBQU0sQ0FBQSxNQUFBLENBQUMsZ0JBQWdCLEtBQUtBLEtBQU0sQ0FBQSxNQUFBLENBQUMsV0FBVyxJQUFJLEtBQUssWUFBWUEsS0FBTSxDQUFBLE1BQUEsQ0FBQyxXQUFXLENBQUMsSUFBSW9ELEtBQUFBLENBQUFBLFFBQU8sQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLEdBQUcsS0FBSyxDQUFDO0FBQzFLLFFBQVEsTUFBTSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsR0FBRyxTQUFTLENBQUM7QUFDMUM7QUFDQSxRQUFRLE1BQU0sSUFBSSxJQUFJLENBQUMsU0FBUyxPQUFPLElBQUksaUNBQWlDLENBQUM7QUFDN0U7QUFDQSxRQUFRLElBQUksS0FBSyxLQUFLLFNBQVMsSUFBSSxNQUFNLEtBQUssU0FBUyxFQUFFO0FBQ3pELFlBQVksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJdU8sS0FBVSxDQUFBLFVBQUEsQ0FBQyxJQUFJLEtBQUs7QUFDOUMsZ0JBQWdCLHlIQUF5SDtBQUN6SSxnQkFBZ0IsNkZBQTZGLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakgsWUFBWSxPQUFPO0FBQ25CLFNBQVM7QUFDVDtBQUNBLFFBQVEsSUFBSSxLQUFLLEtBQUssYUFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksTUFBTSxLQUFLLGFBQWEsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFO0FBQ3hGLFlBQVksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJQSxLQUFVLENBQUEsVUFBQSxDQUFDLElBQUksS0FBSztBQUM5QyxnQkFBZ0IsQ0FBQywyQ0FBMkMsRUFBRSxLQUFLLENBQUMsRUFBRSxFQUFFLE1BQU0sQ0FBQztBQUMvRTtBQUNBLGlCQUFpQixFQUFFLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxhQUFhLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoRixZQUFZLE9BQU87QUFDbkIsU0FBUztBQUNUO0FBQ0EsUUFBUSxNQUFNLElBQUksR0FBRyxFQUFFLEtBQUssWUFBWTNSLEtBQUFBLENBQUFBLE1BQU0sQ0FBQyxnQkFBZ0IsS0FBS0EsWUFBTSxDQUFDLFdBQVcsSUFBSSxLQUFLLFlBQVlBLFlBQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO0FBQ2hJLFFBQVEsYUFBYSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQy9DO0FBQ0EsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxFQUFFLEVBQUUsYUFBYSxDQUFDLENBQUM7QUFDbEQsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLFFBQVEsQ0FBQyxFQUFFLG1CQUFtQjtBQUNsQyxRQUFRLElBQUksQ0FBQyxFQUFFLEVBQUU7QUFDakIsWUFBWSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUkyUixLQUFVLENBQUEsVUFBQSxDQUFDLElBQUksS0FBSyxDQUFDLDJCQUEyQixDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzlFLFlBQVksT0FBTyxLQUFLLENBQUM7QUFDekIsU0FBUztBQUNUO0FBQ0EsUUFBUSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUN6QyxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLFdBQVcsQ0FBQyxFQUFFLFVBQVU7QUFDNUIsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNuQyxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxTQUFTLENBQUMsR0FBRyxVQUFVLFFBQVEsWUFBWTtBQUMvQyxRQUFRSCxjQUFRLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLEVBQUVELEtBQVksQ0FBQSxZQUFBLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxLQUFLO0FBQy9GLFlBQVksUUFBUSxDQUFDLEdBQUcsRUFBRSxHQUFHLFlBQVl2UixZQUFNLENBQUMsZ0JBQWdCLEdBQUdvRCxLQUFPLENBQUEsUUFBQSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUNwRyxTQUFTLENBQUMsQ0FBQztBQUNYLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLFVBQVUsa0JBQWtCO0FBQ2hDLFFBQVEsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO0FBQ3ZDLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLFFBQVEsQ0FBQyxLQUFLLDZDQUE2QyxRQUFRLGlCQUFpQjtBQUN4RixRQUFRLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO0FBQ25DLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQzdDLFFBQVEsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ2xDLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLFNBQVMsQ0FBQyxFQUFFLFVBQVUsUUFBUSxpQkFBaUI7QUFDbkQsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDM0MsUUFBUSxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDbEMsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLFdBQVcsQ0FBQyxFQUFFLGdCQUFnQjtBQUNsQyxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ25DLFFBQVEsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ2xDLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxRQUFRLENBQUMsRUFBRSx1QkFBdUI7QUFDdEMsUUFBUSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3ZDLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLGlCQUFpQixDQUFDLE9BQU8sVUFBVSxPQUFPLFVBQVUsT0FBTyxnQkFBZ0I7QUFDL0UsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDaEUsUUFBUSxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDbEMsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxTQUFTLENBQUMsT0FBTyxVQUFVLE1BQU0seUJBQXlCLE9BQU8sdUJBQXVCLEVBQUUsUUFBUTtBQUN0RyxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDdkQsUUFBUSxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDbEMsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksU0FBUyxDQUFDLE9BQU8sZ0NBQWdDO0FBQ3JELFFBQVEsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUM3QyxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksZ0JBQWdCLENBQUMsT0FBTyxVQUFVLElBQUksVUFBVSxLQUFLLE9BQU8sT0FBTyx1QkFBdUIsRUFBRSxRQUFRO0FBQ3hHLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztBQUNuRSxRQUFRLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNsQyxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLGdCQUFnQixDQUFDLE9BQU8sVUFBVSxJQUFJLDhFQUE4RTtBQUN4SCxRQUFRLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDMUQsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLGlCQUFpQixDQUFDLE9BQU8sVUFBVSxJQUFJLFVBQVUsS0FBSyxPQUFPLE9BQU8sdUJBQXVCLEVBQUUsUUFBUTtBQUN6RyxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDcEUsUUFBUSxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDbEMsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxpQkFBaUIsQ0FBQyxPQUFPLFVBQVUsSUFBSSw4Q0FBOEM7QUFDekYsUUFBUSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQzNELEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxRQUFRLENBQUMsS0FBSyxzQkFBc0IsT0FBTyx1QkFBdUIsRUFBRSxRQUFRO0FBQ2hGLFFBQVEsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7QUFDbkMsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDNUMsUUFBUSxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDbEMsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLFFBQVEsdUJBQXVCO0FBQ25DLFFBQVEsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO0FBQ3JDLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLFVBQVUsQ0FBQyxPQUFPLDhCQUE4QjtBQUNwRCxRQUFRLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO0FBQ25DLFFBQVEsSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxlQUFlLEVBQUU7QUFDbkUsWUFBWSxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQixFQUFFLENBQUM7QUFDOUMsU0FBUyxNQUFNO0FBQ2YsWUFBWSxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUMzQyxTQUFTO0FBQ1QsUUFBUSxJQUFJLENBQUMsOEJBQThCLEdBQUcsQ0FBQyxRQUFRLENBQUM7QUFDeEQsUUFBUSxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDbEMsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLFVBQVUsMEJBQTBCO0FBQ3hDLFFBQVEsT0FBTyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBQzNELEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLE1BQU0sQ0FBQyxHQUFHLDBCQUEwQjtBQUN4QyxRQUFRLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO0FBQ25DLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDL0IsUUFBUSxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDbEMsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLE1BQU0sc0JBQXNCO0FBQ2hDLFFBQVEsT0FBTyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBQ3ZELEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksZ0JBQWdCLENBQUMsTUFBTSxzQkFBc0I7QUFDakQsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ3ZELFFBQVEsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQ2MsS0FBQUEsQ0FBQUEsTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDekYsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLGVBQWUsQ0FBQyxPQUFPLGtFQUFrRSxLQUFLLGdCQUFnQjtBQUNsSCxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztBQUNuRCxRQUFRLE9BQU8sSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBQzlCLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLGtCQUFrQixDQUFDLE9BQU8sbUVBQW1FLEdBQUcsaUJBQWlCO0FBQ3JILFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDcEQsUUFBUSxPQUFPLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztBQUM5QixLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxlQUFlLENBQUMsT0FBTyx1RUFBdUU7QUFDbEcsUUFBUSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ25ELEtBQUs7QUFDTDtBQUNBLElBQUksMEJBQTBCLEdBQUc7QUFDakMsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxPQUFPO0FBQ3JDO0FBQ0EsUUFBUSxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLHFCQUFxQixFQUFFLENBQUMsS0FBSyxJQUFJLEdBQUcsQ0FBQztBQUMzRSxRQUFRLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxNQUFNLElBQUksR0FBRyxDQUFDO0FBQzdFO0FBQ0EsUUFBUSxJQUFJLGVBQWUsQ0FBQztBQUM1QixRQUFRLElBQUksbUJBQW1CLENBQUM7QUFDaEMsUUFBUSxJQUFJLG9CQUFvQixDQUFDO0FBQ2pDLFFBQVEsSUFBSSxFQUFFLGFBQWEsSUFBSSxDQUFDLFVBQVUsQ0FBQztBQUMzQyxRQUFRLE9BQU8sRUFBRSxLQUFLLENBQUMsbUJBQW1CLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxFQUFFO0FBQ3RFLFlBQVksTUFBTSxlQUFlLEdBQUdsRSxLQUFNLENBQUEsTUFBQSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUMxRSxZQUFZLElBQUksZUFBZSxJQUFJLGVBQWUsS0FBSyxNQUFNLEVBQUU7QUFDL0QsZ0JBQWdCLGVBQWUsR0FBRyxlQUFlLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQzNGLGdCQUFnQixJQUFJLGVBQWUsQ0FBQyxDQUFDLENBQUMsSUFBSSxlQUFlLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxJQUFJLGVBQWUsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLEVBQUUsbUJBQW1CLEdBQUcsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzdJLGdCQUFnQixJQUFJLGVBQWUsQ0FBQyxDQUFDLENBQUMsSUFBSSxlQUFlLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxJQUFJLGVBQWUsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLEVBQUUsb0JBQW9CLEdBQUcsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzlJLGFBQWE7QUFDYixZQUFZLEVBQUUsR0FBRyxFQUFFLENBQUMsYUFBYSxDQUFDO0FBQ2xDLFNBQVM7QUFDVDtBQUNBLFFBQVEsSUFBSSxDQUFDLGVBQWUsR0FBRyxtQkFBbUIsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssR0FBRyxtQkFBbUIsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUNuRyxRQUFRLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxvQkFBb0IsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxvQkFBb0IsQ0FBQyxHQUFHLE1BQU0sQ0FBQztBQUN4RyxLQUFLO0FBQ0w7QUFDQSxJQUFJLGlCQUFpQixTQUFTO0FBQzlCLFFBQVEsTUFBTSxhQUFhLEdBQUdBLEtBQU0sQ0FBQSxNQUFBLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsZ0JBQWdCLENBQUMsa0JBQWtCLENBQUMsQ0FBQztBQUNuSCxRQUFRLElBQUksYUFBYSxLQUFLLG9CQUFvQixFQUFFO0FBQ3BELFlBQVk0UixLQUFBQSxDQUFBQSxRQUFRLENBQUMsdURBQXVEO0FBQzVFLGdCQUFnQixnRUFBZ0U7QUFDaEYsZ0JBQWdCLCtEQUErRDtBQUMvRSxnQkFBZ0IsOENBQThDLENBQUMsQ0FBQztBQUNoRSxTQUFTO0FBQ1QsS0FBSztBQUNMO0FBQ0EsSUFBSSxlQUFlLEdBQUc7QUFDdEIsUUFBUSxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO0FBQzFDLFFBQVEsU0FBUyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLENBQUM7QUFDaEQ7QUFDQSxRQUFRLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixHQUFHNkwsUUFBVSxDQUFDLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxTQUFTLENBQUMsQ0FBQztBQUMxRyxRQUFRLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxVQUFVLEdBQUcsUUFBUSxDQUFDO0FBQ3JELFFBQVEsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7QUFDakM7QUFDQSxRQUFRLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsR0FBR0EsUUFBVSxDQUFDLEtBQUssRUFBRSwyQkFBMkIsRUFBRSxTQUFTLENBQUMsQ0FBQztBQUNsSCxRQUFRLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRTtBQUMvQixZQUFZLGVBQWUsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLHNCQUFzQixDQUFDLENBQUM7QUFDbEUsU0FBUztBQUNUO0FBQ0EsUUFBUSxJQUFJLENBQUMsT0FBTyxHQUFHQSxRQUFVLENBQUMsUUFBUSxFQUFFLGlCQUFpQixFQUFFLGVBQWUsQ0FBQyxDQUFDO0FBQ2hGO0FBQ0EsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQixDQUFDLGtCQUFrQixFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDcEY7QUFDQSxRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsc0JBQXNCLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQzVGLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsVUFBVSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ25ELFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztBQUNoRixRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQztBQUNwRDtBQUNBLFFBQVEsSUFBSSxDQUFDLDBCQUEwQixFQUFFLENBQUM7QUFDMUMsUUFBUSxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7QUFDeEU7QUFDQSxRQUFRLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixHQUFHQSxRQUFVLENBQUMsS0FBSyxFQUFFLDRCQUE0QixFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQ3JILFFBQVEsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixHQUFHLEVBQUUsQ0FBQztBQUN0RCxRQUFRLENBQUMsVUFBVSxFQUFFLFdBQVcsRUFBRSxhQUFhLEVBQUUsY0FBYyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsWUFBWSxLQUFLO0FBQzNGLFlBQVksU0FBUyxDQUFDLFlBQVksQ0FBQyxHQUFHQSxRQUFVLENBQUMsS0FBSyxFQUFFLENBQUMsY0FBYyxFQUFFLFlBQVksQ0FBQyxDQUFDLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztBQUMzRyxTQUFTLENBQUMsQ0FBQztBQUNYO0FBQ0E7QUFDQSxRQUFRLElBQUksQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDN0UsS0FBSztBQUNMO0FBQ0EsSUFBSSxhQUFhLENBQUMsS0FBSyxVQUFVLE1BQU0sVUFBVTtBQUNqRCxRQUFRLE1BQU0sVUFBVSxHQUFHcmEsS0FBQUEsQ0FBQUEsUUFBTyxDQUFDLGdCQUFnQixJQUFJLENBQUMsQ0FBQztBQUN6RDtBQUNBO0FBQ0EsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssR0FBRyxVQUFVLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUMzRCxRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQzdEO0FBQ0E7QUFDQSxRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2hELFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDbEQsS0FBSztBQUNMO0FBQ0EsSUFBSSxVQUFVLENBQUMsTUFBTSxVQUFVO0FBQy9CLFFBQVEsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDbkMsS0FBSztBQUNMO0FBQ0EsSUFBSSxhQUFhLENBQUMsTUFBTSxVQUFVO0FBQ2xDLFFBQVEsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDcEQsUUFBUSxJQUFJLEtBQUssS0FBSyxDQUFDLENBQUMsRUFBRTtBQUMxQixZQUFZLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztBQUMzQyxTQUFTO0FBQ1QsS0FBSztBQUNMO0FBQ0EsSUFBSSxTQUFTLENBQUMsS0FBSyxTQUFTO0FBQzVCLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDakMsS0FBSztBQUNMO0FBQ0EsSUFBSSxZQUFZLENBQUMsS0FBSyxTQUFTO0FBQy9CLFFBQVEsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDbEQsUUFBUSxJQUFJLEtBQUssS0FBSyxDQUFDLENBQUMsRUFBRTtBQUMxQixZQUFZLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztBQUMxQyxTQUFTO0FBQ1QsS0FBSztBQUNMO0FBQ0EsSUFBSSxhQUFhLEdBQUc7QUFDcEIsUUFBUSxNQUFNLFVBQVUsR0FBR3pDLEtBQU0sQ0FBQSxNQUFBLENBQUMsRUFBRSxFQUFFLFNBQVMsQ0FBQyxzQkFBc0IsRUFBRTtBQUN4RSxZQUFZLDRCQUE0QixFQUFFLElBQUksQ0FBQyw2QkFBNkI7QUFDNUUsWUFBWSxxQkFBcUIsRUFBRSxJQUFJLENBQUMsc0JBQXNCO0FBQzlELFlBQVksU0FBUyxFQUFFLElBQUksQ0FBQyxVQUFVLElBQUksS0FBSztBQUMvQyxTQUFTLENBQUMsQ0FBQztBQUNYO0FBQ0EsUUFBUSxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsVUFBVSxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsOEJBQThCLENBQUM7QUFDckgsUUFBUSxNQUFNLEVBQUUsR0FBRyxHQUFHO0FBQ3RCLFlBQVksSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQztBQUN4RCxZQUFZLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLG9CQUFvQixFQUFFLFVBQVUsQ0FBQyxDQUFDO0FBQ3RFO0FBQ0EsUUFBUSxJQUFJLENBQUMsRUFBRSxFQUFFO0FBQ2pCLFlBQVksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJZ1IsS0FBVSxDQUFBLFVBQUEsQ0FBQyxJQUFJLEtBQUssQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvRSxZQUFZLE9BQU87QUFDbkIsU0FBUztBQUNUO0FBQ0EsUUFBUSxJQUFJLElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQyxHQUFHLEVBQUU7QUFDckMsWUFBWUMsS0FBUSxDQUFBLFFBQUEsQ0FBQyxrREFBa0QsQ0FBQyxDQUFDO0FBQ3pFLFNBQVM7QUFDVCxRQUFRdU4sb0JBQWMsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDakM7QUFDQSxRQUFRLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxPQUFPLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzlELFFBQVEsSUFBSSxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxLQUFLLG1CQUFtQjtBQUNqRCxZQUFZLElBQUksS0FBSyxDQUFDLFFBQVEsS0FBSyxRQUFRLEVBQUU7QUFDN0MsZ0JBQWdCLElBQUksQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDckQsYUFBYTtBQUNiLFNBQVMsQ0FBQyxDQUFDO0FBQ1g7QUFDQSxRQUFRdGUsZ0JBQWEsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDdEMsS0FBSztBQUNMO0FBQ0EsSUFBSSxZQUFZLENBQUMsS0FBSyxPQUFPO0FBQzdCLFFBQVEsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO0FBQy9CLFFBQVEsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO0FBQ3pCLFlBQVksSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUNqQyxZQUFZLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO0FBQy9CLFNBQVM7QUFDVCxRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSXdRLFdBQUssQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDekUsS0FBSztBQUNMO0FBQ0EsSUFBSSxnQkFBZ0IsQ0FBQyxLQUFLLE9BQU87QUFDakMsUUFBUSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7QUFDN0IsUUFBUSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7QUFDdEIsUUFBUSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7QUFDdkIsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUlBLFdBQUssQ0FBQyxzQkFBc0IsRUFBRSxDQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDN0UsS0FBSztBQUNMO0FBQ0EsSUFBSSxZQUFZLENBQUMsS0FBSyxpQkFBaUI7QUFDdkMsUUFBUSxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLFVBQVUsRUFBRSxPQUFPO0FBQ3JEO0FBQ0E7QUFDQSxRQUFRLElBQUksQ0FBQyxVQUFVLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQztBQUN0QyxRQUFRLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQztBQUN2QyxRQUFRLE9BQU8sS0FBSyxDQUFDO0FBQ3JCLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxNQUFNLFlBQVk7QUFDdEIsUUFBUSxPQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUMvRixLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxPQUFPLENBQUMsV0FBVyxrQkFBa0I7QUFDekMsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxPQUFPLElBQUksQ0FBQztBQUNyQztBQUNBLFFBQVEsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxJQUFJLFdBQVcsQ0FBQztBQUMzRCxRQUFRLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO0FBQ2xDLFFBQVEsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO0FBQzlCO0FBQ0EsUUFBUSxPQUFPLElBQUksQ0FBQztBQUNwQixLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksbUJBQW1CLENBQUMsUUFBUSxzQkFBc0I7QUFDdEQsUUFBUSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7QUFDdkIsUUFBUSxPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDbkQsS0FBSztBQUNMO0FBQ0E7QUFDQSxJQUFJLGtCQUFrQixDQUFDLEVBQUUsVUFBVTtBQUNuQyxRQUFRLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDekMsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksZUFBZSxDQUFDLFFBQVEsY0FBYztBQUMxQztBQUNBO0FBQ0EsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxLQUFLLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxFQUFFO0FBQ25FLFlBQVksUUFBUSxFQUFFLENBQUM7QUFDdkIsU0FBUyxNQUFNO0FBQ2YsWUFBWSxJQUFJLENBQUMsbUJBQW1CLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ25ELFNBQVM7QUFDVCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLE9BQU8sQ0FBQyxtQkFBbUIsVUFBVTtBQUN6QyxRQUFRLE1BQU0sQ0FBQyxHQUFHSCxLQUFBQSxDQUFBQSxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDMUQ7QUFDQSxRQUFRLElBQUksUUFBUSxDQUFDO0FBQ3JCLFFBQVEsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDO0FBQ2pFLFFBQVEsTUFBTSxjQUFjLEdBQUc5TixjQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDN0MsUUFBUSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsa0JBQWtCLENBQUMsRUFBRTtBQUM5QyxZQUFZLFFBQVEsR0FBRyxhQUFhLENBQUMsY0FBYyxFQUFFLENBQUM7QUFDdEQsWUFBWSxhQUFhLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsRUFBRSxRQUFRLENBQUMsQ0FBQztBQUNsRixTQUFTO0FBQ1Q7QUFDQTtBQUNBLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUM7QUFDeEMsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxDQUFDO0FBQ3BDO0FBQ0EsUUFBUSxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxFQUFFO0FBQ3RFLFlBQVksSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxFQUFFcEQsS0FBQUEsQ0FBQUEsTUFBTSxDQUFDLFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO0FBQ3RHLFlBQVksSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxFQUFFQSxLQUFBQSxDQUFBQSxNQUFNLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7QUFDdEcsU0FBUztBQUNUO0FBQ0EsUUFBUSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDLENBQUM7QUFDdkQsUUFBUSxJQUFJLENBQUMsbUJBQW1CLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDLENBQUM7QUFDMUQ7QUFDQSxRQUFRLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRSxPQUFPO0FBQ2xDO0FBQ0EsUUFBUSxJQUFJLENBQUMsMkJBQTJCLEVBQUUsQ0FBQztBQUMzQztBQUNBLFFBQVEsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGNBQWMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQztBQUMxRTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsSUFBSSxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUU7QUFDNUMsWUFBWSxJQUFJLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztBQUNyQztBQUNBLFlBQVksTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUM7QUFDN0MsWUFBWSxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQztBQUMvQyxZQUFZLE1BQU0sR0FBRyxHQUFHb0QsY0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ3RDO0FBQ0EsWUFBWSxNQUFNLFVBQVUsR0FBRyxJQUFJZ2MsS0FBb0IsQ0FBQSxvQkFBQSxDQUFDLElBQUksRUFBRTtBQUM5RCxnQkFBZ0IsR0FBRztBQUNuQixnQkFBZ0IsWUFBWTtBQUM1QixnQkFBZ0IsS0FBSztBQUNyQixnQkFBZ0IsVUFBVSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFO0FBQ3RELGFBQWEsQ0FBQyxDQUFDO0FBQ2Y7QUFDQSxZQUFZLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQzFDLFNBQVM7QUFDVDtBQUNBLFFBQVEsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO0FBQ2xHO0FBQ0EsUUFBUSxJQUFJLGtCQUFrQixFQUFFO0FBQ2hDLFlBQVksSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUM7QUFDakQsWUFBWSxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztBQUN0QyxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLElBQUksdUJBQXVCLEdBQUcsS0FBSyxDQUFDO0FBQzVDLFFBQVEsSUFBSSxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUU7QUFDOUMsWUFBWSxJQUFJLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQztBQUN2QyxZQUFZLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNoRCxZQUFZLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztBQUNsQyxZQUFZLHVCQUF1QixHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxjQUFjLENBQUMsQ0FBQztBQUNuRixZQUFZLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUN0RDtBQUNBLFlBQVksSUFBSSxDQUFDLDBCQUEwQixFQUFFLENBQUM7QUFDOUMsU0FBUyxNQUFNO0FBQ2YsWUFBWSx1QkFBdUIsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUMsY0FBYyxDQUFDLENBQUM7QUFDbkYsU0FBUztBQUNUO0FBQ0EsUUFBUSxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsa0JBQWtCLEVBQUUsWUFBWSxFQUFFLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO0FBQ3JLO0FBQ0E7QUFDQSxRQUFRLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRTtBQUN4QixZQUFZLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUU7QUFDNUMsZ0JBQWdCLGtCQUFrQixFQUFFLElBQUksQ0FBQyxrQkFBa0I7QUFDM0QsZ0JBQWdCLG9CQUFvQixFQUFFLElBQUksQ0FBQyxvQkFBb0I7QUFDL0QsZ0JBQWdCLHFCQUFxQixFQUFFLElBQUksQ0FBQyxzQkFBc0I7QUFDbEUsZ0JBQWdCLGlCQUFpQixFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsa0JBQWtCO0FBQzVELGdCQUFnQixhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWE7QUFDakQsZ0JBQWdCLFFBQVEsRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFO0FBQzNDLGdCQUFnQixPQUFPLEVBQUUsSUFBSSxDQUFDLFNBQVMsRUFBRTtBQUN6QyxnQkFBZ0IsTUFBTSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUU7QUFDdkMsZ0JBQWdCLFlBQVk7QUFDNUIsZ0JBQWdCLGFBQWEsRUFBRSxJQUFJLENBQUMsY0FBYztBQUNsRCxnQkFBZ0IsV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXO0FBQzdDLGdCQUFnQixTQUFTLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsa0JBQWtCLENBQUM7QUFDN0QsZ0JBQWdCLHVCQUF1QixFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLDRCQUE0QixDQUFDO0FBQ3JGLGdCQUFnQixnQkFBZ0IsRUFBRSxJQUFJLENBQUMsZ0JBQWdCO0FBQ3ZELGFBQWEsQ0FBQyxDQUFDO0FBQ2YsU0FBUztBQUNUO0FBQ0EsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUkvTixXQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztBQUN2QztBQUNBLFFBQVEsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFO0FBQzVDLFlBQVksSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7QUFDaEMsWUFBWUgsS0FBQUEsQ0FBQUEsZ0JBQWdCLENBQUMsSUFBSSxDQUFDOE4sd0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDM0QsWUFBWSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUkzTixXQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztBQUN6QyxTQUFTO0FBQ1Q7QUFDQSxRQUFRLElBQUksSUFBSSxDQUFDLEtBQUssS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDLEVBQUU7QUFDekQsWUFBWSxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztBQUNwQyxTQUFTO0FBQ1Q7QUFDQSxRQUFRLElBQUksSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUU7QUFDakQ7QUFDQTtBQUNBO0FBQ0EsWUFBWSxJQUFJLENBQUMsS0FBSyxDQUFDLHVCQUF1QixFQUFFLENBQUM7QUFDakQsU0FBUztBQUNUO0FBQ0EsUUFBUSxJQUFJLFFBQVEsRUFBRTtBQUN0QixZQUFZLE1BQU0sYUFBYSxHQUFHak8sS0FBQUEsQ0FBQUEsUUFBTyxDQUFDLEdBQUcsRUFBRSxHQUFHLGNBQWMsQ0FBQztBQUNqRSxZQUFZLGFBQWEsQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLGdCQUFnQixFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQ2hGLFlBQVksVUFBVSxDQUFDLE1BQU07QUFDN0IsZ0JBQWdCLE1BQU0sYUFBYSxHQUFHLGFBQWEsQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsYUFBYSxDQUFDLGdCQUFnQixDQUFDLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDO0FBQ2hJLGdCQUFnQixhQUFhLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ3ZELGdCQUFnQixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUlpTyxLQUFLLENBQUEsS0FBQSxDQUFDLGtCQUFrQixFQUFFO0FBQ3hELG9CQUFvQixPQUFPLEVBQUUsYUFBYTtBQUMxQyxvQkFBb0IsT0FBTyxFQUFFLGFBQWE7QUFDMUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDO0FBQ3BCLGdCQUFnQnJSLFlBQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRTtBQUNyRCxvQkFBb0IsU0FBUyxFQUFFLGNBQWM7QUFDN0Msb0JBQW9CLE1BQU0sRUFBRTtBQUM1Qix3QkFBd0IsT0FBTyxFQUFFLGFBQWE7QUFDOUMscUJBQXFCO0FBQ3JCLGlCQUFpQixDQUFDLENBQUM7QUFDbkIsYUFBYSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ25CLFNBQVM7QUFDVDtBQUNBLFFBQVFrUixzQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkM7QUFDQSxRQUFRLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFO0FBQzlDO0FBQ0E7QUFDQSxZQUFZLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO0FBQ3RFO0FBQ0EsWUFBWSxVQUFVLENBQUMsTUFBTTtBQUM3QixnQkFBZ0IsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0FBQzFGO0FBQ0EsZ0JBQWdCLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSUcsS0FBSyxDQUFBLEtBQUEsQ0FBQyxrQkFBa0IsRUFBRTtBQUN4RCxvQkFBb0IsVUFBVSxFQUFFLGtCQUFrQjtBQUNsRCxpQkFBaUIsQ0FBQyxDQUFDLENBQUM7QUFDcEIsYUFBYSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ25CLFNBQVM7QUFDVDtBQUNBLFFBQVEsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLDRCQUE0QixDQUFDLEVBQUU7QUFDeEQsWUFBWSxNQUFNLHFCQUFxQixHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsK0JBQStCLEVBQUUsQ0FBQztBQUN6RjtBQUNBLFlBQVksVUFBVSxDQUFDLE1BQU07QUFDN0IsZ0JBQWdCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsMEJBQTBCLENBQUMscUJBQXFCLENBQUMsQ0FBQztBQUMvRixnQkFBZ0IsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJQSxLQUFLLENBQUEsS0FBQSxDQUFDLDRCQUE0QixFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzlFLGFBQWEsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNuQixTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsYUFBYSxJQUFJLElBQUksQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDLGVBQWUsSUFBSSx1QkFBdUIsQ0FBQztBQUN6SCxRQUFRLElBQUksY0FBYyxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7QUFDN0MsWUFBWSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7QUFDbEMsU0FBUyxNQUFNO0FBQ2YsWUFBWSxNQUFNLFFBQVEsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7QUFDL0QsWUFBWSxJQUFJLFFBQVEsRUFBRTtBQUMxQjtBQUNBO0FBQ0EsZ0JBQWdCLHVCQUF1QixHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDN0YsYUFBYTtBQUNiO0FBQ0EsWUFBWSxJQUFJLHVCQUF1QixFQUFFO0FBQ3pDLGdCQUFnQixJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7QUFDdEMsYUFBYSxNQUFNO0FBQ25CLGdCQUFnQixJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzFDLGdCQUFnQixJQUFJLFFBQVEsRUFBRTtBQUM5QixvQkFBb0IsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJQSxXQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztBQUNqRCxvQkFBb0IsSUFBSSxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUM7QUFDaEQ7QUFDQSxvQkFBb0IsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7QUFDL0Msd0JBQXdCLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7QUFDN0Usd0JBQXdCLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSUEsV0FBSyxDQUFDLHFCQUFxQixFQUFFLENBQUMsVUFBVSxFQUFFLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3BHLHdCQUF3QixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsS0FBSyxDQUFDO0FBQ3RELHFCQUFxQjtBQUNyQixpQkFBaUI7QUFDakIsYUFBYTtBQUNiLFNBQVM7QUFDVDtBQUNBLFFBQVEsSUFBSSxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksSUFBSSxDQUFDLGNBQWMsRUFBRTtBQUNuRSxZQUFZLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO0FBQ3JDLFlBQVkwTixLQUFBQSxDQUFBQSxvQkFBb0IsQ0FBQyxJQUFJLENBQUNDLHdCQUFrQixDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ25FO0FBQ0EsWUFBWSxJQUFJLElBQUksQ0FBQyw2QkFBNkIsRUFBRTtBQUNwRCxnQkFBZ0JLLDBCQUFvQixDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsa0JBQWtCLEVBQUU7QUFDOUUsb0JBQW9CLEtBQUssRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUs7QUFDN0Msb0JBQW9CLE1BQU0sRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU07QUFDL0Msb0JBQW9CLGdCQUFnQixFQUFFLElBQUksQ0FBQyxpQkFBaUI7QUFDNUQsb0JBQW9CLGdCQUFnQixFQUFFLElBQUksQ0FBQyxpQkFBaUI7QUFDNUQsb0JBQW9CLGNBQWMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUFFO0FBQ3JFLG9CQUFvQixVQUFVLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRTtBQUM3RCxvQkFBb0IsVUFBVSxFQUFFLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxJQUFJO0FBQ3pELG9CQUFvQixJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJO0FBQzdDLG9CQUFvQixRQUFRLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsUUFBUTtBQUMzRCxvQkFBb0IsTUFBTSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU07QUFDdkQsaUJBQWlCLENBQUMsQ0FBQztBQUNuQixhQUFhO0FBQ2IsWUFBWSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7QUFDakMsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBLElBQUksMEJBQTBCLENBQUMsVUFBVSxZQUFZO0FBQ3JELFFBQVEsS0FBSyxNQUFNLE1BQU0sSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO0FBQzVDO0FBQ0EsWUFBWSxJQUFJLFVBQVUsSUFBSSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxFQUFFO0FBQzVELGdCQUFnQixNQUFNLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7QUFDdkQsYUFBYTtBQUNiLFlBQVksTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBQzdCLFNBQVM7QUFDVCxRQUFRLEtBQUssTUFBTSxLQUFLLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtBQUMxQztBQUNBLFlBQVksSUFBSSxVQUFVLElBQUksQ0FBQyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLEVBQUU7QUFDcEYsZ0JBQWdCLEtBQUssQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUNyRCxhQUFhO0FBQ2IsWUFBWSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7QUFDNUIsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksdUJBQXVCLENBQUMsU0FBUyxVQUFVLGFBQWEsWUFBWSxLQUFLLFdBQVc7QUFDeEYsUUFBUSxNQUFNLFdBQVcsR0FBRyxDQUFDLEtBQUssYUFBYTtBQUMvQyxZQUFZLElBQUksQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLEdBQUcsS0FBSyxDQUFDO0FBQ3BELFlBQVksSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNoQyxZQUFZLE9BQU8sSUFBSSxDQUFDO0FBQ3hCLFNBQVMsQ0FBQztBQUNWO0FBQ0EsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQywyQkFBMkIsRUFBRSxFQUFFO0FBQ3pELFlBQVksSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLGdCQUFnQixLQUFLLENBQUMsRUFBRSxPQUFPLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM3RSxZQUFZLE9BQU8sS0FBSyxDQUFDO0FBQ3pCLFNBQVM7QUFDVDtBQUNBLFFBQVEsTUFBTSxjQUFjLEdBQUcsYUFBYSxJQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMsOEJBQThCLEdBQUcsbUNBQW1DLENBQUM7QUFDdEk7QUFDQSxRQUFRLElBQUksY0FBYyxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsRUFBRTtBQUMzRSxZQUFZLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQztBQUNyRSxZQUFZLElBQUksWUFBWSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztBQUN2RSxZQUFZLElBQUksbUJBQW1CLEdBQUcsS0FBSyxDQUFDO0FBQzVDLFlBQVksSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRTtBQUMxQyxnQkFBZ0IsbUJBQW1CLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsWUFBWSxFQUFFLEtBQUssSUFBSSxDQUFDLDZCQUE2QixDQUFDO0FBQ3JIO0FBQ0EsZ0JBQWdCLElBQUksQ0FBQyw2QkFBNkIsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxZQUFZLEVBQUUsQ0FBQztBQUM3RixhQUFhO0FBQ2I7QUFDQTtBQUNBLFlBQVksSUFBSSxLQUFLLENBQUMsWUFBWSxDQUFDLEVBQUU7QUFDckMsZ0JBQWdCLFlBQVksR0FBRyxDQUFDLENBQUM7QUFDakMsYUFBYSxNQUFNO0FBQ25CO0FBQ0EsZ0JBQWdCLElBQUksQ0FBQyw4QkFBOEIsR0FBRyxTQUFTLENBQUM7QUFDaEUsYUFBYTtBQUNiLFlBQVksTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsR0FBRyxZQUFZLENBQUMsQ0FBQztBQUM5RTtBQUNBLFlBQVksSUFBSSxlQUFlLEdBQUcsZ0NBQWdDLEVBQUU7QUFDcEUsZ0JBQWdCLElBQUksSUFBSSxDQUFDLGNBQWMsSUFBSSxtQkFBbUIsRUFBRTtBQUNoRSxvQkFBb0IsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUNoRSxvQkFBb0IsT0FBTyxXQUFXLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDckQsaUJBQWlCLE1BQU07QUFDdkIsb0JBQW9CLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLFNBQVMsRUFBRSwyQkFBMkIsQ0FBQyxDQUFDO0FBQ3hHLGlCQUFpQjtBQUNqQixhQUFhLE1BQU0sSUFBSSxlQUFlLEdBQUcsa0NBQWtDLEVBQUU7QUFDN0UsZ0JBQWdCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDNUQsZ0JBQWdCLE9BQU8sV0FBVyxDQUFDLFlBQVksQ0FBQyxDQUFDO0FBQ2pELGFBQWE7QUFDYixTQUFTO0FBQ1Q7QUFDQSxRQUFRLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsRUFBRTtBQUN4RCxZQUFZLE9BQU8sV0FBVyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUMzRSxTQUFTO0FBQ1Q7QUFDQSxRQUFRLE9BQU8sS0FBSyxDQUFDO0FBQ3JCLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxhQUFhLEdBQUc7QUFDcEIsUUFBUUMsS0FBQUEsQ0FBQUEsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxHQUFHLEtBQUs7QUFDN0gsWUFBWSxJQUFJLEdBQUcsRUFBRTtBQUNyQjtBQUNBLGdCQUFnQixJQUFJLEdBQUcsQ0FBQyxPQUFPLEtBQUtDLEtBQUFBLENBQUFBLFlBQVksSUFBSSxDQUFDLEdBQUcsT0FBTyxNQUFNLEtBQUssR0FBRyxFQUFFO0FBQy9FLG9CQUFvQixNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7QUFDdkQsb0JBQW9CSixvQkFBYyxDQUFDLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztBQUM5QyxvQkFBb0IsSUFBSSxJQUFJLENBQUMsWUFBWSxZQUFZLFdBQVcsRUFBRTtBQUNsRSx3QkFBd0IsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQztBQUN4RCxxQkFBcUI7QUFDckIsb0JBQW9CLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLGdCQUFnQixHQUFHLEVBQUUsQ0FBQyxnQkFBZ0IsR0FBRyxFQUFFLENBQUMsa0JBQWtCLENBQUMsQ0FBQztBQUN4RztBQUNBLG9CQUFvQixJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFO0FBQ2xELHdCQUF3QixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUl4TixLQUFVLENBQUEsVUFBQSxDQUFDLElBQUksS0FBSyxDQUFDLDRJQUE0SSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNNLHFCQUFxQjtBQUNyQixpQkFBaUI7QUFDakIsYUFBYTtBQUNiLFNBQVMsQ0FBQyxDQUFDO0FBQ1gsUUFBUTZOLEtBQUFBLENBQUFBLGdCQUFnQixDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDLGtCQUFrQixFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7QUFDOUgsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxjQUFjLEdBQUc7QUFDckI7QUFDQTtBQUNBLFFBQVEsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7QUFDdkQsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLG1CQUFtQixDQUFDLENBQUM7QUFDcEUsS0FBSztBQUNMO0FBQ0EsSUFBSSxvQkFBb0IsV0FBVztBQUNuQyxRQUFRLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLENBQUM7QUFDckQsUUFBUSxNQUFNLG1CQUFtQixHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsNEJBQTRCLEVBQUUsQ0FBQztBQUNoRixRQUFRLG1CQUFtQixDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7QUFDL0Q7QUFDQSxRQUFRLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztBQUMzQyxRQUFRLE1BQU0sV0FBVyxHQUFHLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO0FBQ25ELFFBQVEsRUFBRSxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUMsV0FBVyxFQUFFLFdBQVcsQ0FBQyxDQUFDO0FBQ3hEO0FBQ0EsUUFBUSxTQUFTLElBQUksQ0FBQyxPQUFPLGlCQUFpQjtBQUM5QyxZQUFZLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQyxFQUFFLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxFQUFFLENBQUMsVUFBVSxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNyRyxZQUFZLE1BQU0sTUFBTSxHQUFHLElBQUksVUFBVSxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsR0FBRyxFQUFFLENBQUMsbUJBQW1CLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDOUYsWUFBWSxFQUFFLENBQUMsVUFBVSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLGtCQUFrQixFQUFFLEVBQUUsQ0FBQyxtQkFBbUIsRUFBRSxFQUFFLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxhQUFhLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDbEgsWUFBWSxPQUFPLE1BQU0sQ0FBQztBQUMxQixTQUFTO0FBQ1Q7QUFDQSxRQUFRLE9BQU8sSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxtQkFBbUIsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLG1CQUFtQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQ3pJLEtBQUs7QUFDTDtBQUNBLElBQUksc0JBQXNCLENBQUMsVUFBVSxjQUFjLFNBQVMsZ0JBQWdCLFVBQVUsb0JBQW9CO0FBQzFHLFFBQVEsSUFBSSxVQUFVLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2RCxRQUFRLE1BQU0sU0FBUyxHQUFHLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0FBQ2hEO0FBQ0EsUUFBUSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUNuRCxZQUFZLE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QyxZQUFZLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQztBQUN4QixZQUFZLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUU7QUFDdEQsZ0JBQWdCLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLFVBQVUsQ0FBQyxDQUFDLENBQUM7QUFDOUMsb0JBQW9CLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssVUFBVSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDdEQsb0JBQW9CLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssVUFBVSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDdEQsb0JBQW9CLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssVUFBVSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRTtBQUN4RCxvQkFBb0IsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUM7QUFDbEMsaUJBQWlCO0FBQ2pCLGFBQWE7QUFDYjtBQUNBLFlBQVksTUFBTSxRQUFRLEdBQUcsVUFBVSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxVQUFVLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ25FLFlBQVksTUFBTSxpQkFBaUIsR0FBRyxHQUFHLEdBQUcsU0FBUyxDQUFDO0FBQ3RELFlBQVksVUFBVSxLQUFLLFFBQVEsSUFBSSxDQUFDLEdBQUcsaUJBQWlCLENBQUMsQ0FBQztBQUM5RCxTQUFTO0FBQ1QsUUFBUSxPQUFPLFVBQVUsQ0FBQztBQUMxQixLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLE1BQU0sR0FBRztBQUNiLFFBQVEsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7QUFDNUM7QUFDQSxRQUFRLEtBQUssTUFBTSxPQUFPLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3JFLFFBQVEsSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUM7QUFDNUI7QUFDQSxRQUFRLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtBQUN6QixZQUFZLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUM7QUFDakMsWUFBWSxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztBQUMvQixTQUFTO0FBQ1QsUUFBUSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLENBQUM7QUFDdEMsUUFBUSxJQUFJLENBQUMsbUJBQW1CLENBQUMsS0FBSyxFQUFFLENBQUM7QUFDekMsUUFBUSxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUU7QUFDeEIsWUFBWSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBQ2pDLFNBQVM7QUFDVCxRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7QUFDL0IsUUFBUSxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztBQUNuRCxRQUFRLElBQUksQ0FBQyxRQUFRLEdBQUcsU0FBUyxDQUFDO0FBQ2xDLFFBQVEsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUM1QjtBQUNBLFFBQVEsSUFBSSxPQUFPeGYsS0FBTSxDQUFBLE1BQUEsS0FBSyxXQUFXLEVBQUU7QUFDM0M7QUFDQSxZQUFZQSxLQUFNLENBQUEsTUFBQSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsZUFBZSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQzlFO0FBQ0EsWUFBWUEsS0FBTSxDQUFBLE1BQUEsQ0FBQyxtQkFBbUIsQ0FBQyxtQkFBbUIsRUFBRSxJQUFJLENBQUMsZUFBZSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ3pGO0FBQ0EsWUFBWUEsS0FBTSxDQUFBLE1BQUEsQ0FBQyxtQkFBbUIsQ0FBQyx3QkFBd0IsRUFBRSxJQUFJLENBQUMsZUFBZSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQzlGO0FBQ0EsWUFBWUEsS0FBTSxDQUFBLE1BQUEsQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLGVBQWUsRUFBRSxLQUFLLENBQUMsQ0FBQztBQUM5RTtBQUNBLFlBQVlBLEtBQU0sQ0FBQSxNQUFBLENBQUMsbUJBQW1CLENBQUMsa0JBQWtCLEVBQUUsSUFBSSxDQUFDLG1CQUFtQixFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQzVGLFNBQVM7QUFDVDtBQUNBLFFBQVEsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0FBQ3JGLFFBQVEsSUFBSSxTQUFTLEVBQUUsU0FBUyxDQUFDLFdBQVcsRUFBRSxDQUFDO0FBQy9DO0FBQ0E7QUFDQSxRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsbUJBQW1CLENBQUMsa0JBQWtCLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxLQUFLLENBQUMsQ0FBQztBQUN2RjtBQUNBLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxzQkFBc0IsRUFBRSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDL0Y7QUFDQSxRQUFRLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUN2QyxRQUFRLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUN4QyxRQUFRLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUN4QztBQUNBLFFBQVEsSUFBSSxDQUFDLE9BQU8sSUFBSSxTQUFTLE1BQU0sQ0FBQztBQUN4QyxRQUFRLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxTQUFTLE1BQU0sQ0FBQztBQUNqRCxRQUFRLElBQUksQ0FBQyxpQkFBaUIsSUFBSSxTQUFTLE1BQU0sQ0FBQztBQUNsRCxRQUFRLElBQUksQ0FBQyxpQkFBaUIsSUFBSSxTQUFTLE1BQU0sQ0FBQztBQUNsRDtBQUNBLFFBQVEsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0FBQ3pEO0FBQ0EsUUFBUSxJQUFJLENBQUMsVUFBVSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ2hGO0FBQ0EsUUFBUWtSLEtBQWdCLENBQUEsZ0JBQUEsQ0FBQyxZQUFZLEVBQUUsQ0FBQztBQUN4QyxRQUFRdU8sS0FBQUEsQ0FBQUEsZUFBZSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2pELFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7QUFDN0IsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUlwTyxXQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztBQUN2QyxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxjQUFjLEdBQUc7QUFDckIsUUFBUSxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ2pDLEtBQUs7QUFDTDtBQUNBLElBQUksYUFBYSxDQUFDLE1BQU0sV0FBVztBQUNuQyxRQUFRLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLElBQUksTUFBTSxDQUFDO0FBQ2hFLFFBQVEsSUFBSSxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRTtBQUN4QyxZQUFZLElBQUksQ0FBQyxNQUFNLEdBQUdqTyxLQUFBQSxDQUFBQSxRQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsbUJBQW1CLGFBQWE7QUFDekUsZ0JBQWdCLE1BQU0sYUFBYSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7QUFDOUQsZ0JBQWdCOE4sS0FBQUEsQ0FBQUEsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLG1CQUFtQixFQUFFLGFBQWEsQ0FBQyxDQUFDO0FBQzNFLGdCQUFnQixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztBQUNuQyxnQkFBZ0IsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQztBQUM3QyxnQkFBZ0IsSUFBSSxhQUFhLEVBQUU7QUFDbkMsb0JBQW9CLElBQUksQ0FBQyxPQUFPLENBQUMsbUJBQW1CLENBQUMsQ0FBQztBQUN0RCxpQkFBaUI7QUFDakIsYUFBYSxDQUFDLENBQUM7QUFDZixTQUFTO0FBQ1QsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLGFBQWEsQ0FBQyxTQUFTLHNDQUFzQztBQUNqRSxRQUFRLE1BQU0sT0FBTyx1QkFBdUIsSUFBSSxDQUFDLEtBQUssSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLFNBQVMsRUFBRSxDQUFDO0FBQzdHLFFBQVF5QixjQUFRLENBQUMsT0FBTyxFQUFFLENBQUMsTUFBTSxFQUFFLElBQUksS0FBSyxNQUFNLENBQUMsYUFBYSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsRUFBRSxNQUFNO0FBQ3pGLFlBQVksSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO0FBQ2xDLFNBQVMsQ0FBQyxDQUFDO0FBQ1g7QUFDQSxRQUFRLE9BQU8sSUFBSSxDQUFDO0FBQ3BCLEtBQUs7QUFDTDtBQUNBLElBQUksZUFBZSxHQUFHO0FBQ3RCLFFBQVEsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBQ3ZCLEtBQUs7QUFDTDtBQUNBLElBQUksZUFBZSxDQUFDLEtBQUssU0FBUztBQUNsQyxRQUFRLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRTtBQUMvQixZQUFZLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztBQUMxRCxTQUFTO0FBQ1QsS0FBSztBQUNMO0FBQ0EsSUFBSSxtQkFBbUIsR0FBRztBQUMxQixRQUFRLElBQUkzUyxZQUFNLENBQUMsUUFBUSxDQUFDLGVBQWUsS0FBSyxRQUFRLEVBQUU7QUFDMUQsWUFBWSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztBQUNyQyxTQUFTO0FBQ1QsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksSUFBSSxrQkFBa0IsWUFBWSxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFO0FBQzVFLElBQUksSUFBSSxrQkFBa0IsQ0FBQyxLQUFLLFdBQVc7QUFDM0MsUUFBUSxJQUFJLElBQUksQ0FBQyxtQkFBbUIsS0FBSyxLQUFLLEVBQUUsT0FBTztBQUN2RCxRQUFRLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxLQUFLLENBQUM7QUFDekMsUUFBUSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7QUFDdkIsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLElBQUksb0JBQW9CLFlBQVksRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsRUFBRTtBQUNoRixJQUFJLElBQUksb0JBQW9CLENBQUMsS0FBSyxXQUFXO0FBQzdDLFFBQVEsSUFBSSxJQUFJLENBQUMscUJBQXFCLEtBQUssS0FBSyxFQUFFLE9BQU87QUFDekQsUUFBUSxJQUFJLENBQUMscUJBQXFCLEdBQUcsS0FBSyxDQUFDO0FBQzNDLFFBQVEsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBQ3ZCLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLElBQUksZ0JBQWdCLFlBQVksRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsRUFBRTtBQUN4RSxJQUFJLElBQUksZ0JBQWdCLENBQUMsS0FBSyxXQUFXO0FBQ3pDLFFBQVEsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEtBQUssS0FBSyxFQUFFLE9BQU87QUFDckQsUUFBUSxJQUFJLENBQUMsaUJBQWlCLEdBQUcsS0FBSyxDQUFDO0FBQ3ZDLFFBQVEsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBQ3ZCLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksSUFBSSxXQUFXLFlBQVksRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUU7QUFDOUQsSUFBSSxJQUFJLFdBQVcsQ0FBQyxLQUFLLFdBQVc7QUFDcEMsUUFBUSxJQUFJLElBQUksQ0FBQyxZQUFZLEtBQUssS0FBSyxFQUFFLE9BQU87QUFDaEQsUUFBUSxJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztBQUNsQyxRQUFRLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztBQUN2QixLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxJQUFJLGtCQUFrQixZQUFZLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEVBQUU7QUFDNUUsSUFBSSxJQUFJLGtCQUFrQixDQUFDLEtBQUssV0FBVztBQUMzQyxRQUFRLElBQUksSUFBSSxDQUFDLG1CQUFtQixLQUFLLEtBQUssRUFBRSxPQUFPO0FBQ3ZELFFBQVEsSUFBSSxDQUFDLG1CQUFtQixHQUFHLEtBQUssQ0FBQztBQUN6QyxRQUFRLElBQUksS0FBSyxFQUFFO0FBQ25CO0FBQ0E7QUFDQSxZQUFZLElBQUksQ0FBQyxLQUFLLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztBQUNqRCxTQUFTLE1BQU07QUFDZjtBQUNBLFlBQVksSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBQzNCLFNBQVM7QUFDVCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLElBQUkscUJBQXFCLFlBQVksRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsRUFBRTtBQUNsRixJQUFJLElBQUkscUJBQXFCLENBQUMsS0FBSyxXQUFXO0FBQzlDLFFBQVEsSUFBSSxJQUFJLENBQUMsc0JBQXNCLEtBQUssS0FBSyxFQUFFLE9BQU87QUFDMUQsUUFBUSxJQUFJLENBQUMsc0JBQXNCLEdBQUcsS0FBSyxDQUFDO0FBQzVDLFFBQVEsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBQ3ZCLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksSUFBSSxPQUFPLFlBQVksRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUU7QUFDdEQsSUFBSSxJQUFJLE9BQU8sQ0FBQyxLQUFLLFdBQVc7QUFDaEMsUUFBUSxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssS0FBSyxFQUFFO0FBQ3JDLFlBQVksSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7QUFDbEMsWUFBWSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7QUFDbEMsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBLElBQUksSUFBSSxRQUFRLFlBQVksRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUU7QUFDeEQsSUFBSSxJQUFJLFFBQVEsQ0FBQyxLQUFLLFdBQVcsRUFBRSxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFO0FBQzVFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxJQUFJLGFBQWEsWUFBWSxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsRUFBRTtBQUNsRSxJQUFJLElBQUksYUFBYSxDQUFDLEtBQUssV0FBVztBQUN0QyxRQUFRLElBQUksSUFBSSxDQUFDLGNBQWMsS0FBSyxLQUFLLEVBQUUsT0FBTztBQUNsRCxRQUFRLElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDO0FBQ3BDLFFBQVEsSUFBSSxDQUFDLEtBQUssRUFBRSxFQUFFMGIsS0FBQUEsQ0FBQUEsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFO0FBQ25ELFFBQVEsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBQ3ZCLEtBQUs7QUFDTDtBQUNBO0FBQ0EsSUFBSSxlQUFlLENBQUMsS0FBSyxVQUFVLGNBQWMsVUFBVTtBQUMzRCxRQUFRZ0Usb0JBQWMsQ0FBQyxLQUFLLEVBQUUsY0FBYyxDQUFDLENBQUM7QUFDOUMsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxJQUFJLE9BQU8sV0FBVyxFQUFFLE9BQU9DLEtBQUFBLENBQUFBLE9BQU8sQ0FBQyxFQUFFO0FBQzdDLENBQUM7QUFHRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1MEhBO0FBQ0E7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU03QixnQkFBYyxZQUFZO0FBQ2hDLElBQUksV0FBVyxFQUFFLElBQUk7QUFDckIsSUFBSSxRQUFRLEVBQUUsSUFBSTtBQUNsQixJQUFJLGNBQWMsRUFBRSxLQUFLO0FBQ3pCLENBQUMsQ0FBQztBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU0saUJBQWlCLENBQUM7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxXQUFXLENBQUMsT0FBTyxXQUFXO0FBQ2xDLFFBQVEsSUFBSSxDQUFDLE9BQU8sR0FBR25kLEtBQU0sQ0FBQSxNQUFBLENBQUMsRUFBRSxFQUFFbWQsZ0JBQWMsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUMzRDtBQUNBLFFBQVEsSUFBSSxDQUFDLFVBQVUsR0FBR0wsUUFBVSxDQUFDLEtBQUssRUFBRSxtQ0FBbUMsQ0FBQyxDQUFDO0FBQ2pGLFFBQVEsSUFBSSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQztBQUMvRjtBQUNBLFFBQVEsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRTtBQUNuQyxZQUFZekksYUFBTyxDQUFDO0FBQ3BCLGdCQUFnQixpQkFBaUI7QUFDakMsZ0JBQWdCLG9CQUFvQjtBQUNwQyxhQUFhLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDckIsWUFBWSxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsdUJBQXVCLEVBQUUsQ0FBQyxDQUFDLEtBQUssRUFBRSxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLENBQUMsYUFBYSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDbEosWUFBWXlJLFFBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxZQUFZLENBQUMsYUFBYSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQzdHLFlBQVksSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLHdCQUF3QixFQUFFLENBQUMsQ0FBQyxLQUFLLEVBQUUsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3JKLFlBQVlBLFFBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxZQUFZLENBQUMsYUFBYSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQzlHLFNBQVM7QUFDVCxRQUFRLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUU7QUFDdEMsWUFBWXpJLGFBQU8sQ0FBQztBQUNwQixnQkFBZ0IscUJBQXFCO0FBQ3JDLGFBQWEsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUNyQixZQUFZLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDLENBQUMsS0FBSztBQUMvRSxnQkFBZ0IsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztBQUN0QyxnQkFBZ0IsSUFBSSxDQUFDLEdBQUcsRUFBRSxPQUFPO0FBQ2pDLGdCQUFnQixJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFO0FBQ2pELG9CQUFvQixHQUFHLENBQUMsZUFBZSxDQUFDLEVBQUUsRUFBRSxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hFLGlCQUFpQixNQUFNO0FBQ3ZCLG9CQUFvQixHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNELGlCQUFpQjtBQUNqQixhQUFhLENBQUMsQ0FBQztBQUNmLFlBQVksSUFBSSxDQUFDLFlBQVksR0FBR3lJLFFBQVUsQ0FBQyxNQUFNLEVBQUUsb0JBQW9CLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ3hGLFlBQVksSUFBSSxDQUFDLFlBQVksQ0FBQyxZQUFZLENBQUMsYUFBYSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ2xFLFNBQVM7QUFDVCxLQUFLO0FBQ0w7QUFDQSxJQUFJLGtCQUFrQixHQUFHO0FBQ3pCLFFBQVEsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztBQUM5QixRQUFRLElBQUksQ0FBQyxHQUFHLEVBQUUsT0FBTztBQUN6QjtBQUNBLFFBQVEsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBQ25DLFFBQVEsTUFBTSxLQUFLLEdBQUcsSUFBSSxLQUFLLEdBQUcsQ0FBQyxVQUFVLEVBQUUsQ0FBQztBQUNoRCxRQUFRLE1BQU0sS0FBSyxHQUFHLElBQUksS0FBSyxHQUFHLENBQUMsVUFBVSxFQUFFLENBQUM7QUFDaEQsUUFBUSxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7QUFDNUMsUUFBUSxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7QUFDN0MsUUFBUSxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxlQUFlLEVBQUUsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7QUFDM0UsUUFBUSxJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxlQUFlLEVBQUUsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7QUFDNUUsS0FBSztBQUNMO0FBQ0EsSUFBSSxtQkFBbUIsR0FBRztBQUMxQixRQUFRLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7QUFDOUIsUUFBUSxJQUFJLENBQUMsR0FBRyxFQUFFLE9BQU87QUFDekI7QUFDQSxRQUFRLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYztBQUNsRCxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLFVBQVUsRUFBRSxHQUFHLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxhQUFhLEVBQUUsR0FBRyxDQUFDLFNBQVMsQ0FBQyxLQUFLLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUM7QUFDbEwsWUFBWSxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsU0FBUyxDQUFDLEtBQUssSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ2xFO0FBQ0EsUUFBUSxHQUFHLENBQUMsZUFBZSxDQUFDLE1BQU07QUFDbEMsWUFBWSxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7QUFDbkMsZ0JBQWdCLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLFNBQVMsR0FBRyxNQUFNLENBQUM7QUFDM0QsYUFBYTtBQUNiLFNBQVMsQ0FBQyxDQUFDO0FBQ1gsS0FBSztBQUNMO0FBQ0EsSUFBSSxLQUFLLENBQUMsR0FBRyxvQkFBb0I7QUFDakMsUUFBUSxJQUFJLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQztBQUN4QixRQUFRLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUU7QUFDbkMsWUFBWSxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDL0QsWUFBWSxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsU0FBUyxDQUFDLENBQUM7QUFDakU7QUFDQSxZQUFZLEdBQUcsQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0FBQ3BELFlBQVksSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7QUFDdEMsU0FBUztBQUNULFFBQVEsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRTtBQUN0QyxZQUFZLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxjQUFjLENBQUMsQ0FBQztBQUNoRSxZQUFZLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUU7QUFDN0M7QUFDQSxnQkFBZ0IsR0FBRyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUM7QUFDMUQsYUFBYTtBQUNiO0FBQ0EsWUFBWSxHQUFHLENBQUMsRUFBRSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsQ0FBQztBQUN2RCxZQUFZLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO0FBQ3ZDLFlBQVksSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLGtCQUFrQixDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7QUFDcEcsU0FBUztBQUNULFFBQVEsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDO0FBQy9CLEtBQUs7QUFDTDtBQUNBLElBQUksUUFBUSxHQUFHO0FBQ2YsUUFBUSxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO0FBQzlCLFFBQVEsSUFBSSxDQUFDLEdBQUcsRUFBRSxPQUFPO0FBQ3pCLFFBQVEsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUNqQyxRQUFRLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUU7QUFDbkM7QUFDQSxZQUFZLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0FBQ3JELFNBQVM7QUFDVCxRQUFRLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUU7QUFDdEMsWUFBWSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFO0FBQzdDO0FBQ0EsZ0JBQWdCLEdBQUcsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0FBQzNELGFBQWE7QUFDYjtBQUNBLFlBQVksR0FBRyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUM7QUFDeEQsWUFBWSxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNuRCxZQUFZLElBQUksQ0FBQyxRQUFRLEdBQUcsU0FBUyxDQUFDO0FBQ3RDLFNBQVM7QUFDVCxRQUFRLElBQUksQ0FBQyxJQUFJLEdBQUcsU0FBUyxDQUFDO0FBQzlCLEtBQUs7QUFDTDtBQUNBLElBQUksYUFBYSxDQUFDLFNBQVMsVUFBVSxFQUFFLGtDQUFrQztBQUN6RSxRQUFRLE1BQU0sQ0FBQyxHQUFHQSxRQUFVLENBQUMsUUFBUSxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDbkUsUUFBUSxDQUFDLENBQUMsSUFBSSxHQUFHLFFBQVEsQ0FBQztBQUMxQixRQUFRLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDeEMsUUFBUSxPQUFPLENBQUMsQ0FBQztBQUNqQixLQUFLO0FBQ0w7QUFDQSxJQUFJLGVBQWUsQ0FBQyxNQUFNLHFCQUFxQixLQUFLLFVBQVU7QUFDOUQsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxPQUFPO0FBQy9CLFFBQVEsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxrQkFBa0IsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDekUsUUFBUSxNQUFNLENBQUMsWUFBWSxDQUFDLFlBQVksRUFBRSxHQUFHLENBQUMsQ0FBQztBQUMvQyxRQUFRLElBQUksTUFBTSxDQUFDLGlCQUFpQixFQUFFLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQzFGLEtBQUs7QUFDTCxDQUFDO0FBQ0Q7QUFDQSxNQUFNLGtCQUFrQixDQUFDO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksV0FBVyxDQUFDLEdBQUcsT0FBTyxPQUFPLGVBQWUsS0FBSyxhQUFhLEtBQUssRUFBRTtBQUN6RSxRQUFRLElBQUksQ0FBQyxlQUFlLEdBQUcsRUFBRSxDQUFDO0FBQ2xDLFFBQVEsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7QUFDL0IsUUFBUSxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksa0JBQWtCLENBQUMsQ0FBQyxjQUFjLEVBQUUsR0FBRyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQztBQUNqSCxRQUFRLElBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDO0FBQ3ZCLFFBQVEsSUFBSSxLQUFLLEVBQUUsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLGlCQUFpQixDQUFDLENBQUMsY0FBYyxFQUFFLEdBQUcsQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUM7QUFDekg7QUFDQSxRQUFRekksS0FBQUEsQ0FBQUEsT0FBTyxDQUFDLENBQUMsV0FBVyxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQUUsT0FBTyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDN0c7QUFDQSxRQUFRLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQzlEO0FBQ0EsUUFBUSxPQUFPLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNsRjtBQUNBLFFBQVEsT0FBTyxDQUFDLGdCQUFnQixDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDOUQ7QUFDQSxRQUFRLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQzVEO0FBQ0EsUUFBUSxPQUFPLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUM1RCxLQUFLO0FBQ0w7QUFDQSxJQUFJLElBQUksQ0FBQyxDQUFDLGNBQWMsS0FBSyxTQUFTO0FBQ3RDLFFBQVEsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQzdDLFFBQVEsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztBQUNqRSxRQUFRd0ksV0FBZSxFQUFFLENBQUM7QUFDMUIsS0FBSztBQUNMO0FBQ0EsSUFBSSxJQUFJLENBQUMsQ0FBQyxjQUFjLEtBQUssU0FBUztBQUN0QyxRQUFRLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUM7QUFDN0IsUUFBUSxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLGVBQWUsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDN0QsUUFBUSxNQUFNLEtBQUssR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLFlBQVksQ0FBQztBQUMxQyxRQUFRLElBQUksS0FBSyxFQUFFLEdBQUcsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxHQUFHLEtBQUssQ0FBQyxDQUFDO0FBQzVELFFBQVEsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFO0FBQzdCLFlBQVksTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxlQUFlLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ2hFLFlBQVksTUFBTSxLQUFLLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxVQUFVLENBQUM7QUFDNUMsWUFBWSxJQUFJLEtBQUssRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsR0FBRyxLQUFLLENBQUMsQ0FBQztBQUM1RCxTQUFTO0FBQ1QsS0FBSztBQUNMO0FBQ0EsSUFBSSxHQUFHLEdBQUc7QUFDVixRQUFRLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUM7QUFDckM7QUFDQSxRQUFRLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQ2pFO0FBQ0EsUUFBUSxPQUFPLENBQUMsbUJBQW1CLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNyRjtBQUNBLFFBQVEsT0FBTyxDQUFDLG1CQUFtQixDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDakU7QUFDQSxRQUFRLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQy9EO0FBQ0EsUUFBUSxPQUFPLENBQUMsbUJBQW1CLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUMvRCxRQUFRLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztBQUN2QixLQUFLO0FBQ0w7QUFDQSxJQUFJLE9BQU8sR0FBRztBQUNkLFFBQVFHLFVBQWMsRUFBRSxDQUFDO0FBQ3pCO0FBQ0EsUUFBUTNkLEtBQUFBLENBQUFBLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQ2hFO0FBQ0EsUUFBUUEsS0FBQUEsQ0FBQUEsTUFBTSxDQUFDLG1CQUFtQixDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDNUQsS0FBSztBQUNMO0FBQ0EsSUFBSSxTQUFTLENBQUMsQ0FBQyxjQUFjO0FBQzdCLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQ1csWUFBTSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBRSxNQUFNLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLEVBQUUyYyxRQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNIO0FBQ0EsUUFBUXRkLEtBQUFBLENBQUFBLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQzdEO0FBQ0EsUUFBUUEsS0FBQUEsQ0FBQUEsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDekQsS0FBSztBQUNMO0FBQ0EsSUFBSSxTQUFTLENBQUMsQ0FBQyxjQUFjO0FBQzdCLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUVzZCxRQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3BELEtBQUs7QUFDTDtBQUNBLElBQUksT0FBTyxDQUFDLENBQUMsY0FBYztBQUMzQixRQUFRLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzFDLFFBQVEsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzlELFFBQVEsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBQ3ZCLEtBQUs7QUFDTDtBQUNBLElBQUksVUFBVSxDQUFDLENBQUMsY0FBYztBQUM5QixRQUFRLElBQUksQ0FBQyxDQUFDLGFBQWEsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO0FBQzFDLFlBQVksSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO0FBQ3pCLFNBQVMsTUFBTTtBQUNmLFlBQVksSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsUUFBUSxHQUFHQyxRQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDNUYsWUFBWSxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUMsSUFBSSxFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFFLE1BQU0sQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDLHFCQUFxQixJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDcEosU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBLElBQUksU0FBUyxDQUFDLENBQUMsY0FBYztBQUM3QixRQUFRLElBQUksQ0FBQyxDQUFDLGFBQWEsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO0FBQzFDLFlBQVksSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO0FBQ3pCLFNBQVMsTUFBTTtBQUNmLFlBQVksSUFBSSxDQUFDLFFBQVEsR0FBR0EsUUFBWSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNFLFlBQVksSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLGNBQWMsRUFBRSxNQUFNLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxxQkFBcUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ3RHLFNBQVM7QUFDVCxLQUFLO0FBQ0w7QUFDQSxJQUFJLFFBQVEsQ0FBQyxDQUFDLGNBQWM7QUFDNUIsUUFBUSxJQUFJLENBQUMsQ0FBQyxhQUFhLENBQUMsTUFBTSxLQUFLLENBQUM7QUFDeEMsWUFBWSxJQUFJLENBQUMsU0FBUztBQUMxQixZQUFZLElBQUksQ0FBQyxRQUFRO0FBQ3pCLFlBQVksSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLElBQUksQ0FBQyxlQUFlLEVBQUU7QUFDdkUsWUFBWSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO0FBQ2pDLFNBQVM7QUFDVCxRQUFRLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztBQUNyQixLQUFLO0FBQ0w7QUFDQSxJQUFJLEtBQUssR0FBRztBQUNaLFFBQVEsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztBQUNqQyxRQUFRLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO0FBQ3JELFFBQVEsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO0FBQzlCLFFBQVEsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDO0FBQzdCLFFBQVEsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBQ3ZCLEtBQUs7QUFDTCxDQUFBOztBQ3pTQTtBQUNBO0FBVUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU1PLGdCQUFjLEdBQUc7QUFDdkIsSUFBSSxlQUFlLEVBQUU7QUFDckIsUUFBUSxrQkFBa0IsRUFBRSxLQUFLO0FBQ2pDLFFBQVEsVUFBVSxFQUFFLENBQUM7QUFDckIsUUFBUSxPQUFPLEVBQUUsSUFBSTtBQUNyQixLQUFLO0FBQ0wsSUFBSSxnQkFBZ0IsRUFBRTtBQUN0QixRQUFRLE9BQU8sRUFBRSxFQUFFO0FBQ25CLEtBQUs7QUFDTCxJQUFJLGlCQUFpQixFQUFFLEtBQUs7QUFDNUIsSUFBSSxrQkFBa0IsRUFBRSxJQUFJO0FBQzVCLElBQUksZ0JBQWdCLEVBQUUsSUFBSTtBQUMxQixJQUFJLGVBQWUsRUFBRSxLQUFLO0FBQzFCLENBQUMsQ0FBQztBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNLGdCQUFnQixTQUFTcE0sS0FBQUEsQ0FBQUEsT0FBTyxDQUFDO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksV0FBVyxDQUFDLE9BQU8sbUJBQW1CO0FBQzFDLFFBQVEsS0FBSyxFQUFFLENBQUM7QUFDaEIsUUFBUSxNQUFNLFdBQVcsR0FBRzFSLEtBQUFBLENBQUFBLE1BQU0sQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDO0FBQ3pELFFBQVEsSUFBSSxDQUFDLE9BQU8sR0FBR1csWUFBTSxDQUFDLENBQUMsV0FBVyxDQUFDLEVBQUVtZCxnQkFBYyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQ3RFO0FBQ0EsUUFBUTlJLGFBQU8sQ0FBQztBQUNoQixZQUFZLFlBQVk7QUFDeEIsWUFBWSxVQUFVO0FBQ3RCLFlBQVksU0FBUztBQUNyQixZQUFZLFNBQVM7QUFDckIsWUFBWSxVQUFVO0FBQ3RCLFlBQVksZUFBZTtBQUMzQixZQUFZLGVBQWU7QUFDM0IsWUFBWSx1QkFBdUI7QUFDbkMsWUFBWSxzQkFBc0I7QUFDbEMsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ2pCO0FBQ0E7QUFDQSxRQUFRLElBQUksQ0FBQyw4QkFBOEIsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLHFCQUFxQixFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ3ZGLFFBQVEsSUFBSSxDQUFDLGdCQUFnQixHQUFHLENBQUMsQ0FBQztBQUNsQyxLQUFLO0FBQ0w7QUFDQSxJQUFJLEtBQUssQ0FBQyxHQUFHLG9CQUFvQjtBQUNqQyxRQUFRLElBQUksQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDO0FBQ3hCLFFBQVEsSUFBSSxDQUFDLFVBQVUsR0FBR3lJLFFBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDLENBQUM7QUFDakY7QUFDQSxRQUFRLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDckQsUUFBUSxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUM7QUFDL0IsS0FBSztBQUNMO0FBQ0EsSUFBSSxRQUFRLEdBQUc7QUFDZjtBQUNBLFFBQVEsSUFBSSxJQUFJLENBQUMsbUJBQW1CLEtBQUssU0FBUyxFQUFFO0FBQ3BELFlBQVksSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0FBQzFFLFlBQVksSUFBSSxDQUFDLG1CQUFtQixJQUFJLFNBQVMsTUFBTSxDQUFDO0FBQ3hELFNBQVM7QUFDVDtBQUNBO0FBQ0EsUUFBUSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLElBQUksSUFBSSxDQUFDLHNCQUFzQixFQUFFO0FBQzFFLFlBQVksSUFBSSxDQUFDLHNCQUFzQixDQUFDLE1BQU0sRUFBRSxDQUFDO0FBQ2pELFNBQVM7QUFDVCxRQUFRLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsSUFBSSxJQUFJLENBQUMscUJBQXFCLEVBQUU7QUFDM0UsWUFBWSxJQUFJLENBQUMscUJBQXFCLENBQUMsTUFBTSxFQUFFLENBQUM7QUFDaEQsU0FBUztBQUNUO0FBQ0EsUUFBUSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDO0FBQ2pDO0FBQ0EsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQzVDLFFBQVEsSUFBSSxDQUFDLElBQUksSUFBSSxTQUFTLE1BQU0sQ0FBQztBQUNyQyxRQUFRLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7QUFDbEMsUUFBUSxJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztBQUNoQyxLQUFLO0FBQ0w7QUFDQSxJQUFJLHdCQUF3QixDQUFDLFFBQVEsbUJBQW1CO0FBQ3hELFFBQVEsTUFBTSxhQUFhLEdBQUcsQ0FBQyxTQUFTLFlBQVksQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxLQUFLO0FBQ25GLFlBQVksSUFBSSxDQUFDLG9CQUFvQixHQUFHLFNBQVMsQ0FBQztBQUNsRCxZQUFZLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUNoQyxTQUFTLENBQUM7QUFDVjtBQUNBLFFBQVEsSUFBSSxJQUFJLENBQUMsb0JBQW9CLEtBQUssU0FBUyxFQUFFO0FBQ3JELFlBQVksUUFBUSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0FBQ2hEO0FBQ0EsU0FBUyxNQUFNLElBQUl6ZCxLQUFNLENBQUEsTUFBQSxDQUFDLFNBQVMsQ0FBQyxXQUFXLEtBQUssU0FBUyxFQUFFO0FBQy9EO0FBQ0E7QUFDQTtBQUNBLFlBQVlBLEtBQU0sQ0FBQSxNQUFBLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLEVBQUUsYUFBYSxDQUFDLENBQUM7QUFDckUsaUJBQWlCLElBQUksQ0FBQyxDQUFDLElBQUksYUFBYSxDQUFDLENBQUMsQ0FBQyxLQUFLLEtBQUssUUFBUSxDQUFDLENBQUM7QUFDL0QsaUJBQWlCLEtBQUssQ0FBQyxNQUFNLGFBQWEsRUFBRSxDQUFDLENBQUM7QUFDOUM7QUFDQSxTQUFTLE1BQU07QUFDZixZQUFZLGFBQWEsRUFBRSxDQUFDO0FBQzVCLFNBQVM7QUFDVCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksb0JBQW9CLENBQUMsUUFBUSxxQkFBcUI7QUFDdEQsUUFBUSxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO0FBQ2hELFFBQVEsTUFBTSxXQUFXLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQztBQUM1QztBQUNBLFFBQVEsT0FBTyxDQUFDLENBQUMsTUFBTTtBQUN2QixZQUFZLFdBQVcsQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDLE9BQU8sRUFBRTtBQUNwRCxZQUFZLFdBQVcsQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDLE9BQU8sRUFBRTtBQUNwRCxZQUFZLFdBQVcsQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLFFBQVEsRUFBRTtBQUNwRCxZQUFZLFdBQVcsQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLFFBQVEsRUFBRTtBQUNwRCxTQUFTLENBQUM7QUFDVixLQUFLO0FBQ0w7QUFDQSxJQUFJLGNBQWMsR0FBRztBQUNyQixRQUFRLFFBQVEsSUFBSSxDQUFDLFdBQVc7QUFDaEMsUUFBUSxLQUFLLGdCQUFnQjtBQUM3QixZQUFZLElBQUksQ0FBQyxXQUFXLEdBQUcsY0FBYyxDQUFDO0FBQzlDLFlBQVksSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztBQUNyRixZQUFZLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLHNDQUFzQyxDQUFDLENBQUM7QUFDeEYsWUFBWSxNQUFNO0FBQ2xCLFFBQVEsS0FBSyxhQUFhO0FBQzFCLFlBQVksSUFBSSxDQUFDLFdBQVcsR0FBRyxjQUFjLENBQUM7QUFDOUMsWUFBWSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO0FBQ3JGLFlBQVksSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsc0NBQXNDLENBQUMsQ0FBQztBQUN4RixZQUFZLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLGlDQUFpQyxDQUFDLENBQUM7QUFDbkY7QUFDQSxZQUFZLE1BQU07QUFDbEIsUUFBUSxLQUFLLFlBQVk7QUFDekIsWUFBWSxJQUFJLENBQUMsV0FBVyxHQUFHLGtCQUFrQixDQUFDO0FBQ2xELFlBQVksSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsb0NBQW9DLENBQUMsQ0FBQztBQUN6RixZQUFZLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLDBDQUEwQyxDQUFDLENBQUM7QUFDNUYsWUFBWSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO0FBQ25GO0FBQ0EsWUFBWSxNQUFNO0FBQ2xCLFFBQVEsS0FBSyxjQUFjO0FBQzNCLFlBQVksTUFBTTtBQUNsQixRQUFRO0FBQ1IsWUFBWVEsS0FBTSxDQUFBLE1BQUEsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxzQkFBc0IsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZFLFNBQVM7QUFDVCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLFVBQVUsQ0FBQyxRQUFRLFlBQVk7QUFDbkMsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRTtBQUN4QjtBQUNBLFlBQVksT0FBTztBQUNuQixTQUFTO0FBQ1Q7QUFDQSxRQUFRLElBQUksSUFBSSxDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxFQUFFO0FBQ2pELFlBQVksSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO0FBQ2xDO0FBQ0EsWUFBWSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUk2USxLQUFBQSxDQUFBQSxLQUFLLENBQUMsZ0JBQWdCLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQztBQUM3RCxZQUFZLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztBQUNqQyxZQUFZLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztBQUMzQjtBQUNBLFlBQVksT0FBTztBQUNuQixTQUFTO0FBQ1Q7QUFDQSxRQUFRLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsRUFBRTtBQUM1QztBQUNBO0FBQ0E7QUFDQSxZQUFZLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxRQUFRLENBQUM7QUFDL0M7QUFDQSxZQUFZLFFBQVEsSUFBSSxDQUFDLFdBQVc7QUFDcEMsWUFBWSxLQUFLLGdCQUFnQixDQUFDO0FBQ2xDLFlBQVksS0FBSyxhQUFhLENBQUM7QUFDL0IsWUFBWSxLQUFLLGNBQWM7QUFDL0IsZ0JBQWdCLElBQUksQ0FBQyxXQUFXLEdBQUcsYUFBYSxDQUFDO0FBQ2pELGdCQUFnQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO0FBQzFGLGdCQUFnQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO0FBQy9GLGdCQUFnQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO0FBQ3RGLGdCQUFnQixNQUFNO0FBQ3RCLFlBQVksS0FBSyxZQUFZLENBQUM7QUFDOUIsWUFBWSxLQUFLLGtCQUFrQjtBQUNuQyxnQkFBZ0IsSUFBSSxDQUFDLFdBQVcsR0FBRyxZQUFZLENBQUM7QUFDaEQsZ0JBQWdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLGlDQUFpQyxDQUFDLENBQUM7QUFDMUYsZ0JBQWdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLDBDQUEwQyxDQUFDLENBQUM7QUFDbkcsZ0JBQWdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLG9DQUFvQyxDQUFDLENBQUM7QUFDMUYsZ0JBQWdCLE1BQU07QUFDdEIsWUFBWTtBQUNaLGdCQUFnQjdRLEtBQU0sQ0FBQSxNQUFBLENBQUMsS0FBSyxFQUFFLENBQUMsc0JBQXNCLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMzRSxhQUFhO0FBQ2IsU0FBUztBQUNUO0FBQ0E7QUFDQSxRQUFRLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsV0FBVyxLQUFLLEtBQUssRUFBRTtBQUN6RSxZQUFZLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDekMsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsaUJBQWlCLElBQUksSUFBSSxDQUFDLFdBQVcsS0FBSyxhQUFhLEVBQUU7QUFDbkYsWUFBWSxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ3pDLFNBQVM7QUFDVDtBQUNBLFFBQVEsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQixFQUFFO0FBQzNDLFlBQVksSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLGtDQUFrQyxDQUFDLENBQUM7QUFDbEYsU0FBUztBQUNUO0FBQ0EsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUk2USxLQUFBQSxDQUFBQSxLQUFLLENBQUMsV0FBVyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7QUFDcEQsUUFBUSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7QUFDdkIsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxhQUFhLENBQUMsUUFBUSxZQUFZO0FBQ3RDLFFBQVEsTUFBTSxNQUFNLEdBQUcsSUFBSW5OLEtBQU0sQ0FBQSxNQUFBLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUN2RixRQUFRLE1BQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDO0FBQ2hELFFBQVEsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztBQUMvQyxRQUFRLE1BQU0sT0FBTyxHQUFHdkQsS0FBQUEsQ0FBQUEsTUFBTSxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0FBQ3pFO0FBQ0EsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLE9BQU8sRUFBRTtBQUM5RCxZQUFZLGVBQWUsRUFBRSxJQUFJO0FBQ2pDLFNBQVMsQ0FBQyxDQUFDO0FBQ1gsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxhQUFhLENBQUMsUUFBUSxhQUFhO0FBQ3ZDLFFBQVEsSUFBSSxRQUFRLEVBQUU7QUFDdEIsWUFBWSxNQUFNLE1BQU0sR0FBRyxJQUFJdUQsS0FBTSxDQUFBLE1BQUEsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxRQUFRLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQzNGLFlBQVksSUFBSSxDQUFDLHFCQUFxQixDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQzFFLFlBQVksSUFBSSxDQUFDLHNCQUFzQixDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQzNFLFlBQVksSUFBSSxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQztBQUN0RCxZQUFZLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLGtCQUFrQixFQUFFO0FBQ2xGLGdCQUFnQixJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztBQUMzQyxhQUFhO0FBQ2IsU0FBUyxNQUFNO0FBQ2YsWUFBWSxJQUFJLENBQUMsc0JBQXNCLENBQUMsTUFBTSxFQUFFLENBQUM7QUFDakQsWUFBWSxJQUFJLENBQUMscUJBQXFCLENBQUMsTUFBTSxFQUFFLENBQUM7QUFDaEQsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBLElBQUksbUJBQW1CLEdBQUc7QUFDMUIsUUFBUTFELFlBQU0sQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7QUFDcEMsUUFBUSxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO0FBQzlCLFFBQVEsTUFBTSxFQUFFLEdBQUcsR0FBRyxDQUFDLFNBQVMsQ0FBQztBQUNqQztBQUNBLFFBQVEsTUFBTSxjQUFjLEdBQUc0WSxLQUFxQixDQUFBLHFCQUFBLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQztBQUN6RixRQUFRNVksWUFBTSxDQUFDLGNBQWMsS0FBSyxHQUFHLENBQUMsQ0FBQztBQUN2QyxRQUFRLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxTQUFTLEdBQUcsY0FBYyxDQUFDLENBQUM7QUFDaEY7QUFDQSxRQUFRLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUUsY0FBYyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2hFLFFBQVEsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxjQUFjLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDakUsS0FBSztBQUNMO0FBQ0EsSUFBSSxPQUFPLEdBQUc7QUFDZCxRQUFRLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLGtCQUFrQixFQUFFO0FBQzlFLFlBQVksSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7QUFDdkMsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLHFCQUFxQixHQUFHO0FBQzVCLFFBQVEsSUFBSSxJQUFJLENBQUMsc0JBQXNCLElBQUksT0FBTyxJQUFJLENBQUMsUUFBUSxLQUFLLFFBQVEsRUFBRTtBQUM5RSxZQUFZLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ25FLFlBQVksSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLHFDQUFxQyxDQUFDLENBQUM7QUFDbEYsU0FBUyxNQUFNO0FBQ2YsWUFBWSxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMscUNBQXFDLENBQUMsQ0FBQztBQUNyRixZQUFZLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkQsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBLElBQUksUUFBUSxDQUFDLEtBQUssaUJBQWlCO0FBQ25DLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUU7QUFDeEI7QUFDQSxZQUFZLE9BQU87QUFDbkIsU0FBUztBQUNUO0FBQ0EsUUFBUSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsaUJBQWlCLEVBQUU7QUFDNUMsWUFBWSxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssQ0FBQyxFQUFFO0FBQ2xDO0FBQ0EsZ0JBQWdCLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO0FBQ3pDLGdCQUFnQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO0FBQzFGLGdCQUFnQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO0FBQ3pGLGdCQUFnQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO0FBQy9GLGdCQUFnQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFDO0FBQzdGLGdCQUFnQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQywwQ0FBMEMsQ0FBQyxDQUFDO0FBQ25HLGdCQUFnQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztBQUN0RCxnQkFBZ0IsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsdUNBQXVDLENBQUMsQ0FBQztBQUM5RixnQkFBZ0IsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxZQUFZLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDeEUsZ0JBQWdCLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLGlCQUFpQixFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ2xJO0FBQ0EsZ0JBQWdCLElBQUksSUFBSSxDQUFDLG1CQUFtQixLQUFLLFNBQVMsRUFBRTtBQUM1RCxvQkFBb0IsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO0FBQ3ZDLGlCQUFpQjtBQUNqQixhQUFhLE1BQU0sSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFO0FBQzVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLE9BQU87QUFDdkIsYUFBYSxNQUFNO0FBQ25CLGdCQUFnQixJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7QUFDdEMsYUFBYTtBQUNiLFNBQVM7QUFDVDtBQUNBLFFBQVEsSUFBSSxJQUFJLENBQUMsV0FBVyxLQUFLLEtBQUssSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQixFQUFFO0FBQ3pFLFlBQVksSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLGtDQUFrQyxDQUFDLENBQUM7QUFDL0UsU0FBUztBQUNUO0FBQ0EsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUk2USxLQUFBQSxDQUFBQSxLQUFLLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDN0M7QUFDQSxRQUFRLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztBQUN2QixLQUFLO0FBQ0w7QUFDQSxJQUFJLE9BQU8sR0FBRztBQUNkLFFBQVEsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLEVBQUUsWUFBWSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUFFO0FBQy9ELFFBQVEsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUM7QUFDcEMsS0FBSztBQUNMO0FBQ0EsSUFBSSxRQUFRLENBQUMsU0FBUyxXQUFXO0FBQ2pDLFFBQVEsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLFNBQVMsRUFBRTtBQUNyQztBQUNBO0FBQ0EsWUFBWSxPQUFPO0FBQ25CLFNBQVM7QUFDVCxRQUFRLElBQUksQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxFQUFFLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUM7QUFDL0YsUUFBUSxJQUFJLENBQUMsZ0JBQWdCLEdBQUdvTSxRQUFVLENBQUMsUUFBUSxFQUFFLENBQUMsdUJBQXVCLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDakcsUUFBUUEsUUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLGtCQUFrQixDQUFDLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsWUFBWSxDQUFDLGFBQWEsRUFBRSxNQUFNLENBQUMsQ0FBQztBQUM1RztBQUNBLFFBQVEsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksR0FBRyxRQUFRLENBQUM7QUFDOUM7QUFDQSxRQUFRLElBQUksU0FBUyxLQUFLLEtBQUssRUFBRTtBQUNqQyxZQUFZN0wsS0FBUSxDQUFBLFFBQUEsQ0FBQyxnRkFBZ0YsQ0FBQyxDQUFDO0FBQ3ZHLFlBQVksTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsdUNBQXVDLENBQUMsQ0FBQztBQUMxRixZQUFZLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO0FBQ2xELFlBQVksSUFBSSxDQUFDLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxZQUFZLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDcEUsWUFBWSxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxpQkFBaUIsRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsaUJBQWlCLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztBQUM5SCxTQUFTLE1BQU07QUFDZixZQUFZLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLGlDQUFpQyxDQUFDLENBQUM7QUFDcEYsWUFBWSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxDQUFDLFlBQVksRUFBRSxLQUFLLENBQUMsQ0FBQztBQUNwRSxZQUFZLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLGlCQUFpQixFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQzlILFNBQVM7QUFDVDtBQUNBLFFBQVEsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLGlCQUFpQixFQUFFO0FBQzVDLFlBQVksSUFBSSxDQUFDLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxjQUFjLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDeEUsWUFBWSxJQUFJLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztBQUNyQyxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFFBQVEsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQixFQUFFO0FBQzNDLFlBQVksSUFBSSxDQUFDLFdBQVcsR0FBRzZMLFFBQVUsQ0FBQyxLQUFLLEVBQUUsd0JBQXdCLENBQUMsQ0FBQztBQUMzRSxZQUFZLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDQSxRQUFVLENBQUMsS0FBSyxFQUFFLDRCQUE0QixDQUFDLENBQUMsQ0FBQztBQUMxRixZQUFZLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDQSxRQUFVLENBQUMsS0FBSyxFQUFFLGdDQUFnQyxDQUFDLENBQUMsQ0FBQztBQUM5RjtBQUNBLFlBQVksSUFBSSxDQUFDLHNCQUFzQixHQUFHLElBQUksTUFBTSxDQUFDO0FBQ3JELGdCQUFnQixPQUFPLEVBQUUsSUFBSSxDQUFDLFdBQVc7QUFDekMsZ0JBQWdCLGlCQUFpQixFQUFFLEtBQUs7QUFDeEMsZ0JBQWdCLGNBQWMsRUFBRSxLQUFLO0FBQ3JDLGFBQWEsQ0FBQyxDQUFDO0FBQ2Y7QUFDQSxZQUFZLElBQUksQ0FBQyxjQUFjLEdBQUdBLFFBQVUsQ0FBQyxLQUFLLEVBQUUsd0NBQXdDLENBQUMsQ0FBQztBQUM5RixZQUFZLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsY0FBYyxFQUFFLGNBQWMsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQzNHO0FBQ0EsWUFBWSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7QUFDekU7QUFDQTtBQUNBLFlBQVksSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUMvQyxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFFBQVEsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ2pGO0FBQ0EsUUFBUSxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztBQUMzQjtBQUNBO0FBQ0E7QUFDQSxRQUFRLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsRUFBRTtBQUM1QyxZQUFZLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDLEtBQUssS0FBSztBQUNqRCxnQkFBZ0IsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLGFBQWEsSUFBSSxLQUFLLENBQUMsYUFBYSxDQUFDLElBQUksS0FBSyxRQUFRLENBQUM7QUFDaEcsZ0JBQWdCLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxJQUFJLElBQUksQ0FBQyxXQUFXLEtBQUssYUFBYSxJQUFJLENBQUMsVUFBVSxFQUFFO0FBQ2pHLG9CQUFvQixJQUFJLENBQUMsV0FBVyxHQUFHLFlBQVksQ0FBQztBQUNwRCxvQkFBb0IsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsb0NBQW9DLENBQUMsQ0FBQztBQUM5RixvQkFBb0IsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztBQUM3RjtBQUNBLG9CQUFvQixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUlwTSxXQUFLLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDO0FBQ2pFLGlCQUFpQjtBQUNqQixhQUFhLENBQUMsQ0FBQztBQUNmLFNBQVM7QUFDVCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksb0JBQW9CLENBQUMsc0JBQXNCLDBCQUEwQjtBQUN6RTtBQUNBLFFBQVEsSUFBSSxJQUFJLENBQUMsc0JBQXNCLEVBQUU7QUFDekMsWUFBWSxJQUFJLHNCQUFzQixDQUFDLG9CQUFvQixFQUFFO0FBQzdEO0FBQ0EsZ0JBQWdCLElBQUksQ0FBQyxRQUFRLEdBQUcsc0JBQXNCLENBQUMsb0JBQW9CLENBQUM7QUFDNUUsYUFBYSxNQUFNLElBQUksc0JBQXNCLENBQUMsUUFBUSxLQUFLLElBQUksRUFBRTtBQUNqRTtBQUNBLGdCQUFnQixJQUFJLENBQUMsUUFBUSxHQUFHLHNCQUFzQixDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNsRSxhQUFhO0FBQ2IsWUFBWSxJQUFJLENBQUMsOEJBQThCLEVBQUUsQ0FBQztBQUNsRCxTQUFTO0FBQ1QsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxPQUFPLFlBQVk7QUFDdkIsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRTtBQUMxQixZQUFZTyxLQUFRLENBQUEsUUFBQSxDQUFDLG1EQUFtRCxDQUFDLENBQUM7QUFDMUUsWUFBWSxPQUFPLEtBQUssQ0FBQztBQUN6QixTQUFTO0FBQ1QsUUFBUSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsaUJBQWlCLEVBQUU7QUFDNUM7QUFDQSxZQUFZLFFBQVEsSUFBSSxDQUFDLFdBQVc7QUFDcEMsWUFBWSxLQUFLLEtBQUs7QUFDdEI7QUFDQSxnQkFBZ0IsSUFBSSxDQUFDLFdBQVcsR0FBRyxnQkFBZ0IsQ0FBQztBQUNwRDtBQUNBLGdCQUFnQixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUlQLFdBQUssQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDLENBQUM7QUFDL0QsZ0JBQWdCLE1BQU07QUFDdEIsWUFBWSxLQUFLLGdCQUFnQixDQUFDO0FBQ2xDLFlBQVksS0FBSyxhQUFhLENBQUM7QUFDL0IsWUFBWSxLQUFLLGNBQWMsQ0FBQztBQUNoQyxZQUFZLEtBQUssa0JBQWtCO0FBQ25DO0FBQ0EsZ0JBQWdCLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO0FBQ3hDLGdCQUFnQixJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztBQUN4QyxnQkFBZ0IsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7QUFDekMsZ0JBQWdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLGlDQUFpQyxDQUFDLENBQUM7QUFDMUYsZ0JBQWdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLGdDQUFnQyxDQUFDLENBQUM7QUFDekYsZ0JBQWdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLHNDQUFzQyxDQUFDLENBQUM7QUFDL0YsZ0JBQWdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLG9DQUFvQyxDQUFDLENBQUM7QUFDN0YsZ0JBQWdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLDBDQUEwQyxDQUFDLENBQUM7QUFDbkc7QUFDQSxnQkFBZ0IsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJQSxXQUFLLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDO0FBQzdELGdCQUFnQixNQUFNO0FBQ3RCLFlBQVksS0FBSyxZQUFZO0FBQzdCLGdCQUFnQixJQUFJLENBQUMsV0FBVyxHQUFHLGFBQWEsQ0FBQztBQUNqRCxnQkFBZ0IsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsb0NBQW9DLENBQUMsQ0FBQztBQUM3RjtBQUNBLGdCQUFnQixJQUFJLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0FBQ3pGO0FBQ0EsZ0JBQWdCLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSUEsV0FBSyxDQUFDLHdCQUF3QixDQUFDLENBQUMsQ0FBQztBQUMvRCxnQkFBZ0IsTUFBTTtBQUN0QixZQUFZO0FBQ1osZ0JBQWdCN1EsS0FBTSxDQUFBLE1BQUEsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxzQkFBc0IsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNFLGFBQWE7QUFDYjtBQUNBO0FBQ0EsWUFBWSxRQUFRLElBQUksQ0FBQyxXQUFXO0FBQ3BDLFlBQVksS0FBSyxnQkFBZ0I7QUFDakMsZ0JBQWdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLGlDQUFpQyxDQUFDLENBQUM7QUFDdkYsZ0JBQWdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLGdDQUFnQyxDQUFDLENBQUM7QUFDdEYsZ0JBQWdCLE1BQU07QUFDdEIsWUFBWSxLQUFLLGFBQWE7QUFDOUIsZ0JBQWdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLGdDQUFnQyxDQUFDLENBQUM7QUFDdEYsZ0JBQWdCLE1BQU07QUFDdEIsWUFBWSxLQUFLLGNBQWM7QUFDL0IsZ0JBQWdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLGlDQUFpQyxDQUFDLENBQUM7QUFDdkYsZ0JBQWdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLHNDQUFzQyxDQUFDLENBQUM7QUFDNUYsZ0JBQWdCLE1BQU07QUFDdEIsWUFBWSxLQUFLLFlBQVk7QUFDN0IsZ0JBQWdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLG9DQUFvQyxDQUFDLENBQUM7QUFDMUYsZ0JBQWdCLE1BQU07QUFDdEIsWUFBWSxLQUFLLGtCQUFrQjtBQUNuQyxnQkFBZ0IsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsaUNBQWlDLENBQUMsQ0FBQztBQUN2RixnQkFBZ0IsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsMENBQTBDLENBQUMsQ0FBQztBQUNoRyxnQkFBZ0IsTUFBTTtBQUN0QixZQUFZLEtBQUssS0FBSztBQUN0QixnQkFBZ0IsTUFBTTtBQUN0QixZQUFZO0FBQ1osZ0JBQWdCQSxLQUFNLENBQUEsTUFBQSxDQUFDLEtBQUssRUFBRSxDQUFDLHNCQUFzQixFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDM0UsYUFBYTtBQUNiO0FBQ0E7QUFDQSxZQUFZLElBQUksSUFBSSxDQUFDLFdBQVcsS0FBSyxLQUFLLElBQUksSUFBSSxDQUFDLG1CQUFtQixLQUFLLFNBQVMsRUFBRTtBQUN0RjtBQUNBLGdCQUFnQixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7QUFDbkMsYUFBYSxNQUFNLElBQUksSUFBSSxDQUFDLG1CQUFtQixLQUFLLFNBQVMsRUFBRTtBQUMvRDtBQUNBO0FBQ0EsZ0JBQWdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLGlDQUFpQyxDQUFDLENBQUM7QUFDdkYsZ0JBQWdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsY0FBYyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQzNFO0FBQ0EsZ0JBQWdCLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO0FBQ3hDLGdCQUFnQixJQUFJLGVBQWUsQ0FBQztBQUNwQyxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsQ0FBQyxFQUFFO0FBQy9DLG9CQUFvQixlQUFlLEdBQUcsQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNyRSxvQkFBb0IsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7QUFDM0MsaUJBQWlCLE1BQU07QUFDdkIsb0JBQW9CLGVBQWUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQztBQUNuRSxvQkFBb0IsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7QUFDNUMsaUJBQWlCO0FBQ2pCO0FBQ0EsZ0JBQWdCLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxhQUFhO0FBQ2pGLG9CQUFvQixJQUFJLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsZUFBZSxDQUFDLENBQUM7QUFDckU7QUFDQSxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRTtBQUNsRCxvQkFBb0IsSUFBSSxDQUFDLDZCQUE2QixFQUFFLENBQUM7QUFDekQsaUJBQWlCO0FBQ2pCLGFBQWE7QUFDYixTQUFTLE1BQU07QUFDZjtBQUNBLFlBQVksSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDLENBQUM7QUFDdEg7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSyxhQUFhLENBQUM7QUFDMUUsU0FBUztBQUNUO0FBQ0EsUUFBUSxPQUFPLElBQUksQ0FBQztBQUNwQixLQUFLO0FBQ0w7QUFDQSxJQUFJLDZCQUE2QixHQUFHO0FBQ3BDLFFBQVEsTUFBTSxXQUFXLEdBQUcsTUFBTTtBQUNsQyxZQUFZLElBQUksNkJBQTZCLElBQUlSLEtBQUFBLENBQUFBLE1BQU0sRUFBRTtBQUN6RDtBQUNBLGdCQUFnQkEsS0FBQUEsQ0FBQUEsTUFBTSxDQUFDLGdCQUFnQixDQUFDLDJCQUEyQixFQUFFLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0FBQ2hHLGFBQWEsTUFBTTtBQUNuQjtBQUNBLGdCQUFnQkEsS0FBQUEsQ0FBQUEsTUFBTSxDQUFDLGdCQUFnQixDQUFDLG1CQUFtQixFQUFFLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0FBQ3hGLGFBQWE7QUFDYixTQUFTLENBQUM7QUFDVjtBQUNBLFFBQVEsSUFBSSxPQUFPQSxLQUFBQSxDQUFBQSxNQUFNLENBQUMsaUJBQWlCLEtBQUssV0FBVztBQUMzRCxZQUFZLE9BQU9BLFlBQU0sQ0FBQyxpQkFBaUIsQ0FBQyxpQkFBaUIsS0FBSyxVQUFVLEVBQUU7QUFDOUU7QUFDQSxZQUFZLHNCQUFzQixDQUFDLGlCQUFpQixFQUFFO0FBQ3RELGlCQUFpQixJQUFJLENBQUMsUUFBUSxJQUFJO0FBQ2xDLG9CQUFvQixJQUFJLFFBQVEsS0FBSyxTQUFTLEVBQUU7QUFDaEQsd0JBQXdCLFdBQVcsRUFBRSxDQUFDO0FBQ3RDLHFCQUFxQjtBQUNyQixpQkFBaUIsQ0FBQztBQUNsQixpQkFBaUIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUN0QyxTQUFTLE1BQU07QUFDZixZQUFZLFdBQVcsRUFBRSxDQUFDO0FBQzFCLFNBQVM7QUFDVCxLQUFLO0FBQ0w7QUFDQSxJQUFJLFdBQVcsR0FBRztBQUNsQixRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsQ0FBQztBQUN0RTtBQUNBO0FBQ0EsUUFBUUEsS0FBQUEsQ0FBQUEsTUFBTSxDQUFDLG1CQUFtQixDQUFDLG1CQUFtQixFQUFFLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0FBQ25GO0FBQ0EsUUFBUUEsS0FBQUEsQ0FBQUEsTUFBTSxDQUFDLG1CQUFtQixDQUFDLDJCQUEyQixFQUFFLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0FBQzNGO0FBQ0EsUUFBUSxJQUFJLENBQUMsbUJBQW1CLElBQUksU0FBUyxNQUFNLENBQUM7QUFDcEQsUUFBUSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO0FBQ2xGLFFBQVEsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxjQUFjLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDcEU7QUFDQSxRQUFRLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRTtBQUMzQyxZQUFZLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDckMsU0FBUztBQUNULEtBQUs7QUFDTCxDQUFDO0FBR0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0MEJBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU0sY0FBYyxZQUFZO0FBQ2hDLElBQUksUUFBUSxFQUFFLEdBQUc7QUFDakIsSUFBSSxJQUFJLEVBQUUsUUFBUTtBQUNsQixDQUFDLENBQUM7QUFDRjtBQUNBLE1BQU0sUUFBUSxHQUFHO0FBQ2pCLElBQUksU0FBUyxFQUFFLElBQUk7QUFDbkIsSUFBSSxLQUFLLEVBQUUsR0FBRztBQUNkLElBQUksSUFBSSxFQUFFLElBQUk7QUFDZCxJQUFJLElBQUksRUFBRSxJQUFJO0FBQ2QsSUFBSSxlQUFlLEVBQUUsSUFBSTtBQUN6QixDQUFDLENBQUM7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNLFlBQVksQ0FBQztBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLFdBQVcsQ0FBQyxPQUFPLFdBQVc7QUFDbEMsUUFBUSxJQUFJLENBQUMsT0FBTyxHQUFHVyxLQUFNLENBQUEsTUFBQSxDQUFDLEVBQUUsRUFBRSxjQUFjLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDM0Q7QUFDQTtBQUNBO0FBQ0EsUUFBUSxJQUFJLENBQUMsd0JBQXdCLEdBQUcsdUJBQXVCLEVBQUUsQ0FBQztBQUNsRTtBQUNBLFFBQVFxVSxhQUFPLENBQUM7QUFDaEIsWUFBWSxTQUFTO0FBQ3JCLFlBQVksV0FBVztBQUN2QixZQUFZLFNBQVM7QUFDckIsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ2pCLEtBQUs7QUFDTDtBQUNBLElBQUksa0JBQWtCLG9CQUFvQjtBQUMxQyxRQUFRLE9BQU8sYUFBYSxDQUFDO0FBQzdCLEtBQUs7QUFDTDtBQUNBLElBQUksT0FBTyxHQUFHO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxJQUFJLEdBQUcsQ0FBQztBQUN0RDtBQUNBLFFBQVEsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztBQUM5QixRQUFRLE1BQU0sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7QUFDM0MsUUFBUSxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxlQUFlLEdBQUcsQ0FBQyxJQUFJLFFBQVEsR0FBRyxDQUFDLENBQUM7QUFDM0QsUUFBUSxNQUFNLElBQUksR0FBRyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDM0MsUUFBUSxNQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZELFFBQVEsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNqRDtBQUNBO0FBQ0E7QUFDQSxRQUFRLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEtBQUssVUFBVSxFQUFFO0FBQzlDLFlBQVksTUFBTSxPQUFPLEdBQUcsTUFBTSxHQUFHLFNBQVMsQ0FBQztBQUMvQyxZQUFZLElBQUksT0FBTyxHQUFHLElBQUksRUFBRTtBQUNoQyxnQkFBZ0IsTUFBTSxRQUFRLEdBQUcsT0FBTyxHQUFHLElBQUksQ0FBQztBQUNoRCxnQkFBZ0IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQzNELGFBQWEsTUFBTTtBQUNuQixnQkFBZ0IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQzFELGFBQWE7QUFDYixTQUFTLE1BQU0sSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksS0FBSyxVQUFVLEVBQUU7QUFDckQsWUFBWSxNQUFNLFlBQVksR0FBRyxTQUFTLEdBQUcsSUFBSSxDQUFDO0FBQ2xELFlBQVksSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsWUFBWSxFQUFFLGVBQWUsQ0FBQyxDQUFDO0FBQ3BFLFNBQVMsTUFBTSxJQUFJLFNBQVMsSUFBSSxJQUFJLEVBQUU7QUFDdEMsWUFBWSxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxTQUFTLEdBQUcsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0FBQ3BFLFNBQVMsTUFBTTtBQUNmLFlBQVksSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQ3pELFNBQVM7QUFDVCxLQUFLO0FBQ0w7QUFDQSxJQUFJLFNBQVMsQ0FBQyxRQUFRLFVBQVUsV0FBVyxVQUFVLElBQUksVUFBVTtBQUNuRSxRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU07QUFDeEMsWUFBWSxNQUFNLFFBQVEsR0FBRyxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDdEQsWUFBWSxNQUFNLEtBQUssR0FBRyxRQUFRLEdBQUcsV0FBVyxDQUFDO0FBQ2pEO0FBQ0EsWUFBWSxJQUFJLElBQUksQ0FBQyx3QkFBd0IsSUFBSSxJQUFJLEtBQUssZUFBZSxFQUFFO0FBQzNFO0FBQ0EsZ0JBQWdCLElBQUksQ0FBQyxVQUFVLENBQUMsU0FBUyxHQUFHLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ2hKLGFBQWEsTUFBTTtBQUNuQixnQkFBZ0IsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLEdBQUcsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqRixhQUFhO0FBQ2I7QUFDQSxZQUFZLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUUsUUFBUSxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNsRSxTQUFTLENBQUMsQ0FBQztBQUNYLEtBQUs7QUFDTDtBQUNBLElBQUksS0FBSyxDQUFDLEdBQUcsb0JBQW9CO0FBQ2pDLFFBQVEsSUFBSSxDQUFDLElBQUksR0FBRyxHQUFHLENBQUM7QUFDeEIsUUFBUSxJQUFJLENBQUMsU0FBUyxHQUFHLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQztBQUMzQyxRQUFRLElBQUksQ0FBQyxVQUFVLEdBQUd5SSxRQUFVLENBQUMsS0FBSyxFQUFFLG1DQUFtQyxFQUFFLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDO0FBQ3JHLFFBQVEsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEdBQUcsTUFBTSxDQUFDO0FBQ3JDO0FBQ0E7QUFDQSxRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDM0MsUUFBUSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7QUFDdkI7QUFDQSxRQUFRLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQztBQUMvQixLQUFLO0FBQ0w7QUFDQSxJQUFJLFFBQVEsR0FBRztBQUNmLFFBQVEsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUNqQztBQUNBLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUM1QyxRQUFRLElBQUksQ0FBQyxJQUFJLElBQUksU0FBUyxNQUFNLENBQUM7QUFDckMsS0FBSztBQUNMO0FBQ0EsSUFBSSxZQUFZLENBQUMsUUFBUSxVQUFVO0FBQ25DLFFBQVEsSUFBSSxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUM7QUFDbEMsUUFBUSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7QUFDdkIsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksT0FBTyxDQUFDLElBQUksUUFBUTtBQUN4QixRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztBQUNqQyxRQUFRLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztBQUN2QixLQUFLO0FBQ0wsQ0FBQztBQUdEO0FBQ0EsU0FBUyx1QkFBdUIsR0FBRztBQUNuQyxJQUFJLElBQUk7QUFDUjtBQUNBLFFBQVEsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztBQUMxRixRQUFRLE9BQU8sSUFBSSxDQUFDO0FBQ3BCLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRTtBQUNoQixRQUFRLE9BQU8sS0FBSyxDQUFDO0FBQ3JCLEtBQUs7QUFDTCxDQUFDO0FBQ0Q7QUFDQSxTQUFTLGtCQUFrQixDQUFDLENBQUMsVUFBVTtBQUN2QyxJQUFJLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ3pFLElBQUksT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxVQUFVLENBQUMsR0FBRyxVQUFVLENBQUM7QUFDbkQsQ0FBQztBQUNEO0FBQ0EsU0FBUyxXQUFXLENBQUMsR0FBRyxVQUFVO0FBQ2xDLElBQUksTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ2xFLElBQUksSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLEtBQUssQ0FBQztBQUN4QjtBQUNBLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRTtBQUNwQixRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztBQUNsQixRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztBQUNsQixRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztBQUNsQixRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNDO0FBQ0EsSUFBSSxPQUFPLEtBQUssR0FBRyxDQUFDLENBQUM7QUFDckIsQ0FBQTs7QUN2TEE7QUFDQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNLGlCQUFpQixDQUFDO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxXQUFXLENBQUMsT0FBTyxXQUFXO0FBQ2xDLFFBQVEsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7QUFDakMsUUFBUSxJQUFJLE9BQU8sSUFBSSxPQUFPLENBQUMsU0FBUyxFQUFFO0FBQzFDLFlBQVksSUFBSSxPQUFPLENBQUMsU0FBUyxZQUFZemQsS0FBTSxDQUFBLE1BQUEsQ0FBQyxXQUFXLEVBQUU7QUFDakUsZ0JBQWdCLElBQUksQ0FBQyxVQUFVLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQztBQUNwRCxhQUFhLE1BQU07QUFDbkIsZ0JBQWdCNFIsS0FBUSxDQUFBLFFBQUEsQ0FBQywwREFBMEQsQ0FBQyxDQUFDO0FBQ3JGLGFBQWE7QUFDYixTQUFTO0FBQ1QsUUFBUW9ELGFBQU8sQ0FBQztBQUNoQixZQUFZLG9CQUFvQjtBQUNoQyxZQUFZLGFBQWE7QUFDekIsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ2pCLFFBQVEsSUFBSSxvQkFBb0IsSUFBSWhWLEtBQU0sQ0FBQSxNQUFBLENBQUMsUUFBUSxFQUFFO0FBQ3JELFlBQVksSUFBSSxDQUFDLGlCQUFpQixHQUFHLGtCQUFrQixDQUFDO0FBQ3hELFNBQVMsTUFBTSxJQUFJLDBCQUEwQixJQUFJQSxLQUFNLENBQUEsTUFBQSxDQUFDLFFBQVEsRUFBRTtBQUNsRSxZQUFZLElBQUksQ0FBQyxpQkFBaUIsR0FBRyx3QkFBd0IsQ0FBQztBQUM5RCxTQUFTO0FBQ1QsS0FBSztBQUNMO0FBQ0EsSUFBSSxLQUFLLENBQUMsR0FBRyxvQkFBb0I7QUFDakMsUUFBUSxJQUFJLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQztBQUN4QixRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztBQUN6RSxRQUFRLElBQUksQ0FBQyxpQkFBaUIsR0FBR3lkLFFBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDLENBQUM7QUFDeEYsUUFBUSxJQUFJLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxFQUFFO0FBQzVDLFlBQVksSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO0FBQzVCLFNBQVMsTUFBTTtBQUNmLFlBQVksSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDO0FBQzFELFlBQVk3TCxLQUFRLENBQUEsUUFBQSxDQUFDLCtDQUErQyxDQUFDLENBQUM7QUFDdEUsU0FBUztBQUNULFFBQVEsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUM7QUFDdEMsS0FBSztBQUNMO0FBQ0EsSUFBSSxRQUFRLEdBQUc7QUFDZixRQUFRLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUN4QyxRQUFRLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxNQUFNLENBQUM7QUFDaEM7QUFDQSxRQUFRNVIsS0FBTSxDQUFBLE1BQUEsQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUN0RixLQUFLO0FBQ0w7QUFDQSxJQUFJLHVCQUF1QixZQUFZO0FBQ3ZDLFFBQVEsT0FBTyxDQUFDO0FBQ2hCLFlBQVlBLEtBQU0sQ0FBQSxNQUFBLENBQUMsUUFBUSxDQUFDLGlCQUFpQjtBQUM3QyxZQUFZLENBQUNBLEtBQUFBLENBQUFBLE1BQU0sQ0FBQyxRQUFRLE9BQU8sdUJBQXVCO0FBQzFELFNBQVMsQ0FBQztBQUNWLEtBQUs7QUFDTDtBQUNBLElBQUksUUFBUSxHQUFHO0FBQ2YsUUFBUSxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsaUJBQWlCLEdBQUd5ZCxRQUFVLENBQUMsUUFBUSxHQUFHLENBQUMsd0JBQXdCLENBQUMsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztBQUMzSCxRQUFRQSxRQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsa0JBQWtCLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxZQUFZLENBQUMsYUFBYSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQzdGLFFBQVEsTUFBTSxDQUFDLElBQUksR0FBRyxRQUFRLENBQUM7QUFDL0IsUUFBUSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7QUFDNUI7QUFDQSxRQUFRLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7QUFDbEY7QUFDQSxRQUFRemQsS0FBTSxDQUFBLE1BQUEsQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUNuRixLQUFLO0FBQ0w7QUFDQSxJQUFJLFlBQVksR0FBRztBQUNuQixRQUFRLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztBQUN2QyxRQUFRLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLENBQUMsWUFBWSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ2pFLFFBQVEsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLGlCQUFpQixDQUFDLGlCQUFpQixDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDNUgsS0FBSztBQUNMO0FBQ0EsSUFBSSxTQUFTLFdBQVc7QUFDeEIsUUFBUSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsR0FBRyx3QkFBd0IsR0FBRyx5QkFBeUIsQ0FBQyxDQUFDO0FBQ25ILEtBQUs7QUFDTDtBQUNBLElBQUksYUFBYSxZQUFZO0FBQzdCLFFBQVEsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDO0FBQ2hDLEtBQUs7QUFDTDtBQUNBLElBQUksV0FBVyxHQUFHO0FBQ2xCLFFBQVEsTUFBTSxpQkFBaUI7QUFDL0IsWUFBWUEsS0FBTSxDQUFBLE1BQUEsQ0FBQyxRQUFRLENBQUMsaUJBQWlCO0FBQzdDLFlBQVksQ0FBQ0EsS0FBTSxDQUFBLE1BQUEsQ0FBQyxRQUFRLE9BQU8sdUJBQXVCLENBQUM7QUFDM0Q7QUFDQSxRQUFRLElBQUksQ0FBQyxpQkFBaUIsS0FBSyxJQUFJLENBQUMsVUFBVSxNQUFNLElBQUksQ0FBQyxXQUFXLEVBQUU7QUFDMUUsWUFBWSxJQUFJLENBQUMsV0FBVyxHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQztBQUNqRCxZQUFZLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxDQUFDO0FBQzVFLFlBQVksSUFBSSxDQUFDLGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDLENBQUM7QUFDaEYsWUFBWSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7QUFDaEMsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBLElBQUksa0JBQWtCLEdBQUc7QUFDekIsUUFBUSxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsRUFBRTtBQUNsQyxZQUFZLElBQUlBLEtBQU0sQ0FBQSxNQUFBLENBQUMsUUFBUSxDQUFDLGNBQWMsRUFBRTtBQUNoRCxnQkFBZ0IsQ0FBQ0EsS0FBTSxDQUFBLE1BQUEsQ0FBQyxRQUFRLE9BQU8sY0FBYyxFQUFFLENBQUM7QUFDeEQsYUFBYSxNQUFNLElBQUlBLEtBQUFBLENBQUFBLE1BQU0sQ0FBQyxRQUFRLENBQUMsc0JBQXNCLEVBQUU7QUFDL0QsZ0JBQWdCLENBQUNBLEtBQU0sQ0FBQSxNQUFBLENBQUMsUUFBUSxPQUFPLHNCQUFzQixFQUFFLENBQUM7QUFDaEUsYUFBYTtBQUNiO0FBQ0EsU0FBUyxNQUFNLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxpQkFBaUIsRUFBRTtBQUN0RCxZQUFZLElBQUksQ0FBQyxVQUFVLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztBQUNoRCxTQUFTLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLE9BQU8sdUJBQXVCLEVBQUU7QUFDbkUsWUFBWSxDQUFDLElBQUksQ0FBQyxVQUFVLE9BQU8sdUJBQXVCLEVBQUUsQ0FBQztBQUM3RCxTQUFTO0FBQ1QsS0FBSztBQUNMLENBQUE7O0FDcklBO0FBQ0E7QUFNQTtBQUNBLE1BQU00ZixhQUFXLEdBQUc1ZixLQUFNLENBQUEsTUFBQSxDQUFDLFdBQVcsQ0FBQztBQUN2QztBQUNBO0FBQ0E7QUFDTyxNQUFNLHNCQUFzQixHQUFHO0FBQ3RDO0FBQ0EsSUFBSSwwQkFBMEIsQ0FBQyxRQUFRLDRDQUE0QztBQUNuRixRQUFRLE1BQU0sT0FBTyxHQUFHa1Isc0JBQWdCLENBQUMscUJBQXFCLEVBQUUsQ0FBQztBQUNqRSxRQUFRLE1BQU0sVUFBVSxHQUFHLElBQUksVUFBVSxDQUFDc0YsbUJBQWEsRUFBRSxFQUFFLHNCQUFzQixDQUFDLENBQUM7QUFDbkY7QUFDQSxRQUFRLE1BQU0sVUFBVSxHQUFHb0osYUFBVyxDQUFDLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7QUFDdkY7QUFDQSxRQUFRLFVBQVUsQ0FBQyxTQUFTLENBQUMsNkJBQTZCLEVBQUUsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLE9BQU8sS0FBSztBQUNsRixZQUFZLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUNoQyxZQUFZLElBQUksR0FBRyxFQUFFLE9BQU8sUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzFDO0FBQ0EsWUFBWSxNQUFNLElBQUksR0FBRyxFQUFFLENBQUM7QUFDNUI7QUFDQSxZQUFZLEtBQUssTUFBTSxNQUFNLElBQUksT0FBTyxFQUFFO0FBQzFDLGdCQUFnQixLQUFLLE1BQU0sT0FBTyxJQUFJLE1BQU0sQ0FBQyxPQUFPLEVBQUU7QUFDdEQsb0JBQW9CLElBQUksT0FBTyxDQUFDLFNBQVMsS0FBSyxTQUFTLEVBQUUsU0FBUztBQUNsRSxvQkFBb0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUM7QUFDdEYsaUJBQWlCO0FBQ2pCO0FBQ0EsZ0JBQWdCLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxNQUFNLENBQUMsVUFBVSxHQUFHQSxhQUFXLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztBQUNwRyxhQUFhO0FBQ2I7QUFDQSxZQUFZLEtBQUssTUFBTSxJQUFJLElBQUksSUFBSSxFQUFFO0FBQ3JDLGdCQUFnQixPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7QUFDNUQsYUFBYTtBQUNiO0FBQ0EsWUFBWSxPQUFPLENBQUMsVUFBVSxHQUFHLE9BQU8sQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLG9CQUFvQixHQUFHLE9BQU8sQ0FBQyxvQkFBb0IsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDO0FBQ3JJLFlBQVksT0FBTyxDQUFDLGlCQUFpQixHQUFHLE9BQU8sQ0FBQyxVQUFVLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQztBQUM5RTtBQUNBLFlBQVksT0FBTyxDQUFDLFNBQVMsR0FBRyxPQUFPLENBQUMsVUFBVSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUM7QUFDeEU7QUFDQSxZQUFZLE9BQU8sQ0FBQyxTQUFTLEdBQUcsQ0FBQzFPLEtBQUFBLENBQUFBLGdCQUFnQixDQUFDLDJCQUEyQixFQUFFLEVBQUUsR0FBRyxPQUFPLENBQUMsQ0FBQztBQUM3RjtBQUNBLFlBQVksT0FBTyxRQUFRLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQ2hELFNBQVMsQ0FBQyxDQUFDO0FBQ1gsS0FBSztBQUNMLENBQUMsQ0FBQTs7QUNqREQ7QUFDQTtBQStCQTtBQUNBLE1BQU0sUUFBUSxHQUFHO0FBQ2pCLElBQUEsT0FBQSxFQUFJeU8sS0FBTyxDQUFBLE9BQUE7QUFDWCxJQUFJLFNBQVM7QUFDYixJQUFBLGdCQUFBLEVBQUlFLEtBQWdCLENBQUEsZ0JBQUE7QUFDcEIsSUFBQSxzQkFBQSxFQUFJQyxLQUFzQixDQUFBLHNCQUFBO0FBQzFCLElBQUksR0FBRztBQUNQLElBQUksaUJBQWlCO0FBQ3JCLElBQUksZ0JBQWdCO0FBQ3BCLElBQUksa0JBQWtCO0FBQ3RCLElBQUksWUFBWTtBQUNoQixJQUFJLGlCQUFpQjtBQUNyQixJQUFJLEtBQUs7QUFDVCxJQUFJLE1BQU07QUFDVixJQUFJLEtBQUs7QUFDVCxJQUFBLE1BQUEsRUFBSTViLEtBQU0sQ0FBQSxNQUFBO0FBQ1YsSUFBQSxZQUFBLEVBQUlzUCxLQUFZLENBQUEsWUFBQTtBQUNoQixJQUFBLEtBQUEsRUFBSXZULEtBQUssQ0FBQSxLQUFBO0FBQ1QsSUFBQSxrQkFBQSxFQUFJZ0wsS0FBa0IsQ0FBQSxrQkFBQTtBQUN0QixJQUFJLGlCQUFpQjtBQUNyQixJQUFBLE9BQUEsRUFBSXlHLEtBQU8sQ0FBQSxPQUFBO0FBQ1gsSUFBQSxNQUFBLEVBQUlnTixLQUFNLENBQUEsTUFBQTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksT0FBTztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSx1QkFBdUI7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLElBQUksV0FBVyxZQUFZO0FBQy9CLFFBQVEsT0FBT0EsS0FBQUEsQ0FBQUEsTUFBTSxDQUFDLFlBQVksQ0FBQztBQUNuQyxLQUFLO0FBQ0w7QUFDQSxJQUFJLElBQUksV0FBVyxDQUFDLEtBQUssVUFBVTtBQUNuQyxRQUFRQSxLQUFNLENBQUEsTUFBQSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7QUFDcEMsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksSUFBSSxVQUFVLFlBQVk7QUFDOUIsUUFBUSxPQUFPQSxLQUFBQSxDQUFBQSxNQUFNLENBQUMsT0FBTyxDQUFDO0FBQzlCLEtBQUs7QUFDTDtBQUNBLElBQUksSUFBSSxVQUFVLENBQUMsR0FBRyxVQUFVO0FBQ2hDLFFBQVFBLEtBQU0sQ0FBQSxNQUFBLENBQUMsT0FBTyxHQUFHLEdBQUcsQ0FBQztBQUM3QixLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksSUFBSSxXQUFXLFdBQVc7QUFDOUIsUUFBUSxPQUFPLFVBQVUsQ0FBQyxXQUFXLENBQUM7QUFDdEMsS0FBSztBQUNMO0FBQ0EsSUFBSSxJQUFJLFdBQVcsQ0FBQyxLQUFLLFVBQVU7QUFDbkMsUUFBUSxVQUFVLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztBQUN2QyxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLElBQUksd0JBQXdCLFdBQVc7QUFDM0MsUUFBUSxPQUFPQSxLQUFBQSxDQUFBQSxNQUFNLENBQUMsMkJBQTJCLENBQUM7QUFDbEQsS0FBSztBQUNMO0FBQ0EsSUFBSSxJQUFJLHdCQUF3QixDQUFDLFdBQVcsVUFBVTtBQUN0RCxRQUFRQSxLQUFNLENBQUEsTUFBQSxDQUFDLDJCQUEyQixHQUFHLFdBQVcsQ0FBQztBQUN6RCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxZQUFZLENBQUMsUUFBUSwwQkFBMEI7QUFDbkQsUUFBUXFCLEtBQWMsQ0FBQSxjQUFBLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDakMsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLFNBQVMsRUFBRSxFQUFFO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksV0FBVyxFQUFFLElBQUk7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxNQUFNLEVBQUUzYyxLQUFPLENBQUEsUUFBQSxDQUFDLE1BQU07QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLFVBQVUsRUFBRUEsS0FBTyxDQUFBLFFBQUEsQ0FBQyxVQUFVO0FBQ2xDLENBQUMsQ0FBQztBQUNGO0FBQ0E7QUFDQXNZLEtBQUssQ0FBQSxLQUFBLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDc0UsUUFBQUEsRUFBQUEsS0FBQUEsQ0FBQUEsUUFBUSxFQUFFLHFCQUFxQixFQUFFOU8sc0JBQWdCLENBQUMscUJBQXFCLEVBQUUsMEJBQTBCLEVBQUUsc0JBQXNCLENBQUMsMEJBQTBCLENBQUMsQ0FBQyxDQUFDO0FBQ2pMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBQSxRQUFBLEdBQWUsUUFBUSxDQUFDO0FBQ3hCO0FBQ0E7QUFDQTFRLEtBQUFBLENBQUFBLE1BQU0sQ0FBQyxJQUFJLEVBQUUsZUFBZSxDQUFDLENBQUE7Ozs7OztBQzVSN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQXlDQTtBQUNBLGlCQUFlLFFBQVE7Ozs7Ozs7OyIsInhfZ29vZ2xlX2lnbm9yZUxpc3QiOls0LDUsNiw3LDgsOSwxMCwyNiw5NCwxMDYsMTA3LDEwOCwxMTgsMTE5LDEyMCwxMjEsMTIyLDEyMywxMjQsMTI1LDEyNiwxMjcsMTUwLDE1MSwxNTgsMTU5LDE2MCwxNjEsMTY1LDE3OSwxODAsMTgyLDE5MCwxOTMsMjU1LDI1OSwyNjEsMjYyLDI2MywyNjQsMjY1LDI2NiwyNjcsMjY4LDI2OSwyNzAsMjcxLDI3NF19